@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.
@@ -1,4 +1,4 @@
1
- import type { FromSchema } from '@enkaku/schema';
1
+ import type { FromSchema } from '@sozai/schema';
2
2
  export declare const searchModelConfig: {
3
3
  readonly type: "object";
4
4
  readonly properties: {
@@ -1 +1,367 @@
1
- import{clusterModel as e}from"../models/cluster.js";import{documentModelsRecord as t}from"../models/document.js";import{binaryStringValue as r,signedJWTStringValue as a}from"../models/value.js";export const searchModelConfig={type:"object",properties:{fields:{type:"array",items:{type:"string"}}},additionalProperties:!1};export const searchConfig={type:"object",additionalProperties:searchModelConfig};export const deployGraphParams={type:"object",properties:{clusters:{type:"array",items:e},id:{type:"string"},name:{type:"string"},plugins:{type:"object",additionalProperties:{type:"object",additionalProperties:!0}},search:searchConfig},required:["clusters"],additionalProperties:!1};export const deployGraphResult={type:"object",properties:{id:{type:"string"},record:t,aliases:{type:"object",additionalProperties:{type:"string"}},search:searchConfig},required:["id","record","aliases"],additionalProperties:!1};export const listGraphResult={type:"object",properties:{graphs:{type:"array",items:{type:"object",properties:{id:{type:"string"},name:{type:"string"}},required:["id","name"],additionalProperties:!1}}},required:["graphs"],additionalProperties:!1};export const loadGraphParams={type:"object",properties:{id:{type:"string"}},required:["id"],additionalProperties:!1};export const loadGraphResult={type:"object",properties:{record:t,aliases:{type:"object",additionalProperties:{type:"string"}},extensionSDL:{type:"string"}},required:["record","aliases"],additionalProperties:!1};export const executeGraphParams={type:"object",properties:{id:{type:"string"},text:{type:"string"},variables:{type:"object"},catalogID:{type:"string"}},required:["id","text"],additionalProperties:!1};export const executeGraphError={type:"object",properties:{message:{type:"string"},locations:{type:"array",items:{type:"object",properties:{line:{type:"integer"},column:{type:"integer"}},required:["line","column"],additionalProperties:!1}},path:{type:"array",items:{type:"string"}},extensions:{type:"object"}},required:["message"],additionalProperties:!1};export const executeGraphResult={type:"object",properties:{data:{anyOf:[{type:"object"},{type:"null"}]},errors:{type:"array",items:executeGraphError},extensions:{type:"object"}},additionalProperties:!1};export const mutateGraphParams={type:"object",properties:{...executeGraphParams.properties,mutations:{anyOf:[{type:"object",additionalProperties:a},{type:"null"}]},attachments:{type:"object",additionalProperties:r},transactionID:{type:"string"}},required:[...executeGraphParams.required,"mutations"],additionalProperties:!1};export const beginTransactionParams={type:"object",properties:{id:{type:"string"}},required:["id"],additionalProperties:!1};export const beginTransactionResult={type:"object",properties:{transactionID:{type:"string"}},required:["transactionID"],additionalProperties:!1};export const transactionParams={type:"object",properties:{transactionID:{type:"string"}},required:["transactionID"],additionalProperties:!1};export const transactionResult={type:"object",properties:{success:{type:"boolean"},error:{type:"object",properties:{code:{type:"string"},message:{type:"string"},docID:{type:"string"}},required:["code","message"],additionalProperties:!1}},required:["success"],additionalProperties:!1};export const graphProtocol={"graph/deploy":{type:"request",param:deployGraphParams,result:deployGraphResult},"graph/list":{type:"request",result:listGraphResult},"graph/load":{type:"request",param:loadGraphParams,result:loadGraphResult},"graph/mutate":{type:"request",param:mutateGraphParams,result:executeGraphResult},"graph/query":{type:"request",param:executeGraphParams,result:executeGraphResult},"graph/subscribe":{type:"stream",param:executeGraphParams,receive:executeGraphResult,result:{anyOf:[executeGraphResult,{type:"null"}]}},"graph/beginTransaction":{type:"request",param:beginTransactionParams,result:beginTransactionResult},"graph/commitTransaction":{type:"request",param:transactionParams,result:transactionResult},"graph/rollbackTransaction":{type:"request",param:transactionParams,result:transactionResult}};
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
- export{};
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.10.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/codec": "^0.16.0",
19
- "@enkaku/protocol": "^0.16.0",
20
- "@enkaku/schema": "^0.16.0",
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.10.0",
23
- "@kubun/logger": "^0.10.0"
22
+ "@kubun/id": "^0.12.0",
23
+ "@kubun/logger": "^0.12.0"
24
24
  },
25
25
  "devDependencies": {
26
- "graphql": "^16.13.2",
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
- "build": "pnpm run build:clean && pnpm run build:js && pnpm run build:types",
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
  }