@haverstack/core 0.7.0 → 0.9.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 +30 -14
- package/dist/access.d.ts +20 -7
- package/dist/access.d.ts.map +1 -1
- package/dist/access.js +37 -16
- package/dist/access.js.map +1 -1
- package/dist/adapter-entry.d.ts +12 -0
- package/dist/adapter-entry.d.ts.map +1 -0
- package/dist/adapter-entry.js +11 -0
- package/dist/adapter-entry.js.map +1 -0
- package/dist/attachment-download.d.ts +75 -0
- package/dist/attachment-download.d.ts.map +1 -0
- package/dist/attachment-download.js +128 -0
- package/dist/attachment-download.js.map +1 -0
- package/dist/auth.d.ts +88 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +145 -0
- package/dist/auth.js.map +1 -0
- package/dist/combine.d.ts.map +1 -1
- package/dist/combine.js +20 -3
- package/dist/combine.js.map +1 -1
- package/dist/did-entry.d.ts +12 -0
- package/dist/did-entry.d.ts.map +1 -0
- package/dist/did-entry.js +16 -0
- package/dist/did-entry.js.map +1 -0
- package/dist/did.d.ts +51 -0
- package/dist/did.d.ts.map +1 -0
- package/dist/did.js +153 -0
- package/dist/did.js.map +1 -0
- package/dist/id.d.ts +18 -6
- package/dist/id.d.ts.map +1 -1
- package/dist/id.js +39 -10
- package/dist/id.js.map +1 -1
- package/dist/index.d.ts +15 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -9
- package/dist/index.js.map +1 -1
- package/dist/merge.d.ts +11 -0
- package/dist/merge.d.ts.map +1 -0
- package/dist/merge.js +38 -0
- package/dist/merge.js.map +1 -0
- package/dist/schema.d.ts +31 -9
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +134 -11
- package/dist/schema.js.map +1 -1
- package/dist/stack.d.ts +748 -152
- package/dist/stack.d.ts.map +1 -1
- package/dist/stack.js +1805 -328
- package/dist/stack.js.map +1 -1
- package/dist/testing.d.ts +84 -23
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +260 -19
- package/dist/testing.js.map +1 -1
- package/dist/types.d.ts +281 -31
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +14 -0
- package/dist/types.js.map +1 -1
- package/dist/validate.d.ts +26 -0
- package/dist/validate.d.ts.map +1 -1
- package/dist/validate.js +51 -1
- package/dist/validate.js.map +1 -1
- package/dist/wire-entry.d.ts +17 -0
- package/dist/wire-entry.d.ts.map +1 -0
- package/dist/wire-entry.js +24 -0
- package/dist/wire-entry.js.map +1 -0
- package/package.json +13 -1
package/dist/index.d.ts
CHANGED
|
@@ -3,19 +3,24 @@
|
|
|
3
3
|
* -------------------------------------------------------
|
|
4
4
|
* Core library for Haverstack — portable personal data stack.
|
|
5
5
|
*
|
|
6
|
-
* Exports the Stack class,
|
|
6
|
+
* Exports the Stack class, the app/plugin-facing data types, and the
|
|
7
|
+
* general-purpose utilities every caller needs. Audience-specific surfaces
|
|
8
|
+
* live behind their own subpaths, which this root does not re-export:
|
|
9
|
+
* ./did — key generation, custody and signing (did:key)
|
|
10
|
+
* ./wire — the auth handshake and attachment-download policy shared
|
|
11
|
+
* by both sides of a client/server connection
|
|
12
|
+
* ./adapter — the interfaces a storage adapter implements
|
|
13
|
+
* ./testing — the in-memory MemoryAdapter for tests
|
|
7
14
|
* Storage adapters are published as separate packages:
|
|
8
15
|
* @haverstack/adapter-sqlite
|
|
9
16
|
*/
|
|
10
|
-
export { Stack, ScopedStack, StackValidationError, StackMigrationError, StackPermissionError, StackNotFoundError, } from './stack.js';
|
|
11
|
-
export type { StackClient, CreateRecordOptions, GetRecordOptions, DeleteRecordOptions, } from './stack.js';
|
|
12
|
-
export {
|
|
13
|
-
export type { AccessMode, RecordResolver } from './access.js';
|
|
14
|
-
export type { RecordId, TypeId, FileId, AttachmentContent, StackRecord, RecordVersion, StackType, TypeSchema, FieldDef, ScalarFieldDef, ArrayFieldDef, ObjectFieldDef, ScalarFieldKind, Association, TagAssociation, AttachmentAssociation, RelationshipAssociation, Permission, StackQuery, RecordFilter, QuerySort, QueryResult, DateRange, Migration, MigrationFn, AdapterCapabilities, StackFeatures, StackRecordAdapter, StackBlobAdapter, StackAdapter, EntityContent, AppContent, GroupContent, GrantAction, GrantContent, ConfigContent, } from './types.js';
|
|
17
|
+
export { Stack, ScopedStack, StackError, StackValidationError, StackMigrationError, StackPermissionError, StackNotFoundError, StackConflictError, StackVersionConflictError, StackQueryError, StackSchemaDriftError, StackPayloadTooLargeError, StackTimeoutError, StackClosedError, } from './stack.js';
|
|
18
|
+
export type { StackErrorCode, StackClient, CreateRecordOptions, StackOptions, GetRecordOptions, DeleteRecordOptions, IfVersionOptions, CollectAttachmentGarbageOptions, CollectAttachmentGarbageResult, } from './stack.js';
|
|
19
|
+
export type { RecordId, TypeId, FileId, EntityId, AttachmentContent, StackRecord, RecordVersion, StackType, TypeSchema, FieldDef, ScalarFieldDef, ArrayFieldDef, ObjectFieldDef, ScalarFieldKind, Association, TagAssociation, AttachmentAssociation, RelationshipAssociation, Permission, StackQuery, RecordFilter, QuerySort, QueryResult, DateRange, Migration, MigrationFn, StackAdapter, StackFeatures, TokenSession, EntityContent, AppContent, GroupContent, GrantAction, GrantContent, ConfigContent, } from './types.js';
|
|
15
20
|
export { SYSTEM_TYPES } from './types.js';
|
|
16
|
-
export {
|
|
17
|
-
export {
|
|
18
|
-
export {
|
|
19
|
-
export { validateContent, isValid } from './validate.js';
|
|
21
|
+
export { generateId } from './id.js';
|
|
22
|
+
export { hashSchema, isCompatible } from './schema.js';
|
|
23
|
+
export type { SchemaDriftViolation } from './schema.js';
|
|
20
24
|
export type { ValidationError } from './validate.js';
|
|
25
|
+
export { applyMergePatch } from './merge.js';
|
|
21
26
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,EACL,KAAK,EACL,WAAW,EACX,UAAU,EACV,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,kBAAkB,EAClB,yBAAyB,EACzB,eAAe,EACf,qBAAqB,EACrB,yBAAyB,EACzB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,YAAY,CAAC;AACpB,YAAY,EACV,cAAc,EACd,WAAW,EACX,mBAAmB,EACnB,YAAY,EACZ,gBAAgB,EAChB,mBAAmB,EACnB,gBAAgB,EAChB,+BAA+B,EAC/B,8BAA8B,GAC/B,MAAM,YAAY,CAAC;AAGpB,YAAY,EACV,QAAQ,EACR,MAAM,EACN,MAAM,EACN,QAAQ,EACR,iBAAiB,EACjB,WAAW,EACX,aAAa,EACb,SAAS,EACT,UAAU,EACV,QAAQ,EACR,cAAc,EACd,aAAa,EACb,cAAc,EACd,eAAe,EACf,WAAW,EACX,cAAc,EACd,qBAAqB,EACrB,uBAAuB,EACvB,UAAU,EACV,UAAU,EACV,YAAY,EACZ,SAAS,EACT,WAAW,EACX,SAAS,EACT,SAAS,EACT,WAAW,EACX,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,aAAa,EACb,UAAU,EACV,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,aAAa,GACd,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAM1C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACvD,YAAY,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACxD,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -3,19 +3,24 @@
|
|
|
3
3
|
* -------------------------------------------------------
|
|
4
4
|
* Core library for Haverstack — portable personal data stack.
|
|
5
5
|
*
|
|
6
|
-
* Exports the Stack class,
|
|
6
|
+
* Exports the Stack class, the app/plugin-facing data types, and the
|
|
7
|
+
* general-purpose utilities every caller needs. Audience-specific surfaces
|
|
8
|
+
* live behind their own subpaths, which this root does not re-export:
|
|
9
|
+
* ./did — key generation, custody and signing (did:key)
|
|
10
|
+
* ./wire — the auth handshake and attachment-download policy shared
|
|
11
|
+
* by both sides of a client/server connection
|
|
12
|
+
* ./adapter — the interfaces a storage adapter implements
|
|
13
|
+
* ./testing — the in-memory MemoryAdapter for tests
|
|
7
14
|
* Storage adapters are published as separate packages:
|
|
8
15
|
* @haverstack/adapter-sqlite
|
|
9
16
|
*/
|
|
10
17
|
// Core class and client interface
|
|
11
|
-
export { Stack, ScopedStack, StackValidationError, StackMigrationError, StackPermissionError, StackNotFoundError, } from './stack.js';
|
|
12
|
-
// Permissions
|
|
13
|
-
export { checkAccess } from './access.js';
|
|
18
|
+
export { Stack, ScopedStack, StackError, StackValidationError, StackMigrationError, StackPermissionError, StackNotFoundError, StackConflictError, StackVersionConflictError, StackQueryError, StackSchemaDriftError, StackPayloadTooLargeError, StackTimeoutError, StackClosedError, } from './stack.js';
|
|
14
19
|
export { SYSTEM_TYPES } from './types.js';
|
|
15
|
-
// Adapter composition
|
|
16
|
-
export { combineAdapters } from './combine.js';
|
|
17
20
|
// Utilities
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
export {
|
|
21
|
+
// No in-repo caller: client-minted IDs are the default per spec, and an app
|
|
22
|
+
// needing the ID before the write round-trips has to mint one itself.
|
|
23
|
+
export { generateId } from './id.js';
|
|
24
|
+
export { hashSchema, isCompatible } from './schema.js';
|
|
25
|
+
export { applyMergePatch } from './merge.js';
|
|
21
26
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,kCAAkC;AAClC,OAAO,EACL,KAAK,EACL,WAAW,EACX,UAAU,EACV,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,kBAAkB,EAClB,yBAAyB,EACzB,eAAe,EACf,qBAAqB,EACrB,yBAAyB,EACzB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,YAAY,CAAC;AAoDpB,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,YAAY;AAEZ,4EAA4E;AAC5E,sEAAsE;AACtE,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGvD,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/merge.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stack — RFC 7396 JSON Merge Patch
|
|
3
|
+
* -------------------------------------------------------
|
|
4
|
+
* Shallow merge-patch semantics for record content: a field set to `null`
|
|
5
|
+
* removes it, any other value replaces it, and omitted fields are retained.
|
|
6
|
+
* Shared by Stack.update() (for client-side validation) and every
|
|
7
|
+
* StackRecordAdapter's patchContent() implementation, so a patch produces
|
|
8
|
+
* the same merged content everywhere it's applied.
|
|
9
|
+
*/
|
|
10
|
+
export declare function applyMergePatch(content: Record<string, unknown>, patch: Record<string, unknown | null>): Record<string, unknown>;
|
|
11
|
+
//# sourceMappingURL=merge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../src/merge.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC,GACpC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA0BzB"}
|
package/dist/merge.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stack — RFC 7396 JSON Merge Patch
|
|
3
|
+
* -------------------------------------------------------
|
|
4
|
+
* Shallow merge-patch semantics for record content: a field set to `null`
|
|
5
|
+
* removes it, any other value replaces it, and omitted fields are retained.
|
|
6
|
+
* Shared by Stack.update() (for client-side validation) and every
|
|
7
|
+
* StackRecordAdapter's patchContent() implementation, so a patch produces
|
|
8
|
+
* the same merged content everywhere it's applied.
|
|
9
|
+
*/
|
|
10
|
+
export function applyMergePatch(content, patch) {
|
|
11
|
+
const merged = { ...content };
|
|
12
|
+
for (const [key, value] of Object.entries(patch)) {
|
|
13
|
+
if (value === null) {
|
|
14
|
+
delete merged[key];
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
// defineProperty, not `merged[key] = value`: assignment goes through
|
|
18
|
+
// [[Set]], so a patch key of `__proto__` would invoke the prototype
|
|
19
|
+
// setter and reassign the object's prototype instead of setting a
|
|
20
|
+
// field — silently losing the write. defineProperty creates an own
|
|
21
|
+
// data property for any key, which is also what JSON.parse does when
|
|
22
|
+
// the same key is read back, so both write paths agree. The spread
|
|
23
|
+
// above is already safe (it copies data properties directly).
|
|
24
|
+
//
|
|
25
|
+
// Stack.create()/update() reject the reserved keys outright (see
|
|
26
|
+
// validateReservedKeys); this is the backstop for adapters that call
|
|
27
|
+
// this directly, and for the day someone deepens the merge.
|
|
28
|
+
Object.defineProperty(merged, key, {
|
|
29
|
+
value,
|
|
30
|
+
writable: true,
|
|
31
|
+
enumerable: true,
|
|
32
|
+
configurable: true,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return merged;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=merge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merge.js","sourceRoot":"","sources":["../src/merge.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,UAAU,eAAe,CAC7B,OAAgC,EAChC,KAAqC;IAErC,MAAM,MAAM,GAA4B,EAAE,GAAG,OAAO,EAAE,CAAC;IACvD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACjD,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACnB,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC;aAAM,CAAC;YACN,qEAAqE;YACrE,oEAAoE;YACpE,kEAAkE;YAClE,mEAAmE;YACnE,qEAAqE;YACrE,mEAAmE;YACnE,8DAA8D;YAC9D,EAAE;YACF,iEAAiE;YACjE,qEAAqE;YACrE,4DAA4D;YAC5D,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,GAAG,EAAE;gBACjC,KAAK;gBACL,QAAQ,EAAE,IAAI;gBACd,UAAU,EAAE,IAAI;gBAChB,YAAY,EAAE,IAAI;aACnB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
package/dist/schema.d.ts
CHANGED
|
@@ -16,17 +16,25 @@ import type { TypeSchema } from './types.js';
|
|
|
16
16
|
*/
|
|
17
17
|
export declare const hashSchema: (schema: TypeSchema) => Promise<string>;
|
|
18
18
|
/**
|
|
19
|
-
* Check whether a candidate schema
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* shallowly — only the top-level kind is checked.
|
|
25
|
-
*
|
|
26
|
-
* Apps that need precise type matching should compare typeIds directly.
|
|
27
|
-
* isCompatible() is for duck-typed consumption across types.
|
|
19
|
+
* Check whether a candidate schema is read-compatible with a required
|
|
20
|
+
* schema — licensing duck-typed *consumption* of records, not writing
|
|
21
|
+
* them. Every required field must be declared required at a
|
|
22
|
+
* read-compatible kind; array/object fields recurse. See
|
|
23
|
+
* docs/spec/data-model.md § Type compatibility.
|
|
28
24
|
*/
|
|
29
25
|
export declare const isCompatible: (candidateSchema: TypeSchema, requiredSchema: TypeSchema) => boolean;
|
|
26
|
+
export type SchemaDriftViolation = {
|
|
27
|
+
/** Field path where the drift was detected, e.g. "title" or "author.name". Empty string means array-item context. */
|
|
28
|
+
path: string;
|
|
29
|
+
message: string;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Check whether `candidate` is a legal in-place evolution of `stored`:
|
|
33
|
+
* every existing field unchanged (recursively) and every added field
|
|
34
|
+
* optional. Returns the list of violations; empty means legal. See
|
|
35
|
+
* docs/spec/data-model.md § Schema drift detection.
|
|
36
|
+
*/
|
|
37
|
+
export declare const diffSchemas: (stored: TypeSchema, candidate: TypeSchema) => SchemaDriftViolation[];
|
|
30
38
|
/**
|
|
31
39
|
* Parse a versioned TypeId into its base and version components.
|
|
32
40
|
* e.g. "com.example.myapp/note@2" → { baseId: "com.example.myapp/note", version: 2 }
|
|
@@ -41,4 +49,18 @@ export declare const parseTypeId: (typeId: string) => {
|
|
|
41
49
|
* e.g. ("com.example.myapp/note", 2) → "com.example.myapp/note@2"
|
|
42
50
|
*/
|
|
43
51
|
export declare const buildTypeId: (baseId: string, version: number) => string;
|
|
52
|
+
/**
|
|
53
|
+
* Extract the base (family) ID from a TypeId, tolerating an already-bare
|
|
54
|
+
* baseId (no "@n" suffix) as a no-op. Used to compare across versions —
|
|
55
|
+
* e.g. a grant on "comment@1" and a record at "comment@2" share a baseId.
|
|
56
|
+
*/
|
|
57
|
+
export declare const baseIdOf: (typeId: string) => string;
|
|
58
|
+
/**
|
|
59
|
+
* True if typeId is well-formed as either a bare baseId (no version
|
|
60
|
+
* suffix) or a versioned TypeId ("baseId@version") — the shape
|
|
61
|
+
* GrantContent.typeId accepts, the same tolerance baseIdOf() applies.
|
|
62
|
+
* Not used by defineType(), which requires a version and needs the parsed
|
|
63
|
+
* {baseId, version} itself — it calls parseTypeId() directly instead.
|
|
64
|
+
*/
|
|
65
|
+
export declare const isWellFormedTypeId: (typeId: string) => boolean;
|
|
44
66
|
//# sourceMappingURL=schema.d.ts.map
|
package/dist/schema.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,UAAU,EAA6B,MAAM,YAAY,CAAC;AA8CxE;;;;GAIG;AACH,eAAO,MAAM,UAAU,GAAU,QAAQ,UAAU,KAAG,OAAO,CAAC,MAAM,CAMnE,CAAC;AA8DF;;;;;;GAMG;AACH,eAAO,MAAM,YAAY,GAAI,iBAAiB,UAAU,EAAE,gBAAgB,UAAU,KAAG,OAC9B,CAAC;AAU1D,MAAM,MAAM,oBAAoB,GAAG;IACjC,qHAAqH;IACrH,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAyEF;;;;;GAKG;AACH,eAAO,MAAM,WAAW,GAAI,QAAQ,UAAU,EAAE,WAAW,UAAU,KAAG,oBAAoB,EAI3F,CAAC;AAMF;;;;GAIG;AACH,eAAO,MAAM,WAAW,GAAI,QAAQ,MAAM,KAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,IAIlF,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,WAAW,GAAI,QAAQ,MAAM,EAAE,SAAS,MAAM,KAAG,MAAgC,CAAC;AAE/F;;;;GAIG;AACH,eAAO,MAAM,QAAQ,GAAI,QAAQ,MAAM,KAAG,MAA+C,CAAC;AAE1F;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,GAAI,QAAQ,MAAM,KAAG,OAGnD,CAAC"}
|
package/dist/schema.js
CHANGED
|
@@ -60,24 +60,129 @@ export const hashSchema = async (schema) => {
|
|
|
60
60
|
// Type compatibility
|
|
61
61
|
// -------------------------------------------------------
|
|
62
62
|
/**
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
* the required schema with matching kinds. Optional fields in the
|
|
67
|
-
* required schema are ignored. Array and object fields are matched
|
|
68
|
-
* shallowly — only the top-level kind is checked.
|
|
69
|
-
*
|
|
70
|
-
* Apps that need precise type matching should compare typeIds directly.
|
|
71
|
-
* isCompatible() is for duck-typed consumption across types.
|
|
63
|
+
* Kinds acceptable in a candidate field, per required kind. `string` and
|
|
64
|
+
* `text` are mutually acceptable for reading; everything else requires an
|
|
65
|
+
* exact match. See docs/spec/data-model.md § Type compatibility.
|
|
72
66
|
*/
|
|
73
|
-
|
|
67
|
+
const READ_COMPATIBLE = {
|
|
68
|
+
string: ['string', 'text'],
|
|
69
|
+
text: ['text', 'string'],
|
|
70
|
+
number: ['number'],
|
|
71
|
+
boolean: ['boolean'],
|
|
72
|
+
date: ['date'],
|
|
73
|
+
'record-ref': ['record-ref'],
|
|
74
|
+
'file-ref': ['file-ref'],
|
|
75
|
+
};
|
|
76
|
+
// Candidate schemas can come from another app's Type definition (the
|
|
77
|
+
// untrusted side of duck-typed consumption), so recursion into array
|
|
78
|
+
// items / object properties is depth-bounded — matches MAX_VALIDATION_DEPTH
|
|
79
|
+
// in validate.ts. Past the limit we can't verify compatibility, so we
|
|
80
|
+
// fail closed (treat as incompatible) rather than risk a stack overflow.
|
|
81
|
+
const MAX_COMPATIBILITY_DEPTH = 32;
|
|
82
|
+
/**
|
|
83
|
+
* Check whether a candidate field satisfies a required field, recursing
|
|
84
|
+
* into array items and object properties.
|
|
85
|
+
*/
|
|
86
|
+
const isFieldCompatible = (candidate, required, depth) => {
|
|
87
|
+
if (depth > MAX_COMPATIBILITY_DEPTH)
|
|
88
|
+
return false;
|
|
89
|
+
if (required.kind === 'array') {
|
|
90
|
+
return (candidate.kind === 'array' && isFieldCompatible(candidate.items, required.items, depth + 1));
|
|
91
|
+
}
|
|
92
|
+
if (required.kind === 'object') {
|
|
93
|
+
return (candidate.kind === 'object' &&
|
|
94
|
+
isCompatibleAtDepth(candidate.properties, required.properties, depth + 1));
|
|
95
|
+
}
|
|
96
|
+
if (candidate.kind === 'array' || candidate.kind === 'object')
|
|
97
|
+
return false;
|
|
98
|
+
return READ_COMPATIBLE[required.kind].includes(candidate.kind);
|
|
99
|
+
};
|
|
100
|
+
const isCompatibleAtDepth = (candidateSchema, requiredSchema, depth) => {
|
|
101
|
+
if (depth > MAX_COMPATIBILITY_DEPTH)
|
|
102
|
+
return false;
|
|
74
103
|
return Object.entries(requiredSchema).every(([key, def]) => {
|
|
75
104
|
if (!def.required)
|
|
76
105
|
return true;
|
|
77
106
|
const field = candidateSchema[key];
|
|
78
|
-
return field !== undefined && field.
|
|
107
|
+
return field !== undefined && field.required === true && isFieldCompatible(field, def, depth);
|
|
79
108
|
});
|
|
80
109
|
};
|
|
110
|
+
/**
|
|
111
|
+
* Check whether a candidate schema is read-compatible with a required
|
|
112
|
+
* schema — licensing duck-typed *consumption* of records, not writing
|
|
113
|
+
* them. Every required field must be declared required at a
|
|
114
|
+
* read-compatible kind; array/object fields recurse. See
|
|
115
|
+
* docs/spec/data-model.md § Type compatibility.
|
|
116
|
+
*/
|
|
117
|
+
export const isCompatible = (candidateSchema, requiredSchema) => isCompatibleAtDepth(candidateSchema, requiredSchema, 0);
|
|
118
|
+
// Same rationale and bound as MAX_COMPATIBILITY_DEPTH: a pathological or
|
|
119
|
+
// circular schema shouldn't be walked forever. Past the limit we can't
|
|
120
|
+
// verify the change is additive, so we fail closed — report it as drift
|
|
121
|
+
// rather than silently accept.
|
|
122
|
+
const MAX_DIFF_DEPTH = 32;
|
|
123
|
+
const diffField = (path, stored, candidate, depth, violations) => {
|
|
124
|
+
if (depth > MAX_DIFF_DEPTH) {
|
|
125
|
+
violations.push({ path, message: 'exceeds max nesting depth; cannot verify additive change' });
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
if (stored.kind !== candidate.kind) {
|
|
129
|
+
violations.push({
|
|
130
|
+
path,
|
|
131
|
+
message: `kind changed from "${stored.kind}" to "${candidate.kind}"`,
|
|
132
|
+
});
|
|
133
|
+
return; // kinds differ — nested comparison (properties/items) is meaningless
|
|
134
|
+
}
|
|
135
|
+
if (!!stored.required !== !!candidate.required) {
|
|
136
|
+
violations.push({
|
|
137
|
+
path,
|
|
138
|
+
message: `required changed from ${!!stored.required} to ${!!candidate.required}`,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
if (stored.kind === 'array' && candidate.kind === 'array') {
|
|
142
|
+
diffField(`${path}[]`, stored.items, candidate.items, depth + 1, violations);
|
|
143
|
+
}
|
|
144
|
+
if (stored.kind === 'object' && candidate.kind === 'object') {
|
|
145
|
+
diffFields(path, stored.properties, candidate.properties, depth + 1, violations);
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
const diffFields = (prefix, stored, candidate, depth, violations) => {
|
|
149
|
+
if (depth > MAX_DIFF_DEPTH) {
|
|
150
|
+
violations.push({
|
|
151
|
+
path: prefix,
|
|
152
|
+
message: 'exceeds max nesting depth; cannot verify additive change',
|
|
153
|
+
});
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
for (const [key, storedDef] of Object.entries(stored)) {
|
|
157
|
+
const path = prefix ? `${prefix}.${key}` : key;
|
|
158
|
+
const candidateDef = candidate[key];
|
|
159
|
+
if (!candidateDef) {
|
|
160
|
+
violations.push({ path, message: 'field removed' });
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
diffField(path, storedDef, candidateDef, depth, violations);
|
|
164
|
+
}
|
|
165
|
+
for (const [key, candidateDef] of Object.entries(candidate)) {
|
|
166
|
+
if (key in stored)
|
|
167
|
+
continue; // already compared above
|
|
168
|
+
if (candidateDef.required) {
|
|
169
|
+
const path = prefix ? `${prefix}.${key}` : key;
|
|
170
|
+
violations.push({ path, message: 'new field is required; new fields must be optional' });
|
|
171
|
+
}
|
|
172
|
+
// A new optional field is exactly what additive evolution allows — no violation.
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
/**
|
|
176
|
+
* Check whether `candidate` is a legal in-place evolution of `stored`:
|
|
177
|
+
* every existing field unchanged (recursively) and every added field
|
|
178
|
+
* optional. Returns the list of violations; empty means legal. See
|
|
179
|
+
* docs/spec/data-model.md § Schema drift detection.
|
|
180
|
+
*/
|
|
181
|
+
export const diffSchemas = (stored, candidate) => {
|
|
182
|
+
const violations = [];
|
|
183
|
+
diffFields('', stored, candidate, 0, violations);
|
|
184
|
+
return violations;
|
|
185
|
+
};
|
|
81
186
|
// -------------------------------------------------------
|
|
82
187
|
// Type ID parsing
|
|
83
188
|
// -------------------------------------------------------
|
|
@@ -97,4 +202,22 @@ export const parseTypeId = (typeId) => {
|
|
|
97
202
|
* e.g. ("com.example.myapp/note", 2) → "com.example.myapp/note@2"
|
|
98
203
|
*/
|
|
99
204
|
export const buildTypeId = (baseId, version) => `${baseId}@${version}`;
|
|
205
|
+
/**
|
|
206
|
+
* Extract the base (family) ID from a TypeId, tolerating an already-bare
|
|
207
|
+
* baseId (no "@n" suffix) as a no-op. Used to compare across versions —
|
|
208
|
+
* e.g. a grant on "comment@1" and a record at "comment@2" share a baseId.
|
|
209
|
+
*/
|
|
210
|
+
export const baseIdOf = (typeId) => parseTypeId(typeId)?.baseId ?? typeId;
|
|
211
|
+
/**
|
|
212
|
+
* True if typeId is well-formed as either a bare baseId (no version
|
|
213
|
+
* suffix) or a versioned TypeId ("baseId@version") — the shape
|
|
214
|
+
* GrantContent.typeId accepts, the same tolerance baseIdOf() applies.
|
|
215
|
+
* Not used by defineType(), which requires a version and needs the parsed
|
|
216
|
+
* {baseId, version} itself — it calls parseTypeId() directly instead.
|
|
217
|
+
*/
|
|
218
|
+
export const isWellFormedTypeId = (typeId) => {
|
|
219
|
+
if (typeof typeId !== 'string' || typeId.trim().length === 0)
|
|
220
|
+
return false;
|
|
221
|
+
return !typeId.includes('@') || parseTypeId(typeId) !== null;
|
|
222
|
+
};
|
|
100
223
|
//# sourceMappingURL=schema.js.map
|
package/dist/schema.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,0DAA0D;AAC1D,iCAAiC;AACjC,0DAA0D;AAE1D;;;GAGG;AACH,MAAM,oBAAoB,GAAG,CAAC,GAAa,EAAW,EAAE;IACtD,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QACzB,OAAO;YACL,KAAK,EAAE,oBAAoB,CAAC,GAAG,CAAC,KAAK,CAAC;YACtC,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,GAAG,CAAC,GAAG,CAAC,QAAQ,KAAK,SAAS,IAAI,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC;SAC9D,CAAC;IACJ,CAAC;IAED,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC1B,OAAO;YACL,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,UAAU,EAAE,kBAAkB,CAAC,GAAG,CAAC,UAAU,CAAC;YAC9C,GAAG,CAAC,GAAG,CAAC,QAAQ,KAAK,SAAS,IAAI,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC;SAC9D,CAAC;IACJ,CAAC;IAED,SAAS;IACT,OAAO;QACL,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,GAAG,CAAC,GAAG,CAAC,QAAQ,KAAK,SAAS,IAAI,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC;KAC9D,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,kBAAkB,GAAG,CAAC,MAAkB,EAAW,EAAE;IACzD,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;SAChB,IAAI,EAAE;SACN,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,oBAAoB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAC1D,CAAC;AACJ,CAAC,CAAC;AAEF,0DAA0D;AAC1D,UAAU;AACV,0DAA0D;AAE1D;;;;GAIG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,KAAK,EAAE,MAAkB,EAAmB,EAAE;IACtE,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC;IAC7D,MAAM,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACnD,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IACjE,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC;IACzD,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACxE,CAAC,CAAC;AAEF,0DAA0D;AAC1D,qBAAqB;AACrB,0DAA0D;AAE1D
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,0DAA0D;AAC1D,iCAAiC;AACjC,0DAA0D;AAE1D;;;GAGG;AACH,MAAM,oBAAoB,GAAG,CAAC,GAAa,EAAW,EAAE;IACtD,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QACzB,OAAO;YACL,KAAK,EAAE,oBAAoB,CAAC,GAAG,CAAC,KAAK,CAAC;YACtC,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,GAAG,CAAC,GAAG,CAAC,QAAQ,KAAK,SAAS,IAAI,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC;SAC9D,CAAC;IACJ,CAAC;IAED,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC1B,OAAO;YACL,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,UAAU,EAAE,kBAAkB,CAAC,GAAG,CAAC,UAAU,CAAC;YAC9C,GAAG,CAAC,GAAG,CAAC,QAAQ,KAAK,SAAS,IAAI,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC;SAC9D,CAAC;IACJ,CAAC;IAED,SAAS;IACT,OAAO;QACL,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,GAAG,CAAC,GAAG,CAAC,QAAQ,KAAK,SAAS,IAAI,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC;KAC9D,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,kBAAkB,GAAG,CAAC,MAAkB,EAAW,EAAE;IACzD,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;SAChB,IAAI,EAAE;SACN,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,oBAAoB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAC1D,CAAC;AACJ,CAAC,CAAC;AAEF,0DAA0D;AAC1D,UAAU;AACV,0DAA0D;AAE1D;;;;GAIG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,KAAK,EAAE,MAAkB,EAAmB,EAAE;IACtE,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC;IAC7D,MAAM,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACnD,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IACjE,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC;IACzD,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACxE,CAAC,CAAC;AAEF,0DAA0D;AAC1D,qBAAqB;AACrB,0DAA0D;AAE1D;;;;GAIG;AACH,MAAM,eAAe,GAA+C;IAClE,MAAM,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,IAAI,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC;IACxB,MAAM,EAAE,CAAC,QAAQ,CAAC;IAClB,OAAO,EAAE,CAAC,SAAS,CAAC;IACpB,IAAI,EAAE,CAAC,MAAM,CAAC;IACd,YAAY,EAAE,CAAC,YAAY,CAAC;IAC5B,UAAU,EAAE,CAAC,UAAU,CAAC;CACzB,CAAC;AAEF,qEAAqE;AACrE,qEAAqE;AACrE,4EAA4E;AAC5E,sEAAsE;AACtE,yEAAyE;AACzE,MAAM,uBAAuB,GAAG,EAAE,CAAC;AAEnC;;;GAGG;AACH,MAAM,iBAAiB,GAAG,CAAC,SAAmB,EAAE,QAAkB,EAAE,KAAa,EAAW,EAAE;IAC5F,IAAI,KAAK,GAAG,uBAAuB;QAAE,OAAO,KAAK,CAAC;IAClD,IAAI,QAAQ,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC9B,OAAO,CACL,SAAS,CAAC,IAAI,KAAK,OAAO,IAAI,iBAAiB,CAAC,SAAS,CAAC,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,CAAC,CAAC,CAC5F,CAAC;IACJ,CAAC;IACD,IAAI,QAAQ,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC/B,OAAO,CACL,SAAS,CAAC,IAAI,KAAK,QAAQ;YAC3B,mBAAmB,CAAC,SAAS,CAAC,UAAU,EAAE,QAAQ,CAAC,UAAU,EAAE,KAAK,GAAG,CAAC,CAAC,CAC1E,CAAC;IACJ,CAAC;IACD,IAAI,SAAS,CAAC,IAAI,KAAK,OAAO,IAAI,SAAS,CAAC,IAAI,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5E,OAAO,eAAe,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;AACjE,CAAC,CAAC;AAEF,MAAM,mBAAmB,GAAG,CAC1B,eAA2B,EAC3B,cAA0B,EAC1B,KAAa,EACJ,EAAE;IACX,IAAI,KAAK,GAAG,uBAAuB;QAAE,OAAO,KAAK,CAAC;IAClD,OAAO,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,EAAE;QACzD,IAAI,CAAC,GAAG,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAC;QAC/B,MAAM,KAAK,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;QACnC,OAAO,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,QAAQ,KAAK,IAAI,IAAI,iBAAiB,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;IAChG,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,eAA2B,EAAE,cAA0B,EAAW,EAAE,CAC/F,mBAAmB,CAAC,eAAe,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC;AAgB1D,yEAAyE;AACzE,uEAAuE;AACvE,wEAAwE;AACxE,+BAA+B;AAC/B,MAAM,cAAc,GAAG,EAAE,CAAC;AAE1B,MAAM,SAAS,GAAG,CAChB,IAAY,EACZ,MAAgB,EAChB,SAAmB,EACnB,KAAa,EACb,UAAkC,EAC5B,EAAE;IACR,IAAI,KAAK,GAAG,cAAc,EAAE,CAAC;QAC3B,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,0DAA0D,EAAE,CAAC,CAAC;QAC/F,OAAO;IACT,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,CAAC,IAAI,EAAE,CAAC;QACnC,UAAU,CAAC,IAAI,CAAC;YACd,IAAI;YACJ,OAAO,EAAE,sBAAsB,MAAM,CAAC,IAAI,SAAS,SAAS,CAAC,IAAI,GAAG;SACrE,CAAC,CAAC;QACH,OAAO,CAAC,qEAAqE;IAC/E,CAAC;IACD,IAAI,CAAC,CAAC,MAAM,CAAC,QAAQ,KAAK,CAAC,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;QAC/C,UAAU,CAAC,IAAI,CAAC;YACd,IAAI;YACJ,OAAO,EAAE,yBAAyB,CAAC,CAAC,MAAM,CAAC,QAAQ,OAAO,CAAC,CAAC,SAAS,CAAC,QAAQ,EAAE;SACjF,CAAC,CAAC;IACL,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO,IAAI,SAAS,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC1D,SAAS,CAAC,GAAG,IAAI,IAAI,EAAE,MAAM,CAAC,KAAK,EAAE,SAAS,CAAC,KAAK,EAAE,KAAK,GAAG,CAAC,EAAE,UAAU,CAAC,CAAC;IAC/E,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,SAAS,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC5D,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,UAAU,EAAE,SAAS,CAAC,UAAU,EAAE,KAAK,GAAG,CAAC,EAAE,UAAU,CAAC,CAAC;IACnF,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,UAAU,GAAG,CACjB,MAAc,EACd,MAAkB,EAClB,SAAqB,EACrB,KAAa,EACb,UAAkC,EAC5B,EAAE;IACR,IAAI,KAAK,GAAG,cAAc,EAAE,CAAC;QAC3B,UAAU,CAAC,IAAI,CAAC;YACd,IAAI,EAAE,MAAM;YACZ,OAAO,EAAE,0DAA0D;SACpE,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IACD,KAAK,MAAM,CAAC,GAAG,EAAE,SAAS,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QACtD,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;QAC/C,MAAM,YAAY,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,eAAe,EAAE,CAAC,CAAC;YACpD,SAAS;QACX,CAAC;QACD,SAAS,CAAC,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;IAC9D,CAAC;IACD,KAAK,MAAM,CAAC,GAAG,EAAE,YAAY,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;QAC5D,IAAI,GAAG,IAAI,MAAM;YAAE,SAAS,CAAC,yBAAyB;QACtD,IAAI,YAAY,CAAC,QAAQ,EAAE,CAAC;YAC1B,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;YAC/C,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,oDAAoD,EAAE,CAAC,CAAC;QAC3F,CAAC;QACD,iFAAiF;IACnF,CAAC;AACH,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,MAAkB,EAAE,SAAqB,EAA0B,EAAE;IAC/F,MAAM,UAAU,GAA2B,EAAE,CAAC;IAC9C,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,EAAE,UAAU,CAAC,CAAC;IACjD,OAAO,UAAU,CAAC;AACpB,CAAC,CAAC;AAEF,0DAA0D;AAC1D,kBAAkB;AAClB,0DAA0D;AAE1D;;;;GAIG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,MAAc,EAA8C,EAAE;IACxF,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IAC3C,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;AAC/D,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,MAAc,EAAE,OAAe,EAAU,EAAE,CAAC,GAAG,MAAM,IAAI,OAAO,EAAE,CAAC;AAE/F;;;;GAIG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,MAAc,EAAU,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,MAAM,IAAI,MAAM,CAAC;AAE1F;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,MAAc,EAAW,EAAE;IAC5D,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC3E,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,WAAW,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC;AAC/D,CAAC,CAAC"}
|