@panneau/protocol 5.0.0-alpha.3 → 5.0.0-alpha.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/conformance/index.d.ts.map +1 -1
- package/dist/conformance/index.js +151 -1
- package/dist/conformance/index.js.map +1 -1
- package/dist/constants.d.ts +2 -2
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +3 -1
- package/dist/constants.js.map +1 -1
- package/dist/index.js +5 -2
- package/dist/libraries.d.ts +16 -0
- package/dist/libraries.d.ts.map +1 -0
- package/dist/libraries.js +15 -0
- package/dist/libraries.js.map +1 -0
- package/dist/lint.d.ts +2 -1
- package/dist/lint.d.ts.map +1 -1
- package/dist/lint.js +34 -2
- package/dist/lint.js.map +1 -1
- package/dist/mock/example.d.ts +2 -1
- package/dist/mock/example.d.ts.map +1 -1
- package/dist/mock/example.js +227 -143
- package/dist/mock/example.js.map +1 -1
- package/dist/mock/index.d.ts +9 -1
- package/dist/mock/index.d.ts.map +1 -1
- package/dist/mock/index.js +257 -11
- package/dist/mock/index.js.map +1 -1
- package/dist/openapi.d.ts.map +1 -1
- package/dist/openapi.js +55 -101
- package/dist/openapi.js.map +1 -1
- package/dist/rules.d.ts.map +1 -1
- package/dist/rules.js +17 -0
- package/dist/rules.js.map +1 -1
- package/dist/runtime/index.d.ts +3 -0
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/index.js +4 -1
- package/dist/schemas/action.d.ts +17 -1
- package/dist/schemas/action.d.ts.map +1 -1
- package/dist/schemas/api.d.ts +155 -37
- package/dist/schemas/api.d.ts.map +1 -1
- package/dist/schemas/api.js +89 -28
- package/dist/schemas/api.js.map +1 -1
- package/dist/schemas/definition.d.ts +39 -2
- package/dist/schemas/definition.d.ts.map +1 -1
- package/dist/schemas/definition.js +4 -3
- package/dist/schemas/definition.js.map +1 -1
- package/dist/schemas/field.d.ts +24 -1
- package/dist/schemas/field.d.ts.map +1 -1
- package/dist/schemas/field.js +22 -4
- package/dist/schemas/field.js.map +1 -1
- package/dist/schemas/index.d.ts +262 -40
- package/dist/schemas/index.d.ts.map +1 -1
- package/dist/schemas/index.js +13 -5
- package/dist/schemas/index.js.map +1 -1
- package/dist/schemas/resource.d.ts +37 -2
- package/dist/schemas/resource.d.ts.map +1 -1
- package/dist/schemas/resource.js +4 -1
- package/dist/schemas/resource.js.map +1 -1
- package/dist/search.d.ts +51 -0
- package/dist/search.d.ts.map +1 -0
- package/dist/search.js +53 -0
- package/dist/search.js.map +1 -0
- package/dist/transforms.d.ts +17 -0
- package/dist/transforms.d.ts.map +1 -0
- package/dist/transforms.js +34 -0
- package/dist/transforms.js.map +1 -0
- package/package.json +1 -1
- package/schema/boot.schema.json +84 -1
- package/schema/definition.schema.json +84 -1
- package/schema/openapi.json +771 -605
|
@@ -15,6 +15,7 @@ export declare const ResourceFeatures: z.ZodObject<{
|
|
|
15
15
|
}, z.core.$loose>;
|
|
16
16
|
export declare const Resource: z.ZodObject<{
|
|
17
17
|
id: z.ZodString;
|
|
18
|
+
kind: z.ZodOptional<z.ZodString>;
|
|
18
19
|
label: z.ZodObject<{
|
|
19
20
|
singular: z.ZodString;
|
|
20
21
|
plural: z.ZodString;
|
|
@@ -22,6 +23,8 @@ export declare const Resource: z.ZodObject<{
|
|
|
22
23
|
description: z.ZodOptional<z.ZodString>;
|
|
23
24
|
icon: z.ZodOptional<z.ZodString>;
|
|
24
25
|
itemTitle: z.ZodOptional<z.ZodString>;
|
|
26
|
+
itemSubtitle: z.ZodOptional<z.ZodString>;
|
|
27
|
+
itemImage: z.ZodOptional<z.ZodString>;
|
|
25
28
|
fields: z.ZodArray<z.ZodObject<{
|
|
26
29
|
name: z.ZodString;
|
|
27
30
|
type: z.ZodString;
|
|
@@ -75,6 +78,13 @@ export declare const Resource: z.ZodObject<{
|
|
|
75
78
|
field: z.ZodString;
|
|
76
79
|
}, z.core.$loose>]>;
|
|
77
80
|
message: z.ZodOptional<z.ZodString>;
|
|
81
|
+
}, z.core.$loose>, z.ZodObject<{
|
|
82
|
+
rule: z.ZodLiteral<"crop">;
|
|
83
|
+
value: z.ZodObject<{
|
|
84
|
+
ratios: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
85
|
+
required: z.ZodOptional<z.ZodBoolean>;
|
|
86
|
+
}, z.core.$loose>;
|
|
87
|
+
message: z.ZodOptional<z.ZodString>;
|
|
78
88
|
}, z.core.$loose>, z.ZodObject<{
|
|
79
89
|
rule: z.ZodString;
|
|
80
90
|
message: z.ZodOptional<z.ZodString>;
|
|
@@ -95,9 +105,18 @@ export declare const Resource: z.ZodObject<{
|
|
|
95
105
|
disabled: z.ZodOptional<z.ZodBoolean>;
|
|
96
106
|
}, z.core.$loose>>>;
|
|
97
107
|
multiple: z.ZodOptional<z.ZodBoolean>;
|
|
98
|
-
resource: z.ZodOptional<z.ZodString
|
|
108
|
+
resource: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
|
|
99
109
|
accept: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
110
|
+
ratios: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
111
|
+
rotate: z.ZodOptional<z.ZodBoolean>;
|
|
112
|
+
focalPoint: z.ZodOptional<z.ZodBoolean>;
|
|
113
|
+
transformBase: z.ZodOptional<z.ZodEnum<{
|
|
114
|
+
media: "media";
|
|
115
|
+
original: "original";
|
|
116
|
+
choose: "choose";
|
|
117
|
+
}>>;
|
|
100
118
|
from: z.ZodOptional<z.ZodString>;
|
|
119
|
+
check: z.ZodOptional<z.ZodBoolean>;
|
|
101
120
|
display: z.ZodOptional<z.ZodString>;
|
|
102
121
|
fields: z.ZodOptional<z.ZodArray<typeof Field>>;
|
|
103
122
|
types: z.ZodOptional<z.ZodArray<typeof BlockType>>;
|
|
@@ -244,6 +263,13 @@ export declare const Resource: z.ZodObject<{
|
|
|
244
263
|
field: z.ZodString;
|
|
245
264
|
}, z.core.$loose>]>;
|
|
246
265
|
message: z.ZodOptional<z.ZodString>;
|
|
266
|
+
}, z.core.$loose>, z.ZodObject<{
|
|
267
|
+
rule: z.ZodLiteral<"crop">;
|
|
268
|
+
value: z.ZodObject<{
|
|
269
|
+
ratios: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
270
|
+
required: z.ZodOptional<z.ZodBoolean>;
|
|
271
|
+
}, z.core.$loose>;
|
|
272
|
+
message: z.ZodOptional<z.ZodString>;
|
|
247
273
|
}, z.core.$loose>, z.ZodObject<{
|
|
248
274
|
rule: z.ZodString;
|
|
249
275
|
message: z.ZodOptional<z.ZodString>;
|
|
@@ -264,9 +290,18 @@ export declare const Resource: z.ZodObject<{
|
|
|
264
290
|
disabled: z.ZodOptional<z.ZodBoolean>;
|
|
265
291
|
}, z.core.$loose>>>;
|
|
266
292
|
multiple: z.ZodOptional<z.ZodBoolean>;
|
|
267
|
-
resource: z.ZodOptional<z.ZodString
|
|
293
|
+
resource: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
|
|
268
294
|
accept: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
295
|
+
ratios: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
296
|
+
rotate: z.ZodOptional<z.ZodBoolean>;
|
|
297
|
+
focalPoint: z.ZodOptional<z.ZodBoolean>;
|
|
298
|
+
transformBase: z.ZodOptional<z.ZodEnum<{
|
|
299
|
+
media: "media";
|
|
300
|
+
original: "original";
|
|
301
|
+
choose: "choose";
|
|
302
|
+
}>>;
|
|
269
303
|
from: z.ZodOptional<z.ZodString>;
|
|
304
|
+
check: z.ZodOptional<z.ZodBoolean>;
|
|
270
305
|
display: z.ZodOptional<z.ZodString>;
|
|
271
306
|
fields: z.ZodOptional<z.ZodArray<typeof Field>>;
|
|
272
307
|
types: z.ZodOptional<z.ZodArray<typeof BlockType>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resource.d.ts","sourceRoot":"","sources":["../../src/schemas/resource.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAGtC,eAAO,MAAM,gBAAgB;;;;;;;;;;;iBAmB3B,CAAC;AAEH,eAAO,MAAM,QAAQ
|
|
1
|
+
{"version":3,"file":"resource.d.ts","sourceRoot":"","sources":["../../src/schemas/resource.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAGtC,eAAO,MAAM,gBAAgB;;;;;;;;;;;iBAmB3B,CAAC;AAEH,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAkC6C,CAAC;AAEnE,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAChE,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,QAAQ,CAAC,CAAC;AAChD,sEAAsE;AACtE,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,QAAQ,CAAC,CAAC"}
|
package/dist/schemas/resource.js
CHANGED
|
@@ -12,10 +12,11 @@ var ResourceFeatures = z.looseObject({
|
|
|
12
12
|
mode: z.enum(["component", "iframe"]),
|
|
13
13
|
component: z.string().optional().meta({ description: "`component`: the plugin preview." })
|
|
14
14
|
})]).optional(),
|
|
15
|
-
search: z.boolean().optional().meta({ description: "Whether the resource is in the global search." })
|
|
15
|
+
search: z.boolean().optional().meta({ description: "Whether the resource is in the global search. Defaults to whether its list has a search (`list.search`)." })
|
|
16
16
|
});
|
|
17
17
|
var Resource = z.looseObject({
|
|
18
18
|
id: z.string().min(1),
|
|
19
|
+
kind: z.string().min(1).optional().meta({ description: "What the resource is. `media`: a library of media (decision 0026), with a `file` field and a `media` on each item. Without it, an ordinary resource. Clients treat a kind they don't know as an ordinary resource." }),
|
|
19
20
|
label: z.looseObject({
|
|
20
21
|
singular: z.string(),
|
|
21
22
|
plural: z.string()
|
|
@@ -23,6 +24,8 @@ var Resource = z.looseObject({
|
|
|
23
24
|
description: z.string().optional(),
|
|
24
25
|
icon: z.string().optional(),
|
|
25
26
|
itemTitle: z.string().optional().meta({ description: "The field used as the title of an item, in lists and pickers." }),
|
|
27
|
+
itemSubtitle: z.string().optional().meta({ description: "The field shown under the title of an item, in search results, cards and pickers." }),
|
|
28
|
+
itemImage: z.string().optional().meta({ description: "The field that holds the image of an item (a media or a URL), in search results, cards and pickers." }),
|
|
26
29
|
fields: z.array(Field),
|
|
27
30
|
form: z.looseObject({ layout: z.array(LayoutNode).optional() }).optional(),
|
|
28
31
|
list: ListDefinition.optional(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resource.js","names":[],"sources":["../../src/schemas/resource.ts"],"sourcesContent":["import { z } from 'zod';\n\nimport { Action } from './action';\nimport { Abilities } from './common';\nimport { BlockType, Field } from './field';\nimport { LayoutNode } from './layout';\nimport { ListDefinition } from './list';\n\nexport const ResourceFeatures = z.looseObject({\n drafts: z.boolean().optional(),\n revisions: z.boolean().optional(),\n preview: z\n .union([\n z.null(),\n z.looseObject({\n mode: z.enum(['component', 'iframe']),\n component: z\n .string()\n .optional()\n .meta({ description: '`component`: the plugin preview.' }),\n }),\n ])\n .optional(),\n search: z
|
|
1
|
+
{"version":3,"file":"resource.js","names":[],"sources":["../../src/schemas/resource.ts"],"sourcesContent":["import { z } from 'zod';\n\nimport { Action } from './action';\nimport { Abilities } from './common';\nimport { BlockType, Field } from './field';\nimport { LayoutNode } from './layout';\nimport { ListDefinition } from './list';\n\nexport const ResourceFeatures = z.looseObject({\n drafts: z.boolean().optional(),\n revisions: z.boolean().optional(),\n preview: z\n .union([\n z.null(),\n z.looseObject({\n mode: z.enum(['component', 'iframe']),\n component: z\n .string()\n .optional()\n .meta({ description: '`component`: the plugin preview.' }),\n }),\n ])\n .optional(),\n search: z.boolean().optional().meta({\n description:\n 'Whether the resource is in the global search. Defaults to whether its list has a search (`list.search`).',\n }),\n});\n\nexport const Resource = z\n .looseObject({\n id: z.string().min(1),\n kind: z.string().min(1).optional().meta({\n description:\n \"What the resource is. `media`: a library of media (decision 0026), with a `file` field and a `media` on each item. Without it, an ordinary resource. Clients treat a kind they don't know as an ordinary resource.\",\n }),\n label: z.looseObject({ singular: z.string(), plural: z.string() }),\n description: z.string().optional(),\n icon: z.string().optional(),\n itemTitle: z\n .string()\n .optional()\n .meta({ description: 'The field used as the title of an item, in lists and pickers.' }),\n itemSubtitle: z.string().optional().meta({\n description:\n 'The field shown under the title of an item, in search results, cards and pickers.',\n }),\n itemImage: z.string().optional().meta({\n description:\n 'The field that holds the image of an item (a media or a URL), in search results, cards and pickers.',\n }),\n fields: z.array(Field),\n form: z.looseObject({ layout: z.array(LayoutNode).optional() }).optional(),\n list: ListDefinition.optional(),\n actions: z.array(Action).optional(),\n abilities: Abilities.optional(),\n features: ResourceFeatures.optional(),\n types: z\n .array(BlockType)\n .optional()\n .meta({ description: 'Variants of the resource, each with its own extra fields.' }),\n settings: z.record(z.string(), z.unknown()).optional(),\n })\n .meta({ description: 'A set of items managed in the admin.' });\n\nexport type ResourceFeatures = z.infer<typeof ResourceFeatures>;\nexport type Resource = z.infer<typeof Resource>;\n/** A resource as a backend writes it, before defaults are applied. */\nexport type ResourceInput = z.input<typeof Resource>;\n"],"mappings":";;;;;;;AAQA,IAAa,mBAAmB,EAAE,YAAY;CAC1C,QAAQ,EAAE,QAAQ,CAAC,CAAC,SAAS;CAC7B,WAAW,EAAE,QAAQ,CAAC,CAAC,SAAS;CAChC,SAAS,EACJ,MAAM,CACH,EAAE,KAAK,GACP,EAAE,YAAY;EACV,MAAM,EAAE,KAAK,CAAC,aAAa,QAAQ,CAAC;EACpC,WAAW,EACN,OAAO,CAAC,CACR,SAAS,CAAC,CACV,KAAK,EAAE,aAAa,mCAAmC,CAAC;CACjE,CAAC,CACL,CAAC,CAAC,CACD,SAAS;CACd,QAAQ,EAAE,QAAQ,CAAC,CAAC,SAAS,CAAC,CAAC,KAAK,EAChC,aACI,2GACR,CAAC;AACL,CAAC;AAED,IAAa,WAAW,EACnB,YAAY;CACT,IAAI,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC;CACpB,MAAM,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,KAAK,EACpC,aACI,qNACR,CAAC;CACD,OAAO,EAAE,YAAY;EAAE,UAAU,EAAE,OAAO;EAAG,QAAQ,EAAE,OAAO;CAAE,CAAC;CACjE,aAAa,EAAE,OAAO,CAAC,CAAC,SAAS;CACjC,MAAM,EAAE,OAAO,CAAC,CAAC,SAAS;CAC1B,WAAW,EACN,OAAO,CAAC,CACR,SAAS,CAAC,CACV,KAAK,EAAE,aAAa,gEAAgE,CAAC;CAC1F,cAAc,EAAE,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,KAAK,EACrC,aACI,oFACR,CAAC;CACD,WAAW,EAAE,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,KAAK,EAClC,aACI,sGACR,CAAC;CACD,QAAQ,EAAE,MAAM,KAAK;CACrB,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,SAAS;CACzE,MAAM,eAAe,SAAS;CAC9B,SAAS,EAAE,MAAM,MAAM,CAAC,CAAC,SAAS;CAClC,WAAW,UAAU,SAAS;CAC9B,UAAU,iBAAiB,SAAS;CACpC,OAAO,EACF,MAAM,SAAS,CAAC,CAChB,SAAS,CAAC,CACV,KAAK,EAAE,aAAa,4DAA4D,CAAC;CACtF,UAAU,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS;AACzD,CAAC,CAAC,CACD,KAAK,EAAE,aAAa,uCAAuC,CAAC"}
|
package/dist/search.d.ts
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/** Shortest search, in characters once trimmed: shorter is a `422`. */
|
|
2
|
+
export declare const SEARCH_MIN_LENGTH = 2;
|
|
3
|
+
/** Longest search, in characters. */
|
|
4
|
+
export declare const SEARCH_MAX_LENGTH = 255;
|
|
5
|
+
/** Items per resource without a `limit`. */
|
|
6
|
+
export declare const SEARCH_DEFAULT_LIMIT = 5;
|
|
7
|
+
/** Highest `limit`, and most items of a response, every resource together. */
|
|
8
|
+
export declare const SEARCH_MAX_LIMIT = 20;
|
|
9
|
+
/** What the global search reads of a resource. */
|
|
10
|
+
export interface SearchableResource {
|
|
11
|
+
id: string;
|
|
12
|
+
features?: {
|
|
13
|
+
search?: boolean | undefined;
|
|
14
|
+
} | undefined;
|
|
15
|
+
list?: {
|
|
16
|
+
search?: boolean | undefined;
|
|
17
|
+
} | undefined;
|
|
18
|
+
}
|
|
19
|
+
/** Query of the global search (`GET /search`). */
|
|
20
|
+
export interface SearchQuery {
|
|
21
|
+
q: string;
|
|
22
|
+
/** Items per resource, from 1 to 20. Defaults to 5. */
|
|
23
|
+
limit?: number;
|
|
24
|
+
/** Ids of the searchable resources to search. Defaults to every one. */
|
|
25
|
+
resources?: readonly string[];
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Whether a resource is in the global search: its `features.search`, or, without it, whether its
|
|
29
|
+
* list has a search (`list.search`), so one setting serves both (decision 0029).
|
|
30
|
+
*/
|
|
31
|
+
export declare function isSearchableResource(resource: Omit<SearchableResource, 'id'>): boolean;
|
|
32
|
+
/** Serializes a search query: `q=été&limit=20&resources=pages,articles`. */
|
|
33
|
+
export declare function toSearchQueryParams(query: SearchQuery): URLSearchParams;
|
|
34
|
+
/** A search query as a backend reads it: valid, or the messages of its invalid parameters. */
|
|
35
|
+
export type ReadSearchQueryResult = {
|
|
36
|
+
query: Required<SearchQuery>;
|
|
37
|
+
errors?: undefined;
|
|
38
|
+
} | {
|
|
39
|
+
query?: undefined;
|
|
40
|
+
errors: Record<string, string[]>;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Reads the query string of `GET /search`: the reference of how a backend validates it. `q` is
|
|
44
|
+
* trimmed and needs 2 characters; `limit` is an integer from 1 to 20; `resources` lists searchable
|
|
45
|
+
* resources of the definition. Invalid parameters are a `422`, with `errors` keyed by parameter.
|
|
46
|
+
* Without `resources`, every searchable resource is searched, in the order of the definition.
|
|
47
|
+
*/
|
|
48
|
+
export declare function readSearchQuery(params: URLSearchParams, definition: {
|
|
49
|
+
resources: readonly SearchableResource[];
|
|
50
|
+
}): ReadSearchQueryResult;
|
|
51
|
+
//# sourceMappingURL=search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../src/search.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,eAAO,MAAM,iBAAiB,IAAI,CAAC;AACnC,qCAAqC;AACrC,eAAO,MAAM,iBAAiB,MAAM,CAAC;AACrC,4CAA4C;AAC5C,eAAO,MAAM,oBAAoB,IAAI,CAAC;AACtC,8EAA8E;AAC9E,eAAO,MAAM,gBAAgB,KAAK,CAAC;AAEnC,kDAAkD;AAClD,MAAM,WAAW,kBAAkB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;KAAE,GAAG,SAAS,CAAC;IACxD,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;KAAE,GAAG,SAAS,CAAC;CACvD;AAED,kDAAkD;AAClD,MAAM,WAAW,WAAW;IACxB,CAAC,EAAE,MAAM,CAAC;IACV,uDAAuD;IACvD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACjC;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,IAAI,CAAC,kBAAkB,EAAE,IAAI,CAAC,GAAG,OAAO,CAEtF;AAED,4EAA4E;AAC5E,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,WAAW,GAAG,eAAe,CASvE;AAED,8FAA8F;AAC9F,MAAM,MAAM,qBAAqB,GAC3B;IAAE,KAAK,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;IAAC,MAAM,CAAC,EAAE,SAAS,CAAA;CAAE,GACpD;IAAE,KAAK,CAAC,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;CAAE,CAAC;AAE9D;;;;;GAKG;AACH,wBAAgB,eAAe,CAC3B,MAAM,EAAE,eAAe,EACvB,UAAU,EAAE;IAAE,SAAS,EAAE,SAAS,kBAAkB,EAAE,CAAA;CAAE,GACzD,qBAAqB,CAyCvB"}
|
package/dist/search.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
//#region src/search.ts
|
|
2
|
+
/** Shortest search, in characters once trimmed: shorter is a `422`. */
|
|
3
|
+
var SEARCH_MIN_LENGTH = 2;
|
|
4
|
+
/** Longest search, in characters. */
|
|
5
|
+
var SEARCH_MAX_LENGTH = 255;
|
|
6
|
+
/** Items per resource without a `limit`. */
|
|
7
|
+
var SEARCH_DEFAULT_LIMIT = 5;
|
|
8
|
+
/** Highest `limit`, and most items of a response, every resource together. */
|
|
9
|
+
var SEARCH_MAX_LIMIT = 20;
|
|
10
|
+
/**
|
|
11
|
+
* Whether a resource is in the global search: its `features.search`, or, without it, whether its
|
|
12
|
+
* list has a search (`list.search`), so one setting serves both (decision 0029).
|
|
13
|
+
*/
|
|
14
|
+
function isSearchableResource(resource) {
|
|
15
|
+
return resource.features?.search ?? resource.list?.search ?? false;
|
|
16
|
+
}
|
|
17
|
+
/** Serializes a search query: `q=été&limit=20&resources=pages,articles`. */
|
|
18
|
+
function toSearchQueryParams(query) {
|
|
19
|
+
const params = new URLSearchParams({ q: query.q });
|
|
20
|
+
if (query.limit !== void 0) params.set("limit", String(query.limit));
|
|
21
|
+
if (query.resources !== void 0 && query.resources.length > 0) params.set("resources", query.resources.join(","));
|
|
22
|
+
return params;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Reads the query string of `GET /search`: the reference of how a backend validates it. `q` is
|
|
26
|
+
* trimmed and needs 2 characters; `limit` is an integer from 1 to 20; `resources` lists searchable
|
|
27
|
+
* resources of the definition. Invalid parameters are a `422`, with `errors` keyed by parameter.
|
|
28
|
+
* Without `resources`, every searchable resource is searched, in the order of the definition.
|
|
29
|
+
*/
|
|
30
|
+
function readSearchQuery(params, definition) {
|
|
31
|
+
const errors = {};
|
|
32
|
+
const q = (params.get("q") ?? "").trim();
|
|
33
|
+
if (q.length < 2) errors.q = [`The search must have at least 2 characters.`];
|
|
34
|
+
else if (q.length > 255) errors.q = [`The search must have at most 255 characters.`];
|
|
35
|
+
const rawLimit = params.get("limit");
|
|
36
|
+
const limit = rawLimit === null ? 5 : Number(rawLimit);
|
|
37
|
+
if (rawLimit !== null && (!/^\d+$/.test(rawLimit) || limit < 1 || limit > 20)) errors.limit = [`The limit must be an integer from 1 to 20.`];
|
|
38
|
+
const searchable = definition.resources.filter(isSearchableResource).map((resource) => resource.id);
|
|
39
|
+
const rawResources = params.get("resources");
|
|
40
|
+
const asked = rawResources === null ? searchable : rawResources.split(",").map((id) => id.trim()).filter((id) => id !== "");
|
|
41
|
+
const unknown = asked.filter((id) => !searchable.includes(id));
|
|
42
|
+
if (rawResources !== null && (asked.length === 0 || unknown.length > 0)) errors.resources = [unknown.length > 0 ? `These resources are not searchable: ${unknown.join(", ")}.` : "List at least one resource."];
|
|
43
|
+
if (Object.keys(errors).length > 0) return { errors };
|
|
44
|
+
return { query: {
|
|
45
|
+
q,
|
|
46
|
+
limit,
|
|
47
|
+
resources: searchable.filter((id) => asked.includes(id))
|
|
48
|
+
} };
|
|
49
|
+
}
|
|
50
|
+
//#endregion
|
|
51
|
+
export { SEARCH_DEFAULT_LIMIT, SEARCH_MAX_LENGTH, SEARCH_MAX_LIMIT, SEARCH_MIN_LENGTH, isSearchableResource, readSearchQuery, toSearchQueryParams };
|
|
52
|
+
|
|
53
|
+
//# sourceMappingURL=search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.js","names":[],"sources":["../src/search.ts"],"sourcesContent":["/** Shortest search, in characters once trimmed: shorter is a `422`. */\nexport const SEARCH_MIN_LENGTH = 2;\n/** Longest search, in characters. */\nexport const SEARCH_MAX_LENGTH = 255;\n/** Items per resource without a `limit`. */\nexport const SEARCH_DEFAULT_LIMIT = 5;\n/** Highest `limit`, and most items of a response, every resource together. */\nexport const SEARCH_MAX_LIMIT = 20;\n\n/** What the global search reads of a resource. */\nexport interface SearchableResource {\n id: string;\n features?: { search?: boolean | undefined } | undefined;\n list?: { search?: boolean | undefined } | undefined;\n}\n\n/** Query of the global search (`GET /search`). */\nexport interface SearchQuery {\n q: string;\n /** Items per resource, from 1 to 20. Defaults to 5. */\n limit?: number;\n /** Ids of the searchable resources to search. Defaults to every one. */\n resources?: readonly string[];\n}\n\n/**\n * Whether a resource is in the global search: its `features.search`, or, without it, whether its\n * list has a search (`list.search`), so one setting serves both (decision 0029).\n */\nexport function isSearchableResource(resource: Omit<SearchableResource, 'id'>): boolean {\n return resource.features?.search ?? resource.list?.search ?? false;\n}\n\n/** Serializes a search query: `q=été&limit=20&resources=pages,articles`. */\nexport function toSearchQueryParams(query: SearchQuery): URLSearchParams {\n const params = new URLSearchParams({ q: query.q });\n if (query.limit !== undefined) {\n params.set('limit', String(query.limit));\n }\n if (query.resources !== undefined && query.resources.length > 0) {\n params.set('resources', query.resources.join(','));\n }\n return params;\n}\n\n/** A search query as a backend reads it: valid, or the messages of its invalid parameters. */\nexport type ReadSearchQueryResult =\n | { query: Required<SearchQuery>; errors?: undefined }\n | { query?: undefined; errors: Record<string, string[]> };\n\n/**\n * Reads the query string of `GET /search`: the reference of how a backend validates it. `q` is\n * trimmed and needs 2 characters; `limit` is an integer from 1 to 20; `resources` lists searchable\n * resources of the definition. Invalid parameters are a `422`, with `errors` keyed by parameter.\n * Without `resources`, every searchable resource is searched, in the order of the definition.\n */\nexport function readSearchQuery(\n params: URLSearchParams,\n definition: { resources: readonly SearchableResource[] },\n): ReadSearchQueryResult {\n const errors: Record<string, string[]> = {};\n const q = (params.get('q') ?? '').trim();\n if (q.length < SEARCH_MIN_LENGTH) {\n errors.q = [`The search must have at least ${SEARCH_MIN_LENGTH} characters.`];\n } else if (q.length > SEARCH_MAX_LENGTH) {\n errors.q = [`The search must have at most ${SEARCH_MAX_LENGTH} characters.`];\n }\n\n const rawLimit = params.get('limit');\n const limit = rawLimit === null ? SEARCH_DEFAULT_LIMIT : Number(rawLimit);\n if (rawLimit !== null && (!/^\\d+$/.test(rawLimit) || limit < 1 || limit > SEARCH_MAX_LIMIT)) {\n errors.limit = [`The limit must be an integer from 1 to ${SEARCH_MAX_LIMIT}.`];\n }\n\n const searchable = definition.resources\n .filter(isSearchableResource)\n .map((resource) => resource.id);\n const rawResources = params.get('resources');\n const asked =\n rawResources === null\n ? searchable\n : rawResources\n .split(',')\n .map((id) => id.trim())\n .filter((id) => id !== '');\n const unknown = asked.filter((id) => !searchable.includes(id));\n if (rawResources !== null && (asked.length === 0 || unknown.length > 0)) {\n errors.resources = [\n unknown.length > 0\n ? `These resources are not searchable: ${unknown.join(', ')}.`\n : 'List at least one resource.',\n ];\n }\n\n if (Object.keys(errors).length > 0) {\n return { errors };\n }\n // The order of the definition, without duplicates\n const resources = searchable.filter((id) => asked.includes(id));\n return { query: { q, limit, resources } };\n}\n"],"mappings":";;AACA,IAAa,oBAAoB;;AAEjC,IAAa,oBAAoB;;AAEjC,IAAa,uBAAuB;;AAEpC,IAAa,mBAAmB;;;;;AAsBhC,SAAgB,qBAAqB,UAAmD;CACpF,OAAO,SAAS,UAAU,UAAU,SAAS,MAAM,UAAU;AACjE;;AAGA,SAAgB,oBAAoB,OAAqC;CACrE,MAAM,SAAS,IAAI,gBAAgB,EAAE,GAAG,MAAM,EAAE,CAAC;CACjD,IAAI,MAAM,UAAU,KAAA,GAChB,OAAO,IAAI,SAAS,OAAO,MAAM,KAAK,CAAC;CAE3C,IAAI,MAAM,cAAc,KAAA,KAAa,MAAM,UAAU,SAAS,GAC1D,OAAO,IAAI,aAAa,MAAM,UAAU,KAAK,GAAG,CAAC;CAErD,OAAO;AACX;;;;;;;AAaA,SAAgB,gBACZ,QACA,YACqB;CACrB,MAAM,SAAmC,CAAC;CAC1C,MAAM,KAAK,OAAO,IAAI,GAAG,KAAK,GAAA,CAAI,KAAK;CACvC,IAAI,EAAE,SAAA,GACF,OAAO,IAAI,CAAC,6CAAgE;MACzE,IAAI,EAAE,SAAA,KACT,OAAO,IAAI,CAAC,8CAA+D;CAG/E,MAAM,WAAW,OAAO,IAAI,OAAO;CACnC,MAAM,QAAQ,aAAa,OAAA,IAA8B,OAAO,QAAQ;CACxE,IAAI,aAAa,SAAS,CAAC,QAAQ,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAA,KAC9D,OAAO,QAAQ,CAAC,4CAA6D;CAGjF,MAAM,aAAa,WAAW,UACzB,OAAO,oBAAoB,CAAC,CAC5B,KAAK,aAAa,SAAS,EAAE;CAClC,MAAM,eAAe,OAAO,IAAI,WAAW;CAC3C,MAAM,QACF,iBAAiB,OACX,aACA,aACK,MAAM,GAAG,CAAC,CACV,KAAK,OAAO,GAAG,KAAK,CAAC,CAAC,CACtB,QAAQ,OAAO,OAAO,EAAE;CACvC,MAAM,UAAU,MAAM,QAAQ,OAAO,CAAC,WAAW,SAAS,EAAE,CAAC;CAC7D,IAAI,iBAAiB,SAAS,MAAM,WAAW,KAAK,QAAQ,SAAS,IACjE,OAAO,YAAY,CACf,QAAQ,SAAS,IACX,uCAAuC,QAAQ,KAAK,IAAI,EAAE,KAC1D,6BACV;CAGJ,IAAI,OAAO,KAAK,MAAM,CAAC,CAAC,SAAS,GAC7B,OAAO,EAAE,OAAO;CAIpB,OAAO,EAAE,OAAO;EAAE;EAAG;EAAO,WADV,WAAW,QAAQ,OAAO,MAAM,SAAS,EAAE,CACjC;CAAU,EAAE;AAC5C"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { MediaTransform } from './schemas/api';
|
|
2
|
+
/** The ratio of `width:height` (`16:9` gives 1.777…), or null when it isn't one. */
|
|
3
|
+
export declare function parseRatio(ratio: string): number | null;
|
|
4
|
+
/**
|
|
5
|
+
* Whether a size has a ratio (decision 0031): its height is within one pixel of its width divided
|
|
6
|
+
* by the ratio, since crops are in whole pixels.
|
|
7
|
+
*/
|
|
8
|
+
export declare function matchesRatio(width: number, height: number, ratio: number | string): boolean;
|
|
9
|
+
/**
|
|
10
|
+
* The size of the crop of a transform as it is rendered: a quarter turn swaps its width and its
|
|
11
|
+
* height. Null without a crop.
|
|
12
|
+
*/
|
|
13
|
+
export declare function renderedCropSize(transform: Pick<MediaTransform, 'crop' | 'rotate'>): {
|
|
14
|
+
width: number;
|
|
15
|
+
height: number;
|
|
16
|
+
} | null;
|
|
17
|
+
//# sourceMappingURL=transforms.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transforms.d.ts","sourceRoot":"","sources":["../src/transforms.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAGpD,oFAAoF;AACpF,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGvD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAG3F;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC5B,SAAS,EAAE,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,QAAQ,CAAC,GACnD;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAQ1C"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { isRecord } from "./values.js";
|
|
2
|
+
//#region src/transforms.ts
|
|
3
|
+
/** The ratio of `width:height` (`16:9` gives 1.777…), or null when it isn't one. */
|
|
4
|
+
function parseRatio(ratio) {
|
|
5
|
+
const match = /^([1-9][0-9]*):([1-9][0-9]*)$/.exec(ratio);
|
|
6
|
+
return match === null ? null : Number(match[1]) / Number(match[2]);
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Whether a size has a ratio (decision 0031): its height is within one pixel of its width divided
|
|
10
|
+
* by the ratio, since crops are in whole pixels.
|
|
11
|
+
*/
|
|
12
|
+
function matchesRatio(width, height, ratio) {
|
|
13
|
+
const value = typeof ratio === "number" ? ratio : parseRatio(ratio);
|
|
14
|
+
return value !== null && value > 0 && Math.abs(width / value - height) <= 1;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* The size of the crop of a transform as it is rendered: a quarter turn swaps its width and its
|
|
18
|
+
* height. Null without a crop.
|
|
19
|
+
*/
|
|
20
|
+
function renderedCropSize(transform) {
|
|
21
|
+
const crop = transform.crop;
|
|
22
|
+
if (!isRecord(crop) || typeof crop.width !== "number" || typeof crop.height !== "number") return null;
|
|
23
|
+
return transform.rotate === 90 || transform.rotate === 270 ? {
|
|
24
|
+
width: crop.height,
|
|
25
|
+
height: crop.width
|
|
26
|
+
} : {
|
|
27
|
+
width: crop.width,
|
|
28
|
+
height: crop.height
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
//#endregion
|
|
32
|
+
export { matchesRatio, parseRatio, renderedCropSize };
|
|
33
|
+
|
|
34
|
+
//# sourceMappingURL=transforms.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transforms.js","names":[],"sources":["../src/transforms.ts"],"sourcesContent":["import type { MediaTransform } from './schemas/api';\nimport { isRecord } from './values';\n\n/** The ratio of `width:height` (`16:9` gives 1.777…), or null when it isn't one. */\nexport function parseRatio(ratio: string): number | null {\n const match = /^([1-9][0-9]*):([1-9][0-9]*)$/.exec(ratio);\n return match === null ? null : Number(match[1]) / Number(match[2]);\n}\n\n/**\n * Whether a size has a ratio (decision 0031): its height is within one pixel of its width divided\n * by the ratio, since crops are in whole pixels.\n */\nexport function matchesRatio(width: number, height: number, ratio: number | string): boolean {\n const value = typeof ratio === 'number' ? ratio : parseRatio(ratio);\n return value !== null && value > 0 && Math.abs(width / value - height) <= 1;\n}\n\n/**\n * The size of the crop of a transform as it is rendered: a quarter turn swaps its width and its\n * height. Null without a crop.\n */\nexport function renderedCropSize(\n transform: Pick<MediaTransform, 'crop' | 'rotate'>,\n): { width: number; height: number } | null {\n const crop = transform.crop;\n if (!isRecord(crop) || typeof crop.width !== 'number' || typeof crop.height !== 'number') {\n return null;\n }\n return transform.rotate === 90 || transform.rotate === 270\n ? { width: crop.height, height: crop.width }\n : { width: crop.width, height: crop.height };\n}\n"],"mappings":";;;AAIA,SAAgB,WAAW,OAA8B;CACrD,MAAM,QAAQ,gCAAgC,KAAK,KAAK;CACxD,OAAO,UAAU,OAAO,OAAO,OAAO,MAAM,EAAE,IAAI,OAAO,MAAM,EAAE;AACrE;;;;;AAMA,SAAgB,aAAa,OAAe,QAAgB,OAAiC;CACzF,MAAM,QAAQ,OAAO,UAAU,WAAW,QAAQ,WAAW,KAAK;CAClE,OAAO,UAAU,QAAQ,QAAQ,KAAK,KAAK,IAAI,QAAQ,QAAQ,MAAM,KAAK;AAC9E;;;;;AAMA,SAAgB,iBACZ,WACwC;CACxC,MAAM,OAAO,UAAU;CACvB,IAAI,CAAC,SAAS,IAAI,KAAK,OAAO,KAAK,UAAU,YAAY,OAAO,KAAK,WAAW,UAC5E,OAAO;CAEX,OAAO,UAAU,WAAW,MAAM,UAAU,WAAW,MACjD;EAAE,OAAO,KAAK;EAAQ,QAAQ,KAAK;CAAM,IACzC;EAAE,OAAO,KAAK;EAAO,QAAQ,KAAK;CAAO;AACnD"}
|
package/package.json
CHANGED
package/schema/boot.schema.json
CHANGED
|
@@ -171,6 +171,10 @@
|
|
|
171
171
|
"type": "string",
|
|
172
172
|
"minLength": 1
|
|
173
173
|
},
|
|
174
|
+
"kind": {
|
|
175
|
+
"type": "string",
|
|
176
|
+
"minLength": 1
|
|
177
|
+
},
|
|
174
178
|
"label": {
|
|
175
179
|
"type": "object",
|
|
176
180
|
"properties": {
|
|
@@ -196,6 +200,12 @@
|
|
|
196
200
|
"itemTitle": {
|
|
197
201
|
"type": "string"
|
|
198
202
|
},
|
|
203
|
+
"itemSubtitle": {
|
|
204
|
+
"type": "string"
|
|
205
|
+
},
|
|
206
|
+
"itemImage": {
|
|
207
|
+
"type": "string"
|
|
208
|
+
},
|
|
199
209
|
"fields": {
|
|
200
210
|
"type": "array",
|
|
201
211
|
"items": {
|
|
@@ -302,7 +312,20 @@
|
|
|
302
312
|
"type": "boolean"
|
|
303
313
|
},
|
|
304
314
|
"resource": {
|
|
305
|
-
"
|
|
315
|
+
"anyOf": [
|
|
316
|
+
{
|
|
317
|
+
"type": "string",
|
|
318
|
+
"minLength": 1
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
"minItems": 1,
|
|
322
|
+
"type": "array",
|
|
323
|
+
"items": {
|
|
324
|
+
"type": "string",
|
|
325
|
+
"minLength": 1
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
]
|
|
306
329
|
},
|
|
307
330
|
"accept": {
|
|
308
331
|
"type": "array",
|
|
@@ -310,9 +333,33 @@
|
|
|
310
333
|
"type": "string"
|
|
311
334
|
}
|
|
312
335
|
},
|
|
336
|
+
"ratios": {
|
|
337
|
+
"type": "array",
|
|
338
|
+
"items": {
|
|
339
|
+
"type": "string",
|
|
340
|
+
"pattern": "^[1-9][0-9]*:[1-9][0-9]*$"
|
|
341
|
+
}
|
|
342
|
+
},
|
|
343
|
+
"rotate": {
|
|
344
|
+
"type": "boolean"
|
|
345
|
+
},
|
|
346
|
+
"focalPoint": {
|
|
347
|
+
"type": "boolean"
|
|
348
|
+
},
|
|
349
|
+
"transformBase": {
|
|
350
|
+
"type": "string",
|
|
351
|
+
"enum": [
|
|
352
|
+
"media",
|
|
353
|
+
"original",
|
|
354
|
+
"choose"
|
|
355
|
+
]
|
|
356
|
+
},
|
|
313
357
|
"from": {
|
|
314
358
|
"type": "string"
|
|
315
359
|
},
|
|
360
|
+
"check": {
|
|
361
|
+
"type": "boolean"
|
|
362
|
+
},
|
|
316
363
|
"display": {
|
|
317
364
|
"type": "string"
|
|
318
365
|
},
|
|
@@ -538,6 +585,39 @@
|
|
|
538
585
|
],
|
|
539
586
|
"additionalProperties": {}
|
|
540
587
|
},
|
|
588
|
+
{
|
|
589
|
+
"type": "object",
|
|
590
|
+
"properties": {
|
|
591
|
+
"rule": {
|
|
592
|
+
"type": "string",
|
|
593
|
+
"const": "crop"
|
|
594
|
+
},
|
|
595
|
+
"value": {
|
|
596
|
+
"type": "object",
|
|
597
|
+
"properties": {
|
|
598
|
+
"ratios": {
|
|
599
|
+
"type": "array",
|
|
600
|
+
"items": {
|
|
601
|
+
"type": "string",
|
|
602
|
+
"pattern": "^[1-9][0-9]*:[1-9][0-9]*$"
|
|
603
|
+
}
|
|
604
|
+
},
|
|
605
|
+
"required": {
|
|
606
|
+
"type": "boolean"
|
|
607
|
+
}
|
|
608
|
+
},
|
|
609
|
+
"additionalProperties": {}
|
|
610
|
+
},
|
|
611
|
+
"message": {
|
|
612
|
+
"type": "string"
|
|
613
|
+
}
|
|
614
|
+
},
|
|
615
|
+
"required": [
|
|
616
|
+
"rule",
|
|
617
|
+
"value"
|
|
618
|
+
],
|
|
619
|
+
"additionalProperties": {}
|
|
620
|
+
},
|
|
541
621
|
{
|
|
542
622
|
"type": "object",
|
|
543
623
|
"properties": {
|
|
@@ -1459,6 +1539,9 @@
|
|
|
1459
1539
|
},
|
|
1460
1540
|
"abilities": {
|
|
1461
1541
|
"$ref": "#/$defs/Abilities"
|
|
1542
|
+
},
|
|
1543
|
+
"resource": {
|
|
1544
|
+
"type": "string"
|
|
1462
1545
|
}
|
|
1463
1546
|
},
|
|
1464
1547
|
"required": [
|
|
@@ -137,6 +137,10 @@
|
|
|
137
137
|
"type": "string",
|
|
138
138
|
"minLength": 1
|
|
139
139
|
},
|
|
140
|
+
"kind": {
|
|
141
|
+
"type": "string",
|
|
142
|
+
"minLength": 1
|
|
143
|
+
},
|
|
140
144
|
"label": {
|
|
141
145
|
"type": "object",
|
|
142
146
|
"properties": {
|
|
@@ -162,6 +166,12 @@
|
|
|
162
166
|
"itemTitle": {
|
|
163
167
|
"type": "string"
|
|
164
168
|
},
|
|
169
|
+
"itemSubtitle": {
|
|
170
|
+
"type": "string"
|
|
171
|
+
},
|
|
172
|
+
"itemImage": {
|
|
173
|
+
"type": "string"
|
|
174
|
+
},
|
|
165
175
|
"fields": {
|
|
166
176
|
"type": "array",
|
|
167
177
|
"items": {
|
|
@@ -268,7 +278,20 @@
|
|
|
268
278
|
"type": "boolean"
|
|
269
279
|
},
|
|
270
280
|
"resource": {
|
|
271
|
-
"
|
|
281
|
+
"anyOf": [
|
|
282
|
+
{
|
|
283
|
+
"type": "string",
|
|
284
|
+
"minLength": 1
|
|
285
|
+
},
|
|
286
|
+
{
|
|
287
|
+
"minItems": 1,
|
|
288
|
+
"type": "array",
|
|
289
|
+
"items": {
|
|
290
|
+
"type": "string",
|
|
291
|
+
"minLength": 1
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
]
|
|
272
295
|
},
|
|
273
296
|
"accept": {
|
|
274
297
|
"type": "array",
|
|
@@ -276,9 +299,33 @@
|
|
|
276
299
|
"type": "string"
|
|
277
300
|
}
|
|
278
301
|
},
|
|
302
|
+
"ratios": {
|
|
303
|
+
"type": "array",
|
|
304
|
+
"items": {
|
|
305
|
+
"type": "string",
|
|
306
|
+
"pattern": "^[1-9][0-9]*:[1-9][0-9]*$"
|
|
307
|
+
}
|
|
308
|
+
},
|
|
309
|
+
"rotate": {
|
|
310
|
+
"type": "boolean"
|
|
311
|
+
},
|
|
312
|
+
"focalPoint": {
|
|
313
|
+
"type": "boolean"
|
|
314
|
+
},
|
|
315
|
+
"transformBase": {
|
|
316
|
+
"type": "string",
|
|
317
|
+
"enum": [
|
|
318
|
+
"media",
|
|
319
|
+
"original",
|
|
320
|
+
"choose"
|
|
321
|
+
]
|
|
322
|
+
},
|
|
279
323
|
"from": {
|
|
280
324
|
"type": "string"
|
|
281
325
|
},
|
|
326
|
+
"check": {
|
|
327
|
+
"type": "boolean"
|
|
328
|
+
},
|
|
282
329
|
"display": {
|
|
283
330
|
"type": "string"
|
|
284
331
|
},
|
|
@@ -504,6 +551,39 @@
|
|
|
504
551
|
],
|
|
505
552
|
"additionalProperties": {}
|
|
506
553
|
},
|
|
554
|
+
{
|
|
555
|
+
"type": "object",
|
|
556
|
+
"properties": {
|
|
557
|
+
"rule": {
|
|
558
|
+
"type": "string",
|
|
559
|
+
"const": "crop"
|
|
560
|
+
},
|
|
561
|
+
"value": {
|
|
562
|
+
"type": "object",
|
|
563
|
+
"properties": {
|
|
564
|
+
"ratios": {
|
|
565
|
+
"type": "array",
|
|
566
|
+
"items": {
|
|
567
|
+
"type": "string",
|
|
568
|
+
"pattern": "^[1-9][0-9]*:[1-9][0-9]*$"
|
|
569
|
+
}
|
|
570
|
+
},
|
|
571
|
+
"required": {
|
|
572
|
+
"type": "boolean"
|
|
573
|
+
}
|
|
574
|
+
},
|
|
575
|
+
"additionalProperties": {}
|
|
576
|
+
},
|
|
577
|
+
"message": {
|
|
578
|
+
"type": "string"
|
|
579
|
+
}
|
|
580
|
+
},
|
|
581
|
+
"required": [
|
|
582
|
+
"rule",
|
|
583
|
+
"value"
|
|
584
|
+
],
|
|
585
|
+
"additionalProperties": {}
|
|
586
|
+
},
|
|
507
587
|
{
|
|
508
588
|
"type": "object",
|
|
509
589
|
"properties": {
|
|
@@ -1425,6 +1505,9 @@
|
|
|
1425
1505
|
},
|
|
1426
1506
|
"abilities": {
|
|
1427
1507
|
"$ref": "#/$defs/Abilities"
|
|
1508
|
+
},
|
|
1509
|
+
"resource": {
|
|
1510
|
+
"type": "string"
|
|
1428
1511
|
}
|
|
1429
1512
|
},
|
|
1430
1513
|
"required": [
|