@embeddable.com/sdk-core 4.1.3 → 4.1.4-next.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/lib/index.esm.js +2 -1
- package/lib/index.esm.js.map +1 -1
- package/package.json +2 -2
- package/src/buildGlobalHooks.ts +1 -1
- package/src/validate.test.ts +218 -1
- package/src/validate.ts +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@embeddable.com/sdk-core",
|
|
3
|
-
"version": "4.1.
|
|
3
|
+
"version": "4.1.4-next.0",
|
|
4
4
|
"description": "Core Embeddable SDK module responsible for web-components bundling and publishing.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"embeddable",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
},
|
|
41
41
|
"license": "MIT",
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@embeddable.com/core": "2.13.0",
|
|
43
|
+
"@embeddable.com/core": "2.13.1-next.0",
|
|
44
44
|
"@embeddable.com/sdk-utils": "0.8.2",
|
|
45
45
|
"@inquirer/prompts": "^7.2.1",
|
|
46
46
|
"@stencil/core": "^4.23.0",
|
package/src/buildGlobalHooks.ts
CHANGED
|
@@ -176,7 +176,7 @@ async function generateTemporaryHookFile(
|
|
|
176
176
|
|
|
177
177
|
const newContent = templateContent
|
|
178
178
|
.replace("{{LIBRARY_THEME_IMPORTS}}", libraryThemeImports.join("\n"))
|
|
179
|
-
.replace("{{ARRAY_OF_LIBRARY_THEME_PROVIDERS}}", functionNames.join("
|
|
179
|
+
.replace("{{ARRAY_OF_LIBRARY_THEME_PROVIDERS}}", functionNames.join(",\n "))
|
|
180
180
|
.replace("{{LOCAL_THEME_IMPORT}}", repoThemeImport);
|
|
181
181
|
|
|
182
182
|
// Write to temporary hook file
|
package/src/validate.test.ts
CHANGED
|
@@ -11,7 +11,9 @@ const startMock = {
|
|
|
11
11
|
};
|
|
12
12
|
|
|
13
13
|
vi.mock("@embeddable.com/sdk-utils", () => ({
|
|
14
|
-
errorFormatter: vi.fn()
|
|
14
|
+
errorFormatter: vi.fn((issues) =>
|
|
15
|
+
issues.map((issue: any) => issue.message || "Validation error")
|
|
16
|
+
),
|
|
15
17
|
findFiles: vi.fn(),
|
|
16
18
|
}));
|
|
17
19
|
|
|
@@ -49,6 +51,34 @@ const clientContextYaml = `
|
|
|
49
51
|
clientContext:
|
|
50
52
|
color: blue`;
|
|
51
53
|
|
|
54
|
+
const clientContextWithVariablesYaml = `
|
|
55
|
+
- name: US
|
|
56
|
+
clientContext:
|
|
57
|
+
theme: default
|
|
58
|
+
locale: en-US
|
|
59
|
+
variables:
|
|
60
|
+
currency: USD
|
|
61
|
+
country: United States`;
|
|
62
|
+
|
|
63
|
+
const clientContextWithEmptyVariablesYaml = `
|
|
64
|
+
- name: UK
|
|
65
|
+
clientContext:
|
|
66
|
+
theme: default
|
|
67
|
+
locale: en-GB
|
|
68
|
+
variables: {}`;
|
|
69
|
+
|
|
70
|
+
const clientContextWithVariousVariableTypesYaml = `
|
|
71
|
+
- name: Complex
|
|
72
|
+
clientContext:
|
|
73
|
+
theme: dark
|
|
74
|
+
variables:
|
|
75
|
+
stringVar: "hello"
|
|
76
|
+
numberVar: 42
|
|
77
|
+
booleanVar: true
|
|
78
|
+
arrayVar: [1, 2, 3]
|
|
79
|
+
objectVar:
|
|
80
|
+
nested: "value"`;
|
|
81
|
+
|
|
52
82
|
vi.mock("ora", () => ({
|
|
53
83
|
default: () => ({
|
|
54
84
|
start: vi.fn().mockImplementation(() => startMock),
|
|
@@ -160,5 +190,192 @@ describe("validate", () => {
|
|
|
160
190
|
'path/to/file: client context with name "blue" already exists',
|
|
161
191
|
]);
|
|
162
192
|
});
|
|
193
|
+
|
|
194
|
+
it("should validate client context with variables field", async () => {
|
|
195
|
+
vi.mocked(fs.readFile).mockImplementation(async () => {
|
|
196
|
+
return clientContextWithVariablesYaml;
|
|
197
|
+
});
|
|
198
|
+
const filesList: [string, string][] = [
|
|
199
|
+
["valid-client-context-with-variables.yaml", "path/to/file"],
|
|
200
|
+
];
|
|
201
|
+
const result = await clientContextValidation(filesList);
|
|
202
|
+
expect(result).toEqual([]);
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
it("should validate client context with empty variables object", async () => {
|
|
206
|
+
vi.mocked(fs.readFile).mockImplementation(async () => {
|
|
207
|
+
return clientContextWithEmptyVariablesYaml;
|
|
208
|
+
});
|
|
209
|
+
const filesList: [string, string][] = [
|
|
210
|
+
["valid-client-context-empty-variables.yaml", "path/to/file"],
|
|
211
|
+
];
|
|
212
|
+
const result = await clientContextValidation(filesList);
|
|
213
|
+
expect(result).toEqual([]);
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
it("should validate client context with various variable types", async () => {
|
|
217
|
+
vi.mocked(fs.readFile).mockImplementation(async () => {
|
|
218
|
+
return clientContextWithVariousVariableTypesYaml;
|
|
219
|
+
});
|
|
220
|
+
const filesList: [string, string][] = [
|
|
221
|
+
["valid-client-context-various-types.yaml", "path/to/file"],
|
|
222
|
+
];
|
|
223
|
+
const result = await clientContextValidation(filesList);
|
|
224
|
+
expect(result).toEqual([]);
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
it("should validate client context without variables field (backward compatibility)", async () => {
|
|
228
|
+
vi.mocked(fs.readFile).mockImplementation(async () => {
|
|
229
|
+
return clientContextYaml;
|
|
230
|
+
});
|
|
231
|
+
const filesList: [string, string][] = [
|
|
232
|
+
["valid-client-context-no-variables.yaml", "path/to/file"],
|
|
233
|
+
];
|
|
234
|
+
const result = await clientContextValidation(filesList);
|
|
235
|
+
expect(result).toEqual([]);
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
it("should reject client context with variables as non-object type", async () => {
|
|
239
|
+
const invalidYaml = `
|
|
240
|
+
- name: Invalid
|
|
241
|
+
clientContext:
|
|
242
|
+
theme: default
|
|
243
|
+
variables: "not an object"`;
|
|
244
|
+
|
|
245
|
+
vi.mocked(fs.readFile).mockImplementation(async () => {
|
|
246
|
+
return invalidYaml;
|
|
247
|
+
});
|
|
248
|
+
const filesList: [string, string][] = [
|
|
249
|
+
["invalid-variables-type.yaml", "path/to/file"],
|
|
250
|
+
];
|
|
251
|
+
const result = await clientContextValidation(filesList);
|
|
252
|
+
expect(result.length).toBeGreaterThan(0);
|
|
253
|
+
expect(result[0]).toContain("path/to/file");
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
it("should reject client context with variables as array", async () => {
|
|
257
|
+
const invalidYaml = `
|
|
258
|
+
- name: Invalid
|
|
259
|
+
clientContext:
|
|
260
|
+
theme: default
|
|
261
|
+
variables:
|
|
262
|
+
- item1
|
|
263
|
+
- item2`;
|
|
264
|
+
|
|
265
|
+
vi.mocked(fs.readFile).mockImplementation(async () => {
|
|
266
|
+
return invalidYaml;
|
|
267
|
+
});
|
|
268
|
+
const filesList: [string, string][] = [
|
|
269
|
+
["invalid-variables-array.yaml", "path/to/file"],
|
|
270
|
+
];
|
|
271
|
+
const result = await clientContextValidation(filesList);
|
|
272
|
+
expect(result.length).toBeGreaterThan(0);
|
|
273
|
+
expect(result[0]).toContain("path/to/file");
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
it("should validate client context with variables containing null values", async () => {
|
|
277
|
+
const yamlWithNull = `
|
|
278
|
+
- name: WithNull
|
|
279
|
+
clientContext:
|
|
280
|
+
theme: default
|
|
281
|
+
variables:
|
|
282
|
+
nullableVar: null
|
|
283
|
+
stringVar: "value"`;
|
|
284
|
+
|
|
285
|
+
vi.mocked(fs.readFile).mockImplementation(async () => {
|
|
286
|
+
return yamlWithNull;
|
|
287
|
+
});
|
|
288
|
+
const filesList: [string, string][] = [
|
|
289
|
+
["valid-with-null.yaml", "path/to/file"],
|
|
290
|
+
];
|
|
291
|
+
const result = await clientContextValidation(filesList);
|
|
292
|
+
expect(result).toEqual([]);
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
it("should validate multiple client contexts with variables in same file", async () => {
|
|
296
|
+
const multipleContextsYaml = `
|
|
297
|
+
- name: US
|
|
298
|
+
clientContext:
|
|
299
|
+
theme: default
|
|
300
|
+
variables:
|
|
301
|
+
currency: USD
|
|
302
|
+
- name: UK
|
|
303
|
+
clientContext:
|
|
304
|
+
theme: default
|
|
305
|
+
variables:
|
|
306
|
+
currency: GBP`;
|
|
307
|
+
|
|
308
|
+
vi.mocked(fs.readFile).mockImplementation(async () => {
|
|
309
|
+
return multipleContextsYaml;
|
|
310
|
+
});
|
|
311
|
+
const filesList: [string, string][] = [
|
|
312
|
+
["multiple-contexts.yaml", "path/to/file"],
|
|
313
|
+
];
|
|
314
|
+
const result = await clientContextValidation(filesList);
|
|
315
|
+
expect(result).toEqual([]);
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
it("should validate client context with variables having special characters in keys", async () => {
|
|
319
|
+
const yamlWithSpecialKeys = `
|
|
320
|
+
- name: SpecialKeys
|
|
321
|
+
clientContext:
|
|
322
|
+
theme: default
|
|
323
|
+
variables:
|
|
324
|
+
"key-with-dashes": "value1"
|
|
325
|
+
"key_with_underscores": "value2"
|
|
326
|
+
"key.with.dots": "value3"
|
|
327
|
+
"key with spaces": "value4"`;
|
|
328
|
+
|
|
329
|
+
vi.mocked(fs.readFile).mockImplementation(async () => {
|
|
330
|
+
return yamlWithSpecialKeys;
|
|
331
|
+
});
|
|
332
|
+
const filesList: [string, string][] = [
|
|
333
|
+
["special-keys.yaml", "path/to/file"],
|
|
334
|
+
];
|
|
335
|
+
const result = await clientContextValidation(filesList);
|
|
336
|
+
expect(result).toEqual([]);
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
it("should validate client context with deeply nested variables", async () => {
|
|
340
|
+
const yamlWithNested = `
|
|
341
|
+
- name: Nested
|
|
342
|
+
clientContext:
|
|
343
|
+
theme: default
|
|
344
|
+
variables:
|
|
345
|
+
level1:
|
|
346
|
+
level2:
|
|
347
|
+
level3: "deep value"
|
|
348
|
+
array: [1, 2, 3]
|
|
349
|
+
simple: "value"`;
|
|
350
|
+
|
|
351
|
+
vi.mocked(fs.readFile).mockImplementation(async () => {
|
|
352
|
+
return yamlWithNested;
|
|
353
|
+
});
|
|
354
|
+
const filesList: [string, string][] = [
|
|
355
|
+
["nested-variables.yaml", "path/to/file"],
|
|
356
|
+
];
|
|
357
|
+
const result = await clientContextValidation(filesList);
|
|
358
|
+
expect(result).toEqual([]);
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
it("should validate client context with variables and canvas together", async () => {
|
|
362
|
+
const yamlWithBoth = `
|
|
363
|
+
- name: Complete
|
|
364
|
+
clientContext:
|
|
365
|
+
theme: default
|
|
366
|
+
variables:
|
|
367
|
+
currency: USD
|
|
368
|
+
canvas:
|
|
369
|
+
width: 800`;
|
|
370
|
+
|
|
371
|
+
vi.mocked(fs.readFile).mockImplementation(async () => {
|
|
372
|
+
return yamlWithBoth;
|
|
373
|
+
});
|
|
374
|
+
const filesList: [string, string][] = [
|
|
375
|
+
["complete-context.yaml", "path/to/file"],
|
|
376
|
+
];
|
|
377
|
+
const result = await clientContextValidation(filesList);
|
|
378
|
+
expect(result).toEqual([]);
|
|
379
|
+
});
|
|
163
380
|
});
|
|
164
381
|
});
|
package/src/validate.ts
CHANGED
|
@@ -237,6 +237,7 @@ const clientContextSchema = z.array(
|
|
|
237
237
|
.object({
|
|
238
238
|
name: z.string(),
|
|
239
239
|
clientContext: z.object({}), // can be any object
|
|
240
|
+
variables: z.record(z.any()).optional(), // variables key-value pairs
|
|
240
241
|
canvas: z.object({}).optional(),
|
|
241
242
|
})
|
|
242
243
|
.strict(),
|