@jsenv/cli 0.0.3 → 0.0.6

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.
Files changed (90) hide show
  1. package/README.md +7 -0
  2. package/jsenv_cli.js +358 -0
  3. package/package.json +7 -5
  4. package/template-node-package/.eslintignore +2 -0
  5. package/template-node-package/.eslintrc.cjs +102 -0
  6. package/template-node-package/.jsenv/jsenv_tests_output.txt +8 -0
  7. package/template-node-package/.prettierrc.yml +2 -0
  8. package/template-node-package/package.json +23 -0
  9. package/template-node-package/scripts/test.mjs +25 -0
  10. package/template-node-package/src/main.js +8 -0
  11. package/template-node-package/src/message.js +11 -0
  12. package/template-node-package/tests/message.test.mjs +21 -0
  13. package/template-web/.eslintignore +3 -0
  14. package/template-web/.eslintrc.cjs +138 -0
  15. package/template-web/.prettierrc.yml +2 -0
  16. package/template-web/babel.config.cjs +3 -0
  17. package/template-web/package.json +33 -0
  18. package/template-web/scripts/build.mjs +21 -0
  19. package/template-web/scripts/build_serve.mjs +16 -0
  20. package/template-web/scripts/dev.mjs +15 -0
  21. package/template-web/scripts/test.mjs +29 -0
  22. package/template-web/src/app/animals.js +11 -0
  23. package/template-web/src/app/counter.js +11 -0
  24. package/template-web/src/index.html +27 -0
  25. package/template-web/src/jsenv_logo.svg +140 -0
  26. package/template-web/src/main.css +4 -0
  27. package/template-web/src/main.js +31 -0
  28. package/template-web/src/tests/animals.test.html +32 -0
  29. package/template-web/src/tests/app.test.mjs +26 -0
  30. package/template-web-components/.eslintignore +3 -0
  31. package/template-web-components/.eslintrc.cjs +138 -0
  32. package/template-web-components/.prettierrc.yml +2 -0
  33. package/template-web-components/babel.config.cjs +3 -0
  34. package/template-web-components/package.json +35 -0
  35. package/template-web-components/scripts/build.mjs +21 -0
  36. package/template-web-components/scripts/build_serve.mjs +16 -0
  37. package/template-web-components/scripts/dev.mjs +15 -0
  38. package/template-web-components/scripts/test.mjs +29 -0
  39. package/template-web-components/src/app/animals.js +11 -0
  40. package/template-web-components/src/app/app_custom_element.css +4 -0
  41. package/template-web-components/src/app/app_custom_element.js +31 -0
  42. package/template-web-components/src/app/counter.js +11 -0
  43. package/template-web-components/src/app/custom_elements_redefine.js +5 -0
  44. package/template-web-components/src/index.html +27 -0
  45. package/template-web-components/src/jsenv_logo.svg +140 -0
  46. package/template-web-components/src/main.js +11 -0
  47. package/template-web-components/src/tests/animals.test.html +32 -0
  48. package/template-web-components/src/tests/app.test.mjs +26 -0
  49. package/template-web-preact/.eslintignore +3 -0
  50. package/template-web-preact/.eslintrc.cjs +175 -0
  51. package/template-web-preact/.prettierrc.yml +2 -0
  52. package/template-web-preact/babel.config.cjs +11 -0
  53. package/template-web-preact/package.json +40 -0
  54. package/template-web-preact/scripts/build.mjs +23 -0
  55. package/template-web-preact/scripts/build_serve.mjs +16 -0
  56. package/template-web-preact/scripts/dev.mjs +21 -0
  57. package/template-web-preact/scripts/test.mjs +28 -0
  58. package/template-web-preact/src/app/animals.js +11 -0
  59. package/template-web-preact/src/app/app.css +42 -0
  60. package/template-web-preact/src/app/app.jsx +52 -0
  61. package/template-web-preact/src/app/counter.jsx +20 -0
  62. package/template-web-preact/src/index.html +28 -0
  63. package/template-web-preact/src/main.jsx +5 -0
  64. package/template-web-preact/src/preact_logo.svg +6 -0
  65. package/template-web-preact/src/tests/animals.test.html +32 -0
  66. package/template-web-preact/src/tests/app.test.mjs +26 -0
  67. package/template-web-react/.eslintignore +3 -0
  68. package/template-web-react/.eslintrc.cjs +175 -0
  69. package/template-web-react/.prettierrc.yml +2 -0
  70. package/template-web-react/babel.config.cjs +12 -0
  71. package/template-web-react/package.json +41 -0
  72. package/template-web-react/scripts/build.mjs +23 -0
  73. package/template-web-react/scripts/build_serve.mjs +16 -0
  74. package/template-web-react/scripts/dev.mjs +21 -0
  75. package/template-web-react/scripts/test.mjs +28 -0
  76. package/template-web-react/src/app/animals.js +11 -0
  77. package/template-web-react/src/app/app.css +42 -0
  78. package/template-web-react/src/app/app.jsx +55 -0
  79. package/template-web-react/src/app/counter.jsx +19 -0
  80. package/template-web-react/src/index.html +28 -0
  81. package/template-web-react/src/main.jsx +14 -0
  82. package/template-web-react/src/react_logo.svg +7 -0
  83. package/template-web-react/src/tests/animals.test.html +32 -0
  84. package/template-web-react/src/tests/app.test.mjs +26 -0
  85. package/src/command_build.mjs +0 -185
  86. package/src/command_dev.mjs +0 -38
  87. package/src/command_preview.mjs +0 -22
  88. package/src/command_test.mjs +0 -59
  89. package/src/jsenv_cli.mjs +0 -66
  90. package/src/package_installer.js +0 -122
package/README.md ADDED
@@ -0,0 +1,7 @@
1
+ # @jsenv/cli [![npm package](https://img.shields.io/npm/v/@jsenv/cli.svg?logo=npm&label=package)](https://www.npmjs.com/package/@jsenv/cli)
2
+
3
+ _@jsenv/cli_ is a NPM package meant to run via the command below:
4
+
5
+ ```console
6
+ npx @jsenv/cli
7
+ ```
package/jsenv_cli.js ADDED
@@ -0,0 +1,358 @@
1
+ #!/usr/bin/env node
2
+
3
+ // see https://docs.npmjs.com/cli/v8/commands/npm-init#description
4
+
5
+ import {
6
+ existsSync,
7
+ readdirSync,
8
+ mkdirSync,
9
+ statSync,
10
+ writeFileSync,
11
+ readFileSync,
12
+ } from "node:fs";
13
+ import { relative } from "node:path";
14
+ import { parseArgs } from "node:util";
15
+ import { pathToFileURL, fileURLToPath } from "node:url";
16
+ import { execSync } from "node:child_process";
17
+
18
+ import prompts from "prompts";
19
+ import { createTaskLog, UNICODE } from "@jsenv/humanize";
20
+ import { urlToRelativeUrl, ensurePathnameTrailingSlash } from "@jsenv/urls";
21
+
22
+ // not using readdir to control order
23
+ const availableTemplateNameArray = [
24
+ "web",
25
+ "web-components",
26
+ "web-react",
27
+ "web-preact",
28
+ "node-package",
29
+ ];
30
+ const options = {
31
+ help: {
32
+ type: "boolean",
33
+ },
34
+ web: {
35
+ type: "boolean",
36
+ },
37
+ ["web-components"]: {
38
+ type: "boolean",
39
+ },
40
+ ["web-react"]: {
41
+ type: "boolean",
42
+ },
43
+ ["web-preact"]: {
44
+ type: "boolean",
45
+ },
46
+ ["node-package"]: {
47
+ type: "boolean",
48
+ },
49
+ };
50
+ const { values, positionals } = parseArgs({
51
+ options,
52
+ allowPositionals: true,
53
+ });
54
+ if (values.help) {
55
+ console.log(`@jsenv/cli: Init jsenv in a directory.
56
+
57
+ Usage: npx @jsenv/cli <dir> [options]
58
+
59
+ https://github.com/jsenv/core/tree/main/packages/related/cli
60
+
61
+ <dir> Where to install jsenv files; Otherwise you'll be prompted to select.
62
+
63
+ Options:
64
+ --help Display this message.
65
+ --web Consider directory as "web" project; Otherwise you'll be prompted to select.
66
+ --web-components Consider directory as "web-components" project; Otherwise you'll be prompted to select.
67
+ --web-react Consider directory as "web-react" project; Otherwise you'll be prompted to select.
68
+ --web-preact Consider directory as "web-preact" project; Otherwise you'll be prompted to select.
69
+ --node-package Consider directory as "node-package" project; Otherwise you'll be prompted to select.
70
+ `);
71
+ process.exit(0);
72
+ }
73
+
74
+ console.log("Welcome in jsenv CLI");
75
+ const commands = [];
76
+ const cwdUrl = ensurePathnameTrailingSlash(pathToFileURL(process.cwd()));
77
+ let directoryUrl;
78
+ dir: {
79
+ const directoryPathFromArg = positionals[0];
80
+ if (directoryPathFromArg) {
81
+ directoryUrl = ensurePathnameTrailingSlash(
82
+ new URL(directoryPathFromArg, cwdUrl),
83
+ );
84
+ console.log(`${UNICODE.OK} Enter a directory: ${directoryPathFromArg}`);
85
+ break dir;
86
+ }
87
+ const result = await prompts(
88
+ {
89
+ type: "text",
90
+ name: "directory",
91
+ message: "Enter a directory:",
92
+ },
93
+ {
94
+ onCancel: () => {
95
+ console.log("Aborted, can be resumed any time");
96
+ process.exit(0);
97
+ },
98
+ },
99
+ );
100
+ directoryUrl = ensurePathnameTrailingSlash(new URL(result.directory, cwdUrl));
101
+ }
102
+ if (directoryUrl.href !== cwdUrl.href) {
103
+ const dir = relative(fileURLToPath(cwdUrl), fileURLToPath(directoryUrl));
104
+ commands.push({
105
+ label: `cd ${dir}`,
106
+ run: () => {
107
+ process.chdir(dir);
108
+ },
109
+ });
110
+ }
111
+ let templateName;
112
+ template: {
113
+ const templateNameFromArg = availableTemplateNameArray.find(
114
+ (availableTemplateName) => values[availableTemplateName],
115
+ );
116
+ if (templateNameFromArg) {
117
+ templateName = templateNameFromArg;
118
+ console.log(`${UNICODE.OK} Select a template: ${templateNameFromArg}`);
119
+ break template;
120
+ }
121
+ const result = await prompts(
122
+ [
123
+ {
124
+ type: "select",
125
+ name: "templateName",
126
+ message: "Select a template:",
127
+ initial: 0,
128
+ choices: availableTemplateNameArray.map((availableTemplateName) => {
129
+ return {
130
+ title: availableTemplateName,
131
+ value: availableTemplateName,
132
+ };
133
+ }),
134
+ },
135
+ ],
136
+ {
137
+ onCancel: () => {
138
+ console.log("Aborted, can be resumed any time");
139
+ process.exit(0);
140
+ },
141
+ },
142
+ );
143
+ templateName = result.templateName;
144
+ }
145
+
146
+ write_files: {
147
+ const writeFilesTask = createTaskLog(`init jsenv in "${directoryUrl}"`);
148
+ const mergeTwoIgnoreFileContents = (left, right) => {
149
+ const leftLines = String(left)
150
+ .split("\n")
151
+ .map((l) => l.trim());
152
+ const rightLines = String(right)
153
+ .split("\n")
154
+ .map((l) => l.trim());
155
+ let finalContent = left;
156
+ for (const rightLine of rightLines) {
157
+ if (!leftLines.includes(rightLine)) {
158
+ finalContent += "\n";
159
+ finalContent += rightLine;
160
+ }
161
+ }
162
+ return finalContent;
163
+ };
164
+ const overrideHandlers = {
165
+ "package.json": (existingContent, templateContent) => {
166
+ const existingPackage = JSON.parse(existingContent);
167
+ const templatePackage = JSON.parse(templateContent);
168
+ const override = (left, right, allowedKeys) => {
169
+ if (right === null) {
170
+ return left === undefined ? null : left;
171
+ }
172
+ if (Array.isArray(right)) {
173
+ if (Array.isArray(left)) {
174
+ for (const valueFromRight of right) {
175
+ if (!left.includes(valueFromRight)) {
176
+ left.push(valueFromRight);
177
+ }
178
+ }
179
+ return left;
180
+ }
181
+ return left === undefined ? right : left;
182
+ }
183
+ if (typeof right === "object") {
184
+ if (left && typeof left === "object") {
185
+ const keysToVisit = allowedKeys || Object.keys(right);
186
+ for (const keyToVisit of keysToVisit) {
187
+ const rightValue = right[keyToVisit];
188
+ if (rightValue === undefined) {
189
+ continue;
190
+ }
191
+ const leftValue = left[keyToVisit];
192
+ left[keyToVisit] = override(leftValue, rightValue);
193
+ }
194
+ return left;
195
+ }
196
+ return left === undefined ? right : left;
197
+ }
198
+ return left === undefined ? right : left;
199
+ };
200
+ const existingDependencies = existingPackage.dependencies
201
+ ? { ...existingPackage.dependencies }
202
+ : {};
203
+ const existingDevDependencies = existingPackage.devDependencies
204
+ ? { ...existingPackage.devDependencies }
205
+ : {};
206
+ override(existingPackage, templatePackage, [
207
+ "scripts",
208
+ "dependencies",
209
+ "devDependencies",
210
+ ]);
211
+ const finalDependencies = existingPackage.dependencies || {};
212
+ const finalDevDependencies = existingPackage.devDependencies || {};
213
+ if (
214
+ JSON.stringify(existingDependencies) !==
215
+ JSON.stringify(finalDependencies) ||
216
+ JSON.stringify(existingDevDependencies) !==
217
+ JSON.stringify(finalDevDependencies)
218
+ ) {
219
+ commands.push({
220
+ label: "npm install",
221
+ run: () => {
222
+ console.log("npm install");
223
+ execSync("npm install", {
224
+ stdio: [0, 1, 2],
225
+ });
226
+ },
227
+ });
228
+ }
229
+ if (existingContent.startsWith("{\n")) {
230
+ return JSON.stringify(existingPackage, null, " ");
231
+ }
232
+ return JSON.stringify(existingPackage);
233
+ },
234
+ ".gitignore": mergeTwoIgnoreFileContents,
235
+ ".eslintignore": mergeTwoIgnoreFileContents,
236
+ };
237
+ const templateSourceDirectoryUrl = new URL(
238
+ `./template-${templateName}/`,
239
+ import.meta.url,
240
+ );
241
+ const copyDirectoryContent = (fromDirectoryUrl, toDirectoryUrl) => {
242
+ if (!existsSync(toDirectoryUrl)) {
243
+ mkdirSync(toDirectoryUrl, { recursive: true });
244
+ }
245
+ const directoryEntryNameArray = readdirSync(fromDirectoryUrl);
246
+ for (const directoryEntryName of directoryEntryNameArray) {
247
+ if (
248
+ directoryEntryName === ".jsenv" ||
249
+ directoryEntryName === "dist" ||
250
+ directoryEntryName === "node_modules"
251
+ ) {
252
+ continue;
253
+ }
254
+ const fromUrl = new URL(directoryEntryName, fromDirectoryUrl);
255
+ const toUrl = new URL(
256
+ directoryEntryName === "_gitignore" ? ".gitignore" : directoryEntryName,
257
+ toDirectoryUrl,
258
+ );
259
+ const fromStat = statSync(fromUrl);
260
+ if (fromStat.isDirectory()) {
261
+ if (directoryEntryName === "src" || directoryEntryName === "tests") {
262
+ // copy src and tests if they don't exists
263
+ if (existsSync(toUrl)) {
264
+ continue;
265
+ }
266
+ // for web the presence of index.html or main.html at the root
267
+ // prevent src/ content from being copied
268
+ if (templateName.startsWith("web")) {
269
+ if (existsSync(new URL("./index.html", directoryUrl))) {
270
+ continue;
271
+ }
272
+ if (existsSync(new URL("./main.html", directoryUrl))) {
273
+ continue;
274
+ }
275
+ }
276
+ }
277
+ copyDirectoryContent(
278
+ ensurePathnameTrailingSlash(fromUrl),
279
+ ensurePathnameTrailingSlash(toUrl),
280
+ );
281
+ continue;
282
+ }
283
+ if (!existsSync(toUrl)) {
284
+ if (directoryEntryName === "package.json") {
285
+ commands.push({
286
+ label: "npm install",
287
+ run: () => {
288
+ console.log("npm install");
289
+ execSync("npm install", {
290
+ stdio: [0, 1, 2],
291
+ });
292
+ },
293
+ });
294
+ }
295
+ writeFileSync(toUrl, readFileSync(fromUrl));
296
+ continue;
297
+ }
298
+ const relativeUrl = urlToRelativeUrl(fromUrl, templateSourceDirectoryUrl);
299
+ const overrideHandler = overrideHandlers[relativeUrl];
300
+ if (!overrideHandler) {
301
+ // when there is no handler the file is kept as is
302
+ continue;
303
+ }
304
+ const existingContent = readFileSync(toUrl);
305
+ const templateContent = readFileSync(fromUrl);
306
+ const finalContent = overrideHandler(
307
+ String(existingContent),
308
+ String(templateContent),
309
+ );
310
+ writeFileSync(toUrl, finalContent);
311
+ }
312
+ };
313
+ copyDirectoryContent(
314
+ new URL(templateSourceDirectoryUrl),
315
+ new URL(directoryUrl),
316
+ );
317
+ writeFilesTask.done();
318
+ }
319
+
320
+ run_commands: {
321
+ if (commands.length === 0) {
322
+ break run_commands;
323
+ }
324
+ let message;
325
+ if (commands.length === 1) {
326
+ console.log(`----- 1 command to run -----
327
+ ${commands[0].label}
328
+ ---------------------------`);
329
+ // we can't run cd for the parent terminal
330
+ // so we'll just print the command in that case
331
+ // and user will have to run it if he want to go into the
332
+ // directory
333
+ if (commands[0].label.startsWith("cd")) {
334
+ console.log("Done, thank you");
335
+ process.exit(0);
336
+ }
337
+ message = "Can we run the command";
338
+ } else {
339
+ console.log(`----- ${commands.length} commands to run -----
340
+ ${commands.map((c) => c.label).join("\n")}
341
+ -----------------------------`);
342
+ message = "Can we run the commands";
343
+ }
344
+ const { value } = await prompts({
345
+ type: "confirm",
346
+ name: "value",
347
+ message,
348
+ initial: true,
349
+ });
350
+ if (!value) {
351
+ console.log("Done, thank you");
352
+ process.exit(0);
353
+ }
354
+ for (const command of commands) {
355
+ await command.run();
356
+ }
357
+ console.log("Done, thank you");
358
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/cli",
3
- "version": "0.0.3",
3
+ "version": "0.0.6",
4
4
  "description": "Command Line Interface for jsenv",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -20,13 +20,15 @@
20
20
  },
21
21
  "type": "module",
22
22
  "bin": {
23
- "jsenv": "src/jsenv_cli.mjs"
23
+ "jsenv": "jsenv_cli.js"
24
24
  },
25
25
  "files": [
26
- "./src/"
26
+ "./jsenv_cli.js",
27
+ "./template-*/**"
27
28
  ],
28
29
  "dependencies": {
29
- "prompts": "2.4.2",
30
- "@jsenv/humanize": "1.2.4"
30
+ "@jsenv/humanize": "1.2.4",
31
+ "@jsenv/urls": "2.3.0",
32
+ "prompts": "2.4.2"
31
33
  }
32
34
  }
@@ -0,0 +1,2 @@
1
+ .jsenv/
2
+ .coverage/
@@ -0,0 +1,102 @@
1
+ /*
2
+ * This file uses "@jsenv/eslint-config" to configure ESLint
3
+ * See https://github.com/jsenv/eslint-config#eslint-config----
4
+ */
5
+
6
+ const {
7
+ composeEslintConfig,
8
+ eslintConfigBase,
9
+ eslintConfigForPrettier,
10
+ eslintConfigToPreferExplicitGlobals,
11
+ jsenvEslintRules,
12
+ jsenvEslintRulesForImport,
13
+ } = require("@jsenv/eslint-config");
14
+
15
+ const eslintConfig = composeEslintConfig(
16
+ eslintConfigBase,
17
+
18
+ // enable top level await
19
+ {
20
+ parserOptions: {
21
+ ecmaVersion: 2022,
22
+ },
23
+ },
24
+
25
+ // Files in this repository are all meant to be executed in Node.js
26
+ // and we want to tell this to ESLint.
27
+ // As a result ESLint can consider `window` as undefined
28
+ // and `global` as an existing global variable.
29
+ {
30
+ env: {
31
+ node: true,
32
+ },
33
+ },
34
+
35
+ // Reuse jsenv eslint rules
36
+ {
37
+ rules: {
38
+ ...jsenvEslintRules,
39
+ // Example of code changing the ESLint configuration to enable a rule:
40
+ // 'prefer-const': ['error']
41
+ },
42
+ },
43
+
44
+ // Enable import plugin
45
+ {
46
+ plugins: ["import"],
47
+ settings: {
48
+ "import/resolver": {
49
+ "@jsenv/eslint-import-resolver": {
50
+ rootDirectoryUrl: __dirname,
51
+ packageConditions: ["node", "import"],
52
+ },
53
+ },
54
+ "import/extensions": [".js", ".mjs"],
55
+ },
56
+ rules: jsenvEslintRulesForImport,
57
+ },
58
+
59
+ // package is "type": "module" so:
60
+ // 1. disable commonjs globals by default
61
+ // 2. Re-enable commonjs into *.cjs files
62
+ {
63
+ globals: {
64
+ __filename: "off",
65
+ __dirname: "off",
66
+ require: "off",
67
+ exports: "off",
68
+ },
69
+ overrides: [
70
+ {
71
+ files: ["**/*.cjs"],
72
+ env: {
73
+ commonjs: true,
74
+ },
75
+ // inside *.cjs files. restore commonJS "globals"
76
+ globals: {
77
+ __filename: true,
78
+ __dirname: true,
79
+ require: true,
80
+ exports: true,
81
+ },
82
+ // inside *.cjs files, use commonjs module resolution
83
+ settings: {
84
+ "import/resolver": {
85
+ "@jsenv/eslint-import-resolver": {
86
+ rootDirectoryUrl: __dirname,
87
+ packageConditions: ["node", "require"],
88
+ },
89
+ },
90
+ },
91
+ },
92
+ ],
93
+ },
94
+
95
+ eslintConfigToPreferExplicitGlobals,
96
+
97
+ // We are using prettier, disable all eslint rules
98
+ // already handled by prettier.
99
+ eslintConfigForPrettier,
100
+ );
101
+
102
+ module.exports = eslintConfig;
@@ -0,0 +1,8 @@
1
+ ------------- 1 execution ready -------------
2
+ directory: /Users/damien.maillard/dev/perso/jsenv-core/packages/related/create-jsenv/demo-node-package
3
+ ---------------------------------------------
4
+ ✔ 1/1 tests/message.test.mjs [0.02s] (all completed)
5
+ ------------- 1 execution done --------------
6
+ status: all completed
7
+ duration: 0.1s (setup: 0.004s, execution: 0.1s, teardown: 0s)
8
+ ---------------------------------------------
@@ -0,0 +1,2 @@
1
+ trailingComma: "all"
2
+ quoteProps: "consistent"
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "jsenv-template-node-package",
3
+ "private": true,
4
+ "version": "0.0.0",
5
+ "type": "module",
6
+ "exports": {
7
+ ".": "./src/main.js"
8
+ },
9
+ "scripts": {
10
+ "test": "node ./scripts/test.mjs",
11
+ "test:coverage": "npm run test -- --coverage"
12
+ },
13
+ "devDependencies": {
14
+ "@jsenv/assert": "4.1.4",
15
+ "@jsenv/core": "39.2.1",
16
+ "@jsenv/eslint-config": "16.5.2",
17
+ "@jsenv/eslint-import-resolver": "8.1.2",
18
+ "@jsenv/test": "3.3.11",
19
+ "eslint": "8.56.0",
20
+ "eslint-plugin-import": "2.29.1",
21
+ "prettier": "3.3.3"
22
+ }
23
+ }
@@ -0,0 +1,25 @@
1
+ /*
2
+ * Execute all test files
3
+ * - npm test
4
+ * - npm test:coverage
5
+ * Read more in https://github.com/jsenv/core/tree/main/packages/test#jsenvtest-
6
+ */
7
+
8
+ import { executeTestPlan, nodeWorkerThread } from "@jsenv/test";
9
+
10
+ await executeTestPlan({
11
+ rootDirectoryUrl: new URL("../", import.meta.url),
12
+ testPlan: {
13
+ "./tests/**/*.test.mjs": {
14
+ node: {
15
+ runtime: nodeWorkerThread(),
16
+ },
17
+ },
18
+ },
19
+ coverage: process.argv.includes("--coverage")
20
+ ? {
21
+ methodForNodeJs: "Profiler",
22
+ }
23
+ : false,
24
+ githubCheck: false,
25
+ });
@@ -0,0 +1,8 @@
1
+ /*
2
+ * This file is the entry point of this codebase
3
+ * - It is responsible to export the documented API
4
+ * - It should be kept simple (just re-export) to help reader to
5
+ * discover codebase progressively
6
+ */
7
+
8
+ export { getMessage, getMessageAsync } from "./message.js";
@@ -0,0 +1,11 @@
1
+ /*
2
+ * This file is some boilerplate code meant to be replaced by real code
3
+ */
4
+
5
+ export const getMessage = () => {
6
+ return "Hello dev!";
7
+ };
8
+
9
+ export const getMessageAsync = async () => {
10
+ return "Hello dev async!";
11
+ };
@@ -0,0 +1,21 @@
1
+ /*
2
+ * This file test the public exports of "jsenv-template-node"
3
+ * - It illustrates how to test code
4
+ * - It illustrates how to use top level await to test code
5
+ */
6
+
7
+ import { assert } from "@jsenv/assert";
8
+
9
+ import { getMessage, getMessageAsync } from "jsenv-template-node-package";
10
+
11
+ {
12
+ const actual = getMessage();
13
+ const expect = "Hello dev!";
14
+ assert({ actual, expect });
15
+ }
16
+
17
+ {
18
+ const actual = await getMessageAsync();
19
+ const expect = "Hello dev async!";
20
+ assert({ actual, expect });
21
+ }
@@ -0,0 +1,3 @@
1
+ .jsenv/
2
+ .coverage/
3
+ dist/