@patterkit/compiler 0.13.0 → 0.14.1
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 +15 -68
- package/dist/index.js +17 -74
- package/package.json +5 -5
package/dist/index.cjs
CHANGED
|
@@ -430,18 +430,17 @@ function extensionPass(input) {
|
|
|
430
430
|
for (const [id, entry] of Object.entries(taken)) {
|
|
431
431
|
const m = manifests.get(id);
|
|
432
432
|
const version = typeof entry?.version === "string" ? entry.version : "";
|
|
433
|
-
const settings = entry?.settings ?? {};
|
|
434
433
|
if (m === void 0) {
|
|
435
434
|
issues.push({
|
|
436
435
|
severity: "warning",
|
|
437
436
|
file: projectPath,
|
|
438
437
|
message: `the project takes the Patter extension "${id}", but has no manifest for it at ${import_model2.EXTENSIONS_DIR}/${id}${import_model2.MANIFEST_EXTENSION}; its data is left as it is, and not compiled`
|
|
439
438
|
});
|
|
440
|
-
takenList.push({ id
|
|
439
|
+
takenList.push({ id });
|
|
441
440
|
continue;
|
|
442
441
|
}
|
|
443
442
|
if (!m.sound) {
|
|
444
|
-
takenList.push({ id
|
|
443
|
+
takenList.push({ id });
|
|
445
444
|
continue;
|
|
446
445
|
}
|
|
447
446
|
const manifest = m.manifest;
|
|
@@ -452,25 +451,20 @@ function extensionPass(input) {
|
|
|
452
451
|
message: `the project takes "${id}" ${version === "" ? "with no version" : `at version ${version}`}, but its manifest is version ${manifest.version}; run \`patter format\` to take it (renamed stages are renamed in the data as it does)`
|
|
453
452
|
});
|
|
454
453
|
}
|
|
455
|
-
|
|
456
|
-
for (const [name, value] of Object.entries(settings)) {
|
|
457
|
-
if (!known.has(name)) {
|
|
458
|
-
issues.push({ severity: "warning", file: projectPath, message: `"${id}" has no setting "${name}"; it's ignored` });
|
|
459
|
-
} else if (typeof value !== "string" || !/^[A-Za-z_][A-Za-z0-9_]*$/.test(value)) {
|
|
460
|
-
issues.push({
|
|
461
|
-
severity: "error",
|
|
462
|
-
file: projectPath,
|
|
463
|
-
message: `"${id}"'s setting "${name}" names a gameData field, so it's a field name, not ${JSON.stringify(value)}`
|
|
464
|
-
});
|
|
465
|
-
}
|
|
466
|
-
}
|
|
467
|
-
takenList.push({ id, settings, manifest });
|
|
454
|
+
takenList.push({ id, manifest });
|
|
468
455
|
}
|
|
469
456
|
const sound = new Map(takenList.filter((t) => t.manifest !== void 0).map((t) => [t.id, t.manifest]));
|
|
457
|
+
for (const [id, manifest] of sound) {
|
|
458
|
+
for (const req of (0, import_extensions.missingRequirements)(manifest, Object.keys(taken))) {
|
|
459
|
+
issues.push({
|
|
460
|
+
severity: "warning",
|
|
461
|
+
file: projectPath,
|
|
462
|
+
code: "requires-missing",
|
|
463
|
+
message: `the project takes "${id}", which requires the extension "${req}", but doesn't take it; add "${req}" to the project, or ${manifest.name} won't work in the game`
|
|
464
|
+
});
|
|
465
|
+
}
|
|
466
|
+
}
|
|
470
467
|
const nodes = extensionNodes(project, scenes);
|
|
471
|
-
const claims = takenList.flatMap((t) => t.manifest ? (0, import_extensions.resolvedClaims)(t.manifest, "patter", t.settings) : []);
|
|
472
|
-
for (const p of (0, import_extensions.claimClashes)(claims)) issues.push({ severity: p.severity, file: projectPath, code: p.code, message: p.message });
|
|
473
|
-
issues.push(...claimIssues(input, nodes, claims));
|
|
474
468
|
const exists = (kind, id) => kind === "cast" ? (project.cast ?? []).some((c) => c.name === id) : nodes.get(id)?.kind === kind;
|
|
475
469
|
const projectId = project.project.id;
|
|
476
470
|
const projectEntries = /* @__PURE__ */ new Map();
|
|
@@ -578,7 +572,6 @@ function extensionPass(input) {
|
|
|
578
572
|
}
|
|
579
573
|
}
|
|
580
574
|
const bundle = {};
|
|
581
|
-
const chosen = new Map(takenList.map((t) => [t.id, t.settings]));
|
|
582
575
|
for (const [id, manifest] of [...sound.entries()].sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0)) {
|
|
583
576
|
const fields = {};
|
|
584
577
|
for (const kind of Object.keys(manifest.targets.patter ?? {}).sort()) {
|
|
@@ -586,13 +579,7 @@ function extensionPass(input) {
|
|
|
586
579
|
if (target !== void 0) fields[kind] = (0, import_extensions.compiledTarget)(target);
|
|
587
580
|
}
|
|
588
581
|
const projectEntry = projectValues.get(id);
|
|
589
|
-
|
|
590
|
-
bundle[id] = {
|
|
591
|
-
version: manifest.version,
|
|
592
|
-
fields,
|
|
593
|
-
...projectEntry !== void 0 ? { project: projectEntry } : {},
|
|
594
|
-
...settings !== void 0 ? { settings } : {}
|
|
595
|
-
};
|
|
582
|
+
bundle[id] = { version: manifest.version, fields, ...projectEntry !== void 0 ? { project: projectEntry } : {} };
|
|
596
583
|
}
|
|
597
584
|
const sortedNodes = new Map([...values.entries()].map(([id, v]) => [id, sortRecord(v)]));
|
|
598
585
|
return { issues, compiled: { bundle, nodes: sortedNodes } };
|
|
@@ -610,45 +597,6 @@ function pickDecls(manifest) {
|
|
|
610
597
|
function sortRecord(r) {
|
|
611
598
|
return Object.fromEntries(Object.keys(r).sort().map((k) => [k, r[k]]));
|
|
612
599
|
}
|
|
613
|
-
function claimIssues(input, nodes, claims) {
|
|
614
|
-
const issues = [];
|
|
615
|
-
const projectPath = input.projectPath ?? "";
|
|
616
|
-
const declared = input.project.gameDataFields ?? {};
|
|
617
|
-
for (const claim of claims) {
|
|
618
|
-
const decl = (declared[claim.kind] ?? []).find((d) => d.name === claim.field);
|
|
619
|
-
if (decl === void 0) {
|
|
620
|
-
issues.push({
|
|
621
|
-
severity: "warning",
|
|
622
|
-
file: projectPath,
|
|
623
|
-
message: `the Patter extension "${claim.extension}" claims the ${claim.kind} gameData field "${claim.field}", which the project doesn't declare`
|
|
624
|
-
});
|
|
625
|
-
continue;
|
|
626
|
-
}
|
|
627
|
-
if (decl.type !== claim.claim.type) {
|
|
628
|
-
issues.push({
|
|
629
|
-
severity: "error",
|
|
630
|
-
file: projectPath,
|
|
631
|
-
message: `the Patter extension "${claim.extension}" claims the ${claim.kind} gameData field "${claim.field}" as ${claim.claim.type}, but the project declares it as ${decl.type}`
|
|
632
|
-
});
|
|
633
|
-
continue;
|
|
634
|
-
}
|
|
635
|
-
const effective = (0, import_extensions.effectiveClaim)(claim.claim, decl);
|
|
636
|
-
for (const [id, node] of nodes) {
|
|
637
|
-
if (node.kind !== claim.kind || node.gameData === void 0 || !own(node.gameData, claim.field)) continue;
|
|
638
|
-
const file = (node.scene !== void 0 ? input.sceneFiles?.[node.scene] : void 0) ?? projectPath;
|
|
639
|
-
for (const p of (0, import_extensions.valueProblems)(effective, node.gameData[claim.field])) {
|
|
640
|
-
issues.push({
|
|
641
|
-
severity: p.severity,
|
|
642
|
-
file,
|
|
643
|
-
node: id,
|
|
644
|
-
code: p.code,
|
|
645
|
-
message: `${claim.kind} '${id}' gameData "${claim.field}", as the Patter extension "${claim.extension}" claims it: ${p.message}`
|
|
646
|
-
});
|
|
647
|
-
}
|
|
648
|
-
}
|
|
649
|
-
}
|
|
650
|
-
return issues;
|
|
651
|
-
}
|
|
652
600
|
|
|
653
601
|
// src/export.ts
|
|
654
602
|
function compileBeat(beat, ctx, asAction = false) {
|
|
@@ -877,8 +825,7 @@ function exportBundle(input) {
|
|
|
877
825
|
Object.entries(project.gameDataFields).map(([kind, fields]) => [kind, resolved(fields)])
|
|
878
826
|
),
|
|
879
827
|
// The extensions the project takes: each one's version, its compiled declarations by node kind (every
|
|
880
|
-
// default resolved, editor-only fields and the editor's words left out), the project node's values
|
|
881
|
-
// its settings, each the project's value or else the default.
|
|
828
|
+
// default resolved, editor-only fields and the editor's words left out), and the project node's values.
|
|
882
829
|
...extensionSection !== void 0 ? { extensions: extensionSection } : {},
|
|
883
830
|
// Closed-caption delimiters ride along only when the project pins a non-default pair (#214); the
|
|
884
831
|
// runtime falls back to `[` / `]` when absent, so default projects keep their exact prior bundle.
|
package/dist/index.js
CHANGED
|
@@ -321,19 +321,15 @@ import { textIsAction, usedQualifiers, usedSpeakerPairs, walkNodes as walkNodes2
|
|
|
321
321
|
import { EXTENSIONS_DIR, MANIFEST_EXTENSION, PROJECT_LOCALE_SCENE } from "@patterkit/model";
|
|
322
322
|
import {
|
|
323
323
|
HOSTS,
|
|
324
|
-
claimClashes,
|
|
325
324
|
compileEntry,
|
|
326
325
|
compiledTarget,
|
|
327
|
-
effectiveClaim,
|
|
328
326
|
entryProblems,
|
|
329
327
|
manifestProblems,
|
|
328
|
+
missingRequirements,
|
|
330
329
|
orphanedEntries,
|
|
331
330
|
pickClashes,
|
|
332
331
|
pickLists,
|
|
333
|
-
|
|
334
|
-
settingValues,
|
|
335
|
-
targetOf,
|
|
336
|
-
valueProblems
|
|
332
|
+
targetOf
|
|
337
333
|
} from "@wildwinter/toolkit/extensions";
|
|
338
334
|
function extensionNodes(project, scenes) {
|
|
339
335
|
const nodes = /* @__PURE__ */ new Map();
|
|
@@ -409,18 +405,17 @@ function extensionPass(input) {
|
|
|
409
405
|
for (const [id, entry] of Object.entries(taken)) {
|
|
410
406
|
const m = manifests.get(id);
|
|
411
407
|
const version = typeof entry?.version === "string" ? entry.version : "";
|
|
412
|
-
const settings = entry?.settings ?? {};
|
|
413
408
|
if (m === void 0) {
|
|
414
409
|
issues.push({
|
|
415
410
|
severity: "warning",
|
|
416
411
|
file: projectPath,
|
|
417
412
|
message: `the project takes the Patter extension "${id}", but has no manifest for it at ${EXTENSIONS_DIR}/${id}${MANIFEST_EXTENSION}; its data is left as it is, and not compiled`
|
|
418
413
|
});
|
|
419
|
-
takenList.push({ id
|
|
414
|
+
takenList.push({ id });
|
|
420
415
|
continue;
|
|
421
416
|
}
|
|
422
417
|
if (!m.sound) {
|
|
423
|
-
takenList.push({ id
|
|
418
|
+
takenList.push({ id });
|
|
424
419
|
continue;
|
|
425
420
|
}
|
|
426
421
|
const manifest = m.manifest;
|
|
@@ -431,25 +426,20 @@ function extensionPass(input) {
|
|
|
431
426
|
message: `the project takes "${id}" ${version === "" ? "with no version" : `at version ${version}`}, but its manifest is version ${manifest.version}; run \`patter format\` to take it (renamed stages are renamed in the data as it does)`
|
|
432
427
|
});
|
|
433
428
|
}
|
|
434
|
-
|
|
435
|
-
for (const [name, value] of Object.entries(settings)) {
|
|
436
|
-
if (!known.has(name)) {
|
|
437
|
-
issues.push({ severity: "warning", file: projectPath, message: `"${id}" has no setting "${name}"; it's ignored` });
|
|
438
|
-
} else if (typeof value !== "string" || !/^[A-Za-z_][A-Za-z0-9_]*$/.test(value)) {
|
|
439
|
-
issues.push({
|
|
440
|
-
severity: "error",
|
|
441
|
-
file: projectPath,
|
|
442
|
-
message: `"${id}"'s setting "${name}" names a gameData field, so it's a field name, not ${JSON.stringify(value)}`
|
|
443
|
-
});
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
takenList.push({ id, settings, manifest });
|
|
429
|
+
takenList.push({ id, manifest });
|
|
447
430
|
}
|
|
448
431
|
const sound = new Map(takenList.filter((t) => t.manifest !== void 0).map((t) => [t.id, t.manifest]));
|
|
432
|
+
for (const [id, manifest] of sound) {
|
|
433
|
+
for (const req of missingRequirements(manifest, Object.keys(taken))) {
|
|
434
|
+
issues.push({
|
|
435
|
+
severity: "warning",
|
|
436
|
+
file: projectPath,
|
|
437
|
+
code: "requires-missing",
|
|
438
|
+
message: `the project takes "${id}", which requires the extension "${req}", but doesn't take it; add "${req}" to the project, or ${manifest.name} won't work in the game`
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
}
|
|
449
442
|
const nodes = extensionNodes(project, scenes);
|
|
450
|
-
const claims = takenList.flatMap((t) => t.manifest ? resolvedClaims(t.manifest, "patter", t.settings) : []);
|
|
451
|
-
for (const p of claimClashes(claims)) issues.push({ severity: p.severity, file: projectPath, code: p.code, message: p.message });
|
|
452
|
-
issues.push(...claimIssues(input, nodes, claims));
|
|
453
443
|
const exists = (kind, id) => kind === "cast" ? (project.cast ?? []).some((c) => c.name === id) : nodes.get(id)?.kind === kind;
|
|
454
444
|
const projectId = project.project.id;
|
|
455
445
|
const projectEntries = /* @__PURE__ */ new Map();
|
|
@@ -557,7 +547,6 @@ function extensionPass(input) {
|
|
|
557
547
|
}
|
|
558
548
|
}
|
|
559
549
|
const bundle = {};
|
|
560
|
-
const chosen = new Map(takenList.map((t) => [t.id, t.settings]));
|
|
561
550
|
for (const [id, manifest] of [...sound.entries()].sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0)) {
|
|
562
551
|
const fields = {};
|
|
563
552
|
for (const kind of Object.keys(manifest.targets.patter ?? {}).sort()) {
|
|
@@ -565,13 +554,7 @@ function extensionPass(input) {
|
|
|
565
554
|
if (target !== void 0) fields[kind] = compiledTarget(target);
|
|
566
555
|
}
|
|
567
556
|
const projectEntry = projectValues.get(id);
|
|
568
|
-
|
|
569
|
-
bundle[id] = {
|
|
570
|
-
version: manifest.version,
|
|
571
|
-
fields,
|
|
572
|
-
...projectEntry !== void 0 ? { project: projectEntry } : {},
|
|
573
|
-
...settings !== void 0 ? { settings } : {}
|
|
574
|
-
};
|
|
557
|
+
bundle[id] = { version: manifest.version, fields, ...projectEntry !== void 0 ? { project: projectEntry } : {} };
|
|
575
558
|
}
|
|
576
559
|
const sortedNodes = new Map([...values.entries()].map(([id, v]) => [id, sortRecord(v)]));
|
|
577
560
|
return { issues, compiled: { bundle, nodes: sortedNodes } };
|
|
@@ -589,45 +572,6 @@ function pickDecls(manifest) {
|
|
|
589
572
|
function sortRecord(r) {
|
|
590
573
|
return Object.fromEntries(Object.keys(r).sort().map((k) => [k, r[k]]));
|
|
591
574
|
}
|
|
592
|
-
function claimIssues(input, nodes, claims) {
|
|
593
|
-
const issues = [];
|
|
594
|
-
const projectPath = input.projectPath ?? "";
|
|
595
|
-
const declared = input.project.gameDataFields ?? {};
|
|
596
|
-
for (const claim of claims) {
|
|
597
|
-
const decl = (declared[claim.kind] ?? []).find((d) => d.name === claim.field);
|
|
598
|
-
if (decl === void 0) {
|
|
599
|
-
issues.push({
|
|
600
|
-
severity: "warning",
|
|
601
|
-
file: projectPath,
|
|
602
|
-
message: `the Patter extension "${claim.extension}" claims the ${claim.kind} gameData field "${claim.field}", which the project doesn't declare`
|
|
603
|
-
});
|
|
604
|
-
continue;
|
|
605
|
-
}
|
|
606
|
-
if (decl.type !== claim.claim.type) {
|
|
607
|
-
issues.push({
|
|
608
|
-
severity: "error",
|
|
609
|
-
file: projectPath,
|
|
610
|
-
message: `the Patter extension "${claim.extension}" claims the ${claim.kind} gameData field "${claim.field}" as ${claim.claim.type}, but the project declares it as ${decl.type}`
|
|
611
|
-
});
|
|
612
|
-
continue;
|
|
613
|
-
}
|
|
614
|
-
const effective = effectiveClaim(claim.claim, decl);
|
|
615
|
-
for (const [id, node] of nodes) {
|
|
616
|
-
if (node.kind !== claim.kind || node.gameData === void 0 || !own(node.gameData, claim.field)) continue;
|
|
617
|
-
const file = (node.scene !== void 0 ? input.sceneFiles?.[node.scene] : void 0) ?? projectPath;
|
|
618
|
-
for (const p of valueProblems(effective, node.gameData[claim.field])) {
|
|
619
|
-
issues.push({
|
|
620
|
-
severity: p.severity,
|
|
621
|
-
file,
|
|
622
|
-
node: id,
|
|
623
|
-
code: p.code,
|
|
624
|
-
message: `${claim.kind} '${id}' gameData "${claim.field}", as the Patter extension "${claim.extension}" claims it: ${p.message}`
|
|
625
|
-
});
|
|
626
|
-
}
|
|
627
|
-
}
|
|
628
|
-
}
|
|
629
|
-
return issues;
|
|
630
|
-
}
|
|
631
575
|
|
|
632
576
|
// src/export.ts
|
|
633
577
|
function compileBeat(beat, ctx, asAction = false) {
|
|
@@ -856,8 +800,7 @@ function exportBundle(input) {
|
|
|
856
800
|
Object.entries(project.gameDataFields).map(([kind, fields]) => [kind, resolved(fields)])
|
|
857
801
|
),
|
|
858
802
|
// The extensions the project takes: each one's version, its compiled declarations by node kind (every
|
|
859
|
-
// default resolved, editor-only fields and the editor's words left out), the project node's values
|
|
860
|
-
// its settings, each the project's value or else the default.
|
|
803
|
+
// default resolved, editor-only fields and the editor's words left out), and the project node's values.
|
|
861
804
|
...extensionSection !== void 0 ? { extensions: extensionSection } : {},
|
|
862
805
|
// Closed-caption delimiters ride along only when the project pins a non-default pair (#214); the
|
|
863
806
|
// runtime falls back to `[` / `]` when absent, so default projects keep their exact prior bundle.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@patterkit/compiler",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.1",
|
|
4
4
|
"description": "Patter compiler: compile condition/effect expressions, validate them, and export source to the runtime bundle.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -34,11 +34,11 @@
|
|
|
34
34
|
"build": "tsup src/index.ts --format esm,cjs --dts --clean"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@patterkit/model": "0.
|
|
38
|
-
"@patterkit/core": "0.9.
|
|
39
|
-
"@patterkit/dialect": "0.2.
|
|
37
|
+
"@patterkit/model": "0.20.0",
|
|
38
|
+
"@patterkit/core": "0.9.6",
|
|
39
|
+
"@patterkit/dialect": "0.2.17",
|
|
40
40
|
"@wildwinter/expr": "^0.6.0",
|
|
41
|
-
"@wildwinter/toolkit": "^0.
|
|
41
|
+
"@wildwinter/toolkit": "^0.3.1"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
44
44
|
"@wildwinter/scoperegistry": ">=0.9.0 <1.0.0"
|