vyriy 0.3.8 → 0.4.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/README.md +74 -172
- package/bin/vyriy.js +2 -2
- package/cli/args.js +29 -0
- package/cli/cli.d.ts +2 -2
- package/cli/cli.js +18 -64
- package/cli/index.d.ts +1 -1
- package/cli/index.js +1 -1
- package/cli/types.d.ts +12 -3
- package/commands/check-env.d.ts +2 -0
- package/commands/check-env.js +65 -0
- package/commands/create/index.d.ts +2 -0
- package/commands/create/index.js +121 -0
- package/commands/create/plan/index.d.ts +4 -0
- package/commands/create/plan/index.js +3 -0
- package/commands/create/plan/plan.d.ts +9 -0
- package/commands/create/plan/plan.js +34 -0
- package/commands/create/plan/question.d.ts +2 -0
- package/commands/create/plan/question.js +25 -0
- package/commands/create/plan/types.d.ts +14 -0
- package/commands/create/preset/api.d.ts +2 -0
- package/commands/create/preset/api.js +16 -0
- package/commands/create/preset/base.d.ts +2 -0
- package/commands/create/preset/base.js +195 -0
- package/commands/create/preset/gql.d.ts +2 -0
- package/commands/create/preset/gql.js +16 -0
- package/commands/create/preset/index.d.ts +12 -0
- package/commands/create/preset/index.js +14 -0
- package/commands/create/preset/library.d.ts +2 -0
- package/commands/create/preset/library.js +227 -0
- package/commands/create/preset/mfe.d.ts +2 -0
- package/commands/create/preset/mfe.js +16 -0
- package/commands/create/preset/rest.d.ts +2 -0
- package/commands/create/preset/rest.js +16 -0
- package/commands/create/preset/spa.d.ts +2 -0
- package/commands/create/preset/spa.js +16 -0
- package/commands/create/preset/ssg.d.ts +2 -0
- package/commands/create/preset/ssg.js +16 -0
- package/commands/create/preset/ssr.d.ts +2 -0
- package/commands/create/preset/ssr.js +16 -0
- package/commands/create/preset/types.d.ts +15 -0
- package/commands/create/prompt/conflict-strategy.d.ts +5 -0
- package/commands/create/prompt/conflict-strategy.js +22 -0
- package/commands/create/prompt/index.d.ts +7 -0
- package/commands/create/prompt/index.js +6 -0
- package/commands/create/prompt/preset.d.ts +4 -0
- package/commands/create/prompt/preset.js +11 -0
- package/commands/create/prompt/prompt.d.ts +2 -0
- package/commands/create/prompt/prompt.js +4 -0
- package/commands/create/prompt/provider.d.ts +2 -0
- package/commands/create/prompt/provider.js +13 -0
- package/commands/create/prompt/resolve-option.d.ts +6 -0
- package/commands/create/prompt/resolve-option.js +8 -0
- package/commands/create/prompt/scope.d.ts +2 -0
- package/commands/create/prompt/scope.js +2 -0
- package/commands/create/prompt/types.d.ts +4 -0
- package/commands/dist.d.ts +2 -0
- package/commands/dist.js +274 -0
- package/commands/help.d.ts +3 -0
- package/commands/help.js +24 -0
- package/commands/index.d.ts +5 -0
- package/commands/index.js +5 -0
- package/commands/types.d.ts +45 -0
- package/commands/version.d.ts +2 -0
- package/commands/version.js +6 -0
- package/package.json +341 -464
- package/checks/node/index.d.ts +0 -2
- package/checks/node/index.js +0 -1
- package/checks/node/node.d.ts +0 -2
- package/checks/node/node.js +0 -22
- package/checks/node/types.d.ts +0 -11
- package/checks/yarn/index.d.ts +0 -2
- package/checks/yarn/index.js +0 -1
- package/checks/yarn/types.d.ts +0 -7
- package/checks/yarn/yarn.d.ts +0 -2
- package/checks/yarn/yarn.js +0 -40
- package/cli/args/args.js +0 -38
- package/cli/args/index.d.ts +0 -2
- package/cli/args/index.js +0 -1
- package/cli/args/types.d.ts +0 -24
- package/commands/doctor/doctor.d.ts +0 -2
- package/commands/doctor/doctor.js +0 -9
- package/commands/doctor/index.d.ts +0 -2
- package/commands/doctor/index.js +0 -1
- package/commands/doctor/types.d.ts +0 -8
- package/commands/init/index.d.ts +0 -2
- package/commands/init/index.js +0 -1
- package/commands/init/init.d.ts +0 -2
- package/commands/init/init.js +0 -7
- package/commands/init/types.d.ts +0 -5
- package/commands/new/index.d.ts +0 -2
- package/commands/new/index.js +0 -1
- package/commands/new/new.d.ts +0 -3
- package/commands/new/new.js +0 -189
- package/commands/new/types.d.ts +0 -15
- package/doctor/checkCorepack.d.ts +0 -2
- package/doctor/checkCorepack.js +0 -24
- package/doctor/checkGit.d.ts +0 -2
- package/doctor/checkGit.js +0 -23
- package/doctor/checkNodeVersion.d.ts +0 -5
- package/doctor/checkNodeVersion.js +0 -24
- package/doctor/checkYarn.d.ts +0 -10
- package/doctor/checkYarn.js +0 -45
- package/doctor/createDoctorReport.d.ts +0 -2
- package/doctor/createDoctorReport.js +0 -17
- package/doctor/index.d.ts +0 -7
- package/doctor/index.js +0 -6
- package/doctor/printDoctorReport.d.ts +0 -2
- package/doctor/printDoctorReport.js +0 -42
- package/doctor/types.d.ts +0 -25
- package/file-plan/createFilePlan.d.ts +0 -4
- package/file-plan/createFilePlan.js +0 -29
- package/file-plan/index.d.ts +0 -4
- package/file-plan/index.js +0 -3
- package/file-plan/printFilePlan.d.ts +0 -2
- package/file-plan/printFilePlan.js +0 -44
- package/file-plan/types.d.ts +0 -12
- package/file-plan/writeFilePlan.d.ts +0 -2
- package/file-plan/writeFilePlan.js +0 -12
- package/index.d.ts +0 -11
- package/index.js +0 -11
- package/presets/agentsTemplate.d.ts +0 -1
- package/presets/agentsTemplate.js +0 -105
- package/presets/createProjectFiles.d.ts +0 -2
- package/presets/createProjectFiles.js +0 -408
- package/presets/index.d.ts +0 -2
- package/presets/index.js +0 -1
- package/presets/types.d.ts +0 -3
- package/project-plan/api/api.d.ts +0 -6
- package/project-plan/api/api.js +0 -44
- package/project-plan/api/index.d.ts +0 -2
- package/project-plan/api/index.js +0 -1
- package/project-plan/api/types.d.ts +0 -11
- package/project-plan/ci/ci.d.ts +0 -3
- package/project-plan/ci/ci.js +0 -20
- package/project-plan/ci/index.d.ts +0 -2
- package/project-plan/ci/index.js +0 -1
- package/project-plan/ci/types.d.ts +0 -6
- package/project-plan/create/create.d.ts +0 -2
- package/project-plan/create/create.js +0 -129
- package/project-plan/create/index.d.ts +0 -2
- package/project-plan/create/index.js +0 -1
- package/project-plan/create/types.d.ts +0 -13
- package/project-plan/index.d.ts +0 -6
- package/project-plan/index.js +0 -5
- package/project-plan/kind/index.d.ts +0 -2
- package/project-plan/kind/index.js +0 -1
- package/project-plan/kind/kind.d.ts +0 -2
- package/project-plan/kind/kind.js +0 -1
- package/project-plan/kind/types.d.ts +0 -2
- package/project-plan/print/index.d.ts +0 -2
- package/project-plan/print/index.js +0 -1
- package/project-plan/print/print.d.ts +0 -2
- package/project-plan/print/print.js +0 -47
- package/project-plan/print/types.d.ts +0 -2
- package/project-plan/types.d.ts +0 -46
- package/prompts/project-plan/index.d.ts +0 -2
- package/prompts/project-plan/index.js +0 -1
- package/prompts/project-plan/project-plan.d.ts +0 -2
- package/prompts/project-plan/project-plan.js +0 -194
- package/prompts/project-plan/types.d.ts +0 -18
- package/shared/commandExists.d.ts +0 -2
- package/shared/commandExists.js +0 -10
- package/shared/execCommand.d.ts +0 -2
- package/shared/execCommand.js +0 -7
- package/shared/fileExists.d.ts +0 -2
- package/shared/fileExists.js +0 -10
- package/shared/index.d.ts +0 -6
- package/shared/index.js +0 -5
- package/shared/runCommand.d.ts +0 -9
- package/shared/runCommand.js +0 -34
- package/shared/semver.d.ts +0 -1
- package/shared/semver.js +0 -4
- package/shared/types.d.ts +0 -12
- /package/cli/{args/args.d.ts → args.d.ts} +0 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { PlanResult } from '../plan/types.js';
|
|
2
|
+
export type FileMap = Record<string, string>;
|
|
3
|
+
export type CiProvider = 'gitlab' | 'github';
|
|
4
|
+
export type DeployProvider = 'aws' | 'docker';
|
|
5
|
+
export type Preset = {
|
|
6
|
+
files: (options: PlanResult) => FileMap;
|
|
7
|
+
ci: Partial<Record<CiProvider, FileMap>>;
|
|
8
|
+
deploy: Partial<Record<DeployProvider, FileMap>>;
|
|
9
|
+
};
|
|
10
|
+
export type PresetKey = 'base' | 'library' | 'api' | 'ssr' | 'rest' | 'gql' | 'ssg' | 'spa' | 'mfe';
|
|
11
|
+
export type Presets = Partial<Record<PresetKey, {
|
|
12
|
+
name: string;
|
|
13
|
+
description: string;
|
|
14
|
+
preset: Preset;
|
|
15
|
+
}>>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { stdin, stdout } from 'node:process';
|
|
2
|
+
import { createInterface } from 'node:readline/promises';
|
|
3
|
+
export const conflictStrategy = async () => {
|
|
4
|
+
console.log('\nWhat should Vyriy do?\n');
|
|
5
|
+
console.log(' 1. overwrite existing files');
|
|
6
|
+
console.log(' 2. skip existing files');
|
|
7
|
+
console.log(' 3. abort');
|
|
8
|
+
const readline = createInterface({ input: stdin, output: stdout });
|
|
9
|
+
try {
|
|
10
|
+
const answer = (await readline.question('\nWhat should Vyriy do? (abort): ')).trim().toLowerCase();
|
|
11
|
+
if (answer === '1' || answer === 'overwrite') {
|
|
12
|
+
return { overwrite: true, skipExisting: false };
|
|
13
|
+
}
|
|
14
|
+
if (answer === '2' || answer === 'skip') {
|
|
15
|
+
return { overwrite: false, skipExisting: true };
|
|
16
|
+
}
|
|
17
|
+
return undefined;
|
|
18
|
+
}
|
|
19
|
+
finally {
|
|
20
|
+
readline.close();
|
|
21
|
+
}
|
|
22
|
+
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { presets as appPreset } from '../preset/index.js';
|
|
2
|
+
import type { PromptOutput, PromptQuestion } from './types.js';
|
|
3
|
+
export type PresetName = keyof typeof appPreset;
|
|
4
|
+
export declare const preset: (question: PromptQuestion, output: PromptOutput) => Promise<PresetName>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { presets as appPreset } from '../preset/index.js';
|
|
2
|
+
import { prompt } from './prompt.js';
|
|
3
|
+
import { resolveOption } from './resolve-option.js';
|
|
4
|
+
export const preset = async (question, output) => {
|
|
5
|
+
const defaultPreset = 'base';
|
|
6
|
+
const presetNames = Object.keys(appPreset);
|
|
7
|
+
output.write('\nProject preset:\n\n');
|
|
8
|
+
presetNames.forEach((presetName, index) => output.write(` ${index + 1}. ${appPreset[presetName].name} - ${appPreset[presetName].description}\n`));
|
|
9
|
+
const presetValue = await prompt(question, '\nPreset number or name', defaultPreset);
|
|
10
|
+
return resolveOption(presetValue, presetNames, defaultPreset);
|
|
11
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { prompt } from './prompt.js';
|
|
2
|
+
import { resolveOption } from './resolve-option.js';
|
|
3
|
+
export const provider = async (question, output, label, options) => {
|
|
4
|
+
const optionNames = Object.keys(options);
|
|
5
|
+
const defaultOption = optionNames[0];
|
|
6
|
+
if (defaultOption === undefined) {
|
|
7
|
+
return undefined;
|
|
8
|
+
}
|
|
9
|
+
output.write(`\n${label}:\n\n`);
|
|
10
|
+
optionNames.forEach((optionName, index) => output.write(` ${index + 1}. ${optionName}\n`));
|
|
11
|
+
const optionValue = await prompt(question, `\n${label} number or name`, defaultOption);
|
|
12
|
+
return resolveOption(optionValue, optionNames);
|
|
13
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
type ResolveOption = {
|
|
2
|
+
<OptionName extends string>(value: string, optionNames: readonly OptionName[], fallback: OptionName): OptionName;
|
|
3
|
+
<OptionName extends string>(value: string, optionNames: readonly OptionName[]): OptionName | undefined;
|
|
4
|
+
};
|
|
5
|
+
export declare const resolveOption: ResolveOption;
|
|
6
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export const resolveOption = (value, optionNames, fallback) => {
|
|
2
|
+
const normalizedValue = value.trim();
|
|
3
|
+
const numericValue = Number.parseInt(normalizedValue, 10);
|
|
4
|
+
if (Number.isInteger(numericValue)) {
|
|
5
|
+
return optionNames[numericValue - 1] ?? fallback;
|
|
6
|
+
}
|
|
7
|
+
return optionNames.find((optionName) => optionName === normalizedValue) ?? fallback;
|
|
8
|
+
};
|
package/commands/dist.js
ADDED
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
import { chmod, copyFile, readdir, readFile, stat, unlink, writeFile } from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
const DIST_DIR = 'dist';
|
|
4
|
+
const AGENTS_FILE = 'AGENTS.md';
|
|
5
|
+
const LICENSE_FILE = 'LICENSE';
|
|
6
|
+
const PACKAGE_JSON_FILE = 'package.json';
|
|
7
|
+
const PACKAGES_DIR = 'packages';
|
|
8
|
+
const README_FILE = 'README.md';
|
|
9
|
+
const toPosixPath = (value) => value.split(path.sep).join('/');
|
|
10
|
+
const toPackagePath = (value) => {
|
|
11
|
+
const normalizedValue = toPosixPath(value);
|
|
12
|
+
return `./${normalizedValue.replace(/^\.\//, '')}`;
|
|
13
|
+
};
|
|
14
|
+
const hasFile = async (filePath) => {
|
|
15
|
+
try {
|
|
16
|
+
return (await stat(filePath)).isFile();
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
const readJson = async (filePath) => {
|
|
23
|
+
const content = await readFile(filePath, 'utf8');
|
|
24
|
+
return JSON.parse(content);
|
|
25
|
+
};
|
|
26
|
+
const writeJson = async (filePath, value) => {
|
|
27
|
+
await writeFile(filePath, `${JSON.stringify(value, null, 2)}\n`);
|
|
28
|
+
};
|
|
29
|
+
const isEmptyJavaScriptContent = (content) => {
|
|
30
|
+
const normalizedContent = content.trim();
|
|
31
|
+
return normalizedContent.length === 0 || normalizedContent === 'export {};';
|
|
32
|
+
};
|
|
33
|
+
const exportTargetPattern = /^\s*export(?:\s+\*|\s+\{[^}]*\})\s+from\s+['"](\..+\.js)['"];?\s*$/;
|
|
34
|
+
const getMissingExportTarget = async (file, line) => {
|
|
35
|
+
const exportTarget = exportTargetPattern.exec(line)?.[1];
|
|
36
|
+
if (!exportTarget) {
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
const exportTargetPath = path.resolve(path.dirname(file), exportTarget);
|
|
40
|
+
return (await hasFile(exportTargetPath)) ? undefined : exportTargetPath;
|
|
41
|
+
};
|
|
42
|
+
const readFiles = async (directory) => {
|
|
43
|
+
const entries = await readdir(directory, { withFileTypes: true });
|
|
44
|
+
const files = await Promise.all(entries.map(async (entry) => {
|
|
45
|
+
const entryPath = path.join(directory, entry.name);
|
|
46
|
+
if (entry.isDirectory()) {
|
|
47
|
+
return readFiles(entryPath);
|
|
48
|
+
}
|
|
49
|
+
return entry.isFile() ? [entryPath] : [];
|
|
50
|
+
}));
|
|
51
|
+
return files.flat();
|
|
52
|
+
};
|
|
53
|
+
const getPackageMain = async (packageDirectory, packageJson, javaScriptFiles) => {
|
|
54
|
+
if (packageJson.main?.endsWith('.js')) {
|
|
55
|
+
const mainPath = packageJson.main.replace(/^\.\//, '');
|
|
56
|
+
if (await hasFile(path.join(packageDirectory, mainPath))) {
|
|
57
|
+
return toPosixPath(mainPath);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if (javaScriptFiles.includes('index.js')) {
|
|
61
|
+
return 'index.js';
|
|
62
|
+
}
|
|
63
|
+
return javaScriptFiles[0];
|
|
64
|
+
};
|
|
65
|
+
const createExportTarget = (javaScriptFile) => {
|
|
66
|
+
const packagePath = toPackagePath(javaScriptFile);
|
|
67
|
+
return {
|
|
68
|
+
types: packagePath.replace(/\.js$/, '.d.ts'),
|
|
69
|
+
import: packagePath,
|
|
70
|
+
default: packagePath,
|
|
71
|
+
};
|
|
72
|
+
};
|
|
73
|
+
const createExports = (mainFile, javaScriptFiles) => {
|
|
74
|
+
const exports = {
|
|
75
|
+
'.': createExportTarget(mainFile),
|
|
76
|
+
};
|
|
77
|
+
for (const javaScriptFile of javaScriptFiles) {
|
|
78
|
+
const packagePath = toPackagePath(javaScriptFile);
|
|
79
|
+
const extensionlessPackagePath = packagePath.replace(/\.js$/, '');
|
|
80
|
+
const target = createExportTarget(javaScriptFile);
|
|
81
|
+
exports[extensionlessPackagePath] = target;
|
|
82
|
+
exports[packagePath] = target;
|
|
83
|
+
}
|
|
84
|
+
return exports;
|
|
85
|
+
};
|
|
86
|
+
const createPackageRepository = (rootPackageJson, packageDirectory) => {
|
|
87
|
+
const rootRepository = rootPackageJson.repository;
|
|
88
|
+
if (!rootRepository) {
|
|
89
|
+
return undefined;
|
|
90
|
+
}
|
|
91
|
+
return {
|
|
92
|
+
...rootRepository,
|
|
93
|
+
directory: toPosixPath(path.join(PACKAGES_DIR, path.basename(packageDirectory))),
|
|
94
|
+
};
|
|
95
|
+
};
|
|
96
|
+
const getJavaScriptFiles = async (packageDirectory) => {
|
|
97
|
+
const files = await readFiles(packageDirectory);
|
|
98
|
+
const javaScriptFiles = [];
|
|
99
|
+
for (const file of files) {
|
|
100
|
+
const relativeFile = toPosixPath(path.relative(packageDirectory, file));
|
|
101
|
+
const declarationFile = path.join(packageDirectory, relativeFile.replace(/\.js$/, '.d.ts'));
|
|
102
|
+
if (relativeFile.endsWith('.js') && !relativeFile.endsWith('.test.js') && (await hasFile(declarationFile))) {
|
|
103
|
+
javaScriptFiles.push(relativeFile);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return javaScriptFiles.sort((left, right) => left.localeCompare(right));
|
|
107
|
+
};
|
|
108
|
+
const removeEmptyJavaScriptFiles = async (packageDirectory) => {
|
|
109
|
+
const files = await readFiles(packageDirectory);
|
|
110
|
+
for (const file of files) {
|
|
111
|
+
if (file.endsWith('.js') && isEmptyJavaScriptContent(await readFile(file, 'utf8'))) {
|
|
112
|
+
await unlink(file);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
const removeMissingJavaScriptExports = async (packageDirectory) => {
|
|
117
|
+
const files = await readFiles(packageDirectory);
|
|
118
|
+
for (const file of files) {
|
|
119
|
+
if (!file.endsWith('.js')) {
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
const content = await readFile(file, 'utf8');
|
|
123
|
+
const lines = content.split('\n');
|
|
124
|
+
const retainedLines = [];
|
|
125
|
+
for (const line of lines) {
|
|
126
|
+
if (!(await getMissingExportTarget(file, line))) {
|
|
127
|
+
retainedLines.push(line);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
if (retainedLines.length !== lines.length) {
|
|
131
|
+
await writeFile(file, retainedLines.join('\n'));
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
const copyReadme = async (packageDirectory) => {
|
|
136
|
+
const packageName = path.basename(packageDirectory);
|
|
137
|
+
const sourceReadmePath = path.join(PACKAGES_DIR, packageName, README_FILE);
|
|
138
|
+
if (await hasFile(sourceReadmePath)) {
|
|
139
|
+
await copyFile(sourceReadmePath, path.join(packageDirectory, README_FILE));
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
const resolveSourceAgentsPath = async (packageAgentsPath, sharedAgentsPath, rootAgentsPath) => {
|
|
143
|
+
if (await hasFile(packageAgentsPath)) {
|
|
144
|
+
return packageAgentsPath;
|
|
145
|
+
}
|
|
146
|
+
if (await hasFile(sharedAgentsPath)) {
|
|
147
|
+
return sharedAgentsPath;
|
|
148
|
+
}
|
|
149
|
+
return rootAgentsPath;
|
|
150
|
+
};
|
|
151
|
+
const copyAgents = async (packageDirectory, rootPackageJson) => {
|
|
152
|
+
const packageName = path.basename(packageDirectory);
|
|
153
|
+
const packageAgentsPath = path.join(PACKAGES_DIR, packageName, AGENTS_FILE);
|
|
154
|
+
const sharedAgentsPath = path.join(PACKAGES_DIR, AGENTS_FILE);
|
|
155
|
+
const rootAgentsPath = typeof rootPackageJson.agents === 'string' ? rootPackageJson.agents.replace(/^\.\//, '') : '';
|
|
156
|
+
const sourceAgentsPath = await resolveSourceAgentsPath(packageAgentsPath, sharedAgentsPath, rootAgentsPath);
|
|
157
|
+
if (await hasFile(sourceAgentsPath)) {
|
|
158
|
+
await copyFile(sourceAgentsPath, path.join(packageDirectory, AGENTS_FILE));
|
|
159
|
+
return true;
|
|
160
|
+
}
|
|
161
|
+
return false;
|
|
162
|
+
};
|
|
163
|
+
const copyLicense = async (packageDirectory) => {
|
|
164
|
+
if (await hasFile(LICENSE_FILE)) {
|
|
165
|
+
await copyFile(LICENSE_FILE, path.join(packageDirectory, LICENSE_FILE));
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
const getPackageBinFiles = (packageJson) => {
|
|
169
|
+
if (typeof packageJson.bin === 'string') {
|
|
170
|
+
return [packageJson.bin];
|
|
171
|
+
}
|
|
172
|
+
if (packageJson.bin && typeof packageJson.bin === 'object') {
|
|
173
|
+
return Object.values(packageJson.bin);
|
|
174
|
+
}
|
|
175
|
+
return [];
|
|
176
|
+
};
|
|
177
|
+
const makePackageBinsExecutable = async (packageDirectory, packageJson) => {
|
|
178
|
+
for (const binFile of getPackageBinFiles(packageJson)) {
|
|
179
|
+
const binFilePath = path.join(packageDirectory, binFile.replace(/^\.\//, ''));
|
|
180
|
+
if (await hasFile(binFilePath)) {
|
|
181
|
+
await chmod(binFilePath, 0o755);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
const copyRootFile = async (fileName) => {
|
|
186
|
+
if (await hasFile(fileName)) {
|
|
187
|
+
await copyFile(fileName, path.join(DIST_DIR, fileName));
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
const distRootPackageJson = async () => {
|
|
191
|
+
const packageJson = await readJson(PACKAGE_JSON_FILE);
|
|
192
|
+
delete packageJson.agents;
|
|
193
|
+
delete packageJson.dependencies;
|
|
194
|
+
delete packageJson.packageManager;
|
|
195
|
+
delete packageJson.scripts;
|
|
196
|
+
delete packageJson.devDependencies;
|
|
197
|
+
await writeJson(path.join(DIST_DIR, PACKAGE_JSON_FILE), packageJson);
|
|
198
|
+
};
|
|
199
|
+
const distRoot = async () => {
|
|
200
|
+
await copyRootFile(README_FILE);
|
|
201
|
+
await copyRootFile(LICENSE_FILE);
|
|
202
|
+
await distRootPackageJson();
|
|
203
|
+
};
|
|
204
|
+
const syncPackageRuntimeMetadata = (packageJson, rootPackageJson) => {
|
|
205
|
+
if (packageJson.name !== 'vyriy') {
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
packageJson.packageManager = rootPackageJson.packageManager;
|
|
209
|
+
packageJson.engines = rootPackageJson.engines;
|
|
210
|
+
};
|
|
211
|
+
const distPackage = async (packageJsonPath, rootPackageJson) => {
|
|
212
|
+
const packageDirectory = path.dirname(packageJsonPath);
|
|
213
|
+
const packageJson = await readJson(packageJsonPath);
|
|
214
|
+
await removeEmptyJavaScriptFiles(packageDirectory);
|
|
215
|
+
await removeMissingJavaScriptExports(packageDirectory);
|
|
216
|
+
await removeEmptyJavaScriptFiles(packageDirectory);
|
|
217
|
+
const javaScriptFiles = await getJavaScriptFiles(packageDirectory);
|
|
218
|
+
await copyLicense(packageDirectory);
|
|
219
|
+
await copyReadme(packageDirectory);
|
|
220
|
+
const hasAgents = await copyAgents(packageDirectory, rootPackageJson);
|
|
221
|
+
delete packageJson.private;
|
|
222
|
+
if (hasAgents && rootPackageJson.agents) {
|
|
223
|
+
packageJson.agents = toPackagePath(AGENTS_FILE);
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
delete packageJson.agents;
|
|
227
|
+
}
|
|
228
|
+
if (rootPackageJson.license) {
|
|
229
|
+
packageJson.license = rootPackageJson.license;
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
delete packageJson.license;
|
|
233
|
+
}
|
|
234
|
+
const repository = createPackageRepository(rootPackageJson, packageDirectory);
|
|
235
|
+
if (repository) {
|
|
236
|
+
packageJson.repository = repository;
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
delete packageJson.repository;
|
|
240
|
+
}
|
|
241
|
+
syncPackageRuntimeMetadata(packageJson, rootPackageJson);
|
|
242
|
+
if (javaScriptFiles.length > 0) {
|
|
243
|
+
const mainFile = await getPackageMain(packageDirectory, packageJson, javaScriptFiles);
|
|
244
|
+
if (mainFile) {
|
|
245
|
+
packageJson.main = toPackagePath(mainFile);
|
|
246
|
+
packageJson.types = toPackagePath(mainFile).replace(/\.js$/, '.d.ts');
|
|
247
|
+
packageJson.exports = createExports(mainFile, javaScriptFiles);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
await makePackageBinsExecutable(packageDirectory, packageJson);
|
|
251
|
+
await writeJson(packageJsonPath, packageJson);
|
|
252
|
+
};
|
|
253
|
+
export const dist = async () => {
|
|
254
|
+
const previousCwd = process.cwd();
|
|
255
|
+
try {
|
|
256
|
+
process.chdir(process.cwd());
|
|
257
|
+
const rootPackageJson = await readJson(PACKAGE_JSON_FILE);
|
|
258
|
+
await distRoot();
|
|
259
|
+
const entries = await readdir(DIST_DIR, { withFileTypes: true });
|
|
260
|
+
const packageJsonPaths = entries
|
|
261
|
+
.filter((entry) => entry.isDirectory())
|
|
262
|
+
.map((entry) => path.join(DIST_DIR, entry.name, 'package.json'))
|
|
263
|
+
.sort((left, right) => left.localeCompare(right));
|
|
264
|
+
for (const packageJsonPath of packageJsonPaths) {
|
|
265
|
+
if (await hasFile(packageJsonPath)) {
|
|
266
|
+
await distPackage(packageJsonPath, rootPackageJson);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
return 0;
|
|
270
|
+
}
|
|
271
|
+
finally {
|
|
272
|
+
process.chdir(previousCwd);
|
|
273
|
+
}
|
|
274
|
+
};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { Command } from './types.js';
|
|
2
|
+
export declare const text = "Vyriy Project Master\n\nUsage:\n vyriy [name] Create a new Vyriy project\n vyriy . Initialize a new Vyriy project in the current directory\n vyriy --help, -h Show help\n vyriy --version, -v Show version\n vyriy --check-env, -c Check local environment\n vyriy --dist, -d Prepare dist package metadata without publishing to npm\n vyriy --dry-run Print checks and file plan without writing\n vyriy --overwrite Overwrite existing generated paths\n vyriy --skip-existing Leave existing generated paths untouched\n vyriy --no-install Create files without installing dependencies\n vyriy --no-verify Install dependencies without running checks\n\nExamples:\n vyriy app\n vyriy .\n vyriy -d";
|
|
3
|
+
export declare const help: Command;
|
package/commands/help.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export const text = `Vyriy Project Master
|
|
2
|
+
|
|
3
|
+
Usage:
|
|
4
|
+
vyriy [name] Create a new Vyriy project
|
|
5
|
+
vyriy . Initialize a new Vyriy project in the current directory
|
|
6
|
+
vyriy --help, -h Show help
|
|
7
|
+
vyriy --version, -v Show version
|
|
8
|
+
vyriy --check-env, -c Check local environment
|
|
9
|
+
vyriy --dist, -d Prepare dist package metadata without publishing to npm
|
|
10
|
+
vyriy --dry-run Print checks and file plan without writing
|
|
11
|
+
vyriy --overwrite Overwrite existing generated paths
|
|
12
|
+
vyriy --skip-existing Leave existing generated paths untouched
|
|
13
|
+
vyriy --no-install Create files without installing dependencies
|
|
14
|
+
vyriy --no-verify Install dependencies without running checks
|
|
15
|
+
|
|
16
|
+
Examples:
|
|
17
|
+
vyriy app
|
|
18
|
+
vyriy .
|
|
19
|
+
vyriy -d`;
|
|
20
|
+
export const help = async () => {
|
|
21
|
+
console.log(text);
|
|
22
|
+
await Promise.resolve();
|
|
23
|
+
return 0;
|
|
24
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export type Command = () => Promise<number>;
|
|
2
|
+
export type Node = () => {
|
|
3
|
+
ok: boolean;
|
|
4
|
+
message: string;
|
|
5
|
+
};
|
|
6
|
+
export type Yarn = () => Promise<{
|
|
7
|
+
ok: boolean;
|
|
8
|
+
message: string;
|
|
9
|
+
}>;
|
|
10
|
+
export type CreateOptions = {
|
|
11
|
+
readonly directory: string;
|
|
12
|
+
readonly dryRun: boolean;
|
|
13
|
+
readonly overwrite: boolean;
|
|
14
|
+
readonly skipExisting: boolean;
|
|
15
|
+
readonly install: boolean;
|
|
16
|
+
readonly verify: boolean;
|
|
17
|
+
};
|
|
18
|
+
export type Create = (options: CreateOptions) => Promise<number>;
|
|
19
|
+
export type ExportTarget = {
|
|
20
|
+
readonly default: string;
|
|
21
|
+
readonly import: string;
|
|
22
|
+
readonly types: string;
|
|
23
|
+
};
|
|
24
|
+
export type Repository = {
|
|
25
|
+
readonly directory?: string;
|
|
26
|
+
readonly type: string;
|
|
27
|
+
readonly url: string;
|
|
28
|
+
};
|
|
29
|
+
export type PackageJson = {
|
|
30
|
+
agents?: string;
|
|
31
|
+
bin?: string | Record<string, string>;
|
|
32
|
+
dependencies?: unknown;
|
|
33
|
+
engines?: unknown;
|
|
34
|
+
exports?: Record<string, ExportTarget>;
|
|
35
|
+
license?: string;
|
|
36
|
+
main?: string;
|
|
37
|
+
name?: string;
|
|
38
|
+
packageManager?: unknown;
|
|
39
|
+
private?: boolean;
|
|
40
|
+
repository?: Repository;
|
|
41
|
+
scripts?: unknown;
|
|
42
|
+
types?: string;
|
|
43
|
+
workspaces?: unknown;
|
|
44
|
+
[key: string]: unknown;
|
|
45
|
+
};
|