@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.js
CHANGED
|
@@ -4567,9 +4567,18 @@ async function dataModelsValidation(filesList) {
|
|
|
4567
4567
|
for (const [_, filePath] of filesList) {
|
|
4568
4568
|
const fileContentRaw = await fs__namespace.readFile(filePath, "utf8");
|
|
4569
4569
|
const cube = YAML__namespace.parse(fileContentRaw);
|
|
4570
|
-
|
|
4571
|
-
|
|
4572
|
-
|
|
4570
|
+
if (!(cube === null || cube === void 0 ? void 0 : cube.cubes) && !(cube === null || cube === void 0 ? void 0 : cube.views)) {
|
|
4571
|
+
return [`${filePath}: At least one cubes or views must be defined`];
|
|
4572
|
+
}
|
|
4573
|
+
const cubeModelSafeParse = cubeModelSchema.safeParse(cube);
|
|
4574
|
+
const viewModelSafeParse = viewModelSchema.safeParse(cube);
|
|
4575
|
+
if (cube.cubes && !cubeModelSafeParse.success) {
|
|
4576
|
+
errorFormatter(cubeModelSafeParse.error.issues).forEach((error) => {
|
|
4577
|
+
errors.push(`${filePath}: ${error}`);
|
|
4578
|
+
});
|
|
4579
|
+
}
|
|
4580
|
+
if (cube.views && !viewModelSafeParse.success) {
|
|
4581
|
+
errorFormatter(viewModelSafeParse.error.issues).forEach((error) => {
|
|
4573
4582
|
errors.push(`${filePath}: ${error}`);
|
|
4574
4583
|
});
|
|
4575
4584
|
}
|
|
@@ -4648,6 +4657,18 @@ const cubeModelSchema = z
|
|
|
4648
4657
|
message: "At least one measure or dimension must be defined",
|
|
4649
4658
|
path: ["cubes"],
|
|
4650
4659
|
});
|
|
4660
|
+
const viewModelSchema = z.object({
|
|
4661
|
+
views: z.object({
|
|
4662
|
+
name: z.string(),
|
|
4663
|
+
cubes: z
|
|
4664
|
+
.object({
|
|
4665
|
+
join_path: z.string(),
|
|
4666
|
+
})
|
|
4667
|
+
.array()
|
|
4668
|
+
})
|
|
4669
|
+
.array()
|
|
4670
|
+
.min(1),
|
|
4671
|
+
});
|
|
4651
4672
|
const securityContextSchema = z.array(z.object({
|
|
4652
4673
|
name: z.string(),
|
|
4653
4674
|
securityContext: z.object({}), // can be any object
|
|
@@ -20004,6 +20025,25 @@ const checkNodeVersion = async () => {
|
|
|
20004
20025
|
process.exit(1);
|
|
20005
20026
|
}
|
|
20006
20027
|
};
|
|
20028
|
+
/**
|
|
20029
|
+
* Get the value of a process argument by key
|
|
20030
|
+
* Example: getArgumentByKey("--email") or getArgumentByKey(["--email", "-e"])
|
|
20031
|
+
* @param key The key to search for in the process arguments
|
|
20032
|
+
* @returns
|
|
20033
|
+
*/
|
|
20034
|
+
const getArgumentByKey = (key) => {
|
|
20035
|
+
if (Array.isArray(key)) {
|
|
20036
|
+
for (const k of key) {
|
|
20037
|
+
if (process.argv.includes(k)) {
|
|
20038
|
+
const index = process.argv.indexOf(k);
|
|
20039
|
+
return index !== -1 ? process.argv[index + 1] : undefined;
|
|
20040
|
+
}
|
|
20041
|
+
}
|
|
20042
|
+
return undefined;
|
|
20043
|
+
}
|
|
20044
|
+
const index = process.argv.indexOf(key);
|
|
20045
|
+
return index !== -1 ? process.argv[index + 1] : undefined;
|
|
20046
|
+
};
|
|
20007
20047
|
|
|
20008
20048
|
var build = async () => {
|
|
20009
20049
|
try {
|
|
@@ -20114,29 +20154,58 @@ const inquirerSelect = import('@inquirer/select');
|
|
|
20114
20154
|
const YAML_OR_JS_FILES = /^(.*)\.(cube|sc)\.(ya?ml|js)$/;
|
|
20115
20155
|
let ora$1;
|
|
20116
20156
|
var push = async () => {
|
|
20117
|
-
var _a;
|
|
20157
|
+
var _a, _b;
|
|
20118
20158
|
let spinnerPushing;
|
|
20119
20159
|
try {
|
|
20120
20160
|
checkNodeVersion();
|
|
20121
20161
|
ora$1 = (await oraP$1).default;
|
|
20122
20162
|
const config = await provideConfig();
|
|
20123
20163
|
const token = await verify(config);
|
|
20164
|
+
if (process.argv.includes("--api-key") || process.argv.includes("-k")) {
|
|
20165
|
+
spinnerPushing = ora$1("Using API key...").start();
|
|
20166
|
+
await pushByApiKey(config, spinnerPushing);
|
|
20167
|
+
spinnerPushing.succeed("Published using API key");
|
|
20168
|
+
return;
|
|
20169
|
+
}
|
|
20124
20170
|
const { workspaceId, name: workspaceName } = await selectWorkspace(config, token);
|
|
20125
|
-
const
|
|
20126
|
-
|
|
20127
|
-
|
|
20128
|
-
spinnerArchive.succeed("Bundling completed");
|
|
20129
|
-
spinnerPushing = ora$1(`Publishing to ${workspaceName} using ${config.pushBaseUrl}...`).start();
|
|
20171
|
+
const workspacePreviewUrl = `${config.previewBaseUrl}/workspace/${workspaceId}`;
|
|
20172
|
+
await buildArchive(config);
|
|
20173
|
+
spinnerPushing = ora$1(`Publishing to ${workspaceName} using ${workspacePreviewUrl}...`).start();
|
|
20130
20174
|
await sendBuild(config, { workspaceId, token });
|
|
20131
|
-
spinnerPushing.succeed(`Published to ${workspaceName} using ${
|
|
20175
|
+
spinnerPushing.succeed(`Published to ${workspaceName} using ${workspacePreviewUrl}`);
|
|
20132
20176
|
}
|
|
20133
20177
|
catch (error) {
|
|
20134
20178
|
spinnerPushing === null || spinnerPushing === void 0 ? void 0 : spinnerPushing.fail("Publishing failed");
|
|
20135
|
-
|
|
20179
|
+
if (((_a = error.response) === null || _a === void 0 ? void 0 : _a.statusText) === "Unauthorized") {
|
|
20180
|
+
console.error("Unauthorized. Please check your credentials.");
|
|
20181
|
+
}
|
|
20182
|
+
else {
|
|
20183
|
+
console.error(((_b = error.response) === null || _b === void 0 ? void 0 : _b.data) || (error === null || error === void 0 ? void 0 : error.message) || error);
|
|
20184
|
+
}
|
|
20136
20185
|
await reportErrorToRollbar(error);
|
|
20137
20186
|
process.exit(1);
|
|
20138
20187
|
}
|
|
20139
20188
|
};
|
|
20189
|
+
async function pushByApiKey(config, spinner) {
|
|
20190
|
+
const apiKey = getArgumentByKey(["--api-key", "-k"]);
|
|
20191
|
+
if (!apiKey) {
|
|
20192
|
+
spinner.fail("No API key provided");
|
|
20193
|
+
process.exit(1);
|
|
20194
|
+
}
|
|
20195
|
+
const email = getArgumentByKey(["--email", "-e"]);
|
|
20196
|
+
if (!email || !/\S+@\S+\.\S+/.test(email)) {
|
|
20197
|
+
spinner.fail("Invalid email provided. Please provide a valid email using --email (-e) flag");
|
|
20198
|
+
process.exit(1);
|
|
20199
|
+
}
|
|
20200
|
+
// message is optional
|
|
20201
|
+
const message = getArgumentByKey(["--message", "-m"]);
|
|
20202
|
+
await buildArchive(config);
|
|
20203
|
+
return sendBuildByApiKey(config, {
|
|
20204
|
+
apiKey,
|
|
20205
|
+
email,
|
|
20206
|
+
message,
|
|
20207
|
+
});
|
|
20208
|
+
}
|
|
20140
20209
|
async function selectWorkspace(ctx, token) {
|
|
20141
20210
|
const workspaceSpinner = ora$1({
|
|
20142
20211
|
text: `Fetching workspaces using ${ctx.pushBaseUrl}...`,
|
|
@@ -20182,6 +20251,12 @@ async function verify(ctx) {
|
|
|
20182
20251
|
}
|
|
20183
20252
|
return token;
|
|
20184
20253
|
}
|
|
20254
|
+
async function buildArchive(config) {
|
|
20255
|
+
const spinnerArchive = ora$1("Building...").start();
|
|
20256
|
+
const filesList = await findFiles(config.client.srcDir, YAML_OR_JS_FILES);
|
|
20257
|
+
await archive(config, filesList);
|
|
20258
|
+
return spinnerArchive.succeed("Bundling completed");
|
|
20259
|
+
}
|
|
20185
20260
|
async function archive(ctx, yamlFiles, includeBuild = true) {
|
|
20186
20261
|
const output = fs__namespace$1.createWriteStream(ctx.client.archiveFile);
|
|
20187
20262
|
const _archiver = archiver__namespace.create("zip", {
|
|
@@ -20202,13 +20277,30 @@ async function archive(ctx, yamlFiles, includeBuild = true) {
|
|
|
20202
20277
|
output.on("close", resolve);
|
|
20203
20278
|
});
|
|
20204
20279
|
}
|
|
20280
|
+
async function sendBuildByApiKey(ctx, { apiKey, email, message }) {
|
|
20281
|
+
var _a;
|
|
20282
|
+
const { FormData, Blob } = await import('formdata-node');
|
|
20283
|
+
const { fileFromPath } = await Promise.resolve().then(function () { return fileFromPath$1; });
|
|
20284
|
+
const file = await fileFromPath(ctx.client.archiveFile, "embeddable-build.zip");
|
|
20285
|
+
const form = new FormData();
|
|
20286
|
+
form.set("file", file, "embeddable-build.zip");
|
|
20287
|
+
const metadataBlob = new Blob([JSON.stringify({ authorEmail: email, description: message })], { type: "application/json" });
|
|
20288
|
+
form.set("metadata", metadataBlob, "metadata.json");
|
|
20289
|
+
const response = await uploadFile(form, `${ctx.pushBaseUrl}/api/v1/bundle/upload`, apiKey);
|
|
20290
|
+
await fs__namespace.rm(ctx.client.archiveFile);
|
|
20291
|
+
return { bundleId: (_a = response.data) === null || _a === void 0 ? void 0 : _a.bundleId, email, message };
|
|
20292
|
+
}
|
|
20205
20293
|
async function sendBuild(ctx, { workspaceId, token }) {
|
|
20206
20294
|
const { FormData } = await import('formdata-node');
|
|
20207
20295
|
const { fileFromPath } = await Promise.resolve().then(function () { return fileFromPath$1; });
|
|
20208
20296
|
const file = await fileFromPath(ctx.client.archiveFile, "embeddable-build.zip");
|
|
20209
20297
|
const form = new FormData();
|
|
20210
20298
|
form.set("file", file, "embeddable-build.zip");
|
|
20211
|
-
await
|
|
20299
|
+
await uploadFile(form, `${ctx.pushBaseUrl}/bundle/${workspaceId}/upload`, token);
|
|
20300
|
+
await fs__namespace.rm(ctx.client.archiveFile);
|
|
20301
|
+
}
|
|
20302
|
+
async function uploadFile(formData, url, token) {
|
|
20303
|
+
return axios.post(url, formData, {
|
|
20212
20304
|
headers: {
|
|
20213
20305
|
"Content-Type": "multipart/form-data",
|
|
20214
20306
|
Authorization: `Bearer ${token}`,
|
|
@@ -20216,7 +20308,6 @@ async function sendBuild(ctx, { workspaceId, token }) {
|
|
|
20216
20308
|
maxContentLength: Infinity,
|
|
20217
20309
|
maxBodyLength: Infinity,
|
|
20218
20310
|
});
|
|
20219
|
-
await fs__namespace.rm(ctx.client.archiveFile);
|
|
20220
20311
|
}
|
|
20221
20312
|
async function getWorkspaces(ctx, token, workspaceSpinner) {
|
|
20222
20313
|
var _a;
|