@sequenceholdings/artifact-studio 0.5.0 → 0.6.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/README.md +43 -0
- package/VERSION-PIN.md +27 -0
- package/dist/cli.js +1 -1
- package/dist/manifest-next-ingress.d.ts +213 -0
- package/dist/manifest-next-ingress.js +187 -0
- package/dist/manifest-next-reach.d.ts +40 -0
- package/dist/manifest-next-reach.js +48 -0
- package/dist/manifest-next.d.ts +133 -8
- package/dist/manifest-next.js +7 -46
- package/dist/manifest-static.d.ts +6 -0
- package/dist/manifest-static.js +10 -0
- package/dist/manifest.d.ts +67 -0
- package/dist/manifest.js +7 -0
- package/dist/offline/connector.d.ts +2 -0
- package/dist/offline/connector.js +6 -2
- package/dist/offline/management-types.d.ts +25 -0
- package/dist/offline/management-types.js +1 -0
- package/dist/runtime-contracts.js +1 -1
- package/dist/sdk.d.ts +8 -1
- package/dist/server/api-client.d.ts +27 -0
- package/dist/server/api-client.js +39 -0
- package/dist/server/broker-contract.d.ts +33 -6
- package/dist/server/broker-contract.js +20 -2
- package/dist/server/client.d.ts +32 -45
- package/dist/server/client.js +72 -101
- package/dist/server/connection-retry.d.ts +12 -0
- package/dist/server/connection-retry.js +40 -0
- package/dist/server/errors.d.ts +37 -2
- package/dist/server/errors.js +66 -6
- package/dist/server/external-context.d.ts +21 -0
- package/dist/server/external-context.js +19 -0
- package/dist/server/ingress-control-contract.d.ts +272 -0
- package/dist/server/ingress-control-contract.js +196 -0
- package/dist/server/ingress-routes.d.ts +76 -0
- package/dist/server/ingress-routes.js +150 -0
- package/dist/server/internal/signed-token.d.ts +15 -0
- package/dist/server/internal/signed-token.js +67 -0
- package/dist/server/internal/v1-context.d.ts +18 -0
- package/dist/server/internal/v1-context.js +26 -0
- package/dist/server/internal/verify-any.d.ts +22 -0
- package/dist/server/internal/verify-any.js +61 -0
- package/dist/server/logger.d.ts +1 -1
- package/dist/server/principal.d.ts +48 -0
- package/dist/server/principal.js +39 -0
- package/dist/server/processes.d.ts +56 -0
- package/dist/server/processes.js +13 -0
- package/dist/server/request-context.d.ts +121 -5
- package/dist/server/request-context.js +105 -34
- package/dist/server/runtime-config.d.ts +1 -1
- package/dist/server/testing.d.ts +40 -0
- package/dist/server/testing.js +86 -0
- package/dist/server.d.ts +9 -4
- package/dist/server.js +5 -2
- package/dist/templates/nextjs/README.md +9 -0
- package/dist/templates/nextjs/package.json +3 -1
- package/dist/templates/nextjs/tests/server.test.mjs +25 -0
- package/dist/templates/react-vite/package.json +1 -1
- package/dist/tunnel/protocol.js +2 -4
- package/dist/tunnel/reserved-headers.d.ts +7 -0
- package/dist/tunnel/reserved-headers.js +20 -0
- package/package.json +19 -3
- package/templates/nextjs/README.md +9 -0
- package/templates/nextjs/package.json +3 -1
- package/templates/nextjs/tests/server.test.mjs +25 -0
- package/templates/react-vite/package.json +1 -1
package/dist/manifest-next.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
import { artifactNextAuditCapabilitySchema } from './manifest-next-reach.js';
|
|
2
3
|
/** Approved major/minor profile. Builds additionally record exact patch versions. */
|
|
3
4
|
export declare const ARTIFACT_NEXT_RUNTIME: Readonly<{
|
|
4
5
|
sdk: "sequence";
|
|
@@ -20,14 +21,8 @@ export declare const ARTIFACT_NEXT_RESOURCE_DEFAULTS: {
|
|
|
20
21
|
max_instances: number;
|
|
21
22
|
timeout_seconds: number;
|
|
22
23
|
};
|
|
23
|
-
|
|
24
|
-
*
|
|
25
|
-
* application may record under `artifact_studio`; Atlas admits a first-party service, such as
|
|
26
|
-
* `application_portal`, only for the projects it registers for it. Server-only: browsers can't audit.
|
|
27
|
-
*/
|
|
28
|
-
export declare const artifactNextAuditCapabilitySchema: z.ZodObject<{
|
|
29
|
-
service: z.ZodString;
|
|
30
|
-
}, z.core.$strict>;
|
|
24
|
+
export { artifactNextAuditCapabilitySchema };
|
|
25
|
+
export * from './manifest-next-ingress.js';
|
|
31
26
|
export declare const artifactNextServerCapabilitiesSchema: z.ZodPrefault<z.ZodObject<{
|
|
32
27
|
audit: z.ZodOptional<z.ZodObject<{
|
|
33
28
|
service: z.ZodString;
|
|
@@ -132,6 +127,71 @@ export declare const artifactNextServerSchema: z.ZodPrefault<z.ZodObject<{
|
|
|
132
127
|
lattice: z.ZodOptional<z.ZodObject<{
|
|
133
128
|
accept: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
134
129
|
}, z.core.$strict>>;
|
|
130
|
+
ingress: z.ZodOptional<z.ZodObject<{
|
|
131
|
+
external: z.ZodArray<z.ZodObject<{
|
|
132
|
+
id: z.ZodString;
|
|
133
|
+
provider: z.ZodString;
|
|
134
|
+
service_account: z.ZodString;
|
|
135
|
+
headers: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
136
|
+
capabilities: z.ZodPrefault<z.ZodObject<{
|
|
137
|
+
storage: z.ZodOptional<z.ZodRecord<z.ZodUUID, z.ZodEnum<{
|
|
138
|
+
viewer: "viewer";
|
|
139
|
+
editor: "editor";
|
|
140
|
+
admin: "admin";
|
|
141
|
+
}>>>;
|
|
142
|
+
data: z.ZodPrefault<z.ZodObject<{
|
|
143
|
+
read: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
144
|
+
write: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
145
|
+
}, z.core.$strict>>;
|
|
146
|
+
api: z.ZodPrefault<z.ZodObject<{
|
|
147
|
+
read: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
148
|
+
write: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
149
|
+
}, z.core.$strict>>;
|
|
150
|
+
functions: z.ZodPrefault<z.ZodObject<{
|
|
151
|
+
invoke: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
152
|
+
}, z.core.$strict>>;
|
|
153
|
+
audit: z.ZodOptional<z.ZodObject<{
|
|
154
|
+
service: z.ZodString;
|
|
155
|
+
}, z.core.$strict>>;
|
|
156
|
+
processes: z.ZodOptional<z.ZodNever>;
|
|
157
|
+
}, z.core.$strict>>;
|
|
158
|
+
evidence: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
159
|
+
bind: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodEnum<{
|
|
160
|
+
email: "email";
|
|
161
|
+
subject: "subject";
|
|
162
|
+
authTime: "authTime";
|
|
163
|
+
amr: "amr";
|
|
164
|
+
"client.ip": "client.ip";
|
|
165
|
+
"client.userAgent": "client.userAgent";
|
|
166
|
+
issuer: "issuer";
|
|
167
|
+
}>>>;
|
|
168
|
+
fresh_auth_seconds: z.ZodOptional<z.ZodNumber>;
|
|
169
|
+
}, z.core.$strict>>>;
|
|
170
|
+
routes: z.ZodArray<z.ZodObject<{
|
|
171
|
+
path: z.ZodString;
|
|
172
|
+
methods: z.ZodArray<z.ZodEnum<{
|
|
173
|
+
GET: "GET";
|
|
174
|
+
POST: "POST";
|
|
175
|
+
PUT: "PUT";
|
|
176
|
+
PATCH: "PATCH";
|
|
177
|
+
DELETE: "DELETE";
|
|
178
|
+
}>>;
|
|
179
|
+
fresh_auth_seconds: z.ZodOptional<z.ZodNumber>;
|
|
180
|
+
max_body_bytes: z.ZodDefault<z.ZodNumber>;
|
|
181
|
+
responses: z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
182
|
+
"application/json": "application/json";
|
|
183
|
+
"application/problem+json": "application/problem+json";
|
|
184
|
+
"application/pdf": "application/pdf";
|
|
185
|
+
"application/zip": "application/zip";
|
|
186
|
+
"image/png": "image/png";
|
|
187
|
+
"image/jpeg": "image/jpeg";
|
|
188
|
+
"image/webp": "image/webp";
|
|
189
|
+
"text/csv": "text/csv";
|
|
190
|
+
"application/octet-stream": "application/octet-stream";
|
|
191
|
+
}>>>;
|
|
192
|
+
}, z.core.$strict>>;
|
|
193
|
+
}, z.core.$strict>>;
|
|
194
|
+
}, z.core.$strict>>;
|
|
135
195
|
}, z.core.$strict>>;
|
|
136
196
|
export declare const artifactStudioNextManifestSchema: z.ZodObject<{
|
|
137
197
|
ontology: z.ZodOptional<z.ZodObject<{
|
|
@@ -251,6 +311,71 @@ export declare const artifactStudioNextManifestSchema: z.ZodObject<{
|
|
|
251
311
|
lattice: z.ZodOptional<z.ZodObject<{
|
|
252
312
|
accept: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
253
313
|
}, z.core.$strict>>;
|
|
314
|
+
ingress: z.ZodOptional<z.ZodObject<{
|
|
315
|
+
external: z.ZodArray<z.ZodObject<{
|
|
316
|
+
id: z.ZodString;
|
|
317
|
+
provider: z.ZodString;
|
|
318
|
+
service_account: z.ZodString;
|
|
319
|
+
headers: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
320
|
+
capabilities: z.ZodPrefault<z.ZodObject<{
|
|
321
|
+
storage: z.ZodOptional<z.ZodRecord<z.ZodUUID, z.ZodEnum<{
|
|
322
|
+
viewer: "viewer";
|
|
323
|
+
editor: "editor";
|
|
324
|
+
admin: "admin";
|
|
325
|
+
}>>>;
|
|
326
|
+
data: z.ZodPrefault<z.ZodObject<{
|
|
327
|
+
read: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
328
|
+
write: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
329
|
+
}, z.core.$strict>>;
|
|
330
|
+
api: z.ZodPrefault<z.ZodObject<{
|
|
331
|
+
read: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
332
|
+
write: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
333
|
+
}, z.core.$strict>>;
|
|
334
|
+
functions: z.ZodPrefault<z.ZodObject<{
|
|
335
|
+
invoke: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
336
|
+
}, z.core.$strict>>;
|
|
337
|
+
audit: z.ZodOptional<z.ZodObject<{
|
|
338
|
+
service: z.ZodString;
|
|
339
|
+
}, z.core.$strict>>;
|
|
340
|
+
processes: z.ZodOptional<z.ZodNever>;
|
|
341
|
+
}, z.core.$strict>>;
|
|
342
|
+
evidence: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
343
|
+
bind: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodEnum<{
|
|
344
|
+
email: "email";
|
|
345
|
+
subject: "subject";
|
|
346
|
+
authTime: "authTime";
|
|
347
|
+
amr: "amr";
|
|
348
|
+
"client.ip": "client.ip";
|
|
349
|
+
"client.userAgent": "client.userAgent";
|
|
350
|
+
issuer: "issuer";
|
|
351
|
+
}>>>;
|
|
352
|
+
fresh_auth_seconds: z.ZodOptional<z.ZodNumber>;
|
|
353
|
+
}, z.core.$strict>>>;
|
|
354
|
+
routes: z.ZodArray<z.ZodObject<{
|
|
355
|
+
path: z.ZodString;
|
|
356
|
+
methods: z.ZodArray<z.ZodEnum<{
|
|
357
|
+
GET: "GET";
|
|
358
|
+
POST: "POST";
|
|
359
|
+
PUT: "PUT";
|
|
360
|
+
PATCH: "PATCH";
|
|
361
|
+
DELETE: "DELETE";
|
|
362
|
+
}>>;
|
|
363
|
+
fresh_auth_seconds: z.ZodOptional<z.ZodNumber>;
|
|
364
|
+
max_body_bytes: z.ZodDefault<z.ZodNumber>;
|
|
365
|
+
responses: z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
366
|
+
"application/json": "application/json";
|
|
367
|
+
"application/problem+json": "application/problem+json";
|
|
368
|
+
"application/pdf": "application/pdf";
|
|
369
|
+
"application/zip": "application/zip";
|
|
370
|
+
"image/png": "image/png";
|
|
371
|
+
"image/jpeg": "image/jpeg";
|
|
372
|
+
"image/webp": "image/webp";
|
|
373
|
+
"text/csv": "text/csv";
|
|
374
|
+
"application/octet-stream": "application/octet-stream";
|
|
375
|
+
}>>>;
|
|
376
|
+
}, z.core.$strict>>;
|
|
377
|
+
}, z.core.$strict>>;
|
|
378
|
+
}, z.core.$strict>>;
|
|
254
379
|
}, z.core.$strict>>;
|
|
255
380
|
targets: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
256
381
|
url: z.ZodString;
|
package/dist/manifest-next.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { storageScopesSchema } from '@sequenceholdings/storage';
|
|
2
1
|
import { ontologyContractSchema } from '@sequenceholdings/orm/canonical';
|
|
3
2
|
import { z } from 'zod';
|
|
4
3
|
import { capabilityPinsSchema, customRolesBlockSchema, validateCapabilityPins } from './manifest-custom-roles.js';
|
|
5
4
|
import { isManagedServerInvokePath } from './server/managed-server-path.js';
|
|
5
|
+
import { artifactNextIngressSchema, validateIngressAgainstServer } from './manifest-next-ingress.js';
|
|
6
|
+
import { artifactNextAuditCapabilitySchema, reachShape, serviceAccountRef } from './manifest-next-reach.js';
|
|
6
7
|
import { apiCapabilityPathAllowed, artifactPresentationSchema, artifactStudioStaticManifestSchema, sidebarBadgeSchema, } from './manifest-static.js';
|
|
7
8
|
/** Approved major/minor profile. Builds additionally record exact patch versions. */
|
|
8
9
|
export const ARTIFACT_NEXT_RUNTIME = Object.freeze({ sdk: 'sequence', node: 24, react: 19, next: '16.3' });
|
|
@@ -11,51 +12,8 @@ export const ARTIFACT_NEXT_APPROVED_PACKAGES = Object.freeze({ next: '16.3.4', r
|
|
|
11
12
|
export const ARTIFACT_NEXT_RESOURCE_DEFAULTS = {
|
|
12
13
|
cpu: 1, memory_mb: 1024, concurrency: 20, min_instances: 0, max_instances: 3, timeout_seconds: 60,
|
|
13
14
|
};
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const apiPath = z.string().min(1).max(512).refine((value) => {
|
|
17
|
-
if (!value.startsWith('/api/') || value === '/api/' || value === '/api/*')
|
|
18
|
-
return false;
|
|
19
|
-
if (/[\\%?#\s\x00-\x1f]/.test(value))
|
|
20
|
-
return false;
|
|
21
|
-
return value.split('/').slice(1).every((part, index, parts) => part !== '.' && part !== '..' && (part !== '' || index === parts.length - 1));
|
|
22
|
-
}, 'API capability paths must be scoped below /api/ without encoded paths, traversal, queries, or fragments');
|
|
23
|
-
// ORM references are what a delegated data token covers (orm-data-plane checkDataTokenScope):
|
|
24
|
-
// a query needs namespace/table for every table it reads, and a mutation needs its
|
|
25
|
-
// namespace/ops/Operation (or table coverage). Any other shape can never match, so it is
|
|
26
|
-
// a typo to report here rather than a 403 at request time. The patterns mirror the ORM's
|
|
27
|
-
// NAMESPACE_PATTERN, IDENTIFIER_PATTERN and GraphQL operation names; they are kept local so
|
|
28
|
-
// browser code that parses manifests does not load the ORM package. platformUsers is the
|
|
29
|
-
// ORM's built-in platform-user entity (PLATFORM_USER_TABLE), a logical key outside the
|
|
30
|
-
// identifier pattern that queries traversing user relations read.
|
|
31
|
-
const ormTableRef = /^[a-z][a-z0-9_]{0,40}\/(?:[a-z][a-z0-9_]{0,62}|platformUsers)$/;
|
|
32
|
-
const ormOperationRef = /^[a-z][a-z0-9_]{0,40}\/ops\/[_A-Za-z][_0-9A-Za-z]*$/;
|
|
33
|
-
const dataReadRef = boundedRef.refine((ref) => ormTableRef.test(ref), 'ORM read references use namespace/table');
|
|
34
|
-
const dataWriteRef = boundedRef.refine((ref) => ormTableRef.test(ref) || ormOperationRef.test(ref), 'ORM write references use namespace/ops/Operation or namespace/table');
|
|
35
|
-
const latticeProcessRef = z.string().min(2).max(128).regex(/^[A-Za-z0-9._-]+$/, 'Process references are Lattice process ids');
|
|
36
|
-
const reachShape = {
|
|
37
|
-
storage: storageScopesSchema.optional(),
|
|
38
|
-
data: z.strictObject({ read: z.array(dataReadRef).max(256).default([]), write: z.array(dataWriteRef).max(256).default([]) }).prefault({}),
|
|
39
|
-
api: z.strictObject({ read: z.array(apiPath).max(256).default([]), write: z.array(apiPath).max(256).default([]) }).prefault({}),
|
|
40
|
-
functions: z.strictObject({ invoke: z.array(boundedRef).max(256).default([]) }).prefault({}),
|
|
41
|
-
// `start`: processes the server may start runs of. `read`: processes whose runs, template and
|
|
42
|
-
// the user's own steps it may read. `act`: processes whose human steps it may advance and
|
|
43
|
-
// reassign, and whose runs' viewers it may manage. All name exact process ids; the user's own
|
|
44
|
-
// Invoker / Viewer / Advancer / Owner grants decide what happens.
|
|
45
|
-
processes: z.strictObject({
|
|
46
|
-
start: z.array(latticeProcessRef).max(256).default([]),
|
|
47
|
-
read: z.array(latticeProcessRef).max(256).default([]),
|
|
48
|
-
act: z.array(latticeProcessRef).max(256).default([]),
|
|
49
|
-
}).prefault({}),
|
|
50
|
-
};
|
|
51
|
-
/**
|
|
52
|
-
* Where the server's audit events (`client.audit.record`) go: an Atlas audit service id. Every
|
|
53
|
-
* application may record under `artifact_studio`; Atlas admits a first-party service, such as
|
|
54
|
-
* `application_portal`, only for the projects it registers for it. Server-only: browsers can't audit.
|
|
55
|
-
*/
|
|
56
|
-
export const artifactNextAuditCapabilitySchema = z.strictObject({
|
|
57
|
-
service: z.string().regex(/^[a-z][a-z0-9_]{0,63}$/, 'Audit services are Atlas audit service ids, such as artifact_studio'),
|
|
58
|
-
});
|
|
15
|
+
export { artifactNextAuditCapabilitySchema };
|
|
16
|
+
export * from './manifest-next-ingress.js';
|
|
59
17
|
export const artifactNextServerCapabilitiesSchema = z.strictObject({
|
|
60
18
|
...reachShape,
|
|
61
19
|
audit: artifactNextAuditCapabilitySchema.optional(),
|
|
@@ -118,6 +76,8 @@ export const artifactNextServerSchema = z.strictObject({
|
|
|
118
76
|
lattice: z.strictObject({
|
|
119
77
|
accept: z.array(managedServerInvokePath).max(32).default([]),
|
|
120
78
|
}).optional(),
|
|
79
|
+
/** Front doors for callers that are not Atlas users. Omitted means none: external callers are refused. */
|
|
80
|
+
ingress: artifactNextIngressSchema.optional(),
|
|
121
81
|
}).superRefine((server, ctx) => {
|
|
122
82
|
if (new Set(server.secrets.map((secret) => secret.name)).size !== server.secrets.length) {
|
|
123
83
|
ctx.addIssue({ code: 'custom', path: ['secrets'], message: 'Each secret environment name must be unique' });
|
|
@@ -128,6 +88,7 @@ export const artifactNextServerSchema = z.strictObject({
|
|
|
128
88
|
if (server.lattice && new Set(server.lattice.accept).size !== server.lattice.accept.length) {
|
|
129
89
|
ctx.addIssue({ code: 'custom', path: ['lattice', 'accept'], message: 'Lattice accept paths must be unique' });
|
|
130
90
|
}
|
|
91
|
+
validateIngressAgainstServer({ server, ctx });
|
|
131
92
|
}).prefault({});
|
|
132
93
|
const appRoot = z.string().min(1).max(512).refine((value) => {
|
|
133
94
|
if (value === '.')
|
|
@@ -23,6 +23,12 @@ export declare const artifactOfflineCapabilitySchema: z.ZodObject<{
|
|
|
23
23
|
policy_version: z.ZodNumber;
|
|
24
24
|
}, z.core.$strip>;
|
|
25
25
|
export type ArtifactOfflineCapability = z.infer<typeof artifactOfflineCapabilitySchema>;
|
|
26
|
+
/**
|
|
27
|
+
* Whether {@link apiCapabilityPathAllowed} treats an entry as a prefix: a trailing `/`, or a
|
|
28
|
+
* trailing `/*` with no other whole-segment `*`. Such an entry admits every path below it,
|
|
29
|
+
* including routes added later. An entry with a mid-path `*` matches whole segments by count.
|
|
30
|
+
*/
|
|
31
|
+
export declare function isPrefixApiCapabilityEntry(entry: string): boolean;
|
|
26
32
|
export declare function apiCapabilityPathAllowed(pathname: string, allowed: readonly string[]): boolean;
|
|
27
33
|
export declare const artifactStudioStaticManifestSchema: z.ZodObject<{
|
|
28
34
|
ontology: z.ZodOptional<z.ZodObject<{
|
package/dist/manifest-static.js
CHANGED
|
@@ -46,6 +46,16 @@ function hasMidPathWildcard(entry) {
|
|
|
46
46
|
const parts = entry.split('/');
|
|
47
47
|
return parts.slice(1, -1).some((part) => part === '*');
|
|
48
48
|
}
|
|
49
|
+
/**
|
|
50
|
+
* Whether {@link apiCapabilityPathAllowed} treats an entry as a prefix: a trailing `/`, or a
|
|
51
|
+
* trailing `/*` with no other whole-segment `*`. Such an entry admits every path below it,
|
|
52
|
+
* including routes added later. An entry with a mid-path `*` matches whole segments by count.
|
|
53
|
+
*/
|
|
54
|
+
export function isPrefixApiCapabilityEntry(entry) {
|
|
55
|
+
if (entry.includes('*') && (!entry.endsWith('/*') || hasMidPathWildcard(entry)))
|
|
56
|
+
return false;
|
|
57
|
+
return entry.endsWith('/*') || entry.endsWith('/');
|
|
58
|
+
}
|
|
49
59
|
export function apiCapabilityPathAllowed(pathname, allowed) {
|
|
50
60
|
return allowed.some((entry) => matchesApiCapabilityEntry(pathname, entry));
|
|
51
61
|
}
|
package/dist/manifest.d.ts
CHANGED
|
@@ -204,6 +204,71 @@ export declare const artifactStudioManifestSchema: z.ZodUnion<readonly [z.ZodObj
|
|
|
204
204
|
lattice: z.ZodOptional<z.ZodObject<{
|
|
205
205
|
accept: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
206
206
|
}, z.core.$strict>>;
|
|
207
|
+
ingress: z.ZodOptional<z.ZodObject<{
|
|
208
|
+
external: z.ZodArray<z.ZodObject<{
|
|
209
|
+
id: z.ZodString;
|
|
210
|
+
provider: z.ZodString;
|
|
211
|
+
service_account: z.ZodString;
|
|
212
|
+
headers: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
213
|
+
capabilities: z.ZodPrefault<z.ZodObject<{
|
|
214
|
+
storage: z.ZodOptional<z.ZodRecord<z.ZodUUID, z.ZodEnum<{
|
|
215
|
+
viewer: "viewer";
|
|
216
|
+
editor: "editor";
|
|
217
|
+
admin: "admin";
|
|
218
|
+
}>>>;
|
|
219
|
+
data: z.ZodPrefault<z.ZodObject<{
|
|
220
|
+
read: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
221
|
+
write: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
222
|
+
}, z.core.$strict>>;
|
|
223
|
+
api: z.ZodPrefault<z.ZodObject<{
|
|
224
|
+
read: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
225
|
+
write: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
226
|
+
}, z.core.$strict>>;
|
|
227
|
+
functions: z.ZodPrefault<z.ZodObject<{
|
|
228
|
+
invoke: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
229
|
+
}, z.core.$strict>>;
|
|
230
|
+
audit: z.ZodOptional<z.ZodObject<{
|
|
231
|
+
service: z.ZodString;
|
|
232
|
+
}, z.core.$strict>>;
|
|
233
|
+
processes: z.ZodOptional<z.ZodNever>;
|
|
234
|
+
}, z.core.$strict>>;
|
|
235
|
+
evidence: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
236
|
+
bind: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodEnum<{
|
|
237
|
+
email: "email";
|
|
238
|
+
subject: "subject";
|
|
239
|
+
authTime: "authTime";
|
|
240
|
+
amr: "amr";
|
|
241
|
+
"client.ip": "client.ip";
|
|
242
|
+
"client.userAgent": "client.userAgent";
|
|
243
|
+
issuer: "issuer";
|
|
244
|
+
}>>>;
|
|
245
|
+
fresh_auth_seconds: z.ZodOptional<z.ZodNumber>;
|
|
246
|
+
}, z.core.$strict>>>;
|
|
247
|
+
routes: z.ZodArray<z.ZodObject<{
|
|
248
|
+
path: z.ZodString;
|
|
249
|
+
methods: z.ZodArray<z.ZodEnum<{
|
|
250
|
+
GET: "GET";
|
|
251
|
+
POST: "POST";
|
|
252
|
+
PUT: "PUT";
|
|
253
|
+
PATCH: "PATCH";
|
|
254
|
+
DELETE: "DELETE";
|
|
255
|
+
}>>;
|
|
256
|
+
fresh_auth_seconds: z.ZodOptional<z.ZodNumber>;
|
|
257
|
+
max_body_bytes: z.ZodDefault<z.ZodNumber>;
|
|
258
|
+
responses: z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
259
|
+
"application/json": "application/json";
|
|
260
|
+
"application/problem+json": "application/problem+json";
|
|
261
|
+
"application/pdf": "application/pdf";
|
|
262
|
+
"application/zip": "application/zip";
|
|
263
|
+
"image/png": "image/png";
|
|
264
|
+
"image/jpeg": "image/jpeg";
|
|
265
|
+
"image/webp": "image/webp";
|
|
266
|
+
"text/csv": "text/csv";
|
|
267
|
+
"application/octet-stream": "application/octet-stream";
|
|
268
|
+
}>>>;
|
|
269
|
+
}, z.core.$strict>>;
|
|
270
|
+
}, z.core.$strict>>;
|
|
271
|
+
}, z.core.$strict>>;
|
|
207
272
|
}, z.core.$strict>>;
|
|
208
273
|
targets: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
209
274
|
url: z.ZodString;
|
|
@@ -226,3 +291,5 @@ export type ArtifactStudioManifest = ArtifactStudioStaticManifest | ArtifactStud
|
|
|
226
291
|
export type ArtifactStudioManifestInput = z.input<typeof artifactStudioManifestSchema>;
|
|
227
292
|
export declare function parseArtifactStudioManifest(value: unknown): ArtifactStudioManifest;
|
|
228
293
|
export declare function isNextArtifactManifest(manifest: ArtifactStudioManifest): manifest is ArtifactStudioNextManifest;
|
|
294
|
+
/** Parses an `artifact.bundle.yml` that must be an Artifact Next manifest (schema_version 2). */
|
|
295
|
+
export declare function parseArtifactNextManifest(value: unknown): ArtifactStudioNextManifest;
|
package/dist/manifest.js
CHANGED
|
@@ -14,3 +14,10 @@ export function parseArtifactStudioManifest(value) {
|
|
|
14
14
|
export function isNextArtifactManifest(manifest) {
|
|
15
15
|
return manifest.artifact.type === 'nextjs';
|
|
16
16
|
}
|
|
17
|
+
/** Parses an `artifact.bundle.yml` that must be an Artifact Next manifest (schema_version 2). */
|
|
18
|
+
export function parseArtifactNextManifest(value) {
|
|
19
|
+
const manifest = parseArtifactStudioManifest(value);
|
|
20
|
+
if (!isNextArtifactManifest(manifest))
|
|
21
|
+
throw new Error('Expected an Artifact Next manifest (artifact.type nextjs)');
|
|
22
|
+
return manifest;
|
|
23
|
+
}
|
|
@@ -2,9 +2,11 @@ import type { SequenceOfflineRequest, SequenceOfflineRequestConnector } from '..
|
|
|
2
2
|
import type { OfflineReplayEngine } from './replay.js';
|
|
3
3
|
import type { OfflineCache, OfflineMutationPolicy, OfflineReadPolicy } from './types.js';
|
|
4
4
|
export declare class OfflineDataUnavailableError extends Error {
|
|
5
|
+
readonly path: string;
|
|
5
6
|
constructor(path: string);
|
|
6
7
|
}
|
|
7
8
|
export declare class OfflineWriteBlockedError extends Error {
|
|
9
|
+
readonly path: string;
|
|
8
10
|
constructor(path: string);
|
|
9
11
|
}
|
|
10
12
|
export interface ArtifactOfflineConnector {
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
export class OfflineDataUnavailableError extends Error {
|
|
2
|
+
path;
|
|
2
3
|
constructor(path) {
|
|
3
|
-
super(
|
|
4
|
+
super('No offline data available');
|
|
4
5
|
this.name = 'OfflineDataUnavailableError';
|
|
6
|
+
this.path = path;
|
|
5
7
|
}
|
|
6
8
|
}
|
|
7
9
|
export class OfflineWriteBlockedError extends Error {
|
|
10
|
+
path;
|
|
8
11
|
constructor(path) {
|
|
9
|
-
super(
|
|
12
|
+
super('Reconnect to complete this action');
|
|
10
13
|
this.name = 'OfflineWriteBlockedError';
|
|
14
|
+
this.path = path;
|
|
11
15
|
}
|
|
12
16
|
}
|
|
13
17
|
function canUseCachedFallback(response) {
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface SequenceOfflineManagementStatus {
|
|
2
|
+
supported: boolean;
|
|
3
|
+
enrolled: boolean;
|
|
4
|
+
online: boolean;
|
|
5
|
+
pending: number;
|
|
6
|
+
failed: number;
|
|
7
|
+
syncing: boolean;
|
|
8
|
+
lastSyncAt: number | null;
|
|
9
|
+
itemCount?: number;
|
|
10
|
+
itemLabel?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface SequenceOfflineManagementIssue {
|
|
13
|
+
id: string;
|
|
14
|
+
label: string;
|
|
15
|
+
message: string;
|
|
16
|
+
}
|
|
17
|
+
export interface SequenceOfflineManagement {
|
|
18
|
+
status(): Promise<SequenceOfflineManagementStatus>;
|
|
19
|
+
setEnrolled(enrolled: boolean): Promise<void>;
|
|
20
|
+
sync(): Promise<void>;
|
|
21
|
+
issues(): Promise<SequenceOfflineManagementIssue[]>;
|
|
22
|
+
retry(id: string): Promise<void>;
|
|
23
|
+
discard(id: string): Promise<void>;
|
|
24
|
+
subscribe(listener: () => void): () => void;
|
|
25
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -20,7 +20,7 @@ const imageReferenceSchema = z.string().max(1024).regex(/^[a-z0-9]+(?:[.-][a-z0-
|
|
|
20
20
|
const excludedSourceSegments = new Set([
|
|
21
21
|
'.git', 'node_modules', '.next', '.npmrc', '.netrc', '.aws', '.ssh', '.config',
|
|
22
22
|
'dist', '.artifact-studio', '.git-credentials', '.pypirc', '.azure', '.gcloud', '.doppler',
|
|
23
|
-
'.turbo', 'coverage', '.docker',
|
|
23
|
+
'.turbo', 'coverage', '.docker', '.seq-next-output.json',
|
|
24
24
|
]);
|
|
25
25
|
/** Shared upload exclusion policy. Content scanning and filesystem containment remain separate checks. */
|
|
26
26
|
export function isExcludedArtifactSourcePath({ path }) {
|
package/dist/sdk.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { SequenceOfflineManagement } from './offline/management-types.js';
|
|
2
|
+
export type { SequenceOfflineManagement, SequenceOfflineManagementStatus, SequenceOfflineManagementIssue } from './offline/management-types.js';
|
|
1
3
|
import { type StartStorageUpload, type StorageUploadSession } from '@sequenceholdings/storage';
|
|
2
4
|
export { createArtifactOrmExecutor, type ArtifactOrmExecutorConfig } from './sdk-orm.js';
|
|
3
5
|
export type { ArtifactOrmJsonScalars } from './orm-json-scalars.js';
|
|
@@ -78,6 +80,9 @@ export interface SequenceOfflineRequestConnector {
|
|
|
78
80
|
}): void | (() => void);
|
|
79
81
|
}
|
|
80
82
|
export interface SequenceOffline {
|
|
83
|
+
registerManagement(adapter: SequenceOfflineManagement): () => void;
|
|
84
|
+
openSettings(): Promise<void>;
|
|
85
|
+
isManagementSession(): boolean;
|
|
81
86
|
/**
|
|
82
87
|
* Install the artifact's request policy beneath seq.api. Returns a disposer
|
|
83
88
|
* that restores the network-only default when it still owns registration.
|
|
@@ -395,7 +400,9 @@ export declare function createArtifactStorageClient(sdk?: SequenceArtifactSdk):
|
|
|
395
400
|
size: number | null;
|
|
396
401
|
contentType: string | null;
|
|
397
402
|
}>;
|
|
398
|
-
createFolder: (name: string, parentId
|
|
403
|
+
createFolder: (name: string, parentId
|
|
404
|
+
/** The specific step run (the assignee's task) — the step-scoped id reviewers hold access to. */
|
|
405
|
+
? /** The specific step run (the assignee's task) — the step-scoped id reviewers hold access to. */: string | null, { idempotencyKey, }?: {
|
|
399
406
|
idempotencyKey?: string;
|
|
400
407
|
}) => Promise<{
|
|
401
408
|
id: string;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { SequenceApiFetchResponse } from '../sdk.js';
|
|
2
|
+
import { type ArtifactServerMode, type ArtifactServerRequest } from './broker-contract.js';
|
|
3
|
+
export interface ArtifactServerFetchOptions {
|
|
4
|
+
method?: 'GET' | 'HEAD' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
5
|
+
body?: unknown;
|
|
6
|
+
signal?: AbortSignal;
|
|
7
|
+
}
|
|
8
|
+
/** Sends one broker operation; the client's transport (retries, the external-principal gate). */
|
|
9
|
+
export type ArtifactBrokerRequest = (operation: ArtifactServerRequest, options?: {
|
|
10
|
+
signal?: AbortSignal;
|
|
11
|
+
stream?: boolean;
|
|
12
|
+
}) => Promise<Response>;
|
|
13
|
+
/** `client.api`: Atlas routes reached through the broker as `api` operations. */
|
|
14
|
+
export declare function createApiClient({ mode, request, json }: {
|
|
15
|
+
mode: ArtifactServerMode;
|
|
16
|
+
request: ArtifactBrokerRequest;
|
|
17
|
+
json: (operation: ArtifactServerRequest, signal?: AbortSignal) => Promise<unknown>;
|
|
18
|
+
}): {
|
|
19
|
+
request: (path: string, options?: ArtifactServerFetchOptions) => Promise<Response>;
|
|
20
|
+
fetch<TBody = unknown>(path: string, options?: ArtifactServerFetchOptions): Promise<SequenceApiFetchResponse<TBody>>;
|
|
21
|
+
stream(path: string, options?: ArtifactServerFetchOptions): Promise<ReadableStream<Uint8Array<ArrayBuffer>>>;
|
|
22
|
+
get: <T = unknown>(path: string) => Promise<T>;
|
|
23
|
+
post: <T = unknown>(path: string, body?: unknown) => Promise<T>;
|
|
24
|
+
put: <T = unknown>(path: string, body?: unknown) => Promise<T>;
|
|
25
|
+
patch: <T = unknown>(path: string, body?: unknown) => Promise<T>;
|
|
26
|
+
delete: <T = unknown>(path: string, body?: unknown) => Promise<T>;
|
|
27
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { artifactServerRequestSchema } from './broker-contract.js';
|
|
2
|
+
import { ArtifactServerError, stepUpErrorFromResponse } from './errors.js';
|
|
3
|
+
const responseHeaders = ['content-type', 'content-disposition', 'content-length', 'retry-after'];
|
|
4
|
+
/** `client.api`: Atlas routes reached through the broker as `api` operations. */
|
|
5
|
+
export function createApiClient({ mode, request, json }) {
|
|
6
|
+
const operation = (path, options = {}) => artifactServerRequestSchema.parse({ operation: 'api', mode, method: options.method ?? 'GET', path, body: options.body });
|
|
7
|
+
const fetchResponse = (path, options = {}) => request(operation(path, options), { signal: options.signal });
|
|
8
|
+
const typedJson = async (path, options = {}) => {
|
|
9
|
+
// Explicit caller result types match the existing browser SDK; the server validates endpoint schemas.
|
|
10
|
+
return await json(operation(path, options), options.signal);
|
|
11
|
+
};
|
|
12
|
+
return {
|
|
13
|
+
request: fetchResponse,
|
|
14
|
+
async fetch(path, options = {}) {
|
|
15
|
+
const response = await fetchResponse(path, options);
|
|
16
|
+
const contentType = response.headers.get('content-type') ?? '';
|
|
17
|
+
const body = response.status === 204 ? undefined : contentType.includes('json') ? await response.json() : await response.arrayBuffer();
|
|
18
|
+
// The caller declares the endpoint's response type, consistent with SequenceApiFetchResponse.
|
|
19
|
+
return { ok: response.ok, status: response.status, body: body, headers: Object.fromEntries(responseHeaders.flatMap(key => {
|
|
20
|
+
const value = response.headers.get(key);
|
|
21
|
+
return value === null ? [] : [[key, value]];
|
|
22
|
+
})) };
|
|
23
|
+
},
|
|
24
|
+
async stream(path, options = {}) {
|
|
25
|
+
// A stream outlives the broker's answer deadline: only its headers must arrive in time.
|
|
26
|
+
const response = await request(operation(path, options), { signal: options.signal, stream: true });
|
|
27
|
+
if (!response.ok || !response.body) {
|
|
28
|
+
throw await stepUpErrorFromResponse(response) ??
|
|
29
|
+
new ArtifactServerError(response.status, 'stream_unavailable', 'Atlas did not return a readable response');
|
|
30
|
+
}
|
|
31
|
+
return response.body;
|
|
32
|
+
},
|
|
33
|
+
get: (path) => typedJson(path),
|
|
34
|
+
post: (path, body) => typedJson(path, { method: 'POST', body }),
|
|
35
|
+
put: (path, body) => typedJson(path, { method: 'PUT', body }),
|
|
36
|
+
patch: (path, body) => typedJson(path, { method: 'PATCH', body }),
|
|
37
|
+
delete: (path, body) => typedJson(path, { method: 'DELETE', body }),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
@@ -3,10 +3,10 @@ export { ORM_JSON_SCALARS_HEADER, ORM_LOSSLESS_JSON_SCALARS, type ArtifactOrmJso
|
|
|
3
3
|
export declare const artifactServerMethodSchema: z.ZodEnum<{
|
|
4
4
|
GET: "GET";
|
|
5
5
|
POST: "POST";
|
|
6
|
-
DELETE: "DELETE";
|
|
7
|
-
HEAD: "HEAD";
|
|
8
6
|
PUT: "PUT";
|
|
9
7
|
PATCH: "PATCH";
|
|
8
|
+
DELETE: "DELETE";
|
|
9
|
+
HEAD: "HEAD";
|
|
10
10
|
}>;
|
|
11
11
|
export declare const artifactServerModeSchema: z.ZodDefault<z.ZodEnum<{
|
|
12
12
|
service: "service";
|
|
@@ -18,6 +18,8 @@ export declare function isArtifactApiPath(path: string): boolean;
|
|
|
18
18
|
export declare const ARTIFACT_PROCESS_RUN_STATUSES: readonly ["pending", "running", "completed", "failed", "cancelled", "timed_out"];
|
|
19
19
|
/** Lattice lists at most this many runs per call. */
|
|
20
20
|
export declare const ARTIFACT_PROCESS_RUNS_LIMIT = 500;
|
|
21
|
+
/** A run-events read returns at most this many events per call, as the run's stream drains them. */
|
|
22
|
+
export declare const ARTIFACT_PROCESS_RUN_EVENTS_LIMIT = 1000;
|
|
21
23
|
/** Which of the user's human steps to list: parked and waiting on them, or already done. */
|
|
22
24
|
export declare const ARTIFACT_PROCESS_TASK_VIEWS: readonly ["active", "completed"];
|
|
23
25
|
/** Lattice lists at most this many human steps per call, as its own inbox does. */
|
|
@@ -45,10 +47,10 @@ export declare const artifactServerRequestSchema: z.ZodDiscriminatedUnion<[z.Zod
|
|
|
45
47
|
method: z.ZodEnum<{
|
|
46
48
|
GET: "GET";
|
|
47
49
|
POST: "POST";
|
|
48
|
-
DELETE: "DELETE";
|
|
49
|
-
HEAD: "HEAD";
|
|
50
50
|
PUT: "PUT";
|
|
51
51
|
PATCH: "PATCH";
|
|
52
|
+
DELETE: "DELETE";
|
|
53
|
+
HEAD: "HEAD";
|
|
52
54
|
}>;
|
|
53
55
|
path: z.ZodString;
|
|
54
56
|
body: z.ZodOptional<z.ZodUnknown>;
|
|
@@ -71,10 +73,10 @@ export declare const artifactServerRequestSchema: z.ZodDiscriminatedUnion<[z.Zod
|
|
|
71
73
|
method: z.ZodEnum<{
|
|
72
74
|
GET: "GET";
|
|
73
75
|
POST: "POST";
|
|
74
|
-
DELETE: "DELETE";
|
|
75
|
-
HEAD: "HEAD";
|
|
76
76
|
PUT: "PUT";
|
|
77
77
|
PATCH: "PATCH";
|
|
78
|
+
DELETE: "DELETE";
|
|
79
|
+
HEAD: "HEAD";
|
|
78
80
|
}>;
|
|
79
81
|
path: z.ZodString;
|
|
80
82
|
body: z.ZodOptional<z.ZodUnknown>;
|
|
@@ -94,6 +96,7 @@ export declare const artifactServerRequestSchema: z.ZodDiscriminatedUnion<[z.Zod
|
|
|
94
96
|
}>>;
|
|
95
97
|
process: z.ZodString;
|
|
96
98
|
runId: z.ZodOptional<z.ZodString>;
|
|
99
|
+
startNodeId: z.ZodOptional<z.ZodString>;
|
|
97
100
|
title: z.ZodOptional<z.ZodString>;
|
|
98
101
|
entity: z.ZodOptional<z.ZodObject<{
|
|
99
102
|
type: z.ZodString;
|
|
@@ -132,6 +135,15 @@ export declare const artifactServerRequestSchema: z.ZodDiscriminatedUnion<[z.Zod
|
|
|
132
135
|
user: "user";
|
|
133
136
|
}>>;
|
|
134
137
|
runId: z.ZodString;
|
|
138
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
139
|
+
operation: z.ZodLiteral<"lattice_run_events">;
|
|
140
|
+
mode: z.ZodDefault<z.ZodEnum<{
|
|
141
|
+
service: "service";
|
|
142
|
+
user: "user";
|
|
143
|
+
}>>;
|
|
144
|
+
runId: z.ZodString;
|
|
145
|
+
since: z.ZodOptional<z.ZodString>;
|
|
146
|
+
limit: z.ZodOptional<z.ZodNumber>;
|
|
135
147
|
}, z.core.$strict>, z.ZodObject<{
|
|
136
148
|
operation: z.ZodLiteral<"lattice_process">;
|
|
137
149
|
mode: z.ZodDefault<z.ZodEnum<{
|
|
@@ -172,6 +184,21 @@ export declare const artifactServerRequestSchema: z.ZodDiscriminatedUnion<[z.Zod
|
|
|
172
184
|
}>>;
|
|
173
185
|
runId: z.ZodString;
|
|
174
186
|
stepId: z.ZodString;
|
|
187
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
188
|
+
operation: z.ZodLiteral<"lattice_cancel">;
|
|
189
|
+
mode: z.ZodDefault<z.ZodEnum<{
|
|
190
|
+
service: "service";
|
|
191
|
+
user: "user";
|
|
192
|
+
}>>;
|
|
193
|
+
runId: z.ZodString;
|
|
194
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
195
|
+
operation: z.ZodLiteral<"lattice_reset_step">;
|
|
196
|
+
mode: z.ZodDefault<z.ZodEnum<{
|
|
197
|
+
service: "service";
|
|
198
|
+
user: "user";
|
|
199
|
+
}>>;
|
|
200
|
+
runId: z.ZodString;
|
|
201
|
+
stepId: z.ZodString;
|
|
175
202
|
}, z.core.$strict>, z.ZodObject<{
|
|
176
203
|
operation: z.ZodLiteral<"lattice_viewers">;
|
|
177
204
|
mode: z.ZodDefault<z.ZodEnum<{
|