@open-rlb/nestjs-amqp 1.0.13 → 1.0.15
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/modules/broker/index.d.ts +2 -0
- package/modules/broker/index.js +2 -0
- package/modules/broker/index.js.map +1 -1
- package/modules/broker/services/broker.service.js +1 -1
- package/modules/broker/services/broker.service.js.map +1 -1
- package/package.json +14 -5
- package/schematics/collection.json +10 -0
- package/schematics/defaults.d.ts +14 -0
- package/schematics/defaults.js +18 -0
- package/schematics/defaults.js.map +1 -0
- package/schematics/defaults.ts +14 -0
- package/schematics/nest-add/index.d.ts +3 -0
- package/schematics/nest-add/index.js +315 -0
- package/schematics/nest-add/index.js.map +1 -0
- package/schematics/nest-add/index.ts +440 -0
- package/schematics/nest-add/init.schema.d.ts +15 -0
- package/schematics/nest-add/init.schema.js +3 -0
- package/schematics/nest-add/init.schema.js.map +1 -0
- package/schematics/nest-add/init.schema.ts +52 -0
- package/schematics/nest-add/schema.d.ts +5 -0
- package/schematics/nest-add/schema.js +3 -0
- package/schematics/nest-add/schema.js.map +1 -0
- package/schematics/nest-add/schema.json +20 -0
- package/schematics/nest-add/schema.ts +9 -0
- package/schematics/utils/dependencies.utils.d.ts +15 -0
- package/schematics/utils/dependencies.utils.js +43 -0
- package/schematics/utils/dependencies.utils.js.map +1 -0
- package/schematics/utils/dependencies.utils.ts +61 -0
- package/schematics/utils/formatting.d.ts +2 -0
- package/schematics/utils/formatting.js +23 -0
- package/schematics/utils/formatting.js.map +1 -0
- package/schematics/utils/formatting.spec.ts +45 -0
- package/schematics/utils/formatting.ts +31 -0
- package/schematics/utils/index.d.ts +9 -0
- package/schematics/utils/index.js +26 -0
- package/schematics/utils/index.js.map +1 -0
- package/schematics/utils/index.ts +9 -0
- package/schematics/utils/json-file.util.d.ts +15 -0
- package/schematics/utils/json-file.util.js +69 -0
- package/schematics/utils/json-file.util.js.map +1 -0
- package/schematics/utils/json-file.util.ts +100 -0
- package/schematics/utils/metadata.manager.d.ts +13 -0
- package/schematics/utils/metadata.manager.js +175 -0
- package/schematics/utils/metadata.manager.js.map +1 -0
- package/schematics/utils/metadata.manager.spec.ts +357 -0
- package/schematics/utils/metadata.manager.ts +241 -0
- package/schematics/utils/module-import.declarator.d.ts +10 -0
- package/schematics/utils/module-import.declarator.js +40 -0
- package/schematics/utils/module-import.declarator.js.map +1 -0
- package/schematics/utils/module-import.declarator.spec.ts +122 -0
- package/schematics/utils/module-import.declarator.ts +44 -0
- package/schematics/utils/module-metadata.declarator.d.ts +4 -0
- package/schematics/utils/module-metadata.declarator.js +13 -0
- package/schematics/utils/module-metadata.declarator.js.map +1 -0
- package/schematics/utils/module-metadata.declarator.spec.ts +404 -0
- package/schematics/utils/module-metadata.declarator.ts +14 -0
- package/schematics/utils/module.declarator.d.ts +23 -0
- package/schematics/utils/module.declarator.js +33 -0
- package/schematics/utils/module.declarator.js.map +1 -0
- package/schematics/utils/module.declarator.spec.ts +52 -0
- package/schematics/utils/module.declarator.ts +44 -0
- package/schematics/utils/module.finder.d.ts +13 -0
- package/schematics/utils/module.finder.js +25 -0
- package/schematics/utils/module.finder.js.map +1 -0
- package/schematics/utils/module.finder.spec.ts +59 -0
- package/schematics/utils/module.finder.ts +32 -0
- package/schematics/utils/name.parser.d.ts +12 -0
- package/schematics/utils/name.parser.js +18 -0
- package/schematics/utils/name.parser.js.map +1 -0
- package/schematics/utils/name.parser.spec.ts +50 -0
- package/schematics/utils/name.parser.ts +26 -0
- package/schematics/utils/path.solver.d.ts +4 -0
- package/schematics/utils/path.solver.js +15 -0
- package/schematics/utils/path.solver.js.map +1 -0
- package/schematics/utils/path.solver.spec.ts +11 -0
- package/schematics/utils/path.solver.ts +15 -0
- package/schematics/utils/source-root.helpers.d.ts +6 -0
- package/schematics/utils/source-root.helpers.js +25 -0
- package/schematics/utils/source-root.helpers.js.map +1 -0
- package/schematics/utils/source-root.helpers.ts +30 -0
- package/tsconfig.build.tsbuildinfo +1 -1
|
@@ -0,0 +1,440 @@
|
|
|
1
|
+
import { Path, strings } from '@angular-devkit/core';
|
|
2
|
+
import { apply, applyTemplates, branchAndMerge, chain, FileEntry, forEach, MergeStrategy, mergeWith, move, Rule, SchematicContext, Tree, url } from '@angular-devkit/schematics';
|
|
3
|
+
import { parse } from 'jsonc-parser';
|
|
4
|
+
import { normalize } from 'path';
|
|
5
|
+
import { normalizeToKebabOrSnakeCase } from '../utils/formatting';
|
|
6
|
+
import { ModuleFinder } from '../utils/module.finder';
|
|
7
|
+
import { Location, NameParser } from '../utils/name.parser';
|
|
8
|
+
import { mergeSourceRoot } from '../utils/source-root.helpers';
|
|
9
|
+
import { InitOptions } from './init.schema';
|
|
10
|
+
|
|
11
|
+
type UpdateJsonFn<T> = (obj: T) => T | void;
|
|
12
|
+
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
// Costanti per BrokerModule
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
|
|
17
|
+
const BROKER_IMPORT_LINE =
|
|
18
|
+
"import { AppConfig, BrokerModule, BrokerTopic, GatewayConfig, HandlerAuthConfig, ProxyModule, RabbitMQConfig } from '@open-rlb/nestjs-amqp';";
|
|
19
|
+
|
|
20
|
+
const BROKER_FOR_ROOT_ASYNC = `BrokerModule.forRootAsync({
|
|
21
|
+
imports: [ConfigModule],
|
|
22
|
+
inject: [ConfigService],
|
|
23
|
+
useFactory: async (configService: ConfigService) => {
|
|
24
|
+
const options = configService.get<RabbitMQConfig>('broker');
|
|
25
|
+
const topics = configService.get<BrokerTopic[]>('topics');
|
|
26
|
+
const app = configService.get<AppConfig>('app');
|
|
27
|
+
const gateway = configService.get<GatewayConfig>('gateway');
|
|
28
|
+
const authConfig = configService.get<HandlerAuthConfig[]>('auth-providers');
|
|
29
|
+
return { options, topics, appOptions: app, authOptions: authConfig, gatewayOptions: gateway };
|
|
30
|
+
},
|
|
31
|
+
})`;
|
|
32
|
+
|
|
33
|
+
// ---------------------------------------------------------------------------
|
|
34
|
+
// Costanti per config.yaml
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Blocco YAML da appendere (o da usare per creare) config/config.yaml.
|
|
39
|
+
* Contiene un solo esempio per ciascuna delle categorie previste.
|
|
40
|
+
*/
|
|
41
|
+
const CONFIG_YAML_BLOCK = `
|
|
42
|
+
app:
|
|
43
|
+
port: 80
|
|
44
|
+
host: 0.0.0.0
|
|
45
|
+
environment: "development"
|
|
46
|
+
|
|
47
|
+
auth-providers: []
|
|
48
|
+
|
|
49
|
+
broker:
|
|
50
|
+
name: "rabbitmq"
|
|
51
|
+
uri: "<AMQP_URI>"
|
|
52
|
+
defaultSubscribeErrorBehavior: "ack"
|
|
53
|
+
defaultPublishErrorBehavior: "reject"
|
|
54
|
+
connectionManagerOptions:
|
|
55
|
+
heartbeatIntervalInSeconds: 60
|
|
56
|
+
reconnectTimeInSeconds: 60
|
|
57
|
+
connectionOptions:
|
|
58
|
+
clientProperties:
|
|
59
|
+
connection_name: "<APP_NAME>"
|
|
60
|
+
credentials:
|
|
61
|
+
mechanism: PLAIN
|
|
62
|
+
username: "<AMQP_USERNAME>"
|
|
63
|
+
password: "<AMQP_PASSWORD>"
|
|
64
|
+
exchanges:
|
|
65
|
+
- name: example.fanout
|
|
66
|
+
type: "fanout"
|
|
67
|
+
createExchangeIfNotExists: true
|
|
68
|
+
options:
|
|
69
|
+
durable: true
|
|
70
|
+
autoDelete: false
|
|
71
|
+
internal: false
|
|
72
|
+
queues:
|
|
73
|
+
- name: example.queue
|
|
74
|
+
createQueueIfNotExists: true
|
|
75
|
+
exchange: example.fanout
|
|
76
|
+
routingKey: example.queue
|
|
77
|
+
options:
|
|
78
|
+
durable: true
|
|
79
|
+
autoDelete: false
|
|
80
|
+
exclusive: false
|
|
81
|
+
|
|
82
|
+
topics:
|
|
83
|
+
- name: example.topic
|
|
84
|
+
exchange: example.fanout
|
|
85
|
+
routingKey: "example.topic"
|
|
86
|
+
mode: event
|
|
87
|
+
|
|
88
|
+
gateway:
|
|
89
|
+
events: []
|
|
90
|
+
paths:
|
|
91
|
+
- name: example-path
|
|
92
|
+
method: POST
|
|
93
|
+
dataSource: body
|
|
94
|
+
path: /example
|
|
95
|
+
topic: example.topic
|
|
96
|
+
action: example-action
|
|
97
|
+
mode: event
|
|
98
|
+
`;
|
|
99
|
+
|
|
100
|
+
// ---------------------------------------------------------------------------
|
|
101
|
+
// Entry point
|
|
102
|
+
// ---------------------------------------------------------------------------
|
|
103
|
+
|
|
104
|
+
export function main(options: InitOptions): Rule {
|
|
105
|
+
options = transform(options);
|
|
106
|
+
return (tree: Tree, context: SchematicContext) => {
|
|
107
|
+
return branchAndMerge(
|
|
108
|
+
chain([
|
|
109
|
+
mergeSourceRoot(options),
|
|
110
|
+
addDeclarationToModule(options),
|
|
111
|
+
addBrokerModuleToAppModule(),
|
|
112
|
+
updateConfigYaml(),
|
|
113
|
+
updatePackageJson(options),
|
|
114
|
+
mergeWith(generate(options), MergeStrategy.Overwrite),
|
|
115
|
+
]),
|
|
116
|
+
)(tree, context);
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// ---------------------------------------------------------------------------
|
|
121
|
+
// Helpers interni
|
|
122
|
+
// ---------------------------------------------------------------------------
|
|
123
|
+
|
|
124
|
+
function transform(source: InitOptions): InitOptions {
|
|
125
|
+
const target: InitOptions = Object.assign({}, source);
|
|
126
|
+
target.metadata = 'providers';
|
|
127
|
+
target.type = 'module';
|
|
128
|
+
target.language = 'ts';
|
|
129
|
+
const location: Location = new NameParser().parse({ ...target, name: 'init' });
|
|
130
|
+
target.name = '';
|
|
131
|
+
target.path = normalizeToKebabOrSnakeCase(location.path);
|
|
132
|
+
target.specFileSuffix = normalizeToKebabOrSnakeCase(
|
|
133
|
+
source.specFileSuffix || 'spec',
|
|
134
|
+
);
|
|
135
|
+
return target;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function generate(options: InitOptions) {
|
|
139
|
+
return (context: SchematicContext) =>
|
|
140
|
+
apply(url('./files'), [
|
|
141
|
+
applyTemplates({
|
|
142
|
+
classify: strings.classify,
|
|
143
|
+
dasherize: strings.dasherize,
|
|
144
|
+
name: options.name,
|
|
145
|
+
}),
|
|
146
|
+
renameDotfiles,
|
|
147
|
+
move(normalize('./')),
|
|
148
|
+
])(context);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const renameDotfiles = forEach((entry: FileEntry) => {
|
|
152
|
+
if (entry.path.includes('/__dot')) {
|
|
153
|
+
const newPath = normalize(entry.path.replace('/__dot', '/.'));
|
|
154
|
+
return {
|
|
155
|
+
content: entry.content,
|
|
156
|
+
path: newPath,
|
|
157
|
+
} as FileEntry;
|
|
158
|
+
}
|
|
159
|
+
return entry;
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
// ---------------------------------------------------------------------------
|
|
163
|
+
// Rule: aggiunge CoreModule al modulo radice trovato da ModuleFinder
|
|
164
|
+
// ---------------------------------------------------------------------------
|
|
165
|
+
|
|
166
|
+
function addDeclarationToModule(options: InitOptions): Rule {
|
|
167
|
+
return (tree: Tree) => {
|
|
168
|
+
if (options.skipImport !== undefined && options.skipImport) {
|
|
169
|
+
return tree;
|
|
170
|
+
}
|
|
171
|
+
options.module = new ModuleFinder(tree).find({
|
|
172
|
+
name: '',
|
|
173
|
+
path: options.path as Path,
|
|
174
|
+
});
|
|
175
|
+
if (!options.module) {
|
|
176
|
+
return tree;
|
|
177
|
+
}
|
|
178
|
+
const content = tree.read(options.module).toString();
|
|
179
|
+
const contentLines = content.split('\n');
|
|
180
|
+
const importIndex = findImportsEndpoint(contentLines);
|
|
181
|
+
const toInsert = "import { CoreModule } from '@lbd-core/lib-nestjs-core';\n";
|
|
182
|
+
contentLines.splice(importIndex + 1, 0, toInsert);
|
|
183
|
+
|
|
184
|
+
const providersIndex = contentLines.findIndex(line => line.trim().startsWith('imports:'));
|
|
185
|
+
const openingIndex = contentLines.findIndex((line, index) => index >= providersIndex && line.includes('['));
|
|
186
|
+
const closingIndex = contentLines.findIndex((line, index) => index >= providersIndex && index >= openingIndex && line.includes(']'));
|
|
187
|
+
|
|
188
|
+
if (providersIndex !== -1) {
|
|
189
|
+
if (openingIndex === closingIndex) {
|
|
190
|
+
const line = contentLines[providersIndex];
|
|
191
|
+
contentLines[providersIndex] = line.replace('[', `[CoreModule,`);
|
|
192
|
+
} else {
|
|
193
|
+
contentLines.splice(openingIndex, +1, `CoreModule,`);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
tree.overwrite(options.module, contentLines.join('\n'));
|
|
197
|
+
return tree;
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// ---------------------------------------------------------------------------
|
|
202
|
+
// Rule: crea o aggiorna config/config.yaml con il blocco di configurazione
|
|
203
|
+
// ---------------------------------------------------------------------------
|
|
204
|
+
|
|
205
|
+
function updateConfigYaml(): Rule {
|
|
206
|
+
return (tree: Tree) => {
|
|
207
|
+
const CONFIG_PATH = 'config/config.yaml';
|
|
208
|
+
|
|
209
|
+
if (!tree.exists(CONFIG_PATH)) {
|
|
210
|
+
// Crea il file da zero con l'intero blocco template
|
|
211
|
+
tree.create(CONFIG_PATH, CONFIG_YAML_BLOCK.trimStart());
|
|
212
|
+
return tree;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// File esistente: appende solo le sezioni ancora mancanti
|
|
216
|
+
const existing = tree.read(CONFIG_PATH)!.toString('utf-8');
|
|
217
|
+
const SECTION_KEYS = ['app:', 'auth-providers:', 'broker:', 'topics:', 'gateway:'] as const;
|
|
218
|
+
|
|
219
|
+
let toAppend = '';
|
|
220
|
+
for (const key of SECTION_KEYS) {
|
|
221
|
+
if (!existing.includes(key)) {
|
|
222
|
+
const block = extractYamlSection(CONFIG_YAML_BLOCK, key);
|
|
223
|
+
if (block) {
|
|
224
|
+
toAppend += '\n' + block;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
if (toAppend.length > 0) {
|
|
230
|
+
tree.overwrite(CONFIG_PATH, existing.trimEnd() + '\n' + toAppend);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
return tree;
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Estrae dal template YAML il blocco che inizia con `sectionKey`
|
|
239
|
+
* e termina prima del prossimo blocco di primo livello (chiave senza indentazione).
|
|
240
|
+
*/
|
|
241
|
+
function extractYamlSection(yaml: string, sectionKey: string): string {
|
|
242
|
+
const lines = yaml.split('\n');
|
|
243
|
+
const startIdx = lines.findIndex(l => l.startsWith(sectionKey));
|
|
244
|
+
if (startIdx === -1) return '';
|
|
245
|
+
|
|
246
|
+
const endIdx = lines.findIndex(
|
|
247
|
+
(l, i) => i > startIdx && l.length > 0 && !l.startsWith(' ') && !l.startsWith('#'),
|
|
248
|
+
);
|
|
249
|
+
|
|
250
|
+
const sectionLines = endIdx === -1 ? lines.slice(startIdx) : lines.slice(startIdx, endIdx);
|
|
251
|
+
return sectionLines.join('\n').trimEnd();
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// ---------------------------------------------------------------------------
|
|
255
|
+
// Rule: aggiunge BrokerModule.forRootAsync(...) ad app.module.ts
|
|
256
|
+
// ---------------------------------------------------------------------------
|
|
257
|
+
|
|
258
|
+
function addBrokerModuleToAppModule(): Rule {
|
|
259
|
+
return (tree: Tree) => {
|
|
260
|
+
// Cerca app.module.ts nella posizione canonica; fallback su ricerca ricorsiva
|
|
261
|
+
const candidatePaths = [
|
|
262
|
+
'/src/app.module.ts',
|
|
263
|
+
'/app/app.module.ts',
|
|
264
|
+
'src/app.module.ts',
|
|
265
|
+
'app/app.module.ts',
|
|
266
|
+
];
|
|
267
|
+
|
|
268
|
+
let modulePath: string | undefined = candidatePaths.find(p => tree.exists(p));
|
|
269
|
+
|
|
270
|
+
if (!modulePath) {
|
|
271
|
+
// Ricerca ricorsiva come ultima risorsa
|
|
272
|
+
modulePath = findFileInTree(tree, 'app.module.ts');
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
if (!modulePath) {
|
|
276
|
+
console.warn('[ng-add] app.module.ts non trovato: BrokerModule non aggiunto.');
|
|
277
|
+
return tree;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
const rawContent = tree.read(modulePath);
|
|
281
|
+
if (!rawContent) {
|
|
282
|
+
return tree;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
let content = rawContent.toString('utf-8');
|
|
286
|
+
|
|
287
|
+
// ---- 1. Aggiunge l'import statement se non già presente ----------------
|
|
288
|
+
if (!content.includes('@open-rlb/nestjs-amqp')) {
|
|
289
|
+
const importInsertPos = findLastImportEndIndex(content);
|
|
290
|
+
content =
|
|
291
|
+
content.slice(0, importInsertPos) +
|
|
292
|
+
'\n' + BROKER_IMPORT_LINE +
|
|
293
|
+
content.slice(importInsertPos);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// ---- 2. Aggiunge BrokerModule.forRootAsync nell'array imports ----------
|
|
297
|
+
if (!content.includes('BrokerModule.forRootAsync')) {
|
|
298
|
+
content = insertIntoImportsArray(content, BROKER_FOR_ROOT_ASYNC);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
tree.overwrite(modulePath, content);
|
|
302
|
+
return tree;
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Inserisce `moduleEntry` all'interno del primo array `imports: [...]`
|
|
308
|
+
* trovato nel decoratore @Module di NestJS.
|
|
309
|
+
*
|
|
310
|
+
* Gestisce sia array su singola riga sia array multi-riga.
|
|
311
|
+
*/
|
|
312
|
+
function insertIntoImportsArray(source: string, moduleEntry: string): string {
|
|
313
|
+
// Trova "imports:" seguito (eventualmente con spazi/newline) da "["
|
|
314
|
+
const importsArrayRegex = /imports\s*:\s*\[/;
|
|
315
|
+
const match = importsArrayRegex.exec(source);
|
|
316
|
+
if (!match) {
|
|
317
|
+
return source;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// Posizione del "[" che apre l'array
|
|
321
|
+
const openBracketPos = source.indexOf('[', match.index);
|
|
322
|
+
|
|
323
|
+
// Trova il corrispondente "]" tenendo conto di bracket annidati
|
|
324
|
+
let depth = 0;
|
|
325
|
+
let closeBracketPos = -1;
|
|
326
|
+
for (let i = openBracketPos; i < source.length; i++) {
|
|
327
|
+
if (source[i] === '[') depth++;
|
|
328
|
+
else if (source[i] === ']') {
|
|
329
|
+
depth--;
|
|
330
|
+
if (depth === 0) {
|
|
331
|
+
closeBracketPos = i;
|
|
332
|
+
break;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
if (closeBracketPos === -1) {
|
|
338
|
+
return source; // array non chiuso correttamente
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// Determina il contenuto corrente dell'array (senza le parentesi quadre)
|
|
342
|
+
const arrayContent = source.slice(openBracketPos + 1, closeBracketPos).trim();
|
|
343
|
+
|
|
344
|
+
let newArrayContent: string;
|
|
345
|
+
if (arrayContent.length === 0) {
|
|
346
|
+
// Array vuoto → inserisce direttamente
|
|
347
|
+
newArrayContent = `\n ${moduleEntry},\n `;
|
|
348
|
+
} else {
|
|
349
|
+
// Array con contenuto → aggiunge in testa (prima entry), con virgola finale
|
|
350
|
+
newArrayContent = `\n ${moduleEntry},\n ${arrayContent}\n `;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
return (
|
|
354
|
+
source.slice(0, openBracketPos + 1) +
|
|
355
|
+
newArrayContent +
|
|
356
|
+
source.slice(closeBracketPos)
|
|
357
|
+
);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* Restituisce la posizione di fine dell'ultimo statement `import` nel file,
|
|
362
|
+
* utile per inserire un nuovo import subito dopo l'ultimo esistente.
|
|
363
|
+
*/
|
|
364
|
+
function findLastImportEndIndex(source: string): number {
|
|
365
|
+
const importRegex = /^import\s+.+from\s+['"][^'"]+['"];?\s*$/gm;
|
|
366
|
+
let lastEnd = 0;
|
|
367
|
+
let match: RegExpExecArray | null;
|
|
368
|
+
while ((match = importRegex.exec(source)) !== null) {
|
|
369
|
+
lastEnd = match.index + match[0].length;
|
|
370
|
+
}
|
|
371
|
+
return lastEnd;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* Ricerca ricorsiva di un file per nome all'interno dell'albero Schematics.
|
|
376
|
+
*/
|
|
377
|
+
function findFileInTree(tree: Tree, fileName: string): string | undefined {
|
|
378
|
+
let found: string | undefined;
|
|
379
|
+
tree.visit(path => {
|
|
380
|
+
if (!found && path.endsWith(`/${fileName}`)) {
|
|
381
|
+
found = path;
|
|
382
|
+
}
|
|
383
|
+
});
|
|
384
|
+
return found;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
// ---------------------------------------------------------------------------
|
|
388
|
+
// Rule: aggiorna package.json con script jest
|
|
389
|
+
// ---------------------------------------------------------------------------
|
|
390
|
+
|
|
391
|
+
function updatePackageJson(options: InitOptions) {
|
|
392
|
+
return (host: Tree) => {
|
|
393
|
+
if (!host.exists('package.json')) {
|
|
394
|
+
return host;
|
|
395
|
+
}
|
|
396
|
+
return updateJsonFile(
|
|
397
|
+
host,
|
|
398
|
+
'package.json',
|
|
399
|
+
(packageJson: Record<string, any>) => {
|
|
400
|
+
updateNpmScripts(packageJson.scripts, options);
|
|
401
|
+
},
|
|
402
|
+
);
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
function updateJsonFile<T>(
|
|
407
|
+
host: Tree,
|
|
408
|
+
path: string,
|
|
409
|
+
callback: UpdateJsonFn<T>,
|
|
410
|
+
): Tree {
|
|
411
|
+
const source = host.read(path);
|
|
412
|
+
if (source) {
|
|
413
|
+
const sourceText = source.toString('utf-8');
|
|
414
|
+
const json = parse(sourceText);
|
|
415
|
+
callback(json as unknown as T);
|
|
416
|
+
host.overwrite(path, JSON.stringify(json, null, 2));
|
|
417
|
+
}
|
|
418
|
+
return host;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
function updateNpmScripts(scripts: Record<string, any>, _options: InitOptions) {
|
|
422
|
+
if (!scripts) {
|
|
423
|
+
return;
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
// ---------------------------------------------------------------------------
|
|
428
|
+
// Utility: trova l'indice dell'ultimo import nel formato array di stringhe
|
|
429
|
+
// ---------------------------------------------------------------------------
|
|
430
|
+
|
|
431
|
+
function findImportsEndpoint(contentLines: string[]): number {
|
|
432
|
+
const reversedContent = Array.from(contentLines).reverse();
|
|
433
|
+
const reverseImports = reversedContent.filter(line =>
|
|
434
|
+
line.match(/\} from ('|")/),
|
|
435
|
+
);
|
|
436
|
+
if (reverseImports.length <= 0) {
|
|
437
|
+
return 0;
|
|
438
|
+
}
|
|
439
|
+
return contentLines.indexOf(reverseImports[0]);
|
|
440
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Path } from '@angular-devkit/core';
|
|
2
|
+
export interface InitOptions {
|
|
3
|
+
name?: string;
|
|
4
|
+
path?: string;
|
|
5
|
+
module?: Path;
|
|
6
|
+
skipImport?: boolean;
|
|
7
|
+
metadata?: string;
|
|
8
|
+
type?: string;
|
|
9
|
+
language?: string;
|
|
10
|
+
sourceRoot?: string;
|
|
11
|
+
spec?: boolean;
|
|
12
|
+
specFileSuffix?: string;
|
|
13
|
+
flat?: boolean;
|
|
14
|
+
prefix?: string;
|
|
15
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.schema.js","sourceRoot":"","sources":["../../../libs/rlb-nestjs-amqp/src/schematics/nest-add/init.schema.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { Path } from '@angular-devkit/core';
|
|
2
|
+
|
|
3
|
+
export interface InitOptions {
|
|
4
|
+
/**
|
|
5
|
+
* The name of the service.
|
|
6
|
+
*/
|
|
7
|
+
name?: string;
|
|
8
|
+
/**
|
|
9
|
+
* The path to create the service.
|
|
10
|
+
*/
|
|
11
|
+
path?: string;
|
|
12
|
+
/**
|
|
13
|
+
* The path to insert the service declaration.
|
|
14
|
+
*/
|
|
15
|
+
module?: Path;
|
|
16
|
+
/**
|
|
17
|
+
* Directive to insert declaration in module.
|
|
18
|
+
*/
|
|
19
|
+
skipImport?: boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Metadata name affected by declaration insertion.
|
|
22
|
+
*/
|
|
23
|
+
metadata?: string;
|
|
24
|
+
/**
|
|
25
|
+
* Nest element type name
|
|
26
|
+
*/
|
|
27
|
+
type?: string;
|
|
28
|
+
/**
|
|
29
|
+
* Application language.
|
|
30
|
+
*/
|
|
31
|
+
language?: string;
|
|
32
|
+
/**
|
|
33
|
+
* The source root path
|
|
34
|
+
*/
|
|
35
|
+
sourceRoot?: string;
|
|
36
|
+
/**
|
|
37
|
+
* Specifies if a spec file is generated.
|
|
38
|
+
*/
|
|
39
|
+
spec?: boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Specifies the file suffix of spec files.
|
|
42
|
+
* @default "spec"
|
|
43
|
+
*/
|
|
44
|
+
specFileSuffix?: string;
|
|
45
|
+
/**
|
|
46
|
+
* Flag to indicate if a directory is created.
|
|
47
|
+
*/
|
|
48
|
+
flat?: boolean;
|
|
49
|
+
|
|
50
|
+
prefix?: string
|
|
51
|
+
|
|
52
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../libs/rlb-nestjs-amqp/src/schematics/nest-add/schema.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/schema",
|
|
3
|
+
"$id": "SchematicsHandlebar",
|
|
4
|
+
"title": "Init Schema",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"properties": {},
|
|
7
|
+
"path": {
|
|
8
|
+
"type": "string",
|
|
9
|
+
"format": "path",
|
|
10
|
+
"description": "The path to create the init.",
|
|
11
|
+
"visible": false
|
|
12
|
+
},
|
|
13
|
+
"project": {
|
|
14
|
+
"type": "string",
|
|
15
|
+
"description": "The name of the project.",
|
|
16
|
+
"$default": {
|
|
17
|
+
"$source": "projectName"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Tree } from '@angular-devkit/schematics';
|
|
2
|
+
export declare enum NodeDependencyType {
|
|
3
|
+
Default = "dependencies",
|
|
4
|
+
Dev = "devDependencies",
|
|
5
|
+
Peer = "peerDependencies",
|
|
6
|
+
Optional = "optionalDependencies"
|
|
7
|
+
}
|
|
8
|
+
export interface NodeDependency {
|
|
9
|
+
type: NodeDependencyType;
|
|
10
|
+
name: string;
|
|
11
|
+
version: string;
|
|
12
|
+
overwrite?: boolean;
|
|
13
|
+
}
|
|
14
|
+
export declare function addPackageJsonDependency(tree: Tree, dependency: NodeDependency, pkgJsonPath?: string): void;
|
|
15
|
+
export declare function getPackageJsonDependency(tree: Tree, name: string, pkgJsonPath?: string): NodeDependency | null;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NodeDependencyType = void 0;
|
|
4
|
+
exports.addPackageJsonDependency = addPackageJsonDependency;
|
|
5
|
+
exports.getPackageJsonDependency = getPackageJsonDependency;
|
|
6
|
+
const json_file_util_1 = require("./json-file.util");
|
|
7
|
+
const PKG_JSON_PATH = '/package.json';
|
|
8
|
+
var NodeDependencyType;
|
|
9
|
+
(function (NodeDependencyType) {
|
|
10
|
+
NodeDependencyType["Default"] = "dependencies";
|
|
11
|
+
NodeDependencyType["Dev"] = "devDependencies";
|
|
12
|
+
NodeDependencyType["Peer"] = "peerDependencies";
|
|
13
|
+
NodeDependencyType["Optional"] = "optionalDependencies";
|
|
14
|
+
})(NodeDependencyType || (exports.NodeDependencyType = NodeDependencyType = {}));
|
|
15
|
+
const ALL_DEPENDENCY_TYPE = [
|
|
16
|
+
NodeDependencyType.Default,
|
|
17
|
+
NodeDependencyType.Dev,
|
|
18
|
+
NodeDependencyType.Optional,
|
|
19
|
+
NodeDependencyType.Peer,
|
|
20
|
+
];
|
|
21
|
+
function addPackageJsonDependency(tree, dependency, pkgJsonPath = PKG_JSON_PATH) {
|
|
22
|
+
const json = new json_file_util_1.JSONFile(tree, pkgJsonPath);
|
|
23
|
+
const { overwrite, type, name, version } = dependency;
|
|
24
|
+
const path = [type, name];
|
|
25
|
+
if (overwrite || !json.get(path)) {
|
|
26
|
+
json.modify(path, version);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function getPackageJsonDependency(tree, name, pkgJsonPath = PKG_JSON_PATH) {
|
|
30
|
+
const json = new json_file_util_1.JSONFile(tree, pkgJsonPath);
|
|
31
|
+
for (const depType of ALL_DEPENDENCY_TYPE) {
|
|
32
|
+
const version = json.get([depType, name]);
|
|
33
|
+
if (typeof version === 'string') {
|
|
34
|
+
return {
|
|
35
|
+
type: depType,
|
|
36
|
+
name: name,
|
|
37
|
+
version,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=dependencies.utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dependencies.utils.js","sourceRoot":"","sources":["../../../libs/rlb-nestjs-amqp/src/schematics/utils/dependencies.utils.ts"],"names":[],"mappings":";;;AAyBA,4DAaC;AAED,4DAoBC;AA3DD,qDAA4C;AAE5C,MAAM,aAAa,GAAG,eAAe,CAAC;AACtC,IAAY,kBAKX;AALD,WAAY,kBAAkB;IAC5B,8CAAwB,CAAA;IACxB,6CAAuB,CAAA;IACvB,+CAAyB,CAAA;IACzB,uDAAiC,CAAA;AACnC,CAAC,EALW,kBAAkB,kCAAlB,kBAAkB,QAK7B;AASD,MAAM,mBAAmB,GAAG;IAC1B,kBAAkB,CAAC,OAAO;IAC1B,kBAAkB,CAAC,GAAG;IACtB,kBAAkB,CAAC,QAAQ;IAC3B,kBAAkB,CAAC,IAAI;CACxB,CAAC;AAEF,SAAgB,wBAAwB,CACtC,IAAU,EACV,UAA0B,EAC1B,WAAW,GAAG,aAAa;IAE3B,MAAM,IAAI,GAAG,IAAI,yBAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IAE7C,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,UAAU,CAAC;IACtD,MAAM,IAAI,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAE1B,IAAI,SAAS,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QACjC,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC7B,CAAC;AACH,CAAC;AAED,SAAgB,wBAAwB,CACtC,IAAU,EACV,IAAY,EACZ,WAAW,GAAG,aAAa;IAE3B,MAAM,IAAI,GAAG,IAAI,yBAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IAE7C,KAAK,MAAM,OAAO,IAAI,mBAAmB,EAAE,CAAC;QAC1C,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;QAE1C,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YAChC,OAAO;gBACL,IAAI,EAAE,OAAO;gBACb,IAAI,EAAE,IAAI;gBACV,OAAO;aACR,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { Tree } from '@angular-devkit/schematics';
|
|
2
|
+
import { JSONFile } from './json-file.util';
|
|
3
|
+
|
|
4
|
+
const PKG_JSON_PATH = '/package.json';
|
|
5
|
+
export enum NodeDependencyType {
|
|
6
|
+
Default = 'dependencies',
|
|
7
|
+
Dev = 'devDependencies',
|
|
8
|
+
Peer = 'peerDependencies',
|
|
9
|
+
Optional = 'optionalDependencies',
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface NodeDependency {
|
|
13
|
+
type: NodeDependencyType;
|
|
14
|
+
name: string;
|
|
15
|
+
version: string;
|
|
16
|
+
overwrite?: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const ALL_DEPENDENCY_TYPE = [
|
|
20
|
+
NodeDependencyType.Default,
|
|
21
|
+
NodeDependencyType.Dev,
|
|
22
|
+
NodeDependencyType.Optional,
|
|
23
|
+
NodeDependencyType.Peer,
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
export function addPackageJsonDependency(
|
|
27
|
+
tree: Tree,
|
|
28
|
+
dependency: NodeDependency,
|
|
29
|
+
pkgJsonPath = PKG_JSON_PATH,
|
|
30
|
+
): void {
|
|
31
|
+
const json = new JSONFile(tree, pkgJsonPath);
|
|
32
|
+
|
|
33
|
+
const { overwrite, type, name, version } = dependency;
|
|
34
|
+
const path = [type, name];
|
|
35
|
+
|
|
36
|
+
if (overwrite || !json.get(path)) {
|
|
37
|
+
json.modify(path, version);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function getPackageJsonDependency(
|
|
42
|
+
tree: Tree,
|
|
43
|
+
name: string,
|
|
44
|
+
pkgJsonPath = PKG_JSON_PATH,
|
|
45
|
+
): NodeDependency | null {
|
|
46
|
+
const json = new JSONFile(tree, pkgJsonPath);
|
|
47
|
+
|
|
48
|
+
for (const depType of ALL_DEPENDENCY_TYPE) {
|
|
49
|
+
const version = json.get([depType, name]);
|
|
50
|
+
|
|
51
|
+
if (typeof version === 'string') {
|
|
52
|
+
return {
|
|
53
|
+
type: depType,
|
|
54
|
+
name: name,
|
|
55
|
+
version,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return null;
|
|
61
|
+
}
|