@90soft/parse-server-kit 2.0.2 → 2.2.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/decorators/routeDecorator.d.ts +4 -15
- package/dist/decorators/routeDecorator.d.ts.map +1 -1
- package/dist/decorators/routeDecorator.js +80 -63
- package/dist/decorators/routeDecorator.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/middleware/middleware.d.ts +2 -2
- package/dist/middleware/middleware.d.ts.map +1 -1
- package/dist/middleware/middleware.js +8 -7
- package/dist/middleware/middleware.js.map +1 -1
- package/dist/middleware/rateLimit.d.ts +10 -0
- package/dist/middleware/rateLimit.d.ts.map +1 -0
- package/dist/middleware/rateLimit.js +59 -0
- package/dist/middleware/rateLimit.js.map +1 -0
- package/package.json +1 -1
|
@@ -1,35 +1,24 @@
|
|
|
1
1
|
import 'reflect-metadata';
|
|
2
2
|
/**
|
|
3
3
|
* @Route class decorator.
|
|
4
|
-
* Accepts a Parse model class (reads
|
|
4
|
+
* Accepts a Parse model class (reads JS class name) or a custom string.
|
|
5
5
|
*/
|
|
6
6
|
export declare function Route(target: Function | string): (constructor: Function) => void;
|
|
7
7
|
/**
|
|
8
8
|
* Global route registry — maps route prefixes to function names.
|
|
9
|
-
* Built during decorator phase, consumed during server init.
|
|
10
9
|
*/
|
|
11
10
|
export declare class RouteRegistry {
|
|
12
|
-
private static
|
|
11
|
+
private static entries;
|
|
13
12
|
private static routeMap;
|
|
14
13
|
private static registeredPrefixes;
|
|
15
|
-
static register(
|
|
14
|
+
static register(jsClassName: string, prefix: string, methodNames: string[]): void;
|
|
16
15
|
/**
|
|
17
16
|
* Called after CloudFunctionRegistry.initialize().
|
|
18
|
-
*
|
|
17
|
+
* Uses definitive method lists — no string matching guesswork.
|
|
19
18
|
*/
|
|
20
19
|
static initialize(): void;
|
|
21
|
-
/**
|
|
22
|
-
* Look up a cloud function name by route path.
|
|
23
|
-
* '/students/create' → 'createStudent'
|
|
24
|
-
*/
|
|
25
20
|
static resolve(routePath: string): string | undefined;
|
|
26
|
-
/**
|
|
27
|
-
* Check if a path starts with a registered route prefix.
|
|
28
|
-
*/
|
|
29
21
|
static isRegisteredPrefix(path: string): boolean;
|
|
30
|
-
/**
|
|
31
|
-
* Get all registered prefixes (for restrictRoutes middleware).
|
|
32
|
-
*/
|
|
33
22
|
static getPrefixes(): string[];
|
|
34
23
|
}
|
|
35
24
|
//# sourceMappingURL=routeDecorator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routeDecorator.d.ts","sourceRoot":"","sources":["../../src/decorators/routeDecorator.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"routeDecorator.d.ts","sourceRoot":"","sources":["../../src/decorators/routeDecorator.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAqG1B;;;GAGG;AACH,wBAAgB,KAAK,CAAC,MAAM,EAAE,QAAQ,GAAG,MAAM,IAC5B,aAAa,QAAQ,UAuBvC;AAED;;GAEG;AACH,qBAAa,aAAa;IAExB,OAAO,CAAC,MAAM,CAAC,OAAO,CAAqE;IAE3F,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAkC;IAEzD,OAAO,CAAC,MAAM,CAAC,kBAAkB,CAA0B;IAE3D,MAAM,CAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE;IAI1E;;;OAGG;IACH,MAAM,CAAC,UAAU;IA6BjB,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAIrD,MAAM,CAAC,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAOhD,MAAM,CAAC,WAAW,IAAI,MAAM,EAAE;CAG/B"}
|
|
@@ -8,16 +8,11 @@ const cloudRegistry_1 = require("./cloudRegistry");
|
|
|
8
8
|
* @Route decorator — maps cloud functions to entity-based routes.
|
|
9
9
|
*
|
|
10
10
|
* Usage:
|
|
11
|
-
* @Route(Student) // reads
|
|
11
|
+
* @Route(Student) // reads JS class name → 'Student' → /api/students/*
|
|
12
12
|
* @Route('school-students') // custom string → /api/school-students/*
|
|
13
13
|
*
|
|
14
|
-
* The decorator
|
|
15
|
-
*
|
|
16
|
-
* the decorated class with that prefix.
|
|
17
|
-
*
|
|
18
|
-
* At server init, CloudFunctionRegistry builds a route map:
|
|
19
|
-
* /students/create → createStudent
|
|
20
|
-
* /students/list → listStudents
|
|
14
|
+
* The decorator captures the class's static method names and registers them
|
|
15
|
+
* with RouteRegistry. At server init, the registry builds the route map.
|
|
21
16
|
*/
|
|
22
17
|
/**
|
|
23
18
|
* Convert PascalCase to kebab-case plural.
|
|
@@ -29,8 +24,6 @@ function toKebabPlural(name) {
|
|
|
29
24
|
const kebab = name
|
|
30
25
|
.replace(/([a-z0-9])([A-Z])/g, '$1-$2')
|
|
31
26
|
.toLowerCase();
|
|
32
|
-
// Simple pluralize: add 's' (covers most cases)
|
|
33
|
-
// Words ending in 'y' → 'ies', 's'/'sh'/'ch'/'x' → 'es'
|
|
34
27
|
if (kebab.endsWith('y') && !kebab.endsWith('ay') && !kebab.endsWith('ey') && !kebab.endsWith('oy')) {
|
|
35
28
|
return kebab.slice(0, -1) + 'ies';
|
|
36
29
|
}
|
|
@@ -40,78 +33,112 @@ function toKebabPlural(name) {
|
|
|
40
33
|
return kebab + 's';
|
|
41
34
|
}
|
|
42
35
|
/**
|
|
43
|
-
*
|
|
44
|
-
* '
|
|
45
|
-
* '
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
36
|
+
* Convert PascalCase to kebab-case (no pluralization).
|
|
37
|
+
* 'TaskStatus' → 'task-status'
|
|
38
|
+
* 'UnreadCount' → 'unread-count'
|
|
39
|
+
*/
|
|
40
|
+
function toKebab(name) {
|
|
41
|
+
return name.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Extract action from function name by stripping the class name.
|
|
45
|
+
*
|
|
46
|
+
* Exact match (className or plural):
|
|
47
|
+
* createStudent → 'create'
|
|
48
|
+
* listStudents → 'list'
|
|
49
|
+
*
|
|
50
|
+
* Extended match (extra suffix after class name):
|
|
51
|
+
* updateTaskStatus → strip 'Task' → 'update-status'
|
|
52
|
+
* getUnreadCount → no class name found → 'get-unread-count'
|
|
51
53
|
*/
|
|
52
|
-
function extractAction(functionName,
|
|
53
|
-
const
|
|
54
|
+
function extractAction(functionName, jsClassName) {
|
|
55
|
+
const singular = jsClassName;
|
|
56
|
+
const plural = toKebabPlural(singular).replace(/-/g, '');
|
|
54
57
|
const fnLower = functionName.toLowerCase();
|
|
55
|
-
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
58
|
+
const singularLower = singular.toLowerCase();
|
|
59
|
+
const pluralLower = plural.toLowerCase();
|
|
60
|
+
// Try to find where the class name appears in the function name
|
|
61
|
+
let classEnd = -1;
|
|
62
|
+
let matchLen = 0;
|
|
63
|
+
// Check plural first (listStudents → 'list')
|
|
64
|
+
const pluralIdx = fnLower.indexOf(pluralLower);
|
|
65
|
+
if (pluralIdx > 0) {
|
|
66
|
+
classEnd = pluralIdx + pluralLower.length;
|
|
67
|
+
matchLen = pluralLower.length;
|
|
61
68
|
}
|
|
62
|
-
//
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
69
|
+
// Check singular (createStudent → 'create')
|
|
70
|
+
if (classEnd === -1) {
|
|
71
|
+
const singularIdx = fnLower.indexOf(singularLower);
|
|
72
|
+
if (singularIdx > 0) {
|
|
73
|
+
classEnd = singularIdx + singularLower.length;
|
|
74
|
+
matchLen = singularLower.length;
|
|
66
75
|
}
|
|
67
76
|
}
|
|
68
|
-
|
|
69
|
-
|
|
77
|
+
if (classEnd === -1) {
|
|
78
|
+
// Class name not found — kebab the entire function name
|
|
79
|
+
return toKebab(functionName);
|
|
80
|
+
}
|
|
81
|
+
// Extract prefix (before class name)
|
|
82
|
+
const prefixEnd = classEnd - matchLen;
|
|
83
|
+
const prefix = functionName.slice(0, prefixEnd).toLowerCase();
|
|
84
|
+
// Extract suffix (after class name)
|
|
85
|
+
const suffix = functionName.slice(classEnd);
|
|
86
|
+
if (!suffix) {
|
|
87
|
+
// Exact match: createStudent → 'create'
|
|
88
|
+
return prefix;
|
|
89
|
+
}
|
|
90
|
+
// Extended: updateTaskStatus → 'update-status'
|
|
91
|
+
return prefix + '-' + toKebab(suffix);
|
|
70
92
|
}
|
|
71
93
|
/**
|
|
72
94
|
* @Route class decorator.
|
|
73
|
-
* Accepts a Parse model class (reads
|
|
95
|
+
* Accepts a Parse model class (reads JS class name) or a custom string.
|
|
74
96
|
*/
|
|
75
97
|
function Route(target) {
|
|
76
98
|
return function (constructor) {
|
|
77
99
|
let prefix;
|
|
78
|
-
let
|
|
100
|
+
let jsClassName;
|
|
79
101
|
if (typeof target === 'string') {
|
|
80
102
|
prefix = target;
|
|
81
|
-
|
|
103
|
+
jsClassName = target;
|
|
82
104
|
}
|
|
83
105
|
else {
|
|
84
|
-
//
|
|
85
|
-
className
|
|
86
|
-
|
|
106
|
+
// Use JS class name (target.name), NOT Parse className
|
|
107
|
+
// Parse className could be '_User' which breaks matching
|
|
108
|
+
jsClassName = target.name;
|
|
109
|
+
prefix = toKebabPlural(jsClassName);
|
|
87
110
|
}
|
|
88
|
-
//
|
|
89
|
-
|
|
90
|
-
|
|
111
|
+
// Capture static method names from the decorated class
|
|
112
|
+
const methodNames = Object.getOwnPropertyNames(constructor)
|
|
113
|
+
.filter(name => {
|
|
114
|
+
if (name === 'length' || name === 'name' || name === 'prototype')
|
|
115
|
+
return false;
|
|
116
|
+
return typeof constructor[name] === 'function';
|
|
117
|
+
});
|
|
118
|
+
RouteRegistry.register(jsClassName, prefix, methodNames);
|
|
91
119
|
};
|
|
92
120
|
}
|
|
93
121
|
/**
|
|
94
122
|
* Global route registry — maps route prefixes to function names.
|
|
95
|
-
* Built during decorator phase, consumed during server init.
|
|
96
123
|
*/
|
|
97
124
|
class RouteRegistry {
|
|
98
|
-
static register(
|
|
99
|
-
this.
|
|
125
|
+
static register(jsClassName, prefix, methodNames) {
|
|
126
|
+
this.entries.set(jsClassName, { prefix, methodNames });
|
|
100
127
|
}
|
|
101
128
|
/**
|
|
102
129
|
* Called after CloudFunctionRegistry.initialize().
|
|
103
|
-
*
|
|
130
|
+
* Uses definitive method lists — no string matching guesswork.
|
|
104
131
|
*/
|
|
105
132
|
static initialize() {
|
|
106
133
|
const functions = cloudRegistry_1.CloudFunctionRegistry.getFunctions();
|
|
107
134
|
for (const fn of functions) {
|
|
108
|
-
// Find which
|
|
135
|
+
// Find which class owns this function by checking method name lists
|
|
109
136
|
let matchedPrefix = null;
|
|
110
137
|
let matchedClassName = null;
|
|
111
|
-
for (const [
|
|
112
|
-
if (fn.name
|
|
138
|
+
for (const [jsClassName, { prefix, methodNames }] of this.entries) {
|
|
139
|
+
if (methodNames.includes(fn.name)) {
|
|
113
140
|
matchedPrefix = prefix;
|
|
114
|
-
matchedClassName =
|
|
141
|
+
matchedClassName = jsClassName;
|
|
115
142
|
break;
|
|
116
143
|
}
|
|
117
144
|
}
|
|
@@ -126,16 +153,9 @@ class RouteRegistry {
|
|
|
126
153
|
}
|
|
127
154
|
console.log(`Route registry: ${this.routeMap.size} routes registered`);
|
|
128
155
|
}
|
|
129
|
-
/**
|
|
130
|
-
* Look up a cloud function name by route path.
|
|
131
|
-
* '/students/create' → 'createStudent'
|
|
132
|
-
*/
|
|
133
156
|
static resolve(routePath) {
|
|
134
157
|
return this.routeMap.get(routePath);
|
|
135
158
|
}
|
|
136
|
-
/**
|
|
137
|
-
* Check if a path starts with a registered route prefix.
|
|
138
|
-
*/
|
|
139
159
|
static isRegisteredPrefix(path) {
|
|
140
160
|
for (const prefix of this.registeredPrefixes) {
|
|
141
161
|
if (path.startsWith(prefix))
|
|
@@ -143,18 +163,15 @@ class RouteRegistry {
|
|
|
143
163
|
}
|
|
144
164
|
return false;
|
|
145
165
|
}
|
|
146
|
-
/**
|
|
147
|
-
* Get all registered prefixes (for restrictRoutes middleware).
|
|
148
|
-
*/
|
|
149
166
|
static getPrefixes() {
|
|
150
167
|
return Array.from(this.registeredPrefixes);
|
|
151
168
|
}
|
|
152
169
|
}
|
|
153
170
|
exports.RouteRegistry = RouteRegistry;
|
|
154
|
-
//
|
|
155
|
-
RouteRegistry.
|
|
156
|
-
// route path → function name
|
|
171
|
+
// jsClassName → { prefix, methodNames }
|
|
172
|
+
RouteRegistry.entries = new Map();
|
|
173
|
+
// route path → function name
|
|
157
174
|
RouteRegistry.routeMap = new Map();
|
|
158
|
-
//
|
|
175
|
+
// registered route prefixes
|
|
159
176
|
RouteRegistry.registeredPrefixes = new Set();
|
|
160
177
|
//# sourceMappingURL=routeDecorator.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routeDecorator.js","sourceRoot":"","sources":["../../src/decorators/routeDecorator.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"routeDecorator.js","sourceRoot":"","sources":["../../src/decorators/routeDecorator.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -20,6 +20,7 @@ export type { RoleString } from './utils/constants';
|
|
|
20
20
|
export { catchError, getUserRoles, getUsersRoles, formatCount, generateRandomPassword, generateRandomInteger, generateRandomString, sleep } from './utils/helper';
|
|
21
21
|
export { importFiles } from './utils/dynamicImport';
|
|
22
22
|
export { validateFunctionRoutes, validateEntityRoutes, restrictRoutes, removeResultMiddleware, conditionalJsonMiddleware } from './middleware/middleware';
|
|
23
|
+
export { checkRateLimit } from './middleware/rateLimit';
|
|
23
24
|
export { SwaggerRegistry } from './swagger/swaggerRegistry';
|
|
24
25
|
export type { SwaggerModelSchema, SwaggerPropertySchema, SwaggerFunctionSchema } from './swagger/swaggerRegistry';
|
|
25
26
|
export { generateSwaggerSpec, getSwaggerJson } from './swagger/swaggerSpec';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjI,YAAY,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAE3G,OAAO,EAAE,aAAa,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAC1G,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAEnE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAC9E,WAAW,EAAE,UAAU,EAAE,WAAW,EACpC,cAAc,EAAE,aAAa,EAAE,gBAAgB,EAAE,eAAe,EAChE,aAAa,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AACpF,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAE/D,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE9E,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAGnE,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAC5D,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,qBAAqB,EAAE,gBAAgB,EACnF,sBAAsB,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAEpI,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACtH,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AACnG,YAAY,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAChF,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAC;AAG9E,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAG1H,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAG/C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACxE,YAAY,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAGpD,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,WAAW,EAC3D,sBAAsB,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACrG,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAGpD,OAAO,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,cAAc,EACnE,sBAAsB,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjI,YAAY,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAE3G,OAAO,EAAE,aAAa,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AAC1G,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAEnE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAC9E,WAAW,EAAE,UAAU,EAAE,WAAW,EACpC,cAAc,EAAE,aAAa,EAAE,gBAAgB,EAAE,eAAe,EAChE,aAAa,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AACpF,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAE/D,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE9E,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAGnE,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAC5D,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,qBAAqB,EAAE,gBAAgB,EACnF,sBAAsB,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAEpI,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACtH,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AACnG,YAAY,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAChF,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAC;AAG9E,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAG1H,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAG/C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACxE,YAAY,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAGpD,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,WAAW,EAC3D,sBAAsB,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACrG,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAGpD,OAAO,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,cAAc,EACnE,sBAAsB,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AACrF,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAGxD,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,YAAY,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClH,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// @90soft/parse-server-kit — complete toolkit for Parse Server
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
exports.importFiles = exports.sleep = exports.generateRandomString = exports.generateRandomInteger = exports.generateRandomPassword = exports.formatCount = exports.getUsersRoles = exports.getUserRoles = exports.catchError = exports.MAX_QUERY_LIMIT = exports.roleKey = exports.UserRoles = exports.implementACL = exports.BaseModel = exports.applyMongoValidators = exports.getValidators = exports.validateOrThrow = exports.validateObject = exports.classNames = exports.RouteRegistry = exports.Route = exports.CronRegistry = exports.CronSchedule = exports.Cron = exports.TriggerRegistry = exports.AfterEvent = exports.BeforeSubscribe = exports.BeforeConnect = exports.AfterDeleteFile = exports.BeforeDeleteFile = exports.AfterSaveFile = exports.BeforeSaveFile = exports.AfterLogout = exports.AfterLogin = exports.BeforeLogin = exports.AfterFind = exports.BeforeFind = exports.AfterDelete = exports.BeforeDelete = exports.AfterSave = exports.BeforeSave = exports.CloudFunctionRegistry = exports.onFunctionRegistered = exports.ProtectedCloudFunction = exports.CloudFunction = exports.onFieldRegistered = exports.onClassRegistered = exports.getSchemaDefinition = exports.ParseField = exports.ParseClass = void 0;
|
|
5
|
-
exports.setupSwagger = exports.getSwaggerJson = exports.generateSwaggerSpec = exports.SwaggerRegistry = exports.conditionalJsonMiddleware = exports.removeResultMiddleware = exports.restrictRoutes = exports.validateEntityRoutes = exports.validateFunctionRoutes = void 0;
|
|
5
|
+
exports.setupSwagger = exports.getSwaggerJson = exports.generateSwaggerSpec = exports.SwaggerRegistry = exports.checkRateLimit = exports.conditionalJsonMiddleware = exports.removeResultMiddleware = exports.restrictRoutes = exports.validateEntityRoutes = exports.validateFunctionRoutes = void 0;
|
|
6
6
|
// ── Decorators ──
|
|
7
7
|
var parseDecorators_1 = require("./decorators/parseDecorators");
|
|
8
8
|
Object.defineProperty(exports, "ParseClass", { enumerable: true, get: function () { return parseDecorators_1.ParseClass; } });
|
|
@@ -80,6 +80,8 @@ Object.defineProperty(exports, "validateEntityRoutes", { enumerable: true, get:
|
|
|
80
80
|
Object.defineProperty(exports, "restrictRoutes", { enumerable: true, get: function () { return middleware_1.restrictRoutes; } });
|
|
81
81
|
Object.defineProperty(exports, "removeResultMiddleware", { enumerable: true, get: function () { return middleware_1.removeResultMiddleware; } });
|
|
82
82
|
Object.defineProperty(exports, "conditionalJsonMiddleware", { enumerable: true, get: function () { return middleware_1.conditionalJsonMiddleware; } });
|
|
83
|
+
var rateLimit_1 = require("./middleware/rateLimit");
|
|
84
|
+
Object.defineProperty(exports, "checkRateLimit", { enumerable: true, get: function () { return rateLimit_1.checkRateLimit; } });
|
|
83
85
|
// ── Swagger ──
|
|
84
86
|
var swaggerRegistry_1 = require("./swagger/swaggerRegistry");
|
|
85
87
|
Object.defineProperty(exports, "SwaggerRegistry", { enumerable: true, get: function () { return swaggerRegistry_1.SwaggerRegistry; } });
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,+DAA+D;;;;AAE/D,mBAAmB;AACnB,gEAAiI;AAAxH,6GAAA,UAAU,OAAA;AAAE,6GAAA,UAAU,OAAA;AAAE,sHAAA,mBAAmB,OAAA;AAAE,oHAAA,iBAAiB,OAAA;AAAE,oHAAA,iBAAiB,OAAA;AAG1F,8DAA0G;AAAjG,+GAAA,aAAa,OAAA;AAAE,wHAAA,sBAAsB,OAAA;AAAE,sHAAA,oBAAoB,OAAA;AACpE,4DAAmE;AAA1D,sHAAA,qBAAqB,OAAA;AAE9B,kEAGoF;AAH3E,8GAAA,UAAU,OAAA;AAAE,6GAAA,SAAS,OAAA;AAAE,gHAAA,YAAY,OAAA;AAAE,+GAAA,WAAW,OAAA;AAAE,8GAAA,UAAU,OAAA;AAAE,6GAAA,SAAS,OAAA;AAC9E,+GAAA,WAAW,OAAA;AAAE,8GAAA,UAAU,OAAA;AAAE,+GAAA,WAAW,OAAA;AACpC,kHAAA,cAAc,OAAA;AAAE,iHAAA,aAAa,OAAA;AAAE,oHAAA,gBAAgB,OAAA;AAAE,mHAAA,eAAe,OAAA;AAChE,iHAAA,aAAa,OAAA;AAAE,mHAAA,eAAe,OAAA;AAAE,8GAAA,UAAU,OAAA;AAC5C,gEAA+D;AAAtD,kHAAA,eAAe,OAAA;AAExB,4DAA8E;AAArE,qGAAA,IAAI,OAAA;AAAE,6GAAA,YAAY,OAAA;AAAE,6GAAA,YAAY,OAAA;AAEzC,8DAAmE;AAA1D,uGAAA,KAAK,OAAA;AAAE,+GAAA,aAAa,OAAA;AAE7B,cAAc;AACd,8DAA4D;AAAnD,yGAAA,UAAU,OAAA;AASnB,mBAAmB;AACnB,sEAA0H;AAAjH,iHAAA,cAAc,OAAA;AAAE,kHAAA,eAAe,OAAA;AAAE,gHAAA,aAAa,OAAA;AAAE,uHAAA,oBAAoB,OAAA;AAE7E,eAAe;AACf,gDAA+C;AAAtC,sGAAA,SAAS,OAAA;AAElB,0BAA0B;AAC1B,mCAA2C;AAAlC,mGAAA,YAAY,OAAA;AACrB,+CAAwE;AAA/D,sGAAA,SAAS,OAAA;AAAE,oGAAA,OAAO,OAAA;AAAE,4GAAA,eAAe,OAAA;AAG5C,kBAAkB;AAClB,yCACqG;AAD5F,oGAAA,UAAU,OAAA;AAAE,sGAAA,YAAY,OAAA;AAAE,uGAAA,aAAa,OAAA;AAAE,qGAAA,WAAW,OAAA;AAC3D,gHAAA,sBAAsB,OAAA;AAAE,+GAAA,qBAAqB,OAAA;AAAE,8GAAA,oBAAoB,OAAA;AAAE,+FAAA,KAAK,OAAA;AAC5E,uDAAoD;AAA3C,4GAAA,WAAW,OAAA;AAEpB,mBAAmB;AACnB,sDACqF;AAD5E,oHAAA,sBAAsB,OAAA;AAAE,kHAAA,oBAAoB,OAAA;AAAE,4GAAA,cAAc,OAAA;AACnE,oHAAA,sBAAsB,OAAA;AAAE,uHAAA,yBAAyB,OAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,+DAA+D;;;;AAE/D,mBAAmB;AACnB,gEAAiI;AAAxH,6GAAA,UAAU,OAAA;AAAE,6GAAA,UAAU,OAAA;AAAE,sHAAA,mBAAmB,OAAA;AAAE,oHAAA,iBAAiB,OAAA;AAAE,oHAAA,iBAAiB,OAAA;AAG1F,8DAA0G;AAAjG,+GAAA,aAAa,OAAA;AAAE,wHAAA,sBAAsB,OAAA;AAAE,sHAAA,oBAAoB,OAAA;AACpE,4DAAmE;AAA1D,sHAAA,qBAAqB,OAAA;AAE9B,kEAGoF;AAH3E,8GAAA,UAAU,OAAA;AAAE,6GAAA,SAAS,OAAA;AAAE,gHAAA,YAAY,OAAA;AAAE,+GAAA,WAAW,OAAA;AAAE,8GAAA,UAAU,OAAA;AAAE,6GAAA,SAAS,OAAA;AAC9E,+GAAA,WAAW,OAAA;AAAE,8GAAA,UAAU,OAAA;AAAE,+GAAA,WAAW,OAAA;AACpC,kHAAA,cAAc,OAAA;AAAE,iHAAA,aAAa,OAAA;AAAE,oHAAA,gBAAgB,OAAA;AAAE,mHAAA,eAAe,OAAA;AAChE,iHAAA,aAAa,OAAA;AAAE,mHAAA,eAAe,OAAA;AAAE,8GAAA,UAAU,OAAA;AAC5C,gEAA+D;AAAtD,kHAAA,eAAe,OAAA;AAExB,4DAA8E;AAArE,qGAAA,IAAI,OAAA;AAAE,6GAAA,YAAY,OAAA;AAAE,6GAAA,YAAY,OAAA;AAEzC,8DAAmE;AAA1D,uGAAA,KAAK,OAAA;AAAE,+GAAA,aAAa,OAAA;AAE7B,cAAc;AACd,8DAA4D;AAAnD,yGAAA,UAAU,OAAA;AASnB,mBAAmB;AACnB,sEAA0H;AAAjH,iHAAA,cAAc,OAAA;AAAE,kHAAA,eAAe,OAAA;AAAE,gHAAA,aAAa,OAAA;AAAE,uHAAA,oBAAoB,OAAA;AAE7E,eAAe;AACf,gDAA+C;AAAtC,sGAAA,SAAS,OAAA;AAElB,0BAA0B;AAC1B,mCAA2C;AAAlC,mGAAA,YAAY,OAAA;AACrB,+CAAwE;AAA/D,sGAAA,SAAS,OAAA;AAAE,oGAAA,OAAO,OAAA;AAAE,4GAAA,eAAe,OAAA;AAG5C,kBAAkB;AAClB,yCACqG;AAD5F,oGAAA,UAAU,OAAA;AAAE,sGAAA,YAAY,OAAA;AAAE,uGAAA,aAAa,OAAA;AAAE,qGAAA,WAAW,OAAA;AAC3D,gHAAA,sBAAsB,OAAA;AAAE,+GAAA,qBAAqB,OAAA;AAAE,8GAAA,oBAAoB,OAAA;AAAE,+FAAA,KAAK,OAAA;AAC5E,uDAAoD;AAA3C,4GAAA,WAAW,OAAA;AAEpB,mBAAmB;AACnB,sDACqF;AAD5E,oHAAA,sBAAsB,OAAA;AAAE,kHAAA,oBAAoB,OAAA;AAAE,4GAAA,cAAc,OAAA;AACnE,oHAAA,sBAAsB,OAAA;AAAE,uHAAA,yBAAyB,OAAA;AACnD,oDAAwD;AAA/C,2GAAA,cAAc,OAAA;AAEvB,gBAAgB;AAChB,6DAA4D;AAAnD,kHAAA,eAAe,OAAA;AAExB,qDAA4E;AAAnE,kHAAA,mBAAmB,OAAA;AAAE,6GAAA,cAAc,OAAA;AAC5C,yCAA+C;AAAtC,qGAAA,YAAY,OAAA"}
|
|
@@ -35,7 +35,7 @@ export declare function restrictRoutes(req: any, res: Response, next: NextFuncti
|
|
|
35
35
|
export declare function conditionalJsonMiddleware(req: Request, res: Response, next: NextFunction): void;
|
|
36
36
|
/**
|
|
37
37
|
* Removes the {result: ...} wrapper from Parse Server cloud function responses.
|
|
38
|
-
*
|
|
38
|
+
* Applied unconditionally — Parse always wraps cloud function results.
|
|
39
39
|
*/
|
|
40
|
-
export declare function removeResultMiddleware(req: any, res: any, next: any):
|
|
40
|
+
export declare function removeResultMiddleware(req: any, res: any, next: any): void;
|
|
41
41
|
//# sourceMappingURL=middleware.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../src/middleware/middleware.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,EAAE,EAAC,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAC,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../../src/middleware/middleware.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,EAAE,EAAC,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAC,MAAM,SAAS,CAAC;AAMjE;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,YAAY,qDAoBnB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,YAAY,qDAgDnB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,QAAQ,EACb,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,cAAc,QAUzB;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,qDAwBzE;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,YAAY,QAWnB;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,QAWnE"}
|
|
@@ -12,6 +12,7 @@ exports.removeResultMiddleware = removeResultMiddleware;
|
|
|
12
12
|
const express_1 = __importDefault(require("express"));
|
|
13
13
|
const cloudRegistry_1 = require("../decorators/cloudRegistry");
|
|
14
14
|
const routeDecorator_1 = require("../decorators/routeDecorator");
|
|
15
|
+
const rateLimit_1 = require("./rateLimit");
|
|
15
16
|
/**
|
|
16
17
|
* Validates legacy /functions/* routes.
|
|
17
18
|
* Skips if already handled by validateEntityRoutes.
|
|
@@ -66,6 +67,12 @@ function validateEntityRoutes(req, res, next) {
|
|
|
66
67
|
if (!metadata.config.methods.includes(req.method)) {
|
|
67
68
|
return res.status(405).json({ message: 'Method not allowed' });
|
|
68
69
|
}
|
|
70
|
+
// Rate limit check — if config exists and limit exceeded, returns 429
|
|
71
|
+
if (metadata.config.rateLimit) {
|
|
72
|
+
const allowed = (0, rateLimit_1.checkRateLimit)(req, res, functionName, metadata.config.rateLimit);
|
|
73
|
+
if (!allowed)
|
|
74
|
+
return; // 429 already sent
|
|
75
|
+
}
|
|
69
76
|
// Rewrite URL to /functions/{functionName} so Parse Server handles it
|
|
70
77
|
// Preserve query string for GET requests
|
|
71
78
|
const queryString = req.originalUrl.split('?')[1];
|
|
@@ -133,15 +140,9 @@ function conditionalJsonMiddleware(req, res, next) {
|
|
|
133
140
|
}
|
|
134
141
|
/**
|
|
135
142
|
* Removes the {result: ...} wrapper from Parse Server cloud function responses.
|
|
136
|
-
*
|
|
143
|
+
* Applied unconditionally — Parse always wraps cloud function results.
|
|
137
144
|
*/
|
|
138
145
|
function removeResultMiddleware(req, res, next) {
|
|
139
|
-
const mountPath = process.env.mountPath || '/api';
|
|
140
|
-
const pathAfterMount = req.path.replace(mountPath, '');
|
|
141
|
-
const isEntityRoute = routeDecorator_1.RouteRegistry.isRegisteredPrefix(pathAfterMount);
|
|
142
|
-
const isFunctionRoute = req.path.includes('/functions');
|
|
143
|
-
if (!isEntityRoute && !isFunctionRoute)
|
|
144
|
-
return next();
|
|
145
146
|
const originalJson = res.json.bind(res);
|
|
146
147
|
res.json = (body) => {
|
|
147
148
|
if (body && typeof body === 'object' && 'result' in body) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../src/middleware/middleware.ts"],"names":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../src/middleware/middleware.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Request, Response } from 'express';
|
|
2
|
+
/**
|
|
3
|
+
* Check rate limit for a function + client.
|
|
4
|
+
* Returns null if allowed, or an error response object if exceeded.
|
|
5
|
+
*/
|
|
6
|
+
export declare function checkRateLimit(req: Request, res: Response, functionName: string, config: {
|
|
7
|
+
windowMs: number;
|
|
8
|
+
max: number;
|
|
9
|
+
}): boolean;
|
|
10
|
+
//# sourceMappingURL=rateLimit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rateLimit.d.ts","sourceRoot":"","sources":["../../src/middleware/rateLimit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAE,QAAQ,EAAC,MAAM,SAAS,CAAC;AAgC1C;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GACxC,OAAO,CAiCT"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.checkRateLimit = checkRateLimit;
|
|
4
|
+
// Map<functionName, Map<clientKey, RateLimitEntry>>
|
|
5
|
+
const store = new Map();
|
|
6
|
+
// Cleanup old entries every 5 minutes
|
|
7
|
+
setInterval(() => {
|
|
8
|
+
const now = Date.now();
|
|
9
|
+
for (const [fnName, clients] of store) {
|
|
10
|
+
for (const [key, entry] of clients) {
|
|
11
|
+
if (now > entry.resetAt) {
|
|
12
|
+
clients.delete(key);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
if (clients.size === 0) {
|
|
16
|
+
store.delete(fnName);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}, 5 * 60 * 1000);
|
|
20
|
+
/**
|
|
21
|
+
* Get client key — session token if available, fallback to IP.
|
|
22
|
+
*/
|
|
23
|
+
function getClientKey(req) {
|
|
24
|
+
return req.headers['x-parse-session-token'] || req.ip || 'unknown';
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Check rate limit for a function + client.
|
|
28
|
+
* Returns null if allowed, or an error response object if exceeded.
|
|
29
|
+
*/
|
|
30
|
+
function checkRateLimit(req, res, functionName, config) {
|
|
31
|
+
const clientKey = getClientKey(req);
|
|
32
|
+
const now = Date.now();
|
|
33
|
+
// Get or create function map
|
|
34
|
+
if (!store.has(functionName)) {
|
|
35
|
+
store.set(functionName, new Map());
|
|
36
|
+
}
|
|
37
|
+
const clients = store.get(functionName);
|
|
38
|
+
// Get or create client entry
|
|
39
|
+
const entry = clients.get(clientKey);
|
|
40
|
+
if (!entry || now > entry.resetAt) {
|
|
41
|
+
// First request or window expired — start fresh
|
|
42
|
+
clients.set(clientKey, { count: 1, resetAt: now + config.windowMs });
|
|
43
|
+
return true; // allowed
|
|
44
|
+
}
|
|
45
|
+
if (entry.count < config.max) {
|
|
46
|
+
// Under limit
|
|
47
|
+
entry.count++;
|
|
48
|
+
return true; // allowed
|
|
49
|
+
}
|
|
50
|
+
// Exceeded — send 429
|
|
51
|
+
const retryAfter = Math.ceil((entry.resetAt - now) / 1000);
|
|
52
|
+
res.set('Retry-After', String(retryAfter));
|
|
53
|
+
res.status(429).json({
|
|
54
|
+
message: `Too many requests. Try again in ${retryAfter} seconds.`,
|
|
55
|
+
retryAfter,
|
|
56
|
+
});
|
|
57
|
+
return false; // blocked
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=rateLimit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rateLimit.js","sourceRoot":"","sources":["../../src/middleware/rateLimit.ts"],"names":[],"mappings":";;AAoCA,wCAsCC;AAnED,oDAAoD;AACpD,MAAM,KAAK,GAA6C,IAAI,GAAG,EAAE,CAAC;AAElE,sCAAsC;AACtC,WAAW,CAAC,GAAG,EAAE;IACf,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,KAAK,EAAE,CAAC;QACtC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,OAAO,EAAE,CAAC;YACnC,IAAI,GAAG,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC;gBACxB,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACtB,CAAC;QACH,CAAC;QACD,IAAI,OAAO,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YACvB,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;AACH,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;AAElB;;GAEG;AACH,SAAS,YAAY,CAAC,GAAY;IAChC,OAAQ,GAAG,CAAC,OAAO,CAAC,uBAAuB,CAAY,IAAI,GAAG,CAAC,EAAE,IAAI,SAAS,CAAC;AACjF,CAAC;AAED;;;GAGG;AACH,SAAgB,cAAc,CAC5B,GAAY,EACZ,GAAa,EACb,YAAoB,EACpB,MAAyC;IAEzC,MAAM,SAAS,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;IACpC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAEvB,6BAA6B;IAC7B,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;QAC7B,KAAK,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;IACrC,CAAC;IACD,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,YAAY,CAAE,CAAC;IAEzC,6BAA6B;IAC7B,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAErC,IAAI,CAAC,KAAK,IAAI,GAAG,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC;QAClC,gDAAgD;QAChD,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,GAAG,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;QACrE,OAAO,IAAI,CAAC,CAAC,UAAU;IACzB,CAAC;IAED,IAAI,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC,GAAG,EAAE,CAAC;QAC7B,cAAc;QACd,KAAK,CAAC,KAAK,EAAE,CAAC;QACd,OAAO,IAAI,CAAC,CAAC,UAAU;IACzB,CAAC;IAED,sBAAsB;IACtB,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,OAAO,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;IAC3D,GAAG,CAAC,GAAG,CAAC,aAAa,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;IAC3C,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;QACnB,OAAO,EAAE,mCAAmC,UAAU,WAAW;QACjE,UAAU;KACX,CAAC,CAAC;IACH,OAAO,KAAK,CAAC,CAAC,UAAU;AAC1B,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@90soft/parse-server-kit",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "Complete decorator-driven development kit for Parse Server — models, cloud functions, triggers, cron, routing, ACL, Swagger, and more.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|