@valbuild/server 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 +7 -4
- package/.babelrc.json +0 -5
- package/CHANGELOG.md +0 -0
- package/jest.config.js +0 -4
- package/src/LocalValServer.ts +0 -167
- package/src/ProxyValServer.ts +0 -542
- package/src/SerializedModuleContent.ts +0 -36
- package/src/Service.ts +0 -126
- package/src/ValFS.ts +0 -22
- package/src/ValFSHost.ts +0 -66
- package/src/ValModuleLoader.test.ts +0 -75
- package/src/ValModuleLoader.ts +0 -158
- package/src/ValQuickJSRuntime.ts +0 -85
- package/src/ValServer.ts +0 -24
- package/src/ValSourceFileHandler.ts +0 -57
- package/src/createFixPatch.ts +0 -170
- package/src/createRequestHandler.ts +0 -27
- package/src/expressHelpers.ts +0 -5
- package/src/getCompilerOptions.ts +0 -50
- package/src/hosting.ts +0 -290
- package/src/index.ts +0 -16
- package/src/jwt.ts +0 -93
- package/src/patch/ts/ops.test.ts +0 -937
- package/src/patch/ts/ops.ts +0 -897
- package/src/patch/ts/syntax.ts +0 -371
- package/src/patch/ts/valModule.test.ts +0 -26
- package/src/patch/ts/valModule.ts +0 -110
- package/src/patch/validation.ts +0 -81
- package/src/patchValFile.ts +0 -110
- package/src/readValFile.test.ts +0 -49
- package/src/readValFile.ts +0 -96
- package/test/example-projects/basic-next-javascript/jsconfig.json +0 -8
- package/test/example-projects/basic-next-javascript/package.json +0 -23
- package/test/example-projects/basic-next-javascript/pages/blogs.val.js +0 -20
- package/test/example-projects/basic-next-javascript/val.config.js +0 -4
- package/test/example-projects/basic-next-src-typescript/package.json +0 -23
- package/test/example-projects/basic-next-src-typescript/src/pages/blogs.val.ts +0 -20
- package/test/example-projects/basic-next-src-typescript/src/val.config.ts +0 -5
- package/test/example-projects/basic-next-src-typescript/tsconfig.json +0 -24
- package/test/example-projects/basic-next-typescript/package.json +0 -23
- package/test/example-projects/basic-next-typescript/pages/blogs.val.ts +0 -20
- package/test/example-projects/basic-next-typescript/tsconfig.json +0 -25
- package/test/example-projects/basic-next-typescript/val.config.ts +0 -5
- package/test/example-projects/typescript-description-files/README.md +0 -2
- package/test/example-projects/typescript-description-files/jsconfig.json +0 -8
- package/test/example-projects/typescript-description-files/package.json +0 -23
- package/test/example-projects/typescript-description-files/pages/blogs.val.d.ts +0 -7
- package/test/example-projects/typescript-description-files/pages/blogs.val.js +0 -19
- package/test/example-projects/typescript-description-files/val.config.d.ts +0 -3
- package/test/example-projects/typescript-description-files/val.config.js +0 -5
- package/tsconfig.json +0 -12
package/src/patch/ts/ops.test.ts
DELETED
@@ -1,937 +0,0 @@
|
|
1
|
-
import ts from "typescript";
|
2
|
-
import { TSOps } from "./ops";
|
3
|
-
import { result, array, pipe } from "@valbuild/core/fp";
|
4
|
-
import { PatchError, JSONValue } from "@valbuild/core/patch";
|
5
|
-
import { ValSyntaxError } from "./syntax";
|
6
|
-
import { FILE_REF_PROP, VAL_EXTENSION } from "@valbuild/core";
|
7
|
-
|
8
|
-
function testSourceFile(expression: string): ts.SourceFile {
|
9
|
-
return ts.createSourceFile(
|
10
|
-
"test.ts",
|
11
|
-
`(${expression})`,
|
12
|
-
ts.ScriptTarget.ES2020,
|
13
|
-
true
|
14
|
-
);
|
15
|
-
}
|
16
|
-
|
17
|
-
/**
|
18
|
-
* This function throws instead of returning Err because a malformed source
|
19
|
-
* would be an issue with the test data.
|
20
|
-
*/
|
21
|
-
function findRoot(
|
22
|
-
sourceFile: ts.SourceFile
|
23
|
-
): result.Result<ts.Expression, never> {
|
24
|
-
if (sourceFile.statements.length !== 1) {
|
25
|
-
throw Error("Invalid test source file");
|
26
|
-
}
|
27
|
-
const [stmt] = sourceFile.statements;
|
28
|
-
if (!ts.isExpressionStatement(stmt)) {
|
29
|
-
throw Error("Invalid test source file");
|
30
|
-
}
|
31
|
-
const expr = stmt.expression;
|
32
|
-
if (!ts.isParenthesizedExpression(expr)) {
|
33
|
-
throw Error("Invalid test source file");
|
34
|
-
}
|
35
|
-
return result.ok(expr.expression);
|
36
|
-
}
|
37
|
-
|
38
|
-
describe("TSOps", () => {
|
39
|
-
test.each<{
|
40
|
-
name: string;
|
41
|
-
input: string;
|
42
|
-
path: string[];
|
43
|
-
value: JSONValue;
|
44
|
-
expected: result.Result<string, typeof PatchError | typeof ValSyntaxError>;
|
45
|
-
}>([
|
46
|
-
{
|
47
|
-
name: "root of document",
|
48
|
-
input: `{ foo: "bar" }`,
|
49
|
-
path: [],
|
50
|
-
value: null,
|
51
|
-
expected: result.ok(`null`),
|
52
|
-
},
|
53
|
-
{
|
54
|
-
name: "defined property to object",
|
55
|
-
input: `{ foo: "bar" }`,
|
56
|
-
path: ["foo"],
|
57
|
-
value: null,
|
58
|
-
expected: result.ok(`{ foo: null }`),
|
59
|
-
},
|
60
|
-
{
|
61
|
-
name: "new property to object",
|
62
|
-
input: `{ foo: "bar" }`,
|
63
|
-
path: ["bar"],
|
64
|
-
value: null,
|
65
|
-
expected: result.ok(`{ foo: "bar", bar: null }`),
|
66
|
-
},
|
67
|
-
{
|
68
|
-
name: "property to object that is not an identifier (empty string)",
|
69
|
-
input: `{ foo: "bar" }`,
|
70
|
-
path: [""],
|
71
|
-
value: "foo",
|
72
|
-
expected: result.ok(`{ foo: "bar", "": "foo" }`),
|
73
|
-
},
|
74
|
-
{
|
75
|
-
name: "property to object that is not an identifier (strings with whitespace)",
|
76
|
-
input: `{ foo: "bar" }`,
|
77
|
-
path: ["foo and "],
|
78
|
-
value: "foo",
|
79
|
-
expected: result.ok(`{ foo: "bar", "foo and ": "foo" }`),
|
80
|
-
},
|
81
|
-
{
|
82
|
-
name: "item to array followed by other items",
|
83
|
-
input: `["foo", "bar"]`,
|
84
|
-
path: ["0"],
|
85
|
-
value: null,
|
86
|
-
expected: result.ok(`[null, "foo", "bar"]`),
|
87
|
-
},
|
88
|
-
{
|
89
|
-
name: "item to end of array",
|
90
|
-
input: `["foo", "bar"]`,
|
91
|
-
path: ["2"],
|
92
|
-
value: null,
|
93
|
-
expected: result.ok(`["foo", "bar", null]`),
|
94
|
-
},
|
95
|
-
{
|
96
|
-
name: "item to end of array with dash",
|
97
|
-
input: `["foo", "bar"]`,
|
98
|
-
path: ["-"],
|
99
|
-
value: null,
|
100
|
-
expected: result.ok(`["foo", "bar", null]`),
|
101
|
-
},
|
102
|
-
{
|
103
|
-
name: "item to array with invalid index",
|
104
|
-
input: `["foo", "bar"]`,
|
105
|
-
path: ["baz"],
|
106
|
-
value: null,
|
107
|
-
expected: result.err(PatchError),
|
108
|
-
},
|
109
|
-
{
|
110
|
-
name: "item at index out of bounds of array",
|
111
|
-
input: `["foo", "bar"]`,
|
112
|
-
path: ["3"],
|
113
|
-
value: null,
|
114
|
-
expected: result.err(PatchError),
|
115
|
-
},
|
116
|
-
{
|
117
|
-
name: "defined property to object nested within object",
|
118
|
-
input: `{ foo: { bar: "baz" } }`,
|
119
|
-
path: ["foo", "bar"],
|
120
|
-
value: null,
|
121
|
-
expected: result.ok(`{ foo: { bar: null } }`),
|
122
|
-
},
|
123
|
-
{
|
124
|
-
name: "defined property to object nested within array",
|
125
|
-
input: `[{ foo: "bar" }]`,
|
126
|
-
path: ["0", "foo"],
|
127
|
-
value: null,
|
128
|
-
expected: result.ok(`[{ foo: null }]`),
|
129
|
-
},
|
130
|
-
{
|
131
|
-
name: "to undefined object/array",
|
132
|
-
input: `{ foo: "bar" }`,
|
133
|
-
path: ["bar", "foo"],
|
134
|
-
value: null,
|
135
|
-
expected: result.err(PatchError),
|
136
|
-
},
|
137
|
-
{
|
138
|
-
name: "to non-object/array",
|
139
|
-
input: `0`,
|
140
|
-
path: ["foo"],
|
141
|
-
value: null,
|
142
|
-
expected: result.err(PatchError),
|
143
|
-
},
|
144
|
-
{
|
145
|
-
name: "val.file",
|
146
|
-
input: `{ foo: "bar" }`,
|
147
|
-
path: ["image"],
|
148
|
-
value: { _ref: "/public/val/image.jpg" },
|
149
|
-
expected: result.ok(
|
150
|
-
`{ foo: "bar", image: val.file("/public/val/image.jpg") }`
|
151
|
-
),
|
152
|
-
},
|
153
|
-
{
|
154
|
-
name: "ref prop to val.file",
|
155
|
-
input: `val.file("/public/val/foo.jpg")`,
|
156
|
-
path: ["_ref"],
|
157
|
-
value: "/public/val/bar.jpg",
|
158
|
-
expected: result.ok(`val.file("/public/val/bar.jpg")`),
|
159
|
-
},
|
160
|
-
{
|
161
|
-
name: "ref prop",
|
162
|
-
input: `{ foo: "bar", image: {} }`,
|
163
|
-
path: ["image", "_ref"],
|
164
|
-
value: "/public/val/image.jpg",
|
165
|
-
expected: result.err(PatchError),
|
166
|
-
},
|
167
|
-
{
|
168
|
-
name: "prop on val.file TODO",
|
169
|
-
input: `{ foo: "bar", image: val.file("/public/val/image.jpg") }`,
|
170
|
-
path: ["image", "metadata"],
|
171
|
-
value: {
|
172
|
-
width: 123,
|
173
|
-
height: 456,
|
174
|
-
sha256: "abc",
|
175
|
-
},
|
176
|
-
expected: result.ok(
|
177
|
-
`{ foo: "bar", image: val.file("/public/val/image.jpg", { width: 123, height: 456, sha256: "abc" }) }`
|
178
|
-
),
|
179
|
-
},
|
180
|
-
{
|
181
|
-
name: "null prop of name ref on val.file",
|
182
|
-
input: `{ foo: "bar", image: val.file("/public/val/image.jpg") }`,
|
183
|
-
path: ["image", "_ref"],
|
184
|
-
value: null,
|
185
|
-
expected: result.err(PatchError),
|
186
|
-
},
|
187
|
-
{
|
188
|
-
name: "to ref on val.file",
|
189
|
-
input: `{ foo: "bar", image: val.file("/public/val/image.jpg") }`,
|
190
|
-
path: ["image", "_ref", "zoo"],
|
191
|
-
value: null,
|
192
|
-
expected: result.err(PatchError),
|
193
|
-
},
|
194
|
-
])("add $name", ({ input, path, value, expected }) => {
|
195
|
-
const src = testSourceFile(input);
|
196
|
-
const ops = new TSOps(findRoot);
|
197
|
-
expect(ops.add(src, path, value)).toEqual(
|
198
|
-
pipe(
|
199
|
-
expected,
|
200
|
-
result.map(testSourceFile),
|
201
|
-
result.mapErr((errorType) => expect.any(errorType))
|
202
|
-
)
|
203
|
-
);
|
204
|
-
});
|
205
|
-
|
206
|
-
test.each<{
|
207
|
-
name: string;
|
208
|
-
input: string;
|
209
|
-
path: array.NonEmptyArray<string>;
|
210
|
-
expected: result.Result<string, typeof PatchError | typeof ValSyntaxError>;
|
211
|
-
}>([
|
212
|
-
{
|
213
|
-
name: "defined property from object",
|
214
|
-
input: `{ foo: "bar", bar: "baz" }`,
|
215
|
-
path: ["bar"],
|
216
|
-
expected: result.ok(`{ foo: "bar" }`),
|
217
|
-
},
|
218
|
-
{
|
219
|
-
name: "undefined property to object",
|
220
|
-
input: `{ foo: "bar" }`,
|
221
|
-
path: ["bar"],
|
222
|
-
expected: result.err(PatchError),
|
223
|
-
},
|
224
|
-
{
|
225
|
-
name: "existing item from array",
|
226
|
-
input: `["foo", "bar"]`,
|
227
|
-
path: ["0"],
|
228
|
-
expected: result.ok(`["bar"]`),
|
229
|
-
},
|
230
|
-
{
|
231
|
-
name: "item from end of array with dash",
|
232
|
-
input: `["foo", "bar"]`,
|
233
|
-
path: ["-"],
|
234
|
-
expected: result.err(PatchError),
|
235
|
-
},
|
236
|
-
{
|
237
|
-
name: "item at index out of bounds of array",
|
238
|
-
input: `["foo", "bar"]`,
|
239
|
-
path: ["2"],
|
240
|
-
expected: result.err(PatchError),
|
241
|
-
},
|
242
|
-
{
|
243
|
-
name: "item from array with invalid index",
|
244
|
-
input: `["foo", "bar"]`,
|
245
|
-
path: ["baz"],
|
246
|
-
expected: result.err(PatchError),
|
247
|
-
},
|
248
|
-
{
|
249
|
-
name: "defined property from object nested within object",
|
250
|
-
input: `{ foo: { bar: "baz", baz: "bar" } }`,
|
251
|
-
path: ["foo", "baz"],
|
252
|
-
expected: result.ok(`{ foo: { bar: "baz" } }`),
|
253
|
-
},
|
254
|
-
{
|
255
|
-
name: "defined property from object nested within array",
|
256
|
-
input: `[{ foo: "bar", baz: "bar" }]`,
|
257
|
-
path: ["0", "baz"],
|
258
|
-
expected: result.ok(`[{ foo: "bar" }]`),
|
259
|
-
},
|
260
|
-
{
|
261
|
-
name: "from undefined object/array",
|
262
|
-
input: `{ foo: "bar" }`,
|
263
|
-
path: ["bar", "foo"],
|
264
|
-
expected: result.err(PatchError),
|
265
|
-
},
|
266
|
-
{
|
267
|
-
name: "from non-object/array",
|
268
|
-
input: `0`,
|
269
|
-
path: ["foo"],
|
270
|
-
expected: result.err(PatchError),
|
271
|
-
},
|
272
|
-
{
|
273
|
-
name: "val.file from array",
|
274
|
-
input: `[val.file("/public/val/image1.jpg"), val.file("/public/val/image2.jpg")]`,
|
275
|
-
path: ["0"],
|
276
|
-
expected: result.ok(`[val.file("/public/val/image2.jpg")]`),
|
277
|
-
},
|
278
|
-
{
|
279
|
-
name: "val.file from object",
|
280
|
-
input: `[{ foo: "bar", image: val.file("/public/val/image.jpg") }]`,
|
281
|
-
path: ["0", "image"],
|
282
|
-
expected: result.ok(`[{ foo: "bar" }]`),
|
283
|
-
},
|
284
|
-
{
|
285
|
-
name: "ref prop from val.file",
|
286
|
-
input: `{ image: val.file("/public/val/image.jpg") }`,
|
287
|
-
path: ["image", "_ref"],
|
288
|
-
expected: result.err(PatchError),
|
289
|
-
},
|
290
|
-
])("remove $name", ({ input, path, expected }) => {
|
291
|
-
const src = testSourceFile(input);
|
292
|
-
const ops = new TSOps(findRoot);
|
293
|
-
expect(ops.remove(src, path)).toEqual(
|
294
|
-
pipe(
|
295
|
-
expected,
|
296
|
-
result.map(testSourceFile),
|
297
|
-
result.mapErr((errorType) => expect.any(errorType))
|
298
|
-
)
|
299
|
-
);
|
300
|
-
});
|
301
|
-
|
302
|
-
test.each<{
|
303
|
-
name: string;
|
304
|
-
input: string;
|
305
|
-
path: string[];
|
306
|
-
value: JSONValue;
|
307
|
-
expected: result.Result<string, typeof PatchError | typeof ValSyntaxError>;
|
308
|
-
}>([
|
309
|
-
{
|
310
|
-
name: "root of document",
|
311
|
-
input: `{ foo: "bar" }`,
|
312
|
-
path: [],
|
313
|
-
value: null,
|
314
|
-
expected: result.ok(`null`),
|
315
|
-
},
|
316
|
-
{
|
317
|
-
name: "defined property of object",
|
318
|
-
input: `{ foo: "bar" }`,
|
319
|
-
path: ["foo"],
|
320
|
-
value: null,
|
321
|
-
expected: result.ok(`{ foo: null }`),
|
322
|
-
},
|
323
|
-
{
|
324
|
-
name: "undefined property of object",
|
325
|
-
input: `{ foo: "bar" }`,
|
326
|
-
path: ["bar"],
|
327
|
-
value: null,
|
328
|
-
expected: result.err(PatchError),
|
329
|
-
},
|
330
|
-
{
|
331
|
-
name: "item of array",
|
332
|
-
input: `["foo", "bar"]`,
|
333
|
-
path: ["0"],
|
334
|
-
value: null,
|
335
|
-
expected: result.ok(`[null, "bar"]`),
|
336
|
-
},
|
337
|
-
{
|
338
|
-
name: "item of array at invalid index",
|
339
|
-
input: `["foo", "bar"]`,
|
340
|
-
path: ["baz"],
|
341
|
-
value: null,
|
342
|
-
expected: result.err(PatchError),
|
343
|
-
},
|
344
|
-
{
|
345
|
-
name: "item at index out of bounds of array",
|
346
|
-
input: `["foo", "bar"]`,
|
347
|
-
path: ["2"],
|
348
|
-
value: null,
|
349
|
-
expected: result.err(PatchError),
|
350
|
-
},
|
351
|
-
{
|
352
|
-
name: "defined property of object nested within object",
|
353
|
-
input: `{ foo: { bar: "baz" } }`,
|
354
|
-
path: ["foo", "bar"],
|
355
|
-
value: null,
|
356
|
-
expected: result.ok(`{ foo: { bar: null } }`),
|
357
|
-
},
|
358
|
-
{
|
359
|
-
name: "defined property of object nested within array",
|
360
|
-
input: `[{ foo: "bar" }]`,
|
361
|
-
path: ["0", "foo"],
|
362
|
-
value: null,
|
363
|
-
expected: result.ok(`[{ foo: null }]`),
|
364
|
-
},
|
365
|
-
{
|
366
|
-
name: "from undefined object/array",
|
367
|
-
input: `{ foo: "bar" }`,
|
368
|
-
path: ["bar", "foo"],
|
369
|
-
value: null,
|
370
|
-
expected: result.err(PatchError),
|
371
|
-
},
|
372
|
-
{
|
373
|
-
name: "from non-object/array",
|
374
|
-
input: `0`,
|
375
|
-
path: ["foo"],
|
376
|
-
value: null,
|
377
|
-
expected: result.err(PatchError),
|
378
|
-
},
|
379
|
-
{
|
380
|
-
name: "val.files",
|
381
|
-
input: `val.file("/public/val/foo/bar.jpg")`,
|
382
|
-
path: ["_ref"],
|
383
|
-
value: "/public/val/foo/bar2.jpg",
|
384
|
-
expected: result.ok(`val.file("/public/val/foo/bar2.jpg")`),
|
385
|
-
},
|
386
|
-
{
|
387
|
-
name: "val.file ref with options",
|
388
|
-
input: `val.file("/public/val/foo/bar.jpg", { checksum: "123", width: 456, height: 789 })`,
|
389
|
-
path: ["_ref"],
|
390
|
-
value: "/public/val/foo/bar2.jpg",
|
391
|
-
expected: result.ok(
|
392
|
-
`val.file("/public/val/foo/bar2.jpg", { checksum: "123", width: 456, height: 789 })`
|
393
|
-
),
|
394
|
-
},
|
395
|
-
// TODO:
|
396
|
-
// {
|
397
|
-
// name: "val.file non metadata",
|
398
|
-
// input: `val.file("/public/val/foo/bar.jpg", { checksum: "123", width: 456, height: 789 })`,
|
399
|
-
// path: ["failure", "checksum"],
|
400
|
-
// value: "101112",
|
401
|
-
// expected: result.err(PatchError),
|
402
|
-
// },
|
403
|
-
{
|
404
|
-
name: "val.file checksum",
|
405
|
-
input: `val.file("/public/val/foo/bar.jpg", { checksum: "123", width: 456, height: 789 })`,
|
406
|
-
path: ["metadata", "checksum"],
|
407
|
-
value: "101112",
|
408
|
-
expected: result.ok(
|
409
|
-
`val.file("/public/val/foo/bar.jpg", { checksum: "101112", width: 456, height: 789 })`
|
410
|
-
),
|
411
|
-
},
|
412
|
-
{
|
413
|
-
name: "deep val.files",
|
414
|
-
input: `{ foo: { bar: val.file("/public/val/foo/bar/zoo.jpg") } }`,
|
415
|
-
path: ["foo", "bar", "_ref"],
|
416
|
-
value: "/public/val/foo/bar/zoo2.jpg",
|
417
|
-
expected: result.ok(
|
418
|
-
`{ foo: { bar: val.file("/public/val/foo/bar/zoo2.jpg") } }`
|
419
|
-
),
|
420
|
-
},
|
421
|
-
{
|
422
|
-
name: "prop on val.file",
|
423
|
-
input: `{ foo: "bar", image: val.file("/public/val/image.jpg") }`,
|
424
|
-
path: ["image", "metadata"],
|
425
|
-
value: {
|
426
|
-
width: 123,
|
427
|
-
height: 456,
|
428
|
-
sha256: "1234567890abcdef",
|
429
|
-
},
|
430
|
-
expected: result.err(PatchError),
|
431
|
-
},
|
432
|
-
{
|
433
|
-
name: "null prop of name ref on val.file",
|
434
|
-
input: `{ foo: "bar", image: val.file("/public/val/image.jpg") }`,
|
435
|
-
path: ["image", "_ref"],
|
436
|
-
value: null,
|
437
|
-
expected: result.err(PatchError),
|
438
|
-
},
|
439
|
-
{
|
440
|
-
name: "number prop of name ref on val.file",
|
441
|
-
input: `{ foo: "bar", image: val.file("/public/val/image.jpg") }`,
|
442
|
-
path: ["image", "_ref"],
|
443
|
-
value: 1,
|
444
|
-
expected: result.err(PatchError),
|
445
|
-
},
|
446
|
-
{
|
447
|
-
name: "to ref on val.file",
|
448
|
-
input: `{ foo: "bar", image: val.file("/public/val/image.jpg") }`,
|
449
|
-
path: ["image", "_ref", "zoo"],
|
450
|
-
value: null,
|
451
|
-
expected: result.err(PatchError),
|
452
|
-
},
|
453
|
-
{
|
454
|
-
name: "val.richtext basic no nodes",
|
455
|
-
input: "val.richtext`Test`",
|
456
|
-
path: [],
|
457
|
-
value: {
|
458
|
-
[VAL_EXTENSION]: "richtext",
|
459
|
-
templateStrings: ["Test 2"],
|
460
|
-
exprs: [],
|
461
|
-
},
|
462
|
-
expected: result.ok("val.richtext `Test 2`"),
|
463
|
-
},
|
464
|
-
{
|
465
|
-
name: "val.richtext advanced no nodes",
|
466
|
-
input: "val.richtext`Test`",
|
467
|
-
path: [],
|
468
|
-
value: {
|
469
|
-
[VAL_EXTENSION]: "richtext",
|
470
|
-
templateStrings: ["# Title 1\nTest 2"],
|
471
|
-
exprs: [],
|
472
|
-
},
|
473
|
-
expected: result.ok(`val.richtext \`# Title 1
|
474
|
-
Test 2\``),
|
475
|
-
},
|
476
|
-
{
|
477
|
-
name: "val.richtext basic nodes",
|
478
|
-
input: "val.richtext`Test`",
|
479
|
-
path: [],
|
480
|
-
value: {
|
481
|
-
[VAL_EXTENSION]: "richtext",
|
482
|
-
templateStrings: ["# Title 1\nTest 2\n", ""],
|
483
|
-
exprs: [
|
484
|
-
{
|
485
|
-
[VAL_EXTENSION]: "file",
|
486
|
-
[FILE_REF_PROP]: "/public/test",
|
487
|
-
metadata: { width: 100, height: 100, sha256: "123" },
|
488
|
-
},
|
489
|
-
],
|
490
|
-
},
|
491
|
-
expected: result.ok(`val.richtext \`# Title 1
|
492
|
-
Test 2
|
493
|
-
\${val.file("/public/test", { width: 100, height: 100, sha256: "123" })}\``),
|
494
|
-
},
|
495
|
-
{
|
496
|
-
name: "val.richtext advanced nodes",
|
497
|
-
input: "val.richtext`Test`",
|
498
|
-
path: [],
|
499
|
-
value: {
|
500
|
-
[VAL_EXTENSION]: "richtext",
|
501
|
-
templateStrings: ["# Title 1\n", "\n", "\nTest 2"],
|
502
|
-
exprs: [
|
503
|
-
{
|
504
|
-
[VAL_EXTENSION]: "file",
|
505
|
-
[FILE_REF_PROP]: "/public/test1",
|
506
|
-
metadata: { width: 100, height: 100, sha256: "123" },
|
507
|
-
},
|
508
|
-
{
|
509
|
-
[VAL_EXTENSION]: "file",
|
510
|
-
[FILE_REF_PROP]: "/public/test2",
|
511
|
-
metadata: { width: 100, height: 100, sha256: "123" },
|
512
|
-
},
|
513
|
-
],
|
514
|
-
},
|
515
|
-
expected: result.ok(`val.richtext \`# Title 1
|
516
|
-
\${val.file("/public/test1", { width: 100, height: 100, sha256: "123" })}
|
517
|
-
\${val.file("/public/test2", { width: 100, height: 100, sha256: "123" })}
|
518
|
-
Test 2\``),
|
519
|
-
},
|
520
|
-
{
|
521
|
-
name: "val.richtext link",
|
522
|
-
input: "val.richtext`Test`",
|
523
|
-
path: [],
|
524
|
-
value: {
|
525
|
-
[VAL_EXTENSION]: "richtext",
|
526
|
-
templateStrings: ["# Title 1\n", "\n", ""],
|
527
|
-
exprs: [
|
528
|
-
{
|
529
|
-
[VAL_EXTENSION]: "link",
|
530
|
-
href: "https://example.com",
|
531
|
-
children: ["https://example.com"],
|
532
|
-
},
|
533
|
-
{
|
534
|
-
[VAL_EXTENSION]: "file",
|
535
|
-
[FILE_REF_PROP]: "/public/test2",
|
536
|
-
metadata: { width: 100, height: 100, sha256: "123" },
|
537
|
-
},
|
538
|
-
],
|
539
|
-
},
|
540
|
-
expected: result.ok(`val.richtext \`# Title 1
|
541
|
-
\${val.link("https://example.com", { href: "https://example.com" })}
|
542
|
-
\${val.file("/public/test2", { width: 100, height: 100, sha256: "123" })}\``),
|
543
|
-
},
|
544
|
-
{
|
545
|
-
name: "val.richtext empty head",
|
546
|
-
input:
|
547
|
-
"{ text: val.richtext`${val.file('/public/test1', { height: 100 })}` }",
|
548
|
-
path: ["text"],
|
549
|
-
value: {
|
550
|
-
[VAL_EXTENSION]: "richtext",
|
551
|
-
templateStrings: ["", "\n", "\nTest 2"],
|
552
|
-
exprs: [
|
553
|
-
{
|
554
|
-
[VAL_EXTENSION]: "file",
|
555
|
-
[FILE_REF_PROP]: "/public/test1",
|
556
|
-
metadata: { width: 100, height: 100, sha256: "123" },
|
557
|
-
},
|
558
|
-
{
|
559
|
-
[VAL_EXTENSION]: "file",
|
560
|
-
[FILE_REF_PROP]: "/public/test2",
|
561
|
-
metadata: { width: 100, height: 100, sha256: "123" },
|
562
|
-
},
|
563
|
-
],
|
564
|
-
},
|
565
|
-
expected:
|
566
|
-
result.ok(`{ text: val.richtext \`\${val.file("/public/test1", { width: 100, height: 100, sha256: "123" })}
|
567
|
-
\${val.file("/public/test2", { width: 100, height: 100, sha256: "123" })}
|
568
|
-
Test 2\` }`),
|
569
|
-
},
|
570
|
-
])("replace $name", ({ input, path, value, expected }) => {
|
571
|
-
const src = testSourceFile(input);
|
572
|
-
const ops = new TSOps(findRoot);
|
573
|
-
expect(ops.replace(src, path, value)).toEqual(
|
574
|
-
pipe(
|
575
|
-
expected,
|
576
|
-
result.map(testSourceFile),
|
577
|
-
result.mapErr((errorType) => expect.any(errorType))
|
578
|
-
)
|
579
|
-
);
|
580
|
-
});
|
581
|
-
|
582
|
-
test.each<{
|
583
|
-
name: string;
|
584
|
-
input: string;
|
585
|
-
from: array.NonEmptyArray<string>;
|
586
|
-
path: string[];
|
587
|
-
expected: result.Result<string, typeof PatchError | typeof ValSyntaxError>;
|
588
|
-
}>([
|
589
|
-
{
|
590
|
-
name: "value to root of document",
|
591
|
-
input: `{ foo: "bar" }`,
|
592
|
-
from: ["foo"],
|
593
|
-
path: [],
|
594
|
-
expected: result.ok(`"bar"`),
|
595
|
-
},
|
596
|
-
{
|
597
|
-
name: "defined property to undefined property of object",
|
598
|
-
input: `{ foo: null, baz: 1 }`,
|
599
|
-
from: ["foo"],
|
600
|
-
path: ["bar"],
|
601
|
-
expected: result.ok(`{ baz: 1, bar: null }`),
|
602
|
-
},
|
603
|
-
{
|
604
|
-
name: "defined property to defined property of object",
|
605
|
-
input: `{ foo: null, bar: "baz" }`,
|
606
|
-
from: ["foo"],
|
607
|
-
path: ["bar"],
|
608
|
-
expected: result.ok(`{ bar: null }`),
|
609
|
-
},
|
610
|
-
{
|
611
|
-
name: "undefined property of object",
|
612
|
-
input: `{ foo: "bar" }`,
|
613
|
-
from: ["bar"],
|
614
|
-
path: ["baz"],
|
615
|
-
expected: result.err(PatchError),
|
616
|
-
},
|
617
|
-
{
|
618
|
-
name: "item within array",
|
619
|
-
input: `["foo", null]`,
|
620
|
-
from: ["1"],
|
621
|
-
path: ["0"],
|
622
|
-
expected: result.ok(`[null, "foo"]`),
|
623
|
-
},
|
624
|
-
{
|
625
|
-
name: "item to end of array with dash",
|
626
|
-
input: `[null, "foo"]`,
|
627
|
-
from: ["0"],
|
628
|
-
path: ["-"],
|
629
|
-
expected: result.ok(`["foo", null]`),
|
630
|
-
},
|
631
|
-
{
|
632
|
-
name: "item from invalid index of array",
|
633
|
-
input: `["foo", "bar"]`,
|
634
|
-
from: ["foo"],
|
635
|
-
path: ["0"],
|
636
|
-
expected: result.err(PatchError),
|
637
|
-
},
|
638
|
-
{
|
639
|
-
name: "item to invalid index of array",
|
640
|
-
input: `["foo", "bar"]`,
|
641
|
-
from: ["1"],
|
642
|
-
path: ["foo"],
|
643
|
-
expected: result.err(PatchError),
|
644
|
-
},
|
645
|
-
{
|
646
|
-
name: "item from index out of bounds of array",
|
647
|
-
input: `["foo", "bar"]`,
|
648
|
-
from: ["2"],
|
649
|
-
path: ["0"],
|
650
|
-
expected: result.err(PatchError),
|
651
|
-
},
|
652
|
-
{
|
653
|
-
name: "item to index out of bounds of array",
|
654
|
-
input: `["foo", "bar"]`,
|
655
|
-
from: ["0"],
|
656
|
-
path: ["2"],
|
657
|
-
expected: result.err(PatchError),
|
658
|
-
},
|
659
|
-
{
|
660
|
-
name: "val.file to root of document",
|
661
|
-
input: `{ foo: null, baz: val.file("/public/val/foo/bar.jpg") }`,
|
662
|
-
from: ["baz"],
|
663
|
-
path: ["bar"],
|
664
|
-
expected: result.ok(
|
665
|
-
`{ foo: null, bar: val.file("/public/val/foo/bar.jpg") }`
|
666
|
-
),
|
667
|
-
},
|
668
|
-
{
|
669
|
-
name: "ref out of val.file",
|
670
|
-
input: `{ foo: null, baz: val.file("/public/val/foo/bar.jpg") }`,
|
671
|
-
from: ["baz", "_ref"],
|
672
|
-
path: ["bar"],
|
673
|
-
expected: result.err(PatchError),
|
674
|
-
},
|
675
|
-
{
|
676
|
-
name: "object into val.file",
|
677
|
-
input: `{ foo: { bar: "zoo" }, baz: val.file("/public/val/foo/bar.jpg") }`,
|
678
|
-
from: ["foo"],
|
679
|
-
path: ["baz", "metadata"],
|
680
|
-
expected: result.ok(
|
681
|
-
`{ baz: val.file("/public/val/foo/bar.jpg", { bar: "zoo" }) }`
|
682
|
-
),
|
683
|
-
},
|
684
|
-
])("move $name", ({ input, from, path, expected }) => {
|
685
|
-
const src = testSourceFile(input);
|
686
|
-
const ops = new TSOps(findRoot);
|
687
|
-
expect(ops.move(src, from, path)).toEqual(
|
688
|
-
pipe(
|
689
|
-
expected,
|
690
|
-
result.map(testSourceFile),
|
691
|
-
result.mapErr((errorType) => expect.any(errorType))
|
692
|
-
)
|
693
|
-
);
|
694
|
-
});
|
695
|
-
|
696
|
-
test.each<{
|
697
|
-
name: string;
|
698
|
-
input: string;
|
699
|
-
from: string[];
|
700
|
-
path: string[];
|
701
|
-
expected: result.Result<string, typeof PatchError | typeof ValSyntaxError>;
|
702
|
-
}>([
|
703
|
-
{
|
704
|
-
name: "object into itself",
|
705
|
-
input: `{ foo: "bar" }`,
|
706
|
-
from: [],
|
707
|
-
path: ["foo"],
|
708
|
-
expected: result.ok(`{ foo: { foo: "bar" } }`),
|
709
|
-
},
|
710
|
-
{
|
711
|
-
name: "value to root of document",
|
712
|
-
input: `{ foo: "bar" }`,
|
713
|
-
from: ["foo"],
|
714
|
-
path: [],
|
715
|
-
expected: result.ok(`"bar"`),
|
716
|
-
},
|
717
|
-
{
|
718
|
-
name: "defined property to undefined property of object",
|
719
|
-
input: `{ foo: null, baz: 1 }`,
|
720
|
-
from: ["foo"],
|
721
|
-
path: ["bar"],
|
722
|
-
expected: result.ok(`{ foo: null, baz: 1, bar: null }`),
|
723
|
-
},
|
724
|
-
{
|
725
|
-
name: "defined property to defined property of object",
|
726
|
-
input: `{ foo: null, bar: "baz" }`,
|
727
|
-
from: ["foo"],
|
728
|
-
path: ["bar"],
|
729
|
-
expected: result.ok(`{ foo: null, bar: null }`),
|
730
|
-
},
|
731
|
-
{
|
732
|
-
name: "undefined property of object",
|
733
|
-
input: `{ foo: "bar" }`,
|
734
|
-
from: ["bar"],
|
735
|
-
path: ["baz"],
|
736
|
-
expected: result.err(PatchError),
|
737
|
-
},
|
738
|
-
{
|
739
|
-
name: "item within array",
|
740
|
-
input: `["foo", null]`,
|
741
|
-
from: ["1"],
|
742
|
-
path: ["0"],
|
743
|
-
expected: result.ok(`[null, "foo", null]`),
|
744
|
-
},
|
745
|
-
{
|
746
|
-
name: "item to end of array with dash",
|
747
|
-
input: `[null, "foo"]`,
|
748
|
-
from: ["0"],
|
749
|
-
path: ["-"],
|
750
|
-
expected: result.ok(`[null, "foo", null]`),
|
751
|
-
},
|
752
|
-
{
|
753
|
-
name: "item from invalid index of array",
|
754
|
-
input: `["foo", "bar"]`,
|
755
|
-
from: ["foo"],
|
756
|
-
path: ["0"],
|
757
|
-
expected: result.err(PatchError),
|
758
|
-
},
|
759
|
-
{
|
760
|
-
name: "item to invalid index of array",
|
761
|
-
input: `["foo", "bar"]`,
|
762
|
-
from: ["1"],
|
763
|
-
path: ["foo"],
|
764
|
-
expected: result.err(PatchError),
|
765
|
-
},
|
766
|
-
{
|
767
|
-
name: "item from index out of bounds of array",
|
768
|
-
input: `["foo", "bar"]`,
|
769
|
-
from: ["2"],
|
770
|
-
path: ["0"],
|
771
|
-
expected: result.err(PatchError),
|
772
|
-
},
|
773
|
-
{
|
774
|
-
name: "item to index out of bounds of array",
|
775
|
-
input: `["foo", "bar"]`,
|
776
|
-
from: ["0"],
|
777
|
-
path: ["3"],
|
778
|
-
expected: result.err(PatchError),
|
779
|
-
},
|
780
|
-
{
|
781
|
-
name: "val.file to root of object",
|
782
|
-
input: `{ foo: val.file("/public/val/image1.jpg") }`,
|
783
|
-
from: ["foo"],
|
784
|
-
path: [],
|
785
|
-
expected: result.ok(`val.file("/public/val/image1.jpg")`),
|
786
|
-
},
|
787
|
-
{
|
788
|
-
name: "object into val.file",
|
789
|
-
input: `{ foo: val.file("/public/val/image1.jpg"), bar: null }`,
|
790
|
-
from: ["bar"],
|
791
|
-
path: ["foo", "metadata"],
|
792
|
-
expected: result.ok(
|
793
|
-
`{ foo: val.file("/public/val/image1.jpg", null), bar: null }`
|
794
|
-
),
|
795
|
-
},
|
796
|
-
])("copy $name", ({ input, from, path, expected }) => {
|
797
|
-
const src = testSourceFile(input);
|
798
|
-
const ops = new TSOps(findRoot);
|
799
|
-
expect(ops.copy(src, from, path)).toEqual(
|
800
|
-
pipe(expected, result.map(testSourceFile), result.mapErr(expect.any))
|
801
|
-
);
|
802
|
-
});
|
803
|
-
|
804
|
-
test.each<{
|
805
|
-
name: string;
|
806
|
-
input: string;
|
807
|
-
path: string[];
|
808
|
-
value: JSONValue;
|
809
|
-
expected: result.Result<boolean, typeof PatchError | typeof ValSyntaxError>;
|
810
|
-
}>([
|
811
|
-
{
|
812
|
-
name: "object 1",
|
813
|
-
input: `{ foo: "bar" }`,
|
814
|
-
path: [],
|
815
|
-
value: { foo: "bar" },
|
816
|
-
expected: result.ok(true),
|
817
|
-
},
|
818
|
-
{
|
819
|
-
name: "object 2",
|
820
|
-
input: `{ foo: "bar" }`,
|
821
|
-
path: [],
|
822
|
-
value: null,
|
823
|
-
expected: result.ok(false),
|
824
|
-
},
|
825
|
-
{
|
826
|
-
name: "array 1",
|
827
|
-
input: `["foo", "bar"]`,
|
828
|
-
path: [],
|
829
|
-
value: ["foo", "bar"],
|
830
|
-
expected: result.ok(true),
|
831
|
-
},
|
832
|
-
{
|
833
|
-
name: "array 2",
|
834
|
-
input: `["foo", "bar"]`,
|
835
|
-
path: [],
|
836
|
-
value: ["bar", "foo"],
|
837
|
-
expected: result.ok(false),
|
838
|
-
},
|
839
|
-
{
|
840
|
-
name: "defined property from object",
|
841
|
-
input: `{ foo: "bar", bar: "baz" }`,
|
842
|
-
path: ["bar"],
|
843
|
-
value: "baz",
|
844
|
-
expected: result.ok(true),
|
845
|
-
},
|
846
|
-
{
|
847
|
-
name: "undefined property of object",
|
848
|
-
input: `{ foo: "bar" }`,
|
849
|
-
path: ["bar"],
|
850
|
-
value: null,
|
851
|
-
expected: result.err(PatchError),
|
852
|
-
},
|
853
|
-
{
|
854
|
-
name: "item from array",
|
855
|
-
input: `["foo", "bar"]`,
|
856
|
-
path: ["0"],
|
857
|
-
value: "foo",
|
858
|
-
expected: result.ok(true),
|
859
|
-
},
|
860
|
-
{
|
861
|
-
name: "item from end of array with dash",
|
862
|
-
input: `["foo", "bar"]`,
|
863
|
-
path: ["-"],
|
864
|
-
value: null,
|
865
|
-
expected: result.err(PatchError),
|
866
|
-
},
|
867
|
-
{
|
868
|
-
name: "item at index out of bounds of array",
|
869
|
-
input: `["foo", "bar"]`,
|
870
|
-
path: ["2"],
|
871
|
-
value: null,
|
872
|
-
expected: result.err(PatchError),
|
873
|
-
},
|
874
|
-
{
|
875
|
-
name: "item from array with invalid index",
|
876
|
-
input: `["foo", "bar"]`,
|
877
|
-
path: ["baz"],
|
878
|
-
value: null,
|
879
|
-
expected: result.err(PatchError),
|
880
|
-
},
|
881
|
-
{
|
882
|
-
name: "complex nested objects",
|
883
|
-
input: `{ foo: { bar: "baz", baz: ["bar", { 0: 1}] } }`,
|
884
|
-
path: [],
|
885
|
-
value: { foo: { bar: "baz", baz: ["bar", { 0: 1 }] } },
|
886
|
-
expected: result.ok(true),
|
887
|
-
},
|
888
|
-
{
|
889
|
-
name: "at undefined object/array",
|
890
|
-
input: `{ foo: "bar" }`,
|
891
|
-
path: ["bar", "foo"],
|
892
|
-
value: null,
|
893
|
-
expected: result.err(PatchError),
|
894
|
-
},
|
895
|
-
{
|
896
|
-
name: "escaped paths",
|
897
|
-
input: `{ "foo/bar~/~": "baz" }`,
|
898
|
-
path: ["foo/bar~/~"],
|
899
|
-
value: "baz",
|
900
|
-
expected: result.ok(true),
|
901
|
-
},
|
902
|
-
{
|
903
|
-
name: "at non-object/array",
|
904
|
-
input: `0`,
|
905
|
-
path: ["foo"],
|
906
|
-
value: null,
|
907
|
-
expected: result.err(PatchError),
|
908
|
-
},
|
909
|
-
{
|
910
|
-
name: "val.file ref",
|
911
|
-
input: `val.file("/public/val/foo/bar.jpg")`,
|
912
|
-
path: ["_ref"],
|
913
|
-
value: "/public/val/foo/bar.jpg",
|
914
|
-
expected: result.ok(true),
|
915
|
-
},
|
916
|
-
{
|
917
|
-
name: "val.file",
|
918
|
-
input: `val.file("/public/val/foo/bar.jpg")`,
|
919
|
-
path: [],
|
920
|
-
value: { _ref: "/public/val/foo/bar.jpg", _type: "file" },
|
921
|
-
expected: result.ok(true),
|
922
|
-
},
|
923
|
-
{
|
924
|
-
name: "nested val.file",
|
925
|
-
input: `{ foo: { bar: val.file("/public/val/foo/bar/zoo.jpg") } }`,
|
926
|
-
path: ["foo", "bar", "_ref"],
|
927
|
-
value: "/public/val/foo/bar/zoo.jpg",
|
928
|
-
expected: result.ok(true),
|
929
|
-
},
|
930
|
-
])("test $name", ({ input, path, value, expected }) => {
|
931
|
-
const src = testSourceFile(input);
|
932
|
-
const ops = new TSOps(findRoot);
|
933
|
-
expect(ops.test(src, path, value)).toEqual(
|
934
|
-
pipe(expected, result.mapErr(expect.any))
|
935
|
-
);
|
936
|
-
});
|
937
|
-
});
|