@proseql/core 0.1.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/LICENSE +21 -0
- package/dist/errors/crud-errors.d.ts +98 -0
- package/dist/errors/crud-errors.d.ts.map +1 -0
- package/dist/errors/crud-errors.js +23 -0
- package/dist/errors/crud-errors.js.map +1 -0
- package/dist/errors/index.d.ts +16 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +12 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/errors/migration-errors.d.ts +22 -0
- package/dist/errors/migration-errors.d.ts.map +1 -0
- package/dist/errors/migration-errors.js +14 -0
- package/dist/errors/migration-errors.js.map +1 -0
- package/dist/errors/plugin-errors.d.ts +15 -0
- package/dist/errors/plugin-errors.d.ts.map +1 -0
- package/dist/errors/plugin-errors.js +11 -0
- package/dist/errors/plugin-errors.js.map +1 -0
- package/dist/errors/query-errors.d.ts +31 -0
- package/dist/errors/query-errors.d.ts.map +1 -0
- package/dist/errors/query-errors.js +11 -0
- package/dist/errors/query-errors.js.map +1 -0
- package/dist/errors/storage-errors.d.ts +30 -0
- package/dist/errors/storage-errors.d.ts.map +1 -0
- package/dist/errors/storage-errors.js +11 -0
- package/dist/errors/storage-errors.js.map +1 -0
- package/dist/factories/crud-factory-with-relationships.d.ts +28 -0
- package/dist/factories/crud-factory-with-relationships.d.ts.map +1 -0
- package/dist/factories/crud-factory-with-relationships.js +8 -0
- package/dist/factories/crud-factory-with-relationships.js.map +1 -0
- package/dist/factories/crud-factory.d.ts +25 -0
- package/dist/factories/crud-factory.d.ts.map +1 -0
- package/dist/factories/crud-factory.js +8 -0
- package/dist/factories/crud-factory.js.map +1 -0
- package/dist/factories/database-effect.d.ts +241 -0
- package/dist/factories/database-effect.d.ts.map +1 -0
- package/dist/factories/database-effect.js +859 -0
- package/dist/factories/database-effect.js.map +1 -0
- package/dist/hooks/hook-runner.d.ts +60 -0
- package/dist/hooks/hook-runner.d.ts.map +1 -0
- package/dist/hooks/hook-runner.js +107 -0
- package/dist/hooks/hook-runner.js.map +1 -0
- package/dist/index.d.ts +84 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +110 -0
- package/dist/index.js.map +1 -0
- package/dist/indexes/index-lookup.d.ts +33 -0
- package/dist/indexes/index-lookup.d.ts.map +1 -0
- package/dist/indexes/index-lookup.js +180 -0
- package/dist/indexes/index-lookup.js.map +1 -0
- package/dist/indexes/index-manager.d.ts +118 -0
- package/dist/indexes/index-manager.d.ts.map +1 -0
- package/dist/indexes/index-manager.js +345 -0
- package/dist/indexes/index-manager.js.map +1 -0
- package/dist/indexes/search-index.d.ts +179 -0
- package/dist/indexes/search-index.d.ts.map +1 -0
- package/dist/indexes/search-index.js +405 -0
- package/dist/indexes/search-index.js.map +1 -0
- package/dist/migrations/migration-runner.d.ts +70 -0
- package/dist/migrations/migration-runner.d.ts.map +1 -0
- package/dist/migrations/migration-runner.js +271 -0
- package/dist/migrations/migration-runner.js.map +1 -0
- package/dist/migrations/migration-types.d.ts +63 -0
- package/dist/migrations/migration-types.d.ts.map +1 -0
- package/dist/migrations/migration-types.js +5 -0
- package/dist/migrations/migration-types.js.map +1 -0
- package/dist/operations/crud/create-with-relationships.d.ts +44 -0
- package/dist/operations/crud/create-with-relationships.d.ts.map +1 -0
- package/dist/operations/crud/create-with-relationships.js +483 -0
- package/dist/operations/crud/create-with-relationships.js.map +1 -0
- package/dist/operations/crud/create.d.ts +48 -0
- package/dist/operations/crud/create.d.ts.map +1 -0
- package/dist/operations/crud/create.js +333 -0
- package/dist/operations/crud/create.js.map +1 -0
- package/dist/operations/crud/delete-with-relationships.d.ts +63 -0
- package/dist/operations/crud/delete-with-relationships.d.ts.map +1 -0
- package/dist/operations/crud/delete-with-relationships.js +395 -0
- package/dist/operations/crud/delete-with-relationships.js.map +1 -0
- package/dist/operations/crud/delete.d.ts +58 -0
- package/dist/operations/crud/delete.d.ts.map +1 -0
- package/dist/operations/crud/delete.js +267 -0
- package/dist/operations/crud/delete.js.map +1 -0
- package/dist/operations/crud/unique-check.d.ts +114 -0
- package/dist/operations/crud/unique-check.d.ts.map +1 -0
- package/dist/operations/crud/unique-check.js +383 -0
- package/dist/operations/crud/unique-check.js.map +1 -0
- package/dist/operations/crud/update-with-relationships.d.ts +45 -0
- package/dist/operations/crud/update-with-relationships.d.ts.map +1 -0
- package/dist/operations/crud/update-with-relationships.js +516 -0
- package/dist/operations/crud/update-with-relationships.js.map +1 -0
- package/dist/operations/crud/update.d.ts +91 -0
- package/dist/operations/crud/update.d.ts.map +1 -0
- package/dist/operations/crud/update.js +505 -0
- package/dist/operations/crud/update.js.map +1 -0
- package/dist/operations/crud/upsert.d.ts +52 -0
- package/dist/operations/crud/upsert.d.ts.map +1 -0
- package/dist/operations/crud/upsert.js +386 -0
- package/dist/operations/crud/upsert.js.map +1 -0
- package/dist/operations/query/aggregate.d.ts +30 -0
- package/dist/operations/query/aggregate.d.ts.map +1 -0
- package/dist/operations/query/aggregate.js +227 -0
- package/dist/operations/query/aggregate.js.map +1 -0
- package/dist/operations/query/cursor-stream.d.ts +18 -0
- package/dist/operations/query/cursor-stream.d.ts.map +1 -0
- package/dist/operations/query/cursor-stream.js +199 -0
- package/dist/operations/query/cursor-stream.js.map +1 -0
- package/dist/operations/query/filter-stream.d.ts +12 -0
- package/dist/operations/query/filter-stream.d.ts.map +1 -0
- package/dist/operations/query/filter-stream.js +167 -0
- package/dist/operations/query/filter-stream.js.map +1 -0
- package/dist/operations/query/filter.d.ts +13 -0
- package/dist/operations/query/filter.d.ts.map +1 -0
- package/dist/operations/query/filter.js +267 -0
- package/dist/operations/query/filter.js.map +1 -0
- package/dist/operations/query/paginate-stream.d.ts +11 -0
- package/dist/operations/query/paginate-stream.d.ts.map +1 -0
- package/dist/operations/query/paginate-stream.js +22 -0
- package/dist/operations/query/paginate-stream.js.map +1 -0
- package/dist/operations/query/query-helpers.d.ts +14 -0
- package/dist/operations/query/query-helpers.d.ts.map +1 -0
- package/dist/operations/query/query-helpers.js +22 -0
- package/dist/operations/query/query-helpers.js.map +1 -0
- package/dist/operations/query/resolve-computed.d.ts +142 -0
- package/dist/operations/query/resolve-computed.d.ts.map +1 -0
- package/dist/operations/query/resolve-computed.js +197 -0
- package/dist/operations/query/resolve-computed.js.map +1 -0
- package/dist/operations/query/search.d.ts +110 -0
- package/dist/operations/query/search.d.ts.map +1 -0
- package/dist/operations/query/search.js +188 -0
- package/dist/operations/query/search.js.map +1 -0
- package/dist/operations/query/select-stream.d.ts +27 -0
- package/dist/operations/query/select-stream.d.ts.map +1 -0
- package/dist/operations/query/select-stream.js +88 -0
- package/dist/operations/query/select-stream.js.map +1 -0
- package/dist/operations/query/select.d.ts +54 -0
- package/dist/operations/query/select.d.ts.map +1 -0
- package/dist/operations/query/select.js +159 -0
- package/dist/operations/query/select.js.map +1 -0
- package/dist/operations/query/sort-stream.d.ts +46 -0
- package/dist/operations/query/sort-stream.d.ts.map +1 -0
- package/dist/operations/query/sort-stream.js +158 -0
- package/dist/operations/query/sort-stream.js.map +1 -0
- package/dist/operations/query/sort.d.ts +9 -0
- package/dist/operations/query/sort.d.ts.map +1 -0
- package/dist/operations/query/sort.js +58 -0
- package/dist/operations/query/sort.js.map +1 -0
- package/dist/operations/relationships/populate-stream.d.ts +29 -0
- package/dist/operations/relationships/populate-stream.d.ts.map +1 -0
- package/dist/operations/relationships/populate-stream.js +159 -0
- package/dist/operations/relationships/populate-stream.js.map +1 -0
- package/dist/operations/relationships/populate.d.ts +15 -0
- package/dist/operations/relationships/populate.d.ts.map +1 -0
- package/dist/operations/relationships/populate.js +228 -0
- package/dist/operations/relationships/populate.js.map +1 -0
- package/dist/plugins/plugin-hooks.d.ts +25 -0
- package/dist/plugins/plugin-hooks.d.ts.map +1 -0
- package/dist/plugins/plugin-hooks.js +64 -0
- package/dist/plugins/plugin-hooks.js.map +1 -0
- package/dist/plugins/plugin-registry.d.ts +26 -0
- package/dist/plugins/plugin-registry.d.ts.map +1 -0
- package/dist/plugins/plugin-registry.js +150 -0
- package/dist/plugins/plugin-registry.js.map +1 -0
- package/dist/plugins/plugin-types.d.ts +95 -0
- package/dist/plugins/plugin-types.d.ts.map +1 -0
- package/dist/plugins/plugin-types.js +6 -0
- package/dist/plugins/plugin-types.js.map +1 -0
- package/dist/plugins/plugin-validation.d.ts +49 -0
- package/dist/plugins/plugin-validation.d.ts.map +1 -0
- package/dist/plugins/plugin-validation.js +295 -0
- package/dist/plugins/plugin-validation.js.map +1 -0
- package/dist/reactive/change-event.d.ts +44 -0
- package/dist/reactive/change-event.d.ts.map +1 -0
- package/dist/reactive/change-event.js +49 -0
- package/dist/reactive/change-event.js.map +1 -0
- package/dist/reactive/change-pubsub.d.ts +32 -0
- package/dist/reactive/change-pubsub.d.ts.map +1 -0
- package/dist/reactive/change-pubsub.js +31 -0
- package/dist/reactive/change-pubsub.js.map +1 -0
- package/dist/reactive/evaluate-query.d.ts +62 -0
- package/dist/reactive/evaluate-query.d.ts.map +1 -0
- package/dist/reactive/evaluate-query.js +57 -0
- package/dist/reactive/evaluate-query.js.map +1 -0
- package/dist/reactive/watch-by-id.d.ts +53 -0
- package/dist/reactive/watch-by-id.d.ts.map +1 -0
- package/dist/reactive/watch-by-id.js +55 -0
- package/dist/reactive/watch-by-id.js.map +1 -0
- package/dist/reactive/watch.d.ts +78 -0
- package/dist/reactive/watch.d.ts.map +1 -0
- package/dist/reactive/watch.js +133 -0
- package/dist/reactive/watch.js.map +1 -0
- package/dist/serializers/codecs/hjson.d.ts +33 -0
- package/dist/serializers/codecs/hjson.d.ts.map +1 -0
- package/dist/serializers/codecs/hjson.js +40 -0
- package/dist/serializers/codecs/hjson.js.map +1 -0
- package/dist/serializers/codecs/json.d.ts +22 -0
- package/dist/serializers/codecs/json.d.ts.map +1 -0
- package/dist/serializers/codecs/json.js +28 -0
- package/dist/serializers/codecs/json.js.map +1 -0
- package/dist/serializers/codecs/json5.d.ts +26 -0
- package/dist/serializers/codecs/json5.d.ts.map +1 -0
- package/dist/serializers/codecs/json5.js +33 -0
- package/dist/serializers/codecs/json5.js.map +1 -0
- package/dist/serializers/codecs/jsonc.d.ts +29 -0
- package/dist/serializers/codecs/jsonc.d.ts.map +1 -0
- package/dist/serializers/codecs/jsonc.js +38 -0
- package/dist/serializers/codecs/jsonc.js.map +1 -0
- package/dist/serializers/codecs/jsonl.d.ts +17 -0
- package/dist/serializers/codecs/jsonl.d.ts.map +1 -0
- package/dist/serializers/codecs/jsonl.js +31 -0
- package/dist/serializers/codecs/jsonl.js.map +1 -0
- package/dist/serializers/codecs/prose.d.ts +419 -0
- package/dist/serializers/codecs/prose.d.ts.map +1 -0
- package/dist/serializers/codecs/prose.js +1060 -0
- package/dist/serializers/codecs/prose.js.map +1 -0
- package/dist/serializers/codecs/toml.d.ts +23 -0
- package/dist/serializers/codecs/toml.d.ts.map +1 -0
- package/dist/serializers/codecs/toml.js +66 -0
- package/dist/serializers/codecs/toml.js.map +1 -0
- package/dist/serializers/codecs/toon.d.ts +20 -0
- package/dist/serializers/codecs/toon.d.ts.map +1 -0
- package/dist/serializers/codecs/toon.js +33 -0
- package/dist/serializers/codecs/toon.js.map +1 -0
- package/dist/serializers/codecs/yaml.d.ts +24 -0
- package/dist/serializers/codecs/yaml.d.ts.map +1 -0
- package/dist/serializers/codecs/yaml.js +31 -0
- package/dist/serializers/codecs/yaml.js.map +1 -0
- package/dist/serializers/format-codec.d.ts +53 -0
- package/dist/serializers/format-codec.d.ts.map +1 -0
- package/dist/serializers/format-codec.js +148 -0
- package/dist/serializers/format-codec.js.map +1 -0
- package/dist/serializers/presets.d.ts +48 -0
- package/dist/serializers/presets.d.ts.map +1 -0
- package/dist/serializers/presets.js +72 -0
- package/dist/serializers/presets.js.map +1 -0
- package/dist/serializers/serializer-service.d.ts +11 -0
- package/dist/serializers/serializer-service.d.ts.map +1 -0
- package/dist/serializers/serializer-service.js +4 -0
- package/dist/serializers/serializer-service.js.map +1 -0
- package/dist/state/collection-state.d.ts +19 -0
- package/dist/state/collection-state.d.ts.map +1 -0
- package/dist/state/collection-state.js +15 -0
- package/dist/state/collection-state.js.map +1 -0
- package/dist/state/state-operations.d.ts +38 -0
- package/dist/state/state-operations.d.ts.map +1 -0
- package/dist/state/state-operations.js +65 -0
- package/dist/state/state-operations.js.map +1 -0
- package/dist/storage/in-memory-adapter-layer.d.ts +16 -0
- package/dist/storage/in-memory-adapter-layer.d.ts.map +1 -0
- package/dist/storage/in-memory-adapter-layer.js +81 -0
- package/dist/storage/in-memory-adapter-layer.js.map +1 -0
- package/dist/storage/persistence-effect.d.ts +244 -0
- package/dist/storage/persistence-effect.d.ts.map +1 -0
- package/dist/storage/persistence-effect.js +551 -0
- package/dist/storage/persistence-effect.js.map +1 -0
- package/dist/storage/storage-service.d.ts +22 -0
- package/dist/storage/storage-service.d.ts.map +1 -0
- package/dist/storage/storage-service.js +4 -0
- package/dist/storage/storage-service.js.map +1 -0
- package/dist/storage/transforms.d.ts +183 -0
- package/dist/storage/transforms.d.ts.map +1 -0
- package/dist/storage/transforms.js +263 -0
- package/dist/storage/transforms.js.map +1 -0
- package/dist/transactions/transaction.d.ts +87 -0
- package/dist/transactions/transaction.d.ts.map +1 -0
- package/dist/transactions/transaction.js +240 -0
- package/dist/transactions/transaction.js.map +1 -0
- package/dist/types/aggregate-types.d.ts +73 -0
- package/dist/types/aggregate-types.d.ts.map +1 -0
- package/dist/types/aggregate-types.js +14 -0
- package/dist/types/aggregate-types.js.map +1 -0
- package/dist/types/computed-types.d.ts +71 -0
- package/dist/types/computed-types.d.ts.map +1 -0
- package/dist/types/computed-types.js +8 -0
- package/dist/types/computed-types.js.map +1 -0
- package/dist/types/crud-relationship-types.d.ts +180 -0
- package/dist/types/crud-relationship-types.d.ts.map +1 -0
- package/dist/types/crud-relationship-types.js +17 -0
- package/dist/types/crud-relationship-types.js.map +1 -0
- package/dist/types/crud-types.d.ts +343 -0
- package/dist/types/crud-types.d.ts.map +1 -0
- package/dist/types/crud-types.js +43 -0
- package/dist/types/crud-types.js.map +1 -0
- package/dist/types/cursor-types.d.ts +52 -0
- package/dist/types/cursor-types.d.ts.map +1 -0
- package/dist/types/cursor-types.js +2 -0
- package/dist/types/cursor-types.js.map +1 -0
- package/dist/types/database-config-types.d.ts +196 -0
- package/dist/types/database-config-types.d.ts.map +1 -0
- package/dist/types/database-config-types.js +11 -0
- package/dist/types/database-config-types.js.map +1 -0
- package/dist/types/hook-types.d.ts +158 -0
- package/dist/types/hook-types.d.ts.map +1 -0
- package/dist/types/hook-types.js +6 -0
- package/dist/types/hook-types.js.map +1 -0
- package/dist/types/index-types.d.ts +42 -0
- package/dist/types/index-types.d.ts.map +1 -0
- package/dist/types/index-types.js +8 -0
- package/dist/types/index-types.js.map +1 -0
- package/dist/types/operators.d.ts +5 -0
- package/dist/types/operators.d.ts.map +1 -0
- package/dist/types/operators.js +297 -0
- package/dist/types/operators.js.map +1 -0
- package/dist/types/query-overloads.d.ts +54 -0
- package/dist/types/query-overloads.d.ts.map +1 -0
- package/dist/types/query-overloads.js +3 -0
- package/dist/types/query-overloads.js.map +1 -0
- package/dist/types/reactive-types.d.ts +75 -0
- package/dist/types/reactive-types.d.ts.map +1 -0
- package/dist/types/reactive-types.js +7 -0
- package/dist/types/reactive-types.js.map +1 -0
- package/dist/types/schema-types.d.ts +56 -0
- package/dist/types/schema-types.d.ts.map +1 -0
- package/dist/types/schema-types.js +8 -0
- package/dist/types/schema-types.js.map +1 -0
- package/dist/types/search-types.d.ts +82 -0
- package/dist/types/search-types.d.ts.map +1 -0
- package/dist/types/search-types.js +110 -0
- package/dist/types/search-types.js.map +1 -0
- package/dist/types/types.d.ts +286 -0
- package/dist/types/types.d.ts.map +1 -0
- package/dist/types/types.js +2 -0
- package/dist/types/types.js.map +1 -0
- package/dist/utils/id-generator.d.ts +97 -0
- package/dist/utils/id-generator.d.ts.map +1 -0
- package/dist/utils/id-generator.js +247 -0
- package/dist/utils/id-generator.js.map +1 -0
- package/dist/utils/nested-path.d.ts +56 -0
- package/dist/utils/nested-path.d.ts.map +1 -0
- package/dist/utils/nested-path.js +119 -0
- package/dist/utils/nested-path.js.map +1 -0
- package/dist/utils/path.d.ts +16 -0
- package/dist/utils/path.d.ts.map +1 -0
- package/dist/utils/path.js +24 -0
- package/dist/utils/path.js.map +1 -0
- package/dist/validators/foreign-key.d.ts +49 -0
- package/dist/validators/foreign-key.d.ts.map +1 -0
- package/dist/validators/foreign-key.js +153 -0
- package/dist/validators/foreign-key.js.map +1 -0
- package/dist/validators/schema-validator.d.ts +19 -0
- package/dist/validators/schema-validator.d.ts.map +1 -0
- package/dist/validators/schema-validator.js +34 -0
- package/dist/validators/schema-validator.js.map +1 -0
- package/package.json +57 -0
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ID generation utility with uniqueness guarantees
|
|
3
|
+
* Provides various ID generation strategies for database entities
|
|
4
|
+
*/
|
|
5
|
+
// ============================================================================
|
|
6
|
+
// ID Generation Strategies
|
|
7
|
+
// ============================================================================
|
|
8
|
+
/**
|
|
9
|
+
* Counter for sequential IDs within a process
|
|
10
|
+
* Reset on process restart
|
|
11
|
+
*/
|
|
12
|
+
let sequentialCounter = 0;
|
|
13
|
+
/**
|
|
14
|
+
* Generate a timestamp-based ID with microsecond precision
|
|
15
|
+
* Format: timestamp-random-counter
|
|
16
|
+
* Example: "1704067200000-a3f2-0001"
|
|
17
|
+
*/
|
|
18
|
+
export function generateTimestampId() {
|
|
19
|
+
const timestamp = Date.now();
|
|
20
|
+
const random = Math.random().toString(36).substring(2, 6);
|
|
21
|
+
const counter = (++sequentialCounter).toString().padStart(4, "0");
|
|
22
|
+
return `${timestamp}-${random}-${counter}`;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Generate a nano ID - URL-safe, short, unique identifier
|
|
26
|
+
* Uses a larger alphabet for better uniqueness in shorter strings
|
|
27
|
+
*/
|
|
28
|
+
export function generateNanoId(length = 21) {
|
|
29
|
+
const alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_";
|
|
30
|
+
let id = "";
|
|
31
|
+
// Use crypto for better randomness if available
|
|
32
|
+
if (typeof crypto !== "undefined" && crypto.getRandomValues) {
|
|
33
|
+
const bytes = new Uint8Array(length);
|
|
34
|
+
crypto.getRandomValues(bytes);
|
|
35
|
+
for (let i = 0; i < length; i++) {
|
|
36
|
+
id += alphabet[bytes[i] % alphabet.length];
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
// Fallback to Math.random
|
|
41
|
+
for (let i = 0; i < length; i++) {
|
|
42
|
+
id += alphabet[Math.floor(Math.random() * alphabet.length)];
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return id;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Generate a UUID v4 compliant identifier
|
|
49
|
+
* Standard format: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
|
|
50
|
+
*/
|
|
51
|
+
export function generateUUID() {
|
|
52
|
+
if (typeof crypto !== "undefined" && crypto.randomUUID) {
|
|
53
|
+
return crypto.randomUUID();
|
|
54
|
+
}
|
|
55
|
+
// Fallback implementation
|
|
56
|
+
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
|
|
57
|
+
const r = (Math.random() * 16) | 0;
|
|
58
|
+
const v = c === "x" ? r : (r & 0x3) | 0x8;
|
|
59
|
+
return v.toString(16);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Generate a prefixed ID for better organization
|
|
64
|
+
* Format: prefix_id
|
|
65
|
+
* Example: "user_1704067200000-a3f2-0001"
|
|
66
|
+
*/
|
|
67
|
+
export function generatePrefixedId(prefix) {
|
|
68
|
+
const id = generateTimestampId();
|
|
69
|
+
return `${prefix}_${id}`;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Generate a ULID (Universally Unique Lexicographically Sortable Identifier)
|
|
73
|
+
* Sortable by creation time, case-insensitive
|
|
74
|
+
*/
|
|
75
|
+
export function generateULID() {
|
|
76
|
+
const timestamp = Date.now();
|
|
77
|
+
const timestampChars = encodeTime(timestamp, 10);
|
|
78
|
+
const randomChars = encodeRandom(16);
|
|
79
|
+
return timestampChars + randomChars;
|
|
80
|
+
}
|
|
81
|
+
// ULID helper functions
|
|
82
|
+
const ENCODING = "0123456789ABCDEFGHJKMNPQRSTVWXYZ"; // Crockford's Base32
|
|
83
|
+
function encodeTime(timestamp, length) {
|
|
84
|
+
let str = "";
|
|
85
|
+
for (let i = length - 1; i >= 0; i--) {
|
|
86
|
+
const mod = timestamp % ENCODING.length;
|
|
87
|
+
str = ENCODING[mod] + str;
|
|
88
|
+
timestamp = Math.floor(timestamp / ENCODING.length);
|
|
89
|
+
}
|
|
90
|
+
return str;
|
|
91
|
+
}
|
|
92
|
+
function encodeRandom(length) {
|
|
93
|
+
let str = "";
|
|
94
|
+
for (let i = 0; i < length; i++) {
|
|
95
|
+
str += ENCODING[Math.floor(Math.random() * ENCODING.length)];
|
|
96
|
+
}
|
|
97
|
+
return str;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Generate a sortable ID that includes type information
|
|
101
|
+
* Format: type:timestamp:random
|
|
102
|
+
* Example: "user:1704067200000:a3f2"
|
|
103
|
+
*/
|
|
104
|
+
export function generateTypedId(type) {
|
|
105
|
+
const timestamp = Date.now();
|
|
106
|
+
const random = generateNanoId(4);
|
|
107
|
+
return `${type}:${timestamp}:${random}`;
|
|
108
|
+
}
|
|
109
|
+
// ============================================================================
|
|
110
|
+
// ID Validation
|
|
111
|
+
// ============================================================================
|
|
112
|
+
/**
|
|
113
|
+
* Check if a string is a valid ID format
|
|
114
|
+
*/
|
|
115
|
+
export function isValidId(id) {
|
|
116
|
+
return typeof id === "string" && id.length > 0 && !id.includes("\0");
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Check if ID matches expected format
|
|
120
|
+
*/
|
|
121
|
+
export function isValidIdFormat(id, format) {
|
|
122
|
+
switch (format) {
|
|
123
|
+
case "uuid":
|
|
124
|
+
return /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(id);
|
|
125
|
+
case "ulid":
|
|
126
|
+
return /^[0-9A-Z]{26}$/i.test(id);
|
|
127
|
+
case "timestamp":
|
|
128
|
+
return /^\d{13}-[a-z0-9]{4}-\d{4}$/.test(id);
|
|
129
|
+
case "nano":
|
|
130
|
+
return /^[0-9A-Za-z_-]+$/.test(id);
|
|
131
|
+
default:
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Default ID generator configuration
|
|
137
|
+
*/
|
|
138
|
+
export const defaultIdConfig = {
|
|
139
|
+
strategy: "nano",
|
|
140
|
+
length: 21,
|
|
141
|
+
};
|
|
142
|
+
/**
|
|
143
|
+
* Create an ID generator with specific configuration
|
|
144
|
+
*/
|
|
145
|
+
export function createIdGenerator(config = defaultIdConfig) {
|
|
146
|
+
switch (config.strategy) {
|
|
147
|
+
case "timestamp":
|
|
148
|
+
return generateTimestampId;
|
|
149
|
+
case "nano":
|
|
150
|
+
return () => generateNanoId(config.length);
|
|
151
|
+
case "uuid":
|
|
152
|
+
return generateUUID;
|
|
153
|
+
case "ulid":
|
|
154
|
+
return generateULID;
|
|
155
|
+
case "prefixed": {
|
|
156
|
+
if (!config.prefix) {
|
|
157
|
+
throw new Error("Prefix required for prefixed ID strategy");
|
|
158
|
+
}
|
|
159
|
+
const prefix = config.prefix;
|
|
160
|
+
return () => generatePrefixedId(prefix);
|
|
161
|
+
}
|
|
162
|
+
case "typed": {
|
|
163
|
+
if (!config.type) {
|
|
164
|
+
throw new Error("Type required for typed ID strategy");
|
|
165
|
+
}
|
|
166
|
+
const type = config.type;
|
|
167
|
+
return () => generateTypedId(type);
|
|
168
|
+
}
|
|
169
|
+
default:
|
|
170
|
+
throw new Error(`Unknown ID strategy: ${config.strategy}`);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
// ============================================================================
|
|
174
|
+
// Default Export
|
|
175
|
+
// ============================================================================
|
|
176
|
+
/**
|
|
177
|
+
* Default ID generator using nano ID strategy
|
|
178
|
+
*/
|
|
179
|
+
export const generateId = createIdGenerator(defaultIdConfig);
|
|
180
|
+
/**
|
|
181
|
+
* Collection-specific ID generators
|
|
182
|
+
* Allows different ID strategies per collection
|
|
183
|
+
*/
|
|
184
|
+
export class CollectionIdGenerators {
|
|
185
|
+
generators = new Map();
|
|
186
|
+
defaultGenerator;
|
|
187
|
+
constructor(defaultConfig = defaultIdConfig) {
|
|
188
|
+
this.defaultGenerator = createIdGenerator(defaultConfig);
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Register a custom ID generator for a collection
|
|
192
|
+
*/
|
|
193
|
+
register(collection, config) {
|
|
194
|
+
this.generators.set(collection, createIdGenerator(config));
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Get ID generator for a collection
|
|
198
|
+
*/
|
|
199
|
+
getGenerator(collection) {
|
|
200
|
+
return this.generators.get(collection) || this.defaultGenerator;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Generate ID for a collection
|
|
204
|
+
*/
|
|
205
|
+
generateFor(collection) {
|
|
206
|
+
return this.getGenerator(collection)();
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
// ============================================================================
|
|
210
|
+
// ID Utilities
|
|
211
|
+
// ============================================================================
|
|
212
|
+
/**
|
|
213
|
+
* Extract timestamp from timestamp-based IDs
|
|
214
|
+
*/
|
|
215
|
+
export function extractTimestamp(id) {
|
|
216
|
+
// Handle timestamp format
|
|
217
|
+
const timestampMatch = id.match(/^(\d{13})-/);
|
|
218
|
+
if (timestampMatch) {
|
|
219
|
+
return parseInt(timestampMatch[1], 10);
|
|
220
|
+
}
|
|
221
|
+
// Handle typed format
|
|
222
|
+
const typedMatch = id.match(/:(\d{13}):/);
|
|
223
|
+
if (typedMatch) {
|
|
224
|
+
return parseInt(typedMatch[1], 10);
|
|
225
|
+
}
|
|
226
|
+
return null;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Extract type from typed IDs
|
|
230
|
+
*/
|
|
231
|
+
export function extractType(id) {
|
|
232
|
+
const match = id.match(/^([^:]+):/);
|
|
233
|
+
return match ? match[1] : null;
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Compare IDs for sorting (works with timestamp-based IDs)
|
|
237
|
+
*/
|
|
238
|
+
export function compareIds(a, b) {
|
|
239
|
+
const timestampA = extractTimestamp(a);
|
|
240
|
+
const timestampB = extractTimestamp(b);
|
|
241
|
+
if (timestampA !== null && timestampB !== null) {
|
|
242
|
+
return timestampA - timestampB;
|
|
243
|
+
}
|
|
244
|
+
// Fallback to string comparison
|
|
245
|
+
return a.localeCompare(b);
|
|
246
|
+
}
|
|
247
|
+
//# sourceMappingURL=id-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"id-generator.js","sourceRoot":"","sources":["../../src/utils/id-generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utilities for resolving and mutating nested object paths using dot notation.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Check if a string is a dot-notation path (contains at least one ".").
|
|
6
|
+
*
|
|
7
|
+
* @param key - The string to check
|
|
8
|
+
* @returns true if the key contains a dot
|
|
9
|
+
*/
|
|
10
|
+
export declare function isDotPath(key: string): boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Get a nested value from an object using dot notation.
|
|
13
|
+
* Handles single-segment paths (no ".") as direct property access with no overhead.
|
|
14
|
+
*
|
|
15
|
+
* @param obj - The object to get the value from
|
|
16
|
+
* @param path - The dot-separated path to the value (e.g., "metadata.views")
|
|
17
|
+
* @returns The value at the path, or undefined if not found
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* getNestedValue({ a: { b: 1 } }, "a.b") // returns 1
|
|
21
|
+
* getNestedValue({ a: { b: 1 } }, "a") // returns { b: 1 }
|
|
22
|
+
* getNestedValue({ a: { b: 1 } }, "a.c") // returns undefined
|
|
23
|
+
* getNestedValue({ name: "foo" }, "name") // returns "foo" (single-segment, direct access)
|
|
24
|
+
*/
|
|
25
|
+
export declare function getNestedValue(obj: Record<string, unknown>, path: string): unknown;
|
|
26
|
+
/**
|
|
27
|
+
* Recursively collect all paths in an object that have string values.
|
|
28
|
+
* Used for auto-discovering searchable fields when no explicit fields are specified.
|
|
29
|
+
*
|
|
30
|
+
* @param obj - The object to traverse
|
|
31
|
+
* @param prefix - The current path prefix (used during recursion)
|
|
32
|
+
* @returns An array of dot-notation paths pointing to string values
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* collectStringPaths({ name: "foo", metadata: { description: "bar", count: 5 } })
|
|
36
|
+
* // returns ["name", "metadata.description"]
|
|
37
|
+
*/
|
|
38
|
+
export declare function collectStringPaths(obj: Record<string, unknown>, prefix?: string): ReadonlyArray<string>;
|
|
39
|
+
/**
|
|
40
|
+
* Set a nested value on an object using dot notation, returning a new object (immutable).
|
|
41
|
+
* Creates intermediate objects along the path if they don't exist.
|
|
42
|
+
* Handles single-segment paths (no ".") as direct property set with no overhead.
|
|
43
|
+
*
|
|
44
|
+
* @param obj - The source object
|
|
45
|
+
* @param path - The dot-separated path where to set the value (e.g., "metadata.views")
|
|
46
|
+
* @param value - The value to set
|
|
47
|
+
* @returns A new object with the value set at the path
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* setNestedValue({ a: { b: 1 } }, "a.b", 2) // returns { a: { b: 2 } }
|
|
51
|
+
* setNestedValue({ a: { b: 1 } }, "a.c", 3) // returns { a: { b: 1, c: 3 } }
|
|
52
|
+
* setNestedValue({}, "a.b.c", 1) // returns { a: { b: { c: 1 } } }
|
|
53
|
+
* setNestedValue({ name: "foo" }, "name", "bar") // returns { name: "bar" } (single-segment)
|
|
54
|
+
*/
|
|
55
|
+
export declare function setNestedValue(obj: Record<string, unknown>, path: string, value: unknown): Record<string, unknown>;
|
|
56
|
+
//# sourceMappingURL=nested-path.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nested-path.d.ts","sourceRoot":"","sources":["../../src/utils/nested-path.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAE9C;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAC7B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,IAAI,EAAE,MAAM,GACV,OAAO,CAuBT;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CACjC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,MAAM,SAAK,GACT,aAAa,CAAC,MAAM,CAAC,CAmBvB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,cAAc,CAC7B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,OAAO,GACZ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA+BzB"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utilities for resolving and mutating nested object paths using dot notation.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Check if a string is a dot-notation path (contains at least one ".").
|
|
6
|
+
*
|
|
7
|
+
* @param key - The string to check
|
|
8
|
+
* @returns true if the key contains a dot
|
|
9
|
+
*/
|
|
10
|
+
export function isDotPath(key) {
|
|
11
|
+
return key.includes(".");
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Get a nested value from an object using dot notation.
|
|
15
|
+
* Handles single-segment paths (no ".") as direct property access with no overhead.
|
|
16
|
+
*
|
|
17
|
+
* @param obj - The object to get the value from
|
|
18
|
+
* @param path - The dot-separated path to the value (e.g., "metadata.views")
|
|
19
|
+
* @returns The value at the path, or undefined if not found
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* getNestedValue({ a: { b: 1 } }, "a.b") // returns 1
|
|
23
|
+
* getNestedValue({ a: { b: 1 } }, "a") // returns { b: 1 }
|
|
24
|
+
* getNestedValue({ a: { b: 1 } }, "a.c") // returns undefined
|
|
25
|
+
* getNestedValue({ name: "foo" }, "name") // returns "foo" (single-segment, direct access)
|
|
26
|
+
*/
|
|
27
|
+
export function getNestedValue(obj, path) {
|
|
28
|
+
// Fast path: single-segment path (no dot) - direct property access
|
|
29
|
+
if (!isDotPath(path)) {
|
|
30
|
+
return obj[path];
|
|
31
|
+
}
|
|
32
|
+
// Multi-segment path: traverse the object
|
|
33
|
+
const parts = path.split(".");
|
|
34
|
+
let current = obj;
|
|
35
|
+
for (const part of parts) {
|
|
36
|
+
if (current === null || current === undefined) {
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
if (typeof current === "object") {
|
|
40
|
+
current = current[part];
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return current;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Recursively collect all paths in an object that have string values.
|
|
50
|
+
* Used for auto-discovering searchable fields when no explicit fields are specified.
|
|
51
|
+
*
|
|
52
|
+
* @param obj - The object to traverse
|
|
53
|
+
* @param prefix - The current path prefix (used during recursion)
|
|
54
|
+
* @returns An array of dot-notation paths pointing to string values
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* collectStringPaths({ name: "foo", metadata: { description: "bar", count: 5 } })
|
|
58
|
+
* // returns ["name", "metadata.description"]
|
|
59
|
+
*/
|
|
60
|
+
export function collectStringPaths(obj, prefix = "") {
|
|
61
|
+
const paths = [];
|
|
62
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
63
|
+
const path = prefix ? `${prefix}.${key}` : key;
|
|
64
|
+
if (typeof value === "string") {
|
|
65
|
+
paths.push(path);
|
|
66
|
+
}
|
|
67
|
+
else if (value !== null &&
|
|
68
|
+
typeof value === "object" &&
|
|
69
|
+
!Array.isArray(value)) {
|
|
70
|
+
// Recurse into nested objects (but not arrays)
|
|
71
|
+
paths.push(...collectStringPaths(value, path));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return paths;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Set a nested value on an object using dot notation, returning a new object (immutable).
|
|
78
|
+
* Creates intermediate objects along the path if they don't exist.
|
|
79
|
+
* Handles single-segment paths (no ".") as direct property set with no overhead.
|
|
80
|
+
*
|
|
81
|
+
* @param obj - The source object
|
|
82
|
+
* @param path - The dot-separated path where to set the value (e.g., "metadata.views")
|
|
83
|
+
* @param value - The value to set
|
|
84
|
+
* @returns A new object with the value set at the path
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* setNestedValue({ a: { b: 1 } }, "a.b", 2) // returns { a: { b: 2 } }
|
|
88
|
+
* setNestedValue({ a: { b: 1 } }, "a.c", 3) // returns { a: { b: 1, c: 3 } }
|
|
89
|
+
* setNestedValue({}, "a.b.c", 1) // returns { a: { b: { c: 1 } } }
|
|
90
|
+
* setNestedValue({ name: "foo" }, "name", "bar") // returns { name: "bar" } (single-segment)
|
|
91
|
+
*/
|
|
92
|
+
export function setNestedValue(obj, path, value) {
|
|
93
|
+
// Fast path: single-segment path (no dot) - direct property set
|
|
94
|
+
if (!isDotPath(path)) {
|
|
95
|
+
return { ...obj, [path]: value };
|
|
96
|
+
}
|
|
97
|
+
// Multi-segment path: build the nested structure
|
|
98
|
+
const parts = path.split(".");
|
|
99
|
+
const result = { ...obj };
|
|
100
|
+
let current = result;
|
|
101
|
+
// Navigate/create to the parent of the leaf
|
|
102
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
103
|
+
const part = parts[i];
|
|
104
|
+
const existing = current[part];
|
|
105
|
+
// Copy or create the intermediate object
|
|
106
|
+
if (existing !== null && typeof existing === "object") {
|
|
107
|
+
current[part] = { ...existing };
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
current[part] = {};
|
|
111
|
+
}
|
|
112
|
+
current = current[part];
|
|
113
|
+
}
|
|
114
|
+
// Set the leaf value
|
|
115
|
+
const leafKey = parts[parts.length - 1];
|
|
116
|
+
current[leafKey] = value;
|
|
117
|
+
return result;
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=nested-path.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nested-path.js","sourceRoot":"","sources":["../../src/utils/nested-path.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Path utilities for file operations.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Extract the file extension from a file path without the leading dot.
|
|
6
|
+
*
|
|
7
|
+
* @param filePath - The file path to extract extension from
|
|
8
|
+
* @returns The file extension without the dot, or empty string if no extension
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* getFileExtension('/path/to/file.json') // returns 'json'
|
|
12
|
+
* getFileExtension('/path/to/file.data.yaml') // returns 'yaml'
|
|
13
|
+
* getFileExtension('/path/to/file') // returns ''
|
|
14
|
+
*/
|
|
15
|
+
export declare function getFileExtension(filePath: string): string;
|
|
16
|
+
//# sourceMappingURL=path.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path.d.ts","sourceRoot":"","sources":["../../src/utils/path.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAazD"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Path utilities for file operations.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Extract the file extension from a file path without the leading dot.
|
|
6
|
+
*
|
|
7
|
+
* @param filePath - The file path to extract extension from
|
|
8
|
+
* @returns The file extension without the dot, or empty string if no extension
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* getFileExtension('/path/to/file.json') // returns 'json'
|
|
12
|
+
* getFileExtension('/path/to/file.data.yaml') // returns 'yaml'
|
|
13
|
+
* getFileExtension('/path/to/file') // returns ''
|
|
14
|
+
*/
|
|
15
|
+
export function getFileExtension(filePath) {
|
|
16
|
+
const lastDotIndex = filePath.lastIndexOf(".");
|
|
17
|
+
const lastSlashIndex = Math.max(filePath.lastIndexOf("/"), filePath.lastIndexOf("\\"));
|
|
18
|
+
// If there's no dot, or the dot is before the last slash/backslash (part of directory name)
|
|
19
|
+
if (lastDotIndex === -1 || lastDotIndex <= lastSlashIndex) {
|
|
20
|
+
return "";
|
|
21
|
+
}
|
|
22
|
+
return filePath.slice(lastDotIndex + 1).toLowerCase();
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=path.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path.js","sourceRoot":"","sources":["../../src/utils/path.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;;;;;;GAUG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAgB;IAChD,MAAM,YAAY,GAAG,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAC/C,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,CAC9B,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,EACzB,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,CAC1B,CAAC;IAEF,4FAA4F;IAC5F,IAAI,YAAY,KAAK,CAAC,CAAC,IAAI,YAAY,IAAI,cAAc,EAAE,CAAC;QAC3D,OAAO,EAAE,CAAC;IACX,CAAC;IAED,OAAO,QAAQ,CAAC,KAAK,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;AACvD,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Foreign key validation system.
|
|
3
|
+
*
|
|
4
|
+
* Effect-based validators use Ref<ReadonlyMap> for O(1) lookups.
|
|
5
|
+
*/
|
|
6
|
+
import { Effect, Ref } from "effect";
|
|
7
|
+
import { ForeignKeyError } from "../errors/crud-errors.js";
|
|
8
|
+
import type { ForeignKeyValidation } from "../types/crud-types.js";
|
|
9
|
+
import type { RelationshipDef } from "../types/types.js";
|
|
10
|
+
type HasId = {
|
|
11
|
+
readonly id: string;
|
|
12
|
+
};
|
|
13
|
+
type RelationshipConfig = {
|
|
14
|
+
readonly type: "ref" | "inverse";
|
|
15
|
+
readonly target?: string;
|
|
16
|
+
readonly foreignKey?: string;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Extract foreign key configurations from relationships
|
|
20
|
+
*/
|
|
21
|
+
export declare function extractForeignKeyConfigs(relationships: Record<string, RelationshipDef<unknown, "ref" | "inverse", string>>): ForeignKeyValidation[];
|
|
22
|
+
/**
|
|
23
|
+
* Validate foreign keys for an entity using Ref-based state.
|
|
24
|
+
* Returns Effect that fails with ForeignKeyError if a violation is found.
|
|
25
|
+
*
|
|
26
|
+
* Uses ReadonlyMap for O(1) lookups instead of legacy array scanning.
|
|
27
|
+
*/
|
|
28
|
+
export declare const validateForeignKeysEffect: <T extends HasId>(entity: T, collectionName: string, relationships: Record<string, RelationshipConfig>, stateRefs: Record<string, Ref.Ref<ReadonlyMap<string, HasId>>>) => Effect.Effect<void, ForeignKeyError>;
|
|
29
|
+
/**
|
|
30
|
+
* Check if deleting an entity would violate foreign key constraints.
|
|
31
|
+
* Scans all collections for "ref" relationships targeting this collection
|
|
32
|
+
* whose foreign key field references the entity being deleted.
|
|
33
|
+
*
|
|
34
|
+
* Returns Effect that fails with ForeignKeyError if violations exist.
|
|
35
|
+
*/
|
|
36
|
+
export declare const checkDeleteConstraintsEffect: (entityId: string, collectionName: string, allRelationships: Record<string, Record<string, RelationshipConfig>>, stateRefs: Record<string, Ref.Ref<ReadonlyMap<string, HasId>>>) => Effect.Effect<void, ForeignKeyError>;
|
|
37
|
+
/**
|
|
38
|
+
* Check referential integrity for an entire database using Ref-based state.
|
|
39
|
+
* Returns Effect with a list of violations.
|
|
40
|
+
*/
|
|
41
|
+
export declare const checkReferentialIntegrityEffect: (allRelationships: Record<string, Record<string, RelationshipConfig>>, stateRefs: Record<string, Ref.Ref<ReadonlyMap<string, HasId>>>) => Effect.Effect<ReadonlyArray<{
|
|
42
|
+
readonly collection: string;
|
|
43
|
+
readonly entityId: string;
|
|
44
|
+
readonly field: string;
|
|
45
|
+
readonly invalidReference: unknown;
|
|
46
|
+
readonly targetCollection: string;
|
|
47
|
+
}>>;
|
|
48
|
+
export {};
|
|
49
|
+
//# sourceMappingURL=foreign-key.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"foreign-key.d.ts","sourceRoot":"","sources":["../../src/validators/foreign-key.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAC;AACrC,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAMzD,KAAK,KAAK,GAAG;IAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAErC,KAAK,kBAAkB,GAAG;IACzB,QAAQ,CAAC,IAAI,EAAE,KAAK,GAAG,SAAS,CAAC;IACjC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC7B,CAAC;AAMF;;GAEG;AACH,wBAAgB,wBAAwB,CACvC,aAAa,EAAE,MAAM,CACpB,MAAM,EACN,eAAe,CAAC,OAAO,EAAE,KAAK,GAAG,SAAS,EAAE,MAAM,CAAC,CACnD,GACC,oBAAoB,EAAE,CAoBxB;AAMD;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,GAAI,CAAC,SAAS,KAAK,EACxD,QAAQ,CAAC,EACT,gBAAgB,MAAM,EACtB,eAAe,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,EACjD,WAAW,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,KAC5D,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,eAAe,CAoDrC,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B,GACxC,UAAU,MAAM,EAChB,gBAAgB,MAAM,EACtB,kBAAkB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC,EACpE,WAAW,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,KAC5D,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,eAAe,CAkCnC,CAAC;AAEJ;;;GAGG;AACH,eAAO,MAAM,+BAA+B,GAC3C,kBAAkB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC,EACpE,WAAW,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,KAC5D,MAAM,CAAC,MAAM,CACf,aAAa,CAAC;IACb,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;IACnC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;CAClC,CAAC,CAyDA,CAAC"}
|