@mpgd/game-services 0.27.1 → 0.27.2

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.
@@ -133,7 +133,15 @@ export interface CreateAitFunctionalMessageDeliveryProviderOptions {
133
133
  readonly timeoutMs?: number;
134
134
  /** `FAIL` error codes that mean the recipient has not agreed to the template. */
135
135
  readonly agreementErrorCodes?: readonly string[];
136
- /** `reachedFailReason` texts (trimmed) that mean the recipient has not agreed to the template. */
136
+ /**
137
+ * `reachedFailReason` texts (trimmed) that mean the recipient has not
138
+ * agreed to the template. Each is 1 to 1,024 characters (UTF-16 code
139
+ * units) once trimmed: the provider reads at most the first 1,024
140
+ * characters of a `reachedFailReason` and then trims it, so a longer entry
141
+ * could never match, and an empty one would match a blank reason. The
142
+ * provider refuses either at creation. A received reason with leading
143
+ * whitespace loses as much of its end to that cut.
144
+ */
137
145
  readonly agreementFailReasons?: readonly string[];
138
146
  /** Further `FAIL` error codes that mean this recipient cannot receive the message. */
139
147
  readonly recipientErrorCodes?: readonly string[];
@@ -78,6 +78,8 @@ const channelFields = {
78
78
  friendtalk: 'sentFriendtalk',
79
79
  };
80
80
  const maximumResponseBodyBytes = 256 * 1_024;
81
+ /** The longest `reachedFailReason` the provider keeps; a longer one is cut to this. */
82
+ const maximumFailReasonLength = 1_024;
81
83
  const maximumIdentifierLength = 2_048;
82
84
  const maximumTimeoutMs = 60_000;
83
85
  /**
@@ -126,7 +128,7 @@ export function createAitFunctionalMessageDeliveryProvider(options) {
126
128
  const timeoutMs = normalizeTimeout(options.timeoutMs);
127
129
  const agreementErrorCodes = new Set(options.agreementErrorCodes ?? []);
128
130
  const recipientErrorCodes = new Set(options.recipientErrorCodes ?? []);
129
- const agreementFailReasons = new Set((options.agreementFailReasons ?? []).map((reason) => reason.trim()));
131
+ const agreementFailReasons = new Set((options.agreementFailReasons ?? []).map((reason, index) => readAgreementFailReason(reason, index)));
130
132
  // Documented codes come first (RFC "Delivery providers -> Apps in Toss"),
131
133
  // then the deployment's. A list must not turn 4095 into an agreement denial.
132
134
  const classifyFailCode = (code, status) => {
@@ -224,6 +226,14 @@ export function createAitFunctionalMessageDeliveryProvider(options) {
224
226
  },
225
227
  };
226
228
  }
229
+ /** One `agreementFailReasons` entry, trimmed, or a `TypeError` for one that could never match. */
230
+ function readAgreementFailReason(reason, index) {
231
+ const trimmed = typeof reason === 'string' ? reason.trim() : '';
232
+ if (trimmed.length === 0 || trimmed.length > maximumFailReasonLength) {
233
+ throw new TypeError(`agreementFailReasons[${index}]: entries must be 1 to ${maximumFailReasonLength} characters once trimmed: a reachedFailReason is read up to ${maximumFailReasonLength} characters, so a longer entry could never match and an empty one would match a blank reason.`);
234
+ }
235
+ return trimmed;
236
+ }
227
237
  function readSuccess(success, agreementFailReasons) {
228
238
  if (!isRecord(success)) {
229
239
  return { status: 'ambiguous', providerCode: 'SUCCESS' };
@@ -274,7 +284,9 @@ function readContents(input) {
274
284
  const reason = item['reachedFailReason'];
275
285
  contents.push({
276
286
  contentId: item['contentId'].slice(0, 256),
277
- ...(typeof reason === 'string' ? { reachedFailReason: reason.slice(0, 1_024) } : {}),
287
+ ...(typeof reason === 'string'
288
+ ? { reachedFailReason: reason.slice(0, maximumFailReasonLength) }
289
+ : {}),
278
290
  });
279
291
  }
280
292
  return contents;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mpgd/game-services",
3
- "version": "0.27.1",
3
+ "version": "0.27.2",
4
4
  "description": "Client, contract, server, store, and test helpers for authoritative mpgd game services.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -219,9 +219,9 @@
219
219
  "@orpc/client": "2.0.0-beta.14",
220
220
  "@orpc/contract": "2.0.0-beta.14",
221
221
  "@orpc/server": "2.0.0-beta.14",
222
- "@mpgd/analytics": "0.4.15",
223
- "@mpgd/platform": "0.27.1",
224
- "@mpgd/catalog": "0.10.6"
222
+ "@mpgd/analytics": "0.4.16",
223
+ "@mpgd/platform": "0.27.2",
224
+ "@mpgd/catalog": "0.10.7"
225
225
  },
226
226
  "peerDependencies": {
227
227
  "@apple/app-store-server-library": "^3.1.0"