@sequenceholdings/artifact-studio 0.2.5 → 0.3.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 +35 -0
- package/VERSION-PIN.md +14 -3
- package/dist/api.d.ts +11 -1
- package/dist/api.js +26 -9
- package/dist/atlas-ui-css-plugin.d.ts +11 -7
- package/dist/atlas-ui-css-plugin.js +38 -10
- package/dist/build.d.ts +2 -2
- package/dist/build.js +14 -6
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +108 -37
- package/dist/dev-link.d.ts +1 -1
- package/dist/dev-link.js +2 -1
- package/dist/gateway/admission.d.ts +55 -0
- package/dist/gateway/admission.js +132 -0
- package/dist/gateway/control.d.ts +91 -0
- package/dist/gateway/control.js +113 -0
- package/dist/gateway/hosted-proxy.d.ts +36 -0
- package/dist/gateway/hosted-proxy.js +347 -0
- package/dist/gateway/release-admission.d.ts +23 -0
- package/dist/gateway/release-admission.js +259 -0
- package/dist/gateway/server.d.ts +29 -0
- package/dist/gateway/server.js +298 -0
- package/dist/gateway/session.d.ts +71 -0
- package/dist/gateway/session.js +143 -0
- package/dist/gateway/usage.d.ts +37 -0
- package/dist/gateway/usage.js +46 -0
- package/dist/gateway-main.d.ts +1 -0
- package/dist/gateway-main.js +84 -0
- package/dist/git-clone.d.ts +23 -1
- package/dist/git-clone.js +32 -15
- package/dist/manifest-next.d.ts +217 -0
- package/dist/manifest-next.js +120 -0
- package/dist/manifest-static.d.ts +76 -0
- package/dist/manifest-static.js +124 -0
- package/dist/manifest.d.ts +124 -19
- package/dist/manifest.js +12 -118
- package/dist/next/bridge.d.ts +47 -0
- package/dist/next/bridge.js +229 -0
- package/dist/next/browser-logs.d.ts +7 -0
- package/dist/next/browser-logs.js +51 -0
- package/dist/next/browser.d.ts +6 -0
- package/dist/next/browser.js +57 -0
- package/dist/next/protocol.d.ts +73 -0
- package/dist/next/protocol.js +56 -0
- package/dist/next/release.d.ts +15 -0
- package/dist/next/release.js +46 -0
- package/dist/next/requests.d.ts +15 -0
- package/dist/next/requests.js +59 -0
- package/dist/next/routes.d.ts +4 -0
- package/dist/next/routes.js +21 -0
- package/dist/next/streams.d.ts +16 -0
- package/dist/next/streams.js +132 -0
- package/dist/next/theme.d.ts +10 -0
- package/dist/next/theme.js +45 -0
- package/dist/next/transport.d.ts +15 -0
- package/dist/next/transport.js +13 -0
- package/dist/next-build.d.ts +29 -0
- package/dist/next-build.js +129 -0
- package/dist/next-cache/adapter-runtime.d.ts +51 -0
- package/dist/next-cache/adapter-runtime.js +73 -0
- package/dist/next-cache/component-handler.d.ts +3 -0
- package/dist/next-cache/component-handler.js +10 -0
- package/dist/next-cache/components.d.ts +20 -0
- package/dist/next-cache/components.js +113 -0
- package/dist/next-cache/config.d.ts +9 -0
- package/dist/next-cache/config.js +78 -0
- package/dist/next-cache/incremental-handler.d.ts +18 -0
- package/dist/next-cache/incremental-handler.js +17 -0
- package/dist/next-cache/incremental.d.ts +27 -0
- package/dist/next-cache/incremental.js +99 -0
- package/dist/next-cache/index.d.ts +18 -0
- package/dist/next-cache/index.js +16 -0
- package/dist/next-cache/memory-store.d.ts +27 -0
- package/dist/next-cache/memory-store.js +118 -0
- package/dist/next-cache/redis-scripts.d.ts +3 -0
- package/dist/next-cache/redis-scripts.js +85 -0
- package/dist/next-cache/redis-store.d.ts +18 -0
- package/dist/next-cache/redis-store.js +56 -0
- package/dist/next-cache/runtime.d.ts +29 -0
- package/dist/next-cache/runtime.js +63 -0
- package/dist/next-cache/serialization.d.ts +39 -0
- package/dist/next-cache/serialization.js +333 -0
- package/dist/next-cache/store.d.ts +54 -0
- package/dist/next-cache/store.js +45 -0
- package/dist/next-cache/valkey-transport.d.ts +52 -0
- package/dist/next-cache/valkey-transport.js +189 -0
- package/dist/next-dev-control.d.ts +48 -0
- package/dist/next-dev-control.js +63 -0
- package/dist/next-dev-process.d.ts +17 -0
- package/dist/next-dev-process.js +110 -0
- package/dist/next-dev.d.ts +12 -0
- package/dist/next-dev.js +267 -0
- package/dist/next-image-config.d.ts +9 -0
- package/dist/next-image-config.js +101 -0
- package/dist/next-project.d.ts +22 -0
- package/dist/next-project.js +64 -0
- package/dist/next-public-fonts-local.d.ts +7 -0
- package/dist/next-public-fonts-local.js +64 -0
- package/dist/next-public-fonts.d.ts +13 -0
- package/dist/next-public-fonts.js +49 -0
- package/dist/next-source-hash.d.ts +14 -0
- package/dist/next-source-hash.js +18 -0
- package/dist/next-source.d.ts +35 -0
- package/dist/next-source.js +155 -0
- package/dist/next.d.ts +9 -0
- package/dist/next.js +5 -0
- package/dist/project.d.ts +3 -0
- package/dist/project.js +9 -1
- package/dist/runtime-contracts.d.ts +229 -0
- package/dist/runtime-contracts.js +224 -0
- package/dist/sdk.d.ts +420 -1
- package/dist/sdk.js +35 -0
- package/dist/server/broker-contract.d.ts +68 -0
- package/dist/server/broker-contract.js +33 -0
- package/dist/server/client.d.ts +67 -0
- package/dist/server/client.js +159 -0
- package/dist/server/logger.d.ts +26 -0
- package/dist/server/logger.js +24 -0
- package/dist/server/release-forms.d.ts +13 -0
- package/dist/server/release-forms.js +124 -0
- package/dist/server/request-context.d.ts +74 -0
- package/dist/server/request-context.js +103 -0
- package/dist/server/runtime-config.d.ts +53 -0
- package/dist/server/runtime-config.js +64 -0
- package/dist/server.d.ts +8 -0
- package/dist/server.js +4 -0
- package/dist/templates/nextjs/.artifactignore +14 -0
- package/dist/templates/nextjs/README.md +151 -0
- package/dist/templates/nextjs/app/about/page.tsx +26 -0
- package/dist/templates/nextjs/app/actions.ts +18 -0
- package/dist/templates/nextjs/app/api/health/route.ts +6 -0
- package/dist/templates/nextjs/app/components/counter.tsx +19 -0
- package/dist/templates/nextjs/app/components/greeting-form.tsx +38 -0
- package/dist/templates/nextjs/app/globals.css +4 -0
- package/dist/templates/nextjs/app/layout.tsx +27 -0
- package/dist/templates/nextjs/app/page.tsx +51 -0
- package/dist/templates/nextjs/app/providers.tsx +107 -0
- package/dist/templates/nextjs/artifact.bundle.yml +55 -0
- package/dist/templates/nextjs/next.config.mjs +27 -0
- package/dist/templates/nextjs/package.json +32 -0
- package/dist/templates/nextjs/pnpm-workspace.yaml +8 -0
- package/dist/templates/nextjs/postcss.config.mjs +5 -0
- package/dist/templates/nextjs/tsconfig.json +20 -0
- package/dist/templates/react-vite/artifact.bundle.yml +0 -1
- package/dist/templates/react-vite/package.json +1 -1
- package/dist/tunnel/broker.d.ts +75 -0
- package/dist/tunnel/broker.js +451 -0
- package/dist/tunnel/client.d.ts +22 -0
- package/dist/tunnel/client.js +177 -0
- package/dist/tunnel/index.d.ts +6 -0
- package/dist/tunnel/index.js +4 -0
- package/dist/tunnel/io.d.ts +33 -0
- package/dist/tunnel/io.js +108 -0
- package/dist/tunnel/peer.d.ts +25 -0
- package/dist/tunnel/peer.js +147 -0
- package/dist/tunnel/protocol.d.ts +69 -0
- package/dist/tunnel/protocol.js +196 -0
- package/dist/tunnel/redis-ownership.d.ts +38 -0
- package/dist/tunnel/redis-ownership.js +100 -0
- package/dist/tunnel/redis-socket.d.ts +13 -0
- package/dist/tunnel/redis-socket.js +48 -0
- package/dist/tunnel/redis-types.d.ts +70 -0
- package/dist/tunnel/redis-types.js +9 -0
- package/dist/tunnel/redis.d.ts +53 -0
- package/dist/tunnel/redis.js +391 -0
- package/dist/tunnel/transport.d.ts +17 -0
- package/dist/tunnel/transport.js +1 -0
- package/package.json +68 -4
- package/templates/nextjs/.artifactignore +14 -0
- package/templates/nextjs/README.md +151 -0
- package/templates/nextjs/app/about/page.tsx +26 -0
- package/templates/nextjs/app/actions.ts +18 -0
- package/templates/nextjs/app/api/health/route.ts +6 -0
- package/templates/nextjs/app/components/counter.tsx +19 -0
- package/templates/nextjs/app/components/greeting-form.tsx +38 -0
- package/templates/nextjs/app/globals.css +4 -0
- package/templates/nextjs/app/layout.tsx +27 -0
- package/templates/nextjs/app/page.tsx +51 -0
- package/templates/nextjs/app/providers.tsx +107 -0
- package/templates/nextjs/artifact.bundle.yml +55 -0
- package/templates/nextjs/next.config.mjs +27 -0
- package/templates/nextjs/package.json +32 -0
- package/templates/nextjs/pnpm-workspace.yaml +8 -0
- package/templates/nextjs/postcss.config.mjs +5 -0
- package/templates/nextjs/tsconfig.json +20 -0
- package/templates/react-vite/artifact.bundle.yml +0 -1
- package/templates/react-vite/package.json +1 -1
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { ARTIFACT_NEXT_RUNTIME, artifactNextSecretNameSchema } from './manifest-next.js';
|
|
3
|
+
import { MAX_STUDIO_PATH_LENGTH } from './paths.js';
|
|
4
|
+
export { resolveArtifactNextImages } from './next-image-config.js';
|
|
5
|
+
/** Shared by local collection, repository collection and the bounded source-upload API. */
|
|
6
|
+
export const ARTIFACT_NEXT_SOURCE_LIMITS = Object.freeze({
|
|
7
|
+
maxFiles: 2_000,
|
|
8
|
+
maxFileBytes: 10 * 1024 * 1024,
|
|
9
|
+
maxTotalBytes: 32 * 1024 * 1024,
|
|
10
|
+
});
|
|
11
|
+
const identifierSchema = z.string().min(1).max(256).regex(/^[^\s\u0000-\u001f\u007f]+$/);
|
|
12
|
+
const timestampSchema = z.iso.datetime();
|
|
13
|
+
const exactVersionSchema = z.string().regex(/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/, 'An exact, stable toolchain version is required');
|
|
14
|
+
export const artifactSha256DigestSchema = z.string().regex(/^[a-f0-9]{64}$/, 'Expected a lowercase SHA-256 digest');
|
|
15
|
+
/** Immutable Next deploymentId from compiled output; distinct from the Atlas activation ID. */
|
|
16
|
+
export const artifactNextFrameworkBuildIdSchema = z.string().min(1).max(128).refine((value) => !/[^A-Za-z0-9_-]/.test(value), 'Expected a canonical Next.js deploymentId containing only letters, digits, underscores and hyphens');
|
|
17
|
+
const imageDigestSchema = z.string().regex(/^sha256:[a-f0-9]{64}$/, 'Expected a SHA-256 image digest');
|
|
18
|
+
const imageReferenceSchema = z.string().max(1024).regex(/^[a-z0-9]+(?:[.-][a-z0-9]+)*(?::[1-9][0-9]{0,4})?(?:\/[a-z0-9]+(?:[._-][a-z0-9]+)*)+@sha256:[a-f0-9]{64}$/, 'Expected a registry image reference pinned by digest');
|
|
19
|
+
const excludedSourceSegments = new Set([
|
|
20
|
+
'.git', 'node_modules', '.next', '.npmrc', '.netrc', '.aws', '.ssh', '.config',
|
|
21
|
+
'dist', '.artifact-studio', '.git-credentials', '.pypirc', '.azure', '.gcloud', '.doppler',
|
|
22
|
+
'.turbo', 'coverage', '.docker',
|
|
23
|
+
]);
|
|
24
|
+
/** Shared upload exclusion policy. Content scanning and filesystem containment remain separate checks. */
|
|
25
|
+
export function isExcludedArtifactSourcePath({ path }) {
|
|
26
|
+
return path.split('/').some((segment) => {
|
|
27
|
+
const normalized = segment.toLowerCase();
|
|
28
|
+
return excludedSourceSegments.has(normalized)
|
|
29
|
+
|| normalized.startsWith('.env') || normalized.startsWith('.yarnrc')
|
|
30
|
+
|| /(?:^|[-_.])(?:credentials?|service[-_]?account)(?:[-_.].*)?\.json$/.test(normalized)
|
|
31
|
+
|| /\.(pem|key|p12|pfx|jks)$/.test(normalized);
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
/** POSIX source paths only; filesystem readers must additionally reject symlink escapes. */
|
|
35
|
+
export const artifactSourcePathSchema = z.string().min(1).max(MAX_STUDIO_PATH_LENGTH).refine((path) => {
|
|
36
|
+
if (path !== path.trim() || /[\\%:\u0000-\u001f\u007f]/.test(path))
|
|
37
|
+
return false;
|
|
38
|
+
return !isExcludedArtifactSourcePath({ path })
|
|
39
|
+
&& path.split('/').every((segment) => segment !== '' && segment !== '.' && segment !== '..');
|
|
40
|
+
}, 'Source paths must be relative and exclude credentials, dependencies and build output');
|
|
41
|
+
/** An exact browser origin, not a URL prefix or an allowlist wildcard. */
|
|
42
|
+
export const artifactRuntimeOriginSchema = z.string().max(2048).refine((value) => {
|
|
43
|
+
try {
|
|
44
|
+
const url = new URL(value);
|
|
45
|
+
return url.protocol === 'https:' && url.origin === value && !url.hostname.includes('*');
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
}, 'Expected an exact, canonical HTTPS origin');
|
|
51
|
+
const sourceFileSchema = z.strictObject({
|
|
52
|
+
path: artifactSourcePathSchema,
|
|
53
|
+
sha256: artifactSha256DigestSchema,
|
|
54
|
+
sizeBytes: z.number().int().nonnegative().max(ARTIFACT_NEXT_SOURCE_LIMITS.maxFileBytes),
|
|
55
|
+
});
|
|
56
|
+
/** Metadata points to an immutable snapshot; file bytes travel through the source-upload API. */
|
|
57
|
+
export const artifactNextBuildInputSchema = z.strictObject({
|
|
58
|
+
schemaVersion: z.literal(1),
|
|
59
|
+
framework: z.literal('nextjs'),
|
|
60
|
+
projectId: identifierSchema,
|
|
61
|
+
source: z.strictObject({
|
|
62
|
+
snapshotId: identifierSchema,
|
|
63
|
+
sha256: artifactSha256DigestSchema,
|
|
64
|
+
git: z.strictObject({
|
|
65
|
+
repositoryId: identifierSchema,
|
|
66
|
+
commitSha: z.string().regex(/^(?:[a-f0-9]{40}|[a-f0-9]{64})$/, 'Expected a full Git commit SHA'),
|
|
67
|
+
}),
|
|
68
|
+
files: z.array(sourceFileSchema).min(1).max(ARTIFACT_NEXT_SOURCE_LIMITS.maxFiles),
|
|
69
|
+
}),
|
|
70
|
+
lockfile: z.strictObject({ path: z.literal('pnpm-lock.yaml'), sha256: artifactSha256DigestSchema }),
|
|
71
|
+
toolchain: z.strictObject({
|
|
72
|
+
node: exactVersionSchema.refine((version) => version.startsWith(`${ARTIFACT_NEXT_RUNTIME.node}.`), 'Unsupported Node runtime'),
|
|
73
|
+
next: exactVersionSchema.refine((version) => version.startsWith(`${ARTIFACT_NEXT_RUNTIME.next}.`), 'Unsupported Next.js release line'),
|
|
74
|
+
react: exactVersionSchema.refine((version) => version.startsWith(`${ARTIFACT_NEXT_RUNTIME.react}.`), 'Unsupported React release line'),
|
|
75
|
+
packageManager: z.strictObject({ name: z.literal('pnpm'), version: exactVersionSchema }),
|
|
76
|
+
builderImageDigest: imageDigestSchema,
|
|
77
|
+
}),
|
|
78
|
+
}).superRefine((value, ctx) => {
|
|
79
|
+
if (value.source.files.reduce((total, file) => total + file.sizeBytes, 0) > ARTIFACT_NEXT_SOURCE_LIMITS.maxTotalBytes) {
|
|
80
|
+
ctx.addIssue({ code: 'custom', path: ['source', 'files'], message: 'Source snapshot exceeds the upload size limit' });
|
|
81
|
+
}
|
|
82
|
+
const seen = new Set();
|
|
83
|
+
for (const [index, file] of value.source.files.entries()) {
|
|
84
|
+
if (seen.has(file.path)) {
|
|
85
|
+
ctx.addIssue({ code: 'custom', path: ['source', 'files', index, 'path'], message: 'Duplicate source path' });
|
|
86
|
+
}
|
|
87
|
+
seen.add(file.path);
|
|
88
|
+
}
|
|
89
|
+
for (const [index, file] of value.source.files.entries()) {
|
|
90
|
+
const segments = file.path.split('/');
|
|
91
|
+
for (let depth = 1; depth < segments.length; depth += 1) {
|
|
92
|
+
if (seen.has(segments.slice(0, depth).join('/'))) {
|
|
93
|
+
ctx.addIssue({ code: 'custom', path: ['source', 'files', index, 'path'], message: 'A source file cannot also be a directory' });
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
const lockfile = value.source.files.find((file) => file.path === value.lockfile.path);
|
|
99
|
+
if (!lockfile || lockfile.sha256 !== value.lockfile.sha256) {
|
|
100
|
+
ctx.addIssue({ code: 'custom', path: ['lockfile'], message: 'The pinned lockfile must match a file in the source snapshot' });
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
const immutableObjectSchema = z.strictObject({ objectId: identifierSchema, sha256: artifactSha256DigestSchema });
|
|
104
|
+
export const artifactDeploymentOutputSchema = z.discriminatedUnion('kind', [
|
|
105
|
+
z.strictObject({ kind: z.literal('static'), bundle: immutableObjectSchema }),
|
|
106
|
+
z.strictObject({
|
|
107
|
+
kind: z.literal('next-server'),
|
|
108
|
+
frameworkBuildId: artifactNextFrameworkBuildIdSchema,
|
|
109
|
+
imageRef: imageReferenceSchema,
|
|
110
|
+
assets: immutableObjectSchema,
|
|
111
|
+
buildInputSha256: artifactSha256DigestSchema,
|
|
112
|
+
}),
|
|
113
|
+
]);
|
|
114
|
+
const operationFields = {
|
|
115
|
+
id: identifierSchema,
|
|
116
|
+
projectId: identifierSchema,
|
|
117
|
+
environment: identifierSchema,
|
|
118
|
+
kind: z.enum(['build', 'deploy', 'preview', 'rollback', 'suspend', 'delete']),
|
|
119
|
+
deploymentId: identifierSchema.optional(),
|
|
120
|
+
createdAt: timestampSchema,
|
|
121
|
+
updatedAt: timestampSchema,
|
|
122
|
+
};
|
|
123
|
+
const operationProgressSchema = z.strictObject({
|
|
124
|
+
stage: z.string().min(1).max(128),
|
|
125
|
+
percent: z.number().min(0).max(100).optional(),
|
|
126
|
+
});
|
|
127
|
+
export const artifactOperationSchema = z.discriminatedUnion('status', [
|
|
128
|
+
z.strictObject({ ...operationFields, status: z.literal('queued') }),
|
|
129
|
+
z.strictObject({ ...operationFields, status: z.literal('running'), progress: operationProgressSchema.optional() }),
|
|
130
|
+
z.strictObject({ ...operationFields, status: z.literal('succeeded'), completedAt: timestampSchema }),
|
|
131
|
+
z.strictObject({
|
|
132
|
+
...operationFields,
|
|
133
|
+
status: z.literal('failed'),
|
|
134
|
+
completedAt: timestampSchema,
|
|
135
|
+
error: z.strictObject({ code: identifierSchema, message: z.string().min(1).max(4096) }),
|
|
136
|
+
}),
|
|
137
|
+
z.strictObject({ ...operationFields, status: z.literal('cancelled'), completedAt: timestampSchema }),
|
|
138
|
+
]).superRefine((value, ctx) => {
|
|
139
|
+
if (Date.parse(value.updatedAt) < Date.parse(value.createdAt)) {
|
|
140
|
+
ctx.addIssue({ code: 'custom', path: ['updatedAt'], message: 'An operation cannot be updated before it was created' });
|
|
141
|
+
}
|
|
142
|
+
if ('completedAt' in value && (Date.parse(value.completedAt) < Date.parse(value.createdAt)
|
|
143
|
+
|| Date.parse(value.completedAt) > Date.parse(value.updatedAt))) {
|
|
144
|
+
ctx.addIssue({ code: 'custom', path: ['completedAt'], message: 'Completion must be between creation and the last update' });
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
/** Runtime bootstrap is ephemeral. Do not persist bootstrap URLs in deployment history. */
|
|
148
|
+
export const artifactRuntimeSessionSchema = z.strictObject({
|
|
149
|
+
id: identifierSchema,
|
|
150
|
+
projectId: identifierSchema,
|
|
151
|
+
environment: identifierSchema,
|
|
152
|
+
mode: z.enum(['local', 'preview', 'published']),
|
|
153
|
+
origin: artifactRuntimeOriginSchema,
|
|
154
|
+
parentOrigin: artifactRuntimeOriginSchema,
|
|
155
|
+
bootstrapUrl: z.url().max(4096),
|
|
156
|
+
bridge: z.strictObject({ protocolVersion: z.literal(1), channelId: identifierSchema }),
|
|
157
|
+
expiresAt: timestampSchema,
|
|
158
|
+
}).superRefine((value, ctx) => {
|
|
159
|
+
let validBootstrap = false;
|
|
160
|
+
try {
|
|
161
|
+
const url = new URL(value.bootstrapUrl);
|
|
162
|
+
validBootstrap = url.origin === value.origin && !url.username && !url.password && !url.hash;
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
// URL syntax failures are also reported by the field schema; never throw from safeParse.
|
|
166
|
+
}
|
|
167
|
+
if (!validBootstrap) {
|
|
168
|
+
ctx.addIssue({ code: 'custom', path: ['bootstrapUrl'], message: 'Bootstrap must use the exact runtime origin without credentials or a fragment' });
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
/** Public session metadata contains no tunnel bearer, local credentials or managed secrets. */
|
|
172
|
+
export const artifactLocalDevSessionSchema = z.strictObject({
|
|
173
|
+
id: identifierSchema,
|
|
174
|
+
ownerId: identifierSchema,
|
|
175
|
+
projectId: identifierSchema,
|
|
176
|
+
environment: identifierSchema,
|
|
177
|
+
origin: artifactRuntimeOriginSchema,
|
|
178
|
+
sourceRevision: artifactSha256DigestSchema.optional(),
|
|
179
|
+
revision: z.number().int().positive().max(Number.MAX_SAFE_INTEGER),
|
|
180
|
+
state: z.enum(['starting', 'compiling', 'ready', 'reconnecting', 'failed', 'offline', 'revoked', 'expired']),
|
|
181
|
+
lease: z.strictObject({
|
|
182
|
+
id: identifierSchema,
|
|
183
|
+
fence: z.number().int().positive().max(Number.MAX_SAFE_INTEGER),
|
|
184
|
+
expiresAt: timestampSchema,
|
|
185
|
+
}),
|
|
186
|
+
createdAt: timestampSchema,
|
|
187
|
+
updatedAt: timestampSchema,
|
|
188
|
+
expiresAt: timestampSchema,
|
|
189
|
+
}).superRefine((value, ctx) => {
|
|
190
|
+
const created = Date.parse(value.createdAt);
|
|
191
|
+
const updated = Date.parse(value.updatedAt);
|
|
192
|
+
const expires = Date.parse(value.expiresAt);
|
|
193
|
+
const leaseExpires = Date.parse(value.lease.expiresAt);
|
|
194
|
+
if (updated < created || expires <= created || leaseExpires <= created || leaseExpires > expires) {
|
|
195
|
+
ctx.addIssue({ code: 'custom', path: ['lease', 'expiresAt'], message: 'Session timestamps must be ordered and the lease cannot outlive its session' });
|
|
196
|
+
}
|
|
197
|
+
if (['starting', 'compiling', 'ready', 'reconnecting'].includes(value.state) && updated >= leaseExpires) {
|
|
198
|
+
ctx.addIssue({ code: 'custom', path: ['updatedAt'], message: 'An active session must have an unexpired lease at its last update' });
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
export const artifactActivationSchema = z.strictObject({
|
|
202
|
+
id: identifierSchema,
|
|
203
|
+
projectId: identifierSchema,
|
|
204
|
+
environment: identifierSchema,
|
|
205
|
+
deploymentId: identifierSchema,
|
|
206
|
+
configurationSha256: artifactSha256DigestSchema,
|
|
207
|
+
policySha256: artifactSha256DigestSchema,
|
|
208
|
+
secretVersions: z.array(z.strictObject({
|
|
209
|
+
binding: artifactNextSecretNameSchema,
|
|
210
|
+
secretId: identifierSchema,
|
|
211
|
+
version: z.number().int().positive().max(Number.MAX_SAFE_INTEGER),
|
|
212
|
+
})).max(100),
|
|
213
|
+
cacheGeneration: identifierSchema,
|
|
214
|
+
activatedAt: timestampSchema,
|
|
215
|
+
activatedBy: identifierSchema,
|
|
216
|
+
}).superRefine((value, ctx) => {
|
|
217
|
+
const bindings = new Set();
|
|
218
|
+
for (const [index, secret] of value.secretVersions.entries()) {
|
|
219
|
+
if (bindings.has(secret.binding)) {
|
|
220
|
+
ctx.addIssue({ code: 'custom', path: ['secretVersions', index, 'binding'], message: 'Secret binding names must be unique' });
|
|
221
|
+
}
|
|
222
|
+
bindings.add(secret.binding);
|
|
223
|
+
}
|
|
224
|
+
});
|
package/dist/sdk.d.ts
CHANGED
|
@@ -1,4 +1,22 @@
|
|
|
1
|
+
import { type StartStorageUpload, type StorageUploadSession } from '@sequenceholdings/storage';
|
|
2
|
+
export interface SequenceStorageOptions {
|
|
3
|
+
signal?: AbortSignal;
|
|
4
|
+
timeoutMs?: number;
|
|
5
|
+
onProgress?: (progress: {
|
|
6
|
+
uploadId: string;
|
|
7
|
+
fileId: string;
|
|
8
|
+
uploadedBytes: number;
|
|
9
|
+
}) => void;
|
|
10
|
+
}
|
|
11
|
+
export interface SequenceStorage {
|
|
12
|
+
upload(workspaceId: string, input: StartStorageUpload, file: Blob, options?: SequenceStorageOptions): Promise<StorageUploadSession>;
|
|
13
|
+
resume(workspaceId: string, uploadId: string, file: Blob, options?: SequenceStorageOptions): Promise<StorageUploadSession>;
|
|
14
|
+
}
|
|
1
15
|
export interface SequenceApiFetchOptions {
|
|
16
|
+
traceAction?: {
|
|
17
|
+
id: string;
|
|
18
|
+
key: string;
|
|
19
|
+
};
|
|
2
20
|
method?: string;
|
|
3
21
|
body?: unknown;
|
|
4
22
|
headers?: Record<string, string>;
|
|
@@ -7,6 +25,8 @@ export interface SequenceApiFetchResponse<TBody = unknown> {
|
|
|
7
25
|
ok: boolean;
|
|
8
26
|
status: number;
|
|
9
27
|
body: TBody;
|
|
28
|
+
/** Allowlisted download headers for binary responses; keys are lowercase. */
|
|
29
|
+
headers?: Record<string, string>;
|
|
10
30
|
}
|
|
11
31
|
export interface SequenceApiUploadOptions {
|
|
12
32
|
timeoutMs?: number;
|
|
@@ -28,7 +48,10 @@ export interface SequenceApi {
|
|
|
28
48
|
delete<TBody = unknown>(path: string, body?: unknown): Promise<TBody>;
|
|
29
49
|
}
|
|
30
50
|
export interface SequenceFunctions {
|
|
31
|
-
invoke<TOutput = unknown>(id: string, params?: Record<string, unknown
|
|
51
|
+
invoke<TOutput = unknown>(id: string, params?: Record<string, unknown>, traceAction?: {
|
|
52
|
+
id: string;
|
|
53
|
+
key: string;
|
|
54
|
+
}): Promise<TOutput>;
|
|
32
55
|
}
|
|
33
56
|
export interface SequenceUser {
|
|
34
57
|
current(): Promise<{
|
|
@@ -109,6 +132,7 @@ export interface SequenceHost {
|
|
|
109
132
|
}): void;
|
|
110
133
|
}
|
|
111
134
|
export interface SequenceArtifactSdk {
|
|
135
|
+
storage: SequenceStorage;
|
|
112
136
|
api: SequenceApi;
|
|
113
137
|
ai: {
|
|
114
138
|
fetch(path: string, options?: SequenceApiFetchOptions): Promise<Response>;
|
|
@@ -128,3 +152,398 @@ declare global {
|
|
|
128
152
|
}
|
|
129
153
|
export declare const seq: SequenceArtifactSdk;
|
|
130
154
|
export default seq;
|
|
155
|
+
/** Typed metadata API plus direct browser-host transfers for sandboxed Artifacts. */
|
|
156
|
+
export declare function createArtifactStorageClient(sdk?: SequenceArtifactSdk): {
|
|
157
|
+
workspace(id: string): {
|
|
158
|
+
uploads: {
|
|
159
|
+
put: (input: StartStorageUpload, file: Blob, options?: SequenceStorageOptions) => Promise<{
|
|
160
|
+
id: string;
|
|
161
|
+
fileId: string;
|
|
162
|
+
uploadUrl: string | null;
|
|
163
|
+
expiresAt: string;
|
|
164
|
+
state: "aborted" | "complete" | "pending";
|
|
165
|
+
versionId: string | null;
|
|
166
|
+
maxBytes: number;
|
|
167
|
+
}>;
|
|
168
|
+
resume: (uploadId: string, file: Blob, options?: SequenceStorageOptions) => Promise<{
|
|
169
|
+
id: string;
|
|
170
|
+
fileId: string;
|
|
171
|
+
uploadUrl: string | null;
|
|
172
|
+
expiresAt: string;
|
|
173
|
+
state: "aborted" | "complete" | "pending";
|
|
174
|
+
versionId: string | null;
|
|
175
|
+
maxBytes: number;
|
|
176
|
+
}>;
|
|
177
|
+
start: (input: StartStorageUpload) => Promise<{
|
|
178
|
+
id: string;
|
|
179
|
+
fileId: string;
|
|
180
|
+
uploadUrl: string | null;
|
|
181
|
+
expiresAt: string;
|
|
182
|
+
state: "pending" | "complete" | "aborted";
|
|
183
|
+
versionId: string | null;
|
|
184
|
+
maxBytes: number;
|
|
185
|
+
}>;
|
|
186
|
+
get: (id: string) => Promise<{
|
|
187
|
+
id: string;
|
|
188
|
+
fileId: string;
|
|
189
|
+
uploadUrl: string | null;
|
|
190
|
+
expiresAt: string;
|
|
191
|
+
state: "pending" | "complete" | "aborted";
|
|
192
|
+
versionId: string | null;
|
|
193
|
+
maxBytes: number;
|
|
194
|
+
}>;
|
|
195
|
+
complete: (id: string, input?: import("@sequenceholdings/storage").CompleteStorageUpload) => Promise<{
|
|
196
|
+
id: string;
|
|
197
|
+
fileId: string;
|
|
198
|
+
uploadUrl: string | null;
|
|
199
|
+
expiresAt: string;
|
|
200
|
+
state: "pending" | "complete" | "aborted";
|
|
201
|
+
versionId: string | null;
|
|
202
|
+
maxBytes: number;
|
|
203
|
+
}>;
|
|
204
|
+
abort: (id: string) => Promise<{
|
|
205
|
+
id: string;
|
|
206
|
+
fileId: string;
|
|
207
|
+
uploadUrl: string | null;
|
|
208
|
+
expiresAt: string;
|
|
209
|
+
state: "pending" | "complete" | "aborted";
|
|
210
|
+
versionId: string | null;
|
|
211
|
+
maxBytes: number;
|
|
212
|
+
}>;
|
|
213
|
+
};
|
|
214
|
+
get: () => Promise<{
|
|
215
|
+
id: string;
|
|
216
|
+
name: string;
|
|
217
|
+
description: string;
|
|
218
|
+
environment: string;
|
|
219
|
+
state: "active" | "trashed" | "purging";
|
|
220
|
+
revision: number;
|
|
221
|
+
createdAt: string;
|
|
222
|
+
role: "viewer" | "editor" | "admin" | "owner";
|
|
223
|
+
quotaBytes: number;
|
|
224
|
+
usedBytes: number;
|
|
225
|
+
reservedBytes: number;
|
|
226
|
+
}>;
|
|
227
|
+
delete: (expectedRevision: number) => Promise<{
|
|
228
|
+
id: string;
|
|
229
|
+
workspaceId: string;
|
|
230
|
+
targetId: string | null;
|
|
231
|
+
kind: "purge" | "delete_version";
|
|
232
|
+
status: "queued" | "running" | "succeeded" | "failed";
|
|
233
|
+
completed: number;
|
|
234
|
+
total: number;
|
|
235
|
+
error: string | null;
|
|
236
|
+
createdAt: string;
|
|
237
|
+
updatedAt: string;
|
|
238
|
+
canRetry: boolean;
|
|
239
|
+
}>;
|
|
240
|
+
list: (options?: import("@sequenceholdings/storage").StorageListOptions & {
|
|
241
|
+
parentId?: string | null;
|
|
242
|
+
trash?: boolean;
|
|
243
|
+
}) => Promise<{
|
|
244
|
+
items: {
|
|
245
|
+
id: string;
|
|
246
|
+
workspaceId: string;
|
|
247
|
+
parentId: string | null;
|
|
248
|
+
name: string;
|
|
249
|
+
kind: "file" | "folder";
|
|
250
|
+
state: "active" | "trashed" | "purging";
|
|
251
|
+
restricted: boolean;
|
|
252
|
+
revision: number;
|
|
253
|
+
currentVersionId: string | null;
|
|
254
|
+
metadata: Record<string, string>;
|
|
255
|
+
createdAt: string;
|
|
256
|
+
updatedAt: string;
|
|
257
|
+
role: "viewer" | "editor" | "admin";
|
|
258
|
+
size: number | null;
|
|
259
|
+
contentType: string | null;
|
|
260
|
+
}[];
|
|
261
|
+
nextCursor: string | null;
|
|
262
|
+
}>;
|
|
263
|
+
getNode: (id: string) => Promise<{
|
|
264
|
+
id: string;
|
|
265
|
+
workspaceId: string;
|
|
266
|
+
parentId: string | null;
|
|
267
|
+
name: string;
|
|
268
|
+
kind: "file" | "folder";
|
|
269
|
+
state: "active" | "trashed" | "purging";
|
|
270
|
+
restricted: boolean;
|
|
271
|
+
revision: number;
|
|
272
|
+
currentVersionId: string | null;
|
|
273
|
+
metadata: Record<string, string>;
|
|
274
|
+
createdAt: string;
|
|
275
|
+
updatedAt: string;
|
|
276
|
+
role: "viewer" | "editor" | "admin";
|
|
277
|
+
size: number | null;
|
|
278
|
+
contentType: string | null;
|
|
279
|
+
}>;
|
|
280
|
+
createFolder: (name: string, parentId?: string | null, { idempotencyKey, }?: {
|
|
281
|
+
idempotencyKey?: string;
|
|
282
|
+
}) => Promise<{
|
|
283
|
+
id: string;
|
|
284
|
+
workspaceId: string;
|
|
285
|
+
parentId: string | null;
|
|
286
|
+
name: string;
|
|
287
|
+
kind: "file" | "folder";
|
|
288
|
+
state: "active" | "trashed" | "purging";
|
|
289
|
+
restricted: boolean;
|
|
290
|
+
revision: number;
|
|
291
|
+
currentVersionId: string | null;
|
|
292
|
+
metadata: Record<string, string>;
|
|
293
|
+
createdAt: string;
|
|
294
|
+
updatedAt: string;
|
|
295
|
+
role: "viewer" | "editor" | "admin";
|
|
296
|
+
size: number | null;
|
|
297
|
+
contentType: string | null;
|
|
298
|
+
}>;
|
|
299
|
+
update: (id: string, input: import("zod").input<typeof import("@sequenceholdings/storage").updateNodeSchema>) => Promise<{
|
|
300
|
+
id: string;
|
|
301
|
+
workspaceId: string;
|
|
302
|
+
parentId: string | null;
|
|
303
|
+
name: string;
|
|
304
|
+
kind: "file" | "folder";
|
|
305
|
+
state: "active" | "trashed" | "purging";
|
|
306
|
+
restricted: boolean;
|
|
307
|
+
revision: number;
|
|
308
|
+
currentVersionId: string | null;
|
|
309
|
+
metadata: Record<string, string>;
|
|
310
|
+
createdAt: string;
|
|
311
|
+
updatedAt: string;
|
|
312
|
+
role: "viewer" | "editor" | "admin";
|
|
313
|
+
size: number | null;
|
|
314
|
+
contentType: string | null;
|
|
315
|
+
}>;
|
|
316
|
+
trash: (id: string, expectedRevision: number) => Promise<{
|
|
317
|
+
id: string;
|
|
318
|
+
workspaceId: string;
|
|
319
|
+
parentId: string | null;
|
|
320
|
+
name: string;
|
|
321
|
+
kind: "file" | "folder";
|
|
322
|
+
state: "active" | "trashed" | "purging";
|
|
323
|
+
restricted: boolean;
|
|
324
|
+
revision: number;
|
|
325
|
+
currentVersionId: string | null;
|
|
326
|
+
metadata: Record<string, string>;
|
|
327
|
+
createdAt: string;
|
|
328
|
+
updatedAt: string;
|
|
329
|
+
role: "viewer" | "editor" | "admin";
|
|
330
|
+
size: number | null;
|
|
331
|
+
contentType: string | null;
|
|
332
|
+
}>;
|
|
333
|
+
restore: (id: string, expectedRevision: number) => Promise<{
|
|
334
|
+
id: string;
|
|
335
|
+
workspaceId: string;
|
|
336
|
+
parentId: string | null;
|
|
337
|
+
name: string;
|
|
338
|
+
kind: "file" | "folder";
|
|
339
|
+
state: "active" | "trashed" | "purging";
|
|
340
|
+
restricted: boolean;
|
|
341
|
+
revision: number;
|
|
342
|
+
currentVersionId: string | null;
|
|
343
|
+
metadata: Record<string, string>;
|
|
344
|
+
createdAt: string;
|
|
345
|
+
updatedAt: string;
|
|
346
|
+
role: "viewer" | "editor" | "admin";
|
|
347
|
+
size: number | null;
|
|
348
|
+
contentType: string | null;
|
|
349
|
+
}>;
|
|
350
|
+
purge: (id: string, expectedRevision: number) => Promise<{
|
|
351
|
+
id: string;
|
|
352
|
+
workspaceId: string;
|
|
353
|
+
targetId: string | null;
|
|
354
|
+
kind: "purge" | "delete_version";
|
|
355
|
+
status: "queued" | "running" | "succeeded" | "failed";
|
|
356
|
+
completed: number;
|
|
357
|
+
total: number;
|
|
358
|
+
error: string | null;
|
|
359
|
+
createdAt: string;
|
|
360
|
+
updatedAt: string;
|
|
361
|
+
canRetry: boolean;
|
|
362
|
+
}>;
|
|
363
|
+
download: (id: string, options?: {
|
|
364
|
+
versionId?: string;
|
|
365
|
+
preview?: boolean;
|
|
366
|
+
}) => Promise<{
|
|
367
|
+
url: string;
|
|
368
|
+
expiresAt: string;
|
|
369
|
+
preview: boolean;
|
|
370
|
+
}>;
|
|
371
|
+
versions: (id: string, options?: {
|
|
372
|
+
before?: number;
|
|
373
|
+
limit?: number;
|
|
374
|
+
}) => Promise<{
|
|
375
|
+
items: {
|
|
376
|
+
id: string;
|
|
377
|
+
fileId: string;
|
|
378
|
+
revision: number;
|
|
379
|
+
size: number;
|
|
380
|
+
checksum: string;
|
|
381
|
+
contentType: string;
|
|
382
|
+
createdAt: string;
|
|
383
|
+
createdBy: string;
|
|
384
|
+
state: "active" | "purging";
|
|
385
|
+
}[];
|
|
386
|
+
nextRevision: number | null;
|
|
387
|
+
}>;
|
|
388
|
+
restoreVersion: (id: string, versionId: string, expectedRevision: number) => Promise<{
|
|
389
|
+
id: string;
|
|
390
|
+
fileId: string;
|
|
391
|
+
revision: number;
|
|
392
|
+
size: number;
|
|
393
|
+
checksum: string;
|
|
394
|
+
contentType: string;
|
|
395
|
+
createdAt: string;
|
|
396
|
+
createdBy: string;
|
|
397
|
+
state: "active" | "purging";
|
|
398
|
+
}>;
|
|
399
|
+
deleteVersion: (id: string, versionId: string, expectedRevision: number) => Promise<{
|
|
400
|
+
id: string;
|
|
401
|
+
workspaceId: string;
|
|
402
|
+
targetId: string | null;
|
|
403
|
+
kind: "purge" | "delete_version";
|
|
404
|
+
status: "queued" | "running" | "succeeded" | "failed";
|
|
405
|
+
completed: number;
|
|
406
|
+
total: number;
|
|
407
|
+
error: string | null;
|
|
408
|
+
createdAt: string;
|
|
409
|
+
updatedAt: string;
|
|
410
|
+
canRetry: boolean;
|
|
411
|
+
}>;
|
|
412
|
+
access: (id?: string) => Promise<{
|
|
413
|
+
revision: number;
|
|
414
|
+
restricted: boolean;
|
|
415
|
+
grants: {
|
|
416
|
+
type: "user" | "group" | "organization" | "service_account";
|
|
417
|
+
id: string;
|
|
418
|
+
role: "viewer" | "editor" | "admin";
|
|
419
|
+
}[];
|
|
420
|
+
owner: string | null;
|
|
421
|
+
inherited: boolean;
|
|
422
|
+
workspaceAdminOverride: true;
|
|
423
|
+
displayNames: Record<string, string>;
|
|
424
|
+
}>;
|
|
425
|
+
setAccess: (input: import("zod").input<typeof import("@sequenceholdings/storage").updateStorageAccessSchema>, id?: string) => Promise<{
|
|
426
|
+
revision: number;
|
|
427
|
+
restricted: boolean;
|
|
428
|
+
grants: {
|
|
429
|
+
type: "user" | "group" | "organization" | "service_account";
|
|
430
|
+
id: string;
|
|
431
|
+
role: "viewer" | "editor" | "admin";
|
|
432
|
+
}[];
|
|
433
|
+
owner: string | null;
|
|
434
|
+
inherited: boolean;
|
|
435
|
+
workspaceAdminOverride: true;
|
|
436
|
+
displayNames: Record<string, string>;
|
|
437
|
+
}>;
|
|
438
|
+
transferOwner: (principal: {
|
|
439
|
+
type: "user" | "service_account";
|
|
440
|
+
id: string;
|
|
441
|
+
}, expectedRevision: number) => Promise<{
|
|
442
|
+
revision: number;
|
|
443
|
+
restricted: boolean;
|
|
444
|
+
grants: {
|
|
445
|
+
type: "user" | "group" | "organization" | "service_account";
|
|
446
|
+
id: string;
|
|
447
|
+
role: "viewer" | "editor" | "admin";
|
|
448
|
+
}[];
|
|
449
|
+
owner: string | null;
|
|
450
|
+
inherited: boolean;
|
|
451
|
+
workspaceAdminOverride: true;
|
|
452
|
+
displayNames: Record<string, string>;
|
|
453
|
+
}>;
|
|
454
|
+
operations: (options?: {
|
|
455
|
+
before?: string;
|
|
456
|
+
limit?: number;
|
|
457
|
+
scope?: import("@sequenceholdings/storage").StorageOperationScope;
|
|
458
|
+
}) => Promise<{
|
|
459
|
+
items: {
|
|
460
|
+
id: string;
|
|
461
|
+
workspaceId: string;
|
|
462
|
+
targetId: string | null;
|
|
463
|
+
kind: "purge" | "delete_version";
|
|
464
|
+
status: "queued" | "running" | "succeeded" | "failed";
|
|
465
|
+
completed: number;
|
|
466
|
+
total: number;
|
|
467
|
+
error: string | null;
|
|
468
|
+
createdAt: string;
|
|
469
|
+
updatedAt: string;
|
|
470
|
+
canRetry: boolean;
|
|
471
|
+
}[];
|
|
472
|
+
nextCursor: string | null;
|
|
473
|
+
}>;
|
|
474
|
+
retryOperation: (id: string) => Promise<{
|
|
475
|
+
id: string;
|
|
476
|
+
workspaceId: string;
|
|
477
|
+
targetId: string | null;
|
|
478
|
+
kind: "purge" | "delete_version";
|
|
479
|
+
status: "queued" | "running" | "succeeded" | "failed";
|
|
480
|
+
completed: number;
|
|
481
|
+
total: number;
|
|
482
|
+
error: string | null;
|
|
483
|
+
createdAt: string;
|
|
484
|
+
updatedAt: string;
|
|
485
|
+
canRetry: boolean;
|
|
486
|
+
}>;
|
|
487
|
+
};
|
|
488
|
+
capabilities: () => Promise<{
|
|
489
|
+
canProvision: boolean;
|
|
490
|
+
uploadMethods: string[];
|
|
491
|
+
}>;
|
|
492
|
+
list: (options?: import("@sequenceholdings/storage").StorageListOptions) => Promise<{
|
|
493
|
+
items: {
|
|
494
|
+
id: string;
|
|
495
|
+
name: string;
|
|
496
|
+
description: string;
|
|
497
|
+
environment: string;
|
|
498
|
+
state: "active" | "trashed" | "purging";
|
|
499
|
+
revision: number;
|
|
500
|
+
createdAt: string;
|
|
501
|
+
role: "viewer" | "editor" | "admin" | "owner";
|
|
502
|
+
quotaBytes: number;
|
|
503
|
+
usedBytes: number;
|
|
504
|
+
reservedBytes: number;
|
|
505
|
+
}[];
|
|
506
|
+
nextCursor: string | null;
|
|
507
|
+
}>;
|
|
508
|
+
shared: (options?: import("@sequenceholdings/storage").StorageListOptions & {
|
|
509
|
+
trash?: boolean;
|
|
510
|
+
}) => Promise<{
|
|
511
|
+
items: {
|
|
512
|
+
id: string;
|
|
513
|
+
workspaceId: string;
|
|
514
|
+
parentId: string | null;
|
|
515
|
+
name: string;
|
|
516
|
+
kind: "file" | "folder";
|
|
517
|
+
state: "active" | "trashed" | "purging";
|
|
518
|
+
restricted: boolean;
|
|
519
|
+
revision: number;
|
|
520
|
+
currentVersionId: string | null;
|
|
521
|
+
metadata: Record<string, string>;
|
|
522
|
+
createdAt: string;
|
|
523
|
+
updatedAt: string;
|
|
524
|
+
role: "viewer" | "editor" | "admin";
|
|
525
|
+
size: number | null;
|
|
526
|
+
contentType: string | null;
|
|
527
|
+
}[];
|
|
528
|
+
nextCursor: string | null;
|
|
529
|
+
}>;
|
|
530
|
+
apply: (manifest: import("@sequenceholdings/storage").WorkspaceManifest) => Promise<{
|
|
531
|
+
id: string;
|
|
532
|
+
name: string;
|
|
533
|
+
description: string;
|
|
534
|
+
environment: string;
|
|
535
|
+
state: "active" | "trashed" | "purging";
|
|
536
|
+
revision: number;
|
|
537
|
+
createdAt: string;
|
|
538
|
+
role: "viewer" | "editor" | "admin" | "owner";
|
|
539
|
+
quotaBytes: number;
|
|
540
|
+
usedBytes: number;
|
|
541
|
+
reservedBytes: number;
|
|
542
|
+
}>;
|
|
543
|
+
};
|
|
544
|
+
/** Explicit scope keeps concurrent browser actions isolated. The key is a safe
|
|
545
|
+
* author label, never a payload or an authentication claim. */
|
|
546
|
+
export declare function withTraceAction<T>({ key, sdk }: {
|
|
547
|
+
key: string;
|
|
548
|
+
sdk?: SequenceArtifactSdk;
|
|
549
|
+
}, run: (client: Pick<SequenceArtifactSdk, 'api' | 'functions'>) => Promise<T>): Promise<T>;
|