@pd4castr/cli 1.12.0 → 1.13.1

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.
Files changed (2) hide show
  1. package/dist/index.js +88 -38
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -339,7 +339,7 @@ __name(getEnv, "getEnv");
339
339
  // package.json
340
340
  var package_default = {
341
341
  name: "@pd4castr/cli",
342
- version: "1.12.0",
342
+ version: "1.13.1",
343
343
  description: "CLI tool for creating, testing, and publishing pd4castr models",
344
344
  license: "MIT",
345
345
  main: "dist/index.js",
@@ -537,9 +537,10 @@ function registerFetchCommand(program2) {
537
537
  __name(registerFetchCommand, "registerFetchCommand");
538
538
 
539
539
  // src/commands/init/handle-action.ts
540
+ import fs6 from "fs/promises";
541
+ import os2 from "os";
540
542
  import path6 from "path";
541
543
  import * as inquirer from "@inquirer/prompts";
542
- import { ExecaError as ExecaError2 } from "execa";
543
544
  import ora2 from "ora";
544
545
  import tiged from "tiged";
545
546
 
@@ -592,16 +593,26 @@ async function handleAction2() {
592
593
  await fetchTemplate(template, projectName);
593
594
  spinner.succeed("Template fetched successfully");
594
595
  } catch (error) {
595
- spinner.fail("Error fetching template");
596
- if (error instanceof Error && error.cause instanceof ExecaError2) {
597
- console.error(error.cause.shortMessage);
598
- } else if (error instanceof Error && error.cause) {
599
- console.error(error.cause);
596
+ if (isDegitError(error)) {
597
+ spinner.fail(formatErrorMessage(DEGIT_CODE_MAP[error.code]));
598
+ } else {
599
+ spinner.fail(formatErrorMessage("UNKNOWN_ERROR"));
600
+ if (error instanceof Error) {
601
+ console.error(error.stack ?? error.message);
602
+ }
600
603
  }
601
604
  process.exit(1);
602
605
  }
603
606
  }
604
607
  __name(handleAction2, "handleAction");
608
+ var DEGIT_CODE_MAP = {
609
+ COULD_NOT_DOWNLOAD: "TEMPLATE_DOWNLOAD_FAILED",
610
+ COULD_NOT_FETCH: "TEMPLATE_DOWNLOAD_FAILED",
611
+ MISSING_REF: "TEMPLATE_NOT_FOUND",
612
+ BAD_SRC: "TEMPLATE_NOT_FOUND",
613
+ BAD_REF: "TEMPLATE_NOT_FOUND",
614
+ DEST_NOT_EMPTY: "DEST_NOT_EMPTY"
615
+ };
605
616
  async function fetchTemplate(template, projectName) {
606
617
  const templatePath = getTemplatePath(templates[template]);
607
618
  const fetcher = tiged(templatePath, {
@@ -609,9 +620,48 @@ async function fetchTemplate(template, projectName) {
609
620
  force: true
610
621
  });
611
622
  const destination = path6.join(process.cwd(), projectName);
612
- await fetcher.clone(destination);
623
+ const originalCwd = process.cwd();
624
+ let tmpDir;
625
+ try {
626
+ const tmpBase = os2.tmpdir();
627
+ await fs6.mkdir(tmpBase, {
628
+ recursive: true
629
+ });
630
+ tmpDir = await fs6.mkdtemp(path6.join(tmpBase, "pd4castr-init-"));
631
+ process.chdir(tmpDir);
632
+ } catch {
633
+ }
634
+ try {
635
+ await fetcher.clone(destination);
636
+ } finally {
637
+ try {
638
+ process.chdir(originalCwd);
639
+ } catch {
640
+ }
641
+ if (tmpDir) {
642
+ await fs6.rm(tmpDir, {
643
+ recursive: true,
644
+ force: true
645
+ }).catch(() => {
646
+ });
647
+ }
648
+ }
613
649
  }
614
650
  __name(fetchTemplate, "fetchTemplate");
651
+ function isDegitError(error) {
652
+ return error instanceof Error && "code" in error && typeof error.code === "string" && error.code in DEGIT_CODE_MAP;
653
+ }
654
+ __name(isDegitError, "isDegitError");
655
+ var ERROR_MESSAGES = {
656
+ TEMPLATE_DOWNLOAD_FAILED: "Failed to download template. Check your internet connection and try again.",
657
+ TEMPLATE_NOT_FOUND: "Failed to download template. Please try again or report this issue if it persists.",
658
+ DEST_NOT_EMPTY: "Destination directory is not empty.",
659
+ UNKNOWN_ERROR: "An unexpected error occurred. Please try again or report this issue if it persists."
660
+ };
661
+ function formatErrorMessage(code) {
662
+ return `${ERROR_MESSAGES[code]} [CODE:${code}]`;
663
+ }
664
+ __name(formatErrorMessage, "formatErrorMessage");
615
665
 
616
666
  // src/commands/init/index.ts
617
667
  function registerInitCommand(program2) {
@@ -620,20 +670,20 @@ function registerInitCommand(program2) {
620
670
  __name(registerInitCommand, "registerInitCommand");
621
671
 
622
672
  // src/commands/login/handle-action.ts
623
- import { ExecaError as ExecaError3 } from "execa";
673
+ import { ExecaError as ExecaError2 } from "execa";
624
674
  import ora3 from "ora";
625
675
  import { ZodError as ZodError3 } from "zod";
626
676
 
627
677
  // src/config/update-global-config.ts
628
- import fs6 from "fs/promises";
629
- import os2 from "os";
678
+ import fs7 from "fs/promises";
679
+ import os3 from "os";
630
680
  import path7 from "path";
631
681
  import { produce } from "immer";
632
682
  async function updateGlobalConfig(updateFn) {
633
683
  const globalConfig = await loadGlobalConfig();
634
684
  const updatedConfig = produce(globalConfig, updateFn);
635
- const configPath = path7.join(os2.homedir(), GLOBAL_CONFIG_FILE);
636
- await fs6.writeFile(configPath, JSON.stringify(updatedConfig, void 0, 2));
685
+ const configPath = path7.join(os3.homedir(), GLOBAL_CONFIG_FILE);
686
+ await fs7.writeFile(configPath, JSON.stringify(updatedConfig, void 0, 2));
637
687
  }
638
688
  __name(updateGlobalConfig, "updateGlobalConfig");
639
689
 
@@ -736,7 +786,7 @@ async function handleAction3() {
736
786
  } else if (error instanceof Error) {
737
787
  spinner.fail(error.message);
738
788
  }
739
- if (error instanceof Error && error.cause instanceof ExecaError3) {
789
+ if (error instanceof Error && error.cause instanceof ExecaError2) {
740
790
  console.error(error.cause.shortMessage);
741
791
  } else if (error instanceof Error && error.cause) {
742
792
  console.error(error.cause);
@@ -753,7 +803,7 @@ function registerLoginCommand(program2) {
753
803
  __name(registerLoginCommand, "registerLoginCommand");
754
804
 
755
805
  // src/commands/logout/handle-action.ts
756
- import { ExecaError as ExecaError4 } from "execa";
806
+ import { ExecaError as ExecaError3 } from "execa";
757
807
  import ora4 from "ora";
758
808
  import { ZodError as ZodError4 } from "zod";
759
809
  async function handleAction4() {
@@ -776,7 +826,7 @@ async function handleAction4() {
776
826
  } else if (error instanceof Error) {
777
827
  spinner.fail(error.message);
778
828
  }
779
- if (error instanceof Error && error.cause instanceof ExecaError4) {
829
+ if (error instanceof Error && error.cause instanceof ExecaError3) {
780
830
  console.error(error.cause.shortMessage);
781
831
  } else if (error instanceof Error && error.cause) {
782
832
  console.error(error.cause);
@@ -793,7 +843,7 @@ function registerLogoutCommand(program2) {
793
843
  __name(registerLogoutCommand, "registerLogoutCommand");
794
844
 
795
845
  // src/commands/publish/handle-action.ts
796
- import { ExecaError as ExecaError5 } from "execa";
846
+ import { ExecaError as ExecaError4 } from "execa";
797
847
  import express2 from "express";
798
848
  import { HTTPError as HTTPError3 } from "ky";
799
849
  import ora5 from "ora";
@@ -856,14 +906,14 @@ async function triggerModelRun(modelId, authCtx) {
856
906
  __name(triggerModelRun, "triggerModelRun");
857
907
 
858
908
  // src/config/update-project-config.ts
859
- import fs7 from "fs/promises";
909
+ import fs8 from "fs/promises";
860
910
  import path8 from "path";
861
911
  import { produce as produce2 } from "immer";
862
912
  async function updateProjectConfig(updateFn, configPath) {
863
913
  const projectConfig = await loadProjectContext(configPath);
864
914
  const updatedConfig = produce2(projectConfig.config, updateFn);
865
915
  const resolvedConfigPath = configPath ? path8.resolve(configPath) : path8.join(projectConfig.projectRoot, PROJECT_CONFIG_FILE);
866
- await fs7.writeFile(resolvedConfigPath, JSON.stringify(updatedConfig, void 0, 2));
916
+ await fs8.writeFile(resolvedConfigPath, JSON.stringify(updatedConfig, void 0, 2));
867
917
  }
868
918
  __name(updateProjectConfig, "updateProjectConfig");
869
919
 
@@ -945,7 +995,7 @@ function getDockerImage(ctx) {
945
995
  __name(getDockerImage, "getDockerImage");
946
996
 
947
997
  // src/utils/get-model-config-from-project-config.ts
948
- import fs8 from "fs/promises";
998
+ import fs9 from "fs/promises";
949
999
  import path9 from "path";
950
1000
  async function getModelConfigFromProjectConfig(ctx) {
951
1001
  const inputs = await getInputsWithInlinedSQL(ctx);
@@ -979,8 +1029,8 @@ async function getInputsWithInlinedSQL(ctx) {
979
1029
  const fetchQueryPath = path9.resolve(ctx.projectRoot, input2.fetcher.config.fetchQuery);
980
1030
  const checkQueryPath = path9.resolve(ctx.projectRoot, input2.fetcher.config.checkQuery);
981
1031
  const [fetchQuerySQL, checkQuerySQL] = await Promise.all([
982
- fs8.readFile(fetchQueryPath, "utf8"),
983
- fs8.readFile(checkQueryPath, "utf8")
1032
+ fs9.readFile(fetchQueryPath, "utf8"),
1033
+ fs9.readFile(checkQueryPath, "utf8")
984
1034
  ]);
985
1035
  const inputWithSQL = {
986
1036
  ...input2,
@@ -1004,7 +1054,7 @@ async function getSensitivitiesWithInlinedSQL(ctx) {
1004
1054
  for (const sensitivity of sensitivities) {
1005
1055
  const queryPath = path9.resolve(ctx.projectRoot, sensitivity.query);
1006
1056
  try {
1007
- const sql = await fs8.readFile(queryPath, "utf8");
1057
+ const sql = await fs9.readFile(queryPath, "utf8");
1008
1058
  sensitivitiesWithSQL.push({
1009
1059
  ...sensitivity,
1010
1060
  query: sql
@@ -1021,7 +1071,7 @@ async function getInputAggregationsWithInlinedSQL(ctx) {
1021
1071
  for (const inputAggregation of ctx.config.inputAggregations) {
1022
1072
  const queryPath = path9.resolve(ctx.projectRoot, inputAggregation.query);
1023
1073
  try {
1024
- const sql = await fs8.readFile(queryPath, "utf8");
1074
+ const sql = await fs9.readFile(queryPath, "utf8");
1025
1075
  inputAggregationsWithSQL.push({
1026
1076
  ...inputAggregation,
1027
1077
  query: sql
@@ -1039,7 +1089,7 @@ async function getrunDatetimeQuerySQL(ctx) {
1039
1089
  }
1040
1090
  const queryPath = path9.resolve(ctx.projectRoot, ctx.config.runDatetimeQuery);
1041
1091
  try {
1042
- const sql = await fs8.readFile(queryPath, "utf8");
1092
+ const sql = await fs9.readFile(queryPath, "utf8");
1043
1093
  return sql;
1044
1094
  } catch {
1045
1095
  throw new Error(`Run datetime query file not found (${ctx.config.runDatetimeQuery})`);
@@ -1135,7 +1185,7 @@ function getInputType(input2) {
1135
1185
  __name(getInputType, "getInputType");
1136
1186
 
1137
1187
  // src/docker/run-model-container.ts
1138
- import os3 from "os";
1188
+ import os4 from "os";
1139
1189
  import { execa as execa4 } from "execa";
1140
1190
 
1141
1191
  // src/docker/utils/get-input-env.ts
@@ -1187,7 +1237,7 @@ async function runModelContainer(dockerImage, webserverPort, ctx) {
1187
1237
  __name(runModelContainer, "runModelContainer");
1188
1238
  function getWSLMachineIP() {
1189
1239
  const env = getEnv();
1190
- const interfaces = os3.networkInterfaces();
1240
+ const interfaces = os4.networkInterfaces();
1191
1241
  const interfaceInfo = interfaces[env.wslNetworkInterface]?.[0];
1192
1242
  if (!interfaceInfo) {
1193
1243
  throw new Error(`WSL machine IP not found for interface \`${env.wslNetworkInterface}\``);
@@ -1253,18 +1303,18 @@ function createInputHandler(inputFilesPath, modelIOChecks, ctx) {
1253
1303
  __name(createInputHandler, "createInputHandler");
1254
1304
 
1255
1305
  // src/model-io-checks/utils/create-output-handler.ts
1256
- import fs9 from "fs/promises";
1306
+ import fs10 from "fs/promises";
1257
1307
  import path13 from "path";
1258
1308
  function createOutputHandler(modelIOChecks, ctx) {
1259
1309
  return async (req, res) => {
1260
1310
  modelIOChecks.trackOutputHandled();
1261
1311
  const outputPath = path13.join(ctx.projectRoot, TEST_OUTPUT_DATA_DIR);
1262
- await fs9.mkdir(outputPath, {
1312
+ await fs10.mkdir(outputPath, {
1263
1313
  recursive: true
1264
1314
  });
1265
1315
  const outputFilePath = path13.join(outputPath, TEST_OUTPUT_FILENAME);
1266
1316
  const outputData = JSON.stringify(req.body, null, 2);
1267
- await fs9.writeFile(outputFilePath, outputData, "utf8");
1317
+ await fs10.writeFile(outputFilePath, outputData, "utf8");
1268
1318
  return res.status(200).json({
1269
1319
  success: true
1270
1320
  });
@@ -1308,7 +1358,7 @@ async function runModelIOTests(dockerImage, options, app, ctx) {
1308
1358
  __name(runModelIOTests, "runModelIOTests");
1309
1359
 
1310
1360
  // src/commands/publish/utils/upload-static-inputs.ts
1311
- import fs10 from "fs";
1361
+ import fs11 from "fs";
1312
1362
  import path15 from "path";
1313
1363
  import ky3, { isHTTPError } from "ky";
1314
1364
  import promiseRetry from "promise-retry";
@@ -1372,8 +1422,8 @@ var RETRY_LIMIT = 3;
1372
1422
  var RETRY_DELAY_MS = 250;
1373
1423
  async function uploadWithRetry(filePath, signedUploadURL) {
1374
1424
  const upload = /* @__PURE__ */ __name(async (retry) => {
1375
- const { size } = fs10.statSync(filePath);
1376
- const body = fs10.createReadStream(filePath);
1425
+ const { size } = fs11.statSync(filePath);
1426
+ const body = fs11.createReadStream(filePath);
1377
1427
  try {
1378
1428
  const response = await ky3.put(signedUploadURL, {
1379
1429
  body,
@@ -1518,7 +1568,7 @@ import * as inquirer3 from "@inquirer/prompts";
1518
1568
  import chalk4 from "chalk";
1519
1569
 
1520
1570
  // src/utils/migrate-config.ts
1521
- import fs11 from "fs/promises";
1571
+ import fs12 from "fs/promises";
1522
1572
  import invariant4 from "tiny-invariant";
1523
1573
 
1524
1574
  // src/migrations/01-backfill-output-variable-keys.ts
@@ -1630,7 +1680,7 @@ async function migrateConfig(ctx, migrationCtx) {
1630
1680
  $$configVersion: lastMigration.version
1631
1681
  };
1632
1682
  ctx.config = config;
1633
- await fs11.writeFile(ctx.configPath, JSON.stringify(config, null, 2) + "\n", "utf8");
1683
+ await fs12.writeFile(ctx.configPath, JSON.stringify(config, null, 2) + "\n", "utf8");
1634
1684
  }
1635
1685
  __name(migrateConfig, "migrateConfig");
1636
1686
 
@@ -1960,7 +2010,7 @@ async function handleAction5(options) {
1960
2010
  } else if (error instanceof Error) {
1961
2011
  spinner.fail(error.message);
1962
2012
  }
1963
- if (error instanceof Error && error.cause instanceof ExecaError5) {
2013
+ if (error instanceof Error && error.cause instanceof ExecaError4) {
1964
2014
  console.error(error.cause.stderr);
1965
2015
  } else if (error instanceof Error && error.cause) {
1966
2016
  console.error(error.cause);
@@ -1984,7 +2034,7 @@ __name(registerPublishCommand, "registerPublishCommand");
1984
2034
 
1985
2035
  // src/commands/test/handle-action.ts
1986
2036
  import path16 from "path";
1987
- import { ExecaError as ExecaError6 } from "execa";
2037
+ import { ExecaError as ExecaError5 } from "execa";
1988
2038
  import express3 from "express";
1989
2039
  import ora6 from "ora";
1990
2040
  import { ZodError as ZodError6 } from "zod";
@@ -2115,7 +2165,7 @@ ${clickHereLink} to view output (${fileLink})
2115
2165
  } else if (error instanceof Error) {
2116
2166
  spinner.fail(error.message);
2117
2167
  }
2118
- if (error instanceof Error && error.cause instanceof ExecaError6) {
2168
+ if (error instanceof Error && error.cause instanceof ExecaError5) {
2119
2169
  console.error(error.cause.stderr);
2120
2170
  } else if (error instanceof Error && error.cause) {
2121
2171
  console.error(error.cause);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pd4castr/cli",
3
- "version": "1.12.0",
3
+ "version": "1.13.1",
4
4
  "description": "CLI tool for creating, testing, and publishing pd4castr models",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",