@sdeverywhere/create 0.2.25 → 0.2.27

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
@@ -97,7 +97,6 @@ var import_path = require("path");
97
97
  var import_colors2 = require("kleur/colors");
98
98
  var import_ora2 = __toESM(require("ora"), 1);
99
99
  var import_prompts2 = __toESM(require("prompts"), 1);
100
- var import_yaml = __toESM(require("yaml"), 1);
101
100
  var import_compile = require("@sdeverywhere/compile");
102
101
  var sampleChecksContent = `# yaml-language-server: $schema=SCHEMA_PATH
103
102
 
@@ -144,7 +143,7 @@ async function updateSdeConfig(projDir, mdlPath, genFormat) {
144
143
  const configPath = (0, import_path.join)(projDir, "sde.config.js");
145
144
  let configText = await (0, import_promises.readFile)(configPath, "utf8");
146
145
  configText = configText.replace(`const genFormat = 'js'`, `const genFormat = '${genFormat}'`);
147
- configText = configText.replaceAll("MODEL_NAME.mdl", mdlPath);
146
+ configText = configText.replaceAll("model/MODEL_NAME.mdl", mdlPath);
148
147
  await (0, import_promises.writeFile)(configPath, configText);
149
148
  }
150
149
  async function generateYaml(projDir, kind, template) {
@@ -282,16 +281,21 @@ async function chooseGenGraphConfig(projDir, mdlVars) {
282
281
  }
283
282
  }
284
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);
285
295
  if (varsResponse.vars.length === 0) {
286
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.`));
287
297
  return;
288
298
  }
289
- const graphsCsvFile = (0, import_path.join)(projDir, "config", "graphs.csv");
290
- const csvLine = graphsCsvLine(varsResponse.vars);
291
- let graphsCsvContent = await (0, import_promises.readFile)(graphsCsvFile, "utf8");
292
- graphsCsvContent += `${csvLine}
293
- `;
294
- await (0, import_promises.writeFile)(graphsCsvFile, graphsCsvContent);
295
299
  (0, import_ora2.default)(
296
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.")}`)
297
301
  ).succeed();
@@ -365,24 +369,29 @@ async function chooseGenSliderConfig(projDir, mdlVars) {
365
369
  }
366
370
  }
367
371
  );
368
- if (varsResponse.vars.length === 0) {
369
- (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.`));
370
- return;
371
- }
372
372
  const inputsCsvFile = (0, import_path.join)(projDir, "config", "inputs.csv");
373
- let inputsCsvContent = await (0, import_promises.readFile)(inputsCsvFile, "utf8");
374
- let idNumber = 1;
375
- for (const inputVarName of varsResponse.vars) {
376
- const inputVar = mdlVars.find((v) => v.name === inputVarName);
377
- if (inputVar && inputVar.kind === "const") {
378
- const defaultValue = inputVar.value;
379
- const csvLine = inputsCsvLine(inputVarName, defaultValue, idNumber.toString());
380
- inputsCsvContent += `${csvLine}
373
+ const origInputsCsvContent = await (0, import_promises.readFile)(inputsCsvFile, "utf8");
374
+ const inputsCsvHeader = origInputsCsvContent.split("\n")[0];
375
+ let newInputsCsvContent = `${inputsCsvHeader}
381
376
  `;
382
- 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
+ }
383
388
  }
384
389
  }
385
- 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
+ }
386
395
  const slidersText = varsResponse.vars.length > 1 ? "sliders" : "sliders";
387
396
  (0, import_ora2.default)(
388
397
  (0, import_colors2.green)(
@@ -421,9 +430,10 @@ async function readModelVars(projDir, mdlPath) {
421
430
  const mdlDir = (0, import_path.dirname)(mdlFile);
422
431
  const mdlName = (0, import_path.parse)(mdlFile).name;
423
432
  await (0, import_compile.parseAndGenerate)(mdlContent, spec, ["printVarList"], mdlDir, mdlName, buildDir);
424
- const varsYamlFile = (0, import_path.join)(buildDir, `${mdlName}_vars.yaml`);
425
- const varsYamlContent = await (0, import_promises.readFile)(varsYamlFile, "utf8");
426
- const varObjs = import_yaml.default.parse(varsYamlContent);
433
+ const jsonListFile = (0, import_path.join)(buildDir, `${mdlName}.json`);
434
+ const jsonListContent = await (0, import_promises.readFile)(jsonListFile, "utf8");
435
+ const jsonList = JSON.parse(jsonListContent);
436
+ const varObjs = jsonList.variables;
427
437
  const mdlVars = [];
428
438
  for (const varObj of varObjs) {
429
439
  switch (varObj.varType) {
@@ -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") {