@pattern-stack/codegen 0.13.0 → 0.14.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/dist/{job-orchestrator.protocol-CHOEqBDk.d.ts → job-orchestrator.protocol-CARhMLCO.d.ts} +1 -1
- package/dist/runtime/subsystems/analytics/analytics.module.js +6 -2
- package/dist/runtime/subsystems/analytics/analytics.module.js.map +1 -1
- package/dist/runtime/subsystems/analytics/analytics.tokens.d.ts +0 -11
- package/dist/runtime/subsystems/analytics/analytics.tokens.js +6 -2
- package/dist/runtime/subsystems/analytics/analytics.tokens.js.map +1 -1
- package/dist/runtime/subsystems/analytics/cube-backend.js +6 -2
- package/dist/runtime/subsystems/analytics/cube-backend.js.map +1 -1
- package/dist/runtime/subsystems/analytics/index.js +6 -2
- package/dist/runtime/subsystems/analytics/index.js.map +1 -1
- package/dist/runtime/subsystems/auth/auth.module.js +12 -6
- package/dist/runtime/subsystems/auth/auth.module.js.map +1 -1
- package/dist/runtime/subsystems/auth/auth.tokens.d.ts +0 -28
- package/dist/runtime/subsystems/auth/auth.tokens.js +12 -8
- package/dist/runtime/subsystems/auth/auth.tokens.js.map +1 -1
- package/dist/runtime/subsystems/auth/controllers/auth.controller.js +12 -5
- package/dist/runtime/subsystems/auth/controllers/auth.controller.js.map +1 -1
- package/dist/runtime/subsystems/auth/index.js +12 -8
- package/dist/runtime/subsystems/auth/index.js.map +1 -1
- package/dist/runtime/subsystems/auth/middleware/requester-context.js +12 -1
- package/dist/runtime/subsystems/auth/middleware/requester-context.js.map +1 -1
- package/dist/runtime/subsystems/bridge/bridge-delivery-handler.d.ts +1 -1
- package/dist/runtime/subsystems/bridge/bridge-delivery-handler.js +10 -2
- package/dist/runtime/subsystems/bridge/bridge-delivery-handler.js.map +1 -1
- package/dist/runtime/subsystems/bridge/bridge-outbox-drain-hook.js +10 -2
- package/dist/runtime/subsystems/bridge/bridge-outbox-drain-hook.js.map +1 -1
- package/dist/runtime/subsystems/bridge/bridge.module.d.ts +1 -1
- package/dist/runtime/subsystems/bridge/bridge.module.js +14 -9
- package/dist/runtime/subsystems/bridge/bridge.module.js.map +1 -1
- package/dist/runtime/subsystems/bridge/bridge.protocol.d.ts +1 -1
- package/dist/runtime/subsystems/bridge/event-flow.service.d.ts +1 -1
- package/dist/runtime/subsystems/bridge/event-flow.service.js +9 -1
- package/dist/runtime/subsystems/bridge/event-flow.service.js.map +1 -1
- package/dist/runtime/subsystems/bridge/index.d.ts +1 -1
- package/dist/runtime/subsystems/bridge/index.js +14 -9
- package/dist/runtime/subsystems/bridge/index.js.map +1 -1
- package/dist/runtime/subsystems/cache/cache.drizzle-backend.js +6 -1
- package/dist/runtime/subsystems/cache/cache.drizzle-backend.js.map +1 -1
- package/dist/runtime/subsystems/cache/cache.memory-backend.js +6 -1
- package/dist/runtime/subsystems/cache/cache.memory-backend.js.map +1 -1
- package/dist/runtime/subsystems/cache/cache.module.js +6 -2
- package/dist/runtime/subsystems/cache/cache.module.js.map +1 -1
- package/dist/runtime/subsystems/cache/cache.tokens.d.ts +0 -10
- package/dist/runtime/subsystems/cache/cache.tokens.js +6 -2
- package/dist/runtime/subsystems/cache/cache.tokens.js.map +1 -1
- package/dist/runtime/subsystems/cache/index.js +6 -2
- package/dist/runtime/subsystems/cache/index.js.map +1 -1
- package/dist/runtime/subsystems/events/event-bus.drizzle-backend.js +5 -0
- package/dist/runtime/subsystems/events/event-bus.drizzle-backend.js.map +1 -1
- package/dist/runtime/subsystems/events/event-bus.memory-backend.js +5 -0
- package/dist/runtime/subsystems/events/event-bus.memory-backend.js.map +1 -1
- package/dist/runtime/subsystems/events/event-bus.redis-backend.js +5 -1
- package/dist/runtime/subsystems/events/event-bus.redis-backend.js.map +1 -1
- package/dist/runtime/subsystems/events/events.module.js +5 -1
- package/dist/runtime/subsystems/events/events.module.js.map +1 -1
- package/dist/runtime/subsystems/events/events.tokens.d.ts +5 -11
- package/dist/runtime/subsystems/events/events.tokens.js +5 -1
- package/dist/runtime/subsystems/events/events.tokens.js.map +1 -1
- package/dist/runtime/subsystems/events/generated/bus.js +5 -0
- package/dist/runtime/subsystems/events/generated/bus.js.map +1 -1
- package/dist/runtime/subsystems/events/generated/index.js +5 -0
- package/dist/runtime/subsystems/events/generated/index.js.map +1 -1
- package/dist/runtime/subsystems/events/index.js +5 -1
- package/dist/runtime/subsystems/events/index.js.map +1 -1
- package/dist/runtime/subsystems/index.d.ts +3 -3
- package/dist/runtime/subsystems/index.js +34 -26
- package/dist/runtime/subsystems/index.js.map +1 -1
- package/dist/runtime/subsystems/integration/incremental-read.d.ts +35 -8
- package/dist/runtime/subsystems/integration/incremental-read.js +9 -6
- package/dist/runtime/subsystems/integration/incremental-read.js.map +1 -1
- package/dist/runtime/subsystems/integration/index.d.ts +1 -1
- package/dist/runtime/subsystems/integration/index.js +9 -6
- package/dist/runtime/subsystems/integration/index.js.map +1 -1
- package/dist/runtime/subsystems/jobs/bullmq.config.d.ts +0 -9
- package/dist/runtime/subsystems/jobs/bullmq.config.js +6 -2
- package/dist/runtime/subsystems/jobs/bullmq.config.js.map +1 -1
- package/dist/runtime/subsystems/jobs/index.d.ts +1 -1
- package/dist/runtime/subsystems/jobs/index.js +13 -9
- package/dist/runtime/subsystems/jobs/index.js.map +1 -1
- package/dist/runtime/subsystems/jobs/job-handler.base.d.ts +1 -1
- package/dist/runtime/subsystems/jobs/job-handler.base.js +5 -1
- package/dist/runtime/subsystems/jobs/job-handler.base.js.map +1 -1
- package/dist/runtime/subsystems/jobs/job-orchestrator.bullmq-backend.d.ts +1 -1
- package/dist/runtime/subsystems/jobs/job-orchestrator.bullmq-backend.js +10 -3
- package/dist/runtime/subsystems/jobs/job-orchestrator.bullmq-backend.js.map +1 -1
- package/dist/runtime/subsystems/jobs/job-orchestrator.drizzle-backend.d.ts +1 -1
- package/dist/runtime/subsystems/jobs/job-orchestrator.drizzle-backend.js +8 -1
- package/dist/runtime/subsystems/jobs/job-orchestrator.drizzle-backend.js.map +1 -1
- package/dist/runtime/subsystems/jobs/job-orchestrator.memory-backend.d.ts +1 -1
- package/dist/runtime/subsystems/jobs/job-orchestrator.memory-backend.js +9 -1
- package/dist/runtime/subsystems/jobs/job-orchestrator.memory-backend.js.map +1 -1
- package/dist/runtime/subsystems/jobs/job-orchestrator.protocol.d.ts +1 -1
- package/dist/runtime/subsystems/jobs/job-run-keyset-cursor.d.ts +1 -1
- package/dist/runtime/subsystems/jobs/job-run-service.drizzle-backend.d.ts +1 -1
- package/dist/runtime/subsystems/jobs/job-run-service.drizzle-backend.js +8 -2
- package/dist/runtime/subsystems/jobs/job-run-service.drizzle-backend.js.map +1 -1
- package/dist/runtime/subsystems/jobs/job-run-service.memory-backend.d.ts +1 -1
- package/dist/runtime/subsystems/jobs/job-run-service.memory-backend.js +8 -2
- package/dist/runtime/subsystems/jobs/job-run-service.memory-backend.js.map +1 -1
- package/dist/runtime/subsystems/jobs/job-run-service.protocol.d.ts +1 -1
- package/dist/runtime/subsystems/jobs/job-worker.bullmq-backend.d.ts +1 -1
- package/dist/runtime/subsystems/jobs/job-worker.bullmq-backend.js +5 -0
- package/dist/runtime/subsystems/jobs/job-worker.bullmq-backend.js.map +1 -1
- package/dist/runtime/subsystems/jobs/job-worker.d.ts +1 -1
- package/dist/runtime/subsystems/jobs/job-worker.js +10 -4
- package/dist/runtime/subsystems/jobs/job-worker.js.map +1 -1
- package/dist/runtime/subsystems/jobs/job-worker.module.d.ts +5 -2
- package/dist/runtime/subsystems/jobs/job-worker.module.js +13 -8
- package/dist/runtime/subsystems/jobs/job-worker.module.js.map +1 -1
- package/dist/runtime/subsystems/jobs/jobs-domain.module.js +11 -6
- package/dist/runtime/subsystems/jobs/jobs-domain.module.js.map +1 -1
- package/dist/runtime/subsystems/jobs/jobs-domain.tokens.d.ts +0 -11
- package/dist/runtime/subsystems/jobs/jobs-domain.tokens.js +8 -4
- package/dist/runtime/subsystems/jobs/jobs-domain.tokens.js.map +1 -1
- package/dist/runtime/subsystems/jobs/jobs-errors.d.ts +1 -1
- package/dist/runtime/subsystems/observability/index.d.ts +1 -1
- package/dist/runtime/subsystems/observability/index.js +9 -1
- package/dist/runtime/subsystems/observability/index.js.map +1 -1
- package/dist/runtime/subsystems/observability/observability.module.js +9 -1
- package/dist/runtime/subsystems/observability/observability.module.js.map +1 -1
- package/dist/runtime/subsystems/observability/observability.protocol.d.ts +1 -1
- package/dist/runtime/subsystems/observability/observability.service.d.ts +1 -1
- package/dist/runtime/subsystems/observability/observability.service.js +9 -1
- package/dist/runtime/subsystems/observability/observability.service.js.map +1 -1
- package/dist/runtime/subsystems/observability/reporters/bridge-metrics.reporter.d.ts +1 -1
- package/dist/runtime/subsystems/observability/reporters/index.d.ts +1 -1
- package/dist/runtime/subsystems/storage/index.js +5 -1
- package/dist/runtime/subsystems/storage/index.js.map +1 -1
- package/dist/runtime/subsystems/storage/storage.module.js +5 -1
- package/dist/runtime/subsystems/storage/storage.module.js.map +1 -1
- package/dist/runtime/subsystems/storage/storage.tokens.d.ts +0 -8
- package/dist/runtime/subsystems/storage/storage.tokens.js +5 -1
- package/dist/runtime/subsystems/storage/storage.tokens.js.map +1 -1
- package/dist/runtime/subsystems/token-key.d.ts +7 -0
- package/dist/runtime/subsystems/token-key.js +8 -0
- package/dist/runtime/subsystems/token-key.js.map +1 -0
- package/dist/src/cli/index.js +362 -233
- package/dist/src/cli/index.js.map +1 -1
- package/package.json +5 -1
- package/runtime/subsystems/analytics/analytics.tokens.ts +6 -2
- package/runtime/subsystems/auth/auth.tokens.ts +15 -8
- package/runtime/subsystems/cache/cache.tokens.ts +7 -2
- package/runtime/subsystems/events/events.tokens.ts +8 -1
- package/runtime/subsystems/index.ts +6 -1
- package/runtime/subsystems/integration/incremental-read.ts +43 -9
- package/runtime/subsystems/integration/index.ts +1 -0
- package/runtime/subsystems/jobs/bullmq.config.ts +5 -2
- package/runtime/subsystems/jobs/job-handler.base.ts +6 -1
- package/runtime/subsystems/jobs/job-worker.module.ts +5 -1
- package/runtime/subsystems/jobs/job-worker.ts +4 -1
- package/runtime/subsystems/jobs/jobs-domain.tokens.ts +10 -7
- package/runtime/subsystems/storage/storage.tokens.ts +6 -1
- package/runtime/subsystems/token-key.ts +7 -0
- package/src/config/runtime-mode.mjs +82 -0
- package/templates/entity/new/backend/modules/core/integration-source.ejs.t +3 -2
- package/templates/entity/new/clean-lite-ps/controller.ejs.t +1 -1
- package/templates/entity/new/clean-lite-ps/module.ejs.t +1 -1
- package/templates/entity/new/clean-lite-ps/prompt-extension.js +8 -2
- package/templates/entity/new/clean-lite-ps/repository.ejs.t +4 -4
- package/templates/entity/new/clean-lite-ps/service.ejs.t +4 -4
- package/templates/entity/new/prompt.js +49 -10
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pattern-stack/codegen",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"description": "Entity-driven code generation for full-stack TypeScript applications",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -31,6 +31,10 @@
|
|
|
31
31
|
"types": "./dist/runtime/subsystems/index.d.ts",
|
|
32
32
|
"default": "./dist/runtime/subsystems/index.js"
|
|
33
33
|
},
|
|
34
|
+
"./runtime/shared/openapi": {
|
|
35
|
+
"types": "./dist/runtime/shared/openapi/index.d.ts",
|
|
36
|
+
"default": "./dist/runtime/shared/openapi/index.js"
|
|
37
|
+
},
|
|
34
38
|
"./runtime/*": {
|
|
35
39
|
"types": "./dist/runtime/*.d.ts",
|
|
36
40
|
"default": "./dist/runtime/*.js"
|
|
@@ -9,16 +9,20 @@
|
|
|
9
9
|
* constructor(@Inject(ANALYTICS_QUERY) private readonly analytics: IAnalyticsQuery) {}
|
|
10
10
|
* ```
|
|
11
11
|
*/
|
|
12
|
+
import { tokenKey } from '../token-key';
|
|
13
|
+
|
|
12
14
|
export const ANALYTICS_QUERY = 'ANALYTICS_QUERY' as const;
|
|
13
15
|
|
|
16
|
+
// ADR-037: namespaced `Symbol.for(...)` keys (via `tokenKey()`) so these tokens
|
|
17
|
+
// match by value across import boundaries (package vs vendored runtime copy).
|
|
14
18
|
/**
|
|
15
19
|
* Injection token for the cube.js API URL.
|
|
16
20
|
* Provided automatically by AnalyticsModule.forRoot({ backend: 'cube' }).
|
|
17
21
|
*/
|
|
18
|
-
export const CUBE_API_URL = Symbol('
|
|
22
|
+
export const CUBE_API_URL = Symbol.for(tokenKey('analytics', 'cube-api-url'));
|
|
19
23
|
|
|
20
24
|
/**
|
|
21
25
|
* Injection token for the cube.js API secret.
|
|
22
26
|
* Provided automatically by AnalyticsModule.forRoot({ backend: 'cube' }).
|
|
23
27
|
*/
|
|
24
|
-
export const CUBE_API_SECRET = Symbol('
|
|
28
|
+
export const CUBE_API_SECRET = Symbol.for(tokenKey('analytics', 'cube-api-secret'));
|
|
@@ -26,15 +26,22 @@
|
|
|
26
26
|
* `STRATEGY_REGISTRY` (a `ReadonlyMap<slug, IProviderStrategy>`), populated
|
|
27
27
|
* by per-provider modules via a `useFactory` provider.
|
|
28
28
|
*/
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
29
|
+
import { tokenKey } from '../token-key';
|
|
30
|
+
|
|
31
|
+
// ADR-037: namespaced `Symbol.for(...)` keys so a token matches by VALUE across
|
|
32
|
+
// import boundaries — the package copy and a (legacy) vendored copy resolve to
|
|
33
|
+
// the SAME symbol, eliminating the dual-package DI-token identity hazard that
|
|
34
|
+
// crashed boot once the emitter began emitting `STRATEGY_REGISTRY` as a runtime
|
|
35
|
+
// value (RFC-0003 R5). Matches the convention surface packages already use.
|
|
36
|
+
export const ENCRYPTION_KEY = Symbol.for(tokenKey('auth', 'encryption-key'));
|
|
37
|
+
export const OAUTH_STATE_STORE = Symbol.for(tokenKey('auth', 'oauth-state-store'));
|
|
38
|
+
export const AUTH_CONNECTION_READER = Symbol.for(tokenKey('auth', 'connection-reader'));
|
|
39
|
+
export const AUTH_CONNECTION_TOKEN_WRITER = Symbol.for(tokenKey('auth', 'connection-token-writer'));
|
|
40
|
+
export const AUTH_CONNECTION_GRANT_SINK = Symbol.for(tokenKey('auth', 'connection-grant-sink'));
|
|
41
|
+
export const AUTH_USER_CONTEXT = Symbol.for(tokenKey('auth', 'user-context'));
|
|
42
|
+
export const STRATEGY_REGISTRY = Symbol.for(tokenKey('auth', 'strategy-registry'));
|
|
36
43
|
/**
|
|
37
44
|
* Holds the resolved `AuthModuleOptions` (used by `AuthController` to read
|
|
38
45
|
* `redirectUriBase` for building per-provider callback URIs).
|
|
39
46
|
*/
|
|
40
|
-
export const AUTH_OPTIONS = Symbol('
|
|
47
|
+
export const AUTH_OPTIONS = Symbol.for(tokenKey('auth', 'options'));
|
|
@@ -7,11 +7,16 @@
|
|
|
7
7
|
* ```
|
|
8
8
|
*
|
|
9
9
|
* Services may also inject CACHE for reads (get, has) per ADR-003.
|
|
10
|
+
*
|
|
11
|
+
* ADR-037: namespaced `Symbol.for(...)` key (via `tokenKey()`) so the token matches
|
|
12
|
+
* by value across import boundaries (package vs vendored runtime copy).
|
|
10
13
|
*/
|
|
11
|
-
|
|
14
|
+
import { tokenKey } from '../token-key';
|
|
15
|
+
|
|
16
|
+
export const CACHE = Symbol.for(tokenKey('cache', 'cache'));
|
|
12
17
|
|
|
13
18
|
/**
|
|
14
19
|
* Injection token for the default TTL (in seconds) passed from CacheModule.forRoot().
|
|
15
20
|
* Optional — omit for no-expiry behavior.
|
|
16
21
|
*/
|
|
17
|
-
export const CACHE_DEFAULT_TTL = Symbol('
|
|
22
|
+
export const CACHE_DEFAULT_TTL = Symbol.for(tokenKey('cache', 'default-ttl'));
|
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
* constructor(@Inject(EVENT_BUS) private readonly eventBus: IEventBus) {}
|
|
10
10
|
* ```
|
|
11
11
|
*/
|
|
12
|
+
import { tokenKey } from '../token-key';
|
|
13
|
+
|
|
12
14
|
export const EVENT_BUS = 'EVENT_BUS' as const;
|
|
13
15
|
|
|
14
16
|
/**
|
|
@@ -61,8 +63,13 @@ export const EVENTS_MULTI_TENANT = 'EVENTS_MULTI_TENANT' as const;
|
|
|
61
63
|
/**
|
|
62
64
|
* Injection token for the Redis connection URL used by RedisEventBus.
|
|
63
65
|
* Provided automatically by EventsModule.forRoot({ backend: 'redis' }).
|
|
66
|
+
*
|
|
67
|
+
* ADR-037: namespaced `Symbol.for(...)` (via `tokenKey()`) so it matches by value
|
|
68
|
+
* across runtime copies (the sibling string tokens above are already value-stable).
|
|
69
|
+
* Note the jobs subsystem defines its own `REDIS_URL`-equivalent; this is the
|
|
70
|
+
* events one.
|
|
64
71
|
*/
|
|
65
|
-
export const REDIS_URL = Symbol('
|
|
72
|
+
export const REDIS_URL = Symbol.for(tokenKey('events', 'redis-url'));
|
|
66
73
|
|
|
67
74
|
/**
|
|
68
75
|
* Injection token for the resolved `EventsModuleOptions` object.
|
|
@@ -6,7 +6,11 @@
|
|
|
6
6
|
|
|
7
7
|
// Events
|
|
8
8
|
export { EVENT_BUS } from './events';
|
|
9
|
-
|
|
9
|
+
// `DrizzleTransaction` is re-exported here (not just from the `events` barrel)
|
|
10
|
+
// so package-mode generated code — which imports from the single
|
|
11
|
+
// `@pattern-stack/codegen/subsystems` barrel — resolves it (ADR-037). Vendored
|
|
12
|
+
// mode reaches it via `@shared/subsystems/events`; both must export it.
|
|
13
|
+
export type { DomainEvent, IEventBus, DrizzleTransaction } from './events';
|
|
10
14
|
export { EventsModule, DrizzleEventBus, MemoryEventBus } from './events';
|
|
11
15
|
|
|
12
16
|
// Jobs — orchestration schema only (JOB-1). Protocols / modules land in JOB-2 / JOB-5.
|
|
@@ -80,6 +84,7 @@ export {
|
|
|
80
84
|
export type {
|
|
81
85
|
IncrementalRead,
|
|
82
86
|
RandomRead,
|
|
87
|
+
ReadContext,
|
|
83
88
|
ReadMode,
|
|
84
89
|
ReadRequest,
|
|
85
90
|
Ref,
|
|
@@ -79,6 +79,26 @@ export interface ReadRequest<F = unknown> {
|
|
|
79
79
|
readonly pageSize?: number;
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
+
/**
|
|
83
|
+
* Per-run context threaded from `listChanges` into the vendor read body (R5).
|
|
84
|
+
*
|
|
85
|
+
* Carries the `subscription` framing the run so `enumerate`/`hydrate` can resolve
|
|
86
|
+
* **per-connection credentials** (and raw-landing keys) from
|
|
87
|
+
* `subscription.externalRef` — the gap a multi-account consumer surfaced: a
|
|
88
|
+
* singleton change source cannot hold connection-scoped auth, and before R5 the
|
|
89
|
+
* base forwarded the subscription only into `filterFor`, never into the fetch.
|
|
90
|
+
*
|
|
91
|
+
* Optional throughout (the core contract): a direct `read()` / `get()` call — the
|
|
92
|
+
* query surface's "fill one record on click" — may omit it. An adapter that needs
|
|
93
|
+
* per-connection auth reads `ctx?.subscription?.externalRef` and asserts its
|
|
94
|
+
* presence; a provider-level-auth adapter ignores it.
|
|
95
|
+
*/
|
|
96
|
+
export interface ReadContext {
|
|
97
|
+
/** The subscription framing this run; `externalRef` is the upstream scope /
|
|
98
|
+
* connection id the adapter resolves credentials + raw-landing keys from. */
|
|
99
|
+
readonly subscription?: IntegrationSubscriptionView;
|
|
100
|
+
}
|
|
101
|
+
|
|
82
102
|
/**
|
|
83
103
|
* The `read()`-side envelope: canonical record + the raw vendor payload it came
|
|
84
104
|
* from + the originating external id + the per-ref cursor.
|
|
@@ -101,7 +121,7 @@ export interface SourcedRecord<T> {
|
|
|
101
121
|
* hydration, and cursor emission are the providing base's concern.
|
|
102
122
|
*/
|
|
103
123
|
export interface IncrementalRead<T, F = unknown> {
|
|
104
|
-
read(req: ReadRequest<F
|
|
124
|
+
read(req: ReadRequest<F>, ctx?: ReadContext): AsyncIterable<SourcedRecord<T>>;
|
|
105
125
|
}
|
|
106
126
|
|
|
107
127
|
/**
|
|
@@ -111,7 +131,7 @@ export interface IncrementalRead<T, F = unknown> {
|
|
|
111
131
|
* surface.
|
|
112
132
|
*/
|
|
113
133
|
export interface RandomRead<T> {
|
|
114
|
-
get(id: string): Promise<T | null>;
|
|
134
|
+
get(id: string, ctx?: ReadContext): Promise<T | null>;
|
|
115
135
|
}
|
|
116
136
|
|
|
117
137
|
// ============================================================================
|
|
@@ -208,11 +228,16 @@ export abstract class IncrementalReadBase<T, F = unknown, M = Record<string, unk
|
|
|
208
228
|
* `pageSize` (from `ReadRequest`) is the adapter's requested vendor page size
|
|
209
229
|
* — also the atomic-cursor backfill blast-radius bound (§ `cursorDivisible`).
|
|
210
230
|
* Honor it as a hint; vendors that cap page size clamp it.
|
|
231
|
+
*
|
|
232
|
+
* `ctx?.subscription` (R5) carries the run's subscription, so a per-connection
|
|
233
|
+
* adapter resolves credentials / upstream scope from `externalRef` here; absent
|
|
234
|
+
* on a direct `read()` with no run subscription.
|
|
211
235
|
*/
|
|
212
236
|
protected abstract enumerate(
|
|
213
237
|
mode: ReadMode,
|
|
214
238
|
filter?: F,
|
|
215
239
|
pageSize?: number,
|
|
240
|
+
ctx?: ReadContext,
|
|
216
241
|
): AsyncIterable<Ref<M>[]>;
|
|
217
242
|
|
|
218
243
|
/**
|
|
@@ -221,8 +246,12 @@ export abstract class IncrementalReadBase<T, F = unknown, M = Record<string, unk
|
|
|
221
246
|
* alignment. Write it over `mapConcurrent(ids, (id) => this.fetchOne(id),
|
|
222
247
|
* this.hydrateConcurrency)`; override with a real `/batch` call or a
|
|
223
248
|
* passthrough (full-object list) where the vendor allows.
|
|
249
|
+
*
|
|
250
|
+
* `ctx?.subscription` (R5) carries the run's subscription for per-connection
|
|
251
|
+
* credential resolution (the fetch is where the vendor call happens) and is the
|
|
252
|
+
* natural place to land raw payloads keyed by `subscription.id`.
|
|
224
253
|
*/
|
|
225
|
-
protected abstract hydrate(ids: string[]): Promise<Map<string, unknown>>;
|
|
254
|
+
protected abstract hydrate(ids: string[], ctx?: ReadContext): Promise<Map<string, unknown>>;
|
|
226
255
|
|
|
227
256
|
/** Provider payload → canonical record. Return `null` to drop a record. */
|
|
228
257
|
protected abstract toCanonical(raw: unknown): T | null;
|
|
@@ -256,11 +285,14 @@ export abstract class IncrementalReadBase<T, F = unknown, M = Record<string, unk
|
|
|
256
285
|
* adapter cannot hydrate-then-discard. A hydrate miss (deleted mid-run) is
|
|
257
286
|
* skipped, never fabricated.
|
|
258
287
|
*/
|
|
259
|
-
async *read(req: ReadRequest<F
|
|
260
|
-
for await (const refPage of this.enumerate(req.mode, req.filter, req.pageSize)) {
|
|
288
|
+
async *read(req: ReadRequest<F>, ctx?: ReadContext): AsyncIterable<SourcedRecord<T>> {
|
|
289
|
+
for await (const refPage of this.enumerate(req.mode, req.filter, req.pageSize, ctx)) {
|
|
261
290
|
const kept = refPage.filter((ref) => this.matchesRef(ref, req.filter));
|
|
262
291
|
if (kept.length === 0) continue;
|
|
263
|
-
const raws = await this.hydrate(
|
|
292
|
+
const raws = await this.hydrate(
|
|
293
|
+
kept.map((ref) => ref.externalId),
|
|
294
|
+
ctx,
|
|
295
|
+
);
|
|
264
296
|
for (const ref of kept) {
|
|
265
297
|
const raw = raws.get(ref.externalId);
|
|
266
298
|
if (raw === undefined || raw === null) continue; // deleted mid-run → skip
|
|
@@ -277,8 +309,8 @@ export abstract class IncrementalReadBase<T, F = unknown, M = Record<string, unk
|
|
|
277
309
|
* `toCanonical ∘ hydrate([id])`. Reuses the adapter's batched fetch + miss
|
|
278
310
|
* tolerance; returns `null` for a missing or undecodable record.
|
|
279
311
|
*/
|
|
280
|
-
async get(id: string): Promise<T | null> {
|
|
281
|
-
const raws = await this.hydrate([id]);
|
|
312
|
+
async get(id: string, ctx?: ReadContext): Promise<T | null> {
|
|
313
|
+
const raws = await this.hydrate([id], ctx);
|
|
282
314
|
const raw = raws.get(id);
|
|
283
315
|
if (raw === undefined || raw === null) return null;
|
|
284
316
|
return this.toCanonical(raw);
|
|
@@ -308,7 +340,9 @@ export abstract class IncrementalReadBase<T, F = unknown, M = Record<string, unk
|
|
|
308
340
|
? { kind: 'full' }
|
|
309
341
|
: { kind: 'delta', cursor };
|
|
310
342
|
const filter = this.filterFor(subscription);
|
|
311
|
-
|
|
343
|
+
// R5: thread the run's subscription into the read body so `enumerate`/`hydrate`
|
|
344
|
+
// can resolve per-connection credentials (and raw-landing keys) from it.
|
|
345
|
+
const stream = this.read({ mode, filter }, { subscription });
|
|
312
346
|
|
|
313
347
|
if (this.cursorDivisible) {
|
|
314
348
|
for await (const sourced of stream) {
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* `jobs.extensions.bullmq.*` config namespace (CLAUDE.md core/extension
|
|
7
7
|
* protocol). The Drizzle backend never reads any of it.
|
|
8
8
|
*/
|
|
9
|
+
import { tokenKey } from '../token-key';
|
|
9
10
|
import { loadPoolConfig, type PoolConfig } from './pool-config.loader';
|
|
10
11
|
|
|
11
12
|
/**
|
|
@@ -78,11 +79,13 @@ export interface BullMqResolvedConfig {
|
|
|
78
79
|
bullBoard?: { enabled: boolean; mountPath: string };
|
|
79
80
|
}
|
|
80
81
|
|
|
82
|
+
// ADR-037: namespaced `Symbol.for(...)` (via `tokenKey()`) — matches by value
|
|
83
|
+
// across runtime copies.
|
|
81
84
|
/** DI token for the resolved BullMQ `ConnectionOptions` (ioredis-compatible). */
|
|
82
|
-
export const BULLMQ_CONNECTION = Symbol('
|
|
85
|
+
export const BULLMQ_CONNECTION = Symbol.for(tokenKey('jobs', 'bullmq-connection'));
|
|
83
86
|
|
|
84
87
|
/** DI token for the full resolved BullMQ config (prefix + bull board). */
|
|
85
|
-
export const BULLMQ_RESOLVED_CONFIG = Symbol('
|
|
88
|
+
export const BULLMQ_RESOLVED_CONFIG = Symbol.for(tokenKey('jobs', 'bullmq-resolved-config'));
|
|
86
89
|
|
|
87
90
|
const DEFAULT_REDIS_URL = 'redis://localhost:6379';
|
|
88
91
|
const DEFAULT_BULL_BOARD_MOUNT = '/admin/queues';
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
*/
|
|
17
17
|
// TODO(logging-subsystem): swap to ILogger once ADR-028 lands
|
|
18
18
|
import type { Logger } from '@nestjs/common';
|
|
19
|
+
import { tokenKey } from '../token-key';
|
|
19
20
|
import type { EventOfType, EventTypeName } from '../events/generated/types';
|
|
20
21
|
import type { JobRun } from './job-orchestrator.protocol';
|
|
21
22
|
|
|
@@ -160,7 +161,11 @@ export const JOB_HANDLER_REGISTRY = new Map<
|
|
|
160
161
|
}
|
|
161
162
|
>();
|
|
162
163
|
|
|
163
|
-
|
|
164
|
+
// ADR-037: namespaced `Symbol.for(...)` (via `tokenKey()`) so the reflection-metadata
|
|
165
|
+
// key matches by value across import boundaries (the @JobHandler decorator and the
|
|
166
|
+
// reader may resolve different runtime copies). Distinct from the DI tokens but
|
|
167
|
+
// subject to the same dual-package identity hazard.
|
|
168
|
+
export const JOB_HANDLER_METADATA_KEY = Symbol.for(tokenKey('jobs', 'handler-metadata'));
|
|
164
169
|
|
|
165
170
|
/**
|
|
166
171
|
* Class decorator that registers a handler with the job type, the full
|
|
@@ -30,6 +30,7 @@ import {
|
|
|
30
30
|
type OnModuleInit,
|
|
31
31
|
} from '@nestjs/common';
|
|
32
32
|
import { ModuleRef } from '@nestjs/core';
|
|
33
|
+
import { tokenKey } from '../token-key';
|
|
33
34
|
import { DRIZZLE } from '../../constants/tokens';
|
|
34
35
|
import type { DrizzleClient } from '../../types/drizzle';
|
|
35
36
|
import { HandlerRegistry, type HandlerRegistryEntry } from './job-handler.base';
|
|
@@ -128,8 +129,11 @@ export interface JobWorkerModuleOptions {
|
|
|
128
129
|
* configuration — e.g. `BridgeModule.onModuleInit` checks
|
|
129
130
|
* `options.pools` against `BRIDGE_RESERVED_POOLS` to fail fast when a
|
|
130
131
|
* reserved pool isn't being polled (BRIDGE-8).
|
|
132
|
+
*
|
|
133
|
+
* ADR-037: namespaced `Symbol.for(...)` (via `tokenKey()`) — matches by value
|
|
134
|
+
* across runtime copies.
|
|
131
135
|
*/
|
|
132
|
-
export const JOB_WORKER_MODULE_OPTIONS = Symbol('
|
|
136
|
+
export const JOB_WORKER_MODULE_OPTIONS = Symbol.for(tokenKey('jobs', 'worker-module-options'));
|
|
133
137
|
|
|
134
138
|
/**
|
|
135
139
|
* The lifecycle holder. Named `JobWorkerOrchestrator` in the spec to avoid
|
|
@@ -17,6 +17,7 @@ import { Inject, Injectable, Logger, type OnModuleDestroy, type OnModuleInit } f
|
|
|
17
17
|
import { ModuleRef } from '@nestjs/core';
|
|
18
18
|
import { and, asc, desc, eq, inArray, lt, lte, sql } from 'drizzle-orm';
|
|
19
19
|
import type { DrizzleClient } from '../../types/drizzle';
|
|
20
|
+
import { tokenKey } from '../token-key';
|
|
20
21
|
import { DRIZZLE } from '../../constants/tokens';
|
|
21
22
|
import { jobRuns, type JobRunRow } from './job-orchestration.schema';
|
|
22
23
|
import type { IJobOrchestrator, JobRun } from './job-orchestrator.protocol';
|
|
@@ -60,7 +61,9 @@ export interface JobWorkerOptions {
|
|
|
60
61
|
shutdownTimeoutMs?: number;
|
|
61
62
|
}
|
|
62
63
|
|
|
63
|
-
|
|
64
|
+
// ADR-037: namespaced `Symbol.for(...)` (via `tokenKey()`) — matches by value
|
|
65
|
+
// across runtime copies.
|
|
66
|
+
export const JOB_WORKER_OPTIONS = Symbol.for(tokenKey('jobs', 'worker-options'));
|
|
64
67
|
|
|
65
68
|
const DEFAULT_POLL_INTERVAL_MS = 1_000;
|
|
66
69
|
const DEFAULT_STALE_SWEEPER_INTERVAL_MS = 60_000;
|
|
@@ -5,13 +5,16 @@
|
|
|
5
5
|
* concrete backends (JOB-3 Drizzle, JOB-4 Memory) provide the implementations
|
|
6
6
|
* through `JobsDomainModule.forRoot({ backend })` in JOB-5.
|
|
7
7
|
*
|
|
8
|
-
* Each token is a
|
|
9
|
-
*
|
|
10
|
-
*
|
|
8
|
+
* Each token is a namespaced `Symbol.for(...)` (ADR-037, via `tokenKey()`) —
|
|
9
|
+
* distinct per key, so Nest's DI lookup is unambiguous, AND matching by VALUE
|
|
10
|
+
* across import boundaries so the package and a (legacy) vendored runtime copy
|
|
11
|
+
* resolve to the same symbol.
|
|
11
12
|
*/
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
export const
|
|
13
|
+
import { tokenKey } from '../token-key';
|
|
14
|
+
|
|
15
|
+
export const JOB_ORCHESTRATOR = Symbol.for(tokenKey('jobs', 'orchestrator'));
|
|
16
|
+
export const JOB_RUN_SERVICE = Symbol.for(tokenKey('jobs', 'run-service'));
|
|
17
|
+
export const JOB_STEP_SERVICE = Symbol.for(tokenKey('jobs', 'step-service'));
|
|
15
18
|
|
|
16
19
|
/**
|
|
17
20
|
* Multi-tenancy opt-in flag (JOB-8). Bound to the boolean passed in via
|
|
@@ -27,4 +30,4 @@ export const JOB_STEP_SERVICE = Symbol('JOB_STEP_SERVICE');
|
|
|
27
30
|
* tenant context; `tenantId` is populated at write time and enforced on
|
|
28
31
|
* targeted reads. See docs/specs/JOB-8.md.
|
|
29
32
|
*/
|
|
30
|
-
export const JOBS_MULTI_TENANT = Symbol('
|
|
33
|
+
export const JOBS_MULTI_TENANT = Symbol.for(tokenKey('jobs', 'multi-tenant'));
|
|
@@ -5,5 +5,10 @@
|
|
|
5
5
|
* ```typescript
|
|
6
6
|
* constructor(@Inject(STORAGE) private readonly storage: IStorageService) {}
|
|
7
7
|
* ```
|
|
8
|
+
*
|
|
9
|
+
* ADR-037: namespaced `Symbol.for(...)` key (via `tokenKey()`) so the token matches
|
|
10
|
+
* by value across import boundaries (package vs vendored runtime copy).
|
|
8
11
|
*/
|
|
9
|
-
|
|
12
|
+
import { tokenKey } from '../token-key';
|
|
13
|
+
|
|
14
|
+
export const STORAGE = Symbol.for(tokenKey('storage', 'storage'));
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Canonical package namespace for cross-boundary DI token keys. MUST be a hardcoded
|
|
2
|
+
* constant (NOT derived from package.json) so a vendored copy — which lives inside the
|
|
3
|
+
* CONSUMER's package — produces the identical key and the two copies share the symbol. */
|
|
4
|
+
export const PKG = '@pattern-stack/codegen';
|
|
5
|
+
// TODO(token-version): if/when a runtime contract version is adopted, inject it HERE only
|
|
6
|
+
// (e.g. `${PKG}#${ABI}.${area}.${name}`) — this helper is the single chokepoint.
|
|
7
|
+
export const tokenKey = (area: string, name: string): string => `${PKG}.${area}.${name}`;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime mode resolver — `.mjs` twin of `src/cli/shared/runtime-import.ts`
|
|
3
|
+
* (ADR-037), for the Hygen entity templates that run in a subprocess and can
|
|
4
|
+
* only import plain ESM. Keep the two in sync: both map a runtime mode +
|
|
5
|
+
* logical subpath to the concrete import specifier.
|
|
6
|
+
*
|
|
7
|
+
* - `package` → `@pattern-stack/codegen/subsystems` +
|
|
8
|
+
* `@pattern-stack/codegen/runtime/<relpath>`.
|
|
9
|
+
* - `vendored` → `@shared/subsystems/<name>` + `@shared/<relpath>` (the
|
|
10
|
+
* convention the entity templates have always emitted).
|
|
11
|
+
*
|
|
12
|
+
* NOT routed through here: consumer-app files the package never owns and that
|
|
13
|
+
* `project init` always scaffolds locally regardless of mode —
|
|
14
|
+
* `@shared/database/*`, `@shared/http/*`, `@shared/openapi`, `@shared/pipes/*`,
|
|
15
|
+
* `@shared/connections/*`. Those stay `@shared/*` in both modes.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import fs from "node:fs";
|
|
19
|
+
import path from "node:path";
|
|
20
|
+
import yaml from "yaml";
|
|
21
|
+
|
|
22
|
+
const PACKAGE = "@pattern-stack/codegen";
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Read the `runtime` mode from `codegen.config.yaml` at `cwd`. Defaults to
|
|
26
|
+
* `package` (ADR-037) when the file/key is absent or invalid.
|
|
27
|
+
* @returns {'package' | 'vendored'}
|
|
28
|
+
*/
|
|
29
|
+
export function loadRuntimeMode(cwd = process.cwd()) {
|
|
30
|
+
const configPath = path.resolve(cwd, "codegen.config.yaml");
|
|
31
|
+
if (!fs.existsSync(configPath)) return "package";
|
|
32
|
+
try {
|
|
33
|
+
const parsed = yaml.parse(fs.readFileSync(configPath, "utf-8"));
|
|
34
|
+
return parsed?.runtime === "vendored" ? "vendored" : "package";
|
|
35
|
+
} catch {
|
|
36
|
+
return "package";
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Import specifier for a subsystem barrel.
|
|
42
|
+
* @param {'package' | 'vendored'} mode
|
|
43
|
+
* @param {string} [subsystem] logical subsystem name (`events`, `integration`,
|
|
44
|
+
* `auth`, …) — selects the vendored per-subsystem barrel; ignored in package
|
|
45
|
+
* mode (one barrel serves all).
|
|
46
|
+
*/
|
|
47
|
+
export function subsystemsImport(mode, subsystem) {
|
|
48
|
+
if (mode === "vendored") {
|
|
49
|
+
return subsystem ? `@shared/subsystems/${subsystem}` : "@shared/subsystems";
|
|
50
|
+
}
|
|
51
|
+
return `${PACKAGE}/subsystems`;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Import specifier for a non-subsystem runtime file (base-classes, types,
|
|
56
|
+
* constants, helpers). `relpath` is the path under the runtime root WITHOUT a
|
|
57
|
+
* leading slash (e.g. `base-classes/integrated-entity-repository`,
|
|
58
|
+
* `constants/tokens`, `types/drizzle`, `eav-helpers`).
|
|
59
|
+
* @param {'package' | 'vendored'} mode
|
|
60
|
+
* @param {string} relpath
|
|
61
|
+
*/
|
|
62
|
+
export function runtimeImport(mode, relpath) {
|
|
63
|
+
const clean = String(relpath).replace(/^\/+/, "");
|
|
64
|
+
return mode === "vendored" ? `@shared/${clean}` : `${PACKAGE}/runtime/${clean}`;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Rewrite a legacy `@shared/<relpath>` specifier to the mode-correct form. Used
|
|
69
|
+
* to convert pattern-library base-class imports (authored as `@shared/...`) to
|
|
70
|
+
* the package form in package mode without duplicating the path in every
|
|
71
|
+
* pattern. A non-`@shared/` specifier (app-defined pattern alias, e.g.
|
|
72
|
+
* `@/patterns/...`) is returned untouched.
|
|
73
|
+
* @param {'package' | 'vendored'} mode
|
|
74
|
+
* @param {string} specifier
|
|
75
|
+
*/
|
|
76
|
+
export function rewriteSharedImport(mode, specifier) {
|
|
77
|
+
if (mode === "vendored") return specifier;
|
|
78
|
+
if (typeof specifier !== "string" || !specifier.startsWith("@shared/")) {
|
|
79
|
+
return specifier;
|
|
80
|
+
}
|
|
81
|
+
return runtimeImport(mode, specifier.slice("@shared/".length));
|
|
82
|
+
}
|
|
@@ -5,12 +5,13 @@ force: true
|
|
|
5
5
|
---
|
|
6
6
|
<%- typeof generatedBanner !== 'undefined' ? generatedBanner : '' %>
|
|
7
7
|
import { Module } from '@nestjs/common';
|
|
8
|
-
|
|
8
|
+
<% const _integSubsys = typeof integrationSubsystemImport !== 'undefined' ? integrationSubsystemImport : '@shared/subsystems/integration'; -%>
|
|
9
|
+
import { buildChangeSource } from '<%= _integSubsys %>';
|
|
9
10
|
import type {
|
|
10
11
|
DetectionConfig,
|
|
11
12
|
IChangeSource,
|
|
12
13
|
PollFetchCallback,
|
|
13
|
-
} from '
|
|
14
|
+
} from '<%= _integSubsys %>';
|
|
14
15
|
import type { <%= className %> } from '<%= isCleanLitePs ? clpImports.integrationSourceToEntity : imports.moduleToDomain %>';
|
|
15
16
|
|
|
16
17
|
const <%= name.toUpperCase() %>_DETECTION_CONFIGS: Record<string, DetectionConfig> = <%- detectionConfigsLiteral %>;
|
|
@@ -13,7 +13,7 @@ import { <%= classNames.findByIdWithFieldsUseCase %> } from './use-cases/find-<%
|
|
|
13
13
|
import { <%= classNames.listWithFieldsUseCase %> } from './use-cases/list-<%= entityNamePlural %>-with-fields.use-case';
|
|
14
14
|
<% } -%>
|
|
15
15
|
<% if (generateWrites) { -%>
|
|
16
|
-
import { ZodValidationPipe } from '@shared/pipes/zod-validation.pipe';
|
|
16
|
+
import { ZodValidationPipe } from '<%= typeof zodValidationPipeImport !== 'undefined' ? zodValidationPipeImport : '@shared/pipes/zod-validation.pipe' %>';
|
|
17
17
|
import { <%= classNames.createUseCase %> } from './use-cases/create-<%= entityName %>.use-case';
|
|
18
18
|
import { <%= classNames.updateUseCase %> } from './use-cases/update-<%= entityName %>.use-case';
|
|
19
19
|
import { <%= classNames.deleteUseCase %> } from './use-cases/delete-<%= entityName %>.use-case';
|
|
@@ -12,7 +12,7 @@ force: true
|
|
|
12
12
|
*/
|
|
13
13
|
<% } -%>
|
|
14
14
|
import { Inject, Module, type OnModuleInit } from '@nestjs/common';
|
|
15
|
-
import { OPENAPI_REGISTRY, type OpenApiRegistry } from '@shared/openapi';
|
|
15
|
+
import { OPENAPI_REGISTRY, type OpenApiRegistry } from '<%= typeof openApiImport !== 'undefined' ? openApiImport : '@shared/openapi' %>';
|
|
16
16
|
import { DatabaseModule } from '@shared/database/database.module';
|
|
17
17
|
<%_ /* CGP-358b: Import cross-entity repos needed for has_many composition */ _%>
|
|
18
18
|
<%_ if (typeof clpExistingHasMany !== 'undefined') { _%>
|
|
@@ -15,6 +15,7 @@ import pluralizePkg from 'pluralize';
|
|
|
15
15
|
// globs before this helper runs — we only read the registry here.
|
|
16
16
|
import { getPattern } from '../../../../src/patterns/registry.js';
|
|
17
17
|
import '../../../../src/patterns/library/index.js';
|
|
18
|
+
import { rewriteSharedImport } from '../../../../src/config/runtime-mode.mjs';
|
|
18
19
|
|
|
19
20
|
// ============================================================================
|
|
20
21
|
// Pattern registry resolution
|
|
@@ -1058,14 +1059,19 @@ export function buildCleanLitePsLocals(definition, baseLocals) {
|
|
|
1058
1059
|
// emitted output is byte-identical.
|
|
1059
1060
|
const patternBase = resolvePatternBaseClasses(entity);
|
|
1060
1061
|
const { patternName } = patternBase;
|
|
1062
|
+
// Runtime mode (ADR-037) — rewrite library base-class imports authored as
|
|
1063
|
+
// `@shared/base-classes/…` to the mode-correct form (package mode →
|
|
1064
|
+
// `@pattern-stack/codegen/runtime/base-classes/…`). App-defined pattern
|
|
1065
|
+
// aliases (non-`@shared/`) pass through untouched.
|
|
1066
|
+
const runtimeMode = baseLocals?.runtimeMode === 'vendored' ? 'vendored' : 'package';
|
|
1061
1067
|
// FAMILY_MAP is gone (PATTERN-5); `patternConfigClasses` is the structural
|
|
1062
1068
|
// equivalent — repository + service class names + import paths + inherited
|
|
1063
1069
|
// method comment lists, sourced directly from the pattern registry.
|
|
1064
1070
|
const patternConfigClasses = {
|
|
1065
1071
|
repositoryBaseClass: patternBase.repositoryBaseClass,
|
|
1066
1072
|
serviceBaseClass: patternBase.serviceBaseClass,
|
|
1067
|
-
repositoryBaseImport: patternBase.repositoryBaseImport,
|
|
1068
|
-
serviceBaseImport: patternBase.serviceBaseImport,
|
|
1073
|
+
repositoryBaseImport: rewriteSharedImport(runtimeMode, patternBase.repositoryBaseImport),
|
|
1074
|
+
serviceBaseImport: rewriteSharedImport(runtimeMode, patternBase.serviceBaseImport),
|
|
1069
1075
|
repositoryInheritedMethods: patternBase.repositoryInheritedMethods,
|
|
1070
1076
|
serviceInheritedMethods: patternBase.serviceInheritedMethods,
|
|
1071
1077
|
};
|
|
@@ -21,14 +21,14 @@ import { eq<%= hasMultiFieldQuery ? ', and' : '' %><%= hasOrderedQuery ? ', desc
|
|
|
21
21
|
<% if (eavValueTable) { -%>
|
|
22
22
|
import { sql } from 'drizzle-orm';
|
|
23
23
|
<% } -%>
|
|
24
|
-
import { DRIZZLE } from '@shared/constants/tokens';
|
|
25
|
-
import type { DrizzleClient<% if (eavValueTable || (typeof hasIntegrationSurface !== 'undefined' && hasIntegrationSurface)) { %>, DrizzleTx<% } %> } from '@shared/types/drizzle';
|
|
24
|
+
import { DRIZZLE } from '<%= typeof drizzleTokenImport !== 'undefined' ? drizzleTokenImport : '@shared/constants/tokens' %>';
|
|
25
|
+
import type { DrizzleClient<% if (eavValueTable || (typeof hasIntegrationSurface !== 'undefined' && hasIntegrationSurface)) { %>, DrizzleTx<% } %> } from '<%= typeof drizzleTypeImport !== 'undefined' ? drizzleTypeImport : '@shared/types/drizzle' %>';
|
|
26
26
|
import { <%= repositoryBaseClass %> } from '<%= repositoryBaseImport %>';
|
|
27
27
|
<% if (typeof hasIntegrationSurface !== 'undefined' && hasIntegrationSurface) { -%>
|
|
28
|
-
import type { IntegrationUpsertConfig } from '@shared/base-classes/integration-upsert-config';
|
|
28
|
+
import type { IntegrationUpsertConfig } from '<%= typeof integrationUpsertConfigImport !== 'undefined' ? integrationUpsertConfigImport : '@shared/base-classes/integration-upsert-config' %>';
|
|
29
29
|
<% } -%>
|
|
30
30
|
<% if (hasTimestamps || hasSoftDelete || hasUserTracking) { -%>
|
|
31
|
-
import type { BehaviorConfig } from '@shared/base-classes/base-repository';
|
|
31
|
+
import type { BehaviorConfig } from '<%= typeof baseRepositoryImport !== 'undefined' ? baseRepositoryImport : '@shared/base-classes/base-repository' %>';
|
|
32
32
|
<% } -%>
|
|
33
33
|
<% if (eavEnabled) { -%>
|
|
34
34
|
import { FieldValueService } from '../field_values/field_value.service';
|
|
@@ -5,8 +5,8 @@ force: true
|
|
|
5
5
|
---
|
|
6
6
|
<%- typeof generatedBanner !== 'undefined' ? generatedBanner : '' %>
|
|
7
7
|
import { Injectable, Inject, Optional } from '@nestjs/common';
|
|
8
|
-
import { WithAnalytics } from '@shared/base-classes/with-analytics';
|
|
9
|
-
import { EVENT_BUS } from '@shared/constants/tokens';
|
|
8
|
+
import { WithAnalytics } from '<%= typeof withAnalyticsImport !== 'undefined' ? withAnalyticsImport : '@shared/base-classes/with-analytics' %>';
|
|
9
|
+
import { EVENT_BUS } from '<%= typeof drizzleTokenImport !== 'undefined' ? drizzleTokenImport : '@shared/constants/tokens' %>';
|
|
10
10
|
import { <%= serviceBaseClass %> } from '<%= serviceBaseImport %>';
|
|
11
11
|
import { <%= classNames.repository %> } from './<%= entityName %>.repository';
|
|
12
12
|
import type { <%= classNames.entity %> } from './<%= entityName %>.entity';
|
|
@@ -14,8 +14,8 @@ import type { <%= classNames.entity %> } from './<%= entityName %>.entity';
|
|
|
14
14
|
import { FieldValueService } from '../field_values/field_value.service';
|
|
15
15
|
<% } -%>
|
|
16
16
|
<% if (eavValueTable) { -%>
|
|
17
|
-
import { toEavRows, mergeEavRows } from '@shared/eav-helpers';
|
|
18
|
-
import type { DrizzleTx } from '@shared/types/drizzle';
|
|
17
|
+
import { toEavRows, mergeEavRows } from '<%= typeof eavHelpersImport !== 'undefined' ? eavHelpersImport : '@shared/eav-helpers' %>';
|
|
18
|
+
import type { DrizzleTx } from '<%= typeof drizzleTypeImport !== 'undefined' ? drizzleTypeImport : '@shared/types/drizzle' %>';
|
|
19
19
|
import { <%= eavDefinitionPascal %>Repository } from '../<%= eavDefinitionEntityPlural %>/<%= eavDefinitionEntity %>.repository';
|
|
20
20
|
<% } -%>
|
|
21
21
|
<%_ /* CGP-358b — service-layer composition: import target repos for belongs_to relationships */ _%>
|