@objectstack/plugin-webhooks 16.0.0 → 17.0.0-rc.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.
Files changed (39) hide show
  1. package/.turbo/turbo-build.log +22 -22
  2. package/CHANGELOG.md +257 -0
  3. package/dist/{chunk-RBCYKJVL.js → chunk-6EPMRZ7I.js} +28 -2
  4. package/dist/chunk-6EPMRZ7I.js.map +1 -0
  5. package/dist/{chunk-PTMJ5BLL.cjs → chunk-QUTQSOQC.cjs} +28 -2
  6. package/dist/chunk-QUTQSOQC.cjs.map +1 -0
  7. package/dist/index.cjs +222 -24
  8. package/dist/index.cjs.map +1 -1
  9. package/dist/index.d.cts +15 -0
  10. package/dist/index.d.ts +15 -0
  11. package/dist/index.js +202 -4
  12. package/dist/index.js.map +1 -1
  13. package/dist/schema.cjs +2 -2
  14. package/dist/schema.cjs.map +1 -1
  15. package/dist/schema.d.cts +339 -143
  16. package/dist/schema.d.ts +339 -143
  17. package/dist/schema.js +1 -1
  18. package/dist/translations-CBQRUIS5.cjs +383 -0
  19. package/dist/translations-CBQRUIS5.cjs.map +1 -0
  20. package/dist/translations-Y3CXWOTM.js +383 -0
  21. package/dist/translations-Y3CXWOTM.js.map +1 -0
  22. package/package.json +5 -5
  23. package/scripts/i18n-extract.config.ts +5 -3
  24. package/src/bootstrap-declared-webhooks.test.ts +283 -0
  25. package/src/bootstrap-declared-webhooks.ts +205 -0
  26. package/src/sys-webhook.object.ts +50 -12
  27. package/src/translations/bundle-ownership.test.ts +41 -0
  28. package/src/translations/en.objects.generated.ts +27 -113
  29. package/src/translations/es-ES.objects.generated.ts +27 -113
  30. package/src/translations/ja-JP.objects.generated.ts +27 -113
  31. package/src/translations/zh-CN.objects.generated.ts +27 -113
  32. package/src/webhook-outbox-plugin.ts +46 -0
  33. package/src/webhook-provenance.ts +86 -0
  34. package/dist/chunk-PTMJ5BLL.cjs.map +0 -1
  35. package/dist/chunk-RBCYKJVL.js.map +0 -1
  36. package/dist/translations-EPJYANXJ.js +0 -727
  37. package/dist/translations-EPJYANXJ.js.map +0 -1
  38. package/dist/translations-L2JAQDJB.cjs +0 -727
  39. package/dist/translations-L2JAQDJB.cjs.map +0 -1
@@ -1,36 +1,36 @@
1
1
 
2
- > @objectstack/plugin-webhooks@16.0.0 build /home/runner/work/framework/framework/packages/plugins/plugin-webhooks
2
+ > @objectstack/plugin-webhooks@17.0.0-rc.0 build /home/runner/work/objectstack/objectstack/packages/plugins/plugin-webhooks
3
3
  > tsup
4
4
 
5
5
  CLI Building entry: src/index.ts, src/schema.ts
6
6
  CLI Using tsconfig: tsconfig.json
7
7
  CLI tsup v8.5.1
8
- CLI Using tsup config: /home/runner/work/framework/framework/packages/plugins/plugin-webhooks/tsup.config.ts
8
+ CLI Using tsup config: /home/runner/work/objectstack/objectstack/packages/plugins/plugin-webhooks/tsup.config.ts
9
9
  CLI Target: es2020
10
10
  CLI Cleaning output folder
11
11
  ESM Build start
12
12
  CJS Build start
13
- ESM dist/index.js 13.97 KB
13
+ ESM dist/index.js 20.63 KB
14
14
  ESM dist/schema.js 111.00 B
15
- ESM dist/chunk-RBCYKJVL.js 5.61 KB
16
- ESM dist/translations-EPJYANXJ.js 19.34 KB
17
- ESM dist/index.js.map 35.28 KB
15
+ ESM dist/chunk-6EPMRZ7I.js 6.98 KB
16
+ ESM dist/translations-Y3CXWOTM.js 12.89 KB
17
+ ESM dist/index.js.map 53.27 KB
18
18
  ESM dist/schema.js.map 71.00 B
19
- ESM dist/chunk-RBCYKJVL.js.map 10.21 KB
20
- ESM dist/translations-EPJYANXJ.js.map 30.50 KB
21
- ESM ⚡️ Build success in 832ms
22
- CJS dist/index.cjs 17.76 KB
19
+ ESM dist/chunk-6EPMRZ7I.js.map 12.42 KB
20
+ ESM dist/translations-Y3CXWOTM.js.map 17.78 KB
21
+ ESM ⚡️ Build success in 546ms
22
+ CJS dist/index.cjs 26.40 KB
23
23
  CJS dist/schema.cjs 220.00 B
24
- CJS dist/chunk-PTMJ5BLL.cjs 5.76 KB
25
- CJS dist/translations-L2JAQDJB.cjs 19.43 KB
26
- CJS dist/index.cjs.map 32.52 KB
27
- CJS dist/schema.cjs.map 278.00 B
28
- CJS dist/chunk-PTMJ5BLL.cjs.map 12.08 KB
29
- CJS dist/translations-L2JAQDJB.cjs.map 34.61 KB
30
- CJS ⚡️ Build success in 1054ms
24
+ CJS dist/chunk-QUTQSOQC.cjs 7.14 KB
25
+ CJS dist/translations-CBQRUIS5.cjs 12.98 KB
26
+ CJS dist/index.cjs.map 48.41 KB
27
+ CJS dist/schema.cjs.map 286.00 B
28
+ CJS dist/chunk-QUTQSOQC.cjs.map 14.45 KB
29
+ CJS dist/translations-CBQRUIS5.cjs.map 20.24 KB
30
+ CJS ⚡️ Build success in 695ms
31
31
  DTS Build start
32
- DTS ⚡️ Build success in 25376ms
33
- DTS dist/index.d.ts 6.96 KB
34
- DTS dist/schema.d.ts 107.72 KB
35
- DTS dist/index.d.cts 6.96 KB
36
- DTS dist/schema.d.cts 107.72 KB
32
+ DTS ⚡️ Build success in 25488ms
33
+ DTS dist/index.d.ts 7.79 KB
34
+ DTS dist/schema.d.ts 118.05 KB
35
+ DTS dist/index.d.cts 7.79 KB
36
+ DTS dist/schema.d.cts 118.05 KB
package/CHANGELOG.md CHANGED
@@ -1,5 +1,262 @@
1
1
  # @objectstack/plugin-webhooks
2
2
 
3
+ ## 17.0.0-rc.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 69f1dfd: fix(webhooks): materialize stack-declared webhooks into the dispatcher (#3461)
8
+
9
+ A webhook authored declaratively — `defineStack({ webhooks })` / `defineWebhook()`,
10
+ validated against the spec `WebhookSchema` — was a **silent no-op**. The runtime
11
+ dispatcher (`AutoEnqueuer`) fans out off `sys_webhook` DATA rows (`object_name` /
12
+ `active`), which until now were only ever written by hand through the object's
13
+ CRUD UI. Nothing turned a declared webhook (`object` / `isActive`) into a
14
+ dispatchable row, so authoring `webhooks:` on a stack produced `webhook` metadata
15
+ that never fired (ADR-0078). The showcase app itself shipped a `webhooks:` entry
16
+ that did nothing.
17
+
18
+ `@objectstack/plugin-webhooks` now bridges the two on boot:
19
+
20
+ - **`bootstrapDeclaredWebhooks`** reads declared `webhook` metadata from the
21
+ ObjectQL registry (where the manifest decomposition already parks
22
+ `stack.webhooks`), validates each through `WebhookSchema.parse()` — the spec
23
+ schema finally has a real consumer — and materializes it into a `sys_webhook`
24
+ row, mapping `object → object_name`, `isActive → active`, and stashing the full
25
+ envelope (headers / secret / retry / timeout) in `definition_json`. The
26
+ auto-enqueuer's first cache refresh then picks the row up and dispatches it.
27
+ - **Seed-not-clobber provenance** (mirrors `sys_sharing_rule`, #2909): `sys_webhook`
28
+ gains `managed_by` / `customized` columns. Declared webhooks re-seed every boot
29
+ as `managed_by: 'package'`, but a row an admin created (`managed_by: 'admin'`) or
30
+ edited in Setup (`customized: true`, stamped by a `beforeUpdate` hook) is never
31
+ overwritten — a deactivated noisy webhook survives redeploys.
32
+
33
+ Connector-declared `webhooks` remain not-yet-enforced (that is a separate seam,
34
+ #3197). Registering `webhook` as a first-class metadata type + enrolling it in the
35
+ liveness `GOVERNED` set is a tracked follow-up.
36
+
37
+ Migration: none required. Existing hand-authored `sys_webhook` rows default to
38
+ `managed_by: 'admin'` and are never touched by the seeder. Anyone who authored
39
+ `webhooks:` on a stack expecting it to fire will find it now does — review those
40
+ declarations (especially `url` / `isActive`) before upgrading.
41
+
42
+ ### Patch Changes
43
+
44
+ - aff9e56: fix(i18n): translate the platform packages' declared surface, and gate all nine bundles instead of one (#3762)
45
+
46
+ Only `platform-objects` was wired into a translation-drift check. The other
47
+ **eight** packages shipped a `scripts/i18n-extract.config.ts` that nothing ever
48
+ ran — and four of them had already drifted out of sync with the schema, exactly
49
+ the rot `pnpm check:i18n` exists to catch, one directory over.
50
+
51
+ **Translated.** `plugin-security` (45 strings per locale), `plugin-webhooks`
52
+ (15), `plugin-audit` (8), `plugin-sharing` (7) and `service-storage` (7) are now
53
+ at **zero** untranslated declared strings in zh-CN / ja-JP / es-ES — 246
54
+ translations. Most were newly _visible_ rather than newly missing: #3753 taught
55
+ the coverage detector to walk action `params`, `resultDialog`, `listViews` and
56
+ the rest of the declared surface, and these are what it found.
57
+
58
+ Wording was harvested from the repo's own bundles wherever a string was already
59
+ translated somewhere (1382 unambiguous source strings), so `Created At` reads
60
+ `创建时间` here because that is what it reads everywhere else, rather than a
61
+ fresh invention. Protocol tokens are deliberately left identical across locales:
62
+ `GET` / `POST` / `PUT` / `PATCH` / `DELETE`, `ETag`, `ACL`, `URL`.
63
+
64
+ **Gated.** `scripts/check-i18n-bundles.mjs` replaces the single-package
65
+ `pnpm check:i18n` and checks all nine. It does not restate each package's
66
+ command — it parses the one already documented in that config's own docstring
67
+ and runs it, so the documented regenerate command and the gate cannot diverge.
68
+ The coverage ratchet grows the same way, from `examples/*` to twelve configs;
69
+ eight of them sit at zero, which makes it the strict gate there.
70
+
71
+ **Fixed a real truncation bug it exposed.** `os lint --json` on a large config
72
+ came out of a pipe cut off at exactly 65536 bytes — `console.log(big)` followed
73
+ by `process.exit(1)` tears the process down before an async pipe write drains,
74
+ while an interactive run (stdout is a TTY, written synchronously) looks perfect.
75
+ Every scripted consumer silently got invalid JSON. `emitJson` in
76
+ `packages/cli/src/utils/format.ts` waits for the write to drain and sets
77
+ `process.exitCode` instead; `lint`, `i18n check` and `i18n extract` use it.
78
+ Roughly 30 other CLI commands share the pattern and are not touched here.
79
+
80
+ The nine documented regenerate commands also gain `--no-metadata-forms` (added
81
+ in #3768), since the Studio metadata-form baseline belongs to `platform-objects`
82
+ alone, not to a copy in every plugin.
83
+
84
+ Not fixed here: `platform-objects`' own 77-per-locale gap is `apps.*` /
85
+ `dashboards.*` navigation and widget labels, which live outside the `objects`
86
+ subtree and cannot be scaffolded while the package extracts with
87
+ `--objects-only`. That needs an emit decision first — tracked in #3762.
88
+
89
+ - 52281b0: chore(i18n): purge the dead sys_webhook_delivery translation block and guard against recurrence
90
+
91
+ `sys_webhook_delivery` was removed when webhook delivery moved to
92
+ `@objectstack/service-messaging` (`sys_http_delivery`, ADR-0018 M3), but a full
93
+ translation block for it lingered in the four generated plugin-webhooks i18n
94
+ bundles (en/zh-CN/ja-JP/es-ES) — dead weight bound to an object that no longer
95
+ exists, and destined to be dropped silently (with any curated strings) on the
96
+ next `os i18n extract`.
97
+
98
+ - Removed the stale `sys_webhook_delivery` block from all four locale bundles
99
+ (surgical; the `sys_webhook` block is untouched).
100
+ - Corrected three stale `sys_webhook_delivery` doc comments (platform-objects
101
+ `integration/index.ts` + `setup.app.ts`, plugin-webhooks `sys-webhook.object.ts`)
102
+ that still named it as a plugin-webhooks-owned object.
103
+ - Rolled out the platform-objects `bundle-ownership` test guard (#2834 ⑤ /
104
+ ADR-0029 D8) to the eight packages that own i18n bundles, so a stray object
105
+ block in a generated bundle now fails the build instead of dying silently.
106
+ - That guard immediately surfaced a live-object omission: `sys_capability` was
107
+ present in plugin-security's bundles with curated translations but had been
108
+ dropped from its extract config — re-added to the config so the strings are
109
+ preserved, rather than deleted.
110
+
111
+ - c95ac80: chore(plugin-webhooks): drop the dead sys_webhook_delivery i18n blocks
112
+
113
+ `sys_webhook_delivery` was removed from `@objectstack/plugin-webhooks` when
114
+ outbound delivery moved to `@objectstack/service-messaging` (`sys_http_delivery`,
115
+ ADR-0018 M3), but its translation blocks lingered in all four generated locale
116
+ bundles (en / zh-CN / ja-JP / es-ES) — loaded at runtime yet referenced by
117
+ nothing, since the object no longer exists in this plugin.
118
+
119
+ - Removed the `sys_webhook_delivery` node from each `*.objects.generated.ts`
120
+ bundle; `WebhooksTranslations` now carries only `sys_webhook`.
121
+ - Corrected the stale ownership comment on `SysWebhook` that still named
122
+ `sys_webhook_delivery` as a live sibling.
123
+
124
+ (The dangling `SysWebhookDelivery` import in `scripts/i18n-extract.config.ts`
125
+ was fixed independently on `main` by #3489, so it is not part of this change.)
126
+
127
+ - Updated dependencies [50616d9]
128
+ - Updated dependencies [08b5a3d]
129
+ - Updated dependencies [d99aeb3]
130
+ - Updated dependencies [4727eb8]
131
+ - Updated dependencies [f63cd09]
132
+ - Updated dependencies [fa3d0cf]
133
+ - Updated dependencies [af5a224]
134
+ - Updated dependencies [71f76e1]
135
+ - Updated dependencies [37b1346]
136
+ - Updated dependencies [99736a0]
137
+ - Updated dependencies [fe67e34]
138
+ - Updated dependencies [fdb4f50]
139
+ - Updated dependencies [1bd5652]
140
+ - Updated dependencies [14252d3]
141
+ - Updated dependencies [7fb436c]
142
+ - Updated dependencies [879ea13]
143
+ - Updated dependencies [201b31f]
144
+ - Updated dependencies [e2616e0]
145
+ - Updated dependencies [6fdc5c6]
146
+ - Updated dependencies [8b9d71e]
147
+ - Updated dependencies [33f5e23]
148
+ - Updated dependencies [259af21]
149
+ - Updated dependencies [587fc91]
150
+ - Updated dependencies [1986594]
151
+ - Updated dependencies [ad4af62]
152
+ - Updated dependencies [d44dbfa]
153
+ - Updated dependencies [474fe39]
154
+ - Updated dependencies [0bc685a]
155
+ - Updated dependencies [b949059]
156
+ - Updated dependencies [be1c52c]
157
+ - Updated dependencies [c5ff96d]
158
+ - Updated dependencies [84e7be9]
159
+ - Updated dependencies [a6c3f38]
160
+ - Updated dependencies [debc23a]
161
+ - Updated dependencies [0f8ad09]
162
+ - Updated dependencies [8f9689f]
163
+ - Updated dependencies [57a3bb3]
164
+ - Updated dependencies [5f9a987]
165
+ - Updated dependencies [db02d47]
166
+ - Updated dependencies [0bfdf46]
167
+ - Updated dependencies [376a061]
168
+ - Updated dependencies [7c7e246]
169
+ - Updated dependencies [f35cdc5]
170
+ - Updated dependencies [9ea2bc5]
171
+ - Updated dependencies [c2d9098]
172
+ - Updated dependencies [a227ed7]
173
+ - Updated dependencies [9613396]
174
+ - Updated dependencies [e47b342]
175
+ - Updated dependencies [4ed7ed4]
176
+ - Updated dependencies [2fa4ca1]
177
+ - Updated dependencies [f5a2320]
178
+ - Updated dependencies [deb538f]
179
+ - Updated dependencies [5b89711]
180
+ - Updated dependencies [0c8a22f]
181
+ - Updated dependencies [763931e]
182
+ - Updated dependencies [de9af8a]
183
+ - Updated dependencies [c4df271]
184
+ - Updated dependencies [a41ba5c]
185
+ - Updated dependencies [189854c]
186
+ - Updated dependencies [0e3a226]
187
+ - Updated dependencies [1d4756e]
188
+ - Updated dependencies [720c5ad]
189
+ - Updated dependencies [a8d1e24]
190
+ - Updated dependencies [41642b0]
191
+ - Updated dependencies [4cca74c]
192
+ - Updated dependencies [88ef03e]
193
+ - Updated dependencies [9e2caf3]
194
+ - Updated dependencies [81ce41a]
195
+ - Updated dependencies [85e1e4e]
196
+ - Updated dependencies [dac6a08]
197
+ - Updated dependencies [394b7a1]
198
+ - Updated dependencies [677b591]
199
+ - Updated dependencies [d77d1b7]
200
+ - Updated dependencies [5b79a34]
201
+ - Updated dependencies [c757854]
202
+ - Updated dependencies [0045682]
203
+ - Updated dependencies [2a5f04a]
204
+ - Updated dependencies [4f740b0]
205
+ - Updated dependencies [67452d1]
206
+ - Updated dependencies [0fc6219]
207
+ - Updated dependencies [605e190]
208
+ - Updated dependencies [c6c59f1]
209
+ - Updated dependencies [b0e78a8]
210
+ - Updated dependencies [f31cc8d]
211
+ - Updated dependencies [f343dc4]
212
+ - Updated dependencies [8269e32]
213
+ - Updated dependencies [74f7339]
214
+ - Updated dependencies [a6c35a2]
215
+ - Updated dependencies [c2f1002]
216
+ - Updated dependencies [f163028]
217
+ - Updated dependencies [f07808c]
218
+ - Updated dependencies [7ffc3d3]
219
+ - Updated dependencies [88346ba]
220
+ - Updated dependencies [4631592]
221
+ - Updated dependencies [32ff033]
222
+ - Updated dependencies [5ac93d4]
223
+ - Updated dependencies [93f267f]
224
+ - Updated dependencies [0024abf]
225
+ - Updated dependencies [acbf364]
226
+ - Updated dependencies [7687f7b]
227
+ - Updated dependencies [1659072]
228
+ - Updated dependencies [abceb0d]
229
+ - Updated dependencies [0c302a7]
230
+ - Updated dependencies [6633337]
231
+ - Updated dependencies [f00d8d4]
232
+ - Updated dependencies [503be86]
233
+ - Updated dependencies [cde1975]
234
+ - Updated dependencies [0bc685a]
235
+ - Updated dependencies [11949fc]
236
+ - Updated dependencies [b098b0e]
237
+ - Updated dependencies [4d00b13]
238
+ - Updated dependencies [57bab76]
239
+ - Updated dependencies [b90086a]
240
+ - Updated dependencies [b95577a]
241
+ - Updated dependencies [83c161f]
242
+ - Updated dependencies [d8c4957]
243
+ - Updated dependencies [f24cb83]
244
+ - Updated dependencies [5dbbb92]
245
+ - Updated dependencies [69f1dfd]
246
+ - @objectstack/spec@17.0.0-rc.0
247
+ - @objectstack/core@17.0.0-rc.0
248
+ - @objectstack/service-messaging@17.0.0-rc.0
249
+
250
+ ## 16.1.0
251
+
252
+ ### Patch Changes
253
+
254
+ - Updated dependencies [9e45b63]
255
+ - Updated dependencies [b20201f]
256
+ - @objectstack/spec@16.1.0
257
+ - @objectstack/core@16.1.0
258
+ - @objectstack/service-messaging@16.1.0
259
+
3
260
  ## 16.0.0
4
261
 
5
262
  ### Patch Changes
@@ -13,7 +13,7 @@ var SysWebhook = ObjectSchema.create({
13
13
  // create/edit/delete so admins can at least toggle `active` and edit
14
14
  // simple URL/method fields without round-tripping through code.
15
15
  userActions: { create: true, edit: true, delete: true, import: false },
16
- description: "Outbound HTTP webhook subscription. Authored via defineWebhook() in code or the Studio editor; executed by the HTTP connector plugin.",
16
+ description: "Outbound HTTP webhook subscription. Declared in code via defineStack({ webhooks }) / defineWebhook() (materialized into rows on boot) or authored directly in the Studio editor; dispatched by the webhook auto-enqueuer onto the shared HTTP outbox.",
17
17
  displayNameField: "name",
18
18
  nameField: "name",
19
19
  // [ADR-0079] canonical primary-title pointer (mirrors deprecated displayNameField)
@@ -133,6 +133,32 @@ var SysWebhook = ObjectSchema.create({
133
133
  description: "Serialised Webhook JSON (see @objectstack/spec/automation/webhook) \u2014 full headers/auth/retry/payload config",
134
134
  group: "Definition"
135
135
  }),
136
+ // ── Provenance (#3461 — record-authoritative seed-not-clobber) ──
137
+ // Mirrors sys_sharing_rule (#2909). Both columns are `readonly`: the
138
+ // engine strips them from non-system payloads (forge/clear-proof), while
139
+ // bootstrapDeclaredWebhooks and the provenance stamp hook write with
140
+ // isSystem. Deliberately NOT a write gate: webhooks are a first-class admin
141
+ // authoring/tuning surface — admins may edit or deactivate a package row;
142
+ // the seeder simply stops overwriting it once `customized` is stamped.
143
+ managed_by: Field.select(
144
+ ["platform", "package", "admin"],
145
+ {
146
+ label: "Managed By",
147
+ required: false,
148
+ readonly: true,
149
+ defaultValue: "admin",
150
+ description: "Record provenance: platform = framework built-in / package = app/package-declared (boot-seeded from defineStack webhooks) / admin = created in Setup.",
151
+ group: "System"
152
+ }
153
+ ),
154
+ customized: Field.boolean({
155
+ label: "Customized",
156
+ required: false,
157
+ readonly: true,
158
+ defaultValue: false,
159
+ description: "Set when an admin edits a package-declared webhook; boot seeding will no longer overwrite the row (a deactivated noisy webhook survives redeploys). Meaningless on admin rows.",
160
+ group: "System"
161
+ }),
136
162
  created_at: Field.datetime({
137
163
  label: "Created At",
138
164
  required: true,
@@ -152,4 +178,4 @@ var SysWebhook = ObjectSchema.create({
152
178
  export {
153
179
  SysWebhook
154
180
  };
155
- //# sourceMappingURL=chunk-RBCYKJVL.js.map
181
+ //# sourceMappingURL=chunk-6EPMRZ7I.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/sys-webhook.object.ts"],"sourcesContent":["// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport { ObjectSchema, Field } from '@objectstack/spec/data';\n\n/**\n * sys_webhook — Outbound HTTP integration configuration (runtime).\n *\n * Persists a single {@link Webhook} envelope per row so administrators\n * can author, enable/disable, and edit webhook subscriptions from the\n * Studio UI without code changes. The canonical Zod schema for the\n * `definition_json` envelope lives at `@objectstack/spec/automation/webhook`.\n *\n * ## Two authoring doors, one row\n * Rows land here two ways, distinguished by the `managed_by` provenance column:\n * - **admin** — created/edited directly through this object's CRUD UI.\n * - **package** — declared in code (`defineStack({ webhooks })` /\n * `defineWebhook()`) and materialized on boot by\n * `bootstrapDeclaredWebhooks` (#3461). Re-seeded every boot, but an admin\n * edit stamps `customized: true` and freezes the row (seed-not-clobber,\n * mirrors `sys_sharing_rule` #2909).\n *\n * One row per `name`. This plugin's {@link AutoEnqueuer} loads active rows on\n * boot + on `sys_webhook:changed` events, and turns matching `data.record.*`\n * events into deliveries on the shared `service-messaging` HTTP outbox\n * (ADR-0018 M3 — `sys_http_delivery`, drained by the messaging dispatcher).\n *\n * Ownership (ADR-0029 K2.a): this object is **owned by\n * `@objectstack/plugin-webhooks`** — the plugin that consumes these rows. It\n * used to live in the `@objectstack/platform-objects` monolith and be imported\n * here; the definition now lives with its owner so the plugin ships both data\n * and behavior as one unit.\n *\n * Platform-wide on purpose: every project (standalone, single-tenant,\n * cloud) can integrate with external systems (Slack, Stripe, internal\n * services) the same way.\n *\n * @namespace sys\n */\nexport const SysWebhook = ObjectSchema.create({\n name: 'sys_webhook',\n label: 'Webhook',\n pluralLabel: 'Webhooks',\n icon: 'webhook',\n isSystem: true,\n managedBy: 'config',\n // Authoring a webhook from the UI requires a structured form for the\n // headers / auth / retry / payload blocks — the generic JSON textarea\n // is acceptable as a v1 until a dedicated builder lands. Re-enable\n // create/edit/delete so admins can at least toggle `active` and edit\n // simple URL/method fields without round-tripping through code.\n userActions: { create: true, edit: true, delete: true, import: false },\n description: 'Outbound HTTP webhook subscription. Declared in code via defineStack({ webhooks }) / defineWebhook() (materialized into rows on boot) or authored directly in the Studio editor; dispatched by the webhook auto-enqueuer onto the shared HTTP outbox.',\n displayNameField: 'name',\n nameField: 'name', // [ADR-0079] canonical primary-title pointer (mirrors deprecated displayNameField)\n titleFormat: '{label}',\n highlightFields: ['name', 'object_name', 'url', 'active', 'updated_at'],\n\n listViews: {\n active: {\n type: 'grid',\n name: 'active',\n label: 'Active',\n data: { provider: 'object', object: 'sys_webhook' },\n columns: ['label', 'object_name', 'url', 'method', 'active', 'updated_at'],\n filter: [{ field: 'active', operator: 'equals', value: true }],\n sort: [{ field: 'label', order: 'asc' }],\n pagination: { pageSize: 50 },\n },\n inactive: {\n type: 'grid',\n name: 'inactive',\n label: 'Inactive',\n data: { provider: 'object', object: 'sys_webhook' },\n columns: ['label', 'object_name', 'url', 'method', 'active', 'updated_at'],\n filter: [{ field: 'active', operator: 'equals', value: false }],\n sort: [{ field: 'label', order: 'asc' }],\n pagination: { pageSize: 50 },\n },\n by_object: {\n type: 'grid',\n name: 'by_object',\n label: 'By Object',\n data: { provider: 'object', object: 'sys_webhook' },\n columns: ['object_name', 'label', 'url', 'active', 'updated_at'],\n sort: [{ field: 'object_name', order: 'asc' }, { field: 'label', order: 'asc' }],\n grouping: { fields: [{ field: 'object_name', order: 'asc', collapsed: false }] },\n pagination: { pageSize: 100 },\n },\n all_webhooks: {\n type: 'grid',\n name: 'all_webhooks',\n label: 'All',\n data: { provider: 'object', object: 'sys_webhook' },\n columns: ['label', 'object_name', 'url', 'method', 'active', 'updated_at'],\n sort: [{ field: 'label', order: 'asc' }],\n pagination: { pageSize: 50 },\n },\n },\n\n fields: {\n id: Field.text({ label: 'Webhook ID', required: true, readonly: true, group: 'System' }),\n\n name: Field.text({\n label: 'Name',\n required: true,\n maxLength: 100,\n description: 'Unique snake_case name — referenced in logs and audit',\n group: 'Definition',\n }),\n\n label: Field.text({\n label: 'Display Label',\n required: false,\n maxLength: 200,\n group: 'Definition',\n }),\n\n object_name: Field.text({\n label: 'Object',\n required: false,\n maxLength: 100,\n // Object picker (same widget as sys_sharing_rule) instead of a free-text\n // machine name. Falls back to a text input when the widget is unavailable.\n widget: 'object-ref',\n description: 'Short object name whose record events (create/update/delete) fire this webhook',\n group: 'Definition',\n }),\n\n triggers: Field.select(\n ['create', 'update', 'delete'],\n {\n label: 'Triggers',\n required: false,\n // Multi-select instead of a hand-typed comma-separated string. Stored as\n // an array; the auto-enqueuer parser also tolerates the legacy\n // comma-separated / JSON-string forms so existing rows keep working.\n multiple: true,\n description: 'Record events that fire this webhook',\n group: 'Definition',\n },\n ),\n\n url: Field.text({\n label: 'Target URL',\n required: true,\n maxLength: 2048,\n description: 'External endpoint that receives the POST',\n group: 'Definition',\n }),\n\n method: Field.select(\n ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'],\n {\n label: 'HTTP Method',\n required: true,\n // Select instead of free text. Option values are lowercased by the\n // Field.select helper (get/post/…); the auto-enqueuer upper-cases the\n // resolved method before delivery, so existing 'POST' rows and the\n // lowercase option values both normalise correctly.\n defaultValue: 'post',\n description: 'HTTP method used for the callback request',\n group: 'Definition',\n },\n ),\n\n description: Field.textarea({ label: 'Description', required: false, group: 'Definition' }),\n\n active: Field.boolean({\n label: 'Active',\n required: true,\n defaultValue: true,\n description: 'Inactive webhooks are skipped by the dispatcher',\n group: 'Definition',\n }),\n\n definition_json: Field.textarea({\n label: 'Definition',\n required: true,\n description: 'Serialised Webhook JSON (see @objectstack/spec/automation/webhook) — full headers/auth/retry/payload config',\n group: 'Definition',\n }),\n\n // ── Provenance (#3461 — record-authoritative seed-not-clobber) ──\n // Mirrors sys_sharing_rule (#2909). Both columns are `readonly`: the\n // engine strips them from non-system payloads (forge/clear-proof), while\n // bootstrapDeclaredWebhooks and the provenance stamp hook write with\n // isSystem. Deliberately NOT a write gate: webhooks are a first-class admin\n // authoring/tuning surface — admins may edit or deactivate a package row;\n // the seeder simply stops overwriting it once `customized` is stamped.\n managed_by: Field.select(\n ['platform', 'package', 'admin'],\n {\n label: 'Managed By',\n required: false,\n readonly: true,\n defaultValue: 'admin',\n description:\n 'Record provenance: platform = framework built-in / package = app/package-declared ' +\n '(boot-seeded from defineStack webhooks) / admin = created in Setup.',\n group: 'System',\n },\n ),\n\n customized: Field.boolean({\n label: 'Customized',\n required: false,\n readonly: true,\n defaultValue: false,\n description:\n 'Set when an admin edits a package-declared webhook; boot seeding will no longer ' +\n 'overwrite the row (a deactivated noisy webhook survives redeploys). Meaningless on admin rows.',\n group: 'System',\n }),\n\n created_at: Field.datetime({\n label: 'Created At',\n required: true,\n defaultValue: 'NOW()',\n readonly: true,\n group: 'System',\n }),\n\n updated_at: Field.datetime({ label: 'Updated At', required: false, group: 'System' }),\n },\n\n indexes: [\n { fields: ['name'], unique: true },\n { fields: ['object_name'] },\n { fields: ['active', 'object_name'] },\n ],\n});\n"],"mappings":"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","names":[]}
@@ -13,7 +13,7 @@ var SysWebhook = _data.ObjectSchema.create({
13
13
  // create/edit/delete so admins can at least toggle `active` and edit
14
14
  // simple URL/method fields without round-tripping through code.
15
15
  userActions: { create: true, edit: true, delete: true, import: false },
16
- description: "Outbound HTTP webhook subscription. Authored via defineWebhook() in code or the Studio editor; executed by the HTTP connector plugin.",
16
+ description: "Outbound HTTP webhook subscription. Declared in code via defineStack({ webhooks }) / defineWebhook() (materialized into rows on boot) or authored directly in the Studio editor; dispatched by the webhook auto-enqueuer onto the shared HTTP outbox.",
17
17
  displayNameField: "name",
18
18
  nameField: "name",
19
19
  // [ADR-0079] canonical primary-title pointer (mirrors deprecated displayNameField)
@@ -133,6 +133,32 @@ var SysWebhook = _data.ObjectSchema.create({
133
133
  description: "Serialised Webhook JSON (see @objectstack/spec/automation/webhook) \u2014 full headers/auth/retry/payload config",
134
134
  group: "Definition"
135
135
  }),
136
+ // ── Provenance (#3461 — record-authoritative seed-not-clobber) ──
137
+ // Mirrors sys_sharing_rule (#2909). Both columns are `readonly`: the
138
+ // engine strips them from non-system payloads (forge/clear-proof), while
139
+ // bootstrapDeclaredWebhooks and the provenance stamp hook write with
140
+ // isSystem. Deliberately NOT a write gate: webhooks are a first-class admin
141
+ // authoring/tuning surface — admins may edit or deactivate a package row;
142
+ // the seeder simply stops overwriting it once `customized` is stamped.
143
+ managed_by: _data.Field.select(
144
+ ["platform", "package", "admin"],
145
+ {
146
+ label: "Managed By",
147
+ required: false,
148
+ readonly: true,
149
+ defaultValue: "admin",
150
+ description: "Record provenance: platform = framework built-in / package = app/package-declared (boot-seeded from defineStack webhooks) / admin = created in Setup.",
151
+ group: "System"
152
+ }
153
+ ),
154
+ customized: _data.Field.boolean({
155
+ label: "Customized",
156
+ required: false,
157
+ readonly: true,
158
+ defaultValue: false,
159
+ description: "Set when an admin edits a package-declared webhook; boot seeding will no longer overwrite the row (a deactivated noisy webhook survives redeploys). Meaningless on admin rows.",
160
+ group: "System"
161
+ }),
136
162
  created_at: _data.Field.datetime({
137
163
  label: "Created At",
138
164
  required: true,
@@ -152,4 +178,4 @@ var SysWebhook = _data.ObjectSchema.create({
152
178
 
153
179
 
154
180
  exports.SysWebhook = SysWebhook;
155
- //# sourceMappingURL=chunk-PTMJ5BLL.cjs.map
181
+ //# sourceMappingURL=chunk-QUTQSOQC.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/home/runner/work/objectstack/objectstack/packages/plugins/plugin-webhooks/dist/chunk-QUTQSOQC.cjs","../src/sys-webhook.object.ts"],"names":[],"mappings":"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","file":"/home/runner/work/objectstack/objectstack/packages/plugins/plugin-webhooks/dist/chunk-QUTQSOQC.cjs","sourcesContent":[null,"// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.\n\nimport { ObjectSchema, Field } from '@objectstack/spec/data';\n\n/**\n * sys_webhook — Outbound HTTP integration configuration (runtime).\n *\n * Persists a single {@link Webhook} envelope per row so administrators\n * can author, enable/disable, and edit webhook subscriptions from the\n * Studio UI without code changes. The canonical Zod schema for the\n * `definition_json` envelope lives at `@objectstack/spec/automation/webhook`.\n *\n * ## Two authoring doors, one row\n * Rows land here two ways, distinguished by the `managed_by` provenance column:\n * - **admin** — created/edited directly through this object's CRUD UI.\n * - **package** — declared in code (`defineStack({ webhooks })` /\n * `defineWebhook()`) and materialized on boot by\n * `bootstrapDeclaredWebhooks` (#3461). Re-seeded every boot, but an admin\n * edit stamps `customized: true` and freezes the row (seed-not-clobber,\n * mirrors `sys_sharing_rule` #2909).\n *\n * One row per `name`. This plugin's {@link AutoEnqueuer} loads active rows on\n * boot + on `sys_webhook:changed` events, and turns matching `data.record.*`\n * events into deliveries on the shared `service-messaging` HTTP outbox\n * (ADR-0018 M3 — `sys_http_delivery`, drained by the messaging dispatcher).\n *\n * Ownership (ADR-0029 K2.a): this object is **owned by\n * `@objectstack/plugin-webhooks`** — the plugin that consumes these rows. It\n * used to live in the `@objectstack/platform-objects` monolith and be imported\n * here; the definition now lives with its owner so the plugin ships both data\n * and behavior as one unit.\n *\n * Platform-wide on purpose: every project (standalone, single-tenant,\n * cloud) can integrate with external systems (Slack, Stripe, internal\n * services) the same way.\n *\n * @namespace sys\n */\nexport const SysWebhook = ObjectSchema.create({\n name: 'sys_webhook',\n label: 'Webhook',\n pluralLabel: 'Webhooks',\n icon: 'webhook',\n isSystem: true,\n managedBy: 'config',\n // Authoring a webhook from the UI requires a structured form for the\n // headers / auth / retry / payload blocks — the generic JSON textarea\n // is acceptable as a v1 until a dedicated builder lands. Re-enable\n // create/edit/delete so admins can at least toggle `active` and edit\n // simple URL/method fields without round-tripping through code.\n userActions: { create: true, edit: true, delete: true, import: false },\n description: 'Outbound HTTP webhook subscription. Declared in code via defineStack({ webhooks }) / defineWebhook() (materialized into rows on boot) or authored directly in the Studio editor; dispatched by the webhook auto-enqueuer onto the shared HTTP outbox.',\n displayNameField: 'name',\n nameField: 'name', // [ADR-0079] canonical primary-title pointer (mirrors deprecated displayNameField)\n titleFormat: '{label}',\n highlightFields: ['name', 'object_name', 'url', 'active', 'updated_at'],\n\n listViews: {\n active: {\n type: 'grid',\n name: 'active',\n label: 'Active',\n data: { provider: 'object', object: 'sys_webhook' },\n columns: ['label', 'object_name', 'url', 'method', 'active', 'updated_at'],\n filter: [{ field: 'active', operator: 'equals', value: true }],\n sort: [{ field: 'label', order: 'asc' }],\n pagination: { pageSize: 50 },\n },\n inactive: {\n type: 'grid',\n name: 'inactive',\n label: 'Inactive',\n data: { provider: 'object', object: 'sys_webhook' },\n columns: ['label', 'object_name', 'url', 'method', 'active', 'updated_at'],\n filter: [{ field: 'active', operator: 'equals', value: false }],\n sort: [{ field: 'label', order: 'asc' }],\n pagination: { pageSize: 50 },\n },\n by_object: {\n type: 'grid',\n name: 'by_object',\n label: 'By Object',\n data: { provider: 'object', object: 'sys_webhook' },\n columns: ['object_name', 'label', 'url', 'active', 'updated_at'],\n sort: [{ field: 'object_name', order: 'asc' }, { field: 'label', order: 'asc' }],\n grouping: { fields: [{ field: 'object_name', order: 'asc', collapsed: false }] },\n pagination: { pageSize: 100 },\n },\n all_webhooks: {\n type: 'grid',\n name: 'all_webhooks',\n label: 'All',\n data: { provider: 'object', object: 'sys_webhook' },\n columns: ['label', 'object_name', 'url', 'method', 'active', 'updated_at'],\n sort: [{ field: 'label', order: 'asc' }],\n pagination: { pageSize: 50 },\n },\n },\n\n fields: {\n id: Field.text({ label: 'Webhook ID', required: true, readonly: true, group: 'System' }),\n\n name: Field.text({\n label: 'Name',\n required: true,\n maxLength: 100,\n description: 'Unique snake_case name — referenced in logs and audit',\n group: 'Definition',\n }),\n\n label: Field.text({\n label: 'Display Label',\n required: false,\n maxLength: 200,\n group: 'Definition',\n }),\n\n object_name: Field.text({\n label: 'Object',\n required: false,\n maxLength: 100,\n // Object picker (same widget as sys_sharing_rule) instead of a free-text\n // machine name. Falls back to a text input when the widget is unavailable.\n widget: 'object-ref',\n description: 'Short object name whose record events (create/update/delete) fire this webhook',\n group: 'Definition',\n }),\n\n triggers: Field.select(\n ['create', 'update', 'delete'],\n {\n label: 'Triggers',\n required: false,\n // Multi-select instead of a hand-typed comma-separated string. Stored as\n // an array; the auto-enqueuer parser also tolerates the legacy\n // comma-separated / JSON-string forms so existing rows keep working.\n multiple: true,\n description: 'Record events that fire this webhook',\n group: 'Definition',\n },\n ),\n\n url: Field.text({\n label: 'Target URL',\n required: true,\n maxLength: 2048,\n description: 'External endpoint that receives the POST',\n group: 'Definition',\n }),\n\n method: Field.select(\n ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'],\n {\n label: 'HTTP Method',\n required: true,\n // Select instead of free text. Option values are lowercased by the\n // Field.select helper (get/post/…); the auto-enqueuer upper-cases the\n // resolved method before delivery, so existing 'POST' rows and the\n // lowercase option values both normalise correctly.\n defaultValue: 'post',\n description: 'HTTP method used for the callback request',\n group: 'Definition',\n },\n ),\n\n description: Field.textarea({ label: 'Description', required: false, group: 'Definition' }),\n\n active: Field.boolean({\n label: 'Active',\n required: true,\n defaultValue: true,\n description: 'Inactive webhooks are skipped by the dispatcher',\n group: 'Definition',\n }),\n\n definition_json: Field.textarea({\n label: 'Definition',\n required: true,\n description: 'Serialised Webhook JSON (see @objectstack/spec/automation/webhook) — full headers/auth/retry/payload config',\n group: 'Definition',\n }),\n\n // ── Provenance (#3461 — record-authoritative seed-not-clobber) ──\n // Mirrors sys_sharing_rule (#2909). Both columns are `readonly`: the\n // engine strips them from non-system payloads (forge/clear-proof), while\n // bootstrapDeclaredWebhooks and the provenance stamp hook write with\n // isSystem. Deliberately NOT a write gate: webhooks are a first-class admin\n // authoring/tuning surface — admins may edit or deactivate a package row;\n // the seeder simply stops overwriting it once `customized` is stamped.\n managed_by: Field.select(\n ['platform', 'package', 'admin'],\n {\n label: 'Managed By',\n required: false,\n readonly: true,\n defaultValue: 'admin',\n description:\n 'Record provenance: platform = framework built-in / package = app/package-declared ' +\n '(boot-seeded from defineStack webhooks) / admin = created in Setup.',\n group: 'System',\n },\n ),\n\n customized: Field.boolean({\n label: 'Customized',\n required: false,\n readonly: true,\n defaultValue: false,\n description:\n 'Set when an admin edits a package-declared webhook; boot seeding will no longer ' +\n 'overwrite the row (a deactivated noisy webhook survives redeploys). Meaningless on admin rows.',\n group: 'System',\n }),\n\n created_at: Field.datetime({\n label: 'Created At',\n required: true,\n defaultValue: 'NOW()',\n readonly: true,\n group: 'System',\n }),\n\n updated_at: Field.datetime({ label: 'Updated At', required: false, group: 'System' }),\n },\n\n indexes: [\n { fields: ['name'], unique: true },\n { fields: ['object_name'] },\n { fields: ['active', 'object_name'] },\n ],\n});\n"]}