@inixiative/signet 0.12.0 → 0.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/src/archive.ts +45 -3
- package/src/contracts.ts +3 -1
- package/src/lens.ts +13 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inixiative/signet",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.1",
|
|
4
4
|
"description": "Present Kingdom Signets: the wire contracts, DPoP proofs, device pairing and a renewing client shared by Kingdom, Archive, Foundry and Oracle.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.ts",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@asteasolutions/zod-to-openapi": "^9.1.0",
|
|
37
37
|
"@biomejs/biome": "2.5.2",
|
|
38
|
-
"@inixiative/config": "^0.5.
|
|
38
|
+
"@inixiative/config": "^0.5.175",
|
|
39
39
|
"@inixiative/json-rules": "^3.16.0",
|
|
40
40
|
"@types/bun": "1.4.4",
|
|
41
41
|
"lefthook": "2.1.9",
|
package/src/archive.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import type { Condition } from '@inixiative/json-rules';
|
|
1
2
|
import { z } from 'zod';
|
|
2
|
-
import { type GrantLens, projectionFilters, projectionShows } from './lens';
|
|
3
|
+
import { type GrantLens, type LensLayer, projectionFilters, projectionShows } from './lens';
|
|
3
4
|
import { type OperationScope, scopeRefusal } from './operations';
|
|
4
5
|
|
|
5
6
|
/**
|
|
@@ -12,7 +13,14 @@ export const archiveLibraryResourceKind = 'archiveLibrary';
|
|
|
12
13
|
|
|
13
14
|
/** An Archive session id: `archiveKey(snapshot)`, the digest of its source and session. */
|
|
14
15
|
export const archiveDocumentIdSchema = z.string().regex(/^[a-f0-9]{64}$/);
|
|
15
|
-
export const archiveFieldSchema = z.enum([
|
|
16
|
+
export const archiveFieldSchema = z.enum([
|
|
17
|
+
'id',
|
|
18
|
+
'title',
|
|
19
|
+
'content',
|
|
20
|
+
'tags',
|
|
21
|
+
'projectId',
|
|
22
|
+
'createdAt',
|
|
23
|
+
]);
|
|
16
24
|
export type ArchiveField = z.infer<typeof archiveFieldSchema>;
|
|
17
25
|
|
|
18
26
|
/** The operations an `archiveLibrary` resource carries. */
|
|
@@ -42,7 +50,7 @@ export const archiveSourceOperations = [
|
|
|
42
50
|
export const isArchiveSourceOperation = (operation: ArchiveOperation) =>
|
|
43
51
|
(archiveSourceOperations as readonly ArchiveOperation[]).includes(operation);
|
|
44
52
|
|
|
45
|
-
const fieldsSchema = z.array(archiveFieldSchema).min(1).max(
|
|
53
|
+
const fieldsSchema = z.array(archiveFieldSchema).min(1).max(archiveFieldSchema.options.length);
|
|
46
54
|
|
|
47
55
|
/**
|
|
48
56
|
* The input each Archive operation takes. `access/execute` carries the same fields beside
|
|
@@ -90,6 +98,40 @@ export const archiveLensRefusal = (operation: ArchiveOperation, lens: GrantLens)
|
|
|
90
98
|
return null;
|
|
91
99
|
};
|
|
92
100
|
|
|
101
|
+
type ArchiveInput<O extends ArchiveOperation> = z.infer<(typeof archiveInputSchemas)[O]>;
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* What one call filters on, as a json-rules condition over the Archive document, or undefined when
|
|
105
|
+
* it filters on nothing. Kingdom gates it with `validateRuleInLens` against the grant's composed
|
|
106
|
+
* lens: a filter on a field the lens hides (`projectId`, a `tag`) would say which documents carry a
|
|
107
|
+
* value the holder can't see, and is refused with the lens's own code.
|
|
108
|
+
*/
|
|
109
|
+
export const archiveCallCondition = <O extends ArchiveOperation>(
|
|
110
|
+
_operation: O,
|
|
111
|
+
input: ArchiveInput<O>,
|
|
112
|
+
): Condition | undefined => {
|
|
113
|
+
const rules: Condition[] = [
|
|
114
|
+
...('projectId' in input && input.projectId !== undefined
|
|
115
|
+
? [{ field: 'projectId', operator: 'equals' as const, value: input.projectId }]
|
|
116
|
+
: []),
|
|
117
|
+
...('tag' in input && input.tag !== undefined
|
|
118
|
+
? [{ field: 'tags', operator: 'contains' as const, value: input.tag }]
|
|
119
|
+
: []),
|
|
120
|
+
];
|
|
121
|
+
return rules.length === 0 ? undefined : rules.length === 1 ? rules[0] : { all: rules };
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* The fields one call asks for, as a lens layer that picks them, or undefined when it asks for none.
|
|
126
|
+
* Kingdom validates it under the grant's composed lens (`validateNarrowing`): a field the lens hides
|
|
127
|
+
* is refused there.
|
|
128
|
+
*/
|
|
129
|
+
export const archiveCallNarrowing = <O extends ArchiveOperation>(
|
|
130
|
+
_operation: O,
|
|
131
|
+
input: ArchiveInput<O>,
|
|
132
|
+
): LensLayer | undefined =>
|
|
133
|
+
'fields' in input && input.fields?.length ? { root: { picks: [...input.fields] } } : undefined;
|
|
134
|
+
|
|
93
135
|
/** `archiveLensRefusal` over every operation a grant row reaches, `full` meaning all of them. */
|
|
94
136
|
export const archiveGrantRefusal = (scope: OperationScope, lens: GrantLens) =>
|
|
95
137
|
scopeRefusal(scope, archiveOperationSchema.options, (operation) =>
|
package/src/contracts.ts
CHANGED
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
signetGrantSchema,
|
|
15
15
|
signetResourceSchema,
|
|
16
16
|
} from './grants';
|
|
17
|
-
import { storedLensLayersSchema } from './lens';
|
|
17
|
+
import { storedBaseLensSchema, storedLensLayersSchema } from './lens';
|
|
18
18
|
import {
|
|
19
19
|
foundryIdSchema,
|
|
20
20
|
threadFloorActionSchema,
|
|
@@ -280,6 +280,8 @@ export const hostedSignetSchema = z.object({
|
|
|
280
280
|
id: z.uuid(),
|
|
281
281
|
displayName: z.string(),
|
|
282
282
|
}),
|
|
283
|
+
/** Each base lens the rows' `lens` layers compose under, keyed by `baseLensId(provider, kind)`. */
|
|
284
|
+
baseLenses: z.record(z.string(), storedBaseLensSchema),
|
|
283
285
|
resources: grantsSchema,
|
|
284
286
|
});
|
|
285
287
|
export type InstallationSignet = z.infer<typeof installationSignetSchema>;
|
package/src/lens.ts
CHANGED
|
@@ -34,6 +34,19 @@ export const storedLensLayerSchema = z.strictObject({
|
|
|
34
34
|
});
|
|
35
35
|
export const storedLensLayersSchema = z.array(storedLensLayerSchema).max(20);
|
|
36
36
|
|
|
37
|
+
/**
|
|
38
|
+
* A base lens as Kingdom's catalog carries it: the json-rules `Lens` itself (its field maps, map name
|
|
39
|
+
* and model) with an `id` and no parents. Only the envelope is checked here; a holder composes it
|
|
40
|
+
* under a grant's layers with json-rules `composeLens`, which validates what is inside.
|
|
41
|
+
*/
|
|
42
|
+
export const storedBaseLensSchema = z.looseObject({
|
|
43
|
+
id: layerId,
|
|
44
|
+
parents: z.array(layerId).max(0),
|
|
45
|
+
mapName: z.string().min(1),
|
|
46
|
+
model: z.string().min(1),
|
|
47
|
+
maps: z.record(z.string(), z.unknown()),
|
|
48
|
+
});
|
|
49
|
+
|
|
37
50
|
/** The id of an integration's base lens for a resource kind's model, in Kingdom's catalog. */
|
|
38
51
|
export const baseLensId = (provider: string, kind: string) => `${provider}:${kind}`;
|
|
39
52
|
|