@valbuild/core 0.26.0 → 0.27.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/package.json +12 -3
- package/CHANGELOG.md +0 -0
- package/ROADMAP.md +0 -106
- package/jest.config.js +0 -4
- package/src/Json.ts +0 -4
- package/src/ValApi.ts +0 -81
- package/src/expr/README.md +0 -193
- package/src/expr/eval.test.ts +0 -198
- package/src/expr/eval.ts +0 -251
- package/src/expr/expr.ts +0 -91
- package/src/expr/index.ts +0 -3
- package/src/expr/parser.test.ts +0 -158
- package/src/expr/parser.ts +0 -229
- package/src/expr/repl.ts +0 -88
- package/src/expr/tokenizer.test.ts +0 -539
- package/src/expr/tokenizer.ts +0 -117
- package/src/fp/array.ts +0 -30
- package/src/fp/index.ts +0 -3
- package/src/fp/result.ts +0 -214
- package/src/fp/util.ts +0 -52
- package/src/future/fetchVal.test.ts +0 -164
- package/src/future/fetchVal.ts +0 -206
- package/src/getSha256.ts +0 -8
- package/src/index.ts +0 -132
- package/src/initSchema.ts +0 -50
- package/src/initVal.ts +0 -73
- package/src/module.test.ts +0 -170
- package/src/module.ts +0 -397
- package/src/patch/deref.test.ts +0 -298
- package/src/patch/deref.ts +0 -136
- package/src/patch/index.ts +0 -12
- package/src/patch/json.test.ts +0 -582
- package/src/patch/json.ts +0 -304
- package/src/patch/operation.ts +0 -86
- package/src/patch/ops.ts +0 -83
- package/src/patch/parse.test.ts +0 -202
- package/src/patch/parse.ts +0 -202
- package/src/patch/patch.ts +0 -49
- package/src/patch/util.ts +0 -74
- package/src/schema/array.ts +0 -93
- package/src/schema/boolean.ts +0 -49
- package/src/schema/future/i18n.ts +0 -69
- package/src/schema/future/oneOf.ts +0 -63
- package/src/schema/image.ts +0 -137
- package/src/schema/index.ts +0 -70
- package/src/schema/keyOf.ts +0 -167
- package/src/schema/literal.ts +0 -63
- package/src/schema/number.ts +0 -56
- package/src/schema/object.ts +0 -110
- package/src/schema/record.ts +0 -103
- package/src/schema/richtext.ts +0 -44
- package/src/schema/string.ts +0 -95
- package/src/schema/union.ts +0 -63
- package/src/schema/validation/ValidationError.ts +0 -16
- package/src/schema/validation/ValidationFix.ts +0 -6
- package/src/schema/validation.test.ts +0 -291
- package/src/selector/SelectorProxy.ts +0 -238
- package/src/selector/array.ts +0 -13
- package/src/selector/boolean.ts +0 -4
- package/src/selector/file.ts +0 -6
- package/src/selector/future/ExprProxy.test.ts +0 -203
- package/src/selector/future/ExprProxy.ts +0 -216
- package/src/selector/future/SelectorProxy.test.ts +0 -172
- package/src/selector/future/SelectorProxy.ts +0 -238
- package/src/selector/future/array.ts +0 -37
- package/src/selector/future/boolean.ts +0 -4
- package/src/selector/future/file.ts +0 -14
- package/src/selector/future/i18n.ts +0 -13
- package/src/selector/future/index.ts +0 -169
- package/src/selector/future/number.ts +0 -4
- package/src/selector/future/object.ts +0 -22
- package/src/selector/future/primitive.ts +0 -17
- package/src/selector/future/remote.ts +0 -9
- package/src/selector/future/selector.test.ts +0 -429
- package/src/selector/future/selectorOf.ts +0 -7
- package/src/selector/future/string.ts +0 -4
- package/src/selector/index.ts +0 -121
- package/src/selector/number.ts +0 -4
- package/src/selector/object.ts +0 -5
- package/src/selector/primitive.ts +0 -4
- package/src/selector/string.ts +0 -4
- package/src/source/file.ts +0 -45
- package/src/source/future/i18n.ts +0 -60
- package/src/source/future/remote.ts +0 -54
- package/src/source/index.ts +0 -53
- package/src/source/link.ts +0 -14
- package/src/source/richtext.ts +0 -178
- package/src/val/array.ts +0 -10
- package/src/val/index.ts +0 -100
- package/src/val/object.ts +0 -13
- package/src/val/primitive.ts +0 -8
- package/tsconfig.json +0 -8
package/src/module.ts
DELETED
@@ -1,397 +0,0 @@
|
|
1
|
-
import { Schema, SchemaTypeOf, SerializedSchema } from "./schema";
|
2
|
-
import { ObjectSchema, SerializedObjectSchema } from "./schema/object";
|
3
|
-
import {
|
4
|
-
GenericSelector,
|
5
|
-
SelectorOf,
|
6
|
-
SelectorSource,
|
7
|
-
GetSource,
|
8
|
-
GetSchema,
|
9
|
-
Path,
|
10
|
-
} from "./selector";
|
11
|
-
import { Source } from "./source";
|
12
|
-
import { ModuleId, ModulePath, SourcePath } from "./val";
|
13
|
-
import { Expr } from "./expr";
|
14
|
-
import { ArraySchema, SerializedArraySchema } from "./schema/array";
|
15
|
-
import { UnionSchema, SerializedUnionSchema } from "./schema/union";
|
16
|
-
import { Json } from "./Json";
|
17
|
-
import { RichTextSchema, SerializedRichTextSchema } from "./schema/richtext";
|
18
|
-
import {
|
19
|
-
ImageMetadata,
|
20
|
-
ImageSchema,
|
21
|
-
SerializedImageSchema,
|
22
|
-
} from "./schema/image";
|
23
|
-
import { FileSource } from "./source/file";
|
24
|
-
import { AnyRichTextOptions, RichText } from "./source/richtext";
|
25
|
-
import { RecordSchema, SerializedRecordSchema } from "./schema/record";
|
26
|
-
import { RawString } from "./schema/string";
|
27
|
-
|
28
|
-
const brand = Symbol("ValModule");
|
29
|
-
export type ValModule<T extends SelectorSource> = SelectorOf<T> &
|
30
|
-
ValModuleBrand;
|
31
|
-
|
32
|
-
export type ValModuleBrand = {
|
33
|
-
[brand]: "ValModule";
|
34
|
-
};
|
35
|
-
|
36
|
-
export type TypeOfValModule<T extends ValModule<SelectorSource>> =
|
37
|
-
T extends GenericSelector<infer S> ? S : never;
|
38
|
-
|
39
|
-
type ReplaceRawStringWithString<T extends SelectorSource> =
|
40
|
-
SelectorSource extends T
|
41
|
-
? T
|
42
|
-
: T extends RawString
|
43
|
-
? string
|
44
|
-
: T extends { [key in string]: SelectorSource }
|
45
|
-
? {
|
46
|
-
[key in keyof T]: ReplaceRawStringWithString<T[key]>;
|
47
|
-
}
|
48
|
-
: T extends SelectorSource[]
|
49
|
-
? ReplaceRawStringWithString<T[number]>[]
|
50
|
-
: T;
|
51
|
-
|
52
|
-
export function content<T extends Schema<SelectorSource>>(
|
53
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
54
|
-
id: string,
|
55
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
56
|
-
schema: T,
|
57
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
58
|
-
source: ReplaceRawStringWithString<SchemaTypeOf<T>>
|
59
|
-
): ValModule<SchemaTypeOf<T>> {
|
60
|
-
return {
|
61
|
-
[GetSource]: source,
|
62
|
-
[GetSchema]: schema,
|
63
|
-
[Path]: id as SourcePath,
|
64
|
-
} as unknown as ValModule<SchemaTypeOf<T>>;
|
65
|
-
}
|
66
|
-
|
67
|
-
export function getSource(valModule: ValModule<SelectorSource>): Source {
|
68
|
-
const sourceOrExpr = valModule[GetSource];
|
69
|
-
if (sourceOrExpr instanceof Expr) {
|
70
|
-
throw Error("Cannot get raw source of an Expr");
|
71
|
-
}
|
72
|
-
const source = sourceOrExpr;
|
73
|
-
return source;
|
74
|
-
}
|
75
|
-
|
76
|
-
export function splitModuleIdAndModulePath(
|
77
|
-
path: SourcePath
|
78
|
-
): [moduleId: ModuleId, path: ModulePath] {
|
79
|
-
if (path.indexOf(".") === -1) {
|
80
|
-
return [path as unknown as ModuleId, "" as ModulePath];
|
81
|
-
}
|
82
|
-
return [
|
83
|
-
path.slice(0, path.indexOf(".")) as ModuleId,
|
84
|
-
path.slice(path.indexOf(".") + 1) as ModulePath,
|
85
|
-
];
|
86
|
-
}
|
87
|
-
|
88
|
-
export function getSourceAtPath(
|
89
|
-
modulePath: ModulePath,
|
90
|
-
valModule: ValModule<SelectorSource> | Source
|
91
|
-
) {
|
92
|
-
const parts = parsePath(modulePath);
|
93
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
94
|
-
let current: any = valModule;
|
95
|
-
for (const part of parts) {
|
96
|
-
if (typeof current !== "object") {
|
97
|
-
throw Error(`Invalid path: ${part} is not an object`);
|
98
|
-
}
|
99
|
-
current = current[part];
|
100
|
-
}
|
101
|
-
return current;
|
102
|
-
}
|
103
|
-
|
104
|
-
function isObjectSchema(
|
105
|
-
schema: Schema<SelectorSource> | SerializedSchema
|
106
|
-
): schema is
|
107
|
-
| ObjectSchema<{ [key: string]: Schema<SelectorSource> }>
|
108
|
-
| SerializedObjectSchema {
|
109
|
-
return (
|
110
|
-
schema instanceof ObjectSchema ||
|
111
|
-
(typeof schema === "object" && "type" in schema && schema.type === "object")
|
112
|
-
);
|
113
|
-
}
|
114
|
-
|
115
|
-
function isRecordSchema(
|
116
|
-
schema: Schema<SelectorSource> | SerializedSchema
|
117
|
-
): schema is RecordSchema<Schema<SelectorSource>> | SerializedRecordSchema {
|
118
|
-
return (
|
119
|
-
schema instanceof RecordSchema ||
|
120
|
-
(typeof schema === "object" && "type" in schema && schema.type === "record")
|
121
|
-
);
|
122
|
-
}
|
123
|
-
|
124
|
-
function isArraySchema(
|
125
|
-
schema: Schema<SelectorSource> | SerializedSchema
|
126
|
-
): schema is ArraySchema<Schema<SelectorSource>> | SerializedArraySchema {
|
127
|
-
return (
|
128
|
-
schema instanceof ArraySchema ||
|
129
|
-
(typeof schema === "object" && "type" in schema && schema.type === "array")
|
130
|
-
);
|
131
|
-
}
|
132
|
-
|
133
|
-
// function isI18nSchema(
|
134
|
-
// schema: Schema<SelectorSource> | SerializedSchema
|
135
|
-
// ): schema is I18nSchema<readonly string[]> | SerializedI18nSchema {
|
136
|
-
// return (
|
137
|
-
// schema instanceof I18nSchema ||
|
138
|
-
// (typeof schema === "object" && "type" in schema && schema.type === "i18n")
|
139
|
-
// );
|
140
|
-
// }
|
141
|
-
|
142
|
-
function isUnionSchema(
|
143
|
-
schema: Schema<SelectorSource> | SerializedSchema
|
144
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
145
|
-
): schema is UnionSchema<string, any> | SerializedUnionSchema {
|
146
|
-
return (
|
147
|
-
schema instanceof UnionSchema ||
|
148
|
-
(typeof schema === "object" && "type" in schema && schema.type === "union")
|
149
|
-
);
|
150
|
-
}
|
151
|
-
|
152
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
153
|
-
function isRichTextSchema(
|
154
|
-
schema: Schema<SelectorSource> | SerializedSchema
|
155
|
-
): schema is
|
156
|
-
| Schema<RichText<AnyRichTextOptions>> // TODO: RichTextSchema
|
157
|
-
| SerializedRichTextSchema {
|
158
|
-
return (
|
159
|
-
schema instanceof RichTextSchema ||
|
160
|
-
(typeof schema === "object" &&
|
161
|
-
"type" in schema &&
|
162
|
-
schema.type === "richtext")
|
163
|
-
);
|
164
|
-
}
|
165
|
-
|
166
|
-
function isImageSchema(
|
167
|
-
schema: Schema<SelectorSource> | SerializedSchema
|
168
|
-
): schema is
|
169
|
-
| ImageSchema<FileSource<ImageMetadata> | null>
|
170
|
-
| SerializedImageSchema {
|
171
|
-
return (
|
172
|
-
schema instanceof ImageSchema ||
|
173
|
-
(typeof schema === "object" && "type" in schema && schema.type === "image")
|
174
|
-
);
|
175
|
-
}
|
176
|
-
|
177
|
-
// function isOneOfSchema(
|
178
|
-
// schema: Schema<SelectorSource> | SerializedSchema
|
179
|
-
// ): schema is OneOfSchema<GenericSelector<SourceArray>> | SerializedOneOfSchema {
|
180
|
-
// return (
|
181
|
-
// schema instanceof OneOfSchema ||
|
182
|
-
// (typeof schema === "object" && "type" in schema && schema.type === "oneOf")
|
183
|
-
// );
|
184
|
-
// }
|
185
|
-
|
186
|
-
export function resolvePath<
|
187
|
-
Src extends ValModule<SelectorSource> | Source,
|
188
|
-
Sch extends Schema<SelectorSource> | SerializedSchema
|
189
|
-
>(
|
190
|
-
path: ModulePath,
|
191
|
-
valModule: Src,
|
192
|
-
schema: Sch
|
193
|
-
): {
|
194
|
-
path: SourcePath;
|
195
|
-
schema: Sch;
|
196
|
-
source: Src;
|
197
|
-
} {
|
198
|
-
const parts = parsePath(path);
|
199
|
-
const origParts = [...parts];
|
200
|
-
let resolvedSchema: Schema<SelectorSource> | SerializedSchema = schema;
|
201
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
202
|
-
let resolvedSource: any /* TODO: any */ = valModule;
|
203
|
-
while (parts.length > 0) {
|
204
|
-
const part = parts.shift();
|
205
|
-
if (part === undefined) {
|
206
|
-
throw Error("Unexpected undefined part");
|
207
|
-
}
|
208
|
-
if (isArraySchema(resolvedSchema)) {
|
209
|
-
if (Number.isNaN(Number(part))) {
|
210
|
-
throw Error(
|
211
|
-
`Invalid path: array schema ${JSON.stringify(
|
212
|
-
resolvedSchema
|
213
|
-
)} must have a number as path, but got ${part}. Path: ${path}`
|
214
|
-
);
|
215
|
-
}
|
216
|
-
if (
|
217
|
-
typeof resolvedSource !== "object" &&
|
218
|
-
!Array.isArray(resolvedSource)
|
219
|
-
) {
|
220
|
-
throw Error(
|
221
|
-
`Schema type error: expected source to be type of array, but got ${typeof resolvedSource}`
|
222
|
-
);
|
223
|
-
}
|
224
|
-
if (!resolvedSource[part]) {
|
225
|
-
throw Error(
|
226
|
-
`Invalid path: array source (length: ${resolvedSource?.length}) did not have index ${part} from path: ${path}`
|
227
|
-
);
|
228
|
-
}
|
229
|
-
resolvedSource = resolvedSource[part];
|
230
|
-
resolvedSchema = resolvedSchema.item;
|
231
|
-
} else if (isRecordSchema(resolvedSchema)) {
|
232
|
-
if (typeof part !== "string") {
|
233
|
-
throw Error(
|
234
|
-
`Invalid path: record schema ${resolvedSchema} must have path: ${part} as string`
|
235
|
-
);
|
236
|
-
}
|
237
|
-
if (
|
238
|
-
typeof resolvedSource !== "object" &&
|
239
|
-
!Array.isArray(resolvedSource)
|
240
|
-
) {
|
241
|
-
throw Error(
|
242
|
-
`Schema type error: expected source to be type of record, but got ${typeof resolvedSource}`
|
243
|
-
);
|
244
|
-
}
|
245
|
-
if (!resolvedSource[part]) {
|
246
|
-
throw Error(
|
247
|
-
`Invalid path: record source did not have key ${part} from path: ${path}`
|
248
|
-
);
|
249
|
-
}
|
250
|
-
resolvedSource = resolvedSource[part];
|
251
|
-
resolvedSchema = resolvedSchema.item;
|
252
|
-
} else if (isObjectSchema(resolvedSchema)) {
|
253
|
-
if (typeof resolvedSource !== "object") {
|
254
|
-
throw Error(
|
255
|
-
`Schema type error: expected source to be type of object, but got ${typeof resolvedSource}`
|
256
|
-
);
|
257
|
-
}
|
258
|
-
|
259
|
-
if (!resolvedSource[part]) {
|
260
|
-
throw Error(
|
261
|
-
`Invalid path: object source did not have key ${part} from path: ${path}`
|
262
|
-
);
|
263
|
-
}
|
264
|
-
resolvedSource = resolvedSource[part];
|
265
|
-
resolvedSchema = resolvedSchema.items[part];
|
266
|
-
// } else if (isI18nSchema(resolvedSchema)) {
|
267
|
-
// if (!resolvedSchema.locales.includes(part)) {
|
268
|
-
// throw Error(
|
269
|
-
// `Invalid path: i18n schema ${resolvedSchema} supports locales ${resolvedSchema.locales.join(
|
270
|
-
// ", "
|
271
|
-
// )}, but found: ${part}`
|
272
|
-
// );
|
273
|
-
// }
|
274
|
-
// if (!Object.keys(resolvedSource).includes(part)) {
|
275
|
-
// throw Error(
|
276
|
-
// `Schema type error: expected source to be type of i18n with locale ${part}, but got ${JSON.stringify(
|
277
|
-
// Object.keys(resolvedSource)
|
278
|
-
// )}`
|
279
|
-
// );
|
280
|
-
// }
|
281
|
-
// resolvedSource = resolvedSource[part];
|
282
|
-
// resolvedSchema = resolvedSchema.item;
|
283
|
-
} else if (isImageSchema(resolvedSchema)) {
|
284
|
-
return {
|
285
|
-
path: origParts
|
286
|
-
.slice(0, origParts.length - parts.length - 1)
|
287
|
-
.map((p) => JSON.stringify(p))
|
288
|
-
.join(".") as SourcePath, // TODO: create a function generate path from parts (not sure if this always works)
|
289
|
-
schema: resolvedSchema as Sch,
|
290
|
-
source: resolvedSource,
|
291
|
-
};
|
292
|
-
} else if (isUnionSchema(resolvedSchema)) {
|
293
|
-
const key = resolvedSchema.key;
|
294
|
-
const keyValue = resolvedSource[key];
|
295
|
-
if (!keyValue) {
|
296
|
-
throw Error(
|
297
|
-
`Invalid path: union source ${resolvedSchema} did not have required key ${key} in path: ${path}`
|
298
|
-
);
|
299
|
-
}
|
300
|
-
const schemaOfUnionKey = resolvedSchema.items.find(
|
301
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
302
|
-
(child: any) => child?.items?.[key]?.value === keyValue
|
303
|
-
);
|
304
|
-
if (!schemaOfUnionKey) {
|
305
|
-
throw Error(
|
306
|
-
`Invalid path: union schema ${resolvedSchema} did not have a child object with ${key} of value ${keyValue} in path: ${path}`
|
307
|
-
);
|
308
|
-
}
|
309
|
-
resolvedSchema = schemaOfUnionKey.items[part];
|
310
|
-
resolvedSource = resolvedSource[part];
|
311
|
-
} else if (isRichTextSchema(resolvedSchema)) {
|
312
|
-
return {
|
313
|
-
path: origParts
|
314
|
-
.slice(0, origParts.length - parts.length - 1)
|
315
|
-
.map((p) => JSON.stringify(p))
|
316
|
-
.join(".") as SourcePath, // TODO: create a function generate path from parts (not sure if this always works)
|
317
|
-
schema: resolvedSchema as Sch,
|
318
|
-
source: resolvedSource,
|
319
|
-
};
|
320
|
-
} else {
|
321
|
-
throw Error(
|
322
|
-
`Invalid path: ${part} resolved to an unexpected schema ${JSON.stringify(
|
323
|
-
resolvedSchema
|
324
|
-
)}`
|
325
|
-
);
|
326
|
-
}
|
327
|
-
}
|
328
|
-
if (parts.length > 0) {
|
329
|
-
throw Error(`Invalid path: ${parts.join(".")} is not a valid path`);
|
330
|
-
}
|
331
|
-
return {
|
332
|
-
path: origParts
|
333
|
-
.map((p) => {
|
334
|
-
if (!Number.isNaN(Number(p))) {
|
335
|
-
return p;
|
336
|
-
} else {
|
337
|
-
return JSON.stringify(p);
|
338
|
-
}
|
339
|
-
})
|
340
|
-
.join(".") as SourcePath, // TODO: create a function generate path from parts (not sure if this always works)
|
341
|
-
schema: resolvedSchema as Sch,
|
342
|
-
source: resolvedSource as Src,
|
343
|
-
};
|
344
|
-
}
|
345
|
-
|
346
|
-
export function parsePath(input: ModulePath) {
|
347
|
-
const result = [];
|
348
|
-
let i = 0;
|
349
|
-
|
350
|
-
while (i < input.length) {
|
351
|
-
let part = "";
|
352
|
-
|
353
|
-
if (input[i] === '"') {
|
354
|
-
// Parse a quoted string
|
355
|
-
i++;
|
356
|
-
while (i < input.length && input[i] !== '"') {
|
357
|
-
if (input[i] === "\\" && input[i + 1] === '"') {
|
358
|
-
// Handle escaped double quotes
|
359
|
-
part += '"';
|
360
|
-
i++;
|
361
|
-
} else {
|
362
|
-
part += input[i];
|
363
|
-
}
|
364
|
-
i++;
|
365
|
-
}
|
366
|
-
if (input[i] !== '"') {
|
367
|
-
throw new Error(
|
368
|
-
`Invalid input (${JSON.stringify(
|
369
|
-
input
|
370
|
-
)}): Missing closing double quote: ${
|
371
|
-
input[i] ?? "at end of string"
|
372
|
-
} (char: ${i}; length: ${input.length})`
|
373
|
-
);
|
374
|
-
}
|
375
|
-
} else {
|
376
|
-
// Parse a regular string
|
377
|
-
while (i < input.length && input[i] !== ".") {
|
378
|
-
part += input[i];
|
379
|
-
i++;
|
380
|
-
}
|
381
|
-
}
|
382
|
-
|
383
|
-
if (part !== "") {
|
384
|
-
result.push(part);
|
385
|
-
}
|
386
|
-
|
387
|
-
i++;
|
388
|
-
}
|
389
|
-
|
390
|
-
return result;
|
391
|
-
}
|
392
|
-
|
393
|
-
export type SerializedModule = {
|
394
|
-
source: Json;
|
395
|
-
schema: SerializedSchema;
|
396
|
-
path: SourcePath;
|
397
|
-
};
|
package/src/patch/deref.test.ts
DELETED
@@ -1,298 +0,0 @@
|
|
1
|
-
import { file } from "../source/file";
|
2
|
-
import { result } from "../fp";
|
3
|
-
import { remote } from "../source/future/remote";
|
4
|
-
import { derefPatch, DerefPatchResult } from "./deref";
|
5
|
-
import { JSONOps } from "./json";
|
6
|
-
import { PatchError } from "./ops";
|
7
|
-
|
8
|
-
const ops = new JSONOps();
|
9
|
-
describe("deref", () => {
|
10
|
-
test("replace image", () => {
|
11
|
-
const actual = derefPatch(
|
12
|
-
[
|
13
|
-
{
|
14
|
-
op: "replace",
|
15
|
-
path: ["foo", "baz"],
|
16
|
-
value: 2,
|
17
|
-
},
|
18
|
-
{
|
19
|
-
op: "replace",
|
20
|
-
path: ["foo", "$image1"],
|
21
|
-
value: "aWtrZSB25nJzdD8=",
|
22
|
-
},
|
23
|
-
{
|
24
|
-
op: "replace",
|
25
|
-
path: ["foo", "baz"],
|
26
|
-
value: 3,
|
27
|
-
},
|
28
|
-
{
|
29
|
-
op: "replace",
|
30
|
-
path: ["foo", "$image2"],
|
31
|
-
value: "ZnVua2VyIGRldHRlPw==",
|
32
|
-
},
|
33
|
-
],
|
34
|
-
{
|
35
|
-
foo: {
|
36
|
-
baz: 1,
|
37
|
-
image1: file("/public/val/File\\ Name.jpg", {}),
|
38
|
-
image2: file("/public/val/Some\\ Other\\ image.jpg", {}),
|
39
|
-
},
|
40
|
-
},
|
41
|
-
ops
|
42
|
-
);
|
43
|
-
const expected: DerefPatchResult = {
|
44
|
-
dereferencedPatch: [
|
45
|
-
{
|
46
|
-
op: "replace",
|
47
|
-
path: ["foo", "baz"],
|
48
|
-
value: 2,
|
49
|
-
},
|
50
|
-
{
|
51
|
-
op: "replace",
|
52
|
-
path: ["foo", "baz"],
|
53
|
-
value: 3,
|
54
|
-
},
|
55
|
-
],
|
56
|
-
fileUpdates: {
|
57
|
-
"/public/val/File\\ Name.jpg": "aWtrZSB25nJzdD8=",
|
58
|
-
"/public/val/Some\\ Other\\ image.jpg": "ZnVua2VyIGRldHRlPw==",
|
59
|
-
},
|
60
|
-
};
|
61
|
-
expect(actual).toStrictEqual(result.ok(expected));
|
62
|
-
});
|
63
|
-
|
64
|
-
test("replace image sub-reference fails", () => {
|
65
|
-
const actual = derefPatch(
|
66
|
-
[
|
67
|
-
{
|
68
|
-
op: "replace",
|
69
|
-
path: ["foo", "baz"],
|
70
|
-
value: 2,
|
71
|
-
},
|
72
|
-
{
|
73
|
-
op: "replace",
|
74
|
-
path: ["foo", "$image1", "bar"],
|
75
|
-
value: "aWtrZSB25nJzdD8=",
|
76
|
-
},
|
77
|
-
],
|
78
|
-
{
|
79
|
-
foo: {
|
80
|
-
baz: 1,
|
81
|
-
image1: file("/public/val/File\\ Name.jpg", {}),
|
82
|
-
},
|
83
|
-
},
|
84
|
-
ops
|
85
|
-
);
|
86
|
-
expect(actual).toStrictEqual(result.err(expect.any(PatchError)));
|
87
|
-
});
|
88
|
-
|
89
|
-
test("replace image with 2 replaces on same image", () => {
|
90
|
-
const actual = derefPatch(
|
91
|
-
[
|
92
|
-
{
|
93
|
-
op: "replace",
|
94
|
-
path: ["foo", "baz"],
|
95
|
-
value: 2,
|
96
|
-
},
|
97
|
-
{
|
98
|
-
op: "replace",
|
99
|
-
path: ["foo", "$image1"],
|
100
|
-
value: "aWtrZSB25nJzdD8=",
|
101
|
-
},
|
102
|
-
{
|
103
|
-
op: "replace",
|
104
|
-
path: ["foo", "baz"],
|
105
|
-
value: 3,
|
106
|
-
},
|
107
|
-
{
|
108
|
-
op: "replace",
|
109
|
-
path: ["foo", "$image2"],
|
110
|
-
value: "ZnVua2VyIGRldHRlPw==",
|
111
|
-
},
|
112
|
-
],
|
113
|
-
{
|
114
|
-
foo: {
|
115
|
-
baz: 1,
|
116
|
-
image1: file("/public/val/File\\ Name.jpg", {}),
|
117
|
-
image2: file("/public/val/File\\ Name.jpg", {}),
|
118
|
-
},
|
119
|
-
},
|
120
|
-
ops
|
121
|
-
);
|
122
|
-
const expected: DerefPatchResult = {
|
123
|
-
dereferencedPatch: [
|
124
|
-
{
|
125
|
-
op: "replace",
|
126
|
-
path: ["foo", "baz"],
|
127
|
-
value: 2,
|
128
|
-
},
|
129
|
-
{
|
130
|
-
op: "replace",
|
131
|
-
path: ["foo", "baz"],
|
132
|
-
value: 3,
|
133
|
-
},
|
134
|
-
],
|
135
|
-
fileUpdates: {
|
136
|
-
"/public/val/File\\ Name.jpg": "ZnVua2VyIGRldHRlPw==",
|
137
|
-
},
|
138
|
-
};
|
139
|
-
expect(actual).toStrictEqual(result.ok(expected));
|
140
|
-
});
|
141
|
-
|
142
|
-
// test("replace remote", () => {
|
143
|
-
// const actual = derefPatch(
|
144
|
-
// [
|
145
|
-
// {
|
146
|
-
// op: "replace",
|
147
|
-
// path: ["foo", "baz"],
|
148
|
-
// value: 2,
|
149
|
-
// },
|
150
|
-
// {
|
151
|
-
// op: "replace",
|
152
|
-
// path: ["foo", "$re1", "test1"],
|
153
|
-
// value: "next test1 update",
|
154
|
-
// },
|
155
|
-
// {
|
156
|
-
// op: "replace",
|
157
|
-
// path: ["foo", "baz"],
|
158
|
-
// value: 3,
|
159
|
-
// },
|
160
|
-
// {
|
161
|
-
// op: "replace",
|
162
|
-
// path: ["foo", "$re2", "test2", "sub-segment"],
|
163
|
-
// value: "next test2 update",
|
164
|
-
// },
|
165
|
-
// ],
|
166
|
-
// {
|
167
|
-
// foo: {
|
168
|
-
// baz: 1,
|
169
|
-
// re1: remote("41f86df3"),
|
170
|
-
// re2: remote("96536d44"),
|
171
|
-
// },
|
172
|
-
// },
|
173
|
-
// ops
|
174
|
-
// );
|
175
|
-
// const expected: DerefPatchResult = {
|
176
|
-
// dereferencedPatch: [
|
177
|
-
// {
|
178
|
-
// op: "replace",
|
179
|
-
// path: ["foo", "baz"],
|
180
|
-
// value: 2,
|
181
|
-
// },
|
182
|
-
// {
|
183
|
-
// op: "replace",
|
184
|
-
// path: ["foo", "baz"],
|
185
|
-
// value: 3,
|
186
|
-
// },
|
187
|
-
// ],
|
188
|
-
// fileUpdates: {},
|
189
|
-
// remotePatches: {
|
190
|
-
// "41f86df3": [
|
191
|
-
// {
|
192
|
-
// op: "replace",
|
193
|
-
// path: ["test1"],
|
194
|
-
// value: "next test1 update",
|
195
|
-
// },
|
196
|
-
// ],
|
197
|
-
// "96536d44": [
|
198
|
-
// {
|
199
|
-
// op: "replace",
|
200
|
-
// path: ["test2", "sub-segment"],
|
201
|
-
// value: "next test2 update",
|
202
|
-
// },
|
203
|
-
// ],
|
204
|
-
// },
|
205
|
-
// };
|
206
|
-
// expect(actual).toStrictEqual(result.ok(expected));
|
207
|
-
// });
|
208
|
-
// test("replace remote with 2 replaces on same ref", () => {
|
209
|
-
// const actual = derefPatch(
|
210
|
-
// [
|
211
|
-
// {
|
212
|
-
// op: "replace",
|
213
|
-
// path: ["foo", "baz"],
|
214
|
-
// value: 2,
|
215
|
-
// },
|
216
|
-
// {
|
217
|
-
// op: "replace",
|
218
|
-
// path: ["foo", "$re1", "test1"],
|
219
|
-
// value: "next test1 update",
|
220
|
-
// },
|
221
|
-
// {
|
222
|
-
// op: "replace",
|
223
|
-
// path: ["foo", "baz"],
|
224
|
-
// value: 3,
|
225
|
-
// },
|
226
|
-
// {
|
227
|
-
// op: "replace",
|
228
|
-
// path: ["foo", "$re1", "test1"],
|
229
|
-
// value: "next test2 update",
|
230
|
-
// },
|
231
|
-
// ],
|
232
|
-
// {
|
233
|
-
// foo: {
|
234
|
-
// baz: 1,
|
235
|
-
// re1: remote("41f86df3"),
|
236
|
-
// re2: remote("96536d44"),
|
237
|
-
// },
|
238
|
-
// },
|
239
|
-
// ops
|
240
|
-
// );
|
241
|
-
// const expected: DerefPatchResult = {
|
242
|
-
// dereferencedPatch: [
|
243
|
-
// {
|
244
|
-
// op: "replace",
|
245
|
-
// path: ["foo", "baz"],
|
246
|
-
// value: 2,
|
247
|
-
// },
|
248
|
-
// {
|
249
|
-
// op: "replace",
|
250
|
-
// path: ["foo", "baz"],
|
251
|
-
// value: 3,
|
252
|
-
// },
|
253
|
-
// ],
|
254
|
-
// fileUpdates: {},
|
255
|
-
// remotePatches: {
|
256
|
-
// "41f86df3": [
|
257
|
-
// {
|
258
|
-
// op: "replace",
|
259
|
-
// path: ["test1"],
|
260
|
-
// value: "next test1 update",
|
261
|
-
// },
|
262
|
-
// {
|
263
|
-
// op: "replace",
|
264
|
-
// path: ["test1"],
|
265
|
-
// value: "next test2 update",
|
266
|
-
// },
|
267
|
-
// ],
|
268
|
-
// },
|
269
|
-
// };
|
270
|
-
// expect(actual).toStrictEqual(result.ok(expected));
|
271
|
-
// });
|
272
|
-
|
273
|
-
test("replace chained references fails", () => {
|
274
|
-
const actual = derefPatch(
|
275
|
-
[
|
276
|
-
{
|
277
|
-
op: "replace",
|
278
|
-
path: ["foo", "baz"],
|
279
|
-
value: 2,
|
280
|
-
},
|
281
|
-
{
|
282
|
-
op: "replace",
|
283
|
-
path: ["foo", "$re1", "$re2"], // we do not support this, but it might be something we need in the future depending on how remote values
|
284
|
-
value: "next test1 update",
|
285
|
-
},
|
286
|
-
],
|
287
|
-
{
|
288
|
-
foo: {
|
289
|
-
baz: 1,
|
290
|
-
re1: remote("41f86df3"),
|
291
|
-
re2: remote("96536d44"),
|
292
|
-
},
|
293
|
-
},
|
294
|
-
ops
|
295
|
-
);
|
296
|
-
expect(actual).toStrictEqual(result.err(expect.any(PatchError)));
|
297
|
-
});
|
298
|
-
});
|