@patterkit/core 0.3.1 → 0.4.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/README.md +35 -0
- package/dist/index.cjs +70 -11
- package/dist/index.d.cts +4 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +66 -7
- package/package.json +2 -2
package/README.md
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# @patterkit/core
|
|
2
|
+
|
|
3
|
+
The low-level building blocks shared by Patter's editor, command line tool, and CI: ids, readable handles,
|
|
4
|
+
reading and writing the source files, and the structural validator.
|
|
5
|
+
|
|
6
|
+
Most people won't need to install this directly. To play Patter dialogue in a game or web page, use
|
|
7
|
+
[`@patterkit/runtime`](https://www.npmjs.com/package/@patterkit/runtime); to work with Patter projects from
|
|
8
|
+
a terminal or a build script, use [`@patterkit/cli`](https://www.npmjs.com/package/@patterkit/cli).
|
|
9
|
+
|
|
10
|
+
## What's in it
|
|
11
|
+
|
|
12
|
+
- **Ids and handles**: `newId` for stable node ids, and `slug`, `hash4`, and `hash32` for the readable
|
|
13
|
+
handles and content hashes built from them.
|
|
14
|
+
- **Reading and writing source files**: `parseSource` and `canonicalStringify`, which write a project's
|
|
15
|
+
files in one canonical form so version control shows only real changes.
|
|
16
|
+
- **The structural validator**: `validateProject` checks a project and its scenes hang together (ids,
|
|
17
|
+
references, and structure) and returns a list of issues.
|
|
18
|
+
- **Scene scaffolding**: `planProject` and `planScene` plan a stub project or scene that another tool can
|
|
19
|
+
hand to a writer.
|
|
20
|
+
|
|
21
|
+
```sh
|
|
22
|
+
npm install @patterkit/core
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Part of Patter
|
|
26
|
+
|
|
27
|
+
[Patter](https://patterkit.dev/) is a branching dialogue format with its own editor (Patterpad), command line
|
|
28
|
+
tool (`patter`), and runtimes for JavaScript, Unity, Unreal, and Godot. This package is one layer of the
|
|
29
|
+
JavaScript tooling, and the other `@patterkit` packages build on it. [How it fits
|
|
30
|
+
together](https://patterkit.dev/architecture/) shows where each piece sits, and the source is in the
|
|
31
|
+
[patter repository](https://github.com/patterkit/patter).
|
|
32
|
+
|
|
33
|
+
## Licence
|
|
34
|
+
|
|
35
|
+
MIT
|
package/dist/index.cjs
CHANGED
|
@@ -21,12 +21,12 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
canonicalStringify: () => canonicalStringify,
|
|
24
|
-
effectiveGameId: () =>
|
|
25
|
-
gameIdify: () =>
|
|
24
|
+
effectiveGameId: () => import_model5.effectiveGameId,
|
|
25
|
+
gameIdify: () => import_model5.gameIdify,
|
|
26
26
|
hash32: () => hash32,
|
|
27
27
|
hash4: () => hash4,
|
|
28
28
|
humanizeNodeRefs: () => humanizeNodeRefs,
|
|
29
|
-
isValidGameId: () =>
|
|
29
|
+
isValidGameId: () => import_model5.isValidGameId,
|
|
30
30
|
newId: () => import_toolkit.newId,
|
|
31
31
|
parseSource: () => import_toolkit3.parseSource,
|
|
32
32
|
planProject: () => planProject,
|
|
@@ -53,7 +53,7 @@ function hash32(input) {
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
// src/index.ts
|
|
56
|
-
var
|
|
56
|
+
var import_model5 = require("@patterkit/model");
|
|
57
57
|
|
|
58
58
|
// src/noderefs.ts
|
|
59
59
|
var VISIT_FN_RE = /\b(patter_visits|patter_seen|visits|seen)\s*\(\s*(?:(['"])(.*?)\2|([A-Za-z_]\w*))\s*\)/g;
|
|
@@ -106,6 +106,59 @@ function isContentlessNode(node) {
|
|
|
106
106
|
if (node.prompt) return false;
|
|
107
107
|
return Array.isArray(node.children) && node.children.every(isContentlessNode);
|
|
108
108
|
}
|
|
109
|
+
function contentlessJumpCycles(scenes) {
|
|
110
|
+
const firstBlock = /* @__PURE__ */ new Map();
|
|
111
|
+
for (const scene of scenes) {
|
|
112
|
+
const first = Array.isArray(scene.blocks) ? scene.blocks[0] : void 0;
|
|
113
|
+
if (typeof scene.id === "string" && typeof first?.id === "string") firstBlock.set(scene.id, first.id);
|
|
114
|
+
}
|
|
115
|
+
const leads = (children) => {
|
|
116
|
+
if (!Array.isArray(children)) return void 0;
|
|
117
|
+
for (const n of children) {
|
|
118
|
+
if (!n || typeof n !== "object" || n.condition) return void 0;
|
|
119
|
+
if (n.type === "snippet") {
|
|
120
|
+
if ((n.beats?.length ?? 0) > 0) return void 0;
|
|
121
|
+
if (!n.jump) continue;
|
|
122
|
+
if (n.jump.to === "END") return void 0;
|
|
123
|
+
const to = firstBlock.get(n.jump.to) ?? n.jump.to;
|
|
124
|
+
return { via: n.id, to };
|
|
125
|
+
}
|
|
126
|
+
if (n.type !== "group" || n.prompt || n.selector !== void 0 && n.selector !== "run") return void 0;
|
|
127
|
+
const inner = leads(n.children);
|
|
128
|
+
if (inner !== "through") return inner;
|
|
129
|
+
}
|
|
130
|
+
return "through";
|
|
131
|
+
};
|
|
132
|
+
const next = /* @__PURE__ */ new Map();
|
|
133
|
+
for (const scene of scenes) {
|
|
134
|
+
for (const block of Array.isArray(scene.blocks) ? scene.blocks : []) {
|
|
135
|
+
const l = leads(block.children);
|
|
136
|
+
if (l && l !== "through" && typeof block.id === "string") next.set(block.id, l);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
const issues = [];
|
|
140
|
+
const settled = /* @__PURE__ */ new Set();
|
|
141
|
+
for (const startId of next.keys()) {
|
|
142
|
+
const path = [];
|
|
143
|
+
let at = startId;
|
|
144
|
+
while (at !== void 0 && !settled.has(at) && !path.includes(at)) {
|
|
145
|
+
path.push(at);
|
|
146
|
+
at = next.get(at)?.to;
|
|
147
|
+
}
|
|
148
|
+
if (at !== void 0 && path.includes(at)) {
|
|
149
|
+
const loop = path.slice(path.indexOf(at));
|
|
150
|
+
const via = loop.map((b) => next.get(b).via);
|
|
151
|
+
issues.push({
|
|
152
|
+
code: "jump-cycle",
|
|
153
|
+
severity: "warning",
|
|
154
|
+
id: via[0],
|
|
155
|
+
message: `${via.length === 1 ? `snippet '${via[0]}' jumps` : `snippets ${via.map((v) => `'${v}'`).join(", ")} jump`} round a loop with nothing to deliver (blocks ${[...loop, at].map((b) => `'${b}'`).join(" -> ")}); play reaching it never gets out`
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
for (const b of path) settled.add(b);
|
|
159
|
+
}
|
|
160
|
+
return issues;
|
|
161
|
+
}
|
|
109
162
|
function validateProject(input) {
|
|
110
163
|
const { project, scenes } = input;
|
|
111
164
|
const issues = [];
|
|
@@ -243,9 +296,9 @@ function validateProject(input) {
|
|
|
243
296
|
}
|
|
244
297
|
const hasUnconditionalEscape = (node.children ?? []).some((opt) => !opt.condition);
|
|
245
298
|
if ((node.children?.length ?? 0) > 0 && !hasUnconditionalEscape) {
|
|
246
|
-
issues.push({ code: "choice-can-empty", message: `choice '${node.id}' in ${inBlock} has no unconditional option or fallback - it runs dry (falls through) if every condition fails`, id: node.id });
|
|
299
|
+
issues.push({ code: "choice-can-empty", message: `choice '${node.id}' in ${inBlock} has no unconditional option or fallback - it runs dry (falls through) if every condition fails`, id: node.id, severity: "warning" });
|
|
247
300
|
} else if (!hasSticky && fallbacks === 0 && choiceLoopsBack(node, block.id, bgid, scene.id, sgid)) {
|
|
248
|
-
issues.push({ code: "choice-can-empty", message: `choice '${node.id}' in ${inBlock} can be re-entered but every option is once-only with no fallback - it will run dry`, id: node.id });
|
|
301
|
+
issues.push({ code: "choice-can-empty", message: `choice '${node.id}' in ${inBlock} can be re-entered but every option is once-only with no fallback - it will run dry`, id: node.id, severity: "warning" });
|
|
249
302
|
}
|
|
250
303
|
}
|
|
251
304
|
return;
|
|
@@ -254,6 +307,10 @@ function validateProject(input) {
|
|
|
254
307
|
for (const beat of node.beats ?? []) {
|
|
255
308
|
seeId(beat.id, "beat", `snippet '${node.id}'`);
|
|
256
309
|
checkTags(beat.tags, `beat '${beat.id}'`, beat.id);
|
|
310
|
+
const kind = beat.kind;
|
|
311
|
+
if (kind !== "line" && kind !== "text" && kind !== "gameEvent") {
|
|
312
|
+
issues.push({ code: "malformed-node", message: `beat '${beat.id}' has an unknown kind '${kind}' (line, text, or gameEvent)`, id: beat.id });
|
|
313
|
+
}
|
|
257
314
|
if (beat.kind === "line" && beat.character && !castNames.has(beat.character)) {
|
|
258
315
|
issues.push({
|
|
259
316
|
code: "unknown-character",
|
|
@@ -267,6 +324,7 @@ function validateProject(input) {
|
|
|
267
324
|
}
|
|
268
325
|
}
|
|
269
326
|
if (input.authoring) validateAuthoring(input.authoring, project, allIds, issues);
|
|
327
|
+
issues.push(...contentlessJumpCycles(scenes));
|
|
270
328
|
for (const d of jumps) {
|
|
271
329
|
if (d.to === "END") continue;
|
|
272
330
|
if (!allIds.has(d.to)) {
|
|
@@ -476,11 +534,12 @@ function defaultMatchesType(value, decl) {
|
|
|
476
534
|
}
|
|
477
535
|
|
|
478
536
|
// src/scene-scaffold.ts
|
|
537
|
+
var import_model4 = require("@patterkit/model");
|
|
479
538
|
var trimSlash = (p) => p.replace(/\/+$/, "");
|
|
480
539
|
function planProject(opts) {
|
|
481
540
|
const locale = opts.locale ?? "en";
|
|
482
541
|
const project = {
|
|
483
|
-
schema:
|
|
542
|
+
schema: import_model4.PROJECT_SCHEMA,
|
|
484
543
|
project: { id: (0, import_toolkit.newId)("proj"), name: opts.name },
|
|
485
544
|
locales: { default: locale, all: [locale] },
|
|
486
545
|
voiced: true
|
|
@@ -532,10 +591,10 @@ function planScene(target, scaffold) {
|
|
|
532
591
|
gameId: scaffold.gameId,
|
|
533
592
|
blocks: [{ id: (0, import_toolkit.newId)("blk"), type: "block", name: "Main", children }]
|
|
534
593
|
};
|
|
535
|
-
const flow = { schema:
|
|
536
|
-
const locale = { schema:
|
|
537
|
-
const flowDir = trimSlash(target.
|
|
538
|
-
const stringsDir = trimSlash(target.
|
|
594
|
+
const flow = { schema: import_model4.FLOW_SCHEMA, scene };
|
|
595
|
+
const locale = { schema: import_model4.STRINGS_SCHEMA, scene: sceneId, locale: target.locale, default: true, strings };
|
|
596
|
+
const flowDir = trimSlash((0, import_model4.projectLayout)(target).flow);
|
|
597
|
+
const stringsDir = trimSlash((0, import_model4.projectLayout)(target).strings);
|
|
539
598
|
return {
|
|
540
599
|
sceneId,
|
|
541
600
|
writes: [
|
package/dist/index.d.cts
CHANGED
|
@@ -26,10 +26,13 @@ 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" | "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";
|
|
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" | "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";
|
|
30
30
|
message: string;
|
|
31
31
|
/** Id of the offending node/beat, where applicable. */
|
|
32
32
|
id?: string;
|
|
33
|
+
/** Absent means an error: the project should not be built. A warning still compiles and plays (a choice
|
|
34
|
+
* that can run dry gathers or falls through at runtime), and every front end shows it as one. */
|
|
35
|
+
severity?: "warning";
|
|
33
36
|
}
|
|
34
37
|
interface ProjectInput {
|
|
35
38
|
project: ProjectFile;
|
package/dist/index.d.ts
CHANGED
|
@@ -26,10 +26,13 @@ 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" | "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";
|
|
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" | "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";
|
|
30
30
|
message: string;
|
|
31
31
|
/** Id of the offending node/beat, where applicable. */
|
|
32
32
|
id?: string;
|
|
33
|
+
/** Absent means an error: the project should not be built. A warning still compiles and plays (a choice
|
|
34
|
+
* that can run dry gathers or falls through at runtime), and every front end shows it as one. */
|
|
35
|
+
severity?: "warning";
|
|
33
36
|
}
|
|
34
37
|
interface ProjectInput {
|
|
35
38
|
project: ProjectFile;
|
package/dist/index.js
CHANGED
|
@@ -68,6 +68,59 @@ function isContentlessNode(node) {
|
|
|
68
68
|
if (node.prompt) return false;
|
|
69
69
|
return Array.isArray(node.children) && node.children.every(isContentlessNode);
|
|
70
70
|
}
|
|
71
|
+
function contentlessJumpCycles(scenes) {
|
|
72
|
+
const firstBlock = /* @__PURE__ */ new Map();
|
|
73
|
+
for (const scene of scenes) {
|
|
74
|
+
const first = Array.isArray(scene.blocks) ? scene.blocks[0] : void 0;
|
|
75
|
+
if (typeof scene.id === "string" && typeof first?.id === "string") firstBlock.set(scene.id, first.id);
|
|
76
|
+
}
|
|
77
|
+
const leads = (children) => {
|
|
78
|
+
if (!Array.isArray(children)) return void 0;
|
|
79
|
+
for (const n of children) {
|
|
80
|
+
if (!n || typeof n !== "object" || n.condition) return void 0;
|
|
81
|
+
if (n.type === "snippet") {
|
|
82
|
+
if ((n.beats?.length ?? 0) > 0) return void 0;
|
|
83
|
+
if (!n.jump) continue;
|
|
84
|
+
if (n.jump.to === "END") return void 0;
|
|
85
|
+
const to = firstBlock.get(n.jump.to) ?? n.jump.to;
|
|
86
|
+
return { via: n.id, to };
|
|
87
|
+
}
|
|
88
|
+
if (n.type !== "group" || n.prompt || n.selector !== void 0 && n.selector !== "run") return void 0;
|
|
89
|
+
const inner = leads(n.children);
|
|
90
|
+
if (inner !== "through") return inner;
|
|
91
|
+
}
|
|
92
|
+
return "through";
|
|
93
|
+
};
|
|
94
|
+
const next = /* @__PURE__ */ new Map();
|
|
95
|
+
for (const scene of scenes) {
|
|
96
|
+
for (const block of Array.isArray(scene.blocks) ? scene.blocks : []) {
|
|
97
|
+
const l = leads(block.children);
|
|
98
|
+
if (l && l !== "through" && typeof block.id === "string") next.set(block.id, l);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
const issues = [];
|
|
102
|
+
const settled = /* @__PURE__ */ new Set();
|
|
103
|
+
for (const startId of next.keys()) {
|
|
104
|
+
const path = [];
|
|
105
|
+
let at = startId;
|
|
106
|
+
while (at !== void 0 && !settled.has(at) && !path.includes(at)) {
|
|
107
|
+
path.push(at);
|
|
108
|
+
at = next.get(at)?.to;
|
|
109
|
+
}
|
|
110
|
+
if (at !== void 0 && path.includes(at)) {
|
|
111
|
+
const loop = path.slice(path.indexOf(at));
|
|
112
|
+
const via = loop.map((b) => next.get(b).via);
|
|
113
|
+
issues.push({
|
|
114
|
+
code: "jump-cycle",
|
|
115
|
+
severity: "warning",
|
|
116
|
+
id: via[0],
|
|
117
|
+
message: `${via.length === 1 ? `snippet '${via[0]}' jumps` : `snippets ${via.map((v) => `'${v}'`).join(", ")} jump`} round a loop with nothing to deliver (blocks ${[...loop, at].map((b) => `'${b}'`).join(" -> ")}); play reaching it never gets out`
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
for (const b of path) settled.add(b);
|
|
121
|
+
}
|
|
122
|
+
return issues;
|
|
123
|
+
}
|
|
71
124
|
function validateProject(input) {
|
|
72
125
|
const { project, scenes } = input;
|
|
73
126
|
const issues = [];
|
|
@@ -205,9 +258,9 @@ function validateProject(input) {
|
|
|
205
258
|
}
|
|
206
259
|
const hasUnconditionalEscape = (node.children ?? []).some((opt) => !opt.condition);
|
|
207
260
|
if ((node.children?.length ?? 0) > 0 && !hasUnconditionalEscape) {
|
|
208
|
-
issues.push({ code: "choice-can-empty", message: `choice '${node.id}' in ${inBlock} has no unconditional option or fallback - it runs dry (falls through) if every condition fails`, id: node.id });
|
|
261
|
+
issues.push({ code: "choice-can-empty", message: `choice '${node.id}' in ${inBlock} has no unconditional option or fallback - it runs dry (falls through) if every condition fails`, id: node.id, severity: "warning" });
|
|
209
262
|
} else if (!hasSticky && fallbacks === 0 && choiceLoopsBack(node, block.id, bgid, scene.id, sgid)) {
|
|
210
|
-
issues.push({ code: "choice-can-empty", message: `choice '${node.id}' in ${inBlock} can be re-entered but every option is once-only with no fallback - it will run dry`, id: node.id });
|
|
263
|
+
issues.push({ code: "choice-can-empty", message: `choice '${node.id}' in ${inBlock} can be re-entered but every option is once-only with no fallback - it will run dry`, id: node.id, severity: "warning" });
|
|
211
264
|
}
|
|
212
265
|
}
|
|
213
266
|
return;
|
|
@@ -216,6 +269,10 @@ function validateProject(input) {
|
|
|
216
269
|
for (const beat of node.beats ?? []) {
|
|
217
270
|
seeId(beat.id, "beat", `snippet '${node.id}'`);
|
|
218
271
|
checkTags(beat.tags, `beat '${beat.id}'`, beat.id);
|
|
272
|
+
const kind = beat.kind;
|
|
273
|
+
if (kind !== "line" && kind !== "text" && kind !== "gameEvent") {
|
|
274
|
+
issues.push({ code: "malformed-node", message: `beat '${beat.id}' has an unknown kind '${kind}' (line, text, or gameEvent)`, id: beat.id });
|
|
275
|
+
}
|
|
219
276
|
if (beat.kind === "line" && beat.character && !castNames.has(beat.character)) {
|
|
220
277
|
issues.push({
|
|
221
278
|
code: "unknown-character",
|
|
@@ -229,6 +286,7 @@ function validateProject(input) {
|
|
|
229
286
|
}
|
|
230
287
|
}
|
|
231
288
|
if (input.authoring) validateAuthoring(input.authoring, project, allIds, issues);
|
|
289
|
+
issues.push(...contentlessJumpCycles(scenes));
|
|
232
290
|
for (const d of jumps) {
|
|
233
291
|
if (d.to === "END") continue;
|
|
234
292
|
if (!allIds.has(d.to)) {
|
|
@@ -438,11 +496,12 @@ function defaultMatchesType(value, decl) {
|
|
|
438
496
|
}
|
|
439
497
|
|
|
440
498
|
// src/scene-scaffold.ts
|
|
499
|
+
import { projectLayout, FLOW_SCHEMA, PROJECT_SCHEMA, STRINGS_SCHEMA } from "@patterkit/model";
|
|
441
500
|
var trimSlash = (p) => p.replace(/\/+$/, "");
|
|
442
501
|
function planProject(opts) {
|
|
443
502
|
const locale = opts.locale ?? "en";
|
|
444
503
|
const project = {
|
|
445
|
-
schema:
|
|
504
|
+
schema: PROJECT_SCHEMA,
|
|
446
505
|
project: { id: newId("proj"), name: opts.name },
|
|
447
506
|
locales: { default: locale, all: [locale] },
|
|
448
507
|
voiced: true
|
|
@@ -494,10 +553,10 @@ function planScene(target, scaffold) {
|
|
|
494
553
|
gameId: scaffold.gameId,
|
|
495
554
|
blocks: [{ id: newId("blk"), type: "block", name: "Main", children }]
|
|
496
555
|
};
|
|
497
|
-
const flow = { schema:
|
|
498
|
-
const locale = { schema:
|
|
499
|
-
const flowDir = trimSlash(target.
|
|
500
|
-
const stringsDir = trimSlash(target.
|
|
556
|
+
const flow = { schema: FLOW_SCHEMA, scene };
|
|
557
|
+
const locale = { schema: STRINGS_SCHEMA, scene: sceneId, locale: target.locale, default: true, strings };
|
|
558
|
+
const flowDir = trimSlash(projectLayout(target).flow);
|
|
559
|
+
const stringsDir = trimSlash(projectLayout(target).strings);
|
|
501
560
|
return {
|
|
502
561
|
sceneId,
|
|
503
562
|
writes: [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@patterkit/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.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,7 @@
|
|
|
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.10.0",
|
|
38
38
|
"@wildwinter/toolkit": "^0.1.0",
|
|
39
39
|
"json5": "^2.2.3"
|
|
40
40
|
}
|