insite-db 2.3.5 → 2.4.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 +1 -1
- package/README.md +95 -4
- package/dist/index.js +5 -7
- package/dist/index.js.map +4 -4
- package/package.json +49 -34
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -1,13 +1,104 @@
|
|
|
1
|
-
#
|
|
1
|
+
# insite-db
|
|
2
|
+
|
|
3
|
+
MongoDB layer for inSite — connection, collection management, Change Streams, JSON Schema validation, and indexes.
|
|
4
|
+
|
|
5
|
+
Part of [inSite](../../README.md) — used by [insite-server](../server/README.md), [insite-config](../config/README.md), [insite-users-server](../users-server/README.md), [insite-subscriptions-server](../subscriptions-server/README.md).
|
|
2
6
|
|
|
3
7
|
## Installation
|
|
4
8
|
|
|
5
9
|
```sh
|
|
6
|
-
|
|
10
|
+
npm install insite-db
|
|
7
11
|
```
|
|
8
12
|
|
|
9
|
-
Or
|
|
13
|
+
Or:
|
|
10
14
|
|
|
11
15
|
```sh
|
|
12
|
-
|
|
16
|
+
bun add insite-db
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Quick Start
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
import { connect } from "insite-db";
|
|
23
|
+
|
|
24
|
+
const { client, db, collections } = await connect({
|
|
25
|
+
url: "mongodb://127.0.0.1:27017",
|
|
26
|
+
name: "myapp"
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const users = await collections.ensure("users", {
|
|
30
|
+
schema: { /* JSON Schema */ },
|
|
31
|
+
indexes: [[{ email: 1 }, { unique: true }]]
|
|
32
|
+
});
|
|
13
33
|
```
|
|
34
|
+
|
|
35
|
+
## API Reference
|
|
36
|
+
|
|
37
|
+
### Exports
|
|
38
|
+
|
|
39
|
+
| Export | Type | Description |
|
|
40
|
+
|--------|------|-------------|
|
|
41
|
+
| `connect` | function | Connects to MongoDB |
|
|
42
|
+
| `Collections` | class | Map-like manager with `ensure()` |
|
|
43
|
+
| `newObjectIdString` | function | New ObjectId as string |
|
|
44
|
+
| `printChangeStreamChangeDetails` | function | Log change (masks sensitive data) |
|
|
45
|
+
| `printChangeStreamError` | function | Log Change Stream error |
|
|
46
|
+
| `DB` | type | `Db` from mongodb |
|
|
47
|
+
| `CollectionSchema` | type | `JSONSchema4` |
|
|
48
|
+
| `Options` | type | MongoClientOptions & url, name, onConnect |
|
|
49
|
+
| `CollectionOptions` | type | Options for `ensure()` |
|
|
50
|
+
| `CollectionIndexes` | type | `[IndexSpecification, CreateIndexesOptions?][]` |
|
|
51
|
+
| `ChangeStreamListener<TSchema>` | type | `(doc: ChangeStreamDocument<TSchema>) => void` |
|
|
52
|
+
| `WatchedCollection<Doc>` | type | Collection with change stream methods |
|
|
53
|
+
| (full mongodb package) | — | Re-exported |
|
|
54
|
+
|
|
55
|
+
### connect(options)
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
function connect(options: Options): Promise<{ client: MongoClient; db: DB; collections: Collections }>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
| Parameter | Type | Description |
|
|
62
|
+
|-----------|------|-------------|
|
|
63
|
+
| `url` | `string` | MongoDB connection string |
|
|
64
|
+
| `name` | `string` | Database name |
|
|
65
|
+
| `onConnect` | `(collections, db) => Promise<void>` | Optional callback after connect |
|
|
66
|
+
| `...mongoClientOptions` | `MongoClientOptions` | Passed to MongoClient |
|
|
67
|
+
|
|
68
|
+
Note: `localhost` in URL is replaced with `127.0.0.1`.
|
|
69
|
+
|
|
70
|
+
### Collections
|
|
71
|
+
|
|
72
|
+
`class Collections extends Map<string, Collection>`
|
|
73
|
+
|
|
74
|
+
| Property | Type | Description |
|
|
75
|
+
|----------|------|-------------|
|
|
76
|
+
| `db` | `DB` | Raw MongoDB Db instance |
|
|
77
|
+
|
|
78
|
+
**ensure(name, options?)**
|
|
79
|
+
|
|
80
|
+
Gets or creates collection. With `watch: false`, returns plain `Collection`.
|
|
81
|
+
|
|
82
|
+
**CollectionOptions:** schema, indexes, blockCompressor, watch (default true), fullDocument (default true), quiet
|
|
83
|
+
|
|
84
|
+
### Collection extensions (WatchedCollection)
|
|
85
|
+
|
|
86
|
+
| Method | Description |
|
|
87
|
+
|--------|-------------|
|
|
88
|
+
| `ensureIndexes` | Create indexes if missing |
|
|
89
|
+
| `changeStream` | Change Stream instance |
|
|
90
|
+
| `onChange`, `prependChange` | Add change listener |
|
|
91
|
+
| `onceChange`, `prependOnceChange` | One-time listener |
|
|
92
|
+
| `removeChangeListener` | Remove listener |
|
|
93
|
+
|
|
94
|
+
## Environment
|
|
95
|
+
|
|
96
|
+
`NODE_ENV=development` — change stream events logged unless `quiet: true`. `LOGS_MASK_SENSITIVE`, `LOGS_MASK_PII`, `LOGS_MASK_SKIP` — field patterns for masking.
|
|
97
|
+
|
|
98
|
+
## Related
|
|
99
|
+
|
|
100
|
+
- [insite-server](../server/README.md), [insite-config](../config/README.md), [insite-users-server](../users-server/README.md), [insite-subscriptions-server](../subscriptions-server/README.md)
|
|
101
|
+
|
|
102
|
+
## License
|
|
103
|
+
|
|
104
|
+
MIT
|
package/dist/index.js
CHANGED
|
@@ -1,18 +1,16 @@
|
|
|
1
|
-
import{MongoClient as
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
`,"updateDescription:",e.updateDescription);break;case"delete":t.push("_id:",e.documentKey._id);break;default:t.push(e)}console.info("\u{1F33F}\u{1F38F}",`\x1B[1m${this.parent.collectionName}\x1B[0m`,`\x1B[3m${e.operationType}\x1B[0m`,...t)}function P(e){console.error(`\u{1F33F}\u2757\uFE0F MongoDB ${this.parent.collectionName} Change Stream:
|
|
5
|
-
`,e.stack)}var k=class extends Map{constructor(t){super(),this.db=t}db;#e=new Map;#t=new Map;#n=new Map;async ensure(t,n={}){let{db:r}=this,o=this.get(t)??await this.#e.get(t);if(!o){let{promise:s,resolve:c}=Promise.withResolvers();this.#e.set(t,s);try{if((await r.listCollections({name:t},{nameOnly:!0}).toArray()).length?o=r.collection(t):(o=await r.createCollection(t,{...n.schema&&{validator:{$jsonSchema:n.schema}},...n.blockCompressor&&{storageEngine:{wiredTiger:{configString:`block_compressor=${n.blockCompressor}`}}}}),delete n.schema,delete n.blockCompressor),n.watch!==!1){let i=o.watch(void 0,{fullDocument:n.fullDocument===!1?void 0:"updateLookup"});(process.env.NODE_ENV==="development"?n.quiet!==!0:!n.quiet)&&i.on("change",j),i.on("error",P),o.changeStream=i}this.set(t,o),this[t]=o,c(o)}finally{this.#e.delete(t)}}return n.schema&&(this.#t.has(t)?console.warn(`\u{1F33F}\u26A0\uFE0F Attempt to set schema for the \x1B[1m${t}\x1B[22m collection at
|
|
1
|
+
import{MongoClient as L}from"mongodb";import{captureStackTrace as m}from"@nesvet/n";import{ObjectId as b}from"mongodb";var D=["password","secret","token","key","auth","session","hash","salt","fingerprint"],w=["mail","phone","name","address","card","ssn","passport"],k=process.env.LOGS_MASK_SENSITIVE?.split(",").map(e=>e.trim().toLowerCase())??[],x=process.env.LOGS_MASK_PII?.split(",").map(e=>e.trim().toLowerCase())??[],T=process.env.LOGS_MASK_SKIP?.split(",").map(e=>e.trim().toLowerCase())??["_id","id","timestamp","created","updated"],I=Object.freeze(new Set([...D,...k])),E=Object.freeze(new Set([...w,...x])),O=Object.freeze(new Set(T)),l=new Map,_=2048,h={email:e=>{let t=e.indexOf("@");return t>1?`${e[0]}***@${e.slice(t+1)}`:"***@***"},phone:e=>{let t="";for(let n=0;n<e.length;n++){let o=e.codePointAt(n);o&&o>=48&&o<=57&&(t+=e[n])}return t.length>6?`${t.slice(0,3)}***${t.slice(-2)}`:"***"},card:e=>{let t="";for(let n=0;n<e.length;n++){let o=e.codePointAt(n);o&&o>=48&&o<=57&&(t+=e[n])}return t.length>=13?`****-****-****-${t.slice(-4)}`:"****"},generic:e=>{let{length:t}=e;return t<4?"***":t<9?`${e[0]}***`:`${e[0]+e[1]}***${e.slice(-2)}`}},u=()=>{if(l.size>=_){let e=l.keys().next().value;e&&l.delete(e)}};function M(e){let t=l.get(e);if(t!==void 0)return t;let n=e.toLowerCase().replaceAll(/[_-]/g,"");if(O.has(n))return u(),l.set(e,0),0;for(let o of I)if(n.includes(o))return u(),l.set(e,1),1;for(let o of E)if(n.includes(o))return u(),l.set(e,2),2;return-1}function P(e){let t=e.toLowerCase();return t.includes("mail")?h.email:t.includes("phone")||t.includes("tel")?h.phone:t.includes("card")||t.includes("credit")?h.card:h.generic}function g(e,t){let n=t?.depth??50;function o(r,c){if(c>n||r===null||r===void 0||typeof r!="object"||r instanceof Date)return r;if(Array.isArray(r))return r.map(i=>o(i,c+1));if(r.constructor!==Object)return r;let s={};for(let i in r){if(!Object.hasOwn(r,i))continue;let a=r[i];if(typeof a=="string"&&a.length>0)switch(M(i)){case 0:case-1:s[i]=a;break;case 1:s[i]="[MASKED]";break;case 2:s[i]=P(i)(a)}else a!=null&&typeof a=="object"?s[i]=o(a,c+1):s[i]=a}return s}return o(e,0)}function f(e,t){switch(e.operationType){case"delete":case"drop":case"dropDatabase":case"invalidate":return e}let n={...e};return"fullDocument"in n&&(n.fullDocument=g(n.fullDocument,t)),"updateDescription"in n&&n.updateDescription?.updatedFields&&(n.updateDescription={...n.updateDescription,updatedFields:g(n.updateDescription.updatedFields,t)}),n}function F(){return new b().toString()}function S(e){e=f(e);let t=[];switch(e.operationType){case"insert":case"replace":t.push("fullDocument:",e.fullDocument);break;case"update":t.push("_id:",e.documentKey._id,`
|
|
2
|
+
`,"updateDescription:",e.updateDescription);break;case"delete":t.push("_id:",e.documentKey._id);break;default:t.push(e)}console.info("\u{1F33F}\u{1F38F}",`\x1B[1m${this.parent.collectionName}\x1B[0m`,`\x1B[3m${e.operationType}\x1B[0m`,...t)}function C(e){console.error(`\u{1F33F}\u2757\uFE0F MongoDB ${this.parent.collectionName} Change Stream:
|
|
3
|
+
`,e.stack)}var d=class extends Map{constructor(t){super(),this.db=t}db;#e=new Map;#t=new Map;#n=new Map;async ensure(t,n={}){let{db:o}=this,r=this.get(t)??await this.#e.get(t);if(!r){let{promise:c,resolve:s}=Promise.withResolvers();this.#e.set(t,c);try{if((await o.listCollections({name:t},{nameOnly:!0}).toArray()).length?r=o.collection(t):(r=await o.createCollection(t,{...n.schema&&{validator:{$jsonSchema:n.schema}},...n.blockCompressor&&{storageEngine:{wiredTiger:{configString:`block_compressor=${n.blockCompressor}`}}}}),delete n.schema,delete n.blockCompressor),n.watch!==!1){let i=r.watch(void 0,{fullDocument:n.fullDocument===!1?void 0:"updateLookup"});(process.env.NODE_ENV==="development"?n.quiet!==!0:!n.quiet)&&i.on("change",S),i.on("error",C),r.changeStream=i}this.set(t,r),this[t]=r,s(r)}finally{this.#e.delete(t)}}return n.schema&&(this.#t.has(t)?console.warn(`\u{1F33F}\u26A0\uFE0F Attempt to set schema for the \x1B[1m${t}\x1B[22m collection at
|
|
6
4
|
${m()}
|
|
7
5
|
|
|
8
6
|
Which has already been set at
|
|
9
7
|
${this.#t.get(t)}
|
|
10
8
|
|
|
11
|
-
Skipping`):(this.#t.set(t,m()),await
|
|
9
|
+
Skipping`):(this.#t.set(t,m()),await o.command({collMod:t,validator:{$jsonSchema:n.schema}}))),n.indexes&&(this.#n.has(t)?console.warn(`\u{1F33F}\u26A0\uFE0F Attempt to set indexes for the \x1B[1m${t}\x1B[22m collection at
|
|
12
10
|
${m()}
|
|
13
11
|
|
|
14
12
|
Which have already been set at
|
|
15
13
|
${this.#n.get(t)}
|
|
16
14
|
|
|
17
|
-
Skipping`):(this.#n.set(t,m()),await
|
|
15
|
+
Skipping`):(this.#n.set(t,m()),await r.ensureIndexes(n.indexes))),r}};async function G({url:e,name:t,onConnect:n,...o}){/localhost/.test(e)&&(e=e.replace(/localhost/,"127.0.0.1"));let r=new L(e,{maxPoolSize:100,...o});try{await r.connect(),console.info("\u{1F33F} MongoDB Client connected to",e.replace(/(?<=\/\/)[^:]+?:[^@]+@/,"").replace(/[/?][^/]*$/,""))}catch(i){console.error("\u{1F33F}\u2757\uFE0F MongoDB Client connection: ",i)}r.on("close",()=>console.error("\u{1F33F}\u2757\uFE0F MongoDB socket closed")).on("error",i=>console.error("\u{1F33F}\u2757\uFE0F MongoDB:",i)).on("parseError",i=>console.error("\u{1F33F}\u2757\uFE0F MongoDB parse:",i)).on("reconnect",()=>console.info("\u{1F33F} MongoDB reconnected")).on("timeout",()=>console.error("\u{1F33F}\u2757\uFE0F MongoDB timeout"));let c=r.db(t),s=new d(c);return await n?.(s,c),{client:r,db:c,collections:s}}import{isDeepStrictEqual as y}from"node:util";import{Collection as p}from"mongodb";import{omit as $}from"@nesvet/n";var B=2;p.prototype.ensureIndexes=async function(e,t=!1){if(t){let n=await this.indexes();for(let o=0;o<e.length;o++){let[r,c={}]=e[o];for(let s=0;s<n.length;s++){let i=n[s];if(y(r,i.key)&&y(c,$(i,["v","key","name"]))){e.splice(o--,1),n.splice(s,1);break}}}await Promise.all([...e.map(o=>this.createIndex(...o)),...n.filter(({name:o,v:r})=>o&&o!=="_id_"&&(!r||r<=B)).map(({name:o})=>this.dropIndex(o))])}else await Promise.all(e.map(n=>this.createIndex(...n)))};p.prototype.onChange=function(e){return this.changeStream.on("change",e),this};p.prototype.prependChange=function(e){return this.changeStream.prependListener("change",e),this};p.prototype.onceChange=function(e){return this.changeStream.once("change",e),this};p.prototype.prependOnceChange=function(e){return this.changeStream.prependOnceListener("change",e),this};p.prototype.removeChangeListener=function(e){return this.changeStream.removeListener("change",e),this};export*from"mongodb";export{G as connect,F as newObjectIdString,S as printChangeStreamChangeDetails,C as printChangeStreamError};
|
|
18
16
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/connect.ts", "
|
|
4
|
-
"sourcesContent": ["import { MongoClient } from \"mongodb\";\nimport { Collections } from \"./Collections\";\nimport type { Options } from \"./types\";\n\n\nexport async function connect({\n\turl,\n\tname,\n\tonConnect,\n\t...mongoClientOptions\n}: Options) {\n\t\n\tif (/localhost/.test(url))\n\t\turl = url.replace(/localhost/, \"127.0.0.1\");\n\t\n\tconst client = new MongoClient(url, {\n\t\tmaxPoolSize: 100,\n\t\t...mongoClientOptions\n\t});\n\t\n\ttry {\n\t\tawait client.connect();\n\t\tconsole.info(\"\uD83C\uDF3F MongoDB Client connected to\", url.replace(/(?<=\\/\\/)[^:]+?:[^@]+@/, \"\").replace(/[/?][^/]*$/, \"\"));\n\t} catch (error) {\n\t\tconsole.error(\"\uD83C\uDF3F\u2757\uFE0F MongoDB Client connection: \", error);\n\t}\n\t\n\tclient\n\t\t.on(\"close\", () => console.error(\"\uD83C\uDF3F\u2757\uFE0F MongoDB socket closed\"))\n\t\t.on(\"error\", error => console.error(\"\uD83C\uDF3F\u2757\uFE0F MongoDB:\", error))\n\t\t.on(\"parseError\", error => console.error(\"\uD83C\uDF3F\u2757\uFE0F MongoDB parse:\", error))\n\t\t.on(\"reconnect\", () => console.info(\"\uD83C\uDF3F MongoDB reconnected\"))\n\t\t.on(\"timeout\", () => console.error(\"\uD83C\uDF3F\u2757\uFE0F MongoDB timeout\"));\n\t\n\tconst db = client.db(name);\n\t\n\tconst collections = new Collections(db);\n\t\n\tawait onConnect?.(collections, db);\n\t\n\treturn {\n\t\tclient,\n\t\tdb,\n\t\tcollections\n\t};\n}\n", "declare global {\n\tinterface ErrorConstructor {\n\t\tcaptureStackTrace(targetObject: object, constructorOpt?: Function): void;// eslint-disable-line @typescript-eslint/no-unsafe-function-type\n\t}\n}\n\n\nexport function captureStackTrace(depth = 1, indent = 4) {\n\t\n\tconst indentString = \" \".repeat(indent);\n\t\n\tconst object = {} as { stack: string };\n\t\n\tError.captureStackTrace(object, captureStackTrace);\n\t\n\tconst stackTrace =\n\t\tobject.stack\n\t\t\t.replace(/^Error\\W+/m, \"\")\n\t\t\t.replaceAll(/^\\s+/gm, \"\")\n\t\t\t.split(\"\\n\")\n\t\t\t.slice(depth)\n\t\t\t.join(`\\n${indentString}`);\n\t\n\treturn `${indentString}${stackTrace}`;\n}\n", "export function noop() { /**/ }\n", "/* eslint-disable @typescript-eslint/no-explicit-any */\n\ntype Value<T> = PromiseLike<T> | T;\ntype Resolve<T> = (value: Value<T>) => void;\ntype Reject = (reason?: any) => void;\n\ntype Options = {\n\tsignal?: AbortSignal;\n\ttimeout?: number;\n};\n\nconst nativesMap = new WeakMap<StatefulPromise<any>, { resolve: Resolve<any>; reject: Reject }>();\n\n\nexport class StatefulPromise<T> extends Promise<T> {\n\tconstructor(\n\t\texecutor?: (resolve: Resolve<T>, reject: Reject) => void,\n\t\toptions?: Options\n\t) {\n\t\tlet nativeResolve: Resolve<T>;\n\t\tlet nativeReject: Reject;\n\t\t\n\t\tsuper((resolve, reject) => {\n\t\t\tnativeResolve = resolve;\n\t\t\tnativeReject = reject;\n\t\t\t\n\t\t});\n\t\t\n\t\tnativesMap.set(this, { resolve: nativeResolve!, reject: nativeReject! });\n\t\t\n\t\tif (options?.signal)\n\t\t\tif (options.signal.aborted)\n\t\t\t\tthis.reject(new DOMException(\"Aborted\", \"AbortError\"));\n\t\t\telse {\n\t\t\t\tconst abortListener = () => this.reject(new DOMException(\"Aborted\", \"AbortError\"));\n\t\t\t\t\n\t\t\t\toptions.signal.addEventListener(\"abort\", abortListener);\n\t\t\t\t\n\t\t\t\tthis.finally(() => options.signal?.removeEventListener(\"abort\", abortListener));\n\t\t\t}\n\t\t\n\t\tif (typeof options?.timeout === \"number\" && Number.isFinite(options.timeout)) {\n\t\t\tconst timeout = setTimeout(() => this.reject(new DOMException(\"Timeout exceeded\", \"TimeoutError\")), options.timeout);\n\t\t\t\n\t\t\tthis.finally(() => clearTimeout(timeout));\n\t\t}\n\t\t\n\t\texecutor?.(this.resolve, this.reject);\n\t\t\n\t}\n\t\n\tisPending = true;\n\tisFulfilled = false;\n\tisRejected = false;\n\t\n\tstate: \"fulfilled\" | \"pending\" | \"rejected\" = \"pending\";\n\t\n\tresult?: T | unknown;\n\t\n\treadonly resolve = (value: Value<T>) => {\n\t\t\n\t\tif (this.isPending) {\n\t\t\tthis.isPending = false;\n\t\t\tthis.isFulfilled = true;\n\t\t\tthis.state = \"fulfilled\";\n\t\t\tthis.result = value;\n\t\t\t\n\t\t\tconst native = nativesMap.get(this);\n\t\t\t\n\t\t\tif (native) {\n\t\t\t\tnative.resolve.call(this, value);\n\t\t\t\tnativesMap.delete(this);\n\t\t\t}\n\t\t}\n\t\t\n\t};\n\t\n\treadonly reject = (reason?: any) => {\n\t\t\n\t\tif (this.isPending) {\n\t\t\tthis.isPending = false;\n\t\t\tthis.isRejected = true;\n\t\t\tthis.state = \"rejected\";\n\t\t\tthis.result = reason;\n\t\t\t\n\t\t\tconst native = nativesMap.get(this);\n\t\t\t\n\t\t\tif (native) {\n\t\t\t\tnative.reject.call(this, reason);\n\t\t\t\tnativesMap.delete(this);\n\t\t\t}\n\t\t}\n\t\t\n\t};\n\t\n\t\n\tstatic resolved<U>(value: U): StatefulPromise<U> {\n\t\treturn new StatefulPromise<U>(resolve => resolve(value));\n\t}\n\t\n\tstatic rejected(reason: unknown): StatefulPromise<never> {\n\t\treturn new StatefulPromise((_, reject) => reject(reason));\n\t}\n\t\n}\n", "import { noop } from \"./noop.js\";\nimport { StatefulPromise } from \"./StatefulPromise.js\";\n\n\ntype Callback = (...args: any[]) => unknown;// eslint-disable-line @typescript-eslint/no-explicit-any\ntype FunctionOrBoolean = (() => unknown) | boolean;\ntype Options = { leading?: FunctionOrBoolean; maxWait?: number; trailing?: FunctionOrBoolean };\n\ntype DebouncedFunction<C extends Callback> = {\n\t(this: ThisParameterType<C>, ...args: Parameters<C>): Promise<Awaited<ReturnType<C>>>;\n};\n\nexport type Debounced<C extends Callback, R extends ReturnType<C>> = DebouncedFunction<C> & {\n\tcallback: C;\n\tpromise: StatefulPromise<R>;\n\tresolve: (value: R) => void;\n\treject: (reason?: unknown) => void;\n\trun(): Promise<R>;\n\tclear(shouldRun?: boolean): Promise<void>;\n};\n\n\nexport function debounce<C extends Callback, R extends ReturnType<C>>(callback: C, limit = 0, options: Options = {}) {\n\tlet { leading = false, trailing = true } = options;\n\tconst { maxWait = Infinity } = options;\n\t\n\tlet timeout: ReturnType<typeof setTimeout> | undefined;\n\tlet maxWaitTimeout: ReturnType<typeof setTimeout> | undefined;\n\tlet end: number | undefined;\n\tlet context: ThisParameterType<C>;\n\tlet args: unknown[];\n\tlet initial: FunctionOrBoolean;\n\tlet final: FunctionOrBoolean;\n\tlet result: R;\n\t\n\tconst expired = async () => {\n\t\t\n\t\tconst n = Date.now();\n\t\t\n\t\tif (n >= end!) {\n\t\t\ttimeout = undefined;\n\t\t\tend = undefined;\n\t\t\t\n\t\t\tclearTimeout(maxWaitTimeout);\n\t\t\tmaxWaitTimeout = undefined;\n\t\t\t\n\t\t\tif (typeof final == \"function\")\n\t\t\t\tawait final();\n\t\t\t\n\t\t\tdebounced.resolve(result);\n\t\t\t\n\t\t\tinitial = leading;\n\t\t} else {\n\t\t\tclearTimeout(timeout);\n\t\t\ttimeout = setTimeout(expired, end! - n);\n\t\t}\n\t\t\n\t};\n\t\n\tconst maxWaitExpired = Number.isFinite(maxWait) ? () => {\n\t\t\n\t\tif (final === run)\n\t\t\tfinal = false;\n\t\t\n\t\trun();\n\t\t\n\t\tmaxWaitTimeout = setTimeout(maxWaitExpired as TimerHandler, maxWait);\n\t\t\n\t} : null;\n\t\n\tasync function run() {\n\t\ttry {\n\t\t\tresult = await callback.apply(context, args) as R;\n\t\t\t\n\t\t\treturn result;\n\t\t} catch (error) {\n\t\t\tdebounced.reject(error);\n\t\t\t\n\t\t\tthrow error;\n\t\t}\n\t}\n\t\n\tif (leading && typeof leading == \"boolean\")\n\t\tleading = run;\n\tinitial = leading;\n\t\n\tif (trailing && typeof trailing == \"boolean\")\n\t\ttrailing = run;\n\tfinal = trailing;\n\t\n\tconst debounced: Debounced<C, R> = Object.assign(function (..._args) {\n\t\targs = _args;\n\t\tcontext = this;// eslint-disable-line no-invalid-this\n\t\t\n\t\tend = Date.now() + limit;\n\t\tfinal = trailing;\n\t\t\n\t\tif (!debounced.promise.isPending)\n\t\t\tdebounced.promise = new StatefulPromise<R>((resolve, reject) => {\n\t\t\t\tdebounced.resolve = resolve;\n\t\t\t\tdebounced.reject = reject;\n\t\t\t\t\n\t\t\t\tif (typeof initial == \"function\") {\n\t\t\t\t\tinitial();\n\t\t\t\t\t\n\t\t\t\t\tinitial = false;\n\t\t\t\t\t\n\t\t\t\t\tif (final === run)\n\t\t\t\t\t\tfinal = false;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tif (!timeout) {\n\t\t\t\t\ttimeout = setTimeout(expired, limit);\n\t\t\t\t\t\n\t\t\t\t\tif (maxWaitExpired)\n\t\t\t\t\t\tmaxWaitTimeout = setTimeout(maxWaitExpired, maxWait);\n\t\t\t\t}\n\t\t\t\t\n\t\t\t});\n\t\t\n\t\treturn debounced.promise;\n\t} as DebouncedFunction<C>, {\n\t\tcallback,\n\t\tpromise: StatefulPromise.resolved(undefined as unknown as R),\n\t\tresolve: noop,\n\t\treject: noop,\n\t\trun,\n\t\tclear: async (shouldRun?: boolean) => {\n\t\t\t\n\t\t\tclearTimeout(timeout);\n\t\t\ttimeout = undefined;\n\t\t\t\n\t\t\tclearTimeout(maxWaitTimeout);\n\t\t\tmaxWaitTimeout = undefined;\n\t\t\t\n\t\t\tdebounced.resolve(shouldRun ? await run() : result);\n\t\t\t\n\t\t}\n\t});\n\t\n\treturn debounced;\n}\n\n\ndebounce.noop = Object.assign(() => { /**/ }, {\n\tcallback: noop,\n\tpromise: StatefulPromise.resolved(undefined), // eslint-disable-line unicorn/no-useless-undefined\n\tresolve: noop,\n\treject: noop,\n\trun: noop,\n\tclear: noop\n}) as Debounced<() => void, void>;\n\n\nexport function throttle(callback: Callback, limit?: number, options?: Options) {\n\treturn debounce(callback, limit, {\n\t\tmaxWait: limit,\n\t\tleading: true,\n\t\ttrailing: true,\n\t\t...options\n\t});\n}\n", "export function howmuch(number: [] | number, one: string, two: string, five: boolean | string, shouldPrintNumber = true) {\n\tif (Array.isArray(number))\n\t\tnumber = number.length;\n\t\n\tif (typeof five != \"string\") {\n\t\tshouldPrintNumber = five ?? true;\n\t\tfive = two;\n\t}\n\t\n\t\n\treturn (shouldPrintNumber ? `${number}\u00A0` : \"\") + howmuch.raw(number, one, two, five);\n}\n\nhowmuch.raw = (number: number, one: string, two: string, five = two) => {\n\tnumber = Math.abs(number);\n\tconst u = number % 10;\n\tconst d = number % 100;\n\t\n\treturn (\n\t\t(u === 1 && d !== 11) ?\n\t\t\tone :\n\t\t\t((u >= 2 && u <= 4) && !(d >= 12 && d <= 15)) ?\n\t\t\t\ttwo :\n\t\t\t\tfive\n\t);\n};\n", "export function omit<O extends object, K extends keyof O>(object: O, keys: K[]): Omit<O, K> {\n\tconst result = { ...object };\n\t\n\tfor (const key of keys)\n\t\tdelete result[key];\n\t\n\treturn result;\n}\n", "import { ObjectId, type ChangeStream, type ChangeStreamDocument } from \"mongodb\";\nimport { maskChangeStreamDocument } from \"./masker\";\nimport type { WatchedCollection } from \"./types\";\n\n\nexport function newObjectIdString() {\n\treturn (new ObjectId()).toString();\n}\n\n/** @this ChangeStream */\nexport function printChangeStreamChangeDetails(this: ChangeStream, next: ChangeStreamDocument) {\n\tnext = maskChangeStreamDocument(next);\n\t\n\tconst messages = [];\n\t\n\tswitch (next.operationType) {\n\t\tcase \"insert\":\n\t\tcase \"replace\":\n\t\t\tmessages.push(\"fullDocument:\", next.fullDocument);\n\t\t\tbreak;\n\t\t\n\t\tcase \"update\":\n\t\t\tmessages.push(\"_id:\", next.documentKey._id, \"\\n\", \"updateDescription:\", next.updateDescription);\n\t\t\tbreak;\n\t\t\n\t\tcase \"delete\":\n\t\t\tmessages.push(\"_id:\", next.documentKey._id);\n\t\t\tbreak;\n\t\t\n\t\tdefault:\n\t\t\tmessages.push(next);\n\t}\n\t\n\tconsole.info(\"\uD83C\uDF3F\uD83C\uDF8F\", `\\x1B[1m${(this.parent as WatchedCollection).collectionName}\\x1B[0m`, `\\x1B[3m${next.operationType}\\x1B[0m`, ...messages);\n\t\n}\n\n/** @this ChangeStream */\nexport function printChangeStreamError(this: ChangeStream, error: Error) {\n\tconsole.error(`\uD83C\uDF3F\u2757\uFE0F MongoDB ${(this.parent as WatchedCollection).collectionName} Change Stream:\\n`, error.stack);\n\t\n}\n", "import type { ChangeStreamDocument } from \"mongodb\";\n\n\ntype MaskConfig = {\n\treadonly sensitive?: ReadonlySet<string>;\n\treadonly pii?: ReadonlySet<string>;\n\treadonly skip?: ReadonlySet<string>;\n\treadonly depth?: number;\n};\n\nconst enum FieldType {\n\tPii = 2,\n\tSensitive = 1,\n\tSkip = 0,\n\tUnknown = -1\n}\n\n\nconst SENSITIVE = [ \"password\", \"secret\", \"token\", \"key\", \"auth\", \"session\", \"hash\", \"salt\", \"fingerprint\" ];\nconst PII = [ \"mail\", \"phone\", \"name\", \"address\", \"card\", \"ssn\", \"passport\" ];\n\nconst ENV_SENSITIVE = process.env.LOGS_MASK_SENSITIVE?.split(\",\").map(s => s.trim().toLowerCase()) ?? [];\nconst ENV_PII = process.env.LOGS_MASK_PII?.split(\",\").map(s => s.trim().toLowerCase()) ?? [];\nconst ENV_SKIP = process.env.LOGS_MASK_SKIP?.split(\",\").map(s => s.trim().toLowerCase()) ?? [ \"_id\", \"id\", \"timestamp\", \"created\", \"updated\" ];\n\nconst SENSITIVE_SET = Object.freeze(new Set([ ...SENSITIVE, ...ENV_SENSITIVE ]));\nconst PII_SET = Object.freeze(new Set([ ...PII, ...ENV_PII ]));\nconst SKIP_SET = Object.freeze(new Set(ENV_SKIP));\n\nconst cache = new Map<string, FieldType.Pii | FieldType.Sensitive | FieldType.Skip>();\nconst CACHE_SIZE = 2048;\n\nconst mask = {\n\t\n\temail: (v: string): string => {\n\t\tconst i = v.indexOf(\"@\");\n\t\t\n\t\treturn i > 1 ? `${v[0]}***@${v.slice(i + 1)}` : \"***@***\";\n\t},\n\t\n\tphone: (v: string): string => {\n\t\t\n\t\tlet digits = \"\";\n\t\t\n\t\tfor (let i = 0; i < v.length; i++) {\n\t\t\tconst c = v.codePointAt(i);\n\t\t\t\n\t\t\tif (c && c >= 48 && c <= 57)\n\t\t\t\tdigits += v[i];\n\t\t}\n\t\t\n\t\treturn digits.length > 6 ? `${digits.slice(0, 3)}***${digits.slice(-2)}` : \"***\";\n\t},\n\t\n\tcard: (v: string): string => {\n\t\t\n\t\tlet digits = \"\";\n\t\t\n\t\tfor (let i = 0; i < v.length; i++) {\n\t\t\tconst c = v.codePointAt(i);\n\t\t\t\n\t\t\tif (c && c >= 48 && c <= 57)\n\t\t\t\tdigits += v[i];\n\t\t}\n\t\t\n\t\treturn digits.length >= 13 ? `****-****-****-${digits.slice(-4)}` : \"****\";\n\t},\n\t\n\tgeneric: (v: string): string => {\n\t\tconst { length } = v;\n\t\t\n\t\treturn length < 4 ? \"***\" : length < 9 ? `${v[0]}***` : `${v[0] + v[1]}***${v.slice(-2)}`;\n\t}\n};\n\nconst ensureCacheCapacity = (): void => {\n\t\n\tif (cache.size >= CACHE_SIZE) {\n\t\tconst keyToDelete = cache.keys().next().value;\n\t\t\n\t\tif (keyToDelete)\n\t\t\tcache.delete(keyToDelete);\n\t}\n\t\n};\n\nfunction checkField(key: string): FieldType {\n\tconst cached = cache.get(key);\n\t\n\tif (cached !== undefined)\n\t\treturn cached;\n\t\n\tconst normalized = key.toLowerCase().replaceAll(/[_-]/g, \"\");\n\t\n\tif (SKIP_SET.has(normalized)) {\n\t\tensureCacheCapacity();\n\t\t\n\t\tcache.set(key, FieldType.Skip);\n\t\t\n\t\treturn FieldType.Skip;\n\t}\n\t\n\tfor (const pattern of SENSITIVE_SET)\n\t\tif (normalized.includes(pattern)) {\n\t\t\t\n\t\t\tensureCacheCapacity();\n\t\t\t\n\t\t\tcache.set(key, FieldType.Sensitive);\n\t\t\t\n\t\t\treturn FieldType.Sensitive;\n\t\t}\n\t\n\tfor (const pattern of PII_SET)\n\t\tif (normalized.includes(pattern)) {\n\t\t\t\n\t\t\tensureCacheCapacity();\n\t\t\t\n\t\t\tcache.set(key, FieldType.Pii);\n\t\t\t\n\t\t\treturn FieldType.Pii;\n\t\t}\n\t\n\treturn FieldType.Unknown;\n}\n\nfunction getMasker(key: string): (v: string) => string {\n\tconst normalized = key.toLowerCase();\n\t\n\tif (normalized.includes(\"mail\"))\n\t\treturn mask.email;\n\t\n\tif (normalized.includes(\"phone\") || normalized.includes(\"tel\"))\n\t\treturn mask.phone;\n\t\n\tif (normalized.includes(\"card\") || normalized.includes(\"credit\"))\n\t\treturn mask.card;\n\t\n\treturn mask.generic;\n}\n\n\n/**\n * Recursively traverses an object or array and masks sensitive data.\n * The function is immutable and returns a new, masked object.\n * @param data The data to mask.\n * @param config Optional configuration to override default behavior.\n * @returns A deep copy of the data with sensitive fields masked.\n */\nexport function maskData<T>(data: T, config?: MaskConfig): T {\n\tconst maxDepth = config?.depth ?? 50;\n\t\n\tfunction process(obj: unknown, depth: number): unknown {\n\t\tif (depth > maxDepth || obj === null || obj === undefined || typeof obj !== \"object\")\n\t\t\treturn obj;\n\t\t\n\t\tif (obj instanceof Date)\n\t\t\treturn obj;\n\t\t\n\t\tif (Array.isArray(obj))\n\t\t\treturn obj.map(item => process(item, depth + 1));\n\t\t\n\t\tif (obj.constructor !== Object)\n\t\t\treturn obj;\n\t\t\n\t\tconst result: Record<string, unknown> = {};\n\t\t\n\t\tfor (const key in obj) {\n\t\t\tif (!Object.hasOwn(obj, key))\n\t\t\t\tcontinue;\n\t\t\t\n\t\t\tconst value = (obj as Record<string, unknown>)[key];\n\t\t\t\n\t\t\tif (typeof value === \"string\" && value.length > 0) {\n\t\t\t\tconst fieldType = checkField(key);\n\t\t\t\t\n\t\t\t\tswitch (fieldType) {\n\t\t\t\t\tcase FieldType.Skip:\n\t\t\t\t\tcase FieldType.Unknown:\n\t\t\t\t\t\tresult[key] = value;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t\n\t\t\t\t\tcase FieldType.Sensitive:\n\t\t\t\t\t\tresult[key] = \"[MASKED]\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t\n\t\t\t\t\tcase FieldType.Pii:\n\t\t\t\t\t\tresult[key] = getMasker(key)(value);\n\t\t\t\t}\n\t\t\t} else if (value !== null && value !== undefined && typeof value === \"object\")\n\t\t\t\tresult[key] = process(value, depth + 1);\n\t\t\telse\n\t\t\t\tresult[key] = value;\n\t\t}\n\t\t\n\t\treturn result;\n\t}\n\t\n\treturn process(data, 0) as T;\n}\n\n/**\n * A specific wrapper for masking MongoDB Change Stream documents.\n * It intelligently applies masking only to fields that can contain user data.\n * @param doc The Change Stream document.\n * @param config Optional masking configuration.\n * @returns A new Change Stream document with relevant fields masked.\n */\nexport function maskChangeStreamDocument<T extends Partial<ChangeStreamDocument>>(doc: T, config?: MaskConfig): T {\n\tswitch (doc.operationType) {\n\t\tcase \"delete\":\n\t\tcase \"drop\":\n\t\tcase \"dropDatabase\":\n\t\tcase \"invalidate\":\n\t\t\treturn doc;\n\t}\n\t\n\tconst result = { ...doc };\n\t\n\tif (\"fullDocument\" in result)\n\t\tresult.fullDocument = maskData(result.fullDocument, config);\n\t\n\tif (\"updateDescription\" in result && result.updateDescription?.updatedFields)\n\t\tresult.updateDescription = {\n\t\t\t...result.updateDescription,\n\t\t\tupdatedFields: maskData(result.updateDescription.updatedFields, config)\n\t\t};\n\t\n\treturn result;\n}\n\n/**\n * Provides utilities for monitoring and managing the masker's internal state.\n */\nexport const stats = {\n\tcacheSize: (): number => cache.size,\n\tclearCache: (): void => cache.clear(),\n\tpatterns: () => ({\n\t\tsensitive: Array.from(SENSITIVE_SET),\n\t\tpii: Array.from(PII_SET),\n\t\tskip: Array.from(SKIP_SET)\n\t})\n};\n", "import type { Collection, Document } from \"mongodb\";\nimport { captureStackTrace } from \"@nesvet/n\";\nimport { printChangeStreamChangeDetails, printChangeStreamError } from \"./utils\";\nimport type { CollectionOptions, DB, WatchedCollection } from \"./types\";\n\n\nexport class Collections extends Map<string, Collection> {\n\tconstructor(db: DB) {\n\t\tsuper();\n\t\t\n\t\tthis.db = db;\n\t\t\n\t}\n\t\n\tdb: DB;\n\t\n\t#awaiting = new Map<string, Promise<Collection>>();\n\t\n\t#schemaSet = new Map<string, string>();\n\t#indexesSet = new Map<string, string>();\n\t\n\t[key: string]: unknown;\n\t\n\tasync ensure<Doc extends Document>(name: string, options: CollectionOptions & { watch: false }): Promise<Collection<Doc>>;\n\tasync ensure<Doc extends Document>(name: string, options?: CollectionOptions): Promise<WatchedCollection<Doc>>;\n\tasync ensure(name: string, options: CollectionOptions = {}) {\n\t\t\n\t\tconst { db } = this;\n\t\t\n\t\tlet collection = this.get(name) ?? await this.#awaiting.get(name);\n\t\t\n\t\tif (!collection) {\n\t\t\tconst { promise, resolve } = Promise.withResolvers<Collection>();\n\t\t\tthis.#awaiting.set(name, promise);\n\t\t\t\n\t\t\ttry {\n\t\t\t\tif ((await db.listCollections({ name }, { nameOnly: true }).toArray()).length)\n\t\t\t\t\tcollection = db.collection(name);\n\t\t\t\telse {\n\t\t\t\t\tcollection = await db.createCollection(name, {\n\t\t\t\t\t\t...options.schema && { validator: { $jsonSchema: options.schema } },\n\t\t\t\t\t\t...options.blockCompressor && { storageEngine: { wiredTiger: { configString: `block_compressor=${options.blockCompressor}` } } }\n\t\t\t\t\t});\n\t\t\t\t\t\n\t\t\t\t\tdelete options.schema;\n\t\t\t\t\tdelete options.blockCompressor;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tif (options.watch !== false) {\n\t\t\t\t\tconst changeStream = collection.watch(undefined, { fullDocument: options.fullDocument === false ? undefined : \"updateLookup\" });\n\t\t\t\t\t\n\t\t\t\t\tif (process.env.NODE_ENV === \"development\" ? options.quiet !== true : !options.quiet)\n\t\t\t\t\t\tchangeStream.on(\"change\", printChangeStreamChangeDetails);\n\t\t\t\t\t\n\t\t\t\t\tchangeStream.on(\"error\", printChangeStreamError);\n\t\t\t\t\t\n\t\t\t\t\tcollection.changeStream = changeStream;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tthis.set(name, collection);\n\t\t\t\tthis[name] = collection;\n\t\t\t\t\n\t\t\t\tresolve(collection);\n\t\t\t} finally {\n\t\t\t\tthis.#awaiting.delete(name);\n\t\t\t}\n\t\t}\n\t\t\n\t\tif (options.schema)\n\t\t\tif (this.#schemaSet.has(name))\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`\uD83C\uDF3F\u26A0\uFE0F Attempt to set schema for the \\x1B[1m${name}\\x1B[22m collection at\\n` +\n\t\t\t\t\t`${captureStackTrace()}\\n` +\n\t\t\t\t\t\"\\n\" +\n\t\t\t\t\t\" Which has already been set at\\n\" +\n\t\t\t\t\t`${this.#schemaSet.get(name)}\\n` +\n\t\t\t\t\t\"\\n\" +\n\t\t\t\t\t\" Skipping\"\n\t\t\t\t);\n\t\t\telse {\n\t\t\t\tthis.#schemaSet.set(name, captureStackTrace());\n\t\t\t\t\n\t\t\t\tawait db.command({ collMod: name, validator: { $jsonSchema: options.schema } });\n\t\t\t}\n\t\t\n\t\tif (options.indexes)\n\t\t\tif (this.#indexesSet.has(name))\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`\uD83C\uDF3F\u26A0\uFE0F Attempt to set indexes for the \\x1B[1m${name}\\x1B[22m collection at\\n` +\n\t\t\t\t\t`${captureStackTrace()}\\n` +\n\t\t\t\t\t\"\\n\" +\n\t\t\t\t\t\" Which have already been set at\\n\" +\n\t\t\t\t\t`${this.#indexesSet.get(name)}\\n` +\n\t\t\t\t\t\"\\n\" +\n\t\t\t\t\t\" Skipping\"\n\t\t\t\t);\n\t\t\telse {\n\t\t\t\tthis.#indexesSet.set(name, captureStackTrace());\n\t\t\t\t\n\t\t\t\tawait collection.ensureIndexes(options.indexes);\n\t\t\t}\n\t\t\n\t\treturn collection;\n\t}\n\t\n}\n", "import { isDeepStrictEqual } from \"node:util\";\nimport { Collection, type ChangeStream } from \"mongodb\";\nimport { omit } from \"@nesvet/n\";\nimport type { ChangeStreamListener, CollectionIndexes, WatchedCollection } from \"../types\";\n\n\nconst ACTUAL_INDEX_VERSION = 2;\n\n\ndeclare module \"mongodb\" {\n\texport interface Collection<TSchema> { // eslint-disable-line no-shadow\n\t\t\n\t\t/** Ensures the presence of `indexes`. */\n\t\tensureIndexes(indexes: CollectionIndexes): Promise<void>;\n\t\t\n\t\t/** Change Stream, watching for new changes in this collection. */\n\t\tchangeStream?: ChangeStream<TSchema>;\n\t\t\n\t\t/** Adds the `listener` function to the end of the listeners array for the event `change`. */\n\t\tonChange?(listener: ChangeStreamListener<TSchema>): this;\n\t\t\n\t\t/** Adds the `listener` function to the *beginning* of the listeners array for the event `change`. */\n\t\tprependChange?(listener: ChangeStreamListener<TSchema>): this;\n\t\t\n\t\t/** Adds the **one-time** `listener` function to the end of the listeners array for the event `change`. */\n\t\tonceChange?(listener: ChangeStreamListener<TSchema>): this;\n\t\t\n\t\t/** Adds the **one-time** function to the *beginning* of the listeners array for the event `change`. */\n\t\tprependOnceChange?(listener: ChangeStreamListener<TSchema>): this;\n\t\t\n\t\t/** Removes the `listener` from the listener array for the event `change`. */\n\t\tremoveChangeListener?(listener: ChangeStreamListener<TSchema>): this;\n\t\t\n\t}\n}\n\n\nCollection.prototype.ensureIndexes = async function (indexes, dropOther = false) {\n\tif (dropOther) {\n\t\tconst existingIndexes = await this.indexes();\n\t\t\n\t\tfor (let i = 0; i < indexes.length; i++) {\n\t\t\tconst [ specification, options = {} ] = indexes[i];\n\t\t\t\n\t\t\tfor (let j = 0; j < existingIndexes.length; j++) {\n\t\t\t\tconst existingIndex = existingIndexes[j];\n\t\t\t\t\n\t\t\t\tif (\n\t\t\t\t\tisDeepStrictEqual(specification, existingIndex.key) &&\n\t\t\t\t\tisDeepStrictEqual(options, omit(existingIndex, [ \"v\", \"key\", \"name\" ]))\n\t\t\t\t) {\n\t\t\t\t\tindexes.splice(i--, 1);\n\t\t\t\t\texistingIndexes.splice(j, 1);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t\n\t\tawait Promise.all([\n\t\t\t...indexes.map(index => this.createIndex(...index)),\n\t\t\t...existingIndexes.filter(({ name, v }) => name && name !== \"_id_\" && (!v || v <= ACTUAL_INDEX_VERSION)).map(({ name }) => this.dropIndex(name!))\n\t\t]);\n\t} else\n\t\tawait Promise.all(indexes.map(index => this.createIndex(...index)));\n\t\n};\n\nCollection.prototype.onChange = function (this: WatchedCollection, listener) {\n\tthis.changeStream.on(\"change\", listener);\n\t\n\treturn this;\n};\n\nCollection.prototype.prependChange = function (this: WatchedCollection, listener) {\n\tthis.changeStream.prependListener(\"change\", listener);\n\t\n\treturn this;\n};\n\nCollection.prototype.onceChange = function (this: WatchedCollection, listener) {\n\tthis.changeStream.once(\"change\", listener);\n\t\n\treturn this;\n};\n\nCollection.prototype.prependOnceChange = function (this: WatchedCollection, listener) {\n\tthis.changeStream.prependOnceListener(\"change\", listener);\n\t\n\treturn this;\n};\n\nCollection.prototype.removeChangeListener = function (this: WatchedCollection, listener) {\n\tthis.changeStream.removeListener(\"change\", listener);\n\t\n\treturn this;\n};\n", "export type { Collections } from \"./Collections\";\nexport * from \"./connect\";\nexport * from \"./extensions\";\nexport * from \"./types\";\nexport { CollectionOptions } from \"./types\";\nexport * from \"./utils\";\nexport * from \"mongodb\";\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["MongoClient", "captureStackTrace", "
|
|
3
|
+
"sources": ["../src/connect.ts", "../src/Collections.ts", "../src/utils.ts", "../src/masker.ts", "../src/extensions/Collection.ts", "../src/index.ts"],
|
|
4
|
+
"sourcesContent": ["import { MongoClient } from \"mongodb\";\nimport { Collections } from \"./Collections\";\nimport type { Options } from \"./types\";\n\n\nexport async function connect({\n\turl,\n\tname,\n\tonConnect,\n\t...mongoClientOptions\n}: Options) {\n\t\n\tif (/localhost/.test(url))\n\t\turl = url.replace(/localhost/, \"127.0.0.1\");\n\t\n\tconst client = new MongoClient(url, {\n\t\tmaxPoolSize: 100,\n\t\t...mongoClientOptions\n\t});\n\t\n\ttry {\n\t\tawait client.connect();\n\t\tconsole.info(\"\uD83C\uDF3F MongoDB Client connected to\", url.replace(/(?<=\\/\\/)[^:]+?:[^@]+@/, \"\").replace(/[/?][^/]*$/, \"\"));\n\t} catch (error) {\n\t\tconsole.error(\"\uD83C\uDF3F\u2757\uFE0F MongoDB Client connection: \", error);\n\t}\n\t\n\tclient\n\t\t.on(\"close\", () => console.error(\"\uD83C\uDF3F\u2757\uFE0F MongoDB socket closed\"))\n\t\t.on(\"error\", error => console.error(\"\uD83C\uDF3F\u2757\uFE0F MongoDB:\", error))\n\t\t.on(\"parseError\", error => console.error(\"\uD83C\uDF3F\u2757\uFE0F MongoDB parse:\", error))\n\t\t.on(\"reconnect\", () => console.info(\"\uD83C\uDF3F MongoDB reconnected\"))\n\t\t.on(\"timeout\", () => console.error(\"\uD83C\uDF3F\u2757\uFE0F MongoDB timeout\"));\n\t\n\tconst db = client.db(name);\n\t\n\tconst collections = new Collections(db);\n\t\n\tawait onConnect?.(collections, db);\n\t\n\treturn {\n\t\tclient,\n\t\tdb,\n\t\tcollections\n\t};\n}\n", "import type { Collection, Document } from \"mongodb\";\nimport { captureStackTrace } from \"@nesvet/n\";\nimport { printChangeStreamChangeDetails, printChangeStreamError } from \"./utils\";\nimport type { CollectionOptions, DB, WatchedCollection } from \"./types\";\n\n\nexport class Collections extends Map<string, Collection> {\n\tconstructor(db: DB) {\n\t\tsuper();\n\t\t\n\t\tthis.db = db;\n\t\t\n\t}\n\t\n\tdb: DB;\n\t\n\t#awaiting = new Map<string, Promise<Collection>>();\n\t\n\t#schemaSet = new Map<string, string>();\n\t#indexesSet = new Map<string, string>();\n\t\n\t[key: string]: unknown;\n\t\n\tasync ensure<Doc extends Document>(name: string, options: CollectionOptions & { watch: false }): Promise<Collection<Doc>>;\n\tasync ensure<Doc extends Document>(name: string, options?: CollectionOptions): Promise<WatchedCollection<Doc>>;\n\tasync ensure(name: string, options: CollectionOptions = {}) {\n\t\t\n\t\tconst { db } = this;\n\t\t\n\t\tlet collection = this.get(name) ?? await this.#awaiting.get(name);\n\t\t\n\t\tif (!collection) {\n\t\t\tconst { promise, resolve } = Promise.withResolvers<Collection>();\n\t\t\tthis.#awaiting.set(name, promise);\n\t\t\t\n\t\t\ttry {\n\t\t\t\tif ((await db.listCollections({ name }, { nameOnly: true }).toArray()).length)\n\t\t\t\t\tcollection = db.collection(name);\n\t\t\t\telse {\n\t\t\t\t\tcollection = await db.createCollection(name, {\n\t\t\t\t\t\t...options.schema && { validator: { $jsonSchema: options.schema } },\n\t\t\t\t\t\t...options.blockCompressor && { storageEngine: { wiredTiger: { configString: `block_compressor=${options.blockCompressor}` } } }\n\t\t\t\t\t});\n\t\t\t\t\t\n\t\t\t\t\tdelete options.schema;\n\t\t\t\t\tdelete options.blockCompressor;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tif (options.watch !== false) {\n\t\t\t\t\tconst changeStream = collection.watch(undefined, { fullDocument: options.fullDocument === false ? undefined : \"updateLookup\" });\n\t\t\t\t\t\n\t\t\t\t\tif (process.env.NODE_ENV === \"development\" ? options.quiet !== true : !options.quiet)\n\t\t\t\t\t\tchangeStream.on(\"change\", printChangeStreamChangeDetails);\n\t\t\t\t\t\n\t\t\t\t\tchangeStream.on(\"error\", printChangeStreamError);\n\t\t\t\t\t\n\t\t\t\t\tcollection.changeStream = changeStream;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tthis.set(name, collection);\n\t\t\t\tthis[name] = collection;\n\t\t\t\t\n\t\t\t\tresolve(collection);\n\t\t\t} finally {\n\t\t\t\tthis.#awaiting.delete(name);\n\t\t\t}\n\t\t}\n\t\t\n\t\tif (options.schema)\n\t\t\tif (this.#schemaSet.has(name))\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`\uD83C\uDF3F\u26A0\uFE0F Attempt to set schema for the \\x1B[1m${name}\\x1B[22m collection at\\n` +\n\t\t\t\t\t`${captureStackTrace()}\\n` +\n\t\t\t\t\t\"\\n\" +\n\t\t\t\t\t\" Which has already been set at\\n\" +\n\t\t\t\t\t`${this.#schemaSet.get(name)}\\n` +\n\t\t\t\t\t\"\\n\" +\n\t\t\t\t\t\" Skipping\"\n\t\t\t\t);\n\t\t\telse {\n\t\t\t\tthis.#schemaSet.set(name, captureStackTrace());\n\t\t\t\t\n\t\t\t\tawait db.command({ collMod: name, validator: { $jsonSchema: options.schema } });\n\t\t\t}\n\t\t\n\t\tif (options.indexes)\n\t\t\tif (this.#indexesSet.has(name))\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`\uD83C\uDF3F\u26A0\uFE0F Attempt to set indexes for the \\x1B[1m${name}\\x1B[22m collection at\\n` +\n\t\t\t\t\t`${captureStackTrace()}\\n` +\n\t\t\t\t\t\"\\n\" +\n\t\t\t\t\t\" Which have already been set at\\n\" +\n\t\t\t\t\t`${this.#indexesSet.get(name)}\\n` +\n\t\t\t\t\t\"\\n\" +\n\t\t\t\t\t\" Skipping\"\n\t\t\t\t);\n\t\t\telse {\n\t\t\t\tthis.#indexesSet.set(name, captureStackTrace());\n\t\t\t\t\n\t\t\t\tawait collection.ensureIndexes(options.indexes);\n\t\t\t}\n\t\t\n\t\treturn collection;\n\t}\n\t\n}\n", "import { ObjectId, type ChangeStream, type ChangeStreamDocument } from \"mongodb\";\nimport { maskChangeStreamDocument } from \"./masker\";\nimport type { WatchedCollection } from \"./types\";\n\n\nexport function newObjectIdString() {\n\treturn (new ObjectId()).toString();\n}\n\n/** @this ChangeStream */\nexport function printChangeStreamChangeDetails(this: ChangeStream, next: ChangeStreamDocument) {\n\tnext = maskChangeStreamDocument(next);\n\t\n\tconst messages = [];\n\t\n\tswitch (next.operationType) {\n\t\tcase \"insert\":\n\t\tcase \"replace\":\n\t\t\tmessages.push(\"fullDocument:\", next.fullDocument);\n\t\t\tbreak;\n\t\t\n\t\tcase \"update\":\n\t\t\tmessages.push(\"_id:\", next.documentKey._id, \"\\n\", \"updateDescription:\", next.updateDescription);\n\t\t\tbreak;\n\t\t\n\t\tcase \"delete\":\n\t\t\tmessages.push(\"_id:\", next.documentKey._id);\n\t\t\tbreak;\n\t\t\n\t\tdefault:\n\t\t\tmessages.push(next);\n\t}\n\t\n\tconsole.info(\"\uD83C\uDF3F\uD83C\uDF8F\", `\\x1B[1m${(this.parent as WatchedCollection).collectionName}\\x1B[0m`, `\\x1B[3m${next.operationType}\\x1B[0m`, ...messages);\n\t\n}\n\n/** @this ChangeStream */\nexport function printChangeStreamError(this: ChangeStream, error: Error) {\n\tconsole.error(`\uD83C\uDF3F\u2757\uFE0F MongoDB ${(this.parent as WatchedCollection).collectionName} Change Stream:\\n`, error.stack);\n\t\n}\n", "import type { ChangeStreamDocument } from \"mongodb\";\n\n\ntype MaskConfig = {\n\treadonly sensitive?: ReadonlySet<string>;\n\treadonly pii?: ReadonlySet<string>;\n\treadonly skip?: ReadonlySet<string>;\n\treadonly depth?: number;\n};\n\nconst enum FieldType {\n\tUnknown = -1,\n\tSkip = 0,\n\tSensitive = 1,\n\tPii = 2\n}\n\n\nconst SENSITIVE = [ \"password\", \"secret\", \"token\", \"key\", \"auth\", \"session\", \"hash\", \"salt\", \"fingerprint\" ];\nconst PII = [ \"mail\", \"phone\", \"name\", \"address\", \"card\", \"ssn\", \"passport\" ];\n\nconst ENV_SENSITIVE = process.env.LOGS_MASK_SENSITIVE?.split(\",\").map(s => s.trim().toLowerCase()) ?? [];\nconst ENV_PII = process.env.LOGS_MASK_PII?.split(\",\").map(s => s.trim().toLowerCase()) ?? [];\nconst ENV_SKIP = process.env.LOGS_MASK_SKIP?.split(\",\").map(s => s.trim().toLowerCase()) ?? [ \"_id\", \"id\", \"timestamp\", \"created\", \"updated\" ];\n\nconst SENSITIVE_SET = Object.freeze(new Set([ ...SENSITIVE, ...ENV_SENSITIVE ]));\nconst PII_SET = Object.freeze(new Set([ ...PII, ...ENV_PII ]));\nconst SKIP_SET = Object.freeze(new Set(ENV_SKIP));\n\nconst cache = new Map<string, FieldType.Pii | FieldType.Sensitive | FieldType.Skip>();\nconst CACHE_SIZE = 2048;\n\nconst mask = {\n\t\n\temail: (v: string): string => {\n\t\tconst i = v.indexOf(\"@\");\n\t\t\n\t\treturn i > 1 ? `${v[0]}***@${v.slice(i + 1)}` : \"***@***\";\n\t},\n\t\n\tphone: (v: string): string => {\n\t\t\n\t\tlet digits = \"\";\n\t\t\n\t\tfor (let i = 0; i < v.length; i++) {\n\t\t\tconst c = v.codePointAt(i);\n\t\t\t\n\t\t\tif (c && c >= 48 && c <= 57)\n\t\t\t\tdigits += v[i];\n\t\t}\n\t\t\n\t\treturn digits.length > 6 ? `${digits.slice(0, 3)}***${digits.slice(-2)}` : \"***\";\n\t},\n\t\n\tcard: (v: string): string => {\n\t\t\n\t\tlet digits = \"\";\n\t\t\n\t\tfor (let i = 0; i < v.length; i++) {\n\t\t\tconst c = v.codePointAt(i);\n\t\t\t\n\t\t\tif (c && c >= 48 && c <= 57)\n\t\t\t\tdigits += v[i];\n\t\t}\n\t\t\n\t\treturn digits.length >= 13 ? `****-****-****-${digits.slice(-4)}` : \"****\";\n\t},\n\t\n\tgeneric: (v: string): string => {\n\t\tconst { length } = v;\n\t\t\n\t\treturn length < 4 ? \"***\" : length < 9 ? `${v[0]}***` : `${v[0] + v[1]}***${v.slice(-2)}`;\n\t}\n};\n\nconst ensureCacheCapacity = (): void => {\n\t\n\tif (cache.size >= CACHE_SIZE) {\n\t\tconst keyToDelete = cache.keys().next().value;\n\t\t\n\t\tif (keyToDelete)\n\t\t\tcache.delete(keyToDelete);\n\t}\n\t\n};\n\nfunction checkField(key: string): FieldType {\n\tconst cached = cache.get(key);\n\t\n\tif (cached !== undefined)\n\t\treturn cached;\n\t\n\tconst normalized = key.toLowerCase().replaceAll(/[_-]/g, \"\");\n\t\n\tif (SKIP_SET.has(normalized)) {\n\t\tensureCacheCapacity();\n\t\t\n\t\tcache.set(key, FieldType.Skip);\n\t\t\n\t\treturn FieldType.Skip;\n\t}\n\t\n\tfor (const pattern of SENSITIVE_SET)\n\t\tif (normalized.includes(pattern)) {\n\t\t\t\n\t\t\tensureCacheCapacity();\n\t\t\t\n\t\t\tcache.set(key, FieldType.Sensitive);\n\t\t\t\n\t\t\treturn FieldType.Sensitive;\n\t\t}\n\t\n\tfor (const pattern of PII_SET)\n\t\tif (normalized.includes(pattern)) {\n\t\t\t\n\t\t\tensureCacheCapacity();\n\t\t\t\n\t\t\tcache.set(key, FieldType.Pii);\n\t\t\t\n\t\t\treturn FieldType.Pii;\n\t\t}\n\t\n\treturn FieldType.Unknown;\n}\n\nfunction getMasker(key: string): (v: string) => string {\n\tconst normalized = key.toLowerCase();\n\t\n\tif (normalized.includes(\"mail\"))\n\t\treturn mask.email;\n\t\n\tif (normalized.includes(\"phone\") || normalized.includes(\"tel\"))\n\t\treturn mask.phone;\n\t\n\tif (normalized.includes(\"card\") || normalized.includes(\"credit\"))\n\t\treturn mask.card;\n\t\n\treturn mask.generic;\n}\n\n\n/**\n * Recursively traverses an object or array and masks sensitive data.\n * The function is immutable and returns a new, masked object.\n * @param data The data to mask.\n * @param config Optional configuration to override default behavior.\n * @returns A deep copy of the data with sensitive fields masked.\n */\nexport function maskData<T>(data: T, config?: MaskConfig): T {\n\tconst maxDepth = config?.depth ?? 50;\n\t\n\tfunction process(obj: unknown, depth: number): unknown {\n\t\tif (depth > maxDepth || obj === null || obj === undefined || typeof obj !== \"object\")\n\t\t\treturn obj;\n\t\t\n\t\tif (obj instanceof Date)\n\t\t\treturn obj;\n\t\t\n\t\tif (Array.isArray(obj))\n\t\t\treturn obj.map(item => process(item, depth + 1));\n\t\t\n\t\tif (obj.constructor !== Object)\n\t\t\treturn obj;\n\t\t\n\t\tconst result: Record<string, unknown> = {};\n\t\t\n\t\tfor (const key in obj) {\n\t\t\tif (!Object.hasOwn(obj, key))\n\t\t\t\tcontinue;\n\t\t\t\n\t\t\tconst value = (obj as Record<string, unknown>)[key];\n\t\t\t\n\t\t\tif (typeof value === \"string\" && value.length > 0) {\n\t\t\t\tconst fieldType = checkField(key);\n\t\t\t\t\n\t\t\t\tswitch (fieldType) {\n\t\t\t\t\tcase FieldType.Skip:\n\t\t\t\t\tcase FieldType.Unknown:\n\t\t\t\t\t\tresult[key] = value;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t\n\t\t\t\t\tcase FieldType.Sensitive:\n\t\t\t\t\t\tresult[key] = \"[MASKED]\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t\n\t\t\t\t\tcase FieldType.Pii:\n\t\t\t\t\t\tresult[key] = getMasker(key)(value);\n\t\t\t\t}\n\t\t\t} else if (value !== null && value !== undefined && typeof value === \"object\")\n\t\t\t\tresult[key] = process(value, depth + 1);\n\t\t\telse\n\t\t\t\tresult[key] = value;\n\t\t}\n\t\t\n\t\treturn result;\n\t}\n\t\n\treturn process(data, 0) as T;\n}\n\n/**\n * A specific wrapper for masking MongoDB Change Stream documents.\n * It intelligently applies masking only to fields that can contain user data.\n * @param doc The Change Stream document.\n * @param config Optional masking configuration.\n * @returns A new Change Stream document with relevant fields masked.\n */\nexport function maskChangeStreamDocument<T extends Partial<ChangeStreamDocument>>(doc: T, config?: MaskConfig): T {\n\tswitch (doc.operationType) {\n\t\tcase \"delete\":\n\t\tcase \"drop\":\n\t\tcase \"dropDatabase\":\n\t\tcase \"invalidate\":\n\t\t\treturn doc;\n\t}\n\t\n\tconst result = { ...doc };\n\t\n\tif (\"fullDocument\" in result)\n\t\tresult.fullDocument = maskData(result.fullDocument, config);\n\t\n\tif (\"updateDescription\" in result && result.updateDescription?.updatedFields)\n\t\tresult.updateDescription = {\n\t\t\t...result.updateDescription,\n\t\t\tupdatedFields: maskData(result.updateDescription.updatedFields, config)\n\t\t};\n\t\n\treturn result;\n}\n\n/**\n * Provides utilities for monitoring and managing the masker's internal state.\n */\nexport const stats = {\n\tcacheSize: (): number => cache.size,\n\tclearCache: (): void => cache.clear(),\n\tpatterns: () => ({\n\t\tsensitive: Array.from(SENSITIVE_SET),\n\t\tpii: Array.from(PII_SET),\n\t\tskip: Array.from(SKIP_SET)\n\t})\n};\n", "import { isDeepStrictEqual } from \"node:util\";\nimport { Collection, type ChangeStream } from \"mongodb\";\nimport { omit } from \"@nesvet/n\";\nimport type { ChangeStreamListener, CollectionIndexes, WatchedCollection } from \"../types\";\n\n\nconst ACTUAL_INDEX_VERSION = 2;\n\n\ndeclare module \"mongodb\" {\n\texport interface Collection<TSchema> { // eslint-disable-line no-shadow\n\t\t\n\t\t/** Ensures the presence of `indexes`. */\n\t\tensureIndexes(indexes: CollectionIndexes): Promise<void>;\n\t\t\n\t\t/** Change Stream, watching for new changes in this collection. */\n\t\tchangeStream?: ChangeStream<TSchema>;\n\t\t\n\t\t/** Adds the `listener` function to the end of the listeners array for the event `change`. */\n\t\tonChange?(listener: ChangeStreamListener<TSchema>): this;\n\t\t\n\t\t/** Adds the `listener` function to the *beginning* of the listeners array for the event `change`. */\n\t\tprependChange?(listener: ChangeStreamListener<TSchema>): this;\n\t\t\n\t\t/** Adds the **one-time** `listener` function to the end of the listeners array for the event `change`. */\n\t\tonceChange?(listener: ChangeStreamListener<TSchema>): this;\n\t\t\n\t\t/** Adds the **one-time** function to the *beginning* of the listeners array for the event `change`. */\n\t\tprependOnceChange?(listener: ChangeStreamListener<TSchema>): this;\n\t\t\n\t\t/** Removes the `listener` from the listener array for the event `change`. */\n\t\tremoveChangeListener?(listener: ChangeStreamListener<TSchema>): this;\n\t\t\n\t}\n}\n\n\nCollection.prototype.ensureIndexes = async function (indexes, dropOther = false) {\n\tif (dropOther) {\n\t\tconst existingIndexes = await this.indexes();\n\t\t\n\t\tfor (let i = 0; i < indexes.length; i++) {\n\t\t\tconst [ specification, options = {} ] = indexes[i];\n\t\t\t\n\t\t\tfor (let j = 0; j < existingIndexes.length; j++) {\n\t\t\t\tconst existingIndex = existingIndexes[j];\n\t\t\t\t\n\t\t\t\tif (\n\t\t\t\t\tisDeepStrictEqual(specification, existingIndex.key) &&\n\t\t\t\t\tisDeepStrictEqual(options, omit(existingIndex, [ \"v\", \"key\", \"name\" ]))\n\t\t\t\t) {\n\t\t\t\t\tindexes.splice(i--, 1);\n\t\t\t\t\texistingIndexes.splice(j, 1);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t\n\t\tawait Promise.all([\n\t\t\t...indexes.map(index => this.createIndex(...index)),\n\t\t\t...existingIndexes.filter(({ name, v }) => name && name !== \"_id_\" && (!v || v <= ACTUAL_INDEX_VERSION)).map(({ name }) => this.dropIndex(name!))\n\t\t]);\n\t} else\n\t\tawait Promise.all(indexes.map(index => this.createIndex(...index)));\n\t\n};\n\nCollection.prototype.onChange = function (this: WatchedCollection, listener) {\n\tthis.changeStream.on(\"change\", listener);\n\t\n\treturn this;\n};\n\nCollection.prototype.prependChange = function (this: WatchedCollection, listener) {\n\tthis.changeStream.prependListener(\"change\", listener);\n\t\n\treturn this;\n};\n\nCollection.prototype.onceChange = function (this: WatchedCollection, listener) {\n\tthis.changeStream.once(\"change\", listener);\n\t\n\treturn this;\n};\n\nCollection.prototype.prependOnceChange = function (this: WatchedCollection, listener) {\n\tthis.changeStream.prependOnceListener(\"change\", listener);\n\t\n\treturn this;\n};\n\nCollection.prototype.removeChangeListener = function (this: WatchedCollection, listener) {\n\tthis.changeStream.removeListener(\"change\", listener);\n\t\n\treturn this;\n};\n", "export type { Collections } from \"./Collections\";\nexport * from \"./connect\";\nexport * from \"./extensions\";\nexport * from \"./types\";\nexport { CollectionOptions } from \"./types\";\nexport * from \"./utils\";\nexport * from \"mongodb\";\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["MongoClient", "captureStackTrace", "ObjectId", "SENSITIVE", "PII", "ENV_SENSITIVE", "s", "ENV_PII", "ENV_SKIP", "SENSITIVE_SET", "PII_SET", "SKIP_SET", "cache", "CACHE_SIZE", "mask", "v", "i", "digits", "c", "length", "ensureCacheCapacity", "keyToDelete", "checkField", "key", "cached", "normalized", "pattern", "getMasker", "maskData", "data", "config", "maxDepth", "process", "obj", "depth", "item", "result", "value", "maskChangeStreamDocument", "doc", "newObjectIdString", "ObjectId", "printChangeStreamChangeDetails", "next", "maskChangeStreamDocument", "messages", "printChangeStreamError", "error", "Collections", "db", "#awaiting", "#schemaSet", "#indexesSet", "name", "options", "collection", "promise", "resolve", "changeStream", "printChangeStreamChangeDetails", "printChangeStreamError", "captureStackTrace", "connect", "url", "name", "onConnect", "mongoClientOptions", "client", "MongoClient", "error", "db", "collections", "Collections", "isDeepStrictEqual", "Collection", "omit", "ACTUAL_INDEX_VERSION", "indexes", "dropOther", "existingIndexes", "i", "specification", "options", "j", "existingIndex", "index", "name", "v", "listener"]
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,36 +1,51 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
2
|
+
"name": "insite-db",
|
|
3
|
+
"version": "2.4.0",
|
|
4
|
+
"description": "MongoDB adapter for inSite",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"insite",
|
|
7
|
+
"mongodb",
|
|
8
|
+
"database"
|
|
9
|
+
],
|
|
10
|
+
"homepage": "https://github.com/nesvet/insite#readme",
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/nesvet/insite/issues"
|
|
13
|
+
},
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "https://github.com/nesvet/insite.git",
|
|
17
|
+
"directory": "packages/db"
|
|
18
|
+
},
|
|
19
|
+
"funding": {
|
|
20
|
+
"type": "patreon",
|
|
21
|
+
"url": "https://www.patreon.com/nesvet"
|
|
22
|
+
},
|
|
23
|
+
"license": "MIT",
|
|
24
|
+
"author": "Eugene Nesvetaev <dev@nesvet.dev> (https://nesvet.dev/)",
|
|
25
|
+
"type": "module",
|
|
26
|
+
"main": "./dist/index.js",
|
|
27
|
+
"module": "./dist/index.js",
|
|
28
|
+
"files": [
|
|
29
|
+
"dist",
|
|
30
|
+
"README.md",
|
|
31
|
+
"LICENSE"
|
|
32
|
+
],
|
|
33
|
+
"scripts": {
|
|
34
|
+
"build": "bun .conveyer.js",
|
|
35
|
+
"postbuild": "tsc -p .",
|
|
36
|
+
"clean": "rm -rf dist",
|
|
37
|
+
"test": "echo \"Error: no test specified\" && exit 1",
|
|
38
|
+
"typecheck": "tsc --noEmit"
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"@nesvet/n": "^1.2.1",
|
|
42
|
+
"mongodb": "^7.1"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@types/json-schema": "^7.0.15"
|
|
46
|
+
},
|
|
47
|
+
"packageManager": "bun@1.3.9",
|
|
48
|
+
"engines": {
|
|
49
|
+
"node": ">=20.0.0"
|
|
50
|
+
}
|
|
36
51
|
}
|