@azure-net/cli 5.1.1 → 6.0.0-next.3

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.
Files changed (180) hide show
  1. package/README.md +201 -0
  2. package/bin/azure-net.js +236 -221
  3. package/dist/bin/azure-net.d.ts +2 -0
  4. package/dist/src/checks/architecture.d.ts +20 -0
  5. package/dist/src/checks/checkDomain.d.ts +1 -0
  6. package/dist/src/checks/checkFoldersStructure.d.ts +1 -0
  7. package/dist/src/checks/checkHooks.d.ts +1 -0
  8. package/dist/src/checks/checkImports.d.ts +1 -0
  9. package/dist/src/checks/checkInternal.d.ts +1 -0
  10. package/dist/src/checks/checkLayerBoundaries.d.ts +1 -0
  11. package/dist/src/checks/checkLayerImports.d.ts +1 -0
  12. package/dist/src/checks/checkPresenterNames.d.ts +1 -0
  13. package/dist/src/checks/checkProject.d.ts +1 -0
  14. package/dist/src/checks/checkProviderGraph.d.ts +1 -0
  15. package/dist/src/checks/checkProviderNames.d.ts +1 -0
  16. package/dist/src/generate/layers/generateRepository.d.ts +1 -0
  17. package/dist/src/generate/layers/generateRepositoryMethod.d.ts +1 -0
  18. package/dist/src/generate/layers/generateUseCases.d.ts +1 -0
  19. package/dist/src/generate/module/generateDomain.d.ts +8 -0
  20. package/dist/src/generate/module/generateModule.d.ts +1 -0
  21. package/dist/src/generate/module/generateModulePreset.d.ts +1 -0
  22. package/dist/src/generate/module/generatePresenter.d.ts +29 -0
  23. package/dist/src/generate/module/generateRepository.d.ts +15 -0
  24. package/dist/src/generate/module/generateRepositoryMethod.d.ts +2 -0
  25. package/dist/src/generate/module/generateSchemaFromType.d.ts +9 -0
  26. package/dist/src/generate/module/generateStore.d.ts +1 -0
  27. package/dist/src/generate/module/generateTypesJson.d.ts +2 -0
  28. package/dist/src/generate/module/generateUseCases.d.ts +1 -0
  29. package/dist/src/generate/module/repositoryModuleShared.d.ts +89 -0
  30. package/dist/src/generate/routes/generateRoutes.d.ts +14 -0
  31. package/dist/src/generate/ui/generateComponent.d.ts +1 -0
  32. package/dist/src/generate/ui/generateDesignComponent.d.ts +1 -0
  33. package/dist/src/generate/ui/generateWidget.d.ts +1 -0
  34. package/dist/src/git/commit.d.ts +23 -0
  35. package/dist/src/git/push.d.ts +11 -0
  36. package/dist/src/git/runGit.d.ts +2 -0
  37. package/dist/src/init/initAliases.d.ts +12 -0
  38. package/dist/src/init/initEdges.d.ts +2 -0
  39. package/dist/src/init/initStructure.d.ts +1 -0
  40. package/dist/src/install/configureCommitTools.d.ts +1 -0
  41. package/dist/src/install/installFresh.d.ts +1 -0
  42. package/dist/src/migrate/migrate.d.ts +22 -0
  43. package/dist/src/migrate/presenterFactories.d.ts +9 -0
  44. package/dist/src/migrate/presenters.d.ts +13 -0
  45. package/dist/src/migrate/translations.d.ts +8 -0
  46. package/dist/src/plugins/addLint.d.ts +5 -0
  47. package/dist/src/scaffolds/createCoreSchema.d.ts +1 -0
  48. package/dist/src/scaffolds/createDatasource.d.ts +1 -0
  49. package/dist/src/scaffolds/createProgram.d.ts +1 -0
  50. package/dist/src/scaffolds/createResponse.d.ts +1 -0
  51. package/dist/src/scaffolds/createSchemaRule.d.ts +1 -0
  52. package/dist/src/scaffolds/createTranslationManager.d.ts +1 -0
  53. package/{src/scaffolds/index.ts → dist/src/scaffolds/index.d.ts} +0 -2
  54. package/dist/src/scaffolds/registerDatasource.d.ts +2 -0
  55. package/dist/src/scaffolds/updateDefaultFactoryConfig.d.ts +1 -0
  56. package/dist/src/utils/architecture.d.ts +31 -0
  57. package/dist/src/utils/contextUtils.d.ts +6 -0
  58. package/dist/src/utils/fileUtils.d.ts +5 -0
  59. package/dist/src/utils/flattenConfig.d.ts +2 -0
  60. package/dist/src/utils/legacyAliases.d.ts +1 -0
  61. package/dist/src/utils/loadConfig.d.ts +16 -0
  62. package/dist/src/utils/packageImports.d.ts +4 -0
  63. package/dist/src/utils/sharedFoundation.d.ts +20 -0
  64. package/dist/src/utils/viteConfig.d.ts +9 -0
  65. package/package.json +17 -7
  66. package/src/checks/architecture.js +154 -0
  67. package/src/checks/checkDomain.js +124 -154
  68. package/src/checks/checkFoldersStructure.js +64 -52
  69. package/src/checks/checkHooks.js +12 -12
  70. package/src/checks/checkImports.js +26 -142
  71. package/src/checks/checkInternal.js +27 -24
  72. package/src/checks/checkLayerBoundaries.js +22 -197
  73. package/src/checks/checkLayerImports.js +14 -134
  74. package/src/checks/checkPresenterNames.js +156 -143
  75. package/src/checks/checkProject.js +27 -26
  76. package/src/checks/checkProviderGraph.js +182 -166
  77. package/src/checks/checkProviderNames.js +123 -112
  78. package/src/generate/layers/generateRepository.js +1 -109
  79. package/src/generate/layers/generateRepositoryMethod.js +1 -90
  80. package/src/generate/layers/generateUseCases.js +1 -44
  81. package/src/generate/module/generateDomain.js +81 -105
  82. package/src/generate/module/generateModule.js +34 -68
  83. package/src/generate/module/generateModulePreset.js +188 -248
  84. package/src/generate/module/generatePresenter.js +441 -369
  85. package/src/generate/module/generateRepository.js +102 -121
  86. package/src/generate/module/generateRepositoryMethod.js +117 -0
  87. package/src/generate/module/generateSchemaFromType.js +283 -280
  88. package/src/generate/module/generateStore.js +41 -0
  89. package/src/generate/module/generateTypesJson.js +196 -195
  90. package/src/generate/module/generateUseCases.js +47 -55
  91. package/src/generate/module/repositoryModuleShared.js +480 -459
  92. package/src/generate/routes/generateRoutes.js +4 -7
  93. package/src/generate/ui/generateComponent.js +44 -64
  94. package/src/generate/ui/generateDesignComponent.js +21 -41
  95. package/src/generate/ui/generateWidget.js +21 -41
  96. package/src/git/commit.js +67 -0
  97. package/src/git/push.js +19 -0
  98. package/src/git/runGit.js +11 -0
  99. package/src/init/initAliases.js +19 -135
  100. package/src/init/initEdges.js +79 -54
  101. package/src/init/initStructure.js +31 -145
  102. package/src/install/configureCommitTools.js +1 -0
  103. package/src/install/installFresh.js +39 -68
  104. package/src/migrate/migrate.js +1027 -0
  105. package/src/migrate/presenterFactories.js +189 -0
  106. package/src/migrate/presenters.js +373 -0
  107. package/src/migrate/translations.js +213 -0
  108. package/src/plugins/addLint.js +52 -219
  109. package/src/scaffolds/createCoreSchema.js +65 -91
  110. package/src/scaffolds/createDatasource.js +67 -101
  111. package/src/scaffolds/createProgram.js +8 -8
  112. package/src/scaffolds/createResponse.js +29 -29
  113. package/src/scaffolds/createSchemaRule.js +19 -19
  114. package/src/scaffolds/createTranslationManager.js +84 -37
  115. package/src/scaffolds/index.js +0 -2
  116. package/src/scaffolds/registerDatasource.js +59 -0
  117. package/src/scaffolds/updateDefaultFactoryConfig.js +31 -0
  118. package/src/utils/architecture.js +145 -0
  119. package/src/utils/contextUtils.js +32 -65
  120. package/src/utils/fileUtils.js +69 -50
  121. package/src/utils/flattenConfig.js +38 -0
  122. package/src/utils/legacyAliases.js +75 -0
  123. package/src/utils/loadConfig.js +76 -40
  124. package/src/utils/packageImports.js +63 -0
  125. package/src/utils/sharedFoundation.js +36 -42
  126. package/src/utils/viteConfig.js +295 -0
  127. package/.prettierrc +0 -7
  128. package/bin/azure-net.ts +0 -308
  129. package/eslint.config.js +0 -34
  130. package/src/checks/checkDomain.ts +0 -223
  131. package/src/checks/checkFoldersStructure.ts +0 -85
  132. package/src/checks/checkHooks.ts +0 -22
  133. package/src/checks/checkImports.ts +0 -193
  134. package/src/checks/checkInternal.ts +0 -48
  135. package/src/checks/checkLayerBoundaries.ts +0 -255
  136. package/src/checks/checkLayerImports.ts +0 -185
  137. package/src/checks/checkPresenterNames.ts +0 -203
  138. package/src/checks/checkProject.ts +0 -45
  139. package/src/checks/checkProviderGraph.ts +0 -234
  140. package/src/checks/checkProviderNames.ts +0 -165
  141. package/src/generate/layers/generateRepository.ts +0 -123
  142. package/src/generate/layers/generateRepositoryMethod.ts +0 -102
  143. package/src/generate/layers/generateUseCases.ts +0 -50
  144. package/src/generate/layers/repositoryShared.js +0 -506
  145. package/src/generate/layers/repositoryShared.ts +0 -662
  146. package/src/generate/module/generateDomain.ts +0 -147
  147. package/src/generate/module/generateModule.ts +0 -84
  148. package/src/generate/module/generateModulePreset.ts +0 -338
  149. package/src/generate/module/generatePresenter.ts +0 -498
  150. package/src/generate/module/generateRepository.ts +0 -158
  151. package/src/generate/module/generateSchemaFromType.ts +0 -368
  152. package/src/generate/module/generateTypesJson.ts +0 -259
  153. package/src/generate/module/generateUseCases.ts +0 -67
  154. package/src/generate/module/repositoryModuleShared.ts +0 -669
  155. package/src/generate/routes/generateRoutes.ts +0 -275
  156. package/src/generate/ui/generateComponent.ts +0 -100
  157. package/src/generate/ui/generateDesignComponent.ts +0 -71
  158. package/src/generate/ui/generateWidget.ts +0 -71
  159. package/src/init/initAliases.ts +0 -172
  160. package/src/init/initEdges.ts +0 -74
  161. package/src/init/initStructure.ts +0 -172
  162. package/src/install/installFresh.ts +0 -93
  163. package/src/plugins/addLint.ts +0 -274
  164. package/src/scaffolds/createCoreSchema.ts +0 -130
  165. package/src/scaffolds/createDatasource.ts +0 -161
  166. package/src/scaffolds/createDatasourceProvider.js +0 -127
  167. package/src/scaffolds/createDatasourceProvider.ts +0 -161
  168. package/src/scaffolds/createPresenterFactory.js +0 -83
  169. package/src/scaffolds/createPresenterFactory.ts +0 -102
  170. package/src/scaffolds/createProgram.ts +0 -19
  171. package/src/scaffolds/createResponse.ts +0 -66
  172. package/src/scaffolds/createSchemaRule.ts +0 -44
  173. package/src/scaffolds/createTranslationManager.ts +0 -80
  174. package/src/utils/contextUtils.ts +0 -88
  175. package/src/utils/fileUtils.ts +0 -74
  176. package/src/utils/loadConfig.ts +0 -68
  177. package/src/utils/sharedFoundation.ts +0 -70
  178. package/tsconfig.json +0 -19
  179. /package/{src/checks/index.ts → dist/src/checks/index.d.ts} +0 -0
  180. /package/{src/plugins/index.ts → dist/src/plugins/index.d.ts} +0 -0
@@ -0,0 +1,63 @@
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { format } from 'prettier';
4
+ export const PACKAGE_IMPORTS = Object.fromEntries(['Contexts', 'Presentation', 'Platform'].flatMap((name) => {
5
+ const key = '#' + name.toLowerCase(), root = './src/app/' + name;
6
+ return [
7
+ [key, root + '/index.ts'],
8
+ [key + '/*', { types: [root + '/*.ts', root + '/*/index.ts', root + '/*'], default: root + '/*' }]
9
+ ];
10
+ }));
11
+ export async function mergePackageImports(content) {
12
+ const json = JSON.parse(content);
13
+ if (!json || typeof json !== 'object' || Array.isArray(json))
14
+ throw new Error('Expected a package.json object');
15
+ if (json.imports !== undefined && (!json.imports || typeof json.imports !== 'object' || Array.isArray(json.imports)))
16
+ throw new Error('Expected package.json imports object');
17
+ const imports = { ...json.imports };
18
+ for (const [key, value] of Object.entries(PACKAGE_IMPORTS)) {
19
+ if (key in imports && JSON.stringify(imports[key]) !== JSON.stringify(value))
20
+ throw new Error(`Conflicting package import ${key}; review its target before initialization.`);
21
+ imports[key] = value;
22
+ }
23
+ return format(JSON.stringify({ ...json, imports }), { parser: 'json', useTabs: true });
24
+ }
25
+ export async function initializePackageImports() {
26
+ const file = path.resolve('package.json');
27
+ let content;
28
+ try {
29
+ content = await fs.readFile(file, 'utf8');
30
+ }
31
+ catch (error) {
32
+ if (error.code !== 'ENOENT')
33
+ throw error;
34
+ content = '{}';
35
+ }
36
+ await fs.writeFile(file, await mergePackageImports(content));
37
+ }
38
+ export function resolvePackageImport(imports, specifier, root) {
39
+ const target = (v) => {
40
+ if (typeof v === 'string')
41
+ return v;
42
+ if (Array.isArray(v))
43
+ return v.map(target).find(Boolean);
44
+ if (v && typeof v === 'object') {
45
+ const obj = v;
46
+ return target(obj.default ?? obj.import ?? obj.types);
47
+ }
48
+ };
49
+ for (const key of Object.keys(imports).sort((a, b) => b.replace('*', '').length - a.replace('*', '').length)) {
50
+ const value = target(imports[key]);
51
+ if (!value?.startsWith('./'))
52
+ continue;
53
+ if (!key.includes('*')) {
54
+ if (key === specifier)
55
+ return path.resolve(root, value);
56
+ continue;
57
+ }
58
+ const [prefix, suffix = ''] = key.split('*');
59
+ if (specifier.startsWith(prefix) && specifier.endsWith(suffix))
60
+ return path.resolve(root, value.replace('*', specifier.slice(prefix.length, suffix ? -suffix.length : undefined)));
61
+ }
62
+ return null;
63
+ }
@@ -1,48 +1,42 @@
1
1
  import path from 'node:path';
2
- import { normalizeContexts } from '../init/initAliases.js';
3
- import { loadUserConfig, resolveConfigFile } from './loadConfig.js';
4
- export const SHARED_ESSENTIALS_DIR_NAME = 'essentials';
5
- const normalizeAlias = (value) => {
6
- const raw = String(value ?? '').trim();
7
- return raw.startsWith('$') ? raw : `$${raw}`;
2
+ import { discoverContexts, getContextPath, getPlatformPath, SHARED_CONTEXT } from './architecture.js';
3
+ import { resolveConfigFile } from './loadConfig.js';
4
+ export const SHARED_ESSENTIALS_DIR_NAME = 'Platform';
5
+ const constructNames = {
6
+ datasource: 'Datasource',
7
+ presenter: 'Presenter',
8
+ provider: 'DI',
9
+ response: 'Response',
10
+ schema: 'Schema'
8
11
  };
9
- const createMissingSharedAliasError = () =>
10
- new Error(
11
- '`sharedAlias` is missing in azure-net.config.ts/js. Add sharedAlias and make sure it points to one of `contexts`, for example: sharedAlias: "$shared-kernel".'
12
- );
13
- export const getSharedState = async () => {
14
- const config = await loadUserConfig();
15
- const contexts = normalizeContexts(config.contexts);
16
- const sharedAliasRaw = String(config.sharedAlias ?? '').trim();
17
- if (!sharedAliasRaw.length) throw createMissingSharedAliasError();
18
- const sharedAlias = normalizeAlias(sharedAliasRaw);
19
- const sharedContext = contexts.find((context) => normalizeAlias(context.alias) === sharedAlias);
20
- if (!sharedContext) {
21
- throw new Error(
22
- `sharedAlias "${sharedAlias}" does not point to any configured context. Add a context with alias "${sharedAlias}" in azure-net.config.ts/js.`
23
- );
24
- }
25
- return {
26
- contexts,
27
- sharedAlias,
28
- sharedContext
29
- };
12
+ export async function getSharedState() {
13
+ const names = await discoverContexts();
14
+ if (!names.includes(SHARED_CONTEXT))
15
+ names.push(SHARED_CONTEXT);
16
+ const contexts = names.sort().map((name) => ({ name, alias: `#contexts/${name}` }));
17
+ return { contexts, sharedAlias: '#platform', sharedContext: contexts.find((context) => context.name === SHARED_CONTEXT) };
18
+ }
19
+ export const hasSharedAliasConfig = async () => true;
20
+ export const getSharedContextRootPath = (name = SHARED_CONTEXT) => getContextPath(name);
21
+ export const getSharedEssentialsPath = (...compatibility) => {
22
+ void compatibility;
23
+ return getPlatformPath();
30
24
  };
31
- export const hasSharedAliasConfig = async () => {
32
- const config = await loadUserConfig();
33
- return String(config.sharedAlias ?? '').trim().length > 0;
25
+ export const getFoundationRootPath = (...compatibility) => {
26
+ void compatibility;
27
+ return path.join(getPlatformPath(), 'Foundation');
28
+ };
29
+ export const getFoundationConstructPath = (name, construct) => path.join(getFoundationRootPath(name), constructNames[construct]);
30
+ export const getFoundationConstructImportPath = (_alias, construct) => `#platform/Foundation/${constructNames[construct]}`;
31
+ export const getLocalizationPath = (...compatibility) => {
32
+ void compatibility;
33
+ return path.join(getPlatformPath(), 'Bootstrap', 'Localization');
34
+ };
35
+ export const getLocalizationImportPath = (...compatibility) => {
36
+ void compatibility;
37
+ return '#platform/Bootstrap/Localization';
34
38
  };
35
- export const getSharedContextRootPath = (sharedContextName) => path.join(process.cwd(), 'src', 'app', sharedContextName);
36
- export const getSharedEssentialsPath = (sharedContextName) =>
37
- path.join(getSharedContextRootPath(sharedContextName), SHARED_ESSENTIALS_DIR_NAME);
38
- export const getFoundationRootPath = (sharedContextName) =>
39
- path.join(getSharedEssentialsPath(sharedContextName), 'foundation', 'constructs');
40
- export const getFoundationConstructPath = (sharedContextName, construct) => path.join(getFoundationRootPath(sharedContextName), construct);
41
- export const getFoundationConstructImportPath = (sharedAlias, construct) =>
42
- `${sharedAlias}/${SHARED_ESSENTIALS_DIR_NAME}/foundation/constructs/${construct}`;
43
- export const getLocalizationPath = (sharedContextName) => path.join(getSharedEssentialsPath(sharedContextName), 'localization');
44
- export const getLocalizationImportPath = (sharedAlias) => `${sharedAlias}/${SHARED_ESSENTIALS_DIR_NAME}/localization`;
45
39
  export const getConfigFileLabel = () => {
46
- const config = resolveConfigFile();
47
- return config.exists ? path.basename(config.filepath) : 'azure-net.config.ts/js';
40
+ const config = resolveConfigFile();
41
+ return config.exists ? path.basename(config.filepath) : 'azure-net.config.ts/js';
48
42
  };
@@ -0,0 +1,295 @@
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import ts from 'typescript';
4
+ import { format, resolveConfig } from 'prettier';
5
+ import { mergeAliasesInSvelteConfig } from './legacyAliases.js';
6
+ import { ARCHITECTURE_ALIASES } from './architecture.js';
7
+ export const VITE_CONFIGS = ['vite.config.ts', 'vite.config.js', 'vite.config.mts', 'vite.config.mjs'];
8
+ export const SVELTE_CONFIGS = ['svelte.config.js', 'svelte.config.ts', 'svelte.config.mjs'];
9
+ const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });
10
+ const parse = (text) => ts.createSourceFile('config.ts', text, ts.ScriptTarget.Latest, true);
11
+ const name = (node) => node && (ts.isIdentifier(node) || ts.isStringLiteral(node)) ? node.text : undefined;
12
+ function object(expression, source, seen = new Set()) {
13
+ if (ts.isObjectLiteralExpression(expression))
14
+ return expression;
15
+ if (ts.isParenthesizedExpression(expression) || ts.isAsExpression(expression) || ts.isSatisfiesExpression(expression))
16
+ return object(expression.expression, source, seen);
17
+ if (ts.isIdentifier(expression) && !seen.has(expression.text)) {
18
+ seen.add(expression.text);
19
+ for (const statement of source.statements)
20
+ if (ts.isVariableStatement(statement))
21
+ for (const d of statement.declarationList.declarations)
22
+ if (name(d.name) === expression.text && d.initializer)
23
+ return object(d.initializer, source, seen);
24
+ }
25
+ throw new Error('Cannot safely edit dynamic SvelteKit options. Use an object literal or a local object variable in sveltekit().');
26
+ }
27
+ function kitCall(source) {
28
+ const names = new Set();
29
+ for (const s of source.statements)
30
+ if (ts.isImportDeclaration(s) && ts.isStringLiteral(s.moduleSpecifier) && s.moduleSpecifier.text === '@sveltejs/kit/vite') {
31
+ const b = s.importClause?.namedBindings;
32
+ if (b && ts.isNamedImports(b))
33
+ for (const e of b.elements)
34
+ if ((e.propertyName?.text ?? e.name.text) === 'sveltekit')
35
+ names.add(e.name.text);
36
+ }
37
+ const calls = [];
38
+ const visit = (n) => {
39
+ if (ts.isCallExpression(n) && ts.isIdentifier(n.expression) && names.has(n.expression.text))
40
+ calls.push(n);
41
+ ts.forEachChild(n, visit);
42
+ };
43
+ visit(source);
44
+ if (calls.length !== 1)
45
+ throw new Error('Expected exactly one imported sveltekit() call in vite.config. No files changed.');
46
+ return calls[0];
47
+ }
48
+ function modernOptions(input, source) {
49
+ const has = (obj, key) => obj.properties.some((p) => name(p.name) === key);
50
+ const nestedHas = (key, keys) => {
51
+ const property = input.properties.find((p) => name(p.name) === key);
52
+ if (!property || !ts.isPropertyAssignment(property))
53
+ return false;
54
+ const value = objectOrUndefined(property.initializer, source);
55
+ return value && keys.some((k) => has(value, k));
56
+ };
57
+ if (!['kit', 'vitePlugin', 'preloadStrategy'].some((k) => has(input, k)) &&
58
+ !nestedHas('files', ['lib']) &&
59
+ !nestedHas('experimental', ['handleRenderingErrors', 'instrumentation', 'tracing']) &&
60
+ !nestedHas('prerender', ['origin']) &&
61
+ !nestedHas('csrf', ['checkOrigin']))
62
+ return input.getText(source);
63
+ const print = (n) => printer.printNode(ts.EmitHint.Unspecified, n, source);
64
+ const props = [...input.properties];
65
+ const take = (items, key) => {
66
+ const found = items.findIndex((p) => name(p.name) === key);
67
+ if (found < 0)
68
+ return;
69
+ const p = items.splice(found, 1)[0];
70
+ if (!ts.isPropertyAssignment(p))
71
+ throw new Error(`Cannot safely convert option ${key}`);
72
+ return p.initializer;
73
+ };
74
+ const set = (items, key, value) => {
75
+ if (items.some((p) => name(p.name) === key))
76
+ throw new Error(`Conflicting SvelteKit option ${key}; resolve manually.`);
77
+ items.push(ts.factory.createPropertyAssignment(key, value));
78
+ };
79
+ const nested = (key, edit) => {
80
+ const value = take(props, key);
81
+ if (!value)
82
+ return;
83
+ const items = [...object(value, source).properties];
84
+ edit(items);
85
+ if (items.length)
86
+ set(props, key, ts.factory.createObjectLiteralExpression(items, true));
87
+ };
88
+ const oldKit = take(props, 'kit');
89
+ if (oldKit)
90
+ for (const p of object(oldKit, source).properties) {
91
+ if (props.some((existing) => name(existing.name) && name(existing.name) === name(p.name)))
92
+ throw new Error(`Conflicting option ${name(p.name)}`);
93
+ props.push(p);
94
+ }
95
+ const vitePlugin = take(props, 'vitePlugin');
96
+ if (vitePlugin)
97
+ for (const p of object(vitePlugin, source).properties) {
98
+ if (props.some((existing) => name(existing.name) && name(existing.name) === name(p.name)))
99
+ throw new Error(`Conflicting option ${name(p.name)}`);
100
+ props.push(p);
101
+ }
102
+ take(props, 'preloadStrategy');
103
+ nested('files', (items) => {
104
+ take(items, 'lib');
105
+ });
106
+ nested('experimental', (items) => {
107
+ take(items, 'handleRenderingErrors');
108
+ take(items, 'instrumentation');
109
+ const tracing = take(items, 'tracing');
110
+ if (tracing)
111
+ set(props, 'tracing', tracing);
112
+ });
113
+ let origin;
114
+ nested('prerender', (items) => {
115
+ origin = take(items, 'origin');
116
+ });
117
+ if (origin) {
118
+ const paths = take(props, 'paths');
119
+ const items = paths ? [...object(paths, source).properties] : [];
120
+ set(items, 'origin', origin);
121
+ set(props, 'paths', ts.factory.createObjectLiteralExpression(items, true));
122
+ }
123
+ nested('csrf', (items) => {
124
+ const check = take(items, 'checkOrigin');
125
+ if (!check)
126
+ return;
127
+ if (check.kind === ts.SyntaxKind.FalseKeyword) {
128
+ if (items.some((p) => name(p.name) === 'trustedOrigins'))
129
+ throw new Error('Resolve csrf.checkOrigin and trustedOrigins manually.');
130
+ set(items, 'trustedOrigins', ts.factory.createArrayLiteralExpression([ts.factory.createStringLiteral('*')]));
131
+ }
132
+ else if (check.kind !== ts.SyntaxKind.TrueKeyword)
133
+ throw new Error('Dynamic csrf.checkOrigin requires manual migration.');
134
+ });
135
+ return print(ts.factory.createObjectLiteralExpression(props, true));
136
+ }
137
+ /** Pure config edit; never evaluates a project's configuration. */
138
+ export function mergeKitViteConfig(content, aliases, legacy) {
139
+ let source = parse(content);
140
+ const call = kitCall(source);
141
+ let options = call.arguments[0] ? object(call.arguments[0], source) : undefined;
142
+ let optionText = options ? modernOptions(options, source) : '{}';
143
+ if (legacy) {
144
+ if (options && options.properties.length)
145
+ throw new Error('Both Vite and legacy Svelte config contain options. Merge them with sv migrate sveltekit-3 first.');
146
+ const old = parse(legacy), exported = old.statements.find(ts.isExportAssignment);
147
+ if (!exported)
148
+ throw new Error('Legacy Svelte config has no default export.');
149
+ const root = object(exported.expression, old);
150
+ optionText = modernOptions(root, old);
151
+ const imports = old.statements.filter(ts.isImportDeclaration);
152
+ const bindings = (s) => {
153
+ const names = new Set();
154
+ for (const n of s.statements) {
155
+ if (ts.isImportDeclaration(n)) {
156
+ if (n.importClause?.name)
157
+ names.add(n.importClause.name.text);
158
+ const b = n.importClause?.namedBindings;
159
+ if (b && ts.isNamespaceImport(b))
160
+ names.add(b.name.text);
161
+ if (b && ts.isNamedImports(b))
162
+ for (const e of b.elements)
163
+ names.add(e.name.text);
164
+ }
165
+ if (ts.isVariableStatement(n))
166
+ for (const d of n.declarationList.declarations)
167
+ if (ts.isIdentifier(d.name))
168
+ names.add(d.name.text);
169
+ }
170
+ return names;
171
+ };
172
+ const oldNames = bindings(old);
173
+ const currentNames = bindings(source);
174
+ for (const n of oldNames)
175
+ if (currentNames.has(n))
176
+ throw new Error(`Config binding collision: ${n}. Run sv migrate sveltekit-3 first.`);
177
+ const rootStatement = old.statements.find((s) => ts.isVariableStatement(s) &&
178
+ s.declarationList.declarations.some((d) => d.initializer && objectOrUndefined(d.initializer, old) === root));
179
+ if (rootStatement && ts.isVariableStatement(rootStatement) && rootStatement.declarationList.declarations.length !== 1)
180
+ throw new Error('Split legacy config variable declarations before migration.');
181
+ for (const statement of old.statements)
182
+ if (!ts.isImportDeclaration(statement) &&
183
+ !ts.isExportAssignment(statement) &&
184
+ statement !== rootStatement &&
185
+ !ts.isEmptyStatement(statement))
186
+ throw new Error('Complex legacy config: run sv migrate sveltekit-3 first.');
187
+ const importText = imports.map((s) => s.getText(old)).join('\n');
188
+ content = content.slice(0, call.arguments.pos) + optionText + content.slice(call.arguments.end);
189
+ content = importText + '\n' + content;
190
+ source = parse(content);
191
+ const updated = kitCall(source);
192
+ options = object(updated.arguments[0], source);
193
+ }
194
+ const synthetic = mergeAliasesInSvelteConfig(`export default { kit: ${optionText} };`, aliases);
195
+ const merged = parse(synthetic).statements.find(ts.isExportAssignment);
196
+ const kit = merged.expression.properties[0];
197
+ const replacement = kit.initializer.getText(merged.getSourceFile());
198
+ if (options)
199
+ return content.slice(0, options.getStart(source)) + replacement + content.slice(options.end);
200
+ const actual = kitCall(source);
201
+ return content.slice(0, actual.arguments.pos) + replacement + content.slice(actual.arguments.end);
202
+ }
203
+ function objectOrUndefined(e, source) {
204
+ try {
205
+ return object(e, source);
206
+ }
207
+ catch {
208
+ return undefined;
209
+ }
210
+ }
211
+ export async function formatConfig(content, file) {
212
+ return format(content, { ...(await resolveConfig(file)), filepath: file, parser: 'typescript' });
213
+ }
214
+ export async function configureKitProject() {
215
+ const root = process.cwd();
216
+ const existing = async (names) => {
217
+ for (const n of names) {
218
+ try {
219
+ await fs.access(path.join(root, n));
220
+ return path.join(root, n);
221
+ }
222
+ catch (error) {
223
+ if (error.code !== 'ENOENT')
224
+ throw error;
225
+ }
226
+ }
227
+ };
228
+ const vite = await existing(VITE_CONFIGS), legacy = await existing(SVELTE_CONFIGS);
229
+ if (!vite && !legacy) {
230
+ console.warn('No Vite config found; initialize a SvelteKit project first.');
231
+ return;
232
+ }
233
+ const file = vite ?? path.join(root, 'vite.config.ts');
234
+ const content = vite
235
+ ? await fs.readFile(vite, 'utf8')
236
+ : "import { defineConfig } from 'vite';\nimport { sveltekit } from '@sveltejs/kit/vite';\nexport default defineConfig({plugins: [sveltekit()]});\n";
237
+ const old = legacy ? await fs.readFile(legacy, 'utf8') : undefined;
238
+ const next = await formatConfig(mergeKitViteConfig(content, ARCHITECTURE_ALIASES, old), file);
239
+ if (legacy) {
240
+ const backup = await fs.mkdtemp(path.join(await fs
241
+ .mkdir(path.join(root, '.azure-net/ConfigBackups'), { recursive: true })
242
+ .then(() => path.join(root, '.azure-net/ConfigBackups')), 'kit3-'));
243
+ await fs.writeFile(path.join(backup, path.basename(legacy)), old);
244
+ if (vite)
245
+ await fs.writeFile(path.join(backup, path.basename(vite)), content);
246
+ }
247
+ await fs.writeFile(file, next);
248
+ if (legacy)
249
+ await fs.unlink(legacy);
250
+ }
251
+ export function readStaticAliases(content) {
252
+ const aliases = {};
253
+ const source = parse(content);
254
+ const visit = (n) => {
255
+ if (ts.isPropertyAssignment(n) && name(n.name) === 'alias') {
256
+ const value = objectOrUndefined(n.initializer, source);
257
+ if (value)
258
+ for (const p of value.properties)
259
+ if (ts.isPropertyAssignment(p) && name(p.name) && ts.isStringLiteral(p.initializer))
260
+ aliases[name(p.name)] = p.initializer.text;
261
+ }
262
+ ts.forEachChild(n, visit);
263
+ };
264
+ visit(source);
265
+ return aliases;
266
+ }
267
+ /** Hydratable needs Svelte async mode. Preserve all unrelated literal options. */
268
+ export function enableHydratable(content) {
269
+ const source = parse(content);
270
+ const call = kitCall(source);
271
+ const update = (value, keys) => {
272
+ const key = keys[0];
273
+ const props = [...value.properties];
274
+ const existing = props.find((p) => name(p.name) === key);
275
+ if (existing && !ts.isPropertyAssignment(existing))
276
+ throw new Error(`Cannot safely configure ${keys.join('.')}. Use literal compilerOptions.`);
277
+ if (props.some(ts.isSpreadAssignment))
278
+ throw new Error('Cannot safely enable async mode in spread options. Set compilerOptions.experimental.async: true manually.');
279
+ const next = keys.length === 1
280
+ ? ts.factory.createTrue()
281
+ : update(existing ? object(existing.initializer, source) : ts.factory.createObjectLiteralExpression(), keys.slice(1));
282
+ const index = props.findIndex((p) => name(p.name) === key);
283
+ const property = ts.factory.createPropertyAssignment(key, next);
284
+ if (index === -1)
285
+ props.push(property);
286
+ else
287
+ props[index] = property;
288
+ return ts.factory.createObjectLiteralExpression(props, true);
289
+ };
290
+ const options = call.arguments[0] ? object(call.arguments[0], source) : ts.factory.createObjectLiteralExpression();
291
+ const updated = update(options, ['compilerOptions', 'experimental', 'async']);
292
+ return (content.slice(0, call.getStart(source)) +
293
+ `${call.expression.getText(source)}(${ts.createPrinter().printNode(ts.EmitHint.Expression, updated, source)})` +
294
+ content.slice(call.end));
295
+ }
package/.prettierrc DELETED
@@ -1,7 +0,0 @@
1
- {
2
- "useTabs": true,
3
- "singleQuote": true,
4
- "trailingComma": "none",
5
- "printWidth": 140,
6
- "semi": true
7
- }