@adbayb/stack 3.2.1 → 3.3.0

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.
@@ -27,6 +27,6 @@ declare const config: {
27
27
  useTabs: true;
28
28
  vueIndentScriptAndStyle: false;
29
29
  };
30
- declare const createConfig: ({ overrides }: Required<Pick<OxfmtConfig, "overrides">>) => OxfmtConfig;
30
+ export declare const createConfig: ({ overrides }: Required<Pick<OxfmtConfig, "overrides">>) => OxfmtConfig;
31
31
  //#endregion
32
- export { createConfig, config as default };
32
+ export { config as default };
@@ -269,6 +269,6 @@ declare const config: {
269
269
  "unicorn/prefer-math-trunc": "off";
270
270
  };
271
271
  };
272
- declare const createConfig: ({ ignorePatterns }: Required<Pick<OxlintConfig, "ignorePatterns">>) => OxlintConfig;
272
+ export declare const createConfig: ({ ignorePatterns }: Required<Pick<OxlintConfig, "ignorePatterns">>) => OxlintConfig;
273
273
  //#endregion
274
- export { createConfig, config as default };
274
+ export { config as default };
package/dist/index.js CHANGED
@@ -1,48 +1,16 @@
1
- import { helpers, termost } from "termost";
1
+ import { createLogger, exec, termost } from "termost";
2
2
  import { createRequire } from "node:module";
3
3
  import { basename, join, resolve } from "node:path";
4
4
  import { existsSync, readdirSync } from "node:fs";
5
5
  import { chmod, cp, mkdir, readFile, readdir, rename, rm, symlink, writeFile } from "node:fs/promises";
6
6
 
7
7
  //#region src/helpers.ts
8
+ const logger = createLogger();
8
9
  const require = createRequire(import.meta.url);
9
10
  const assert = (expectedCondition, createError) => {
10
11
  if (!expectedCondition) throw createError();
11
12
  };
12
13
  /**
13
- * Helper to format log messages with a welcoming bot.
14
- *
15
- * @example
16
- * botMessage({
17
- * title: "Oops, an error occurred",
18
- * description: "Keep calm and carry on with some coffee ☕️",
19
- * body: String(previousTaskError),
20
- * type: "error",
21
- * });
22
- *
23
- * @param input - Message factory.
24
- * @param input.title - Title input.
25
- * @param input.description - Description input.
26
- * @param input.body - Body input.
27
- * @param input.type - Message type.
28
- */
29
- const botMessage = (input) => {
30
- const { type } = input;
31
- const log = console[type === "error" ? "error" : "log"];
32
- log(helpers.format(`
33
- ╭─────╮
34
- │ ◠ ◠ ${input.title}
35
- │ ${type === "error" ? "◠" : "◡"} │ ${input.description}
36
- ╰─────╯
37
- ${input.body ? `
38
- ${input.body}
39
- ` : ""}`, { color: {
40
- error: "red",
41
- information: "blue",
42
- success: "green"
43
- }[type] }));
44
- };
45
- /**
46
14
  * Resolve a relative path to an absolute one resolved from the generated project root directory.
47
15
  *
48
16
  * @example
@@ -76,7 +44,7 @@ const createError = (bin, error) => {
76
44
  };
77
45
  const getPnpmVersion = async () => {
78
46
  try {
79
- return await helpers.exec("pnpm -v");
47
+ return await exec("pnpm -v");
80
48
  } catch {
81
49
  throw createError("pnpm", "The project must use `pnpm` as a node package manager tool. Follow this installation guide https://pnpm.io/installation");
82
50
  }
@@ -91,7 +59,7 @@ const setPackageManager = async () => {
91
59
  *
92
60
  * @see {@link https://github.com/nodejs/corepack/issues/613}
93
61
  */
94
- await helpers.exec("pnx corepack enable");
62
+ await exec("pnx corepack enable");
95
63
  };
96
64
  const request = { async get(url, responseType) {
97
65
  const response = await fetch(url);
@@ -110,7 +78,7 @@ const oxlint = (options) => {
110
78
  ];
111
79
  if (options.isFixMode) args.push("--fix-dangerously");
112
80
  try {
113
- return await helpers.exec(`oxlint ${args.join(" ")}`);
81
+ return await exec(`oxlint ${args.join(" ")}`);
114
82
  } catch (error) {
115
83
  throw createError("oxlint", error instanceof Error ? error : new Error(String(error)));
116
84
  }
@@ -125,7 +93,7 @@ const oxfmt = (options) => {
125
93
  options.isFixMode ? "--write" : "--check"
126
94
  ];
127
95
  try {
128
- return await helpers.exec(`oxfmt ${args.join(" ")}`);
96
+ return await exec(`oxfmt ${args.join(" ")}`);
129
97
  } catch (error) {
130
98
  throw createError("oxfmt", error instanceof Error ? error : new Error(String(error)));
131
99
  }
@@ -134,7 +102,7 @@ const oxfmt = (options) => {
134
102
  const turbo = async (command, options = {}) => {
135
103
  try {
136
104
  const { excludeExamples = false, hasLiveOutput = true, ...restOptions } = options;
137
- return await helpers.exec(`turbo run ${command} ${excludeExamples ? "--filter !@examples/*" : ""}`, {
105
+ return await exec(`turbo run ${command} ${excludeExamples ? "--filter !@examples/*" : ""}`, {
138
106
  ...restOptions,
139
107
  hasLiveOutput
140
108
  });
@@ -144,26 +112,14 @@ const turbo = async (command, options = {}) => {
144
112
  };
145
113
  const logCheckableFiles = (files) => {
146
114
  if (files.length === 0) {
147
- helpers.message("The whole project will be checked.", {
148
- label: false,
149
- lineBreak: {
150
- end: true,
151
- start: false
152
- }
153
- });
115
+ logger.info("The whole project will be checked.");
154
116
  return;
155
117
  }
156
- helpers.message(files.join("\n "), {
157
- label: "Following files will be checked:",
158
- lineBreak: {
159
- end: true,
160
- start: false
161
- }
162
- });
118
+ logger.info(`Following files will be checked:\n ${files.join("\n ")}`);
163
119
  };
164
120
  const changeset = async (command) => {
165
121
  try {
166
- return await helpers.exec(command, { hasLiveOutput: true });
122
+ return await exec(command, { hasLiveOutput: true });
167
123
  } catch (error) {
168
124
  throw createError("changeset", error instanceof Error ? error : new Error(String(error)));
169
125
  }
@@ -188,7 +144,7 @@ const checkCode = oxlint({ isFixMode: false });
188
144
  //#region src/commands/check/checkCommit.ts
189
145
  const checkCommit = async () => {
190
146
  try {
191
- return await helpers.exec("commitlint --extends \"@commitlint/config-conventional\" --edit");
147
+ return await exec("commitlint --extends \"@commitlint/config-conventional\" --edit");
192
148
  } catch (error) {
193
149
  throw createError("commitlint", error instanceof Error ? error : new Error(String(error)));
194
150
  }
@@ -197,7 +153,7 @@ const checkCommit = async () => {
197
153
  //#endregion
198
154
  //#region src/commands/check/checkDependency.ts
199
155
  const checkDependency = async () => {
200
- const stdout = await helpers.exec("pnpm recursive ls --json");
156
+ const stdout = await exec("pnpm recursive ls --json");
201
157
  const checkDependencyVersionMismatch = createPackagesVersionMismatchChecker();
202
158
  const packages = JSON.parse(stdout).map((pkg) => {
203
159
  const packagePath = join(pkg.path, "package.json");
@@ -400,14 +356,7 @@ const createCleanCommand = (program) => {
400
356
  }
401
357
  }).task({
402
358
  handler({ files }) {
403
- helpers.message(files.join("\n "), {
404
- label: "Removed assets",
405
- lineBreak: {
406
- end: false,
407
- start: true
408
- },
409
- type: "information"
410
- });
359
+ logger.info(`Removed assets\n ${files.join("\n ")}`);
411
360
  },
412
361
  skip({ files }) {
413
362
  return files.length === 0;
@@ -430,7 +379,7 @@ const isDirectoryExistAndNotEmpty = (path) => {
430
379
  };
431
380
  const LINEBREAK_REGEXP = /\n|\r\n/u;
432
381
  const retrieveIgnoredFiles = async () => {
433
- return (await helpers.exec("git clean -fdXn")).split(LINEBREAK_REGEXP).filter((cleanOutput) => {
382
+ return (await exec("git clean -fdXn")).split(LINEBREAK_REGEXP).filter((cleanOutput) => {
434
383
  return PRESERVE_FILES.every((excludedFile) => {
435
384
  return !cleanOutput.includes(excludedFile);
436
385
  });
@@ -440,10 +389,6 @@ const retrieveIgnoredFiles = async () => {
440
389
  };
441
390
  const PRESERVE_FILES = ["node_modules"];
442
391
 
443
- //#endregion
444
- //#region package.json
445
- var version = "3.2.1";
446
-
447
392
  //#endregion
448
393
  //#region src/commands/create.ts
449
394
  const REPOSITORY_REGEXP = /^(?:git@.*:|https?:\/\/.*\/)(?<repoOwner>[^/]+)\/(?<repoName>[^/]+)\.git$/u;
@@ -451,13 +396,7 @@ const createCreateCommand = (program) => {
451
396
  program.command({
452
397
  name: "create",
453
398
  description: "Scaffold a new project"
454
- }).task({ handler() {
455
- botMessage({
456
- title: `I'm Stack v${version} 👋`,
457
- description: "I can guarantee you a project creation in under 1 minute 🚀",
458
- type: "information"
459
- });
460
- } }).task({
399
+ }).task({
461
400
  label: label$2("Check pre-requisites"),
462
401
  async handler() {
463
402
  await getPnpmVersion();
@@ -554,8 +493,8 @@ const createCreateCommand = (program) => {
554
493
  }).task({
555
494
  label: label$2("Initialize `git`"),
556
495
  async handler({ data: { projectUrl } }) {
557
- await helpers.exec("git init");
558
- await helpers.exec(`git remote add origin ${projectUrl}`);
496
+ await exec("git init");
497
+ await exec(`git remote add origin ${projectUrl}`);
559
498
  }
560
499
  }).task({
561
500
  label: label$2("Set up the package manager"),
@@ -568,9 +507,9 @@ const createCreateCommand = (program) => {
568
507
  const localDevelopmentDependencies = ["quickbundle", "vitest"];
569
508
  const globalDevelopmentDependencies = ["@adbayb/stack"];
570
509
  try {
571
- await helpers.exec(`pnpm add ${globalDevelopmentDependencies.join(" ")} --save-dev --ignore-workspace-root-check`);
572
- await helpers.exec(`pnpm add ${localDevelopmentDependencies.join(" ")} --save-dev --filter ${projectName}`);
573
- await helpers.exec("pnpm install");
510
+ await exec(`pnpm add ${globalDevelopmentDependencies.join(" ")} --save-dev --ignore-workspace-root-check`);
511
+ await exec(`pnpm add ${localDevelopmentDependencies.join(" ")} --save-dev --filter ${projectName}`);
512
+ await exec("pnpm install");
574
513
  } catch (error) {
575
514
  throw createError("pnpm", error instanceof Error ? error : new Error(String(error)));
576
515
  }
@@ -578,20 +517,16 @@ const createCreateCommand = (program) => {
578
517
  }).task({
579
518
  label: label$2("Run `stack install`"),
580
519
  async handler() {
581
- await helpers.exec("stack install");
520
+ await exec("stack install");
582
521
  }
583
522
  }).task({
584
523
  label: label$2("Commit"),
585
524
  async handler() {
586
- await helpers.exec("git add -A");
587
- await helpers.exec("git commit -m \"chore: initial commit\"");
525
+ await exec("git add -A");
526
+ await exec("git commit -m \"chore: initial commit\"");
588
527
  }
589
528
  }).task({ handler({ data: { projectName } }) {
590
- botMessage({
591
- title: "The project was successfully created",
592
- description: `Run \`cd ./${projectName}\` and Enjoy 🚀`,
593
- type: "success"
594
- });
529
+ logger.success(`The project was successfully created.\nRun \`cd ./${projectName}\` and Enjoy 🚀.`);
595
530
  } });
596
531
  };
597
532
  const label$2 = (message) => {
@@ -783,32 +718,32 @@ const createReleaseCommand = (program) => {
783
718
  description: "Publish stable version(s) to the registry"
784
719
  }).task({
785
720
  async handler() {
786
- helpers.message("Adding a changelog\n");
721
+ logger.info("Adding a changelog");
787
722
  await changeset("changeset");
788
723
  },
789
724
  skip: ifNotEqualTo("changelog")
790
725
  }).task({
791
726
  async handler() {
792
- helpers.message("Adding an empty changelog\n");
727
+ logger.info("Adding an empty changelog");
793
728
  await changeset("changeset --empty");
794
729
  },
795
730
  skip: ifNotEqualTo("emptyChangelog")
796
731
  }).task({
797
732
  async handler() {
798
- helpers.message("Bumping version(s)\n");
733
+ logger.info("Bumping version(s)");
799
734
  await changeset("changeset version");
800
735
  },
801
736
  skip: ifNotEqualTo("bump")
802
737
  }).task({
803
738
  async handler() {
804
- helpers.message("Publishing snapshot version(s) to the registry\n");
739
+ logger.info("Publishing snapshot version(s) to the registry");
805
740
  await changeset("changeset version --snapshot next");
806
741
  await changeset("changeset publish --tag next --no-git-tag");
807
742
  },
808
743
  skip: ifNotEqualTo("snapshot")
809
744
  }).task({
810
745
  async handler() {
811
- helpers.message("Publishing stable version(s) to the registry\n");
746
+ logger.info("Publishing stable version(s) to the registry");
812
747
  await changeset("stack build && changeset publish");
813
748
  },
814
749
  skip: ifNotEqualTo("publish")
@@ -853,6 +788,10 @@ const createWatchCommand = (program) => {
853
788
  } });
854
789
  };
855
790
 
791
+ //#endregion
792
+ //#region package.json
793
+ var version = "3.3.0";
794
+
856
795
  //#endregion
857
796
  //#region src/index.ts
858
797
  const createProgram = (...commandFactories) => {
@@ -860,11 +799,7 @@ const createProgram = (...commandFactories) => {
860
799
  name: "stack",
861
800
  description: "Toolbox to easily scaffold and maintain a project",
862
801
  onException() {
863
- botMessage({
864
- title: "Oops, an error occurred",
865
- description: "Keep calm and carry on with some coffee ☕️",
866
- type: "error"
867
- });
802
+ logger.error("Oops, an error occurred.\nKeep calm and carry on with some coffee ☕️.");
868
803
  },
869
804
  version
870
805
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adbayb/stack",
3
- "version": "3.2.1",
3
+ "version": "3.3.0",
4
4
  "description": "My opinionated JavaScript-based toolchain",
5
5
  "keywords": [
6
6
  "development",
@@ -61,13 +61,13 @@
61
61
  "oxfmt": "^0.64.0",
62
62
  "oxlint": "^1.79.0",
63
63
  "oxlint-tsgolint": "^7.0.2001",
64
- "termost": "^1.9.2",
64
+ "termost": "^2.0.0",
65
65
  "turbo": "^2.10.11",
66
66
  "typescript": "^6.0.3"
67
67
  },
68
68
  "devDependencies": {
69
69
  "@types/node": "24.13.3",
70
- "quickbundle": "3.1.1"
70
+ "quickbundle": "3.2.0"
71
71
  },
72
72
  "scripts": {
73
73
  "build": "quickbundle build",