@cratis/scene.engine 4.39.0 → 4.41.0

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.
@@ -7,3 +7,4 @@ export * from './blueprintRules';
7
7
  export * from './verifyBlueprintPackage';
8
8
  export * from './describeBlueprintCatalog';
9
9
  export * from './evaluateBlueprintPin';
10
+ export * from './verifyTemplateDefinitionOfDone';
@@ -0,0 +1,126 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ import { FlowArrangement, FlowNode, SampleDataPack, ScreenTemplate } from '@cratis/scene.model';
5
+ import { resolveScreenTemplates } from '../resolveScreenTemplates';
6
+ import { findTemplateSampleRowLiterals } from '../sampleData/findSampleRowLiterals';
7
+ import { validateTemplateMetadata } from '../templates/validateTemplateMetadata';
8
+ import { TemplateSource } from '../templates/TemplateSource';
9
+ import { BlueprintSource } from './BlueprintSource';
10
+ import { blueprintTemplateTypes, isValidThumbnailPath } from './blueprintRules';
11
+
12
+ /** What {@link verifyTemplateDefinitionOfDone} holds a template to beyond the rules every template has. */
13
+ export interface TemplateDefinitionOfDoneOptions {
14
+ /** The category prefix the template's category must start with, e.g. `Foundation /`. */
15
+ categoryPrefix?: string;
16
+
17
+ /** The sample-data pack the template is previewed with. When given, every query the template binds to must be answered by one of its shapes. */
18
+ pack?: SampleDataPack;
19
+ }
20
+
21
+ interface ScannedElement { properties?: Record<string, unknown>; slots?: Record<string, ScannedElement[]> }
22
+
23
+ /**
24
+ * The per-template definition of done (spec Part B 6), as one reusable check every blueprint package's specs call for each of its
25
+ * templates: complete metadata, a type from the vocabulary, a category, a display name and a one-sentence description, a thumbnail
26
+ * that is in the package, a slot arrangement that places every declared slot and no other, placement by the slot resolver (not
27
+ * unplaced, not nested in itself), no inline sample rows (the preview data is a sample-data pack, SD1), and - given the pack - every
28
+ * bound query answered by it. Verification of the whole package is {@link verifyBlueprintPackage}; this is the template-level
29
+ * checklist a spec can assert for each template by name, so a failure says which template and which rule.
30
+ *
31
+ * @param template The screen template.
32
+ * @param source The blueprint that provides it.
33
+ * @param library The other packages available, so the template can be placed into their layouts.
34
+ * @param options What else to hold it to.
35
+ * @returns The problems; empty when the template is done.
36
+ */
37
+ export function verifyTemplateDefinitionOfDone(template: ScreenTemplate, source: BlueprintSource, library: readonly TemplateSource[] = [], options: TemplateDefinitionOfDoneOptions = {}): string[] {
38
+ const owner = `Template '${template.name}'`;
39
+ const problems: string[] = [...validateTemplateMetadata(template.name, template.metadata)];
40
+ const metadata = template.metadata;
41
+
42
+ if ((template.displayName ?? '').trim() === '') problems.push(`${owner} declares no display name`);
43
+ const description = (template.description ?? '').trim();
44
+ if (description === '') problems.push(`${owner} declares no description`);
45
+ else if (!/^\p{Lu}.*\.$/u.test(description) || description.includes('. ')) problems.push(`${owner} describes itself in more than one sentence, or without a full stop`);
46
+
47
+ if (metadata?.type === undefined) problems.push(`${owner} declares no type`);
48
+ else if (!blueprintTemplateTypes.includes(metadata.type)) problems.push(`${owner} declares type '${metadata.type}', which is not one of ${blueprintTemplateTypes.join(', ')}`);
49
+
50
+ if ((metadata?.category ?? '').trim() === '') problems.push(`${owner} declares no category`);
51
+ else if (options.categoryPrefix !== undefined && !metadata!.category!.startsWith(options.categoryPrefix)) problems.push(`${owner} declares category '${metadata!.category}', which does not start with '${options.categoryPrefix}'`);
52
+
53
+ if ((metadata?.thumbnail ?? '').trim() === '') problems.push(`${owner} declares no thumbnail`);
54
+ else if (!isValidThumbnailPath(metadata!.thumbnail)) problems.push(`${owner} declares thumbnail '${metadata!.thumbnail}', which is not 'thumbnails/<name>.png|webp|jpg|svg'`);
55
+ else if (source.files !== undefined && !source.files.includes(metadata!.thumbnail!)) problems.push(`${owner} declares thumbnail '${metadata!.thumbnail}', which is not in the package`);
56
+
57
+ problems.push(...slotProblems(template, owner));
58
+ problems.push(...placementProblems(template, source, library, owner));
59
+
60
+ for (const literal of findTemplateSampleRowLiterals(template.content as Record<string, ScannedElement[]> | undefined)) {
61
+ problems.push(`${owner} carries sample rows inline at ${literal}; preview data belongs in a sample-data pack`);
62
+ }
63
+
64
+ if (options.pack !== undefined) {
65
+ const shapes = new Set(options.pack.sets.map(set => set.shape));
66
+ for (const query of queriesBoundBy(template).filter(name => !shapes.has(name))) {
67
+ problems.push(`${owner} binds to query '${query}', which sample-data pack '${options.pack.id}' does not answer`);
68
+ }
69
+ }
70
+
71
+ return problems;
72
+ }
73
+
74
+ function slotProblems(template: ScreenTemplate, owner: string): string[] {
75
+ const declared = template.slots.map(slot => slot.name);
76
+ const arranged = new Set<string>();
77
+ const visit = (node: FlowNode | undefined) => {
78
+ if (!node) return;
79
+ const named = node as { slotName?: string; children?: FlowNode[] };
80
+ if (named.slotName !== undefined) arranged.add(named.slotName);
81
+ named.children?.forEach(visit);
82
+ };
83
+
84
+ const arrangement = template.arrangement as FlowArrangement | undefined;
85
+ visit(arrangement?.root);
86
+ arrangement?.overrides?.forEach(override => visit(override.root));
87
+
88
+ const problems: string[] = [];
89
+ for (const name of declared.filter(slot => !arranged.has(slot))) problems.push(`${owner} declares slot '${name}' but its arrangement never places it`);
90
+ for (const name of [...arranged].filter(slot => !declared.includes(slot))) problems.push(`${owner} arranges slot '${name}', which it does not declare`);
91
+ for (const name of Object.keys(template.content ?? {}).filter(slot => !declared.includes(slot))) problems.push(`${owner} fills slot '${name}', which it does not declare`);
92
+ return problems;
93
+ }
94
+
95
+ function placementProblems(template: ScreenTemplate, source: BlueprintSource, library: readonly TemplateSource[], owner: string): string[] {
96
+ if (template.fitsSlot === undefined) return [];
97
+ const layouts = [...(source.layouts ?? []), ...library.flatMap(other => other.layouts ?? [])];
98
+ const everyTemplate = [...(source.screenTemplates ?? []), ...library.flatMap(other => other.screenTemplates ?? [])];
99
+ const resolutions = layouts.map(layout => resolveScreenTemplates(layout, everyTemplate));
100
+
101
+ if (resolutions.some(resolution => resolution.placements.some(placement => placement.template === template.name))) return [];
102
+ if (resolutions.some(resolution => resolution.cycles.some(cycle => cycle.includes(template.name)))) return [`${owner} is nested inside itself`];
103
+ return [`${owner} is unplaced: no layout or template declares slot '${template.fitsSlot}'`];
104
+ }
105
+
106
+ function queriesBoundBy(template: ScreenTemplate): string[] {
107
+ const queries = new Set<string>();
108
+ const visitValue = (value: unknown) => {
109
+ if (Array.isArray(value)) value.forEach(visitValue);
110
+ else if (typeof value === 'object' && value !== null) {
111
+ const candidate = value as { query?: unknown; path?: unknown };
112
+ if (typeof candidate.query === 'string' && 'path' in candidate) queries.add(candidate.query);
113
+ Object.values(value).forEach(visitValue);
114
+ }
115
+ };
116
+
117
+ const visit = (elements: ScannedElement[] | undefined) => {
118
+ for (const element of elements ?? []) {
119
+ Object.values(element.properties ?? {}).forEach(visitValue);
120
+ Object.values(element.slots ?? {}).forEach(visit);
121
+ }
122
+ };
123
+
124
+ Object.values(template.content ?? {}).forEach(content => visit(content as ScannedElement[]));
125
+ return [...queries].sort();
126
+ }
@@ -0,0 +1,115 @@
1
+ 'use strict';
2
+
3
+ var resolveScreenTemplates = require('../resolveScreenTemplates.js');
4
+ var findSampleRowLiterals = require('../sampleData/findSampleRowLiterals.js');
5
+ var validateTemplateMetadata = require('../templates/validateTemplateMetadata.js');
6
+ var blueprintRules = require('./blueprintRules.js');
7
+
8
+ // Copyright (c) Cratis. All rights reserved.
9
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
10
+ /**
11
+ * The per-template definition of done (spec Part B 6), as one reusable check every blueprint package's specs call for each of its
12
+ * templates: complete metadata, a type from the vocabulary, a category, a display name and a one-sentence description, a thumbnail
13
+ * that is in the package, a slot arrangement that places every declared slot and no other, placement by the slot resolver (not
14
+ * unplaced, not nested in itself), no inline sample rows (the preview data is a sample-data pack, SD1), and - given the pack - every
15
+ * bound query answered by it. Verification of the whole package is {@link verifyBlueprintPackage}; this is the template-level
16
+ * checklist a spec can assert for each template by name, so a failure says which template and which rule.
17
+ *
18
+ * @param template The screen template.
19
+ * @param source The blueprint that provides it.
20
+ * @param library The other packages available, so the template can be placed into their layouts.
21
+ * @param options What else to hold it to.
22
+ * @returns The problems; empty when the template is done.
23
+ */ function verifyTemplateDefinitionOfDone(template, source, library = [], options = {}) {
24
+ const owner = `Template '${template.name}'`;
25
+ const problems = [
26
+ ...validateTemplateMetadata.validateTemplateMetadata(template.name, template.metadata)
27
+ ];
28
+ const metadata = template.metadata;
29
+ if ((template.displayName ?? '').trim() === '') problems.push(`${owner} declares no display name`);
30
+ const description = (template.description ?? '').trim();
31
+ if (description === '') problems.push(`${owner} declares no description`);
32
+ else if (!/^\p{Lu}.*\.$/u.test(description) || description.includes('. ')) problems.push(`${owner} describes itself in more than one sentence, or without a full stop`);
33
+ if (metadata?.type === undefined) problems.push(`${owner} declares no type`);
34
+ else if (!blueprintRules.blueprintTemplateTypes.includes(metadata.type)) problems.push(`${owner} declares type '${metadata.type}', which is not one of ${blueprintRules.blueprintTemplateTypes.join(', ')}`);
35
+ if ((metadata?.category ?? '').trim() === '') problems.push(`${owner} declares no category`);
36
+ else if (options.categoryPrefix !== undefined && !metadata.category.startsWith(options.categoryPrefix)) problems.push(`${owner} declares category '${metadata.category}', which does not start with '${options.categoryPrefix}'`);
37
+ if ((metadata?.thumbnail ?? '').trim() === '') problems.push(`${owner} declares no thumbnail`);
38
+ else if (!blueprintRules.isValidThumbnailPath(metadata.thumbnail)) problems.push(`${owner} declares thumbnail '${metadata.thumbnail}', which is not 'thumbnails/<name>.png|webp|jpg|svg'`);
39
+ else if (source.files !== undefined && !source.files.includes(metadata.thumbnail)) problems.push(`${owner} declares thumbnail '${metadata.thumbnail}', which is not in the package`);
40
+ problems.push(...slotProblems(template, owner));
41
+ problems.push(...placementProblems(template, source, library, owner));
42
+ for (const literal of findSampleRowLiterals.findTemplateSampleRowLiterals(template.content)){
43
+ problems.push(`${owner} carries sample rows inline at ${literal}; preview data belongs in a sample-data pack`);
44
+ }
45
+ if (options.pack !== undefined) {
46
+ const shapes = new Set(options.pack.sets.map((set)=>set.shape));
47
+ for (const query of queriesBoundBy(template).filter((name)=>!shapes.has(name))){
48
+ problems.push(`${owner} binds to query '${query}', which sample-data pack '${options.pack.id}' does not answer`);
49
+ }
50
+ }
51
+ return problems;
52
+ }
53
+ function slotProblems(template, owner) {
54
+ const declared = template.slots.map((slot)=>slot.name);
55
+ const arranged = new Set();
56
+ const visit = (node)=>{
57
+ if (!node) return;
58
+ const named = node;
59
+ if (named.slotName !== undefined) arranged.add(named.slotName);
60
+ named.children?.forEach(visit);
61
+ };
62
+ const arrangement = template.arrangement;
63
+ visit(arrangement?.root);
64
+ arrangement?.overrides?.forEach((override)=>visit(override.root));
65
+ const problems = [];
66
+ for (const name of declared.filter((slot)=>!arranged.has(slot)))problems.push(`${owner} declares slot '${name}' but its arrangement never places it`);
67
+ for (const name of [
68
+ ...arranged
69
+ ].filter((slot)=>!declared.includes(slot)))problems.push(`${owner} arranges slot '${name}', which it does not declare`);
70
+ for (const name of Object.keys(template.content ?? {}).filter((slot)=>!declared.includes(slot)))problems.push(`${owner} fills slot '${name}', which it does not declare`);
71
+ return problems;
72
+ }
73
+ function placementProblems(template, source, library, owner) {
74
+ if (template.fitsSlot === undefined) return [];
75
+ const layouts = [
76
+ ...source.layouts ?? [],
77
+ ...library.flatMap((other)=>other.layouts ?? [])
78
+ ];
79
+ const everyTemplate = [
80
+ ...source.screenTemplates ?? [],
81
+ ...library.flatMap((other)=>other.screenTemplates ?? [])
82
+ ];
83
+ const resolutions = layouts.map((layout)=>resolveScreenTemplates.resolveScreenTemplates(layout, everyTemplate));
84
+ if (resolutions.some((resolution)=>resolution.placements.some((placement)=>placement.template === template.name))) return [];
85
+ if (resolutions.some((resolution)=>resolution.cycles.some((cycle)=>cycle.includes(template.name)))) return [
86
+ `${owner} is nested inside itself`
87
+ ];
88
+ return [
89
+ `${owner} is unplaced: no layout or template declares slot '${template.fitsSlot}'`
90
+ ];
91
+ }
92
+ function queriesBoundBy(template) {
93
+ const queries = new Set();
94
+ const visitValue = (value)=>{
95
+ if (Array.isArray(value)) value.forEach(visitValue);
96
+ else if (typeof value === 'object' && value !== null) {
97
+ const candidate = value;
98
+ if (typeof candidate.query === 'string' && 'path' in candidate) queries.add(candidate.query);
99
+ Object.values(value).forEach(visitValue);
100
+ }
101
+ };
102
+ const visit = (elements)=>{
103
+ for (const element of elements ?? []){
104
+ Object.values(element.properties ?? {}).forEach(visitValue);
105
+ Object.values(element.slots ?? {}).forEach(visit);
106
+ }
107
+ };
108
+ Object.values(template.content ?? {}).forEach((content)=>visit(content));
109
+ return [
110
+ ...queries
111
+ ].sort();
112
+ }
113
+
114
+ exports.verifyTemplateDefinitionOfDone = verifyTemplateDefinitionOfDone;
115
+ //# sourceMappingURL=verifyTemplateDefinitionOfDone.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verifyTemplateDefinitionOfDone.js","sources":["../../../blueprints/verifyTemplateDefinitionOfDone.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { FlowArrangement, FlowNode, SampleDataPack, ScreenTemplate } from '@cratis/scene.model';\nimport { resolveScreenTemplates } from '../resolveScreenTemplates';\nimport { findTemplateSampleRowLiterals } from '../sampleData/findSampleRowLiterals';\nimport { validateTemplateMetadata } from '../templates/validateTemplateMetadata';\nimport { TemplateSource } from '../templates/TemplateSource';\nimport { BlueprintSource } from './BlueprintSource';\nimport { blueprintTemplateTypes, isValidThumbnailPath } from './blueprintRules';\n\n/** What {@link verifyTemplateDefinitionOfDone} holds a template to beyond the rules every template has. */\nexport interface TemplateDefinitionOfDoneOptions {\n /** The category prefix the template's category must start with, e.g. `Foundation /`. */\n categoryPrefix?: string;\n\n /** The sample-data pack the template is previewed with. When given, every query the template binds to must be answered by one of its shapes. */\n pack?: SampleDataPack;\n}\n\ninterface ScannedElement { properties?: Record<string, unknown>; slots?: Record<string, ScannedElement[]> }\n\n/**\n * The per-template definition of done (spec Part B 6), as one reusable check every blueprint package's specs call for each of its\n * templates: complete metadata, a type from the vocabulary, a category, a display name and a one-sentence description, a thumbnail\n * that is in the package, a slot arrangement that places every declared slot and no other, placement by the slot resolver (not\n * unplaced, not nested in itself), no inline sample rows (the preview data is a sample-data pack, SD1), and - given the pack - every\n * bound query answered by it. Verification of the whole package is {@link verifyBlueprintPackage}; this is the template-level\n * checklist a spec can assert for each template by name, so a failure says which template and which rule.\n *\n * @param template The screen template.\n * @param source The blueprint that provides it.\n * @param library The other packages available, so the template can be placed into their layouts.\n * @param options What else to hold it to.\n * @returns The problems; empty when the template is done.\n */\nexport function verifyTemplateDefinitionOfDone(template: ScreenTemplate, source: BlueprintSource, library: readonly TemplateSource[] = [], options: TemplateDefinitionOfDoneOptions = {}): string[] {\n const owner = `Template '${template.name}'`;\n const problems: string[] = [...validateTemplateMetadata(template.name, template.metadata)];\n const metadata = template.metadata;\n\n if ((template.displayName ?? '').trim() === '') problems.push(`${owner} declares no display name`);\n const description = (template.description ?? '').trim();\n if (description === '') problems.push(`${owner} declares no description`);\n else if (!/^\\p{Lu}.*\\.$/u.test(description) || description.includes('. ')) problems.push(`${owner} describes itself in more than one sentence, or without a full stop`);\n\n if (metadata?.type === undefined) problems.push(`${owner} declares no type`);\n else if (!blueprintTemplateTypes.includes(metadata.type)) problems.push(`${owner} declares type '${metadata.type}', which is not one of ${blueprintTemplateTypes.join(', ')}`);\n\n if ((metadata?.category ?? '').trim() === '') problems.push(`${owner} declares no category`);\n else if (options.categoryPrefix !== undefined && !metadata!.category!.startsWith(options.categoryPrefix)) problems.push(`${owner} declares category '${metadata!.category}', which does not start with '${options.categoryPrefix}'`);\n\n if ((metadata?.thumbnail ?? '').trim() === '') problems.push(`${owner} declares no thumbnail`);\n else if (!isValidThumbnailPath(metadata!.thumbnail)) problems.push(`${owner} declares thumbnail '${metadata!.thumbnail}', which is not 'thumbnails/<name>.png|webp|jpg|svg'`);\n else if (source.files !== undefined && !source.files.includes(metadata!.thumbnail!)) problems.push(`${owner} declares thumbnail '${metadata!.thumbnail}', which is not in the package`);\n\n problems.push(...slotProblems(template, owner));\n problems.push(...placementProblems(template, source, library, owner));\n\n for (const literal of findTemplateSampleRowLiterals(template.content as Record<string, ScannedElement[]> | undefined)) {\n problems.push(`${owner} carries sample rows inline at ${literal}; preview data belongs in a sample-data pack`);\n }\n\n if (options.pack !== undefined) {\n const shapes = new Set(options.pack.sets.map(set => set.shape));\n for (const query of queriesBoundBy(template).filter(name => !shapes.has(name))) {\n problems.push(`${owner} binds to query '${query}', which sample-data pack '${options.pack.id}' does not answer`);\n }\n }\n\n return problems;\n}\n\nfunction slotProblems(template: ScreenTemplate, owner: string): string[] {\n const declared = template.slots.map(slot => slot.name);\n const arranged = new Set<string>();\n const visit = (node: FlowNode | undefined) => {\n if (!node) return;\n const named = node as { slotName?: string; children?: FlowNode[] };\n if (named.slotName !== undefined) arranged.add(named.slotName);\n named.children?.forEach(visit);\n };\n\n const arrangement = template.arrangement as FlowArrangement | undefined;\n visit(arrangement?.root);\n arrangement?.overrides?.forEach(override => visit(override.root));\n\n const problems: string[] = [];\n for (const name of declared.filter(slot => !arranged.has(slot))) problems.push(`${owner} declares slot '${name}' but its arrangement never places it`);\n for (const name of [...arranged].filter(slot => !declared.includes(slot))) problems.push(`${owner} arranges slot '${name}', which it does not declare`);\n for (const name of Object.keys(template.content ?? {}).filter(slot => !declared.includes(slot))) problems.push(`${owner} fills slot '${name}', which it does not declare`);\n return problems;\n}\n\nfunction placementProblems(template: ScreenTemplate, source: BlueprintSource, library: readonly TemplateSource[], owner: string): string[] {\n if (template.fitsSlot === undefined) return [];\n const layouts = [...(source.layouts ?? []), ...library.flatMap(other => other.layouts ?? [])];\n const everyTemplate = [...(source.screenTemplates ?? []), ...library.flatMap(other => other.screenTemplates ?? [])];\n const resolutions = layouts.map(layout => resolveScreenTemplates(layout, everyTemplate));\n\n if (resolutions.some(resolution => resolution.placements.some(placement => placement.template === template.name))) return [];\n if (resolutions.some(resolution => resolution.cycles.some(cycle => cycle.includes(template.name)))) return [`${owner} is nested inside itself`];\n return [`${owner} is unplaced: no layout or template declares slot '${template.fitsSlot}'`];\n}\n\nfunction queriesBoundBy(template: ScreenTemplate): string[] {\n const queries = new Set<string>();\n const visitValue = (value: unknown) => {\n if (Array.isArray(value)) value.forEach(visitValue);\n else if (typeof value === 'object' && value !== null) {\n const candidate = value as { query?: unknown; path?: unknown };\n if (typeof candidate.query === 'string' && 'path' in candidate) queries.add(candidate.query);\n Object.values(value).forEach(visitValue);\n }\n };\n\n const visit = (elements: ScannedElement[] | undefined) => {\n for (const element of elements ?? []) {\n Object.values(element.properties ?? {}).forEach(visitValue);\n Object.values(element.slots ?? {}).forEach(visit);\n }\n };\n\n Object.values(template.content ?? {}).forEach(content => visit(content as ScannedElement[]));\n return [...queries].sort();\n}\n"],"names":["verifyTemplateDefinitionOfDone","template","source","library","options","owner","name","problems","validateTemplateMetadata","metadata","displayName","trim","push","description","test","includes","type","undefined","blueprintTemplateTypes","join","category","categoryPrefix","startsWith","thumbnail","isValidThumbnailPath","files","slotProblems","placementProblems","literal","findTemplateSampleRowLiterals","content","pack","shapes","Set","sets","map","set","shape","query","queriesBoundBy","filter","has","id","declared","slots","slot","arranged","visit","node","named","slotName","add","children","forEach","arrangement","root","overrides","override","Object","keys","fitsSlot","layouts","flatMap","other","everyTemplate","screenTemplates","resolutions","layout","resolveScreenTemplates","some","resolution","placements","placement","cycles","cycle","queries","visitValue","value","Array","isArray","candidate","values","elements","element","properties","sort"],"mappings":"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"}
package/dist/cjs/index.js CHANGED
@@ -55,6 +55,7 @@ var blueprintRules = require('./blueprints/blueprintRules.js');
55
55
  var verifyBlueprintPackage = require('./blueprints/verifyBlueprintPackage.js');
56
56
  var describeBlueprintCatalog = require('./blueprints/describeBlueprintCatalog.js');
57
57
  var evaluateBlueprintPin = require('./blueprints/evaluateBlueprintPin.js');
58
+ var verifyTemplateDefinitionOfDone = require('./blueprints/verifyTemplateDefinitionOfDone.js');
58
59
  var buildStarterProfile = require('./buildStarterProfile.js');
59
60
  var incompatibleStarterThemes = require('./incompatibleStarterThemes.js');
60
61
  var runActions = require('./runActions.js');
@@ -213,6 +214,7 @@ exports.toBlueprintCatalogFile = describeBlueprintCatalog.toBlueprintCatalogFile
213
214
  exports.BlueprintPinStatus = evaluateBlueprintPin.BlueprintPinStatus;
214
215
  exports.defaultBlueprintPin = evaluateBlueprintPin.defaultBlueprintPin;
215
216
  exports.evaluateBlueprintPin = evaluateBlueprintPin.evaluateBlueprintPin;
217
+ exports.verifyTemplateDefinitionOfDone = verifyTemplateDefinitionOfDone.verifyTemplateDefinitionOfDone;
216
218
  exports.buildStarterProfile = buildStarterProfile.buildStarterProfile;
217
219
  exports.incompatibleStarterThemes = incompatibleStarterThemes.incompatibleStarterThemes;
218
220
  exports.InteractionStop = runActions.InteractionStop;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -4,4 +4,5 @@ export * from './blueprintRules';
4
4
  export * from './verifyBlueprintPackage';
5
5
  export * from './describeBlueprintCatalog';
6
6
  export * from './evaluateBlueprintPin';
7
+ export * from './verifyTemplateDefinitionOfDone';
7
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../blueprints/index.ts"],"names":[],"mappings":"AAGA,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,kBAAkB,CAAC;AACjC,cAAc,0BAA0B,CAAC;AACzC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../blueprints/index.ts"],"names":[],"mappings":"AAGA,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,kBAAkB,CAAC;AACjC,cAAc,0BAA0B,CAAC;AACzC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,wBAAwB,CAAC;AACvC,cAAc,kCAAkC,CAAC"}
@@ -4,4 +4,5 @@ export * from './blueprintRules';
4
4
  export * from './verifyBlueprintPackage';
5
5
  export * from './describeBlueprintCatalog';
6
6
  export * from './evaluateBlueprintPin';
7
+ export * from './verifyTemplateDefinitionOfDone';
7
8
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../blueprints/index.ts"],"names":[],"mappings":"AAGA,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,kBAAkB,CAAC;AACjC,cAAc,0BAA0B,CAAC;AACzC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../blueprints/index.ts"],"names":[],"mappings":"AAGA,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,kBAAkB,CAAC;AACjC,cAAc,0BAA0B,CAAC;AACzC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,wBAAwB,CAAC;AACvC,cAAc,kCAAkC,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { SampleDataPack, ScreenTemplate } from '@cratis/scene.model';
2
+ import { TemplateSource } from '../templates/TemplateSource';
3
+ import { BlueprintSource } from './BlueprintSource';
4
+ export interface TemplateDefinitionOfDoneOptions {
5
+ categoryPrefix?: string;
6
+ pack?: SampleDataPack;
7
+ }
8
+ export declare function verifyTemplateDefinitionOfDone(template: ScreenTemplate, source: BlueprintSource, library?: readonly TemplateSource[], options?: TemplateDefinitionOfDoneOptions): string[];
9
+ //# sourceMappingURL=verifyTemplateDefinitionOfDone.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verifyTemplateDefinitionOfDone.d.ts","sourceRoot":"","sources":["../../../blueprints/verifyTemplateDefinitionOfDone.ts"],"names":[],"mappings":"AAGA,OAAO,EAA6B,cAAc,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAIhG,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAIpD,MAAM,WAAW,+BAA+B;IAE5C,cAAc,CAAC,EAAE,MAAM,CAAC;IAGxB,IAAI,CAAC,EAAE,cAAc,CAAC;CACzB;AAkBD,wBAAgB,8BAA8B,CAAC,QAAQ,EAAE,cAAc,EAAE,MAAM,EAAE,eAAe,EAAE,OAAO,GAAE,SAAS,cAAc,EAAO,EAAE,OAAO,GAAE,+BAAoC,GAAG,MAAM,EAAE,CAmClM"}
@@ -0,0 +1,113 @@
1
+ import { resolveScreenTemplates } from '../resolveScreenTemplates.js';
2
+ import { findTemplateSampleRowLiterals } from '../sampleData/findSampleRowLiterals.js';
3
+ import { validateTemplateMetadata } from '../templates/validateTemplateMetadata.js';
4
+ import { blueprintTemplateTypes, isValidThumbnailPath } from './blueprintRules.js';
5
+
6
+ // Copyright (c) Cratis. All rights reserved.
7
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
8
+ /**
9
+ * The per-template definition of done (spec Part B 6), as one reusable check every blueprint package's specs call for each of its
10
+ * templates: complete metadata, a type from the vocabulary, a category, a display name and a one-sentence description, a thumbnail
11
+ * that is in the package, a slot arrangement that places every declared slot and no other, placement by the slot resolver (not
12
+ * unplaced, not nested in itself), no inline sample rows (the preview data is a sample-data pack, SD1), and - given the pack - every
13
+ * bound query answered by it. Verification of the whole package is {@link verifyBlueprintPackage}; this is the template-level
14
+ * checklist a spec can assert for each template by name, so a failure says which template and which rule.
15
+ *
16
+ * @param template The screen template.
17
+ * @param source The blueprint that provides it.
18
+ * @param library The other packages available, so the template can be placed into their layouts.
19
+ * @param options What else to hold it to.
20
+ * @returns The problems; empty when the template is done.
21
+ */ function verifyTemplateDefinitionOfDone(template, source, library = [], options = {}) {
22
+ const owner = `Template '${template.name}'`;
23
+ const problems = [
24
+ ...validateTemplateMetadata(template.name, template.metadata)
25
+ ];
26
+ const metadata = template.metadata;
27
+ if ((template.displayName ?? '').trim() === '') problems.push(`${owner} declares no display name`);
28
+ const description = (template.description ?? '').trim();
29
+ if (description === '') problems.push(`${owner} declares no description`);
30
+ else if (!/^\p{Lu}.*\.$/u.test(description) || description.includes('. ')) problems.push(`${owner} describes itself in more than one sentence, or without a full stop`);
31
+ if (metadata?.type === undefined) problems.push(`${owner} declares no type`);
32
+ else if (!blueprintTemplateTypes.includes(metadata.type)) problems.push(`${owner} declares type '${metadata.type}', which is not one of ${blueprintTemplateTypes.join(', ')}`);
33
+ if ((metadata?.category ?? '').trim() === '') problems.push(`${owner} declares no category`);
34
+ else if (options.categoryPrefix !== undefined && !metadata.category.startsWith(options.categoryPrefix)) problems.push(`${owner} declares category '${metadata.category}', which does not start with '${options.categoryPrefix}'`);
35
+ if ((metadata?.thumbnail ?? '').trim() === '') problems.push(`${owner} declares no thumbnail`);
36
+ else if (!isValidThumbnailPath(metadata.thumbnail)) problems.push(`${owner} declares thumbnail '${metadata.thumbnail}', which is not 'thumbnails/<name>.png|webp|jpg|svg'`);
37
+ else if (source.files !== undefined && !source.files.includes(metadata.thumbnail)) problems.push(`${owner} declares thumbnail '${metadata.thumbnail}', which is not in the package`);
38
+ problems.push(...slotProblems(template, owner));
39
+ problems.push(...placementProblems(template, source, library, owner));
40
+ for (const literal of findTemplateSampleRowLiterals(template.content)){
41
+ problems.push(`${owner} carries sample rows inline at ${literal}; preview data belongs in a sample-data pack`);
42
+ }
43
+ if (options.pack !== undefined) {
44
+ const shapes = new Set(options.pack.sets.map((set)=>set.shape));
45
+ for (const query of queriesBoundBy(template).filter((name)=>!shapes.has(name))){
46
+ problems.push(`${owner} binds to query '${query}', which sample-data pack '${options.pack.id}' does not answer`);
47
+ }
48
+ }
49
+ return problems;
50
+ }
51
+ function slotProblems(template, owner) {
52
+ const declared = template.slots.map((slot)=>slot.name);
53
+ const arranged = new Set();
54
+ const visit = (node)=>{
55
+ if (!node) return;
56
+ const named = node;
57
+ if (named.slotName !== undefined) arranged.add(named.slotName);
58
+ named.children?.forEach(visit);
59
+ };
60
+ const arrangement = template.arrangement;
61
+ visit(arrangement?.root);
62
+ arrangement?.overrides?.forEach((override)=>visit(override.root));
63
+ const problems = [];
64
+ for (const name of declared.filter((slot)=>!arranged.has(slot)))problems.push(`${owner} declares slot '${name}' but its arrangement never places it`);
65
+ for (const name of [
66
+ ...arranged
67
+ ].filter((slot)=>!declared.includes(slot)))problems.push(`${owner} arranges slot '${name}', which it does not declare`);
68
+ for (const name of Object.keys(template.content ?? {}).filter((slot)=>!declared.includes(slot)))problems.push(`${owner} fills slot '${name}', which it does not declare`);
69
+ return problems;
70
+ }
71
+ function placementProblems(template, source, library, owner) {
72
+ if (template.fitsSlot === undefined) return [];
73
+ const layouts = [
74
+ ...source.layouts ?? [],
75
+ ...library.flatMap((other)=>other.layouts ?? [])
76
+ ];
77
+ const everyTemplate = [
78
+ ...source.screenTemplates ?? [],
79
+ ...library.flatMap((other)=>other.screenTemplates ?? [])
80
+ ];
81
+ const resolutions = layouts.map((layout)=>resolveScreenTemplates(layout, everyTemplate));
82
+ if (resolutions.some((resolution)=>resolution.placements.some((placement)=>placement.template === template.name))) return [];
83
+ if (resolutions.some((resolution)=>resolution.cycles.some((cycle)=>cycle.includes(template.name)))) return [
84
+ `${owner} is nested inside itself`
85
+ ];
86
+ return [
87
+ `${owner} is unplaced: no layout or template declares slot '${template.fitsSlot}'`
88
+ ];
89
+ }
90
+ function queriesBoundBy(template) {
91
+ const queries = new Set();
92
+ const visitValue = (value)=>{
93
+ if (Array.isArray(value)) value.forEach(visitValue);
94
+ else if (typeof value === 'object' && value !== null) {
95
+ const candidate = value;
96
+ if (typeof candidate.query === 'string' && 'path' in candidate) queries.add(candidate.query);
97
+ Object.values(value).forEach(visitValue);
98
+ }
99
+ };
100
+ const visit = (elements)=>{
101
+ for (const element of elements ?? []){
102
+ Object.values(element.properties ?? {}).forEach(visitValue);
103
+ Object.values(element.slots ?? {}).forEach(visit);
104
+ }
105
+ };
106
+ Object.values(template.content ?? {}).forEach((content)=>visit(content));
107
+ return [
108
+ ...queries
109
+ ].sort();
110
+ }
111
+
112
+ export { verifyTemplateDefinitionOfDone };
113
+ //# sourceMappingURL=verifyTemplateDefinitionOfDone.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verifyTemplateDefinitionOfDone.js","sources":["../../../blueprints/verifyTemplateDefinitionOfDone.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { FlowArrangement, FlowNode, SampleDataPack, ScreenTemplate } from '@cratis/scene.model';\nimport { resolveScreenTemplates } from '../resolveScreenTemplates';\nimport { findTemplateSampleRowLiterals } from '../sampleData/findSampleRowLiterals';\nimport { validateTemplateMetadata } from '../templates/validateTemplateMetadata';\nimport { TemplateSource } from '../templates/TemplateSource';\nimport { BlueprintSource } from './BlueprintSource';\nimport { blueprintTemplateTypes, isValidThumbnailPath } from './blueprintRules';\n\n/** What {@link verifyTemplateDefinitionOfDone} holds a template to beyond the rules every template has. */\nexport interface TemplateDefinitionOfDoneOptions {\n /** The category prefix the template's category must start with, e.g. `Foundation /`. */\n categoryPrefix?: string;\n\n /** The sample-data pack the template is previewed with. When given, every query the template binds to must be answered by one of its shapes. */\n pack?: SampleDataPack;\n}\n\ninterface ScannedElement { properties?: Record<string, unknown>; slots?: Record<string, ScannedElement[]> }\n\n/**\n * The per-template definition of done (spec Part B 6), as one reusable check every blueprint package's specs call for each of its\n * templates: complete metadata, a type from the vocabulary, a category, a display name and a one-sentence description, a thumbnail\n * that is in the package, a slot arrangement that places every declared slot and no other, placement by the slot resolver (not\n * unplaced, not nested in itself), no inline sample rows (the preview data is a sample-data pack, SD1), and - given the pack - every\n * bound query answered by it. Verification of the whole package is {@link verifyBlueprintPackage}; this is the template-level\n * checklist a spec can assert for each template by name, so a failure says which template and which rule.\n *\n * @param template The screen template.\n * @param source The blueprint that provides it.\n * @param library The other packages available, so the template can be placed into their layouts.\n * @param options What else to hold it to.\n * @returns The problems; empty when the template is done.\n */\nexport function verifyTemplateDefinitionOfDone(template: ScreenTemplate, source: BlueprintSource, library: readonly TemplateSource[] = [], options: TemplateDefinitionOfDoneOptions = {}): string[] {\n const owner = `Template '${template.name}'`;\n const problems: string[] = [...validateTemplateMetadata(template.name, template.metadata)];\n const metadata = template.metadata;\n\n if ((template.displayName ?? '').trim() === '') problems.push(`${owner} declares no display name`);\n const description = (template.description ?? '').trim();\n if (description === '') problems.push(`${owner} declares no description`);\n else if (!/^\\p{Lu}.*\\.$/u.test(description) || description.includes('. ')) problems.push(`${owner} describes itself in more than one sentence, or without a full stop`);\n\n if (metadata?.type === undefined) problems.push(`${owner} declares no type`);\n else if (!blueprintTemplateTypes.includes(metadata.type)) problems.push(`${owner} declares type '${metadata.type}', which is not one of ${blueprintTemplateTypes.join(', ')}`);\n\n if ((metadata?.category ?? '').trim() === '') problems.push(`${owner} declares no category`);\n else if (options.categoryPrefix !== undefined && !metadata!.category!.startsWith(options.categoryPrefix)) problems.push(`${owner} declares category '${metadata!.category}', which does not start with '${options.categoryPrefix}'`);\n\n if ((metadata?.thumbnail ?? '').trim() === '') problems.push(`${owner} declares no thumbnail`);\n else if (!isValidThumbnailPath(metadata!.thumbnail)) problems.push(`${owner} declares thumbnail '${metadata!.thumbnail}', which is not 'thumbnails/<name>.png|webp|jpg|svg'`);\n else if (source.files !== undefined && !source.files.includes(metadata!.thumbnail!)) problems.push(`${owner} declares thumbnail '${metadata!.thumbnail}', which is not in the package`);\n\n problems.push(...slotProblems(template, owner));\n problems.push(...placementProblems(template, source, library, owner));\n\n for (const literal of findTemplateSampleRowLiterals(template.content as Record<string, ScannedElement[]> | undefined)) {\n problems.push(`${owner} carries sample rows inline at ${literal}; preview data belongs in a sample-data pack`);\n }\n\n if (options.pack !== undefined) {\n const shapes = new Set(options.pack.sets.map(set => set.shape));\n for (const query of queriesBoundBy(template).filter(name => !shapes.has(name))) {\n problems.push(`${owner} binds to query '${query}', which sample-data pack '${options.pack.id}' does not answer`);\n }\n }\n\n return problems;\n}\n\nfunction slotProblems(template: ScreenTemplate, owner: string): string[] {\n const declared = template.slots.map(slot => slot.name);\n const arranged = new Set<string>();\n const visit = (node: FlowNode | undefined) => {\n if (!node) return;\n const named = node as { slotName?: string; children?: FlowNode[] };\n if (named.slotName !== undefined) arranged.add(named.slotName);\n named.children?.forEach(visit);\n };\n\n const arrangement = template.arrangement as FlowArrangement | undefined;\n visit(arrangement?.root);\n arrangement?.overrides?.forEach(override => visit(override.root));\n\n const problems: string[] = [];\n for (const name of declared.filter(slot => !arranged.has(slot))) problems.push(`${owner} declares slot '${name}' but its arrangement never places it`);\n for (const name of [...arranged].filter(slot => !declared.includes(slot))) problems.push(`${owner} arranges slot '${name}', which it does not declare`);\n for (const name of Object.keys(template.content ?? {}).filter(slot => !declared.includes(slot))) problems.push(`${owner} fills slot '${name}', which it does not declare`);\n return problems;\n}\n\nfunction placementProblems(template: ScreenTemplate, source: BlueprintSource, library: readonly TemplateSource[], owner: string): string[] {\n if (template.fitsSlot === undefined) return [];\n const layouts = [...(source.layouts ?? []), ...library.flatMap(other => other.layouts ?? [])];\n const everyTemplate = [...(source.screenTemplates ?? []), ...library.flatMap(other => other.screenTemplates ?? [])];\n const resolutions = layouts.map(layout => resolveScreenTemplates(layout, everyTemplate));\n\n if (resolutions.some(resolution => resolution.placements.some(placement => placement.template === template.name))) return [];\n if (resolutions.some(resolution => resolution.cycles.some(cycle => cycle.includes(template.name)))) return [`${owner} is nested inside itself`];\n return [`${owner} is unplaced: no layout or template declares slot '${template.fitsSlot}'`];\n}\n\nfunction queriesBoundBy(template: ScreenTemplate): string[] {\n const queries = new Set<string>();\n const visitValue = (value: unknown) => {\n if (Array.isArray(value)) value.forEach(visitValue);\n else if (typeof value === 'object' && value !== null) {\n const candidate = value as { query?: unknown; path?: unknown };\n if (typeof candidate.query === 'string' && 'path' in candidate) queries.add(candidate.query);\n Object.values(value).forEach(visitValue);\n }\n };\n\n const visit = (elements: ScannedElement[] | undefined) => {\n for (const element of elements ?? []) {\n Object.values(element.properties ?? {}).forEach(visitValue);\n Object.values(element.slots ?? {}).forEach(visit);\n }\n };\n\n Object.values(template.content ?? {}).forEach(content => visit(content as ScannedElement[]));\n return [...queries].sort();\n}\n"],"names":["verifyTemplateDefinitionOfDone","template","source","library","options","owner","name","problems","validateTemplateMetadata","metadata","displayName","trim","push","description","test","includes","type","undefined","blueprintTemplateTypes","join","category","categoryPrefix","startsWith","thumbnail","isValidThumbnailPath","files","slotProblems","placementProblems","literal","findTemplateSampleRowLiterals","content","pack","shapes","Set","sets","map","set","shape","query","queriesBoundBy","filter","has","id","declared","slots","slot","arranged","visit","node","named","slotName","add","children","forEach","arrangement","root","overrides","override","Object","keys","fitsSlot","layouts","flatMap","other","everyTemplate","screenTemplates","resolutions","layout","resolveScreenTemplates","some","resolution","placements","placement","cycles","cycle","queries","visitValue","value","Array","isArray","candidate","values","elements","element","properties","sort"],"mappings":"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"}
package/dist/esm/index.js CHANGED
@@ -53,6 +53,7 @@ export { blueprintTemplateTypes, businessCategoryPrefix, foundationPackageName,
53
53
  export { verifyBlueprintPackage } from './blueprints/verifyBlueprintPackage.js';
54
54
  export { describeBlueprintCatalog, toBlueprintCatalogFile } from './blueprints/describeBlueprintCatalog.js';
55
55
  export { BlueprintPinStatus, defaultBlueprintPin, evaluateBlueprintPin } from './blueprints/evaluateBlueprintPin.js';
56
+ export { verifyTemplateDefinitionOfDone } from './blueprints/verifyTemplateDefinitionOfDone.js';
56
57
  export { buildStarterProfile } from './buildStarterProfile.js';
57
58
  export { incompatibleStarterThemes } from './incompatibleStarterThemes.js';
58
59
  export { InteractionStop, runActions, runBindings } from './runActions.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}