@antasphere/chassis-contract 0.0.0-stage → 1.0.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/LICENSE +82 -0
- package/dist/define.d.ts +177 -0
- package/dist/define.d.ts.map +1 -0
- package/dist/define.js +35 -0
- package/dist/define.js.map +1 -0
- package/dist/entitlements.d.ts +486 -0
- package/dist/entitlements.d.ts.map +1 -0
- package/dist/entitlements.js +344 -0
- package/dist/entitlements.js.map +1 -0
- package/dist/identity.d.ts +56 -0
- package/dist/identity.d.ts.map +1 -0
- package/dist/identity.js +2 -0
- package/dist/identity.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -0
- package/dist/routes/index.d.ts +5403 -0
- package/dist/routes/index.d.ts.map +1 -0
- package/dist/routes/index.js +940 -0
- package/dist/routes/index.js.map +1 -0
- package/dist/schemas/api-keys.d.ts +54 -0
- package/dist/schemas/api-keys.d.ts.map +1 -0
- package/dist/schemas/api-keys.js +48 -0
- package/dist/schemas/api-keys.js.map +1 -0
- package/dist/schemas/audit.d.ts +74 -0
- package/dist/schemas/audit.d.ts.map +1 -0
- package/dist/schemas/audit.js +65 -0
- package/dist/schemas/audit.js.map +1 -0
- package/dist/schemas/break-glass.d.ts +42 -0
- package/dist/schemas/break-glass.d.ts.map +1 -0
- package/dist/schemas/break-glass.js +38 -0
- package/dist/schemas/break-glass.js.map +1 -0
- package/dist/schemas/cli-auth.d.ts +59 -0
- package/dist/schemas/cli-auth.d.ts.map +1 -0
- package/dist/schemas/cli-auth.js +68 -0
- package/dist/schemas/cli-auth.js.map +1 -0
- package/dist/schemas/common.d.ts +96 -0
- package/dist/schemas/common.d.ts.map +1 -0
- package/dist/schemas/common.js +205 -0
- package/dist/schemas/common.js.map +1 -0
- package/dist/schemas/demo-passes.d.ts +90 -0
- package/dist/schemas/demo-passes.d.ts.map +1 -0
- package/dist/schemas/demo-passes.js +60 -0
- package/dist/schemas/demo-passes.js.map +1 -0
- package/dist/schemas/files.d.ts +39 -0
- package/dist/schemas/files.d.ts.map +1 -0
- package/dist/schemas/files.js +26 -0
- package/dist/schemas/files.js.map +1 -0
- package/dist/schemas/instance.d.ts +58 -0
- package/dist/schemas/instance.d.ts.map +1 -0
- package/dist/schemas/instance.js +70 -0
- package/dist/schemas/instance.js.map +1 -0
- package/dist/schemas/invitations.d.ts +100 -0
- package/dist/schemas/invitations.d.ts.map +1 -0
- package/dist/schemas/invitations.js +55 -0
- package/dist/schemas/invitations.js.map +1 -0
- package/dist/schemas/me.d.ts +81 -0
- package/dist/schemas/me.d.ts.map +1 -0
- package/dist/schemas/me.js +178 -0
- package/dist/schemas/me.js.map +1 -0
- package/dist/schemas/members.d.ts +60 -0
- package/dist/schemas/members.d.ts.map +1 -0
- package/dist/schemas/members.js +43 -0
- package/dist/schemas/members.js.map +1 -0
- package/dist/schemas/projects.d.ts +232 -0
- package/dist/schemas/projects.d.ts.map +1 -0
- package/dist/schemas/projects.js +140 -0
- package/dist/schemas/projects.js.map +1 -0
- package/dist/schemas/scope.d.ts +14 -0
- package/dist/schemas/scope.d.ts.map +1 -0
- package/dist/schemas/scope.js +5 -0
- package/dist/schemas/scope.js.map +1 -0
- package/dist/schemas/setup.d.ts +28 -0
- package/dist/schemas/setup.d.ts.map +1 -0
- package/dist/schemas/setup.js +28 -0
- package/dist/schemas/setup.js.map +1 -0
- package/dist/schemas/sso-connect.d.ts +30 -0
- package/dist/schemas/sso-connect.d.ts.map +1 -0
- package/dist/schemas/sso-connect.js +38 -0
- package/dist/schemas/sso-connect.js.map +1 -0
- package/dist/schemas/sso-logout.d.ts +17 -0
- package/dist/schemas/sso-logout.d.ts.map +1 -0
- package/dist/schemas/sso-logout.js +16 -0
- package/dist/schemas/sso-logout.js.map +1 -0
- package/dist/schemas/teams.d.ts +100 -0
- package/dist/schemas/teams.d.ts.map +1 -0
- package/dist/schemas/teams.js +84 -0
- package/dist/schemas/teams.js.map +1 -0
- package/dist/schemas/workspaces.d.ts +99 -0
- package/dist/schemas/workspaces.d.ts.map +1 -0
- package/dist/schemas/workspaces.js +96 -0
- package/dist/schemas/workspaces.js.map +1 -0
- package/dist/seams.d.ts +185 -0
- package/dist/seams.d.ts.map +1 -0
- package/dist/seams.js +37 -0
- package/dist/seams.js.map +1 -0
- package/dist/wire.d.ts +101 -0
- package/dist/wire.d.ts.map +1 -0
- package/dist/wire.js +161 -0
- package/dist/wire.js.map +1 -0
- package/package.json +41 -3
- package/src/define.ts +64 -0
- package/src/entitlements.ts +527 -0
- package/src/identity.ts +49 -0
- package/src/index.ts +38 -0
- package/src/routes/index.ts +1146 -0
- package/src/schemas/api-keys.ts +53 -0
- package/src/schemas/audit.ts +74 -0
- package/src/schemas/break-glass.ts +46 -0
- package/src/schemas/cli-auth.ts +78 -0
- package/src/schemas/common.ts +206 -0
- package/src/schemas/demo-passes.ts +73 -0
- package/src/schemas/files.ts +30 -0
- package/src/schemas/instance.ts +71 -0
- package/src/schemas/invitations.ts +66 -0
- package/src/schemas/me.ts +184 -0
- package/src/schemas/members.ts +53 -0
- package/src/schemas/projects.ts +174 -0
- package/src/schemas/scope.ts +18 -0
- package/src/schemas/setup.ts +31 -0
- package/src/schemas/sso-connect.ts +40 -0
- package/src/schemas/sso-logout.ts +17 -0
- package/src/schemas/teams.ts +101 -0
- package/src/schemas/workspaces.ts +109 -0
- package/src/seams.ts +202 -0
- package/src/wire.ts +246 -0
- package/test/define.test.ts +59 -0
- package/test/hub-wire.test.ts +114 -0
- package/README.md +0 -3
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* API conventions (fixed): plain resource JSON on success — no
|
|
4
|
+
* `{ success, data }` envelope; errors are `{ error: { code, message,
|
|
5
|
+
* details? } }`; cursor pagination.
|
|
6
|
+
*/
|
|
7
|
+
export declare const apiErrorSchema: z.ZodObject<{
|
|
8
|
+
error: z.ZodObject<{
|
|
9
|
+
code: z.ZodString;
|
|
10
|
+
message: z.ZodString;
|
|
11
|
+
details: z.ZodOptional<z.ZodUnknown>;
|
|
12
|
+
}, z.core.$strip>;
|
|
13
|
+
}, z.core.$strip>;
|
|
14
|
+
export type ApiError = z.infer<typeof apiErrorSchema>;
|
|
15
|
+
export declare const workspaceRoleSchema: z.ZodEnum<{
|
|
16
|
+
owner: "owner";
|
|
17
|
+
admin: "admin";
|
|
18
|
+
member: "member";
|
|
19
|
+
}>;
|
|
20
|
+
export type WorkspaceRole = z.infer<typeof workspaceRoleSchema>;
|
|
21
|
+
export declare const cursorPageQuerySchema: z.ZodObject<{
|
|
22
|
+
cursor: z.ZodOptional<z.ZodString>;
|
|
23
|
+
limit: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
|
|
24
|
+
}, z.core.$strip>;
|
|
25
|
+
/**
|
|
26
|
+
* Free text a client may send that ends up in a Postgres `text`/`varchar`
|
|
27
|
+
* column, a filename, or a log line.
|
|
28
|
+
*
|
|
29
|
+
* Postgres cannot store a NUL byte in a text value: it raises SQLSTATE 22021
|
|
30
|
+
* from deep inside the driver, which surfaces as an unhandled 500 whose
|
|
31
|
+
* error-level log line prints the failing statement AND its bound parameters.
|
|
32
|
+
* An anonymous client can drive that on any free-text sink (`/setup`, the
|
|
33
|
+
* invitation accept, the CLI key mint). NUL is never meaningful in a name, a
|
|
34
|
+
* label, or a title, so the contract refuses it and the caller gets the
|
|
35
|
+
* ordinary 400 validation_error instead.
|
|
36
|
+
*
|
|
37
|
+
* The other C0 controls are rejected with it: they are invisible in every UI,
|
|
38
|
+
* they are the raw material of log-injection and terminal-escape tricks, and
|
|
39
|
+
* no legitimate name contains one. Newlines and tabs are ALLOWED — multi-line
|
|
40
|
+
* free text is a real thing; a sink that must stay single-line adds its own
|
|
41
|
+
* `.regex()`.
|
|
42
|
+
*/
|
|
43
|
+
export declare function hasControlChars(value: string): boolean;
|
|
44
|
+
export declare function noControlChars<T extends z.ZodType<string>>(schema: T): T;
|
|
45
|
+
/**
|
|
46
|
+
* Postgres int4 ceiling. Every integer the API accepts that lands in an
|
|
47
|
+
* `integer` column (version numbers, cursors) must be bounded by it at the
|
|
48
|
+
* contract: `Number.isInteger(1e15)` is true, so a bare `.int()` lets a value
|
|
49
|
+
* past bigint-free column range through to Postgres, which refuses it with
|
|
50
|
+
* a numeric-overflow error that would surface as a 500.
|
|
51
|
+
*/
|
|
52
|
+
export declare const INT4_MAX = 2147483647;
|
|
53
|
+
/**
|
|
54
|
+
* True when the value graph carries a NUL character in any string — object
|
|
55
|
+
* keys included. Postgres cannot store NUL in `text` (SQLSTATE 22021) or in
|
|
56
|
+
* `jsonb` (`\u0000` raises 22P05), so any client-supplied structure bound for
|
|
57
|
+
* a jsonb column (annotation selections, form payloads, a resource's metadata) is
|
|
58
|
+
* refused at the contract instead of surfacing a driver error. Iterative walk
|
|
59
|
+
* — never recursion — so a deeply nested value cannot blow the stack in the
|
|
60
|
+
* very guard meant to protect against hostile shapes.
|
|
61
|
+
*/
|
|
62
|
+
export declare function hasNulDeep(value: unknown): boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Nesting depth of a parsed JSON value, computed iteratively (the point is to
|
|
65
|
+
* measure hostile depth without recursing over it). Scalars are depth 0; an
|
|
66
|
+
* object or array adds one level. Contracts cap opaque structures with this
|
|
67
|
+
* BEFORE any `JSON.stringify` runs on them — stringify is recursive and blows
|
|
68
|
+
* the V8 stack with a RangeError at a build-dependent depth (SL-B5), so the
|
|
69
|
+
* check must come first, and the contract must stay safe even when consumed
|
|
70
|
+
* outside the server (SDK, dashboard) where no edge middleware ran.
|
|
71
|
+
*/
|
|
72
|
+
export declare function jsonDepthOf(value: unknown): number;
|
|
73
|
+
/**
|
|
74
|
+
* Depth cap for the opaque JSON objects the contract carries (metadata,
|
|
75
|
+
* annotation selections, form payloads). Far above any legitimate shape —
|
|
76
|
+
* the deepest real structure is a handful of levels — and far below both the
|
|
77
|
+
* server edge cap (100) and the stringify breaking depth (~5000 on
|
|
78
|
+
* node:22-alpine).
|
|
79
|
+
*/
|
|
80
|
+
export declare const MAX_OPAQUE_JSON_DEPTH = 32;
|
|
81
|
+
/**
|
|
82
|
+
* The shared guard for an opaque client-supplied JSON object bound for a
|
|
83
|
+
* jsonb column: depth-capped first (so the later size refine may stringify
|
|
84
|
+
* safely), then NUL-free. Compose it onto a `z.record(...)` with `.check`
|
|
85
|
+
* short-circuiting: zod runs refinements in order and skips later ones once
|
|
86
|
+
* one fails only when `abort` is set, so both checks abort.
|
|
87
|
+
*/
|
|
88
|
+
export declare function opaqueJsonChecks<T extends z.ZodType<Record<string, unknown>>>(schema: T): T;
|
|
89
|
+
/**
|
|
90
|
+
* The one free-text string builder: length-bounded and NUL-free.
|
|
91
|
+
* Every user-supplied name/label/title in this contract goes through it.
|
|
92
|
+
*/
|
|
93
|
+
export declare function plainText(min: number, max: number): z.ZodString;
|
|
94
|
+
export declare const MEDIA_TYPE_RE: RegExp;
|
|
95
|
+
export declare function isValidMediaType(value: string): boolean;
|
|
96
|
+
//# sourceMappingURL=common.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../src/schemas/common.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;GAIG;AACH,eAAO,MAAM,cAAc;;;;;;iBAMzB,CAAC;AACH,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAEtD,eAAO,MAAM,mBAAmB;;;;EAAuC,CAAC;AACxE,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,eAAO,MAAM,qBAAqB;;;iBAGhC,CAAC;AACH;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAQtD;AAED,wBAAgB,cAAc,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAIxE;AAED;;;;;;GAMG;AACH,eAAO,MAAM,QAAQ,aAAgB,CAAC;AAEtC;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAwBlD;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAoBlD;AAED;;;;;;GAMG;AACH,eAAO,MAAM,qBAAqB,KAAK,CAAC;AAExC;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAU3F;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,eAEjD;AAcD,eAAO,MAAM,aAAa,QAGzB,CAAC;AAoBF,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEvD"}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* API conventions (fixed): plain resource JSON on success — no
|
|
4
|
+
* `{ success, data }` envelope; errors are `{ error: { code, message,
|
|
5
|
+
* details? } }`; cursor pagination.
|
|
6
|
+
*/
|
|
7
|
+
export const apiErrorSchema = z.object({
|
|
8
|
+
error: z.object({
|
|
9
|
+
code: z.string(),
|
|
10
|
+
message: z.string(),
|
|
11
|
+
details: z.unknown().optional()
|
|
12
|
+
})
|
|
13
|
+
});
|
|
14
|
+
export const workspaceRoleSchema = z.enum(['owner', 'admin', 'member']);
|
|
15
|
+
export const cursorPageQuerySchema = z.object({
|
|
16
|
+
cursor: z.string().optional(),
|
|
17
|
+
limit: z.coerce.number().int().min(1).max(100).default(50)
|
|
18
|
+
});
|
|
19
|
+
/**
|
|
20
|
+
* Free text a client may send that ends up in a Postgres `text`/`varchar`
|
|
21
|
+
* column, a filename, or a log line.
|
|
22
|
+
*
|
|
23
|
+
* Postgres cannot store a NUL byte in a text value: it raises SQLSTATE 22021
|
|
24
|
+
* from deep inside the driver, which surfaces as an unhandled 500 whose
|
|
25
|
+
* error-level log line prints the failing statement AND its bound parameters.
|
|
26
|
+
* An anonymous client can drive that on any free-text sink (`/setup`, the
|
|
27
|
+
* invitation accept, the CLI key mint). NUL is never meaningful in a name, a
|
|
28
|
+
* label, or a title, so the contract refuses it and the caller gets the
|
|
29
|
+
* ordinary 400 validation_error instead.
|
|
30
|
+
*
|
|
31
|
+
* The other C0 controls are rejected with it: they are invisible in every UI,
|
|
32
|
+
* they are the raw material of log-injection and terminal-escape tricks, and
|
|
33
|
+
* no legitimate name contains one. Newlines and tabs are ALLOWED — multi-line
|
|
34
|
+
* free text is a real thing; a sink that must stay single-line adds its own
|
|
35
|
+
* `.regex()`.
|
|
36
|
+
*/
|
|
37
|
+
export function hasControlChars(value) {
|
|
38
|
+
for (let i = 0; i < value.length; i++) {
|
|
39
|
+
const code = value.charCodeAt(i);
|
|
40
|
+
// Tab / LF / CR are legitimate in multi-line free text.
|
|
41
|
+
if (code === 0x09 || code === 0x0a || code === 0x0d)
|
|
42
|
+
continue;
|
|
43
|
+
if (code < 0x20 || code === 0x7f)
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
export function noControlChars(schema) {
|
|
49
|
+
return schema.refine((v) => !hasControlChars(v), {
|
|
50
|
+
error: 'must not contain NUL or other control characters'
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Postgres int4 ceiling. Every integer the API accepts that lands in an
|
|
55
|
+
* `integer` column (version numbers, cursors) must be bounded by it at the
|
|
56
|
+
* contract: `Number.isInteger(1e15)` is true, so a bare `.int()` lets a value
|
|
57
|
+
* past bigint-free column range through to Postgres, which refuses it with
|
|
58
|
+
* a numeric-overflow error that would surface as a 500.
|
|
59
|
+
*/
|
|
60
|
+
export const INT4_MAX = 2_147_483_647;
|
|
61
|
+
/**
|
|
62
|
+
* True when the value graph carries a NUL character in any string — object
|
|
63
|
+
* keys included. Postgres cannot store NUL in `text` (SQLSTATE 22021) or in
|
|
64
|
+
* `jsonb` (`\u0000` raises 22P05), so any client-supplied structure bound for
|
|
65
|
+
* a jsonb column (annotation selections, form payloads, a resource's metadata) is
|
|
66
|
+
* refused at the contract instead of surfacing a driver error. Iterative walk
|
|
67
|
+
* — never recursion — so a deeply nested value cannot blow the stack in the
|
|
68
|
+
* very guard meant to protect against hostile shapes.
|
|
69
|
+
*/
|
|
70
|
+
export function hasNulDeep(value) {
|
|
71
|
+
const stack = [value];
|
|
72
|
+
// A shared value graph (the contract is documented safe to run outside the
|
|
73
|
+
// server, where a caller may hand it a live object carrying a cycle) would
|
|
74
|
+
// spin this walk forever; the seen-set makes each container visited once.
|
|
75
|
+
const seen = new WeakSet();
|
|
76
|
+
while (stack.length > 0) {
|
|
77
|
+
const current = stack.pop();
|
|
78
|
+
if (typeof current === 'string') {
|
|
79
|
+
if (current.includes('\u0000'))
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
else if (Array.isArray(current)) {
|
|
83
|
+
if (seen.has(current))
|
|
84
|
+
continue;
|
|
85
|
+
seen.add(current);
|
|
86
|
+
for (const item of current)
|
|
87
|
+
stack.push(item);
|
|
88
|
+
}
|
|
89
|
+
else if (current !== null && typeof current === 'object') {
|
|
90
|
+
if (seen.has(current))
|
|
91
|
+
continue;
|
|
92
|
+
seen.add(current);
|
|
93
|
+
for (const [key, item] of Object.entries(current)) {
|
|
94
|
+
if (key.includes('\u0000'))
|
|
95
|
+
return true;
|
|
96
|
+
stack.push(item);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Nesting depth of a parsed JSON value, computed iteratively (the point is to
|
|
104
|
+
* measure hostile depth without recursing over it). Scalars are depth 0; an
|
|
105
|
+
* object or array adds one level. Contracts cap opaque structures with this
|
|
106
|
+
* BEFORE any `JSON.stringify` runs on them — stringify is recursive and blows
|
|
107
|
+
* the V8 stack with a RangeError at a build-dependent depth (SL-B5), so the
|
|
108
|
+
* check must come first, and the contract must stay safe even when consumed
|
|
109
|
+
* outside the server (SDK, dashboard) where no edge middleware ran.
|
|
110
|
+
*/
|
|
111
|
+
export function jsonDepthOf(value) {
|
|
112
|
+
let max = 0;
|
|
113
|
+
const stack = [{ node: value, depth: 0 }];
|
|
114
|
+
// Same cycle guard as hasNulDeep: a live object with a back-reference must
|
|
115
|
+
// not make the depth walk (or the caller's later stringify) run forever.
|
|
116
|
+
const seen = new WeakSet();
|
|
117
|
+
while (stack.length > 0) {
|
|
118
|
+
const { node, depth } = stack.pop();
|
|
119
|
+
if (depth > max)
|
|
120
|
+
max = depth;
|
|
121
|
+
if (node !== null && typeof node === 'object') {
|
|
122
|
+
if (seen.has(node))
|
|
123
|
+
continue;
|
|
124
|
+
seen.add(node);
|
|
125
|
+
}
|
|
126
|
+
if (Array.isArray(node)) {
|
|
127
|
+
for (const item of node)
|
|
128
|
+
stack.push({ node: item, depth: depth + 1 });
|
|
129
|
+
}
|
|
130
|
+
else if (node !== null && typeof node === 'object') {
|
|
131
|
+
for (const item of Object.values(node))
|
|
132
|
+
stack.push({ node: item, depth: depth + 1 });
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return max;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Depth cap for the opaque JSON objects the contract carries (metadata,
|
|
139
|
+
* annotation selections, form payloads). Far above any legitimate shape —
|
|
140
|
+
* the deepest real structure is a handful of levels — and far below both the
|
|
141
|
+
* server edge cap (100) and the stringify breaking depth (~5000 on
|
|
142
|
+
* node:22-alpine).
|
|
143
|
+
*/
|
|
144
|
+
export const MAX_OPAQUE_JSON_DEPTH = 32;
|
|
145
|
+
/**
|
|
146
|
+
* The shared guard for an opaque client-supplied JSON object bound for a
|
|
147
|
+
* jsonb column: depth-capped first (so the later size refine may stringify
|
|
148
|
+
* safely), then NUL-free. Compose it onto a `z.record(...)` with `.check`
|
|
149
|
+
* short-circuiting: zod runs refinements in order and skips later ones once
|
|
150
|
+
* one fails only when `abort` is set, so both checks abort.
|
|
151
|
+
*/
|
|
152
|
+
export function opaqueJsonChecks(schema) {
|
|
153
|
+
return schema
|
|
154
|
+
.refine((v) => jsonDepthOf(v) <= MAX_OPAQUE_JSON_DEPTH, {
|
|
155
|
+
error: `must not nest deeper than ${MAX_OPAQUE_JSON_DEPTH} levels`,
|
|
156
|
+
abort: true
|
|
157
|
+
})
|
|
158
|
+
.refine((v) => !hasNulDeep(v), {
|
|
159
|
+
error: 'must not contain NUL characters in keys or values',
|
|
160
|
+
abort: true
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* The one free-text string builder: length-bounded and NUL-free.
|
|
165
|
+
* Every user-supplied name/label/title in this contract goes through it.
|
|
166
|
+
*/
|
|
167
|
+
export function plainText(min, max) {
|
|
168
|
+
return noControlChars(z.string().min(min).max(max));
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* RFC 7231 media type: `token "/" token`, optionally followed by
|
|
172
|
+
* `;`-separated `token=token|quoted-string` parameters. The manifest's
|
|
173
|
+
* `contentType` is copied VERBATIM into the response `Content-Type` header
|
|
174
|
+
* when the blob is served (`files/serve.ts`), including on the anonymous
|
|
175
|
+
* viewer — and versions are immutable, so a committed value that the
|
|
176
|
+
* `Headers` constructor refuses (a non-Latin-1 character, say) was a
|
|
177
|
+
* permanent anonymous 500 on that asset (PLT-5, PRDCT-1358). The grammar
|
|
178
|
+
* check at commit is the fix; the serve-time sanitizer is the backstop for
|
|
179
|
+
* rows committed before it.
|
|
180
|
+
*/
|
|
181
|
+
const MEDIA_TYPE_TOKEN = "[!#$%&'*+.^_`|~0-9A-Za-z-]+";
|
|
182
|
+
export const MEDIA_TYPE_RE = new RegExp(`^${MEDIA_TYPE_TOKEN}\\/${MEDIA_TYPE_TOKEN}` +
|
|
183
|
+
`(?:[ \\t]*;[ \\t]*${MEDIA_TYPE_TOKEN}=(?:${MEDIA_TYPE_TOKEN}|"[^"\\\\\\u0000-\\u001f\\u007f]*"))*$`);
|
|
184
|
+
/**
|
|
185
|
+
* A response header VALUE is a ByteString: setting it converts each UTF-16
|
|
186
|
+
* code unit and throws a TypeError on any unit above 0xFF. The token grammar
|
|
187
|
+
* already excludes those in unquoted positions, but a quoted parameter value
|
|
188
|
+
* (`charset="€"`) can carry any character the regex's negated class does not
|
|
189
|
+
* name — U+20AC passes the pattern and then throws at the `Headers` set. So
|
|
190
|
+
* the Latin-1 ceiling is a SEPARATE, explicit check: every code unit ≤ 0xFF,
|
|
191
|
+
* which also rejects astral characters and lone surrogates (their code units
|
|
192
|
+
* are all ≥ 0xD800). Without it the grammar check is not the closure PLT-5
|
|
193
|
+
* needs.
|
|
194
|
+
*/
|
|
195
|
+
function isLatin1(value) {
|
|
196
|
+
for (let i = 0; i < value.length; i++) {
|
|
197
|
+
if (value.charCodeAt(i) > 0xff)
|
|
198
|
+
return false;
|
|
199
|
+
}
|
|
200
|
+
return true;
|
|
201
|
+
}
|
|
202
|
+
export function isValidMediaType(value) {
|
|
203
|
+
return value.length >= 1 && value.length <= 255 && isLatin1(value) && MEDIA_TYPE_RE.test(value);
|
|
204
|
+
}
|
|
205
|
+
//# sourceMappingURL=common.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"common.js","sourceRoot":"","sources":["../../src/schemas/common.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* A DEMO PASS is a link an owner mints so that one member of the workspace
|
|
4
|
+
* is signed in without a password, for a demonstration (the demo pass spec).
|
|
5
|
+
* The routes exist only while the instance's DEMO_SIGN_IN switch is on, on
|
|
6
|
+
* the self-hosted edition; `GET /instance` says so with `demoSignIn: true`.
|
|
7
|
+
* The secret is shown once, in the mint's answer, and stored nowhere.
|
|
8
|
+
*/
|
|
9
|
+
/** A pass's lifetime when the mint names none: one day, in minutes. */
|
|
10
|
+
export declare const DEMO_PASS_DEFAULT_MINUTES = 1440;
|
|
11
|
+
/** The longest lifetime a mint may ask for: one week, in minutes. */
|
|
12
|
+
export declare const DEMO_PASS_MAX_MINUTES = 10080;
|
|
13
|
+
export declare const demoPassSchema: z.ZodObject<{
|
|
14
|
+
id: z.ZodString;
|
|
15
|
+
userId: z.ZodString;
|
|
16
|
+
email: z.ZodString;
|
|
17
|
+
name: z.ZodString;
|
|
18
|
+
targetPath: z.ZodString;
|
|
19
|
+
createdBy: z.ZodNullable<z.ZodString>;
|
|
20
|
+
createdAt: z.ZodString;
|
|
21
|
+
expiresAt: z.ZodString;
|
|
22
|
+
revokedAt: z.ZodNullable<z.ZodString>;
|
|
23
|
+
lastUsedAt: z.ZodNullable<z.ZodString>;
|
|
24
|
+
useCount: z.ZodNumber;
|
|
25
|
+
}, z.core.$strip>;
|
|
26
|
+
export type DemoPass = z.infer<typeof demoPassSchema>;
|
|
27
|
+
export declare const demoPassesListSchema: z.ZodObject<{
|
|
28
|
+
passes: z.ZodArray<z.ZodObject<{
|
|
29
|
+
id: z.ZodString;
|
|
30
|
+
userId: z.ZodString;
|
|
31
|
+
email: z.ZodString;
|
|
32
|
+
name: z.ZodString;
|
|
33
|
+
targetPath: z.ZodString;
|
|
34
|
+
createdBy: z.ZodNullable<z.ZodString>;
|
|
35
|
+
createdAt: z.ZodString;
|
|
36
|
+
expiresAt: z.ZodString;
|
|
37
|
+
revokedAt: z.ZodNullable<z.ZodString>;
|
|
38
|
+
lastUsedAt: z.ZodNullable<z.ZodString>;
|
|
39
|
+
useCount: z.ZodNumber;
|
|
40
|
+
}, z.core.$strip>>;
|
|
41
|
+
}, z.core.$strip>;
|
|
42
|
+
export type DemoPassesList = z.infer<typeof demoPassesListSchema>;
|
|
43
|
+
/**
|
|
44
|
+
* The mint: a member of the caller's workspace by address, the page the link
|
|
45
|
+
* lands on (a same-origin path, checked by the server), and a lifetime.
|
|
46
|
+
*/
|
|
47
|
+
export declare const demoPassMintSchema: z.ZodObject<{
|
|
48
|
+
email: z.ZodEmail;
|
|
49
|
+
path: z.ZodOptional<z.ZodString>;
|
|
50
|
+
expiresInMinutes: z.ZodOptional<z.ZodNumber>;
|
|
51
|
+
}, z.core.$strip>;
|
|
52
|
+
export type DemoPassMint = z.infer<typeof demoPassMintSchema>;
|
|
53
|
+
export declare const demoPassMintedSchema: z.ZodObject<{
|
|
54
|
+
pass: z.ZodObject<{
|
|
55
|
+
id: z.ZodString;
|
|
56
|
+
userId: z.ZodString;
|
|
57
|
+
email: z.ZodString;
|
|
58
|
+
name: z.ZodString;
|
|
59
|
+
targetPath: z.ZodString;
|
|
60
|
+
createdBy: z.ZodNullable<z.ZodString>;
|
|
61
|
+
createdAt: z.ZodString;
|
|
62
|
+
expiresAt: z.ZodString;
|
|
63
|
+
revokedAt: z.ZodNullable<z.ZodString>;
|
|
64
|
+
lastUsedAt: z.ZodNullable<z.ZodString>;
|
|
65
|
+
useCount: z.ZodNumber;
|
|
66
|
+
}, z.core.$strip>;
|
|
67
|
+
secret: z.ZodString;
|
|
68
|
+
url: z.ZodString;
|
|
69
|
+
}, z.core.$strip>;
|
|
70
|
+
export type DemoPassMinted = z.infer<typeof demoPassMintedSchema>;
|
|
71
|
+
/**
|
|
72
|
+
* `POST /api/v1/auth/demo/redeem`: served by the sign-in library itself (so
|
|
73
|
+
* its own cookie and hooks apply), hence no route contract; these two
|
|
74
|
+
* shapes are the wire the SDK's `redeemDemoPass` speaks.
|
|
75
|
+
*/
|
|
76
|
+
export declare const demoPassRedeemSchema: z.ZodObject<{
|
|
77
|
+
pass: z.ZodString;
|
|
78
|
+
}, z.core.$strip>;
|
|
79
|
+
export type DemoPassRedeem = z.infer<typeof demoPassRedeemSchema>;
|
|
80
|
+
export declare const demoPassRedeemedSchema: z.ZodObject<{
|
|
81
|
+
user: z.ZodObject<{
|
|
82
|
+
id: z.ZodString;
|
|
83
|
+
email: z.ZodString;
|
|
84
|
+
name: z.ZodString;
|
|
85
|
+
}, z.core.$strip>;
|
|
86
|
+
path: z.ZodString;
|
|
87
|
+
expiresAt: z.ZodString;
|
|
88
|
+
}, z.core.$strip>;
|
|
89
|
+
export type DemoPassRedeemed = z.infer<typeof demoPassRedeemedSchema>;
|
|
90
|
+
//# sourceMappingURL=demo-passes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"demo-passes.d.ts","sourceRoot":"","sources":["../../src/schemas/demo-passes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;GAMG;AAEH,uEAAuE;AACvE,eAAO,MAAM,yBAAyB,OAAO,CAAC;AAC9C,qEAAqE;AACrE,eAAO,MAAM,qBAAqB,QAAQ,CAAC;AAE3C,eAAO,MAAM,cAAc;;;;;;;;;;;;iBAgBzB,CAAC;AACH,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAEtD,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;iBAAgD,CAAC;AAClF,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE;;;GAGG;AACH,eAAO,MAAM,kBAAkB;;;;iBAI7B,CAAC;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;iBAM/B,CAAC;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE;;;;GAIG;AACH,eAAO,MAAM,oBAAoB;;iBAAwC,CAAC;AAC1E,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE,eAAO,MAAM,sBAAsB;;;;;;;;iBAMjC,CAAC;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* A DEMO PASS is a link an owner mints so that one member of the workspace
|
|
4
|
+
* is signed in without a password, for a demonstration (the demo pass spec).
|
|
5
|
+
* The routes exist only while the instance's DEMO_SIGN_IN switch is on, on
|
|
6
|
+
* the self-hosted edition; `GET /instance` says so with `demoSignIn: true`.
|
|
7
|
+
* The secret is shown once, in the mint's answer, and stored nowhere.
|
|
8
|
+
*/
|
|
9
|
+
/** A pass's lifetime when the mint names none: one day, in minutes. */
|
|
10
|
+
export const DEMO_PASS_DEFAULT_MINUTES = 1440;
|
|
11
|
+
/** The longest lifetime a mint may ask for: one week, in minutes. */
|
|
12
|
+
export const DEMO_PASS_MAX_MINUTES = 10080;
|
|
13
|
+
export const demoPassSchema = z.object({
|
|
14
|
+
id: z.string(),
|
|
15
|
+
/** The person the pass signs in. */
|
|
16
|
+
userId: z.string(),
|
|
17
|
+
email: z.string(),
|
|
18
|
+
name: z.string(),
|
|
19
|
+
/** The page the link lands on. */
|
|
20
|
+
targetPath: z.string(),
|
|
21
|
+
/** The owner who minted it; null once that account is gone. */
|
|
22
|
+
createdBy: z.string().nullable(),
|
|
23
|
+
createdAt: z.string(),
|
|
24
|
+
expiresAt: z.string(),
|
|
25
|
+
revokedAt: z.string().nullable(),
|
|
26
|
+
lastUsedAt: z.string().nullable(),
|
|
27
|
+
/** How many sessions the pass has opened. */
|
|
28
|
+
useCount: z.number().int()
|
|
29
|
+
});
|
|
30
|
+
export const demoPassesListSchema = z.object({ passes: z.array(demoPassSchema) });
|
|
31
|
+
/**
|
|
32
|
+
* The mint: a member of the caller's workspace by address, the page the link
|
|
33
|
+
* lands on (a same-origin path, checked by the server), and a lifetime.
|
|
34
|
+
*/
|
|
35
|
+
export const demoPassMintSchema = z.object({
|
|
36
|
+
email: z.email(),
|
|
37
|
+
path: z.string().optional(),
|
|
38
|
+
expiresInMinutes: z.number().int().min(1).max(DEMO_PASS_MAX_MINUTES).optional()
|
|
39
|
+
});
|
|
40
|
+
export const demoPassMintedSchema = z.object({
|
|
41
|
+
pass: demoPassSchema,
|
|
42
|
+
/** The secret itself: shown here once, never again. */
|
|
43
|
+
secret: z.string(),
|
|
44
|
+
/** `<PUBLIC_BASE_URL>/demo#pass=<secret>&to=<path>`: the fragment never reaches a server log. */
|
|
45
|
+
url: z.string()
|
|
46
|
+
});
|
|
47
|
+
/**
|
|
48
|
+
* `POST /api/v1/auth/demo/redeem`: served by the sign-in library itself (so
|
|
49
|
+
* its own cookie and hooks apply), hence no route contract; these two
|
|
50
|
+
* shapes are the wire the SDK's `redeemDemoPass` speaks.
|
|
51
|
+
*/
|
|
52
|
+
export const demoPassRedeemSchema = z.object({ pass: z.string().min(1) });
|
|
53
|
+
export const demoPassRedeemedSchema = z.object({
|
|
54
|
+
user: z.object({ id: z.string(), email: z.string(), name: z.string() }),
|
|
55
|
+
/** The pass's page: where the dashboard goes when the link names none. */
|
|
56
|
+
path: z.string(),
|
|
57
|
+
/** When the PASS expires (the session it opened keeps its own lifetime). */
|
|
58
|
+
expiresAt: z.string()
|
|
59
|
+
});
|
|
60
|
+
//# sourceMappingURL=demo-passes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"demo-passes.js","sourceRoot":"","sources":["../../src/schemas/demo-passes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;GAMG;AAEH,uEAAuE;AACvE,MAAM,CAAC,MAAM,yBAAyB,GAAG,IAAI,CAAC;AAC9C,qEAAqE;AACrE,MAAM,CAAC,MAAM,qBAAqB,GAAG,KAAK,CAAC;AAE3C,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;IACd,oCAAoC;IACpC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;IAClB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,kCAAkC;IAClC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;IACtB,+DAA+D;IAC/D,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAChC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAChC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACjC,6CAA6C;IAC7C,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;CAC3B,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;AAGlF;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE;IAChB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC3B,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC,QAAQ,EAAE;CAChF,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C,IAAI,EAAE,cAAc;IACpB,uDAAuD;IACvD,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;IAClB,iGAAiG;IACjG,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE;CAChB,CAAC,CAAC;AAGH;;;;GAIG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AAG1E,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7C,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC;IACvE,0EAA0E;IAC1E,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,4EAA4E;IAC5E,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;CACtB,CAAC,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const fileSchema: z.ZodObject<{
|
|
3
|
+
id: z.ZodString;
|
|
4
|
+
sha256: z.ZodString;
|
|
5
|
+
sizeBytes: z.ZodNumber;
|
|
6
|
+
contentType: z.ZodString;
|
|
7
|
+
originalName: z.ZodString;
|
|
8
|
+
createdBy: z.ZodNullable<z.ZodString>;
|
|
9
|
+
createdAt: z.ZodString;
|
|
10
|
+
}, z.core.$strip>;
|
|
11
|
+
export type FileInfo = z.infer<typeof fileSchema>;
|
|
12
|
+
export declare const filesListSchema: z.ZodObject<{
|
|
13
|
+
files: z.ZodArray<z.ZodObject<{
|
|
14
|
+
id: z.ZodString;
|
|
15
|
+
sha256: z.ZodString;
|
|
16
|
+
sizeBytes: z.ZodNumber;
|
|
17
|
+
contentType: z.ZodString;
|
|
18
|
+
originalName: z.ZodString;
|
|
19
|
+
createdBy: z.ZodNullable<z.ZodString>;
|
|
20
|
+
createdAt: z.ZodString;
|
|
21
|
+
}, z.core.$strip>>;
|
|
22
|
+
nextCursor: z.ZodNullable<z.ZodString>;
|
|
23
|
+
}, z.core.$strip>;
|
|
24
|
+
export declare const fileUploadedSchema: z.ZodObject<{
|
|
25
|
+
file: z.ZodObject<{
|
|
26
|
+
id: z.ZodString;
|
|
27
|
+
sha256: z.ZodString;
|
|
28
|
+
sizeBytes: z.ZodNumber;
|
|
29
|
+
contentType: z.ZodString;
|
|
30
|
+
originalName: z.ZodString;
|
|
31
|
+
createdBy: z.ZodNullable<z.ZodString>;
|
|
32
|
+
createdAt: z.ZodString;
|
|
33
|
+
}, z.core.$strip>;
|
|
34
|
+
deduplicated: z.ZodBoolean;
|
|
35
|
+
}, z.core.$strip>;
|
|
36
|
+
export declare const fileUploadQuerySchema: z.ZodObject<{
|
|
37
|
+
name: z.ZodString;
|
|
38
|
+
}, z.core.$strip>;
|
|
39
|
+
//# sourceMappingURL=files.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../../src/schemas/files.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,UAAU;;;;;;;;iBASrB,CAAC;AACH,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,UAAU,CAAC,CAAC;AAElD,eAAO,MAAM,eAAe;;;;;;;;;;;iBAG1B,CAAC;AAEH,eAAO,MAAM,kBAAkB;;;;;;;;;;;iBAI7B,CAAC;AAEH,eAAO,MAAM,qBAAqB;;iBAGhC,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { plainText } from './common.js';
|
|
3
|
+
export const fileSchema = z.object({
|
|
4
|
+
id: z.string(),
|
|
5
|
+
sha256: z.string(),
|
|
6
|
+
sizeBytes: z.number(),
|
|
7
|
+
contentType: z.string(),
|
|
8
|
+
originalName: z.string(),
|
|
9
|
+
/** Null once the uploader's account was deleted (files are workspace data). */
|
|
10
|
+
createdBy: z.string().nullable(),
|
|
11
|
+
createdAt: z.string()
|
|
12
|
+
});
|
|
13
|
+
export const filesListSchema = z.object({
|
|
14
|
+
files: z.array(fileSchema),
|
|
15
|
+
nextCursor: z.string().nullable()
|
|
16
|
+
});
|
|
17
|
+
export const fileUploadedSchema = z.object({
|
|
18
|
+
file: fileSchema,
|
|
19
|
+
/** True when identical bytes already existed for this workspace. */
|
|
20
|
+
deduplicated: z.boolean()
|
|
21
|
+
});
|
|
22
|
+
export const fileUploadQuerySchema = z.object({
|
|
23
|
+
/** Original filename (the body is the raw bytes). */
|
|
24
|
+
name: plainText(1, 255)
|
|
25
|
+
});
|
|
26
|
+
//# sourceMappingURL=files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files.js","sourceRoot":"","sources":["../../src/schemas/files.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC;IACjC,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE;IACd,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;IAClB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;IACvB,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE;IACxB,+EAA+E;IAC/E,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAChC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;CACtB,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC;IACtC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC;IAC1B,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAClC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,IAAI,EAAE,UAAU;IAChB,oEAAoE;IACpE,YAAY,EAAE,CAAC,CAAC,OAAO,EAAE;CAC1B,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5C,qDAAqD;IACrD,IAAI,EAAE,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC;CACxB,CAAC,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* GET /api/v1/instance — unauthenticated, cacheable discovery. This is what
|
|
4
|
+
* CLIs and MCP clients read to route: which auth methods exist, whether
|
|
5
|
+
* first-boot setup is still pending, and what the instance is.
|
|
6
|
+
*/
|
|
7
|
+
export declare const instanceInfoSchema: z.ZodObject<{
|
|
8
|
+
name: z.ZodString;
|
|
9
|
+
instanceId: z.ZodNullable<z.ZodString>;
|
|
10
|
+
edition: z.ZodString;
|
|
11
|
+
version: z.ZodString;
|
|
12
|
+
apiVersion: z.ZodLiteral<"v1">;
|
|
13
|
+
setupRequired: z.ZodBoolean;
|
|
14
|
+
auth: z.ZodObject<{
|
|
15
|
+
methods: z.ZodArray<z.ZodUnion<[z.ZodEnum<{
|
|
16
|
+
password: "password";
|
|
17
|
+
oauth: "oauth";
|
|
18
|
+
"email-otp": "email-otp";
|
|
19
|
+
google: "google";
|
|
20
|
+
"api-key": "api-key";
|
|
21
|
+
antasphere: "antasphere";
|
|
22
|
+
}>, z.ZodString]>>;
|
|
23
|
+
passwordReset: z.ZodBoolean;
|
|
24
|
+
emailChange: z.ZodBoolean;
|
|
25
|
+
twoFactor: z.ZodBoolean;
|
|
26
|
+
sso: z.ZodOptional<z.ZodObject<{
|
|
27
|
+
hintCookieName: z.ZodString;
|
|
28
|
+
hintCookieDomain: z.ZodString;
|
|
29
|
+
}, z.core.$strip>>;
|
|
30
|
+
}, z.core.$strip>;
|
|
31
|
+
features: z.ZodObject<{
|
|
32
|
+
mcp: z.ZodBoolean;
|
|
33
|
+
oauth: z.ZodBoolean;
|
|
34
|
+
files: z.ZodBoolean;
|
|
35
|
+
}, z.core.$strip>;
|
|
36
|
+
demoSignIn: z.ZodOptional<z.ZodBoolean>;
|
|
37
|
+
restricted: z.ZodOptional<z.ZodBoolean>;
|
|
38
|
+
entitlements: z.ZodOptional<z.ZodObject<{
|
|
39
|
+
actions: z.ZodArray<z.ZodObject<{
|
|
40
|
+
key: z.ZodString;
|
|
41
|
+
creditsPerUnit: z.ZodNumber;
|
|
42
|
+
unit: z.ZodString;
|
|
43
|
+
per: z.ZodOptional<z.ZodNumber>;
|
|
44
|
+
label: z.ZodString;
|
|
45
|
+
}, z.core.$strip>>;
|
|
46
|
+
limits: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
47
|
+
oss: z.ZodNullable<z.ZodNumber>;
|
|
48
|
+
free: z.ZodNullable<z.ZodNumber>;
|
|
49
|
+
pro: z.ZodNullable<z.ZodNumber>;
|
|
50
|
+
}, z.core.$strip>>;
|
|
51
|
+
features: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
52
|
+
free: z.ZodBoolean;
|
|
53
|
+
pro: z.ZodBoolean;
|
|
54
|
+
}, z.core.$strip>>;
|
|
55
|
+
}, z.core.$strip>>;
|
|
56
|
+
}, z.core.$strip>;
|
|
57
|
+
export type InstanceInfo = z.infer<typeof instanceInfoSchema>;
|
|
58
|
+
//# sourceMappingURL=instance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instance.d.ts","sourceRoot":"","sources":["../../src/schemas/instance.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB;;;;GAIG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA4D7B,CAAC;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC"}
|