@embeddable.com/sdk-core 4.1.3 → 4.1.4

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@embeddable.com/sdk-core",
3
- "version": "4.1.3",
3
+ "version": "4.1.4",
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",
44
44
  "@embeddable.com/sdk-utils": "0.8.2",
45
45
  "@inquirer/prompts": "^7.2.1",
46
46
  "@stencil/core": "^4.23.0",
@@ -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("\n"))
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
@@ -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(),