@embeddable.com/sdk-core 3.13.0-next.2 → 3.13.0-next.3

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/push.d.ts CHANGED
@@ -1,14 +1,25 @@
1
+ import { ResolvedEmbeddableConfig } from "./defineConfig";
1
2
  export declare const CUBE_FILES: RegExp;
2
3
  export declare const PRESET_FILES: RegExp;
3
4
  declare const _default: () => Promise<void>;
4
5
  export default _default;
5
- export declare function archive(ctx: any, yamlFiles: [string, string][], isDev?: boolean): Promise<unknown>;
6
- export declare function sendBuildByApiKey(ctx: any, { apiKey, email, message }: any): Promise<{
6
+ export declare function buildArchive(config: ResolvedEmbeddableConfig): Promise<import("ora").Ora>;
7
+ export declare function archive(args: {
8
+ ctx: ResolvedEmbeddableConfig;
9
+ filesList: [string, string][];
10
+ isDev: boolean;
11
+ includeComponents: boolean;
12
+ }): Promise<unknown>;
13
+ export declare function sendBuildByApiKey(ctx: ResolvedEmbeddableConfig, { apiKey, email, message, }: {
14
+ apiKey: string;
15
+ email: string;
16
+ message?: string;
17
+ }): Promise<{
7
18
  bundleId: any;
8
- email: any;
9
- message: any;
19
+ email: string;
20
+ message: string | undefined;
10
21
  }>;
11
- export declare function sendBuild(ctx: any, { workspaceId, token }: {
22
+ export declare function sendBuild(ctx: ResolvedEmbeddableConfig, { workspaceId, token }: {
12
23
  workspaceId: string;
13
24
  token: string;
14
25
  }): Promise<void>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@embeddable.com/sdk-core",
3
- "version": "3.13.0-next.2",
3
+ "version": "3.13.0-next.3",
4
4
  "description": "Core Embeddable SDK module responsible for web-components bundling and publishing.",
5
5
  "keywords": [
6
6
  "embeddable",
@@ -35,7 +35,7 @@ describe("defineConfig", () => {
35
35
  vi.mocked(path.resolve).mockReturnValue(coreRoot);
36
36
 
37
37
  vi.spyOn(process, "cwd").mockReturnValue(
38
- "/embeddable-sdk/packages/core-sdk",
38
+ "/embeddable-sdk/packages/core-sdk"
39
39
  );
40
40
  });
41
41
 
@@ -75,11 +75,29 @@ describe("defineConfig", () => {
75
75
  "plugins": [],
76
76
  "previewBaseUrl": "previewBaseUrl",
77
77
  "pushBaseUrl": "pushBaseUrl",
78
+ "pushComponents": true,
79
+ "pushModels": true,
78
80
  "rollbarAccessToken": "rollbarAccessToken",
79
81
  }
80
82
  `);
81
83
  });
82
84
 
85
+ it("throws error for invalid property", () => {
86
+ expect(() =>
87
+ defineConfig({ plugins: [], invalidProp: "INVALID" as any } as any)
88
+ ).toThrow(
89
+ `Invalid Embeddable Configuration: "": Unrecognized key(s) in object: 'invalidProp'}`
90
+ );
91
+ });
92
+
93
+ it("throws error for invalid property value", () => {
94
+ expect(() =>
95
+ defineConfig({ plugins: [], pushBaseUrl: 123 as any } as any)
96
+ ).toThrow(
97
+ `Invalid Embeddable Configuration: "pushBaseUrl": Expected string, received number}`
98
+ );
99
+ });
100
+
83
101
  describe("region configuration", () => {
84
102
  it("uses legacy-US region by default", () => {
85
103
  const config = defineConfig({ plugins: [] });
@@ -129,10 +147,46 @@ describe("defineConfig", () => {
129
147
 
130
148
  it("throws error for invalid region", () => {
131
149
  expect(() =>
132
- defineConfig({ plugins: [], region: "INVALID" as any }),
150
+ defineConfig({ plugins: [], region: "INVALID" as any })
133
151
  ).toThrow(
134
- "Unsupported region: INVALID. Supported regions are: EU, US, legacy-US",
152
+ `Invalid Embeddable Configuration: "region": Invalid literal value, expected "legacy-US"}`
135
153
  );
136
154
  });
137
155
  });
156
+
157
+ describe("push configuration", () => {
158
+ it("defaults pushModels and pushComponents to true", () => {
159
+ const config = defineConfig({ plugins: [] });
160
+ expect(config.pushModels).toBe(true);
161
+ expect(config.pushComponents).toBe(true);
162
+ });
163
+
164
+ it("allows overriding pushModels and pushComponents", () => {
165
+ const config = defineConfig({
166
+ plugins: [],
167
+ pushModels: false,
168
+ pushComponents: false,
169
+ });
170
+ expect(config.pushModels).toBe(false);
171
+ expect(config.pushComponents).toBe(false);
172
+ });
173
+
174
+ it("allows mixed configuration of pushModels and pushComponents", () => {
175
+ const configModelOnly = defineConfig({
176
+ plugins: [],
177
+ pushModels: true,
178
+ pushComponents: false,
179
+ });
180
+ expect(configModelOnly.pushModels).toBe(true);
181
+ expect(configModelOnly.pushComponents).toBe(false);
182
+
183
+ const configComponentOnly = defineConfig({
184
+ plugins: [],
185
+ pushModels: false,
186
+ pushComponents: true,
187
+ });
188
+ expect(configComponentOnly.pushModels).toBe(false);
189
+ expect(configComponentOnly.pushComponents).toBe(true);
190
+ });
191
+ });
138
192
  });
@@ -1,6 +1,8 @@
1
1
  import * as path from "node:path";
2
2
  import { existsSync } from "node:fs";
3
3
  import { RollupOptions } from "rollup";
4
+ import { z } from "zod";
5
+ import { errorFormatter } from "@embeddable.com/sdk-utils";
4
6
 
5
7
  export type Region = "EU" | "US" | "legacy-US";
6
8
 
@@ -11,6 +13,8 @@ export type EmbeddableConfig = {
11
13
  cleanup: (config: EmbeddableConfig) => Promise<unknown>;
12
14
  validate: (config: EmbeddableConfig) => Promise<unknown>;
13
15
  })[];
16
+ pushModels?: boolean;
17
+ pushComponents?: boolean;
14
18
  pushBaseUrl?: string;
15
19
  audienceUrl?: string;
16
20
  authDomain?: string;
@@ -32,6 +36,47 @@ export type EmbeddableConfig = {
32
36
  region?: Region;
33
37
  };
34
38
 
39
+ export type ResolvedEmbeddableConfig = {
40
+ core: {
41
+ rootDir: string;
42
+ templatesDir: string;
43
+ configsDir: string;
44
+ };
45
+ client: {
46
+ rootDir: string;
47
+ srcDir: string;
48
+ modelsSrc?: string;
49
+ presetsSrc?: string;
50
+ buildDir: string;
51
+ tmpDir: string;
52
+ globalCss: string;
53
+ componentDir: string;
54
+ stencilBuild: string;
55
+ archiveFile: string;
56
+ errorFallbackComponent?: string;
57
+ bundleHash?: string;
58
+ viteConfig: {
59
+ resolve?: {
60
+ alias?: Record<string, string>;
61
+ };
62
+ };
63
+ rollupOptions: RollupOptions;
64
+ };
65
+ outputOptions: {
66
+ typesEntryPointFilename: string;
67
+ };
68
+ pushModels: boolean;
69
+ pushComponents: boolean;
70
+ pushBaseUrl: string;
71
+ audienceUrl: string;
72
+ previewBaseUrl: string;
73
+ authDomain: string;
74
+ authClientId: string;
75
+ applicationEnvironment: string;
76
+ rollbarAccessToken: string;
77
+ plugins: EmbeddableConfig["plugins"];
78
+ };
79
+
35
80
  const REGION_CONFIGS = {
36
81
  EU: {
37
82
  pushBaseUrl: "https://api.eu.embeddable.com",
@@ -56,30 +101,74 @@ const REGION_CONFIGS = {
56
101
  },
57
102
  };
58
103
 
59
- export default ({
60
- plugins,
61
- region = "legacy-US",
62
- pushBaseUrl,
63
- audienceUrl,
64
- authDomain,
65
- authClientId,
66
- errorFallbackComponent,
67
- applicationEnvironment,
68
- rollbarAccessToken,
69
- previewBaseUrl,
70
- modelsSrc = "src",
71
- presetsSrc = "src",
72
- componentsSrc = "src",
73
- globalCss = "src/global.css",
74
- viteConfig = {},
75
- rollupOptions = {},
76
- }: EmbeddableConfig) => {
77
- if (region && !REGION_CONFIGS[region]) {
78
- throw new Error(
79
- `Unsupported region: ${region}. Supported regions are: ${Object.keys(REGION_CONFIGS).join(", ")}`,
80
- );
104
+ export const embeddableConfigSchema = z
105
+ .object({
106
+ plugins: z.array(z.function()),
107
+ region: z
108
+ .union([z.literal("EU"), z.literal("US"), z.literal("legacy-US")])
109
+ .optional(),
110
+ pushModels: z.boolean().optional(),
111
+ pushComponents: z.boolean().optional(),
112
+ pushBaseUrl: z.string().optional(),
113
+ audienceUrl: z.string().optional(),
114
+ authDomain: z.string().optional(),
115
+ authClientId: z.string().optional(),
116
+ errorFallbackComponent: z.string().optional(),
117
+ applicationEnvironment: z.string().optional(),
118
+ rollbarAccessToken: z.string().optional(),
119
+ previewBaseUrl: z.string().optional(),
120
+ modelsSrc: z.string().optional(),
121
+ presetsSrc: z.string().optional(),
122
+ componentsSrc: z.string().optional(),
123
+ globalCss: z.string().optional(),
124
+ viteConfig: z
125
+ .object({
126
+ resolve: z
127
+ .object({
128
+ alias: z.record(z.string()),
129
+ })
130
+ .optional(),
131
+ })
132
+ .optional(),
133
+ rollupOptions: z.object({}).optional(),
134
+ })
135
+ .strict();
136
+
137
+ export default (config: EmbeddableConfig) => {
138
+ const safeParse = embeddableConfigSchema.safeParse(config);
139
+
140
+ const errors: string[] = [];
141
+ if (!safeParse.success) {
142
+ errorFormatter(safeParse.error.issues).forEach((error) => {
143
+ errors.push(`${error}`);
144
+ });
145
+ }
146
+
147
+ if (errors.length > 0) {
148
+ throw new Error(`Invalid Embeddable Configuration: ${errors.join("\n")}}`);
81
149
  }
82
150
 
151
+ let {
152
+ plugins,
153
+ region = "legacy-US",
154
+ pushModels = true,
155
+ pushComponents = true,
156
+ pushBaseUrl,
157
+ audienceUrl,
158
+ authDomain,
159
+ authClientId,
160
+ errorFallbackComponent,
161
+ applicationEnvironment,
162
+ rollbarAccessToken,
163
+ previewBaseUrl,
164
+ modelsSrc = "src",
165
+ presetsSrc = "src",
166
+ componentsSrc = "src",
167
+ globalCss = "src/global.css",
168
+ viteConfig = {},
169
+ rollupOptions = {},
170
+ } = config;
171
+
83
172
  const regionConfig = REGION_CONFIGS[region];
84
173
 
85
174
  const __dirname = import.meta.dirname;
@@ -145,6 +234,8 @@ export default ({
145
234
  outputOptions: {
146
235
  typesEntryPointFilename: "embeddable-types-entry-point.js",
147
236
  },
237
+ pushModels,
238
+ pushComponents,
148
239
  pushBaseUrl: pushBaseUrl ?? regionConfig.pushBaseUrl,
149
240
  audienceUrl: audienceUrl ?? regionConfig.audienceUrl,
150
241
  previewBaseUrl: previewBaseUrl ?? regionConfig.previewBaseUrl,
package/src/dev.ts CHANGED
@@ -26,20 +26,21 @@ import validate from "./validate";
26
26
  import { checkNodeVersion } from "./utils";
27
27
  import { createManifest } from "./cleanup";
28
28
  import { selectWorkspace } from "./workspaceUtils";
29
- import * as fs from "node:fs/promises";
30
- import minimist from "minimist";
29
+ import * as fs from "fs";
30
+ const minimist = require("minimist");
31
31
  import { initLogger, logError } from "./logger";
32
32
  import fg from "fast-glob";
33
33
  import * as dotenv from "dotenv";
34
- import ora from "ora";
35
- import finalhandler from "finalhandler";
36
- import serveStatic from "serve-static";
34
+ import { pathToFileURL } from "node:url";
35
+
37
36
  dotenv.config();
38
37
 
38
+ const oraP = import("ora");
39
39
  let wss: WSServer;
40
40
  let changedFiles: string[] = [];
41
41
  let browserWindow: ChildProcess | null = null;
42
42
 
43
+ let ora: any;
43
44
  let previewWorkspace: string;
44
45
 
45
46
  const SERVER_PORT = 8926;
@@ -52,6 +53,7 @@ const buildWebComponent = async (config: any) => {
52
53
 
53
54
  const addToGitingore = async () => {
54
55
  try {
56
+ const fs = require("fs").promises;
55
57
  const gitignorePath = path.resolve(process.cwd(), ".gitignore");
56
58
  const gitignoreContent = await fs.readFile(gitignorePath, "utf8");
57
59
 
@@ -81,6 +83,8 @@ export default async () => {
81
83
  checkNodeVersion();
82
84
  addToGitingore();
83
85
 
86
+ ora = (await oraP).default;
87
+
84
88
  process.on("warning", (e) => console.warn(e.stack));
85
89
 
86
90
  const logger = createNodeLogger();
@@ -112,6 +116,9 @@ export default async () => {
112
116
  breadcrumbs.push("prepare config");
113
117
  await prepare(config);
114
118
 
119
+ const finalhandler = require("finalhandler");
120
+ const serveStatic = require("serve-static");
121
+
115
122
  const serve = serveStatic(config.client.buildDir);
116
123
 
117
124
  let workspacePreparation = ora("Preparing workspace...").start();
@@ -142,7 +149,7 @@ export default async () => {
142
149
  workspacePreparation.succeed("Workspace is ready");
143
150
 
144
151
  const server = http.createServer(
145
- async (request: IncomingMessage, res: ServerResponse) => {
152
+ (request: IncomingMessage, res: ServerResponse) => {
146
153
  res.setHeader("Access-Control-Allow-Origin", "*");
147
154
  res.setHeader(
148
155
  "Access-Control-Allow-Methods",
@@ -165,7 +172,7 @@ export default async () => {
165
172
  try {
166
173
  if (request.url?.endsWith(GLOBAL_CSS)) {
167
174
  res.writeHead(200, { "Content-Type": "text/css" });
168
- res.end(await fs.readFile(config.client.globalCss));
175
+ res.end(fs.readFileSync(config.client.globalCss));
169
176
  return;
170
177
  }
171
178
  } catch {}
@@ -339,7 +346,12 @@ const sendDataModelsAndContextsChanges = async (ctx: any) => {
339
346
  path.resolve(ctx.client.buildDir, "embeddable-manifest.json"),
340
347
  ]);
341
348
 
342
- await archive(ctx, filesList, true);
349
+ await archive({
350
+ ctx,
351
+ filesList,
352
+ isDev: true,
353
+ includeComponents: false,
354
+ });
343
355
  await sendBuild(ctx, { workspaceId: previewWorkspace, token });
344
356
  sending.succeed(`Data models and/or security context synchronized`);
345
357
  sendMessage("dataModelsAndOrSecurityContextUpdateSuccess");