@open-rlb/nestjs-amqp 2.1.0 → 2.2.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/package.json +6 -5
- package/schematics/add-auth-provider/index.d.ts +3 -0
- package/schematics/add-auth-provider/index.js +60 -0
- package/schematics/add-auth-provider/index.js.map +1 -0
- package/schematics/add-auth-provider/index.spec.ts +83 -0
- package/schematics/add-auth-provider/index.ts +83 -0
- package/schematics/add-auth-provider/schema.d.ts +18 -0
- package/schematics/add-auth-provider/schema.js +3 -0
- package/schematics/add-auth-provider/schema.js.map +1 -0
- package/schematics/add-auth-provider/schema.json +59 -0
- package/schematics/add-auth-provider/schema.ts +35 -0
- package/schematics/add-exchange/index.d.ts +3 -0
- package/schematics/add-exchange/index.js +49 -0
- package/schematics/add-exchange/index.js.map +1 -0
- package/schematics/add-exchange/index.spec.ts +65 -0
- package/schematics/add-exchange/index.ts +65 -0
- package/schematics/add-exchange/schema.d.ts +14 -0
- package/schematics/add-exchange/schema.js +3 -0
- package/schematics/add-exchange/schema.js.map +1 -0
- package/schematics/add-exchange/schema.json +50 -0
- package/schematics/add-exchange/schema.ts +26 -0
- package/schematics/add-exchange-binding/index.d.ts +3 -0
- package/schematics/add-exchange-binding/index.js +53 -0
- package/schematics/add-exchange-binding/index.js.map +1 -0
- package/schematics/add-exchange-binding/index.spec.ts +73 -0
- package/schematics/add-exchange-binding/index.ts +64 -0
- package/schematics/add-exchange-binding/schema.d.ts +8 -0
- package/schematics/add-exchange-binding/schema.js +3 -0
- package/schematics/add-exchange-binding/schema.js.map +1 -0
- package/schematics/add-exchange-binding/schema.json +36 -0
- package/schematics/add-exchange-binding/schema.ts +14 -0
- package/schematics/add-gateway/index.d.ts +4 -0
- package/schematics/add-gateway/index.js +105 -0
- package/schematics/add-gateway/index.js.map +1 -0
- package/schematics/add-gateway/index.spec.ts +163 -0
- package/schematics/add-gateway/index.ts +141 -0
- package/schematics/add-gateway/paths.d.ts +12 -0
- package/schematics/add-gateway/paths.js +87 -0
- package/schematics/add-gateway/paths.js.map +1 -0
- package/schematics/add-gateway/paths.ts +103 -0
- package/schematics/add-gateway/schema.d.ts +13 -0
- package/schematics/add-gateway/schema.js +3 -0
- package/schematics/add-gateway/schema.js.map +1 -0
- package/schematics/add-gateway/schema.json +63 -0
- package/schematics/add-gateway/schema.ts +24 -0
- package/schematics/add-gateway/wiring.d.ts +14 -0
- package/schematics/add-gateway/wiring.js +102 -0
- package/schematics/add-gateway/wiring.js.map +1 -0
- package/schematics/add-gateway/wiring.ts +115 -0
- package/schematics/add-metrics-topic/index.d.ts +3 -0
- package/schematics/add-metrics-topic/index.js +31 -0
- package/schematics/add-metrics-topic/index.js.map +1 -0
- package/schematics/add-metrics-topic/index.spec.ts +79 -0
- package/schematics/add-metrics-topic/index.ts +49 -0
- package/schematics/add-metrics-topic/schema.d.ts +10 -0
- package/schematics/add-metrics-topic/schema.js +3 -0
- package/schematics/add-metrics-topic/schema.js.map +1 -0
- package/schematics/add-metrics-topic/schema.json +48 -0
- package/schematics/add-metrics-topic/schema.ts +18 -0
- package/schematics/add-queue/index.d.ts +3 -0
- package/schematics/add-queue/index.js +48 -0
- package/schematics/add-queue/index.js.map +1 -0
- package/schematics/add-queue/index.spec.ts +75 -0
- package/schematics/add-queue/index.ts +74 -0
- package/schematics/add-queue/schema.d.ts +17 -0
- package/schematics/add-queue/schema.js +3 -0
- package/schematics/add-queue/schema.js.map +1 -0
- package/schematics/add-queue/schema.json +54 -0
- package/schematics/add-queue/schema.ts +32 -0
- package/schematics/add-reply-queue/index.d.ts +3 -0
- package/schematics/add-reply-queue/index.js +26 -0
- package/schematics/add-reply-queue/index.js.map +1 -0
- package/schematics/add-reply-queue/index.spec.ts +69 -0
- package/schematics/add-reply-queue/index.ts +33 -0
- package/schematics/add-reply-queue/schema.d.ts +6 -0
- package/schematics/add-reply-queue/schema.js +3 -0
- package/schematics/add-reply-queue/schema.js.map +1 -0
- package/schematics/add-reply-queue/schema.json +28 -0
- package/schematics/add-reply-queue/schema.ts +10 -0
- package/schematics/add-route/index.d.ts +3 -0
- package/schematics/add-route/index.js +57 -0
- package/schematics/add-route/index.js.map +1 -0
- package/schematics/add-route/index.spec.ts +75 -0
- package/schematics/add-route/index.ts +74 -0
- package/schematics/add-route/schema.d.ts +22 -0
- package/schematics/add-route/schema.js +3 -0
- package/schematics/add-route/schema.js.map +1 -0
- package/schematics/add-route/schema.json +74 -0
- package/schematics/add-route/schema.ts +43 -0
- package/schematics/add-topic/index.d.ts +3 -0
- package/schematics/add-topic/index.js +69 -0
- package/schematics/add-topic/index.js.map +1 -0
- package/schematics/add-topic/index.spec.ts +100 -0
- package/schematics/add-topic/index.ts +104 -0
- package/schematics/add-topic/schema.d.ts +18 -0
- package/schematics/add-topic/schema.js +3 -0
- package/schematics/add-topic/schema.js.map +1 -0
- package/schematics/add-topic/schema.json +63 -0
- package/schematics/add-topic/schema.ts +34 -0
- package/schematics/add-ws-event/index.d.ts +3 -0
- package/schematics/add-ws-event/index.js +53 -0
- package/schematics/add-ws-event/index.js.map +1 -0
- package/schematics/add-ws-event/index.spec.ts +85 -0
- package/schematics/add-ws-event/index.ts +72 -0
- package/schematics/add-ws-event/schema.d.ts +17 -0
- package/schematics/add-ws-event/schema.js +3 -0
- package/schematics/add-ws-event/schema.js.map +1 -0
- package/schematics/add-ws-event/schema.json +53 -0
- package/schematics/add-ws-event/schema.ts +33 -0
- package/schematics/collection.json +81 -1
- package/schematics/configure-broker/index.d.ts +3 -0
- package/schematics/configure-broker/index.js +41 -0
- package/schematics/configure-broker/index.js.map +1 -0
- package/schematics/configure-broker/index.spec.ts +62 -0
- package/schematics/configure-broker/index.ts +51 -0
- package/schematics/configure-broker/schema.d.ts +11 -0
- package/schematics/configure-broker/schema.js +3 -0
- package/schematics/configure-broker/schema.js.map +1 -0
- package/schematics/configure-broker/schema.json +47 -0
- package/schematics/configure-broker/schema.ts +20 -0
- package/schematics/enable-load-config/index.d.ts +3 -0
- package/schematics/enable-load-config/index.js +32 -0
- package/schematics/enable-load-config/index.js.map +1 -0
- package/schematics/enable-load-config/index.spec.ts +61 -0
- package/schematics/enable-load-config/index.ts +39 -0
- package/schematics/enable-load-config/schema.d.ts +8 -0
- package/schematics/enable-load-config/schema.js +3 -0
- package/schematics/enable-load-config/schema.js.map +1 -0
- package/schematics/enable-load-config/schema.json +36 -0
- package/schematics/enable-load-config/schema.ts +14 -0
- package/schematics/enable-retry/index.d.ts +3 -0
- package/schematics/enable-retry/index.js +51 -0
- package/schematics/enable-retry/index.js.map +1 -0
- package/schematics/enable-retry/index.spec.ts +73 -0
- package/schematics/enable-retry/index.ts +62 -0
- package/schematics/enable-retry/schema.d.ts +13 -0
- package/schematics/enable-retry/schema.js +3 -0
- package/schematics/enable-retry/schema.js.map +1 -0
- package/schematics/enable-retry/schema.json +64 -0
- package/schematics/enable-retry/schema.ts +24 -0
- package/schematics/enable-route-discovery/index.d.ts +3 -0
- package/schematics/enable-route-discovery/index.js +36 -0
- package/schematics/enable-route-discovery/index.js.map +1 -0
- package/schematics/enable-route-discovery/index.spec.ts +55 -0
- package/schematics/enable-route-discovery/index.ts +48 -0
- package/schematics/enable-route-discovery/schema.d.ts +9 -0
- package/schematics/enable-route-discovery/schema.js +3 -0
- package/schematics/enable-route-discovery/schema.js.map +1 -0
- package/schematics/enable-route-discovery/schema.json +44 -0
- package/schematics/enable-route-discovery/schema.ts +16 -0
- package/schematics/harden-gateway/index.d.ts +3 -0
- package/schematics/harden-gateway/index.js +93 -0
- package/schematics/harden-gateway/index.js.map +1 -0
- package/schematics/harden-gateway/index.spec.ts +105 -0
- package/schematics/harden-gateway/index.ts +108 -0
- package/schematics/harden-gateway/schema.d.ts +11 -0
- package/schematics/harden-gateway/schema.js +3 -0
- package/schematics/harden-gateway/schema.js.map +1 -0
- package/schematics/harden-gateway/schema.json +47 -0
- package/schematics/harden-gateway/schema.ts +20 -0
- package/schematics/nest-add/index.js +55 -832
- package/schematics/nest-add/index.js.map +1 -1
- package/schematics/nest-add/index.spec.ts +73 -0
- package/schematics/nest-add/index.ts +76 -917
- package/schematics/nest-add/init.schema.d.ts +1 -0
- package/schematics/nest-add/init.schema.ts +3 -0
- package/schematics/nest-add/schema.json +4 -43
- package/schematics/set-connection-name/index.d.ts +3 -0
- package/schematics/set-connection-name/index.js +34 -0
- package/schematics/set-connection-name/index.js.map +1 -0
- package/schematics/set-connection-name/index.spec.ts +48 -0
- package/schematics/set-connection-name/index.ts +42 -0
- package/schematics/set-connection-name/schema.d.ts +5 -0
- package/schematics/set-connection-name/schema.js +3 -0
- package/schematics/set-connection-name/schema.js.map +1 -0
- package/schematics/set-connection-name/schema.json +24 -0
- package/schematics/set-connection-name/schema.ts +8 -0
- package/schematics/utils/broker-yaml.util.d.ts +53 -0
- package/schematics/utils/broker-yaml.util.js +91 -0
- package/schematics/utils/broker-yaml.util.js.map +1 -0
- package/schematics/utils/broker-yaml.util.ts +172 -0
- package/schematics/utils/nest-wiring.util.d.ts +30 -0
- package/schematics/utils/nest-wiring.util.js +170 -0
- package/schematics/utils/nest-wiring.util.js.map +1 -0
- package/schematics/utils/nest-wiring.util.ts +211 -0
- package/schematics/utils/schematic-prompt.util.d.ts +7 -0
- package/schematics/utils/schematic-prompt.util.js +57 -0
- package/schematics/utils/schematic-prompt.util.js.map +1 -0
- package/schematics/utils/schematic-prompt.util.ts +82 -0
- package/schematics/utils/yaml-config.util.d.ts +22 -0
- package/schematics/utils/yaml-config.util.js +119 -0
- package/schematics/utils/yaml-config.util.js.map +1 -0
- package/schematics/utils/yaml-config.util.ts +167 -0
- /package/schematics/{nest-add → add-gateway}/files/acl/src/cache/in-memory-acl-store.ts +0 -0
- /package/schematics/{nest-add → add-gateway}/files/acl/src/modules/database/repository/acl.repository.ts +0 -0
- /package/schematics/{nest-add → add-gateway}/files/db-core/src/modules/database/repository/in-memory-collection.ts +0 -0
- /package/schematics/{nest-add → add-gateway}/files/gateway-admin/src/modules/database/repository/gateway.repository.ts +0 -0
- /package/schematics/{nest-add → add-gateway}/files/gateway-admin/src/modules/database/repository/route-sync.repository.ts +0 -0
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.findFileInTree = findFileInTree;
|
|
4
|
+
exports.findAppModule = findAppModule;
|
|
5
|
+
exports.findMainTs = findMainTs;
|
|
6
|
+
exports.ensureLibImport = ensureLibImport;
|
|
7
|
+
exports.ensureImportLine = ensureImportLine;
|
|
8
|
+
exports.insertIntoImportsArray = insertIntoImportsArray;
|
|
9
|
+
exports.wireAppModule = wireAppModule;
|
|
10
|
+
exports.coreLibSymbols = coreLibSymbols;
|
|
11
|
+
exports.coreImportLines = coreImportLines;
|
|
12
|
+
exports.configModuleEntry = configModuleEntry;
|
|
13
|
+
exports.brokerModuleEntry = brokerModuleEntry;
|
|
14
|
+
exports.createConfigLoader = createConfigLoader;
|
|
15
|
+
exports.configureMainForGateway = configureMainForGateway;
|
|
16
|
+
exports.addDeps = addDeps;
|
|
17
|
+
const APP_MODULE_CANDIDATES = ['/src/app.module.ts', '/app/app.module.ts', 'src/app.module.ts', 'app/app.module.ts'];
|
|
18
|
+
const MAIN_CANDIDATES = ['/src/main.ts', '/app/main.ts', 'src/main.ts', 'app/main.ts'];
|
|
19
|
+
function findFileInTree(tree, fileName) {
|
|
20
|
+
let found;
|
|
21
|
+
tree.visit((path) => {
|
|
22
|
+
if (!found && path.endsWith(`/${fileName}`))
|
|
23
|
+
found = path;
|
|
24
|
+
});
|
|
25
|
+
return found;
|
|
26
|
+
}
|
|
27
|
+
function findAppModule(tree) {
|
|
28
|
+
return APP_MODULE_CANDIDATES.find((p) => tree.exists(p)) || findFileInTree(tree, 'app.module.ts');
|
|
29
|
+
}
|
|
30
|
+
function findMainTs(tree) {
|
|
31
|
+
return MAIN_CANDIDATES.find((p) => tree.exists(p)) || findFileInTree(tree, 'main.ts');
|
|
32
|
+
}
|
|
33
|
+
function findLastImportEndIndex(source) {
|
|
34
|
+
const importRegex = /^import\s+.+from\s+['"][^'"]+['"];?\s*$/gm;
|
|
35
|
+
let lastEnd = 0;
|
|
36
|
+
let match;
|
|
37
|
+
while ((match = importRegex.exec(source)) !== null) {
|
|
38
|
+
lastEnd = match.index + match[0].length;
|
|
39
|
+
}
|
|
40
|
+
return lastEnd;
|
|
41
|
+
}
|
|
42
|
+
function ensureLibImport(source, symbols) {
|
|
43
|
+
const re = /import\s*\{([^}]*)\}\s*from\s*['"]@open-rlb\/nestjs-amqp['"];?/;
|
|
44
|
+
const m = re.exec(source);
|
|
45
|
+
if (m) {
|
|
46
|
+
const current = m[1]
|
|
47
|
+
.split(',')
|
|
48
|
+
.map((s) => s.trim())
|
|
49
|
+
.filter(Boolean);
|
|
50
|
+
const merged = [...new Set([...current, ...symbols])].sort();
|
|
51
|
+
return source.slice(0, m.index) + `import { ${merged.join(', ')} } from '@open-rlb/nestjs-amqp';` + source.slice(m.index + m[0].length);
|
|
52
|
+
}
|
|
53
|
+
const pos = findLastImportEndIndex(source);
|
|
54
|
+
const line = `\nimport { ${[...new Set(symbols)].sort().join(', ')} } from '@open-rlb/nestjs-amqp';`;
|
|
55
|
+
return source.slice(0, pos) + line + source.slice(pos);
|
|
56
|
+
}
|
|
57
|
+
function ensureImportLine(source, line, marker) {
|
|
58
|
+
if (source.includes(marker))
|
|
59
|
+
return source;
|
|
60
|
+
const pos = findLastImportEndIndex(source);
|
|
61
|
+
return source.slice(0, pos) + '\n' + line + source.slice(pos);
|
|
62
|
+
}
|
|
63
|
+
function insertIntoImportsArray(source, moduleEntry) {
|
|
64
|
+
const match = /imports\s*:\s*\[/.exec(source);
|
|
65
|
+
if (!match)
|
|
66
|
+
return source;
|
|
67
|
+
const openBracketPos = source.indexOf('[', match.index);
|
|
68
|
+
let depth = 0;
|
|
69
|
+
let closeBracketPos = -1;
|
|
70
|
+
for (let i = openBracketPos; i < source.length; i++) {
|
|
71
|
+
if (source[i] === '[')
|
|
72
|
+
depth++;
|
|
73
|
+
else if (source[i] === ']') {
|
|
74
|
+
depth--;
|
|
75
|
+
if (depth === 0) {
|
|
76
|
+
closeBracketPos = i;
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
if (closeBracketPos === -1)
|
|
82
|
+
return source;
|
|
83
|
+
const arrayContent = source.slice(openBracketPos + 1, closeBracketPos).trim();
|
|
84
|
+
const newArrayContent = arrayContent.length === 0 ? `\n ${moduleEntry},\n ` : `\n ${moduleEntry},\n ${arrayContent}\n `;
|
|
85
|
+
return source.slice(0, openBracketPos + 1) + newArrayContent + source.slice(closeBracketPos);
|
|
86
|
+
}
|
|
87
|
+
function wireAppModule(tree, opts) {
|
|
88
|
+
const modulePath = findAppModule(tree);
|
|
89
|
+
if (!modulePath)
|
|
90
|
+
return undefined;
|
|
91
|
+
let content = tree.read(modulePath).toString('utf-8');
|
|
92
|
+
content = ensureLibImport(content, opts.libSymbols);
|
|
93
|
+
for (const imp of opts.importLines || [])
|
|
94
|
+
content = ensureImportLine(content, imp.line, imp.marker);
|
|
95
|
+
const toAdd = opts.entries.filter((e) => !content.includes(e.sentinel));
|
|
96
|
+
for (let i = toAdd.length - 1; i >= 0; i--)
|
|
97
|
+
content = insertIntoImportsArray(content, toAdd[i].code);
|
|
98
|
+
tree.overwrite(modulePath, content);
|
|
99
|
+
return modulePath;
|
|
100
|
+
}
|
|
101
|
+
function coreLibSymbols() {
|
|
102
|
+
return ['AppConfig', 'BrokerModule', 'BrokerTopic', 'RabbitMQConfig'];
|
|
103
|
+
}
|
|
104
|
+
function coreImportLines() {
|
|
105
|
+
return [
|
|
106
|
+
{ line: `import { ConfigModule, ConfigService } from '@nestjs/config';`, marker: '@nestjs/config' },
|
|
107
|
+
{ line: `import yamlConfig from './config/config.loader';`, marker: './config/config.loader' },
|
|
108
|
+
];
|
|
109
|
+
}
|
|
110
|
+
function configModuleEntry() {
|
|
111
|
+
return { code: `ConfigModule.forRoot({ isGlobal: true, load: [yamlConfig] })`, sentinel: 'ConfigModule.forRoot' };
|
|
112
|
+
}
|
|
113
|
+
function brokerModuleEntry() {
|
|
114
|
+
return {
|
|
115
|
+
code: `BrokerModule.forRootAsync({
|
|
116
|
+
imports: [ConfigModule],
|
|
117
|
+
inject: [ConfigService],
|
|
118
|
+
useFactory: async (configService: ConfigService) => ({
|
|
119
|
+
options: configService.get<RabbitMQConfig>('broker')!,
|
|
120
|
+
topics: configService.get<BrokerTopic[]>('topics')!,
|
|
121
|
+
appOptions: configService.get<AppConfig>('app'),
|
|
122
|
+
})
|
|
123
|
+
})`,
|
|
124
|
+
sentinel: 'BrokerModule.forRootAsync',
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
function createConfigLoader(tree) {
|
|
128
|
+
const path = 'src/config/config.loader.ts';
|
|
129
|
+
if (tree.exists(path))
|
|
130
|
+
return;
|
|
131
|
+
tree.create(path, `import { readFileSync } from 'fs';
|
|
132
|
+
import * as yaml from 'js-yaml';
|
|
133
|
+
import { join } from 'path';
|
|
134
|
+
|
|
135
|
+
const YAML_CONFIG_FILENAME = 'config/config.yaml';
|
|
136
|
+
|
|
137
|
+
export default () =>
|
|
138
|
+
yaml.load(readFileSync(join(process.cwd(), YAML_CONFIG_FILENAME), 'utf8')) as Record<string, any>;
|
|
139
|
+
`);
|
|
140
|
+
}
|
|
141
|
+
function configureMainForGateway(tree) {
|
|
142
|
+
const mainPath = findMainTs(tree);
|
|
143
|
+
if (!mainPath)
|
|
144
|
+
return false;
|
|
145
|
+
let content = tree.read(mainPath).toString('utf-8');
|
|
146
|
+
if (content.includes('WsAdapter'))
|
|
147
|
+
return true;
|
|
148
|
+
content = ensureImportLine(content, `import { WsAdapter } from '@nestjs/platform-ws';`, '@nestjs/platform-ws');
|
|
149
|
+
const m = content.match(/const\s+(\w+)\s*=\s*await\s+NestFactory\.create[^(]*\(\s*([A-Za-z0-9_]+)\s*(,\s*\{[^}]*\})?\s*\)\s*;?/);
|
|
150
|
+
if (m) {
|
|
151
|
+
const appVar = m[1];
|
|
152
|
+
const moduleArg = m[2];
|
|
153
|
+
const replacement = `const ${appVar} = await NestFactory.create(${moduleArg}, { rawBody: true });\n ${appVar}.useWebSocketAdapter(new WsAdapter(${appVar}));\n ${appVar}.enableShutdownHooks();`;
|
|
154
|
+
content = content.replace(m[0], replacement);
|
|
155
|
+
}
|
|
156
|
+
tree.overwrite(mainPath, content);
|
|
157
|
+
return true;
|
|
158
|
+
}
|
|
159
|
+
function addDeps(tree, deps) {
|
|
160
|
+
if (!tree.exists('package.json'))
|
|
161
|
+
return;
|
|
162
|
+
const pkg = JSON.parse(tree.read('package.json').toString('utf-8'));
|
|
163
|
+
pkg.dependencies = pkg.dependencies || {};
|
|
164
|
+
for (const [name, version] of Object.entries(deps)) {
|
|
165
|
+
if (!pkg.dependencies[name])
|
|
166
|
+
pkg.dependencies[name] = version;
|
|
167
|
+
}
|
|
168
|
+
tree.overwrite('package.json', JSON.stringify(pkg, null, 2));
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=nest-wiring.util.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nest-wiring.util.js","sourceRoot":"","sources":["../../../libs/rlb-nestjs-amqp/src/schematics/utils/nest-wiring.util.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { Tree } from '@angular-devkit/schematics';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* TypeScript-source wiring helpers shared by the scaffolding schematics (add-gateway today). They
|
|
5
|
+
* edit app.module.ts / main.ts / package.json / the config loader idempotently via light source
|
|
6
|
+
* surgery — the same technique nest-add used, extracted here so a promote-to-gateway run produces a
|
|
7
|
+
* fully wired app, not just YAML. Every helper is a no-op when its target is already in place.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const APP_MODULE_CANDIDATES = ['/src/app.module.ts', '/app/app.module.ts', 'src/app.module.ts', 'app/app.module.ts'];
|
|
11
|
+
const MAIN_CANDIDATES = ['/src/main.ts', '/app/main.ts', 'src/main.ts', 'app/main.ts'];
|
|
12
|
+
|
|
13
|
+
export function findFileInTree(tree: Tree, fileName: string): string | undefined {
|
|
14
|
+
let found: string | undefined;
|
|
15
|
+
tree.visit((path) => {
|
|
16
|
+
if (!found && path.endsWith(`/${fileName}`)) found = path;
|
|
17
|
+
});
|
|
18
|
+
return found;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function findAppModule(tree: Tree): string | undefined {
|
|
22
|
+
return APP_MODULE_CANDIDATES.find((p) => tree.exists(p)) || findFileInTree(tree, 'app.module.ts');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function findMainTs(tree: Tree): string | undefined {
|
|
26
|
+
return MAIN_CANDIDATES.find((p) => tree.exists(p)) || findFileInTree(tree, 'main.ts');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function findLastImportEndIndex(source: string): number {
|
|
30
|
+
const importRegex = /^import\s+.+from\s+['"][^'"]+['"];?\s*$/gm;
|
|
31
|
+
let lastEnd = 0;
|
|
32
|
+
let match: RegExpExecArray | null;
|
|
33
|
+
while ((match = importRegex.exec(source)) !== null) {
|
|
34
|
+
lastEnd = match.index + match[0].length;
|
|
35
|
+
}
|
|
36
|
+
return lastEnd;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Ensure `symbols` are all imported from `@open-rlb/nestjs-amqp`: merge the missing ones into an
|
|
41
|
+
* existing lib import (kept sorted), or insert a fresh import after the last import when none exists.
|
|
42
|
+
*/
|
|
43
|
+
export function ensureLibImport(source: string, symbols: string[]): string {
|
|
44
|
+
const re = /import\s*\{([^}]*)\}\s*from\s*['"]@open-rlb\/nestjs-amqp['"];?/;
|
|
45
|
+
const m = re.exec(source);
|
|
46
|
+
if (m) {
|
|
47
|
+
const current = m[1]
|
|
48
|
+
.split(',')
|
|
49
|
+
.map((s) => s.trim())
|
|
50
|
+
.filter(Boolean);
|
|
51
|
+
const merged = [...new Set([...current, ...symbols])].sort();
|
|
52
|
+
return source.slice(0, m.index) + `import { ${merged.join(', ')} } from '@open-rlb/nestjs-amqp';` + source.slice(m.index + m[0].length);
|
|
53
|
+
}
|
|
54
|
+
const pos = findLastImportEndIndex(source);
|
|
55
|
+
const line = `\nimport { ${[...new Set(symbols)].sort().join(', ')} } from '@open-rlb/nestjs-amqp';`;
|
|
56
|
+
return source.slice(0, pos) + line + source.slice(pos);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** Ensure a standalone import line is present, keyed by a substring `marker` already-present check. */
|
|
60
|
+
export function ensureImportLine(source: string, line: string, marker: string): string {
|
|
61
|
+
if (source.includes(marker)) return source;
|
|
62
|
+
const pos = findLastImportEndIndex(source);
|
|
63
|
+
return source.slice(0, pos) + '\n' + line + source.slice(pos);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** Insert `moduleEntry` at the head of the first `imports: [...]` array of the @Module decorator. */
|
|
67
|
+
export function insertIntoImportsArray(source: string, moduleEntry: string): string {
|
|
68
|
+
const match = /imports\s*:\s*\[/.exec(source);
|
|
69
|
+
if (!match) return source;
|
|
70
|
+
const openBracketPos = source.indexOf('[', match.index);
|
|
71
|
+
|
|
72
|
+
let depth = 0;
|
|
73
|
+
let closeBracketPos = -1;
|
|
74
|
+
for (let i = openBracketPos; i < source.length; i++) {
|
|
75
|
+
if (source[i] === '[') depth++;
|
|
76
|
+
else if (source[i] === ']') {
|
|
77
|
+
depth--;
|
|
78
|
+
if (depth === 0) {
|
|
79
|
+
closeBracketPos = i;
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (closeBracketPos === -1) return source;
|
|
85
|
+
|
|
86
|
+
const arrayContent = source.slice(openBracketPos + 1, closeBracketPos).trim();
|
|
87
|
+
const newArrayContent =
|
|
88
|
+
arrayContent.length === 0 ? `\n ${moduleEntry},\n ` : `\n ${moduleEntry},\n ${arrayContent}\n `;
|
|
89
|
+
return source.slice(0, openBracketPos + 1) + newArrayContent + source.slice(closeBracketPos);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export interface WireEntry {
|
|
93
|
+
/** The literal module entry, e.g. `HttpModule` or `ProxyModule.forRootAsync({...})`. */
|
|
94
|
+
code: string;
|
|
95
|
+
/** Skip this entry when `source` already contains this substring (idempotency sentinel). */
|
|
96
|
+
sentinel: string;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export interface WireAppModuleOptions {
|
|
100
|
+
/** Symbols to import from `@open-rlb/nestjs-amqp`. */
|
|
101
|
+
libSymbols: string[];
|
|
102
|
+
/** Extra standalone import lines, each with a presence marker. */
|
|
103
|
+
importLines?: { line: string; marker: string }[];
|
|
104
|
+
/** @Module imports[] entries to add (each only if its sentinel is absent). */
|
|
105
|
+
entries: WireEntry[];
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Wire modules into the app's AppModule: ensure the lib + helper imports, then insert each module
|
|
110
|
+
* entry whose sentinel is missing. Entries are inserted in reverse so the final visual order matches
|
|
111
|
+
* the given array. Returns the module path when found, else undefined (caller logs the skip).
|
|
112
|
+
*/
|
|
113
|
+
export function wireAppModule(tree: Tree, opts: WireAppModuleOptions): string | undefined {
|
|
114
|
+
const modulePath = findAppModule(tree);
|
|
115
|
+
if (!modulePath) return undefined;
|
|
116
|
+
let content = tree.read(modulePath)!.toString('utf-8');
|
|
117
|
+
|
|
118
|
+
content = ensureLibImport(content, opts.libSymbols);
|
|
119
|
+
for (const imp of opts.importLines || []) content = ensureImportLine(content, imp.line, imp.marker);
|
|
120
|
+
|
|
121
|
+
const toAdd = opts.entries.filter((e) => !content.includes(e.sentinel));
|
|
122
|
+
for (let i = toAdd.length - 1; i >= 0; i--) content = insertIntoImportsArray(content, toAdd[i].code);
|
|
123
|
+
|
|
124
|
+
tree.overwrite(modulePath, content);
|
|
125
|
+
return modulePath;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// --- Core (BrokerModule) wiring shared by nest-add and add-gateway --------------------------------
|
|
129
|
+
|
|
130
|
+
/** Lib symbols every core (microservice) AppModule needs. */
|
|
131
|
+
export function coreLibSymbols(): string[] {
|
|
132
|
+
return ['AppConfig', 'BrokerModule', 'BrokerTopic', 'RabbitMQConfig'];
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/** The ConfigModule + config-loader import lines. */
|
|
136
|
+
export function coreImportLines(): { line: string; marker: string }[] {
|
|
137
|
+
return [
|
|
138
|
+
{ line: `import { ConfigModule, ConfigService } from '@nestjs/config';`, marker: '@nestjs/config' },
|
|
139
|
+
{ line: `import yamlConfig from './config/config.loader';`, marker: './config/config.loader' },
|
|
140
|
+
];
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/** `ConfigModule.forRoot({...})` entry (sentinel: 'ConfigModule.forRoot'). */
|
|
144
|
+
export function configModuleEntry(): WireEntry {
|
|
145
|
+
return { code: `ConfigModule.forRoot({ isGlobal: true, load: [yamlConfig] })`, sentinel: 'ConfigModule.forRoot' };
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/** `BrokerModule.forRootAsync({...})` entry (sentinel: 'BrokerModule.forRootAsync'). */
|
|
149
|
+
export function brokerModuleEntry(): WireEntry {
|
|
150
|
+
return {
|
|
151
|
+
code: `BrokerModule.forRootAsync({
|
|
152
|
+
imports: [ConfigModule],
|
|
153
|
+
inject: [ConfigService],
|
|
154
|
+
useFactory: async (configService: ConfigService) => ({
|
|
155
|
+
options: configService.get<RabbitMQConfig>('broker')!,
|
|
156
|
+
topics: configService.get<BrokerTopic[]>('topics')!,
|
|
157
|
+
appOptions: configService.get<AppConfig>('app'),
|
|
158
|
+
})
|
|
159
|
+
})`,
|
|
160
|
+
sentinel: 'BrokerModule.forRootAsync',
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/** Create src/config/config.loader.ts (js-yaml loader) when missing. */
|
|
165
|
+
export function createConfigLoader(tree: Tree): void {
|
|
166
|
+
const path = 'src/config/config.loader.ts';
|
|
167
|
+
if (tree.exists(path)) return;
|
|
168
|
+
tree.create(
|
|
169
|
+
path,
|
|
170
|
+
`import { readFileSync } from 'fs';
|
|
171
|
+
import * as yaml from 'js-yaml';
|
|
172
|
+
import { join } from 'path';
|
|
173
|
+
|
|
174
|
+
const YAML_CONFIG_FILENAME = 'config/config.yaml';
|
|
175
|
+
|
|
176
|
+
export default () =>
|
|
177
|
+
yaml.load(readFileSync(join(process.cwd(), YAML_CONFIG_FILENAME), 'utf8')) as Record<string, any>;
|
|
178
|
+
`,
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/** Enable rawBody + the WebSocket adapter + shutdown hooks in main.ts (idempotent). Returns false if unwired. */
|
|
183
|
+
export function configureMainForGateway(tree: Tree): boolean {
|
|
184
|
+
const mainPath = findMainTs(tree);
|
|
185
|
+
if (!mainPath) return false;
|
|
186
|
+
let content = tree.read(mainPath)!.toString('utf-8');
|
|
187
|
+
if (content.includes('WsAdapter')) return true;
|
|
188
|
+
|
|
189
|
+
content = ensureImportLine(content, `import { WsAdapter } from '@nestjs/platform-ws';`, '@nestjs/platform-ws');
|
|
190
|
+
|
|
191
|
+
const m = content.match(/const\s+(\w+)\s*=\s*await\s+NestFactory\.create[^(]*\(\s*([A-Za-z0-9_]+)\s*(,\s*\{[^}]*\})?\s*\)\s*;?/);
|
|
192
|
+
if (m) {
|
|
193
|
+
const appVar = m[1];
|
|
194
|
+
const moduleArg = m[2];
|
|
195
|
+
const replacement = `const ${appVar} = await NestFactory.create(${moduleArg}, { rawBody: true });\n ${appVar}.useWebSocketAdapter(new WsAdapter(${appVar}));\n ${appVar}.enableShutdownHooks();`;
|
|
196
|
+
content = content.replace(m[0], replacement);
|
|
197
|
+
}
|
|
198
|
+
tree.overwrite(mainPath, content);
|
|
199
|
+
return true;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/** Add runtime dependencies to package.json (only when absent). No-op without a package.json. */
|
|
203
|
+
export function addDeps(tree: Tree, deps: Record<string, string>): void {
|
|
204
|
+
if (!tree.exists('package.json')) return;
|
|
205
|
+
const pkg = JSON.parse(tree.read('package.json')!.toString('utf-8'));
|
|
206
|
+
pkg.dependencies = pkg.dependencies || {};
|
|
207
|
+
for (const [name, version] of Object.entries(deps)) {
|
|
208
|
+
if (!pkg.dependencies[name]) pkg.dependencies[name] = version;
|
|
209
|
+
}
|
|
210
|
+
tree.overwrite('package.json', JSON.stringify(pkg, null, 2));
|
|
211
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { SchematicContext } from '@angular-devkit/schematics';
|
|
2
|
+
export declare function loadPrompts(context: SchematicContext, flagsProvided: boolean): any | undefined;
|
|
3
|
+
export declare function askText(prompts: any | undefined, message: string, fallback: string): Promise<string>;
|
|
4
|
+
export declare function askConfirm(prompts: any | undefined, message: string, fallback: boolean): Promise<boolean>;
|
|
5
|
+
export declare function askSelect<T extends string>(prompts: any | undefined, message: string, choices: readonly T[], fallback: T): Promise<T>;
|
|
6
|
+
export declare function askNumber(prompts: any | undefined, message: string, fallback: number | undefined): Promise<number | undefined>;
|
|
7
|
+
export declare function logOutcome(context: SchematicContext, what: string, outcome: 'created' | 'updated' | 'unchanged'): void;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.loadPrompts = loadPrompts;
|
|
4
|
+
exports.askText = askText;
|
|
5
|
+
exports.askConfirm = askConfirm;
|
|
6
|
+
exports.askSelect = askSelect;
|
|
7
|
+
exports.askNumber = askNumber;
|
|
8
|
+
exports.logOutcome = logOutcome;
|
|
9
|
+
function loadPrompts(context, flagsProvided) {
|
|
10
|
+
const isTty = !!process.stdout && !!process.stdout.isTTY;
|
|
11
|
+
const canPrompt = isTty && !process.env.CI && !flagsProvided;
|
|
12
|
+
if (!canPrompt)
|
|
13
|
+
return undefined;
|
|
14
|
+
try {
|
|
15
|
+
return require('@inquirer/prompts');
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
context.logger.warn('[rlb-amqp] @inquirer/prompts not found; falling back to flags/defaults.');
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
async function askText(prompts, message, fallback) {
|
|
23
|
+
if (!prompts)
|
|
24
|
+
return fallback;
|
|
25
|
+
return (await prompts.input({ message, default: fallback })) || fallback;
|
|
26
|
+
}
|
|
27
|
+
async function askConfirm(prompts, message, fallback) {
|
|
28
|
+
if (!prompts)
|
|
29
|
+
return fallback;
|
|
30
|
+
return prompts.confirm({ message, default: fallback });
|
|
31
|
+
}
|
|
32
|
+
async function askSelect(prompts, message, choices, fallback) {
|
|
33
|
+
if (!prompts)
|
|
34
|
+
return fallback;
|
|
35
|
+
return prompts.select({
|
|
36
|
+
message,
|
|
37
|
+
default: fallback,
|
|
38
|
+
choices: choices.map((c) => ({ name: c, value: c })),
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
async function askNumber(prompts, message, fallback) {
|
|
42
|
+
if (!prompts)
|
|
43
|
+
return fallback;
|
|
44
|
+
const raw = await prompts.input({
|
|
45
|
+
message,
|
|
46
|
+
default: fallback === undefined ? '' : String(fallback),
|
|
47
|
+
});
|
|
48
|
+
if (!raw?.trim())
|
|
49
|
+
return fallback;
|
|
50
|
+
const n = Number(raw);
|
|
51
|
+
return Number.isFinite(n) ? n : fallback;
|
|
52
|
+
}
|
|
53
|
+
function logOutcome(context, what, outcome) {
|
|
54
|
+
const verb = outcome === 'created' ? 'created' : outcome === 'updated' ? 'updated' : 'already present';
|
|
55
|
+
context.logger.info(`[rlb-amqp] ${what}: ${verb}.`);
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=schematic-prompt.util.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schematic-prompt.util.js","sourceRoot":"","sources":["../../../libs/rlb-nestjs-amqp/src/schematics/utils/schematic-prompt.util.ts"],"names":[],"mappings":";;AASA,kCAWC;AAGD,0BAOC;AAGD,gCAOC;AAGD,8BAYC;AAGD,8BAaC;AAGD,gCAOC;AAxED,SAAgB,WAAW,CAAC,OAAyB,EAAE,aAAsB;IAC3E,MAAM,KAAK,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,IAAI,CAAC,CAAE,OAAO,CAAC,MAAyC,CAAC,KAAK,CAAC;IAC7F,MAAM,SAAS,GAAG,KAAK,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,aAAa,CAAC;IAC7D,IAAI,CAAC,SAAS;QAAE,OAAO,SAAS,CAAC;IACjC,IAAI,CAAC;QAEH,OAAO,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,yEAAyE,CAAC,CAAC;QAC/F,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAGM,KAAK,UAAU,OAAO,CAC3B,OAAwB,EACxB,OAAe,EACf,QAAgB;IAEhB,IAAI,CAAC,OAAO;QAAE,OAAO,QAAQ,CAAC;IAC9B,OAAO,CAAC,MAAM,OAAO,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC,IAAI,QAAQ,CAAC;AAC3E,CAAC;AAGM,KAAK,UAAU,UAAU,CAC9B,OAAwB,EACxB,OAAe,EACf,QAAiB;IAEjB,IAAI,CAAC,OAAO;QAAE,OAAO,QAAQ,CAAC;IAC9B,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC;AACzD,CAAC;AAGM,KAAK,UAAU,SAAS,CAC7B,OAAwB,EACxB,OAAe,EACf,OAAqB,EACrB,QAAW;IAEX,IAAI,CAAC,OAAO;QAAE,OAAO,QAAQ,CAAC;IAC9B,OAAO,OAAO,CAAC,MAAM,CAAC;QACpB,OAAO;QACP,OAAO,EAAE,QAAQ;QACjB,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;KACrD,CAAC,CAAC;AACL,CAAC;AAGM,KAAK,UAAU,SAAS,CAC7B,OAAwB,EACxB,OAAe,EACf,QAA4B;IAE5B,IAAI,CAAC,OAAO;QAAE,OAAO,QAAQ,CAAC;IAC9B,MAAM,GAAG,GAAW,MAAM,OAAO,CAAC,KAAK,CAAC;QACtC,OAAO;QACP,OAAO,EAAE,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC;KACxD,CAAC,CAAC;IACH,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE;QAAE,OAAO,QAAQ,CAAC;IAClC,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IACtB,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;AAC3C,CAAC;AAGD,SAAgB,UAAU,CACxB,OAAyB,EACzB,IAAY,EACZ,OAA4C;IAE5C,MAAM,IAAI,GAAG,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,iBAAiB,CAAC;IACvG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,IAAI,KAAK,IAAI,GAAG,CAAC,CAAC;AACtD,CAAC"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { SchematicContext } from '@angular-devkit/schematics';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Shared interactive-prompt plumbing for the YAML schematics, mirroring nest-add's behaviour:
|
|
5
|
+
* prompt only when attached to a TTY, not in CI, and no flags were provided; otherwise fall back
|
|
6
|
+
* to the flags/defaults so the schematics stay CI-safe and scriptable.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/** Returns the `@inquirer/prompts` module when interactive, or `undefined` to signal "use defaults". */
|
|
10
|
+
export function loadPrompts(context: SchematicContext, flagsProvided: boolean): any | undefined {
|
|
11
|
+
const isTty = !!process.stdout && !!(process.stdout as unknown as { isTTY?: boolean }).isTTY;
|
|
12
|
+
const canPrompt = isTty && !process.env.CI && !flagsProvided;
|
|
13
|
+
if (!canPrompt) return undefined;
|
|
14
|
+
try {
|
|
15
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
16
|
+
return require('@inquirer/prompts');
|
|
17
|
+
} catch {
|
|
18
|
+
context.logger.warn('[rlb-amqp] @inquirer/prompts not found; falling back to flags/defaults.');
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** Ask for a string, or return `fallback` when non-interactive. */
|
|
24
|
+
export async function askText(
|
|
25
|
+
prompts: any | undefined,
|
|
26
|
+
message: string,
|
|
27
|
+
fallback: string,
|
|
28
|
+
): Promise<string> {
|
|
29
|
+
if (!prompts) return fallback;
|
|
30
|
+
return (await prompts.input({ message, default: fallback })) || fallback;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** Ask yes/no, or return `fallback` when non-interactive. */
|
|
34
|
+
export async function askConfirm(
|
|
35
|
+
prompts: any | undefined,
|
|
36
|
+
message: string,
|
|
37
|
+
fallback: boolean,
|
|
38
|
+
): Promise<boolean> {
|
|
39
|
+
if (!prompts) return fallback;
|
|
40
|
+
return prompts.confirm({ message, default: fallback });
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** Ask to pick one of `choices`, or return `fallback` when non-interactive. */
|
|
44
|
+
export async function askSelect<T extends string>(
|
|
45
|
+
prompts: any | undefined,
|
|
46
|
+
message: string,
|
|
47
|
+
choices: readonly T[],
|
|
48
|
+
fallback: T,
|
|
49
|
+
): Promise<T> {
|
|
50
|
+
if (!prompts) return fallback;
|
|
51
|
+
return prompts.select({
|
|
52
|
+
message,
|
|
53
|
+
default: fallback,
|
|
54
|
+
choices: choices.map((c) => ({ name: c, value: c })),
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** Ask for a positive integer, or return `fallback` when non-interactive. Empty input → fallback. */
|
|
59
|
+
export async function askNumber(
|
|
60
|
+
prompts: any | undefined,
|
|
61
|
+
message: string,
|
|
62
|
+
fallback: number | undefined,
|
|
63
|
+
): Promise<number | undefined> {
|
|
64
|
+
if (!prompts) return fallback;
|
|
65
|
+
const raw: string = await prompts.input({
|
|
66
|
+
message,
|
|
67
|
+
default: fallback === undefined ? '' : String(fallback),
|
|
68
|
+
});
|
|
69
|
+
if (!raw?.trim()) return fallback;
|
|
70
|
+
const n = Number(raw);
|
|
71
|
+
return Number.isFinite(n) ? n : fallback;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** Log a `created/updated/unchanged` outcome consistently across schematics. */
|
|
75
|
+
export function logOutcome(
|
|
76
|
+
context: SchematicContext,
|
|
77
|
+
what: string,
|
|
78
|
+
outcome: 'created' | 'updated' | 'unchanged',
|
|
79
|
+
): void {
|
|
80
|
+
const verb = outcome === 'created' ? 'created' : outcome === 'updated' ? 'updated' : 'already present';
|
|
81
|
+
context.logger.info(`[rlb-amqp] ${what}: ${verb}.`);
|
|
82
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Tree } from '@angular-devkit/schematics';
|
|
2
|
+
import { Document, YAMLMap, YAMLSeq } from 'yaml';
|
|
3
|
+
export declare const DEFAULT_CONFIG_PATH = "config/config.yaml";
|
|
4
|
+
export type UpsertOutcome = 'created' | 'updated' | 'unchanged';
|
|
5
|
+
export declare function findConfigYaml(tree: Tree, preferred?: string): string;
|
|
6
|
+
export declare function readConfigDoc(tree: Tree, path: string): {
|
|
7
|
+
doc: Document;
|
|
8
|
+
existed: boolean;
|
|
9
|
+
};
|
|
10
|
+
export declare function writeConfigDoc(tree: Tree, path: string, doc: Document): void;
|
|
11
|
+
export declare function ensureSeqAt(doc: Document, path: (string | number)[]): YAMLSeq;
|
|
12
|
+
export declare function ensureMapAt(doc: Document, path: (string | number)[]): YAMLMap;
|
|
13
|
+
export declare function findSeqItemByKey(doc: Document, path: (string | number)[], keyField: string, key: string): YAMLMap | undefined;
|
|
14
|
+
export declare function seqItemExists(doc: Document, path: (string | number)[], keyField: string, key: string): boolean;
|
|
15
|
+
export interface UpsertOptions {
|
|
16
|
+
overwrite?: boolean;
|
|
17
|
+
commentBefore?: string;
|
|
18
|
+
}
|
|
19
|
+
export declare function upsertSeqItemByKey(doc: Document, path: (string | number)[], keyField: string, item: Record<string, unknown>, opts?: UpsertOptions): UpsertOutcome;
|
|
20
|
+
export declare function setIn(doc: Document, path: (string | number)[], value: unknown): UpsertOutcome;
|
|
21
|
+
export declare function deleteSeqItemByKey(doc: Document, path: (string | number)[], keyField: string, key: string): boolean;
|
|
22
|
+
export declare function getScalar(doc: Document, path: (string | number)[]): unknown;
|