@spacefast/common 0.0.12 → 0.0.17
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/agents/client-registry.d.ts +22 -0
- package/dist/agents/client-registry.js +41 -0
- package/dist/agents/connect-targets.d.ts +51 -6
- package/dist/agents/connect-targets.js +93 -28
- package/dist/brand.d.ts +0 -11
- package/dist/brand.js +0 -20
- package/dist/config/domains.d.ts +15 -6
- package/dist/config/domains.js +24 -10
- package/dist/config/postgres-budget.d.ts +3 -0
- package/dist/config/postgres-budget.js +6 -1
- package/dist/config/postgres-budget.json +2 -1
- package/dist/contracts/abuse.js +1 -1
- package/dist/contracts/access.d.ts +486 -1196
- package/dist/contracts/access.js +323 -1054
- package/dist/contracts/activity.d.ts +1 -1
- package/dist/contracts/activity.js +11 -15
- package/dist/contracts/api-keys.d.ts +16 -0
- package/dist/contracts/api-keys.js +11 -9
- package/dist/contracts/archives.d.ts +1 -2
- package/dist/contracts/archives.js +15 -17
- package/dist/contracts/beta.js +1 -1
- package/dist/contracts/builds.js +14 -14
- package/dist/contracts/channels.js +2 -2
- package/dist/contracts/comments.d.ts +143 -99
- package/dist/contracts/comments.js +194 -79
- package/dist/contracts/common.d.ts +12 -12
- package/dist/contracts/common.js +33 -30
- package/dist/contracts/continuation.js +5 -5
- package/dist/contracts/countries.js +2 -7
- package/dist/contracts/data-source-routes.d.ts +20 -0
- package/dist/contracts/data-source-routes.js +15 -0
- package/dist/contracts/device-auth.d.ts +13 -9
- package/dist/contracts/device-auth.js +12 -12
- package/dist/contracts/docs.d.ts +10 -10
- package/dist/contracts/domains.js +39 -33
- package/dist/contracts/enums.d.ts +4 -14
- package/dist/contracts/enums.js +3 -10
- package/dist/contracts/error-code-meta.d.ts +122 -56
- package/dist/contracts/error-code-meta.js +43 -19
- package/dist/contracts/error-codes.d.ts +7 -4
- package/dist/contracts/error-codes.js +48 -24
- package/dist/contracts/events.d.ts +22 -15
- package/dist/contracts/events.js +33 -5
- package/dist/contracts/execution.d.ts +238 -0
- package/dist/contracts/execution.js +309 -0
- package/dist/contracts/feature-lifecycle.d.ts +39 -188
- package/dist/contracts/feature-lifecycle.js +52 -196
- package/dist/contracts/features.d.ts +13 -115
- package/dist/contracts/features.js +5 -35
- package/dist/contracts/functions.d.ts +597 -0
- package/dist/contracts/functions.js +475 -0
- package/dist/contracts/grants.d.ts +1175 -0
- package/dist/contracts/grants.js +783 -0
- package/dist/contracts/ids.d.ts +7 -5
- package/dist/contracts/ids.js +7 -7
- package/dist/contracts/internal.js +2 -2
- package/dist/contracts/mcp.d.ts +17 -556
- package/dist/contracts/mcp.js +9 -103
- package/dist/contracts/me.js +3 -4
- package/dist/contracts/notifications.d.ts +108 -0
- package/dist/contracts/notifications.js +54 -0
- package/dist/contracts/oauth-resources.d.ts +22 -5
- package/dist/contracts/oauth-resources.js +23 -2
- package/dist/contracts/operations.d.ts +0 -48
- package/dist/contracts/operations.js +0 -19
- package/dist/contracts/pages.d.ts +10 -14
- package/dist/contracts/pages.js +17 -21
- package/dist/contracts/plan-policy.d.ts +1 -8
- package/dist/contracts/plan-policy.js +1 -4
- package/dist/contracts/platform.d.ts +78 -30
- package/dist/contracts/platform.js +69 -20
- package/dist/contracts/problem-document.d.ts +14 -0
- package/dist/contracts/problem-document.js +35 -0
- package/dist/contracts/push-new.d.ts +41 -2
- package/dist/contracts/push-new.js +4 -0
- package/dist/contracts/quotas.d.ts +0 -1
- package/dist/contracts/quotas.js +0 -5
- package/dist/contracts/repository-connections.d.ts +1 -1
- package/dist/contracts/resources.d.ts +16 -71
- package/dist/contracts/resources.js +13 -16
- package/dist/contracts/runtime-api.d.ts +666 -303
- package/dist/contracts/runtime-api.js +272 -113
- package/dist/contracts/runtime-app.d.ts +168 -0
- package/dist/contracts/runtime-app.js +42 -0
- package/dist/contracts/runtime-db.d.ts +424 -0
- package/dist/contracts/runtime-db.js +108 -0
- package/dist/contracts/runtime-storage.d.ts +120 -0
- package/dist/contracts/runtime-storage.js +40 -0
- package/dist/contracts/sf-config-v1.d.ts +54 -1
- package/dist/contracts/sf-config-v1.js +2 -2
- package/dist/contracts/sites.d.ts +6 -0
- package/dist/contracts/sites.js +30 -11
- package/dist/contracts/space-config.d.ts +91 -121
- package/dist/contracts/space-config.js +464 -42
- package/dist/contracts/spaces.d.ts +300 -171
- package/dist/contracts/spaces.js +128 -98
- package/dist/contracts/superadmin-emails.d.ts +2 -2
- package/dist/contracts/superadmin-spaces.d.ts +26 -130
- package/dist/contracts/superadmin-spaces.js +22 -0
- package/dist/contracts/superadmin-tenants.js +4 -4
- package/dist/contracts/superadmin.d.ts +4 -0
- package/dist/contracts/superadmin.js +14 -1
- package/dist/contracts/tags.d.ts +6 -6
- package/dist/contracts/tags.js +1 -1
- package/dist/contracts/teams.d.ts +9 -9
- package/dist/contracts/teams.js +25 -16
- package/dist/contracts/theme-json.js +1 -1
- package/dist/contracts/transfers.d.ts +0 -1
- package/dist/contracts/transfers.js +4 -4
- package/dist/contracts/variables.js +3 -3
- package/dist/contracts/zero.d.ts +384 -596
- package/dist/contracts/zero.js +167 -299
- package/dist/dashboard-paths/index.d.ts +18 -3
- package/dist/dashboard-paths/index.js +19 -0
- package/dist/docs/agent-handoff-document.d.ts +2 -2
- package/dist/docs/agent-handoff-document.js +8 -7
- package/dist/docs/agent-prose.d.ts +22 -3
- package/dist/docs/agent-prose.js +227 -55
- package/dist/docs/agent-setup.d.ts +14 -11
- package/dist/docs/agent-setup.js +289 -61
- package/dist/docs/agent-solutions.d.ts +6 -6
- package/dist/docs/agent-solutions.js +24 -22
- package/dist/docs/catalog.d.ts +53 -98
- package/dist/docs/catalog.js +90 -117
- package/dist/docs/error-docs.js +304 -236
- package/dist/docs/skill-distribution.d.ts +2 -0
- package/dist/docs/skill-distribution.js +7 -4
- package/dist/docs/skills.d.ts +546 -0
- package/dist/docs/skills.js +340 -0
- package/dist/utils/auth-redirect.d.ts +1 -3
- package/dist/utils/auth-redirect.js +1 -21
- package/dist/utils/browser-credential.d.ts +19 -0
- package/dist/utils/browser-credential.js +62 -0
- package/dist/utils/build-settings.d.ts +2 -0
- package/dist/utils/build-settings.js +61 -9
- package/dist/utils/comment-avatars.d.ts +7 -0
- package/dist/utils/comment-avatars.js +42 -0
- package/dist/utils/content-type.d.ts +3 -3
- package/dist/utils/content-type.js +38 -61
- package/dist/utils/credential-policy.d.ts +1 -1
- package/dist/utils/credential-policy.js +4 -0
- package/dist/utils/domain-diagnostics.d.ts +5 -5
- package/dist/utils/domain-diagnostics.js +21 -10
- package/dist/utils/egress-policy.fixtures.json +1 -1
- package/dist/utils/grants.d.ts +53 -0
- package/dist/utils/grants.js +160 -0
- package/dist/utils/local-space-state.d.ts +78 -4
- package/dist/utils/local-space-state.js +384 -82
- package/dist/utils/one-shot-replay.d.ts +14 -0
- package/dist/utils/one-shot-replay.js +21 -0
- package/dist/utils/page-preview.d.ts +7 -0
- package/dist/utils/page-preview.js +9 -0
- package/dist/utils/pages.d.ts +2 -5
- package/dist/utils/pages.js +64 -33
- package/dist/utils/publish-form-data.d.ts +22 -0
- package/dist/utils/publish-form-data.js +26 -0
- package/dist/utils/publish-policy.d.ts +34 -4
- package/dist/utils/publish-policy.js +149 -62
- package/dist/utils/query-keys.d.ts +8 -10
- package/dist/utils/query-keys.js +14 -10
- package/dist/utils/runtime-paths.d.ts +3 -0
- package/dist/utils/runtime-paths.js +7 -0
- package/dist/utils/secure-local-file.d.ts +73 -0
- package/dist/utils/secure-local-file.js +1373 -0
- package/dist/utils/space-config.d.ts +17 -4
- package/dist/utils/space-config.js +151 -8
- package/dist/utils/static-runtime-policy.d.ts +5 -0
- package/dist/utils/static-runtime-policy.js +54 -10
- package/dist/utils/storage-policy.d.ts +20 -0
- package/dist/utils/storage-policy.fixtures.json +174 -0
- package/dist/utils/storage-policy.js +193 -0
- package/dist/utils/upload-session.d.ts +15 -1
- package/dist/utils/upload-session.js +68 -2
- package/dist/utils/version-file-browser.d.ts +13 -0
- package/dist/utils/version-file-browser.js +59 -0
- package/package.json +20 -1
- package/dist/contracts/mounts.d.ts +0 -142
- package/dist/contracts/mounts.js +0 -56
- package/dist/utils/access-grant.d.ts +0 -14
- package/dist/utils/access-grant.js +0 -88
- package/dist/utils/access-match.d.ts +0 -46
- package/dist/utils/access-match.fixtures.json +0 -513
- package/dist/utils/access-match.js +0 -312
- package/dist/utils/access-verdict.fixtures.json +0 -421
- package/dist/utils/asset-fingerprint.d.ts +0 -53
- package/dist/utils/asset-fingerprint.js +0 -574
- package/dist/utils/sf-config-v1.d.ts +0 -2
- package/dist/utils/sf-config-v1.fixtures.json +0 -9
- package/dist/utils/sf-config-v1.js +0 -551
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
import { accessRoleSchema, authorityReferenceSchema } from "./access.js";
|
|
2
3
|
import { CursorPaginationSchema, cursorListQuerySchema } from "./common.js";
|
|
3
4
|
export const commentThreadStatusSchema = z.enum(["open", "archived"]);
|
|
4
5
|
export const COMMENT_SEARCH_QUERY_MAX_LENGTH = 160;
|
|
@@ -6,28 +7,147 @@ export function normalizeCommentSearchQuery(value) {
|
|
|
6
7
|
const trimmed = value?.trim();
|
|
7
8
|
return trimmed ? trimmed.slice(0, COMMENT_SEARCH_QUERY_MAX_LENGTH) : undefined;
|
|
8
9
|
}
|
|
9
|
-
// The space access levels capability follows (SPACEFAST-CAST-PLAN D-2). Invited
|
|
10
|
-
// reviewers are space invitees with one of these levels; the on-page overlay and
|
|
11
|
-
// inbox re-evaluate the effective level server-side at join — this is only the
|
|
12
|
-
// stored grant the dashboard manages.
|
|
13
|
-
export const collaborationReviewerLevelSchema = z.enum(["viewer", "commenter", "editor"]);
|
|
14
10
|
export const COMMENT_PAGE_PATH_MAX_LENGTH = 2_048;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
11
|
+
const COMMENT_CAPABILITIES = ["page.view", "comments.read", "comments.write"];
|
|
12
|
+
export const commentCapabilitiesSchema = z
|
|
13
|
+
.array(z.enum(COMMENT_CAPABILITIES))
|
|
14
|
+
.min(2)
|
|
15
|
+
.max(3)
|
|
16
|
+
.refine((capabilities) => new Set(capabilities).size === capabilities.length, {
|
|
17
|
+
message: "comment capabilities must be unique",
|
|
18
|
+
})
|
|
19
|
+
.superRefine((capabilities, context) => {
|
|
20
|
+
if (capabilities.includes("comments.write") && !capabilities.includes("comments.read")) {
|
|
21
|
+
context.addIssue({
|
|
22
|
+
code: "custom",
|
|
23
|
+
message: "comments.write requires comments.read",
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
if (capabilities.includes("comments.read") && !capabilities.includes("page.view")) {
|
|
27
|
+
context.addIssue({
|
|
28
|
+
code: "custom",
|
|
29
|
+
message: "comments.read requires page.view",
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
export const collaborationGuestProjectionSchema = z.object({
|
|
34
|
+
anonymousId: z.string().min(8).max(160),
|
|
35
|
+
// No control or format characters: newlines, bidi overrides, and zero-width
|
|
36
|
+
// joiners in a self-asserted display name are only ever spoofing material.
|
|
37
|
+
name: z
|
|
38
|
+
.string()
|
|
39
|
+
.trim()
|
|
40
|
+
.min(1)
|
|
41
|
+
.max(160)
|
|
42
|
+
.regex(/^[^\p{Cc}\p{Cf}]+$/u),
|
|
43
|
+
namedByUser: z.boolean(),
|
|
44
|
+
grantId: z.string().min(1).max(128),
|
|
45
|
+
admittedBy: z.union([
|
|
46
|
+
z.literal("anyone"),
|
|
47
|
+
z.templateLiteral(["link:", z.string().regex(/^[A-Za-z0-9_.-]+$/)]),
|
|
48
|
+
z.templateLiteral(["password:", z.string().regex(/^[A-Za-z0-9_.-]+$/)]),
|
|
49
|
+
]),
|
|
50
|
+
emailVerified: z.boolean().default(false),
|
|
51
|
+
capabilities: commentCapabilitiesSchema,
|
|
52
|
+
});
|
|
53
|
+
// The identity a browser asserts when requesting a guest ticket — the
|
|
54
|
+
// self-asserted subset of the guest projection.
|
|
55
|
+
export const commentsGuestIdentitySchema = collaborationGuestProjectionSchema.pick({
|
|
56
|
+
anonymousId: true,
|
|
57
|
+
name: true,
|
|
58
|
+
namedByUser: true,
|
|
59
|
+
});
|
|
60
|
+
export function commentCapabilitiesOf(capabilities) {
|
|
61
|
+
return capabilities.filter((capability) => COMMENT_CAPABILITIES.includes(capability));
|
|
62
|
+
}
|
|
63
|
+
// The only account metadata exposed to Comments clients. Keep this shape
|
|
64
|
+
// deliberately smaller than the private account record carried server-side.
|
|
65
|
+
export const collaborationPublicProfileSchema = z
|
|
66
|
+
.object({
|
|
67
|
+
name: z.string().trim().min(1).max(120).nullable(),
|
|
68
|
+
username: z.string().trim().min(1).max(160).nullable(),
|
|
69
|
+
avatar_url: z
|
|
70
|
+
.url({ protocol: /^https?$/ })
|
|
71
|
+
.max(2_048)
|
|
72
|
+
.nullable(),
|
|
73
|
+
})
|
|
74
|
+
.strict();
|
|
75
|
+
export const collaborationTicketClaimsSchema = z
|
|
76
|
+
.object({
|
|
77
|
+
sub: z.string().min(1),
|
|
78
|
+
email: z.string().email().optional(),
|
|
79
|
+
profile: collaborationPublicProfileSchema.optional(),
|
|
80
|
+
role: accessRoleSchema,
|
|
81
|
+
// The session's principal, never the class of authority that admitted it:
|
|
82
|
+
// a signed-in account is "user" even when a share Link carried it in.
|
|
83
|
+
actorKind: z.enum(["user", "guest"]),
|
|
84
|
+
authorities: z.array(authorityReferenceSchema).max(16).optional(),
|
|
85
|
+
capabilities: commentCapabilitiesSchema,
|
|
86
|
+
anonymousId: z.string().min(8).max(160).optional(),
|
|
87
|
+
grantId: z.string().min(1).max(128).optional(),
|
|
88
|
+
namedByUser: z.boolean().optional(),
|
|
89
|
+
admittedBy: z
|
|
90
|
+
.union([
|
|
91
|
+
z.literal("anyone"),
|
|
92
|
+
z.templateLiteral(["link:", z.string().regex(/^[A-Za-z0-9_.-]+$/)]),
|
|
93
|
+
z.templateLiteral(["password:", z.string().regex(/^[A-Za-z0-9_.-]+$/)]),
|
|
94
|
+
])
|
|
95
|
+
.optional(),
|
|
96
|
+
emailVerified: z.boolean().optional(),
|
|
97
|
+
room: z.string().min(1).max(4_096),
|
|
98
|
+
scope: z.string().min(1).max(COMMENT_PAGE_PATH_MAX_LENGTH),
|
|
99
|
+
surface: z.enum(["published", "preview"]),
|
|
100
|
+
nonce: z.string().min(1).max(160),
|
|
101
|
+
iat: z.number().int(),
|
|
102
|
+
nbf: z.number().int(),
|
|
103
|
+
exp: z.number().int(),
|
|
104
|
+
iss: z.literal("spacefast-api"),
|
|
105
|
+
aud: z.string().min(1),
|
|
106
|
+
})
|
|
107
|
+
.superRefine((claims, context) => {
|
|
108
|
+
if (claims.actorKind !== "guest")
|
|
109
|
+
return;
|
|
110
|
+
// A guest ticket names an anonymous browser identity, and one grant always
|
|
111
|
+
// admitted it: the guest projection the mint builds carries all five of
|
|
112
|
+
// these or it is not a guest at all. Capabilities still come from the union
|
|
113
|
+
// of every authority the session holds — the admitting grant describes the
|
|
114
|
+
// admission, not the reach.
|
|
115
|
+
for (const field of [
|
|
116
|
+
"anonymousId",
|
|
117
|
+
"grantId",
|
|
118
|
+
"namedByUser",
|
|
119
|
+
"admittedBy",
|
|
120
|
+
"emailVerified",
|
|
121
|
+
]) {
|
|
122
|
+
if (claims[field] === undefined) {
|
|
123
|
+
context.addIssue({
|
|
124
|
+
code: "custom",
|
|
125
|
+
path: [field],
|
|
126
|
+
message: `${field} is required for a guest ticket`,
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
// Identity never follows from an authority, but the reverse still holds:
|
|
131
|
+
// an anonymous principal can only ever have acquired credential-class
|
|
132
|
+
// authorities. Account-class references on a guest ticket are a forgery.
|
|
133
|
+
for (const [index, authority] of (claims.authorities ?? []).entries()) {
|
|
134
|
+
if (!authority.startsWith("link:") && !authority.startsWith("password:")) {
|
|
135
|
+
context.addIssue({
|
|
136
|
+
code: "custom",
|
|
137
|
+
path: ["authorities", index],
|
|
138
|
+
message: "a guest ticket carries only link or password authorities",
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
}
|
|
20
142
|
});
|
|
21
143
|
export const collaborationSettingsSchema = z
|
|
22
144
|
.object({
|
|
23
|
-
anonymousReviewers: z.boolean().optional(),
|
|
24
|
-
publishedAnonymousCommenters: z.boolean().optional(),
|
|
25
145
|
spamFilterEnabled: z.boolean().optional(),
|
|
26
|
-
invitedReviewers: z.array(collaborationInvitedReviewerSchema).optional(),
|
|
27
146
|
// Whether comments are surfaced on the live/published host (vs preview-only).
|
|
28
147
|
// The published loader (SPACEFAST-CAST-PLAN §4.2) mounts the orb on a live
|
|
29
148
|
// host only when this is true; toggling it never requires a republish — the
|
|
30
|
-
// always-injected inert tag reads
|
|
149
|
+
// always-injected inert tag re-reads it through the runtime's same-origin
|
|
150
|
+
// Comments config exchange on every load.
|
|
31
151
|
publishedComments: z.boolean().optional(),
|
|
32
152
|
notificationPreferences: z
|
|
33
153
|
.object({
|
|
@@ -39,8 +159,23 @@ export const collaborationSettingsSchema = z
|
|
|
39
159
|
.optional(),
|
|
40
160
|
})
|
|
41
161
|
.strict();
|
|
162
|
+
const collaborationSettingsPatchSchema = z
|
|
163
|
+
.object({
|
|
164
|
+
spamFilterEnabled: z.boolean().optional(),
|
|
165
|
+
publishedComments: z.boolean().optional(),
|
|
166
|
+
notificationPreferences: z
|
|
167
|
+
.object({
|
|
168
|
+
newThreads: z.boolean().optional(),
|
|
169
|
+
newReplies: z.boolean().optional(),
|
|
170
|
+
statusChanges: z.boolean().optional(),
|
|
171
|
+
})
|
|
172
|
+
.strict()
|
|
173
|
+
.optional(),
|
|
174
|
+
})
|
|
175
|
+
.strict();
|
|
42
176
|
export const collaborationSchema = z.object({
|
|
43
177
|
spaceId: z.string(),
|
|
178
|
+
revision: z.number().int().nonnegative(),
|
|
44
179
|
enabled: z.boolean(),
|
|
45
180
|
castResourceId: z.string().nullable(),
|
|
46
181
|
castResourceKey: z.string().nullable(),
|
|
@@ -48,17 +183,23 @@ export const collaborationSchema = z.object({
|
|
|
48
183
|
createdAt: z.string().datetime().nullable(),
|
|
49
184
|
updatedAt: z.string().datetime().nullable(),
|
|
50
185
|
});
|
|
51
|
-
export const collaborationUpdateSchema = z
|
|
52
|
-
|
|
53
|
-
|
|
186
|
+
export const collaborationUpdateSchema = z
|
|
187
|
+
.object({
|
|
188
|
+
expectedRevision: z.number().int().nonnegative(),
|
|
189
|
+
enabled: z.boolean().optional(),
|
|
190
|
+
settings: collaborationSettingsPatchSchema.optional(),
|
|
191
|
+
})
|
|
192
|
+
.refine((update) => update.enabled !== undefined || update.settings !== undefined, {
|
|
193
|
+
message: "At least one collaboration field is required",
|
|
54
194
|
});
|
|
55
|
-
export const
|
|
56
|
-
|
|
195
|
+
export const commentsTicketRequestSchema = z.object({
|
|
196
|
+
spaceId: z.string().min(1),
|
|
57
197
|
pagePath: z.string().min(1).max(COMMENT_PAGE_PATH_MAX_LENGTH).default("/"),
|
|
58
|
-
|
|
59
|
-
|
|
198
|
+
origin: z.string().url(),
|
|
199
|
+
versionId: z.string().min(1).optional(),
|
|
200
|
+
identity: commentsGuestIdentitySchema.optional(),
|
|
60
201
|
});
|
|
61
|
-
export const
|
|
202
|
+
export const commentsTicketResponseSchema = z.object({
|
|
62
203
|
token: z.string(),
|
|
63
204
|
expiresAt: z.string().datetime(),
|
|
64
205
|
cast: z.object({
|
|
@@ -66,18 +207,6 @@ export const collaborationTokenResponseSchema = z.object({
|
|
|
66
207
|
room: z.string(),
|
|
67
208
|
}),
|
|
68
209
|
});
|
|
69
|
-
export const collaborationHandoffRequestSchema = z.object({
|
|
70
|
-
versionId: z.string().min(1),
|
|
71
|
-
pagePath: z.string().min(1).max(COMMENT_PAGE_PATH_MAX_LENGTH).default("/"),
|
|
72
|
-
});
|
|
73
|
-
export const collaborationHandoffResponseSchema = z.object({
|
|
74
|
-
handoffToken: z.string(),
|
|
75
|
-
expiresAt: z.string().datetime(),
|
|
76
|
-
url: z.string().url().nullable(),
|
|
77
|
-
});
|
|
78
|
-
export const collaborationHandoffExchangeSchema = z.object({
|
|
79
|
-
handoffToken: z.string().min(16),
|
|
80
|
-
});
|
|
81
210
|
export const realtimeTokenRequestSchema = z.object({
|
|
82
211
|
versionId: z.string().optional(),
|
|
83
212
|
scope: z.enum(["space", "version"]).default("space"),
|
|
@@ -105,52 +234,9 @@ export const noticePublishResponseSchema = z.object({
|
|
|
105
234
|
event: z.record(z.string(), z.unknown()).nullable(),
|
|
106
235
|
broadcast: z.record(z.string(), z.unknown()).nullable(),
|
|
107
236
|
});
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
versionId: z.string().min(1).optional(),
|
|
111
|
-
host: z.string().min(1).optional(),
|
|
112
|
-
});
|
|
113
|
-
// Snake case is intentional: the injected Collab SDK consumes this alongside
|
|
114
|
-
// Cast's snake-case join payload without a remapping layer.
|
|
115
|
-
export const collabOverlayConfigSchema = z.object({
|
|
116
|
-
enabled: z.boolean(),
|
|
117
|
-
anonymous_commenters: z.boolean(),
|
|
118
|
-
resource_key: z.string().nullable(),
|
|
119
|
-
room_key: z.string().nullable(),
|
|
120
|
-
version: z.object({
|
|
121
|
-
id: z.string().nullable(),
|
|
122
|
-
current: z.string().nullable(),
|
|
123
|
-
// The viewed version's immutable URL; null when unknown (live context).
|
|
124
|
-
url: z.string().nullable(),
|
|
125
|
-
}),
|
|
126
|
-
// The space's canonical live/published URL; null when comments-on-live is the
|
|
127
|
-
// current context (you're already there) or no live URL exists.
|
|
128
|
-
space: z.object({
|
|
129
|
-
live_url: z.string().nullable(),
|
|
130
|
-
}),
|
|
131
|
-
ws_url: z.string().nullable(),
|
|
132
|
-
endpoints: z.object({
|
|
133
|
-
token: z.string().url(),
|
|
134
|
-
handoff_exchange: z.string().url(),
|
|
135
|
-
auth_bridge: z.string().url(),
|
|
136
|
-
screenshots: z.string().url(),
|
|
137
|
-
}),
|
|
138
|
-
features: z.object({
|
|
139
|
-
drawing: z.boolean(),
|
|
140
|
-
capture: z.boolean(),
|
|
141
|
-
notices: z.boolean(),
|
|
142
|
-
}),
|
|
143
|
-
});
|
|
144
|
-
// Cross-version navigation directory (§5 "versions are native"): the SDK asks
|
|
145
|
-
// for the immutable URLs of the version ids present in a room's threads so
|
|
146
|
-
// "Open this comment on v12" is a real link. Gated exactly like the overlay
|
|
147
|
-
// config — disabled comments never leak version URLs.
|
|
237
|
+
// Cross-version navigation directory: the Comments overlay asks for the
|
|
238
|
+
// immutable URLs of version ids present in a room's threads.
|
|
148
239
|
export const COLLAB_VERSION_URLS_MAX_IDS = 50;
|
|
149
|
-
export const collabVersionUrlsQuerySchema = collabOverlayConfigQuerySchema.extend({
|
|
150
|
-
// Comma-separated version ids; the route caps the lookup at
|
|
151
|
-
// COLLAB_VERSION_URLS_MAX_IDS ids.
|
|
152
|
-
ids: z.string().min(1).max(4_096),
|
|
153
|
-
});
|
|
154
240
|
export const collabVersionUrlSchema = z.object({
|
|
155
241
|
id: z.string(),
|
|
156
242
|
url: z.string(),
|
|
@@ -162,10 +248,28 @@ export const collabVersionUrlSchema = z.object({
|
|
|
162
248
|
export const commentAuthorSchema = z.object({
|
|
163
249
|
kind: z.string().nullable(),
|
|
164
250
|
id: z.string().nullable(),
|
|
251
|
+
profileId: z.string().nullable(),
|
|
165
252
|
name: z.string().nullable(),
|
|
253
|
+
username: z.string().max(160).nullable(),
|
|
254
|
+
avatarUrl: z
|
|
255
|
+
.url({ protocol: /^https?$/ })
|
|
256
|
+
.max(2_048)
|
|
257
|
+
.nullable(),
|
|
166
258
|
color: z.string().max(64).nullable(),
|
|
167
259
|
});
|
|
168
260
|
export const commentTargetSchema = z.record(z.string(), z.unknown()).nullable();
|
|
261
|
+
export const commentReactionActorSchema = z.object({
|
|
262
|
+
name: z.string().nullable(),
|
|
263
|
+
});
|
|
264
|
+
export const commentReactionEntrySchema = z.object({
|
|
265
|
+
count: z.number().int().min(0),
|
|
266
|
+
actors: z.record(z.string(), commentReactionActorSchema),
|
|
267
|
+
});
|
|
268
|
+
export const COMMENT_REACTION_EMOJIS = ["👍", "❤️", "🎉", "👀", "🚀", "🙏"];
|
|
269
|
+
export const commentReactionUpdateSchema = z.object({
|
|
270
|
+
emoji: z.enum(COMMENT_REACTION_EMOJIS),
|
|
271
|
+
op: z.enum(["add", "remove"]),
|
|
272
|
+
});
|
|
169
273
|
export const commentThreadSchema = z.object({
|
|
170
274
|
id: z.string(),
|
|
171
275
|
castThreadId: z.string(),
|
|
@@ -182,6 +286,7 @@ export const commentThreadSchema = z.object({
|
|
|
182
286
|
body: z.string().nullable(),
|
|
183
287
|
author: commentAuthorSchema.nullable(),
|
|
184
288
|
target: commentTargetSchema,
|
|
289
|
+
reactions: z.record(z.string(), commentReactionEntrySchema),
|
|
185
290
|
comments: z.array(z.record(z.string(), z.unknown())),
|
|
186
291
|
permalink: z.string().nullable(),
|
|
187
292
|
updatedAt: z.string().datetime().nullable(),
|
|
@@ -218,6 +323,16 @@ export const commentScreenshotSchema = z.object({
|
|
|
218
323
|
url: z.string().url(),
|
|
219
324
|
expiresAt: z.string().datetime(),
|
|
220
325
|
});
|
|
326
|
+
export const commentScreenshotRefreshSchema = z.object({
|
|
327
|
+
versionId: z.string().min(1),
|
|
328
|
+
pagePath: z.string().min(1).max(COMMENT_PAGE_PATH_MAX_LENGTH).default("/"),
|
|
329
|
+
key: z.string().min(1).max(2_048),
|
|
330
|
+
});
|
|
331
|
+
export const commentScreenshotRefreshResponseSchema = z.object({
|
|
332
|
+
key: z.string(),
|
|
333
|
+
url: z.string().url(),
|
|
334
|
+
expiresAt: z.string().datetime(),
|
|
335
|
+
});
|
|
221
336
|
export const commentReplySchema = z.object({
|
|
222
337
|
body: z.string().min(1).max(16_000),
|
|
223
338
|
idempotencyKey: z.string().min(1).max(320).optional(),
|
|
@@ -102,19 +102,19 @@ export declare const requiredActionsSchema: z.ZodArray<z.ZodDiscriminatedUnion<[
|
|
|
102
102
|
type: z.ZodLiteral<"renew">;
|
|
103
103
|
domainId: z.ZodString;
|
|
104
104
|
}, z.core.$strip>], "type">>;
|
|
105
|
-
export declare const
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
105
|
+
export declare const ProblemDetailsSchema: z.ZodObject<{
|
|
106
|
+
type: z.ZodString;
|
|
107
|
+
title: z.ZodString;
|
|
108
|
+
status: z.ZodNumber;
|
|
109
|
+
detail: z.ZodString;
|
|
110
|
+
code: z.ZodString;
|
|
111
|
+
pointer: z.ZodOptional<z.ZodString>;
|
|
112
|
+
details: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
113
|
+
suggestions: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
114
|
+
next: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
115
|
+
requestId: z.ZodString;
|
|
116
116
|
}, z.core.$strip>;
|
|
117
|
-
export type
|
|
117
|
+
export type ProblemDetails = z.infer<typeof ProblemDetailsSchema>;
|
|
118
118
|
export declare function dataEnvelope<T extends z.ZodType>(data: T): z.ZodObject<{
|
|
119
119
|
data: T;
|
|
120
120
|
}, z.core.$strip>;
|
package/dist/contracts/common.js
CHANGED
|
@@ -18,7 +18,7 @@ export const baseDiagnosticSchema = z.object({
|
|
|
18
18
|
path: z
|
|
19
19
|
.string()
|
|
20
20
|
.nullish()
|
|
21
|
-
.describe('Artifact path the diagnostic points at,
|
|
21
|
+
.describe('Artifact path the diagnostic points at, for example "_headers:12", when one exists.'),
|
|
22
22
|
provider: diagnosticProvider
|
|
23
23
|
.nullish()
|
|
24
24
|
.describe("Upstream system the diagnostic originated from, when not Spacefast itself."),
|
|
@@ -30,7 +30,7 @@ export const baseDiagnosticSchema = z.object({
|
|
|
30
30
|
retryable: z
|
|
31
31
|
.boolean()
|
|
32
32
|
.nullish()
|
|
33
|
-
.describe("Whether retrying the same operation
|
|
33
|
+
.describe("Whether retrying the same operation can resolve this diagnostic without the caller changing anything."),
|
|
34
34
|
});
|
|
35
35
|
// Canonical DnsInstruction (internal-docs/platform.md L2500-2506): provider vocabulary
|
|
36
36
|
// never leaks into `purpose`.
|
|
@@ -64,31 +64,34 @@ export const requiredActionSchema = z.discriminatedUnion("type", [
|
|
|
64
64
|
export const requiredActionsSchema = z
|
|
65
65
|
.array(requiredActionSchema)
|
|
66
66
|
.describe("Concrete user steps that unblock this resource, using the one shared vocabulary.");
|
|
67
|
-
// The error
|
|
68
|
-
//
|
|
69
|
-
//
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
67
|
+
// The error shape (internal-docs/platform.md "Global API Conventions"): every 4xx/5xx body
|
|
68
|
+
// is one RFC 9457 problem details document served as `application/problem+json`. `type` and
|
|
69
|
+
// `title` are derived mechanically from `code` (see contracts/error-codes.ts); `code`,
|
|
70
|
+
// `pointer` (RFC 6901), `details`, `suggestions`, `next`, and `requestId` are extension members.
|
|
71
|
+
export const ProblemDetailsSchema = z.object({
|
|
72
|
+
type: z
|
|
73
|
+
.string()
|
|
74
|
+
.describe("Problem type URI. It resolves to the error docs page. The server derives it mechanically from `code` against the docs origin."),
|
|
75
|
+
title: z
|
|
76
|
+
.string()
|
|
77
|
+
.describe("Short human-readable summary of the problem type. The server derives it mechanically from `code`."),
|
|
78
|
+
status: z.number().int().describe("HTTP status code of this response, repeated in the body."),
|
|
79
|
+
detail: z.string().describe("Human-readable failure explanation for this occurrence."),
|
|
80
|
+
code: z.string().describe("Stable snake_case error code naming the failed public contract."),
|
|
81
|
+
pointer: z
|
|
82
|
+
.string()
|
|
83
|
+
.optional()
|
|
84
|
+
.describe('RFC 6901 JSON Pointer into the failing request field, for example "/files/37/path", on validation failures.'),
|
|
85
|
+
details: AnyObjectSchema.optional().describe("Machine-readable context for the error code."),
|
|
86
|
+
suggestions: z
|
|
87
|
+
.array(z.string())
|
|
88
|
+
.optional()
|
|
89
|
+
.describe("Actionable recovery steps safe to show in dashboards, SDKs, and CLI output."),
|
|
90
|
+
next: z
|
|
91
|
+
.array(z.string())
|
|
92
|
+
.optional()
|
|
93
|
+
.describe("Copy-pasteable commands or API requests an agent can run next."),
|
|
94
|
+
requestId: z.string().describe("The request id to quote when contacting support."),
|
|
92
95
|
});
|
|
93
96
|
// Success envelope (internal-docs/platform.md "Global API Conventions"): `{ data: T }` for
|
|
94
97
|
// single resources and mutations, `{ data: T[], pagination }` for lists. Mutations whose work
|
|
@@ -98,7 +101,7 @@ export function dataEnvelope(data) {
|
|
|
98
101
|
}
|
|
99
102
|
export const ApiUploadInstructionSchema = z
|
|
100
103
|
.object({
|
|
101
|
-
id: z.string().describe("
|
|
104
|
+
id: z.string().describe("The upload session id (`upl_…`)."),
|
|
102
105
|
expiresAt: z.string().datetime(),
|
|
103
106
|
method: z.literal("PUT"),
|
|
104
107
|
url: z
|
|
@@ -114,7 +117,7 @@ export const CursorPaginationSchema = z.object({
|
|
|
114
117
|
nextCursor: z
|
|
115
118
|
.string()
|
|
116
119
|
.nullable()
|
|
117
|
-
.describe("Opaque cursor for the next page;
|
|
120
|
+
.describe("Opaque cursor for the next page; null when there are no more results."),
|
|
118
121
|
hasMore: z.boolean().describe("Whether another page exists after this one."),
|
|
119
122
|
});
|
|
120
123
|
export const CURSOR_MAX_LENGTH = 4_096;
|
|
@@ -133,7 +136,7 @@ export const cursorListQuerySchema = z.object({
|
|
|
133
136
|
.min(1)
|
|
134
137
|
.max(CURSOR_MAX_LENGTH)
|
|
135
138
|
.optional()
|
|
136
|
-
.describe("Opaque cursor from
|
|
139
|
+
.describe("Opaque cursor from the previous page's `nextCursor`."),
|
|
137
140
|
});
|
|
138
141
|
// The operator-only offset list-response shape (superadmin surfaces): the named
|
|
139
142
|
// items array, plus `total`/`limit`/`offset` and the offset `pagination` block.
|
|
@@ -13,7 +13,7 @@ import { AnyObjectSchema } from "./common.js";
|
|
|
13
13
|
// generalized resume endpoint once the human step is done.
|
|
14
14
|
export const RequiresActionTypeSchema = z
|
|
15
15
|
.enum(["device_authorization"])
|
|
16
|
-
.describe("Stable identifier for the out-of-band step
|
|
16
|
+
.describe("Stable identifier for the out-of-band step that blocks the flow. Add new blocking steps here so resume stays one generalized contract.");
|
|
17
17
|
export const RequiresActionSchema = z
|
|
18
18
|
.object({
|
|
19
19
|
actionType: RequiresActionTypeSchema,
|
|
@@ -29,7 +29,7 @@ export const RequiresActionSchema = z
|
|
|
29
29
|
continuationToken: z
|
|
30
30
|
.string()
|
|
31
31
|
.min(1)
|
|
32
|
-
.describe("Short-lived,
|
|
32
|
+
.describe("Short-lived, principal-scoped capability for this exact flow. Present it to POST /v1/actions/resume to poll and complete the flow. The token is single-use on completion. Treat it as a secret. Never log it."),
|
|
33
33
|
pollAfterSeconds: z
|
|
34
34
|
.number()
|
|
35
35
|
.int()
|
|
@@ -38,7 +38,7 @@ export const RequiresActionSchema = z
|
|
|
38
38
|
expiresAt: z
|
|
39
39
|
.string()
|
|
40
40
|
.datetime()
|
|
41
|
-
.describe("Instant
|
|
41
|
+
.describe("Instant when the human step deadline is reached for the originating flow. Resume after this returns terminal `expired`. The token survives for a short grace so resume can report `expired`, but the flow can no longer be redeemed."),
|
|
42
42
|
})
|
|
43
43
|
.strict();
|
|
44
44
|
/** The canonical `{ requiresAction }` envelope, additive alongside `{ data }` / `{ error }`. */
|
|
@@ -70,7 +70,7 @@ export const ActionResumeResponseSchema = z
|
|
|
70
70
|
.object({
|
|
71
71
|
status: z.literal("completed"),
|
|
72
72
|
actionType: RequiresActionTypeSchema,
|
|
73
|
-
result: AnyObjectSchema.describe("
|
|
73
|
+
result: AnyObjectSchema.describe("Flow success payload, redeemed exactly once. For device_authorization, this carries the one-time `apiKey` and any `claimedSpaceId`."),
|
|
74
74
|
})
|
|
75
75
|
.strict(),
|
|
76
76
|
z
|
|
@@ -88,4 +88,4 @@ export const ActionResumeResponseSchema = z
|
|
|
88
88
|
})
|
|
89
89
|
.strict(),
|
|
90
90
|
])
|
|
91
|
-
.describe("Consistent resume result across flows
|
|
91
|
+
.describe("Consistent resume result across flows. Keep polling on `pending`. Read the one-time payload on `completed`. Stop on `denied` or `expired`.");
|
|
@@ -1,10 +1,5 @@
|
|
|
1
|
-
// ISO 3166-1 alpha-2 country codes
|
|
2
|
-
//
|
|
3
|
-
// §5.6). The rule `match.country` is an exact-equality matcher against the
|
|
4
|
-
// edge-supplied country header, so "allow only these countries" compiles to
|
|
5
|
-
// one deny/challenge rule per code in the COMPLEMENT of this list — which is
|
|
6
|
-
// why the list itself is a contract: the compiler and the projection must
|
|
7
|
-
// agree on the universe.
|
|
1
|
+
// ISO 3166-1 alpha-2 country codes used by Grant network constraints. The
|
|
2
|
+
// runtime compares them with the edge-supplied country header.
|
|
8
3
|
//
|
|
9
4
|
// Officially assigned codes only (no exceptionally-reserved / user-assigned
|
|
10
5
|
// ranges). Display names are a UI concern (`Intl.DisplayNames`), never stored.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const dataSourceListItemSchema: z.ZodObject<{
|
|
3
|
+
kind: z.ZodLiteral<"wordpress">;
|
|
4
|
+
url: z.ZodString;
|
|
5
|
+
name: z.ZodString;
|
|
6
|
+
default: z.ZodBoolean;
|
|
7
|
+
}, z.core.$strict>;
|
|
8
|
+
export type DataSourceListItem = z.infer<typeof dataSourceListItemSchema>;
|
|
9
|
+
export declare const dataSourceListResponseSchema: z.ZodObject<{
|
|
10
|
+
data: z.ZodObject<{
|
|
11
|
+
dataSources: z.ZodArray<z.ZodObject<{
|
|
12
|
+
kind: z.ZodLiteral<"wordpress">;
|
|
13
|
+
url: z.ZodString;
|
|
14
|
+
name: z.ZodString;
|
|
15
|
+
default: z.ZodBoolean;
|
|
16
|
+
}, z.core.$strict>>;
|
|
17
|
+
defaultDataSource: z.ZodNullable<z.ZodString>;
|
|
18
|
+
}, z.core.$strip>;
|
|
19
|
+
}, z.core.$strip>;
|
|
20
|
+
export type DataSourceListResponse = z.infer<typeof dataSourceListResponseSchema>;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { dataEnvelope } from "./common.js";
|
|
3
|
+
import { dataSourceNameSchema, wordpressDataSourceSchema } from "./space-config.js";
|
|
4
|
+
export const dataSourceListItemSchema = wordpressDataSourceSchema
|
|
5
|
+
.extend({
|
|
6
|
+
name: dataSourceNameSchema,
|
|
7
|
+
default: z.boolean().describe("Whether this source is the effective default."),
|
|
8
|
+
})
|
|
9
|
+
.strict();
|
|
10
|
+
export const dataSourceListResponseSchema = dataEnvelope(z.object({
|
|
11
|
+
dataSources: z.array(dataSourceListItemSchema),
|
|
12
|
+
defaultDataSource: dataSourceNameSchema
|
|
13
|
+
.nullable()
|
|
14
|
+
.describe("Configured default source, or the first source in bytewise name order; null when no sources are configured."),
|
|
15
|
+
}));
|