@voyantjs/promotions 0.33.0 → 0.35.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.
@@ -1 +1 @@
1
- {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAG9C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAEjE,OAAO,EAIL,KAAK,sBAAsB,EAC5B,MAAM,aAAa,CAAA;AACpB,OAAO,EAEL,KAAK,gBAAgB,EAItB,MAAM,aAAa,CAAA;AACpB,OAAO,KAAK,EACV,sBAAsB,EACtB,yBAAyB,EACzB,qBAAqB,EACrB,sBAAsB,EACvB,MAAM,iBAAiB,CAAA;AAExB,MAAM,WAAW,oBAAoB;IACnC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAA;IACnB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,sBAAsB,CAAA;CAChC;AAUD;;;;;;;;;;GAUG;AACH,wBAAsB,sBAAsB,CAC1C,EAAE,EAAE,kBAAkB,EACtB,KAAK,EAAE,qBAAqB,GAC3B,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAyB1B;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,EAAE,EAAE,kBAAkB,EACtB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,qBAAqB,GAC3B,OAAO,CAAC;IAAE,UAAU,EAAE,MAAM,EAAE,GAAG,IAAI,CAAA;CAAE,CAAC,CAS1C;AA8ED,iBAAe,UAAU,CAAC,EAAE,EAAE,kBAAkB,EAAE,KAAK,EAAE,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwBjF;AAED,iBAAe,YAAY,CAAC,EAAE,EAAE,kBAAkB,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAOhG;AAED,iBAAe,WAAW,CACxB,EAAE,EAAE,kBAAkB,EACtB,KAAK,EAAE,sBAAsB,EAC7B,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,gBAAgB,CAAC,CAa3B;AAED,iBAAe,WAAW,CACxB,EAAE,EAAE,kBAAkB,EACtB,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,sBAAsB,EAC7B,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAsClC;AAED,iBAAe,YAAY,CACzB,EAAE,EAAE,kBAAkB,EACtB,EAAE,EAAE,MAAM,EACV,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAgBlC;AAED,iBAAe,WAAW,CACxB,EAAE,EAAE,kBAAkB,EACtB,EAAE,EAAE,MAAM,EACV,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAiChC;AAED,eAAO,MAAM,iBAAiB;;;;;;;;;CAS7B,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG,OAAO,iBAAiB,CAAA"}
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AAgB9C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAEjE,OAAO,EAIL,KAAK,sBAAsB,EAC5B,MAAM,aAAa,CAAA;AACpB,OAAO,EAEL,KAAK,gBAAgB,EAItB,MAAM,aAAa,CAAA;AACpB,OAAO,KAAK,EACV,sBAAsB,EACtB,yBAAyB,EACzB,qBAAqB,EACrB,sBAAsB,EACvB,MAAM,iBAAiB,CAAA;AAExB,MAAM,WAAW,oBAAoB;IACnC;;;;OAIG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAA;IACnB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,sBAAsB,CAAA;CAChC;AAUD;;;;;;;;;;GAUG;AACH,wBAAsB,sBAAsB,CAC1C,EAAE,EAAE,kBAAkB,EACtB,KAAK,EAAE,qBAAqB,GAC3B,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAyB1B;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,EAAE,EAAE,kBAAkB,EACtB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,qBAAqB,GAC3B,OAAO,CAAC;IAAE,UAAU,EAAE,MAAM,EAAE,GAAG,IAAI,CAAA;CAAE,CAAC,CAS1C;AA8ED,iBAAe,UAAU,CAAC,EAAE,EAAE,kBAAkB,EAAE,KAAK,EAAE,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0EjF;AAUD,iBAAe,YAAY,CAAC,EAAE,EAAE,kBAAkB,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAOhG;AAED,iBAAe,WAAW,CACxB,EAAE,EAAE,kBAAkB,EACtB,KAAK,EAAE,sBAAsB,EAC7B,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,gBAAgB,CAAC,CAa3B;AAED,iBAAe,WAAW,CACxB,EAAE,EAAE,kBAAkB,EACtB,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,sBAAsB,EAC7B,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAsClC;AAED,iBAAe,YAAY,CACzB,EAAE,EAAE,kBAAkB,EACtB,EAAE,EAAE,MAAM,EACV,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAgBlC;AAED,iBAAe,WAAW,CACxB,EAAE,EAAE,kBAAkB,EACtB,EAAE,EAAE,MAAM,EACV,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAiChC;AAED,eAAO,MAAM,iBAAiB;;;;;;;;;CAS7B,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG,OAAO,iBAAiB,CAAA"}
package/dist/service.js CHANGED
@@ -15,7 +15,7 @@
15
15
  * - `destinations` scope expands via `product_destinations` (in @voyantjs/products)
16
16
  */
17
17
  import { productCategoryProducts, productDestinations } from "@voyantjs/products/schema";
18
- import { and, count, desc, eq, inArray, sql } from "drizzle-orm";
18
+ import { and, count, desc, eq, gte, ilike, inArray, isNotNull, isNull, lte, or, sql, } from "drizzle-orm";
19
19
  import { PROMOTION_CHANGED_EVENT, } from "./events.js";
20
20
  import { promotionalOfferProducts, promotionalOfferRedemptions, promotionalOffers, } from "./schema.js";
21
21
  /** Fields whose change does NOT affect projection or evaluation — safe to skip emit. */
@@ -165,6 +165,38 @@ async function listOffers(db, query) {
165
165
  where.push(eq(promotionalOffers.active, query.active));
166
166
  if (query.code !== undefined)
167
167
  where.push(eq(promotionalOffers.code, query.code.toLowerCase()));
168
+ if (query.search !== undefined) {
169
+ const term = `%${query.search}%`;
170
+ where.push(or(ilike(promotionalOffers.name, term), ilike(promotionalOffers.slug, term), ilike(promotionalOffers.description, term), ilike(promotionalOffers.code, term)));
171
+ }
172
+ if (query.applicationMode === "auto")
173
+ where.push(isNull(promotionalOffers.code));
174
+ if (query.applicationMode === "code")
175
+ where.push(isNotNull(promotionalOffers.code));
176
+ if (query.scopeKind !== undefined) {
177
+ where.push(sql `${promotionalOffers.scope}->>'kind' = ${query.scopeKind}`);
178
+ }
179
+ if (query.status !== undefined) {
180
+ const now = new Date();
181
+ if (query.status === "archived") {
182
+ where.push(eq(promotionalOffers.active, false));
183
+ }
184
+ else if (query.status === "scheduled") {
185
+ where.push(and(eq(promotionalOffers.active, true), gte(promotionalOffers.validFrom, now)));
186
+ }
187
+ else if (query.status === "expired") {
188
+ where.push(and(eq(promotionalOffers.active, true), lte(promotionalOffers.validUntil, now)));
189
+ }
190
+ else {
191
+ where.push(and(eq(promotionalOffers.active, true), or(isNull(promotionalOffers.validFrom), lte(promotionalOffers.validFrom, now)), or(isNull(promotionalOffers.validUntil), gte(promotionalOffers.validUntil, now))));
192
+ }
193
+ }
194
+ if (query.validFrom !== undefined) {
195
+ where.push(or(isNull(promotionalOffers.validUntil), gte(promotionalOffers.validUntil, startOfDay(query.validFrom))));
196
+ }
197
+ if (query.validUntil !== undefined) {
198
+ where.push(or(isNull(promotionalOffers.validFrom), lte(promotionalOffers.validFrom, endOfDay(query.validUntil))));
199
+ }
168
200
  const filter = where.length > 0 ? and(...where) : undefined;
169
201
  const limit = query.limit ?? 50;
170
202
  const offset = query.offset ?? 0;
@@ -182,6 +214,12 @@ async function listOffers(db, query) {
182
214
  .offset(offset);
183
215
  return { data, total, limit, offset };
184
216
  }
217
+ function startOfDay(isoDate) {
218
+ return new Date(`${isoDate}T00:00:00.000Z`);
219
+ }
220
+ function endOfDay(isoDate) {
221
+ return new Date(`${isoDate}T23:59:59.999Z`);
222
+ }
185
223
  async function getOfferById(db, id) {
186
224
  const [row] = await db
187
225
  .select()
@@ -129,6 +129,27 @@ export declare const updatePromotionalOfferSchema: z.ZodObject<{
129
129
  export declare const promotionalOfferListQuerySchema: z.ZodObject<{
130
130
  active: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodLiteral<"true">, z.ZodLiteral<"false">]>, z.ZodTransform<boolean, "true" | "false">>>;
131
131
  code: z.ZodOptional<z.ZodString>;
132
+ search: z.ZodOptional<z.ZodString>;
133
+ applicationMode: z.ZodOptional<z.ZodEnum<{
134
+ code: "code";
135
+ auto: "auto";
136
+ }>>;
137
+ status: z.ZodOptional<z.ZodEnum<{
138
+ expired: "expired";
139
+ active: "active";
140
+ archived: "archived";
141
+ scheduled: "scheduled";
142
+ }>>;
143
+ scopeKind: z.ZodOptional<z.ZodEnum<{
144
+ products: "products";
145
+ markets: "markets";
146
+ destinations: "destinations";
147
+ global: "global";
148
+ categories: "categories";
149
+ audiences: "audiences";
150
+ }>>;
151
+ validFrom: z.ZodOptional<z.ZodString>;
152
+ validUntil: z.ZodOptional<z.ZodString>;
132
153
  limit: z.ZodDefault<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
133
154
  offset: z.ZodDefault<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
134
155
  }, z.core.$strip>;
@@ -137,4 +158,6 @@ export type InsertPromotionalOffer = z.infer<typeof insertPromotionalOfferSchema
137
158
  export type UpdatePromotionalOfferInput = z.input<typeof updatePromotionalOfferSchema>;
138
159
  export type UpdatePromotionalOffer = z.infer<typeof updatePromotionalOfferSchema>;
139
160
  export type PromotionalOfferListQuery = z.infer<typeof promotionalOfferListQuerySchema>;
161
+ export type PromotionalOfferApplicationMode = NonNullable<PromotionalOfferListQuery["applicationMode"]>;
162
+ export type PromotionalOfferListStatus = NonNullable<PromotionalOfferListQuery["status"]>;
140
163
  //# sourceMappingURL=validation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAUvB,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;2BAsBtC,CAAA;AAEF,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAA;AAC/E,MAAM,MAAM,yBAAyB,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAA;AAOrE,eAAO,MAAM,gCAAgC;;iBAK3C,CAAA;AAEF,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gCAAgC,CAAC,CAAA;AAqFzF,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAmD,CAAA;AAE5F,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAQxC,CAAA;AAED,eAAO,MAAM,+BAA+B;;;;;iBAQ1C,CAAA;AAEF,MAAM,MAAM,2BAA2B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAA;AACtF,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAA;AACjF,MAAM,MAAM,2BAA2B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAA;AACtF,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAA;AACjF,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,+BAA+B,CAAC,CAAA"}
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAUvB,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;2BAsBtC,CAAA;AAEF,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAA;AAC/E,MAAM,MAAM,yBAAyB,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAA;AAOrE,eAAO,MAAM,gCAAgC;;iBAK3C,CAAA;AAEF,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gCAAgC,CAAC,CAAA;AAqFzF,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAmD,CAAA;AAE5F,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAQxC,CAAA;AAED,eAAO,MAAM,+BAA+B;;;;;;;;;;;;;;;;;;;;;;;;;;iBAgB1C,CAAA;AAEF,MAAM,MAAM,2BAA2B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAA;AACtF,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAA;AACjF,MAAM,MAAM,2BAA2B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAA;AACtF,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAA;AACjF,MAAM,MAAM,yBAAyB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,+BAA+B,CAAC,CAAA;AACvF,MAAM,MAAM,+BAA+B,GAAG,WAAW,CACvD,yBAAyB,CAAC,iBAAiB,CAAC,CAC7C,CAAA;AACD,MAAM,MAAM,0BAA0B,GAAG,WAAW,CAAC,yBAAyB,CAAC,QAAQ,CAAC,CAAC,CAAA"}
@@ -129,6 +129,14 @@ export const promotionalOfferListQuerySchema = z.object({
129
129
  .transform((v) => v === "true")
130
130
  .optional(),
131
131
  code: z.string().min(1).max(80).optional(),
132
+ search: z.string().trim().min(1).max(200).optional(),
133
+ applicationMode: z.enum(["auto", "code"]).optional(),
134
+ status: z.enum(["active", "scheduled", "expired", "archived"]).optional(),
135
+ scopeKind: z
136
+ .enum(["global", "products", "categories", "destinations", "markets", "audiences"])
137
+ .optional(),
138
+ validFrom: z.string().date().optional(),
139
+ validUntil: z.string().date().optional(),
132
140
  limit: z.coerce.number().int().positive().max(200).optional().default(50),
133
141
  offset: z.coerce.number().int().nonnegative().optional().default(0),
134
142
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@voyantjs/promotions",
3
- "version": "0.33.0",
3
+ "version": "0.35.0",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "exports": {
@@ -64,13 +64,13 @@
64
64
  "drizzle-orm": "^0.45.2",
65
65
  "hono": "^4.12.10",
66
66
  "zod": "^4.3.6",
67
- "@voyantjs/catalog": "0.33.0",
68
- "@voyantjs/core": "0.33.0",
69
- "@voyantjs/db": "0.33.0",
70
- "@voyantjs/hono": "0.33.0",
71
- "@voyantjs/products": "0.33.0",
72
- "@voyantjs/storefront": "0.33.0",
73
- "@voyantjs/workflows": "0.33.0"
67
+ "@voyantjs/catalog": "0.35.0",
68
+ "@voyantjs/core": "0.35.0",
69
+ "@voyantjs/db": "0.35.0",
70
+ "@voyantjs/hono": "0.35.0",
71
+ "@voyantjs/products": "0.35.0",
72
+ "@voyantjs/storefront": "0.35.0",
73
+ "@voyantjs/workflows": "0.35.0"
74
74
  },
75
75
  "devDependencies": {
76
76
  "typescript": "^6.0.2",