@kubun/protocol 0.11.0 → 0.13.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 +14 -0
- package/lib/errors.js +17 -2
- package/lib/index.d.ts +1 -1
- package/lib/index.js +1 -1
- package/lib/models/cluster.d.ts +6 -6
- package/lib/models/document.d.ts +28 -28
- package/lib/models/document.js +55 -4
- package/lib/models/json-schema.d.ts +11 -10
- package/lib/models/json-schema.js +5 -2
- package/lib/services/graph.d.ts +36 -36
- package/lib/types.d.ts +34 -1
- package/lib/types.js +45 -1
- package/package.json +16 -13
package/lib/errors.d.ts
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Every error code kubun may attach to a thrown error. Also the allowlist of
|
|
3
|
+
* codes a handler refusal may carry to a remote caller: an error with no
|
|
4
|
+
* registered code is treated as internal and stays opaque on the wire, so
|
|
5
|
+
* adding a forwardable reason is an edit to this table rather than a decision
|
|
6
|
+
* made at a throw site.
|
|
7
|
+
*/
|
|
1
8
|
export declare const KubunErrorCodes: {
|
|
2
9
|
readonly KB01: "Validation error";
|
|
3
10
|
readonly KB02: "Not found";
|
|
@@ -8,5 +15,12 @@ export declare const KubunErrorCodes: {
|
|
|
8
15
|
readonly KB07: "Access denied";
|
|
9
16
|
readonly KB08: "Sync access denied";
|
|
10
17
|
readonly KB09: "Document ID mismatch";
|
|
18
|
+
readonly KB10: "HLC drift exceeded";
|
|
19
|
+
readonly KB11: "Owner change rejected";
|
|
20
|
+
readonly KB12: "Unsupported mutation type";
|
|
21
|
+
readonly KB13: "Mutation schema validation error";
|
|
22
|
+
readonly KB14: "Group control denied";
|
|
23
|
+
readonly KB15: "Model not deployed";
|
|
11
24
|
};
|
|
12
25
|
export type KubunErrorCode = keyof typeof KubunErrorCodes;
|
|
26
|
+
export declare function isKubunErrorCode(value: unknown): value is KubunErrorCode;
|
package/lib/errors.js
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Every error code kubun may attach to a thrown error. Also the allowlist of
|
|
3
|
+
* codes a handler refusal may carry to a remote caller: an error with no
|
|
4
|
+
* registered code is treated as internal and stays opaque on the wire, so
|
|
5
|
+
* adding a forwardable reason is an edit to this table rather than a decision
|
|
6
|
+
* made at a throw site.
|
|
7
|
+
*/ export const KubunErrorCodes = {
|
|
2
8
|
KB01: 'Validation error',
|
|
3
9
|
KB02: 'Not found',
|
|
4
10
|
KB03: 'Unauthorized',
|
|
@@ -7,5 +13,14 @@ export const KubunErrorCodes = {
|
|
|
7
13
|
KB06: 'Internal error',
|
|
8
14
|
KB07: 'Access denied',
|
|
9
15
|
KB08: 'Sync access denied',
|
|
10
|
-
KB09: 'Document ID mismatch'
|
|
16
|
+
KB09: 'Document ID mismatch',
|
|
17
|
+
KB10: 'HLC drift exceeded',
|
|
18
|
+
KB11: 'Owner change rejected',
|
|
19
|
+
KB12: 'Unsupported mutation type',
|
|
20
|
+
KB13: 'Mutation schema validation error',
|
|
21
|
+
KB14: 'Group control denied',
|
|
22
|
+
KB15: 'Model not deployed'
|
|
11
23
|
};
|
|
24
|
+
export function isKubunErrorCode(value) {
|
|
25
|
+
return typeof value === 'string' && Object.hasOwn(KubunErrorCodes, value);
|
|
26
|
+
}
|
package/lib/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { AnyClientMessageOf, AnyServerMessageOf, ClientTransportOf, ServerTransportOf } from '@enkaku/protocol';
|
|
2
2
|
import type { GraphProtocol } from './services/graph.js';
|
|
3
|
-
export { type KubunErrorCode, KubunErrorCodes } from './errors.js';
|
|
3
|
+
export { isKubunErrorCode, type KubunErrorCode, KubunErrorCodes } from './errors.js';
|
|
4
4
|
export type { GraphQLOperationParams, GraphQLSource, GraphQLSourceParams, GraphQLSourceProvider, GraphsProvider, } from './executor.js';
|
|
5
5
|
export * from './models/catalog.js';
|
|
6
6
|
export * from './models/cluster.js';
|
package/lib/index.js
CHANGED
package/lib/models/cluster.d.ts
CHANGED
|
@@ -153,12 +153,12 @@ export declare const clusterModel: {
|
|
|
153
153
|
readonly type: "array";
|
|
154
154
|
readonly items: {
|
|
155
155
|
readonly type: "string";
|
|
156
|
-
readonly pattern: "^[A-Z]
|
|
156
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
157
157
|
};
|
|
158
158
|
};
|
|
159
159
|
readonly default: {
|
|
160
160
|
readonly type: "string";
|
|
161
|
-
readonly pattern: "^[A-Z]
|
|
161
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
162
162
|
};
|
|
163
163
|
};
|
|
164
164
|
readonly required: readonly ["type", "title", "enum"];
|
|
@@ -512,12 +512,12 @@ export declare const clusterModel: {
|
|
|
512
512
|
readonly type: "array";
|
|
513
513
|
readonly items: {
|
|
514
514
|
readonly type: "string";
|
|
515
|
-
readonly pattern: "^[A-Z]
|
|
515
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
516
516
|
};
|
|
517
517
|
};
|
|
518
518
|
readonly default: {
|
|
519
519
|
readonly type: "string";
|
|
520
|
-
readonly pattern: "^[A-Z]
|
|
520
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
521
521
|
};
|
|
522
522
|
};
|
|
523
523
|
readonly required: readonly ["type", "title", "enum"];
|
|
@@ -877,12 +877,12 @@ export declare const clusterModel: {
|
|
|
877
877
|
readonly type: "array";
|
|
878
878
|
readonly items: {
|
|
879
879
|
readonly type: "string";
|
|
880
|
-
readonly pattern: "^[A-Z]
|
|
880
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
881
881
|
};
|
|
882
882
|
};
|
|
883
883
|
readonly default: {
|
|
884
884
|
readonly type: "string";
|
|
885
|
-
readonly pattern: "^[A-Z]
|
|
885
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
886
886
|
};
|
|
887
887
|
};
|
|
888
888
|
readonly required: readonly ["type", "title", "enum"];
|
package/lib/models/document.d.ts
CHANGED
|
@@ -277,12 +277,12 @@ export declare const documentModelSchema: {
|
|
|
277
277
|
readonly type: "array";
|
|
278
278
|
readonly items: {
|
|
279
279
|
readonly type: "string";
|
|
280
|
-
readonly pattern: "^[A-Z]
|
|
280
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
281
281
|
};
|
|
282
282
|
};
|
|
283
283
|
readonly default: {
|
|
284
284
|
readonly type: "string";
|
|
285
|
-
readonly pattern: "^[A-Z]
|
|
285
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
286
286
|
};
|
|
287
287
|
};
|
|
288
288
|
readonly required: readonly ["type", "title", "enum"];
|
|
@@ -578,12 +578,12 @@ export declare const documentModelBase: {
|
|
|
578
578
|
readonly type: "array";
|
|
579
579
|
readonly items: {
|
|
580
580
|
readonly type: "string";
|
|
581
|
-
readonly pattern: "^[A-Z]
|
|
581
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
582
582
|
};
|
|
583
583
|
};
|
|
584
584
|
readonly default: {
|
|
585
585
|
readonly type: "string";
|
|
586
|
-
readonly pattern: "^[A-Z]
|
|
586
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
587
587
|
};
|
|
588
588
|
};
|
|
589
589
|
readonly required: readonly ["type", "title", "enum"];
|
|
@@ -938,12 +938,12 @@ export declare const documentModelDefault: {
|
|
|
938
938
|
readonly type: "array";
|
|
939
939
|
readonly items: {
|
|
940
940
|
readonly type: "string";
|
|
941
|
-
readonly pattern: "^[A-Z]
|
|
941
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
942
942
|
};
|
|
943
943
|
};
|
|
944
944
|
readonly default: {
|
|
945
945
|
readonly type: "string";
|
|
946
|
-
readonly pattern: "^[A-Z]
|
|
946
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
947
947
|
};
|
|
948
948
|
};
|
|
949
949
|
readonly required: readonly ["type", "title", "enum"];
|
|
@@ -1298,12 +1298,12 @@ export declare const documentModelInterface: {
|
|
|
1298
1298
|
readonly type: "array";
|
|
1299
1299
|
readonly items: {
|
|
1300
1300
|
readonly type: "string";
|
|
1301
|
-
readonly pattern: "^[A-Z]
|
|
1301
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
1302
1302
|
};
|
|
1303
1303
|
};
|
|
1304
1304
|
readonly default: {
|
|
1305
1305
|
readonly type: "string";
|
|
1306
|
-
readonly pattern: "^[A-Z]
|
|
1306
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
1307
1307
|
};
|
|
1308
1308
|
};
|
|
1309
1309
|
readonly required: readonly ["type", "title", "enum"];
|
|
@@ -1664,12 +1664,12 @@ export declare const documentModelUnique: {
|
|
|
1664
1664
|
readonly type: "array";
|
|
1665
1665
|
readonly items: {
|
|
1666
1666
|
readonly type: "string";
|
|
1667
|
-
readonly pattern: "^[A-Z]
|
|
1667
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
1668
1668
|
};
|
|
1669
1669
|
};
|
|
1670
1670
|
readonly default: {
|
|
1671
1671
|
readonly type: "string";
|
|
1672
|
-
readonly pattern: "^[A-Z]
|
|
1672
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
1673
1673
|
};
|
|
1674
1674
|
};
|
|
1675
1675
|
readonly required: readonly ["type", "title", "enum"];
|
|
@@ -2026,12 +2026,12 @@ export declare const documentModel: {
|
|
|
2026
2026
|
readonly type: "array";
|
|
2027
2027
|
readonly items: {
|
|
2028
2028
|
readonly type: "string";
|
|
2029
|
-
readonly pattern: "^[A-Z]
|
|
2029
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
2030
2030
|
};
|
|
2031
2031
|
};
|
|
2032
2032
|
readonly default: {
|
|
2033
2033
|
readonly type: "string";
|
|
2034
|
-
readonly pattern: "^[A-Z]
|
|
2034
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
2035
2035
|
};
|
|
2036
2036
|
};
|
|
2037
2037
|
readonly required: readonly ["type", "title", "enum"];
|
|
@@ -2385,12 +2385,12 @@ export declare const documentModel: {
|
|
|
2385
2385
|
readonly type: "array";
|
|
2386
2386
|
readonly items: {
|
|
2387
2387
|
readonly type: "string";
|
|
2388
|
-
readonly pattern: "^[A-Z]
|
|
2388
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
2389
2389
|
};
|
|
2390
2390
|
};
|
|
2391
2391
|
readonly default: {
|
|
2392
2392
|
readonly type: "string";
|
|
2393
|
-
readonly pattern: "^[A-Z]
|
|
2393
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
2394
2394
|
};
|
|
2395
2395
|
};
|
|
2396
2396
|
readonly required: readonly ["type", "title", "enum"];
|
|
@@ -2750,12 +2750,12 @@ export declare const documentModel: {
|
|
|
2750
2750
|
readonly type: "array";
|
|
2751
2751
|
readonly items: {
|
|
2752
2752
|
readonly type: "string";
|
|
2753
|
-
readonly pattern: "^[A-Z]
|
|
2753
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
2754
2754
|
};
|
|
2755
2755
|
};
|
|
2756
2756
|
readonly default: {
|
|
2757
2757
|
readonly type: "string";
|
|
2758
|
-
readonly pattern: "^[A-Z]
|
|
2758
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
2759
2759
|
};
|
|
2760
2760
|
};
|
|
2761
2761
|
readonly required: readonly ["type", "title", "enum"];
|
|
@@ -3116,12 +3116,12 @@ export declare const documentModelsCluster: {
|
|
|
3116
3116
|
readonly type: "array";
|
|
3117
3117
|
readonly items: {
|
|
3118
3118
|
readonly type: "string";
|
|
3119
|
-
readonly pattern: "^[A-Z]
|
|
3119
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
3120
3120
|
};
|
|
3121
3121
|
};
|
|
3122
3122
|
readonly default: {
|
|
3123
3123
|
readonly type: "string";
|
|
3124
|
-
readonly pattern: "^[A-Z]
|
|
3124
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
3125
3125
|
};
|
|
3126
3126
|
};
|
|
3127
3127
|
readonly required: readonly ["type", "title", "enum"];
|
|
@@ -3475,12 +3475,12 @@ export declare const documentModelsCluster: {
|
|
|
3475
3475
|
readonly type: "array";
|
|
3476
3476
|
readonly items: {
|
|
3477
3477
|
readonly type: "string";
|
|
3478
|
-
readonly pattern: "^[A-Z]
|
|
3478
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
3479
3479
|
};
|
|
3480
3480
|
};
|
|
3481
3481
|
readonly default: {
|
|
3482
3482
|
readonly type: "string";
|
|
3483
|
-
readonly pattern: "^[A-Z]
|
|
3483
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
3484
3484
|
};
|
|
3485
3485
|
};
|
|
3486
3486
|
readonly required: readonly ["type", "title", "enum"];
|
|
@@ -3840,12 +3840,12 @@ export declare const documentModelsCluster: {
|
|
|
3840
3840
|
readonly type: "array";
|
|
3841
3841
|
readonly items: {
|
|
3842
3842
|
readonly type: "string";
|
|
3843
|
-
readonly pattern: "^[A-Z]
|
|
3843
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
3844
3844
|
};
|
|
3845
3845
|
};
|
|
3846
3846
|
readonly default: {
|
|
3847
3847
|
readonly type: "string";
|
|
3848
|
-
readonly pattern: "^[A-Z]
|
|
3848
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
3849
3849
|
};
|
|
3850
3850
|
};
|
|
3851
3851
|
readonly required: readonly ["type", "title", "enum"];
|
|
@@ -4207,12 +4207,12 @@ export declare const documentModelsRecord: {
|
|
|
4207
4207
|
readonly type: "array";
|
|
4208
4208
|
readonly items: {
|
|
4209
4209
|
readonly type: "string";
|
|
4210
|
-
readonly pattern: "^[A-Z]
|
|
4210
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
4211
4211
|
};
|
|
4212
4212
|
};
|
|
4213
4213
|
readonly default: {
|
|
4214
4214
|
readonly type: "string";
|
|
4215
|
-
readonly pattern: "^[A-Z]
|
|
4215
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
4216
4216
|
};
|
|
4217
4217
|
};
|
|
4218
4218
|
readonly required: readonly ["type", "title", "enum"];
|
|
@@ -4566,12 +4566,12 @@ export declare const documentModelsRecord: {
|
|
|
4566
4566
|
readonly type: "array";
|
|
4567
4567
|
readonly items: {
|
|
4568
4568
|
readonly type: "string";
|
|
4569
|
-
readonly pattern: "^[A-Z]
|
|
4569
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
4570
4570
|
};
|
|
4571
4571
|
};
|
|
4572
4572
|
readonly default: {
|
|
4573
4573
|
readonly type: "string";
|
|
4574
|
-
readonly pattern: "^[A-Z]
|
|
4574
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
4575
4575
|
};
|
|
4576
4576
|
};
|
|
4577
4577
|
readonly required: readonly ["type", "title", "enum"];
|
|
@@ -4931,12 +4931,12 @@ export declare const documentModelsRecord: {
|
|
|
4931
4931
|
readonly type: "array";
|
|
4932
4932
|
readonly items: {
|
|
4933
4933
|
readonly type: "string";
|
|
4934
|
-
readonly pattern: "^[A-Z]
|
|
4934
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
4935
4935
|
};
|
|
4936
4936
|
};
|
|
4937
4937
|
readonly default: {
|
|
4938
4938
|
readonly type: "string";
|
|
4939
|
-
readonly pattern: "^[A-Z]
|
|
4939
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
4940
4940
|
};
|
|
4941
4941
|
};
|
|
4942
4942
|
readonly required: readonly ["type", "title", "enum"];
|
package/lib/models/document.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { DocumentModelID, ScalarModelID, ShapeModelID } from '@kubun/id';
|
|
2
2
|
import { asType, createValidator } from '@sozai/schema';
|
|
3
|
-
import { pascalCase } from 'change-case';
|
|
4
|
-
import { baseObjectModel, nameString, referencesRecordModel } from './json-schema.js';
|
|
3
|
+
import { constantCase, pascalCase } from 'change-case';
|
|
4
|
+
import { baseObjectModel, ENUM_MEMBER_PATTERN, nameString, referencesRecordModel } from './json-schema.js';
|
|
5
5
|
import { binaryStringValue, didStringValue } from './value.js';
|
|
6
6
|
export const documentModelVersion = {
|
|
7
7
|
type: 'string',
|
|
@@ -306,6 +306,9 @@ const JSONObjectSchema = {
|
|
|
306
306
|
additionalProperties: true
|
|
307
307
|
};
|
|
308
308
|
const LOCAL_ID_REGEXP = /^#([0-9]+)$/;
|
|
309
|
+
// Built from the shared pattern source so the in-code gate and json-schema.ts's `enumString`
|
|
310
|
+
// (which validates this normalized output) can never drift apart.
|
|
311
|
+
const ENUM_MEMBER_REGEXP = new RegExp(ENUM_MEMBER_PATTERN);
|
|
309
312
|
// TODO: add fieldsMeta for account and attachment when walking the schema
|
|
310
313
|
export class DocumentModelNormalizer {
|
|
311
314
|
#inputModel;
|
|
@@ -455,7 +458,6 @@ export class DocumentModelNormalizer {
|
|
|
455
458
|
}
|
|
456
459
|
// Handle other JSON Schema references like #/properties/, #/items/, etc.
|
|
457
460
|
const segments = ref.split('/').slice(1);
|
|
458
|
-
// biome-ignore lint/suspicious/noExplicitAny: mixed type
|
|
459
461
|
let current = this.#root;
|
|
460
462
|
for (const segment of segments){
|
|
461
463
|
if (current == null || typeof current !== 'object') {
|
|
@@ -469,11 +471,13 @@ export class DocumentModelNormalizer {
|
|
|
469
471
|
return current;
|
|
470
472
|
}
|
|
471
473
|
#addScalar(fieldKey, schema) {
|
|
472
|
-
const id = ScalarModelID.create(schema);
|
|
473
474
|
let normalizedSchema = schema;
|
|
474
475
|
if (schema.type === 'boolean') {
|
|
475
476
|
const { title: _, ...rest } = schema;
|
|
476
477
|
normalizedSchema = rest;
|
|
478
|
+
} else if (schema.enum != null) {
|
|
479
|
+
// Only string scalars carry `enum` in this system.
|
|
480
|
+
normalizedSchema = this.#normalizeEnumSchema(schema);
|
|
477
481
|
} else if (schema.title != null) {
|
|
478
482
|
const lowerCaseTitle = schema.title.toLowerCase();
|
|
479
483
|
if (lowerCaseTitle === 'attachmentid') {
|
|
@@ -514,9 +518,56 @@ export class DocumentModelNormalizer {
|
|
|
514
518
|
};
|
|
515
519
|
}
|
|
516
520
|
}
|
|
521
|
+
// Hash the normalized schema, not the raw input, so the digest matches what gets stored.
|
|
522
|
+
const id = ScalarModelID.create(normalizedSchema);
|
|
517
523
|
this.#refs[id.toString()] = normalizedSchema;
|
|
518
524
|
return toReference(id);
|
|
519
525
|
}
|
|
526
|
+
#assertValidEnumMember(source, normalized) {
|
|
527
|
+
if (!ENUM_MEMBER_REGEXP.test(normalized)) {
|
|
528
|
+
throw new Error(`Invalid enum member "${source}": normalizes to "${normalized}", which does not match ${ENUM_MEMBER_REGEXP}`);
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
#normalizeEnumSchema(schema) {
|
|
532
|
+
const members = schema.enum;
|
|
533
|
+
// Track every source spelling per normalized token (pre-dedup) so a collision can name both.
|
|
534
|
+
const sourcesByNormalized = new Map();
|
|
535
|
+
for (const member of members){
|
|
536
|
+
const normalized = constantCase(member);
|
|
537
|
+
this.#assertValidEnumMember(member, normalized);
|
|
538
|
+
const sources = sourcesByNormalized.get(normalized);
|
|
539
|
+
if (sources == null) {
|
|
540
|
+
sourcesByNormalized.set(normalized, [
|
|
541
|
+
member
|
|
542
|
+
]);
|
|
543
|
+
} else {
|
|
544
|
+
sources.push(member);
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
for (const [normalized, sources] of sourcesByNormalized){
|
|
548
|
+
if (sources.length > 1) {
|
|
549
|
+
throw new Error(`Enum members ${sources.map((source)=>`"${source}"`).join(' and ')} both normalize to "${normalized}"`);
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
// Sort so the digest doesn't depend on source member order (canonicalStringify preserves
|
|
553
|
+
// array order, so ['A', 'B'] and ['B', 'A'] would otherwise hash differently).
|
|
554
|
+
const sortedMembers = Array.from(sourcesByNormalized.keys()).sort();
|
|
555
|
+
const normalizedSchema = {
|
|
556
|
+
...schema,
|
|
557
|
+
title: schema.title != null ? pascalCase(schema.title) : schema.title,
|
|
558
|
+
enum: sortedMembers
|
|
559
|
+
};
|
|
560
|
+
if (schema.default != null) {
|
|
561
|
+
const source = schema.default;
|
|
562
|
+
const normalizedDefault = constantCase(source);
|
|
563
|
+
this.#assertValidEnumMember(source, normalizedDefault);
|
|
564
|
+
if (!sortedMembers.includes(normalizedDefault)) {
|
|
565
|
+
throw new Error(`Enum default "${source}" normalizes to "${normalizedDefault}", which is not a member of [${sortedMembers.join(', ')}]`);
|
|
566
|
+
}
|
|
567
|
+
normalizedSchema.default = normalizedDefault;
|
|
568
|
+
}
|
|
569
|
+
return normalizedSchema;
|
|
570
|
+
}
|
|
520
571
|
#addShape(schema) {
|
|
521
572
|
const id = ShapeModelID.create(schema);
|
|
522
573
|
this.#refs[id.toString()] = schema;
|
|
@@ -77,6 +77,7 @@ export declare const stringConstModel: {
|
|
|
77
77
|
readonly additionalProperties: false;
|
|
78
78
|
};
|
|
79
79
|
export type StringConstModel = FromSchema<typeof stringConstModel>;
|
|
80
|
+
export declare const ENUM_MEMBER_PATTERN: "^[A-Z][A-Z0-9_]*$";
|
|
80
81
|
export declare const stringEnumModel: {
|
|
81
82
|
readonly type: "object";
|
|
82
83
|
readonly properties: {
|
|
@@ -91,12 +92,12 @@ export declare const stringEnumModel: {
|
|
|
91
92
|
readonly type: "array";
|
|
92
93
|
readonly items: {
|
|
93
94
|
readonly type: "string";
|
|
94
|
-
readonly pattern: "^[A-Z]
|
|
95
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
95
96
|
};
|
|
96
97
|
};
|
|
97
98
|
readonly default: {
|
|
98
99
|
readonly type: "string";
|
|
99
|
-
readonly pattern: "^[A-Z]
|
|
100
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
100
101
|
};
|
|
101
102
|
};
|
|
102
103
|
readonly required: readonly ["type", "title", "enum"];
|
|
@@ -222,12 +223,12 @@ export declare const stringModel: {
|
|
|
222
223
|
readonly type: "array";
|
|
223
224
|
readonly items: {
|
|
224
225
|
readonly type: "string";
|
|
225
|
-
readonly pattern: "^[A-Z]
|
|
226
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
226
227
|
};
|
|
227
228
|
};
|
|
228
229
|
readonly default: {
|
|
229
230
|
readonly type: "string";
|
|
230
|
-
readonly pattern: "^[A-Z]
|
|
231
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
231
232
|
};
|
|
232
233
|
};
|
|
233
234
|
readonly required: readonly ["type", "title", "enum"];
|
|
@@ -372,12 +373,12 @@ export declare const scalarModel: {
|
|
|
372
373
|
readonly type: "array";
|
|
373
374
|
readonly items: {
|
|
374
375
|
readonly type: "string";
|
|
375
|
-
readonly pattern: "^[A-Z]
|
|
376
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
376
377
|
};
|
|
377
378
|
};
|
|
378
379
|
readonly default: {
|
|
379
380
|
readonly type: "string";
|
|
380
|
-
readonly pattern: "^[A-Z]
|
|
381
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
381
382
|
};
|
|
382
383
|
};
|
|
383
384
|
readonly required: readonly ["type", "title", "enum"];
|
|
@@ -765,12 +766,12 @@ export declare const typeModel: {
|
|
|
765
766
|
readonly type: "array";
|
|
766
767
|
readonly items: {
|
|
767
768
|
readonly type: "string";
|
|
768
|
-
readonly pattern: "^[A-Z]
|
|
769
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
769
770
|
};
|
|
770
771
|
};
|
|
771
772
|
readonly default: {
|
|
772
773
|
readonly type: "string";
|
|
773
|
-
readonly pattern: "^[A-Z]
|
|
774
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
774
775
|
};
|
|
775
776
|
};
|
|
776
777
|
readonly required: readonly ["type", "title", "enum"];
|
|
@@ -1012,12 +1013,12 @@ export declare const referencesRecordModel: {
|
|
|
1012
1013
|
readonly type: "array";
|
|
1013
1014
|
readonly items: {
|
|
1014
1015
|
readonly type: "string";
|
|
1015
|
-
readonly pattern: "^[A-Z]
|
|
1016
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
1016
1017
|
};
|
|
1017
1018
|
};
|
|
1018
1019
|
readonly default: {
|
|
1019
1020
|
readonly type: "string";
|
|
1020
|
-
readonly pattern: "^[A-Z]
|
|
1021
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
1021
1022
|
};
|
|
1022
1023
|
};
|
|
1023
1024
|
readonly required: readonly ["type", "title", "enum"];
|
|
@@ -81,10 +81,13 @@ export const stringConstModel = {
|
|
|
81
81
|
],
|
|
82
82
|
additionalProperties: false
|
|
83
83
|
};
|
|
84
|
-
//
|
|
84
|
+
// GraphQL enum value: uppercase start, then uppercase/digit/underscore. Enum members are
|
|
85
|
+
// canonicalized to this form (constantCase) at model-build; the pattern validates that
|
|
86
|
+
// canonical output. Shared with the in-code gate in document.ts so both enforce one rule.
|
|
87
|
+
export const ENUM_MEMBER_PATTERN = '^[A-Z][A-Z0-9_]*$';
|
|
85
88
|
const enumString = {
|
|
86
89
|
type: 'string',
|
|
87
|
-
pattern:
|
|
90
|
+
pattern: ENUM_MEMBER_PATTERN
|
|
88
91
|
};
|
|
89
92
|
export const stringEnumModel = {
|
|
90
93
|
type: 'object',
|
package/lib/services/graph.d.ts
CHANGED
|
@@ -183,12 +183,12 @@ export declare const deployGraphParams: {
|
|
|
183
183
|
readonly type: "array";
|
|
184
184
|
readonly items: {
|
|
185
185
|
readonly type: "string";
|
|
186
|
-
readonly pattern: "^[A-Z]
|
|
186
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
187
187
|
};
|
|
188
188
|
};
|
|
189
189
|
readonly default: {
|
|
190
190
|
readonly type: "string";
|
|
191
|
-
readonly pattern: "^[A-Z]
|
|
191
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
192
192
|
};
|
|
193
193
|
};
|
|
194
194
|
readonly required: readonly ["type", "title", "enum"];
|
|
@@ -542,12 +542,12 @@ export declare const deployGraphParams: {
|
|
|
542
542
|
readonly type: "array";
|
|
543
543
|
readonly items: {
|
|
544
544
|
readonly type: "string";
|
|
545
|
-
readonly pattern: "^[A-Z]
|
|
545
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
546
546
|
};
|
|
547
547
|
};
|
|
548
548
|
readonly default: {
|
|
549
549
|
readonly type: "string";
|
|
550
|
-
readonly pattern: "^[A-Z]
|
|
550
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
551
551
|
};
|
|
552
552
|
};
|
|
553
553
|
readonly required: readonly ["type", "title", "enum"];
|
|
@@ -907,12 +907,12 @@ export declare const deployGraphParams: {
|
|
|
907
907
|
readonly type: "array";
|
|
908
908
|
readonly items: {
|
|
909
909
|
readonly type: "string";
|
|
910
|
-
readonly pattern: "^[A-Z]
|
|
910
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
911
911
|
};
|
|
912
912
|
};
|
|
913
913
|
readonly default: {
|
|
914
914
|
readonly type: "string";
|
|
915
|
-
readonly pattern: "^[A-Z]
|
|
915
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
916
916
|
};
|
|
917
917
|
};
|
|
918
918
|
readonly required: readonly ["type", "title", "enum"];
|
|
@@ -1327,12 +1327,12 @@ export declare const deployGraphResult: {
|
|
|
1327
1327
|
readonly type: "array";
|
|
1328
1328
|
readonly items: {
|
|
1329
1329
|
readonly type: "string";
|
|
1330
|
-
readonly pattern: "^[A-Z]
|
|
1330
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
1331
1331
|
};
|
|
1332
1332
|
};
|
|
1333
1333
|
readonly default: {
|
|
1334
1334
|
readonly type: "string";
|
|
1335
|
-
readonly pattern: "^[A-Z]
|
|
1335
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
1336
1336
|
};
|
|
1337
1337
|
};
|
|
1338
1338
|
readonly required: readonly ["type", "title", "enum"];
|
|
@@ -1686,12 +1686,12 @@ export declare const deployGraphResult: {
|
|
|
1686
1686
|
readonly type: "array";
|
|
1687
1687
|
readonly items: {
|
|
1688
1688
|
readonly type: "string";
|
|
1689
|
-
readonly pattern: "^[A-Z]
|
|
1689
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
1690
1690
|
};
|
|
1691
1691
|
};
|
|
1692
1692
|
readonly default: {
|
|
1693
1693
|
readonly type: "string";
|
|
1694
|
-
readonly pattern: "^[A-Z]
|
|
1694
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
1695
1695
|
};
|
|
1696
1696
|
};
|
|
1697
1697
|
readonly required: readonly ["type", "title", "enum"];
|
|
@@ -2051,12 +2051,12 @@ export declare const deployGraphResult: {
|
|
|
2051
2051
|
readonly type: "array";
|
|
2052
2052
|
readonly items: {
|
|
2053
2053
|
readonly type: "string";
|
|
2054
|
-
readonly pattern: "^[A-Z]
|
|
2054
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
2055
2055
|
};
|
|
2056
2056
|
};
|
|
2057
2057
|
readonly default: {
|
|
2058
2058
|
readonly type: "string";
|
|
2059
|
-
readonly pattern: "^[A-Z]
|
|
2059
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
2060
2060
|
};
|
|
2061
2061
|
};
|
|
2062
2062
|
readonly required: readonly ["type", "title", "enum"];
|
|
@@ -2481,12 +2481,12 @@ export declare const loadGraphResult: {
|
|
|
2481
2481
|
readonly type: "array";
|
|
2482
2482
|
readonly items: {
|
|
2483
2483
|
readonly type: "string";
|
|
2484
|
-
readonly pattern: "^[A-Z]
|
|
2484
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
2485
2485
|
};
|
|
2486
2486
|
};
|
|
2487
2487
|
readonly default: {
|
|
2488
2488
|
readonly type: "string";
|
|
2489
|
-
readonly pattern: "^[A-Z]
|
|
2489
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
2490
2490
|
};
|
|
2491
2491
|
};
|
|
2492
2492
|
readonly required: readonly ["type", "title", "enum"];
|
|
@@ -2840,12 +2840,12 @@ export declare const loadGraphResult: {
|
|
|
2840
2840
|
readonly type: "array";
|
|
2841
2841
|
readonly items: {
|
|
2842
2842
|
readonly type: "string";
|
|
2843
|
-
readonly pattern: "^[A-Z]
|
|
2843
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
2844
2844
|
};
|
|
2845
2845
|
};
|
|
2846
2846
|
readonly default: {
|
|
2847
2847
|
readonly type: "string";
|
|
2848
|
-
readonly pattern: "^[A-Z]
|
|
2848
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
2849
2849
|
};
|
|
2850
2850
|
};
|
|
2851
2851
|
readonly required: readonly ["type", "title", "enum"];
|
|
@@ -3205,12 +3205,12 @@ export declare const loadGraphResult: {
|
|
|
3205
3205
|
readonly type: "array";
|
|
3206
3206
|
readonly items: {
|
|
3207
3207
|
readonly type: "string";
|
|
3208
|
-
readonly pattern: "^[A-Z]
|
|
3208
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
3209
3209
|
};
|
|
3210
3210
|
};
|
|
3211
3211
|
readonly default: {
|
|
3212
3212
|
readonly type: "string";
|
|
3213
|
-
readonly pattern: "^[A-Z]
|
|
3213
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
3214
3214
|
};
|
|
3215
3215
|
};
|
|
3216
3216
|
readonly required: readonly ["type", "title", "enum"];
|
|
@@ -3818,12 +3818,12 @@ export declare const graphProtocol: {
|
|
|
3818
3818
|
readonly type: "array";
|
|
3819
3819
|
readonly items: {
|
|
3820
3820
|
readonly type: "string";
|
|
3821
|
-
readonly pattern: "^[A-Z]
|
|
3821
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
3822
3822
|
};
|
|
3823
3823
|
};
|
|
3824
3824
|
readonly default: {
|
|
3825
3825
|
readonly type: "string";
|
|
3826
|
-
readonly pattern: "^[A-Z]
|
|
3826
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
3827
3827
|
};
|
|
3828
3828
|
};
|
|
3829
3829
|
readonly required: readonly ["type", "title", "enum"];
|
|
@@ -4177,12 +4177,12 @@ export declare const graphProtocol: {
|
|
|
4177
4177
|
readonly type: "array";
|
|
4178
4178
|
readonly items: {
|
|
4179
4179
|
readonly type: "string";
|
|
4180
|
-
readonly pattern: "^[A-Z]
|
|
4180
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
4181
4181
|
};
|
|
4182
4182
|
};
|
|
4183
4183
|
readonly default: {
|
|
4184
4184
|
readonly type: "string";
|
|
4185
|
-
readonly pattern: "^[A-Z]
|
|
4185
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
4186
4186
|
};
|
|
4187
4187
|
};
|
|
4188
4188
|
readonly required: readonly ["type", "title", "enum"];
|
|
@@ -4542,12 +4542,12 @@ export declare const graphProtocol: {
|
|
|
4542
4542
|
readonly type: "array";
|
|
4543
4543
|
readonly items: {
|
|
4544
4544
|
readonly type: "string";
|
|
4545
|
-
readonly pattern: "^[A-Z]
|
|
4545
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
4546
4546
|
};
|
|
4547
4547
|
};
|
|
4548
4548
|
readonly default: {
|
|
4549
4549
|
readonly type: "string";
|
|
4550
|
-
readonly pattern: "^[A-Z]
|
|
4550
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
4551
4551
|
};
|
|
4552
4552
|
};
|
|
4553
4553
|
readonly required: readonly ["type", "title", "enum"];
|
|
@@ -4961,12 +4961,12 @@ export declare const graphProtocol: {
|
|
|
4961
4961
|
readonly type: "array";
|
|
4962
4962
|
readonly items: {
|
|
4963
4963
|
readonly type: "string";
|
|
4964
|
-
readonly pattern: "^[A-Z]
|
|
4964
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
4965
4965
|
};
|
|
4966
4966
|
};
|
|
4967
4967
|
readonly default: {
|
|
4968
4968
|
readonly type: "string";
|
|
4969
|
-
readonly pattern: "^[A-Z]
|
|
4969
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
4970
4970
|
};
|
|
4971
4971
|
};
|
|
4972
4972
|
readonly required: readonly ["type", "title", "enum"];
|
|
@@ -5320,12 +5320,12 @@ export declare const graphProtocol: {
|
|
|
5320
5320
|
readonly type: "array";
|
|
5321
5321
|
readonly items: {
|
|
5322
5322
|
readonly type: "string";
|
|
5323
|
-
readonly pattern: "^[A-Z]
|
|
5323
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
5324
5324
|
};
|
|
5325
5325
|
};
|
|
5326
5326
|
readonly default: {
|
|
5327
5327
|
readonly type: "string";
|
|
5328
|
-
readonly pattern: "^[A-Z]
|
|
5328
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
5329
5329
|
};
|
|
5330
5330
|
};
|
|
5331
5331
|
readonly required: readonly ["type", "title", "enum"];
|
|
@@ -5685,12 +5685,12 @@ export declare const graphProtocol: {
|
|
|
5685
5685
|
readonly type: "array";
|
|
5686
5686
|
readonly items: {
|
|
5687
5687
|
readonly type: "string";
|
|
5688
|
-
readonly pattern: "^[A-Z]
|
|
5688
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
5689
5689
|
};
|
|
5690
5690
|
};
|
|
5691
5691
|
readonly default: {
|
|
5692
5692
|
readonly type: "string";
|
|
5693
|
-
readonly pattern: "^[A-Z]
|
|
5693
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
5694
5694
|
};
|
|
5695
5695
|
};
|
|
5696
5696
|
readonly required: readonly ["type", "title", "enum"];
|
|
@@ -6118,12 +6118,12 @@ export declare const graphProtocol: {
|
|
|
6118
6118
|
readonly type: "array";
|
|
6119
6119
|
readonly items: {
|
|
6120
6120
|
readonly type: "string";
|
|
6121
|
-
readonly pattern: "^[A-Z]
|
|
6121
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
6122
6122
|
};
|
|
6123
6123
|
};
|
|
6124
6124
|
readonly default: {
|
|
6125
6125
|
readonly type: "string";
|
|
6126
|
-
readonly pattern: "^[A-Z]
|
|
6126
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
6127
6127
|
};
|
|
6128
6128
|
};
|
|
6129
6129
|
readonly required: readonly ["type", "title", "enum"];
|
|
@@ -6477,12 +6477,12 @@ export declare const graphProtocol: {
|
|
|
6477
6477
|
readonly type: "array";
|
|
6478
6478
|
readonly items: {
|
|
6479
6479
|
readonly type: "string";
|
|
6480
|
-
readonly pattern: "^[A-Z]
|
|
6480
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
6481
6481
|
};
|
|
6482
6482
|
};
|
|
6483
6483
|
readonly default: {
|
|
6484
6484
|
readonly type: "string";
|
|
6485
|
-
readonly pattern: "^[A-Z]
|
|
6485
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
6486
6486
|
};
|
|
6487
6487
|
};
|
|
6488
6488
|
readonly required: readonly ["type", "title", "enum"];
|
|
@@ -6842,12 +6842,12 @@ export declare const graphProtocol: {
|
|
|
6842
6842
|
readonly type: "array";
|
|
6843
6843
|
readonly items: {
|
|
6844
6844
|
readonly type: "string";
|
|
6845
|
-
readonly pattern: "^[A-Z]
|
|
6845
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
6846
6846
|
};
|
|
6847
6847
|
};
|
|
6848
6848
|
readonly default: {
|
|
6849
6849
|
readonly type: "string";
|
|
6850
|
-
readonly pattern: "^[A-Z]
|
|
6850
|
+
readonly pattern: "^[A-Z][A-Z0-9_]*$";
|
|
6851
6851
|
};
|
|
6852
6852
|
};
|
|
6853
6853
|
readonly required: readonly ["type", "title", "enum"];
|
package/lib/types.d.ts
CHANGED
|
@@ -33,7 +33,18 @@ export type ScalarValueFilter<T = string | number> = {
|
|
|
33
33
|
} | {
|
|
34
34
|
greaterThanOrEqualTo: T;
|
|
35
35
|
};
|
|
36
|
-
export type
|
|
36
|
+
export type StringValueFilter = ScalarValueFilter<string> | {
|
|
37
|
+
contains: string;
|
|
38
|
+
};
|
|
39
|
+
export type ArrayPresence = 'null' | 'nonNull' | 'empty' | 'nonEmpty' | 'nullOrEmpty';
|
|
40
|
+
export type ArrayValueFilter = {
|
|
41
|
+
includesAll: Array<string | number>;
|
|
42
|
+
} | {
|
|
43
|
+
includesAny: Array<string | number>;
|
|
44
|
+
} | {
|
|
45
|
+
presence: ArrayPresence;
|
|
46
|
+
};
|
|
47
|
+
export type AnyValueFilter = BooleanValueFilter | EnumValueFilter | ScalarValueFilter | StringValueFilter | ArrayValueFilter;
|
|
37
48
|
export type ObjectValuesFilter = {
|
|
38
49
|
[key: string]: AnyValueFilter | ObjectValuesFilter;
|
|
39
50
|
};
|
|
@@ -122,6 +133,28 @@ export type GroupedAggregateValue = {
|
|
|
122
133
|
keys: Record<string, unknown>;
|
|
123
134
|
} & AggregateValues;
|
|
124
135
|
export type DocumentData = Record<string, unknown>;
|
|
136
|
+
/**
|
|
137
|
+
* Document fields carried in signed document data and synced, but excluded from
|
|
138
|
+
* model-schema validation. Model schemas are normalized with
|
|
139
|
+
* `additionalProperties: false` and never declare these, so the apply path
|
|
140
|
+
* validates only model-declared fields and preserves reserved fields through
|
|
141
|
+
* patches unchanged.
|
|
142
|
+
*/
|
|
143
|
+
export declare const RESERVED_DOCUMENT_FIELDS: readonly ["accessPermissions"];
|
|
144
|
+
export declare function isAccessLevel(value: unknown): value is AccessLevel;
|
|
145
|
+
export declare function isValidAccessRule(value: unknown): boolean;
|
|
146
|
+
/**
|
|
147
|
+
* True when `value` is a well-formed `accessPermissions` object: an object whose
|
|
148
|
+
* present `read`/`write` entries each carry a known `level` and, when present,
|
|
149
|
+
* `allowedDIDs`/`allowedCircles`/`allowedGroups` that are string arrays (or
|
|
150
|
+
* null). Unknown keys are ignored, mirroring the engine's tolerant parser.
|
|
151
|
+
*
|
|
152
|
+
* This is the shape contract for the reserved `accessPermissions` document
|
|
153
|
+
* field. It is enforced strictly when a mutation is minted (authoring time), so
|
|
154
|
+
* a producer bug is caught at signing rather than persisted as garbage that
|
|
155
|
+
* unguarded consumers (e.g. the SQL read predicate) could mis-read.
|
|
156
|
+
*/
|
|
157
|
+
export declare function isValidAccessPermissions(value: unknown): boolean;
|
|
125
158
|
export type DocumentNode = {
|
|
126
159
|
id: string;
|
|
127
160
|
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,42 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kubun/protocol",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"license": "see LICENSE.md",
|
|
3
|
+
"version": "0.13.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
|
-
"@
|
|
19
|
-
"@
|
|
20
|
-
"@sozai/schema": "^0.1.
|
|
18
|
+
"@enkaku/protocol": "^0.21.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
26
|
"graphql": "^16.14.2",
|
|
27
27
|
"json-schema-typed": "^8.0.2"
|
|
28
28
|
},
|
|
29
|
+
"publishConfig": {
|
|
30
|
+
"access": "public"
|
|
31
|
+
},
|
|
29
32
|
"scripts": {
|
|
33
|
+
"build": "pnpm run build:clean && pnpm run build:js && pnpm run build:types",
|
|
30
34
|
"build:clean": "del lib",
|
|
31
35
|
"build:js": "swc src -d ./lib --config-file ../../node_modules/@kigu/dev/swc.json --strip-leading-paths",
|
|
32
36
|
"build:types": "tsc --emitDeclarationOnly --skipLibCheck",
|
|
33
37
|
"build:types:ci": "tsc --emitDeclarationOnly --declarationMap false",
|
|
34
|
-
"
|
|
38
|
+
"test": "pnpm run test:types && pnpm run test:unit",
|
|
35
39
|
"test:types": "tsc --noEmit -p tsconfig.test.json",
|
|
36
|
-
"test:unit": "vitest run"
|
|
37
|
-
"test": "pnpm run test:types && pnpm run test:unit"
|
|
40
|
+
"test:unit": "vitest run"
|
|
38
41
|
}
|
|
39
42
|
}
|