@0kmpo/openapi-clean-arch-generator 1.3.15 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +120 -63
- package/dist/main.js +9 -3
- package/dist/package.json +1 -1
- package/dist/src/generators/clean-arch.generator.js +45 -33
- package/dist/src/generators/dto.generator.js +8 -4
- package/dist/src/utils/config.js +3 -0
- package/dist/src/utils/name-formatter.js +34 -0
- package/dist/templates/api.repository.contract.mustache +1 -1
- package/dist/templates/api.repository.impl.mock.mustache +2 -2
- package/dist/templates/api.repository.impl.mustache +5 -5
- package/dist/templates/api.repository.impl.spec.mustache +2 -2
- package/dist/templates/api.use-cases.contract.mustache +1 -1
- package/dist/templates/api.use-cases.impl.mustache +2 -2
- package/dist/templates/api.use-cases.impl.spec.mustache +2 -2
- package/dist/templates/api.use-cases.mock.mustache +2 -2
- package/dist/templates/mapper.mustache +2 -2
- package/dist/templates/mapper.spec.mustache +2 -2
- package/dist/templates/model-entity.mustache +1 -1
- package/dist/templates/model.mock.mustache +2 -2
- package/dist/templates/repository.provider.mock.mustache +2 -2
- package/dist/templates/repository.provider.mustache +2 -2
- package/dist/templates/use-cases.provider.mock.mustache +2 -2
- package/dist/templates/use-cases.provider.mustache +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -75,6 +75,7 @@ Options:
|
|
|
75
75
|
-i, --input <file> OpenAPI/Swagger file (yaml or json) [default: swagger.yaml]
|
|
76
76
|
-o, --output <dir> Output directory [default: ./src/app]
|
|
77
77
|
-t, --templates <dir> Custom templates directory [default: ./templates]
|
|
78
|
+
-k, --base-name <name> Base name for generated folders (defaults to swagger filename)
|
|
78
79
|
-s, --select-endpoints Interactively select tags and endpoints to generate
|
|
79
80
|
-c, --config <file> Use a JSON configuration file (skips interactive prompts)
|
|
80
81
|
--init-config [file] Generate a JSON configuration file instead of generating code
|
|
@@ -84,12 +85,31 @@ Options:
|
|
|
84
85
|
-h, --help Show help
|
|
85
86
|
```
|
|
86
87
|
|
|
88
|
+
### Base name (`-k`)
|
|
89
|
+
|
|
90
|
+
The generator organises output into subfolders based on a **base name** derived from your OpenAPI file. By default it extracts the token immediately before `-swagger` in the filename:
|
|
91
|
+
|
|
92
|
+
| Filename | Derived base name |
|
|
93
|
+
|---|---|
|
|
94
|
+
| `my-app-swagger.yaml` | `app` |
|
|
95
|
+
| `ecommerce-swagger.yaml` | `ecommerce` |
|
|
96
|
+
| `backoffice.yaml` | `backoffice` (+ warning) |
|
|
97
|
+
|
|
98
|
+
Use `-k` to override this value:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
generate-clean-arch -i api.yaml -k example1 # all files go under example1/
|
|
102
|
+
```
|
|
103
|
+
|
|
87
104
|
### Examples
|
|
88
105
|
|
|
89
106
|
```bash
|
|
90
107
|
# Generate from swagger.yaml into src/app
|
|
91
108
|
generate-clean-arch -i swagger.yaml -o ./src/app
|
|
92
109
|
|
|
110
|
+
# Override base name (folder organisation)
|
|
111
|
+
generate-clean-arch -i ecommerce-api-swagger.yaml -o src/app -k ecommerce
|
|
112
|
+
|
|
93
113
|
# Interactively select tags/endpoints
|
|
94
114
|
generate-clean-arch -i api.yaml -s
|
|
95
115
|
|
|
@@ -109,68 +129,62 @@ generate-clean-arch --init-config generation-config.json
|
|
|
109
129
|
generate-clean-arch -c generation-config.json
|
|
110
130
|
|
|
111
131
|
# Full example with all options
|
|
112
|
-
generate-clean-arch -i ./docs/api.yaml -o ./frontend/src/app -t ./custom-templates
|
|
132
|
+
generate-clean-arch -i ./docs/api.yaml -o ./frontend/src/app -t ./custom-templates -k myapp
|
|
113
133
|
```
|
|
114
134
|
|
|
115
135
|
## 📁 Generated Structure
|
|
116
136
|
|
|
117
|
-
The generator creates the following structure following Clean Architecture:
|
|
137
|
+
The generator creates the following structure following Clean Architecture. All artefacts are organised under a **base name** folder (derived from the OpenAPI filename or set with `-k`), and within each layer further grouped by **tag subfolders** (one per API tag, or `shared` for types used across multiple tags):
|
|
118
138
|
|
|
119
139
|
```
|
|
120
140
|
src/app/
|
|
121
|
-
├──
|
|
122
|
-
│ ├──
|
|
123
|
-
│ │ ├──
|
|
124
|
-
│ │ │ ├──
|
|
125
|
-
│ │ │
|
|
126
|
-
│ │
|
|
127
|
-
│ │
|
|
128
|
-
│ │ │
|
|
129
|
-
│ │
|
|
130
|
-
│ │
|
|
131
|
-
│ │
|
|
132
|
-
│ ├──
|
|
133
|
-
│ │
|
|
134
|
-
│ │ ├──
|
|
135
|
-
│ │
|
|
136
|
-
│ │ ├──
|
|
137
|
-
│ │ ├──
|
|
138
|
-
│ │ ├──
|
|
139
|
-
│ │
|
|
140
|
-
│ └──
|
|
141
|
-
│
|
|
142
|
-
│
|
|
143
|
-
│
|
|
144
|
-
│
|
|
145
|
-
│
|
|
146
|
-
|
|
147
|
-
│ ├──
|
|
148
|
-
│ │
|
|
149
|
-
│
|
|
150
|
-
│ └── use-cases/ # Use cases
|
|
151
|
-
│ ├── node/
|
|
152
|
-
│ │ ├── node.use-cases.contract.ts
|
|
153
|
-
│ │ ├── node.use-cases.impl.ts
|
|
154
|
-
│ │ ├── node.use-cases.mock.ts
|
|
155
|
-
│ │ └── node.use-cases.impl.spec.ts
|
|
141
|
+
├── <baseName>/ # Base name folder (e.g. "ecommerce")
|
|
142
|
+
│ ├── <tag1>/ # Tag subfolder (camelCase, e.g. "user")
|
|
143
|
+
│ │ ├── data/dtos/ # Data Transfer Objects
|
|
144
|
+
│ │ │ ├── user.dto.ts
|
|
145
|
+
│ │ │ ├── user.dto.mock.ts
|
|
146
|
+
│ │ │ └── ...
|
|
147
|
+
│ │ ├── data/repositories/ # Repository implementations
|
|
148
|
+
│ │ │ ├── user.repository.impl.ts
|
|
149
|
+
│ │ │ ├── user.repository.impl.mock.ts
|
|
150
|
+
│ │ │ └── user.repository.impl.spec.ts
|
|
151
|
+
│ │ ├── data/mappers/ # DTO → Entity transformers
|
|
152
|
+
│ │ │ ├── user.mapper.ts
|
|
153
|
+
│ │ │ └── user.mapper.spec.ts
|
|
154
|
+
│ │ ├── domain/repositories/ # Repository contracts
|
|
155
|
+
│ │ │ └── user.repository.contract.ts
|
|
156
|
+
│ │ ├── domain/use-cases/ # Use cases
|
|
157
|
+
│ │ │ ├── user.use-cases.contract.ts
|
|
158
|
+
│ │ │ ├── user.use-cases.impl.ts
|
|
159
|
+
│ │ │ ├── user.use-cases.mock.ts
|
|
160
|
+
│ │ │ └── user.use-cases.impl.spec.ts
|
|
161
|
+
│ │ ├── di/repositories/ # Repository DI providers
|
|
162
|
+
│ │ │ ├── user.repository.provider.ts
|
|
163
|
+
│ │ │ └── user.repository.provider.mock.ts
|
|
164
|
+
│ │ └── di/use-cases/ # Use case DI providers
|
|
165
|
+
│ │ ├── user.use-cases.provider.ts
|
|
166
|
+
│ │ └── user.use-cases.provider.mock.ts
|
|
167
|
+
│ ├── <tag2>/ # Another tag (e.g. "productFormat")
|
|
168
|
+
│ │ └── ... # Same internal structure
|
|
169
|
+
│ └── shared/ # Shared types (used by 0 or multiple tags)
|
|
156
170
|
│ └── ...
|
|
157
|
-
|
|
158
|
-
│ ├── repositories/ # Repository providers
|
|
159
|
-
│ │ ├── node.repository.provider.ts
|
|
160
|
-
│ │ ├── node.repository.provider.mock.ts
|
|
161
|
-
│ │ └── ...
|
|
162
|
-
│ └── use-cases/ # Use case providers
|
|
163
|
-
│ ├── node.use-cases.provider.ts
|
|
164
|
-
│ ├── node.use-cases.provider.mock.ts
|
|
165
|
-
│ └── ...
|
|
166
|
-
└── entities/ # Domain entities
|
|
171
|
+
└── entities/ # Domain entities (outside baseName)
|
|
167
172
|
└── models/
|
|
168
|
-
├──
|
|
169
|
-
├──
|
|
170
|
-
├──
|
|
171
|
-
└──
|
|
173
|
+
├── <tag1>/
|
|
174
|
+
│ ├── user.model.ts
|
|
175
|
+
│ ├── user.model.mock.ts
|
|
176
|
+
│ └── user.model.spec.ts
|
|
177
|
+
└── shared/
|
|
178
|
+
└── ...
|
|
172
179
|
```
|
|
173
180
|
|
|
181
|
+
### How the folder organisation works
|
|
182
|
+
|
|
183
|
+
1. **Base name** — derived from the OpenAPI filename (token before `-swagger`) or overridden with `-k`
|
|
184
|
+
2. **Tag subfolders** — each API tag gets its own camelCase folder (e.g. `User` → `user`, `Product Format` → `productFormat`)
|
|
185
|
+
3. **Shared types** — schemas used by zero or multiple tags land in `shared/`
|
|
186
|
+
4. **Layer grouping** — each tag subfolder mirrors the full Clean Architecture layers (`data/`, `domain/`, `di/`, `entities/`)
|
|
187
|
+
|
|
174
188
|
## 🔧 Template Customization
|
|
175
189
|
|
|
176
190
|
Templates live in `templates/` and use [Mustache](https://mustache.github.io/) syntax. Override them by passing your own directory with `-t`.
|
|
@@ -231,6 +245,20 @@ After each run a `generation-report.json` file is created:
|
|
|
231
245
|
"prettier": { "ran": true, "filesFormatted": 42 },
|
|
232
246
|
"eslint": { "ran": true, "filesFixed": 42 }
|
|
233
247
|
},
|
|
248
|
+
"warnings": {
|
|
249
|
+
"total": 2,
|
|
250
|
+
"exampleMismatches": [
|
|
251
|
+
{
|
|
252
|
+
"schemaName": "UserDto",
|
|
253
|
+
"propertyName": "age",
|
|
254
|
+
"declaredType": "string",
|
|
255
|
+
"exampleValue": 25,
|
|
256
|
+
"exampleJsType": "number",
|
|
257
|
+
"action": "coerced",
|
|
258
|
+
"coercedValue": "25"
|
|
259
|
+
}
|
|
260
|
+
]
|
|
261
|
+
},
|
|
234
262
|
"structure": {
|
|
235
263
|
"dtos": 15,
|
|
236
264
|
"repositories": 9,
|
|
@@ -243,27 +271,35 @@ After each run a `generation-report.json` file is created:
|
|
|
243
271
|
}
|
|
244
272
|
```
|
|
245
273
|
|
|
274
|
+
The report includes **example/type mismatch warnings** — when your OpenAPI schema declares a type (e.g. `string`) but the `example` value has a different JS type (e.g. a number). The generator either coerces the value or falls back to a type default and logs it here.
|
|
275
|
+
|
|
246
276
|
## 🎯 Angular Integration Example
|
|
247
277
|
|
|
248
278
|
### 1. Generate code
|
|
249
279
|
|
|
250
280
|
```bash
|
|
251
|
-
generate-clean-arch -i ./docs/api.yaml -o ./src/app
|
|
281
|
+
generate-clean-arch -i ./docs/api.yaml -o ./src/app -k myapp
|
|
252
282
|
```
|
|
253
283
|
|
|
284
|
+
### Automatic environment API key detection
|
|
285
|
+
|
|
286
|
+
During generation the tool automatically searches for an `environment.ts` file (up to 8 levels deep, skipping `node_modules`, `.git`, `dist`, etc.). It extracts keys containing "api" and offers them for selection per tag. If no file or no matching keys are found, you'll be prompted to enter them manually.
|
|
287
|
+
|
|
288
|
+
Each tag's repositories use the selected environment key to configure the base URL for HTTP calls (e.g. `environment.apiUrl`).
|
|
289
|
+
|
|
254
290
|
### 2. Register providers
|
|
255
291
|
|
|
256
292
|
In your `app.config.ts` (Angular 17+ standalone):
|
|
257
293
|
|
|
258
294
|
```typescript
|
|
259
295
|
import { ApplicationConfig } from '@angular/core';
|
|
260
|
-
import {
|
|
261
|
-
import {
|
|
296
|
+
import { UserRepositoryProvider } from './myapp/user/di/repositories/user.repository.provider';
|
|
297
|
+
import { UserUseCasesProvider } from './myapp/user/di/use-cases/user.use-cases.provider';
|
|
262
298
|
|
|
263
299
|
export const appConfig: ApplicationConfig = {
|
|
264
300
|
providers: [
|
|
265
|
-
|
|
266
|
-
|
|
301
|
+
UserRepositoryProvider,
|
|
302
|
+
UserUseCasesProvider,
|
|
267
303
|
// ... rest of generated providers
|
|
268
304
|
]
|
|
269
305
|
};
|
|
@@ -273,18 +309,18 @@ export const appConfig: ApplicationConfig = {
|
|
|
273
309
|
|
|
274
310
|
```typescript
|
|
275
311
|
import { Component, inject } from '@angular/core';
|
|
276
|
-
import {
|
|
312
|
+
import { USER_USE_CASES } from './domain/use-cases/myapp/user/user.use-cases.contract';
|
|
277
313
|
|
|
278
314
|
@Component({
|
|
279
|
-
selector: 'app-
|
|
315
|
+
selector: 'app-users',
|
|
280
316
|
template: `...`
|
|
281
317
|
})
|
|
282
|
-
export class
|
|
283
|
-
readonly #
|
|
318
|
+
export class UsersComponent {
|
|
319
|
+
readonly #userUseCases = inject(USER_USE_CASES);
|
|
284
320
|
|
|
285
|
-
|
|
286
|
-
this.#
|
|
287
|
-
console.log(
|
|
321
|
+
loadUsers(): void {
|
|
322
|
+
this.#userUseCases.getUsers().subscribe((users) => {
|
|
323
|
+
console.log(users);
|
|
288
324
|
});
|
|
289
325
|
}
|
|
290
326
|
}
|
|
@@ -308,6 +344,18 @@ Specify the correct path with `-i`:
|
|
|
308
344
|
generate-clean-arch -i ./path/to/your/api.yaml
|
|
309
345
|
```
|
|
310
346
|
|
|
347
|
+
### Base name warning
|
|
348
|
+
|
|
349
|
+
If your OpenAPI file doesn't contain `-swagger` in the filename (e.g. `backoffice.yaml`), the generator uses the last token and emits a warning. Use `-k` to set it explicitly, or define it in your config file:
|
|
350
|
+
|
|
351
|
+
```bash
|
|
352
|
+
# Via CLI
|
|
353
|
+
generate-clean-arch -i backoffice.yaml -k backoffice
|
|
354
|
+
|
|
355
|
+
# Via config file (-c)
|
|
356
|
+
generate-clean-arch -c generation-config.json # with "baseName": "backoffice" in the JSON
|
|
357
|
+
```
|
|
358
|
+
|
|
311
359
|
### Path aliases `@/` not resolving
|
|
312
360
|
|
|
313
361
|
Configure the aliases in your Angular project's `tsconfig.json`:
|
|
@@ -328,12 +376,21 @@ Configure the aliases in your Angular project's `tsconfig.json`:
|
|
|
328
376
|
2. Check the Mustache syntax
|
|
329
377
|
3. Use `--dry-run` to simulate without writing files
|
|
330
378
|
|
|
379
|
+
### Example/type mismatch warnings
|
|
380
|
+
|
|
381
|
+
When your OpenAPI schema declares a type (e.g. `type: string`) but the `example` value is a different JS type (e.g. `example: 25` — a number), the generator either coerces it or uses a type default. Check `generation-report.json` under `warnings.exampleMismatches` for details.
|
|
382
|
+
|
|
331
383
|
## 📝 Notes
|
|
332
384
|
|
|
333
385
|
- The generator produces ready-to-use `.ts` files, it does not compile them
|
|
334
386
|
- Providers must be registered manually in your Angular module or config
|
|
335
387
|
- Requires Angular 17+ (uses the `inject()` function)
|
|
336
388
|
- Compatible with both standalone and module-based projects
|
|
389
|
+
- **Base name**: derived from the OpenAPI filename (token before `-swagger`), overridden with `-k`, or set in the config file (`-c`) as `"baseName"`
|
|
390
|
+
- **Tag organisation**: each API tag gets its own subfolder; shared types go in `shared/`
|
|
391
|
+
- **Environment detection**: automatically finds `environment.ts` and offers API keys per tag
|
|
392
|
+
- **Example validation**: type mismatches between declared types and example values are detected, coerced when possible, and reported in `generation-report.json`
|
|
393
|
+
- **Config workflow**: use `--init-config` to generate a `generation-config.json`, edit it to customise tags/endpoints/baseUrls/baseName, then reuse with `-c`
|
|
337
394
|
|
|
338
395
|
## 🤝 Contributing
|
|
339
396
|
|
package/dist/main.js
CHANGED
|
@@ -20,6 +20,7 @@ const environment_finder_1 = require("./src/utils/environment-finder");
|
|
|
20
20
|
const example_validator_1 = require("./src/utils/example-validator");
|
|
21
21
|
const prompt_1 = require("./src/utils/prompt");
|
|
22
22
|
const config_1 = require("./src/utils/config");
|
|
23
|
+
const name_formatter_1 = require("./src/utils/name-formatter");
|
|
23
24
|
const package_json_1 = __importDefault(require("./package.json"));
|
|
24
25
|
// Disable HTML escaping so that < and > produce valid TypeScript generic types.
|
|
25
26
|
mustache_1.default.escape = function (text) {
|
|
@@ -37,6 +38,7 @@ commander_1.program
|
|
|
37
38
|
.option('--dry-run', 'Simulate without generating files')
|
|
38
39
|
.option('--skip-lint', 'Skip post-generation linting and formatting')
|
|
39
40
|
.option('-s, --select-endpoints', 'Interactively select which tags and endpoints to generate')
|
|
41
|
+
.option('-k, --base-name <name>', 'Base name for generated folders (defaults to swagger filename)')
|
|
40
42
|
.option('-c, --config <file>', 'Use a JSON configuration file (skips interactive prompts)')
|
|
41
43
|
.option('--init-config [file]', 'Generate a JSON configuration file instead of generating code')
|
|
42
44
|
.parse(process.argv);
|
|
@@ -63,6 +65,8 @@ async function main() {
|
|
|
63
65
|
options.skipInstall = generationConfig.skipInstall;
|
|
64
66
|
if (generationConfig.skipLint !== undefined)
|
|
65
67
|
options.skipLint = generationConfig.skipLint;
|
|
68
|
+
if (generationConfig.baseName)
|
|
69
|
+
options.baseName = generationConfig.baseName;
|
|
66
70
|
(0, logger_1.logDetail)('config', `Using configuration file: ${configFile}`);
|
|
67
71
|
}
|
|
68
72
|
(0, logger_1.logDetail)('config', `Input: ${options.input}`);
|
|
@@ -72,6 +76,8 @@ async function main() {
|
|
|
72
76
|
(0, logger_1.logError)(`File not found: ${options.input}`);
|
|
73
77
|
process.exit(1);
|
|
74
78
|
}
|
|
79
|
+
const baseName = options.baseName ?? (0, name_formatter_1.deriveBaseName)(options.input);
|
|
80
|
+
(0, logger_1.logDetail)('config', `Base name: ${baseName}`);
|
|
75
81
|
if (options.dryRun) {
|
|
76
82
|
(0, logger_1.logWarning)('DRY RUN mode — no files will be generated');
|
|
77
83
|
}
|
|
@@ -156,9 +162,9 @@ async function main() {
|
|
|
156
162
|
const tagsMapForSchema = (0, clean_arch_generator_1.buildTagsMapFromAnalysis)(analysis, selectionFilter);
|
|
157
163
|
const schemaTagMap = (0, clean_arch_generator_1.buildSchemaTagMap)(analysis.swagger.components
|
|
158
164
|
?.schemas || {}, tagsMapForSchema);
|
|
159
|
-
(0, dto_generator_1.organizeFiles)(tempDir, options.output, schemaTagMap);
|
|
160
|
-
(0, dto_generator_1.addDtoImports)(options.output);
|
|
161
|
-
(0, clean_arch_generator_1.generateCleanArchitecture)(analysis, options.output, options.templates, tagApiKeyMap, selectionFilter, schemaTagMap);
|
|
165
|
+
(0, dto_generator_1.organizeFiles)(tempDir, options.output, schemaTagMap, baseName);
|
|
166
|
+
(0, dto_generator_1.addDtoImports)(options.output, baseName);
|
|
167
|
+
(0, clean_arch_generator_1.generateCleanArchitecture)(analysis, options.output, options.templates, tagApiKeyMap, selectionFilter, schemaTagMap, baseName);
|
|
162
168
|
(0, filesystem_1.cleanup)(tempDir);
|
|
163
169
|
// ── EXAMPLE/TYPE MISMATCH WARNINGS ─────────────────────────────────────────
|
|
164
170
|
const mismatches = (0, example_validator_1.getExampleMismatches)();
|
package/dist/package.json
CHANGED
|
@@ -191,7 +191,7 @@ function buildSchemaTagMap(schemas, tagsMap) {
|
|
|
191
191
|
return result;
|
|
192
192
|
}
|
|
193
193
|
/** Generates all Clean Architecture artefacts (models, mappers, repos, use cases, providers) using Mustache. */
|
|
194
|
-
function generateCleanArchitecture(analysis, outputDir, templatesDir, tagApiKeyMap = {}, selectionFilter = {}, precomputedSchemaTagMap = {}) {
|
|
194
|
+
function generateCleanArchitecture(analysis, outputDir, templatesDir, tagApiKeyMap = {}, selectionFilter = {}, precomputedSchemaTagMap = {}, baseName = '') {
|
|
195
195
|
(0, logger_1.logStep)('Generating Clean Architecture artefacts using Mustache...');
|
|
196
196
|
const generatedCount = {
|
|
197
197
|
models: 0,
|
|
@@ -212,8 +212,9 @@ function generateCleanArchitecture(analysis, outputDir, templatesDir, tagApiKeyM
|
|
|
212
212
|
: buildSchemaTagMap(schemas, tagsMap);
|
|
213
213
|
// 1. Generate Models, Entities and Mappers from Schemas
|
|
214
214
|
Object.keys(schemas).forEach((schemaName) => {
|
|
215
|
-
const
|
|
216
|
-
const tagFilename = schemaTagMap[
|
|
215
|
+
const schemaBaseName = schemaName.replace(/Dto$/, '');
|
|
216
|
+
const tagFilename = schemaTagMap[schemaBaseName] || 'shared';
|
|
217
|
+
const tagFolderPath = baseName ? `${baseName}/${tagFilename}` : tagFilename;
|
|
217
218
|
const schemaObj = schemas[schemaName];
|
|
218
219
|
const rawProperties = schemaObj.properties || {};
|
|
219
220
|
const requiredProps = schemaObj.required || [];
|
|
@@ -248,16 +249,20 @@ function generateCleanArchitecture(analysis, outputDir, templatesDir, tagApiKeyM
|
|
|
248
249
|
const modelImports = [...referencedTypes].filter(Boolean).map((name) => ({
|
|
249
250
|
classname: name,
|
|
250
251
|
classFilename: (0, name_formatter_1.toCamelCase)(name),
|
|
251
|
-
tagFilename: schemaTagMap[name] || 'shared'
|
|
252
|
+
tagFilename: schemaTagMap[name] || 'shared',
|
|
253
|
+
tagFolderPath: baseName
|
|
254
|
+
? `${baseName}/${schemaTagMap[name] || 'shared'}`
|
|
255
|
+
: schemaTagMap[name] || 'shared'
|
|
252
256
|
}));
|
|
253
257
|
const modelViewData = {
|
|
254
258
|
tagFilename,
|
|
259
|
+
tagFolderPath,
|
|
255
260
|
models: [
|
|
256
261
|
{
|
|
257
262
|
model: {
|
|
258
|
-
classname:
|
|
259
|
-
classFilename: (0, name_formatter_1.toCamelCase)(
|
|
260
|
-
classVarName: (0, name_formatter_1.toCamelCase)(
|
|
263
|
+
classname: schemaBaseName,
|
|
264
|
+
classFilename: (0, name_formatter_1.toCamelCase)(schemaBaseName),
|
|
265
|
+
classVarName: (0, name_formatter_1.toCamelCase)(schemaBaseName),
|
|
261
266
|
description: schemaObj.description || '',
|
|
262
267
|
imports: modelImports,
|
|
263
268
|
vars: varsMap
|
|
@@ -272,10 +277,11 @@ function generateCleanArchitecture(analysis, outputDir, templatesDir, tagApiKeyM
|
|
|
272
277
|
apis: [
|
|
273
278
|
{
|
|
274
279
|
operations: {
|
|
275
|
-
classname:
|
|
276
|
-
classFilename: (0, name_formatter_1.toCamelCase)(
|
|
277
|
-
classVarName: (0, name_formatter_1.toCamelCase)(
|
|
278
|
-
tagFilename
|
|
280
|
+
classname: schemaBaseName,
|
|
281
|
+
classFilename: (0, name_formatter_1.toCamelCase)(schemaBaseName),
|
|
282
|
+
classVarName: (0, name_formatter_1.toCamelCase)(schemaBaseName),
|
|
283
|
+
tagFilename,
|
|
284
|
+
tagFolderPath
|
|
279
285
|
}
|
|
280
286
|
}
|
|
281
287
|
]
|
|
@@ -286,7 +292,7 @@ function generateCleanArchitecture(analysis, outputDir, templatesDir, tagApiKeyM
|
|
|
286
292
|
if (fs_extra_1.default.existsSync(modelTemplatePath)) {
|
|
287
293
|
const template = fs_extra_1.default.readFileSync(modelTemplatePath, 'utf8');
|
|
288
294
|
const output = mustache_1.default.render(template, modelViewData);
|
|
289
|
-
const destPath = path_1.default.join(outputDir, 'entities/models',
|
|
295
|
+
const destPath = path_1.default.join(outputDir, 'entities/models', tagFolderPath, `${(0, name_formatter_1.toCamelCase)(schemaBaseName)}.model.ts`);
|
|
290
296
|
fs_extra_1.default.ensureDirSync(path_1.default.dirname(destPath));
|
|
291
297
|
fs_extra_1.default.writeFileSync(destPath, output);
|
|
292
298
|
generatedCount.models++;
|
|
@@ -297,7 +303,7 @@ function generateCleanArchitecture(analysis, outputDir, templatesDir, tagApiKeyM
|
|
|
297
303
|
if (fs_extra_1.default.existsSync(mapperTemplatePath)) {
|
|
298
304
|
const template = fs_extra_1.default.readFileSync(mapperTemplatePath, 'utf8');
|
|
299
305
|
const output = mustache_1.default.render(template, mapperViewData);
|
|
300
|
-
const destPath = path_1.default.join(outputDir, 'data/mappers',
|
|
306
|
+
const destPath = path_1.default.join(outputDir, 'data/mappers', tagFolderPath, `${(0, name_formatter_1.toCamelCase)(schemaBaseName)}.mapper.ts`);
|
|
301
307
|
fs_extra_1.default.ensureDirSync(path_1.default.dirname(destPath));
|
|
302
308
|
fs_extra_1.default.writeFileSync(destPath, output);
|
|
303
309
|
generatedCount.mappers++;
|
|
@@ -315,45 +321,50 @@ function generateCleanArchitecture(analysis, outputDir, templatesDir, tagApiKeyM
|
|
|
315
321
|
classname: name,
|
|
316
322
|
classFilename: (0, name_formatter_1.toCamelCase)(name),
|
|
317
323
|
tagFilename: targetTag,
|
|
324
|
+
tagFolderPath: baseName ? `${baseName}/${targetTag}` : targetTag,
|
|
318
325
|
importPath
|
|
319
326
|
};
|
|
320
327
|
});
|
|
321
328
|
const dtoMockViewData = {
|
|
322
329
|
tagFilename,
|
|
330
|
+
tagFolderPath,
|
|
323
331
|
models: [
|
|
324
332
|
{
|
|
325
333
|
model: {
|
|
326
|
-
classname:
|
|
327
|
-
classFilename: (0, name_formatter_1.toCamelCase)(
|
|
328
|
-
classVarName: (0, name_formatter_1.toCamelCase)(
|
|
334
|
+
classname: schemaBaseName,
|
|
335
|
+
classFilename: (0, name_formatter_1.toCamelCase)(schemaBaseName),
|
|
336
|
+
classVarName: (0, name_formatter_1.toCamelCase)(schemaBaseName),
|
|
329
337
|
mockImports: dtoMockImports,
|
|
330
338
|
vars: dtoMockVarsMap
|
|
331
339
|
}
|
|
332
340
|
}
|
|
333
341
|
]
|
|
334
342
|
};
|
|
335
|
-
renderTemplate(templatesDir, 'dto.mock.mustache', dtoMockViewData, path_1.default.join(outputDir, 'data/dtos',
|
|
343
|
+
renderTemplate(templatesDir, 'dto.mock.mustache', dtoMockViewData, path_1.default.join(outputDir, 'data/dtos', tagFolderPath, `${(0, name_formatter_1.toCamelCase)(schemaBaseName)}.dto.mock.ts`), generatedCount, 'mocks');
|
|
336
344
|
// Model mock — delegates to mapper + DTO mock (no property values needed)
|
|
337
|
-
renderTemplate(templatesDir, 'model.mock.mustache', modelViewData, path_1.default.join(outputDir, 'entities/models',
|
|
345
|
+
renderTemplate(templatesDir, 'model.mock.mustache', modelViewData, path_1.default.join(outputDir, 'entities/models', tagFolderPath, `${(0, name_formatter_1.toCamelCase)(schemaBaseName)}.model.mock.ts`), generatedCount, 'mocks');
|
|
338
346
|
// Model spec
|
|
339
|
-
renderTemplate(templatesDir, 'model-entity.spec.mustache', modelViewData, path_1.default.join(outputDir, 'entities/models',
|
|
347
|
+
renderTemplate(templatesDir, 'model-entity.spec.mustache', modelViewData, path_1.default.join(outputDir, 'entities/models', tagFolderPath, `${(0, name_formatter_1.toCamelCase)(schemaBaseName)}.model.spec.ts`), generatedCount, 'specs');
|
|
340
348
|
// Mapper spec
|
|
341
|
-
renderTemplate(templatesDir, 'mapper.spec.mustache', mapperViewData, path_1.default.join(outputDir, 'data/mappers',
|
|
349
|
+
renderTemplate(templatesDir, 'mapper.spec.mustache', mapperViewData, path_1.default.join(outputDir, 'data/mappers', tagFolderPath, `${(0, name_formatter_1.toCamelCase)(schemaBaseName)}.mapper.spec.ts`), generatedCount, 'specs');
|
|
342
350
|
});
|
|
343
351
|
// 2. Generate Use Cases and Repositories from Paths/Tags
|
|
344
352
|
// Generate per tag
|
|
345
353
|
Object.keys(tagsMap).forEach((tag) => {
|
|
346
354
|
const tagFilename = (0, name_formatter_1.toCamelCase)(tag);
|
|
355
|
+
const tagFolderPath = baseName ? `${baseName}/${tagFilename}` : tagFilename;
|
|
347
356
|
const returnImports = [];
|
|
348
357
|
const paramImports = [];
|
|
349
358
|
Object.keys(schemas).forEach((s) => {
|
|
350
359
|
const usedAsReturn = tagsMap[tag].some((op) => op.returnType === s || op.returnType === `${s}[]`);
|
|
351
360
|
const usedAsParam = tagsMap[tag].some((op) => op.allParams.some((p) => p.dataType === s || p.dataType === `${s}[]`));
|
|
361
|
+
const schemaTag = schemaTagMap[s] || 'shared';
|
|
352
362
|
const entry = {
|
|
353
363
|
classname: s,
|
|
354
364
|
classFilename: (0, name_formatter_1.toCamelCase)(s),
|
|
355
365
|
classVarName: (0, name_formatter_1.toCamelCase)(s),
|
|
356
|
-
tagFilename:
|
|
366
|
+
tagFilename: schemaTag,
|
|
367
|
+
tagFolderPath: baseName ? `${baseName}/${schemaTag}` : schemaTag
|
|
357
368
|
};
|
|
358
369
|
if (usedAsReturn) {
|
|
359
370
|
returnImports.push(entry);
|
|
@@ -371,6 +382,7 @@ function generateCleanArchitecture(analysis, outputDir, templatesDir, tagApiKeyM
|
|
|
371
382
|
classname: (0, name_formatter_1.toPascalCase)(tag),
|
|
372
383
|
classFilename: tagFilename,
|
|
373
384
|
classVarName: tagFilename,
|
|
385
|
+
tagFolderPath,
|
|
374
386
|
constantName: tag.toUpperCase().replace(/[^A-Z0-9]/g, '_'),
|
|
375
387
|
operation: tagsMap[tag],
|
|
376
388
|
imports: [...returnImports, ...paramImports],
|
|
@@ -382,21 +394,21 @@ function generateCleanArchitecture(analysis, outputDir, templatesDir, tagApiKeyM
|
|
|
382
394
|
]
|
|
383
395
|
}
|
|
384
396
|
};
|
|
385
|
-
renderTemplate(templatesDir, 'api.use-cases.contract.mustache', apiViewData, path_1.default.join(outputDir, 'domain/use-cases',
|
|
386
|
-
renderTemplate(templatesDir, 'api.use-cases.impl.mustache', apiViewData, path_1.default.join(outputDir, 'domain/use-cases',
|
|
387
|
-
renderTemplate(templatesDir, 'api.repository.contract.mustache', apiViewData, path_1.default.join(outputDir, 'domain/repositories',
|
|
388
|
-
renderTemplate(templatesDir, 'api.repository.impl.mustache', apiViewData, path_1.default.join(outputDir, 'data/repositories',
|
|
389
|
-
renderTemplate(templatesDir, 'use-cases.provider.mustache', apiViewData, path_1.default.join(outputDir, 'di/use-cases',
|
|
390
|
-
renderTemplate(templatesDir, 'repository.provider.mustache', apiViewData, path_1.default.join(outputDir, 'di/repositories',
|
|
397
|
+
renderTemplate(templatesDir, 'api.use-cases.contract.mustache', apiViewData, path_1.default.join(outputDir, 'domain/use-cases', tagFolderPath, `${tagFilename}.use-cases.contract.ts`), generatedCount, 'useCases');
|
|
398
|
+
renderTemplate(templatesDir, 'api.use-cases.impl.mustache', apiViewData, path_1.default.join(outputDir, 'domain/use-cases', tagFolderPath, `${tagFilename}.use-cases.impl.ts`), generatedCount, 'useCases');
|
|
399
|
+
renderTemplate(templatesDir, 'api.repository.contract.mustache', apiViewData, path_1.default.join(outputDir, 'domain/repositories', tagFolderPath, `${tagFilename}.repository.contract.ts`), generatedCount, 'repositories');
|
|
400
|
+
renderTemplate(templatesDir, 'api.repository.impl.mustache', apiViewData, path_1.default.join(outputDir, 'data/repositories', tagFolderPath, `${tagFilename}.repository.impl.ts`), generatedCount, 'repositories');
|
|
401
|
+
renderTemplate(templatesDir, 'use-cases.provider.mustache', apiViewData, path_1.default.join(outputDir, 'di/use-cases', tagFolderPath, `${tagFilename}.use-cases.provider.ts`), generatedCount, 'providers');
|
|
402
|
+
renderTemplate(templatesDir, 'repository.provider.mustache', apiViewData, path_1.default.join(outputDir, 'di/repositories', tagFolderPath, `${tagFilename}.repository.provider.ts`), generatedCount, 'providers');
|
|
391
403
|
// Mocks
|
|
392
|
-
renderTemplate(templatesDir, 'api.repository.impl.mock.mustache', apiViewData, path_1.default.join(outputDir, 'data/repositories',
|
|
393
|
-
renderTemplate(templatesDir, 'api.use-cases.mock.mustache', apiViewData, path_1.default.join(outputDir, 'domain/use-cases',
|
|
394
|
-
renderTemplate(templatesDir, 'repository.provider.mock.mustache', apiViewData, path_1.default.join(outputDir, 'di/repositories',
|
|
395
|
-
renderTemplate(templatesDir, 'use-cases.provider.mock.mustache', apiViewData, path_1.default.join(outputDir, 'di/use-cases',
|
|
404
|
+
renderTemplate(templatesDir, 'api.repository.impl.mock.mustache', apiViewData, path_1.default.join(outputDir, 'data/repositories', tagFolderPath, `${tagFilename}.repository.impl.mock.ts`), generatedCount, 'mocks');
|
|
405
|
+
renderTemplate(templatesDir, 'api.use-cases.mock.mustache', apiViewData, path_1.default.join(outputDir, 'domain/use-cases', tagFolderPath, `${tagFilename}.use-cases.mock.ts`), generatedCount, 'mocks');
|
|
406
|
+
renderTemplate(templatesDir, 'repository.provider.mock.mustache', apiViewData, path_1.default.join(outputDir, 'di/repositories', tagFolderPath, `${tagFilename}.repository.provider.mock.ts`), generatedCount, 'mocks');
|
|
407
|
+
renderTemplate(templatesDir, 'use-cases.provider.mock.mustache', apiViewData, path_1.default.join(outputDir, 'di/use-cases', tagFolderPath, `${tagFilename}.use-cases.provider.mock.ts`), generatedCount, 'mocks');
|
|
396
408
|
// Repository impl spec
|
|
397
|
-
renderTemplate(templatesDir, 'api.repository.impl.spec.mustache', apiViewData, path_1.default.join(outputDir, 'data/repositories',
|
|
409
|
+
renderTemplate(templatesDir, 'api.repository.impl.spec.mustache', apiViewData, path_1.default.join(outputDir, 'data/repositories', tagFolderPath, `${tagFilename}.repository.impl.spec.ts`), generatedCount, 'specs');
|
|
398
410
|
// Use-cases impl spec
|
|
399
|
-
renderTemplate(templatesDir, 'api.use-cases.impl.spec.mustache', apiViewData, path_1.default.join(outputDir, 'domain/use-cases',
|
|
411
|
+
renderTemplate(templatesDir, 'api.use-cases.impl.spec.mustache', apiViewData, path_1.default.join(outputDir, 'domain/use-cases', tagFolderPath, `${tagFilename}.use-cases.impl.spec.ts`), generatedCount, 'specs');
|
|
400
412
|
});
|
|
401
413
|
(0, logger_1.logSuccess)(`${generatedCount.models} Models, ${generatedCount.repositories} Repos, ${generatedCount.useCases} Use Cases, ${generatedCount.mappers} Mappers, ${generatedCount.providers} Providers, ${generatedCount.mocks} Mocks, ${generatedCount.specs} Specs generated`);
|
|
402
414
|
return generatedCount;
|
|
@@ -39,7 +39,7 @@ function generateCode(swaggerFile, templatesDir) {
|
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
/** Copies the generated DTOs from the temporary directory to the output directory, organised by tag subfolder. */
|
|
42
|
-
function organizeFiles(tempDir, outputDir, schemaTagMap = {}) {
|
|
42
|
+
function organizeFiles(tempDir, outputDir, schemaTagMap = {}, baseName = '') {
|
|
43
43
|
(0, logger_1.logStep)('Organising generated DTO files...');
|
|
44
44
|
const sourceDir = path_1.default.join(tempDir, 'model');
|
|
45
45
|
const destDir = path_1.default.join(outputDir, 'data/dtos');
|
|
@@ -53,7 +53,9 @@ function organizeFiles(tempDir, outputDir, schemaTagMap = {}) {
|
|
|
53
53
|
const pascalName = (0, name_formatter_1.toPascalCase)(camelName);
|
|
54
54
|
const tagFolder = schemaTagMap[pascalName] || 'shared';
|
|
55
55
|
const sourcePath = path_1.default.join(sourceDir, file);
|
|
56
|
-
const destPath =
|
|
56
|
+
const destPath = baseName
|
|
57
|
+
? path_1.default.join(destDir, baseName, tagFolder, file)
|
|
58
|
+
: path_1.default.join(destDir, tagFolder, file);
|
|
57
59
|
fs_extra_1.default.ensureDirSync(path_1.default.dirname(destPath));
|
|
58
60
|
fs_extra_1.default.copySync(sourcePath, destPath);
|
|
59
61
|
filesMoved++;
|
|
@@ -63,9 +65,11 @@ function organizeFiles(tempDir, outputDir, schemaTagMap = {}) {
|
|
|
63
65
|
(0, logger_1.logSuccess)(`${filesMoved} DTOs moved successfully`);
|
|
64
66
|
}
|
|
65
67
|
/** Post-processes the generated DTOs: adds cross-DTO imports and normalises Array<T> → T[]. */
|
|
66
|
-
function addDtoImports(outputDir) {
|
|
68
|
+
function addDtoImports(outputDir, baseName = '') {
|
|
67
69
|
(0, logger_1.logStep)('Post-processing generated DTOs...');
|
|
68
|
-
const dtosDir =
|
|
70
|
+
const dtosDir = baseName
|
|
71
|
+
? path_1.default.join(outputDir, 'data/dtos', baseName)
|
|
72
|
+
: path_1.default.join(outputDir, 'data/dtos');
|
|
69
73
|
if (!fs_extra_1.default.existsSync(dtosDir))
|
|
70
74
|
return;
|
|
71
75
|
// Collect all .dto.ts files from all subfolders (1 level deep)
|
package/dist/src/utils/config.js
CHANGED
|
@@ -66,6 +66,9 @@ function generateDefaultConfig(analysis, tagSummaries, cliOptions, apiKeys) {
|
|
|
66
66
|
if (cliOptions.templates) {
|
|
67
67
|
config.templates = cliOptions.templates;
|
|
68
68
|
}
|
|
69
|
+
if (cliOptions.baseName) {
|
|
70
|
+
config.baseName = cliOptions.baseName;
|
|
71
|
+
}
|
|
69
72
|
return config;
|
|
70
73
|
}
|
|
71
74
|
/**
|
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.toPascalCase = toPascalCase;
|
|
4
7
|
exports.toCamelCase = toCamelCase;
|
|
5
8
|
exports.isReservedWord = isReservedWord;
|
|
6
9
|
exports.safePropertyName = safePropertyName;
|
|
10
|
+
exports.deriveBaseName = deriveBaseName;
|
|
11
|
+
const path_1 = __importDefault(require("path"));
|
|
12
|
+
const logger_1 = require("./logger");
|
|
7
13
|
/**
|
|
8
14
|
* Converts a string to PascalCase, handling spaces, hyphens and underscores.
|
|
9
15
|
* Used to derive class names from schema/tag names.
|
|
@@ -111,3 +117,31 @@ function isReservedWord(name) {
|
|
|
111
117
|
function safePropertyName(name) {
|
|
112
118
|
return isReservedWord(name) ? `_${name}` : name;
|
|
113
119
|
}
|
|
120
|
+
/**
|
|
121
|
+
* Derives a baseName from a swagger file path, used as the top-level folder
|
|
122
|
+
* that groups all generated artefacts for that contract.
|
|
123
|
+
*
|
|
124
|
+
* Primary rule: takes the token immediately before `-swagger` (case-insensitive).
|
|
125
|
+
* Fallback: takes the last token of the basename and emits a warning.
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* deriveBaseName('my-app-swagger.yaml') // 'app'
|
|
129
|
+
* deriveBaseName('aprovalm-swagger.yaml') // 'aprovalm'
|
|
130
|
+
* deriveBaseName('backoffice.yaml') // 'backoffice' + warning
|
|
131
|
+
* deriveBaseName('my-backoffice.yaml') // 'backoffice' + warning
|
|
132
|
+
*/
|
|
133
|
+
function deriveBaseName(filepath) {
|
|
134
|
+
const base = path_1.default.basename(filepath, path_1.default.extname(filepath));
|
|
135
|
+
const tokens = base.split(/[-_]+/);
|
|
136
|
+
const swaggerIdx = tokens.findIndex((t) => t.toLowerCase() === 'swagger');
|
|
137
|
+
let raw;
|
|
138
|
+
if (swaggerIdx > 0) {
|
|
139
|
+
raw = tokens[swaggerIdx - 1];
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
raw = tokens[tokens.length - 1];
|
|
143
|
+
(0, logger_1.logWarning)(`Could not find "-swagger" segment in "${base}". ` +
|
|
144
|
+
`Using "${raw}" as baseName. Use -k to override.`);
|
|
145
|
+
}
|
|
146
|
+
return toCamelCase(raw);
|
|
147
|
+
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { InjectionToken } from '@angular/core';
|
|
5
5
|
import { Observable } from 'rxjs';
|
|
6
6
|
{{#imports}}
|
|
7
|
-
import { {{classname}} } from '@/entities/models/{{
|
|
7
|
+
import { {{classname}} } from '@/entities/models/{{tagFolderPath}}/{{classFilename}}.model';
|
|
8
8
|
{{/imports}}
|
|
9
9
|
|
|
10
10
|
/**
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
import { MockService } from 'ng-mocks';
|
|
5
5
|
import { of } from 'rxjs';
|
|
6
6
|
|
|
7
|
-
import { {{classname}}RepositoryImpl } from '@/data/repositories/{{
|
|
7
|
+
import { {{classname}}RepositoryImpl } from '@/data/repositories/{{tagFolderPath}}/{{classFilename}}.repository.impl';
|
|
8
8
|
{{#returnImports}}
|
|
9
|
-
import { mock{{classname}}Model } from '@/entities/models/{{
|
|
9
|
+
import { mock{{classname}}Model } from '@/entities/models/{{tagFolderPath}}/{{classFilename}}.model.mock';
|
|
10
10
|
{{/returnImports}}
|
|
11
11
|
|
|
12
12
|
export const mock{{classname}}RepositoryImpl = () =>
|
|
@@ -9,14 +9,14 @@ import { environment } from '@environment';
|
|
|
9
9
|
|
|
10
10
|
import { MRepository } from '@mercadona/core/utils/repository';
|
|
11
11
|
|
|
12
|
-
import { {{classname}}Repository } from '@/domain/repositories/{{
|
|
12
|
+
import { {{classname}}Repository } from '@/domain/repositories/{{tagFolderPath}}/{{classFilename}}.repository.contract';
|
|
13
13
|
{{#returnImports}}
|
|
14
|
-
import { {{classname}}Dto } from '@/dtos/{{
|
|
15
|
-
import { {{classname}} } from '@/entities/models/{{
|
|
16
|
-
import { {{classVarName}}Mapper } from '@/mappers/{{
|
|
14
|
+
import { {{classname}}Dto } from '@/dtos/{{tagFolderPath}}/{{classFilename}}.dto';
|
|
15
|
+
import { {{classname}} } from '@/entities/models/{{tagFolderPath}}/{{classFilename}}.model';
|
|
16
|
+
import { {{classVarName}}Mapper } from '@/mappers/{{tagFolderPath}}/{{classFilename}}.mapper';
|
|
17
17
|
{{/returnImports}}
|
|
18
18
|
{{#paramImports}}
|
|
19
|
-
import { {{classname}} } from '@/entities/models/{{
|
|
19
|
+
import { {{classname}} } from '@/entities/models/{{tagFolderPath}}/{{classFilename}}.model';
|
|
20
20
|
{{/paramImports}}
|
|
21
21
|
|
|
22
22
|
/**
|
|
@@ -6,8 +6,8 @@ import { TestBed } from '@angular/core/testing';
|
|
|
6
6
|
|
|
7
7
|
import { {{classname}}RepositoryImpl } from './{{classFilename}}.repository.impl';
|
|
8
8
|
{{#returnImports}}
|
|
9
|
-
import { mock{{classname}}Dto } from '@/dtos/{{
|
|
10
|
-
import { mock{{classname}}Model } from '@/entities/models/{{
|
|
9
|
+
import { mock{{classname}}Dto } from '@/dtos/{{tagFolderPath}}/{{classFilename}}.dto.mock';
|
|
10
|
+
import { mock{{classname}}Model } from '@/entities/models/{{tagFolderPath}}/{{classFilename}}.model.mock';
|
|
11
11
|
{{/returnImports}}
|
|
12
12
|
|
|
13
13
|
describe('{{classname}}RepositoryImpl', () => {
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { InjectionToken } from '@angular/core';
|
|
5
5
|
import { Observable } from 'rxjs';
|
|
6
6
|
{{#imports}}
|
|
7
|
-
import { {{classname}} } from '@/entities/models/{{
|
|
7
|
+
import { {{classname}} } from '@/entities/models/{{tagFolderPath}}/{{classFilename}}.model';
|
|
8
8
|
{{/imports}}
|
|
9
9
|
|
|
10
10
|
/**
|
|
@@ -6,9 +6,9 @@ import { Observable } from 'rxjs';
|
|
|
6
6
|
|
|
7
7
|
import { {{classname}}UseCases } from './{{classFilename}}.use-cases.contract';
|
|
8
8
|
|
|
9
|
-
import { {{constantName}}_REPOSITORY, {{classname}}Repository } from '@/domain/repositories/{{
|
|
9
|
+
import { {{constantName}}_REPOSITORY, {{classname}}Repository } from '@/domain/repositories/{{tagFolderPath}}/{{classFilename}}.repository.contract';
|
|
10
10
|
{{#imports}}
|
|
11
|
-
import { {{classname}} } from '@/entities/models/{{
|
|
11
|
+
import { {{classname}} } from '@/entities/models/{{tagFolderPath}}/{{classFilename}}.model';
|
|
12
12
|
{{/imports}}
|
|
13
13
|
|
|
14
14
|
/**
|
|
@@ -6,9 +6,9 @@ import { of } from 'rxjs';
|
|
|
6
6
|
|
|
7
7
|
import { {{classname}}UseCasesImpl } from './{{classFilename}}.use-cases.impl';
|
|
8
8
|
|
|
9
|
-
import { {{constantName}}_REPOSITORY, {{classname}}Repository } from '@/domain/repositories/{{
|
|
9
|
+
import { {{constantName}}_REPOSITORY, {{classname}}Repository } from '@/domain/repositories/{{tagFolderPath}}/{{classFilename}}.repository.contract';
|
|
10
10
|
{{#returnImports}}
|
|
11
|
-
import { mock{{classname}}Model } from '@/entities/models/{{
|
|
11
|
+
import { mock{{classname}}Model } from '@/entities/models/{{tagFolderPath}}/{{classFilename}}.model.mock';
|
|
12
12
|
{{/returnImports}}
|
|
13
13
|
|
|
14
14
|
describe('{{classname}}UseCasesImpl', () => {
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
import { MockService } from 'ng-mocks';
|
|
5
5
|
import { of } from 'rxjs';
|
|
6
6
|
|
|
7
|
-
import { {{classname}}UseCasesImpl } from '@/domain/use-cases/{{
|
|
7
|
+
import { {{classname}}UseCasesImpl } from '@/domain/use-cases/{{tagFolderPath}}/{{classFilename}}.use-cases.impl';
|
|
8
8
|
{{#returnImports}}
|
|
9
|
-
import { mock{{classname}}Model } from '@/entities/models/{{
|
|
9
|
+
import { mock{{classname}}Model } from '@/entities/models/{{tagFolderPath}}/{{classFilename}}.model.mock';
|
|
10
10
|
{{/returnImports}}
|
|
11
11
|
|
|
12
12
|
export const mock{{classname}}UseCasesImpl = () =>
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
import { MapFromFn } from '@mercadona/common/public';
|
|
5
5
|
import { Builder } from '@mercadona/common/utils';
|
|
6
6
|
|
|
7
|
-
import { {{classname}}Dto } from '@/dtos/{{
|
|
8
|
-
import { {{classname}} } from '@/entities/models/{{
|
|
7
|
+
import { {{classname}}Dto } from '@/dtos/{{tagFolderPath}}/{{classFilename}}.dto';
|
|
8
|
+
import { {{classname}} } from '@/entities/models/{{tagFolderPath}}/{{classFilename}}.model';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* {{classname}} Mapper
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
{{#model}}
|
|
3
3
|
import { {{classVarName}}Mapper } from './{{classFilename}}.mapper';
|
|
4
4
|
|
|
5
|
-
import { mock{{classname}}Dto } from '@/dtos/{{
|
|
6
|
-
import { {{classname}} } from '@/entities/models/{{
|
|
5
|
+
import { mock{{classname}}Dto } from '@/dtos/{{tagFolderPath}}/{{classFilename}}.dto.mock';
|
|
6
|
+
import { {{classname}} } from '@/entities/models/{{tagFolderPath}}/{{classFilename}}.model';
|
|
7
7
|
|
|
8
8
|
describe('{{classVarName}}Mapper', () => {
|
|
9
9
|
{{#vars}}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{{#models}}
|
|
2
2
|
{{#model}}
|
|
3
3
|
import { {{classname}} } from './{{classFilename}}.model';
|
|
4
|
-
import { {{classVarName}}Mapper } from '@/mappers/{{
|
|
5
|
-
import { mock{{classname}}Dto } from '@/dtos/{{
|
|
4
|
+
import { {{classVarName}}Mapper } from '@/mappers/{{tagFolderPath}}/{{classFilename}}.mapper';
|
|
5
|
+
import { mock{{classname}}Dto } from '@/dtos/{{tagFolderPath}}/{{classFilename}}.dto.mock';
|
|
6
6
|
|
|
7
7
|
export const mock{{classname}}Model = (overrides: Partial<{{classname}}> = {}): {{classname}} =>
|
|
8
8
|
Object.assign(new {{classname}}(), {
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
{{#operations}}
|
|
4
4
|
import { Provider } from '@angular/core';
|
|
5
5
|
|
|
6
|
-
import { {{constantName}}_REPOSITORY } from '@/domain/repositories/{{
|
|
7
|
-
import { mock{{classname}}RepositoryImpl } from '@/data/repositories/{{
|
|
6
|
+
import { {{constantName}}_REPOSITORY } from '@/domain/repositories/{{tagFolderPath}}/{{classFilename}}.repository.contract';
|
|
7
|
+
import { mock{{classname}}RepositoryImpl } from '@/data/repositories/{{tagFolderPath}}/{{classFilename}}.repository.impl.mock';
|
|
8
8
|
|
|
9
9
|
export function mock{{classname}}Repository(): Provider[] {
|
|
10
10
|
return [
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
{{#operations}}
|
|
4
4
|
import { EnvironmentProviders, makeEnvironmentProviders } from '@angular/core';
|
|
5
5
|
|
|
6
|
-
import { {{constantName}}_REPOSITORY } from '@/domain/repositories/{{
|
|
7
|
-
import { {{classname}}RepositoryImpl } from '@/data/repositories/{{
|
|
6
|
+
import { {{constantName}}_REPOSITORY } from '@/domain/repositories/{{tagFolderPath}}/{{classFilename}}.repository.contract';
|
|
7
|
+
import { {{classname}}RepositoryImpl } from '@/data/repositories/{{tagFolderPath}}/{{classFilename}}.repository.impl';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* {{classname}} Repository Provider
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
{{#operations}}
|
|
4
4
|
import { Provider } from '@angular/core';
|
|
5
5
|
|
|
6
|
-
import { {{constantName}}_USE_CASES } from '@/domain/use-cases/{{
|
|
7
|
-
import { mock{{classname}}UseCasesImpl } from '@/domain/use-cases/{{
|
|
6
|
+
import { {{constantName}}_USE_CASES } from '@/domain/use-cases/{{tagFolderPath}}/{{classFilename}}.use-cases.contract';
|
|
7
|
+
import { mock{{classname}}UseCasesImpl } from '@/domain/use-cases/{{tagFolderPath}}/{{classFilename}}.use-cases.mock';
|
|
8
8
|
|
|
9
9
|
export function mock{{classname}}UseCases(): Provider[] {
|
|
10
10
|
return [
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
{{#operations}}
|
|
4
4
|
import { EnvironmentProviders, makeEnvironmentProviders } from '@angular/core';
|
|
5
5
|
|
|
6
|
-
import { {{constantName}}_USE_CASES } from '@/domain/use-cases/{{
|
|
7
|
-
import { {{classname}}UseCasesImpl } from '@/domain/use-cases/{{
|
|
6
|
+
import { {{constantName}}_USE_CASES } from '@/domain/use-cases/{{tagFolderPath}}/{{classFilename}}.use-cases.contract';
|
|
7
|
+
import { {{classname}}UseCasesImpl } from '@/domain/use-cases/{{tagFolderPath}}/{{classFilename}}.use-cases.impl';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* {{classname}} Use Cases Provider
|