@arden-hq/revisions 0.0.0-stage → 0.1.2
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/LICENSE +202 -0
- package/README.md +84 -2
- package/dist/domain/change-set.d.ts +34 -0
- package/dist/domain/change-set.d.ts.map +1 -0
- package/dist/domain/change-set.js +206 -0
- package/dist/domain/change-set.js.map +1 -0
- package/dist/domain/codec.d.ts +17 -0
- package/dist/domain/codec.d.ts.map +1 -0
- package/dist/domain/codec.js +188 -0
- package/dist/domain/codec.js.map +1 -0
- package/dist/domain/errors.d.ts +61 -0
- package/dist/domain/errors.d.ts.map +1 -0
- package/dist/domain/errors.js +44 -0
- package/dist/domain/errors.js.map +1 -0
- package/dist/domain/format.d.ts +72 -0
- package/dist/domain/format.d.ts.map +1 -0
- package/dist/domain/format.js +93 -0
- package/dist/domain/format.js.map +1 -0
- package/dist/domain/integrity.d.ts +7 -0
- package/dist/domain/integrity.d.ts.map +1 -0
- package/dist/domain/integrity.js +100 -0
- package/dist/domain/integrity.js.map +1 -0
- package/dist/domain/model.d.ts +114 -0
- package/dist/domain/model.d.ts.map +1 -0
- package/dist/domain/model.js +145 -0
- package/dist/domain/model.js.map +1 -0
- package/dist/domain/query.d.ts +31 -0
- package/dist/domain/query.d.ts.map +1 -0
- package/dist/domain/query.js +168 -0
- package/dist/domain/query.js.map +1 -0
- package/dist/domain/transaction.d.ts +26 -0
- package/dist/domain/transaction.d.ts.map +1 -0
- package/dist/domain/transaction.js +93 -0
- package/dist/domain/transaction.js.map +1 -0
- package/dist/domain/tree.d.ts +6 -0
- package/dist/domain/tree.d.ts.map +1 -0
- package/dist/domain/tree.js +59 -0
- package/dist/domain/tree.js.map +1 -0
- package/dist/effect/index.d.ts +10 -0
- package/dist/effect/index.d.ts.map +1 -0
- package/dist/effect/index.js +4 -0
- package/dist/effect/index.js.map +1 -0
- package/dist/repository/commit.d.ts +12 -0
- package/dist/repository/commit.d.ts.map +1 -0
- package/dist/repository/commit.js +164 -0
- package/dist/repository/commit.js.map +1 -0
- package/dist/repository/history.d.ts +21 -0
- package/dist/repository/history.d.ts.map +1 -0
- package/dist/repository/history.js +152 -0
- package/dist/repository/history.js.map +1 -0
- package/dist/repository/service.d.ts +114 -0
- package/dist/repository/service.d.ts.map +1 -0
- package/dist/repository/service.js +374 -0
- package/dist/repository/service.js.map +1 -0
- package/dist/repository/state.d.ts +27 -0
- package/dist/repository/state.d.ts.map +1 -0
- package/dist/repository/state.js +72 -0
- package/dist/repository/state.js.map +1 -0
- package/dist/repository/transaction.d.ts +27 -0
- package/dist/repository/transaction.d.ts.map +1 -0
- package/dist/repository/transaction.js +372 -0
- package/dist/repository/transaction.js.map +1 -0
- package/dist/storage/files.d.ts +17 -0
- package/dist/storage/files.d.ts.map +1 -0
- package/dist/storage/files.js +179 -0
- package/dist/storage/files.js.map +1 -0
- package/dist/storage/maintenance-adapter.d.ts +5 -0
- package/dist/storage/maintenance-adapter.d.ts.map +1 -0
- package/dist/storage/maintenance-adapter.js +177 -0
- package/dist/storage/maintenance-adapter.js.map +1 -0
- package/dist/storage/maintenance-reader.d.ts +17 -0
- package/dist/storage/maintenance-reader.d.ts.map +1 -0
- package/dist/storage/maintenance-reader.js +82 -0
- package/dist/storage/maintenance-reader.js.map +1 -0
- package/dist/storage/maintenance.d.ts +113 -0
- package/dist/storage/maintenance.d.ts.map +1 -0
- package/dist/storage/maintenance.js +445 -0
- package/dist/storage/maintenance.js.map +1 -0
- package/dist/storage/node.d.ts +7 -0
- package/dist/storage/node.d.ts.map +1 -0
- package/dist/storage/node.js +53 -0
- package/dist/storage/node.js.map +1 -0
- package/dist/storage/service.d.ts +88 -0
- package/dist/storage/service.d.ts.map +1 -0
- package/dist/storage/service.js +506 -0
- package/dist/storage/service.js.map +1 -0
- package/package.json +63 -4
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import { DateTime, Effect, Option, Schema } from "effect";
|
|
2
|
+
import { Commit, ResourceChange, ResourceState, ResourceVersion, normalizeRelativePath } from "./model.js";
|
|
3
|
+
import { CorruptRepositoryError } from "./errors.js";
|
|
4
|
+
import { canonicalJsonl, decodeUtf8 } from "./format.js";
|
|
5
|
+
import { compareCodePoints } from "@arden-hq/std/json";
|
|
6
|
+
import { sha256Hex } from "@arden-hq/std/hash";
|
|
7
|
+
const Hash = Schema.String.check(Schema.isPattern(/^[0-9a-f]{64}$/));
|
|
8
|
+
const NonEmptyText = Schema.String.check(Schema.isMinLength(1));
|
|
9
|
+
const CanonicalTimestamp = Schema.String.pipe(Schema.check(Schema.isPattern(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{6}Z$/)));
|
|
10
|
+
const VersionRecordSchema = Schema.Struct({
|
|
11
|
+
resource_id: NonEmptyText,
|
|
12
|
+
path: NonEmptyText,
|
|
13
|
+
blob_id: Hash,
|
|
14
|
+
state: ResourceState,
|
|
15
|
+
version_id: Hash
|
|
16
|
+
});
|
|
17
|
+
const ChangeRecordSchema = Schema.Struct({
|
|
18
|
+
action: NonEmptyText,
|
|
19
|
+
before: Schema.NullOr(VersionRecordSchema),
|
|
20
|
+
after: Schema.NullOr(VersionRecordSchema)
|
|
21
|
+
});
|
|
22
|
+
const CommitRecordSchema = Schema.Struct({
|
|
23
|
+
version: Schema.Literal(2),
|
|
24
|
+
kind: Schema.Literal("commit"),
|
|
25
|
+
parent_id: Schema.NullOr(Hash),
|
|
26
|
+
tree_id: Hash,
|
|
27
|
+
actor: NonEmptyText,
|
|
28
|
+
origin: NonEmptyText,
|
|
29
|
+
reason: NonEmptyText,
|
|
30
|
+
timestamp: CanonicalTimestamp,
|
|
31
|
+
changes: Schema.Array(ChangeRecordSchema).check(Schema.isMinLength(1))
|
|
32
|
+
});
|
|
33
|
+
const TreeResourceRecordSchema = Schema.Struct({
|
|
34
|
+
kind: Schema.Literal("resource"),
|
|
35
|
+
name: NonEmptyText,
|
|
36
|
+
resource_id: NonEmptyText,
|
|
37
|
+
blob_id: Hash,
|
|
38
|
+
state: ResourceState,
|
|
39
|
+
version_id: Hash
|
|
40
|
+
});
|
|
41
|
+
const TreeSubtreeRecordSchema = Schema.Struct({
|
|
42
|
+
kind: Schema.Literal("subtree"),
|
|
43
|
+
name: NonEmptyText,
|
|
44
|
+
tree_id: Hash
|
|
45
|
+
});
|
|
46
|
+
const TreeRecordSchema = Schema.Struct({
|
|
47
|
+
version: Schema.Literal(2),
|
|
48
|
+
kind: Schema.Literal("tree"),
|
|
49
|
+
entries: Schema.Array(Schema.Union([TreeResourceRecordSchema, TreeSubtreeRecordSchema]))
|
|
50
|
+
});
|
|
51
|
+
const JsonRecordSchema = Schema.Record(Schema.String, Schema.Unknown);
|
|
52
|
+
const JsonRecordFromString = Schema.fromJsonString(JsonRecordSchema);
|
|
53
|
+
const fail = (message) => Effect.fail(new CorruptRepositoryError({ message }));
|
|
54
|
+
const decode = (schema, input, label) => Schema.decodeUnknownEffect(schema)(input, { onExcessProperty: "error" }).pipe(Effect.mapError(() => new CorruptRepositoryError({ message: `${label} has an invalid shape` })));
|
|
55
|
+
const bytesEqual = (left, right) => left.length === right.length && left.every((value, index) => value === right[index]);
|
|
56
|
+
/** Decode one canonical JSONL object and reject non-canonical bytes. */
|
|
57
|
+
export const decodeCanonicalJsonl = Effect.fn("decodeCanonicalJsonl")(function* (content) {
|
|
58
|
+
if (content.length === 0 ||
|
|
59
|
+
content[content.length - 1] !== 0x0a ||
|
|
60
|
+
content.filter((byte) => byte === 0x0a).length !== 1) {
|
|
61
|
+
return yield* fail("record is not one canonical JSONL object");
|
|
62
|
+
}
|
|
63
|
+
const text = yield* Effect.try({
|
|
64
|
+
try: () => decodeUtf8(content),
|
|
65
|
+
catch: () => new CorruptRepositoryError({ message: "record is not valid UTF-8" })
|
|
66
|
+
});
|
|
67
|
+
const record = yield* Schema.decodeUnknownEffect(JsonRecordFromString)(text).pipe(Effect.mapError(() => new CorruptRepositoryError({ message: "record is invalid JSONL" })));
|
|
68
|
+
const canonical = canonicalJsonl(record);
|
|
69
|
+
if (!bytesEqual(content, canonical))
|
|
70
|
+
return yield* fail("record is not canonical JSONL");
|
|
71
|
+
return record;
|
|
72
|
+
});
|
|
73
|
+
const decodeVersion = Effect.fn("decodeVersion")(function* (value, label) {
|
|
74
|
+
const decoded = yield* decode(VersionRecordSchema, value, label);
|
|
75
|
+
const normalizedPath = yield* normalizeRelativePath(decoded.path).pipe(Effect.mapError(() => new CorruptRepositoryError({ message: `${label} has an unsafe path` })));
|
|
76
|
+
if (normalizedPath !== decoded.path)
|
|
77
|
+
return yield* fail(`${label} has a non-normalized path`);
|
|
78
|
+
return decoded;
|
|
79
|
+
});
|
|
80
|
+
const toResourceVersion = (value, label) => Effect.try({
|
|
81
|
+
try: () => new ResourceVersion({
|
|
82
|
+
resourceId: value.resource_id,
|
|
83
|
+
path: value.path,
|
|
84
|
+
blobId: value.blob_id,
|
|
85
|
+
state: value.state,
|
|
86
|
+
versionId: value.version_id
|
|
87
|
+
}),
|
|
88
|
+
catch: () => new CorruptRepositoryError({ message: `${label} has an invalid resource version` })
|
|
89
|
+
});
|
|
90
|
+
const decodeChange = Effect.fn("decodeChange")(function* (value, label) {
|
|
91
|
+
const decoded = yield* decode(ChangeRecordSchema, value, label);
|
|
92
|
+
const before = decoded.before === null ? null : yield* decodeVersion(decoded.before, `${label}.before`);
|
|
93
|
+
const after = decoded.after === null ? null : yield* decodeVersion(decoded.after, `${label}.after`);
|
|
94
|
+
const beforeVersion = before === null ? null : yield* toResourceVersion(before, `${label}.before`);
|
|
95
|
+
const afterVersion = after === null ? null : yield* toResourceVersion(after, `${label}.after`);
|
|
96
|
+
return yield* Effect.try({
|
|
97
|
+
try: () => new ResourceChange({ action: decoded.action, before: beforeVersion, after: afterVersion }),
|
|
98
|
+
catch: () => new CorruptRepositoryError({ message: `${label} has an invalid resource change` })
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
/** Parse a v2 tree record, including strict entry shapes and state values. */
|
|
102
|
+
export const parseTreeRecord = Effect.fn("parseTreeRecord")(function* (value) {
|
|
103
|
+
const decoded = yield* decode(TreeRecordSchema, value, "tree");
|
|
104
|
+
const entries = [];
|
|
105
|
+
const subtreeNames = new Set();
|
|
106
|
+
const activeResourceNames = new Set();
|
|
107
|
+
for (const [index, entry] of decoded.entries.entries()) {
|
|
108
|
+
const normalizedName = yield* normalizeRelativePath(entry.name).pipe(Effect.mapError(() => new CorruptRepositoryError({ message: `tree entry ${index} has an invalid name` })));
|
|
109
|
+
if (normalizedName !== entry.name || entry.name.includes("/")) {
|
|
110
|
+
return yield* fail(`tree entry ${index} has an invalid name`);
|
|
111
|
+
}
|
|
112
|
+
if (entry.kind === "resource") {
|
|
113
|
+
if (entry.state === "active") {
|
|
114
|
+
if (activeResourceNames.has(entry.name))
|
|
115
|
+
return yield* fail(`tree repeats active name ${entry.name}`);
|
|
116
|
+
activeResourceNames.add(entry.name);
|
|
117
|
+
}
|
|
118
|
+
entries.push(entry);
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
if (subtreeNames.has(entry.name))
|
|
122
|
+
return yield* fail(`tree repeats subtree name ${entry.name}`);
|
|
123
|
+
subtreeNames.add(entry.name);
|
|
124
|
+
entries.push(entry);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
const sortKey = (entry) => `${entry.name}\u0000${entry.kind}\u0000${entry.kind === "resource" ? entry.resource_id : entry.tree_id}`;
|
|
128
|
+
let previousKey;
|
|
129
|
+
for (const entry of entries) {
|
|
130
|
+
const key = sortKey(entry);
|
|
131
|
+
if (previousKey !== undefined && compareCodePoints(previousKey, key) > 0) {
|
|
132
|
+
return yield* fail("tree entries are not uniquely ordered");
|
|
133
|
+
}
|
|
134
|
+
previousKey = key;
|
|
135
|
+
}
|
|
136
|
+
return { version: 2, kind: "tree", entries };
|
|
137
|
+
});
|
|
138
|
+
/** Parse a v2 commit record and validate canonical timestamp precision. */
|
|
139
|
+
export const parseCommitRecord = Effect.fn("parseCommitRecord")(function* (value) {
|
|
140
|
+
const decoded = yield* decode(CommitRecordSchema, value, "commit");
|
|
141
|
+
if (Option.isNone(DateTime.make(decoded.timestamp)))
|
|
142
|
+
return yield* fail("commit timestamp is invalid");
|
|
143
|
+
const resourceIds = decoded.changes.map((change) => change.after?.resource_id ?? change.before?.resource_id ?? "");
|
|
144
|
+
const sortedIds = [...resourceIds].sort(compareCodePoints);
|
|
145
|
+
if (resourceIds.some((resourceId, index) => resourceId !== sortedIds[index]) ||
|
|
146
|
+
new Set(resourceIds).size !== resourceIds.length) {
|
|
147
|
+
return yield* fail("commit changes are not uniquely ordered");
|
|
148
|
+
}
|
|
149
|
+
return {
|
|
150
|
+
version: 2,
|
|
151
|
+
kind: "commit",
|
|
152
|
+
parent_id: decoded.parent_id,
|
|
153
|
+
tree_id: decoded.tree_id,
|
|
154
|
+
actor: decoded.actor,
|
|
155
|
+
origin: decoded.origin,
|
|
156
|
+
reason: decoded.reason,
|
|
157
|
+
timestamp: decoded.timestamp,
|
|
158
|
+
changes: decoded.changes
|
|
159
|
+
};
|
|
160
|
+
});
|
|
161
|
+
/** Parse a canonical commit object and attach its content-addressed identifier. */
|
|
162
|
+
export const parseCommitObject = Effect.fn("parseCommitObject")(function* (objectId, content) {
|
|
163
|
+
const record = yield* decodeCanonicalJsonl(content);
|
|
164
|
+
const commitRecordValue = yield* parseCommitRecord(record);
|
|
165
|
+
if (!/^[0-9a-f]{64}$/.test(objectId))
|
|
166
|
+
return yield* fail("commit identifier is invalid");
|
|
167
|
+
if (sha256Hex(content) !== objectId)
|
|
168
|
+
return yield* fail("commit object identifier does not match content");
|
|
169
|
+
const changes = [];
|
|
170
|
+
for (const [index, change] of commitRecordValue.changes.entries()) {
|
|
171
|
+
changes.push(yield* decodeChange(change, `commit change ${index}`));
|
|
172
|
+
}
|
|
173
|
+
return new Commit({
|
|
174
|
+
commitId: objectId,
|
|
175
|
+
parentId: commitRecordValue.parent_id,
|
|
176
|
+
treeId: commitRecordValue.tree_id,
|
|
177
|
+
actor: commitRecordValue.actor,
|
|
178
|
+
origin: commitRecordValue.origin,
|
|
179
|
+
reason: commitRecordValue.reason,
|
|
180
|
+
timestamp: commitRecordValue.timestamp,
|
|
181
|
+
changes
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
/** Encode a validated commit record into its exact v2 canonical bytes. */
|
|
185
|
+
export const encodeCommitRecord = (record) => canonicalJsonl(record);
|
|
186
|
+
/** Encode a validated tree record into its exact v2 canonical bytes. */
|
|
187
|
+
export const encodeTreeRecord = (record) => canonicalJsonl(record);
|
|
188
|
+
//# sourceMappingURL=codec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codec.js","sourceRoot":"","sources":["../../src/domain/codec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { Schema } from "effect";
|
|
2
|
+
declare const RevisionConflictError_base: Schema.Class<RevisionConflictError, Schema.TaggedStruct<"RevisionConflictError", {
|
|
3
|
+
readonly message: Schema.String;
|
|
4
|
+
}>, import("effect/Cause").YieldableError>;
|
|
5
|
+
/** A revision request violates a current resource or repository precondition. */
|
|
6
|
+
export declare class RevisionConflictError extends RevisionConflictError_base {
|
|
7
|
+
}
|
|
8
|
+
declare const IdempotencyConflictError_base: Schema.Class<IdempotencyConflictError, Schema.TaggedStruct<"IdempotencyConflictError", {
|
|
9
|
+
readonly message: Schema.String;
|
|
10
|
+
}>, import("effect/Cause").YieldableError>;
|
|
11
|
+
/** An idempotency key was reused for a different request. */
|
|
12
|
+
export declare class IdempotencyConflictError extends IdempotencyConflictError_base {
|
|
13
|
+
}
|
|
14
|
+
declare const CorruptRepositoryError_base: Schema.Class<CorruptRepositoryError, Schema.TaggedStruct<"CorruptRepositoryError", {
|
|
15
|
+
readonly message: Schema.String;
|
|
16
|
+
}>, import("effect/Cause").YieldableError>;
|
|
17
|
+
/** Persisted revision metadata or an immutable object is invalid. */
|
|
18
|
+
export declare class CorruptRepositoryError extends CorruptRepositoryError_base {
|
|
19
|
+
}
|
|
20
|
+
declare const RevisionContentLimitError_base: Schema.Class<RevisionContentLimitError, Schema.TaggedStruct<"RevisionContentLimitError", {
|
|
21
|
+
readonly actualBytes: Schema.Int;
|
|
22
|
+
readonly limitBytes: Schema.Int;
|
|
23
|
+
readonly message: Schema.String;
|
|
24
|
+
}>, import("effect/Cause").YieldableError>;
|
|
25
|
+
/** A content operation exceeds its caller-declared byte bound. */
|
|
26
|
+
export declare class RevisionContentLimitError extends RevisionContentLimitError_base {
|
|
27
|
+
}
|
|
28
|
+
declare const UnsafePathError_base: Schema.Class<UnsafePathError, Schema.TaggedStruct<"UnsafePathError", {
|
|
29
|
+
readonly message: Schema.String;
|
|
30
|
+
}>, import("effect/Cause").YieldableError>;
|
|
31
|
+
/** A managed or metadata path is not a normalized relative path. */
|
|
32
|
+
export declare class UnsafePathError extends UnsafePathError_base {
|
|
33
|
+
}
|
|
34
|
+
declare const NoChangesError_base: Schema.Class<NoChangesError, Schema.TaggedStruct<"NoChangesError", {
|
|
35
|
+
readonly message: Schema.String;
|
|
36
|
+
}>, import("effect/Cause").YieldableError>;
|
|
37
|
+
/** A change set does not produce a new repository state. */
|
|
38
|
+
export declare class NoChangesError extends NoChangesError_base {
|
|
39
|
+
}
|
|
40
|
+
declare const InvalidRevisionInputError_base: Schema.Class<InvalidRevisionInputError, Schema.TaggedStruct<"InvalidRevisionInputError", {
|
|
41
|
+
readonly message: Schema.String;
|
|
42
|
+
}>, import("effect/Cause").YieldableError>;
|
|
43
|
+
/** An input record cannot be represented by the revisions v2 contract. */
|
|
44
|
+
export declare class InvalidRevisionInputError extends InvalidRevisionInputError_base {
|
|
45
|
+
}
|
|
46
|
+
declare const RevisionStorageError_base: Schema.Class<RevisionStorageError, Schema.TaggedStruct<"RevisionStorageError", {
|
|
47
|
+
readonly message: Schema.String;
|
|
48
|
+
readonly cause: Schema.optionalKey<Schema.Defect>;
|
|
49
|
+
}>, import("effect/Cause").YieldableError>;
|
|
50
|
+
/** A filesystem operation could not be completed by the repository adapter. */
|
|
51
|
+
export declare class RevisionStorageError extends RevisionStorageError_base {
|
|
52
|
+
}
|
|
53
|
+
declare const RepositoryClosedError_base: Schema.Class<RepositoryClosedError, Schema.TaggedStruct<"RepositoryClosedError", {
|
|
54
|
+
readonly message: Schema.String;
|
|
55
|
+
}>, import("effect/Cause").YieldableError>;
|
|
56
|
+
/** The repository's scope closed; the service handle outlived its layer. */
|
|
57
|
+
export declare class RepositoryClosedError extends RepositoryClosedError_base {
|
|
58
|
+
}
|
|
59
|
+
export type RevisionError = RevisionConflictError | IdempotencyConflictError | CorruptRepositoryError | RevisionContentLimitError | UnsafePathError | NoChangesError | InvalidRevisionInputError | RevisionStorageError | RepositoryClosedError;
|
|
60
|
+
export {};
|
|
61
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/domain/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;;;;AAE/B,iFAAiF;AACjF,qBAAa,qBAAsB,SAAQ,0BAK1C;CAAG;;;;AAEJ,6DAA6D;AAC7D,qBAAa,wBAAyB,SAAQ,6BAG7C;CAAG;;;;AAEJ,qEAAqE;AACrE,qBAAa,sBAAuB,SAAQ,2BAK3C;CAAG;;;;;;AAEJ,kEAAkE;AAClE,qBAAa,yBAA0B,SAAQ,8BAO9C;CAAG;;;;AAEJ,oEAAoE;AACpE,qBAAa,eAAgB,SAAQ,oBAEnC;CAAG;;;;AAEL,4DAA4D;AAC5D,qBAAa,cAAe,SAAQ,mBAElC;CAAG;;;;AAEL,0EAA0E;AAC1E,qBAAa,yBAA0B,SAAQ,8BAG9C;CAAG;;;;;AAEJ,+EAA+E;AAC/E,qBAAa,oBAAqB,SAAQ,yBAMzC;CAAG;;;;AAEJ,4EAA4E;AAC5E,qBAAa,qBAAsB,SAAQ,0BAG1C;CAAG;AAEJ,MAAM,MAAM,aAAa,GACrB,qBAAqB,GACrB,wBAAwB,GACxB,sBAAsB,GACtB,yBAAyB,GACzB,eAAe,GACf,cAAc,GACd,yBAAyB,GACzB,oBAAoB,GACpB,qBAAqB,CAAA"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Schema } from "effect";
|
|
2
|
+
/** A revision request violates a current resource or repository precondition. */
|
|
3
|
+
export class RevisionConflictError extends Schema.TaggedError()("RevisionConflictError", {
|
|
4
|
+
message: Schema.String
|
|
5
|
+
}) {
|
|
6
|
+
}
|
|
7
|
+
/** An idempotency key was reused for a different request. */
|
|
8
|
+
export class IdempotencyConflictError extends Schema.TaggedError()("IdempotencyConflictError", { message: Schema.String }) {
|
|
9
|
+
}
|
|
10
|
+
/** Persisted revision metadata or an immutable object is invalid. */
|
|
11
|
+
export class CorruptRepositoryError extends Schema.TaggedError()("CorruptRepositoryError", {
|
|
12
|
+
message: Schema.String
|
|
13
|
+
}) {
|
|
14
|
+
}
|
|
15
|
+
/** A content operation exceeds its caller-declared byte bound. */
|
|
16
|
+
export class RevisionContentLimitError extends Schema.TaggedError()("RevisionContentLimitError", {
|
|
17
|
+
actualBytes: Schema.Int,
|
|
18
|
+
limitBytes: Schema.Int,
|
|
19
|
+
message: Schema.String
|
|
20
|
+
}) {
|
|
21
|
+
}
|
|
22
|
+
/** A managed or metadata path is not a normalized relative path. */
|
|
23
|
+
export class UnsafePathError extends Schema.TaggedError()("UnsafePathError", {
|
|
24
|
+
message: Schema.String
|
|
25
|
+
}) {
|
|
26
|
+
}
|
|
27
|
+
/** A change set does not produce a new repository state. */
|
|
28
|
+
export class NoChangesError extends Schema.TaggedError()("NoChangesError", {
|
|
29
|
+
message: Schema.String
|
|
30
|
+
}) {
|
|
31
|
+
}
|
|
32
|
+
/** An input record cannot be represented by the revisions v2 contract. */
|
|
33
|
+
export class InvalidRevisionInputError extends Schema.TaggedError()("InvalidRevisionInputError", { message: Schema.String }) {
|
|
34
|
+
}
|
|
35
|
+
/** A filesystem operation could not be completed by the repository adapter. */
|
|
36
|
+
export class RevisionStorageError extends Schema.TaggedError()("RevisionStorageError", {
|
|
37
|
+
message: Schema.String,
|
|
38
|
+
cause: Schema.optionalKey(Schema.Defect())
|
|
39
|
+
}) {
|
|
40
|
+
}
|
|
41
|
+
/** The repository's scope closed; the service handle outlived its layer. */
|
|
42
|
+
export class RepositoryClosedError extends Schema.TaggedError()("RepositoryClosedError", { message: Schema.String }) {
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/domain/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAE/B,iFAAiF;AACjF,MAAM,OAAO,qBAAsB,SAAQ,MAAM,CAAC,WAAW,EAAyB,CACpF,uBAAuB,EACvB;IACE,OAAO,EAAE,MAAM,CAAC,MAAM;CACvB,CACF;CAAG;AAEJ,6DAA6D;AAC7D,MAAM,OAAO,wBAAyB,SAAQ,MAAM,CAAC,WAAW,EAA4B,CAC1F,0BAA0B,EAC1B,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,CAC3B;CAAG;AAEJ,qEAAqE;AACrE,MAAM,OAAO,sBAAuB,SAAQ,MAAM,CAAC,WAAW,EAA0B,CACtF,wBAAwB,EACxB;IACE,OAAO,EAAE,MAAM,CAAC,MAAM;CACvB,CACF;CAAG;AAEJ,kEAAkE;AAClE,MAAM,OAAO,yBAA0B,SAAQ,MAAM,CAAC,WAAW,EAA6B,CAC5F,2BAA2B,EAC3B;IACE,WAAW,EAAE,MAAM,CAAC,GAAG;IACvB,UAAU,EAAE,MAAM,CAAC,GAAG;IACtB,OAAO,EAAE,MAAM,CAAC,MAAM;CACvB,CACF;CAAG;AAEJ,oEAAoE;AACpE,MAAM,OAAO,eAAgB,SAAQ,MAAM,CAAC,WAAW,EAAmB,CAAC,iBAAiB,EAAE;IAC5F,OAAO,EAAE,MAAM,CAAC,MAAM;CACvB,CAAC;CAAG;AAEL,4DAA4D;AAC5D,MAAM,OAAO,cAAe,SAAQ,MAAM,CAAC,WAAW,EAAkB,CAAC,gBAAgB,EAAE;IACzF,OAAO,EAAE,MAAM,CAAC,MAAM;CACvB,CAAC;CAAG;AAEL,0EAA0E;AAC1E,MAAM,OAAO,yBAA0B,SAAQ,MAAM,CAAC,WAAW,EAA6B,CAC5F,2BAA2B,EAC3B,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,CAC3B;CAAG;AAEJ,+EAA+E;AAC/E,MAAM,OAAO,oBAAqB,SAAQ,MAAM,CAAC,WAAW,EAAwB,CAClF,sBAAsB,EACtB;IACE,OAAO,EAAE,MAAM,CAAC,MAAM;IACtB,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;CAC3C,CACF;CAAG;AAEJ,4EAA4E;AAC5E,MAAM,OAAO,qBAAsB,SAAQ,MAAM,CAAC,WAAW,EAAyB,CACpF,uBAAuB,EACvB,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,CAC3B;CAAG"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import type { ResourceChange, ResourceState, ResourceVersion } from "./model.js";
|
|
2
|
+
type JsonPrimitive = null | boolean | number | string;
|
|
3
|
+
export type JsonValue = JsonPrimitive | readonly JsonValue[] | {
|
|
4
|
+
readonly [key: string]: JsonValue;
|
|
5
|
+
};
|
|
6
|
+
export type JsonRecord = {
|
|
7
|
+
readonly [key: string]: JsonValue;
|
|
8
|
+
};
|
|
9
|
+
export declare const encodeUtf8: (value: string) => Uint8Array;
|
|
10
|
+
export declare const decodeUtf8: (value: Uint8Array) => string;
|
|
11
|
+
/** Encode the canonical compact, key-sorted JSON representation followed by LF. */
|
|
12
|
+
export declare const canonicalJsonl: (value: JsonRecord) => Uint8Array;
|
|
13
|
+
export interface VersionRecord {
|
|
14
|
+
readonly resource_id: string;
|
|
15
|
+
readonly path: string;
|
|
16
|
+
readonly blob_id: string;
|
|
17
|
+
readonly state: ResourceState;
|
|
18
|
+
readonly version_id: string;
|
|
19
|
+
}
|
|
20
|
+
export interface ChangeRecord {
|
|
21
|
+
readonly action: string;
|
|
22
|
+
readonly before: VersionRecord | null;
|
|
23
|
+
readonly after: VersionRecord | null;
|
|
24
|
+
}
|
|
25
|
+
export interface CommitRecord {
|
|
26
|
+
readonly version: 2;
|
|
27
|
+
readonly kind: "commit";
|
|
28
|
+
readonly parent_id: string | null;
|
|
29
|
+
readonly tree_id: string;
|
|
30
|
+
readonly actor: string;
|
|
31
|
+
readonly origin: string;
|
|
32
|
+
readonly reason: string;
|
|
33
|
+
readonly timestamp: string;
|
|
34
|
+
readonly changes: readonly ChangeRecord[];
|
|
35
|
+
}
|
|
36
|
+
interface TreeResourceRecord {
|
|
37
|
+
readonly kind: "resource";
|
|
38
|
+
readonly name: string;
|
|
39
|
+
readonly resource_id: string;
|
|
40
|
+
readonly blob_id: string;
|
|
41
|
+
readonly state: ResourceState;
|
|
42
|
+
readonly version_id: string;
|
|
43
|
+
}
|
|
44
|
+
interface TreeSubtreeRecord {
|
|
45
|
+
readonly kind: "subtree";
|
|
46
|
+
readonly name: string;
|
|
47
|
+
readonly tree_id: string;
|
|
48
|
+
}
|
|
49
|
+
export type TreeEntryRecord = TreeResourceRecord | TreeSubtreeRecord;
|
|
50
|
+
export interface TreeRecord {
|
|
51
|
+
readonly version: 2;
|
|
52
|
+
readonly kind: "tree";
|
|
53
|
+
readonly entries: readonly TreeEntryRecord[];
|
|
54
|
+
}
|
|
55
|
+
export interface TreeObjects {
|
|
56
|
+
readonly rootId: string;
|
|
57
|
+
readonly objects: ReadonlyMap<string, TreeRecord>;
|
|
58
|
+
}
|
|
59
|
+
/** Build the exact v2 commit record before content-addressing it. */
|
|
60
|
+
export declare const commitRecord: (value: {
|
|
61
|
+
readonly parentId: string | null;
|
|
62
|
+
readonly treeId: string;
|
|
63
|
+
readonly actor: string;
|
|
64
|
+
readonly origin: string;
|
|
65
|
+
readonly reason: string;
|
|
66
|
+
readonly timestamp: string;
|
|
67
|
+
readonly changes: readonly ResourceChange[];
|
|
68
|
+
}) => CommitRecord;
|
|
69
|
+
/** Build v2 per-directory tree objects with structural sharing by identity. */
|
|
70
|
+
export declare const buildTreeObjects: (resources: readonly ResourceVersion[]) => TreeObjects;
|
|
71
|
+
export {};
|
|
72
|
+
//# sourceMappingURL=format.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/domain/format.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { sha256Hex } from "@arden-hq/std/hash";
|
|
2
|
+
import { canonicalJson, compareCodePoints } from "@arden-hq/std/json";
|
|
3
|
+
const encoder = new TextEncoder();
|
|
4
|
+
const decoder = new TextDecoder("utf-8", { fatal: true });
|
|
5
|
+
export const encodeUtf8 = (value) => encoder.encode(value);
|
|
6
|
+
export const decodeUtf8 = (value) => decoder.decode(value);
|
|
7
|
+
const assertSafeIntegers = (value) => {
|
|
8
|
+
if (typeof value === "number") {
|
|
9
|
+
if (!Number.isSafeInteger(value))
|
|
10
|
+
throw new TypeError("revision records support only safe integers");
|
|
11
|
+
}
|
|
12
|
+
else if (Array.isArray(value)) {
|
|
13
|
+
value.forEach(assertSafeIntegers);
|
|
14
|
+
}
|
|
15
|
+
else if (typeof value === "object" && value !== null) {
|
|
16
|
+
Object.values(value).forEach(assertSafeIntegers);
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
/** Encode the canonical compact, key-sorted JSON representation followed by LF. */
|
|
20
|
+
export const canonicalJsonl = (value) => {
|
|
21
|
+
assertSafeIntegers(value);
|
|
22
|
+
return encodeUtf8(`${canonicalJson(value, { lenient: true })}\n`);
|
|
23
|
+
};
|
|
24
|
+
const versionRecord = (value) => ({
|
|
25
|
+
resource_id: value.resourceId,
|
|
26
|
+
path: value.path,
|
|
27
|
+
blob_id: value.blobId,
|
|
28
|
+
state: value.state,
|
|
29
|
+
version_id: value.versionId
|
|
30
|
+
});
|
|
31
|
+
const changeRecord = (value) => ({
|
|
32
|
+
action: value.action,
|
|
33
|
+
before: value.before === null ? null : versionRecord(value.before),
|
|
34
|
+
after: value.after === null ? null : versionRecord(value.after)
|
|
35
|
+
});
|
|
36
|
+
/** Build the exact v2 commit record before content-addressing it. */
|
|
37
|
+
export const commitRecord = (value) => ({
|
|
38
|
+
version: 2,
|
|
39
|
+
kind: "commit",
|
|
40
|
+
parent_id: value.parentId,
|
|
41
|
+
tree_id: value.treeId,
|
|
42
|
+
actor: value.actor,
|
|
43
|
+
origin: value.origin,
|
|
44
|
+
reason: value.reason,
|
|
45
|
+
timestamp: value.timestamp,
|
|
46
|
+
changes: value.changes.map(changeRecord)
|
|
47
|
+
});
|
|
48
|
+
const entrySortKey = (entry) => `${entry.name}\u0000${entry.kind}\u0000${entry.kind === "resource" ? entry.resource_id : entry.tree_id}`;
|
|
49
|
+
const buildTreeNode = (items, objects) => {
|
|
50
|
+
const resources = [];
|
|
51
|
+
const children = new Map();
|
|
52
|
+
for (const [[name, ...rest], resource] of items) {
|
|
53
|
+
if (name === undefined)
|
|
54
|
+
continue;
|
|
55
|
+
if (rest.length === 0) {
|
|
56
|
+
resources.push({
|
|
57
|
+
kind: "resource",
|
|
58
|
+
name,
|
|
59
|
+
resource_id: resource.resourceId,
|
|
60
|
+
blob_id: resource.blobId,
|
|
61
|
+
state: resource.state,
|
|
62
|
+
version_id: resource.versionId
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
const child = children.get(name);
|
|
67
|
+
if (child === undefined)
|
|
68
|
+
children.set(name, [[rest, resource]]);
|
|
69
|
+
else
|
|
70
|
+
child.push([rest, resource]);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
const entries = [...resources];
|
|
74
|
+
for (const [name, childItems] of children) {
|
|
75
|
+
entries.push({ kind: "subtree", name, tree_id: buildTreeNode(childItems, objects) });
|
|
76
|
+
}
|
|
77
|
+
entries.sort((left, right) => {
|
|
78
|
+
const leftKey = entrySortKey(left);
|
|
79
|
+
const rightKey = entrySortKey(right);
|
|
80
|
+
return compareCodePoints(leftKey, rightKey);
|
|
81
|
+
});
|
|
82
|
+
const record = { version: 2, kind: "tree", entries };
|
|
83
|
+
const treeId = sha256Hex(canonicalJsonl(record));
|
|
84
|
+
objects.set(treeId, record);
|
|
85
|
+
return treeId;
|
|
86
|
+
};
|
|
87
|
+
/** Build v2 per-directory tree objects with structural sharing by identity. */
|
|
88
|
+
export const buildTreeObjects = (resources) => {
|
|
89
|
+
const objects = new Map();
|
|
90
|
+
const items = resources.map((resource) => [resource.path.split("/"), resource]);
|
|
91
|
+
return { rootId: buildTreeNode(items, objects), objects };
|
|
92
|
+
};
|
|
93
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/domain/format.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import type { ResourceSnapshot } from "./change-set.js";
|
|
3
|
+
import { Commit } from "./model.js";
|
|
4
|
+
import { CorruptRepositoryError } from "./errors.js";
|
|
5
|
+
export declare const validateSnapshotTransition: (commit: Commit, before: ResourceSnapshot, after: ResourceSnapshot) => Effect.Effect<void, CorruptRepositoryError, never>;
|
|
6
|
+
export declare const validateActivePaths: (snapshot: ResourceSnapshot) => Effect.Effect<void, CorruptRepositoryError, never>;
|
|
7
|
+
//# sourceMappingURL=integrity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integrity.d.ts","sourceRoot":"","sources":["../../src/domain/integrity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAE/B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AACvD,OAAO,EAAE,MAAM,EAAgC,MAAM,YAAY,CAAA;AACjE,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;AA8DpD,eAAO,MAAM,0BAA0B,2HAwEtC,CAAA;AAED,eAAO,MAAM,mBAAmB,oFAc9B,CAAA"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { Commit, ResourceVersion, makeVersion } from "./model.js";
|
|
3
|
+
import { CorruptRepositoryError } from "./errors.js";
|
|
4
|
+
import { compareCodePoints } from "@arden-hq/std/json";
|
|
5
|
+
const failCorrupt = (message) => Effect.fail(new CorruptRepositoryError({ message }));
|
|
6
|
+
const versionsEqual = (left, right) => left === right ||
|
|
7
|
+
(left !== null &&
|
|
8
|
+
right !== null &&
|
|
9
|
+
left.resourceId === right.resourceId &&
|
|
10
|
+
left.path === right.path &&
|
|
11
|
+
left.blobId === right.blobId &&
|
|
12
|
+
left.state === right.state &&
|
|
13
|
+
left.versionId === right.versionId);
|
|
14
|
+
const changeResourceId = (change) => change.after?.resourceId ?? change.before?.resourceId ?? null;
|
|
15
|
+
const validChangeAction = (change) => {
|
|
16
|
+
const { before, after } = change;
|
|
17
|
+
if (change.action === "create")
|
|
18
|
+
return before === null && after !== null;
|
|
19
|
+
if (before === null ||
|
|
20
|
+
after === null ||
|
|
21
|
+
before.resourceId !== after.resourceId ||
|
|
22
|
+
versionsEqual(before, after))
|
|
23
|
+
return false;
|
|
24
|
+
if (change.action === "update") {
|
|
25
|
+
return (before.state === "active" &&
|
|
26
|
+
after.state === "active" &&
|
|
27
|
+
before.path === after.path &&
|
|
28
|
+
before.blobId !== after.blobId);
|
|
29
|
+
}
|
|
30
|
+
if (change.action === "move") {
|
|
31
|
+
return (before.state === "active" &&
|
|
32
|
+
after.state === "active" &&
|
|
33
|
+
(before.path !== after.path || before.blobId !== after.blobId));
|
|
34
|
+
}
|
|
35
|
+
if (change.action === "archive") {
|
|
36
|
+
return (before.state === "active" &&
|
|
37
|
+
after.state === "archived" &&
|
|
38
|
+
before.path === after.path &&
|
|
39
|
+
before.blobId === after.blobId);
|
|
40
|
+
}
|
|
41
|
+
if (change.action === "restore")
|
|
42
|
+
return after.state === "active";
|
|
43
|
+
return false;
|
|
44
|
+
};
|
|
45
|
+
export const validateSnapshotTransition = Effect.fn("Revision.validateSnapshotTransition")(function* (commit, before, after) {
|
|
46
|
+
const identified = commit.changes.flatMap((change) => {
|
|
47
|
+
const resourceId = changeResourceId(change);
|
|
48
|
+
return resourceId === null ? [] : [[resourceId, change]];
|
|
49
|
+
});
|
|
50
|
+
if (identified.length !== commit.changes.length)
|
|
51
|
+
return yield* failCorrupt(`commit ${commit.commitId} contains a change without a resource identity`);
|
|
52
|
+
const recordedIds = identified.map(([resourceId]) => resourceId);
|
|
53
|
+
const changedIds = [];
|
|
54
|
+
for (const [resourceId, version] of before) {
|
|
55
|
+
if (!versionsEqual(version, after.get(resourceId) ?? null))
|
|
56
|
+
changedIds.push(resourceId);
|
|
57
|
+
}
|
|
58
|
+
for (const resourceId of after.keys()) {
|
|
59
|
+
if (!before.has(resourceId))
|
|
60
|
+
changedIds.push(resourceId);
|
|
61
|
+
}
|
|
62
|
+
changedIds.sort(compareCodePoints);
|
|
63
|
+
if (recordedIds.length !== changedIds.length ||
|
|
64
|
+
recordedIds.some((resourceId, index) => resourceId !== changedIds[index]))
|
|
65
|
+
return yield* failCorrupt(`commit ${commit.commitId} changes do not match its parent and resulting trees`);
|
|
66
|
+
const changed = new Map(identified);
|
|
67
|
+
if (changed.size !== commit.changes.length)
|
|
68
|
+
return yield* failCorrupt(`commit ${commit.commitId} repeats a resource change`);
|
|
69
|
+
for (const resourceId of changedIds) {
|
|
70
|
+
const beforeVersion = before.get(resourceId) ?? null;
|
|
71
|
+
const afterVersion = after.get(resourceId) ?? null;
|
|
72
|
+
const change = changed.get(resourceId);
|
|
73
|
+
if (change === undefined ||
|
|
74
|
+
change.after === null ||
|
|
75
|
+
!versionsEqual(beforeVersion, change.before) ||
|
|
76
|
+
!versionsEqual(afterVersion, change.after)) {
|
|
77
|
+
return yield* failCorrupt(`commit ${commit.commitId} does not describe its full tree transition`);
|
|
78
|
+
}
|
|
79
|
+
const recomputed = yield* makeVersion(change.after.resourceId, change.after.path, change.after.blobId, change.after.state, beforeVersion?.versionId ?? null).pipe(Effect.mapError(() => new CorruptRepositoryError({
|
|
80
|
+
message: `commit ${commit.commitId} contains an invalid version identity`
|
|
81
|
+
})));
|
|
82
|
+
if (recomputed.versionId !== change.after.versionId)
|
|
83
|
+
return yield* failCorrupt(`commit ${commit.commitId} contains a non-canonical version identity`);
|
|
84
|
+
if (!validChangeAction(change))
|
|
85
|
+
return yield* failCorrupt(`commit ${commit.commitId} has invalid ${change.action} semantics for ${resourceId}`);
|
|
86
|
+
}
|
|
87
|
+
yield* validateActivePaths(after);
|
|
88
|
+
});
|
|
89
|
+
export const validateActivePaths = Effect.fn("Revision.validateActivePaths")(function* (snapshot) {
|
|
90
|
+
const activePaths = new Set([...snapshot.values()]
|
|
91
|
+
.filter((version) => version.state === "active")
|
|
92
|
+
.map((version) => version.path));
|
|
93
|
+
for (const path of activePaths) {
|
|
94
|
+
for (let slash = path.indexOf("/"); slash !== -1; slash = path.indexOf("/", slash + 1)) {
|
|
95
|
+
if (activePaths.has(path.slice(0, slash)))
|
|
96
|
+
return yield* failCorrupt("tree contains an active path ancestor collision");
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
//# sourceMappingURL=integrity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integrity.js","sourceRoot":"","sources":["../../src/domain/integrity.ts"],"names":[],"mappings":"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"}
|