@adbayb/stack 2.39.0-next-b0fcf5b → 2.39.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.
- package/dist/index.js +78 -150
- package/package.json +2 -1
- package/templates/multi-projects/.npmrc.tmpl +1 -0
- package/templates/{single-project/package.json → multi-projects/package.json.tmpl} +11 -6
- package/templates/multi-projects/{pnpm-workspace.yaml → pnpm-workspace.yaml.tmpl} +0 -5
- package/templates/single-project/.npmrc.tmpl +1 -0
- package/templates/{multi-projects/package.json → single-project/package.json.tmpl} +11 -6
- package/templates/single-project/{pnpm-workspace.yaml → pnpm-workspace.yaml.tmpl} +0 -5
- /package/templates/multi-projects/.changeset/{config.json → config.json.tmpl} +0 -0
- /package/templates/multi-projects/.changeset/{welcome.md → welcome.md.tmpl} +0 -0
- /package/templates/multi-projects/.github/{PULL_REQUEST_TEMPLATE.md → PULL_REQUEST_TEMPLATE.md.tmpl} +0 -0
- /package/templates/multi-projects/{.nvmrc → .nvmrc.tmpl} +0 -0
- /package/templates/multi-projects/{CONTRIBUTING.md → CONTRIBUTING.md.tmpl} +0 -0
- /package/templates/multi-projects/{LICENSE → LICENSE.tmpl} +0 -0
- /package/templates/multi-projects/examples/default/{package.json → package.json.tmpl} +0 -0
- /package/templates/multi-projects/examples/default/src/{index.ts → index.ts.tmpl} +0 -0
- /package/templates/multi-projects/libraries/{{projectName}}/{README.md → README.md.tmpl} +0 -0
- /package/templates/multi-projects/libraries/{{projectName}}/{package.json → package.json.tmpl} +0 -0
- /package/templates/multi-projects/libraries/{{projectName}}/src/{index.test.ts → index.test.ts.tmpl} +0 -0
- /package/templates/single-project/.changeset/{config.json → config.json.tmpl} +0 -0
- /package/templates/single-project/.changeset/{welcome.md → welcome.md.tmpl} +0 -0
- /package/templates/single-project/.github/{PULL_REQUEST_TEMPLATE.md → PULL_REQUEST_TEMPLATE.md.tmpl} +0 -0
- /package/templates/single-project/{.nvmrc → .nvmrc.tmpl} +0 -0
- /package/templates/single-project/{CONTRIBUTING.md → CONTRIBUTING.md.tmpl} +0 -0
- /package/templates/single-project/{LICENSE → LICENSE.tmpl} +0 -0
- /package/templates/single-project/examples/default/{package.json → package.json.tmpl} +0 -0
- /package/templates/single-project/examples/default/src/{index.ts → index.ts.tmpl} +0 -0
- /package/templates/single-project/{{projectName}}/{README.md → README.md.tmpl} +0 -0
- /package/templates/single-project/{{projectName}}/{package.json → package.json.tmpl} +0 -0
- /package/templates/single-project/{{projectName}}/src/{index.test.ts → index.test.ts.tmpl} +0 -0
package/dist/index.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { helpers, termost } from "termost";
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
|
-
import {
|
|
4
|
-
import { existsSync, readdirSync } from "node:fs";
|
|
5
|
-
import { chmod,
|
|
3
|
+
import { join, resolve } from "node:path";
|
|
4
|
+
import { cpSync, existsSync, readFileSync, readdirSync, renameSync, writeFileSync } from "node:fs";
|
|
5
|
+
import { chmod, mkdir, rm, symlink, writeFile } from "node:fs/promises";
|
|
6
|
+
import { fdir } from "fdir";
|
|
6
7
|
|
|
7
8
|
//#region src/helpers.ts
|
|
8
9
|
const require = createRequire(import.meta.url);
|
|
@@ -48,20 +49,20 @@ ${input.body}
|
|
|
48
49
|
* @param path - The relative path.
|
|
49
50
|
* @returns The resolved absolute path.
|
|
50
51
|
* @example
|
|
51
|
-
*
|
|
52
|
+
* resolveFromProjectDirectory(".gitignore");
|
|
52
53
|
*/
|
|
53
|
-
const
|
|
54
|
-
return resolve(process.cwd(),
|
|
54
|
+
const resolveFromProjectDirectory = (path) => {
|
|
55
|
+
return resolve(process.cwd(), path);
|
|
55
56
|
};
|
|
56
57
|
/**
|
|
57
58
|
* Resolve a relative path to an absolute one resolved from the `stack` node module directory.
|
|
58
59
|
* @param path - The relative path.
|
|
59
60
|
* @returns The resolved absolute path.
|
|
60
61
|
* @example
|
|
61
|
-
*
|
|
62
|
+
* resolveFromStackDirectory("./templates");
|
|
62
63
|
*/
|
|
63
|
-
const
|
|
64
|
-
return resolve(import.meta.dirname, "../",
|
|
64
|
+
const resolveFromStackDirectory = (path) => {
|
|
65
|
+
return resolve(import.meta.dirname, "../", path);
|
|
65
66
|
};
|
|
66
67
|
const createError = (bin, error) => {
|
|
67
68
|
const errorMessage = `\`${bin}\` command failed.\n${String(error)}`;
|
|
@@ -71,7 +72,7 @@ const createError = (bin, error) => {
|
|
|
71
72
|
}
|
|
72
73
|
return new Error(errorMessage);
|
|
73
74
|
};
|
|
74
|
-
const
|
|
75
|
+
const getNpmVersion = async () => {
|
|
75
76
|
try {
|
|
76
77
|
return await helpers.exec("pnpm -v");
|
|
77
78
|
} catch {
|
|
@@ -89,7 +90,7 @@ const setPackageManager = async () => {
|
|
|
89
90
|
* Corepack is downloaded remotely to get always up-to-date npm registry fingerprints since they're hardcoded.
|
|
90
91
|
* @see {@link https://github.com/nodejs/corepack/issues/613}
|
|
91
92
|
*/
|
|
92
|
-
return helpers.exec("
|
|
93
|
+
return helpers.exec("npx corepack enable");
|
|
93
94
|
};
|
|
94
95
|
const request = { async get(url, responseType) {
|
|
95
96
|
const response = await fetch(url);
|
|
@@ -111,7 +112,7 @@ const eslint = (options) => async (files = []) => {
|
|
|
111
112
|
const arguments_ = [
|
|
112
113
|
...eslintFiles,
|
|
113
114
|
"--cache",
|
|
114
|
-
`--cache-location ${
|
|
115
|
+
`--cache-location ${resolveFromProjectDirectory("node_modules/.cache/.eslintcache")}`,
|
|
115
116
|
"--no-error-on-unmatched-pattern"
|
|
116
117
|
];
|
|
117
118
|
if (options.isFixMode) arguments_.push("--fix");
|
|
@@ -381,7 +382,7 @@ const createCleanCommand = (program) => {
|
|
|
381
382
|
async handler() {
|
|
382
383
|
const cachePath = "node_modules/.cache";
|
|
383
384
|
const files = await retrieveIgnoredFiles();
|
|
384
|
-
if (isDirectoryExistAndNotEmpty(
|
|
385
|
+
if (isDirectoryExistAndNotEmpty(resolveFromProjectDirectory(cachePath))) files.push(cachePath);
|
|
385
386
|
return files;
|
|
386
387
|
},
|
|
387
388
|
key: "files",
|
|
@@ -427,7 +428,7 @@ const PRESERVE_FILES = ["node_modules"];
|
|
|
427
428
|
|
|
428
429
|
//#endregion
|
|
429
430
|
//#region package.json
|
|
430
|
-
var version = "2.39.0
|
|
431
|
+
var version = "2.39.0";
|
|
431
432
|
|
|
432
433
|
//#endregion
|
|
433
434
|
//#region src/commands/create.ts
|
|
@@ -438,12 +439,12 @@ const createCreateCommand = (program) => {
|
|
|
438
439
|
}).task({ handler() {
|
|
439
440
|
botMessage({
|
|
440
441
|
description: "I can guarantee you a project creation in under 1 minute 🚀",
|
|
441
|
-
title: `I'm Stack v${version}
|
|
442
|
+
title: `I'm Stack v${version}, your bot assistant`,
|
|
442
443
|
type: "information"
|
|
443
444
|
});
|
|
444
445
|
} }).task({
|
|
445
446
|
async handler() {
|
|
446
|
-
await
|
|
447
|
+
await getNpmVersion();
|
|
447
448
|
},
|
|
448
449
|
label: label$2("Check pre-requisites")
|
|
449
450
|
}).input({
|
|
@@ -466,92 +467,61 @@ const createCreateCommand = (program) => {
|
|
|
466
467
|
options: ["single-project", "multi-projects"],
|
|
467
468
|
type: "select"
|
|
468
469
|
}).task({
|
|
469
|
-
async handler({ inputDescription, inputName,
|
|
470
|
+
async handler({ inputDescription, inputName, inputUrl }) {
|
|
470
471
|
if (!inputName) throw createError("stack create", "The project name is not optional. Make sure to provide a valid value (non-empty string).");
|
|
471
472
|
const { repoName, repoOwner } = (inputUrl.startsWith("git") ? /^git@.*:(?<repoOwner>.*)\/(?<repoName>.*)\.git$/ : /^https?:\/\/.*\/(?<repoOwner>.*)\/(?<repoName>.*)\.git$/).exec(inputUrl)?.groups ?? {};
|
|
472
473
|
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.");
|
|
473
474
|
const nodeVersion = await request.get("https://resolve-node.vercel.app/lts", "text");
|
|
474
|
-
const { version:
|
|
475
|
-
const projectName = slugify(inputName);
|
|
475
|
+
const { version: npmVersion } = await request.get("https://registry.npmjs.org/pnpm/latest", "json");
|
|
476
476
|
return {
|
|
477
477
|
licenseYear: (/* @__PURE__ */ new Date()).getFullYear().toString(),
|
|
478
478
|
nodeVersion: nodeVersion.replace("v", ""),
|
|
479
|
-
|
|
480
|
-
projectDescription:
|
|
481
|
-
projectName,
|
|
479
|
+
npmVersion: String(npmVersion),
|
|
480
|
+
projectDescription: inputDescription.charAt(0).toUpperCase() + inputDescription.slice(1),
|
|
481
|
+
projectName: inputName.toLowerCase(),
|
|
482
482
|
projectUrl: inputUrl,
|
|
483
|
-
repoId: `${repoOwner}/${repoName}
|
|
484
|
-
templatePath: resolveFromPackageDirectory("templates", inputTemplate),
|
|
485
|
-
workingPath: resolveFromWorkingDirectory(projectName)
|
|
483
|
+
repoId: `${repoOwner}/${repoName}`
|
|
486
484
|
};
|
|
487
485
|
},
|
|
488
486
|
key: "data",
|
|
489
487
|
label: label$2("Check and format input")
|
|
490
|
-
}).
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
},
|
|
496
|
-
skip({ data: { workingPath } }) {
|
|
497
|
-
return !existsSync(workingPath);
|
|
488
|
+
}).task({
|
|
489
|
+
async handler({ data }) {
|
|
490
|
+
const projectPath = resolve(process.cwd(), data.projectName);
|
|
491
|
+
await mkdir(projectPath);
|
|
492
|
+
process.chdir(projectPath);
|
|
498
493
|
},
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
if (canRemoveExistingDirectoryInput) return;
|
|
502
|
-
return createError("mkdir", `Remove or rename the \`${projectName}\` existing directory to apply the template from a clean state.`);
|
|
494
|
+
label({ data }) {
|
|
495
|
+
return label$2(`Create \`${data.projectName}\` folder`);
|
|
503
496
|
}
|
|
504
497
|
}).task({
|
|
505
|
-
async handler({
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
recursive: true
|
|
509
|
-
});
|
|
510
|
-
return createTemplateEngine(workingPath, {
|
|
511
|
-
projectName,
|
|
512
|
-
templateModel: {
|
|
513
|
-
licenseYear,
|
|
514
|
-
nodeVersion,
|
|
515
|
-
pnpmVersion,
|
|
516
|
-
projectDescription,
|
|
517
|
-
projectName,
|
|
518
|
-
projectUrl,
|
|
519
|
-
repoId
|
|
520
|
-
},
|
|
521
|
-
templateName: inputTemplate,
|
|
522
|
-
templatePath
|
|
523
|
-
});
|
|
498
|
+
async handler({ data }) {
|
|
499
|
+
await helpers.exec("git init");
|
|
500
|
+
await helpers.exec(`git remote add origin ${data.projectUrl}`);
|
|
524
501
|
},
|
|
525
|
-
|
|
526
|
-
label({ data: { projectName }, inputTemplate }) {
|
|
527
|
-
return label$2(`Copy \`${inputTemplate}\` template to \`${projectName}\` directory`);
|
|
528
|
-
}
|
|
502
|
+
label: label$2("Initialize `git`")
|
|
529
503
|
}).task({
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
await templateEngine.processPaths();
|
|
504
|
+
handler({ data, inputTemplate }) {
|
|
505
|
+
applyTemplate(inputTemplate, data);
|
|
533
506
|
},
|
|
534
|
-
label()
|
|
535
|
-
return label$2("Process template");
|
|
536
|
-
}
|
|
507
|
+
label: label$2("Apply template")
|
|
537
508
|
}).task({
|
|
538
|
-
async handler({ data: {
|
|
539
|
-
await
|
|
540
|
-
await helpers.exec(`git remote add origin ${projectUrl}`);
|
|
509
|
+
async handler({ data: { projectName }, inputTemplate }) {
|
|
510
|
+
await symlink(join(inputTemplate === "single-project" ? projectName : join("libraries", projectName), "README.md"), "./README.md");
|
|
541
511
|
},
|
|
542
|
-
label: label$2("
|
|
512
|
+
label: label$2("Create a symlink to `README.md` file")
|
|
543
513
|
}).task({
|
|
544
514
|
async handler() {
|
|
545
515
|
await setPackageManager();
|
|
546
516
|
},
|
|
547
517
|
label: label$2("Set up the package manager")
|
|
548
518
|
}).task({
|
|
549
|
-
async handler({ data
|
|
519
|
+
async handler({ data }) {
|
|
550
520
|
const localDevelopmentDependencies = ["quickbundle", "vitest"];
|
|
551
521
|
const globalDevelopmentDependencies = ["@adbayb/stack"];
|
|
552
522
|
try {
|
|
553
523
|
await helpers.exec(`pnpm add ${globalDevelopmentDependencies.join(" ")} --save-dev --ignore-workspace-root-check`);
|
|
554
|
-
await helpers.exec(`pnpm add ${localDevelopmentDependencies.join(" ")} --save-dev --filter ${projectName}`);
|
|
524
|
+
await helpers.exec(`pnpm add ${localDevelopmentDependencies.join(" ")} --save-dev --filter ${data.projectName}`);
|
|
555
525
|
await helpers.exec("pnpm install");
|
|
556
526
|
} catch (error) {
|
|
557
527
|
throw createError("pnpm", error);
|
|
@@ -569,95 +539,53 @@ const createCreateCommand = (program) => {
|
|
|
569
539
|
await helpers.exec("git commit -m \"chore: initial commit\"");
|
|
570
540
|
},
|
|
571
541
|
label: label$2("Commit")
|
|
572
|
-
}).task({ handler({ data
|
|
542
|
+
}).task({ handler({ data }) {
|
|
573
543
|
botMessage({
|
|
574
|
-
description: `Run \`cd ./${projectName}\` and Enjoy 🚀`,
|
|
544
|
+
description: `Run \`cd ./${data.projectName}\` and Enjoy 🚀`,
|
|
575
545
|
title: "The project was successfully created",
|
|
576
546
|
type: "success"
|
|
577
547
|
});
|
|
578
548
|
} });
|
|
579
549
|
};
|
|
580
550
|
const label$2 = (message) => `${message} 🔨`;
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
551
|
+
/**
|
|
552
|
+
* A simple template engine to evaluate dynamic expressions and apply side effets (such as hydrating a content with values from an input object) on impacted template files.
|
|
553
|
+
* @param template - The selected template.
|
|
554
|
+
* @param dataModel - Data model mapping the template expression key with its corresponding value.
|
|
555
|
+
* @example
|
|
556
|
+
* applyTemplate(
|
|
557
|
+
* { toReplace: "value" },
|
|
558
|
+
* );
|
|
559
|
+
*/
|
|
560
|
+
const applyTemplate = (template, dataModel) => {
|
|
561
|
+
const templateExtension = ".tmpl";
|
|
562
|
+
const templateRootPath = resolveFromStackDirectory(join("./templates", template));
|
|
563
|
+
const projectRootPath = resolveFromProjectDirectory("./");
|
|
564
|
+
const templateExpressionRegExp = /{{(.*?)}}/g;
|
|
565
|
+
const evaluate = (content) => {
|
|
566
|
+
return content.replaceAll(templateExpressionRegExp, (_, key) => dataModel[key] || "");
|
|
567
|
+
};
|
|
568
|
+
/** Copy the template before mutations. */
|
|
569
|
+
cpSync(templateRootPath, projectRootPath, {
|
|
590
570
|
force: true,
|
|
591
571
|
recursive: true
|
|
592
572
|
});
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
return {
|
|
600
|
-
async processContents() {
|
|
601
|
-
await Promise.all(templateEntries.filter(({ type }) => type === "content").map(async (entry) => {
|
|
602
|
-
return writeFile(entry.path, setTemplateVariables(entry, templateModel));
|
|
603
|
-
}));
|
|
604
|
-
},
|
|
605
|
-
async processPaths() {
|
|
606
|
-
const sortedDirectoryEntries = templateEntries.filter(({ content, type }) => {
|
|
607
|
-
if (type === "path.directory" || type === "path.file") return hasTemplateVariable(basename(content));
|
|
608
|
-
return false;
|
|
609
|
-
}).toSorted(({ path: pathA }, { path: pathB }) => pathB.length - pathA.length);
|
|
610
|
-
for (const entry of sortedDirectoryEntries) {
|
|
611
|
-
const newPath = setTemplateVariables(entry, templateModel);
|
|
612
|
-
await rename(entry.path, newPath);
|
|
613
|
-
}
|
|
614
|
-
await symlink(join(templateName === "single-project" ? projectName : join("libraries", projectName), "README.md"), "./README.md");
|
|
615
|
-
}
|
|
616
|
-
};
|
|
617
|
-
};
|
|
618
|
-
const getTemplateEntries = async (path) => {
|
|
619
|
-
const entries = await readdir(path, {
|
|
620
|
-
recursive: true,
|
|
621
|
-
withFileTypes: true
|
|
573
|
+
/** Template file mutations. */
|
|
574
|
+
new fdir().withBasePath().glob(`**/*${templateExtension}`).crawl(projectRootPath).sync().forEach((templateFilePath) => {
|
|
575
|
+
const projectFilePath = templateFilePath.slice(0, templateFilePath.lastIndexOf(templateExtension));
|
|
576
|
+
const content = evaluate(readFileSync(templateFilePath, "utf8"));
|
|
577
|
+
renameSync(templateFilePath, projectFilePath);
|
|
578
|
+
writeFileSync(projectFilePath, content, "utf8");
|
|
622
579
|
});
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
}] : [{
|
|
631
|
-
content: entryPath,
|
|
632
|
-
type: "path.file"
|
|
633
|
-
}, {
|
|
634
|
-
content: await readFile(entryPath, "utf8"),
|
|
635
|
-
type: "content"
|
|
636
|
-
}]).map(({ content, type }) => {
|
|
637
|
-
if (!hasTemplateVariable(content)) return void 0;
|
|
638
|
-
return {
|
|
639
|
-
content,
|
|
640
|
-
path: entryPath,
|
|
641
|
-
type
|
|
642
|
-
};
|
|
643
|
-
}).filter((input) => Boolean(input));
|
|
644
|
-
}))).flat();
|
|
645
|
-
};
|
|
646
|
-
const setTemplateVariables = (entry, model) => {
|
|
647
|
-
return entry.content.replaceAll(TEMPLATE_VARIABLE_MATCHER, (match, dataModelKey) => {
|
|
648
|
-
return model[dataModelKey] ?? match;
|
|
580
|
+
/** Template folder mutations. */
|
|
581
|
+
new fdir().withBasePath().onlyDirs().filter((path) => {
|
|
582
|
+
return templateExpressionRegExp.test(path);
|
|
583
|
+
}).crawl(projectRootPath).sync().toSorted((a, b) => b.length - a.length).forEach((templateFolderPath) => {
|
|
584
|
+
renameSync(templateFolderPath, templateFolderPath.replaceAll(templateExpressionRegExp, (_, dataModelKey) => {
|
|
585
|
+
return dataModel[dataModelKey];
|
|
586
|
+
}));
|
|
649
587
|
});
|
|
650
588
|
};
|
|
651
|
-
const TEMPLATE_VARIABLE_MATCHER = /* @__PURE__ */ new RegExp(/{{(.*?)}}/g, "gi");
|
|
652
|
-
const hasTemplateVariable = (input) => {
|
|
653
|
-
/**
|
|
654
|
-
* TemplateVariableMatcher.test() is not used since the `RegExp` is stateful when the global is used leading to some unstable results
|
|
655
|
-
* (relying on latest `lastIndex` set (lastIndex specifies the index at which to start the next match)).
|
|
656
|
-
* String.search is stateless.
|
|
657
|
-
* @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test MDN documentation}.
|
|
658
|
-
*/
|
|
659
|
-
return input.search(TEMPLATE_VARIABLE_MATCHER) >= 0;
|
|
660
|
-
};
|
|
661
589
|
|
|
662
590
|
//#endregion
|
|
663
591
|
//#region src/commands/fix/fixFormatting.ts
|
|
@@ -672,7 +600,7 @@ const fixFormatting = async (files) => {
|
|
|
672
600
|
if (prettierFiles.length === 0) return;
|
|
673
601
|
}
|
|
674
602
|
const arguments_ = [...prettierFiles];
|
|
675
|
-
if (existsSync(
|
|
603
|
+
if (existsSync(resolveFromProjectDirectory(".gitignore"))) arguments_.push("--ignore-path .gitignore");
|
|
676
604
|
arguments_.push("--write", "--ignore-unknown", "--no-error-on-unmatched-pattern");
|
|
677
605
|
try {
|
|
678
606
|
return await helpers.exec(`prettier ${arguments_.join(" ")}`);
|
|
@@ -735,7 +663,7 @@ const createInstallCommand = (program) => {
|
|
|
735
663
|
};
|
|
736
664
|
const label = (message) => `${message} 📲`;
|
|
737
665
|
const installGitHook = async (hook, content) => {
|
|
738
|
-
const filename =
|
|
666
|
+
const filename = resolveFromProjectDirectory(`.git/hooks/${hook}`);
|
|
739
667
|
await writeFile(filename, content);
|
|
740
668
|
return chmod(filename, "0755");
|
|
741
669
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adbayb/stack",
|
|
3
|
-
"version": "2.39.0
|
|
3
|
+
"version": "2.39.0",
|
|
4
4
|
"description": "My opinionated JavaScript-based toolchain",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"stack",
|
|
@@ -59,6 +59,7 @@
|
|
|
59
59
|
"eslint-plugin-prettier": "^5.5.6",
|
|
60
60
|
"eslint-plugin-sonarjs": "^4.1.0",
|
|
61
61
|
"eslint-plugin-unicorn": "^68.0.0",
|
|
62
|
+
"fdir": "^6.5.0",
|
|
62
63
|
"globals": "^17.6.0",
|
|
63
64
|
"prettier": "^3.8.4",
|
|
64
65
|
"prettier-plugin-packagejson": "^3.0.2",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
save-exact=true
|
|
@@ -17,13 +17,18 @@
|
|
|
17
17
|
"watch": "stack watch"
|
|
18
18
|
},
|
|
19
19
|
"prettier": "@adbayb/stack/prettier",
|
|
20
|
-
"packageManager": "pnpm@{{
|
|
20
|
+
"packageManager": "pnpm@{{npmVersion}}",
|
|
21
21
|
"devEngines": {
|
|
22
|
-
"packageManager":
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
"packageManager": [
|
|
23
|
+
{
|
|
24
|
+
"name": "pnpm",
|
|
25
|
+
"version": "{{npmVersion}}",
|
|
26
|
+
"onFail": "download"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"name": "npm"
|
|
30
|
+
}
|
|
31
|
+
],
|
|
27
32
|
"runtime": {
|
|
28
33
|
"name": "node",
|
|
29
34
|
"version": ">=24.0.0",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
save-exact=true
|
|
@@ -17,13 +17,18 @@
|
|
|
17
17
|
"watch": "stack watch"
|
|
18
18
|
},
|
|
19
19
|
"prettier": "@adbayb/stack/prettier",
|
|
20
|
-
"packageManager": "pnpm@{{
|
|
20
|
+
"packageManager": "pnpm@{{npmVersion}}",
|
|
21
21
|
"devEngines": {
|
|
22
|
-
"packageManager":
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
"packageManager": [
|
|
23
|
+
{
|
|
24
|
+
"name": "pnpm",
|
|
25
|
+
"version": "{{npmVersion}}",
|
|
26
|
+
"onFail": "download"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"name": "npm"
|
|
30
|
+
}
|
|
31
|
+
],
|
|
27
32
|
"runtime": {
|
|
28
33
|
"name": "node",
|
|
29
34
|
"version": ">=24.0.0",
|
|
File without changes
|
|
File without changes
|
/package/templates/multi-projects/.github/{PULL_REQUEST_TEMPLATE.md → PULL_REQUEST_TEMPLATE.md.tmpl}
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/templates/multi-projects/libraries/{{projectName}}/{package.json → package.json.tmpl}
RENAMED
|
File without changes
|
/package/templates/multi-projects/libraries/{{projectName}}/src/{index.test.ts → index.test.ts.tmpl}
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/templates/single-project/.github/{PULL_REQUEST_TEMPLATE.md → PULL_REQUEST_TEMPLATE.md.tmpl}
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|