@yargote/artifacts-contracts 0.1.0-beta.1 → 0.1.0-beta.10
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 +9 -1
- package/package.json +1 -1
- package/src/http.d.ts +25 -0
- package/src/http.js +18 -3
- package/src/index.d.ts +217 -2
- package/src/index.js +136 -5
- package/src/workflow.js +2 -2
package/README.md
CHANGED
|
@@ -3,11 +3,19 @@
|
|
|
3
3
|
`@yargote/artifacts-contracts` contains strict domain schemas, types, `ArtifactError`, snapshot serialization, and pure retained-edit helpers. It has no database, ZIP, server, or CLI dependency. Node 24 or later is required.
|
|
4
4
|
|
|
5
5
|
```sh
|
|
6
|
-
npm install @yargote/artifacts-contracts@0.1.0-beta.
|
|
6
|
+
npm install @yargote/artifacts-contracts@0.1.0-beta.10
|
|
7
7
|
```
|
|
8
8
|
|
|
9
9
|
The root export contains domain schemas and types. `/workflow` contains `prepareArtifactEdit`, revision comparison, and compact projections. `/serialization` contains canonical JSON and SHA-256. `/http` contains HTTP response schemas, identity, canonical resource validation, and route URL helpers.
|
|
10
10
|
|
|
11
|
+
`protectedResourceMetadataSchema` accepts standard protected-resource metadata and an optional `artifacts_rest_resource`. The relation names the exact absolute canonical REST OAuth resource URL. It may name the resource itself or one distinct REST resource. Metadata for the distinct resource may omit the relation or name itself, but cannot name another resource.
|
|
12
|
+
|
|
13
|
+
`slugSchema` validates page slugs such as `concepts/rag` without normalizing them. `readSchema` takes exactly one of `artifactId` or a `{ project, slug }` locator, and `readByIdSchema` takes only an ID. `moveSchema` takes `project`, `slug`, or both, each optional and nullable. `moveResultSchema` is unchanged. `ArtifactRead` and the HTTP summary schema include `slug`, and `ArtifactErrorCode` includes `slug_conflict`.
|
|
14
|
+
|
|
15
|
+
`searchSchema` takes a trimmed `query` of 1 to 256 characters, optional `project`, `limit` from 1 to 25 with default 10, and an opaque decimal `cursor`. `searchResultSchema` holds `items` of `searchHitSchema`, `{ artifactId, project, slug, title, snippet, rank }`, and a nullable `nextCursor`.
|
|
16
|
+
|
|
11
17
|
The existing `@artifacts/artifacts` root, `/contracts`, and `/workflow` exports re-export these implementations. Store and REST packages share one `ArtifactError` runtime.
|
|
12
18
|
|
|
13
19
|
This package is MIT licensed. The license applies to this package and does not license the private Artifacts application repository.
|
|
20
|
+
|
|
21
|
+
`shareSchema` accepts optional `notify` and `requireNew: true` without defaults. `shareResultSchema` remains the strict five-field grant shape used by lists. `shareCommandResultSchema` adds an optional immutable notification disposition for commands. Plain and explicit-false requests return the original grant shape. An absent flag and an explicit false remain distinct receipt arguments.
|
package/package.json
CHANGED
package/src/http.d.ts
CHANGED
|
@@ -33,6 +33,7 @@ export declare const revisionSummarySchema: z.ZodObject<{
|
|
|
33
33
|
text: "text";
|
|
34
34
|
html: "html";
|
|
35
35
|
markdown: "markdown";
|
|
36
|
+
design: "design";
|
|
36
37
|
}>;
|
|
37
38
|
utf8Bytes: z.ZodNumber;
|
|
38
39
|
}, z.core.$strict>;
|
|
@@ -50,6 +51,8 @@ export declare const revisionSummarySchema: z.ZodObject<{
|
|
|
50
51
|
export declare const compactArtifactReadSchema: z.ZodObject<{
|
|
51
52
|
ownerId: z.ZodString;
|
|
52
53
|
headRevisionId: z.ZodString;
|
|
54
|
+
project: z.ZodNullable<z.ZodString>;
|
|
55
|
+
slug: z.ZodNullable<z.ZodString>;
|
|
53
56
|
artifactId: z.ZodString;
|
|
54
57
|
publication: z.ZodNullable<z.ZodObject<{
|
|
55
58
|
revisionId: z.ZodString;
|
|
@@ -73,6 +76,7 @@ export declare const compactArtifactReadSchema: z.ZodObject<{
|
|
|
73
76
|
text: "text";
|
|
74
77
|
html: "html";
|
|
75
78
|
markdown: "markdown";
|
|
79
|
+
design: "design";
|
|
76
80
|
}>;
|
|
77
81
|
utf8Bytes: z.ZodNumber;
|
|
78
82
|
}, z.core.$strict>;
|
|
@@ -93,6 +97,8 @@ export declare const artifactSummarySchema: z.ZodObject<{
|
|
|
93
97
|
title: z.ZodString;
|
|
94
98
|
headRevisionId: z.ZodString;
|
|
95
99
|
createdAt: z.ZodISODateTime;
|
|
100
|
+
project: z.ZodNullable<z.ZodString>;
|
|
101
|
+
slug: z.ZodNullable<z.ZodString>;
|
|
96
102
|
publication: z.ZodNullable<z.ZodObject<{
|
|
97
103
|
revisionId: z.ZodString;
|
|
98
104
|
version: z.ZodNumber;
|
|
@@ -105,6 +111,8 @@ export declare const listResultSchema: z.ZodObject<{
|
|
|
105
111
|
title: z.ZodString;
|
|
106
112
|
headRevisionId: z.ZodString;
|
|
107
113
|
createdAt: z.ZodISODateTime;
|
|
114
|
+
project: z.ZodNullable<z.ZodString>;
|
|
115
|
+
slug: z.ZodNullable<z.ZodString>;
|
|
108
116
|
publication: z.ZodNullable<z.ZodObject<{
|
|
109
117
|
revisionId: z.ZodString;
|
|
110
118
|
version: z.ZodNumber;
|
|
@@ -113,6 +121,16 @@ export declare const listResultSchema: z.ZodObject<{
|
|
|
113
121
|
}, z.core.$strict>>;
|
|
114
122
|
nextCursor: z.ZodNullable<z.ZodString>;
|
|
115
123
|
}, z.core.$strict>;
|
|
124
|
+
export declare const projectSummarySchema: z.ZodObject<{
|
|
125
|
+
name: z.ZodString;
|
|
126
|
+
artifactCount: z.ZodNumber;
|
|
127
|
+
}, z.core.$strict>;
|
|
128
|
+
export declare const projectsResultSchema: z.ZodObject<{
|
|
129
|
+
items: z.ZodArray<z.ZodObject<{
|
|
130
|
+
name: z.ZodString;
|
|
131
|
+
artifactCount: z.ZodNumber;
|
|
132
|
+
}, z.core.$strict>>;
|
|
133
|
+
}, z.core.$strict>;
|
|
116
134
|
export declare const historyResultSchema: z.ZodObject<{
|
|
117
135
|
items: z.ZodArray<z.ZodObject<{
|
|
118
136
|
id: z.ZodString;
|
|
@@ -133,6 +151,7 @@ export declare const historyResultSchema: z.ZodObject<{
|
|
|
133
151
|
text: "text";
|
|
134
152
|
html: "html";
|
|
135
153
|
markdown: "markdown";
|
|
154
|
+
design: "design";
|
|
136
155
|
}>;
|
|
137
156
|
text: z.ZodString;
|
|
138
157
|
}, z.core.$strict>;
|
|
@@ -168,6 +187,7 @@ export declare const summaryHistoryResultSchema: z.ZodObject<{
|
|
|
168
187
|
text: "text";
|
|
169
188
|
html: "html";
|
|
170
189
|
markdown: "markdown";
|
|
190
|
+
design: "design";
|
|
171
191
|
}>;
|
|
172
192
|
utf8Bytes: z.ZodNumber;
|
|
173
193
|
}, z.core.$strict>;
|
|
@@ -191,5 +211,10 @@ export declare const httpErrorSchema: z.ZodObject<{
|
|
|
191
211
|
}, z.core.$strict>;
|
|
192
212
|
}, z.core.$strict>;
|
|
193
213
|
export declare function canonicalResource(value: string): string;
|
|
214
|
+
export declare const protectedResourceMetadataSchema: z.ZodObject<{
|
|
215
|
+
resource: z.ZodString;
|
|
216
|
+
authorization_servers: z.ZodArray<z.ZodString>;
|
|
217
|
+
artifacts_rest_resource: z.ZodOptional<z.ZodString>;
|
|
218
|
+
}, z.core.$strip>;
|
|
194
219
|
export declare function protectedResourceMetadataUrl(resource: string): URL;
|
|
195
220
|
export declare function restBase(resource: string): string;
|
package/src/http.js
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { artifactReadSchema, publicationSchema, revisionSchema, snapshotSchema } from "./index.js";
|
|
2
|
+
import { artifactReadSchema, contentKinds, publicationSchema, revisionSchema, snapshotSchema } from "./index.js";
|
|
3
3
|
const identifier = z.string().min(1).max(128);
|
|
4
4
|
const digest = z.string().regex(/^[a-f0-9]{64}$/);
|
|
5
5
|
export const identitySchema = z.strictObject({ userId: identifier, sessionId: identifier, clientId: identifier, scopes: z.array(z.string()) });
|
|
6
6
|
export const attachmentSummarySchema = z.strictObject({ path: z.string(), mediaType: z.string(), encoding: z.enum(['utf8', 'base64']), decodedBytes: z.number().int().nonnegative(), sha256: digest });
|
|
7
7
|
export const revisionSummarySchema = revisionSchema.omit({ snapshot: true }).extend({
|
|
8
8
|
metadata: snapshotSchema.shape.metadata.pick({ title: true, description: true }),
|
|
9
|
-
content: z.strictObject({ kind:
|
|
9
|
+
content: z.strictObject({ kind: z.enum(contentKinds), utf8Bytes: z.number().int().nonnegative() }),
|
|
10
10
|
files: z.array(attachmentSummarySchema).max(32),
|
|
11
11
|
});
|
|
12
12
|
export const compactArtifactReadSchema = artifactReadSchema.omit({ revision: true }).extend({ revision: revisionSummarySchema });
|
|
13
|
-
export const artifactSummarySchema = z.strictObject({ artifactId: identifier, title: z.string(), headRevisionId: identifier, createdAt: z.iso.datetime(), publication: publicationSchema.nullable() });
|
|
13
|
+
export const artifactSummarySchema = z.strictObject({ artifactId: identifier, title: z.string(), headRevisionId: identifier, createdAt: z.iso.datetime(), project: z.string().nullable(), slug: z.string().nullable(), publication: publicationSchema.nullable() });
|
|
14
14
|
export const listResultSchema = z.strictObject({ items: z.array(artifactSummarySchema).max(100), nextCursor: identifier.nullable() });
|
|
15
|
+
export const projectSummarySchema = z.strictObject({ name: z.string(), artifactCount: z.number().int().positive() });
|
|
16
|
+
export const projectsResultSchema = z.strictObject({ items: z.array(projectSummarySchema) });
|
|
15
17
|
export const historyResultSchema = z.strictObject({ items: z.array(revisionSchema).max(10), nextBeforeSequence: z.number().int().positive().nullable() });
|
|
16
18
|
export const summaryHistoryResultSchema = historyResultSchema.extend({ items: z.array(revisionSummarySchema).max(10) });
|
|
17
19
|
export const httpErrorSchema = z.strictObject({ error: z.strictObject({ code: z.string().min(1), message: z.string(), details: z.record(z.string(), z.unknown()) }) });
|
|
@@ -24,6 +26,19 @@ export function canonicalResource(value) {
|
|
|
24
26
|
throw new TypeError('Use the exact canonical resource URL without a trailing slash');
|
|
25
27
|
return value;
|
|
26
28
|
}
|
|
29
|
+
export const protectedResourceMetadataSchema = z.object({
|
|
30
|
+
resource: z.string(),
|
|
31
|
+
authorization_servers: z.array(z.string()).min(1),
|
|
32
|
+
artifacts_rest_resource: z.string().refine((value) => {
|
|
33
|
+
try {
|
|
34
|
+
canonicalResource(value);
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
}).optional(),
|
|
41
|
+
});
|
|
27
42
|
export function protectedResourceMetadataUrl(resource) {
|
|
28
43
|
const url = new URL(canonicalResource(resource));
|
|
29
44
|
return new URL(`/.well-known/oauth-protected-resource${url.pathname === '/' ? '' : url.pathname}`, url.origin);
|
package/src/index.d.ts
CHANGED
|
@@ -1,4 +1,28 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
export declare const contentKinds: readonly ["html", "markdown", "text", "design"];
|
|
3
|
+
export declare const canvasIndexSchema: z.ZodObject<{
|
|
4
|
+
v: z.ZodLiteral<1>;
|
|
5
|
+
boards: z.ZodPipe<z.ZodUnknown, z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
6
|
+
x: z.ZodNumber;
|
|
7
|
+
y: z.ZodNumber;
|
|
8
|
+
w: z.ZodNumber;
|
|
9
|
+
h: z.ZodNumber;
|
|
10
|
+
title: z.ZodOptional<z.ZodString>;
|
|
11
|
+
page: z.ZodOptional<z.ZodString>;
|
|
12
|
+
}, z.core.$strict>>>;
|
|
13
|
+
order: z.ZodPipe<z.ZodArray<z.ZodUnknown>, z.ZodArray<z.ZodString>>;
|
|
14
|
+
notes: z.ZodOptional<z.ZodPipe<z.ZodUnknown, z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
15
|
+
x: z.ZodNumber;
|
|
16
|
+
y: z.ZodNumber;
|
|
17
|
+
text: z.ZodString;
|
|
18
|
+
w: z.ZodOptional<z.ZodNumber>;
|
|
19
|
+
page: z.ZodOptional<z.ZodString>;
|
|
20
|
+
}, z.core.$strict>>>>;
|
|
21
|
+
pages: z.ZodOptional<z.ZodPipe<z.ZodArray<z.ZodUnknown>, z.ZodArray<z.ZodObject<{
|
|
22
|
+
id: z.ZodString;
|
|
23
|
+
name: z.ZodString;
|
|
24
|
+
}, z.core.$strict>>>>;
|
|
25
|
+
}, z.core.$strict>;
|
|
2
26
|
export declare const snapshotSchema: z.ZodObject<{
|
|
3
27
|
metadata: z.ZodObject<{
|
|
4
28
|
title: z.ZodString;
|
|
@@ -10,6 +34,7 @@ export declare const snapshotSchema: z.ZodObject<{
|
|
|
10
34
|
text: "text";
|
|
11
35
|
html: "html";
|
|
12
36
|
markdown: "markdown";
|
|
37
|
+
design: "design";
|
|
13
38
|
}>;
|
|
14
39
|
text: z.ZodString;
|
|
15
40
|
}, z.core.$strict>;
|
|
@@ -23,6 +48,18 @@ export declare const snapshotSchema: z.ZodObject<{
|
|
|
23
48
|
data: z.ZodString;
|
|
24
49
|
}, z.core.$strict>>;
|
|
25
50
|
}, z.core.$strict>;
|
|
51
|
+
export type CanvasIndex = z.infer<typeof canvasIndexSchema>;
|
|
52
|
+
export type CanvasBoard = CanvasIndex['boards'][string] & {
|
|
53
|
+
path: string;
|
|
54
|
+
html: string;
|
|
55
|
+
};
|
|
56
|
+
export type Canvas = {
|
|
57
|
+
index: CanvasIndex;
|
|
58
|
+
boards: CanvasBoard[];
|
|
59
|
+
};
|
|
60
|
+
export declare function parseCanvas(snapshot: Pick<Snapshot, 'content' | 'files'>): Canvas;
|
|
61
|
+
export declare const projectNameSchema: z.ZodString;
|
|
62
|
+
export declare const slugSchema: z.ZodString;
|
|
26
63
|
export declare const createSchema: z.ZodObject<{
|
|
27
64
|
requestId: z.ZodString;
|
|
28
65
|
snapshot: z.ZodObject<{
|
|
@@ -36,6 +73,7 @@ export declare const createSchema: z.ZodObject<{
|
|
|
36
73
|
text: "text";
|
|
37
74
|
html: "html";
|
|
38
75
|
markdown: "markdown";
|
|
76
|
+
design: "design";
|
|
39
77
|
}>;
|
|
40
78
|
text: z.ZodString;
|
|
41
79
|
}, z.core.$strict>;
|
|
@@ -49,12 +87,14 @@ export declare const createSchema: z.ZodObject<{
|
|
|
49
87
|
data: z.ZodString;
|
|
50
88
|
}, z.core.$strict>>;
|
|
51
89
|
}, z.core.$strict>;
|
|
90
|
+
project: z.ZodOptional<z.ZodString>;
|
|
91
|
+
slug: z.ZodOptional<z.ZodString>;
|
|
52
92
|
response: z.ZodOptional<z.ZodEnum<{
|
|
53
93
|
full: "full";
|
|
54
94
|
compact: "compact";
|
|
55
95
|
}>>;
|
|
56
96
|
}, z.core.$strict>;
|
|
57
|
-
export declare const
|
|
97
|
+
export declare const readByIdSchema: z.ZodObject<{
|
|
58
98
|
artifactId: z.ZodString;
|
|
59
99
|
revisionId: z.ZodOptional<z.ZodString>;
|
|
60
100
|
response: z.ZodOptional<z.ZodEnum<{
|
|
@@ -62,6 +102,16 @@ export declare const readSchema: z.ZodObject<{
|
|
|
62
102
|
compact: "compact";
|
|
63
103
|
}>>;
|
|
64
104
|
}, z.core.$strict>;
|
|
105
|
+
export declare const readSchema: z.ZodObject<{
|
|
106
|
+
artifactId: z.ZodOptional<z.ZodString>;
|
|
107
|
+
project: z.ZodOptional<z.ZodString>;
|
|
108
|
+
slug: z.ZodOptional<z.ZodString>;
|
|
109
|
+
revisionId: z.ZodOptional<z.ZodString>;
|
|
110
|
+
response: z.ZodOptional<z.ZodEnum<{
|
|
111
|
+
full: "full";
|
|
112
|
+
compact: "compact";
|
|
113
|
+
}>>;
|
|
114
|
+
}, z.core.$strict>;
|
|
65
115
|
export declare const updateSchema: z.ZodObject<{
|
|
66
116
|
requestId: z.ZodString;
|
|
67
117
|
artifactId: z.ZodString;
|
|
@@ -77,6 +127,7 @@ export declare const updateSchema: z.ZodObject<{
|
|
|
77
127
|
text: "text";
|
|
78
128
|
html: "html";
|
|
79
129
|
markdown: "markdown";
|
|
130
|
+
design: "design";
|
|
80
131
|
}>;
|
|
81
132
|
text: z.ZodString;
|
|
82
133
|
}, z.core.$strict>;
|
|
@@ -101,6 +152,85 @@ export declare const publishSchema: z.ZodObject<{
|
|
|
101
152
|
revisionId: z.ZodString;
|
|
102
153
|
expectedPublicationVersion: z.ZodNumber;
|
|
103
154
|
}, z.core.$strict>;
|
|
155
|
+
export declare const deleteSchema: z.ZodObject<{
|
|
156
|
+
requestId: z.ZodString;
|
|
157
|
+
artifactId: z.ZodString;
|
|
158
|
+
expectedRevisionId: z.ZodString;
|
|
159
|
+
expectedPublicationVersion: z.ZodNumber;
|
|
160
|
+
}, z.core.$strict>;
|
|
161
|
+
export declare const deleteResultSchema: z.ZodObject<{
|
|
162
|
+
artifactId: z.ZodString;
|
|
163
|
+
}, z.core.$strict>;
|
|
164
|
+
export type DeleteInput = z.infer<typeof deleteSchema>;
|
|
165
|
+
export type DeleteResult = z.infer<typeof deleteResultSchema>;
|
|
166
|
+
export declare const moveSchema: z.ZodObject<{
|
|
167
|
+
requestId: z.ZodString;
|
|
168
|
+
artifactId: z.ZodString;
|
|
169
|
+
project: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
170
|
+
slug: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
171
|
+
}, z.core.$strict>;
|
|
172
|
+
export declare const moveResultSchema: z.ZodObject<{
|
|
173
|
+
artifactId: z.ZodString;
|
|
174
|
+
project: z.ZodNullable<z.ZodString>;
|
|
175
|
+
}, z.core.$strict>;
|
|
176
|
+
export type MoveResult = z.infer<typeof moveResultSchema>;
|
|
177
|
+
export declare const shareSchema: z.ZodObject<{
|
|
178
|
+
requestId: z.ZodString;
|
|
179
|
+
artifactId: z.ZodString;
|
|
180
|
+
email: z.ZodPipe<z.ZodString, z.ZodEmail>;
|
|
181
|
+
notify: z.ZodOptional<z.ZodBoolean>;
|
|
182
|
+
requireNew: z.ZodOptional<z.ZodLiteral<true>>;
|
|
183
|
+
}, z.core.$strict>;
|
|
184
|
+
export declare const unshareSchema: z.ZodObject<{
|
|
185
|
+
requestId: z.ZodString;
|
|
186
|
+
artifactId: z.ZodString;
|
|
187
|
+
shareId: z.ZodString;
|
|
188
|
+
}, z.core.$strict>;
|
|
189
|
+
export declare const listSharesSchema: z.ZodObject<{
|
|
190
|
+
artifactId: z.ZodString;
|
|
191
|
+
}, z.core.$strict>;
|
|
192
|
+
export declare const shareResultSchema: z.ZodObject<{
|
|
193
|
+
shareId: z.ZodString;
|
|
194
|
+
artifactId: z.ZodString;
|
|
195
|
+
kind: z.ZodLiteral<"email">;
|
|
196
|
+
value: z.ZodEmail;
|
|
197
|
+
createdAt: z.ZodISODateTime;
|
|
198
|
+
}, z.core.$strict>;
|
|
199
|
+
export declare const notificationSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
200
|
+
status: z.ZodLiteral<"requested">;
|
|
201
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
202
|
+
status: z.ZodLiteral<"skipped">;
|
|
203
|
+
reason: z.ZodLiteral<"disabled">;
|
|
204
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
205
|
+
status: z.ZodLiteral<"skipped">;
|
|
206
|
+
reason: z.ZodLiteral<"rate_limited">;
|
|
207
|
+
retryAt: z.ZodISODateTime;
|
|
208
|
+
}, z.core.$strict>]>;
|
|
209
|
+
export declare const shareCommandResultSchema: z.ZodObject<{
|
|
210
|
+
shareId: z.ZodString;
|
|
211
|
+
artifactId: z.ZodString;
|
|
212
|
+
kind: z.ZodLiteral<"email">;
|
|
213
|
+
value: z.ZodEmail;
|
|
214
|
+
createdAt: z.ZodISODateTime;
|
|
215
|
+
notification: z.ZodOptional<z.ZodUnion<readonly [z.ZodObject<{
|
|
216
|
+
status: z.ZodLiteral<"requested">;
|
|
217
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
218
|
+
status: z.ZodLiteral<"skipped">;
|
|
219
|
+
reason: z.ZodLiteral<"disabled">;
|
|
220
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
221
|
+
status: z.ZodLiteral<"skipped">;
|
|
222
|
+
reason: z.ZodLiteral<"rate_limited">;
|
|
223
|
+
retryAt: z.ZodISODateTime;
|
|
224
|
+
}, z.core.$strict>]>>;
|
|
225
|
+
}, z.core.$strict>;
|
|
226
|
+
export declare const unshareResultSchema: z.ZodObject<{
|
|
227
|
+
artifactId: z.ZodString;
|
|
228
|
+
shareId: z.ZodString;
|
|
229
|
+
}, z.core.$strict>;
|
|
230
|
+
export type Share = z.infer<typeof shareResultSchema>;
|
|
231
|
+
export type ShareResult = z.infer<typeof shareCommandResultSchema>;
|
|
232
|
+
export type Notification = z.infer<typeof notificationSchema>;
|
|
233
|
+
export type UnshareResult = z.infer<typeof unshareResultSchema>;
|
|
104
234
|
export declare const exportSchema: z.ZodObject<{
|
|
105
235
|
artifactId: z.ZodString;
|
|
106
236
|
revisionId: z.ZodString;
|
|
@@ -108,7 +238,35 @@ export declare const exportSchema: z.ZodObject<{
|
|
|
108
238
|
export declare const listSchema: z.ZodObject<{
|
|
109
239
|
limit: z.ZodDefault<z.ZodNumber>;
|
|
110
240
|
cursor: z.ZodOptional<z.ZodString>;
|
|
241
|
+
project: z.ZodOptional<z.ZodString>;
|
|
242
|
+
}, z.core.$strict>;
|
|
243
|
+
export declare const searchSchema: z.ZodObject<{
|
|
244
|
+
query: z.ZodString;
|
|
245
|
+
project: z.ZodOptional<z.ZodString>;
|
|
246
|
+
limit: z.ZodDefault<z.ZodNumber>;
|
|
247
|
+
cursor: z.ZodOptional<z.ZodString>;
|
|
111
248
|
}, z.core.$strict>;
|
|
249
|
+
export declare const searchHitSchema: z.ZodObject<{
|
|
250
|
+
artifactId: z.ZodString;
|
|
251
|
+
project: z.ZodNullable<z.ZodString>;
|
|
252
|
+
slug: z.ZodNullable<z.ZodString>;
|
|
253
|
+
title: z.ZodString;
|
|
254
|
+
snippet: z.ZodString;
|
|
255
|
+
rank: z.ZodNumber;
|
|
256
|
+
}, z.core.$strict>;
|
|
257
|
+
export declare const searchResultSchema: z.ZodObject<{
|
|
258
|
+
items: z.ZodArray<z.ZodObject<{
|
|
259
|
+
artifactId: z.ZodString;
|
|
260
|
+
project: z.ZodNullable<z.ZodString>;
|
|
261
|
+
slug: z.ZodNullable<z.ZodString>;
|
|
262
|
+
title: z.ZodString;
|
|
263
|
+
snippet: z.ZodString;
|
|
264
|
+
rank: z.ZodNumber;
|
|
265
|
+
}, z.core.$strict>>;
|
|
266
|
+
nextCursor: z.ZodNullable<z.ZodString>;
|
|
267
|
+
}, z.core.$strict>;
|
|
268
|
+
export type SearchHit = z.infer<typeof searchHitSchema>;
|
|
269
|
+
export type SearchResult = z.infer<typeof searchResultSchema>;
|
|
112
270
|
export declare const libraryQuerySchema: z.ZodObject<{
|
|
113
271
|
q: z.ZodDefault<z.ZodString>;
|
|
114
272
|
status: z.ZodDefault<z.ZodEnum<{
|
|
@@ -117,6 +275,7 @@ export declare const libraryQuerySchema: z.ZodObject<{
|
|
|
117
275
|
unpublished: "unpublished";
|
|
118
276
|
pending: "pending";
|
|
119
277
|
}>>;
|
|
278
|
+
project: z.ZodOptional<z.ZodString>;
|
|
120
279
|
cursor: z.ZodOptional<z.ZodString>;
|
|
121
280
|
}, z.core.$strict>;
|
|
122
281
|
export declare const historySchema: z.ZodObject<{
|
|
@@ -172,13 +331,26 @@ export type Viewer = z.infer<typeof viewerSchema>;
|
|
|
172
331
|
export type Publication = z.infer<typeof publicationSchema>;
|
|
173
332
|
export type Revision = z.infer<typeof revisionSchema>;
|
|
174
333
|
export type ArtifactRead = z.infer<typeof artifactReadSchema>;
|
|
334
|
+
export type SharedRead = z.infer<typeof sharedReadSchema>;
|
|
335
|
+
export type SharedArtifactSummary = Readonly<{
|
|
336
|
+
artifactId: string;
|
|
337
|
+
title: string;
|
|
338
|
+
ownerName: string;
|
|
339
|
+
url: string;
|
|
340
|
+
}>;
|
|
175
341
|
export type ArtifactSummary = {
|
|
176
342
|
artifactId: string;
|
|
177
343
|
title: string;
|
|
178
344
|
headRevisionId: string;
|
|
179
345
|
createdAt: string;
|
|
346
|
+
project: string | null;
|
|
347
|
+
slug: string | null;
|
|
180
348
|
publication: Publication | null;
|
|
181
349
|
};
|
|
350
|
+
export type ProjectSummary = {
|
|
351
|
+
name: string;
|
|
352
|
+
artifactCount: number;
|
|
353
|
+
};
|
|
182
354
|
export type ArtifactLibraryQuery = z.infer<typeof libraryQuerySchema>;
|
|
183
355
|
export type ArtifactLibraryPage = {
|
|
184
356
|
items: ArtifactSummary[];
|
|
@@ -196,7 +368,7 @@ export type Archive = {
|
|
|
196
368
|
base64: string;
|
|
197
369
|
sha256: string;
|
|
198
370
|
};
|
|
199
|
-
export type ArtifactErrorCode = 'forbidden' | 'not_found' | 'conflict' | 'request_conflict' | 'invalid_grant';
|
|
371
|
+
export type ArtifactErrorCode = 'forbidden' | 'not_found' | 'conflict' | 'request_conflict' | 'slug_conflict' | 'invalid_grant';
|
|
200
372
|
export declare class ArtifactError extends Error {
|
|
201
373
|
readonly code: ArtifactErrorCode;
|
|
202
374
|
readonly details: Record<string, unknown>;
|
|
@@ -230,6 +402,7 @@ export declare const revisionSchema: z.ZodObject<{
|
|
|
230
402
|
text: "text";
|
|
231
403
|
html: "html";
|
|
232
404
|
markdown: "markdown";
|
|
405
|
+
design: "design";
|
|
233
406
|
}>;
|
|
234
407
|
text: z.ZodString;
|
|
235
408
|
}, z.core.$strict>;
|
|
@@ -248,6 +421,8 @@ export declare const artifactReadSchema: z.ZodObject<{
|
|
|
248
421
|
artifactId: z.ZodString;
|
|
249
422
|
ownerId: z.ZodString;
|
|
250
423
|
headRevisionId: z.ZodString;
|
|
424
|
+
project: z.ZodNullable<z.ZodString>;
|
|
425
|
+
slug: z.ZodNullable<z.ZodString>;
|
|
251
426
|
publication: z.ZodNullable<z.ZodObject<{
|
|
252
427
|
revisionId: z.ZodString;
|
|
253
428
|
version: z.ZodNumber;
|
|
@@ -272,6 +447,46 @@ export declare const artifactReadSchema: z.ZodObject<{
|
|
|
272
447
|
text: "text";
|
|
273
448
|
html: "html";
|
|
274
449
|
markdown: "markdown";
|
|
450
|
+
design: "design";
|
|
451
|
+
}>;
|
|
452
|
+
text: z.ZodString;
|
|
453
|
+
}, z.core.$strict>;
|
|
454
|
+
files: z.ZodArray<z.ZodObject<{
|
|
455
|
+
path: z.ZodString;
|
|
456
|
+
mediaType: z.ZodString;
|
|
457
|
+
encoding: z.ZodEnum<{
|
|
458
|
+
utf8: "utf8";
|
|
459
|
+
base64: "base64";
|
|
460
|
+
}>;
|
|
461
|
+
data: z.ZodString;
|
|
462
|
+
}, z.core.$strict>>;
|
|
463
|
+
}, z.core.$strict>;
|
|
464
|
+
}, z.core.$strict>;
|
|
465
|
+
}, z.core.$strict>;
|
|
466
|
+
export declare const sharedReadSchema: z.ZodObject<{
|
|
467
|
+
artifactId: z.ZodString;
|
|
468
|
+
ownerName: z.ZodDefault<z.ZodString>;
|
|
469
|
+
publication: z.ZodObject<{
|
|
470
|
+
revisionId: z.ZodString;
|
|
471
|
+
version: z.ZodNumber;
|
|
472
|
+
url: z.ZodURL;
|
|
473
|
+
}, z.core.$strict>;
|
|
474
|
+
revision: z.ZodObject<{
|
|
475
|
+
id: z.ZodString;
|
|
476
|
+
createdAt: z.ZodISODateTime;
|
|
477
|
+
sha256: z.ZodString;
|
|
478
|
+
snapshot: z.ZodObject<{
|
|
479
|
+
metadata: z.ZodObject<{
|
|
480
|
+
title: z.ZodString;
|
|
481
|
+
description: z.ZodString;
|
|
482
|
+
custom: z.ZodOptional<z.ZodJSONSchema>;
|
|
483
|
+
}, z.core.$strict>;
|
|
484
|
+
content: z.ZodObject<{
|
|
485
|
+
kind: z.ZodEnum<{
|
|
486
|
+
text: "text";
|
|
487
|
+
html: "html";
|
|
488
|
+
markdown: "markdown";
|
|
489
|
+
design: "design";
|
|
275
490
|
}>;
|
|
276
491
|
text: z.ZodString;
|
|
277
492
|
}, z.core.$strict>;
|
package/src/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
const identifier = z.string().min(1).max(128);
|
|
3
3
|
const requestId = z.string().min(8).max(128);
|
|
4
|
+
export const contentKinds = ['html', 'markdown', 'text', 'design'];
|
|
4
5
|
const fileSchema = z.strictObject({
|
|
5
6
|
path: z.string().min(1).max(240).refine((path) => path === path.normalize('NFC') && !/[:\\%\x00-\x1f\x7f]/.test(path) && path.split('/').every((part) => part !== '' && part !== '.' && part !== '..'), 'Use a normalized relative file path'),
|
|
6
7
|
mediaType: z.string().max(128).regex(/^[a-zA-Z0-9!#$&^_.+-]+\/[a-zA-Z0-9!#$&^_.+-]+$/),
|
|
@@ -10,9 +11,63 @@ const fileSchema = z.strictObject({
|
|
|
10
11
|
if (file.encoding === 'base64' && Buffer.from(file.data, 'base64').toString('base64') !== file.data)
|
|
11
12
|
context.addIssue({ code: 'custom', path: ['data'], message: 'Use canonical padded base64' });
|
|
12
13
|
});
|
|
14
|
+
const canvasId = z.string().regex(/^[A-Za-z0-9_-]{1,40}$/, 'Use 1 to 40 letters, digits, underscores, or hyphens').refine((id) => id !== '__proto__', 'Use an id other than __proto__');
|
|
15
|
+
const boardPath = z.string().regex(/^boards\/[A-Za-z0-9_][A-Za-z0-9_.-]*\.html$/, 'Use a board path such as boards/Home.html');
|
|
16
|
+
const coordinate = z.number().min(-1_000_000).max(1_000_000);
|
|
17
|
+
const extent = z.number().min(40).max(8000);
|
|
18
|
+
const label = z.string().min(1).max(256);
|
|
19
|
+
// An oversized count or a bad key aborts before any entry is parsed, so an oversized collection reports one issue.
|
|
20
|
+
// Keys are read from the raw object because a zod record skips a __proto__ key without checking it.
|
|
21
|
+
function keyed(key, value, max, noun) {
|
|
22
|
+
return z.unknown().superRefine((input, context) => {
|
|
23
|
+
if (typeof input !== 'object' || input === null || Array.isArray(input))
|
|
24
|
+
return;
|
|
25
|
+
const keys = Object.keys(input);
|
|
26
|
+
if (keys.length > max) {
|
|
27
|
+
context.addIssue({ code: 'too_big', origin: 'object', maximum: max, inclusive: true, input, continue: false, message: `A canvas holds at most ${max} ${noun}` });
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
for (const name of keys) {
|
|
31
|
+
const result = key.safeParse(name);
|
|
32
|
+
if (!result.success)
|
|
33
|
+
context.addIssue({ code: 'invalid_key', origin: 'record', issues: result.error.issues, input: name, path: [name], continue: false, message: result.error.issues[0].message });
|
|
34
|
+
}
|
|
35
|
+
}).pipe(z.record(z.string(), value));
|
|
36
|
+
}
|
|
37
|
+
export const canvasIndexSchema = z.strictObject({
|
|
38
|
+
v: z.literal(1),
|
|
39
|
+
boards: keyed(boardPath, z.strictObject({ x: coordinate, y: coordinate, w: extent, h: extent, title: label.optional(), page: canvasId.optional() }), 32, 'boards'),
|
|
40
|
+
order: z.array(z.unknown()).min(1, 'A canvas needs at least one board').max(32, { message: 'A canvas holds at most 32 boards', abort: true }).pipe(z.array(boardPath)),
|
|
41
|
+
notes: keyed(canvasId, z.strictObject({ x: coordinate, y: coordinate, text: z.string(), w: extent.optional(), page: canvasId.optional() }), 200, 'notes').optional(),
|
|
42
|
+
pages: z.array(z.unknown()).max(32, { message: 'A canvas holds at most 32 pages', abort: true }).pipe(z.array(z.strictObject({ id: canvasId, name: label }))).optional(),
|
|
43
|
+
}).superRefine((index, context) => {
|
|
44
|
+
const ordered = new Set();
|
|
45
|
+
index.order.forEach((path, position) => {
|
|
46
|
+
if (!Object.hasOwn(index.boards, path))
|
|
47
|
+
context.addIssue({ code: 'custom', path: ['order', position], message: `Canvas order names ${path}, which is not a board` });
|
|
48
|
+
else if (ordered.has(path))
|
|
49
|
+
context.addIssue({ code: 'custom', path: ['order', position], message: `Canvas order lists ${path} more than once` });
|
|
50
|
+
ordered.add(path);
|
|
51
|
+
});
|
|
52
|
+
for (const path of Object.keys(index.boards))
|
|
53
|
+
if (!ordered.has(path))
|
|
54
|
+
context.addIssue({ code: 'custom', path: ['order'], message: `Canvas order omits board ${path}` });
|
|
55
|
+
const pages = new Set();
|
|
56
|
+
index.pages?.forEach(({ id }, position) => {
|
|
57
|
+
if (pages.has(id))
|
|
58
|
+
context.addIssue({ code: 'custom', path: ['pages', position, 'id'], message: `Canvas page ${id} is declared more than once` });
|
|
59
|
+
pages.add(id);
|
|
60
|
+
});
|
|
61
|
+
for (const [path, board] of Object.entries(index.boards))
|
|
62
|
+
if (board.page !== undefined && !pages.has(board.page))
|
|
63
|
+
context.addIssue({ code: 'custom', path: ['boards', path, 'page'], message: `Canvas board ${path} names unknown page ${board.page}` });
|
|
64
|
+
for (const [id, note] of Object.entries(index.notes ?? {}))
|
|
65
|
+
if (note.page !== undefined && !pages.has(note.page))
|
|
66
|
+
context.addIssue({ code: 'custom', path: ['notes', id, 'page'], message: `Canvas note ${id} names unknown page ${note.page}` });
|
|
67
|
+
});
|
|
13
68
|
export const snapshotSchema = z.strictObject({
|
|
14
69
|
metadata: z.strictObject({ title: z.string().min(1).max(256), description: z.string().max(8192), custom: z.json().optional() }),
|
|
15
|
-
content: z.strictObject({ kind: z.enum(
|
|
70
|
+
content: z.strictObject({ kind: z.enum(contentKinds), text: z.string().max(1_048_576).refine((text) => text.isWellFormed(), 'Content must contain well-formed Unicode') }),
|
|
16
71
|
files: z.array(fileSchema).max(32),
|
|
17
72
|
}).superRefine((snapshot, context) => {
|
|
18
73
|
const paths = snapshot.files.map((file) => file.path);
|
|
@@ -21,17 +76,92 @@ export const snapshotSchema = z.strictObject({
|
|
|
21
76
|
const bytes = Buffer.byteLength(JSON.stringify(snapshot.metadata)) + Buffer.byteLength(snapshot.content.text) + snapshot.files.reduce((total, file) => total + Buffer.byteLength(file.path) + Buffer.byteLength(file.mediaType) + decodeFile(file).length, 0);
|
|
22
77
|
if (bytes > 1_048_576)
|
|
23
78
|
context.addIssue({ code: 'custom', message: 'A revision must fit within 1 MiB of decoded content and metadata' });
|
|
79
|
+
// A request body can reach 8 MiB, so the index of an oversized design is not parsed.
|
|
80
|
+
if (snapshot.content.kind !== 'design' || bytes > 1_048_576)
|
|
81
|
+
return;
|
|
82
|
+
const canvas = readCanvas(snapshot);
|
|
83
|
+
if (!canvas.success)
|
|
84
|
+
for (const issue of canvas.issues)
|
|
85
|
+
context.addIssue({ ...issue });
|
|
24
86
|
});
|
|
87
|
+
function readCanvas({ content, files }) {
|
|
88
|
+
let value;
|
|
89
|
+
try {
|
|
90
|
+
value = JSON.parse(content.text);
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
return { success: false, issues: [{ code: 'custom', path: ['content', 'text'], message: 'Design content must be a canvas index in JSON' }] };
|
|
94
|
+
}
|
|
95
|
+
const index = canvasIndexSchema.safeParse(value);
|
|
96
|
+
if (!index.success)
|
|
97
|
+
return { success: false, issues: index.error.issues.map((issue) => ({ ...issue, path: ['content', 'text', ...issue.path] })) };
|
|
98
|
+
const positions = new Map(files.map((file, position) => [file.path, position]));
|
|
99
|
+
const boards = [];
|
|
100
|
+
const issues = [];
|
|
101
|
+
for (const path of index.data.order) {
|
|
102
|
+
const position = positions.get(path);
|
|
103
|
+
if (position === undefined) {
|
|
104
|
+
issues.push({ code: 'custom', path: ['content', 'text', 'boards', path], message: `Canvas board ${path} has no matching file` });
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
const file = files[position];
|
|
108
|
+
if (file.mediaType !== 'text/html' || file.encoding !== 'utf8')
|
|
109
|
+
issues.push({ code: 'custom', path: ['files', position], message: `Canvas board ${path} must be a text/html file with utf8 encoding` });
|
|
110
|
+
else
|
|
111
|
+
boards.push({ ...index.data.boards[path], path, html: file.data });
|
|
112
|
+
}
|
|
113
|
+
return issues.length ? { success: false, issues } : { success: true, data: { index: index.data, boards } };
|
|
114
|
+
}
|
|
115
|
+
export function parseCanvas(snapshot) {
|
|
116
|
+
if (snapshot.content.kind !== 'design')
|
|
117
|
+
throw new TypeError('Only a design snapshot has a canvas');
|
|
118
|
+
const canvas = readCanvas(snapshot);
|
|
119
|
+
if (!canvas.success)
|
|
120
|
+
throw new z.ZodError(canvas.issues);
|
|
121
|
+
return canvas.data;
|
|
122
|
+
}
|
|
123
|
+
export const projectNameSchema = z.string().normalize('NFC').trim().min(1).max(80).refine((name) => name.isWellFormed() && !/\p{Cc}/u.test(name), 'Use a project name without control characters');
|
|
25
124
|
const response = z.enum(['full', 'compact']).optional();
|
|
26
|
-
|
|
27
|
-
export const
|
|
125
|
+
// The .md check aborts so a file-style name gets the suffix hint instead of the generic pattern message.
|
|
126
|
+
export const slugSchema = z.string().min(1).max(160)
|
|
127
|
+
.refine((slug) => !slug.endsWith('.md'), { message: 'Remove the .md suffix: a slug names a page, not a file', abort: true })
|
|
128
|
+
.regex(/^[a-z0-9]+(-[a-z0-9]+)*(\/[a-z0-9]+(-[a-z0-9]+)*)*$/, 'Use lowercase kebab-case segments separated by /, such as concepts/rag');
|
|
129
|
+
export const createSchema = z.strictObject({ requestId, snapshot: snapshotSchema, project: projectNameSchema.optional(), slug: slugSchema.optional(), response });
|
|
130
|
+
export const readByIdSchema = z.strictObject({ artifactId: identifier, revisionId: identifier.optional(), response });
|
|
131
|
+
export const readSchema = z.strictObject({ artifactId: identifier.optional(), project: projectNameSchema.optional(), slug: slugSchema.optional(), revisionId: identifier.optional(), response })
|
|
132
|
+
.refine((input) => (input.artifactId === undefined) !== (input.slug === undefined) && (input.project === undefined || input.slug !== undefined), 'Specify exactly one of artifactId or slug; project applies only with slug');
|
|
28
133
|
export const updateSchema = z.strictObject({ requestId, artifactId: identifier, expectedRevisionId: identifier, snapshot: snapshotSchema, response });
|
|
29
134
|
export const publishSchema = z.strictObject({ requestId, artifactId: identifier, revisionId: identifier, expectedPublicationVersion: z.number().int().nonnegative() });
|
|
135
|
+
export const deleteSchema = z.strictObject({ requestId, artifactId: identifier, expectedRevisionId: identifier, expectedPublicationVersion: z.number().int().nonnegative() });
|
|
136
|
+
export const deleteResultSchema = z.strictObject({ artifactId: identifier });
|
|
137
|
+
export const moveSchema = z.strictObject({ requestId, artifactId: identifier, project: projectNameSchema.nullable().optional(), slug: slugSchema.nullable().optional() })
|
|
138
|
+
.refine((input) => input.project !== undefined || input.slug !== undefined, 'Specify project, slug, or both; null clears either');
|
|
139
|
+
export const moveResultSchema = z.strictObject({ artifactId: identifier, project: z.string().nullable() });
|
|
140
|
+
export const shareSchema = z.strictObject({ requestId, artifactId: identifier, email: z.string().trim().toLowerCase().pipe(z.email().max(254)).meta({ format: 'email', description: 'Email address, trimmed and lowercased; at most 254 characters after trimming' }), notify: z.boolean().optional(), requireNew: z.literal(true).optional() });
|
|
141
|
+
export const unshareSchema = z.strictObject({ requestId, artifactId: identifier, shareId: identifier });
|
|
142
|
+
export const listSharesSchema = z.strictObject({ artifactId: identifier });
|
|
143
|
+
export const shareResultSchema = z.strictObject({ shareId: identifier, artifactId: identifier, kind: z.literal('email'), value: z.email(), createdAt: z.iso.datetime() });
|
|
144
|
+
export const notificationSchema = z.union([
|
|
145
|
+
z.strictObject({ status: z.literal('requested') }),
|
|
146
|
+
z.strictObject({ status: z.literal('skipped'), reason: z.literal('disabled') }),
|
|
147
|
+
z.strictObject({ status: z.literal('skipped'), reason: z.literal('rate_limited'), retryAt: z.iso.datetime() }),
|
|
148
|
+
]);
|
|
149
|
+
export const shareCommandResultSchema = shareResultSchema.extend({ notification: notificationSchema.optional() });
|
|
150
|
+
export const unshareResultSchema = z.strictObject({ artifactId: identifier, shareId: identifier });
|
|
30
151
|
export const exportSchema = z.strictObject({ artifactId: identifier, revisionId: identifier });
|
|
31
|
-
export const listSchema = z.strictObject({ limit: z.number().int().min(1).max(100).default(25), cursor: identifier.optional() });
|
|
152
|
+
export const listSchema = z.strictObject({ limit: z.number().int().min(1).max(100).default(25), cursor: identifier.optional(), project: projectNameSchema.optional() });
|
|
153
|
+
export const searchSchema = z.strictObject({
|
|
154
|
+
query: z.string().trim().min(1).max(256),
|
|
155
|
+
project: projectNameSchema.optional(),
|
|
156
|
+
limit: z.number().int().min(1).max(25).default(10),
|
|
157
|
+
cursor: z.string().regex(/^\d{1,6}$/, 'Use the nextCursor from a previous search').optional(),
|
|
158
|
+
});
|
|
159
|
+
export const searchHitSchema = z.strictObject({ artifactId: identifier, project: z.string().nullable(), slug: z.string().nullable(), title: z.string(), snippet: z.string(), rank: z.number() });
|
|
160
|
+
export const searchResultSchema = z.strictObject({ items: z.array(searchHitSchema).max(25), nextCursor: z.string().nullable() });
|
|
32
161
|
export const libraryQuerySchema = z.strictObject({
|
|
33
162
|
q: z.string().trim().max(256).default(''),
|
|
34
163
|
status: z.enum(['all', 'published', 'unpublished', 'pending']).default('all'),
|
|
164
|
+
project: projectNameSchema.optional(),
|
|
35
165
|
cursor: identifier.optional(),
|
|
36
166
|
});
|
|
37
167
|
export const historySchema = z.strictObject({ artifactId: identifier, limit: z.number().int().min(1).max(10).default(5), beforeSequence: z.number().int().positive().optional(), response: z.enum(['full', 'summary']).optional() });
|
|
@@ -52,5 +182,6 @@ export function decodeFile(file) {
|
|
|
52
182
|
}
|
|
53
183
|
export const publicationSchema = z.strictObject({ revisionId: identifier, version: z.number().int().positive(), url: z.url() });
|
|
54
184
|
export const revisionSchema = z.strictObject({ id: identifier, parentRevisionId: identifier.nullable(), sequence: z.number().int().positive(), authorUserId: identifier, authorClientId: identifier, createdAt: z.iso.datetime(), sha256: z.string().regex(/^[a-f0-9]{64}$/), snapshot: snapshotSchema });
|
|
55
|
-
export const artifactReadSchema = z.strictObject({ artifactId: identifier, ownerId: identifier, headRevisionId: identifier, publication: publicationSchema.nullable(), revision: revisionSchema });
|
|
185
|
+
export const artifactReadSchema = z.strictObject({ artifactId: identifier, ownerId: identifier, headRevisionId: identifier, project: z.string().nullable(), slug: z.string().nullable(), publication: publicationSchema.nullable(), revision: revisionSchema });
|
|
186
|
+
export const sharedReadSchema = z.strictObject({ artifactId: identifier, ownerName: z.string().default('Usuario de Artifacts'), publication: publicationSchema, revision: revisionSchema.pick({ id: true, createdAt: true, sha256: true, snapshot: true }) });
|
|
56
187
|
export const publishResultSchema = publicationSchema.extend({ artifactId: identifier });
|
package/src/workflow.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { ArtifactError, artifactReadSchema, createSchema, decodeFile,
|
|
2
|
+
import { ArtifactError, artifactReadSchema, createSchema, decodeFile, readByIdSchema, snapshotSchema, updateSchema } from "./index.js";
|
|
3
3
|
import { canonicalJson, sha256 } from "./serialization.js";
|
|
4
4
|
async function summarizeFiles(files) {
|
|
5
5
|
return Promise.all([...files].sort((left, right) => left.path < right.path ? -1 : left.path > right.path ? 1 : 0).map(async ({ path, mediaType, encoding, data }) => {
|
|
@@ -57,7 +57,7 @@ export async function compareRevisions(before, after) {
|
|
|
57
57
|
};
|
|
58
58
|
}
|
|
59
59
|
const prepareEditSchema = z.strictObject({
|
|
60
|
-
artifactId:
|
|
60
|
+
artifactId: readByIdSchema.shape.artifactId,
|
|
61
61
|
requestId: createSchema.shape.requestId,
|
|
62
62
|
changes: z.strictObject({
|
|
63
63
|
metadata: snapshotSchema.shape.metadata.partial().optional(),
|