@daena/core 0.1.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -0
- package/dist/index.d.ts +527 -0
- package/dist/index.js +102 -0
- package/package.json +33 -0
- package/src/errors.ts +25 -0
- package/src/index.ts +4 -0
- package/src/parse.ts +35 -0
- package/src/schema.ts +66 -0
- package/src/types.ts +90 -0
package/README.md
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# @daena/core
|
|
2
|
+
|
|
3
|
+
Core types, schema validation, and document utilities for the Daena Protocol.
|
|
4
|
+
|
|
5
|
+
This package is the foundation every other reference package depends on. It contains:
|
|
6
|
+
|
|
7
|
+
- TypeScript types for Daena documents, facts, capabilities, and render hints
|
|
8
|
+
- JSON Schema validators for the on-the-wire shapes defined in [SPEC.md](https://github.com/daena-protocol/spec/blob/main/SPEC.md)
|
|
9
|
+
- Canonical serialization helpers required for stable signing
|
|
10
|
+
|
|
11
|
+
## Status
|
|
12
|
+
|
|
13
|
+
Pre-alpha. Interfaces will change as the spec evolves toward v1.
|
|
14
|
+
|
|
15
|
+
## License
|
|
16
|
+
|
|
17
|
+
[Apache-2.0](../../LICENSE).
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,527 @@
|
|
|
1
|
+
import { z, ZodError } from 'zod';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Daena Protocol v0 — TypeScript types
|
|
5
|
+
*
|
|
6
|
+
* Derived from SPEC.md sections 2-5. These types track the editor's draft
|
|
7
|
+
* and will evolve until v1.0.
|
|
8
|
+
*/
|
|
9
|
+
/** A cryptographic attestation by a publisher. */
|
|
10
|
+
interface Signature {
|
|
11
|
+
/** Algorithm identifier, e.g. "ed25519". */
|
|
12
|
+
algorithm: string;
|
|
13
|
+
/** Base64-encoded signature value. */
|
|
14
|
+
value: string;
|
|
15
|
+
/** DID URL identifying the key that produced the signature. */
|
|
16
|
+
keyId: string;
|
|
17
|
+
}
|
|
18
|
+
/** A typed, dated, signed statement made by a publisher about a subject. */
|
|
19
|
+
interface Fact {
|
|
20
|
+
/** Stable identifier for this fact within the document. */
|
|
21
|
+
id: string;
|
|
22
|
+
/** URI identifying the vocabulary under which this fact is interpreted. */
|
|
23
|
+
type: string;
|
|
24
|
+
/** The fact's value. May be a primitive, object, or array. */
|
|
25
|
+
value: unknown;
|
|
26
|
+
/** ISO 8601 timestamp of when the fact was last asserted. */
|
|
27
|
+
asOf: string;
|
|
28
|
+
/** Optional per-fact signature. If absent, the document-level signature attests this fact. */
|
|
29
|
+
signature?: Signature;
|
|
30
|
+
}
|
|
31
|
+
/** Typed parameter specification for a capability. */
|
|
32
|
+
interface CapabilityParameter {
|
|
33
|
+
type: "string" | "integer" | "number" | "boolean" | "datetime" | "phone" | "email";
|
|
34
|
+
required: boolean;
|
|
35
|
+
min?: number;
|
|
36
|
+
max?: number;
|
|
37
|
+
pattern?: string;
|
|
38
|
+
}
|
|
39
|
+
/** An action a publisher offers to agents. */
|
|
40
|
+
interface Capability {
|
|
41
|
+
/** Stable identifier for this capability within the document. */
|
|
42
|
+
id: string;
|
|
43
|
+
/** Human-readable label for the action. */
|
|
44
|
+
name: string;
|
|
45
|
+
/** URI identifying the capability vocabulary. */
|
|
46
|
+
type: string;
|
|
47
|
+
/** Typed parameter specifications keyed by parameter name. */
|
|
48
|
+
parameters: Record<string, CapabilityParameter>;
|
|
49
|
+
/** HTTPS endpoint where ACT requests are sent. */
|
|
50
|
+
endpoint: string;
|
|
51
|
+
/** Authentication mode required to invoke this capability. */
|
|
52
|
+
auth: "none" | "bearer" | "did";
|
|
53
|
+
/** Optional payment requirement. */
|
|
54
|
+
price?: {
|
|
55
|
+
amount: number;
|
|
56
|
+
currency: string;
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
/** Optional metadata that guides how a renderer produces a human view. */
|
|
60
|
+
interface RenderHints {
|
|
61
|
+
/** Title shown at the top of the rendered view. */
|
|
62
|
+
title?: string;
|
|
63
|
+
/** Ordered list of fact IDs to feature prominently. */
|
|
64
|
+
primary?: string[];
|
|
65
|
+
/** Ordered list of capability IDs to surface as primary actions. */
|
|
66
|
+
callsToAction?: string[];
|
|
67
|
+
/** Optional theming. */
|
|
68
|
+
theme?: {
|
|
69
|
+
accent?: string;
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/** A complete Daena document — the atomic unit of publication. */
|
|
73
|
+
interface DaenaDocument {
|
|
74
|
+
/** Protocol version. */
|
|
75
|
+
daena: "0";
|
|
76
|
+
/** Publisher identity as a Decentralized Identifier. */
|
|
77
|
+
publisher: string;
|
|
78
|
+
/** Signed statements made by the publisher. */
|
|
79
|
+
facts: Fact[];
|
|
80
|
+
/** Actions the publisher offers to agents. */
|
|
81
|
+
capabilities: Capability[];
|
|
82
|
+
/** Optional rendering metadata. */
|
|
83
|
+
render?: RenderHints;
|
|
84
|
+
/** Document-level signature. */
|
|
85
|
+
signature: Signature;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
declare const SignatureSchema: z.ZodObject<{
|
|
89
|
+
algorithm: z.ZodString;
|
|
90
|
+
value: z.ZodString;
|
|
91
|
+
keyId: z.ZodString;
|
|
92
|
+
}, "strip", z.ZodTypeAny, {
|
|
93
|
+
algorithm: string;
|
|
94
|
+
value: string;
|
|
95
|
+
keyId: string;
|
|
96
|
+
}, {
|
|
97
|
+
algorithm: string;
|
|
98
|
+
value: string;
|
|
99
|
+
keyId: string;
|
|
100
|
+
}>;
|
|
101
|
+
declare const CapabilityParameterSchema: z.ZodObject<{
|
|
102
|
+
type: z.ZodEnum<["string", "integer", "number", "boolean", "datetime", "phone", "email"]>;
|
|
103
|
+
required: z.ZodBoolean;
|
|
104
|
+
min: z.ZodOptional<z.ZodNumber>;
|
|
105
|
+
max: z.ZodOptional<z.ZodNumber>;
|
|
106
|
+
pattern: z.ZodOptional<z.ZodString>;
|
|
107
|
+
}, "strip", z.ZodTypeAny, {
|
|
108
|
+
type: "string" | "number" | "boolean" | "integer" | "datetime" | "phone" | "email";
|
|
109
|
+
required: boolean;
|
|
110
|
+
min?: number | undefined;
|
|
111
|
+
max?: number | undefined;
|
|
112
|
+
pattern?: string | undefined;
|
|
113
|
+
}, {
|
|
114
|
+
type: "string" | "number" | "boolean" | "integer" | "datetime" | "phone" | "email";
|
|
115
|
+
required: boolean;
|
|
116
|
+
min?: number | undefined;
|
|
117
|
+
max?: number | undefined;
|
|
118
|
+
pattern?: string | undefined;
|
|
119
|
+
}>;
|
|
120
|
+
declare const CapabilitySchema: z.ZodObject<{
|
|
121
|
+
id: z.ZodString;
|
|
122
|
+
name: z.ZodString;
|
|
123
|
+
type: z.ZodString;
|
|
124
|
+
parameters: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
125
|
+
type: z.ZodEnum<["string", "integer", "number", "boolean", "datetime", "phone", "email"]>;
|
|
126
|
+
required: z.ZodBoolean;
|
|
127
|
+
min: z.ZodOptional<z.ZodNumber>;
|
|
128
|
+
max: z.ZodOptional<z.ZodNumber>;
|
|
129
|
+
pattern: z.ZodOptional<z.ZodString>;
|
|
130
|
+
}, "strip", z.ZodTypeAny, {
|
|
131
|
+
type: "string" | "number" | "boolean" | "integer" | "datetime" | "phone" | "email";
|
|
132
|
+
required: boolean;
|
|
133
|
+
min?: number | undefined;
|
|
134
|
+
max?: number | undefined;
|
|
135
|
+
pattern?: string | undefined;
|
|
136
|
+
}, {
|
|
137
|
+
type: "string" | "number" | "boolean" | "integer" | "datetime" | "phone" | "email";
|
|
138
|
+
required: boolean;
|
|
139
|
+
min?: number | undefined;
|
|
140
|
+
max?: number | undefined;
|
|
141
|
+
pattern?: string | undefined;
|
|
142
|
+
}>>;
|
|
143
|
+
endpoint: z.ZodString;
|
|
144
|
+
auth: z.ZodEnum<["none", "bearer", "did"]>;
|
|
145
|
+
price: z.ZodOptional<z.ZodObject<{
|
|
146
|
+
amount: z.ZodNumber;
|
|
147
|
+
currency: z.ZodString;
|
|
148
|
+
}, "strip", z.ZodTypeAny, {
|
|
149
|
+
amount: number;
|
|
150
|
+
currency: string;
|
|
151
|
+
}, {
|
|
152
|
+
amount: number;
|
|
153
|
+
currency: string;
|
|
154
|
+
}>>;
|
|
155
|
+
}, "strip", z.ZodTypeAny, {
|
|
156
|
+
type: string;
|
|
157
|
+
id: string;
|
|
158
|
+
name: string;
|
|
159
|
+
parameters: Record<string, {
|
|
160
|
+
type: "string" | "number" | "boolean" | "integer" | "datetime" | "phone" | "email";
|
|
161
|
+
required: boolean;
|
|
162
|
+
min?: number | undefined;
|
|
163
|
+
max?: number | undefined;
|
|
164
|
+
pattern?: string | undefined;
|
|
165
|
+
}>;
|
|
166
|
+
endpoint: string;
|
|
167
|
+
auth: "none" | "bearer" | "did";
|
|
168
|
+
price?: {
|
|
169
|
+
amount: number;
|
|
170
|
+
currency: string;
|
|
171
|
+
} | undefined;
|
|
172
|
+
}, {
|
|
173
|
+
type: string;
|
|
174
|
+
id: string;
|
|
175
|
+
name: string;
|
|
176
|
+
parameters: Record<string, {
|
|
177
|
+
type: "string" | "number" | "boolean" | "integer" | "datetime" | "phone" | "email";
|
|
178
|
+
required: boolean;
|
|
179
|
+
min?: number | undefined;
|
|
180
|
+
max?: number | undefined;
|
|
181
|
+
pattern?: string | undefined;
|
|
182
|
+
}>;
|
|
183
|
+
endpoint: string;
|
|
184
|
+
auth: "none" | "bearer" | "did";
|
|
185
|
+
price?: {
|
|
186
|
+
amount: number;
|
|
187
|
+
currency: string;
|
|
188
|
+
} | undefined;
|
|
189
|
+
}>;
|
|
190
|
+
declare const FactSchema: z.ZodObject<{
|
|
191
|
+
id: z.ZodString;
|
|
192
|
+
type: z.ZodString;
|
|
193
|
+
value: z.ZodUnknown;
|
|
194
|
+
asOf: z.ZodString;
|
|
195
|
+
signature: z.ZodOptional<z.ZodObject<{
|
|
196
|
+
algorithm: z.ZodString;
|
|
197
|
+
value: z.ZodString;
|
|
198
|
+
keyId: z.ZodString;
|
|
199
|
+
}, "strip", z.ZodTypeAny, {
|
|
200
|
+
algorithm: string;
|
|
201
|
+
value: string;
|
|
202
|
+
keyId: string;
|
|
203
|
+
}, {
|
|
204
|
+
algorithm: string;
|
|
205
|
+
value: string;
|
|
206
|
+
keyId: string;
|
|
207
|
+
}>>;
|
|
208
|
+
}, "strip", z.ZodTypeAny, {
|
|
209
|
+
type: string;
|
|
210
|
+
id: string;
|
|
211
|
+
asOf: string;
|
|
212
|
+
value?: unknown;
|
|
213
|
+
signature?: {
|
|
214
|
+
algorithm: string;
|
|
215
|
+
value: string;
|
|
216
|
+
keyId: string;
|
|
217
|
+
} | undefined;
|
|
218
|
+
}, {
|
|
219
|
+
type: string;
|
|
220
|
+
id: string;
|
|
221
|
+
asOf: string;
|
|
222
|
+
value?: unknown;
|
|
223
|
+
signature?: {
|
|
224
|
+
algorithm: string;
|
|
225
|
+
value: string;
|
|
226
|
+
keyId: string;
|
|
227
|
+
} | undefined;
|
|
228
|
+
}>;
|
|
229
|
+
declare const RenderHintsSchema: z.ZodObject<{
|
|
230
|
+
title: z.ZodOptional<z.ZodString>;
|
|
231
|
+
primary: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
232
|
+
callsToAction: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
233
|
+
theme: z.ZodOptional<z.ZodObject<{
|
|
234
|
+
accent: z.ZodOptional<z.ZodString>;
|
|
235
|
+
}, "strip", z.ZodTypeAny, {
|
|
236
|
+
accent?: string | undefined;
|
|
237
|
+
}, {
|
|
238
|
+
accent?: string | undefined;
|
|
239
|
+
}>>;
|
|
240
|
+
}, "strip", z.ZodTypeAny, {
|
|
241
|
+
title?: string | undefined;
|
|
242
|
+
primary?: string[] | undefined;
|
|
243
|
+
callsToAction?: string[] | undefined;
|
|
244
|
+
theme?: {
|
|
245
|
+
accent?: string | undefined;
|
|
246
|
+
} | undefined;
|
|
247
|
+
}, {
|
|
248
|
+
title?: string | undefined;
|
|
249
|
+
primary?: string[] | undefined;
|
|
250
|
+
callsToAction?: string[] | undefined;
|
|
251
|
+
theme?: {
|
|
252
|
+
accent?: string | undefined;
|
|
253
|
+
} | undefined;
|
|
254
|
+
}>;
|
|
255
|
+
declare const DaenaDocumentSchema: z.ZodObject<{
|
|
256
|
+
daena: z.ZodLiteral<"0">;
|
|
257
|
+
publisher: z.ZodString;
|
|
258
|
+
facts: z.ZodArray<z.ZodObject<{
|
|
259
|
+
id: z.ZodString;
|
|
260
|
+
type: z.ZodString;
|
|
261
|
+
value: z.ZodUnknown;
|
|
262
|
+
asOf: z.ZodString;
|
|
263
|
+
signature: z.ZodOptional<z.ZodObject<{
|
|
264
|
+
algorithm: z.ZodString;
|
|
265
|
+
value: z.ZodString;
|
|
266
|
+
keyId: z.ZodString;
|
|
267
|
+
}, "strip", z.ZodTypeAny, {
|
|
268
|
+
algorithm: string;
|
|
269
|
+
value: string;
|
|
270
|
+
keyId: string;
|
|
271
|
+
}, {
|
|
272
|
+
algorithm: string;
|
|
273
|
+
value: string;
|
|
274
|
+
keyId: string;
|
|
275
|
+
}>>;
|
|
276
|
+
}, "strip", z.ZodTypeAny, {
|
|
277
|
+
type: string;
|
|
278
|
+
id: string;
|
|
279
|
+
asOf: string;
|
|
280
|
+
value?: unknown;
|
|
281
|
+
signature?: {
|
|
282
|
+
algorithm: string;
|
|
283
|
+
value: string;
|
|
284
|
+
keyId: string;
|
|
285
|
+
} | undefined;
|
|
286
|
+
}, {
|
|
287
|
+
type: string;
|
|
288
|
+
id: string;
|
|
289
|
+
asOf: string;
|
|
290
|
+
value?: unknown;
|
|
291
|
+
signature?: {
|
|
292
|
+
algorithm: string;
|
|
293
|
+
value: string;
|
|
294
|
+
keyId: string;
|
|
295
|
+
} | undefined;
|
|
296
|
+
}>, "many">;
|
|
297
|
+
capabilities: z.ZodArray<z.ZodObject<{
|
|
298
|
+
id: z.ZodString;
|
|
299
|
+
name: z.ZodString;
|
|
300
|
+
type: z.ZodString;
|
|
301
|
+
parameters: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
302
|
+
type: z.ZodEnum<["string", "integer", "number", "boolean", "datetime", "phone", "email"]>;
|
|
303
|
+
required: z.ZodBoolean;
|
|
304
|
+
min: z.ZodOptional<z.ZodNumber>;
|
|
305
|
+
max: z.ZodOptional<z.ZodNumber>;
|
|
306
|
+
pattern: z.ZodOptional<z.ZodString>;
|
|
307
|
+
}, "strip", z.ZodTypeAny, {
|
|
308
|
+
type: "string" | "number" | "boolean" | "integer" | "datetime" | "phone" | "email";
|
|
309
|
+
required: boolean;
|
|
310
|
+
min?: number | undefined;
|
|
311
|
+
max?: number | undefined;
|
|
312
|
+
pattern?: string | undefined;
|
|
313
|
+
}, {
|
|
314
|
+
type: "string" | "number" | "boolean" | "integer" | "datetime" | "phone" | "email";
|
|
315
|
+
required: boolean;
|
|
316
|
+
min?: number | undefined;
|
|
317
|
+
max?: number | undefined;
|
|
318
|
+
pattern?: string | undefined;
|
|
319
|
+
}>>;
|
|
320
|
+
endpoint: z.ZodString;
|
|
321
|
+
auth: z.ZodEnum<["none", "bearer", "did"]>;
|
|
322
|
+
price: z.ZodOptional<z.ZodObject<{
|
|
323
|
+
amount: z.ZodNumber;
|
|
324
|
+
currency: z.ZodString;
|
|
325
|
+
}, "strip", z.ZodTypeAny, {
|
|
326
|
+
amount: number;
|
|
327
|
+
currency: string;
|
|
328
|
+
}, {
|
|
329
|
+
amount: number;
|
|
330
|
+
currency: string;
|
|
331
|
+
}>>;
|
|
332
|
+
}, "strip", z.ZodTypeAny, {
|
|
333
|
+
type: string;
|
|
334
|
+
id: string;
|
|
335
|
+
name: string;
|
|
336
|
+
parameters: Record<string, {
|
|
337
|
+
type: "string" | "number" | "boolean" | "integer" | "datetime" | "phone" | "email";
|
|
338
|
+
required: boolean;
|
|
339
|
+
min?: number | undefined;
|
|
340
|
+
max?: number | undefined;
|
|
341
|
+
pattern?: string | undefined;
|
|
342
|
+
}>;
|
|
343
|
+
endpoint: string;
|
|
344
|
+
auth: "none" | "bearer" | "did";
|
|
345
|
+
price?: {
|
|
346
|
+
amount: number;
|
|
347
|
+
currency: string;
|
|
348
|
+
} | undefined;
|
|
349
|
+
}, {
|
|
350
|
+
type: string;
|
|
351
|
+
id: string;
|
|
352
|
+
name: string;
|
|
353
|
+
parameters: Record<string, {
|
|
354
|
+
type: "string" | "number" | "boolean" | "integer" | "datetime" | "phone" | "email";
|
|
355
|
+
required: boolean;
|
|
356
|
+
min?: number | undefined;
|
|
357
|
+
max?: number | undefined;
|
|
358
|
+
pattern?: string | undefined;
|
|
359
|
+
}>;
|
|
360
|
+
endpoint: string;
|
|
361
|
+
auth: "none" | "bearer" | "did";
|
|
362
|
+
price?: {
|
|
363
|
+
amount: number;
|
|
364
|
+
currency: string;
|
|
365
|
+
} | undefined;
|
|
366
|
+
}>, "many">;
|
|
367
|
+
render: z.ZodOptional<z.ZodObject<{
|
|
368
|
+
title: z.ZodOptional<z.ZodString>;
|
|
369
|
+
primary: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
370
|
+
callsToAction: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
371
|
+
theme: z.ZodOptional<z.ZodObject<{
|
|
372
|
+
accent: z.ZodOptional<z.ZodString>;
|
|
373
|
+
}, "strip", z.ZodTypeAny, {
|
|
374
|
+
accent?: string | undefined;
|
|
375
|
+
}, {
|
|
376
|
+
accent?: string | undefined;
|
|
377
|
+
}>>;
|
|
378
|
+
}, "strip", z.ZodTypeAny, {
|
|
379
|
+
title?: string | undefined;
|
|
380
|
+
primary?: string[] | undefined;
|
|
381
|
+
callsToAction?: string[] | undefined;
|
|
382
|
+
theme?: {
|
|
383
|
+
accent?: string | undefined;
|
|
384
|
+
} | undefined;
|
|
385
|
+
}, {
|
|
386
|
+
title?: string | undefined;
|
|
387
|
+
primary?: string[] | undefined;
|
|
388
|
+
callsToAction?: string[] | undefined;
|
|
389
|
+
theme?: {
|
|
390
|
+
accent?: string | undefined;
|
|
391
|
+
} | undefined;
|
|
392
|
+
}>>;
|
|
393
|
+
signature: z.ZodObject<{
|
|
394
|
+
algorithm: z.ZodString;
|
|
395
|
+
value: z.ZodString;
|
|
396
|
+
keyId: z.ZodString;
|
|
397
|
+
}, "strip", z.ZodTypeAny, {
|
|
398
|
+
algorithm: string;
|
|
399
|
+
value: string;
|
|
400
|
+
keyId: string;
|
|
401
|
+
}, {
|
|
402
|
+
algorithm: string;
|
|
403
|
+
value: string;
|
|
404
|
+
keyId: string;
|
|
405
|
+
}>;
|
|
406
|
+
}, "strip", z.ZodTypeAny, {
|
|
407
|
+
signature: {
|
|
408
|
+
algorithm: string;
|
|
409
|
+
value: string;
|
|
410
|
+
keyId: string;
|
|
411
|
+
};
|
|
412
|
+
daena: "0";
|
|
413
|
+
publisher: string;
|
|
414
|
+
facts: {
|
|
415
|
+
type: string;
|
|
416
|
+
id: string;
|
|
417
|
+
asOf: string;
|
|
418
|
+
value?: unknown;
|
|
419
|
+
signature?: {
|
|
420
|
+
algorithm: string;
|
|
421
|
+
value: string;
|
|
422
|
+
keyId: string;
|
|
423
|
+
} | undefined;
|
|
424
|
+
}[];
|
|
425
|
+
capabilities: {
|
|
426
|
+
type: string;
|
|
427
|
+
id: string;
|
|
428
|
+
name: string;
|
|
429
|
+
parameters: Record<string, {
|
|
430
|
+
type: "string" | "number" | "boolean" | "integer" | "datetime" | "phone" | "email";
|
|
431
|
+
required: boolean;
|
|
432
|
+
min?: number | undefined;
|
|
433
|
+
max?: number | undefined;
|
|
434
|
+
pattern?: string | undefined;
|
|
435
|
+
}>;
|
|
436
|
+
endpoint: string;
|
|
437
|
+
auth: "none" | "bearer" | "did";
|
|
438
|
+
price?: {
|
|
439
|
+
amount: number;
|
|
440
|
+
currency: string;
|
|
441
|
+
} | undefined;
|
|
442
|
+
}[];
|
|
443
|
+
render?: {
|
|
444
|
+
title?: string | undefined;
|
|
445
|
+
primary?: string[] | undefined;
|
|
446
|
+
callsToAction?: string[] | undefined;
|
|
447
|
+
theme?: {
|
|
448
|
+
accent?: string | undefined;
|
|
449
|
+
} | undefined;
|
|
450
|
+
} | undefined;
|
|
451
|
+
}, {
|
|
452
|
+
signature: {
|
|
453
|
+
algorithm: string;
|
|
454
|
+
value: string;
|
|
455
|
+
keyId: string;
|
|
456
|
+
};
|
|
457
|
+
daena: "0";
|
|
458
|
+
publisher: string;
|
|
459
|
+
facts: {
|
|
460
|
+
type: string;
|
|
461
|
+
id: string;
|
|
462
|
+
asOf: string;
|
|
463
|
+
value?: unknown;
|
|
464
|
+
signature?: {
|
|
465
|
+
algorithm: string;
|
|
466
|
+
value: string;
|
|
467
|
+
keyId: string;
|
|
468
|
+
} | undefined;
|
|
469
|
+
}[];
|
|
470
|
+
capabilities: {
|
|
471
|
+
type: string;
|
|
472
|
+
id: string;
|
|
473
|
+
name: string;
|
|
474
|
+
parameters: Record<string, {
|
|
475
|
+
type: "string" | "number" | "boolean" | "integer" | "datetime" | "phone" | "email";
|
|
476
|
+
required: boolean;
|
|
477
|
+
min?: number | undefined;
|
|
478
|
+
max?: number | undefined;
|
|
479
|
+
pattern?: string | undefined;
|
|
480
|
+
}>;
|
|
481
|
+
endpoint: string;
|
|
482
|
+
auth: "none" | "bearer" | "did";
|
|
483
|
+
price?: {
|
|
484
|
+
amount: number;
|
|
485
|
+
currency: string;
|
|
486
|
+
} | undefined;
|
|
487
|
+
}[];
|
|
488
|
+
render?: {
|
|
489
|
+
title?: string | undefined;
|
|
490
|
+
primary?: string[] | undefined;
|
|
491
|
+
callsToAction?: string[] | undefined;
|
|
492
|
+
theme?: {
|
|
493
|
+
accent?: string | undefined;
|
|
494
|
+
} | undefined;
|
|
495
|
+
} | undefined;
|
|
496
|
+
}>;
|
|
497
|
+
|
|
498
|
+
interface DaenaIssue {
|
|
499
|
+
path: string;
|
|
500
|
+
message: string;
|
|
501
|
+
}
|
|
502
|
+
declare class DaenaParseError extends Error {
|
|
503
|
+
readonly issues: DaenaIssue[];
|
|
504
|
+
constructor(zodError: ZodError);
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
/**
|
|
508
|
+
* Parse and validate a Daena document.
|
|
509
|
+
*
|
|
510
|
+
* Accepts either a JSON string or an already-parsed value.
|
|
511
|
+
* Throws DaenaParseError if the input fails v0 schema validation.
|
|
512
|
+
*/
|
|
513
|
+
declare function parse(input: string | unknown): DaenaDocument;
|
|
514
|
+
/**
|
|
515
|
+
* Non-throwing variant of parse(). Returns a result object so callers can
|
|
516
|
+
* branch without try/catch.
|
|
517
|
+
*/
|
|
518
|
+
type ParseResult = {
|
|
519
|
+
ok: true;
|
|
520
|
+
doc: DaenaDocument;
|
|
521
|
+
} | {
|
|
522
|
+
ok: false;
|
|
523
|
+
error: DaenaParseError;
|
|
524
|
+
};
|
|
525
|
+
declare function tryParse(input: string | unknown): ParseResult;
|
|
526
|
+
|
|
527
|
+
export { type Capability, type CapabilityParameter, CapabilityParameterSchema, CapabilitySchema, type DaenaDocument, DaenaDocumentSchema, type DaenaIssue, DaenaParseError, type Fact, FactSchema, type ParseResult, type RenderHints, RenderHintsSchema, type Signature, SignatureSchema, parse, tryParse };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
// src/schema.ts
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
var SignatureSchema = z.object({
|
|
4
|
+
algorithm: z.string().min(1),
|
|
5
|
+
value: z.string().min(1),
|
|
6
|
+
keyId: z.string().min(1)
|
|
7
|
+
});
|
|
8
|
+
var CapabilityParameterSchema = z.object({
|
|
9
|
+
type: z.enum([
|
|
10
|
+
"string",
|
|
11
|
+
"integer",
|
|
12
|
+
"number",
|
|
13
|
+
"boolean",
|
|
14
|
+
"datetime",
|
|
15
|
+
"phone",
|
|
16
|
+
"email"
|
|
17
|
+
]),
|
|
18
|
+
required: z.boolean(),
|
|
19
|
+
min: z.number().optional(),
|
|
20
|
+
max: z.number().optional(),
|
|
21
|
+
pattern: z.string().optional()
|
|
22
|
+
});
|
|
23
|
+
var CapabilitySchema = z.object({
|
|
24
|
+
id: z.string().min(1),
|
|
25
|
+
name: z.string().min(1),
|
|
26
|
+
type: z.string().url(),
|
|
27
|
+
parameters: z.record(CapabilityParameterSchema),
|
|
28
|
+
endpoint: z.string().url(),
|
|
29
|
+
auth: z.enum(["none", "bearer", "did"]),
|
|
30
|
+
price: z.object({
|
|
31
|
+
amount: z.number(),
|
|
32
|
+
currency: z.string().length(3)
|
|
33
|
+
}).optional()
|
|
34
|
+
});
|
|
35
|
+
var FactSchema = z.object({
|
|
36
|
+
id: z.string().min(1),
|
|
37
|
+
type: z.string().url(),
|
|
38
|
+
value: z.unknown(),
|
|
39
|
+
asOf: z.string().datetime(),
|
|
40
|
+
signature: SignatureSchema.optional()
|
|
41
|
+
});
|
|
42
|
+
var RenderHintsSchema = z.object({
|
|
43
|
+
title: z.string().optional(),
|
|
44
|
+
primary: z.array(z.string()).optional(),
|
|
45
|
+
callsToAction: z.array(z.string()).optional(),
|
|
46
|
+
theme: z.object({
|
|
47
|
+
accent: z.string().optional()
|
|
48
|
+
}).optional()
|
|
49
|
+
});
|
|
50
|
+
var DaenaDocumentSchema = z.object({
|
|
51
|
+
daena: z.literal("0"),
|
|
52
|
+
publisher: z.string().min(1),
|
|
53
|
+
facts: z.array(FactSchema),
|
|
54
|
+
capabilities: z.array(CapabilitySchema),
|
|
55
|
+
render: RenderHintsSchema.optional(),
|
|
56
|
+
signature: SignatureSchema
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
// src/errors.ts
|
|
60
|
+
var DaenaParseError = class extends Error {
|
|
61
|
+
issues;
|
|
62
|
+
constructor(zodError) {
|
|
63
|
+
const issues = zodError.errors.map((e) => ({
|
|
64
|
+
path: e.path.join(".") || "(root)",
|
|
65
|
+
message: e.message
|
|
66
|
+
}));
|
|
67
|
+
const summary = issues.slice(0, 3).map((i) => `${i.path}: ${i.message}`).join("; ");
|
|
68
|
+
const tail = issues.length > 3 ? ` (+${issues.length - 3} more)` : "";
|
|
69
|
+
super(`Invalid Daena document \u2014 ${summary}${tail}`);
|
|
70
|
+
this.name = "DaenaParseError";
|
|
71
|
+
this.issues = issues;
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
// src/parse.ts
|
|
76
|
+
function parse(input) {
|
|
77
|
+
const raw = typeof input === "string" ? JSON.parse(input) : input;
|
|
78
|
+
const result = DaenaDocumentSchema.safeParse(raw);
|
|
79
|
+
if (!result.success) {
|
|
80
|
+
throw new DaenaParseError(result.error);
|
|
81
|
+
}
|
|
82
|
+
return result.data;
|
|
83
|
+
}
|
|
84
|
+
function tryParse(input) {
|
|
85
|
+
try {
|
|
86
|
+
return { ok: true, doc: parse(input) };
|
|
87
|
+
} catch (e) {
|
|
88
|
+
if (e instanceof DaenaParseError) return { ok: false, error: e };
|
|
89
|
+
throw e;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
export {
|
|
93
|
+
CapabilityParameterSchema,
|
|
94
|
+
CapabilitySchema,
|
|
95
|
+
DaenaDocumentSchema,
|
|
96
|
+
DaenaParseError,
|
|
97
|
+
FactSchema,
|
|
98
|
+
RenderHintsSchema,
|
|
99
|
+
SignatureSchema,
|
|
100
|
+
parse,
|
|
101
|
+
tryParse
|
|
102
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@daena/core",
|
|
3
|
+
"version": "0.1.0-alpha.0",
|
|
4
|
+
"description": "Core types and validation for the Daena Protocol",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"default": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": ["src", "dist"],
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "https://github.com/daena-protocol/daena.git",
|
|
19
|
+
"directory": "packages/core"
|
|
20
|
+
},
|
|
21
|
+
"homepage": "https://daena-protocol.org",
|
|
22
|
+
"publishConfig": {
|
|
23
|
+
"access": "public"
|
|
24
|
+
},
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "tsup src/index.ts --format esm --dts --clean",
|
|
27
|
+
"test": "vitest run",
|
|
28
|
+
"prepublishOnly": "npm run build"
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"zod": "^3.23.0"
|
|
32
|
+
}
|
|
33
|
+
}
|
package/src/errors.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ZodError } from "zod";
|
|
2
|
+
|
|
3
|
+
export interface DaenaIssue {
|
|
4
|
+
path: string;
|
|
5
|
+
message: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export class DaenaParseError extends Error {
|
|
9
|
+
readonly issues: DaenaIssue[];
|
|
10
|
+
|
|
11
|
+
constructor(zodError: ZodError) {
|
|
12
|
+
const issues: DaenaIssue[] = zodError.errors.map((e) => ({
|
|
13
|
+
path: e.path.join(".") || "(root)",
|
|
14
|
+
message: e.message
|
|
15
|
+
}));
|
|
16
|
+
const summary = issues
|
|
17
|
+
.slice(0, 3)
|
|
18
|
+
.map((i) => `${i.path}: ${i.message}`)
|
|
19
|
+
.join("; ");
|
|
20
|
+
const tail = issues.length > 3 ? ` (+${issues.length - 3} more)` : "";
|
|
21
|
+
super(`Invalid Daena document — ${summary}${tail}`);
|
|
22
|
+
this.name = "DaenaParseError";
|
|
23
|
+
this.issues = issues;
|
|
24
|
+
}
|
|
25
|
+
}
|
package/src/index.ts
ADDED
package/src/parse.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { DaenaDocumentSchema } from "./schema.js";
|
|
2
|
+
import { DaenaParseError } from "./errors.js";
|
|
3
|
+
import type { DaenaDocument } from "./types.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Parse and validate a Daena document.
|
|
7
|
+
*
|
|
8
|
+
* Accepts either a JSON string or an already-parsed value.
|
|
9
|
+
* Throws DaenaParseError if the input fails v0 schema validation.
|
|
10
|
+
*/
|
|
11
|
+
export function parse(input: string | unknown): DaenaDocument {
|
|
12
|
+
const raw = typeof input === "string" ? JSON.parse(input) : input;
|
|
13
|
+
const result = DaenaDocumentSchema.safeParse(raw);
|
|
14
|
+
if (!result.success) {
|
|
15
|
+
throw new DaenaParseError(result.error);
|
|
16
|
+
}
|
|
17
|
+
return result.data as DaenaDocument;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Non-throwing variant of parse(). Returns a result object so callers can
|
|
22
|
+
* branch without try/catch.
|
|
23
|
+
*/
|
|
24
|
+
export type ParseResult =
|
|
25
|
+
| { ok: true; doc: DaenaDocument }
|
|
26
|
+
| { ok: false; error: DaenaParseError };
|
|
27
|
+
|
|
28
|
+
export function tryParse(input: string | unknown): ParseResult {
|
|
29
|
+
try {
|
|
30
|
+
return { ok: true, doc: parse(input) };
|
|
31
|
+
} catch (e) {
|
|
32
|
+
if (e instanceof DaenaParseError) return { ok: false, error: e };
|
|
33
|
+
throw e;
|
|
34
|
+
}
|
|
35
|
+
}
|
package/src/schema.ts
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
export const SignatureSchema = z.object({
|
|
4
|
+
algorithm: z.string().min(1),
|
|
5
|
+
value: z.string().min(1),
|
|
6
|
+
keyId: z.string().min(1)
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
export const CapabilityParameterSchema = z.object({
|
|
10
|
+
type: z.enum([
|
|
11
|
+
"string",
|
|
12
|
+
"integer",
|
|
13
|
+
"number",
|
|
14
|
+
"boolean",
|
|
15
|
+
"datetime",
|
|
16
|
+
"phone",
|
|
17
|
+
"email"
|
|
18
|
+
]),
|
|
19
|
+
required: z.boolean(),
|
|
20
|
+
min: z.number().optional(),
|
|
21
|
+
max: z.number().optional(),
|
|
22
|
+
pattern: z.string().optional()
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
export const CapabilitySchema = z.object({
|
|
26
|
+
id: z.string().min(1),
|
|
27
|
+
name: z.string().min(1),
|
|
28
|
+
type: z.string().url(),
|
|
29
|
+
parameters: z.record(CapabilityParameterSchema),
|
|
30
|
+
endpoint: z.string().url(),
|
|
31
|
+
auth: z.enum(["none", "bearer", "did"]),
|
|
32
|
+
price: z
|
|
33
|
+
.object({
|
|
34
|
+
amount: z.number(),
|
|
35
|
+
currency: z.string().length(3)
|
|
36
|
+
})
|
|
37
|
+
.optional()
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
export const FactSchema = z.object({
|
|
41
|
+
id: z.string().min(1),
|
|
42
|
+
type: z.string().url(),
|
|
43
|
+
value: z.unknown(),
|
|
44
|
+
asOf: z.string().datetime(),
|
|
45
|
+
signature: SignatureSchema.optional()
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
export const RenderHintsSchema = z.object({
|
|
49
|
+
title: z.string().optional(),
|
|
50
|
+
primary: z.array(z.string()).optional(),
|
|
51
|
+
callsToAction: z.array(z.string()).optional(),
|
|
52
|
+
theme: z
|
|
53
|
+
.object({
|
|
54
|
+
accent: z.string().optional()
|
|
55
|
+
})
|
|
56
|
+
.optional()
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
export const DaenaDocumentSchema = z.object({
|
|
60
|
+
daena: z.literal("0"),
|
|
61
|
+
publisher: z.string().min(1),
|
|
62
|
+
facts: z.array(FactSchema),
|
|
63
|
+
capabilities: z.array(CapabilitySchema),
|
|
64
|
+
render: RenderHintsSchema.optional(),
|
|
65
|
+
signature: SignatureSchema
|
|
66
|
+
});
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Daena Protocol v0 — TypeScript types
|
|
3
|
+
*
|
|
4
|
+
* Derived from SPEC.md sections 2-5. These types track the editor's draft
|
|
5
|
+
* and will evolve until v1.0.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/** A cryptographic attestation by a publisher. */
|
|
9
|
+
export interface Signature {
|
|
10
|
+
/** Algorithm identifier, e.g. "ed25519". */
|
|
11
|
+
algorithm: string;
|
|
12
|
+
/** Base64-encoded signature value. */
|
|
13
|
+
value: string;
|
|
14
|
+
/** DID URL identifying the key that produced the signature. */
|
|
15
|
+
keyId: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** A typed, dated, signed statement made by a publisher about a subject. */
|
|
19
|
+
export interface Fact {
|
|
20
|
+
/** Stable identifier for this fact within the document. */
|
|
21
|
+
id: string;
|
|
22
|
+
/** URI identifying the vocabulary under which this fact is interpreted. */
|
|
23
|
+
type: string;
|
|
24
|
+
/** The fact's value. May be a primitive, object, or array. */
|
|
25
|
+
value: unknown;
|
|
26
|
+
/** ISO 8601 timestamp of when the fact was last asserted. */
|
|
27
|
+
asOf: string;
|
|
28
|
+
/** Optional per-fact signature. If absent, the document-level signature attests this fact. */
|
|
29
|
+
signature?: Signature;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** Typed parameter specification for a capability. */
|
|
33
|
+
export interface CapabilityParameter {
|
|
34
|
+
type: "string" | "integer" | "number" | "boolean" | "datetime" | "phone" | "email";
|
|
35
|
+
required: boolean;
|
|
36
|
+
min?: number;
|
|
37
|
+
max?: number;
|
|
38
|
+
pattern?: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** An action a publisher offers to agents. */
|
|
42
|
+
export interface Capability {
|
|
43
|
+
/** Stable identifier for this capability within the document. */
|
|
44
|
+
id: string;
|
|
45
|
+
/** Human-readable label for the action. */
|
|
46
|
+
name: string;
|
|
47
|
+
/** URI identifying the capability vocabulary. */
|
|
48
|
+
type: string;
|
|
49
|
+
/** Typed parameter specifications keyed by parameter name. */
|
|
50
|
+
parameters: Record<string, CapabilityParameter>;
|
|
51
|
+
/** HTTPS endpoint where ACT requests are sent. */
|
|
52
|
+
endpoint: string;
|
|
53
|
+
/** Authentication mode required to invoke this capability. */
|
|
54
|
+
auth: "none" | "bearer" | "did";
|
|
55
|
+
/** Optional payment requirement. */
|
|
56
|
+
price?: {
|
|
57
|
+
amount: number;
|
|
58
|
+
currency: string;
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** Optional metadata that guides how a renderer produces a human view. */
|
|
63
|
+
export interface RenderHints {
|
|
64
|
+
/** Title shown at the top of the rendered view. */
|
|
65
|
+
title?: string;
|
|
66
|
+
/** Ordered list of fact IDs to feature prominently. */
|
|
67
|
+
primary?: string[];
|
|
68
|
+
/** Ordered list of capability IDs to surface as primary actions. */
|
|
69
|
+
callsToAction?: string[];
|
|
70
|
+
/** Optional theming. */
|
|
71
|
+
theme?: {
|
|
72
|
+
accent?: string;
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** A complete Daena document — the atomic unit of publication. */
|
|
77
|
+
export interface DaenaDocument {
|
|
78
|
+
/** Protocol version. */
|
|
79
|
+
daena: "0";
|
|
80
|
+
/** Publisher identity as a Decentralized Identifier. */
|
|
81
|
+
publisher: string;
|
|
82
|
+
/** Signed statements made by the publisher. */
|
|
83
|
+
facts: Fact[];
|
|
84
|
+
/** Actions the publisher offers to agents. */
|
|
85
|
+
capabilities: Capability[];
|
|
86
|
+
/** Optional rendering metadata. */
|
|
87
|
+
render?: RenderHints;
|
|
88
|
+
/** Document-level signature. */
|
|
89
|
+
signature: Signature;
|
|
90
|
+
}
|