@adbayb/stack 2.40.0-next-7baa8ed โ†’ 2.40.0-next-314d883

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/bin/index.js CHANGED
@@ -1,7 +1,5 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { createRequire } from "node:module";
3
+ import pkg from "../package.json" with { type: "json" };
4
4
 
5
- const package_ = createRequire(import.meta.url)("../package.json");
6
-
7
- void import(new URL(`../${package_.exports["."].default}`, import.meta.url));
5
+ void import(new URL(`../${pkg.exports["."].default}`, import.meta.url));
@@ -15,8 +15,31 @@ export default defineConfig({
15
15
  "unicorn",
16
16
  "vitest",
17
17
  ],
18
+ // TODO: add jsPlugins for perfectionist and padding-line-between-statements + add React rules (such as set-state-in-effect) from React X https://github.com/oxc-project/oxc/issues/1022
18
19
  categories: {
19
20
  correctness: "error",
21
+ pedantic: "error",
22
+ perf: "error",
23
+ suspicious: "error",
24
+ nursery: "error",
25
+ },
26
+ rules: {
27
+ "no-undef": "off",
28
+ "prefer-readonly-parameter-types": "off",
29
+ "strict-boolean-expressions": "off",
30
+ "max-lines": "off",
31
+ "max-lines-per-function": "off",
32
+ "max-classes-per-file": "off",
33
+ "import/max-dependencies": "off",
34
+ "react/jsx-max-depth": "off",
35
+ "jsdoc/require-param-type": "off",
36
+ "jsdoc/require-property-type": "off",
37
+ "jsdoc/require-returns-type": "off",
38
+ "no-warning-comments": "off",
39
+ "array-callback-return": ["error", { allowImplicit: true }],
40
+ "typescript/consistent-return": "off",
41
+ "typescript/no-unsafe-type-assertion": "off",
42
+ // TODO: disable typescript/no-unsafe-type-assertion and check previous code to reinsert as assertion
20
43
  },
21
44
  options: {
22
45
  denyWarnings: true,
package/dist/index.js CHANGED
@@ -91,40 +91,42 @@ const setPackageManager = async () => {
91
91
  *
92
92
  * @see {@link https://github.com/nodejs/corepack/issues/613}
93
93
  */
94
- return helpers.exec("pnx corepack enable");
94
+ await helpers.exec("pnx corepack enable");
95
95
  };
96
- const request = { async get(url, responseType) {
96
+ async function getRequest(url, responseType) {
97
97
  const response = await fetch(url);
98
98
  if (!response.ok) throw createError("fetch", `Failed to fetch resources from ${url} (${JSON.stringify({
99
99
  status: response.status,
100
100
  statusText: response.statusText
101
101
  })})`);
102
- return response[responseType === "text" ? "text" : "json"]();
103
- } };
102
+ if (responseType === "text") return response.text();
103
+ return response.json();
104
+ }
105
+ const request = { get: getRequest };
104
106
  const oxlint = (options) => async (files = []) => {
105
- const arguments_ = [
107
+ const args = [
106
108
  ...files,
107
109
  "--disable-nested-config",
108
110
  "--no-error-on-unmatched-pattern"
109
111
  ];
110
- if (options.isFixMode) arguments_.push("--fix");
112
+ if (options.isFixMode) args.push("--fix");
111
113
  try {
112
- return await helpers.exec(`oxlint ${arguments_.join(" ")}`);
114
+ return await helpers.exec(`oxlint ${args.join(" ")}`);
113
115
  } catch (error) {
114
- throw createError("oxlint", error);
116
+ throw createError("oxlint", error instanceof Error ? error : new Error(String(error)));
115
117
  }
116
118
  };
117
119
  const oxfmt = (options) => async (files = []) => {
118
- const arguments_ = [
120
+ const args = [
119
121
  ...files,
120
122
  "--disable-nested-config",
121
123
  "--no-error-on-unmatched-pattern",
122
124
  options.isFixMode ? "--write" : "--check"
123
125
  ];
124
126
  try {
125
- return await helpers.exec(`oxfmt ${arguments_.join(" ")}`);
127
+ return await helpers.exec(`oxfmt ${args.join(" ")}`);
126
128
  } catch (error) {
127
- throw createError("oxfmt", error);
129
+ throw createError("oxfmt", error instanceof Error ? error : new Error(String(error)));
128
130
  }
129
131
  };
130
132
  const turbo = async (command, options = {}) => {
@@ -135,7 +137,7 @@ const turbo = async (command, options = {}) => {
135
137
  hasLiveOutput
136
138
  });
137
139
  } catch (error) {
138
- throw createError("turbo", error);
140
+ throw createError("turbo", error instanceof Error ? error : new Error(String(error)));
139
141
  }
140
142
  };
141
143
  const logCheckableFiles = (files) => {
@@ -161,7 +163,7 @@ const changeset = async (command) => {
161
163
  try {
162
164
  return await helpers.exec(command, { hasLiveOutput: true });
163
165
  } catch (error) {
164
- throw createError("changeset", error);
166
+ throw createError("changeset", error instanceof Error ? error : new Error(String(error)));
165
167
  }
166
168
  };
167
169
 
@@ -186,7 +188,7 @@ const checkCommit = async () => {
186
188
  try {
187
189
  return await helpers.exec("commitlint --extends \"@commitlint/config-conventional\" --edit");
188
190
  } catch (error) {
189
- throw createError("commitlint", error);
191
+ throw createError("commitlint", error instanceof Error ? error : new Error(String(error)));
190
192
  }
191
193
  };
192
194
 
@@ -195,22 +197,22 @@ const checkCommit = async () => {
195
197
  const checkDependency = async () => {
196
198
  const stdout = await helpers.exec("pnpm recursive ls --json");
197
199
  const checkDependencyVersionMismatch = createPackagesVersionMismatchChecker();
198
- const packages = JSON.parse(stdout).map((package_) => {
199
- const packagePath = join(package_.path, "package.json");
200
- assert(package_.name, () => createPackageError(`\`${packagePath}\` must have a name field.`));
200
+ const packages = JSON.parse(stdout).map((pkg) => {
201
+ const packagePath = join(pkg.path, "package.json");
202
+ assert(pkg.name, () => createPackageError(`\`${packagePath}\` must have a name field.`));
201
203
  const packageContent = require(packagePath);
202
204
  const peerDependencies = packageContent.peerDependencies ?? {};
203
205
  const devDependencies = packageContent.devDependencies ?? {};
204
206
  return {
205
207
  dependencies: packageContent.dependencies ?? {},
206
208
  devDependencies,
207
- name: package_.name,
209
+ name: pkg.name,
208
210
  peerDependencies
209
211
  };
210
212
  });
211
- for (const package_ of packages) {
212
- checkDependencyVersionMismatch(package_);
213
- checkDependencyVersionRange(package_);
213
+ for (const pkg of packages) {
214
+ checkDependencyVersionMismatch(pkg);
215
+ checkDependencyVersionRange(pkg);
214
216
  }
215
217
  };
216
218
  const checkDependencyVersionRange = ({ dependencies, devDependencies, name, peerDependencies }) => {
@@ -219,7 +221,7 @@ const checkDependencyVersionRange = ({ dependencies, devDependencies, name, peer
219
221
  consumedBy: name,
220
222
  name: dependencyName
221
223
  });
222
- if (version !== "workspace:*" && !isExcluded(version) && !/^\d/.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.`, {
224
+ if (version !== "workspace:*" && !isExcluded(version) && !/^\d/u.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.`, {
223
225
  consumedBy: name,
224
226
  name: dependencyName
225
227
  });
@@ -248,11 +250,11 @@ const checkDependencyVersionRange = ({ dependencies, devDependencies, name, peer
248
250
  const createPackagesVersionMismatchChecker = () => {
249
251
  const monorepoDependencies = /* @__PURE__ */ new Map();
250
252
  const monorepoDevelopmentDependencies = /* @__PURE__ */ new Map();
251
- const lint = (package_, type) => {
252
- const packageName = package_.name;
253
+ const lint = (pkg, type) => {
254
+ const packageName = pkg.name;
253
255
  const isDevelopment = type === "development";
254
256
  const store = isDevelopment ? monorepoDevelopmentDependencies : monorepoDependencies;
255
- const dependencies = package_[isDevelopment ? "devDependencies" : "dependencies"];
257
+ const dependencies = pkg[isDevelopment ? "devDependencies" : "dependencies"];
256
258
  for (const [dependencyName, dependencyVersion] of Object.entries(dependencies)) {
257
259
  if (!dependencyVersion) continue;
258
260
  const storedVersion = store.get(dependencyName);
@@ -266,9 +268,9 @@ const createPackagesVersionMismatchChecker = () => {
266
268
  });
267
269
  }
268
270
  };
269
- return (package_) => {
270
- lint(package_, "development");
271
- lint(package_, "production");
271
+ return (pkg) => {
272
+ lint(pkg, "development");
273
+ lint(pkg, "production");
272
274
  };
273
275
  };
274
276
  const createPackageError = (message, context) => {
@@ -281,7 +283,7 @@ function assertVersion(version, { consumedBy, name }) {
281
283
  }));
282
284
  }
283
285
  const isExcluded = (version) => {
284
- const isPreReleaseVersion = /\d+\.\d+\.\d+-(alpha|beta|experimental|next|rc).*/.exec(version);
286
+ const isPreReleaseVersion = /\d+\.\d+\.\d+-(alpha|beta|experimental|next|rc).*/u.exec(version);
285
287
  return version.startsWith("npm:") || isPreReleaseVersion;
286
288
  };
287
289
  const hasCaret = (version) => version.startsWith("^");
@@ -399,22 +401,24 @@ const createCleanCommand = (program) => {
399
401
  };
400
402
  const label$3 = (message) => `${message} ๐Ÿงน`;
401
403
  const cleanFiles = async (files) => {
402
- return Promise.all(files.map(async (file) => rm(file, {
403
- force: true,
404
- recursive: true
405
- })));
404
+ await Promise.all(files.map(async (file) => {
405
+ await rm(file, {
406
+ force: true,
407
+ recursive: true
408
+ });
409
+ }));
406
410
  };
407
411
  const isDirectoryExistAndNotEmpty = (path) => {
408
412
  return existsSync(path) && readdirSync(path).length > 0;
409
413
  };
410
414
  const retrieveIgnoredFiles = async () => {
411
- return (await helpers.exec("git clean -fdXn")).split(/\n|\r\n/).filter((cleanOutput) => PRESERVE_FILES.every((excludedFile) => !cleanOutput.includes(excludedFile))).map((cleanOutput) => cleanOutput.split(" ").at(-1));
415
+ return (await helpers.exec("git clean -fdXn")).split(/\n|\r\n/u).filter((cleanOutput) => PRESERVE_FILES.every((excludedFile) => !cleanOutput.includes(excludedFile))).map((cleanOutput) => cleanOutput.split(" ").at(-1) ?? "").filter(Boolean);
412
416
  };
413
417
  const PRESERVE_FILES = ["node_modules"];
414
418
 
415
419
  //#endregion
416
420
  //#region package.json
417
- var version = "2.40.0-next-7baa8ed";
421
+ var version = "2.40.0-next-314d883";
418
422
 
419
423
  //#endregion
420
424
  //#region src/commands/create.ts
@@ -455,7 +459,7 @@ const createCreateCommand = (program) => {
455
459
  }).task({
456
460
  async handler({ inputDescription, inputName, inputTemplate, inputUrl }) {
457
461
  if (!inputName) throw createError("stack create", "The project name is not optional. Make sure to provide a valid value (non-empty string).");
458
- const { repoName, repoOwner } = (inputUrl.startsWith("git") ? /^git@.*:(?<repoOwner>.*)\/(?<repoName>.*)\.git$/ : /^https?:\/\/.*\/(?<repoOwner>.*)\/(?<repoName>.*)\.git$/).exec(inputUrl)?.groups ?? {};
462
+ const { repoName, repoOwner } = (inputUrl.startsWith("git") ? /^git@.*:(?<repoOwner>.*)\/(?<repoName>.*)\.git$/u : /^https?:\/\/.*\/(?<repoOwner>.*)\/(?<repoName>.*)\.git$/u).exec(inputUrl)?.groups ?? {};
459
463
  if (!repoOwner || !repoName) throw createError("git", "The owner and repository name can not be extracted. Please make sure to follow either `/^git@.*:(?<repoOwner>.*)/(?<repoName>.*).git$/` or `/^https?://.*/(?<repoOwner>.*)/(?<repoName>.*).git$/` pattern.");
460
464
  const nodeVersion = await request.get("https://resolve-node.vercel.app/lts", "text");
461
465
  const { version: pnpmVersion } = await request.get("https://registry.npmjs.org/pnpm/latest", "json");
@@ -541,7 +545,7 @@ const createCreateCommand = (program) => {
541
545
  await helpers.exec(`pnpm add ${localDevelopmentDependencies.join(" ")} --save-dev --filter ${projectName}`);
542
546
  await helpers.exec("pnpm install");
543
547
  } catch (error) {
544
- throw createError("pnpm", error);
548
+ throw createError("pnpm", error instanceof Error ? error : new Error(String(error)));
545
549
  }
546
550
  },
547
551
  label: label$2("Install dependencies")
@@ -566,7 +570,7 @@ const createCreateCommand = (program) => {
566
570
  };
567
571
  const label$2 = (message) => `${message} ๐Ÿ”จ`;
568
572
  const slugify = (input) => {
569
- return input.toLowerCase().replaceAll(/[^a-z0-9\s-]/g, "").trim().replaceAll(/\s+/g, "-").replaceAll(/-+/g, "-");
573
+ return input.toLowerCase().replaceAll(/[^a-z0-9\s-]/gu, "").trim().replaceAll(/\s+/gu, "-").replaceAll(/-+/gu, "-");
570
574
  };
571
575
  const toCapitalLetter = (input) => {
572
576
  return input.charAt(0).toUpperCase() + input.slice(1);
@@ -586,7 +590,7 @@ const createTemplateEngine = async (workingPath, { projectName, templateModel, t
586
590
  return {
587
591
  async processContents() {
588
592
  await Promise.all(templateEntries.filter(({ type }) => type === "content").map(async (entry) => {
589
- return writeFile(entry.path, setTemplateVariables(entry, templateModel));
593
+ await writeFile(entry.path, setTemplateVariables(entry, templateModel));
590
594
  }));
591
595
  },
592
596
  async processPaths() {
@@ -621,7 +625,7 @@ const getTemplateEntries = async (path) => {
621
625
  content: await readFile(entryPath, "utf8"),
622
626
  type: "content"
623
627
  }]).map(({ content, type }) => {
624
- if (!hasTemplateVariable(content)) return void 0;
628
+ if (!hasTemplateVariable(content)) return;
625
629
  return {
626
630
  content,
627
631
  path: entryPath,
@@ -635,7 +639,7 @@ const setTemplateVariables = (entry, model) => {
635
639
  return model[dataModelKey] ?? match;
636
640
  });
637
641
  };
638
- const TEMPLATE_VARIABLE_MATCHER = /* @__PURE__ */ new RegExp(/{{(.*?)}}/g, "gi");
642
+ const TEMPLATE_VARIABLE_MATCHER = /\{\{(.*?)\}\}/giu;
639
643
  const hasTemplateVariable = (input) => {
640
644
  /**
641
645
  * TemplateVariableMatcher.test() is not used since the `RegExp` is stateful when the global is
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adbayb/stack",
3
- "version": "2.40.0-next-7baa8ed",
3
+ "version": "2.40.0-next-314d883",
4
4
  "description": "My opinionated JavaScript-based toolchain",
5
5
  "keywords": [
6
6
  "development",
@@ -45,17 +45,17 @@
45
45
  "dependencies": {
46
46
  "@changesets/changelog-github": "^0.7.0",
47
47
  "@changesets/cli": "^2.31.0",
48
- "@commitlint/cli": "^21.0.2",
49
- "@commitlint/config-conventional": "^21.0.2",
50
- "oxfmt": "^0.57.0",
51
- "oxlint": "^1.72.0",
48
+ "@commitlint/cli": "^21.2.1",
49
+ "@commitlint/config-conventional": "^21.2.0",
50
+ "oxfmt": "^0.58.0",
51
+ "oxlint": "^1.73.0",
52
52
  "oxlint-tsgolint": "^0.24.0",
53
53
  "termost": "^1.9.1",
54
- "turbo": "^2.9.18",
54
+ "turbo": "^2.10.4",
55
55
  "typescript": "^6.0.3"
56
56
  },
57
57
  "devDependencies": {
58
- "@types/node": "24.13.2",
58
+ "@types/node": "24.13.3",
59
59
  "quickbundle": "3.0.0"
60
60
  },
61
61
  "scripts": {
@@ -8,8 +8,8 @@ packages:
8
8
  publicHoistPattern:
9
9
  - "*changesets*"
10
10
  - "*commitlint*"
11
- - "*eslint*"
12
- - "*prettier*"
11
+ - "*oxfmt*"
12
+ - "*oxlint*"
13
13
  - "*turbo*"
14
14
  - "*typescript*"
15
15
  - "*types*"
@@ -7,8 +7,8 @@ packages:
7
7
  publicHoistPattern:
8
8
  - "*changesets*"
9
9
  - "*commitlint*"
10
- - "*eslint*"
11
- - "*prettier*"
10
+ - "*oxfmt*"
11
+ - "*oxlint*"
12
12
  - "*turbo*"
13
13
  - "*typescript*"
14
14
  - "*types*"