nestjs-ddd-cli 3.2.2 → 3.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +118 -9
- package/ddd.schema.json +11 -1
- package/dist/commands/doctor-enhanced.d.ts +1 -0
- package/dist/commands/doctor-enhanced.js +94 -79
- package/dist/commands/doctor-enhanced.js.map +1 -1
- package/dist/commands/doctor.d.ts +9 -0
- package/dist/commands/doctor.js +68 -21
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/generate-all.js +54 -28
- package/dist/commands/generate-all.js.map +1 -1
- package/dist/commands/generate-controller.d.ts +1 -0
- package/dist/commands/generate-controller.js +71 -0
- package/dist/commands/generate-controller.js.map +1 -0
- package/dist/commands/generate-domain-service.d.ts +1 -1
- package/dist/commands/generate-domain-service.js +6 -4
- package/dist/commands/generate-domain-service.js.map +1 -1
- package/dist/commands/generate-dto.d.ts +4 -0
- package/dist/commands/generate-dto.js +162 -0
- package/dist/commands/generate-dto.js.map +1 -0
- package/dist/commands/generate-entity.js +7 -2
- package/dist/commands/generate-entity.js.map +1 -1
- package/dist/commands/generate-event.js +10 -4
- package/dist/commands/generate-event.js.map +1 -1
- package/dist/commands/generate-migration-deployment.d.ts +15 -0
- package/dist/commands/generate-migration-deployment.js +326 -0
- package/dist/commands/generate-migration-deployment.js.map +1 -0
- package/dist/commands/generate-migration-deployment.spec.d.ts +1 -0
- package/dist/commands/generate-migration-deployment.spec.js +337 -0
- package/dist/commands/generate-migration-deployment.spec.js.map +1 -0
- package/dist/commands/generate-module.js +4 -2
- package/dist/commands/generate-module.js.map +1 -1
- package/dist/commands/generate-query.js +23 -4
- package/dist/commands/generate-query.js.map +1 -1
- package/dist/commands/generate-repository.d.ts +1 -1
- package/dist/commands/generate-repository.js +17 -34
- package/dist/commands/generate-repository.js.map +1 -1
- package/dist/commands/generate-service.js +19 -4
- package/dist/commands/generate-service.js.map +1 -1
- package/dist/commands/generate-usecase.js +12 -31
- package/dist/commands/generate-usecase.js.map +1 -1
- package/dist/commands/generate-value-object.js +3 -14
- package/dist/commands/generate-value-object.js.map +1 -1
- package/dist/commands/init-project.d.ts +3 -0
- package/dist/commands/init-project.js +19 -9
- package/dist/commands/init-project.js.map +1 -1
- package/dist/commands/interactive-scaffold.js +10 -0
- package/dist/commands/interactive-scaffold.js.map +1 -1
- package/dist/commands/migration.d.ts +3 -0
- package/dist/commands/migration.js +83 -48
- package/dist/commands/migration.js.map +1 -1
- package/dist/commands/recipe.d.ts +2 -0
- package/dist/commands/recipe.js +229 -85
- package/dist/commands/recipe.js.map +1 -1
- package/dist/commands/recipes/banklink-connector-contract.recipe.d.ts +1 -0
- package/dist/commands/recipes/banklink-connector-contract.recipe.js +161 -0
- package/dist/commands/recipes/banklink-connector-contract.recipe.js.map +1 -0
- package/dist/commands/recipes/bounded-json-http.recipe.d.ts +2 -0
- package/dist/commands/recipes/bounded-json-http.recipe.js +53 -0
- package/dist/commands/recipes/bounded-json-http.recipe.js.map +1 -0
- package/dist/commands/recipes/business-reference-identifiers.recipe.d.ts +1 -0
- package/dist/commands/recipes/business-reference-identifiers.recipe.js +223 -0
- package/dist/commands/recipes/business-reference-identifiers.recipe.js.map +1 -0
- package/dist/commands/recipes/event-backbone.recipe.d.ts +1 -0
- package/dist/commands/recipes/event-backbone.recipe.js +1118 -0
- package/dist/commands/recipes/event-backbone.recipe.js.map +1 -0
- package/dist/commands/recipes/external-projection-worker.recipe.d.ts +6 -0
- package/dist/commands/recipes/external-projection-worker.recipe.js +211 -0
- package/dist/commands/recipes/external-projection-worker.recipe.js.map +1 -0
- package/dist/commands/recipes/index.d.ts +11 -0
- package/dist/commands/recipes/index.js +11 -0
- package/dist/commands/recipes/index.js.map +1 -1
- package/dist/commands/recipes/jest-cjs-compat.recipe.d.ts +3 -0
- package/dist/commands/recipes/jest-cjs-compat.recipe.js +130 -0
- package/dist/commands/recipes/jest-cjs-compat.recipe.js.map +1 -0
- package/dist/commands/recipes/joi-env.recipe.js +1 -1
- package/dist/commands/recipes/kafka-consumer.recipe.d.ts +1 -0
- package/dist/commands/recipes/kafka-consumer.recipe.js +65 -0
- package/dist/commands/recipes/kafka-consumer.recipe.js.map +1 -0
- package/dist/commands/recipes/oauth2-client-credentials.recipe.d.ts +1 -0
- package/dist/commands/recipes/oauth2-client-credentials.recipe.js +60 -0
- package/dist/commands/recipes/oauth2-client-credentials.recipe.js.map +1 -0
- package/dist/commands/recipes/oauth2-token-introspection.recipe.d.ts +1 -0
- package/dist/commands/recipes/oauth2-token-introspection.recipe.js +67 -0
- package/dist/commands/recipes/oauth2-token-introspection.recipe.js.map +1 -0
- package/dist/commands/recipes/oidc-bff-session.recipe.d.ts +1 -0
- package/dist/commands/recipes/oidc-bff-session.recipe.js +57 -0
- package/dist/commands/recipes/oidc-bff-session.recipe.js.map +1 -0
- package/dist/commands/recipes/oidc-dashboard.recipe.d.ts +1 -0
- package/dist/commands/recipes/oidc-dashboard.recipe.js +463 -0
- package/dist/commands/recipes/oidc-dashboard.recipe.js.map +1 -0
- package/dist/commands/recipes/oidc-resource-server.recipe.d.ts +1 -0
- package/dist/commands/recipes/oidc-resource-server.recipe.js +85 -0
- package/dist/commands/recipes/oidc-resource-server.recipe.js.map +1 -0
- package/dist/commands/recipes/platform-context.recipe.d.ts +1 -0
- package/dist/commands/recipes/platform-context.recipe.js +229 -0
- package/dist/commands/recipes/platform-context.recipe.js.map +1 -0
- package/dist/commands/recipes/platform-parc-authorization.recipe.d.ts +1 -0
- package/dist/commands/recipes/platform-parc-authorization.recipe.js +339 -0
- package/dist/commands/recipes/platform-parc-authorization.recipe.js.map +1 -0
- package/dist/commands/recipes/platform-parc-bound-authorization.recipe.d.ts +1 -0
- package/dist/commands/recipes/platform-parc-bound-authorization.recipe.js +56 -0
- package/dist/commands/recipes/platform-parc-bound-authorization.recipe.js.map +1 -0
- package/dist/commands/recipes/platform-service-access-request-context.recipe.d.ts +1 -0
- package/dist/commands/recipes/platform-service-access-request-context.recipe.js +103 -0
- package/dist/commands/recipes/platform-service-access-request-context.recipe.js.map +1 -0
- package/dist/commands/recipes/platform-service-runtime.recipe.d.ts +1 -0
- package/dist/commands/recipes/platform-service-runtime.recipe.js +415 -0
- package/dist/commands/recipes/platform-service-runtime.recipe.js.map +1 -0
- package/dist/index.js +77 -9
- package/dist/index.js.map +1 -1
- package/dist/templates/ai-context/CLAUDE.md.hbs +39 -3
- package/dist/templates/ai-context/conventions.md.hbs +13 -8
- package/dist/templates/command/create-command.hbs +8 -3
- package/dist/templates/command/delete-command.hbs +1 -1
- package/dist/templates/command/update-command.hbs +1 -1
- package/dist/templates/controller/application-controller.hbs +7 -0
- package/dist/templates/controller/controller.hbs +6 -0
- package/dist/templates/dto/create-dto.hbs +17 -5
- package/dist/templates/dto/filter-dto.hbs +1 -1
- package/dist/templates/dto/response-dto.hbs +1 -1
- package/dist/templates/entity/entity.hbs +4 -0
- package/dist/templates/mapper/mapper.hbs +5 -1
- package/dist/templates/orm-entity/orm-entity.hbs +9 -1
- package/dist/templates/prisma/prisma-mapper.hbs +6 -0
- package/dist/templates/prisma/prisma-repository.hbs +57 -5
- package/dist/templates/prisma/prisma-schema.hbs +2 -0
- package/dist/templates/query/get-all.query.hbs +10 -2
- package/dist/templates/recipes/bounded-json-http/README.md.hbs +36 -0
- package/dist/templates/recipes/external-projection-worker/README.md.hbs +157 -0
- package/dist/templates/recipes/external-projection-worker/canonical-json.ts.hbs +123 -0
- package/dist/templates/recipes/external-projection-worker/enqueuer.ts.hbs +167 -0
- package/dist/templates/recipes/external-projection-worker/index.ts.hbs +6 -0
- package/dist/templates/recipes/external-projection-worker/migration.ts.hbs +88 -0
- package/dist/templates/recipes/external-projection-worker/module.ts.hbs +36 -0
- package/dist/templates/recipes/external-projection-worker/store.ts.hbs +354 -0
- package/dist/templates/recipes/external-projection-worker/types.ts.hbs +134 -0
- package/dist/templates/recipes/external-projection-worker/worker.ts.hbs +296 -0
- package/dist/templates/recipes/kafka-consumer/README.md.hbs +50 -0
- package/dist/templates/recipes/kafka-consumer/kafka-consumer.ts.hbs +135 -0
- package/dist/templates/recipes/kafka-consumer/migration.ts.hbs +17 -0
- package/dist/templates/recipes/oauth2-client-credentials/README.md.hbs +40 -0
- package/dist/templates/recipes/oauth2-client-credentials/client.spec.ts.hbs +234 -0
- package/dist/templates/recipes/oauth2-client-credentials/client.ts.hbs +210 -0
- package/dist/templates/recipes/oauth2-client-credentials/index.ts.hbs +2 -0
- package/dist/templates/recipes/oauth2-client-credentials/module.ts.hbs +58 -0
- package/dist/templates/recipes/oauth2-token-introspection/README.md.hbs +158 -0
- package/dist/templates/recipes/oauth2-token-introspection/client.spec.ts.hbs +350 -0
- package/dist/templates/recipes/oauth2-token-introspection/client.ts.hbs +241 -0
- package/dist/templates/recipes/oauth2-token-introspection/http-client.spec.ts.hbs +411 -0
- package/dist/templates/recipes/oauth2-token-introspection/http-client.ts.hbs +343 -0
- package/dist/templates/recipes/oauth2-token-introspection/index.ts.hbs +3 -0
- package/dist/templates/recipes/oauth2-token-introspection/module.ts.hbs +58 -0
- package/dist/templates/recipes/oidc-bff-session/README.md.hbs +96 -0
- package/dist/templates/recipes/oidc-bff-session/client.test.ts.hbs +663 -0
- package/dist/templates/recipes/oidc-bff-session/client.ts.hbs +635 -0
- package/dist/templates/recipes/oidc-bff-session/index.ts.hbs +3 -0
- package/dist/templates/recipes/oidc-bff-session/store.integration.test.ts.hbs +480 -0
- package/dist/templates/recipes/oidc-bff-session/store.test.ts.hbs +87 -0
- package/dist/templates/recipes/oidc-bff-session/store.ts.hbs +549 -0
- package/dist/templates/recipes/oidc-bff-session/valkey.test.ts.hbs +158 -0
- package/dist/templates/recipes/oidc-bff-session/valkey.ts.hbs +148 -0
- package/dist/templates/recipes/oidc-resource-server/README.md.hbs +74 -0
- package/dist/templates/recipes/oidc-resource-server/index.ts.hbs +2 -0
- package/dist/templates/recipes/oidc-resource-server/module.ts.hbs +51 -0
- package/dist/templates/recipes/oidc-resource-server/verifier.spec.ts.hbs +186 -0
- package/dist/templates/recipes/oidc-resource-server/verifier.ts.hbs +440 -0
- package/dist/templates/recipes/platform-parc-bound-authorization/README.md.hbs +92 -0
- package/dist/templates/recipes/platform-parc-bound-authorization/client.ts.hbs +142 -0
- package/dist/templates/recipes/platform-service-access-request-context/docs.md.hbs +61 -0
- package/dist/templates/recipes/platform-service-access-request-context/env.example.hbs +7 -0
- package/dist/templates/recipes/platform-service-access-request-context/index.ts.hbs +7 -0
- package/dist/templates/recipes/platform-service-access-request-context/request-context-headers.ts.hbs +61 -0
- package/dist/templates/recipes/platform-service-access-request-context/request-context-introspection.parser.ts.hbs +132 -0
- package/dist/templates/recipes/platform-service-access-request-context/request-context-introspection.types.ts.hbs +40 -0
- package/dist/templates/recipes/platform-service-access-request-context/service-access-request-context.client.ts.hbs +45 -0
- package/dist/templates/recipes/platform-service-access-request-context/service-access-request-context.config.ts.hbs +142 -0
- package/dist/templates/recipes/platform-service-access-request-context/service-access-request-context.guard.ts.hbs +77 -0
- package/dist/templates/recipes/platform-service-access-request-context/service-access-request-context.module.ts.hbs +17 -0
- package/dist/templates/repository/repository.hbs +42 -4
- package/dist/templates/resolver/graphql-input.hbs +23 -6
- package/dist/templates/resolver/resolver.hbs +4 -0
- package/dist/templates/service/domain-service.hbs +2 -2
- package/dist/templates/test/controller.spec.hbs +5 -1
- package/dist/templates/test/prisma-repository.spec.hbs +192 -0
- package/dist/templates/test/repository.spec.hbs +40 -1
- package/dist/templates/test/usecase.spec.hbs +23 -4
- package/dist/templates/usecase/application-usecase.hbs +17 -0
- package/dist/templates/usecase/create-usecase.hbs +34 -3
- package/dist/templates/usecase/update-usecase.hbs +15 -1
- package/dist/utils/config.utils.d.ts +2 -0
- package/dist/utils/config.utils.js +14 -2
- package/dist/utils/config.utils.js.map +1 -1
- package/dist/utils/dependency.utils.d.ts +16 -2
- package/dist/utils/dependency.utils.js +100 -12
- package/dist/utils/dependency.utils.js.map +1 -1
- package/dist/utils/field.utils.d.ts +6 -0
- package/dist/utils/field.utils.js +50 -8
- package/dist/utils/field.utils.js.map +1 -1
- package/dist/utils/field.utils.spec.d.ts +1 -0
- package/dist/utils/field.utils.spec.js +38 -0
- package/dist/utils/field.utils.spec.js.map +1 -0
- package/dist/utils/file.utils.d.ts +23 -1
- package/dist/utils/file.utils.js +37 -1
- package/dist/utils/file.utils.js.map +1 -1
- package/dist/utils/naming.utils.js +5 -4
- package/dist/utils/naming.utils.js.map +1 -1
- package/dist/utils/static-recipe.utils.d.ts +4 -0
- package/dist/utils/static-recipe.utils.js +148 -0
- package/dist/utils/static-recipe.utils.js.map +1 -0
- package/package.json +12 -5
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.applyBanklinkConnectorContractRecipe = applyBanklinkConnectorContractRecipe;
|
|
40
|
+
const path = __importStar(require("path"));
|
|
41
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
42
|
+
const file_utils_1 = require("../../utils/file.utils");
|
|
43
|
+
async function applyBanklinkConnectorContractRecipe(basePath) {
|
|
44
|
+
const sharedPath = path.join(basePath, 'src/shared');
|
|
45
|
+
const banklinkPath = path.join(sharedPath, 'banklink-connector');
|
|
46
|
+
const docsPath = path.join(basePath, 'docs');
|
|
47
|
+
await (0, file_utils_1.ensureDir)(banklinkPath);
|
|
48
|
+
await (0, file_utils_1.ensureDir)(docsPath);
|
|
49
|
+
await (0, file_utils_1.writeFile)(path.join(banklinkPath, 'banklink-connector.types.ts'), typesContent);
|
|
50
|
+
await (0, file_utils_1.writeFile)(path.join(banklinkPath, 'banklink-connector.errors.ts'), errorsContent);
|
|
51
|
+
await (0, file_utils_1.writeFile)(path.join(banklinkPath, 'index.ts'), indexContent);
|
|
52
|
+
await (0, file_utils_1.writeFile)(path.join(docsPath, 'BANKLINK_CONNECTOR_CONTRACT.md'), docsContent);
|
|
53
|
+
console.log(chalk_1.default.green(' ✓ BankLink connector contract types'));
|
|
54
|
+
console.log(chalk_1.default.green(' ✓ Go sidecar boundary documentation'));
|
|
55
|
+
console.log(chalk_1.default.yellow(' Keep BankLink business policy in NestJS; put VPN/bank transport pain in sidecars.'));
|
|
56
|
+
}
|
|
57
|
+
const typesContent = `export type BankConnectorRuntime = "nestjs" | "go-sidecar" | "external";
|
|
58
|
+
|
|
59
|
+
export type BankConnectorCapability =
|
|
60
|
+
| "client_lookup"
|
|
61
|
+
| "account_statement"
|
|
62
|
+
| "rib_download"
|
|
63
|
+
| "iban_validation"
|
|
64
|
+
| "virtual_accounts"
|
|
65
|
+
| "single_transfer"
|
|
66
|
+
| "bulk_transfers"
|
|
67
|
+
| "transfer_status"
|
|
68
|
+
| "webhook_receiver";
|
|
69
|
+
|
|
70
|
+
export type BankConnectorHealthStatus = "healthy" | "degraded" | "down" | "unknown";
|
|
71
|
+
|
|
72
|
+
export interface BankConnectorDescriptor {
|
|
73
|
+
code: string;
|
|
74
|
+
displayName: string;
|
|
75
|
+
country: string;
|
|
76
|
+
runtime: BankConnectorRuntime;
|
|
77
|
+
capabilities: BankConnectorCapability[];
|
|
78
|
+
requiresVpn: boolean;
|
|
79
|
+
requiresMutualTls: boolean;
|
|
80
|
+
requiredEnv: string[];
|
|
81
|
+
healthPath: string;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export interface BankConnectorHealth {
|
|
85
|
+
connectorCode: string;
|
|
86
|
+
status: BankConnectorHealthStatus;
|
|
87
|
+
checkedAt: string;
|
|
88
|
+
latencyMs?: number;
|
|
89
|
+
message?: string;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export interface BankConnectorRequestContext {
|
|
93
|
+
requestId: string;
|
|
94
|
+
tenantId?: string;
|
|
95
|
+
businessEntityId?: string;
|
|
96
|
+
idempotencyKey: string;
|
|
97
|
+
initiatedBy: string;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export interface BankConnectorResult<TPayload> {
|
|
101
|
+
success: boolean;
|
|
102
|
+
payload?: TPayload;
|
|
103
|
+
providerReference?: string;
|
|
104
|
+
retryable?: boolean;
|
|
105
|
+
errorCode?: string;
|
|
106
|
+
errorMessage?: string;
|
|
107
|
+
}
|
|
108
|
+
`;
|
|
109
|
+
const errorsContent = `export class BankConnectorConfigurationError extends Error {
|
|
110
|
+
constructor(message: string) {
|
|
111
|
+
super(message);
|
|
112
|
+
this.name = "BankConnectorConfigurationError";
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export class BankConnectorUnavailableError extends Error {
|
|
117
|
+
constructor(message: string) {
|
|
118
|
+
super(message);
|
|
119
|
+
this.name = "BankConnectorUnavailableError";
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
`;
|
|
123
|
+
const indexContent = `export * from "./banklink-connector.types";
|
|
124
|
+
export * from "./banklink-connector.errors";
|
|
125
|
+
`;
|
|
126
|
+
const docsContent = `# BankLink Connector Contract
|
|
127
|
+
|
|
128
|
+
BankLink is the NestJS control plane. It owns consents, linked accounts, user
|
|
129
|
+
policy, business policy, audit, and service-facing APIs.
|
|
130
|
+
|
|
131
|
+
Bank connector sidecars own bank-specific transport pain: VPN, mTLS, IP
|
|
132
|
+
allowlisting, SOAP/SFTP/HTTP quirks, and provider health probing.
|
|
133
|
+
|
|
134
|
+
## Runtime Decision
|
|
135
|
+
|
|
136
|
+
- Use NestJS for the BankLink core service and any connector whose complexity is
|
|
137
|
+
mostly business/domain logic.
|
|
138
|
+
- Use Go sidecars for VPN-bound or high-throughput bank adapters where a small
|
|
139
|
+
static binary, low memory, simple containerization, and explicit network
|
|
140
|
+
behavior are valuable.
|
|
141
|
+
|
|
142
|
+
## Required Sidecar Surface
|
|
143
|
+
|
|
144
|
+
Every sidecar must expose:
|
|
145
|
+
|
|
146
|
+
- \`GET /health/live\`
|
|
147
|
+
- \`GET /health/ready\`
|
|
148
|
+
- \`GET /capabilities\`
|
|
149
|
+
- \`POST /commands/:commandName\`
|
|
150
|
+
|
|
151
|
+
Commands must require an idempotency key and return a normalized
|
|
152
|
+
\`BankConnectorResult\`. BankLink persists the business request and audit before
|
|
153
|
+
calling the sidecar.
|
|
154
|
+
|
|
155
|
+
## Ownership Rule
|
|
156
|
+
|
|
157
|
+
Never put business approval, consent decisions, fee decisions, account ownership,
|
|
158
|
+
or tenant access rules in a sidecar. The sidecar only talks to the bank and
|
|
159
|
+
normalizes the response.
|
|
160
|
+
`;
|
|
161
|
+
//# sourceMappingURL=banklink-connector-contract.recipe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"banklink-connector-contract.recipe.js","sourceRoot":"","sources":["../../../src/commands/recipes/banklink-connector-contract.recipe.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIA,oFAoBC;AAxBD,2CAA6B;AAC7B,kDAA0B;AAC1B,uDAA8D;AAEvD,KAAK,UAAU,oCAAoC,CAAC,QAAgB;IACzE,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;IACrD,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,oBAAoB,CAAC,CAAC;IACjE,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAE7C,MAAM,IAAA,sBAAS,EAAC,YAAY,CAAC,CAAC;IAC9B,MAAM,IAAA,sBAAS,EAAC,QAAQ,CAAC,CAAC;IAE1B,MAAM,IAAA,sBAAS,EAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,6BAA6B,CAAC,EAAE,YAAY,CAAC,CAAC;IACtF,MAAM,IAAA,sBAAS,EAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,8BAA8B,CAAC,EAAE,aAAa,CAAC,CAAC;IACxF,MAAM,IAAA,sBAAS,EAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,UAAU,CAAC,EAAE,YAAY,CAAC,CAAC;IACnE,MAAM,IAAA,sBAAS,EAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,gCAAgC,CAAC,EAAE,WAAW,CAAC,CAAC;IAEpF,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC,CAAC;IAClE,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC,CAAC;IAClE,OAAO,CAAC,GAAG,CACT,eAAK,CAAC,MAAM,CACV,qFAAqF,CACtF,CACF,CAAC;AACJ,CAAC;AAED,MAAM,YAAY,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmDpB,CAAC;AAEF,MAAM,aAAa,GAAG;;;;;;;;;;;;;CAarB,CAAC;AAEF,MAAM,YAAY,GAAG;;CAEpB,CAAC;AAEF,MAAM,WAAW,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkCnB,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.applyBoundedJsonHttpRecipe = applyBoundedJsonHttpRecipe;
|
|
37
|
+
const path = __importStar(require("node:path"));
|
|
38
|
+
const static_recipe_utils_1 = require("../../utils/static-recipe.utils");
|
|
39
|
+
/** Emit the shared transport alone for consumers that do not use NestJS. */
|
|
40
|
+
async function applyBoundedJsonHttpRecipe(basePath, dryRun = false) {
|
|
41
|
+
const templateRoot = path.join(__dirname, '../../templates/recipes');
|
|
42
|
+
await (0, static_recipe_utils_1.applyStaticRecipePlan)(basePath, [
|
|
43
|
+
{
|
|
44
|
+
template: path.join(templateRoot, 'oauth2-token-introspection/http-client.ts.hbs'),
|
|
45
|
+
destination: 'src/shared/auth/oauth2-token-introspection/bounded-json-http.client.ts',
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
template: path.join(templateRoot, 'bounded-json-http/README.md.hbs'),
|
|
49
|
+
destination: 'docs/auth/bounded-json-http.md',
|
|
50
|
+
},
|
|
51
|
+
], dryRun);
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=bounded-json-http.recipe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bounded-json-http.recipe.js","sourceRoot":"","sources":["../../../src/commands/recipes/bounded-json-http.recipe.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIA,gEAgBC;AApBD,gDAAkC;AAClC,yEAAwE;AAExE,4EAA4E;AACrE,KAAK,UAAU,0BAA0B,CAAC,QAAgB,EAAE,MAAM,GAAG,KAAK;IAC/E,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,yBAAyB,CAAC,CAAC;IACrE,MAAM,IAAA,2CAAqB,EACzB,QAAQ,EACR;QACE;YACE,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,+CAA+C,CAAC;YAClF,WAAW,EAAE,wEAAwE;SACtF;QACD;YACE,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,iCAAiC,CAAC;YACpE,WAAW,EAAE,gCAAgC;SAC9C;KACF,EACD,MAAM,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function applyBusinessReferenceIdentifiersRecipe(basePath: string): Promise<void>;
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.applyBusinessReferenceIdentifiersRecipe = applyBusinessReferenceIdentifiersRecipe;
|
|
40
|
+
const path = __importStar(require("path"));
|
|
41
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
42
|
+
const file_utils_1 = require("../../utils/file.utils");
|
|
43
|
+
async function applyBusinessReferenceIdentifiersRecipe(basePath) {
|
|
44
|
+
const sharedPath = path.join(basePath, 'src/shared');
|
|
45
|
+
const referencesPath = path.join(sharedPath, 'business-references');
|
|
46
|
+
await (0, file_utils_1.ensureDir)(referencesPath);
|
|
47
|
+
const typesContent = `export interface BusinessReferenceInput {
|
|
48
|
+
/**
|
|
49
|
+
* Short service prefix, for example PSW, KOR, VHQ, CRH.
|
|
50
|
+
*/
|
|
51
|
+
service: string;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Short record type, for example SET, FXQ, KYC, LVN, INV.
|
|
55
|
+
*/
|
|
56
|
+
type: string;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* ISO 3166 alpha-2 country code when market context matters.
|
|
60
|
+
*/
|
|
61
|
+
country?: string;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* ISO 4217 currency code when a single currency matters.
|
|
65
|
+
*/
|
|
66
|
+
currency?: string;
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Currency pair without separator, for example XOFUSD.
|
|
70
|
+
*/
|
|
71
|
+
currencyPair?: string;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Optional rail or provider hint when it materially helps operations.
|
|
75
|
+
*/
|
|
76
|
+
rail?: string;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Defaults to the creation time.
|
|
80
|
+
*/
|
|
81
|
+
occurredAt?: Date;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Include epoch seconds for partner file reconciliation or chronological sorting outside the DB.
|
|
85
|
+
*/
|
|
86
|
+
includeEpoch?: boolean;
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Random Crockford/base36 suffix length. Defaults to 6.
|
|
90
|
+
*/
|
|
91
|
+
randomLength?: number;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export interface BusinessReferenceParts {
|
|
95
|
+
service: string;
|
|
96
|
+
type: string;
|
|
97
|
+
country?: string;
|
|
98
|
+
currencyOrPair?: string;
|
|
99
|
+
rail?: string;
|
|
100
|
+
timestamp: string;
|
|
101
|
+
epoch?: string;
|
|
102
|
+
random: string;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export interface BusinessReferenceGeneratorPort {
|
|
106
|
+
generate(input: BusinessReferenceInput): string;
|
|
107
|
+
}
|
|
108
|
+
`;
|
|
109
|
+
await (0, file_utils_1.writeFile)(path.join(referencesPath, 'business-reference.types.ts'), typesContent);
|
|
110
|
+
const generatorContent = `import { randomBytes } from "crypto";
|
|
111
|
+
import { Injectable } from "@nestjs/common";
|
|
112
|
+
import {
|
|
113
|
+
BusinessReferenceGeneratorPort,
|
|
114
|
+
BusinessReferenceInput,
|
|
115
|
+
BusinessReferenceParts,
|
|
116
|
+
} from "./business-reference.types";
|
|
117
|
+
|
|
118
|
+
const SAFE_SEGMENT = /^[A-Z0-9][A-Z0-9_-]{1,15}$/;
|
|
119
|
+
const SAFE_RANDOM_ALPHABET = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
|
|
120
|
+
|
|
121
|
+
@Injectable()
|
|
122
|
+
export class BusinessReferenceGenerator implements BusinessReferenceGeneratorPort {
|
|
123
|
+
generate(input: BusinessReferenceInput): string {
|
|
124
|
+
const occurredAt = input.occurredAt ?? new Date();
|
|
125
|
+
const randomLength = input.randomLength ?? 6;
|
|
126
|
+
|
|
127
|
+
const parts: BusinessReferenceParts = {
|
|
128
|
+
service: this.normalizeSegment(input.service, "service"),
|
|
129
|
+
type: this.normalizeSegment(input.type, "type"),
|
|
130
|
+
country: input.country ? this.normalizeSegment(input.country, "country") : undefined,
|
|
131
|
+
currencyOrPair: this.currencySegment(input),
|
|
132
|
+
rail: input.rail ? this.normalizeSegment(input.rail, "rail") : undefined,
|
|
133
|
+
timestamp: this.utcTimestamp(occurredAt),
|
|
134
|
+
epoch: input.includeEpoch ? Math.floor(occurredAt.getTime() / 1000).toString() : undefined,
|
|
135
|
+
random: this.randomSuffix(randomLength),
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
return [
|
|
139
|
+
parts.service,
|
|
140
|
+
parts.type,
|
|
141
|
+
parts.country,
|
|
142
|
+
parts.currencyOrPair,
|
|
143
|
+
parts.rail,
|
|
144
|
+
parts.timestamp,
|
|
145
|
+
parts.epoch,
|
|
146
|
+
parts.random,
|
|
147
|
+
]
|
|
148
|
+
.filter((part): part is string => Boolean(part))
|
|
149
|
+
.join("-");
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
private currencySegment(input: BusinessReferenceInput): string | undefined {
|
|
153
|
+
if (input.currencyPair && input.currency) {
|
|
154
|
+
throw new Error("Use either currency or currencyPair, not both");
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
if (input.currencyPair) {
|
|
158
|
+
return this.normalizeSegment(input.currencyPair, "currencyPair");
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (input.currency) {
|
|
162
|
+
return this.normalizeSegment(input.currency, "currency");
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return undefined;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
private normalizeSegment(value: string, label: string): string {
|
|
169
|
+
const normalized = value.trim().replace(/[^a-zA-Z0-9_-]/g, "").toUpperCase();
|
|
170
|
+
if (!SAFE_SEGMENT.test(normalized)) {
|
|
171
|
+
throw new Error(
|
|
172
|
+
"Invalid " + label + " segment for business reference: " + value,
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
return normalized;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
private utcTimestamp(date: Date): string {
|
|
179
|
+
const year = date.getUTCFullYear().toString().padStart(4, "0");
|
|
180
|
+
const month = (date.getUTCMonth() + 1).toString().padStart(2, "0");
|
|
181
|
+
const day = date.getUTCDate().toString().padStart(2, "0");
|
|
182
|
+
const hour = date.getUTCHours().toString().padStart(2, "0");
|
|
183
|
+
const minute = date.getUTCMinutes().toString().padStart(2, "0");
|
|
184
|
+
const second = date.getUTCSeconds().toString().padStart(2, "0");
|
|
185
|
+
|
|
186
|
+
return year + month + day + "T" + hour + minute + second;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
private randomSuffix(length: number): string {
|
|
190
|
+
if (!Number.isInteger(length) || length < 4 || length > 16) {
|
|
191
|
+
throw new Error("Business reference randomLength must be between 4 and 16");
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
const bytes = randomBytes(length);
|
|
195
|
+
let output = "";
|
|
196
|
+
for (const byte of bytes) {
|
|
197
|
+
output += SAFE_RANDOM_ALPHABET[byte % SAFE_RANDOM_ALPHABET.length];
|
|
198
|
+
}
|
|
199
|
+
return output;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
`;
|
|
203
|
+
await (0, file_utils_1.writeFile)(path.join(referencesPath, 'business-reference.generator.ts'), generatorContent);
|
|
204
|
+
const moduleContent = `import { Module } from "@nestjs/common";
|
|
205
|
+
import { BusinessReferenceGenerator } from "./business-reference.generator";
|
|
206
|
+
|
|
207
|
+
@Module({
|
|
208
|
+
providers: [BusinessReferenceGenerator],
|
|
209
|
+
exports: [BusinessReferenceGenerator],
|
|
210
|
+
})
|
|
211
|
+
export class BusinessReferenceModule {}
|
|
212
|
+
`;
|
|
213
|
+
await (0, file_utils_1.writeFile)(path.join(referencesPath, 'business-reference.module.ts'), moduleContent);
|
|
214
|
+
const indexContent = `export * from "./business-reference.types";
|
|
215
|
+
export * from "./business-reference.generator";
|
|
216
|
+
export * from "./business-reference.module";
|
|
217
|
+
`;
|
|
218
|
+
await (0, file_utils_1.writeFile)(path.join(referencesPath, 'index.ts'), indexContent);
|
|
219
|
+
console.log(chalk_1.default.green(' ✓ Business reference generator'));
|
|
220
|
+
console.log(chalk_1.default.green(' ✓ Business reference module'));
|
|
221
|
+
console.log(chalk_1.default.green(' ✓ UUID/id remains canonical; reference is sidecar metadata'));
|
|
222
|
+
}
|
|
223
|
+
//# sourceMappingURL=business-reference-identifiers.recipe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"business-reference-identifiers.recipe.js","sourceRoot":"","sources":["../../../src/commands/recipes/business-reference-identifiers.recipe.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIA,0FA6LC;AAjMD,2CAA6B;AAC7B,kDAA0B;AAC1B,uDAA8D;AAEvD,KAAK,UAAU,uCAAuC,CAAC,QAAgB;IAC5E,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;IACrD,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,qBAAqB,CAAC,CAAC;IAEpE,MAAM,IAAA,sBAAS,EAAC,cAAc,CAAC,CAAC;IAEhC,MAAM,YAAY,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6DtB,CAAC;IAEA,MAAM,IAAA,sBAAS,EAAC,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,6BAA6B,CAAC,EAAE,YAAY,CAAC,CAAC;IAExF,MAAM,gBAAgB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4F1B,CAAC;IAEA,MAAM,IAAA,sBAAS,EAAC,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,iCAAiC,CAAC,EAAE,gBAAgB,CAAC,CAAC;IAEhG,MAAM,aAAa,GAAG;;;;;;;;CAQvB,CAAC;IAEA,MAAM,IAAA,sBAAS,EAAC,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,8BAA8B,CAAC,EAAE,aAAa,CAAC,CAAC;IAE1F,MAAM,YAAY,GAAG;;;CAGtB,CAAC;IAEA,MAAM,IAAA,sBAAS,EAAC,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,UAAU,CAAC,EAAE,YAAY,CAAC,CAAC;IAErE,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC,CAAC;IAC7D,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC,CAAC;IAC1D,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,8DAA8D,CAAC,CAAC,CAAC;AAC3F,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function applyEventBackboneRecipe(basePath: string): Promise<void>;
|