@patterkit/core 0.7.0 → 0.8.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.
- package/dist/index.cjs +82 -30
- package/dist/index.d.cts +8 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.js +82 -30
- package/package.json +3 -2
package/dist/index.cjs
CHANGED
|
@@ -96,6 +96,7 @@ ${indent}}`;
|
|
|
96
96
|
var import_model = require("@patterkit/model");
|
|
97
97
|
var import_model2 = require("@patterkit/model");
|
|
98
98
|
var import_model3 = require("@patterkit/model");
|
|
99
|
+
var import_expr = require("@wildwinter/expr");
|
|
99
100
|
function choiceLoopsBack(choice, ...targets) {
|
|
100
101
|
const back = new Set(targets.filter((s) => typeof s === "string" && s.length > 0));
|
|
101
102
|
const hits = (n) => n.type === "snippet" ? !!n.jump && back.has(n.jump.to) : (n.children ?? []).some(hits);
|
|
@@ -228,6 +229,7 @@ function validateProject(input) {
|
|
|
228
229
|
return true;
|
|
229
230
|
};
|
|
230
231
|
validateProjectFile(project, issues);
|
|
232
|
+
validateGameDataValues(project, scenes, issues);
|
|
231
233
|
for (const scene of scenes) {
|
|
232
234
|
seeId(scene.id, "scene", "project");
|
|
233
235
|
checkPad(scene.padAfterDefault, `scene '${scene.id}' default`, scene.id);
|
|
@@ -504,12 +506,75 @@ function validateProjectFile(project, issues) {
|
|
|
504
506
|
if (!f.name.trim()) issues.push({ code: "invalid-gamedata-field", message: `${kind} gameData field has no name` });
|
|
505
507
|
else if (seen.has(key)) issues.push({ code: "invalid-gamedata-field", message: `${kind} gameData field '${f.name}' is declared more than once` });
|
|
506
508
|
else seen.add(key);
|
|
509
|
+
const subject = `${kind} gameData field '${f.name}'`;
|
|
507
510
|
if (f.type === "enum" && !(f.values && f.values.length)) {
|
|
508
|
-
issues.push({ code: "invalid-gamedata-field", message: `${
|
|
511
|
+
issues.push({ code: "invalid-gamedata-field", message: `${subject} is an enum but lists no values` });
|
|
512
|
+
} else if (f.type === "flags" && !(f.values && f.values.length)) {
|
|
513
|
+
issues.push({ code: "invalid-gamedata-field", message: `${subject} is flags but lists no values` });
|
|
514
|
+
}
|
|
515
|
+
if (f.type === "quality") {
|
|
516
|
+
for (const problem of (0, import_expr.qualityDeclarationProblems)(f.stages, f.default)) {
|
|
517
|
+
issues.push({ code: "invalid-gamedata-field", message: `${subject} ${qualityProblemWords(problem)}` });
|
|
518
|
+
}
|
|
519
|
+
} else if (f.default !== void 0 && !(0, import_expr.valueFits)(f, f.default, { noneChosen: true })) {
|
|
520
|
+
issues.push({
|
|
521
|
+
code: "invalid-gamedata-field",
|
|
522
|
+
message: `${subject} default ${JSON.stringify(f.default)} does not match type '${f.type}'`
|
|
523
|
+
});
|
|
509
524
|
}
|
|
510
525
|
}
|
|
511
526
|
}
|
|
512
527
|
}
|
|
528
|
+
function qualityProblemWords(problem) {
|
|
529
|
+
switch (problem.kind) {
|
|
530
|
+
case "too-few-stages":
|
|
531
|
+
return `is a quality but declares ${problem.count === 0 ? "no stages" : "only one stage"} (a ladder needs at least two)`;
|
|
532
|
+
case "empty-stage":
|
|
533
|
+
return "has an empty stage name";
|
|
534
|
+
case "duplicate-stage":
|
|
535
|
+
return `declares stage '${problem.stage}' more than once`;
|
|
536
|
+
case "default-not-a-stage":
|
|
537
|
+
return `default ${JSON.stringify(problem.value)} is not one of its stages`;
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
function validateGameDataValues(project, scenes, issues) {
|
|
541
|
+
const declared = project.gameDataFields ?? {};
|
|
542
|
+
const check = (kind, id, values) => {
|
|
543
|
+
if (!values) return;
|
|
544
|
+
const fields = declared[kind] ?? [];
|
|
545
|
+
if (fields.length === 0) return;
|
|
546
|
+
for (const [name, value] of Object.entries(values)) {
|
|
547
|
+
const f = fields.find((d) => d.name === name);
|
|
548
|
+
if (!f || (0, import_expr.valueFits)(f, value, { noneChosen: true })) continue;
|
|
549
|
+
const where = `${kind} '${id ?? "?"}'`;
|
|
550
|
+
if (f.type === "quality" && typeof value === "string") {
|
|
551
|
+
issues.push({
|
|
552
|
+
code: "invalid-gamedata-value",
|
|
553
|
+
id,
|
|
554
|
+
message: `${where} gameData '${name}' is '${value}', which is not one of its stages`,
|
|
555
|
+
offLadder: { field: name, bad: value, options: (0, import_expr.stagesEitherSide)(f, value) }
|
|
556
|
+
});
|
|
557
|
+
} else {
|
|
558
|
+
issues.push({
|
|
559
|
+
code: "invalid-gamedata-value",
|
|
560
|
+
id,
|
|
561
|
+
message: `${where} gameData '${name}' ${JSON.stringify(value)} does not match type '${f.type}'`
|
|
562
|
+
});
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
};
|
|
566
|
+
for (const scene of scenes) {
|
|
567
|
+
check("scene", scene.id, scene.gameData);
|
|
568
|
+
for (const block of scene.blocks ?? []) {
|
|
569
|
+
check("block", block.id, block.gameData);
|
|
570
|
+
(0, import_model.walkNodes)(block.children ?? [], (node) => {
|
|
571
|
+
if (node.type !== "snippet") return;
|
|
572
|
+
check("snippet", node.id, node.gameData);
|
|
573
|
+
for (const beat of node.beats ?? []) check(beat.kind, beat.id, beat.gameData);
|
|
574
|
+
});
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
}
|
|
513
578
|
function validateAuthoring(files, project, allIds, issues) {
|
|
514
579
|
const writingLadder = new Set((project.writingStatuses ?? import_model.DEFAULT_WRITING_STATUSES).map((s) => s.name));
|
|
515
580
|
const recordingLadder = new Set((project.recordingStatuses ?? import_model.DEFAULT_RECORDING_STATUSES).map((s) => s.name));
|
|
@@ -601,21 +666,24 @@ function checkDecls(decls, where, issues) {
|
|
|
601
666
|
});
|
|
602
667
|
}
|
|
603
668
|
if (decl.type === "quality") {
|
|
604
|
-
const
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
669
|
+
for (const problem2 of (0, import_expr.qualityDeclarationProblems)(decl.stages)) {
|
|
670
|
+
switch (problem2.kind) {
|
|
671
|
+
case "too-few-stages":
|
|
672
|
+
issues.push({
|
|
673
|
+
code: "invalid-declaration",
|
|
674
|
+
message: `${where}: '${decl.name}' is a quality but declares ${problem2.count === 0 ? "no stages" : "only one stage"} (a ladder needs at least two)`
|
|
675
|
+
});
|
|
676
|
+
break;
|
|
677
|
+
case "empty-stage":
|
|
678
|
+
issues.push({ code: "invalid-declaration", message: `${where}: '${decl.name}' has an empty stage name` });
|
|
679
|
+
break;
|
|
680
|
+
case "duplicate-stage":
|
|
681
|
+
issues.push({ code: "invalid-declaration", message: `${where}: '${decl.name}' declares stage '${problem2.stage}' more than once` });
|
|
682
|
+
break;
|
|
683
|
+
}
|
|
616
684
|
}
|
|
617
685
|
}
|
|
618
|
-
if (decl.default !== void 0 && !
|
|
686
|
+
if (decl.default !== void 0 && !(0, import_expr.valueFits)(decl, decl.default)) {
|
|
619
687
|
issues.push({
|
|
620
688
|
code: "invalid-declaration",
|
|
621
689
|
message: `${where}: '${decl.name}' default ${JSON.stringify(decl.default)} does not match type '${decl.type}'`
|
|
@@ -623,22 +691,6 @@ function checkDecls(decls, where, issues) {
|
|
|
623
691
|
}
|
|
624
692
|
}
|
|
625
693
|
}
|
|
626
|
-
function defaultMatchesType(value, decl) {
|
|
627
|
-
switch (decl.type) {
|
|
628
|
-
case "boolean":
|
|
629
|
-
return typeof value === "boolean";
|
|
630
|
-
case "number":
|
|
631
|
-
return typeof value === "number";
|
|
632
|
-
case "string":
|
|
633
|
-
return typeof value === "string";
|
|
634
|
-
case "enum":
|
|
635
|
-
return typeof value === "string" && (decl.values?.includes(value) ?? true);
|
|
636
|
-
case "flags":
|
|
637
|
-
return Array.isArray(value) && value.every((v) => typeof v === "string" && (decl.values?.includes(v) ?? true));
|
|
638
|
-
case "quality":
|
|
639
|
-
return typeof value === "string" && (decl.stages?.includes(value) ?? true);
|
|
640
|
-
}
|
|
641
|
-
}
|
|
642
694
|
|
|
643
695
|
// src/scene-scaffold.ts
|
|
644
696
|
var import_model4 = require("@patterkit/model");
|
package/dist/index.d.cts
CHANGED
|
@@ -26,13 +26,20 @@ interface StringifyOptions {
|
|
|
26
26
|
declare function canonicalStringify(value: unknown, opts?: StringifyOptions): string;
|
|
27
27
|
|
|
28
28
|
interface ValidationIssue {
|
|
29
|
-
code: "duplicate-id" | "missing-id" | "malformed-node" | "missing-name" | "empty-scene" | "empty-snippet" | "empty-container" | "dangling-jump" | "jump-into-non-addressable" | "invalid-gameid" | "duplicate-gameid" | "unknown-character" | "unknown-qualifier" | "invalid-qualifier" | "invalid-pad" | "pad-overlaps-seam" | "prompt-pad-without-beat" | "qualifier-without-speaker" | "invalid-speaker-label" | "unused-speaker-label" | "invalid-temporary" | "invalid-declaration" | "invalid-status-ladder" | "invalid-locales" | "invalid-captions" | "missing-prompt" | "invalid-prompt" | "multiple-fallbacks" | "choice-can-empty" | "invalid-status-value" | "unknown-doc-class" | "invalid-tag" | "invalid-gamedata-field" | "jump-cycle";
|
|
29
|
+
code: "duplicate-id" | "missing-id" | "malformed-node" | "missing-name" | "empty-scene" | "empty-snippet" | "empty-container" | "dangling-jump" | "jump-into-non-addressable" | "invalid-gameid" | "duplicate-gameid" | "unknown-character" | "unknown-qualifier" | "invalid-qualifier" | "invalid-pad" | "pad-overlaps-seam" | "prompt-pad-without-beat" | "qualifier-without-speaker" | "invalid-speaker-label" | "unused-speaker-label" | "invalid-temporary" | "invalid-declaration" | "invalid-status-ladder" | "invalid-locales" | "invalid-captions" | "missing-prompt" | "invalid-prompt" | "multiple-fallbacks" | "choice-can-empty" | "invalid-status-value" | "unknown-doc-class" | "invalid-tag" | "invalid-gamedata-field" | "invalid-gamedata-value" | "jump-cycle";
|
|
30
30
|
message: string;
|
|
31
31
|
/** Id of the offending node/beat, where applicable. */
|
|
32
32
|
id?: string;
|
|
33
33
|
/** Absent means an error: the project should not be built. A warning still compiles and plays (a choice
|
|
34
34
|
* that can run dry gathers or falls through at runtime), and every front end shows it as one. */
|
|
35
35
|
severity?: "warning";
|
|
36
|
+
/** A quality gameData value off its field's ladder (a deleted or renamed stage, most often): the field, the
|
|
37
|
+
* value, and the stages to offer in its place, in ladder order. An editor's quick fix reads it. */
|
|
38
|
+
offLadder?: {
|
|
39
|
+
field: string;
|
|
40
|
+
bad: string;
|
|
41
|
+
options: string[];
|
|
42
|
+
};
|
|
36
43
|
}
|
|
37
44
|
interface ProjectInput {
|
|
38
45
|
project: ProjectFile;
|
package/dist/index.d.ts
CHANGED
|
@@ -26,13 +26,20 @@ interface StringifyOptions {
|
|
|
26
26
|
declare function canonicalStringify(value: unknown, opts?: StringifyOptions): string;
|
|
27
27
|
|
|
28
28
|
interface ValidationIssue {
|
|
29
|
-
code: "duplicate-id" | "missing-id" | "malformed-node" | "missing-name" | "empty-scene" | "empty-snippet" | "empty-container" | "dangling-jump" | "jump-into-non-addressable" | "invalid-gameid" | "duplicate-gameid" | "unknown-character" | "unknown-qualifier" | "invalid-qualifier" | "invalid-pad" | "pad-overlaps-seam" | "prompt-pad-without-beat" | "qualifier-without-speaker" | "invalid-speaker-label" | "unused-speaker-label" | "invalid-temporary" | "invalid-declaration" | "invalid-status-ladder" | "invalid-locales" | "invalid-captions" | "missing-prompt" | "invalid-prompt" | "multiple-fallbacks" | "choice-can-empty" | "invalid-status-value" | "unknown-doc-class" | "invalid-tag" | "invalid-gamedata-field" | "jump-cycle";
|
|
29
|
+
code: "duplicate-id" | "missing-id" | "malformed-node" | "missing-name" | "empty-scene" | "empty-snippet" | "empty-container" | "dangling-jump" | "jump-into-non-addressable" | "invalid-gameid" | "duplicate-gameid" | "unknown-character" | "unknown-qualifier" | "invalid-qualifier" | "invalid-pad" | "pad-overlaps-seam" | "prompt-pad-without-beat" | "qualifier-without-speaker" | "invalid-speaker-label" | "unused-speaker-label" | "invalid-temporary" | "invalid-declaration" | "invalid-status-ladder" | "invalid-locales" | "invalid-captions" | "missing-prompt" | "invalid-prompt" | "multiple-fallbacks" | "choice-can-empty" | "invalid-status-value" | "unknown-doc-class" | "invalid-tag" | "invalid-gamedata-field" | "invalid-gamedata-value" | "jump-cycle";
|
|
30
30
|
message: string;
|
|
31
31
|
/** Id of the offending node/beat, where applicable. */
|
|
32
32
|
id?: string;
|
|
33
33
|
/** Absent means an error: the project should not be built. A warning still compiles and plays (a choice
|
|
34
34
|
* that can run dry gathers or falls through at runtime), and every front end shows it as one. */
|
|
35
35
|
severity?: "warning";
|
|
36
|
+
/** A quality gameData value off its field's ladder (a deleted or renamed stage, most often): the field, the
|
|
37
|
+
* value, and the stages to offer in its place, in ladder order. An editor's quick fix reads it. */
|
|
38
|
+
offLadder?: {
|
|
39
|
+
field: string;
|
|
40
|
+
bad: string;
|
|
41
|
+
options: string[];
|
|
42
|
+
};
|
|
36
43
|
}
|
|
37
44
|
interface ProjectInput {
|
|
38
45
|
project: ProjectFile;
|
package/dist/index.js
CHANGED
|
@@ -58,6 +58,7 @@ ${indent}}`;
|
|
|
58
58
|
import { walkNodes, DEFAULT_WRITING_STATUSES, DEFAULT_RECORDING_STATUSES, DEFAULT_DOCUMENTATION_CLASSES, projectQualifiers, usedSpeakerPairs, PAD_AFTER_MIN, PAD_AFTER_MAX } from "@patterkit/model";
|
|
59
59
|
import { isValidGameId, effectiveGameId } from "@patterkit/model";
|
|
60
60
|
import { isValidPropertyName, propertyNameify, RESERVED_PROPERTY_NAMES } from "@patterkit/model";
|
|
61
|
+
import { qualityDeclarationProblems, stagesEitherSide, valueFits } from "@wildwinter/expr";
|
|
61
62
|
function choiceLoopsBack(choice, ...targets) {
|
|
62
63
|
const back = new Set(targets.filter((s) => typeof s === "string" && s.length > 0));
|
|
63
64
|
const hits = (n) => n.type === "snippet" ? !!n.jump && back.has(n.jump.to) : (n.children ?? []).some(hits);
|
|
@@ -190,6 +191,7 @@ function validateProject(input) {
|
|
|
190
191
|
return true;
|
|
191
192
|
};
|
|
192
193
|
validateProjectFile(project, issues);
|
|
194
|
+
validateGameDataValues(project, scenes, issues);
|
|
193
195
|
for (const scene of scenes) {
|
|
194
196
|
seeId(scene.id, "scene", "project");
|
|
195
197
|
checkPad(scene.padAfterDefault, `scene '${scene.id}' default`, scene.id);
|
|
@@ -466,12 +468,75 @@ function validateProjectFile(project, issues) {
|
|
|
466
468
|
if (!f.name.trim()) issues.push({ code: "invalid-gamedata-field", message: `${kind} gameData field has no name` });
|
|
467
469
|
else if (seen.has(key)) issues.push({ code: "invalid-gamedata-field", message: `${kind} gameData field '${f.name}' is declared more than once` });
|
|
468
470
|
else seen.add(key);
|
|
471
|
+
const subject = `${kind} gameData field '${f.name}'`;
|
|
469
472
|
if (f.type === "enum" && !(f.values && f.values.length)) {
|
|
470
|
-
issues.push({ code: "invalid-gamedata-field", message: `${
|
|
473
|
+
issues.push({ code: "invalid-gamedata-field", message: `${subject} is an enum but lists no values` });
|
|
474
|
+
} else if (f.type === "flags" && !(f.values && f.values.length)) {
|
|
475
|
+
issues.push({ code: "invalid-gamedata-field", message: `${subject} is flags but lists no values` });
|
|
476
|
+
}
|
|
477
|
+
if (f.type === "quality") {
|
|
478
|
+
for (const problem of qualityDeclarationProblems(f.stages, f.default)) {
|
|
479
|
+
issues.push({ code: "invalid-gamedata-field", message: `${subject} ${qualityProblemWords(problem)}` });
|
|
480
|
+
}
|
|
481
|
+
} else if (f.default !== void 0 && !valueFits(f, f.default, { noneChosen: true })) {
|
|
482
|
+
issues.push({
|
|
483
|
+
code: "invalid-gamedata-field",
|
|
484
|
+
message: `${subject} default ${JSON.stringify(f.default)} does not match type '${f.type}'`
|
|
485
|
+
});
|
|
471
486
|
}
|
|
472
487
|
}
|
|
473
488
|
}
|
|
474
489
|
}
|
|
490
|
+
function qualityProblemWords(problem) {
|
|
491
|
+
switch (problem.kind) {
|
|
492
|
+
case "too-few-stages":
|
|
493
|
+
return `is a quality but declares ${problem.count === 0 ? "no stages" : "only one stage"} (a ladder needs at least two)`;
|
|
494
|
+
case "empty-stage":
|
|
495
|
+
return "has an empty stage name";
|
|
496
|
+
case "duplicate-stage":
|
|
497
|
+
return `declares stage '${problem.stage}' more than once`;
|
|
498
|
+
case "default-not-a-stage":
|
|
499
|
+
return `default ${JSON.stringify(problem.value)} is not one of its stages`;
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
function validateGameDataValues(project, scenes, issues) {
|
|
503
|
+
const declared = project.gameDataFields ?? {};
|
|
504
|
+
const check = (kind, id, values) => {
|
|
505
|
+
if (!values) return;
|
|
506
|
+
const fields = declared[kind] ?? [];
|
|
507
|
+
if (fields.length === 0) return;
|
|
508
|
+
for (const [name, value] of Object.entries(values)) {
|
|
509
|
+
const f = fields.find((d) => d.name === name);
|
|
510
|
+
if (!f || valueFits(f, value, { noneChosen: true })) continue;
|
|
511
|
+
const where = `${kind} '${id ?? "?"}'`;
|
|
512
|
+
if (f.type === "quality" && typeof value === "string") {
|
|
513
|
+
issues.push({
|
|
514
|
+
code: "invalid-gamedata-value",
|
|
515
|
+
id,
|
|
516
|
+
message: `${where} gameData '${name}' is '${value}', which is not one of its stages`,
|
|
517
|
+
offLadder: { field: name, bad: value, options: stagesEitherSide(f, value) }
|
|
518
|
+
});
|
|
519
|
+
} else {
|
|
520
|
+
issues.push({
|
|
521
|
+
code: "invalid-gamedata-value",
|
|
522
|
+
id,
|
|
523
|
+
message: `${where} gameData '${name}' ${JSON.stringify(value)} does not match type '${f.type}'`
|
|
524
|
+
});
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
};
|
|
528
|
+
for (const scene of scenes) {
|
|
529
|
+
check("scene", scene.id, scene.gameData);
|
|
530
|
+
for (const block of scene.blocks ?? []) {
|
|
531
|
+
check("block", block.id, block.gameData);
|
|
532
|
+
walkNodes(block.children ?? [], (node) => {
|
|
533
|
+
if (node.type !== "snippet") return;
|
|
534
|
+
check("snippet", node.id, node.gameData);
|
|
535
|
+
for (const beat of node.beats ?? []) check(beat.kind, beat.id, beat.gameData);
|
|
536
|
+
});
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
}
|
|
475
540
|
function validateAuthoring(files, project, allIds, issues) {
|
|
476
541
|
const writingLadder = new Set((project.writingStatuses ?? DEFAULT_WRITING_STATUSES).map((s) => s.name));
|
|
477
542
|
const recordingLadder = new Set((project.recordingStatuses ?? DEFAULT_RECORDING_STATUSES).map((s) => s.name));
|
|
@@ -563,21 +628,24 @@ function checkDecls(decls, where, issues) {
|
|
|
563
628
|
});
|
|
564
629
|
}
|
|
565
630
|
if (decl.type === "quality") {
|
|
566
|
-
const
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
631
|
+
for (const problem2 of qualityDeclarationProblems(decl.stages)) {
|
|
632
|
+
switch (problem2.kind) {
|
|
633
|
+
case "too-few-stages":
|
|
634
|
+
issues.push({
|
|
635
|
+
code: "invalid-declaration",
|
|
636
|
+
message: `${where}: '${decl.name}' is a quality but declares ${problem2.count === 0 ? "no stages" : "only one stage"} (a ladder needs at least two)`
|
|
637
|
+
});
|
|
638
|
+
break;
|
|
639
|
+
case "empty-stage":
|
|
640
|
+
issues.push({ code: "invalid-declaration", message: `${where}: '${decl.name}' has an empty stage name` });
|
|
641
|
+
break;
|
|
642
|
+
case "duplicate-stage":
|
|
643
|
+
issues.push({ code: "invalid-declaration", message: `${where}: '${decl.name}' declares stage '${problem2.stage}' more than once` });
|
|
644
|
+
break;
|
|
645
|
+
}
|
|
578
646
|
}
|
|
579
647
|
}
|
|
580
|
-
if (decl.default !== void 0 && !
|
|
648
|
+
if (decl.default !== void 0 && !valueFits(decl, decl.default)) {
|
|
581
649
|
issues.push({
|
|
582
650
|
code: "invalid-declaration",
|
|
583
651
|
message: `${where}: '${decl.name}' default ${JSON.stringify(decl.default)} does not match type '${decl.type}'`
|
|
@@ -585,22 +653,6 @@ function checkDecls(decls, where, issues) {
|
|
|
585
653
|
}
|
|
586
654
|
}
|
|
587
655
|
}
|
|
588
|
-
function defaultMatchesType(value, decl) {
|
|
589
|
-
switch (decl.type) {
|
|
590
|
-
case "boolean":
|
|
591
|
-
return typeof value === "boolean";
|
|
592
|
-
case "number":
|
|
593
|
-
return typeof value === "number";
|
|
594
|
-
case "string":
|
|
595
|
-
return typeof value === "string";
|
|
596
|
-
case "enum":
|
|
597
|
-
return typeof value === "string" && (decl.values?.includes(value) ?? true);
|
|
598
|
-
case "flags":
|
|
599
|
-
return Array.isArray(value) && value.every((v) => typeof v === "string" && (decl.values?.includes(v) ?? true));
|
|
600
|
-
case "quality":
|
|
601
|
-
return typeof value === "string" && (decl.stages?.includes(value) ?? true);
|
|
602
|
-
}
|
|
603
|
-
}
|
|
604
656
|
|
|
605
657
|
// src/scene-scaffold.ts
|
|
606
658
|
import { projectLayout, FLOW_SCHEMA, PROJECT_SCHEMA, STRINGS_SCHEMA } from "@patterkit/model";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@patterkit/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Patter core: stable id generation, readable-handle computation, canonical (de)serialisation, and the structural validator.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -34,7 +34,8 @@
|
|
|
34
34
|
"build": "tsup src/index.ts --format esm,cjs --dts --clean"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@patterkit/model": "0.
|
|
37
|
+
"@patterkit/model": "0.15.0",
|
|
38
|
+
"@wildwinter/expr": "^0.6.0",
|
|
38
39
|
"@wildwinter/toolkit": "^0.1.0",
|
|
39
40
|
"json5": "^2.2.3"
|
|
40
41
|
}
|