dgc-core 2.0.0 → 2.0.1

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,6 @@
1
+ /** Mobile giveaway pagination; private dashboard pagination keeps its own contract. */
2
+ export declare function parseGiveawayApiPagination(params: URLSearchParams): {
3
+ page: number;
4
+ pageSize: number;
5
+ skip: number;
6
+ };
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseGiveawayApiPagination = parseGiveawayApiPagination;
4
+ const http_error_1 = require("../http-error");
5
+ /** Mobile giveaway pagination; private dashboard pagination keeps its own contract. */
6
+ function parseGiveawayApiPagination(params) {
7
+ const invalid = () => new http_error_1.HttpError('Invalid page or size parameter', 400);
8
+ const integer = (key, fallback) => {
9
+ const values = params.getAll(key);
10
+ if (!values.length)
11
+ return fallback;
12
+ if (values.length !== 1 || !/^\d+$/.test(values[0]))
13
+ throw invalid();
14
+ const value = Number(values[0]);
15
+ if (!Number.isSafeInteger(value) || value < 1)
16
+ throw invalid();
17
+ return value;
18
+ };
19
+ const page = integer('page', 1);
20
+ const pageSize = integer('size', 20);
21
+ const skip = (page - 1) * pageSize;
22
+ if (pageSize > 50 || !Number.isSafeInteger(skip))
23
+ throw invalid();
24
+ return { page, pageSize, skip };
25
+ }
@@ -1,7 +1,7 @@
1
1
  import { GiveawayAction, GiveawayCategory, GiveawaySelectionMethod, GiveawayStatus, GiveawayWinnerStatus } from '../enums/giveaway';
2
2
  import { UserCollectorType } from '../enums/user';
3
3
  import type { ClientSession, Db, MongoClient } from 'mongodb';
4
- import type { GiveawayPreset, GiveawayTicket, GiveawayClaim } from '../types';
4
+ import type { GiveawayPreset, GiveawayTicket, GiveawayClaim, PaginatedApiResponse } from '../types';
5
5
  import type { UserProfile, AuditEvent, DashboardData, Entry, EntryRecord, Giveaway, GiveawayDetailData, GiveawaySummary, NotificationJob, NotificationRecord, OverviewData, PageResult, Winner, WinnerRecord } from './types';
6
6
  type Stored<T extends {
7
7
  _id: string;
@@ -26,7 +26,7 @@ export declare class GiveawayRepository {
26
26
  private audit;
27
27
  getGiveaway(id: string, session?: ClientSession): Promise<Giveaway>;
28
28
  getPublicGiveaway(id: string): Promise<GiveawaySummary>;
29
- listPublicGiveaways(params?: URLSearchParams): Promise<PageResult<GiveawaySummary>>;
29
+ listPublicGiveaways(params?: URLSearchParams): Promise<PaginatedApiResponse<GiveawaySummary>>;
30
30
  listGiveaways(params?: URLSearchParams): Promise<PageResult<GiveawaySummary>>;
31
31
  getDashboard(admin: string): Promise<DashboardData>;
32
32
  getOverview(days?: number): Promise<OverviewData>;
@@ -233,12 +233,7 @@ export declare class GiveawayRepository {
233
233
  _id: string;
234
234
  }>;
235
235
  getTicket(userId: string, entryId: string): Promise<GiveawayTicket>;
236
- listTickets(userId: string, params: URLSearchParams): Promise<{
237
- data: GiveawayTicket[];
238
- total: number;
239
- page: number;
240
- limit: number;
241
- }>;
236
+ listTickets(userId: string, params: URLSearchParams): Promise<PaginatedApiResponse<GiveawayTicket>>;
242
237
  getUserClaim(giveawayId: string, userId: string): Promise<GiveawayClaim>;
243
238
  claimPrize(giveawayId: string, userId: string, raw: unknown): Promise<Omit<import("mongodb").WithId<Stored<Winner>>, "_id"> & {
244
239
  _id: string;
@@ -8,6 +8,7 @@ const user_1 = require("../enums/user");
8
8
  const node_crypto_1 = require("node:crypto");
9
9
  const mongodb_1 = require("mongodb");
10
10
  const entry_id_1 = require("./entry-id");
11
+ const api_pagination_1 = require("./api-pagination");
11
12
  const domain_1 = require("./domain");
12
13
  const schemas_1 = require("./schemas");
13
14
  const projection = { entryVersion: 0 };
@@ -179,9 +180,7 @@ class GiveawayRepository {
179
180
  return { ...g, status, entryCount: await this.entries.countDocuments({ giveawayId: id }) };
180
181
  }
181
182
  async listPublicGiveaways(params = new URLSearchParams()) {
182
- const { page, limit: requestedLimit } = pagination(params);
183
- const limit = Math.min(requestedLimit, 50);
184
- const skip = (page - 1) * limit;
183
+ const { page, pageSize, skip } = (0, api_pagination_1.parseGiveawayApiPagination)(params);
185
184
  const filter = {
186
185
  $or: [
187
186
  {
@@ -204,20 +203,21 @@ class GiveawayRepository {
204
203
  { $match: filter },
205
204
  { $sort: { createdAt: -1, _id: 1 } },
206
205
  { $skip: skip },
207
- { $limit: limit },
206
+ { $limit: pageSize },
208
207
  ...entryCountLookup
209
208
  ])
210
209
  .toArray(),
211
210
  this.giveaways.countDocuments(filter)
212
211
  ]);
213
212
  return {
213
+ page,
214
+ pageSize,
215
+ count: rows.length,
216
+ totalCount: total,
214
217
  data: rows.map(row => {
215
218
  const g = row;
216
219
  return { ...g, status: (0, domain_1.effectiveStatus)(g) };
217
- }),
218
- total,
219
- page,
220
- limit
220
+ })
221
221
  };
222
222
  }
223
223
  async listGiveaways(params = new URLSearchParams()) {
@@ -978,24 +978,23 @@ class GiveawayRepository {
978
978
  };
979
979
  }
980
980
  async listTickets(userId, params) {
981
- const { page, limit: requestedLimit } = pagination(params);
982
- const limit = Math.min(requestedLimit, 50);
983
- const skip = (page - 1) * limit;
981
+ const { page, pageSize, skip } = (0, api_pagination_1.parseGiveawayApiPagination)(params);
984
982
  const filter = { userId };
985
983
  const [entries, total] = await Promise.all([
986
984
  this.entries
987
985
  .find(filter, { projection: { _id: 1 } })
988
986
  .sort({ enteredAt: -1, _id: 1 })
989
987
  .skip(skip)
990
- .limit(limit)
988
+ .limit(pageSize)
991
989
  .toArray(),
992
990
  this.entries.countDocuments(filter)
993
991
  ]);
994
992
  return {
995
- data: await Promise.all(entries.map(e => this.getTicket(userId, e._id))),
996
- total,
997
993
  page,
998
- limit
994
+ pageSize,
995
+ count: entries.length,
996
+ totalCount: total,
997
+ data: await Promise.all(entries.map(e => this.getTicket(userId, e._id)))
999
998
  };
1000
999
  }
1001
1000
  async getUserClaim(giveawayId, userId) {
@@ -1,5 +1,6 @@
1
1
  /** Server-only giveaway rules and persistence shared by the admin dashboard and cloud APIs. */
2
2
  export * from './domain';
3
+ export * from './api-pagination';
3
4
  export * from './entry-id';
4
5
  export * from './giveaway-repository';
5
6
  export * from './schemas';
@@ -16,6 +16,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  /** Server-only giveaway rules and persistence shared by the admin dashboard and cloud APIs. */
18
18
  __exportStar(require("./domain"), exports);
19
+ __exportStar(require("./api-pagination"), exports);
19
20
  __exportStar(require("./entry-id"), exports);
20
21
  __exportStar(require("./giveaway-repository"), exports);
21
22
  __exportStar(require("./schemas"), exports);
@@ -0,0 +1,12 @@
1
+ /** Successful non-paginated DGC API response. */
2
+ export type ApiResponse<T> = {
3
+ data: T;
4
+ };
5
+ /** Successful paginated DGC API response. count is the number of returned records. */
6
+ export type PaginatedApiResponse<T> = {
7
+ page: number;
8
+ pageSize: number;
9
+ count: number;
10
+ totalCount: number;
11
+ data: T[];
12
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -5,6 +5,7 @@ export * from '../enums/card';
5
5
  export * from '../enums/rc';
6
6
  export * from '../enums/user';
7
7
  export * from './blockchain';
8
+ export * from './api';
8
9
  export * from './card';
9
10
  export * from './embedding';
10
11
  export * from './env';
@@ -21,6 +21,7 @@ __exportStar(require("../enums/card"), exports);
21
21
  __exportStar(require("../enums/rc"), exports);
22
22
  __exportStar(require("../enums/user"), exports);
23
23
  __exportStar(require("./blockchain"), exports);
24
+ __exportStar(require("./api"), exports);
24
25
  __exportStar(require("./card"), exports);
25
26
  __exportStar(require("./embedding"), exports);
26
27
  __exportStar(require("./env"), exports);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dgc-core",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "description": "Shared DGC contracts, business rules and server utilities",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",