@sdeverywhere/create 0.2.12 → 0.2.14

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
@@ -615,8 +615,16 @@ async function chooseGitInit(projDir, args) {
615
615
  (0, import_ora5.default)().info((0, import_colors5.dim)(`No problem! You can come back and run ${(0, import_colors5.cyan)(`git init`)} later.`));
616
616
  return;
617
617
  }
618
- await (0, import_execa3.execaCommand)("git init", { cwd: projDir });
619
- (0, import_ora5.default)().succeed((0, import_colors5.green)("Git repository initialized!"));
618
+ try {
619
+ await (0, import_execa3.execaCommand)("git init", { cwd: projDir });
620
+ (0, import_ora5.default)().succeed((0, import_colors5.green)("Git repository initialized!"));
621
+ } catch (e) {
622
+ (0, import_ora5.default)().warn(
623
+ (0, import_colors5.yellow)(
624
+ `There was a problem initializing the Git repository, but no problem, you can run ${(0, import_colors5.cyan)(`git init`)} later.`
625
+ )
626
+ );
627
+ }
620
628
  }
621
629
 
622
630
  // src/step-mdl.ts
@@ -706,7 +714,7 @@ var import_promises3 = require("fs/promises");
706
714
  var import_fs_extra = require("fs-extra");
707
715
  var import_os = require("os");
708
716
  var import_path5 = require("path");
709
- var import_degit = __toESM(require("degit"), 1);
717
+ var import_giget = require("giget");
710
718
  var import_colors7 = require("kleur/colors");
711
719
  var import_ora7 = __toESM(require("ora"), 1);
712
720
  var import_prompts7 = __toESM(require("prompts"), 1);
@@ -745,10 +753,9 @@ async function chooseTemplate(projDir, args, pkgManager) {
745
753
  }
746
754
  const defaultRev = "main";
747
755
  const commit = args.commit || defaultRev;
748
- const templateTarget = `climateinteractive/SDEverywhere/examples/${options.template}`;
749
- const hash = `#${commit}`;
756
+ const templateTarget = `climateinteractive/SDEverywhere/examples/${options.template}#${commit}`;
750
757
  const templateSpinner = (0, import_ora7.default)("Copying project files...").start();
751
- await runDegit(templateTarget, hash, projDir, args, templateSpinner);
758
+ await copyTemplate(templateTarget, projDir, templateSpinner);
752
759
  templateSpinner.text = (0, import_colors7.green)("Template copied!");
753
760
  templateSpinner.succeed();
754
761
  if (options.template === "template-default" && pkgManager === "pnpm") {
@@ -760,23 +767,16 @@ async function chooseTemplate(projDir, args, pkgManager) {
760
767
  }
761
768
  return options.template;
762
769
  }
763
- async function runDegit(templateTarget, hash, dstDir, args, spinner) {
764
- const verbose = args.verbose;
765
- const emitter = (0, import_degit.default)(`${templateTarget}${hash}`, {
766
- cache: false,
767
- force: true,
768
- verbose
769
- });
770
+ async function copyTemplate(templateTarget, dstDir, spinner) {
770
771
  try {
771
- if (verbose) {
772
- emitter.on("info", (info) => {
773
- console.log(info.message);
774
- });
775
- }
776
772
  const tmpDir = (0, import_fs4.mkdtempSync)((0, import_path5.join)((0, import_os.tmpdir)(), "sde-create-"));
777
- await emitter.clone(tmpDir);
773
+ await (0, import_giget.downloadTemplate)(`github:${templateTarget}`, {
774
+ force: true,
775
+ provider: "github",
776
+ dir: tmpDir
777
+ });
778
778
  if (!(0, import_fs4.existsSync)(tmpDir) || (0, import_fs4.readdirSync)(tmpDir).length === 0) {
779
- throw new Error("The requested template failed to download");
779
+ throw new Error("Failed to download the requested template: the temporary directory is empty.");
780
780
  }
781
781
  await (0, import_fs_extra.copy)(tmpDir, dstDir, {
782
782
  overwrite: false,
@@ -786,10 +786,10 @@ async function runDegit(templateTarget, hash, dstDir, args, spinner) {
786
786
  } catch (e) {
787
787
  spinner.fail();
788
788
  console.error((0, import_colors7.red)(e.message));
789
- console.error((0, import_colors7.yellow)("There was a problem copying the template."));
789
+ console.error((0, import_colors7.yellow)("\nThere was a problem copying the template."));
790
790
  console.error(
791
791
  (0, import_colors7.yellow)(
792
- "Please file a new issue with the command output here: https://github.com/climateinteractive/sdeverywhere/issues"
792
+ "Please start a new discussion thread and include the command output so that we can help:\n https://github.com/climateinteractive/SDEverywhere/discussions/categories/q-a\n"
793
793
  )
794
794
  );
795
795
  process.exit(0);
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/step-config.ts","../src/step-deps.ts","../src/step-directory.ts","../src/step-emsdk.ts","../src/step-git.ts","../src/step-mdl.ts","../src/step-template.ts"],"sourcesContent":["// Copyright (c) 2022 Climate Interactive / New Venture Fund\n\nimport { relative } from 'path'\n\nimport { bgCyan, black, bold, cyan, green } from 'kleur/colors'\nimport ora from 'ora'\nimport prompts from 'prompts'\nimport detectPackageManager from 'which-pm-runs'\nimport yargs from 'yargs-parser'\n\nimport { chooseGenConfig, generateCheckYaml, updateSdeConfig } from './step-config'\nimport { chooseInstallDeps } from './step-deps'\nimport { chooseProjectDir } from './step-directory'\nimport { chooseInstallEmsdk } from './step-emsdk'\nimport { chooseGitInit } from './step-git'\nimport { chooseMdlFile } from './step-mdl'\nimport { chooseTemplate } from './step-template'\n\nexport async function main(): Promise<void> {\n // Detect the package manager\n const pkgManager = detectPackageManager()?.name || 'npm'\n\n // Parse command line arguments\n const args = yargs(process.argv)\n prompts.override(args)\n\n // Display welcome message\n console.log(`\\n${bold('Welcome to SDEverywhere!')}`)\n console.log(`Let's create a new SDEverywhere project for your model.\\n`)\n\n // Prompt the user to select a project directory\n const projDir = await chooseProjectDir(args)\n console.log()\n\n // Prompt the user to select a template\n const templateName = await chooseTemplate(projDir, args, pkgManager)\n console.log()\n\n // Prompt the user to select an mdl file\n const mdlPath = await chooseMdlFile(projDir)\n\n // Update the `sde.config.js` file to use the chosen mdl file and\n // generate a sample `.check.yaml` file\n await updateSdeConfig(projDir, mdlPath)\n await generateCheckYaml(projDir, mdlPath)\n console.log()\n\n // If the user chose the default template, offer to set up CSV files\n if (templateName === 'template-default' && !args.dryRun) {\n await chooseGenConfig(projDir, mdlPath)\n console.log()\n }\n\n // Prompt the user to install Emscripten SDK\n await chooseInstallEmsdk(projDir, args)\n console.log()\n\n // Prompt the user to install dependencies\n await chooseInstallDeps(projDir, args, pkgManager)\n console.log()\n\n // Prompt the user to initialize a git repo\n await chooseGitInit(projDir, args)\n console.log()\n\n ora(green('Setup complete!')).succeed()\n\n console.log(`\\n${bgCyan(black(' Next steps '))}\\n`)\n\n const relProjDir = relative(process.cwd(), projDir)\n const devCmd = pkgManager === 'npm' ? 'npm run dev' : `${pkgManager} dev`\n\n // If the project dir is the current dir, no need to tell users to cd\n if (relProjDir !== '') {\n console.log(`You can now ${bold(cyan('cd'))} into the ${bold(cyan(relProjDir))} project directory.`)\n }\n console.log(`Run ${bold(cyan(devCmd))} to start the local dev server. ${bold(cyan('CTRL-C'))} to close.`)\n console.log('')\n}\n","// Copyright (c) 2022 Climate Interactive / New Venture Fund\n\nimport { existsSync } from 'fs'\nimport { mkdir, readFile, writeFile } from 'fs/promises'\nimport { dirname, join as joinPath, parse as parsePath, relative, resolve as resolvePath } from 'path'\n\nimport { bold, cyan, dim, green, reset, yellow } from 'kleur/colors'\nimport ora from 'ora'\nimport type { Choice } from 'prompts'\nimport prompts from 'prompts'\nimport yaml from 'yaml'\n\nimport { parseAndGenerate, preprocessModel } from '@sdeverywhere/compile'\n\ninterface MdlConstVariable {\n kind: 'const'\n name: string\n value: number\n}\n\ninterface MdlAuxVariable {\n kind: 'aux'\n name: string\n}\n\ninterface MdlLevelVariable {\n kind: 'level'\n name: string\n}\n\ntype MdlVariable = MdlConstVariable | MdlAuxVariable | MdlLevelVariable\n\nconst sampleCheckContent = `\\\n# yaml-language-server: $schema=SCHEMA_PATH\n\n# NOTE: This is just a simple check to get you started. Replace \"Some output\" with\n# the name of some variable you'd like to test. Additional tests can be developed\n# in the \"playground\" (beta) inside the model-check report.\n- describe: Some output\n tests:\n - it: should be > 0 for all input scenarios\n scenarios:\n - preset: matrix\n datasets:\n - name: Some output\n predicates:\n - gt: 0\n`\n\nexport async function updateSdeConfig(projDir: string, mdlPath: string): Promise<void> {\n // Read the `sde.config.js` file from the template\n const configPath = joinPath(projDir, 'sde.config.js')\n let configText = await readFile(configPath, 'utf8')\n\n // Replace instances of `MODEL_NAME.mdl` with the path to the chosen mdl file\n configText = configText.replaceAll('MODEL_NAME.mdl', mdlPath)\n\n // Write the updated file\n await writeFile(configPath, configText)\n}\n\nexport async function generateCheckYaml(projDir: string, mdlPath: string): Promise<void> {\n // Generate a sample `{mdl}.check.yaml` file if one doesn't already exist\n // TODO: Make this optional (ask user first)?\n const checkYamlFile = mdlPath.replace('.mdl', '.check.yaml')\n const checkYamlPath = joinPath(projDir, checkYamlFile)\n if (!existsSync(checkYamlPath)) {\n // Get relative path from yaml file parent dir to project dir\n let relProjPath = relative(dirname(checkYamlPath), projDir)\n if (relProjPath.length === 0) {\n relProjPath = './'\n }\n\n // TODO: This path is normally different depending on whether using npm/yarn or\n // pnpm. For npm/yarn, `check-core` is hoisted under top-level `node_modules`,\n // but for pnpm, it is nested under `node_modules/.pnpm`. As an ugly workaround\n // the templates declare `check-core` as a direct dependency even though it is\n // not really needed (a transitive dependency via `plugin-check` would normally\n // suffice). This allows us to use the same path here that works for all\n // three package managers.\n const nodeModulesPart = joinPath(relProjPath, 'node_modules')\n const checkCorePart = '@sdeverywhere/check-core/schema/check.schema.json'\n const schemaPath = `${nodeModulesPart}/${checkCorePart}`\n const checkContent = sampleCheckContent.replace('SCHEMA_PATH', schemaPath)\n await writeFile(checkYamlPath, checkContent)\n }\n}\n\nexport async function chooseGenConfig(projDir: string, mdlPath: string): Promise<void> {\n // TODO: For now we eagerly read the mdl file; maybe change this to only load it if\n // the user chooses to generate graph and/or slider config\n let mdlVars: MdlVariable[]\n try {\n // Get the list of variables available in the model\n mdlVars = await readModelVars(projDir, mdlPath)\n } catch (e) {\n console.log(e)\n ora(\n yellow('The mdl file failed to load. We will continue setting things up, and you can diagnose the issue later.')\n ).warn()\n return\n }\n\n // Extract `INITIAL TIME` and `FINAL TIME` values and remove special control variables from the list\n let initialTime: number\n let finalTime: number\n const validVars: MdlVariable[] = []\n for (const v of mdlVars) {\n const varName = v.name.toLowerCase()\n let skip = false\n switch (varName) {\n case 'final time':\n skip = true\n if (v.kind === 'const') {\n finalTime = v.value\n }\n break\n case 'initial time':\n skip = true\n if (v.kind === 'const') {\n initialTime = v.value\n }\n break\n case 'saveper':\n case 'time':\n case 'time step':\n skip = true\n break\n default:\n break\n }\n if (!skip) {\n validVars.push(v)\n }\n }\n\n // Set the values in `model.csv`\n if (initialTime === undefined) {\n initialTime = 0\n }\n if (finalTime === undefined) {\n finalTime = 100\n }\n\n // TODO: Auto-detect dat files that are referenced by the mdl and include them here\n const datFiles: string[] = []\n const datPart = datFiles.join(';')\n\n // Preserve the `model.csv` header but drop other existing content (if any)\n const modelCsvFile = joinPath(projDir, 'config', 'model.csv')\n const origModelCsvContent = await readFile(modelCsvFile, 'utf8')\n const modelCsvHeader = origModelCsvContent.split('\\n')[0]\n\n // Add line and write out updated `model.csv`\n const modelCsvLine = `${initialTime},${finalTime},${datPart}`\n const newModelCsvContent = `${modelCsvHeader}\\n${modelCsvLine}\\n`\n await writeFile(modelCsvFile, newModelCsvContent)\n\n // See if the user wants to generate graph config\n await chooseGenGraphConfig(projDir, validVars)\n console.log()\n\n // See if the user wants to generate slider config\n await chooseGenSliderConfig(projDir, validVars)\n}\n\nasync function chooseGenGraphConfig(projDir: string, mdlVars: MdlVariable[]): Promise<void> {\n // Prompt the user\n const genResponse = await prompts(\n {\n type: 'confirm',\n name: 'genGraph',\n message: `Would you like to configure a graph to get you started? ${reset(dim('(recommended)'))}`,\n initial: true\n },\n {\n onCancel: () => {\n ora().info(dim('Operation cancelled.'))\n process.exit(0)\n }\n }\n )\n\n // Handle response\n if (!genResponse.genGraph) {\n ora().info(dim(`No problem! You can edit the \"${cyan('config/graphs.csv')}\" file later.`))\n return\n }\n\n // Offer multi-select with available output variables\n const outputVarNames: string[] = []\n for (const mdlVar of mdlVars) {\n if (mdlVar.kind === 'aux' || mdlVar.kind === 'level') {\n outputVarNames.push(mdlVar.name)\n }\n }\n outputVarNames.sort((a, b) => {\n return a.toLowerCase().localeCompare(b.toLowerCase())\n })\n const choices = outputVarNames.map(f => {\n return {\n title: f,\n value: f\n } as Choice\n })\n const varsResponse = await prompts(\n {\n type: 'autocompleteMultiselect',\n name: 'vars',\n message: 'Choose up to three output variables to display in the graph',\n choices,\n max: 3\n },\n {\n onCancel: () => {\n ora().info(dim('Operation cancelled.'))\n process.exit(0)\n }\n }\n )\n\n if (varsResponse.vars.length === 0) {\n ora().info(dim(`No variables selected. You can edit the \"${cyan('config/graphs.csv')}\" file later.`))\n return\n }\n\n // Add line to `graphs.csv`\n const graphsCsvFile = joinPath(projDir, 'config', 'graphs.csv')\n const csvLine = graphsCsvLine(varsResponse.vars)\n let graphsCsvContent = await readFile(graphsCsvFile, 'utf8')\n graphsCsvContent += `${csvLine}\\n`\n await writeFile(graphsCsvFile, graphsCsvContent)\n\n ora(\n green(`Added graph to \"${bold('config/graphs.csv')}\". ${dim('You can configure graphs in that file later.')}`)\n ).succeed()\n}\n\n// TODO: Ideally the `plugin-config` package would expose an API for generating CSV, but\n// until then, we will generate a comma-separated line of values in hardcoded fashion\nfunction graphsCsvLine(outputVarNames: string[]): string {\n const colors = ['blue', 'red', 'green']\n\n // Fill the line with blanks initially, then set the small subset of fields\n const a = Array(131).fill('')\n // id\n a[0] = '1'\n // parent menu\n a[2] = 'Graphs'\n // graph title\n a[3] = 'Graph Title'\n // kind\n a[7] = 'line'\n // Plots start at 26\n let index = 26\n let colorIndex = 0\n for (const outputVarName of outputVarNames) {\n // Surround the name in quotes if it contains a comma\n const escapedName = escapeCsvField(outputVarName)\n // plot N variable\n a[index + 0] = escapedName\n // plot N style\n a[index + 2] = 'line'\n // plot N label\n a[index + 3] = escapedName\n // plot N color\n a[index + 4] = colors[colorIndex]\n index += 7\n colorIndex++\n }\n\n return a.join(',')\n}\n\nasync function chooseGenSliderConfig(projDir: string, mdlVars: MdlVariable[]): Promise<void> {\n // Prompt the user\n const genResponse = await prompts(\n {\n type: 'confirm',\n name: 'genSliders',\n message: `Would you like to configure a few sliders to get you started? ${reset(dim('(recommended)'))}`,\n initial: true\n },\n {\n onCancel: () => {\n ora().info(dim('Operation cancelled.'))\n process.exit(0)\n }\n }\n )\n\n // Handle response\n if (!genResponse.genSliders) {\n ora().info(dim(`No problem! You can edit the \"${cyan('config/inputs.csv')}\" file later.`))\n return\n }\n\n // Offer multi-select with available input variables\n const inputVarNames: string[] = []\n for (const mdlVar of mdlVars) {\n if (mdlVar.kind === 'const') {\n inputVarNames.push(mdlVar.name)\n }\n }\n inputVarNames.sort((a, b) => {\n return a.toLowerCase().localeCompare(b.toLowerCase())\n })\n const choices = inputVarNames.map(f => {\n return {\n title: f,\n value: f\n } as Choice\n })\n const varsResponse = await prompts(\n {\n type: 'autocompleteMultiselect',\n name: 'vars',\n message: 'Choose up to three input variables to control with sliders',\n choices,\n max: 3\n },\n {\n onCancel: () => {\n ora().info(dim('Operation cancelled.'))\n process.exit(0)\n }\n }\n )\n\n if (varsResponse.vars.length === 0) {\n ora().info(dim(`No variables selected. You can edit the \"${cyan('config/inputs.csv')}\" file later.`))\n return\n }\n\n // Add lines to `inputs.csv`\n const inputsCsvFile = joinPath(projDir, 'config', 'inputs.csv')\n let inputsCsvContent = await readFile(inputsCsvFile, 'utf8')\n let idNumber = 1\n for (const inputVarName of varsResponse.vars) {\n const inputVar = mdlVars.find(v => v.name === inputVarName)\n if (inputVar && inputVar.kind === 'const') {\n const defaultValue = inputVar.value\n const csvLine = inputsCsvLine(inputVarName, defaultValue, idNumber.toString())\n inputsCsvContent += `${csvLine}\\n`\n idNumber++\n }\n }\n await writeFile(inputsCsvFile, inputsCsvContent)\n\n const slidersText = varsResponse.vars.length > 1 ? 'sliders' : 'sliders'\n ora(\n green(\n `Added ${slidersText} to \"${bold('config/inputs.csv')}\". ${dim('You can configure sliders in that file later.')}`\n )\n ).succeed()\n}\n\n// TODO: Ideally the `plugin-config` package would expose an API for generating CSV, but\n// until then, we will generate a comma-separated line of values in hardcoded fashion\nfunction inputsCsvLine(inputVarName: string, defaultValue: number, id: string): string {\n // Surround the name in quotes if it contains a comma\n const escapedName = escapeCsvField(inputVarName)\n\n // TODO: Be smarter about automatically choosing min/max/step values\n const minValue = defaultValue - 1\n const maxValue = defaultValue + 1\n const step = 0.1\n\n // Fill the line with blanks initially, then set the small subset of fields\n const a = Array(28).fill('')\n // id\n a[0] = id\n // input type\n a[1] = 'slider'\n // viewid\n a[2] = 'view1'\n // varname\n a[3] = escapedName\n // label\n a[4] = escapedName\n // group name\n a[6] = 'Sliders'\n // slider min\n a[7] = minValue\n // slider max\n a[8] = maxValue\n // slider default\n a[9] = defaultValue\n // slider step\n a[10] = step\n // units\n a[11] = '(units)'\n\n return a.join(',')\n}\n\nfunction escapeCsvField(s: string): string {\n // Surround the value in quotes if it contains a comma\n // TODO: Escape double quotes as well\n return s.includes(',') ? `\"${s}\"` : s\n}\n\nasync function readModelVars(projDir: string, mdlPath: string): Promise<MdlVariable[]> {\n // TODO: This function contains a subset of the logic from `sde-generate.js` in\n // the `cli` package; should revisit\n // let { modelDirname, modelName, modelPathname } = modelPathProps(model)\n\n // Ensure the `build` directory exists (under the `sde-prep` directory)\n const buildDir = resolvePath(projDir, 'sde-prep', 'build')\n await mkdir(buildDir, { recursive: true })\n\n // Use an empty model spec; this will make SDE look at all variables in the mdl\n const spec = {}\n\n // Try parsing the mdl file to generate the list of variables\n // TODO: This depends on some `compile` package APIs that are not yet considered stable.\n // Ideally we'd use an API that does not write files but instead returns an in-memory\n // object in a specified format.\n\n // Read and preprocess the model\n const mdlFile = resolvePath(projDir, mdlPath)\n const preprocessed = preprocessModel(mdlFile, spec, 'genc', /*writeFiles=*/ false)\n\n // Parse the model and generate the variable list\n const mdlDir = dirname(mdlFile)\n const mdlName = parsePath(mdlFile).name\n await parseAndGenerate(preprocessed, spec, ['printVarList'], mdlDir, mdlName, buildDir)\n\n // Read `build/{mdl}_vars.yaml`\n // TODO: For now the printVarList code only outputs txt and yaml files; we'll use the\n // yaml file for now, but that means we have a dependency on the `yaml` package. Once\n // we change the `compile` package to output JSON, we'll need to change this code.\n const varsYamlFile = joinPath(buildDir, `${mdlName}_vars.yaml`)\n const varsYamlContent = await readFile(varsYamlFile, 'utf8')\n const varObjs = yaml.parse(varsYamlContent)\n\n // Create a simplified array of variables\n const mdlVars: MdlVariable[] = []\n for (const varObj of varObjs) {\n // Only include certain variables for now\n // TODO: Include \"data\" vars\n switch (varObj.varType) {\n case 'const':\n mdlVars.push({\n kind: 'const',\n name: varObj.modelLHS,\n value: Number.parseFloat(varObj.modelFormula)\n })\n break\n case 'aux':\n mdlVars.push({\n kind: 'aux',\n name: varObj.modelLHS\n })\n break\n case 'level':\n mdlVars.push({\n kind: 'level',\n name: varObj.modelLHS\n })\n break\n default:\n break\n }\n }\n\n return mdlVars\n}\n","// Copyright (c) 2022 Climate Interactive / New Venture Fund\n\nimport { execa } from 'execa'\nimport { bold, cyan, dim, green, reset, yellow } from 'kleur/colors'\nimport ora from 'ora'\nimport prompts from 'prompts'\nimport type { Arguments } from 'yargs-parser'\n\nexport async function chooseInstallDeps(projDir: string, args: Arguments, pkgManager: string): Promise<void> {\n // Prompt the user\n const installResponse = await prompts(\n {\n type: 'confirm',\n name: 'install',\n message: `Would you like to install ${pkgManager} dependencies? ${reset(dim('(recommended)'))}`,\n initial: true\n },\n {\n onCancel: () => {\n ora().info(\n dim('Operation cancelled. Your project folder has been created, but no dependencies have been installed.')\n )\n process.exit(0)\n }\n }\n )\n\n // Handle response\n if (args.dryRun) {\n ora().info(dim(`--dry-run enabled, skipping.`))\n return\n } else if (!installResponse.install) {\n ora().info(dim(`No problem! Remember to install dependencies after setup.`))\n return\n }\n\n // Install dependencies\n const installExec = execa(pkgManager, ['install'], { cwd: projDir })\n const installingPackagesMsg = 'Installing packages...'\n const installSpinner = ora(installingPackagesMsg).start()\n try {\n await new Promise<void>((resolve, reject) => {\n installExec.stdout?.on('data', function (data) {\n installSpinner.text = `${installingPackagesMsg}\\n${bold(`[${pkgManager}]`)} ${data}`\n })\n installExec.stderr?.on('data', function (data) {\n installSpinner.text = `${installingPackagesMsg}\\n${bold(`[${pkgManager}]`)} ${data}`\n })\n installExec.on('error', error => reject(error))\n installExec.on('close', code => {\n if (code !== 0) {\n reject(`Install failed (code=${code})`)\n } else {\n resolve()\n }\n })\n })\n installSpinner.text = green('Packages installed!')\n installSpinner.succeed()\n } catch (e) {\n installSpinner.text = yellow(\n `There was an error installing packages. Try running ${cyan(\n `${pkgManager} install`\n )} in your project directory later.`\n )\n installSpinner.warn()\n }\n}\n","// Copyright (c) 2022 Climate Interactive / New Venture Fund\n\nimport { existsSync } from 'fs'\nimport { resolve as resolvePath } from 'path'\n\nimport { bold, dim, green, red } from 'kleur/colors'\nimport ora from 'ora'\nimport prompts from 'prompts'\nimport type { Arguments } from 'yargs-parser'\n\nexport async function chooseProjectDir(args: Arguments): Promise<string> {\n /**\n * Return true if the given directory does not exist, or it does not contain important files\n * like `package.json`.\n */\n function isValidDir(dir: string): boolean {\n const packageJson = resolvePath(dir, 'package.json')\n const packagesDir = resolvePath(dir, 'packages')\n return !existsSync(dir) || (!existsSync(packageJson) && !existsSync(packagesDir))\n }\n\n const showValidDirMsg = (dir: string) => {\n ora(green(`Using \"${bold(dir)}\" as the project directory.`)).succeed()\n }\n\n const showInvalidDirMsg = (dir: string) => {\n ora(red(`\"${bold(dir)}\" contains existing 'package.json' and/or 'packages' directory, stopping.`)).fail()\n }\n\n // See if project directory is provided on command line\n let projDir = args['_'][2] as string\n if (projDir) {\n // Directory was provided, see if it is valid\n if (isValidDir(projDir)) {\n // The provided directory is valid, so proceed\n showValidDirMsg(projDir)\n } else {\n // The provided directory is not valid, so show error message and exit\n showInvalidDirMsg(projDir)\n process.exit(0)\n }\n } else {\n // Directory was not provided, so prompt the user\n const dirResponse = await prompts(\n {\n type: 'text',\n name: 'directory',\n message: 'Where would you like to create your new project?',\n initial: '<current directory>'\n // validate(value) {\n // if (value === '<current directory>') {\n // value = process.cwd()\n // }\n // if (!isValidDir(value)) {\n // return notValidMsg(value)\n // }\n // return true\n // }\n },\n {\n onCancel: () => {\n ora().info(dim('Operation cancelled.'))\n process.exit(0)\n }\n }\n )\n projDir = dirResponse.directory\n if (projDir === '<current directory>') {\n projDir = process.cwd()\n }\n if (isValidDir(projDir)) {\n showValidDirMsg(projDir)\n } else {\n showInvalidDirMsg(projDir)\n process.exit(0)\n }\n }\n\n return projDir\n}\n","// Copyright (c) 2022 Climate Interactive / New Venture Fund\n\nimport { existsSync, rmSync } from 'fs'\nimport { join as joinPath, resolve as resolvePath } from 'path'\n\nimport { execa } from 'execa'\nimport { bold, cyan, dim, green, red } from 'kleur/colors'\nimport ora from 'ora'\nimport prompts from 'prompts'\nimport type { Arguments } from 'yargs-parser'\n\n// TODO: Make this configurable; we're using this older version for now because it is\n// relatively stable and has been used to build En-ROADS and C-ROADS for a long time\nconst version = '2.0.34'\n\nexport async function chooseInstallEmsdk(projDir: string, args: Arguments): Promise<void> {\n // TODO: Use findUp and skip this step if emsdk directory already exists\n\n // Prompt the user\n const underParentDir = resolvePath(projDir, '..', 'emsdk')\n const underProjDir = joinPath(projDir, 'emsdk')\n const installResponse = await prompts(\n {\n type: 'select',\n name: 'install',\n message: `Would you like to install the Emscripten SDK?`,\n choices: [\n // ${reset(dim('(recommended)'))\n {\n title: `Install under parent directory (${bold(underParentDir)})`,\n description: 'This is recommended so that it can be shared by multiple projects',\n value: 'parent'\n },\n {\n title: `Install under project directory (${bold(underProjDir)})\"`,\n description: 'This is useful for keeping everything under a single project directory',\n value: 'project'\n },\n {\n title: `Don't install`,\n description: `It's OK, you can install it later`,\n value: 'skip'\n }\n ]\n },\n {\n onCancel: () => {\n ora().info(\n dim(\n 'Operation cancelled. Your project folder has been created, but the Emscripten SDK and other dependencies have not been installed.'\n )\n )\n process.exit(0)\n }\n }\n )\n\n // Handle response\n if (args.dryRun) {\n ora().info(dim(`--dry-run enabled, skipping.`))\n return\n } else if (installResponse.install === 'skip') {\n ora().info(\n dim(\n `No problem! Be sure to install the Emscripten SDK and configure it in \"${cyan('sde.config.js')}\" after setup.`\n )\n )\n return\n }\n\n const installDir = installResponse.install === 'parent' ? underParentDir : underProjDir\n try {\n // TODO: Use spinner here\n await installEmscripten(installDir)\n } catch (e) {\n ora(red(`Failed to install Emscripten SDK: ${e.message}`)).fail()\n process.exit(0)\n }\n\n ora(green(`Installed the Emscripten SDK in \"${bold(installDir)}\"`)).succeed()\n}\n\n/**\n * Install the Emscripten SDK to the `emsdk` directory under the\n * given directory (if `emsdk` is not already present), then\n * activates the requested version (specified with `version`).\n *\n * The implementation is similar to the existing `setup-emsdk` action\n * (https://github.com/mymindstorm/setup-emsdk) except that one has issues\n * with the cache directory on Windows, so having our own script gives us\n * more control over installation and caching behavior.\n */\nasync function installEmscripten(emsdkDir: string /*, options?: { verbose?: boolean }*/): Promise<void> {\n // Only download if the emsdk directory wasn't restored from a cache\n if (!existsSync(emsdkDir)) {\n console.log(`Downloading Emscripten SDK to ${emsdkDir}`)\n // console.log()\n await execa('git', ['clone', 'https://github.com/emscripten-core/emsdk.git', emsdkDir])\n } else {\n console.log(`Found existing Emscripten SDK directory: ${emsdkDir}`)\n }\n // console.log()\n\n if (process.env.CI) {\n // On GitHub Actions, remove the `.git` directory to keep the cache smaller.\n // When we update to a new version, the cache key will miss and the emsdk\n // repo will be redownloaded.\n console.log('CI detected, removing .git directory...')\n const gitDir = joinPath(emsdkDir, '.git')\n rmSync(gitDir, { recursive: true, force: true })\n } else {\n // For local development, pull to get the latest\n console.log('Local development detected, performing git pull...')\n await execa('git', ['pull'], { cwd: emsdkDir })\n // console.log()\n }\n\n const emsdkCmd = async (...args: string[]) => {\n return execa('python3', ['emsdk.py', ...args], { cwd: emsdkDir })\n }\n\n console.log(`Activating Emscripten SDK ${version}...`)\n await emsdkCmd('install', version)\n await emsdkCmd('activate', version)\n}\n","// Copyright (c) 2022 Climate Interactive / New Venture Fund\n\nimport { execaCommand } from 'execa'\nimport { cyan, dim, green, reset } from 'kleur/colors'\nimport ora from 'ora'\nimport prompts from 'prompts'\nimport type { Arguments } from 'yargs-parser'\n\nexport async function chooseGitInit(projDir: string, args: Arguments): Promise<void> {\n // Prompt the user\n const gitResponse = await prompts(\n {\n type: 'confirm',\n name: 'git',\n message: `Would you like to initialize a new git repository? ${reset(dim('(optional)'))}`,\n initial: true\n },\n {\n onCancel: () => {\n ora().info(dim('Operation cancelled. Your project folder has already been created.'))\n process.exit(0)\n }\n }\n )\n\n // Handle response\n if (args.dryRun) {\n ora().info(dim(`--dry-run enabled, skipping.`))\n return\n } else if (!gitResponse.git) {\n ora().info(dim(`No problem! You can come back and run ${cyan(`git init`)} later.`))\n return\n }\n\n // Init git repo\n await execaCommand('git init', { cwd: projDir })\n ora().succeed(green('Git repository initialized!'))\n}\n","// Copyright (c) 2022 Climate Interactive / New Venture Fund\n\nimport { readdir, writeFile } from 'fs/promises'\nimport { join as joinPath, relative, resolve as resolvePath } from 'path'\n\nimport { bold, cyan, dim, green, yellow } from 'kleur/colors'\nimport ora from 'ora'\nimport type { Choice } from 'prompts'\nimport prompts from 'prompts'\n\nconst sampleMdlContent = `\\\n{UTF-8}\n\nX = TIME\n ~~|\n\nY = 0\n ~ [-10,10,0.1]\n ~\n |\n\nZ = X + Y\n ~~|\n\nINITIAL TIME = 2000 ~~|\nFINAL TIME = 2100 ~~|\nTIME STEP = 1 ~~|\nSAVEPER = TIME STEP ~~|\n`\n\nexport async function chooseMdlFile(projDir: string): Promise<string> {\n // Find all `.mdl` files in the project directory\n // From https://stackoverflow.com/a/45130990\n async function getFiles(dir: string): Promise<string[]> {\n const dirents = await readdir(dir, { withFileTypes: true })\n const files = await Promise.all(\n dirents.map(dirent => {\n const res = resolvePath(dir, dirent.name)\n return dirent.isDirectory() ? getFiles(res) : res\n })\n )\n return files.flat()\n }\n const allFiles = await getFiles(projDir)\n const mdlFiles = allFiles.filter(f => f.endsWith('.mdl')).map(f => relative(projDir, f))\n const mdlChoices = mdlFiles.map(f => {\n return {\n title: f,\n value: f\n } as Choice\n })\n\n let mdlFile: string\n if (mdlFiles.length === 0) {\n // No mdl files found; write a sample mdl to get the user started\n const sampleMdlFile = joinPath(projDir, 'sample.mdl')\n await writeFile(sampleMdlFile, sampleMdlContent)\n ora(\n yellow(\n `No mdl files were found in \"${projDir}\". A \"${cyan(\n 'sample.mdl'\n )}\" file has been added to the project to get you started.`\n )\n ).warn()\n mdlFile = 'sample.mdl'\n } else if (mdlFiles.length === 1) {\n // Only one mdl file\n ora().succeed(`Found \"${mdlFiles[0]}\", will configure the project to use that mdl file.`)\n mdlFile = mdlFiles[0]\n } else {\n // Multiple mdl files found; allow the user to choose one\n // TODO: Eventually we should allow the user to choose to flatten if there are multiple submodels\n const options = await prompts(\n [\n {\n type: 'select',\n name: 'mdlFile',\n message: 'It looks like there are multiple mdl files. Which one would you like to use?',\n choices: mdlChoices\n }\n ],\n {\n onCancel: () => {\n ora().info(dim('Operation cancelled.'))\n process.exit(0)\n }\n }\n )\n mdlFile = options.mdlFile\n }\n\n ora(green(`Using \"${bold(mdlFile)}\" as the model for the project.`)).succeed()\n\n return mdlFile\n}\n","// Copyright (c) 2022 Climate Interactive / New Venture Fund\n\nimport { existsSync, mkdtempSync, readdirSync, rmSync } from 'fs'\nimport { writeFile } from 'fs/promises'\nimport { copy } from 'fs-extra'\nimport { tmpdir } from 'os'\nimport { join as joinPath } from 'path'\n\nimport degit from 'degit'\nimport { dim, green, red, yellow } from 'kleur/colors'\nimport type { Ora } from 'ora'\nimport ora from 'ora'\nimport prompts from 'prompts'\nimport type { Arguments } from 'yargs-parser'\n\nconst TEMPLATES = [\n {\n title: 'Default project',\n description: 'Includes recommended structure with config files, app, core library, model-check, etc',\n value: 'template-default'\n },\n {\n title: 'Minimal project',\n description: 'Includes simple config for model-check',\n value: 'template-minimal'\n }\n]\n\nexport async function chooseTemplate(projDir: string, args: Arguments, pkgManager: string): Promise<string> {\n // Prompt the user\n const options = await prompts(\n [\n {\n type: 'select',\n name: 'template',\n message: 'Which template would you like to use?',\n choices: TEMPLATES\n }\n ],\n {\n onCancel: () => {\n ora().info(dim('Operation cancelled.'))\n process.exit(0)\n }\n }\n )\n\n // Handle response\n if (args.dryRun) {\n ora().info(dim(`--dry-run enabled, skipping.`))\n return\n }\n\n // Allow branch name or commit hash to be overridden on command line\n const defaultRev = 'main'\n const commit = args.commit || defaultRev\n\n // Copy the template files to the project directory\n const templateTarget = `climateinteractive/SDEverywhere/examples/${options.template}`\n const hash = `#${commit}`\n const templateSpinner = ora('Copying project files...').start()\n await runDegit(templateTarget, hash, projDir, args, templateSpinner)\n templateSpinner.text = green('Template copied!')\n templateSpinner.succeed()\n\n if (options.template === 'template-default' && pkgManager === 'pnpm') {\n // pnpm doesn't use the \"workspaces\" config from `package.json` (like npm and yarn use),\n // so in the case of pnpm, write a `pnpm-workspace.yaml` file so that the default\n // template monorepo layout is set up correctly\n const workspaceFile = joinPath(projDir, 'pnpm-workspace.yaml')\n const workspaceContent = `packages:\\n - packages/*\\n`\n await writeFile(workspaceFile, workspaceContent)\n }\n\n return options.template\n}\n\n// XXX: This is mostly copied from Astro's create package:\n// https://github.com/withastro/astro/blob/main/packages/create-astro/src/index.ts\n// It contains workarounds for degit issues that may or may not be relevant for SDE,\n// so this should be re-evaluated later.\nasync function runDegit(\n templateTarget: string,\n hash: string,\n dstDir: string,\n args: Arguments,\n spinner: Ora\n): Promise<void> {\n // Enable verbose degit logging if the --verbose flag is used\n const verbose = args.verbose\n\n // Set up degit (we will be writing to a temporary directory, so force is safe)\n const emitter = degit(`${templateTarget}${hash}`, {\n cache: false,\n force: true,\n verbose\n })\n\n try {\n if (verbose) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n emitter.on('info', (info: any) => {\n console.log(info.message)\n })\n }\n\n // Make degit write to a temporary directory\n const tmpDir = mkdtempSync(joinPath(tmpdir(), 'sde-create-'))\n await emitter.clone(tmpDir)\n\n // degit does not return an error when an invalid template is provided, as such we\n // need to handle this manually\n if (!existsSync(tmpDir) || readdirSync(tmpDir).length === 0) {\n throw new Error('The requested template failed to download')\n }\n\n // Copy files to destination without overwriting\n await copy(tmpDir, dstDir, {\n overwrite: false,\n errorOnExist: false\n })\n\n // Remove the temporary directory\n rmSync(tmpDir, { recursive: true, force: true })\n } catch (e) {\n spinner.fail()\n\n // degit is compiled, so the stacktrace is pretty noisy. Only report the stacktrace when using verbose mode.\n // logger.debug(err)\n console.error(red(e.message))\n\n // TODO: Handle common degit issues like below; for now, just log the error and exit\n console.error(yellow('There was a problem copying the template.'))\n console.error(\n yellow(\n 'Please file a new issue with the command output here: https://github.com/climateinteractive/sdeverywhere/issues'\n )\n )\n process.exit(0)\n\n // // Warning for issue #655 and other corrupted cache issue\n // if (e.message === 'zlib: unexpected end of file' || e.message === 'TAR_BAD_ARCHIVE: Unrecognized archive format') {\n // console.log(\n // yellow(\n // // 'Local degit cache seems to be corrupted.'\n // // 'For more information check out this issue: https://github.com/withastro/astro/issues/655.'\n // )\n // )\n // const cacheIssueResponse = await prompts({\n // type: 'confirm',\n // name: 'cache',\n // message: 'Would you like us to clear the cache and try again?',\n // initial: true\n // })\n // if (cacheIssueResponse.cache) {\n // const homeDirectory = os.homedir()\n // const cacheDir = joinPath(homeDirectory, '.degit', 'github', '@sdeverywhere')\n // rmSync(cacheDir, { recursive: true, force: true, maxRetries: 3 })\n // spinner = ora('Copying project files...').start()\n // try {\n // await emitter.clone(dstDir)\n // } catch (e) {\n // // logger.debug(e)\n // console.error(red(e.message))\n // }\n // } else {\n // console.log(\n // \"Okay, no worries! To fix this manually, remove the folder '~/.degit/github/withastro' and rerun the command.\"\n // )\n // }\n // }\n\n // // Helpful message when encountering the \"could not find commit hash for ...\" error\n // if (e.code === 'MISSING_REF') {\n // console.log(\n // yellow(\n // \"This seems to be an issue with degit. Please check if you have 'git' installed on your system, and if you don't, go here to install: https://git-scm.com\"\n // )\n // )\n // console.log(\n // yellow(\n // \"If you do have 'git' installed, please file a new issue with the command output here: https://github.com/climateinteractive/sdeverywhere/issues\"\n // )\n // )\n // }\n\n // process.exit(1)\n }\n}\n"],"mappings":"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","names":["import_path","import_colors","import_ora","import_prompts","joinPath","ora","prompts","resolvePath","parsePath","yaml","import_colors","import_ora","import_prompts","prompts","ora","import_fs","import_path","import_colors","import_ora","import_prompts","resolvePath","ora","prompts","import_fs","import_path","import_execa","import_colors","import_ora","import_prompts","resolvePath","joinPath","prompts","ora","import_execa","import_colors","import_ora","import_prompts","prompts","ora","import_promises","import_path","import_colors","import_ora","import_prompts","resolvePath","joinPath","ora","prompts","import_fs","import_promises","import_path","import_colors","import_ora","import_prompts","prompts","ora","joinPath","degit","detectPackageManager","yargs","prompts","ora"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/step-config.ts","../src/step-deps.ts","../src/step-directory.ts","../src/step-emsdk.ts","../src/step-git.ts","../src/step-mdl.ts","../src/step-template.ts"],"sourcesContent":["// Copyright (c) 2022 Climate Interactive / New Venture Fund\n\nimport { relative } from 'path'\n\nimport { bgCyan, black, bold, cyan, green } from 'kleur/colors'\nimport ora from 'ora'\nimport prompts from 'prompts'\nimport detectPackageManager from 'which-pm-runs'\nimport yargs from 'yargs-parser'\n\nimport { chooseGenConfig, generateCheckYaml, updateSdeConfig } from './step-config'\nimport { chooseInstallDeps } from './step-deps'\nimport { chooseProjectDir } from './step-directory'\nimport { chooseInstallEmsdk } from './step-emsdk'\nimport { chooseGitInit } from './step-git'\nimport { chooseMdlFile } from './step-mdl'\nimport { chooseTemplate } from './step-template'\n\nexport async function main(): Promise<void> {\n // Detect the package manager\n const pkgManager = detectPackageManager()?.name || 'npm'\n\n // Parse command line arguments\n const args = yargs(process.argv)\n prompts.override(args)\n\n // Display welcome message\n console.log(`\\n${bold('Welcome to SDEverywhere!')}`)\n console.log(`Let's create a new SDEverywhere project for your model.\\n`)\n\n // Prompt the user to select a project directory\n const projDir = await chooseProjectDir(args)\n console.log()\n\n // Prompt the user to select a template\n const templateName = await chooseTemplate(projDir, args, pkgManager)\n console.log()\n\n // Prompt the user to select an mdl file\n const mdlPath = await chooseMdlFile(projDir)\n\n // Update the `sde.config.js` file to use the chosen mdl file and\n // generate a sample `.check.yaml` file\n await updateSdeConfig(projDir, mdlPath)\n await generateCheckYaml(projDir, mdlPath)\n console.log()\n\n // If the user chose the default template, offer to set up CSV files\n if (templateName === 'template-default' && !args.dryRun) {\n await chooseGenConfig(projDir, mdlPath)\n console.log()\n }\n\n // Prompt the user to install Emscripten SDK\n await chooseInstallEmsdk(projDir, args)\n console.log()\n\n // Prompt the user to install dependencies\n await chooseInstallDeps(projDir, args, pkgManager)\n console.log()\n\n // Prompt the user to initialize a git repo\n await chooseGitInit(projDir, args)\n console.log()\n\n ora(green('Setup complete!')).succeed()\n\n console.log(`\\n${bgCyan(black(' Next steps '))}\\n`)\n\n const relProjDir = relative(process.cwd(), projDir)\n const devCmd = pkgManager === 'npm' ? 'npm run dev' : `${pkgManager} dev`\n\n // If the project dir is the current dir, no need to tell users to cd\n if (relProjDir !== '') {\n console.log(`You can now ${bold(cyan('cd'))} into the ${bold(cyan(relProjDir))} project directory.`)\n }\n console.log(`Run ${bold(cyan(devCmd))} to start the local dev server. ${bold(cyan('CTRL-C'))} to close.`)\n console.log('')\n}\n","// Copyright (c) 2022 Climate Interactive / New Venture Fund\n\nimport { existsSync } from 'fs'\nimport { mkdir, readFile, writeFile } from 'fs/promises'\nimport { dirname, join as joinPath, parse as parsePath, relative, resolve as resolvePath } from 'path'\n\nimport { bold, cyan, dim, green, reset, yellow } from 'kleur/colors'\nimport ora from 'ora'\nimport type { Choice } from 'prompts'\nimport prompts from 'prompts'\nimport yaml from 'yaml'\n\nimport { parseAndGenerate, preprocessModel } from '@sdeverywhere/compile'\n\ninterface MdlConstVariable {\n kind: 'const'\n name: string\n value: number\n}\n\ninterface MdlAuxVariable {\n kind: 'aux'\n name: string\n}\n\ninterface MdlLevelVariable {\n kind: 'level'\n name: string\n}\n\ntype MdlVariable = MdlConstVariable | MdlAuxVariable | MdlLevelVariable\n\nconst sampleCheckContent = `\\\n# yaml-language-server: $schema=SCHEMA_PATH\n\n# NOTE: This is just a simple check to get you started. Replace \"Some output\" with\n# the name of some variable you'd like to test. Additional tests can be developed\n# in the \"playground\" (beta) inside the model-check report.\n- describe: Some output\n tests:\n - it: should be > 0 for all input scenarios\n scenarios:\n - preset: matrix\n datasets:\n - name: Some output\n predicates:\n - gt: 0\n`\n\nexport async function updateSdeConfig(projDir: string, mdlPath: string): Promise<void> {\n // Read the `sde.config.js` file from the template\n const configPath = joinPath(projDir, 'sde.config.js')\n let configText = await readFile(configPath, 'utf8')\n\n // Replace instances of `MODEL_NAME.mdl` with the path to the chosen mdl file\n configText = configText.replaceAll('MODEL_NAME.mdl', mdlPath)\n\n // Write the updated file\n await writeFile(configPath, configText)\n}\n\nexport async function generateCheckYaml(projDir: string, mdlPath: string): Promise<void> {\n // Generate a sample `{mdl}.check.yaml` file if one doesn't already exist\n // TODO: Make this optional (ask user first)?\n const checkYamlFile = mdlPath.replace('.mdl', '.check.yaml')\n const checkYamlPath = joinPath(projDir, checkYamlFile)\n if (!existsSync(checkYamlPath)) {\n // Get relative path from yaml file parent dir to project dir\n let relProjPath = relative(dirname(checkYamlPath), projDir)\n if (relProjPath.length === 0) {\n relProjPath = './'\n }\n\n // TODO: This path is normally different depending on whether using npm/yarn or\n // pnpm. For npm/yarn, `check-core` is hoisted under top-level `node_modules`,\n // but for pnpm, it is nested under `node_modules/.pnpm`. As an ugly workaround\n // the templates declare `check-core` as a direct dependency even though it is\n // not really needed (a transitive dependency via `plugin-check` would normally\n // suffice). This allows us to use the same path here that works for all\n // three package managers.\n const nodeModulesPart = joinPath(relProjPath, 'node_modules')\n const checkCorePart = '@sdeverywhere/check-core/schema/check.schema.json'\n const schemaPath = `${nodeModulesPart}/${checkCorePart}`\n const checkContent = sampleCheckContent.replace('SCHEMA_PATH', schemaPath)\n await writeFile(checkYamlPath, checkContent)\n }\n}\n\nexport async function chooseGenConfig(projDir: string, mdlPath: string): Promise<void> {\n // TODO: For now we eagerly read the mdl file; maybe change this to only load it if\n // the user chooses to generate graph and/or slider config\n let mdlVars: MdlVariable[]\n try {\n // Get the list of variables available in the model\n mdlVars = await readModelVars(projDir, mdlPath)\n } catch (e) {\n console.log(e)\n ora(\n yellow('The mdl file failed to load. We will continue setting things up, and you can diagnose the issue later.')\n ).warn()\n return\n }\n\n // Extract `INITIAL TIME` and `FINAL TIME` values and remove special control variables from the list\n let initialTime: number\n let finalTime: number\n const validVars: MdlVariable[] = []\n for (const v of mdlVars) {\n const varName = v.name.toLowerCase()\n let skip = false\n switch (varName) {\n case 'final time':\n skip = true\n if (v.kind === 'const') {\n finalTime = v.value\n }\n break\n case 'initial time':\n skip = true\n if (v.kind === 'const') {\n initialTime = v.value\n }\n break\n case 'saveper':\n case 'time':\n case 'time step':\n skip = true\n break\n default:\n break\n }\n if (!skip) {\n validVars.push(v)\n }\n }\n\n // Set the values in `model.csv`\n if (initialTime === undefined) {\n initialTime = 0\n }\n if (finalTime === undefined) {\n finalTime = 100\n }\n\n // TODO: Auto-detect dat files that are referenced by the mdl and include them here\n const datFiles: string[] = []\n const datPart = datFiles.join(';')\n\n // Preserve the `model.csv` header but drop other existing content (if any)\n const modelCsvFile = joinPath(projDir, 'config', 'model.csv')\n const origModelCsvContent = await readFile(modelCsvFile, 'utf8')\n const modelCsvHeader = origModelCsvContent.split('\\n')[0]\n\n // Add line and write out updated `model.csv`\n const modelCsvLine = `${initialTime},${finalTime},${datPart}`\n const newModelCsvContent = `${modelCsvHeader}\\n${modelCsvLine}\\n`\n await writeFile(modelCsvFile, newModelCsvContent)\n\n // See if the user wants to generate graph config\n await chooseGenGraphConfig(projDir, validVars)\n console.log()\n\n // See if the user wants to generate slider config\n await chooseGenSliderConfig(projDir, validVars)\n}\n\nasync function chooseGenGraphConfig(projDir: string, mdlVars: MdlVariable[]): Promise<void> {\n // Prompt the user\n const genResponse = await prompts(\n {\n type: 'confirm',\n name: 'genGraph',\n message: `Would you like to configure a graph to get you started? ${reset(dim('(recommended)'))}`,\n initial: true\n },\n {\n onCancel: () => {\n ora().info(dim('Operation cancelled.'))\n process.exit(0)\n }\n }\n )\n\n // Handle response\n if (!genResponse.genGraph) {\n ora().info(dim(`No problem! You can edit the \"${cyan('config/graphs.csv')}\" file later.`))\n return\n }\n\n // Offer multi-select with available output variables\n const outputVarNames: string[] = []\n for (const mdlVar of mdlVars) {\n if (mdlVar.kind === 'aux' || mdlVar.kind === 'level') {\n outputVarNames.push(mdlVar.name)\n }\n }\n outputVarNames.sort((a, b) => {\n return a.toLowerCase().localeCompare(b.toLowerCase())\n })\n const choices = outputVarNames.map(f => {\n return {\n title: f,\n value: f\n } as Choice\n })\n const varsResponse = await prompts(\n {\n type: 'autocompleteMultiselect',\n name: 'vars',\n message: 'Choose up to three output variables to display in the graph',\n choices,\n max: 3\n },\n {\n onCancel: () => {\n ora().info(dim('Operation cancelled.'))\n process.exit(0)\n }\n }\n )\n\n if (varsResponse.vars.length === 0) {\n ora().info(dim(`No variables selected. You can edit the \"${cyan('config/graphs.csv')}\" file later.`))\n return\n }\n\n // Add line to `graphs.csv`\n const graphsCsvFile = joinPath(projDir, 'config', 'graphs.csv')\n const csvLine = graphsCsvLine(varsResponse.vars)\n let graphsCsvContent = await readFile(graphsCsvFile, 'utf8')\n graphsCsvContent += `${csvLine}\\n`\n await writeFile(graphsCsvFile, graphsCsvContent)\n\n ora(\n green(`Added graph to \"${bold('config/graphs.csv')}\". ${dim('You can configure graphs in that file later.')}`)\n ).succeed()\n}\n\n// TODO: Ideally the `plugin-config` package would expose an API for generating CSV, but\n// until then, we will generate a comma-separated line of values in hardcoded fashion\nfunction graphsCsvLine(outputVarNames: string[]): string {\n const colors = ['blue', 'red', 'green']\n\n // Fill the line with blanks initially, then set the small subset of fields\n const a = Array(131).fill('')\n // id\n a[0] = '1'\n // parent menu\n a[2] = 'Graphs'\n // graph title\n a[3] = 'Graph Title'\n // kind\n a[7] = 'line'\n // Plots start at 26\n let index = 26\n let colorIndex = 0\n for (const outputVarName of outputVarNames) {\n // Surround the name in quotes if it contains a comma\n const escapedName = escapeCsvField(outputVarName)\n // plot N variable\n a[index + 0] = escapedName\n // plot N style\n a[index + 2] = 'line'\n // plot N label\n a[index + 3] = escapedName\n // plot N color\n a[index + 4] = colors[colorIndex]\n index += 7\n colorIndex++\n }\n\n return a.join(',')\n}\n\nasync function chooseGenSliderConfig(projDir: string, mdlVars: MdlVariable[]): Promise<void> {\n // Prompt the user\n const genResponse = await prompts(\n {\n type: 'confirm',\n name: 'genSliders',\n message: `Would you like to configure a few sliders to get you started? ${reset(dim('(recommended)'))}`,\n initial: true\n },\n {\n onCancel: () => {\n ora().info(dim('Operation cancelled.'))\n process.exit(0)\n }\n }\n )\n\n // Handle response\n if (!genResponse.genSliders) {\n ora().info(dim(`No problem! You can edit the \"${cyan('config/inputs.csv')}\" file later.`))\n return\n }\n\n // Offer multi-select with available input variables\n const inputVarNames: string[] = []\n for (const mdlVar of mdlVars) {\n if (mdlVar.kind === 'const') {\n inputVarNames.push(mdlVar.name)\n }\n }\n inputVarNames.sort((a, b) => {\n return a.toLowerCase().localeCompare(b.toLowerCase())\n })\n const choices = inputVarNames.map(f => {\n return {\n title: f,\n value: f\n } as Choice\n })\n const varsResponse = await prompts(\n {\n type: 'autocompleteMultiselect',\n name: 'vars',\n message: 'Choose up to three input variables to control with sliders',\n choices,\n max: 3\n },\n {\n onCancel: () => {\n ora().info(dim('Operation cancelled.'))\n process.exit(0)\n }\n }\n )\n\n if (varsResponse.vars.length === 0) {\n ora().info(dim(`No variables selected. You can edit the \"${cyan('config/inputs.csv')}\" file later.`))\n return\n }\n\n // Add lines to `inputs.csv`\n const inputsCsvFile = joinPath(projDir, 'config', 'inputs.csv')\n let inputsCsvContent = await readFile(inputsCsvFile, 'utf8')\n let idNumber = 1\n for (const inputVarName of varsResponse.vars) {\n const inputVar = mdlVars.find(v => v.name === inputVarName)\n if (inputVar && inputVar.kind === 'const') {\n const defaultValue = inputVar.value\n const csvLine = inputsCsvLine(inputVarName, defaultValue, idNumber.toString())\n inputsCsvContent += `${csvLine}\\n`\n idNumber++\n }\n }\n await writeFile(inputsCsvFile, inputsCsvContent)\n\n const slidersText = varsResponse.vars.length > 1 ? 'sliders' : 'sliders'\n ora(\n green(\n `Added ${slidersText} to \"${bold('config/inputs.csv')}\". ${dim('You can configure sliders in that file later.')}`\n )\n ).succeed()\n}\n\n// TODO: Ideally the `plugin-config` package would expose an API for generating CSV, but\n// until then, we will generate a comma-separated line of values in hardcoded fashion\nfunction inputsCsvLine(inputVarName: string, defaultValue: number, id: string): string {\n // Surround the name in quotes if it contains a comma\n const escapedName = escapeCsvField(inputVarName)\n\n // TODO: Be smarter about automatically choosing min/max/step values\n const minValue = defaultValue - 1\n const maxValue = defaultValue + 1\n const step = 0.1\n\n // Fill the line with blanks initially, then set the small subset of fields\n const a = Array(28).fill('')\n // id\n a[0] = id\n // input type\n a[1] = 'slider'\n // viewid\n a[2] = 'view1'\n // varname\n a[3] = escapedName\n // label\n a[4] = escapedName\n // group name\n a[6] = 'Sliders'\n // slider min\n a[7] = minValue\n // slider max\n a[8] = maxValue\n // slider default\n a[9] = defaultValue\n // slider step\n a[10] = step\n // units\n a[11] = '(units)'\n\n return a.join(',')\n}\n\nfunction escapeCsvField(s: string): string {\n // Surround the value in quotes if it contains a comma\n // TODO: Escape double quotes as well\n return s.includes(',') ? `\"${s}\"` : s\n}\n\nasync function readModelVars(projDir: string, mdlPath: string): Promise<MdlVariable[]> {\n // TODO: This function contains a subset of the logic from `sde-generate.js` in\n // the `cli` package; should revisit\n // let { modelDirname, modelName, modelPathname } = modelPathProps(model)\n\n // Ensure the `build` directory exists (under the `sde-prep` directory)\n const buildDir = resolvePath(projDir, 'sde-prep', 'build')\n await mkdir(buildDir, { recursive: true })\n\n // Use an empty model spec; this will make SDE look at all variables in the mdl\n const spec = {}\n\n // Try parsing the mdl file to generate the list of variables\n // TODO: This depends on some `compile` package APIs that are not yet considered stable.\n // Ideally we'd use an API that does not write files but instead returns an in-memory\n // object in a specified format.\n\n // Read and preprocess the model\n const mdlFile = resolvePath(projDir, mdlPath)\n const preprocessed = preprocessModel(mdlFile, spec, 'genc', /*writeFiles=*/ false)\n\n // Parse the model and generate the variable list\n const mdlDir = dirname(mdlFile)\n const mdlName = parsePath(mdlFile).name\n await parseAndGenerate(preprocessed, spec, ['printVarList'], mdlDir, mdlName, buildDir)\n\n // Read `build/{mdl}_vars.yaml`\n // TODO: For now the printVarList code only outputs txt and yaml files; we'll use the\n // yaml file for now, but that means we have a dependency on the `yaml` package. Once\n // we change the `compile` package to output JSON, we'll need to change this code.\n const varsYamlFile = joinPath(buildDir, `${mdlName}_vars.yaml`)\n const varsYamlContent = await readFile(varsYamlFile, 'utf8')\n const varObjs = yaml.parse(varsYamlContent)\n\n // Create a simplified array of variables\n const mdlVars: MdlVariable[] = []\n for (const varObj of varObjs) {\n // Only include certain variables for now\n // TODO: Include \"data\" vars\n switch (varObj.varType) {\n case 'const':\n mdlVars.push({\n kind: 'const',\n name: varObj.modelLHS,\n value: Number.parseFloat(varObj.modelFormula)\n })\n break\n case 'aux':\n mdlVars.push({\n kind: 'aux',\n name: varObj.modelLHS\n })\n break\n case 'level':\n mdlVars.push({\n kind: 'level',\n name: varObj.modelLHS\n })\n break\n default:\n break\n }\n }\n\n return mdlVars\n}\n","// Copyright (c) 2022 Climate Interactive / New Venture Fund\n\nimport { execa } from 'execa'\nimport { bold, cyan, dim, green, reset, yellow } from 'kleur/colors'\nimport ora from 'ora'\nimport prompts from 'prompts'\nimport type { Arguments } from 'yargs-parser'\n\nexport async function chooseInstallDeps(projDir: string, args: Arguments, pkgManager: string): Promise<void> {\n // Prompt the user\n const installResponse = await prompts(\n {\n type: 'confirm',\n name: 'install',\n message: `Would you like to install ${pkgManager} dependencies? ${reset(dim('(recommended)'))}`,\n initial: true\n },\n {\n onCancel: () => {\n ora().info(\n dim('Operation cancelled. Your project folder has been created, but no dependencies have been installed.')\n )\n process.exit(0)\n }\n }\n )\n\n // Handle response\n if (args.dryRun) {\n ora().info(dim(`--dry-run enabled, skipping.`))\n return\n } else if (!installResponse.install) {\n ora().info(dim(`No problem! Remember to install dependencies after setup.`))\n return\n }\n\n // Install dependencies\n const installExec = execa(pkgManager, ['install'], { cwd: projDir })\n const installingPackagesMsg = 'Installing packages...'\n const installSpinner = ora(installingPackagesMsg).start()\n try {\n await new Promise<void>((resolve, reject) => {\n installExec.stdout?.on('data', function (data) {\n installSpinner.text = `${installingPackagesMsg}\\n${bold(`[${pkgManager}]`)} ${data}`\n })\n installExec.stderr?.on('data', function (data) {\n installSpinner.text = `${installingPackagesMsg}\\n${bold(`[${pkgManager}]`)} ${data}`\n })\n installExec.on('error', error => reject(error))\n installExec.on('close', code => {\n if (code !== 0) {\n reject(`Install failed (code=${code})`)\n } else {\n resolve()\n }\n })\n })\n installSpinner.text = green('Packages installed!')\n installSpinner.succeed()\n } catch (e) {\n installSpinner.text = yellow(\n `There was an error installing packages. Try running ${cyan(\n `${pkgManager} install`\n )} in your project directory later.`\n )\n installSpinner.warn()\n }\n}\n","// Copyright (c) 2022 Climate Interactive / New Venture Fund\n\nimport { existsSync } from 'fs'\nimport { resolve as resolvePath } from 'path'\n\nimport { bold, dim, green, red } from 'kleur/colors'\nimport ora from 'ora'\nimport prompts from 'prompts'\nimport type { Arguments } from 'yargs-parser'\n\nexport async function chooseProjectDir(args: Arguments): Promise<string> {\n /**\n * Return true if the given directory does not exist, or it does not contain important files\n * like `package.json`.\n */\n function isValidDir(dir: string): boolean {\n const packageJson = resolvePath(dir, 'package.json')\n const packagesDir = resolvePath(dir, 'packages')\n return !existsSync(dir) || (!existsSync(packageJson) && !existsSync(packagesDir))\n }\n\n const showValidDirMsg = (dir: string) => {\n ora(green(`Using \"${bold(dir)}\" as the project directory.`)).succeed()\n }\n\n const showInvalidDirMsg = (dir: string) => {\n ora(red(`\"${bold(dir)}\" contains existing 'package.json' and/or 'packages' directory, stopping.`)).fail()\n }\n\n // See if project directory is provided on command line\n let projDir = args['_'][2] as string\n if (projDir) {\n // Directory was provided, see if it is valid\n if (isValidDir(projDir)) {\n // The provided directory is valid, so proceed\n showValidDirMsg(projDir)\n } else {\n // The provided directory is not valid, so show error message and exit\n showInvalidDirMsg(projDir)\n process.exit(0)\n }\n } else {\n // Directory was not provided, so prompt the user\n const dirResponse = await prompts(\n {\n type: 'text',\n name: 'directory',\n message: 'Where would you like to create your new project?',\n initial: '<current directory>'\n // validate(value) {\n // if (value === '<current directory>') {\n // value = process.cwd()\n // }\n // if (!isValidDir(value)) {\n // return notValidMsg(value)\n // }\n // return true\n // }\n },\n {\n onCancel: () => {\n ora().info(dim('Operation cancelled.'))\n process.exit(0)\n }\n }\n )\n projDir = dirResponse.directory\n if (projDir === '<current directory>') {\n projDir = process.cwd()\n }\n if (isValidDir(projDir)) {\n showValidDirMsg(projDir)\n } else {\n showInvalidDirMsg(projDir)\n process.exit(0)\n }\n }\n\n return projDir\n}\n","// Copyright (c) 2022 Climate Interactive / New Venture Fund\n\nimport { existsSync, rmSync } from 'fs'\nimport { join as joinPath, resolve as resolvePath } from 'path'\n\nimport { execa } from 'execa'\nimport { bold, cyan, dim, green, red } from 'kleur/colors'\nimport ora from 'ora'\nimport prompts from 'prompts'\nimport type { Arguments } from 'yargs-parser'\n\n// TODO: Make this configurable; we're using this older version for now because it is\n// relatively stable and has been used to build En-ROADS and C-ROADS for a long time\nconst version = '2.0.34'\n\nexport async function chooseInstallEmsdk(projDir: string, args: Arguments): Promise<void> {\n // TODO: Use findUp and skip this step if emsdk directory already exists\n\n // Prompt the user\n const underParentDir = resolvePath(projDir, '..', 'emsdk')\n const underProjDir = joinPath(projDir, 'emsdk')\n const installResponse = await prompts(\n {\n type: 'select',\n name: 'install',\n message: `Would you like to install the Emscripten SDK?`,\n choices: [\n // ${reset(dim('(recommended)'))\n {\n title: `Install under parent directory (${bold(underParentDir)})`,\n description: 'This is recommended so that it can be shared by multiple projects',\n value: 'parent'\n },\n {\n title: `Install under project directory (${bold(underProjDir)})\"`,\n description: 'This is useful for keeping everything under a single project directory',\n value: 'project'\n },\n {\n title: `Don't install`,\n description: `It's OK, you can install it later`,\n value: 'skip'\n }\n ]\n },\n {\n onCancel: () => {\n ora().info(\n dim(\n 'Operation cancelled. Your project folder has been created, but the Emscripten SDK and other dependencies have not been installed.'\n )\n )\n process.exit(0)\n }\n }\n )\n\n // Handle response\n if (args.dryRun) {\n ora().info(dim(`--dry-run enabled, skipping.`))\n return\n } else if (installResponse.install === 'skip') {\n ora().info(\n dim(\n `No problem! Be sure to install the Emscripten SDK and configure it in \"${cyan('sde.config.js')}\" after setup.`\n )\n )\n return\n }\n\n const installDir = installResponse.install === 'parent' ? underParentDir : underProjDir\n try {\n // TODO: Use spinner here\n await installEmscripten(installDir)\n } catch (e) {\n ora(red(`Failed to install Emscripten SDK: ${e.message}`)).fail()\n process.exit(0)\n }\n\n ora(green(`Installed the Emscripten SDK in \"${bold(installDir)}\"`)).succeed()\n}\n\n/**\n * Install the Emscripten SDK to the `emsdk` directory under the\n * given directory (if `emsdk` is not already present), then\n * activates the requested version (specified with `version`).\n *\n * The implementation is similar to the existing `setup-emsdk` action\n * (https://github.com/mymindstorm/setup-emsdk) except that one has issues\n * with the cache directory on Windows, so having our own script gives us\n * more control over installation and caching behavior.\n */\nasync function installEmscripten(emsdkDir: string /*, options?: { verbose?: boolean }*/): Promise<void> {\n // Only download if the emsdk directory wasn't restored from a cache\n if (!existsSync(emsdkDir)) {\n console.log(`Downloading Emscripten SDK to ${emsdkDir}`)\n // console.log()\n await execa('git', ['clone', 'https://github.com/emscripten-core/emsdk.git', emsdkDir])\n } else {\n console.log(`Found existing Emscripten SDK directory: ${emsdkDir}`)\n }\n // console.log()\n\n if (process.env.CI) {\n // On GitHub Actions, remove the `.git` directory to keep the cache smaller.\n // When we update to a new version, the cache key will miss and the emsdk\n // repo will be redownloaded.\n console.log('CI detected, removing .git directory...')\n const gitDir = joinPath(emsdkDir, '.git')\n rmSync(gitDir, { recursive: true, force: true })\n } else {\n // For local development, pull to get the latest\n console.log('Local development detected, performing git pull...')\n await execa('git', ['pull'], { cwd: emsdkDir })\n // console.log()\n }\n\n const emsdkCmd = async (...args: string[]) => {\n return execa('python3', ['emsdk.py', ...args], { cwd: emsdkDir })\n }\n\n console.log(`Activating Emscripten SDK ${version}...`)\n await emsdkCmd('install', version)\n await emsdkCmd('activate', version)\n}\n","// Copyright (c) 2022 Climate Interactive / New Venture Fund\n\nimport { execaCommand } from 'execa'\nimport { cyan, dim, green, reset, yellow } from 'kleur/colors'\nimport ora from 'ora'\nimport prompts from 'prompts'\nimport type { Arguments } from 'yargs-parser'\n\nexport async function chooseGitInit(projDir: string, args: Arguments): Promise<void> {\n // Prompt the user\n const gitResponse = await prompts(\n {\n type: 'confirm',\n name: 'git',\n message: `Would you like to initialize a new git repository? ${reset(dim('(optional)'))}`,\n initial: true\n },\n {\n onCancel: () => {\n ora().info(dim('Operation cancelled. Your project folder has already been created.'))\n process.exit(0)\n }\n }\n )\n\n // Handle response\n if (args.dryRun) {\n ora().info(dim(`--dry-run enabled, skipping.`))\n return\n } else if (!gitResponse.git) {\n ora().info(dim(`No problem! You can come back and run ${cyan(`git init`)} later.`))\n return\n }\n\n // Init git repo\n try {\n await execaCommand('git init', { cwd: projDir })\n ora().succeed(green('Git repository initialized!'))\n } catch (e) {\n ora().warn(\n yellow(\n `There was a problem initializing the Git repository, but no problem, you can run ${cyan(`git init`)} later.`\n )\n )\n }\n}\n","// Copyright (c) 2022 Climate Interactive / New Venture Fund\n\nimport { readdir, writeFile } from 'fs/promises'\nimport { join as joinPath, relative, resolve as resolvePath } from 'path'\n\nimport { bold, cyan, dim, green, yellow } from 'kleur/colors'\nimport ora from 'ora'\nimport type { Choice } from 'prompts'\nimport prompts from 'prompts'\n\nconst sampleMdlContent = `\\\n{UTF-8}\n\nX = TIME\n ~~|\n\nY = 0\n ~ [-10,10,0.1]\n ~\n |\n\nZ = X + Y\n ~~|\n\nINITIAL TIME = 2000 ~~|\nFINAL TIME = 2100 ~~|\nTIME STEP = 1 ~~|\nSAVEPER = TIME STEP ~~|\n`\n\nexport async function chooseMdlFile(projDir: string): Promise<string> {\n // Find all `.mdl` files in the project directory\n // From https://stackoverflow.com/a/45130990\n async function getFiles(dir: string): Promise<string[]> {\n const dirents = await readdir(dir, { withFileTypes: true })\n const files = await Promise.all(\n dirents.map(dirent => {\n const res = resolvePath(dir, dirent.name)\n return dirent.isDirectory() ? getFiles(res) : res\n })\n )\n return files.flat()\n }\n const allFiles = await getFiles(projDir)\n const mdlFiles = allFiles.filter(f => f.endsWith('.mdl')).map(f => relative(projDir, f))\n const mdlChoices = mdlFiles.map(f => {\n return {\n title: f,\n value: f\n } as Choice\n })\n\n let mdlFile: string\n if (mdlFiles.length === 0) {\n // No mdl files found; write a sample mdl to get the user started\n const sampleMdlFile = joinPath(projDir, 'sample.mdl')\n await writeFile(sampleMdlFile, sampleMdlContent)\n ora(\n yellow(\n `No mdl files were found in \"${projDir}\". A \"${cyan(\n 'sample.mdl'\n )}\" file has been added to the project to get you started.`\n )\n ).warn()\n mdlFile = 'sample.mdl'\n } else if (mdlFiles.length === 1) {\n // Only one mdl file\n ora().succeed(`Found \"${mdlFiles[0]}\", will configure the project to use that mdl file.`)\n mdlFile = mdlFiles[0]\n } else {\n // Multiple mdl files found; allow the user to choose one\n // TODO: Eventually we should allow the user to choose to flatten if there are multiple submodels\n const options = await prompts(\n [\n {\n type: 'select',\n name: 'mdlFile',\n message: 'It looks like there are multiple mdl files. Which one would you like to use?',\n choices: mdlChoices\n }\n ],\n {\n onCancel: () => {\n ora().info(dim('Operation cancelled.'))\n process.exit(0)\n }\n }\n )\n mdlFile = options.mdlFile\n }\n\n ora(green(`Using \"${bold(mdlFile)}\" as the model for the project.`)).succeed()\n\n return mdlFile\n}\n","// Copyright (c) 2022 Climate Interactive / New Venture Fund\n\nimport { existsSync, mkdtempSync, readdirSync, rmSync } from 'fs'\nimport { writeFile } from 'fs/promises'\nimport { copy } from 'fs-extra'\nimport { tmpdir } from 'os'\nimport { join as joinPath } from 'path'\n\nimport { downloadTemplate } from 'giget'\nimport { dim, green, red, yellow } from 'kleur/colors'\nimport type { Ora } from 'ora'\nimport ora from 'ora'\nimport prompts from 'prompts'\nimport type { Arguments } from 'yargs-parser'\n\nconst TEMPLATES = [\n {\n title: 'Default project',\n description: 'Includes recommended structure with config files, app, core library, model-check, etc',\n value: 'template-default'\n },\n {\n title: 'Minimal project',\n description: 'Includes simple config for model-check',\n value: 'template-minimal'\n }\n]\n\nexport async function chooseTemplate(projDir: string, args: Arguments, pkgManager: string): Promise<string> {\n // Prompt the user\n const options = await prompts(\n [\n {\n type: 'select',\n name: 'template',\n message: 'Which template would you like to use?',\n choices: TEMPLATES\n }\n ],\n {\n onCancel: () => {\n ora().info(dim('Operation cancelled.'))\n process.exit(0)\n }\n }\n )\n\n // Handle response\n if (args.dryRun) {\n ora().info(dim(`--dry-run enabled, skipping.`))\n return\n }\n\n // Allow branch name or commit hash to be overridden on command line\n const defaultRev = 'main'\n const commit = args.commit || defaultRev\n\n // Copy the template files to the project directory\n const templateTarget = `climateinteractive/SDEverywhere/examples/${options.template}#${commit}`\n const templateSpinner = ora('Copying project files...').start()\n await copyTemplate(templateTarget, projDir, templateSpinner)\n templateSpinner.text = green('Template copied!')\n templateSpinner.succeed()\n\n if (options.template === 'template-default' && pkgManager === 'pnpm') {\n // pnpm doesn't use the \"workspaces\" config from `package.json` (like npm and yarn use),\n // so in the case of pnpm, write a `pnpm-workspace.yaml` file so that the default\n // template monorepo layout is set up correctly\n const workspaceFile = joinPath(projDir, 'pnpm-workspace.yaml')\n const workspaceContent = `packages:\\n - packages/*\\n`\n await writeFile(workspaceFile, workspaceContent)\n }\n\n return options.template\n}\n\nasync function copyTemplate(templateTarget: string, dstDir: string, spinner: Ora): Promise<void> {\n try {\n // Make giget write to a temporary directory\n const tmpDir = mkdtempSync(joinPath(tmpdir(), 'sde-create-'))\n\n // Use giget to download the template (we will be writing to a temporary directory,\n // so `force` is safe)\n await downloadTemplate(`github:${templateTarget}`, {\n force: true,\n provider: 'github',\n dir: tmpDir\n })\n\n // In case giget doesn't return an error when an invalid template is provided, check\n // that the temporary directory is non-empty\n if (!existsSync(tmpDir) || readdirSync(tmpDir).length === 0) {\n throw new Error('Failed to download the requested template: the temporary directory is empty.')\n }\n\n // Copy files to destination without overwriting\n await copy(tmpDir, dstDir, {\n overwrite: false,\n errorOnExist: false\n })\n\n // Remove the temporary directory\n rmSync(tmpDir, { recursive: true, force: true })\n } catch (e) {\n // The download failed; show an error message\n // TODO: Handle common download issues; for now, just log the error message and exit\n spinner.fail()\n console.error(red(e.message))\n console.error(yellow('\\nThere was a problem copying the template.'))\n console.error(\n yellow(\n 'Please start a new discussion thread and include the command output so that we can help:\\n https://github.com/climateinteractive/SDEverywhere/discussions/categories/q-a\\n'\n )\n )\n process.exit(0)\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,IAAAA,eAAyB;AAEzB,IAAAC,iBAAiD;AACjD,IAAAC,cAAgB;AAChB,IAAAC,kBAAoB;AACpB,2BAAiC;AACjC,0BAAkB;;;ACNlB,gBAA2B;AAC3B,sBAA2C;AAC3C,kBAAgG;AAEhG,oBAAsD;AACtD,iBAAgB;AAEhB,qBAAoB;AACpB,kBAAiB;AAEjB,qBAAkD;AAoBlD,IAAM,qBAAqB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiB3B,eAAsB,gBAAgB,SAAiB,SAAgC;AAErF,QAAM,iBAAa,YAAAC,MAAS,SAAS,eAAe;AACpD,MAAI,aAAa,UAAM,0BAAS,YAAY,MAAM;AAGlD,eAAa,WAAW,WAAW,kBAAkB,OAAO;AAG5D,YAAM,2BAAU,YAAY,UAAU;AACxC;AAEA,eAAsB,kBAAkB,SAAiB,SAAgC;AAGvF,QAAM,gBAAgB,QAAQ,QAAQ,QAAQ,aAAa;AAC3D,QAAM,oBAAgB,YAAAA,MAAS,SAAS,aAAa;AACrD,MAAI,KAAC,sBAAW,aAAa,GAAG;AAE9B,QAAI,kBAAc,0BAAS,qBAAQ,aAAa,GAAG,OAAO;AAC1D,QAAI,YAAY,WAAW,GAAG;AAC5B,oBAAc;AAAA,IAChB;AASA,UAAM,sBAAkB,YAAAA,MAAS,aAAa,cAAc;AAC5D,UAAM,gBAAgB;AACtB,UAAM,aAAa,GAAG,eAAe,IAAI,aAAa;AACtD,UAAM,eAAe,mBAAmB,QAAQ,eAAe,UAAU;AACzE,cAAM,2BAAU,eAAe,YAAY;AAAA,EAC7C;AACF;AAEA,eAAsB,gBAAgB,SAAiB,SAAgC;AAGrF,MAAI;AACJ,MAAI;AAEF,cAAU,MAAM,cAAc,SAAS,OAAO;AAAA,EAChD,SAAS,GAAG;AACV,YAAQ,IAAI,CAAC;AACb,mBAAAC;AAAA,UACE,sBAAO,wGAAwG;AAAA,IACjH,EAAE,KAAK;AACP;AAAA,EACF;AAGA,MAAI;AACJ,MAAI;AACJ,QAAM,YAA2B,CAAC;AAClC,aAAW,KAAK,SAAS;AACvB,UAAM,UAAU,EAAE,KAAK,YAAY;AACnC,QAAI,OAAO;AACX,YAAQ,SAAS;AAAA,MACf,KAAK;AACH,eAAO;AACP,YAAI,EAAE,SAAS,SAAS;AACtB,sBAAY,EAAE;AAAA,QAChB;AACA;AAAA,MACF,KAAK;AACH,eAAO;AACP,YAAI,EAAE,SAAS,SAAS;AACtB,wBAAc,EAAE;AAAA,QAClB;AACA;AAAA,MACF,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AACH,eAAO;AACP;AAAA,MACF;AACE;AAAA,IACJ;AACA,QAAI,CAAC,MAAM;AACT,gBAAU,KAAK,CAAC;AAAA,IAClB;AAAA,EACF;AAGA,MAAI,gBAAgB,QAAW;AAC7B,kBAAc;AAAA,EAChB;AACA,MAAI,cAAc,QAAW;AAC3B,gBAAY;AAAA,EACd;AAGA,QAAM,WAAqB,CAAC;AAC5B,QAAM,UAAU,SAAS,KAAK,GAAG;AAGjC,QAAM,mBAAe,YAAAD,MAAS,SAAS,UAAU,WAAW;AAC5D,QAAM,sBAAsB,UAAM,0BAAS,cAAc,MAAM;AAC/D,QAAM,iBAAiB,oBAAoB,MAAM,IAAI,EAAE,CAAC;AAGxD,QAAM,eAAe,GAAG,WAAW,IAAI,SAAS,IAAI,OAAO;AAC3D,QAAM,qBAAqB,GAAG,cAAc;AAAA,EAAK,YAAY;AAAA;AAC7D,YAAM,2BAAU,cAAc,kBAAkB;AAGhD,QAAM,qBAAqB,SAAS,SAAS;AAC7C,UAAQ,IAAI;AAGZ,QAAM,sBAAsB,SAAS,SAAS;AAChD;AAEA,eAAe,qBAAqB,SAAiB,SAAuC;AAE1F,QAAM,cAAc,UAAM,eAAAE;AAAA,IACxB;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS,+DAA2D,yBAAM,mBAAI,eAAe,CAAC,CAAC;AAAA,MAC/F,SAAS;AAAA,IACX;AAAA,IACA;AAAA,MACE,UAAU,MAAM;AACd,uBAAAD,SAAI,EAAE,SAAK,mBAAI,sBAAsB,CAAC;AACtC,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AAGA,MAAI,CAAC,YAAY,UAAU;AACzB,mBAAAA,SAAI,EAAE,SAAK,mBAAI,qCAAiC,oBAAK,mBAAmB,CAAC,eAAe,CAAC;AACzF;AAAA,EACF;AAGA,QAAM,iBAA2B,CAAC;AAClC,aAAW,UAAU,SAAS;AAC5B,QAAI,OAAO,SAAS,SAAS,OAAO,SAAS,SAAS;AACpD,qBAAe,KAAK,OAAO,IAAI;AAAA,IACjC;AAAA,EACF;AACA,iBAAe,KAAK,CAAC,GAAG,MAAM;AAC5B,WAAO,EAAE,YAAY,EAAE,cAAc,EAAE,YAAY,CAAC;AAAA,EACtD,CAAC;AACD,QAAM,UAAU,eAAe,IAAI,OAAK;AACtC,WAAO;AAAA,MACL,OAAO;AAAA,MACP,OAAO;AAAA,IACT;AAAA,EACF,CAAC;AACD,QAAM,eAAe,UAAM,eAAAC;AAAA,IACzB;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA;AAAA,MACE,UAAU,MAAM;AACd,uBAAAD,SAAI,EAAE,SAAK,mBAAI,sBAAsB,CAAC;AACtC,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AAEA,MAAI,aAAa,KAAK,WAAW,GAAG;AAClC,mBAAAA,SAAI,EAAE,SAAK,mBAAI,gDAA4C,oBAAK,mBAAmB,CAAC,eAAe,CAAC;AACpG;AAAA,EACF;AAGA,QAAM,oBAAgB,YAAAD,MAAS,SAAS,UAAU,YAAY;AAC9D,QAAM,UAAU,cAAc,aAAa,IAAI;AAC/C,MAAI,mBAAmB,UAAM,0BAAS,eAAe,MAAM;AAC3D,sBAAoB,GAAG,OAAO;AAAA;AAC9B,YAAM,2BAAU,eAAe,gBAAgB;AAE/C,iBAAAC;AAAA,QACE,qBAAM,uBAAmB,oBAAK,mBAAmB,CAAC,UAAM,mBAAI,8CAA8C,CAAC,EAAE;AAAA,EAC/G,EAAE,QAAQ;AACZ;AAIA,SAAS,cAAc,gBAAkC;AACvD,QAAM,SAAS,CAAC,QAAQ,OAAO,OAAO;AAGtC,QAAM,IAAI,MAAM,GAAG,EAAE,KAAK,EAAE;AAE5B,IAAE,CAAC,IAAI;AAEP,IAAE,CAAC,IAAI;AAEP,IAAE,CAAC,IAAI;AAEP,IAAE,CAAC,IAAI;AAEP,MAAI,QAAQ;AACZ,MAAI,aAAa;AACjB,aAAW,iBAAiB,gBAAgB;AAE1C,UAAM,cAAc,eAAe,aAAa;AAEhD,MAAE,QAAQ,CAAC,IAAI;AAEf,MAAE,QAAQ,CAAC,IAAI;AAEf,MAAE,QAAQ,CAAC,IAAI;AAEf,MAAE,QAAQ,CAAC,IAAI,OAAO,UAAU;AAChC,aAAS;AACT;AAAA,EACF;AAEA,SAAO,EAAE,KAAK,GAAG;AACnB;AAEA,eAAe,sBAAsB,SAAiB,SAAuC;AAE3F,QAAM,cAAc,UAAM,eAAAC;AAAA,IACxB;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS,qEAAiE,yBAAM,mBAAI,eAAe,CAAC,CAAC;AAAA,MACrG,SAAS;AAAA,IACX;AAAA,IACA;AAAA,MACE,UAAU,MAAM;AACd,uBAAAD,SAAI,EAAE,SAAK,mBAAI,sBAAsB,CAAC;AACtC,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AAGA,MAAI,CAAC,YAAY,YAAY;AAC3B,mBAAAA,SAAI,EAAE,SAAK,mBAAI,qCAAiC,oBAAK,mBAAmB,CAAC,eAAe,CAAC;AACzF;AAAA,EACF;AAGA,QAAM,gBAA0B,CAAC;AACjC,aAAW,UAAU,SAAS;AAC5B,QAAI,OAAO,SAAS,SAAS;AAC3B,oBAAc,KAAK,OAAO,IAAI;AAAA,IAChC;AAAA,EACF;AACA,gBAAc,KAAK,CAAC,GAAG,MAAM;AAC3B,WAAO,EAAE,YAAY,EAAE,cAAc,EAAE,YAAY,CAAC;AAAA,EACtD,CAAC;AACD,QAAM,UAAU,cAAc,IAAI,OAAK;AACrC,WAAO;AAAA,MACL,OAAO;AAAA,MACP,OAAO;AAAA,IACT;AAAA,EACF,CAAC;AACD,QAAM,eAAe,UAAM,eAAAC;AAAA,IACzB;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT;AAAA,MACA,KAAK;AAAA,IACP;AAAA,IACA;AAAA,MACE,UAAU,MAAM;AACd,uBAAAD,SAAI,EAAE,SAAK,mBAAI,sBAAsB,CAAC;AACtC,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AAEA,MAAI,aAAa,KAAK,WAAW,GAAG;AAClC,mBAAAA,SAAI,EAAE,SAAK,mBAAI,gDAA4C,oBAAK,mBAAmB,CAAC,eAAe,CAAC;AACpG;AAAA,EACF;AAGA,QAAM,oBAAgB,YAAAD,MAAS,SAAS,UAAU,YAAY;AAC9D,MAAI,mBAAmB,UAAM,0BAAS,eAAe,MAAM;AAC3D,MAAI,WAAW;AACf,aAAW,gBAAgB,aAAa,MAAM;AAC5C,UAAM,WAAW,QAAQ,KAAK,OAAK,EAAE,SAAS,YAAY;AAC1D,QAAI,YAAY,SAAS,SAAS,SAAS;AACzC,YAAM,eAAe,SAAS;AAC9B,YAAM,UAAU,cAAc,cAAc,cAAc,SAAS,SAAS,CAAC;AAC7E,0BAAoB,GAAG,OAAO;AAAA;AAC9B;AAAA,IACF;AAAA,EACF;AACA,YAAM,2BAAU,eAAe,gBAAgB;AAE/C,QAAM,cAAc,aAAa,KAAK,SAAS,IAAI,YAAY;AAC/D,iBAAAC;AAAA,QACE;AAAA,MACE,SAAS,WAAW,YAAQ,oBAAK,mBAAmB,CAAC,UAAM,mBAAI,+CAA+C,CAAC;AAAA,IACjH;AAAA,EACF,EAAE,QAAQ;AACZ;AAIA,SAAS,cAAc,cAAsB,cAAsB,IAAoB;AAErF,QAAM,cAAc,eAAe,YAAY;AAG/C,QAAM,WAAW,eAAe;AAChC,QAAM,WAAW,eAAe;AAChC,QAAM,OAAO;AAGb,QAAM,IAAI,MAAM,EAAE,EAAE,KAAK,EAAE;AAE3B,IAAE,CAAC,IAAI;AAEP,IAAE,CAAC,IAAI;AAEP,IAAE,CAAC,IAAI;AAEP,IAAE,CAAC,IAAI;AAEP,IAAE,CAAC,IAAI;AAEP,IAAE,CAAC,IAAI;AAEP,IAAE,CAAC,IAAI;AAEP,IAAE,CAAC,IAAI;AAEP,IAAE,CAAC,IAAI;AAEP,IAAE,EAAE,IAAI;AAER,IAAE,EAAE,IAAI;AAER,SAAO,EAAE,KAAK,GAAG;AACnB;AAEA,SAAS,eAAe,GAAmB;AAGzC,SAAO,EAAE,SAAS,GAAG,IAAI,IAAI,CAAC,MAAM;AACtC;AAEA,eAAe,cAAc,SAAiB,SAAyC;AAMrF,QAAM,eAAW,YAAAE,SAAY,SAAS,YAAY,OAAO;AACzD,YAAM,uBAAM,UAAU,EAAE,WAAW,KAAK,CAAC;AAGzC,QAAM,OAAO,CAAC;AAQd,QAAM,cAAU,YAAAA,SAAY,SAAS,OAAO;AAC5C,QAAM,mBAAe;AAAA,IAAgB;AAAA,IAAS;AAAA,IAAM;AAAA;AAAA,IAAwB;AAAA,EAAK;AAGjF,QAAM,aAAS,qBAAQ,OAAO;AAC9B,QAAM,cAAU,YAAAC,OAAU,OAAO,EAAE;AACnC,YAAM,iCAAiB,cAAc,MAAM,CAAC,cAAc,GAAG,QAAQ,SAAS,QAAQ;AAMtF,QAAM,mBAAe,YAAAJ,MAAS,UAAU,GAAG,OAAO,YAAY;AAC9D,QAAM,kBAAkB,UAAM,0BAAS,cAAc,MAAM;AAC3D,QAAM,UAAU,YAAAK,QAAK,MAAM,eAAe;AAG1C,QAAM,UAAyB,CAAC;AAChC,aAAW,UAAU,SAAS;AAG5B,YAAQ,OAAO,SAAS;AAAA,MACtB,KAAK;AACH,gBAAQ,KAAK;AAAA,UACX,MAAM;AAAA,UACN,MAAM,OAAO;AAAA,UACb,OAAO,OAAO,WAAW,OAAO,YAAY;AAAA,QAC9C,CAAC;AACD;AAAA,MACF,KAAK;AACH,gBAAQ,KAAK;AAAA,UACX,MAAM;AAAA,UACN,MAAM,OAAO;AAAA,QACf,CAAC;AACD;AAAA,MACF,KAAK;AACH,gBAAQ,KAAK;AAAA,UACX,MAAM;AAAA,UACN,MAAM,OAAO;AAAA,QACf,CAAC;AACD;AAAA,MACF;AACE;AAAA,IACJ;AAAA,EACF;AAEA,SAAO;AACT;;;ACjdA,mBAAsB;AACtB,IAAAC,iBAAsD;AACtD,IAAAC,cAAgB;AAChB,IAAAC,kBAAoB;AAGpB,eAAsB,kBAAkB,SAAiB,MAAiB,YAAmC;AAE3G,QAAM,kBAAkB,UAAM,gBAAAC;AAAA,IAC5B;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS,6BAA6B,UAAU,sBAAkB,0BAAM,oBAAI,eAAe,CAAC,CAAC;AAAA,MAC7F,SAAS;AAAA,IACX;AAAA,IACA;AAAA,MACE,UAAU,MAAM;AACd,wBAAAC,SAAI,EAAE;AAAA,cACJ,oBAAI,qGAAqG;AAAA,QAC3G;AACA,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AAGA,MAAI,KAAK,QAAQ;AACf,oBAAAA,SAAI,EAAE,SAAK,oBAAI,8BAA8B,CAAC;AAC9C;AAAA,EACF,WAAW,CAAC,gBAAgB,SAAS;AACnC,oBAAAA,SAAI,EAAE,SAAK,oBAAI,2DAA2D,CAAC;AAC3E;AAAA,EACF;AAGA,QAAM,kBAAc,oBAAM,YAAY,CAAC,SAAS,GAAG,EAAE,KAAK,QAAQ,CAAC;AACnE,QAAM,wBAAwB;AAC9B,QAAM,qBAAiB,YAAAA,SAAI,qBAAqB,EAAE,MAAM;AACxD,MAAI;AACF,UAAM,IAAI,QAAc,CAAC,SAAS,WAAW;AAC3C,kBAAY,QAAQ,GAAG,QAAQ,SAAU,MAAM;AAC7C,uBAAe,OAAO,GAAG,qBAAqB;AAAA,MAAK,qBAAK,IAAI,UAAU,GAAG,CAAC,IAAI,IAAI;AAAA,MACpF,CAAC;AACD,kBAAY,QAAQ,GAAG,QAAQ,SAAU,MAAM;AAC7C,uBAAe,OAAO,GAAG,qBAAqB;AAAA,MAAK,qBAAK,IAAI,UAAU,GAAG,CAAC,IAAI,IAAI;AAAA,MACpF,CAAC;AACD,kBAAY,GAAG,SAAS,WAAS,OAAO,KAAK,CAAC;AAC9C,kBAAY,GAAG,SAAS,UAAQ;AAC9B,YAAI,SAAS,GAAG;AACd,iBAAO,wBAAwB,IAAI,GAAG;AAAA,QACxC,OAAO;AACL,kBAAQ;AAAA,QACV;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AACD,mBAAe,WAAO,sBAAM,qBAAqB;AACjD,mBAAe,QAAQ;AAAA,EACzB,SAAS,GAAG;AACV,mBAAe,WAAO;AAAA,MACpB,2DAAuD;AAAA,QACrD,GAAG,UAAU;AAAA,MACf,CAAC;AAAA,IACH;AACA,mBAAe,KAAK;AAAA,EACtB;AACF;;;ACjEA,IAAAC,aAA2B;AAC3B,IAAAC,eAAuC;AAEvC,IAAAC,iBAAsC;AACtC,IAAAC,cAAgB;AAChB,IAAAC,kBAAoB;AAGpB,eAAsB,iBAAiB,MAAkC;AAKvE,WAAS,WAAW,KAAsB;AACxC,UAAM,kBAAc,aAAAC,SAAY,KAAK,cAAc;AACnD,UAAM,kBAAc,aAAAA,SAAY,KAAK,UAAU;AAC/C,WAAO,KAAC,uBAAW,GAAG,KAAM,KAAC,uBAAW,WAAW,KAAK,KAAC,uBAAW,WAAW;AAAA,EACjF;AAEA,QAAM,kBAAkB,CAAC,QAAgB;AACvC,oBAAAC,aAAI,sBAAM,cAAU,qBAAK,GAAG,CAAC,6BAA6B,CAAC,EAAE,QAAQ;AAAA,EACvE;AAEA,QAAM,oBAAoB,CAAC,QAAgB;AACzC,oBAAAA,aAAI,oBAAI,QAAI,qBAAK,GAAG,CAAC,2EAA2E,CAAC,EAAE,KAAK;AAAA,EAC1G;AAGA,MAAI,UAAU,KAAK,GAAG,EAAE,CAAC;AACzB,MAAI,SAAS;AAEX,QAAI,WAAW,OAAO,GAAG;AAEvB,sBAAgB,OAAO;AAAA,IACzB,OAAO;AAEL,wBAAkB,OAAO;AACzB,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,OAAO;AAEL,UAAM,cAAc,UAAM,gBAAAC;AAAA,MACxB;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAUX;AAAA,MACA;AAAA,QACE,UAAU,MAAM;AACd,0BAAAD,SAAI,EAAE,SAAK,oBAAI,sBAAsB,CAAC;AACtC,kBAAQ,KAAK,CAAC;AAAA,QAChB;AAAA,MACF;AAAA,IACF;AACA,cAAU,YAAY;AACtB,QAAI,YAAY,uBAAuB;AACrC,gBAAU,QAAQ,IAAI;AAAA,IACxB;AACA,QAAI,WAAW,OAAO,GAAG;AACvB,sBAAgB,OAAO;AAAA,IACzB,OAAO;AACL,wBAAkB,OAAO;AACzB,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF;AAEA,SAAO;AACT;;;AC7EA,IAAAE,aAAmC;AACnC,IAAAC,eAAyD;AAEzD,IAAAC,gBAAsB;AACtB,IAAAC,iBAA4C;AAC5C,IAAAC,cAAgB;AAChB,IAAAC,kBAAoB;AAKpB,IAAM,UAAU;AAEhB,eAAsB,mBAAmB,SAAiB,MAAgC;AAIxF,QAAM,qBAAiB,aAAAC,SAAY,SAAS,MAAM,OAAO;AACzD,QAAM,mBAAe,aAAAC,MAAS,SAAS,OAAO;AAC9C,QAAM,kBAAkB,UAAM,gBAAAC;AAAA,IAC5B;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS;AAAA;AAAA,QAEP;AAAA,UACE,OAAO,uCAAmC,qBAAK,cAAc,CAAC;AAAA,UAC9D,aAAa;AAAA,UACb,OAAO;AAAA,QACT;AAAA,QACA;AAAA,UACE,OAAO,wCAAoC,qBAAK,YAAY,CAAC;AAAA,UAC7D,aAAa;AAAA,UACb,OAAO;AAAA,QACT;AAAA,QACA;AAAA,UACE,OAAO;AAAA,UACP,aAAa;AAAA,UACb,OAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,MACE,UAAU,MAAM;AACd,wBAAAC,SAAI,EAAE;AAAA,cACJ;AAAA,YACE;AAAA,UACF;AAAA,QACF;AACA,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AAGA,MAAI,KAAK,QAAQ;AACf,oBAAAA,SAAI,EAAE,SAAK,oBAAI,8BAA8B,CAAC;AAC9C;AAAA,EACF,WAAW,gBAAgB,YAAY,QAAQ;AAC7C,oBAAAA,SAAI,EAAE;AAAA,UACJ;AAAA,QACE,8EAA0E,qBAAK,eAAe,CAAC;AAAA,MACjG;AAAA,IACF;AACA;AAAA,EACF;AAEA,QAAM,aAAa,gBAAgB,YAAY,WAAW,iBAAiB;AAC3E,MAAI;AAEF,UAAM,kBAAkB,UAAU;AAAA,EACpC,SAAS,GAAG;AACV,oBAAAA,aAAI,oBAAI,qCAAqC,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK;AAChE,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,kBAAAA,aAAI,sBAAM,wCAAoC,qBAAK,UAAU,CAAC,GAAG,CAAC,EAAE,QAAQ;AAC9E;AAYA,eAAe,kBAAkB,UAAuE;AAEtG,MAAI,KAAC,uBAAW,QAAQ,GAAG;AACzB,YAAQ,IAAI,iCAAiC,QAAQ,EAAE;AAEvD,cAAM,qBAAM,OAAO,CAAC,SAAS,gDAAgD,QAAQ,CAAC;AAAA,EACxF,OAAO;AACL,YAAQ,IAAI,4CAA4C,QAAQ,EAAE;AAAA,EACpE;AAGA,MAAI,QAAQ,IAAI,IAAI;AAIlB,YAAQ,IAAI,yCAAyC;AACrD,UAAM,aAAS,aAAAF,MAAS,UAAU,MAAM;AACxC,2BAAO,QAAQ,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,EACjD,OAAO;AAEL,YAAQ,IAAI,oDAAoD;AAChE,cAAM,qBAAM,OAAO,CAAC,MAAM,GAAG,EAAE,KAAK,SAAS,CAAC;AAAA,EAEhD;AAEA,QAAM,WAAW,UAAU,SAAmB;AAC5C,eAAO,qBAAM,WAAW,CAAC,YAAY,GAAG,IAAI,GAAG,EAAE,KAAK,SAAS,CAAC;AAAA,EAClE;AAEA,UAAQ,IAAI,6BAA6B,OAAO,KAAK;AACrD,QAAM,SAAS,WAAW,OAAO;AACjC,QAAM,SAAS,YAAY,OAAO;AACpC;;;AC1HA,IAAAG,gBAA6B;AAC7B,IAAAC,iBAAgD;AAChD,IAAAC,cAAgB;AAChB,IAAAC,kBAAoB;AAGpB,eAAsB,cAAc,SAAiB,MAAgC;AAEnF,QAAM,cAAc,UAAM,gBAAAC;AAAA,IACxB;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS,0DAAsD,0BAAM,oBAAI,YAAY,CAAC,CAAC;AAAA,MACvF,SAAS;AAAA,IACX;AAAA,IACA;AAAA,MACE,UAAU,MAAM;AACd,wBAAAC,SAAI,EAAE,SAAK,oBAAI,oEAAoE,CAAC;AACpF,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AAGA,MAAI,KAAK,QAAQ;AACf,oBAAAA,SAAI,EAAE,SAAK,oBAAI,8BAA8B,CAAC;AAC9C;AAAA,EACF,WAAW,CAAC,YAAY,KAAK;AAC3B,oBAAAA,SAAI,EAAE,SAAK,oBAAI,6CAAyC,qBAAK,UAAU,CAAC,SAAS,CAAC;AAClF;AAAA,EACF;AAGA,MAAI;AACF,cAAM,4BAAa,YAAY,EAAE,KAAK,QAAQ,CAAC;AAC/C,oBAAAA,SAAI,EAAE,YAAQ,sBAAM,6BAA6B,CAAC;AAAA,EACpD,SAAS,GAAG;AACV,oBAAAA,SAAI,EAAE;AAAA,UACJ;AAAA,QACE,wFAAoF,qBAAK,UAAU,CAAC;AAAA,MACtG;AAAA,IACF;AAAA,EACF;AACF;;;AC3CA,IAAAC,mBAAmC;AACnC,IAAAC,eAAmE;AAEnE,IAAAC,iBAA+C;AAC/C,IAAAC,cAAgB;AAEhB,IAAAC,kBAAoB;AAEpB,IAAM,mBAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAoBzB,eAAsB,cAAc,SAAkC;AAGpE,iBAAe,SAAS,KAAgC;AACtD,UAAM,UAAU,UAAM,0BAAQ,KAAK,EAAE,eAAe,KAAK,CAAC;AAC1D,UAAM,QAAQ,MAAM,QAAQ;AAAA,MAC1B,QAAQ,IAAI,YAAU;AACpB,cAAM,UAAM,aAAAC,SAAY,KAAK,OAAO,IAAI;AACxC,eAAO,OAAO,YAAY,IAAI,SAAS,GAAG,IAAI;AAAA,MAChD,CAAC;AAAA,IACH;AACA,WAAO,MAAM,KAAK;AAAA,EACpB;AACA,QAAM,WAAW,MAAM,SAAS,OAAO;AACvC,QAAM,WAAW,SAAS,OAAO,OAAK,EAAE,SAAS,MAAM,CAAC,EAAE,IAAI,WAAK,uBAAS,SAAS,CAAC,CAAC;AACvF,QAAM,aAAa,SAAS,IAAI,OAAK;AACnC,WAAO;AAAA,MACL,OAAO;AAAA,MACP,OAAO;AAAA,IACT;AAAA,EACF,CAAC;AAED,MAAI;AACJ,MAAI,SAAS,WAAW,GAAG;AAEzB,UAAM,oBAAgB,aAAAC,MAAS,SAAS,YAAY;AACpD,cAAM,4BAAU,eAAe,gBAAgB;AAC/C,oBAAAC;AAAA,UACE;AAAA,QACE,+BAA+B,OAAO,aAAS;AAAA,UAC7C;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF,EAAE,KAAK;AACP,cAAU;AAAA,EACZ,WAAW,SAAS,WAAW,GAAG;AAEhC,oBAAAA,SAAI,EAAE,QAAQ,UAAU,SAAS,CAAC,CAAC,qDAAqD;AACxF,cAAU,SAAS,CAAC;AAAA,EACtB,OAAO;AAGL,UAAM,UAAU,UAAM,gBAAAC;AAAA,MACpB;AAAA,QACE;AAAA,UACE,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,UACT,SAAS;AAAA,QACX;AAAA,MACF;AAAA,MACA;AAAA,QACE,UAAU,MAAM;AACd,0BAAAD,SAAI,EAAE,SAAK,oBAAI,sBAAsB,CAAC;AACtC,kBAAQ,KAAK,CAAC;AAAA,QAChB;AAAA,MACF;AAAA,IACF;AACA,cAAU,QAAQ;AAAA,EACpB;AAEA,kBAAAA,aAAI,sBAAM,cAAU,qBAAK,OAAO,CAAC,iCAAiC,CAAC,EAAE,QAAQ;AAE7E,SAAO;AACT;;;AC5FA,IAAAE,aAA6D;AAC7D,IAAAC,mBAA0B;AAC1B,sBAAqB;AACrB,gBAAuB;AACvB,IAAAC,eAAiC;AAEjC,mBAAiC;AACjC,IAAAC,iBAAwC;AAExC,IAAAC,cAAgB;AAChB,IAAAC,kBAAoB;AAGpB,IAAM,YAAY;AAAA,EAChB;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,IACb,OAAO;AAAA,EACT;AAAA,EACA;AAAA,IACE,OAAO;AAAA,IACP,aAAa;AAAA,IACb,OAAO;AAAA,EACT;AACF;AAEA,eAAsB,eAAe,SAAiB,MAAiB,YAAqC;AAE1G,QAAM,UAAU,UAAM,gBAAAC;AAAA,IACpB;AAAA,MACE;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,MACX;AAAA,IACF;AAAA,IACA;AAAA,MACE,UAAU,MAAM;AACd,wBAAAC,SAAI,EAAE,SAAK,oBAAI,sBAAsB,CAAC;AACtC,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AAGA,MAAI,KAAK,QAAQ;AACf,oBAAAA,SAAI,EAAE,SAAK,oBAAI,8BAA8B,CAAC;AAC9C;AAAA,EACF;AAGA,QAAM,aAAa;AACnB,QAAM,SAAS,KAAK,UAAU;AAG9B,QAAM,iBAAiB,4CAA4C,QAAQ,QAAQ,IAAI,MAAM;AAC7F,QAAM,sBAAkB,YAAAA,SAAI,0BAA0B,EAAE,MAAM;AAC9D,QAAM,aAAa,gBAAgB,SAAS,eAAe;AAC3D,kBAAgB,WAAO,sBAAM,kBAAkB;AAC/C,kBAAgB,QAAQ;AAExB,MAAI,QAAQ,aAAa,sBAAsB,eAAe,QAAQ;AAIpE,UAAM,oBAAgB,aAAAC,MAAS,SAAS,qBAAqB;AAC7D,UAAM,mBAAmB;AAAA;AAAA;AACzB,cAAM,4BAAU,eAAe,gBAAgB;AAAA,EACjD;AAEA,SAAO,QAAQ;AACjB;AAEA,eAAe,aAAa,gBAAwB,QAAgB,SAA6B;AAC/F,MAAI;AAEF,UAAM,aAAS,4BAAY,aAAAA,UAAS,kBAAO,GAAG,aAAa,CAAC;AAI5D,cAAM,+BAAiB,UAAU,cAAc,IAAI;AAAA,MACjD,OAAO;AAAA,MACP,UAAU;AAAA,MACV,KAAK;AAAA,IACP,CAAC;AAID,QAAI,KAAC,uBAAW,MAAM,SAAK,wBAAY,MAAM,EAAE,WAAW,GAAG;AAC3D,YAAM,IAAI,MAAM,8EAA8E;AAAA,IAChG;AAGA,cAAM,sBAAK,QAAQ,QAAQ;AAAA,MACzB,WAAW;AAAA,MACX,cAAc;AAAA,IAChB,CAAC;AAGD,2BAAO,QAAQ,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,EACjD,SAAS,GAAG;AAGV,YAAQ,KAAK;AACb,YAAQ,UAAM,oBAAI,EAAE,OAAO,CAAC;AAC5B,YAAQ,UAAM,uBAAO,6CAA6C,CAAC;AACnE,YAAQ;AAAA,UACN;AAAA,QACE;AAAA,MACF;AAAA,IACF;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;;;APlGA,eAAsB,OAAsB;AAE1C,QAAM,iBAAa,qBAAAC,SAAqB,GAAG,QAAQ;AAGnD,QAAM,WAAO,oBAAAC,SAAM,QAAQ,IAAI;AAC/B,kBAAAC,QAAQ,SAAS,IAAI;AAGrB,UAAQ,IAAI;AAAA,MAAK,qBAAK,0BAA0B,CAAC,EAAE;AACnD,UAAQ,IAAI;AAAA,CAA2D;AAGvE,QAAM,UAAU,MAAM,iBAAiB,IAAI;AAC3C,UAAQ,IAAI;AAGZ,QAAM,eAAe,MAAM,eAAe,SAAS,MAAM,UAAU;AACnE,UAAQ,IAAI;AAGZ,QAAM,UAAU,MAAM,cAAc,OAAO;AAI3C,QAAM,gBAAgB,SAAS,OAAO;AACtC,QAAM,kBAAkB,SAAS,OAAO;AACxC,UAAQ,IAAI;AAGZ,MAAI,iBAAiB,sBAAsB,CAAC,KAAK,QAAQ;AACvD,UAAM,gBAAgB,SAAS,OAAO;AACtC,YAAQ,IAAI;AAAA,EACd;AAGA,QAAM,mBAAmB,SAAS,IAAI;AACtC,UAAQ,IAAI;AAGZ,QAAM,kBAAkB,SAAS,MAAM,UAAU;AACjD,UAAQ,IAAI;AAGZ,QAAM,cAAc,SAAS,IAAI;AACjC,UAAQ,IAAI;AAEZ,kBAAAC,aAAI,sBAAM,iBAAiB,CAAC,EAAE,QAAQ;AAEtC,UAAQ,IAAI;AAAA,MAAK,2BAAO,sBAAM,cAAc,CAAC,CAAC;AAAA,CAAI;AAElD,QAAM,iBAAa,uBAAS,QAAQ,IAAI,GAAG,OAAO;AAClD,QAAM,SAAS,eAAe,QAAQ,gBAAgB,GAAG,UAAU;AAGnE,MAAI,eAAe,IAAI;AACrB,YAAQ,IAAI,mBAAe,yBAAK,qBAAK,IAAI,CAAC,CAAC,iBAAa,yBAAK,qBAAK,UAAU,CAAC,CAAC,qBAAqB;AAAA,EACrG;AACA,UAAQ,IAAI,WAAO,yBAAK,qBAAK,MAAM,CAAC,CAAC,uCAAmC,yBAAK,qBAAK,QAAQ,CAAC,CAAC,YAAY;AACxG,UAAQ,IAAI,EAAE;AAChB;","names":["import_path","import_colors","import_ora","import_prompts","joinPath","ora","prompts","resolvePath","parsePath","yaml","import_colors","import_ora","import_prompts","prompts","ora","import_fs","import_path","import_colors","import_ora","import_prompts","resolvePath","ora","prompts","import_fs","import_path","import_execa","import_colors","import_ora","import_prompts","resolvePath","joinPath","prompts","ora","import_execa","import_colors","import_ora","import_prompts","prompts","ora","import_promises","import_path","import_colors","import_ora","import_prompts","resolvePath","joinPath","ora","prompts","import_fs","import_promises","import_path","import_colors","import_ora","import_prompts","prompts","ora","joinPath","detectPackageManager","yargs","prompts","ora"]}
package/dist/index.js CHANGED
@@ -557,7 +557,7 @@ async function installEmscripten(emsdkDir) {
557
557
 
558
558
  // src/step-git.ts
559
559
  import { execaCommand } from "execa";
560
- import { cyan as cyan4, dim as dim5, green as green5, reset as reset3 } from "kleur/colors";
560
+ import { cyan as cyan4, dim as dim5, green as green5, reset as reset3, yellow as yellow3 } from "kleur/colors";
561
561
  import ora5 from "ora";
562
562
  import prompts5 from "prompts";
563
563
  async function chooseGitInit(projDir, args) {
@@ -582,14 +582,22 @@ async function chooseGitInit(projDir, args) {
582
582
  ora5().info(dim5(`No problem! You can come back and run ${cyan4(`git init`)} later.`));
583
583
  return;
584
584
  }
585
- await execaCommand("git init", { cwd: projDir });
586
- ora5().succeed(green5("Git repository initialized!"));
585
+ try {
586
+ await execaCommand("git init", { cwd: projDir });
587
+ ora5().succeed(green5("Git repository initialized!"));
588
+ } catch (e) {
589
+ ora5().warn(
590
+ yellow3(
591
+ `There was a problem initializing the Git repository, but no problem, you can run ${cyan4(`git init`)} later.`
592
+ )
593
+ );
594
+ }
587
595
  }
588
596
 
589
597
  // src/step-mdl.ts
590
598
  import { readdir, writeFile as writeFile2 } from "fs/promises";
591
599
  import { join as joinPath3, relative as relative2, resolve as resolvePath4 } from "path";
592
- import { bold as bold5, cyan as cyan5, dim as dim6, green as green6, yellow as yellow3 } from "kleur/colors";
600
+ import { bold as bold5, cyan as cyan5, dim as dim6, green as green6, yellow as yellow4 } from "kleur/colors";
593
601
  import ora6 from "ora";
594
602
  import prompts6 from "prompts";
595
603
  var sampleMdlContent = `{UTF-8}
@@ -634,7 +642,7 @@ async function chooseMdlFile(projDir) {
634
642
  const sampleMdlFile = joinPath3(projDir, "sample.mdl");
635
643
  await writeFile2(sampleMdlFile, sampleMdlContent);
636
644
  ora6(
637
- yellow3(
645
+ yellow4(
638
646
  `No mdl files were found in "${projDir}". A "${cyan5(
639
647
  "sample.mdl"
640
648
  )}" file has been added to the project to get you started.`
@@ -673,8 +681,8 @@ import { writeFile as writeFile3 } from "fs/promises";
673
681
  import { copy } from "fs-extra";
674
682
  import { tmpdir } from "os";
675
683
  import { join as joinPath4 } from "path";
676
- import degit from "degit";
677
- import { dim as dim7, green as green7, red as red3, yellow as yellow4 } from "kleur/colors";
684
+ import { downloadTemplate } from "giget";
685
+ import { dim as dim7, green as green7, red as red3, yellow as yellow5 } from "kleur/colors";
678
686
  import ora7 from "ora";
679
687
  import prompts7 from "prompts";
680
688
  var TEMPLATES = [
@@ -712,10 +720,9 @@ async function chooseTemplate(projDir, args, pkgManager) {
712
720
  }
713
721
  const defaultRev = "main";
714
722
  const commit = args.commit || defaultRev;
715
- const templateTarget = `climateinteractive/SDEverywhere/examples/${options.template}`;
716
- const hash = `#${commit}`;
723
+ const templateTarget = `climateinteractive/SDEverywhere/examples/${options.template}#${commit}`;
717
724
  const templateSpinner = ora7("Copying project files...").start();
718
- await runDegit(templateTarget, hash, projDir, args, templateSpinner);
725
+ await copyTemplate(templateTarget, projDir, templateSpinner);
719
726
  templateSpinner.text = green7("Template copied!");
720
727
  templateSpinner.succeed();
721
728
  if (options.template === "template-default" && pkgManager === "pnpm") {
@@ -727,23 +734,16 @@ async function chooseTemplate(projDir, args, pkgManager) {
727
734
  }
728
735
  return options.template;
729
736
  }
730
- async function runDegit(templateTarget, hash, dstDir, args, spinner) {
731
- const verbose = args.verbose;
732
- const emitter = degit(`${templateTarget}${hash}`, {
733
- cache: false,
734
- force: true,
735
- verbose
736
- });
737
+ async function copyTemplate(templateTarget, dstDir, spinner) {
737
738
  try {
738
- if (verbose) {
739
- emitter.on("info", (info) => {
740
- console.log(info.message);
741
- });
742
- }
743
739
  const tmpDir = mkdtempSync(joinPath4(tmpdir(), "sde-create-"));
744
- await emitter.clone(tmpDir);
740
+ await downloadTemplate(`github:${templateTarget}`, {
741
+ force: true,
742
+ provider: "github",
743
+ dir: tmpDir
744
+ });
745
745
  if (!existsSync4(tmpDir) || readdirSync(tmpDir).length === 0) {
746
- throw new Error("The requested template failed to download");
746
+ throw new Error("Failed to download the requested template: the temporary directory is empty.");
747
747
  }
748
748
  await copy(tmpDir, dstDir, {
749
749
  overwrite: false,
@@ -753,10 +753,10 @@ async function runDegit(templateTarget, hash, dstDir, args, spinner) {
753
753
  } catch (e) {
754
754
  spinner.fail();
755
755
  console.error(red3(e.message));
756
- console.error(yellow4("There was a problem copying the template."));
756
+ console.error(yellow5("\nThere was a problem copying the template."));
757
757
  console.error(
758
- yellow4(
759
- "Please file a new issue with the command output here: https://github.com/climateinteractive/sdeverywhere/issues"
758
+ yellow5(
759
+ "Please start a new discussion thread and include the command output so that we can help:\n https://github.com/climateinteractive/SDEverywhere/discussions/categories/q-a\n"
760
760
  )
761
761
  );
762
762
  process.exit(0);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/step-config.ts","../src/step-deps.ts","../src/step-directory.ts","../src/step-emsdk.ts","../src/step-git.ts","../src/step-mdl.ts","../src/step-template.ts"],"sourcesContent":["// Copyright (c) 2022 Climate Interactive / New Venture Fund\n\nimport { relative } from 'path'\n\nimport { bgCyan, black, bold, cyan, green } from 'kleur/colors'\nimport ora from 'ora'\nimport prompts from 'prompts'\nimport detectPackageManager from 'which-pm-runs'\nimport yargs from 'yargs-parser'\n\nimport { chooseGenConfig, generateCheckYaml, updateSdeConfig } from './step-config'\nimport { chooseInstallDeps } from './step-deps'\nimport { chooseProjectDir } from './step-directory'\nimport { chooseInstallEmsdk } from './step-emsdk'\nimport { chooseGitInit } from './step-git'\nimport { chooseMdlFile } from './step-mdl'\nimport { chooseTemplate } from './step-template'\n\nexport async function main(): Promise<void> {\n // Detect the package manager\n const pkgManager = detectPackageManager()?.name || 'npm'\n\n // Parse command line arguments\n const args = yargs(process.argv)\n prompts.override(args)\n\n // Display welcome message\n console.log(`\\n${bold('Welcome to SDEverywhere!')}`)\n console.log(`Let's create a new SDEverywhere project for your model.\\n`)\n\n // Prompt the user to select a project directory\n const projDir = await chooseProjectDir(args)\n console.log()\n\n // Prompt the user to select a template\n const templateName = await chooseTemplate(projDir, args, pkgManager)\n console.log()\n\n // Prompt the user to select an mdl file\n const mdlPath = await chooseMdlFile(projDir)\n\n // Update the `sde.config.js` file to use the chosen mdl file and\n // generate a sample `.check.yaml` file\n await updateSdeConfig(projDir, mdlPath)\n await generateCheckYaml(projDir, mdlPath)\n console.log()\n\n // If the user chose the default template, offer to set up CSV files\n if (templateName === 'template-default' && !args.dryRun) {\n await chooseGenConfig(projDir, mdlPath)\n console.log()\n }\n\n // Prompt the user to install Emscripten SDK\n await chooseInstallEmsdk(projDir, args)\n console.log()\n\n // Prompt the user to install dependencies\n await chooseInstallDeps(projDir, args, pkgManager)\n console.log()\n\n // Prompt the user to initialize a git repo\n await chooseGitInit(projDir, args)\n console.log()\n\n ora(green('Setup complete!')).succeed()\n\n console.log(`\\n${bgCyan(black(' Next steps '))}\\n`)\n\n const relProjDir = relative(process.cwd(), projDir)\n const devCmd = pkgManager === 'npm' ? 'npm run dev' : `${pkgManager} dev`\n\n // If the project dir is the current dir, no need to tell users to cd\n if (relProjDir !== '') {\n console.log(`You can now ${bold(cyan('cd'))} into the ${bold(cyan(relProjDir))} project directory.`)\n }\n console.log(`Run ${bold(cyan(devCmd))} to start the local dev server. ${bold(cyan('CTRL-C'))} to close.`)\n console.log('')\n}\n","// Copyright (c) 2022 Climate Interactive / New Venture Fund\n\nimport { existsSync } from 'fs'\nimport { mkdir, readFile, writeFile } from 'fs/promises'\nimport { dirname, join as joinPath, parse as parsePath, relative, resolve as resolvePath } from 'path'\n\nimport { bold, cyan, dim, green, reset, yellow } from 'kleur/colors'\nimport ora from 'ora'\nimport type { Choice } from 'prompts'\nimport prompts from 'prompts'\nimport yaml from 'yaml'\n\nimport { parseAndGenerate, preprocessModel } from '@sdeverywhere/compile'\n\ninterface MdlConstVariable {\n kind: 'const'\n name: string\n value: number\n}\n\ninterface MdlAuxVariable {\n kind: 'aux'\n name: string\n}\n\ninterface MdlLevelVariable {\n kind: 'level'\n name: string\n}\n\ntype MdlVariable = MdlConstVariable | MdlAuxVariable | MdlLevelVariable\n\nconst sampleCheckContent = `\\\n# yaml-language-server: $schema=SCHEMA_PATH\n\n# NOTE: This is just a simple check to get you started. Replace \"Some output\" with\n# the name of some variable you'd like to test. Additional tests can be developed\n# in the \"playground\" (beta) inside the model-check report.\n- describe: Some output\n tests:\n - it: should be > 0 for all input scenarios\n scenarios:\n - preset: matrix\n datasets:\n - name: Some output\n predicates:\n - gt: 0\n`\n\nexport async function updateSdeConfig(projDir: string, mdlPath: string): Promise<void> {\n // Read the `sde.config.js` file from the template\n const configPath = joinPath(projDir, 'sde.config.js')\n let configText = await readFile(configPath, 'utf8')\n\n // Replace instances of `MODEL_NAME.mdl` with the path to the chosen mdl file\n configText = configText.replaceAll('MODEL_NAME.mdl', mdlPath)\n\n // Write the updated file\n await writeFile(configPath, configText)\n}\n\nexport async function generateCheckYaml(projDir: string, mdlPath: string): Promise<void> {\n // Generate a sample `{mdl}.check.yaml` file if one doesn't already exist\n // TODO: Make this optional (ask user first)?\n const checkYamlFile = mdlPath.replace('.mdl', '.check.yaml')\n const checkYamlPath = joinPath(projDir, checkYamlFile)\n if (!existsSync(checkYamlPath)) {\n // Get relative path from yaml file parent dir to project dir\n let relProjPath = relative(dirname(checkYamlPath), projDir)\n if (relProjPath.length === 0) {\n relProjPath = './'\n }\n\n // TODO: This path is normally different depending on whether using npm/yarn or\n // pnpm. For npm/yarn, `check-core` is hoisted under top-level `node_modules`,\n // but for pnpm, it is nested under `node_modules/.pnpm`. As an ugly workaround\n // the templates declare `check-core` as a direct dependency even though it is\n // not really needed (a transitive dependency via `plugin-check` would normally\n // suffice). This allows us to use the same path here that works for all\n // three package managers.\n const nodeModulesPart = joinPath(relProjPath, 'node_modules')\n const checkCorePart = '@sdeverywhere/check-core/schema/check.schema.json'\n const schemaPath = `${nodeModulesPart}/${checkCorePart}`\n const checkContent = sampleCheckContent.replace('SCHEMA_PATH', schemaPath)\n await writeFile(checkYamlPath, checkContent)\n }\n}\n\nexport async function chooseGenConfig(projDir: string, mdlPath: string): Promise<void> {\n // TODO: For now we eagerly read the mdl file; maybe change this to only load it if\n // the user chooses to generate graph and/or slider config\n let mdlVars: MdlVariable[]\n try {\n // Get the list of variables available in the model\n mdlVars = await readModelVars(projDir, mdlPath)\n } catch (e) {\n console.log(e)\n ora(\n yellow('The mdl file failed to load. We will continue setting things up, and you can diagnose the issue later.')\n ).warn()\n return\n }\n\n // Extract `INITIAL TIME` and `FINAL TIME` values and remove special control variables from the list\n let initialTime: number\n let finalTime: number\n const validVars: MdlVariable[] = []\n for (const v of mdlVars) {\n const varName = v.name.toLowerCase()\n let skip = false\n switch (varName) {\n case 'final time':\n skip = true\n if (v.kind === 'const') {\n finalTime = v.value\n }\n break\n case 'initial time':\n skip = true\n if (v.kind === 'const') {\n initialTime = v.value\n }\n break\n case 'saveper':\n case 'time':\n case 'time step':\n skip = true\n break\n default:\n break\n }\n if (!skip) {\n validVars.push(v)\n }\n }\n\n // Set the values in `model.csv`\n if (initialTime === undefined) {\n initialTime = 0\n }\n if (finalTime === undefined) {\n finalTime = 100\n }\n\n // TODO: Auto-detect dat files that are referenced by the mdl and include them here\n const datFiles: string[] = []\n const datPart = datFiles.join(';')\n\n // Preserve the `model.csv` header but drop other existing content (if any)\n const modelCsvFile = joinPath(projDir, 'config', 'model.csv')\n const origModelCsvContent = await readFile(modelCsvFile, 'utf8')\n const modelCsvHeader = origModelCsvContent.split('\\n')[0]\n\n // Add line and write out updated `model.csv`\n const modelCsvLine = `${initialTime},${finalTime},${datPart}`\n const newModelCsvContent = `${modelCsvHeader}\\n${modelCsvLine}\\n`\n await writeFile(modelCsvFile, newModelCsvContent)\n\n // See if the user wants to generate graph config\n await chooseGenGraphConfig(projDir, validVars)\n console.log()\n\n // See if the user wants to generate slider config\n await chooseGenSliderConfig(projDir, validVars)\n}\n\nasync function chooseGenGraphConfig(projDir: string, mdlVars: MdlVariable[]): Promise<void> {\n // Prompt the user\n const genResponse = await prompts(\n {\n type: 'confirm',\n name: 'genGraph',\n message: `Would you like to configure a graph to get you started? ${reset(dim('(recommended)'))}`,\n initial: true\n },\n {\n onCancel: () => {\n ora().info(dim('Operation cancelled.'))\n process.exit(0)\n }\n }\n )\n\n // Handle response\n if (!genResponse.genGraph) {\n ora().info(dim(`No problem! You can edit the \"${cyan('config/graphs.csv')}\" file later.`))\n return\n }\n\n // Offer multi-select with available output variables\n const outputVarNames: string[] = []\n for (const mdlVar of mdlVars) {\n if (mdlVar.kind === 'aux' || mdlVar.kind === 'level') {\n outputVarNames.push(mdlVar.name)\n }\n }\n outputVarNames.sort((a, b) => {\n return a.toLowerCase().localeCompare(b.toLowerCase())\n })\n const choices = outputVarNames.map(f => {\n return {\n title: f,\n value: f\n } as Choice\n })\n const varsResponse = await prompts(\n {\n type: 'autocompleteMultiselect',\n name: 'vars',\n message: 'Choose up to three output variables to display in the graph',\n choices,\n max: 3\n },\n {\n onCancel: () => {\n ora().info(dim('Operation cancelled.'))\n process.exit(0)\n }\n }\n )\n\n if (varsResponse.vars.length === 0) {\n ora().info(dim(`No variables selected. You can edit the \"${cyan('config/graphs.csv')}\" file later.`))\n return\n }\n\n // Add line to `graphs.csv`\n const graphsCsvFile = joinPath(projDir, 'config', 'graphs.csv')\n const csvLine = graphsCsvLine(varsResponse.vars)\n let graphsCsvContent = await readFile(graphsCsvFile, 'utf8')\n graphsCsvContent += `${csvLine}\\n`\n await writeFile(graphsCsvFile, graphsCsvContent)\n\n ora(\n green(`Added graph to \"${bold('config/graphs.csv')}\". ${dim('You can configure graphs in that file later.')}`)\n ).succeed()\n}\n\n// TODO: Ideally the `plugin-config` package would expose an API for generating CSV, but\n// until then, we will generate a comma-separated line of values in hardcoded fashion\nfunction graphsCsvLine(outputVarNames: string[]): string {\n const colors = ['blue', 'red', 'green']\n\n // Fill the line with blanks initially, then set the small subset of fields\n const a = Array(131).fill('')\n // id\n a[0] = '1'\n // parent menu\n a[2] = 'Graphs'\n // graph title\n a[3] = 'Graph Title'\n // kind\n a[7] = 'line'\n // Plots start at 26\n let index = 26\n let colorIndex = 0\n for (const outputVarName of outputVarNames) {\n // Surround the name in quotes if it contains a comma\n const escapedName = escapeCsvField(outputVarName)\n // plot N variable\n a[index + 0] = escapedName\n // plot N style\n a[index + 2] = 'line'\n // plot N label\n a[index + 3] = escapedName\n // plot N color\n a[index + 4] = colors[colorIndex]\n index += 7\n colorIndex++\n }\n\n return a.join(',')\n}\n\nasync function chooseGenSliderConfig(projDir: string, mdlVars: MdlVariable[]): Promise<void> {\n // Prompt the user\n const genResponse = await prompts(\n {\n type: 'confirm',\n name: 'genSliders',\n message: `Would you like to configure a few sliders to get you started? ${reset(dim('(recommended)'))}`,\n initial: true\n },\n {\n onCancel: () => {\n ora().info(dim('Operation cancelled.'))\n process.exit(0)\n }\n }\n )\n\n // Handle response\n if (!genResponse.genSliders) {\n ora().info(dim(`No problem! You can edit the \"${cyan('config/inputs.csv')}\" file later.`))\n return\n }\n\n // Offer multi-select with available input variables\n const inputVarNames: string[] = []\n for (const mdlVar of mdlVars) {\n if (mdlVar.kind === 'const') {\n inputVarNames.push(mdlVar.name)\n }\n }\n inputVarNames.sort((a, b) => {\n return a.toLowerCase().localeCompare(b.toLowerCase())\n })\n const choices = inputVarNames.map(f => {\n return {\n title: f,\n value: f\n } as Choice\n })\n const varsResponse = await prompts(\n {\n type: 'autocompleteMultiselect',\n name: 'vars',\n message: 'Choose up to three input variables to control with sliders',\n choices,\n max: 3\n },\n {\n onCancel: () => {\n ora().info(dim('Operation cancelled.'))\n process.exit(0)\n }\n }\n )\n\n if (varsResponse.vars.length === 0) {\n ora().info(dim(`No variables selected. You can edit the \"${cyan('config/inputs.csv')}\" file later.`))\n return\n }\n\n // Add lines to `inputs.csv`\n const inputsCsvFile = joinPath(projDir, 'config', 'inputs.csv')\n let inputsCsvContent = await readFile(inputsCsvFile, 'utf8')\n let idNumber = 1\n for (const inputVarName of varsResponse.vars) {\n const inputVar = mdlVars.find(v => v.name === inputVarName)\n if (inputVar && inputVar.kind === 'const') {\n const defaultValue = inputVar.value\n const csvLine = inputsCsvLine(inputVarName, defaultValue, idNumber.toString())\n inputsCsvContent += `${csvLine}\\n`\n idNumber++\n }\n }\n await writeFile(inputsCsvFile, inputsCsvContent)\n\n const slidersText = varsResponse.vars.length > 1 ? 'sliders' : 'sliders'\n ora(\n green(\n `Added ${slidersText} to \"${bold('config/inputs.csv')}\". ${dim('You can configure sliders in that file later.')}`\n )\n ).succeed()\n}\n\n// TODO: Ideally the `plugin-config` package would expose an API for generating CSV, but\n// until then, we will generate a comma-separated line of values in hardcoded fashion\nfunction inputsCsvLine(inputVarName: string, defaultValue: number, id: string): string {\n // Surround the name in quotes if it contains a comma\n const escapedName = escapeCsvField(inputVarName)\n\n // TODO: Be smarter about automatically choosing min/max/step values\n const minValue = defaultValue - 1\n const maxValue = defaultValue + 1\n const step = 0.1\n\n // Fill the line with blanks initially, then set the small subset of fields\n const a = Array(28).fill('')\n // id\n a[0] = id\n // input type\n a[1] = 'slider'\n // viewid\n a[2] = 'view1'\n // varname\n a[3] = escapedName\n // label\n a[4] = escapedName\n // group name\n a[6] = 'Sliders'\n // slider min\n a[7] = minValue\n // slider max\n a[8] = maxValue\n // slider default\n a[9] = defaultValue\n // slider step\n a[10] = step\n // units\n a[11] = '(units)'\n\n return a.join(',')\n}\n\nfunction escapeCsvField(s: string): string {\n // Surround the value in quotes if it contains a comma\n // TODO: Escape double quotes as well\n return s.includes(',') ? `\"${s}\"` : s\n}\n\nasync function readModelVars(projDir: string, mdlPath: string): Promise<MdlVariable[]> {\n // TODO: This function contains a subset of the logic from `sde-generate.js` in\n // the `cli` package; should revisit\n // let { modelDirname, modelName, modelPathname } = modelPathProps(model)\n\n // Ensure the `build` directory exists (under the `sde-prep` directory)\n const buildDir = resolvePath(projDir, 'sde-prep', 'build')\n await mkdir(buildDir, { recursive: true })\n\n // Use an empty model spec; this will make SDE look at all variables in the mdl\n const spec = {}\n\n // Try parsing the mdl file to generate the list of variables\n // TODO: This depends on some `compile` package APIs that are not yet considered stable.\n // Ideally we'd use an API that does not write files but instead returns an in-memory\n // object in a specified format.\n\n // Read and preprocess the model\n const mdlFile = resolvePath(projDir, mdlPath)\n const preprocessed = preprocessModel(mdlFile, spec, 'genc', /*writeFiles=*/ false)\n\n // Parse the model and generate the variable list\n const mdlDir = dirname(mdlFile)\n const mdlName = parsePath(mdlFile).name\n await parseAndGenerate(preprocessed, spec, ['printVarList'], mdlDir, mdlName, buildDir)\n\n // Read `build/{mdl}_vars.yaml`\n // TODO: For now the printVarList code only outputs txt and yaml files; we'll use the\n // yaml file for now, but that means we have a dependency on the `yaml` package. Once\n // we change the `compile` package to output JSON, we'll need to change this code.\n const varsYamlFile = joinPath(buildDir, `${mdlName}_vars.yaml`)\n const varsYamlContent = await readFile(varsYamlFile, 'utf8')\n const varObjs = yaml.parse(varsYamlContent)\n\n // Create a simplified array of variables\n const mdlVars: MdlVariable[] = []\n for (const varObj of varObjs) {\n // Only include certain variables for now\n // TODO: Include \"data\" vars\n switch (varObj.varType) {\n case 'const':\n mdlVars.push({\n kind: 'const',\n name: varObj.modelLHS,\n value: Number.parseFloat(varObj.modelFormula)\n })\n break\n case 'aux':\n mdlVars.push({\n kind: 'aux',\n name: varObj.modelLHS\n })\n break\n case 'level':\n mdlVars.push({\n kind: 'level',\n name: varObj.modelLHS\n })\n break\n default:\n break\n }\n }\n\n return mdlVars\n}\n","// Copyright (c) 2022 Climate Interactive / New Venture Fund\n\nimport { execa } from 'execa'\nimport { bold, cyan, dim, green, reset, yellow } from 'kleur/colors'\nimport ora from 'ora'\nimport prompts from 'prompts'\nimport type { Arguments } from 'yargs-parser'\n\nexport async function chooseInstallDeps(projDir: string, args: Arguments, pkgManager: string): Promise<void> {\n // Prompt the user\n const installResponse = await prompts(\n {\n type: 'confirm',\n name: 'install',\n message: `Would you like to install ${pkgManager} dependencies? ${reset(dim('(recommended)'))}`,\n initial: true\n },\n {\n onCancel: () => {\n ora().info(\n dim('Operation cancelled. Your project folder has been created, but no dependencies have been installed.')\n )\n process.exit(0)\n }\n }\n )\n\n // Handle response\n if (args.dryRun) {\n ora().info(dim(`--dry-run enabled, skipping.`))\n return\n } else if (!installResponse.install) {\n ora().info(dim(`No problem! Remember to install dependencies after setup.`))\n return\n }\n\n // Install dependencies\n const installExec = execa(pkgManager, ['install'], { cwd: projDir })\n const installingPackagesMsg = 'Installing packages...'\n const installSpinner = ora(installingPackagesMsg).start()\n try {\n await new Promise<void>((resolve, reject) => {\n installExec.stdout?.on('data', function (data) {\n installSpinner.text = `${installingPackagesMsg}\\n${bold(`[${pkgManager}]`)} ${data}`\n })\n installExec.stderr?.on('data', function (data) {\n installSpinner.text = `${installingPackagesMsg}\\n${bold(`[${pkgManager}]`)} ${data}`\n })\n installExec.on('error', error => reject(error))\n installExec.on('close', code => {\n if (code !== 0) {\n reject(`Install failed (code=${code})`)\n } else {\n resolve()\n }\n })\n })\n installSpinner.text = green('Packages installed!')\n installSpinner.succeed()\n } catch (e) {\n installSpinner.text = yellow(\n `There was an error installing packages. Try running ${cyan(\n `${pkgManager} install`\n )} in your project directory later.`\n )\n installSpinner.warn()\n }\n}\n","// Copyright (c) 2022 Climate Interactive / New Venture Fund\n\nimport { existsSync } from 'fs'\nimport { resolve as resolvePath } from 'path'\n\nimport { bold, dim, green, red } from 'kleur/colors'\nimport ora from 'ora'\nimport prompts from 'prompts'\nimport type { Arguments } from 'yargs-parser'\n\nexport async function chooseProjectDir(args: Arguments): Promise<string> {\n /**\n * Return true if the given directory does not exist, or it does not contain important files\n * like `package.json`.\n */\n function isValidDir(dir: string): boolean {\n const packageJson = resolvePath(dir, 'package.json')\n const packagesDir = resolvePath(dir, 'packages')\n return !existsSync(dir) || (!existsSync(packageJson) && !existsSync(packagesDir))\n }\n\n const showValidDirMsg = (dir: string) => {\n ora(green(`Using \"${bold(dir)}\" as the project directory.`)).succeed()\n }\n\n const showInvalidDirMsg = (dir: string) => {\n ora(red(`\"${bold(dir)}\" contains existing 'package.json' and/or 'packages' directory, stopping.`)).fail()\n }\n\n // See if project directory is provided on command line\n let projDir = args['_'][2] as string\n if (projDir) {\n // Directory was provided, see if it is valid\n if (isValidDir(projDir)) {\n // The provided directory is valid, so proceed\n showValidDirMsg(projDir)\n } else {\n // The provided directory is not valid, so show error message and exit\n showInvalidDirMsg(projDir)\n process.exit(0)\n }\n } else {\n // Directory was not provided, so prompt the user\n const dirResponse = await prompts(\n {\n type: 'text',\n name: 'directory',\n message: 'Where would you like to create your new project?',\n initial: '<current directory>'\n // validate(value) {\n // if (value === '<current directory>') {\n // value = process.cwd()\n // }\n // if (!isValidDir(value)) {\n // return notValidMsg(value)\n // }\n // return true\n // }\n },\n {\n onCancel: () => {\n ora().info(dim('Operation cancelled.'))\n process.exit(0)\n }\n }\n )\n projDir = dirResponse.directory\n if (projDir === '<current directory>') {\n projDir = process.cwd()\n }\n if (isValidDir(projDir)) {\n showValidDirMsg(projDir)\n } else {\n showInvalidDirMsg(projDir)\n process.exit(0)\n }\n }\n\n return projDir\n}\n","// Copyright (c) 2022 Climate Interactive / New Venture Fund\n\nimport { existsSync, rmSync } from 'fs'\nimport { join as joinPath, resolve as resolvePath } from 'path'\n\nimport { execa } from 'execa'\nimport { bold, cyan, dim, green, red } from 'kleur/colors'\nimport ora from 'ora'\nimport prompts from 'prompts'\nimport type { Arguments } from 'yargs-parser'\n\n// TODO: Make this configurable; we're using this older version for now because it is\n// relatively stable and has been used to build En-ROADS and C-ROADS for a long time\nconst version = '2.0.34'\n\nexport async function chooseInstallEmsdk(projDir: string, args: Arguments): Promise<void> {\n // TODO: Use findUp and skip this step if emsdk directory already exists\n\n // Prompt the user\n const underParentDir = resolvePath(projDir, '..', 'emsdk')\n const underProjDir = joinPath(projDir, 'emsdk')\n const installResponse = await prompts(\n {\n type: 'select',\n name: 'install',\n message: `Would you like to install the Emscripten SDK?`,\n choices: [\n // ${reset(dim('(recommended)'))\n {\n title: `Install under parent directory (${bold(underParentDir)})`,\n description: 'This is recommended so that it can be shared by multiple projects',\n value: 'parent'\n },\n {\n title: `Install under project directory (${bold(underProjDir)})\"`,\n description: 'This is useful for keeping everything under a single project directory',\n value: 'project'\n },\n {\n title: `Don't install`,\n description: `It's OK, you can install it later`,\n value: 'skip'\n }\n ]\n },\n {\n onCancel: () => {\n ora().info(\n dim(\n 'Operation cancelled. Your project folder has been created, but the Emscripten SDK and other dependencies have not been installed.'\n )\n )\n process.exit(0)\n }\n }\n )\n\n // Handle response\n if (args.dryRun) {\n ora().info(dim(`--dry-run enabled, skipping.`))\n return\n } else if (installResponse.install === 'skip') {\n ora().info(\n dim(\n `No problem! Be sure to install the Emscripten SDK and configure it in \"${cyan('sde.config.js')}\" after setup.`\n )\n )\n return\n }\n\n const installDir = installResponse.install === 'parent' ? underParentDir : underProjDir\n try {\n // TODO: Use spinner here\n await installEmscripten(installDir)\n } catch (e) {\n ora(red(`Failed to install Emscripten SDK: ${e.message}`)).fail()\n process.exit(0)\n }\n\n ora(green(`Installed the Emscripten SDK in \"${bold(installDir)}\"`)).succeed()\n}\n\n/**\n * Install the Emscripten SDK to the `emsdk` directory under the\n * given directory (if `emsdk` is not already present), then\n * activates the requested version (specified with `version`).\n *\n * The implementation is similar to the existing `setup-emsdk` action\n * (https://github.com/mymindstorm/setup-emsdk) except that one has issues\n * with the cache directory on Windows, so having our own script gives us\n * more control over installation and caching behavior.\n */\nasync function installEmscripten(emsdkDir: string /*, options?: { verbose?: boolean }*/): Promise<void> {\n // Only download if the emsdk directory wasn't restored from a cache\n if (!existsSync(emsdkDir)) {\n console.log(`Downloading Emscripten SDK to ${emsdkDir}`)\n // console.log()\n await execa('git', ['clone', 'https://github.com/emscripten-core/emsdk.git', emsdkDir])\n } else {\n console.log(`Found existing Emscripten SDK directory: ${emsdkDir}`)\n }\n // console.log()\n\n if (process.env.CI) {\n // On GitHub Actions, remove the `.git` directory to keep the cache smaller.\n // When we update to a new version, the cache key will miss and the emsdk\n // repo will be redownloaded.\n console.log('CI detected, removing .git directory...')\n const gitDir = joinPath(emsdkDir, '.git')\n rmSync(gitDir, { recursive: true, force: true })\n } else {\n // For local development, pull to get the latest\n console.log('Local development detected, performing git pull...')\n await execa('git', ['pull'], { cwd: emsdkDir })\n // console.log()\n }\n\n const emsdkCmd = async (...args: string[]) => {\n return execa('python3', ['emsdk.py', ...args], { cwd: emsdkDir })\n }\n\n console.log(`Activating Emscripten SDK ${version}...`)\n await emsdkCmd('install', version)\n await emsdkCmd('activate', version)\n}\n","// Copyright (c) 2022 Climate Interactive / New Venture Fund\n\nimport { execaCommand } from 'execa'\nimport { cyan, dim, green, reset } from 'kleur/colors'\nimport ora from 'ora'\nimport prompts from 'prompts'\nimport type { Arguments } from 'yargs-parser'\n\nexport async function chooseGitInit(projDir: string, args: Arguments): Promise<void> {\n // Prompt the user\n const gitResponse = await prompts(\n {\n type: 'confirm',\n name: 'git',\n message: `Would you like to initialize a new git repository? ${reset(dim('(optional)'))}`,\n initial: true\n },\n {\n onCancel: () => {\n ora().info(dim('Operation cancelled. Your project folder has already been created.'))\n process.exit(0)\n }\n }\n )\n\n // Handle response\n if (args.dryRun) {\n ora().info(dim(`--dry-run enabled, skipping.`))\n return\n } else if (!gitResponse.git) {\n ora().info(dim(`No problem! You can come back and run ${cyan(`git init`)} later.`))\n return\n }\n\n // Init git repo\n await execaCommand('git init', { cwd: projDir })\n ora().succeed(green('Git repository initialized!'))\n}\n","// Copyright (c) 2022 Climate Interactive / New Venture Fund\n\nimport { readdir, writeFile } from 'fs/promises'\nimport { join as joinPath, relative, resolve as resolvePath } from 'path'\n\nimport { bold, cyan, dim, green, yellow } from 'kleur/colors'\nimport ora from 'ora'\nimport type { Choice } from 'prompts'\nimport prompts from 'prompts'\n\nconst sampleMdlContent = `\\\n{UTF-8}\n\nX = TIME\n ~~|\n\nY = 0\n ~ [-10,10,0.1]\n ~\n |\n\nZ = X + Y\n ~~|\n\nINITIAL TIME = 2000 ~~|\nFINAL TIME = 2100 ~~|\nTIME STEP = 1 ~~|\nSAVEPER = TIME STEP ~~|\n`\n\nexport async function chooseMdlFile(projDir: string): Promise<string> {\n // Find all `.mdl` files in the project directory\n // From https://stackoverflow.com/a/45130990\n async function getFiles(dir: string): Promise<string[]> {\n const dirents = await readdir(dir, { withFileTypes: true })\n const files = await Promise.all(\n dirents.map(dirent => {\n const res = resolvePath(dir, dirent.name)\n return dirent.isDirectory() ? getFiles(res) : res\n })\n )\n return files.flat()\n }\n const allFiles = await getFiles(projDir)\n const mdlFiles = allFiles.filter(f => f.endsWith('.mdl')).map(f => relative(projDir, f))\n const mdlChoices = mdlFiles.map(f => {\n return {\n title: f,\n value: f\n } as Choice\n })\n\n let mdlFile: string\n if (mdlFiles.length === 0) {\n // No mdl files found; write a sample mdl to get the user started\n const sampleMdlFile = joinPath(projDir, 'sample.mdl')\n await writeFile(sampleMdlFile, sampleMdlContent)\n ora(\n yellow(\n `No mdl files were found in \"${projDir}\". A \"${cyan(\n 'sample.mdl'\n )}\" file has been added to the project to get you started.`\n )\n ).warn()\n mdlFile = 'sample.mdl'\n } else if (mdlFiles.length === 1) {\n // Only one mdl file\n ora().succeed(`Found \"${mdlFiles[0]}\", will configure the project to use that mdl file.`)\n mdlFile = mdlFiles[0]\n } else {\n // Multiple mdl files found; allow the user to choose one\n // TODO: Eventually we should allow the user to choose to flatten if there are multiple submodels\n const options = await prompts(\n [\n {\n type: 'select',\n name: 'mdlFile',\n message: 'It looks like there are multiple mdl files. Which one would you like to use?',\n choices: mdlChoices\n }\n ],\n {\n onCancel: () => {\n ora().info(dim('Operation cancelled.'))\n process.exit(0)\n }\n }\n )\n mdlFile = options.mdlFile\n }\n\n ora(green(`Using \"${bold(mdlFile)}\" as the model for the project.`)).succeed()\n\n return mdlFile\n}\n","// Copyright (c) 2022 Climate Interactive / New Venture Fund\n\nimport { existsSync, mkdtempSync, readdirSync, rmSync } from 'fs'\nimport { writeFile } from 'fs/promises'\nimport { copy } from 'fs-extra'\nimport { tmpdir } from 'os'\nimport { join as joinPath } from 'path'\n\nimport degit from 'degit'\nimport { dim, green, red, yellow } from 'kleur/colors'\nimport type { Ora } from 'ora'\nimport ora from 'ora'\nimport prompts from 'prompts'\nimport type { Arguments } from 'yargs-parser'\n\nconst TEMPLATES = [\n {\n title: 'Default project',\n description: 'Includes recommended structure with config files, app, core library, model-check, etc',\n value: 'template-default'\n },\n {\n title: 'Minimal project',\n description: 'Includes simple config for model-check',\n value: 'template-minimal'\n }\n]\n\nexport async function chooseTemplate(projDir: string, args: Arguments, pkgManager: string): Promise<string> {\n // Prompt the user\n const options = await prompts(\n [\n {\n type: 'select',\n name: 'template',\n message: 'Which template would you like to use?',\n choices: TEMPLATES\n }\n ],\n {\n onCancel: () => {\n ora().info(dim('Operation cancelled.'))\n process.exit(0)\n }\n }\n )\n\n // Handle response\n if (args.dryRun) {\n ora().info(dim(`--dry-run enabled, skipping.`))\n return\n }\n\n // Allow branch name or commit hash to be overridden on command line\n const defaultRev = 'main'\n const commit = args.commit || defaultRev\n\n // Copy the template files to the project directory\n const templateTarget = `climateinteractive/SDEverywhere/examples/${options.template}`\n const hash = `#${commit}`\n const templateSpinner = ora('Copying project files...').start()\n await runDegit(templateTarget, hash, projDir, args, templateSpinner)\n templateSpinner.text = green('Template copied!')\n templateSpinner.succeed()\n\n if (options.template === 'template-default' && pkgManager === 'pnpm') {\n // pnpm doesn't use the \"workspaces\" config from `package.json` (like npm and yarn use),\n // so in the case of pnpm, write a `pnpm-workspace.yaml` file so that the default\n // template monorepo layout is set up correctly\n const workspaceFile = joinPath(projDir, 'pnpm-workspace.yaml')\n const workspaceContent = `packages:\\n - packages/*\\n`\n await writeFile(workspaceFile, workspaceContent)\n }\n\n return options.template\n}\n\n// XXX: This is mostly copied from Astro's create package:\n// https://github.com/withastro/astro/blob/main/packages/create-astro/src/index.ts\n// It contains workarounds for degit issues that may or may not be relevant for SDE,\n// so this should be re-evaluated later.\nasync function runDegit(\n templateTarget: string,\n hash: string,\n dstDir: string,\n args: Arguments,\n spinner: Ora\n): Promise<void> {\n // Enable verbose degit logging if the --verbose flag is used\n const verbose = args.verbose\n\n // Set up degit (we will be writing to a temporary directory, so force is safe)\n const emitter = degit(`${templateTarget}${hash}`, {\n cache: false,\n force: true,\n verbose\n })\n\n try {\n if (verbose) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n emitter.on('info', (info: any) => {\n console.log(info.message)\n })\n }\n\n // Make degit write to a temporary directory\n const tmpDir = mkdtempSync(joinPath(tmpdir(), 'sde-create-'))\n await emitter.clone(tmpDir)\n\n // degit does not return an error when an invalid template is provided, as such we\n // need to handle this manually\n if (!existsSync(tmpDir) || readdirSync(tmpDir).length === 0) {\n throw new Error('The requested template failed to download')\n }\n\n // Copy files to destination without overwriting\n await copy(tmpDir, dstDir, {\n overwrite: false,\n errorOnExist: false\n })\n\n // Remove the temporary directory\n rmSync(tmpDir, { recursive: true, force: true })\n } catch (e) {\n spinner.fail()\n\n // degit is compiled, so the stacktrace is pretty noisy. Only report the stacktrace when using verbose mode.\n // logger.debug(err)\n console.error(red(e.message))\n\n // TODO: Handle common degit issues like below; for now, just log the error and exit\n console.error(yellow('There was a problem copying the template.'))\n console.error(\n yellow(\n 'Please file a new issue with the command output here: https://github.com/climateinteractive/sdeverywhere/issues'\n )\n )\n process.exit(0)\n\n // // Warning for issue #655 and other corrupted cache issue\n // if (e.message === 'zlib: unexpected end of file' || e.message === 'TAR_BAD_ARCHIVE: Unrecognized archive format') {\n // console.log(\n // yellow(\n // // 'Local degit cache seems to be corrupted.'\n // // 'For more information check out this issue: https://github.com/withastro/astro/issues/655.'\n // )\n // )\n // const cacheIssueResponse = await prompts({\n // type: 'confirm',\n // name: 'cache',\n // message: 'Would you like us to clear the cache and try again?',\n // initial: true\n // })\n // if (cacheIssueResponse.cache) {\n // const homeDirectory = os.homedir()\n // const cacheDir = joinPath(homeDirectory, '.degit', 'github', '@sdeverywhere')\n // rmSync(cacheDir, { recursive: true, force: true, maxRetries: 3 })\n // spinner = ora('Copying project files...').start()\n // try {\n // await emitter.clone(dstDir)\n // } catch (e) {\n // // logger.debug(e)\n // console.error(red(e.message))\n // }\n // } else {\n // console.log(\n // \"Okay, no worries! To fix this manually, remove the folder '~/.degit/github/withastro' and rerun the command.\"\n // )\n // }\n // }\n\n // // Helpful message when encountering the \"could not find commit hash for ...\" error\n // if (e.code === 'MISSING_REF') {\n // console.log(\n // yellow(\n // \"This seems to be an issue with degit. Please check if you have 'git' installed on your system, and if you don't, go here to install: https://git-scm.com\"\n // )\n // )\n // console.log(\n // yellow(\n // \"If you do have 'git' installed, please file a new issue with the command output here: https://github.com/climateinteractive/sdeverywhere/issues\"\n // )\n // )\n // }\n\n // process.exit(1)\n }\n}\n"],"mappings":"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","names":["relative","bold","cyan","green","ora","prompts","bold","cyan","dim","green","reset","yellow","ora","prompts","existsSync","resolvePath","bold","dim","green","ora","prompts","existsSync","joinPath","resolvePath","execa","bold","cyan","dim","green","red","ora","prompts","cyan","dim","green","reset","ora","prompts","writeFile","joinPath","relative","resolvePath","bold","cyan","dim","green","yellow","ora","prompts","existsSync","rmSync","writeFile","joinPath","dim","green","red","yellow","ora","prompts","prompts","bold","ora","green","relative","cyan"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/step-config.ts","../src/step-deps.ts","../src/step-directory.ts","../src/step-emsdk.ts","../src/step-git.ts","../src/step-mdl.ts","../src/step-template.ts"],"sourcesContent":["// Copyright (c) 2022 Climate Interactive / New Venture Fund\n\nimport { relative } from 'path'\n\nimport { bgCyan, black, bold, cyan, green } from 'kleur/colors'\nimport ora from 'ora'\nimport prompts from 'prompts'\nimport detectPackageManager from 'which-pm-runs'\nimport yargs from 'yargs-parser'\n\nimport { chooseGenConfig, generateCheckYaml, updateSdeConfig } from './step-config'\nimport { chooseInstallDeps } from './step-deps'\nimport { chooseProjectDir } from './step-directory'\nimport { chooseInstallEmsdk } from './step-emsdk'\nimport { chooseGitInit } from './step-git'\nimport { chooseMdlFile } from './step-mdl'\nimport { chooseTemplate } from './step-template'\n\nexport async function main(): Promise<void> {\n // Detect the package manager\n const pkgManager = detectPackageManager()?.name || 'npm'\n\n // Parse command line arguments\n const args = yargs(process.argv)\n prompts.override(args)\n\n // Display welcome message\n console.log(`\\n${bold('Welcome to SDEverywhere!')}`)\n console.log(`Let's create a new SDEverywhere project for your model.\\n`)\n\n // Prompt the user to select a project directory\n const projDir = await chooseProjectDir(args)\n console.log()\n\n // Prompt the user to select a template\n const templateName = await chooseTemplate(projDir, args, pkgManager)\n console.log()\n\n // Prompt the user to select an mdl file\n const mdlPath = await chooseMdlFile(projDir)\n\n // Update the `sde.config.js` file to use the chosen mdl file and\n // generate a sample `.check.yaml` file\n await updateSdeConfig(projDir, mdlPath)\n await generateCheckYaml(projDir, mdlPath)\n console.log()\n\n // If the user chose the default template, offer to set up CSV files\n if (templateName === 'template-default' && !args.dryRun) {\n await chooseGenConfig(projDir, mdlPath)\n console.log()\n }\n\n // Prompt the user to install Emscripten SDK\n await chooseInstallEmsdk(projDir, args)\n console.log()\n\n // Prompt the user to install dependencies\n await chooseInstallDeps(projDir, args, pkgManager)\n console.log()\n\n // Prompt the user to initialize a git repo\n await chooseGitInit(projDir, args)\n console.log()\n\n ora(green('Setup complete!')).succeed()\n\n console.log(`\\n${bgCyan(black(' Next steps '))}\\n`)\n\n const relProjDir = relative(process.cwd(), projDir)\n const devCmd = pkgManager === 'npm' ? 'npm run dev' : `${pkgManager} dev`\n\n // If the project dir is the current dir, no need to tell users to cd\n if (relProjDir !== '') {\n console.log(`You can now ${bold(cyan('cd'))} into the ${bold(cyan(relProjDir))} project directory.`)\n }\n console.log(`Run ${bold(cyan(devCmd))} to start the local dev server. ${bold(cyan('CTRL-C'))} to close.`)\n console.log('')\n}\n","// Copyright (c) 2022 Climate Interactive / New Venture Fund\n\nimport { existsSync } from 'fs'\nimport { mkdir, readFile, writeFile } from 'fs/promises'\nimport { dirname, join as joinPath, parse as parsePath, relative, resolve as resolvePath } from 'path'\n\nimport { bold, cyan, dim, green, reset, yellow } from 'kleur/colors'\nimport ora from 'ora'\nimport type { Choice } from 'prompts'\nimport prompts from 'prompts'\nimport yaml from 'yaml'\n\nimport { parseAndGenerate, preprocessModel } from '@sdeverywhere/compile'\n\ninterface MdlConstVariable {\n kind: 'const'\n name: string\n value: number\n}\n\ninterface MdlAuxVariable {\n kind: 'aux'\n name: string\n}\n\ninterface MdlLevelVariable {\n kind: 'level'\n name: string\n}\n\ntype MdlVariable = MdlConstVariable | MdlAuxVariable | MdlLevelVariable\n\nconst sampleCheckContent = `\\\n# yaml-language-server: $schema=SCHEMA_PATH\n\n# NOTE: This is just a simple check to get you started. Replace \"Some output\" with\n# the name of some variable you'd like to test. Additional tests can be developed\n# in the \"playground\" (beta) inside the model-check report.\n- describe: Some output\n tests:\n - it: should be > 0 for all input scenarios\n scenarios:\n - preset: matrix\n datasets:\n - name: Some output\n predicates:\n - gt: 0\n`\n\nexport async function updateSdeConfig(projDir: string, mdlPath: string): Promise<void> {\n // Read the `sde.config.js` file from the template\n const configPath = joinPath(projDir, 'sde.config.js')\n let configText = await readFile(configPath, 'utf8')\n\n // Replace instances of `MODEL_NAME.mdl` with the path to the chosen mdl file\n configText = configText.replaceAll('MODEL_NAME.mdl', mdlPath)\n\n // Write the updated file\n await writeFile(configPath, configText)\n}\n\nexport async function generateCheckYaml(projDir: string, mdlPath: string): Promise<void> {\n // Generate a sample `{mdl}.check.yaml` file if one doesn't already exist\n // TODO: Make this optional (ask user first)?\n const checkYamlFile = mdlPath.replace('.mdl', '.check.yaml')\n const checkYamlPath = joinPath(projDir, checkYamlFile)\n if (!existsSync(checkYamlPath)) {\n // Get relative path from yaml file parent dir to project dir\n let relProjPath = relative(dirname(checkYamlPath), projDir)\n if (relProjPath.length === 0) {\n relProjPath = './'\n }\n\n // TODO: This path is normally different depending on whether using npm/yarn or\n // pnpm. For npm/yarn, `check-core` is hoisted under top-level `node_modules`,\n // but for pnpm, it is nested under `node_modules/.pnpm`. As an ugly workaround\n // the templates declare `check-core` as a direct dependency even though it is\n // not really needed (a transitive dependency via `plugin-check` would normally\n // suffice). This allows us to use the same path here that works for all\n // three package managers.\n const nodeModulesPart = joinPath(relProjPath, 'node_modules')\n const checkCorePart = '@sdeverywhere/check-core/schema/check.schema.json'\n const schemaPath = `${nodeModulesPart}/${checkCorePart}`\n const checkContent = sampleCheckContent.replace('SCHEMA_PATH', schemaPath)\n await writeFile(checkYamlPath, checkContent)\n }\n}\n\nexport async function chooseGenConfig(projDir: string, mdlPath: string): Promise<void> {\n // TODO: For now we eagerly read the mdl file; maybe change this to only load it if\n // the user chooses to generate graph and/or slider config\n let mdlVars: MdlVariable[]\n try {\n // Get the list of variables available in the model\n mdlVars = await readModelVars(projDir, mdlPath)\n } catch (e) {\n console.log(e)\n ora(\n yellow('The mdl file failed to load. We will continue setting things up, and you can diagnose the issue later.')\n ).warn()\n return\n }\n\n // Extract `INITIAL TIME` and `FINAL TIME` values and remove special control variables from the list\n let initialTime: number\n let finalTime: number\n const validVars: MdlVariable[] = []\n for (const v of mdlVars) {\n const varName = v.name.toLowerCase()\n let skip = false\n switch (varName) {\n case 'final time':\n skip = true\n if (v.kind === 'const') {\n finalTime = v.value\n }\n break\n case 'initial time':\n skip = true\n if (v.kind === 'const') {\n initialTime = v.value\n }\n break\n case 'saveper':\n case 'time':\n case 'time step':\n skip = true\n break\n default:\n break\n }\n if (!skip) {\n validVars.push(v)\n }\n }\n\n // Set the values in `model.csv`\n if (initialTime === undefined) {\n initialTime = 0\n }\n if (finalTime === undefined) {\n finalTime = 100\n }\n\n // TODO: Auto-detect dat files that are referenced by the mdl and include them here\n const datFiles: string[] = []\n const datPart = datFiles.join(';')\n\n // Preserve the `model.csv` header but drop other existing content (if any)\n const modelCsvFile = joinPath(projDir, 'config', 'model.csv')\n const origModelCsvContent = await readFile(modelCsvFile, 'utf8')\n const modelCsvHeader = origModelCsvContent.split('\\n')[0]\n\n // Add line and write out updated `model.csv`\n const modelCsvLine = `${initialTime},${finalTime},${datPart}`\n const newModelCsvContent = `${modelCsvHeader}\\n${modelCsvLine}\\n`\n await writeFile(modelCsvFile, newModelCsvContent)\n\n // See if the user wants to generate graph config\n await chooseGenGraphConfig(projDir, validVars)\n console.log()\n\n // See if the user wants to generate slider config\n await chooseGenSliderConfig(projDir, validVars)\n}\n\nasync function chooseGenGraphConfig(projDir: string, mdlVars: MdlVariable[]): Promise<void> {\n // Prompt the user\n const genResponse = await prompts(\n {\n type: 'confirm',\n name: 'genGraph',\n message: `Would you like to configure a graph to get you started? ${reset(dim('(recommended)'))}`,\n initial: true\n },\n {\n onCancel: () => {\n ora().info(dim('Operation cancelled.'))\n process.exit(0)\n }\n }\n )\n\n // Handle response\n if (!genResponse.genGraph) {\n ora().info(dim(`No problem! You can edit the \"${cyan('config/graphs.csv')}\" file later.`))\n return\n }\n\n // Offer multi-select with available output variables\n const outputVarNames: string[] = []\n for (const mdlVar of mdlVars) {\n if (mdlVar.kind === 'aux' || mdlVar.kind === 'level') {\n outputVarNames.push(mdlVar.name)\n }\n }\n outputVarNames.sort((a, b) => {\n return a.toLowerCase().localeCompare(b.toLowerCase())\n })\n const choices = outputVarNames.map(f => {\n return {\n title: f,\n value: f\n } as Choice\n })\n const varsResponse = await prompts(\n {\n type: 'autocompleteMultiselect',\n name: 'vars',\n message: 'Choose up to three output variables to display in the graph',\n choices,\n max: 3\n },\n {\n onCancel: () => {\n ora().info(dim('Operation cancelled.'))\n process.exit(0)\n }\n }\n )\n\n if (varsResponse.vars.length === 0) {\n ora().info(dim(`No variables selected. You can edit the \"${cyan('config/graphs.csv')}\" file later.`))\n return\n }\n\n // Add line to `graphs.csv`\n const graphsCsvFile = joinPath(projDir, 'config', 'graphs.csv')\n const csvLine = graphsCsvLine(varsResponse.vars)\n let graphsCsvContent = await readFile(graphsCsvFile, 'utf8')\n graphsCsvContent += `${csvLine}\\n`\n await writeFile(graphsCsvFile, graphsCsvContent)\n\n ora(\n green(`Added graph to \"${bold('config/graphs.csv')}\". ${dim('You can configure graphs in that file later.')}`)\n ).succeed()\n}\n\n// TODO: Ideally the `plugin-config` package would expose an API for generating CSV, but\n// until then, we will generate a comma-separated line of values in hardcoded fashion\nfunction graphsCsvLine(outputVarNames: string[]): string {\n const colors = ['blue', 'red', 'green']\n\n // Fill the line with blanks initially, then set the small subset of fields\n const a = Array(131).fill('')\n // id\n a[0] = '1'\n // parent menu\n a[2] = 'Graphs'\n // graph title\n a[3] = 'Graph Title'\n // kind\n a[7] = 'line'\n // Plots start at 26\n let index = 26\n let colorIndex = 0\n for (const outputVarName of outputVarNames) {\n // Surround the name in quotes if it contains a comma\n const escapedName = escapeCsvField(outputVarName)\n // plot N variable\n a[index + 0] = escapedName\n // plot N style\n a[index + 2] = 'line'\n // plot N label\n a[index + 3] = escapedName\n // plot N color\n a[index + 4] = colors[colorIndex]\n index += 7\n colorIndex++\n }\n\n return a.join(',')\n}\n\nasync function chooseGenSliderConfig(projDir: string, mdlVars: MdlVariable[]): Promise<void> {\n // Prompt the user\n const genResponse = await prompts(\n {\n type: 'confirm',\n name: 'genSliders',\n message: `Would you like to configure a few sliders to get you started? ${reset(dim('(recommended)'))}`,\n initial: true\n },\n {\n onCancel: () => {\n ora().info(dim('Operation cancelled.'))\n process.exit(0)\n }\n }\n )\n\n // Handle response\n if (!genResponse.genSliders) {\n ora().info(dim(`No problem! You can edit the \"${cyan('config/inputs.csv')}\" file later.`))\n return\n }\n\n // Offer multi-select with available input variables\n const inputVarNames: string[] = []\n for (const mdlVar of mdlVars) {\n if (mdlVar.kind === 'const') {\n inputVarNames.push(mdlVar.name)\n }\n }\n inputVarNames.sort((a, b) => {\n return a.toLowerCase().localeCompare(b.toLowerCase())\n })\n const choices = inputVarNames.map(f => {\n return {\n title: f,\n value: f\n } as Choice\n })\n const varsResponse = await prompts(\n {\n type: 'autocompleteMultiselect',\n name: 'vars',\n message: 'Choose up to three input variables to control with sliders',\n choices,\n max: 3\n },\n {\n onCancel: () => {\n ora().info(dim('Operation cancelled.'))\n process.exit(0)\n }\n }\n )\n\n if (varsResponse.vars.length === 0) {\n ora().info(dim(`No variables selected. You can edit the \"${cyan('config/inputs.csv')}\" file later.`))\n return\n }\n\n // Add lines to `inputs.csv`\n const inputsCsvFile = joinPath(projDir, 'config', 'inputs.csv')\n let inputsCsvContent = await readFile(inputsCsvFile, 'utf8')\n let idNumber = 1\n for (const inputVarName of varsResponse.vars) {\n const inputVar = mdlVars.find(v => v.name === inputVarName)\n if (inputVar && inputVar.kind === 'const') {\n const defaultValue = inputVar.value\n const csvLine = inputsCsvLine(inputVarName, defaultValue, idNumber.toString())\n inputsCsvContent += `${csvLine}\\n`\n idNumber++\n }\n }\n await writeFile(inputsCsvFile, inputsCsvContent)\n\n const slidersText = varsResponse.vars.length > 1 ? 'sliders' : 'sliders'\n ora(\n green(\n `Added ${slidersText} to \"${bold('config/inputs.csv')}\". ${dim('You can configure sliders in that file later.')}`\n )\n ).succeed()\n}\n\n// TODO: Ideally the `plugin-config` package would expose an API for generating CSV, but\n// until then, we will generate a comma-separated line of values in hardcoded fashion\nfunction inputsCsvLine(inputVarName: string, defaultValue: number, id: string): string {\n // Surround the name in quotes if it contains a comma\n const escapedName = escapeCsvField(inputVarName)\n\n // TODO: Be smarter about automatically choosing min/max/step values\n const minValue = defaultValue - 1\n const maxValue = defaultValue + 1\n const step = 0.1\n\n // Fill the line with blanks initially, then set the small subset of fields\n const a = Array(28).fill('')\n // id\n a[0] = id\n // input type\n a[1] = 'slider'\n // viewid\n a[2] = 'view1'\n // varname\n a[3] = escapedName\n // label\n a[4] = escapedName\n // group name\n a[6] = 'Sliders'\n // slider min\n a[7] = minValue\n // slider max\n a[8] = maxValue\n // slider default\n a[9] = defaultValue\n // slider step\n a[10] = step\n // units\n a[11] = '(units)'\n\n return a.join(',')\n}\n\nfunction escapeCsvField(s: string): string {\n // Surround the value in quotes if it contains a comma\n // TODO: Escape double quotes as well\n return s.includes(',') ? `\"${s}\"` : s\n}\n\nasync function readModelVars(projDir: string, mdlPath: string): Promise<MdlVariable[]> {\n // TODO: This function contains a subset of the logic from `sde-generate.js` in\n // the `cli` package; should revisit\n // let { modelDirname, modelName, modelPathname } = modelPathProps(model)\n\n // Ensure the `build` directory exists (under the `sde-prep` directory)\n const buildDir = resolvePath(projDir, 'sde-prep', 'build')\n await mkdir(buildDir, { recursive: true })\n\n // Use an empty model spec; this will make SDE look at all variables in the mdl\n const spec = {}\n\n // Try parsing the mdl file to generate the list of variables\n // TODO: This depends on some `compile` package APIs that are not yet considered stable.\n // Ideally we'd use an API that does not write files but instead returns an in-memory\n // object in a specified format.\n\n // Read and preprocess the model\n const mdlFile = resolvePath(projDir, mdlPath)\n const preprocessed = preprocessModel(mdlFile, spec, 'genc', /*writeFiles=*/ false)\n\n // Parse the model and generate the variable list\n const mdlDir = dirname(mdlFile)\n const mdlName = parsePath(mdlFile).name\n await parseAndGenerate(preprocessed, spec, ['printVarList'], mdlDir, mdlName, buildDir)\n\n // Read `build/{mdl}_vars.yaml`\n // TODO: For now the printVarList code only outputs txt and yaml files; we'll use the\n // yaml file for now, but that means we have a dependency on the `yaml` package. Once\n // we change the `compile` package to output JSON, we'll need to change this code.\n const varsYamlFile = joinPath(buildDir, `${mdlName}_vars.yaml`)\n const varsYamlContent = await readFile(varsYamlFile, 'utf8')\n const varObjs = yaml.parse(varsYamlContent)\n\n // Create a simplified array of variables\n const mdlVars: MdlVariable[] = []\n for (const varObj of varObjs) {\n // Only include certain variables for now\n // TODO: Include \"data\" vars\n switch (varObj.varType) {\n case 'const':\n mdlVars.push({\n kind: 'const',\n name: varObj.modelLHS,\n value: Number.parseFloat(varObj.modelFormula)\n })\n break\n case 'aux':\n mdlVars.push({\n kind: 'aux',\n name: varObj.modelLHS\n })\n break\n case 'level':\n mdlVars.push({\n kind: 'level',\n name: varObj.modelLHS\n })\n break\n default:\n break\n }\n }\n\n return mdlVars\n}\n","// Copyright (c) 2022 Climate Interactive / New Venture Fund\n\nimport { execa } from 'execa'\nimport { bold, cyan, dim, green, reset, yellow } from 'kleur/colors'\nimport ora from 'ora'\nimport prompts from 'prompts'\nimport type { Arguments } from 'yargs-parser'\n\nexport async function chooseInstallDeps(projDir: string, args: Arguments, pkgManager: string): Promise<void> {\n // Prompt the user\n const installResponse = await prompts(\n {\n type: 'confirm',\n name: 'install',\n message: `Would you like to install ${pkgManager} dependencies? ${reset(dim('(recommended)'))}`,\n initial: true\n },\n {\n onCancel: () => {\n ora().info(\n dim('Operation cancelled. Your project folder has been created, but no dependencies have been installed.')\n )\n process.exit(0)\n }\n }\n )\n\n // Handle response\n if (args.dryRun) {\n ora().info(dim(`--dry-run enabled, skipping.`))\n return\n } else if (!installResponse.install) {\n ora().info(dim(`No problem! Remember to install dependencies after setup.`))\n return\n }\n\n // Install dependencies\n const installExec = execa(pkgManager, ['install'], { cwd: projDir })\n const installingPackagesMsg = 'Installing packages...'\n const installSpinner = ora(installingPackagesMsg).start()\n try {\n await new Promise<void>((resolve, reject) => {\n installExec.stdout?.on('data', function (data) {\n installSpinner.text = `${installingPackagesMsg}\\n${bold(`[${pkgManager}]`)} ${data}`\n })\n installExec.stderr?.on('data', function (data) {\n installSpinner.text = `${installingPackagesMsg}\\n${bold(`[${pkgManager}]`)} ${data}`\n })\n installExec.on('error', error => reject(error))\n installExec.on('close', code => {\n if (code !== 0) {\n reject(`Install failed (code=${code})`)\n } else {\n resolve()\n }\n })\n })\n installSpinner.text = green('Packages installed!')\n installSpinner.succeed()\n } catch (e) {\n installSpinner.text = yellow(\n `There was an error installing packages. Try running ${cyan(\n `${pkgManager} install`\n )} in your project directory later.`\n )\n installSpinner.warn()\n }\n}\n","// Copyright (c) 2022 Climate Interactive / New Venture Fund\n\nimport { existsSync } from 'fs'\nimport { resolve as resolvePath } from 'path'\n\nimport { bold, dim, green, red } from 'kleur/colors'\nimport ora from 'ora'\nimport prompts from 'prompts'\nimport type { Arguments } from 'yargs-parser'\n\nexport async function chooseProjectDir(args: Arguments): Promise<string> {\n /**\n * Return true if the given directory does not exist, or it does not contain important files\n * like `package.json`.\n */\n function isValidDir(dir: string): boolean {\n const packageJson = resolvePath(dir, 'package.json')\n const packagesDir = resolvePath(dir, 'packages')\n return !existsSync(dir) || (!existsSync(packageJson) && !existsSync(packagesDir))\n }\n\n const showValidDirMsg = (dir: string) => {\n ora(green(`Using \"${bold(dir)}\" as the project directory.`)).succeed()\n }\n\n const showInvalidDirMsg = (dir: string) => {\n ora(red(`\"${bold(dir)}\" contains existing 'package.json' and/or 'packages' directory, stopping.`)).fail()\n }\n\n // See if project directory is provided on command line\n let projDir = args['_'][2] as string\n if (projDir) {\n // Directory was provided, see if it is valid\n if (isValidDir(projDir)) {\n // The provided directory is valid, so proceed\n showValidDirMsg(projDir)\n } else {\n // The provided directory is not valid, so show error message and exit\n showInvalidDirMsg(projDir)\n process.exit(0)\n }\n } else {\n // Directory was not provided, so prompt the user\n const dirResponse = await prompts(\n {\n type: 'text',\n name: 'directory',\n message: 'Where would you like to create your new project?',\n initial: '<current directory>'\n // validate(value) {\n // if (value === '<current directory>') {\n // value = process.cwd()\n // }\n // if (!isValidDir(value)) {\n // return notValidMsg(value)\n // }\n // return true\n // }\n },\n {\n onCancel: () => {\n ora().info(dim('Operation cancelled.'))\n process.exit(0)\n }\n }\n )\n projDir = dirResponse.directory\n if (projDir === '<current directory>') {\n projDir = process.cwd()\n }\n if (isValidDir(projDir)) {\n showValidDirMsg(projDir)\n } else {\n showInvalidDirMsg(projDir)\n process.exit(0)\n }\n }\n\n return projDir\n}\n","// Copyright (c) 2022 Climate Interactive / New Venture Fund\n\nimport { existsSync, rmSync } from 'fs'\nimport { join as joinPath, resolve as resolvePath } from 'path'\n\nimport { execa } from 'execa'\nimport { bold, cyan, dim, green, red } from 'kleur/colors'\nimport ora from 'ora'\nimport prompts from 'prompts'\nimport type { Arguments } from 'yargs-parser'\n\n// TODO: Make this configurable; we're using this older version for now because it is\n// relatively stable and has been used to build En-ROADS and C-ROADS for a long time\nconst version = '2.0.34'\n\nexport async function chooseInstallEmsdk(projDir: string, args: Arguments): Promise<void> {\n // TODO: Use findUp and skip this step if emsdk directory already exists\n\n // Prompt the user\n const underParentDir = resolvePath(projDir, '..', 'emsdk')\n const underProjDir = joinPath(projDir, 'emsdk')\n const installResponse = await prompts(\n {\n type: 'select',\n name: 'install',\n message: `Would you like to install the Emscripten SDK?`,\n choices: [\n // ${reset(dim('(recommended)'))\n {\n title: `Install under parent directory (${bold(underParentDir)})`,\n description: 'This is recommended so that it can be shared by multiple projects',\n value: 'parent'\n },\n {\n title: `Install under project directory (${bold(underProjDir)})\"`,\n description: 'This is useful for keeping everything under a single project directory',\n value: 'project'\n },\n {\n title: `Don't install`,\n description: `It's OK, you can install it later`,\n value: 'skip'\n }\n ]\n },\n {\n onCancel: () => {\n ora().info(\n dim(\n 'Operation cancelled. Your project folder has been created, but the Emscripten SDK and other dependencies have not been installed.'\n )\n )\n process.exit(0)\n }\n }\n )\n\n // Handle response\n if (args.dryRun) {\n ora().info(dim(`--dry-run enabled, skipping.`))\n return\n } else if (installResponse.install === 'skip') {\n ora().info(\n dim(\n `No problem! Be sure to install the Emscripten SDK and configure it in \"${cyan('sde.config.js')}\" after setup.`\n )\n )\n return\n }\n\n const installDir = installResponse.install === 'parent' ? underParentDir : underProjDir\n try {\n // TODO: Use spinner here\n await installEmscripten(installDir)\n } catch (e) {\n ora(red(`Failed to install Emscripten SDK: ${e.message}`)).fail()\n process.exit(0)\n }\n\n ora(green(`Installed the Emscripten SDK in \"${bold(installDir)}\"`)).succeed()\n}\n\n/**\n * Install the Emscripten SDK to the `emsdk` directory under the\n * given directory (if `emsdk` is not already present), then\n * activates the requested version (specified with `version`).\n *\n * The implementation is similar to the existing `setup-emsdk` action\n * (https://github.com/mymindstorm/setup-emsdk) except that one has issues\n * with the cache directory on Windows, so having our own script gives us\n * more control over installation and caching behavior.\n */\nasync function installEmscripten(emsdkDir: string /*, options?: { verbose?: boolean }*/): Promise<void> {\n // Only download if the emsdk directory wasn't restored from a cache\n if (!existsSync(emsdkDir)) {\n console.log(`Downloading Emscripten SDK to ${emsdkDir}`)\n // console.log()\n await execa('git', ['clone', 'https://github.com/emscripten-core/emsdk.git', emsdkDir])\n } else {\n console.log(`Found existing Emscripten SDK directory: ${emsdkDir}`)\n }\n // console.log()\n\n if (process.env.CI) {\n // On GitHub Actions, remove the `.git` directory to keep the cache smaller.\n // When we update to a new version, the cache key will miss and the emsdk\n // repo will be redownloaded.\n console.log('CI detected, removing .git directory...')\n const gitDir = joinPath(emsdkDir, '.git')\n rmSync(gitDir, { recursive: true, force: true })\n } else {\n // For local development, pull to get the latest\n console.log('Local development detected, performing git pull...')\n await execa('git', ['pull'], { cwd: emsdkDir })\n // console.log()\n }\n\n const emsdkCmd = async (...args: string[]) => {\n return execa('python3', ['emsdk.py', ...args], { cwd: emsdkDir })\n }\n\n console.log(`Activating Emscripten SDK ${version}...`)\n await emsdkCmd('install', version)\n await emsdkCmd('activate', version)\n}\n","// Copyright (c) 2022 Climate Interactive / New Venture Fund\n\nimport { execaCommand } from 'execa'\nimport { cyan, dim, green, reset, yellow } from 'kleur/colors'\nimport ora from 'ora'\nimport prompts from 'prompts'\nimport type { Arguments } from 'yargs-parser'\n\nexport async function chooseGitInit(projDir: string, args: Arguments): Promise<void> {\n // Prompt the user\n const gitResponse = await prompts(\n {\n type: 'confirm',\n name: 'git',\n message: `Would you like to initialize a new git repository? ${reset(dim('(optional)'))}`,\n initial: true\n },\n {\n onCancel: () => {\n ora().info(dim('Operation cancelled. Your project folder has already been created.'))\n process.exit(0)\n }\n }\n )\n\n // Handle response\n if (args.dryRun) {\n ora().info(dim(`--dry-run enabled, skipping.`))\n return\n } else if (!gitResponse.git) {\n ora().info(dim(`No problem! You can come back and run ${cyan(`git init`)} later.`))\n return\n }\n\n // Init git repo\n try {\n await execaCommand('git init', { cwd: projDir })\n ora().succeed(green('Git repository initialized!'))\n } catch (e) {\n ora().warn(\n yellow(\n `There was a problem initializing the Git repository, but no problem, you can run ${cyan(`git init`)} later.`\n )\n )\n }\n}\n","// Copyright (c) 2022 Climate Interactive / New Venture Fund\n\nimport { readdir, writeFile } from 'fs/promises'\nimport { join as joinPath, relative, resolve as resolvePath } from 'path'\n\nimport { bold, cyan, dim, green, yellow } from 'kleur/colors'\nimport ora from 'ora'\nimport type { Choice } from 'prompts'\nimport prompts from 'prompts'\n\nconst sampleMdlContent = `\\\n{UTF-8}\n\nX = TIME\n ~~|\n\nY = 0\n ~ [-10,10,0.1]\n ~\n |\n\nZ = X + Y\n ~~|\n\nINITIAL TIME = 2000 ~~|\nFINAL TIME = 2100 ~~|\nTIME STEP = 1 ~~|\nSAVEPER = TIME STEP ~~|\n`\n\nexport async function chooseMdlFile(projDir: string): Promise<string> {\n // Find all `.mdl` files in the project directory\n // From https://stackoverflow.com/a/45130990\n async function getFiles(dir: string): Promise<string[]> {\n const dirents = await readdir(dir, { withFileTypes: true })\n const files = await Promise.all(\n dirents.map(dirent => {\n const res = resolvePath(dir, dirent.name)\n return dirent.isDirectory() ? getFiles(res) : res\n })\n )\n return files.flat()\n }\n const allFiles = await getFiles(projDir)\n const mdlFiles = allFiles.filter(f => f.endsWith('.mdl')).map(f => relative(projDir, f))\n const mdlChoices = mdlFiles.map(f => {\n return {\n title: f,\n value: f\n } as Choice\n })\n\n let mdlFile: string\n if (mdlFiles.length === 0) {\n // No mdl files found; write a sample mdl to get the user started\n const sampleMdlFile = joinPath(projDir, 'sample.mdl')\n await writeFile(sampleMdlFile, sampleMdlContent)\n ora(\n yellow(\n `No mdl files were found in \"${projDir}\". A \"${cyan(\n 'sample.mdl'\n )}\" file has been added to the project to get you started.`\n )\n ).warn()\n mdlFile = 'sample.mdl'\n } else if (mdlFiles.length === 1) {\n // Only one mdl file\n ora().succeed(`Found \"${mdlFiles[0]}\", will configure the project to use that mdl file.`)\n mdlFile = mdlFiles[0]\n } else {\n // Multiple mdl files found; allow the user to choose one\n // TODO: Eventually we should allow the user to choose to flatten if there are multiple submodels\n const options = await prompts(\n [\n {\n type: 'select',\n name: 'mdlFile',\n message: 'It looks like there are multiple mdl files. Which one would you like to use?',\n choices: mdlChoices\n }\n ],\n {\n onCancel: () => {\n ora().info(dim('Operation cancelled.'))\n process.exit(0)\n }\n }\n )\n mdlFile = options.mdlFile\n }\n\n ora(green(`Using \"${bold(mdlFile)}\" as the model for the project.`)).succeed()\n\n return mdlFile\n}\n","// Copyright (c) 2022 Climate Interactive / New Venture Fund\n\nimport { existsSync, mkdtempSync, readdirSync, rmSync } from 'fs'\nimport { writeFile } from 'fs/promises'\nimport { copy } from 'fs-extra'\nimport { tmpdir } from 'os'\nimport { join as joinPath } from 'path'\n\nimport { downloadTemplate } from 'giget'\nimport { dim, green, red, yellow } from 'kleur/colors'\nimport type { Ora } from 'ora'\nimport ora from 'ora'\nimport prompts from 'prompts'\nimport type { Arguments } from 'yargs-parser'\n\nconst TEMPLATES = [\n {\n title: 'Default project',\n description: 'Includes recommended structure with config files, app, core library, model-check, etc',\n value: 'template-default'\n },\n {\n title: 'Minimal project',\n description: 'Includes simple config for model-check',\n value: 'template-minimal'\n }\n]\n\nexport async function chooseTemplate(projDir: string, args: Arguments, pkgManager: string): Promise<string> {\n // Prompt the user\n const options = await prompts(\n [\n {\n type: 'select',\n name: 'template',\n message: 'Which template would you like to use?',\n choices: TEMPLATES\n }\n ],\n {\n onCancel: () => {\n ora().info(dim('Operation cancelled.'))\n process.exit(0)\n }\n }\n )\n\n // Handle response\n if (args.dryRun) {\n ora().info(dim(`--dry-run enabled, skipping.`))\n return\n }\n\n // Allow branch name or commit hash to be overridden on command line\n const defaultRev = 'main'\n const commit = args.commit || defaultRev\n\n // Copy the template files to the project directory\n const templateTarget = `climateinteractive/SDEverywhere/examples/${options.template}#${commit}`\n const templateSpinner = ora('Copying project files...').start()\n await copyTemplate(templateTarget, projDir, templateSpinner)\n templateSpinner.text = green('Template copied!')\n templateSpinner.succeed()\n\n if (options.template === 'template-default' && pkgManager === 'pnpm') {\n // pnpm doesn't use the \"workspaces\" config from `package.json` (like npm and yarn use),\n // so in the case of pnpm, write a `pnpm-workspace.yaml` file so that the default\n // template monorepo layout is set up correctly\n const workspaceFile = joinPath(projDir, 'pnpm-workspace.yaml')\n const workspaceContent = `packages:\\n - packages/*\\n`\n await writeFile(workspaceFile, workspaceContent)\n }\n\n return options.template\n}\n\nasync function copyTemplate(templateTarget: string, dstDir: string, spinner: Ora): Promise<void> {\n try {\n // Make giget write to a temporary directory\n const tmpDir = mkdtempSync(joinPath(tmpdir(), 'sde-create-'))\n\n // Use giget to download the template (we will be writing to a temporary directory,\n // so `force` is safe)\n await downloadTemplate(`github:${templateTarget}`, {\n force: true,\n provider: 'github',\n dir: tmpDir\n })\n\n // In case giget doesn't return an error when an invalid template is provided, check\n // that the temporary directory is non-empty\n if (!existsSync(tmpDir) || readdirSync(tmpDir).length === 0) {\n throw new Error('Failed to download the requested template: the temporary directory is empty.')\n }\n\n // Copy files to destination without overwriting\n await copy(tmpDir, dstDir, {\n overwrite: false,\n errorOnExist: false\n })\n\n // Remove the temporary directory\n rmSync(tmpDir, { recursive: true, force: true })\n } catch (e) {\n // The download failed; show an error message\n // TODO: Handle common download issues; for now, just log the error message and exit\n spinner.fail()\n console.error(red(e.message))\n console.error(yellow('\\nThere was a problem copying the template.'))\n console.error(\n yellow(\n 'Please start a new discussion thread and include the command output so that we can help:\\n https://github.com/climateinteractive/SDEverywhere/discussions/categories/q-a\\n'\n )\n )\n process.exit(0)\n }\n}\n"],"mappings":"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","names":["relative","bold","cyan","green","ora","prompts","bold","cyan","dim","green","reset","yellow","ora","prompts","existsSync","resolvePath","bold","dim","green","ora","prompts","existsSync","joinPath","resolvePath","execa","bold","cyan","dim","green","red","ora","prompts","cyan","dim","green","reset","yellow","ora","prompts","writeFile","joinPath","relative","resolvePath","bold","cyan","dim","green","yellow","ora","prompts","existsSync","rmSync","writeFile","joinPath","dim","green","red","yellow","ora","prompts","prompts","bold","ora","green","relative","cyan"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sdeverywhere/create",
3
- "version": "0.2.12",
3
+ "version": "0.2.14",
4
4
  "description": "Create a new SDEverywhere project with minimal configuration",
5
5
  "type": "module",
6
6
  "files": [
@@ -11,10 +11,10 @@
11
11
  "create-sde": "bin/create-sde.js"
12
12
  },
13
13
  "dependencies": {
14
- "@sdeverywhere/compile": "^0.7.15",
15
- "degit": "^2.8.4",
14
+ "@sdeverywhere/compile": "^0.7.17",
16
15
  "execa": "^6.1.0",
17
16
  "fs-extra": "^10.1.0",
17
+ "giget": "^1.2.3",
18
18
  "kleur": "^4.1.5",
19
19
  "ora": "^6.1.2",
20
20
  "prompts": "^2.4.2",
@@ -23,7 +23,6 @@
23
23
  "yargs-parser": "^21.1.1"
24
24
  },
25
25
  "devDependencies": {
26
- "@types/degit": "^2.8.3",
27
26
  "@types/fs-extra": "^9.0.13",
28
27
  "@types/node": "^20.5.7",
29
28
  "@types/prompts": "^2.0.14",