@sdeverywhere/create 0.2.26 → 0.2.28

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/dist/index.cjs CHANGED
@@ -143,7 +143,7 @@ async function updateSdeConfig(projDir, mdlPath, genFormat) {
143
143
  const configPath = (0, import_path.join)(projDir, "sde.config.js");
144
144
  let configText = await (0, import_promises.readFile)(configPath, "utf8");
145
145
  configText = configText.replace(`const genFormat = 'js'`, `const genFormat = '${genFormat}'`);
146
- configText = configText.replaceAll("MODEL_NAME.mdl", mdlPath);
146
+ configText = configText.replaceAll("model/MODEL_NAME.mdl", mdlPath);
147
147
  await (0, import_promises.writeFile)(configPath, configText);
148
148
  }
149
149
  async function generateYaml(projDir, kind, template) {
@@ -281,16 +281,21 @@ async function chooseGenGraphConfig(projDir, mdlVars) {
281
281
  }
282
282
  }
283
283
  );
284
+ const graphsCsvFile = (0, import_path.join)(projDir, "config", "graphs.csv");
285
+ const origGraphsCsvContent = await (0, import_promises.readFile)(graphsCsvFile, "utf8");
286
+ const graphsCsvHeader = origGraphsCsvContent.split("\n")[0];
287
+ let newGraphsCsvContent = `${graphsCsvHeader}
288
+ `;
289
+ if (varsResponse.vars.length > 0) {
290
+ const csvLine = graphsCsvLine(varsResponse.vars);
291
+ newGraphsCsvContent += `${csvLine}
292
+ `;
293
+ }
294
+ await (0, import_promises.writeFile)(graphsCsvFile, newGraphsCsvContent);
284
295
  if (varsResponse.vars.length === 0) {
285
296
  (0, import_ora2.default)().info((0, import_colors2.dim)(`No variables selected. You can edit the "${(0, import_colors2.cyan)("config/graphs.csv")}" file later.`));
286
297
  return;
287
298
  }
288
- const graphsCsvFile = (0, import_path.join)(projDir, "config", "graphs.csv");
289
- const csvLine = graphsCsvLine(varsResponse.vars);
290
- let graphsCsvContent = await (0, import_promises.readFile)(graphsCsvFile, "utf8");
291
- graphsCsvContent += `${csvLine}
292
- `;
293
- await (0, import_promises.writeFile)(graphsCsvFile, graphsCsvContent);
294
299
  (0, import_ora2.default)(
295
300
  (0, import_colors2.green)(`Added graph to "${(0, import_colors2.bold)("config/graphs.csv")}". ${(0, import_colors2.dim)("You can configure graphs in that file later.")}`)
296
301
  ).succeed();
@@ -364,24 +369,29 @@ async function chooseGenSliderConfig(projDir, mdlVars) {
364
369
  }
365
370
  }
366
371
  );
367
- if (varsResponse.vars.length === 0) {
368
- (0, import_ora2.default)().info((0, import_colors2.dim)(`No variables selected. You can edit the "${(0, import_colors2.cyan)("config/inputs.csv")}" file later.`));
369
- return;
370
- }
371
372
  const inputsCsvFile = (0, import_path.join)(projDir, "config", "inputs.csv");
372
- let inputsCsvContent = await (0, import_promises.readFile)(inputsCsvFile, "utf8");
373
- let idNumber = 1;
374
- for (const inputVarName of varsResponse.vars) {
375
- const inputVar = mdlVars.find((v) => v.name === inputVarName);
376
- if (inputVar && inputVar.kind === "const") {
377
- const defaultValue = inputVar.value;
378
- const csvLine = inputsCsvLine(inputVarName, defaultValue, idNumber.toString());
379
- inputsCsvContent += `${csvLine}
373
+ const origInputsCsvContent = await (0, import_promises.readFile)(inputsCsvFile, "utf8");
374
+ const inputsCsvHeader = origInputsCsvContent.split("\n")[0];
375
+ let newInputsCsvContent = `${inputsCsvHeader}
380
376
  `;
381
- idNumber++;
377
+ if (varsResponse.vars.length > 0) {
378
+ let idNumber = 1;
379
+ for (const inputVarName of varsResponse.vars) {
380
+ const inputVar = mdlVars.find((v) => v.name === inputVarName);
381
+ if (inputVar && inputVar.kind === "const") {
382
+ const defaultValue = inputVar.value;
383
+ const csvLine = inputsCsvLine(inputVarName, defaultValue, idNumber.toString());
384
+ newInputsCsvContent += `${csvLine}
385
+ `;
386
+ idNumber++;
387
+ }
382
388
  }
383
389
  }
384
- await (0, import_promises.writeFile)(inputsCsvFile, inputsCsvContent);
390
+ await (0, import_promises.writeFile)(inputsCsvFile, newInputsCsvContent);
391
+ if (varsResponse.vars.length === 0) {
392
+ (0, import_ora2.default)().info((0, import_colors2.dim)(`No variables selected. You can edit the "${(0, import_colors2.cyan)("config/inputs.csv")}" file later.`));
393
+ return;
394
+ }
385
395
  const slidersText = varsResponse.vars.length > 1 ? "sliders" : "sliders";
386
396
  (0, import_ora2.default)(
387
397
  (0, import_colors2.green)(
@@ -724,24 +734,6 @@ var import_path4 = require("path");
724
734
  var import_colors7 = require("kleur/colors");
725
735
  var import_ora7 = __toESM(require("ora"), 1);
726
736
  var import_prompts7 = __toESM(require("prompts"), 1);
727
- var sampleMdlContent = `{UTF-8}
728
-
729
- X = TIME
730
- ~~|
731
-
732
- Y = 0
733
- ~ [-10,10,0.1]
734
- ~
735
- |
736
-
737
- Z = X + Y
738
- ~~|
739
-
740
- INITIAL TIME = 2000 ~~|
741
- FINAL TIME = 2100 ~~|
742
- TIME STEP = 1 ~~|
743
- SAVEPER = TIME STEP ~~|
744
- `;
745
737
  async function chooseMdlFile(projDir) {
746
738
  async function getFiles(dir) {
747
739
  const dirents = await (0, import_promises2.readdir)(dir, { withFileTypes: true });
@@ -763,19 +755,11 @@ async function chooseMdlFile(projDir) {
763
755
  });
764
756
  let mdlFile;
765
757
  if (mdlFiles.length === 0) {
766
- const sampleMdlFile = (0, import_path4.join)(projDir, "sample.mdl");
767
- await (0, import_promises2.writeFile)(sampleMdlFile, sampleMdlContent);
768
- (0, import_ora7.default)(
769
- (0, import_colors7.yellow)(
770
- `No mdl files were found in "${projDir}". A "${(0, import_colors7.cyan)(
771
- "sample.mdl"
772
- )}" file has been added to the project to get you started.`
773
- )
774
- ).warn();
775
- mdlFile = "sample.mdl";
758
+ (0, import_ora7.default)((0, import_colors7.yellow)(`No mdl files were found in "${projDir}". The mdl file from the template will be used instead.`)).warn();
759
+ mdlFile = void 0;
776
760
  } else if (mdlFiles.length === 1) {
777
- (0, import_ora7.default)().succeed(`Found "${mdlFiles[0]}", will configure the project to use that mdl file.`);
778
761
  mdlFile = mdlFiles[0];
762
+ (0, import_ora7.default)().succeed(`Found "${mdlFile}", will configure the project to use that mdl file.`);
779
763
  } else {
780
764
  const options = await (0, import_prompts7.default)(
781
765
  [
@@ -794,8 +778,8 @@ async function chooseMdlFile(projDir) {
794
778
  }
795
779
  );
796
780
  mdlFile = options.mdlFile;
781
+ (0, import_ora7.default)((0, import_colors7.green)(`Using "${(0, import_colors7.bold)(mdlFile)}" as the model for the project.`)).succeed();
797
782
  }
798
- (0, import_ora7.default)((0, import_colors7.green)(`Using "${(0, import_colors7.bold)(mdlFile)}" as the model for the project.`)).succeed();
799
783
  return mdlFile;
800
784
  }
801
785
 
@@ -811,71 +795,88 @@ var import_ora8 = __toESM(require("ora"), 1);
811
795
  var import_prompts8 = __toESM(require("prompts"), 1);
812
796
  var TEMPLATES = [
813
797
  {
814
- title: "Default project",
815
- description: "Includes recommended structure with config files, app, core library, model-check, etc",
816
- value: "template-default"
798
+ title: "Default (jQuery) project",
799
+ description: "Includes recommended structure with config files, jQuery-based app, core library, model-check, etc",
800
+ value: "default"
801
+ },
802
+ {
803
+ title: "Svelte project",
804
+ description: "Includes recommended structure with config files, Svelte-based app, core library, model-check, etc",
805
+ value: "svelte"
817
806
  },
818
807
  {
819
808
  title: "Minimal project",
820
809
  description: "Includes simple config for model-check",
821
- value: "template-minimal"
810
+ value: "minimal"
822
811
  }
823
812
  ];
824
- async function chooseTemplate(projDir, args, pkgManager) {
825
- const options = await (0, import_prompts8.default)(
826
- [
813
+ async function chooseTemplate(args) {
814
+ let templateName;
815
+ if (args.template) {
816
+ templateName = args.template;
817
+ } else {
818
+ const options = await (0, import_prompts8.default)(
819
+ [
820
+ {
821
+ type: "select",
822
+ name: "template",
823
+ message: "Which template would you like to use?",
824
+ choices: TEMPLATES
825
+ }
826
+ ],
827
827
  {
828
- type: "select",
829
- name: "template",
830
- message: "Which template would you like to use?",
831
- choices: TEMPLATES
832
- }
833
- ],
834
- {
835
- onCancel: () => {
836
- (0, import_ora8.default)().info((0, import_colors8.dim)("Operation cancelled."));
837
- process.exit(0);
828
+ onCancel: () => {
829
+ (0, import_ora8.default)().info((0, import_colors8.dim)("Operation cancelled."));
830
+ process.exit(0);
831
+ }
838
832
  }
839
- }
840
- );
841
- if (args.dryRun) {
842
- (0, import_ora8.default)().info((0, import_colors8.dim)(`--dry-run enabled, skipping.`));
843
- return;
833
+ );
834
+ templateName = options.template;
844
835
  }
845
836
  const defaultRev = "main";
846
837
  const commit = args.commit || defaultRev;
847
- const templateTarget = `climateinteractive/SDEverywhere/examples/${options.template}#${commit}`;
848
- const templateSpinner = (0, import_ora8.default)("Copying project files...").start();
849
- await copyTemplate(templateTarget, projDir, templateSpinner);
850
- templateSpinner.text = (0, import_colors8.green)("Template copied!");
851
- templateSpinner.succeed();
852
- if (options.template === "template-default" && pkgManager === "pnpm") {
853
- const workspaceFile = (0, import_path5.join)(projDir, "pnpm-workspace.yaml");
854
- const workspaceContent = `packages:
855
- - packages/*
856
- `;
857
- await (0, import_promises3.writeFile)(workspaceFile, workspaceContent);
838
+ let baseTemplateUri;
839
+ if (templateName.includes(":")) {
840
+ baseTemplateUri = templateName;
841
+ } else if (templateName.includes("/")) {
842
+ baseTemplateUri = `github:${templateName}`;
843
+ } else {
844
+ baseTemplateUri = `github:climateinteractive/SDEverywhere/examples/template-${templateName}`;
858
845
  }
859
- return options.template;
846
+ const templateUri = `${baseTemplateUri}#${commit}`;
847
+ (0, import_ora8.default)((0, import_colors8.green)(`Using "${(0, import_colors8.bold)(templateUri)}" as the template for the project.`)).succeed();
848
+ return {
849
+ uri: templateUri,
850
+ name: templateName
851
+ };
860
852
  }
861
- async function copyTemplate(templateTarget, dstDir, spinner) {
853
+ async function copyTemplate(template, projDir, pkgManager, configDirExisted, mdlExisted) {
854
+ const templateSpinner = (0, import_ora8.default)("Copying template files...").start();
862
855
  try {
863
856
  const tmpDir = (0, import_fs4.mkdtempSync)((0, import_path5.join)((0, import_os.tmpdir)(), "sde-create-"));
864
- await (0, import_giget.downloadTemplate)(`github:${templateTarget}`, {
857
+ await (0, import_giget.downloadTemplate)(template.uri, {
865
858
  force: true,
866
- provider: "github",
867
859
  dir: tmpDir
868
860
  });
869
861
  if (!(0, import_fs4.existsSync)(tmpDir) || (0, import_fs4.readdirSync)(tmpDir).length === 0) {
870
862
  throw new Error("Failed to download the requested template: the temporary directory is empty.");
871
863
  }
872
- await (0, import_fs_extra.copy)(tmpDir, dstDir, {
864
+ if (configDirExisted) {
865
+ (0, import_fs4.rmSync)((0, import_path5.join)(tmpDir, "config"), { recursive: true, force: true });
866
+ }
867
+ if (mdlExisted) {
868
+ (0, import_fs4.rmSync)((0, import_path5.join)(tmpDir, "model"), { recursive: true, force: true });
869
+ }
870
+ await (0, import_fs_extra.copy)(tmpDir, projDir, {
873
871
  overwrite: false,
874
872
  errorOnExist: false
875
873
  });
874
+ if (!mdlExisted) {
875
+ (0, import_fs4.renameSync)((0, import_path5.join)(projDir, "model", "MODEL_NAME.mdl"), (0, import_path5.join)(projDir, "model", "sample.mdl"));
876
+ }
876
877
  (0, import_fs4.rmSync)(tmpDir, { recursive: true, force: true });
877
878
  } catch (e) {
878
- spinner.fail();
879
+ templateSpinner.fail();
879
880
  console.error((0, import_colors8.red)(e.message));
880
881
  console.error((0, import_colors8.yellow)("\nThere was a problem copying the template."));
881
882
  console.error(
@@ -885,6 +886,15 @@ async function copyTemplate(templateTarget, dstDir, spinner) {
885
886
  );
886
887
  process.exit(0);
887
888
  }
889
+ if ((0, import_fs4.existsSync)((0, import_path5.join)(projDir, "packages")) && pkgManager === "pnpm") {
890
+ const workspaceFile = (0, import_path5.join)(projDir, "pnpm-workspace.yaml");
891
+ const workspaceContent = `packages:
892
+ - packages/*
893
+ `;
894
+ await (0, import_promises3.writeFile)(workspaceFile, workspaceContent);
895
+ }
896
+ templateSpinner.text = (0, import_colors8.green)("Template copied!");
897
+ templateSpinner.succeed();
888
898
  }
889
899
 
890
900
  // src/index.ts
@@ -903,28 +913,38 @@ ${(0, import_colors9.bold)("Welcome to SDEverywhere!")}`);
903
913
  const projDir = await chooseProjectDir(args);
904
914
  console.log();
905
915
  const configDirExisted = (0, import_fs5.existsSync)((0, import_path6.resolve)(projDir, "config"));
906
- const templateName = await chooseTemplate(projDir, args, pkgManager);
916
+ const template = await chooseTemplate(args);
907
917
  console.log();
908
- const mdlPath = await chooseMdlFile(projDir);
918
+ let mdlPath = await chooseMdlFile(projDir);
919
+ const mdlExisted = mdlPath !== void 0;
909
920
  console.log();
921
+ if (!args.dryRun) {
922
+ await copyTemplate(template, projDir, pkgManager, configDirExisted, mdlExisted);
923
+ console.log();
924
+ }
925
+ if (mdlPath === void 0) {
926
+ mdlPath = `model${import_path6.posix.sep}sample.mdl`;
927
+ }
910
928
  const genFormat = await chooseCodeFormat();
911
929
  if (!args.dryRun) {
912
930
  await updateSdeConfig(projDir, mdlPath, genFormat);
913
- await generateSampleYamlFiles(projDir);
931
+ const modelCheckFilesExist = (0, import_fs5.existsSync)((0, import_path6.resolve)(projDir, "model", "checks")) || (0, import_fs5.existsSync)((0, import_path6.resolve)(projDir, "model", "comparisons"));
932
+ if (!modelCheckFilesExist) {
933
+ await generateSampleYamlFiles(projDir);
934
+ }
914
935
  }
915
936
  console.log();
916
- if (templateName === "template-default") {
917
- if (configDirExisted) {
918
- (0, import_ora9.default)().succeed(`Found existing "${(0, import_colors9.bold)("config")}" directory.`);
919
- (0, import_ora9.default)().info(
920
- (0, import_colors9.dim)(`You can edit the files in the "${(0, import_colors9.cyan)("config")}" directory later to configure graphs and sliders.`)
921
- );
937
+ if (configDirExisted) {
938
+ (0, import_ora9.default)().succeed(`Found existing "${(0, import_colors9.bold)("config")}" directory.`);
939
+ (0, import_ora9.default)().info(
940
+ (0, import_colors9.dim)(`You can edit the files in the "${(0, import_colors9.cyan)("config")}" directory later to configure graphs and sliders.`)
941
+ );
942
+ console.log();
943
+ } else {
944
+ const configDirExistsNow = (0, import_fs5.existsSync)((0, import_path6.resolve)(projDir, "config"));
945
+ if (configDirExistsNow && mdlExisted && !args.dryRun) {
946
+ await chooseGenConfig(projDir, mdlPath);
922
947
  console.log();
923
- } else {
924
- if (!args.dryRun) {
925
- await chooseGenConfig(projDir, mdlPath);
926
- console.log();
927
- }
928
948
  }
929
949
  }
930
950
  if (genFormat === "c") {