@sequenceholdings/artifact-studio 0.3.1 → 0.5.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/README.md +71 -0
- package/VERSION-PIN.md +9 -0
- package/dist/active-deploy-policy.d.ts +9 -3
- package/dist/active-deploy-policy.js +20 -8
- package/dist/artifact-env-bindings.d.ts +9 -0
- package/dist/artifact-env-bindings.js +32 -0
- package/dist/build.js +7 -0
- package/dist/cli.js +66 -13
- package/dist/deployment-validation.d.ts +2 -0
- package/dist/deployment-validation.js +2 -0
- package/dist/dev-link.js +29 -3
- package/dist/env-binding-scan.d.ts +10 -0
- package/dist/env-binding-scan.js +179 -0
- package/dist/env-bindings.d.ts +52 -0
- package/dist/env-bindings.js +180 -0
- package/dist/gateway/control.d.ts +33 -0
- package/dist/gateway/control.js +29 -0
- package/dist/gateway/hosted-proxy.d.ts +5 -0
- package/dist/gateway/hosted-proxy.js +4 -1
- package/dist/gateway/lattice-invoke.d.ts +48 -0
- package/dist/gateway/lattice-invoke.js +245 -0
- package/dist/gateway/lattice-upstream.d.ts +38 -0
- package/dist/gateway/lattice-upstream.js +136 -0
- package/dist/gateway/server.d.ts +3 -0
- package/dist/gateway/server.js +4 -5
- package/dist/gateway/session.d.ts +17 -2
- package/dist/gateway/session.js +27 -6
- package/dist/gateway-main.js +2 -0
- package/dist/loopback.d.ts +8 -0
- package/dist/loopback.js +13 -0
- package/dist/manifest-custom-roles.d.ts +11 -1
- package/dist/manifest-custom-roles.js +13 -5
- package/dist/manifest-next.d.ts +55 -0
- package/dist/manifest-next.js +35 -2
- package/dist/manifest-static.d.ts +35 -0
- package/dist/manifest-static.js +12 -0
- package/dist/manifest.d.ts +48 -0
- package/dist/next/protocol.js +2 -1
- package/dist/next-build.d.ts +2 -1
- package/dist/next-build.js +12 -7
- package/dist/next-dev.js +2 -1
- package/dist/next-project.js +2 -1
- package/dist/offline/cache.d.ts +4 -0
- package/dist/offline/cache.js +7 -0
- package/dist/offline/connector.d.ts +26 -0
- package/dist/offline/connector.js +118 -0
- package/dist/offline/crypto.d.ts +5 -0
- package/dist/offline/crypto.js +24 -0
- package/dist/offline/index.d.ts +8 -0
- package/dist/offline/index.js +7 -0
- package/dist/offline/indexed-db.d.ts +10 -0
- package/dist/offline/indexed-db.js +104 -0
- package/dist/offline/outbox.d.ts +7 -0
- package/dist/offline/outbox.js +46 -0
- package/dist/offline/replay.d.ts +25 -0
- package/dist/offline/replay.js +192 -0
- package/dist/offline/secure-store.d.ts +6 -0
- package/dist/offline/secure-store.js +51 -0
- package/dist/offline/types.d.ts +162 -0
- package/dist/offline/types.js +1 -0
- package/dist/orm-json-scalars.d.ts +21 -0
- package/dist/orm-json-scalars.js +21 -0
- package/dist/project.js +3 -3
- package/dist/role-definitions-notice.d.ts +7 -0
- package/dist/role-definitions-notice.js +19 -0
- package/dist/runtime-contracts.d.ts +7 -7
- package/dist/runtime-contracts.js +2 -1
- package/dist/sandbox-lint.js +1 -1
- package/dist/sdk-orm.d.ts +24 -0
- package/dist/sdk-orm.js +28 -0
- package/dist/sdk.d.ts +127 -0
- package/dist/sdk.js +1 -0
- package/dist/server/broker-contract.d.ts +191 -5
- package/dist/server/broker-contract.js +142 -1
- package/dist/server/client.d.ts +60 -12
- package/dist/server/client.js +143 -20
- package/dist/server/errors.d.ts +26 -0
- package/dist/server/errors.js +29 -0
- package/dist/server/managed-server-path.d.ts +6 -0
- package/dist/server/managed-server-path.js +14 -0
- package/dist/server/processes.d.ts +290 -0
- package/dist/server/processes.js +56 -0
- package/dist/server/request-context.d.ts +6 -0
- package/dist/server/request-context.js +12 -2
- package/dist/server/runtime-config.js +2 -1
- package/dist/server.d.ts +5 -1
- package/dist/server.js +1 -0
- package/dist/source-resolver.d.ts +9 -2
- package/dist/source-resolver.js +55 -8
- package/dist/templates/nextjs/AGENTS.md +10 -0
- package/dist/templates/nextjs/CLAUDE.md +1 -0
- package/dist/templates/nextjs/README.md +88 -0
- package/dist/templates/react-vite/AGENTS.md +8 -88
- package/dist/templates/react-vite/CLAUDE.md +0 -6
- package/dist/templates/react-vite/package.json +1 -1
- package/dist/templates/react-vite/src/App.tsx +37 -14
- package/dist/templates/react-vite/src/styles.css +10 -0
- package/dist/tunnel/client.js +10 -3
- package/dist/tunnel/protocol.js +2 -1
- package/package.json +7 -3
- package/templates/nextjs/AGENTS.md +10 -0
- package/templates/nextjs/CLAUDE.md +1 -0
- package/templates/nextjs/README.md +88 -0
- package/templates/react-vite/AGENTS.md +8 -88
- package/templates/react-vite/CLAUDE.md +0 -6
- package/templates/react-vite/package.json +1 -1
- package/templates/react-vite/src/App.tsx +37 -14
- package/templates/react-vite/src/styles.css +10 -0
|
@@ -158,18 +158,26 @@ export function customRolesDeclared(block) {
|
|
|
158
158
|
* manifest's `capabilities.roles.capabilities` record, or already published
|
|
159
159
|
* to the host's registry scope). Roles are never pinned — composition and
|
|
160
160
|
* grants are live runtime configuration owned by the registry.
|
|
161
|
+
*
|
|
162
|
+
* `app/<application-id>/<key>` pins a capability an Application defines in
|
|
163
|
+
* `sequence.app.yml`. It needn't exist yet (members deploy first) and counts
|
|
164
|
+
* only while the host is a member of that Application.
|
|
161
165
|
*/
|
|
162
|
-
export const CUSTOM_CAPABILITY_PIN_RE = /^(?:org\/)?[a-z0-9-]+$/;
|
|
166
|
+
export const CUSTOM_CAPABILITY_PIN_RE = /^(?:org\/|app\/[a-z][a-z0-9-]{0,63}\/)?[a-z0-9-]+$/;
|
|
163
167
|
const MAX_CAPABILITY_PINS = 100;
|
|
164
168
|
export const capabilityPinsSchema = z
|
|
165
|
-
.array(z.string().min(1).max(
|
|
169
|
+
.array(z.string().min(1).max(140).regex(CUSTOM_CAPABILITY_PIN_RE, 'Pins must be "org/<key>", "app/<application-id>/<key>", or a bare "<key>" matching [a-z0-9-]+'))
|
|
166
170
|
.max(MAX_CAPABILITY_PINS)
|
|
167
171
|
.default([]);
|
|
168
172
|
/** Split a pin into its scope and key. Assumes the pin grammar validated. */
|
|
169
173
|
export function parseCapabilityPin(pin) {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
174
|
+
if (pin.startsWith('org/'))
|
|
175
|
+
return { scope: 'org', key: pin.slice('org/'.length) };
|
|
176
|
+
if (pin.startsWith('app/')) {
|
|
177
|
+
const [, applicationId = '', key = ''] = pin.split('/');
|
|
178
|
+
return { scope: 'app', applicationId, key };
|
|
179
|
+
}
|
|
180
|
+
return { scope: 'project', key: pin };
|
|
173
181
|
}
|
|
174
182
|
/**
|
|
175
183
|
* Cross-field pin validation, called from the manifest superRefine (the
|
package/dist/manifest-next.d.ts
CHANGED
|
@@ -20,7 +20,18 @@ export declare const ARTIFACT_NEXT_RESOURCE_DEFAULTS: {
|
|
|
20
20
|
max_instances: number;
|
|
21
21
|
timeout_seconds: number;
|
|
22
22
|
};
|
|
23
|
+
/**
|
|
24
|
+
* Where the server's audit events (`client.audit.record`) go: an Atlas audit service id. Every
|
|
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>;
|
|
23
31
|
export declare const artifactNextServerCapabilitiesSchema: z.ZodPrefault<z.ZodObject<{
|
|
32
|
+
audit: z.ZodOptional<z.ZodObject<{
|
|
33
|
+
service: z.ZodString;
|
|
34
|
+
}, z.core.$strict>>;
|
|
24
35
|
storage: z.ZodOptional<z.ZodRecord<z.ZodUUID, z.ZodEnum<{
|
|
25
36
|
viewer: "viewer";
|
|
26
37
|
editor: "editor";
|
|
@@ -37,6 +48,11 @@ export declare const artifactNextServerCapabilitiesSchema: z.ZodPrefault<z.ZodOb
|
|
|
37
48
|
functions: z.ZodPrefault<z.ZodObject<{
|
|
38
49
|
invoke: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
39
50
|
}, z.core.$strict>>;
|
|
51
|
+
processes: z.ZodPrefault<z.ZodObject<{
|
|
52
|
+
start: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
53
|
+
read: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
54
|
+
act: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
55
|
+
}, z.core.$strict>>;
|
|
40
56
|
}, z.core.$strict>>;
|
|
41
57
|
export type ArtifactNextServerCapabilities = z.infer<typeof artifactNextServerCapabilitiesSchema>;
|
|
42
58
|
export declare const artifactNextResourceLimitsSchema: z.ZodPrefault<z.ZodObject<{
|
|
@@ -70,6 +86,9 @@ export declare const artifactNextBuildConfigSchema: z.ZodPrefault<z.ZodObject<{
|
|
|
70
86
|
}, z.core.$strict>>;
|
|
71
87
|
export declare const artifactNextServerSchema: z.ZodPrefault<z.ZodObject<{
|
|
72
88
|
capabilities: z.ZodPrefault<z.ZodObject<{
|
|
89
|
+
audit: z.ZodOptional<z.ZodObject<{
|
|
90
|
+
service: z.ZodString;
|
|
91
|
+
}, z.core.$strict>>;
|
|
73
92
|
storage: z.ZodOptional<z.ZodRecord<z.ZodUUID, z.ZodEnum<{
|
|
74
93
|
viewer: "viewer";
|
|
75
94
|
editor: "editor";
|
|
@@ -86,6 +105,11 @@ export declare const artifactNextServerSchema: z.ZodPrefault<z.ZodObject<{
|
|
|
86
105
|
functions: z.ZodPrefault<z.ZodObject<{
|
|
87
106
|
invoke: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
88
107
|
}, z.core.$strict>>;
|
|
108
|
+
processes: z.ZodPrefault<z.ZodObject<{
|
|
109
|
+
start: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
110
|
+
read: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
111
|
+
act: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
112
|
+
}, z.core.$strict>>;
|
|
89
113
|
}, z.core.$strict>>;
|
|
90
114
|
service_account: z.ZodOptional<z.ZodString>;
|
|
91
115
|
secrets: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
@@ -105,8 +129,18 @@ export declare const artifactNextServerSchema: z.ZodPrefault<z.ZodObject<{
|
|
|
105
129
|
cache: z.ZodOptional<z.ZodObject<{
|
|
106
130
|
capacity_gb: z.ZodNumber;
|
|
107
131
|
}, z.core.$strict>>;
|
|
132
|
+
lattice: z.ZodOptional<z.ZodObject<{
|
|
133
|
+
accept: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
134
|
+
}, z.core.$strict>>;
|
|
108
135
|
}, z.core.$strict>>;
|
|
109
136
|
export declare const artifactStudioNextManifestSchema: z.ZodObject<{
|
|
137
|
+
ontology: z.ZodOptional<z.ZodObject<{
|
|
138
|
+
version: z.ZodLiteral<1>;
|
|
139
|
+
read: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
140
|
+
write: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
141
|
+
produce: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
142
|
+
invoke: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
143
|
+
}, z.core.$strict>>;
|
|
110
144
|
bundle: z.ZodObject<{
|
|
111
145
|
name: z.ZodString;
|
|
112
146
|
schema_version: z.ZodLiteral<2>;
|
|
@@ -155,6 +189,11 @@ export declare const artifactStudioNextManifestSchema: z.ZodObject<{
|
|
|
155
189
|
functions: z.ZodPrefault<z.ZodObject<{
|
|
156
190
|
invoke: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
157
191
|
}, z.core.$strict>>;
|
|
192
|
+
processes: z.ZodPrefault<z.ZodObject<{
|
|
193
|
+
start: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
194
|
+
read: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
195
|
+
act: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
196
|
+
}, z.core.$strict>>;
|
|
158
197
|
}, z.core.$strict>>;
|
|
159
198
|
build: z.ZodPrefault<z.ZodObject<{
|
|
160
199
|
public_env: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
@@ -166,6 +205,9 @@ export declare const artifactStudioNextManifestSchema: z.ZodObject<{
|
|
|
166
205
|
}, z.core.$strict>>;
|
|
167
206
|
server: z.ZodPrefault<z.ZodObject<{
|
|
168
207
|
capabilities: z.ZodPrefault<z.ZodObject<{
|
|
208
|
+
audit: z.ZodOptional<z.ZodObject<{
|
|
209
|
+
service: z.ZodString;
|
|
210
|
+
}, z.core.$strict>>;
|
|
169
211
|
storage: z.ZodOptional<z.ZodRecord<z.ZodUUID, z.ZodEnum<{
|
|
170
212
|
viewer: "viewer";
|
|
171
213
|
editor: "editor";
|
|
@@ -182,6 +224,11 @@ export declare const artifactStudioNextManifestSchema: z.ZodObject<{
|
|
|
182
224
|
functions: z.ZodPrefault<z.ZodObject<{
|
|
183
225
|
invoke: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
184
226
|
}, z.core.$strict>>;
|
|
227
|
+
processes: z.ZodPrefault<z.ZodObject<{
|
|
228
|
+
start: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
229
|
+
read: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
230
|
+
act: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
231
|
+
}, z.core.$strict>>;
|
|
185
232
|
}, z.core.$strict>>;
|
|
186
233
|
service_account: z.ZodOptional<z.ZodString>;
|
|
187
234
|
secrets: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
@@ -201,10 +248,18 @@ export declare const artifactStudioNextManifestSchema: z.ZodObject<{
|
|
|
201
248
|
cache: z.ZodOptional<z.ZodObject<{
|
|
202
249
|
capacity_gb: z.ZodNumber;
|
|
203
250
|
}, z.core.$strict>>;
|
|
251
|
+
lattice: z.ZodOptional<z.ZodObject<{
|
|
252
|
+
accept: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
253
|
+
}, z.core.$strict>>;
|
|
204
254
|
}, z.core.$strict>>;
|
|
205
255
|
targets: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
206
256
|
url: z.ZodString;
|
|
207
257
|
}, z.core.$strict>>>;
|
|
258
|
+
presentation: z.ZodOptional<z.ZodObject<{
|
|
259
|
+
mobile: z.ZodOptional<z.ZodEnum<{
|
|
260
|
+
responsive: "responsive";
|
|
261
|
+
}>>;
|
|
262
|
+
}, z.core.$strip>>;
|
|
208
263
|
sidebarIcon: z.ZodOptional<z.ZodString>;
|
|
209
264
|
sidebarBadge: z.ZodOptional<z.ZodObject<{
|
|
210
265
|
endpoint: z.ZodString;
|
package/dist/manifest-next.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { storageScopesSchema } from '@sequenceholdings/storage';
|
|
2
|
+
import { ontologyContractSchema } from '@sequenceholdings/orm/canonical';
|
|
2
3
|
import { z } from 'zod';
|
|
3
4
|
import { capabilityPinsSchema, customRolesBlockSchema, validateCapabilityPins } from './manifest-custom-roles.js';
|
|
4
|
-
import {
|
|
5
|
+
import { isManagedServerInvokePath } from './server/managed-server-path.js';
|
|
6
|
+
import { apiCapabilityPathAllowed, artifactPresentationSchema, artifactStudioStaticManifestSchema, sidebarBadgeSchema, } from './manifest-static.js';
|
|
5
7
|
/** Approved major/minor profile. Builds additionally record exact patch versions. */
|
|
6
8
|
export const ARTIFACT_NEXT_RUNTIME = Object.freeze({ sdk: 'sequence', node: 24, react: 19, next: '16.3' });
|
|
7
9
|
/** Admission policy for new development sessions and builds; retained releases keep their recorded toolchain. */
|
|
@@ -30,13 +32,34 @@ const ormTableRef = /^[a-z][a-z0-9_]{0,40}\/(?:[a-z][a-z0-9_]{0,62}|platformUser
|
|
|
30
32
|
const ormOperationRef = /^[a-z][a-z0-9_]{0,40}\/ops\/[_A-Za-z][_0-9A-Za-z]*$/;
|
|
31
33
|
const dataReadRef = boundedRef.refine((ref) => ormTableRef.test(ref), 'ORM read references use namespace/table');
|
|
32
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');
|
|
33
36
|
const reachShape = {
|
|
34
37
|
storage: storageScopesSchema.optional(),
|
|
35
38
|
data: z.strictObject({ read: z.array(dataReadRef).max(256).default([]), write: z.array(dataWriteRef).max(256).default([]) }).prefault({}),
|
|
36
39
|
api: z.strictObject({ read: z.array(apiPath).max(256).default([]), write: z.array(apiPath).max(256).default([]) }).prefault({}),
|
|
37
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({}),
|
|
38
50
|
};
|
|
39
|
-
|
|
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
|
+
});
|
|
59
|
+
export const artifactNextServerCapabilitiesSchema = z.strictObject({
|
|
60
|
+
...reachShape,
|
|
61
|
+
audit: artifactNextAuditCapabilitySchema.optional(),
|
|
62
|
+
}).prefault({});
|
|
40
63
|
// Reuse role semantics and validation; only the new manifest rejects unknown keys.
|
|
41
64
|
const strictCustomRoles = customRolesBlockSchema.safeExtend({
|
|
42
65
|
definitions: z.record(customRolesBlockSchema.shape.definitions.unwrap().keyType, customRolesBlockSchema.shape.definitions.unwrap().valueType.strict()).default({}),
|
|
@@ -83,6 +106,7 @@ export const artifactNextBuildConfigSchema = z.strictObject({
|
|
|
83
106
|
public_fonts: z.array(artifactNextPublicFontSchema).max(8).refine((fonts) => new Set(fonts.map((font) => font.path)).size === fonts.length, 'Public font destination paths must be unique').default([]),
|
|
84
107
|
}).prefault({});
|
|
85
108
|
const hostname = z.string().max(253).regex(/^(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z](?:[a-z0-9-]{0,61}[a-z0-9])?$/, 'Egress entries must be exact lowercase DNS hostnames without schemes, ports, paths, IPs, or wildcards').refine((host) => !host.endsWith('.localhost') && !host.endsWith('.local') && !host.endsWith('.internal'), 'Egress cannot target local or platform-internal hostnames');
|
|
109
|
+
const managedServerInvokePath = z.string().refine(isManagedServerInvokePath, 'Lattice accept paths are exact origin-relative paths with no query or traversal');
|
|
86
110
|
export const artifactNextServerSchema = z.strictObject({
|
|
87
111
|
capabilities: artifactNextServerCapabilitiesSchema,
|
|
88
112
|
service_account: serviceAccountRef.optional(),
|
|
@@ -90,6 +114,10 @@ export const artifactNextServerSchema = z.strictObject({
|
|
|
90
114
|
egress: z.array(hostname).max(64).default([]),
|
|
91
115
|
resources: artifactNextResourceLimitsSchema,
|
|
92
116
|
cache: z.strictObject({ capacity_gb: z.number().int().min(1).max(16) }).optional(),
|
|
117
|
+
/** Paths Lattice may POST. Exact match only; omitted means Lattice cannot call this server. */
|
|
118
|
+
lattice: z.strictObject({
|
|
119
|
+
accept: z.array(managedServerInvokePath).max(32).default([]),
|
|
120
|
+
}).optional(),
|
|
93
121
|
}).superRefine((server, ctx) => {
|
|
94
122
|
if (new Set(server.secrets.map((secret) => secret.name)).size !== server.secrets.length) {
|
|
95
123
|
ctx.addIssue({ code: 'custom', path: ['secrets'], message: 'Each secret environment name must be unique' });
|
|
@@ -97,6 +125,9 @@ export const artifactNextServerSchema = z.strictObject({
|
|
|
97
125
|
if (new Set(server.egress).size !== server.egress.length) {
|
|
98
126
|
ctx.addIssue({ code: 'custom', path: ['egress'], message: 'Egress hosts must be unique' });
|
|
99
127
|
}
|
|
128
|
+
if (server.lattice && new Set(server.lattice.accept).size !== server.lattice.accept.length) {
|
|
129
|
+
ctx.addIssue({ code: 'custom', path: ['lattice', 'accept'], message: 'Lattice accept paths must be unique' });
|
|
130
|
+
}
|
|
100
131
|
}).prefault({});
|
|
101
132
|
const appRoot = z.string().min(1).max(512).refine((value) => {
|
|
102
133
|
if (value === '.')
|
|
@@ -105,6 +136,7 @@ const appRoot = z.string().min(1).max(512).refine((value) => {
|
|
|
105
136
|
value.split('/').every((part) => part !== '' && part !== '.' && part !== '..' && !part.startsWith('.') && part !== 'node_modules');
|
|
106
137
|
}, 'app_root must be a relative source directory without traversal, hidden directories, or node_modules').default('.');
|
|
107
138
|
export const artifactStudioNextManifestSchema = z.strictObject({
|
|
139
|
+
ontology: ontologyContractSchema.optional(),
|
|
108
140
|
bundle: z.strictObject({ name: z.string().min(1).max(255), schema_version: z.literal(2) }),
|
|
109
141
|
artifact: z.strictObject({
|
|
110
142
|
project_id: artifactStudioStaticManifestSchema.shape.artifact.shape.project_id,
|
|
@@ -120,6 +152,7 @@ export const artifactStudioNextManifestSchema = z.strictObject({
|
|
|
120
152
|
build: artifactNextBuildConfigSchema,
|
|
121
153
|
server: artifactNextServerSchema,
|
|
122
154
|
targets: z.record(z.string().min(1), z.strictObject({ url: z.string().url() })).default({}),
|
|
155
|
+
presentation: artifactPresentationSchema.optional(),
|
|
123
156
|
sidebarIcon: z.string().max(64).optional(),
|
|
124
157
|
sidebarBadge: sidebarBadgeSchema.strict().optional(),
|
|
125
158
|
}).superRefine((manifest, ctx) => {
|
|
@@ -8,8 +8,30 @@ export declare const sidebarBadgeSchema: z.ZodObject<{
|
|
|
8
8
|
}>>;
|
|
9
9
|
}, z.core.$strip>;
|
|
10
10
|
export type SidebarBadgeManifest = z.infer<typeof sidebarBadgeSchema>;
|
|
11
|
+
export declare const artifactPresentationSchema: z.ZodObject<{
|
|
12
|
+
mobile: z.ZodOptional<z.ZodEnum<{
|
|
13
|
+
responsive: "responsive";
|
|
14
|
+
}>>;
|
|
15
|
+
}, z.core.$strip>;
|
|
16
|
+
export type ArtifactPresentation = z.infer<typeof artifactPresentationSchema>;
|
|
17
|
+
export declare const artifactOfflineCapabilitySchema: z.ZodObject<{
|
|
18
|
+
mode: z.ZodEnum<{
|
|
19
|
+
read: "read";
|
|
20
|
+
"read-write": "read-write";
|
|
21
|
+
}>;
|
|
22
|
+
max_age_hours: z.ZodNumber;
|
|
23
|
+
policy_version: z.ZodNumber;
|
|
24
|
+
}, z.core.$strip>;
|
|
25
|
+
export type ArtifactOfflineCapability = z.infer<typeof artifactOfflineCapabilitySchema>;
|
|
11
26
|
export declare function apiCapabilityPathAllowed(pathname: string, allowed: readonly string[]): boolean;
|
|
12
27
|
export declare const artifactStudioStaticManifestSchema: z.ZodObject<{
|
|
28
|
+
ontology: z.ZodOptional<z.ZodObject<{
|
|
29
|
+
version: z.ZodLiteral<1>;
|
|
30
|
+
read: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
31
|
+
write: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
32
|
+
produce: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
33
|
+
invoke: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
34
|
+
}, z.core.$strict>>;
|
|
13
35
|
bundle: z.ZodObject<{
|
|
14
36
|
name: z.ZodString;
|
|
15
37
|
schema_version: z.ZodDefault<z.ZodLiteral<1>>;
|
|
@@ -63,6 +85,19 @@ export declare const artifactStudioStaticManifestSchema: z.ZodObject<{
|
|
|
63
85
|
targets: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
64
86
|
url: z.ZodString;
|
|
65
87
|
}, z.core.$strict>>>;
|
|
88
|
+
presentation: z.ZodOptional<z.ZodObject<{
|
|
89
|
+
mobile: z.ZodOptional<z.ZodEnum<{
|
|
90
|
+
responsive: "responsive";
|
|
91
|
+
}>>;
|
|
92
|
+
}, z.core.$strip>>;
|
|
93
|
+
offline: z.ZodOptional<z.ZodObject<{
|
|
94
|
+
mode: z.ZodEnum<{
|
|
95
|
+
read: "read";
|
|
96
|
+
"read-write": "read-write";
|
|
97
|
+
}>;
|
|
98
|
+
max_age_hours: z.ZodNumber;
|
|
99
|
+
policy_version: z.ZodNumber;
|
|
100
|
+
}, z.core.$strip>>;
|
|
66
101
|
sidebarIcon: z.ZodOptional<z.ZodString>;
|
|
67
102
|
sidebarBadge: z.ZodOptional<z.ZodObject<{
|
|
68
103
|
endpoint: z.ZodString;
|
package/dist/manifest-static.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { storageScopesSchema } from '@sequenceholdings/storage';
|
|
2
|
+
import { ontologyContractSchema } from '@sequenceholdings/orm/canonical';
|
|
2
3
|
import { z } from 'zod';
|
|
3
4
|
import { capabilityPinsSchema, customRolesBlockSchema, validateCapabilityPins, } from './manifest-custom-roles.js';
|
|
4
5
|
import { normalizeArtifactPath } from './paths.js';
|
|
@@ -13,6 +14,14 @@ export const sidebarBadgeSchema = z.object({
|
|
|
13
14
|
endpoint: apiCapabilityPathSchema,
|
|
14
15
|
tone: sidebarBadgeToneSchema.optional(),
|
|
15
16
|
});
|
|
17
|
+
export const artifactPresentationSchema = z.object({
|
|
18
|
+
mobile: z.enum(['responsive']).optional(),
|
|
19
|
+
});
|
|
20
|
+
export const artifactOfflineCapabilitySchema = z.object({
|
|
21
|
+
mode: z.enum(['read', 'read-write']),
|
|
22
|
+
max_age_hours: z.number().int().min(1),
|
|
23
|
+
policy_version: z.number().int().min(1),
|
|
24
|
+
});
|
|
16
25
|
function matchesApiCapabilityEntry(pathname, entry) {
|
|
17
26
|
if (!entry.startsWith('/api/'))
|
|
18
27
|
return false;
|
|
@@ -41,6 +50,7 @@ export function apiCapabilityPathAllowed(pathname, allowed) {
|
|
|
41
50
|
return allowed.some((entry) => matchesApiCapabilityEntry(pathname, entry));
|
|
42
51
|
}
|
|
43
52
|
export const artifactStudioStaticManifestSchema = z.object({
|
|
53
|
+
ontology: ontologyContractSchema.optional(),
|
|
44
54
|
bundle: z.object({
|
|
45
55
|
name: z.string().min(1).max(255),
|
|
46
56
|
schema_version: z.literal(1).default(1),
|
|
@@ -99,6 +109,8 @@ export const artifactStudioStaticManifestSchema = z.object({
|
|
|
99
109
|
targets: z.record(z.string().min(1), z.object({
|
|
100
110
|
url: z.string().url(),
|
|
101
111
|
}).strict()).default({}),
|
|
112
|
+
presentation: artifactPresentationSchema.optional(),
|
|
113
|
+
offline: artifactOfflineCapabilitySchema.optional(),
|
|
102
114
|
sidebarIcon: z.string().max(64).optional(),
|
|
103
115
|
sidebarBadge: sidebarBadgeSchema.optional(),
|
|
104
116
|
}).superRefine((manifest, ctx) => {
|
package/dist/manifest.d.ts
CHANGED
|
@@ -5,6 +5,13 @@ export * from './manifest-static.js';
|
|
|
5
5
|
export * from './manifest-next.js';
|
|
6
6
|
/** Versioned parsing keeps schema-v1 stripping/default behavior unchanged. */
|
|
7
7
|
export declare const artifactStudioManifestSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
8
|
+
ontology: z.ZodOptional<z.ZodObject<{
|
|
9
|
+
version: z.ZodLiteral<1>;
|
|
10
|
+
read: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
11
|
+
write: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
12
|
+
produce: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
13
|
+
invoke: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
14
|
+
}, z.core.$strict>>;
|
|
8
15
|
bundle: z.ZodObject<{
|
|
9
16
|
name: z.ZodString;
|
|
10
17
|
schema_version: z.ZodDefault<z.ZodLiteral<1>>;
|
|
@@ -58,6 +65,19 @@ export declare const artifactStudioManifestSchema: z.ZodUnion<readonly [z.ZodObj
|
|
|
58
65
|
targets: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
59
66
|
url: z.ZodString;
|
|
60
67
|
}, z.core.$strict>>>;
|
|
68
|
+
presentation: z.ZodOptional<z.ZodObject<{
|
|
69
|
+
mobile: z.ZodOptional<z.ZodEnum<{
|
|
70
|
+
responsive: "responsive";
|
|
71
|
+
}>>;
|
|
72
|
+
}, z.core.$strip>>;
|
|
73
|
+
offline: z.ZodOptional<z.ZodObject<{
|
|
74
|
+
mode: z.ZodEnum<{
|
|
75
|
+
read: "read";
|
|
76
|
+
"read-write": "read-write";
|
|
77
|
+
}>;
|
|
78
|
+
max_age_hours: z.ZodNumber;
|
|
79
|
+
policy_version: z.ZodNumber;
|
|
80
|
+
}, z.core.$strip>>;
|
|
61
81
|
sidebarIcon: z.ZodOptional<z.ZodString>;
|
|
62
82
|
sidebarBadge: z.ZodOptional<z.ZodObject<{
|
|
63
83
|
endpoint: z.ZodString;
|
|
@@ -67,6 +87,13 @@ export declare const artifactStudioManifestSchema: z.ZodUnion<readonly [z.ZodObj
|
|
|
67
87
|
}>>;
|
|
68
88
|
}, z.core.$strip>>;
|
|
69
89
|
}, z.core.$strip>, z.ZodObject<{
|
|
90
|
+
ontology: z.ZodOptional<z.ZodObject<{
|
|
91
|
+
version: z.ZodLiteral<1>;
|
|
92
|
+
read: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
93
|
+
write: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
94
|
+
produce: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
95
|
+
invoke: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
96
|
+
}, z.core.$strict>>;
|
|
70
97
|
bundle: z.ZodObject<{
|
|
71
98
|
name: z.ZodString;
|
|
72
99
|
schema_version: z.ZodLiteral<2>;
|
|
@@ -115,6 +142,11 @@ export declare const artifactStudioManifestSchema: z.ZodUnion<readonly [z.ZodObj
|
|
|
115
142
|
functions: z.ZodPrefault<z.ZodObject<{
|
|
116
143
|
invoke: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
117
144
|
}, z.core.$strict>>;
|
|
145
|
+
processes: z.ZodPrefault<z.ZodObject<{
|
|
146
|
+
start: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
147
|
+
read: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
148
|
+
act: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
149
|
+
}, z.core.$strict>>;
|
|
118
150
|
}, z.core.$strict>>;
|
|
119
151
|
build: z.ZodPrefault<z.ZodObject<{
|
|
120
152
|
public_env: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
@@ -126,6 +158,9 @@ export declare const artifactStudioManifestSchema: z.ZodUnion<readonly [z.ZodObj
|
|
|
126
158
|
}, z.core.$strict>>;
|
|
127
159
|
server: z.ZodPrefault<z.ZodObject<{
|
|
128
160
|
capabilities: z.ZodPrefault<z.ZodObject<{
|
|
161
|
+
audit: z.ZodOptional<z.ZodObject<{
|
|
162
|
+
service: z.ZodString;
|
|
163
|
+
}, z.core.$strict>>;
|
|
129
164
|
storage: z.ZodOptional<z.ZodRecord<z.ZodUUID, z.ZodEnum<{
|
|
130
165
|
viewer: "viewer";
|
|
131
166
|
editor: "editor";
|
|
@@ -142,6 +177,11 @@ export declare const artifactStudioManifestSchema: z.ZodUnion<readonly [z.ZodObj
|
|
|
142
177
|
functions: z.ZodPrefault<z.ZodObject<{
|
|
143
178
|
invoke: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
144
179
|
}, z.core.$strict>>;
|
|
180
|
+
processes: z.ZodPrefault<z.ZodObject<{
|
|
181
|
+
start: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
182
|
+
read: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
183
|
+
act: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
184
|
+
}, z.core.$strict>>;
|
|
145
185
|
}, z.core.$strict>>;
|
|
146
186
|
service_account: z.ZodOptional<z.ZodString>;
|
|
147
187
|
secrets: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
@@ -161,10 +201,18 @@ export declare const artifactStudioManifestSchema: z.ZodUnion<readonly [z.ZodObj
|
|
|
161
201
|
cache: z.ZodOptional<z.ZodObject<{
|
|
162
202
|
capacity_gb: z.ZodNumber;
|
|
163
203
|
}, z.core.$strict>>;
|
|
204
|
+
lattice: z.ZodOptional<z.ZodObject<{
|
|
205
|
+
accept: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
206
|
+
}, z.core.$strict>>;
|
|
164
207
|
}, z.core.$strict>>;
|
|
165
208
|
targets: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
166
209
|
url: z.ZodString;
|
|
167
210
|
}, z.core.$strict>>>;
|
|
211
|
+
presentation: z.ZodOptional<z.ZodObject<{
|
|
212
|
+
mobile: z.ZodOptional<z.ZodEnum<{
|
|
213
|
+
responsive: "responsive";
|
|
214
|
+
}>>;
|
|
215
|
+
}, z.core.$strip>>;
|
|
168
216
|
sidebarIcon: z.ZodOptional<z.ZodString>;
|
|
169
217
|
sidebarBadge: z.ZodOptional<z.ZodObject<{
|
|
170
218
|
endpoint: z.ZodString;
|
package/dist/next/protocol.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { stripArtifactReleaseQuery } from './routes.js';
|
|
3
|
+
import { isLoopbackHostname } from '../loopback.js';
|
|
3
4
|
export const NEXT_ARTIFACT_BRIDGE_TYPE = 'artifact-studio-next';
|
|
4
5
|
export const NEXT_ARTIFACT_BRIDGE_VERSION = 1;
|
|
5
6
|
export const nextArtifactThemeSchema = z.object({
|
|
@@ -44,7 +45,7 @@ export function validateNextArtifactBootstrap({ bootstrap }) {
|
|
|
44
45
|
catch {
|
|
45
46
|
throw new Error('Artifact parent origin must be an exact HTTP(S) origin');
|
|
46
47
|
}
|
|
47
|
-
const local = parsed.hostname
|
|
48
|
+
const local = isLoopbackHostname(parsed.hostname);
|
|
48
49
|
if (parsed.origin !== bootstrap.parentOrigin || (parsed.protocol !== 'https:' && !(parsed.protocol === 'http:' && local))) {
|
|
49
50
|
throw new Error('Artifact parent origin must be HTTPS (or HTTP loopback), without a path');
|
|
50
51
|
}
|
package/dist/next-build.d.ts
CHANGED
|
@@ -15,8 +15,9 @@ export declare function resolveNextRepositoryId({ spec, repository, baseUrl, tok
|
|
|
15
15
|
baseUrl: string;
|
|
16
16
|
token: string;
|
|
17
17
|
}): Promise<string>;
|
|
18
|
-
export declare function submitNextBuild({ root, manifest, projectId, baseUrl, getToken, provenance, repository, repositoryId, channel, out }: {
|
|
18
|
+
export declare function submitNextBuild({ root, sourceRoot, manifest, projectId, baseUrl, getToken, provenance, repository, repositoryId, channel, out }: {
|
|
19
19
|
root: string;
|
|
20
|
+
sourceRoot: string;
|
|
20
21
|
manifest: ArtifactStudioNextManifest;
|
|
21
22
|
projectId: string;
|
|
22
23
|
baseUrl: string;
|
package/dist/next-build.js
CHANGED
|
@@ -58,12 +58,16 @@ export async function resolveNextRepositoryId({ spec, repository, baseUrl, token
|
|
|
58
58
|
return match[1];
|
|
59
59
|
}
|
|
60
60
|
catch { /* Opaque labels/SSH origins are valid preview provenance but cannot attest a release. */ }
|
|
61
|
-
throw new Error('Official Next.js releases require a Git Service repository in this Atlas environment. Push the reviewed revision, then run artifact deploy --repo <namespace>/<name> --ref main --env <env
|
|
61
|
+
throw new Error('Official Next.js releases require a Git Service repository in this Atlas environment. Push the reviewed revision, then run artifact deploy --repo <namespace>/<name> --ref main --env <env> (or --ref staging for a staging environment).');
|
|
62
62
|
}
|
|
63
|
-
/**
|
|
64
|
-
|
|
63
|
+
/**
|
|
64
|
+
* A verified repository build names a commit and the application's directory in it;
|
|
65
|
+
* anything else uploads the committed source snapshot. The repository root is omitted
|
|
66
|
+
* so the request stays valid for Atlas versions that predate `sourceRoot`.
|
|
67
|
+
*/
|
|
68
|
+
function nextBuildRequestBody({ manifest, files, commit, provenance, repository, repositoryId, sourceRoot, channel }) {
|
|
65
69
|
if (repositoryId)
|
|
66
|
-
return { repositoryId, commit, idempotencyKey: randomUUID(), channel };
|
|
70
|
+
return { repositoryId, commit, ...(sourceRoot === '.' ? {} : { sourceRoot }), idempotencyKey: randomUUID(), channel };
|
|
67
71
|
return {
|
|
68
72
|
manifest,
|
|
69
73
|
files: files.map(({ path, content, encoding }) => ({ path, content, encoding: encoding ?? 'utf8' })),
|
|
@@ -71,7 +75,7 @@ function nextBuildRequestBody({ manifest, files, commit, provenance, repository,
|
|
|
71
75
|
idempotencyKey: randomUUID(), channel,
|
|
72
76
|
};
|
|
73
77
|
}
|
|
74
|
-
export async function submitNextBuild({ root, manifest, projectId, baseUrl, getToken, provenance, repository, repositoryId, channel, out }) {
|
|
78
|
+
export async function submitNextBuild({ root, sourceRoot, manifest, projectId, baseUrl, getToken, provenance, repository, repositoryId, channel, out }) {
|
|
75
79
|
if (!provenance.gitCommit || !/^[a-f0-9]{40}$/i.test(provenance.gitCommit)) {
|
|
76
80
|
throw new Error('Commit the application source before requesting a hosted build. Use artifact dev for uncommitted local development.');
|
|
77
81
|
}
|
|
@@ -80,9 +84,10 @@ export async function submitNextBuild({ root, manifest, projectId, baseUrl, getT
|
|
|
80
84
|
if (channel === 'active' && !repositoryId)
|
|
81
85
|
throw new Error('An official release requires a verified Git Service repository.');
|
|
82
86
|
const path = `/api/artifact-studio/projects/${encodeURIComponent(projectId)}/next`;
|
|
83
|
-
const body = nextBuildRequestBody({ manifest, files: source.files, commit: provenance.gitCommit, provenance, repository, repositoryId, channel });
|
|
87
|
+
const body = nextBuildRequestBody({ manifest, files: source.files, commit: provenance.gitCommit, provenance, repository, repositoryId, sourceRoot, channel });
|
|
84
88
|
const response = operationSchema.parse(await postJson({ baseUrl, token: await getToken(), path: `${path}/builds${repositoryId ? '/from-repository' : ''}`, body }));
|
|
85
|
-
|
|
89
|
+
const directory = repositoryId && sourceRoot !== '.' ? ` (${sourceRoot})` : '';
|
|
90
|
+
console.log(`[seq-studio] Atlas build ${response.operation.id} (${channel}) from ${provenance.gitCommit.slice(0, 12)}${directory}`);
|
|
86
91
|
console.log(`${baseUrl}/artifact-studio/projects/${projectId}`);
|
|
87
92
|
const controller = new AbortController();
|
|
88
93
|
const onSignal = () => controller.abort();
|
package/dist/next-dev.js
CHANGED
|
@@ -14,6 +14,7 @@ import { materializeNextPublicFonts } from './next-public-fonts-local.js';
|
|
|
14
14
|
import { isTransientNextControlFailure, requestNextDevLease, renewNextDevLease, writeNextRuntimeFile } from './next-dev-control.js';
|
|
15
15
|
import { openNextPreview, selectNextDevPort, startNextDevProcess } from './next-dev-process.js';
|
|
16
16
|
import { connectLocalTunnel } from './tunnel/index.js';
|
|
17
|
+
import { isLocalEnvironmentName } from './loopback.js';
|
|
17
18
|
/** Shutdown never waits longer than this on Atlas; an unconfirmed session still expires with its lease. */
|
|
18
19
|
const SESSION_REVOCATION_TIMEOUT_MS = 10_000;
|
|
19
20
|
export async function runNextDevelopment({ root, manifest, projectId, baseUrl, environment, previewKey, port: requestedPort, links, getToken }) {
|
|
@@ -218,7 +219,7 @@ async function runTunnelConnections({ lease: initialLease, environment, port, re
|
|
|
218
219
|
try {
|
|
219
220
|
const connection = await connectLocalTunnel({
|
|
220
221
|
url: lease.tunnel.url, token: lease.tunnel.token, sessionId: lease.session.id, epoch: lease.tunnel.epoch,
|
|
221
|
-
localPort: port, publicOrigin: lease.session.publicOrigin, signal, allowInsecureLoopback: environment
|
|
222
|
+
localPort: port, publicOrigin: lease.session.publicOrigin, signal, allowInsecureLoopback: isLocalEnvironmentName(environment),
|
|
222
223
|
});
|
|
223
224
|
attempt = 0;
|
|
224
225
|
onStatus('ready');
|
package/dist/next-project.js
CHANGED
|
@@ -5,6 +5,7 @@ import { join, resolve } from 'node:path';
|
|
|
5
5
|
import { z } from 'zod';
|
|
6
6
|
import { createScrubbedChildEnv } from './child-environment.js';
|
|
7
7
|
import { ARTIFACT_NEXT_APPROVED_PACKAGES } from './manifest.js';
|
|
8
|
+
import { isLocalEnvironmentName, isLoopbackHostname } from './loopback.js';
|
|
8
9
|
const packageSchema = z.object({
|
|
9
10
|
dependencies: z.record(z.string(), z.string()).default({}),
|
|
10
11
|
devDependencies: z.record(z.string(), z.string()).default({}),
|
|
@@ -42,7 +43,7 @@ export async function validateNextProject({ root, manifest, installed, nodeVersi
|
|
|
42
43
|
}
|
|
43
44
|
export function validateNextPublicOrigin({ value, environment }) {
|
|
44
45
|
const url = new URL(value);
|
|
45
|
-
const local = environment
|
|
46
|
+
const local = isLocalEnvironmentName(environment) && isLoopbackHostname(url.hostname);
|
|
46
47
|
if ((url.protocol !== 'https:' && !(local && url.protocol === 'http:')) || url.username || url.password || url.search || url.hash || url.pathname !== '/') {
|
|
47
48
|
throw new Error('Atlas returned an invalid application origin; an exact credential-free HTTPS origin is required.');
|
|
48
49
|
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { SequenceOfflineRequest, SequenceOfflineRequestConnector } from '../sdk.js';
|
|
2
|
+
import type { OfflineReplayEngine } from './replay.js';
|
|
3
|
+
import type { OfflineCache, OfflineMutationPolicy, OfflineReadPolicy } from './types.js';
|
|
4
|
+
export declare class OfflineDataUnavailableError extends Error {
|
|
5
|
+
constructor(path: string);
|
|
6
|
+
}
|
|
7
|
+
export declare class OfflineWriteBlockedError extends Error {
|
|
8
|
+
constructor(path: string);
|
|
9
|
+
}
|
|
10
|
+
export interface ArtifactOfflineConnector {
|
|
11
|
+
connector: SequenceOfflineRequestConnector;
|
|
12
|
+
flush(): Promise<void>;
|
|
13
|
+
}
|
|
14
|
+
export declare function createArtifactOfflineConnector({ cache, readPolicy, mutationPolicy, outbox, replay, isOnline, clock, onCacheWriteError, }: {
|
|
15
|
+
cache: OfflineCache;
|
|
16
|
+
readPolicy: OfflineReadPolicy;
|
|
17
|
+
mutationPolicy: OfflineMutationPolicy;
|
|
18
|
+
outbox: import('./types.js').OfflineOutbox;
|
|
19
|
+
replay: OfflineReplayEngine;
|
|
20
|
+
isOnline: () => boolean;
|
|
21
|
+
clock?: () => number;
|
|
22
|
+
onCacheWriteError?: (input: {
|
|
23
|
+
request: SequenceOfflineRequest;
|
|
24
|
+
error: unknown;
|
|
25
|
+
}) => void;
|
|
26
|
+
}): ArtifactOfflineConnector;
|