knitto 0.0.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.
Files changed (87) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +869 -0
  3. package/dist/src/checks/run.d.ts +3 -0
  4. package/dist/src/checks/run.js +173 -0
  5. package/dist/src/checks/run.js.map +1 -0
  6. package/dist/src/cli.d.ts +2 -0
  7. package/dist/src/cli.js +406 -0
  8. package/dist/src/cli.js.map +1 -0
  9. package/dist/src/config.d.ts +11 -0
  10. package/dist/src/config.js +585 -0
  11. package/dist/src/config.js.map +1 -0
  12. package/dist/src/context/build.d.ts +2 -0
  13. package/dist/src/context/build.js +147 -0
  14. package/dist/src/context/build.js.map +1 -0
  15. package/dist/src/context/render.d.ts +7 -0
  16. package/dist/src/context/render.js +74 -0
  17. package/dist/src/context/render.js.map +1 -0
  18. package/dist/src/engine/apply.d.ts +2 -0
  19. package/dist/src/engine/apply.js +96 -0
  20. package/dist/src/engine/apply.js.map +1 -0
  21. package/dist/src/engine/diff.d.ts +2 -0
  22. package/dist/src/engine/diff.js +100 -0
  23. package/dist/src/engine/diff.js.map +1 -0
  24. package/dist/src/engine/plan.d.ts +2 -0
  25. package/dist/src/engine/plan.js +259 -0
  26. package/dist/src/engine/plan.js.map +1 -0
  27. package/dist/src/errors.d.ts +14 -0
  28. package/dist/src/errors.js +31 -0
  29. package/dist/src/errors.js.map +1 -0
  30. package/dist/src/filesystem/paths.d.ts +2 -0
  31. package/dist/src/filesystem/paths.js +47 -0
  32. package/dist/src/filesystem/paths.js.map +1 -0
  33. package/dist/src/hooks/run.d.ts +10 -0
  34. package/dist/src/hooks/run.js +105 -0
  35. package/dist/src/hooks/run.js.map +1 -0
  36. package/dist/src/index.d.ts +7 -0
  37. package/dist/src/index.js +7 -0
  38. package/dist/src/index.js.map +1 -0
  39. package/dist/src/lock.d.ts +2 -0
  40. package/dist/src/lock.js +16 -0
  41. package/dist/src/lock.js.map +1 -0
  42. package/dist/src/onboarding.d.ts +26 -0
  43. package/dist/src/onboarding.js +212 -0
  44. package/dist/src/onboarding.js.map +1 -0
  45. package/dist/src/parsers/index.d.ts +18 -0
  46. package/dist/src/parsers/index.js +194 -0
  47. package/dist/src/parsers/index.js.map +1 -0
  48. package/dist/src/parsers/json.d.ts +17 -0
  49. package/dist/src/parsers/json.js +214 -0
  50. package/dist/src/parsers/json.js.map +1 -0
  51. package/dist/src/parsers/merge.d.ts +1 -0
  52. package/dist/src/parsers/merge.js +17 -0
  53. package/dist/src/parsers/merge.js.map +1 -0
  54. package/dist/src/project/discover.d.ts +2 -0
  55. package/dist/src/project/discover.js +144 -0
  56. package/dist/src/project/discover.js.map +1 -0
  57. package/dist/src/rules/json-pointer.d.ts +3 -0
  58. package/dist/src/rules/json-pointer.js +114 -0
  59. package/dist/src/rules/json-pointer.js.map +1 -0
  60. package/dist/src/snapshots/canonical.d.ts +11 -0
  61. package/dist/src/snapshots/canonical.js +150 -0
  62. package/dist/src/snapshots/canonical.js.map +1 -0
  63. package/dist/src/sources/process.d.ts +3 -0
  64. package/dist/src/sources/process.js +28 -0
  65. package/dist/src/sources/process.js.map +1 -0
  66. package/dist/src/sources/resolve.d.ts +3 -0
  67. package/dist/src/sources/resolve.js +144 -0
  68. package/dist/src/sources/resolve.js.map +1 -0
  69. package/dist/src/template/init.d.ts +1 -0
  70. package/dist/src/template/init.js +62 -0
  71. package/dist/src/template/init.js.map +1 -0
  72. package/dist/src/template/manifest.d.ts +2 -0
  73. package/dist/src/template/manifest.js +80 -0
  74. package/dist/src/template/manifest.js.map +1 -0
  75. package/dist/src/template/release.d.ts +3 -0
  76. package/dist/src/template/release.js +8 -0
  77. package/dist/src/template/release.js.map +1 -0
  78. package/dist/src/template/validate.d.ts +2 -0
  79. package/dist/src/template/validate.js +62 -0
  80. package/dist/src/template/validate.js.map +1 -0
  81. package/dist/src/types.d.ts +242 -0
  82. package/dist/src/types.js +4 -0
  83. package/dist/src/types.js.map +1 -0
  84. package/dist/src/version.d.ts +2 -0
  85. package/dist/src/version.js +3 -0
  86. package/dist/src/version.js.map +1 -0
  87. package/package.json +51 -0
@@ -0,0 +1,214 @@
1
+ import { Ajv2020 } from "ajv/dist/2020.js";
2
+ import jsonPatch from "fast-json-patch";
3
+ import { DELETE_SENTINEL } from "../context/render.js";
4
+ import { setPointer } from "../rules/json-pointer.js";
5
+ import { deletePointer, getPointer } from "../rules/json-pointer.js";
6
+ const REMOVE = Symbol("remove");
7
+ function isRecord(value) {
8
+ return typeof value === "object" && value !== null && !Array.isArray(value);
9
+ }
10
+ function clone(value) {
11
+ return value === undefined ? undefined : structuredClone(value);
12
+ }
13
+ function escapePointer(value) {
14
+ return value.replaceAll("~", "~0").replaceAll("/", "~1");
15
+ }
16
+ function childPointer(pointer, key) {
17
+ return `${pointer}/${escapePointer(key)}`;
18
+ }
19
+ function isExcluded(pointer, exclusions) {
20
+ return exclusions.some((excluded) => pointer === excluded || pointer.startsWith(`${excluded}/`));
21
+ }
22
+ function mergeDesired(current, desired) {
23
+ if (desired === DELETE_SENTINEL)
24
+ return REMOVE;
25
+ if (desired === undefined)
26
+ return clone(current);
27
+ if (Array.isArray(desired)) {
28
+ return desired.flatMap((value) => {
29
+ const merged = mergeDesired(undefined, value);
30
+ return merged === REMOVE ? [] : [merged];
31
+ });
32
+ }
33
+ if (!isRecord(desired))
34
+ return clone(desired);
35
+ const output = isRecord(current)
36
+ ? structuredClone(current)
37
+ : {};
38
+ for (const [key, value] of Object.entries(desired)) {
39
+ const merged = mergeDesired(output[key], value);
40
+ if (merged === REMOVE)
41
+ delete output[key];
42
+ else
43
+ output[key] = merged;
44
+ }
45
+ return output;
46
+ }
47
+ function matchingSchema(key, patterns) {
48
+ for (const [pattern, schema] of Object.entries(patterns)) {
49
+ if (new RegExp(pattern).test(key))
50
+ return schema;
51
+ }
52
+ return undefined;
53
+ }
54
+ function reconcileNode(current, desired, schema, pointer, exclusions) {
55
+ if (isExcluded(pointer, exclusions))
56
+ return clone(current);
57
+ if (schema === false)
58
+ return REMOVE;
59
+ const merged = mergeDesired(current, desired);
60
+ if (merged === REMOVE)
61
+ return REMOVE;
62
+ if (schema === true || !isRecord(schema))
63
+ return merged;
64
+ if ("const" in schema)
65
+ return clone(schema.const);
66
+ if (merged === undefined && "default" in schema)
67
+ return clone(schema.default);
68
+ const objectSchema = schema.type === "object" ||
69
+ isRecord(schema.properties) ||
70
+ isRecord(schema.patternProperties);
71
+ if (objectSchema) {
72
+ const output = isRecord(merged)
73
+ ? structuredClone(merged)
74
+ : {};
75
+ const desiredRecord = isRecord(desired) ? desired : {};
76
+ const currentRecord = isRecord(current) ? current : {};
77
+ const properties = isRecord(schema.properties) ? schema.properties : {};
78
+ const patterns = isRecord(schema.patternProperties)
79
+ ? schema.patternProperties
80
+ : {};
81
+ for (const [key, propertySchema] of Object.entries(properties)) {
82
+ if (!(key in output) && !(key in desiredRecord))
83
+ continue;
84
+ const reconciled = reconcileNode(currentRecord[key], desiredRecord[key], propertySchema, childPointer(pointer, key), exclusions);
85
+ if (reconciled === REMOVE)
86
+ delete output[key];
87
+ else
88
+ output[key] = reconciled;
89
+ }
90
+ for (const key of Object.keys(output)) {
91
+ if (key in properties)
92
+ continue;
93
+ const patternSchema = matchingSchema(key, patterns);
94
+ if (patternSchema !== undefined) {
95
+ const reconciled = reconcileNode(currentRecord[key], desiredRecord[key], patternSchema, childPointer(pointer, key), exclusions);
96
+ if (reconciled === REMOVE)
97
+ delete output[key];
98
+ else
99
+ output[key] = reconciled;
100
+ continue;
101
+ }
102
+ const additional = schema.unevaluatedProperties ?? schema.additionalProperties;
103
+ if (additional === false &&
104
+ !isExcluded(childPointer(pointer, key), exclusions)) {
105
+ delete output[key];
106
+ }
107
+ else if (isRecord(additional) || additional === true) {
108
+ const reconciled = reconcileNode(currentRecord[key], desiredRecord[key], additional, childPointer(pointer, key), exclusions);
109
+ if (reconciled === REMOVE)
110
+ delete output[key];
111
+ else
112
+ output[key] = reconciled;
113
+ }
114
+ }
115
+ for (const required of Array.isArray(schema.required)
116
+ ? schema.required.filter((entry) => typeof entry === "string")
117
+ : []) {
118
+ if (required in output)
119
+ continue;
120
+ const propertySchema = properties[required];
121
+ if (!isRecord(propertySchema))
122
+ continue;
123
+ if ("const" in propertySchema)
124
+ output[required] = clone(propertySchema.const);
125
+ else if ("default" in propertySchema) {
126
+ output[required] = clone(propertySchema.default);
127
+ }
128
+ }
129
+ return output;
130
+ }
131
+ if ((schema.type === "array" || "items" in schema) &&
132
+ Array.isArray(merged) &&
133
+ schema.items !== undefined) {
134
+ return merged.flatMap((value, index) => {
135
+ const reconciled = reconcileNode(Array.isArray(current) ? current[index] : undefined, Array.isArray(desired) ? desired[index] : value, schema.items, childPointer(pointer, String(index)), exclusions);
136
+ return reconciled === REMOVE ? [] : [reconciled];
137
+ });
138
+ }
139
+ return merged;
140
+ }
141
+ function errorPointer(error) {
142
+ if (error.keyword === "additionalProperties" &&
143
+ typeof error.params.additionalProperty === "string") {
144
+ return childPointer(error.instancePath, error.params.additionalProperty);
145
+ }
146
+ if (error.keyword === "required" &&
147
+ typeof error.params.missingProperty === "string") {
148
+ return childPointer(error.instancePath, error.params.missingProperty);
149
+ }
150
+ return error.instancePath;
151
+ }
152
+ function filterExcludedErrors(errors, exclusions) {
153
+ return (errors ?? []).filter((error) => !isExcluded(errorPointer(error), exclusions));
154
+ }
155
+ function toPatchOperations(current, value) {
156
+ const left = isRecord(current) || Array.isArray(current) ? current : {};
157
+ const right = isRecord(value) || Array.isArray(value) ? value : {};
158
+ return jsonPatch
159
+ .compare(left, right)
160
+ .filter((operation) => operation.op !== "_get")
161
+ .map((operation) => ({
162
+ op: operation.op,
163
+ path: operation.path,
164
+ ...("from" in operation ? { from: operation.from } : {}),
165
+ ...("value" in operation ? { value: operation.value } : {}),
166
+ }));
167
+ }
168
+ export function prepareJson(options) {
169
+ const exclusions = options.excludedPointers ?? [];
170
+ const hasSchema = options.schema !== undefined;
171
+ const ajv = new Ajv2020({ allErrors: true, strict: false });
172
+ let validate = null;
173
+ if (options.schema !== undefined) {
174
+ const schema = options.schema;
175
+ if (typeof schema !== "boolean" && !isRecord(schema)) {
176
+ throw new TypeError("JSON Schema must be an object or boolean");
177
+ }
178
+ validate = ajv.compile(schema);
179
+ }
180
+ validate?.(options.current);
181
+ const violations = filterExcludedErrors(validate?.errors, exclusions);
182
+ let value = hasSchema
183
+ ? reconcileNode(options.current, options.desired, options.schema, "", exclusions)
184
+ : mergeDesired(options.current, options.desired);
185
+ if (value === REMOVE)
186
+ value = {};
187
+ for (const pointer of options.exactPointers ?? []) {
188
+ if (isExcluded(pointer, exclusions))
189
+ continue;
190
+ const desired = getPointer(options.desired, pointer);
191
+ value =
192
+ pointer === ""
193
+ ? clone(desired)
194
+ : desired === DELETE_SENTINEL
195
+ ? deletePointer(value, pointer)
196
+ : desired === undefined
197
+ ? value
198
+ : setPointer(value, pointer, desired);
199
+ }
200
+ if (options.overrides) {
201
+ for (const [pointer, override] of Object.entries(options.overrides)) {
202
+ value = setPointer(value, pointer, override);
203
+ }
204
+ }
205
+ validate?.(value);
206
+ const unfixable = filterExcludedErrors(validate?.errors, exclusions);
207
+ return {
208
+ value,
209
+ patch: toPatchOperations(options.current, value),
210
+ violations,
211
+ unfixable,
212
+ };
213
+ }
214
+ //# sourceMappingURL=json.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json.js","sourceRoot":"","sources":["../../../src/parsers/json.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export declare function mergeDocuments(target: unknown, source: unknown): unknown;
@@ -0,0 +1,17 @@
1
+ function isRecord(value) {
2
+ return typeof value === "object" && value !== null && !Array.isArray(value);
3
+ }
4
+ export function mergeDocuments(target, source) {
5
+ if (Array.isArray(source))
6
+ return structuredClone(source);
7
+ if (!isRecord(source))
8
+ return structuredClone(source);
9
+ const output = isRecord(target)
10
+ ? structuredClone(target)
11
+ : {};
12
+ for (const [key, value] of Object.entries(source)) {
13
+ output[key] = mergeDocuments(output[key], value);
14
+ }
15
+ return output;
16
+ }
17
+ //# sourceMappingURL=merge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge.js","sourceRoot":"","sources":["../../../src/parsers/merge.ts"],"names":[],"mappings":"AAAA,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,MAAe,EAAE,MAAe;IAC7D,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;QAAE,OAAO,eAAe,CAAC,MAAM,CAAC,CAAC;IAC1D,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,eAAe,CAAC,MAAM,CAAC,CAAC;IAEtD,MAAM,MAAM,GAA4B,QAAQ,CAAC,MAAM,CAAC;QACtD,CAAC,CAAC,eAAe,CAAC,MAAM,CAAC;QACzB,CAAC,CAAC,EAAE,CAAC;IACP,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,MAAM,CAAC,GAAG,CAAC,GAAG,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC;IACnD,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { ProjectConfig, ProjectUnit } from "../types.js";
2
+ export declare function discoverProjectUnits(repositoryRoot: string, projectConfig: ProjectConfig): Promise<ProjectUnit[]>;
@@ -0,0 +1,144 @@
1
+ import path from "node:path";
2
+ import { readFile } from "node:fs/promises";
3
+ import { glob } from "glob";
4
+ import { validateProjectConfig } from "../config.js";
5
+ import { KnittoError } from "../errors.js";
6
+ function isRecord(value) {
7
+ return typeof value === "object" && value !== null && !Array.isArray(value);
8
+ }
9
+ async function readPackageJson(directory) {
10
+ try {
11
+ const value = JSON.parse(await readFile(path.join(directory, "package.json"), "utf8"));
12
+ if (!isRecord(value)) {
13
+ throw new KnittoError(`package.json must contain an object: ${directory}`, "CONFIG");
14
+ }
15
+ return value;
16
+ }
17
+ catch (error) {
18
+ if (typeof error === "object" &&
19
+ error !== null &&
20
+ "code" in error &&
21
+ error.code === "ENOENT") {
22
+ return {};
23
+ }
24
+ if (error instanceof KnittoError)
25
+ throw error;
26
+ throw new KnittoError(`Unable to read package.json: ${directory}`, "CONFIG", {
27
+ cause: error,
28
+ });
29
+ }
30
+ }
31
+ function workspacePatterns(packageJson) {
32
+ const value = packageJson.workspaces;
33
+ if (Array.isArray(value)) {
34
+ return value.filter((entry) => typeof entry === "string");
35
+ }
36
+ if (isRecord(value) && Array.isArray(value.packages)) {
37
+ return value.packages.filter((entry) => typeof entry === "string");
38
+ }
39
+ return [];
40
+ }
41
+ function mergeConfig(base, overlayValue) {
42
+ if (overlayValue === undefined)
43
+ return base;
44
+ if (!isRecord(overlayValue)) {
45
+ throw new KnittoError("package.json#knitto must be an object", "CONFIG");
46
+ }
47
+ const { source: _ignoredSource, ...overlayWithoutSource } = overlayValue;
48
+ const overlay = validateProjectConfig({
49
+ ...overlayWithoutSource,
50
+ source: base.source,
51
+ });
52
+ const pointerExclusions = {
53
+ ...(base.exclude?.pointers ?? {}),
54
+ };
55
+ for (const [ruleId, pointers] of Object.entries(overlay.exclude?.pointers ?? {})) {
56
+ pointerExclusions[ruleId] = [
57
+ ...new Set([...(pointerExclusions[ruleId] ?? []), ...pointers]),
58
+ ];
59
+ }
60
+ const overrides = {
61
+ ...(base.overrides ?? {}),
62
+ };
63
+ for (const [ruleId, values] of Object.entries(overlay.overrides ?? {})) {
64
+ overrides[ruleId] = {
65
+ ...(overrides[ruleId] ?? {}),
66
+ ...values,
67
+ };
68
+ }
69
+ return {
70
+ source: base.source,
71
+ metadata: {
72
+ ...(base.metadata ?? {}),
73
+ ...(overlay.metadata ?? {}),
74
+ },
75
+ variables: {
76
+ ...(base.variables ?? {}),
77
+ ...(overlay.variables ?? {}),
78
+ },
79
+ exclude: {
80
+ rules: [
81
+ ...new Set([
82
+ ...(base.exclude?.rules ?? []),
83
+ ...(overlay.exclude?.rules ?? []),
84
+ ]),
85
+ ],
86
+ checks: [
87
+ ...new Set([
88
+ ...(base.exclude?.checks ?? []),
89
+ ...(overlay.exclude?.checks ?? []),
90
+ ]),
91
+ ],
92
+ pointers: pointerExclusions,
93
+ },
94
+ overrides,
95
+ ...(base.trust ? { trust: base.trust } : {}),
96
+ };
97
+ }
98
+ export async function discoverProjectUnits(repositoryRoot, projectConfig) {
99
+ const root = path.resolve(repositoryRoot);
100
+ const rootPackage = await readPackageJson(root);
101
+ const rootConfig = mergeConfig(projectConfig, rootPackage.knitto);
102
+ const patterns = workspacePatterns(rootPackage);
103
+ const workspacePackageFiles = patterns.length
104
+ ? await glob(patterns.map((pattern) => `${pattern.replace(/\/+$/, "")}/package.json`), {
105
+ cwd: root,
106
+ absolute: true,
107
+ dot: false,
108
+ nodir: true,
109
+ ignore: ["**/node_modules/**", "**/.git/**"],
110
+ })
111
+ : [];
112
+ const workspaceDirectories = workspacePackageFiles.map((file) => path.dirname(file));
113
+ const workspacePaths = [];
114
+ const workspacePackages = [];
115
+ for (const directory of [...new Set(workspaceDirectories)].sort()) {
116
+ const packageJson = await readPackageJson(directory);
117
+ if (Object.keys(packageJson).length === 0)
118
+ continue;
119
+ const relativePath = path.relative(root, directory).split(path.sep).join("/");
120
+ workspacePaths.push(relativePath);
121
+ workspacePackages.push({ path: directory, relativePath, packageJson });
122
+ }
123
+ return [
124
+ {
125
+ repositoryRoot: root,
126
+ path: root,
127
+ relativePath: ".",
128
+ packageJson: rootPackage,
129
+ config: rootConfig,
130
+ isRoot: true,
131
+ workspacePaths,
132
+ },
133
+ ...workspacePackages.map((workspace) => ({
134
+ repositoryRoot: root,
135
+ path: workspace.path,
136
+ relativePath: workspace.relativePath,
137
+ packageJson: workspace.packageJson,
138
+ config: mergeConfig(rootConfig, workspace.packageJson.knitto),
139
+ isRoot: false,
140
+ workspacePaths,
141
+ })),
142
+ ];
143
+ }
144
+ //# sourceMappingURL=discover.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discover.js","sourceRoot":"","sources":["../../../src/project/discover.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare function getPointer(document: unknown, pointer: string): unknown;
2
+ export declare function setPointer(document: unknown, pointer: string, value: unknown): unknown;
3
+ export declare function deletePointer(document: unknown, pointer: string): unknown;
@@ -0,0 +1,114 @@
1
+ import { KnittoError } from "../errors.js";
2
+ function tokens(pointer) {
3
+ if (pointer === "")
4
+ return [];
5
+ if (!pointer.startsWith("/")) {
6
+ throw new KnittoError(`Invalid JSON Pointer: ${pointer}`, "TEMPLATE");
7
+ }
8
+ return pointer
9
+ .slice(1)
10
+ .split("/")
11
+ .map((token) => token.replaceAll("~1", "/").replaceAll("~0", "~"));
12
+ }
13
+ function indexFor(token, length) {
14
+ if (!/^(0|[1-9]\d*)$/.test(token)) {
15
+ throw new KnittoError(`Invalid array index in JSON Pointer: ${token}`, "TEMPLATE");
16
+ }
17
+ const index = Number(token);
18
+ if (!Number.isSafeInteger(index) || index > length) {
19
+ throw new KnittoError(`Array index is out of range: ${token}`, "TEMPLATE");
20
+ }
21
+ return index;
22
+ }
23
+ export function getPointer(document, pointer) {
24
+ let current = document;
25
+ for (const token of tokens(pointer)) {
26
+ if (Array.isArray(current)) {
27
+ current = current[indexFor(token, current.length)];
28
+ }
29
+ else if (typeof current === "object" && current !== null) {
30
+ current = current[token];
31
+ }
32
+ else {
33
+ return undefined;
34
+ }
35
+ }
36
+ return current;
37
+ }
38
+ export function setPointer(document, pointer, value) {
39
+ const parts = tokens(pointer);
40
+ if (parts.length === 0)
41
+ return structuredClone(value);
42
+ const root = typeof document === "object" && document !== null
43
+ ? structuredClone(document)
44
+ : {};
45
+ let current = root;
46
+ for (let index = 0; index < parts.length; index += 1) {
47
+ const token = parts[index];
48
+ if (token === undefined)
49
+ continue;
50
+ const last = index === parts.length - 1;
51
+ const nextToken = parts[index + 1];
52
+ const nextShouldBeArray = nextToken !== undefined && /^(0|[1-9]\d*)$/.test(nextToken);
53
+ if (Array.isArray(current)) {
54
+ const arrayIndex = indexFor(token, current.length);
55
+ if (last) {
56
+ current[arrayIndex] = structuredClone(value);
57
+ }
58
+ else {
59
+ current[arrayIndex] ??= nextShouldBeArray ? [] : {};
60
+ current = current[arrayIndex];
61
+ }
62
+ continue;
63
+ }
64
+ if (typeof current !== "object" || current === null) {
65
+ throw new KnittoError(`Cannot traverse scalar value at JSON Pointer: ${pointer}`, "TEMPLATE");
66
+ }
67
+ const record = current;
68
+ if (last) {
69
+ record[token] = structuredClone(value);
70
+ }
71
+ else {
72
+ record[token] ??= nextShouldBeArray ? [] : {};
73
+ current = record[token];
74
+ }
75
+ }
76
+ return root;
77
+ }
78
+ export function deletePointer(document, pointer) {
79
+ const parts = tokens(pointer);
80
+ if (parts.length === 0)
81
+ return undefined;
82
+ const root = typeof document === "object" && document !== null
83
+ ? structuredClone(document)
84
+ : {};
85
+ let current = root;
86
+ for (let index = 0; index < parts.length - 1; index += 1) {
87
+ const token = parts[index];
88
+ if (token === undefined)
89
+ return root;
90
+ if (Array.isArray(current)) {
91
+ current = current[indexFor(token, current.length)];
92
+ }
93
+ else if (typeof current === "object" && current !== null) {
94
+ current = current[token];
95
+ }
96
+ else {
97
+ return root;
98
+ }
99
+ if (current === undefined)
100
+ return root;
101
+ }
102
+ const finalToken = parts.at(-1);
103
+ if (finalToken === undefined)
104
+ return root;
105
+ if (Array.isArray(current)) {
106
+ const index = indexFor(finalToken, current.length);
107
+ current.splice(index, 1);
108
+ }
109
+ else if (typeof current === "object" && current !== null) {
110
+ delete current[finalToken];
111
+ }
112
+ return root;
113
+ }
114
+ //# sourceMappingURL=json-pointer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json-pointer.js","sourceRoot":"","sources":["../../../src/rules/json-pointer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { SnapshotProvenance } from "../types.js";
2
+ export declare function digestDirectory(root: string): Promise<string>;
3
+ export declare function cacheRoot(): string;
4
+ export declare function cachePath(digest: string): string;
5
+ export declare function cacheSnapshot(sourceDirectory: string, digest: string): Promise<string>;
6
+ export declare function loadCachedSnapshot(digest: string, provenance: SnapshotProvenance): Promise<{
7
+ digest: string;
8
+ directory: string;
9
+ manifest: import("../types.js").TemplateManifest;
10
+ provenance: SnapshotProvenance;
11
+ } | null>;