next-data-kit 1.0.1 → 3.0.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/README.md +224 -137
- package/dist/client/components/data-kit-table.d.ts.map +1 -1
- package/dist/client/components/data-kit-table.js +1 -1
- package/dist/client/components/data-kit-table.js.map +1 -1
- package/dist/client/hooks/useDataKit.d.ts.map +1 -1
- package/dist/client/hooks/useDataKit.js +21 -19
- package/dist/client/hooks/useDataKit.js.map +1 -1
- package/dist/index.cjs +77 -57
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -2
- package/dist/index.d.ts +5 -2
- package/dist/index.js +77 -57
- package/dist/index.js.map +1 -1
- package/dist/{next-data-kit-DmZ7pNHV.d.cts → next-data-kit-DBl9PPWh.d.cts} +2 -2
- package/dist/{next-data-kit-DmZ7pNHV.d.ts → next-data-kit-DBl9PPWh.d.ts} +2 -2
- package/dist/server.cjs +71 -39
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +19 -13
- package/dist/server.d.ts +19 -13
- package/dist/server.js +71 -39
- package/dist/server.js.map +1 -1
- package/dist/types/index.cjs.map +1 -1
- package/dist/types/index.d.cts +2 -2
- package/dist/types/next-data-kit.d.ts +2 -2
- package/dist/types/next-data-kit.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -151,7 +151,7 @@ type TSortEntry = {
|
|
|
151
151
|
*/
|
|
152
152
|
type TFilterConfig = {
|
|
153
153
|
[key: string]: {
|
|
154
|
-
type: '
|
|
154
|
+
type: 'REGEX' | 'EXACT';
|
|
155
155
|
field?: string;
|
|
156
156
|
};
|
|
157
157
|
};
|
|
@@ -178,7 +178,7 @@ type TDataKitInput<T = unknown> = {
|
|
|
178
178
|
limit?: number;
|
|
179
179
|
sort?: TSortOptions<T>;
|
|
180
180
|
sorts?: TSortEntry[];
|
|
181
|
-
query?: Record<string,
|
|
181
|
+
query?: Record<string, string | number | boolean>;
|
|
182
182
|
filter?: Record<string, unknown>;
|
|
183
183
|
filterConfig?: TFilterConfig;
|
|
184
184
|
filterCustom?: TFilterCustomConfig<T>;
|
|
@@ -151,7 +151,7 @@ type TSortEntry = {
|
|
|
151
151
|
*/
|
|
152
152
|
type TFilterConfig = {
|
|
153
153
|
[key: string]: {
|
|
154
|
-
type: '
|
|
154
|
+
type: 'REGEX' | 'EXACT';
|
|
155
155
|
field?: string;
|
|
156
156
|
};
|
|
157
157
|
};
|
|
@@ -178,7 +178,7 @@ type TDataKitInput<T = unknown> = {
|
|
|
178
178
|
limit?: number;
|
|
179
179
|
sort?: TSortOptions<T>;
|
|
180
180
|
sorts?: TSortEntry[];
|
|
181
|
-
query?: Record<string,
|
|
181
|
+
query?: Record<string, string | number | boolean>;
|
|
182
182
|
filter?: Record<string, unknown>;
|
|
183
183
|
filterConfig?: TFilterConfig;
|
|
184
184
|
filterCustom?: TFilterCustomConfig<T>;
|
package/dist/server.cjs
CHANGED
|
@@ -2,8 +2,30 @@
|
|
|
2
2
|
|
|
3
3
|
var zod = require('zod');
|
|
4
4
|
|
|
5
|
+
// src/server/utils.ts
|
|
6
|
+
var escapeRegex = (str) => {
|
|
7
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
8
|
+
};
|
|
9
|
+
var createSearchFilter = (fields) => {
|
|
10
|
+
return (value) => {
|
|
11
|
+
if (!value || typeof value !== "string") {
|
|
12
|
+
return {};
|
|
13
|
+
}
|
|
14
|
+
const escapedValue = escapeRegex(value);
|
|
15
|
+
return {
|
|
16
|
+
$or: fields.map((field) => ({
|
|
17
|
+
[field]: { $regex: escapedValue, $options: "i" }
|
|
18
|
+
}))
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
|
|
5
23
|
// src/server/adapters/mongoose.ts
|
|
6
24
|
var isProvided = (value) => value !== void 0 && value !== null && value !== "";
|
|
25
|
+
var isSafeKey = (key) => {
|
|
26
|
+
const unsafeKeys = ["__proto__", "constructor", "prototype"];
|
|
27
|
+
return !unsafeKeys.includes(key);
|
|
28
|
+
};
|
|
7
29
|
var mongooseAdapter = (model, options = {}) => {
|
|
8
30
|
const { filter: customFilterFn, filterCustom, defaultSort = { _id: -1 } } = options;
|
|
9
31
|
return async ({ filter, sorts, limit, skip, input }) => {
|
|
@@ -23,7 +45,7 @@ var mongooseAdapter = (model, options = {}) => {
|
|
|
23
45
|
let filterQuery = {};
|
|
24
46
|
if (input.query) {
|
|
25
47
|
Object.entries(input.query).forEach(([key, value]) => {
|
|
26
|
-
if (isProvided(value)) {
|
|
48
|
+
if (isProvided(value) && isSafeKey(key)) {
|
|
27
49
|
filterQuery[key] = value;
|
|
28
50
|
}
|
|
29
51
|
});
|
|
@@ -35,28 +57,28 @@ var mongooseAdapter = (model, options = {}) => {
|
|
|
35
57
|
if (filter && !customFilterFn) {
|
|
36
58
|
if (input.filterConfig) {
|
|
37
59
|
Object.entries(filter).forEach(([key, value]) => {
|
|
38
|
-
if (isProvided(value) && input.filterConfig?.[key]) {
|
|
60
|
+
if (isProvided(value) && isSafeKey(key) && input.filterConfig?.[key]) {
|
|
39
61
|
const config = input.filterConfig[key];
|
|
40
62
|
const fieldName = config?.field ?? key;
|
|
41
|
-
if (config?.type === "
|
|
63
|
+
if (config?.type === "REGEX") {
|
|
42
64
|
filterQuery[fieldName] = {
|
|
43
|
-
$regex: value,
|
|
65
|
+
$regex: escapeRegex(String(value)),
|
|
44
66
|
$options: "i"
|
|
45
67
|
};
|
|
46
|
-
} else if (config?.type === "
|
|
68
|
+
} else if (config?.type === "EXACT") {
|
|
47
69
|
filterQuery[fieldName] = value;
|
|
48
70
|
}
|
|
49
71
|
}
|
|
50
72
|
});
|
|
51
73
|
} else {
|
|
52
74
|
Object.entries(filter).forEach(([key, value]) => {
|
|
53
|
-
if (isProvided(value)) {
|
|
75
|
+
if (isProvided(value) && isSafeKey(key)) {
|
|
54
76
|
if (typeof value === "string") {
|
|
55
77
|
filterQuery[key] = {
|
|
56
|
-
$regex: value,
|
|
78
|
+
$regex: escapeRegex(value),
|
|
57
79
|
$options: "i"
|
|
58
80
|
};
|
|
59
|
-
} else {
|
|
81
|
+
} else if (typeof value === "number" || typeof value === "boolean") {
|
|
60
82
|
filterQuery[key] = value;
|
|
61
83
|
}
|
|
62
84
|
}
|
|
@@ -65,7 +87,7 @@ var mongooseAdapter = (model, options = {}) => {
|
|
|
65
87
|
}
|
|
66
88
|
if (filterCustom && filter) {
|
|
67
89
|
Object.entries(filter).forEach(([key, value]) => {
|
|
68
|
-
if (isProvided(value) && filterCustom[key]) {
|
|
90
|
+
if (isProvided(value) && isSafeKey(key) && filterCustom[key]) {
|
|
69
91
|
const customFilter = filterCustom[key](value);
|
|
70
92
|
filterQuery = { ...filterQuery, ...customFilter };
|
|
71
93
|
}
|
|
@@ -79,18 +101,45 @@ var mongooseAdapter = (model, options = {}) => {
|
|
|
79
101
|
|
|
80
102
|
// src/server/action.ts
|
|
81
103
|
var dataKitServerAction = async (props) => {
|
|
82
|
-
const { input, adapter, item,
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
104
|
+
const { input, adapter, item, maxLimit = 100, filterCustom, queryAllowed } = props;
|
|
105
|
+
const filterAllowed = filterCustom ? Object.keys(filterCustom) : void 0;
|
|
106
|
+
if (input.query) {
|
|
107
|
+
const safeQuery = {};
|
|
108
|
+
Object.keys(input.query).forEach((key) => {
|
|
109
|
+
if (queryAllowed && !queryAllowed.includes(key)) {
|
|
110
|
+
throw new Error(`[Security] Query field '${key}' is not allowed.`);
|
|
111
|
+
}
|
|
112
|
+
const val = input.query[key];
|
|
113
|
+
if (val !== null && typeof val === "object") {
|
|
114
|
+
throw new Error(`[Security] Query value for '${key}' must be a primitive.`);
|
|
115
|
+
}
|
|
116
|
+
if (val !== void 0) {
|
|
117
|
+
safeQuery[key] = val;
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
input.query = safeQuery;
|
|
121
|
+
}
|
|
122
|
+
if (input.filter) {
|
|
123
|
+
const safeFilter = {};
|
|
124
|
+
Object.keys(input.filter).forEach((key) => {
|
|
125
|
+
if (filterAllowed && !filterAllowed.includes(key)) {
|
|
126
|
+
throw new Error(`[Security] Filter field '${key}' is not allowed.`);
|
|
127
|
+
}
|
|
128
|
+
const val = input.filter[key];
|
|
129
|
+
if (val !== null && typeof val === "object") {
|
|
130
|
+
throw new Error(`[Security] Filter value for '${key}' must be a primitive.`);
|
|
131
|
+
}
|
|
132
|
+
safeFilter[key] = val;
|
|
133
|
+
});
|
|
134
|
+
input.filter = safeFilter;
|
|
135
|
+
}
|
|
136
|
+
const finalAdapter = typeof adapter === "function" ? adapter : mongooseAdapter(adapter, props);
|
|
88
137
|
switch (input.action ?? "FETCH") {
|
|
89
138
|
case "FETCH": {
|
|
90
139
|
if (!input.limit || !input.page) {
|
|
91
140
|
throw new Error("Invalid input: missing limit or page");
|
|
92
141
|
}
|
|
93
|
-
const limit = input.limit;
|
|
142
|
+
const limit = Math.min(input.limit, maxLimit);
|
|
94
143
|
const skip = limit * (input.page - 1);
|
|
95
144
|
const { items, total } = await finalAdapter({
|
|
96
145
|
filter: input.filter ?? {},
|
|
@@ -196,39 +245,22 @@ var adapterMemory = (dataset, options = {}) => {
|
|
|
196
245
|
return { items, total };
|
|
197
246
|
};
|
|
198
247
|
};
|
|
199
|
-
|
|
200
|
-
// src/server/utils.ts
|
|
201
|
-
var escapeRegex = (str) => {
|
|
202
|
-
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
203
|
-
};
|
|
204
|
-
var createSearchFilter = (fields) => {
|
|
205
|
-
return (value) => {
|
|
206
|
-
if (!value || typeof value !== "string") {
|
|
207
|
-
return {};
|
|
208
|
-
}
|
|
209
|
-
const escapedValue = escapeRegex(value);
|
|
210
|
-
return {
|
|
211
|
-
$or: fields.map((field) => ({
|
|
212
|
-
[field]: { $regex: escapedValue, $options: "i" }
|
|
213
|
-
}))
|
|
214
|
-
};
|
|
215
|
-
};
|
|
216
|
-
};
|
|
217
248
|
var dataKitSchemaZod = zod.z.object({
|
|
218
249
|
page: zod.z.number().int().positive().optional(),
|
|
219
|
-
limit: zod.z.number().int().positive().
|
|
220
|
-
query: zod.z.record(zod.z.string(), zod.z.
|
|
221
|
-
filter: zod.z.record(zod.z.string(), zod.z.
|
|
250
|
+
limit: zod.z.number().int().positive().optional(),
|
|
251
|
+
query: zod.z.record(zod.z.string(), zod.z.union([zod.z.string(), zod.z.number(), zod.z.boolean()])).optional(),
|
|
252
|
+
filter: zod.z.record(zod.z.string(), zod.z.union([zod.z.string(), zod.z.number(), zod.z.boolean(), zod.z.null()])).optional(),
|
|
222
253
|
filterConfig: zod.z.record(zod.z.string(), zod.z.object({
|
|
223
|
-
type: zod.z.enum(["
|
|
254
|
+
type: zod.z.enum(["REGEX", "EXACT"]),
|
|
224
255
|
field: zod.z.string().optional()
|
|
225
256
|
})).optional(),
|
|
226
257
|
sorts: zod.z.array(zod.z.object({
|
|
227
258
|
path: zod.z.string().max(100),
|
|
228
259
|
// Limit path length to prevent abuse
|
|
229
260
|
value: zod.z.literal(-1).or(zod.z.literal(1))
|
|
230
|
-
})).max(5).optional()
|
|
261
|
+
})).max(5).optional(),
|
|
231
262
|
// Limit to 5 sort fields
|
|
263
|
+
sort: zod.z.record(zod.z.string(), zod.z.literal(1).or(zod.z.literal(-1))).optional()
|
|
232
264
|
});
|
|
233
265
|
|
|
234
266
|
exports.adapterMemory = adapterMemory;
|
package/dist/server.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/server/adapters/mongoose.ts","../src/server/action.ts","../src/server/adapters/memory.ts","../src/server/utils.ts","../src/server/schema.ts"],"names":["isProvided","z"],"mappings":"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","file":"server.cjs","sourcesContent":["/**\n * next-data-kit - Mongoose Adapter\n *\n * Database adapter for Mongoose/MongoDB.\n */\n\nimport type {\n TMongoModel,\n TMongoFilterQuery,\n TSortOrder,\n TSortOptions,\n TFilterCustomConfigWithFilter,\n TDataKitAdapter,\n TExtractDocType,\n} from '../../types';\n\n// ** ============================================================================\n// ** Helpers\n// ** ============================================================================\n\nconst isProvided = (value: unknown): boolean =>\n value !== undefined && value !== null && value !== '';\n\n// ** ============================================================================\n// ** Adapter\n// ** ============================================================================\n\nexport const mongooseAdapter = <\n M extends TMongoModel<unknown, object>,\n DocType = TExtractDocType<M>\n>(\n model: M,\n options: Readonly<{\n filter?: (filterInput?: Record<string, unknown>) => TMongoFilterQuery<DocType>;\n filterCustom?: TFilterCustomConfigWithFilter<DocType, TMongoFilterQuery<DocType>>;\n defaultSort?: TSortOptions<DocType>;\n }> = {}\n): TDataKitAdapter<DocType> => {\n // ** Deconstruct options\n const { filter: customFilterFn, filterCustom, defaultSort = { _id: -1 } as TSortOptions<DocType> } = options;\n\n return async ({ filter, sorts, limit, skip, input }) => {\n // ** Normalize sort\n let sortOption: Record<string, TSortOrder>;\n\n if (input.sort && Object.keys(input.sort).length > 0) {\n sortOption = input.sort as Record<string, TSortOrder>;\n } else if (sorts && sorts.length > 0) {\n sortOption = sorts.reduce<Record<string, TSortOrder>>((acc, s) => {\n if (s?.path && (s.value === 1 || s.value === -1)) {\n acc[s.path] = s.value;\n }\n return acc;\n }, {});\n } else {\n sortOption = defaultSort as Record<string, TSortOrder>;\n }\n\n // ** Construct filter query\n let filterQuery: TMongoFilterQuery<DocType> = {};\n\n // ** Query params (exact match)\n if (input.query) {\n Object.entries(input.query).forEach(([key, value]) => {\n if (isProvided(value)) {\n (filterQuery as Record<string, unknown>)[key] = value;\n }\n });\n }\n\n // ** Custom filter function\n if (customFilterFn) {\n const customQuery = customFilterFn(filter);\n filterQuery = { ...filterQuery, ...customQuery };\n }\n\n // ** User defined filters\n if (filter && !customFilterFn) {\n if (input.filterConfig) {\n Object.entries(filter).forEach(([key, value]) => {\n if (isProvided(value) && input.filterConfig?.[key]) {\n const config = input.filterConfig[key];\n const fieldName = config?.field ?? key;\n\n if (config?.type === 'regex') {\n (filterQuery as Record<string, unknown>)[fieldName] = {\n $regex: value,\n $options: 'i',\n };\n } else if (config?.type === 'exact') {\n (filterQuery as Record<string, unknown>)[fieldName] = value;\n }\n }\n });\n } else {\n // ** Default automatic filtering\n Object.entries(filter).forEach(([key, value]) => {\n if (isProvided(value)) {\n if (typeof value === 'string') {\n (filterQuery as Record<string, unknown>)[key] = {\n $regex: value,\n $options: 'i',\n };\n } else {\n (filterQuery as Record<string, unknown>)[key] = value;\n }\n }\n });\n }\n }\n\n // ** Custom filter logic (filterCustom)\n if (filterCustom && filter) {\n Object.entries(filter).forEach(([key, value]) => {\n if (isProvided(value) && filterCustom[key]) {\n const customFilter = filterCustom[key]!(value);\n filterQuery = { ...filterQuery, ...customFilter };\n }\n });\n }\n\n // ** Execute queries\n const total = await model.countDocuments(filterQuery as TMongoFilterQuery<unknown>);\n const items = await model\n .find(filterQuery as TMongoFilterQuery<unknown>)\n .sort(sortOption)\n .limit(limit)\n .skip(skip) as unknown as DocType[];\n\n return { items, total };\n };\n};\n","/**\n * next-data-kit - Server Action\n *\n * The main server-side function for handling table data fetching\n * with pagination, filtering, and sorting.\n */\n\nimport { mongooseAdapter } from './adapters/mongoose';\nimport type {\n TDataKitInput,\n TDataKitResult,\n TDataKitAdapter,\n TMongoModel,\n TMongoFilterQuery,\n TFilterCustomConfigWithFilter,\n TSortOptions,\n} from '../types';\n\n// ** ============================================================================\n// ** Types\n// ** ============================================================================\n\nexport type TDataKitServerActionOptions<T, R> = {\n // ** The input from the client\n input: TDataKitInput<T>;\n // ** The database adapter or Mongoose model\n adapter: TDataKitAdapter<T> | TMongoModel<T>;\n // ** Function to transform each item before returning\n item: (item: T) => Promise<R> | R;\n // ** Custom filter function\n filter?: (filterInput?: Record<string, unknown>) => TMongoFilterQuery<T>;\n // ** Custom filter configuration\n filterCustom?: TFilterCustomConfigWithFilter<T, TMongoFilterQuery<T>>;\n // ** Default sort options\n defaultSort?: TSortOptions<T>;\n};\n\n// ** ============================================================================\n// ** Server Action\n// ** ============================================================================\n\nexport const dataKitServerAction = async <T, R>(\n props: Readonly<TDataKitServerActionOptions<T, R>>\n): Promise<TDataKitResult<R>> => {\n // ** Deconstruct Props\n const { input, adapter, item, filter, filterCustom, defaultSort } = props;\n\n // ** Determine adapter\n const finalAdapter: TDataKitAdapter<T> = typeof adapter === 'function'\n ? adapter\n : mongooseAdapter(adapter as TMongoModel<T>, {\n filter: filter as ((filterInput?: Record<string, unknown>) => TMongoFilterQuery<T>) | undefined,\n filterCustom: filterCustom as TFilterCustomConfigWithFilter<T, TMongoFilterQuery<T>> | undefined,\n defaultSort: defaultSort as TSortOptions<T> | undefined,\n });\n\n // ** Handle action\n switch (input.action ?? 'FETCH') {\n case 'FETCH': {\n if (!input.limit || !input.page) {\n throw new Error('Invalid input: missing limit or page');\n }\n\n const limit = input.limit;\n const skip = limit * (input.page - 1);\n\n // ** Fetch data using adapter\n const { items, total } = await finalAdapter({\n filter: input.filter ?? {},\n sorts: input.sorts ?? [],\n limit,\n page: input.page,\n skip,\n input,\n });\n\n // ** Process each item through the item mapper function\n const processedItems = await Promise.all(items.map((dataItem) => item(dataItem)));\n\n return {\n type: 'ITEMS',\n items: processedItems,\n documentTotal: total,\n };\n }\n\n default:\n throw new Error(`Unsupported action: ${(input as { action?: string }).action}`);\n }\n};\n","/**\n * next-data-kit - Memory Adapter\n *\n * In-memory adapter for demos, tests, and local playgrounds.\n * Implements the React Data Kit adapter contract over an array dataset.\n */\n\nimport type { TFilterConfig, TSortEntry, TDataKitAdapter } from '../../types';\n\nconst isProvided = (value: unknown): boolean =>\n value !== undefined && value !== null && value !== '';\n\nconst getValueByPath = (obj: unknown, path: string): unknown => {\n if (!path) return undefined;\n const parts = path.split('.');\n let current: unknown = obj;\n for (const part of parts) {\n if (current && typeof current === 'object' && part in (current as Record<string, unknown>)) {\n current = (current as Record<string, unknown>)[part];\n } else {\n return undefined;\n }\n }\n return current;\n};\n\nconst matchesExact = (rowValue: unknown, needle: unknown): boolean => {\n if (Array.isArray(needle)) return needle.includes(rowValue as never);\n return rowValue === needle;\n};\n\nconst matchesRegexLike = (rowValue: unknown, needle: unknown): boolean => {\n if (!isProvided(needle)) return true;\n if (rowValue === undefined || rowValue === null) return false;\n const hay = String(rowValue);\n\n if (needle instanceof RegExp) return needle.test(hay);\n const n = String(needle);\n return hay.toLowerCase().includes(n.toLowerCase());\n};\n\nconst compareValues = (a: unknown, b: unknown): number => {\n if (a === b) return 0;\n if (a === undefined || a === null) return -1;\n if (b === undefined || b === null) return 1;\n\n if (typeof a === 'number' && typeof b === 'number') return a - b;\n if (typeof a === 'bigint' && typeof b === 'bigint') return a < b ? -1 : 1;\n\n const as = String(a);\n const bs = String(b);\n return as.localeCompare(bs);\n};\n\nconst normalizeSorts = (sorts: TSortEntry[] | undefined): TSortEntry[] =>\n Array.isArray(sorts) ? sorts.filter((s) => !!s?.path && (s.value === 1 || s.value === -1)) : [];\n\n/**\n * Creates an adapter that pages/filters/sorts an in-memory dataset.\n */\nexport const adapterMemory = <T extends Record<string, unknown>>(\n dataset: ReadonlyArray<T>,\n options: Readonly<{\n /** default behavior for filter keys not present in filterConfig */\n defaultFilterType?: 'regex' | 'exact';\n }> = {}\n): TDataKitAdapter<T> => {\n const { defaultFilterType = 'exact' } = options;\n\n return async ({ filter, sorts, limit, skip, input }) => {\n const filterConfig: TFilterConfig | undefined = input.filterConfig;\n const query = input.query ?? {};\n\n // 1) Apply query (exact match)\n let rows = dataset.filter((row) => {\n for (const [key, value] of Object.entries(query)) {\n if (!isProvided(value)) continue;\n const rowValue = getValueByPath(row, key);\n if (!matchesExact(rowValue, value)) return false;\n }\n return true;\n });\n\n // 2) Apply filter (via filterConfig when present)\n const effectiveFilter = filter ?? {};\n rows = rows.filter((row) => {\n for (const [key, value] of Object.entries(effectiveFilter)) {\n if (!isProvided(value)) continue;\n\n const config = filterConfig?.[key];\n const field = config?.field ?? key;\n const rowValue = getValueByPath(row, field);\n\n const type = config?.type ?? defaultFilterType;\n if (type === 'regex') {\n if (!matchesRegexLike(rowValue, value)) return false;\n } else {\n if (!matchesExact(rowValue, value)) return false;\n }\n }\n return true;\n });\n\n // 3) Sort\n const normalizedSorts = normalizeSorts(sorts);\n if (normalizedSorts.length > 0) {\n rows = [...rows].sort((ra, rb) => {\n for (const s of normalizedSorts) {\n const av = getValueByPath(ra, s.path);\n const bv = getValueByPath(rb, s.path);\n const cmp = compareValues(av, bv);\n if (cmp !== 0) return s.value === 1 ? cmp : -cmp;\n }\n return 0;\n });\n }\n\n const total = rows.length;\n const items = rows.slice(skip, skip + limit);\n return { items, total };\n };\n};\n","/**\n * next-data-kit - Server Utilities\n */\n\nimport type { TMongoFilterQuery } from '../types';\n\n/**\n * Helper to escape regex special characters in a string\n */\nexport const escapeRegex = (str: string): string => {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n};\n\n/**\n * Create a search filter for multiple fields\n * \n * @example\n * ```typescript\n * filterCustom: {\n * search: createSearchFilter(['name', 'email', 'phone'])\n * }\n * ```\n */\nexport const createSearchFilter = <T>(\n fields: (keyof T | string)[]\n): (value: unknown) => TMongoFilterQuery<T> => {\n return (value: unknown): TMongoFilterQuery<T> => {\n if (!value || typeof value !== 'string') {\n return {} as TMongoFilterQuery<T>;\n }\n\n const escapedValue = escapeRegex(value);\n return {\n $or: fields.map((field) => ({\n [field]: { $regex: escapedValue, $options: 'i' },\n })),\n } as TMongoFilterQuery<T>;\n };\n};\n","import { z } from 'zod';\n\nexport const dataKitSchemaZod = z.object({\n page: z.number().int().positive().optional(),\n limit: z.number().int().positive().max(100, \"Maximum limit is 100\").optional(),\n query: z.record(z.string(), z.unknown()).optional(),\n filter: z.record(z.string(), z.unknown()).optional(),\n filterConfig: z.record(z.string(), z.object({\n type: z.enum([\"regex\", \"exact\"]),\n field: z.string().optional()\n })).optional(),\n sorts: z.array(z.object({\n path: z.string().max(100), // Limit path length to prevent abuse\n value: z.literal(-1).or(z.literal(1))\n })).max(5).optional(), // Limit to 5 sort fields\n});\n\nexport type TDataKitSchemaZod = z.infer<typeof dataKitSchemaZod>;\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/server/utils.ts","../src/server/adapters/mongoose.ts","../src/server/action.ts","../src/server/adapters/memory.ts","../src/server/schema.ts"],"names":["isProvided","z"],"mappings":"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","file":"server.cjs","sourcesContent":["/**\n * next-data-kit - Server Utilities\n */\n\nimport type { TMongoFilterQuery } from '../types';\n\n/**\n * Helper to escape regex special characters in a string\n */\nexport const escapeRegex = (str: string): string => {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n};\n\n/**\n * Create a search filter for multiple fields\n * \n * @example\n * ```typescript\n * filterCustom: {\n * search: createSearchFilter(['name', 'email', 'phone'])\n * }\n * ```\n */\nexport const createSearchFilter = <T>(\n fields: (keyof T | string)[]\n): (value: unknown) => TMongoFilterQuery<T> => {\n return (value: unknown): TMongoFilterQuery<T> => {\n if (!value || typeof value !== 'string') {\n return {} as TMongoFilterQuery<T>;\n }\n\n const escapedValue = escapeRegex(value);\n return {\n $or: fields.map((field) => ({\n [field]: { $regex: escapedValue, $options: 'i' },\n })),\n } as TMongoFilterQuery<T>;\n };\n};\n","/**\n * next-data-kit - Mongoose Adapter\n *\n * Database adapter for Mongoose/MongoDB.\n */\n\nimport type {\n TMongoModel,\n TMongoFilterQuery,\n TSortOrder,\n TSortOptions,\n TFilterCustomConfigWithFilter,\n TDataKitAdapter,\n TExtractDocType,\n} from '../../types';\n\n// ** ============================================================================\n// ** Helpers\n// ** ============================================================================\n\nimport { escapeRegex } from '../utils';\n\n// ** ============================================================================\n// ** Helpers\n// ** ============================================================================\n\nconst isProvided = (value: unknown): boolean =>\n value !== undefined && value !== null && value !== '';\n\nconst isSafeKey = (key: string): boolean => {\n const unsafeKeys = ['__proto__', 'constructor', 'prototype'];\n return !unsafeKeys.includes(key);\n};\n\n// ** ============================================================================\n// ** Adapter\n// ** ============================================================================\n\nexport const mongooseAdapter = <\n M extends TMongoModel<unknown, object>,\n DocType = TExtractDocType<M>\n>(\n model: M,\n options: Readonly<{\n filter?: (filterInput?: Record<string, unknown>) => TMongoFilterQuery<DocType>;\n filterCustom?: TFilterCustomConfigWithFilter<DocType, TMongoFilterQuery<DocType>>;\n defaultSort?: TSortOptions<DocType>;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n [key: string]: any;\n }> = {}\n): TDataKitAdapter<DocType> => {\n // ** Deconstruct options\n const { filter: customFilterFn, filterCustom, defaultSort = { _id: -1 } as TSortOptions<DocType> } = options;\n\n return async ({ filter, sorts, limit, skip, input }) => {\n // ** Normalize sort\n let sortOption: Record<string, TSortOrder>;\n\n if (input.sort && Object.keys(input.sort).length > 0) {\n sortOption = input.sort as Record<string, TSortOrder>;\n } else if (sorts && sorts.length > 0) {\n sortOption = sorts.reduce<Record<string, TSortOrder>>((acc, s) => {\n if (s?.path && (s.value === 1 || s.value === -1)) {\n acc[s.path] = s.value;\n }\n return acc;\n }, {});\n } else {\n sortOption = defaultSort as Record<string, TSortOrder>;\n }\n\n // ** Construct filter query\n let filterQuery: TMongoFilterQuery<DocType> = {};\n\n // ** Query params (exact match)\n if (input.query) {\n Object.entries(input.query).forEach(([key, value]) => {\n if (isProvided(value) && isSafeKey(key)) {\n (filterQuery as Record<string, unknown>)[key] = value;\n }\n });\n }\n\n // ** Custom filter function\n if (customFilterFn) {\n const customQuery = customFilterFn(filter);\n filterQuery = { ...filterQuery, ...customQuery };\n }\n\n // ** User defined filters\n if (filter && !customFilterFn) {\n if (input.filterConfig) {\n Object.entries(filter).forEach(([key, value]) => {\n if (isProvided(value) && isSafeKey(key) && input.filterConfig?.[key]) {\n const config = input.filterConfig[key];\n const fieldName = config?.field ?? key;\n\n if (config?.type === 'REGEX') {\n (filterQuery as Record<string, unknown>)[fieldName] = {\n $regex: escapeRegex(String(value)),\n $options: 'i',\n };\n } else if (config?.type === 'EXACT') {\n (filterQuery as Record<string, unknown>)[fieldName] = value;\n }\n }\n });\n } else {\n // ** Default automatic filtering\n Object.entries(filter).forEach(([key, value]) => {\n if (isProvided(value) && isSafeKey(key)) {\n if (typeof value === 'string') {\n (filterQuery as Record<string, unknown>)[key] = {\n $regex: escapeRegex(value),\n $options: 'i',\n };\n } else if (typeof value === 'number' || typeof value === 'boolean') {\n (filterQuery as Record<string, unknown>)[key] = value;\n }\n }\n });\n }\n }\n\n // ** Custom filter logic (filterCustom)\n if (filterCustom && filter) {\n Object.entries(filter).forEach(([key, value]) => {\n if (isProvided(value) && isSafeKey(key) && filterCustom[key]) {\n const customFilter = filterCustom[key]!(value);\n filterQuery = { ...filterQuery, ...customFilter };\n }\n });\n }\n\n // ** Execute queries\n const total = await model.countDocuments(filterQuery as TMongoFilterQuery<unknown>);\n const items = await model\n .find(filterQuery as TMongoFilterQuery<unknown>)\n .sort(sortOption)\n .limit(limit)\n .skip(skip) as unknown as DocType[];\n\n return { items, total };\n };\n};\n","/**\n * next-data-kit - Server Action\n *\n * The main server-side function for handling table data fetching\n * with pagination, filtering, and sorting.\n */\n\nimport { mongooseAdapter } from './adapters/mongoose';\nimport type { TDataKitInput, TDataKitResult, TDataKitAdapter, TMongoModel, TMongoFilterQuery, TFilterCustomConfigWithFilter, TSortOptions } from '../types';\n\n// ** ============================================================================\n// ** Types\n// ** ============================================================================\n\nexport type TDataKitServerActionOptions<T, R> = {\n\t// ** The input from the client\n\tinput: TDataKitInput<T>;\n\t// ** The database adapter or Mongoose model\n\tadapter: TDataKitAdapter<T> | TMongoModel<T>;\n\t// ** Function to transform each item before returning\n\titem: (item: T) => Promise<R> | R;\n\t// ** Custom filter function\n\tfilter?: (filterInput?: Record<string, unknown>) => TMongoFilterQuery<T>;\n\t// ** Custom filter configuration (defines allowed filter keys)\n\tfilterCustom?: TFilterCustomConfigWithFilter<T, TMongoFilterQuery<T>>;\n\t// ** Default sort options\n\tdefaultSort?: TSortOptions<T>;\n\t// ** Maximum limit per page (default: 100)\n\tmaxLimit?: number;\n\t// ** Whitelist of allowed query fields\n\tqueryAllowed?: string[];\n};\n\n// ** ============================================================================\n// ** Server Action\n// ** ============================================================================\n\nexport const dataKitServerAction = async <T, R>(props: Readonly<TDataKitServerActionOptions<T, R>>): Promise<TDataKitResult<R>> => {\n\t// ** Deconstruct Props\n\tconst { input, adapter, item, maxLimit = 100, filterCustom, queryAllowed } = props;\n\n\t// ** Auto-generate filterAllowed from filterCustom keys (server defines what's allowed)\n\tconst filterAllowed = filterCustom ? Object.keys(filterCustom) : undefined;\n\n\t// ** Whitelist filtering for security (if configured)\n\t// ** We do this here instead of in the adapter to keep the adapter simple and \"dumb\"\n\n\t// ** Check Query\n\tif (input.query) {\n\t\tconst safeQuery: Record<string, string | number | boolean> = {};\n\t\tObject.keys(input.query).forEach(key => {\n\t\t\tif (queryAllowed && !queryAllowed.includes(key)) {\n\t\t\t\tthrow new Error(`[Security] Query field '${key}' is not allowed.`);\n\t\t\t}\n\t\t\t// ** Enforce primitive values only (Anti-NoSQL Injection)\n\t\t\tconst val = input.query![key];\n\t\t\tif (val !== null && typeof val === 'object') {\n\t\t\t\tthrow new Error(`[Security] Query value for '${key}' must be a primitive.`);\n\t\t\t}\n\t\t\tif (val !== undefined) {\n\t\t\t\tsafeQuery[key] = val;\n\t\t\t}\n\t\t});\n\t\tinput.query = safeQuery;\n\t}\n\n\t// ** Check Filter\n\tif (input.filter) {\n\t\tconst safeFilter: Record<string, unknown> = {};\n\t\tObject.keys(input.filter).forEach(key => {\n\t\t\tif (filterAllowed && !filterAllowed.includes(key)) {\n\t\t\t\tthrow new Error(`[Security] Filter field '${key}' is not allowed.`);\n\t\t\t}\n\t\t\t// ** Enforce primitive values only (Anti-NoSQL Injection)\n\t\t\tconst val = input.filter![key];\n\t\t\tif (val !== null && typeof val === 'object') {\n\t\t\t\tthrow new Error(`[Security] Filter value for '${key}' must be a primitive.`);\n\t\t\t}\n\t\t\tsafeFilter[key] = val;\n\t\t});\n\t\tinput.filter = safeFilter;\n\t}\n\n\t// ** Determine adapter\n\tconst finalAdapter: TDataKitAdapter<T> = typeof adapter === 'function' ? adapter : mongooseAdapter(adapter as TMongoModel<T>, props);\n\n\t// ** Handle action\n\tswitch (input.action ?? 'FETCH') {\n\t\tcase 'FETCH': {\n\t\t\tif (!input.limit || !input.page) {\n\t\t\t\tthrow new Error('Invalid input: missing limit or page');\n\t\t\t}\n\n\t\t\tconst limit = Math.min(input.limit, maxLimit);\n\t\t\tconst skip = limit * (input.page - 1);\n\n\t\t\t// ** Fetch data using adapter\n\t\t\tconst { items, total } = await finalAdapter({\n\t\t\t\tfilter: input.filter ?? {},\n\t\t\t\tsorts: input.sorts ?? [],\n\t\t\t\tlimit,\n\t\t\t\tpage: input.page,\n\t\t\t\tskip,\n\t\t\t\tinput,\n\t\t\t});\n\n\t\t\t// ** Process each item through the item mapper function\n\t\t\tconst processedItems = await Promise.all(items.map(dataItem => item(dataItem)));\n\n\t\t\treturn {\n\t\t\t\ttype: 'ITEMS',\n\t\t\t\titems: processedItems,\n\t\t\t\tdocumentTotal: total,\n\t\t\t};\n\t\t}\n\n\t\tdefault:\n\t\t\tthrow new Error(`Unsupported action: ${(input as { action?: string }).action}`);\n\t}\n};\n","/**\n * next-data-kit - Memory Adapter\n *\n * In-memory adapter for demos, tests, and local playgrounds.\n * Implements the React Data Kit adapter contract over an array dataset.\n */\n\nimport type { TFilterConfig, TSortEntry, TDataKitAdapter } from '../../types';\n\nconst isProvided = (value: unknown): boolean =>\n value !== undefined && value !== null && value !== '';\n\nconst getValueByPath = (obj: unknown, path: string): unknown => {\n if (!path) return undefined;\n const parts = path.split('.');\n let current: unknown = obj;\n for (const part of parts) {\n if (current && typeof current === 'object' && part in (current as Record<string, unknown>)) {\n current = (current as Record<string, unknown>)[part];\n } else {\n return undefined;\n }\n }\n return current;\n};\n\nconst matchesExact = (rowValue: unknown, needle: unknown): boolean => {\n if (Array.isArray(needle)) return needle.includes(rowValue as never);\n return rowValue === needle;\n};\n\nconst matchesRegexLike = (rowValue: unknown, needle: unknown): boolean => {\n if (!isProvided(needle)) return true;\n if (rowValue === undefined || rowValue === null) return false;\n const hay = String(rowValue);\n\n if (needle instanceof RegExp) return needle.test(hay);\n const n = String(needle);\n return hay.toLowerCase().includes(n.toLowerCase());\n};\n\nconst compareValues = (a: unknown, b: unknown): number => {\n if (a === b) return 0;\n if (a === undefined || a === null) return -1;\n if (b === undefined || b === null) return 1;\n\n if (typeof a === 'number' && typeof b === 'number') return a - b;\n if (typeof a === 'bigint' && typeof b === 'bigint') return a < b ? -1 : 1;\n\n const as = String(a);\n const bs = String(b);\n return as.localeCompare(bs);\n};\n\nconst normalizeSorts = (sorts: TSortEntry[] | undefined): TSortEntry[] =>\n Array.isArray(sorts) ? sorts.filter((s) => !!s?.path && (s.value === 1 || s.value === -1)) : [];\n\n/**\n * Creates an adapter that pages/filters/sorts an in-memory dataset.\n */\nexport const adapterMemory = <T extends Record<string, unknown>>(\n dataset: ReadonlyArray<T>,\n options: Readonly<{\n /** default behavior for filter keys not present in filterConfig */\n defaultFilterType?: 'regex' | 'exact';\n }> = {}\n): TDataKitAdapter<T> => {\n const { defaultFilterType = 'exact' } = options;\n\n return async ({ filter, sorts, limit, skip, input }) => {\n const filterConfig: TFilterConfig | undefined = input.filterConfig;\n const query = input.query ?? {};\n\n // 1) Apply query (exact match)\n let rows = dataset.filter((row) => {\n for (const [key, value] of Object.entries(query)) {\n if (!isProvided(value)) continue;\n const rowValue = getValueByPath(row, key);\n if (!matchesExact(rowValue, value)) return false;\n }\n return true;\n });\n\n // 2) Apply filter (via filterConfig when present)\n const effectiveFilter = filter ?? {};\n rows = rows.filter((row) => {\n for (const [key, value] of Object.entries(effectiveFilter)) {\n if (!isProvided(value)) continue;\n\n const config = filterConfig?.[key];\n const field = config?.field ?? key;\n const rowValue = getValueByPath(row, field);\n\n const type = config?.type ?? defaultFilterType;\n if (type === 'regex') {\n if (!matchesRegexLike(rowValue, value)) return false;\n } else {\n if (!matchesExact(rowValue, value)) return false;\n }\n }\n return true;\n });\n\n // 3) Sort\n const normalizedSorts = normalizeSorts(sorts);\n if (normalizedSorts.length > 0) {\n rows = [...rows].sort((ra, rb) => {\n for (const s of normalizedSorts) {\n const av = getValueByPath(ra, s.path);\n const bv = getValueByPath(rb, s.path);\n const cmp = compareValues(av, bv);\n if (cmp !== 0) return s.value === 1 ? cmp : -cmp;\n }\n return 0;\n });\n }\n\n const total = rows.length;\n const items = rows.slice(skip, skip + limit);\n return { items, total };\n };\n};\n","import { z } from 'zod';\n\nexport const dataKitSchemaZod = z.object({\n page: z.number().int().positive().optional(),\n limit: z.number().int().positive().optional(),\n query: z.record(z.string(), z.union([z.string(), z.number(), z.boolean()])).optional(),\n filter: z.record(z.string(), z.union([z.string(), z.number(), z.boolean(), z.null()])).optional(),\n filterConfig: z.record(z.string(), z.object({\n type: z.enum([\"REGEX\", \"EXACT\"]),\n field: z.string().optional()\n })).optional(),\n sorts: z.array(z.object({\n path: z.string().max(100), // Limit path length to prevent abuse\n value: z.literal(-1).or(z.literal(1))\n })).max(5).optional(), // Limit to 5 sort fields\n sort: z.record(z.string(), z.literal(1).or(z.literal(-1))).optional(),\n});\n\nexport type TDataKitSchemaZod = z.infer<typeof dataKitSchemaZod>;\n"]}
|
package/dist/server.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { T as TDataKitInput, a as TDataKitAdapter, b as TMongoModel, c as TMongoFilterQuery, d as TFilterCustomConfigWithFilter, e as TSortOptions, f as TDataKitResult, g as TExtractDocType } from './next-data-kit-
|
|
2
|
-
export { l as TFilterConfig, k as TFilterCustomConfig, i as THydratedDocument, h as TModel, p as TMongoDocument, m as TMongoFilterOperators, q as TMongoHydratedDocument, n as TMongoRootFilterOperators, o as TObjectId, j as TSortOrder } from './next-data-kit-
|
|
1
|
+
import { T as TDataKitInput, a as TDataKitAdapter, b as TMongoModel, c as TMongoFilterQuery, d as TFilterCustomConfigWithFilter, e as TSortOptions, f as TDataKitResult, g as TExtractDocType } from './next-data-kit-DBl9PPWh.cjs';
|
|
2
|
+
export { l as TFilterConfig, k as TFilterCustomConfig, i as THydratedDocument, h as TModel, p as TMongoDocument, m as TMongoFilterOperators, q as TMongoHydratedDocument, n as TMongoRootFilterOperators, o as TObjectId, j as TSortOrder } from './next-data-kit-DBl9PPWh.cjs';
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -16,6 +16,8 @@ type TDataKitServerActionOptions<T, R> = {
|
|
|
16
16
|
filter?: (filterInput?: Record<string, unknown>) => TMongoFilterQuery<T>;
|
|
17
17
|
filterCustom?: TFilterCustomConfigWithFilter<T, TMongoFilterQuery<T>>;
|
|
18
18
|
defaultSort?: TSortOptions<T>;
|
|
19
|
+
maxLimit?: number;
|
|
20
|
+
queryAllowed?: string[];
|
|
19
21
|
};
|
|
20
22
|
declare const dataKitServerAction: <T, R>(props: Readonly<TDataKitServerActionOptions<T, R>>) => Promise<TDataKitResult<R>>;
|
|
21
23
|
|
|
@@ -29,6 +31,7 @@ declare const mongooseAdapter: <M extends TMongoModel<unknown, object>, DocType
|
|
|
29
31
|
filter?: (filterInput?: Record<string, unknown>) => TMongoFilterQuery<DocType>;
|
|
30
32
|
filterCustom?: TFilterCustomConfigWithFilter<DocType, TMongoFilterQuery<DocType>>;
|
|
31
33
|
defaultSort?: TSortOptions<DocType>;
|
|
34
|
+
[key: string]: any;
|
|
32
35
|
}>) => TDataKitAdapter<DocType>;
|
|
33
36
|
|
|
34
37
|
/**
|
|
@@ -69,16 +72,16 @@ declare const createSearchFilter: <T>(fields: (keyof T | string)[]) => (value: u
|
|
|
69
72
|
declare const dataKitSchemaZod: z.ZodObject<{
|
|
70
73
|
page: z.ZodOptional<z.ZodNumber>;
|
|
71
74
|
limit: z.ZodOptional<z.ZodNumber>;
|
|
72
|
-
query: z.ZodOptional<z.ZodRecord<z.ZodString, z.
|
|
73
|
-
filter: z.ZodOptional<z.ZodRecord<z.ZodString, z.
|
|
75
|
+
query: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean]>>>;
|
|
76
|
+
filter: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>>>;
|
|
74
77
|
filterConfig: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
75
|
-
type: z.ZodEnum<["
|
|
78
|
+
type: z.ZodEnum<["REGEX", "EXACT"]>;
|
|
76
79
|
field: z.ZodOptional<z.ZodString>;
|
|
77
80
|
}, "strip", z.ZodTypeAny, {
|
|
78
|
-
type: "
|
|
81
|
+
type: "REGEX" | "EXACT";
|
|
79
82
|
field?: string | undefined;
|
|
80
83
|
}, {
|
|
81
|
-
type: "
|
|
84
|
+
type: "REGEX" | "EXACT";
|
|
82
85
|
field?: string | undefined;
|
|
83
86
|
}>>>;
|
|
84
87
|
sorts: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
@@ -91,30 +94,33 @@ declare const dataKitSchemaZod: z.ZodObject<{
|
|
|
91
94
|
value: 1 | -1;
|
|
92
95
|
path: string;
|
|
93
96
|
}>, "many">>;
|
|
97
|
+
sort: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodLiteral<1>, z.ZodLiteral<-1>]>>>;
|
|
94
98
|
}, "strip", z.ZodTypeAny, {
|
|
95
|
-
|
|
99
|
+
sort?: Record<string, 1 | -1> | undefined;
|
|
100
|
+
filter?: Record<string, string | number | boolean | null> | undefined;
|
|
96
101
|
sorts?: {
|
|
97
102
|
value: 1 | -1;
|
|
98
103
|
path: string;
|
|
99
104
|
}[] | undefined;
|
|
100
105
|
limit?: number | undefined;
|
|
101
106
|
page?: number | undefined;
|
|
102
|
-
query?: Record<string,
|
|
107
|
+
query?: Record<string, string | number | boolean> | undefined;
|
|
103
108
|
filterConfig?: Record<string, {
|
|
104
|
-
type: "
|
|
109
|
+
type: "REGEX" | "EXACT";
|
|
105
110
|
field?: string | undefined;
|
|
106
111
|
}> | undefined;
|
|
107
112
|
}, {
|
|
108
|
-
|
|
113
|
+
sort?: Record<string, 1 | -1> | undefined;
|
|
114
|
+
filter?: Record<string, string | number | boolean | null> | undefined;
|
|
109
115
|
sorts?: {
|
|
110
116
|
value: 1 | -1;
|
|
111
117
|
path: string;
|
|
112
118
|
}[] | undefined;
|
|
113
119
|
limit?: number | undefined;
|
|
114
120
|
page?: number | undefined;
|
|
115
|
-
query?: Record<string,
|
|
121
|
+
query?: Record<string, string | number | boolean> | undefined;
|
|
116
122
|
filterConfig?: Record<string, {
|
|
117
|
-
type: "
|
|
123
|
+
type: "REGEX" | "EXACT";
|
|
118
124
|
field?: string | undefined;
|
|
119
125
|
}> | undefined;
|
|
120
126
|
}>;
|
package/dist/server.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { T as TDataKitInput, a as TDataKitAdapter, b as TMongoModel, c as TMongoFilterQuery, d as TFilterCustomConfigWithFilter, e as TSortOptions, f as TDataKitResult, g as TExtractDocType } from './next-data-kit-
|
|
2
|
-
export { l as TFilterConfig, k as TFilterCustomConfig, i as THydratedDocument, h as TModel, p as TMongoDocument, m as TMongoFilterOperators, q as TMongoHydratedDocument, n as TMongoRootFilterOperators, o as TObjectId, j as TSortOrder } from './next-data-kit-
|
|
1
|
+
import { T as TDataKitInput, a as TDataKitAdapter, b as TMongoModel, c as TMongoFilterQuery, d as TFilterCustomConfigWithFilter, e as TSortOptions, f as TDataKitResult, g as TExtractDocType } from './next-data-kit-DBl9PPWh.js';
|
|
2
|
+
export { l as TFilterConfig, k as TFilterCustomConfig, i as THydratedDocument, h as TModel, p as TMongoDocument, m as TMongoFilterOperators, q as TMongoHydratedDocument, n as TMongoRootFilterOperators, o as TObjectId, j as TSortOrder } from './next-data-kit-DBl9PPWh.js';
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -16,6 +16,8 @@ type TDataKitServerActionOptions<T, R> = {
|
|
|
16
16
|
filter?: (filterInput?: Record<string, unknown>) => TMongoFilterQuery<T>;
|
|
17
17
|
filterCustom?: TFilterCustomConfigWithFilter<T, TMongoFilterQuery<T>>;
|
|
18
18
|
defaultSort?: TSortOptions<T>;
|
|
19
|
+
maxLimit?: number;
|
|
20
|
+
queryAllowed?: string[];
|
|
19
21
|
};
|
|
20
22
|
declare const dataKitServerAction: <T, R>(props: Readonly<TDataKitServerActionOptions<T, R>>) => Promise<TDataKitResult<R>>;
|
|
21
23
|
|
|
@@ -29,6 +31,7 @@ declare const mongooseAdapter: <M extends TMongoModel<unknown, object>, DocType
|
|
|
29
31
|
filter?: (filterInput?: Record<string, unknown>) => TMongoFilterQuery<DocType>;
|
|
30
32
|
filterCustom?: TFilterCustomConfigWithFilter<DocType, TMongoFilterQuery<DocType>>;
|
|
31
33
|
defaultSort?: TSortOptions<DocType>;
|
|
34
|
+
[key: string]: any;
|
|
32
35
|
}>) => TDataKitAdapter<DocType>;
|
|
33
36
|
|
|
34
37
|
/**
|
|
@@ -69,16 +72,16 @@ declare const createSearchFilter: <T>(fields: (keyof T | string)[]) => (value: u
|
|
|
69
72
|
declare const dataKitSchemaZod: z.ZodObject<{
|
|
70
73
|
page: z.ZodOptional<z.ZodNumber>;
|
|
71
74
|
limit: z.ZodOptional<z.ZodNumber>;
|
|
72
|
-
query: z.ZodOptional<z.ZodRecord<z.ZodString, z.
|
|
73
|
-
filter: z.ZodOptional<z.ZodRecord<z.ZodString, z.
|
|
75
|
+
query: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean]>>>;
|
|
76
|
+
filter: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>>>;
|
|
74
77
|
filterConfig: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
75
|
-
type: z.ZodEnum<["
|
|
78
|
+
type: z.ZodEnum<["REGEX", "EXACT"]>;
|
|
76
79
|
field: z.ZodOptional<z.ZodString>;
|
|
77
80
|
}, "strip", z.ZodTypeAny, {
|
|
78
|
-
type: "
|
|
81
|
+
type: "REGEX" | "EXACT";
|
|
79
82
|
field?: string | undefined;
|
|
80
83
|
}, {
|
|
81
|
-
type: "
|
|
84
|
+
type: "REGEX" | "EXACT";
|
|
82
85
|
field?: string | undefined;
|
|
83
86
|
}>>>;
|
|
84
87
|
sorts: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
@@ -91,30 +94,33 @@ declare const dataKitSchemaZod: z.ZodObject<{
|
|
|
91
94
|
value: 1 | -1;
|
|
92
95
|
path: string;
|
|
93
96
|
}>, "many">>;
|
|
97
|
+
sort: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodLiteral<1>, z.ZodLiteral<-1>]>>>;
|
|
94
98
|
}, "strip", z.ZodTypeAny, {
|
|
95
|
-
|
|
99
|
+
sort?: Record<string, 1 | -1> | undefined;
|
|
100
|
+
filter?: Record<string, string | number | boolean | null> | undefined;
|
|
96
101
|
sorts?: {
|
|
97
102
|
value: 1 | -1;
|
|
98
103
|
path: string;
|
|
99
104
|
}[] | undefined;
|
|
100
105
|
limit?: number | undefined;
|
|
101
106
|
page?: number | undefined;
|
|
102
|
-
query?: Record<string,
|
|
107
|
+
query?: Record<string, string | number | boolean> | undefined;
|
|
103
108
|
filterConfig?: Record<string, {
|
|
104
|
-
type: "
|
|
109
|
+
type: "REGEX" | "EXACT";
|
|
105
110
|
field?: string | undefined;
|
|
106
111
|
}> | undefined;
|
|
107
112
|
}, {
|
|
108
|
-
|
|
113
|
+
sort?: Record<string, 1 | -1> | undefined;
|
|
114
|
+
filter?: Record<string, string | number | boolean | null> | undefined;
|
|
109
115
|
sorts?: {
|
|
110
116
|
value: 1 | -1;
|
|
111
117
|
path: string;
|
|
112
118
|
}[] | undefined;
|
|
113
119
|
limit?: number | undefined;
|
|
114
120
|
page?: number | undefined;
|
|
115
|
-
query?: Record<string,
|
|
121
|
+
query?: Record<string, string | number | boolean> | undefined;
|
|
116
122
|
filterConfig?: Record<string, {
|
|
117
|
-
type: "
|
|
123
|
+
type: "REGEX" | "EXACT";
|
|
118
124
|
field?: string | undefined;
|
|
119
125
|
}> | undefined;
|
|
120
126
|
}>;
|