@objectstack/plugin-approvals 17.0.0-rc.0 → 17.0.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/CHANGELOG.md +439 -0
  2. package/dist/index.d.mts +2304 -3491
  3. package/dist/index.d.ts +2304 -3491
  4. package/dist/index.js +116 -43
  5. package/dist/index.js.map +1 -1
  6. package/dist/index.mjs +114 -41
  7. package/dist/index.mjs.map +1 -1
  8. package/package.json +16 -9
  9. package/.turbo/turbo-build.log +0 -22
  10. package/scripts/i18n-extract.config.ts +0 -38
  11. package/src/action-link-pages.ts +0 -102
  12. package/src/approval-actor-impersonation.test.ts +0 -330
  13. package/src/approval-node.test.ts +0 -356
  14. package/src/approval-node.ts +0 -196
  15. package/src/approval-revise.test.ts +0 -418
  16. package/src/approval-service.test.ts +0 -2858
  17. package/src/approval-service.ts +0 -3617
  18. package/src/approvals-plugin.ts +0 -294
  19. package/src/approver-cross-org.integration.test.ts +0 -206
  20. package/src/approver-org-scope.test.ts +0 -201
  21. package/src/approver-org-scope.ts +0 -261
  22. package/src/index.ts +0 -42
  23. package/src/lifecycle-hooks.ts +0 -201
  24. package/src/nav-contribution.test.ts +0 -50
  25. package/src/record-lock-schedule-run.integration.test.ts +0 -206
  26. package/src/status-mirror-cascade.integration.test.ts +0 -224
  27. package/src/sys-approval-action.object.ts +0 -149
  28. package/src/sys-approval-approver.object.ts +0 -85
  29. package/src/sys-approval-delegation.object.test.ts +0 -42
  30. package/src/sys-approval-delegation.object.ts +0 -142
  31. package/src/sys-approval-request.object.test.ts +0 -116
  32. package/src/sys-approval-request.object.ts +0 -413
  33. package/src/sys-approval-token.object.ts +0 -101
  34. package/src/translations/bundle-ownership.test.ts +0 -48
  35. package/src/translations/en.objects.generated.ts +0 -311
  36. package/src/translations/es-ES.objects.generated.ts +0 -311
  37. package/src/translations/index.ts +0 -23
  38. package/src/translations/ja-JP.objects.generated.ts +0 -311
  39. package/src/translations/zh-CN.objects.generated.ts +0 -311
  40. package/tsconfig.json +0 -10
package/CHANGELOG.md CHANGED
@@ -1,5 +1,444 @@
1
1
  # @objectstack/plugin-approvals
2
2
 
3
+ ## 17.0.0-rc.1
4
+
5
+ ### Minor Changes
6
+
7
+ - f5a4ef0: refactor!: ADR-0112 batch 2 — sweep the lowercase error-code emitters (#4003)
8
+
9
+ Continues #3841 per ADR-0112. Batch 1 (#3988) settled the vocabulary and closed
10
+ the set; this batch moves the emitters that still spoke lowercase `snake_case`
11
+ onto it.
12
+
13
+ **Wire-visible change.** Error codes on these surfaces change spelling. Generic
14
+ conditions collapse onto the standard catalog rather than keeping a synonym:
15
+ `unauthorized`/`unauthenticated` → `UNAUTHENTICATED`, `forbidden` →
16
+ `PERMISSION_DENIED`, `not_found` → `RESOURCE_NOT_FOUND`, `internal` →
17
+ `INTERNAL_ERROR`, `unavailable` → `SERVICE_UNAVAILABLE`, `not_supported` →
18
+ `NOT_IMPLEMENTED`, `bad_request` → `INVALID_REQUEST`. Domain conditions get codes
19
+ registered in `ERROR_CODE_LEDGER` (`MARKETPLACE_STORAGE_FAILED`,
20
+ `PLUGIN_MANIFEST_INVALID`, `ITEM_LOCKED`, `DELIVERY_NOT_ELIGIBLE`, …). Swept:
21
+ `cloud-connection`, `plugin-auth`, `hono`, `metadata-protocol`, `rest`,
22
+ `service-messaging`, `service-automation`, `trigger-api`.
23
+
24
+ Branch on `error.code` values rather than pattern-matching their case: the
25
+ console's fix for the same rename (objectui#2977) reads codes case-insensitively
26
+ for exactly this reason, and that is the pattern to copy in your own consumers if
27
+ you support servers on both sides of the change.
28
+
29
+ **Four routes stop putting a code in the message slot.** The webhook redeliver
30
+ route, the API-trigger webhook, and two `rest` routes answered
31
+ `{ success: false, error: '<code>', message }` — the code occupying `error`, the
32
+ declared object envelope nowhere. They now emit `error: { code, message }`, and
33
+ three API-trigger branches gained a message they never had. Clients reading
34
+ `body.error` as a string on those routes must read `body.error.code`.
35
+
36
+ **`ConnectorErrorCategory` / `ConnectorRetryStrategy`** (ADR-0112 D9a):
37
+ `@objectstack/spec` exported two mutually incompatible `ErrorCategory` types and
38
+ two `RetryStrategy` types. The connector-side pair is renamed; importers of the
39
+ `integration` subpath update the name. Side effect: the api-side `ErrorCategory`
40
+ and `RetryStrategy` now appear in the generated API reference at all — the name
41
+ collision had been silently dropping them.
42
+
43
+ **`OAUTH_REGISTER_FAILED` replaces an unbounded code source.** The OAuth client
44
+ registration route put better-auth's arbitrary `body.error` string straight into
45
+ `error.code`. The code is now ours and the upstream discriminator moved to
46
+ `details.upstreamError`.
47
+
48
+ **Not swept, deliberately.** `sys_metadata_audit.code` keeps its lowercase values
49
+ (ADR-0112 D6b): it is persisted audit history, and the same column holds
50
+ non-error outcomes (`ok`, `lock_override`). Diagnostics records that ship inside a
51
+ 200 keep theirs (D6c), as do field-level codes (D6, #3977) and the CLI's
52
+ `--json` output contract.
53
+
54
+ A `check:error-code-casing` CI guard now fails on a new lowercase literal in a
55
+ code position, since the ledger's casing rule can only police codes that someone
56
+ registers.
57
+
58
+ - 91f4c78: feat(approvals,spec): structured reassign hand-off parties on `sys_approval_action` (#4365)
59
+
60
+ A reassign's audit row used to encode "who handed the slot to whom" only inside
61
+ a default free-text comment — `"<from_id> → <to_id>"`, two raw user ids — which
62
+ clients could neither parse reliably nor render readably, so the approvals
63
+ timeline showed opaque identifier soup for the single most important fact of
64
+ the entry.
65
+
66
+ - `sys_approval_action` gains `reassign_from` / `reassign_to`
67
+ (`lookup('sys_user')`), written by `ApprovalService.reassign()`.
68
+ - `comment` is pure user input again: nothing is invented when the actor
69
+ supplies none.
70
+ - `listActions()` resolves both parties' display names into
71
+ `reassign_from_name` / `reassign_to_name`, alongside the existing
72
+ `actor_name`, so timelines can render "from A to B" without extra lookups.
73
+ - `ApprovalActionRow` (spec contract) declares the four new fields.
74
+
75
+ Pre-existing rows keep their legacy comment; clients should prefer the
76
+ structured fields when present and fall back to `comment` otherwise.
77
+
78
+ - cd6b9f2: `decisionOutputs` entries may now be declared `required` (objectui#2955). A typed entry `{ key, label?, type?, multiple?, required?: true }` tells the runtime — not just the decision UI — that an approver must supply the value: an **approve** carrying no value, or a blank one (`''`, whitespace, `[]`, an array of blanks), is rejected with `VALIDATION_FAILED` before any write, so the audit row and the request are untouched and the run can never resume past the node with the key missing.
79
+
80
+ That gap is what the flag closes. `decisionOutputs` exists so a decision can route the next step (`approvers: [{ type: 'expression', value: 'vars.lead_review.next_reviewers' }]`), but nothing made the approver actually answer: a skipped output resumed the run with the key absent, and the next node either faulted with `EXPRESSION_FAILED` or resolved an empty slate and stalled on `onEmptyApprovers: 'admin_rescue'` — long after the one person who could have filled it in had moved on. `onEmptyApprovers` was the only backstop, and it is a recovery mechanism, not a contract.
81
+
82
+ **Reject never requires them.** The run leaves down the `reject` edge, where nothing reads the outputs — demanding routing data to say "no" would trap the rejection. Outputs still ride a reject when the approver filled them in.
83
+
84
+ **No elevation bypass.** A one-click email action link and an `auto_approve` SLA escalation both fail the same way rather than advancing into a node that would resolve nobody; the escalation sweep already isolates a throwing request, so that decision stays pending and visibly overdue instead of silently breaking the run downstream. Enforcement is per decision, so on a `unanimous` / `quorum` node every approver supplies the required outputs and the finalizing decision's values are what the flow resumes with.
85
+
86
+ `required` rides `normalizeDecisionOutputs`, so it reaches clients on `decision_output_defs` — a decision UI marks the field required and blocks locally instead of round-tripping to a 400. The console side ships in objectui#2955.
87
+
88
+ ### Patch Changes
89
+
90
+ - 820eff9: fix(spec,plugin-approvals): the two approval vocabularies are derived, not hand-matched (#3786)
91
+
92
+ `sys_approval_request.status` and `sys_approval_action.action` spelled their
93
+ option lists out — five values and twelve — each under a "Keep in sync with
94
+ `ApprovalStatus` / `ApprovalActionKind` (spec/contracts)" comment, while the
95
+ contract held the same sets as bare type unions. Seventeen strings matched by
96
+ hand across a package boundary, with nothing checking them. They did all still
97
+ agree; the sweep that found them (#3786) verified that verbatim before changing
98
+ anything.
99
+
100
+ Agreeing is not the same as being held, and both directions of drift are quiet:
101
+
102
+ - a value the **column** accepts and the contract omits is invisible to every
103
+ consumer typed against the contract — the row exists and nothing can narrow it;
104
+ - a value the **contract** declares and the column rejects surfaces only at write
105
+ time, on whichever tenant first reaches that transition.
106
+
107
+ An audit vocabulary is a bad place for either. So the contract now publishes the
108
+ lists as values — `APPROVAL_STATUSES` and `APPROVAL_ACTION_KINDS` — with
109
+ `ApprovalStatus` / `ApprovalActionKind` derived from them via
110
+ `(typeof X)[number]`, and the two columns spread the constants. The per-entry
111
+ rationale (which action kinds move the flow, which are thread-only, why
112
+ `returned` differs from `recalled`) moved onto the constants, where the values
113
+ live.
114
+
115
+ **New exports, no behaviour change.** The emitted option lists are byte-identical
116
+ — verified against the built artifact before and after. Existing imports of the
117
+ two types are unaffected; the types resolve to the same unions.
118
+
119
+ `approval-vocabularies.test.ts` pins the qualifier that derivation alone cannot:
120
+ the columns agree with the contract _while the spread is there_, and the test
121
+ fails if either is re-inlined as a literal that has drifted. It also guards the
122
+ guard (an unresolvable import would compare two empty lists and pass) and asserts
123
+ the two vocabularies stay distinct, since a copy-paste pointing one column at the
124
+ other constant would satisfy "derived from the contract" while being the wrong
125
+ vocabulary entirely.
126
+
127
+ Verified by mutation in both directions: adding a value to `APPROVAL_STATUSES`
128
+ propagates into the built `sys_approval_request.status` options (the derivation
129
+ is live, not a stale build), and re-inlining a drifted literal fails
130
+ `sys_approval_request.status offers exactly the contract statuses, in order`.
131
+
132
+ - 2e836de: chore(packaging): CHANGELOG.md ships in every npm tarball (#4261)
133
+
134
+ The AGENTS.md post-task checklist requires breaking changesets to carry their
135
+ FROM → TO migration because "this text ships to consumers as `CHANGELOG.md`
136
+ inside the npm package and is what an upgrading agent greps after the tombstone
137
+ error." That delivery path was severed for 68 of the 69 publishable packages:
138
+ npm packs `package.json` / `README*` / `LICENSE*` unconditionally but — unlike
139
+ older npm versions — not `CHANGELOG.md`, and the canonical
140
+ `"files": ["dist", "README.md"]` whitelist never named it. Measured on npm
141
+ 10.9.7: `npm pack --dry-run` on `@objectstack/types` shipped 3 files while its
142
+ 70KB `CHANGELOG.md` stayed behind. Only `@objectstack/spec` listed it
143
+ explicitly.
144
+
145
+ The tombstone-error scenario is precisely the one where the repo is out of
146
+ reach — the upgrading agent has `node_modules` and nothing else — so the
147
+ migration text has to ride in the tarball. Every publishable package now
148
+ declares `CHANGELOG.md` in `files`, and the canonical whitelist is
149
+ `["dist", "README.md", "CHANGELOG.md"]`.
150
+
151
+ The other half is the gate: `check:published-files` gains a fifth invariant,
152
+ COMPLETE — a whitelist that fails to cover `CHANGELOG.md` fails the
153
+ always-required lint job, so the next package cannot silently sever the path
154
+ again. `@objectstack/spec`'s per-package EXTRA_ENTRIES exemption dissolves
155
+ into the canonical set.
156
+
157
+ Consumer-visible change: one more file per install (the package's changelog,
158
+ e.g. 70.8KB for `@objectstack/types`), and `grep -r "removed key"
159
+ node_modules/@objectstack/*/CHANGELOG.md` now finds the migration it was
160
+ promised.
161
+
162
+ - 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)
163
+
164
+ Two changes with different weights, from one sweep of every in-repo engine
165
+ call site that still speaks a deprecated alias.
166
+
167
+ **The bug — three dropped sorts.** #4346 made the engine fold `filter`→`where`
168
+ and `top`→`limit` on all six methods. The other four pairs in
169
+ `RPC_QUERY_ALIAS_SLOTS` (`select`, `sort`, `skip`, `populate`) are folded at
170
+ the RPC/wire layer only — their values need shape lowering that belongs to
171
+ those layers — and a **direct `engine.find()` never crosses that layer**. Three
172
+ call sites passed `sort` there, so it rode onto the AST untouched, every
173
+ driver's `Array.isArray(query.orderBy)` guard declined to emit an ORDER BY, and
174
+ the query returned an ordinary-looking, arbitrarily-ordered result:
175
+
176
+ | call site | asked for | actually got |
177
+ | ----------------------------------- | ------------------------------------------------- | --------------------------- |
178
+ | `share-link-routes.ts` | shared AI conversation messages, `created_at asc` | messages in arbitrary order |
179
+ | `runtime/domains/share-links.ts` | same route, runtime-domain copy | same |
180
+ | `share-link-service.ts` `listLinks` | the 200 most recent share links | an arbitrary 200 |
181
+
182
+ All three combine the dropped sort with a `limit` — the "latest N" shape whose
183
+ failure #4226 spelled out: an unapplied sort returns rows in arbitrary order,
184
+ which `limit` then slices into an arbitrary page. #4226 fixed that in the wire
185
+ normalizer; these calls sit one layer below it. `listLinks` had no test at all,
186
+ which is why it went unnoticed. Now pinned — on the option bag the engine
187
+ receives, not on row order, because the failure is that the key never becomes
188
+ `orderBy` and a fake engine honouring either spelling would pass either way.
189
+
190
+ **The cleanup — 27 no-op renames.** Every remaining in-repo engine call passing
191
+ `filter` now passes `where` (approvals 5, auth 2, reports 6, sharing 11,
192
+ webhooks 2, plus the one `filters` in a spec doc example). These are strict
193
+ no-ops since #4346 folds the alias — the point is that the framework stops
194
+ depending on a spelling it asks users to migrate off, which is a prerequisite
195
+ for ever retiring the aliases. Service-level `filter` PARAMETERS (each
196
+ service's own public API, e.g. `listRequests(filter)`) are deliberately
197
+ untouched — those are not engine option bags.
198
+
199
+ Two of the renamed calls were live victims of the #4346 bug rather than
200
+ cosmetic: `auth-manager`'s `stampIdentitySource` read the table's first row via
201
+ `findOne({filter})` and counted the whole table via `count({filter})`, so a
202
+ federated sign-in never stamped `source: 'idp_provisioned'`. #4346 already
203
+ corrected the behaviour; this makes the call say what it means.
204
+
205
+ - 9881074: fix(batch): the background walks seek instead of counting, so they stop skipping rows (#4363)
206
+
207
+ #4363 made a single paged read a partition of its result set. It could not make
208
+ a _walk_ one: seven background scans paged with a growing `offset` while writing
209
+ to the very rows they were reading, and an offset counts into a set those writes
210
+ are changing. Rows slide past the cursor and are never visited.
211
+
212
+ That is not a slow page in any of these — it is a wrong answer wearing the shape
213
+ of a clean run:
214
+
215
+ - **`rebuildApproverIndex`** built its desired state by walking
216
+ `sys_approval_request WHERE status = 'pending'` with no `orderBy` at all, then
217
+ **deleted** every index row that state did not explain. A skipped request
218
+ meant an approver silently dropped from someone's queue. (The loop beside it
219
+ ordered by `created_at` — not unique, so its pages were never a partition
220
+ either.)
221
+ - **`verifyFileReferences`** decides which files nothing references. A record it
222
+ never visits is reported as an unreferenced file.
223
+ - **`backfillFileReferences`** and the **pinyin companion backfill** rewrite
224
+ each row they read, so their own writes were shifting the set out from under
225
+ the cursor. Records were left unconverted and unsearchable by a run that
226
+ reported success.
227
+ - **`scanValueShapes`** exists to vouch that no stored value is off-shape, and
228
+ it opens a migration gate on that evidence.
229
+
230
+ All of them now go through `keysetWalk` (`@objectstack/types`): order by a
231
+ unique key, and seek past the last one instead of counting from the start. A
232
+ row's key does not move when the row is updated, and cannot be shifted when
233
+ another is deleted, so the walk is stable under exactly the mutation these
234
+ functions perform. It is also O(n) rather than O(n²/page) — measured on
235
+ Postgres over 2M rows, deep pages cost ~1.1 s by offset against ~0.09 s by seek.
236
+
237
+ One deliberate non-conversion: the REST **export** stream keeps its offset. It
238
+ honors a caller-chosen sort, and a keyset walk would have to re-order the export
239
+ by `id` to seek — changing what the user asked for to fix a cost. Its pages are
240
+ already a partition since #4363; only the depth cost remains.
241
+
242
+ `keysetWalk` merges the cursor with `$and` rather than spreading it into the
243
+ caller's filter, so a walk whose own `where` constrains the key column
244
+ (`{ id: { $in: [...] } }`) keeps that constraint instead of having it silently
245
+ overwritten. When a `max` cap is set it reads one row beyond the cap to tell
246
+ "the cap stopped us" from "the source ended exactly there" — without that, a
247
+ walk that read everything still reports `truncated`, and a caller acting on it
248
+ goes looking for rows that were never withheld.
249
+
250
+ The storage suites' fake engines now **throw** on an `offset` instead of serving
251
+ one, so the conversion is pinned rather than merely passing.
252
+
253
+ - cc2de0e: chore(packaging): 20 packages stop publishing their sources, tests and build tooling (#4248)
254
+
255
+ These 20 packages declared no `files` field, so npm fell back to packing the
256
+ whole package directory. `npm pack --dry-run` on `@objectstack/plugin-webhooks`
257
+ listed **21 files** — 15 under `src/`, three of them unit tests
258
+ (`auto-enqueuer.test.ts`, `bootstrap-declared-webhooks.test.ts`, …), plus the
259
+ build-time `scripts/i18n-extract.config.ts`. `dist/` lands on top of that at
260
+ publish time rather than instead of it, so consumers were installing the
261
+ TypeScript sources and the test suite alongside the artifact they asked for.
262
+
263
+ Each now declares `"files": ["dist", "README.md"]`, matching the 29 packages
264
+ that already did. Nothing a consumer imports moves: every `main` / `types` /
265
+ `exports` target in all 20 already resolved inside `dist/`, which the new
266
+ `check:published-files` guard verifies rather than assumes. The visible change
267
+ is a smaller install and a smaller dependency-scanning surface — `npm pack` on
268
+ `@objectstack/plugin-webhooks` now yields 2 files plus `dist/`.
269
+
270
+ The other half of the fix is the gate. Half the packages declaring `files` and
271
+ half not was the #3786 shape — a hand-copied convention with nothing enforcing
272
+ it, where whoever forgets the line gets no signal at all. `check:published-files`
273
+ (new, wired into the always-required `lint` job) holds every non-private
274
+ workspace package to four invariants: `files` is **declared**; it is
275
+ **sufficient** (covers every entry point, so tightening a whitelist cannot ship
276
+ a package that fails to resolve); it is **minimal** (admits no test, test-harness
277
+ config or build script); and anything beyond `dist` + `README.md` is
278
+ **registered** with a reason, reconciled in both directions so a stale exemption
279
+ is an error rather than dead text. `@objectstack/spec` is the one package with
280
+ registered extras — its `.zod.ts` sources, JSON Schemas, liveness ledgers and
281
+ `CHANGELOG.md` are product, not build input.
282
+
283
+ This also closes an assumption #4206 was resting on. Excluding `<pkg>/scripts/**`
284
+ from the docs-drift implementation test is sound only while no package publishes
285
+ `scripts/` as runtime code; that held, but it held because someone read all three
286
+ offenders by hand. It is now checked on every PR.
287
+
288
+ - Updated dependencies [6a67d7a]
289
+ - Updated dependencies [0ecc656]
290
+ - Updated dependencies [06772eb]
291
+ - Updated dependencies [270650f]
292
+ - Updated dependencies [3aef718]
293
+ - Updated dependencies [1ea6bce]
294
+ - Updated dependencies [c1dcacd]
295
+ - Updated dependencies [ad303ed]
296
+ - Updated dependencies [32ccb23]
297
+ - Updated dependencies [f5a4ef0]
298
+ - Updated dependencies [2d3e255]
299
+ - Updated dependencies [7d7521f]
300
+ - Updated dependencies [5dc4d02]
301
+ - Updated dependencies [05154a1]
302
+ - Updated dependencies [9b6fe7c]
303
+ - Updated dependencies [8c711fb]
304
+ - Updated dependencies [09e4547]
305
+ - Updated dependencies [91f4c78]
306
+ - Updated dependencies [820eff9]
307
+ - Updated dependencies [8d895ff]
308
+ - Updated dependencies [f6472d7]
309
+ - Updated dependencies [78caf51]
310
+ - Updated dependencies [62a789b]
311
+ - Updated dependencies [789ad63]
312
+ - Updated dependencies [2af1988]
313
+ - Updated dependencies [0af50a3]
314
+ - Updated dependencies [2e836de]
315
+ - Updated dependencies [12a19a8]
316
+ - Updated dependencies [41dcda3]
317
+ - Updated dependencies [c8124e5]
318
+ - Updated dependencies [a1a4140]
319
+ - Updated dependencies [c20b875]
320
+ - Updated dependencies [2a37694]
321
+ - Updated dependencies [217e2e6]
322
+ - Updated dependencies [86a71d1]
323
+ - Updated dependencies [d5c75e2]
324
+ - Updated dependencies [03d26f7]
325
+ - Updated dependencies [4384921]
326
+ - Updated dependencies [3c628ce]
327
+ - Updated dependencies [7cb922e]
328
+ - Updated dependencies [1d22114]
329
+ - Updated dependencies [b5f9397]
330
+ - Updated dependencies [ed77493]
331
+ - Updated dependencies [58a03d2]
332
+ - Updated dependencies [dc530b4]
333
+ - Updated dependencies [e59786e]
334
+ - Updated dependencies [bcf1112]
335
+ - Updated dependencies [9774b78]
336
+ - Updated dependencies [b07d829]
337
+ - Updated dependencies [a648e96]
338
+ - Updated dependencies [a47ac06]
339
+ - Updated dependencies [e4c61a7]
340
+ - Updated dependencies [cc60165]
341
+ - Updated dependencies [081aa6f]
342
+ - Updated dependencies [91f4c78]
343
+ - Updated dependencies [e8d0c21]
344
+ - Updated dependencies [45dc446]
345
+ - Updated dependencies [c1d44f7]
346
+ - Updated dependencies [ab9fb5c]
347
+ - Updated dependencies [f985b3f]
348
+ - Updated dependencies [9a4932a]
349
+ - Updated dependencies [f9fc874]
350
+ - Updated dependencies [011b386]
351
+ - Updated dependencies [9881074]
352
+ - Updated dependencies [7777e8f]
353
+ - Updated dependencies [507b92a]
354
+ - Updated dependencies [7309c81]
355
+ - Updated dependencies [20bc1ec]
356
+ - Updated dependencies [90c2b15]
357
+ - Updated dependencies [39eb01b]
358
+ - Updated dependencies [42eeb7d]
359
+ - Updated dependencies [01e124d]
360
+ - Updated dependencies [7ce02eb]
361
+ - Updated dependencies [a13827e]
362
+ - Updated dependencies [7733604]
363
+ - Updated dependencies [40e420f]
364
+ - Updated dependencies [d13004a]
365
+ - Updated dependencies [be7360c]
366
+ - Updated dependencies [cc2de0e]
367
+ - Updated dependencies [5b47ab5]
368
+ - Updated dependencies [b09d8d9]
369
+ - Updated dependencies [b09d8d9]
370
+ - Updated dependencies [8675db6]
371
+ - Updated dependencies [b09d8d9]
372
+ - Updated dependencies [3eb1b2b]
373
+ - Updated dependencies [59b85c0]
374
+ - Updated dependencies [6e357ed]
375
+ - Updated dependencies [d6938bf]
376
+ - Updated dependencies [31e0be9]
377
+ - Updated dependencies [4bfd455]
378
+ - Updated dependencies [ffd2ce2]
379
+ - Updated dependencies [62f8017]
380
+ - Updated dependencies [a831df1]
381
+ - Updated dependencies [f752ee3]
382
+ - Updated dependencies [a1b61e0]
383
+ - Updated dependencies [cd6b9f2]
384
+ - Updated dependencies [2cb6d3c]
385
+ - Updated dependencies [af2a095]
386
+ - Updated dependencies [ec796d5]
387
+ - Updated dependencies [e87fea1]
388
+ - Updated dependencies [c65e529]
389
+ - Updated dependencies [3ca34c1]
390
+ - Updated dependencies [239c3a3]
391
+ - Updated dependencies [94a0bbc]
392
+ - Updated dependencies [d6bfb3d]
393
+ - Updated dependencies [a2266a6]
394
+ - Updated dependencies [d25a0ec]
395
+ - Updated dependencies [667b83e]
396
+ - Updated dependencies [627b188]
397
+ - Updated dependencies [8d4eae7]
398
+ - Updated dependencies [857a6cf]
399
+ - Updated dependencies [65a3a84]
400
+ - Updated dependencies [d5749d7]
401
+ - Updated dependencies [ccd9397]
402
+ - Updated dependencies [bca935b]
403
+ - Updated dependencies [d92c72d]
404
+ - Updated dependencies [c54c822]
405
+ - Updated dependencies [8dcc0f5]
406
+ - Updated dependencies [75b9e51]
407
+ - Updated dependencies [0a2f233]
408
+ - Updated dependencies [8621cdd]
409
+ - Updated dependencies [6f23667]
410
+ - Updated dependencies [5d21a48]
411
+ - Updated dependencies [19365b7]
412
+ - Updated dependencies [b7ed26d]
413
+ - Updated dependencies [68dea0b]
414
+ - Updated dependencies [64f8cbe]
415
+ - Updated dependencies [b3a3d83]
416
+ - Updated dependencies [7a55913]
417
+ - Updated dependencies [35accbf]
418
+ - Updated dependencies [6038de7]
419
+ - Updated dependencies [eb95d97]
420
+ - Updated dependencies [e4c2dc8]
421
+ - Updated dependencies [1bd2795]
422
+ - Updated dependencies [8186a70]
423
+ - Updated dependencies [a329cca]
424
+ - Updated dependencies [6eec18c]
425
+ - Updated dependencies [4d7bebf]
426
+ - Updated dependencies [821ac7a]
427
+ - Updated dependencies [8f81731]
428
+ - Updated dependencies [4965bfa]
429
+ - Updated dependencies [8b50cb3]
430
+ - Updated dependencies [8c2db68]
431
+ - Updated dependencies [22b5e54]
432
+ - Updated dependencies [0166bd5]
433
+ - Updated dependencies [9b702dc]
434
+ - Updated dependencies [ab16331]
435
+ - @objectstack/spec@17.0.0-rc.1
436
+ - @objectstack/platform-objects@17.0.0-rc.1
437
+ - @objectstack/core@17.0.0-rc.1
438
+ - @objectstack/metadata-core@17.0.0-rc.1
439
+ - @objectstack/formula@17.0.0-rc.1
440
+ - @objectstack/types@17.0.0-rc.1
441
+
3
442
  ## 17.0.0-rc.0
4
443
 
5
444
  ### Minor Changes