@azure-net/cli 2.3.63 → 4.0.0-1
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/.prettierrc +7 -0
- package/bin/azure-net.js +278 -157
- package/bin/azure-net.ts +284 -0
- package/eslint.config.js +34 -0
- package/package.json +12 -5
- package/src/checks/checkDomain.js +201 -0
- package/src/checks/checkDomain.ts +213 -0
- package/src/checks/checkFoldersStructure.js +70 -0
- package/src/checks/checkFoldersStructure.ts +85 -0
- package/src/checks/checkInternal.js +35 -0
- package/src/checks/checkInternal.ts +40 -0
- package/src/checks/checkLayerBoundaries.js +178 -0
- package/src/checks/checkLayerBoundaries.ts +189 -0
- package/src/checks/checkPresenterNames.js +202 -0
- package/src/checks/checkPresenterNames.ts +208 -0
- package/src/checks/checkProject.js +42 -0
- package/src/checks/checkProject.ts +45 -0
- package/src/checks/checkProviderNames.js +158 -0
- package/src/checks/checkProviderNames.ts +165 -0
- package/src/checks/index.js +7 -0
- package/src/checks/index.ts +7 -0
- package/src/generate/layers/generateRepository.js +124 -0
- package/src/generate/layers/generateRepository.ts +123 -0
- package/src/generate/layers/generateRepositoryMethod.js +102 -0
- package/src/generate/layers/generateRepositoryMethod.ts +102 -0
- package/src/generate/layers/generateUseCases.js +50 -0
- package/src/generate/layers/generateUseCases.ts +50 -0
- package/src/generate/layers/repositoryShared.js +569 -0
- package/src/generate/layers/repositoryShared.ts +657 -0
- package/src/generate/module/generateDomain.js +146 -0
- package/src/generate/module/generateDomain.ts +147 -0
- package/src/generate/module/generateModule.js +84 -0
- package/src/generate/module/generateModule.ts +84 -0
- package/src/generate/module/generateModulePreset.js +307 -0
- package/src/generate/module/generateModulePreset.ts +337 -0
- package/src/generate/module/generatePresenter.js +419 -0
- package/src/generate/module/generatePresenter.ts +442 -0
- package/src/generate/module/generateRepository.js +144 -0
- package/src/generate/module/generateRepository.ts +158 -0
- package/src/generate/module/generateSchemaFromType.js +358 -0
- package/src/generate/module/generateSchemaFromType.ts +369 -0
- package/src/generate/module/generateTypesJson.js +252 -0
- package/src/generate/module/generateTypesJson.ts +259 -0
- package/src/generate/module/generateUseCases.js +67 -0
- package/src/generate/module/generateUseCases.ts +67 -0
- package/src/generate/module/repositoryModuleShared.js +598 -0
- package/src/generate/module/repositoryModuleShared.ts +661 -0
- package/src/generate/ui/generateComponent.js +98 -0
- package/src/generate/ui/generateComponent.ts +100 -0
- package/src/generate/ui/generateDesignComponent.js +71 -0
- package/src/generate/ui/generateDesignComponent.ts +71 -0
- package/src/generate/ui/generateWidget.js +71 -0
- package/src/generate/ui/generateWidget.ts +71 -0
- package/src/init/initAliases.js +159 -0
- package/src/init/initAliases.ts +167 -0
- package/src/init/initEdges.js +74 -0
- package/src/init/initEdges.ts +74 -0
- package/src/init/initStructure.js +122 -0
- package/src/init/initStructure.ts +124 -0
- package/src/install/installFresh.js +101 -0
- package/src/install/installFresh.ts +101 -0
- package/src/plugins/addLint.js +257 -0
- package/src/plugins/addLint.ts +274 -0
- package/src/plugins/index.js +1 -0
- package/src/plugins/index.ts +1 -0
- package/src/scaffolds/createCoreMiddleware.js +27 -0
- package/src/scaffolds/createCoreMiddleware.ts +27 -0
- package/src/scaffolds/createCoreSchema.js +141 -0
- package/src/scaffolds/createCoreSchema.ts +142 -0
- package/src/scaffolds/createDatasource.js +173 -0
- package/src/scaffolds/createDatasource.ts +175 -0
- package/src/scaffolds/createDatasourceProvider.js +164 -0
- package/src/scaffolds/createDatasourceProvider.ts +175 -0
- package/src/scaffolds/createMiddleware.js +105 -0
- package/src/scaffolds/createMiddleware.ts +105 -0
- package/src/scaffolds/createPresenterFactory.js +112 -0
- package/src/scaffolds/createPresenterFactory.ts +114 -0
- package/src/scaffolds/createResponse.js +64 -0
- package/src/scaffolds/createResponse.ts +64 -0
- package/src/scaffolds/createSchemaRule.js +40 -0
- package/src/scaffolds/createSchemaRule.ts +42 -0
- package/src/scaffolds/createTranslationManager.js +78 -0
- package/src/scaffolds/createTranslationManager.ts +78 -0
- package/src/scaffolds/index.js +9 -0
- package/src/scaffolds/index.ts +9 -0
- package/src/utils/contextUtils.js +56 -49
- package/src/utils/contextUtils.ts +89 -0
- package/src/utils/fileUtils.js +72 -84
- package/src/utils/fileUtils.ts +100 -0
- package/src/utils/loadConfig.js +57 -13
- package/src/utils/loadConfig.ts +69 -0
- package/tsconfig.json +19 -0
- package/src/commands/generate/generateComponent.js +0 -53
- package/src/commands/generate/generateCrudBase.js +0 -207
- package/src/commands/generate/generateCrudPresenter.js +0 -232
- package/src/commands/generate/generateDatasource.js +0 -84
- package/src/commands/generate/generateDesignComponent.js +0 -53
- package/src/commands/generate/generateModule.js +0 -31
- package/src/commands/generate/generateModuleBase.js +0 -152
- package/src/commands/generate/generateModulePresenter.js +0 -110
- package/src/commands/generate/generatePresenter.js +0 -86
- package/src/commands/generate/generateRepository.js +0 -76
- package/src/commands/generate/generateResponse.js +0 -41
- package/src/commands/generate/generateSchema.js +0 -96
- package/src/commands/generate/generateService.js +0 -71
- package/src/commands/generate/generateWidget.js +0 -53
- package/src/commands/generate/index.js +0 -14
- package/src/commands/init/index.js +0 -9
- package/src/commands/init/initAliases.js +0 -52
- package/src/commands/init/initEdges.js +0 -42
- package/src/commands/init/initLint.js +0 -138
- package/src/commands/init/initMiddleware.js +0 -21
- package/src/commands/init/initPresenter.js +0 -25
- package/src/commands/init/initSchema.js +0 -22
- package/src/commands/init/initStructure.js +0 -140
- package/src/commands/init/initTranslations.js +0 -59
- package/src/commands/init/migrateStructure.js +0 -144
|
@@ -1,207 +0,0 @@
|
|
|
1
|
-
import prompts from 'prompts';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
import {
|
|
4
|
-
selectContext,
|
|
5
|
-
getContextPath,
|
|
6
|
-
toPascalCase,
|
|
7
|
-
toCamelCase,
|
|
8
|
-
getAvailableFiles,
|
|
9
|
-
toKebabCase
|
|
10
|
-
} from '../../utils/contextUtils.js';
|
|
11
|
-
import { writeIfNotExists, updateIndexTs, updateCoreIndex } from '../../utils/fileUtils.js';
|
|
12
|
-
|
|
13
|
-
// Templates for CRUD base generation
|
|
14
|
-
const entityTemplate = `export interface I{{name}} {
|
|
15
|
-
\tid: number;
|
|
16
|
-
\t// Add entity fields here
|
|
17
|
-
\tcreated_at: string;
|
|
18
|
-
\tupdated_at: string;
|
|
19
|
-
}`;
|
|
20
|
-
|
|
21
|
-
const portsIndexTemplate = `import type { I{{name}} } from '\${{context}}/domain/{{entityLower}}/model';
|
|
22
|
-
|
|
23
|
-
export type I{{name}}Collection = I{{name}}[];
|
|
24
|
-
|
|
25
|
-
export interface I{{name}}CollectionQuery {
|
|
26
|
-
\tpage?: number;
|
|
27
|
-
\tperPage?: number;
|
|
28
|
-
\t[key: string]: unknown;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export interface I{{name}}CreateRequest {
|
|
32
|
-
\t// Add request fields here
|
|
33
|
-
\t[key: string]: unknown;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export interface I{{name}}UpdateRequest {
|
|
37
|
-
\t// Add request fields here
|
|
38
|
-
\t[key: string]: unknown;
|
|
39
|
-
}`;
|
|
40
|
-
|
|
41
|
-
const repositoryTemplate = `import { {{datasource}} } from '{{datasourceImport}}';
|
|
42
|
-
import type {
|
|
43
|
-
\tI{{name}},
|
|
44
|
-
\tI{{name}}Collection,
|
|
45
|
-
\tI{{name}}CollectionQuery,
|
|
46
|
-
\tI{{name}}CreateRequest,
|
|
47
|
-
\tI{{name}}UpdateRequest
|
|
48
|
-
} from '\${{context}}/domain/{{entityLower}}';
|
|
49
|
-
|
|
50
|
-
export class {{name}}Repository {
|
|
51
|
-
\tprivate endpoint = '{{endpoint}}';
|
|
52
|
-
\t
|
|
53
|
-
\tconstructor(private {{datasourceVar}}: {{datasource}}) {}
|
|
54
|
-
\t
|
|
55
|
-
\tpublic async collection(query?: I{{name}}CollectionQuery) {
|
|
56
|
-
\t\treturn this.{{datasourceVar}}.createRequest<I{{name}}Collection>(({ http, query: q }) =>
|
|
57
|
-
\t\t\thttp.get(\`\${this.endpoint}\${q.build(query ?? {})}\`)
|
|
58
|
-
\t\t).then(res => res.getData());
|
|
59
|
-
\t}
|
|
60
|
-
\t
|
|
61
|
-
\tpublic async resource(id: number) {
|
|
62
|
-
\t\treturn this.{{datasourceVar}}.createRequest<I{{name}}>(({ http }) =>
|
|
63
|
-
\t\t\thttp.get(\`\${this.endpoint}/\${id}\`)
|
|
64
|
-
\t\t).then(res => res.getData());
|
|
65
|
-
\t}
|
|
66
|
-
\t
|
|
67
|
-
\tpublic async create(data: I{{name}}CreateRequest) {
|
|
68
|
-
\t\treturn this.{{datasourceVar}}.createRequest<I{{name}}>(({ http }) =>
|
|
69
|
-
\t\t\thttp.post(this.endpoint, { json: data })
|
|
70
|
-
\t\t).then(res => res.getData());
|
|
71
|
-
\t}
|
|
72
|
-
\t
|
|
73
|
-
\tpublic async update(id: number, data: I{{name}}UpdateRequest) {
|
|
74
|
-
\t\treturn this.{{datasourceVar}}.createRequest<I{{name}}>(({ http }) =>
|
|
75
|
-
\t\t\thttp.put(\`\${this.endpoint}/\${id}\`, { json: data })
|
|
76
|
-
\t\t).then(res => res.getData());
|
|
77
|
-
\t}
|
|
78
|
-
\t
|
|
79
|
-
\tpublic async destroy(id: number) {
|
|
80
|
-
\t\treturn this.{{datasourceVar}}.createRequest<void>(({ http }) =>
|
|
81
|
-
\t\t\thttp.delete(\`\${this.endpoint}/\${id}\`)
|
|
82
|
-
\t\t).then(() => undefined);
|
|
83
|
-
\t}
|
|
84
|
-
}`;
|
|
85
|
-
|
|
86
|
-
const serviceTemplate = `import { ClassMirror } from '@azure-net/kit';
|
|
87
|
-
import { {{name}}Repository } from '\${{context}}/infrastructure/http/repositories';
|
|
88
|
-
|
|
89
|
-
export class {{name}}Service extends ClassMirror<{{name}}Repository> {
|
|
90
|
-
\tconstructor(private {{camelName}}Repository: {{name}}Repository) {
|
|
91
|
-
\t\tsuper({{camelName}}Repository);
|
|
92
|
-
\t}
|
|
93
|
-
\t
|
|
94
|
-
\tdeclare collection: {{name}}Repository['collection'];
|
|
95
|
-
\tdeclare resource: {{name}}Repository['resource'];
|
|
96
|
-
\tdeclare create: {{name}}Repository['create'];
|
|
97
|
-
\tdeclare update: {{name}}Repository['update'];
|
|
98
|
-
\tdeclare destroy: {{name}}Repository['destroy'];
|
|
99
|
-
}`;
|
|
100
|
-
|
|
101
|
-
export default async function generateCrudBase() {
|
|
102
|
-
const context = await selectContext('Select context for CRUD base:');
|
|
103
|
-
|
|
104
|
-
const { name } = await prompts({
|
|
105
|
-
type: 'text',
|
|
106
|
-
name: 'name',
|
|
107
|
-
message: 'Entity name (PascalCase):'
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
const { endpoint } = await prompts({
|
|
111
|
-
type: 'text',
|
|
112
|
-
name: 'endpoint',
|
|
113
|
-
message: 'API endpoint (e.g. /api/users):'
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
// Get available datasources
|
|
117
|
-
const contextPath = getContextPath(context);
|
|
118
|
-
const coreDatasources = await getAvailableFiles(
|
|
119
|
-
path.join(process.cwd(), 'src/core/datasources')
|
|
120
|
-
);
|
|
121
|
-
const contextDatasources = await getAvailableFiles(
|
|
122
|
-
path.join(contextPath, 'infrastructure/http/datasources')
|
|
123
|
-
);
|
|
124
|
-
|
|
125
|
-
const allDatasources = [
|
|
126
|
-
...coreDatasources.map(d => ({ title: `${d} (core)`, value: { name: d, from: 'core' } })),
|
|
127
|
-
...contextDatasources.map(d => ({ title: `${d} (${context})`, value: { name: d, from: context } }))
|
|
128
|
-
];
|
|
129
|
-
|
|
130
|
-
const { datasource } = await prompts({
|
|
131
|
-
type: 'select',
|
|
132
|
-
name: 'datasource',
|
|
133
|
-
message: 'Select datasource:',
|
|
134
|
-
choices: allDatasources
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
const pascalName = toPascalCase(name);
|
|
138
|
-
const camelName = toCamelCase(name);
|
|
139
|
-
const entityLower = toKebabCase(pascalName);
|
|
140
|
-
|
|
141
|
-
console.log('\n🚀 Generating CRUD base (repository & service)...\n');
|
|
142
|
-
|
|
143
|
-
// 1. Create Domain structure
|
|
144
|
-
const domainPath = path.join(contextPath, 'domain', entityLower);
|
|
145
|
-
const modelPath = path.join(domainPath, 'model');
|
|
146
|
-
const portsPath = path.join(domainPath, 'ports');
|
|
147
|
-
|
|
148
|
-
// Create Model
|
|
149
|
-
await writeIfNotExists(
|
|
150
|
-
path.join(modelPath, 'index.ts'),
|
|
151
|
-
entityTemplate.replace(/{{name}}/g, pascalName)
|
|
152
|
-
);
|
|
153
|
-
|
|
154
|
-
// Create Ports
|
|
155
|
-
await writeIfNotExists(
|
|
156
|
-
path.join(portsPath, 'index.ts'),
|
|
157
|
-
portsIndexTemplate
|
|
158
|
-
.replace(/{{name}}/g, pascalName)
|
|
159
|
-
.replace(/{{context}}/g, context)
|
|
160
|
-
.replace(/{{entityLower}}/g, entityLower)
|
|
161
|
-
);
|
|
162
|
-
|
|
163
|
-
// Create Domain module index
|
|
164
|
-
await writeIfNotExists(
|
|
165
|
-
path.join(domainPath, 'index.ts'),
|
|
166
|
-
`export * from './model';\nexport * from './ports';`
|
|
167
|
-
);
|
|
168
|
-
|
|
169
|
-
// 2. Create Repository
|
|
170
|
-
const repoPath = path.join(contextPath, 'infrastructure/http/repositories');
|
|
171
|
-
const datasourceImport = datasource.from === 'core'
|
|
172
|
-
? '$core/datasources'
|
|
173
|
-
: `\$${context}/infrastructure/http/datasources`;
|
|
174
|
-
|
|
175
|
-
await writeIfNotExists(
|
|
176
|
-
path.join(repoPath, `${pascalName}Repository.ts`),
|
|
177
|
-
repositoryTemplate
|
|
178
|
-
.replace(/{{name}}/g, pascalName)
|
|
179
|
-
.replace(/{{context}}/g, context)
|
|
180
|
-
.replace(/{{endpoint}}/g, endpoint)
|
|
181
|
-
.replace(/{{datasource}}/g, datasource.name)
|
|
182
|
-
.replace(/{{datasourceImport}}/g, datasourceImport)
|
|
183
|
-
.replace(/{{datasourceVar}}/g, toCamelCase(datasource.name))
|
|
184
|
-
.replace(/{{entityLower}}/g, entityLower)
|
|
185
|
-
);
|
|
186
|
-
await updateIndexTs(repoPath);
|
|
187
|
-
|
|
188
|
-
// 3. Create Service
|
|
189
|
-
const servicePath = path.join(contextPath, 'application/services');
|
|
190
|
-
await writeIfNotExists(
|
|
191
|
-
path.join(servicePath, `${pascalName}Service.ts`),
|
|
192
|
-
serviceTemplate
|
|
193
|
-
.replace(/{{name}}/g, pascalName)
|
|
194
|
-
.replace(/{{camelName}}/g, camelName)
|
|
195
|
-
.replace(/{{context}}/g, context)
|
|
196
|
-
);
|
|
197
|
-
await updateIndexTs(servicePath);
|
|
198
|
-
|
|
199
|
-
// Update core index
|
|
200
|
-
await updateCoreIndex();
|
|
201
|
-
|
|
202
|
-
console.log(`✅ CRUD base for ${pascalName} created successfully!`);
|
|
203
|
-
console.log(`\n💡 Remember to:`);
|
|
204
|
-
console.log(` 1. Add ${pascalName}Repository to InfrastructureProvider`);
|
|
205
|
-
console.log(` 2. Add ${pascalName}Service to ApplicationProvider`);
|
|
206
|
-
console.log(` 3. Use 'make:crud-presenter' to create the CRUD presenter`);
|
|
207
|
-
}
|
|
@@ -1,232 +0,0 @@
|
|
|
1
|
-
import prompts from 'prompts';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
import {
|
|
4
|
-
selectContext,
|
|
5
|
-
getContextPath,
|
|
6
|
-
toPascalCase,
|
|
7
|
-
getAvailableFiles,
|
|
8
|
-
getApplicationProviderServices,
|
|
9
|
-
toKebabCase
|
|
10
|
-
} from '../../utils/contextUtils.js';
|
|
11
|
-
import { updateIndexTs, writeIfNotExists, updateCoreIndex } from '../../utils/fileUtils.js';
|
|
12
|
-
|
|
13
|
-
const createSchemaTemplate = `import { {{schemaFactory}} } from '{{schemaImport}}';
|
|
14
|
-
import type { I{{name}}CreateRequest } from '\${{context}}/domain/{{entityLower}}';
|
|
15
|
-
|
|
16
|
-
export const Create{{name}}Schema = {{schemaFactory}}<I{{name}}CreateRequest>()
|
|
17
|
-
\t.rules(() => ({
|
|
18
|
-
\t\t// Add validation rules here
|
|
19
|
-
\t}))
|
|
20
|
-
\t.create();`;
|
|
21
|
-
|
|
22
|
-
const updateSchemaTemplate = `import { {{schemaFactory}} } from '{{schemaImport}}';
|
|
23
|
-
import type { I{{name}}UpdateRequest } from '\${{context}}/domain/{{entityLower}}';
|
|
24
|
-
|
|
25
|
-
export const Update{{name}}Schema = {{schemaFactory}}<I{{name}}UpdateRequest>()
|
|
26
|
-
\t.rules(() => ({
|
|
27
|
-
\t\t// Add validation rules here
|
|
28
|
-
\t}))
|
|
29
|
-
\t.create();`;
|
|
30
|
-
|
|
31
|
-
const presenterWithCoreTemplate = `import { {{presenterFactory}} } from '$core/presenters';
|
|
32
|
-
import { ApplicationProvider } from '\${{context}}/application';
|
|
33
|
-
import { Create{{name}}Schema, Update{{name}}Schema } from './schema';
|
|
34
|
-
import type {
|
|
35
|
-
\tI{{name}},
|
|
36
|
-
\tI{{name}}CollectionQuery,
|
|
37
|
-
\tI{{name}}CreateRequest,
|
|
38
|
-
\tI{{name}}UpdateRequest
|
|
39
|
-
} from '\${{context}}/domain/{{entityLower}}';
|
|
40
|
-
|
|
41
|
-
export const {{name}}Presenter = {{presenterFactory}}('{{name}}Presenter', ({ createAsyncResource, createAsyncAction }) => {
|
|
42
|
-
\tconst { {{serviceName}} } = ApplicationProvider();
|
|
43
|
-
\t
|
|
44
|
-
\tconst collection = async (query?: I{{name}}CollectionQuery) =>
|
|
45
|
-
\t\tawait createAsyncResource({{serviceName}}.collection(query));
|
|
46
|
-
\t
|
|
47
|
-
\tconst resource = async (id: number) =>
|
|
48
|
-
\t\tawait createAsyncResource({{serviceName}}.resource(id));
|
|
49
|
-
\t
|
|
50
|
-
\tconst create = async (request: I{{name}}CreateRequest) =>
|
|
51
|
-
\t\tawait createAsyncAction<I{{name}}, I{{name}}CreateRequest>(() => {{serviceName}}.create(Create{{name}}Schema.from(request).json()));
|
|
52
|
-
\t
|
|
53
|
-
\tconst update = async (id: number, request: I{{name}}UpdateRequest) =>
|
|
54
|
-
\t\tawait createAsyncAction<I{{name}}, I{{name}}UpdateRequest>(() => {{serviceName}}.update(id, Update{{name}}Schema.from(request).json()));
|
|
55
|
-
\t
|
|
56
|
-
\tconst destroy = async (id: number) =>
|
|
57
|
-
\t\tawait createAsyncAction(() => {{serviceName}}.destroy(id));
|
|
58
|
-
\t
|
|
59
|
-
\treturn { collection, resource, create, update, destroy };
|
|
60
|
-
});`;
|
|
61
|
-
|
|
62
|
-
const presenterWithoutCoreTemplate = `import { createPresenter } from '@azure-net/kit';
|
|
63
|
-
import { ApplicationProvider } from '\${{context}}/application';
|
|
64
|
-
import { Create{{name}}Schema, Update{{name}}Schema } from './schema';
|
|
65
|
-
import type {
|
|
66
|
-
\tI{{name}}CollectionQuery,
|
|
67
|
-
\tI{{name}}CreateRequest,
|
|
68
|
-
\tI{{name}}UpdateRequest
|
|
69
|
-
} from '\${{context}}/domain/{{entityLower}}';
|
|
70
|
-
|
|
71
|
-
export const {{name}}Presenter = createPresenter('{{name}}Presenter', () => {
|
|
72
|
-
\tconst { {{serviceName}} } = ApplicationProvider();
|
|
73
|
-
\t
|
|
74
|
-
\tconst collection = async (query?: I{{name}}CollectionQuery) =>
|
|
75
|
-
\t\tawait {{serviceName}}.collection(query);
|
|
76
|
-
\t
|
|
77
|
-
\tconst resource = async (id: number) =>
|
|
78
|
-
\t\tawait {{serviceName}}.resource(id);
|
|
79
|
-
\t
|
|
80
|
-
\tconst create = async (request: I{{name}}CreateRequest) =>
|
|
81
|
-
\t\tawait {{serviceName}}.create(Create{{name}}Schema.from(request).json());
|
|
82
|
-
\t
|
|
83
|
-
\tconst update = async (id: number, request: I{{name}}UpdateRequest) =>
|
|
84
|
-
\t\tawait {{serviceName}}.update(id, Update{{name}}Schema.from(request).json()));
|
|
85
|
-
\t
|
|
86
|
-
\tconst destroy = async (id: number) =>
|
|
87
|
-
\t\tawait {{serviceName}}.destroy(id);
|
|
88
|
-
\t
|
|
89
|
-
\treturn { collection, resource, create, update, destroy };
|
|
90
|
-
});`;
|
|
91
|
-
|
|
92
|
-
export default async function generateCrudPresenter() {
|
|
93
|
-
const context = await selectContext('Select context for CRUD presenter:');
|
|
94
|
-
|
|
95
|
-
// Get available services from ApplicationProvider
|
|
96
|
-
const services = await getApplicationProviderServices(context);
|
|
97
|
-
|
|
98
|
-
if (services.length === 0) {
|
|
99
|
-
console.error('❌ No services found in ApplicationProvider. Add services manually first.');
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
const { service } = await prompts({
|
|
104
|
-
type: 'select',
|
|
105
|
-
name: 'service',
|
|
106
|
-
message: 'Select service for CRUD:',
|
|
107
|
-
choices: services.map(s => ({ title: s, value: s }))
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
// Extract entity name from service name
|
|
111
|
-
const entityName = service.replace('Service', '');
|
|
112
|
-
const pascalName = toPascalCase(entityName);
|
|
113
|
-
const entityLower = toKebabCase(pascalName);
|
|
114
|
-
|
|
115
|
-
// Get schema factory
|
|
116
|
-
const coreSchemas = await getAvailableFiles(
|
|
117
|
-
path.join(process.cwd(), 'src/core/schemas')
|
|
118
|
-
);
|
|
119
|
-
|
|
120
|
-
const { schemaType } = await prompts({
|
|
121
|
-
type: 'select',
|
|
122
|
-
name: 'schemaType',
|
|
123
|
-
message: 'Select schema factory:',
|
|
124
|
-
choices: [
|
|
125
|
-
{ title: 'Use createSchemaFactory from package', value: 'package' },
|
|
126
|
-
...coreSchemas.map(s => ({ title: `Use ${s} from core`, value: s }))
|
|
127
|
-
]
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
// Get presenter factory
|
|
131
|
-
const corePresenters = await getAvailableFiles(
|
|
132
|
-
path.join(process.cwd(), 'src/core/presenters')
|
|
133
|
-
);
|
|
134
|
-
|
|
135
|
-
const { presenterType } = await prompts({
|
|
136
|
-
type: 'select',
|
|
137
|
-
name: 'presenterType',
|
|
138
|
-
message: 'Select presenter factory:',
|
|
139
|
-
choices: [
|
|
140
|
-
{ title: 'Use createPresenter from package', value: 'package' },
|
|
141
|
-
...corePresenters.map(p => ({ title: `Use ${p} from core`, value: p }))
|
|
142
|
-
]
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
const contextPath = getContextPath(context);
|
|
146
|
-
const deliveryModulePath = path.join(contextPath, 'delivery', entityLower);
|
|
147
|
-
const schemaPath = path.join(deliveryModulePath, 'schema');
|
|
148
|
-
|
|
149
|
-
console.log('\n🚀 Generating CRUD presenter...\n');
|
|
150
|
-
|
|
151
|
-
// Create schemas
|
|
152
|
-
const schemaFactory = schemaType === 'package' ? 'Schema' : schemaType;
|
|
153
|
-
const schemaImport = schemaType === 'package'
|
|
154
|
-
? '@azure-net/kit'
|
|
155
|
-
: '$core/schemas';
|
|
156
|
-
|
|
157
|
-
if (schemaType === 'package') {
|
|
158
|
-
const schemaImportFull = `import { createSchemaFactory } from '@azure-net/kit';
|
|
159
|
-
import { createRules, validationMessagesI18n } from '@azure-net/kit/schema';
|
|
160
|
-
|
|
161
|
-
const Schema = createSchemaFactory(createRules(validationMessagesI18n));`;
|
|
162
|
-
|
|
163
|
-
await writeIfNotExists(
|
|
164
|
-
path.join(schemaPath, `Create${pascalName}Schema.ts`),
|
|
165
|
-
schemaImportFull + '\n' + createSchemaTemplate
|
|
166
|
-
.replace('import { {{schemaFactory}} } from \'{{schemaImport}}\';\n', '')
|
|
167
|
-
.replace(/{{name}}/g, pascalName)
|
|
168
|
-
.replace(/{{context}}/g, context)
|
|
169
|
-
.replace(/{{entityLower}}/g, entityLower)
|
|
170
|
-
.replace(/{{schemaFactory}}/g, 'Schema')
|
|
171
|
-
);
|
|
172
|
-
|
|
173
|
-
await writeIfNotExists(
|
|
174
|
-
path.join(schemaPath, `Update${pascalName}Schema.ts`),
|
|
175
|
-
schemaImportFull + '\n' + updateSchemaTemplate
|
|
176
|
-
.replace('import { {{schemaFactory}} } from \'{{schemaImport}}\';\n', '')
|
|
177
|
-
.replace(/{{name}}/g, pascalName)
|
|
178
|
-
.replace(/{{context}}/g, context)
|
|
179
|
-
.replace(/{{entityLower}}/g, entityLower)
|
|
180
|
-
.replace(/{{schemaFactory}}/g, 'Schema')
|
|
181
|
-
);
|
|
182
|
-
} else {
|
|
183
|
-
await writeIfNotExists(
|
|
184
|
-
path.join(schemaPath, `Create${pascalName}Schema.ts`),
|
|
185
|
-
createSchemaTemplate
|
|
186
|
-
.replace(/{{name}}/g, pascalName)
|
|
187
|
-
.replace(/{{context}}/g, context)
|
|
188
|
-
.replace(/{{entityLower}}/g, entityLower)
|
|
189
|
-
.replace(/{{schemaFactory}}/g, schemaFactory)
|
|
190
|
-
.replace(/{{schemaImport}}/g, schemaImport)
|
|
191
|
-
);
|
|
192
|
-
|
|
193
|
-
await writeIfNotExists(
|
|
194
|
-
path.join(schemaPath, `Update${pascalName}Schema.ts`),
|
|
195
|
-
updateSchemaTemplate
|
|
196
|
-
.replace(/{{name}}/g, pascalName)
|
|
197
|
-
.replace(/{{context}}/g, context)
|
|
198
|
-
.replace(/{{entityLower}}/g, entityLower)
|
|
199
|
-
.replace(/{{schemaFactory}}/g, schemaFactory)
|
|
200
|
-
.replace(/{{schemaImport}}/g, schemaImport)
|
|
201
|
-
);
|
|
202
|
-
}
|
|
203
|
-
await updateIndexTs(schemaPath);
|
|
204
|
-
|
|
205
|
-
// Create Presenter
|
|
206
|
-
const presenterTemplate = presenterType === 'package'
|
|
207
|
-
? presenterWithoutCoreTemplate
|
|
208
|
-
: presenterWithCoreTemplate;
|
|
209
|
-
|
|
210
|
-
const presenterFactory = presenterType === 'package' ? 'createPresenter' : presenterType;
|
|
211
|
-
|
|
212
|
-
await writeIfNotExists(
|
|
213
|
-
path.join(deliveryModulePath, `${pascalName}Presenter.ts`),
|
|
214
|
-
presenterTemplate
|
|
215
|
-
.replace(/{{name}}/g, pascalName)
|
|
216
|
-
.replace(/{{context}}/g, context)
|
|
217
|
-
.replace(/{{serviceName}}/g, service)
|
|
218
|
-
.replace(/{{presenterFactory}}/g, presenterFactory)
|
|
219
|
-
.replace(/{{entityLower}}/g, entityLower)
|
|
220
|
-
);
|
|
221
|
-
|
|
222
|
-
// Create module index
|
|
223
|
-
await writeIfNotExists(
|
|
224
|
-
path.join(deliveryModulePath, 'index.ts'),
|
|
225
|
-
`export * from './${pascalName}Presenter';\nexport * from './schema';`
|
|
226
|
-
);
|
|
227
|
-
|
|
228
|
-
// Update core index
|
|
229
|
-
await updateCoreIndex();
|
|
230
|
-
|
|
231
|
-
console.log(`✅ CRUD presenter for ${pascalName} created successfully!`);
|
|
232
|
-
}
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import prompts from 'prompts';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
import { selectContext, getContextPath, toPascalCase, getAvailableFiles } from '../../utils/contextUtils.js';
|
|
4
|
-
import { writeIfNotExists, updateIndexTs, updateCoreIndex } from '../../utils/fileUtils.js';
|
|
5
|
-
|
|
6
|
-
const datasourceWithResponseTemplate = `import { BaseHttpDatasource, type CreateRequestCallbackType } from '@azure-net/kit/infra';
|
|
7
|
-
import { {{responseClass}} } from '{{responseImport}}';
|
|
8
|
-
|
|
9
|
-
export class {{name}}Datasource extends BaseHttpDatasource {
|
|
10
|
-
\tasync createRequest<T>(callback: CreateRequestCallbackType<T>) {
|
|
11
|
-
\t\treturn new {{responseClass}}<T>(await this.createRawRequest<T>(callback));
|
|
12
|
-
\t}
|
|
13
|
-
}`;
|
|
14
|
-
|
|
15
|
-
export default async function generateDatasource() {
|
|
16
|
-
const context = await selectContext('Select context for datasource (or core):');
|
|
17
|
-
|
|
18
|
-
const { name } = await prompts({
|
|
19
|
-
type: 'text',
|
|
20
|
-
name: 'name',
|
|
21
|
-
message: 'Datasource name (without "Datasource" suffix):'
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
const pascalName = toPascalCase(name);
|
|
25
|
-
const contextPath = context === 'core'
|
|
26
|
-
? path.join(process.cwd(), 'src/core')
|
|
27
|
-
: getContextPath(context);
|
|
28
|
-
|
|
29
|
-
// Get available responses
|
|
30
|
-
const coreResponses = await getAvailableFiles(
|
|
31
|
-
path.join(process.cwd(), 'src/core/responses')
|
|
32
|
-
);
|
|
33
|
-
|
|
34
|
-
const contextResponses = context !== 'core'
|
|
35
|
-
? await getAvailableFiles(path.join(contextPath, 'infrastructure/responses'))
|
|
36
|
-
: [];
|
|
37
|
-
|
|
38
|
-
const allResponses = [
|
|
39
|
-
...coreResponses.map(r => ({
|
|
40
|
-
title: `${r} (core)`,
|
|
41
|
-
value: { name: r, from: 'core' }
|
|
42
|
-
})),
|
|
43
|
-
...contextResponses.map(r => ({
|
|
44
|
-
title: `${r} (${context})`,
|
|
45
|
-
value: { name: r, from: context }
|
|
46
|
-
}))
|
|
47
|
-
];
|
|
48
|
-
|
|
49
|
-
if (allResponses.length === 0) {
|
|
50
|
-
console.error('❌ No responses available. Create a response first with make:response');
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const { response } = await prompts({
|
|
55
|
-
type: 'select',
|
|
56
|
-
name: 'response',
|
|
57
|
-
message: 'Select response for datasource:',
|
|
58
|
-
choices: allResponses
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
const datasourcePath = context === 'core'
|
|
62
|
-
? path.join(contextPath, 'datasources')
|
|
63
|
-
: path.join(contextPath, 'infrastructure/http/datasources');
|
|
64
|
-
|
|
65
|
-
const responseImport = response.from === 'core'
|
|
66
|
-
? context === 'core' ? '../responses' : '$core/responses'
|
|
67
|
-
: `\$${context}/infrastructure/responses`;
|
|
68
|
-
|
|
69
|
-
const content = datasourceWithResponseTemplate
|
|
70
|
-
.replace(/{{name}}/g, pascalName)
|
|
71
|
-
.replace(/{{responseClass}}/g, response.name)
|
|
72
|
-
.replace(/{{responseImport}}/g, responseImport);
|
|
73
|
-
|
|
74
|
-
const filePath = path.join(datasourcePath, `${pascalName}Datasource.ts`);
|
|
75
|
-
await writeIfNotExists(filePath, content);
|
|
76
|
-
await updateIndexTs(datasourcePath);
|
|
77
|
-
|
|
78
|
-
// Update core index if needed
|
|
79
|
-
if (context === 'core') {
|
|
80
|
-
await updateCoreIndex();
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
console.log(`✅ Datasource created at ${filePath}`);
|
|
84
|
-
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import prompts from 'prompts';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
import { selectContext } from '../../utils/contextUtils.js';
|
|
4
|
-
import { writeIfNotExists } from '../../utils/fileUtils.js';
|
|
5
|
-
|
|
6
|
-
const designComponentTemplate = `<script lang="ts">
|
|
7
|
-
\timport './style.scss';
|
|
8
|
-
</script>
|
|
9
|
-
|
|
10
|
-
{{componentName}}
|
|
11
|
-
`;
|
|
12
|
-
|
|
13
|
-
const styleTemplate = `// Add your styles here
|
|
14
|
-
`;
|
|
15
|
-
|
|
16
|
-
export default async function generateDesignComponent() {
|
|
17
|
-
const context = await selectContext('Select context for design component:');
|
|
18
|
-
|
|
19
|
-
const { componentPath } = await prompts({
|
|
20
|
-
type: 'text',
|
|
21
|
-
name: 'componentPath',
|
|
22
|
-
message: 'Design component path (e.g. Button/Themes/PrimaryButton):',
|
|
23
|
-
validate: value => value.length > 0 ? true : 'Path cannot be empty'
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
// Parse the path
|
|
27
|
-
const normalizedPath = componentPath.replace(/\\/g, '/');
|
|
28
|
-
const pathParts = normalizedPath.split('/');
|
|
29
|
-
const componentName = pathParts[pathParts.length - 1];
|
|
30
|
-
|
|
31
|
-
// Build the full path: src/app/{context}/ui/design/{path}
|
|
32
|
-
const contextUiPath = path.join(process.cwd(), 'src/app', context, 'ui/design');
|
|
33
|
-
const fullComponentPath = path.join(contextUiPath, normalizedPath);
|
|
34
|
-
|
|
35
|
-
console.log(`\n🚀 Generating design component: ${componentName}...\n`);
|
|
36
|
-
|
|
37
|
-
// Create Component.svelte
|
|
38
|
-
await writeIfNotExists(
|
|
39
|
-
path.join(fullComponentPath, 'Component.svelte'),
|
|
40
|
-
designComponentTemplate.replace(/{{componentName}}/g, componentName)
|
|
41
|
-
);
|
|
42
|
-
|
|
43
|
-
// Create style.scss
|
|
44
|
-
await writeIfNotExists(
|
|
45
|
-
path.join(fullComponentPath, 'style.scss'),
|
|
46
|
-
styleTemplate
|
|
47
|
-
);
|
|
48
|
-
|
|
49
|
-
console.log(`✅ Design component created at: ${fullComponentPath}`);
|
|
50
|
-
console.log(`\n💡 Files created:`);
|
|
51
|
-
console.log(` - Component.svelte`);
|
|
52
|
-
console.log(` - style.scss`);
|
|
53
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import prompts from 'prompts';
|
|
2
|
-
import generateRepository from './generateRepository.js';
|
|
3
|
-
import generateService from './generateService.js';
|
|
4
|
-
import generatePresenter from './generatePresenter.js';
|
|
5
|
-
import generateSchema from './generateSchema.js';
|
|
6
|
-
|
|
7
|
-
export default async function generateModule() {
|
|
8
|
-
console.log('🚀 Generating complete module...\n');
|
|
9
|
-
console.log('⚠️ Note: This will create repository, service, presenter and schemas.');
|
|
10
|
-
console.log(' You will need to manually wire them in the providers.\n');
|
|
11
|
-
|
|
12
|
-
const { confirm } = await prompts({
|
|
13
|
-
type: 'confirm',
|
|
14
|
-
name: 'confirm',
|
|
15
|
-
message: 'Continue?'
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
if (confirm) {
|
|
19
|
-
await generateRepository();
|
|
20
|
-
await generateService();
|
|
21
|
-
await generatePresenter();
|
|
22
|
-
await generateSchema(); // Create schema
|
|
23
|
-
await generateSchema(); // Update schema
|
|
24
|
-
|
|
25
|
-
console.log('\n✅ Module generation complete!');
|
|
26
|
-
console.log('\n💡 Remember to:');
|
|
27
|
-
console.log(' 1. Add repository to InfrastructureProvider');
|
|
28
|
-
console.log(' 2. Add service to ApplicationProvider');
|
|
29
|
-
console.log(' 3. Update presenter to use the service from ApplicationProvider');
|
|
30
|
-
}
|
|
31
|
-
}
|