@pattern-stack/codegen 0.27.2 → 0.28.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/CHANGELOG.md +43 -0
- package/dist/{chunk-YQA5PMOD.js → chunk-3GMQKHJD.js} +2 -2
- package/dist/{chunk-5TK7MEN4.js → chunk-CPUSJPAP.js} +1 -1
- package/dist/{chunk-5TK7MEN4.js.map → chunk-CPUSJPAP.js.map} +1 -1
- package/dist/{chunk-PBENHIN2.js → chunk-IB733A6R.js} +2 -2
- package/dist/{chunk-YHVZAL6U.js → chunk-K6LH4PXZ.js} +2 -2
- package/dist/{chunk-XW4XKN3F.js → chunk-KS4BZHIA.js} +7 -7
- package/dist/{chunk-BK5ICA2F.js → chunk-RUSUZZAF.js} +4 -4
- package/dist/{chunk-7LKAMLV4.js → chunk-T6SCOJF4.js} +4 -4
- package/dist/{chunk-LQZESSM3.js → chunk-WE6DIDMM.js} +1 -1
- package/dist/chunk-WE6DIDMM.js.map +1 -0
- package/dist/{chunk-K4BQQ2NN.js → chunk-YUVEJNRE.js} +133 -10
- package/dist/chunk-YUVEJNRE.js.map +1 -0
- package/dist/{chunk-EGXFEZ2N.js → chunk-Z7YFYK6H.js} +4 -4
- package/dist/runtime/subsystems/auth/auth.module.js +2 -2
- package/dist/runtime/subsystems/auth/index.js +11 -11
- package/dist/runtime/subsystems/bridge/bridge.module.js +6 -6
- package/dist/runtime/subsystems/bridge/index.js +6 -6
- package/dist/runtime/subsystems/events/events.module.js +3 -3
- package/dist/runtime/subsystems/events/generated/bus.js +2 -2
- package/dist/runtime/subsystems/events/generated/index.js +2 -2
- package/dist/runtime/subsystems/events/generated/registry.d.ts +6 -0
- package/dist/runtime/subsystems/events/generated/registry.js +1 -1
- package/dist/runtime/subsystems/events/index.js +3 -3
- package/dist/runtime/subsystems/index.js +34 -34
- package/dist/runtime/subsystems/integration/detection-config.schema.d.ts +6 -4
- package/dist/runtime/subsystems/integration/detection-config.schema.js +1 -1
- package/dist/runtime/subsystems/integration/index.js +1 -1
- package/dist/runtime/subsystems/jobs/index.js +13 -13
- package/dist/runtime/subsystems/jobs/job-worker.module.js +5 -5
- package/dist/runtime/subsystems/jobs/jobs-domain.module.js +3 -3
- package/dist/runtime/subsystems/observability/index.js +3 -3
- package/dist/runtime/subsystems/storage/index.js +4 -4
- package/dist/runtime/subsystems/storage/storage.module.js +2 -2
- package/dist/src/cli/index.js +81 -25
- package/dist/src/cli/index.js.map +1 -1
- package/dist/src/index.js +2 -2
- package/package.json +1 -1
- package/runtime/subsystems/events/generated/registry.ts +1 -0
- package/runtime/subsystems/integration/detection-config.schema.ts +7 -5
- package/templates/entity/new/clean-lite-ps/dto/output.ejs.t +6 -0
- package/dist/chunk-K4BQQ2NN.js.map +0 -1
- package/dist/chunk-LQZESSM3.js.map +0 -1
- /package/dist/{chunk-YQA5PMOD.js.map → chunk-3GMQKHJD.js.map} +0 -0
- /package/dist/{chunk-PBENHIN2.js.map → chunk-IB733A6R.js.map} +0 -0
- /package/dist/{chunk-YHVZAL6U.js.map → chunk-K6LH4PXZ.js.map} +0 -0
- /package/dist/{chunk-XW4XKN3F.js.map → chunk-KS4BZHIA.js.map} +0 -0
- /package/dist/{chunk-BK5ICA2F.js.map → chunk-RUSUZZAF.js.map} +0 -0
- /package/dist/{chunk-7LKAMLV4.js.map → chunk-T6SCOJF4.js.map} +0 -0
- /package/dist/{chunk-EGXFEZ2N.js.map → chunk-Z7YFYK6H.js.map} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,49 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [0.28.0] — 2026-06-14
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **`trigger:` block on event definitions — a projectable workflow-trigger
|
|
10
|
+
catalog.** Event YAMLs may now declare an optional, strict
|
|
11
|
+
`trigger: { surface, label?, description?, fields[] }` block. Its presence
|
|
12
|
+
marks the event as a *selectable workflow trigger* — a domain change-fact an
|
|
13
|
+
automation can fire on — as opposed to inbound transport events whose only job
|
|
14
|
+
is to sync state. Selectability is an explicit opt-in, deliberately decoupled
|
|
15
|
+
from `direction`: a `direction: change` event can still be a non-trigger (e.g.
|
|
16
|
+
metadata-churn edits like read/label flips), so the block is simply omitted
|
|
17
|
+
there. The parsed `trigger` is emitted verbatim into
|
|
18
|
+
`eventRegistry[type].trigger` (and the `EventMetadata` interface), so consumers
|
|
19
|
+
**project** their authoring trigger catalog from the event registry instead of
|
|
20
|
+
hand-maintaining a parallel list that drifts from the event definitions.
|
|
21
|
+
Backward-compatible — events without a `trigger:` block emit no `trigger` key,
|
|
22
|
+
so existing generated registries are unchanged. Dogfood-driven from swe-brain's
|
|
23
|
+
directive authoring surface.
|
|
24
|
+
|
|
25
|
+
## [0.27.3] — 2026-06-13
|
|
26
|
+
|
|
27
|
+
### Fixed
|
|
28
|
+
|
|
29
|
+
- **Frontend lookups/resolver hydration no longer full-fetches every entity —
|
|
30
|
+
the LANDMINE-1 OOM guard.** `buildLookupsAsync` (store/lookups.ts) and
|
|
31
|
+
`hydrateResolverCache` (store/resolvers.ts) paged the COMPLETE table of *every*
|
|
32
|
+
entity via `api.listAll()` on the first `useData()` mount of *any* route, to
|
|
33
|
+
populate cross-entity FK-resolution maps. On a large content table this is
|
|
34
|
+
catastrophic: a swe-brain mailbox of 21,648 emails × ~33 KB `bodyHtml` pulled
|
|
35
|
+
~700 MB into the renderer and the browser silently OOM-killed the tab — on
|
|
36
|
+
every route, including ones that never read email. Dogfood discovery from
|
|
37
|
+
swe-brain. Fix: full-fetch an entity only if it is a **lookup target** (some
|
|
38
|
+
`belongs_to` resolves it by id → it backs a FieldMeta `reference`) **or** it
|
|
39
|
+
has no unbounded text column; heavy, non-target entities (a `text` field, or a
|
|
40
|
+
`string` with no `max_length`) are seeded from current collection state
|
|
41
|
+
instead — nothing resolves them by id, so the current page is all any consumer
|
|
42
|
+
can use. `api` imports for skipped entities are dropped so none dangle. See
|
|
43
|
+
`lookupFullFetchNames` in `emit-store.ts`. Known edge: an entity consumed as a
|
|
44
|
+
lookup ONLY via hand-authored `lookups.<plural>` access (not a FieldMeta
|
|
45
|
+
reference) that *also* has an unbounded string column would be skipped — give
|
|
46
|
+
it a bounded `max_length` or declare the FK so it registers as a target.
|
|
47
|
+
|
|
5
48
|
## [0.27.2] — 2026-06-08
|
|
6
49
|
|
|
7
50
|
### Fixed
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
} from "./chunk-NXXDZ6ZF.js";
|
|
25
25
|
import {
|
|
26
26
|
JOB_WORKER_MODULE_OPTIONS
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-Z7YFYK6H.js";
|
|
28
28
|
import {
|
|
29
29
|
BRIDGE_DELIVERY_REPO,
|
|
30
30
|
BRIDGE_MODULE_OPTIONS,
|
|
@@ -119,4 +119,4 @@ BridgeModule = __decorateClass([
|
|
|
119
119
|
export {
|
|
120
120
|
BridgeModule
|
|
121
121
|
};
|
|
122
|
-
//# sourceMappingURL=chunk-
|
|
122
|
+
//# sourceMappingURL=chunk-3GMQKHJD.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../runtime/subsystems/integration/detection-config.schema.ts"],"sourcesContent":["/**\n * Integration subsystem — DetectionConfig schema (#226-1)\n *\n * Canonical Zod schema for per-entity integration detection config. The schema is\n * the single source of truth for filter/mapping shape and is consumed by:\n *\n * 1. Runtime primitives — `PollChangeSource<T>`, `WebhookChangeSource<T>`\n * (#226-3, #226-4) accept a parsed `DetectionConfig` at construction.\n * 2. Codegen — `src/schema/entity-definition.schema.ts` (#226-6) imports\n * this schema so per-entity YAML `detection:` blocks validate against\n * the same shape the runtime enforces.\n *\n * Locked decisions (see ADR-033 + decision memo Q1–Q6):\n * - Filter vocabulary is flat AND of `{ field, op, value }` triples; richer\n * boolean expressions (OR / NOT / nested) are deferred per epic open Q3.\n * - Cursor strategy is a tagged union over the four shapes the three modes\n * need (`systemModstamp`, `replayId`, `timestamp`, `eventId`). Each\n * strategy types its cursor internally; the orchestrator persists what\n * the iterator last yielded (integration skill rule 2).\n * - `mode: 'poll'` may opt into `provenance: 'cdc'` so Stripe-style event\n * endpoints (mechanically a poll, semantically CDC) reuse the poll\n * primitive while emitting `Change<T>.source = 'cdc'`. Long-lived\n * streaming CDC (SFDC Pub-Sub, Debezium) is a separate primitive\n * deferred to #226-8.\n * - `webhook` mode's `eventIdField` is optional: `WebhookChangeSource<T>`\n * prefers an `eventId` yielded by the queue iterator and falls back to the\n * `eventIdField` record extraction (precedence: yielded eventId >\n * eventIdField extraction > undefined dedupKey).\n */\nimport { z } from \"zod\";\n\n// ============================================================================\n// Field mapping — provider field → canonical target\n// ============================================================================\n\n/**\n * Maps a single provider field onto the canonical record. `transform` is an\n * opt-in tag the adapter callback may inspect (`date-iso`, `decimal-string`,\n * etc.); the schema does not enumerate transforms — adapters interpret them.\n */\nexport const FieldMappingSchema = z.object({\n\tsource: z.string().min(1),\n\ttarget: z.string().min(1),\n\ttransform: z.string().min(1).optional(),\n});\n\nexport type FieldMapping = z.infer<typeof FieldMappingSchema>;\n\n// ============================================================================\n// Resolved filter — flat-AND triple\n// ============================================================================\n\n/**\n * A single resolved filter clause applied at fetch time. `value` is `unknown`\n * to admit primitives, arrays (for `in` / `nin`), and dates as ISO strings —\n * adapters interpret per provider.\n */\nexport const ResolvedFilterSchema = z.object({\n\tfield: z.string().min(1),\n\top: z.enum([\"eq\", \"neq\", \"in\", \"nin\", \"gt\", \"gte\", \"lt\", \"lte\"]),\n\tvalue: z.unknown(),\n});\n\nexport type ResolvedFilter = z.infer<typeof ResolvedFilterSchema>;\n\n// ============================================================================\n// Cursor strategy — tagged union over the four shapes the modes need\n// ============================================================================\n\nconst SystemModstampCursorSchema = z.object({\n\tkind: z.literal(\"systemModstamp\"),\n\tfield: z.string().min(1),\n});\n\nconst ReplayIdCursorSchema = z.object({\n\tkind: z.literal(\"replayId\"),\n\tfield: z.string().min(1),\n});\n\nconst TimestampCursorSchema = z.object({\n\tkind: z.literal(\"timestamp\"),\n\tfield: z.string().min(1),\n});\n\nconst EventIdCursorSchema = z.object({\n\tkind: z.literal(\"eventId\"),\n\tfield: z.string().min(1),\n});\n\n/**\n * Gmail `historyId` (RFC-0003 §3) — an opaque, atomic vendor token. The next\n * watermark only exists at end-of-walk; there is no resumable mid-walk value.\n * `field` is metadata for codegen/adapters (the response key the token lives on).\n */\nconst HistoryIdCursorSchema = z.object({\n\tkind: z.literal(\"historyId\"),\n\tfield: z.string().min(1),\n});\n\n/**\n * Google Calendar `syncToken` (RFC-0003 §3) — an opaque, atomic sync token,\n * same divisibility profile as `historyId`.\n */\nconst SyncTokenCursorSchema = z.object({\n\tkind: z.literal(\"syncToken\"),\n\tfield: z.string().min(1),\n});\n\nexport const CursorStrategySchema = z.discriminatedUnion(\"kind\", [\n\tSystemModstampCursorSchema,\n\tReplayIdCursorSchema,\n\tTimestampCursorSchema,\n\tEventIdCursorSchema,\n\tHistoryIdCursorSchema,\n\tSyncTokenCursorSchema,\n]);\n\nexport type CursorStrategy = z.infer<typeof CursorStrategySchema>;\n\n// ============================================================================\n// Cursor divisibility (RFC-0003 §3)\n// ============================================================================\n\n/**\n * Whether a cursor strategy is *divisible* — a property of the strategy, not\n * the read primitive. Divisible cursors are sortable/monotonic watermarks whose\n * value is meaningful AS OF any single record (HubSpot `systemModstamp`, a\n * `timestamp` field, a Salesforce CDC `replayId`); the read primitive may\n * checkpoint per-ref mid-walk, so a crash resumes from the last delivered ref.\n *\n * Atomic cursors are opaque vendor tokens (Gmail `historyId`, Calendar\n * `syncToken`, a generic `eventId`) whose next value only exists at end-of-walk.\n * The primitive must withhold per-ref cursors and emit the token only at a safe\n * boundary, so an interrupted run never persists an unresumable mid-walk token\n * (it resumes all-or-nothing from the prior token — see `IncrementalReadBase`).\n *\n * `eventId` is classified atomic conservatively: a generic opaque id is treated\n * all-or-nothing unless a concrete strategy proves it monotonically resumable.\n */\nexport const CURSOR_DIVISIBILITY: Readonly<\n\tRecord<CursorStrategy[\"kind\"], boolean>\n> = {\n\tsystemModstamp: true,\n\ttimestamp: true,\n\treplayId: true,\n\teventId: false,\n\thistoryId: false,\n\tsyncToken: false,\n};\n\n/** Predicate form of {@link CURSOR_DIVISIBILITY}. */\nexport function isDivisibleCursor(kind: CursorStrategy[\"kind\"]): boolean {\n\treturn CURSOR_DIVISIBILITY[kind];\n}\n\n// ============================================================================\n// Mode-specific blocks\n// ============================================================================\n\n/**\n * Poll-mode block. `provenance: 'cdc'` opts the poll primitive into stamping\n * `Change<T>.source = 'cdc'` and populating `dedupKey` from the cursor's\n * `field` — used for Stripe-style event endpoints. Defaults to `'poll'`.\n */\nexport const PollDetectionSchema = z.object({\n\tcursor: CursorStrategySchema,\n\tprovenance: z.enum([\"poll\", \"cdc\"]).optional(),\n});\n\nexport type PollDetection = z.infer<typeof PollDetectionSchema>;\n\n/**\n * Webhook-mode block. `eventIdField`, when present, names the field on the\n * emitted canonical record that `WebhookChangeSource<T>` reads to set\n * `Change<T>.dedupKey` — used only as the fallback when the queue iterator\n * does NOT yield an `eventId` alongside the record.\n *\n * `eventIdField` is **optional**: a queue iterator that always yields an\n * `eventId` (vendor delivery metadata, the preferred channel) need not declare\n * a record field for it. dedupKey precedence is: yielded `eventId` >\n * `eventIdField` record extraction > undefined.\n */\nexport const WebhookDetectionSchema = z.object({\n\teventIdField: z.string().min(1).optional(),\n});\n\nexport type WebhookDetection = z.infer<typeof WebhookDetectionSchema>;\n\n// ============================================================================\n// DetectionConfig — top-level discriminated union over `mode`\n// ============================================================================\n\nconst PollModeSchema = z.object({\n\tmode: z.literal(\"poll\"),\n\tpoll: PollDetectionSchema,\n\tmapping: z.array(FieldMappingSchema).min(1),\n\tfilters: z.array(ResolvedFilterSchema).default([]),\n});\n\nconst WebhookModeSchema = z.object({\n\tmode: z.literal(\"webhook\"),\n\twebhook: WebhookDetectionSchema,\n\tmapping: z.array(FieldMappingSchema).min(1),\n\tfilters: z.array(ResolvedFilterSchema).default([]),\n});\n\n/**\n * Top-level detection config. Discriminated on `mode` so the relevant\n * mode-block (poll/webhook) is structurally required for that mode. CDC as a\n * long-lived streaming primitive is deferred (#226-8); CDC-as-provenance\n * (Stripe-style event endpoints) is expressed via `mode: 'poll'` with\n * `poll.provenance: 'cdc'`.\n */\nexport const DetectionConfigSchema = z.discriminatedUnion(\"mode\", [\n\tPollModeSchema,\n\tWebhookModeSchema,\n]);\n\nexport type DetectionConfig = z.infer<typeof DetectionConfigSchema>;\n"],"mappings":";AA6BA,SAAS,SAAS;AAWX,IAAM,qBAAqB,EAAE,OAAO;AAAA,EAC1C,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACxB,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACxB,WAAW,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS;AACvC,CAAC;AAaM,IAAM,uBAAuB,EAAE,OAAO;AAAA,EAC5C,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACvB,IAAI,EAAE,KAAK,CAAC,MAAM,OAAO,MAAM,OAAO,MAAM,OAAO,MAAM,KAAK,CAAC;AAAA,EAC/D,OAAO,EAAE,QAAQ;AAClB,CAAC;AAQD,IAAM,6BAA6B,EAAE,OAAO;AAAA,EAC3C,MAAM,EAAE,QAAQ,gBAAgB;AAAA,EAChC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC;AACxB,CAAC;AAED,IAAM,uBAAuB,EAAE,OAAO;AAAA,EACrC,MAAM,EAAE,QAAQ,UAAU;AAAA,EAC1B,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC;AACxB,CAAC;AAED,IAAM,wBAAwB,EAAE,OAAO;AAAA,EACtC,MAAM,EAAE,QAAQ,WAAW;AAAA,EAC3B,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC;AACxB,CAAC;AAED,IAAM,sBAAsB,EAAE,OAAO;AAAA,EACpC,MAAM,EAAE,QAAQ,SAAS;AAAA,EACzB,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC;AACxB,CAAC;AAOD,IAAM,wBAAwB,EAAE,OAAO;AAAA,EACtC,MAAM,EAAE,QAAQ,WAAW;AAAA,EAC3B,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC;AACxB,CAAC;AAMD,IAAM,wBAAwB,EAAE,OAAO;AAAA,EACtC,MAAM,EAAE,QAAQ,WAAW;AAAA,EAC3B,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC;AACxB,CAAC;AAEM,IAAM,uBAAuB,EAAE,mBAAmB,QAAQ;AAAA,EAChE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD,CAAC;AAwBM,IAAM,sBAET;AAAA,EACH,gBAAgB;AAAA,EAChB,WAAW;AAAA,EACX,UAAU;AAAA,EACV,SAAS;AAAA,EACT,WAAW;AAAA,EACX,WAAW;AACZ;AAGO,SAAS,kBAAkB,MAAuC;AACxE,SAAO,oBAAoB,IAAI;AAChC;AAWO,IAAM,sBAAsB,EAAE,OAAO;AAAA,EAC3C,QAAQ;AAAA,EACR,YAAY,EAAE,KAAK,CAAC,QAAQ,KAAK,CAAC,EAAE,SAAS;AAC9C,CAAC;AAeM,IAAM,yBAAyB,EAAE,OAAO;AAAA,EAC9C,cAAc,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS;AAC1C,CAAC;AAQD,IAAM,iBAAiB,EAAE,OAAO;AAAA,EAC/B,MAAM,EAAE,QAAQ,MAAM;AAAA,EACtB,MAAM;AAAA,EACN,SAAS,EAAE,MAAM,kBAAkB,EAAE,IAAI,CAAC;AAAA,EAC1C,SAAS,EAAE,MAAM,oBAAoB,EAAE,QAAQ,CAAC,CAAC;AAClD,CAAC;AAED,IAAM,oBAAoB,EAAE,OAAO;AAAA,EAClC,MAAM,EAAE,QAAQ,SAAS;AAAA,EACzB,SAAS;AAAA,EACT,SAAS,EAAE,MAAM,kBAAkB,EAAE,IAAI,CAAC;AAAA,EAC1C,SAAS,EAAE,MAAM,oBAAoB,EAAE,QAAQ,CAAC,CAAC;AAClD,CAAC;AASM,IAAM,wBAAwB,EAAE,mBAAmB,QAAQ;AAAA,EACjE;AAAA,EACA;AACD,CAAC;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../runtime/subsystems/integration/detection-config.schema.ts"],"sourcesContent":["/**\n * Integration subsystem — DetectionConfig schema (#226-1)\n *\n * Canonical Zod schema for per-entity integration detection config. The schema is\n * the single source of truth for filter/mapping shape and is consumed by:\n *\n * 1. Runtime primitives — `PollChangeSource<T>`, `WebhookChangeSource<T>`\n * (#226-3, #226-4) accept a parsed `DetectionConfig` at construction.\n * 2. Codegen — `src/schema/entity-definition.schema.ts` (#226-6) imports\n * this schema so per-entity YAML `detection:` blocks validate against\n * the same shape the runtime enforces.\n *\n * Locked decisions (see ADR-033 + decision memo Q1–Q6):\n * - Filter vocabulary is flat AND of `{ field, op, value }` triples; richer\n * boolean expressions (OR / NOT / nested) are deferred per epic open Q3.\n * - Cursor strategy is a tagged union over the six shapes the modes need\n * (`systemModstamp`, `replayId`, `timestamp`, `eventId`, plus `historyId`\n * and `syncToken` added in RFC-0003). Each strategy types its cursor\n * internally; the orchestrator persists what the iterator last yielded\n * (integration skill rule 2). Divisibility per strategy is tabled in\n * `CURSOR_DIVISIBILITY` below.\n * - `mode: 'poll'` may opt into `provenance: 'cdc'` so Stripe-style event\n * endpoints (mechanically a poll, semantically CDC) reuse the poll\n * primitive while emitting `Change<T>.source = 'cdc'`. Long-lived\n * streaming CDC (SFDC Pub-Sub, Debezium) is a separate primitive\n * deferred to #226-8.\n * - `webhook` mode's `eventIdField` is optional: `WebhookChangeSource<T>`\n * prefers an `eventId` yielded by the queue iterator and falls back to the\n * `eventIdField` record extraction (precedence: yielded eventId >\n * eventIdField extraction > undefined dedupKey).\n */\nimport { z } from \"zod\";\n\n// ============================================================================\n// Field mapping — provider field → canonical target\n// ============================================================================\n\n/**\n * Maps a single provider field onto the canonical record. `transform` is an\n * opt-in tag the adapter callback may inspect (`date-iso`, `decimal-string`,\n * etc.); the schema does not enumerate transforms — adapters interpret them.\n */\nexport const FieldMappingSchema = z.object({\n\tsource: z.string().min(1),\n\ttarget: z.string().min(1),\n\ttransform: z.string().min(1).optional(),\n});\n\nexport type FieldMapping = z.infer<typeof FieldMappingSchema>;\n\n// ============================================================================\n// Resolved filter — flat-AND triple\n// ============================================================================\n\n/**\n * A single resolved filter clause applied at fetch time. `value` is `unknown`\n * to admit primitives, arrays (for `in` / `nin`), and dates as ISO strings —\n * adapters interpret per provider.\n */\nexport const ResolvedFilterSchema = z.object({\n\tfield: z.string().min(1),\n\top: z.enum([\"eq\", \"neq\", \"in\", \"nin\", \"gt\", \"gte\", \"lt\", \"lte\"]),\n\tvalue: z.unknown(),\n});\n\nexport type ResolvedFilter = z.infer<typeof ResolvedFilterSchema>;\n\n// ============================================================================\n// Cursor strategy — tagged union over the six shapes the modes need\n// ============================================================================\n\nconst SystemModstampCursorSchema = z.object({\n\tkind: z.literal(\"systemModstamp\"),\n\tfield: z.string().min(1),\n});\n\nconst ReplayIdCursorSchema = z.object({\n\tkind: z.literal(\"replayId\"),\n\tfield: z.string().min(1),\n});\n\nconst TimestampCursorSchema = z.object({\n\tkind: z.literal(\"timestamp\"),\n\tfield: z.string().min(1),\n});\n\nconst EventIdCursorSchema = z.object({\n\tkind: z.literal(\"eventId\"),\n\tfield: z.string().min(1),\n});\n\n/**\n * Gmail `historyId` (RFC-0003 §3) — an opaque, atomic vendor token. The next\n * watermark only exists at end-of-walk; there is no resumable mid-walk value.\n * `field` is metadata for codegen/adapters (the response key the token lives on).\n */\nconst HistoryIdCursorSchema = z.object({\n\tkind: z.literal(\"historyId\"),\n\tfield: z.string().min(1),\n});\n\n/**\n * Google Calendar `syncToken` (RFC-0003 §3) — an opaque, atomic sync token,\n * same divisibility profile as `historyId`.\n */\nconst SyncTokenCursorSchema = z.object({\n\tkind: z.literal(\"syncToken\"),\n\tfield: z.string().min(1),\n});\n\nexport const CursorStrategySchema = z.discriminatedUnion(\"kind\", [\n\tSystemModstampCursorSchema,\n\tReplayIdCursorSchema,\n\tTimestampCursorSchema,\n\tEventIdCursorSchema,\n\tHistoryIdCursorSchema,\n\tSyncTokenCursorSchema,\n]);\n\nexport type CursorStrategy = z.infer<typeof CursorStrategySchema>;\n\n// ============================================================================\n// Cursor divisibility (RFC-0003 §3)\n// ============================================================================\n\n/**\n * Whether a cursor strategy is *divisible* — a property of the strategy, not\n * the read primitive. Divisible cursors are sortable/monotonic watermarks whose\n * value is meaningful AS OF any single record (HubSpot `systemModstamp`, a\n * `timestamp` field, a Salesforce CDC `replayId`); the read primitive may\n * checkpoint per-ref mid-walk, so a crash resumes from the last delivered ref.\n *\n * Atomic cursors are opaque vendor tokens (Gmail `historyId`, Calendar\n * `syncToken`, a generic `eventId`) whose next value only exists at end-of-walk.\n * The primitive must withhold per-ref cursors and emit the token only at a safe\n * boundary, so an interrupted run never persists an unresumable mid-walk token\n * (it resumes all-or-nothing from the prior token — see `IncrementalReadBase`).\n *\n * `eventId` is classified atomic conservatively: a generic opaque id is treated\n * all-or-nothing unless a concrete strategy proves it monotonically resumable.\n */\nexport const CURSOR_DIVISIBILITY: Readonly<\n\tRecord<CursorStrategy[\"kind\"], boolean>\n> = {\n\tsystemModstamp: true,\n\ttimestamp: true,\n\treplayId: true,\n\teventId: false,\n\thistoryId: false,\n\tsyncToken: false,\n};\n\n/** Predicate form of {@link CURSOR_DIVISIBILITY}. */\nexport function isDivisibleCursor(kind: CursorStrategy[\"kind\"]): boolean {\n\treturn CURSOR_DIVISIBILITY[kind];\n}\n\n// ============================================================================\n// Mode-specific blocks\n// ============================================================================\n\n/**\n * Poll-mode block. `provenance: 'cdc'` opts the poll primitive into stamping\n * `Change<T>.source = 'cdc'` and populating `dedupKey` from the cursor's\n * `field` — used for Stripe-style event endpoints. Defaults to `'poll'`.\n */\nexport const PollDetectionSchema = z.object({\n\tcursor: CursorStrategySchema,\n\tprovenance: z.enum([\"poll\", \"cdc\"]).optional(),\n});\n\nexport type PollDetection = z.infer<typeof PollDetectionSchema>;\n\n/**\n * Webhook-mode block. `eventIdField`, when present, names the field on the\n * emitted canonical record that `WebhookChangeSource<T>` reads to set\n * `Change<T>.dedupKey` — used only as the fallback when the queue iterator\n * does NOT yield an `eventId` alongside the record.\n *\n * `eventIdField` is **optional**: a queue iterator that always yields an\n * `eventId` (vendor delivery metadata, the preferred channel) need not declare\n * a record field for it. dedupKey precedence is: yielded `eventId` >\n * `eventIdField` record extraction > undefined.\n */\nexport const WebhookDetectionSchema = z.object({\n\teventIdField: z.string().min(1).optional(),\n});\n\nexport type WebhookDetection = z.infer<typeof WebhookDetectionSchema>;\n\n// ============================================================================\n// DetectionConfig — top-level discriminated union over `mode`\n// ============================================================================\n\nconst PollModeSchema = z.object({\n\tmode: z.literal(\"poll\"),\n\tpoll: PollDetectionSchema,\n\tmapping: z.array(FieldMappingSchema).min(1),\n\tfilters: z.array(ResolvedFilterSchema).default([]),\n});\n\nconst WebhookModeSchema = z.object({\n\tmode: z.literal(\"webhook\"),\n\twebhook: WebhookDetectionSchema,\n\tmapping: z.array(FieldMappingSchema).min(1),\n\tfilters: z.array(ResolvedFilterSchema).default([]),\n});\n\n/**\n * Top-level detection config. Discriminated on `mode` so the relevant\n * mode-block (poll/webhook) is structurally required for that mode. CDC as a\n * long-lived streaming primitive is deferred (#226-8); CDC-as-provenance\n * (Stripe-style event endpoints) is expressed via `mode: 'poll'` with\n * `poll.provenance: 'cdc'`.\n */\nexport const DetectionConfigSchema = z.discriminatedUnion(\"mode\", [\n\tPollModeSchema,\n\tWebhookModeSchema,\n]);\n\nexport type DetectionConfig = z.infer<typeof DetectionConfigSchema>;\n"],"mappings":";AA+BA,SAAS,SAAS;AAWX,IAAM,qBAAqB,EAAE,OAAO;AAAA,EAC1C,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACxB,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACxB,WAAW,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS;AACvC,CAAC;AAaM,IAAM,uBAAuB,EAAE,OAAO;AAAA,EAC5C,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACvB,IAAI,EAAE,KAAK,CAAC,MAAM,OAAO,MAAM,OAAO,MAAM,OAAO,MAAM,KAAK,CAAC;AAAA,EAC/D,OAAO,EAAE,QAAQ;AAClB,CAAC;AAQD,IAAM,6BAA6B,EAAE,OAAO;AAAA,EAC3C,MAAM,EAAE,QAAQ,gBAAgB;AAAA,EAChC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC;AACxB,CAAC;AAED,IAAM,uBAAuB,EAAE,OAAO;AAAA,EACrC,MAAM,EAAE,QAAQ,UAAU;AAAA,EAC1B,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC;AACxB,CAAC;AAED,IAAM,wBAAwB,EAAE,OAAO;AAAA,EACtC,MAAM,EAAE,QAAQ,WAAW;AAAA,EAC3B,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC;AACxB,CAAC;AAED,IAAM,sBAAsB,EAAE,OAAO;AAAA,EACpC,MAAM,EAAE,QAAQ,SAAS;AAAA,EACzB,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC;AACxB,CAAC;AAOD,IAAM,wBAAwB,EAAE,OAAO;AAAA,EACtC,MAAM,EAAE,QAAQ,WAAW;AAAA,EAC3B,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC;AACxB,CAAC;AAMD,IAAM,wBAAwB,EAAE,OAAO;AAAA,EACtC,MAAM,EAAE,QAAQ,WAAW;AAAA,EAC3B,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC;AACxB,CAAC;AAEM,IAAM,uBAAuB,EAAE,mBAAmB,QAAQ;AAAA,EAChE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD,CAAC;AAwBM,IAAM,sBAET;AAAA,EACH,gBAAgB;AAAA,EAChB,WAAW;AAAA,EACX,UAAU;AAAA,EACV,SAAS;AAAA,EACT,WAAW;AAAA,EACX,WAAW;AACZ;AAGO,SAAS,kBAAkB,MAAuC;AACxE,SAAO,oBAAoB,IAAI;AAChC;AAWO,IAAM,sBAAsB,EAAE,OAAO;AAAA,EAC3C,QAAQ;AAAA,EACR,YAAY,EAAE,KAAK,CAAC,QAAQ,KAAK,CAAC,EAAE,SAAS;AAC9C,CAAC;AAeM,IAAM,yBAAyB,EAAE,OAAO;AAAA,EAC9C,cAAc,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,SAAS;AAC1C,CAAC;AAQD,IAAM,iBAAiB,EAAE,OAAO;AAAA,EAC/B,MAAM,EAAE,QAAQ,MAAM;AAAA,EACtB,MAAM;AAAA,EACN,SAAS,EAAE,MAAM,kBAAkB,EAAE,IAAI,CAAC;AAAA,EAC1C,SAAS,EAAE,MAAM,oBAAoB,EAAE,QAAQ,CAAC,CAAC;AAClD,CAAC;AAED,IAAM,oBAAoB,EAAE,OAAO;AAAA,EAClC,MAAM,EAAE,QAAQ,SAAS;AAAA,EACzB,SAAS;AAAA,EACT,SAAS,EAAE,MAAM,kBAAkB,EAAE,IAAI,CAAC;AAAA,EAC1C,SAAS,EAAE,MAAM,oBAAoB,EAAE,QAAQ,CAAC,CAAC;AAClD,CAAC;AASM,IAAM,wBAAwB,EAAE,mBAAmB,QAAQ;AAAA,EACjE;AAAA,EACA;AACD,CAAC;","names":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getEventMetadata
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-WE6DIDMM.js";
|
|
4
4
|
import {
|
|
5
5
|
eventPayloadSchemas
|
|
6
6
|
} from "./chunk-MU54DZCC.js";
|
|
@@ -89,4 +89,4 @@ TypedEventBus = __decorateClass([
|
|
|
89
89
|
export {
|
|
90
90
|
TypedEventBus
|
|
91
91
|
};
|
|
92
|
-
//# sourceMappingURL=chunk-
|
|
92
|
+
//# sourceMappingURL=chunk-IB733A6R.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
TypedEventBus
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-IB733A6R.js";
|
|
4
4
|
import {
|
|
5
5
|
MemoryEventBus
|
|
6
6
|
} from "./chunk-GOO5ZMYO.js";
|
|
@@ -200,4 +200,4 @@ export {
|
|
|
200
200
|
EventSchedulerLifecycle,
|
|
201
201
|
EventsModule
|
|
202
202
|
};
|
|
203
|
-
//# sourceMappingURL=chunk-
|
|
203
|
+
//# sourceMappingURL=chunk-K6LH4PXZ.js.map
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
MemoryJobRunService
|
|
3
|
+
} from "./chunk-BHZP6LOV.js";
|
|
1
4
|
import {
|
|
2
5
|
DrizzleJobStepService
|
|
3
6
|
} from "./chunk-DV4RV2DC.js";
|
|
@@ -10,15 +13,12 @@ import {
|
|
|
10
13
|
import {
|
|
11
14
|
MemoryJobStepService
|
|
12
15
|
} from "./chunk-PNZSGAB2.js";
|
|
13
|
-
import {
|
|
14
|
-
DrizzleJobRunService
|
|
15
|
-
} from "./chunk-VNBC3VXM.js";
|
|
16
|
-
import {
|
|
17
|
-
MemoryJobRunService
|
|
18
|
-
} from "./chunk-BHZP6LOV.js";
|
|
19
16
|
import {
|
|
20
17
|
MemoryJobStore
|
|
21
18
|
} from "./chunk-SNQ3TOWP.js";
|
|
19
|
+
import {
|
|
20
|
+
DrizzleJobRunService
|
|
21
|
+
} from "./chunk-VNBC3VXM.js";
|
|
22
22
|
import {
|
|
23
23
|
BULLMQ_CONNECTION,
|
|
24
24
|
BULLMQ_RESOLVED_CONFIG,
|
|
@@ -114,4 +114,4 @@ JobsDomainModule = __decorateClass([
|
|
|
114
114
|
export {
|
|
115
115
|
JobsDomainModule
|
|
116
116
|
};
|
|
117
|
-
//# sourceMappingURL=chunk-
|
|
117
|
+
//# sourceMappingURL=chunk-KS4BZHIA.js.map
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
+
import {
|
|
2
|
+
MemoryStorageBackend
|
|
3
|
+
} from "./chunk-3SZFUTXE.js";
|
|
1
4
|
import {
|
|
2
5
|
STORAGE
|
|
3
6
|
} from "./chunk-NYBCQZC7.js";
|
|
4
7
|
import {
|
|
5
8
|
LocalStorageBackend
|
|
6
9
|
} from "./chunk-JWNHNUYL.js";
|
|
7
|
-
import {
|
|
8
|
-
MemoryStorageBackend
|
|
9
|
-
} from "./chunk-3SZFUTXE.js";
|
|
10
10
|
import {
|
|
11
11
|
__decorateClass
|
|
12
12
|
} from "./chunk-2E224ZSN.js";
|
|
@@ -37,4 +37,4 @@ StorageModule = __decorateClass([
|
|
|
37
37
|
export {
|
|
38
38
|
StorageModule
|
|
39
39
|
};
|
|
40
|
-
//# sourceMappingURL=chunk-
|
|
40
|
+
//# sourceMappingURL=chunk-RUSUZZAF.js.map
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
2
|
EnvEncryptionKey
|
|
3
3
|
} from "./chunk-IP4OO26U.js";
|
|
4
|
+
import {
|
|
5
|
+
AuthController
|
|
6
|
+
} from "./chunk-SZVPIHWE.js";
|
|
4
7
|
import {
|
|
5
8
|
DrizzleOAuthStateStore
|
|
6
9
|
} from "./chunk-N5OTOWTP.js";
|
|
7
10
|
import {
|
|
8
11
|
MemoryOAuthStateStore
|
|
9
12
|
} from "./chunk-QLTJSCE6.js";
|
|
10
|
-
import {
|
|
11
|
-
AuthController
|
|
12
|
-
} from "./chunk-SZVPIHWE.js";
|
|
13
13
|
import {
|
|
14
14
|
AUTH_OPTIONS,
|
|
15
15
|
ENCRYPTION_KEY,
|
|
@@ -89,4 +89,4 @@ AuthModule = __decorateClass([
|
|
|
89
89
|
export {
|
|
90
90
|
AuthModule
|
|
91
91
|
};
|
|
92
|
-
//# sourceMappingURL=chunk-
|
|
92
|
+
//# sourceMappingURL=chunk-T6SCOJF4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../runtime/subsystems/events/generated/registry.ts"],"sourcesContent":["// AUTO-GENERATED by @pattern-stack/codegen. Do not edit.\n// Run `codegen entity new --all` to refresh.\n\n\nimport type { EventTypeName } from './types';\n\nexport interface EventMetadata {\n\ttype: EventTypeName;\n\ttier: 'domain' | 'audit';\n\tdirection: 'inbound' | 'change' | 'outbound' | null;\n\tpool: 'events_inbound' | 'events_change' | 'events_outbound' | null;\n\taggregate?: string;\n\tsource?: string;\n\tdestination?: string;\n\tversion: number;\n\tretry: { attempts: number; backoff: 'linear' | 'exponential' };\n\tschedule?: { every: string | number; align: boolean; catchUp: boolean; maxCatchUpSlots: number };\n\ttrigger?: { surface: string; label?: string; description?: string; fields: string[] };\n}\n\nexport const eventRegistry = {\n\t'contact_created': {\n\t\ttype: 'contact_created',\n\t\ttier: 'domain',\n\t\tdirection: 'change',\n\t\tpool: 'events_change',\n\t\taggregate: 'contact',\n\t\tversion: 1,\n\t\tretry: { attempts: 3, backoff: 'exponential' },\n\t},\n\t'contact_marked_champion': {\n\t\ttype: 'contact_marked_champion',\n\t\ttier: 'domain',\n\t\tdirection: 'change',\n\t\tpool: 'events_change',\n\t\taggregate: 'contact',\n\t\tversion: 1,\n\t\tretry: { attempts: 3, backoff: 'exponential' },\n\t},\n\t'contact_merged': {\n\t\ttype: 'contact_merged',\n\t\ttier: 'domain',\n\t\tdirection: 'change',\n\t\tpool: 'events_change',\n\t\taggregate: 'contact',\n\t\tversion: 1,\n\t\tretry: { attempts: 3, backoff: 'exponential' },\n\t},\n\t'crm_sync_started': {\n\t\ttype: 'crm_sync_started',\n\t\ttier: 'audit',\n\t\tdirection: null,\n\t\tpool: null,\n\t\tversion: 1,\n\t\tretry: { attempts: 3, backoff: 'exponential' },\n\t},\n\t'deal_created': {\n\t\ttype: 'deal_created',\n\t\ttier: 'domain',\n\t\tdirection: 'change',\n\t\tpool: 'events_change',\n\t\taggregate: 'deal',\n\t\tversion: 1,\n\t\tretry: { attempts: 3, backoff: 'exponential' },\n\t},\n\t'deal_stage_changed': {\n\t\ttype: 'deal_stage_changed',\n\t\ttier: 'domain',\n\t\tdirection: 'change',\n\t\tpool: 'events_change',\n\t\taggregate: 'deal',\n\t\tversion: 1,\n\t\tretry: { attempts: 3, backoff: 'exponential' },\n\t},\n\t'message_created': {\n\t\ttype: 'message_created',\n\t\ttier: 'domain',\n\t\tdirection: 'change',\n\t\tpool: 'events_change',\n\t\taggregate: 'message',\n\t\tversion: 1,\n\t\tretry: { attempts: 3, backoff: 'exponential' },\n\t},\n\t'message_deleted': {\n\t\ttype: 'message_deleted',\n\t\ttier: 'domain',\n\t\tdirection: 'change',\n\t\tpool: 'events_change',\n\t\taggregate: 'message',\n\t\tversion: 1,\n\t\tretry: { attempts: 3, backoff: 'exponential' },\n\t},\n\t'message_edited': {\n\t\ttype: 'message_edited',\n\t\ttier: 'domain',\n\t\tdirection: 'change',\n\t\tpool: 'events_change',\n\t\taggregate: 'message',\n\t\tversion: 1,\n\t\tretry: { attempts: 3, backoff: 'exponential' },\n\t},\n\t'stripe_payment_received': {\n\t\ttype: 'stripe_payment_received',\n\t\ttier: 'domain',\n\t\tdirection: 'inbound',\n\t\tpool: 'events_inbound',\n\t\tsource: 'stripe',\n\t\tversion: 1,\n\t\tretry: { attempts: 5, backoff: 'exponential' },\n\t},\n\t'webhook_outbound_contact_sync': {\n\t\ttype: 'webhook_outbound_contact_sync',\n\t\ttier: 'domain',\n\t\tdirection: 'outbound',\n\t\tpool: 'events_outbound',\n\t\taggregate: 'contact',\n\t\tdestination: 'crm',\n\t\tversion: 1,\n\t\tretry: { attempts: 3, backoff: 'exponential' },\n\t},\n} as const satisfies Record<EventTypeName, EventMetadata>;\n\nexport function getEventMetadata<T extends EventTypeName>(type: T): EventMetadata {\n\tconst meta = eventRegistry[type];\n\tif (!meta) {\n\t\tthrow new Error(`No registry entry for event type '${String(type)}' — declare events under events/*.yaml and re-run \\`codegen entity new --all\\`.`);\n\t}\n\treturn meta;\n}\n"],"mappings":";AAoBO,IAAM,gBAAgB;AAAA,EAC5B,mBAAmB;AAAA,IAClB,MAAM;AAAA,IACN,MAAM;AAAA,IACN,WAAW;AAAA,IACX,MAAM;AAAA,IACN,WAAW;AAAA,IACX,SAAS;AAAA,IACT,OAAO,EAAE,UAAU,GAAG,SAAS,cAAc;AAAA,EAC9C;AAAA,EACA,2BAA2B;AAAA,IAC1B,MAAM;AAAA,IACN,MAAM;AAAA,IACN,WAAW;AAAA,IACX,MAAM;AAAA,IACN,WAAW;AAAA,IACX,SAAS;AAAA,IACT,OAAO,EAAE,UAAU,GAAG,SAAS,cAAc;AAAA,EAC9C;AAAA,EACA,kBAAkB;AAAA,IACjB,MAAM;AAAA,IACN,MAAM;AAAA,IACN,WAAW;AAAA,IACX,MAAM;AAAA,IACN,WAAW;AAAA,IACX,SAAS;AAAA,IACT,OAAO,EAAE,UAAU,GAAG,SAAS,cAAc;AAAA,EAC9C;AAAA,EACA,oBAAoB;AAAA,IACnB,MAAM;AAAA,IACN,MAAM;AAAA,IACN,WAAW;AAAA,IACX,MAAM;AAAA,IACN,SAAS;AAAA,IACT,OAAO,EAAE,UAAU,GAAG,SAAS,cAAc;AAAA,EAC9C;AAAA,EACA,gBAAgB;AAAA,IACf,MAAM;AAAA,IACN,MAAM;AAAA,IACN,WAAW;AAAA,IACX,MAAM;AAAA,IACN,WAAW;AAAA,IACX,SAAS;AAAA,IACT,OAAO,EAAE,UAAU,GAAG,SAAS,cAAc;AAAA,EAC9C;AAAA,EACA,sBAAsB;AAAA,IACrB,MAAM;AAAA,IACN,MAAM;AAAA,IACN,WAAW;AAAA,IACX,MAAM;AAAA,IACN,WAAW;AAAA,IACX,SAAS;AAAA,IACT,OAAO,EAAE,UAAU,GAAG,SAAS,cAAc;AAAA,EAC9C;AAAA,EACA,mBAAmB;AAAA,IAClB,MAAM;AAAA,IACN,MAAM;AAAA,IACN,WAAW;AAAA,IACX,MAAM;AAAA,IACN,WAAW;AAAA,IACX,SAAS;AAAA,IACT,OAAO,EAAE,UAAU,GAAG,SAAS,cAAc;AAAA,EAC9C;AAAA,EACA,mBAAmB;AAAA,IAClB,MAAM;AAAA,IACN,MAAM;AAAA,IACN,WAAW;AAAA,IACX,MAAM;AAAA,IACN,WAAW;AAAA,IACX,SAAS;AAAA,IACT,OAAO,EAAE,UAAU,GAAG,SAAS,cAAc;AAAA,EAC9C;AAAA,EACA,kBAAkB;AAAA,IACjB,MAAM;AAAA,IACN,MAAM;AAAA,IACN,WAAW;AAAA,IACX,MAAM;AAAA,IACN,WAAW;AAAA,IACX,SAAS;AAAA,IACT,OAAO,EAAE,UAAU,GAAG,SAAS,cAAc;AAAA,EAC9C;AAAA,EACA,2BAA2B;AAAA,IAC1B,MAAM;AAAA,IACN,MAAM;AAAA,IACN,WAAW;AAAA,IACX,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,OAAO,EAAE,UAAU,GAAG,SAAS,cAAc;AAAA,EAC9C;AAAA,EACA,iCAAiC;AAAA,IAChC,MAAM;AAAA,IACN,MAAM;AAAA,IACN,WAAW;AAAA,IACX,MAAM;AAAA,IACN,WAAW;AAAA,IACX,aAAa;AAAA,IACb,SAAS;AAAA,IACT,OAAO,EAAE,UAAU,GAAG,SAAS,cAAc;AAAA,EAC9C;AACD;AAEO,SAAS,iBAA0C,MAAwB;AACjF,QAAM,OAAO,cAAc,IAAI;AAC/B,MAAI,CAAC,MAAM;AACV,UAAM,IAAI,MAAM,qCAAqC,OAAO,IAAI,CAAC,sFAAiF;AAAA,EACnJ;AACA,SAAO;AACR;","names":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
DetectionConfigSchema
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-CPUSJPAP.js";
|
|
4
4
|
|
|
5
5
|
// src/parser/load-entities.ts
|
|
6
6
|
import { resolve as resolve2 } from "path";
|
|
@@ -691,6 +691,17 @@ var ScheduleSchema = z2.object({
|
|
|
691
691
|
maxCatchUpSlots: z2.number().int().positive().optional().default(1e3)
|
|
692
692
|
}).strict();
|
|
693
693
|
var SNAKE_CASE_RE = /^[a-z][a-z0-9_]*$/;
|
|
694
|
+
var EventTriggerSchema = z2.object({
|
|
695
|
+
surface: z2.string().min(1),
|
|
696
|
+
label: z2.string().optional(),
|
|
697
|
+
description: z2.string().optional(),
|
|
698
|
+
fields: z2.array(
|
|
699
|
+
z2.string().regex(
|
|
700
|
+
SNAKE_CASE_RE,
|
|
701
|
+
"trigger.fields entries must be snake_case payload paths"
|
|
702
|
+
)
|
|
703
|
+
).default([])
|
|
704
|
+
}).strict();
|
|
694
705
|
var EventDefinitionSchemaCore = z2.object({
|
|
695
706
|
type: z2.string().regex(
|
|
696
707
|
SNAKE_CASE_RE,
|
|
@@ -714,7 +725,13 @@ var EventDefinitionSchemaCore = z2.object({
|
|
|
714
725
|
// platform emits this event on the given cadence (see ScheduleSchema).
|
|
715
726
|
schedule: ScheduleSchema.optional(),
|
|
716
727
|
version: z2.number().int().min(1).optional().default(1),
|
|
717
|
-
description: z2.string().optional()
|
|
728
|
+
description: z2.string().optional(),
|
|
729
|
+
// Trigger-catalog projection (workflow authoring). Present ⇒ this event is
|
|
730
|
+
// a selectable workflow trigger; consumers build the catalog from it. No
|
|
731
|
+
// refinement ties it to `direction` — selectability is an explicit opt-in,
|
|
732
|
+
// deliberately decoupled from transport (a change-fact may still be a
|
|
733
|
+
// non-trigger; an inbound event could opt in if a consumer hydrates it).
|
|
734
|
+
trigger: EventTriggerSchema.optional()
|
|
718
735
|
}).strict();
|
|
719
736
|
var EventDefinitionSchemaRefined = EventDefinitionSchemaCore.superRefine(
|
|
720
737
|
(data, ctx) => {
|
|
@@ -1145,6 +1162,109 @@ function isActiveProvider(def) {
|
|
|
1145
1162
|
return def.status !== "planned";
|
|
1146
1163
|
}
|
|
1147
1164
|
|
|
1165
|
+
// src/schema/job-definition.schema.ts
|
|
1166
|
+
import { z as z6 } from "zod";
|
|
1167
|
+
var JOB_BACKOFF_STRATEGIES = ["fixed", "exponential"];
|
|
1168
|
+
var COLLISION_MODES = ["queue", "reject", "replace"];
|
|
1169
|
+
var REPLAY_FROM = ["scratch", "last_step", "last_checkpoint"];
|
|
1170
|
+
var SNAKE_CASE_RE2 = /^[a-z][a-z0-9_]*$/;
|
|
1171
|
+
var RetryPolicySchema = z6.object({
|
|
1172
|
+
attempts: z6.number().int().min(0).max(20),
|
|
1173
|
+
backoff: z6.enum(JOB_BACKOFF_STRATEGIES),
|
|
1174
|
+
baseMs: z6.number().int().positive(),
|
|
1175
|
+
nonRetryableErrors: z6.array(z6.string().min(1)).optional()
|
|
1176
|
+
}).strict();
|
|
1177
|
+
var ConcurrencyPolicySchema = z6.object({
|
|
1178
|
+
key: z6.string().min(1),
|
|
1179
|
+
collisionMode: z6.enum(COLLISION_MODES)
|
|
1180
|
+
}).strict();
|
|
1181
|
+
var DedupePolicySchema = z6.object({
|
|
1182
|
+
key: z6.string().min(1),
|
|
1183
|
+
windowMs: z6.number().int().positive()
|
|
1184
|
+
}).strict();
|
|
1185
|
+
var ScopeRefSchema = z6.object({
|
|
1186
|
+
entity: z6.string().regex(SNAKE_CASE_RE2, "scope.entity must be snake_case"),
|
|
1187
|
+
from: z6.string().min(1)
|
|
1188
|
+
}).strict();
|
|
1189
|
+
var DifferOverrideSchema = z6.object({
|
|
1190
|
+
// Deliberately `.min(1)`: the runtime `DeepEqualDifferOptions.unignore` accepts
|
|
1191
|
+
// `[]` (a harmless no-op), but an empty `differ` block in YAML is meaningless
|
|
1192
|
+
// and almost certainly an authoring mistake — reject it rather than silently
|
|
1193
|
+
// accept a pointless block. (Schema is intentionally stricter than the runtime.)
|
|
1194
|
+
unignore: z6.array(z6.string().min(1)).min(1)
|
|
1195
|
+
}).strict();
|
|
1196
|
+
var ScheduleTriggerSchema = z6.object({
|
|
1197
|
+
schedule: ScheduleSchema
|
|
1198
|
+
}).strict();
|
|
1199
|
+
var EventTriggerSchema2 = z6.object({
|
|
1200
|
+
event: z6.string().regex(SNAKE_CASE_RE2, "trigger.event must be a snake_case event type")
|
|
1201
|
+
}).strict();
|
|
1202
|
+
var TriggerSchema = z6.union([ScheduleTriggerSchema, EventTriggerSchema2]);
|
|
1203
|
+
var PollArmSchema = z6.object({
|
|
1204
|
+
kind: z6.literal("poll"),
|
|
1205
|
+
domain: z6.string().regex(SNAKE_CASE_RE2, "arm.domain must be snake_case"),
|
|
1206
|
+
read: DetectionConfigSchema
|
|
1207
|
+
}).strict();
|
|
1208
|
+
var ReconcileArmSchema = z6.object({
|
|
1209
|
+
kind: z6.literal("reconcile"),
|
|
1210
|
+
domain: z6.string().regex(SNAKE_CASE_RE2, "arm.domain must be snake_case"),
|
|
1211
|
+
window: z6.object({ hours: z6.number().positive().finite() }).strict(),
|
|
1212
|
+
cursorWithheld: z6.literal(true).optional().default(true),
|
|
1213
|
+
read: DetectionConfigSchema
|
|
1214
|
+
}).strict();
|
|
1215
|
+
var RealtimeArmSchema = z6.object({
|
|
1216
|
+
kind: z6.literal("realtime"),
|
|
1217
|
+
domain: z6.string().regex(SNAKE_CASE_RE2, "arm.domain must be snake_case"),
|
|
1218
|
+
staging: z6.object({
|
|
1219
|
+
table: z6.string().min(1),
|
|
1220
|
+
pushAccelerate: z6.boolean().optional()
|
|
1221
|
+
}).strict(),
|
|
1222
|
+
read: DetectionConfigSchema
|
|
1223
|
+
}).strict();
|
|
1224
|
+
var ArmSchema = z6.discriminatedUnion("kind", [
|
|
1225
|
+
PollArmSchema,
|
|
1226
|
+
ReconcileArmSchema,
|
|
1227
|
+
RealtimeArmSchema
|
|
1228
|
+
]);
|
|
1229
|
+
var JobDefinitionSchemaCore = z6.object({
|
|
1230
|
+
type: z6.string().regex(SNAKE_CASE_RE2, "Job type must be snake_case starting with a letter"),
|
|
1231
|
+
// ── JobHandlerMeta surface (8 fields) ──────────────────────────────────
|
|
1232
|
+
pool: z6.string().min(1).optional(),
|
|
1233
|
+
scope: ScopeRefSchema.optional(),
|
|
1234
|
+
retry: RetryPolicySchema.optional(),
|
|
1235
|
+
concurrency: ConcurrencyPolicySchema.optional(),
|
|
1236
|
+
dedupe: DedupePolicySchema.optional(),
|
|
1237
|
+
timeoutMs: z6.number().int().positive().optional(),
|
|
1238
|
+
replayFrom: z6.enum(REPLAY_FROM).optional(),
|
|
1239
|
+
// `triggers` is the 8th meta field, reshaped to the declarative surface.
|
|
1240
|
+
triggers: z6.array(TriggerSchema).default([]),
|
|
1241
|
+
// ── job-definition additions ───────────────────────────────────────────
|
|
1242
|
+
differ: DifferOverrideSchema.optional(),
|
|
1243
|
+
arms: z6.array(ArmSchema).min(1, "a job must declare at least one arm"),
|
|
1244
|
+
description: z6.string().optional()
|
|
1245
|
+
}).strict();
|
|
1246
|
+
var JobDefinitionSchema = JobDefinitionSchemaCore.superRefine(
|
|
1247
|
+
(data, ctx) => {
|
|
1248
|
+
data.arms.forEach((arm, i) => {
|
|
1249
|
+
const mode = arm.read.mode;
|
|
1250
|
+
if (arm.kind === "realtime" && mode !== "webhook") {
|
|
1251
|
+
ctx.addIssue({
|
|
1252
|
+
code: z6.ZodIssueCode.custom,
|
|
1253
|
+
message: `realtime arm '${arm.domain}' requires read.mode 'webhook' (got '${mode}'). Realtime is a webhook-drain shape (ADR-0018 D1).`,
|
|
1254
|
+
path: ["arms", i, "read", "mode"]
|
|
1255
|
+
});
|
|
1256
|
+
}
|
|
1257
|
+
if ((arm.kind === "poll" || arm.kind === "reconcile") && mode !== "poll") {
|
|
1258
|
+
ctx.addIssue({
|
|
1259
|
+
code: z6.ZodIssueCode.custom,
|
|
1260
|
+
message: `${arm.kind} arm '${arm.domain}' requires read.mode 'poll' (got '${mode}').`,
|
|
1261
|
+
path: ["arms", i, "read", "mode"]
|
|
1262
|
+
});
|
|
1263
|
+
}
|
|
1264
|
+
});
|
|
1265
|
+
}
|
|
1266
|
+
);
|
|
1267
|
+
|
|
1148
1268
|
// src/utils/yaml-loader.ts
|
|
1149
1269
|
function loadEntityFromYaml(filePath) {
|
|
1150
1270
|
if (!existsSync(filePath)) {
|
|
@@ -2005,6 +2125,9 @@ function validateProviders(providers, opts) {
|
|
|
2005
2125
|
return issues;
|
|
2006
2126
|
}
|
|
2007
2127
|
|
|
2128
|
+
// src/parser/load-jobs.ts
|
|
2129
|
+
import { basename, resolve as resolve5 } from "path";
|
|
2130
|
+
|
|
2008
2131
|
// src/analyzer/graph-builder.ts
|
|
2009
2132
|
function inferCardinality(type) {
|
|
2010
2133
|
switch (type) {
|
|
@@ -3994,14 +4117,14 @@ function formatMermaidGraph(result) {
|
|
|
3994
4117
|
}
|
|
3995
4118
|
|
|
3996
4119
|
// src/patterns/library/activity.pattern.ts
|
|
3997
|
-
import { z as
|
|
3998
|
-
var ActivityPatternConfigSchema =
|
|
4120
|
+
import { z as z7 } from "zod";
|
|
4121
|
+
var ActivityPatternConfigSchema = z7.object({
|
|
3999
4122
|
/** Subject entity name → derives the FK column `<subject>_id`. */
|
|
4000
|
-
subject:
|
|
4123
|
+
subject: z7.string().optional(),
|
|
4001
4124
|
/** Explicit snake_case FK column, when it does not follow `<subject>_id`. */
|
|
4002
|
-
subjectColumn:
|
|
4125
|
+
subjectColumn: z7.string().optional(),
|
|
4003
4126
|
/** snake_case recency-ordering column; defaults to `occurred_at`. */
|
|
4004
|
-
occurredAt:
|
|
4127
|
+
occurredAt: z7.string().optional()
|
|
4005
4128
|
}).strict();
|
|
4006
4129
|
var ActivityPattern = definePattern({
|
|
4007
4130
|
name: "Activity",
|
|
@@ -4039,8 +4162,8 @@ var BasePattern = definePattern({
|
|
|
4039
4162
|
});
|
|
4040
4163
|
|
|
4041
4164
|
// src/patterns/library/junction.pattern.ts
|
|
4042
|
-
import { z as
|
|
4043
|
-
var JunctionPatternConfigSchema =
|
|
4165
|
+
import { z as z8 } from "zod";
|
|
4166
|
+
var JunctionPatternConfigSchema = z8.object({}).strict();
|
|
4044
4167
|
var JunctionPattern = definePattern({
|
|
4045
4168
|
name: "Junction",
|
|
4046
4169
|
description: "Explicit many-to-many junction with role + temporal + sourcing metadata",
|
|
@@ -4349,4 +4472,4 @@ export {
|
|
|
4349
4472
|
analyzeDomain,
|
|
4350
4473
|
validateEntities
|
|
4351
4474
|
};
|
|
4352
|
-
//# sourceMappingURL=chunk-
|
|
4475
|
+
//# sourceMappingURL=chunk-YUVEJNRE.js.map
|