@classytic/mongokit 3.20.0 → 3.21.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/dist/adapter/index.d.mts +17 -10
- package/dist/adapter/index.mjs +1 -1
- package/dist/{adapter-CW1EL0fF.mjs → adapter-rTPLUrAV.mjs} +2 -1
- package/dist/better-auth/index.mjs +1 -1
- package/dist/index.mjs +2 -1
- package/dist/memory-cache-DI1jb4dz.mjs +67 -0
- package/dist/{mongooseToJsonSchema-khdzVo8x.mjs → mongooseToJsonSchema-CVnrKFDq.mjs} +1 -67
- package/dist/utils/index.mjs +2 -1
- package/package.json +1 -1
package/dist/adapter/index.d.mts
CHANGED
|
@@ -22,8 +22,18 @@ interface MongooseAdapterOptions<TDoc = unknown> {
|
|
|
22
22
|
*/
|
|
23
23
|
repository: AdapterRepositoryInput<TDoc>;
|
|
24
24
|
/**
|
|
25
|
-
*
|
|
26
|
-
*
|
|
25
|
+
* Schema generator for OpenAPI / introspection docs.
|
|
26
|
+
*
|
|
27
|
+
* **Defaults to mongokit's own `buildCrudSchemasFromModel`** (3.21) — the
|
|
28
|
+
* canonical Mongoose→JSON-Schema generator ships in this package, so
|
|
29
|
+
* omitting the option now means "use it" rather than "no schemas". An
|
|
30
|
+
* audit of a 68-resource production host found 28 adapters that omitted
|
|
31
|
+
* it by accident and silently shipped `null` OpenAPI bodies + empty MCP
|
|
32
|
+
* tool schemas — correct-by-default closes that failure class.
|
|
33
|
+
*
|
|
34
|
+
* Pass `false` to opt OUT of schema generation entirely (`generateSchemas`
|
|
35
|
+
* returns `null`, hosts fall back to permissive bodies). Pass your own
|
|
36
|
+
* `SchemaGenerator` to replace the default.
|
|
27
37
|
*
|
|
28
38
|
* **Model type is intentionally `Model<unknown>`, not `Model<TDoc>`**:
|
|
29
39
|
* schema generators introspect `.schema.paths` — they read metadata,
|
|
@@ -35,17 +45,14 @@ interface MongooseAdapterOptions<TDoc = unknown> {
|
|
|
35
45
|
*
|
|
36
46
|
* @example
|
|
37
47
|
* ```ts
|
|
38
|
-
*
|
|
39
|
-
*
|
|
48
|
+
* // Default — full OpenAPI/MCP schemas, zero config:
|
|
49
|
+
* createMongooseAdapter({ model: ProductModel, repository: productRepository });
|
|
40
50
|
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
* repository: productRepository,
|
|
44
|
-
* schemaGenerator: buildCrudSchemasFromModel,
|
|
45
|
-
* });
|
|
51
|
+
* // Explicit opt-out (permissive bodies, no generated schemas):
|
|
52
|
+
* createMongooseAdapter({ model, repository, schemaGenerator: false });
|
|
46
53
|
* ```
|
|
47
54
|
*/
|
|
48
|
-
schemaGenerator?: SchemaGenerator<Model<unknown
|
|
55
|
+
schemaGenerator?: SchemaGenerator<Model<unknown>> | false;
|
|
49
56
|
}
|
|
50
57
|
/**
|
|
51
58
|
* Mongoose data adapter — implements the `DataAdapter<TDoc>` contract from
|
package/dist/adapter/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as createMongooseAdapter, r as isMongooseModel, t as MongooseAdapter } from "../adapter-
|
|
1
|
+
import { n as createMongooseAdapter, r as isMongooseModel, t as MongooseAdapter } from "../adapter-rTPLUrAV.mjs";
|
|
2
2
|
export { MongooseAdapter, createMongooseAdapter, isMongooseModel };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { n as warn } from "./logger-K7dPmu2U.mjs";
|
|
2
|
+
import { t as buildCrudSchemasFromModel } from "./mongooseToJsonSchema-CVnrKFDq.mjs";
|
|
2
3
|
import { mergeFieldRuleConstraints } from "@classytic/repo-core/schema";
|
|
3
4
|
import { asRepositoryLike, isRepository } from "@classytic/repo-core/adapter";
|
|
4
5
|
//#region src/adapter/types.ts
|
|
@@ -77,7 +78,7 @@ var MongooseAdapter = class {
|
|
|
77
78
|
if (!isRepository(options.repository)) throw new TypeError(formatInvalidRepositoryError(options.repository, options.model));
|
|
78
79
|
this.model = options.model;
|
|
79
80
|
this.repository = asRepositoryLike(options.repository);
|
|
80
|
-
this.schemaGenerator = options.schemaGenerator;
|
|
81
|
+
this.schemaGenerator = options.schemaGenerator === false ? void 0 : options.schemaGenerator ?? buildCrudSchemasFromModel;
|
|
81
82
|
this.name = `MongooseAdapter<${options.model.modelName}>`;
|
|
82
83
|
}
|
|
83
84
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as Repository } from "../Repository-dbbgOGjK.mjs";
|
|
2
|
-
import { n as createMongooseAdapter } from "../adapter-
|
|
2
|
+
import { n as createMongooseAdapter } from "../adapter-rTPLUrAV.mjs";
|
|
3
3
|
import { pluralizeBetterAuthCollection, resolveBetterAuthCollections } from "@classytic/repo-core/better-auth";
|
|
4
4
|
//#region src/better-auth/index.ts
|
|
5
5
|
/**
|
package/dist/index.mjs
CHANGED
|
@@ -12,7 +12,8 @@ import { a as uniqueField, c as subdocumentPlugin, d as leasePlugin, f as fieldF
|
|
|
12
12
|
import { i as getMongooseProjection, n as filterResponseData, r as getFieldsForUser, t as createFieldPreset } from "./field-selection-FSQFLpsU.mjs";
|
|
13
13
|
import { buildFieldTypeMap, coerceFieldValue, coerceHeuristic } from "./query/primitives/coercion.mjs";
|
|
14
14
|
import { extractSchemaIndexes } from "./query/primitives/indexes.mjs";
|
|
15
|
-
import {
|
|
15
|
+
import { t as createMemoryCache } from "./memory-cache-DI1jb4dz.mjs";
|
|
16
|
+
import { n as buildCrudSchemasFromMongooseSchema, t as buildCrudSchemasFromModel } from "./mongooseToJsonSchema-CVnrKFDq.mjs";
|
|
16
17
|
import { runChunkedPurge } from "@classytic/repo-core/repository";
|
|
17
18
|
import { isControlParam } from "@classytic/repo-core/query-parser";
|
|
18
19
|
//#region src/actions/cascade-references.ts
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
//#region src/utils/memory-cache.ts
|
|
2
|
+
/**
|
|
3
|
+
* Creates an in-memory cache adapter
|
|
4
|
+
*
|
|
5
|
+
* Features:
|
|
6
|
+
* - Automatic TTL expiration
|
|
7
|
+
* - Pattern-based clearing (simple glob with *)
|
|
8
|
+
* - Max entries limit to prevent memory leaks
|
|
9
|
+
*
|
|
10
|
+
* @param maxEntries - Maximum cache entries before oldest are evicted (default: 1000)
|
|
11
|
+
*/
|
|
12
|
+
function createMemoryCache(maxEntries = 1e3) {
|
|
13
|
+
const cache = /* @__PURE__ */ new Map();
|
|
14
|
+
let lastCleanup = Date.now();
|
|
15
|
+
const CLEANUP_INTERVAL_MS = 6e4;
|
|
16
|
+
function cleanupIfNeeded() {
|
|
17
|
+
const now = Date.now();
|
|
18
|
+
if (now - lastCleanup < CLEANUP_INTERVAL_MS) return;
|
|
19
|
+
lastCleanup = now;
|
|
20
|
+
for (const [key, entry] of cache) if (entry.expiresAt < now) cache.delete(key);
|
|
21
|
+
}
|
|
22
|
+
function evictOldest() {
|
|
23
|
+
while (cache.size >= maxEntries) {
|
|
24
|
+
const firstKey = cache.keys().next().value;
|
|
25
|
+
if (firstKey) cache.delete(firstKey);
|
|
26
|
+
else break;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return {
|
|
30
|
+
async get(key) {
|
|
31
|
+
const entry = cache.get(key);
|
|
32
|
+
if (!entry) return null;
|
|
33
|
+
if (entry.expiresAt < Date.now()) {
|
|
34
|
+
cache.delete(key);
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
cache.delete(key);
|
|
38
|
+
cache.set(key, entry);
|
|
39
|
+
return entry.value;
|
|
40
|
+
},
|
|
41
|
+
async set(key, value, ttl) {
|
|
42
|
+
cache.delete(key);
|
|
43
|
+
if (cache.size >= maxEntries) {
|
|
44
|
+
cleanupIfNeeded();
|
|
45
|
+
evictOldest();
|
|
46
|
+
}
|
|
47
|
+
cache.set(key, {
|
|
48
|
+
value,
|
|
49
|
+
expiresAt: Date.now() + ttl * 1e3
|
|
50
|
+
});
|
|
51
|
+
},
|
|
52
|
+
async delete(key) {
|
|
53
|
+
cache.delete(key);
|
|
54
|
+
},
|
|
55
|
+
async clear(pattern) {
|
|
56
|
+
if (!pattern) {
|
|
57
|
+
cache.clear();
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
const escaped = pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*").replace(/\?/g, ".");
|
|
61
|
+
const regex = new RegExp(`^${escaped}$`);
|
|
62
|
+
for (const key of cache.keys()) if (regex.test(key)) cache.delete(key);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
//#endregion
|
|
67
|
+
export { createMemoryCache as t };
|
|
@@ -1,72 +1,6 @@
|
|
|
1
1
|
import { r as isObjectIdInstance } from "./id-resolution-P2OzcyRl.mjs";
|
|
2
2
|
import mongoose from "mongoose";
|
|
3
3
|
import { applyFieldRules, collectFieldsToOmit } from "@classytic/repo-core/schema";
|
|
4
|
-
//#region src/utils/memory-cache.ts
|
|
5
|
-
/**
|
|
6
|
-
* Creates an in-memory cache adapter
|
|
7
|
-
*
|
|
8
|
-
* Features:
|
|
9
|
-
* - Automatic TTL expiration
|
|
10
|
-
* - Pattern-based clearing (simple glob with *)
|
|
11
|
-
* - Max entries limit to prevent memory leaks
|
|
12
|
-
*
|
|
13
|
-
* @param maxEntries - Maximum cache entries before oldest are evicted (default: 1000)
|
|
14
|
-
*/
|
|
15
|
-
function createMemoryCache(maxEntries = 1e3) {
|
|
16
|
-
const cache = /* @__PURE__ */ new Map();
|
|
17
|
-
let lastCleanup = Date.now();
|
|
18
|
-
const CLEANUP_INTERVAL_MS = 6e4;
|
|
19
|
-
function cleanupIfNeeded() {
|
|
20
|
-
const now = Date.now();
|
|
21
|
-
if (now - lastCleanup < CLEANUP_INTERVAL_MS) return;
|
|
22
|
-
lastCleanup = now;
|
|
23
|
-
for (const [key, entry] of cache) if (entry.expiresAt < now) cache.delete(key);
|
|
24
|
-
}
|
|
25
|
-
function evictOldest() {
|
|
26
|
-
while (cache.size >= maxEntries) {
|
|
27
|
-
const firstKey = cache.keys().next().value;
|
|
28
|
-
if (firstKey) cache.delete(firstKey);
|
|
29
|
-
else break;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
return {
|
|
33
|
-
async get(key) {
|
|
34
|
-
const entry = cache.get(key);
|
|
35
|
-
if (!entry) return null;
|
|
36
|
-
if (entry.expiresAt < Date.now()) {
|
|
37
|
-
cache.delete(key);
|
|
38
|
-
return null;
|
|
39
|
-
}
|
|
40
|
-
cache.delete(key);
|
|
41
|
-
cache.set(key, entry);
|
|
42
|
-
return entry.value;
|
|
43
|
-
},
|
|
44
|
-
async set(key, value, ttl) {
|
|
45
|
-
cache.delete(key);
|
|
46
|
-
if (cache.size >= maxEntries) {
|
|
47
|
-
cleanupIfNeeded();
|
|
48
|
-
evictOldest();
|
|
49
|
-
}
|
|
50
|
-
cache.set(key, {
|
|
51
|
-
value,
|
|
52
|
-
expiresAt: Date.now() + ttl * 1e3
|
|
53
|
-
});
|
|
54
|
-
},
|
|
55
|
-
async delete(key) {
|
|
56
|
-
cache.delete(key);
|
|
57
|
-
},
|
|
58
|
-
async clear(pattern) {
|
|
59
|
-
if (!pattern) {
|
|
60
|
-
cache.clear();
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
const escaped = pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*").replace(/\?/g, ".");
|
|
64
|
-
const regex = new RegExp(`^${escaped}$`);
|
|
65
|
-
for (const key of cache.keys()) if (regex.test(key)) cache.delete(key);
|
|
66
|
-
}
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
//#endregion
|
|
70
4
|
//#region src/utils/mongooseToJsonSchema.ts
|
|
71
5
|
/**
|
|
72
6
|
* Mongoose → JSON Schema converter.
|
|
@@ -624,4 +558,4 @@ function buildJsonSchemaForQuery(_tree, options) {
|
|
|
624
558
|
return basePagination;
|
|
625
559
|
}
|
|
626
560
|
//#endregion
|
|
627
|
-
export { buildCrudSchemasFromMongooseSchema as n,
|
|
561
|
+
export { buildCrudSchemasFromMongooseSchema as n, buildCrudSchemasFromModel as t };
|
package/dist/utils/index.mjs
CHANGED
|
@@ -2,5 +2,6 @@ import { i as isValidIdForType, r as isObjectIdInstance, t as getSchemaIdType }
|
|
|
2
2
|
import { t as configureLogger } from "../logger-K7dPmu2U.mjs";
|
|
3
3
|
import { t as createError } from "../error-BuByZwKU.mjs";
|
|
4
4
|
import { i as getMongooseProjection, n as filterResponseData, r as getFieldsForUser, t as createFieldPreset } from "../field-selection-FSQFLpsU.mjs";
|
|
5
|
-
import {
|
|
5
|
+
import { t as createMemoryCache } from "../memory-cache-DI1jb4dz.mjs";
|
|
6
|
+
import { n as buildCrudSchemasFromMongooseSchema, t as buildCrudSchemasFromModel } from "../mongooseToJsonSchema-CVnrKFDq.mjs";
|
|
6
7
|
export { buildCrudSchemasFromModel, buildCrudSchemasFromMongooseSchema, configureLogger, createError, createFieldPreset, createMemoryCache, filterResponseData, getFieldsForUser, getMongooseProjection, getSchemaIdType, isObjectIdInstance, isValidIdForType };
|
package/package.json
CHANGED