mumz-strapi-plugin-coupon 2.0.0 → 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.
Files changed (45) hide show
  1. package/dist/admin/index.js +677 -0
  2. package/dist/admin/index.mjs +678 -0
  3. package/dist/server/index.js +1201 -0
  4. package/dist/server/index.mjs +1202 -0
  5. package/package.json +42 -18
  6. package/strapi-admin.js +3 -0
  7. package/strapi-server.js +3 -1
  8. package/dist/bootstrap.d.ts +0 -5
  9. package/dist/bootstrap.js +0 -6
  10. package/dist/config/index.d.ts +0 -5
  11. package/dist/config/index.js +0 -6
  12. package/dist/content-types/coupon/index.d.ts +0 -96
  13. package/dist/content-types/coupon/index.js +0 -9
  14. package/dist/content-types/coupon/schema.d.ts +0 -94
  15. package/dist/content-types/coupon/schema.js +0 -117
  16. package/dist/content-types/index.d.ts +0 -161
  17. package/dist/content-types/index.js +0 -11
  18. package/dist/content-types/redemption/index.d.ts +0 -64
  19. package/dist/content-types/redemption/index.js +0 -9
  20. package/dist/content-types/redemption/schema.d.ts +0 -62
  21. package/dist/content-types/redemption/schema.js +0 -74
  22. package/dist/controllers/coupon.d.ts +0 -41
  23. package/dist/controllers/coupon.js +0 -154
  24. package/dist/controllers/index.d.ts +0 -5
  25. package/dist/controllers/index.js +0 -9
  26. package/dist/destroy.d.ts +0 -5
  27. package/dist/destroy.js +0 -6
  28. package/dist/index.d.ts +0 -207
  29. package/dist/index.js +0 -24
  30. package/dist/middlewares/index.d.ts +0 -4
  31. package/dist/middlewares/index.js +0 -9
  32. package/dist/middlewares/rate-limit.d.ts +0 -6
  33. package/dist/middlewares/rate-limit.js +0 -42
  34. package/dist/register.d.ts +0 -5
  35. package/dist/register.js +0 -6
  36. package/dist/routes/content-api/index.d.ts +0 -23
  37. package/dist/routes/content-api/index.js +0 -76
  38. package/dist/routes/index.d.ts +0 -25
  39. package/dist/routes/index.js +0 -9
  40. package/dist/services/coupon.d.ts +0 -64
  41. package/dist/services/coupon.js +0 -432
  42. package/dist/services/index.d.ts +0 -5
  43. package/dist/services/index.js +0 -9
  44. package/dist/utils/validators.d.ts +0 -14
  45. package/dist/utils/validators.js +0 -41
@@ -1,9 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const schema_1 = __importDefault(require("./schema"));
7
- exports.default = {
8
- schema: schema_1.default,
9
- };
@@ -1,62 +0,0 @@
1
- declare const _default: {
2
- kind: string;
3
- collectionName: string;
4
- info: {
5
- singularName: string;
6
- pluralName: string;
7
- displayName: string;
8
- description: string;
9
- };
10
- options: {
11
- draftAndPublish: boolean;
12
- };
13
- pluginOptions: {
14
- 'content-manager': {
15
- visible: boolean;
16
- };
17
- 'content-type-builder': {
18
- visible: boolean;
19
- };
20
- };
21
- layouts: {
22
- list: string[];
23
- edit: {
24
- name: string;
25
- size: number;
26
- }[][];
27
- };
28
- attributes: {
29
- coupon: {
30
- type: string;
31
- relation: string;
32
- target: string;
33
- inversedBy: string;
34
- };
35
- orderId: {
36
- type: string;
37
- required: boolean;
38
- };
39
- phoneNumber: {
40
- type: string;
41
- required: boolean;
42
- };
43
- redemptionDate: {
44
- type: string;
45
- required: boolean;
46
- };
47
- discountType: {
48
- type: string;
49
- required: boolean;
50
- };
51
- discountValue: {
52
- type: string;
53
- required: boolean;
54
- };
55
- metadata: {
56
- type: string;
57
- required: boolean;
58
- default: null;
59
- };
60
- };
61
- };
62
- export default _default;
@@ -1,74 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.default = {
4
- kind: 'collectionType',
5
- collectionName: 'coupon_redemptions',
6
- info: {
7
- singularName: 'redemption',
8
- pluralName: 'redemptions',
9
- displayName: 'Coupon Redemption',
10
- description: 'Tracks coupon redemptions for audit trail',
11
- },
12
- options: {
13
- draftAndPublish: false,
14
- },
15
- pluginOptions: {
16
- 'content-manager': {
17
- visible: true,
18
- },
19
- 'content-type-builder': {
20
- visible: true,
21
- },
22
- },
23
- layouts: {
24
- list: ['orderId', 'phoneNumber', 'redemptionDate', 'coupon'],
25
- edit: [
26
- [
27
- { name: 'orderId', size: 6 },
28
- { name: 'phoneNumber', size: 6 },
29
- ],
30
- [
31
- { name: 'redemptionDate', size: 6 },
32
- { name: 'coupon', size: 6 },
33
- ],
34
- [
35
- { name: 'discountType', size: 6 },
36
- { name: 'discountValue', size: 6 },
37
- ],
38
- [{ name: 'metadata', size: 12 }],
39
- ],
40
- },
41
- attributes: {
42
- coupon: {
43
- type: 'relation',
44
- relation: 'manyToOne',
45
- target: 'plugin::coupon.coupon',
46
- inversedBy: 'redemptions',
47
- },
48
- orderId: {
49
- type: 'string',
50
- required: true,
51
- },
52
- phoneNumber: {
53
- type: 'string',
54
- required: true,
55
- },
56
- redemptionDate: {
57
- type: 'datetime',
58
- required: true,
59
- },
60
- discountType: {
61
- type: 'string',
62
- required: true,
63
- },
64
- discountValue: {
65
- type: 'decimal',
66
- required: true,
67
- },
68
- metadata: {
69
- type: 'json',
70
- required: false,
71
- default: null,
72
- },
73
- },
74
- };
@@ -1,41 +0,0 @@
1
- import type { Core } from '@strapi/strapi';
2
- declare const _default: ({ strapi }: {
3
- strapi: Core.Strapi;
4
- }) => {
5
- /**
6
- * Validate coupon endpoint
7
- * POST /api/coupons/validate
8
- */
9
- validate(ctx: any): Promise<any>;
10
- /**
11
- * Redeem coupon endpoint
12
- * POST /api/coupons/redeem
13
- */
14
- redeem(ctx: any): Promise<any>;
15
- /**
16
- * Create coupon endpoint (Admin only)
17
- * POST /api/coupons
18
- */
19
- create(ctx: any): Promise<any>;
20
- /**
21
- * Find all coupons
22
- * GET /api/coupons
23
- */
24
- find(ctx: any): Promise<void>;
25
- /**
26
- * Find one coupon
27
- * GET /api/coupons/:id
28
- */
29
- findOne(ctx: any): Promise<any>;
30
- /**
31
- * Update coupon
32
- * PUT /api/coupons/:id
33
- */
34
- update(ctx: any): Promise<void>;
35
- /**
36
- * Delete coupon
37
- * DELETE /api/coupons/:id
38
- */
39
- delete(ctx: any): Promise<void>;
40
- };
41
- export default _default;
@@ -1,154 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.default = ({ strapi }) => ({
4
- /**
5
- * Validate coupon endpoint
6
- * POST /api/coupons/validate
7
- */
8
- async validate(ctx) {
9
- try {
10
- const { couponCode, phoneNumber, orderAmount } = ctx.request.body;
11
- // Validate required fields
12
- if (!couponCode || !phoneNumber) {
13
- return ctx.badRequest('Missing required fields: couponCode, phoneNumber');
14
- }
15
- const result = await strapi
16
- .plugin('coupon')
17
- .service('coupon')
18
- .validate({
19
- couponCode,
20
- phoneNumber,
21
- orderAmount,
22
- });
23
- ctx.body = result;
24
- }
25
- catch (error) {
26
- strapi.log.error('Controller error in validate:', error);
27
- ctx.internalServerError('An error occurred while validating the coupon');
28
- }
29
- },
30
- /**
31
- * Redeem coupon endpoint
32
- * POST /api/coupons/redeem
33
- */
34
- async redeem(ctx) {
35
- try {
36
- const { couponCode, phoneNumber, orderId, orderAmount } = ctx.request.body;
37
- // Validate required fields
38
- if (!couponCode || !phoneNumber || !orderId) {
39
- return ctx.badRequest('Missing required fields: couponCode, phoneNumber, orderId');
40
- }
41
- const result = await strapi
42
- .plugin('coupon')
43
- .service('coupon')
44
- .redeem({
45
- couponCode,
46
- phoneNumber,
47
- orderId,
48
- orderAmount,
49
- });
50
- ctx.body = result;
51
- }
52
- catch (error) {
53
- strapi.log.error('Controller error in redeem:', error);
54
- ctx.internalServerError('An error occurred while redeeming the coupon');
55
- }
56
- },
57
- /**
58
- * Create coupon endpoint (Admin only)
59
- * POST /api/coupons
60
- */
61
- async create(ctx) {
62
- try {
63
- const { code, discountType, discountValue, maxUsage, validFrom, validTo, description, userRestrictions, } = ctx.request.body;
64
- // Validate required fields
65
- if (!code || !discountType || !discountValue || !validFrom || !validTo) {
66
- return ctx.badRequest('Missing required fields: code, discountType, discountValue, validFrom, validTo');
67
- }
68
- const result = await strapi
69
- .plugin('coupon')
70
- .service('coupon')
71
- .create({
72
- code,
73
- discountType,
74
- discountValue,
75
- maxUsage,
76
- validFrom,
77
- validTo,
78
- description,
79
- userRestrictions,
80
- });
81
- if (!result.success) {
82
- return ctx.badRequest(result.message, { errorCode: result.errorCode });
83
- }
84
- ctx.body = result;
85
- }
86
- catch (error) {
87
- strapi.log.error('Controller error in create:', error);
88
- ctx.internalServerError('An error occurred while creating the coupon');
89
- }
90
- },
91
- /**
92
- * Find all coupons
93
- * GET /api/coupons
94
- */
95
- async find(ctx) {
96
- try {
97
- const coupons = await strapi.plugin('coupon').service('coupon').findAll(ctx.query);
98
- ctx.body = coupons;
99
- }
100
- catch (error) {
101
- strapi.log.error('Controller error in find:', error);
102
- ctx.internalServerError('An error occurred while fetching coupons');
103
- }
104
- },
105
- /**
106
- * Find one coupon
107
- * GET /api/coupons/:id
108
- */
109
- async findOne(ctx) {
110
- try {
111
- const { id } = ctx.params;
112
- const coupon = await strapi.plugin('coupon').service('coupon').findOne(id);
113
- if (!coupon) {
114
- return ctx.notFound('Coupon not found');
115
- }
116
- ctx.body = coupon;
117
- }
118
- catch (error) {
119
- strapi.log.error('Controller error in findOne:', error);
120
- ctx.internalServerError('An error occurred while fetching the coupon');
121
- }
122
- },
123
- /**
124
- * Update coupon
125
- * PUT /api/coupons/:id
126
- */
127
- async update(ctx) {
128
- try {
129
- const { id } = ctx.params;
130
- const data = ctx.request.body;
131
- const coupon = await strapi.plugin('coupon').service('coupon').update(id, data);
132
- ctx.body = coupon;
133
- }
134
- catch (error) {
135
- strapi.log.error('Controller error in update:', error);
136
- ctx.internalServerError('An error occurred while updating the coupon');
137
- }
138
- },
139
- /**
140
- * Delete coupon
141
- * DELETE /api/coupons/:id
142
- */
143
- async delete(ctx) {
144
- try {
145
- const { id } = ctx.params;
146
- const coupon = await strapi.plugin('coupon').service('coupon').delete(id);
147
- ctx.body = coupon;
148
- }
149
- catch (error) {
150
- strapi.log.error('Controller error in delete:', error);
151
- ctx.internalServerError('An error occurred while deleting the coupon');
152
- }
153
- },
154
- });
@@ -1,5 +0,0 @@
1
- import type { Core } from '@strapi/strapi';
2
- declare const _default: Record<string, (params: {
3
- strapi: Core.Strapi;
4
- }) => any>;
5
- export default _default;
@@ -1,9 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const coupon_1 = __importDefault(require("./coupon"));
7
- exports.default = {
8
- coupon: coupon_1.default,
9
- };
package/dist/destroy.d.ts DELETED
@@ -1,5 +0,0 @@
1
- import type { Core } from '@strapi/strapi';
2
- declare const _default: ({ strapi }: {
3
- strapi: Core.Strapi;
4
- }) => void;
5
- export default _default;
package/dist/destroy.js DELETED
@@ -1,6 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.default = ({ strapi }) => {
4
- // Cleanup plugin logic here
5
- strapi.log.info('Coupon plugin destroyed');
6
- };
package/dist/index.d.ts DELETED
@@ -1,207 +0,0 @@
1
- import type { Core } from '@strapi/strapi';
2
- declare const plugin: {
3
- register: ({ strapi }: {
4
- strapi: Core.Strapi;
5
- }) => void;
6
- bootstrap: ({ strapi }: {
7
- strapi: Core.Strapi;
8
- }) => void;
9
- destroy: ({ strapi }: {
10
- strapi: Core.Strapi;
11
- }) => void;
12
- config: {
13
- default: {};
14
- validator(): void;
15
- };
16
- controllers: Record<string, (params: {
17
- strapi: Core.Strapi;
18
- }) => any>;
19
- routes: {
20
- 'content-api': {
21
- type: string;
22
- routes: ({
23
- method: string;
24
- path: string;
25
- handler: string;
26
- config: {
27
- policies: never[];
28
- middlewares: ((ctx: any, next: any) => Promise<any>)[];
29
- auth: boolean;
30
- };
31
- } | {
32
- method: string;
33
- path: string;
34
- handler: string;
35
- config: {
36
- policies: never[];
37
- auth: boolean;
38
- middlewares?: undefined;
39
- };
40
- })[];
41
- };
42
- };
43
- services: Record<string, (params: {
44
- strapi: Core.Strapi;
45
- }) => any>;
46
- contentTypes: {
47
- coupon: {
48
- schema: {
49
- kind: string;
50
- collectionName: string;
51
- info: {
52
- singularName: string;
53
- pluralName: string;
54
- displayName: string;
55
- description: string;
56
- };
57
- options: {
58
- draftAndPublish: boolean;
59
- };
60
- pluginOptions: {
61
- 'content-manager': {
62
- visible: boolean;
63
- };
64
- 'content-type-builder': {
65
- visible: boolean;
66
- };
67
- };
68
- layouts: {
69
- list: string[];
70
- edit: {
71
- name: string;
72
- size: number;
73
- }[][];
74
- };
75
- attributes: {
76
- code: {
77
- type: string;
78
- required: boolean;
79
- unique: boolean;
80
- configurable: boolean;
81
- };
82
- discountType: {
83
- type: string;
84
- enum: string[];
85
- required: boolean;
86
- default: string;
87
- };
88
- discountValue: {
89
- type: string;
90
- required: boolean;
91
- min: number;
92
- };
93
- maxUsage: {
94
- type: string;
95
- required: boolean;
96
- min: number;
97
- default: null;
98
- };
99
- maxUsagePerUser: {
100
- type: string;
101
- required: boolean;
102
- min: number;
103
- default: null;
104
- };
105
- currentUsage: {
106
- type: string;
107
- required: boolean;
108
- default: number;
109
- min: number;
110
- };
111
- validFrom: {
112
- type: string;
113
- required: boolean;
114
- };
115
- validTo: {
116
- type: string;
117
- required: boolean;
118
- };
119
- isActive: {
120
- type: string;
121
- default: boolean;
122
- required: boolean;
123
- };
124
- description: {
125
- type: string;
126
- required: boolean;
127
- };
128
- userRestrictions: {
129
- type: string;
130
- required: boolean;
131
- default: null;
132
- };
133
- redemptions: {
134
- type: string;
135
- relation: string;
136
- target: string;
137
- mappedBy: string;
138
- };
139
- };
140
- };
141
- };
142
- redemption: {
143
- schema: {
144
- kind: string;
145
- collectionName: string;
146
- info: {
147
- singularName: string;
148
- pluralName: string;
149
- displayName: string;
150
- description: string;
151
- };
152
- options: {
153
- draftAndPublish: boolean;
154
- };
155
- pluginOptions: {
156
- 'content-manager': {
157
- visible: boolean;
158
- };
159
- 'content-type-builder': {
160
- visible: boolean;
161
- };
162
- };
163
- layouts: {
164
- list: string[];
165
- edit: {
166
- name: string;
167
- size: number;
168
- }[][];
169
- };
170
- attributes: {
171
- coupon: {
172
- type: string;
173
- relation: string;
174
- target: string;
175
- inversedBy: string;
176
- };
177
- orderId: {
178
- type: string;
179
- required: boolean;
180
- };
181
- phoneNumber: {
182
- type: string;
183
- required: boolean;
184
- };
185
- redemptionDate: {
186
- type: string;
187
- required: boolean;
188
- };
189
- discountType: {
190
- type: string;
191
- required: boolean;
192
- };
193
- discountValue: {
194
- type: string;
195
- required: boolean;
196
- };
197
- metadata: {
198
- type: string;
199
- required: boolean;
200
- default: null;
201
- };
202
- };
203
- };
204
- };
205
- };
206
- };
207
- export default plugin;
package/dist/index.js DELETED
@@ -1,24 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const register_1 = __importDefault(require("./register"));
7
- const bootstrap_1 = __importDefault(require("./bootstrap"));
8
- const destroy_1 = __importDefault(require("./destroy"));
9
- const config_1 = __importDefault(require("./config"));
10
- const content_types_1 = __importDefault(require("./content-types"));
11
- const controllers_1 = __importDefault(require("./controllers"));
12
- const routes_1 = __importDefault(require("./routes"));
13
- const services_1 = __importDefault(require("./services"));
14
- const plugin = {
15
- register: register_1.default,
16
- bootstrap: bootstrap_1.default,
17
- destroy: destroy_1.default,
18
- config: config_1.default,
19
- controllers: controllers_1.default,
20
- routes: routes_1.default,
21
- services: services_1.default,
22
- contentTypes: content_types_1.default,
23
- };
24
- exports.default = plugin;
@@ -1,4 +0,0 @@
1
- declare const _default: {
2
- rateLimit: (config: import("./rate-limit").RateLimitConfig) => (ctx: any, next: any) => Promise<any>;
3
- };
4
- export default _default;
@@ -1,9 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const rate_limit_1 = __importDefault(require("./rate-limit"));
7
- exports.default = {
8
- rateLimit: rate_limit_1.default,
9
- };
@@ -1,6 +0,0 @@
1
- export interface RateLimitConfig {
2
- maxRequests: number;
3
- windowMs: number;
4
- }
5
- declare const _default: (config: RateLimitConfig) => (ctx: any, next: any) => Promise<any>;
6
- export default _default;
@@ -1,42 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- // Simple in-memory rate limiter
4
- // Uses in-memory storage - suitable for single-instance deployments
5
- const rateLimitStore = new Map();
6
- // Clean up old entries every hour
7
- setInterval(() => {
8
- const now = Date.now();
9
- for (const [key, value] of rateLimitStore.entries()) {
10
- if (now > value.resetAt) {
11
- rateLimitStore.delete(key);
12
- }
13
- }
14
- }, 3600000); // 1 hour
15
- exports.default = (config) => {
16
- return async (ctx, next) => {
17
- const identifier = ctx.ip || ctx.request.ip || 'unknown';
18
- const now = Date.now();
19
- const record = rateLimitStore.get(identifier);
20
- // No record or expired, create new
21
- if (!record || now > record.resetAt) {
22
- rateLimitStore.set(identifier, {
23
- count: 1,
24
- resetAt: now + config.windowMs,
25
- });
26
- return next();
27
- }
28
- // Check if limit reached
29
- if (record.count >= config.maxRequests) {
30
- ctx.status = 429;
31
- ctx.body = {
32
- error: 'Too many requests',
33
- message: `Rate limit exceeded. Please try again in ${Math.ceil((record.resetAt - now) / 1000)} seconds.`,
34
- retryAfter: Math.ceil((record.resetAt - now) / 1000),
35
- };
36
- return;
37
- }
38
- // Increment counter
39
- record.count++;
40
- return next();
41
- };
42
- };
@@ -1,5 +0,0 @@
1
- import type { Core } from '@strapi/strapi';
2
- declare const _default: ({ strapi }: {
3
- strapi: Core.Strapi;
4
- }) => void;
5
- export default _default;
package/dist/register.js DELETED
@@ -1,6 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.default = ({ strapi }) => {
4
- // Register plugin custom logic here
5
- strapi.log.info('Coupon plugin registered');
6
- };