@xyo-network/module-abstract-mongodb 5.3.22 → 5.3.24

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.
@@ -20,10 +20,10 @@ export declare const MongoDBModuleMixin: <TParams extends MongoDBModuleParams =
20
20
  id: string;
21
21
  modName?: import("@xyo-network/module-model").ModuleName;
22
22
  params: TParams;
23
- previousHash: () => import("@xylabs/promise").Promisable<string | undefined>;
23
+ previousHash: () => import("@xylabs/sdk-js").Promisable<string | undefined>;
24
24
  queries: string[];
25
- query: <T extends import("@xyo-network/boundwitness-model").QueryBoundWitness = import("@xyo-network/boundwitness-model").QueryBoundWitness, TConf extends import("@xyo-network/module-model").ModuleConfig = import("@xyo-network/module-model").ModuleConfig>(query: T, payloads?: import("@xyo-network/payload-model").Payload[], queryConfig?: TConf) => import("@xylabs/promise").Promisable<import("@xyo-network/module-model").ModuleQueryResult>;
26
- queryable: <T extends import("@xyo-network/boundwitness-model").QueryBoundWitness = import("@xyo-network/boundwitness-model").QueryBoundWitness, TConf_1 extends import("@xyo-network/module-model").ModuleConfig = import("@xyo-network/module-model").ModuleConfig>(query: T, payloads?: import("@xyo-network/payload-model").Payload[], queryConfig?: TConf_1) => import("@xylabs/promise").Promisable<boolean>;
25
+ query: <T extends import("@xyo-network/boundwitness-model").QueryBoundWitness = import("@xyo-network/boundwitness-model").QueryBoundWitness, TConf extends import("@xyo-network/module-model").ModuleConfig = import("@xyo-network/module-model").ModuleConfig>(query: T, payloads?: import("@xyo-network/payload-model").Payload[], queryConfig?: TConf) => import("@xylabs/sdk-js").Promisable<import("@xyo-network/module-model").ModuleQueryResult>;
26
+ queryable: <T extends import("@xyo-network/boundwitness-model").QueryBoundWitness = import("@xyo-network/boundwitness-model").QueryBoundWitness, TConf_1 extends import("@xyo-network/module-model").ModuleConfig = import("@xyo-network/module-model").ModuleConfig>(query: T, payloads?: import("@xyo-network/payload-model").Payload[], queryConfig?: TConf_1) => import("@xylabs/sdk-js").Promisable<boolean>;
27
27
  eventData: import("@xyo-network/module-model").ModuleEventData<object>;
28
28
  name: import("@xylabs/sdk-js").CreatableName;
29
29
  start: () => Promise<boolean>;
@@ -17,10 +17,10 @@ export declare const MongoDBModuleMixinV2: <TParams extends MongoDBModuleParamsV
17
17
  id: string;
18
18
  modName?: import("@xyo-network/module-model").ModuleName;
19
19
  params: TParams;
20
- previousHash: () => import("@xylabs/promise").Promisable<string | undefined>;
20
+ previousHash: () => import("@xylabs/sdk-js").Promisable<string | undefined>;
21
21
  queries: string[];
22
- query: <T extends import("@xyo-network/boundwitness-model").QueryBoundWitness = import("@xyo-network/boundwitness-model").QueryBoundWitness, TConf extends import("@xyo-network/module-model").ModuleConfig = import("@xyo-network/module-model").ModuleConfig>(query: T, payloads?: import("@xyo-network/payload-model").Payload[], queryConfig?: TConf) => import("@xylabs/promise").Promisable<import("@xyo-network/module-model").ModuleQueryResult>;
23
- queryable: <T extends import("@xyo-network/boundwitness-model").QueryBoundWitness = import("@xyo-network/boundwitness-model").QueryBoundWitness, TConf_1 extends import("@xyo-network/module-model").ModuleConfig = import("@xyo-network/module-model").ModuleConfig>(query: T, payloads?: import("@xyo-network/payload-model").Payload[], queryConfig?: TConf_1) => import("@xylabs/promise").Promisable<boolean>;
22
+ query: <T extends import("@xyo-network/boundwitness-model").QueryBoundWitness = import("@xyo-network/boundwitness-model").QueryBoundWitness, TConf extends import("@xyo-network/module-model").ModuleConfig = import("@xyo-network/module-model").ModuleConfig>(query: T, payloads?: import("@xyo-network/payload-model").Payload[], queryConfig?: TConf) => import("@xylabs/sdk-js").Promisable<import("@xyo-network/module-model").ModuleQueryResult>;
23
+ queryable: <T extends import("@xyo-network/boundwitness-model").QueryBoundWitness = import("@xyo-network/boundwitness-model").QueryBoundWitness, TConf_1 extends import("@xyo-network/module-model").ModuleConfig = import("@xyo-network/module-model").ModuleConfig>(query: T, payloads?: import("@xyo-network/payload-model").Payload[], queryConfig?: TConf_1) => import("@xylabs/sdk-js").Promisable<boolean>;
24
24
  eventData: import("@xyo-network/module-model").ModuleEventData<object>;
25
25
  name: import("@xylabs/sdk-js").CreatableName;
26
26
  start: () => Promise<boolean>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xyo-network/module-abstract-mongodb",
3
- "version": "5.3.22",
3
+ "version": "5.3.24",
4
4
  "description": "Primary SDK for using XYO Protocol 2.0",
5
5
  "homepage": "https://xyo.network",
6
6
  "bugs": {
@@ -33,38 +33,34 @@
33
33
  "types": "dist/node/index.d.ts",
34
34
  "files": [
35
35
  "dist",
36
- "src",
37
36
  "!**/*.bench.*",
38
37
  "!**/*.spec.*",
39
38
  "!**/*.test.*",
40
39
  "README.md"
41
40
  ],
42
41
  "dependencies": {
43
- "@xyo-network/module-model": "~5.3.22",
44
- "@xyo-network/module-model-mongodb": "~5.3.22",
45
- "@xyo-network/payload-mongodb": "~5.3.22"
42
+ "@xyo-network/module-model": "~5.3.24",
43
+ "@xyo-network/module-model-mongodb": "~5.3.24",
44
+ "@xyo-network/payload-mongodb": "~5.3.24"
46
45
  },
47
46
  "devDependencies": {
48
47
  "@opentelemetry/api": "^1.9.1",
49
48
  "@types/node": "^25.5.0",
50
- "@xylabs/mongo": "^5.0.91",
51
- "@xylabs/sdk-js": "^5.0.91",
52
- "@xylabs/ts-scripts-common": "~7.6.8",
53
- "@xylabs/ts-scripts-yarn3": "~7.6.8",
54
- "@xylabs/tsconfig": "~7.6.8",
55
- "@xyo-network/module-model": "~5.3.22",
56
- "@xyo-network/module-model-mongodb": "~5.3.22",
57
- "@xyo-network/payload-mongodb": "~5.3.22",
49
+ "@xylabs/mongo": "^5.0.93",
50
+ "@xylabs/sdk-js": "^5.0.93",
51
+ "@xylabs/ts-scripts-common": "~7.6.16",
52
+ "@xylabs/ts-scripts-pnpm": "~7.6.16",
53
+ "@xylabs/tsconfig": "~7.6.16",
58
54
  "acorn": "^8.16.0",
59
55
  "axios": "^1.14.0",
60
- "cosmiconfig": "^9.0.1",
61
- "esbuild": "^0.27.4",
62
- "eslint": "^10.1.0",
56
+ "esbuild": "^0.28.0",
63
57
  "mongodb": "~7.1.1",
64
- "rollup": "^4.60.1",
65
58
  "tslib": "~2.8.1",
66
59
  "typescript": "~5.9.3",
67
- "zod": "^4.3.6"
60
+ "zod": "^4.3.6",
61
+ "@xyo-network/module-model-mongodb": "~5.3.24",
62
+ "@xyo-network/payload-mongodb": "~5.3.24",
63
+ "@xyo-network/module-model": "~5.3.24"
68
64
  },
69
65
  "peerDependencies": {
70
66
  "@xylabs/mongo": "^5",
@@ -79,4 +75,4 @@
79
75
  "publishConfig": {
80
76
  "access": "public"
81
77
  }
82
- }
78
+ }
@@ -1,5 +0,0 @@
1
- import type { QueryableModule } from '@xyo-network/module-model'
2
- import type { MongoDBModuleParams } from '@xyo-network/module-model-mongodb'
3
-
4
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
5
- export type AnyAbstractModule<TParams extends MongoDBModuleParams = MongoDBModuleParams> = abstract new (...args: any[]) => QueryableModule<TParams>
@@ -1,9 +0,0 @@
1
- // TODO: By DB
2
- export const COLLECTIONS = {
3
- AddressInfo: 'address_info' as const,
4
- ArchivistStats: 'archivist_stats' as const,
5
- BoundWitnesses: 'bound_witnesses' as const,
6
- Payloads: 'payloads' as const,
7
- Thumbnails: 'thumbnails' as const,
8
- Users: 'users' as const,
9
- }
package/src/Databases.ts DELETED
@@ -1 +0,0 @@
1
- export const DATABASES = { Archivist: 'archivist' as const }
package/src/Defaults.ts DELETED
@@ -1,4 +0,0 @@
1
- export const DefaultAggregateTimeoutMs = 10_000
2
- export const DefaultLimit = 20
3
- export const DefaultMaxTimeMS = 2000
4
- export const DefaultOrder = 'desc'
@@ -1,26 +0,0 @@
1
- /**
2
- * The index direction (1 for ascending, -1 for descending)
3
- */
4
- export type IndexDirection = -1 | 1
5
-
6
- /**
7
- * Description of index(es) to be created on a store
8
- */
9
- export type IndexDescription = {
10
- /**
11
- * The key(s) to index
12
- */
13
- key:
14
- | {
15
- [key: string]: IndexDirection
16
- }
17
- | Map<string, IndexDirection>
18
- /**
19
- * The name of the index
20
- */
21
- name?: string
22
- /**
23
- * If true, the index must enforce uniqueness on the key
24
- */
25
- unique?: boolean
26
- }
@@ -1,3 +0,0 @@
1
- import type { IndexDescription } from 'mongodb'
2
-
3
- export type CollectionIndexFunction = (collectionName: string) => IndexDescription[]
@@ -1 +0,0 @@
1
- export * from './CollectionIndexFunction.ts'
package/src/Module.ts DELETED
@@ -1,122 +0,0 @@
1
- import { BaseMongoSdk, BaseMongoSdkConfig } from '@xylabs/mongo'
2
- import { assertEx, staticImplements } from '@xylabs/sdk-js'
3
- import {
4
- MongoDBModule, MongoDBModuleParams, MongoDBStorageClassLabels,
5
- } from '@xyo-network/module-model-mongodb'
6
- import { BoundWitnessWithMongoMeta, PayloadWithMongoMeta } from '@xyo-network/payload-mongodb'
7
- import { MongoServerError } from 'mongodb'
8
-
9
- import { AnyAbstractModule } from './AnyAbstractModule.ts'
10
- import { COLLECTIONS } from './Collections.ts'
11
- import { getBaseMongoSdkPrivateConfig } from './config/index.ts'
12
- import { IndexDescription } from './IndexDescription.ts'
13
- import { merge } from './merge.ts'
14
-
15
- const standardIndexes: IndexDescription[] = [
16
- {
17
- name: 'IX__hash', key: { _hash: 1 }, unique: false,
18
- },
19
- {
20
- name: 'IX__dataHash', key: { _dataHash: 1 }, unique: false,
21
- },
22
- {
23
- name: 'IX__sequence', key: { _sequence: 1 }, unique: false,
24
- },
25
- ]
26
-
27
- export const MongoDBModuleMixin = <
28
- TParams extends MongoDBModuleParams = MongoDBModuleParams,
29
- TModule extends AnyAbstractModule<TParams> = AnyAbstractModule<TParams>,
30
- >(
31
- ModuleBase: TModule,
32
- ) => {
33
- @staticImplements<TModule>()
34
- abstract class MongoModuleBase extends ModuleBase implements MongoDBModule {
35
- static readonly labels = MongoDBStorageClassLabels
36
- _boundWitnessSdk: BaseMongoSdk<BoundWitnessWithMongoMeta> | undefined
37
- _payloadSdk: BaseMongoSdk<PayloadWithMongoMeta> | undefined
38
-
39
- get boundWitnessSdkConfig(): BaseMongoSdkConfig {
40
- const config = { collection: COLLECTIONS.BoundWitnesses, ...getBaseMongoSdkPrivateConfig() }
41
- return merge(
42
- config,
43
- this.params.boundWitnessSdkConfig,
44
- this.config.boundWitnessSdkConfig,
45
- { collection: this.config.boundWitnessSdkConfig?.collection ?? this.params.boundWitnessSdkConfig?.collection ?? COLLECTIONS.BoundWitnesses },
46
- )
47
- }
48
-
49
- get boundWitnesses() {
50
- this._boundWitnessSdk = this._boundWitnessSdk ?? new BaseMongoSdk<BoundWitnessWithMongoMeta>(this.boundWitnessSdkConfig)
51
- return assertEx(this._boundWitnessSdk)
52
- }
53
-
54
- get jobQueue() {
55
- return assertEx(this.params.jobQueue, () => 'MongoDBModule Error: jobQueue required for this module but is not defined')
56
- }
57
-
58
- get payloadSdkConfig(): BaseMongoSdkConfig {
59
- const config = { collection: COLLECTIONS.Payloads, ...getBaseMongoSdkPrivateConfig() }
60
- return merge(
61
- config,
62
- this.params.payloadSdkConfig,
63
- this.config.payloadSdkConfig,
64
- { collection: this.config.payloadSdkConfig?.collection ?? this.params.payloadSdkConfig?.collection ?? COLLECTIONS.Payloads },
65
- )
66
- }
67
-
68
- get payloads() {
69
- this._payloadSdk = this._payloadSdk ?? new BaseMongoSdk<PayloadWithMongoMeta>(this.payloadSdkConfig)
70
- return assertEx(this._payloadSdk)
71
- }
72
-
73
- /**
74
- * Ensures any indexes specified within the config are created. This method should be idempotent
75
- * allowing for multiple calls without causing errors while ensuring the desired state.
76
- */
77
- async ensureIndexes(): Promise<void> {
78
- const configIndexes = (this.config as { storage?: { indexes?: IndexDescription[] } })?.storage?.indexes ?? []
79
- const boundWitnessesCollectionName = this.boundWitnessSdkConfig.collection
80
- const payloadCollectionName = this.payloadSdkConfig.collection
81
-
82
- const bwStandardIndexes = standardIndexes.map(ix => ({ ...ix, name: `${boundWitnessesCollectionName}.${ix.name}` }))
83
- await ensureIndexesExistOnCollection(this.boundWitnesses, [...bwStandardIndexes, ...configIndexes])
84
- const payloadStandardIndexes = standardIndexes.map(ix => ({ ...ix, name: `${payloadCollectionName}.${ix.name}` }))
85
- await ensureIndexesExistOnCollection(this.payloads, [...payloadStandardIndexes, ...configIndexes])
86
- }
87
- }
88
- return MongoModuleBase
89
- }
90
-
91
- /**
92
- * Ensures the specified indexes exist on the collection
93
- * @param sdk The sdk to use for the collection
94
- * @param configIndexes The indexes to ensure exist on the collection
95
- */
96
- const ensureIndexesExistOnCollection = async (
97
- sdk: BaseMongoSdk<PayloadWithMongoMeta> | BaseMongoSdk<BoundWitnessWithMongoMeta>,
98
- configIndexes: IndexDescription[],
99
- ) => {
100
- await sdk.useCollection(async (collection) => {
101
- const collectionName = collection.collectionName.toLowerCase()
102
- const indexes = configIndexes.filter(ix => ix?.name?.toLowerCase().startsWith(collectionName))
103
- if (indexes.length === 0) return
104
- for (const ix of indexes) {
105
- try {
106
- await collection.createIndexes([ix])
107
- } catch (error) {
108
- const mongoServerError = error as MongoServerError
109
- const { codeName } = mongoServerError
110
- if (codeName === 'IndexKeySpecsConflict' || codeName === 'IndexOptionsConflict') {
111
- // Index already exists which is fine OR index exists with another name which is fine
112
- // TODO: For the latter case (IndexOptionsConflict) we could get into this case
113
- // if we change the TTL an existing index. We currently don't support TTLs so
114
- // we'll need to revisit this assumption if we do.
115
- continue
116
- }
117
- console.error(`Error creating index ${ix.name} for collection ${collectionName}: ${error}`)
118
- throw error
119
- }
120
- }
121
- })
122
- }
package/src/ModuleV2.ts DELETED
@@ -1,220 +0,0 @@
1
- import { BaseMongoSdk, BaseMongoSdkConfig } from '@xylabs/mongo'
2
- import {
3
- assertEx, isDefined, staticImplements,
4
- } from '@xylabs/sdk-js'
5
- import {
6
- MongoDBModuleParamsV2, MongoDBModuleStatic, MongoDBModuleV2, MongoDBStorageClassLabels,
7
- } from '@xyo-network/module-model-mongodb'
8
- import { PayloadWithMongoMeta } from '@xyo-network/payload-mongodb'
9
- import { Db, MongoServerError } from 'mongodb'
10
-
11
- import { AnyAbstractModule } from './AnyAbstractModule.ts'
12
- import { COLLECTIONS } from './Collections.ts'
13
- import { getBaseMongoSdkPrivateConfig } from './config/index.ts'
14
- import { IndexDescription } from './IndexDescription.ts'
15
- import { merge } from './merge.ts'
16
-
17
- const standardIndexes: IndexDescription[] = [
18
- {
19
- name: 'UX__hash', key: { _hash: 1 }, unique: true,
20
- },
21
- {
22
- name: 'IX__dataHash', key: { _dataHash: 1 }, unique: false,
23
- },
24
- {
25
- name: 'UX__sequence', key: { _sequence: 1 }, unique: true,
26
- },
27
- ]
28
-
29
- export const MongoDBModuleMixinV2 = <
30
- TParams extends MongoDBModuleParamsV2 = MongoDBModuleParamsV2,
31
- TModule extends AnyAbstractModule<TParams> = AnyAbstractModule<TParams>,
32
- >(
33
- ModuleBase: TModule,
34
- ) => {
35
- @staticImplements<MongoDBModuleStatic>()
36
- abstract class MongoModuleBase extends ModuleBase implements MongoDBModuleV2 {
37
- static readonly labels = MongoDBStorageClassLabels
38
- _payloadSdk: BaseMongoSdk<PayloadWithMongoMeta> | undefined
39
-
40
- get jobQueue() {
41
- return assertEx(this.params.jobQueue, () => 'MongoDBModule Error: jobQueue required for this module but is not defined')
42
- }
43
-
44
- get payloadSdkConfig(): BaseMongoSdkConfig {
45
- const defaultConfig = { collection: COLLECTIONS.Payloads }
46
- // If the params of config have payloadSdkConfig, merge it with the default config
47
- const paramsPayloadSdkConfig = this.params.payloadSdkConfig
48
- const configPayloadSdkConfig = this.config.payloadSdkConfig
49
- if (isDefined(paramsPayloadSdkConfig) || isDefined(configPayloadSdkConfig)) {
50
- return merge(
51
- defaultConfig,
52
- configPayloadSdkConfig ?? {},
53
- paramsPayloadSdkConfig ?? {},
54
- )
55
- } else {
56
- // Otherwise, attempt to get the config from the environment
57
- // TODO: Deprecate this in favor of params/config injection
58
- // This is a temporary solution to maintain backward compatibility
59
- // and should be removed in the future.
60
- const envConfig = getBaseMongoSdkPrivateConfig()
61
- return merge(
62
- defaultConfig,
63
- envConfig,
64
- )
65
- }
66
- }
67
-
68
- get payloads() {
69
- this._payloadSdk = this._payloadSdk ?? new BaseMongoSdk<PayloadWithMongoMeta>(this.payloadSdkConfig)
70
- return assertEx(this._payloadSdk)
71
- }
72
-
73
- /**
74
- * Ensures any indexes specified within the config are created. This method should be idempotent
75
- * allowing for multiple calls without causing errors while ensuring the desired state.
76
- */
77
- async ensureCollection(): Promise<void> {
78
- const { max } = this.config
79
- const payloadCollectionName = this.payloadSdkConfig.collection
80
-
81
- const payloadStandardIndexes = standardIndexes.map(ix => ({ ...ix, name: `${payloadCollectionName}.${ix.name}` }))
82
-
83
- if (isDefined(max)) {
84
- // Create capped collection if it doesn't exist or convert it if it does
85
- await ensureCappedCollection(this.payloads, max)
86
- // Recreate indexes after creating/converting a capped collection as
87
- // capped will remove all indexes on existing collections.
88
- // https://www.mongodb.com/docs/manual/reference/command/convertToCapped/
89
- await ensureIndexesExistOnCollection(this.payloads, [...payloadStandardIndexes])
90
- } else {
91
- // Create indexes (creates collection without having to write data to it)
92
- await ensureIndexesExistOnCollection(this.payloads, [...payloadStandardIndexes])
93
- }
94
- }
95
- }
96
- return MongoModuleBase
97
- }
98
-
99
- const collectionExists = async (db: Db, name: string): Promise<boolean> => {
100
- const collections = await db.listCollections({ name }).toArray()
101
- return collections.length > 0
102
- }
103
-
104
- /**
105
- * Ensures the specified indexes exist on the collection
106
- * @param sdk The sdk to use for the collection
107
- * @param configIndexes The indexes to ensure exist on the collection
108
- */
109
- const ensureIndexesExistOnCollection = async (
110
- sdk: BaseMongoSdk<PayloadWithMongoMeta>,
111
- configIndexes: IndexDescription[],
112
- ) => {
113
- await sdk.useCollection(async (collection) => {
114
- const collectionName = collection.collectionName.toLowerCase()
115
- const indexes = configIndexes.filter(ix => ix?.name?.toLowerCase().startsWith(collectionName))
116
- if (indexes.length === 0) return
117
- for (const ix of indexes) {
118
- try {
119
- await collection.createIndexes([ix])
120
- } catch (error) {
121
- const mongoServerError = error as MongoServerError
122
- const { codeName } = mongoServerError
123
- if (codeName === 'IndexKeySpecsConflict' || codeName === 'IndexOptionsConflict' || codeName === 'Unauthorized') {
124
- // Allowed errors:
125
- // - IndexKeySpecsConflict: Index already exists which is fine
126
- // - IndexOptionsConflict: Index already exists with another name which is fine
127
- // - Unauthorized: Index can't be created since we don't have permission to create indexes
128
- // which is fine so long as we're only viewing collection as readonly (determined by connection
129
- // string passed in so presumably the desired configuration)
130
- // TODO: For the latter case (IndexOptionsConflict) we could get into this case
131
- // if we change the TTL an existing index. We currently don't support TTLs so
132
- // we'll need to revisit this assumption if we do.
133
- continue
134
- }
135
- console.error(`Error creating index ${ix.name} for collection ${collectionName}: ${error}`)
136
- throw error
137
- }
138
- }
139
- })
140
- }
141
-
142
- /**
143
- * Ensures that a collection is capped with a max document count and a reasonable size.
144
- * If the collection exists and is not capped, it will be converted.
145
- * If it doesn't exist, it will be created.
146
- *
147
- * @param name The name of the collection.
148
- * @param count The maximum number of documents to retain.
149
- * @param documentSize Estimated average document size in bytes if collection is empty.
150
- */
151
- const ensureCappedCollection = async (sdk: BaseMongoSdk<PayloadWithMongoMeta>, max: number, docSize = 1024) => {
152
- await sdk.useCollection(async (collection) => {
153
- const name = collection.collectionName.toLowerCase()
154
- await sdk.useMongo(async (client) => {
155
- const db = client.db(collection.dbName)
156
- const exists = await collectionExists(db, name)
157
- const size = docSize * max
158
- return exists
159
- ? await ensureExistingCollectionIsCapped(sdk, max, size)
160
- // Create capped collection
161
- : await db.createCollection(name, {
162
- capped: true, size, max,
163
- })
164
- })
165
- })
166
- }
167
-
168
- /**
169
- * Converts an existing collection to a capped collection with a max document count.
170
- * Since MongoDB doesn't support `max` in `convertToCapped` or `cloneCollectionAsCapped`,
171
- * this function recreates the collection to work around Mongo's limitations.
172
- * https://www.mongodb.com/docs/manual/reference/command/convertToCapped/
173
- * https://www.mongodb.com/docs/manual/reference/command/clonecollectionascapped/
174
- * @param db - The MongoDB database instance
175
- * @param name - The name of the collection to convert
176
- * @param max - The maximum number of documents to retain
177
- * @param docSize - Fallback size (in bytes) to use if no documents exist (default 1KB)
178
- */
179
- const ensureExistingCollectionIsCapped = async (
180
- sdk: BaseMongoSdk<PayloadWithMongoMeta>,
181
- max: number,
182
- docSize = 1024,
183
- ): Promise<void> => {
184
- await sdk.useCollection(async (collection) => {
185
- const name = collection.collectionName.toLowerCase()
186
- await sdk.useMongo(async (client) => {
187
- const db = client.db(collection.dbName)
188
- const exists = await collectionExists(db, name)
189
- if (!exists) throw new Error(`Collection '${name}' does not exist`)
190
-
191
- const size = docSize * max
192
-
193
- const stats = await db.command({ collStats: name })
194
- if (stats.capped && stats.max === max && stats.maxSize === size) {
195
- return
196
- }
197
-
198
- const tmpName = `${name}_tmp_capped`
199
-
200
- // Create new capped collection
201
- await db.createCollection(tmpName, {
202
- capped: true, size, max,
203
- })
204
-
205
- // Copy most recent documents
206
- const docs = await collection
207
- .find()
208
-
209
- .sort({ $natural: -1 })
210
- .limit(max)
211
- .toArray()
212
-
213
- if (docs.length > 0) await db.collection(tmpName).insertMany(docs.toReversed())
214
-
215
- // Replace old collection
216
- await collection.drop()
217
- await db.collection(tmpName).rename(name)
218
- })
219
- })
220
- }
@@ -1,21 +0,0 @@
1
- import type { BaseMongoSdkPrivateConfig } from '@xylabs/mongo'
2
- import { BaseMongoSdk } from '@xylabs/mongo'
3
- import { assertEx } from '@xylabs/sdk-js'
4
- import type { Document } from 'mongodb'
5
-
6
- import { getMongoDBConfig } from './getMongoDBConfig.ts'
7
-
8
- export const getBaseMongoSdkPrivateConfig = (): BaseMongoSdkPrivateConfig => {
9
- const env = getMongoDBConfig()
10
- return {
11
- dbConnectionString: env.MONGO_CONNECTION_STRING,
12
- dbDomain: assertEx(env.MONGO_DOMAIN, () => 'Missing Mongo Domain'),
13
- dbName: assertEx(env.MONGO_DATABASE, () => 'Missing Mongo Database'),
14
- dbPassword: assertEx(env.MONGO_PASSWORD, () => 'Missing Mongo Password'),
15
- dbUserName: assertEx(env.MONGO_USERNAME, () => 'Missing Mongo Username'),
16
- }
17
- }
18
-
19
- export const getBaseMongoSdk = <T extends Document>(collection: string) => {
20
- return new BaseMongoSdk<T>({ ...getBaseMongoSdkPrivateConfig(), collection })
21
- }
@@ -1,18 +0,0 @@
1
- export type MongoDbConnectionStringEnvVar = 'MONGO_CONNECTION_STRING'
2
- export type MongoDbEnvVars = 'MONGO_DATABASE' | 'MONGO_DOMAIN' | 'MONGO_PASSWORD' | 'MONGO_USERNAME'
3
-
4
- export type MongoEnv = Record<MongoDbEnvVars | MongoDbConnectionStringEnvVar, string | undefined>
5
-
6
- export const getMongoDBConfig = (): MongoEnv => {
7
- const env: MongoEnv = {} as MongoEnv
8
- if (process.env.MONGO_CONNECTION_STRING) {
9
- env.MONGO_CONNECTION_STRING = process.env.MONGO_CONNECTION_STRING
10
- }
11
- if (process.env.MONGO_DOMAIN) {
12
- env.MONGO_DATABASE = process.env.MONGO_DATABASE
13
- env.MONGO_DOMAIN = process.env.MONGO_DOMAIN
14
- env.MONGO_PASSWORD = process.env.MONGO_PASSWORD
15
- env.MONGO_USERNAME = process.env.MONGO_USERNAME
16
- }
17
- return env
18
- }
@@ -1,9 +0,0 @@
1
- import { exists } from '@xylabs/sdk-js'
2
-
3
- import { getMongoDBConfig } from './getMongoDBConfig.ts'
4
-
5
- export const hasMongoDBConfig = (): boolean => {
6
- const env = getMongoDBConfig()
7
- const requiredValues = [env.MONGO_CONNECTION_STRING, env.MONGO_DATABASE, env.MONGO_DOMAIN, env.MONGO_PASSWORD, env.MONGO_USERNAME]
8
- return requiredValues.every(exists)
9
- }
@@ -1,3 +0,0 @@
1
- export * from './getBaseMongoSdk.ts'
2
- export * from './getMongoDBConfig.ts'
3
- export * from './hasMongoDBConfig.ts'
package/src/index.ts DELETED
@@ -1,9 +0,0 @@
1
- export * from './Collections.ts'
2
- export * from './config/index.ts'
3
- export * from './Databases.ts'
4
- export * from './Defaults.ts'
5
- export * from './IndexDescription.ts'
6
- export * from './Indexes/index.ts'
7
- export * from './Module.ts'
8
- export * from './ModuleV2.ts'
9
- export * from './util/index.ts'
package/src/merge.ts DELETED
@@ -1,35 +0,0 @@
1
- /* eslint-disable @typescript-eslint/no-explicit-any */
2
- function isObject(val: unknown): val is Record<string, any> {
3
- return val !== null && typeof val === 'object'
4
- }
5
-
6
- export function merge<T extends object>(target: T, ...sources: any[]): T {
7
- if (!isObject(target)) {
8
- throw new TypeError('Target must be an object')
9
- }
10
-
11
- for (const source of sources) {
12
- if (!isObject(source)) {
13
- continue
14
- }
15
-
16
- for (const key of Object.keys(source)) {
17
- const sourceVal = source[key]
18
- const targetVal = (target as any)[key]
19
-
20
- if (Array.isArray(sourceVal)) {
21
- // Arrays are replaced, not deeply merged (lodash behavior)
22
- (target as any)[key] = [...sourceVal]
23
- } else if (isObject(sourceVal)) {
24
- if (!isObject(targetVal)) {
25
- (target as any)[key] = {}
26
- }
27
- merge((target as any)[key], sourceVal)
28
- } else {
29
- (target as any)[key] = sourceVal
30
- }
31
- }
32
- }
33
-
34
- return target
35
- }
@@ -1,5 +0,0 @@
1
- export const escapeChar = '#'
2
-
3
- export const toDbProperty = (value: string) => value.replaceAll('.', escapeChar)
4
-
5
- export const fromDbProperty = (value: string) => value.replaceAll(escapeChar, '.')
package/src/util/index.ts DELETED
@@ -1 +0,0 @@
1
- export * from './dbProperty.ts'