@embeddable.com/sdk-core 3.2.0-next.9 → 3.2.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/bin/embeddable +1 -1
- package/configs/tsconfig.json +4 -11
- package/lib/defineConfig.d.ts +5 -2
- package/lib/index.esm.js +470 -88
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +470 -88
- package/lib/index.js.map +1 -1
- package/lib/push.d.ts +5 -0
- package/lib/utils.d.ts +7 -0
- package/loader/custom-esm-loader.mjs +1 -1
- package/package.json +3 -3
- package/src/buildTypes.ts +5 -0
- package/src/cleanup.ts +40 -8
- package/src/defineConfig.ts +25 -1
- package/src/entryPoint.js +12 -0
- package/src/generate.ts +17 -0
- package/src/prepare.ts +2 -0
- package/src/push.ts +103 -13
- package/src/utils.ts +22 -0
- package/src/validate.ts +30 -4
- package/templates/component.tsx.template +17 -1
- package/lib/entryPoint.d.ts +0 -1
- package/src/entryPoint.ts +0 -18
package/lib/push.d.ts
CHANGED
|
@@ -2,6 +2,11 @@ export declare const YAML_OR_JS_FILES: RegExp;
|
|
|
2
2
|
declare const _default: () => Promise<void>;
|
|
3
3
|
export default _default;
|
|
4
4
|
export declare function archive(ctx: any, yamlFiles: [string, string][], includeBuild?: boolean): Promise<unknown>;
|
|
5
|
+
export declare function sendBuildByApiKey(ctx: any, { apiKey, email, message }: any): Promise<{
|
|
6
|
+
bundleId: any;
|
|
7
|
+
email: any;
|
|
8
|
+
message: any;
|
|
9
|
+
}>;
|
|
5
10
|
export declare function sendBuild(ctx: any, { workspaceId, token }: {
|
|
6
11
|
workspaceId: string;
|
|
7
12
|
token: string;
|
package/lib/utils.d.ts
CHANGED
|
@@ -1 +1,8 @@
|
|
|
1
1
|
export declare const checkNodeVersion: () => Promise<void>;
|
|
2
|
+
/**
|
|
3
|
+
* Get the value of a process argument by key
|
|
4
|
+
* Example: getArgumentByKey("--email") or getArgumentByKey(["--email", "-e"])
|
|
5
|
+
* @param key The key to search for in the process arguments
|
|
6
|
+
* @returns
|
|
7
|
+
*/
|
|
8
|
+
export declare const getArgumentByKey: (key: string | string[]) => string | undefined;
|
|
@@ -69,7 +69,7 @@ export const resolve = async (specifier, context, nextResolve) => {
|
|
|
69
69
|
const isPackageImport =
|
|
70
70
|
!specifier.startsWith(".") &&
|
|
71
71
|
!specifier.startsWith("/") &&
|
|
72
|
-
|
|
72
|
+
!/^[A-Z]:/.test(specifier); // windows path
|
|
73
73
|
// import/require from external library
|
|
74
74
|
if (
|
|
75
75
|
(context.parentURL.includes("/node_modules/") || isPackageImport) &&
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@embeddable.com/sdk-core",
|
|
3
|
-
"version": "3.2.0
|
|
3
|
+
"version": "3.2.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
|
"@stencil/core": "^4.6.0",
|
|
41
41
|
"@swc-node/register": "^1.9.0",
|
|
42
42
|
"archiver": "^5.3.1",
|
|
43
|
-
"axios": "^1.
|
|
43
|
+
"axios": "^1.7.2",
|
|
44
44
|
"chokidar": "^3.5.3",
|
|
45
45
|
"finalhandler": "^1.2.0",
|
|
46
46
|
"formdata-node": "^6.0.3",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"serve-static": "^1.15.0",
|
|
51
51
|
"sorcery": "^0.11.0",
|
|
52
52
|
"vite": "^4.5.0",
|
|
53
|
-
"ws": "^8.
|
|
53
|
+
"ws": "^8.17.0",
|
|
54
54
|
"yaml": "^2.3.3"
|
|
55
55
|
},
|
|
56
56
|
"lint-staged": {
|
package/src/buildTypes.ts
CHANGED
package/src/cleanup.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { findFiles } from "@embeddable.com/sdk-utils";
|
|
1
2
|
import * as fs from "node:fs/promises";
|
|
2
3
|
import * as path from "node:path";
|
|
3
4
|
|
|
@@ -10,24 +11,55 @@ export default async (ctx: any) => {
|
|
|
10
11
|
};
|
|
11
12
|
|
|
12
13
|
async function extractBuild(ctx: any) {
|
|
14
|
+
const [[, stencilWrapperFilePath]] = await findFiles(
|
|
15
|
+
ctx.client.stencilBuild,
|
|
16
|
+
/embeddable-wrapper.esm-[a-z0-9]+\.js/,
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
const stencilWrapperFileName = path.basename(stencilWrapperFilePath);
|
|
13
20
|
await fs.rename(
|
|
14
21
|
path.resolve(ctx.client.buildDir, ctx.client.stencilBuild),
|
|
15
22
|
ctx.client.tmpDir,
|
|
16
23
|
);
|
|
17
24
|
|
|
18
|
-
await
|
|
19
|
-
|
|
20
|
-
|
|
25
|
+
const [[, typesFilePath]] = await findFiles(
|
|
26
|
+
ctx.client.buildDir,
|
|
27
|
+
/embeddable-types-[a-z0-9]+\.js/,
|
|
21
28
|
);
|
|
22
29
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
30
|
+
const typesFileName = path.basename(typesFilePath);
|
|
31
|
+
await fs.rename(typesFilePath, path.join(ctx.client.tmpDir, typesFileName));
|
|
32
|
+
|
|
33
|
+
const [[, metaFilePath]] = await findFiles(
|
|
34
|
+
ctx.client.buildDir,
|
|
35
|
+
/embeddable-components-meta-[a-z0-9]+\.js/,
|
|
26
36
|
);
|
|
37
|
+
const metaFileName = path.basename(metaFilePath);
|
|
38
|
+
await fs.rename(metaFilePath, path.join(ctx.client.tmpDir, metaFileName));
|
|
27
39
|
|
|
40
|
+
const [[, editorsMetaFilePath]] = await findFiles(
|
|
41
|
+
ctx.client.buildDir,
|
|
42
|
+
/embeddable-editors-meta-[a-z0-9]+\.js/,
|
|
43
|
+
);
|
|
44
|
+
const editorsMetaFileName = path.basename(editorsMetaFilePath);
|
|
28
45
|
await fs.rename(
|
|
29
|
-
|
|
30
|
-
path.join(ctx.client.tmpDir,
|
|
46
|
+
editorsMetaFilePath,
|
|
47
|
+
path.join(ctx.client.tmpDir, editorsMetaFileName),
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
// write manifest file with files with hash
|
|
51
|
+
const manifest = {
|
|
52
|
+
entryFiles: {
|
|
53
|
+
"embeddable-types.js": typesFileName,
|
|
54
|
+
"embeddable-components-meta.js": metaFileName,
|
|
55
|
+
"embeddable-editors-meta.js": editorsMetaFileName,
|
|
56
|
+
"embeddable-wrapper.esm.js": stencilWrapperFileName,
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
await fs.writeFile(
|
|
61
|
+
path.join(ctx.client.tmpDir, "embeddable-manifest.json"),
|
|
62
|
+
JSON.stringify(manifest),
|
|
31
63
|
);
|
|
32
64
|
}
|
|
33
65
|
|
package/src/defineConfig.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as path from "node:path";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
2
3
|
|
|
3
4
|
export type EmbeddableConfig = {
|
|
4
5
|
plugins: (() => {
|
|
@@ -15,6 +16,8 @@ export type EmbeddableConfig = {
|
|
|
15
16
|
applicationEnvironment?: string;
|
|
16
17
|
rollbarAccessToken?: string;
|
|
17
18
|
previewBaseUrl?: string;
|
|
19
|
+
componentsSrc?: string;
|
|
20
|
+
modelsSrc?: string;
|
|
18
21
|
};
|
|
19
22
|
|
|
20
23
|
export default ({
|
|
@@ -27,10 +30,30 @@ export default ({
|
|
|
27
30
|
applicationEnvironment,
|
|
28
31
|
rollbarAccessToken,
|
|
29
32
|
previewBaseUrl,
|
|
33
|
+
modelsSrc,
|
|
34
|
+
componentsSrc = "src",
|
|
30
35
|
}: EmbeddableConfig) => {
|
|
31
36
|
const coreRoot = path.resolve(__dirname, "..");
|
|
32
37
|
const clientRoot = process.cwd();
|
|
33
38
|
|
|
39
|
+
if (!path.isAbsolute(componentsSrc)) {
|
|
40
|
+
componentsSrc = path.resolve(clientRoot, componentsSrc);
|
|
41
|
+
|
|
42
|
+
if (!existsSync(componentsSrc)) {
|
|
43
|
+
throw new Error(
|
|
44
|
+
`componentsSrc directory ${componentsSrc} does not exist`,
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (modelsSrc && !path.isAbsolute(modelsSrc)) {
|
|
50
|
+
modelsSrc = path.resolve(clientRoot, modelsSrc);
|
|
51
|
+
|
|
52
|
+
if (!existsSync(modelsSrc)) {
|
|
53
|
+
throw new Error(`modelsSrc directory ${modelsSrc} does not exist`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
34
57
|
return {
|
|
35
58
|
core: {
|
|
36
59
|
rootDir: coreRoot,
|
|
@@ -39,8 +62,9 @@ export default ({
|
|
|
39
62
|
},
|
|
40
63
|
client: {
|
|
41
64
|
rootDir: clientRoot,
|
|
65
|
+
srcDir: path.resolve(clientRoot, componentsSrc),
|
|
66
|
+
modelsSrc: modelsSrc ? path.resolve(clientRoot, modelsSrc) : undefined,
|
|
42
67
|
buildDir: path.resolve(clientRoot, ".embeddable-build"),
|
|
43
|
-
srcDir: path.resolve(clientRoot, "src"),
|
|
44
68
|
tmpDir: path.resolve(clientRoot, ".embeddable-tmp"),
|
|
45
69
|
componentDir: path.resolve(clientRoot, ".embeddable-build", "component"),
|
|
46
70
|
stencilBuild: path.resolve(
|
package/src/generate.ts
CHANGED
|
@@ -2,6 +2,7 @@ import * as fs from "node:fs/promises";
|
|
|
2
2
|
import * as path from "node:path";
|
|
3
3
|
import { createNodeLogger, createNodeSys } from "@stencil/core/sys/node";
|
|
4
4
|
import { createCompiler, loadConfig } from "@stencil/core/compiler";
|
|
5
|
+
import { getContentHash } from "@embeddable.com/sdk-utils";
|
|
5
6
|
|
|
6
7
|
const sorcery = require("sorcery");
|
|
7
8
|
|
|
@@ -63,12 +64,15 @@ async function runStencil(ctx: any) {
|
|
|
63
64
|
const sys = ctx.dev?.sys || createNodeSys({ process });
|
|
64
65
|
const devMode = !!ctx.dev;
|
|
65
66
|
|
|
67
|
+
const isWindows = process.platform === "win32";
|
|
68
|
+
|
|
66
69
|
const validated = await loadConfig({
|
|
67
70
|
initTsConfig: true,
|
|
68
71
|
logger,
|
|
69
72
|
sys,
|
|
70
73
|
config: {
|
|
71
74
|
devMode,
|
|
75
|
+
maxConcurrentWorkers: isWindows ? 0 : 8, // workers break on windows
|
|
72
76
|
rootDir: ctx.client.buildDir,
|
|
73
77
|
configPath: path.resolve(ctx.client.buildDir, "stencil.config.ts"),
|
|
74
78
|
tsconfig: path.resolve(ctx.client.buildDir, "tsconfig.json"),
|
|
@@ -85,6 +89,19 @@ async function runStencil(ctx: any) {
|
|
|
85
89
|
const compiler = await createCompiler(validated.config);
|
|
86
90
|
|
|
87
91
|
await compiler.build();
|
|
92
|
+
const entryFilePath = path.resolve(
|
|
93
|
+
ctx.client.stencilBuild,
|
|
94
|
+
"embeddable-wrapper.esm.js",
|
|
95
|
+
);
|
|
96
|
+
const entryFileContent = await fs.readFile(entryFilePath, "utf8");
|
|
97
|
+
|
|
98
|
+
const fileHash = getContentHash(entryFileContent);
|
|
99
|
+
|
|
100
|
+
const newFileName = `embeddable-wrapper.esm-${fileHash}.js`;
|
|
101
|
+
await fs.rename(
|
|
102
|
+
entryFilePath,
|
|
103
|
+
path.resolve(ctx.client.stencilBuild, newFileName),
|
|
104
|
+
);
|
|
88
105
|
|
|
89
106
|
await compiler.destroy();
|
|
90
107
|
process.chdir(ctx.client.rootDir);
|
package/src/prepare.ts
CHANGED
|
@@ -12,6 +12,8 @@ export default async (ctx: any) => {
|
|
|
12
12
|
export async function removeIfExists(ctx: any) {
|
|
13
13
|
if (fsSync.existsSync(ctx.client.buildDir))
|
|
14
14
|
await fs.rm(ctx.client.buildDir, { recursive: true });
|
|
15
|
+
if (fsSync.existsSync(ctx.client.tmpDir))
|
|
16
|
+
await fs.rm(ctx.client.tmpDir, { recursive: true });
|
|
15
17
|
}
|
|
16
18
|
|
|
17
19
|
async function copyStencilConfigsToClient(ctx: any) {
|
package/src/push.ts
CHANGED
|
@@ -10,7 +10,7 @@ import reportErrorToRollbar from "./rollbar.mjs";
|
|
|
10
10
|
|
|
11
11
|
import { findFiles } from "@embeddable.com/sdk-utils";
|
|
12
12
|
import { getToken } from "./login";
|
|
13
|
-
import { checkNodeVersion } from "./utils";
|
|
13
|
+
import { checkNodeVersion, getArgumentByKey } from "./utils";
|
|
14
14
|
|
|
15
15
|
// grab .cube.yml|js and .sc.yml|js files
|
|
16
16
|
export const YAML_OR_JS_FILES = /^(.*)\.(cube|sc)\.(ya?ml|js)$/;
|
|
@@ -25,6 +25,15 @@ export default async () => {
|
|
|
25
25
|
|
|
26
26
|
const config = await provideConfig();
|
|
27
27
|
|
|
28
|
+
if (process.argv.includes("--api-key") || process.argv.includes("-k")) {
|
|
29
|
+
spinnerPushing = ora("Using API key...").start();
|
|
30
|
+
await pushByApiKey(config, spinnerPushing);
|
|
31
|
+
|
|
32
|
+
spinnerPushing.succeed("Published using API key");
|
|
33
|
+
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
28
37
|
const token = await verify(config);
|
|
29
38
|
|
|
30
39
|
const { workspaceId, name: workspaceName } = await selectWorkspace(
|
|
@@ -32,29 +41,59 @@ export default async () => {
|
|
|
32
41
|
token,
|
|
33
42
|
);
|
|
34
43
|
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
const filesList = await findFiles(config.client.srcDir, YAML_OR_JS_FILES);
|
|
38
|
-
|
|
39
|
-
await archive(config, filesList);
|
|
40
|
-
spinnerArchive.succeed("Bundling completed");
|
|
44
|
+
const workspacePreviewUrl = `${config.previewBaseUrl}/workspace/${workspaceId}`;
|
|
41
45
|
|
|
46
|
+
await buildArchive(config);
|
|
42
47
|
spinnerPushing = ora(
|
|
43
|
-
`Publishing to ${workspaceName} using ${
|
|
48
|
+
`Publishing to ${workspaceName} using ${workspacePreviewUrl}...`,
|
|
44
49
|
).start();
|
|
45
50
|
|
|
46
51
|
await sendBuild(config, { workspaceId, token });
|
|
47
52
|
spinnerPushing.succeed(
|
|
48
|
-
`Published to ${workspaceName} using ${
|
|
53
|
+
`Published to ${workspaceName} using ${workspacePreviewUrl}`,
|
|
49
54
|
);
|
|
50
55
|
} catch (error: any) {
|
|
51
56
|
spinnerPushing?.fail("Publishing failed");
|
|
52
|
-
|
|
57
|
+
if (error.response?.statusText === "Unauthorized") {
|
|
58
|
+
console.error("Unauthorized. Please check your credentials.");
|
|
59
|
+
} else {
|
|
60
|
+
console.error(error.response?.data || error?.message || error);
|
|
61
|
+
}
|
|
62
|
+
|
|
53
63
|
await reportErrorToRollbar(error);
|
|
54
64
|
process.exit(1);
|
|
55
65
|
}
|
|
56
66
|
};
|
|
57
67
|
|
|
68
|
+
async function pushByApiKey(config: any, spinner: any) {
|
|
69
|
+
const apiKey = getArgumentByKey(["--api-key", "-k"]);
|
|
70
|
+
|
|
71
|
+
if (!apiKey) {
|
|
72
|
+
spinner.fail("No API key provided");
|
|
73
|
+
process.exit(1);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const email = getArgumentByKey(["--email", "-e"]);
|
|
77
|
+
|
|
78
|
+
if (!email || !/\S+@\S+\.\S+/.test(email)) {
|
|
79
|
+
spinner.fail(
|
|
80
|
+
"Invalid email provided. Please provide a valid email using --email (-e) flag",
|
|
81
|
+
);
|
|
82
|
+
process.exit(1);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// message is optional
|
|
86
|
+
const message = getArgumentByKey(["--message", "-m"]);
|
|
87
|
+
|
|
88
|
+
await buildArchive(config);
|
|
89
|
+
|
|
90
|
+
return sendBuildByApiKey(config, {
|
|
91
|
+
apiKey,
|
|
92
|
+
email,
|
|
93
|
+
message,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
|
|
58
97
|
async function selectWorkspace(ctx: any, token: string) {
|
|
59
98
|
const workspaceSpinner = ora({
|
|
60
99
|
text: `Fetching workspaces using ${ctx.pushBaseUrl}...`,
|
|
@@ -112,6 +151,18 @@ async function verify(ctx: any) {
|
|
|
112
151
|
return token;
|
|
113
152
|
}
|
|
114
153
|
|
|
154
|
+
async function buildArchive(config: any) {
|
|
155
|
+
const spinnerArchive = ora("Building...").start();
|
|
156
|
+
|
|
157
|
+
const filesList = await findFiles(
|
|
158
|
+
config.client.modelsSrc || config.client.srcDir,
|
|
159
|
+
YAML_OR_JS_FILES,
|
|
160
|
+
);
|
|
161
|
+
|
|
162
|
+
await archive(config, filesList);
|
|
163
|
+
return spinnerArchive.succeed("Bundling completed");
|
|
164
|
+
}
|
|
165
|
+
|
|
115
166
|
export async function archive(
|
|
116
167
|
ctx: any,
|
|
117
168
|
yamlFiles: [string, string][],
|
|
@@ -143,6 +194,37 @@ export async function archive(
|
|
|
143
194
|
});
|
|
144
195
|
}
|
|
145
196
|
|
|
197
|
+
export async function sendBuildByApiKey(
|
|
198
|
+
ctx: any,
|
|
199
|
+
{ apiKey, email, message }: any,
|
|
200
|
+
) {
|
|
201
|
+
const { FormData, Blob } = await import("formdata-node");
|
|
202
|
+
const { fileFromPath } = await import("formdata-node/file-from-path");
|
|
203
|
+
|
|
204
|
+
const file = await fileFromPath(
|
|
205
|
+
ctx.client.archiveFile,
|
|
206
|
+
"embeddable-build.zip",
|
|
207
|
+
);
|
|
208
|
+
|
|
209
|
+
const form = new FormData();
|
|
210
|
+
form.set("file", file, "embeddable-build.zip");
|
|
211
|
+
|
|
212
|
+
const metadataBlob = new Blob(
|
|
213
|
+
[JSON.stringify({ authorEmail: email, description: message })],
|
|
214
|
+
{ type: "application/json" },
|
|
215
|
+
);
|
|
216
|
+
form.set("metadata", metadataBlob, "metadata.json");
|
|
217
|
+
|
|
218
|
+
const response = await uploadFile(
|
|
219
|
+
form,
|
|
220
|
+
`${ctx.pushBaseUrl}/api/v1/bundle/upload`,
|
|
221
|
+
apiKey,
|
|
222
|
+
);
|
|
223
|
+
await fs.rm(ctx.client.archiveFile);
|
|
224
|
+
|
|
225
|
+
return { bundleId: response.data?.bundleId, email, message };
|
|
226
|
+
}
|
|
227
|
+
|
|
146
228
|
export async function sendBuild(
|
|
147
229
|
ctx: any,
|
|
148
230
|
{ workspaceId, token }: { workspaceId: string; token: string },
|
|
@@ -158,7 +240,17 @@ export async function sendBuild(
|
|
|
158
240
|
const form = new FormData();
|
|
159
241
|
form.set("file", file, "embeddable-build.zip");
|
|
160
242
|
|
|
161
|
-
await
|
|
243
|
+
await uploadFile(
|
|
244
|
+
form,
|
|
245
|
+
`${ctx.pushBaseUrl}/bundle/${workspaceId}/upload`,
|
|
246
|
+
token,
|
|
247
|
+
);
|
|
248
|
+
|
|
249
|
+
await fs.rm(ctx.client.archiveFile);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
async function uploadFile(formData: any, url: string, token: string) {
|
|
253
|
+
return axios.post(url, formData, {
|
|
162
254
|
headers: {
|
|
163
255
|
"Content-Type": "multipart/form-data",
|
|
164
256
|
Authorization: `Bearer ${token}`,
|
|
@@ -166,8 +258,6 @@ export async function sendBuild(
|
|
|
166
258
|
maxContentLength: Infinity,
|
|
167
259
|
maxBodyLength: Infinity,
|
|
168
260
|
});
|
|
169
|
-
|
|
170
|
-
await fs.rm(ctx.client.archiveFile);
|
|
171
261
|
}
|
|
172
262
|
|
|
173
263
|
async function getWorkspaces(ctx: any, token: string, workspaceSpinner: any) {
|
package/src/utils.ts
CHANGED
|
@@ -22,3 +22,25 @@ export const checkNodeVersion = async () => {
|
|
|
22
22
|
process.exit(1);
|
|
23
23
|
}
|
|
24
24
|
};
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Get the value of a process argument by key
|
|
28
|
+
* Example: getArgumentByKey("--email") or getArgumentByKey(["--email", "-e"])
|
|
29
|
+
* @param key The key to search for in the process arguments
|
|
30
|
+
* @returns
|
|
31
|
+
*/
|
|
32
|
+
export const getArgumentByKey = (key: string | string[]) => {
|
|
33
|
+
if (Array.isArray(key)) {
|
|
34
|
+
for (const k of key) {
|
|
35
|
+
if (process.argv.includes(k)) {
|
|
36
|
+
const index = process.argv.indexOf(k);
|
|
37
|
+
return index !== -1 ? process.argv[index + 1] : undefined;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const index = process.argv.indexOf(key);
|
|
45
|
+
return index !== -1 ? process.argv[index + 1] : undefined;
|
|
46
|
+
};
|
package/src/validate.ts
CHANGED
|
@@ -28,7 +28,7 @@ export default async (ctx: any, exitIfInvalid = true) => {
|
|
|
28
28
|
|
|
29
29
|
const filesList = await findFiles(ctx.client.srcDir, CUBE_YAML_FILE_REGEX);
|
|
30
30
|
const securityContextFilesList = await findFiles(
|
|
31
|
-
ctx.client.srcDir,
|
|
31
|
+
ctx.client.modelsSrc || ctx.client.srcDir,
|
|
32
32
|
SECURITY_CONTEXT_FILE_REGEX,
|
|
33
33
|
);
|
|
34
34
|
|
|
@@ -75,9 +75,21 @@ export async function dataModelsValidation(filesList: [string, string][]) {
|
|
|
75
75
|
|
|
76
76
|
const cube = YAML.parse(fileContentRaw);
|
|
77
77
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
78
|
+
if (!cube?.cubes && !cube?.views) {
|
|
79
|
+
return [`${filePath}: At least one cubes or views must be defined`];
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const cubeModelSafeParse = cubeModelSchema.safeParse(cube);
|
|
83
|
+
const viewModelSafeParse = viewModelSchema.safeParse(cube);
|
|
84
|
+
|
|
85
|
+
if (cube.cubes && !cubeModelSafeParse.success) {
|
|
86
|
+
errorFormatter(cubeModelSafeParse.error.issues).forEach((error) => {
|
|
87
|
+
errors.push(`${filePath}: ${error}`);
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (cube.views && !viewModelSafeParse.success) {
|
|
92
|
+
errorFormatter(viewModelSafeParse.error.issues).forEach((error) => {
|
|
81
93
|
errors.push(`${filePath}: ${error}`);
|
|
82
94
|
});
|
|
83
95
|
}
|
|
@@ -172,6 +184,20 @@ const cubeModelSchema = z
|
|
|
172
184
|
},
|
|
173
185
|
);
|
|
174
186
|
|
|
187
|
+
const viewModelSchema = z.object({
|
|
188
|
+
views: z
|
|
189
|
+
.object({
|
|
190
|
+
name: z.string(),
|
|
191
|
+
cubes: z
|
|
192
|
+
.object({
|
|
193
|
+
join_path: z.string(),
|
|
194
|
+
})
|
|
195
|
+
.array(),
|
|
196
|
+
})
|
|
197
|
+
.array()
|
|
198
|
+
.min(1),
|
|
199
|
+
});
|
|
200
|
+
|
|
175
201
|
const securityContextSchema = z.array(
|
|
176
202
|
z.object({
|
|
177
203
|
name: z.string(),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Component, Watch, Host, Prop, Event, EventEmitter, h } from '@stencil/core';
|
|
1
|
+
import { Component, Watch, Host, Prop, Event, EventEmitter, h, Listen } from '@stencil/core';
|
|
2
2
|
{{RENDER_IMPORT}}
|
|
3
3
|
|
|
4
4
|
@Component({
|
|
@@ -9,6 +9,7 @@ import { Component, Watch, Host, Prop, Event, EventEmitter, h } from '@stencil/c
|
|
|
9
9
|
export class EmbeddableComponent {
|
|
10
10
|
|
|
11
11
|
private rootElement?: HTMLDivElement;
|
|
12
|
+
private updatePropsEventDispatched?: boolean;
|
|
12
13
|
|
|
13
14
|
@Prop() componentName: string;
|
|
14
15
|
@Prop() props: string = '{}';
|
|
@@ -44,6 +45,21 @@ export class EmbeddableComponent {
|
|
|
44
45
|
detail: JSON.parse(this.props),
|
|
45
46
|
});
|
|
46
47
|
this.rootElement.dispatchEvent(event);
|
|
48
|
+
this.updatePropsEventDispatched = true;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
@Listen('embeddable-event:update-props-listen', {target: 'window'})
|
|
52
|
+
handleUpdatePropsListen(e) {
|
|
53
|
+
const componentId = e.detail.componentId;
|
|
54
|
+
const props = JSON.parse(this.props);
|
|
55
|
+
|
|
56
|
+
if(this.updatePropsEventDispatched && componentId === props.componentId) {
|
|
57
|
+
const event = new CustomEvent('embeddable-event:update-props', {
|
|
58
|
+
bubbles: false,
|
|
59
|
+
detail: props,
|
|
60
|
+
});
|
|
61
|
+
this.rootElement.dispatchEvent(event);
|
|
62
|
+
}
|
|
47
63
|
}
|
|
48
64
|
|
|
49
65
|
render() {
|
package/lib/entryPoint.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/src/entryPoint.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
|
-
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
3
|
-
|
|
4
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
5
|
-
const COMMANDS_MAP = await import(
|
|
6
|
-
pathToFileURL(path.join(__dirname, "../lib/index.js")).href
|
|
7
|
-
);
|
|
8
|
-
|
|
9
|
-
async function main() {
|
|
10
|
-
const command = process.argv[2];
|
|
11
|
-
const runScript = COMMANDS_MAP[command];
|
|
12
|
-
|
|
13
|
-
if (!runScript) process.exit(1);
|
|
14
|
-
|
|
15
|
-
await runScript();
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
main();
|