@objectstack/plugin-webhooks 17.0.0-rc.0 → 17.0.0-rc.2
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 +632 -0
- package/dist/{chunk-6EPMRZ7I.js → chunk-3QGZLM3T.js} +8 -3
- package/dist/chunk-3QGZLM3T.js.map +1 -0
- package/dist/{chunk-QUTQSOQC.cjs → chunk-JQUVS5KK.cjs} +8 -3
- package/dist/chunk-JQUVS5KK.cjs.map +1 -0
- package/dist/index.cjs +182 -63
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +37 -1
- package/dist/index.d.ts +37 -1
- package/dist/index.js +138 -19
- package/dist/index.js.map +1 -1
- package/dist/schema.cjs +2 -2
- package/dist/schema.d.cts +721 -548
- package/dist/schema.d.ts +721 -548
- package/dist/schema.js +1 -1
- package/dist/{translations-Y3CXWOTM.js → translations-2VGD4XRF.js} +17 -9
- package/dist/translations-2VGD4XRF.js.map +1 -0
- package/dist/{translations-CBQRUIS5.cjs → translations-BWS57U2V.cjs} +17 -9
- package/dist/translations-BWS57U2V.cjs.map +1 -0
- package/package.json +12 -6
- package/.turbo/turbo-build.log +0 -36
- package/dist/chunk-6EPMRZ7I.js.map +0 -1
- package/dist/chunk-QUTQSOQC.cjs.map +0 -1
- package/dist/translations-CBQRUIS5.cjs.map +0 -1
- package/dist/translations-Y3CXWOTM.js.map +0 -1
- package/scripts/i18n-extract.config.ts +0 -34
- package/src/auto-enqueuer.test.ts +0 -431
- package/src/auto-enqueuer.ts +0 -383
- package/src/bootstrap-declared-webhooks.test.ts +0 -283
- package/src/bootstrap-declared-webhooks.ts +0 -205
- package/src/index.ts +0 -29
- package/src/schema.ts +0 -21
- package/src/sys-webhook.object.ts +0 -231
- package/src/translations/bundle-ownership.test.ts +0 -41
- package/src/translations/en.objects.generated.ts +0 -101
- package/src/translations/es-ES.objects.generated.ts +0 -101
- package/src/translations/index.ts +0 -23
- package/src/translations/ja-JP.objects.generated.ts +0 -101
- package/src/translations/zh-CN.objects.generated.ts +0 -101
- package/src/webhook-outbox-plugin.ts +0 -305
- package/src/webhook-provenance.ts +0 -86
- package/tsconfig.json +0 -10
- package/tsup.config.ts +0 -14
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,637 @@
|
|
|
1
1
|
# @objectstack/plugin-webhooks
|
|
2
2
|
|
|
3
|
+
## 17.0.0-rc.2
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- f2445c9: feat(spec,objectql,client,plugin-webhooks): predicate writes get an honest bulk event contract (#4639)
|
|
8
|
+
|
|
9
|
+
A `multi: true` update/delete reaches `IDataDriver.updateMany` / `deleteMany`,
|
|
10
|
+
which are contracted to resolve an affected row COUNT and nothing else. That
|
|
11
|
+
satisfies neither `DataEvent.recordId` (required) nor `before` / `after` /
|
|
12
|
+
`changes`, so before #4626 the engine fabricated a per-record event with
|
|
13
|
+
`recordId: ''` and `after: <count>` — an event every schema-compliant consumer
|
|
14
|
+
must reject, and one the webhook enqueuer's `?? 'unknown'` fallback turned into
|
|
15
|
+
a real delivery naming an unidentifiable record. #4626 removed the fabrication
|
|
16
|
+
and published nothing instead: honest, but it left webhooks, knowledge sync and
|
|
17
|
+
`subscribeData` silent for every predicate write.
|
|
18
|
+
|
|
19
|
+
Bulk writes now get their **own** contract rather than impersonating a
|
|
20
|
+
per-record one or going dark:
|
|
21
|
+
|
|
22
|
+
- **New `BulkDataEvent`** (`@objectstack/spec/api`): `data.records.updated` /
|
|
23
|
+
`data.records.deleted` — note the plural — carrying `id`, `type`, `object`,
|
|
24
|
+
`matched`, `userId?`, `timestamp`. Deliberately a separate schema from
|
|
25
|
+
`DataEvent`, not a widened one: a consumer that receives
|
|
26
|
+
`data.records.updated` knows from the type alone that no `recordId` is
|
|
27
|
+
coming, instead of discovering an empty string at runtime.
|
|
28
|
+
- **Engine** publishes it from the `multi: true` branches of `update()` /
|
|
29
|
+
`delete()`, validated with `BulkDataEventSchema.parse` before publish. A
|
|
30
|
+
predicate that matched **zero** rows publishes nothing (no data changed — this
|
|
31
|
+
is what keeps an idle background sweep from becoming an hourly "0 records"
|
|
32
|
+
delivery), and a driver that resolves a non-count publishes nothing and warns
|
|
33
|
+
rather than asserting a number it cannot verify. Per-record writes are
|
|
34
|
+
untouched, including a scalar `where.id` with `multi: true`, which is still a
|
|
35
|
+
single-record target and still emits `data.record.deleted`.
|
|
36
|
+
- **Webhooks**: two new opt-in triggers, `bulk_update` and `bulk_delete`
|
|
37
|
+
(`WebhookTriggerType`, and the `sys_webhook.triggers` multi-select). They are
|
|
38
|
+
**not** extra sources for `create` / `update` / `delete`: the delivered body
|
|
39
|
+
has no `recordId` and no record, so routing it to existing per-record
|
|
40
|
+
subscribers would hand them a payload missing every field they read — the
|
|
41
|
+
same class of breakage as the old `recordId: ''`, from the other direction. A
|
|
42
|
+
webhook that wants both subscribes to both. Bulk deliveries dedup on the
|
|
43
|
+
producer's event uuid, since two sweeps in the same millisecond are genuinely
|
|
44
|
+
different events that a timestamp-based key would collapse.
|
|
45
|
+
- **Client SDK**: new `client.events.subscribeBulkData(object, cb)`, with the
|
|
46
|
+
same loud boundary validation as `subscribeData`. Kept a separate method for
|
|
47
|
+
the same reason — delivering a `BulkDataEvent` to a `(event: DataEvent) =>
|
|
48
|
+
void` callback would recreate exactly the "typed field, `undefined` at
|
|
49
|
+
runtime" defect #4626 removed. `subscribeData`'s own guard was also tightened
|
|
50
|
+
from `data.` to `data.record.`, so an aggregate event is ignored rather than
|
|
51
|
+
rejected as off-contract.
|
|
52
|
+
- **Knowledge sync** now says out loud that a predicate write leaves its index
|
|
53
|
+
stale. A knowledge index is a per-record projection and `matched: 40` names no
|
|
54
|
+
record, so no event shape could drive it — the durable fix is reconciliation,
|
|
55
|
+
tracked in #4672.
|
|
56
|
+
|
|
57
|
+
The event carries no `where` predicate. The only one available at publish time
|
|
58
|
+
is the middleware-composed AST, whose filter embeds the security layer's
|
|
59
|
+
injected row scoping (RLS, sharing) — publishing it would ship tenant scoping
|
|
60
|
+
internals to whatever external URL a webhook points at.
|
|
61
|
+
|
|
62
|
+
Also pays off a measurement debt from #4655, which claimed the write-path cost
|
|
63
|
+
of event publishing had been measured but never published the numbers:
|
|
64
|
+
`packages/objectql/src/engine-data-events.bench.ts` measures it. Against an
|
|
65
|
+
in-memory driver, publishing costs ~7–9µs per event (insert 0.021ms vs 0.012ms,
|
|
66
|
+
single-id update 0.013ms vs 0.007ms). A bulk write pays that **once** regardless
|
|
67
|
+
of how many rows matched (0.040ms vs 0.034ms over a 100-row match set), so its
|
|
68
|
+
relative cost shrinks as the match set grows.
|
|
69
|
+
|
|
70
|
+
### Patch Changes
|
|
71
|
+
|
|
72
|
+
- 257d97a: ADR-0078 Phase 4, decided rather than deferred: the silent skips stop being silent at runtime. The registry — the one choke point every metadata door goes through — now emits a functional-completeness diagnostic at registration, and the webhook enqueuer's zero-trigger skip warns instead of returning `null` wordlessly.
|
|
73
|
+
|
|
74
|
+
**The Phase 4 ruling.** The phase had two halves, and they got opposite verdicts:
|
|
75
|
+
|
|
76
|
+
- **Generative rule sweep: rejected — not deferred.** A generator can enumerate candidates ("which optional keys might be load-bearing?") but cannot verify runtime skip sites, and a rule without its skip-site citation is a false prescription — this campaign shipped four of those and every one was caught by the verification pass a generator would skip. The route is structurally wrong; no amount of waiting produces the evidence that would fix it.
|
|
77
|
+
- **Registration-time diagnostics: built now.** The evidence was already in hand, not pending: #3896 (Setup authoring inserted `sys_sharing_rule` rows directly, bypassing the schema that "required" `criteria`) and cloud's `rowColor.mapping` (an `as never` cast bypassed tsc) prove that doors which skip Zod and lint are real. The author-time gate only protects metadata that passes through `os build` / `validate` / `lint`; `SchemaRegistry.registerObject` is where _every_ door converges — declared stacks, plugin objects, `extend` contributions, `saveMetaItem`, raw `registerObject` calls.
|
|
78
|
+
|
|
79
|
+
**Same predicate, same rule ids, different posture.** The registry calls the same `checkFieldCompleteness` that `validate-functional-completeness` uses, so the boot log carries the _same rule ids_ the lint reports (`field/summary-without-operations`, …) — an operator or an AI reading the log greps the id straight into the same docs and suppression story. But the registry **warns and never throws**: ADR-0078 §1's error severity means _the instance is dead_, not _the system is dead_ — an inert field must not kill a boot that thousands of healthy objects share. Errors block at author time; the registry's job is to make sure the silence never survives to runtime unobserved.
|
|
80
|
+
|
|
81
|
+
One line per object with every finding aggregated (not per request — the hot path stays free; not per finding — a three-dead-field object is one greppable line). Follows `warnStrippedLegacyApiMethods` (#3543) exactly: module-level once-per-object dedup, injectable `warn`, pure observation that never mutates the schema.
|
|
82
|
+
|
|
83
|
+
**The webhook skip now names itself.** `auto-enqueuer.ts`'s `if (triggers.size === 0) return null` sat under a comment blessing the empty case as "a manual-only webhook" — a mode #3196 removed (no manual fire path exists). The skip now warns with the author-time rule id (`webhook/without-triggers`), and the comment tells the truth. Only _active_ rows reach the parse (`where: { active: true }` — verified, not assumed), so a deliberately disabled webhook stays warning-free.
|
|
84
|
+
|
|
85
|
+
**Scope honesty:** field rules and the webhook rule get the runtime twin. `view/layout-without-binding` stays author-time-only — views don't register through this choke point and the renderer half of the evidence lives in objectui.
|
|
86
|
+
|
|
87
|
+
Tracked in #4544. This closes the ADR-0078 loop end to end: author-time error, runtime warning, one shared predicate deciding both.
|
|
88
|
+
|
|
89
|
+
- 462b713: fix(objectql,client): `subscribeData` callbacks receive real `DataEvent`s — the producer now fulfils the declared contract (#4626)
|
|
90
|
+
|
|
91
|
+
`@objectstack/spec/api`'s `DataEvent` declares top-level `id` (uuid,
|
|
92
|
+
required), `type`, `object`, `recordId` (required), `changes?`, `before?`,
|
|
93
|
+
`after?`, `userId?`, `timestamp`. But the producer (the ObjectQL engine)
|
|
94
|
+
published a raw `RealtimeEventPayload` envelope with `{ recordId, after,
|
|
95
|
+
changes }` nested under `payload` and never generated `id`/`userId`, while the
|
|
96
|
+
client SDK force-cast that envelope into the callback (`callback(event as any
|
|
97
|
+
as DataEvent)`). Subscribers who wrote `event.recordId` / `event.changes` —
|
|
98
|
+
exactly what the types promised — compiled green and read `undefined` at
|
|
99
|
+
runtime. The data-side twin of #4602.
|
|
100
|
+
|
|
101
|
+
Producer now fulfils the contract:
|
|
102
|
+
|
|
103
|
+
- `ObjectQL.insert()` / `update()` / `delete()` build a true `DataEvent`
|
|
104
|
+
(generated uuid `id`, flattened top-level fields, `userId` from the
|
|
105
|
+
execution context when the write names an actor) and validate it with
|
|
106
|
+
`DataEventSchema.parse` before publishing. The transport envelope is
|
|
107
|
+
unchanged (`RealtimeEventPayload`, with `payload` carrying the complete
|
|
108
|
+
`DataEvent`), so subscribers keep receiving `{ type, object, payload,
|
|
109
|
+
timestamp }` on the wire.
|
|
110
|
+
- A batch insert publishes one event **per record** (as before), each with its
|
|
111
|
+
own event id.
|
|
112
|
+
- **A multi-row write (`multi: true` → `updateMany` / `deleteMany`) now
|
|
113
|
+
publishes nothing.** Those driver methods return only an affected count, so
|
|
114
|
+
there is no record for a required `recordId` to name; the engine logs a
|
|
115
|
+
warning naming the gap instead of publishing the previous fabrication
|
|
116
|
+
(`recordId: ''`, `after: <affected count>`), which every schema-compliant
|
|
117
|
+
consumer had to reject. **Consequence: webhooks and knowledge sync no longer
|
|
118
|
+
fire for bulk writes** — they previously fired once with an unusable body. A
|
|
119
|
+
real bulk event contract is tracked in #4639.
|
|
120
|
+
|
|
121
|
+
Consumers validate or read the fulfilled shape instead of guessing:
|
|
122
|
+
|
|
123
|
+
- `@objectstack/client`'s `subscribeData` (and therefore
|
|
124
|
+
`@objectstack/client-react`'s `useDataSubscription` /
|
|
125
|
+
`useDataSubscriptionCallback` / `useAutoRefresh`, which delegate to it)
|
|
126
|
+
unwraps the envelope and runs `DataEventSchema.safeParse` at the boundary.
|
|
127
|
+
An off-contract payload is rejected loudly (handler error, callback never
|
|
128
|
+
invoked) — never coerced or passed through. The `as any as DataEvent`
|
|
129
|
+
double-cast is gone, and the `recordId` option now filters on the fulfilled
|
|
130
|
+
event.
|
|
131
|
+
- `@objectstack/plugin-webhooks`' auto-enqueuer reads the required
|
|
132
|
+
`recordId` directly; its `recordId ?? id ?? after?.id ?? before?.id ??
|
|
133
|
+
'unknown'` fallback chain is gone, and an off-contract event is dropped with
|
|
134
|
+
a warning rather than delivered under the literal id `'unknown'`. Delivered
|
|
135
|
+
webhook bodies now also carry the event's `id`/`type`/`userId`; the record
|
|
136
|
+
itself stays nested under `after` and the envelope keys (`object`,
|
|
137
|
+
`recordId`, `action`, `timestamp`) still win.
|
|
138
|
+
- `@objectstack/service-knowledge`'s event sync reads the record from `after`
|
|
139
|
+
(create/update) and the id from `recordId` (delete) for `data.record.*`.
|
|
140
|
+
It previously indexed the envelope itself as if it were the row, and never
|
|
141
|
+
resolved an id for deletes.
|
|
142
|
+
|
|
143
|
+
- Updated dependencies [430dcc2]
|
|
144
|
+
- Updated dependencies [e6ac4bd]
|
|
145
|
+
- Updated dependencies [80334c7]
|
|
146
|
+
- Updated dependencies [ce5242c]
|
|
147
|
+
- Updated dependencies [a7163ea]
|
|
148
|
+
- Updated dependencies [e6e9379]
|
|
149
|
+
- Updated dependencies [98877c9]
|
|
150
|
+
- Updated dependencies [98877c9]
|
|
151
|
+
- Updated dependencies [e6b1b69]
|
|
152
|
+
- Updated dependencies [ad047d2]
|
|
153
|
+
- Updated dependencies [2826d1e]
|
|
154
|
+
- Updated dependencies [5a84d41]
|
|
155
|
+
- Updated dependencies [20b1a9e]
|
|
156
|
+
- Updated dependencies [203a449]
|
|
157
|
+
- Updated dependencies [ac37fc6]
|
|
158
|
+
- Updated dependencies [4820f55]
|
|
159
|
+
- Updated dependencies [462d9c4]
|
|
160
|
+
- Updated dependencies [7d21581]
|
|
161
|
+
- Updated dependencies [f2445c9]
|
|
162
|
+
- Updated dependencies [23338c3]
|
|
163
|
+
- Updated dependencies [5b843fb]
|
|
164
|
+
- Updated dependencies [b4487aa]
|
|
165
|
+
- Updated dependencies [65ca83a]
|
|
166
|
+
- Updated dependencies [67bf2e2]
|
|
167
|
+
- Updated dependencies [c6d1cb4]
|
|
168
|
+
- Updated dependencies [36030ff]
|
|
169
|
+
- Updated dependencies [6117f7b]
|
|
170
|
+
- Updated dependencies [e533b0b]
|
|
171
|
+
- Updated dependencies [cdf4d9a]
|
|
172
|
+
- Updated dependencies [aee1806]
|
|
173
|
+
- Updated dependencies [c13350b]
|
|
174
|
+
- Updated dependencies [c13350b]
|
|
175
|
+
- Updated dependencies [9ca2d85]
|
|
176
|
+
- Updated dependencies [c13350b]
|
|
177
|
+
- Updated dependencies [891d345]
|
|
178
|
+
- Updated dependencies [a52e2ef]
|
|
179
|
+
- Updated dependencies [5293114]
|
|
180
|
+
- Updated dependencies [20bc357]
|
|
181
|
+
- Updated dependencies [5966c2a]
|
|
182
|
+
- Updated dependencies [2382580]
|
|
183
|
+
- Updated dependencies [d9fa683]
|
|
184
|
+
- Updated dependencies [3c7bcc0]
|
|
185
|
+
- Updated dependencies [4b6cac7]
|
|
186
|
+
- Updated dependencies [7631964]
|
|
187
|
+
- Updated dependencies [ac471a0]
|
|
188
|
+
- Updated dependencies [60ae58e]
|
|
189
|
+
- Updated dependencies [ce92674]
|
|
190
|
+
- Updated dependencies [9f601e8]
|
|
191
|
+
- Updated dependencies [51c5227]
|
|
192
|
+
- Updated dependencies [a4a85c8]
|
|
193
|
+
- Updated dependencies [07a4e26]
|
|
194
|
+
- Updated dependencies [ec975f1]
|
|
195
|
+
- Updated dependencies [eb4204b]
|
|
196
|
+
- Updated dependencies [4f13be2]
|
|
197
|
+
- Updated dependencies [61cc079]
|
|
198
|
+
- Updated dependencies [0e96e46]
|
|
199
|
+
- Updated dependencies [d52d4fe]
|
|
200
|
+
- Updated dependencies [742cebb]
|
|
201
|
+
- Updated dependencies [ce92674]
|
|
202
|
+
- Updated dependencies [cf2c9b7]
|
|
203
|
+
- Updated dependencies [833b512]
|
|
204
|
+
- Updated dependencies [0f9faa2]
|
|
205
|
+
- Updated dependencies [7cf42fe]
|
|
206
|
+
- Updated dependencies [5966c2a]
|
|
207
|
+
- Updated dependencies [040ecd2]
|
|
208
|
+
- Updated dependencies [f78dd83]
|
|
209
|
+
- Updated dependencies [a2cd18a]
|
|
210
|
+
- Updated dependencies [4638aaa]
|
|
211
|
+
- Updated dependencies [0222d3c]
|
|
212
|
+
- Updated dependencies [071d0dc]
|
|
213
|
+
- Updated dependencies [0a936ea]
|
|
214
|
+
- Updated dependencies [023c00b]
|
|
215
|
+
- Updated dependencies [155507e]
|
|
216
|
+
- Updated dependencies [7bba90b]
|
|
217
|
+
- Updated dependencies [7e05d8e]
|
|
218
|
+
- Updated dependencies [061406d]
|
|
219
|
+
- Updated dependencies [c1f344b]
|
|
220
|
+
- Updated dependencies [9c93465]
|
|
221
|
+
- Updated dependencies [ebb209c]
|
|
222
|
+
- Updated dependencies [63b33e6]
|
|
223
|
+
- Updated dependencies [2a44c1d]
|
|
224
|
+
- Updated dependencies [695cfbd]
|
|
225
|
+
- Updated dependencies [7445149]
|
|
226
|
+
- Updated dependencies [071d0dc]
|
|
227
|
+
- Updated dependencies [0848bea]
|
|
228
|
+
- Updated dependencies [d51bed2]
|
|
229
|
+
- Updated dependencies [b8b3c64]
|
|
230
|
+
- Updated dependencies [0c0fbd9]
|
|
231
|
+
- Updated dependencies [f3141d8]
|
|
232
|
+
- Updated dependencies [5a84d41]
|
|
233
|
+
- Updated dependencies [fd3013a]
|
|
234
|
+
- Updated dependencies [21676eb]
|
|
235
|
+
- Updated dependencies [e336549]
|
|
236
|
+
- Updated dependencies [d40f43a]
|
|
237
|
+
- Updated dependencies [e5e7ee0]
|
|
238
|
+
- Updated dependencies [a2ebea2]
|
|
239
|
+
- Updated dependencies [800bdb0]
|
|
240
|
+
- Updated dependencies [04f1182]
|
|
241
|
+
- Updated dependencies [5647006]
|
|
242
|
+
- Updated dependencies [38f7e4f]
|
|
243
|
+
- Updated dependencies [c57f3cf]
|
|
244
|
+
- Updated dependencies [97faca3]
|
|
245
|
+
- Updated dependencies [ad5fe25]
|
|
246
|
+
- Updated dependencies [ea90179]
|
|
247
|
+
- Updated dependencies [ce92674]
|
|
248
|
+
- Updated dependencies [5ef0b5b]
|
|
249
|
+
- Updated dependencies [48fbacb]
|
|
250
|
+
- Updated dependencies [355e951]
|
|
251
|
+
- Updated dependencies [dadb43f]
|
|
252
|
+
- @objectstack/spec@17.0.0-rc.2
|
|
253
|
+
- @objectstack/core@17.0.0-rc.2
|
|
254
|
+
- @objectstack/service-messaging@17.0.0-rc.2
|
|
255
|
+
|
|
256
|
+
## 17.0.0-rc.1
|
|
257
|
+
|
|
258
|
+
### Minor Changes
|
|
259
|
+
|
|
260
|
+
- f5a4ef0: refactor!: ADR-0112 batch 2 — sweep the lowercase error-code emitters (#4003)
|
|
261
|
+
|
|
262
|
+
Continues #3841 per ADR-0112. Batch 1 (#3988) settled the vocabulary and closed
|
|
263
|
+
the set; this batch moves the emitters that still spoke lowercase `snake_case`
|
|
264
|
+
onto it.
|
|
265
|
+
|
|
266
|
+
**Wire-visible change.** Error codes on these surfaces change spelling. Generic
|
|
267
|
+
conditions collapse onto the standard catalog rather than keeping a synonym:
|
|
268
|
+
`unauthorized`/`unauthenticated` → `UNAUTHENTICATED`, `forbidden` →
|
|
269
|
+
`PERMISSION_DENIED`, `not_found` → `RESOURCE_NOT_FOUND`, `internal` →
|
|
270
|
+
`INTERNAL_ERROR`, `unavailable` → `SERVICE_UNAVAILABLE`, `not_supported` →
|
|
271
|
+
`NOT_IMPLEMENTED`, `bad_request` → `INVALID_REQUEST`. Domain conditions get codes
|
|
272
|
+
registered in `ERROR_CODE_LEDGER` (`MARKETPLACE_STORAGE_FAILED`,
|
|
273
|
+
`PLUGIN_MANIFEST_INVALID`, `ITEM_LOCKED`, `DELIVERY_NOT_ELIGIBLE`, …). Swept:
|
|
274
|
+
`cloud-connection`, `plugin-auth`, `hono`, `metadata-protocol`, `rest`,
|
|
275
|
+
`service-messaging`, `service-automation`, `trigger-api`.
|
|
276
|
+
|
|
277
|
+
Branch on `error.code` values rather than pattern-matching their case: the
|
|
278
|
+
console's fix for the same rename (objectui#2977) reads codes case-insensitively
|
|
279
|
+
for exactly this reason, and that is the pattern to copy in your own consumers if
|
|
280
|
+
you support servers on both sides of the change.
|
|
281
|
+
|
|
282
|
+
**Four routes stop putting a code in the message slot.** The webhook redeliver
|
|
283
|
+
route, the API-trigger webhook, and two `rest` routes answered
|
|
284
|
+
`{ success: false, error: '<code>', message }` — the code occupying `error`, the
|
|
285
|
+
declared object envelope nowhere. They now emit `error: { code, message }`, and
|
|
286
|
+
three API-trigger branches gained a message they never had. Clients reading
|
|
287
|
+
`body.error` as a string on those routes must read `body.error.code`.
|
|
288
|
+
|
|
289
|
+
**`ConnectorErrorCategory` / `ConnectorRetryStrategy`** (ADR-0112 D9a):
|
|
290
|
+
`@objectstack/spec` exported two mutually incompatible `ErrorCategory` types and
|
|
291
|
+
two `RetryStrategy` types. The connector-side pair is renamed; importers of the
|
|
292
|
+
`integration` subpath update the name. Side effect: the api-side `ErrorCategory`
|
|
293
|
+
and `RetryStrategy` now appear in the generated API reference at all — the name
|
|
294
|
+
collision had been silently dropping them.
|
|
295
|
+
|
|
296
|
+
**`OAUTH_REGISTER_FAILED` replaces an unbounded code source.** The OAuth client
|
|
297
|
+
registration route put better-auth's arbitrary `body.error` string straight into
|
|
298
|
+
`error.code`. The code is now ours and the upstream discriminator moved to
|
|
299
|
+
`details.upstreamError`.
|
|
300
|
+
|
|
301
|
+
**Not swept, deliberately.** `sys_metadata_audit.code` keeps its lowercase values
|
|
302
|
+
(ADR-0112 D6b): it is persisted audit history, and the same column holds
|
|
303
|
+
non-error outcomes (`ok`, `lock_override`). Diagnostics records that ship inside a
|
|
304
|
+
200 keep theirs (D6c), as do field-level codes (D6, #3977) and the CLI's
|
|
305
|
+
`--json` output contract.
|
|
306
|
+
|
|
307
|
+
A `check:error-code-casing` CI guard now fails on a new lowercase literal in a
|
|
308
|
+
code position, since the ledger's casing rule can only police codes that someone
|
|
309
|
+
registers.
|
|
310
|
+
|
|
311
|
+
### Patch Changes
|
|
312
|
+
|
|
313
|
+
- bb1ce2e: fix(plugin-auth,plugin-webhooks): retire a dead degrade branch and an implicit transitive dependency (ADR-0116 follow-ups, #4187)
|
|
314
|
+
|
|
315
|
+
Two concrete findings from the ADR-0116 consumer-side audit, plus the
|
|
316
|
+
authoring rule that would have prevented both.
|
|
317
|
+
|
|
318
|
+
**`plugin-auth` claimed a fallback it did not have.** `init()` ran
|
|
319
|
+
`const dataEngine = ctx.getService('data'); if (!dataEngine) { warn('No data
|
|
320
|
+
engine service found - auth will use in-memory storage') }`. That branch could
|
|
321
|
+
never execute: `getService` **throws** for an unregistered service rather than
|
|
322
|
+
returning `undefined`, and this plugin declares a hard dependency on ObjectQL
|
|
323
|
+
(which registers `data` unconditionally), so a kernel without the engine fails
|
|
324
|
+
even earlier with `Dependency … not found`. The branch is removed and the real
|
|
325
|
+
contract is declared — `requiresServices: ['data', 'manifest']` — which also
|
|
326
|
+
replaces a trailing `// manifest service required` comment with the
|
|
327
|
+
machine-checked form of the same claim. `AuthManager` keeps its own optional
|
|
328
|
+
`dataEngine` guards: it is usable outside the plugin.
|
|
329
|
+
|
|
330
|
+
**`plugin-webhook-outbox` was protected only transitively.** It resolves
|
|
331
|
+
`manifest` in `init()` with no fallback while depending on
|
|
332
|
+
`com.objectstack.service.messaging`, which in turn depends on ObjectQL, the
|
|
333
|
+
actual provider. That works today and would have broken silently the day
|
|
334
|
+
messaging stopped depending on the engine — surfacing as a crash inside an
|
|
335
|
+
unrelated plugin's init. It now declares `requiresServices: ['manifest']`
|
|
336
|
+
directly.
|
|
337
|
+
|
|
338
|
+
Neither change alters ordering or boot outcomes on any current composition:
|
|
339
|
+
both plugins were already ordered correctly. What changes is what a broken
|
|
340
|
+
composition _says_, and that the guarantees are now checked rather than
|
|
341
|
+
inherited.
|
|
342
|
+
|
|
343
|
+
Docs: `content/docs/plugins/anatomy.mdx` gains the three ADR-0116 fields and
|
|
344
|
+
the decision rule for resolving a service inside `init()` (hard dependency vs
|
|
345
|
+
`optionalDependencies` + `requiresServices`), including the two traps behind
|
|
346
|
+
these fixes — don't rely on a transitive provider, and don't write an
|
|
347
|
+
`if (!svc)` fallback after a bare `getService`. The api-registry example
|
|
348
|
+
declares the contract on all seven of its plugins instead of relying on
|
|
349
|
+
`kernel.use()` order.
|
|
350
|
+
|
|
351
|
+
- 2e836de: chore(packaging): CHANGELOG.md ships in every npm tarball (#4261)
|
|
352
|
+
|
|
353
|
+
The AGENTS.md post-task checklist requires breaking changesets to carry their
|
|
354
|
+
FROM → TO migration because "this text ships to consumers as `CHANGELOG.md`
|
|
355
|
+
inside the npm package and is what an upgrading agent greps after the tombstone
|
|
356
|
+
error." That delivery path was severed for 68 of the 69 publishable packages:
|
|
357
|
+
npm packs `package.json` / `README*` / `LICENSE*` unconditionally but — unlike
|
|
358
|
+
older npm versions — not `CHANGELOG.md`, and the canonical
|
|
359
|
+
`"files": ["dist", "README.md"]` whitelist never named it. Measured on npm
|
|
360
|
+
10.9.7: `npm pack --dry-run` on `@objectstack/types` shipped 3 files while its
|
|
361
|
+
70KB `CHANGELOG.md` stayed behind. Only `@objectstack/spec` listed it
|
|
362
|
+
explicitly.
|
|
363
|
+
|
|
364
|
+
The tombstone-error scenario is precisely the one where the repo is out of
|
|
365
|
+
reach — the upgrading agent has `node_modules` and nothing else — so the
|
|
366
|
+
migration text has to ride in the tarball. Every publishable package now
|
|
367
|
+
declares `CHANGELOG.md` in `files`, and the canonical whitelist is
|
|
368
|
+
`["dist", "README.md", "CHANGELOG.md"]`.
|
|
369
|
+
|
|
370
|
+
The other half is the gate: `check:published-files` gains a fifth invariant,
|
|
371
|
+
COMPLETE — a whitelist that fails to cover `CHANGELOG.md` fails the
|
|
372
|
+
always-required lint job, so the next package cannot silently sever the path
|
|
373
|
+
again. `@objectstack/spec`'s per-package EXTRA_ENTRIES exemption dissolves
|
|
374
|
+
into the canonical set.
|
|
375
|
+
|
|
376
|
+
Consumer-visible change: one more file per install (the package's changelog,
|
|
377
|
+
e.g. 70.8KB for `@objectstack/types`), and `grep -r "removed key"
|
|
378
|
+
node_modules/@objectstack/*/CHANGELOG.md` now finds the migration it was
|
|
379
|
+
promised.
|
|
380
|
+
|
|
381
|
+
- a225ef5: fix(runtime,webhooks): the path object wins on /data/:object/query, and the webhook envelope owns its keys (#3946)
|
|
382
|
+
|
|
383
|
+
Follow-up sweep for the shape behind #3897 and #3933 — a trusted, server-derived
|
|
384
|
+
value written into an object literal with a caller-controlled bag spread OVER
|
|
385
|
+
it. Both of those were in the same block of REST code, so the pattern was swept
|
|
386
|
+
across all 1313 non-test TypeScript files in `packages/`. Nine candidate sites;
|
|
387
|
+
one real, one worth hardening, seven verified clean (recorded in #3946 so the
|
|
388
|
+
next sweep does not re-litigate them).
|
|
389
|
+
|
|
390
|
+
**`POST /data/:object/query` (runtime dispatcher).** The `/data` domain built
|
|
391
|
+
`{ object: objectName, ...body }`, so `{"object":"other", …}` in the body moved
|
|
392
|
+
the read to a different object than the URL named.
|
|
393
|
+
|
|
394
|
+
This is NOT an authorization bypass, and the tests pin why: `callData` gates
|
|
395
|
+
API exposure on `params.object`, so the gate followed the body and agreed with
|
|
396
|
+
the read — an object hidden by `apiEnabled: false` was refused either way. What
|
|
397
|
+
broke is that the URL stopped describing the operation (audit trails, logs, and
|
|
398
|
+
anything keyed on the request path saw object A while object B was read), and
|
|
399
|
+
that one endpoint spoke a second dialect of the contract the REST side had just
|
|
400
|
+
standardised on: the path object wins. The other handlers in that file never had
|
|
401
|
+
the problem — they nest caller data (`data: body`, `query: normalized`) instead
|
|
402
|
+
of splatting it, and the GET-by-id branch already allowlists its query params
|
|
403
|
+
against exactly this pollution.
|
|
404
|
+
|
|
405
|
+
**Webhook delivery envelope.** `auto-enqueuer` built
|
|
406
|
+
`{ object, recordId, action, timestamp, ...payload }`, letting an event payload
|
|
407
|
+
rewrite the envelope a subscriber receives. Behaviour-neutral for the engine's
|
|
408
|
+
own publishers — `data.record.*` payloads are `{ recordId, after, changes }`
|
|
409
|
+
with record fields nested under `after`, so none of those four keys collide
|
|
410
|
+
today — but the shape was wrong, and the `payload.id` fallback right above it
|
|
411
|
+
suggests publishers that flatten record fields do exist. Envelope keys are
|
|
412
|
+
written last now.
|
|
413
|
+
|
|
414
|
+
- b5f9397: fix(sharing,runtime): a `sort` passed straight to the engine never ordered anything; migrate every in-repo engine call to canonical QueryAST keys (#4346)
|
|
415
|
+
|
|
416
|
+
Two changes with different weights, from one sweep of every in-repo engine
|
|
417
|
+
call site that still speaks a deprecated alias.
|
|
418
|
+
|
|
419
|
+
**The bug — three dropped sorts.** #4346 made the engine fold `filter`→`where`
|
|
420
|
+
and `top`→`limit` on all six methods. The other four pairs in
|
|
421
|
+
`RPC_QUERY_ALIAS_SLOTS` (`select`, `sort`, `skip`, `populate`) are folded at
|
|
422
|
+
the RPC/wire layer only — their values need shape lowering that belongs to
|
|
423
|
+
those layers — and a **direct `engine.find()` never crosses that layer**. Three
|
|
424
|
+
call sites passed `sort` there, so it rode onto the AST untouched, every
|
|
425
|
+
driver's `Array.isArray(query.orderBy)` guard declined to emit an ORDER BY, and
|
|
426
|
+
the query returned an ordinary-looking, arbitrarily-ordered result:
|
|
427
|
+
|
|
428
|
+
| call site | asked for | actually got |
|
|
429
|
+
| ----------------------------------- | ------------------------------------------------- | --------------------------- |
|
|
430
|
+
| `share-link-routes.ts` | shared AI conversation messages, `created_at asc` | messages in arbitrary order |
|
|
431
|
+
| `runtime/domains/share-links.ts` | same route, runtime-domain copy | same |
|
|
432
|
+
| `share-link-service.ts` `listLinks` | the 200 most recent share links | an arbitrary 200 |
|
|
433
|
+
|
|
434
|
+
All three combine the dropped sort with a `limit` — the "latest N" shape whose
|
|
435
|
+
failure #4226 spelled out: an unapplied sort returns rows in arbitrary order,
|
|
436
|
+
which `limit` then slices into an arbitrary page. #4226 fixed that in the wire
|
|
437
|
+
normalizer; these calls sit one layer below it. `listLinks` had no test at all,
|
|
438
|
+
which is why it went unnoticed. Now pinned — on the option bag the engine
|
|
439
|
+
receives, not on row order, because the failure is that the key never becomes
|
|
440
|
+
`orderBy` and a fake engine honouring either spelling would pass either way.
|
|
441
|
+
|
|
442
|
+
**The cleanup — 27 no-op renames.** Every remaining in-repo engine call passing
|
|
443
|
+
`filter` now passes `where` (approvals 5, auth 2, reports 6, sharing 11,
|
|
444
|
+
webhooks 2, plus the one `filters` in a spec doc example). These are strict
|
|
445
|
+
no-ops since #4346 folds the alias — the point is that the framework stops
|
|
446
|
+
depending on a spelling it asks users to migrate off, which is a prerequisite
|
|
447
|
+
for ever retiring the aliases. Service-level `filter` PARAMETERS (each
|
|
448
|
+
service's own public API, e.g. `listRequests(filter)`) are deliberately
|
|
449
|
+
untouched — those are not engine option bags.
|
|
450
|
+
|
|
451
|
+
Two of the renamed calls were live victims of the #4346 bug rather than
|
|
452
|
+
cosmetic: `auth-manager`'s `stampIdentitySource` read the table's first row via
|
|
453
|
+
`findOne({filter})` and counted the whole table via `count({filter})`, so a
|
|
454
|
+
federated sign-in never stamped `source: 'idp_provisioned'`. #4346 already
|
|
455
|
+
corrected the behaviour; this makes the call say what it means.
|
|
456
|
+
|
|
457
|
+
- cc2de0e: chore(packaging): 20 packages stop publishing their sources, tests and build tooling (#4248)
|
|
458
|
+
|
|
459
|
+
These 20 packages declared no `files` field, so npm fell back to packing the
|
|
460
|
+
whole package directory. `npm pack --dry-run` on `@objectstack/plugin-webhooks`
|
|
461
|
+
listed **21 files** — 15 under `src/`, three of them unit tests
|
|
462
|
+
(`auto-enqueuer.test.ts`, `bootstrap-declared-webhooks.test.ts`, …), plus the
|
|
463
|
+
build-time `scripts/i18n-extract.config.ts`. `dist/` lands on top of that at
|
|
464
|
+
publish time rather than instead of it, so consumers were installing the
|
|
465
|
+
TypeScript sources and the test suite alongside the artifact they asked for.
|
|
466
|
+
|
|
467
|
+
Each now declares `"files": ["dist", "README.md"]`, matching the 29 packages
|
|
468
|
+
that already did. Nothing a consumer imports moves: every `main` / `types` /
|
|
469
|
+
`exports` target in all 20 already resolved inside `dist/`, which the new
|
|
470
|
+
`check:published-files` guard verifies rather than assumes. The visible change
|
|
471
|
+
is a smaller install and a smaller dependency-scanning surface — `npm pack` on
|
|
472
|
+
`@objectstack/plugin-webhooks` now yields 2 files plus `dist/`.
|
|
473
|
+
|
|
474
|
+
The other half of the fix is the gate. Half the packages declaring `files` and
|
|
475
|
+
half not was the #3786 shape — a hand-copied convention with nothing enforcing
|
|
476
|
+
it, where whoever forgets the line gets no signal at all. `check:published-files`
|
|
477
|
+
(new, wired into the always-required `lint` job) holds every non-private
|
|
478
|
+
workspace package to four invariants: `files` is **declared**; it is
|
|
479
|
+
**sufficient** (covers every entry point, so tightening a whitelist cannot ship
|
|
480
|
+
a package that fails to resolve); it is **minimal** (admits no test, test-harness
|
|
481
|
+
config or build script); and anything beyond `dist` + `README.md` is
|
|
482
|
+
**registered** with a reason, reconciled in both directions so a stale exemption
|
|
483
|
+
is an error rather than dead text. `@objectstack/spec` is the one package with
|
|
484
|
+
registered extras — its `.zod.ts` sources, JSON Schemas, liveness ledgers and
|
|
485
|
+
`CHANGELOG.md` are product, not build input.
|
|
486
|
+
|
|
487
|
+
This also closes an assumption #4206 was resting on. Excluding `<pkg>/scripts/**`
|
|
488
|
+
from the docs-drift implementation test is sound only while no package publishes
|
|
489
|
+
`scripts/` as runtime code; that held, but it held because someone read all three
|
|
490
|
+
offenders by hand. It is now checked on every PR.
|
|
491
|
+
|
|
492
|
+
- Updated dependencies [6a67d7a]
|
|
493
|
+
- Updated dependencies [0ecc656]
|
|
494
|
+
- Updated dependencies [06772eb]
|
|
495
|
+
- Updated dependencies [270650f]
|
|
496
|
+
- Updated dependencies [3aef718]
|
|
497
|
+
- Updated dependencies [1ea6bce]
|
|
498
|
+
- Updated dependencies [c1dcacd]
|
|
499
|
+
- Updated dependencies [ad303ed]
|
|
500
|
+
- Updated dependencies [32ccb23]
|
|
501
|
+
- Updated dependencies [f5a4ef0]
|
|
502
|
+
- Updated dependencies [2d3e255]
|
|
503
|
+
- Updated dependencies [7d7521f]
|
|
504
|
+
- Updated dependencies [5dc4d02]
|
|
505
|
+
- Updated dependencies [05154a1]
|
|
506
|
+
- Updated dependencies [9b6fe7c]
|
|
507
|
+
- Updated dependencies [8c711fb]
|
|
508
|
+
- Updated dependencies [09e4547]
|
|
509
|
+
- Updated dependencies [91f4c78]
|
|
510
|
+
- Updated dependencies [820eff9]
|
|
511
|
+
- Updated dependencies [8d895ff]
|
|
512
|
+
- Updated dependencies [f6472d7]
|
|
513
|
+
- Updated dependencies [78caf51]
|
|
514
|
+
- Updated dependencies [62a789b]
|
|
515
|
+
- Updated dependencies [789ad63]
|
|
516
|
+
- Updated dependencies [2af1988]
|
|
517
|
+
- Updated dependencies [0af50a3]
|
|
518
|
+
- Updated dependencies [2e836de]
|
|
519
|
+
- Updated dependencies [12a19a8]
|
|
520
|
+
- Updated dependencies [41dcda3]
|
|
521
|
+
- Updated dependencies [c8124e5]
|
|
522
|
+
- Updated dependencies [a1a4140]
|
|
523
|
+
- Updated dependencies [217e2e6]
|
|
524
|
+
- Updated dependencies [86a71d1]
|
|
525
|
+
- Updated dependencies [d5c75e2]
|
|
526
|
+
- Updated dependencies [03d26f7]
|
|
527
|
+
- Updated dependencies [4384921]
|
|
528
|
+
- Updated dependencies [3c628ce]
|
|
529
|
+
- Updated dependencies [7cb922e]
|
|
530
|
+
- Updated dependencies [1d22114]
|
|
531
|
+
- Updated dependencies [b5f9397]
|
|
532
|
+
- Updated dependencies [ed77493]
|
|
533
|
+
- Updated dependencies [58a03d2]
|
|
534
|
+
- Updated dependencies [dc530b4]
|
|
535
|
+
- Updated dependencies [e59786e]
|
|
536
|
+
- Updated dependencies [bcf1112]
|
|
537
|
+
- Updated dependencies [9774b78]
|
|
538
|
+
- Updated dependencies [b07d829]
|
|
539
|
+
- Updated dependencies [a648e96]
|
|
540
|
+
- Updated dependencies [a47ac06]
|
|
541
|
+
- Updated dependencies [e4c61a7]
|
|
542
|
+
- Updated dependencies [cc60165]
|
|
543
|
+
- Updated dependencies [081aa6f]
|
|
544
|
+
- Updated dependencies [91f4c78]
|
|
545
|
+
- Updated dependencies [e8d0c21]
|
|
546
|
+
- Updated dependencies [45dc446]
|
|
547
|
+
- Updated dependencies [c1d44f7]
|
|
548
|
+
- Updated dependencies [ab9fb5c]
|
|
549
|
+
- Updated dependencies [f985b3f]
|
|
550
|
+
- Updated dependencies [9a4932a]
|
|
551
|
+
- Updated dependencies [f9fc874]
|
|
552
|
+
- Updated dependencies [011b386]
|
|
553
|
+
- Updated dependencies [7777e8f]
|
|
554
|
+
- Updated dependencies [507b92a]
|
|
555
|
+
- Updated dependencies [7309c81]
|
|
556
|
+
- Updated dependencies [a8dcc37]
|
|
557
|
+
- Updated dependencies [20bc1ec]
|
|
558
|
+
- Updated dependencies [90c2b15]
|
|
559
|
+
- Updated dependencies [42eeb7d]
|
|
560
|
+
- Updated dependencies [01e124d]
|
|
561
|
+
- Updated dependencies [7ce02eb]
|
|
562
|
+
- Updated dependencies [a13827e]
|
|
563
|
+
- Updated dependencies [7733604]
|
|
564
|
+
- Updated dependencies [40e420f]
|
|
565
|
+
- Updated dependencies [d13004a]
|
|
566
|
+
- Updated dependencies [be7360c]
|
|
567
|
+
- Updated dependencies [5b47ab5]
|
|
568
|
+
- Updated dependencies [b09d8d9]
|
|
569
|
+
- Updated dependencies [b09d8d9]
|
|
570
|
+
- Updated dependencies [8675db6]
|
|
571
|
+
- Updated dependencies [b09d8d9]
|
|
572
|
+
- Updated dependencies [3eb1b2b]
|
|
573
|
+
- Updated dependencies [59b85c0]
|
|
574
|
+
- Updated dependencies [6e357ed]
|
|
575
|
+
- Updated dependencies [d6938bf]
|
|
576
|
+
- Updated dependencies [31e0be9]
|
|
577
|
+
- Updated dependencies [4bfd455]
|
|
578
|
+
- Updated dependencies [ffd2ce2]
|
|
579
|
+
- Updated dependencies [62f8017]
|
|
580
|
+
- Updated dependencies [a831df1]
|
|
581
|
+
- Updated dependencies [f752ee3]
|
|
582
|
+
- Updated dependencies [a1b61e0]
|
|
583
|
+
- Updated dependencies [cd6b9f2]
|
|
584
|
+
- Updated dependencies [2cb6d3c]
|
|
585
|
+
- Updated dependencies [af2a095]
|
|
586
|
+
- Updated dependencies [ec796d5]
|
|
587
|
+
- Updated dependencies [e87fea1]
|
|
588
|
+
- Updated dependencies [c65e529]
|
|
589
|
+
- Updated dependencies [3ca34c1]
|
|
590
|
+
- Updated dependencies [239c3a3]
|
|
591
|
+
- Updated dependencies [94a0bbc]
|
|
592
|
+
- Updated dependencies [d6bfb3d]
|
|
593
|
+
- Updated dependencies [a2266a6]
|
|
594
|
+
- Updated dependencies [d25a0ec]
|
|
595
|
+
- Updated dependencies [667b83e]
|
|
596
|
+
- Updated dependencies [627b188]
|
|
597
|
+
- Updated dependencies [8d4eae7]
|
|
598
|
+
- Updated dependencies [857a6cf]
|
|
599
|
+
- Updated dependencies [65a3a84]
|
|
600
|
+
- Updated dependencies [ccd9397]
|
|
601
|
+
- Updated dependencies [bca935b]
|
|
602
|
+
- Updated dependencies [d92c72d]
|
|
603
|
+
- Updated dependencies [c54c822]
|
|
604
|
+
- Updated dependencies [8dcc0f5]
|
|
605
|
+
- Updated dependencies [75b9e51]
|
|
606
|
+
- Updated dependencies [0a2f233]
|
|
607
|
+
- Updated dependencies [8621cdd]
|
|
608
|
+
- Updated dependencies [6f23667]
|
|
609
|
+
- Updated dependencies [5d21a48]
|
|
610
|
+
- Updated dependencies [19365b7]
|
|
611
|
+
- Updated dependencies [b7ed26d]
|
|
612
|
+
- Updated dependencies [b3a3d83]
|
|
613
|
+
- Updated dependencies [7a55913]
|
|
614
|
+
- Updated dependencies [35accbf]
|
|
615
|
+
- Updated dependencies [6038de7]
|
|
616
|
+
- Updated dependencies [eb95d97]
|
|
617
|
+
- Updated dependencies [e4c2dc8]
|
|
618
|
+
- Updated dependencies [1bd2795]
|
|
619
|
+
- Updated dependencies [8186a70]
|
|
620
|
+
- Updated dependencies [a329cca]
|
|
621
|
+
- Updated dependencies [6eec18c]
|
|
622
|
+
- Updated dependencies [4d7bebf]
|
|
623
|
+
- Updated dependencies [821ac7a]
|
|
624
|
+
- Updated dependencies [8f81731]
|
|
625
|
+
- Updated dependencies [8b50cb3]
|
|
626
|
+
- Updated dependencies [8c2db68]
|
|
627
|
+
- Updated dependencies [22b5e54]
|
|
628
|
+
- Updated dependencies [0166bd5]
|
|
629
|
+
- Updated dependencies [9b702dc]
|
|
630
|
+
- Updated dependencies [ab16331]
|
|
631
|
+
- @objectstack/spec@17.0.0-rc.1
|
|
632
|
+
- @objectstack/core@17.0.0-rc.1
|
|
633
|
+
- @objectstack/service-messaging@17.0.0-rc.1
|
|
634
|
+
|
|
3
635
|
## 17.0.0-rc.0
|
|
4
636
|
|
|
5
637
|
### Minor Changes
|
|
@@ -86,7 +86,7 @@ var SysWebhook = ObjectSchema.create({
|
|
|
86
86
|
group: "Definition"
|
|
87
87
|
}),
|
|
88
88
|
triggers: Field.select(
|
|
89
|
-
["create", "update", "delete"],
|
|
89
|
+
["create", "update", "delete", "bulk_update", "bulk_delete"],
|
|
90
90
|
{
|
|
91
91
|
label: "Triggers",
|
|
92
92
|
required: false,
|
|
@@ -94,7 +94,12 @@ var SysWebhook = ObjectSchema.create({
|
|
|
94
94
|
// an array; the auto-enqueuer parser also tolerates the legacy
|
|
95
95
|
// comma-separated / JSON-string forms so existing rows keep working.
|
|
96
96
|
multiple: true,
|
|
97
|
-
|
|
97
|
+
// [#4639] `bulk_*` fire on predicate writes (`multi: true`), whose
|
|
98
|
+
// delivery carries `matched` instead of a record — opt-in precisely
|
|
99
|
+
// because that body is a different shape. Kept in step with
|
|
100
|
+
// `WebhookTriggerType` (`@objectstack/spec/automation`), which is the
|
|
101
|
+
// contract the auto-enqueuer validates against.
|
|
102
|
+
description: "Record events that fire this webhook (bulk_* deliver a count, not a record)",
|
|
98
103
|
group: "Definition"
|
|
99
104
|
}
|
|
100
105
|
),
|
|
@@ -178,4 +183,4 @@ var SysWebhook = ObjectSchema.create({
|
|
|
178
183
|
export {
|
|
179
184
|
SysWebhook
|
|
180
185
|
};
|
|
181
|
-
//# sourceMappingURL=chunk-
|
|
186
|
+
//# sourceMappingURL=chunk-3QGZLM3T.js.map
|