@embeddable.com/sdk-core 3.9.2 → 3.9.4

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
@@ -652,14 +652,7 @@ const getPackageVersion = (packageName) => {
652
652
  return undefined;
653
653
  }
654
654
  };
655
-
656
- var cleanup = async (ctx) => {
657
- await extractBuild(ctx);
658
- await removeObsoleteDir(ctx.client.buildDir);
659
- await moveBuildTOBuildDir(ctx);
660
- };
661
- async function createManifest({ ctx, typesFileName, metaFileName, editorsMetaFileName, stencilWrapperFileName, }) {
662
- var _a, _b, _c, _d;
655
+ const getSDKVersions = () => {
663
656
  const packageNames = [
664
657
  "@embeddable.com/core",
665
658
  "@embeddable.com/react",
@@ -674,6 +667,30 @@ async function createManifest({ ctx, typesFileName, metaFileName, editorsMetaFil
674
667
  }
675
668
  return acc;
676
669
  }, {});
670
+ return sdkVersions;
671
+ };
672
+ const hrtimeToISO8601 = (hrtime) => {
673
+ if (hrtime === null || hrtime === undefined) {
674
+ return "";
675
+ }
676
+ const seconds = hrtime[0];
677
+ const nanoseconds = hrtime[1];
678
+ // Convert time components
679
+ const totalSeconds = seconds + nanoseconds / 1e9;
680
+ const minutes = Math.floor(totalSeconds / 60);
681
+ const remainingSeconds = totalSeconds % 60;
682
+ // Format ISO 8601 duration without hours
683
+ return `PT${minutes > 0 ? minutes + "M" : ""}${remainingSeconds.toFixed(3)}S`;
684
+ };
685
+
686
+ var cleanup = async (ctx) => {
687
+ await extractBuild(ctx);
688
+ await removeObsoleteDir(ctx.client.buildDir);
689
+ await moveBuildTOBuildDir(ctx);
690
+ };
691
+ async function createManifest({ ctx, typesFileName, metaFileName, editorsMetaFileName, stencilWrapperFileName, }) {
692
+ var _a, _b, _c, _d;
693
+ const sdkVersions = getSDKVersions();
677
694
  // identify user's package manager and its version
678
695
  let packageManager = "npm";
679
696
  if ((_a = process.env.npm_config_user_agent) === null || _a === void 0 ? void 0 : _a.includes("yarn")) {
@@ -699,6 +716,9 @@ async function createManifest({ ctx, typesFileName, metaFileName, editorsMetaFil
699
716
  sdkVersions,
700
717
  packageManager,
701
718
  packageManagerVersion,
719
+ metrics: {
720
+ buildTime: hrtimeToISO8601(ctx.buildTime),
721
+ },
702
722
  },
703
723
  };
704
724
  await fs.writeFile(path.join(ctx.client.tmpDir, "embeddable-manifest.json"), JSON.stringify(manifest));
@@ -21198,9 +21218,96 @@ async function getUserData() {
21198
21218
  }
21199
21219
  }
21200
21220
 
21221
+ const LOG_DIR = path.join(process.cwd(), ".embeddable", "logs");
21222
+ const ERROR_LOG_FILE = path.join(LOG_DIR, "error.log");
21223
+ const MAX_LOG_SIZE = 5 * 1024 * 1024; // 5 MB
21224
+ const MAX_LOG_FILES = 5;
21225
+ async function initLogger(command) {
21226
+ try {
21227
+ await fs.mkdir(LOG_DIR, { recursive: true });
21228
+ }
21229
+ catch (error) {
21230
+ console.error("Failed to create log directory:", error);
21231
+ }
21232
+ setupGlobalErrorHandlers(command);
21233
+ }
21234
+ async function logError({ command, breadcrumbs, error, }) {
21235
+ const sdkVersions = getSDKVersions();
21236
+ const logEntry = {
21237
+ timestamp: new Date().toISOString(),
21238
+ command,
21239
+ breadcrumbs,
21240
+ error: error instanceof Error
21241
+ ? `${error.name}: ${error.message}\n${error.stack}`
21242
+ : String(error),
21243
+ };
21244
+ const logMessage = `
21245
+ [${logEntry.timestamp}] Command: ${logEntry.command}
21246
+ Breadcrumbs: ${logEntry.breadcrumbs.join(" > ")}
21247
+ Error: ${logEntry.error}
21248
+ OS: ${process.platform}
21249
+ Node: ${process.version}
21250
+ SDK Versions: ${JSON.stringify(sdkVersions, null, 2)}
21251
+ ----------------------------------------
21252
+ `;
21253
+ try {
21254
+ await rotateLogIfNeeded();
21255
+ await fs.appendFile(ERROR_LOG_FILE, logMessage);
21256
+ console.error(`An error occurred during ${command}. Check the log file for details: ${ERROR_LOG_FILE}`);
21257
+ }
21258
+ catch (error) {
21259
+ console.error("Failed to write to log file:", error);
21260
+ }
21261
+ }
21262
+ async function rotateLogIfNeeded() {
21263
+ try {
21264
+ const stats = await fs.stat(ERROR_LOG_FILE);
21265
+ if (stats.size < MAX_LOG_SIZE) {
21266
+ return;
21267
+ }
21268
+ for (let i = MAX_LOG_FILES - 1; i > 0; i--) {
21269
+ const oldFile = `${ERROR_LOG_FILE}.${i}`;
21270
+ const newFile = `${ERROR_LOG_FILE}.${i + 1}`;
21271
+ try {
21272
+ await fs.rename(oldFile, newFile);
21273
+ }
21274
+ catch (error) {
21275
+ // Ignore error if file doesn't exist
21276
+ }
21277
+ }
21278
+ await fs.rename(ERROR_LOG_FILE, `${ERROR_LOG_FILE}.1`);
21279
+ await fs.writeFile(ERROR_LOG_FILE, ""); // Create a new empty log file
21280
+ }
21281
+ catch (error) {
21282
+ if (error.code !== "ENOENT") {
21283
+ console.error("Error rotating log file:", error);
21284
+ }
21285
+ }
21286
+ }
21287
+ function setupGlobalErrorHandlers(command) {
21288
+ process.on("uncaughtException", async (error) => {
21289
+ await logError({ command, breadcrumbs: ["uncaughtException"], error });
21290
+ console.error("An uncaught error occurred. Check the log file for details.");
21291
+ process.exit(1);
21292
+ });
21293
+ process.on("unhandledRejection", async (reason) => {
21294
+ await logError({
21295
+ command,
21296
+ breadcrumbs: ["unhandledRejection"],
21297
+ error: reason,
21298
+ });
21299
+ console.error("An unhandled rejection occurred. Check the log file for details.");
21300
+ process.exit(1);
21301
+ });
21302
+ }
21303
+
21201
21304
  var build = async () => {
21305
+ await initLogger("build");
21306
+ const breadcrumbs = [];
21202
21307
  try {
21308
+ const startTime = process.hrtime();
21203
21309
  checkNodeVersion();
21310
+ breadcrumbs.push("checkNodeVersion");
21204
21311
  removeBuildSuccessFlag();
21205
21312
  const config = await provideConfig();
21206
21313
  await validate(config);
@@ -21208,16 +21315,24 @@ var build = async () => {
21208
21315
  await buildTypes(config);
21209
21316
  for (const getPlugin of config.plugins) {
21210
21317
  const plugin = getPlugin();
21318
+ breadcrumbs.push(`${plugin.pluginName}: validate`);
21211
21319
  await plugin.validate(config);
21320
+ breadcrumbs.push(`${plugin.pluginName}: build`);
21212
21321
  await plugin.build(config);
21322
+ breadcrumbs.push(`${plugin.pluginName}: cleanup`);
21213
21323
  await plugin.cleanup(config);
21214
21324
  }
21215
21325
  // NOTE: likely this will be called inside the loop above if we decide to support clients with mixed frameworks simultaneously.
21326
+ breadcrumbs.push("generate");
21216
21327
  await generate(config, "sdk-react");
21328
+ // Calculating build time in seconds
21329
+ config.buildTime = process.hrtime(startTime);
21330
+ breadcrumbs.push("cleanup");
21217
21331
  await cleanup(config);
21218
21332
  await storeBuildSuccessFlag();
21219
21333
  }
21220
21334
  catch (error) {
21335
+ await logError({ command: "build", breadcrumbs, error });
21221
21336
  await reportErrorToRollbar(error);
21222
21337
  console.log(error);
21223
21338
  process.exit(1);
@@ -21228,12 +21343,16 @@ const oraP$2 = import('ora');
21228
21343
  const openP = import('open');
21229
21344
  var login = async () => {
21230
21345
  var _a;
21346
+ await initLogger("login");
21347
+ const breadcrumbs = [];
21231
21348
  const ora = (await oraP$2).default;
21232
21349
  const authenticationSpinner = ora("Waiting for code verification...").start();
21233
21350
  try {
21234
21351
  const open = (await openP).default;
21235
21352
  const config = await provideConfig();
21353
+ breadcrumbs.push("provideConfig");
21236
21354
  await resolveFiles();
21355
+ breadcrumbs.push("resolveFiles");
21237
21356
  const deviceCodePayload = {
21238
21357
  client_id: config.authClientId,
21239
21358
  audience: config.audienceUrl,
@@ -21269,6 +21388,7 @@ var login = async () => {
21269
21388
  }
21270
21389
  catch (error) {
21271
21390
  authenticationSpinner.fail("Authentication failed. Please try again.");
21391
+ await logError({ command: "login", breadcrumbs, error });
21272
21392
  await reportErrorToRollbar(error);
21273
21393
  console.log(error);
21274
21394
  process.exit(1);
@@ -21357,10 +21477,12 @@ const oraP$1 = import('ora');
21357
21477
  const YAML_OR_JS_FILES = /^(.*)\.(cube|sc)\.(ya?ml|js)$/;
21358
21478
  let ora$1;
21359
21479
  var push = async () => {
21360
- var _a, _b;
21480
+ await initLogger("push");
21481
+ const breadcrumbs = [];
21361
21482
  let spinnerPushing;
21362
21483
  try {
21363
21484
  checkNodeVersion();
21485
+ breadcrumbs.push("checkNodeVersion");
21364
21486
  const isBuildSuccess = await checkBuildSuccess();
21365
21487
  if (!isBuildSuccess) {
21366
21488
  console.error("Build failed or not completed. Please run `embeddable:build` first.");
@@ -21370,29 +21492,29 @@ var push = async () => {
21370
21492
  const config = await provideConfig();
21371
21493
  if (process.argv.includes("--api-key") || process.argv.includes("-k")) {
21372
21494
  spinnerPushing = ora$1("Using API key...").start();
21495
+ breadcrumbs.push("push by api key");
21373
21496
  await pushByApiKey(config, spinnerPushing);
21374
21497
  spinnerPushing.succeed("Published using API key");
21375
21498
  return;
21376
21499
  }
21500
+ breadcrumbs.push("push by standard login");
21377
21501
  const token = await verify(config);
21378
21502
  spinnerPushing = ora$1()
21379
21503
  .start()
21380
21504
  .info("No API Key provided. Standard login will be used.");
21505
+ breadcrumbs.push("select workspace");
21381
21506
  const { workspaceId, name: workspaceName } = await selectWorkspace(ora$1, config, token);
21382
21507
  const workspacePreviewUrl = `${config.previewBaseUrl}/workspace/${workspaceId}`;
21508
+ breadcrumbs.push("build archive");
21383
21509
  await buildArchive(config);
21384
21510
  spinnerPushing.info(`Publishing to ${workspaceName} using ${workspacePreviewUrl}...`);
21511
+ breadcrumbs.push("send build");
21385
21512
  await sendBuild(config, { workspaceId, token });
21386
21513
  spinnerPushing.succeed(`Published to ${workspaceName} using ${workspacePreviewUrl}`);
21387
21514
  }
21388
21515
  catch (error) {
21389
21516
  spinnerPushing === null || spinnerPushing === void 0 ? void 0 : spinnerPushing.fail("Publishing failed");
21390
- if (((_a = error.response) === null || _a === void 0 ? void 0 : _a.statusText) === "Unauthorized") {
21391
- console.error("Unauthorized. Please check your credentials.");
21392
- }
21393
- else {
21394
- console.error(((_b = error.response) === null || _b === void 0 ? void 0 : _b.data) || (error === null || error === void 0 ? void 0 : error.message) || error);
21395
- }
21517
+ await logError({ command: "push", breadcrumbs, error });
21396
21518
  await reportErrorToRollbar(error);
21397
21519
  process.exit(1);
21398
21520
  }
@@ -21531,96 +21653,111 @@ const chokidarWatchOptions = {
21531
21653
  };
21532
21654
  var dev = async () => {
21533
21655
  var _a, _b;
21534
- checkNodeVersion();
21535
- addToGitingore();
21536
- ora = (await oraP).default;
21537
- process.on("warning", (e) => console.warn(e.stack));
21538
- const logger = createNodeLogger();
21539
- const sys = createNodeSys({ process });
21540
- const defaultConfig = await provideConfig();
21541
- const buildDir = path$1.resolve(defaultConfig.client.rootDir, BUILD_DEV_DIR);
21542
- const config = {
21543
- ...defaultConfig,
21544
- dev: {
21545
- watch: true,
21546
- logger,
21547
- sys,
21548
- },
21549
- client: {
21550
- ...defaultConfig.client,
21551
- buildDir,
21552
- componentDir: path$1.resolve(buildDir, "component"),
21553
- stencilBuild: path$1.resolve(buildDir, "dist", "embeddable-wrapper"),
21554
- tmpDir: path$1.resolve(defaultConfig.client.rootDir, ".embeddable-dev-tmp"),
21555
- },
21556
- };
21557
- await prepare(config);
21558
- const finalhandler = require("finalhandler");
21559
- const serveStatic = require("serve-static");
21560
- const serve = serveStatic(config.client.buildDir);
21561
- const workspacePreparation = ora("Preparing workspace...").start();
21656
+ await initLogger("dev");
21657
+ const breadcrumbs = [];
21562
21658
  try {
21563
- previewWorkspace = await getPreviewWorkspace(workspacePreparation, config);
21564
- }
21565
- catch (e) {
21566
- workspacePreparation.fail(((_b = (_a = e.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.errorMessage) || "Unknown error: " + e.message);
21567
- process.exit(1);
21568
- }
21569
- workspacePreparation.succeed("Workspace is ready");
21570
- const server = http.createServer((request, res) => {
21571
- var _a;
21572
- res.setHeader("Access-Control-Allow-Origin", "*");
21573
- res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
21574
- res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
21575
- if (request.method === "OPTIONS") {
21576
- // Respond to OPTIONS requests with just the CORS headers and a 200 status code
21577
- res.writeHead(200);
21578
- res.end();
21579
- return;
21580
- }
21581
- const done = finalhandler(request, res);
21659
+ breadcrumbs.push("run dev");
21660
+ checkNodeVersion();
21661
+ addToGitingore();
21662
+ ora = (await oraP).default;
21663
+ process.on("warning", (e) => console.warn(e.stack));
21664
+ const logger = createNodeLogger();
21665
+ const sys = createNodeSys({ process });
21666
+ const defaultConfig = await provideConfig();
21667
+ const buildDir = path$1.resolve(defaultConfig.client.rootDir, BUILD_DEV_DIR);
21668
+ const config = {
21669
+ ...defaultConfig,
21670
+ dev: {
21671
+ watch: true,
21672
+ logger,
21673
+ sys,
21674
+ },
21675
+ client: {
21676
+ ...defaultConfig.client,
21677
+ buildDir,
21678
+ componentDir: path$1.resolve(buildDir, "component"),
21679
+ stencilBuild: path$1.resolve(buildDir, "dist", "embeddable-wrapper"),
21680
+ tmpDir: path$1.resolve(defaultConfig.client.rootDir, ".embeddable-dev-tmp"),
21681
+ },
21682
+ };
21683
+ breadcrumbs.push("prepare config");
21684
+ await prepare(config);
21685
+ const finalhandler = require("finalhandler");
21686
+ const serveStatic = require("serve-static");
21687
+ const serve = serveStatic(config.client.buildDir);
21688
+ const workspacePreparation = ora("Preparing workspace...").start();
21689
+ breadcrumbs.push("get preview workspace");
21582
21690
  try {
21583
- if ((_a = request.url) === null || _a === void 0 ? void 0 : _a.endsWith(GLOBAL_CSS)) {
21584
- res.writeHead(200, { "Content-Type": "text/css" });
21585
- res.end(require$$2$1.readFileSync(config.client.globalCss));
21586
- return;
21587
- }
21691
+ previewWorkspace = await getPreviewWorkspace(workspacePreparation, config);
21588
21692
  }
21589
- catch (_b) { }
21590
- serve(request, res, done);
21591
- });
21592
- wss = new WebSocketServer({ server });
21593
- server.listen(SERVER_PORT, async () => {
21594
- const watchers = [];
21595
- if (sys === null || sys === void 0 ? void 0 : sys.onProcessInterrupt) {
21596
- sys.onProcessInterrupt(async () => await onClose(server, sys, watchers, config));
21693
+ catch (e) {
21694
+ workspacePreparation.fail(((_b = (_a = e.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.errorMessage) || "Unknown error: " + e.message);
21695
+ process.exit(1);
21597
21696
  }
21598
- await createManifest({
21599
- ctx: {
21600
- ...config,
21601
- client: {
21602
- ...config.client,
21603
- tmpDir: buildDir,
21697
+ workspacePreparation.succeed("Workspace is ready");
21698
+ const server = http.createServer((request, res) => {
21699
+ var _a;
21700
+ res.setHeader("Access-Control-Allow-Origin", "*");
21701
+ res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
21702
+ res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
21703
+ if (request.method === "OPTIONS") {
21704
+ // Respond to OPTIONS requests with just the CORS headers and a 200 status code
21705
+ res.writeHead(200);
21706
+ res.end();
21707
+ return;
21708
+ }
21709
+ const done = finalhandler(request, res);
21710
+ try {
21711
+ if ((_a = request.url) === null || _a === void 0 ? void 0 : _a.endsWith(GLOBAL_CSS)) {
21712
+ res.writeHead(200, { "Content-Type": "text/css" });
21713
+ res.end(require$$2$1.readFileSync(config.client.globalCss));
21714
+ return;
21715
+ }
21716
+ }
21717
+ catch (_b) { }
21718
+ serve(request, res, done);
21719
+ });
21720
+ wss = new WebSocketServer({ server });
21721
+ server.listen(SERVER_PORT, async () => {
21722
+ const watchers = [];
21723
+ if (sys === null || sys === void 0 ? void 0 : sys.onProcessInterrupt) {
21724
+ sys.onProcessInterrupt(async () => await onClose(server, sys, watchers, config));
21725
+ }
21726
+ breadcrumbs.push("create manifest");
21727
+ await createManifest({
21728
+ ctx: {
21729
+ ...config,
21730
+ client: {
21731
+ ...config.client,
21732
+ tmpDir: buildDir,
21733
+ },
21604
21734
  },
21605
- },
21606
- typesFileName: "embeddable-types.js",
21607
- stencilWrapperFileName: "embeddable-wrapper.js",
21608
- metaFileName: "embeddable-components-meta.js",
21609
- editorsMetaFileName: "embeddable-editors-meta.js",
21735
+ typesFileName: "embeddable-types.js",
21736
+ stencilWrapperFileName: "embeddable-wrapper.js",
21737
+ metaFileName: "embeddable-components-meta.js",
21738
+ editorsMetaFileName: "embeddable-editors-meta.js",
21739
+ });
21740
+ await sendDataModelsAndSecurityContextsChanges(config);
21741
+ for (const getPlugin of config.plugins) {
21742
+ const plugin = getPlugin();
21743
+ breadcrumbs.push("validate plugin");
21744
+ await plugin.validate(config);
21745
+ breadcrumbs.push("build plugin");
21746
+ const watcher = await plugin.build(config);
21747
+ breadcrumbs.push("configure watcher");
21748
+ await configureWatcher(watcher, config);
21749
+ watchers.push(watcher);
21750
+ }
21751
+ const dataModelAndSecurityContextWatch = dataModelAndSecurityContextWatcher(config);
21752
+ const customGlobalCssWatch = globalCssWatcher(config);
21753
+ watchers.push(dataModelAndSecurityContextWatch);
21754
+ watchers.push(customGlobalCssWatch);
21610
21755
  });
21611
- await sendDataModelsAndSecurityContextsChanges(config);
21612
- for (const getPlugin of config.plugins) {
21613
- const plugin = getPlugin();
21614
- await plugin.validate(config);
21615
- const watcher = await plugin.build(config);
21616
- await configureWatcher(watcher, config);
21617
- watchers.push(watcher);
21618
- }
21619
- const dataModelAndSecurityContextWatch = dataModelAndSecurityContextWatcher(config);
21620
- const customGlobalCssWatch = globalCssWatcher(config);
21621
- watchers.push(dataModelAndSecurityContextWatch);
21622
- watchers.push(customGlobalCssWatch);
21623
- });
21756
+ }
21757
+ catch (error) {
21758
+ await logError({ command: "dev", breadcrumbs, error });
21759
+ process.exit(1);
21760
+ }
21624
21761
  };
21625
21762
  const configureWatcher = async (watcher, ctx) => {
21626
21763
  watcher.on("change", (path) => {
@@ -21804,7 +21941,7 @@ var defineConfig = ({ plugins, pushBaseUrl, audienceUrl, authDomain, authClientI
21804
21941
  };
21805
21942
 
21806
21943
  var name = "@embeddable.com/sdk-core";
21807
- var version = "3.9.2";
21944
+ var version = "3.9.4";
21808
21945
  var description = "Core Embeddable SDK module responsible for web-components bundling and publishing.";
21809
21946
  var keywords = [
21810
21947
  "embeddable",