@sdeverywhere/create 0.2.2 → 0.2.3

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/README.md CHANGED
@@ -1,20 +1,42 @@
1
1
  # @sdeverywhere/create
2
2
 
3
- Create a new SDEverywhere project with minimal configuration.
3
+ Create a new [SDEverywhere](https://github.com/climateinteractive/SDEverywhere) project with minimal configuration.
4
4
 
5
5
  ## Quick Start
6
6
 
7
+ The quickest way to get started with SDEverywhere is to open your terminal emulator ("Terminal" on macOS or Linux, or "Command Prompt" on Windows) and type the following commands.
8
+
9
+ If you already have a directory containing a Vensim `mdl` file, change to that directory first.
10
+ (The script will generate some new files in that directory, so if you would prefer, feel free to create a fresh directory that includes just your `mdl` file.)
11
+
7
12
  ```sh
8
- # with npm
9
- npm create @sdeverywhere
13
+ # Change to the directory containing your `mdl` file:
14
+ cd my-project-folder
15
+ ```
10
16
 
11
- # with pnpm
12
- pnpm create @sdeverywhere
17
+ Or, if you don't already have a Vensim `mdl` file, and/or you want to evaluate SDEverywhere for the first time, you can create an empty directory, and the script will add a sample model to get you started:
18
+
19
+ ```sh
20
+ # Create an empty directory and change to that directory:
21
+ mkdir my-project-folder
22
+ cd my-project-folder
23
+ ```
13
24
 
14
- # with yarn
25
+ Once you are in the correct folder, run the `create` script:
26
+
27
+ ```sh
28
+ # Use `npm` to run the "create" script:
29
+ npm create @sdeverywhere@latest
30
+
31
+ # Or, if you use pnpm:
32
+ pnpm create @sdeverywhere@latest
33
+
34
+ # Or, if you use Yarn:
15
35
  yarn create @sdeverywhere
16
36
  ```
17
37
 
38
+ Answer a few questions, and within minutes you can have a functional web application that runs your model!
39
+
18
40
  ## License
19
41
 
20
42
  SDEverywhere is distributed under the MIT license. See `LICENSE` for more details.
package/dist/index.cjs CHANGED
@@ -17,6 +17,10 @@ var __copyProps = (to, from, except, desc) => {
17
17
  return to;
18
18
  };
19
19
  var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
+ // If the importer is in node compatibility mode or this is not an ESM
21
+ // file that has been converted to a CommonJS file using a Babel-
22
+ // compatible transform (i.e. "__esModule" has not been set), then set
23
+ // "default" to the CommonJS "module.exports" for node compatibility.
20
24
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
21
25
  mod
22
26
  ));
@@ -326,7 +330,13 @@ async function readModelVars(projDir, mdlPath) {
326
330
  await (0, import_promises.mkdir)(buildDir, { recursive: true });
327
331
  const spec = {};
328
332
  const mdlFile = (0, import_path.resolve)(projDir, mdlPath);
329
- const preprocessed = (0, import_compile.preprocessModel)(mdlFile, spec, "genc", false);
333
+ const preprocessed = (0, import_compile.preprocessModel)(
334
+ mdlFile,
335
+ spec,
336
+ "genc",
337
+ /*writeFiles=*/
338
+ false
339
+ );
330
340
  const mdlDir = (0, import_path.dirname)(mdlFile);
331
341
  const mdlName = (0, import_path.parse)(mdlFile).name;
332
342
  await (0, import_compile.parseAndGenerate)(preprocessed, spec, "printVarList", mdlDir, mdlName, buildDir);
@@ -396,12 +406,11 @@ async function chooseInstallDeps(projDir, args, pkgManager) {
396
406
  const installSpinner = (0, import_ora2.default)(installingPackagesMsg).start();
397
407
  try {
398
408
  await new Promise((resolve, reject) => {
399
- var _a, _b;
400
- (_a = installExec.stdout) == null ? void 0 : _a.on("data", function(data) {
409
+ installExec.stdout?.on("data", function(data) {
401
410
  installSpinner.text = `${installingPackagesMsg}
402
411
  ${(0, import_colors2.bold)(`[${pkgManager}]`)} ${data}`;
403
412
  });
404
- (_b = installExec.stderr) == null ? void 0 : _b.on("data", function(data) {
413
+ installExec.stderr?.on("data", function(data) {
405
414
  installSpinner.text = `${installingPackagesMsg}
406
415
  ${(0, import_colors2.bold)(`[${pkgManager}]`)} ${data}`;
407
416
  });
@@ -459,6 +468,15 @@ async function chooseProjectDir(args) {
459
468
  name: "directory",
460
469
  message: "Where would you like to create your new project?",
461
470
  initial: "<current directory>"
471
+ // validate(value) {
472
+ // if (value === '<current directory>') {
473
+ // value = process.cwd()
474
+ // }
475
+ // if (!isValidDir(value)) {
476
+ // return notValidMsg(value)
477
+ // }
478
+ // return true
479
+ // }
462
480
  },
463
481
  {
464
482
  onCancel: () => {
@@ -498,6 +516,7 @@ async function chooseInstallEmsdk(projDir, args) {
498
516
  name: "install",
499
517
  message: `Would you like to install the Emscripten SDK?`,
500
518
  choices: [
519
+ // ${reset(dim('(recommended)'))
501
520
  {
502
521
  title: `Install under parent directory (${(0, import_colors4.bold)(underParentDir)})`,
503
522
  description: "This is recommended so that it can be shared by multiple projects",
@@ -779,8 +798,7 @@ async function runDegit(templateTarget, hash, dstDir, args, spinner) {
779
798
 
780
799
  // src/index.ts
781
800
  async function main() {
782
- var _a;
783
- const pkgManager = ((_a = (0, import_which_pm_runs.default)()) == null ? void 0 : _a.name) || "npm";
801
+ const pkgManager = (0, import_which_pm_runs.default)()?.name || "npm";
784
802
  const args = (0, import_yargs_parser.default)(process.argv);
785
803
  import_prompts8.default.override(args);
786
804
  console.log(`
@@ -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 } 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"]}
@@ -0,0 +1,3 @@
1
+ declare function main(): Promise<void>;
2
+
3
+ export { main };
package/dist/index.js CHANGED
@@ -297,7 +297,13 @@ async function readModelVars(projDir, mdlPath) {
297
297
  await mkdir(buildDir, { recursive: true });
298
298
  const spec = {};
299
299
  const mdlFile = resolvePath(projDir, mdlPath);
300
- const preprocessed = preprocessModel(mdlFile, spec, "genc", false);
300
+ const preprocessed = preprocessModel(
301
+ mdlFile,
302
+ spec,
303
+ "genc",
304
+ /*writeFiles=*/
305
+ false
306
+ );
301
307
  const mdlDir = dirname(mdlFile);
302
308
  const mdlName = parsePath(mdlFile).name;
303
309
  await parseAndGenerate(preprocessed, spec, "printVarList", mdlDir, mdlName, buildDir);
@@ -367,12 +373,11 @@ async function chooseInstallDeps(projDir, args, pkgManager) {
367
373
  const installSpinner = ora2(installingPackagesMsg).start();
368
374
  try {
369
375
  await new Promise((resolve, reject) => {
370
- var _a, _b;
371
- (_a = installExec.stdout) == null ? void 0 : _a.on("data", function(data) {
376
+ installExec.stdout?.on("data", function(data) {
372
377
  installSpinner.text = `${installingPackagesMsg}
373
378
  ${bold2(`[${pkgManager}]`)} ${data}`;
374
379
  });
375
- (_b = installExec.stderr) == null ? void 0 : _b.on("data", function(data) {
380
+ installExec.stderr?.on("data", function(data) {
376
381
  installSpinner.text = `${installingPackagesMsg}
377
382
  ${bold2(`[${pkgManager}]`)} ${data}`;
378
383
  });
@@ -430,6 +435,15 @@ async function chooseProjectDir(args) {
430
435
  name: "directory",
431
436
  message: "Where would you like to create your new project?",
432
437
  initial: "<current directory>"
438
+ // validate(value) {
439
+ // if (value === '<current directory>') {
440
+ // value = process.cwd()
441
+ // }
442
+ // if (!isValidDir(value)) {
443
+ // return notValidMsg(value)
444
+ // }
445
+ // return true
446
+ // }
433
447
  },
434
448
  {
435
449
  onCancel: () => {
@@ -469,6 +483,7 @@ async function chooseInstallEmsdk(projDir, args) {
469
483
  name: "install",
470
484
  message: `Would you like to install the Emscripten SDK?`,
471
485
  choices: [
486
+ // ${reset(dim('(recommended)'))
472
487
  {
473
488
  title: `Install under parent directory (${bold4(underParentDir)})`,
474
489
  description: "This is recommended so that it can be shared by multiple projects",
@@ -750,8 +765,7 @@ async function runDegit(templateTarget, hash, dstDir, args, spinner) {
750
765
 
751
766
  // src/index.ts
752
767
  async function main() {
753
- var _a;
754
- const pkgManager = ((_a = detectPackageManager()) == null ? void 0 : _a.name) || "npm";
768
+ const pkgManager = detectPackageManager()?.name || "npm";
755
769
  const args = yargs(process.argv);
756
770
  prompts8.override(args);
757
771
  console.log(`
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 } 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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sdeverywhere/create",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "Create a new SDEverywhere project with minimal configuration",
5
5
  "type": "module",
6
6
  "files": [
@@ -11,7 +11,7 @@
11
11
  "create-sde": "bin/create-sde.js"
12
12
  },
13
13
  "dependencies": {
14
- "@sdeverywhere/compile": "^0.7.5",
14
+ "@sdeverywhere/compile": "^0.7.6",
15
15
  "degit": "^2.8.4",
16
16
  "execa": "^6.1.0",
17
17
  "fs-extra": "^10.1.0",
@@ -19,13 +19,13 @@
19
19
  "ora": "^6.1.2",
20
20
  "prompts": "^2.4.2",
21
21
  "which-pm-runs": "^1.1.0",
22
- "yaml": "^2.1.1",
22
+ "yaml": "^2.2.2",
23
23
  "yargs-parser": "^21.1.1"
24
24
  },
25
25
  "devDependencies": {
26
26
  "@types/degit": "^2.8.3",
27
27
  "@types/fs-extra": "^9.0.13",
28
- "@types/node": "^16.11.7",
28
+ "@types/node": "^20.5.7",
29
29
  "@types/prompts": "^2.0.14",
30
30
  "@types/which-pm-runs": "^1.0.0",
31
31
  "@types/yargs-parser": "^21.0.0"