@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 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
- const safeParse = cubeModelSchema.safeParse(cube);
4544
- if (!safeParse.success) {
4545
- errorFormatter(safeParse.error.issues).forEach((error) => {
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 spinnerArchive = ora$1("Building...").start();
20099
- const filesList = await findFiles(config.client.srcDir, YAML_OR_JS_FILES);
20100
- await archive(config, filesList);
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 ${config.pushBaseUrl}`);
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
- console.error(((_a = error.response) === null || _a === void 0 ? void 0 : _a.data) || (error === null || error === void 0 ? void 0 : error.message) || error);
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 axios.post(`${ctx.pushBaseUrl}/bundle/${workspaceId}/upload`, form, {
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;