@azure-net/cli 2.0.0 → 2.0.2

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.
@@ -1,10 +1,11 @@
1
1
  import prompts from 'prompts';
2
2
  import path from 'path';
3
+ import fs from 'fs/promises';
3
4
  import { selectContext, getContextPath, toPascalCase, getAvailableFiles } from '../../utils/contextUtils.js';
4
5
  import { writeIfNotExists, updateIndexTs } from '../../utils/fileUtils.js';
5
6
 
6
- const schemaWithCoreTemplate = `import { {{coreSchema}} } from '$core/Schemas/index.js';
7
- import type { I{{name}}Request } from '../../Domain/Ports/{{name}}/index.js';
7
+ const schemaWithCoreTemplate = `import { {{coreSchema}} } from '\$core/Schema';
8
+ import type { I{{name}}Request } from '\${{context}}/Domain/Ports/{{entity}}';
8
9
 
9
10
  export const {{name}}Schema = {{coreSchema}}<I{{name}}Request>()
10
11
  \t.rules((rules) => ({
@@ -12,10 +13,13 @@ export const {{name}}Schema = {{coreSchema}}<I{{name}}Request>()
12
13
  \t}))
13
14
  \t.create();`;
14
15
 
15
- const schemaWithPackageTemplate = `import { schema } from '@azure-net/kit';
16
- import type { I{{name}}Request } from '../../Domain/Ports/{{name}}/index.js';
16
+ const schemaWithPackageTemplate = `import { createSchemaFactory } from '@azure-net/kit';
17
+ import { createRules, validationMessagesI18n } from '@azure-net/kit/schema';
18
+ import type { I{{name}}Request } from '\${{context}}/Domain/Ports/{{entity}}';
17
19
 
18
- export const {{name}}Schema = schema<I{{name}}Request>()
20
+ const Schema = createSchemaFactory(createRules(validationMessagesI18n));
21
+
22
+ export const {{name}}Schema = Schema<I{{name}}Request>()
19
23
  \t.rules((rules) => ({
20
24
  \t\t// Add validation rules here
21
25
  \t}))
@@ -29,6 +33,12 @@ export default async function generateSchema() {
29
33
  return;
30
34
  }
31
35
 
36
+ const { module } = await prompts({
37
+ type: 'text',
38
+ name: 'module',
39
+ message: 'Module name (folder in Delivery):'
40
+ });
41
+
32
42
  const { name } = await prompts({
33
43
  type: 'text',
34
44
  name: 'name',
@@ -37,11 +47,11 @@ export default async function generateSchema() {
37
47
 
38
48
  // Check for core schemas
39
49
  const coreSchemas = await getAvailableFiles(
40
- path.join(process.cwd(), 'src/app/core/Schemas')
50
+ path.join(process.cwd(), 'src/app/core/Schema')
41
51
  );
42
52
 
43
53
  const choices = [
44
- { title: 'Use schema from package', value: 'package' },
54
+ { title: 'Use createSchemaFactory from package', value: 'package' },
45
55
  ...coreSchemas.map(s => ({ title: `Use ${s} from core`, value: s }))
46
56
  ];
47
57
 
@@ -53,18 +63,34 @@ export default async function generateSchema() {
53
63
  });
54
64
 
55
65
  const pascalName = toPascalCase(name);
66
+ const moduleName = toPascalCase(module);
56
67
  const contextPath = getContextPath(context);
57
- const schemaPath = path.join(contextPath, 'Delivery', 'Schemas');
68
+ const schemaPath = path.join(contextPath, 'Delivery', moduleName, 'Schema');
58
69
  const filePath = path.join(schemaPath, `${pascalName}Schema.ts`);
59
70
 
60
71
  const content = schemaType === 'package'
61
- ? schemaWithPackageTemplate.replace(/{{name}}/g, pascalName)
72
+ ? schemaWithPackageTemplate
73
+ .replace(/{{name}}/g, pascalName)
74
+ .replace(/{{context}}/g, context)
75
+ .replace(/{{entity}}/g, moduleName)
62
76
  : schemaWithCoreTemplate
63
77
  .replace(/{{name}}/g, pascalName)
78
+ .replace(/{{context}}/g, context)
79
+ .replace(/{{entity}}/g, moduleName)
64
80
  .replace(/{{coreSchema}}/g, schemaType);
65
81
 
66
82
  await writeIfNotExists(filePath, content);
67
83
  await updateIndexTs(schemaPath);
68
84
 
85
+ // Update module index
86
+ const moduleIndexPath = path.join(contextPath, 'Delivery', moduleName, 'index.ts');
87
+ if (await fs.access(moduleIndexPath).then(() => true).catch(() => false)) {
88
+ let indexContent = await fs.readFile(moduleIndexPath, 'utf-8');
89
+ if (!indexContent.includes(`export * from './Schema'`)) {
90
+ indexContent += `\nexport * from './Schema';`;
91
+ await fs.writeFile(moduleIndexPath, indexContent, 'utf-8');
92
+ }
93
+ }
94
+
69
95
  console.log(`✅ Schema created at ${filePath}`);
70
96
  }
@@ -6,7 +6,7 @@ import { writeIfNotExists, updateIndexTs } from '../../utils/fileUtils.js';
6
6
  import { ensureProvider, addToProvider } from '../../utils/providerUtils.js';
7
7
 
8
8
  const serviceTemplate = `import { ClassMirror } from '@azure-net/kit';
9
- import { {{repository}} } from '../../Infrastructure/Repositories/index.js';
9
+ import { {{repository}} } from '../../Infrastructure/Http/Repositories';
10
10
 
11
11
  export class {{name}}Service extends ClassMirror<{{repository}}> {
12
12
  \tconstructor(private {{repositoryVar}}: {{repository}}) {
@@ -42,12 +42,12 @@ export default async function generateService() {
42
42
  // Get available repositories
43
43
  const contextPath = getContextPath(context);
44
44
  const repositories = await getAvailableFiles(
45
- path.join(contextPath, 'Infrastructure', 'Repositories')
45
+ path.join(contextPath, 'Infrastructure', 'Http', 'Repositories')
46
46
  );
47
47
 
48
48
  const choices = [
49
49
  { title: 'Without repository', value: null },
50
- ...repositories.map(r => ({ title: `${r}Repository`, value: `${r}Repository` }))
50
+ ...repositories.map(r => ({ title: `${r}`, value: r }))
51
51
  ];
52
52
 
53
53
  const { repository } = await prompts({
@@ -74,19 +74,20 @@ export default async function generateService() {
74
74
 
75
75
  // Ensure ApplicationProvider exists and add service
76
76
  const appProvider = await ensureProvider(context, 'Application', { infrastructure: true });
77
- await addToProvider(
78
- appProvider.path,
79
- `${pascalName}Service`,
80
- '../Services/index.js'
81
- );
82
77
 
83
- // Add repository dependency if selected
84
78
  if (repository) {
85
- let providerContent = await fs.readFile(appProvider.path, 'utf-8');
86
- const serviceFactory = `${pascalName}Service: () => new ${pascalName}Service()`;
87
- const serviceWithRepo = `${pascalName}Service: () => new ${pascalName}Service(InfrastructureProvider.${repository})`;
88
- providerContent = providerContent.replace(serviceFactory, serviceWithRepo);
89
- await fs.writeFile(appProvider.path, providerContent, 'utf-8');
79
+ await addToProvider(
80
+ appProvider.path,
81
+ `${pascalName}Service`,
82
+ '../Services',
83
+ `InfrastructureProvider.${repository}`
84
+ );
85
+ } else {
86
+ await addToProvider(
87
+ appProvider.path,
88
+ `${pascalName}Service`,
89
+ '../Services'
90
+ );
90
91
  }
91
92
 
92
93
  console.log(`✅ Service created at ${filePath}`);
@@ -3,4 +3,5 @@ export { default as initAliases } from './initAliases.js';
3
3
  export { default as initMiddleware } from './initMiddleware.js';
4
4
  export { default as initEdges } from './initEdges.js';
5
5
  export { default as initTranslations } from './initTranslations.js';
6
- export { default as initSchema } from './initSchema.js';
6
+ export { default as initSchema } from './initSchema.js';
7
+ export { default as initLint } from './initLint.js';
@@ -0,0 +1,138 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import { execSync } from 'child_process';
4
+ import prompts from 'prompts';
5
+
6
+ const dependencies = [
7
+ '@commitlint/cli',
8
+ 'semantic-release',
9
+ '@semantic-release/git',
10
+ 'git-cz',
11
+ 'husky',
12
+ 'commitizen',
13
+ 'env-cmd'
14
+ ];
15
+
16
+ const scriptsToAdd = {
17
+ precommit: 'pnpm lint && pnpm check',
18
+ 'semantic-release': 'env-cmd semantic-release',
19
+ commit: 'pnpm format && git add . && git-cz && git push',
20
+ release: 'pnpm commit && pnpm semantic-release'
21
+ };
22
+
23
+ const commitlintConfig = `export default {
24
+ rules: {
25
+ 'body-leading-blank': [2, 'always'],
26
+ 'footer-leading-blank': [2, 'always'],
27
+ 'header-max-length': [2, 'always', 72],
28
+ 'subject-empty': [2, 'never'],
29
+ 'subject-full-stop': [2, 'never', '.'],
30
+ 'type-case': [2, 'always', 'lower-case'],
31
+ 'type-empty': [2, 'never'],
32
+ 'type-enum': [2, 'always', ['feat', 'fix', 'refactor', 'perf', 'chore', 'docs', 'style', 'test', 'ci']]
33
+ }
34
+ };
35
+ `;
36
+
37
+ const releaseConfig = `export default {
38
+ branches: ['main', 'dev'],
39
+ dryRun: false,
40
+ ci: false,
41
+ plugins: [
42
+ [
43
+ '@semantic-release/commit-analyzer',
44
+ {
45
+ releaseRules: [
46
+ { type: 'release', release: 'major' },
47
+ { type: 'feature', release: 'minor' },
48
+ { type: 'perf', release: false },
49
+ { type: 'refactor', release: false },
50
+ { type: 'fix', release: 'patch' },
51
+ { type: 'chore', release: false },
52
+ { type: 'ci', release: false },
53
+ { type: 'docs', scope: 'README', release: false },
54
+ { type: 'test', release: false },
55
+ { type: 'style', release: false }
56
+ ]
57
+ }
58
+ ],
59
+ '@semantic-release/release-notes-generator'
60
+ ]
61
+ };
62
+ `;
63
+
64
+ const prettierConfig = `{
65
+ "useTabs": true,
66
+ "singleQuote": true,
67
+ "trailingComma": "none",
68
+ "tabWidth": 2,
69
+ "semi": true,
70
+ "printWidth": 150,
71
+ "plugins": ["prettier-plugin-svelte"],
72
+ "overrides": [
73
+ {
74
+ "files": "*.svelte",
75
+ "options": {
76
+ "parser": "svelte"
77
+ }
78
+ }
79
+ ]
80
+ }
81
+ `;
82
+
83
+ export default async function initLint() {
84
+ const cwd = process.cwd();
85
+ const pkgPath = path.join(cwd, 'package.json');
86
+
87
+ if (!fs.existsSync(pkgPath)) {
88
+ console.error('❌ package.json not found in this directory');
89
+ process.exit(1);
90
+ }
91
+
92
+ const { manager } = await prompts({
93
+ type: 'select',
94
+ name: 'manager',
95
+ message: 'Choose your package manager:',
96
+ choices: [
97
+ { title: 'pnpm', value: 'pnpm' },
98
+ { title: 'npm', value: 'npm' },
99
+ { title: 'yarn', value: 'yarn' }
100
+ ],
101
+ initial: 0
102
+ });
103
+
104
+ const installCommand =
105
+ manager === 'pnpm'
106
+ ? `pnpm add -D ${dependencies.join(' ')}`
107
+ : manager === 'npm'
108
+ ? `npm install -D ${dependencies.join(' ')}`
109
+ : `yarn add -D ${dependencies.join(' ')}`;
110
+
111
+ console.log(`📦 Installing packages with ${manager}...`);
112
+ execSync(installCommand, { stdio: 'inherit' });
113
+
114
+ console.log('📁 Updating package.json...');
115
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
116
+
117
+ pkg.scripts = {
118
+ ...pkg.scripts,
119
+ ...scriptsToAdd
120
+ };
121
+
122
+ pkg.config = pkg.config || {};
123
+ pkg.config.commitizen = {
124
+ path: 'git-cz'
125
+ };
126
+
127
+ fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 4));
128
+
129
+ // Write config files
130
+ fs.writeFileSync(path.join(cwd, 'commitlint.config.ts'), commitlintConfig);
131
+ fs.writeFileSync(path.join(cwd, 'release.config.ts'), releaseConfig);
132
+ fs.writeFileSync(path.join(cwd, '.prettierrc'), prettierConfig);
133
+
134
+ console.log('🔧 Initializing Husky...');
135
+ execSync(`${manager === 'npm' ? 'npx' : manager} husky`, { stdio: 'inherit' });
136
+ execSync('npm run format', { stdio: 'inherit' });
137
+ console.log('✅ Linting and release setup completed! Change your prepare script in package.json: node -e \"if (process.env.NODE_ENV !== \'production\'){process.exit(1)} \" || (husky && svelte-kit sync)');
138
+ }
@@ -5,37 +5,22 @@ const middlewarePath = path.join(process.cwd(), 'src/app/core/Middleware/Middlew
5
5
  const hooksServerPath = path.join(process.cwd(), 'src/hooks.server.ts');
6
6
  const layoutPath = path.join(process.cwd(), 'src/routes/+layout.svelte');
7
7
 
8
- const middlewareTemplate = `import { createMiddlewareManager, type IMiddleware } from '@azure-net/kit';
9
-
10
- const AuthMiddleware: IMiddleware = async ({ next, page, event, isServer, cookies }) => {
11
- \tconst user = isServer ? event?.locals?.user : page?.data?.user;
12
- \tif (isServer && !user && cookies.get('token') && event) {
13
- \t\t// Add auth logic here
14
- \t}
15
- \tnext();
16
- };
17
-
18
- const GuardMiddleware: IMiddleware = async ({ next, page, event, isServer, to }) => {
19
- \tconst user = isServer ? event?.locals?.user : page?.data?.user;
20
- \tif (!user && !to.pathname.startsWith('/login')) {
21
- \t\tnext('/login');
22
- \t}
23
- \tif (user && to.pathname.startsWith('/login')) {
24
- \t\tnext('/');
25
- \t}
26
- \tnext();
27
- };
28
-
29
- export const { clientMiddleware, serverMiddleware } = createMiddlewareManager([AuthMiddleware, GuardMiddleware]);`;
8
+ const middlewareTemplate = `import { createMiddlewareManager } from '@azure-net/kit';
9
+
10
+ export const { clientMiddleware, serverMiddleware } = createMiddlewareManager([]);`;
30
11
 
31
12
  export default async function initMiddleware() {
32
13
  await writeIfNotExists(middlewarePath, middlewareTemplate);
14
+ await writeIfNotExists(
15
+ path.join(process.cwd(), 'src/app/core/Middleware/index.ts'),
16
+ `export * from './MiddlewareManager';`
17
+ );
33
18
 
34
19
  // Add to hooks.server.ts
35
20
  await injectIntoFile(
36
21
  hooksServerPath,
37
- `import { serverMiddleware } from '$core/Middleware/index.js';`,
38
22
  'import',
23
+ `import { serverMiddleware } from '$core';`,
39
24
  'before'
40
25
  );
41
26
 
@@ -50,7 +35,7 @@ export default async function initMiddleware() {
50
35
  await injectIntoFile(
51
36
  layoutPath,
52
37
  '<script',
53
- `\timport { clientMiddleware } from '$core/Middleware/index.js';\n\tclientMiddleware();`,
38
+ `\timport { clientMiddleware } from '$core';\n\tclientMiddleware();`,
54
39
  'after'
55
40
  );
56
41
 
@@ -3,7 +3,7 @@ import path from 'path';
3
3
 
4
4
  const schemaPath = path.join(process.cwd(), 'src/app/core/Schemas/Schema.ts');
5
5
 
6
- const schemaTemplate = `import { createSchemaFactory } from '@azure-net/kit/schema';
6
+ const schemaTemplate = `import { createSchemaFactory } from '@azure-net/kit';
7
7
  import { createRules, validationMessagesI18n } from '@azure-net/kit/schema';
8
8
 
9
9
  export const Schema = createSchemaFactory(createRules(validationMessagesI18n));`;
@@ -12,7 +12,7 @@ export default async function initSchema() {
12
12
  await writeIfNotExists(schemaPath, schemaTemplate);
13
13
  await writeIfNotExists(
14
14
  path.join(process.cwd(), 'src/app/core/Schemas/index.ts'),
15
- `export * from './Schema.js';`
15
+ `export * from './Schema';`
16
16
  );
17
17
 
18
18
  console.log('✅ Schema factory initialized');
@@ -2,7 +2,6 @@ import fs from 'fs/promises';
2
2
  import path from 'path';
3
3
  import { loadUserConfig } from '../../utils/loadConfig.js';
4
4
 
5
- const BASE_STRUCTURE = ['Domain', 'Infrastructure', 'Application', 'Delivery'];
6
5
  const APP_ROOT = path.join(process.cwd(), 'src', 'app');
7
6
  const CONTEXTS_PATH = path.join(APP_ROOT, 'contexts');
8
7
  const CORE_PATH = path.join(APP_ROOT, 'core');
@@ -16,31 +15,34 @@ async function createDirIfNotExists(dirPath) {
16
15
  }
17
16
  }
18
17
 
18
+ async function createIndexFile(dirPath, exportPatterns = []) {
19
+ const indexPath = path.join(dirPath, 'index.ts');
20
+ if (exportPatterns.length > 0) {
21
+ const content = exportPatterns.map(pattern => `export * from '${pattern}';`).join('\n') + '\n';
22
+ await fs.writeFile(indexPath, content, 'utf-8');
23
+ }
24
+ }
25
+
19
26
  async function createBaseStructure(root) {
20
- for (const section of BASE_STRUCTURE) {
21
- const sectionPath = path.join(root, section);
22
- await createDirIfNotExists(sectionPath);
27
+ // Domain
28
+ const domainPath = path.join(root, 'Domain');
29
+ await createDirIfNotExists(path.join(domainPath, 'Entities'));
30
+ await createDirIfNotExists(path.join(domainPath, 'Ports'));
23
31
 
24
- if (section === 'Infrastructure') {
25
- await createDirIfNotExists(path.join(sectionPath, 'Repositories'));
26
- await createDirIfNotExists(path.join(sectionPath, 'Datasources'));
27
- await createDirIfNotExists(path.join(sectionPath, 'Providers'));
28
- }
29
- if (section === 'Application') {
30
- await createDirIfNotExists(path.join(sectionPath, 'Services'));
31
- await createDirIfNotExists(path.join(sectionPath, 'Providers'));
32
- }
33
- if (section === 'Domain') {
34
- await createDirIfNotExists(path.join(sectionPath, 'Entities'));
35
- await createDirIfNotExists(path.join(sectionPath, 'Ports'));
36
- }
37
- if (section === 'Delivery') {
38
- await createDirIfNotExists(path.join(sectionPath, 'Presenters'));
39
- await createDirIfNotExists(path.join(sectionPath, 'Schemas'));
40
- await createDirIfNotExists(path.join(sectionPath, 'Actions'));
41
- await createDirIfNotExists(path.join(sectionPath, 'Stores'));
42
- }
43
- }
32
+ // Infrastructure
33
+ const infraPath = path.join(root, 'Infrastructure');
34
+ await createDirIfNotExists(path.join(infraPath, 'Http', 'Repositories'));
35
+ await createDirIfNotExists(path.join(infraPath, 'Http', 'Datasource'));
36
+ await createDirIfNotExists(path.join(infraPath, 'Providers'));
37
+
38
+ // Application
39
+ const appPath = path.join(root, 'Application');
40
+ await createDirIfNotExists(path.join(appPath, 'Services'));
41
+ await createDirIfNotExists(path.join(appPath, 'Providers'));
42
+
43
+ // Delivery - organized by modules, not by type
44
+ const deliveryPath = path.join(root, 'Delivery');
45
+ await createDirIfNotExists(deliveryPath);
44
46
  }
45
47
 
46
48
  export default async function initStructure() {
@@ -57,12 +59,21 @@ export default async function initStructure() {
57
59
 
58
60
  // Create core structure
59
61
  await createDirIfNotExists(CORE_PATH);
60
- await createDirIfNotExists(path.join(CORE_PATH, 'Datasources'));
61
- await createDirIfNotExists(path.join(CORE_PATH, 'Responses'));
62
- await createDirIfNotExists(path.join(CORE_PATH, 'Schemas'));
62
+ await createDirIfNotExists(path.join(CORE_PATH, 'Datasource'));
63
+ await createDirIfNotExists(path.join(CORE_PATH, 'Response'));
64
+ await createDirIfNotExists(path.join(CORE_PATH, 'Schema'));
63
65
  await createDirIfNotExists(path.join(CORE_PATH, 'Middleware'));
64
- await createDirIfNotExists(path.join(CORE_PATH, 'Presenters'));
65
- await createDirIfNotExists(path.join(CORE_PATH, 'Translations'));
66
+ await createDirIfNotExists(path.join(CORE_PATH, 'Presenter'));
67
+ await createDirIfNotExists(path.join(CORE_PATH, 'Translation'));
68
+
69
+ // Create core index.ts that exports all subdirectories
70
+ await createIndexFile(CORE_PATH, [
71
+ './Schema',
72
+ './Datasource',
73
+ './Response',
74
+ './Middleware',
75
+ './Translation'
76
+ ]);
66
77
 
67
78
  console.log('✅ Structure initialization complete!');
68
79
  }
@@ -1,11 +1,11 @@
1
1
  import { writeIfNotExists, updateIndexTs, injectIntoFile } from '../../utils/fileUtils.js';
2
2
  import path from 'path';
3
3
 
4
- const translationsPath = path.join(process.cwd(), 'src/app/core/Translations');
4
+ const translationsPath = path.join(process.cwd(), 'src/app/core/Translation');
5
5
  const layoutServerPath = path.join(process.cwd(), 'src/routes/+layout.server.ts');
6
6
  const layoutTsPath = path.join(process.cwd(), 'src/routes/+layout.ts');
7
7
 
8
- const translationProviderTemplate = `import { messages } from './Locales/index.js';
8
+ const translationProviderTemplate = `import { messages } from './Locales';
9
9
  import { createTranslations } from '@azure-net/kit/i18n';
10
10
 
11
11
  export const Translation = createTranslations({
@@ -28,8 +28,8 @@ const ruLocaleTemplate = `export default {
28
28
  };`;
29
29
 
30
30
  const localesIndexTemplate = `export const messages = {
31
- \ten: () => import('./en.js').then((res) => res.default),
32
- \tru: () => import('./ru.js').then((res) => res.default)
31
+ \ten: () => import('./en').then((res) => res.default),
32
+ \tru: () => import('./ru').then((res) => res.default)
33
33
  };`;
34
34
 
35
35
  export default async function initTranslations() {
@@ -54,13 +54,11 @@ export default async function initTranslations() {
54
54
  localesIndexTemplate
55
55
  );
56
56
 
57
- await updateIndexTs(translationsPath);
58
-
59
57
  // Add to hooks.server.ts
60
58
  await injectIntoFile(
61
59
  path.join(process.cwd(), 'src/hooks.server.ts'),
62
60
  'import',
63
- `import { Translation } from '$core/Translations/index.js';`,
61
+ `import { Translation } from '$core';`,
64
62
  'before'
65
63
  );
66
64
 
@@ -71,18 +69,25 @@ export default async function initTranslations() {
71
69
  'after'
72
70
  );
73
71
 
72
+ await injectIntoFile(
73
+ path.join(process.cwd(), 'src/hooks.server.ts'),
74
+ 'transformPageChunk: ({ html })',
75
+ ' => {\n\t\t\t\tconst serialized = serialize(html);\n\t\t\t\treturn applyHtmlLocaleAttr(serialized);\n\t\t\t}',
76
+ 'after'
77
+ );
78
+
74
79
  // Add to layout files
75
80
  await injectIntoFile(
76
81
  layoutServerPath,
77
82
  'export const load',
78
- `\treturn { lang: locals.lang, user: locals.user };`,
83
+ `\treturn { lang: locals.lang };`,
79
84
  'after'
80
85
  );
81
86
 
82
87
  await injectIntoFile(
83
88
  layoutTsPath,
84
89
  'import',
85
- `import { Translation } from '$core/Translations/index.js';`,
90
+ `import { Translation } from '$core';\nimport { browser } from '$app/environment';`,
86
91
  'before'
87
92
  );
88
93
 
@@ -20,7 +20,7 @@ export async function updateIndexTs(dir, filePattern = '.ts', ignore = ['index.t
20
20
  f.endsWith(filePattern) && !ignore.includes(f)
21
21
  );
22
22
  const content = files
23
- .map(f => `export * from './${f.replace('.ts', '')}.js';`)
23
+ .map(f => `export * from './${f.replace('.ts', '')}';`)
24
24
  .join('\n') + '\n';
25
25
  await fs.writeFile(path.join(dir, 'index.ts'), content, 'utf-8');
26
26
  } catch (error) {
@@ -28,6 +28,25 @@ export async function updateIndexTs(dir, filePattern = '.ts', ignore = ['index.t
28
28
  }
29
29
  }
30
30
 
31
+ export async function ensureIndexExports(layerPath) {
32
+ try {
33
+ const subdirs = await fs.readdir(layerPath, { withFileTypes: true });
34
+ const exportLines = subdirs
35
+ .filter(d => d.isDirectory())
36
+ .map(d => `export * from './${d.name}';`);
37
+
38
+ if (exportLines.length > 0) {
39
+ await fs.writeFile(
40
+ path.join(layerPath, 'index.ts'),
41
+ exportLines.join('\n') + '\n',
42
+ 'utf-8'
43
+ );
44
+ }
45
+ } catch (error) {
46
+ // Directory doesn't exist
47
+ }
48
+ }
49
+
31
50
  export async function injectIntoFile(filepath, searchPattern, newContent, position = 'after') {
32
51
  try {
33
52
  let content = await fs.readFile(filepath, 'utf-8');