@open-rlb/nestjs-amqp 2.1.1 → 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
|
@@ -4,12 +4,6 @@
|
|
|
4
4
|
"title": "Init Schema",
|
|
5
5
|
"type": "object",
|
|
6
6
|
"properties": {
|
|
7
|
-
"path": {
|
|
8
|
-
"type": "string",
|
|
9
|
-
"format": "path",
|
|
10
|
-
"description": "The path to create the init.",
|
|
11
|
-
"visible": false
|
|
12
|
-
},
|
|
13
7
|
"project": {
|
|
14
8
|
"type": "string",
|
|
15
9
|
"description": "The name of the project.",
|
|
@@ -17,46 +11,13 @@
|
|
|
17
11
|
"$source": "projectName"
|
|
18
12
|
}
|
|
19
13
|
},
|
|
20
|
-
"
|
|
14
|
+
"skills": {
|
|
21
15
|
"type": "boolean",
|
|
22
|
-
"description": "
|
|
23
|
-
},
|
|
24
|
-
"features": {
|
|
25
|
-
"type": "array",
|
|
26
|
-
"items": { "type": "string" },
|
|
27
|
-
"description": "Features to include. Gateway (gatewayConfig=true): acl, gateway-admin, route-reception. Microservice (gatewayConfig=false): auto-config-publish. Prompted interactively when omitted."
|
|
28
|
-
},
|
|
29
|
-
"exchange": {
|
|
30
|
-
"type": "string",
|
|
31
|
-
"description": "Main AMQP exchange backing the ACL / gateway-admin queues. Default: rlb."
|
|
32
|
-
},
|
|
33
|
-
"aclQueue": {
|
|
34
|
-
"type": "string",
|
|
35
|
-
"description": "Queue backing the (fixed) rlb-acl topic. Default: rlb-acl."
|
|
36
|
-
},
|
|
37
|
-
"adminQueue": {
|
|
38
|
-
"type": "string",
|
|
39
|
-
"description": "Queue backing the (fixed) rlb-gateway-admin topic. Default: rlb-gateway-admin."
|
|
16
|
+
"description": "Copy the Claude skills / project docs into .claude/skills. Prompted when omitted; defaults to true."
|
|
40
17
|
},
|
|
41
|
-
"
|
|
18
|
+
"config": {
|
|
42
19
|
"type": "string",
|
|
43
|
-
"description": "
|
|
44
|
-
},
|
|
45
|
-
"routeExchange": {
|
|
46
|
-
"type": "string",
|
|
47
|
-
"description": "Route auto-discovery fanout exchange (must match between publisher and gateway). Default: rlb-route-discovery."
|
|
48
|
-
},
|
|
49
|
-
"routeQueue": {
|
|
50
|
-
"type": "string",
|
|
51
|
-
"description": "Route-sync durable queue (gateway consumer side). Default: rlb-route-sync."
|
|
52
|
-
},
|
|
53
|
-
"serviceName": {
|
|
54
|
-
"type": "string",
|
|
55
|
-
"description": "Service name used for route auto-publish (route ownership + AMQP connection_name). Default: the project name."
|
|
56
|
-
},
|
|
57
|
-
"skills": {
|
|
58
|
-
"type": "boolean",
|
|
59
|
-
"description": "Copy the Claude skill files into .claude/skills. Prompted when omitted; defaults to true."
|
|
20
|
+
"description": "Path to config.yaml (default: auto-detected, typically config/config.yaml)."
|
|
60
21
|
}
|
|
61
22
|
}
|
|
62
23
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.main = main;
|
|
4
|
+
const schematic_prompt_util_1 = require("../utils/schematic-prompt.util");
|
|
5
|
+
const yaml_config_util_1 = require("../utils/yaml-config.util");
|
|
6
|
+
const CONNECTION_NAME_PATH = [
|
|
7
|
+
'broker',
|
|
8
|
+
'connectionManagerOptions',
|
|
9
|
+
'connectionOptions',
|
|
10
|
+
'clientProperties',
|
|
11
|
+
'connection_name',
|
|
12
|
+
];
|
|
13
|
+
function main(options) {
|
|
14
|
+
return async (tree, context) => {
|
|
15
|
+
const flagsProvided = options.name !== undefined;
|
|
16
|
+
const prompts = (0, schematic_prompt_util_1.loadPrompts)(context, flagsProvided);
|
|
17
|
+
const raw = options.name || (await (0, schematic_prompt_util_1.askText)(prompts, 'Logical connection name?', ''));
|
|
18
|
+
const name = raw.trim();
|
|
19
|
+
if (!name) {
|
|
20
|
+
context.logger.error('[rlb-amqp] set-connection-name: a name is required.');
|
|
21
|
+
return tree;
|
|
22
|
+
}
|
|
23
|
+
const configPath = (0, yaml_config_util_1.findConfigYaml)(tree, options.config);
|
|
24
|
+
const { doc, existed } = (0, yaml_config_util_1.readConfigDoc)(tree, configPath);
|
|
25
|
+
if (!existed)
|
|
26
|
+
context.logger.info(`[rlb-amqp] ${configPath} not found — creating it.`);
|
|
27
|
+
const outcome = (0, yaml_config_util_1.setIn)(doc, CONNECTION_NAME_PATH, name);
|
|
28
|
+
(0, schematic_prompt_util_1.logOutcome)(context, `connection_name '${name}'`, outcome);
|
|
29
|
+
context.logger.info('[rlb-amqp] logical name; the library appends -hostname-pid per instance.');
|
|
30
|
+
(0, yaml_config_util_1.writeConfigDoc)(tree, configPath, doc);
|
|
31
|
+
return tree;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../libs/rlb-nestjs-amqp/src/schematics/set-connection-name/index.ts"],"names":[],"mappings":";;AAkBA,oBAuBC;AAxCD,0EAAkF;AAClF,gEAAiG;AAGjG,MAAM,oBAAoB,GAAG;IAC3B,QAAQ;IACR,0BAA0B;IAC1B,mBAAmB;IACnB,kBAAkB;IAClB,iBAAiB;CAClB,CAAC;AAOF,SAAgB,IAAI,CAAC,OAAiC;IACpD,OAAO,KAAK,EAAE,IAAU,EAAE,OAAyB,EAAE,EAAE;QACrD,MAAM,aAAa,GAAG,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC;QACjD,MAAM,OAAO,GAAG,IAAA,mCAAW,EAAC,OAAO,EAAE,aAAa,CAAC,CAAC;QAEpD,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,IAAI,CAAC,MAAM,IAAA,+BAAO,EAAC,OAAO,EAAE,0BAA0B,EAAE,EAAE,CAAC,CAAC,CAAC;QACrF,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;QACxB,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qDAAqD,CAAC,CAAC;YAC5E,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,UAAU,GAAG,IAAA,iCAAc,EAAC,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QACxD,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,IAAA,gCAAa,EAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QACzD,IAAI,CAAC,OAAO;YAAE,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,UAAU,2BAA2B,CAAC,CAAC;QAEvF,MAAM,OAAO,GAAG,IAAA,wBAAK,EAAC,GAAG,EAAE,oBAAoB,EAAE,IAAI,CAAC,CAAC;QACvD,IAAA,kCAAU,EAAC,OAAO,EAAE,oBAAoB,IAAI,GAAG,EAAE,OAAO,CAAC,CAAC;QAC1D,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,0EAA0E,CAAC,CAAC;QAEhG,IAAA,iCAAc,EAAC,IAAI,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC;QACtC,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Rule, SchematicContext, Tree } from '@angular-devkit/schematics';
|
|
2
|
+
import { parseDocument } from 'yaml';
|
|
3
|
+
import { main } from './index';
|
|
4
|
+
import { SetConnectionNameOptions } from './schema';
|
|
5
|
+
|
|
6
|
+
/** Invoke the factory Rule directly (SchematicTestRunner eagerly loads ESM `ora`). */
|
|
7
|
+
const ctx = { logger: { info() {}, warn() {}, error() {} } } as unknown as SchematicContext;
|
|
8
|
+
|
|
9
|
+
async function run(options: SetConnectionNameOptions, tree: Tree): Promise<Tree> {
|
|
10
|
+
const rule = main(options) as Rule;
|
|
11
|
+
const result = await (rule as (t: Tree, c: SchematicContext) => Promise<Tree>)(tree, ctx);
|
|
12
|
+
return result || tree;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function read(tree: Tree, path = 'config/config.yaml'): string {
|
|
16
|
+
return tree.read(path)!.toString('utf-8');
|
|
17
|
+
}
|
|
18
|
+
function doc(tree: Tree) {
|
|
19
|
+
return parseDocument(read(tree));
|
|
20
|
+
}
|
|
21
|
+
const PATH = ['broker', 'connectionManagerOptions', 'connectionOptions', 'clientProperties', 'connection_name'];
|
|
22
|
+
|
|
23
|
+
function seedConfig(): Tree {
|
|
24
|
+
const tree = Tree.empty();
|
|
25
|
+
tree.create('config/config.yaml', ['# my config', 'broker:', ' uri: amqp://localhost', 'topics: []', ''].join('\n'));
|
|
26
|
+
return tree;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
describe('set-connection-name schematic', () => {
|
|
30
|
+
it('sets the nested connection_name, trimming but not normalizing', async () => {
|
|
31
|
+
const tree = await run({ name: ' My Service ' }, seedConfig());
|
|
32
|
+
expect(String(doc(tree).getIn(PATH))).toBe('My Service');
|
|
33
|
+
expect(read(tree)).toContain('# my config');
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('is idempotent: re-running with the same value leaves the file unchanged', async () => {
|
|
37
|
+
let tree = await run({ name: 'my-service' }, seedConfig());
|
|
38
|
+
const first = read(tree);
|
|
39
|
+
tree = await run({ name: 'my-service' }, tree);
|
|
40
|
+
expect(read(tree)).toBe(first);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('creates the full nested path when missing', async () => {
|
|
44
|
+
const tree = await run({ name: 'gateway' }, Tree.empty());
|
|
45
|
+
expect(tree.exists('config/config.yaml')).toBe(true);
|
|
46
|
+
expect(String(doc(tree).getIn(PATH))).toBe('gateway');
|
|
47
|
+
});
|
|
48
|
+
});
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Rule, SchematicContext, Tree } from '@angular-devkit/schematics';
|
|
2
|
+
import { askText, loadPrompts, logOutcome } from '../utils/schematic-prompt.util';
|
|
3
|
+
import { findConfigYaml, readConfigDoc, setIn, writeConfigDoc } from '../utils/yaml-config.util';
|
|
4
|
+
import { SetConnectionNameOptions } from './schema';
|
|
5
|
+
|
|
6
|
+
const CONNECTION_NAME_PATH = [
|
|
7
|
+
'broker',
|
|
8
|
+
'connectionManagerOptions',
|
|
9
|
+
'connectionOptions',
|
|
10
|
+
'clientProperties',
|
|
11
|
+
'connection_name',
|
|
12
|
+
];
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* `set-connection-name` — set the LOGICAL connection_name. In 2.1.x the library auto-appends
|
|
16
|
+
* `-<hostname>-<pid>` per instance, so replicas can share one config while still showing up
|
|
17
|
+
* distinctly in the broker. The name is trimmed but intentionally NOT kebab-normalized.
|
|
18
|
+
*/
|
|
19
|
+
export function main(options: SetConnectionNameOptions): Rule {
|
|
20
|
+
return async (tree: Tree, context: SchematicContext) => {
|
|
21
|
+
const flagsProvided = options.name !== undefined;
|
|
22
|
+
const prompts = loadPrompts(context, flagsProvided);
|
|
23
|
+
|
|
24
|
+
const raw = options.name || (await askText(prompts, 'Logical connection name?', ''));
|
|
25
|
+
const name = raw.trim();
|
|
26
|
+
if (!name) {
|
|
27
|
+
context.logger.error('[rlb-amqp] set-connection-name: a name is required.');
|
|
28
|
+
return tree;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const configPath = findConfigYaml(tree, options.config);
|
|
32
|
+
const { doc, existed } = readConfigDoc(tree, configPath);
|
|
33
|
+
if (!existed) context.logger.info(`[rlb-amqp] ${configPath} not found — creating it.`);
|
|
34
|
+
|
|
35
|
+
const outcome = setIn(doc, CONNECTION_NAME_PATH, name);
|
|
36
|
+
logOutcome(context, `connection_name '${name}'`, outcome);
|
|
37
|
+
context.logger.info('[rlb-amqp] logical name; the library appends -hostname-pid per instance.');
|
|
38
|
+
|
|
39
|
+
writeConfigDoc(tree, configPath, doc);
|
|
40
|
+
return tree;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../libs/rlb-nestjs-amqp/src/schematics/set-connection-name/schema.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/schema",
|
|
3
|
+
"$id": "SchematicsRlbAmqpSetConnectionName",
|
|
4
|
+
"title": "Set the logical AMQP connection_name in config.yaml",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"properties": {
|
|
7
|
+
"name": {
|
|
8
|
+
"type": "string",
|
|
9
|
+
"description": "The logical connection name (trimmed; the library appends -hostname-pid per instance).",
|
|
10
|
+
"x-prompt": "Logical connection name?",
|
|
11
|
+
"$default": { "$source": "argv", "index": 0 }
|
|
12
|
+
},
|
|
13
|
+
"overwrite": {
|
|
14
|
+
"type": "boolean",
|
|
15
|
+
"default": false,
|
|
16
|
+
"description": "Update the value if it already exists."
|
|
17
|
+
},
|
|
18
|
+
"config": {
|
|
19
|
+
"type": "string",
|
|
20
|
+
"description": "Path to config.yaml (default: auto-detected)."
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"required": []
|
|
24
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface SetConnectionNameOptions {
|
|
2
|
+
/** The LOGICAL connection name. Trimmed but NOT kebab-normalized. Prompted when omitted. */
|
|
3
|
+
name?: string;
|
|
4
|
+
/** Update the value when it already exists (default: leave it untouched). */
|
|
5
|
+
overwrite?: boolean;
|
|
6
|
+
/** Path to config.yaml (default: auto-detected, typically config/config.yaml). */
|
|
7
|
+
config?: string;
|
|
8
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { Document } from 'yaml';
|
|
2
|
+
import { UpsertOptions, UpsertOutcome } from './yaml-config.util';
|
|
3
|
+
export type ExchangeType = 'direct' | 'topic' | 'fanout' | 'headers';
|
|
4
|
+
export type TopicMode = 'rpc' | 'handle' | 'broadcast' | 'event';
|
|
5
|
+
export declare function exchangeExists(doc: Document, name: string): boolean;
|
|
6
|
+
export declare function queueExists(doc: Document, name: string): boolean;
|
|
7
|
+
export declare function topicExists(doc: Document, name: string): boolean;
|
|
8
|
+
export declare function getExchangeType(doc: Document, name: string): ExchangeType | undefined;
|
|
9
|
+
export interface ExchangeSpec {
|
|
10
|
+
name: string;
|
|
11
|
+
type?: ExchangeType;
|
|
12
|
+
createExchangeIfNotExists?: boolean;
|
|
13
|
+
durable?: boolean;
|
|
14
|
+
autoDelete?: boolean;
|
|
15
|
+
internal?: boolean;
|
|
16
|
+
}
|
|
17
|
+
export declare function ensureExchange(doc: Document, spec: ExchangeSpec, opts?: UpsertOptions): UpsertOutcome;
|
|
18
|
+
export interface QueueSpec {
|
|
19
|
+
name: string;
|
|
20
|
+
exchange: string;
|
|
21
|
+
routingKey?: string | string[];
|
|
22
|
+
createQueueIfNotExists?: boolean;
|
|
23
|
+
durable?: boolean;
|
|
24
|
+
exclusive?: boolean;
|
|
25
|
+
autoDelete?: boolean;
|
|
26
|
+
messageTtl?: number;
|
|
27
|
+
maxLength?: number;
|
|
28
|
+
expires?: number;
|
|
29
|
+
}
|
|
30
|
+
export declare function ensureQueue(doc: Document, spec: QueueSpec, opts?: UpsertOptions): UpsertOutcome;
|
|
31
|
+
export interface RetrySpec {
|
|
32
|
+
maxAttempts?: number;
|
|
33
|
+
delayMs?: number;
|
|
34
|
+
onExhausted?: 'dead-letter' | 'drop';
|
|
35
|
+
deadLetter?: {
|
|
36
|
+
exchange: string;
|
|
37
|
+
routingKey?: string;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
export interface TopicSpec {
|
|
41
|
+
name: string;
|
|
42
|
+
mode: TopicMode;
|
|
43
|
+
queue?: string;
|
|
44
|
+
exchange?: string;
|
|
45
|
+
routingKey?: string | string[];
|
|
46
|
+
errorBehavior?: 'ack' | 'nack' | 'requeue';
|
|
47
|
+
retry?: RetrySpec;
|
|
48
|
+
mandatory?: boolean;
|
|
49
|
+
persistent?: boolean;
|
|
50
|
+
toObservable?: boolean;
|
|
51
|
+
}
|
|
52
|
+
export declare function ensureTopic(doc: Document, spec: TopicSpec, opts?: UpsertOptions): UpsertOutcome;
|
|
53
|
+
export declare function routingKeyRequired(doc: Document, exchangeName: string): boolean;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.exchangeExists = exchangeExists;
|
|
4
|
+
exports.queueExists = queueExists;
|
|
5
|
+
exports.topicExists = topicExists;
|
|
6
|
+
exports.getExchangeType = getExchangeType;
|
|
7
|
+
exports.ensureExchange = ensureExchange;
|
|
8
|
+
exports.ensureQueue = ensureQueue;
|
|
9
|
+
exports.ensureTopic = ensureTopic;
|
|
10
|
+
exports.routingKeyRequired = routingKeyRequired;
|
|
11
|
+
const yaml_config_util_1 = require("./yaml-config.util");
|
|
12
|
+
const EXCHANGES = ['broker', 'exchanges'];
|
|
13
|
+
const QUEUES = ['broker', 'queues'];
|
|
14
|
+
const TOPICS = ['topics'];
|
|
15
|
+
function exchangeExists(doc, name) {
|
|
16
|
+
return (0, yaml_config_util_1.seqItemExists)(doc, EXCHANGES, 'name', name);
|
|
17
|
+
}
|
|
18
|
+
function queueExists(doc, name) {
|
|
19
|
+
return (0, yaml_config_util_1.seqItemExists)(doc, QUEUES, 'name', name);
|
|
20
|
+
}
|
|
21
|
+
function topicExists(doc, name) {
|
|
22
|
+
return (0, yaml_config_util_1.seqItemExists)(doc, TOPICS, 'name', name);
|
|
23
|
+
}
|
|
24
|
+
function getExchangeType(doc, name) {
|
|
25
|
+
const item = (0, yaml_config_util_1.findSeqItemByKey)(doc, EXCHANGES, 'name', name);
|
|
26
|
+
return item ? item.get('type') : undefined;
|
|
27
|
+
}
|
|
28
|
+
function ensureExchange(doc, spec, opts = {}) {
|
|
29
|
+
const options = pruneEmpty({
|
|
30
|
+
durable: spec.durable,
|
|
31
|
+
autoDelete: spec.autoDelete,
|
|
32
|
+
internal: spec.internal,
|
|
33
|
+
});
|
|
34
|
+
return (0, yaml_config_util_1.upsertSeqItemByKey)(doc, EXCHANGES, 'name', {
|
|
35
|
+
name: spec.name,
|
|
36
|
+
type: spec.type ?? 'direct',
|
|
37
|
+
createExchangeIfNotExists: spec.createExchangeIfNotExists ?? true,
|
|
38
|
+
...(options ? { options } : {}),
|
|
39
|
+
}, opts);
|
|
40
|
+
}
|
|
41
|
+
function ensureQueue(doc, spec, opts = {}) {
|
|
42
|
+
const options = pruneEmpty({
|
|
43
|
+
durable: spec.durable,
|
|
44
|
+
exclusive: spec.exclusive,
|
|
45
|
+
autoDelete: spec.autoDelete,
|
|
46
|
+
messageTtl: spec.messageTtl,
|
|
47
|
+
maxLength: spec.maxLength,
|
|
48
|
+
expires: spec.expires,
|
|
49
|
+
});
|
|
50
|
+
return (0, yaml_config_util_1.upsertSeqItemByKey)(doc, QUEUES, 'name', {
|
|
51
|
+
name: spec.name,
|
|
52
|
+
exchange: spec.exchange,
|
|
53
|
+
routingKey: spec.routingKey,
|
|
54
|
+
createQueueIfNotExists: spec.createQueueIfNotExists ?? true,
|
|
55
|
+
...(options ? { options } : {}),
|
|
56
|
+
}, opts);
|
|
57
|
+
}
|
|
58
|
+
function ensureTopic(doc, spec, opts = {}) {
|
|
59
|
+
const retry = spec.retry
|
|
60
|
+
? pruneEmpty({
|
|
61
|
+
maxAttempts: spec.retry.maxAttempts,
|
|
62
|
+
delayMs: spec.retry.delayMs,
|
|
63
|
+
onExhausted: spec.retry.onExhausted,
|
|
64
|
+
deadLetter: spec.retry.deadLetter,
|
|
65
|
+
})
|
|
66
|
+
: undefined;
|
|
67
|
+
return (0, yaml_config_util_1.upsertSeqItemByKey)(doc, TOPICS, 'name', {
|
|
68
|
+
name: spec.name,
|
|
69
|
+
mode: spec.mode,
|
|
70
|
+
queue: spec.queue,
|
|
71
|
+
exchange: spec.exchange,
|
|
72
|
+
routingKey: spec.routingKey,
|
|
73
|
+
errorBehavior: spec.errorBehavior,
|
|
74
|
+
retry,
|
|
75
|
+
mandatory: spec.mandatory,
|
|
76
|
+
persistent: spec.persistent,
|
|
77
|
+
toObservable: spec.toObservable,
|
|
78
|
+
}, opts);
|
|
79
|
+
}
|
|
80
|
+
function routingKeyRequired(doc, exchangeName) {
|
|
81
|
+
return getExchangeType(doc, exchangeName) === 'topic';
|
|
82
|
+
}
|
|
83
|
+
function pruneEmpty(obj) {
|
|
84
|
+
const out = {};
|
|
85
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
86
|
+
if (v !== undefined)
|
|
87
|
+
out[k] = v;
|
|
88
|
+
}
|
|
89
|
+
return Object.keys(out).length ? out : undefined;
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=broker-yaml.util.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"broker-yaml.util.js","sourceRoot":"","sources":["../../../libs/rlb-nestjs-amqp/src/schematics/utils/broker-yaml.util.ts"],"names":[],"mappings":";;AAyBA,wCAEC;AACD,kCAEC;AACD,kCAEC;AAGD,0CAGC;AAaD,wCAkBC;AAiBD,kCAsBC;AAsBD,kCA2BC;AAGD,gDAEC;AAlKD,yDAM4B;AAY5B,MAAM,SAAS,GAAG,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;AAC1C,MAAM,MAAM,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;AACpC,MAAM,MAAM,GAAG,CAAC,QAAQ,CAAC,CAAC;AAI1B,SAAgB,cAAc,CAAC,GAAa,EAAE,IAAY;IACxD,OAAO,IAAA,gCAAa,EAAC,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;AACrD,CAAC;AACD,SAAgB,WAAW,CAAC,GAAa,EAAE,IAAY;IACrD,OAAO,IAAA,gCAAa,EAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;AAClD,CAAC;AACD,SAAgB,WAAW,CAAC,GAAa,EAAE,IAAY;IACrD,OAAO,IAAA,gCAAa,EAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;AAClD,CAAC;AAGD,SAAgB,eAAe,CAAC,GAAa,EAAE,IAAY;IACzD,MAAM,IAAI,GAAG,IAAA,mCAAgB,EAAC,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;IAC5D,OAAO,IAAI,CAAC,CAAC,CAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAA8B,CAAC,CAAC,CAAC,SAAS,CAAC;AAC3E,CAAC;AAaD,SAAgB,cAAc,CAAC,GAAa,EAAE,IAAkB,EAAE,OAAsB,EAAE;IACxF,MAAM,OAAO,GAAG,UAAU,CAAC;QACzB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,QAAQ,EAAE,IAAI,CAAC,QAAQ;KACxB,CAAC,CAAC;IACH,OAAO,IAAA,qCAAkB,EACvB,GAAG,EACH,SAAS,EACT,MAAM,EACN;QACE,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,QAAQ;QAC3B,yBAAyB,EAAE,IAAI,CAAC,yBAAyB,IAAI,IAAI;QACjE,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAChC,EACD,IAAI,CACL,CAAC;AACJ,CAAC;AAiBD,SAAgB,WAAW,CAAC,GAAa,EAAE,IAAe,EAAE,OAAsB,EAAE;IAClF,MAAM,OAAO,GAAG,UAAU,CAAC;QACzB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,OAAO,EAAE,IAAI,CAAC,OAAO;KACtB,CAAC,CAAC;IACH,OAAO,IAAA,qCAAkB,EACvB,GAAG,EACH,MAAM,EACN,MAAM,EACN;QACE,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,sBAAsB,EAAE,IAAI,CAAC,sBAAsB,IAAI,IAAI;QAC3D,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAChC,EACD,IAAI,CACL,CAAC;AACJ,CAAC;AAsBD,SAAgB,WAAW,CAAC,GAAa,EAAE,IAAe,EAAE,OAAsB,EAAE;IAClF,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK;QACtB,CAAC,CAAC,UAAU,CAAC;YACT,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW;YACnC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO;YAC3B,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW;YACnC,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU;SAClC,CAAC;QACJ,CAAC,CAAC,SAAS,CAAC;IACd,OAAO,IAAA,qCAAkB,EACvB,GAAG,EACH,MAAM,EACN,MAAM,EACN;QACE,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,aAAa,EAAE,IAAI,CAAC,aAAa;QACjC,KAAK;QACL,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,YAAY,EAAE,IAAI,CAAC,YAAY;KAChC,EACD,IAAI,CACL,CAAC;AACJ,CAAC;AAGD,SAAgB,kBAAkB,CAAC,GAAa,EAAE,YAAoB;IACpE,OAAO,eAAe,CAAC,GAAG,EAAE,YAAY,CAAC,KAAK,OAAO,CAAC;AACxD,CAAC;AAED,SAAS,UAAU,CAAoC,GAAM;IAC3D,MAAM,GAAG,GAA4B,EAAE,CAAC;IACxC,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACzC,IAAI,CAAC,KAAK,SAAS;YAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAClC,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAE,GAAS,CAAC,CAAC,CAAC,SAAS,CAAC;AAC1D,CAAC"}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { Document } from 'yaml';
|
|
2
|
+
import {
|
|
3
|
+
findSeqItemByKey,
|
|
4
|
+
seqItemExists,
|
|
5
|
+
upsertSeqItemByKey,
|
|
6
|
+
UpsertOptions,
|
|
7
|
+
UpsertOutcome,
|
|
8
|
+
} from './yaml-config.util';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Domain helpers for the `broker` section, layered on the generic YAML upsert. They encode the
|
|
12
|
+
* cross-reference invariants the gotchas warn about (exchange type ⇒ routingKey required, topic
|
|
13
|
+
* needs a queue for rpc/handle, dead-letter exchange must be declared, …) so each schematic's
|
|
14
|
+
* index.ts stays a thin "read doc → ensureX → write doc".
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
export type ExchangeType = 'direct' | 'topic' | 'fanout' | 'headers';
|
|
18
|
+
export type TopicMode = 'rpc' | 'handle' | 'broadcast' | 'event';
|
|
19
|
+
|
|
20
|
+
const EXCHANGES = ['broker', 'exchanges'];
|
|
21
|
+
const QUEUES = ['broker', 'queues'];
|
|
22
|
+
const TOPICS = ['topics'];
|
|
23
|
+
|
|
24
|
+
// --- existence / lookups ----------------------------------------------------
|
|
25
|
+
|
|
26
|
+
export function exchangeExists(doc: Document, name: string): boolean {
|
|
27
|
+
return seqItemExists(doc, EXCHANGES, 'name', name);
|
|
28
|
+
}
|
|
29
|
+
export function queueExists(doc: Document, name: string): boolean {
|
|
30
|
+
return seqItemExists(doc, QUEUES, 'name', name);
|
|
31
|
+
}
|
|
32
|
+
export function topicExists(doc: Document, name: string): boolean {
|
|
33
|
+
return seqItemExists(doc, TOPICS, 'name', name);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** The declared type of an exchange (used to decide whether a queue/topic needs a routingKey). */
|
|
37
|
+
export function getExchangeType(doc: Document, name: string): ExchangeType | undefined {
|
|
38
|
+
const item = findSeqItemByKey(doc, EXCHANGES, 'name', name);
|
|
39
|
+
return item ? (item.get('type') as ExchangeType | undefined) : undefined;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// --- ensure (idempotent upsert) --------------------------------------------
|
|
43
|
+
|
|
44
|
+
export interface ExchangeSpec {
|
|
45
|
+
name: string;
|
|
46
|
+
type?: ExchangeType;
|
|
47
|
+
createExchangeIfNotExists?: boolean;
|
|
48
|
+
durable?: boolean;
|
|
49
|
+
autoDelete?: boolean;
|
|
50
|
+
internal?: boolean;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function ensureExchange(doc: Document, spec: ExchangeSpec, opts: UpsertOptions = {}): UpsertOutcome {
|
|
54
|
+
const options = pruneEmpty({
|
|
55
|
+
durable: spec.durable,
|
|
56
|
+
autoDelete: spec.autoDelete,
|
|
57
|
+
internal: spec.internal,
|
|
58
|
+
});
|
|
59
|
+
return upsertSeqItemByKey(
|
|
60
|
+
doc,
|
|
61
|
+
EXCHANGES,
|
|
62
|
+
'name',
|
|
63
|
+
{
|
|
64
|
+
name: spec.name,
|
|
65
|
+
type: spec.type ?? 'direct',
|
|
66
|
+
createExchangeIfNotExists: spec.createExchangeIfNotExists ?? true,
|
|
67
|
+
...(options ? { options } : {}),
|
|
68
|
+
},
|
|
69
|
+
opts,
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export interface QueueSpec {
|
|
74
|
+
name: string;
|
|
75
|
+
exchange: string;
|
|
76
|
+
/** Required (and only meaningful) when the exchange is a `topic` exchange. */
|
|
77
|
+
routingKey?: string | string[];
|
|
78
|
+
createQueueIfNotExists?: boolean;
|
|
79
|
+
durable?: boolean;
|
|
80
|
+
exclusive?: boolean;
|
|
81
|
+
autoDelete?: boolean;
|
|
82
|
+
/** Growth bounds (2.1.x hardening): message TTL / max length / unused-queue TTL, all in the queue options. */
|
|
83
|
+
messageTtl?: number;
|
|
84
|
+
maxLength?: number;
|
|
85
|
+
expires?: number;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export function ensureQueue(doc: Document, spec: QueueSpec, opts: UpsertOptions = {}): UpsertOutcome {
|
|
89
|
+
const options = pruneEmpty({
|
|
90
|
+
durable: spec.durable,
|
|
91
|
+
exclusive: spec.exclusive,
|
|
92
|
+
autoDelete: spec.autoDelete,
|
|
93
|
+
messageTtl: spec.messageTtl,
|
|
94
|
+
maxLength: spec.maxLength,
|
|
95
|
+
expires: spec.expires,
|
|
96
|
+
});
|
|
97
|
+
return upsertSeqItemByKey(
|
|
98
|
+
doc,
|
|
99
|
+
QUEUES,
|
|
100
|
+
'name',
|
|
101
|
+
{
|
|
102
|
+
name: spec.name,
|
|
103
|
+
exchange: spec.exchange,
|
|
104
|
+
routingKey: spec.routingKey,
|
|
105
|
+
createQueueIfNotExists: spec.createQueueIfNotExists ?? true,
|
|
106
|
+
...(options ? { options } : {}),
|
|
107
|
+
},
|
|
108
|
+
opts,
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export interface RetrySpec {
|
|
113
|
+
maxAttempts?: number;
|
|
114
|
+
delayMs?: number;
|
|
115
|
+
onExhausted?: 'dead-letter' | 'drop';
|
|
116
|
+
deadLetter?: { exchange: string; routingKey?: string };
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export interface TopicSpec {
|
|
120
|
+
name: string;
|
|
121
|
+
mode: TopicMode;
|
|
122
|
+
queue?: string;
|
|
123
|
+
exchange?: string;
|
|
124
|
+
routingKey?: string | string[];
|
|
125
|
+
errorBehavior?: 'ack' | 'nack' | 'requeue';
|
|
126
|
+
retry?: RetrySpec;
|
|
127
|
+
mandatory?: boolean;
|
|
128
|
+
persistent?: boolean;
|
|
129
|
+
toObservable?: boolean;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export function ensureTopic(doc: Document, spec: TopicSpec, opts: UpsertOptions = {}): UpsertOutcome {
|
|
133
|
+
const retry = spec.retry
|
|
134
|
+
? pruneEmpty({
|
|
135
|
+
maxAttempts: spec.retry.maxAttempts,
|
|
136
|
+
delayMs: spec.retry.delayMs,
|
|
137
|
+
onExhausted: spec.retry.onExhausted,
|
|
138
|
+
deadLetter: spec.retry.deadLetter,
|
|
139
|
+
})
|
|
140
|
+
: undefined;
|
|
141
|
+
return upsertSeqItemByKey(
|
|
142
|
+
doc,
|
|
143
|
+
TOPICS,
|
|
144
|
+
'name',
|
|
145
|
+
{
|
|
146
|
+
name: spec.name,
|
|
147
|
+
mode: spec.mode,
|
|
148
|
+
queue: spec.queue,
|
|
149
|
+
exchange: spec.exchange,
|
|
150
|
+
routingKey: spec.routingKey,
|
|
151
|
+
errorBehavior: spec.errorBehavior,
|
|
152
|
+
retry,
|
|
153
|
+
mandatory: spec.mandatory,
|
|
154
|
+
persistent: spec.persistent,
|
|
155
|
+
toObservable: spec.toObservable,
|
|
156
|
+
},
|
|
157
|
+
opts,
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/** `true` when the exchange is a topic exchange, so a bound queue/topic MUST carry a routingKey. */
|
|
162
|
+
export function routingKeyRequired(doc: Document, exchangeName: string): boolean {
|
|
163
|
+
return getExchangeType(doc, exchangeName) === 'topic';
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function pruneEmpty<T extends Record<string, unknown>>(obj: T): T | undefined {
|
|
167
|
+
const out: Record<string, unknown> = {};
|
|
168
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
169
|
+
if (v !== undefined) out[k] = v;
|
|
170
|
+
}
|
|
171
|
+
return Object.keys(out).length ? (out as T) : undefined;
|
|
172
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Tree } from '@angular-devkit/schematics';
|
|
2
|
+
export declare function findFileInTree(tree: Tree, fileName: string): string | undefined;
|
|
3
|
+
export declare function findAppModule(tree: Tree): string | undefined;
|
|
4
|
+
export declare function findMainTs(tree: Tree): string | undefined;
|
|
5
|
+
export declare function ensureLibImport(source: string, symbols: string[]): string;
|
|
6
|
+
export declare function ensureImportLine(source: string, line: string, marker: string): string;
|
|
7
|
+
export declare function insertIntoImportsArray(source: string, moduleEntry: string): string;
|
|
8
|
+
export interface WireEntry {
|
|
9
|
+
code: string;
|
|
10
|
+
sentinel: string;
|
|
11
|
+
}
|
|
12
|
+
export interface WireAppModuleOptions {
|
|
13
|
+
libSymbols: string[];
|
|
14
|
+
importLines?: {
|
|
15
|
+
line: string;
|
|
16
|
+
marker: string;
|
|
17
|
+
}[];
|
|
18
|
+
entries: WireEntry[];
|
|
19
|
+
}
|
|
20
|
+
export declare function wireAppModule(tree: Tree, opts: WireAppModuleOptions): string | undefined;
|
|
21
|
+
export declare function coreLibSymbols(): string[];
|
|
22
|
+
export declare function coreImportLines(): {
|
|
23
|
+
line: string;
|
|
24
|
+
marker: string;
|
|
25
|
+
}[];
|
|
26
|
+
export declare function configModuleEntry(): WireEntry;
|
|
27
|
+
export declare function brokerModuleEntry(): WireEntry;
|
|
28
|
+
export declare function createConfigLoader(tree: Tree): void;
|
|
29
|
+
export declare function configureMainForGateway(tree: Tree): boolean;
|
|
30
|
+
export declare function addDeps(tree: Tree, deps: Record<string, string>): void;
|