@90soft/parse-server-kit 1.0.0 → 2.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.
Files changed (85) hide show
  1. package/dist/decorators/cloudDecorator.d.ts +7 -0
  2. package/dist/decorators/cloudDecorator.d.ts.map +1 -0
  3. package/dist/decorators/cloudDecorator.js +77 -0
  4. package/dist/decorators/cloudDecorator.js.map +1 -0
  5. package/dist/decorators/cloudRegistry.d.ts +9 -0
  6. package/dist/decorators/cloudRegistry.d.ts.map +1 -0
  7. package/dist/decorators/cloudRegistry.js +26 -0
  8. package/dist/decorators/cloudRegistry.js.map +1 -0
  9. package/dist/decorators/cronDecorator.d.ts +6 -0
  10. package/dist/decorators/cronDecorator.d.ts.map +1 -0
  11. package/dist/decorators/cronDecorator.js +28 -0
  12. package/dist/decorators/cronDecorator.js.map +1 -0
  13. package/dist/decorators/cronRegistry.d.ts +13 -0
  14. package/dist/decorators/cronRegistry.d.ts.map +1 -0
  15. package/dist/decorators/cronRegistry.js +96 -0
  16. package/dist/decorators/cronRegistry.js.map +1 -0
  17. package/dist/decorators/routeDecorator.d.ts +35 -0
  18. package/dist/decorators/routeDecorator.d.ts.map +1 -0
  19. package/dist/decorators/routeDecorator.js +160 -0
  20. package/dist/decorators/routeDecorator.js.map +1 -0
  21. package/dist/decorators/triggerDecorator.d.ts +19 -0
  22. package/dist/decorators/triggerDecorator.d.ts.map +1 -0
  23. package/dist/decorators/triggerDecorator.js +45 -0
  24. package/dist/decorators/triggerDecorator.js.map +1 -0
  25. package/dist/decorators/triggerRegistry.d.ts +10 -0
  26. package/dist/decorators/triggerRegistry.d.ts.map +1 -0
  27. package/dist/decorators/triggerRegistry.js +87 -0
  28. package/dist/decorators/triggerRegistry.js.map +1 -0
  29. package/dist/decorators/types/cloudTypes.d.ts +32 -0
  30. package/dist/decorators/types/cloudTypes.d.ts.map +1 -0
  31. package/dist/decorators/types/cloudTypes.js +3 -0
  32. package/dist/decorators/types/cloudTypes.js.map +1 -0
  33. package/dist/decorators/types/common.d.ts +14 -0
  34. package/dist/decorators/types/common.d.ts.map +1 -0
  35. package/dist/decorators/types/common.js +3 -0
  36. package/dist/decorators/types/common.js.map +1 -0
  37. package/dist/decorators/types/cronTypes.d.ts +32 -0
  38. package/dist/decorators/types/cronTypes.d.ts.map +1 -0
  39. package/dist/decorators/types/cronTypes.js +21 -0
  40. package/dist/decorators/types/cronTypes.js.map +1 -0
  41. package/dist/decorators/types/fieldValidation.d.ts +36 -0
  42. package/dist/decorators/types/fieldValidation.d.ts.map +1 -0
  43. package/dist/decorators/types/fieldValidation.js +135 -0
  44. package/dist/decorators/types/fieldValidation.js.map +1 -0
  45. package/dist/decorators/types/triggerTypes.d.ts +14 -0
  46. package/dist/decorators/types/triggerTypes.d.ts.map +1 -0
  47. package/dist/decorators/types/triggerTypes.js +3 -0
  48. package/dist/decorators/types/triggerTypes.js.map +1 -0
  49. package/dist/index.d.ts +25 -4
  50. package/dist/index.d.ts.map +1 -1
  51. package/dist/index.js +78 -6
  52. package/dist/index.js.map +1 -1
  53. package/dist/middleware/middleware.d.ts +36 -0
  54. package/dist/middleware/middleware.d.ts.map +1 -0
  55. package/dist/middleware/middleware.js +133 -0
  56. package/dist/middleware/middleware.js.map +1 -0
  57. package/dist/swagger/index.d.ts +9 -0
  58. package/dist/swagger/index.d.ts.map +1 -0
  59. package/dist/swagger/index.js +37 -0
  60. package/dist/swagger/index.js.map +1 -0
  61. package/dist/swagger/swaggerRegistry.d.ts +79 -0
  62. package/dist/swagger/swaggerRegistry.d.ts.map +1 -0
  63. package/dist/swagger/swaggerRegistry.js +115 -0
  64. package/dist/swagger/swaggerRegistry.js.map +1 -0
  65. package/dist/swagger/swaggerSpec.d.ts +69 -0
  66. package/dist/swagger/swaggerSpec.d.ts.map +1 -0
  67. package/dist/swagger/swaggerSpec.js +174 -0
  68. package/dist/swagger/swaggerSpec.js.map +1 -0
  69. package/dist/utils/ACL.d.ts +19 -0
  70. package/dist/utils/ACL.d.ts.map +1 -0
  71. package/dist/utils/ACL.js +35 -0
  72. package/dist/utils/ACL.js.map +1 -0
  73. package/dist/utils/constants.d.ts +13 -0
  74. package/dist/utils/constants.d.ts.map +1 -0
  75. package/dist/utils/constants.js +19 -0
  76. package/dist/utils/constants.js.map +1 -0
  77. package/dist/utils/dynamicImport.d.ts +2 -0
  78. package/dist/utils/dynamicImport.d.ts.map +1 -0
  79. package/dist/utils/dynamicImport.js +21 -0
  80. package/dist/utils/dynamicImport.js.map +1 -0
  81. package/dist/utils/helper.d.ts +15 -0
  82. package/dist/utils/helper.d.ts.map +1 -0
  83. package/dist/utils/helper.js +93 -0
  84. package/dist/utils/helper.js.map +1 -0
  85. package/package.json +21 -5
@@ -0,0 +1,7 @@
1
+ import { RouteConfig } from './types/cloudTypes';
2
+ type OnFunctionRegistered = (name: string, config: RouteConfig, target: any) => void;
3
+ export declare function onFunctionRegistered(hook: OnFunctionRegistered): void;
4
+ export declare function CloudFunction(config: RouteConfig): (target: any, propertyKey: string, descriptor?: PropertyDescriptor | undefined) => PropertyDescriptor;
5
+ export declare function ProtectedCloudFunction(config?: Partial<RouteConfig>): (target: any, propertyKey: string, descriptor?: PropertyDescriptor | undefined) => PropertyDescriptor;
6
+ export {};
7
+ //# sourceMappingURL=cloudDecorator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloudDecorator.d.ts","sourceRoot":"","sources":["../../src/decorators/cloudDecorator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,WAAW,EAAC,MAAM,oBAAoB,CAAC;AAKtE,KAAK,oBAAoB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,KAAK,IAAI,CAAC;AAErF,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,oBAAoB,QAE9D;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,WAAW,IAE7C,QAAQ,GAAG,EACX,aAAa,MAAM,EACnB,aAAa,kBAAkB,GAAG,SAAS,wBAkC9C;AAoCD,wBAAgB,sBAAsB,CAAC,MAAM,GAAE,OAAO,CAAC,WAAW,CAAM,YAxE5D,GAAG,eACE,MAAM,eACN,kBAAkB,GAAG,SAAS,wBA4E9C"}
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.onFunctionRegistered = onFunctionRegistered;
4
+ exports.CloudFunction = CloudFunction;
5
+ exports.ProtectedCloudFunction = ProtectedCloudFunction;
6
+ const helper_1 = require("../utils/helper");
7
+ const cloudRegistry_1 = require("./cloudRegistry");
8
+ const functionHooks = [];
9
+ function onFunctionRegistered(hook) {
10
+ functionHooks.push(hook);
11
+ }
12
+ function CloudFunction(config) {
13
+ return function (target, propertyKey, descriptor) {
14
+ if (!descriptor) {
15
+ descriptor = Object.getOwnPropertyDescriptor(target, propertyKey);
16
+ }
17
+ if (!descriptor) {
18
+ throw new Error(`Descriptor not found for property ${propertyKey}`);
19
+ }
20
+ const originalMethod = descriptor.value;
21
+ // Wrap with role checking
22
+ descriptor.value = async function (...args) {
23
+ const request = args[0];
24
+ if (config.requireRoles) {
25
+ await checkUserRoles(request, config);
26
+ }
27
+ return originalMethod.apply(this, args);
28
+ };
29
+ const metadata = {
30
+ name: propertyKey,
31
+ config,
32
+ handler: descriptor.value,
33
+ };
34
+ cloudRegistry_1.CloudFunctionRegistry.register(metadata);
35
+ // Notify hooks (Swagger, etc.)
36
+ for (const hook of functionHooks) {
37
+ hook(propertyKey, config, target);
38
+ }
39
+ return descriptor;
40
+ };
41
+ }
42
+ async function checkUserRoles(request, config) {
43
+ const user = request.user;
44
+ if (!user) {
45
+ throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Authentication required');
46
+ }
47
+ if (!config.requireRoles || config.requireRoles.length === 0)
48
+ return;
49
+ const roleQuery = new Parse.Query('_Role');
50
+ roleQuery.containedIn('name', config.requireRoles);
51
+ roleQuery.equalTo('users', user);
52
+ const [error, userRoles] = await (0, helper_1.catchError)(roleQuery.find({ useMasterKey: true }));
53
+ if (error) {
54
+ throw new Parse.Error(Parse.Error.OTHER_CAUSE, 'Authorization check failed');
55
+ }
56
+ let hasPermission = false;
57
+ if (config.requireAllRoles) {
58
+ const userRoleNames = userRoles.map(role => role.get('name'));
59
+ hasPermission = config.requireRoles.every(role => userRoleNames.includes(role));
60
+ }
61
+ else {
62
+ hasPermission = userRoles.length > 0;
63
+ }
64
+ if (!hasPermission) {
65
+ const msg = config.customErrorMessage ||
66
+ `Access denied. Required ${config.requireAllRoles ? 'all' : 'one of'} these roles: ${config.requireRoles.join(', ')}`;
67
+ throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, msg);
68
+ }
69
+ }
70
+ function ProtectedCloudFunction(config = {}) {
71
+ return CloudFunction({
72
+ methods: ['POST'],
73
+ validation: { requireUser: true },
74
+ ...config,
75
+ });
76
+ }
77
+ //# sourceMappingURL=cloudDecorator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloudDecorator.js","sourceRoot":"","sources":["../../src/decorators/cloudDecorator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { CloudFunctionMetadata } from './types/cloudTypes';
2
+ export declare class CloudFunctionRegistry {
3
+ private static functions;
4
+ static register(metadata: CloudFunctionMetadata): void;
5
+ static getFunctions(): CloudFunctionMetadata[];
6
+ static getFunction(name: string): CloudFunctionMetadata | undefined;
7
+ static initialize(): void;
8
+ }
9
+ //# sourceMappingURL=cloudRegistry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloudRegistry.d.ts","sourceRoot":"","sources":["../../src/decorators/cloudRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,qBAAqB,EAAC,MAAM,oBAAoB,CAAC;AAGzD,qBAAa,qBAAqB;IAChC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAiD;IAEzE,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,qBAAqB;IAI/C,MAAM,CAAC,YAAY;IAInB,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM;IAI/B,MAAM,CAAC,UAAU;CASlB"}
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CloudFunctionRegistry = void 0;
4
+ const routeDecorator_1 = require("./routeDecorator");
5
+ class CloudFunctionRegistry {
6
+ static register(metadata) {
7
+ this.functions.set(metadata.name, metadata);
8
+ }
9
+ static getFunctions() {
10
+ return Array.from(this.functions.values());
11
+ }
12
+ static getFunction(name) {
13
+ return this.functions.get(name);
14
+ }
15
+ static initialize() {
16
+ this.functions.forEach(metadata => {
17
+ Parse.Cloud.define(metadata.name, metadata.handler, metadata.config.validation);
18
+ console.log(`Registered cloud function: ${metadata.name}`);
19
+ });
20
+ // Build entity-based route map after all functions are registered
21
+ routeDecorator_1.RouteRegistry.initialize();
22
+ }
23
+ }
24
+ exports.CloudFunctionRegistry = CloudFunctionRegistry;
25
+ CloudFunctionRegistry.functions = new Map();
26
+ //# sourceMappingURL=cloudRegistry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloudRegistry.js","sourceRoot":"","sources":["../../src/decorators/cloudRegistry.ts"],"names":[],"mappings":";;;AACA,qDAA+C;AAE/C,MAAa,qBAAqB;IAGhC,MAAM,CAAC,QAAQ,CAAC,QAA+B;QAC7C,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAC9C,CAAC;IAED,MAAM,CAAC,YAAY;QACjB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7C,CAAC;IAED,MAAM,CAAC,WAAW,CAAC,IAAY;QAC7B,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC;IAED,MAAM,CAAC,UAAU;QACf,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;YAChC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YAChF,OAAO,CAAC,GAAG,CAAC,8BAA8B,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;QAC7D,CAAC,CAAC,CAAC;QAEH,kEAAkE;QAClE,8BAAa,CAAC,UAAU,EAAE,CAAC;IAC7B,CAAC;;AAvBH,sDAwBC;AAvBgB,+BAAS,GAAuC,IAAI,GAAG,EAAE,CAAC"}
@@ -0,0 +1,6 @@
1
+ import 'reflect-metadata';
2
+ import { CronConfig } from './types/cronTypes';
3
+ export declare function Cron(config: CronConfig): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
4
+ export { CronSchedule } from './types/cronTypes';
5
+ export { CronRegistry } from './cronRegistry';
6
+ //# sourceMappingURL=cronDecorator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cronDecorator.d.ts","sourceRoot":"","sources":["../../src/decorators/cronDecorator.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAC1B,OAAO,EAAC,UAAU,EAAC,MAAM,mBAAmB,CAAC;AAG7C,wBAAgB,IAAI,CAAC,MAAM,EAAE,UAAU,IACpB,QAAQ,GAAG,EAAE,aAAa,MAAM,EAAE,YAAY,kBAAkB,wBAiBlF;AAED,OAAO,EAAC,YAAY,EAAC,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CronRegistry = exports.CronSchedule = void 0;
4
+ exports.Cron = Cron;
5
+ require("reflect-metadata");
6
+ const cronRegistry_1 = require("./cronRegistry");
7
+ function Cron(config) {
8
+ return function (target, propertyKey, descriptor) {
9
+ const handler = descriptor.value;
10
+ if (typeof handler !== 'function') {
11
+ throw new Error(`@Cron decorator can only be applied to methods.`);
12
+ }
13
+ cronRegistry_1.CronRegistry.register({
14
+ name: propertyKey,
15
+ schedule: config.schedule,
16
+ handler: handler,
17
+ description: config.description,
18
+ enabled: config.enabled ?? true,
19
+ timezone: config.timezone ?? 'UTC',
20
+ });
21
+ return descriptor;
22
+ };
23
+ }
24
+ var cronTypes_1 = require("./types/cronTypes");
25
+ Object.defineProperty(exports, "CronSchedule", { enumerable: true, get: function () { return cronTypes_1.CronSchedule; } });
26
+ var cronRegistry_2 = require("./cronRegistry");
27
+ Object.defineProperty(exports, "CronRegistry", { enumerable: true, get: function () { return cronRegistry_2.CronRegistry; } });
28
+ //# sourceMappingURL=cronDecorator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cronDecorator.js","sourceRoot":"","sources":["../../src/decorators/cronDecorator.ts"],"names":[],"mappings":";;;AAIA,oBAkBC;AAtBD,4BAA0B;AAE1B,iDAA4C;AAE5C,SAAgB,IAAI,CAAC,MAAkB;IACrC,OAAO,UAAU,MAAW,EAAE,WAAmB,EAAE,UAA8B;QAC/E,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC;QACjC,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE,CAAC;YAClC,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;QACrE,CAAC;QAED,2BAAY,CAAC,QAAQ,CAAC;YACpB,IAAI,EAAE,WAAW;YACjB,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,OAAO,EAAE,OAAO;YAChB,WAAW,EAAE,MAAM,CAAC,WAAW;YAC/B,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,IAAI;YAC/B,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,KAAK;SACnC,CAAC,CAAC;QAEH,OAAO,UAAU,CAAC;IACpB,CAAC,CAAC;AACJ,CAAC;AAED,+CAA+C;AAAvC,yGAAA,YAAY,OAAA;AACpB,+CAA4C;AAApC,4GAAA,YAAY,OAAA"}
@@ -0,0 +1,13 @@
1
+ import { CronJobMetadata } from './types/cronTypes';
2
+ export declare class CronRegistry {
3
+ private static jobs;
4
+ static register(metadata: CronJobMetadata): void;
5
+ static getJobs(): CronJobMetadata[];
6
+ static getJob(name: string): CronJobMetadata | undefined;
7
+ static initialize(): void;
8
+ static stopJob(name: string): boolean;
9
+ static startJob(name: string): boolean;
10
+ static stopAll(): void;
11
+ static runNow(name: string): Promise<void>;
12
+ }
13
+ //# sourceMappingURL=cronRegistry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cronRegistry.d.ts","sourceRoot":"","sources":["../../src/decorators/cronRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAC;AAUlD,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAC,IAAI,CAAyC;IAE5D,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI;IAOhD,MAAM,CAAC,OAAO,IAAI,eAAe,EAAE;IAInC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAIxD,MAAM,CAAC,UAAU,IAAI,IAAI;IA2CzB,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAMrC,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAMtC,MAAM,CAAC,OAAO,IAAI,IAAI;WAKT,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAMjD"}
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CronRegistry = void 0;
4
+ let cron;
5
+ try {
6
+ cron = require('node-cron');
7
+ }
8
+ catch { /* optional dependency */ }
9
+ class CronRegistry {
10
+ static register(metadata) {
11
+ if (this.jobs.has(metadata.name)) {
12
+ console.warn(`[Cron] Warning: Overwriting existing job '${metadata.name}'`);
13
+ }
14
+ this.jobs.set(metadata.name, { metadata, task: null });
15
+ }
16
+ static getJobs() {
17
+ return Array.from(this.jobs.values()).map(j => j.metadata);
18
+ }
19
+ static getJob(name) {
20
+ return this.jobs.get(name)?.metadata;
21
+ }
22
+ static initialize() {
23
+ if (!cron) {
24
+ console.warn('[Cron] node-cron not installed — skipping cron job registration');
25
+ return;
26
+ }
27
+ const jobs = this.getJobs();
28
+ if (jobs.length === 0) {
29
+ console.log('[Cron] No cron jobs to register');
30
+ return;
31
+ }
32
+ console.log(`[Cron] Registering ${jobs.length} cron job(s)...`);
33
+ for (const metadata of jobs) {
34
+ const { name, schedule, handler, description, enabled = true, timezone = 'UTC' } = metadata;
35
+ if (!enabled) {
36
+ console.log(`[Cron] Skipping disabled job: ${name}`);
37
+ continue;
38
+ }
39
+ if (!cron.validate(schedule)) {
40
+ console.error(`[Cron] Invalid schedule for job '${name}': ${schedule}`);
41
+ continue;
42
+ }
43
+ const task = cron.schedule(schedule, async () => {
44
+ const startTime = Date.now();
45
+ console.log(`[Cron] Running job: ${name}`);
46
+ try {
47
+ await handler();
48
+ console.log(`[Cron] Job '${name}' completed in ${Date.now() - startTime}ms`);
49
+ }
50
+ catch (error) {
51
+ console.error(`[Cron] Job '${name}' failed:`, error.message);
52
+ }
53
+ }, { timezone });
54
+ task.start();
55
+ const jobEntry = this.jobs.get(name);
56
+ if (jobEntry)
57
+ jobEntry.task = task;
58
+ const desc = description ? ` - ${description}` : '';
59
+ console.log(`[Cron] Registered: ${name} (${schedule})${desc}`);
60
+ }
61
+ console.log('[Cron] All cron jobs registered');
62
+ }
63
+ static stopJob(name) {
64
+ const job = this.jobs.get(name);
65
+ if (job?.task) {
66
+ job.task.stop();
67
+ return true;
68
+ }
69
+ return false;
70
+ }
71
+ static startJob(name) {
72
+ const job = this.jobs.get(name);
73
+ if (job?.task) {
74
+ job.task.start();
75
+ return true;
76
+ }
77
+ return false;
78
+ }
79
+ static stopAll() {
80
+ for (const [, job] of this.jobs) {
81
+ if (job.task)
82
+ job.task.stop();
83
+ }
84
+ console.log('[Cron] All jobs stopped');
85
+ }
86
+ static async runNow(name) {
87
+ const job = this.jobs.get(name);
88
+ if (!job)
89
+ throw new Error(`Job '${name}' not found`);
90
+ console.log(`[Cron] Manually running job: ${name}`);
91
+ await job.metadata.handler();
92
+ }
93
+ }
94
+ exports.CronRegistry = CronRegistry;
95
+ CronRegistry.jobs = new Map();
96
+ //# sourceMappingURL=cronRegistry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cronRegistry.js","sourceRoot":"","sources":["../../src/decorators/cronRegistry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import 'reflect-metadata';
2
+ /**
3
+ * @Route class decorator.
4
+ * Accepts a Parse model class (reads className) or a custom string.
5
+ */
6
+ export declare function Route(target: Function | string): (constructor: Function) => void;
7
+ /**
8
+ * Global route registry — maps route prefixes to function names.
9
+ * Built during decorator phase, consumed during server init.
10
+ */
11
+ export declare class RouteRegistry {
12
+ private static prefixes;
13
+ private static routeMap;
14
+ private static registeredPrefixes;
15
+ static register(className: string, prefix: string): void;
16
+ /**
17
+ * Called after CloudFunctionRegistry.initialize().
18
+ * Builds the route map by matching function names to route prefixes.
19
+ */
20
+ static initialize(): void;
21
+ /**
22
+ * Look up a cloud function name by route path.
23
+ * '/students/create' → 'createStudent'
24
+ */
25
+ static resolve(routePath: string): string | undefined;
26
+ /**
27
+ * Check if a path starts with a registered route prefix.
28
+ */
29
+ static isRegisteredPrefix(path: string): boolean;
30
+ /**
31
+ * Get all registered prefixes (for restrictRoutes middleware).
32
+ */
33
+ static getPrefixes(): string[];
34
+ }
35
+ //# sourceMappingURL=routeDecorator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routeDecorator.d.ts","sourceRoot":"","sources":["../../src/decorators/routeDecorator.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAyE1B;;;GAGG;AACH,wBAAgB,KAAK,CAAC,MAAM,EAAE,QAAQ,GAAG,MAAM,IAC5B,aAAa,QAAQ,UAiBvC;AAED;;;GAGG;AACH,qBAAa,aAAa;IAExB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAkC;IAEzD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAkC;IAEzD,OAAO,CAAC,MAAM,CAAC,kBAAkB,CAA0B;IAE3D,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAIjD;;;OAGG;IACH,MAAM,CAAC,UAAU;IA6BjB;;;OAGG;IACH,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAIrD;;OAEG;IACH,MAAM,CAAC,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAOhD;;OAEG;IACH,MAAM,CAAC,WAAW,IAAI,MAAM,EAAE;CAG/B"}
@@ -0,0 +1,160 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RouteRegistry = void 0;
4
+ exports.Route = Route;
5
+ require("reflect-metadata");
6
+ const cloudRegistry_1 = require("./cloudRegistry");
7
+ /**
8
+ * @Route decorator — maps cloud functions to entity-based routes.
9
+ *
10
+ * Usage:
11
+ * @Route(Student) // reads className → 'Student' → /api/students/*
12
+ * @Route('school-students') // custom string → /api/school-students/*
13
+ *
14
+ * The decorator reads the class name (from @ParseClass metadata or string),
15
+ * converts it to a kebab-plural prefix, and tags all cloud functions in
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
21
+ */
22
+ /**
23
+ * Convert PascalCase to kebab-case plural.
24
+ * 'Student' → 'students'
25
+ * 'MenuItem' → 'menu-items'
26
+ * 'MeetingMinute' → 'meeting-minutes'
27
+ */
28
+ function toKebabPlural(name) {
29
+ const kebab = name
30
+ .replace(/([a-z0-9])([A-Z])/g, '$1-$2')
31
+ .toLowerCase();
32
+ // Simple pluralize: add 's' (covers most cases)
33
+ // Words ending in 'y' → 'ies', 's'/'sh'/'ch'/'x' → 'es'
34
+ if (kebab.endsWith('y') && !kebab.endsWith('ay') && !kebab.endsWith('ey') && !kebab.endsWith('oy')) {
35
+ return kebab.slice(0, -1) + 'ies';
36
+ }
37
+ if (kebab.endsWith('s') || kebab.endsWith('sh') || kebab.endsWith('ch') || kebab.endsWith('x')) {
38
+ return kebab + 'es';
39
+ }
40
+ return kebab + 's';
41
+ }
42
+ /**
43
+ * Extract action name from a cloud function name.
44
+ * 'createStudent' → 'create'
45
+ * 'listStudents' → 'list'
46
+ * 'getStudent' → 'get'
47
+ * 'updateStudent' → 'update'
48
+ * 'deleteStudent' → 'delete'
49
+ * 'searchStudents' → 'search'
50
+ * 'customAction' → 'customAction' (fallback: use full name)
51
+ */
52
+ function extractAction(functionName, className) {
53
+ const classLower = className.toLowerCase();
54
+ const fnLower = functionName.toLowerCase();
55
+ // Standard CRUD prefixes
56
+ const prefixes = ['create', 'get', 'list', 'update', 'delete', 'search'];
57
+ for (const prefix of prefixes) {
58
+ if (fnLower.startsWith(prefix) && fnLower.includes(classLower)) {
59
+ return prefix;
60
+ }
61
+ }
62
+ // Pluralized form (e.g., 'listStudents' where className is 'Student')
63
+ for (const prefix of prefixes) {
64
+ if (fnLower.startsWith(prefix)) {
65
+ return prefix;
66
+ }
67
+ }
68
+ // Fallback: return the full function name as the action
69
+ return functionName;
70
+ }
71
+ /**
72
+ * @Route class decorator.
73
+ * Accepts a Parse model class (reads className) or a custom string.
74
+ */
75
+ function Route(target) {
76
+ return function (constructor) {
77
+ let prefix;
78
+ let className;
79
+ if (typeof target === 'string') {
80
+ prefix = target;
81
+ className = target;
82
+ }
83
+ else {
84
+ // Read className from @ParseClass metadata
85
+ className = Reflect.getMetadata('parse:className', target) || target.name;
86
+ prefix = toKebabPlural(className);
87
+ }
88
+ // Tag all functions registered by this class with the route prefix
89
+ // We use a post-init hook: store the mapping, apply after CloudFunctionRegistry.initialize()
90
+ RouteRegistry.register(className, prefix);
91
+ };
92
+ }
93
+ /**
94
+ * Global route registry — maps route prefixes to function names.
95
+ * Built during decorator phase, consumed during server init.
96
+ */
97
+ class RouteRegistry {
98
+ static register(className, prefix) {
99
+ this.prefixes.set(className.toLowerCase(), prefix);
100
+ }
101
+ /**
102
+ * Called after CloudFunctionRegistry.initialize().
103
+ * Builds the route map by matching function names to route prefixes.
104
+ */
105
+ static initialize() {
106
+ const functions = cloudRegistry_1.CloudFunctionRegistry.getFunctions();
107
+ for (const fn of functions) {
108
+ // Find which prefix this function belongs to
109
+ let matchedPrefix = null;
110
+ let matchedClassName = null;
111
+ for (const [className, prefix] of this.prefixes) {
112
+ if (fn.name.toLowerCase().includes(className)) {
113
+ matchedPrefix = prefix;
114
+ matchedClassName = className;
115
+ break;
116
+ }
117
+ }
118
+ if (matchedPrefix && matchedClassName) {
119
+ const action = extractAction(fn.name, matchedClassName);
120
+ const routePath = `/${matchedPrefix}/${action}`;
121
+ this.routeMap.set(routePath, fn.name);
122
+ this.registeredPrefixes.add(`/${matchedPrefix}`);
123
+ fn.routePrefix = matchedPrefix;
124
+ console.log(` Route: ${routePath} → ${fn.name}`);
125
+ }
126
+ }
127
+ console.log(`Route registry: ${this.routeMap.size} routes registered`);
128
+ }
129
+ /**
130
+ * Look up a cloud function name by route path.
131
+ * '/students/create' → 'createStudent'
132
+ */
133
+ static resolve(routePath) {
134
+ return this.routeMap.get(routePath);
135
+ }
136
+ /**
137
+ * Check if a path starts with a registered route prefix.
138
+ */
139
+ static isRegisteredPrefix(path) {
140
+ for (const prefix of this.registeredPrefixes) {
141
+ if (path.startsWith(prefix))
142
+ return true;
143
+ }
144
+ return false;
145
+ }
146
+ /**
147
+ * Get all registered prefixes (for restrictRoutes middleware).
148
+ */
149
+ static getPrefixes() {
150
+ return Array.from(this.registeredPrefixes);
151
+ }
152
+ }
153
+ exports.RouteRegistry = RouteRegistry;
154
+ // className → route prefix
155
+ RouteRegistry.prefixes = new Map();
156
+ // route path → function name (built during initialize)
157
+ RouteRegistry.routeMap = new Map();
158
+ // all registered route prefixes (for middleware)
159
+ RouteRegistry.registeredPrefixes = new Set();
160
+ //# sourceMappingURL=routeDecorator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routeDecorator.js","sourceRoot":"","sources":["../../src/decorators/routeDecorator.ts"],"names":[],"mappings":";;;AA6EA,sBAkBC;AA/FD,4BAA0B;AAC1B,mDAAsD;AAEtD;;;;;;;;;;;;;;GAcG;AAEH;;;;;GAKG;AACH,SAAS,aAAa,CAAC,IAAY;IACjC,MAAM,KAAK,GAAG,IAAI;SACf,OAAO,CAAC,oBAAoB,EAAE,OAAO,CAAC;SACtC,WAAW,EAAE,CAAC;IACjB,gDAAgD;IAChD,wDAAwD;IACxD,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACnG,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;IACpC,CAAC;IACD,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/F,OAAO,KAAK,GAAG,IAAI,CAAC;IACtB,CAAC;IACD,OAAO,KAAK,GAAG,GAAG,CAAC;AACrB,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,aAAa,CAAC,YAAoB,EAAE,SAAiB;IAC5D,MAAM,UAAU,GAAG,SAAS,CAAC,WAAW,EAAE,CAAC;IAC3C,MAAM,OAAO,GAAG,YAAY,CAAC,WAAW,EAAE,CAAC;IAE3C,yBAAyB;IACzB,MAAM,QAAQ,GAAG,CAAC,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACzE,KAAK,MAAM,MAAM,IAAI,QAAQ,EAAE,CAAC;QAC9B,IAAI,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YAC/D,OAAO,MAAM,CAAC;QAChB,CAAC;IACH,CAAC;IAED,sEAAsE;IACtE,KAAK,MAAM,MAAM,IAAI,QAAQ,EAAE,CAAC;QAC9B,IAAI,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YAC/B,OAAO,MAAM,CAAC;QAChB,CAAC;IACH,CAAC;IAED,wDAAwD;IACxD,OAAO,YAAY,CAAC;AACtB,CAAC;AAED;;;GAGG;AACH,SAAgB,KAAK,CAAC,MAAyB;IAC7C,OAAO,UAAU,WAAqB;QACpC,IAAI,MAAc,CAAC;QACnB,IAAI,SAAiB,CAAC;QAEtB,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC/B,MAAM,GAAG,MAAM,CAAC;YAChB,SAAS,GAAG,MAAM,CAAC;QACrB,CAAC;aAAM,CAAC;YACN,2CAA2C;YAC3C,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,iBAAiB,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC;YAC1E,MAAM,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC;QACpC,CAAC;QAED,mEAAmE;QACnE,6FAA6F;QAC7F,aAAa,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAC5C,CAAC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAa,aAAa;IAQxB,MAAM,CAAC,QAAQ,CAAC,SAAiB,EAAE,MAAc;QAC/C,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,WAAW,EAAE,EAAE,MAAM,CAAC,CAAC;IACrD,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,UAAU;QACf,MAAM,SAAS,GAAG,qCAAqB,CAAC,YAAY,EAAE,CAAC;QAEvD,KAAK,MAAM,EAAE,IAAI,SAAS,EAAE,CAAC;YAC3B,6CAA6C;YAC7C,IAAI,aAAa,GAAkB,IAAI,CAAC;YACxC,IAAI,gBAAgB,GAAkB,IAAI,CAAC;YAE3C,KAAK,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAChD,IAAI,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;oBAC9C,aAAa,GAAG,MAAM,CAAC;oBACvB,gBAAgB,GAAG,SAAS,CAAC;oBAC7B,MAAM;gBACR,CAAC;YACH,CAAC;YAED,IAAI,aAAa,IAAI,gBAAgB,EAAE,CAAC;gBACtC,MAAM,MAAM,GAAG,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;gBACxD,MAAM,SAAS,GAAG,IAAI,aAAa,IAAI,MAAM,EAAE,CAAC;gBAChD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;gBACtC,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,IAAI,aAAa,EAAE,CAAC,CAAC;gBACjD,EAAE,CAAC,WAAW,GAAG,aAAa,CAAC;gBAC/B,OAAO,CAAC,GAAG,CAAC,YAAY,SAAS,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;YACpD,CAAC;QACH,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,CAAC,QAAQ,CAAC,IAAI,oBAAoB,CAAC,CAAC;IACzE,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,OAAO,CAAC,SAAiB;QAC9B,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACtC,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,kBAAkB,CAAC,IAAY;QACpC,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC7C,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;gBAAE,OAAO,IAAI,CAAC;QAC3C,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,WAAW;QAChB,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAC7C,CAAC;;AApEH,sCAqEC;AApEC,2BAA2B;AACZ,sBAAQ,GAAwB,IAAI,GAAG,EAAE,CAAC;AACzD,uDAAuD;AACxC,sBAAQ,GAAwB,IAAI,GAAG,EAAE,CAAC;AACzD,iDAAiD;AAClC,gCAAkB,GAAgB,IAAI,GAAG,EAAE,CAAC"}
@@ -0,0 +1,19 @@
1
+ import 'reflect-metadata';
2
+ import { TriggerConfig } from './types/triggerTypes';
3
+ export declare const BeforeSave: (config?: TriggerConfig) => (target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
4
+ export declare const AfterSave: (config?: TriggerConfig) => (target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
5
+ export declare const BeforeDelete: (config?: TriggerConfig) => (target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
6
+ export declare const AfterDelete: (config?: TriggerConfig) => (target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
7
+ export declare const BeforeFind: (config?: TriggerConfig) => (target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
8
+ export declare const AfterFind: (config?: TriggerConfig) => (target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
9
+ export declare const BeforeLogin: (config?: TriggerConfig) => (target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
10
+ export declare const AfterLogin: (config?: TriggerConfig) => (target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
11
+ export declare const AfterLogout: (config?: TriggerConfig) => (target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
12
+ export declare const BeforeSaveFile: (config?: TriggerConfig) => (target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
13
+ export declare const AfterSaveFile: (config?: TriggerConfig) => (target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
14
+ export declare const BeforeDeleteFile: (config?: TriggerConfig) => (target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
15
+ export declare const AfterDeleteFile: (config?: TriggerConfig) => (target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
16
+ export declare const BeforeConnect: (config?: TriggerConfig) => (target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
17
+ export declare const BeforeSubscribe: (config?: TriggerConfig) => (target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
18
+ export declare const AfterEvent: (config?: TriggerConfig) => (target: any, propertyKey: string, descriptor: PropertyDescriptor) => PropertyDescriptor;
19
+ //# sourceMappingURL=triggerDecorator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"triggerDecorator.d.ts","sourceRoot":"","sources":["../../src/decorators/triggerDecorator.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAC1B,OAAO,EAAC,aAAa,EAAc,MAAM,sBAAsB,CAAC;AA0BhE,eAAO,MAAM,UAAU,YAvBI,aAAa,MACnB,QAAQ,GAAG,EAAE,aAAa,MAAM,EAAE,YAAY,kBAAkB,uBAsBvB,CAAC;AAC/D,eAAO,MAAM,SAAS,YAxBK,aAAa,MACnB,QAAQ,GAAG,EAAE,aAAa,MAAM,EAAE,YAAY,kBAAkB,uBAuBzB,CAAC;AAC7D,eAAO,MAAM,YAAY,YAzBE,aAAa,MACnB,QAAQ,GAAG,EAAE,aAAa,MAAM,EAAE,YAAY,kBAAkB,uBAwBnB,CAAC;AACnE,eAAO,MAAM,WAAW,YA1BG,aAAa,MACnB,QAAQ,GAAG,EAAE,aAAa,MAAM,EAAE,YAAY,kBAAkB,uBAyBrB,CAAC;AACjE,eAAO,MAAM,UAAU,YA3BI,aAAa,MACnB,QAAQ,GAAG,EAAE,aAAa,MAAM,EAAE,YAAY,kBAAkB,uBA0BvB,CAAC;AAC/D,eAAO,MAAM,SAAS,YA5BK,aAAa,MACnB,QAAQ,GAAG,EAAE,aAAa,MAAM,EAAE,YAAY,kBAAkB,uBA2BzB,CAAC;AAG7D,eAAO,MAAM,WAAW,YA/BG,aAAa,MACnB,QAAQ,GAAG,EAAE,aAAa,MAAM,EAAE,YAAY,kBAAkB,uBA8BrB,CAAC;AACjE,eAAO,MAAM,UAAU,YAhCI,aAAa,MACnB,QAAQ,GAAG,EAAE,aAAa,MAAM,EAAE,YAAY,kBAAkB,uBA+BvB,CAAC;AAC/D,eAAO,MAAM,WAAW,YAjCG,aAAa,MACnB,QAAQ,GAAG,EAAE,aAAa,MAAM,EAAE,YAAY,kBAAkB,uBAgCrB,CAAC;AAGjE,eAAO,MAAM,cAAc,YApCA,aAAa,MACnB,QAAQ,GAAG,EAAE,aAAa,MAAM,EAAE,YAAY,kBAAkB,uBAmCf,CAAC;AACvE,eAAO,MAAM,aAAa,YArCC,aAAa,MACnB,QAAQ,GAAG,EAAE,aAAa,MAAM,EAAE,YAAY,kBAAkB,uBAoCjB,CAAC;AACrE,eAAO,MAAM,gBAAgB,YAtCF,aAAa,MACnB,QAAQ,GAAG,EAAE,aAAa,MAAM,EAAE,YAAY,kBAAkB,uBAqCX,CAAC;AAC3E,eAAO,MAAM,eAAe,YAvCD,aAAa,MACnB,QAAQ,GAAG,EAAE,aAAa,MAAM,EAAE,YAAY,kBAAkB,uBAsCb,CAAC;AAGzE,eAAO,MAAM,aAAa,YA1CC,aAAa,MACnB,QAAQ,GAAG,EAAE,aAAa,MAAM,EAAE,YAAY,kBAAkB,uBAyCjB,CAAC;AACrE,eAAO,MAAM,eAAe,YA3CD,aAAa,MACnB,QAAQ,GAAG,EAAE,aAAa,MAAM,EAAE,YAAY,kBAAkB,uBA0Cb,CAAC;AACzE,eAAO,MAAM,UAAU,YA5CI,aAAa,MACnB,QAAQ,GAAG,EAAE,aAAa,MAAM,EAAE,YAAY,kBAAkB,uBA2CvB,CAAC"}
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ 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 = void 0;
4
+ require("reflect-metadata");
5
+ function createTriggerDecorator(type) {
6
+ return function (config = {}) {
7
+ return function (target, propertyKey, descriptor) {
8
+ const handler = descriptor.value;
9
+ if (typeof handler !== 'function') {
10
+ throw new Error(`@${type} decorator can only be applied to methods.`);
11
+ }
12
+ const constructor = typeof target === 'function' ? target : target.constructor;
13
+ const pendingTriggers = Reflect.getMetadata('parse:pendingTriggers', constructor) || [];
14
+ pendingTriggers.push({
15
+ type,
16
+ handler,
17
+ description: config.description,
18
+ validation: config.validation,
19
+ });
20
+ Reflect.defineMetadata('parse:pendingTriggers', pendingTriggers, constructor);
21
+ return descriptor;
22
+ };
23
+ };
24
+ }
25
+ // Object triggers
26
+ exports.BeforeSave = createTriggerDecorator('beforeSave');
27
+ exports.AfterSave = createTriggerDecorator('afterSave');
28
+ exports.BeforeDelete = createTriggerDecorator('beforeDelete');
29
+ exports.AfterDelete = createTriggerDecorator('afterDelete');
30
+ exports.BeforeFind = createTriggerDecorator('beforeFind');
31
+ exports.AfterFind = createTriggerDecorator('afterFind');
32
+ // User auth triggers
33
+ exports.BeforeLogin = createTriggerDecorator('beforeLogin');
34
+ exports.AfterLogin = createTriggerDecorator('afterLogin');
35
+ exports.AfterLogout = createTriggerDecorator('afterLogout');
36
+ // File triggers
37
+ exports.BeforeSaveFile = createTriggerDecorator('beforeSaveFile');
38
+ exports.AfterSaveFile = createTriggerDecorator('afterSaveFile');
39
+ exports.BeforeDeleteFile = createTriggerDecorator('beforeDeleteFile');
40
+ exports.AfterDeleteFile = createTriggerDecorator('afterDeleteFile');
41
+ // LiveQuery triggers
42
+ exports.BeforeConnect = createTriggerDecorator('beforeConnect');
43
+ exports.BeforeSubscribe = createTriggerDecorator('beforeSubscribe');
44
+ exports.AfterEvent = createTriggerDecorator('afterEvent');
45
+ //# sourceMappingURL=triggerDecorator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"triggerDecorator.js","sourceRoot":"","sources":["../../src/decorators/triggerDecorator.ts"],"names":[],"mappings":";;;AAAA,4BAA0B;AAG1B,SAAS,sBAAsB,CAAC,IAAiB;IAC/C,OAAO,UAAU,SAAwB,EAAE;QACzC,OAAO,UAAU,MAAW,EAAE,WAAmB,EAAE,UAA8B;YAC/E,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC;YACjC,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE,CAAC;gBAClC,MAAM,IAAI,KAAK,CAAC,IAAI,IAAI,4CAA4C,CAAC,CAAC;YACxE,CAAC;YAED,MAAM,WAAW,GAAG,OAAO,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC;YAC/E,MAAM,eAAe,GAAG,OAAO,CAAC,WAAW,CAAC,uBAAuB,EAAE,WAAW,CAAC,IAAI,EAAE,CAAC;YACxF,eAAe,CAAC,IAAI,CAAC;gBACnB,IAAI;gBACJ,OAAO;gBACP,WAAW,EAAE,MAAM,CAAC,WAAW;gBAC/B,UAAU,EAAE,MAAM,CAAC,UAAU;aAC9B,CAAC,CAAC;YACH,OAAO,CAAC,cAAc,CAAC,uBAAuB,EAAE,eAAe,EAAE,WAAW,CAAC,CAAC;YAE9E,OAAO,UAAU,CAAC;QACpB,CAAC,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC;AAED,kBAAkB;AACL,QAAA,UAAU,GAAG,sBAAsB,CAAC,YAAY,CAAC,CAAC;AAClD,QAAA,SAAS,GAAG,sBAAsB,CAAC,WAAW,CAAC,CAAC;AAChD,QAAA,YAAY,GAAG,sBAAsB,CAAC,cAAc,CAAC,CAAC;AACtD,QAAA,WAAW,GAAG,sBAAsB,CAAC,aAAa,CAAC,CAAC;AACpD,QAAA,UAAU,GAAG,sBAAsB,CAAC,YAAY,CAAC,CAAC;AAClD,QAAA,SAAS,GAAG,sBAAsB,CAAC,WAAW,CAAC,CAAC;AAE7D,qBAAqB;AACR,QAAA,WAAW,GAAG,sBAAsB,CAAC,aAAa,CAAC,CAAC;AACpD,QAAA,UAAU,GAAG,sBAAsB,CAAC,YAAY,CAAC,CAAC;AAClD,QAAA,WAAW,GAAG,sBAAsB,CAAC,aAAa,CAAC,CAAC;AAEjE,gBAAgB;AACH,QAAA,cAAc,GAAG,sBAAsB,CAAC,gBAAgB,CAAC,CAAC;AAC1D,QAAA,aAAa,GAAG,sBAAsB,CAAC,eAAe,CAAC,CAAC;AACxD,QAAA,gBAAgB,GAAG,sBAAsB,CAAC,kBAAkB,CAAC,CAAC;AAC9D,QAAA,eAAe,GAAG,sBAAsB,CAAC,iBAAiB,CAAC,CAAC;AAEzE,qBAAqB;AACR,QAAA,aAAa,GAAG,sBAAsB,CAAC,eAAe,CAAC,CAAC;AACxD,QAAA,eAAe,GAAG,sBAAsB,CAAC,iBAAiB,CAAC,CAAC;AAC5D,QAAA,UAAU,GAAG,sBAAsB,CAAC,YAAY,CAAC,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { TriggerMetadata } from './types/triggerTypes';
2
+ export declare class TriggerRegistry {
3
+ private static triggers;
4
+ private static getKey;
5
+ static register(metadata: TriggerMetadata): void;
6
+ static getTriggers(): TriggerMetadata[];
7
+ static getTriggersForClass(className: string): TriggerMetadata[];
8
+ static initialize(): void;
9
+ }
10
+ //# sourceMappingURL=triggerRegistry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"triggerRegistry.d.ts","sourceRoot":"","sources":["../../src/decorators/triggerRegistry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,eAAe,EAAc,MAAM,sBAAsB,CAAC;AAElE,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA2C;IAElE,OAAO,CAAC,MAAM,CAAC,MAAM;IAIrB,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI;IAQhD,MAAM,CAAC,WAAW,IAAI,eAAe,EAAE;IAIvC,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,eAAe,EAAE;IAIhE,MAAM,CAAC,UAAU,IAAI,IAAI;CAoC1B"}