@fabrika/app 0.9.0-dev.1 → 0.9.0-dev.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +27 -26
- package/skill/SKILL.md +1 -1
- package/skill/references/app-setup.md +8 -8
- package/src/dev/changes.ts +5 -43
- package/src/dev/contract-digest.ts +17 -0
- package/src/dev/index.ts +1 -1
- package/src/dev/launcher.ts +69 -22
- package/src/dev/wire.ts +2 -1
- package/types/src/agent-skill.d.ts +29 -0
- package/types/src/build.d.ts +11 -0
- package/types/src/bun.d.ts +66 -0
- package/types/src/client/caller.d.ts +19 -0
- package/types/src/client/contract.d.ts +131 -0
- package/types/src/client/error-reporting.d.ts +66 -0
- package/types/src/client/index.d.ts +4 -0
- package/types/src/client/rpc.d.ts +14 -0
- package/types/src/client/share.d.ts +2 -0
- package/types/src/client/transport.d.ts +42 -0
- package/types/src/cloudflare.d.ts +49 -0
- package/types/src/contract/artifact-schema.d.ts +8 -0
- package/types/src/contract/attachment.d.ts +41 -0
- package/types/src/contract/build.d.ts +12 -0
- package/types/src/contract/compile.d.ts +11 -0
- package/types/src/contract/connect.d.ts +51 -0
- package/types/src/contract/context.d.ts +501 -0
- package/types/src/contract/declaration.d.ts +303 -0
- package/types/src/contract/defaults.d.ts +208 -0
- package/types/src/contract/define.d.ts +359 -0
- package/types/src/contract/file.d.ts +44 -0
- package/types/src/contract/group.d.ts +274 -0
- package/types/src/contract/handled.d.ts +18 -0
- package/types/src/contract/index.d.ts +19 -0
- package/types/src/contract/kit.d.ts +210 -0
- package/types/src/contract/platform.d.ts +9 -0
- package/types/src/contract/problems.d.ts +14 -0
- package/types/src/contract/redirect.d.ts +25 -0
- package/types/src/contract/schema-from-shape.d.ts +10 -0
- package/types/src/contract/schema-shape.d.ts +5 -0
- package/types/src/contract/snapshot-source.d.ts +15 -0
- package/types/src/contract/token.d.ts +58 -0
- package/types/src/contract/vocabulary.d.ts +30 -0
- package/types/src/contract/webhook-binding.d.ts +24 -0
- package/types/src/contract/webhook-scheme.d.ts +23 -0
- package/types/src/dev/changes.d.ts +7 -0
- package/types/src/dev/contract-digest.d.ts +1 -0
- package/types/src/dev/index.d.ts +2 -0
- package/types/src/dev/launcher.d.ts +32 -0
- package/types/src/dev/output.d.ts +22 -0
- package/types/src/dev/wire.d.ts +122 -0
- package/types/src/disk-assets.d.ts +3 -0
- package/types/src/errors.d.ts +46 -0
- package/types/src/fetch.d.ts +7 -0
- package/types/src/files/archive.d.ts +26 -0
- package/types/src/files/clamscan.d.ts +32 -0
- package/types/src/files/handle.d.ts +106 -0
- package/types/src/files/kinds.d.ts +105 -0
- package/types/src/files/scan.d.ts +80 -0
- package/types/src/files/sniff.d.ts +7 -0
- package/types/src/files/streams.d.ts +17 -0
- package/types/src/files/treatment.d.ts +18 -0
- package/types/src/from-row.d.ts +20 -0
- package/types/src/honeypot.d.ts +2 -0
- package/types/src/implement/anonymous.d.ts +26 -0
- package/types/src/implement/attachment.d.ts +14 -0
- package/types/src/implement/boot.d.ts +109 -0
- package/types/src/implement/bounded.d.ts +22 -0
- package/types/src/implement/browser-config.d.ts +19 -0
- package/types/src/implement/capability.d.ts +140 -0
- package/types/src/implement/challenge.d.ts +75 -0
- package/types/src/implement/client-address.d.ts +11 -0
- package/types/src/implement/connect.d.ts +67 -0
- package/types/src/implement/crashes.d.ts +31 -0
- package/types/src/implement/dispatch.d.ts +218 -0
- package/types/src/implement/egress.d.ts +14 -0
- package/types/src/implement/environment.d.ts +14 -0
- package/types/src/implement/failures.d.ts +34 -0
- package/types/src/implement/faults.d.ts +44 -0
- package/types/src/implement/headers.d.ts +7 -0
- package/types/src/implement/implement.d.ts +58 -0
- package/types/src/implement/index.d.ts +24 -0
- package/types/src/implement/invocation.d.ts +120 -0
- package/types/src/implement/membership.d.ts +201 -0
- package/types/src/implement/multipart.d.ts +36 -0
- package/types/src/implement/params.d.ts +7 -0
- package/types/src/implement/principal.d.ts +52 -0
- package/types/src/implement/project.d.ts +11 -0
- package/types/src/implement/public.d.ts +61 -0
- package/types/src/implement/serve.d.ts +25 -0
- package/types/src/implement/tokens.d.ts +49 -0
- package/types/src/implement/types.d.ts +243 -0
- package/types/src/implement/urls.d.ts +15 -0
- package/types/src/implement/verifiers.d.ts +19 -0
- package/types/src/implement/webhook.d.ts +55 -0
- package/types/src/implement/workload.d.ts +56 -0
- package/types/src/implement/xlsx.d.ts +6 -0
- package/types/src/index.d.ts +12 -0
- package/types/src/jobs/exception.d.ts +40 -0
- package/types/src/jobs/mail.d.ts +67 -0
- package/types/src/jobs/report.d.ts +56 -0
- package/types/src/jobs/runner.d.ts +145 -0
- package/types/src/jobs/schedule.d.ts +15 -0
- package/types/src/jobs/scrub.d.ts +12 -0
- package/types/src/jobs/types.d.ts +92 -0
- package/types/src/react/caller.d.ts +30 -0
- package/types/src/react/errors.d.ts +40 -0
- package/types/src/react/hooks.d.ts +110 -0
- package/types/src/react/index.d.ts +5 -0
- package/types/src/react/provider.d.ts +58 -0
- package/types/src/react/store.d.ts +68 -0
- package/types/src/react/testing.d.ts +28 -0
- package/types/src/react/types.d.ts +33 -0
- package/types/src/rpc/builder.d.ts +52 -0
- package/types/src/rpc/contract.d.ts +23 -0
- package/types/src/rpc/dispatcher.d.ts +11 -0
- package/types/src/rpc/types.d.ts +62 -0
- package/types/src/service/define.d.ts +42 -0
- package/types/src/service/index.d.ts +3 -0
- package/types/src/service/serve.d.ts +28 -0
- package/types/src/standard-schema.d.ts +55 -0
- package/types/src/testing/caller.d.ts +95 -0
- package/types/src/testing/challenge.d.ts +11 -0
- package/types/src/testing/dev.d.ts +97 -0
- package/types/src/testing/endpoint-access.d.ts +99 -0
- package/types/src/testing/index.d.ts +12 -0
- package/types/src/testing/isolation.d.ts +3 -0
- package/types/src/testing/kit.d.ts +182 -0
- package/types/src/testing/membership.d.ts +132 -0
- package/types/src/testing/policy-isolation.d.ts +113 -0
- package/types/src/testing/preload.d.ts +1 -0
- package/types/src/testing/proxy.d.ts +40 -0
- package/types/src/testing/runner.d.ts +8 -0
- package/types/src/testing/sample-file.d.ts +5 -0
- package/types/src/testing/status.d.ts +4 -0
- package/types/src/undumpable.d.ts +5 -0
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
import type { CspSource, MailTemplate, RpcCaller } from '@fabrika/auth-core';
|
|
2
|
+
export interface ContractDeclaration<S> {
|
|
3
|
+
readonly app: string;
|
|
4
|
+
readonly dimensions: Readonly<Record<string, DimensionDeclaration>>;
|
|
5
|
+
readonly actions: Readonly<Record<string, string>>;
|
|
6
|
+
readonly roles: Readonly<Record<string, RoleDeclaration>>;
|
|
7
|
+
readonly mounts: Readonly<Record<string, MountDeclaration<S>>>;
|
|
8
|
+
readonly files: Readonly<Record<string, FileKindDeclaration>>;
|
|
9
|
+
readonly jobs: Readonly<Record<string, CronDeclaration>>;
|
|
10
|
+
readonly exports: Readonly<Record<string, ExportDeclaration<S>>>;
|
|
11
|
+
readonly imports: Readonly<Record<string, ImportDeclaration>>;
|
|
12
|
+
readonly csp: CspDeclaration;
|
|
13
|
+
/** The token purposes of `defineApp`'s options, by purpose; absent without any. */
|
|
14
|
+
readonly tokens?: Readonly<Record<string, TokenDeclaration<S>>>;
|
|
15
|
+
/** A language IAM speaks; `buildArtifact` refuses another value. */
|
|
16
|
+
readonly locale?: string;
|
|
17
|
+
readonly displayName?: string;
|
|
18
|
+
/** Message kind → locale → template; `buildArtifact` refuses an unknown kind or locale and a bad template. */
|
|
19
|
+
readonly mail?: Readonly<Record<string, Readonly<Record<string, MailTemplate>>>>;
|
|
20
|
+
/** The actions that manage and list the application's own people. */
|
|
21
|
+
readonly members?: {
|
|
22
|
+
readonly manage: string;
|
|
23
|
+
readonly list: string;
|
|
24
|
+
};
|
|
25
|
+
/** `'labels'` only; `buildArtifact` refuses another value, and refuses it without `members`. */
|
|
26
|
+
readonly directory?: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* The keys of the object `defineContract`'s callback returns that are sections, not mounts. Every other key is a
|
|
30
|
+
* mount. A reader of source splits the object the same way.
|
|
31
|
+
*/
|
|
32
|
+
export declare const SURFACE_SECTIONS: readonly ["files", "jobs", "exports", "imports", "csp", "tokens"];
|
|
33
|
+
export type SurfaceSection = (typeof SURFACE_SECTIONS)[number];
|
|
34
|
+
/**
|
|
35
|
+
* The option fields each builder takes, and the fields it sets itself. A builder copies only its option fields and
|
|
36
|
+
* records every other key of its options in `unknownOptions`, so an option can never replace what the builder set;
|
|
37
|
+
* `buildArtifact` refuses a non-empty `unknownOptions`. A reader of source fills it the same way.
|
|
38
|
+
*/
|
|
39
|
+
export type Builder = 'procedure' | 'rpc' | 'link' | 'spa' | 'webhook' | 'fileKind' | 'cron' | 'export' | 'attachment';
|
|
40
|
+
export interface BuilderFields {
|
|
41
|
+
readonly options: readonly string[];
|
|
42
|
+
readonly owned: readonly string[];
|
|
43
|
+
}
|
|
44
|
+
export declare const BUILDER_FIELDS: Readonly<Record<Builder, BuilderFields>>;
|
|
45
|
+
/** The keys of `options` that are not `builder`'s option fields. */
|
|
46
|
+
export declare function unknownOptions(options: object, builder: Builder): string[];
|
|
47
|
+
/**
|
|
48
|
+
* The off-road fields a site of the staged kit declares beside its builder's options. The kit copies them into
|
|
49
|
+
* `declared`; `buildArtifact` checks which of them the site may carry.
|
|
50
|
+
*/
|
|
51
|
+
export declare const DECLARED_FIELDS: readonly ["sql", "unscoped", "connect", "issues", "mailer", "kicks", "binds", "signs", "egress"];
|
|
52
|
+
/** The keys of a kit site's `options` that are neither `builder`'s option fields nor a declared field. */
|
|
53
|
+
export declare function kitUnknownOptions(options: object, builder: Builder): string[];
|
|
54
|
+
/**
|
|
55
|
+
* The reach a site of the staged kit declares, as written (`sql`, `unscoped`, `connect`, `issues`, `mailer`, `kicks`, `binds`, `signs`, `egress`): only the fields
|
|
56
|
+
* its options carry. Unchecked here: the static reader copies what the source holds, and `buildArtifact` parses it.
|
|
57
|
+
*/
|
|
58
|
+
export interface DeclaredDeclaration {
|
|
59
|
+
readonly sql?: unknown;
|
|
60
|
+
readonly unscoped?: unknown;
|
|
61
|
+
readonly connect?: unknown;
|
|
62
|
+
readonly issues?: unknown;
|
|
63
|
+
readonly mailer?: unknown;
|
|
64
|
+
readonly kicks?: unknown;
|
|
65
|
+
readonly binds?: unknown;
|
|
66
|
+
readonly signs?: unknown;
|
|
67
|
+
readonly egress?: unknown;
|
|
68
|
+
}
|
|
69
|
+
/** The declared fields of a kit site's options, each one only when the options carry it. */
|
|
70
|
+
export declare function declaredOf(options: DeclaredDeclaration): DeclaredDeclaration;
|
|
71
|
+
/** One token purpose as written: its claims schema and its longest lifetime; `buildArtifact` checks both. */
|
|
72
|
+
export interface TokenDeclaration<S> {
|
|
73
|
+
readonly claims: S;
|
|
74
|
+
readonly maxDays: unknown;
|
|
75
|
+
}
|
|
76
|
+
/** Option keys outside the builder's option fields; `buildArtifact` refuses any. */
|
|
77
|
+
interface OptionsRecord {
|
|
78
|
+
readonly unknownOptions?: readonly string[];
|
|
79
|
+
}
|
|
80
|
+
export interface DimensionDeclaration {
|
|
81
|
+
readonly in?: string;
|
|
82
|
+
readonly creator?: string;
|
|
83
|
+
readonly members?: {
|
|
84
|
+
readonly manage: string;
|
|
85
|
+
readonly list: string;
|
|
86
|
+
};
|
|
87
|
+
/** `'labels'` only; `buildArtifact` refuses another value. */
|
|
88
|
+
readonly directory?: string;
|
|
89
|
+
}
|
|
90
|
+
export interface RoleDeclaration {
|
|
91
|
+
readonly grants: readonly string[];
|
|
92
|
+
readonly member?: {
|
|
93
|
+
readonly scope: string;
|
|
94
|
+
readonly assignableBy: readonly string[];
|
|
95
|
+
};
|
|
96
|
+
/** `true` only; `buildArtifact` refuses another value, and refuses it on a role without `member`. */
|
|
97
|
+
readonly external?: boolean;
|
|
98
|
+
}
|
|
99
|
+
export type AccessDeclaration = {
|
|
100
|
+
readonly member: true;
|
|
101
|
+
} | {
|
|
102
|
+
readonly action: string;
|
|
103
|
+
readonly over: string;
|
|
104
|
+
} | {
|
|
105
|
+
readonly action: string;
|
|
106
|
+
readonly in: string;
|
|
107
|
+
readonly from: string;
|
|
108
|
+
} | {
|
|
109
|
+
readonly action: string;
|
|
110
|
+
readonly on: string;
|
|
111
|
+
readonly from: string;
|
|
112
|
+
} | {
|
|
113
|
+
readonly action: string;
|
|
114
|
+
readonly creates: string;
|
|
115
|
+
} | {
|
|
116
|
+
readonly action: string;
|
|
117
|
+
readonly app: true;
|
|
118
|
+
} | {
|
|
119
|
+
readonly capabilities: Readonly<Record<string, CapabilityDeclaration>>;
|
|
120
|
+
}
|
|
121
|
+
/** Anyone calls it; its handler runs as the procedure's own workload, with its top-level `actions`. RPC only. */
|
|
122
|
+
| {
|
|
123
|
+
readonly public: true;
|
|
124
|
+
};
|
|
125
|
+
/** One of several capabilities: an action in a dimension, listed `over` it or read from an input field. */
|
|
126
|
+
export type CapabilityDeclaration = {
|
|
127
|
+
readonly action: string;
|
|
128
|
+
readonly over: string;
|
|
129
|
+
} | {
|
|
130
|
+
readonly action: string;
|
|
131
|
+
readonly in: string;
|
|
132
|
+
readonly from: string;
|
|
133
|
+
} | {
|
|
134
|
+
readonly action: string;
|
|
135
|
+
readonly on: string;
|
|
136
|
+
readonly from: string;
|
|
137
|
+
};
|
|
138
|
+
/**
|
|
139
|
+
* An export procedure's access: an action in a dimension, never `member`, because the consumer's key holds exactly the
|
|
140
|
+
* actions, never `app`, because a v1 export declares one dimension, and never several capabilities.
|
|
141
|
+
*/
|
|
142
|
+
export type ExportAccessDeclaration = Exclude<AccessDeclaration, {
|
|
143
|
+
readonly member: true;
|
|
144
|
+
} | {
|
|
145
|
+
readonly app: true;
|
|
146
|
+
} | {
|
|
147
|
+
readonly capabilities: Readonly<Record<string, CapabilityDeclaration>>;
|
|
148
|
+
} | {
|
|
149
|
+
readonly public: true;
|
|
150
|
+
}>;
|
|
151
|
+
export interface LinkAccessDeclaration {
|
|
152
|
+
readonly action: string;
|
|
153
|
+
}
|
|
154
|
+
/** `{ public: true }` serves the SPA to anyone, with no session: an anonymous `public-spa` row. */
|
|
155
|
+
export type SpaAccessDeclaration = {
|
|
156
|
+
readonly member: true;
|
|
157
|
+
} | {
|
|
158
|
+
readonly action: string;
|
|
159
|
+
readonly over: string;
|
|
160
|
+
} | {
|
|
161
|
+
readonly action: string;
|
|
162
|
+
readonly app: true;
|
|
163
|
+
} | {
|
|
164
|
+
readonly public: true;
|
|
165
|
+
};
|
|
166
|
+
export type ProcedureType = 'query' | 'mutation';
|
|
167
|
+
export interface ProcedureDeclaration<S, Access = AccessDeclaration> extends OptionsRecord {
|
|
168
|
+
readonly '~kind': 'procedure';
|
|
169
|
+
readonly type: ProcedureType;
|
|
170
|
+
/** `null` when the procedure takes no input. */
|
|
171
|
+
readonly input: S | null;
|
|
172
|
+
readonly output: S;
|
|
173
|
+
readonly access: Access;
|
|
174
|
+
/** A public procedure's workload actions, as written: all its handler holds. Required there, refused elsewhere. */
|
|
175
|
+
readonly actions?: unknown;
|
|
176
|
+
/** `{ origins?, rate?, challenge? }`, as written; `buildArtifact` merges it into the defaults. */
|
|
177
|
+
readonly admission?: unknown;
|
|
178
|
+
/** `{ maxBytes?, timeoutMs? }`, as written; `buildArtifact` checks each against its ceiling. */
|
|
179
|
+
readonly limits?: unknown;
|
|
180
|
+
/** `{ method?, query?, body?, cache? }`, as written; `buildArtifact` checks the HTTP shape's rules. */
|
|
181
|
+
readonly http?: unknown;
|
|
182
|
+
/** What a procedure of the staged kit declares off the paved road; a `defineContract` procedure has none. */
|
|
183
|
+
readonly declared?: unknown;
|
|
184
|
+
/**
|
|
185
|
+
* Set by `describeContract` when the output is an `attachment()`: the procedure answers a file, and its described
|
|
186
|
+
* `output` is the array of rows the handler returns.
|
|
187
|
+
*/
|
|
188
|
+
readonly attachment?: AttachmentDeclaration;
|
|
189
|
+
/** Set by `describeContract` when the output is a `redirect()`: the procedure answers a redirect to `{ to }`. */
|
|
190
|
+
readonly redirect?: RedirectDeclaration;
|
|
191
|
+
}
|
|
192
|
+
/** The origins a `redirect()` output lists, as written; `buildArtifact` checks each. */
|
|
193
|
+
export interface RedirectDeclaration {
|
|
194
|
+
readonly origins: readonly string[];
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* The file an `attachment()` output declares beside its row schema, as written; `buildArtifact` checks each field and
|
|
198
|
+
* applies the default `maxRows`.
|
|
199
|
+
*/
|
|
200
|
+
export interface AttachmentDeclaration extends OptionsRecord {
|
|
201
|
+
readonly format: string;
|
|
202
|
+
readonly filename: string;
|
|
203
|
+
readonly maxBytes: number;
|
|
204
|
+
readonly maxRows?: number;
|
|
205
|
+
}
|
|
206
|
+
/** Procedures by name; a nested object groups them, and the path joins the names with `.`. */
|
|
207
|
+
export interface ProcedureTreeDeclaration<S, Access = AccessDeclaration> {
|
|
208
|
+
readonly [name: string]: ProcedureDeclaration<S, Access> | ProcedureTreeDeclaration<S, Access>;
|
|
209
|
+
}
|
|
210
|
+
export type MountDeclaration<S> = RpcMountDeclaration<S> | LinkMountDeclaration<S> | SpaMountDeclaration | HealthMountDeclaration | WebhookMountDeclaration<S>;
|
|
211
|
+
export interface RpcMountDeclaration<S> extends OptionsRecord {
|
|
212
|
+
readonly kind: 'rpc';
|
|
213
|
+
readonly prefix: string;
|
|
214
|
+
/** The callers of its credentialed procedures; none when every procedure is public. */
|
|
215
|
+
readonly callers: readonly RpcCaller[];
|
|
216
|
+
readonly procedures: ProcedureTreeDeclaration<S>;
|
|
217
|
+
/** The kit's `c.rpc` options, as written; `buildArtifact` takes `'backward'` and `'unchecked'`. */
|
|
218
|
+
readonly compatibility?: unknown;
|
|
219
|
+
}
|
|
220
|
+
export interface LinkMountDeclaration<S> extends OptionsRecord {
|
|
221
|
+
readonly kind: 'link';
|
|
222
|
+
readonly prefix: string;
|
|
223
|
+
readonly spa: string;
|
|
224
|
+
readonly dimension: string;
|
|
225
|
+
readonly grants: readonly string[];
|
|
226
|
+
readonly issuedBy: string;
|
|
227
|
+
readonly maxDays: number;
|
|
228
|
+
readonly procedures: ProcedureTreeDeclaration<S, LinkAccessDeclaration>;
|
|
229
|
+
}
|
|
230
|
+
export interface SpaMountDeclaration extends OptionsRecord {
|
|
231
|
+
readonly kind: 'spa';
|
|
232
|
+
readonly prefix: string;
|
|
233
|
+
readonly dir: string;
|
|
234
|
+
readonly access: SpaAccessDeclaration;
|
|
235
|
+
/** Application variables whose values the mount's pages read from `<prefix>/__fabrika-config.json`. */
|
|
236
|
+
readonly browserConfig?: readonly string[];
|
|
237
|
+
}
|
|
238
|
+
export interface HealthMountDeclaration {
|
|
239
|
+
readonly kind: 'health';
|
|
240
|
+
readonly path: string;
|
|
241
|
+
}
|
|
242
|
+
export interface WebhookMountDeclaration<S> extends OptionsRecord {
|
|
243
|
+
readonly kind: 'webhook';
|
|
244
|
+
readonly path: string;
|
|
245
|
+
/** A preset or a verifier shape, as written; `buildArtifact` checks it. */
|
|
246
|
+
readonly scheme: unknown;
|
|
247
|
+
/** A dimension, or `app` for the whole application. */
|
|
248
|
+
readonly boundTo: string;
|
|
249
|
+
readonly actions: readonly string[];
|
|
250
|
+
readonly input: S;
|
|
251
|
+
/** `{ maxBytes?, timeoutMs? }`, as written; `buildArtifact` checks each against its ceiling. */
|
|
252
|
+
readonly limits?: unknown;
|
|
253
|
+
/** What a webhook of the staged kit declares off the paved road. */
|
|
254
|
+
readonly declared?: unknown;
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* A file kind (`c.files({ types, maxBytes, scan? })`, no `owner`): a class of stored files a table's file column holds.
|
|
258
|
+
* It has no owner, no actions and no endpoint.
|
|
259
|
+
*/
|
|
260
|
+
export interface FileKindDeclaration extends OptionsRecord {
|
|
261
|
+
readonly kind: 'file-kind';
|
|
262
|
+
readonly types: readonly string[];
|
|
263
|
+
readonly maxBytes: number;
|
|
264
|
+
/** Every file waits `quarantined` until the scan gives it a clean verdict; a byte consumer answers 409 until then. */
|
|
265
|
+
readonly scan?: boolean;
|
|
266
|
+
}
|
|
267
|
+
export interface CronDeclaration extends OptionsRecord {
|
|
268
|
+
readonly kind: 'cron';
|
|
269
|
+
readonly schedule: string;
|
|
270
|
+
readonly actions: readonly string[];
|
|
271
|
+
/** `{ timeoutMs? }`, as written; `buildArtifact` checks it against its ceiling. */
|
|
272
|
+
readonly limits?: unknown;
|
|
273
|
+
readonly retries?: number;
|
|
274
|
+
/** What a job of the staged kit declares off the paved road. */
|
|
275
|
+
readonly declared?: unknown;
|
|
276
|
+
}
|
|
277
|
+
export interface ExportDeclaration<S> extends OptionsRecord {
|
|
278
|
+
readonly kind: 'export';
|
|
279
|
+
readonly version: number;
|
|
280
|
+
readonly consumers: readonly string[];
|
|
281
|
+
readonly audience: string;
|
|
282
|
+
readonly procedures: ProcedureTreeDeclaration<S, ExportAccessDeclaration>;
|
|
283
|
+
}
|
|
284
|
+
export interface ImportDeclaration {
|
|
285
|
+
readonly app: string;
|
|
286
|
+
readonly export: string;
|
|
287
|
+
readonly version: number;
|
|
288
|
+
readonly digest: string;
|
|
289
|
+
readonly procedures: readonly string[];
|
|
290
|
+
readonly usedBy: readonly string[];
|
|
291
|
+
readonly timeoutMs?: number;
|
|
292
|
+
}
|
|
293
|
+
export interface CspDeclaration {
|
|
294
|
+
readonly connectSrc?: readonly CspSource[];
|
|
295
|
+
readonly imgSrc?: readonly CspSource[];
|
|
296
|
+
readonly frameAncestors?: readonly CspSource[];
|
|
297
|
+
readonly scriptSrc?: readonly CspSource[];
|
|
298
|
+
readonly frameSrc?: readonly CspSource[];
|
|
299
|
+
readonly styleSrc?: readonly CspSource[];
|
|
300
|
+
readonly fontSrc?: readonly CspSource[];
|
|
301
|
+
}
|
|
302
|
+
export declare function isProcedure<S, Access>(node: ProcedureDeclaration<S, Access> | ProcedureTreeDeclaration<S, Access>): node is ProcedureDeclaration<S, Access>;
|
|
303
|
+
export {};
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import type { BodyAdmission, ChallengeProvider } from '@fabrika/auth-core';
|
|
2
|
+
export declare const CONTRACT_DEFAULTS: {
|
|
3
|
+
/** A failed job run is not retried unless the job asks for it: a retry repeats work. */
|
|
4
|
+
readonly jobRetries: 0;
|
|
5
|
+
readonly importTimeoutMs: null;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* A procedure's bounds: its body (`maxBytes`, without files) and its handler's time (`timeoutMs`, counted after the last
|
|
9
|
+
* body byte), each with its default and its ceiling, and the most calls a bucket admits per minute.
|
|
10
|
+
*/
|
|
11
|
+
export declare const PROCEDURE_LIMITS: {
|
|
12
|
+
readonly maxBytes: number;
|
|
13
|
+
readonly maxMaxBytes: number;
|
|
14
|
+
readonly timeoutMs: 10000;
|
|
15
|
+
readonly maxTimeoutMs: 60000;
|
|
16
|
+
readonly maxPerMinute: 10000;
|
|
17
|
+
readonly maxBytesPerHour: number;
|
|
18
|
+
/** The body of a procedure with file fields: its default adds each field's files at its kind's `maxBytes`. */
|
|
19
|
+
readonly maxFileBodyBytes: number;
|
|
20
|
+
/** The files one request carries, at most: each field's `.max(n)` together. */
|
|
21
|
+
readonly maxFiles: 20;
|
|
22
|
+
/** The headers of one part of a multipart body, at most. */
|
|
23
|
+
readonly maxPartHeaderBytes: number;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* A procedure with file fields is `multipart/form-data`: its JSON input travels in the first part, named `input`, and
|
|
27
|
+
* each file in a part named after its field. A field of several files sends one part per file, under its name.
|
|
28
|
+
*/
|
|
29
|
+
export declare const FILE_INPUT_PART = "input";
|
|
30
|
+
/**
|
|
31
|
+
* A webhook's bounds: a provider's body, by default the most a procedure without files takes, since providers send
|
|
32
|
+
* whole objects; up to what a procedure with file fields takes, since an inbound e-mail carries its attachments in the
|
|
33
|
+
* body for the handler to `put`; and its handler's time, a procedure's.
|
|
34
|
+
*/
|
|
35
|
+
export declare const WEBHOOK_LIMITS: {
|
|
36
|
+
readonly maxBytes: number;
|
|
37
|
+
readonly maxMaxBytes: number;
|
|
38
|
+
readonly timeoutMs: 10000;
|
|
39
|
+
};
|
|
40
|
+
/** A job attempt's time limit (`limits.timeoutMs`) and its ceiling, which keeps a lease and a timer within a day. */
|
|
41
|
+
export declare const JOB_LIMITS: {
|
|
42
|
+
readonly timeoutMs: number;
|
|
43
|
+
readonly maxTimeoutMs: number;
|
|
44
|
+
};
|
|
45
|
+
/** A public mutation's buckets per minute unless it declares its own: per client and for the endpoint. */
|
|
46
|
+
export declare const PUBLIC_MUTATION_RATE: {
|
|
47
|
+
readonly perClient: 10;
|
|
48
|
+
readonly perEndpoint: 100;
|
|
49
|
+
};
|
|
50
|
+
/** What a widget's `action` may be: at most 32 letters, digits, `_` and `-`, what Turnstile admits, and a path segment. */
|
|
51
|
+
export declare const CHALLENGE_ACTION: RegExp;
|
|
52
|
+
/**
|
|
53
|
+
* The challenge widget's `action` of a public procedure that declares none (`challenge.action`): its endpoint id with
|
|
54
|
+
* `_` for `.`.
|
|
55
|
+
*/
|
|
56
|
+
export declare function challengeAction(endpoint: string): string;
|
|
57
|
+
/** The input field that carries a challenge token; a procedure with a challenge declares it as a string. */
|
|
58
|
+
export declare const CHALLENGE_FIELD = "challengeToken";
|
|
59
|
+
/** A procedure with file fields reads `multipart/form-data`; the proxy admits that type for its row. */
|
|
60
|
+
export { FORM_MULTIPART_TYPE } from '@fabrika/auth-core';
|
|
61
|
+
/**
|
|
62
|
+
* Each challenge provider's fixed browser sources: the origins of its widget's script and frame, and `blob:` for workers
|
|
63
|
+
* when the widget starts its own. ALTCHA's widget is bundled with the page and solves in workers built from `Blob`s.
|
|
64
|
+
*/
|
|
65
|
+
export declare const CHALLENGE_ORIGINS: Readonly<Record<ChallengeProvider, {
|
|
66
|
+
readonly scriptSrc: readonly string[];
|
|
67
|
+
readonly frameSrc: readonly string[];
|
|
68
|
+
readonly workerSrc: readonly string[];
|
|
69
|
+
}>>;
|
|
70
|
+
/**
|
|
71
|
+
* An ALTCHA challenge: PBKDF2/SHA-256 attempts of `cost` iterations each, counted up to a number drawn per challenge
|
|
72
|
+
* between `minCounter` and `maxCounter`, so a browser makes that many attempts, about half of `maxCounter` on average.
|
|
73
|
+
* The draw starts at 1: a solver that knew a higher floor would skip the attempts below it, which the widget makes.
|
|
74
|
+
* `cost` and `maxAgeMs` are the contract's (`challenge.cost`, `challenge.maxAgeMs`), each with its default and its
|
|
75
|
+
* bounds, and together they must leave a slow phone time to solve (`altchaSolvable`). The HMAC key is at least
|
|
76
|
+
* `minKeyLength` characters: every issued challenge publishes a signature a short key could be guessed from. A solved
|
|
77
|
+
* payload is base64 JSON of the challenge and its solution, at most `maxTokenLength` characters.
|
|
78
|
+
*/
|
|
79
|
+
export declare const ALTCHA_LIMITS: {
|
|
80
|
+
readonly algorithm: "PBKDF2/SHA-256";
|
|
81
|
+
readonly cost: 5000;
|
|
82
|
+
readonly minCost: 1000;
|
|
83
|
+
readonly maxCost: 18000;
|
|
84
|
+
readonly minCounter: 1;
|
|
85
|
+
readonly maxCounter: 10000;
|
|
86
|
+
readonly maxAgeMs: number;
|
|
87
|
+
readonly minMaxAgeMs: 60000;
|
|
88
|
+
readonly maxMaxAgeMs: number;
|
|
89
|
+
readonly maxTokenLength: 4096;
|
|
90
|
+
readonly minKeyLength: 32;
|
|
91
|
+
/** What a slow phone's widget runs over its workers, PBKDF2 iterations a second: the rate the worst case is sized by. */
|
|
92
|
+
readonly slowIterationsPerSecond: 2000000;
|
|
93
|
+
/** How long the widget tries before it gives up. */
|
|
94
|
+
readonly solveTimeoutMs: 90000;
|
|
95
|
+
};
|
|
96
|
+
/** How long a slow phone takes for the worst draw of a challenge of `cost`, in ms. */
|
|
97
|
+
export declare function altchaWorstSolveMs(cost: number): number;
|
|
98
|
+
/** Whether a slow phone solves the worst draw before the widget gives up and within half the challenge's lifetime. */
|
|
99
|
+
export declare function altchaSolvable(cost: number, maxAgeMs: number): boolean;
|
|
100
|
+
/**
|
|
101
|
+
* The `action` a procedure's challenge expects back: the declared one, else the endpoint id with `_` for `.`. The build
|
|
102
|
+
* and the typed client both read it here, so the client's challenge path is the artifact's.
|
|
103
|
+
*/
|
|
104
|
+
export declare function declaredChallengeAction(endpoint: string, declared: unknown): string;
|
|
105
|
+
/** Where an ALTCHA challenge is issued: one path per procedure, under its action. */
|
|
106
|
+
export declare const CHALLENGE_PREFIX = "/__fabrika/challenge";
|
|
107
|
+
export declare function challengePath(action: string): string;
|
|
108
|
+
/** The endpoint id of the row that issues the challenge of public procedure `endpoint`. */
|
|
109
|
+
export declare function challengeRowId(endpoint: string): string;
|
|
110
|
+
/**
|
|
111
|
+
* The buckets per minute of the endpoint that issues a challenge: a visitor fetches one per form shown and one more per
|
|
112
|
+
* expiry, and every issue costs the server one attempt's work. Each is at least this, and at least twice the
|
|
113
|
+
* procedure's own bucket, so the issuer never admits fewer submissions than the procedure declares. A bucket the
|
|
114
|
+
* procedure turns off (`null`) is this one on the issuer: the procedure's handler may be cheap, the issue never is.
|
|
115
|
+
*/
|
|
116
|
+
export declare const CHALLENGE_ISSUE_RATE: {
|
|
117
|
+
readonly perClient: 30;
|
|
118
|
+
readonly perEndpoint: 600;
|
|
119
|
+
};
|
|
120
|
+
/** The issuer's bucket for the procedure's `own`, within the ceiling of every bucket. */
|
|
121
|
+
export declare function challengeIssueBucket(own: number | null, floor: number): number;
|
|
122
|
+
/**
|
|
123
|
+
* The bounds of a file kind: the largest file a `scan: true` kind admits (the scanner reads at most this much of one
|
|
124
|
+
* file, so a larger one could never be given a clean verdict).
|
|
125
|
+
*/
|
|
126
|
+
export declare const FILE_LIMITS: {
|
|
127
|
+
readonly maxScannedBytes: number;
|
|
128
|
+
/** Sniffable types a `scan: true` kind refuses: archives other than ZIP, whose contents the framework does not check. */
|
|
129
|
+
readonly unscannedTypes: readonly string[];
|
|
130
|
+
};
|
|
131
|
+
/**
|
|
132
|
+
* The bounds of an `attachment()` output. `maxBytes` and `maxRows` are each attachment's own, at most these; a cell holds
|
|
133
|
+
* at most `maxCellLength` UTF-16 code units, the most a spreadsheet cell keeps.
|
|
134
|
+
*/
|
|
135
|
+
export declare const ATTACHMENT_LIMITS: {
|
|
136
|
+
readonly maxBytes: number;
|
|
137
|
+
readonly maxRows: 100000;
|
|
138
|
+
readonly defaultMaxRows: 10000;
|
|
139
|
+
readonly maxCellLength: 32767;
|
|
140
|
+
};
|
|
141
|
+
/** The type each attachment format answers with. */
|
|
142
|
+
export declare const CSV_CONTENT_TYPE = "text/csv; charset=utf-8";
|
|
143
|
+
export declare const XLSX_CONTENT_TYPE = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
|
|
144
|
+
/** Export procedures are served here, one path per procedure, and each export's description at its own path. */
|
|
145
|
+
export { CONNECT_PREFIX } from '@fabrika/auth-core';
|
|
146
|
+
/**
|
|
147
|
+
* Every connector call has a deadline; it bounds the retries too. Queries are safe to retry. An answer and a
|
|
148
|
+
* description are read under a byte budget, so another application cannot make the consumer buffer without bound.
|
|
149
|
+
*/
|
|
150
|
+
export declare const CONNECT_LIMITS: {
|
|
151
|
+
readonly defaultTimeoutMs: 3000;
|
|
152
|
+
readonly maxTimeoutMs: 10000;
|
|
153
|
+
readonly retries: 2;
|
|
154
|
+
readonly maxAnswerBytes: number;
|
|
155
|
+
readonly maxDescriptionBytes: number;
|
|
156
|
+
};
|
|
157
|
+
/** `products` version 1 → `products.v1`: the description's endpoint id, and the prefix of each procedure's. */
|
|
158
|
+
export declare function exportBase(name: string, version: number): string;
|
|
159
|
+
/** A link mount serves its procedures under `<prefix>/api`; everything else under the prefix is its SPA. */
|
|
160
|
+
export declare const LINK_API_SEGMENT = "api";
|
|
161
|
+
/** The path segment a webhook appends for the binding a delivery addresses. */
|
|
162
|
+
export declare const WEBHOOK_BINDING_PARAMETER = "bindingId";
|
|
163
|
+
/**
|
|
164
|
+
* The share SPA's bootstrap, served by the framework under the link prefix and loaded before any other script: it
|
|
165
|
+
* takes the key out of the URL fragment and keeps it in a closure behind `SHARE_KEY_GLOBAL`.
|
|
166
|
+
*/
|
|
167
|
+
export declare const LINK_BOOTSTRAP_FILE = "__fabrika-share.js";
|
|
168
|
+
export declare const SHARE_KEY_GLOBAL = "__fabrikaShareKey";
|
|
169
|
+
/** What every `c.spa` mount serves under its prefix: the browser's Operations DSN and the release, as JSON. */
|
|
170
|
+
export declare const BROWSER_CONFIG_FILE = "__fabrika-config.json";
|
|
171
|
+
/** What every `c.spa` mount serves under its prefix to the person its access admitted: label, mailbox and actions. */
|
|
172
|
+
export declare const PAGE_CALLER_FILE = "__fabrika-me.json";
|
|
173
|
+
/** The row of an SPA mount's bare prefix (`GET /admin`), which redirects to the mount (`/admin/`). */
|
|
174
|
+
export declare function spaPrefixRowId(mount: string): string;
|
|
175
|
+
/**
|
|
176
|
+
* The value a generated endpoint access case sends in an input field that names a member the handler looks up
|
|
177
|
+
* (`members` of `endpoint-access.fixtures.ts`); the endpoint access kit replaces it with a real member of the directory.
|
|
178
|
+
*/
|
|
179
|
+
export declare const GENERATED_MEMBER = "fabrika:member";
|
|
180
|
+
/**
|
|
181
|
+
* The value a generated endpoint access case sends in an input field that names an invitation the handler cancels
|
|
182
|
+
* (`invitations` of `endpoint-access.fixtures.ts`); the endpoint access kit replaces it with one open in the target's value.
|
|
183
|
+
*/
|
|
184
|
+
export declare const GENERATED_INVITATION = "fabrika:invitation";
|
|
185
|
+
/**
|
|
186
|
+
* The value a generated endpoint access case sends in an input field that names a share link the handler revokes
|
|
187
|
+
* (`links` of `endpoint-access.fixtures.ts`); the endpoint access kit replaces it with one the case's caller issued.
|
|
188
|
+
*/
|
|
189
|
+
export declare const GENERATED_LINK = "fabrika:link";
|
|
190
|
+
/**
|
|
191
|
+
* The prefix of the value a generated endpoint access case sends in an input field that names a row lying in its object
|
|
192
|
+
* (`rows` of `endpoint-access.fixtures.ts`), followed by the row's table: `fabrika:row:note_comments`. The endpoint
|
|
193
|
+
* access kit seeds one such row in each scope's object and sends that scope's key.
|
|
194
|
+
*/
|
|
195
|
+
export declare const GENERATED_ROW_PREFIX = "fabrika:row:";
|
|
196
|
+
/**
|
|
197
|
+
* The prefix of the value a generated endpoint access case sends in a file field, followed by the field's file kind:
|
|
198
|
+
* `fabrika:file:attachments`. The endpoint access kit sends a small file of the kind's first type it can write in its place.
|
|
199
|
+
*/
|
|
200
|
+
export declare const GENERATED_FILE_PREFIX = "fabrika:file:";
|
|
201
|
+
export declare const JSON_ADMISSION: BodyAdmission;
|
|
202
|
+
/** `/api` + `notes.list` → `/api/notes.list`; a root prefix does not double the `/`. */
|
|
203
|
+
export declare function joinPath(prefix: string, rest: string): string;
|
|
204
|
+
/**
|
|
205
|
+
* The path of an RPC mount's procedure: its own `http.path` when it declares one (a public procedure only, which
|
|
206
|
+
* `buildArtifact` checks), else `<prefix>/<dotted.path>`. The typed client calls the path the artifact's row carries.
|
|
207
|
+
*/
|
|
208
|
+
export declare function procedurePath(prefix: string, dotted: string, http: unknown): string;
|