@stripchatdev/create-stripchat-extension 0.1.46 → 0.1.48
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/bin/cli/actions/updateAction.d.ts +6 -0
- package/dist/bin/cli/actions/updateAction.js +33 -0
- package/dist/bin/cli/helpers/printCliError.d.ts +1 -0
- package/dist/bin/cli/helpers/printCliError.js +21 -0
- package/dist/bin/cli/index.js +70 -0
- package/dist/bin/create.d.ts +2 -0
- package/dist/bin/create.js +246 -0
- package/dist/package.json +9 -4
- package/dist/src/constants.d.ts +14 -9
- package/dist/src/constants.js +73 -12
- package/dist/src/dependencies/constants.d.ts +2 -0
- package/dist/src/dependencies/constants.js +11 -0
- package/dist/src/dependencies/resolveDependencies.d.ts +6 -0
- package/dist/src/dependencies/resolveDependencies.js +43 -0
- package/dist/src/dependencies/resolveDependencies.test.js +74 -0
- package/dist/src/helpers/error.d.ts +3 -0
- package/dist/src/helpers/error.js +9 -0
- package/dist/src/helpers/error.test.js +15 -0
- package/dist/src/helpers/getIsDirectoryExists.d.ts +7 -0
- package/dist/src/helpers/getIsDirectoryExists.js +23 -0
- package/dist/src/helpers/getIsDirectoryExists.test.js +34 -0
- package/dist/src/helpers/getIsJsxFramework.d.ts +2 -0
- package/dist/src/helpers/getIsJsxFramework.js +2 -0
- package/dist/src/helpers/getIsJsxFramework.test.js +10 -0
- package/dist/src/helpers/getIsTypescript.d.ts +2 -0
- package/dist/src/helpers/getIsTypescript.js +1 -0
- package/dist/src/helpers/getIsTypescript.test.js +10 -0
- package/dist/src/helpers/isSubPath.d.ts +1 -0
- package/dist/src/helpers/isSubPath.js +5 -0
- package/dist/src/helpers/normalizePath.d.ts +2 -0
- package/dist/src/helpers/normalizePath.js +4 -0
- package/dist/src/helpers/normalizePath.test.js +19 -0
- package/dist/src/migrator/executor.d.ts +9 -0
- package/dist/src/migrator/executor.js +112 -0
- package/dist/src/migrator/migration.d.ts +3 -0
- package/dist/src/migrator/migration.js +18 -0
- package/dist/src/migrator/migration.test.js +74 -0
- package/dist/src/migrator/migrations/migrations.test.js +97 -0
- package/dist/src/migrator/migrations/v2/AGENTS_md/001_recreate-with-generated-part.d.ts +2 -0
- package/dist/src/migrator/migrations/v2/AGENTS_md/001_recreate-with-generated-part.js +14 -0
- package/dist/src/migrator/migrations/v2/_project-config_json/001_create.d.ts +2 -0
- package/dist/src/migrator/migrations/v2/_project-config_json/001_create.js +14 -0
- package/dist/src/migrator/migrations/v2/vite_config_ts/001_turn_off_minify_and_assets_inline.d.ts +2 -0
- package/dist/src/migrator/migrations/v2/vite_config_ts/001_turn_off_minify_and_assets_inline.js +118 -0
- package/dist/src/migrator/planner.d.ts +5 -0
- package/dist/src/migrator/planner.js +65 -0
- package/dist/src/migrator/planner.test.js +40 -0
- package/dist/src/migrator/types.d.ts +29 -0
- package/dist/src/migrator/updates/updates.test.js +102 -0
- package/dist/src/migrator/updates/v2/AGENTS_md/001_update-generated-part.d.ts +2 -0
- package/dist/src/migrator/updates/v2/AGENTS_md/001_update-generated-part.js +38 -0
- package/dist/src/migrator/updates/v2/package_json/001_update-versions.d.ts +2 -0
- package/dist/src/migrator/updates/v2/package_json/001_update-versions.js +77 -0
- package/dist/src/migrator/updates/v2/package_json/002_add-cli-commands.d.ts +2 -0
- package/dist/src/migrator/updates/v2/package_json/002_add-cli-commands.js +61 -0
- package/dist/src/migrator/validators/getIsValidMigration.d.ts +2 -0
- package/dist/src/migrator/validators/getIsValidMigration.js +3 -0
- package/dist/src/migrator/validators/getIsValidMigration.test.js +13 -0
- package/dist/src/projectConfig/buildProjectConfig.d.ts +15 -0
- package/dist/src/projectConfig/buildProjectConfig.js +27 -0
- package/dist/src/projectConfig/detectPackageManagerRuntime.d.ts +2 -0
- package/dist/src/{helpers/detectPackageManager.js → projectConfig/detectPackageManagerRuntime.js} +1 -1
- package/dist/src/{helpers/detectPackageManager.test.js → projectConfig/detectPackageManagerRuntime.test.js} +10 -10
- package/dist/src/projectConfig/recoverProjectConfig.d.ts +1 -0
- package/dist/src/projectConfig/recoverProjectConfig.js +34 -0
- package/dist/src/projectConfig/recovery/detectPackageManagerFromFiles.d.ts +2 -0
- package/dist/src/projectConfig/recovery/detectPackageManagerFromFiles.js +16 -0
- package/dist/src/projectConfig/recovery/detectPackageManagerFromFiles.test.d.ts +1 -0
- package/dist/src/projectConfig/recovery/detectPackageManagerFromFiles.test.js +37 -0
- package/dist/src/projectConfig/recovery/parseAgentsMd.d.ts +10 -0
- package/dist/src/projectConfig/recovery/parseAgentsMd.js +52 -0
- package/dist/src/projectConfig/recovery/parseAgentsMd.test.d.ts +1 -0
- package/dist/src/projectConfig/recovery/parseAgentsMd.test.js +67 -0
- package/dist/src/projectConfig/recovery/resolveProjectNameFromDir.d.ts +1 -0
- package/dist/src/projectConfig/recovery/resolveProjectNameFromDir.js +11 -0
- package/dist/src/projectConfig/recovery/resolveProjectNameFromDir.test.d.ts +1 -0
- package/dist/src/projectConfig/recovery/resolveProjectNameFromDir.test.js +21 -0
- package/dist/src/projectConfig/resolveExistsProjectConfig.d.ts +2 -0
- package/dist/src/projectConfig/resolveExistsProjectConfig.js +34 -0
- package/dist/src/projectConfig/updateProjectConfig.d.ts +2 -0
- package/dist/src/projectConfig/updateProjectConfig.js +20 -0
- package/dist/src/projectConfig/validators/getIsValidProjectConfig.d.ts +2 -0
- package/dist/src/projectConfig/validators/getIsValidProjectConfig.js +6 -0
- package/dist/src/projectConfig/validators/getIsValidProjectConfig.test.d.ts +1 -0
- package/dist/src/projectConfig/validators/getIsValidProjectConfig.test.js +33 -0
- package/dist/src/projectConfig/validators/validateProjectConfig.d.ts +2 -0
- package/dist/src/projectConfig/validators/validateProjectConfig.js +30 -0
- package/dist/src/projectConfig/validators/validateProjectConfig.test.d.ts +1 -0
- package/dist/src/projectConfig/validators/validateProjectConfig.test.js +215 -0
- package/dist/src/templater/executor.d.ts +2 -0
- package/dist/src/templater/executor.js +22 -0
- package/dist/src/templater/executor.test.d.ts +1 -0
- package/dist/src/{executor.test.js → templater/executor.test.js} +25 -11
- package/dist/src/templater/helpers/getIsTypescriptOnlyFile.d.ts +1 -0
- package/dist/src/templater/helpers/getIsTypescriptOnlyFile.js +10 -0
- package/dist/src/templater/helpers/getIsTypescriptOnlyFile.test.d.ts +1 -0
- package/dist/src/templater/helpers/getIsTypescriptOnlyFile.test.js +25 -0
- package/dist/src/templater/helpers/resolveTemplateExtension.d.ts +1 -0
- package/dist/src/templater/helpers/resolveTemplateExtension.js +16 -0
- package/dist/src/templater/helpers/resolveTemplateExtension.test.d.ts +1 -0
- package/dist/src/{mappers → templater/mappers}/mapProjectConfigToTemplateModel.d.ts +1 -1
- package/dist/src/{mappers → templater/mappers}/mapProjectConfigToTemplateModel.js +6 -8
- package/dist/src/templater/mappers/mapProjectConfigToTemplateModel.test.d.ts +1 -0
- package/dist/src/{mappers → templater/mappers}/mapProjectConfigToTemplateModel.test.js +29 -23
- package/dist/src/templater/planner.d.ts +2 -0
- package/dist/src/templater/planner.js +104 -0
- package/dist/src/templater/planner.test.d.ts +1 -0
- package/dist/src/templater/planner.test.js +64 -0
- package/dist/src/templates/constants.d.ts +6 -0
- package/dist/src/templates/constants.js +11 -0
- package/dist/src/templates/helpers/resolveTemplatesDir.d.ts +1 -0
- package/dist/src/templates/helpers/resolveTemplatesDir.js +16 -0
- package/dist/src/templates/templates.d.ts +10 -0
- package/dist/src/templates/templates.js +133 -0
- package/dist/src/templates/templates.test.d.ts +1 -0
- package/dist/src/templates/templates.test.js +263 -0
- package/dist/src/templates/types.d.ts +21 -0
- package/dist/src/templates/types.js +1 -0
- package/dist/src/types.d.ts +28 -9
- package/dist/src/validators/getIsValidCategory.d.ts +2 -0
- package/dist/src/validators/getIsValidCategory.js +2 -0
- package/dist/src/validators/getIsValidCategory.test.d.ts +1 -0
- package/dist/src/validators/{isValidCategory.test.js → getIsValidCategory.test.js} +3 -3
- package/dist/src/validators/getIsValidFramework.d.ts +2 -0
- package/dist/src/validators/getIsValidFramework.js +2 -0
- package/dist/src/validators/getIsValidFramework.test.d.ts +1 -0
- package/dist/src/validators/{isValidFramework.test.js → getIsValidFramework.test.js} +3 -3
- package/dist/src/validators/getIsValidLanguage.d.ts +2 -0
- package/dist/src/validators/getIsValidLanguage.js +2 -0
- package/dist/src/validators/getIsValidLanguage.test.d.ts +1 -0
- package/dist/src/validators/{isValidLanguage.test.js → getIsValidLanguage.test.js} +3 -3
- package/dist/src/validators/getIsValidPackageManager.d.ts +2 -0
- package/dist/src/validators/getIsValidPackageManager.js +4 -0
- package/dist/src/validators/getIsValidPackageManager.test.d.ts +1 -0
- package/dist/src/validators/getIsValidPackageManager.test.js +11 -0
- package/dist/src/validators/getIsValidSlot.d.ts +2 -0
- package/dist/src/validators/getIsValidSlot.js +4 -0
- package/dist/src/validators/getIsValidSlot.test.d.ts +1 -0
- package/dist/src/validators/getIsValidSlot.test.js +26 -0
- package/dist/src/validators/validateSlots.js +40 -8
- package/dist/src/validators/validateSlots.test.js +125 -34
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +9 -4
- package/templates/v1/vite.config.ts.ejs +27 -0
- package/templates/v2/.project-config.json.ejs +1 -0
- package/templates/v2/AGENTS.md.ejs +712 -0
- package/templates/v2/README.md.ejs +31 -0
- package/templates/v2/package.json.ejs +26 -0
- package/dist/bin/cli.js +0 -221
- package/dist/src/executor.d.ts +0 -2
- package/dist/src/executor.js +0 -22
- package/dist/src/helpers/detectPackageManager.d.ts +0 -2
- package/dist/src/helpers/isDirectory.d.ts +0 -1
- package/dist/src/helpers/isDirectory.js +0 -9
- package/dist/src/helpers/isDirectory.test.js +0 -22
- package/dist/src/helpers/isTypescriptOnlyFile.d.ts +0 -1
- package/dist/src/helpers/isTypescriptOnlyFile.js +0 -5
- package/dist/src/helpers/isTypescriptOnlyFile.test.js +0 -22
- package/dist/src/helpers/normalizeRelPath.d.ts +0 -1
- package/dist/src/helpers/normalizeRelPath.js +0 -1
- package/dist/src/helpers/normalizeRelPath.test.js +0 -19
- package/dist/src/helpers/resolveTemplateExtension.d.ts +0 -1
- package/dist/src/helpers/resolveTemplateExtension.js +0 -17
- package/dist/src/helpers/resolveTemplatesDir.d.ts +0 -1
- package/dist/src/helpers/resolveTemplatesDir.js +0 -11
- package/dist/src/helpers/resolveTemplatesDir.test.js +0 -21
- package/dist/src/planner.d.ts +0 -2
- package/dist/src/planner.js +0 -126
- package/dist/src/planner.test.js +0 -58
- package/dist/src/validators/index.d.ts +0 -6
- package/dist/src/validators/index.js +0 -6
- package/dist/src/validators/isValidCategory.d.ts +0 -2
- package/dist/src/validators/isValidCategory.js +0 -2
- package/dist/src/validators/isValidFramework.d.ts +0 -2
- package/dist/src/validators/isValidFramework.js +0 -2
- package/dist/src/validators/isValidLanguage.d.ts +0 -2
- package/dist/src/validators/isValidLanguage.js +0 -2
- package/dist/src/validators/validateProjectDir.d.ts +0 -1
- package/dist/src/validators/validateProjectDir.js +0 -6
- package/dist/src/validators/validateProjectDir.test.js +0 -19
- package/dist/bin/{cli.d.ts → cli/index.d.ts} +0 -0
- package/dist/src/{executor.test.d.ts → dependencies/resolveDependencies.test.d.ts} +0 -0
- package/dist/src/helpers/{detectPackageManager.test.d.ts → error.test.d.ts} +0 -0
- package/dist/src/helpers/{isDirectory.test.d.ts → getIsDirectoryExists.test.d.ts} +0 -0
- package/dist/src/helpers/{isTypescriptOnlyFile.test.d.ts → getIsJsxFramework.test.d.ts} +0 -0
- package/dist/src/helpers/{normalizeRelPath.test.d.ts → getIsTypescript.test.d.ts} +0 -0
- package/dist/src/helpers/{resolveTemplateExtension.test.d.ts → normalizePath.test.d.ts} +0 -0
- package/dist/src/{helpers/resolveTemplatesDir.test.d.ts → migrator/migration.test.d.ts} +0 -0
- package/dist/src/{mappers/mapProjectConfigToTemplateModel.test.d.ts → migrator/migrations/migrations.test.d.ts} +0 -0
- package/dist/src/{planner.test.d.ts → migrator/planner.test.d.ts} +0 -0
- package/dist/src/{validators/isValidCategory.test.d.ts → migrator/types.js} +0 -0
- package/dist/src/{validators/isValidFramework.test.d.ts → migrator/updates/updates.test.d.ts} +0 -0
- package/dist/src/{validators/isValidLanguage.test.d.ts → migrator/validators/getIsValidMigration.test.d.ts} +0 -0
- package/dist/src/{validators/validateProjectDir.test.d.ts → projectConfig/detectPackageManagerRuntime.test.d.ts} +0 -0
- package/dist/src/{helpers → templater/helpers}/resolveTemplateExtension.test.js +0 -0
- package/templates/{.gitignore.ejs → v1/.gitignore.ejs} +0 -0
- package/templates/{AGENTS.md.ejs → v1/AGENTS.md.ejs} +0 -0
- package/templates/{CLAUDE.md → v1/CLAUDE.md} +0 -0
- package/templates/{README.md.ejs → v1/README.md.ejs} +0 -0
- package/templates/{package.json.ejs → v1/package.json.ejs} +0 -0
- package/templates/{public → v1/public}/icon.svg +0 -0
- package/templates/{public → v1/public}/manifest.json.ejs +0 -0
- package/templates/{public → v1/public}/resolveSlotPage.js.ejs +0 -0
- package/templates/{src → v1/src}/slots/background/app.ts.ejs +0 -0
- package/templates/{src → v1/src}/slots/background/background.html.ejs +0 -0
- package/templates/{src → v1/src}/slots/background/main.ts.ejs +0 -0
- package/templates/{src/slots/slot/slot.html.ejs → v1/src/slots/slot/__SLOT_KEY__.html.ejs} +0 -0
- package/templates/{src → v1/src}/slots/slot/app.ts.ejs +0 -0
- package/templates/{src → v1/src}/slots/slot/app.tsx.ejs +0 -0
- package/templates/{src → v1/src}/slots/slot/main.css.ejs +0 -0
- package/templates/{src → v1/src}/slots/slot/main.ts.ejs +0 -0
- package/templates/{src → v1/src}/slots/slot/main.tsx.ejs +0 -0
- package/templates/{tsconfig.json.ejs → v1/tsconfig.json.ejs} +0 -0
- package/templates/{vite.config.ts.ejs → v2/vite.config.ts.ejs} +1 -1
package/dist/src/migrator/migrations/v2/vite_config_ts/001_turn_off_minify_and_assets_inline.js
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { dirname, join } from 'node:path';
|
|
3
|
+
import { IndentationText, NewLineKind, Node, Project, SyntaxKind } from 'ts-morph';
|
|
4
|
+
import { VITE_CONFIG_REL_PATH_BY_LANGUAGE } from '../../../../constants.js';
|
|
5
|
+
const resolveConfigObject = (sourceText, fileName) => {
|
|
6
|
+
const project = new Project({
|
|
7
|
+
manipulationSettings: {
|
|
8
|
+
indentationText: IndentationText.TwoSpaces,
|
|
9
|
+
newLineKind: NewLineKind.LineFeed,
|
|
10
|
+
},
|
|
11
|
+
useInMemoryFileSystem: true,
|
|
12
|
+
});
|
|
13
|
+
const sourceFile = project.createSourceFile(fileName, sourceText, { overwrite: true });
|
|
14
|
+
const exportAssignment = sourceFile.getExportAssignment(() => true);
|
|
15
|
+
if (!exportAssignment || exportAssignment.isExportEquals()) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
const expression = exportAssignment.getExpression();
|
|
19
|
+
if (!expression) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
if (Node.isObjectLiteralExpression(expression)) {
|
|
23
|
+
return { sourceFile, configObject: expression };
|
|
24
|
+
}
|
|
25
|
+
if (!Node.isCallExpression(expression)) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
const firstArg = expression.getArguments()[0];
|
|
29
|
+
if (!firstArg || !Node.isObjectLiteralExpression(firstArg)) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
return { sourceFile, configObject: firstArg };
|
|
33
|
+
};
|
|
34
|
+
const withTurnedOffMinifyAndAssetsInline = (viteConfigContent, fileName) => {
|
|
35
|
+
const resolved = resolveConfigObject(viteConfigContent, fileName);
|
|
36
|
+
if (!resolved) {
|
|
37
|
+
return viteConfigContent;
|
|
38
|
+
}
|
|
39
|
+
const { configObject, sourceFile } = resolved;
|
|
40
|
+
const buildProperty = configObject.getProperty('build');
|
|
41
|
+
if (!buildProperty || !Node.isPropertyAssignment(buildProperty)) {
|
|
42
|
+
return viteConfigContent;
|
|
43
|
+
}
|
|
44
|
+
const buildObject = buildProperty.getInitializerIfKind(SyntaxKind.ObjectLiteralExpression);
|
|
45
|
+
if (!buildObject) {
|
|
46
|
+
return viteConfigContent;
|
|
47
|
+
}
|
|
48
|
+
const minifyProperty = buildObject.getProperty('minify');
|
|
49
|
+
const assetsInlineLimitProperty = buildObject.getProperty('assetsInlineLimit');
|
|
50
|
+
let isPresetMinify = false;
|
|
51
|
+
let isPresentAssetsInlineLimit = false;
|
|
52
|
+
if (minifyProperty && Node.isPropertyAssignment(minifyProperty)) {
|
|
53
|
+
minifyProperty.setInitializer('false');
|
|
54
|
+
isPresetMinify = true;
|
|
55
|
+
}
|
|
56
|
+
if (assetsInlineLimitProperty && Node.isPropertyAssignment(assetsInlineLimitProperty)) {
|
|
57
|
+
assetsInlineLimitProperty.setInitializer('0');
|
|
58
|
+
isPresentAssetsInlineLimit = true;
|
|
59
|
+
}
|
|
60
|
+
const properties = buildObject.getProperties();
|
|
61
|
+
const outDirProperty = properties.find((property) => Node.isPropertyAssignment(property) && property.getName() === 'outDir');
|
|
62
|
+
const rollupProperty = properties.find((property) => Node.isPropertyAssignment(property) && property.getName() === 'rollupOptions');
|
|
63
|
+
const outDirIndex = outDirProperty ? properties.indexOf(outDirProperty) : -1;
|
|
64
|
+
const rollupIndex = rollupProperty ? properties.indexOf(rollupProperty) : -1;
|
|
65
|
+
let currInsertIndex = rollupIndex >= 0
|
|
66
|
+
? rollupIndex
|
|
67
|
+
: outDirIndex >= 0
|
|
68
|
+
? outDirIndex + 1
|
|
69
|
+
: properties.length;
|
|
70
|
+
if (!isPresetMinify) {
|
|
71
|
+
buildObject.insertPropertyAssignment(currInsertIndex, {
|
|
72
|
+
name: 'minify',
|
|
73
|
+
initializer: 'false',
|
|
74
|
+
});
|
|
75
|
+
currInsertIndex += 1;
|
|
76
|
+
}
|
|
77
|
+
if (!isPresentAssetsInlineLimit) {
|
|
78
|
+
buildObject.insertPropertyAssignment(currInsertIndex, {
|
|
79
|
+
name: 'assetsInlineLimit',
|
|
80
|
+
initializer: '0',
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
sourceFile.formatText({
|
|
84
|
+
convertTabsToSpaces: true,
|
|
85
|
+
indentSize: 2,
|
|
86
|
+
});
|
|
87
|
+
return sourceFile.getFullText();
|
|
88
|
+
};
|
|
89
|
+
export const up = (ctx) => {
|
|
90
|
+
const viteConfigRelPath = VITE_CONFIG_REL_PATH_BY_LANGUAGE[ctx.targetProjectConfig.language];
|
|
91
|
+
const targetViteConfigPath = join(ctx.projectDir, viteConfigRelPath);
|
|
92
|
+
const generatedViteConfigPath = join(ctx.generatedProjectDir, viteConfigRelPath);
|
|
93
|
+
if (!existsSync(targetViteConfigPath)) {
|
|
94
|
+
mkdirSync(dirname(targetViteConfigPath), { recursive: true });
|
|
95
|
+
copyFileSync(generatedViteConfigPath, targetViteConfigPath);
|
|
96
|
+
return [
|
|
97
|
+
{
|
|
98
|
+
filePath: targetViteConfigPath,
|
|
99
|
+
relFilePath: viteConfigRelPath,
|
|
100
|
+
},
|
|
101
|
+
];
|
|
102
|
+
}
|
|
103
|
+
const targetViteConfigContent = readFileSync(targetViteConfigPath, 'utf8');
|
|
104
|
+
const mergedViteConfigContent = withTurnedOffMinifyAndAssetsInline(targetViteConfigContent, viteConfigRelPath);
|
|
105
|
+
if (targetViteConfigContent === mergedViteConfigContent) {
|
|
106
|
+
return [];
|
|
107
|
+
}
|
|
108
|
+
writeFileSync(targetViteConfigPath, mergedViteConfigContent, {
|
|
109
|
+
encoding: 'utf8',
|
|
110
|
+
flag: 'w',
|
|
111
|
+
});
|
|
112
|
+
return [
|
|
113
|
+
{
|
|
114
|
+
filePath: targetViteConfigPath,
|
|
115
|
+
relFilePath: viteConfigRelPath,
|
|
116
|
+
},
|
|
117
|
+
];
|
|
118
|
+
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { TManagedFile } from '../templates/types';
|
|
2
|
+
import type { TProjectConfig } from '../types';
|
|
3
|
+
import type { TMigrationExecutionPlan, TMigrationPlan } from './types';
|
|
4
|
+
export declare const planMigrations: (targetManagedFiles: TManagedFile[], managedFiles: TManagedFile[], lastTemplateVersion: number) => TMigrationPlan[];
|
|
5
|
+
export declare const planMigrationExecution: (targetProjectConfig: TProjectConfig, templateVersion: number) => TMigrationExecutionPlan;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { existsSync, readdirSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { updateProjectConfig } from '../projectConfig/updateProjectConfig.js';
|
|
4
|
+
import { INIT_TEMPLATE_VERSION } from '../templates/constants.js';
|
|
5
|
+
import { getTemplateMigrationsDir } from './migration.js';
|
|
6
|
+
const discoverMigrationsByVersion = (type, relPath, version) => {
|
|
7
|
+
const migrationsDir = getTemplateMigrationsDir(type, version, relPath);
|
|
8
|
+
if (!existsSync(migrationsDir)) {
|
|
9
|
+
return [];
|
|
10
|
+
}
|
|
11
|
+
const entries = readdirSync(migrationsDir, { withFileTypes: true });
|
|
12
|
+
return entries
|
|
13
|
+
.filter((entry) => {
|
|
14
|
+
return entry.isFile() && !entry.name.endsWith('.d.ts');
|
|
15
|
+
})
|
|
16
|
+
.map((entry) => {
|
|
17
|
+
const scriptPath = join(entry.parentPath, entry.name);
|
|
18
|
+
const migrationPlan = {
|
|
19
|
+
scriptPath,
|
|
20
|
+
templateRelPath: relPath,
|
|
21
|
+
templateVersion: version,
|
|
22
|
+
};
|
|
23
|
+
return migrationPlan;
|
|
24
|
+
})
|
|
25
|
+
.sort((a, b) => {
|
|
26
|
+
return a.scriptPath.localeCompare(b.scriptPath);
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
const discoverMigrationsForTemplate = (templateFileRelPath, fromVersion, toVersion) => {
|
|
30
|
+
const templateMigrations = [];
|
|
31
|
+
let iterVersion = fromVersion;
|
|
32
|
+
while (iterVersion <= toVersion) {
|
|
33
|
+
if (iterVersion > fromVersion) {
|
|
34
|
+
const versionMigrations = discoverMigrationsByVersion('migrations', templateFileRelPath, iterVersion);
|
|
35
|
+
templateMigrations.push(...versionMigrations);
|
|
36
|
+
}
|
|
37
|
+
const versionUpdates = discoverMigrationsByVersion('updates', templateFileRelPath, iterVersion);
|
|
38
|
+
templateMigrations.push(...versionUpdates);
|
|
39
|
+
iterVersion++;
|
|
40
|
+
}
|
|
41
|
+
return templateMigrations;
|
|
42
|
+
};
|
|
43
|
+
export const planMigrations = (targetManagedFiles, managedFiles, lastTemplateVersion) => {
|
|
44
|
+
const targetManagedFilesMap = {};
|
|
45
|
+
targetManagedFiles.forEach((file) => {
|
|
46
|
+
targetManagedFilesMap[file.relPath] = file;
|
|
47
|
+
});
|
|
48
|
+
const allMigrations = [];
|
|
49
|
+
for (const managedFile of managedFiles) {
|
|
50
|
+
const targetManagedFile = targetManagedFilesMap[managedFile.relPath];
|
|
51
|
+
const targetVersion = targetManagedFile ? targetManagedFile.version : INIT_TEMPLATE_VERSION;
|
|
52
|
+
const templateMigrations = discoverMigrationsForTemplate(managedFile.relPath, targetVersion, lastTemplateVersion);
|
|
53
|
+
allMigrations.push(...templateMigrations);
|
|
54
|
+
}
|
|
55
|
+
return allMigrations;
|
|
56
|
+
};
|
|
57
|
+
export const planMigrationExecution = (targetProjectConfig, templateVersion) => {
|
|
58
|
+
const updatedProjectConfig = updateProjectConfig(templateVersion, targetProjectConfig);
|
|
59
|
+
const migrationPlans = planMigrations(targetProjectConfig.managedFiles, updatedProjectConfig.managedFiles, updatedProjectConfig.lastTemplateVersion);
|
|
60
|
+
return {
|
|
61
|
+
migrationPlans,
|
|
62
|
+
targetProjectConfig,
|
|
63
|
+
updatedProjectConfig,
|
|
64
|
+
};
|
|
65
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { dirname, relative } from 'node:path';
|
|
2
|
+
import { normalizePath } from 'vite';
|
|
3
|
+
import { describe, expect, it } from 'vitest';
|
|
4
|
+
import { INIT_TEMPLATE_VERSION, MANAGED_TEMPLATES, } from '../templates/constants.js';
|
|
5
|
+
import { collectManagedFiles, LAST_TEMPLATE_VERSION, TEMPLATES_DIR } from '../templates/templates.js';
|
|
6
|
+
import { planMigrations } from './planner.js';
|
|
7
|
+
const buildTestCases = () => {
|
|
8
|
+
const testCases = [];
|
|
9
|
+
let fromVersion = INIT_TEMPLATE_VERSION;
|
|
10
|
+
const lastVersion = LAST_TEMPLATE_VERSION;
|
|
11
|
+
while (fromVersion <= lastVersion) {
|
|
12
|
+
const testCase = {
|
|
13
|
+
fromVersion,
|
|
14
|
+
lastVersion,
|
|
15
|
+
targetManagedFiles: collectManagedFiles(TEMPLATES_DIR, MANAGED_TEMPLATES, fromVersion),
|
|
16
|
+
managedFiles: collectManagedFiles(TEMPLATES_DIR, MANAGED_TEMPLATES, lastVersion),
|
|
17
|
+
};
|
|
18
|
+
testCases.push(testCase);
|
|
19
|
+
fromVersion++;
|
|
20
|
+
}
|
|
21
|
+
return testCases;
|
|
22
|
+
};
|
|
23
|
+
const normalizeMigrationPlans = (migrationPlans) => {
|
|
24
|
+
return migrationPlans.map((migrationPlan) => {
|
|
25
|
+
const scriptPathResl = normalizePath(relative(dirname(TEMPLATES_DIR), migrationPlan.scriptPath));
|
|
26
|
+
return {
|
|
27
|
+
type: 'script',
|
|
28
|
+
scriptPath: scriptPathResl,
|
|
29
|
+
templateRelPath: normalizePath(migrationPlan.templateRelPath),
|
|
30
|
+
templateVersion: migrationPlan.templateVersion,
|
|
31
|
+
};
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
const TEST_CASES = buildTestCases();
|
|
35
|
+
describe('planMigrations', { tags: ['snapshot'] }, () => {
|
|
36
|
+
it.each(TEST_CASES)('from version $fromVersion to last version $lastVersion', ({ lastVersion, managedFiles, targetManagedFiles }) => {
|
|
37
|
+
const migrationPlans = planMigrations(targetManagedFiles, managedFiles, lastVersion);
|
|
38
|
+
expect(normalizeMigrationPlans(migrationPlans)).toMatchSnapshot();
|
|
39
|
+
});
|
|
40
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { TProjectConfig } from '../types.js';
|
|
2
|
+
export type TMigrationContext = {
|
|
3
|
+
generatedProjectDir: string;
|
|
4
|
+
projectDir: string;
|
|
5
|
+
targetProjectConfig: TProjectConfig;
|
|
6
|
+
templateVersion: number;
|
|
7
|
+
updatedProjectConfig: TProjectConfig;
|
|
8
|
+
};
|
|
9
|
+
export type TMigrationChange = {
|
|
10
|
+
filePath: string;
|
|
11
|
+
relFilePath: string;
|
|
12
|
+
};
|
|
13
|
+
export type TMigrationPlan = {
|
|
14
|
+
scriptPath: string;
|
|
15
|
+
templateRelPath: string;
|
|
16
|
+
templateVersion: number;
|
|
17
|
+
};
|
|
18
|
+
export type TMigrationExecutionPlan = {
|
|
19
|
+
migrationPlans: TMigrationPlan[];
|
|
20
|
+
targetProjectConfig: TProjectConfig;
|
|
21
|
+
updatedProjectConfig: TProjectConfig;
|
|
22
|
+
};
|
|
23
|
+
export type TMigration = {
|
|
24
|
+
up(ctx: TMigrationContext): TMigrationChange[];
|
|
25
|
+
};
|
|
26
|
+
export type TMigrationDiff = {
|
|
27
|
+
diff: string;
|
|
28
|
+
filePath: string;
|
|
29
|
+
};
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { mkdtempSync, readFileSync, rmSync } from 'node:fs';
|
|
2
|
+
import { tmpdir } from 'node:os';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { describe, expect, it } from 'vitest';
|
|
5
|
+
import { CLI_COMMANDS_MAP, EXT_HELPER_VERSION } from '../../constants.js';
|
|
6
|
+
import { toNormalizedRelPath } from '../../helpers/normalizePath.js';
|
|
7
|
+
import { buildProjectConfig } from '../../projectConfig/buildProjectConfig.js';
|
|
8
|
+
import { executeCommands } from '../../templater/executor.js';
|
|
9
|
+
import { mapProjectConfigToTemplateData } from '../../templater/mappers/mapProjectConfigToTemplateModel.js';
|
|
10
|
+
import { planProject } from '../../templater/planner.js';
|
|
11
|
+
import { MANAGED_TEMPLATES } from '../../templates/constants.js';
|
|
12
|
+
import { collectManagedFiles, discoverVersionDirs, LAST_TEMPLATE_VERSION, TEMPLATES_DIR, } from '../../templates/templates.js';
|
|
13
|
+
import { executeMigrations } from '../executor.js';
|
|
14
|
+
import { planMigrationExecution } from '../planner.js';
|
|
15
|
+
const testBuildProjectConfigOptions = {
|
|
16
|
+
category: 'games-and-fun',
|
|
17
|
+
framework: 'preact',
|
|
18
|
+
lastTemplateVersion: LAST_TEMPLATE_VERSION,
|
|
19
|
+
cliCommands: {
|
|
20
|
+
cli: 'old-cli-command',
|
|
21
|
+
'cli:update': 'old-update-command',
|
|
22
|
+
},
|
|
23
|
+
managedTemplates: MANAGED_TEMPLATES,
|
|
24
|
+
templatesDir: TEMPLATES_DIR,
|
|
25
|
+
name: 'test',
|
|
26
|
+
slots: ['EXTENSION_SLOT_MAIN_GAME_FUN', 'EXTENSION_SLOT_BACKGROUND'],
|
|
27
|
+
extHelperVersion: EXT_HELPER_VERSION,
|
|
28
|
+
language: 'ts',
|
|
29
|
+
packageManager: 'npm',
|
|
30
|
+
};
|
|
31
|
+
const compareManagedFiles = (targetProjectDir, referenceProjectDir, templateVersion, migrationPlans) => {
|
|
32
|
+
const managedFiles = collectManagedFiles(TEMPLATES_DIR, MANAGED_TEMPLATES, templateVersion);
|
|
33
|
+
const diffFileRelPaths = [];
|
|
34
|
+
const migrationPlansFilesSet = new Set();
|
|
35
|
+
migrationPlans.forEach((migrationPlan) => {
|
|
36
|
+
migrationPlansFilesSet.add(migrationPlan.templateRelPath);
|
|
37
|
+
});
|
|
38
|
+
for (const managedFile of managedFiles) {
|
|
39
|
+
if (!migrationPlansFilesSet.has(managedFile.relPath)) {
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
const targetFileContent = readFileSync(join(targetProjectDir, managedFile.relPath), 'utf8');
|
|
43
|
+
const referenceFileContent = readFileSync(join(referenceProjectDir, managedFile.relPath), 'utf8');
|
|
44
|
+
if (targetFileContent !== referenceFileContent) {
|
|
45
|
+
diffFileRelPaths.push(managedFile.relPath);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return diffFileRelPaths;
|
|
49
|
+
};
|
|
50
|
+
describe('updates', () => {
|
|
51
|
+
const versionDirs = discoverVersionDirs(TEMPLATES_DIR, LAST_TEMPLATE_VERSION, 'asc');
|
|
52
|
+
for (const versionDir of versionDirs) {
|
|
53
|
+
const templateVersion = versionDir.version;
|
|
54
|
+
it(`runs updates for v${templateVersion}`, async () => {
|
|
55
|
+
const targetProjectDir = mkdtempSync(join(tmpdir(), 'sce-test-target-project-dir'));
|
|
56
|
+
const referenceProjectDir = mkdtempSync(join(tmpdir(), 'sce-test-reference-project-dir'));
|
|
57
|
+
try {
|
|
58
|
+
const targetProjectConfig = buildProjectConfig({
|
|
59
|
+
...testBuildProjectConfigOptions,
|
|
60
|
+
lastTemplateVersion: templateVersion,
|
|
61
|
+
});
|
|
62
|
+
const targetTemplateData = mapProjectConfigToTemplateData(targetProjectConfig);
|
|
63
|
+
const targetCommands = planProject(targetProjectDir, templateVersion, targetTemplateData);
|
|
64
|
+
executeCommands(targetCommands);
|
|
65
|
+
const referenceProjectConfig = buildProjectConfig({
|
|
66
|
+
...testBuildProjectConfigOptions,
|
|
67
|
+
cliCommands: CLI_COMMANDS_MAP,
|
|
68
|
+
lastTemplateVersion: templateVersion,
|
|
69
|
+
});
|
|
70
|
+
const referenceTemplateData = mapProjectConfigToTemplateData({
|
|
71
|
+
...referenceProjectConfig,
|
|
72
|
+
lastTemplateVersion: templateVersion,
|
|
73
|
+
});
|
|
74
|
+
const referenceCommands = planProject(referenceProjectDir, templateVersion, referenceTemplateData);
|
|
75
|
+
executeCommands(referenceCommands);
|
|
76
|
+
const executionPlan = planMigrationExecution(targetProjectConfig, templateVersion);
|
|
77
|
+
await executeMigrations({
|
|
78
|
+
projectDir: targetProjectDir,
|
|
79
|
+
executionPlan,
|
|
80
|
+
isDryRun: false,
|
|
81
|
+
});
|
|
82
|
+
const isOnlyUpdates = executionPlan.migrationPlans.every((migrationPlan) => {
|
|
83
|
+
return toNormalizedRelPath(migrationPlan.scriptPath).includes('/updates/');
|
|
84
|
+
});
|
|
85
|
+
expect(isOnlyUpdates).toBe(true);
|
|
86
|
+
const result = compareManagedFiles(targetProjectDir, referenceProjectDir, templateVersion, executionPlan.migrationPlans);
|
|
87
|
+
expect(result).toEqual([]);
|
|
88
|
+
const idempotentExecutionPlan = planMigrationExecution(targetProjectConfig, templateVersion);
|
|
89
|
+
const idempotentResult = await executeMigrations({
|
|
90
|
+
projectDir: targetProjectDir,
|
|
91
|
+
executionPlan: idempotentExecutionPlan,
|
|
92
|
+
isDryRun: false,
|
|
93
|
+
});
|
|
94
|
+
expect(idempotentResult).toEqual([]);
|
|
95
|
+
}
|
|
96
|
+
finally {
|
|
97
|
+
rmSync(targetProjectDir, { recursive: true, force: true });
|
|
98
|
+
rmSync(referenceProjectDir, { recursive: true, force: true });
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
});
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { dirname, join } from 'node:path';
|
|
3
|
+
import { AGENTS_MD_REL_PATH, AGENTS_TEMPLATE_END, AGENTS_TEMPLATE_START } from '../../../../constants.js';
|
|
4
|
+
const agentsReplaceRegexp = new RegExp(`${AGENTS_TEMPLATE_START}[\\s\\S]*${AGENTS_TEMPLATE_END}`);
|
|
5
|
+
export const up = (ctx) => {
|
|
6
|
+
const targetAgentsFilePath = join(ctx.projectDir, AGENTS_MD_REL_PATH);
|
|
7
|
+
const generatedAgentsPath = join(ctx.generatedProjectDir, AGENTS_MD_REL_PATH);
|
|
8
|
+
const generatedAgentsContent = readFileSync(generatedAgentsPath, 'utf8');
|
|
9
|
+
if (!existsSync(targetAgentsFilePath)) {
|
|
10
|
+
mkdirSync(dirname(targetAgentsFilePath), { recursive: true });
|
|
11
|
+
copyFileSync(generatedAgentsPath, targetAgentsFilePath);
|
|
12
|
+
return [
|
|
13
|
+
{
|
|
14
|
+
filePath: targetAgentsFilePath,
|
|
15
|
+
relFilePath: AGENTS_MD_REL_PATH,
|
|
16
|
+
},
|
|
17
|
+
];
|
|
18
|
+
}
|
|
19
|
+
const targetAgentsContent = readFileSync(targetAgentsFilePath, 'utf8');
|
|
20
|
+
const generatedTrimmedContent = generatedAgentsContent.trim();
|
|
21
|
+
const hasGeneratedMarkers = agentsReplaceRegexp.test(targetAgentsContent);
|
|
22
|
+
const newAgentsContent = hasGeneratedMarkers
|
|
23
|
+
? targetAgentsContent.replace(agentsReplaceRegexp, generatedTrimmedContent)
|
|
24
|
+
: `${generatedTrimmedContent}\n\n${targetAgentsContent}`;
|
|
25
|
+
if (newAgentsContent === targetAgentsContent) {
|
|
26
|
+
return [];
|
|
27
|
+
}
|
|
28
|
+
writeFileSync(targetAgentsFilePath, newAgentsContent, {
|
|
29
|
+
encoding: 'utf8',
|
|
30
|
+
flag: 'w',
|
|
31
|
+
});
|
|
32
|
+
return [
|
|
33
|
+
{
|
|
34
|
+
filePath: targetAgentsFilePath,
|
|
35
|
+
relFilePath: AGENTS_MD_REL_PATH,
|
|
36
|
+
},
|
|
37
|
+
];
|
|
38
|
+
};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { dirname, join } from 'node:path';
|
|
3
|
+
import { PACKAGE_JSON_REL_PATH } from '../../../../constants.js';
|
|
4
|
+
import { AppError } from '../../../../helpers/error.js';
|
|
5
|
+
const resolvePackageJson = (packageJsonPath) => {
|
|
6
|
+
const packageJsonContent = readFileSync(packageJsonPath, 'utf8');
|
|
7
|
+
let packageJson;
|
|
8
|
+
try {
|
|
9
|
+
packageJson = JSON.parse(packageJsonContent);
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
throw new AppError(`Failed to parse package json: ${packageJsonPath}`);
|
|
13
|
+
}
|
|
14
|
+
return {
|
|
15
|
+
packageJson,
|
|
16
|
+
packageJsonContent,
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
const updateDependencies = (packageJson, newProjectConfig) => {
|
|
20
|
+
const { dependencies, devDependencies } = newProjectConfig;
|
|
21
|
+
const newPackageJson = structuredClone(packageJson);
|
|
22
|
+
if (!newPackageJson.dependencies) {
|
|
23
|
+
newPackageJson.dependencies = {};
|
|
24
|
+
}
|
|
25
|
+
for (const packageName in dependencies) {
|
|
26
|
+
const packageVersion = dependencies[packageName];
|
|
27
|
+
if (!packageVersion) {
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
if (newPackageJson.dependencies[packageName] !== packageVersion) {
|
|
31
|
+
newPackageJson.dependencies[packageName] = packageVersion;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (!newPackageJson.devDependencies) {
|
|
35
|
+
newPackageJson.devDependencies = {};
|
|
36
|
+
}
|
|
37
|
+
for (const packageName in devDependencies) {
|
|
38
|
+
const packageVersion = devDependencies[packageName];
|
|
39
|
+
if (!packageVersion) {
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
if (newPackageJson.devDependencies[packageName] !== packageVersion) {
|
|
43
|
+
newPackageJson.devDependencies[packageName] = packageVersion;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return newPackageJson;
|
|
47
|
+
};
|
|
48
|
+
export const up = (ctx) => {
|
|
49
|
+
const targetPackageJsonPath = join(ctx.projectDir, PACKAGE_JSON_REL_PATH);
|
|
50
|
+
const generatedPackageJsonPath = join(ctx.generatedProjectDir, PACKAGE_JSON_REL_PATH);
|
|
51
|
+
if (!existsSync(targetPackageJsonPath)) {
|
|
52
|
+
mkdirSync(dirname(targetPackageJsonPath), { recursive: true });
|
|
53
|
+
copyFileSync(generatedPackageJsonPath, targetPackageJsonPath);
|
|
54
|
+
return [
|
|
55
|
+
{
|
|
56
|
+
filePath: targetPackageJsonPath,
|
|
57
|
+
relFilePath: PACKAGE_JSON_REL_PATH,
|
|
58
|
+
},
|
|
59
|
+
];
|
|
60
|
+
}
|
|
61
|
+
const { packageJson, packageJsonContent } = resolvePackageJson(targetPackageJsonPath);
|
|
62
|
+
const updatedPackageJson = updateDependencies(packageJson, ctx.updatedProjectConfig);
|
|
63
|
+
const newPackageJsonContent = `${JSON.stringify(updatedPackageJson, null, 2)}\n`;
|
|
64
|
+
if (newPackageJsonContent === packageJsonContent) {
|
|
65
|
+
return [];
|
|
66
|
+
}
|
|
67
|
+
writeFileSync(targetPackageJsonPath, newPackageJsonContent, {
|
|
68
|
+
encoding: 'utf8',
|
|
69
|
+
flag: 'w',
|
|
70
|
+
});
|
|
71
|
+
return [
|
|
72
|
+
{
|
|
73
|
+
filePath: targetPackageJsonPath,
|
|
74
|
+
relFilePath: PACKAGE_JSON_REL_PATH,
|
|
75
|
+
},
|
|
76
|
+
];
|
|
77
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { dirname, join } from 'node:path';
|
|
3
|
+
import { PACKAGE_JSON_REL_PATH } from '../../../../constants.js';
|
|
4
|
+
import { AppError } from '../../../../helpers/error.js';
|
|
5
|
+
const resolvePackageJson = (packageJsonPath) => {
|
|
6
|
+
const packageJsonContent = readFileSync(packageJsonPath, 'utf8');
|
|
7
|
+
let packageJson;
|
|
8
|
+
try {
|
|
9
|
+
packageJson = JSON.parse(packageJsonContent);
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
throw new AppError(`Failed to parse package json: ${packageJsonPath}`);
|
|
13
|
+
}
|
|
14
|
+
return {
|
|
15
|
+
packageJson,
|
|
16
|
+
packageJsonContent,
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
const updateCliCommands = (packageJson, projectConfig, newProjectConfig) => {
|
|
20
|
+
const newPackageJson = structuredClone(packageJson);
|
|
21
|
+
if (!newPackageJson.scripts) {
|
|
22
|
+
throw new AppError('Section scripts in package.json not found');
|
|
23
|
+
}
|
|
24
|
+
for (const commandName in projectConfig.cliCommands) {
|
|
25
|
+
delete newPackageJson.scripts[commandName];
|
|
26
|
+
}
|
|
27
|
+
for (const commandName in newProjectConfig.cliCommands) {
|
|
28
|
+
newPackageJson.scripts[commandName] = newProjectConfig.cliCommands[commandName];
|
|
29
|
+
}
|
|
30
|
+
return newPackageJson;
|
|
31
|
+
};
|
|
32
|
+
export const up = (ctx) => {
|
|
33
|
+
const targetPackageJsonPath = join(ctx.projectDir, PACKAGE_JSON_REL_PATH);
|
|
34
|
+
const generatedPackageJsonPath = join(ctx.generatedProjectDir, PACKAGE_JSON_REL_PATH);
|
|
35
|
+
if (!existsSync(targetPackageJsonPath)) {
|
|
36
|
+
mkdirSync(dirname(targetPackageJsonPath), { recursive: true });
|
|
37
|
+
copyFileSync(generatedPackageJsonPath, targetPackageJsonPath);
|
|
38
|
+
return [
|
|
39
|
+
{
|
|
40
|
+
filePath: targetPackageJsonPath,
|
|
41
|
+
relFilePath: PACKAGE_JSON_REL_PATH,
|
|
42
|
+
},
|
|
43
|
+
];
|
|
44
|
+
}
|
|
45
|
+
const { packageJson, packageJsonContent } = resolvePackageJson(targetPackageJsonPath);
|
|
46
|
+
const newPackageJson = updateCliCommands(packageJson, ctx.targetProjectConfig, ctx.updatedProjectConfig);
|
|
47
|
+
const newPackageJsonContent = `${JSON.stringify(newPackageJson, null, 2)}\n`;
|
|
48
|
+
if (newPackageJsonContent === packageJsonContent) {
|
|
49
|
+
return [];
|
|
50
|
+
}
|
|
51
|
+
writeFileSync(targetPackageJsonPath, newPackageJsonContent, {
|
|
52
|
+
encoding: 'utf8',
|
|
53
|
+
flag: 'w',
|
|
54
|
+
});
|
|
55
|
+
return [
|
|
56
|
+
{
|
|
57
|
+
filePath: targetPackageJsonPath,
|
|
58
|
+
relFilePath: PACKAGE_JSON_REL_PATH,
|
|
59
|
+
},
|
|
60
|
+
];
|
|
61
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { getIsValidMigration } from './getIsValidMigration.js';
|
|
3
|
+
describe('getIsValidMigration', () => {
|
|
4
|
+
it('returns true for migration-like object with up function', () => {
|
|
5
|
+
const value = {
|
|
6
|
+
up: () => [],
|
|
7
|
+
};
|
|
8
|
+
expect(getIsValidMigration(value)).toBe(true);
|
|
9
|
+
});
|
|
10
|
+
it.each([null, undefined, 42, 'migration', true, {}, { up: 1 }, { up: 'fn' }, { up: null }])('returns false for invalid migration shape: %p', (value) => {
|
|
11
|
+
expect(getIsValidMigration(value)).toBe(false);
|
|
12
|
+
});
|
|
13
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { TCategory, TCliCommandsMap, TFramework, TLanguage, TPackageManager, TProjectConfig, TRelPath, TSlot } from '../types.js';
|
|
2
|
+
export type TBuildProjectConfigOptions = {
|
|
3
|
+
category: TCategory;
|
|
4
|
+
cliCommands: TCliCommandsMap;
|
|
5
|
+
extHelperVersion: string;
|
|
6
|
+
framework: TFramework;
|
|
7
|
+
language: TLanguage;
|
|
8
|
+
lastTemplateVersion: number;
|
|
9
|
+
managedTemplates: TRelPath[];
|
|
10
|
+
name: string;
|
|
11
|
+
packageManager: TPackageManager;
|
|
12
|
+
slots: TSlot[];
|
|
13
|
+
templatesDir: string;
|
|
14
|
+
};
|
|
15
|
+
export declare const buildProjectConfig: (options: TBuildProjectConfigOptions) => TProjectConfig;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { resolveDependencies } from '../dependencies/resolveDependencies.js';
|
|
2
|
+
import { toNormalizedRelPath } from '../helpers/normalizePath.js';
|
|
3
|
+
import { collectManagedFiles, TEMPLATES_DIR } from '../templates/templates.js';
|
|
4
|
+
export const buildProjectConfig = (options) => {
|
|
5
|
+
const { category, cliCommands, extHelperVersion, framework, language, lastTemplateVersion, managedTemplates, name, packageManager, slots, } = options;
|
|
6
|
+
const { dependencies, devDependencies } = resolveDependencies(language, framework);
|
|
7
|
+
const managedFiles = collectManagedFiles(TEMPLATES_DIR, managedTemplates, lastTemplateVersion).map((file) => {
|
|
8
|
+
return {
|
|
9
|
+
...file,
|
|
10
|
+
relPath: toNormalizedRelPath(file.relPath),
|
|
11
|
+
};
|
|
12
|
+
});
|
|
13
|
+
return {
|
|
14
|
+
lastTemplateVersion,
|
|
15
|
+
name,
|
|
16
|
+
category,
|
|
17
|
+
language,
|
|
18
|
+
framework,
|
|
19
|
+
packageManager,
|
|
20
|
+
dependencies,
|
|
21
|
+
devDependencies,
|
|
22
|
+
slots,
|
|
23
|
+
cliCommands,
|
|
24
|
+
managedFiles: managedFiles,
|
|
25
|
+
extHelperVersion,
|
|
26
|
+
};
|
|
27
|
+
};
|