@adbayb/stack 2.40.0-next-d18b77e → 2.40.0-next-c79a72a

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.
@@ -38,6 +38,7 @@ const config = defineConfig({
38
38
  rules: {
39
39
  "vitest/consistent-test-it": ["error", { fn: "test", withinDescribe: "test" }],
40
40
  "vitest/no-importing-vitest-globals": "off",
41
+ "vitest/require-test-timeout": "off",
41
42
  "vitest/valid-title": ["error", { mustMatch: { test: ["^should "] } }],
42
43
  },
43
44
  },
@@ -59,8 +60,10 @@ const config = defineConfig({
59
60
  `**/*.stories.{${JAVASCRIPT_LIKE_EXTENSIONS_AS_STRING}}`,
60
61
  ],
61
62
  rules: {
63
+ "e18e/prefer-static-regex": "off",
62
64
  "import/no-anonymous-default-export": "off",
63
65
  "import/no-default-export": "off",
66
+ "react/forbid-component-props": "off",
64
67
  },
65
68
  },
66
69
  ],
@@ -80,6 +83,44 @@ const config = defineConfig({
80
83
  rules: {
81
84
  ...e18ePlugin.configs.recommended.rules,
82
85
  ...perfectionistPlugin["recommended-natural"].rules,
86
+ ...Object.fromEntries(
87
+ [
88
+ "sort-export-attributes",
89
+ "sort-import-attributes",
90
+ "sort-interfaces",
91
+ "sort-jsx-props",
92
+ "sort-maps",
93
+ "sort-object-types",
94
+ "sort-objects",
95
+ "sort-union-types",
96
+ "sort-variable-declarations",
97
+ ].map((ruleName) => {
98
+ return [
99
+ `perfectionist/${ruleName}`,
100
+ [
101
+ "error",
102
+ {
103
+ customGroups: [
104
+ {
105
+ elementNamePattern: "^(as|id|identifier|htmlFor|key|ref)$",
106
+ groupName: "id-like",
107
+ },
108
+ {
109
+ elementNamePattern: "^(label|name|title)$",
110
+ groupName: "name-like",
111
+ },
112
+ {
113
+ elementNamePattern: "^(description|metadata)$",
114
+ groupName: "metadata-like",
115
+ },
116
+ ],
117
+ groups: ["id-like", "name-like", "metadata-like", "unknown"],
118
+ type: "natural",
119
+ },
120
+ ],
121
+ ];
122
+ }),
123
+ ),
83
124
  "@stylistic/jsx-pascal-case": "error",
84
125
  "@stylistic/jsx-self-closing-comp": "error",
85
126
  "@stylistic/lines-between-class-members": "error",
@@ -184,6 +225,7 @@ const config = defineConfig({
184
225
  "no-ternary": "off",
185
226
  "no-undef": "off",
186
227
  "no-undefined": "off",
228
+ "no-underscore-dangle": "off",
187
229
  "no-use-before-define": "off",
188
230
  "no-void": "off",
189
231
  "no-warning-comments": "off",
@@ -194,8 +236,11 @@ const config = defineConfig({
194
236
  "prefer-readonly-parameter-types": "off",
195
237
  "react/jsx-filename-extension": ["error", { extensions: ["jsx", "tsx"] }],
196
238
  "react/jsx-max-depth": "off",
239
+ "react/jsx-no-literals": "off",
197
240
  "react/react-in-jsx-scope": "off",
198
- "sort-imports": ["error", { ignoreDeclarationSort: true }],
241
+ "sort-imports": "off", // Already supported by ESLint Perfectionist
242
+ "sort-keys": "off", // Already supported by ESLint Perfectionist
243
+ "sort-vars": "off", // Already supported by ESLint Perfectionist
199
244
  "strict-boolean-expressions": "off",
200
245
  "typescript/consistent-return": "off",
201
246
  "typescript/consistent-type-definitions": ["error", "type"],
@@ -204,6 +249,7 @@ const config = defineConfig({
204
249
  "typescript/no-unsafe-type-assertion": "off",
205
250
  "unicorn/filename-case": "off",
206
251
  "unicorn/import-style": "off",
252
+ "unicorn/no-array-reduce": "off",
207
253
  "unicorn/no-useless-undefined": "off",
208
254
  },
209
255
  });
@@ -28,21 +28,27 @@ declare const config: {
28
28
  withinDescribe: "test";
29
29
  }];
30
30
  "vitest/no-importing-vitest-globals": "off";
31
+ "vitest/require-test-timeout": "off";
31
32
  "vitest/valid-title": ["error", {
32
33
  mustMatch: {
33
34
  test: string[];
34
35
  };
35
36
  }];
37
+ "e18e/prefer-static-regex"?: never;
36
38
  "import/no-anonymous-default-export"?: never;
37
39
  "import/no-default-export"?: never;
40
+ "react/forbid-component-props"?: never;
38
41
  };
39
42
  } | {
40
43
  files: string[];
41
44
  rules: {
45
+ "e18e/prefer-static-regex": "off";
42
46
  "import/no-anonymous-default-export": "off";
43
47
  "import/no-default-export": "off";
48
+ "react/forbid-component-props": "off";
44
49
  "vitest/consistent-test-it"?: never;
45
50
  "vitest/no-importing-vitest-globals"?: never;
51
+ "vitest/require-test-timeout"?: never;
46
52
  "vitest/valid-title"?: never;
47
53
  };
48
54
  plugins?: never;
@@ -135,6 +141,7 @@ declare const config: {
135
141
  "no-ternary": "off";
136
142
  "no-undef": "off";
137
143
  "no-undefined": "off";
144
+ "no-underscore-dangle": "off";
138
145
  "no-use-before-define": "off";
139
146
  "no-void": "off";
140
147
  "no-warning-comments": "off";
@@ -147,10 +154,11 @@ declare const config: {
147
154
  extensions: string[];
148
155
  }];
149
156
  "react/jsx-max-depth": "off";
157
+ "react/jsx-no-literals": "off";
150
158
  "react/react-in-jsx-scope": "off";
151
- "sort-imports": ["error", {
152
- ignoreDeclarationSort: true;
153
- }];
159
+ "sort-imports": "off";
160
+ "sort-keys": "off";
161
+ "sort-vars": "off";
154
162
  "strict-boolean-expressions": "off";
155
163
  "typescript/consistent-return": "off";
156
164
  "typescript/consistent-type-definitions": ["error", "type"];
@@ -159,6 +167,7 @@ declare const config: {
159
167
  "typescript/no-unsafe-type-assertion": "off";
160
168
  "unicorn/filename-case": "off";
161
169
  "unicorn/import-style": "off";
170
+ "unicorn/no-array-reduce": "off";
162
171
  "unicorn/no-useless-undefined": "off";
163
172
  };
164
173
  };
@@ -50,6 +50,7 @@ const config = defineConfig({
50
50
  withinDescribe: "test"
51
51
  }],
52
52
  "vitest/no-importing-vitest-globals": "off",
53
+ "vitest/require-test-timeout": "off",
53
54
  "vitest/valid-title": ["error", { mustMatch: { test: ["^should "] } }]
54
55
  }
55
56
  }, {
@@ -70,8 +71,10 @@ const config = defineConfig({
70
71
  `**/*.stories.{${JAVASCRIPT_LIKE_EXTENSIONS_AS_STRING}}`
71
72
  ],
72
73
  rules: {
74
+ "e18e/prefer-static-regex": "off",
73
75
  "import/no-anonymous-default-export": "off",
74
- "import/no-default-export": "off"
76
+ "import/no-default-export": "off",
77
+ "react/forbid-component-props": "off"
75
78
  }
76
79
  }],
77
80
  plugins: [
@@ -90,6 +93,41 @@ const config = defineConfig({
90
93
  rules: {
91
94
  ...e18ePlugin.configs.recommended.rules,
92
95
  ...configs["recommended-natural"].rules,
96
+ ...Object.fromEntries([
97
+ "sort-export-attributes",
98
+ "sort-import-attributes",
99
+ "sort-interfaces",
100
+ "sort-jsx-props",
101
+ "sort-maps",
102
+ "sort-object-types",
103
+ "sort-objects",
104
+ "sort-union-types",
105
+ "sort-variable-declarations"
106
+ ].map((ruleName) => {
107
+ return [`perfectionist/${ruleName}`, ["error", {
108
+ customGroups: [
109
+ {
110
+ elementNamePattern: "^(as|id|identifier|htmlFor|key|ref)$",
111
+ groupName: "id-like"
112
+ },
113
+ {
114
+ elementNamePattern: "^(label|name|title)$",
115
+ groupName: "name-like"
116
+ },
117
+ {
118
+ elementNamePattern: "^(description|metadata)$",
119
+ groupName: "metadata-like"
120
+ }
121
+ ],
122
+ groups: [
123
+ "id-like",
124
+ "name-like",
125
+ "metadata-like",
126
+ "unknown"
127
+ ],
128
+ type: "natural"
129
+ }]];
130
+ })),
93
131
  "@stylistic/jsx-pascal-case": "error",
94
132
  "@stylistic/jsx-self-closing-comp": "error",
95
133
  "@stylistic/lines-between-class-members": "error",
@@ -198,6 +236,7 @@ const config = defineConfig({
198
236
  "no-ternary": "off",
199
237
  "no-undef": "off",
200
238
  "no-undefined": "off",
239
+ "no-underscore-dangle": "off",
201
240
  "no-use-before-define": "off",
202
241
  "no-void": "off",
203
242
  "no-warning-comments": "off",
@@ -208,8 +247,11 @@ const config = defineConfig({
208
247
  "prefer-readonly-parameter-types": "off",
209
248
  "react/jsx-filename-extension": ["error", { extensions: ["jsx", "tsx"] }],
210
249
  "react/jsx-max-depth": "off",
250
+ "react/jsx-no-literals": "off",
211
251
  "react/react-in-jsx-scope": "off",
212
- "sort-imports": ["error", { ignoreDeclarationSort: true }],
252
+ "sort-imports": "off",
253
+ "sort-keys": "off",
254
+ "sort-vars": "off",
213
255
  "strict-boolean-expressions": "off",
214
256
  "typescript/consistent-return": "off",
215
257
  "typescript/consistent-type-definitions": ["error", "type"],
@@ -218,6 +260,7 @@ const config = defineConfig({
218
260
  "typescript/no-unsafe-type-assertion": "off",
219
261
  "unicorn/filename-case": "off",
220
262
  "unicorn/import-style": "off",
263
+ "unicorn/no-array-reduce": "off",
221
264
  "unicorn/no-useless-undefined": "off"
222
265
  }
223
266
  });
package/dist/index.js CHANGED
@@ -173,8 +173,8 @@ const changeset = async (command) => {
173
173
  //#region src/commands/build.ts
174
174
  const createBuildCommand = (program) => {
175
175
  program.command({
176
- description: "Build the project in production mode",
177
- name: "build"
176
+ name: "build",
177
+ description: "Build the project in production mode"
178
178
  }).task({ async handler() {
179
179
  await turbo("build");
180
180
  } });
@@ -207,10 +207,11 @@ const checkDependency = async () => {
207
207
  const packageContent = require(packagePath);
208
208
  const peerDependencies = packageContent.peerDependencies ?? {};
209
209
  const devDependencies = packageContent.devDependencies ?? {};
210
+ const dependencies = packageContent.dependencies ?? {};
210
211
  return {
211
- dependencies: packageContent.dependencies ?? {},
212
- devDependencies,
213
212
  name: pkg.name,
213
+ dependencies,
214
+ devDependencies,
214
215
  peerDependencies
215
216
  };
216
217
  });
@@ -220,35 +221,35 @@ const checkDependency = async () => {
220
221
  }
221
222
  };
222
223
  const STARTING_WITH_DIGIT_REGEXP = /^\d/u;
223
- const checkDependencyVersionRange = ({ dependencies, devDependencies, name, peerDependencies }) => {
224
+ const checkDependencyVersionRange = ({ name, dependencies, devDependencies, peerDependencies }) => {
224
225
  for (const [dependencyName, version] of Object.entries(devDependencies)) {
225
226
  assertVersion(version, {
226
- consumedBy: name,
227
- name: dependencyName
227
+ name: dependencyName,
228
+ consumedBy: name
228
229
  });
229
230
  if (version !== "workspace:*" && !isExcluded(version) && !STARTING_WITH_DIGIT_REGEXP.test(version)) throw createPackageError(`As a dev dependency, \`${dependencyName}\` version must be fixed (or set as "workspace:*" for local packages) to reduce accidental breaking change risks due to an implicit semver upgrade.`, {
230
- consumedBy: name,
231
- name: dependencyName
231
+ name: dependencyName,
232
+ consumedBy: name
232
233
  });
233
234
  }
234
235
  for (const [dependencyName, version] of Object.entries(dependencies)) {
235
236
  assertVersion(version, {
236
- consumedBy: name,
237
- name: dependencyName
237
+ name: dependencyName,
238
+ consumedBy: name
238
239
  });
239
240
  if (version !== "workspace:^" && !hasCaret(version) && !isExcluded(version)) throw createPackageError(`As a dependency, \`${dependencyName}\` version must be prefixed with a caret (or set as "workspace:^" for local packages) to optimize the size (whether of installation or bundle output) on the consumer side.`, {
240
- consumedBy: name,
241
- name: dependencyName
241
+ name: dependencyName,
242
+ consumedBy: name
242
243
  });
243
244
  }
244
245
  for (const [dependencyName, version] of Object.entries(peerDependencies)) {
245
246
  assertVersion(version, {
246
- consumedBy: name,
247
- name: dependencyName
247
+ name: dependencyName,
248
+ consumedBy: name
248
249
  });
249
250
  if (!hasCaret(version) && !isExcluded(version)) throw createPackageError(`As a peer dependency, \`${dependencyName}\` version must be explicit (i.e. the "workspace:^" protocol a version resolver is not allowed) and prefixed with a caret to optimize the size (whether of installation or bundle output) on the consumer side.`, {
250
- consumedBy: name,
251
- name: dependencyName
251
+ name: dependencyName,
252
+ consumedBy: name
252
253
  });
253
254
  }
254
255
  };
@@ -268,8 +269,8 @@ const createPackagesVersionMismatchChecker = () => {
268
269
  continue;
269
270
  }
270
271
  if (!(dependencyVersion === storedVersion)) throw createPackageError(`Mismatched versions: received version \`${dependencyVersion}\` while others use \`${storedVersion}\`. To prevent issues with singleton-like code (React contexts, …), please make sure to update all packages to use the same \`${dependencyName}\` version (either \`${storedVersion}\` or \`${dependencyVersion}\`).`, {
271
- consumedBy: packageName,
272
- name: dependencyName
272
+ name: dependencyName,
273
+ consumedBy: packageName
273
274
  });
274
275
  }
275
276
  };
@@ -281,11 +282,11 @@ const createPackagesVersionMismatchChecker = () => {
281
282
  const createPackageError = (message, context) => {
282
283
  return createError("stack check", context ? `\`${context.name}\` consumed by \`${context.consumedBy}\` doesn't conform to package guidelines.\n${message}` : message);
283
284
  };
284
- const assertVersion = (version, { consumedBy, name }) => {
285
+ const assertVersion = (version, { name, consumedBy }) => {
285
286
  assert(version, () => {
286
287
  return createPackageError(`\`${name}\` must have a valid version specified (current version equals to \`${String(version)}\`).`, {
287
- consumedBy,
288
- name
288
+ name,
289
+ consumedBy
289
290
  });
290
291
  });
291
292
  };
@@ -312,54 +313,54 @@ const ONLY_VALUES = [
312
313
  ];
313
314
  const createCheckCommand = (program) => {
314
315
  program.command({
315
- description: "Check code health (static analysis)",
316
- name: "check"
316
+ name: "check",
317
+ description: "Check code health (static analysis)"
317
318
  }).option({
318
- defaultValue: void 0,
319
- description: `Filter the compliance check to run (accepted value: ${ONLY_VALUES.join(", ")})`,
320
319
  key: "filter",
321
- name: "filter"
320
+ name: "filter",
321
+ description: `Filter the compliance check to run (accepted value: ${ONLY_VALUES.join(", ")})`,
322
+ defaultValue: void 0
322
323
  }).task({
323
324
  handler(_, argv) {
324
325
  logCheckableFiles(argv.operands);
325
326
  },
326
327
  skip: ifFilterDefinedAndNotEqualTo("code")
327
328
  }).task({
329
+ label: label$4("Prepare the project"),
328
330
  async handler() {
329
331
  await turbo("build", {
330
332
  excludeExamples: true,
331
333
  hasLiveOutput: false
332
334
  });
333
335
  },
334
- label: label$4("Prepare the project"),
335
336
  skip({ filter }) {
336
337
  return filter === "commit";
337
338
  }
338
339
  }).task({
340
+ label: label$4("Check dependency compliance"),
339
341
  async handler() {
340
342
  await checkDependency();
341
343
  },
342
- label: label$4("Check dependency compliance"),
343
344
  skip: ifFilterDefinedAndNotEqualTo("dependency")
344
345
  }).task({
346
+ label: label$4("Check formatting compliance"),
345
347
  async handler(_, argv) {
346
348
  const filenames = argv.operands;
347
349
  await checkFormatting(filenames);
348
350
  },
349
- label: label$4("Check formatting compliance"),
350
351
  skip: ifFilterDefinedAndNotEqualTo("formatting")
351
352
  }).task({
353
+ label: label$4("Check code compliance"),
352
354
  async handler(_, argv) {
353
355
  const filenames = argv.operands;
354
356
  await checkCode(filenames);
355
357
  },
356
- label: label$4("Check code compliance"),
357
358
  skip: ifFilterDefinedAndNotEqualTo("code")
358
359
  }).task({
360
+ label: label$4("Check commit compliance"),
359
361
  async handler() {
360
362
  await checkCommit();
361
363
  },
362
- label: label$4("Check commit compliance"),
363
364
  skip(context) {
364
365
  return context.filter !== "commit";
365
366
  }
@@ -378,24 +379,24 @@ const ifFilterDefinedAndNotEqualTo = (filter) => {
378
379
  //#region src/commands/clean.ts
379
380
  const createCleanCommand = (program) => {
380
381
  program.command({
381
- description: "Clean the project",
382
- name: "clean"
382
+ name: "clean",
383
+ description: "Clean the project"
383
384
  }).task({
385
+ key: "files",
386
+ label: label$3("Retrieve removable files"),
384
387
  async handler() {
385
388
  const cachePath = "node_modules/.cache";
386
389
  const files = await retrieveIgnoredFiles();
387
390
  if (isDirectoryExistAndNotEmpty(resolveFromWorkingDirectory(cachePath))) files.push(cachePath);
388
391
  return files;
389
- },
390
- key: "files",
391
- label: label$3("Retrieve removable files")
392
+ }
392
393
  }).task({
394
+ label({ files }) {
395
+ return files.length > 0 ? label$3("Clean assets") : "Already clean ✨";
396
+ },
393
397
  async handler({ files }) {
394
398
  if (files.length === 0) return;
395
399
  await cleanFiles(files);
396
- },
397
- label({ files }) {
398
- return files.length > 0 ? label$3("Clean assets") : "Already clean ✨";
399
400
  }
400
401
  }).task({
401
402
  handler({ files }) {
@@ -441,26 +442,26 @@ const PRESERVE_FILES = ["node_modules"];
441
442
 
442
443
  //#endregion
443
444
  //#region package.json
444
- var version = "2.40.0-next-d18b77e";
445
+ var version = "2.40.0-next-c79a72a";
445
446
 
446
447
  //#endregion
447
448
  //#region src/commands/create.ts
448
449
  const REPOSITORY_REGEXP = /^(?:git@.*:|https?:\/\/.*\/)(?<repoOwner>[^/]+)\/(?<repoName>[^/]+)\.git$/u;
449
450
  const createCreateCommand = (program) => {
450
451
  program.command({
451
- description: "Scaffold a new project",
452
- name: "create"
452
+ name: "create",
453
+ description: "Scaffold a new project"
453
454
  }).task({ handler() {
454
455
  botMessage({
455
- description: "I can guarantee you a project creation in under 1 minute 🚀",
456
456
  title: `I'm Stack v${version} 👋`,
457
+ description: "I can guarantee you a project creation in under 1 minute 🚀",
457
458
  type: "information"
458
459
  });
459
460
  } }).task({
461
+ label: label$2("Check pre-requisites"),
460
462
  async handler() {
461
463
  await getPnpmVersion();
462
- },
463
- label: label$2("Check pre-requisites")
464
+ }
464
465
  }).input({
465
466
  key: "inputName",
466
467
  label: "What's your project name?",
@@ -470,17 +471,19 @@ const createCreateCommand = (program) => {
470
471
  label: "How would you describe it?",
471
472
  type: "text"
472
473
  }).input({
473
- defaultValue: "git@github.com:adbayb/xxx.git",
474
474
  key: "inputUrl",
475
475
  label: "Where will it be stored? (Git remote URL)",
476
+ defaultValue: "git@github.com:adbayb/xxx.git",
476
477
  type: "text"
477
478
  }).input({
478
- defaultValue: "single-project",
479
479
  key: "inputTemplate",
480
480
  label: "Which template you would like to apply?",
481
+ defaultValue: "single-project",
481
482
  options: ["single-project", "multi-projects"],
482
483
  type: "select"
483
484
  }).task({
485
+ key: "data",
486
+ label: label$2("Check and format input"),
484
487
  async handler({ inputDescription, inputName, inputTemplate, inputUrl }) {
485
488
  if (!inputName) throw createError("stack create", "The project name is not optional. Make sure to provide a valid value (non-empty string).");
486
489
  const { repoName, repoOwner } = REPOSITORY_REGEXP.exec(inputUrl)?.groups ?? {};
@@ -499,15 +502,13 @@ const createCreateCommand = (program) => {
499
502
  templatePath: resolveFromPackageDirectory("templates", inputTemplate),
500
503
  workingPath: resolveFromWorkingDirectory(projectName)
501
504
  };
502
- },
503
- key: "data",
504
- label: label$2("Check and format input")
505
+ }
505
506
  }).input({
506
- defaultValue: true,
507
507
  key: "canRemoveExistingDirectoryInput",
508
508
  label({ data: { projectName } }) {
509
509
  return label$2(`\`${projectName}\` directory already exists, do you want to remove it?`);
510
510
  },
511
+ defaultValue: true,
511
512
  skip({ data: { workingPath } }) {
512
513
  return !existsSync(workingPath);
513
514
  },
@@ -517,6 +518,10 @@ const createCreateCommand = (program) => {
517
518
  return createError("mkdir", `Remove or rename the \`${projectName}\` existing directory to apply the template from a clean state.`);
518
519
  }
519
520
  }).task({
521
+ key: "templateEngine",
522
+ label({ data: { projectName }, inputTemplate }) {
523
+ return label$2(`Copy \`${inputTemplate}\` template to \`${projectName}\` directory`);
524
+ },
520
525
  async handler({ canRemoveExistingDirectoryInput, data: { licenseYear, nodeVersion, pnpmVersion, projectDescription, projectName, projectUrl, repoId, templatePath, workingPath }, inputTemplate }) {
521
526
  if (canRemoveExistingDirectoryInput) await rm(workingPath, {
522
527
  force: true,
@@ -536,31 +541,28 @@ const createCreateCommand = (program) => {
536
541
  templateName: inputTemplate,
537
542
  templatePath
538
543
  });
539
- },
540
- key: "templateEngine",
541
- label({ data: { projectName }, inputTemplate }) {
542
- return label$2(`Copy \`${inputTemplate}\` template to \`${projectName}\` directory`);
543
544
  }
544
545
  }).task({
546
+ label() {
547
+ return label$2("Process template");
548
+ },
545
549
  async handler({ templateEngine }) {
546
550
  await templateEngine.processContents();
547
551
  await templateEngine.processPaths();
548
- },
549
- label() {
550
- return label$2("Process template");
551
552
  }
552
553
  }).task({
554
+ label: label$2("Initialize `git`"),
553
555
  async handler({ data: { projectUrl } }) {
554
556
  await helpers.exec("git init");
555
557
  await helpers.exec(`git remote add origin ${projectUrl}`);
556
- },
557
- label: label$2("Initialize `git`")
558
+ }
558
559
  }).task({
560
+ label: label$2("Set up the package manager"),
559
561
  async handler() {
560
562
  await setPackageManager();
561
- },
562
- label: label$2("Set up the package manager")
563
+ }
563
564
  }).task({
565
+ label: label$2("Install dependencies"),
564
566
  async handler({ data: { projectName } }) {
565
567
  const localDevelopmentDependencies = ["quickbundle", "vitest"];
566
568
  const globalDevelopmentDependencies = ["@adbayb/stack"];
@@ -571,23 +573,22 @@ const createCreateCommand = (program) => {
571
573
  } catch (error) {
572
574
  throw createError("pnpm", error instanceof Error ? error : new Error(String(error)));
573
575
  }
574
- },
575
- label: label$2("Install dependencies")
576
+ }
576
577
  }).task({
578
+ label: label$2("Run `stack install`"),
577
579
  async handler() {
578
580
  await helpers.exec("stack install");
579
- },
580
- label: label$2("Run `stack install`")
581
+ }
581
582
  }).task({
583
+ label: label$2("Commit"),
582
584
  async handler() {
583
585
  await helpers.exec("git add -A");
584
586
  await helpers.exec("git commit -m \"chore: initial commit\"");
585
- },
586
- label: label$2("Commit")
587
+ }
587
588
  }).task({ handler({ data: { projectName } }) {
588
589
  botMessage({
589
- description: `Run \`cd ./${projectName}\` and Enjoy 🚀`,
590
590
  title: "The project was successfully created",
591
+ description: `Run \`cd ./${projectName}\` and Enjoy 🚀`,
591
592
  type: "success"
592
593
  });
593
594
  } });
@@ -693,28 +694,28 @@ const fixFormatting = oxfmt({ isFixMode: true });
693
694
  //#region src/commands/fix/fix.ts
694
695
  const createFixCommand = (program) => {
695
696
  program.command({
696
- description: "Fix auto-fixable issues",
697
- name: "fix"
697
+ name: "fix",
698
+ description: "Fix auto-fixable issues"
698
699
  }).task({ handler(_, argv) {
699
700
  logCheckableFiles(argv.operands);
700
701
  } }).task({
702
+ label: label$1("Prepare the project"),
701
703
  async handler() {
702
704
  await turbo("build", {
703
705
  excludeExamples: true,
704
706
  hasLiveOutput: false
705
707
  });
706
- },
707
- label: label$1("Prepare the project")
708
+ }
708
709
  }).task({
710
+ label: label$1("Fix formatting issues"),
709
711
  async handler(_, argv) {
710
712
  await fixFormatting(argv.operands);
711
- },
712
- label: label$1("Fix formatting issues")
713
+ }
713
714
  }).task({
715
+ label: label$1("Fix code issues"),
714
716
  async handler(_, argv) {
715
717
  await fixCode(argv.operands);
716
- },
717
- label: label$1("Fix code issues")
718
+ }
718
719
  });
719
720
  };
720
721
  const label$1 = (message) => {
@@ -725,18 +726,18 @@ const label$1 = (message) => {
725
726
  //#region src/commands/install.ts
726
727
  const createInstallCommand = (program) => {
727
728
  program.command({
728
- description: "Install required setup",
729
- name: "install"
729
+ name: "install",
730
+ description: "Install required setup"
730
731
  }).task({
732
+ label: label("Install `git.pre-commit` hook"),
731
733
  async handler() {
732
734
  await installGitHook("pre-commit", `${getStackCommand(`fix $(node -e 'console.log(require("child_process").execSync("git status --porcelain", {encoding: "utf8"}).split(/${String.raw`\n|\r\n`}/).filter(Boolean).map(item => item.split(" ").at(-1)).join(" "))')`)} && git add -A`);
733
- },
734
- label: label("Install `git.pre-commit` hook")
735
+ }
735
736
  }).task({
737
+ label: label("Install `git.commit-msg` hook"),
736
738
  async handler() {
737
739
  await installGitHook("commit-msg", getStackCommand("check --filter commit"));
738
- },
739
- label: label("Install `git.commit-msg` hook")
740
+ }
740
741
  });
741
742
  };
742
743
  const label = (message) => {
@@ -752,24 +753,24 @@ const installGitHook = async (hook, content) => {
752
753
  //#region src/commands/release.ts
753
754
  const createReleaseCommand = (program) => {
754
755
  program.command({
755
- description: "Log, version, and publish package(s)",
756
- name: "release"
756
+ name: "release",
757
+ description: "Log, version, and publish package(s)"
757
758
  }).option({
758
- description: "Add a new changelog entry",
759
759
  key: "log",
760
- name: "log"
760
+ name: "log",
761
+ description: "Add a new changelog entry"
761
762
  }).option({
762
- description: "Add an empty changelog entry",
763
763
  key: "emptyLog",
764
- name: "empty-log"
764
+ name: "empty-log",
765
+ description: "Add an empty changelog entry"
765
766
  }).option({
766
- description: "Bump the package(s) version",
767
767
  key: "tag",
768
- name: "tag"
768
+ name: "tag",
769
+ description: "Bump the package(s) version"
769
770
  }).option({
770
- description: "Publish package(s) to the registry",
771
771
  key: "publish",
772
- name: "publish"
772
+ name: "publish",
773
+ description: "Publish package(s) to the registry"
773
774
  }).task({
774
775
  async handler() {
775
776
  helpers.message("New changelog entry\n");
@@ -806,8 +807,8 @@ const ifNotEqualTo = (validOption) => {
806
807
  //#region src/commands/start.ts
807
808
  const createStartCommand = (program) => {
808
809
  program.command({
809
- description: "Start the project in production mode",
810
- name: "start"
810
+ name: "start",
811
+ description: "Start the project in production mode"
811
812
  }).task({ async handler() {
812
813
  await turbo("start");
813
814
  } });
@@ -817,8 +818,8 @@ const createStartCommand = (program) => {
817
818
  //#region src/commands/test.ts
818
819
  const createTestCommand = (program) => {
819
820
  program.command({
820
- description: "Test the code execution",
821
- name: "test"
821
+ name: "test",
822
+ description: "Test the code execution"
822
823
  }).task({ async handler() {
823
824
  await turbo("test");
824
825
  } });
@@ -828,8 +829,8 @@ const createTestCommand = (program) => {
828
829
  //#region src/commands/watch.ts
829
830
  const createWatchCommand = (program) => {
830
831
  program.command({
831
- description: "Build and start the project in development mode",
832
- name: "watch"
832
+ name: "watch",
833
+ description: "Build and start the project in development mode"
833
834
  }).task({ async handler() {
834
835
  await turbo("watch");
835
836
  } });
@@ -839,12 +840,12 @@ const createWatchCommand = (program) => {
839
840
  //#region src/index.ts
840
841
  const createProgram = (...commandFactories) => {
841
842
  const program = termost({
842
- description: "Toolbox to easily scaffold and maintain a project",
843
843
  name: "stack",
844
+ description: "Toolbox to easily scaffold and maintain a project",
844
845
  onException() {
845
846
  botMessage({
846
- description: "Keep calm and carry on with some coffee ☕️",
847
847
  title: "Oops, an error occurred",
848
+ description: "Keep calm and carry on with some coffee ☕️",
848
849
  type: "error"
849
850
  });
850
851
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adbayb/stack",
3
- "version": "2.40.0-next-d18b77e",
3
+ "version": "2.40.0-next-c79a72a",
4
4
  "description": "My opinionated JavaScript-based toolchain",
5
5
  "keywords": [
6
6
  "development",
@@ -52,17 +52,17 @@
52
52
  },
53
53
  "dependencies": {
54
54
  "@changesets/changelog-github": "^0.7.0",
55
- "@changesets/cli": "^2.31.0",
55
+ "@changesets/cli": "^2.31.1",
56
56
  "@commitlint/cli": "^21.2.1",
57
57
  "@commitlint/config-conventional": "^21.2.0",
58
58
  "@e18e/eslint-plugin": "^0.5.1",
59
59
  "@stylistic/eslint-plugin": "^5.10.0",
60
60
  "eslint-plugin-perfectionist": "^5.10.0",
61
61
  "oxfmt": "^0.58.0",
62
- "oxlint": "^1.73.0",
62
+ "oxlint": "^1.74.0",
63
63
  "oxlint-tsgolint": "^0.24.0",
64
64
  "termost": "^1.9.1",
65
- "turbo": "^2.10.4",
65
+ "turbo": "^2.10.5",
66
66
  "typescript": "^6.0.3"
67
67
  },
68
68
  "devDependencies": {