@classytic/promo 0.1.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.
@@ -0,0 +1,3 @@
1
+ import { a as RepositoryPlugins, c as TenantConfig, i as PromoConfig, n as ModelName, o as ResolvedConfig, r as PluginType, s as ResolvedTenant, t as IndexDefinition } from "../config-iZjn_8pp.mjs";
2
+ import { C as UpdateRuleInput, S as UpdateRewardInput, _ as GiftCardTopUpInput, a as GiftCardBalance, b as RedeemVoucherInput, c as VoucherValidation, d as CreateRewardInput, f as CreateRuleInput, g as GiftCardSpendInput, h as GenerateSingleCodeInput, i as FreeProductLine, l as CartItem, m as GenerateCodesInput, n as DiscountLine, o as PaginatedResult, p as EvaluateInput, r as EvaluationResult, s as RejectedCode, t as CommitResult, u as CreateProgramInput, v as ListQuery, x as UpdateProgramInput, y as PromoContext } from "../results-Ca5ZCNbN.mjs";
3
+ export { type CartItem, type CommitResult, type CreateProgramInput, type CreateRewardInput, type CreateRuleInput, type DiscountLine, type EvaluateInput, type EvaluationResult, type FreeProductLine, type GenerateCodesInput, type GenerateSingleCodeInput, type GiftCardBalance, type GiftCardSpendInput, type GiftCardTopUpInput, type IndexDefinition, type ListQuery, type ModelName, type PaginatedResult, type PluginType, type PromoConfig, type PromoContext, type RedeemVoucherInput, type RejectedCode, type RepositoryPlugins, type ResolvedConfig, type ResolvedTenant, type TenantConfig, type UpdateProgramInput, type UpdateRewardInput, type UpdateRuleInput, type VoucherValidation };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,7 @@
1
+ //#region src/domain/ports/unit-of-work.port.d.ts
2
+ type TransactionSession = unknown;
3
+ interface UnitOfWork {
4
+ withTransaction<T>(cb: (session: TransactionSession) => Promise<T>): Promise<T>;
5
+ }
6
+ //#endregion
7
+ export { UnitOfWork as n, TransactionSession as t };
@@ -0,0 +1,146 @@
1
+ import { a as RewardType, c as VoucherStatus, i as ProgramType, n as DiscountScope, o as StackingMode, r as ProgramStatus, s as TriggerMode, t as DiscountMode } from "./index-J5BC20DN.mjs";
2
+
3
+ //#region src/domain/entities/program.d.ts
4
+ interface Program {
5
+ _id: string;
6
+ name: string;
7
+ description?: string;
8
+ programType: ProgramType;
9
+ triggerMode: TriggerMode;
10
+ status: ProgramStatus;
11
+ stackingMode: StackingMode;
12
+ priority: number;
13
+ startsAt?: Date;
14
+ endsAt?: Date;
15
+ maxUsageTotal?: number;
16
+ usedCount: number;
17
+ maxUsagePerCustomer?: number;
18
+ applicableCustomerIds: string[];
19
+ applicableCustomerTags: string[];
20
+ customerUsageCounts?: Record<string, number>;
21
+ metadata?: Record<string, unknown>;
22
+ createdAt: Date;
23
+ updatedAt: Date;
24
+ }
25
+ //#endregion
26
+ //#region src/domain/entities/reward.d.ts
27
+ interface Reward {
28
+ _id: string;
29
+ programId: string;
30
+ ruleId?: string;
31
+ rewardType: RewardType;
32
+ discountMode?: DiscountMode;
33
+ discountAmount?: number;
34
+ maxDiscountAmount?: number;
35
+ discountScope: DiscountScope;
36
+ applicableProductIds: string[];
37
+ freeProductId?: string;
38
+ freeProductSku?: string;
39
+ freeQuantity: number;
40
+ giftCardAmount?: number;
41
+ metadata?: Record<string, unknown>;
42
+ createdAt: Date;
43
+ updatedAt: Date;
44
+ }
45
+ //#endregion
46
+ //#region src/domain/entities/rule.d.ts
47
+ interface Rule {
48
+ _id: string;
49
+ programId: string;
50
+ name?: string;
51
+ minimumAmount: number;
52
+ minimumQuantity: number;
53
+ applicableProductIds: string[];
54
+ applicableCategories: string[];
55
+ applicableSkus: string[];
56
+ buyQuantity?: number;
57
+ code?: string;
58
+ startsAt?: Date;
59
+ endsAt?: Date;
60
+ metadata?: Record<string, unknown>;
61
+ createdAt: Date;
62
+ updatedAt: Date;
63
+ }
64
+ //#endregion
65
+ //#region src/domain/entities/voucher.d.ts
66
+ interface BalanceLedgerEntry {
67
+ amount: number;
68
+ orderId?: string;
69
+ description?: string;
70
+ createdAt: Date;
71
+ idempotencyKey?: string;
72
+ }
73
+ interface VoucherRedemption {
74
+ orderId: string;
75
+ customerId?: string;
76
+ discountAmount: number;
77
+ redeemedAt: Date;
78
+ idempotencyKey?: string;
79
+ }
80
+ interface Voucher {
81
+ _id: string;
82
+ programId: string;
83
+ code: string;
84
+ status: VoucherStatus;
85
+ customerId?: string;
86
+ usageLimit: number;
87
+ usedCount: number;
88
+ initialBalance?: number;
89
+ currentBalance?: number;
90
+ balanceLedger: BalanceLedgerEntry[];
91
+ expiresAt?: Date;
92
+ redemptions: VoucherRedemption[];
93
+ metadata?: Record<string, unknown>;
94
+ createdAt: Date;
95
+ updatedAt: Date;
96
+ }
97
+ //#endregion
98
+ //#region src/domain/ports/program.port.d.ts
99
+ interface ProgramPort {
100
+ create(data: Record<string, unknown>, session?: unknown): Promise<Program>;
101
+ getById(id: string, tenantId?: string): Promise<Program | null>;
102
+ update(id: string, data: Record<string, unknown>, tenantId?: string, session?: unknown): Promise<Program>;
103
+ findMany(query: Record<string, unknown>, options?: Record<string, unknown>): Promise<Program[]>;
104
+ findActive(tenantId?: string, now?: Date): Promise<Program[]>;
105
+ incrementUsage(id: string, tenantId?: string, session?: unknown): Promise<Program>;
106
+ decrementUsage(id: string, tenantId?: string, session?: unknown): Promise<Program>;
107
+ getCustomerUsage(id: string, customerId: string, tenantId?: string): Promise<number>;
108
+ incrementCustomerUsage(id: string, customerId: string, tenantId?: string, session?: unknown): Promise<Program>;
109
+ }
110
+ //#endregion
111
+ //#region src/domain/ports/reward.port.d.ts
112
+ interface RewardPort {
113
+ create(data: Record<string, unknown>, session?: unknown): Promise<Reward>;
114
+ getById(id: string, tenantId?: string): Promise<Reward | null>;
115
+ update(id: string, data: Record<string, unknown>, tenantId?: string, session?: unknown): Promise<Reward>;
116
+ delete(id: string, tenantId?: string, session?: unknown): Promise<void>;
117
+ findByProgramId(programId: string, tenantId?: string): Promise<Reward[]>;
118
+ findByProgramIds(programIds: string[], tenantId?: string): Promise<Reward[]>;
119
+ }
120
+ //#endregion
121
+ //#region src/domain/ports/rule.port.d.ts
122
+ interface RulePort {
123
+ create(data: Record<string, unknown>, session?: unknown): Promise<Rule>;
124
+ getById(id: string, tenantId?: string): Promise<Rule | null>;
125
+ update(id: string, data: Record<string, unknown>, tenantId?: string, session?: unknown): Promise<Rule>;
126
+ delete(id: string, tenantId?: string, session?: unknown): Promise<void>;
127
+ findByProgramId(programId: string, tenantId?: string): Promise<Rule[]>;
128
+ findByCode(code: string, tenantId?: string): Promise<Rule | null>;
129
+ findByProgramIds(programIds: string[], tenantId?: string): Promise<Rule[]>;
130
+ }
131
+ //#endregion
132
+ //#region src/domain/ports/voucher.port.d.ts
133
+ interface VoucherPort {
134
+ create(data: Record<string, unknown>, session?: unknown): Promise<Voucher>;
135
+ createMany(data: Record<string, unknown>[], session?: unknown): Promise<Voucher[]>;
136
+ getById(id: string, tenantId?: string): Promise<Voucher | null>;
137
+ getByCode(code: string, tenantId?: string): Promise<Voucher | null>;
138
+ update(id: string, data: Record<string, unknown>, tenantId?: string, session?: unknown): Promise<Voucher>;
139
+ findMany(query: Record<string, unknown>, options?: Record<string, unknown>): Promise<Voucher[]>;
140
+ incrementUsage(id: string, redemption: Record<string, unknown>, tenantId?: string, session?: unknown): Promise<Voucher>;
141
+ addLedgerEntry(id: string, entry: Record<string, unknown>, balanceDelta: number, tenantId?: string, session?: unknown): Promise<Voucher>;
142
+ expireByDate(before: Date, tenantId?: string): Promise<number>;
143
+ hasIdempotencyKey(id: string, key: string): Promise<boolean>;
144
+ }
145
+ //#endregion
146
+ export { BalanceLedgerEntry as a, Rule as c, ProgramPort as i, Reward as l, RulePort as n, Voucher as o, RewardPort as r, VoucherRedemption as s, VoucherPort as t, Program as u };
package/package.json ADDED
@@ -0,0 +1,108 @@
1
+ {
2
+ "name": "@classytic/promo",
3
+ "version": "0.1.0",
4
+ "description": "Production-grade promotion, coupon, and discount engine for MongoDB — programs, rules, rewards, vouchers, gift cards, buy-x-get-y",
5
+ "author": "Classytic",
6
+ "homepage": "https://www.npmjs.com/package/@classytic/promo",
7
+ "bugs": {
8
+ "url": "https://github.com/classytic/promo/issues"
9
+ },
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/classytic/promo.git"
13
+ },
14
+ "publishConfig": {
15
+ "access": "public"
16
+ },
17
+ "type": "module",
18
+ "sideEffects": false,
19
+ "engines": {
20
+ "node": ">=22"
21
+ },
22
+ "exports": {
23
+ ".": {
24
+ "types": "./dist/index.d.mts",
25
+ "default": "./dist/index.mjs"
26
+ },
27
+ "./domain": {
28
+ "types": "./dist/domain/index.d.mts",
29
+ "default": "./dist/domain/index.mjs"
30
+ },
31
+ "./domain/enums": {
32
+ "types": "./dist/domain/enums/index.d.mts",
33
+ "default": "./dist/domain/enums/index.mjs"
34
+ },
35
+ "./models": {
36
+ "types": "./dist/models/index.d.mts",
37
+ "default": "./dist/models/index.mjs"
38
+ },
39
+ "./repositories": {
40
+ "types": "./dist/repositories/index.d.mts",
41
+ "default": "./dist/repositories/index.mjs"
42
+ },
43
+ "./services": {
44
+ "types": "./dist/services/index.d.mts",
45
+ "default": "./dist/services/index.mjs"
46
+ },
47
+ "./events": {
48
+ "types": "./dist/events/index.d.mts",
49
+ "default": "./dist/events/index.mjs"
50
+ },
51
+ "./types": {
52
+ "types": "./dist/types/index.d.mts",
53
+ "default": "./dist/types/index.mjs"
54
+ }
55
+ },
56
+ "main": "./dist/index.mjs",
57
+ "types": "./dist/index.d.mts",
58
+ "files": [
59
+ "dist",
60
+ "README.md",
61
+ "CHANGELOG.md",
62
+ "LICENSE"
63
+ ],
64
+ "scripts": {
65
+ "build": "tsdown",
66
+ "dev": "tsdown --watch",
67
+ "test": "vitest run",
68
+ "test:watch": "vitest",
69
+ "test:coverage": "vitest run --coverage",
70
+ "typecheck": "tsc --noEmit",
71
+ "lint": "biome check src/ tests/",
72
+ "lint:fix": "biome check --write src/ tests/",
73
+ "format": "biome format --write src/ tests/",
74
+ "check": "biome check --write --unsafe src/ tests/",
75
+ "prepublishOnly": "npm run lint && npm run typecheck && npm run test && npm run build",
76
+ "release": "npm run build && npm run typecheck && npm publish --access public"
77
+ },
78
+ "peerDependencies": {
79
+ "@classytic/mongokit": ">=3.5.3",
80
+ "mongoose": ">=9.0.0"
81
+ },
82
+ "devDependencies": {
83
+ "@biomejs/biome": "^2.4.9",
84
+ "@classytic/mongokit": "^3.5.3",
85
+ "@types/node": "^25.5.0",
86
+ "@vitest/coverage-v8": "^3.2.4",
87
+ "knip": "^6.3.0",
88
+ "mongodb-memory-server": "^10.2.3",
89
+ "mongoose": "^9.3.3",
90
+ "tsdown": "^0.21.5",
91
+ "typescript": "^5.7.0",
92
+ "vitest": "^3.0.0"
93
+ },
94
+ "keywords": [
95
+ "promotion",
96
+ "coupon",
97
+ "discount",
98
+ "promo-code",
99
+ "gift-card",
100
+ "buy-x-get-y",
101
+ "voucher",
102
+ "mongodb",
103
+ "mongoose",
104
+ "commerce",
105
+ "ecommerce"
106
+ ],
107
+ "license": "MIT"
108
+ }