@sequenceholdings/artifact-studio 0.7.1 → 0.8.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/dist/build.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { existsSync } from 'node:fs';
2
- import { mkdir, writeFile } from 'node:fs/promises';
2
+ import { mkdir, realpath, writeFile } from 'node:fs/promises';
3
3
  import { createRequire } from 'node:module';
4
4
  import { dirname, relative, resolve } from 'node:path';
5
5
  import { fileURLToPath } from 'node:url';
@@ -122,7 +122,9 @@ export async function buildArtifactStudioProject(rootDir, { candidateTokenCompat
122
122
  ? collectCandidateTokenCompatibilityDiagnostics({ files: source.files })
123
123
  : []),
124
124
  ];
125
- const root = source.root;
125
+ // Vite resolves imports to physical paths, including macOS /tmp -> /private/tmp.
126
+ // Give Vite and the source boundary the same physical root.
127
+ const root = await realpath(source.root);
126
128
  const transformedCssModules = new Map();
127
129
  const result = await viteBuild({
128
130
  root,
@@ -28,6 +28,9 @@ export declare const artifactNextServerCapabilitiesSchema: z.ZodPrefault<z.ZodOb
28
28
  audit: z.ZodOptional<z.ZodObject<{
29
29
  service: z.ZodString;
30
30
  }, z.core.$strict>>;
31
+ groups: z.ZodOptional<z.ZodObject<{
32
+ read: z.ZodBoolean;
33
+ }, z.core.$strict>>;
31
34
  storage: z.ZodOptional<z.ZodRecord<z.ZodUUID, z.ZodEnum<{
32
35
  viewer: "viewer";
33
36
  editor: "editor";
@@ -89,6 +92,9 @@ export declare const artifactNextServerSchema: z.ZodPrefault<z.ZodObject<{
89
92
  audit: z.ZodOptional<z.ZodObject<{
90
93
  service: z.ZodString;
91
94
  }, z.core.$strict>>;
95
+ groups: z.ZodOptional<z.ZodObject<{
96
+ read: z.ZodBoolean;
97
+ }, z.core.$strict>>;
92
98
  storage: z.ZodOptional<z.ZodRecord<z.ZodUUID, z.ZodEnum<{
93
99
  viewer: "viewer";
94
100
  editor: "editor";
@@ -280,6 +286,9 @@ export declare const artifactStudioNextManifestSchema: z.ZodObject<{
280
286
  audit: z.ZodOptional<z.ZodObject<{
281
287
  service: z.ZodString;
282
288
  }, z.core.$strict>>;
289
+ groups: z.ZodOptional<z.ZodObject<{
290
+ read: z.ZodBoolean;
291
+ }, z.core.$strict>>;
283
292
  storage: z.ZodOptional<z.ZodRecord<z.ZodUUID, z.ZodEnum<{
284
293
  viewer: "viewer";
285
294
  editor: "editor";
@@ -15,9 +15,14 @@ export const ARTIFACT_NEXT_RESOURCE_DEFAULTS = {
15
15
  };
16
16
  export { artifactNextAuditCapabilitySchema };
17
17
  export * from './manifest-next-ingress.js';
18
+ /** Caller-scoped group membership. A boolean, not a list of group ids: the directory decides which groups the signed-in user is in. */
19
+ const artifactNextGroupsCapabilitySchema = z.strictObject({
20
+ read: z.boolean(),
21
+ });
18
22
  export const artifactNextServerCapabilitiesSchema = z.strictObject({
19
23
  ...reachShape,
20
24
  audit: artifactNextAuditCapabilitySchema.optional(),
25
+ groups: artifactNextGroupsCapabilitySchema.optional(),
21
26
  }).prefault({});
22
27
  // Reuse role semantics and validation; only the new manifest rejects unknown keys.
23
28
  const strictCustomRoles = customRolesBlockSchema.safeExtend({
@@ -167,6 +167,9 @@ export declare const artifactStudioManifestSchema: z.ZodUnion<readonly [z.ZodObj
167
167
  audit: z.ZodOptional<z.ZodObject<{
168
168
  service: z.ZodString;
169
169
  }, z.core.$strict>>;
170
+ groups: z.ZodOptional<z.ZodObject<{
171
+ read: z.ZodBoolean;
172
+ }, z.core.$strict>>;
170
173
  storage: z.ZodOptional<z.ZodRecord<z.ZodUUID, z.ZodEnum<{
171
174
  viewer: "viewer";
172
175
  editor: "editor";
@@ -18,6 +18,10 @@ export declare function isArtifactApiPath(path: string): boolean;
18
18
  export declare const ARTIFACT_PROCESS_RUN_STATUSES: readonly ["pending", "running", "completed", "failed", "cancelled", "timed_out"];
19
19
  /** Lattice lists at most this many runs per call. */
20
20
  export declare const ARTIFACT_PROCESS_RUNS_LIMIT = 500;
21
+ /** One page of the caller's own group memberships. */
22
+ export declare const ARTIFACT_GROUP_MEMBERSHIPS_LIMIT = 100;
23
+ /** How far a caller may page their own memberships. The directory is not walked past this. */
24
+ export declare const ARTIFACT_GROUP_MEMBERSHIPS_MAX_PAGE = 100;
21
25
  /** A run page can filter to at most this many entities of one type. */
22
26
  export declare const ARTIFACT_PROCESS_RUN_ENTITIES_LIMIT = 500;
23
27
  /** A run share adds collaborators to at most this many explicitly assigned human nodes. */
@@ -298,6 +302,14 @@ export declare const artifactServerRequestSchema: z.ZodDiscriminatedUnion<[z.Zod
298
302
  group: "group";
299
303
  }>>>;
300
304
  limit: z.ZodOptional<z.ZodNumber>;
305
+ }, z.core.$strict>, z.ZodObject<{
306
+ operation: z.ZodLiteral<"groups_memberships">;
307
+ mode: z.ZodDefault<z.ZodEnum<{
308
+ service: "service";
309
+ user: "user";
310
+ }>>;
311
+ page: z.ZodOptional<z.ZodNumber>;
312
+ limit: z.ZodOptional<z.ZodNumber>;
301
313
  }, z.core.$strict>, z.ZodObject<{
302
314
  operation: z.ZodLiteral<"flags">;
303
315
  mode: z.ZodDefault<z.ZodEnum<{
@@ -31,6 +31,10 @@ const latticeVersion = z.string().min(1).max(128).regex(/^[A-Za-z0-9._-]+$/);
31
31
  export const ARTIFACT_PROCESS_RUN_STATUSES = ['pending', 'running', 'completed', 'failed', 'cancelled', 'timed_out'];
32
32
  /** Lattice lists at most this many runs per call. */
33
33
  export const ARTIFACT_PROCESS_RUNS_LIMIT = 500;
34
+ /** One page of the caller's own group memberships. */
35
+ export const ARTIFACT_GROUP_MEMBERSHIPS_LIMIT = 100;
36
+ /** How far a caller may page their own memberships. The directory is not walked past this. */
37
+ export const ARTIFACT_GROUP_MEMBERSHIPS_MAX_PAGE = 100;
34
38
  /** A run page can filter to at most this many entities of one type. */
35
39
  export const ARTIFACT_PROCESS_RUN_ENTITIES_LIMIT = 500;
36
40
  /** A run share adds collaborators to at most this many explicitly assigned human nodes. */
@@ -225,6 +229,13 @@ export const artifactServerRequestSchema = z.discriminatedUnion('operation', [
225
229
  types: z.array(z.enum(ARTIFACT_PROCESS_PRINCIPAL_TYPES)).min(1).max(2).optional(),
226
230
  limit: z.number().int().min(1).max(ARTIFACT_PROCESS_PRINCIPAL_SEARCH_LIMIT).optional(),
227
231
  }).strict(),
232
+ // The signed-in user's own group memberships. No search, no admin directory, no group-id allowlist:
233
+ // the directory returns the groups this user is in. Service mode is refused by the handler.
234
+ z.object({
235
+ operation: z.literal('groups_memberships'), mode,
236
+ page: z.number().int().min(1).max(ARTIFACT_GROUP_MEMBERSHIPS_MAX_PAGE).optional(),
237
+ limit: z.number().int().min(1).max(ARTIFACT_GROUP_MEMBERSHIPS_LIMIT).optional(),
238
+ }).strict(),
228
239
  // Evaluates feature flags as Atlas evaluates its own: for the user, or with no user in service mode.
229
240
  // A read: it needs no manifest declaration, as the browser bridge's flags.isEnabled needs none.
230
241
  z.object({ operation: z.literal('flags'), mode, names: z.array(flagName).min(1).max(ARTIFACT_FLAGS_PER_REQUEST) }).strict(),
@@ -1,6 +1,7 @@
1
1
  import { storageClient } from '@sequenceholdings/storage';
2
2
  import { type OperationExecutor } from '@sequenceholdings/orm/client';
3
3
  import { type ArtifactAuditAction, type ArtifactServerMode } from './broker-contract.js';
4
+ import { type ArtifactServerGroups } from './groups.js';
4
5
  import { type ArtifactServerProcesses } from './processes.js';
5
6
  import { type ArtifactOrmJsonScalars } from '../orm-json-scalars.js';
6
7
  import { createArtifactLogger, type ArtifactLogRecord } from './logger.js';
@@ -10,6 +11,7 @@ import { createApiClient } from './api-client.js';
10
11
  import { type ArtifactPrincipal } from './principal.js';
11
12
  import { type ArtifactRuntimeConfig, type ArtifactRequestHeaders } from './runtime-config.js';
12
13
  export { ArtifactPrincipalError, ArtifactServerError, INSUFFICIENT_USER_AUTHENTICATION, stepUpResponse } from './errors.js';
14
+ export type * from './groups.js';
13
15
  export type * from './processes.js';
14
16
  export type { ArtifactServerFetchOptions } from './api-client.js';
15
17
  /**
@@ -82,6 +84,7 @@ export interface ArtifactServerClient<TContext extends ArtifactServerContext = A
82
84
  invoke<TOutput = unknown>(id: string, params?: Record<string, unknown>): Promise<TOutput>;
83
85
  };
84
86
  processes: ArtifactServerProcesses;
87
+ groups: ArtifactServerGroups;
85
88
  flags: ArtifactServerFlags;
86
89
  audit: ArtifactServerAudit;
87
90
  orm(input: ArtifactOrmOptions): OperationExecutor;
@@ -3,6 +3,7 @@ import { StorageApiError, storageClient, storageErrorSchema } from '@sequencehol
3
3
  import { OrmOperationError } from '@sequenceholdings/orm/client';
4
4
  import { z } from 'zod';
5
5
  import { artifactOrmIdempotencyKeySchema, artifactServerRequestSchema } from './broker-contract.js';
6
+ import { createArtifactGroupsClient } from './groups.js';
6
7
  import { createArtifactProcessesClient } from './processes.js';
7
8
  import { assertJsonScalarsAcknowledged, ORM_JSON_SCALARS_HEADER } from '../orm-json-scalars.js';
8
9
  import { createArtifactLogger } from './logger.js';
@@ -96,6 +97,7 @@ function buildClient(args) {
96
97
  },
97
98
  },
98
99
  processes: createArtifactProcessesClient({ mode, json }),
100
+ groups: createArtifactGroupsClient({ mode, json }),
99
101
  flags: {
100
102
  evaluate: evaluateFlags,
101
103
  isEnabled: async (flagName) => (await evaluateFlags([flagName]))[flagName] === true,
@@ -0,0 +1,32 @@
1
+ import { type ArtifactServerMode, type ArtifactServerRequest } from './broker-contract.js';
2
+ /** One group the signed-in user belongs to. `userRole` is `admin` when they administer it. */
3
+ export interface ArtifactGroupMembership {
4
+ id: string;
5
+ userRole: 'admin' | 'member';
6
+ memberCount: number;
7
+ }
8
+ export interface ArtifactGroupMembershipsQuery {
9
+ page?: number;
10
+ limit?: number;
11
+ }
12
+ export interface ArtifactGroupMembershipsPage {
13
+ groups: ArtifactGroupMembership[];
14
+ pagination: {
15
+ page: number;
16
+ limit: number;
17
+ totalCount: number;
18
+ totalPages: number;
19
+ };
20
+ }
21
+ export interface ArtifactServerGroups {
22
+ /**
23
+ * The signed-in user's group memberships. Requires `server.capabilities.groups.read`.
24
+ * Atlas decides which groups they are in; this call cannot name groups, search the directory,
25
+ * or read another user's memberships.
26
+ */
27
+ list(query?: ArtifactGroupMembershipsQuery): Promise<ArtifactGroupMembershipsPage>;
28
+ }
29
+ export declare function createArtifactGroupsClient({ mode, json }: {
30
+ mode: ArtifactServerMode;
31
+ json: (operation: ArtifactServerRequest) => Promise<unknown>;
32
+ }): ArtifactServerGroups;
@@ -0,0 +1,28 @@
1
+ import { z } from 'zod';
2
+ import { ARTIFACT_GROUP_MEMBERSHIPS_LIMIT, artifactServerRequestSchema, } from './broker-contract.js';
3
+ import { ArtifactServerError } from './errors.js';
4
+ const membershipsPageSchema = z.object({
5
+ groups: z.array(z.object({
6
+ id: z.string().min(1).max(255),
7
+ userRole: z.enum(['admin', 'member']),
8
+ memberCount: z.number().int().nonnegative(),
9
+ }).strict()),
10
+ pagination: z.object({
11
+ page: z.number().int().min(1),
12
+ limit: z.number().int().min(1).max(ARTIFACT_GROUP_MEMBERSHIPS_LIMIT),
13
+ totalCount: z.number().int().nonnegative(),
14
+ totalPages: z.number().int().nonnegative(),
15
+ }).strict(),
16
+ }).strict();
17
+ export function createArtifactGroupsClient({ mode, json }) {
18
+ return {
19
+ async list(query = {}) {
20
+ const parsed = membershipsPageSchema.safeParse(await json(artifactServerRequestSchema.parse({
21
+ operation: 'groups_memberships', mode, ...query,
22
+ })));
23
+ if (!parsed.success)
24
+ throw new ArtifactServerError(502, 'invalid_response', 'Atlas returned a malformed groups response');
25
+ return parsed.data;
26
+ },
27
+ };
28
+ }
package/dist/server.d.ts CHANGED
@@ -2,8 +2,8 @@ import 'server-only';
2
2
  export { createArtifactServerClient } from './server/client.js';
3
3
  export { ArtifactPrincipalError, ArtifactServerError, INSUFFICIENT_USER_AUTHENTICATION, stepUpResponse } from './server/errors.js';
4
4
  export type { ArtifactAtlasRefusal } from './server/errors.js';
5
- export type { ArtifactAuditEvent, ArtifactOrmOperations, ArtifactOrmOptions, ArtifactProcessAdvance, ArtifactProcessAdvanceResult, ArtifactProcessArtifactRef, ArtifactProcessAssign, ArtifactProcessAssignResult, ArtifactProcessDefinition, ArtifactProcessDescribeQuery, ArtifactProcessEdge, ArtifactProcessHumanNode, ArtifactProcessNode, ArtifactProcessNodeBase, ArtifactProcessNodeState, ArtifactProcessPrincipal, ArtifactProcessPrincipalSearch, ArtifactProcessPrincipals, ArtifactProcessRun, ArtifactProcessRunRecord, ArtifactProcessRunSnapshot, ArtifactProcessRunSummary, ArtifactProcessRunsPage, ArtifactProcessRunsPageQuery, ArtifactProcessRunsQuery, ArtifactProcessRunViewerChange, ArtifactProcessRunViewers, ArtifactProcessStart, ArtifactProcessStepRecord, ArtifactProcessShareRun, ArtifactProcessShareRunResult, ArtifactProcessRunSharingAuthoritiesQuery, ArtifactProcessRunSharingAuthoritiesPage, ArtifactProcessRunSharingAuthority, ArtifactProcessRunSharingDelegate, ArtifactProcessRevokeRunSharingAuthority, ArtifactProcessRevokeRunSharingAuthorityResult, ArtifactProcessTask, ArtifactProcessTasksQuery, ArtifactServerAudit, ArtifactServerClient, ArtifactServerClientOptions, ArtifactServerContext, ArtifactServerFetchOptions, ArtifactServerFlags, ArtifactServerProcesses, } from './server/client.js';
6
- export { ARTIFACT_AUDIT_ACTIONS, ARTIFACT_AUDIT_RESOURCES_PER_EVENT, ARTIFACT_FLAGS_PER_REQUEST, ARTIFACT_PROCESS_PRINCIPAL_SEARCH_LIMIT, ARTIFACT_PROCESS_PRINCIPAL_TYPES, ARTIFACT_PROCESS_PRINCIPALS_PER_CALL, ARTIFACT_PROCESS_RUN_STATUSES, ARTIFACT_PROCESS_RUNS_LIMIT, ARTIFACT_PROCESS_RUN_ENTITIES_LIMIT, ARTIFACT_PROCESS_SHARE_NODES_LIMIT, ARTIFACT_PROCESS_SHARING_AUTHORITIES_LIMIT, ARTIFACT_PROCESS_TASK_VIEWS, ARTIFACT_PROCESS_TASKS_LIMIT, } from './server/broker-contract.js';
5
+ export type { ArtifactAuditEvent, ArtifactOrmOperations, ArtifactOrmOptions, ArtifactProcessAdvance, ArtifactProcessAdvanceResult, ArtifactProcessArtifactRef, ArtifactProcessAssign, ArtifactProcessAssignResult, ArtifactProcessDefinition, ArtifactProcessDescribeQuery, ArtifactProcessEdge, ArtifactProcessHumanNode, ArtifactProcessNode, ArtifactProcessNodeBase, ArtifactProcessNodeState, ArtifactProcessPrincipal, ArtifactProcessPrincipalSearch, ArtifactProcessPrincipals, ArtifactProcessRun, ArtifactProcessRunRecord, ArtifactProcessRunSnapshot, ArtifactProcessRunSummary, ArtifactProcessRunsPage, ArtifactProcessRunsPageQuery, ArtifactProcessRunsQuery, ArtifactProcessRunViewerChange, ArtifactProcessRunViewers, ArtifactProcessStart, ArtifactProcessStepRecord, ArtifactProcessShareRun, ArtifactProcessShareRunResult, ArtifactProcessRunSharingAuthoritiesQuery, ArtifactProcessRunSharingAuthoritiesPage, ArtifactProcessRunSharingAuthority, ArtifactProcessRunSharingDelegate, ArtifactProcessRevokeRunSharingAuthority, ArtifactProcessRevokeRunSharingAuthorityResult, ArtifactProcessTask, ArtifactProcessTasksQuery, ArtifactServerAudit, ArtifactServerClient, ArtifactServerClientOptions, ArtifactServerContext, ArtifactServerFetchOptions, ArtifactServerFlags, ArtifactServerGroups, ArtifactServerProcesses, ArtifactGroupMembership, ArtifactGroupMembershipsPage, ArtifactGroupMembershipsQuery, } from './server/client.js';
6
+ export { ARTIFACT_AUDIT_ACTIONS, ARTIFACT_AUDIT_RESOURCES_PER_EVENT, ARTIFACT_FLAGS_PER_REQUEST, ARTIFACT_GROUP_MEMBERSHIPS_LIMIT, ARTIFACT_GROUP_MEMBERSHIPS_MAX_PAGE, ARTIFACT_PROCESS_PRINCIPAL_SEARCH_LIMIT, ARTIFACT_PROCESS_PRINCIPAL_TYPES, ARTIFACT_PROCESS_PRINCIPALS_PER_CALL, ARTIFACT_PROCESS_RUN_STATUSES, ARTIFACT_PROCESS_RUNS_LIMIT, ARTIFACT_PROCESS_RUN_ENTITIES_LIMIT, ARTIFACT_PROCESS_SHARE_NODES_LIMIT, ARTIFACT_PROCESS_SHARING_AUTHORITIES_LIMIT, ARTIFACT_PROCESS_TASK_VIEWS, ARTIFACT_PROCESS_TASKS_LIMIT, } from './server/broker-contract.js';
7
7
  export type { ArtifactAuditAction, ArtifactProcessPrincipalType, ArtifactProcessRunStatus, ArtifactProcessTaskView, } from './server/broker-contract.js';
8
8
  export { getArtifactRequestContext, readArtifactRuntimeConfig } from './server/runtime-config.js';
9
9
  export type { ArtifactRuntimeConfig, ArtifactRequestHeaders } from './server/runtime-config.js';
package/dist/server.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import 'server-only';
2
2
  export { createArtifactServerClient } from './server/client.js';
3
3
  export { ArtifactPrincipalError, ArtifactServerError, INSUFFICIENT_USER_AUTHENTICATION, stepUpResponse } from './server/errors.js';
4
- export { ARTIFACT_AUDIT_ACTIONS, ARTIFACT_AUDIT_RESOURCES_PER_EVENT, ARTIFACT_FLAGS_PER_REQUEST, ARTIFACT_PROCESS_PRINCIPAL_SEARCH_LIMIT, ARTIFACT_PROCESS_PRINCIPAL_TYPES, ARTIFACT_PROCESS_PRINCIPALS_PER_CALL, ARTIFACT_PROCESS_RUN_STATUSES, ARTIFACT_PROCESS_RUNS_LIMIT, ARTIFACT_PROCESS_RUN_ENTITIES_LIMIT, ARTIFACT_PROCESS_SHARE_NODES_LIMIT, ARTIFACT_PROCESS_SHARING_AUTHORITIES_LIMIT, ARTIFACT_PROCESS_TASK_VIEWS, ARTIFACT_PROCESS_TASKS_LIMIT, } from './server/broker-contract.js';
4
+ export { ARTIFACT_AUDIT_ACTIONS, ARTIFACT_AUDIT_RESOURCES_PER_EVENT, ARTIFACT_FLAGS_PER_REQUEST, ARTIFACT_GROUP_MEMBERSHIPS_LIMIT, ARTIFACT_GROUP_MEMBERSHIPS_MAX_PAGE, ARTIFACT_PROCESS_PRINCIPAL_SEARCH_LIMIT, ARTIFACT_PROCESS_PRINCIPAL_TYPES, ARTIFACT_PROCESS_PRINCIPALS_PER_CALL, ARTIFACT_PROCESS_RUN_STATUSES, ARTIFACT_PROCESS_RUNS_LIMIT, ARTIFACT_PROCESS_RUN_ENTITIES_LIMIT, ARTIFACT_PROCESS_SHARE_NODES_LIMIT, ARTIFACT_PROCESS_SHARING_AUTHORITIES_LIMIT, ARTIFACT_PROCESS_TASK_VIEWS, ARTIFACT_PROCESS_TASKS_LIMIT, } from './server/broker-contract.js';
5
5
  export { getArtifactRequestContext, readArtifactRuntimeConfig } from './server/runtime-config.js';
6
6
  export { ArtifactContextError, getArtifactBrowserBootstrap } from './server/request-context.js';
7
7
  export { verifyArtifactExternalContext } from './server/external-context.js';
@@ -1,3 +1,4 @@
1
+ import { realpathSync } from 'node:fs';
1
2
  import { isAbsolute, relative, resolve, sep } from 'node:path';
2
3
  /**
3
4
  * Artifact source must be self-contained: allowing a relative import to escape
@@ -7,8 +8,8 @@ import { isAbsolute, relative, resolve, sep } from 'node:path';
7
8
  * allowed because they are external to the artifact by design.
8
9
  */
9
10
  export function rejectOutsideSourcePlugin({ root, trustedExternalRoots, }) {
10
- const rootResolved = resolve(root);
11
- const trustedRoots = trustedExternalRoots.map((trustedRoot) => resolve(trustedRoot));
11
+ const rootResolved = realpathSync(resolve(root));
12
+ const trustedRoots = trustedExternalRoots.map((trustedRoot) => realpathSync(resolve(trustedRoot)));
12
13
  return {
13
14
  name: 'reject-artifact-outside-source',
14
15
  enforce: 'pre',
@@ -17,15 +18,22 @@ export function rejectOutsideSourcePlugin({ root, trustedExternalRoots, }) {
17
18
  if (!resolved || resolved.external || resolved.id.startsWith('\0'))
18
19
  return resolved;
19
20
  const filePath = resolved.id.split('?')[0];
20
- if (!isAbsolute(filePath) || isPathWithin(rootResolved, filePath))
21
+ if (!isAbsolute(filePath))
22
+ return resolved;
23
+ // Vite may return a physical path for a root reached through /tmp or
24
+ // another symlink. Check physical paths on both sides of the boundary;
25
+ // this also prevents an in-root symlink from admitting an outside file.
26
+ const realFilePath = realpathSync(filePath);
27
+ if (isPathWithin(rootResolved, realFilePath))
21
28
  return resolved;
22
29
  const importerPath = importer?.split('?')[0];
23
30
  const importerIsTrustedExternal = importerPath != null &&
24
- (isNodeModulesPath(importerPath) || isTrustedExternalPath(importerPath, trustedRoots));
31
+ (isNodeModulesPath(importerPath) ||
32
+ (isAbsolute(importerPath) && isTrustedExternalPath(realpathSync(importerPath), trustedRoots)));
25
33
  if (isNodeModulesPath(filePath) && (isBareImport(source) || importerIsTrustedExternal)) {
26
34
  return resolved;
27
35
  }
28
- if (isTrustedExternalPath(filePath, trustedRoots))
36
+ if (isTrustedExternalPath(realFilePath, trustedRoots))
29
37
  return resolved;
30
38
  const from = importer
31
39
  ? ` (imported from ${relative(rootResolved, importer.split('?')[0])})`
@@ -10,7 +10,7 @@
10
10
  },
11
11
  "dependencies": {},
12
12
  "devDependencies": {
13
- "@sequenceholdings/artifact-studio": "^0.7.0",
13
+ "@sequenceholdings/artifact-studio": "^0.8.0",
14
14
  "@sequenceholdings/atlas-ui": "^3.1.1",
15
15
  "@tailwindcss/postcss": "^4.2.2",
16
16
  "@tailwindcss/vite": "^4.2.2",
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  "publishConfig": {
10
10
  "access": "public"
11
11
  },
12
- "version": "0.7.1",
12
+ "version": "0.8.0",
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": {
@@ -167,9 +167,9 @@
167
167
  "google-auth-library": "^10.5.0",
168
168
  "server-only": "0.0.1",
169
169
  "parse5": "7.3.0",
170
- "@sequenceholdings/lattice-form-renderer": "0.2.0",
171
170
  "@sequenceholdings/storage": "0.1.1",
172
- "@sequenceholdings/orm": "2.6.1"
171
+ "@sequenceholdings/orm": "2.6.1",
172
+ "@sequenceholdings/lattice-form-renderer": "0.2.0"
173
173
  },
174
174
  "devDependencies": {
175
175
  "@types/js-yaml": "^4.0.9",
@@ -10,7 +10,7 @@
10
10
  },
11
11
  "dependencies": {},
12
12
  "devDependencies": {
13
- "@sequenceholdings/artifact-studio": "^0.7.0",
13
+ "@sequenceholdings/artifact-studio": "^0.8.0",
14
14
  "@sequenceholdings/atlas-ui": "^3.1.1",
15
15
  "@tailwindcss/postcss": "^4.2.2",
16
16
  "@tailwindcss/vite": "^4.2.2",