Skip to content

Commit

Permalink
Feature/schema generation update (#347)
Browse files Browse the repository at this point in the history
* ClassesVisitor - Removed interface and basic inheritance logic

* TypescriptModuleWriter - added generalized ContentReferenceField and ContentReferenceListField

* Cleanup: Schema

* fix(TypescriptModuleWriter) Image and Binary simplified prop type, allowed reference filters

* chore(TypescriptEnumsVisitor): single quote to double quote, removed namespace from example

* chore(TypescriptFormatter): extracted disabled content types

* refac(TypescriptFieldSettingsVisitor): removed logic, options, ctor, added FieldDataType and IsVisible properties

* refac(TypescriptClassesVisitor): fixed imports, removed some static comments, added descriptions

* chore(TypescriptComplexTypesVisitor): addex explicit Actions and Type properties for base types

* refac(TypescriptComplexTypesVisitor): added missing access types , removed ctor & assignment logic

* fix(TypescriptCtdVisitor): changed single quotes to double quotes (tslint change), added assignment assertions

* chore(TypescriptEnumsVisitor): added disable tslint comment, fixed indention

* feat(TypescriptFieldSettingsVisitor): added isFieldSettingOfType() type guard, fixed indention

* feat(TypescriptModuleWriter): removed FieldDataType and Visible from blacklist, added simplified property type to AllowedChildTypes and EffectiveAllowedChildTypes

* TypescriptFieldSettings, TypescriptModuleWriter: removed FieldDataType property, enabled FieldClassName

* chore(TypescriptClassesVisitor): RequiredFields to private

* chore(TypescriptFormatter): DisabledContentTypeNames made internal

* Small cleanup and remove the undone.
  • Loading branch information
gallayl authored and tusmester committed May 17, 2018
1 parent 94de024 commit 759f8df
Show file tree
Hide file tree
Showing 8 changed files with 239 additions and 293 deletions.
6 changes: 1 addition & 5 deletions src/Services/Metadata/ClientMetadataProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,6 @@ namespace SenseNet.Services.Metadata
/// </summary>
public class ClientMetadataProvider : IClientMetadataProvider
{
//UNDONE: from TypescriptFormatter. ToDo: put this somewhere. const? web.config? Setting?
private static readonly string[] ContentTypeBlacklist =
{"Application", "ApplicationCacheFile", "FieldSettingContent", "JournalNode"};

private const string ClientMetadataProviderKey = "ClientMetadataProvider";
private static readonly object MetadataProviderSync = new object();

Expand Down Expand Up @@ -143,7 +139,7 @@ protected virtual JObject ConvertMetaClass(Class schemaClass)
[ODataFunction]
public static object GetSchema(Content content, string contentTypeName = null)
{
var sch = new Schema(ContentTypeBlacklist);
var sch = new Schema(Portal.OData.Typescript.TypescriptFormatter.DisabledContentTypeNames);

// If the content type name filter is provided, the result array contains
// only that type. In the future it may contain parent content types too
Expand Down
109 changes: 55 additions & 54 deletions src/Services/OData/Typescript/TypescriptClassesVisitor.cs
Original file line number Diff line number Diff line change
@@ -1,43 +1,46 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using SenseNet.ContentRepository.i18n;
using SenseNet.ContentRepository.Schema.Metadata;

namespace SenseNet.Portal.OData.Typescript
{
internal class TypescriptClassesVisitor : TypescriptModuleWriter
{
private static readonly string[] RequiredFields = new []{ "Id", "Name", "Path", "Type" };

public TypescriptClassesVisitor(TypescriptGenerationContext context, TextWriter writer) : base(context, writer) { }

protected override IMetaNode VisitSchema(ContentRepository.Schema.Metadata.Schema schema)
{
_writer.WriteLine(@"/**
*
* @module ContentTypes
* @preferred
*
*
* @description The Content Repository contains many different types of ```Content```. ```Content``` vary in structure and even in function. Different types of content contain different fields,
* are displayed with different views, and may also implement different business logic. The fields, views and business logic of a content is defined by its type - the Content Type.
*
* Content Types are defined in a type hierarchy: a Content Type may be inherited from another Content Type - thus automatically inheriting its fields.
*
* This module represents the above mentioned type hierarchy by Typescript classes with the Content Types' Fields as properties. With Typescript classes we can derive types from another
* inheriting its properties just like Content Types in the Content Repository. This module provides us to create an objects with a type so that we can validate on its properties by their
* types or check the required ones.
*
*//** */
import { Content, IContentOptions } from './Content';
import { Enums, FieldSettings, ComplexTypes } from './SN';
import { BaseRepository } from './Repository';
_writer.WriteLine(@"/**
* The Content Repository contains many different types of *Content*. *Content* vary in structure and even in function.
*
* Different types of content contain different fields, are displayed with different views, and may also implement different business logic. The fields, views and business logic of a content is defined by its type - the Content Type.
*
* Content Types are defined in a type hierarchy: a Content Type may be inherited from another Content Type - thus automatically inheriting its fields.
*
* This module represents the above mentioned type hierarchy by Typescript classes with the Content Types' Fields as properties. With Typescript classes we can derive types from another
* inheriting its properties just like Content Types in the Content Repository. This module provides us to create an objects with a type so that we can validate on its properties by their
* types or check the required ones.
*
*//** */
// tslint:disable:naming-convention
import * as ComplexTypes from ""./ComplexTypes"";
import * as Enums from ""./Enums"";
import { IActionModel } from ""./IActionModel"";
export type ContentReferenceField<T> = ComplexTypes.DeferredObject | T | number;
export type ContentListReferenceField<T> = ComplexTypes.DeferredObject | T[] | number[];
export type BinaryField = ComplexTypes.MediaResourceObject;
");

// Do not call base because only classes will be read.
_indentCount++;
Visit(schema.Classes);
_indentCount--;

return schema;
}
protected override IMetaNode VisitClass(Class @class)
Expand All @@ -46,49 +49,47 @@ protected override IMetaNode VisitClass(Class @class)
var propertyLines = new List<string>();
foreach (var property in visitedProperties)
{
propertyLines.Add($"{property.Name}?: {GetPropertyTypeName(property)};");
var fieldDescription = SNSR.GetString(property.FieldSetting.Description);
if (!string.IsNullOrWhiteSpace(fieldDescription))
{
propertyLines.Add($" /* {fieldDescription} */");
}
var isRequired = RequiredFields.Contains(property.Name) ? "!" : "?";
propertyLines.Add($"public {property.Name}{isRequired}: {GetPropertyTypeName(property)};");
}

var type = @class.Name;
var parentName = @class.BaseClassName ?? "Content";
WriteLine($"/**");
WriteLine($" * Class representing a {type}");
WriteLine($" * @class {type}");
WriteLine($" * @extends {{@link {parentName}" + "}");
WriteLine($" */");
WriteLine($"export class {type} extends {parentName} {{");
_indentCount++;
foreach (var propertyLine in propertyLines)
WriteLine(propertyLine);
WriteLine();

var parentName = @class.BaseClassName;
WriteLine($"/**");
WriteLine($" * @constructs {type}");
WriteLine($" * @param options {{object}} An object implementing {{@link I{type}Options" + "} interface");
WriteLine($" */");
WriteLine($"constructor(public readonly options: I{type}Options, repository: BaseRepository) {{");
WriteLine($" super(options, repository);");

_indentCount++;
_indentCount--;
WriteLine("}");
WriteLine();
_indentCount--;
WriteLine("}");
var description = SNSR.GetString(@class.ContentType.Description);

WriteLine($"/**");
WriteLine($" * Interface for classes that represent a {type}.");
WriteLine($" * @interface I{type}Options");
WriteLine($" * @extends {{@link I{parentName}Options" + "}");
if (!string.IsNullOrWhiteSpace(description))
{
WriteLine($" * {description}");
}
WriteLine($" */");
WriteLine($"export interface I{type}Options extends I{parentName}Options {{");
if (!string.IsNullOrWhiteSpace(parentName))
{
WriteLine($"export class {type} extends {parentName} {{");
}
else
{
WriteLine($"export class {type} {{");
}

_indentCount++;
foreach (var propertyLine in propertyLines)
{
WriteLine(propertyLine);
}
WriteLine();
if (string.IsNullOrWhiteSpace(parentName))
{
WriteLine("public Actions?: ContentListReferenceField<IActionModel>;");
WriteLine("public Type!: string;");
}
_indentCount--;

WriteLine("}");
WriteLine();

if (@class.Properties == visitedProperties)
return @class;
Expand Down
95 changes: 38 additions & 57 deletions src/Services/OData/Typescript/TypescriptComplexTypesVisitor.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SenseNet.ContentRepository.Schema.Metadata;

namespace SenseNet.Portal.OData.Typescript
Expand All @@ -20,29 +16,31 @@ protected override IMetaNode VisitSchema(ContentRepository.Schema.Metadata.Schem
_writer.WriteLine(@"/**
* @module ComplexTypes
* @preferred
*
* @description Module containing complex data types like HyperLink or ChoiceOption.
*
* This module is autogenerated from Sense/Net ContentRepository.
*
* ```
* let link = new Fields.HyperlinkData({
* Href: 'http://sensenet.com',
* Text: 'Link to sensenet.com',
* Title: 'Go to sensenet.com',
* Target: '_blank'
* });
*
* let webContent = new ContentTypes.WebContentDemo({
* Id: 1,
* Name: 'MyContent',
* DisplayName: 'My Content',
* Type: 'WebContentDemo',
* Details: link
* });
*
* ```
*/ /** */
*
* @description Module containing complex data types like HyperLink or ChoiceOption.
*
* This module is autogenerated from Sense/Net ContentRepository.
*
* ```
* let link = new Fields.HyperlinkData({
* Href: 'http://sensenet.com',
* Text: 'Link to sensenet.com',
* Title: 'Go to sensenet.com',
* Target: '_blank'
* });
*
* let webContent = new ContentTypes.WebContentDemo({
* Id: 1,
* Name: 'MyContent',
* DisplayName: 'My Content',
* Type: 'WebContentDemo',
* Details: link
* });
*
* ```
*/ /** */
// tslint:disable:naming-convention
");
#endregion

Expand All @@ -53,36 +51,29 @@ protected override IMetaNode VisitSchema(ContentRepository.Schema.Metadata.Schem

#region Write fileend
_writer.WriteLine(@"export class ChoiceOption {
Value: string;
Text?: string;
Enabled?: boolean;
Selected?: boolean;
constructor(value: string, text?: string, enabled?: boolean, selected?: boolean) {
this.Value = value;
this.Text = text;
this.Enabled = enabled;
this.Selected = selected;
}
public Value!: string;
public Text?: string;
public Enabled?: boolean;
public Selected?: boolean;
}
export class DeferredUriObject {
uri: string;
public uri!: string;
}
export class DeferredObject extends Object {
__deferred: DeferredUriObject;
public __deferred!: DeferredUriObject;
}
export class MediaObject {
edit_media: string;
media_src: string;
content_type: string;
media_etag: string;
public edit_media!: string;
public media_src!: string;
public content_type!: string;
public media_etag!: string;
}
export class MediaResourceObject extends Object {
__mediaresource: MediaObject;
public __mediaresource!: MediaObject;
}");
#endregion

Expand All @@ -102,26 +93,16 @@ protected override IMetaNode VisitComplexType(ComplexType complexType)

var propertyLines = new List<string>();
var ctorParams = new List<string>();
var assignments = new List<string>();
foreach (var property in complexType.Properties)
{
var propertyLowerName = property.Name.ToLowerInvariant();
var typeName = GetPropertyTypeName(property.PropertyType);
propertyLines.Add($"{property.Name}: {typeName}");
ctorParams.Add($"{propertyLowerName}: {typeName}");
assignments.Add($"this.{property.Name} = {propertyLowerName}");
propertyLines.Add($"public {property.Name}: {typeName}");
}

foreach (var propertyLine in propertyLines)
WriteLine(propertyLine + ";");

WriteLine($"constructor({string.Join(", ", ctorParams)}) {{");
_indentCount++;
foreach (var assignment in assignments)
WriteLine(assignment + ";");
_indentCount--;
WriteLine("}");

// -------------

_indentCount--;
Expand Down
Loading

0 comments on commit 759f8df

Please sign in to comment.