@panneau/protocol 5.0.0-alpha.4 → 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 +121 -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 -2
- package/dist/lint.d.ts.map +1 -1
- package/dist/lint.js +15 -9
- package/dist/lint.js.map +1 -1
- package/dist/mock/example.d.ts.map +1 -1
- package/dist/mock/example.js +8 -0
- 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 +119 -13
- package/dist/mock/index.js.map +1 -1
- package/dist/openapi.d.ts.map +1 -1
- package/dist/openapi.js +37 -7
- 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 +87 -0
- package/dist/schemas/api.d.ts.map +1 -1
- package/dist/schemas/api.js +28 -9
- package/dist/schemas/api.js.map +1 -1
- package/dist/schemas/definition.d.ts +38 -2
- package/dist/schemas/definition.d.ts.map +1 -1
- package/dist/schemas/definition.js +2 -1
- 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 +201 -6
- package/dist/schemas/index.d.ts.map +1 -1
- package/dist/schemas/index.js +4 -2
- package/dist/schemas/index.js.map +1 -1
- package/dist/schemas/resource.d.ts +36 -2
- package/dist/schemas/resource.d.ts.map +1 -1
- package/dist/schemas/resource.js +3 -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 +80 -1
- package/schema/definition.schema.json +80 -1
- package/schema/openapi.json +342 -13
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
|
@@ -200,6 +200,12 @@
|
|
|
200
200
|
"itemTitle": {
|
|
201
201
|
"type": "string"
|
|
202
202
|
},
|
|
203
|
+
"itemSubtitle": {
|
|
204
|
+
"type": "string"
|
|
205
|
+
},
|
|
206
|
+
"itemImage": {
|
|
207
|
+
"type": "string"
|
|
208
|
+
},
|
|
203
209
|
"fields": {
|
|
204
210
|
"type": "array",
|
|
205
211
|
"items": {
|
|
@@ -306,7 +312,20 @@
|
|
|
306
312
|
"type": "boolean"
|
|
307
313
|
},
|
|
308
314
|
"resource": {
|
|
309
|
-
"
|
|
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
|
+
]
|
|
310
329
|
},
|
|
311
330
|
"accept": {
|
|
312
331
|
"type": "array",
|
|
@@ -314,9 +333,33 @@
|
|
|
314
333
|
"type": "string"
|
|
315
334
|
}
|
|
316
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
|
+
},
|
|
317
357
|
"from": {
|
|
318
358
|
"type": "string"
|
|
319
359
|
},
|
|
360
|
+
"check": {
|
|
361
|
+
"type": "boolean"
|
|
362
|
+
},
|
|
320
363
|
"display": {
|
|
321
364
|
"type": "string"
|
|
322
365
|
},
|
|
@@ -542,6 +585,39 @@
|
|
|
542
585
|
],
|
|
543
586
|
"additionalProperties": {}
|
|
544
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
|
+
},
|
|
545
621
|
{
|
|
546
622
|
"type": "object",
|
|
547
623
|
"properties": {
|
|
@@ -1463,6 +1539,9 @@
|
|
|
1463
1539
|
},
|
|
1464
1540
|
"abilities": {
|
|
1465
1541
|
"$ref": "#/$defs/Abilities"
|
|
1542
|
+
},
|
|
1543
|
+
"resource": {
|
|
1544
|
+
"type": "string"
|
|
1466
1545
|
}
|
|
1467
1546
|
},
|
|
1468
1547
|
"required": [
|
|
@@ -166,6 +166,12 @@
|
|
|
166
166
|
"itemTitle": {
|
|
167
167
|
"type": "string"
|
|
168
168
|
},
|
|
169
|
+
"itemSubtitle": {
|
|
170
|
+
"type": "string"
|
|
171
|
+
},
|
|
172
|
+
"itemImage": {
|
|
173
|
+
"type": "string"
|
|
174
|
+
},
|
|
169
175
|
"fields": {
|
|
170
176
|
"type": "array",
|
|
171
177
|
"items": {
|
|
@@ -272,7 +278,20 @@
|
|
|
272
278
|
"type": "boolean"
|
|
273
279
|
},
|
|
274
280
|
"resource": {
|
|
275
|
-
"
|
|
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
|
+
]
|
|
276
295
|
},
|
|
277
296
|
"accept": {
|
|
278
297
|
"type": "array",
|
|
@@ -280,9 +299,33 @@
|
|
|
280
299
|
"type": "string"
|
|
281
300
|
}
|
|
282
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
|
+
},
|
|
283
323
|
"from": {
|
|
284
324
|
"type": "string"
|
|
285
325
|
},
|
|
326
|
+
"check": {
|
|
327
|
+
"type": "boolean"
|
|
328
|
+
},
|
|
286
329
|
"display": {
|
|
287
330
|
"type": "string"
|
|
288
331
|
},
|
|
@@ -508,6 +551,39 @@
|
|
|
508
551
|
],
|
|
509
552
|
"additionalProperties": {}
|
|
510
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
|
+
},
|
|
511
587
|
{
|
|
512
588
|
"type": "object",
|
|
513
589
|
"properties": {
|
|
@@ -1429,6 +1505,9 @@
|
|
|
1429
1505
|
},
|
|
1430
1506
|
"abilities": {
|
|
1431
1507
|
"$ref": "#/$defs/Abilities"
|
|
1508
|
+
},
|
|
1509
|
+
"resource": {
|
|
1510
|
+
"type": "string"
|
|
1432
1511
|
}
|
|
1433
1512
|
},
|
|
1434
1513
|
"required": [
|