@objectstack/plugin-webhooks 17.0.0-rc.6 → 17.1.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 +2019 -0
- package/dist/chunk-DRHJ2M45.cjs +319 -0
- package/dist/chunk-DRHJ2M45.cjs.map +1 -0
- package/dist/chunk-XERWWQKN.js +319 -0
- package/dist/chunk-XERWWQKN.js.map +1 -0
- package/dist/index.cjs +803 -90
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +457 -1
- package/dist/index.d.ts +457 -1
- package/dist/index.js +742 -29
- package/dist/index.js.map +1 -1
- package/dist/schema.cjs +2 -2
- package/dist/schema.cjs.map +1 -1
- package/dist/schema.d.cts +1733 -405
- package/dist/schema.d.ts +1733 -405
- package/dist/schema.js +1 -1
- package/dist/{translations-2VGD4XRF.js → translations-IAKF6NAP.js} +41 -9
- package/dist/translations-IAKF6NAP.js.map +1 -0
- package/dist/{translations-BWS57U2V.cjs → translations-IHRALWSP.cjs} +41 -9
- package/dist/translations-IHRALWSP.cjs.map +1 -0
- package/package.json +8 -6
- package/dist/chunk-3QGZLM3T.js +0 -186
- package/dist/chunk-3QGZLM3T.js.map +0 -1
- package/dist/chunk-JQUVS5KK.cjs +0 -186
- package/dist/chunk-JQUVS5KK.cjs.map +0 -1
- package/dist/translations-2VGD4XRF.js.map +0 -1
- package/dist/translations-BWS57U2V.cjs.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,2024 @@
|
|
|
1
1
|
# @objectstack/plugin-webhooks
|
|
2
2
|
|
|
3
|
+
## 17.1.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 90417a8: chore(plugin-webhooks): `sys_webhook` declares its data-API exposure explicitly — recording the posture, not narrowing it (#9756)
|
|
8
|
+
|
|
9
|
+
`sys_webhook` shipped with no `enable` block at all, so it kept the full default
|
|
10
|
+
data API. Three cards each noticed and each named the narrowing as the next
|
|
11
|
+
step — #7799 (the signing secret), #7986 (the custom headers), #8025 option 2
|
|
12
|
+
(the URL) — and each assumed a later one would write the line. None did, and the
|
|
13
|
+
last of them closed `completed` with the line still unwritten. The posture was
|
|
14
|
+
never a judgement; it was a default nobody had written down.
|
|
15
|
+
|
|
16
|
+
It is written down now:
|
|
17
|
+
|
|
18
|
+
```ts
|
|
19
|
+
enable: { apiMethods: ['get', 'list', 'create', 'update', 'delete', 'bulk'] }
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
**The effective surface is unchanged, and that is the honest headline.** The set
|
|
23
|
+
is derived from a census of who actually reaches the object, taken before
|
|
24
|
+
anything was edited:
|
|
25
|
+
|
|
26
|
+
| consumer | reaches it through | needs |
|
|
27
|
+
|:---|:---|:---|
|
|
28
|
+
| Setup/Studio console — `nav_webhooks`, four list views, `userActions` create/edit/delete | REST `/api/v1/data/sys_webhook` (gated) | `get` `list` `create` `update` `delete` |
|
|
29
|
+
| Operator predicate write — "deactivate every webhook on an object" (#4639) | REST `updateMany`/`deleteMany` (gated on `bulk`) | `bulk` |
|
|
30
|
+
| `AutoEnqueuer`, `bootstrapDeclaredWebhooks`, the provenance stamp, `redeliver-guard`, the secret sweep | `engine.*` and lifecycle hooks — ObjectQL directly, which never consults `enable.apiMethods` | ungated |
|
|
31
|
+
|
|
32
|
+
Every primitive is required by a real consumer, so the set is all six — whose
|
|
33
|
+
operation closure is what the absent block already produced. Nothing that was
|
|
34
|
+
reachable becomes unreachable, and `/me/permissions` reports the identical
|
|
35
|
+
`apiOperations` array. No caller needs to change anything.
|
|
36
|
+
|
|
37
|
+
⛔ **Do not read this as the read-surface narrowing those three cards asked
|
|
38
|
+
for.** It is not one, and `apiMethods` cannot be one here: `url` (#8025 —
|
|
39
|
+
won't-fix on masking, because the URL is the routing key an operator must be
|
|
40
|
+
able to see, search, sort and edit) and a legacy row's un-migrated
|
|
41
|
+
`definition_json.headers` (#7986 — still read, and warned about, by
|
|
42
|
+
`readLegacyHeaders`) are served by `get`/`list`, which is exactly what the admin
|
|
43
|
+
console requires. Any set that removes them removes the admin surface too. The
|
|
44
|
+
sibling `sys_http_delivery` can hold `['get','list']` because it is engine-owned
|
|
45
|
+
and never authored; `sys_webhook` is a first-class admin authoring surface.
|
|
46
|
+
|
|
47
|
+
The equality above is pinned in `sys-webhook-api-exposure.test.ts` rather than
|
|
48
|
+
left as a claim, so a later change that does move the surface has to say so.
|
|
49
|
+
- b278695: fix(webhooks): refuse a malformed `sys_webhook.headers_secret` at the write door instead of at the next delivery (#8566)
|
|
50
|
+
|
|
51
|
+
<!-- adr-0087: not-required (no-migration-prescription) Nothing authorable is
|
|
52
|
+
renamed, retired or tombstoned. This adds a runtime validation hook on one
|
|
53
|
+
plugin-owned object's existing column; the authoring envelope
|
|
54
|
+
(`webhook.zod.ts`), the field declaration and every stored shape are untouched.
|
|
55
|
+
The accept-set narrows, but only over values that were already unusable at
|
|
56
|
+
delivery time (see below), so there is no configuration for a migration to
|
|
57
|
+
prescribe a rewrite of. -->
|
|
58
|
+
|
|
59
|
+
`sys_webhook.headers_secret` is a `Field.secret()` whose plaintext is **not** an
|
|
60
|
+
opaque blob: it is a serialized header map with a required shape — a flat JSON
|
|
61
|
+
object of string values — and `parseStoredHeaders` is its only reader. Nothing
|
|
62
|
+
validated that shape on the way in. The ordinary data API accepted any string,
|
|
63
|
+
encrypted it like any other secret, minted a real `sys_secret` row, and left the
|
|
64
|
+
column holding a perfectly valid `secret:` ref that read back as the mask with
|
|
65
|
+
`active: true`.
|
|
66
|
+
|
|
67
|
+
Measured on a real engine through `engine.update()` — the ordinary data API, no
|
|
68
|
+
privileged access — every one of these was **accepted** and is a value the
|
|
69
|
+
plugin can never use: `{}`, `[]`, `{"X-Count": 5}`, a nested object, and
|
|
70
|
+
`{X-Team: crm}` (a typo). The field is directly admin-authorable and its own
|
|
71
|
+
description instructs the author to type a JSON object into it, which makes a
|
|
72
|
+
typo the *expected* failure rather than an exotic one.
|
|
73
|
+
|
|
74
|
+
**This is not an exposure fix and must not be read as one.** #8558/#8565 already
|
|
75
|
+
closed the consumer half: a webhook whose stored header map does not come back
|
|
76
|
+
as a flat string map parks the subscription and reports at `error`, rather than
|
|
77
|
+
delivering header-less with a valid signature. Nothing leaks, and nothing is
|
|
78
|
+
silently lost today. What this changes is **when the author finds out** — at the
|
|
79
|
+
write door where they typed it, instead of at the next matching record change,
|
|
80
|
+
an unbounded time later and in a different surface.
|
|
81
|
+
|
|
82
|
+
**What is refused:** a `headers_secret` plaintext that does not parse back as a
|
|
83
|
+
flat JSON object of string values with at least one entry, with a located
|
|
84
|
+
ADR-0112 `VALIDATION_ERROR` / 400 naming `sys_webhook.headers_secret`, quoting
|
|
85
|
+
the shape the field's own description asks for, and diagnosing the specific
|
|
86
|
+
spelling (invalid JSON / an array / an empty object / which key's value is not a
|
|
87
|
+
string). ⛔ The message never echoes the rejected value — this column carries
|
|
88
|
+
credentials, and quoting the input would print an `Authorization: Bearer …` into
|
|
89
|
+
logs and error bodies, re-opening in the diagnostic exactly the exposure #7986
|
|
90
|
+
moved this field onto the encrypted channel to close. It names header *keys* and
|
|
91
|
+
value *types* only.
|
|
92
|
+
|
|
93
|
+
**What stays accepted, byte for byte:** every valid flat string map (as JSON
|
|
94
|
+
text, or as an authored object the engine serializes into the same form); `null`
|
|
95
|
+
to clear; an omitted key to leave the stored value unchanged; and an **echoed
|
|
96
|
+
read-mask**, so the ordinary Setup-form round-trip (GET a row, edit an unrelated
|
|
97
|
+
field, PATCH it back) is untouched. `""` is deliberately passed through to
|
|
98
|
+
#8559's `EmptyCredentialWriteError` rather than re-refused here — one door, one
|
|
99
|
+
owner, one message.
|
|
100
|
+
|
|
101
|
+
**Where it runs, and why that is the whole mechanism:** a `beforeInsert` /
|
|
102
|
+
`beforeUpdate` hook on `sys_webhook`, bound by `WebhookOutboxPlugin` before its
|
|
103
|
+
first seeded write. It has to run *before* the engine's `encryptSecretFields` —
|
|
104
|
+
one step later the plaintext is gone and the column holds an opaque ref, so a
|
|
105
|
+
validator behind it would have nothing left to validate. The suite measures that
|
|
106
|
+
ordering rather than asserting it: every refusal pins that **no `sys_secret`
|
|
107
|
+
cipher row was minted**, which is only true if the gate ran first.
|
|
108
|
+
|
|
109
|
+
A hook rather than checks on the plugin's own write paths
|
|
110
|
+
(`bootstrapDeclaredWebhooks` / `headersPatch` / the migration sweep), because a
|
|
111
|
+
direct `PATCH /api/v1/data/sys_webhook` goes through none of them and that is
|
|
112
|
+
the measured trigger. Those paths inherit the validation through the hook and
|
|
113
|
+
deliberately carry no second check.
|
|
114
|
+
|
|
115
|
+
A general `secret`-channel plaintext validator — letting any `secret`-typed
|
|
116
|
+
field declare its own plaintext shape — is the principled generalization and is
|
|
117
|
+
recorded as the **promotion path**, not built here: it becomes the shape the
|
|
118
|
+
moment a second shaped-plaintext `secret` field exists (maintainer ruling
|
|
119
|
+
2026-08-13; one consumer does not justify a general capability).
|
|
120
|
+
- Updated dependencies [56656aa]
|
|
121
|
+
- Updated dependencies [07e630e]
|
|
122
|
+
- Updated dependencies [2f65b1b]
|
|
123
|
+
- Updated dependencies [720ee95]
|
|
124
|
+
- Updated dependencies [f287435]
|
|
125
|
+
- Updated dependencies [2782805]
|
|
126
|
+
- Updated dependencies [e43d63a]
|
|
127
|
+
- Updated dependencies [9aa8890]
|
|
128
|
+
- Updated dependencies [7c9c1dd]
|
|
129
|
+
- Updated dependencies [75b7c24]
|
|
130
|
+
- Updated dependencies [d5552ca]
|
|
131
|
+
- Updated dependencies [d9813a9]
|
|
132
|
+
- Updated dependencies [8640fb2]
|
|
133
|
+
- Updated dependencies [2420641]
|
|
134
|
+
- Updated dependencies [2ad91c3]
|
|
135
|
+
- Updated dependencies [f57fb38]
|
|
136
|
+
- Updated dependencies [00777a0]
|
|
137
|
+
- Updated dependencies [d491625]
|
|
138
|
+
- Updated dependencies [420804d]
|
|
139
|
+
- Updated dependencies [716ac9b]
|
|
140
|
+
- Updated dependencies [a38408a]
|
|
141
|
+
- Updated dependencies [62b1427]
|
|
142
|
+
- Updated dependencies [7ea1372]
|
|
143
|
+
- Updated dependencies [23abe27]
|
|
144
|
+
- Updated dependencies [985a9cd]
|
|
145
|
+
- Updated dependencies [5f5e234]
|
|
146
|
+
- Updated dependencies [a8189ae]
|
|
147
|
+
- Updated dependencies [26e70fb]
|
|
148
|
+
- Updated dependencies [42b05af]
|
|
149
|
+
- Updated dependencies [2b292ce]
|
|
150
|
+
- Updated dependencies [abcf853]
|
|
151
|
+
- Updated dependencies [8b9eba5]
|
|
152
|
+
- Updated dependencies [d575779]
|
|
153
|
+
- Updated dependencies [94f7ef8]
|
|
154
|
+
- Updated dependencies [c5ac5e4]
|
|
155
|
+
- Updated dependencies [a777944]
|
|
156
|
+
- Updated dependencies [dd88e1c]
|
|
157
|
+
- Updated dependencies [856527c]
|
|
158
|
+
- Updated dependencies [870f710]
|
|
159
|
+
- Updated dependencies [79c46da]
|
|
160
|
+
- Updated dependencies [7ff3975]
|
|
161
|
+
- Updated dependencies [29d055b]
|
|
162
|
+
- Updated dependencies [65589d6]
|
|
163
|
+
- Updated dependencies [2c86fe3]
|
|
164
|
+
- Updated dependencies [e196c6a]
|
|
165
|
+
- Updated dependencies [24173e9]
|
|
166
|
+
- Updated dependencies [4ab7523]
|
|
167
|
+
- Updated dependencies [19539b4]
|
|
168
|
+
- Updated dependencies [f8eb736]
|
|
169
|
+
- Updated dependencies [11b779e]
|
|
170
|
+
- Updated dependencies [739fe5b]
|
|
171
|
+
- Updated dependencies [4bfe1a5]
|
|
172
|
+
- Updated dependencies [2065e31]
|
|
173
|
+
- Updated dependencies [b69d0f5]
|
|
174
|
+
- Updated dependencies [4d47afe]
|
|
175
|
+
- Updated dependencies [e4e5c6e]
|
|
176
|
+
- Updated dependencies [9a56784]
|
|
177
|
+
- Updated dependencies [d00d2f6]
|
|
178
|
+
- Updated dependencies [df0c12d]
|
|
179
|
+
- Updated dependencies [44738f7]
|
|
180
|
+
- Updated dependencies [d31785f]
|
|
181
|
+
- Updated dependencies [c308a4f]
|
|
182
|
+
- Updated dependencies [e2899f6]
|
|
183
|
+
- Updated dependencies [3851f87]
|
|
184
|
+
- Updated dependencies [2a29caa]
|
|
185
|
+
- Updated dependencies [09a6eee]
|
|
186
|
+
- Updated dependencies [1a7f907]
|
|
187
|
+
- Updated dependencies [cd455c8]
|
|
188
|
+
- Updated dependencies [e1bb0ca]
|
|
189
|
+
- Updated dependencies [30d3752]
|
|
190
|
+
- Updated dependencies [c80e7ae]
|
|
191
|
+
- Updated dependencies [09a9a8a]
|
|
192
|
+
- Updated dependencies [07026cf]
|
|
193
|
+
- Updated dependencies [5d4f3d5]
|
|
194
|
+
- Updated dependencies [4d80e8b]
|
|
195
|
+
- Updated dependencies [30b1c63]
|
|
196
|
+
- Updated dependencies [079b457]
|
|
197
|
+
- Updated dependencies [e43b211]
|
|
198
|
+
- Updated dependencies [890b38f]
|
|
199
|
+
- Updated dependencies [8bee54b]
|
|
200
|
+
- Updated dependencies [7a537ce]
|
|
201
|
+
- Updated dependencies [593c4bf]
|
|
202
|
+
- Updated dependencies [ff08691]
|
|
203
|
+
- Updated dependencies [60e0f90]
|
|
204
|
+
- Updated dependencies [90c5285]
|
|
205
|
+
- Updated dependencies [402c125]
|
|
206
|
+
- Updated dependencies [7901b2d]
|
|
207
|
+
- Updated dependencies [56bca91]
|
|
208
|
+
- Updated dependencies [79394d7]
|
|
209
|
+
- Updated dependencies [730fd9a]
|
|
210
|
+
- Updated dependencies [44bc51d]
|
|
211
|
+
- Updated dependencies [73cfddf]
|
|
212
|
+
- Updated dependencies [d634e66]
|
|
213
|
+
- @objectstack/spec@17.1.0
|
|
214
|
+
- @objectstack/core@17.1.0
|
|
215
|
+
- @objectstack/service-messaging@17.1.0
|
|
216
|
+
|
|
217
|
+
## 17.0.0
|
|
218
|
+
|
|
219
|
+
### Minor Changes
|
|
220
|
+
|
|
221
|
+
- f5a4ef0: refactor!: ADR-0112 batch 2 — sweep the lowercase error-code emitters (#4003)
|
|
222
|
+
|
|
223
|
+
Continues #3841 per ADR-0112. Batch 1 (#3988) settled the vocabulary and closed
|
|
224
|
+
the set; this batch moves the emitters that still spoke lowercase `snake_case`
|
|
225
|
+
onto it.
|
|
226
|
+
|
|
227
|
+
**Wire-visible change.** Error codes on these surfaces change spelling. Generic
|
|
228
|
+
conditions collapse onto the standard catalog rather than keeping a synonym:
|
|
229
|
+
`unauthorized`/`unauthenticated` → `UNAUTHENTICATED`, `forbidden` →
|
|
230
|
+
`PERMISSION_DENIED`, `not_found` → `RESOURCE_NOT_FOUND`, `internal` →
|
|
231
|
+
`INTERNAL_ERROR`, `unavailable` → `SERVICE_UNAVAILABLE`, `not_supported` →
|
|
232
|
+
`NOT_IMPLEMENTED`, `bad_request` → `INVALID_REQUEST`. Domain conditions get codes
|
|
233
|
+
registered in `ERROR_CODE_LEDGER` (`MARKETPLACE_STORAGE_FAILED`,
|
|
234
|
+
`PLUGIN_MANIFEST_INVALID`, `ITEM_LOCKED`, `DELIVERY_NOT_ELIGIBLE`, …). Swept:
|
|
235
|
+
`cloud-connection`, `plugin-auth`, `hono`, `metadata-protocol`, `rest`,
|
|
236
|
+
`service-messaging`, `service-automation`, `trigger-api`.
|
|
237
|
+
|
|
238
|
+
Branch on `error.code` values rather than pattern-matching their case: the
|
|
239
|
+
console's fix for the same rename (objectui#2977) reads codes case-insensitively
|
|
240
|
+
for exactly this reason, and that is the pattern to copy in your own consumers if
|
|
241
|
+
you support servers on both sides of the change.
|
|
242
|
+
|
|
243
|
+
**Four routes stop putting a code in the message slot.** The webhook redeliver
|
|
244
|
+
route, the API-trigger webhook, and two `rest` routes answered
|
|
245
|
+
`{ success: false, error: '<code>', message }` — the code occupying `error`, the
|
|
246
|
+
declared object envelope nowhere. They now emit `error: { code, message }`, and
|
|
247
|
+
three API-trigger branches gained a message they never had. Clients reading
|
|
248
|
+
`body.error` as a string on those routes must read `body.error.code`.
|
|
249
|
+
|
|
250
|
+
**`ConnectorErrorCategory` / `ConnectorRetryStrategy`** (ADR-0112 D9a):
|
|
251
|
+
`@objectstack/spec` exported two mutually incompatible `ErrorCategory` types and
|
|
252
|
+
two `RetryStrategy` types. The connector-side pair is renamed; importers of the
|
|
253
|
+
`integration` subpath update the name. Side effect: the api-side `ErrorCategory`
|
|
254
|
+
and `RetryStrategy` now appear in the generated API reference at all — the name
|
|
255
|
+
collision had been silently dropping them.
|
|
256
|
+
|
|
257
|
+
**`OAUTH_REGISTER_FAILED` replaces an unbounded code source.** The OAuth client
|
|
258
|
+
registration route put better-auth's arbitrary `body.error` string straight into
|
|
259
|
+
`error.code`. The code is now ours and the upstream discriminator moved to
|
|
260
|
+
`details.upstreamError`.
|
|
261
|
+
|
|
262
|
+
**Not swept, deliberately.** `sys_metadata_audit.code` keeps its lowercase values
|
|
263
|
+
(ADR-0112 D6b): it is persisted audit history, and the same column holds
|
|
264
|
+
non-error outcomes (`ok`, `lock_override`). Diagnostics records that ship inside a
|
|
265
|
+
200 keep theirs (D6c), as do field-level codes (D6, #3977) and the CLI's
|
|
266
|
+
`--json` output contract.
|
|
267
|
+
|
|
268
|
+
A `check:error-code-casing` CI guard now fails on a new lowercase literal in a
|
|
269
|
+
code position, since the ledger's casing rule can only police codes that someone
|
|
270
|
+
registers.
|
|
271
|
+
|
|
272
|
+
- f2445c9: feat(spec,objectql,client,plugin-webhooks): predicate writes get an honest bulk event contract (#4639)
|
|
273
|
+
|
|
274
|
+
A `multi: true` update/delete reaches `IDataDriver.updateMany` / `deleteMany`,
|
|
275
|
+
which are contracted to resolve an affected row COUNT and nothing else. That
|
|
276
|
+
satisfies neither `DataEvent.recordId` (required) nor `before` / `after` /
|
|
277
|
+
`changes`, so before #4626 the engine fabricated a per-record event with
|
|
278
|
+
`recordId: ''` and `after: <count>` — an event every schema-compliant consumer
|
|
279
|
+
must reject, and one the webhook enqueuer's `?? 'unknown'` fallback turned into
|
|
280
|
+
a real delivery naming an unidentifiable record. #4626 removed the fabrication
|
|
281
|
+
and published nothing instead: honest, but it left webhooks, knowledge sync and
|
|
282
|
+
`subscribeData` silent for every predicate write.
|
|
283
|
+
|
|
284
|
+
Bulk writes now get their **own** contract rather than impersonating a
|
|
285
|
+
per-record one or going dark:
|
|
286
|
+
|
|
287
|
+
- **New `BulkDataEvent`** (`@objectstack/spec/api`): `data.records.updated` /
|
|
288
|
+
`data.records.deleted` — note the plural — carrying `id`, `type`, `object`,
|
|
289
|
+
`matched`, `userId?`, `timestamp`. Deliberately a separate schema from
|
|
290
|
+
`DataEvent`, not a widened one: a consumer that receives
|
|
291
|
+
`data.records.updated` knows from the type alone that no `recordId` is
|
|
292
|
+
coming, instead of discovering an empty string at runtime.
|
|
293
|
+
- **Engine** publishes it from the `multi: true` branches of `update()` /
|
|
294
|
+
`delete()`, validated with `BulkDataEventSchema.parse` before publish. A
|
|
295
|
+
predicate that matched **zero** rows publishes nothing (no data changed — this
|
|
296
|
+
is what keeps an idle background sweep from becoming an hourly "0 records"
|
|
297
|
+
delivery), and a driver that resolves a non-count publishes nothing and warns
|
|
298
|
+
rather than asserting a number it cannot verify. Per-record writes are
|
|
299
|
+
untouched, including a scalar `where.id` with `multi: true`, which is still a
|
|
300
|
+
single-record target and still emits `data.record.deleted`.
|
|
301
|
+
- **Webhooks**: two new opt-in triggers, `bulk_update` and `bulk_delete`
|
|
302
|
+
(`WebhookTriggerType`, and the `sys_webhook.triggers` multi-select). They are
|
|
303
|
+
**not** extra sources for `create` / `update` / `delete`: the delivered body
|
|
304
|
+
has no `recordId` and no record, so routing it to existing per-record
|
|
305
|
+
subscribers would hand them a payload missing every field they read — the
|
|
306
|
+
same class of breakage as the old `recordId: ''`, from the other direction. A
|
|
307
|
+
webhook that wants both subscribes to both. Bulk deliveries dedup on the
|
|
308
|
+
producer's event uuid, since two sweeps in the same millisecond are genuinely
|
|
309
|
+
different events that a timestamp-based key would collapse.
|
|
310
|
+
- **Client SDK**: new `client.events.subscribeBulkData(object, cb)`, with the
|
|
311
|
+
same loud boundary validation as `subscribeData`. Kept a separate method for
|
|
312
|
+
the same reason — delivering a `BulkDataEvent` to a `(event: DataEvent) =>
|
|
313
|
+
void` callback would recreate exactly the "typed field, `undefined` at
|
|
314
|
+
runtime" defect #4626 removed. `subscribeData`'s own guard was also tightened
|
|
315
|
+
from `data.` to `data.record.`, so an aggregate event is ignored rather than
|
|
316
|
+
rejected as off-contract.
|
|
317
|
+
- **Knowledge sync** now says out loud that a predicate write leaves its index
|
|
318
|
+
stale. A knowledge index is a per-record projection and `matched: 40` names no
|
|
319
|
+
record, so no event shape could drive it — the durable fix is reconciliation,
|
|
320
|
+
tracked in #4672.
|
|
321
|
+
|
|
322
|
+
The event carries no `where` predicate. The only one available at publish time
|
|
323
|
+
is the middleware-composed AST, whose filter embeds the security layer's
|
|
324
|
+
injected row scoping (RLS, sharing) — publishing it would ship tenant scoping
|
|
325
|
+
internals to whatever external URL a webhook points at.
|
|
326
|
+
|
|
327
|
+
Also pays off a measurement debt from #4655, which claimed the write-path cost
|
|
328
|
+
of event publishing had been measured but never published the numbers:
|
|
329
|
+
`packages/objectql/src/engine-data-events.bench.ts` measures it. Against an
|
|
330
|
+
in-memory driver, publishing costs ~7–9µs per event (insert 0.021ms vs 0.012ms,
|
|
331
|
+
single-id update 0.013ms vs 0.007ms). A bulk write pays that **once** regardless
|
|
332
|
+
of how many rows matched (0.040ms vs 0.034ms over a 100-row match set), so its
|
|
333
|
+
relative cost shrinks as the match set grows.
|
|
334
|
+
|
|
335
|
+
- 69f1dfd: fix(webhooks): materialize stack-declared webhooks into the dispatcher (#3461)
|
|
336
|
+
|
|
337
|
+
A webhook authored declaratively — `defineStack({ webhooks })` / `defineWebhook()`,
|
|
338
|
+
validated against the spec `WebhookSchema` — was a **silent no-op**. The runtime
|
|
339
|
+
dispatcher (`AutoEnqueuer`) fans out off `sys_webhook` DATA rows (`object_name` /
|
|
340
|
+
`active`), which until now were only ever written by hand through the object's
|
|
341
|
+
CRUD UI. Nothing turned a declared webhook (`object` / `isActive`) into a
|
|
342
|
+
dispatchable row, so authoring `webhooks:` on a stack produced `webhook` metadata
|
|
343
|
+
that never fired (ADR-0078). The showcase app itself shipped a `webhooks:` entry
|
|
344
|
+
that did nothing.
|
|
345
|
+
|
|
346
|
+
`@objectstack/plugin-webhooks` now bridges the two on boot:
|
|
347
|
+
|
|
348
|
+
- **`bootstrapDeclaredWebhooks`** reads declared `webhook` metadata from the
|
|
349
|
+
ObjectQL registry (where the manifest decomposition already parks
|
|
350
|
+
`stack.webhooks`), validates each through `WebhookSchema.parse()` — the spec
|
|
351
|
+
schema finally has a real consumer — and materializes it into a `sys_webhook`
|
|
352
|
+
row, mapping `object → object_name`, `isActive → active`, and stashing the full
|
|
353
|
+
envelope (headers / secret / retry / timeout) in `definition_json`. The
|
|
354
|
+
auto-enqueuer's first cache refresh then picks the row up and dispatches it.
|
|
355
|
+
- **Seed-not-clobber provenance** (mirrors `sys_sharing_rule`, #2909): `sys_webhook`
|
|
356
|
+
gains `managed_by` / `customized` columns. Declared webhooks re-seed every boot
|
|
357
|
+
as `managed_by: 'package'`, but a row an admin created (`managed_by: 'admin'`) or
|
|
358
|
+
edited in Setup (`customized: true`, stamped by a `beforeUpdate` hook) is never
|
|
359
|
+
overwritten — a deactivated noisy webhook survives redeploys.
|
|
360
|
+
|
|
361
|
+
Connector-declared `webhooks` remain not-yet-enforced (that is a separate seam,
|
|
362
|
+
#3197). Registering `webhook` as a first-class metadata type + enrolling it in the
|
|
363
|
+
liveness `GOVERNED` set is a tracked follow-up.
|
|
364
|
+
|
|
365
|
+
Migration: none required. Existing hand-authored `sys_webhook` rows default to
|
|
366
|
+
`managed_by: 'admin'` and are never touched by the seeder. Anyone who authored
|
|
367
|
+
`webhooks:` on a stack expecting it to fire will find it now does — review those
|
|
368
|
+
declarations (especially `url` / `isActive`) before upgrading.
|
|
369
|
+
|
|
370
|
+
### Patch Changes
|
|
371
|
+
|
|
372
|
+
- 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.
|
|
373
|
+
|
|
374
|
+
**The Phase 4 ruling.** The phase had two halves, and they got opposite verdicts:
|
|
375
|
+
|
|
376
|
+
- **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.
|
|
377
|
+
- **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.
|
|
378
|
+
|
|
379
|
+
**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.
|
|
380
|
+
|
|
381
|
+
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.
|
|
382
|
+
|
|
383
|
+
**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.
|
|
384
|
+
|
|
385
|
+
**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.
|
|
386
|
+
|
|
387
|
+
Tracked in #4544. This closes the ADR-0078 loop end to end: author-time error, runtime warning, one shared predicate deciding both.
|
|
388
|
+
|
|
389
|
+
- bb1ce2e: fix(plugin-auth,plugin-webhooks): retire a dead degrade branch and an implicit transitive dependency (ADR-0116 follow-ups, #4187)
|
|
390
|
+
|
|
391
|
+
Two concrete findings from the ADR-0116 consumer-side audit, plus the
|
|
392
|
+
authoring rule that would have prevented both.
|
|
393
|
+
|
|
394
|
+
**`plugin-auth` claimed a fallback it did not have.** `init()` ran
|
|
395
|
+
`const dataEngine = ctx.getService('data'); if (!dataEngine) { warn('No data
|
|
396
|
+
engine service found - auth will use in-memory storage') }`. That branch could
|
|
397
|
+
never execute: `getService` **throws** for an unregistered service rather than
|
|
398
|
+
returning `undefined`, and this plugin declares a hard dependency on ObjectQL
|
|
399
|
+
(which registers `data` unconditionally), so a kernel without the engine fails
|
|
400
|
+
even earlier with `Dependency … not found`. The branch is removed and the real
|
|
401
|
+
contract is declared — `requiresServices: ['data', 'manifest']` — which also
|
|
402
|
+
replaces a trailing `// manifest service required` comment with the
|
|
403
|
+
machine-checked form of the same claim. `AuthManager` keeps its own optional
|
|
404
|
+
`dataEngine` guards: it is usable outside the plugin.
|
|
405
|
+
|
|
406
|
+
**`plugin-webhook-outbox` was protected only transitively.** It resolves
|
|
407
|
+
`manifest` in `init()` with no fallback while depending on
|
|
408
|
+
`com.objectstack.service.messaging`, which in turn depends on ObjectQL, the
|
|
409
|
+
actual provider. That works today and would have broken silently the day
|
|
410
|
+
messaging stopped depending on the engine — surfacing as a crash inside an
|
|
411
|
+
unrelated plugin's init. It now declares `requiresServices: ['manifest']`
|
|
412
|
+
directly.
|
|
413
|
+
|
|
414
|
+
Neither change alters ordering or boot outcomes on any current composition:
|
|
415
|
+
both plugins were already ordered correctly. What changes is what a broken
|
|
416
|
+
composition _says_, and that the guarantees are now checked rather than
|
|
417
|
+
inherited.
|
|
418
|
+
|
|
419
|
+
Docs: `content/docs/plugins/anatomy.mdx` gains the three ADR-0116 fields and
|
|
420
|
+
the decision rule for resolving a service inside `init()` (hard dependency vs
|
|
421
|
+
`optionalDependencies` + `requiresServices`), including the two traps behind
|
|
422
|
+
these fixes — don't rely on a transitive provider, and don't write an
|
|
423
|
+
`if (!svc)` fallback after a bare `getService`. The api-registry example
|
|
424
|
+
declares the contract on all seven of its plugins instead of relying on
|
|
425
|
+
`kernel.use()` order.
|
|
426
|
+
|
|
427
|
+
- 2e836de: chore(packaging): CHANGELOG.md ships in every npm tarball (#4261)
|
|
428
|
+
|
|
429
|
+
The AGENTS.md post-task checklist requires breaking changesets to carry their
|
|
430
|
+
FROM → TO migration because "this text ships to consumers as `CHANGELOG.md`
|
|
431
|
+
inside the npm package and is what an upgrading agent greps after the tombstone
|
|
432
|
+
error." That delivery path was severed for 68 of the 69 publishable packages:
|
|
433
|
+
npm packs `package.json` / `README*` / `LICENSE*` unconditionally but — unlike
|
|
434
|
+
older npm versions — not `CHANGELOG.md`, and the canonical
|
|
435
|
+
`"files": ["dist", "README.md"]` whitelist never named it. Measured on npm
|
|
436
|
+
10.9.7: `npm pack --dry-run` on `@objectstack/types` shipped 3 files while its
|
|
437
|
+
70KB `CHANGELOG.md` stayed behind. Only `@objectstack/spec` listed it
|
|
438
|
+
explicitly.
|
|
439
|
+
|
|
440
|
+
The tombstone-error scenario is precisely the one where the repo is out of
|
|
441
|
+
reach — the upgrading agent has `node_modules` and nothing else — so the
|
|
442
|
+
migration text has to ride in the tarball. Every publishable package now
|
|
443
|
+
declares `CHANGELOG.md` in `files`, and the canonical whitelist is
|
|
444
|
+
`["dist", "README.md", "CHANGELOG.md"]`.
|
|
445
|
+
|
|
446
|
+
The other half is the gate: `check:published-files` gains a fifth invariant,
|
|
447
|
+
COMPLETE — a whitelist that fails to cover `CHANGELOG.md` fails the
|
|
448
|
+
always-required lint job, so the next package cannot silently sever the path
|
|
449
|
+
again. `@objectstack/spec`'s per-package EXTRA_ENTRIES exemption dissolves
|
|
450
|
+
into the canonical set.
|
|
451
|
+
|
|
452
|
+
Consumer-visible change: one more file per install (the package's changelog,
|
|
453
|
+
e.g. 70.8KB for `@objectstack/types`), and `grep -r "removed key"
|
|
454
|
+
node_modules/@objectstack/*/CHANGELOG.md` now finds the migration it was
|
|
455
|
+
promised.
|
|
456
|
+
|
|
457
|
+
- 462b713: fix(objectql,client): `subscribeData` callbacks receive real `DataEvent`s — the producer now fulfils the declared contract (#4626)
|
|
458
|
+
|
|
459
|
+
`@objectstack/spec/api`'s `DataEvent` declares top-level `id` (uuid,
|
|
460
|
+
required), `type`, `object`, `recordId` (required), `changes?`, `before?`,
|
|
461
|
+
`after?`, `userId?`, `timestamp`. But the producer (the ObjectQL engine)
|
|
462
|
+
published a raw `RealtimeEventPayload` envelope with `{ recordId, after,
|
|
463
|
+
changes }` nested under `payload` and never generated `id`/`userId`, while the
|
|
464
|
+
client SDK force-cast that envelope into the callback (`callback(event as any
|
|
465
|
+
as DataEvent)`). Subscribers who wrote `event.recordId` / `event.changes` —
|
|
466
|
+
exactly what the types promised — compiled green and read `undefined` at
|
|
467
|
+
runtime. The data-side twin of #4602.
|
|
468
|
+
|
|
469
|
+
Producer now fulfils the contract:
|
|
470
|
+
|
|
471
|
+
- `ObjectQL.insert()` / `update()` / `delete()` build a true `DataEvent`
|
|
472
|
+
(generated uuid `id`, flattened top-level fields, `userId` from the
|
|
473
|
+
execution context when the write names an actor) and validate it with
|
|
474
|
+
`DataEventSchema.parse` before publishing. The transport envelope is
|
|
475
|
+
unchanged (`RealtimeEventPayload`, with `payload` carrying the complete
|
|
476
|
+
`DataEvent`), so subscribers keep receiving `{ type, object, payload,
|
|
477
|
+
timestamp }` on the wire.
|
|
478
|
+
- A batch insert publishes one event **per record** (as before), each with its
|
|
479
|
+
own event id.
|
|
480
|
+
- **A multi-row write (`multi: true` → `updateMany` / `deleteMany`) now
|
|
481
|
+
publishes nothing.** Those driver methods return only an affected count, so
|
|
482
|
+
there is no record for a required `recordId` to name; the engine logs a
|
|
483
|
+
warning naming the gap instead of publishing the previous fabrication
|
|
484
|
+
(`recordId: ''`, `after: <affected count>`), which every schema-compliant
|
|
485
|
+
consumer had to reject. **Consequence: webhooks and knowledge sync no longer
|
|
486
|
+
fire for bulk writes** — they previously fired once with an unusable body. A
|
|
487
|
+
real bulk event contract is tracked in #4639.
|
|
488
|
+
|
|
489
|
+
Consumers validate or read the fulfilled shape instead of guessing:
|
|
490
|
+
|
|
491
|
+
- `@objectstack/client`'s `subscribeData` (and therefore
|
|
492
|
+
`@objectstack/client-react`'s `useDataSubscription` /
|
|
493
|
+
`useDataSubscriptionCallback` / `useAutoRefresh`, which delegate to it)
|
|
494
|
+
unwraps the envelope and runs `DataEventSchema.safeParse` at the boundary.
|
|
495
|
+
An off-contract payload is rejected loudly (handler error, callback never
|
|
496
|
+
invoked) — never coerced or passed through. The `as any as DataEvent`
|
|
497
|
+
double-cast is gone, and the `recordId` option now filters on the fulfilled
|
|
498
|
+
event.
|
|
499
|
+
- `@objectstack/plugin-webhooks`' auto-enqueuer reads the required
|
|
500
|
+
`recordId` directly; its `recordId ?? id ?? after?.id ?? before?.id ??
|
|
501
|
+
'unknown'` fallback chain is gone, and an off-contract event is dropped with
|
|
502
|
+
a warning rather than delivered under the literal id `'unknown'`. Delivered
|
|
503
|
+
webhook bodies now also carry the event's `id`/`type`/`userId`; the record
|
|
504
|
+
itself stays nested under `after` and the envelope keys (`object`,
|
|
505
|
+
`recordId`, `action`, `timestamp`) still win.
|
|
506
|
+
- `@objectstack/service-knowledge`'s event sync reads the record from `after`
|
|
507
|
+
(create/update) and the id from `recordId` (delete) for `data.record.*`.
|
|
508
|
+
It previously indexed the envelope itself as if it were the row, and never
|
|
509
|
+
resolved an id for deletes.
|
|
510
|
+
|
|
511
|
+
- a225ef5: fix(runtime,webhooks): the path object wins on /data/:object/query, and the webhook envelope owns its keys (#3946)
|
|
512
|
+
|
|
513
|
+
Follow-up sweep for the shape behind #3897 and #3933 — a trusted, server-derived
|
|
514
|
+
value written into an object literal with a caller-controlled bag spread OVER
|
|
515
|
+
it. Both of those were in the same block of REST code, so the pattern was swept
|
|
516
|
+
across all 1313 non-test TypeScript files in `packages/`. Nine candidate sites;
|
|
517
|
+
one real, one worth hardening, seven verified clean (recorded in #3946 so the
|
|
518
|
+
next sweep does not re-litigate them).
|
|
519
|
+
|
|
520
|
+
**`POST /data/:object/query` (runtime dispatcher).** The `/data` domain built
|
|
521
|
+
`{ object: objectName, ...body }`, so `{"object":"other", …}` in the body moved
|
|
522
|
+
the read to a different object than the URL named.
|
|
523
|
+
|
|
524
|
+
This is NOT an authorization bypass, and the tests pin why: `callData` gates
|
|
525
|
+
API exposure on `params.object`, so the gate followed the body and agreed with
|
|
526
|
+
the read — an object hidden by `apiEnabled: false` was refused either way. What
|
|
527
|
+
broke is that the URL stopped describing the operation (audit trails, logs, and
|
|
528
|
+
anything keyed on the request path saw object A while object B was read), and
|
|
529
|
+
that one endpoint spoke a second dialect of the contract the REST side had just
|
|
530
|
+
standardised on: the path object wins. The other handlers in that file never had
|
|
531
|
+
the problem — they nest caller data (`data: body`, `query: normalized`) instead
|
|
532
|
+
of splatting it, and the GET-by-id branch already allowlists its query params
|
|
533
|
+
against exactly this pollution.
|
|
534
|
+
|
|
535
|
+
**Webhook delivery envelope.** `auto-enqueuer` built
|
|
536
|
+
`{ object, recordId, action, timestamp, ...payload }`, letting an event payload
|
|
537
|
+
rewrite the envelope a subscriber receives. Behaviour-neutral for the engine's
|
|
538
|
+
own publishers — `data.record.*` payloads are `{ recordId, after, changes }`
|
|
539
|
+
with record fields nested under `after`, so none of those four keys collide
|
|
540
|
+
today — but the shape was wrong, and the `payload.id` fallback right above it
|
|
541
|
+
suggests publishers that flatten record fields do exist. Envelope keys are
|
|
542
|
+
written last now.
|
|
543
|
+
|
|
544
|
+
- 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)
|
|
545
|
+
|
|
546
|
+
Two changes with different weights, from one sweep of every in-repo engine
|
|
547
|
+
call site that still speaks a deprecated alias.
|
|
548
|
+
|
|
549
|
+
**The bug — three dropped sorts.** #4346 made the engine fold `filter`→`where`
|
|
550
|
+
and `top`→`limit` on all six methods. The other four pairs in
|
|
551
|
+
`RPC_QUERY_ALIAS_SLOTS` (`select`, `sort`, `skip`, `populate`) are folded at
|
|
552
|
+
the RPC/wire layer only — their values need shape lowering that belongs to
|
|
553
|
+
those layers — and a **direct `engine.find()` never crosses that layer**. Three
|
|
554
|
+
call sites passed `sort` there, so it rode onto the AST untouched, every
|
|
555
|
+
driver's `Array.isArray(query.orderBy)` guard declined to emit an ORDER BY, and
|
|
556
|
+
the query returned an ordinary-looking, arbitrarily-ordered result:
|
|
557
|
+
|
|
558
|
+
| call site | asked for | actually got |
|
|
559
|
+
| ----------------------------------- | ------------------------------------------------- | --------------------------- |
|
|
560
|
+
| `share-link-routes.ts` | shared AI conversation messages, `created_at asc` | messages in arbitrary order |
|
|
561
|
+
| `runtime/domains/share-links.ts` | same route, runtime-domain copy | same |
|
|
562
|
+
| `share-link-service.ts` `listLinks` | the 200 most recent share links | an arbitrary 200 |
|
|
563
|
+
|
|
564
|
+
All three combine the dropped sort with a `limit` — the "latest N" shape whose
|
|
565
|
+
failure #4226 spelled out: an unapplied sort returns rows in arbitrary order,
|
|
566
|
+
which `limit` then slices into an arbitrary page. #4226 fixed that in the wire
|
|
567
|
+
normalizer; these calls sit one layer below it. `listLinks` had no test at all,
|
|
568
|
+
which is why it went unnoticed. Now pinned — on the option bag the engine
|
|
569
|
+
receives, not on row order, because the failure is that the key never becomes
|
|
570
|
+
`orderBy` and a fake engine honouring either spelling would pass either way.
|
|
571
|
+
|
|
572
|
+
**The cleanup — 27 no-op renames.** Every remaining in-repo engine call passing
|
|
573
|
+
`filter` now passes `where` (approvals 5, auth 2, reports 6, sharing 11,
|
|
574
|
+
webhooks 2, plus the one `filters` in a spec doc example). These are strict
|
|
575
|
+
no-ops since #4346 folds the alias — the point is that the framework stops
|
|
576
|
+
depending on a spelling it asks users to migrate off, which is a prerequisite
|
|
577
|
+
for ever retiring the aliases. Service-level `filter` PARAMETERS (each
|
|
578
|
+
service's own public API, e.g. `listRequests(filter)`) are deliberately
|
|
579
|
+
untouched — those are not engine option bags.
|
|
580
|
+
|
|
581
|
+
Two of the renamed calls were live victims of the #4346 bug rather than
|
|
582
|
+
cosmetic: `auth-manager`'s `stampIdentitySource` read the table's first row via
|
|
583
|
+
`findOne({filter})` and counted the whole table via `count({filter})`, so a
|
|
584
|
+
federated sign-in never stamped `source: 'idp_provisioned'`. #4346 already
|
|
585
|
+
corrected the behaviour; this makes the call say what it means.
|
|
586
|
+
|
|
587
|
+
- 8af76ae: The i18n extractor's default locale now tracks the source instead of merging (#8543), and the approval vocabularies carry authored English labels in the contract (#8580).
|
|
588
|
+
|
|
589
|
+
- `os i18n extract` merge mode no longer applies to the default locale: `en` is a copy of the source, not a translation, so an edited label/description/help now reaches the regenerated `en` bundle instead of being silently shadowed by the stale entry forever (53 stale entries had accumulated across 6 packages under the old behavior; all rewritten here). Translated locales (`zh-CN` / `ja-JP` / `es-ES`) keep merge semantics exactly as before — no existing translation is overwritten.
|
|
590
|
+
- Bare-string and label-less select options now seed through the extractor's derived channel: the machine value still seeds the skeleton, but the coverage gate no longer demands "translations" of machine identifiers, and a copied value can no longer masquerade as authored display text.
|
|
591
|
+
- New `@objectstack/spec/contracts` exports `APPROVAL_STATUS_LABELS` and `APPROVAL_ACTION_KIND_LABELS`: the authored English for `sys_approval_request.status` (previously living only in the generated `en` bundle) and `sys_approval_action.action` (previously shipping raw machine values such as `submit` / `request_info` — the #7232 humanization missed this sibling field). Both columns derive their option labels from these maps; the regenerated `en` bundles copy them verbatim.
|
|
592
|
+
|
|
593
|
+
- aff9e56: fix(i18n): translate the platform packages' declared surface, and gate all nine bundles instead of one (#3762)
|
|
594
|
+
|
|
595
|
+
Only `platform-objects` was wired into a translation-drift check. The other
|
|
596
|
+
**eight** packages shipped a `scripts/i18n-extract.config.ts` that nothing ever
|
|
597
|
+
ran — and four of them had already drifted out of sync with the schema, exactly
|
|
598
|
+
the rot `pnpm check:i18n` exists to catch, one directory over.
|
|
599
|
+
|
|
600
|
+
**Translated.** `plugin-security` (45 strings per locale), `plugin-webhooks`
|
|
601
|
+
(15), `plugin-audit` (8), `plugin-sharing` (7) and `service-storage` (7) are now
|
|
602
|
+
at **zero** untranslated declared strings in zh-CN / ja-JP / es-ES — 246
|
|
603
|
+
translations. Most were newly _visible_ rather than newly missing: #3753 taught
|
|
604
|
+
the coverage detector to walk action `params`, `resultDialog`, `listViews` and
|
|
605
|
+
the rest of the declared surface, and these are what it found.
|
|
606
|
+
|
|
607
|
+
Wording was harvested from the repo's own bundles wherever a string was already
|
|
608
|
+
translated somewhere (1382 unambiguous source strings), so `Created At` reads
|
|
609
|
+
`创建时间` here because that is what it reads everywhere else, rather than a
|
|
610
|
+
fresh invention. Protocol tokens are deliberately left identical across locales:
|
|
611
|
+
`GET` / `POST` / `PUT` / `PATCH` / `DELETE`, `ETag`, `ACL`, `URL`.
|
|
612
|
+
|
|
613
|
+
**Gated.** `scripts/check-i18n-bundles.mjs` replaces the single-package
|
|
614
|
+
`pnpm check:i18n` and checks all nine. It does not restate each package's
|
|
615
|
+
command — it parses the one already documented in that config's own docstring
|
|
616
|
+
and runs it, so the documented regenerate command and the gate cannot diverge.
|
|
617
|
+
The coverage ratchet grows the same way, from `examples/*` to twelve configs;
|
|
618
|
+
eight of them sit at zero, which makes it the strict gate there.
|
|
619
|
+
|
|
620
|
+
**Fixed a real truncation bug it exposed.** `os lint --json` on a large config
|
|
621
|
+
came out of a pipe cut off at exactly 65536 bytes — `console.log(big)` followed
|
|
622
|
+
by `process.exit(1)` tears the process down before an async pipe write drains,
|
|
623
|
+
while an interactive run (stdout is a TTY, written synchronously) looks perfect.
|
|
624
|
+
Every scripted consumer silently got invalid JSON. `emitJson` in
|
|
625
|
+
`packages/cli/src/utils/format.ts` waits for the write to drain and sets
|
|
626
|
+
`process.exitCode` instead; `lint`, `i18n check` and `i18n extract` use it.
|
|
627
|
+
Roughly 30 other CLI commands share the pattern and are not touched here.
|
|
628
|
+
|
|
629
|
+
The nine documented regenerate commands also gain `--no-metadata-forms` (added
|
|
630
|
+
in #3768), since the Studio metadata-form baseline belongs to `platform-objects`
|
|
631
|
+
alone, not to a copy in every plugin.
|
|
632
|
+
|
|
633
|
+
Not fixed here: `platform-objects`' own 77-per-locale gap is `apps.*` /
|
|
634
|
+
`dashboards.*` navigation and widget labels, which live outside the `objects`
|
|
635
|
+
subtree and cannot be scaffolded while the package extracts with
|
|
636
|
+
`--objects-only`. That needs an emit decision first — tracked in #3762.
|
|
637
|
+
|
|
638
|
+
- cc2de0e: chore(packaging): 20 packages stop publishing their sources, tests and build tooling (#4248)
|
|
639
|
+
|
|
640
|
+
These 20 packages declared no `files` field, so npm fell back to packing the
|
|
641
|
+
whole package directory. `npm pack --dry-run` on `@objectstack/plugin-webhooks`
|
|
642
|
+
listed **21 files** — 15 under `src/`, three of them unit tests
|
|
643
|
+
(`auto-enqueuer.test.ts`, `bootstrap-declared-webhooks.test.ts`, …), plus the
|
|
644
|
+
build-time `scripts/i18n-extract.config.ts`. `dist/` lands on top of that at
|
|
645
|
+
publish time rather than instead of it, so consumers were installing the
|
|
646
|
+
TypeScript sources and the test suite alongside the artifact they asked for.
|
|
647
|
+
|
|
648
|
+
Each now declares `"files": ["dist", "README.md"]`, matching the 29 packages
|
|
649
|
+
that already did. Nothing a consumer imports moves: every `main` / `types` /
|
|
650
|
+
`exports` target in all 20 already resolved inside `dist/`, which the new
|
|
651
|
+
`check:published-files` guard verifies rather than assumes. The visible change
|
|
652
|
+
is a smaller install and a smaller dependency-scanning surface — `npm pack` on
|
|
653
|
+
`@objectstack/plugin-webhooks` now yields 2 files plus `dist/`.
|
|
654
|
+
|
|
655
|
+
The other half of the fix is the gate. Half the packages declaring `files` and
|
|
656
|
+
half not was the #3786 shape — a hand-copied convention with nothing enforcing
|
|
657
|
+
it, where whoever forgets the line gets no signal at all. `check:published-files`
|
|
658
|
+
(new, wired into the always-required `lint` job) holds every non-private
|
|
659
|
+
workspace package to four invariants: `files` is **declared**; it is
|
|
660
|
+
**sufficient** (covers every entry point, so tightening a whitelist cannot ship
|
|
661
|
+
a package that fails to resolve); it is **minimal** (admits no test, test-harness
|
|
662
|
+
config or build script); and anything beyond `dist` + `README.md` is
|
|
663
|
+
**registered** with a reason, reconciled in both directions so a stale exemption
|
|
664
|
+
is an error rather than dead text. `@objectstack/spec` is the one package with
|
|
665
|
+
registered extras — its `.zod.ts` sources, JSON Schemas, liveness ledgers and
|
|
666
|
+
`CHANGELOG.md` are product, not build input.
|
|
667
|
+
|
|
668
|
+
This also closes an assumption #4206 was resting on. Excluding `<pkg>/scripts/**`
|
|
669
|
+
from the docs-drift implementation test is sound only while no package publishes
|
|
670
|
+
`scripts/` as runtime code; that held, but it held because someone read all three
|
|
671
|
+
offenders by hand. It is now checked on every PR.
|
|
672
|
+
|
|
673
|
+
- 52281b0: chore(i18n): purge the dead sys_webhook_delivery translation block and guard against recurrence
|
|
674
|
+
|
|
675
|
+
`sys_webhook_delivery` was removed when webhook delivery moved to
|
|
676
|
+
`@objectstack/service-messaging` (`sys_http_delivery`, ADR-0018 M3), but a full
|
|
677
|
+
translation block for it lingered in the four generated plugin-webhooks i18n
|
|
678
|
+
bundles (en/zh-CN/ja-JP/es-ES) — dead weight bound to an object that no longer
|
|
679
|
+
exists, and destined to be dropped silently (with any curated strings) on the
|
|
680
|
+
next `os i18n extract`.
|
|
681
|
+
|
|
682
|
+
- Removed the stale `sys_webhook_delivery` block from all four locale bundles
|
|
683
|
+
(surgical; the `sys_webhook` block is untouched).
|
|
684
|
+
- Corrected three stale `sys_webhook_delivery` doc comments (platform-objects
|
|
685
|
+
`integration/index.ts` + `setup.app.ts`, plugin-webhooks `sys-webhook.object.ts`)
|
|
686
|
+
that still named it as a plugin-webhooks-owned object.
|
|
687
|
+
- Rolled out the platform-objects `bundle-ownership` test guard (#2834 ⑤ /
|
|
688
|
+
ADR-0029 D8) to the eight packages that own i18n bundles, so a stray object
|
|
689
|
+
block in a generated bundle now fails the build instead of dying silently.
|
|
690
|
+
- That guard immediately surfaced a live-object omission: `sys_capability` was
|
|
691
|
+
present in plugin-security's bundles with curated translations but had been
|
|
692
|
+
dropped from its extract config — re-added to the config so the strings are
|
|
693
|
+
preserved, rather than deleted.
|
|
694
|
+
|
|
695
|
+
- 30f1b74: fix(plugins): a declared item reaches its schema intact — retire the `i?.content ?? i` unwrap from plugin read paths (#8378)
|
|
696
|
+
|
|
697
|
+
Ten production reads over `SchemaRegistry.listItems` unwrapped every declared
|
|
698
|
+
item as `i?.content ?? i`, presuming a `{ name, content }` storage envelope.
|
|
699
|
+
That envelope has **no producer**. Re-measured at these seams rather than
|
|
700
|
+
inherited from #7519's measurement of `MetadataFacade`:
|
|
701
|
+
|
|
702
|
+
- `registerMetadataCollections` (objectql) registers each stack-collection
|
|
703
|
+
element as-is — `registerItem(type, item, 'name')`, no boxing;
|
|
704
|
+
- `loadMetaFromDb` registers `convertStoredItem(JSON.parse(record.metadata))` —
|
|
705
|
+
the parsed body, never the `sys_metadata` row (whose body column is
|
|
706
|
+
`metadata`, not `content`);
|
|
707
|
+
- the facade's own interim boxing of non-object values, the one writer that ever
|
|
708
|
+
produced the shape, was removed by #8349.
|
|
709
|
+
|
|
710
|
+
**Removal is a fix, not a cleanup.** None of the types read through these seams
|
|
711
|
+
— `permission`, `position`, `capability`, `object`, `sharingRule`, `webhook`,
|
|
712
|
+
`emailTemplate` — declares a stored `content` key; every one of them rejects it
|
|
713
|
+
as an unrecognized key. So wherever the key did appear the unwrap replaced a
|
|
714
|
+
whole authoring document with one of its values, and `''` — falsy but
|
|
715
|
+
non-nullish — passed `??` and then died at the reader's own `filter(Boolean)`,
|
|
716
|
+
dropping the item with no warning, no count and no row.
|
|
717
|
+
|
|
718
|
+
**On email templates the harm was sharpest, and it is the one users will
|
|
719
|
+
notice.** `content` really is a spelling an author can write there:
|
|
720
|
+
`EmailTemplateDefinitionSchema` lists it in its `strictObject` **aliases** table
|
|
721
|
+
(`content: 'bodyHtml'`). That table is a _rejection_ facility, not a conversion —
|
|
722
|
+
it feeds `strictUnknownKeyError`, which runs only on the `unrecognized_keys`
|
|
723
|
+
path and only builds a message; nothing rewrites the key, and the ADR-0087
|
|
724
|
+
conversion layer has no `email_template` entry either. The schema was therefore
|
|
725
|
+
always ready with the author's fix, and the unwrap was the one thing standing
|
|
726
|
+
between the author and it: the HTML string reached
|
|
727
|
+
`EmailTemplateDefinitionSchema.parse()`, which answered `Invalid input: expected
|
|
728
|
+
object, received string`, and the boot warning's `name` field came back
|
|
729
|
+
`undefined` — so an operator could not even tell **which** template had failed.
|
|
730
|
+
|
|
731
|
+
A template authored with `content` now yields what it was always meant to:
|
|
732
|
+
|
|
733
|
+
> Unrecognized key(s) on this email template: `content`. Did you mean
|
|
734
|
+
> `content` → `bodyHtml`?
|
|
735
|
+
|
|
736
|
+
…named against the template it came from, and counted as `skipped` rather than
|
|
737
|
+
vanishing.
|
|
738
|
+
|
|
739
|
+
No behaviour changes for spec-valid metadata: the reads hand back exactly the
|
|
740
|
+
documents they always did.
|
|
741
|
+
|
|
742
|
+
- 2465133: fix(plugins): sweep the service-lookup erasures out of the plugin composition roots, and fix the two alias-only HTTP reads it exposed (#4251 B5)
|
|
743
|
+
|
|
744
|
+
Batch B5 of the #4251 sweep: the seven remaining `packages/plugins/*` composition
|
|
745
|
+
roots. 35 lookup sites that had been erased to `any` now carry the slot's
|
|
746
|
+
contract, so the compiler checks what each plugin actually calls on the service
|
|
747
|
+
it resolved. The ratchet drops 143 sites / 32 files to 108 / 25.
|
|
748
|
+
|
|
749
|
+
**Two real defects, both of the shape this sweep exists to find.** Approvals'
|
|
750
|
+
actionable-link pages (ADR-0043) and sharing's public share-link REST routes each
|
|
751
|
+
read the HTTP server under `http-server` _only_ — the deprecated alias. The
|
|
752
|
+
ledger records `http.server` as canonical and as the only name present on every
|
|
753
|
+
provider path: `runtime.ts`'s `config.server` path registers no alias at all. On
|
|
754
|
+
that path both lookups threw, the surrounding `catch` swallowed it, and the
|
|
755
|
+
routes silently never mounted — approval e-mail action links 404'd and the
|
|
756
|
+
share-link surface was absent, with nothing in the log to say so. Both reads are
|
|
757
|
+
now canonical-first with the alias as fallback, each name in its own `try`
|
|
758
|
+
because `getService` throws on an empty slot (so `a() ?? b()` inside one `try`
|
|
759
|
+
never reaches `b` — the same correction #4393 made in metadata and
|
|
760
|
+
cloud-connection).
|
|
761
|
+
|
|
762
|
+
Typing choices follow the batch method: pure data-plane consumers take the
|
|
763
|
+
narrow contract (`IDataEngine` in reports), consumers that bind hook or
|
|
764
|
+
middleware seams take the engine seen whole (`IObjectQLEngine` in approvals,
|
|
765
|
+
sharing and pinyin-search), and slots with no contract get a **named** local
|
|
766
|
+
surface rather than `any` — plugin-email's `MailSettingsSurface`, and the
|
|
767
|
+
surfaces the consuming packages already declared (`ApprovalMessagingSurface`,
|
|
768
|
+
`SharingSecurityProbe`, `ReportEmail`). A named surface that omits a member
|
|
769
|
+
still makes the compiler name every call site; `any` says nothing.
|
|
770
|
+
|
|
771
|
+
No behaviour change beyond the two alias reads. No contract changes.
|
|
772
|
+
|
|
773
|
+
- b45c71e: fix(plugin-security,plugin-sharing,plugin-webhooks,platform-objects,service-messaging,spec): five tenant-scoped declared unique indexes become per-organization (#8554)
|
|
774
|
+
|
|
775
|
+
Five platform objects declared their uniqueness as a table-level index with bare
|
|
776
|
+
`unique: true`. At the DECLARED-index level that is the positional spelling of
|
|
777
|
+
`'global'` — the listed columns verbatim — so on a tenant-scoped object each
|
|
778
|
+
materialized an **installation-wide** unique index. (Field-level `unique: true`
|
|
779
|
+
means the opposite, per-organization, and has since #3696; `packages/lint` names
|
|
780
|
+
that divergence "the #4986 trap" and warns on it via
|
|
781
|
+
`unique/unscoped-declared-index`.) These are the fourth act of the class ruled on
|
|
782
|
+
2026-08-13, after `sys_user_preference` / `sys_capability` (#8461) and
|
|
783
|
+
`sys_position` (#8556).
|
|
784
|
+
|
|
785
|
+
| object | package | was | now |
|
|
786
|
+
| ----------------------------- | ------------------- | ---------------------------------- | --------------------------------- |
|
|
787
|
+
| `sys_permission_set` | `plugin-security` | `[name]` global | `[name]` per organization |
|
|
788
|
+
| `sys_sharing_rule` | `plugin-sharing` | `[name]` global | `[name]` per organization |
|
|
789
|
+
| `sys_webhook` | `plugin-webhooks` | `[name]` global | `[name]` per organization |
|
|
790
|
+
| `sys_email_template` | `platform-objects` | `[name, locale]` global | `[name, locale]` per organization |
|
|
791
|
+
| `sys_notification_preference` | `service-messaging` | `[user_id, topic, channel]` global | same, per organization |
|
|
792
|
+
|
|
793
|
+
Measured live on a real engine before the fix — two organizations, the same key,
|
|
794
|
+
`OS_TENANCY_POSTURE=isolated`, driving the real shipped declarations. All five
|
|
795
|
+
reproduced identically:
|
|
796
|
+
|
|
797
|
+
```
|
|
798
|
+
org_jia POST the key → 201
|
|
799
|
+
org_yi POST the SAME → 409 UNIQUE_VIOLATION
|
|
800
|
+
org_yi POST an unused → 201 ← the control that makes it an oracle
|
|
801
|
+
org_yi GET the key → total 0 ← refused by a row it cannot see
|
|
802
|
+
```
|
|
803
|
+
|
|
804
|
+
Two consequences, both removed. **A cross-tenant existence oracle:** the 409 is a
|
|
805
|
+
per-value answer about a row the caller cannot read, so an organization could
|
|
806
|
+
enumerate another organization's permission-set, sharing-rule, webhook and
|
|
807
|
+
template naming. **A functional dead end:** the second organization simply could
|
|
808
|
+
not use the name, and the refusal did not say why. For
|
|
809
|
+
`sys_notification_preference` the shape is the one #8323 measured on
|
|
810
|
+
`sys_user_preference` — a user belonging to two organizations could not hold
|
|
811
|
+
independent per-topic delivery toggles.
|
|
812
|
+
|
|
813
|
+
## ⚠️ Operators: a migration is REQUIRED, and deploying this release is not it
|
|
814
|
+
|
|
815
|
+
Respelling a declared index changes its generated **name**. On an existing
|
|
816
|
+
database `initObjects` is additive: it creates the new per-organization composite
|
|
817
|
+
at boot and **never drops the old global index**, which goes on enforcing. Until
|
|
818
|
+
the retirement is applied, a deployed installation that has taken this release is
|
|
819
|
+
still enumerable — that is asserted as a test, not assumed.
|
|
820
|
+
|
|
821
|
+
Run the migration:
|
|
822
|
+
|
|
823
|
+
```
|
|
824
|
+
os migrate plan # shows one `replace_unique_index` per object, categorised `safe`
|
|
825
|
+
os migrate apply # no --allow-destructive needed
|
|
826
|
+
```
|
|
827
|
+
|
|
828
|
+
Each object plans as **one pure relaxation**, not as two findings. That matters:
|
|
829
|
+
if it read as "composite missing" (safe) plus "old global index orphaned"
|
|
830
|
+
(destructive, opt-in), an operator applying only the safe half would keep the
|
|
831
|
+
global index — keep the defect — while the plan read as applied. The `#8461`
|
|
832
|
+
`replace_unique_index` arm covers all five unchanged (no driver change in this
|
|
833
|
+
release), applies CREATE-before-DROP so uniqueness is never unenforced in
|
|
834
|
+
between, drops the legacy index only once the replacement is confirmed present,
|
|
835
|
+
preserves every row, and converges to no drift.
|
|
836
|
+
|
|
837
|
+
Two columns are worth an operator's attention:
|
|
838
|
+
|
|
839
|
+
- `sys_notification_preference`'s replacement index name is **hash-suffixed** —
|
|
840
|
+
`uniq_sys_notification_preference_a22d7d27` — because the natural name is 70
|
|
841
|
+
characters and the limit is 60. That is expected, not corruption.
|
|
842
|
+
- Rows with no `organization_id` (platform/seed rows) stay unique **among
|
|
843
|
+
themselves**: the organization key part is NULL-safe
|
|
844
|
+
(`COALESCE(organization_id, '__global__')`, ADR-0120 D3), so seeding by name
|
|
845
|
+
keeps working and a tenant may hold its own row of the same name.
|
|
846
|
+
|
|
847
|
+
## Not breaking
|
|
848
|
+
|
|
849
|
+
A relaxation admits key pairs that were previously refused and refuses nothing
|
|
850
|
+
that previously succeeded, so no caller that worked before fails now. Every read
|
|
851
|
+
path for these five objects goes through the tenant-scoped data API, so no
|
|
852
|
+
consumer resolves one of these names across organizations expecting at most one
|
|
853
|
+
row. Shipped as `patch` for that reason — the same call #8556 made for the same
|
|
854
|
+
shape.
|
|
855
|
+
|
|
856
|
+
Published text carrying the bare uniqueness claim was corrected at its source and
|
|
857
|
+
the generated reference pages regenerated (`security/permission.mdx`,
|
|
858
|
+
`automation/webhook.mdx`, and `integration/connector.mdx`, which embeds the same
|
|
859
|
+
webhook schema), together with the `sys_permission_set` field description, its
|
|
860
|
+
clone-dialog help text, the `sys_webhook` field description, and the matching
|
|
861
|
+
translation bundles in all four shipped locales.
|
|
862
|
+
|
|
863
|
+
- f46e987: fix(plugin-webhooks): a webhook holding an encrypted signing secret re-arms the moment the CryptoProvider registers, instead of ~60s later (#8022)
|
|
864
|
+
|
|
865
|
+
For roughly **60 seconds after every server start**, a webhook whose
|
|
866
|
+
`signing_secret` is encrypted (the population #7799 created) was **not
|
|
867
|
+
subscribed**. A record change in that window produced no delivery **and no
|
|
868
|
+
`sys_http_delivery` row at all** — no dead letter, no retry, no durable trace
|
|
869
|
+
that anything was missed — while `GET /api/v1/data/sys_webhook/` kept reading
|
|
870
|
+
`active: true`, so the webhook looked armed in Setup the whole time. It
|
|
871
|
+
self-healed at the next periodic cache refresh, which is why it was invisible to
|
|
872
|
+
anyone not watching that window.
|
|
873
|
+
|
|
874
|
+
**The fail-closed behaviour is unchanged and is not the bug.** Dropping a
|
|
875
|
+
subscription whose stored key cannot be recovered — rather than delivering it
|
|
876
|
+
unsigned — is #7799's whole point and still holds: the signature is the
|
|
877
|
+
receiver's only proof of origin, and a webhook that stops arriving gets
|
|
878
|
+
investigated while one that keeps arriving unsigned teaches the receiver to
|
|
879
|
+
accept unauthenticated traffic. What was wrong is that a fail-closed drop
|
|
880
|
+
outlived its own cause.
|
|
881
|
+
|
|
882
|
+
**The ordering.** It was never a race that sometimes went the other way. Plugins
|
|
883
|
+
run inside `kernel:ready`, which `runtime.start()` completes; the host's
|
|
884
|
+
composition root calls `engine.setCryptoProvider(...)` only _after_
|
|
885
|
+
`runtime.start()` returns (`packages/cli/src/commands/serve.ts`,
|
|
886
|
+
`packages/verify/src/harness.ts`). So `AutoEnqueuer`'s first subscription-cache
|
|
887
|
+
build reliably preceded the capability it needs, dropped every secret-bearing
|
|
888
|
+
row on what it could see, and nothing re-read until the periodic refresh.
|
|
889
|
+
|
|
890
|
+
`ObjectQL` now reports the registration (`onCryptoProviderChange(listener)`,
|
|
891
|
+
fired after the provider is in place), and the auto-enqueuer subscribes
|
|
892
|
+
**before** its first build and rebuilds the cache when it fires. Re-arming is
|
|
893
|
+
immediate and event-driven — no polling, and no shorter-but-still-present
|
|
894
|
+
window. The re-arm deliberately does not join an in-flight refresh: the build
|
|
895
|
+
most likely running at that moment is the pre-registration one, and joining it
|
|
896
|
+
would report success having re-armed nothing.
|
|
897
|
+
|
|
898
|
+
The channel is feature-detected, as `resolveSecretField` already was — this
|
|
899
|
+
plugin takes no dependency on `@objectstack/objectql`. An engine without it keeps
|
|
900
|
+
the previous behaviour, with the periodic refresh as the backstop.
|
|
901
|
+
|
|
902
|
+
**The drop is also no longer quiet.** A subscription dropped for an unresolvable
|
|
903
|
+
key now reports at `error` with the consequence and the fix stated in the
|
|
904
|
+
message, and carries an ADR-0112 `code`/`status` pair (`INTERNAL_ERROR`/500) in
|
|
905
|
+
its metadata — the same pair the seeder's refusal for the same cause already
|
|
906
|
+
carried. Per AGENTS.md it is said **once** per outage per webhook rather than
|
|
907
|
+
every refresh cycle, and a webhook that recovers and breaks again is loud again.
|
|
908
|
+
|
|
909
|
+
Unaffected, and verified still true: the secret's bytes appear nowhere in
|
|
910
|
+
`sys_webhook` or in a delivery row, deliveries carry `signature` and never the
|
|
911
|
+
key (#7722), and a delivery whose key exists only as ciphertext after a restart
|
|
912
|
+
still produces the byte-identical HMAC receivers already verify.
|
|
913
|
+
|
|
914
|
+
- 1602949: fix(plugin-webhooks): webhook custom `headers` are encrypted at rest instead of riding `definition_json` in cleartext (#7986)
|
|
915
|
+
|
|
916
|
+
`#7799` moved the webhook **signing secret** out of `sys_webhook.definition_json`
|
|
917
|
+
into an encrypted `signing_secret` column. It did not move the custom **headers**
|
|
918
|
+
map — and `headers` is the ordinary place an `Authorization: Bearer …` goes.
|
|
919
|
+
|
|
920
|
+
`sys_webhook` declares **no `enable` block at all**, so it keeps the full default
|
|
921
|
+
data API: an ordinary `GET /api/v1/data/sys_webhook` handed the whole header map,
|
|
922
|
+
credentials included, to every persona that can read the object. Unlike the
|
|
923
|
+
delivery table's copies, nothing ages this out — the configuration row is
|
|
924
|
+
retained for the life of the webhook.
|
|
925
|
+
|
|
926
|
+
This is a **scope-of-the-original-fix** finding, not a regression: the exposure
|
|
927
|
+
predates `#7799` and nothing that card did made it worse. What was wrong was the
|
|
928
|
+
conclusion a reader would reasonably draw from it — that webhook credentials are
|
|
929
|
+
no longer in a blob.
|
|
930
|
+
|
|
931
|
+
**What changed.** The authored `headers` map now lands in a new
|
|
932
|
+
`sys_webhook.headers_secret` column on the engine's encrypted credential channel,
|
|
933
|
+
exactly as `signing_secret` does: the engine encrypts it into `sys_secret`, the
|
|
934
|
+
row keeps only an opaque `secret:<id>` ref, and every read path returns a mask.
|
|
935
|
+
`definition_json` carries the same envelope minus both credential passengers. The
|
|
936
|
+
auto-enqueuer recovers the map server-side through `engine.resolveSecretField()`
|
|
937
|
+
on the **same** cache refresh that recovers the signing key, and the existing
|
|
938
|
+
boot sweep (`migrateLegacyWebhookSecrets`) now moves already-persisted cleartext
|
|
939
|
+
headers out of the blob in the same single, idempotent update it uses for the
|
|
940
|
+
key.
|
|
941
|
+
|
|
942
|
+
**Nothing about authoring changes.** Authors still write
|
|
943
|
+
`headers: { … }` on `defineWebhook()`, `webhook.zod.ts` is untouched, and every
|
|
944
|
+
authored header is still delivered on the wire byte-for-byte.
|
|
945
|
+
|
|
946
|
+
**The whole map moves, not just the credential-looking entries.** Only some
|
|
947
|
+
entries are credentials and the platform cannot tell which. Guessing from the
|
|
948
|
+
header name (`authorization`, `x-api-key`, …) is fail-**open** on exactly the
|
|
949
|
+
custom spellings — `X-Acme-Token` — most likely to be one, and a heuristic that
|
|
950
|
+
silently passes the header that mattered is worse than none because it reads as
|
|
951
|
+
coverage. Letting the author declare which are sensitive is a change to the
|
|
952
|
+
authoring envelope and belongs to the spec surface. The cost this shape is
|
|
953
|
+
accused of is measured and small: `definition_json` is a raw JSON textarea
|
|
954
|
+
pending a real builder, so what an admin loses is the ability to read back a
|
|
955
|
+
`Content-Type` they typed.
|
|
956
|
+
|
|
957
|
+
**Fail-closed, and symmetric with `#7799`.** With no CryptoProvider the engine
|
|
958
|
+
refuses the write rather than storing cleartext; a stored map that cannot be
|
|
959
|
+
decrypted **drops** the subscription rather than delivering it with its headers
|
|
960
|
+
silently missing. That drop is deliberately the same trade the signing secret
|
|
961
|
+
makes: against an endpoint that does not require the header, a delivery missing
|
|
962
|
+
its `Authorization` **succeeds** while quietly deviating from the configuration
|
|
963
|
+
the author wrote, and nothing records that it went out incomplete. Subscriptions
|
|
964
|
+
dropped this way re-arm on CryptoProvider registration exactly as `#8022` made
|
|
965
|
+
them — the header map is resolved on the same rebuilt cache as the key, so a
|
|
966
|
+
re-arm can never produce a correctly-signed delivery with no headers on it.
|
|
967
|
+
|
|
968
|
+
**This does not close the exposure end to end.** The same headers are still
|
|
969
|
+
written in cleartext to `sys_http_delivery.headers_json` at enqueue time, and
|
|
970
|
+
that table is readable over the data API (`apiMethods: ['get','list']`, 30-day
|
|
971
|
+
retention). Measured after this change: the credential is still recoverable
|
|
972
|
+
there. Closing that half needs a decision outside this package and is tracked on
|
|
973
|
+
#7986; `sys_email.headers_json` (the same shape, on the email delivery row) is
|
|
974
|
+
untouched here for the same reason.
|
|
975
|
+
|
|
976
|
+
- 06306f1: fix(service-messaging): stop persisting webhook HMAC signing secrets on every delivery row (#7722)
|
|
977
|
+
|
|
978
|
+
`sys_http_delivery` carried the caller's `signingSecret` verbatim, once per
|
|
979
|
+
delivery attempt, in a plain `signing_secret` column — and that table is
|
|
980
|
+
readable over the ordinary data API (`GET /api/v1/data/sys_http_delivery`).
|
|
981
|
+
Anyone who could read deliveries recovered the shared key that authenticates
|
|
982
|
+
ObjectStack to the receiver, for **every** subscriber at once. The signature is
|
|
983
|
+
the receiver's only proof of origin, so the blast radius reaches outside the
|
|
984
|
+
deployment: a leaked key mints payloads the receiver accepts as genuine, and
|
|
985
|
+
rotating it means re-coordinating with every receiver operator.
|
|
986
|
+
|
|
987
|
+
**The row now carries the signature, not the key.** A delivery's body is
|
|
988
|
+
decided at enqueue and replayed byte-for-byte by every retry and by
|
|
989
|
+
`redeliver()` — so the HMAC has exactly one correct value for the row's whole
|
|
990
|
+
life. `enqueue()` computes it once from the producer's secret and stores only
|
|
991
|
+
the result (`signature`, `sha256=<hex>`); the secret is consumed and dropped.
|
|
992
|
+
The stored value is what the receiver is handed on the wire anyway and is
|
|
993
|
+
one-way in the key, so reading a delivery row tells you what was sent, not how
|
|
994
|
+
to forge something else.
|
|
995
|
+
|
|
996
|
+
Signing behaviour on the wire is unchanged: `X-Objectstack-Signature` still
|
|
997
|
+
carries `sha256=HMAC-SHA256(raw body, secret)` and verifies against the
|
|
998
|
+
subscriber's secret exactly as before — now pinned by tests that recompute the
|
|
999
|
+
HMAC over the delivered body rather than asserting a header is merely present,
|
|
1000
|
+
and by an at-rest guard that byte-scans every column of a real delivery table
|
|
1001
|
+
after a real delivery.
|
|
1002
|
+
|
|
1003
|
+
Producers are unaffected: `enqueueHttp({ …, signingSecret })` keeps its shape
|
|
1004
|
+
for both callers (webhook fan-out and the Flow `http` node), and the fix sits at
|
|
1005
|
+
the outbox, so both stop writing cleartext.
|
|
1006
|
+
|
|
1007
|
+
**Upgrading.** The `signing_secret` column is no longer declared, so an existing
|
|
1008
|
+
database keeps it as an unmapped column holding the old cleartext until it is
|
|
1009
|
+
dropped: run `os migrate plan` and apply the reported `drop_column` op (it is
|
|
1010
|
+
classified destructive, so it is never applied unattended). Until then those
|
|
1011
|
+
rows also age out on the table's existing 30-day telemetry retention. Rotate any
|
|
1012
|
+
signing secret that was exposed. Code reading `HttpDelivery.signingSecret` off a
|
|
1013
|
+
row should read `signature` instead — the secret is not available there by
|
|
1014
|
+
design.
|
|
1015
|
+
|
|
1016
|
+
- bbe05de: A dropped webhook subscription now leaves a durable record, and no operator action can turn that record into an unsigned delivery (#8069).
|
|
1017
|
+
|
|
1018
|
+
When the auto-enqueuer cannot decrypt a webhook's signing secret or its custom header map, it drops the subscription rather than delivering unsigned (#7799, #7986). Until now the drop left no `sys_http_delivery` row at all: every matching record change was discarded with nothing an operator reading the delivery table could find. `#8043` made that loud in the logs; it did not make it durable.
|
|
1019
|
+
|
|
1020
|
+
Each discarded event is now recorded as a `sys_http_delivery` row with `status: dead`, `attempts: 0`, and the cause and remedy in the existing `error` column — so it appears in the object's existing "Failures" view with no new lifecycle state and no migration.
|
|
1021
|
+
|
|
1022
|
+
The record is unsendable by construction, which is the half that matters:
|
|
1023
|
+
|
|
1024
|
+
- `redeliver()` refuses any terminal row with `attempts: 0`. Such a row was never sent, so re-sending it would be a **first** delivery — and a parked row carries no HMAC signature, because the secret that would have produced one is exactly what went missing. New error code `DELIVERY_NEVER_SENT` (409 on `POST /api/v1/webhooks/redeliver`).
|
|
1025
|
+
- `redeliver()` also consults a producer-registered guard, so a webhook row whose `sys_webhook` subscription was deleted, or whose stored signing secret can no longer be recovered, is refused rather than replayed. A guard whose own lookup fails refuses too.
|
|
1026
|
+
- The parked row never carries the authored header map, so a credential is not copied onto a row that will sit out the retention window without ever being sent.
|
|
1027
|
+
|
|
1028
|
+
Redelivery of a genuine dead-letter is unchanged: the same bytes, the same signature.
|
|
1029
|
+
|
|
1030
|
+
- bf1ea92: fix(plugin-webhooks): a stored header map that cannot be recovered parks the subscription instead of arming it and delivering the headers MISSING (#8558)
|
|
1031
|
+
|
|
1032
|
+
A webhook whose `sys_webhook.headers_secret` held a value that did not come back
|
|
1033
|
+
as a header map was treated as **authored without custom headers**. The
|
|
1034
|
+
subscription armed, every matching record change was delivered, and the entire
|
|
1035
|
+
authored map — the ordinary place an `Authorization: Bearer …` goes — was
|
|
1036
|
+
silently absent. Nothing logged, nothing dropped, and
|
|
1037
|
+
`GET /api/v1/data/sys_webhook` kept reporting `active: true` with the header
|
|
1038
|
+
column masked, so both the operator and the Setup UI still read "custom headers
|
|
1039
|
+
are configured".
|
|
1040
|
+
|
|
1041
|
+
Measured end to end against a real engine, what reached the receiver was worse
|
|
1042
|
+
than "a delivery with something missing": the request SUCCEEDED
|
|
1043
|
+
(`sys_http_delivery.status = 'success'`) carrying a byte-correct
|
|
1044
|
+
`X-Objectstack-Signature`. The signature is the receiver's proof the request is
|
|
1045
|
+
genuinely ours, so a receiver that authenticates by signature had every reason
|
|
1046
|
+
to accept a request that no longer matched the configuration its operator wrote.
|
|
1047
|
+
Against an endpoint that requires the credential the result is a 401 nobody
|
|
1048
|
+
attributes correctly; against one that does not — a routing `X-Tenant-Id`, an
|
|
1049
|
+
`X-Environment: staging` — the delivery is simply wrong and nobody finds out.
|
|
1050
|
+
|
|
1051
|
+
The cause was one return value carrying two facts. `resolveWebhookHeaders`
|
|
1052
|
+
answered `undefined` both for _"the author configured no custom headers"_ —
|
|
1053
|
+
legitimate, `headers` is optional on the envelope — and for _"a map is stored
|
|
1054
|
+
and did not come back as one"_. Its caller acts on the first reading, so the
|
|
1055
|
+
second became the first. This is the sibling of the signing-secret collapse
|
|
1056
|
+
(#8542) on the same seam's other credential, and the file's own header comment
|
|
1057
|
+
already promised the opposite: _"It does not deliver partially. A row whose
|
|
1058
|
+
stored headers cannot be resolved DROPS the subscription."_
|
|
1059
|
+
|
|
1060
|
+
**This path is wider than the signing-secret one, not symmetric to it.** A
|
|
1061
|
+
signing secret is an opaque scalar, so any non-empty answer is a usable key and
|
|
1062
|
+
only the empty string collapsed. A header map's CONTENT decides, and
|
|
1063
|
+
`parseStoredHeaders` answers `undefined` — correctly, for its own job — for every
|
|
1064
|
+
string that is not a flat JSON object of string values. Four states reach the
|
|
1065
|
+
seam, all confirmed against a real engine:
|
|
1066
|
+
|
|
1067
|
+
- the `sys_webhook` row is deleted between the enqueuer's cache read and the
|
|
1068
|
+
per-row dereference;
|
|
1069
|
+
- the column holds something that is not a `secret:` ref — reachable only
|
|
1070
|
+
through a write that bypasses the engine (a column edited in SQL, a dump
|
|
1071
|
+
restored without its `sys_secret` rows, a seed script writing at driver level);
|
|
1072
|
+
- the stored value decrypts to an **empty string**;
|
|
1073
|
+
- the stored value decrypts to a perfectly readable string that is **not a flat
|
|
1074
|
+
string map** — `{}`, `[]`, `{"X-Count": 5}`, a nested object, or any typo.
|
|
1075
|
+
This is the widest road rather than an exotic one: `headers_secret` is an
|
|
1076
|
+
admin-authorable field whose own description instructs the author to type a
|
|
1077
|
+
JSON object into it, and every one of these spellings is accepted by the
|
|
1078
|
+
ordinary data API, encrypted like any other value, and left behind a
|
|
1079
|
+
perfectly valid ref that reads back as the mask.
|
|
1080
|
+
|
|
1081
|
+
The fix is at the seam, so no consumer has to re-derive the rule: presence is
|
|
1082
|
+
already decidable there (`headers_secret` is a map only in the plaintext — at
|
|
1083
|
+
the storage layer it is an ordinary scalar `secret` column, so a set map comes
|
|
1084
|
+
back from the generic read path as the engine's mask and an unset one as `null`),
|
|
1085
|
+
and stored headers that do not come back as a map now raise rather than
|
|
1086
|
+
answering `undefined`. They therefore reach `AutoEnqueuer.attachHeaders` exactly
|
|
1087
|
+
the way a throwing resolver already did — the subscription is parked, the
|
|
1088
|
+
discarded event lands in `sys_http_delivery` with a cause (#8069), and the
|
|
1089
|
+
operator gets the existing remedy-bearing say-once `error` carrying
|
|
1090
|
+
`INTERNAL_ERROR` / `500` (ADR-0112) and naming `headers_secret`, so it cannot be
|
|
1091
|
+
confused with the signing secret's identical-looking drop.
|
|
1092
|
+
|
|
1093
|
+
**Unchanged:** a webhook authored with no custom headers at all still arms and
|
|
1094
|
+
delivers — that is a legitimate authored configuration, and it is pinned as the
|
|
1095
|
+
control for this change, as is a webhook whose stored map resolves normally and
|
|
1096
|
+
still delivers every header including the credential entry.
|
|
1097
|
+
|
|
1098
|
+
**What an operator sees after upgrading.** A webhook that was quietly delivering
|
|
1099
|
+
without its headers stops delivering and starts reporting. Re-save the headers
|
|
1100
|
+
as a flat JSON object of string values so the column holds a fresh ref, or
|
|
1101
|
+
**clear** the field to `null` if the webhook is meant to send no custom headers
|
|
1102
|
+
— an empty or unparseable header map is not the same thing as no header map,
|
|
1103
|
+
and only the second one means "send nothing extra".
|
|
1104
|
+
|
|
1105
|
+
- 719a21b: fix(plugin-webhooks): a stored signing secret that cannot be recovered parks the subscription instead of arming it and delivering UNSIGNED (#8542)
|
|
1106
|
+
|
|
1107
|
+
A webhook whose `sys_webhook.signing_secret` held a value that did not resolve
|
|
1108
|
+
was treated as **authored unsigned**. The subscription armed, every matching
|
|
1109
|
+
record change was delivered, and the HMAC signature — the receiver's only proof
|
|
1110
|
+
the delivery came from us — was silently absent. Nothing logged, nothing
|
|
1111
|
+
dropped, and `GET /api/v1/data/sys_webhook` kept reporting `active: true` with
|
|
1112
|
+
the secret column masked, so both the operator and the Setup UI still read
|
|
1113
|
+
"this webhook is signed".
|
|
1114
|
+
|
|
1115
|
+
The cause was one return value carrying two facts. `resolveWebhookSecret`
|
|
1116
|
+
answered `undefined` both for _"the author configured this webhook unsigned"_ —
|
|
1117
|
+
legitimate, `secret` is optional on the envelope — and for _"a key is stored and
|
|
1118
|
+
nothing came back"_. Its caller acts on the first reading, so the second became
|
|
1119
|
+
the first. That is the #7799 signing invariant failing **open**, immediately
|
|
1120
|
+
beside two adjacent failure modes that fail closed and loudly: a resolver that
|
|
1121
|
+
throws, and an engine with no encrypted-field channel, both of which drop the
|
|
1122
|
+
subscription and report at `error`.
|
|
1123
|
+
|
|
1124
|
+
Three states reach the silent path, all confirmed against a real engine:
|
|
1125
|
+
|
|
1126
|
+
- the `sys_webhook` row is deleted between the dispatcher's cache read and the
|
|
1127
|
+
per-row dereference;
|
|
1128
|
+
- the column holds something that is not a `secret:` ref — reachable only
|
|
1129
|
+
through a write that bypasses the engine (a column edited in SQL, a dump
|
|
1130
|
+
restored without its `sys_secret` rows, a seed script writing at driver
|
|
1131
|
+
level). The engine's own write path defends the two obvious routes: an echoed
|
|
1132
|
+
read-mask is dropped and cleartext is re-encrypted;
|
|
1133
|
+
- the stored value decrypts to an **empty string** — reachable through the
|
|
1134
|
+
ordinary data API, which accepts `signing_secret: ""`, encrypts it like any
|
|
1135
|
+
other value, and leaves the column holding a perfectly valid ref.
|
|
1136
|
+
|
|
1137
|
+
The fix is at the seam, so no consumer has to re-derive the rule: presence is
|
|
1138
|
+
already decidable there (a set secret comes back from the generic read path as
|
|
1139
|
+
the engine's mask, an unset one as `null`), and a stored key that does not
|
|
1140
|
+
resolve now raises rather than answering `undefined`. It therefore reaches
|
|
1141
|
+
`AutoEnqueuer.attachSecret` exactly the way a throwing resolver already did —
|
|
1142
|
+
the subscription is parked, the discarded event lands in `sys_http_delivery`
|
|
1143
|
+
with a cause (#8069), and the operator gets the existing remedy-bearing
|
|
1144
|
+
say-once `error` carrying `INTERNAL_ERROR` / `500` (ADR-0112).
|
|
1145
|
+
|
|
1146
|
+
**Unchanged:** a webhook authored with no secret at all still arms and delivers
|
|
1147
|
+
unsigned — that is a legitimate authored configuration, and it is pinned as the
|
|
1148
|
+
control for this change. The redelivery guard (#8069) keeps its behaviour in
|
|
1149
|
+
both directions: a stored-but-unresolvable key is still refused with its own
|
|
1150
|
+
reason, and any other failure still propagates, because "we could not check"
|
|
1151
|
+
must never read as "allowed".
|
|
1152
|
+
|
|
1153
|
+
**What an operator sees after upgrading.** A webhook that was quietly delivering
|
|
1154
|
+
unsigned stops delivering and starts reporting. If the deliveries were meant to
|
|
1155
|
+
be signed, re-save the secret so the column holds a fresh ref. If the webhook
|
|
1156
|
+
was meant to be unsigned, **clear** the field to `null` — an empty secret is not
|
|
1157
|
+
the same thing as no secret, and only the second one means "unsigned".
|
|
1158
|
+
|
|
1159
|
+
- e3a6f6e: fix(webhooks): the subscriber's HMAC signing secret is no longer readable from `sys_webhook` over the data API (#7799)
|
|
1160
|
+
|
|
1161
|
+
`bootstrapDeclaredWebhooks` persisted the whole validated `Webhook` envelope —
|
|
1162
|
+
**`secret` included** — as `definition_json: JSON.stringify(wh)`, and
|
|
1163
|
+
`AutoEnqueuer.parseRow` read `defn.secret` straight back out to sign deliveries.
|
|
1164
|
+
`definition_json` is an ordinary textarea on an admin-authorable object with no
|
|
1165
|
+
restrictive `enable.apiMethods`, so a plain `GET /api/v1/data/sys_webhook`
|
|
1166
|
+
returned the key to **every persona that can read the object**. That key is the
|
|
1167
|
+
receiver's only proof that a delivery came from us.
|
|
1168
|
+
|
|
1169
|
+
This is the remaining half of #7722, which removed the same secret's per-attempt
|
|
1170
|
+
copies from `sys_http_delivery`. Unlike the delivery table, no retention window
|
|
1171
|
+
ever aged these out.
|
|
1172
|
+
|
|
1173
|
+
**What changed.** The authored key now lands in `sys_webhook.signing_secret`, a
|
|
1174
|
+
new `type: 'secret'` column: the engine encrypts it into `sys_secret` on write,
|
|
1175
|
+
keeps only an opaque `secret:<id>` ref on the row, and returns a mask on every
|
|
1176
|
+
read path. `definition_json` carries the same envelope **minus** `secret`. The
|
|
1177
|
+
auto-enqueuer recovers the plaintext server-side when it refreshes its
|
|
1178
|
+
subscription cache.
|
|
1179
|
+
|
|
1180
|
+
**Nothing about authoring changes.** `packages/spec/src/automation/webhook.zod.ts`
|
|
1181
|
+
is untouched — `defineWebhook({ secret })` is written exactly as before, and the
|
|
1182
|
+
delivered `X-Objectstack-Signature` is byte-identical, so no receiver has to
|
|
1183
|
+
change anything.
|
|
1184
|
+
|
|
1185
|
+
**Existing rows are migrated.** A boot sweep moves any cleartext
|
|
1186
|
+
`definition_json.secret` into the encrypted column — including the rows the
|
|
1187
|
+
seeder deliberately never rewrites (`managed_by: 'admin'`, and package rows an
|
|
1188
|
+
admin froze with `customized: true`), which are the ones most likely to hold a
|
|
1189
|
+
real production key. The sweep is idempotent and stores the encrypted copy in
|
|
1190
|
+
the same update that strips the blob, so a failure can never leave a webhook
|
|
1191
|
+
stripped _and_ unsigned. Until a row is swept, signing keeps working from the
|
|
1192
|
+
legacy blob and the enqueuer warns that the value is still exposed.
|
|
1193
|
+
|
|
1194
|
+
**Fail-closed.** With no `ICryptoProvider` wired the engine refuses the write
|
|
1195
|
+
rather than storing cleartext, so a secret-bearing webhook is skipped — and a
|
|
1196
|
+
legacy row is left intact — with an actionable log line carrying an ADR-0112
|
|
1197
|
+
`code`/`status` pair. It is never seeded with an exposed key in a new column.
|
|
1198
|
+
|
|
1199
|
+
Also adds `ObjectQL.resolveSecretField(object, recordId, field)` — the privileged,
|
|
1200
|
+
driver-level dereference of one row's `secret`-typed field. `resolveSecret()` was
|
|
1201
|
+
already documented for "privileged consumers … against the stored ref", but the
|
|
1202
|
+
read mask meant no consumer could obtain that ref; this is why the webhook key
|
|
1203
|
+
can live in the encrypted channel at all. It refuses any field not declared
|
|
1204
|
+
`type: 'secret'`, so it cannot become a mask bypass over a `password` field
|
|
1205
|
+
(plaintext at rest by design — ADR-0100).
|
|
1206
|
+
|
|
1207
|
+
- c95ac80: chore(plugin-webhooks): drop the dead sys_webhook_delivery i18n blocks
|
|
1208
|
+
|
|
1209
|
+
`sys_webhook_delivery` was removed from `@objectstack/plugin-webhooks` when
|
|
1210
|
+
outbound delivery moved to `@objectstack/service-messaging` (`sys_http_delivery`,
|
|
1211
|
+
ADR-0018 M3), but its translation blocks lingered in all four generated locale
|
|
1212
|
+
bundles (en / zh-CN / ja-JP / es-ES) — loaded at runtime yet referenced by
|
|
1213
|
+
nothing, since the object no longer exists in this plugin.
|
|
1214
|
+
|
|
1215
|
+
- Removed the `sys_webhook_delivery` node from each `*.objects.generated.ts`
|
|
1216
|
+
bundle; `WebhooksTranslations` now carries only `sys_webhook`.
|
|
1217
|
+
- Corrected the stale ownership comment on `SysWebhook` that still named
|
|
1218
|
+
`sys_webhook_delivery` as a live sibling.
|
|
1219
|
+
|
|
1220
|
+
(The dangling `SysWebhookDelivery` import in `scripts/i18n-extract.config.ts`
|
|
1221
|
+
was fixed independently on `main` by #3489, so it is not part of this change.)
|
|
1222
|
+
|
|
1223
|
+
- Updated dependencies [50616d9]
|
|
1224
|
+
- Updated dependencies [430dcc2]
|
|
1225
|
+
- Updated dependencies [690ccf2]
|
|
1226
|
+
- Updated dependencies [6a67d7a]
|
|
1227
|
+
- Updated dependencies [333a374]
|
|
1228
|
+
- Updated dependencies [9fe9c1d]
|
|
1229
|
+
- Updated dependencies [3d5c090]
|
|
1230
|
+
- Updated dependencies [e5bd768]
|
|
1231
|
+
- Updated dependencies [08b5a3d]
|
|
1232
|
+
- Updated dependencies [e027b3e]
|
|
1233
|
+
- Updated dependencies [e6ac4bd]
|
|
1234
|
+
- Updated dependencies [c2429b0]
|
|
1235
|
+
- Updated dependencies [445a0c2]
|
|
1236
|
+
- Updated dependencies [d99aeb3]
|
|
1237
|
+
- Updated dependencies [f6609e6]
|
|
1238
|
+
- Updated dependencies [4727eb8]
|
|
1239
|
+
- Updated dependencies [a70358a]
|
|
1240
|
+
- Updated dependencies [0ecc656]
|
|
1241
|
+
- Updated dependencies [06772eb]
|
|
1242
|
+
- Updated dependencies [d4e0809]
|
|
1243
|
+
- Updated dependencies [80334c7]
|
|
1244
|
+
- Updated dependencies [f63cd09]
|
|
1245
|
+
- Updated dependencies [97e7e3c]
|
|
1246
|
+
- Updated dependencies [ce5242c]
|
|
1247
|
+
- Updated dependencies [a7163ea]
|
|
1248
|
+
- Updated dependencies [e6e9379]
|
|
1249
|
+
- Updated dependencies [5823d59]
|
|
1250
|
+
- Updated dependencies [3140f9c]
|
|
1251
|
+
- Updated dependencies [9500ba4]
|
|
1252
|
+
- Updated dependencies [fa3d0cf]
|
|
1253
|
+
- Updated dependencies [af5a224]
|
|
1254
|
+
- Updated dependencies [71f76e1]
|
|
1255
|
+
- Updated dependencies [37b1346]
|
|
1256
|
+
- Updated dependencies [99736a0]
|
|
1257
|
+
- Updated dependencies [fe67e34]
|
|
1258
|
+
- Updated dependencies [fdb4f50]
|
|
1259
|
+
- Updated dependencies [270650f]
|
|
1260
|
+
- Updated dependencies [3aef718]
|
|
1261
|
+
- Updated dependencies [1bd5652]
|
|
1262
|
+
- Updated dependencies [14252d3]
|
|
1263
|
+
- Updated dependencies [7fb436c]
|
|
1264
|
+
- Updated dependencies [879ea13]
|
|
1265
|
+
- Updated dependencies [8828b9e]
|
|
1266
|
+
- Updated dependencies [1ea6bce]
|
|
1267
|
+
- Updated dependencies [c1dcacd]
|
|
1268
|
+
- Updated dependencies [ad303ed]
|
|
1269
|
+
- Updated dependencies [32ccb23]
|
|
1270
|
+
- Updated dependencies [f5a4ef0]
|
|
1271
|
+
- Updated dependencies [2d3e255]
|
|
1272
|
+
- Updated dependencies [a8940e4]
|
|
1273
|
+
- Updated dependencies [7d7521f]
|
|
1274
|
+
- Updated dependencies [5dc4d02]
|
|
1275
|
+
- Updated dependencies [f724f69]
|
|
1276
|
+
- Updated dependencies [98877c9]
|
|
1277
|
+
- Updated dependencies [98877c9]
|
|
1278
|
+
- Updated dependencies [53068c1]
|
|
1279
|
+
- Updated dependencies [ee58392]
|
|
1280
|
+
- Updated dependencies [f16e54e]
|
|
1281
|
+
- Updated dependencies [06be54e]
|
|
1282
|
+
- Updated dependencies [28ad90e]
|
|
1283
|
+
- Updated dependencies [76d74ec]
|
|
1284
|
+
- Updated dependencies [201b31f]
|
|
1285
|
+
- Updated dependencies [e6b1b69]
|
|
1286
|
+
- Updated dependencies [259459d]
|
|
1287
|
+
- Updated dependencies [3f7f14e]
|
|
1288
|
+
- Updated dependencies [e2616e0]
|
|
1289
|
+
- Updated dependencies [6fdc5c6]
|
|
1290
|
+
- Updated dependencies [8b9d71e]
|
|
1291
|
+
- Updated dependencies [05154a1]
|
|
1292
|
+
- Updated dependencies [33f5e23]
|
|
1293
|
+
- Updated dependencies [259af21]
|
|
1294
|
+
- Updated dependencies [f8644c7]
|
|
1295
|
+
- Updated dependencies [306ca50]
|
|
1296
|
+
- Updated dependencies [978fed2]
|
|
1297
|
+
- Updated dependencies [cfc293f]
|
|
1298
|
+
- Updated dependencies [587fc91]
|
|
1299
|
+
- Updated dependencies [de70b42]
|
|
1300
|
+
- Updated dependencies [9b6fe7c]
|
|
1301
|
+
- Updated dependencies [fb3d99b]
|
|
1302
|
+
- Updated dependencies [1986594]
|
|
1303
|
+
- Updated dependencies [6968885]
|
|
1304
|
+
- Updated dependencies [eaed61f]
|
|
1305
|
+
- Updated dependencies [cdfbee2]
|
|
1306
|
+
- Updated dependencies [ad4af62]
|
|
1307
|
+
- Updated dependencies [debe2f6]
|
|
1308
|
+
- Updated dependencies [d44dbfa]
|
|
1309
|
+
- Updated dependencies [29c6c9d]
|
|
1310
|
+
- Updated dependencies [d21c001]
|
|
1311
|
+
- Updated dependencies [ad047d2]
|
|
1312
|
+
- Updated dependencies [8c711fb]
|
|
1313
|
+
- Updated dependencies [f1cc3a3]
|
|
1314
|
+
- Updated dependencies [09e4547]
|
|
1315
|
+
- Updated dependencies [97b0798]
|
|
1316
|
+
- Updated dependencies [474fe39]
|
|
1317
|
+
- Updated dependencies [0bc685a]
|
|
1318
|
+
- Updated dependencies [b949059]
|
|
1319
|
+
- Updated dependencies [2826d1e]
|
|
1320
|
+
- Updated dependencies [be1c52c]
|
|
1321
|
+
- Updated dependencies [c5ff96d]
|
|
1322
|
+
- Updated dependencies [5a84d41]
|
|
1323
|
+
- Updated dependencies [84e7be9]
|
|
1324
|
+
- Updated dependencies [91f4c78]
|
|
1325
|
+
- Updated dependencies [ddc2527]
|
|
1326
|
+
- Updated dependencies [820eff9]
|
|
1327
|
+
- Updated dependencies [a6c3f38]
|
|
1328
|
+
- Updated dependencies [debc23a]
|
|
1329
|
+
- Updated dependencies [0f8ad09]
|
|
1330
|
+
- Updated dependencies [553a47f]
|
|
1331
|
+
- Updated dependencies [43a7a8d]
|
|
1332
|
+
- Updated dependencies [a98085f]
|
|
1333
|
+
- Updated dependencies [20b1a9e]
|
|
1334
|
+
- Updated dependencies [344a22a]
|
|
1335
|
+
- Updated dependencies [4827e91]
|
|
1336
|
+
- Updated dependencies [8d895ff]
|
|
1337
|
+
- Updated dependencies [86f7a20]
|
|
1338
|
+
- Updated dependencies [a3a884d]
|
|
1339
|
+
- Updated dependencies [cfed092]
|
|
1340
|
+
- Updated dependencies [203a449]
|
|
1341
|
+
- Updated dependencies [8f9689f]
|
|
1342
|
+
- Updated dependencies [73f69dc]
|
|
1343
|
+
- Updated dependencies [04c56aa]
|
|
1344
|
+
- Updated dependencies [f6472d7]
|
|
1345
|
+
- Updated dependencies [57a3bb3]
|
|
1346
|
+
- Updated dependencies [b3efeb7]
|
|
1347
|
+
- Updated dependencies [ddd075a]
|
|
1348
|
+
- Updated dependencies [88154be]
|
|
1349
|
+
- Updated dependencies [e8dc61e]
|
|
1350
|
+
- Updated dependencies [9c82146]
|
|
1351
|
+
- Updated dependencies [5f9a987]
|
|
1352
|
+
- Updated dependencies [744b8f5]
|
|
1353
|
+
- Updated dependencies [ac37fc6]
|
|
1354
|
+
- Updated dependencies [2f3e793]
|
|
1355
|
+
- Updated dependencies [4820f55]
|
|
1356
|
+
- Updated dependencies [462d9c4]
|
|
1357
|
+
- Updated dependencies [78caf51]
|
|
1358
|
+
- Updated dependencies [7d21581]
|
|
1359
|
+
- Updated dependencies [37785ed]
|
|
1360
|
+
- Updated dependencies [62a789b]
|
|
1361
|
+
- Updated dependencies [2e284b2]
|
|
1362
|
+
- Updated dependencies [d8e8d9c]
|
|
1363
|
+
- Updated dependencies [789ad63]
|
|
1364
|
+
- Updated dependencies [f2445c9]
|
|
1365
|
+
- Updated dependencies [94e749b]
|
|
1366
|
+
- Updated dependencies [ea1d916]
|
|
1367
|
+
- Updated dependencies [2af1988]
|
|
1368
|
+
- Updated dependencies [0af50a3]
|
|
1369
|
+
- Updated dependencies [1b49eaf]
|
|
1370
|
+
- Updated dependencies [ae31a19]
|
|
1371
|
+
- Updated dependencies [2e836de]
|
|
1372
|
+
- Updated dependencies [e0f300b]
|
|
1373
|
+
- Updated dependencies [0161c7f]
|
|
1374
|
+
- Updated dependencies [e900015]
|
|
1375
|
+
- Updated dependencies [db02d47]
|
|
1376
|
+
- Updated dependencies [b5bdf48]
|
|
1377
|
+
- Updated dependencies [23338c3]
|
|
1378
|
+
- Updated dependencies [12a19a8]
|
|
1379
|
+
- Updated dependencies [5b843fb]
|
|
1380
|
+
- Updated dependencies [62b6a2f]
|
|
1381
|
+
- Updated dependencies [7e5af5c]
|
|
1382
|
+
- Updated dependencies [5b4780b]
|
|
1383
|
+
- Updated dependencies [a933452]
|
|
1384
|
+
- Updated dependencies [9d1d9c7]
|
|
1385
|
+
- Updated dependencies [8140915]
|
|
1386
|
+
- Updated dependencies [a019e52]
|
|
1387
|
+
- Updated dependencies [e8f8f6c]
|
|
1388
|
+
- Updated dependencies [41dcda3]
|
|
1389
|
+
- Updated dependencies [7b48cf9]
|
|
1390
|
+
- Updated dependencies [b5404f4]
|
|
1391
|
+
- Updated dependencies [64fc6d5]
|
|
1392
|
+
- Updated dependencies [b746aa0]
|
|
1393
|
+
- Updated dependencies [b4487aa]
|
|
1394
|
+
- Updated dependencies [1007379]
|
|
1395
|
+
- Updated dependencies [65ca83a]
|
|
1396
|
+
- Updated dependencies [0bfdf46]
|
|
1397
|
+
- Updated dependencies [947d4f9]
|
|
1398
|
+
- Updated dependencies [f764691]
|
|
1399
|
+
- Updated dependencies [e120a5a]
|
|
1400
|
+
- Updated dependencies [e5bd2f6]
|
|
1401
|
+
- Updated dependencies [e650d67]
|
|
1402
|
+
- Updated dependencies [04476e7]
|
|
1403
|
+
- Updated dependencies [67bf2e2]
|
|
1404
|
+
- Updated dependencies [eaaf03c]
|
|
1405
|
+
- Updated dependencies [d17df80]
|
|
1406
|
+
- Updated dependencies [7d0e7b5]
|
|
1407
|
+
- Updated dependencies [c6d1cb4]
|
|
1408
|
+
- Updated dependencies [6513c17]
|
|
1409
|
+
- Updated dependencies [36030ff]
|
|
1410
|
+
- Updated dependencies [79228cd]
|
|
1411
|
+
- Updated dependencies [6117f7b]
|
|
1412
|
+
- Updated dependencies [e533b0b]
|
|
1413
|
+
- Updated dependencies [cdf4d9a]
|
|
1414
|
+
- Updated dependencies [aee1806]
|
|
1415
|
+
- Updated dependencies [c13350b]
|
|
1416
|
+
- Updated dependencies [c13350b]
|
|
1417
|
+
- Updated dependencies [2c1988c]
|
|
1418
|
+
- Updated dependencies [9ca2d85]
|
|
1419
|
+
- Updated dependencies [c13350b]
|
|
1420
|
+
- Updated dependencies [891d345]
|
|
1421
|
+
- Updated dependencies [c8124e5]
|
|
1422
|
+
- Updated dependencies [a52e2ef]
|
|
1423
|
+
- Updated dependencies [5293114]
|
|
1424
|
+
- Updated dependencies [376a061]
|
|
1425
|
+
- Updated dependencies [c142ced]
|
|
1426
|
+
- Updated dependencies [211abdb]
|
|
1427
|
+
- Updated dependencies [b3363e9]
|
|
1428
|
+
- Updated dependencies [eda599e]
|
|
1429
|
+
- Updated dependencies [a1a4140]
|
|
1430
|
+
- Updated dependencies [7c7e246]
|
|
1431
|
+
- Updated dependencies [2ef1807]
|
|
1432
|
+
- Updated dependencies [c519533]
|
|
1433
|
+
- Updated dependencies [f9a5c59]
|
|
1434
|
+
- Updated dependencies [f35cdc5]
|
|
1435
|
+
- Updated dependencies [d03fe25]
|
|
1436
|
+
- Updated dependencies [217e2e6]
|
|
1437
|
+
- Updated dependencies [2672f85]
|
|
1438
|
+
- Updated dependencies [20bc357]
|
|
1439
|
+
- Updated dependencies [11066f6]
|
|
1440
|
+
- Updated dependencies [916af17]
|
|
1441
|
+
- Updated dependencies [84c86fb]
|
|
1442
|
+
- Updated dependencies [2a2a9fb]
|
|
1443
|
+
- Updated dependencies [86a71d1]
|
|
1444
|
+
- Updated dependencies [c001422]
|
|
1445
|
+
- Updated dependencies [77022a9]
|
|
1446
|
+
- Updated dependencies [d5c75e2]
|
|
1447
|
+
- Updated dependencies [03d26f7]
|
|
1448
|
+
- Updated dependencies [5966c2a]
|
|
1449
|
+
- Updated dependencies [2382580]
|
|
1450
|
+
- Updated dependencies [9ea2bc5]
|
|
1451
|
+
- Updated dependencies [a2e157c]
|
|
1452
|
+
- Updated dependencies [95c4227]
|
|
1453
|
+
- Updated dependencies [2a61116]
|
|
1454
|
+
- Updated dependencies [52760bf]
|
|
1455
|
+
- Updated dependencies [5543020]
|
|
1456
|
+
- Updated dependencies [880d343]
|
|
1457
|
+
- Updated dependencies [6e82972]
|
|
1458
|
+
- Updated dependencies [d4df105]
|
|
1459
|
+
- Updated dependencies [4615a18]
|
|
1460
|
+
- Updated dependencies [f505689]
|
|
1461
|
+
- Updated dependencies [d9fa683]
|
|
1462
|
+
- Updated dependencies [606d577]
|
|
1463
|
+
- Updated dependencies [4384921]
|
|
1464
|
+
- Updated dependencies [e2798fa]
|
|
1465
|
+
- Updated dependencies [3c628ce]
|
|
1466
|
+
- Updated dependencies [c2d9098]
|
|
1467
|
+
- Updated dependencies [0fd8556]
|
|
1468
|
+
- Updated dependencies [3c7bcc0]
|
|
1469
|
+
- Updated dependencies [4b6cac7]
|
|
1470
|
+
- Updated dependencies [7631964]
|
|
1471
|
+
- Updated dependencies [ac471a0]
|
|
1472
|
+
- Updated dependencies [60ae58e]
|
|
1473
|
+
- Updated dependencies [7f62706]
|
|
1474
|
+
- Updated dependencies [667fa44]
|
|
1475
|
+
- Updated dependencies [37e38d1]
|
|
1476
|
+
- Updated dependencies [e906126]
|
|
1477
|
+
- Updated dependencies [ce92674]
|
|
1478
|
+
- Updated dependencies [08363a0]
|
|
1479
|
+
- Updated dependencies [444de5b]
|
|
1480
|
+
- Updated dependencies [a227ed7]
|
|
1481
|
+
- Updated dependencies [7cb922e]
|
|
1482
|
+
- Updated dependencies [1d22114]
|
|
1483
|
+
- Updated dependencies [1eb13a0]
|
|
1484
|
+
- Updated dependencies [c52e608]
|
|
1485
|
+
- Updated dependencies [9613396]
|
|
1486
|
+
- Updated dependencies [3f7b4ff]
|
|
1487
|
+
- Updated dependencies [74155c7]
|
|
1488
|
+
- Updated dependencies [b5f9397]
|
|
1489
|
+
- Updated dependencies [ed77493]
|
|
1490
|
+
- Updated dependencies [6908830]
|
|
1491
|
+
- Updated dependencies [8b06bba]
|
|
1492
|
+
- Updated dependencies [58a03d2]
|
|
1493
|
+
- Updated dependencies [2bacd1a]
|
|
1494
|
+
- Updated dependencies [e47b342]
|
|
1495
|
+
- Updated dependencies [4c54037]
|
|
1496
|
+
- Updated dependencies [dc530b4]
|
|
1497
|
+
- Updated dependencies [9f601e8]
|
|
1498
|
+
- Updated dependencies [6a9dec6]
|
|
1499
|
+
- Updated dependencies [0f7157b]
|
|
1500
|
+
- Updated dependencies [4dc1c7d]
|
|
1501
|
+
- Updated dependencies [d9bef45]
|
|
1502
|
+
- Updated dependencies [4dfd002]
|
|
1503
|
+
- Updated dependencies [f549a0d]
|
|
1504
|
+
- Updated dependencies [51c5227]
|
|
1505
|
+
- Updated dependencies [82da264]
|
|
1506
|
+
- Updated dependencies [f586f1a]
|
|
1507
|
+
- Updated dependencies [77be690]
|
|
1508
|
+
- Updated dependencies [4ed7ed4]
|
|
1509
|
+
- Updated dependencies [9b9b70f]
|
|
1510
|
+
- Updated dependencies [f5a9bc2]
|
|
1511
|
+
- Updated dependencies [e59786e]
|
|
1512
|
+
- Updated dependencies [2fa4ca1]
|
|
1513
|
+
- Updated dependencies [bcf1112]
|
|
1514
|
+
- Updated dependencies [baeb4f0]
|
|
1515
|
+
- Updated dependencies [29488cc]
|
|
1516
|
+
- Updated dependencies [881a3cc]
|
|
1517
|
+
- Updated dependencies [f5a2320]
|
|
1518
|
+
- Updated dependencies [ad6317b]
|
|
1519
|
+
- Updated dependencies [811c30c]
|
|
1520
|
+
- Updated dependencies [a4a85c8]
|
|
1521
|
+
- Updated dependencies [859cb83]
|
|
1522
|
+
- Updated dependencies [07a4e26]
|
|
1523
|
+
- Updated dependencies [9774b78]
|
|
1524
|
+
- Updated dependencies [8a88885]
|
|
1525
|
+
- Updated dependencies [deb538f]
|
|
1526
|
+
- Updated dependencies [b49ccfd]
|
|
1527
|
+
- Updated dependencies [5b89711]
|
|
1528
|
+
- Updated dependencies [85d95e7]
|
|
1529
|
+
- Updated dependencies [08cd163]
|
|
1530
|
+
- Updated dependencies [0c8a22f]
|
|
1531
|
+
- Updated dependencies [5f7669e]
|
|
1532
|
+
- Updated dependencies [becbe53]
|
|
1533
|
+
- Updated dependencies [b127c8b]
|
|
1534
|
+
- Updated dependencies [763931e]
|
|
1535
|
+
- Updated dependencies [ec975f1]
|
|
1536
|
+
- Updated dependencies [168f60f]
|
|
1537
|
+
- Updated dependencies [b07d829]
|
|
1538
|
+
- Updated dependencies [de9af8a]
|
|
1539
|
+
- Updated dependencies [eb4204b]
|
|
1540
|
+
- Updated dependencies [a80302a]
|
|
1541
|
+
- Updated dependencies [a648e96]
|
|
1542
|
+
- Updated dependencies [a47ac06]
|
|
1543
|
+
- Updated dependencies [e4c61a7]
|
|
1544
|
+
- Updated dependencies [cc60165]
|
|
1545
|
+
- Updated dependencies [474f131]
|
|
1546
|
+
- Updated dependencies [081aa6f]
|
|
1547
|
+
- Updated dependencies [91f4c78]
|
|
1548
|
+
- Updated dependencies [050cd82]
|
|
1549
|
+
- Updated dependencies [4d552af]
|
|
1550
|
+
- Updated dependencies [44d677c]
|
|
1551
|
+
- Updated dependencies [c32944d]
|
|
1552
|
+
- Updated dependencies [1dd780f]
|
|
1553
|
+
- Updated dependencies [e8d0c21]
|
|
1554
|
+
- Updated dependencies [244ca86]
|
|
1555
|
+
- Updated dependencies [546ab3c]
|
|
1556
|
+
- Updated dependencies [c4df271]
|
|
1557
|
+
- Updated dependencies [c8d6f6e]
|
|
1558
|
+
- Updated dependencies [0b51bb6]
|
|
1559
|
+
- Updated dependencies [d9971d3]
|
|
1560
|
+
- Updated dependencies [7dc1067]
|
|
1561
|
+
- Updated dependencies [4f13be2]
|
|
1562
|
+
- Updated dependencies [a41ba5c]
|
|
1563
|
+
- Updated dependencies [189854c]
|
|
1564
|
+
- Updated dependencies [0e3a226]
|
|
1565
|
+
- Updated dependencies [92a67f2]
|
|
1566
|
+
- Updated dependencies [9136327]
|
|
1567
|
+
- Updated dependencies [bf0ae99]
|
|
1568
|
+
- Updated dependencies [eb3e650]
|
|
1569
|
+
- Updated dependencies [abeb375]
|
|
1570
|
+
- Updated dependencies [cb3b6cd]
|
|
1571
|
+
- Updated dependencies [73b7234]
|
|
1572
|
+
- Updated dependencies [d2b97c3]
|
|
1573
|
+
- Updated dependencies [61cc079]
|
|
1574
|
+
- Updated dependencies [45dc446]
|
|
1575
|
+
- Updated dependencies [0e96e46]
|
|
1576
|
+
- Updated dependencies [c1d44f7]
|
|
1577
|
+
- Updated dependencies [59b794f]
|
|
1578
|
+
- Updated dependencies [ef4efa8]
|
|
1579
|
+
- Updated dependencies [cbb6a5c]
|
|
1580
|
+
- Updated dependencies [fc3a36a]
|
|
1581
|
+
- Updated dependencies [ab9fb5c]
|
|
1582
|
+
- Updated dependencies [69787f0]
|
|
1583
|
+
- Updated dependencies [5d022a1]
|
|
1584
|
+
- Updated dependencies [042b9ee]
|
|
1585
|
+
- Updated dependencies [f985b3f]
|
|
1586
|
+
- Updated dependencies [795b6e1]
|
|
1587
|
+
- Updated dependencies [d52d4fe]
|
|
1588
|
+
- Updated dependencies [742cebb]
|
|
1589
|
+
- Updated dependencies [175d789]
|
|
1590
|
+
- Updated dependencies [f549a0d]
|
|
1591
|
+
- Updated dependencies [427344c]
|
|
1592
|
+
- Updated dependencies [8af76ae]
|
|
1593
|
+
- Updated dependencies [1d4756e]
|
|
1594
|
+
- Updated dependencies [720c5ad]
|
|
1595
|
+
- Updated dependencies [a8d1e24]
|
|
1596
|
+
- Updated dependencies [b85cc54]
|
|
1597
|
+
- Updated dependencies [a36db28]
|
|
1598
|
+
- Updated dependencies [7a8476f]
|
|
1599
|
+
- Updated dependencies [518ca7a]
|
|
1600
|
+
- Updated dependencies [41642b0]
|
|
1601
|
+
- Updated dependencies [4cca74c]
|
|
1602
|
+
- Updated dependencies [88ef03e]
|
|
1603
|
+
- Updated dependencies [9a4932a]
|
|
1604
|
+
- Updated dependencies [3f8817a]
|
|
1605
|
+
- Updated dependencies [a2443e3]
|
|
1606
|
+
- Updated dependencies [e1554b1]
|
|
1607
|
+
- Updated dependencies [9e2caf3]
|
|
1608
|
+
- Updated dependencies [4856789]
|
|
1609
|
+
- Updated dependencies [81ce41a]
|
|
1610
|
+
- Updated dependencies [85e1e4e]
|
|
1611
|
+
- Updated dependencies [c3f4916]
|
|
1612
|
+
- Updated dependencies [55dbbba]
|
|
1613
|
+
- Updated dependencies [33e0385]
|
|
1614
|
+
- Updated dependencies [dac6a08]
|
|
1615
|
+
- Updated dependencies [72c3c86]
|
|
1616
|
+
- Updated dependencies [2d8dba3]
|
|
1617
|
+
- Updated dependencies [7f1a635]
|
|
1618
|
+
- Updated dependencies [2205363]
|
|
1619
|
+
- Updated dependencies [09fe58d]
|
|
1620
|
+
- Updated dependencies [f9fc874]
|
|
1621
|
+
- Updated dependencies [d62f8eb]
|
|
1622
|
+
- Updated dependencies [d0a5ceb]
|
|
1623
|
+
- Updated dependencies [a7586cd]
|
|
1624
|
+
- Updated dependencies [4c5e80e]
|
|
1625
|
+
- Updated dependencies [4b5702a]
|
|
1626
|
+
- Updated dependencies [011b386]
|
|
1627
|
+
- Updated dependencies [e18a162]
|
|
1628
|
+
- Updated dependencies [394b7a1]
|
|
1629
|
+
- Updated dependencies [ce92674]
|
|
1630
|
+
- Updated dependencies [0f2fdcd]
|
|
1631
|
+
- Updated dependencies [d6d1a50]
|
|
1632
|
+
- Updated dependencies [cf2c9b7]
|
|
1633
|
+
- Updated dependencies [8ffa8b9]
|
|
1634
|
+
- Updated dependencies [d127ff0]
|
|
1635
|
+
- Updated dependencies [674ac99]
|
|
1636
|
+
- Updated dependencies [833b512]
|
|
1637
|
+
- Updated dependencies [36d90fc]
|
|
1638
|
+
- Updated dependencies [7777e8f]
|
|
1639
|
+
- Updated dependencies [9b86cf6]
|
|
1640
|
+
- Updated dependencies [d063a96]
|
|
1641
|
+
- Updated dependencies [8825a06]
|
|
1642
|
+
- Updated dependencies [5087ac6]
|
|
1643
|
+
- Updated dependencies [677b591]
|
|
1644
|
+
- Updated dependencies [cf7c694]
|
|
1645
|
+
- Updated dependencies [ddd0f06]
|
|
1646
|
+
- Updated dependencies [d77d1b7]
|
|
1647
|
+
- Updated dependencies [0f9faa2]
|
|
1648
|
+
- Updated dependencies [2d1ddf0]
|
|
1649
|
+
- Updated dependencies [354b00f]
|
|
1650
|
+
- Updated dependencies [3de535b]
|
|
1651
|
+
- Updated dependencies [fe2e15a]
|
|
1652
|
+
- Updated dependencies [5b79a34]
|
|
1653
|
+
- Updated dependencies [502564d]
|
|
1654
|
+
- Updated dependencies [603cab8]
|
|
1655
|
+
- Updated dependencies [c757854]
|
|
1656
|
+
- Updated dependencies [471839d]
|
|
1657
|
+
- Updated dependencies [507b92a]
|
|
1658
|
+
- Updated dependencies [46365ab]
|
|
1659
|
+
- Updated dependencies [b508244]
|
|
1660
|
+
- Updated dependencies [df95346]
|
|
1661
|
+
- Updated dependencies [3dede58]
|
|
1662
|
+
- Updated dependencies [c6b6bb4]
|
|
1663
|
+
- Updated dependencies [594508e]
|
|
1664
|
+
- Updated dependencies [7cf42fe]
|
|
1665
|
+
- Updated dependencies [5966c2a]
|
|
1666
|
+
- Updated dependencies [0045682]
|
|
1667
|
+
- Updated dependencies [7309c81]
|
|
1668
|
+
- Updated dependencies [a8dcc37]
|
|
1669
|
+
- Updated dependencies [040ecd2]
|
|
1670
|
+
- Updated dependencies [932d7e2]
|
|
1671
|
+
- Updated dependencies [2f59da0]
|
|
1672
|
+
- Updated dependencies [d56012f]
|
|
1673
|
+
- Updated dependencies [f78dd83]
|
|
1674
|
+
- Updated dependencies [a2cd18a]
|
|
1675
|
+
- Updated dependencies [9051802]
|
|
1676
|
+
- Updated dependencies [20bc1ec]
|
|
1677
|
+
- Updated dependencies [1c625ca]
|
|
1678
|
+
- Updated dependencies [2f8328c]
|
|
1679
|
+
- Updated dependencies [2a6c279]
|
|
1680
|
+
- Updated dependencies [9319586]
|
|
1681
|
+
- Updated dependencies [8c8f0df]
|
|
1682
|
+
- Updated dependencies [8ad609c]
|
|
1683
|
+
- Updated dependencies [bbee302]
|
|
1684
|
+
- Updated dependencies [90c2b15]
|
|
1685
|
+
- Updated dependencies [4638aaa]
|
|
1686
|
+
- Updated dependencies [0222d3c]
|
|
1687
|
+
- Updated dependencies [08863dd]
|
|
1688
|
+
- Updated dependencies [071d0dc]
|
|
1689
|
+
- Updated dependencies [f293d45]
|
|
1690
|
+
- Updated dependencies [56664f5]
|
|
1691
|
+
- Updated dependencies [71f205d]
|
|
1692
|
+
- Updated dependencies [f067930]
|
|
1693
|
+
- Updated dependencies [414395b]
|
|
1694
|
+
- Updated dependencies [42eeb7d]
|
|
1695
|
+
- Updated dependencies [31cbe90]
|
|
1696
|
+
- Updated dependencies [6b7129a]
|
|
1697
|
+
- Updated dependencies [c5adfe1]
|
|
1698
|
+
- Updated dependencies [97ace2a]
|
|
1699
|
+
- Updated dependencies [26e1029]
|
|
1700
|
+
- Updated dependencies [0a936ea]
|
|
1701
|
+
- Updated dependencies [90bbf25]
|
|
1702
|
+
- Updated dependencies [f1850d8]
|
|
1703
|
+
- Updated dependencies [023c00b]
|
|
1704
|
+
- Updated dependencies [eb91eba]
|
|
1705
|
+
- Updated dependencies [17d0954]
|
|
1706
|
+
- Updated dependencies [f28ef3b]
|
|
1707
|
+
- Updated dependencies [42da73d]
|
|
1708
|
+
- Updated dependencies [01e124d]
|
|
1709
|
+
- Updated dependencies [ef7b5ef]
|
|
1710
|
+
- Updated dependencies [9514767]
|
|
1711
|
+
- Updated dependencies [8f20201]
|
|
1712
|
+
- Updated dependencies [155507e]
|
|
1713
|
+
- Updated dependencies [643b7c7]
|
|
1714
|
+
- Updated dependencies [7bba90b]
|
|
1715
|
+
- Updated dependencies [8813b90]
|
|
1716
|
+
- Updated dependencies [108ba8d]
|
|
1717
|
+
- Updated dependencies [2a5f04a]
|
|
1718
|
+
- Updated dependencies [4f740b0]
|
|
1719
|
+
- Updated dependencies [7ce02eb]
|
|
1720
|
+
- Updated dependencies [b4ad984]
|
|
1721
|
+
- Updated dependencies [a9f32df]
|
|
1722
|
+
- Updated dependencies [aeb9b27]
|
|
1723
|
+
- Updated dependencies [7d27da0]
|
|
1724
|
+
- Updated dependencies [d0d5205]
|
|
1725
|
+
- Updated dependencies [1a15893]
|
|
1726
|
+
- Updated dependencies [b70e534]
|
|
1727
|
+
- Updated dependencies [7e05d8e]
|
|
1728
|
+
- Updated dependencies [8f1851e]
|
|
1729
|
+
- Updated dependencies [61ea810]
|
|
1730
|
+
- Updated dependencies [2233a85]
|
|
1731
|
+
- Updated dependencies [67452d1]
|
|
1732
|
+
- Updated dependencies [089767f]
|
|
1733
|
+
- Updated dependencies [a13827e]
|
|
1734
|
+
- Updated dependencies [66d99ec]
|
|
1735
|
+
- Updated dependencies [cb43296]
|
|
1736
|
+
- Updated dependencies [b61afc1]
|
|
1737
|
+
- Updated dependencies [79021fc]
|
|
1738
|
+
- Updated dependencies [7733604]
|
|
1739
|
+
- Updated dependencies [40e420f]
|
|
1740
|
+
- Updated dependencies [62dd69a]
|
|
1741
|
+
- Updated dependencies [d13004a]
|
|
1742
|
+
- Updated dependencies [be7360c]
|
|
1743
|
+
- Updated dependencies [e15e679]
|
|
1744
|
+
- Updated dependencies [2ab1257]
|
|
1745
|
+
- Updated dependencies [0fc6219]
|
|
1746
|
+
- Updated dependencies [061406d]
|
|
1747
|
+
- Updated dependencies [e4c8b6c]
|
|
1748
|
+
- Updated dependencies [acb10f6]
|
|
1749
|
+
- Updated dependencies [605e190]
|
|
1750
|
+
- Updated dependencies [c6c59f1]
|
|
1751
|
+
- Updated dependencies [b0e78a8]
|
|
1752
|
+
- Updated dependencies [f31cc8d]
|
|
1753
|
+
- Updated dependencies [f343dc4]
|
|
1754
|
+
- Updated dependencies [8269e32]
|
|
1755
|
+
- Updated dependencies [74f7339]
|
|
1756
|
+
- Updated dependencies [a6c35a2]
|
|
1757
|
+
- Updated dependencies [c2f1002]
|
|
1758
|
+
- Updated dependencies [4cc4fb7]
|
|
1759
|
+
- Updated dependencies [97b6658]
|
|
1760
|
+
- Updated dependencies [28d1eb7]
|
|
1761
|
+
- Updated dependencies [06770c0]
|
|
1762
|
+
- Updated dependencies [2c26040]
|
|
1763
|
+
- Updated dependencies [f758cec]
|
|
1764
|
+
- Updated dependencies [5b47ab5]
|
|
1765
|
+
- Updated dependencies [b09d8d9]
|
|
1766
|
+
- Updated dependencies [b09d8d9]
|
|
1767
|
+
- Updated dependencies [8675db6]
|
|
1768
|
+
- Updated dependencies [b09d8d9]
|
|
1769
|
+
- Updated dependencies [27358d5]
|
|
1770
|
+
- Updated dependencies [1c3da1f]
|
|
1771
|
+
- Updated dependencies [c1f344b]
|
|
1772
|
+
- Updated dependencies [3eb1b2b]
|
|
1773
|
+
- Updated dependencies [9c93465]
|
|
1774
|
+
- Updated dependencies [a34fd2e]
|
|
1775
|
+
- Updated dependencies [ebb209c]
|
|
1776
|
+
- Updated dependencies [76bcb83]
|
|
1777
|
+
- Updated dependencies [59b85c0]
|
|
1778
|
+
- Updated dependencies [889ae47]
|
|
1779
|
+
- Updated dependencies [4f4c3fb]
|
|
1780
|
+
- Updated dependencies [78f0be8]
|
|
1781
|
+
- Updated dependencies [6e357ed]
|
|
1782
|
+
- Updated dependencies [d6938bf]
|
|
1783
|
+
- Updated dependencies [35f7fb4]
|
|
1784
|
+
- Updated dependencies [0410522]
|
|
1785
|
+
- Updated dependencies [63b33e6]
|
|
1786
|
+
- Updated dependencies [f163028]
|
|
1787
|
+
- Updated dependencies [814db6d]
|
|
1788
|
+
- Updated dependencies [a5302c7]
|
|
1789
|
+
- Updated dependencies [31e0be9]
|
|
1790
|
+
- Updated dependencies [4bfd455]
|
|
1791
|
+
- Updated dependencies [ffd2ce2]
|
|
1792
|
+
- Updated dependencies [2a44c1d]
|
|
1793
|
+
- Updated dependencies [7084313]
|
|
1794
|
+
- Updated dependencies [f07808c]
|
|
1795
|
+
- Updated dependencies [7ffc3d3]
|
|
1796
|
+
- Updated dependencies [88346ba]
|
|
1797
|
+
- Updated dependencies [4631592]
|
|
1798
|
+
- Updated dependencies [62f8017]
|
|
1799
|
+
- Updated dependencies [32ff033]
|
|
1800
|
+
- Updated dependencies [a831df1]
|
|
1801
|
+
- Updated dependencies [f752ee3]
|
|
1802
|
+
- Updated dependencies [a1b61e0]
|
|
1803
|
+
- Updated dependencies [cd6b9f2]
|
|
1804
|
+
- Updated dependencies [2cb6d3c]
|
|
1805
|
+
- Updated dependencies [af2a095]
|
|
1806
|
+
- Updated dependencies [5ac93d4]
|
|
1807
|
+
- Updated dependencies [695cfbd]
|
|
1808
|
+
- Updated dependencies [0e043d8]
|
|
1809
|
+
- Updated dependencies [93f267f]
|
|
1810
|
+
- Updated dependencies [7445149]
|
|
1811
|
+
- Updated dependencies [ec796d5]
|
|
1812
|
+
- Updated dependencies [071d0dc]
|
|
1813
|
+
- Updated dependencies [0024abf]
|
|
1814
|
+
- Updated dependencies [8dd98bf]
|
|
1815
|
+
- Updated dependencies [e87fea1]
|
|
1816
|
+
- Updated dependencies [c65e529]
|
|
1817
|
+
- Updated dependencies [0848bea]
|
|
1818
|
+
- Updated dependencies [d51bed2]
|
|
1819
|
+
- Updated dependencies [dadd1ad]
|
|
1820
|
+
- Updated dependencies [acbf364]
|
|
1821
|
+
- Updated dependencies [3ca34c1]
|
|
1822
|
+
- Updated dependencies [7adc841]
|
|
1823
|
+
- Updated dependencies [239c3a3]
|
|
1824
|
+
- Updated dependencies [b8b3c64]
|
|
1825
|
+
- Updated dependencies [2f2e63c]
|
|
1826
|
+
- Updated dependencies [4845f85]
|
|
1827
|
+
- Updated dependencies [486d526]
|
|
1828
|
+
- Updated dependencies [94a0bbc]
|
|
1829
|
+
- Updated dependencies [d6bfb3d]
|
|
1830
|
+
- Updated dependencies [8a9c079]
|
|
1831
|
+
- Updated dependencies [7b005b4]
|
|
1832
|
+
- Updated dependencies [cc3555e]
|
|
1833
|
+
- Updated dependencies [a2266a6]
|
|
1834
|
+
- Updated dependencies [d25a0ec]
|
|
1835
|
+
- Updated dependencies [89d7b35]
|
|
1836
|
+
- Updated dependencies [94f7b6a]
|
|
1837
|
+
- Updated dependencies [5c94f83]
|
|
1838
|
+
- Updated dependencies [ea936f3]
|
|
1839
|
+
- Updated dependencies [0c0fbd9]
|
|
1840
|
+
- Updated dependencies [667b83e]
|
|
1841
|
+
- Updated dependencies [f3141d8]
|
|
1842
|
+
- Updated dependencies [7687f7b]
|
|
1843
|
+
- Updated dependencies [5a84d41]
|
|
1844
|
+
- Updated dependencies [fd3013a]
|
|
1845
|
+
- Updated dependencies [85ec26d]
|
|
1846
|
+
- Updated dependencies [73e576f]
|
|
1847
|
+
- Updated dependencies [f6476fc]
|
|
1848
|
+
- Updated dependencies [69ac82c]
|
|
1849
|
+
- Updated dependencies [4ac12ef]
|
|
1850
|
+
- Updated dependencies [833ed84]
|
|
1851
|
+
- Updated dependencies [a18abf3]
|
|
1852
|
+
- Updated dependencies [c6a4eeb]
|
|
1853
|
+
- Updated dependencies [1659072]
|
|
1854
|
+
- Updated dependencies [f450ae7]
|
|
1855
|
+
- Updated dependencies [abceb0d]
|
|
1856
|
+
- Updated dependencies [627b188]
|
|
1857
|
+
- Updated dependencies [8d4eae7]
|
|
1858
|
+
- Updated dependencies [c5a5996]
|
|
1859
|
+
- Updated dependencies [0c302a7]
|
|
1860
|
+
- Updated dependencies [b88f5e8]
|
|
1861
|
+
- Updated dependencies [857a6cf]
|
|
1862
|
+
- Updated dependencies [65a3a84]
|
|
1863
|
+
- Updated dependencies [6633337]
|
|
1864
|
+
- Updated dependencies [21676eb]
|
|
1865
|
+
- Updated dependencies [e9cb9ab]
|
|
1866
|
+
- Updated dependencies [42cc219]
|
|
1867
|
+
- Updated dependencies [d7e0b42]
|
|
1868
|
+
- Updated dependencies [3510e4a]
|
|
1869
|
+
- Updated dependencies [f00d8d4]
|
|
1870
|
+
- Updated dependencies [5326b36]
|
|
1871
|
+
- Updated dependencies [aa4b90d]
|
|
1872
|
+
- Updated dependencies [ccd9397]
|
|
1873
|
+
- Updated dependencies [503be86]
|
|
1874
|
+
- Updated dependencies [54299ca]
|
|
1875
|
+
- Updated dependencies [ae490ef]
|
|
1876
|
+
- Updated dependencies [e124711]
|
|
1877
|
+
- Updated dependencies [dc61def]
|
|
1878
|
+
- Updated dependencies [bca935b]
|
|
1879
|
+
- Updated dependencies [d92c72d]
|
|
1880
|
+
- Updated dependencies [c54c822]
|
|
1881
|
+
- Updated dependencies [8dcc0f5]
|
|
1882
|
+
- Updated dependencies [75b9e51]
|
|
1883
|
+
- Updated dependencies [9c90ea0]
|
|
1884
|
+
- Updated dependencies [f61c8cf]
|
|
1885
|
+
- Updated dependencies [e3ef52b]
|
|
1886
|
+
- Updated dependencies [0a2f233]
|
|
1887
|
+
- Updated dependencies [8621cdd]
|
|
1888
|
+
- Updated dependencies [251e888]
|
|
1889
|
+
- Updated dependencies [07f1822]
|
|
1890
|
+
- Updated dependencies [e336549]
|
|
1891
|
+
- Updated dependencies [3bb9340]
|
|
1892
|
+
- Updated dependencies [1e604c4]
|
|
1893
|
+
- Updated dependencies [04fab5e]
|
|
1894
|
+
- Updated dependencies [183b4c4]
|
|
1895
|
+
- Updated dependencies [7f713b6]
|
|
1896
|
+
- Updated dependencies [d40f43a]
|
|
1897
|
+
- Updated dependencies [2fdb36e]
|
|
1898
|
+
- Updated dependencies [6f23667]
|
|
1899
|
+
- Updated dependencies [cde1975]
|
|
1900
|
+
- Updated dependencies [0bc685a]
|
|
1901
|
+
- Updated dependencies [20526f5]
|
|
1902
|
+
- Updated dependencies [efedd28]
|
|
1903
|
+
- Updated dependencies [5d21a48]
|
|
1904
|
+
- Updated dependencies [5278e11]
|
|
1905
|
+
- Updated dependencies [c5eef1d]
|
|
1906
|
+
- Updated dependencies [e5e7ee0]
|
|
1907
|
+
- Updated dependencies [23dba62]
|
|
1908
|
+
- Updated dependencies [e0f300b]
|
|
1909
|
+
- Updated dependencies [761a0ba]
|
|
1910
|
+
- Updated dependencies [c960170]
|
|
1911
|
+
- Updated dependencies [19365b7]
|
|
1912
|
+
- Updated dependencies [ba98e26]
|
|
1913
|
+
- Updated dependencies [b7ed26d]
|
|
1914
|
+
- Updated dependencies [a2ebea2]
|
|
1915
|
+
- Updated dependencies [800bdb0]
|
|
1916
|
+
- Updated dependencies [9d4dfc4]
|
|
1917
|
+
- Updated dependencies [1059965]
|
|
1918
|
+
- Updated dependencies [def5919]
|
|
1919
|
+
- Updated dependencies [ee264b2]
|
|
1920
|
+
- Updated dependencies [60b672e]
|
|
1921
|
+
- Updated dependencies [6b441a8]
|
|
1922
|
+
- Updated dependencies [ce0cfe9]
|
|
1923
|
+
- Updated dependencies [04f1182]
|
|
1924
|
+
- Updated dependencies [be87153]
|
|
1925
|
+
- Updated dependencies [dd0f681]
|
|
1926
|
+
- Updated dependencies [60f0dd8]
|
|
1927
|
+
- Updated dependencies [a87c5cd]
|
|
1928
|
+
- Updated dependencies [a47f338]
|
|
1929
|
+
- Updated dependencies [b3a3d83]
|
|
1930
|
+
- Updated dependencies [7a55913]
|
|
1931
|
+
- Updated dependencies [35accbf]
|
|
1932
|
+
- Updated dependencies [6038de7]
|
|
1933
|
+
- Updated dependencies [fc5f536]
|
|
1934
|
+
- Updated dependencies [5647006]
|
|
1935
|
+
- Updated dependencies [e654bfd]
|
|
1936
|
+
- Updated dependencies [01a7337]
|
|
1937
|
+
- Updated dependencies [7e4783f]
|
|
1938
|
+
- Updated dependencies [b45c71e]
|
|
1939
|
+
- Updated dependencies [f8cfbb4]
|
|
1940
|
+
- Updated dependencies [6e6c872]
|
|
1941
|
+
- Updated dependencies [2598216]
|
|
1942
|
+
- Updated dependencies [11949fc]
|
|
1943
|
+
- Updated dependencies [2c7e62d]
|
|
1944
|
+
- Updated dependencies [eb95d97]
|
|
1945
|
+
- Updated dependencies [b098b0e]
|
|
1946
|
+
- Updated dependencies [4d00b13]
|
|
1947
|
+
- Updated dependencies [1363084]
|
|
1948
|
+
- Updated dependencies [fa5758e]
|
|
1949
|
+
- Updated dependencies [38f7e4f]
|
|
1950
|
+
- Updated dependencies [eb7613c]
|
|
1951
|
+
- Updated dependencies [c57f3cf]
|
|
1952
|
+
- Updated dependencies [ecc9110]
|
|
1953
|
+
- Updated dependencies [e4c2dc8]
|
|
1954
|
+
- Updated dependencies [97faca3]
|
|
1955
|
+
- Updated dependencies [57bab76]
|
|
1956
|
+
- Updated dependencies [c89d18c]
|
|
1957
|
+
- Updated dependencies [1bd2795]
|
|
1958
|
+
- Updated dependencies [f7bd4e2]
|
|
1959
|
+
- Updated dependencies [361bd5b]
|
|
1960
|
+
- Updated dependencies [aac90a5]
|
|
1961
|
+
- Updated dependencies [3da3da5]
|
|
1962
|
+
- Updated dependencies [1e6ab15]
|
|
1963
|
+
- Updated dependencies [b90086a]
|
|
1964
|
+
- Updated dependencies [8186a70]
|
|
1965
|
+
- Updated dependencies [a329cca]
|
|
1966
|
+
- Updated dependencies [c87ef70]
|
|
1967
|
+
- Updated dependencies [3cb0618]
|
|
1968
|
+
- Updated dependencies [32a0874]
|
|
1969
|
+
- Updated dependencies [6eec18c]
|
|
1970
|
+
- Updated dependencies [4d7bebf]
|
|
1971
|
+
- Updated dependencies [821ac7a]
|
|
1972
|
+
- Updated dependencies [8f81731]
|
|
1973
|
+
- Updated dependencies [7055c22]
|
|
1974
|
+
- Updated dependencies [785a748]
|
|
1975
|
+
- Updated dependencies [3af0354]
|
|
1976
|
+
- Updated dependencies [866ff16]
|
|
1977
|
+
- Updated dependencies [5a85e67]
|
|
1978
|
+
- Updated dependencies [8b50cb3]
|
|
1979
|
+
- Updated dependencies [a0fdc56]
|
|
1980
|
+
- Updated dependencies [b95577a]
|
|
1981
|
+
- Updated dependencies [0dcbc11]
|
|
1982
|
+
- Updated dependencies [d88f3e9]
|
|
1983
|
+
- Updated dependencies [ad5fe25]
|
|
1984
|
+
- Updated dependencies [c183a12]
|
|
1985
|
+
- Updated dependencies [83c161f]
|
|
1986
|
+
- Updated dependencies [d8c4957]
|
|
1987
|
+
- Updated dependencies [b9f930b]
|
|
1988
|
+
- Updated dependencies [f24cb83]
|
|
1989
|
+
- Updated dependencies [5dbbb92]
|
|
1990
|
+
- Updated dependencies [ea90179]
|
|
1991
|
+
- Updated dependencies [1818998]
|
|
1992
|
+
- Updated dependencies [ce92674]
|
|
1993
|
+
- Updated dependencies [5ef0b5b]
|
|
1994
|
+
- Updated dependencies [8c2db68]
|
|
1995
|
+
- Updated dependencies [22b5e54]
|
|
1996
|
+
- Updated dependencies [0166bd5]
|
|
1997
|
+
- Updated dependencies [8064b07]
|
|
1998
|
+
- Updated dependencies [09ee21c]
|
|
1999
|
+
- Updated dependencies [4a56dbd]
|
|
2000
|
+
- Updated dependencies [289d04a]
|
|
2001
|
+
- Updated dependencies [f549a0d]
|
|
2002
|
+
- Updated dependencies [48fbacb]
|
|
2003
|
+
- Updated dependencies [06df4fa]
|
|
2004
|
+
- Updated dependencies [3fc2e48]
|
|
2005
|
+
- Updated dependencies [c9b809f]
|
|
2006
|
+
- Updated dependencies [e8f435c]
|
|
2007
|
+
- Updated dependencies [32386f8]
|
|
2008
|
+
- Updated dependencies [9b702dc]
|
|
2009
|
+
- Updated dependencies [ab16331]
|
|
2010
|
+
- Updated dependencies [41610f6]
|
|
2011
|
+
- Updated dependencies [69f1dfd]
|
|
2012
|
+
- Updated dependencies [06306f1]
|
|
2013
|
+
- Updated dependencies [bbe05de]
|
|
2014
|
+
- Updated dependencies [355e951]
|
|
2015
|
+
- Updated dependencies [a1dd1e4]
|
|
2016
|
+
- Updated dependencies [dadb43f]
|
|
2017
|
+
- Updated dependencies [3556b67]
|
|
2018
|
+
- @objectstack/spec@17.0.0
|
|
2019
|
+
- @objectstack/core@17.0.0
|
|
2020
|
+
- @objectstack/service-messaging@17.0.0
|
|
2021
|
+
|
|
3
2022
|
## 17.0.0-rc.6
|
|
4
2023
|
|
|
5
2024
|
### Patch Changes
|