@chevre/domain 28.0.0 → 28.1.0-alpha.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.
@@ -34,12 +34,6 @@ export declare class AdminAcceptedOfferRepo extends AcceptedOfferInReserveRepo {
34
34
  * 索条件を最小化(2026-06-05~)
35
35
  */
36
36
  params: Pick<factory.order.ISearchConditions, 'limit' | 'orderNumbers' | 'page' | 'project' | 'provider' | 'sort' | 'orderDate'>, projection: IProjection4searchWithUnwoundAcceptedOffers, options: {
37
- /**
38
- * reservationForをid属性のみにするオプション
39
- * 2026-08-31~
40
- * always true(2026-10-08~)
41
- */
42
- minimizeReservationFor: true;
43
37
  /**
44
38
  * reservedTicket以外の属性を除外するオプション
45
39
  * 2026-10-08~
@@ -67,17 +61,12 @@ export declare class AdminAcceptedOfferRepo extends AcceptedOfferInReserveRepo {
67
61
  id: string;
68
62
  };
69
63
  }, options: {
70
- /**
71
- * reservationForをid属性のみにするオプション
72
- * 2026-08-31~
73
- * always true(2026-10-08~)
74
- */
75
- minimizeReservationFor: true;
76
64
  /**
77
65
  * reservedTicket以外の属性を除外するオプション
78
66
  * 2026-10-08~
67
+ * always true(2026-10-23~)
79
68
  */
80
- onlyReservedTicket: boolean;
69
+ onlyReservedTicket: true;
81
70
  /**
82
71
  * reservedTicketからticketTypeを除外するオプション
83
72
  * 2026-10-23~
@@ -7,45 +7,40 @@ const settings_1 = require("../settings");
7
7
  const acceptedOfferInReserve_1 = require("./acceptedOfferInReserve");
8
8
  const order_2 = require("./order");
9
9
  function minimizeItemOffered(itemOffered, options) {
10
- const { minimizeReservationFor, onlyReservedTicket, minimizeReservedTicket } = options;
11
- if (minimizeReservationFor) {
12
- const { reservationFor, ...itemOfferedWithoutEvent } = itemOffered;
13
- if (onlyReservedTicket) {
14
- const { id, reservationNumber, reservedTicket } = itemOfferedWithoutEvent;
15
- // support minimizeReservedTicket(2026-10-23~)
16
- if (minimizeReservedTicket) {
17
- const { coaReserveAmount, coaTicketInfo, ticketToken, identifier, ticketedSeat } = reservedTicket;
18
- return {
19
- id, reservationNumber,
20
- reservedTicket: {
21
- typeOf: reservedTicket.typeOf,
22
- identifier,
23
- ...(typeof ticketedSeat?.typeOf === 'string') && { ticketedSeat },
24
- ...(coaReserveAmount !== undefined) && { coaReserveAmount },
25
- ...(coaTicketInfo !== undefined) && { coaTicketInfo },
26
- ...(typeof ticketToken === 'string') && { ticketToken },
27
- },
28
- typeOf: itemOfferedWithoutEvent.typeOf,
29
- reservationFor: { id: reservationFor.id, typeOf: reservationFor.typeOf }
30
- };
31
- }
32
- else {
33
- return {
34
- id, reservationNumber, reservedTicket,
35
- typeOf: itemOfferedWithoutEvent.typeOf,
36
- reservationFor: { id: reservationFor.id, typeOf: reservationFor.typeOf }
37
- };
38
- }
10
+ const { onlyReservedTicket, minimizeReservedTicket } = options;
11
+ const { reservationFor, ...itemOfferedWithoutEvent } = itemOffered;
12
+ if (onlyReservedTicket) {
13
+ const { id, reservationNumber, reservedTicket } = itemOfferedWithoutEvent;
14
+ // support minimizeReservedTicket(2026-10-23~)
15
+ if (minimizeReservedTicket) {
16
+ const { coaReserveAmount, coaTicketInfo, ticketToken, identifier, ticketedSeat } = reservedTicket;
17
+ return {
18
+ id, reservationNumber,
19
+ reservedTicket: {
20
+ typeOf: reservedTicket.typeOf,
21
+ identifier,
22
+ ...(typeof ticketedSeat?.typeOf === 'string') && { ticketedSeat },
23
+ ...(coaReserveAmount !== undefined) && { coaReserveAmount },
24
+ ...(coaTicketInfo !== undefined) && { coaTicketInfo },
25
+ ...(typeof ticketToken === 'string') && { ticketToken },
26
+ },
27
+ typeOf: itemOfferedWithoutEvent.typeOf,
28
+ reservationFor: { id: reservationFor.id, typeOf: reservationFor.typeOf }
29
+ };
39
30
  }
40
31
  else {
41
32
  return {
42
- ...itemOfferedWithoutEvent,
33
+ id, reservationNumber, reservedTicket,
34
+ typeOf: itemOfferedWithoutEvent.typeOf,
43
35
  reservationFor: { id: reservationFor.id, typeOf: reservationFor.typeOf }
44
36
  };
45
37
  }
46
38
  }
47
39
  else {
48
- return itemOffered;
40
+ return {
41
+ ...itemOfferedWithoutEvent,
42
+ reservationFor: { id: reservationFor.id, typeOf: reservationFor.typeOf }
43
+ };
49
44
  }
50
45
  }
51
46
  /**
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.minimizeReservationFor = minimizeReservationFor;
4
- const USE_DEPRECATED_RESERVATION_FOR = process.env.USE_DEPRECATED_RESERVATION_FOR === '1';
5
4
  function minimizeWorkPerformed(params) {
6
5
  const { identifier, id, typeOf, version } = params;
7
6
  return {
@@ -29,10 +28,6 @@ function minimizeRoom(params) {
29
28
  return { branchCode, typeOf };
30
29
  }
31
30
  function minimizeReservationFor(params) {
32
- if (USE_DEPRECATED_RESERVATION_FOR) {
33
- // 互換性維持対応として
34
- return { minimizedReservationFor: params }; // eslint-disable-line @typescript-eslint/no-explicit-any
35
- }
36
31
  const { name: _name, doorTime: _doorTime, superEvent, location, ...reservationForNoName } = params;
37
32
  const minimizedReservationFor = {
38
33
  ...reservationForNoName,
@@ -69,6 +69,10 @@ interface ITriggerWebhookSettings {
69
69
  headerIdentifier?: string;
70
70
  retryCountMax?: number;
71
71
  retryIntervalInMS?: number;
72
+ /**
73
+ * support(2026-10-30~)
74
+ */
75
+ googleTargetAudience?: string;
72
76
  }
73
77
  export interface IWaiterSettings {
74
78
  disabled?: boolean;
@@ -0,0 +1,5 @@
1
+ import { IdTokenClient } from 'google-auth-library';
2
+ /**
3
+ * 指定した targetAudience に対応する IdTokenClient を取得(キャッシュ対応)
4
+ */
5
+ export declare function getGoogleIdTokenClient(targetAudience: string): Promise<IdTokenClient>;
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getGoogleIdTokenClient = getGoogleIdTokenClient;
4
+ const google_auth_library_1 = require("google-auth-library");
5
+ // GoogleAuth のベースインスタンスは 1 つで共有
6
+ let auth;
7
+ // Audience ごとに生成したクライアントを保持するキャッシュ
8
+ const idTokenClients = new Map();
9
+ const initPromises = new Map();
10
+ /**
11
+ * 指定した targetAudience に対応する IdTokenClient を取得(キャッシュ対応)
12
+ */
13
+ async function getGoogleIdTokenClient(targetAudience) {
14
+ if (typeof targetAudience !== 'string' || targetAudience === '') {
15
+ throw new Error('targetAudience is required.');
16
+ }
17
+ // 1. 既に生成済みのインスタンスがあれば即座に返す(メモリ参照のみ、負荷ゼロ)
18
+ const cachedClient = idTokenClients.get(targetAudience);
19
+ if (cachedClient !== undefined) {
20
+ return cachedClient;
21
+ }
22
+ if (auth === undefined) {
23
+ auth = new google_auth_library_1.GoogleAuth();
24
+ }
25
+ // 2. 起動直後など、同一 Audience への多重初期化を防ぐ(Promise キャッシュ)
26
+ let promise = initPromises.get(targetAudience);
27
+ if (promise === undefined) {
28
+ promise = auth.getIdTokenClient(targetAudience)
29
+ .then((client) => {
30
+ idTokenClients.set(targetAudience, client);
31
+ return client;
32
+ }).finally(() => {
33
+ // 成功・失敗にかかわらず進行中フラグ(Promise)を掃除する
34
+ initPromises.delete(targetAudience);
35
+ });
36
+ initPromises.set(targetAudience, promise);
37
+ }
38
+ return promise;
39
+ }
@@ -37,6 +37,7 @@ exports.triggerWebhook = triggerWebhook;
37
37
  const crypto = __importStar(require("crypto"));
38
38
  const http_status_1 = require("http-status");
39
39
  const factory_1 = require("../../factory");
40
+ const getGoogleIdTokenClient_1 = require("./triggerWebhook/getGoogleIdTokenClient");
40
41
  const USERNAME_ARGUMENT_REQUIRED_MESSAGE = 'Missing required key \'Username\' in params';
41
42
  function triggerWebhook(params) {
42
43
  return async (repos) => {
@@ -141,11 +142,40 @@ function signRequest(params) {
141
142
  .update(payload)
142
143
  .digest('hex');
143
144
  }
145
+ async function makeRequestHeaders(action, options, requestBody) {
146
+ const secretKey = options?.triggerWebhook?.secretKey;
147
+ const headerIdentifier = options?.triggerWebhook?.headerIdentifier;
148
+ const googleTargetAudience = options?.triggerWebhook?.googleTargetAudience;
149
+ const timestamp = action.startDate.valueOf();
150
+ // sign request(2024-10-28~)
151
+ let signature;
152
+ if (typeof secretKey === 'string' && secretKey !== ''
153
+ && typeof headerIdentifier === 'string' && headerIdentifier !== '') {
154
+ signature = signRequest({ requestBody, timestamp, secretKey });
155
+ }
156
+ const headers = new Headers({ 'Content-Type': 'application/json' });
157
+ if (typeof headerIdentifier === 'string' && headerIdentifier !== '') {
158
+ headers.append(`X-${headerIdentifier}-Webhook-Timestamp`, String(timestamp));
159
+ if (typeof signature === 'string') {
160
+ headers.append(`X-${headerIdentifier}-Webhook-Signature`, signature);
161
+ }
162
+ }
163
+ // support googleAuth(2026-10-30~)
164
+ if (typeof googleTargetAudience === 'string' && googleTargetAudience !== '') {
165
+ const idTokenClient = await (0, getGoogleIdTokenClient_1.getGoogleIdTokenClient)(googleTargetAudience);
166
+ // getRequestHeaders() からキャッシュ済みの "Bearer eyJhbG..." を取得
167
+ const requestHeaders = await idTokenClient.getRequestHeaders();
168
+ const idToken = requestHeaders.get('authorization'); // "Bearer eyJhbG..."
169
+ if (typeof idToken === 'string') {
170
+ // IAPを通過するための認証(Googleが認識するヘッダー)
171
+ headers.append('Proxy-Authorization', idToken);
172
+ }
173
+ }
174
+ return headers;
175
+ }
144
176
  function processInformAction(params, options) {
145
177
  return async (repos) => {
146
178
  const timeout = options?.triggerWebhook?.timeout;
147
- const secretKey = options?.triggerWebhook?.secretKey;
148
- const headerIdentifier = options?.triggerWebhook?.headerIdentifier;
149
179
  const { identifier } = params;
150
180
  const informActionAttributes = await createInformActionAttributes(params)(repos);
151
181
  const action = await repos.actions.inform.startInformAction(informActionAttributes);
@@ -161,20 +191,7 @@ function processInformAction(params, options) {
161
191
  ? { identifier }
162
192
  : undefined
163
193
  });
164
- const timestamp = action.startDate.valueOf();
165
- // sign request(2024-10-28~)
166
- let signature;
167
- if (typeof secretKey === 'string' && secretKey !== ''
168
- && typeof headerIdentifier === 'string' && headerIdentifier !== '') {
169
- signature = signRequest({ requestBody, timestamp, secretKey });
170
- }
171
- const headers = new Headers({ 'Content-Type': 'application/json' });
172
- if (typeof headerIdentifier === 'string' && headerIdentifier !== '') {
173
- headers.append(`X-${headerIdentifier}-Webhook-Timestamp`, String(timestamp));
174
- if (typeof signature === 'string') {
175
- headers.append(`X-${headerIdentifier}-Webhook-Signature`, signature);
176
- }
177
- }
194
+ const headers = await makeRequestHeaders(action, options, requestBody);
178
195
  const res = await fetch(urlTemplate, {
179
196
  method: 'POST',
180
197
  headers,
@@ -18,7 +18,9 @@ export declare function validateAcceptedOffers(params: {
18
18
  result: {
19
19
  order: PlaceOrderFactory.IResultOrderParams;
20
20
  };
21
- acceptedOffers: (Pick<factory.acceptedOffer.IAcceptedOffer, 'itemOffered' | 'offeredThrough' | 'serialNumber'>)[];
21
+ acceptedOffers: (Pick<factory.acceptedOffer.IAcceptedOffer, 'itemOffered' | 'offeredThrough' | 'serialNumber' | 'id'>)[];
22
+ }, options: {
23
+ maxNumUnitPriceOffers: number;
22
24
  }): void;
23
25
  export declare function validateOrderedItem(params: {
24
26
  order: Pick<factory.order.IOrder, 'orderedItem'>;
@@ -196,7 +196,7 @@ function validatePaymentUrl(params) {
196
196
  /**
197
197
  * 注文オファー数検証
198
198
  */
199
- function validateAcceptedOffers(params) {
199
+ function validateAcceptedOffers(params, options) {
200
200
  if (!Array.isArray(params.acceptedOffers)) {
201
201
  throw new factory_1.factory.errors.Argument('order.acceptedOffers', 'must be array');
202
202
  }
@@ -266,6 +266,12 @@ function validateAcceptedOffers(params) {
266
266
  throw new factory_1.factory.errors.Argument('Transaction', 'ticketNumbers must be unique');
267
267
  }
268
268
  }
269
+ // 単価オファー数検証(2026-10-26~)
270
+ const { maxNumUnitPriceOffers } = options;
271
+ const numUnitPriceOffers = [...new Set(params.acceptedOffers.map(({ id }) => String(id)))].length;
272
+ if (numUnitPriceOffers > maxNumUnitPriceOffers) {
273
+ throw new factory_1.factory.errors.Argument('Transaction', (0, util_1.format)('Number of unitPriceOffers must be less than or equal to %s', maxNumUnitPriceOffers));
274
+ }
269
275
  }
270
276
  function validateOrderedItem(params) {
271
277
  if (!Array.isArray(params.order.orderedItem)) {
@@ -40,6 +40,11 @@ interface IConfirmOptions {
40
40
  * 注文における最大CreditCardIF決済方法数
41
41
  */
42
42
  maxNumCreditCardPaymentMethod: number;
43
+ /**
44
+ * ユニークな単価オファー最大数
45
+ * 2026-10-26~
46
+ */
47
+ maxNumUnitPriceOffers: number;
43
48
  }
44
49
  type IConfirmParams = PlaceOrderFactory.IConfirmParams & {
45
50
  /**
@@ -327,7 +327,7 @@ function createResult(params, options) {
327
327
  (0, validation_1.validateAcceptedOffers)({
328
328
  result: params.result,
329
329
  acceptedOffers: params.acceptedOffers
330
- });
330
+ }, options);
331
331
  // 注文アイテム検証(2024-01-20~)
332
332
  (0, validation_1.validateOrderedItem)({
333
333
  order: { orderedItem },
package/package.json CHANGED
@@ -17,6 +17,7 @@
17
17
  "@sendgrid/client": "8.1.4",
18
18
  "@surfrock/sdk": "2.0.0",
19
19
  "debug": "4.4.3",
20
+ "google-auth-library": "11.3.2",
20
21
  "http-status": "2.1.0",
21
22
  "jsonwebtoken": "9.0.0",
22
23
  "libphonenumber-js": "1.13.8",
@@ -88,5 +89,5 @@
88
89
  "postversion": "git push origin --tags",
89
90
  "prepublishOnly": "npm run clean && npm run build"
90
91
  },
91
- "version": "28.0.0"
92
+ "version": "28.1.0-alpha.1"
92
93
  }