@vxil/config 0.5.0 → 0.6.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/dist/index.d.ts +33 -0
- package/package.json +2 -2
- package/src/index.ts +34 -4
package/dist/index.d.ts
CHANGED
|
@@ -106,6 +106,26 @@ export interface CollectionDef {
|
|
|
106
106
|
* session.revoked — auth.session.revoked { user_id, session_id, reason }
|
|
107
107
|
* signin.failure — auth.signin.failure { email_hash | user_id, reason } */
|
|
108
108
|
export type AuthHookEvent = 'user.created' | 'session.created' | 'session.revoked' | 'signin.failure';
|
|
109
|
+
/** The opt-in re-delivery of a platform-delivered trigger (F33, 2026-09-25).
|
|
110
|
+
* DEFAULT OFF: the platform acknowledges every delivery with a 200 whatever
|
|
111
|
+
* the handler returned — an application error is observed (`functions.run.failed`),
|
|
112
|
+
* never re-delivered. With `retry` set on a `queue` / `webhook` / `cmsHook` /
|
|
113
|
+
* `authHook` trigger, a non-2xx answer of the handler is handed back to the
|
|
114
|
+
* jobs retry ladder instead (60 s, 120 s, … backoff) and the last failed
|
|
115
|
+
* attempt dead-letters the run (`job.dead_lettered`, replayable from the
|
|
116
|
+
* Jobs page). Each attempt is a billed invocation and carries the SAME
|
|
117
|
+
* `idempotency_key` — dedupe on it. Effective attempts =
|
|
118
|
+
* min(maxAttempts, the project's `jobs.retry.defaultMaxAttempts`, default 5).
|
|
119
|
+
* A handler that partially writes and then fails re-fires its downstream
|
|
120
|
+
* events on EVERY attempt, so the chain is a tree (up to maxAttempts children
|
|
121
|
+
* per hop): the causal-depth guard bounds its length (32 hops), not its size —
|
|
122
|
+
* the breaker, the loop guard, the dead-letter quota and the daily share do.
|
|
123
|
+
* Write only once you will return 2xx, or dedupe on idempotency_key. Not accepted on `http` (it returns its
|
|
124
|
+
* real status to its caller) or `cron` (a retry would overlap the next tick). */
|
|
125
|
+
export interface FunctionTriggerRetry {
|
|
126
|
+
/** 1–5 attempts in all (1 = a failed attempt dead-letters at once, no re-delivery) */
|
|
127
|
+
maxAttempts: number;
|
|
128
|
+
}
|
|
109
129
|
/** A function trigger (the §7.3 crossing). cmsHook fires on a CMS write;
|
|
110
130
|
* authHook fires on ONE auth lifecycle event (default `user.created` — the
|
|
111
131
|
* post-signup hook; at-least-once, ~1min fanout latency). */
|
|
@@ -118,6 +138,7 @@ export type FunctionTrigger = {
|
|
|
118
138
|
} | {
|
|
119
139
|
kind: 'queue';
|
|
120
140
|
source: string;
|
|
141
|
+
retry?: FunctionTriggerRetry;
|
|
121
142
|
}
|
|
122
143
|
/** `webhook`: the function is woken by a webhook_subscription fan-out whose
|
|
123
144
|
* target_url is `<edge>/v1/internal/fn/trigger/<name>?tenant=<id>`. That
|
|
@@ -132,6 +153,7 @@ export type FunctionTrigger = {
|
|
|
132
153
|
| {
|
|
133
154
|
kind: 'webhook';
|
|
134
155
|
source: string;
|
|
156
|
+
retry?: FunctionTriggerRetry;
|
|
135
157
|
}
|
|
136
158
|
/** `cmsHook`: fires after a CMS write in `collection`. The platform filters
|
|
137
159
|
* deliveries on the binding (2026-09-19): `beforeCreate` → created only,
|
|
@@ -142,15 +164,26 @@ export type FunctionTrigger = {
|
|
|
142
164
|
kind: 'cmsHook';
|
|
143
165
|
collection: string;
|
|
144
166
|
event: 'beforeCreate' | 'beforeUpdate' | 'beforeWrite';
|
|
167
|
+
retry?: FunctionTriggerRetry;
|
|
145
168
|
} | {
|
|
146
169
|
kind: 'authHook';
|
|
147
170
|
event?: AuthHookEvent;
|
|
171
|
+
retry?: FunctionTriggerRetry;
|
|
148
172
|
};
|
|
149
173
|
/** A deployed tenant function — source in functions/, deployed on `vxil push`. */
|
|
150
174
|
export interface FunctionDef {
|
|
151
175
|
/** path to the ES-module entrypoint, e.g. ./functions/<name>.ts */
|
|
152
176
|
entry: string;
|
|
153
177
|
trigger?: FunctionTrigger;
|
|
178
|
+
/** Further bindings beside `trigger` (2026-09-25): a function is code + a SET
|
|
179
|
+
* of trigger bindings, so one bundle can be reached by several front doors —
|
|
180
|
+
* a webhook AND a cron, an http door AND a cmsHook. `trigger` and `triggers`
|
|
181
|
+
* may both be present; the deploy carries them in that order as
|
|
182
|
+
* `bindings[]`, at most 8 in all (the CLI refuses a 9th before the wire).
|
|
183
|
+
* Every binding lands the same isolate; only the envelope's `trigger` /
|
|
184
|
+
* `payload` differ. Each platform-delivered binding is billed per
|
|
185
|
+
* invocation and bounded by the loop guard and the breaker. */
|
|
186
|
+
triggers?: FunctionTrigger[];
|
|
154
187
|
/** clamped by DENY_FUNCTION_SCOPES at deploy (admin, wildcard, features:write,
|
|
155
188
|
* functions:write, secrets:write rejected; payments:write / notifications:send /
|
|
156
189
|
* users:* allowed as owner-granted business scopes). */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vxil/config",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Typed vxil.config.ts authoring for the vxil backend platform — defineConfig, feature and cms field definitions (published for @vxil/cli).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://vxil.com",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"src"
|
|
23
23
|
],
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@vxil/feature-configs": "0.
|
|
25
|
+
"@vxil/feature-configs": "0.6.0"
|
|
26
26
|
},
|
|
27
27
|
"publishConfig": {
|
|
28
28
|
"access": "public"
|
package/src/index.ts
CHANGED
|
@@ -130,13 +130,34 @@ export interface CollectionDef {
|
|
|
130
130
|
* signin.failure — auth.signin.failure { email_hash | user_id, reason } */
|
|
131
131
|
export type AuthHookEvent = 'user.created' | 'session.created' | 'session.revoked' | 'signin.failure';
|
|
132
132
|
|
|
133
|
+
/** The opt-in re-delivery of a platform-delivered trigger (F33, 2026-09-25).
|
|
134
|
+
* DEFAULT OFF: the platform acknowledges every delivery with a 200 whatever
|
|
135
|
+
* the handler returned — an application error is observed (`functions.run.failed`),
|
|
136
|
+
* never re-delivered. With `retry` set on a `queue` / `webhook` / `cmsHook` /
|
|
137
|
+
* `authHook` trigger, a non-2xx answer of the handler is handed back to the
|
|
138
|
+
* jobs retry ladder instead (60 s, 120 s, … backoff) and the last failed
|
|
139
|
+
* attempt dead-letters the run (`job.dead_lettered`, replayable from the
|
|
140
|
+
* Jobs page). Each attempt is a billed invocation and carries the SAME
|
|
141
|
+
* `idempotency_key` — dedupe on it. Effective attempts =
|
|
142
|
+
* min(maxAttempts, the project's `jobs.retry.defaultMaxAttempts`, default 5).
|
|
143
|
+
* A handler that partially writes and then fails re-fires its downstream
|
|
144
|
+
* events on EVERY attempt, so the chain is a tree (up to maxAttempts children
|
|
145
|
+
* per hop): the causal-depth guard bounds its length (32 hops), not its size —
|
|
146
|
+
* the breaker, the loop guard, the dead-letter quota and the daily share do.
|
|
147
|
+
* Write only once you will return 2xx, or dedupe on idempotency_key. Not accepted on `http` (it returns its
|
|
148
|
+
* real status to its caller) or `cron` (a retry would overlap the next tick). */
|
|
149
|
+
export interface FunctionTriggerRetry {
|
|
150
|
+
/** 1–5 attempts in all (1 = a failed attempt dead-letters at once, no re-delivery) */
|
|
151
|
+
maxAttempts: number;
|
|
152
|
+
}
|
|
153
|
+
|
|
133
154
|
/** A function trigger (the §7.3 crossing). cmsHook fires on a CMS write;
|
|
134
155
|
* authHook fires on ONE auth lifecycle event (default `user.created` — the
|
|
135
156
|
* post-signup hook; at-least-once, ~1min fanout latency). */
|
|
136
157
|
export type FunctionTrigger =
|
|
137
158
|
| { kind: 'http'; path?: string }
|
|
138
159
|
| { kind: 'cron'; schedule: string }
|
|
139
|
-
| { kind: 'queue'; source: string }
|
|
160
|
+
| { kind: 'queue'; source: string; retry?: FunctionTriggerRetry }
|
|
140
161
|
/** `webhook`: the function is woken by a webhook_subscription fan-out whose
|
|
141
162
|
* target_url is `<edge>/v1/internal/fn/trigger/<name>?tenant=<id>`. That
|
|
142
163
|
* subscription is AUTO-WIRED on deploy (2026-09-19): the platform reconciles
|
|
@@ -147,20 +168,29 @@ export type FunctionTrigger =
|
|
|
147
168
|
* also enforced at delivery: a non-matching event is ACK-200 skipped.
|
|
148
169
|
* Declaring the binding is what opts the function into event delivery; a
|
|
149
170
|
* receiver that declares only `cron` keeps the older cron+{} wake. */
|
|
150
|
-
| { kind: 'webhook'; source: string }
|
|
171
|
+
| { kind: 'webhook'; source: string; retry?: FunctionTriggerRetry }
|
|
151
172
|
/** `cmsHook`: fires after a CMS write in `collection`. The platform filters
|
|
152
173
|
* deliveries on the binding (2026-09-19): `beforeCreate` → created only,
|
|
153
174
|
* `beforeUpdate` → updated only, `beforeWrite` → created|updated; a write to
|
|
154
175
|
* another collection never wakes the function. Deleted/bulk events are not
|
|
155
176
|
* delivered to a cmsHook binding. */
|
|
156
|
-
| { kind: 'cmsHook'; collection: string; event: 'beforeCreate' | 'beforeUpdate' | 'beforeWrite' }
|
|
157
|
-
| { kind: 'authHook'; event?: AuthHookEvent };
|
|
177
|
+
| { kind: 'cmsHook'; collection: string; event: 'beforeCreate' | 'beforeUpdate' | 'beforeWrite'; retry?: FunctionTriggerRetry }
|
|
178
|
+
| { kind: 'authHook'; event?: AuthHookEvent; retry?: FunctionTriggerRetry };
|
|
158
179
|
|
|
159
180
|
/** A deployed tenant function — source in functions/, deployed on `vxil push`. */
|
|
160
181
|
export interface FunctionDef {
|
|
161
182
|
/** path to the ES-module entrypoint, e.g. ./functions/<name>.ts */
|
|
162
183
|
entry: string;
|
|
163
184
|
trigger?: FunctionTrigger;
|
|
185
|
+
/** Further bindings beside `trigger` (2026-09-25): a function is code + a SET
|
|
186
|
+
* of trigger bindings, so one bundle can be reached by several front doors —
|
|
187
|
+
* a webhook AND a cron, an http door AND a cmsHook. `trigger` and `triggers`
|
|
188
|
+
* may both be present; the deploy carries them in that order as
|
|
189
|
+
* `bindings[]`, at most 8 in all (the CLI refuses a 9th before the wire).
|
|
190
|
+
* Every binding lands the same isolate; only the envelope's `trigger` /
|
|
191
|
+
* `payload` differ. Each platform-delivered binding is billed per
|
|
192
|
+
* invocation and bounded by the loop guard and the breaker. */
|
|
193
|
+
triggers?: FunctionTrigger[];
|
|
164
194
|
/** clamped by DENY_FUNCTION_SCOPES at deploy (admin, wildcard, features:write,
|
|
165
195
|
* functions:write, secrets:write rejected; payments:write / notifications:send /
|
|
166
196
|
* users:* allowed as owner-granted business scopes). */
|