@sdeverywhere/create 0.2.26 → 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.js CHANGED
@@ -1,7 +1,7 @@
1
1
  // src/index.ts
2
2
  import { existsSync as existsSync5 } from "fs";
3
- import { relative as relative3, resolve as resolvePath5 } from "path";
4
- import { bgCyan, black, bold as bold7, cyan as cyan6, dim as dim9, green as green9 } from "kleur/colors";
3
+ import { posix as posix2, relative as relative3, resolve as resolvePath5 } from "path";
4
+ import { bgCyan, black, bold as bold8, cyan as cyan5, dim as dim9, green as green9 } from "kleur/colors";
5
5
  import ora9 from "ora";
6
6
  import prompts9 from "prompts";
7
7
  import detectPackageManager from "which-pm-runs";
@@ -110,7 +110,7 @@ async function updateSdeConfig(projDir, mdlPath, genFormat) {
110
110
  const configPath = joinPath(projDir, "sde.config.js");
111
111
  let configText = await readFile(configPath, "utf8");
112
112
  configText = configText.replace(`const genFormat = 'js'`, `const genFormat = '${genFormat}'`);
113
- configText = configText.replaceAll("MODEL_NAME.mdl", mdlPath);
113
+ configText = configText.replaceAll("model/MODEL_NAME.mdl", mdlPath);
114
114
  await writeFile(configPath, configText);
115
115
  }
116
116
  async function generateYaml(projDir, kind, template) {
@@ -248,16 +248,21 @@ async function chooseGenGraphConfig(projDir, mdlVars) {
248
248
  }
249
249
  }
250
250
  );
251
+ const graphsCsvFile = joinPath(projDir, "config", "graphs.csv");
252
+ const origGraphsCsvContent = await readFile(graphsCsvFile, "utf8");
253
+ const graphsCsvHeader = origGraphsCsvContent.split("\n")[0];
254
+ let newGraphsCsvContent = `${graphsCsvHeader}
255
+ `;
256
+ if (varsResponse.vars.length > 0) {
257
+ const csvLine = graphsCsvLine(varsResponse.vars);
258
+ newGraphsCsvContent += `${csvLine}
259
+ `;
260
+ }
261
+ await writeFile(graphsCsvFile, newGraphsCsvContent);
251
262
  if (varsResponse.vars.length === 0) {
252
263
  ora2().info(dim2(`No variables selected. You can edit the "${cyan("config/graphs.csv")}" file later.`));
253
264
  return;
254
265
  }
255
- const graphsCsvFile = joinPath(projDir, "config", "graphs.csv");
256
- const csvLine = graphsCsvLine(varsResponse.vars);
257
- let graphsCsvContent = await readFile(graphsCsvFile, "utf8");
258
- graphsCsvContent += `${csvLine}
259
- `;
260
- await writeFile(graphsCsvFile, graphsCsvContent);
261
266
  ora2(
262
267
  green2(`Added graph to "${bold2("config/graphs.csv")}". ${dim2("You can configure graphs in that file later.")}`)
263
268
  ).succeed();
@@ -331,24 +336,29 @@ async function chooseGenSliderConfig(projDir, mdlVars) {
331
336
  }
332
337
  }
333
338
  );
334
- if (varsResponse.vars.length === 0) {
335
- ora2().info(dim2(`No variables selected. You can edit the "${cyan("config/inputs.csv")}" file later.`));
336
- return;
337
- }
338
339
  const inputsCsvFile = joinPath(projDir, "config", "inputs.csv");
339
- let inputsCsvContent = await readFile(inputsCsvFile, "utf8");
340
- let idNumber = 1;
341
- for (const inputVarName of varsResponse.vars) {
342
- const inputVar = mdlVars.find((v) => v.name === inputVarName);
343
- if (inputVar && inputVar.kind === "const") {
344
- const defaultValue = inputVar.value;
345
- const csvLine = inputsCsvLine(inputVarName, defaultValue, idNumber.toString());
346
- inputsCsvContent += `${csvLine}
340
+ const origInputsCsvContent = await readFile(inputsCsvFile, "utf8");
341
+ const inputsCsvHeader = origInputsCsvContent.split("\n")[0];
342
+ let newInputsCsvContent = `${inputsCsvHeader}
347
343
  `;
348
- idNumber++;
344
+ if (varsResponse.vars.length > 0) {
345
+ let idNumber = 1;
346
+ for (const inputVarName of varsResponse.vars) {
347
+ const inputVar = mdlVars.find((v) => v.name === inputVarName);
348
+ if (inputVar && inputVar.kind === "const") {
349
+ const defaultValue = inputVar.value;
350
+ const csvLine = inputsCsvLine(inputVarName, defaultValue, idNumber.toString());
351
+ newInputsCsvContent += `${csvLine}
352
+ `;
353
+ idNumber++;
354
+ }
349
355
  }
350
356
  }
351
- await writeFile(inputsCsvFile, inputsCsvContent);
357
+ await writeFile(inputsCsvFile, newInputsCsvContent);
358
+ if (varsResponse.vars.length === 0) {
359
+ ora2().info(dim2(`No variables selected. You can edit the "${cyan("config/inputs.csv")}" file later.`));
360
+ return;
361
+ }
352
362
  const slidersText = varsResponse.vars.length > 1 ? "sliders" : "sliders";
353
363
  ora2(
354
364
  green2(
@@ -686,29 +696,11 @@ async function chooseGitInit(projDir, args) {
686
696
  }
687
697
 
688
698
  // src/step-mdl.ts
689
- import { readdir, writeFile as writeFile2 } from "fs/promises";
690
- import { join as joinPath3, relative as relative2, resolve as resolvePath4, sep, posix } from "path";
691
- import { bold as bold6, cyan as cyan5, dim as dim7, green as green7, yellow as yellow4 } from "kleur/colors";
699
+ import { readdir } from "fs/promises";
700
+ import { relative as relative2, resolve as resolvePath4, sep, posix } from "path";
701
+ import { bold as bold6, dim as dim7, green as green7, yellow as yellow4 } from "kleur/colors";
692
702
  import ora7 from "ora";
693
703
  import prompts7 from "prompts";
694
- var sampleMdlContent = `{UTF-8}
695
-
696
- X = TIME
697
- ~~|
698
-
699
- Y = 0
700
- ~ [-10,10,0.1]
701
- ~
702
- |
703
-
704
- Z = X + Y
705
- ~~|
706
-
707
- INITIAL TIME = 2000 ~~|
708
- FINAL TIME = 2100 ~~|
709
- TIME STEP = 1 ~~|
710
- SAVEPER = TIME STEP ~~|
711
- `;
712
704
  async function chooseMdlFile(projDir) {
713
705
  async function getFiles(dir) {
714
706
  const dirents = await readdir(dir, { withFileTypes: true });
@@ -730,19 +722,11 @@ async function chooseMdlFile(projDir) {
730
722
  });
731
723
  let mdlFile;
732
724
  if (mdlFiles.length === 0) {
733
- const sampleMdlFile = joinPath3(projDir, "sample.mdl");
734
- await writeFile2(sampleMdlFile, sampleMdlContent);
735
- ora7(
736
- yellow4(
737
- `No mdl files were found in "${projDir}". A "${cyan5(
738
- "sample.mdl"
739
- )}" file has been added to the project to get you started.`
740
- )
741
- ).warn();
742
- mdlFile = "sample.mdl";
725
+ ora7(yellow4(`No mdl files were found in "${projDir}". The mdl file from the template will be used instead.`)).warn();
726
+ mdlFile = void 0;
743
727
  } else if (mdlFiles.length === 1) {
744
- ora7().succeed(`Found "${mdlFiles[0]}", will configure the project to use that mdl file.`);
745
728
  mdlFile = mdlFiles[0];
729
+ ora7().succeed(`Found "${mdlFile}", will configure the project to use that mdl file.`);
746
730
  } else {
747
731
  const options = await prompts7(
748
732
  [
@@ -761,88 +745,105 @@ async function chooseMdlFile(projDir) {
761
745
  }
762
746
  );
763
747
  mdlFile = options.mdlFile;
748
+ ora7(green7(`Using "${bold6(mdlFile)}" as the model for the project.`)).succeed();
764
749
  }
765
- ora7(green7(`Using "${bold6(mdlFile)}" as the model for the project.`)).succeed();
766
750
  return mdlFile;
767
751
  }
768
752
 
769
753
  // src/step-template.ts
770
- import { existsSync as existsSync4, mkdtempSync, readdirSync, rmSync as rmSync2 } from "fs";
771
- import { writeFile as writeFile3 } from "fs/promises";
754
+ import { existsSync as existsSync4, mkdtempSync, readdirSync, renameSync, rmSync as rmSync2 } from "fs";
755
+ import { writeFile as writeFile2 } from "fs/promises";
772
756
  import { copy } from "fs-extra";
773
757
  import { tmpdir } from "os";
774
- import { join as joinPath4 } from "path";
758
+ import { join as joinPath3 } from "path";
775
759
  import { downloadTemplate } from "giget";
776
- import { dim as dim8, green as green8, red as red3, yellow as yellow5 } from "kleur/colors";
760
+ import { bold as bold7, dim as dim8, green as green8, red as red3, yellow as yellow5 } from "kleur/colors";
777
761
  import ora8 from "ora";
778
762
  import prompts8 from "prompts";
779
763
  var TEMPLATES = [
780
764
  {
781
- title: "Default project",
782
- description: "Includes recommended structure with config files, app, core library, model-check, etc",
783
- value: "template-default"
765
+ title: "Default (jQuery) project",
766
+ description: "Includes recommended structure with config files, jQuery-based app, core library, model-check, etc",
767
+ value: "default"
768
+ },
769
+ {
770
+ title: "Svelte project",
771
+ description: "Includes recommended structure with config files, Svelte-based app, core library, model-check, etc",
772
+ value: "svelte"
784
773
  },
785
774
  {
786
775
  title: "Minimal project",
787
776
  description: "Includes simple config for model-check",
788
- value: "template-minimal"
777
+ value: "minimal"
789
778
  }
790
779
  ];
791
- async function chooseTemplate(projDir, args, pkgManager) {
792
- const options = await prompts8(
793
- [
780
+ async function chooseTemplate(args) {
781
+ let templateName;
782
+ if (args.template) {
783
+ templateName = args.template;
784
+ } else {
785
+ const options = await prompts8(
786
+ [
787
+ {
788
+ type: "select",
789
+ name: "template",
790
+ message: "Which template would you like to use?",
791
+ choices: TEMPLATES
792
+ }
793
+ ],
794
794
  {
795
- type: "select",
796
- name: "template",
797
- message: "Which template would you like to use?",
798
- choices: TEMPLATES
799
- }
800
- ],
801
- {
802
- onCancel: () => {
803
- ora8().info(dim8("Operation cancelled."));
804
- process.exit(0);
795
+ onCancel: () => {
796
+ ora8().info(dim8("Operation cancelled."));
797
+ process.exit(0);
798
+ }
805
799
  }
806
- }
807
- );
808
- if (args.dryRun) {
809
- ora8().info(dim8(`--dry-run enabled, skipping.`));
810
- return;
800
+ );
801
+ templateName = options.template;
811
802
  }
812
803
  const defaultRev = "main";
813
804
  const commit = args.commit || defaultRev;
814
- const templateTarget = `climateinteractive/SDEverywhere/examples/${options.template}#${commit}`;
815
- const templateSpinner = ora8("Copying project files...").start();
816
- await copyTemplate(templateTarget, projDir, templateSpinner);
817
- templateSpinner.text = green8("Template copied!");
818
- templateSpinner.succeed();
819
- if (options.template === "template-default" && pkgManager === "pnpm") {
820
- const workspaceFile = joinPath4(projDir, "pnpm-workspace.yaml");
821
- const workspaceContent = `packages:
822
- - packages/*
823
- `;
824
- await writeFile3(workspaceFile, workspaceContent);
805
+ let baseTemplateUri;
806
+ if (templateName.includes(":")) {
807
+ baseTemplateUri = templateName;
808
+ } else if (templateName.includes("/")) {
809
+ baseTemplateUri = `github:${templateName}`;
810
+ } else {
811
+ baseTemplateUri = `github:climateinteractive/SDEverywhere/examples/template-${templateName}`;
825
812
  }
826
- return options.template;
813
+ const templateUri = `${baseTemplateUri}#${commit}`;
814
+ ora8(green8(`Using "${bold7(templateUri)}" as the template for the project.`)).succeed();
815
+ return {
816
+ uri: templateUri,
817
+ name: templateName
818
+ };
827
819
  }
828
- async function copyTemplate(templateTarget, dstDir, spinner) {
820
+ async function copyTemplate(template, projDir, pkgManager, configDirExisted, mdlExisted) {
821
+ const templateSpinner = ora8("Copying template files...").start();
829
822
  try {
830
- const tmpDir = mkdtempSync(joinPath4(tmpdir(), "sde-create-"));
831
- await downloadTemplate(`github:${templateTarget}`, {
823
+ const tmpDir = mkdtempSync(joinPath3(tmpdir(), "sde-create-"));
824
+ await downloadTemplate(template.uri, {
832
825
  force: true,
833
- provider: "github",
834
826
  dir: tmpDir
835
827
  });
836
828
  if (!existsSync4(tmpDir) || readdirSync(tmpDir).length === 0) {
837
829
  throw new Error("Failed to download the requested template: the temporary directory is empty.");
838
830
  }
839
- await copy(tmpDir, dstDir, {
831
+ if (configDirExisted) {
832
+ rmSync2(joinPath3(tmpDir, "config"), { recursive: true, force: true });
833
+ }
834
+ if (mdlExisted) {
835
+ rmSync2(joinPath3(tmpDir, "model"), { recursive: true, force: true });
836
+ }
837
+ await copy(tmpDir, projDir, {
840
838
  overwrite: false,
841
839
  errorOnExist: false
842
840
  });
841
+ if (!mdlExisted) {
842
+ renameSync(joinPath3(projDir, "model", "MODEL_NAME.mdl"), joinPath3(projDir, "model", "sample.mdl"));
843
+ }
843
844
  rmSync2(tmpDir, { recursive: true, force: true });
844
845
  } catch (e) {
845
- spinner.fail();
846
+ templateSpinner.fail();
846
847
  console.error(red3(e.message));
847
848
  console.error(yellow5("\nThere was a problem copying the template."));
848
849
  console.error(
@@ -852,6 +853,15 @@ async function copyTemplate(templateTarget, dstDir, spinner) {
852
853
  );
853
854
  process.exit(0);
854
855
  }
856
+ if (existsSync4(joinPath3(projDir, "packages")) && pkgManager === "pnpm") {
857
+ const workspaceFile = joinPath3(projDir, "pnpm-workspace.yaml");
858
+ const workspaceContent = `packages:
859
+ - packages/*
860
+ `;
861
+ await writeFile2(workspaceFile, workspaceContent);
862
+ }
863
+ templateSpinner.text = green8("Template copied!");
864
+ templateSpinner.succeed();
855
865
  }
856
866
 
857
867
  // src/index.ts
@@ -864,34 +874,44 @@ async function main() {
864
874
  ora9().info(dim9(`--dry-run enabled, no files will be written.`));
865
875
  }
866
876
  console.log(`
867
- ${bold7("Welcome to SDEverywhere!")}`);
877
+ ${bold8("Welcome to SDEverywhere!")}`);
868
878
  console.log(`Let's create a new SDEverywhere project for your model.
869
879
  `);
870
880
  const projDir = await chooseProjectDir(args);
871
881
  console.log();
872
882
  const configDirExisted = existsSync5(resolvePath5(projDir, "config"));
873
- const templateName = await chooseTemplate(projDir, args, pkgManager);
883
+ const template = await chooseTemplate(args);
874
884
  console.log();
875
- const mdlPath = await chooseMdlFile(projDir);
885
+ let mdlPath = await chooseMdlFile(projDir);
886
+ const mdlExisted = mdlPath !== void 0;
876
887
  console.log();
888
+ if (!args.dryRun) {
889
+ await copyTemplate(template, projDir, pkgManager, configDirExisted, mdlExisted);
890
+ console.log();
891
+ }
892
+ if (mdlPath === void 0) {
893
+ mdlPath = `model${posix2.sep}sample.mdl`;
894
+ }
877
895
  const genFormat = await chooseCodeFormat();
878
896
  if (!args.dryRun) {
879
897
  await updateSdeConfig(projDir, mdlPath, genFormat);
880
- await generateSampleYamlFiles(projDir);
898
+ const modelCheckFilesExist = existsSync5(resolvePath5(projDir, "model", "checks")) || existsSync5(resolvePath5(projDir, "model", "comparisons"));
899
+ if (!modelCheckFilesExist) {
900
+ await generateSampleYamlFiles(projDir);
901
+ }
881
902
  }
882
903
  console.log();
883
- if (templateName === "template-default") {
884
- if (configDirExisted) {
885
- ora9().succeed(`Found existing "${bold7("config")}" directory.`);
886
- ora9().info(
887
- dim9(`You can edit the files in the "${cyan6("config")}" directory later to configure graphs and sliders.`)
888
- );
904
+ if (configDirExisted) {
905
+ ora9().succeed(`Found existing "${bold8("config")}" directory.`);
906
+ ora9().info(
907
+ dim9(`You can edit the files in the "${cyan5("config")}" directory later to configure graphs and sliders.`)
908
+ );
909
+ console.log();
910
+ } else {
911
+ const configDirExistsNow = existsSync5(resolvePath5(projDir, "config"));
912
+ if (configDirExistsNow && mdlExisted && !args.dryRun) {
913
+ await chooseGenConfig(projDir, mdlPath);
889
914
  console.log();
890
- } else {
891
- if (!args.dryRun) {
892
- await chooseGenConfig(projDir, mdlPath);
893
- console.log();
894
- }
895
915
  }
896
916
  }
897
917
  if (genFormat === "c") {
@@ -909,9 +929,9 @@ ${bgCyan(black(" Next steps "))}
909
929
  const relProjDir = relative3(process.cwd(), projDir);
910
930
  const devCmd = pkgManager === "npm" ? "npm run dev" : `${pkgManager} dev`;
911
931
  if (relProjDir !== "") {
912
- console.log(`You can now ${bold7(cyan6("cd"))} into the ${bold7(cyan6(relProjDir))} project directory.`);
932
+ console.log(`You can now ${bold8(cyan5("cd"))} into the ${bold8(cyan5(relProjDir))} project directory.`);
913
933
  }
914
- console.log(`Run ${bold7(cyan6(devCmd))} to start the local dev server. ${bold7(cyan6("CTRL-C"))} to close.`);
934
+ console.log(`Run ${bold8(cyan5(devCmd))} to start the local dev server. ${bold8(cyan5("CTRL-C"))} to close.`);
915
935
  console.log("");
916
936
  }
917
937
  export {