@yargote/artifacts-contracts 0.1.0-beta.7 → 0.1.0-beta.9
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 +5 -1
- package/package.json +1 -1
- package/src/http.d.ts +8 -0
- package/src/http.js +14 -1
- package/src/index.d.ts +18 -3
- package/src/index.js +11 -4
- package/src/workflow.js +2 -2
package/README.md
CHANGED
|
@@ -3,11 +3,15 @@
|
|
|
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.9
|
|
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
|
+
|
|
11
15
|
The existing `@artifacts/artifacts` root, `/contracts`, and `/workflow` exports re-export these implementations. Store and REST packages share one `ArtifactError` runtime.
|
|
12
16
|
|
|
13
17
|
This package is MIT licensed. The license applies to this package and does not license the private Artifacts application repository.
|
package/package.json
CHANGED
package/src/http.d.ts
CHANGED
|
@@ -52,6 +52,7 @@ export declare const compactArtifactReadSchema: z.ZodObject<{
|
|
|
52
52
|
ownerId: z.ZodString;
|
|
53
53
|
headRevisionId: z.ZodString;
|
|
54
54
|
project: z.ZodNullable<z.ZodString>;
|
|
55
|
+
slug: z.ZodNullable<z.ZodString>;
|
|
55
56
|
artifactId: z.ZodString;
|
|
56
57
|
publication: z.ZodNullable<z.ZodObject<{
|
|
57
58
|
revisionId: z.ZodString;
|
|
@@ -97,6 +98,7 @@ export declare const artifactSummarySchema: z.ZodObject<{
|
|
|
97
98
|
headRevisionId: z.ZodString;
|
|
98
99
|
createdAt: z.ZodISODateTime;
|
|
99
100
|
project: z.ZodNullable<z.ZodString>;
|
|
101
|
+
slug: z.ZodNullable<z.ZodString>;
|
|
100
102
|
publication: z.ZodNullable<z.ZodObject<{
|
|
101
103
|
revisionId: z.ZodString;
|
|
102
104
|
version: z.ZodNumber;
|
|
@@ -110,6 +112,7 @@ export declare const listResultSchema: z.ZodObject<{
|
|
|
110
112
|
headRevisionId: z.ZodString;
|
|
111
113
|
createdAt: z.ZodISODateTime;
|
|
112
114
|
project: z.ZodNullable<z.ZodString>;
|
|
115
|
+
slug: z.ZodNullable<z.ZodString>;
|
|
113
116
|
publication: z.ZodNullable<z.ZodObject<{
|
|
114
117
|
revisionId: z.ZodString;
|
|
115
118
|
version: z.ZodNumber;
|
|
@@ -208,5 +211,10 @@ export declare const httpErrorSchema: z.ZodObject<{
|
|
|
208
211
|
}, z.core.$strict>;
|
|
209
212
|
}, z.core.$strict>;
|
|
210
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>;
|
|
211
219
|
export declare function protectedResourceMetadataUrl(resource: string): URL;
|
|
212
220
|
export declare function restBase(resource: string): string;
|
package/src/http.js
CHANGED
|
@@ -10,7 +10,7 @@ export const revisionSummarySchema = revisionSchema.omit({ snapshot: true }).ext
|
|
|
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(), project: z.string().nullable(), 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
15
|
export const projectSummarySchema = z.strictObject({ name: z.string(), artifactCount: z.number().int().positive() });
|
|
16
16
|
export const projectsResultSchema = z.strictObject({ items: z.array(projectSummarySchema) });
|
|
@@ -26,6 +26,19 @@ export function canonicalResource(value) {
|
|
|
26
26
|
throw new TypeError('Use the exact canonical resource URL without a trailing slash');
|
|
27
27
|
return value;
|
|
28
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
|
+
});
|
|
29
42
|
export function protectedResourceMetadataUrl(resource) {
|
|
30
43
|
const url = new URL(canonicalResource(resource));
|
|
31
44
|
return new URL(`/.well-known/oauth-protected-resource${url.pathname === '/' ? '' : url.pathname}`, url.origin);
|
package/src/index.d.ts
CHANGED
|
@@ -59,6 +59,7 @@ export type Canvas = {
|
|
|
59
59
|
};
|
|
60
60
|
export declare function parseCanvas(snapshot: Pick<Snapshot, 'content' | 'files'>): Canvas;
|
|
61
61
|
export declare const projectNameSchema: z.ZodString;
|
|
62
|
+
export declare const slugSchema: z.ZodString;
|
|
62
63
|
export declare const createSchema: z.ZodObject<{
|
|
63
64
|
requestId: z.ZodString;
|
|
64
65
|
snapshot: z.ZodObject<{
|
|
@@ -87,12 +88,13 @@ export declare const createSchema: z.ZodObject<{
|
|
|
87
88
|
}, z.core.$strict>>;
|
|
88
89
|
}, z.core.$strict>;
|
|
89
90
|
project: z.ZodOptional<z.ZodString>;
|
|
91
|
+
slug: z.ZodOptional<z.ZodString>;
|
|
90
92
|
response: z.ZodOptional<z.ZodEnum<{
|
|
91
93
|
full: "full";
|
|
92
94
|
compact: "compact";
|
|
93
95
|
}>>;
|
|
94
96
|
}, z.core.$strict>;
|
|
95
|
-
export declare const
|
|
97
|
+
export declare const readByIdSchema: z.ZodObject<{
|
|
96
98
|
artifactId: z.ZodString;
|
|
97
99
|
revisionId: z.ZodOptional<z.ZodString>;
|
|
98
100
|
response: z.ZodOptional<z.ZodEnum<{
|
|
@@ -100,6 +102,16 @@ export declare const readSchema: z.ZodObject<{
|
|
|
100
102
|
compact: "compact";
|
|
101
103
|
}>>;
|
|
102
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>;
|
|
103
115
|
export declare const updateSchema: z.ZodObject<{
|
|
104
116
|
requestId: z.ZodString;
|
|
105
117
|
artifactId: z.ZodString;
|
|
@@ -154,7 +166,8 @@ export type DeleteResult = z.infer<typeof deleteResultSchema>;
|
|
|
154
166
|
export declare const moveSchema: z.ZodObject<{
|
|
155
167
|
requestId: z.ZodString;
|
|
156
168
|
artifactId: z.ZodString;
|
|
157
|
-
project: z.ZodNullable<z.ZodString
|
|
169
|
+
project: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
170
|
+
slug: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
158
171
|
}, z.core.$strict>;
|
|
159
172
|
export declare const moveResultSchema: z.ZodObject<{
|
|
160
173
|
artifactId: z.ZodString;
|
|
@@ -304,6 +317,7 @@ export type ArtifactSummary = {
|
|
|
304
317
|
headRevisionId: string;
|
|
305
318
|
createdAt: string;
|
|
306
319
|
project: string | null;
|
|
320
|
+
slug: string | null;
|
|
307
321
|
publication: Publication | null;
|
|
308
322
|
};
|
|
309
323
|
export type ProjectSummary = {
|
|
@@ -327,7 +341,7 @@ export type Archive = {
|
|
|
327
341
|
base64: string;
|
|
328
342
|
sha256: string;
|
|
329
343
|
};
|
|
330
|
-
export type ArtifactErrorCode = 'forbidden' | 'not_found' | 'conflict' | 'request_conflict' | 'invalid_grant';
|
|
344
|
+
export type ArtifactErrorCode = 'forbidden' | 'not_found' | 'conflict' | 'request_conflict' | 'slug_conflict' | 'invalid_grant';
|
|
331
345
|
export declare class ArtifactError extends Error {
|
|
332
346
|
readonly code: ArtifactErrorCode;
|
|
333
347
|
readonly details: Record<string, unknown>;
|
|
@@ -381,6 +395,7 @@ export declare const artifactReadSchema: z.ZodObject<{
|
|
|
381
395
|
ownerId: z.ZodString;
|
|
382
396
|
headRevisionId: z.ZodString;
|
|
383
397
|
project: z.ZodNullable<z.ZodString>;
|
|
398
|
+
slug: z.ZodNullable<z.ZodString>;
|
|
384
399
|
publication: z.ZodNullable<z.ZodObject<{
|
|
385
400
|
revisionId: z.ZodString;
|
|
386
401
|
version: z.ZodNumber;
|
package/src/index.js
CHANGED
|
@@ -122,13 +122,20 @@ export function parseCanvas(snapshot) {
|
|
|
122
122
|
}
|
|
123
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');
|
|
124
124
|
const response = z.enum(['full', 'compact']).optional();
|
|
125
|
-
|
|
126
|
-
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');
|
|
127
133
|
export const updateSchema = z.strictObject({ requestId, artifactId: identifier, expectedRevisionId: identifier, snapshot: snapshotSchema, response });
|
|
128
134
|
export const publishSchema = z.strictObject({ requestId, artifactId: identifier, revisionId: identifier, expectedPublicationVersion: z.number().int().nonnegative() });
|
|
129
135
|
export const deleteSchema = z.strictObject({ requestId, artifactId: identifier, expectedRevisionId: identifier, expectedPublicationVersion: z.number().int().nonnegative() });
|
|
130
136
|
export const deleteResultSchema = z.strictObject({ artifactId: identifier });
|
|
131
|
-
export const moveSchema = z.strictObject({ requestId, artifactId: identifier, project: projectNameSchema.nullable() })
|
|
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');
|
|
132
139
|
export const moveResultSchema = z.strictObject({ artifactId: identifier, project: z.string().nullable() });
|
|
133
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() });
|
|
134
141
|
export const unshareSchema = z.strictObject({ requestId, artifactId: identifier, shareId: identifier });
|
|
@@ -167,6 +174,6 @@ export function decodeFile(file) {
|
|
|
167
174
|
}
|
|
168
175
|
export const publicationSchema = z.strictObject({ revisionId: identifier, version: z.number().int().positive(), url: z.url() });
|
|
169
176
|
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 });
|
|
170
|
-
export const artifactReadSchema = z.strictObject({ artifactId: identifier, ownerId: identifier, headRevisionId: identifier, project: z.string().nullable(), publication: publicationSchema.nullable(), revision: revisionSchema });
|
|
177
|
+
export const artifactReadSchema = z.strictObject({ artifactId: identifier, ownerId: identifier, headRevisionId: identifier, project: z.string().nullable(), slug: z.string().nullable(), publication: publicationSchema.nullable(), revision: revisionSchema });
|
|
171
178
|
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 }) });
|
|
172
179
|
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(),
|