@owlmeans/mongo-resource 0.1.18-rc.8 → 0.1.18
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 +232 -71
- package/agent-meta/manifest.json +3 -3
- package/agent-meta/skills/mongo-resource/SKILL.md +89 -44
- package/build/consts.d.ts +8 -4
- package/build/consts.d.ts.map +1 -1
- package/build/consts.js +8 -4
- package/build/consts.js.map +1 -1
- package/build/declarations/types.d.ts +12 -0
- package/build/declarations/types.d.ts.map +1 -0
- package/build/declarations/types.js +2 -0
- package/build/declarations/types.js.map +1 -0
- package/build/declarations.d.ts +4 -9
- package/build/declarations.d.ts.map +1 -1
- package/build/declarations.js +28 -21
- package/build/declarations.js.map +1 -1
- package/build/index.d.ts +4 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +1 -0
- package/build/index.js.map +1 -1
- package/build/resource.d.ts +2 -2
- package/build/resource.d.ts.map +1 -1
- package/build/resource.js +100 -130
- package/build/resource.js.map +1 -1
- package/build/types.d.ts +11 -5
- package/build/types.d.ts.map +1 -1
- package/build/types.local.d.ts +4 -0
- package/build/types.local.d.ts.map +1 -0
- package/build/types.local.js +2 -0
- package/build/types.local.js.map +1 -0
- package/build/utils/consts.local.d.ts +25 -0
- package/build/utils/consts.local.d.ts.map +1 -0
- package/build/utils/consts.local.js +31 -0
- package/build/utils/consts.local.js.map +1 -0
- package/build/utils/criteria/types.d.ts +27 -0
- package/build/utils/criteria/types.d.ts.map +1 -0
- package/build/utils/criteria/types.js +2 -0
- package/build/utils/criteria/types.js.map +1 -0
- package/build/utils/criteria.d.ts +9 -0
- package/build/utils/criteria.d.ts.map +1 -0
- package/build/utils/criteria.js +204 -0
- package/build/utils/criteria.js.map +1 -0
- package/build/utils/index.d.ts +1 -0
- package/build/utils/index.d.ts.map +1 -1
- package/build/utils/index.js +1 -0
- package/build/utils/index.js.map +1 -1
- package/build/utils/indexes/types.d.ts +19 -0
- package/build/utils/indexes/types.d.ts.map +1 -0
- package/build/utils/indexes/types.js +2 -0
- package/build/utils/indexes/types.js.map +1 -0
- package/build/utils/indexes.d.ts +3 -4
- package/build/utils/indexes.d.ts.map +1 -1
- package/build/utils/indexes.js +44 -28
- package/build/utils/indexes.js.map +1 -1
- package/build/utils/life-cycle/types.d.ts +36 -0
- package/build/utils/life-cycle/types.d.ts.map +1 -0
- package/build/utils/life-cycle/types.js +2 -0
- package/build/utils/life-cycle/types.js.map +1 -0
- package/build/utils/life-cycle.d.ts +3 -30
- package/build/utils/life-cycle.d.ts.map +1 -1
- package/build/utils/life-cycle.js +96 -112
- package/build/utils/life-cycle.js.map +1 -1
- package/build/utils/migrations.d.ts.map +1 -1
- package/build/utils/migrations.js +1 -2
- package/build/utils/migrations.js.map +1 -1
- package/build/utils/name.d.ts.map +1 -1
- package/build/utils/name.js +1 -5
- package/build/utils/name.js.map +1 -1
- package/build/utils/refs/types.d.ts +78 -0
- package/build/utils/refs/types.d.ts.map +1 -0
- package/build/utils/refs/types.js +2 -0
- package/build/utils/refs/types.js.map +1 -0
- package/build/utils/refs.d.ts +13 -67
- package/build/utils/refs.d.ts.map +1 -1
- package/build/utils/refs.js +115 -158
- package/build/utils/refs.js.map +1 -1
- package/build/utils/schema/types.d.ts +16 -0
- package/build/utils/schema/types.d.ts.map +1 -0
- package/build/utils/schema/types.js +2 -0
- package/build/utils/schema/types.js.map +1 -0
- package/build/utils/schema.d.ts +3 -11
- package/build/utils/schema.d.ts.map +1 -1
- package/build/utils/schema.js +86 -88
- package/build/utils/schema.js.map +1 -1
- package/build/utils/types.local.d.ts +13 -0
- package/build/utils/types.local.d.ts.map +1 -0
- package/build/utils/types.local.js +2 -0
- package/build/utils/types.local.js.map +1 -0
- package/package.json +10 -9
- package/src/consts.ts +8 -4
- package/src/declarations/types.ts +12 -0
- package/src/declarations.ts +32 -28
- package/src/index.ts +4 -0
- package/src/resource.ts +121 -163
- package/src/types.local.ts +5 -0
- package/src/types.ts +13 -7
- package/src/utils/consts.local.ts +35 -0
- package/src/utils/criteria/types.ts +28 -0
- package/src/utils/criteria.ts +235 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/indexes/types.ts +20 -0
- package/src/utils/indexes.ts +48 -28
- package/src/utils/life-cycle/types.ts +39 -0
- package/src/utils/life-cycle.ts +120 -134
- package/src/utils/migrations.ts +3 -17
- package/src/utils/name.ts +1 -6
- package/src/utils/refs/types.ts +79 -0
- package/src/utils/refs.ts +147 -189
- package/src/utils/schema/types.ts +17 -0
- package/src/utils/schema.ts +92 -91
- package/src/utils/types.local.ts +13 -0
- package/tests/context.ts +3 -3
- package/tests/criteria.spec.ts +116 -0
- package/tests/crud.spec.ts +2 -2
- package/tests/indexes.spec.ts +42 -0
- package/tests/refs.spec.ts +5 -3
- package/build/.gitkeep +0 -0
package/build/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Resource, ResourceRecord, ResourceDbService, DbLocker,
|
|
1
|
+
import type { Resource, ResourceRecord, ResourceDbService, DbLocker, LockableResource, MigratableResource, MigrationRegistry } from '@owlmeans/resource';
|
|
2
2
|
import type { Collection, CreateIndexesOptions, Db, IndexSpecification, MongoClient } from 'mongodb';
|
|
3
3
|
import type { AnySchema } from 'ajv';
|
|
4
4
|
/**
|
|
@@ -38,7 +38,7 @@ export interface MongoRefOptions {
|
|
|
38
38
|
resource?: string;
|
|
39
39
|
noIndex?: boolean;
|
|
40
40
|
}
|
|
41
|
-
export interface MongoResource<T extends ResourceRecord> extends Resource<T>,
|
|
41
|
+
export interface MongoResource<T extends ResourceRecord> extends Resource<T>, LockableResource<T>, MigratableResource<MongoTx, MongoResource<T>> {
|
|
42
42
|
name?: string;
|
|
43
43
|
/**
|
|
44
44
|
* The db-config alias this resource was registered against.
|
|
@@ -59,13 +59,14 @@ export interface MongoResource<T extends ResourceRecord> extends Resource<T>, Re
|
|
|
59
59
|
collection: Collection;
|
|
60
60
|
db: () => Promise<Db>;
|
|
61
61
|
client: () => Promise<MongoClient>;
|
|
62
|
-
index:
|
|
62
|
+
index: (name: string, index: IndexSpecification, options?: CreateIndexesOptions) => this;
|
|
63
63
|
/**
|
|
64
64
|
* Declare that a field stores another record's id.
|
|
65
65
|
*
|
|
66
66
|
* Chainable and idempotent like {@link MigratableResource.migration}, and stored the same
|
|
67
|
-
* way — per alias at module scope —
|
|
68
|
-
*
|
|
67
|
+
* way — per alias at module scope — so a maker that runs more than once for the same alias
|
|
68
|
+
* re-declares the same entry rather than losing it. A lost declaration would silently stop
|
|
69
|
+
* the string/ObjectId conversion for the field.
|
|
69
70
|
*
|
|
70
71
|
* Declare only fields whose values really are mongo ids (assigned from another record's
|
|
71
72
|
* `id`). Composite keys, external provider ids, DIDs and business slugs must stay
|
|
@@ -78,4 +79,9 @@ export interface MongoResource<T extends ResourceRecord> extends Resource<T>, Re
|
|
|
78
79
|
}
|
|
79
80
|
export interface MongoDbService extends ResourceDbService<Db, MongoClient>, DbLocker<ResourceRecord> {
|
|
80
81
|
}
|
|
82
|
+
export interface MongoDeclaration {
|
|
83
|
+
migrations: MigrationRegistry<MongoTx>;
|
|
84
|
+
/** Declared ObjectId references, keyed by field. Registered via `resource.reference()`. */
|
|
85
|
+
references: Map<string, MongoReference>;
|
|
86
|
+
}
|
|
81
87
|
//# sourceMappingURL=types.d.ts.map
|
package/build/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,iBAAiB,EAAE,QAAQ,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AACxJ,OAAO,KAAK,EAAE,UAAU,EAAE,oBAAoB,EAAE,EAAE,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AACpG,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,KAAK,CAAA;AAEpC;;;;;;;GAOG;AACH,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,EAAE,CAAA;IACN,wCAAwC;IACxC,UAAU,EAAE,UAAU,CAAA;IACtB,yFAAyF;IACzF,GAAG,EAAE,CAAC,KAAK,CAAC,EAAE,MAAM,KAAK,UAAU,CAAA;IACnC,mGAAmG;IACnG,GAAG,EAAE,CAAC,KAAK,CAAC,EAAE,MAAM,KAAK,MAAM,CAAA;CAChC;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,cAAc;IAC7B,wFAAwF;IACxF,KAAK,EAAE,MAAM,CAAA;IACb,sFAAsF;IACtF,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,iDAAiD;IACjD,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,MAAM,WAAW,aAAa,CAAC,CAAC,SAAS,cAAc,CAAE,SAAQ,QAAQ,CAAC,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAC/F,kBAAkB,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC;IAC7C,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,MAAM,CAAC,EAAE,SAAS,CAAA;IAClB,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,kBAAkB,CAAC;QAAC,OAAO,CAAC,EAAE,oBAAoB,CAAA;KAAE,CAAC,CAAA;IAC5F,UAAU,EAAE,UAAU,CAAA;IACtB,EAAE,EAAE,MAAM,OAAO,CAAC,EAAE,CAAC,CAAA;IACrB,MAAM,EAAE,MAAM,OAAO,CAAC,WAAW,CAAC,CAAA;IAClC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,EAAE,OAAO,CAAC,EAAE,oBAAoB,KAAK,IAAI,CAAA;IACxF;;;;;;;;;;;OAWG;IACH,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,eAAe,KAAK,IAAI,CAAA;IACnE,6CAA6C;IAC7C,UAAU,EAAE,MAAM,cAAc,EAAE,CAAA;IAClC,WAAW,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,CAAA;CAC9B;AAED,MAAM,WAAW,cAAe,SAAQ,iBAAiB,CAAC,EAAE,EAAE,WAAW,CAAC,EAAE,QAAQ,CAAC,cAAc,CAAC;CACnG;AAED,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,iBAAiB,CAAC,OAAO,CAAC,CAAA;IACtC,2FAA2F;IAC3F,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAA;CACxC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.local.d.ts","sourceRoot":"","sources":["../src/types.local.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAE3E,MAAM,MAAM,MAAM,GAAG,YAAY,CAAA;AAEjC,MAAM,MAAM,OAAO,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,IAAI,aAAa,CAAC,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.local.js","sourceRoot":"","sources":["../src/types.local.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Operators mongo speaks natively and that mean the same thing here as they do in SQL and in
|
|
3
|
+
* the in-memory engine. Everything else in the shared vocabulary is rewritten below into a
|
|
4
|
+
* mongo expression with the same meaning — a criteria object has to answer identically
|
|
5
|
+
* whichever store it reaches.
|
|
6
|
+
*/
|
|
7
|
+
export declare const NATIVE: Set<string>;
|
|
8
|
+
/** What the SERVER reports about an index rather than what a declaration asks for — never a
|
|
9
|
+
* reason to recreate one. `collation` is here because a collection's default collation is
|
|
10
|
+
* reported on every index in it, including the ones declared without any. */
|
|
11
|
+
export declare const REPORTED_FIELDS: Set<string>;
|
|
12
|
+
export declare const VALID_COLLECTION_NAME: RegExp;
|
|
13
|
+
/**
|
|
14
|
+
* The only shape a stored reference is converted from. Deliberately stricter than
|
|
15
|
+
* `ObjectId.isValid`, which also accepts any 12 character string and would silently
|
|
16
|
+
* swallow short business keys.
|
|
17
|
+
*/
|
|
18
|
+
export declare const HEX24: RegExp;
|
|
19
|
+
/**
|
|
20
|
+
* Operators whose operand is never an id — a 24 hex string under `$regex` is a pattern,
|
|
21
|
+
* not a reference.
|
|
22
|
+
*/
|
|
23
|
+
export declare const OPAQUE_OPERATORS: string[];
|
|
24
|
+
export declare const LOGICAL_OPERATORS: string[];
|
|
25
|
+
//# sourceMappingURL=consts.local.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consts.local.d.ts","sourceRoot":"","sources":["../../src/utils/consts.local.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,eAAO,MAAM,MAAM,aAAiF,CAAA;AAEpG;;8EAE8E;AAC9E,eAAO,MAAM,eAAe,aAE1B,CAAA;AAMF,eAAO,MAAM,qBAAqB,QAAqB,CAAA;AAEvD;;;;GAIG;AACH,eAAO,MAAM,KAAK,QAAsB,CAAA;AAExC;;;GAGG;AACH,eAAO,MAAM,gBAAgB,UAAwE,CAAA;AAErG,eAAO,MAAM,iBAAiB,UAA0B,CAAA"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Operators mongo speaks natively and that mean the same thing here as they do in SQL and in
|
|
3
|
+
* the in-memory engine. Everything else in the shared vocabulary is rewritten below into a
|
|
4
|
+
* mongo expression with the same meaning — a criteria object has to answer identically
|
|
5
|
+
* whichever store it reaches.
|
|
6
|
+
*/
|
|
7
|
+
export const NATIVE = new Set(['$eq', '$ne', '$gt', '$gte', '$lt', '$lte', '$in', '$nin', '$regex']);
|
|
8
|
+
/** What the SERVER reports about an index rather than what a declaration asks for — never a
|
|
9
|
+
* reason to recreate one. `collation` is here because a collection's default collation is
|
|
10
|
+
* reported on every index in it, including the ones declared without any. */
|
|
11
|
+
export const REPORTED_FIELDS = new Set([
|
|
12
|
+
'v', 'ns', 'name', 'collation', 'textIndexVersion', '2dsphereIndexVersion', 'background'
|
|
13
|
+
]);
|
|
14
|
+
// Collection names must use only alphanumeric characters, underscore, and hyphen — no
|
|
15
|
+
// colons or other delimiters. This guard enforces the rule for every collection created
|
|
16
|
+
// through makeMongoResource across all projects (common/internal/app), failing fast at
|
|
17
|
+
// initialization rather than silently creating a badly-named collection.
|
|
18
|
+
export const VALID_COLLECTION_NAME = /^[a-zA-Z0-9_-]+$/;
|
|
19
|
+
/**
|
|
20
|
+
* The only shape a stored reference is converted from. Deliberately stricter than
|
|
21
|
+
* `ObjectId.isValid`, which also accepts any 12 character string and would silently
|
|
22
|
+
* swallow short business keys.
|
|
23
|
+
*/
|
|
24
|
+
export const HEX24 = /^[0-9a-fA-F]{24}$/;
|
|
25
|
+
/**
|
|
26
|
+
* Operators whose operand is never an id — a 24 hex string under `$regex` is a pattern,
|
|
27
|
+
* not a reference.
|
|
28
|
+
*/
|
|
29
|
+
export const OPAQUE_OPERATORS = ['$regex', '$options', '$type', '$size', '$mod', '$exists', '$where'];
|
|
30
|
+
export const LOGICAL_OPERATORS = ['$and', '$or', '$nor'];
|
|
31
|
+
//# sourceMappingURL=consts.local.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consts.local.js","sourceRoot":"","sources":["../../src/utils/consts.local.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAA;AAEpG;;8EAE8E;AAC9E,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC;IACrC,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,YAAY;CACzF,CAAC,CAAA;AAEF,sFAAsF;AACtF,wFAAwF;AACxF,uFAAuF;AACvF,yEAAyE;AACzE,MAAM,CAAC,MAAM,qBAAqB,GAAG,kBAAkB,CAAA;AAEvD;;;;GAIG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG,mBAAmB,CAAA;AAExC;;;GAGG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAA;AAErG,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAA"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { Criteria, Sort } from '@owlmeans/resource';
|
|
2
|
+
import type { Document } from 'mongodb';
|
|
3
|
+
import type { MongoReference } from '../../types.js';
|
|
4
|
+
/** The portable criteria and sort vocabulary, as the documents a collection takes. */
|
|
5
|
+
export interface MongoCriteriaHelper {
|
|
6
|
+
/**
|
|
7
|
+
* Translate `Criteria<T>` into the filter a collection takes.
|
|
8
|
+
*
|
|
9
|
+
* Two passes: the shared operator vocabulary becomes mongo expressions, then
|
|
10
|
+
* `mongoRefHelper.marshalCriteria` converts the values addressed at `_id` or at a declared
|
|
11
|
+
* reference into `ObjectId`s and maps the `id` alias onto `_id`. Both halves are needed — a
|
|
12
|
+
* criteria object carries string ids and portable operators, a collection stores neither.
|
|
13
|
+
*
|
|
14
|
+
* An empty result is an empty filter, which matches everything. Callers that must not act on
|
|
15
|
+
* "everything" — `purge` — check for it themselves.
|
|
16
|
+
*
|
|
17
|
+
* @throws {UnsupportedArgumentError}
|
|
18
|
+
*/
|
|
19
|
+
criteriaToFilter: (criteria: Criteria<any> | undefined, refs: Map<string, MongoReference>) => Document;
|
|
20
|
+
/**
|
|
21
|
+
* Translate `Sort<T>[]` into a mongo sort document. A bare field name is ascending, and `id`
|
|
22
|
+
* addresses `_id` — documents never store an `id` field, so sorting by the name records carry
|
|
23
|
+
* would silently order by nothing.
|
|
24
|
+
*/
|
|
25
|
+
sortToMongo: (sort?: Sort<any>[]) => Document | undefined;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/utils/criteria/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAEvC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAEpD,sFAAsF;AACtF,MAAM,WAAW,mBAAmB;IAClC;;;;;;;;;;;;OAYG;IACH,gBAAgB,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,GAAG,SAAS,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,KAAK,QAAQ,CAAA;IACtG;;;;OAIG;IACH,WAAW,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,KAAK,QAAQ,GAAG,SAAS,CAAA;CAC1D"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/utils/criteria/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type Criteria } from '@owlmeans/resource';
|
|
2
|
+
import type { Document } from 'mongodb';
|
|
3
|
+
import type { MongoReference } from '../types.js';
|
|
4
|
+
import type { MongoCriteriaHelper } from './criteria/types.js';
|
|
5
|
+
export declare const createMongoCriteriaHelper: () => MongoCriteriaHelper;
|
|
6
|
+
export declare const mongoCriteriaHelper: MongoCriteriaHelper;
|
|
7
|
+
/** @deprecated compat:factory-refactor — use `mongoCriteriaHelper.criteriaToFilter(…)` */
|
|
8
|
+
export declare const criteriaToFilter: (criteria: Criteria<any> | undefined, refs: Map<string, MongoReference>) => Document;
|
|
9
|
+
//# sourceMappingURL=criteria.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"criteria.d.ts","sourceRoot":"","sources":["../../src/utils/criteria.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,KAAK,QAAQ,EAAa,MAAM,oBAAoB,CAAA;AACvF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAEvC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAGjD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAsF9D,eAAO,MAAM,yBAAyB,QAAO,mBAwI5C,CAAA;AAED,eAAO,MAAM,mBAAmB,qBAA8B,CAAA;AAE9D,0FAA0F;AAC1F,eAAO,MAAM,gBAAgB,aAAc,QAAQ,CAAC,GAAG,CAAC,GAAG,SAAS,QAAQ,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,KAAG,QACpD,CAAA"}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import { UnsupportedArgumentError } from '@owlmeans/resource';
|
|
2
|
+
import { mongoRefHelper } from './refs.js';
|
|
3
|
+
import { NATIVE } from './consts.local.js';
|
|
4
|
+
const escapeRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
5
|
+
/**
|
|
6
|
+
* A SQL `LIKE` pattern as an anchored regular expression: `%` is any run, `_` is one
|
|
7
|
+
* character, and `\` escapes either. The mapping is the one the in-memory engine applies, so
|
|
8
|
+
* the same pattern selects the same records against a collection.
|
|
9
|
+
*/
|
|
10
|
+
const likeToRegExp = (pattern) => {
|
|
11
|
+
let source = '';
|
|
12
|
+
for (let index = 0; index < pattern.length; index++) {
|
|
13
|
+
const char = pattern[index];
|
|
14
|
+
if (char === '\\' && index + 1 < pattern.length) {
|
|
15
|
+
source += escapeRegExp(pattern[++index]);
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
if (char === '%') {
|
|
19
|
+
source += '.*';
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
if (char === '_') {
|
|
23
|
+
source += '.';
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
source += escapeRegExp(char);
|
|
27
|
+
}
|
|
28
|
+
return `^${source}$`;
|
|
29
|
+
};
|
|
30
|
+
const asArray = (operand) => Array.isArray(operand) ? operand : [operand];
|
|
31
|
+
/**
|
|
32
|
+
* One operator as the mongo field expression that answers it.
|
|
33
|
+
*
|
|
34
|
+
* `$exists` and `$null` both become a comparison against `null`, not mongo's own `$exists`:
|
|
35
|
+
* the shared vocabulary asks whether a field *has a value*, which the relational and
|
|
36
|
+
* in-memory stores answer as `IS NULL` / `value == null`. Mongo's `$exists` answers a
|
|
37
|
+
* different question — whether the key is present — and a key present but null would part
|
|
38
|
+
* the three stores over one criteria object.
|
|
39
|
+
*
|
|
40
|
+
* @throws {UnsupportedArgumentError} on an operator this store cannot answer.
|
|
41
|
+
*/
|
|
42
|
+
const operatorToFilter = (field, operator, operand) => {
|
|
43
|
+
if (NATIVE.has(operator)) {
|
|
44
|
+
return { [operator]: operand };
|
|
45
|
+
}
|
|
46
|
+
switch (operator) {
|
|
47
|
+
case '$exists':
|
|
48
|
+
return operand === false ? { $eq: null } : { $ne: null };
|
|
49
|
+
case '$null':
|
|
50
|
+
return operand === false ? { $ne: null } : { $eq: null };
|
|
51
|
+
case '$like':
|
|
52
|
+
return { $regex: likeToRegExp(`${operand}`) };
|
|
53
|
+
case '$ilike':
|
|
54
|
+
return { $regex: likeToRegExp(`${operand}`), $options: 'i' };
|
|
55
|
+
case '$startsWith':
|
|
56
|
+
return { $regex: `^${escapeRegExp(`${operand}`)}` };
|
|
57
|
+
case '$endsWith':
|
|
58
|
+
return { $regex: `${escapeRegExp(`${operand}`)}$` };
|
|
59
|
+
case '$between':
|
|
60
|
+
if (!Array.isArray(operand) || operand.length !== 2) {
|
|
61
|
+
throw new UnsupportedArgumentError(`criteria:$between:${field}`);
|
|
62
|
+
}
|
|
63
|
+
return { $gte: operand[0], $lte: operand[1] };
|
|
64
|
+
/** Array membership, mirroring the postgres array operators `@>`, `<@` and `&&`. */
|
|
65
|
+
case '$contains':
|
|
66
|
+
return { $all: asArray(operand) };
|
|
67
|
+
case '$contained':
|
|
68
|
+
/**
|
|
69
|
+
* Nothing outside the operand list may appear in the field. The `$ne: null` keeps an
|
|
70
|
+
* absent field out of the result — `$not` alone is satisfied by a document that has no
|
|
71
|
+
* such field at all, where the relational store answers NULL and matches nothing.
|
|
72
|
+
*/
|
|
73
|
+
return { $not: { $elemMatch: { $nin: asArray(operand) } }, $ne: null };
|
|
74
|
+
case '$overlaps':
|
|
75
|
+
return { $in: asArray(operand) };
|
|
76
|
+
default:
|
|
77
|
+
throw new UnsupportedArgumentError(`criteria-operator:${operator}`);
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* An object naming at least one `$` key is a spec, not a value to compare against. A Date and
|
|
82
|
+
* an array are values even though both are objects.
|
|
83
|
+
*/
|
|
84
|
+
const isOperatorSpec = (value) => value != null && typeof value === 'object' && !Array.isArray(value) && !(value instanceof Date)
|
|
85
|
+
&& Object.keys(value).some(key => key.startsWith('$'));
|
|
86
|
+
export const createMongoCriteriaHelper = () => {
|
|
87
|
+
const { marshalCriteria } = mongoRefHelper;
|
|
88
|
+
/**
|
|
89
|
+
* One field's criteria as mongo conditions. Operators that translate into the same mongo key —
|
|
90
|
+
* `$like` and `$startsWith` both produce `$regex` — are emitted as separate conditions rather
|
|
91
|
+
* than merged, so neither silently overwrites the other.
|
|
92
|
+
*/
|
|
93
|
+
const fieldConditions = (field, spec) => {
|
|
94
|
+
const merged = {};
|
|
95
|
+
const conditions = [];
|
|
96
|
+
for (const [operator, operand] of Object.entries(spec)) {
|
|
97
|
+
if (operand === undefined) {
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
const fragment = operatorToFilter(field, operator, operand);
|
|
101
|
+
if (Object.keys(fragment).some(key => key in merged)) {
|
|
102
|
+
conditions.push({ [field]: fragment });
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
Object.assign(merged, fragment);
|
|
106
|
+
}
|
|
107
|
+
if (Object.keys(merged).length > 0) {
|
|
108
|
+
conditions.unshift({ [field]: merged });
|
|
109
|
+
}
|
|
110
|
+
return conditions;
|
|
111
|
+
};
|
|
112
|
+
/**
|
|
113
|
+
* Flatten the conditions into one filter document. Mongo reads sibling keys as a conjunction,
|
|
114
|
+
* so only the ones that would overwrite an earlier key — two `$regex` expressions over the
|
|
115
|
+
* same field, say — need an explicit `$and`.
|
|
116
|
+
*/
|
|
117
|
+
const flatten = (conditions) => {
|
|
118
|
+
const filter = {};
|
|
119
|
+
const conflicting = [];
|
|
120
|
+
for (const condition of conditions) {
|
|
121
|
+
if (Object.keys(condition).some(key => key in filter)) {
|
|
122
|
+
conflicting.push(condition);
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
Object.assign(filter, condition);
|
|
126
|
+
}
|
|
127
|
+
if (conflicting.length > 0) {
|
|
128
|
+
filter.$and = [...(Array.isArray(filter.$and) ? filter.$and : []), ...conflicting];
|
|
129
|
+
}
|
|
130
|
+
return filter;
|
|
131
|
+
};
|
|
132
|
+
const build = (criteria) => {
|
|
133
|
+
const conditions = [];
|
|
134
|
+
for (const [key, raw] of Object.entries(criteria ?? {})) {
|
|
135
|
+
/**
|
|
136
|
+
* An untouched filter must never empty a list, so `undefined` is skipped rather than
|
|
137
|
+
* compared. `null` asks for the absence of a value.
|
|
138
|
+
*/
|
|
139
|
+
if (raw === undefined) {
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
if (key === '$and' || key === '$or') {
|
|
143
|
+
const parts = (Array.isArray(raw) ? raw : [raw])
|
|
144
|
+
.map(part => build(part))
|
|
145
|
+
.filter(part => part.length > 0)
|
|
146
|
+
.map(part => flatten(part));
|
|
147
|
+
if (parts.length > 0) {
|
|
148
|
+
conditions.push(key === '$and' ? { $and: parts } : { $or: parts });
|
|
149
|
+
}
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
if (key === '$not') {
|
|
153
|
+
const inner = build(raw);
|
|
154
|
+
if (inner.length > 0) {
|
|
155
|
+
/** Mongo has no top level `$not`; `$nor` over a single branch is its negation. */
|
|
156
|
+
conditions.push({ $nor: [flatten(inner)] });
|
|
157
|
+
}
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
if (raw === null) {
|
|
161
|
+
conditions.push({ [key]: { $eq: null } });
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
if (isOperatorSpec(raw)) {
|
|
165
|
+
conditions.push(...fieldConditions(key, raw));
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
if (Array.isArray(raw)) {
|
|
169
|
+
/**
|
|
170
|
+
* A bare array means "any of these", exactly as it does against a relational store.
|
|
171
|
+
* Exact array equality stays reachable as `{ $eq: [...] }`.
|
|
172
|
+
*/
|
|
173
|
+
conditions.push({ [key]: { $in: raw } });
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
conditions.push({ [key]: raw });
|
|
177
|
+
}
|
|
178
|
+
return conditions;
|
|
179
|
+
};
|
|
180
|
+
const criteriaToFilter = (criteria, refs) => {
|
|
181
|
+
const conditions = build(criteria);
|
|
182
|
+
if (conditions.length < 1) {
|
|
183
|
+
return {};
|
|
184
|
+
}
|
|
185
|
+
return marshalCriteria(flatten(conditions), refs) ?? {};
|
|
186
|
+
};
|
|
187
|
+
const sortToMongo = (sort) => {
|
|
188
|
+
if (sort == null || sort.length < 1) {
|
|
189
|
+
return undefined;
|
|
190
|
+
}
|
|
191
|
+
return sort.reduce((order, entry) => {
|
|
192
|
+
const [field, direction] = typeof entry === 'string'
|
|
193
|
+
? [entry, 1]
|
|
194
|
+
: [entry.field, entry.order === 'desc' ? -1 : 1];
|
|
195
|
+
order[field === 'id' ? '_id' : field] = direction;
|
|
196
|
+
return order;
|
|
197
|
+
}, {});
|
|
198
|
+
};
|
|
199
|
+
return { criteriaToFilter, sortToMongo };
|
|
200
|
+
};
|
|
201
|
+
export const mongoCriteriaHelper = createMongoCriteriaHelper();
|
|
202
|
+
/** @deprecated compat:factory-refactor — use `mongoCriteriaHelper.criteriaToFilter(…)` */
|
|
203
|
+
export const criteriaToFilter = (criteria, refs) => mongoCriteriaHelper.criteriaToFilter(criteria, refs);
|
|
204
|
+
//# sourceMappingURL=criteria.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"criteria.js","sourceRoot":"","sources":["../../src/utils/criteria.ts"],"names":[],"mappings":"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"}
|
package/build/utils/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AACA,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA;AAC3B,cAAc,WAAW,CAAA;AACzB,cAAc,iBAAiB,CAAA;AAC/B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,WAAW,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AACA,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA;AAC3B,cAAc,WAAW,CAAA;AACzB,cAAc,iBAAiB,CAAA;AAC/B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,WAAW,CAAA;AACzB,cAAc,eAAe,CAAA"}
|
package/build/utils/index.js
CHANGED
package/build/utils/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AACA,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA;AAC3B,cAAc,WAAW,CAAA;AACzB,cAAc,iBAAiB,CAAA;AAC/B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,WAAW,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AACA,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA;AAC3B,cAAc,WAAW,CAAA;AACzB,cAAc,iBAAiB,CAAA;AAC/B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,WAAW,CAAA;AACzB,cAAc,eAAe,CAAA"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ResourceRecord } from '@owlmeans/resource';
|
|
2
|
+
import type { Collection, Document } from 'mongodb';
|
|
3
|
+
import type { MongoResource } from '../../types.js';
|
|
4
|
+
/** A collection's indexes against the ones its resource declares. */
|
|
5
|
+
export interface MongoIndexUtils {
|
|
6
|
+
/**
|
|
7
|
+
* Whether an index the database already holds differs from the one declared.
|
|
8
|
+
*
|
|
9
|
+
* Mongo returns an index's options in ITS order, not the declaration's, so comparing the two
|
|
10
|
+
* documents as JSON reported every index as changed — and every boot then dropped and recreated
|
|
11
|
+
* every index. That is invisible until two processes boot at once, when the second one's drop
|
|
12
|
+
* fails with `IndexNotFound` and takes the service down with it. Only the KEY is order-sensitive
|
|
13
|
+
* (a compound index is its key order); options are a set.
|
|
14
|
+
*/
|
|
15
|
+
indexChanged: (existing: Document, proposed: Document) => boolean;
|
|
16
|
+
/** Create the declared indexes the collection lacks and recreate the ones that changed. */
|
|
17
|
+
updateIndexes: (collection: Collection, resource: MongoResource<ResourceRecord>) => Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/utils/indexes/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAEnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAEnD,qEAAqE;AACrE,MAAM,WAAW,eAAe;IAC9B;;;;;;;;OAQG;IACH,YAAY,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,KAAK,OAAO,CAAA;IACjE,2FAA2F;IAC3F,aAAa,EAAE,CAAC,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,aAAa,CAAC,cAAc,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CAClG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/utils/indexes/types.ts"],"names":[],"mappings":""}
|
package/build/utils/indexes.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export declare const updateIndexes: (collection: Collection, resource: MongoResource<ResourceRecord>) => Promise<void>;
|
|
1
|
+
import type { MongoIndexUtils } from './indexes/types.js';
|
|
2
|
+
export declare const createMongoIndexUtils: () => MongoIndexUtils;
|
|
3
|
+
export declare const mongoIndexUtils: MongoIndexUtils;
|
|
5
4
|
//# sourceMappingURL=indexes.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"indexes.d.ts","sourceRoot":"","sources":["../../src/utils/indexes.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"indexes.d.ts","sourceRoot":"","sources":["../../src/utils/indexes.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AAQzD,eAAO,MAAM,qBAAqB,QAAO,eA0CxC,CAAA;AAED,eAAO,MAAM,eAAe,iBAA0B,CAAA"}
|
package/build/utils/indexes.js
CHANGED
|
@@ -1,34 +1,50 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { logger } from '@owlmeans/log';
|
|
2
|
+
import { REPORTED_FIELDS } from './consts.local.js';
|
|
3
|
+
const log = logger('mongo-resource');
|
|
4
|
+
const options = (spec) => Object.entries(spec)
|
|
5
|
+
.filter(([field]) => field !== 'key' && !REPORTED_FIELDS.has(field))
|
|
6
|
+
.sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0);
|
|
7
|
+
export const createMongoIndexUtils = () => {
|
|
8
|
+
const indexChanged = (existing, proposed) => {
|
|
9
|
+
// We do not recreate text indexes.
|
|
10
|
+
if ('weights' in existing)
|
|
11
|
+
return false;
|
|
12
|
+
if (JSON.stringify(existing.key) !== JSON.stringify(proposed.key))
|
|
13
|
+
return true;
|
|
14
|
+
return JSON.stringify(options(existing)) !== JSON.stringify(options(proposed));
|
|
15
|
+
};
|
|
16
|
+
const updateIndexes = async (collection, resource) => {
|
|
17
|
+
if (resource.indexes == null) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const present = await collection.indexes();
|
|
3
21
|
await Promise.all(resource.indexes.map(async (index) => {
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
const propsed = { key: index.index, ...index.options };
|
|
14
|
-
// We do not recreate text indexes
|
|
15
|
-
if (JSON.stringify(existing) !== JSON.stringify(propsed) && !('weights' in existing)) {
|
|
16
|
-
console.info(JSON.stringify(existing));
|
|
17
|
-
console.info(JSON.stringify(propsed));
|
|
18
|
-
console.debug(`Recreate index ${resource.alias} : ${index.name}`);
|
|
19
|
-
await collection.dropIndex(index.name);
|
|
20
|
-
await collection.createIndex(index.index, {
|
|
21
|
-
name: index.name, ...((index.options != null) ? index.options : {})
|
|
22
|
-
});
|
|
23
|
-
}
|
|
22
|
+
const create = async () => await collection.createIndex(index.index, {
|
|
23
|
+
name: index.name, ...((index.options != null) ? index.options : {})
|
|
24
|
+
});
|
|
25
|
+
const existing = present.find(_index => _index.name === index.name);
|
|
26
|
+
if (existing == null) {
|
|
27
|
+
log.debug('Create index', { resource: resource.alias, index: index.name });
|
|
28
|
+
await create();
|
|
29
|
+
return;
|
|
24
30
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
await collection.createIndex(index.index, {
|
|
28
|
-
name: index.name, ...((index.options != null) ? index.options : {})
|
|
29
|
-
});
|
|
31
|
+
if (!indexChanged(existing, { key: index.index, ...index.options })) {
|
|
32
|
+
return;
|
|
30
33
|
}
|
|
34
|
+
log.debug('Recreate index', { resource: resource.alias, index: index.name });
|
|
35
|
+
try {
|
|
36
|
+
await collection.dropIndex(index.name);
|
|
37
|
+
}
|
|
38
|
+
catch (e) {
|
|
39
|
+
// IndexNotFound: another process booting alongside this one dropped it first — it is
|
|
40
|
+
// recreating the same declaration, so there is nothing here to fail over.
|
|
41
|
+
if (e.code !== 27)
|
|
42
|
+
throw e;
|
|
43
|
+
}
|
|
44
|
+
await create();
|
|
31
45
|
}));
|
|
32
|
-
}
|
|
46
|
+
};
|
|
47
|
+
return { indexChanged, updateIndexes };
|
|
33
48
|
};
|
|
49
|
+
export const mongoIndexUtils = createMongoIndexUtils();
|
|
34
50
|
//# sourceMappingURL=indexes.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"indexes.js","sourceRoot":"","sources":["../../src/utils/indexes.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"indexes.js","sourceRoot":"","sources":["../../src/utils/indexes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { BasicContext } from '@owlmeans/context';
|
|
2
|
+
import type { DbConfig, ResourceRecord } from '@owlmeans/resource';
|
|
3
|
+
import type { Collection } from 'mongodb';
|
|
4
|
+
import type { MongoResource } from '../../types.js';
|
|
5
|
+
/** A resource collection's initialization over one database. */
|
|
6
|
+
export interface MongoLifeCycleUtils {
|
|
7
|
+
/**
|
|
8
|
+
* Bring a resource's collection to the shape its schema declares.
|
|
9
|
+
*
|
|
10
|
+
* Order is deliberate, and matches the Postgres counterpart:
|
|
11
|
+
*
|
|
12
|
+
* 1. probe for the collection
|
|
13
|
+
* 2. absent → *baseline* every registered migration; present → run the `pre` ones
|
|
14
|
+
* (including the system `$ref:` migrations that convert declared references)
|
|
15
|
+
* 3. create the collection, or update its validator and indexes
|
|
16
|
+
* 4. present → run the `post` migrations
|
|
17
|
+
* 5. reconcile declared references — the second half of their double check: the ledger
|
|
18
|
+
* said whether the `$ref:` migration ran, this probes the collection itself and
|
|
19
|
+
* converts whatever strings still slipped through
|
|
20
|
+
*
|
|
21
|
+
* Step 2 is what stops the two mechanisms colliding. A `pre` migration runs before the
|
|
22
|
+
* validator is tightened, so it can reshape documents the new validator would reject. On a
|
|
23
|
+
* collection this call just created there is nothing to reshape — replaying a historical
|
|
24
|
+
* migration against a collection born in its final shape would at best scan for nothing —
|
|
25
|
+
* so the migrations are recorded as satisfied instead of run.
|
|
26
|
+
*
|
|
27
|
+
* `context` is optional so the existing three-argument call keeps working; without it a
|
|
28
|
+
* migration's `use`/`ref` can only address the owning resource.
|
|
29
|
+
*/
|
|
30
|
+
initializeCollection: (config: DbConfig, resource: MongoResource<ResourceRecord>, context?: BasicContext<any>) => Promise<Collection>;
|
|
31
|
+
/** Create the collection with its validator and its declared indexes. */
|
|
32
|
+
createCollection: (name: string, resource: MongoResource<ResourceRecord>) => Promise<Collection>;
|
|
33
|
+
/** Replace the validator of an existing collection and bring its indexes up to date. */
|
|
34
|
+
updateCollection: (name: string, resource: MongoResource<ResourceRecord>) => Promise<Collection>;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=types.d.ts.map
|