@kubun/protocol 0.10.0 → 0.12.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/lib/errors.d.ts +16 -0
- package/lib/errors.js +26 -1
- package/lib/executor.js +6 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.js +12 -1
- package/lib/models/catalog.js +6 -1
- package/lib/models/cluster.d.ts +2 -2
- package/lib/models/cluster.js +186 -1
- package/lib/models/document.d.ts +2 -2
- package/lib/models/document.js +549 -1
- package/lib/models/graph.js +55 -1
- package/lib/models/group.js +1 -1
- package/lib/models/json-schema.d.ts +1 -1
- package/lib/models/json-schema.js +320 -1
- package/lib/models/optimal-clusters.js +324 -1
- package/lib/models/value.js +16 -1
- package/lib/semantic.js +23 -1
- package/lib/services/graph.d.ts +1 -1
- package/lib/services/graph.js +367 -1
- package/lib/types.d.ts +22 -0
- package/lib/types.js +45 -1
- package/package.json +15 -15
package/lib/services/graph.d.ts
CHANGED
package/lib/services/graph.js
CHANGED
|
@@ -1 +1,367 @@
|
|
|
1
|
-
import{clusterModel
|
|
1
|
+
import { clusterModel } from '../models/cluster.js';
|
|
2
|
+
import { documentModelsRecord } from '../models/document.js';
|
|
3
|
+
import { binaryStringValue, signedJWTStringValue } from '../models/value.js';
|
|
4
|
+
export const searchModelConfig = {
|
|
5
|
+
type: 'object',
|
|
6
|
+
properties: {
|
|
7
|
+
fields: {
|
|
8
|
+
type: 'array',
|
|
9
|
+
items: {
|
|
10
|
+
type: 'string'
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
additionalProperties: false
|
|
15
|
+
};
|
|
16
|
+
export const searchConfig = {
|
|
17
|
+
type: 'object',
|
|
18
|
+
additionalProperties: searchModelConfig
|
|
19
|
+
};
|
|
20
|
+
export const deployGraphParams = {
|
|
21
|
+
type: 'object',
|
|
22
|
+
properties: {
|
|
23
|
+
clusters: {
|
|
24
|
+
type: 'array',
|
|
25
|
+
items: clusterModel
|
|
26
|
+
},
|
|
27
|
+
id: {
|
|
28
|
+
type: 'string'
|
|
29
|
+
},
|
|
30
|
+
name: {
|
|
31
|
+
type: 'string'
|
|
32
|
+
},
|
|
33
|
+
plugins: {
|
|
34
|
+
type: 'object',
|
|
35
|
+
additionalProperties: {
|
|
36
|
+
type: 'object',
|
|
37
|
+
additionalProperties: true
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
search: searchConfig
|
|
41
|
+
},
|
|
42
|
+
required: [
|
|
43
|
+
'clusters'
|
|
44
|
+
],
|
|
45
|
+
additionalProperties: false
|
|
46
|
+
};
|
|
47
|
+
export const deployGraphResult = {
|
|
48
|
+
type: 'object',
|
|
49
|
+
properties: {
|
|
50
|
+
id: {
|
|
51
|
+
type: 'string'
|
|
52
|
+
},
|
|
53
|
+
record: documentModelsRecord,
|
|
54
|
+
aliases: {
|
|
55
|
+
type: 'object',
|
|
56
|
+
additionalProperties: {
|
|
57
|
+
type: 'string'
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
search: searchConfig
|
|
61
|
+
},
|
|
62
|
+
required: [
|
|
63
|
+
'id',
|
|
64
|
+
'record',
|
|
65
|
+
'aliases'
|
|
66
|
+
],
|
|
67
|
+
additionalProperties: false
|
|
68
|
+
};
|
|
69
|
+
export const listGraphResult = {
|
|
70
|
+
type: 'object',
|
|
71
|
+
properties: {
|
|
72
|
+
graphs: {
|
|
73
|
+
type: 'array',
|
|
74
|
+
items: {
|
|
75
|
+
type: 'object',
|
|
76
|
+
properties: {
|
|
77
|
+
id: {
|
|
78
|
+
type: 'string'
|
|
79
|
+
},
|
|
80
|
+
name: {
|
|
81
|
+
type: 'string'
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
required: [
|
|
85
|
+
'id',
|
|
86
|
+
'name'
|
|
87
|
+
],
|
|
88
|
+
additionalProperties: false
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
required: [
|
|
93
|
+
'graphs'
|
|
94
|
+
],
|
|
95
|
+
additionalProperties: false
|
|
96
|
+
};
|
|
97
|
+
export const loadGraphParams = {
|
|
98
|
+
type: 'object',
|
|
99
|
+
properties: {
|
|
100
|
+
id: {
|
|
101
|
+
type: 'string'
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
required: [
|
|
105
|
+
'id'
|
|
106
|
+
],
|
|
107
|
+
additionalProperties: false
|
|
108
|
+
};
|
|
109
|
+
export const loadGraphResult = {
|
|
110
|
+
type: 'object',
|
|
111
|
+
properties: {
|
|
112
|
+
record: documentModelsRecord,
|
|
113
|
+
aliases: {
|
|
114
|
+
type: 'object',
|
|
115
|
+
additionalProperties: {
|
|
116
|
+
type: 'string'
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
extensionSDL: {
|
|
120
|
+
type: 'string'
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
required: [
|
|
124
|
+
'record',
|
|
125
|
+
'aliases'
|
|
126
|
+
],
|
|
127
|
+
additionalProperties: false
|
|
128
|
+
};
|
|
129
|
+
export const executeGraphParams = {
|
|
130
|
+
type: 'object',
|
|
131
|
+
properties: {
|
|
132
|
+
id: {
|
|
133
|
+
type: 'string'
|
|
134
|
+
},
|
|
135
|
+
text: {
|
|
136
|
+
type: 'string'
|
|
137
|
+
},
|
|
138
|
+
variables: {
|
|
139
|
+
type: 'object'
|
|
140
|
+
},
|
|
141
|
+
catalogID: {
|
|
142
|
+
type: 'string'
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
required: [
|
|
146
|
+
'id',
|
|
147
|
+
'text'
|
|
148
|
+
],
|
|
149
|
+
additionalProperties: false
|
|
150
|
+
};
|
|
151
|
+
export const executeGraphError = {
|
|
152
|
+
type: 'object',
|
|
153
|
+
properties: {
|
|
154
|
+
message: {
|
|
155
|
+
type: 'string'
|
|
156
|
+
},
|
|
157
|
+
locations: {
|
|
158
|
+
type: 'array',
|
|
159
|
+
items: {
|
|
160
|
+
type: 'object',
|
|
161
|
+
properties: {
|
|
162
|
+
line: {
|
|
163
|
+
type: 'integer'
|
|
164
|
+
},
|
|
165
|
+
column: {
|
|
166
|
+
type: 'integer'
|
|
167
|
+
}
|
|
168
|
+
},
|
|
169
|
+
required: [
|
|
170
|
+
'line',
|
|
171
|
+
'column'
|
|
172
|
+
],
|
|
173
|
+
additionalProperties: false
|
|
174
|
+
}
|
|
175
|
+
},
|
|
176
|
+
path: {
|
|
177
|
+
type: 'array',
|
|
178
|
+
items: {
|
|
179
|
+
type: 'string'
|
|
180
|
+
}
|
|
181
|
+
},
|
|
182
|
+
extensions: {
|
|
183
|
+
type: 'object'
|
|
184
|
+
}
|
|
185
|
+
},
|
|
186
|
+
required: [
|
|
187
|
+
'message'
|
|
188
|
+
],
|
|
189
|
+
additionalProperties: false
|
|
190
|
+
};
|
|
191
|
+
export const executeGraphResult = {
|
|
192
|
+
type: 'object',
|
|
193
|
+
properties: {
|
|
194
|
+
data: {
|
|
195
|
+
anyOf: [
|
|
196
|
+
{
|
|
197
|
+
type: 'object'
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
type: 'null'
|
|
201
|
+
}
|
|
202
|
+
]
|
|
203
|
+
},
|
|
204
|
+
errors: {
|
|
205
|
+
type: 'array',
|
|
206
|
+
items: executeGraphError
|
|
207
|
+
},
|
|
208
|
+
extensions: {
|
|
209
|
+
type: 'object'
|
|
210
|
+
}
|
|
211
|
+
},
|
|
212
|
+
additionalProperties: false
|
|
213
|
+
};
|
|
214
|
+
export const mutateGraphParams = {
|
|
215
|
+
type: 'object',
|
|
216
|
+
properties: {
|
|
217
|
+
...executeGraphParams.properties,
|
|
218
|
+
mutations: {
|
|
219
|
+
anyOf: [
|
|
220
|
+
{
|
|
221
|
+
type: 'object',
|
|
222
|
+
additionalProperties: signedJWTStringValue
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
type: 'null'
|
|
226
|
+
}
|
|
227
|
+
]
|
|
228
|
+
},
|
|
229
|
+
attachments: {
|
|
230
|
+
type: 'object',
|
|
231
|
+
additionalProperties: binaryStringValue
|
|
232
|
+
},
|
|
233
|
+
transactionID: {
|
|
234
|
+
type: 'string'
|
|
235
|
+
}
|
|
236
|
+
},
|
|
237
|
+
required: [
|
|
238
|
+
...executeGraphParams.required,
|
|
239
|
+
'mutations'
|
|
240
|
+
],
|
|
241
|
+
additionalProperties: false
|
|
242
|
+
};
|
|
243
|
+
export const beginTransactionParams = {
|
|
244
|
+
type: 'object',
|
|
245
|
+
properties: {
|
|
246
|
+
id: {
|
|
247
|
+
type: 'string'
|
|
248
|
+
}
|
|
249
|
+
},
|
|
250
|
+
required: [
|
|
251
|
+
'id'
|
|
252
|
+
],
|
|
253
|
+
additionalProperties: false
|
|
254
|
+
};
|
|
255
|
+
export const beginTransactionResult = {
|
|
256
|
+
type: 'object',
|
|
257
|
+
properties: {
|
|
258
|
+
transactionID: {
|
|
259
|
+
type: 'string'
|
|
260
|
+
}
|
|
261
|
+
},
|
|
262
|
+
required: [
|
|
263
|
+
'transactionID'
|
|
264
|
+
],
|
|
265
|
+
additionalProperties: false
|
|
266
|
+
};
|
|
267
|
+
export const transactionParams = {
|
|
268
|
+
type: 'object',
|
|
269
|
+
properties: {
|
|
270
|
+
transactionID: {
|
|
271
|
+
type: 'string'
|
|
272
|
+
}
|
|
273
|
+
},
|
|
274
|
+
required: [
|
|
275
|
+
'transactionID'
|
|
276
|
+
],
|
|
277
|
+
additionalProperties: false
|
|
278
|
+
};
|
|
279
|
+
export const transactionResult = {
|
|
280
|
+
type: 'object',
|
|
281
|
+
properties: {
|
|
282
|
+
success: {
|
|
283
|
+
type: 'boolean'
|
|
284
|
+
},
|
|
285
|
+
// Populated when `success` is false and the failure carries a recoverable
|
|
286
|
+
// reason the caller can act on — currently access-denied surfaces from the
|
|
287
|
+
// commit-time apply. Generic handler failures still come back via the
|
|
288
|
+
// enkaku error-reply path with code `EK01`.
|
|
289
|
+
error: {
|
|
290
|
+
type: 'object',
|
|
291
|
+
properties: {
|
|
292
|
+
code: {
|
|
293
|
+
type: 'string'
|
|
294
|
+
},
|
|
295
|
+
message: {
|
|
296
|
+
type: 'string'
|
|
297
|
+
},
|
|
298
|
+
docID: {
|
|
299
|
+
type: 'string'
|
|
300
|
+
}
|
|
301
|
+
},
|
|
302
|
+
required: [
|
|
303
|
+
'code',
|
|
304
|
+
'message'
|
|
305
|
+
],
|
|
306
|
+
additionalProperties: false
|
|
307
|
+
}
|
|
308
|
+
},
|
|
309
|
+
required: [
|
|
310
|
+
'success'
|
|
311
|
+
],
|
|
312
|
+
additionalProperties: false
|
|
313
|
+
};
|
|
314
|
+
export const graphProtocol = {
|
|
315
|
+
'graph/deploy': {
|
|
316
|
+
type: 'request',
|
|
317
|
+
param: deployGraphParams,
|
|
318
|
+
result: deployGraphResult
|
|
319
|
+
},
|
|
320
|
+
'graph/list': {
|
|
321
|
+
type: 'request',
|
|
322
|
+
result: listGraphResult
|
|
323
|
+
},
|
|
324
|
+
'graph/load': {
|
|
325
|
+
type: 'request',
|
|
326
|
+
param: loadGraphParams,
|
|
327
|
+
result: loadGraphResult
|
|
328
|
+
},
|
|
329
|
+
'graph/mutate': {
|
|
330
|
+
type: 'request',
|
|
331
|
+
param: mutateGraphParams,
|
|
332
|
+
result: executeGraphResult
|
|
333
|
+
},
|
|
334
|
+
'graph/query': {
|
|
335
|
+
type: 'request',
|
|
336
|
+
param: executeGraphParams,
|
|
337
|
+
result: executeGraphResult
|
|
338
|
+
},
|
|
339
|
+
'graph/subscribe': {
|
|
340
|
+
type: 'stream',
|
|
341
|
+
param: executeGraphParams,
|
|
342
|
+
receive: executeGraphResult,
|
|
343
|
+
result: {
|
|
344
|
+
anyOf: [
|
|
345
|
+
executeGraphResult,
|
|
346
|
+
{
|
|
347
|
+
type: 'null'
|
|
348
|
+
}
|
|
349
|
+
]
|
|
350
|
+
}
|
|
351
|
+
},
|
|
352
|
+
'graph/beginTransaction': {
|
|
353
|
+
type: 'request',
|
|
354
|
+
param: beginTransactionParams,
|
|
355
|
+
result: beginTransactionResult
|
|
356
|
+
},
|
|
357
|
+
'graph/commitTransaction': {
|
|
358
|
+
type: 'request',
|
|
359
|
+
param: transactionParams,
|
|
360
|
+
result: transactionResult
|
|
361
|
+
},
|
|
362
|
+
'graph/rollbackTransaction': {
|
|
363
|
+
type: 'request',
|
|
364
|
+
param: transactionParams,
|
|
365
|
+
result: transactionResult
|
|
366
|
+
}
|
|
367
|
+
};
|
package/lib/types.d.ts
CHANGED
|
@@ -122,6 +122,28 @@ export type GroupedAggregateValue = {
|
|
|
122
122
|
keys: Record<string, unknown>;
|
|
123
123
|
} & AggregateValues;
|
|
124
124
|
export type DocumentData = Record<string, unknown>;
|
|
125
|
+
/**
|
|
126
|
+
* Document fields carried in signed document data and synced, but excluded from
|
|
127
|
+
* model-schema validation. Model schemas are normalized with
|
|
128
|
+
* `additionalProperties: false` and never declare these, so the apply path
|
|
129
|
+
* validates only model-declared fields and preserves reserved fields through
|
|
130
|
+
* patches unchanged.
|
|
131
|
+
*/
|
|
132
|
+
export declare const RESERVED_DOCUMENT_FIELDS: readonly ["accessPermissions"];
|
|
133
|
+
export declare function isAccessLevel(value: unknown): value is AccessLevel;
|
|
134
|
+
export declare function isValidAccessRule(value: unknown): boolean;
|
|
135
|
+
/**
|
|
136
|
+
* True when `value` is a well-formed `accessPermissions` object: an object whose
|
|
137
|
+
* present `read`/`write` entries each carry a known `level` and, when present,
|
|
138
|
+
* `allowedDIDs`/`allowedCircles`/`allowedGroups` that are string arrays (or
|
|
139
|
+
* null). Unknown keys are ignored, mirroring the engine's tolerant parser.
|
|
140
|
+
*
|
|
141
|
+
* This is the shape contract for the reserved `accessPermissions` document
|
|
142
|
+
* field. It is enforced strictly when a mutation is minted (authoring time), so
|
|
143
|
+
* a producer bug is caught at signing rather than persisted as garbage that
|
|
144
|
+
* unguarded consumers (e.g. the SQL read predicate) could mis-read.
|
|
145
|
+
*/
|
|
146
|
+
export declare function isValidAccessPermissions(value: unknown): boolean;
|
|
125
147
|
export type DocumentNode = {
|
|
126
148
|
id: string;
|
|
127
149
|
model: string;
|
package/lib/types.js
CHANGED
|
@@ -1 +1,45 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Document fields carried in signed document data and synced, but excluded from
|
|
3
|
+
* model-schema validation. Model schemas are normalized with
|
|
4
|
+
* `additionalProperties: false` and never declare these, so the apply path
|
|
5
|
+
* validates only model-declared fields and preserves reserved fields through
|
|
6
|
+
* patches unchanged.
|
|
7
|
+
*/ export const RESERVED_DOCUMENT_FIELDS = [
|
|
8
|
+
'accessPermissions'
|
|
9
|
+
];
|
|
10
|
+
export function isAccessLevel(value) {
|
|
11
|
+
return value === 'only_owner' || value === 'anyone' || value === 'restricted';
|
|
12
|
+
}
|
|
13
|
+
function isStringArrayOrNull(value) {
|
|
14
|
+
return value == null || Array.isArray(value) && value.every((item)=>typeof item === 'string');
|
|
15
|
+
}
|
|
16
|
+
export function isValidAccessRule(value) {
|
|
17
|
+
if (value == null || typeof value !== 'object') {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
const rule = value;
|
|
21
|
+
return isAccessLevel(rule.level) && isStringArrayOrNull(rule.allowedDIDs) && isStringArrayOrNull(rule.allowedCircles) && isStringArrayOrNull(rule.allowedGroups);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* True when `value` is a well-formed `accessPermissions` object: an object whose
|
|
25
|
+
* present `read`/`write` entries each carry a known `level` and, when present,
|
|
26
|
+
* `allowedDIDs`/`allowedCircles`/`allowedGroups` that are string arrays (or
|
|
27
|
+
* null). Unknown keys are ignored, mirroring the engine's tolerant parser.
|
|
28
|
+
*
|
|
29
|
+
* This is the shape contract for the reserved `accessPermissions` document
|
|
30
|
+
* field. It is enforced strictly when a mutation is minted (authoring time), so
|
|
31
|
+
* a producer bug is caught at signing rather than persisted as garbage that
|
|
32
|
+
* unguarded consumers (e.g. the SQL read predicate) could mis-read.
|
|
33
|
+
*/ export function isValidAccessPermissions(value) {
|
|
34
|
+
if (value == null || typeof value !== 'object') {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
const perms = value;
|
|
38
|
+
if (perms.read !== undefined && !isValidAccessRule(perms.read)) {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
if (perms.write !== undefined && !isValidAccessRule(perms.write)) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
return true;
|
|
45
|
+
}
|
package/package.json
CHANGED
|
@@ -1,39 +1,39 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kubun/protocol",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"license": "see LICENSE.md",
|
|
3
|
+
"version": "0.12.0",
|
|
5
4
|
"keywords": [],
|
|
5
|
+
"license": "see LICENSE.md",
|
|
6
|
+
"sideEffects": false,
|
|
6
7
|
"type": "module",
|
|
7
|
-
"main": "lib/index.js",
|
|
8
|
-
"types": "lib/index.d.ts",
|
|
9
8
|
"exports": {
|
|
10
9
|
".": "./lib/index.js"
|
|
11
10
|
},
|
|
11
|
+
"main": "lib/index.js",
|
|
12
|
+
"types": "lib/index.d.ts",
|
|
12
13
|
"files": [
|
|
13
14
|
"lib/*",
|
|
14
15
|
"LICENSE.md"
|
|
15
16
|
],
|
|
16
|
-
"sideEffects": false,
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@enkaku/
|
|
19
|
-
"@
|
|
20
|
-
"@
|
|
18
|
+
"@enkaku/protocol": "^0.20.0",
|
|
19
|
+
"@sozai/codec": "^0.4.0",
|
|
20
|
+
"@sozai/schema": "^0.1.1",
|
|
21
21
|
"change-case": "^5.4.4",
|
|
22
|
-
"@kubun/id": "^0.
|
|
23
|
-
"@kubun/logger": "^0.
|
|
22
|
+
"@kubun/id": "^0.12.0",
|
|
23
|
+
"@kubun/logger": "^0.12.0"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
|
-
"graphql": "^16.
|
|
26
|
+
"graphql": "^16.14.2",
|
|
27
27
|
"json-schema-typed": "^8.0.2"
|
|
28
28
|
},
|
|
29
29
|
"scripts": {
|
|
30
|
+
"build": "pnpm run build:clean && pnpm run build:js && pnpm run build:types",
|
|
30
31
|
"build:clean": "del lib",
|
|
31
|
-
"build:js": "swc src -d ./lib --config-file ../../swc.json --strip-leading-paths",
|
|
32
|
+
"build:js": "swc src -d ./lib --config-file ../../node_modules/@kigu/dev/swc.json --strip-leading-paths",
|
|
32
33
|
"build:types": "tsc --emitDeclarationOnly --skipLibCheck",
|
|
33
34
|
"build:types:ci": "tsc --emitDeclarationOnly --declarationMap false",
|
|
34
|
-
"
|
|
35
|
+
"test": "pnpm run test:types && pnpm run test:unit",
|
|
35
36
|
"test:types": "tsc --noEmit -p tsconfig.test.json",
|
|
36
|
-
"test:unit": "vitest run"
|
|
37
|
-
"test": "pnpm run test:types && pnpm run test:unit"
|
|
37
|
+
"test:unit": "vitest run"
|
|
38
38
|
}
|
|
39
39
|
}
|