mirror of https://github.com/Squidex/squidex.git
Browse Source
Improved filters with new filter model and reduced dependency to EDM (OData). Also generates the query model in the backend instead of the frontend.pull/837/head
committed by
GitHub
125 changed files with 5239 additions and 2138 deletions
@ -0,0 +1,792 @@ |
|||||
|
//------------------------------------------------------------------------------
|
||||
|
// <auto-generated>
|
||||
|
// This code was generated by a tool.
|
||||
|
// Runtime Version:4.0.30319.42000
|
||||
|
//
|
||||
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
|
// the code is regenerated.
|
||||
|
// </auto-generated>
|
||||
|
//------------------------------------------------------------------------------
|
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Core { |
||||
|
using System; |
||||
|
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
|
/// </summary>
|
||||
|
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
|
// class via a tool like ResGen or Visual Studio.
|
||||
|
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
|
// with the /str option, or rebuild your VS project.
|
||||
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] |
||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()] |
||||
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] |
||||
|
public class FieldDescriptions { |
||||
|
|
||||
|
private static global::System.Resources.ResourceManager resourceMan; |
||||
|
|
||||
|
private static global::System.Globalization.CultureInfo resourceCulture; |
||||
|
|
||||
|
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] |
||||
|
internal FieldDescriptions() { |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Returns the cached ResourceManager instance used by this class.
|
||||
|
/// </summary>
|
||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] |
||||
|
public static global::System.Resources.ResourceManager ResourceManager { |
||||
|
get { |
||||
|
if (object.ReferenceEquals(resourceMan, null)) { |
||||
|
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Squidex.Domain.Apps.Core.FieldDescriptions", typeof(FieldDescriptions).Assembly); |
||||
|
resourceMan = temp; |
||||
|
} |
||||
|
return resourceMan; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Overrides the current thread's CurrentUICulture property for all
|
||||
|
/// resource lookups using this strongly typed resource class.
|
||||
|
/// </summary>
|
||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] |
||||
|
public static global::System.Globalization.CultureInfo Culture { |
||||
|
get { |
||||
|
return resourceCulture; |
||||
|
} |
||||
|
set { |
||||
|
resourceCulture = value; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The ID of the current app..
|
||||
|
/// </summary>
|
||||
|
public static string AppId { |
||||
|
get { |
||||
|
return ResourceManager.GetString("AppId", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The name of the current app..
|
||||
|
/// </summary>
|
||||
|
public static string AppName { |
||||
|
get { |
||||
|
return ResourceManager.GetString("AppName", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The asset..
|
||||
|
/// </summary>
|
||||
|
public static string Asset { |
||||
|
get { |
||||
|
return ResourceManager.GetString("Asset", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The hash of the file. Can be null for old files..
|
||||
|
/// </summary>
|
||||
|
public static string AssetFileHash { |
||||
|
get { |
||||
|
return ResourceManager.GetString("AssetFileHash", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The file name of the asset..
|
||||
|
/// </summary>
|
||||
|
public static string AssetFileName { |
||||
|
get { |
||||
|
return ResourceManager.GetString("AssetFileName", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The size of the file in bytes..
|
||||
|
/// </summary>
|
||||
|
public static string AssetFileSize { |
||||
|
get { |
||||
|
return ResourceManager.GetString("AssetFileSize", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The file type (file extension) of the asset..
|
||||
|
/// </summary>
|
||||
|
public static string AssetFileType { |
||||
|
get { |
||||
|
return ResourceManager.GetString("AssetFileType", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The version of the file..
|
||||
|
/// </summary>
|
||||
|
public static string AssetFileVersion { |
||||
|
get { |
||||
|
return ResourceManager.GetString("AssetFileVersion", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to Determines if the uploaded file is an image..
|
||||
|
/// </summary>
|
||||
|
public static string AssetIsImage { |
||||
|
get { |
||||
|
return ResourceManager.GetString("AssetIsImage", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to True, when the asset is not public..
|
||||
|
/// </summary>
|
||||
|
public static string AssetIsProtected { |
||||
|
get { |
||||
|
return ResourceManager.GetString("AssetIsProtected", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The asset metadata..
|
||||
|
/// </summary>
|
||||
|
public static string AssetMetadata { |
||||
|
get { |
||||
|
return ResourceManager.GetString("AssetMetadata", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The type of the image..
|
||||
|
/// </summary>
|
||||
|
public static string AssetMetadataText { |
||||
|
get { |
||||
|
return ResourceManager.GetString("AssetMetadataText", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The asset metadata with name 'name'..
|
||||
|
/// </summary>
|
||||
|
public static string AssetMetadataValue { |
||||
|
get { |
||||
|
return ResourceManager.GetString("AssetMetadataValue", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The mime type..
|
||||
|
/// </summary>
|
||||
|
public static string AssetMimeType { |
||||
|
get { |
||||
|
return ResourceManager.GetString("AssetMimeType", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The id of the parent folder. Empty for files without parent..
|
||||
|
/// </summary>
|
||||
|
public static string AssetParentId { |
||||
|
get { |
||||
|
return ResourceManager.GetString("AssetParentId", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The full path in the folder hierarchy as array of folder infos..
|
||||
|
/// </summary>
|
||||
|
public static string AssetParentPath { |
||||
|
get { |
||||
|
return ResourceManager.GetString("AssetParentPath", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The height of the image in pixels if the asset is an image..
|
||||
|
/// </summary>
|
||||
|
public static string AssetPixelHeight { |
||||
|
get { |
||||
|
return ResourceManager.GetString("AssetPixelHeight", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The width of the image in pixels if the asset is an image..
|
||||
|
/// </summary>
|
||||
|
public static string AssetPixelWidth { |
||||
|
get { |
||||
|
return ResourceManager.GetString("AssetPixelWidth", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The assets..
|
||||
|
/// </summary>
|
||||
|
public static string AssetsItems { |
||||
|
get { |
||||
|
return ResourceManager.GetString("AssetsItems", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The file name as slug..
|
||||
|
/// </summary>
|
||||
|
public static string AssetSlug { |
||||
|
get { |
||||
|
return ResourceManager.GetString("AssetSlug", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The source URL of the asset..
|
||||
|
/// </summary>
|
||||
|
public static string AssetSourceUrl { |
||||
|
get { |
||||
|
return ResourceManager.GetString("AssetSourceUrl", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The total count of assets..
|
||||
|
/// </summary>
|
||||
|
public static string AssetsTotal { |
||||
|
get { |
||||
|
return ResourceManager.GetString("AssetsTotal", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The asset tags..
|
||||
|
/// </summary>
|
||||
|
public static string AssetTags { |
||||
|
get { |
||||
|
return ResourceManager.GetString("AssetTags", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The thumbnail URL to the asset..
|
||||
|
/// </summary>
|
||||
|
public static string AssetThumbnailUrl { |
||||
|
get { |
||||
|
return ResourceManager.GetString("AssetThumbnailUrl", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The type of the asset..
|
||||
|
/// </summary>
|
||||
|
public static string AssetType { |
||||
|
get { |
||||
|
return ResourceManager.GetString("AssetType", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The URL to the asset..
|
||||
|
/// </summary>
|
||||
|
public static string AssetUrl { |
||||
|
get { |
||||
|
return ResourceManager.GetString("AssetUrl", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The executed command..
|
||||
|
/// </summary>
|
||||
|
public static string Command { |
||||
|
get { |
||||
|
return ResourceManager.GetString("Command", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to {0} field ({1} component)..
|
||||
|
/// </summary>
|
||||
|
public static string ComponentField { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ComponentField", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The schema id to identity the component type..
|
||||
|
/// </summary>
|
||||
|
public static string ComponentSchemaId { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ComponentSchemaId", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to {0} nested field..
|
||||
|
/// </summary>
|
||||
|
public static string ContentArrayField { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ContentArrayField", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The data of the content..
|
||||
|
/// </summary>
|
||||
|
public static string ContentData { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ContentData", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The previous data of the content..
|
||||
|
/// </summary>
|
||||
|
public static string ContentDataOld { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ContentDataOld", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to {0} field..
|
||||
|
/// </summary>
|
||||
|
public static string ContentField { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ContentField", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The flat data of the content..
|
||||
|
/// </summary>
|
||||
|
public static string ContentFlatData { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ContentFlatData", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The new status of the content..
|
||||
|
/// </summary>
|
||||
|
public static string ContentNewStatus { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ContentNewStatus", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The new status color of the content..
|
||||
|
/// </summary>
|
||||
|
public static string ContentNewStatusColor { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ContentNewStatusColor", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to {0} field ({1})..
|
||||
|
/// </summary>
|
||||
|
public static string ContentPartitionField { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ContentPartitionField", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The data for the content..
|
||||
|
/// </summary>
|
||||
|
public static string ContentRequestData { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ContentRequestData", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The timestamp when the status should be changed..
|
||||
|
/// </summary>
|
||||
|
public static string ContentRequestDueTime { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ContentRequestDueTime", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The optional custom content ID..
|
||||
|
/// </summary>
|
||||
|
public static string ContentRequestOptionalId { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ContentRequestOptionalId", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The initial status..
|
||||
|
/// </summary>
|
||||
|
public static string ContentRequestOptionalStatus { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ContentRequestOptionalStatus", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to Set to true to autopublish content on create..
|
||||
|
/// </summary>
|
||||
|
public static string ContentRequestPublish { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ContentRequestPublish", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The status for the content..
|
||||
|
/// </summary>
|
||||
|
public static string ContentRequestStatus { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ContentRequestStatus", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The name of the schema..
|
||||
|
/// </summary>
|
||||
|
public static string ContentSchema { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ContentSchema", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The ID of the schema..
|
||||
|
/// </summary>
|
||||
|
public static string ContentSchemaId { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ContentSchemaId", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The display name of the schema..
|
||||
|
/// </summary>
|
||||
|
public static string ContentSchemaName { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ContentSchemaName", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The contents..
|
||||
|
/// </summary>
|
||||
|
public static string ContentsItems { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ContentsItems", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The status of the content..
|
||||
|
/// </summary>
|
||||
|
public static string ContentStatus { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ContentStatus", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The status color of the content..
|
||||
|
/// </summary>
|
||||
|
public static string ContentStatusColor { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ContentStatusColor", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The previous status of the content..
|
||||
|
/// </summary>
|
||||
|
public static string ContentStatusOld { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ContentStatusOld", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The total count of contents..
|
||||
|
/// </summary>
|
||||
|
public static string ContentsTotal { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ContentsTotal", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The URL to the content..
|
||||
|
/// </summary>
|
||||
|
public static string ContentUrl { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ContentUrl", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The context object holding all values..
|
||||
|
/// </summary>
|
||||
|
public static string Context { |
||||
|
get { |
||||
|
return ResourceManager.GetString("Context", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The edit token..
|
||||
|
/// </summary>
|
||||
|
public static string EditToken { |
||||
|
get { |
||||
|
return ResourceManager.GetString("EditToken", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The timestamp when the object was created..
|
||||
|
/// </summary>
|
||||
|
public static string EntityCreated { |
||||
|
get { |
||||
|
return ResourceManager.GetString("EntityCreated", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The user who created the object..
|
||||
|
/// </summary>
|
||||
|
public static string EntityCreatedBy { |
||||
|
get { |
||||
|
return ResourceManager.GetString("EntityCreatedBy", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The expected version..
|
||||
|
/// </summary>
|
||||
|
public static string EntityExpectedVersion { |
||||
|
get { |
||||
|
return ResourceManager.GetString("EntityExpectedVersion", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The ID of the object (usually GUID)..
|
||||
|
/// </summary>
|
||||
|
public static string EntityId { |
||||
|
get { |
||||
|
return ResourceManager.GetString("EntityId", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to True when deleted..
|
||||
|
/// </summary>
|
||||
|
public static string EntityIsDeleted { |
||||
|
get { |
||||
|
return ResourceManager.GetString("EntityIsDeleted", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The timestamp when the object was updated the last time..
|
||||
|
/// </summary>
|
||||
|
public static string EntityLastModified { |
||||
|
get { |
||||
|
return ResourceManager.GetString("EntityLastModified", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The user who updated the object the last time..
|
||||
|
/// </summary>
|
||||
|
public static string EntityLastModifiedBy { |
||||
|
get { |
||||
|
return ResourceManager.GetString("EntityLastModifiedBy", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to True when the entity should be deleted permanently..
|
||||
|
/// </summary>
|
||||
|
public static string EntityRequestDeletePermanent { |
||||
|
get { |
||||
|
return ResourceManager.GetString("EntityRequestDeletePermanent", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The version of the objec..
|
||||
|
/// </summary>
|
||||
|
public static string EntityVersion { |
||||
|
get { |
||||
|
return ResourceManager.GetString("EntityVersion", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The path to the json value..
|
||||
|
/// </summary>
|
||||
|
public static string JsonPath { |
||||
|
get { |
||||
|
return ResourceManager.GetString("JsonPath", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The current operation..
|
||||
|
/// </summary>
|
||||
|
public static string Operation { |
||||
|
get { |
||||
|
return ResourceManager.GetString("Operation", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to Optional OData filter..
|
||||
|
/// </summary>
|
||||
|
public static string QueryFilter { |
||||
|
get { |
||||
|
return ResourceManager.GetString("QueryFilter", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to Comma separated list of object IDs. Overrides all other query parameters..
|
||||
|
/// </summary>
|
||||
|
public static string QueryIds { |
||||
|
get { |
||||
|
return ResourceManager.GetString("QueryIds", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to Optional OData order definition..
|
||||
|
/// </summary>
|
||||
|
public static string QueryOrderBy { |
||||
|
get { |
||||
|
return ResourceManager.GetString("QueryOrderBy", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to JSON query as well formatted json string. Overrides all other query parameters, except 'ids'..
|
||||
|
/// </summary>
|
||||
|
public static string QueryQ { |
||||
|
get { |
||||
|
return ResourceManager.GetString("QueryQ", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to Optional OData full text search..
|
||||
|
/// </summary>
|
||||
|
public static string QuerySearch { |
||||
|
get { |
||||
|
return ResourceManager.GetString("QuerySearch", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to Optional number of contents to skip..
|
||||
|
/// </summary>
|
||||
|
public static string QuerySkip { |
||||
|
get { |
||||
|
return ResourceManager.GetString("QuerySkip", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to Optional number of contents to take..
|
||||
|
/// </summary>
|
||||
|
public static string QueryTop { |
||||
|
get { |
||||
|
return ResourceManager.GetString("QueryTop", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The optional version of the content to retrieve an older instance (not cached)..
|
||||
|
/// </summary>
|
||||
|
public static string QueryVersion { |
||||
|
get { |
||||
|
return ResourceManager.GetString("QueryVersion", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to Information about the current user..
|
||||
|
/// </summary>
|
||||
|
public static string User { |
||||
|
get { |
||||
|
return ResourceManager.GetString("User", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The additional properties of the user..
|
||||
|
/// </summary>
|
||||
|
public static string UserClaims { |
||||
|
get { |
||||
|
return ResourceManager.GetString("UserClaims", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The display name of the user..
|
||||
|
/// </summary>
|
||||
|
public static string UserDisplayName { |
||||
|
get { |
||||
|
return ResourceManager.GetString("UserDisplayName", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The email address of the current user..
|
||||
|
/// </summary>
|
||||
|
public static string UserEmail { |
||||
|
get { |
||||
|
return ResourceManager.GetString("UserEmail", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The ID of the user..
|
||||
|
/// </summary>
|
||||
|
public static string UserId { |
||||
|
get { |
||||
|
return ResourceManager.GetString("UserId", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to True when the current user is a client, which is typically the case when the request is made from the API..
|
||||
|
/// </summary>
|
||||
|
public static string UserIsClient { |
||||
|
get { |
||||
|
return ResourceManager.GetString("UserIsClient", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to True when the current user is a user, which is typically the case when the request is made in the UI..
|
||||
|
/// </summary>
|
||||
|
public static string UserIsUser { |
||||
|
get { |
||||
|
return ResourceManager.GetString("UserIsUser", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The list of additional properties that have the name 'name'..
|
||||
|
/// </summary>
|
||||
|
public static string UsersClaimsValue { |
||||
|
get { |
||||
|
return ResourceManager.GetString("UsersClaimsValue", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,363 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<root> |
||||
|
<!-- |
||||
|
Microsoft ResX Schema |
||||
|
|
||||
|
Version 2.0 |
||||
|
|
||||
|
The primary goals of this format is to allow a simple XML format |
||||
|
that is mostly human readable. The generation and parsing of the |
||||
|
various data types are done through the TypeConverter classes |
||||
|
associated with the data types. |
||||
|
|
||||
|
Example: |
||||
|
|
||||
|
... ado.net/XML headers & schema ... |
||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader> |
||||
|
<resheader name="version">2.0</resheader> |
||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> |
||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> |
||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> |
||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> |
||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> |
||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value> |
||||
|
</data> |
||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> |
||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> |
||||
|
<comment>This is a comment</comment> |
||||
|
</data> |
||||
|
|
||||
|
There are any number of "resheader" rows that contain simple |
||||
|
name/value pairs. |
||||
|
|
||||
|
Each data row contains a name, and value. The row also contains a |
||||
|
type or mimetype. Type corresponds to a .NET class that support |
||||
|
text/value conversion through the TypeConverter architecture. |
||||
|
Classes that don't support this are serialized and stored with the |
||||
|
mimetype set. |
||||
|
|
||||
|
The mimetype is used for serialized objects, and tells the |
||||
|
ResXResourceReader how to depersist the object. This is currently not |
||||
|
extensible. For a given mimetype the value must be set accordingly: |
||||
|
|
||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format |
||||
|
that the ResXResourceWriter will generate, however the reader can |
||||
|
read any of the formats listed below. |
||||
|
|
||||
|
mimetype: application/x-microsoft.net.object.binary.base64 |
||||
|
value : The object must be serialized with |
||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter |
||||
|
: and then encoded with base64 encoding. |
||||
|
|
||||
|
mimetype: application/x-microsoft.net.object.soap.base64 |
||||
|
value : The object must be serialized with |
||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter |
||||
|
: and then encoded with base64 encoding. |
||||
|
|
||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64 |
||||
|
value : The object must be serialized into a byte array |
||||
|
: using a System.ComponentModel.TypeConverter |
||||
|
: and then encoded with base64 encoding. |
||||
|
--> |
||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> |
||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> |
||||
|
<xsd:element name="root" msdata:IsDataSet="true"> |
||||
|
<xsd:complexType> |
||||
|
<xsd:choice maxOccurs="unbounded"> |
||||
|
<xsd:element name="metadata"> |
||||
|
<xsd:complexType> |
||||
|
<xsd:sequence> |
||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" /> |
||||
|
</xsd:sequence> |
||||
|
<xsd:attribute name="name" use="required" type="xsd:string" /> |
||||
|
<xsd:attribute name="type" type="xsd:string" /> |
||||
|
<xsd:attribute name="mimetype" type="xsd:string" /> |
||||
|
<xsd:attribute ref="xml:space" /> |
||||
|
</xsd:complexType> |
||||
|
</xsd:element> |
||||
|
<xsd:element name="assembly"> |
||||
|
<xsd:complexType> |
||||
|
<xsd:attribute name="alias" type="xsd:string" /> |
||||
|
<xsd:attribute name="name" type="xsd:string" /> |
||||
|
</xsd:complexType> |
||||
|
</xsd:element> |
||||
|
<xsd:element name="data"> |
||||
|
<xsd:complexType> |
||||
|
<xsd:sequence> |
||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> |
||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> |
||||
|
</xsd:sequence> |
||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> |
||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> |
||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> |
||||
|
<xsd:attribute ref="xml:space" /> |
||||
|
</xsd:complexType> |
||||
|
</xsd:element> |
||||
|
<xsd:element name="resheader"> |
||||
|
<xsd:complexType> |
||||
|
<xsd:sequence> |
||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> |
||||
|
</xsd:sequence> |
||||
|
<xsd:attribute name="name" type="xsd:string" use="required" /> |
||||
|
</xsd:complexType> |
||||
|
</xsd:element> |
||||
|
</xsd:choice> |
||||
|
</xsd:complexType> |
||||
|
</xsd:element> |
||||
|
</xsd:schema> |
||||
|
<resheader name="resmimetype"> |
||||
|
<value>text/microsoft-resx</value> |
||||
|
</resheader> |
||||
|
<resheader name="version"> |
||||
|
<value>2.0</value> |
||||
|
</resheader> |
||||
|
<resheader name="reader"> |
||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> |
||||
|
</resheader> |
||||
|
<resheader name="writer"> |
||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> |
||||
|
</resheader> |
||||
|
<data name="AppId" xml:space="preserve"> |
||||
|
<value>The ID of the current app.</value> |
||||
|
</data> |
||||
|
<data name="AppName" xml:space="preserve"> |
||||
|
<value>The name of the current app.</value> |
||||
|
</data> |
||||
|
<data name="Asset" xml:space="preserve"> |
||||
|
<value>The asset.</value> |
||||
|
</data> |
||||
|
<data name="AssetFileHash" xml:space="preserve"> |
||||
|
<value>The hash of the file. Can be null for old files.</value> |
||||
|
</data> |
||||
|
<data name="AssetFileName" xml:space="preserve"> |
||||
|
<value>The file name of the asset.</value> |
||||
|
</data> |
||||
|
<data name="AssetFileSize" xml:space="preserve"> |
||||
|
<value>The size of the file in bytes.</value> |
||||
|
</data> |
||||
|
<data name="AssetFileType" xml:space="preserve"> |
||||
|
<value>The file type (file extension) of the asset.</value> |
||||
|
</data> |
||||
|
<data name="AssetFileVersion" xml:space="preserve"> |
||||
|
<value>The version of the file.</value> |
||||
|
</data> |
||||
|
<data name="AssetIsImage" xml:space="preserve"> |
||||
|
<value>Determines if the uploaded file is an image.</value> |
||||
|
</data> |
||||
|
<data name="AssetIsProtected" xml:space="preserve"> |
||||
|
<value>True, when the asset is not public.</value> |
||||
|
</data> |
||||
|
<data name="AssetMetadata" xml:space="preserve"> |
||||
|
<value>The asset metadata.</value> |
||||
|
</data> |
||||
|
<data name="AssetMetadataText" xml:space="preserve"> |
||||
|
<value>The type of the image.</value> |
||||
|
</data> |
||||
|
<data name="AssetMetadataValue" xml:space="preserve"> |
||||
|
<value>The asset metadata with name 'name'.</value> |
||||
|
</data> |
||||
|
<data name="AssetMimeType" xml:space="preserve"> |
||||
|
<value>The mime type.</value> |
||||
|
</data> |
||||
|
<data name="AssetParentId" xml:space="preserve"> |
||||
|
<value>The id of the parent folder. Empty for files without parent.</value> |
||||
|
</data> |
||||
|
<data name="AssetParentPath" xml:space="preserve"> |
||||
|
<value>The full path in the folder hierarchy as array of folder infos.</value> |
||||
|
</data> |
||||
|
<data name="AssetPixelHeight" xml:space="preserve"> |
||||
|
<value>The height of the image in pixels if the asset is an image.</value> |
||||
|
</data> |
||||
|
<data name="AssetPixelWidth" xml:space="preserve"> |
||||
|
<value>The width of the image in pixels if the asset is an image.</value> |
||||
|
</data> |
||||
|
<data name="AssetsItems" xml:space="preserve"> |
||||
|
<value>The assets.</value> |
||||
|
</data> |
||||
|
<data name="AssetSlug" xml:space="preserve"> |
||||
|
<value>The file name as slug.</value> |
||||
|
</data> |
||||
|
<data name="AssetSourceUrl" xml:space="preserve"> |
||||
|
<value>The source URL of the asset.</value> |
||||
|
</data> |
||||
|
<data name="AssetsTotal" xml:space="preserve"> |
||||
|
<value>The total count of assets.</value> |
||||
|
</data> |
||||
|
<data name="AssetTags" xml:space="preserve"> |
||||
|
<value>The asset tags.</value> |
||||
|
</data> |
||||
|
<data name="AssetThumbnailUrl" xml:space="preserve"> |
||||
|
<value>The thumbnail URL to the asset.</value> |
||||
|
</data> |
||||
|
<data name="AssetType" xml:space="preserve"> |
||||
|
<value>The type of the asset.</value> |
||||
|
</data> |
||||
|
<data name="AssetUrl" xml:space="preserve"> |
||||
|
<value>The URL to the asset.</value> |
||||
|
</data> |
||||
|
<data name="Command" xml:space="preserve"> |
||||
|
<value>The executed command.</value> |
||||
|
</data> |
||||
|
<data name="ComponentField" xml:space="preserve"> |
||||
|
<value>{0} field ({1} component).</value> |
||||
|
</data> |
||||
|
<data name="ComponentSchemaId" xml:space="preserve"> |
||||
|
<value>The schema id to identity the component type.</value> |
||||
|
</data> |
||||
|
<data name="ContentArrayField" xml:space="preserve"> |
||||
|
<value>{0} nested field.</value> |
||||
|
</data> |
||||
|
<data name="ContentData" xml:space="preserve"> |
||||
|
<value>The data of the content.</value> |
||||
|
</data> |
||||
|
<data name="ContentDataOld" xml:space="preserve"> |
||||
|
<value>The previous data of the content.</value> |
||||
|
</data> |
||||
|
<data name="ContentField" xml:space="preserve"> |
||||
|
<value>{0} field.</value> |
||||
|
</data> |
||||
|
<data name="ContentFlatData" xml:space="preserve"> |
||||
|
<value>The flat data of the content.</value> |
||||
|
</data> |
||||
|
<data name="ContentNewStatus" xml:space="preserve"> |
||||
|
<value>The new status of the content.</value> |
||||
|
</data> |
||||
|
<data name="ContentNewStatusColor" xml:space="preserve"> |
||||
|
<value>The new status color of the content.</value> |
||||
|
</data> |
||||
|
<data name="ContentPartitionField" xml:space="preserve"> |
||||
|
<value>{0} field ({1}).</value> |
||||
|
</data> |
||||
|
<data name="ContentRequestData" xml:space="preserve"> |
||||
|
<value>The data for the content.</value> |
||||
|
</data> |
||||
|
<data name="ContentRequestDueTime" xml:space="preserve"> |
||||
|
<value>The timestamp when the status should be changed.</value> |
||||
|
</data> |
||||
|
<data name="ContentRequestOptionalId" xml:space="preserve"> |
||||
|
<value>The optional custom content ID.</value> |
||||
|
</data> |
||||
|
<data name="ContentRequestOptionalStatus" xml:space="preserve"> |
||||
|
<value>The initial status.</value> |
||||
|
</data> |
||||
|
<data name="ContentRequestPublish" xml:space="preserve"> |
||||
|
<value>Set to true to autopublish content on create.</value> |
||||
|
</data> |
||||
|
<data name="ContentRequestStatus" xml:space="preserve"> |
||||
|
<value>The status for the content.</value> |
||||
|
</data> |
||||
|
<data name="ContentSchema" xml:space="preserve"> |
||||
|
<value>The name of the schema.</value> |
||||
|
</data> |
||||
|
<data name="ContentSchemaId" xml:space="preserve"> |
||||
|
<value>The ID of the schema.</value> |
||||
|
</data> |
||||
|
<data name="ContentSchemaName" xml:space="preserve"> |
||||
|
<value>The display name of the schema.</value> |
||||
|
</data> |
||||
|
<data name="ContentsItems" xml:space="preserve"> |
||||
|
<value>The contents.</value> |
||||
|
</data> |
||||
|
<data name="ContentStatus" xml:space="preserve"> |
||||
|
<value>The status of the content.</value> |
||||
|
</data> |
||||
|
<data name="ContentStatusColor" xml:space="preserve"> |
||||
|
<value>The status color of the content.</value> |
||||
|
</data> |
||||
|
<data name="ContentStatusOld" xml:space="preserve"> |
||||
|
<value>The previous status of the content.</value> |
||||
|
</data> |
||||
|
<data name="ContentsTotal" xml:space="preserve"> |
||||
|
<value>The total count of contents.</value> |
||||
|
</data> |
||||
|
<data name="ContentUrl" xml:space="preserve"> |
||||
|
<value>The URL to the content.</value> |
||||
|
</data> |
||||
|
<data name="Context" xml:space="preserve"> |
||||
|
<value>The context object holding all values.</value> |
||||
|
</data> |
||||
|
<data name="EditToken" xml:space="preserve"> |
||||
|
<value>The edit token.</value> |
||||
|
</data> |
||||
|
<data name="EntityCreated" xml:space="preserve"> |
||||
|
<value>The timestamp when the object was created.</value> |
||||
|
</data> |
||||
|
<data name="EntityCreatedBy" xml:space="preserve"> |
||||
|
<value>The user who created the object.</value> |
||||
|
</data> |
||||
|
<data name="EntityExpectedVersion" xml:space="preserve"> |
||||
|
<value>The expected version.</value> |
||||
|
</data> |
||||
|
<data name="EntityId" xml:space="preserve"> |
||||
|
<value>The ID of the object (usually GUID).</value> |
||||
|
</data> |
||||
|
<data name="EntityIsDeleted" xml:space="preserve"> |
||||
|
<value>True when deleted.</value> |
||||
|
</data> |
||||
|
<data name="EntityLastModified" xml:space="preserve"> |
||||
|
<value>The timestamp when the object was updated the last time.</value> |
||||
|
</data> |
||||
|
<data name="EntityLastModifiedBy" xml:space="preserve"> |
||||
|
<value>The user who updated the object the last time.</value> |
||||
|
</data> |
||||
|
<data name="EntityRequestDeletePermanent" xml:space="preserve"> |
||||
|
<value>True when the entity should be deleted permanently.</value> |
||||
|
</data> |
||||
|
<data name="EntityVersion" xml:space="preserve"> |
||||
|
<value>The version of the objec.</value> |
||||
|
</data> |
||||
|
<data name="JsonPath" xml:space="preserve"> |
||||
|
<value>The path to the json value.</value> |
||||
|
</data> |
||||
|
<data name="Operation" xml:space="preserve"> |
||||
|
<value>The current operation.</value> |
||||
|
</data> |
||||
|
<data name="QueryFilter" xml:space="preserve"> |
||||
|
<value>Optional OData filter.</value> |
||||
|
</data> |
||||
|
<data name="QueryIds" xml:space="preserve"> |
||||
|
<value>Comma separated list of object IDs. Overrides all other query parameters.</value> |
||||
|
</data> |
||||
|
<data name="QueryOrderBy" xml:space="preserve"> |
||||
|
<value>Optional OData order definition.</value> |
||||
|
</data> |
||||
|
<data name="QueryQ" xml:space="preserve"> |
||||
|
<value>JSON query as well formatted json string. Overrides all other query parameters, except 'ids'.</value> |
||||
|
</data> |
||||
|
<data name="QuerySearch" xml:space="preserve"> |
||||
|
<value>Optional OData full text search.</value> |
||||
|
</data> |
||||
|
<data name="QuerySkip" xml:space="preserve"> |
||||
|
<value>Optional number of contents to skip.</value> |
||||
|
</data> |
||||
|
<data name="QueryTop" xml:space="preserve"> |
||||
|
<value>Optional number of contents to take.</value> |
||||
|
</data> |
||||
|
<data name="QueryVersion" xml:space="preserve"> |
||||
|
<value>The optional version of the content to retrieve an older instance (not cached).</value> |
||||
|
</data> |
||||
|
<data name="User" xml:space="preserve"> |
||||
|
<value>Information about the current user.</value> |
||||
|
</data> |
||||
|
<data name="UserClaims" xml:space="preserve"> |
||||
|
<value>The additional properties of the user.</value> |
||||
|
</data> |
||||
|
<data name="UserDisplayName" xml:space="preserve"> |
||||
|
<value>The display name of the user.</value> |
||||
|
</data> |
||||
|
<data name="UserEmail" xml:space="preserve"> |
||||
|
<value>The email address of the current user.</value> |
||||
|
</data> |
||||
|
<data name="UserId" xml:space="preserve"> |
||||
|
<value>The ID of the user.</value> |
||||
|
</data> |
||||
|
<data name="UserIsClient" xml:space="preserve"> |
||||
|
<value>True when the current user is a client, which is typically the case when the request is made from the API.</value> |
||||
|
</data> |
||||
|
<data name="UserIsUser" xml:space="preserve"> |
||||
|
<value>True when the current user is a user, which is typically the case when the request is made in the UI.</value> |
||||
|
</data> |
||||
|
<data name="UsersClaimsValue" xml:space="preserve"> |
||||
|
<value>The list of additional properties that have the name 'name'.</value> |
||||
|
</data> |
||||
|
</root> |
||||
@ -1,240 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
namespace Squidex.Domain.Apps.Core |
|
||||
{ |
|
||||
public static class FieldDescriptions |
|
||||
{ |
|
||||
public static string AppId => |
|
||||
"The ID of the current app."; |
|
||||
|
|
||||
public static string AppName => |
|
||||
"The name of the current app."; |
|
||||
|
|
||||
public static string Asset => |
|
||||
"The asset."; |
|
||||
|
|
||||
public static string AssetFileHash => |
|
||||
"The hash of the file. Can be null for old files."; |
|
||||
|
|
||||
public static string AssetFileName => |
|
||||
"The file name of the asset."; |
|
||||
|
|
||||
public static string AssetFileSize => |
|
||||
"The size of the file in bytes."; |
|
||||
|
|
||||
public static string AssetFileType => |
|
||||
"The file type (file extension) of the asset."; |
|
||||
|
|
||||
public static string AssetFileVersion => |
|
||||
"The version of the file."; |
|
||||
|
|
||||
public static string AssetIsImage => |
|
||||
"Determines if the uploaded file is an image."; |
|
||||
|
|
||||
public static string AssetIsProtected => |
|
||||
"True, when the asset is not public."; |
|
||||
|
|
||||
public static string AssetMetadata => |
|
||||
"The asset metadata."; |
|
||||
|
|
||||
public static string AssetMetadataText => |
|
||||
"The type of the image."; |
|
||||
|
|
||||
public static string AssetMetadataValue => |
|
||||
"The asset metadata with name 'name'."; |
|
||||
|
|
||||
public static string AssetMimeType => |
|
||||
"The mime type."; |
|
||||
|
|
||||
public static string AssetParentId => |
|
||||
"The id of the parent folder. Empty for files without parent."; |
|
||||
|
|
||||
public static string AssetParentPath => |
|
||||
"The full path in the folder hierarchy as array of folder infos."; |
|
||||
|
|
||||
public static string AssetPixelHeight => |
|
||||
"The height of the image in pixels if the asset is an image."; |
|
||||
|
|
||||
public static string AssetPixelWidth => |
|
||||
"The width of the image in pixels if the asset is an image."; |
|
||||
|
|
||||
public static string AssetsItems => |
|
||||
"The assets."; |
|
||||
|
|
||||
public static string AssetSlug => |
|
||||
"The file name as slug."; |
|
||||
|
|
||||
public static string AssetSourceUrl => |
|
||||
"The source URL of the asset."; |
|
||||
|
|
||||
public static string AssetsTotal => |
|
||||
"The total count of assets."; |
|
||||
|
|
||||
public static string AssetTags => |
|
||||
"The asset tags."; |
|
||||
|
|
||||
public static string AssetThumbnailUrl => |
|
||||
"The thumbnail URL to the asset."; |
|
||||
|
|
||||
public static string AssetType => |
|
||||
"The type of the image."; |
|
||||
|
|
||||
public static string AssetUrl => |
|
||||
"The URL to the asset."; |
|
||||
|
|
||||
public static string Command => |
|
||||
"The executed command."; |
|
||||
|
|
||||
public static string ContentData => |
|
||||
"The data of the content."; |
|
||||
|
|
||||
public static string ContentDataOld => |
|
||||
"The previous data of the content."; |
|
||||
|
|
||||
public static string ContentFlatData => |
|
||||
"The flat data of the content."; |
|
||||
|
|
||||
public static string ContentNewStatus => |
|
||||
"The new status of the content."; |
|
||||
|
|
||||
public static string ContentNewStatusColor => |
|
||||
"The new status color of the content."; |
|
||||
|
|
||||
public static string ContentRequestData => |
|
||||
"The data for the content."; |
|
||||
|
|
||||
public static string ContentRequestDueTime => |
|
||||
"The timestamp when the status should be changed."; |
|
||||
|
|
||||
public static string ContentRequestOptionalId => |
|
||||
"The optional custom content ID."; |
|
||||
|
|
||||
public static string ContentRequestOptionalStatus => |
|
||||
"The initial status."; |
|
||||
|
|
||||
public static string ContentRequestPublish => |
|
||||
"Set to true to autopublish content on create."; |
|
||||
|
|
||||
public static string ContentRequestStatus => |
|
||||
"The status for the content."; |
|
||||
|
|
||||
public static string ContentSchema => |
|
||||
"The name of the schema."; |
|
||||
|
|
||||
public static string ContentSchemaId => |
|
||||
"The ID of the schema."; |
|
||||
|
|
||||
public static string ContentSchemaName => |
|
||||
"The display name of the schema."; |
|
||||
|
|
||||
public static string ContentsItems => |
|
||||
$"The contents."; |
|
||||
|
|
||||
public static string ContentStatus => |
|
||||
"The status of the content."; |
|
||||
|
|
||||
public static string ContentStatusColor => |
|
||||
"The status color of the content."; |
|
||||
|
|
||||
public static string ContentStatusOld => |
|
||||
"The previous status of the content."; |
|
||||
|
|
||||
public static string ContentsTotal => |
|
||||
$"The total count of contents."; |
|
||||
|
|
||||
public static string ContentUrl => |
|
||||
"The URL to the content."; |
|
||||
|
|
||||
public static string Context => |
|
||||
"The context object holding all values."; |
|
||||
|
|
||||
public static string EditToken => |
|
||||
"The edit token."; |
|
||||
|
|
||||
public static string EntityCreated => |
|
||||
"The timestamp when the object was created."; |
|
||||
|
|
||||
public static string EntityCreatedBy => |
|
||||
"The user who created the object."; |
|
||||
|
|
||||
public static string EntityExpectedVersion => |
|
||||
"The expected version."; |
|
||||
|
|
||||
public static string EntityId => |
|
||||
"The ID of the object."; |
|
||||
|
|
||||
public static string EntityIsDeleted => |
|
||||
"True when deleted."; |
|
||||
|
|
||||
public static string EntityLastModified => |
|
||||
"The timestamp when the object was updated the last time."; |
|
||||
|
|
||||
public static string EntityLastModifiedBy => |
|
||||
"The user who updated the object the last time."; |
|
||||
|
|
||||
public static string EntityRequestDeletePermanent => |
|
||||
"True when the entity should be deleted permanently."; |
|
||||
|
|
||||
public static string EntityVersion => |
|
||||
"The version of the object (usually GUID)."; |
|
||||
|
|
||||
public static string JsonPath => |
|
||||
"The path to the json value."; |
|
||||
|
|
||||
public static string Operation => |
|
||||
"The current operation."; |
|
||||
|
|
||||
public static string QueryFilter => |
|
||||
"Optional OData filter."; |
|
||||
|
|
||||
public static string QueryIds => |
|
||||
"Comma separated list of object IDs. Overrides all other query parameters."; |
|
||||
|
|
||||
public static string QueryOrderBy => |
|
||||
"Optional OData order definition."; |
|
||||
|
|
||||
public static string QueryQ => |
|
||||
"JSON query as well formatted json string. Overrides all other query parameters, except 'ids'."; |
|
||||
|
|
||||
public static string QuerySearch => |
|
||||
"Optional OData full text search."; |
|
||||
|
|
||||
public static string QuerySkip => |
|
||||
"Optional number of contents to skip."; |
|
||||
|
|
||||
public static string QueryTop => |
|
||||
"Optional number of contents to take."; |
|
||||
|
|
||||
public static string QueryVersion => |
|
||||
"The optional version of the content to retrieve an older instance (not cached)."; |
|
||||
|
|
||||
public static string User => |
|
||||
"Information about the current user."; |
|
||||
|
|
||||
public static string UserClaims => |
|
||||
"The additional properties of the user."; |
|
||||
|
|
||||
public static string UserDisplayName => |
|
||||
"The display name of the user."; |
|
||||
|
|
||||
public static string UserEmail => |
|
||||
"The email address of the current user."; |
|
||||
|
|
||||
public static string UserId => |
|
||||
"The ID of the user."; |
|
||||
|
|
||||
public static string UserIsClient => |
|
||||
"True when the current user is a client, which is typically the case when the request is made from the API."; |
|
||||
|
|
||||
public static string UserIsUser => |
|
||||
"True when the current user is a user, which is typically the case when the request is made in the UI."; |
|
||||
|
|
||||
public static string UsersClaimsValue => |
|
||||
"The list of additional properties that have the name 'name'."; |
|
||||
} |
|
||||
} |
|
||||
@ -1,69 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using Microsoft.OData.Edm; |
|
||||
using Squidex.Domain.Apps.Core.Schemas; |
|
||||
using Squidex.Infrastructure; |
|
||||
using Squidex.Text; |
|
||||
|
|
||||
namespace Squidex.Domain.Apps.Core.GenerateEdmSchema |
|
||||
{ |
|
||||
public delegate (EdmComplexType Type, bool Created) EdmTypeFactory(string name); |
|
||||
|
|
||||
public static class EdmSchemaExtensions |
|
||||
{ |
|
||||
public static EdmComplexType BuildEdmType(this Schema schema, bool withHidden, PartitionResolver partitionResolver, EdmTypeFactory factory, |
|
||||
ResolvedComponents components) |
|
||||
{ |
|
||||
Guard.NotNull(factory, nameof(factory)); |
|
||||
Guard.NotNull(partitionResolver, nameof(partitionResolver)); |
|
||||
|
|
||||
var (edmType, _) = factory("Data"); |
|
||||
|
|
||||
foreach (var field in schema.FieldsByName.Values) |
|
||||
{ |
|
||||
if (!field.IsForApi(withHidden)) |
|
||||
{ |
|
||||
continue; |
|
||||
} |
|
||||
|
|
||||
var fieldEdmType = EdmTypeVisitor.BuildType(field, factory, components); |
|
||||
|
|
||||
if (fieldEdmType == null) |
|
||||
{ |
|
||||
continue; |
|
||||
} |
|
||||
|
|
||||
var (partitionType, created) = factory($"Data.{field.Name.ToPascalCase()}"); |
|
||||
|
|
||||
if (created) |
|
||||
{ |
|
||||
var partitioning = partitionResolver(field.Partitioning); |
|
||||
|
|
||||
foreach (var partitionKey in partitioning.AllKeys) |
|
||||
{ |
|
||||
partitionType.AddStructuralProperty(partitionKey.EscapeEdmField(), fieldEdmType); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
edmType.AddStructuralProperty(field.Name.EscapeEdmField(), new EdmComplexTypeReference(partitionType, false)); |
|
||||
} |
|
||||
|
|
||||
return edmType; |
|
||||
} |
|
||||
|
|
||||
public static string EscapeEdmField(this string field) |
|
||||
{ |
|
||||
return field.Replace("-", "_", StringComparison.Ordinal); |
|
||||
} |
|
||||
|
|
||||
public static string UnescapeEdmField(this string field) |
|
||||
{ |
|
||||
return field.Replace("_", "-", StringComparison.Ordinal); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,142 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using Microsoft.OData.Edm; |
|
||||
using Squidex.Domain.Apps.Core.Schemas; |
|
||||
using Squidex.Text; |
|
||||
|
|
||||
#pragma warning disable SA1313 // Parameter names should begin with lower-case letter
|
|
||||
|
|
||||
namespace Squidex.Domain.Apps.Core.GenerateEdmSchema |
|
||||
{ |
|
||||
internal sealed class EdmTypeVisitor : IFieldVisitor<IEdmTypeReference?, EdmTypeVisitor.Args> |
|
||||
{ |
|
||||
private const int MaxDepth = 5; |
|
||||
private static readonly EdmComplexType JsonType = new EdmComplexType("Squidex", "Json", null, false, true); |
|
||||
private static readonly EdmTypeVisitor Instance = new EdmTypeVisitor(); |
|
||||
|
|
||||
public sealed record Args(EdmTypeFactory Factory, ResolvedComponents Components, int Level = 0); |
|
||||
|
|
||||
private EdmTypeVisitor() |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
public static IEdmTypeReference? BuildType(IField field, EdmTypeFactory factory, ResolvedComponents components) |
|
||||
{ |
|
||||
var args = new Args(factory, components); |
|
||||
|
|
||||
return field.Accept(Instance, args); |
|
||||
} |
|
||||
|
|
||||
public IEdmTypeReference? Visit(IArrayField field, Args args) |
|
||||
{ |
|
||||
return CreateNestedType(field, field.Fields.ForApi(true), args); |
|
||||
} |
|
||||
|
|
||||
public IEdmTypeReference? Visit(IField<AssetsFieldProperties> field, Args args) |
|
||||
{ |
|
||||
return CreatePrimitive(EdmPrimitiveTypeKind.String, field); |
|
||||
} |
|
||||
|
|
||||
public IEdmTypeReference? Visit(IField<BooleanFieldProperties> field, Args args) |
|
||||
{ |
|
||||
return CreatePrimitive(EdmPrimitiveTypeKind.Boolean, field); |
|
||||
} |
|
||||
|
|
||||
public IEdmTypeReference? Visit(IField<ComponentFieldProperties> field, Args args) |
|
||||
{ |
|
||||
return CreateNestedType(field, args.Components.GetSharedFields(field.Properties.SchemaIds, true), args); |
|
||||
} |
|
||||
|
|
||||
public IEdmTypeReference? Visit(IField<ComponentsFieldProperties> field, Args args) |
|
||||
{ |
|
||||
return CreateNestedType(field, args.Components.GetSharedFields(field.Properties.SchemaIds, true), args); |
|
||||
} |
|
||||
|
|
||||
public IEdmTypeReference? Visit(IField<DateTimeFieldProperties> field, Args args) |
|
||||
{ |
|
||||
return CreatePrimitive(EdmPrimitiveTypeKind.DateTimeOffset, field); |
|
||||
} |
|
||||
|
|
||||
public IEdmTypeReference? Visit(IField<GeolocationFieldProperties> field, Args args) |
|
||||
{ |
|
||||
return CreateGeographyPoint(field); |
|
||||
} |
|
||||
|
|
||||
public IEdmTypeReference? Visit(IField<JsonFieldProperties> field, Args args) |
|
||||
{ |
|
||||
return CreateJson(field); |
|
||||
} |
|
||||
|
|
||||
public IEdmTypeReference? Visit(IField<NumberFieldProperties> field, Args args) |
|
||||
{ |
|
||||
return CreatePrimitive(EdmPrimitiveTypeKind.Double, field); |
|
||||
} |
|
||||
|
|
||||
public IEdmTypeReference? Visit(IField<ReferencesFieldProperties> field, Args args) |
|
||||
{ |
|
||||
return CreatePrimitive(EdmPrimitiveTypeKind.String, field); |
|
||||
} |
|
||||
|
|
||||
public IEdmTypeReference? Visit(IField<StringFieldProperties> field, Args args) |
|
||||
{ |
|
||||
return CreatePrimitive(EdmPrimitiveTypeKind.String, field); |
|
||||
} |
|
||||
|
|
||||
public IEdmTypeReference? Visit(IField<TagsFieldProperties> field, Args args) |
|
||||
{ |
|
||||
return CreatePrimitive(EdmPrimitiveTypeKind.String, field); |
|
||||
} |
|
||||
|
|
||||
public IEdmTypeReference? Visit(IField<UIFieldProperties> field, Args args) |
|
||||
{ |
|
||||
return null; |
|
||||
} |
|
||||
|
|
||||
private static IEdmTypeReference CreatePrimitive(EdmPrimitiveTypeKind kind, IField field) |
|
||||
{ |
|
||||
return EdmCoreModel.Instance.GetPrimitive(kind, !field.RawProperties.IsRequired); |
|
||||
} |
|
||||
|
|
||||
private static IEdmTypeReference CreateGeographyPoint(IField<GeolocationFieldProperties> field) |
|
||||
{ |
|
||||
return EdmCoreModel.Instance.GetSpatial(EdmPrimitiveTypeKind.GeographyPoint, !field.RawProperties.IsRequired); |
|
||||
} |
|
||||
|
|
||||
private static IEdmTypeReference CreateJson(IField<JsonFieldProperties> field) |
|
||||
{ |
|
||||
return new EdmComplexTypeReference(JsonType, !field.RawProperties.IsRequired); |
|
||||
} |
|
||||
|
|
||||
private IEdmTypeReference? CreateNestedType(IField field, IEnumerable<IField> nested, Args args) |
|
||||
{ |
|
||||
if (args.Level > MaxDepth) |
|
||||
{ |
|
||||
return null; |
|
||||
} |
|
||||
|
|
||||
var (fieldEdmType, created) = args.Factory($"Data.{field.Name.ToPascalCase()}.Nested"); |
|
||||
|
|
||||
if (created) |
|
||||
{ |
|
||||
var nestedArgs = args with { Level = args.Level + 1 }; |
|
||||
|
|
||||
foreach (var sharedField in nested) |
|
||||
{ |
|
||||
var nestedEdmType = sharedField.Accept(this, nestedArgs); |
|
||||
|
|
||||
if (nestedEdmType != null) |
|
||||
{ |
|
||||
fieldEdmType.AddStructuralProperty(sharedField.Name.EscapeEdmField(), nestedEdmType); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
return new EdmComplexTypeReference(fieldEdmType, false); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,101 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using Squidex.Infrastructure.Collections; |
||||
|
using Squidex.Infrastructure.Queries; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Core.GenerateFilters |
||||
|
{ |
||||
|
public static class AssetQueryModel |
||||
|
{ |
||||
|
public static QueryModel Build() |
||||
|
{ |
||||
|
var fields = new List<FilterField> |
||||
|
{ |
||||
|
new FilterField(FilterSchema.String, "id") |
||||
|
{ |
||||
|
Description = FieldDescriptions.EntityId |
||||
|
}, |
||||
|
new FilterField(FilterSchema.Boolean, "isDeleted") |
||||
|
{ |
||||
|
Description = FieldDescriptions.EntityIsDeleted |
||||
|
}, |
||||
|
new FilterField(FilterSchema.DateTime, "created") |
||||
|
{ |
||||
|
Description = FieldDescriptions.EntityCreated |
||||
|
}, |
||||
|
new FilterField(SharedSchemas.User, "createdBy") |
||||
|
{ |
||||
|
Description = FieldDescriptions.EntityCreatedBy |
||||
|
}, |
||||
|
new FilterField(FilterSchema.DateTime, "lastModified") |
||||
|
{ |
||||
|
Description = FieldDescriptions.EntityLastModified |
||||
|
}, |
||||
|
new FilterField(SharedSchemas.User, "lastModifiedBy") |
||||
|
{ |
||||
|
Description = FieldDescriptions.EntityLastModifiedBy |
||||
|
}, |
||||
|
new FilterField(FilterSchema.String, "status") |
||||
|
{ |
||||
|
Description = FieldDescriptions.ContentStatus |
||||
|
}, |
||||
|
new FilterField(FilterSchema.String, "version") |
||||
|
{ |
||||
|
Description = FieldDescriptions.EntityVersion |
||||
|
}, |
||||
|
new FilterField(FilterSchema.String, "fileHash") |
||||
|
{ |
||||
|
Description = FieldDescriptions.AssetFileHash |
||||
|
}, |
||||
|
new FilterField(FilterSchema.String, "fileName") |
||||
|
{ |
||||
|
Description = FieldDescriptions.AssetFileName |
||||
|
}, |
||||
|
new FilterField(FilterSchema.Number, "fileSize") |
||||
|
{ |
||||
|
Description = FieldDescriptions.AssetFileSize |
||||
|
}, |
||||
|
new FilterField(FilterSchema.Number, "fileVersion") |
||||
|
{ |
||||
|
Description = FieldDescriptions.AssetFileVersion |
||||
|
}, |
||||
|
new FilterField(FilterSchema.Boolean, "isProtected") |
||||
|
{ |
||||
|
Description = FieldDescriptions.AssetIsProtected |
||||
|
}, |
||||
|
new FilterField(FilterSchema.Any, "metadata") |
||||
|
{ |
||||
|
Description = FieldDescriptions.AssetMetadata |
||||
|
}, |
||||
|
new FilterField(FilterSchema.String, "mimeType") |
||||
|
{ |
||||
|
Description = FieldDescriptions.AssetMimeType |
||||
|
}, |
||||
|
new FilterField(FilterSchema.String, "slug") |
||||
|
{ |
||||
|
Description = FieldDescriptions.AssetSlug |
||||
|
}, |
||||
|
new FilterField(FilterSchema.StringArray, "tags") |
||||
|
{ |
||||
|
Description = FieldDescriptions.AssetTags |
||||
|
}, |
||||
|
new FilterField(FilterSchema.String, "type") |
||||
|
{ |
||||
|
Description = FieldDescriptions.AssetType |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
var schema = new FilterSchema(FilterSchemaType.Object) |
||||
|
{ |
||||
|
Fields = fields.ToReadonlyList() |
||||
|
}; |
||||
|
|
||||
|
return new QueryModel { Schema = schema }; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,76 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using Squidex.Domain.Apps.Core.Schemas; |
||||
|
using Squidex.Infrastructure.Collections; |
||||
|
using Squidex.Infrastructure.Queries; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Core.GenerateFilters |
||||
|
{ |
||||
|
public static class ContentQueryModel |
||||
|
{ |
||||
|
public static QueryModel Build(Schema? schema, PartitionResolver partitionResolver, ResolvedComponents components) |
||||
|
{ |
||||
|
var fields = new List<FilterField> |
||||
|
{ |
||||
|
new FilterField(FilterSchema.String, "id") |
||||
|
{ |
||||
|
Description = FieldDescriptions.EntityId |
||||
|
}, |
||||
|
new FilterField(FilterSchema.Boolean, "isDeleted") |
||||
|
{ |
||||
|
Description = FieldDescriptions.EntityIsDeleted |
||||
|
}, |
||||
|
new FilterField(FilterSchema.DateTime, "created") |
||||
|
{ |
||||
|
Description = FieldDescriptions.EntityCreated |
||||
|
}, |
||||
|
new FilterField(SharedSchemas.User, "createdBy") |
||||
|
{ |
||||
|
Description = FieldDescriptions.EntityCreatedBy |
||||
|
}, |
||||
|
new FilterField(FilterSchema.DateTime, "lastModified") |
||||
|
{ |
||||
|
Description = FieldDescriptions.EntityLastModified |
||||
|
}, |
||||
|
new FilterField(SharedSchemas.User, "lastModifiedBy") |
||||
|
{ |
||||
|
Description = FieldDescriptions.EntityLastModifiedBy |
||||
|
}, |
||||
|
new FilterField(FilterSchema.Number, "version") |
||||
|
{ |
||||
|
Description = FieldDescriptions.EntityVersion |
||||
|
}, |
||||
|
new FilterField(SharedSchemas.Status, "status") |
||||
|
{ |
||||
|
Description = FieldDescriptions.ContentStatus, |
||||
|
}, |
||||
|
new FilterField(SharedSchemas.Status, "newStatus", IsNullable: true) |
||||
|
{ |
||||
|
Description = FieldDescriptions.ContentNewStatus |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
if (schema != null) |
||||
|
{ |
||||
|
var dataSchema = schema.BuildDataSchema(partitionResolver, components); |
||||
|
|
||||
|
fields.Add(new FilterField(dataSchema, "data") |
||||
|
{ |
||||
|
Description = FieldDescriptions.ContentData |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
var filterSchema = new FilterSchema(FilterSchemaType.Object) |
||||
|
{ |
||||
|
Fields = fields.ToReadonlyList() |
||||
|
}; |
||||
|
|
||||
|
return new QueryModel { Schema = filterSchema }; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,86 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System.Globalization; |
||||
|
using Squidex.Domain.Apps.Core.Schemas; |
||||
|
using Squidex.Infrastructure; |
||||
|
using Squidex.Infrastructure.Collections; |
||||
|
using Squidex.Infrastructure.Queries; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Core.GenerateFilters |
||||
|
{ |
||||
|
public static class JsonSchemaExtensions |
||||
|
{ |
||||
|
public static FilterSchema BuildDataSchema(this Schema schema, PartitionResolver partitionResolver, |
||||
|
ResolvedComponents components) |
||||
|
{ |
||||
|
Guard.NotNull(partitionResolver, nameof(partitionResolver)); |
||||
|
Guard.NotNull(components, nameof(components)); |
||||
|
|
||||
|
var fields = new List<FilterField>(); |
||||
|
|
||||
|
var schemaName = schema.DisplayName(); |
||||
|
|
||||
|
foreach (var field in schema.Fields.ForApi(true)) |
||||
|
{ |
||||
|
var fieldSchema = FilterVisitor.BuildProperty(field, components); |
||||
|
|
||||
|
if (fieldSchema == null) |
||||
|
{ |
||||
|
continue; |
||||
|
} |
||||
|
|
||||
|
var partitioning = partitionResolver(field.Partitioning); |
||||
|
var partitionFields = new List<FilterField>(); |
||||
|
|
||||
|
foreach (var partitionKey in partitioning.AllKeys) |
||||
|
{ |
||||
|
var partitionDescription = FieldPartitionDescription(field, partitioning.GetName(partitionKey) ?? partitionKey); |
||||
|
|
||||
|
var partitionField = new FilterField( |
||||
|
fieldSchema, |
||||
|
partitionKey, |
||||
|
partitionDescription, |
||||
|
true); |
||||
|
|
||||
|
partitionFields.Add(partitionField); |
||||
|
} |
||||
|
|
||||
|
var filterable = new FilterField( |
||||
|
new FilterSchema(FilterSchemaType.Object) |
||||
|
{ |
||||
|
Fields = partitionFields.ToReadonlyList() |
||||
|
}, |
||||
|
field.Name, |
||||
|
FieldDescription(schemaName, field)); |
||||
|
|
||||
|
fields.Add(filterable); |
||||
|
} |
||||
|
|
||||
|
var dataSchema = new FilterSchema(FilterSchemaType.Object) |
||||
|
{ |
||||
|
Fields = fields.ToReadonlyList() |
||||
|
}; |
||||
|
|
||||
|
return dataSchema; |
||||
|
} |
||||
|
|
||||
|
private static string FieldPartitionDescription(RootField field, string partition) |
||||
|
{ |
||||
|
var name = field.DisplayName(); |
||||
|
|
||||
|
return string.Format(CultureInfo.InvariantCulture, FieldDescriptions.ContentPartitionField, name, partition); |
||||
|
} |
||||
|
|
||||
|
private static string FieldDescription(string schemaName, RootField field) |
||||
|
{ |
||||
|
var name = field.DisplayName(); |
||||
|
|
||||
|
return string.Format(CultureInfo.InvariantCulture, FieldDescriptions.ContentField, name, schemaName); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,206 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System.Globalization; |
||||
|
using Squidex.Domain.Apps.Core.Contents; |
||||
|
using Squidex.Domain.Apps.Core.Schemas; |
||||
|
using Squidex.Infrastructure; |
||||
|
using Squidex.Infrastructure.Collections; |
||||
|
using Squidex.Infrastructure.Queries; |
||||
|
|
||||
|
#pragma warning disable SA1313 // Parameter names should begin with lower-case letter
|
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Core.GenerateFilters |
||||
|
{ |
||||
|
internal sealed class FilterVisitor : IFieldVisitor<FilterSchema?, FilterVisitor.Args> |
||||
|
{ |
||||
|
private const int MaxDepth = 3; |
||||
|
private static readonly FilterVisitor Instance = new FilterVisitor(); |
||||
|
|
||||
|
public record struct Args(ResolvedComponents Components, int Level = 0); |
||||
|
|
||||
|
private FilterVisitor() |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public static FilterSchema? BuildProperty(IField field, ResolvedComponents components) |
||||
|
{ |
||||
|
var args = new Args(components); |
||||
|
|
||||
|
return field.Accept(Instance, args); |
||||
|
} |
||||
|
|
||||
|
public FilterSchema? Visit(IArrayField field, Args args) |
||||
|
{ |
||||
|
if (args.Level >= MaxDepth) |
||||
|
{ |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
var fields = new List<FilterField>(); |
||||
|
|
||||
|
var nestedArgs = args with { Level = args.Level + 1 }; |
||||
|
|
||||
|
foreach (var nestedField in field.Fields.ForApi(true)) |
||||
|
{ |
||||
|
var nestedSchema = nestedField.Accept(this, nestedArgs); |
||||
|
|
||||
|
if (nestedSchema != null) |
||||
|
{ |
||||
|
var filterableField = new FilterField( |
||||
|
nestedSchema, |
||||
|
nestedField.Name, |
||||
|
ArrayFieldDescription(nestedField), |
||||
|
true); |
||||
|
|
||||
|
fields.Add(filterableField); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return new FilterSchema(FilterSchemaType.ObjectArray) |
||||
|
{ |
||||
|
Fields = fields.ToReadonlyList() |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
public FilterSchema? Visit(IField<AssetsFieldProperties> field, Args args) |
||||
|
{ |
||||
|
return FilterSchema.StringArray; |
||||
|
} |
||||
|
|
||||
|
public FilterSchema? Visit(IField<BooleanFieldProperties> field, Args args) |
||||
|
{ |
||||
|
return FilterSchema.Boolean; |
||||
|
} |
||||
|
|
||||
|
public FilterSchema? Visit(IField<GeolocationFieldProperties> field, Args args) |
||||
|
{ |
||||
|
return FilterSchema.GeoObject; |
||||
|
} |
||||
|
|
||||
|
public FilterSchema? Visit(IField<JsonFieldProperties> field, Args args) |
||||
|
{ |
||||
|
return FilterSchema.Any; |
||||
|
} |
||||
|
|
||||
|
public FilterSchema? Visit(IField<NumberFieldProperties> field, Args args) |
||||
|
{ |
||||
|
return FilterSchema.Number; |
||||
|
} |
||||
|
|
||||
|
public FilterSchema? Visit(IField<StringFieldProperties> field, Args args) |
||||
|
{ |
||||
|
return FilterSchema.String; |
||||
|
} |
||||
|
|
||||
|
public FilterSchema? Visit(IField<TagsFieldProperties> field, Args args) |
||||
|
{ |
||||
|
return FilterSchema.StringArray; |
||||
|
} |
||||
|
|
||||
|
public FilterSchema? Visit(IField<UIFieldProperties> field, Args args) |
||||
|
{ |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
public FilterSchema? Visit(IField<ComponentFieldProperties> field, Args args) |
||||
|
{ |
||||
|
if (args.Level >= MaxDepth) |
||||
|
{ |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
return new FilterSchema(FilterSchemaType.Object) |
||||
|
{ |
||||
|
Fields = BuildComponent(field.Properties.SchemaIds, args) |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
public FilterSchema? Visit(IField<ComponentsFieldProperties> field, Args args) |
||||
|
{ |
||||
|
if (args.Level >= MaxDepth) |
||||
|
{ |
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
return new FilterSchema(FilterSchemaType.Object) |
||||
|
{ |
||||
|
Fields = BuildComponent(field.Properties.SchemaIds, args) |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
public FilterSchema? Visit(IField<DateTimeFieldProperties> field, Args args) |
||||
|
{ |
||||
|
if (field.Properties.Editor == DateTimeFieldEditor.Date) |
||||
|
{ |
||||
|
return SharedSchemas.Date; |
||||
|
} |
||||
|
|
||||
|
return SharedSchemas.DateTime; |
||||
|
} |
||||
|
|
||||
|
public FilterSchema? Visit(IField<ReferencesFieldProperties> field, Args args) |
||||
|
{ |
||||
|
return new FilterSchema(FilterSchemaType.StringArray) |
||||
|
{ |
||||
|
Extra = new |
||||
|
{ |
||||
|
schemaIds = field.Properties.SchemaIds |
||||
|
} |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
private ReadonlyList<FilterField> BuildComponent(ReadonlyList<DomainId>? schemaIds, Args args) |
||||
|
{ |
||||
|
var fields = new List<FilterField>(); |
||||
|
|
||||
|
var nestedArgs = args with { Level = args.Level + 1 }; |
||||
|
|
||||
|
foreach (var schema in args.Components.Resolve(schemaIds).Values) |
||||
|
{ |
||||
|
var componentName = schema.DisplayName(); |
||||
|
|
||||
|
foreach (var field in schema.Fields.ForApi(true)) |
||||
|
{ |
||||
|
var fieldSchema = field.Accept(this, nestedArgs); |
||||
|
|
||||
|
if (fieldSchema != null) |
||||
|
{ |
||||
|
var filterableField = new FilterField( |
||||
|
fieldSchema, |
||||
|
field.Name, |
||||
|
ComponentFieldDescription(componentName, field), |
||||
|
true); |
||||
|
|
||||
|
fields.Add(filterableField); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
fields.Add(new FilterField(FilterSchema.String, Component.Discriminator) |
||||
|
{ |
||||
|
Description = FieldDescriptions.ComponentSchemaId |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
return fields.ToReadonlyList(); |
||||
|
} |
||||
|
|
||||
|
private static string ArrayFieldDescription(IField field) |
||||
|
{ |
||||
|
var name = field.DisplayName(); |
||||
|
|
||||
|
return string.Format(CultureInfo.InvariantCulture, FieldDescriptions.ContentArrayField, name); |
||||
|
} |
||||
|
|
||||
|
private static string ComponentFieldDescription(string componentName, RootField field) |
||||
|
{ |
||||
|
var name = field.DisplayName(); |
||||
|
|
||||
|
return string.Format(CultureInfo.InvariantCulture, FieldDescriptions.ComponentField, name, componentName); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,46 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using Squidex.Infrastructure.Queries; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Core.GenerateFilters |
||||
|
{ |
||||
|
internal static class SharedSchemas |
||||
|
{ |
||||
|
public static readonly FilterSchema Date = new FilterSchema(FilterSchemaType.DateTime) |
||||
|
{ |
||||
|
Extra = new |
||||
|
{ |
||||
|
editor = "Date" |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
public static readonly FilterSchema DateTime = new FilterSchema(FilterSchemaType.DateTime) |
||||
|
{ |
||||
|
Extra = new |
||||
|
{ |
||||
|
editor = "DateTime" |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
public static readonly FilterSchema Status = new FilterSchema(FilterSchemaType.String) |
||||
|
{ |
||||
|
Extra = new |
||||
|
{ |
||||
|
editor = "Status" |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
public static readonly FilterSchema User = new FilterSchema(FilterSchemaType.String) |
||||
|
{ |
||||
|
Extra = new |
||||
|
{ |
||||
|
editor = "User" |
||||
|
} |
||||
|
}; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,306 @@ |
|||||
|
//------------------------------------------------------------------------------
|
||||
|
// <auto-generated>
|
||||
|
// This code was generated by a tool.
|
||||
|
// Runtime Version:4.0.30319.42000
|
||||
|
//
|
||||
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
|
// the code is regenerated.
|
||||
|
// </auto-generated>
|
||||
|
//------------------------------------------------------------------------------
|
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Core.Properties { |
||||
|
using System; |
||||
|
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
|
/// </summary>
|
||||
|
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
|
// class via a tool like ResGen or Visual Studio.
|
||||
|
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
|
// with the /str option, or rebuild your VS project.
|
||||
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] |
||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()] |
||||
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] |
||||
|
internal class Resources { |
||||
|
|
||||
|
private static global::System.Resources.ResourceManager resourceMan; |
||||
|
|
||||
|
private static global::System.Globalization.CultureInfo resourceCulture; |
||||
|
|
||||
|
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] |
||||
|
internal Resources() { |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Returns the cached ResourceManager instance used by this class.
|
||||
|
/// </summary>
|
||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] |
||||
|
internal static global::System.Resources.ResourceManager ResourceManager { |
||||
|
get { |
||||
|
if (object.ReferenceEquals(resourceMan, null)) { |
||||
|
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Squidex.Domain.Apps.Core.Properties.Resources", typeof(Resources).Assembly); |
||||
|
resourceMan = temp; |
||||
|
} |
||||
|
return resourceMan; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Overrides the current thread's CurrentUICulture property for all
|
||||
|
/// resource lookups using this strongly typed resource class.
|
||||
|
/// </summary>
|
||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] |
||||
|
internal static global::System.Globalization.CultureInfo Culture { |
||||
|
get { |
||||
|
return resourceCulture; |
||||
|
} |
||||
|
set { |
||||
|
resourceCulture = value; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The download URL to the asset..
|
||||
|
/// </summary>
|
||||
|
internal static string ScriptingAssetContentAppUrl { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ScriptingAssetContentAppUrl", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The download URL to the asset using the file slug instead of the ID..
|
||||
|
/// </summary>
|
||||
|
internal static string ScriptingAssetContentSlugUrl { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ScriptingAssetContentSlugUrl", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The download URL to the asset without the app name (deprecated)..
|
||||
|
/// </summary>
|
||||
|
internal static string ScriptingAssetContentUrl { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ScriptingAssetContentUrl", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to Counts the number of characters in a text. Useful in combination with html2Text or markdown2Text..
|
||||
|
/// </summary>
|
||||
|
internal static string ScriptingCharacterCount { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ScriptingCharacterCount", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to Completes the script when an async method is used..
|
||||
|
/// </summary>
|
||||
|
internal static string ScriptingComplete { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ScriptingComplete", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The status of the content..
|
||||
|
/// </summary>
|
||||
|
internal static string ScriptingContentAction { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ScriptingContentAction", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to The URL to the content in the UI..
|
||||
|
/// </summary>
|
||||
|
internal static string ScriptingContentUrl { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ScriptingContentUrl", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to Makes a DELETE request to the defined URL and parses the result as JSON. Headers are optional..
|
||||
|
/// </summary>
|
||||
|
internal static string ScriptingDeleteJson { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ScriptingDeleteJson", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to Tell Squidex to not allow the current operation and to return a 403 (Forbidden)..
|
||||
|
/// </summary>
|
||||
|
internal static string ScriptingDisallow { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ScriptingDisallow", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to Formats a JavaScript date object using the specified pattern..
|
||||
|
/// </summary>
|
||||
|
internal static string ScriptingFormatDate { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ScriptingFormatDate", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to Formats a JavaScript date object using the specified pattern..
|
||||
|
/// </summary>
|
||||
|
internal static string ScriptingFormatTime { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ScriptingFormatTime", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to Makes a GET request to the defined URL and parses the result as JSON. Headers are optional..
|
||||
|
/// </summary>
|
||||
|
internal static string ScriptingGetJSON { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ScriptingGetJSON", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to Generates a guid..
|
||||
|
/// </summary>
|
||||
|
internal static string ScriptingGuid { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ScriptingGuid", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to Converts a HTML string to plain text..
|
||||
|
/// </summary>
|
||||
|
internal static string ScriptingHtml2Text { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ScriptingHtml2Text", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to Converts a markdown string to plain text..
|
||||
|
/// </summary>
|
||||
|
internal static string ScriptingMarkdown2Text { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ScriptingMarkdown2Text", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to Calculate the MD5 hash from a given string. Use this method for hashing passwords, when backwards compatibility is important..
|
||||
|
/// </summary>
|
||||
|
internal static string ScriptingMD5 { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ScriptingMD5", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to Makes a PATCH request to the defined URL and parses the result as JSON. Headers are optional..
|
||||
|
/// </summary>
|
||||
|
internal static string ScriptingPatchJson { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ScriptingPatchJson", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to Makes a POST request to the defined URL and parses the result as JSON. Headers are optional..
|
||||
|
/// </summary>
|
||||
|
internal static string ScriptingPostJSON { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ScriptingPostJSON", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to Makes a PUT request to the defined URL and parses the result as JSON. Headers are optional..
|
||||
|
/// </summary>
|
||||
|
internal static string ScriptingPutJson { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ScriptingPutJson", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to Tell Squidex to reject the current operation and to return a 403 (Forbidden)..
|
||||
|
/// </summary>
|
||||
|
internal static string ScriptingReject { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ScriptingReject", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to Tell Squidex that you have modified the data and that the change should be applied..
|
||||
|
/// </summary>
|
||||
|
internal static string ScriptingReplace { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ScriptingReplace", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to Calculate the SHA256 hash from a given string. Use this method for hashing passwords..
|
||||
|
/// </summary>
|
||||
|
internal static string ScriptingSHA256 { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ScriptingSHA256", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to Calculate the SHA256 hash from a given string. Use this method for hashing passwords..
|
||||
|
/// </summary>
|
||||
|
internal static string ScriptingSHA512 { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ScriptingSHA512", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to Calculates the slug of a text by removing all special characters and whitespaces to create a friendly term that can be used for SEO-friendly URLs..
|
||||
|
/// </summary>
|
||||
|
internal static string ScriptingSlugify { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ScriptingSlugify", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to Converts a text to camelCase..
|
||||
|
/// </summary>
|
||||
|
internal static string ScriptingToCamelCase { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ScriptingToCamelCase", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to Converts a text to PascalCase.
|
||||
|
/// </summary>
|
||||
|
internal static string ScriptingToPascalCase { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ScriptingToPascalCase", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to Counts the number of words in a text. Useful in combination with html2Text or markdown2Text..
|
||||
|
/// </summary>
|
||||
|
internal static string ScriptingWordCount { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ScriptingWordCount", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,201 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<root> |
||||
|
<!-- |
||||
|
Microsoft ResX Schema |
||||
|
|
||||
|
Version 2.0 |
||||
|
|
||||
|
The primary goals of this format is to allow a simple XML format |
||||
|
that is mostly human readable. The generation and parsing of the |
||||
|
various data types are done through the TypeConverter classes |
||||
|
associated with the data types. |
||||
|
|
||||
|
Example: |
||||
|
|
||||
|
... ado.net/XML headers & schema ... |
||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader> |
||||
|
<resheader name="version">2.0</resheader> |
||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> |
||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> |
||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> |
||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> |
||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> |
||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value> |
||||
|
</data> |
||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> |
||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> |
||||
|
<comment>This is a comment</comment> |
||||
|
</data> |
||||
|
|
||||
|
There are any number of "resheader" rows that contain simple |
||||
|
name/value pairs. |
||||
|
|
||||
|
Each data row contains a name, and value. The row also contains a |
||||
|
type or mimetype. Type corresponds to a .NET class that support |
||||
|
text/value conversion through the TypeConverter architecture. |
||||
|
Classes that don't support this are serialized and stored with the |
||||
|
mimetype set. |
||||
|
|
||||
|
The mimetype is used for serialized objects, and tells the |
||||
|
ResXResourceReader how to depersist the object. This is currently not |
||||
|
extensible. For a given mimetype the value must be set accordingly: |
||||
|
|
||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format |
||||
|
that the ResXResourceWriter will generate, however the reader can |
||||
|
read any of the formats listed below. |
||||
|
|
||||
|
mimetype: application/x-microsoft.net.object.binary.base64 |
||||
|
value : The object must be serialized with |
||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter |
||||
|
: and then encoded with base64 encoding. |
||||
|
|
||||
|
mimetype: application/x-microsoft.net.object.soap.base64 |
||||
|
value : The object must be serialized with |
||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter |
||||
|
: and then encoded with base64 encoding. |
||||
|
|
||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64 |
||||
|
value : The object must be serialized into a byte array |
||||
|
: using a System.ComponentModel.TypeConverter |
||||
|
: and then encoded with base64 encoding. |
||||
|
--> |
||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> |
||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> |
||||
|
<xsd:element name="root" msdata:IsDataSet="true"> |
||||
|
<xsd:complexType> |
||||
|
<xsd:choice maxOccurs="unbounded"> |
||||
|
<xsd:element name="metadata"> |
||||
|
<xsd:complexType> |
||||
|
<xsd:sequence> |
||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" /> |
||||
|
</xsd:sequence> |
||||
|
<xsd:attribute name="name" use="required" type="xsd:string" /> |
||||
|
<xsd:attribute name="type" type="xsd:string" /> |
||||
|
<xsd:attribute name="mimetype" type="xsd:string" /> |
||||
|
<xsd:attribute ref="xml:space" /> |
||||
|
</xsd:complexType> |
||||
|
</xsd:element> |
||||
|
<xsd:element name="assembly"> |
||||
|
<xsd:complexType> |
||||
|
<xsd:attribute name="alias" type="xsd:string" /> |
||||
|
<xsd:attribute name="name" type="xsd:string" /> |
||||
|
</xsd:complexType> |
||||
|
</xsd:element> |
||||
|
<xsd:element name="data"> |
||||
|
<xsd:complexType> |
||||
|
<xsd:sequence> |
||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> |
||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> |
||||
|
</xsd:sequence> |
||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> |
||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> |
||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> |
||||
|
<xsd:attribute ref="xml:space" /> |
||||
|
</xsd:complexType> |
||||
|
</xsd:element> |
||||
|
<xsd:element name="resheader"> |
||||
|
<xsd:complexType> |
||||
|
<xsd:sequence> |
||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> |
||||
|
</xsd:sequence> |
||||
|
<xsd:attribute name="name" type="xsd:string" use="required" /> |
||||
|
</xsd:complexType> |
||||
|
</xsd:element> |
||||
|
</xsd:choice> |
||||
|
</xsd:complexType> |
||||
|
</xsd:element> |
||||
|
</xsd:schema> |
||||
|
<resheader name="resmimetype"> |
||||
|
<value>text/microsoft-resx</value> |
||||
|
</resheader> |
||||
|
<resheader name="version"> |
||||
|
<value>2.0</value> |
||||
|
</resheader> |
||||
|
<resheader name="reader"> |
||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> |
||||
|
</resheader> |
||||
|
<resheader name="writer"> |
||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> |
||||
|
</resheader> |
||||
|
<data name="ScriptingAssetContentAppUrl" xml:space="preserve"> |
||||
|
<value>The download URL to the asset.</value> |
||||
|
</data> |
||||
|
<data name="ScriptingAssetContentSlugUrl" xml:space="preserve"> |
||||
|
<value>The download URL to the asset using the file slug instead of the ID.</value> |
||||
|
</data> |
||||
|
<data name="ScriptingAssetContentUrl" xml:space="preserve"> |
||||
|
<value>The download URL to the asset without the app name (deprecated).</value> |
||||
|
</data> |
||||
|
<data name="ScriptingCharacterCount" xml:space="preserve"> |
||||
|
<value>Counts the number of characters in a text. Useful in combination with html2Text or markdown2Text.</value> |
||||
|
</data> |
||||
|
<data name="ScriptingComplete" xml:space="preserve"> |
||||
|
<value>Completes the script when an async method is used.</value> |
||||
|
</data> |
||||
|
<data name="ScriptingContentAction" xml:space="preserve"> |
||||
|
<value>The status of the content.</value> |
||||
|
</data> |
||||
|
<data name="ScriptingContentUrl" xml:space="preserve"> |
||||
|
<value>The URL to the content in the UI.</value> |
||||
|
</data> |
||||
|
<data name="ScriptingDeleteJson" xml:space="preserve"> |
||||
|
<value>Makes a DELETE request to the defined URL and parses the result as JSON. Headers are optional.</value> |
||||
|
</data> |
||||
|
<data name="ScriptingDisallow" xml:space="preserve"> |
||||
|
<value>Tell Squidex to not allow the current operation and to return a 403 (Forbidden).</value> |
||||
|
</data> |
||||
|
<data name="ScriptingFormatDate" xml:space="preserve"> |
||||
|
<value>Formats a JavaScript date object using the specified pattern.</value> |
||||
|
</data> |
||||
|
<data name="ScriptingFormatTime" xml:space="preserve"> |
||||
|
<value>Formats a JavaScript date object using the specified pattern.</value> |
||||
|
</data> |
||||
|
<data name="ScriptingGetJSON" xml:space="preserve"> |
||||
|
<value>Makes a GET request to the defined URL and parses the result as JSON. Headers are optional.</value> |
||||
|
</data> |
||||
|
<data name="ScriptingGuid" xml:space="preserve"> |
||||
|
<value>Generates a guid.</value> |
||||
|
</data> |
||||
|
<data name="ScriptingHtml2Text" xml:space="preserve"> |
||||
|
<value>Converts a HTML string to plain text.</value> |
||||
|
</data> |
||||
|
<data name="ScriptingMarkdown2Text" xml:space="preserve"> |
||||
|
<value>Converts a markdown string to plain text.</value> |
||||
|
</data> |
||||
|
<data name="ScriptingMD5" xml:space="preserve"> |
||||
|
<value>Calculate the MD5 hash from a given string. Use this method for hashing passwords, when backwards compatibility is important.</value> |
||||
|
</data> |
||||
|
<data name="ScriptingPatchJson" xml:space="preserve"> |
||||
|
<value>Makes a PATCH request to the defined URL and parses the result as JSON. Headers are optional.</value> |
||||
|
</data> |
||||
|
<data name="ScriptingPostJSON" xml:space="preserve"> |
||||
|
<value>Makes a POST request to the defined URL and parses the result as JSON. Headers are optional.</value> |
||||
|
</data> |
||||
|
<data name="ScriptingPutJson" xml:space="preserve"> |
||||
|
<value>Makes a PUT request to the defined URL and parses the result as JSON. Headers are optional.</value> |
||||
|
</data> |
||||
|
<data name="ScriptingReject" xml:space="preserve"> |
||||
|
<value>Tell Squidex to reject the current operation and to return a 403 (Forbidden).</value> |
||||
|
</data> |
||||
|
<data name="ScriptingReplace" xml:space="preserve"> |
||||
|
<value>Tell Squidex that you have modified the data and that the change should be applied.</value> |
||||
|
</data> |
||||
|
<data name="ScriptingSHA256" xml:space="preserve"> |
||||
|
<value>Calculate the SHA256 hash from a given string. Use this method for hashing passwords.</value> |
||||
|
</data> |
||||
|
<data name="ScriptingSHA512" xml:space="preserve"> |
||||
|
<value>Calculate the SHA256 hash from a given string. Use this method for hashing passwords.</value> |
||||
|
</data> |
||||
|
<data name="ScriptingSlugify" xml:space="preserve"> |
||||
|
<value>Calculates the slug of a text by removing all special characters and whitespaces to create a friendly term that can be used for SEO-friendly URLs.</value> |
||||
|
</data> |
||||
|
<data name="ScriptingToCamelCase" xml:space="preserve"> |
||||
|
<value>Converts a text to camelCase.</value> |
||||
|
</data> |
||||
|
<data name="ScriptingToPascalCase" xml:space="preserve"> |
||||
|
<value>Converts a text to PascalCase</value> |
||||
|
</data> |
||||
|
<data name="ScriptingWordCount" xml:space="preserve"> |
||||
|
<value>Counts the number of words in a text. Useful in combination with html2Text or markdown2Text.</value> |
||||
|
</data> |
||||
|
</root> |
||||
@ -0,0 +1,16 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Core.Scripting |
||||
|
{ |
||||
|
public delegate void AddDescription(JsonType type, string name, string description); |
||||
|
|
||||
|
public interface IScriptDescriptor |
||||
|
{ |
||||
|
void Describe(AddDescription describe, ScriptScope scope); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,19 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Core.Scripting |
||||
|
{ |
||||
|
[Flags] |
||||
|
public enum ScriptScope |
||||
|
{ |
||||
|
AssetScript, |
||||
|
AssetTrigger, |
||||
|
ContentScript, |
||||
|
ContentTrigger, |
||||
|
Transform |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,307 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using Squidex.Infrastructure; |
||||
|
using Squidex.Infrastructure.Queries; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Core.Scripting |
||||
|
{ |
||||
|
public sealed class ScriptingCompleter |
||||
|
{ |
||||
|
private readonly IEnumerable<IScriptDescriptor> descriptors; |
||||
|
|
||||
|
public ScriptingCompleter(IEnumerable<IScriptDescriptor> descriptors) |
||||
|
{ |
||||
|
this.descriptors = descriptors; |
||||
|
} |
||||
|
|
||||
|
public IReadOnlyList<ScriptingValue> ContentScript(FilterSchema dataSchema) |
||||
|
{ |
||||
|
Guard.NotNull(dataSchema, nameof(dataSchema)); |
||||
|
|
||||
|
return new Process(descriptors).Content(dataSchema, ScriptScope.ContentScript | ScriptScope.Transform); |
||||
|
} |
||||
|
|
||||
|
public IReadOnlyList<ScriptingValue> ContentTrigger(FilterSchema dataSchema) |
||||
|
{ |
||||
|
Guard.NotNull(dataSchema, nameof(dataSchema)); |
||||
|
|
||||
|
return new Process(descriptors).Content(dataSchema, ScriptScope.ContentTrigger); |
||||
|
} |
||||
|
|
||||
|
public IReadOnlyList<ScriptingValue> AssetScript() |
||||
|
{ |
||||
|
return new Process(descriptors).Asset(ScriptScope.AssetScript); |
||||
|
} |
||||
|
|
||||
|
public IReadOnlyList<ScriptingValue> AssetTrigger() |
||||
|
{ |
||||
|
return new Process(descriptors).Asset(ScriptScope.AssetTrigger); |
||||
|
} |
||||
|
|
||||
|
private sealed class Process |
||||
|
{ |
||||
|
private readonly Stack<string> prefixes = new Stack<string>(); |
||||
|
private readonly HashSet<ScriptingValue> result = new HashSet<ScriptingValue>(); |
||||
|
private readonly IEnumerable<IScriptDescriptor> descriptors; |
||||
|
|
||||
|
public Process(IEnumerable<IScriptDescriptor> descriptors) |
||||
|
{ |
||||
|
this.descriptors = descriptors; |
||||
|
} |
||||
|
|
||||
|
public IReadOnlyList<ScriptingValue> Content(FilterSchema dataSchema, ScriptScope scope) |
||||
|
{ |
||||
|
AddShared(scope); |
||||
|
|
||||
|
AddObject("ctx", FieldDescriptions.Context, () => |
||||
|
{ |
||||
|
AddString("contentId", |
||||
|
FieldDescriptions.EntityId); |
||||
|
|
||||
|
AddString("status", |
||||
|
FieldDescriptions.ContentStatus); |
||||
|
|
||||
|
AddString("statusOld", |
||||
|
FieldDescriptions.ContentStatusOld); |
||||
|
|
||||
|
AddObject("data", FieldDescriptions.ContentData, () => |
||||
|
{ |
||||
|
AddData(dataSchema); |
||||
|
}); |
||||
|
|
||||
|
AddObject("dataOld", FieldDescriptions.ContentDataOld, () => |
||||
|
{ |
||||
|
AddData(dataSchema); |
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
return result.OrderBy(x => x.Path).ToList(); |
||||
|
} |
||||
|
|
||||
|
public IReadOnlyList<ScriptingValue> Asset(ScriptScope scope) |
||||
|
{ |
||||
|
AddShared(scope); |
||||
|
|
||||
|
AddObject("ctx", FieldDescriptions.Context, () => |
||||
|
{ |
||||
|
AddString("assetId", |
||||
|
FieldDescriptions.EntityId); |
||||
|
|
||||
|
AddObject("asset", |
||||
|
FieldDescriptions.Asset, () => |
||||
|
{ |
||||
|
AddSharedAsset(); |
||||
|
|
||||
|
AddNumber("fileVersion", |
||||
|
FieldDescriptions.AssetFileVersion); |
||||
|
}); |
||||
|
|
||||
|
AddObject("command", |
||||
|
FieldDescriptions.Command, () => |
||||
|
{ |
||||
|
AddSharedAsset(); |
||||
|
|
||||
|
AddBoolean("permanent", |
||||
|
FieldDescriptions.EntityRequestDeletePermanent); |
||||
|
}); |
||||
|
}); |
||||
|
|
||||
|
return result.OrderBy(x => x.Path).ToList(); |
||||
|
} |
||||
|
|
||||
|
private void AddSharedAsset() |
||||
|
{ |
||||
|
AddString("fileHash", |
||||
|
FieldDescriptions.AssetFileHash); |
||||
|
|
||||
|
AddString("fileName", |
||||
|
FieldDescriptions.AssetFileName); |
||||
|
|
||||
|
AddString("fileSize", |
||||
|
FieldDescriptions.AssetFileSize); |
||||
|
|
||||
|
AddString("fileSlug", |
||||
|
FieldDescriptions.AssetSlug); |
||||
|
|
||||
|
AddString("mimeType", |
||||
|
FieldDescriptions.AssetMimeType); |
||||
|
|
||||
|
AddBoolean("isProtected", |
||||
|
FieldDescriptions.AssetIsProtected); |
||||
|
|
||||
|
AddString("parentId", |
||||
|
FieldDescriptions.AssetParentId); |
||||
|
|
||||
|
AddArray("parentPath", |
||||
|
FieldDescriptions.AssetParentPath); |
||||
|
|
||||
|
AddArray("tags", |
||||
|
FieldDescriptions.AssetTags); |
||||
|
|
||||
|
AddObject("metadata", |
||||
|
FieldDescriptions.AssetMetadata, () => |
||||
|
{ |
||||
|
AddArray("name", |
||||
|
FieldDescriptions.AssetMetadataValue); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private void AddShared(ScriptScope scope) |
||||
|
{ |
||||
|
foreach (var descriptor in descriptors) |
||||
|
{ |
||||
|
descriptor.Describe(Add, scope); |
||||
|
} |
||||
|
|
||||
|
AddString("appId", |
||||
|
FieldDescriptions.AppId); |
||||
|
|
||||
|
AddString("appName", |
||||
|
FieldDescriptions.AppName); |
||||
|
|
||||
|
AddString("operation", |
||||
|
FieldDescriptions.Operation); |
||||
|
|
||||
|
AddObject("user", |
||||
|
FieldDescriptions.User, () => |
||||
|
{ |
||||
|
AddString("id", |
||||
|
FieldDescriptions.UserId); |
||||
|
|
||||
|
AddString("email", |
||||
|
FieldDescriptions.UserEmail); |
||||
|
|
||||
|
AddBoolean("isClient", |
||||
|
FieldDescriptions.UserIsClient); |
||||
|
|
||||
|
AddBoolean("isUser", |
||||
|
FieldDescriptions.UserIsUser); |
||||
|
|
||||
|
AddObject("claims", |
||||
|
FieldDescriptions.UserClaims, () => |
||||
|
{ |
||||
|
AddArray("name", |
||||
|
FieldDescriptions.UsersClaimsValue); |
||||
|
}); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
private void AddData(FilterSchema dataSchema) |
||||
|
{ |
||||
|
if (dataSchema.Fields == null) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
foreach (var field in dataSchema.Fields) |
||||
|
{ |
||||
|
switch (field.Schema.Type) |
||||
|
{ |
||||
|
case FilterSchemaType.Any: |
||||
|
AddAny(field.Path, field.Description); |
||||
|
break; |
||||
|
case FilterSchemaType.Boolean: |
||||
|
AddBoolean(field.Path, field.Description); |
||||
|
break; |
||||
|
case FilterSchemaType.DateTime: |
||||
|
AddString(field.Path, field.Description); |
||||
|
break; |
||||
|
case FilterSchemaType.GeoObject: |
||||
|
AddObject(field.Path, field.Description); |
||||
|
break; |
||||
|
case FilterSchemaType.Guid: |
||||
|
AddString(field.Path, field.Description); |
||||
|
break; |
||||
|
case FilterSchemaType.Number: |
||||
|
AddNumber(field.Path, field.Description); |
||||
|
break; |
||||
|
case FilterSchemaType.Object: |
||||
|
AddObject(field.Path, field.Description); |
||||
|
break; |
||||
|
case FilterSchemaType.ObjectArray: |
||||
|
AddArray(field.Path, field.Description); |
||||
|
break; |
||||
|
case FilterSchemaType.String: |
||||
|
AddString(field.Path, field.Description); |
||||
|
break; |
||||
|
case FilterSchemaType.StringArray: |
||||
|
AddArray(field.Path, field.Description); |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private void AddAny(string? name, string? description) |
||||
|
{ |
||||
|
Add(JsonType.Any, name, description); |
||||
|
} |
||||
|
|
||||
|
private void AddArray(string? name, string? description) |
||||
|
{ |
||||
|
Add(JsonType.Array, name, description); |
||||
|
} |
||||
|
|
||||
|
private void AddBoolean(string? name, string? description) |
||||
|
{ |
||||
|
Add(JsonType.Boolean, name, description); |
||||
|
} |
||||
|
|
||||
|
private void AddObject(string? name, string? description) |
||||
|
{ |
||||
|
Add(JsonType.Object, name, description); |
||||
|
} |
||||
|
|
||||
|
private void AddNumber(string? name, string? description) |
||||
|
{ |
||||
|
Add(JsonType.Number, name, description); |
||||
|
} |
||||
|
|
||||
|
private void AddString(string? name, string? description) |
||||
|
{ |
||||
|
Add(JsonType.String, name, description); |
||||
|
} |
||||
|
|
||||
|
private void Add(JsonType type, string? name, string? description) |
||||
|
{ |
||||
|
if (name != null) |
||||
|
{ |
||||
|
prefixes.Push(name); |
||||
|
} |
||||
|
|
||||
|
if (prefixes.Count == 0) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
var path = string.Join('.', prefixes.Reverse()); |
||||
|
|
||||
|
result.Add(new ScriptingValue(path, type, description)); |
||||
|
|
||||
|
if (name != null) |
||||
|
{ |
||||
|
prefixes.Pop(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private void AddObject(string name, string description, Action inner) |
||||
|
{ |
||||
|
Add(JsonType.Object, name, description); |
||||
|
|
||||
|
prefixes.Push(name); |
||||
|
try |
||||
|
{ |
||||
|
inner(); |
||||
|
} |
||||
|
finally |
||||
|
{ |
||||
|
prefixes.Pop(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,126 @@ |
|||||
|
//------------------------------------------------------------------------------
|
||||
|
// <auto-generated>
|
||||
|
// This code was generated by a tool.
|
||||
|
// Runtime Version:4.0.30319.42000
|
||||
|
//
|
||||
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
|
// the code is regenerated.
|
||||
|
// </auto-generated>
|
||||
|
//------------------------------------------------------------------------------
|
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Entities.Properties { |
||||
|
using System; |
||||
|
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
|
/// </summary>
|
||||
|
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
|
// class via a tool like ResGen or Visual Studio.
|
||||
|
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
|
// with the /str option, or rebuild your VS project.
|
||||
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] |
||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()] |
||||
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] |
||||
|
internal class Resources { |
||||
|
|
||||
|
private static global::System.Resources.ResourceManager resourceMan; |
||||
|
|
||||
|
private static global::System.Globalization.CultureInfo resourceCulture; |
||||
|
|
||||
|
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] |
||||
|
internal Resources() { |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Returns the cached ResourceManager instance used by this class.
|
||||
|
/// </summary>
|
||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] |
||||
|
internal static global::System.Resources.ResourceManager ResourceManager { |
||||
|
get { |
||||
|
if (object.ReferenceEquals(resourceMan, null)) { |
||||
|
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Squidex.Domain.Apps.Entities.Properties.Resources", typeof(Resources).Assembly); |
||||
|
resourceMan = temp; |
||||
|
} |
||||
|
return resourceMan; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Overrides the current thread's CurrentUICulture property for all
|
||||
|
/// resource lookups using this strongly typed resource class.
|
||||
|
/// </summary>
|
||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] |
||||
|
internal static global::System.Globalization.CultureInfo Culture { |
||||
|
get { |
||||
|
return resourceCulture; |
||||
|
} |
||||
|
set { |
||||
|
resourceCulture = value; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to Queries the asset with the specified ID and invokes the callback with an array of assets..
|
||||
|
/// </summary>
|
||||
|
internal static string ScriptingGetAsset { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ScriptingGetAsset", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to ueries the assets with the specified IDs and invokes the callback with an array of assets..
|
||||
|
/// </summary>
|
||||
|
internal static string ScriptingGetAssets { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ScriptingGetAssets", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to Get the text of an asset. Encodings: base64,ascii,unicode,utf8.
|
||||
|
/// </summary>
|
||||
|
internal static string ScriptingGetAssetText { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ScriptingGetAssetText", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to Queries the content item with the specified ID and invokes the callback with an array of contents..
|
||||
|
/// </summary>
|
||||
|
internal static string ScriptingGetReference { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ScriptingGetReference", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to Queries the content items with the specified IDs and invokes the callback with an array of contents..
|
||||
|
/// </summary>
|
||||
|
internal static string ScriptingGetReferences { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ScriptingGetReferences", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to Increments the counter with the given name and returns the value..
|
||||
|
/// </summary>
|
||||
|
internal static string ScriptingIncrementCounter { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ScriptingIncrementCounter", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to Resets the counter with the given name to zero..
|
||||
|
/// </summary>
|
||||
|
internal static string ScriptingResetCounter { |
||||
|
get { |
||||
|
return ResourceManager.GetString("ScriptingResetCounter", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,141 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<root> |
||||
|
<!-- |
||||
|
Microsoft ResX Schema |
||||
|
|
||||
|
Version 2.0 |
||||
|
|
||||
|
The primary goals of this format is to allow a simple XML format |
||||
|
that is mostly human readable. The generation and parsing of the |
||||
|
various data types are done through the TypeConverter classes |
||||
|
associated with the data types. |
||||
|
|
||||
|
Example: |
||||
|
|
||||
|
... ado.net/XML headers & schema ... |
||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader> |
||||
|
<resheader name="version">2.0</resheader> |
||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> |
||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> |
||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> |
||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> |
||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> |
||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value> |
||||
|
</data> |
||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> |
||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> |
||||
|
<comment>This is a comment</comment> |
||||
|
</data> |
||||
|
|
||||
|
There are any number of "resheader" rows that contain simple |
||||
|
name/value pairs. |
||||
|
|
||||
|
Each data row contains a name, and value. The row also contains a |
||||
|
type or mimetype. Type corresponds to a .NET class that support |
||||
|
text/value conversion through the TypeConverter architecture. |
||||
|
Classes that don't support this are serialized and stored with the |
||||
|
mimetype set. |
||||
|
|
||||
|
The mimetype is used for serialized objects, and tells the |
||||
|
ResXResourceReader how to depersist the object. This is currently not |
||||
|
extensible. For a given mimetype the value must be set accordingly: |
||||
|
|
||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format |
||||
|
that the ResXResourceWriter will generate, however the reader can |
||||
|
read any of the formats listed below. |
||||
|
|
||||
|
mimetype: application/x-microsoft.net.object.binary.base64 |
||||
|
value : The object must be serialized with |
||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter |
||||
|
: and then encoded with base64 encoding. |
||||
|
|
||||
|
mimetype: application/x-microsoft.net.object.soap.base64 |
||||
|
value : The object must be serialized with |
||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter |
||||
|
: and then encoded with base64 encoding. |
||||
|
|
||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64 |
||||
|
value : The object must be serialized into a byte array |
||||
|
: using a System.ComponentModel.TypeConverter |
||||
|
: and then encoded with base64 encoding. |
||||
|
--> |
||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> |
||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> |
||||
|
<xsd:element name="root" msdata:IsDataSet="true"> |
||||
|
<xsd:complexType> |
||||
|
<xsd:choice maxOccurs="unbounded"> |
||||
|
<xsd:element name="metadata"> |
||||
|
<xsd:complexType> |
||||
|
<xsd:sequence> |
||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" /> |
||||
|
</xsd:sequence> |
||||
|
<xsd:attribute name="name" use="required" type="xsd:string" /> |
||||
|
<xsd:attribute name="type" type="xsd:string" /> |
||||
|
<xsd:attribute name="mimetype" type="xsd:string" /> |
||||
|
<xsd:attribute ref="xml:space" /> |
||||
|
</xsd:complexType> |
||||
|
</xsd:element> |
||||
|
<xsd:element name="assembly"> |
||||
|
<xsd:complexType> |
||||
|
<xsd:attribute name="alias" type="xsd:string" /> |
||||
|
<xsd:attribute name="name" type="xsd:string" /> |
||||
|
</xsd:complexType> |
||||
|
</xsd:element> |
||||
|
<xsd:element name="data"> |
||||
|
<xsd:complexType> |
||||
|
<xsd:sequence> |
||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> |
||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> |
||||
|
</xsd:sequence> |
||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> |
||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> |
||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> |
||||
|
<xsd:attribute ref="xml:space" /> |
||||
|
</xsd:complexType> |
||||
|
</xsd:element> |
||||
|
<xsd:element name="resheader"> |
||||
|
<xsd:complexType> |
||||
|
<xsd:sequence> |
||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> |
||||
|
</xsd:sequence> |
||||
|
<xsd:attribute name="name" type="xsd:string" use="required" /> |
||||
|
</xsd:complexType> |
||||
|
</xsd:element> |
||||
|
</xsd:choice> |
||||
|
</xsd:complexType> |
||||
|
</xsd:element> |
||||
|
</xsd:schema> |
||||
|
<resheader name="resmimetype"> |
||||
|
<value>text/microsoft-resx</value> |
||||
|
</resheader> |
||||
|
<resheader name="version"> |
||||
|
<value>2.0</value> |
||||
|
</resheader> |
||||
|
<resheader name="reader"> |
||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> |
||||
|
</resheader> |
||||
|
<resheader name="writer"> |
||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> |
||||
|
</resheader> |
||||
|
<data name="ScriptingGetAsset" xml:space="preserve"> |
||||
|
<value>Queries the asset with the specified ID and invokes the callback with an array of assets.</value> |
||||
|
</data> |
||||
|
<data name="ScriptingGetAssets" xml:space="preserve"> |
||||
|
<value>ueries the assets with the specified IDs and invokes the callback with an array of assets.</value> |
||||
|
</data> |
||||
|
<data name="ScriptingGetAssetText" xml:space="preserve"> |
||||
|
<value>Get the text of an asset. Encodings: base64,ascii,unicode,utf8</value> |
||||
|
</data> |
||||
|
<data name="ScriptingGetReference" xml:space="preserve"> |
||||
|
<value>Queries the content item with the specified ID and invokes the callback with an array of contents.</value> |
||||
|
</data> |
||||
|
<data name="ScriptingGetReferences" xml:space="preserve"> |
||||
|
<value>Queries the content items with the specified IDs and invokes the callback with an array of contents.</value> |
||||
|
</data> |
||||
|
<data name="ScriptingIncrementCounter" xml:space="preserve"> |
||||
|
<value>Increments the counter with the given name and returns the value.</value> |
||||
|
</data> |
||||
|
<data name="ScriptingResetCounter" xml:space="preserve"> |
||||
|
<value>Resets the counter with the given name to zero.</value> |
||||
|
</data> |
||||
|
</root> |
||||
@ -1,313 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using Squidex.Domain.Apps.Core; |
|
||||
using Squidex.Domain.Apps.Core.Schemas; |
|
||||
|
|
||||
namespace Squidex.Domain.Apps.Entities.Scripting |
|
||||
{ |
|
||||
public sealed class ScriptingCompletion |
|
||||
{ |
|
||||
private readonly Stack<string> prefixes = new Stack<string>(); |
|
||||
private readonly HashSet<ScriptingValue> result = new HashSet<ScriptingValue>(); |
|
||||
|
|
||||
public IReadOnlyList<ScriptingValue> Content(Schema schema, PartitionResolver partitionResolver) |
|
||||
{ |
|
||||
AddFunction("replace()", |
|
||||
"Tell Squidex that you have modified the data and that the change should be applied."); |
|
||||
|
|
||||
AddFunction("getReferences(ids, callback)", |
|
||||
"Queries the content items with the specified IDs and invokes the callback with an array of contents."); |
|
||||
|
|
||||
AddFunction("getReference(ids, callback)", |
|
||||
"Queries the content item with the specified ID and invokes the callback with an array of contents."); |
|
||||
|
|
||||
AddFunction("getAssets(ids, callback)", |
|
||||
"Queries the assets with the specified IDs and invokes the callback with an array of assets."); |
|
||||
|
|
||||
AddFunction("getAsset(ids, callback)", |
|
||||
"Queries the asset with the specified ID and invokes the callback with an array of assets."); |
|
||||
|
|
||||
AddShared(); |
|
||||
|
|
||||
AddObject("ctx", FieldDescriptions.Context, () => |
|
||||
{ |
|
||||
AddString("contentId", |
|
||||
FieldDescriptions.EntityId); |
|
||||
|
|
||||
AddString("status", |
|
||||
FieldDescriptions.ContentStatus); |
|
||||
|
|
||||
AddString("statusOld", |
|
||||
FieldDescriptions.ContentStatusOld); |
|
||||
|
|
||||
AddObject("data", FieldDescriptions.ContentData, () => |
|
||||
{ |
|
||||
AddData(schema, partitionResolver); |
|
||||
}); |
|
||||
|
|
||||
AddObject("dataOld", FieldDescriptions.ContentDataOld, () => |
|
||||
{ |
|
||||
AddData(schema, partitionResolver); |
|
||||
}); |
|
||||
}); |
|
||||
|
|
||||
return result.OrderBy(x => x.Path).ToList(); |
|
||||
} |
|
||||
|
|
||||
public IReadOnlyList<ScriptingValue> Asset() |
|
||||
{ |
|
||||
AddShared(); |
|
||||
|
|
||||
AddObject("ctx", FieldDescriptions.Context, () => |
|
||||
{ |
|
||||
AddString("assetId", |
|
||||
FieldDescriptions.EntityId); |
|
||||
|
|
||||
AddObject("asset", |
|
||||
FieldDescriptions.Asset, () => |
|
||||
{ |
|
||||
AddSharedAsset(); |
|
||||
|
|
||||
AddNumber("fileVersion", |
|
||||
FieldDescriptions.AssetFileVersion); |
|
||||
}); |
|
||||
|
|
||||
AddObject("command", |
|
||||
FieldDescriptions.Command, () => |
|
||||
{ |
|
||||
AddSharedAsset(); |
|
||||
|
|
||||
AddBoolean("permanent", |
|
||||
FieldDescriptions.EntityRequestDeletePermanent); |
|
||||
}); |
|
||||
}); |
|
||||
|
|
||||
return result.OrderBy(x => x.Path).ToList(); |
|
||||
} |
|
||||
|
|
||||
private void AddSharedAsset() |
|
||||
{ |
|
||||
AddString("fileHash", |
|
||||
FieldDescriptions.AssetFileHash); |
|
||||
|
|
||||
AddString("fileName", |
|
||||
FieldDescriptions.AssetFileName); |
|
||||
|
|
||||
AddString("fileSize", |
|
||||
FieldDescriptions.AssetFileSize); |
|
||||
|
|
||||
AddString("fileSlug", |
|
||||
FieldDescriptions.AssetSlug); |
|
||||
|
|
||||
AddString("mimeType", |
|
||||
FieldDescriptions.AssetMimeType); |
|
||||
|
|
||||
AddBoolean("isProtected", |
|
||||
FieldDescriptions.AssetIsProtected); |
|
||||
|
|
||||
AddString("parentId", |
|
||||
FieldDescriptions.AssetParentId); |
|
||||
|
|
||||
AddArray("parentPath", |
|
||||
FieldDescriptions.AssetParentPath); |
|
||||
|
|
||||
AddArray("tags", |
|
||||
FieldDescriptions.AssetTags); |
|
||||
|
|
||||
AddObject("metadata", |
|
||||
FieldDescriptions.AssetMetadata, () => |
|
||||
{ |
|
||||
AddArray("name", |
|
||||
FieldDescriptions.AssetMetadataValue); |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
private void AddShared() |
|
||||
{ |
|
||||
AddFunction("disallow()", |
|
||||
"Tell Squidex to not allow the current operation and to return a 403 (Forbidden)."); |
|
||||
|
|
||||
AddFunction("reject('Reason')", |
|
||||
"Tell Squidex to reject the current operation and to return a 403 (Forbidden)."); |
|
||||
|
|
||||
AddFunction("html2Text(text)", |
|
||||
"Converts a HTML string to plain text."); |
|
||||
|
|
||||
AddFunction("markdown2Text(text)", |
|
||||
"Converts a markdown string to plain text."); |
|
||||
|
|
||||
AddFunction("formatDate(data, pattern)", |
|
||||
"Formats a JavaScript date object using the specified pattern."); |
|
||||
|
|
||||
AddFunction("formatTime(text)", |
|
||||
"Formats a JavaScript date object using the specified pattern."); |
|
||||
|
|
||||
AddFunction("wordCount(text)", |
|
||||
"Counts the number of words in a text. Useful in combination with html2Text or markdown2Text."); |
|
||||
|
|
||||
AddFunction("characterCount(text)", |
|
||||
"Counts the number of characters in a text. Useful in combination with html2Text or markdown2Text."); |
|
||||
|
|
||||
AddFunction("toCamelCase(text)", |
|
||||
"Converts a text to camelCase."); |
|
||||
|
|
||||
AddFunction("toPascalCase(text)", |
|
||||
"Calculate the SHA256 hash from a given string. Use this method for hashing passwords"); |
|
||||
|
|
||||
AddFunction("sha256(text)", |
|
||||
"Calculate the MD5 hash from a given string. Use this method for hashing passwords, when backwards compatibility is important."); |
|
||||
|
|
||||
AddFunction("slugify(text)", |
|
||||
"Calculates the slug of a text by removing all special characters and whitespaces to create a friendly term that can be used for SEO-friendly URLs."); |
|
||||
|
|
||||
AddFunction("slugify(text)", |
|
||||
"Calculates the slug of a text by removing all special characters and whitespaces to create a friendly term that can be used for SEO-friendly URLs."); |
|
||||
|
|
||||
AddFunction("slugify(text)", |
|
||||
"Calculates the slug of a text by removing all special characters and whitespaces to create a friendly term that can be used for SEO-friendly URLs."); |
|
||||
|
|
||||
AddFunction("slugify(text)", |
|
||||
"Calculates the slug of a text by removing all special characters and whitespaces to create a friendly term that can be used for SEO-friendly URLs."); |
|
||||
|
|
||||
AddFunction("getJSON(url, callback, ?headers)", |
|
||||
"Makes a GET request to the defined URL and parses the result as JSON. Headers are optional."); |
|
||||
|
|
||||
AddFunction("postJSON(url, body, callback, ?headers)", |
|
||||
"Makes a POST request to the defined URL and parses the result as JSON. Headers are optional."); |
|
||||
|
|
||||
AddFunction("putJSON(url, body, callback, ?headers)", |
|
||||
"Makes a PUT request to the defined URL and parses the result as JSON. Headers are optional."); |
|
||||
|
|
||||
AddFunction("putJSON(url, body, callback, ?headers)", |
|
||||
"Makes a PUT request to the defined URL and parses the result as JSON. Headers are optional."); |
|
||||
|
|
||||
AddFunction("patchJSON(url, body, callback, headers)", |
|
||||
"Makes a PATCH request to the defined URL and parses the result as JSON. Headers are optional."); |
|
||||
|
|
||||
AddFunction("deleteJSON(url, body, callback, headers)", |
|
||||
"Makes a DELETE request to the defined URL and parses the result as JSON. Headers are optional."); |
|
||||
|
|
||||
AddString("appId", |
|
||||
FieldDescriptions.AppId); |
|
||||
|
|
||||
AddString("appName", |
|
||||
FieldDescriptions.AppName); |
|
||||
|
|
||||
AddString("operation", |
|
||||
FieldDescriptions.Operation); |
|
||||
|
|
||||
AddObject("user", |
|
||||
FieldDescriptions.User, () => |
|
||||
{ |
|
||||
AddString("id", |
|
||||
FieldDescriptions.UserId); |
|
||||
|
|
||||
AddString("email", |
|
||||
FieldDescriptions.UserEmail); |
|
||||
|
|
||||
AddBoolean("isClient", |
|
||||
FieldDescriptions.UserIsClient); |
|
||||
|
|
||||
AddBoolean("isUser", |
|
||||
FieldDescriptions.UserIsUser); |
|
||||
|
|
||||
AddObject("claims", |
|
||||
FieldDescriptions.UserClaims, () => |
|
||||
{ |
|
||||
AddArray("name", |
|
||||
FieldDescriptions.UsersClaimsValue); |
|
||||
}); |
|
||||
}); |
|
||||
} |
|
||||
|
|
||||
private void AddData(Schema schema, PartitionResolver partitionResolver) |
|
||||
{ |
|
||||
foreach (var field in schema.Fields.Where(x => x.IsForApi(true))) |
|
||||
{ |
|
||||
var description = $"The values of the '{field.DisplayName()}' field."; |
|
||||
|
|
||||
AddObject(field.Name, $"The values of the '{field.DisplayName()}' field.", () => |
|
||||
{ |
|
||||
foreach (var partition in partitionResolver(field.Partitioning).AllKeys) |
|
||||
{ |
|
||||
var description = $"The '{partition}' value of the '{field.DisplayName()}' field."; |
|
||||
|
|
||||
if (field is ArrayField arrayField) |
|
||||
{ |
|
||||
AddObject(partition, description, () => |
|
||||
{ |
|
||||
foreach (var nestedField in arrayField.Fields.Where(x => x.IsForApi(true))) |
|
||||
{ |
|
||||
var description = $"The value of the '{nestedField.DisplayName()}' nested field."; |
|
||||
|
|
||||
AddAny(field.Name, description); |
|
||||
} |
|
||||
}); |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
AddAny(partition, description); |
|
||||
} |
|
||||
} |
|
||||
}); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
private void AddAny(string name, string description) |
|
||||
{ |
|
||||
Add(JsonType.Any, name, description); |
|
||||
} |
|
||||
|
|
||||
private void AddArray(string name, string description) |
|
||||
{ |
|
||||
Add(JsonType.Array, name, description); |
|
||||
} |
|
||||
|
|
||||
private void AddBoolean(string name, string description) |
|
||||
{ |
|
||||
Add(JsonType.Boolean, name, description); |
|
||||
} |
|
||||
|
|
||||
private void AddFunction(string name, string description) |
|
||||
{ |
|
||||
Add(JsonType.Function, name, description); |
|
||||
} |
|
||||
|
|
||||
private void AddNumber(string name, string description) |
|
||||
{ |
|
||||
Add(JsonType.Number, name, description); |
|
||||
} |
|
||||
|
|
||||
private void AddString(string name, string description) |
|
||||
{ |
|
||||
Add(JsonType.String, name, description); |
|
||||
} |
|
||||
|
|
||||
private void Add(JsonType type, string name, string description) |
|
||||
{ |
|
||||
var fullName = string.Join('.', prefixes.Reverse().Union(Enumerable.Repeat(name, 1))); |
|
||||
|
|
||||
result.Add(new ScriptingValue(fullName, type, description)); |
|
||||
} |
|
||||
|
|
||||
private void AddObject(string name, string description, Action inner) |
|
||||
{ |
|
||||
Add(JsonType.Object, description, name); |
|
||||
|
|
||||
prefixes.Push(name); |
|
||||
try |
|
||||
{ |
|
||||
inner(); |
|
||||
} |
|
||||
finally |
|
||||
{ |
|
||||
prefixes.Pop(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,162 @@ |
|||||
|
//------------------------------------------------------------------------------
|
||||
|
// <auto-generated>
|
||||
|
// This code was generated by a tool.
|
||||
|
// Runtime Version:4.0.30319.42000
|
||||
|
//
|
||||
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
|
// the code is regenerated.
|
||||
|
// </auto-generated>
|
||||
|
//------------------------------------------------------------------------------
|
||||
|
|
||||
|
namespace Squidex.Infrastructure.Properties { |
||||
|
using System; |
||||
|
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
|
/// </summary>
|
||||
|
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
|
// class via a tool like ResGen or Visual Studio.
|
||||
|
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
|
// with the /str option, or rebuild your VS project.
|
||||
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] |
||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()] |
||||
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] |
||||
|
internal class Resources { |
||||
|
|
||||
|
private static global::System.Resources.ResourceManager resourceMan; |
||||
|
|
||||
|
private static global::System.Globalization.CultureInfo resourceCulture; |
||||
|
|
||||
|
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] |
||||
|
internal Resources() { |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Returns the cached ResourceManager instance used by this class.
|
||||
|
/// </summary>
|
||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] |
||||
|
internal static global::System.Resources.ResourceManager ResourceManager { |
||||
|
get { |
||||
|
if (object.ReferenceEquals(resourceMan, null)) { |
||||
|
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Squidex.Infrastructure.Properties.Resources", typeof(Resources).Assembly); |
||||
|
resourceMan = temp; |
||||
|
} |
||||
|
return resourceMan; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Overrides the current thread's CurrentUICulture property for all
|
||||
|
/// resource lookups using this strongly typed resource class.
|
||||
|
/// </summary>
|
||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] |
||||
|
internal static global::System.Globalization.CultureInfo Culture { |
||||
|
get { |
||||
|
return resourceCulture; |
||||
|
} |
||||
|
set { |
||||
|
resourceCulture = value; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to Json query not valid: {0}..
|
||||
|
/// </summary>
|
||||
|
internal static string QueryInvalid { |
||||
|
get { |
||||
|
return ResourceManager.GetString("QueryInvalid", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to Array value is not allowed for '{0}' operator and path '{1}'..
|
||||
|
/// </summary>
|
||||
|
internal static string QueryInvalidArray { |
||||
|
get { |
||||
|
return ResourceManager.GetString("QueryInvalidArray", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to Json query not valid json: {0}..
|
||||
|
/// </summary>
|
||||
|
internal static string QueryInvalidJson { |
||||
|
get { |
||||
|
return ResourceManager.GetString("QueryInvalidJson", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to Either 'and', 'or', 'not' or 'path'+'op' must be set..
|
||||
|
/// </summary>
|
||||
|
internal static string QueryInvalidJsonStructure { |
||||
|
get { |
||||
|
return ResourceManager.GetString("QueryInvalidJsonStructure", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to '{0}' is not a valid operator for type {1} at '{2}'..
|
||||
|
/// </summary>
|
||||
|
internal static string QueryInvalidOperator { |
||||
|
get { |
||||
|
return ResourceManager.GetString("QueryInvalidOperator", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to Path '{0}' does not point to a valid property in the model..
|
||||
|
/// </summary>
|
||||
|
internal static string QueryInvalidPath { |
||||
|
get { |
||||
|
return ResourceManager.GetString("QueryInvalidPath", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to {0} is not a valid regular expression at path '{1}'..
|
||||
|
/// </summary>
|
||||
|
internal static string QueryInvalidRegex { |
||||
|
get { |
||||
|
return ResourceManager.GetString("QueryInvalidRegex", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to Expected {0} for path '{2}', but got {1}..
|
||||
|
/// </summary>
|
||||
|
internal static string QueryWrongExpectedType { |
||||
|
get { |
||||
|
return ResourceManager.GetString("QueryWrongExpectedType", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to Expected {0} for path '{1}', but got invalid String..
|
||||
|
/// </summary>
|
||||
|
internal static string QueryWrongFormat { |
||||
|
get { |
||||
|
return ResourceManager.GetString("QueryWrongFormat", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to Expected primitive for path '{1}', but got {0}..
|
||||
|
/// </summary>
|
||||
|
internal static string QueryWrongPrimitive { |
||||
|
get { |
||||
|
return ResourceManager.GetString("QueryWrongPrimitive", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Looks up a localized string similar to Unsupported type {0} for path '{1}'..
|
||||
|
/// </summary>
|
||||
|
internal static string QueryWrongType { |
||||
|
get { |
||||
|
return ResourceManager.GetString("QueryWrongType", resourceCulture); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,153 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<root> |
||||
|
<!-- |
||||
|
Microsoft ResX Schema |
||||
|
|
||||
|
Version 2.0 |
||||
|
|
||||
|
The primary goals of this format is to allow a simple XML format |
||||
|
that is mostly human readable. The generation and parsing of the |
||||
|
various data types are done through the TypeConverter classes |
||||
|
associated with the data types. |
||||
|
|
||||
|
Example: |
||||
|
|
||||
|
... ado.net/XML headers & schema ... |
||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader> |
||||
|
<resheader name="version">2.0</resheader> |
||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader> |
||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader> |
||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data> |
||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data> |
||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64"> |
||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value> |
||||
|
</data> |
||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64"> |
||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value> |
||||
|
<comment>This is a comment</comment> |
||||
|
</data> |
||||
|
|
||||
|
There are any number of "resheader" rows that contain simple |
||||
|
name/value pairs. |
||||
|
|
||||
|
Each data row contains a name, and value. The row also contains a |
||||
|
type or mimetype. Type corresponds to a .NET class that support |
||||
|
text/value conversion through the TypeConverter architecture. |
||||
|
Classes that don't support this are serialized and stored with the |
||||
|
mimetype set. |
||||
|
|
||||
|
The mimetype is used for serialized objects, and tells the |
||||
|
ResXResourceReader how to depersist the object. This is currently not |
||||
|
extensible. For a given mimetype the value must be set accordingly: |
||||
|
|
||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format |
||||
|
that the ResXResourceWriter will generate, however the reader can |
||||
|
read any of the formats listed below. |
||||
|
|
||||
|
mimetype: application/x-microsoft.net.object.binary.base64 |
||||
|
value : The object must be serialized with |
||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter |
||||
|
: and then encoded with base64 encoding. |
||||
|
|
||||
|
mimetype: application/x-microsoft.net.object.soap.base64 |
||||
|
value : The object must be serialized with |
||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter |
||||
|
: and then encoded with base64 encoding. |
||||
|
|
||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64 |
||||
|
value : The object must be serialized into a byte array |
||||
|
: using a System.ComponentModel.TypeConverter |
||||
|
: and then encoded with base64 encoding. |
||||
|
--> |
||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> |
||||
|
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" /> |
||||
|
<xsd:element name="root" msdata:IsDataSet="true"> |
||||
|
<xsd:complexType> |
||||
|
<xsd:choice maxOccurs="unbounded"> |
||||
|
<xsd:element name="metadata"> |
||||
|
<xsd:complexType> |
||||
|
<xsd:sequence> |
||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" /> |
||||
|
</xsd:sequence> |
||||
|
<xsd:attribute name="name" use="required" type="xsd:string" /> |
||||
|
<xsd:attribute name="type" type="xsd:string" /> |
||||
|
<xsd:attribute name="mimetype" type="xsd:string" /> |
||||
|
<xsd:attribute ref="xml:space" /> |
||||
|
</xsd:complexType> |
||||
|
</xsd:element> |
||||
|
<xsd:element name="assembly"> |
||||
|
<xsd:complexType> |
||||
|
<xsd:attribute name="alias" type="xsd:string" /> |
||||
|
<xsd:attribute name="name" type="xsd:string" /> |
||||
|
</xsd:complexType> |
||||
|
</xsd:element> |
||||
|
<xsd:element name="data"> |
||||
|
<xsd:complexType> |
||||
|
<xsd:sequence> |
||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> |
||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" /> |
||||
|
</xsd:sequence> |
||||
|
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" /> |
||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" /> |
||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" /> |
||||
|
<xsd:attribute ref="xml:space" /> |
||||
|
</xsd:complexType> |
||||
|
</xsd:element> |
||||
|
<xsd:element name="resheader"> |
||||
|
<xsd:complexType> |
||||
|
<xsd:sequence> |
||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" /> |
||||
|
</xsd:sequence> |
||||
|
<xsd:attribute name="name" type="xsd:string" use="required" /> |
||||
|
</xsd:complexType> |
||||
|
</xsd:element> |
||||
|
</xsd:choice> |
||||
|
</xsd:complexType> |
||||
|
</xsd:element> |
||||
|
</xsd:schema> |
||||
|
<resheader name="resmimetype"> |
||||
|
<value>text/microsoft-resx</value> |
||||
|
</resheader> |
||||
|
<resheader name="version"> |
||||
|
<value>2.0</value> |
||||
|
</resheader> |
||||
|
<resheader name="reader"> |
||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> |
||||
|
</resheader> |
||||
|
<resheader name="writer"> |
||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> |
||||
|
</resheader> |
||||
|
<data name="QueryInvalid" xml:space="preserve"> |
||||
|
<value>Json query not valid: {0}.</value> |
||||
|
</data> |
||||
|
<data name="QueryInvalidArray" xml:space="preserve"> |
||||
|
<value>Array value is not allowed for '{0}' operator and path '{1}'.</value> |
||||
|
</data> |
||||
|
<data name="QueryInvalidJson" xml:space="preserve"> |
||||
|
<value>Json query not valid json: {0}.</value> |
||||
|
</data> |
||||
|
<data name="QueryInvalidJsonStructure" xml:space="preserve"> |
||||
|
<value>Either 'and', 'or', 'not' or 'path'+'op' must be set.</value> |
||||
|
</data> |
||||
|
<data name="QueryInvalidOperator" xml:space="preserve"> |
||||
|
<value>'{0}' is not a valid operator for type {1} at '{2}'.</value> |
||||
|
</data> |
||||
|
<data name="QueryInvalidPath" xml:space="preserve"> |
||||
|
<value>Path '{0}' does not point to a valid property in the model.</value> |
||||
|
</data> |
||||
|
<data name="QueryInvalidRegex" xml:space="preserve"> |
||||
|
<value>{0} is not a valid regular expression at path '{1}'.</value> |
||||
|
</data> |
||||
|
<data name="QueryWrongExpectedType" xml:space="preserve"> |
||||
|
<value>Expected {0} for path '{2}', but got {1}.</value> |
||||
|
</data> |
||||
|
<data name="QueryWrongFormat" xml:space="preserve"> |
||||
|
<value>Expected {0} for path '{1}', but got invalid String.</value> |
||||
|
</data> |
||||
|
<data name="QueryWrongPrimitive" xml:space="preserve"> |
||||
|
<value>Expected primitive for path '{1}', but got {0}.</value> |
||||
|
</data> |
||||
|
<data name="QueryWrongType" xml:space="preserve"> |
||||
|
<value>Unsupported type {0} for path '{1}'.</value> |
||||
|
</data> |
||||
|
</root> |
||||
@ -0,0 +1,99 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System.ComponentModel; |
||||
|
using System.Globalization; |
||||
|
|
||||
|
namespace Squidex.Infrastructure.Queries |
||||
|
{ |
||||
|
public sealed class CompareOperatorTypeConverter : TypeConverter |
||||
|
{ |
||||
|
public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType) |
||||
|
{ |
||||
|
return sourceType == typeof(string); |
||||
|
} |
||||
|
|
||||
|
public override bool CanConvertTo(ITypeDescriptorContext? context, Type? destinationType) |
||||
|
{ |
||||
|
return destinationType == typeof(string); |
||||
|
} |
||||
|
|
||||
|
public override object ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value) |
||||
|
{ |
||||
|
var op = (string)value; |
||||
|
|
||||
|
switch (op.ToLowerInvariant()) |
||||
|
{ |
||||
|
case "eq": |
||||
|
return CompareOperator.Equals; |
||||
|
case "ne": |
||||
|
return CompareOperator.NotEquals; |
||||
|
case "lt": |
||||
|
return CompareOperator.LessThan; |
||||
|
case "le": |
||||
|
return CompareOperator.LessThanOrEqual; |
||||
|
case "gt": |
||||
|
return CompareOperator.GreaterThan; |
||||
|
case "ge": |
||||
|
return CompareOperator.GreaterThanOrEqual; |
||||
|
case "empty": |
||||
|
return CompareOperator.Empty; |
||||
|
case "exists": |
||||
|
return CompareOperator.Exists; |
||||
|
case "matchs": |
||||
|
return CompareOperator.Matchs; |
||||
|
case "contains": |
||||
|
return CompareOperator.Contains; |
||||
|
case "endswith": |
||||
|
return CompareOperator.EndsWith; |
||||
|
case "startswith": |
||||
|
return CompareOperator.StartsWith; |
||||
|
case "in": |
||||
|
return CompareOperator.In; |
||||
|
} |
||||
|
|
||||
|
throw new InvalidCastException($"Unexpected compare operator, got {op}."); |
||||
|
} |
||||
|
|
||||
|
public override object ConvertTo(ITypeDescriptorContext? context, CultureInfo? culture, object? value, Type? destinationType) |
||||
|
{ |
||||
|
var op = (CompareOperator)value!; |
||||
|
|
||||
|
switch (op) |
||||
|
{ |
||||
|
case CompareOperator.Equals: |
||||
|
return "eq"; |
||||
|
case CompareOperator.NotEquals: |
||||
|
return "ne"; |
||||
|
case CompareOperator.LessThan: |
||||
|
return "lt"; |
||||
|
case CompareOperator.LessThanOrEqual: |
||||
|
return "le"; |
||||
|
case CompareOperator.GreaterThan: |
||||
|
return "gt"; |
||||
|
case CompareOperator.GreaterThanOrEqual: |
||||
|
return "gt"; |
||||
|
case CompareOperator.Empty: |
||||
|
return "empty"; |
||||
|
case CompareOperator.Exists: |
||||
|
return "exists"; |
||||
|
case CompareOperator.Matchs: |
||||
|
return "matchs"; |
||||
|
case CompareOperator.Contains: |
||||
|
return "contains"; |
||||
|
case CompareOperator.EndsWith: |
||||
|
return "endsWith"; |
||||
|
case CompareOperator.StartsWith: |
||||
|
return "startsWith"; |
||||
|
case CompareOperator.In: |
||||
|
return "in"; |
||||
|
} |
||||
|
|
||||
|
throw new InvalidCastException($"Unexpected compare operator, got {op}."); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,14 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
#pragma warning disable SA1313 // Parameter names should begin with lower-case letter
|
||||
|
|
||||
|
namespace Squidex.Infrastructure.Queries |
||||
|
{ |
||||
|
public sealed record FilterField(FilterSchema Schema, string Path, string? Description = null, |
||||
|
bool IsNullable = false); |
||||
|
} |
||||
@ -0,0 +1,104 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using Squidex.Infrastructure.Collections; |
||||
|
|
||||
|
#pragma warning disable SA1313 // Parameter names should begin with lower-case letter
|
||||
|
|
||||
|
namespace Squidex.Infrastructure.Queries |
||||
|
{ |
||||
|
public sealed record FilterSchema(FilterSchemaType Type) |
||||
|
{ |
||||
|
public static readonly FilterSchema Any = new FilterSchema(FilterSchemaType.Any); |
||||
|
public static readonly FilterSchema Boolean = new FilterSchema(FilterSchemaType.Boolean); |
||||
|
public static readonly FilterSchema Date = new FilterSchema(FilterSchemaType.Date); |
||||
|
public static readonly FilterSchema DateTime = new FilterSchema(FilterSchemaType.DateTime); |
||||
|
public static readonly FilterSchema GeoObject = new FilterSchema(FilterSchemaType.GeoObject); |
||||
|
public static readonly FilterSchema Guid = new FilterSchema(FilterSchemaType.Guid); |
||||
|
public static readonly FilterSchema Number = new FilterSchema(FilterSchemaType.Number); |
||||
|
public static readonly FilterSchema String = new FilterSchema(FilterSchemaType.String); |
||||
|
public static readonly FilterSchema StringArray = new FilterSchema(FilterSchemaType.StringArray); |
||||
|
|
||||
|
public ReadonlyList<FilterField>? Fields { get; init; } |
||||
|
|
||||
|
public object? Extra { get; init; } |
||||
|
|
||||
|
public FilterSchema Flatten(int maxDepth = 7, Predicate<FilterSchema>? predicate = null) |
||||
|
{ |
||||
|
if (Fields == null || Fields.Count == 0) |
||||
|
{ |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
var result = new List<FilterField>(); |
||||
|
|
||||
|
var pathStack = new Stack<string>(); |
||||
|
|
||||
|
void AddField(FilterField field) |
||||
|
{ |
||||
|
pathStack.Push(field.Path); |
||||
|
|
||||
|
if (predicate?.Invoke(field.Schema) != false) |
||||
|
{ |
||||
|
var path = string.Join('.', pathStack.Reverse()); |
||||
|
|
||||
|
var schema = field.Schema; |
||||
|
|
||||
|
if (schema.Fields != null) |
||||
|
{ |
||||
|
schema = schema with { Fields = null }; |
||||
|
} |
||||
|
|
||||
|
result?.Add(field with { Path = path, Schema = schema }); |
||||
|
} |
||||
|
|
||||
|
if (field.Schema.Fields?.Count > 0 && pathStack.Count < maxDepth) |
||||
|
{ |
||||
|
AddFields(field.Schema.Fields); |
||||
|
} |
||||
|
|
||||
|
pathStack.Pop(); |
||||
|
} |
||||
|
|
||||
|
void AddFields(IEnumerable<FilterField> source) |
||||
|
{ |
||||
|
foreach (var field in source) |
||||
|
{ |
||||
|
AddField(field); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
AddFields(Fields); |
||||
|
|
||||
|
var conflictFree = GetConflictFreeFields(result); |
||||
|
|
||||
|
return this with |
||||
|
{ |
||||
|
Fields = conflictFree.ToReadonlyList() |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
public static IEnumerable<FilterField> GetConflictFreeFields(IEnumerable<FilterField> fields) |
||||
|
{ |
||||
|
var conflictFree = fields.GroupBy(x => x.Path).Select(group => |
||||
|
{ |
||||
|
var firstType = group.First().Schema.Type; |
||||
|
|
||||
|
if (group.All(x => x.Schema.Type == firstType)) |
||||
|
{ |
||||
|
return group.Take(1); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
return Enumerable.Empty<FilterField>(); |
||||
|
} |
||||
|
}).SelectMany(x => x); |
||||
|
|
||||
|
return conflictFree; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,24 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
namespace Squidex.Infrastructure.Queries |
||||
|
{ |
||||
|
public enum FilterSchemaType |
||||
|
{ |
||||
|
Any, |
||||
|
Boolean, |
||||
|
Date, |
||||
|
DateTime, |
||||
|
GeoObject, |
||||
|
Guid, |
||||
|
Number, |
||||
|
Object, |
||||
|
ObjectArray, |
||||
|
String, |
||||
|
StringArray |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,46 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System.ComponentModel; |
||||
|
using Newtonsoft.Json; |
||||
|
using Squidex.Infrastructure.Json; |
||||
|
using JsonException = Squidex.Infrastructure.Json.JsonException; |
||||
|
|
||||
|
namespace Squidex.Infrastructure.Queries.Json |
||||
|
{ |
||||
|
public sealed class CompareOperatorJsonConverter : JsonConverter, ISupportedTypes |
||||
|
{ |
||||
|
private readonly TypeConverter typeConverter = TypeDescriptor.GetConverter(typeof(CompareOperator)); |
||||
|
|
||||
|
public IEnumerable<Type> SupportedTypes |
||||
|
{ |
||||
|
get { yield return typeof(CompareOperator); } |
||||
|
} |
||||
|
|
||||
|
public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
return typeConverter.ConvertFromInvariantString(reader.Value?.ToString()!); |
||||
|
} |
||||
|
catch (InvalidCastException ex) |
||||
|
{ |
||||
|
throw new JsonException(ex.Message); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer) |
||||
|
{ |
||||
|
writer.WriteValue(typeConverter.ConvertToInvariantString(value)); |
||||
|
} |
||||
|
|
||||
|
public override bool CanConvert(Type objectType) |
||||
|
{ |
||||
|
return SupportedTypes.Contains(objectType); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,70 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System.Globalization; |
||||
|
using Squidex.Infrastructure.Properties; |
||||
|
|
||||
|
namespace Squidex.Infrastructure.Queries.Json |
||||
|
{ |
||||
|
internal static class Errors |
||||
|
{ |
||||
|
public static string InvalidJsonStructure() |
||||
|
{ |
||||
|
return Resources.QueryInvalidJsonStructure; |
||||
|
} |
||||
|
|
||||
|
public static string InvalidQuery(object message) |
||||
|
{ |
||||
|
return string.Format(CultureInfo.InvariantCulture, Resources.QueryInvalid, message); |
||||
|
} |
||||
|
|
||||
|
public static string InvalidQueryJson(object message) |
||||
|
{ |
||||
|
return string.Format(CultureInfo.InvariantCulture, Resources.QueryInvalidJson, message); |
||||
|
} |
||||
|
|
||||
|
public static string InvalidPath(PropertyPath path) |
||||
|
{ |
||||
|
return string.Format(CultureInfo.InvariantCulture, Resources.QueryInvalidPath, path); |
||||
|
} |
||||
|
|
||||
|
public static string InvalidOperator(object @operator, object type, PropertyPath path) |
||||
|
{ |
||||
|
return string.Format(CultureInfo.InvariantCulture, Resources.QueryInvalidOperator, @operator, type, path); |
||||
|
} |
||||
|
|
||||
|
public static string InvalidRegex(object value, PropertyPath path) |
||||
|
{ |
||||
|
return string.Format(CultureInfo.InvariantCulture, Resources.QueryInvalidRegex, value, path); |
||||
|
} |
||||
|
|
||||
|
public static string InvalidArray(object @operator, PropertyPath path) |
||||
|
{ |
||||
|
return string.Format(CultureInfo.InvariantCulture, Resources.QueryInvalidArray, @operator, path); |
||||
|
} |
||||
|
|
||||
|
public static string WrongExpectedType(object expected, object type, PropertyPath path) |
||||
|
{ |
||||
|
return string.Format(CultureInfo.InvariantCulture, Resources.QueryWrongExpectedType, expected, type, path); |
||||
|
} |
||||
|
|
||||
|
public static string WrongFormat(object expected, PropertyPath path) |
||||
|
{ |
||||
|
return string.Format(CultureInfo.InvariantCulture, Resources.QueryWrongFormat, expected, path); |
||||
|
} |
||||
|
|
||||
|
public static string WrongType(object type, PropertyPath path) |
||||
|
{ |
||||
|
return string.Format(CultureInfo.InvariantCulture, Resources.QueryWrongType, type, path); |
||||
|
} |
||||
|
|
||||
|
public static string WrongPrimitive(object type, PropertyPath path) |
||||
|
{ |
||||
|
return string.Format(CultureInfo.InvariantCulture, Resources.QueryWrongPrimitive, type, path); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,86 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using NJsonSchema; |
|
||||
using Squidex.Infrastructure.Json; |
|
||||
|
|
||||
namespace Squidex.Infrastructure.Queries.Json |
|
||||
{ |
|
||||
public static class OperatorValidator |
|
||||
{ |
|
||||
private static readonly CompareOperator[] BooleanOperators = |
|
||||
{ |
|
||||
CompareOperator.Equals, |
|
||||
CompareOperator.Exists, |
|
||||
CompareOperator.In, |
|
||||
CompareOperator.NotEquals |
|
||||
}; |
|
||||
private static readonly CompareOperator[] NumberOperators = |
|
||||
{ |
|
||||
CompareOperator.Equals, |
|
||||
CompareOperator.Exists, |
|
||||
CompareOperator.LessThan, |
|
||||
CompareOperator.LessThanOrEqual, |
|
||||
CompareOperator.GreaterThan, |
|
||||
CompareOperator.GreaterThanOrEqual, |
|
||||
CompareOperator.In, |
|
||||
CompareOperator.NotEquals |
|
||||
}; |
|
||||
private static readonly CompareOperator[] StringOperators = |
|
||||
{ |
|
||||
CompareOperator.Contains, |
|
||||
CompareOperator.Empty, |
|
||||
CompareOperator.Exists, |
|
||||
CompareOperator.EndsWith, |
|
||||
CompareOperator.Equals, |
|
||||
CompareOperator.GreaterThan, |
|
||||
CompareOperator.GreaterThanOrEqual, |
|
||||
CompareOperator.In, |
|
||||
CompareOperator.LessThan, |
|
||||
CompareOperator.LessThanOrEqual, |
|
||||
CompareOperator.Matchs, |
|
||||
CompareOperator.NotEquals, |
|
||||
CompareOperator.StartsWith |
|
||||
}; |
|
||||
private static readonly CompareOperator[] ArrayOperators = |
|
||||
{ |
|
||||
CompareOperator.Empty, |
|
||||
CompareOperator.Exists, |
|
||||
CompareOperator.Equals, |
|
||||
CompareOperator.In, |
|
||||
CompareOperator.NotEquals |
|
||||
}; |
|
||||
private static readonly CompareOperator[] GeoOperators = |
|
||||
{ |
|
||||
CompareOperator.LessThan, |
|
||||
CompareOperator.Exists |
|
||||
}; |
|
||||
|
|
||||
public static bool IsAllowedOperator(JsonSchema schema, CompareOperator compareOperator) |
|
||||
{ |
|
||||
switch (schema.Type) |
|
||||
{ |
|
||||
case JsonObjectType.None: |
|
||||
return true; |
|
||||
case JsonObjectType.Boolean: |
|
||||
return BooleanOperators.Contains(compareOperator); |
|
||||
case JsonObjectType.Integer: |
|
||||
return NumberOperators.Contains(compareOperator); |
|
||||
case JsonObjectType.Number: |
|
||||
return NumberOperators.Contains(compareOperator); |
|
||||
case JsonObjectType.String: |
|
||||
return StringOperators.Contains(compareOperator); |
|
||||
case JsonObjectType.Array: |
|
||||
return ArrayOperators.Contains(compareOperator); |
|
||||
case JsonObjectType.Object when schema.Format == GeoJson.Format: |
|
||||
return GeoOperators.Contains(compareOperator); |
|
||||
} |
|
||||
|
|
||||
return false; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,125 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using Microsoft.OData.Edm; |
||||
|
using Squidex.Text; |
||||
|
|
||||
|
namespace Squidex.Infrastructure.Queries.OData |
||||
|
{ |
||||
|
public static class EdmModelConverter |
||||
|
{ |
||||
|
private const int MaxDepth = 7; |
||||
|
|
||||
|
public static EdmModel ConvertToEdm(this QueryModel queryModel, string modelName, string name) |
||||
|
{ |
||||
|
var model = new EdmModel(); |
||||
|
|
||||
|
var entityType = new EdmEntityType(modelName, name); |
||||
|
var entityPath = new Stack<string>(); |
||||
|
|
||||
|
void Convert(EdmStructuredType target, FilterSchema schema) |
||||
|
{ |
||||
|
if (schema.Fields == null) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
foreach (var field in FilterSchema.GetConflictFreeFields(schema.Fields)) |
||||
|
{ |
||||
|
var fieldName = field.Path.EscapeEdmField(); |
||||
|
|
||||
|
switch (field.Schema.Type) |
||||
|
{ |
||||
|
case FilterSchemaType.Boolean: |
||||
|
target.AddStructuralProperty(fieldName, EdmPrimitiveTypeKind.Boolean, field.IsNullable); |
||||
|
break; |
||||
|
case FilterSchemaType.DateTime: |
||||
|
target.AddStructuralProperty(fieldName, EdmPrimitiveTypeKind.DateTimeOffset, field.IsNullable); |
||||
|
break; |
||||
|
case FilterSchemaType.GeoObject: |
||||
|
target.AddStructuralProperty(fieldName, EdmPrimitiveTypeKind.GeographyPoint, field.IsNullable); |
||||
|
break; |
||||
|
case FilterSchemaType.Guid: |
||||
|
target.AddStructuralProperty(fieldName, EdmPrimitiveTypeKind.Guid, field.IsNullable); |
||||
|
break; |
||||
|
case FilterSchemaType.Number: |
||||
|
target.AddStructuralProperty(fieldName, EdmPrimitiveTypeKind.Double, field.IsNullable); |
||||
|
break; |
||||
|
case FilterSchemaType.String: |
||||
|
case FilterSchemaType.StringArray: |
||||
|
target.AddStructuralProperty(fieldName, EdmPrimitiveTypeKind.String, field.IsNullable); |
||||
|
break; |
||||
|
case FilterSchemaType.Object: |
||||
|
case FilterSchemaType.ObjectArray: |
||||
|
{ |
||||
|
if (field.Schema.Fields == null || field.Schema.Fields.Count == 0 || entityPath.Count >= MaxDepth) |
||||
|
{ |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
entityPath.Push(fieldName); |
||||
|
|
||||
|
var typeName = string.Join("_", entityPath.Reverse().Select(x => x.EscapeEdmField().ToPascalCase())); |
||||
|
|
||||
|
var result = model.SchemaElements.OfType<EdmComplexType>().FirstOrDefault(x => x.Name == typeName); |
||||
|
|
||||
|
if (result == null) |
||||
|
{ |
||||
|
result = new EdmComplexType(modelName, typeName); |
||||
|
|
||||
|
model.AddElement(result); |
||||
|
|
||||
|
Convert(result, field.Schema); |
||||
|
} |
||||
|
|
||||
|
target.AddStructuralProperty(fieldName, new EdmComplexTypeReference(result, field.IsNullable)); |
||||
|
|
||||
|
entityPath.Pop(); |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
case FilterSchemaType.Any: |
||||
|
{ |
||||
|
var result = model.SchemaElements.OfType<EdmComplexType>().FirstOrDefault(x => x.Name == "Any"); |
||||
|
|
||||
|
if (result == null) |
||||
|
{ |
||||
|
result = new EdmComplexType("Squidex", "Any", null, false, true); |
||||
|
|
||||
|
model.AddElement(result); |
||||
|
} |
||||
|
|
||||
|
target.AddStructuralProperty(fieldName, new EdmComplexTypeReference(result, field.IsNullable)); |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
Convert(entityType, queryModel.Schema); |
||||
|
|
||||
|
var container = new EdmEntityContainer("Squidex", "Container"); |
||||
|
|
||||
|
container.AddEntitySet("ContentSet", entityType); |
||||
|
|
||||
|
model.AddElement(container); |
||||
|
model.AddElement(entityType); |
||||
|
|
||||
|
return model; |
||||
|
} |
||||
|
|
||||
|
public static string EscapeEdmField(this string field) |
||||
|
{ |
||||
|
return field.Replace("-", "_", StringComparison.Ordinal); |
||||
|
} |
||||
|
|
||||
|
public static string UnescapeEdmField(this string field) |
||||
|
{ |
||||
|
return field.Replace("_", "-", StringComparison.Ordinal); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,136 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
namespace Squidex.Infrastructure.Queries |
||||
|
{ |
||||
|
public sealed class QueryModel |
||||
|
{ |
||||
|
public static readonly IReadOnlyDictionary<FilterSchemaType, IReadOnlyList<CompareOperator>> DefaultOperators = new Dictionary<FilterSchemaType, IReadOnlyList<CompareOperator>> |
||||
|
{ |
||||
|
[FilterSchemaType.Any] = Enum.GetValues(typeof(CompareOperator)).OfType<CompareOperator>().ToList(), |
||||
|
[FilterSchemaType.Boolean] = new List<CompareOperator> |
||||
|
{ |
||||
|
CompareOperator.Equals, |
||||
|
CompareOperator.Exists, |
||||
|
CompareOperator.In, |
||||
|
CompareOperator.NotEquals |
||||
|
}, |
||||
|
[FilterSchemaType.DateTime] = new List<CompareOperator> |
||||
|
{ |
||||
|
CompareOperator.Contains, |
||||
|
CompareOperator.Empty, |
||||
|
CompareOperator.Exists, |
||||
|
CompareOperator.EndsWith, |
||||
|
CompareOperator.Equals, |
||||
|
CompareOperator.GreaterThan, |
||||
|
CompareOperator.GreaterThanOrEqual, |
||||
|
CompareOperator.In, |
||||
|
CompareOperator.LessThan, |
||||
|
CompareOperator.LessThanOrEqual, |
||||
|
CompareOperator.Matchs, |
||||
|
CompareOperator.NotEquals, |
||||
|
CompareOperator.StartsWith |
||||
|
}, |
||||
|
[FilterSchemaType.GeoObject] = new List<CompareOperator> |
||||
|
{ |
||||
|
CompareOperator.LessThan, |
||||
|
CompareOperator.Exists |
||||
|
}, |
||||
|
[FilterSchemaType.Guid] = new List<CompareOperator> |
||||
|
{ |
||||
|
CompareOperator.Contains, |
||||
|
CompareOperator.Empty, |
||||
|
CompareOperator.Exists, |
||||
|
CompareOperator.EndsWith, |
||||
|
CompareOperator.Equals, |
||||
|
CompareOperator.GreaterThan, |
||||
|
CompareOperator.GreaterThanOrEqual, |
||||
|
CompareOperator.In, |
||||
|
CompareOperator.LessThan, |
||||
|
CompareOperator.LessThanOrEqual, |
||||
|
CompareOperator.Matchs, |
||||
|
CompareOperator.NotEquals, |
||||
|
CompareOperator.StartsWith |
||||
|
}, |
||||
|
[FilterSchemaType.Object] = new List<CompareOperator>(), |
||||
|
[FilterSchemaType.ObjectArray] = new List<CompareOperator> |
||||
|
{ |
||||
|
CompareOperator.Empty, |
||||
|
CompareOperator.Exists, |
||||
|
CompareOperator.Equals, |
||||
|
CompareOperator.In, |
||||
|
CompareOperator.NotEquals |
||||
|
}, |
||||
|
[FilterSchemaType.Number] = new List<CompareOperator> |
||||
|
{ |
||||
|
CompareOperator.Equals, |
||||
|
CompareOperator.Exists, |
||||
|
CompareOperator.LessThan, |
||||
|
CompareOperator.LessThanOrEqual, |
||||
|
CompareOperator.GreaterThan, |
||||
|
CompareOperator.GreaterThanOrEqual, |
||||
|
CompareOperator.In, |
||||
|
CompareOperator.NotEquals |
||||
|
}, |
||||
|
[FilterSchemaType.String] = new List<CompareOperator> |
||||
|
{ |
||||
|
CompareOperator.Contains, |
||||
|
CompareOperator.Empty, |
||||
|
CompareOperator.Exists, |
||||
|
CompareOperator.EndsWith, |
||||
|
CompareOperator.Equals, |
||||
|
CompareOperator.GreaterThan, |
||||
|
CompareOperator.GreaterThanOrEqual, |
||||
|
CompareOperator.In, |
||||
|
CompareOperator.LessThan, |
||||
|
CompareOperator.LessThanOrEqual, |
||||
|
CompareOperator.Matchs, |
||||
|
CompareOperator.NotEquals, |
||||
|
CompareOperator.StartsWith |
||||
|
}, |
||||
|
[FilterSchemaType.StringArray] = new List<CompareOperator> |
||||
|
{ |
||||
|
CompareOperator.Contains, |
||||
|
CompareOperator.Empty, |
||||
|
CompareOperator.Exists, |
||||
|
CompareOperator.EndsWith, |
||||
|
CompareOperator.Equals, |
||||
|
CompareOperator.GreaterThan, |
||||
|
CompareOperator.GreaterThanOrEqual, |
||||
|
CompareOperator.In, |
||||
|
CompareOperator.LessThan, |
||||
|
CompareOperator.LessThanOrEqual, |
||||
|
CompareOperator.Matchs, |
||||
|
CompareOperator.NotEquals, |
||||
|
CompareOperator.StartsWith |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
public FilterSchema Schema { get; init; } = FilterSchema.Any; |
||||
|
|
||||
|
public IReadOnlyDictionary<FilterSchemaType, IReadOnlyList<CompareOperator>> Operators { get; init; } = DefaultOperators; |
||||
|
|
||||
|
public QueryModel Flatten(int maxDepth = 7, bool onlyWithOperators = true) |
||||
|
{ |
||||
|
var predicate = (Predicate<FilterSchema>?)null; |
||||
|
|
||||
|
if (onlyWithOperators) |
||||
|
{ |
||||
|
predicate = x => Operators.TryGetValue(x.Type, out var operators) && operators.Count > 0; |
||||
|
} |
||||
|
|
||||
|
var flatten = Schema.Flatten(maxDepth, predicate); |
||||
|
|
||||
|
if (ReferenceEquals(flatten, Schema)) |
||||
|
{ |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
return new QueryModel { Operators = Operators, Schema = flatten }; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,49 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using Microsoft.OData.Edm; |
|
||||
using Squidex.Domain.Apps.Core.Apps; |
|
||||
using Squidex.Domain.Apps.Core.GenerateEdmSchema; |
|
||||
using Squidex.Domain.Apps.Core.Schemas; |
|
||||
using Squidex.Domain.Apps.Core.TestHelpers; |
|
||||
using Squidex.Infrastructure; |
|
||||
using Xunit; |
|
||||
|
|
||||
namespace Squidex.Domain.Apps.Core.Operations.GenerateEdmSchema |
|
||||
{ |
|
||||
public class EdmTests |
|
||||
{ |
|
||||
[Fact] |
|
||||
public void Should_escape_field_name() |
|
||||
{ |
|
||||
Assert.Equal("field_name", "field-name".EscapeEdmField()); |
|
||||
} |
|
||||
|
|
||||
[Fact] |
|
||||
public void Should_unescape_field_name() |
|
||||
{ |
|
||||
Assert.Equal("field-name", "field_name".UnescapeEdmField()); |
|
||||
} |
|
||||
|
|
||||
[Fact] |
|
||||
public void Should_build_edm_model() |
|
||||
{ |
|
||||
var languagesConfig = LanguagesConfig.English.Set(Language.DE); |
|
||||
|
|
||||
var typeFactory = new EdmTypeFactory(names => |
|
||||
{ |
|
||||
return (new EdmComplexType("Squidex", string.Join(".", names)), true); |
|
||||
}); |
|
||||
|
|
||||
var edmModel = |
|
||||
TestUtils.MixedSchema() |
|
||||
.BuildEdmType(true, languagesConfig.ToResolver(), typeFactory, ResolvedComponents.Empty); |
|
||||
|
|
||||
Assert.NotNull(edmModel); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,104 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using Squidex.Domain.Apps.Core.Apps; |
||||
|
using Squidex.Domain.Apps.Core.GenerateFilters; |
||||
|
using Squidex.Domain.Apps.Core.Schemas; |
||||
|
using Squidex.Domain.Apps.Core.TestHelpers; |
||||
|
using Squidex.Infrastructure; |
||||
|
using Squidex.Infrastructure.Queries; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Core.Operations.GenerateFilters |
||||
|
{ |
||||
|
public class FiltersTests |
||||
|
{ |
||||
|
[Fact] |
||||
|
public void Should_build_content_query_model() |
||||
|
{ |
||||
|
var languagesConfig = LanguagesConfig.English.Set(Language.DE); |
||||
|
|
||||
|
var (schema, components) = TestUtils.MixedSchema(); |
||||
|
|
||||
|
var queryModel = ContentQueryModel.Build(schema, languagesConfig.ToResolver(), components); |
||||
|
|
||||
|
Assert.NotNull(queryModel); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_build_dynamic_content_query_model() |
||||
|
{ |
||||
|
var languagesConfig = LanguagesConfig.English.Set(Language.DE); |
||||
|
|
||||
|
var queryModel = ContentQueryModel.Build(null, languagesConfig.ToResolver(), ResolvedComponents.Empty); |
||||
|
|
||||
|
Assert.NotNull(queryModel); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_build_asset_query_model() |
||||
|
{ |
||||
|
var queryModel = AssetQueryModel.Build(); |
||||
|
|
||||
|
Assert.NotNull(queryModel); |
||||
|
} |
||||
|
|
||||
|
private static void CheckFields(FilterSchema filterSchema, Schema schema) |
||||
|
{ |
||||
|
var filterProperties = AllPropertyNames(filterSchema); |
||||
|
|
||||
|
void CheckField(IField field) |
||||
|
{ |
||||
|
if (!field.IsForApi()) |
||||
|
{ |
||||
|
Assert.DoesNotContain(field.Name, filterProperties); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
Assert.Contains(field.Name, filterProperties); |
||||
|
} |
||||
|
|
||||
|
if (field is IArrayField array) |
||||
|
{ |
||||
|
foreach (var nested in array.Fields) |
||||
|
{ |
||||
|
CheckField(nested); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
foreach (var field in schema.Fields) |
||||
|
{ |
||||
|
CheckField(field); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private static HashSet<string> AllPropertyNames(FilterSchema schema) |
||||
|
{ |
||||
|
var result = new HashSet<string>(); |
||||
|
|
||||
|
void AddProperties(FilterSchema current) |
||||
|
{ |
||||
|
if (current == null) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
foreach (var field in current.Fields.OrEmpty()) |
||||
|
{ |
||||
|
result.Add(field.Path); |
||||
|
|
||||
|
AddProperties(field.Schema); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
AddProperties(schema); |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,156 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using Squidex.Infrastructure.Collections; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace Squidex.Infrastructure.Queries |
||||
|
{ |
||||
|
public class FilterSchemaTests |
||||
|
{ |
||||
|
[Fact] |
||||
|
public void Should_flatten_schema() |
||||
|
{ |
||||
|
var schema = new FilterSchema(FilterSchemaType.Object) |
||||
|
{ |
||||
|
Fields = new[] |
||||
|
{ |
||||
|
new FilterField(new FilterSchema(FilterSchemaType.Object) |
||||
|
{ |
||||
|
Fields = new[] |
||||
|
{ |
||||
|
new FilterField(new FilterSchema(FilterSchemaType.Object) |
||||
|
{ |
||||
|
Fields = new[] |
||||
|
{ |
||||
|
new FilterField(FilterSchema.Number, "nested3") |
||||
|
}.ToReadonlyList() |
||||
|
}, "nested2") |
||||
|
}.ToReadonlyList() |
||||
|
}, "nested1") |
||||
|
}.ToReadonlyList() |
||||
|
}; |
||||
|
|
||||
|
var expected = new FilterSchema(FilterSchemaType.Object) |
||||
|
{ |
||||
|
Fields = new[] |
||||
|
{ |
||||
|
new FilterField(new FilterSchema(FilterSchemaType.Object), "nested1"), |
||||
|
new FilterField(new FilterSchema(FilterSchemaType.Object), "nested1.nested2"), |
||||
|
new FilterField(new FilterSchema(FilterSchemaType.Number), "nested1.nested2.nested3") |
||||
|
}.ToReadonlyList() |
||||
|
}; |
||||
|
|
||||
|
var actual = schema.Flatten(); |
||||
|
|
||||
|
Assert.Equal(expected, actual); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_ignore_conflicts_when_flatten() |
||||
|
{ |
||||
|
var schema = new FilterSchema(FilterSchemaType.Object) |
||||
|
{ |
||||
|
Fields = new[] |
||||
|
{ |
||||
|
new FilterField(FilterSchema.Number, "property1"), |
||||
|
new FilterField(FilterSchema.String, "property1"), |
||||
|
new FilterField(FilterSchema.String, "property2"), |
||||
|
new FilterField(FilterSchema.String, "property2") |
||||
|
}.ToReadonlyList() |
||||
|
}; |
||||
|
|
||||
|
var expected = new FilterSchema(FilterSchemaType.Object) |
||||
|
{ |
||||
|
Fields = new[] |
||||
|
{ |
||||
|
new FilterField(FilterSchema.String, "property2") |
||||
|
}.ToReadonlyList() |
||||
|
}; |
||||
|
|
||||
|
var actual = schema.Flatten(); |
||||
|
|
||||
|
Assert.Equal(expected, actual); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_filter_out_fields_by_predicate_when_flatten() |
||||
|
{ |
||||
|
var schema = new FilterSchema(FilterSchemaType.Object) |
||||
|
{ |
||||
|
Fields = new[] |
||||
|
{ |
||||
|
new FilterField(new FilterSchema(FilterSchemaType.Object), "property1"), |
||||
|
new FilterField(FilterSchema.String, "property2"), |
||||
|
}.ToReadonlyList() |
||||
|
}; |
||||
|
|
||||
|
var expected = new FilterSchema(FilterSchemaType.Object) |
||||
|
{ |
||||
|
Fields = new[] |
||||
|
{ |
||||
|
new FilterField(FilterSchema.String, "property2") |
||||
|
}.ToReadonlyList() |
||||
|
}; |
||||
|
|
||||
|
var actual = schema.Flatten(predicate: x => x.Type != FilterSchemaType.Object); |
||||
|
|
||||
|
Assert.Equal(expected, actual); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_filter_out_fields_without_operators_when_flattened_by_model() |
||||
|
{ |
||||
|
var schema = new FilterSchema(FilterSchemaType.Object) |
||||
|
{ |
||||
|
Fields = new[] |
||||
|
{ |
||||
|
new FilterField(new FilterSchema(FilterSchemaType.Object), "property1"), |
||||
|
new FilterField(FilterSchema.String, "property2"), |
||||
|
}.ToReadonlyList() |
||||
|
}; |
||||
|
|
||||
|
var expected = new FilterSchema(FilterSchemaType.Object) |
||||
|
{ |
||||
|
Fields = new[] |
||||
|
{ |
||||
|
new FilterField(FilterSchema.String, "property2") |
||||
|
}.ToReadonlyList() |
||||
|
}; |
||||
|
|
||||
|
var actual = new QueryModel { Schema = schema }.Flatten().Schema; |
||||
|
|
||||
|
Assert.Equal(expected, actual); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void Should_not_filter_out_fields_without_operators_when_flattened_by_model_but_flag_is_false() |
||||
|
{ |
||||
|
var schema = new FilterSchema(FilterSchemaType.Object) |
||||
|
{ |
||||
|
Fields = new[] |
||||
|
{ |
||||
|
new FilterField(new FilterSchema(FilterSchemaType.Object), "property1"), |
||||
|
new FilterField(FilterSchema.String, "property2"), |
||||
|
}.ToReadonlyList() |
||||
|
}; |
||||
|
|
||||
|
var expected = new FilterSchema(FilterSchemaType.Object) |
||||
|
{ |
||||
|
Fields = new[] |
||||
|
{ |
||||
|
new FilterField(new FilterSchema(FilterSchemaType.Object), "property1"), |
||||
|
new FilterField(FilterSchema.String, "property2") |
||||
|
}.ToReadonlyList() |
||||
|
}; |
||||
|
|
||||
|
var actual = new QueryModel { Schema = schema }.Flatten(onlyWithOperators: false).Schema; |
||||
|
|
||||
|
Assert.Equal(expected, actual); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue