@embeddable.com/sdk-core 3.1.4 → 3.1.6
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 +104 -13
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +104 -13
- package/lib/index.js.map +1 -1
- package/lib/push.d.ts +5 -0
- package/lib/utils.d.ts +7 -0
- package/package.json +1 -1
- package/src/push.ts +100 -13
- package/src/utils.ts +22 -0
- package/src/validate.ts +28 -3
package/lib/index.esm.js
CHANGED
|
@@ -4540,9 +4540,18 @@ async function dataModelsValidation(filesList) {
|
|
|
4540
4540
|
for (const [_, filePath] of filesList) {
|
|
4541
4541
|
const fileContentRaw = await fs$1.readFile(filePath, "utf8");
|
|
4542
4542
|
const cube = YAML.parse(fileContentRaw);
|
|
4543
|
-
|
|
4544
|
-
|
|
4545
|
-
|
|
4543
|
+
if (!(cube === null || cube === void 0 ? void 0 : cube.cubes) && !(cube === null || cube === void 0 ? void 0 : cube.views)) {
|
|
4544
|
+
return [`${filePath}: At least one cubes or views must be defined`];
|
|
4545
|
+
}
|
|
4546
|
+
const cubeModelSafeParse = cubeModelSchema.safeParse(cube);
|
|
4547
|
+
const viewModelSafeParse = viewModelSchema.safeParse(cube);
|
|
4548
|
+
if (cube.cubes && !cubeModelSafeParse.success) {
|
|
4549
|
+
errorFormatter(cubeModelSafeParse.error.issues).forEach((error) => {
|
|
4550
|
+
errors.push(`${filePath}: ${error}`);
|
|
4551
|
+
});
|
|
4552
|
+
}
|
|
4553
|
+
if (cube.views && !viewModelSafeParse.success) {
|
|
4554
|
+
errorFormatter(viewModelSafeParse.error.issues).forEach((error) => {
|
|
4546
4555
|
errors.push(`${filePath}: ${error}`);
|
|
4547
4556
|
});
|
|
4548
4557
|
}
|
|
@@ -4621,6 +4630,18 @@ const cubeModelSchema = z
|
|
|
4621
4630
|
message: "At least one measure or dimension must be defined",
|
|
4622
4631
|
path: ["cubes"],
|
|
4623
4632
|
});
|
|
4633
|
+
const viewModelSchema = z.object({
|
|
4634
|
+
views: z.object({
|
|
4635
|
+
name: z.string(),
|
|
4636
|
+
cubes: z
|
|
4637
|
+
.object({
|
|
4638
|
+
join_path: z.string(),
|
|
4639
|
+
})
|
|
4640
|
+
.array()
|
|
4641
|
+
})
|
|
4642
|
+
.array()
|
|
4643
|
+
.min(1),
|
|
4644
|
+
});
|
|
4624
4645
|
const securityContextSchema = z.array(z.object({
|
|
4625
4646
|
name: z.string(),
|
|
4626
4647
|
securityContext: z.object({}), // can be any object
|
|
@@ -19977,6 +19998,25 @@ const checkNodeVersion = async () => {
|
|
|
19977
19998
|
process.exit(1);
|
|
19978
19999
|
}
|
|
19979
20000
|
};
|
|
20001
|
+
/**
|
|
20002
|
+
* Get the value of a process argument by key
|
|
20003
|
+
* Example: getArgumentByKey("--email") or getArgumentByKey(["--email", "-e"])
|
|
20004
|
+
* @param key The key to search for in the process arguments
|
|
20005
|
+
* @returns
|
|
20006
|
+
*/
|
|
20007
|
+
const getArgumentByKey = (key) => {
|
|
20008
|
+
if (Array.isArray(key)) {
|
|
20009
|
+
for (const k of key) {
|
|
20010
|
+
if (process.argv.includes(k)) {
|
|
20011
|
+
const index = process.argv.indexOf(k);
|
|
20012
|
+
return index !== -1 ? process.argv[index + 1] : undefined;
|
|
20013
|
+
}
|
|
20014
|
+
}
|
|
20015
|
+
return undefined;
|
|
20016
|
+
}
|
|
20017
|
+
const index = process.argv.indexOf(key);
|
|
20018
|
+
return index !== -1 ? process.argv[index + 1] : undefined;
|
|
20019
|
+
};
|
|
19980
20020
|
|
|
19981
20021
|
var build = async () => {
|
|
19982
20022
|
try {
|
|
@@ -20087,29 +20127,58 @@ const inquirerSelect = import('@inquirer/select');
|
|
|
20087
20127
|
const YAML_OR_JS_FILES = /^(.*)\.(cube|sc)\.(ya?ml|js)$/;
|
|
20088
20128
|
let ora$1;
|
|
20089
20129
|
var push = async () => {
|
|
20090
|
-
var _a;
|
|
20130
|
+
var _a, _b;
|
|
20091
20131
|
let spinnerPushing;
|
|
20092
20132
|
try {
|
|
20093
20133
|
checkNodeVersion();
|
|
20094
20134
|
ora$1 = (await oraP$1).default;
|
|
20095
20135
|
const config = await provideConfig();
|
|
20096
20136
|
const token = await verify(config);
|
|
20137
|
+
if (process.argv.includes("--api-key") || process.argv.includes("-k")) {
|
|
20138
|
+
spinnerPushing = ora$1("Using API key...").start();
|
|
20139
|
+
await pushByApiKey(config, spinnerPushing);
|
|
20140
|
+
spinnerPushing.succeed("Published using API key");
|
|
20141
|
+
return;
|
|
20142
|
+
}
|
|
20097
20143
|
const { workspaceId, name: workspaceName } = await selectWorkspace(config, token);
|
|
20098
|
-
const
|
|
20099
|
-
|
|
20100
|
-
|
|
20101
|
-
spinnerArchive.succeed("Bundling completed");
|
|
20102
|
-
spinnerPushing = ora$1(`Publishing to ${workspaceName} using ${config.pushBaseUrl}...`).start();
|
|
20144
|
+
const workspacePreviewUrl = `${config.previewBaseUrl}/workspace/${workspaceId}`;
|
|
20145
|
+
await buildArchive(config);
|
|
20146
|
+
spinnerPushing = ora$1(`Publishing to ${workspaceName} using ${workspacePreviewUrl}...`).start();
|
|
20103
20147
|
await sendBuild(config, { workspaceId, token });
|
|
20104
|
-
spinnerPushing.succeed(`Published to ${workspaceName} using ${
|
|
20148
|
+
spinnerPushing.succeed(`Published to ${workspaceName} using ${workspacePreviewUrl}`);
|
|
20105
20149
|
}
|
|
20106
20150
|
catch (error) {
|
|
20107
20151
|
spinnerPushing === null || spinnerPushing === void 0 ? void 0 : spinnerPushing.fail("Publishing failed");
|
|
20108
|
-
|
|
20152
|
+
if (((_a = error.response) === null || _a === void 0 ? void 0 : _a.statusText) === "Unauthorized") {
|
|
20153
|
+
console.error("Unauthorized. Please check your credentials.");
|
|
20154
|
+
}
|
|
20155
|
+
else {
|
|
20156
|
+
console.error(((_b = error.response) === null || _b === void 0 ? void 0 : _b.data) || (error === null || error === void 0 ? void 0 : error.message) || error);
|
|
20157
|
+
}
|
|
20109
20158
|
await reportErrorToRollbar(error);
|
|
20110
20159
|
process.exit(1);
|
|
20111
20160
|
}
|
|
20112
20161
|
};
|
|
20162
|
+
async function pushByApiKey(config, spinner) {
|
|
20163
|
+
const apiKey = getArgumentByKey(["--api-key", "-k"]);
|
|
20164
|
+
if (!apiKey) {
|
|
20165
|
+
spinner.fail("No API key provided");
|
|
20166
|
+
process.exit(1);
|
|
20167
|
+
}
|
|
20168
|
+
const email = getArgumentByKey(["--email", "-e"]);
|
|
20169
|
+
if (!email || !/\S+@\S+\.\S+/.test(email)) {
|
|
20170
|
+
spinner.fail("Invalid email provided. Please provide a valid email using --email (-e) flag");
|
|
20171
|
+
process.exit(1);
|
|
20172
|
+
}
|
|
20173
|
+
// message is optional
|
|
20174
|
+
const message = getArgumentByKey(["--message", "-m"]);
|
|
20175
|
+
await buildArchive(config);
|
|
20176
|
+
return sendBuildByApiKey(config, {
|
|
20177
|
+
apiKey,
|
|
20178
|
+
email,
|
|
20179
|
+
message,
|
|
20180
|
+
});
|
|
20181
|
+
}
|
|
20113
20182
|
async function selectWorkspace(ctx, token) {
|
|
20114
20183
|
const workspaceSpinner = ora$1({
|
|
20115
20184
|
text: `Fetching workspaces using ${ctx.pushBaseUrl}...`,
|
|
@@ -20155,6 +20224,12 @@ async function verify(ctx) {
|
|
|
20155
20224
|
}
|
|
20156
20225
|
return token;
|
|
20157
20226
|
}
|
|
20227
|
+
async function buildArchive(config) {
|
|
20228
|
+
const spinnerArchive = ora$1("Building...").start();
|
|
20229
|
+
const filesList = await findFiles(config.client.srcDir, YAML_OR_JS_FILES);
|
|
20230
|
+
await archive(config, filesList);
|
|
20231
|
+
return spinnerArchive.succeed("Bundling completed");
|
|
20232
|
+
}
|
|
20158
20233
|
async function archive(ctx, yamlFiles, includeBuild = true) {
|
|
20159
20234
|
const output = fs$2.createWriteStream(ctx.client.archiveFile);
|
|
20160
20235
|
const _archiver = archiver.create("zip", {
|
|
@@ -20175,13 +20250,30 @@ async function archive(ctx, yamlFiles, includeBuild = true) {
|
|
|
20175
20250
|
output.on("close", resolve);
|
|
20176
20251
|
});
|
|
20177
20252
|
}
|
|
20253
|
+
async function sendBuildByApiKey(ctx, { apiKey, email, message }) {
|
|
20254
|
+
var _a;
|
|
20255
|
+
const { FormData, Blob } = await import('formdata-node');
|
|
20256
|
+
const { fileFromPath } = await Promise.resolve().then(function () { return fileFromPath$1; });
|
|
20257
|
+
const file = await fileFromPath(ctx.client.archiveFile, "embeddable-build.zip");
|
|
20258
|
+
const form = new FormData();
|
|
20259
|
+
form.set("file", file, "embeddable-build.zip");
|
|
20260
|
+
const metadataBlob = new Blob([JSON.stringify({ authorEmail: email, description: message })], { type: "application/json" });
|
|
20261
|
+
form.set("metadata", metadataBlob, "metadata.json");
|
|
20262
|
+
const response = await uploadFile(form, `${ctx.pushBaseUrl}/api/v1/bundle/upload`, apiKey);
|
|
20263
|
+
await fs$1.rm(ctx.client.archiveFile);
|
|
20264
|
+
return { bundleId: (_a = response.data) === null || _a === void 0 ? void 0 : _a.bundleId, email, message };
|
|
20265
|
+
}
|
|
20178
20266
|
async function sendBuild(ctx, { workspaceId, token }) {
|
|
20179
20267
|
const { FormData } = await import('formdata-node');
|
|
20180
20268
|
const { fileFromPath } = await Promise.resolve().then(function () { return fileFromPath$1; });
|
|
20181
20269
|
const file = await fileFromPath(ctx.client.archiveFile, "embeddable-build.zip");
|
|
20182
20270
|
const form = new FormData();
|
|
20183
20271
|
form.set("file", file, "embeddable-build.zip");
|
|
20184
|
-
await
|
|
20272
|
+
await uploadFile(form, `${ctx.pushBaseUrl}/bundle/${workspaceId}/upload`, token);
|
|
20273
|
+
await fs$1.rm(ctx.client.archiveFile);
|
|
20274
|
+
}
|
|
20275
|
+
async function uploadFile(formData, url, token) {
|
|
20276
|
+
return axios.post(url, formData, {
|
|
20185
20277
|
headers: {
|
|
20186
20278
|
"Content-Type": "multipart/form-data",
|
|
20187
20279
|
Authorization: `Bearer ${token}`,
|
|
@@ -20189,7 +20281,6 @@ async function sendBuild(ctx, { workspaceId, token }) {
|
|
|
20189
20281
|
maxContentLength: Infinity,
|
|
20190
20282
|
maxBodyLength: Infinity,
|
|
20191
20283
|
});
|
|
20192
|
-
await fs$1.rm(ctx.client.archiveFile);
|
|
20193
20284
|
}
|
|
20194
20285
|
async function getWorkspaces(ctx, token, workspaceSpinner) {
|
|
20195
20286
|
var _a;
|