@sequenceholdings/artifact-studio 0.6.7 → 0.7.1
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 +26 -1
- package/dist/cli.js +4 -6
- package/dist/gateway/abort.d.ts +6 -0
- package/dist/gateway/abort.js +16 -0
- package/dist/gateway/authorization-cache.d.ts +24 -0
- package/dist/gateway/authorization-cache.js +21 -3
- package/dist/gateway/bootstrap-page.d.ts +16 -0
- package/dist/gateway/bootstrap-page.js +42 -0
- package/dist/gateway/control-config.d.ts +21 -0
- package/dist/gateway/control-config.js +18 -0
- package/dist/gateway/control.d.ts +61 -0
- package/dist/gateway/control.js +86 -7
- package/dist/gateway/hosted-proxy.d.ts +3 -0
- package/dist/gateway/hosted-proxy.js +12 -2
- package/dist/gateway/release-admission.d.ts +5 -0
- package/dist/gateway/release-admission.js +19 -0
- package/dist/gateway/server.d.ts +4 -1
- package/dist/gateway/server.js +35 -42
- package/dist/gateway/session.d.ts +9 -8
- package/dist/gateway/session.js +9 -11
- package/dist/gateway/static-files.d.ts +66 -0
- package/dist/gateway/static-files.js +112 -0
- package/dist/gateway/usage.d.ts +13 -0
- package/dist/gateway/usage.js +18 -0
- package/dist/gateway-main.js +8 -5
- package/dist/git-clone.d.ts +1 -3
- package/dist/git-clone.js +6 -8
- package/dist/manifest-next.d.ts +4 -0
- package/dist/manifest-static.d.ts +8 -0
- package/dist/manifest-static.js +5 -0
- package/dist/manifest.d.ts +8 -0
- package/dist/runtime-contracts.d.ts +8 -0
- package/dist/runtime-contracts.js +10 -0
- package/dist/sdk-orm.d.ts +3 -3
- package/dist/source-boundary.d.ts +6 -0
- package/dist/source-boundary.js +7 -2
- package/dist/source-resolver.js +7 -16
- package/dist/templates/nextjs/README.md +7 -0
- package/dist/templates/react-vite/package.json +5 -2
- package/dist/templates/react-vite/tsconfig.json +17 -0
- package/dist/trusted-install.d.ts +9 -2
- package/dist/trusted-install.js +9 -2
- package/package.json +4 -4
- package/templates/nextjs/README.md +7 -0
- package/templates/react-vite/package.json +5 -2
- package/templates/react-vite/tsconfig.json +17 -0
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
export { resolveArtifactNextImages } from './next-image-config.js';
|
|
3
|
+
/** Atlas routes the gateway calls; every one authenticates the gateway itself. */
|
|
4
|
+
export declare const ARTIFACT_NEXT_CONTROL_PATH = "/api/artifact-studio/next/control";
|
|
5
|
+
/**
|
|
6
|
+
* The identity-token audience for gateway control calls: Atlas's public origin plus the control
|
|
7
|
+
* path, whichever address the call is routed to. Path-scoped, so a token minted for another
|
|
8
|
+
* Atlas audience is never accepted here.
|
|
9
|
+
*/
|
|
10
|
+
export declare function artifactNextControlAudience(atlasOrigin: string): string;
|
|
3
11
|
/** Shared by local collection, repository collection and the bounded source-upload API. */
|
|
4
12
|
export declare const ARTIFACT_NEXT_SOURCE_LIMITS: Readonly<{
|
|
5
13
|
maxFiles: 2000;
|
|
@@ -3,6 +3,16 @@ import { ARTIFACT_NEXT_RUNTIME, artifactNextSecretNameSchema } from './manifest-
|
|
|
3
3
|
import { MAX_STUDIO_PATH_LENGTH } from './paths.js';
|
|
4
4
|
import { isLoopbackHostname } from './loopback.js';
|
|
5
5
|
export { resolveArtifactNextImages } from './next-image-config.js';
|
|
6
|
+
/** Atlas routes the gateway calls; every one authenticates the gateway itself. */
|
|
7
|
+
export const ARTIFACT_NEXT_CONTROL_PATH = '/api/artifact-studio/next/control';
|
|
8
|
+
/**
|
|
9
|
+
* The identity-token audience for gateway control calls: Atlas's public origin plus the control
|
|
10
|
+
* path, whichever address the call is routed to. Path-scoped, so a token minted for another
|
|
11
|
+
* Atlas audience is never accepted here.
|
|
12
|
+
*/
|
|
13
|
+
export function artifactNextControlAudience(atlasOrigin) {
|
|
14
|
+
return `${new URL(atlasOrigin).origin}${ARTIFACT_NEXT_CONTROL_PATH}`;
|
|
15
|
+
}
|
|
6
16
|
/** Shared by local collection, repository collection and the bounded source-upload API. */
|
|
7
17
|
export const ARTIFACT_NEXT_SOURCE_LIMITS = Object.freeze({
|
|
8
18
|
maxFiles: 2_000,
|
package/dist/sdk-orm.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type SqlOperationExecutor } from '@sequenceholdings/orm/client';
|
|
2
2
|
import { type ArtifactOrmJsonScalars } from './orm-json-scalars.js';
|
|
3
3
|
import { type SequenceApi } from './sdk.js';
|
|
4
4
|
export interface ArtifactOrmExecutorConfig {
|
|
5
5
|
namespace: string;
|
|
6
6
|
/** The generated operations.manifest.json, validated before any host call. */
|
|
7
|
-
manifest
|
|
7
|
+
manifest?: unknown;
|
|
8
8
|
/** Optional action-scoped host client (for example, withTraceAction's client). */
|
|
9
9
|
sdk?: {
|
|
10
10
|
api: Pick<SequenceApi, 'fetch'>;
|
|
@@ -21,4 +21,4 @@ export interface ArtifactOrmExecutorConfig {
|
|
|
21
21
|
* Declare the namespace path in capabilities.api.write (queries also use POST).
|
|
22
22
|
* Namespace grants, capabilities, row policies, and write checks still apply.
|
|
23
23
|
*/
|
|
24
|
-
export declare function createArtifactOrmExecutor({ namespace, manifest, sdk, jsonScalars }: ArtifactOrmExecutorConfig):
|
|
24
|
+
export declare function createArtifactOrmExecutor({ namespace, manifest, sdk, jsonScalars }: ArtifactOrmExecutorConfig): SqlOperationExecutor;
|
|
@@ -11,3 +11,9 @@ export interface ArtifactSourceBoundaryOptions {
|
|
|
11
11
|
* allowed because they are external to the artifact by design.
|
|
12
12
|
*/
|
|
13
13
|
export declare function rejectOutsideSourcePlugin({ root, trustedExternalRoots, }: ArtifactSourceBoundaryOptions): Plugin;
|
|
14
|
+
/**
|
|
15
|
+
* Whether `filePath` is inside a `node_modules` directory. Bundlers pass
|
|
16
|
+
* Windows paths with forward slashes, so compare in that form whatever the
|
|
17
|
+
* platform separator is.
|
|
18
|
+
*/
|
|
19
|
+
export declare function isNodeModulesPath(filePath: string): boolean;
|
package/dist/source-boundary.js
CHANGED
|
@@ -46,8 +46,13 @@ function isPathWithin(root, candidate) {
|
|
|
46
46
|
function isTrustedExternalPath(filePath, trustedRoots) {
|
|
47
47
|
return trustedRoots.some((trustedRoot) => isPathWithin(trustedRoot, filePath));
|
|
48
48
|
}
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
/**
|
|
50
|
+
* Whether `filePath` is inside a `node_modules` directory. Bundlers pass
|
|
51
|
+
* Windows paths with forward slashes, so compare in that form whatever the
|
|
52
|
+
* platform separator is.
|
|
53
|
+
*/
|
|
54
|
+
export function isNodeModulesPath(filePath) {
|
|
55
|
+
return filePath.replaceAll('\\', '/').includes('/node_modules/');
|
|
51
56
|
}
|
|
52
57
|
function isBareImport(source) {
|
|
53
58
|
return !source.startsWith('.') && !isAbsolute(source);
|
package/dist/source-resolver.js
CHANGED
|
@@ -5,7 +5,7 @@ import { tmpdir } from 'node:os';
|
|
|
5
5
|
import { isAbsolute, join, relative, resolve, sep } from 'node:path';
|
|
6
6
|
import { createScrubbedChildEnv } from './child-environment.js';
|
|
7
7
|
import { materializeRepo, resolveCommitSha, resolveRepo } from './git-service-client.js';
|
|
8
|
-
import { gitServiceCloneUrl,
|
|
8
|
+
import { gitServiceCloneUrl, runGitClone } from './git-clone.js';
|
|
9
9
|
/** True for sources that must be fetched from a remote (git-service / git-url). */
|
|
10
10
|
export function isRemoteSpec(spec) {
|
|
11
11
|
return spec.kind !== 'local';
|
|
@@ -136,21 +136,12 @@ export async function resolveArtifactSource(spec, opts = {}) {
|
|
|
136
136
|
console.log(`[seq-studio] source: ${spec.namespace}/${spec.name}@${ref} (${sha.slice(0, 10)}, ${count} file(s), M2M)`);
|
|
137
137
|
return await materialized({ gitCommit: sha, gitBranch: ref, gitDirty: false });
|
|
138
138
|
}
|
|
139
|
-
//
|
|
140
|
-
//
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
if (pat) {
|
|
146
|
-
const cloneUrl = gitServiceCloneUrl(opts.baseUrl, repo.id);
|
|
147
|
-
await runGitClone({ cloneUrl, destDir: dest, pat, ref: sha });
|
|
148
|
-
console.log(`[seq-studio] source: ${spec.namespace}/${spec.name}@${ref} (${sha.slice(0, 10)}, git clone)`);
|
|
149
|
-
return await materialized({ gitCommit: sha, gitBranch: ref, gitDirty: false });
|
|
150
|
-
}
|
|
151
|
-
throw new Error('Deploying from --repo requires a git PAT. Set ATLAS_GIT_PAT to a token with the ' +
|
|
152
|
-
'repo:read scope (create one in Atlas → Settings → Tokens, or `seq-studio auth pat create`). ' +
|
|
153
|
-
'The git-service clone uses smart-HTTP, which authenticates by PAT — the same token you clone the repo with.');
|
|
139
|
+
// Use the same selected human identity for metadata and Git transport.
|
|
140
|
+
// An ambient PAT must not silently change the principal on the clone.
|
|
141
|
+
const cloneUrl = gitServiceCloneUrl(opts.baseUrl, repo.id);
|
|
142
|
+
await runGitClone({ cloneUrl, destDir: dest, pat: opts.token, ref: sha });
|
|
143
|
+
console.log(`[seq-studio] source: ${spec.namespace}/${spec.name}@${ref} (${sha.slice(0, 10)}, git clone)`);
|
|
144
|
+
return await materialized({ gitCommit: sha, gitBranch: ref, gitDirty: false });
|
|
154
145
|
}
|
|
155
146
|
const { sha, branch } = cloneGitUrl(spec.url, spec.ref, dest);
|
|
156
147
|
console.log(`[seq-studio] source: ${redactGitUrl(spec.url)}${spec.ref ? `@${spec.ref}` : ''} (${sha.slice(0, 10)})`);
|
|
@@ -179,6 +179,13 @@ own test credentials, mocks or an existing governed function. Use a hosted
|
|
|
179
179
|
preview for application code that needs a managed secret. Never put secrets in
|
|
180
180
|
`build.public_env`, `NEXT_PUBLIC_*`, client components or committed files.
|
|
181
181
|
|
|
182
|
+
Cookies your application sets itself should use a `__Host-` name with `Secure`,
|
|
183
|
+
`HttpOnly`, `Path=/` and no `Domain`. Applications on one deployment share a
|
|
184
|
+
registrable domain, and only a `__Host-` cookie is guaranteed to come from your
|
|
185
|
+
own origin rather than a neighbour's. When the application origin is on a
|
|
186
|
+
different site from its Atlas frame, a cookie it needs there must also be
|
|
187
|
+
`SameSite=None; Partitioned`, or the browser drops it.
|
|
188
|
+
|
|
182
189
|
The local process is ordinary code running as your operating-system user.
|
|
183
190
|
Atlas governs access to platform resources; it does not sandbox your laptop's
|
|
184
191
|
filesystem or all outbound network connections.
|
|
@@ -5,15 +5,18 @@
|
|
|
5
5
|
"scripts": {
|
|
6
6
|
"dev": "vite",
|
|
7
7
|
"build": "vite build",
|
|
8
|
-
"preview": "vite preview"
|
|
8
|
+
"preview": "vite preview",
|
|
9
|
+
"type-check": "tsc --noEmit"
|
|
9
10
|
},
|
|
10
11
|
"dependencies": {},
|
|
11
12
|
"devDependencies": {
|
|
12
|
-
"@sequenceholdings/artifact-studio": "^0.
|
|
13
|
+
"@sequenceholdings/artifact-studio": "^0.7.0",
|
|
13
14
|
"@sequenceholdings/atlas-ui": "^3.1.1",
|
|
14
15
|
"@tailwindcss/postcss": "^4.2.2",
|
|
15
16
|
"@tailwindcss/vite": "^4.2.2",
|
|
16
17
|
"@tanstack/react-query": "^4.36.1",
|
|
18
|
+
"@types/react": "^18.3.31",
|
|
19
|
+
"@types/react-dom": "^18.3.7",
|
|
17
20
|
"@vitejs/plugin-react": "^5.0.0",
|
|
18
21
|
"react": "^18.2.0",
|
|
19
22
|
"react-dom": "^18.2.0",
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"lib": ["dom", "dom.iterable", "esnext"],
|
|
5
|
+
"skipLibCheck": true,
|
|
6
|
+
"strict": true,
|
|
7
|
+
"noEmit": true,
|
|
8
|
+
"esModuleInterop": true,
|
|
9
|
+
"module": "esnext",
|
|
10
|
+
"moduleResolution": "bundler",
|
|
11
|
+
"resolveJsonModule": true,
|
|
12
|
+
"isolatedModules": true,
|
|
13
|
+
"jsx": "react-jsx",
|
|
14
|
+
"types": ["vite/client"]
|
|
15
|
+
},
|
|
16
|
+
"include": ["src", "vite.config.ts"]
|
|
17
|
+
}
|
|
@@ -7,7 +7,14 @@ export declare const PNPM_WORKSPACE_FILE_RE: RegExp;
|
|
|
7
7
|
/** Platform peers the CLI aliases at build time — must not be prod-installed remotely. */
|
|
8
8
|
export declare const REMOTE_INSTALL_PLATFORM_PACKAGES: Set<string>;
|
|
9
9
|
/**
|
|
10
|
-
*
|
|
11
|
-
* `pnpm install`
|
|
10
|
+
* Trust gate for remote static React/Vite artifact installs (called by
|
|
11
|
+
* `prepare-build.ts` before `pnpm install`); also reused for remote process repos.
|
|
12
|
+
* It rejects install-control files and non-registry dependency specs.
|
|
13
|
+
*
|
|
14
|
+
* Hosted Next.js builds use `prepareHostedBuildSource` in Atlas
|
|
15
|
+
* `next-hosted/source-policy.ts` and a controlled install workspace from
|
|
16
|
+
* `hostedInstallWorkspace` in `next-hosted/release-age.ts` instead. Do not apply
|
|
17
|
+
* this static gate to a Next.js template: its workspace file and approved
|
|
18
|
+
* platform dependencies follow the hosted policy.
|
|
12
19
|
*/
|
|
13
20
|
export declare function assertTrustedArtifactInstallTree(dir: string): void;
|
package/dist/trusted-install.js
CHANGED
|
@@ -225,8 +225,15 @@ function assertChainguardLockfile(dir) {
|
|
|
225
225
|
assertParsedPackageResolutions(lockfileText);
|
|
226
226
|
}
|
|
227
227
|
/**
|
|
228
|
-
*
|
|
229
|
-
* `pnpm install`
|
|
228
|
+
* Trust gate for remote static React/Vite artifact installs (called by
|
|
229
|
+
* `prepare-build.ts` before `pnpm install`); also reused for remote process repos.
|
|
230
|
+
* It rejects install-control files and non-registry dependency specs.
|
|
231
|
+
*
|
|
232
|
+
* Hosted Next.js builds use `prepareHostedBuildSource` in Atlas
|
|
233
|
+
* `next-hosted/source-policy.ts` and a controlled install workspace from
|
|
234
|
+
* `hostedInstallWorkspace` in `next-hosted/release-age.ts` instead. Do not apply
|
|
235
|
+
* this static gate to a Next.js template: its workspace file and approved
|
|
236
|
+
* platform dependencies follow the hosted policy.
|
|
230
237
|
*/
|
|
231
238
|
export function assertTrustedArtifactInstallTree(dir) {
|
|
232
239
|
for (const rel of listRelativeFiles(dir)) {
|
package/package.json
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"publishConfig": {
|
|
10
10
|
"access": "public"
|
|
11
11
|
},
|
|
12
|
-
"version": "0.
|
|
12
|
+
"version": "0.7.1",
|
|
13
13
|
"description": "SDK types and CLI library for building Artifact Studio apps. Driven via `seq-studio artifact <sub>` (@sequenceholdings/studio-cli), which runs the `./cli` runCli export.",
|
|
14
14
|
"type": "module",
|
|
15
15
|
"exports": {
|
|
@@ -159,6 +159,7 @@
|
|
|
159
159
|
"sonner": "^2.0.7",
|
|
160
160
|
"tailwindcss": "^4.1.8",
|
|
161
161
|
"tw-animate-css": "^1.4.0",
|
|
162
|
+
"typescript": "^5.6.0",
|
|
162
163
|
"vite": "8.0.16",
|
|
163
164
|
"zod": "^4.1.13",
|
|
164
165
|
"ws": "^8.21.0",
|
|
@@ -166,14 +167,13 @@
|
|
|
166
167
|
"google-auth-library": "^10.5.0",
|
|
167
168
|
"server-only": "0.0.1",
|
|
168
169
|
"parse5": "7.3.0",
|
|
170
|
+
"@sequenceholdings/lattice-form-renderer": "0.2.0",
|
|
169
171
|
"@sequenceholdings/storage": "0.1.1",
|
|
170
|
-
"@sequenceholdings/orm": "2.
|
|
171
|
-
"@sequenceholdings/lattice-form-renderer": "0.2.0"
|
|
172
|
+
"@sequenceholdings/orm": "2.6.1"
|
|
172
173
|
},
|
|
173
174
|
"devDependencies": {
|
|
174
175
|
"@types/js-yaml": "^4.0.9",
|
|
175
176
|
"@types/node": "^22.0.0",
|
|
176
|
-
"typescript": "^5.6.0",
|
|
177
177
|
"vitest": "^4.1.11",
|
|
178
178
|
"@types/ws": "^8.18.1"
|
|
179
179
|
},
|
|
@@ -179,6 +179,13 @@ own test credentials, mocks or an existing governed function. Use a hosted
|
|
|
179
179
|
preview for application code that needs a managed secret. Never put secrets in
|
|
180
180
|
`build.public_env`, `NEXT_PUBLIC_*`, client components or committed files.
|
|
181
181
|
|
|
182
|
+
Cookies your application sets itself should use a `__Host-` name with `Secure`,
|
|
183
|
+
`HttpOnly`, `Path=/` and no `Domain`. Applications on one deployment share a
|
|
184
|
+
registrable domain, and only a `__Host-` cookie is guaranteed to come from your
|
|
185
|
+
own origin rather than a neighbour's. When the application origin is on a
|
|
186
|
+
different site from its Atlas frame, a cookie it needs there must also be
|
|
187
|
+
`SameSite=None; Partitioned`, or the browser drops it.
|
|
188
|
+
|
|
182
189
|
The local process is ordinary code running as your operating-system user.
|
|
183
190
|
Atlas governs access to platform resources; it does not sandbox your laptop's
|
|
184
191
|
filesystem or all outbound network connections.
|
|
@@ -5,15 +5,18 @@
|
|
|
5
5
|
"scripts": {
|
|
6
6
|
"dev": "vite",
|
|
7
7
|
"build": "vite build",
|
|
8
|
-
"preview": "vite preview"
|
|
8
|
+
"preview": "vite preview",
|
|
9
|
+
"type-check": "tsc --noEmit"
|
|
9
10
|
},
|
|
10
11
|
"dependencies": {},
|
|
11
12
|
"devDependencies": {
|
|
12
|
-
"@sequenceholdings/artifact-studio": "^0.
|
|
13
|
+
"@sequenceholdings/artifact-studio": "^0.7.0",
|
|
13
14
|
"@sequenceholdings/atlas-ui": "^3.1.1",
|
|
14
15
|
"@tailwindcss/postcss": "^4.2.2",
|
|
15
16
|
"@tailwindcss/vite": "^4.2.2",
|
|
16
17
|
"@tanstack/react-query": "^4.36.1",
|
|
18
|
+
"@types/react": "^18.3.31",
|
|
19
|
+
"@types/react-dom": "^18.3.7",
|
|
17
20
|
"@vitejs/plugin-react": "^5.0.0",
|
|
18
21
|
"react": "^18.2.0",
|
|
19
22
|
"react-dom": "^18.2.0",
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"lib": ["dom", "dom.iterable", "esnext"],
|
|
5
|
+
"skipLibCheck": true,
|
|
6
|
+
"strict": true,
|
|
7
|
+
"noEmit": true,
|
|
8
|
+
"esModuleInterop": true,
|
|
9
|
+
"module": "esnext",
|
|
10
|
+
"moduleResolution": "bundler",
|
|
11
|
+
"resolveJsonModule": true,
|
|
12
|
+
"isolatedModules": true,
|
|
13
|
+
"jsx": "react-jsx",
|
|
14
|
+
"types": ["vite/client"]
|
|
15
|
+
},
|
|
16
|
+
"include": ["src", "vite.config.ts"]
|
|
17
|
+
}
|