@drttix/drt-sdk 1.0.6 → 1.0.8

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 (50) hide show
  1. package/dist/cjs/src/generated/portal/core/OpenAPI.js +1 -1
  2. package/dist/cjs/src/generated/portal/index.d.ts +2 -0
  3. package/dist/cjs/src/generated/portal/models/BulkEditCouponRequestDto.d.ts +16 -0
  4. package/dist/cjs/src/generated/portal/models/BulkEditRequestDto.d.ts +1 -1
  5. package/dist/cjs/src/generated/portal/models/ImportFromEventRequestDto.d.ts +4 -0
  6. package/dist/cjs/src/generated/portal/models/ReorderBookmarkRequestDto.d.ts +1 -1
  7. package/dist/cjs/src/generated/portal/services/FeaturesBlockedSeatsService.d.ts +10 -0
  8. package/dist/cjs/src/generated/portal/services/FeaturesBlockedSeatsService.js +19 -0
  9. package/dist/cjs/src/generated/portal/services/FeaturesDiscountsService.d.ts +10 -0
  10. package/dist/cjs/src/generated/portal/services/FeaturesDiscountsService.js +19 -0
  11. package/dist/cjs/src/generated/portal/types.d.ts +2 -0
  12. package/dist/cjs/src/scripts/generate-definition.js +20 -19
  13. package/dist/cjs/src/staging/portal.js +1 -0
  14. package/dist/esm/package.json +3 -0
  15. package/dist/esm/src/generated/portal/core/OpenAPI.js +1 -1
  16. package/dist/esm/src/generated/portal/index.d.ts +2 -0
  17. package/dist/esm/src/generated/portal/models/BulkEditCouponRequestDto.d.ts +16 -0
  18. package/dist/esm/src/generated/portal/models/BulkEditRequestDto.d.ts +1 -1
  19. package/dist/esm/src/generated/portal/models/ImportFromEventRequestDto.d.ts +4 -0
  20. package/dist/esm/src/generated/portal/models/ReorderBookmarkRequestDto.d.ts +1 -1
  21. package/dist/esm/src/generated/portal/services/FeaturesBlockedSeatsService.d.ts +10 -0
  22. package/dist/esm/src/generated/portal/services/FeaturesBlockedSeatsService.js +19 -0
  23. package/dist/esm/src/generated/portal/services/FeaturesDiscountsService.d.ts +10 -0
  24. package/dist/esm/src/generated/portal/services/FeaturesDiscountsService.js +19 -0
  25. package/dist/esm/src/generated/portal/types.d.ts +2 -0
  26. package/dist/esm/src/scripts/generate-definition.js +20 -19
  27. package/dist/esm/src/staging/portal.js +1 -0
  28. package/package.json +3 -3
  29. package/scripts/fix-import-extensions.mjs +16 -0
  30. package/src/generated/portal/core/OpenAPI.ts +1 -1
  31. package/src/generated/portal/index.ts +2 -0
  32. package/src/generated/portal/models/BulkEditCouponRequestDto.ts +21 -0
  33. package/src/generated/portal/models/BulkEditRequestDto.ts +1 -1
  34. package/src/generated/portal/models/ImportFromEventRequestDto.ts +9 -0
  35. package/src/generated/portal/models/ReorderBookmarkRequestDto.ts +1 -1
  36. package/src/generated/portal/services/FeaturesBlockedSeatsService.ts +23 -0
  37. package/src/generated/portal/services/FeaturesDiscountsService.ts +23 -0
  38. package/src/generated/portal/types.ts +2 -0
  39. package/src/scripts/generate-definition.ts +32 -26
  40. package/src/staging/portal.ts +1 -0
  41. package/.claude/admin-auth/auth.middleware.ts.txt +0 -149
  42. package/.claude/admin-auth/superuser.middleware.ts.txt +0 -41
  43. package/dist/cjs/src/generated/portal/models/BlockedSeatDetail.d.ts +0 -9
  44. package/dist/cjs/src/generated/portal/models/OrderDetail.d.ts +0 -4
  45. package/dist/esm/src/generated/portal/models/BlockedSeatDetail.d.ts +0 -9
  46. package/dist/esm/src/generated/portal/models/OrderDetail.d.ts +0 -4
  47. /package/dist/cjs/src/generated/portal/models/{BlockedSeatDetail.js → BulkEditCouponRequestDto.js} +0 -0
  48. /package/dist/cjs/src/generated/portal/models/{OrderDetail.js → ImportFromEventRequestDto.js} +0 -0
  49. /package/dist/esm/src/generated/portal/models/{BlockedSeatDetail.js → BulkEditCouponRequestDto.js} +0 -0
  50. /package/dist/esm/src/generated/portal/models/{OrderDetail.js → ImportFromEventRequestDto.js} +0 -0
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.OpenAPI = void 0;
4
4
  exports.OpenAPI = {
5
5
  BASE: '',
6
- VERSION: '20260427.1',
6
+ VERSION: '20260428.2',
7
7
  WITH_CREDENTIALS: false,
8
8
  CREDENTIALS: 'include',
9
9
  TOKEN: undefined,
@@ -31,6 +31,7 @@ export type { BlockSeatsRequestDto } from './models/BlockSeatsRequestDto';
31
31
  export type { BookmarkResponseDto } from './models/BookmarkResponseDto';
32
32
  export type { BugReportRequestDto } from './models/BugReportRequestDto';
33
33
  export type { BulkCreateGiftCardRequestDto } from './models/BulkCreateGiftCardRequestDto';
34
+ export type { BulkEditCouponRequestDto } from './models/BulkEditCouponRequestDto';
34
35
  export type { BulkEditRequestDto } from './models/BulkEditRequestDto';
35
36
  export type { BuyerResponseDto } from './models/BuyerResponseDto';
36
37
  export type { CancelExchangeTicketRequestDto } from './models/CancelExchangeTicketRequestDto';
@@ -131,6 +132,7 @@ export type { HiddenCodeResponseDto } from './models/HiddenCodeResponseDto';
131
132
  export type { HoldChartSeatResponseDto } from './models/HoldChartSeatResponseDto';
132
133
  export type { HoldSeatDetailsResponseDto } from './models/HoldSeatDetailsResponseDto';
133
134
  export type { IconShowGroupResponseDto } from './models/IconShowGroupResponseDto';
135
+ export type { ImportFromEventRequestDto } from './models/ImportFromEventRequestDto';
134
136
  export type { InsertUpdateBlacklistBuyerRequestDto } from './models/InsertUpdateBlacklistBuyerRequestDto';
135
137
  export type { InterviewDetailDto } from './models/InterviewDetailDto';
136
138
  export type { InterviewDetailResponseDto } from './models/InterviewDetailResponseDto';
@@ -0,0 +1,16 @@
1
+ export type BulkEditCouponRequestDto = {
2
+ ids: Array<string>;
3
+ fields: Array<string>;
4
+ showId?: number;
5
+ showGroupId?: number;
6
+ showTypeId?: number;
7
+ minOrderSize?: number;
8
+ dateAllowed?: string;
9
+ dateExpires?: string;
10
+ type?: string;
11
+ amount?: number;
12
+ applyOrder?: string;
13
+ customLogicId?: number;
14
+ couponLogicId?: number;
15
+ seats?: number;
16
+ };
@@ -1,6 +1,6 @@
1
1
  export type BulkEditRequestDto = {
2
2
  ids: Array<string>;
3
- fields: Array<any[]>;
3
+ fields: Array<string>;
4
4
  maxUsesType: string;
5
5
  seat: number;
6
6
  dateAllowed: string;
@@ -0,0 +1,4 @@
1
+ export type ImportFromEventRequestDto = {
2
+ srcShowId: number;
3
+ targetShowId: number;
4
+ };
@@ -2,5 +2,5 @@ export type ReorderBookmarkRequestDto = {
2
2
  /**
3
3
  * Array of tool IDs in the new order
4
4
  */
5
- toolIds: Array<any[]>;
5
+ toolIds: Array<number>;
6
6
  };
@@ -11,6 +11,7 @@ import type { EmailDetailResponseDto } from '../models/EmailDetailResponseDto';
11
11
  import type { ExchangeShowDetailResponseDto } from '../models/ExchangeShowDetailResponseDto';
12
12
  import type { FilterShowsResponseDto } from '../models/FilterShowsResponseDto';
13
13
  import type { HoldChartSeatResponseDto } from '../models/HoldChartSeatResponseDto';
14
+ import type { ImportFromEventRequestDto } from '../models/ImportFromEventRequestDto';
14
15
  import type { RemoveReservationCodeRequestDto } from '../models/RemoveReservationCodeRequestDto';
15
16
  import type { RemoveSeatsRequestDto } from '../models/RemoveSeatsRequestDto';
16
17
  import type { ReservationCodeResponseDto } from '../models/ReservationCodeResponseDto';
@@ -194,6 +195,15 @@ export declare class FeaturesBlockedSeatsService {
194
195
  * @throws ApiError
195
196
  */
196
197
  static holdChartSeatTickets(xStudioId: string, showId: string, requestBody: BlockChartSeatRequestDto): CancelablePromise<HoldChartSeatResponseDto>;
198
+ /**
199
+ * Import blocked seats from another event
200
+ * Import all blocked seats from a source event to the target event
201
+ * @param xStudioId The ID of the studio
202
+ * @param requestBody Request body for importing seats from an event
203
+ * @returns SuccessResponse Seats imported successfully
204
+ * @throws ApiError
205
+ */
206
+ static importFromEvent(xStudioId: string, requestBody: ImportFromEventRequestDto): CancelablePromise<SuccessResponse>;
197
207
  /**
198
208
  * Release the selected seat
199
209
  * Release the selected seat
@@ -375,6 +375,25 @@ class FeaturesBlockedSeatsService {
375
375
  mediaType: 'application/json',
376
376
  });
377
377
  }
378
+ /**
379
+ * Import blocked seats from another event
380
+ * Import all blocked seats from a source event to the target event
381
+ * @param xStudioId The ID of the studio
382
+ * @param requestBody Request body for importing seats from an event
383
+ * @returns SuccessResponse Seats imported successfully
384
+ * @throws ApiError
385
+ */
386
+ static importFromEvent(xStudioId, requestBody) {
387
+ return (0, request_1.request)(OpenAPI_1.OpenAPI, {
388
+ method: 'POST',
389
+ url: '/features/blocked-seats/import-from-event',
390
+ headers: {
391
+ 'x-studio-id': xStudioId,
392
+ },
393
+ body: requestBody,
394
+ mediaType: 'application/json',
395
+ });
396
+ }
378
397
  /**
379
398
  * Release the selected seat
380
399
  * Release the selected seat
@@ -1,3 +1,4 @@
1
+ import type { BulkEditCouponRequestDto } from '../models/BulkEditCouponRequestDto';
1
2
  import type { CouponDataResponseDto } from '../models/CouponDataResponseDto';
2
3
  import type { CouponDetailResponseDto } from '../models/CouponDetailResponseDto';
3
4
  import type { CouponFilterResponseDto } from '../models/CouponFilterResponseDto';
@@ -109,6 +110,15 @@ export declare class FeaturesDiscountsService {
109
110
  * @throws ApiError
110
111
  */
111
112
  static updateCode(xStudioId: string, requestBody: UpdateDiscountCodeRequestDto): CancelablePromise<SuccessResponse>;
113
+ /**
114
+ * Bulk edit coupon codes
115
+ * Bulk edit multiple coupon codes
116
+ * @param xStudioId The ID of the studio
117
+ * @param requestBody Request body for bulk editing coupons
118
+ * @returns SuccessResponse Coupon codes updated successfully
119
+ * @throws ApiError
120
+ */
121
+ static bulkEditCoupons(xStudioId: string, requestBody: BulkEditCouponRequestDto): CancelablePromise<SuccessResponse>;
112
122
  /**
113
123
  * Expire a group code
114
124
  * Expire a group code for the studio
@@ -207,6 +207,25 @@ class FeaturesDiscountsService {
207
207
  mediaType: 'application/json',
208
208
  });
209
209
  }
210
+ /**
211
+ * Bulk edit coupon codes
212
+ * Bulk edit multiple coupon codes
213
+ * @param xStudioId The ID of the studio
214
+ * @param requestBody Request body for bulk editing coupons
215
+ * @returns SuccessResponse Coupon codes updated successfully
216
+ * @throws ApiError
217
+ */
218
+ static bulkEditCoupons(xStudioId, requestBody) {
219
+ return (0, request_1.request)(OpenAPI_1.OpenAPI, {
220
+ method: 'PUT',
221
+ url: '/features/discounts/bulk-edit',
222
+ headers: {
223
+ 'x-studio-id': xStudioId,
224
+ },
225
+ body: requestBody,
226
+ mediaType: 'application/json',
227
+ });
228
+ }
210
229
  /**
211
230
  * Expire a group code
212
231
  * Expire a group code for the studio
@@ -27,6 +27,7 @@ export type { BlockSeatsRequestDto } from './models/BlockSeatsRequestDto';
27
27
  export type { BookmarkResponseDto } from './models/BookmarkResponseDto';
28
28
  export type { BugReportRequestDto } from './models/BugReportRequestDto';
29
29
  export type { BulkCreateGiftCardRequestDto } from './models/BulkCreateGiftCardRequestDto';
30
+ export type { BulkEditCouponRequestDto } from './models/BulkEditCouponRequestDto';
30
31
  export type { BulkEditRequestDto } from './models/BulkEditRequestDto';
31
32
  export type { BuyerResponseDto } from './models/BuyerResponseDto';
32
33
  export type { CancelExchangeTicketRequestDto } from './models/CancelExchangeTicketRequestDto';
@@ -127,6 +128,7 @@ export type { HiddenCodeResponseDto } from './models/HiddenCodeResponseDto';
127
128
  export type { HoldChartSeatResponseDto } from './models/HoldChartSeatResponseDto';
128
129
  export type { HoldSeatDetailsResponseDto } from './models/HoldSeatDetailsResponseDto';
129
130
  export type { IconShowGroupResponseDto } from './models/IconShowGroupResponseDto';
131
+ export type { ImportFromEventRequestDto } from './models/ImportFromEventRequestDto';
130
132
  export type { InsertUpdateBlacklistBuyerRequestDto } from './models/InsertUpdateBlacklistBuyerRequestDto';
131
133
  export type { InterviewDetailDto } from './models/InterviewDetailDto';
132
134
  export type { InterviewDetailResponseDto } from './models/InterviewDetailResponseDto';
@@ -13,6 +13,7 @@ if (!serviceName) {
13
13
  const GENERATED_INDEX = path_1.default.resolve(`src/generated/${serviceName}/index.ts`);
14
14
  const GENERATED_TYPES = path_1.default.resolve(`src/generated/${serviceName}/types.ts`);
15
15
  const OUTPUT_FILE = path_1.default.resolve(`src/definitions/${serviceName}.ts`);
16
+ const STAGING_OUTPUT_FILE = path_1.default.resolve(`src/staging/${serviceName}.ts`);
16
17
  if (!fs_1.default.existsSync(GENERATED_INDEX)) {
17
18
  console.error(`❌ File not found: ${GENERATED_INDEX}`);
18
19
  process.exit(1);
@@ -68,27 +69,27 @@ output += `// Re-export all types as a namespace\n`;
68
69
  output += `export * as ${typesNamespace} from "../generated/${serviceName}/types";\n`;
69
70
  fs_1.default.writeFileSync(OUTPUT_FILE, output);
70
71
  console.log(`✅ Wrote ${serviceName} definition to: ${OUTPUT_FILE}`);
71
- // If generating the portal, also regenerate the staging portal definition
72
- if (serviceName === 'portal') {
73
- const STAGING_FILE = path_1.default.resolve('src/staging/portal.ts');
72
+ if (serviceName === 'portal' && services.length > 1) {
74
73
  const stagingImports = [
74
+ `// AUTO-GENERATED FILE – DO NOT EDIT`,
75
+ `// Staging portal services - wraps all portal services to use staging API`,
76
+ '',
75
77
  `import { OpenAPI as PortalOpenAPI } from "../generated/portal/core/OpenAPI";`,
76
78
  `import { wrapServiceForStaging, STAGING_URLS } from "./wrapService";`,
77
- ``,
78
- ...services.map((s) => `import { ${s} } from "../generated/portal";`),
79
+ '',
80
+ ...services.map((service) => `import { ${service} } from "../generated/${serviceName}";`),
81
+ '',
82
+ `const wrap = <T extends object>(service: T) =>`,
83
+ `\twrapServiceForStaging(service, PortalOpenAPI, STAGING_URLS.portal);`,
84
+ '',
85
+ `export const portalStaging = {`,
86
+ ...services.map((service) => `\t${service.replace('Service', '').toLowerCase()}: wrap(${service}),`),
87
+ `};`,
88
+ '',
89
+ `// Re-export types`,
90
+ `export * as PortalTypes from "../generated/${serviceName}/types";`,
91
+ '',
79
92
  ];
80
- const stagingKeys = services
81
- .map((s) => `\t${s.replace('Service', '').toLowerCase()}: wrap(${s}),`)
82
- .join('\n');
83
- let stagingOutput = `// AUTO-GENERATED FILE – DO NOT EDIT\n\n`;
84
- stagingOutput += stagingImports.join('\n') + '\n\n';
85
- stagingOutput += `const wrap = <T extends object>(service: T) =>\n`;
86
- stagingOutput += `\twrapServiceForStaging(service, PortalOpenAPI, STAGING_URLS.portal);\n\n`;
87
- stagingOutput += `export const portalStaging = {\n`;
88
- stagingOutput += stagingKeys + '\n';
89
- stagingOutput += `};\n\n`;
90
- stagingOutput += `// Re-export types\n`;
91
- stagingOutput += `export * as PortalTypes from "../generated/portal/types";\n`;
92
- fs_1.default.writeFileSync(STAGING_FILE, stagingOutput);
93
- console.log(`✅ Wrote staging portal definition to: ${STAGING_FILE}`);
93
+ fs_1.default.writeFileSync(STAGING_OUTPUT_FILE, stagingImports.join('\n'));
94
+ console.log(`✅ Wrote ${serviceName} staging definition to: ${STAGING_OUTPUT_FILE}`);
94
95
  }
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  // AUTO-GENERATED FILE – DO NOT EDIT
3
+ // Staging portal services - wraps all portal services to use staging API
3
4
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
5
  if (k2 === undefined) k2 = k;
5
6
  var desc = Object.getOwnPropertyDescriptor(m, k);
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "module"
3
+ }
@@ -1,6 +1,6 @@
1
1
  export const OpenAPI = {
2
2
  BASE: '',
3
- VERSION: '20260427.1',
3
+ VERSION: '20260428.2',
4
4
  WITH_CREDENTIALS: false,
5
5
  CREDENTIALS: 'include',
6
6
  TOKEN: undefined,
@@ -31,6 +31,7 @@ export type { BlockSeatsRequestDto } from './models/BlockSeatsRequestDto';
31
31
  export type { BookmarkResponseDto } from './models/BookmarkResponseDto';
32
32
  export type { BugReportRequestDto } from './models/BugReportRequestDto';
33
33
  export type { BulkCreateGiftCardRequestDto } from './models/BulkCreateGiftCardRequestDto';
34
+ export type { BulkEditCouponRequestDto } from './models/BulkEditCouponRequestDto';
34
35
  export type { BulkEditRequestDto } from './models/BulkEditRequestDto';
35
36
  export type { BuyerResponseDto } from './models/BuyerResponseDto';
36
37
  export type { CancelExchangeTicketRequestDto } from './models/CancelExchangeTicketRequestDto';
@@ -131,6 +132,7 @@ export type { HiddenCodeResponseDto } from './models/HiddenCodeResponseDto';
131
132
  export type { HoldChartSeatResponseDto } from './models/HoldChartSeatResponseDto';
132
133
  export type { HoldSeatDetailsResponseDto } from './models/HoldSeatDetailsResponseDto';
133
134
  export type { IconShowGroupResponseDto } from './models/IconShowGroupResponseDto';
135
+ export type { ImportFromEventRequestDto } from './models/ImportFromEventRequestDto';
134
136
  export type { InsertUpdateBlacklistBuyerRequestDto } from './models/InsertUpdateBlacklistBuyerRequestDto';
135
137
  export type { InterviewDetailDto } from './models/InterviewDetailDto';
136
138
  export type { InterviewDetailResponseDto } from './models/InterviewDetailResponseDto';
@@ -0,0 +1,16 @@
1
+ export type BulkEditCouponRequestDto = {
2
+ ids: Array<string>;
3
+ fields: Array<string>;
4
+ showId?: number;
5
+ showGroupId?: number;
6
+ showTypeId?: number;
7
+ minOrderSize?: number;
8
+ dateAllowed?: string;
9
+ dateExpires?: string;
10
+ type?: string;
11
+ amount?: number;
12
+ applyOrder?: string;
13
+ customLogicId?: number;
14
+ couponLogicId?: number;
15
+ seats?: number;
16
+ };
@@ -1,6 +1,6 @@
1
1
  export type BulkEditRequestDto = {
2
2
  ids: Array<string>;
3
- fields: Array<any[]>;
3
+ fields: Array<string>;
4
4
  maxUsesType: string;
5
5
  seat: number;
6
6
  dateAllowed: string;
@@ -0,0 +1,4 @@
1
+ export type ImportFromEventRequestDto = {
2
+ srcShowId: number;
3
+ targetShowId: number;
4
+ };
@@ -2,5 +2,5 @@ export type ReorderBookmarkRequestDto = {
2
2
  /**
3
3
  * Array of tool IDs in the new order
4
4
  */
5
- toolIds: Array<any[]>;
5
+ toolIds: Array<number>;
6
6
  };
@@ -11,6 +11,7 @@ import type { EmailDetailResponseDto } from '../models/EmailDetailResponseDto';
11
11
  import type { ExchangeShowDetailResponseDto } from '../models/ExchangeShowDetailResponseDto';
12
12
  import type { FilterShowsResponseDto } from '../models/FilterShowsResponseDto';
13
13
  import type { HoldChartSeatResponseDto } from '../models/HoldChartSeatResponseDto';
14
+ import type { ImportFromEventRequestDto } from '../models/ImportFromEventRequestDto';
14
15
  import type { RemoveReservationCodeRequestDto } from '../models/RemoveReservationCodeRequestDto';
15
16
  import type { RemoveSeatsRequestDto } from '../models/RemoveSeatsRequestDto';
16
17
  import type { ReservationCodeResponseDto } from '../models/ReservationCodeResponseDto';
@@ -194,6 +195,15 @@ export declare class FeaturesBlockedSeatsService {
194
195
  * @throws ApiError
195
196
  */
196
197
  static holdChartSeatTickets(xStudioId: string, showId: string, requestBody: BlockChartSeatRequestDto): CancelablePromise<HoldChartSeatResponseDto>;
198
+ /**
199
+ * Import blocked seats from another event
200
+ * Import all blocked seats from a source event to the target event
201
+ * @param xStudioId The ID of the studio
202
+ * @param requestBody Request body for importing seats from an event
203
+ * @returns SuccessResponse Seats imported successfully
204
+ * @throws ApiError
205
+ */
206
+ static importFromEvent(xStudioId: string, requestBody: ImportFromEventRequestDto): CancelablePromise<SuccessResponse>;
197
207
  /**
198
208
  * Release the selected seat
199
209
  * Release the selected seat
@@ -372,6 +372,25 @@ export class FeaturesBlockedSeatsService {
372
372
  mediaType: 'application/json',
373
373
  });
374
374
  }
375
+ /**
376
+ * Import blocked seats from another event
377
+ * Import all blocked seats from a source event to the target event
378
+ * @param xStudioId The ID of the studio
379
+ * @param requestBody Request body for importing seats from an event
380
+ * @returns SuccessResponse Seats imported successfully
381
+ * @throws ApiError
382
+ */
383
+ static importFromEvent(xStudioId, requestBody) {
384
+ return __request(OpenAPI, {
385
+ method: 'POST',
386
+ url: '/features/blocked-seats/import-from-event',
387
+ headers: {
388
+ 'x-studio-id': xStudioId,
389
+ },
390
+ body: requestBody,
391
+ mediaType: 'application/json',
392
+ });
393
+ }
375
394
  /**
376
395
  * Release the selected seat
377
396
  * Release the selected seat
@@ -1,3 +1,4 @@
1
+ import type { BulkEditCouponRequestDto } from '../models/BulkEditCouponRequestDto';
1
2
  import type { CouponDataResponseDto } from '../models/CouponDataResponseDto';
2
3
  import type { CouponDetailResponseDto } from '../models/CouponDetailResponseDto';
3
4
  import type { CouponFilterResponseDto } from '../models/CouponFilterResponseDto';
@@ -109,6 +110,15 @@ export declare class FeaturesDiscountsService {
109
110
  * @throws ApiError
110
111
  */
111
112
  static updateCode(xStudioId: string, requestBody: UpdateDiscountCodeRequestDto): CancelablePromise<SuccessResponse>;
113
+ /**
114
+ * Bulk edit coupon codes
115
+ * Bulk edit multiple coupon codes
116
+ * @param xStudioId The ID of the studio
117
+ * @param requestBody Request body for bulk editing coupons
118
+ * @returns SuccessResponse Coupon codes updated successfully
119
+ * @throws ApiError
120
+ */
121
+ static bulkEditCoupons(xStudioId: string, requestBody: BulkEditCouponRequestDto): CancelablePromise<SuccessResponse>;
112
122
  /**
113
123
  * Expire a group code
114
124
  * Expire a group code for the studio
@@ -204,6 +204,25 @@ export class FeaturesDiscountsService {
204
204
  mediaType: 'application/json',
205
205
  });
206
206
  }
207
+ /**
208
+ * Bulk edit coupon codes
209
+ * Bulk edit multiple coupon codes
210
+ * @param xStudioId The ID of the studio
211
+ * @param requestBody Request body for bulk editing coupons
212
+ * @returns SuccessResponse Coupon codes updated successfully
213
+ * @throws ApiError
214
+ */
215
+ static bulkEditCoupons(xStudioId, requestBody) {
216
+ return __request(OpenAPI, {
217
+ method: 'PUT',
218
+ url: '/features/discounts/bulk-edit',
219
+ headers: {
220
+ 'x-studio-id': xStudioId,
221
+ },
222
+ body: requestBody,
223
+ mediaType: 'application/json',
224
+ });
225
+ }
207
226
  /**
208
227
  * Expire a group code
209
228
  * Expire a group code for the studio
@@ -27,6 +27,7 @@ export type { BlockSeatsRequestDto } from './models/BlockSeatsRequestDto';
27
27
  export type { BookmarkResponseDto } from './models/BookmarkResponseDto';
28
28
  export type { BugReportRequestDto } from './models/BugReportRequestDto';
29
29
  export type { BulkCreateGiftCardRequestDto } from './models/BulkCreateGiftCardRequestDto';
30
+ export type { BulkEditCouponRequestDto } from './models/BulkEditCouponRequestDto';
30
31
  export type { BulkEditRequestDto } from './models/BulkEditRequestDto';
31
32
  export type { BuyerResponseDto } from './models/BuyerResponseDto';
32
33
  export type { CancelExchangeTicketRequestDto } from './models/CancelExchangeTicketRequestDto';
@@ -127,6 +128,7 @@ export type { HiddenCodeResponseDto } from './models/HiddenCodeResponseDto';
127
128
  export type { HoldChartSeatResponseDto } from './models/HoldChartSeatResponseDto';
128
129
  export type { HoldSeatDetailsResponseDto } from './models/HoldSeatDetailsResponseDto';
129
130
  export type { IconShowGroupResponseDto } from './models/IconShowGroupResponseDto';
131
+ export type { ImportFromEventRequestDto } from './models/ImportFromEventRequestDto';
130
132
  export type { InsertUpdateBlacklistBuyerRequestDto } from './models/InsertUpdateBlacklistBuyerRequestDto';
131
133
  export type { InterviewDetailDto } from './models/InterviewDetailDto';
132
134
  export type { InterviewDetailResponseDto } from './models/InterviewDetailResponseDto';
@@ -8,6 +8,7 @@ if (!serviceName) {
8
8
  const GENERATED_INDEX = path.resolve(`src/generated/${serviceName}/index.ts`);
9
9
  const GENERATED_TYPES = path.resolve(`src/generated/${serviceName}/types.ts`);
10
10
  const OUTPUT_FILE = path.resolve(`src/definitions/${serviceName}.ts`);
11
+ const STAGING_OUTPUT_FILE = path.resolve(`src/staging/${serviceName}.ts`);
11
12
  if (!fs.existsSync(GENERATED_INDEX)) {
12
13
  console.error(`❌ File not found: ${GENERATED_INDEX}`);
13
14
  process.exit(1);
@@ -63,27 +64,27 @@ output += `// Re-export all types as a namespace\n`;
63
64
  output += `export * as ${typesNamespace} from "../generated/${serviceName}/types.js";\n`;
64
65
  fs.writeFileSync(OUTPUT_FILE, output);
65
66
  console.log(`✅ Wrote ${serviceName} definition to: ${OUTPUT_FILE}`);
66
- // If generating the portal, also regenerate the staging portal definition
67
- if (serviceName === 'portal') {
68
- const STAGING_FILE = path.resolve('src/staging/portal.ts');
67
+ if (serviceName === 'portal' && services.length > 1) {
69
68
  const stagingImports = [
69
+ `// AUTO-GENERATED FILE – DO NOT EDIT`,
70
+ `// Staging portal services - wraps all portal services to use staging API`,
71
+ '',
70
72
  `import { OpenAPI as PortalOpenAPI } from "../generated/portal/core/OpenAPI.js";`,
71
73
  `import { wrapServiceForStaging, STAGING_URLS } from "./wrapService.js";`,
72
- ``,
73
- ...services.map((s) => `import { ${s} } from "../generated/portal/index.js";`),
74
+ '',
75
+ ...services.map((service) => `import { ${service} } from "../generated/${serviceName}.js";`),
76
+ '',
77
+ `const wrap = <T extends object>(service: T) =>`,
78
+ `\twrapServiceForStaging(service, PortalOpenAPI, STAGING_URLS.portal);`,
79
+ '',
80
+ `export const portalStaging = {`,
81
+ ...services.map((service) => `\t${service.replace('Service', '').toLowerCase()}: wrap(${service}),`),
82
+ `};`,
83
+ '',
84
+ `// Re-export types`,
85
+ `export * as PortalTypes from "../generated/${serviceName}/types.js";`,
86
+ '',
74
87
  ];
75
- const stagingKeys = services
76
- .map((s) => `\t${s.replace('Service', '').toLowerCase()}: wrap(${s}),`)
77
- .join('\n');
78
- let stagingOutput = `// AUTO-GENERATED FILE – DO NOT EDIT\n\n`;
79
- stagingOutput += stagingImports.join('\n') + '\n\n';
80
- stagingOutput += `const wrap = <T extends object>(service: T) =>\n`;
81
- stagingOutput += `\twrapServiceForStaging(service, PortalOpenAPI, STAGING_URLS.portal);\n\n`;
82
- stagingOutput += `export const portalStaging = {\n`;
83
- stagingOutput += stagingKeys + '\n';
84
- stagingOutput += `};\n\n`;
85
- stagingOutput += `// Re-export types\n`;
86
- stagingOutput += `export * as PortalTypes from "../generated/portal/types.js";\n`;
87
- fs.writeFileSync(STAGING_FILE, stagingOutput);
88
- console.log(`✅ Wrote staging portal definition to: ${STAGING_FILE}`);
88
+ fs.writeFileSync(STAGING_OUTPUT_FILE, stagingImports.join('\n'));
89
+ console.log(`✅ Wrote ${serviceName} staging definition to: ${STAGING_OUTPUT_FILE}`);
89
90
  }
@@ -1,4 +1,5 @@
1
1
  // AUTO-GENERATED FILE – DO NOT EDIT
2
+ // Staging portal services - wraps all portal services to use staging API
2
3
  import { OpenAPI as PortalOpenAPI } from "../generated/portal/core/OpenAPI.js";
3
4
  import { wrapServiceForStaging, STAGING_URLS } from "./wrapService.js";
4
5
  import { AccountService } from "../generated/portal/index.js";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@drttix/drt-sdk",
3
3
  "description": "DRT SDK",
4
- "version": "1.0.6",
4
+ "version": "1.0.8",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",
7
7
  "types": "dist/esm/index.d.ts",
@@ -30,11 +30,11 @@
30
30
  "prepublishOnly": "npx tsx src/scripts/check-version-not-published.ts && npm run build"
31
31
  },
32
32
  "devDependencies": {
33
- "@types/node": "^24.0.4",
33
+ "@types/node": "^24.12.2",
34
34
  "esbuild": "^0.20.0",
35
35
  "typescript": "^5.8.3"
36
36
  },
37
37
  "dependencies": {
38
- "@drttix/drt-sdk": "^0.2.9"
38
+ "@drttix/drt-sdk": "^0.2.91"
39
39
  }
40
40
  }
@@ -78,6 +78,22 @@ async function main() {
78
78
  await fixFile(rootIndex);
79
79
 
80
80
  await walk(root);
81
+
82
+ // Mark the ESM output tree as a module package. The SDK root package
83
+ // stays `type: commonjs` so the CJS build continues to work, but the
84
+ // `exports.import` entry points into `dist/esm/*.js`. Without a nested
85
+ // package.json here, tools like Next treat those `.js` files as CJS and
86
+ // reject the ESM syntax.
87
+ const esmPackageJson = path.resolve(
88
+ process.cwd(),
89
+ 'dist/esm/package.json',
90
+ );
91
+ await fs.writeFile(
92
+ esmPackageJson,
93
+ `${JSON.stringify({ type: 'module' }, null, 2)}\n`,
94
+ 'utf8',
95
+ );
96
+
81
97
  console.log('Done.');
82
98
  } catch (err) {
83
99
  console.error(err);
@@ -21,7 +21,7 @@ export type OpenAPIConfig = {
21
21
 
22
22
  export const OpenAPI: OpenAPIConfig = {
23
23
  BASE: '',
24
- VERSION: '20260427.1',
24
+ VERSION: '20260428.2',
25
25
  WITH_CREDENTIALS: false,
26
26
  CREDENTIALS: 'include',
27
27
  TOKEN: undefined,
@@ -36,6 +36,7 @@ export type { BlockSeatsRequestDto } from './models/BlockSeatsRequestDto';
36
36
  export type { BookmarkResponseDto } from './models/BookmarkResponseDto';
37
37
  export type { BugReportRequestDto } from './models/BugReportRequestDto';
38
38
  export type { BulkCreateGiftCardRequestDto } from './models/BulkCreateGiftCardRequestDto';
39
+ export type { BulkEditCouponRequestDto } from './models/BulkEditCouponRequestDto';
39
40
  export type { BulkEditRequestDto } from './models/BulkEditRequestDto';
40
41
  export type { BuyerResponseDto } from './models/BuyerResponseDto';
41
42
  export type { CancelExchangeTicketRequestDto } from './models/CancelExchangeTicketRequestDto';
@@ -136,6 +137,7 @@ export type { HiddenCodeResponseDto } from './models/HiddenCodeResponseDto';
136
137
  export type { HoldChartSeatResponseDto } from './models/HoldChartSeatResponseDto';
137
138
  export type { HoldSeatDetailsResponseDto } from './models/HoldSeatDetailsResponseDto';
138
139
  export type { IconShowGroupResponseDto } from './models/IconShowGroupResponseDto';
140
+ export type { ImportFromEventRequestDto } from './models/ImportFromEventRequestDto';
139
141
  export type { InsertUpdateBlacklistBuyerRequestDto } from './models/InsertUpdateBlacklistBuyerRequestDto';
140
142
  export type { InterviewDetailDto } from './models/InterviewDetailDto';
141
143
  export type { InterviewDetailResponseDto } from './models/InterviewDetailResponseDto';
@@ -0,0 +1,21 @@
1
+ /* generated using openapi-typescript-codegen -- do not edit */
2
+ /* istanbul ignore file */
3
+ /* tslint:disable */
4
+ /* eslint-disable */
5
+ export type BulkEditCouponRequestDto = {
6
+ ids: Array<string>;
7
+ fields: Array<string>;
8
+ showId?: number;
9
+ showGroupId?: number;
10
+ showTypeId?: number;
11
+ minOrderSize?: number;
12
+ dateAllowed?: string;
13
+ dateExpires?: string;
14
+ type?: string;
15
+ amount?: number;
16
+ applyOrder?: string;
17
+ customLogicId?: number;
18
+ couponLogicId?: number;
19
+ seats?: number;
20
+ };
21
+
@@ -4,7 +4,7 @@
4
4
  /* eslint-disable */
5
5
  export type BulkEditRequestDto = {
6
6
  ids: Array<string>;
7
- fields: Array<any[]>;
7
+ fields: Array<string>;
8
8
  maxUsesType: string;
9
9
  seat: number;
10
10
  dateAllowed: string;
@@ -0,0 +1,9 @@
1
+ /* generated using openapi-typescript-codegen -- do not edit */
2
+ /* istanbul ignore file */
3
+ /* tslint:disable */
4
+ /* eslint-disable */
5
+ export type ImportFromEventRequestDto = {
6
+ srcShowId: number;
7
+ targetShowId: number;
8
+ };
9
+
@@ -6,6 +6,6 @@ export type ReorderBookmarkRequestDto = {
6
6
  /**
7
7
  * Array of tool IDs in the new order
8
8
  */
9
- toolIds: Array<any[]>;
9
+ toolIds: Array<number>;
10
10
  };
11
11
 
@@ -15,6 +15,7 @@ import type { EmailDetailResponseDto } from '../models/EmailDetailResponseDto';
15
15
  import type { ExchangeShowDetailResponseDto } from '../models/ExchangeShowDetailResponseDto';
16
16
  import type { FilterShowsResponseDto } from '../models/FilterShowsResponseDto';
17
17
  import type { HoldChartSeatResponseDto } from '../models/HoldChartSeatResponseDto';
18
+ import type { ImportFromEventRequestDto } from '../models/ImportFromEventRequestDto';
18
19
  import type { RemoveReservationCodeRequestDto } from '../models/RemoveReservationCodeRequestDto';
19
20
  import type { RemoveSeatsRequestDto } from '../models/RemoveSeatsRequestDto';
20
21
  import type { ReservationCodeResponseDto } from '../models/ReservationCodeResponseDto';
@@ -457,6 +458,28 @@ export class FeaturesBlockedSeatsService {
457
458
  mediaType: 'application/json',
458
459
  });
459
460
  }
461
+ /**
462
+ * Import blocked seats from another event
463
+ * Import all blocked seats from a source event to the target event
464
+ * @param xStudioId The ID of the studio
465
+ * @param requestBody Request body for importing seats from an event
466
+ * @returns SuccessResponse Seats imported successfully
467
+ * @throws ApiError
468
+ */
469
+ public static importFromEvent(
470
+ xStudioId: string,
471
+ requestBody: ImportFromEventRequestDto,
472
+ ): CancelablePromise<SuccessResponse> {
473
+ return __request(OpenAPI, {
474
+ method: 'POST',
475
+ url: '/features/blocked-seats/import-from-event',
476
+ headers: {
477
+ 'x-studio-id': xStudioId,
478
+ },
479
+ body: requestBody,
480
+ mediaType: 'application/json',
481
+ });
482
+ }
460
483
  /**
461
484
  * Release the selected seat
462
485
  * Release the selected seat
@@ -2,6 +2,7 @@
2
2
  /* istanbul ignore file */
3
3
  /* tslint:disable */
4
4
  /* eslint-disable */
5
+ import type { BulkEditCouponRequestDto } from '../models/BulkEditCouponRequestDto';
5
6
  import type { CouponDataResponseDto } from '../models/CouponDataResponseDto';
6
7
  import type { CouponDetailResponseDto } from '../models/CouponDetailResponseDto';
7
8
  import type { CouponFilterResponseDto } from '../models/CouponFilterResponseDto';
@@ -252,6 +253,28 @@ export class FeaturesDiscountsService {
252
253
  mediaType: 'application/json',
253
254
  });
254
255
  }
256
+ /**
257
+ * Bulk edit coupon codes
258
+ * Bulk edit multiple coupon codes
259
+ * @param xStudioId The ID of the studio
260
+ * @param requestBody Request body for bulk editing coupons
261
+ * @returns SuccessResponse Coupon codes updated successfully
262
+ * @throws ApiError
263
+ */
264
+ public static bulkEditCoupons(
265
+ xStudioId: string,
266
+ requestBody: BulkEditCouponRequestDto,
267
+ ): CancelablePromise<SuccessResponse> {
268
+ return __request(OpenAPI, {
269
+ method: 'PUT',
270
+ url: '/features/discounts/bulk-edit',
271
+ headers: {
272
+ 'x-studio-id': xStudioId,
273
+ },
274
+ body: requestBody,
275
+ mediaType: 'application/json',
276
+ });
277
+ }
255
278
  /**
256
279
  * Expire a group code
257
280
  * Expire a group code for the studio
@@ -30,6 +30,7 @@ export type { BlockSeatsRequestDto } from './models/BlockSeatsRequestDto';
30
30
  export type { BookmarkResponseDto } from './models/BookmarkResponseDto';
31
31
  export type { BugReportRequestDto } from './models/BugReportRequestDto';
32
32
  export type { BulkCreateGiftCardRequestDto } from './models/BulkCreateGiftCardRequestDto';
33
+ export type { BulkEditCouponRequestDto } from './models/BulkEditCouponRequestDto';
33
34
  export type { BulkEditRequestDto } from './models/BulkEditRequestDto';
34
35
  export type { BuyerResponseDto } from './models/BuyerResponseDto';
35
36
  export type { CancelExchangeTicketRequestDto } from './models/CancelExchangeTicketRequestDto';
@@ -130,6 +131,7 @@ export type { HiddenCodeResponseDto } from './models/HiddenCodeResponseDto';
130
131
  export type { HoldChartSeatResponseDto } from './models/HoldChartSeatResponseDto';
131
132
  export type { HoldSeatDetailsResponseDto } from './models/HoldSeatDetailsResponseDto';
132
133
  export type { IconShowGroupResponseDto } from './models/IconShowGroupResponseDto';
134
+ export type { ImportFromEventRequestDto } from './models/ImportFromEventRequestDto';
133
135
  export type { InsertUpdateBlacklistBuyerRequestDto } from './models/InsertUpdateBlacklistBuyerRequestDto';
134
136
  export type { InterviewDetailDto } from './models/InterviewDetailDto';
135
137
  export type { InterviewDetailResponseDto } from './models/InterviewDetailResponseDto';
@@ -5,7 +5,7 @@ const [, , serviceName] = process.argv;
5
5
 
6
6
  if (!serviceName) {
7
7
  console.error(
8
- '❌ Please provide a service name as an argument (e.g., "shopper")'
8
+ '❌ Please provide a service name as an argument (e.g., "shopper")',
9
9
  );
10
10
  process.exit(1);
11
11
  }
@@ -13,6 +13,7 @@ if (!serviceName) {
13
13
  const GENERATED_INDEX = path.resolve(`src/generated/${serviceName}/index.ts`);
14
14
  const GENERATED_TYPES = path.resolve(`src/generated/${serviceName}/types.ts`);
15
15
  const OUTPUT_FILE = path.resolve(`src/definitions/${serviceName}.ts`);
16
+ const STAGING_OUTPUT_FILE = path.resolve(`src/staging/${serviceName}.ts`);
16
17
 
17
18
  if (!fs.existsSync(GENERATED_INDEX)) {
18
19
  console.error(`❌ File not found: ${GENERATED_INDEX}`);
@@ -37,13 +38,13 @@ const services = exportLines
37
38
  const typeLines = contents
38
39
  .split('\n')
39
40
  .filter(
40
- (line) => line.startsWith('export type {') && line.includes('models')
41
+ (line) => line.startsWith('export type {') && line.includes('models'),
41
42
  );
42
43
 
43
44
  const typeExports = typeLines
44
45
  .map((line) => {
45
46
  const match = line.match(
46
- /export type { (\w+) } from '\.\/models\/(\w+)'/
47
+ /export type { (\w+) } from '\.\/models\/(\w+)'/,
47
48
  );
48
49
  if (match) {
49
50
  return `export type { ${match[1]} } from './models/${match[2]}';`;
@@ -60,7 +61,7 @@ fs.writeFileSync(GENERATED_TYPES, typesOutput);
60
61
  console.log(`✅ Wrote types to: ${GENERATED_TYPES}`);
61
62
 
62
63
  const imports = services.map(
63
- (service) => `import { ${service} } from "../generated/${serviceName}";`
64
+ (service) => `import { ${service} } from "../generated/${serviceName}";`,
64
65
  );
65
66
 
66
67
  const objectName = serviceName.toLowerCase();
@@ -88,31 +89,36 @@ output += `export * as ${typesNamespace} from "../generated/${serviceName}/types
88
89
  fs.writeFileSync(OUTPUT_FILE, output);
89
90
  console.log(`✅ Wrote ${serviceName} definition to: ${OUTPUT_FILE}`);
90
91
 
91
- // If generating the portal, also regenerate the staging portal definition
92
- if (serviceName === 'portal') {
93
- const STAGING_FILE = path.resolve('src/staging/portal.ts');
94
-
92
+ if (serviceName === 'portal' && services.length > 1) {
95
93
  const stagingImports = [
94
+ `// AUTO-GENERATED FILE – DO NOT EDIT`,
95
+ `// Staging portal services - wraps all portal services to use staging API`,
96
+ '',
96
97
  `import { OpenAPI as PortalOpenAPI } from "../generated/portal/core/OpenAPI";`,
97
98
  `import { wrapServiceForStaging, STAGING_URLS } from "./wrapService";`,
98
- ``,
99
- ...services.map((s) => `import { ${s} } from "../generated/portal";`),
99
+ '',
100
+ ...services.map(
101
+ (service) =>
102
+ `import { ${service} } from "../generated/${serviceName}";`,
103
+ ),
104
+ '',
105
+ `const wrap = <T extends object>(service: T) =>`,
106
+ `\twrapServiceForStaging(service, PortalOpenAPI, STAGING_URLS.portal);`,
107
+ '',
108
+ `export const portalStaging = {`,
109
+ ...services.map(
110
+ (service) =>
111
+ `\t${service.replace('Service', '').toLowerCase()}: wrap(${service}),`,
112
+ ),
113
+ `};`,
114
+ '',
115
+ `// Re-export types`,
116
+ `export * as PortalTypes from "../generated/${serviceName}/types";`,
117
+ '',
100
118
  ];
101
119
 
102
- const stagingKeys = services
103
- .map((s) => `\t${s.replace('Service', '').toLowerCase()}: wrap(${s}),`)
104
- .join('\n');
105
-
106
- let stagingOutput = `// AUTO-GENERATED FILE – DO NOT EDIT\n\n`;
107
- stagingOutput += stagingImports.join('\n') + '\n\n';
108
- stagingOutput += `const wrap = <T extends object>(service: T) =>\n`;
109
- stagingOutput += `\twrapServiceForStaging(service, PortalOpenAPI, STAGING_URLS.portal);\n\n`;
110
- stagingOutput += `export const portalStaging = {\n`;
111
- stagingOutput += stagingKeys + '\n';
112
- stagingOutput += `};\n\n`;
113
- stagingOutput += `// Re-export types\n`;
114
- stagingOutput += `export * as PortalTypes from "../generated/portal/types";\n`;
115
-
116
- fs.writeFileSync(STAGING_FILE, stagingOutput);
117
- console.log(`✅ Wrote staging portal definition to: ${STAGING_FILE}`);
120
+ fs.writeFileSync(STAGING_OUTPUT_FILE, stagingImports.join('\n'));
121
+ console.log(
122
+ `✅ Wrote ${serviceName} staging definition to: ${STAGING_OUTPUT_FILE}`,
123
+ );
118
124
  }
@@ -1,4 +1,5 @@
1
1
  // AUTO-GENERATED FILE – DO NOT EDIT
2
+ // Staging portal services - wraps all portal services to use staging API
2
3
 
3
4
  import { OpenAPI as PortalOpenAPI } from "../generated/portal/core/OpenAPI";
4
5
  import { wrapServiceForStaging, STAGING_URLS } from "./wrapService";
@@ -1,149 +0,0 @@
1
- import {
2
- ForbiddenException,
3
- Injectable,
4
- Logger,
5
- NestMiddleware,
6
- UnauthorizedException,
7
- } from '@nestjs/common';
8
- import { NextFunction, Request, Response } from 'express';
9
- import { ErrorCode } from '../shared/consts/errorCodes';
10
- import { EXCEPTION_PATHS, HEADER_STUDIO_KEY } from '../shared/consts/values';
11
- import { MssqlService } from '../database/mssql/services/mssql.service';
12
- import { CacheService } from '../shared/service/cache.service';
13
- import { CommonService } from '../shared/service/common.service';
14
- import { DRT } from '@drttix/drt-api';
15
-
16
- @Injectable()
17
- export class AuthMiddleware implements NestMiddleware {
18
- constructor(
19
- private readonly msSqlService: MssqlService,
20
- private readonly cacheService: CacheService,
21
- private readonly commonService: CommonService,
22
- private readonly logger: Logger,
23
- ) {}
24
-
25
- async use(req: Request, res: Response, next: NextFunction): Promise<void> {
26
- const headerStudioId = Number(req.headers[HEADER_STUDIO_KEY]);
27
-
28
- if (!headerStudioId) {
29
- throw new UnauthorizedException(ErrorCode.MISSING_STUDIO_ID);
30
- }
31
-
32
- const shopperGuidKey =
33
- this.commonService.formatShopperGuid(headerStudioId);
34
-
35
- let shopperGuid = req.cookies[shopperGuidKey];
36
-
37
- if (!shopperGuid) {
38
- shopperGuid = this.commonService.getFormattedGuid();
39
- this.logger.log(
40
- `[Middleware] Generated NEW shopperGuid=${shopperGuid}`,
41
- );
42
- } else {
43
- this.logger.log(
44
- `[Middleware] Using EXISTING cookie shopperGuid=${shopperGuid}`,
45
- );
46
- }
47
-
48
- const clientIp = req.ip as string;
49
-
50
- try {
51
- await this.msSqlService.checkSession(
52
- headerStudioId,
53
- shopperGuid,
54
- clientIp,
55
- );
56
-
57
- // Call is here to seed the session service with the correct session.
58
- // TODO: Replace this and the above checkSession
59
- await DRT.session.getSession(shopperGuid, headerStudioId);
60
-
61
- this.setCookie(res, shopperGuidKey, shopperGuid);
62
- } catch (error) {
63
- this.logger.error(error);
64
- throw new UnauthorizedException(ErrorCode.UNAUTHORIZED);
65
- }
66
-
67
- // If the route is not in the exceptions list, validate the session and permissions
68
- this.logger.log(
69
- `[Middleware] req.baseUrl="${req.baseUrl}", req.path="${req.path}", req.originalUrl="${req.originalUrl}"`,
70
- );
71
- if (!EXCEPTION_PATHS.includes(req.baseUrl)) {
72
- const isValidLogin = await this.cacheService.checkStudioLogin(
73
- shopperGuid,
74
- Number(headerStudioId),
75
- );
76
-
77
- if (!isValidLogin) {
78
- throw new UnauthorizedException(ErrorCode.INVALID_LOGIN);
79
- }
80
-
81
- const isUserPrimary = await this.msSqlService.getPrimaryStatus(
82
- shopperGuid,
83
- Number(headerStudioId),
84
- );
85
-
86
- const isValid = await this.validateRoute(
87
- req.baseUrl,
88
- req.method,
89
- shopperGuid,
90
- isUserPrimary,
91
- );
92
-
93
- if (!isValid) {
94
- throw new ForbiddenException(ErrorCode.FORBIDDEN);
95
- }
96
- }
97
-
98
- req.cookies = { [`${shopperGuidKey}`]: shopperGuid };
99
- next();
100
- }
101
-
102
- setCookie(res: Response, key: string, value: string | number): void {
103
- res.cookie(key, value, {
104
- httpOnly: true,
105
- secure: true,
106
- sameSite: 'lax',
107
- path: '/',
108
- // eslint-disable-next-line no-magic-numbers
109
- maxAge: 60 * 60 * 24,
110
- });
111
- }
112
-
113
- async validateRoute(
114
- currentRoute: string,
115
- currentMethod: string,
116
- shopperGuid: string,
117
- isUserPrimary: number,
118
- ): Promise<boolean> {
119
- const cachedRoutes = await this.cacheService.getCachedRoutes();
120
- // Replace numbers in the route with a generic 'id'
121
- currentRoute = currentRoute.replace(/\d+/g, 'id');
122
-
123
- const routeMatch = cachedRoutes.find(
124
- route =>
125
- route.route === currentRoute && route.method === currentMethod,
126
- );
127
-
128
- if (!routeMatch) {
129
- return false;
130
- }
131
-
132
- if (routeMatch.primaryUserOnly === 1 && isUserPrimary !== 1) {
133
- return false;
134
- }
135
-
136
- if (routeMatch.rejectOnFail === 0) {
137
- return true;
138
- }
139
-
140
- const portalObjects =
141
- await this.cacheService.getUserPermissions(shopperGuid);
142
-
143
- if (portalObjects.some(item => item.id === routeMatch.portalObjectId)) {
144
- return true;
145
- }
146
-
147
- return false;
148
- }
149
- }
@@ -1,41 +0,0 @@
1
- import {
2
- ForbiddenException,
3
- Injectable,
4
- Logger,
5
- NestMiddleware,
6
- } from '@nestjs/common';
7
- import { NextFunction, Request, Response } from 'express';
8
- import { MssqlService } from '../database/mssql/services/mssql.service';
9
- import { ErrorCode } from '../shared/consts/errorCodes';
10
- import { HEADER_STUDIO_KEY } from '../shared/consts/values';
11
- import { CommonService } from '../shared/service/common.service';
12
-
13
- @Injectable()
14
- export class SuperUserMiddleware implements NestMiddleware {
15
- constructor(
16
- private readonly msSqlService: MssqlService,
17
- private readonly commonService: CommonService,
18
- private readonly logger: Logger,
19
- ) {}
20
-
21
- async use(req: Request, res: Response, next: NextFunction): Promise<void> {
22
- const headerStudioId = Number(req.headers[HEADER_STUDIO_KEY]);
23
-
24
- const shopperGuidKey =
25
- this.commonService.formatShopperGuid(headerStudioId);
26
-
27
- let shopperGuid = req.cookies[shopperGuidKey];
28
-
29
- const adminDetails =
30
- await this.msSqlService.getAdminDetails(shopperGuid);
31
-
32
- if (adminDetails.superuser !== 1) {
33
- this.logger.log(
34
- `Unauthorized access attempt to superuser route by shopperGuid: ${shopperGuid} on Studio: ${headerStudioId}`,
35
- );
36
- throw new ForbiddenException(ErrorCode.FORBIDDEN);
37
- }
38
-
39
- next();
40
- }
41
- }
@@ -1,9 +0,0 @@
1
- export type BlockedSeatDetail = {
2
- designation: Record<string, any>;
3
- section: string;
4
- row: string;
5
- seat: number;
6
- showName: string;
7
- isGeneralSeating: number;
8
- tierId: Record<string, any>;
9
- };
@@ -1,4 +0,0 @@
1
- export type OrderDetail = {
2
- id: number;
3
- dateCreated: string;
4
- };
@@ -1,9 +0,0 @@
1
- export type BlockedSeatDetail = {
2
- designation: Record<string, any>;
3
- section: string;
4
- row: string;
5
- seat: number;
6
- showName: string;
7
- isGeneralSeating: number;
8
- tierId: Record<string, any>;
9
- };
@@ -1,4 +0,0 @@
1
- export type OrderDetail = {
2
- id: number;
3
- dateCreated: string;
4
- };