@patterkit/ops 0.8.0 → 0.10.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.d.ts +28 -1
- package/dist/index.js +62 -20
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -142,10 +142,17 @@ declare function defaultGameScopesDir(root: string): string;
|
|
|
142
142
|
* engine's, which is that engine's to declare). The project keeps its copy. When the walk-up from the
|
|
143
143
|
* project would not find `dir`, the project names it (`gameScopes`), so it is found next time. Returns
|
|
144
144
|
* the writes (the folder comes with the first), and the project as it should now be saved.
|
|
145
|
+
*
|
|
146
|
+
* A folder another tool already made is JOINED, never overwritten: an existing `game.scopes.json` keeps
|
|
147
|
+
* every scope it holds, and gains only the project's game scopes it doesn't declare yet (as the
|
|
148
|
+
* Storylet Engine's share adds `@world` only when the file has none). One that won't parse is an error,
|
|
149
|
+
* and nothing is written.
|
|
145
150
|
*/
|
|
146
151
|
declare function planShareScopes(root: string, project: ProjectFile, dir: string): {
|
|
147
152
|
writes: PlannedWrite[];
|
|
148
153
|
project: ProjectFile;
|
|
154
|
+
} | {
|
|
155
|
+
error: string;
|
|
149
156
|
};
|
|
150
157
|
|
|
151
158
|
interface LoadedProject {
|
|
@@ -921,6 +928,26 @@ interface ReplacePlan {
|
|
|
921
928
|
*/
|
|
922
929
|
declare function runReplace(loaded: LoadedProject, opts: ReplaceOptions): ReplacePlan;
|
|
923
930
|
|
|
931
|
+
/** One address written down. */
|
|
932
|
+
interface PinnedName {
|
|
933
|
+
/** The node's immutable id. */
|
|
934
|
+
id: string;
|
|
935
|
+
kind: "scene" | "block";
|
|
936
|
+
/** The scene it belongs to (itself, for a scene). */
|
|
937
|
+
sceneId: string;
|
|
938
|
+
/** The address, now pinned: the same one it had while it followed the name. */
|
|
939
|
+
gameId: string;
|
|
940
|
+
}
|
|
941
|
+
interface PinPlan {
|
|
942
|
+
pinned: PinnedName[];
|
|
943
|
+
/** Flow-shard writes the caller commits through the VC layer (one per touched scene). */
|
|
944
|
+
writes: PlannedWrite[];
|
|
945
|
+
/** The rewritten scenes, index-aligned with `writes`. */
|
|
946
|
+
scenes: Scene[];
|
|
947
|
+
}
|
|
948
|
+
/** Plan pinning every scene and block address still following its name. */
|
|
949
|
+
declare function planPins(loaded: LoadedProject): PinPlan;
|
|
950
|
+
|
|
924
951
|
/** The source-shard extensions a document carries (the merge-friendly truth). */
|
|
925
952
|
declare const SHARD_EXTENSIONS: readonly [".patterflow", ".patterloc", ".patterx", ".patterproj"];
|
|
926
953
|
/** Manifest embedded at the document root - what this envelope is and contains. */
|
|
@@ -1087,4 +1114,4 @@ declare function classesForChannel(classes: DocumentationClass[], channel: strin
|
|
|
1087
1114
|
*/
|
|
1088
1115
|
declare function resolveDocumentation(loaded: LoadedProject, channel: string): Map<string, DocLine[]>;
|
|
1089
1116
|
|
|
1090
|
-
export { AUTHORING_HANDLED, type ApplyStats, type BundlePosture, CONFLICT_SIDECAR, type CharacterReport, type Conflict, type ConflictKind, type CoverageAsyncHooks, type CoverageBeat, type CoverageHooks, type CoverageOptions, type CoverageReport, type DocumentManifest, type FormatResult, GAME_SCOPES_OWNER, type GameScopes, type GameScopesIssue, type HygieneIssue, type InitOptions, type InitResult, type InitVcs, type LoadedProject, type LocCatalog, type LocEntry, type LocaleReport, type MergeFileType, type MergeResult, type MergedShard, PATTER_SCOPES_FILE, PATTER_SCOPES_OWNER, type PlannedWrite, type PlayEvent, type PlayOptions, type PlayOutcome, type PlayResult, type ProvenanceCheck, type ReplaceHit, type ReplaceOptions, type ReplacePlan, type ReportData, type ReportTotals, type ResolveEntry, SHARD_EXTENSIONS, type SceneReport, type ScriptDoc, type ScriptElement, type SearchFocus, type UnpackMergeResult, type UnpackResult, UnsafeEntryError, UnsupportedMergeError, type ValidateResult, type VoiceLine, type VoiceScript, type VoicedCounts, type WebExport, type WrittenCounts, applyLoc, applySceneOrder, applyWrites, bundleOutputPath, catalogToJson, catalogToPo, catalogToXlsx, classesForChannel, defaultGameScopesDir, detectMergeType, discoverGameScopes, drivableScopes, extractLoc, findProjectFile, gameScopeTokens, gameScopesCatalogue, gameScopesSnapshot, hostScopeTokens, jsonToCatalog, listProjectTags, loadProject, loadProjectLanding, patterScopesFile, patterScopesStale, patterScopesWrite, planReturnedWorld, planShareScopes, planWorldSave, poToCatalog, previewRegistry, proposeCoverageDrivers, reachabilityIssues, readGameScopes, renderCoverageText, renderPlay, renderReportText, resolveDocumentation, resolveStart, runCoverage, runCoverageAsync, runExport, runExportFull, runExportHtml, runExportWeb, runFormat, runInit, runMerge, runPack, runPlay, runPropertyUsage, runReplace, runReport, runReportXlsx, runResolve, runScriptDoc, runSearch, runStatusBrowse, runTagBrowse, runUnpack, runUnpackMerge, runValidate, runVoiceScript, scanAudioStatus, sceneIdForShard, scriptToDocx, scriptToPdf, sidecarIssues, vcsConfigWrites, voiceScriptToXlsx, worldSettingsScopes, xlsxToCatalog };
|
|
1117
|
+
export { AUTHORING_HANDLED, type ApplyStats, type BundlePosture, CONFLICT_SIDECAR, type CharacterReport, type Conflict, type ConflictKind, type CoverageAsyncHooks, type CoverageBeat, type CoverageHooks, type CoverageOptions, type CoverageReport, type DocumentManifest, type FormatResult, GAME_SCOPES_OWNER, type GameScopes, type GameScopesIssue, type HygieneIssue, type InitOptions, type InitResult, type InitVcs, type LoadedProject, type LocCatalog, type LocEntry, type LocaleReport, type MergeFileType, type MergeResult, type MergedShard, PATTER_SCOPES_FILE, PATTER_SCOPES_OWNER, type PinPlan, type PinnedName, type PlannedWrite, type PlayEvent, type PlayOptions, type PlayOutcome, type PlayResult, type ProvenanceCheck, type ReplaceHit, type ReplaceOptions, type ReplacePlan, type ReportData, type ReportTotals, type ResolveEntry, SHARD_EXTENSIONS, type SceneReport, type ScriptDoc, type ScriptElement, type SearchFocus, type UnpackMergeResult, type UnpackResult, UnsafeEntryError, UnsupportedMergeError, type ValidateResult, type VoiceLine, type VoiceScript, type VoicedCounts, type WebExport, type WrittenCounts, applyLoc, applySceneOrder, applyWrites, bundleOutputPath, catalogToJson, catalogToPo, catalogToXlsx, classesForChannel, defaultGameScopesDir, detectMergeType, discoverGameScopes, drivableScopes, extractLoc, findProjectFile, gameScopeTokens, gameScopesCatalogue, gameScopesSnapshot, hostScopeTokens, jsonToCatalog, listProjectTags, loadProject, loadProjectLanding, patterScopesFile, patterScopesStale, patterScopesWrite, planPins, planReturnedWorld, planShareScopes, planWorldSave, poToCatalog, previewRegistry, proposeCoverageDrivers, reachabilityIssues, readGameScopes, renderCoverageText, renderPlay, renderReportText, resolveDocumentation, resolveStart, runCoverage, runCoverageAsync, runExport, runExportFull, runExportHtml, runExportWeb, runFormat, runInit, runMerge, runPack, runPlay, runPropertyUsage, runReplace, runReport, runReportXlsx, runResolve, runScriptDoc, runSearch, runStatusBrowse, runTagBrowse, runUnpack, runUnpackMerge, runValidate, runVoiceScript, scanAudioStatus, sceneIdForShard, scriptToDocx, scriptToPdf, sidecarIssues, vcsConfigWrites, voiceScriptToXlsx, worldSettingsScopes, xlsxToCatalog };
|
package/dist/index.js
CHANGED
|
@@ -211,18 +211,23 @@ function defaultGameScopesDir(root) {
|
|
|
211
211
|
}
|
|
212
212
|
function planShareScopes(root, project, dir) {
|
|
213
213
|
const target = resolve(dir);
|
|
214
|
-
const
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
214
|
+
const gamePath = join(target, GAME_SCOPES_FILE);
|
|
215
|
+
let existing = { version: 1, owner: GAME_SCOPES_OWNER, scopes: [] };
|
|
216
|
+
if (existsSync(gamePath)) {
|
|
217
|
+
const parsed = parseScopesFile(readFileSync(gamePath, "utf8"), GAME_SCOPES_FILE);
|
|
218
|
+
if (!parsed.file) return { error: `${GAME_SCOPES_FILE} in ${target} won't parse, so it was left alone: ${parsed.issues.map((i) => i.message).join("; ")}` };
|
|
219
|
+
existing = parsed.file;
|
|
220
|
+
}
|
|
221
|
+
const held = new Set(existing.scopes.map((s) => s.token));
|
|
222
|
+
const added = (project.scopeRegistry?.scopes ?? []).filter((h) => isGameToken(h.token, void 0) && !held.has(h.token)).map((h) => ({
|
|
223
|
+
token: h.token,
|
|
224
|
+
...h.writable !== void 0 ? { writable: h.writable } : {},
|
|
225
|
+
...h.declarations ? { declarations: h.declarations.map((d) => ({ ...d })) } : {}
|
|
226
|
+
}));
|
|
227
|
+
const game = { ...existing, scopes: [...existing.scopes, ...added] };
|
|
223
228
|
const writes = [
|
|
224
229
|
{ path: join(target, PATTER_SCOPES_FILE), content: serialiseScopesFile(patterScopesFile(project)) },
|
|
225
|
-
{ path:
|
|
230
|
+
{ path: gamePath, content: serialiseScopesFile(game) }
|
|
226
231
|
];
|
|
227
232
|
let found = false;
|
|
228
233
|
for (let at = resolve(root); ; ) {
|
|
@@ -3872,18 +3877,54 @@ function runReplace(loaded, opts) {
|
|
|
3872
3877
|
return plan;
|
|
3873
3878
|
}
|
|
3874
3879
|
|
|
3880
|
+
// src/pin.ts
|
|
3881
|
+
import { readFileSync as readFileSync5 } from "fs";
|
|
3882
|
+
import { canonicalStringify as canonicalStringify8, parseSource as parseSource4 } from "@patterkit/core";
|
|
3883
|
+
import { effectiveGameId as effectiveGameId2, gameIdify } from "@patterkit/model";
|
|
3884
|
+
function toPin(node) {
|
|
3885
|
+
if (node.gameId?.trim()) return void 0;
|
|
3886
|
+
if (!gameIdify(node.name)) return void 0;
|
|
3887
|
+
return effectiveGameId2(node);
|
|
3888
|
+
}
|
|
3889
|
+
function planPins(loaded) {
|
|
3890
|
+
const plan = { pinned: [], writes: [], scenes: [] };
|
|
3891
|
+
for (const scene of loaded.scenes) {
|
|
3892
|
+
const path = loaded.sceneFiles[scene.id];
|
|
3893
|
+
if (!path) continue;
|
|
3894
|
+
let changed = false;
|
|
3895
|
+
const sceneGameId = toPin(scene);
|
|
3896
|
+
if (sceneGameId !== void 0) {
|
|
3897
|
+
plan.pinned.push({ id: scene.id, kind: "scene", sceneId: scene.id, gameId: sceneGameId });
|
|
3898
|
+
changed = true;
|
|
3899
|
+
}
|
|
3900
|
+
const blocks = scene.blocks.map((block) => {
|
|
3901
|
+
const gameId = toPin(block);
|
|
3902
|
+
if (gameId === void 0) return block;
|
|
3903
|
+
plan.pinned.push({ id: block.id, kind: "block", sceneId: scene.id, gameId });
|
|
3904
|
+
changed = true;
|
|
3905
|
+
return { ...block, gameId };
|
|
3906
|
+
});
|
|
3907
|
+
if (!changed) continue;
|
|
3908
|
+
const next = { ...scene, ...sceneGameId !== void 0 ? { gameId: sceneGameId } : {}, blocks };
|
|
3909
|
+
const file = parseSource4(readFileSync5(path, "utf8"));
|
|
3910
|
+
plan.writes.push({ path, content: canonicalStringify8({ ...file, scene: next }) });
|
|
3911
|
+
plan.scenes.push(next);
|
|
3912
|
+
}
|
|
3913
|
+
return plan;
|
|
3914
|
+
}
|
|
3915
|
+
|
|
3875
3916
|
// src/pack.ts
|
|
3876
3917
|
import JSZip from "jszip";
|
|
3877
|
-
import { readFileSync as
|
|
3918
|
+
import { readFileSync as readFileSync6 } from "fs";
|
|
3878
3919
|
import { dirname as dirname5, relative as relative3, sep as sep2 } from "path";
|
|
3879
|
-
import { parseSource as
|
|
3920
|
+
import { parseSource as parseSource5 } from "@patterkit/core";
|
|
3880
3921
|
import { ARCHIVE_ENTRY_OPTS } from "@wildwinter/toolkit/archive";
|
|
3881
3922
|
var SHARD_EXTENSIONS = [".patterflow", ".patterloc", ".patterx", ".patterproj"];
|
|
3882
3923
|
var ENTRY_OPTS = ARCHIVE_ENTRY_OPTS;
|
|
3883
3924
|
async function runPack(startPath) {
|
|
3884
3925
|
const projectFile = findProjectFile(startPath);
|
|
3885
3926
|
const root = dirname5(projectFile);
|
|
3886
|
-
const project =
|
|
3927
|
+
const project = parseSource5(readFileSync6(projectFile, "utf8"));
|
|
3887
3928
|
const unresolved = sidecarIssues(walkFiles(root, CONFLICT_SIDECAR));
|
|
3888
3929
|
if (unresolved.length) {
|
|
3889
3930
|
throw new Error(
|
|
@@ -3901,7 +3942,7 @@ async function runPack(startPath) {
|
|
|
3901
3942
|
};
|
|
3902
3943
|
const zip = new JSZip();
|
|
3903
3944
|
zip.file("patter.manifest.json", JSON.stringify(manifest, null, 2) + "\n", ENTRY_OPTS);
|
|
3904
|
-
for (const f of files) zip.file(f.rel,
|
|
3945
|
+
for (const f of files) zip.file(f.rel, readFileSync6(f.abs, "utf8"), ENTRY_OPTS);
|
|
3905
3946
|
for (const f of scopes) zip.file(`${GAME_SCOPES_DIR}/${f.fileName}`, f.text, ENTRY_OPTS);
|
|
3906
3947
|
return zip.generateAsync({ type: "nodebuffer", compression: "DEFLATE", streamFiles: false });
|
|
3907
3948
|
}
|
|
@@ -3909,8 +3950,8 @@ async function runPack(startPath) {
|
|
|
3909
3950
|
// src/unpack.ts
|
|
3910
3951
|
import JSZip2 from "jszip";
|
|
3911
3952
|
import { join as join7, resolve as resolve5, sep as sep3 } from "path";
|
|
3912
|
-
import { existsSync as existsSync4, readFileSync as
|
|
3913
|
-
import { parseSource as
|
|
3953
|
+
import { existsSync as existsSync4, readFileSync as readFileSync7 } from "fs";
|
|
3954
|
+
import { parseSource as parseSource6, canonicalStringify as canonicalStringify9 } from "@patterkit/core";
|
|
3914
3955
|
import { isUnsafeEntry } from "@wildwinter/toolkit/archive";
|
|
3915
3956
|
import { SCOPES_FILE_SUFFIX as SCOPES_FILE_SUFFIX2 } from "@wildwinter/scoperegistry/scopes";
|
|
3916
3957
|
import { isUnsafeEntry as isUnsafeEntry2 } from "@wildwinter/toolkit/archive";
|
|
@@ -3956,7 +3997,7 @@ function checkProvenance(returned, base, target) {
|
|
|
3956
3997
|
}
|
|
3957
3998
|
function targetProjectId(projectDir) {
|
|
3958
3999
|
try {
|
|
3959
|
-
const pf =
|
|
4000
|
+
const pf = parseSource6(readFileSync7(findProjectFile(projectDir), "utf8"));
|
|
3960
4001
|
return pf.project?.id;
|
|
3961
4002
|
} catch {
|
|
3962
4003
|
return void 0;
|
|
@@ -3983,17 +4024,17 @@ async function runUnpackMerge(returnedBytes, baseBytes, projectDir) {
|
|
|
3983
4024
|
}
|
|
3984
4025
|
const readSide = (side, text) => {
|
|
3985
4026
|
try {
|
|
3986
|
-
return
|
|
4027
|
+
return parseSource6(text);
|
|
3987
4028
|
} catch (e) {
|
|
3988
4029
|
throw new Error(`${rel}: the ${side} copy is not readable Patter source - ${e instanceof Error ? e.message : String(e)}`);
|
|
3989
4030
|
}
|
|
3990
4031
|
};
|
|
3991
|
-
const oursObj = readSide("ours",
|
|
4032
|
+
const oursObj = readSide("ours", readFileSync7(outPath, "utf8"));
|
|
3992
4033
|
const theirsObj = readSide("theirs", theirText);
|
|
3993
4034
|
const baseText = base.get(rel);
|
|
3994
4035
|
const baseObj = baseText !== void 0 ? readSide("base", baseText) : {};
|
|
3995
4036
|
const result = runMerge(baseObj, oursObj, theirsObj);
|
|
3996
|
-
writes.push({ path: outPath, content:
|
|
4037
|
+
writes.push({ path: outPath, content: canonicalStringify9(result.merged) });
|
|
3997
4038
|
if (rel === projectRel && baseText !== void 0) {
|
|
3998
4039
|
projectSides = { ours: oursObj, base: baseObj, theirs: theirsObj, merged: result.merged };
|
|
3999
4040
|
}
|
|
@@ -4064,6 +4105,7 @@ export {
|
|
|
4064
4105
|
patterScopesFile,
|
|
4065
4106
|
patterScopesStale,
|
|
4066
4107
|
patterScopesWrite,
|
|
4108
|
+
planPins,
|
|
4067
4109
|
planReturnedWorld,
|
|
4068
4110
|
planShareScopes,
|
|
4069
4111
|
planWorldSave,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@patterkit/ops",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "The shared operations layer: every project operation (load, validate, export, format, play, ...) as a pure function, consumed by the patter CLI and Patterpad alike.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|