@art-suite/art-core-ts-communication-status 0.7.0 → 0.9.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.
- package/dist/index.cjs +48 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +35 -10
- package/dist/index.d.ts +35 -10
- package/dist/index.js +43 -20
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -20,10 +20,12 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
+
UnknownCommunicationStatusDetails: () => UnknownCommunicationStatusDetails,
|
|
23
24
|
aborted: () => aborted,
|
|
24
25
|
clientFailure: () => clientFailure,
|
|
25
26
|
clientFailureNotAuthorized: () => clientFailureNotAuthorized,
|
|
26
27
|
communicationStatuses: () => communicationStatuses,
|
|
28
|
+
disabled: () => disabled,
|
|
27
29
|
failure: () => failure,
|
|
28
30
|
getCommunicationStatus: () => getCommunicationStatus,
|
|
29
31
|
getCommunicationStatusDetails: () => getCommunicationStatusDetails,
|
|
@@ -33,6 +35,7 @@ __export(index_exports, {
|
|
|
33
35
|
isAborted: () => isAborted,
|
|
34
36
|
isClientFailure: () => isClientFailure,
|
|
35
37
|
isClientFailureNotAuthorized: () => isClientFailureNotAuthorized,
|
|
38
|
+
isDisabled: () => isDisabled,
|
|
36
39
|
isFailure: () => isFailure,
|
|
37
40
|
isMissing: () => isMissing,
|
|
38
41
|
isNetworkFailure: () => isNetworkFailure,
|
|
@@ -49,7 +52,8 @@ __export(index_exports, {
|
|
|
49
52
|
serverFailure: () => serverFailure,
|
|
50
53
|
statusRegex: () => statusRegex,
|
|
51
54
|
success: () => success,
|
|
52
|
-
timeoutFailure: () => timeoutFailure
|
|
55
|
+
timeoutFailure: () => timeoutFailure,
|
|
56
|
+
unknown: () => unknown
|
|
53
57
|
});
|
|
54
58
|
module.exports = __toCommonJS(index_exports);
|
|
55
59
|
|
|
@@ -64,6 +68,8 @@ var aborted = "aborted";
|
|
|
64
68
|
var pending = "pending";
|
|
65
69
|
var failure = "failure";
|
|
66
70
|
var timeoutFailure = "timeoutFailure";
|
|
71
|
+
var disabled = "disabled";
|
|
72
|
+
var unknown = "unknown";
|
|
67
73
|
|
|
68
74
|
// ../art-core-ts-types/dist/index.js
|
|
69
75
|
var isObject = (v) => v != null && typeof v === "object";
|
|
@@ -75,6 +81,7 @@ var isPlainObject = (v) => {
|
|
|
75
81
|
return null == Object.getPrototypeOf(prototype);
|
|
76
82
|
};
|
|
77
83
|
var isFunction = (obj) => typeof obj === "function";
|
|
84
|
+
var isString = (obj) => typeof obj === "string";
|
|
78
85
|
var exists = (value) => value != null;
|
|
79
86
|
|
|
80
87
|
// ../art-core-ts-comprehensions/dist/index.js
|
|
@@ -180,7 +187,15 @@ var communicationStatusesPartials = {
|
|
|
180
187
|
pending: { httpStatus: void 0 },
|
|
181
188
|
networkFailure: { httpStatus: void 0, failure: true },
|
|
182
189
|
aborted: { httpStatus: void 0, failure: true },
|
|
183
|
-
timeoutFailure: { httpStatus: void 0, failure: true }
|
|
190
|
+
timeoutFailure: { httpStatus: void 0, failure: true },
|
|
191
|
+
disabled: { httpStatus: void 0 },
|
|
192
|
+
unknown: { httpStatus: void 0, failure: true }
|
|
193
|
+
};
|
|
194
|
+
var UnknownCommunicationStatusDetails = {
|
|
195
|
+
status: "unknown",
|
|
196
|
+
communicationStatus: "unknown",
|
|
197
|
+
message: "Unknown communication status",
|
|
198
|
+
failure: true
|
|
184
199
|
};
|
|
185
200
|
var communicationStatuses = object(communicationStatusesPartials, (details, status) => ({
|
|
186
201
|
...details,
|
|
@@ -195,29 +210,31 @@ var statusRegex = new RegExp(`^(${Object.keys(communicationStatuses).join("|")})
|
|
|
195
210
|
|
|
196
211
|
// src/CommunicationStatusTests.ts
|
|
197
212
|
var isSuccess = (status) => !!status && getCommunicationStatus(status) === success;
|
|
198
|
-
var isFailure = (status) => !!status && getCommunicationStatusDetails(status).failure;
|
|
199
|
-
var isClientFailure = (status) => !!status && getCommunicationStatusDetails(status).clientFailure;
|
|
200
|
-
var isServerFailure = (status) => !!status && getCommunicationStatusDetails(status).serverFailure;
|
|
201
|
-
var isNetworkFailure = (status) => !!status && getCommunicationStatus(status) === networkFailure;
|
|
213
|
+
var isFailure = (status) => !!(status && getCommunicationStatusDetails(status).failure);
|
|
214
|
+
var isClientFailure = (status) => !!(status && getCommunicationStatusDetails(status).clientFailure);
|
|
215
|
+
var isServerFailure = (status) => !!(status && getCommunicationStatusDetails(status).serverFailure);
|
|
216
|
+
var isNetworkFailure = (status) => !!(status && getCommunicationStatus(status) === networkFailure);
|
|
202
217
|
var isNonClientFailure = (status) => {
|
|
203
218
|
if (!status) return false;
|
|
204
219
|
const details = getCommunicationStatusDetails(status);
|
|
205
|
-
return details.failure && !details.clientFailure;
|
|
220
|
+
return !!(details.failure && !details.clientFailure);
|
|
206
221
|
};
|
|
207
222
|
var isClientFailureNotAuthorized = (status) => !!status && getCommunicationStatus(status) === clientFailureNotAuthorized;
|
|
208
|
-
var isAborted = (status) => !!status && getCommunicationStatus(status) === aborted;
|
|
209
|
-
var isMissing = (status) => !!status && getCommunicationStatus(status) === missing;
|
|
210
|
-
var isPending = (status) => !!status && getCommunicationStatus(status) === pending;
|
|
211
|
-
var isTimeout = (status) => !!status && getCommunicationStatus(status) === timeoutFailure;
|
|
223
|
+
var isAborted = (status) => !!(status && getCommunicationStatus(status) === aborted);
|
|
224
|
+
var isMissing = (status) => !!(status && getCommunicationStatus(status) === missing);
|
|
225
|
+
var isPending = (status) => !!(status && getCommunicationStatus(status) === pending);
|
|
226
|
+
var isTimeout = (status) => !!(status && getCommunicationStatus(status) === timeoutFailure);
|
|
212
227
|
var isRetryableFailure = (status) => {
|
|
213
228
|
if (!status) return false;
|
|
214
229
|
const { status: communicationStatus, failure: failure2 } = getCommunicationStatusDetails(status);
|
|
215
|
-
return failure2 && (communicationStatus === networkFailure || communicationStatus === timeoutFailure || communicationStatus === aborted);
|
|
230
|
+
return !!(failure2 && (communicationStatus === networkFailure || communicationStatus === timeoutFailure || communicationStatus === aborted));
|
|
216
231
|
};
|
|
217
|
-
var isStatusValid = (status) => statusRegex.test(status);
|
|
232
|
+
var isStatusValid = (status) => !!(isString(status) && statusRegex.test(status));
|
|
233
|
+
var isDisabled = (status) => !!(status && getCommunicationStatus(status) === disabled);
|
|
218
234
|
|
|
219
235
|
// src/CommunicationStatusConversions.ts
|
|
220
236
|
var getCommunicationStatusFromHttpStatusOrUndefined = (httpStatus) => {
|
|
237
|
+
if (httpStatus === 0) return disabled;
|
|
221
238
|
switch (Math.floor(httpStatus / 100)) {
|
|
222
239
|
case 2:
|
|
223
240
|
return success;
|
|
@@ -296,23 +313,31 @@ var getHttpStatus = (status) => {
|
|
|
296
313
|
}
|
|
297
314
|
return httpStatus;
|
|
298
315
|
};
|
|
299
|
-
|
|
316
|
+
function getCommunicationStatusDetails(status) {
|
|
300
317
|
if (status == null) return void 0;
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
318
|
+
try {
|
|
319
|
+
const communicationStatus = getCommunicationStatus(status);
|
|
320
|
+
const details = communicationStatuses[communicationStatus] ?? UnknownCommunicationStatusDetails;
|
|
321
|
+
return details;
|
|
322
|
+
} catch {
|
|
323
|
+
return UnknownCommunicationStatusDetails;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
function getCommunicationStatusDetailsOrUndefined(status) {
|
|
305
327
|
if (status == null) return void 0;
|
|
306
328
|
const communicationStatus = getCommunicationStatusOrUndefined(status);
|
|
307
329
|
if (communicationStatus == null) return void 0;
|
|
308
|
-
|
|
309
|
-
|
|
330
|
+
const details = communicationStatuses[communicationStatus];
|
|
331
|
+
return details;
|
|
332
|
+
}
|
|
310
333
|
// Annotate the CommonJS export names for ESM import in node:
|
|
311
334
|
0 && (module.exports = {
|
|
335
|
+
UnknownCommunicationStatusDetails,
|
|
312
336
|
aborted,
|
|
313
337
|
clientFailure,
|
|
314
338
|
clientFailureNotAuthorized,
|
|
315
339
|
communicationStatuses,
|
|
340
|
+
disabled,
|
|
316
341
|
failure,
|
|
317
342
|
getCommunicationStatus,
|
|
318
343
|
getCommunicationStatusDetails,
|
|
@@ -322,6 +347,7 @@ var getCommunicationStatusDetailsOrUndefined = (status) => {
|
|
|
322
347
|
isAborted,
|
|
323
348
|
isClientFailure,
|
|
324
349
|
isClientFailureNotAuthorized,
|
|
350
|
+
isDisabled,
|
|
325
351
|
isFailure,
|
|
326
352
|
isMissing,
|
|
327
353
|
isNetworkFailure,
|
|
@@ -338,6 +364,7 @@ var getCommunicationStatusDetailsOrUndefined = (status) => {
|
|
|
338
364
|
serverFailure,
|
|
339
365
|
statusRegex,
|
|
340
366
|
success,
|
|
341
|
-
timeoutFailure
|
|
367
|
+
timeoutFailure,
|
|
368
|
+
unknown
|
|
342
369
|
});
|
|
343
370
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/CommunicationStatusConsts.ts","../../art-core-ts-types/src/Types.ts","../../art-core-ts-comprehensions/src/Comprehensions.ts","../../art-core-ts-comprehensions/src/DeepComprehensions.ts","../src/CommunicationStatusTypes.ts","../src/CommunicationStatusTests.ts","../src/CommunicationStatusConversions.ts"],"sourcesContent":["export * from \"./CommunicationStatusConsts\";\nexport * from \"./CommunicationStatusConversions\";\nexport * from \"./CommunicationStatusTests\";\nexport * from \"./CommunicationStatusTypes\";\n","// Export status constants\nimport type { CommunicationStatus } from './CommunicationStatusTypes'\n\n/**\n * HTTP 2xx responses\n *\n * Client Can Automatically:\n * - Process the successful response\n * - Update UI to reflect success\n *\n * Client Developer Can:\n * - Handle the successful response data\n */\nexport const success: CommunicationStatus = \"success\"\n\n/**\n * Resource not found\n *\n * HTTP Status Codes Covered:\n * - 404: Not Found\n *\n * Client Can Automatically:\n * - notify the user that the resource was not found\n * - prompt the user to request a different resource\n *\n * Client Developer Can:\n * - fix the bad resource paths\n */\nexport const missing: CommunicationStatus = \"missing\"\n\n/**\n * Client-side errors; i.e. the client needs to change the request somehow to succeed\n *\n * HTTP Status Codes Covered:\n * - 400: Bad Request\n * - 401: Unauthorized\n * - 403: Forbidden\n * - 407: Proxy Authentication Required\n * - 409: Conflict\n * - 422: Unprocessable Entity\n *\n * Client Can Automatically:\n * - Notify the user that the client is experiencing issues\n * - Prompt user to correct invalid input\n *\n * Client Developer Can:\n * - use isClientFailureNotAuthorized to check for 401/403/407/451\n * - fix the request to avoid the 4xx error\n * - validate input before sending requests\n */\nexport const clientFailure: CommunicationStatus = \"clientFailure\"\n\n/**\n * Unauthorized requests; i.e. client needs to change the credentials (or the grants for the current credentials) to succeed\n *\n * HTTP Status Codes Covered:\n * - 401: Unauthorized\n * - 403: Forbidden\n * - 407: Proxy Authentication Required\n * - 451: Unavailable For Legal Reasons\n *\n * Client Can Automatically:\n * - refresh the request token\n * - prompt the user to re-login\n * - ask the user to contact the administrator for access\n *\n * Client and Server Developer Can:\n * - fix authorization / authentication bugs\n */\nexport const clientFailureNotAuthorized: CommunicationStatus = \"clientFailureNotAuthorized\"\n\n/**\n * Server-side errors; i.e. internal server errors\n *\n * HTTP Status Codes Covered:\n * - 500: Internal Server Error\n * - 502: Bad Gateway\n * - 503: Service Unavailable\n * - 504: Gateway Timeout\n *\n * Client Can Automatically:\n * - Ask the user to try again later\n * - Notify the user that the server is experiencing issues\n * - Implement automatic retry with backoff\n *\n * Client Developer: (probably) can't fix\n *\n * Server Developer Can:\n * - fix the server to avoid the 5xx error\n * - fix server infrastructure to avoid the 5xx error\n */\nexport const serverFailure: CommunicationStatus = \"serverFailure\"\n\n/**\n * Request fails due to network connectivity issues\n *\n * HTTP Status Codes Covered: NONE (server was not reachable)\n *\n * Client Can Automatically:\n * - Prompt the user to fix the network connection\n * - Retry the request when network is available\n * - Monitor network status for recovery\n *\n * Client Developer Can:\n * - fix bad network constants (like address, ports, etc.)\n * - implement offline-first capabilities\n */\nexport const networkFailure: CommunicationStatus = \"networkFailure\"\n\n/**\n * Request was cancelled by client\n *\n * Client Can Automatically:\n * - notify the user that the request was cancelled\n * - prompt the user to try again\n * - cleanup any pending state\n *\n * Client Developer Can:\n * - fix the client to not abort the request unnecessarily\n * - implement proper cleanup on abort\n */\nexport const aborted: CommunicationStatus = \"aborted\"\n\n/**\n * Request is in progress\n *\n * Client Can Automatically:\n * - notify the user that the request is in progress\n * - show the user progress (if available)\n * - allow the user to cancel the request\n *\n * Client Developer Can:\n * - if \"pending\" was not expected, maybe the client needs to `wait` for the request to complete?\n * - implement proper loading states\n */\nexport const pending: CommunicationStatus = \"pending\"\n\n/**\n * Any error response (HTTP 4xx/5xx) or network/abort failures\n *\n * HTTP Status Codes Covered:\n * - 4xx: Client-side errors (except 404)\n * - 5xx: Server-side errors\n * - Network failures\n * - Abort failures\n *\n * Client Can Automatically:\n * - Show appropriate error message to user\n * - Implement generic error handling\n * - Log errors for debugging\n *\n * Client Developer Can:\n * - Use more specific is* functions for targeted error handling\n * - Implement proper error recovery strategies\n */\nexport const failure: CommunicationStatus = \"failure\"\n\n/**\n * Request timed out\n *\n * Client Can Automatically:\n * - notify the user that the request timed out\n * - try again (automatically or via user action)\n *\n * Client Developer Can:\n * - fix the client to not timeoutFailure the request\n * - implement proper timeoutFailure handling\n */\nexport const timeoutFailure: CommunicationStatus = \"timeoutFailure\"\n","import { PlainObject } from \"./TypeScriptTypes\"\n\ntype TypedArray = Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array\n\n/*\n\n @isPromise: (obj) => obj? && isFunction(obj.then) && !isFunction obj\n @isRegExp: (obj) => obj.constructor.name == \"RegExp\"\n @isNumber: isNumber = (obj) => typeof obj == \"number\"\n\n isNonNegativeInt: (x) ->\n ((x | 0) == x) &&\n x >= 0\n\n @isError: (obj) => obj? && obj instanceof Error\n @isDate: (obj) => obj?.constructor == Date\n @isString: isString = (obj) => typeof obj == \"string\"\n @isFunction: isFunction = (obj) => typeof obj == \"function\"\n @isEmptyObject: (obj) => Object.keys(obj).length == 0\n @isBoolean: (obj) => obj == true || obj == false\n\n @isArrayBuffer: isArrayBuffer = if global.ArrayBuffer\n (obj) -> obj? && obj.constructor == ArrayBuffer\n else -> false\n @isTypedArray: (obj) -> obj? && obj.length >= 0 && obj.length == (obj.length | 0) && isArrayBuffer obj.buffer\n\n */\n\n/**\n * Returns true if the value is an object. (note, Arrays are objects)\n * This is only false for null, undefined, functions, and primitives like strings, numbers, and booleans.\n * @param v\n * @returns\n */\nexport const isObject = (v: any): v is Record<string, any> => v != null && typeof v === 'object'\n\n/**\n * Returns true if the value is a plain object - i.e. an object who's prototype is Object\n * @param v\n * @returns\n */\nexport const isPlainObject = (v: any): v is PlainObject => {\n if (!isObject(v)) return false\n if (v.constructor === Object) return true // fast pass, but could fail if v was created in a different context with a different instance of Object\n const prototype = Object.getPrototypeOf(v)\n if (prototype === null) return true\n return null == Object.getPrototypeOf(prototype)\n}\n\nexport const asPlainObject = (v: any): PlainObject => isPlainObject(v) ? v : {}\n\nexport const isFunction = (obj: any): obj is Function => typeof obj === \"function\"\nexport const isNumber = (obj: any): obj is number => typeof obj === \"number\"\nexport const isString = (obj: any): obj is string => typeof obj === \"string\"\nexport const isArrayBuffer = (obj: any): obj is ArrayBuffer => obj != null && obj.constructor === ArrayBuffer\nexport const isArray = (obj: any): obj is any[] => Array.isArray(obj)\n\nexport const isPromise = (obj: any): obj is Promise<any> => obj != null && isFunction(obj.then) && !isFunction(obj)\nexport const isRegExp = (obj: any): obj is RegExp => obj?.constructor.name === \"RegExp\"\nexport const isError = (obj: any): obj is Error => obj != null && obj instanceof Error\nexport const isDate = (obj: any): obj is Date => obj?.constructor === Date\nexport const isEmptyObject = (obj: any): obj is Record<string, never> => Object.keys(obj).length === 0\nexport const isBoolean = (obj: any): obj is boolean => obj === true || obj === false\nexport const isTypedArray = (obj: any): obj is TypedArray =>\n obj != null &&\n obj.length >= 0 &&\n obj.length === (obj.length | 0) &&\n isArrayBuffer(obj.buffer)\n\nexport const isNonNegativeInt = (x: number): x is number => ((x | 0) === x) && x >= 0\n\nexport const stringIsPresent = (str: string): boolean => isString(str) && !/^(\\s+|)$/.test(str)\n\nexport const exists = (value: any): boolean => value != null\nexport const doesNotExist = (value: any): boolean => !exists(value)\n\nexport const isNull = (value: any): boolean => value === null\nexport const isNotNull = (value: any): boolean => !isNull(value)\n\nexport const isUndefined = (value: any): boolean => value === undefined\nexport const isNotUndefined = (value: any): boolean => !isUndefined(value)\n\nexport const isNullish = (value: any): boolean => value == null || value == undefined\nexport const isNotNullish = (value: any): boolean => !isNullish(value)\n\n/**\n * present returns true if \"there is a value _present_\"\n *\n * Specifically:\n * - if `value.getPresent()` is a function; it's called and it's value is returned\n * - if `value.present()` is a function; it's called and it's value is returned\n * - else: returns `true` if `!null`, `!undefined` and `!(string with only whitespace)`\n *\n * > Inspired by Ruby's `present?` method\n *\n * @param v\n * @returns\n */\nexport const present = <T>(v: T): v is NonNullable<T> => {\n if (v == null) return false\n if (isFunction((v as any).getPresent)) {\n return (v as any).getPresent()\n } else if (isFunction((v as any).present)) {\n return (v as any).present()\n } else if (isString(v)) {\n return stringIsPresent(v)\n } else return true\n}\n","import { isPlainObject, isFunction, exists } from '@art-suite/art-core-ts-types'\nimport { EachFunction, ArrayFunction, ObjectFunction, ReduceFunction, FindFunction, AnyContainer, ArrayInput, ObjectInput, NotPresent } from './ComprehensionTypes'\n\nconst isMap = (source: any): source is Map<any, any> => source instanceof Map;\nconst isSet = (source: any): source is Set<any> => source instanceof Set;\n\nexport const isArrayIterable = (source: any): source is any[] => {\n if (typeof source === 'string') return false\n if (isFunction(source)) return false\n return source != null && source.length >= 0;\n}\n\nexport const isOfIterable = (o: any): boolean => {\n if (typeof o === 'string') return false\n if (isFunction(o)) return false\n return isFunction(o[Symbol.iterator] || o.next)\n}\n\nconst returnFirstArg = (a: any) => a;\nconst returnSecondArg = (a: any, b: any) => b;\n\nconst emptyOptions = {};\n\ntype CoreIterationFunction = (value: any, key: any) => boolean; // returns true to stop iteration\n\n/**\n * Tight function to abstract away all possible iteration methods based on the source container type.\n *\n * Iterates over the source collection, calling the given function for each element.\n *\n * Stops when the body function returns true.\n * Does NOT return anything. If you need a return value, must set it as a side-effect of the body function.\n *\n * @param source - The collection to iterate (array, object, Map, Set, etc.)\n * @param body - The function to call for each element.\n * @returns void\n */\nconst iterate = (source: any, body: CoreIterationFunction): void => {\n if (exists(source))\n if (isArrayIterable(source)) for (let key = 0, { length } = source; key < length; key++) { if (body(source[key], key)) break; }\n else if (isPlainObject(source)) for (const key in source) { if (body(source[key], key)) break; }\n else if (isMap(source)) for (const [key, value] of source.entries()) { if (body(value, key)) break; }\n // else if (isSet(source)) for (const value of source) { if (body(value, value)) break; }\n else if (isOfIterable(source)) { let count = 0; for (const value of source) { if (body(value, count++)) break; } }\n else throw new Error(`Unsupported source type: ${typeof source}`);\n};\n\n/*\n Returns a function that handles \"with\", \"when\" and \"stopWhen\" comprehension clauses:\n\n 1. Returns true if the \"stopWhen\" is provided and returns true, otherwise returns it will return false\n 2. If stopWhen is false, \"when\" and \"with\" are processed\n 3. If there is no \"when\" or \"when\" returns true, \"with\" is called.\n*/\nconst normalizeBody = (withFunction: (value: any, key: any) => any, options: AcceptedComprehensionOptions): (value: any, key: any) => boolean => {\n let { when, stopWhen } = options;\n if (when && stopWhen) {\n return (v: any, k: any) => {\n if (stopWhen(v, k)) return true;\n if (when(v, k)) withFunction(v, k);\n return false;\n }\n }\n if (when) {\n return (v: any, k: any) => {\n if (when(v, k)) withFunction(v, k);\n return false;\n }\n }\n if (stopWhen) {\n return (v: any, k: any) => {\n if (stopWhen(v, k)) return true;\n withFunction(v, k);\n return false;\n }\n }\n return (v: any, k: any) => { withFunction(v, k); return false; };\n};\n\n\nlet normalizeKeyFunction = (source: any, options: AcceptedComprehensionOptions) =>\n options.withKey || (isArrayIterable(source) ? returnFirstArg : returnSecondArg)\n\nconst _each = (source: any, withFunction: (value: any, key: any) => any, options: AcceptedComprehensionOptions) => {\n iterate(source, normalizeBody(withFunction, options));\n};\n\n//************************************************************************\n// NORMALIZED COMPREHENSION FUNCTIONS\n//************************************************************************\ntype NormalizedIterationFunction = (source: any, options: NormalizedComprehensionOptions) => any;\n\nconst normalizedEach: NormalizedIterationFunction = (source: any, options: NormalizedComprehensionOptions) => {\n _each(source, options.with, options);\n return options.into;\n};\n\nconst normalizedArrayIteration: NormalizedIterationFunction = (source: any, options: NormalizedComprehensionOptions) => {\n let { into, with: withFunction } = options;\n if (into == null) into = [];\n _each(source, (v: any, k: any) => into.push(withFunction(v, k)), options);\n return into;\n};\n\nconst normalizedObjectIteration: NormalizedIterationFunction = (source: any, options: NormalizedComprehensionOptions) => {\n let { into, with: withFunction } = options;\n if (into == null) into = {};\n let withKey = normalizeKeyFunction(source, options);\n _each(source, (v, k) => (into[withKey(v, k)] = withFunction(v, k)), options);\n return into;\n};\n\nconst normalizedReduceIteration: NormalizedIterationFunction = (source: any, options: NormalizedComprehensionOptions) => {\n let { into, with: withFunction } = options;\n let first = into === undefined;\n _each(source, (v: any, k: any) => {\n if (first) { first = false; into = v; }\n else {\n into = withFunction(into, v, k)\n }\n }, options);\n return into;\n};\n\nconst normalizedFindIteration: NormalizedIterationFunction = (source: any, options: NormalizedComprehensionOptions) => {\n let { with: withFunction } = options;\n let { when } = options;\n let found: any | undefined = undefined;\n iterate(\n source,\n when\n ? (v, k) => {\n if (when(v, k)) {\n found = withFunction(v, k);\n return true; // signal to stop iteration\n }\n return false;\n }\n : (v, k) => {\n found = withFunction(v, k) // stops iteration if withFunction returns an value that \"exists\" (is not undefined, non null)\n return found != null;\n }\n );\n return found;\n};\n\n//####################\n// PRIVATE\n//####################\n\n// WithFunction has two signatures: value + key, or for reduce, accumulator + value + key\ntype ValueKeyFunction = (value?: any, key?: any) => any;\ntype AccumulatorValueKeyFunction = (accumulator?: any, value?: any, key?: any) => any;\ntype WithFunction = ValueKeyFunction | AccumulatorValueKeyFunction;\ntype WhenFunction = (value: any, key: any) => any;\ntype WithKeyFunction = (value: any, key: any) => any;\n\ntype AcceptedComprehensionOptions = {\n into?: any;\n inject?: any; // alias for into - used to make \"reduce\" calls make more sense\n returning?: any; // alias for into - used to make \"each\" calls make more sense\n with?: WithFunction;\n when?: WhenFunction;\n withKey?: WithKeyFunction;\n stopWhen?: (value: any, key: any) => any;\n}\n\ntype WithOrOptions = WithFunction | AcceptedComprehensionOptions;\n\nconst isAcceptedComprehensionOptions = (o: any): o is AcceptedComprehensionOptions => isPlainObject(o)\n\n// the 'with' param will always exist when normalized\ntype NormalizedComprehensionOptions = Omit<AcceptedComprehensionOptions, 'with' | 'inject' | 'returning'> & {\n with: WithFunction;\n}\n\n/**\n * Returns the first non-undefined value from into, inject, or returning\n *\n * @param into - The 'into' parameter.\n * @param inject - The 'inject' parameter.\n * @param returning - The 'returning' parameter.\n * @returns The normalized 'into' parameter.\n */\nconst firstNotUndefined = (into: any, inject: any, returning: any) => {\n if (into === undefined) into = inject\n if (into === undefined) into = returning\n return into\n}\n\nconst normalizeIterationParams = (withOrOptions?: WithOrOptions): NormalizedComprehensionOptions => {\n if (isAcceptedComprehensionOptions(withOrOptions)) {\n const { with: withFunction, into, inject, returning, ...rest } = withOrOptions;\n return { ...rest, into: firstNotUndefined(into, inject, returning), with: withFunction ?? returnFirstArg };\n }\n if (isFunction(withOrOptions)) {\n return { with: withOrOptions };\n }\n return { with: returnFirstArg };\n};\n\n/*\nNormalizes input params for the 'iteration' function.\nSince this normalizes multiple params, and therefor would need to return\nan new array or new object otherwise, we pass IN the iteration function\nand pass the params directly to it. This keeps the computed params on the\nstack and doesn't create new objects.\n\nIN signature 1: (iteration, source, withFunction) ->\nIN signature 2: (iteration, source, options) ->\nIN signature 3: (iteration, source) ->\n\nIN:\niteration: (source, into, withFunction, options) -> out\n\n The iteration function is invoked last with the computed args.\n Its results are returned.\n\n IN:\n source: passed directly through from inputs\n into: passed directly through from inputs OR from options.into\n withFunction: passed directly through from inputs OR from options.with\n options: passed directly through from inputs OR {}\n (guaranteed to be set and a plainObject)\n\nsource: the source collection to be iterated over. Passed directly through.\n\ninto: passed through to 'iteration'\nwithFunction: passed through to 'iteration'\noptions: passed through to 'iteration' AND:\n\n into: set 'into' from the options object\n with: set 'withFunction' from the options object\n\nOUT: out\n*/\nconst invokeNormalizedIteration = (\n normalizedIterationFunction: NormalizedIterationFunction,\n source: any,\n withOrOptions: WithOrOptions\n) => normalizedIterationFunction(source, normalizeIterationParams(withOrOptions));\n\n/**\n * Iterates over the provided collection, calling the given function for each element.\n *\n * Unlike other comprehensions, `each` is designed for side effects and does not build a new collection.\n *\n * **Return value:**\n * - If an `into`, `inject`, or `returning` option is provided (or as the second argument), that value is returned (not modified by `each` itself).\n * - If no such value is provided, returns `undefined`.\n *\n * This allows you to use `each` for side effects while optionally threading a value through the iteration.\n *\n * @param source The collection to iterate (array, object, Map, Set, etc.)\n * @param withOrOptions Optional: Either the `into` value or the function to call for each element.\n * @returns The `into`/`inject`/`returning` value if provided, otherwise `undefined`.\n */\nexport const each: EachFunction = ((source: any, withOrOptions: WithOrOptions) => invokeNormalizedIteration(normalizedEach, source, withOrOptions)) as EachFunction;\n\n/**\n * Builds a new array from the provided collection, optionally transforming or filtering elements.\n *\n * Options:\n * - `with`: function to transform each element (like map)\n * - `when`: function to filter elements (like filter)\n * - `into`: array to push results into (default: new array)\n *\n * @param source The collection to iterate (array, object, Map, Set, etc.)\n * @param withOrOptions Optional: `with` function, or options object, or `into` array.\n * @returns The resulting array.\n */\nexport const array: ArrayFunction = ((source: any, withOrOptions: WithOrOptions) => invokeNormalizedIteration(normalizedArrayIteration, source, withOrOptions)) as ArrayFunction;\n\n/**\n * Builds a new object from the provided collection, optionally transforming keys/values or filtering elements.\n *\n * Options:\n * - `with`: function to transform each value\n * - `when`: function to filter elements\n * - `key`/`withKey`: function to determine output keys\n * - `into`: object to assign results into (default: new object)\n *\n * Defaults:\n * - no `with`: uses the source container's \"values\" as the default\n * - no `withKey`: from arrays, uses the values as keys, from objects, uses the keys as keys\n * - no `into`: creates a new object\n *\n * Simplest example use: `object([\"sally\", \"billy\", \"chad\"])` => { \"sally\": \"sally\", \"billy\": \"billy\", \"chad\": \"chad\" }\n *\n * @param source The collection to iterate (array, object, Map, Set, etc.)\n * @param withOrOptions Optional: `with` function, or options object, or `into` object.\n * @returns The resulting object.\n */\nexport const object: ObjectFunction = ((source: any, withOrOptions: WithOrOptions) => invokeNormalizedIteration(normalizedObjectIteration, source, withOrOptions)) as ObjectFunction;\n\n/**\n * Reduces the provided collection to a single value, similar to Array.prototype.reduce.\n *\n * The first element is used as the initial value unless an `into`/`inject`/`returning` option is provided.\n *\n * Options:\n * - `with`: reducer function (receives accumulator, value, key)\n * - `when`: function to filter elements\n * - `into`/`inject`/`returning`: initial value for the reduction\n *\n * @param source The collection to reduce (array, object, Map, Set, etc.)\n * @param withOrOptions Optional: initial value or reducer function or options object.\n * @returns The reduced value.\n */\nexport const reduce: ReduceFunction = ((source: any, withOrOptions: WithOrOptions) => invokeNormalizedIteration(normalizedReduceIteration, source, withOrOptions)) as ReduceFunction;\n\n/**\n * Finds and returns the first value in the collection that matches the given criteria.\n *\n * Options:\n * - `with`: function to transform the found value\n * - `when`: function to filter elements (predicate)\n *\n * @param source The collection to search (array, object, Map, Set, etc.)\n * @param withOrOptions Optional: predicate or options object.\n * @returns The found value, or undefined if not found.\n */\nexport const find: FindFunction = ((source: any, withOrOptions: WithOrOptions) => invokeNormalizedIteration(normalizedFindIteration, source, withOrOptions)) as FindFunction;\n\n\n/**\n * Returns true if the source is a comprehension iterable.\n *\n * A comprehension iterable is any object that can be iterated over.\n *\n * This is different from isFullySupportedComprehensionIterable, which only checks if we can both generate and iterate over the source.\n *\n * NOTE strings are not considered comprehension iterables.\n *\n * @param source - The source to check.\n * @returns True if the source is a comprehension iterable, false otherwise.\n */\nexport const isComprehensionIterable = (source: any): source is AnyContainer<any> =>\n isArrayIterable(source) || isPlainObject(source) || isMap(source) || isSet(source) || isOfIterable(source)\n\n/**\n * Returns true if the source is a fully supported comprehension iterable.\n *\n * Fully supported means we can both generate as well as iterate over the source.\n *\n * This is different from isComprehensionIterable, which only checks if we can iterate over the source.\n *\n * This is useful for cases where we need to know if we can both generate and iterate over the source,\n * such as when we are using the source in a comprehension.\n *\n * Currently, this is only true for arrays and objects. TODO: add Map and Set support.\n * @param source - The source to check.\n * @returns True if the source is a fully supported comprehension iterable, false otherwise.\n */\nexport const isFullySupportedComprehensionIterable = (source: any): source is AnyContainer<any> =>\n isArrayIterable(source) || isPlainObject(source)\n","/**\n * DeepComprehensions is a library that provides a way to map and iterate over deeply nested comprehension iterables.\n *\n * It is useful for cases where you need to map or iterate over a deeply nested comprehension iterable.\n *\n * NOTE: due to their nature, deep comprehensions don't support TypeScript's type inference. You'll need to post-validate or coerce the results to the correct type.\n *\n * TODO: add Map and Set support.\n * TODO: add {when} support. Example usage: deepStripNull = deepMap(obj, {when: v => v !== null})\n */\nimport { isPlainObject } from '@art-suite/art-core-ts-types'\nimport { each, isComprehensionIterable, isFullySupportedComprehensionIterable, isArrayIterable, array, object } from './Comprehensions'\nimport { AnyContainer, FullySupportedContainer, ArrayInput, ObjectInput, NotPresent } from './ComprehensionTypes'\nimport { isFunction } from '@art-suite/art-core-ts-types'\n\nexport type DeepWithFunction = (value: any, key: any) => void\nexport type DeepWhenFunction = (value: any, key: any) => boolean\n\nexport type DeepOptions = {\n when?: DeepWhenFunction\n with?: DeepWithFunction\n}\n\nexport type DeepSecondParameter = DeepWithFunction | DeepOptions\n\n//******************************************************************************************************************\n// HELPERS\n//******************************************************************************************************************\n\nconst defaultWithFunction: DeepWithFunction = v => v\nconst defaultWhenFunction: DeepWhenFunction = () => true\n\ntype DeepOptionsFullSupport = {\n when: DeepWhenFunction\n with: DeepWithFunction\n}\n\nconst normalizeDeepOptions = (options: DeepSecondParameter): DeepOptionsFullSupport => {\n if (isFunction(options)) {\n return { with: options, when: defaultWhenFunction }\n }\n return { with: options.with ?? defaultWithFunction, when: options.when ?? defaultWhenFunction }\n}\n\nconst deepEachR = (obj: AnyContainer<any>, options: DeepOptionsFullSupport) =>\n each(obj, {\n when: options.when,\n with: (value: any, key: any) =>\n isComprehensionIterable(value)\n ? deepEachR(value, options)\n : options.with(value, key)\n })\n\nconst deepMapR = (obj: AnyContainer<any>, options: DeepOptionsFullSupport) =>\n mapInternal(obj, {\n when: options.when, with: (value: any, key: any) =>\n isFullySupportedComprehensionIterable(value)\n ? deepMapR(value, options)\n : options.with(value, key)\n })\n\nconst mapInternal = (source: ArrayInput<any> | ObjectInput<any> | NotPresent, options: DeepOptionsFullSupport) => {\n if (isArrayIterable(source)) return array(source, options)\n if (isPlainObject(source)) return object(source, options)\n throw new Error(`Unsupported source type: ${typeof source}`)\n}\n\n//******************************************************************************************************************\n// EXPORTS\n//******************************************************************************************************************\n/**\n * Maps over a fully supported comprehension iterable, shallowly.\n *\n * Returns the same container type (array or object) as the original object, but with the values mapped.\n *\n * @param source - The source to map over.\n * @param options - the map-function or {with: the map-function, when: the when-function}\n * @returns The mapped container.\n */\nexport const map = (source: ArrayInput<any> | ObjectInput<any> | NotPresent, options: DeepSecondParameter) =>\n mapInternal(source, normalizeDeepOptions(options))\n\n/**\n * Iterates over a fully supported comprehension iterable, and any nested isComprehensionIterable values.\n *\n * withFunction is called for each value that is NOT isComprehensionIterable and true for whenFunction (if provided).\n *\n * whenFunction is called on EVERY value, isComprehensionIterable or not. If it returns false, isComprehensionIterable values will be skipped.\n *\n * @param obj - The object to iterate over.\n * @param options - the with-function or {with: the with-function, when: the when-function}\n * @returns The object.\n */\nexport const deepEach = (obj: AnyContainer<any>, options: DeepSecondParameter) =>\n deepEachR(obj, normalizeDeepOptions(options))\n\n/**\n * Maps over a fully supported comprehension iterable, and any nested fully supported comprehension iterables.\n *\n * Returns the same structure (of fully supported comprehension iterables) as the original object, but with the values mapped.\n * If the source is not a fully supported comprehension iterable, it will return the source unchanged.\n * If the source is a fully supported comprehension iterable, it will return a new fully supported comprehension iterable with the values mapped.\n *\n * whenFunction is called on EVERY value, isComprehensionIterable or not. If it returns false, isComprehensionIterable values will be skipped.\n *\n * @param obj - The object to map over.\n * @param options - the map-function or {with: the map-function, when: the when-function}\n * @returns The mapped object.\n */\nexport const deepMap = (obj: FullySupportedContainer<any>, options: DeepSecondParameter) =>\n deepMapR(obj, normalizeDeepOptions(options))\n","import { object } from '@art-suite/art-core-ts-comprehensions';\n\nconst communicationStatusesPartials = {\n // HTTP Success Statuses\n success: { httpStatus: 200 },\n\n // HTTP Failure Statuses\n missing: { httpStatus: 404, failure: true },\n clientFailure: { httpStatus: 400, clientFailure: true, failure: true },\n clientFailureNotAuthorized: { httpStatus: 403, clientFailure: true, failure: true },\n serverFailure: { httpStatus: 500, failure: true, serverFailure: true },\n failure: { httpStatus: 500, failure: true },\n\n // Non-HTTP Statuses\n pending: { httpStatus: undefined },\n networkFailure: { httpStatus: undefined, failure: true },\n aborted: { httpStatus: undefined, failure: true },\n timeoutFailure: { httpStatus: undefined, failure: true }\n};\n\n/**\n * The core of Art-core-ts-communication-status: A simplified set of statuses as a human-readable and machine-interpretable string\n * representing all the possible communication statuses that are pragmatically actionable.\n */\nexport type CommunicationStatus = keyof typeof communicationStatusesPartials;\n\nexport type HttpOrCommunicationStatus = CommunicationStatus | number;\n\n/**\n * Details about a communication status\n *\n * @param httpStatus - The HTTP status code for the communication status\n * @param failure - Whether the communication status is a failure\n * @param clientFailure - Whether the communication status is a client failure\n * @param serverFailure - Whether the communication status is a server failure\n * @param status - The communication status - alias for communicationStatus\n * @param communicationStatus - The communication status\n */\nexport interface CommunicationStatusDetails {\n httpStatus?: number;\n failure?: boolean;\n clientFailure?: boolean;\n serverFailure?: boolean;\n status: CommunicationStatus;\n communicationStatus: CommunicationStatus;\n message: string;\n}\n\nexport const communicationStatuses: Record<CommunicationStatus, CommunicationStatusDetails> = object(communicationStatusesPartials, (details: any, status) => ({\n ...details,\n failure: !!details.failure,\n clientFailure: !!details.clientFailure,\n serverFailure: !!details.serverFailure,\n status: status as CommunicationStatus,\n communicationStatus: status as CommunicationStatus,\n message: details.httpStatus ? `${status} (${details.httpStatus})` : status\n})) as Record<CommunicationStatus, CommunicationStatusDetails>;\n\nexport type CommunicationStatuses = typeof communicationStatuses;\n\n/**\n * RegEx returns true for all valid communication statuses\n */\nexport const statusRegex = new RegExp(`^(${Object.keys(communicationStatuses).join('|')})$`);\n","import { aborted, clientFailureNotAuthorized, missing, networkFailure, pending, success, timeoutFailure } from './CommunicationStatusConsts';\nimport { getCommunicationStatus, getCommunicationStatusDetails } from './CommunicationStatusConversions';\nimport { HttpOrCommunicationStatus, statusRegex } from './CommunicationStatusTypes';\n\n// Core status check functions\n/** Returns true for HTTP 2xx responses */\nexport const isSuccess = (status: HttpOrCommunicationStatus | null | undefined) => !!status && getCommunicationStatus(status) === success;\n\n/**\n * Returns true for any error response (HTTP 4xx/5xx) or network/abort failures\n *\n * HTTP Status Codes Covered:\n * - 4xx: Client-side errors (except 404)\n * - 5xx: Server-side errors\n * - Network failures\n * - Abort failures\n *\n * Client Can:\n * - Use a different is* function for more specific checks\n */\nexport const isFailure = (status: HttpOrCommunicationStatus | null | undefined) => !!status && getCommunicationStatusDetails(status).failure;\n\n/**\n * Returns true for client-side errors\n *\n * HTTP Status Codes Covered:\n * - 400: Bad Request\n * - 401: Unauthorized\n * - 403: Forbidden\n * - 407: Proxy Authentication Required\n * - 409: Conflict\n * - 422: Unprocessable Entity\n *\n * Client Can Automatically:\n * - Notify the user that the client is experiencing issues\n *\n * Client Developer Can:\n * - use isClientFailureNotAuthorized to check for 401/403/407/451\n * - fix the request to avoid the 4xx error\n*/\nexport const isClientFailure = (status: HttpOrCommunicationStatus | null | undefined) => !!status && getCommunicationStatusDetails(status).clientFailure;\n\n/**\n * Returns true for server-side errors\n *\n * HTTP Status Codes Covered:\n * - 500: Internal Server Error\n * - 502: Bad Gateway\n * - 503: Service Unavailable\n * - 504: Gateway Timeout\n *\n * Client Can Automatically:\n * - Ask the user to try again later\n * - Notify the user that the server is experiencing issues\n *\n * Client Developer: (probably) can't fix\n *\n * Server Developer Can:\n * - fix the server to avoid the 5xx error\n * - fix server infrastructure to avoid the 5xx error (e.g. Bad Gateway, Service Unavailable, Gateway Timeout)\n*/\nexport const isServerFailure = (status: HttpOrCommunicationStatus | null | undefined) => !!status && getCommunicationStatusDetails(status).serverFailure;\n\n/**\n * Returns true when request fails due to network connectivity issues\n *\n * HTTP Status Codes Covered: NONE (server was not reachable)\n *\n * Client Can Automatically:\n * - Prompt the user to fix the network connection\n * - Retry the request\n *\n * Client Developer Can:\n * - fix bad network constants (like address, ports, etc.)\n*/\nexport const isNetworkFailure = (status: HttpOrCommunicationStatus | null | undefined) => !!status && getCommunicationStatus(status) === networkFailure;\n\n/** Returns true for server errors, network failures and aborted requests; i.e. the client did nothing wrong (as far as we can tell); client can ask the user to do something OR retry the request */\nexport const isNonClientFailure = (status: HttpOrCommunicationStatus | null | undefined) => {\n if (!status) return false;\n const details = getCommunicationStatusDetails(status);\n return details.failure && !details.clientFailure;\n};\n\n/**\n * Returns true for unauthorized requests (not authenticated or not authorized)\n *\n * HTTP Status Codes Covered:\n * - 401: Unauthorized\n * - 403: Forbidden\n * - 407: Proxy Authentication Required\n * - 451: Unavailable For Legal Reasons\n * - 511: Network Authentication Required\n *\n * Client Can Automatically:\n * - refresh the request token\n * - prompt the user to re-login\n * - ask the user to contact the administrator for access\n *\n * Client and Server Developer Can:\n * - fix authorization / authentication bugs\n */\nexport const isClientFailureNotAuthorized = (status: HttpOrCommunicationStatus | null | undefined) =>\n !!status &&\n getCommunicationStatus(status) === clientFailureNotAuthorized;\n\n/**\n * Returns true when request was cancelled by client\n *\n * Client Can Automatically:\n * - notify the user that the request was cancelled\n * - prompt the user to try again\n *\n * Client Developer Can:\n * - fix the client to not abort the request\n */\nexport const isAborted = (status: HttpOrCommunicationStatus | null | undefined) => !!status && getCommunicationStatus(status) === aborted;\n\n/**\n * Returns true when resource not found / not available\n *\n * HTTP Status Codes Covered:\n * - 404: Not Found\n * - 501: Not Implemented\n *\n * Client Can Automatically:\n * - notify the user that the resource was not found\n * - prompt the user to request a different resource\n *\n * Client Developer Can:\n * - fix the bad resource paths\n */\nexport const isMissing = (status: HttpOrCommunicationStatus | null | undefined) => !!status && getCommunicationStatus(status) === missing;\n\n/**\n * Returns true while request is in progress\n *\n * Client Can Automatically:\n * - notify the user that the request is in progress\n * - show the user progress (if available)\n * - allow the user to cancel the request (trigging an \"aborted\" communication status)\n *\n * Client Developer Can:\n * - if \"pending\" was not expected, maybe the client needs to `wait` for the request to complete?\n */\nexport const isPending = (status: HttpOrCommunicationStatus | null | undefined) => !!status && getCommunicationStatus(status) === pending;\n\n/**\n * Returns true if the request timed out\n *\n * Client Can Automatically:\n * - notify the user that the request timed out\n * - try again (automatically or via user action)\n *\n * Client Developer Can:\n * - extend the timeoutFailure duration\n *\n * Server Developer Can:\n * - improve server performance and reliability\n */\nexport const isTimeout = (status: HttpOrCommunicationStatus | null | undefined) => !!status && getCommunicationStatus(status) === timeoutFailure;\n\n/**\n * Returns true if client can safely retry the request\n *\n * A a clearly-retryable failure:\n *\n * - network failure\n * - timeoutFailure\n * - aborted\n *\n * Note: some serverFailures will succeed on retry, but HTTP doesn't return clear indications which ones. To be safe, the client should not retry serverFailures indiscriminately.\n *\n * Client and Server Devs can\n * - investigate network, client and server performance and reliability issues\n */\nexport const isRetryableFailure = (status: HttpOrCommunicationStatus | null | undefined) => {\n if (!status) return false;\n const { status: communicationStatus, failure } = getCommunicationStatusDetails(status);\n return failure && (communicationStatus === networkFailure || communicationStatus === timeoutFailure || communicationStatus === aborted);\n};\n\n/**\n * Returns true if the status is a valid communication status\n */\nexport const isStatusValid = (status: string) => statusRegex.test(status);\n","import { clientFailure, clientFailureNotAuthorized, missing, networkFailure, serverFailure, success } from './CommunicationStatusConsts';\nimport { isStatusValid } from './CommunicationStatusTests';\nimport { CommunicationStatus, CommunicationStatusDetails, communicationStatuses } from './CommunicationStatusTypes';\n\n//***************************************************************************************************************\n// Private Helpers\n//***************************************************************************************************************\nconst getCommunicationStatusFromHttpStatusOrUndefined = (httpStatus: number): CommunicationStatus | undefined => {\n switch (Math.floor(httpStatus / 100)) {\n case 2: return success;\n case 3: return missing;\n case 4:\n switch (httpStatus) {\n case 401:\n case 403:\n case 407:\n case 451: return clientFailureNotAuthorized;\n case 404: return missing;\n default: return clientFailure;\n }\n case 5:\n switch (httpStatus) {\n case 502:\n case 503:\n case 504: return networkFailure;\n case 511: return clientFailureNotAuthorized;\n case 501: return missing; // 501 Not Implemented - i.e. it \"does not exist\" currently - i.e. missing\n case 505: // HTTP Version Not Supported - client should change the request\n case 530: return clientFailure;\n default: return serverFailure;\n }\n }\n return undefined;\n};\n\nconst getCommunicationStatusFromHttpStatus = (httpStatus: number): CommunicationStatus => {\n const status = getCommunicationStatusFromHttpStatusOrUndefined(httpStatus);\n if (!status) {\n throw new Error(`httpStatus ${httpStatus} is not a supported CommunicationStatus.`);\n }\n return status;\n};\n\n//***************************************************************************************************************\n// Public Functions\n//***************************************************************************************************************\nexport const getCommunicationStatusOrUndefined = <T extends number | CommunicationStatus | null | undefined>(\n status: T\n): T extends null | undefined ? undefined : (CommunicationStatus | undefined) => {\n if (status == null) return undefined as any;\n if (typeof status === 'string') {\n if (!isStatusValid(status)) {\n return undefined;\n }\n return status as any;\n }\n if (typeof status === 'number') {\n return getCommunicationStatusFromHttpStatusOrUndefined(status) as any;\n }\n return undefined;\n};\n\n/*\n * Returns the CommunicationStatus for a given CommunicationStatus or number\n * If the input is null or undefined, returns undefined, otherwise throws an error if the CommunicationStatus or number is not supported\n * @param status - The CommunicationStatus or number to get the CommunicationStatus for\n * @returns The CommunicationStatus for the given CommunicationStatus or number\n */\nexport const getCommunicationStatus = <T extends number | CommunicationStatus | null | undefined>(\n status: T\n): T extends null | undefined ? undefined : CommunicationStatus => {\n if (status == null) return undefined as any;\n if (typeof status === 'number') {\n return getCommunicationStatusFromHttpStatus(status) as any;\n }\n const communicationStatus: CommunicationStatus | undefined = getCommunicationStatusOrUndefined(status);\n if (!communicationStatus) {\n throw new Error(`${status} is not a valid CommunicationStatus.`);\n }\n return communicationStatus as any;\n};\n\n/**\n * Returns the HTTP status code for a given CommunicationStatus or number\n * If the input is null or undefined, returns undefined, otherwise throws an error if the CommunicationStatus or number is not supported\n * @param status - The CommunicationStatus or number to get the HTTP status code for\n * @returns The HTTP status code for the given CommunicationStatus or number\n */\nexport const getHttpStatus = <T extends CommunicationStatus | number | null | undefined>(status: T): T extends null | undefined ? undefined : number => {\n if (status == null) return undefined as any;\n const communicationStatus = getCommunicationStatus(status);\n const httpStatus = communicationStatuses[communicationStatus].httpStatus;\n if (httpStatus == null) {\n throw new Error(`There is no valid HttpStatus for ${status}.`);\n }\n return httpStatus as any;\n};\n\n/**\n * Returns CommunicationStatusDetails {status, httpStatus, message} given an HTTP status code\n *\n * Throws: Error if the HTTP status code is not supported (i.e. the 100 codes or non HTTP status code numbers)\n *\n * @param status - The HTTP status code to get the communication status for\n * @returns The CommunicationStatusDetails for the given status. Note, if an HTTP status is given, it won't necessarily be the httpStatus returned; HTTPStatuses are simplified along with CommunicationStatuses.\n */\nexport const getCommunicationStatusDetails = <T extends number | CommunicationStatus | null | undefined>(status: T):\n T extends null | undefined ? undefined : CommunicationStatusDetails => {\n if (status == null) return undefined as any;\n const communicationStatus = getCommunicationStatus(status);\n return communicationStatuses[communicationStatus] as any;\n};\n\nexport const getCommunicationStatusDetailsOrUndefined = <T extends number | CommunicationStatus | null | undefined>(\n status: T\n): T extends null | undefined ? undefined : (CommunicationStatusDetails | undefined) => {\n if (status == null) return undefined as any;\n const communicationStatus = getCommunicationStatusOrUndefined(status);\n if (communicationStatus == null) return undefined as any;\n return communicationStatuses[communicationStatus] as any;\n};\n"],"mappings":"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","names":["failure"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/CommunicationStatusConsts.ts","../../art-core-ts-types/src/Types.ts","../../art-core-ts-comprehensions/src/Comprehensions.ts","../../art-core-ts-comprehensions/src/DeepComprehensions.ts","../src/CommunicationStatusTypes.ts","../src/CommunicationStatusTests.ts","../src/CommunicationStatusConversions.ts"],"sourcesContent":["export * from \"./CommunicationStatusConsts\";\nexport * from \"./CommunicationStatusConversions\";\nexport * from \"./CommunicationStatusTests\";\nexport * from \"./CommunicationStatusTypes\";\n","// Export status constants\nimport type { CommunicationStatus } from './CommunicationStatusTypes';\n\n/**\n * HTTP 2xx responses\n *\n * Client Can Automatically:\n * - Process the successful response\n * - Update UI to reflect success\n *\n * Client Developer Can:\n * - Handle the successful response data\n */\nexport const success: CommunicationStatus = \"success\";\n\n/**\n * Resource not found\n *\n * HTTP Status Codes Covered:\n * - 404: Not Found\n *\n * Client Can Automatically:\n * - notify the user that the resource was not found\n * - prompt the user to request a different resource\n *\n * Client Developer Can:\n * - fix the bad resource paths\n */\nexport const missing: CommunicationStatus = \"missing\";\n\n/**\n * Client-side errors; i.e. the client needs to change the request somehow to succeed\n *\n * HTTP Status Codes Covered:\n * - 400: Bad Request\n * - 401: Unauthorized\n * - 403: Forbidden\n * - 407: Proxy Authentication Required\n * - 409: Conflict\n * - 422: Unprocessable Entity\n *\n * Client Can Automatically:\n * - Notify the user that the client is experiencing issues\n * - Prompt user to correct invalid input\n *\n * Client Developer Can:\n * - use isClientFailureNotAuthorized to check for 401/403/407/451\n * - fix the request to avoid the 4xx error\n * - validate input before sending requests\n */\nexport const clientFailure: CommunicationStatus = \"clientFailure\";\n\n/**\n * Unauthorized requests; i.e. client needs to change the credentials (or the grants for the current credentials) to succeed\n *\n * HTTP Status Codes Covered:\n * - 401: Unauthorized\n * - 403: Forbidden\n * - 407: Proxy Authentication Required\n * - 451: Unavailable For Legal Reasons\n *\n * Client Can Automatically:\n * - refresh the request token\n * - prompt the user to re-login\n * - ask the user to contact the administrator for access\n *\n * Client and Server Developer Can:\n * - fix authorization / authentication bugs\n */\nexport const clientFailureNotAuthorized: CommunicationStatus = \"clientFailureNotAuthorized\";\n\n/**\n * Server-side errors; i.e. internal server errors\n *\n * HTTP Status Codes Covered:\n * - 500: Internal Server Error\n * - 502: Bad Gateway\n * - 503: Service Unavailable\n * - 504: Gateway Timeout\n *\n * Client Can Automatically:\n * - Ask the user to try again later\n * - Notify the user that the server is experiencing issues\n * - Implement automatic retry with backoff\n *\n * Client Developer: (probably) can't fix\n *\n * Server Developer Can:\n * - fix the server to avoid the 5xx error\n * - fix server infrastructure to avoid the 5xx error\n */\nexport const serverFailure: CommunicationStatus = \"serverFailure\";\n\n/**\n * Request fails due to network connectivity issues\n *\n * HTTP Status Codes Covered: NONE (server was not reachable)\n *\n * Client Can Automatically:\n * - Prompt the user to fix the network connection\n * - Retry the request when network is available\n * - Monitor network status for recovery\n *\n * Client Developer Can:\n * - fix bad network constants (like address, ports, etc.)\n * - implement offline-first capabilities\n */\nexport const networkFailure: CommunicationStatus = \"networkFailure\";\n\n/**\n * Request was cancelled by client\n *\n * Client Can Automatically:\n * - notify the user that the request was cancelled\n * - prompt the user to try again\n * - cleanup any pending state\n *\n * Client Developer Can:\n * - fix the client to not abort the request unnecessarily\n * - implement proper cleanup on abort\n */\nexport const aborted: CommunicationStatus = \"aborted\";\n\n/**\n * Request is in progress\n *\n * Client Can Automatically:\n * - notify the user that the request is in progress\n * - show the user progress (if available)\n * - allow the user to cancel the request\n *\n * Client Developer Can:\n * - if \"pending\" was not expected, maybe the client needs to `wait` for the request to complete?\n * - implement proper loading states\n */\nexport const pending: CommunicationStatus = \"pending\";\n\n/**\n * Any error response (HTTP 4xx/5xx) or network/abort failures\n *\n * HTTP Status Codes Covered:\n * - 4xx: Client-side errors (except 404)\n * - 5xx: Server-side errors\n * - Network failures\n * - Abort failures\n *\n * Client Can Automatically:\n * - Show appropriate error message to user\n * - Implement generic error handling\n * - Log errors for debugging\n *\n * Client Developer Can:\n * - Use more specific is* functions for targeted error handling\n * - Implement proper error recovery strategies\n */\nexport const failure: CommunicationStatus = \"failure\";\n\n/**\n * Request timed out\n *\n * Client Can Automatically:\n * - notify the user that the request timed out\n * - try again (automatically or via user action)\n *\n * Client Developer Can:\n * - fix the client to not timeoutFailure the request\n * - implement proper timeoutFailure handling\n */\nexport const timeoutFailure: CommunicationStatus = \"timeoutFailure\";\n\n/**\n * Client has disabled the request explicitly.\n *\n * Client Can:\n * - re-enable the request\n */\nexport const disabled: CommunicationStatus = \"disabled\";\n\n/**\n * Unknown communication status\n *\n * Client Can:\n * - log the unknown status for debugging\n */\nexport const unknown: CommunicationStatus = \"unknown\";\n","import { PlainObject } from \"./TypeScriptTypes\"\n\ntype TypedArray = Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array\n\n/*\n\n @isPromise: (obj) => obj? && isFunction(obj.then) && !isFunction obj\n @isRegExp: (obj) => obj.constructor.name == \"RegExp\"\n @isNumber: isNumber = (obj) => typeof obj == \"number\"\n\n isNonNegativeInt: (x) ->\n ((x | 0) == x) &&\n x >= 0\n\n @isError: (obj) => obj? && obj instanceof Error\n @isDate: (obj) => obj?.constructor == Date\n @isString: isString = (obj) => typeof obj == \"string\"\n @isFunction: isFunction = (obj) => typeof obj == \"function\"\n @isEmptyObject: (obj) => Object.keys(obj).length == 0\n @isBoolean: (obj) => obj == true || obj == false\n\n @isArrayBuffer: isArrayBuffer = if global.ArrayBuffer\n (obj) -> obj? && obj.constructor == ArrayBuffer\n else -> false\n @isTypedArray: (obj) -> obj? && obj.length >= 0 && obj.length == (obj.length | 0) && isArrayBuffer obj.buffer\n\n */\n\n/**\n * Returns true if the value is an object. (note, Arrays are objects)\n * This is only false for null, undefined, functions, and primitives like strings, numbers, and booleans.\n * @param v\n * @returns\n */\nexport const isObject = (v: any): v is Record<string, any> => v != null && typeof v === 'object'\n\n/**\n * Returns true if the value is a plain object - i.e. an object who's prototype is Object\n * @param v\n * @returns\n */\nexport const isPlainObject = (v: any): v is PlainObject => {\n if (!isObject(v)) return false\n if (v.constructor === Object) return true // fast pass, but could fail if v was created in a different context with a different instance of Object\n const prototype = Object.getPrototypeOf(v)\n if (prototype === null) return true\n return null == Object.getPrototypeOf(prototype)\n}\n\nexport const asPlainObject = (v: any): PlainObject => isPlainObject(v) ? v : {}\n\nexport const isFunction = (obj: any): obj is Function => typeof obj === \"function\"\nexport const isNumber = (obj: any): obj is number => typeof obj === \"number\"\nexport const isString = (obj: any): obj is string => typeof obj === \"string\"\nexport const isArrayBuffer = (obj: any): obj is ArrayBuffer => obj != null && obj.constructor === ArrayBuffer\nexport const isArray = (obj: any): obj is any[] => Array.isArray(obj)\n\nexport const isPromise = (obj: any): obj is Promise<any> => obj != null && isFunction(obj.then) && !isFunction(obj)\nexport const isRegExp = (obj: any): obj is RegExp => obj?.constructor.name === \"RegExp\"\nexport const isError = (obj: any): obj is Error => obj != null && obj instanceof Error\nexport const isDate = (obj: any): obj is Date => obj?.constructor === Date\nexport const isEmptyObject = (obj: any): obj is Record<string, never> => Object.keys(obj).length === 0\nexport const isBoolean = (obj: any): obj is boolean => obj === true || obj === false\nexport const isTypedArray = (obj: any): obj is TypedArray =>\n obj != null &&\n obj.length >= 0 &&\n obj.length === (obj.length | 0) &&\n isArrayBuffer(obj.buffer)\n\nexport const isNonNegativeInt = (x: number): x is number => ((x | 0) === x) && x >= 0\n\nexport const stringIsPresent = (str: string): boolean => isString(str) && !/^(\\s+|)$/.test(str)\n\nexport const exists = (value: any): boolean => value != null\nexport const doesNotExist = (value: any): boolean => !exists(value)\n\nexport const isNull = (value: any): boolean => value === null\nexport const isNotNull = (value: any): boolean => !isNull(value)\n\nexport const isUndefined = (value: any): boolean => value === undefined\nexport const isNotUndefined = (value: any): boolean => !isUndefined(value)\n\nexport const isNullish = (value: any): boolean => value == null || value == undefined\nexport const isNotNullish = (value: any): boolean => !isNullish(value)\n\n/**\n * present returns true if \"there is a value _present_\"\n *\n * Specifically:\n * - if `value.getPresent()` is a function; it's called and it's value is returned\n * - if `value.present()` is a function; it's called and it's value is returned\n * - else: returns `true` if `!null`, `!undefined` and `!(string with only whitespace)`\n *\n * > Inspired by Ruby's `present?` method\n *\n * @param v\n * @returns\n */\nexport const present = <T>(v: T): v is NonNullable<T> => {\n if (v == null) return false\n if (isFunction((v as any).getPresent)) {\n return (v as any).getPresent()\n } else if (isFunction((v as any).present)) {\n return (v as any).present()\n } else if (isString(v)) {\n return stringIsPresent(v)\n } else return true\n}\n","import { isPlainObject, isFunction, exists } from '@art-suite/art-core-ts-types'\nimport { EachFunction, ArrayFunction, ObjectFunction, ReduceFunction, FindFunction, AnyContainer, ArrayInput, ObjectInput, NotPresent } from './ComprehensionTypes'\n\nconst isMap = (source: any): source is Map<any, any> => source instanceof Map;\nconst isSet = (source: any): source is Set<any> => source instanceof Set;\n\nexport const isArrayIterable = (source: any): source is any[] => {\n if (typeof source === 'string') return false\n if (isFunction(source)) return false\n return source != null && source.length >= 0;\n}\n\nexport const isOfIterable = (o: any): boolean => {\n if (typeof o === 'string') return false\n if (isFunction(o)) return false\n return isFunction(o[Symbol.iterator] || o.next)\n}\n\nconst returnFirstArg = (a: any) => a;\nconst returnSecondArg = (a: any, b: any) => b;\n\nconst emptyOptions = {};\n\ntype CoreIterationFunction = (value: any, key: any) => boolean; // returns true to stop iteration\n\n/**\n * Tight function to abstract away all possible iteration methods based on the source container type.\n *\n * Iterates over the source collection, calling the given function for each element.\n *\n * Stops when the body function returns true.\n * Does NOT return anything. If you need a return value, must set it as a side-effect of the body function.\n *\n * @param source - The collection to iterate (array, object, Map, Set, etc.)\n * @param body - The function to call for each element.\n * @returns void\n */\nconst iterate = (source: any, body: CoreIterationFunction): void => {\n if (exists(source))\n if (isArrayIterable(source)) for (let key = 0, { length } = source; key < length; key++) { if (body(source[key], key)) break; }\n else if (isPlainObject(source)) for (const key in source) { if (body(source[key], key)) break; }\n else if (isMap(source)) for (const [key, value] of source.entries()) { if (body(value, key)) break; }\n // else if (isSet(source)) for (const value of source) { if (body(value, value)) break; }\n else if (isOfIterable(source)) { let count = 0; for (const value of source) { if (body(value, count++)) break; } }\n else throw new Error(`Unsupported source type: ${typeof source}`);\n};\n\n/*\n Returns a function that handles \"with\", \"when\" and \"stopWhen\" comprehension clauses:\n\n 1. Returns true if the \"stopWhen\" is provided and returns true, otherwise returns it will return false\n 2. If stopWhen is false, \"when\" and \"with\" are processed\n 3. If there is no \"when\" or \"when\" returns true, \"with\" is called.\n*/\nconst normalizeBody = (withFunction: (value: any, key: any) => any, options: AcceptedComprehensionOptions): (value: any, key: any) => boolean => {\n let { when, stopWhen } = options;\n if (when && stopWhen) {\n return (v: any, k: any) => {\n if (stopWhen(v, k)) return true;\n if (when(v, k)) withFunction(v, k);\n return false;\n }\n }\n if (when) {\n return (v: any, k: any) => {\n if (when(v, k)) withFunction(v, k);\n return false;\n }\n }\n if (stopWhen) {\n return (v: any, k: any) => {\n if (stopWhen(v, k)) return true;\n withFunction(v, k);\n return false;\n }\n }\n return (v: any, k: any) => { withFunction(v, k); return false; };\n};\n\n\nlet normalizeKeyFunction = (source: any, options: AcceptedComprehensionOptions) =>\n options.withKey || (isArrayIterable(source) ? returnFirstArg : returnSecondArg)\n\nconst _each = (source: any, withFunction: (value: any, key: any) => any, options: AcceptedComprehensionOptions) => {\n iterate(source, normalizeBody(withFunction, options));\n};\n\n//************************************************************************\n// NORMALIZED COMPREHENSION FUNCTIONS\n//************************************************************************\ntype NormalizedIterationFunction = (source: any, options: NormalizedComprehensionOptions) => any;\n\nconst normalizedEach: NormalizedIterationFunction = (source: any, options: NormalizedComprehensionOptions) => {\n _each(source, options.with, options);\n return options.into;\n};\n\nconst normalizedArrayIteration: NormalizedIterationFunction = (source: any, options: NormalizedComprehensionOptions) => {\n let { into, with: withFunction } = options;\n if (into == null) into = [];\n _each(source, (v: any, k: any) => into.push(withFunction(v, k)), options);\n return into;\n};\n\nconst normalizedObjectIteration: NormalizedIterationFunction = (source: any, options: NormalizedComprehensionOptions) => {\n let { into, with: withFunction } = options;\n if (into == null) into = {};\n let withKey = normalizeKeyFunction(source, options);\n _each(source, (v, k) => (into[withKey(v, k)] = withFunction(v, k)), options);\n return into;\n};\n\nconst normalizedReduceIteration: NormalizedIterationFunction = (source: any, options: NormalizedComprehensionOptions) => {\n let { into, with: withFunction } = options;\n let first = into === undefined;\n _each(source, (v: any, k: any) => {\n if (first) { first = false; into = v; }\n else {\n into = withFunction(into, v, k)\n }\n }, options);\n return into;\n};\n\nconst normalizedFindIteration: NormalizedIterationFunction = (source: any, options: NormalizedComprehensionOptions) => {\n let { with: withFunction } = options;\n let { when } = options;\n let found: any | undefined = undefined;\n iterate(\n source,\n when\n ? (v, k) => {\n if (when(v, k)) {\n found = withFunction(v, k);\n return true; // signal to stop iteration\n }\n return false;\n }\n : (v, k) => {\n found = withFunction(v, k) // stops iteration if withFunction returns an value that \"exists\" (is not undefined, non null)\n return found != null;\n }\n );\n return found;\n};\n\n//####################\n// PRIVATE\n//####################\n\n// WithFunction has two signatures: value + key, or for reduce, accumulator + value + key\ntype ValueKeyFunction = (value?: any, key?: any) => any;\ntype AccumulatorValueKeyFunction = (accumulator?: any, value?: any, key?: any) => any;\ntype WithFunction = ValueKeyFunction | AccumulatorValueKeyFunction;\ntype WhenFunction = (value: any, key: any) => any;\ntype WithKeyFunction = (value: any, key: any) => any;\n\ntype AcceptedComprehensionOptions = {\n into?: any;\n inject?: any; // alias for into - used to make \"reduce\" calls make more sense\n returning?: any; // alias for into - used to make \"each\" calls make more sense\n with?: WithFunction;\n when?: WhenFunction;\n withKey?: WithKeyFunction;\n stopWhen?: (value: any, key: any) => any;\n}\n\ntype WithOrOptions = WithFunction | AcceptedComprehensionOptions;\n\nconst isAcceptedComprehensionOptions = (o: any): o is AcceptedComprehensionOptions => isPlainObject(o)\n\n// the 'with' param will always exist when normalized\ntype NormalizedComprehensionOptions = Omit<AcceptedComprehensionOptions, 'with' | 'inject' | 'returning'> & {\n with: WithFunction;\n}\n\n/**\n * Returns the first non-undefined value from into, inject, or returning\n *\n * @param into - The 'into' parameter.\n * @param inject - The 'inject' parameter.\n * @param returning - The 'returning' parameter.\n * @returns The normalized 'into' parameter.\n */\nconst firstNotUndefined = (into: any, inject: any, returning: any) => {\n if (into === undefined) into = inject\n if (into === undefined) into = returning\n return into\n}\n\nconst normalizeIterationParams = (withOrOptions?: WithOrOptions): NormalizedComprehensionOptions => {\n if (isAcceptedComprehensionOptions(withOrOptions)) {\n const { with: withFunction, into, inject, returning, ...rest } = withOrOptions;\n return { ...rest, into: firstNotUndefined(into, inject, returning), with: withFunction ?? returnFirstArg };\n }\n if (isFunction(withOrOptions)) {\n return { with: withOrOptions };\n }\n return { with: returnFirstArg };\n};\n\n/*\nNormalizes input params for the 'iteration' function.\nSince this normalizes multiple params, and therefor would need to return\nan new array or new object otherwise, we pass IN the iteration function\nand pass the params directly to it. This keeps the computed params on the\nstack and doesn't create new objects.\n\nIN signature 1: (iteration, source, withFunction) ->\nIN signature 2: (iteration, source, options) ->\nIN signature 3: (iteration, source) ->\n\nIN:\niteration: (source, into, withFunction, options) -> out\n\n The iteration function is invoked last with the computed args.\n Its results are returned.\n\n IN:\n source: passed directly through from inputs\n into: passed directly through from inputs OR from options.into\n withFunction: passed directly through from inputs OR from options.with\n options: passed directly through from inputs OR {}\n (guaranteed to be set and a plainObject)\n\nsource: the source collection to be iterated over. Passed directly through.\n\ninto: passed through to 'iteration'\nwithFunction: passed through to 'iteration'\noptions: passed through to 'iteration' AND:\n\n into: set 'into' from the options object\n with: set 'withFunction' from the options object\n\nOUT: out\n*/\nconst invokeNormalizedIteration = (\n normalizedIterationFunction: NormalizedIterationFunction,\n source: any,\n withOrOptions: WithOrOptions\n) => normalizedIterationFunction(source, normalizeIterationParams(withOrOptions));\n\n/**\n * Iterates over the provided collection, calling the given function for each element.\n *\n * Unlike other comprehensions, `each` is designed for side effects and does not build a new collection.\n *\n * **Return value:**\n * - If an `into`, `inject`, or `returning` option is provided (or as the second argument), that value is returned (not modified by `each` itself).\n * - If no such value is provided, returns `undefined`.\n *\n * This allows you to use `each` for side effects while optionally threading a value through the iteration.\n *\n * @param source The collection to iterate (array, object, Map, Set, etc.)\n * @param withOrOptions Optional: Either the `into` value or the function to call for each element.\n * @returns The `into`/`inject`/`returning` value if provided, otherwise `undefined`.\n */\nexport const each: EachFunction = ((source: any, withOrOptions: WithOrOptions) => invokeNormalizedIteration(normalizedEach, source, withOrOptions)) as EachFunction;\n\n/**\n * Builds a new array from the provided collection, optionally transforming or filtering elements.\n *\n * Options:\n * - `with`: function to transform each element (like map)\n * - `when`: function to filter elements (like filter)\n * - `into`: array to push results into (default: new array)\n *\n * @param source The collection to iterate (array, object, Map, Set, etc.)\n * @param withOrOptions Optional: `with` function, or options object, or `into` array.\n * @returns The resulting array.\n */\nexport const array: ArrayFunction = ((source: any, withOrOptions: WithOrOptions) => invokeNormalizedIteration(normalizedArrayIteration, source, withOrOptions)) as ArrayFunction;\n\n/**\n * Builds a new object from the provided collection, optionally transforming keys/values or filtering elements.\n *\n * Options:\n * - `with`: function to transform each value\n * - `when`: function to filter elements\n * - `key`/`withKey`: function to determine output keys\n * - `into`: object to assign results into (default: new object)\n *\n * Defaults:\n * - no `with`: uses the source container's \"values\" as the default\n * - no `withKey`: from arrays, uses the values as keys, from objects, uses the keys as keys\n * - no `into`: creates a new object\n *\n * Simplest example use: `object([\"sally\", \"billy\", \"chad\"])` => { \"sally\": \"sally\", \"billy\": \"billy\", \"chad\": \"chad\" }\n *\n * @param source The collection to iterate (array, object, Map, Set, etc.)\n * @param withOrOptions Optional: `with` function, or options object, or `into` object.\n * @returns The resulting object.\n */\nexport const object: ObjectFunction = ((source: any, withOrOptions: WithOrOptions) => invokeNormalizedIteration(normalizedObjectIteration, source, withOrOptions)) as ObjectFunction;\n\n/**\n * Reduces the provided collection to a single value, similar to Array.prototype.reduce.\n *\n * The first element is used as the initial value unless an `into`/`inject`/`returning` option is provided.\n *\n * Options:\n * - `with`: reducer function (receives accumulator, value, key)\n * - `when`: function to filter elements\n * - `into`/`inject`/`returning`: initial value for the reduction\n *\n * @param source The collection to reduce (array, object, Map, Set, etc.)\n * @param withOrOptions Optional: initial value or reducer function or options object.\n * @returns The reduced value.\n */\nexport const reduce: ReduceFunction = ((source: any, withOrOptions: WithOrOptions) => invokeNormalizedIteration(normalizedReduceIteration, source, withOrOptions)) as ReduceFunction;\n\n/**\n * Finds and returns the first value in the collection that matches the given criteria.\n *\n * Options:\n * - `with`: function to transform the found value\n * - `when`: function to filter elements (predicate)\n *\n * @param source The collection to search (array, object, Map, Set, etc.)\n * @param withOrOptions Optional: predicate or options object.\n * @returns The found value, or undefined if not found.\n */\nexport const find: FindFunction = ((source: any, withOrOptions: WithOrOptions) => invokeNormalizedIteration(normalizedFindIteration, source, withOrOptions)) as FindFunction;\n\n\n/**\n * Returns true if the source is a comprehension iterable.\n *\n * A comprehension iterable is any object that can be iterated over.\n *\n * This is different from isFullySupportedComprehensionIterable, which only checks if we can both generate and iterate over the source.\n *\n * NOTE strings are not considered comprehension iterables.\n *\n * @param source - The source to check.\n * @returns True if the source is a comprehension iterable, false otherwise.\n */\nexport const isComprehensionIterable = (source: any): source is AnyContainer<any> =>\n isArrayIterable(source) || isPlainObject(source) || isMap(source) || isSet(source) || isOfIterable(source)\n\n/**\n * Returns true if the source is a fully supported comprehension iterable.\n *\n * Fully supported means we can both generate as well as iterate over the source.\n *\n * This is different from isComprehensionIterable, which only checks if we can iterate over the source.\n *\n * This is useful for cases where we need to know if we can both generate and iterate over the source,\n * such as when we are using the source in a comprehension.\n *\n * Currently, this is only true for arrays and objects. TODO: add Map and Set support.\n * @param source - The source to check.\n * @returns True if the source is a fully supported comprehension iterable, false otherwise.\n */\nexport const isFullySupportedComprehensionIterable = (source: any): source is AnyContainer<any> =>\n isArrayIterable(source) || isPlainObject(source)\n","/**\n * DeepComprehensions is a library that provides a way to map and iterate over deeply nested comprehension iterables.\n *\n * It is useful for cases where you need to map or iterate over a deeply nested comprehension iterable.\n *\n * NOTE: due to their nature, deep comprehensions don't support TypeScript's type inference. You'll need to post-validate or coerce the results to the correct type.\n *\n * TODO: add Map and Set support.\n * TODO: add {when} support. Example usage: deepStripNull = deepMap(obj, {when: v => v !== null})\n */\nimport { isPlainObject } from '@art-suite/art-core-ts-types'\nimport { each, isComprehensionIterable, isFullySupportedComprehensionIterable, isArrayIterable, array, object } from './Comprehensions'\nimport { AnyContainer, FullySupportedContainer, ArrayInput, ObjectInput, NotPresent } from './ComprehensionTypes'\nimport { isFunction } from '@art-suite/art-core-ts-types'\n\nexport type DeepWithFunction = (value: any, key: any) => void\nexport type DeepWhenFunction = (value: any, key: any) => boolean\n\nexport type DeepOptions = {\n when?: DeepWhenFunction\n with?: DeepWithFunction\n}\n\nexport type DeepSecondParameter = DeepWithFunction | DeepOptions\n\n//******************************************************************************************************************\n// HELPERS\n//******************************************************************************************************************\n\nconst defaultWithFunction: DeepWithFunction = v => v\nconst defaultWhenFunction: DeepWhenFunction = () => true\n\ntype DeepOptionsFullSupport = {\n when: DeepWhenFunction\n with: DeepWithFunction\n}\n\nconst normalizeDeepOptions = (options: DeepSecondParameter): DeepOptionsFullSupport => {\n if (isFunction(options)) {\n return { with: options, when: defaultWhenFunction }\n }\n return { with: options.with ?? defaultWithFunction, when: options.when ?? defaultWhenFunction }\n}\n\nconst deepEachR = (obj: AnyContainer<any>, options: DeepOptionsFullSupport) =>\n each(obj, {\n when: options.when,\n with: (value: any, key: any) =>\n isComprehensionIterable(value)\n ? deepEachR(value, options)\n : options.with(value, key)\n })\n\nconst deepMapR = (obj: AnyContainer<any>, options: DeepOptionsFullSupport) =>\n mapInternal(obj, {\n when: options.when, with: (value: any, key: any) =>\n isFullySupportedComprehensionIterable(value)\n ? deepMapR(value, options)\n : options.with(value, key)\n })\n\nconst mapInternal = (source: ArrayInput<any> | ObjectInput<any> | NotPresent, options: DeepOptionsFullSupport) => {\n if (isArrayIterable(source)) return array(source, options)\n if (isPlainObject(source)) return object(source, options)\n throw new Error(`Unsupported source type: ${typeof source}`)\n}\n\n//******************************************************************************************************************\n// EXPORTS\n//******************************************************************************************************************\n/**\n * Maps over a fully supported comprehension iterable, shallowly.\n *\n * Returns the same container type (array or object) as the original object, but with the values mapped.\n *\n * @param source - The source to map over.\n * @param options - the map-function or {with: the map-function, when: the when-function}\n * @returns The mapped container.\n */\nexport const map = (source: ArrayInput<any> | ObjectInput<any> | NotPresent, options: DeepSecondParameter) =>\n mapInternal(source, normalizeDeepOptions(options))\n\n/**\n * Iterates over a fully supported comprehension iterable, and any nested isComprehensionIterable values.\n *\n * withFunction is called for each value that is NOT isComprehensionIterable and true for whenFunction (if provided).\n *\n * whenFunction is called on EVERY value, isComprehensionIterable or not. If it returns false, isComprehensionIterable values will be skipped.\n *\n * @param obj - The object to iterate over.\n * @param options - the with-function or {with: the with-function, when: the when-function}\n * @returns The object.\n */\nexport const deepEach = (obj: AnyContainer<any>, options: DeepSecondParameter) =>\n deepEachR(obj, normalizeDeepOptions(options))\n\n/**\n * Maps over a fully supported comprehension iterable, and any nested fully supported comprehension iterables.\n *\n * Returns the same structure (of fully supported comprehension iterables) as the original object, but with the values mapped.\n * If the source is not a fully supported comprehension iterable, it will return the source unchanged.\n * If the source is a fully supported comprehension iterable, it will return a new fully supported comprehension iterable with the values mapped.\n *\n * whenFunction is called on EVERY value, isComprehensionIterable or not. If it returns false, isComprehensionIterable values will be skipped.\n *\n * @param obj - The object to map over.\n * @param options - the map-function or {with: the map-function, when: the when-function}\n * @returns The mapped object.\n */\nexport const deepMap = (obj: FullySupportedContainer<any>, options: DeepSecondParameter) =>\n deepMapR(obj, normalizeDeepOptions(options))\n","import { object } from '@art-suite/art-core-ts-comprehensions';\n\nconst communicationStatusesPartials = {\n // HTTP Success Statuses\n success: { httpStatus: 200 },\n\n // HTTP Failure Statuses\n missing: { httpStatus: 404, failure: true },\n clientFailure: { httpStatus: 400, clientFailure: true, failure: true },\n clientFailureNotAuthorized: { httpStatus: 403, clientFailure: true, failure: true },\n serverFailure: { httpStatus: 500, failure: true, serverFailure: true },\n failure: { httpStatus: 500, failure: true },\n\n // Non-HTTP Statuses\n pending: { httpStatus: undefined },\n networkFailure: { httpStatus: undefined, failure: true },\n aborted: { httpStatus: undefined, failure: true },\n timeoutFailure: { httpStatus: undefined, failure: true },\n disabled: { httpStatus: undefined },\n unknown: { httpStatus: undefined, failure: true }\n};\n\n/**\n * The core of Art-core-ts-communication-status: A simplified set of statuses as a human-readable and machine-interpretable string\n * representing all the possible communication statuses that are pragmatically actionable.\n */\nexport type CommunicationStatus = keyof typeof communicationStatusesPartials;\n\nexport type HttpOrCommunicationStatus = CommunicationStatus | number;\n\n/**\n * Details about a communication status\n *\n * @param httpStatus - The HTTP status code for the communication status\n * @param failure - Whether the communication status is a failure\n * @param clientFailure - Whether the communication status is a client failure\n * @param serverFailure - Whether the communication status is a server failure\n * @param status - The communication status - alias for communicationStatus\n * @param communicationStatus - The communication status\n */\nexport interface CommunicationStatusDetails {\n httpStatus?: number;\n failure?: boolean;\n clientFailure?: boolean;\n serverFailure?: boolean;\n status: CommunicationStatus;\n communicationStatus: CommunicationStatus;\n message: string;\n}\n\nexport const UnknownCommunicationStatusDetails: CommunicationStatusDetails = {\n status: 'unknown',\n communicationStatus: 'unknown',\n message: 'Unknown communication status',\n failure: true\n};\n\nexport const communicationStatuses: Record<CommunicationStatus, CommunicationStatusDetails> = object(communicationStatusesPartials, (details: any, status) => ({\n ...details,\n failure: !!details.failure,\n clientFailure: !!details.clientFailure,\n serverFailure: !!details.serverFailure,\n status: status as CommunicationStatus,\n communicationStatus: status as CommunicationStatus,\n message: details.httpStatus ? `${status} (${details.httpStatus})` : status\n})) as Record<CommunicationStatus, CommunicationStatusDetails>;\n\nexport type CommunicationStatuses = typeof communicationStatuses;\n\n/**\n * RegEx returns true for all valid communication statuses\n */\nexport const statusRegex = new RegExp(`^(${Object.keys(communicationStatuses).join('|')})$`);\n","import { isString } from '@art-suite/art-core-ts-types';\nimport { aborted, clientFailureNotAuthorized, disabled, missing, networkFailure, pending, success, timeoutFailure } from './CommunicationStatusConsts';\nimport { getCommunicationStatus, getCommunicationStatusDetails } from './CommunicationStatusConversions';\nimport { HttpOrCommunicationStatus, statusRegex } from './CommunicationStatusTypes';\n\n// Core status check functions\n/** Returns true for HTTP 2xx responses */\nexport const isSuccess = (status: HttpOrCommunicationStatus | null | undefined): boolean => !!status && getCommunicationStatus(status) === success;\n\n/**\n * Returns true for any error response (HTTP 4xx/5xx) or network/abort failures\n *\n * HTTP Status Codes Covered:\n * - 4xx: Client-side errors (except 404)\n * - 5xx: Server-side errors\n * - Network failures\n * - Abort failures\n *\n * Client Can:\n * - Use a different is* function for more specific checks\n */\nexport const isFailure = (status: HttpOrCommunicationStatus | null | undefined): boolean => !!(status && getCommunicationStatusDetails(status).failure);\n\n/**\n * Returns true for client-side errors\n *\n * HTTP Status Codes Covered:\n * - 400: Bad Request\n * - 401: Unauthorized\n * - 403: Forbidden\n * - 407: Proxy Authentication Required\n * - 409: Conflict\n * - 422: Unprocessable Entity\n *\n * Client Can Automatically:\n * - Notify the user that the client is experiencing issues\n *\n * Client Developer Can:\n * - use isClientFailureNotAuthorized to check for 401/403/407/451\n * - fix the request to avoid the 4xx error\n*/\nexport const isClientFailure = (status: HttpOrCommunicationStatus | null | undefined): boolean => !!(status && getCommunicationStatusDetails(status).clientFailure);\n\n/**\n * Returns true for server-side errors\n *\n * HTTP Status Codes Covered:\n * - 500: Internal Server Error\n * - 502: Bad Gateway\n * - 503: Service Unavailable\n * - 504: Gateway Timeout\n *\n * Client Can Automatically:\n * - Ask the user to try again later\n * - Notify the user that the server is experiencing issues\n *\n * Client Developer: (probably) can't fix\n *\n * Server Developer Can:\n * - fix the server to avoid the 5xx error\n * - fix server infrastructure to avoid the 5xx error (e.g. Bad Gateway, Service Unavailable, Gateway Timeout)\n*/\nexport const isServerFailure = (status: HttpOrCommunicationStatus | null | undefined): boolean => !!(status && getCommunicationStatusDetails(status).serverFailure);\n\n/**\n * Returns true when request fails due to network connectivity issues\n *\n * HTTP Status Codes Covered: NONE (server was not reachable)\n *\n * Client Can Automatically:\n * - Prompt the user to fix the network connection\n * - Retry the request\n *\n * Client Developer Can:\n * - fix bad network constants (like address, ports, etc.)\n*/\nexport const isNetworkFailure = (status: HttpOrCommunicationStatus | null | undefined): boolean => !!(status && getCommunicationStatus(status) === networkFailure);\n\n/** Returns true for server errors, network failures and aborted requests; i.e. the client did nothing wrong (as far as we can tell); client can ask the user to do something OR retry the request */\nexport const isNonClientFailure = (status: HttpOrCommunicationStatus | null | undefined): boolean => {\n if (!status) return false;\n const details = getCommunicationStatusDetails(status);\n return !!(details.failure && !details.clientFailure);\n};\n\n/**\n * Returns true for unauthorized requests (not authenticated or not authorized)\n *\n * HTTP Status Codes Covered:\n * - 401: Unauthorized\n * - 403: Forbidden\n * - 407: Proxy Authentication Required\n * - 451: Unavailable For Legal Reasons\n * - 511: Network Authentication Required\n *\n * Client Can Automatically:\n * - refresh the request token\n * - prompt the user to re-login\n * - ask the user to contact the administrator for access\n *\n * Client and Server Developer Can:\n * - fix authorization / authentication bugs\n */\nexport const isClientFailureNotAuthorized = (status: HttpOrCommunicationStatus | null | undefined): boolean =>\n !!status &&\n getCommunicationStatus(status) === clientFailureNotAuthorized;\n\n/**\n * Returns true when request was cancelled by client\n *\n * Client Can Automatically:\n * - notify the user that the request was cancelled\n * - prompt the user to try again\n *\n * Client Developer Can:\n * - fix the client to not abort the request\n */\nexport const isAborted = (status: HttpOrCommunicationStatus | null | undefined): boolean => !!(status && getCommunicationStatus(status) === aborted);\n\n/**\n * Returns true when resource not found / not available\n *\n * HTTP Status Codes Covered:\n * - 404: Not Found\n * - 501: Not Implemented\n *\n * Client Can Automatically:\n * - notify the user that the resource was not found\n * - prompt the user to request a different resource\n *\n * Client Developer Can:\n * - fix the bad resource paths\n */\nexport const isMissing = (status: HttpOrCommunicationStatus | null | undefined): boolean => !!(status && getCommunicationStatus(status) === missing);\n\n/**\n * Returns true while request is in progress\n *\n * Client Can Automatically:\n * - notify the user that the request is in progress\n * - show the user progress (if available)\n * - allow the user to cancel the request (trigging an \"aborted\" communication status)\n *\n * Client Developer Can:\n * - if \"pending\" was not expected, maybe the client needs to `wait` for the request to complete?\n */\nexport const isPending = (status: HttpOrCommunicationStatus | null | undefined): boolean => !!(status && getCommunicationStatus(status) === pending);\n\n/**\n * Returns true if the request timed out\n *\n * Client Can Automatically:\n * - notify the user that the request timed out\n * - try again (automatically or via user action)\n *\n * Client Developer Can:\n * - extend the timeoutFailure duration\n *\n * Server Developer Can:\n * - improve server performance and reliability\n */\nexport const isTimeout = (status: HttpOrCommunicationStatus | null | undefined): boolean => !!(status && getCommunicationStatus(status) === timeoutFailure);\n\n/**\n * Returns true if client can safely retry the request\n *\n * A a clearly-retryable failure:\n *\n * - network failure\n * - timeoutFailure\n * - aborted\n *\n * Note: some serverFailures will succeed on retry, but HTTP doesn't return clear indications which ones. To be safe, the client should not retry serverFailures indiscriminately.\n *\n * Client and Server Devs can\n * - investigate network, client and server performance and reliability issues\n */\nexport const isRetryableFailure = (status: HttpOrCommunicationStatus | null | undefined): boolean => {\n if (!status) return false;\n const { status: communicationStatus, failure } = getCommunicationStatusDetails(status);\n return !!(failure && (communicationStatus === networkFailure || communicationStatus === timeoutFailure || communicationStatus === aborted));\n};\n\n/**\n * Returns true if the status is a valid communication status\n */\nexport const isStatusValid = (status: string | null | undefined): boolean => !!(isString(status) && statusRegex.test(status));\n\nexport const isDisabled = (status: HttpOrCommunicationStatus | null | undefined): boolean => !!(status && getCommunicationStatus(status) === disabled);\n","import { clientFailure, clientFailureNotAuthorized, disabled, missing, networkFailure, serverFailure, success } from './CommunicationStatusConsts';\nimport { isStatusValid } from './CommunicationStatusTests';\nimport { CommunicationStatus, CommunicationStatusDetails, communicationStatuses, UnknownCommunicationStatusDetails } from './CommunicationStatusTypes';\n\n//***************************************************************************************************************\n// Private Helpers\n//***************************************************************************************************************\nconst getCommunicationStatusFromHttpStatusOrUndefined = (httpStatus: number): CommunicationStatus | undefined => {\n if (httpStatus === 0) return disabled;\n switch (Math.floor(httpStatus / 100)) {\n case 2: return success;\n case 3: return missing;\n case 4:\n switch (httpStatus) {\n case 401:\n case 403:\n case 407:\n case 451: return clientFailureNotAuthorized;\n case 404: return missing;\n default: return clientFailure;\n }\n case 5:\n switch (httpStatus) {\n case 502:\n case 503:\n case 504: return networkFailure;\n case 511: return clientFailureNotAuthorized;\n case 501: return missing; // 501 Not Implemented - i.e. it \"does not exist\" currently - i.e. missing\n case 505: // HTTP Version Not Supported - client should change the request\n case 530: return clientFailure;\n default: return serverFailure;\n }\n }\n return undefined;\n};\n\nconst getCommunicationStatusFromHttpStatus = (httpStatus: number): CommunicationStatus => {\n const status = getCommunicationStatusFromHttpStatusOrUndefined(httpStatus);\n if (!status) {\n throw new Error(`httpStatus ${httpStatus} is not a supported CommunicationStatus.`);\n }\n return status;\n};\n\n//***************************************************************************************************************\n// Public Functions\n//***************************************************************************************************************\nexport const getCommunicationStatusOrUndefined = <T extends number | CommunicationStatus | null | undefined>(\n status: T\n): T extends null | undefined ? undefined : (CommunicationStatus | undefined) => {\n if (status == null) return undefined as any;\n if (typeof status === 'string') {\n if (!isStatusValid(status)) {\n return undefined;\n }\n return status as any;\n }\n if (typeof status === 'number') {\n return getCommunicationStatusFromHttpStatusOrUndefined(status) as any;\n }\n return undefined;\n};\n\n/*\n * Returns the CommunicationStatus for a given CommunicationStatus or number\n * If the input is null or undefined, returns undefined, otherwise throws an error if the CommunicationStatus or number is not supported\n * @param status - The CommunicationStatus or number to get the CommunicationStatus for\n * @returns The CommunicationStatus for the given CommunicationStatus or number\n */\nexport const getCommunicationStatus = <T extends number | CommunicationStatus | null | undefined>(\n status: T\n): T extends null | undefined ? undefined : CommunicationStatus => {\n if (status == null) return undefined as any;\n if (typeof status === 'number') {\n return getCommunicationStatusFromHttpStatus(status) as any;\n }\n const communicationStatus: CommunicationStatus | undefined = getCommunicationStatusOrUndefined(status);\n if (!communicationStatus) {\n throw new Error(`${status} is not a valid CommunicationStatus.`);\n }\n return communicationStatus as any;\n};\n\n/**\n * Returns the HTTP status code for a given CommunicationStatus or number\n * If the input is null or undefined, returns undefined, otherwise throws an error if the CommunicationStatus or number is not supported\n * @param status - The CommunicationStatus or number to get the HTTP status code for\n * @returns The HTTP status code for the given CommunicationStatus or number\n */\nexport const getHttpStatus = <T extends CommunicationStatus | number | null | undefined>(status: T): T extends null | undefined ? undefined : number => {\n if (status == null) return undefined as any;\n const communicationStatus = getCommunicationStatus(status);\n const httpStatus = communicationStatuses[communicationStatus].httpStatus;\n if (httpStatus == null) {\n throw new Error(`There is no valid HttpStatus for ${status}.`);\n }\n return httpStatus as any;\n};\n\n/**\n * Returns CommunicationStatusDetails {status, httpStatus, message} given an HTTP status code\n *\n * Never throws - returns UnknownCommunicationStatusDetails for invalid inputs\n *\n * @param status - The HTTP status code to get the communication status for\n * @returns The CommunicationStatusDetails for the given status. Note, if an HTTP status is given, it won't necessarily be the httpStatus returned; HTTPStatuses are simplified along with CommunicationStatuses.\n */\nexport function getCommunicationStatusDetails(status: null | undefined): undefined;\nexport function getCommunicationStatusDetails(status: number | CommunicationStatus): CommunicationStatusDetails;\nexport function getCommunicationStatusDetails(status: number | CommunicationStatus | null | undefined): CommunicationStatusDetails | undefined {\n if (status == null) return undefined;\n\n try {\n const communicationStatus = getCommunicationStatus(status);\n const details: CommunicationStatusDetails = communicationStatuses[communicationStatus] ?? UnknownCommunicationStatusDetails;\n return details;\n } catch {\n return UnknownCommunicationStatusDetails;\n }\n}\n\nexport function getCommunicationStatusDetailsOrUndefined(status: null | undefined): undefined;\nexport function getCommunicationStatusDetailsOrUndefined(status: number | CommunicationStatus): CommunicationStatusDetails | undefined;\nexport function getCommunicationStatusDetailsOrUndefined(status: number | CommunicationStatus | null | undefined): CommunicationStatusDetails | undefined {\n if (status == null) return undefined;\n const communicationStatus = getCommunicationStatusOrUndefined(status);\n if (communicationStatus == null) return undefined;\n const details: CommunicationStatusDetails | undefined = communicationStatuses[communicationStatus];\n return details;\n}\n"],"mappings":"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","names":["failure"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -40,6 +40,13 @@ declare const communicationStatusesPartials: {
|
|
|
40
40
|
httpStatus: undefined;
|
|
41
41
|
failure: boolean;
|
|
42
42
|
};
|
|
43
|
+
disabled: {
|
|
44
|
+
httpStatus: undefined;
|
|
45
|
+
};
|
|
46
|
+
unknown: {
|
|
47
|
+
httpStatus: undefined;
|
|
48
|
+
failure: boolean;
|
|
49
|
+
};
|
|
43
50
|
};
|
|
44
51
|
/**
|
|
45
52
|
* The core of Art-core-ts-communication-status: A simplified set of statuses as a human-readable and machine-interpretable string
|
|
@@ -66,6 +73,7 @@ interface CommunicationStatusDetails {
|
|
|
66
73
|
communicationStatus: CommunicationStatus;
|
|
67
74
|
message: string;
|
|
68
75
|
}
|
|
76
|
+
declare const UnknownCommunicationStatusDetails: CommunicationStatusDetails;
|
|
69
77
|
declare const communicationStatuses: Record<CommunicationStatus, CommunicationStatusDetails>;
|
|
70
78
|
type CommunicationStatuses = typeof communicationStatuses;
|
|
71
79
|
/**
|
|
@@ -230,6 +238,20 @@ declare const failure: CommunicationStatus;
|
|
|
230
238
|
* - implement proper timeoutFailure handling
|
|
231
239
|
*/
|
|
232
240
|
declare const timeoutFailure: CommunicationStatus;
|
|
241
|
+
/**
|
|
242
|
+
* Client has disabled the request explicitly.
|
|
243
|
+
*
|
|
244
|
+
* Client Can:
|
|
245
|
+
* - re-enable the request
|
|
246
|
+
*/
|
|
247
|
+
declare const disabled: CommunicationStatus;
|
|
248
|
+
/**
|
|
249
|
+
* Unknown communication status
|
|
250
|
+
*
|
|
251
|
+
* Client Can:
|
|
252
|
+
* - log the unknown status for debugging
|
|
253
|
+
*/
|
|
254
|
+
declare const unknown: CommunicationStatus;
|
|
233
255
|
|
|
234
256
|
declare const getCommunicationStatusOrUndefined: <T extends number | CommunicationStatus | null | undefined>(status: T) => T extends null | undefined ? undefined : (CommunicationStatus | undefined);
|
|
235
257
|
declare const getCommunicationStatus: <T extends number | CommunicationStatus | null | undefined>(status: T) => T extends null | undefined ? undefined : CommunicationStatus;
|
|
@@ -243,13 +265,15 @@ declare const getHttpStatus: <T extends CommunicationStatus | number | null | un
|
|
|
243
265
|
/**
|
|
244
266
|
* Returns CommunicationStatusDetails {status, httpStatus, message} given an HTTP status code
|
|
245
267
|
*
|
|
246
|
-
*
|
|
268
|
+
* Never throws - returns UnknownCommunicationStatusDetails for invalid inputs
|
|
247
269
|
*
|
|
248
270
|
* @param status - The HTTP status code to get the communication status for
|
|
249
271
|
* @returns The CommunicationStatusDetails for the given status. Note, if an HTTP status is given, it won't necessarily be the httpStatus returned; HTTPStatuses are simplified along with CommunicationStatuses.
|
|
250
272
|
*/
|
|
251
|
-
declare
|
|
252
|
-
declare
|
|
273
|
+
declare function getCommunicationStatusDetails(status: null | undefined): undefined;
|
|
274
|
+
declare function getCommunicationStatusDetails(status: number | CommunicationStatus): CommunicationStatusDetails;
|
|
275
|
+
declare function getCommunicationStatusDetailsOrUndefined(status: null | undefined): undefined;
|
|
276
|
+
declare function getCommunicationStatusDetailsOrUndefined(status: number | CommunicationStatus): CommunicationStatusDetails | undefined;
|
|
253
277
|
|
|
254
278
|
/** Returns true for HTTP 2xx responses */
|
|
255
279
|
declare const isSuccess: (status: HttpOrCommunicationStatus | null | undefined) => boolean;
|
|
@@ -265,7 +289,7 @@ declare const isSuccess: (status: HttpOrCommunicationStatus | null | undefined)
|
|
|
265
289
|
* Client Can:
|
|
266
290
|
* - Use a different is* function for more specific checks
|
|
267
291
|
*/
|
|
268
|
-
declare const isFailure: (status: HttpOrCommunicationStatus | null | undefined) => boolean
|
|
292
|
+
declare const isFailure: (status: HttpOrCommunicationStatus | null | undefined) => boolean;
|
|
269
293
|
/**
|
|
270
294
|
* Returns true for client-side errors
|
|
271
295
|
*
|
|
@@ -284,7 +308,7 @@ declare const isFailure: (status: HttpOrCommunicationStatus | null | undefined)
|
|
|
284
308
|
* - use isClientFailureNotAuthorized to check for 401/403/407/451
|
|
285
309
|
* - fix the request to avoid the 4xx error
|
|
286
310
|
*/
|
|
287
|
-
declare const isClientFailure: (status: HttpOrCommunicationStatus | null | undefined) => boolean
|
|
311
|
+
declare const isClientFailure: (status: HttpOrCommunicationStatus | null | undefined) => boolean;
|
|
288
312
|
/**
|
|
289
313
|
* Returns true for server-side errors
|
|
290
314
|
*
|
|
@@ -304,7 +328,7 @@ declare const isClientFailure: (status: HttpOrCommunicationStatus | null | undef
|
|
|
304
328
|
* - fix the server to avoid the 5xx error
|
|
305
329
|
* - fix server infrastructure to avoid the 5xx error (e.g. Bad Gateway, Service Unavailable, Gateway Timeout)
|
|
306
330
|
*/
|
|
307
|
-
declare const isServerFailure: (status: HttpOrCommunicationStatus | null | undefined) => boolean
|
|
331
|
+
declare const isServerFailure: (status: HttpOrCommunicationStatus | null | undefined) => boolean;
|
|
308
332
|
/**
|
|
309
333
|
* Returns true when request fails due to network connectivity issues
|
|
310
334
|
*
|
|
@@ -319,7 +343,7 @@ declare const isServerFailure: (status: HttpOrCommunicationStatus | null | undef
|
|
|
319
343
|
*/
|
|
320
344
|
declare const isNetworkFailure: (status: HttpOrCommunicationStatus | null | undefined) => boolean;
|
|
321
345
|
/** Returns true for server errors, network failures and aborted requests; i.e. the client did nothing wrong (as far as we can tell); client can ask the user to do something OR retry the request */
|
|
322
|
-
declare const isNonClientFailure: (status: HttpOrCommunicationStatus | null | undefined) => boolean
|
|
346
|
+
declare const isNonClientFailure: (status: HttpOrCommunicationStatus | null | undefined) => boolean;
|
|
323
347
|
/**
|
|
324
348
|
* Returns true for unauthorized requests (not authenticated or not authorized)
|
|
325
349
|
*
|
|
@@ -405,10 +429,11 @@ declare const isTimeout: (status: HttpOrCommunicationStatus | null | undefined)
|
|
|
405
429
|
* Client and Server Devs can
|
|
406
430
|
* - investigate network, client and server performance and reliability issues
|
|
407
431
|
*/
|
|
408
|
-
declare const isRetryableFailure: (status: HttpOrCommunicationStatus | null | undefined) => boolean
|
|
432
|
+
declare const isRetryableFailure: (status: HttpOrCommunicationStatus | null | undefined) => boolean;
|
|
409
433
|
/**
|
|
410
434
|
* Returns true if the status is a valid communication status
|
|
411
435
|
*/
|
|
412
|
-
declare const isStatusValid: (status: string) => boolean;
|
|
436
|
+
declare const isStatusValid: (status: string | null | undefined) => boolean;
|
|
437
|
+
declare const isDisabled: (status: HttpOrCommunicationStatus | null | undefined) => boolean;
|
|
413
438
|
|
|
414
|
-
export { type CommunicationStatus, type CommunicationStatusDetails, type CommunicationStatuses, type HttpOrCommunicationStatus, aborted, clientFailure, clientFailureNotAuthorized, communicationStatuses, failure, getCommunicationStatus, getCommunicationStatusDetails, getCommunicationStatusDetailsOrUndefined, getCommunicationStatusOrUndefined, getHttpStatus, isAborted, isClientFailure, isClientFailureNotAuthorized, isFailure, isMissing, isNetworkFailure, isNonClientFailure, isPending, isRetryableFailure, isServerFailure, isStatusValid, isSuccess, isTimeout, missing, networkFailure, pending, serverFailure, statusRegex, success, timeoutFailure };
|
|
439
|
+
export { type CommunicationStatus, type CommunicationStatusDetails, type CommunicationStatuses, type HttpOrCommunicationStatus, UnknownCommunicationStatusDetails, aborted, clientFailure, clientFailureNotAuthorized, communicationStatuses, disabled, failure, getCommunicationStatus, getCommunicationStatusDetails, getCommunicationStatusDetailsOrUndefined, getCommunicationStatusOrUndefined, getHttpStatus, isAborted, isClientFailure, isClientFailureNotAuthorized, isDisabled, isFailure, isMissing, isNetworkFailure, isNonClientFailure, isPending, isRetryableFailure, isServerFailure, isStatusValid, isSuccess, isTimeout, missing, networkFailure, pending, serverFailure, statusRegex, success, timeoutFailure, unknown };
|
package/dist/index.d.ts
CHANGED
|
@@ -40,6 +40,13 @@ declare const communicationStatusesPartials: {
|
|
|
40
40
|
httpStatus: undefined;
|
|
41
41
|
failure: boolean;
|
|
42
42
|
};
|
|
43
|
+
disabled: {
|
|
44
|
+
httpStatus: undefined;
|
|
45
|
+
};
|
|
46
|
+
unknown: {
|
|
47
|
+
httpStatus: undefined;
|
|
48
|
+
failure: boolean;
|
|
49
|
+
};
|
|
43
50
|
};
|
|
44
51
|
/**
|
|
45
52
|
* The core of Art-core-ts-communication-status: A simplified set of statuses as a human-readable and machine-interpretable string
|
|
@@ -66,6 +73,7 @@ interface CommunicationStatusDetails {
|
|
|
66
73
|
communicationStatus: CommunicationStatus;
|
|
67
74
|
message: string;
|
|
68
75
|
}
|
|
76
|
+
declare const UnknownCommunicationStatusDetails: CommunicationStatusDetails;
|
|
69
77
|
declare const communicationStatuses: Record<CommunicationStatus, CommunicationStatusDetails>;
|
|
70
78
|
type CommunicationStatuses = typeof communicationStatuses;
|
|
71
79
|
/**
|
|
@@ -230,6 +238,20 @@ declare const failure: CommunicationStatus;
|
|
|
230
238
|
* - implement proper timeoutFailure handling
|
|
231
239
|
*/
|
|
232
240
|
declare const timeoutFailure: CommunicationStatus;
|
|
241
|
+
/**
|
|
242
|
+
* Client has disabled the request explicitly.
|
|
243
|
+
*
|
|
244
|
+
* Client Can:
|
|
245
|
+
* - re-enable the request
|
|
246
|
+
*/
|
|
247
|
+
declare const disabled: CommunicationStatus;
|
|
248
|
+
/**
|
|
249
|
+
* Unknown communication status
|
|
250
|
+
*
|
|
251
|
+
* Client Can:
|
|
252
|
+
* - log the unknown status for debugging
|
|
253
|
+
*/
|
|
254
|
+
declare const unknown: CommunicationStatus;
|
|
233
255
|
|
|
234
256
|
declare const getCommunicationStatusOrUndefined: <T extends number | CommunicationStatus | null | undefined>(status: T) => T extends null | undefined ? undefined : (CommunicationStatus | undefined);
|
|
235
257
|
declare const getCommunicationStatus: <T extends number | CommunicationStatus | null | undefined>(status: T) => T extends null | undefined ? undefined : CommunicationStatus;
|
|
@@ -243,13 +265,15 @@ declare const getHttpStatus: <T extends CommunicationStatus | number | null | un
|
|
|
243
265
|
/**
|
|
244
266
|
* Returns CommunicationStatusDetails {status, httpStatus, message} given an HTTP status code
|
|
245
267
|
*
|
|
246
|
-
*
|
|
268
|
+
* Never throws - returns UnknownCommunicationStatusDetails for invalid inputs
|
|
247
269
|
*
|
|
248
270
|
* @param status - The HTTP status code to get the communication status for
|
|
249
271
|
* @returns The CommunicationStatusDetails for the given status. Note, if an HTTP status is given, it won't necessarily be the httpStatus returned; HTTPStatuses are simplified along with CommunicationStatuses.
|
|
250
272
|
*/
|
|
251
|
-
declare
|
|
252
|
-
declare
|
|
273
|
+
declare function getCommunicationStatusDetails(status: null | undefined): undefined;
|
|
274
|
+
declare function getCommunicationStatusDetails(status: number | CommunicationStatus): CommunicationStatusDetails;
|
|
275
|
+
declare function getCommunicationStatusDetailsOrUndefined(status: null | undefined): undefined;
|
|
276
|
+
declare function getCommunicationStatusDetailsOrUndefined(status: number | CommunicationStatus): CommunicationStatusDetails | undefined;
|
|
253
277
|
|
|
254
278
|
/** Returns true for HTTP 2xx responses */
|
|
255
279
|
declare const isSuccess: (status: HttpOrCommunicationStatus | null | undefined) => boolean;
|
|
@@ -265,7 +289,7 @@ declare const isSuccess: (status: HttpOrCommunicationStatus | null | undefined)
|
|
|
265
289
|
* Client Can:
|
|
266
290
|
* - Use a different is* function for more specific checks
|
|
267
291
|
*/
|
|
268
|
-
declare const isFailure: (status: HttpOrCommunicationStatus | null | undefined) => boolean
|
|
292
|
+
declare const isFailure: (status: HttpOrCommunicationStatus | null | undefined) => boolean;
|
|
269
293
|
/**
|
|
270
294
|
* Returns true for client-side errors
|
|
271
295
|
*
|
|
@@ -284,7 +308,7 @@ declare const isFailure: (status: HttpOrCommunicationStatus | null | undefined)
|
|
|
284
308
|
* - use isClientFailureNotAuthorized to check for 401/403/407/451
|
|
285
309
|
* - fix the request to avoid the 4xx error
|
|
286
310
|
*/
|
|
287
|
-
declare const isClientFailure: (status: HttpOrCommunicationStatus | null | undefined) => boolean
|
|
311
|
+
declare const isClientFailure: (status: HttpOrCommunicationStatus | null | undefined) => boolean;
|
|
288
312
|
/**
|
|
289
313
|
* Returns true for server-side errors
|
|
290
314
|
*
|
|
@@ -304,7 +328,7 @@ declare const isClientFailure: (status: HttpOrCommunicationStatus | null | undef
|
|
|
304
328
|
* - fix the server to avoid the 5xx error
|
|
305
329
|
* - fix server infrastructure to avoid the 5xx error (e.g. Bad Gateway, Service Unavailable, Gateway Timeout)
|
|
306
330
|
*/
|
|
307
|
-
declare const isServerFailure: (status: HttpOrCommunicationStatus | null | undefined) => boolean
|
|
331
|
+
declare const isServerFailure: (status: HttpOrCommunicationStatus | null | undefined) => boolean;
|
|
308
332
|
/**
|
|
309
333
|
* Returns true when request fails due to network connectivity issues
|
|
310
334
|
*
|
|
@@ -319,7 +343,7 @@ declare const isServerFailure: (status: HttpOrCommunicationStatus | null | undef
|
|
|
319
343
|
*/
|
|
320
344
|
declare const isNetworkFailure: (status: HttpOrCommunicationStatus | null | undefined) => boolean;
|
|
321
345
|
/** Returns true for server errors, network failures and aborted requests; i.e. the client did nothing wrong (as far as we can tell); client can ask the user to do something OR retry the request */
|
|
322
|
-
declare const isNonClientFailure: (status: HttpOrCommunicationStatus | null | undefined) => boolean
|
|
346
|
+
declare const isNonClientFailure: (status: HttpOrCommunicationStatus | null | undefined) => boolean;
|
|
323
347
|
/**
|
|
324
348
|
* Returns true for unauthorized requests (not authenticated or not authorized)
|
|
325
349
|
*
|
|
@@ -405,10 +429,11 @@ declare const isTimeout: (status: HttpOrCommunicationStatus | null | undefined)
|
|
|
405
429
|
* Client and Server Devs can
|
|
406
430
|
* - investigate network, client and server performance and reliability issues
|
|
407
431
|
*/
|
|
408
|
-
declare const isRetryableFailure: (status: HttpOrCommunicationStatus | null | undefined) => boolean
|
|
432
|
+
declare const isRetryableFailure: (status: HttpOrCommunicationStatus | null | undefined) => boolean;
|
|
409
433
|
/**
|
|
410
434
|
* Returns true if the status is a valid communication status
|
|
411
435
|
*/
|
|
412
|
-
declare const isStatusValid: (status: string) => boolean;
|
|
436
|
+
declare const isStatusValid: (status: string | null | undefined) => boolean;
|
|
437
|
+
declare const isDisabled: (status: HttpOrCommunicationStatus | null | undefined) => boolean;
|
|
413
438
|
|
|
414
|
-
export { type CommunicationStatus, type CommunicationStatusDetails, type CommunicationStatuses, type HttpOrCommunicationStatus, aborted, clientFailure, clientFailureNotAuthorized, communicationStatuses, failure, getCommunicationStatus, getCommunicationStatusDetails, getCommunicationStatusDetailsOrUndefined, getCommunicationStatusOrUndefined, getHttpStatus, isAborted, isClientFailure, isClientFailureNotAuthorized, isFailure, isMissing, isNetworkFailure, isNonClientFailure, isPending, isRetryableFailure, isServerFailure, isStatusValid, isSuccess, isTimeout, missing, networkFailure, pending, serverFailure, statusRegex, success, timeoutFailure };
|
|
439
|
+
export { type CommunicationStatus, type CommunicationStatusDetails, type CommunicationStatuses, type HttpOrCommunicationStatus, UnknownCommunicationStatusDetails, aborted, clientFailure, clientFailureNotAuthorized, communicationStatuses, disabled, failure, getCommunicationStatus, getCommunicationStatusDetails, getCommunicationStatusDetailsOrUndefined, getCommunicationStatusOrUndefined, getHttpStatus, isAborted, isClientFailure, isClientFailureNotAuthorized, isDisabled, isFailure, isMissing, isNetworkFailure, isNonClientFailure, isPending, isRetryableFailure, isServerFailure, isStatusValid, isSuccess, isTimeout, missing, networkFailure, pending, serverFailure, statusRegex, success, timeoutFailure, unknown };
|
package/dist/index.js
CHANGED
|
@@ -9,6 +9,8 @@ var aborted = "aborted";
|
|
|
9
9
|
var pending = "pending";
|
|
10
10
|
var failure = "failure";
|
|
11
11
|
var timeoutFailure = "timeoutFailure";
|
|
12
|
+
var disabled = "disabled";
|
|
13
|
+
var unknown = "unknown";
|
|
12
14
|
|
|
13
15
|
// ../art-core-ts-types/dist/index.js
|
|
14
16
|
var isObject = (v) => v != null && typeof v === "object";
|
|
@@ -20,6 +22,7 @@ var isPlainObject = (v) => {
|
|
|
20
22
|
return null == Object.getPrototypeOf(prototype);
|
|
21
23
|
};
|
|
22
24
|
var isFunction = (obj) => typeof obj === "function";
|
|
25
|
+
var isString = (obj) => typeof obj === "string";
|
|
23
26
|
var exists = (value) => value != null;
|
|
24
27
|
|
|
25
28
|
// ../art-core-ts-comprehensions/dist/index.js
|
|
@@ -125,7 +128,15 @@ var communicationStatusesPartials = {
|
|
|
125
128
|
pending: { httpStatus: void 0 },
|
|
126
129
|
networkFailure: { httpStatus: void 0, failure: true },
|
|
127
130
|
aborted: { httpStatus: void 0, failure: true },
|
|
128
|
-
timeoutFailure: { httpStatus: void 0, failure: true }
|
|
131
|
+
timeoutFailure: { httpStatus: void 0, failure: true },
|
|
132
|
+
disabled: { httpStatus: void 0 },
|
|
133
|
+
unknown: { httpStatus: void 0, failure: true }
|
|
134
|
+
};
|
|
135
|
+
var UnknownCommunicationStatusDetails = {
|
|
136
|
+
status: "unknown",
|
|
137
|
+
communicationStatus: "unknown",
|
|
138
|
+
message: "Unknown communication status",
|
|
139
|
+
failure: true
|
|
129
140
|
};
|
|
130
141
|
var communicationStatuses = object(communicationStatusesPartials, (details, status) => ({
|
|
131
142
|
...details,
|
|
@@ -140,29 +151,31 @@ var statusRegex = new RegExp(`^(${Object.keys(communicationStatuses).join("|")})
|
|
|
140
151
|
|
|
141
152
|
// src/CommunicationStatusTests.ts
|
|
142
153
|
var isSuccess = (status) => !!status && getCommunicationStatus(status) === success;
|
|
143
|
-
var isFailure = (status) => !!status && getCommunicationStatusDetails(status).failure;
|
|
144
|
-
var isClientFailure = (status) => !!status && getCommunicationStatusDetails(status).clientFailure;
|
|
145
|
-
var isServerFailure = (status) => !!status && getCommunicationStatusDetails(status).serverFailure;
|
|
146
|
-
var isNetworkFailure = (status) => !!status && getCommunicationStatus(status) === networkFailure;
|
|
154
|
+
var isFailure = (status) => !!(status && getCommunicationStatusDetails(status).failure);
|
|
155
|
+
var isClientFailure = (status) => !!(status && getCommunicationStatusDetails(status).clientFailure);
|
|
156
|
+
var isServerFailure = (status) => !!(status && getCommunicationStatusDetails(status).serverFailure);
|
|
157
|
+
var isNetworkFailure = (status) => !!(status && getCommunicationStatus(status) === networkFailure);
|
|
147
158
|
var isNonClientFailure = (status) => {
|
|
148
159
|
if (!status) return false;
|
|
149
160
|
const details = getCommunicationStatusDetails(status);
|
|
150
|
-
return details.failure && !details.clientFailure;
|
|
161
|
+
return !!(details.failure && !details.clientFailure);
|
|
151
162
|
};
|
|
152
163
|
var isClientFailureNotAuthorized = (status) => !!status && getCommunicationStatus(status) === clientFailureNotAuthorized;
|
|
153
|
-
var isAborted = (status) => !!status && getCommunicationStatus(status) === aborted;
|
|
154
|
-
var isMissing = (status) => !!status && getCommunicationStatus(status) === missing;
|
|
155
|
-
var isPending = (status) => !!status && getCommunicationStatus(status) === pending;
|
|
156
|
-
var isTimeout = (status) => !!status && getCommunicationStatus(status) === timeoutFailure;
|
|
164
|
+
var isAborted = (status) => !!(status && getCommunicationStatus(status) === aborted);
|
|
165
|
+
var isMissing = (status) => !!(status && getCommunicationStatus(status) === missing);
|
|
166
|
+
var isPending = (status) => !!(status && getCommunicationStatus(status) === pending);
|
|
167
|
+
var isTimeout = (status) => !!(status && getCommunicationStatus(status) === timeoutFailure);
|
|
157
168
|
var isRetryableFailure = (status) => {
|
|
158
169
|
if (!status) return false;
|
|
159
170
|
const { status: communicationStatus, failure: failure2 } = getCommunicationStatusDetails(status);
|
|
160
|
-
return failure2 && (communicationStatus === networkFailure || communicationStatus === timeoutFailure || communicationStatus === aborted);
|
|
171
|
+
return !!(failure2 && (communicationStatus === networkFailure || communicationStatus === timeoutFailure || communicationStatus === aborted));
|
|
161
172
|
};
|
|
162
|
-
var isStatusValid = (status) => statusRegex.test(status);
|
|
173
|
+
var isStatusValid = (status) => !!(isString(status) && statusRegex.test(status));
|
|
174
|
+
var isDisabled = (status) => !!(status && getCommunicationStatus(status) === disabled);
|
|
163
175
|
|
|
164
176
|
// src/CommunicationStatusConversions.ts
|
|
165
177
|
var getCommunicationStatusFromHttpStatusOrUndefined = (httpStatus) => {
|
|
178
|
+
if (httpStatus === 0) return disabled;
|
|
166
179
|
switch (Math.floor(httpStatus / 100)) {
|
|
167
180
|
case 2:
|
|
168
181
|
return success;
|
|
@@ -241,22 +254,30 @@ var getHttpStatus = (status) => {
|
|
|
241
254
|
}
|
|
242
255
|
return httpStatus;
|
|
243
256
|
};
|
|
244
|
-
|
|
257
|
+
function getCommunicationStatusDetails(status) {
|
|
245
258
|
if (status == null) return void 0;
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
259
|
+
try {
|
|
260
|
+
const communicationStatus = getCommunicationStatus(status);
|
|
261
|
+
const details = communicationStatuses[communicationStatus] ?? UnknownCommunicationStatusDetails;
|
|
262
|
+
return details;
|
|
263
|
+
} catch {
|
|
264
|
+
return UnknownCommunicationStatusDetails;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
function getCommunicationStatusDetailsOrUndefined(status) {
|
|
250
268
|
if (status == null) return void 0;
|
|
251
269
|
const communicationStatus = getCommunicationStatusOrUndefined(status);
|
|
252
270
|
if (communicationStatus == null) return void 0;
|
|
253
|
-
|
|
254
|
-
|
|
271
|
+
const details = communicationStatuses[communicationStatus];
|
|
272
|
+
return details;
|
|
273
|
+
}
|
|
255
274
|
export {
|
|
275
|
+
UnknownCommunicationStatusDetails,
|
|
256
276
|
aborted,
|
|
257
277
|
clientFailure,
|
|
258
278
|
clientFailureNotAuthorized,
|
|
259
279
|
communicationStatuses,
|
|
280
|
+
disabled,
|
|
260
281
|
failure,
|
|
261
282
|
getCommunicationStatus,
|
|
262
283
|
getCommunicationStatusDetails,
|
|
@@ -266,6 +287,7 @@ export {
|
|
|
266
287
|
isAborted,
|
|
267
288
|
isClientFailure,
|
|
268
289
|
isClientFailureNotAuthorized,
|
|
290
|
+
isDisabled,
|
|
269
291
|
isFailure,
|
|
270
292
|
isMissing,
|
|
271
293
|
isNetworkFailure,
|
|
@@ -282,6 +304,7 @@ export {
|
|
|
282
304
|
serverFailure,
|
|
283
305
|
statusRegex,
|
|
284
306
|
success,
|
|
285
|
-
timeoutFailure
|
|
307
|
+
timeoutFailure,
|
|
308
|
+
unknown
|
|
286
309
|
};
|
|
287
310
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/CommunicationStatusConsts.ts","../../art-core-ts-types/src/Types.ts","../../art-core-ts-comprehensions/src/Comprehensions.ts","../../art-core-ts-comprehensions/src/DeepComprehensions.ts","../src/CommunicationStatusTypes.ts","../src/CommunicationStatusTests.ts","../src/CommunicationStatusConversions.ts"],"sourcesContent":["// Export status constants\nimport type { CommunicationStatus } from './CommunicationStatusTypes'\n\n/**\n * HTTP 2xx responses\n *\n * Client Can Automatically:\n * - Process the successful response\n * - Update UI to reflect success\n *\n * Client Developer Can:\n * - Handle the successful response data\n */\nexport const success: CommunicationStatus = \"success\"\n\n/**\n * Resource not found\n *\n * HTTP Status Codes Covered:\n * - 404: Not Found\n *\n * Client Can Automatically:\n * - notify the user that the resource was not found\n * - prompt the user to request a different resource\n *\n * Client Developer Can:\n * - fix the bad resource paths\n */\nexport const missing: CommunicationStatus = \"missing\"\n\n/**\n * Client-side errors; i.e. the client needs to change the request somehow to succeed\n *\n * HTTP Status Codes Covered:\n * - 400: Bad Request\n * - 401: Unauthorized\n * - 403: Forbidden\n * - 407: Proxy Authentication Required\n * - 409: Conflict\n * - 422: Unprocessable Entity\n *\n * Client Can Automatically:\n * - Notify the user that the client is experiencing issues\n * - Prompt user to correct invalid input\n *\n * Client Developer Can:\n * - use isClientFailureNotAuthorized to check for 401/403/407/451\n * - fix the request to avoid the 4xx error\n * - validate input before sending requests\n */\nexport const clientFailure: CommunicationStatus = \"clientFailure\"\n\n/**\n * Unauthorized requests; i.e. client needs to change the credentials (or the grants for the current credentials) to succeed\n *\n * HTTP Status Codes Covered:\n * - 401: Unauthorized\n * - 403: Forbidden\n * - 407: Proxy Authentication Required\n * - 451: Unavailable For Legal Reasons\n *\n * Client Can Automatically:\n * - refresh the request token\n * - prompt the user to re-login\n * - ask the user to contact the administrator for access\n *\n * Client and Server Developer Can:\n * - fix authorization / authentication bugs\n */\nexport const clientFailureNotAuthorized: CommunicationStatus = \"clientFailureNotAuthorized\"\n\n/**\n * Server-side errors; i.e. internal server errors\n *\n * HTTP Status Codes Covered:\n * - 500: Internal Server Error\n * - 502: Bad Gateway\n * - 503: Service Unavailable\n * - 504: Gateway Timeout\n *\n * Client Can Automatically:\n * - Ask the user to try again later\n * - Notify the user that the server is experiencing issues\n * - Implement automatic retry with backoff\n *\n * Client Developer: (probably) can't fix\n *\n * Server Developer Can:\n * - fix the server to avoid the 5xx error\n * - fix server infrastructure to avoid the 5xx error\n */\nexport const serverFailure: CommunicationStatus = \"serverFailure\"\n\n/**\n * Request fails due to network connectivity issues\n *\n * HTTP Status Codes Covered: NONE (server was not reachable)\n *\n * Client Can Automatically:\n * - Prompt the user to fix the network connection\n * - Retry the request when network is available\n * - Monitor network status for recovery\n *\n * Client Developer Can:\n * - fix bad network constants (like address, ports, etc.)\n * - implement offline-first capabilities\n */\nexport const networkFailure: CommunicationStatus = \"networkFailure\"\n\n/**\n * Request was cancelled by client\n *\n * Client Can Automatically:\n * - notify the user that the request was cancelled\n * - prompt the user to try again\n * - cleanup any pending state\n *\n * Client Developer Can:\n * - fix the client to not abort the request unnecessarily\n * - implement proper cleanup on abort\n */\nexport const aborted: CommunicationStatus = \"aborted\"\n\n/**\n * Request is in progress\n *\n * Client Can Automatically:\n * - notify the user that the request is in progress\n * - show the user progress (if available)\n * - allow the user to cancel the request\n *\n * Client Developer Can:\n * - if \"pending\" was not expected, maybe the client needs to `wait` for the request to complete?\n * - implement proper loading states\n */\nexport const pending: CommunicationStatus = \"pending\"\n\n/**\n * Any error response (HTTP 4xx/5xx) or network/abort failures\n *\n * HTTP Status Codes Covered:\n * - 4xx: Client-side errors (except 404)\n * - 5xx: Server-side errors\n * - Network failures\n * - Abort failures\n *\n * Client Can Automatically:\n * - Show appropriate error message to user\n * - Implement generic error handling\n * - Log errors for debugging\n *\n * Client Developer Can:\n * - Use more specific is* functions for targeted error handling\n * - Implement proper error recovery strategies\n */\nexport const failure: CommunicationStatus = \"failure\"\n\n/**\n * Request timed out\n *\n * Client Can Automatically:\n * - notify the user that the request timed out\n * - try again (automatically or via user action)\n *\n * Client Developer Can:\n * - fix the client to not timeoutFailure the request\n * - implement proper timeoutFailure handling\n */\nexport const timeoutFailure: CommunicationStatus = \"timeoutFailure\"\n","import { PlainObject } from \"./TypeScriptTypes\"\n\ntype TypedArray = Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array\n\n/*\n\n @isPromise: (obj) => obj? && isFunction(obj.then) && !isFunction obj\n @isRegExp: (obj) => obj.constructor.name == \"RegExp\"\n @isNumber: isNumber = (obj) => typeof obj == \"number\"\n\n isNonNegativeInt: (x) ->\n ((x | 0) == x) &&\n x >= 0\n\n @isError: (obj) => obj? && obj instanceof Error\n @isDate: (obj) => obj?.constructor == Date\n @isString: isString = (obj) => typeof obj == \"string\"\n @isFunction: isFunction = (obj) => typeof obj == \"function\"\n @isEmptyObject: (obj) => Object.keys(obj).length == 0\n @isBoolean: (obj) => obj == true || obj == false\n\n @isArrayBuffer: isArrayBuffer = if global.ArrayBuffer\n (obj) -> obj? && obj.constructor == ArrayBuffer\n else -> false\n @isTypedArray: (obj) -> obj? && obj.length >= 0 && obj.length == (obj.length | 0) && isArrayBuffer obj.buffer\n\n */\n\n/**\n * Returns true if the value is an object. (note, Arrays are objects)\n * This is only false for null, undefined, functions, and primitives like strings, numbers, and booleans.\n * @param v\n * @returns\n */\nexport const isObject = (v: any): v is Record<string, any> => v != null && typeof v === 'object'\n\n/**\n * Returns true if the value is a plain object - i.e. an object who's prototype is Object\n * @param v\n * @returns\n */\nexport const isPlainObject = (v: any): v is PlainObject => {\n if (!isObject(v)) return false\n if (v.constructor === Object) return true // fast pass, but could fail if v was created in a different context with a different instance of Object\n const prototype = Object.getPrototypeOf(v)\n if (prototype === null) return true\n return null == Object.getPrototypeOf(prototype)\n}\n\nexport const asPlainObject = (v: any): PlainObject => isPlainObject(v) ? v : {}\n\nexport const isFunction = (obj: any): obj is Function => typeof obj === \"function\"\nexport const isNumber = (obj: any): obj is number => typeof obj === \"number\"\nexport const isString = (obj: any): obj is string => typeof obj === \"string\"\nexport const isArrayBuffer = (obj: any): obj is ArrayBuffer => obj != null && obj.constructor === ArrayBuffer\nexport const isArray = (obj: any): obj is any[] => Array.isArray(obj)\n\nexport const isPromise = (obj: any): obj is Promise<any> => obj != null && isFunction(obj.then) && !isFunction(obj)\nexport const isRegExp = (obj: any): obj is RegExp => obj?.constructor.name === \"RegExp\"\nexport const isError = (obj: any): obj is Error => obj != null && obj instanceof Error\nexport const isDate = (obj: any): obj is Date => obj?.constructor === Date\nexport const isEmptyObject = (obj: any): obj is Record<string, never> => Object.keys(obj).length === 0\nexport const isBoolean = (obj: any): obj is boolean => obj === true || obj === false\nexport const isTypedArray = (obj: any): obj is TypedArray =>\n obj != null &&\n obj.length >= 0 &&\n obj.length === (obj.length | 0) &&\n isArrayBuffer(obj.buffer)\n\nexport const isNonNegativeInt = (x: number): x is number => ((x | 0) === x) && x >= 0\n\nexport const stringIsPresent = (str: string): boolean => isString(str) && !/^(\\s+|)$/.test(str)\n\nexport const exists = (value: any): boolean => value != null\nexport const doesNotExist = (value: any): boolean => !exists(value)\n\nexport const isNull = (value: any): boolean => value === null\nexport const isNotNull = (value: any): boolean => !isNull(value)\n\nexport const isUndefined = (value: any): boolean => value === undefined\nexport const isNotUndefined = (value: any): boolean => !isUndefined(value)\n\nexport const isNullish = (value: any): boolean => value == null || value == undefined\nexport const isNotNullish = (value: any): boolean => !isNullish(value)\n\n/**\n * present returns true if \"there is a value _present_\"\n *\n * Specifically:\n * - if `value.getPresent()` is a function; it's called and it's value is returned\n * - if `value.present()` is a function; it's called and it's value is returned\n * - else: returns `true` if `!null`, `!undefined` and `!(string with only whitespace)`\n *\n * > Inspired by Ruby's `present?` method\n *\n * @param v\n * @returns\n */\nexport const present = <T>(v: T): v is NonNullable<T> => {\n if (v == null) return false\n if (isFunction((v as any).getPresent)) {\n return (v as any).getPresent()\n } else if (isFunction((v as any).present)) {\n return (v as any).present()\n } else if (isString(v)) {\n return stringIsPresent(v)\n } else return true\n}\n","import { isPlainObject, isFunction, exists } from '@art-suite/art-core-ts-types'\nimport { EachFunction, ArrayFunction, ObjectFunction, ReduceFunction, FindFunction, AnyContainer, ArrayInput, ObjectInput, NotPresent } from './ComprehensionTypes'\n\nconst isMap = (source: any): source is Map<any, any> => source instanceof Map;\nconst isSet = (source: any): source is Set<any> => source instanceof Set;\n\nexport const isArrayIterable = (source: any): source is any[] => {\n if (typeof source === 'string') return false\n if (isFunction(source)) return false\n return source != null && source.length >= 0;\n}\n\nexport const isOfIterable = (o: any): boolean => {\n if (typeof o === 'string') return false\n if (isFunction(o)) return false\n return isFunction(o[Symbol.iterator] || o.next)\n}\n\nconst returnFirstArg = (a: any) => a;\nconst returnSecondArg = (a: any, b: any) => b;\n\nconst emptyOptions = {};\n\ntype CoreIterationFunction = (value: any, key: any) => boolean; // returns true to stop iteration\n\n/**\n * Tight function to abstract away all possible iteration methods based on the source container type.\n *\n * Iterates over the source collection, calling the given function for each element.\n *\n * Stops when the body function returns true.\n * Does NOT return anything. If you need a return value, must set it as a side-effect of the body function.\n *\n * @param source - The collection to iterate (array, object, Map, Set, etc.)\n * @param body - The function to call for each element.\n * @returns void\n */\nconst iterate = (source: any, body: CoreIterationFunction): void => {\n if (exists(source))\n if (isArrayIterable(source)) for (let key = 0, { length } = source; key < length; key++) { if (body(source[key], key)) break; }\n else if (isPlainObject(source)) for (const key in source) { if (body(source[key], key)) break; }\n else if (isMap(source)) for (const [key, value] of source.entries()) { if (body(value, key)) break; }\n // else if (isSet(source)) for (const value of source) { if (body(value, value)) break; }\n else if (isOfIterable(source)) { let count = 0; for (const value of source) { if (body(value, count++)) break; } }\n else throw new Error(`Unsupported source type: ${typeof source}`);\n};\n\n/*\n Returns a function that handles \"with\", \"when\" and \"stopWhen\" comprehension clauses:\n\n 1. Returns true if the \"stopWhen\" is provided and returns true, otherwise returns it will return false\n 2. If stopWhen is false, \"when\" and \"with\" are processed\n 3. If there is no \"when\" or \"when\" returns true, \"with\" is called.\n*/\nconst normalizeBody = (withFunction: (value: any, key: any) => any, options: AcceptedComprehensionOptions): (value: any, key: any) => boolean => {\n let { when, stopWhen } = options;\n if (when && stopWhen) {\n return (v: any, k: any) => {\n if (stopWhen(v, k)) return true;\n if (when(v, k)) withFunction(v, k);\n return false;\n }\n }\n if (when) {\n return (v: any, k: any) => {\n if (when(v, k)) withFunction(v, k);\n return false;\n }\n }\n if (stopWhen) {\n return (v: any, k: any) => {\n if (stopWhen(v, k)) return true;\n withFunction(v, k);\n return false;\n }\n }\n return (v: any, k: any) => { withFunction(v, k); return false; };\n};\n\n\nlet normalizeKeyFunction = (source: any, options: AcceptedComprehensionOptions) =>\n options.withKey || (isArrayIterable(source) ? returnFirstArg : returnSecondArg)\n\nconst _each = (source: any, withFunction: (value: any, key: any) => any, options: AcceptedComprehensionOptions) => {\n iterate(source, normalizeBody(withFunction, options));\n};\n\n//************************************************************************\n// NORMALIZED COMPREHENSION FUNCTIONS\n//************************************************************************\ntype NormalizedIterationFunction = (source: any, options: NormalizedComprehensionOptions) => any;\n\nconst normalizedEach: NormalizedIterationFunction = (source: any, options: NormalizedComprehensionOptions) => {\n _each(source, options.with, options);\n return options.into;\n};\n\nconst normalizedArrayIteration: NormalizedIterationFunction = (source: any, options: NormalizedComprehensionOptions) => {\n let { into, with: withFunction } = options;\n if (into == null) into = [];\n _each(source, (v: any, k: any) => into.push(withFunction(v, k)), options);\n return into;\n};\n\nconst normalizedObjectIteration: NormalizedIterationFunction = (source: any, options: NormalizedComprehensionOptions) => {\n let { into, with: withFunction } = options;\n if (into == null) into = {};\n let withKey = normalizeKeyFunction(source, options);\n _each(source, (v, k) => (into[withKey(v, k)] = withFunction(v, k)), options);\n return into;\n};\n\nconst normalizedReduceIteration: NormalizedIterationFunction = (source: any, options: NormalizedComprehensionOptions) => {\n let { into, with: withFunction } = options;\n let first = into === undefined;\n _each(source, (v: any, k: any) => {\n if (first) { first = false; into = v; }\n else {\n into = withFunction(into, v, k)\n }\n }, options);\n return into;\n};\n\nconst normalizedFindIteration: NormalizedIterationFunction = (source: any, options: NormalizedComprehensionOptions) => {\n let { with: withFunction } = options;\n let { when } = options;\n let found: any | undefined = undefined;\n iterate(\n source,\n when\n ? (v, k) => {\n if (when(v, k)) {\n found = withFunction(v, k);\n return true; // signal to stop iteration\n }\n return false;\n }\n : (v, k) => {\n found = withFunction(v, k) // stops iteration if withFunction returns an value that \"exists\" (is not undefined, non null)\n return found != null;\n }\n );\n return found;\n};\n\n//####################\n// PRIVATE\n//####################\n\n// WithFunction has two signatures: value + key, or for reduce, accumulator + value + key\ntype ValueKeyFunction = (value?: any, key?: any) => any;\ntype AccumulatorValueKeyFunction = (accumulator?: any, value?: any, key?: any) => any;\ntype WithFunction = ValueKeyFunction | AccumulatorValueKeyFunction;\ntype WhenFunction = (value: any, key: any) => any;\ntype WithKeyFunction = (value: any, key: any) => any;\n\ntype AcceptedComprehensionOptions = {\n into?: any;\n inject?: any; // alias for into - used to make \"reduce\" calls make more sense\n returning?: any; // alias for into - used to make \"each\" calls make more sense\n with?: WithFunction;\n when?: WhenFunction;\n withKey?: WithKeyFunction;\n stopWhen?: (value: any, key: any) => any;\n}\n\ntype WithOrOptions = WithFunction | AcceptedComprehensionOptions;\n\nconst isAcceptedComprehensionOptions = (o: any): o is AcceptedComprehensionOptions => isPlainObject(o)\n\n// the 'with' param will always exist when normalized\ntype NormalizedComprehensionOptions = Omit<AcceptedComprehensionOptions, 'with' | 'inject' | 'returning'> & {\n with: WithFunction;\n}\n\n/**\n * Returns the first non-undefined value from into, inject, or returning\n *\n * @param into - The 'into' parameter.\n * @param inject - The 'inject' parameter.\n * @param returning - The 'returning' parameter.\n * @returns The normalized 'into' parameter.\n */\nconst firstNotUndefined = (into: any, inject: any, returning: any) => {\n if (into === undefined) into = inject\n if (into === undefined) into = returning\n return into\n}\n\nconst normalizeIterationParams = (withOrOptions?: WithOrOptions): NormalizedComprehensionOptions => {\n if (isAcceptedComprehensionOptions(withOrOptions)) {\n const { with: withFunction, into, inject, returning, ...rest } = withOrOptions;\n return { ...rest, into: firstNotUndefined(into, inject, returning), with: withFunction ?? returnFirstArg };\n }\n if (isFunction(withOrOptions)) {\n return { with: withOrOptions };\n }\n return { with: returnFirstArg };\n};\n\n/*\nNormalizes input params for the 'iteration' function.\nSince this normalizes multiple params, and therefor would need to return\nan new array or new object otherwise, we pass IN the iteration function\nand pass the params directly to it. This keeps the computed params on the\nstack and doesn't create new objects.\n\nIN signature 1: (iteration, source, withFunction) ->\nIN signature 2: (iteration, source, options) ->\nIN signature 3: (iteration, source) ->\n\nIN:\niteration: (source, into, withFunction, options) -> out\n\n The iteration function is invoked last with the computed args.\n Its results are returned.\n\n IN:\n source: passed directly through from inputs\n into: passed directly through from inputs OR from options.into\n withFunction: passed directly through from inputs OR from options.with\n options: passed directly through from inputs OR {}\n (guaranteed to be set and a plainObject)\n\nsource: the source collection to be iterated over. Passed directly through.\n\ninto: passed through to 'iteration'\nwithFunction: passed through to 'iteration'\noptions: passed through to 'iteration' AND:\n\n into: set 'into' from the options object\n with: set 'withFunction' from the options object\n\nOUT: out\n*/\nconst invokeNormalizedIteration = (\n normalizedIterationFunction: NormalizedIterationFunction,\n source: any,\n withOrOptions: WithOrOptions\n) => normalizedIterationFunction(source, normalizeIterationParams(withOrOptions));\n\n/**\n * Iterates over the provided collection, calling the given function for each element.\n *\n * Unlike other comprehensions, `each` is designed for side effects and does not build a new collection.\n *\n * **Return value:**\n * - If an `into`, `inject`, or `returning` option is provided (or as the second argument), that value is returned (not modified by `each` itself).\n * - If no such value is provided, returns `undefined`.\n *\n * This allows you to use `each` for side effects while optionally threading a value through the iteration.\n *\n * @param source The collection to iterate (array, object, Map, Set, etc.)\n * @param withOrOptions Optional: Either the `into` value or the function to call for each element.\n * @returns The `into`/`inject`/`returning` value if provided, otherwise `undefined`.\n */\nexport const each: EachFunction = ((source: any, withOrOptions: WithOrOptions) => invokeNormalizedIteration(normalizedEach, source, withOrOptions)) as EachFunction;\n\n/**\n * Builds a new array from the provided collection, optionally transforming or filtering elements.\n *\n * Options:\n * - `with`: function to transform each element (like map)\n * - `when`: function to filter elements (like filter)\n * - `into`: array to push results into (default: new array)\n *\n * @param source The collection to iterate (array, object, Map, Set, etc.)\n * @param withOrOptions Optional: `with` function, or options object, or `into` array.\n * @returns The resulting array.\n */\nexport const array: ArrayFunction = ((source: any, withOrOptions: WithOrOptions) => invokeNormalizedIteration(normalizedArrayIteration, source, withOrOptions)) as ArrayFunction;\n\n/**\n * Builds a new object from the provided collection, optionally transforming keys/values or filtering elements.\n *\n * Options:\n * - `with`: function to transform each value\n * - `when`: function to filter elements\n * - `key`/`withKey`: function to determine output keys\n * - `into`: object to assign results into (default: new object)\n *\n * Defaults:\n * - no `with`: uses the source container's \"values\" as the default\n * - no `withKey`: from arrays, uses the values as keys, from objects, uses the keys as keys\n * - no `into`: creates a new object\n *\n * Simplest example use: `object([\"sally\", \"billy\", \"chad\"])` => { \"sally\": \"sally\", \"billy\": \"billy\", \"chad\": \"chad\" }\n *\n * @param source The collection to iterate (array, object, Map, Set, etc.)\n * @param withOrOptions Optional: `with` function, or options object, or `into` object.\n * @returns The resulting object.\n */\nexport const object: ObjectFunction = ((source: any, withOrOptions: WithOrOptions) => invokeNormalizedIteration(normalizedObjectIteration, source, withOrOptions)) as ObjectFunction;\n\n/**\n * Reduces the provided collection to a single value, similar to Array.prototype.reduce.\n *\n * The first element is used as the initial value unless an `into`/`inject`/`returning` option is provided.\n *\n * Options:\n * - `with`: reducer function (receives accumulator, value, key)\n * - `when`: function to filter elements\n * - `into`/`inject`/`returning`: initial value for the reduction\n *\n * @param source The collection to reduce (array, object, Map, Set, etc.)\n * @param withOrOptions Optional: initial value or reducer function or options object.\n * @returns The reduced value.\n */\nexport const reduce: ReduceFunction = ((source: any, withOrOptions: WithOrOptions) => invokeNormalizedIteration(normalizedReduceIteration, source, withOrOptions)) as ReduceFunction;\n\n/**\n * Finds and returns the first value in the collection that matches the given criteria.\n *\n * Options:\n * - `with`: function to transform the found value\n * - `when`: function to filter elements (predicate)\n *\n * @param source The collection to search (array, object, Map, Set, etc.)\n * @param withOrOptions Optional: predicate or options object.\n * @returns The found value, or undefined if not found.\n */\nexport const find: FindFunction = ((source: any, withOrOptions: WithOrOptions) => invokeNormalizedIteration(normalizedFindIteration, source, withOrOptions)) as FindFunction;\n\n\n/**\n * Returns true if the source is a comprehension iterable.\n *\n * A comprehension iterable is any object that can be iterated over.\n *\n * This is different from isFullySupportedComprehensionIterable, which only checks if we can both generate and iterate over the source.\n *\n * NOTE strings are not considered comprehension iterables.\n *\n * @param source - The source to check.\n * @returns True if the source is a comprehension iterable, false otherwise.\n */\nexport const isComprehensionIterable = (source: any): source is AnyContainer<any> =>\n isArrayIterable(source) || isPlainObject(source) || isMap(source) || isSet(source) || isOfIterable(source)\n\n/**\n * Returns true if the source is a fully supported comprehension iterable.\n *\n * Fully supported means we can both generate as well as iterate over the source.\n *\n * This is different from isComprehensionIterable, which only checks if we can iterate over the source.\n *\n * This is useful for cases where we need to know if we can both generate and iterate over the source,\n * such as when we are using the source in a comprehension.\n *\n * Currently, this is only true for arrays and objects. TODO: add Map and Set support.\n * @param source - The source to check.\n * @returns True if the source is a fully supported comprehension iterable, false otherwise.\n */\nexport const isFullySupportedComprehensionIterable = (source: any): source is AnyContainer<any> =>\n isArrayIterable(source) || isPlainObject(source)\n","/**\n * DeepComprehensions is a library that provides a way to map and iterate over deeply nested comprehension iterables.\n *\n * It is useful for cases where you need to map or iterate over a deeply nested comprehension iterable.\n *\n * NOTE: due to their nature, deep comprehensions don't support TypeScript's type inference. You'll need to post-validate or coerce the results to the correct type.\n *\n * TODO: add Map and Set support.\n * TODO: add {when} support. Example usage: deepStripNull = deepMap(obj, {when: v => v !== null})\n */\nimport { isPlainObject } from '@art-suite/art-core-ts-types'\nimport { each, isComprehensionIterable, isFullySupportedComprehensionIterable, isArrayIterable, array, object } from './Comprehensions'\nimport { AnyContainer, FullySupportedContainer, ArrayInput, ObjectInput, NotPresent } from './ComprehensionTypes'\nimport { isFunction } from '@art-suite/art-core-ts-types'\n\nexport type DeepWithFunction = (value: any, key: any) => void\nexport type DeepWhenFunction = (value: any, key: any) => boolean\n\nexport type DeepOptions = {\n when?: DeepWhenFunction\n with?: DeepWithFunction\n}\n\nexport type DeepSecondParameter = DeepWithFunction | DeepOptions\n\n//******************************************************************************************************************\n// HELPERS\n//******************************************************************************************************************\n\nconst defaultWithFunction: DeepWithFunction = v => v\nconst defaultWhenFunction: DeepWhenFunction = () => true\n\ntype DeepOptionsFullSupport = {\n when: DeepWhenFunction\n with: DeepWithFunction\n}\n\nconst normalizeDeepOptions = (options: DeepSecondParameter): DeepOptionsFullSupport => {\n if (isFunction(options)) {\n return { with: options, when: defaultWhenFunction }\n }\n return { with: options.with ?? defaultWithFunction, when: options.when ?? defaultWhenFunction }\n}\n\nconst deepEachR = (obj: AnyContainer<any>, options: DeepOptionsFullSupport) =>\n each(obj, {\n when: options.when,\n with: (value: any, key: any) =>\n isComprehensionIterable(value)\n ? deepEachR(value, options)\n : options.with(value, key)\n })\n\nconst deepMapR = (obj: AnyContainer<any>, options: DeepOptionsFullSupport) =>\n mapInternal(obj, {\n when: options.when, with: (value: any, key: any) =>\n isFullySupportedComprehensionIterable(value)\n ? deepMapR(value, options)\n : options.with(value, key)\n })\n\nconst mapInternal = (source: ArrayInput<any> | ObjectInput<any> | NotPresent, options: DeepOptionsFullSupport) => {\n if (isArrayIterable(source)) return array(source, options)\n if (isPlainObject(source)) return object(source, options)\n throw new Error(`Unsupported source type: ${typeof source}`)\n}\n\n//******************************************************************************************************************\n// EXPORTS\n//******************************************************************************************************************\n/**\n * Maps over a fully supported comprehension iterable, shallowly.\n *\n * Returns the same container type (array or object) as the original object, but with the values mapped.\n *\n * @param source - The source to map over.\n * @param options - the map-function or {with: the map-function, when: the when-function}\n * @returns The mapped container.\n */\nexport const map = (source: ArrayInput<any> | ObjectInput<any> | NotPresent, options: DeepSecondParameter) =>\n mapInternal(source, normalizeDeepOptions(options))\n\n/**\n * Iterates over a fully supported comprehension iterable, and any nested isComprehensionIterable values.\n *\n * withFunction is called for each value that is NOT isComprehensionIterable and true for whenFunction (if provided).\n *\n * whenFunction is called on EVERY value, isComprehensionIterable or not. If it returns false, isComprehensionIterable values will be skipped.\n *\n * @param obj - The object to iterate over.\n * @param options - the with-function or {with: the with-function, when: the when-function}\n * @returns The object.\n */\nexport const deepEach = (obj: AnyContainer<any>, options: DeepSecondParameter) =>\n deepEachR(obj, normalizeDeepOptions(options))\n\n/**\n * Maps over a fully supported comprehension iterable, and any nested fully supported comprehension iterables.\n *\n * Returns the same structure (of fully supported comprehension iterables) as the original object, but with the values mapped.\n * If the source is not a fully supported comprehension iterable, it will return the source unchanged.\n * If the source is a fully supported comprehension iterable, it will return a new fully supported comprehension iterable with the values mapped.\n *\n * whenFunction is called on EVERY value, isComprehensionIterable or not. If it returns false, isComprehensionIterable values will be skipped.\n *\n * @param obj - The object to map over.\n * @param options - the map-function or {with: the map-function, when: the when-function}\n * @returns The mapped object.\n */\nexport const deepMap = (obj: FullySupportedContainer<any>, options: DeepSecondParameter) =>\n deepMapR(obj, normalizeDeepOptions(options))\n","import { object } from '@art-suite/art-core-ts-comprehensions';\n\nconst communicationStatusesPartials = {\n // HTTP Success Statuses\n success: { httpStatus: 200 },\n\n // HTTP Failure Statuses\n missing: { httpStatus: 404, failure: true },\n clientFailure: { httpStatus: 400, clientFailure: true, failure: true },\n clientFailureNotAuthorized: { httpStatus: 403, clientFailure: true, failure: true },\n serverFailure: { httpStatus: 500, failure: true, serverFailure: true },\n failure: { httpStatus: 500, failure: true },\n\n // Non-HTTP Statuses\n pending: { httpStatus: undefined },\n networkFailure: { httpStatus: undefined, failure: true },\n aborted: { httpStatus: undefined, failure: true },\n timeoutFailure: { httpStatus: undefined, failure: true }\n};\n\n/**\n * The core of Art-core-ts-communication-status: A simplified set of statuses as a human-readable and machine-interpretable string\n * representing all the possible communication statuses that are pragmatically actionable.\n */\nexport type CommunicationStatus = keyof typeof communicationStatusesPartials;\n\nexport type HttpOrCommunicationStatus = CommunicationStatus | number;\n\n/**\n * Details about a communication status\n *\n * @param httpStatus - The HTTP status code for the communication status\n * @param failure - Whether the communication status is a failure\n * @param clientFailure - Whether the communication status is a client failure\n * @param serverFailure - Whether the communication status is a server failure\n * @param status - The communication status - alias for communicationStatus\n * @param communicationStatus - The communication status\n */\nexport interface CommunicationStatusDetails {\n httpStatus?: number;\n failure?: boolean;\n clientFailure?: boolean;\n serverFailure?: boolean;\n status: CommunicationStatus;\n communicationStatus: CommunicationStatus;\n message: string;\n}\n\nexport const communicationStatuses: Record<CommunicationStatus, CommunicationStatusDetails> = object(communicationStatusesPartials, (details: any, status) => ({\n ...details,\n failure: !!details.failure,\n clientFailure: !!details.clientFailure,\n serverFailure: !!details.serverFailure,\n status: status as CommunicationStatus,\n communicationStatus: status as CommunicationStatus,\n message: details.httpStatus ? `${status} (${details.httpStatus})` : status\n})) as Record<CommunicationStatus, CommunicationStatusDetails>;\n\nexport type CommunicationStatuses = typeof communicationStatuses;\n\n/**\n * RegEx returns true for all valid communication statuses\n */\nexport const statusRegex = new RegExp(`^(${Object.keys(communicationStatuses).join('|')})$`);\n","import { aborted, clientFailureNotAuthorized, missing, networkFailure, pending, success, timeoutFailure } from './CommunicationStatusConsts';\nimport { getCommunicationStatus, getCommunicationStatusDetails } from './CommunicationStatusConversions';\nimport { HttpOrCommunicationStatus, statusRegex } from './CommunicationStatusTypes';\n\n// Core status check functions\n/** Returns true for HTTP 2xx responses */\nexport const isSuccess = (status: HttpOrCommunicationStatus | null | undefined) => !!status && getCommunicationStatus(status) === success;\n\n/**\n * Returns true for any error response (HTTP 4xx/5xx) or network/abort failures\n *\n * HTTP Status Codes Covered:\n * - 4xx: Client-side errors (except 404)\n * - 5xx: Server-side errors\n * - Network failures\n * - Abort failures\n *\n * Client Can:\n * - Use a different is* function for more specific checks\n */\nexport const isFailure = (status: HttpOrCommunicationStatus | null | undefined) => !!status && getCommunicationStatusDetails(status).failure;\n\n/**\n * Returns true for client-side errors\n *\n * HTTP Status Codes Covered:\n * - 400: Bad Request\n * - 401: Unauthorized\n * - 403: Forbidden\n * - 407: Proxy Authentication Required\n * - 409: Conflict\n * - 422: Unprocessable Entity\n *\n * Client Can Automatically:\n * - Notify the user that the client is experiencing issues\n *\n * Client Developer Can:\n * - use isClientFailureNotAuthorized to check for 401/403/407/451\n * - fix the request to avoid the 4xx error\n*/\nexport const isClientFailure = (status: HttpOrCommunicationStatus | null | undefined) => !!status && getCommunicationStatusDetails(status).clientFailure;\n\n/**\n * Returns true for server-side errors\n *\n * HTTP Status Codes Covered:\n * - 500: Internal Server Error\n * - 502: Bad Gateway\n * - 503: Service Unavailable\n * - 504: Gateway Timeout\n *\n * Client Can Automatically:\n * - Ask the user to try again later\n * - Notify the user that the server is experiencing issues\n *\n * Client Developer: (probably) can't fix\n *\n * Server Developer Can:\n * - fix the server to avoid the 5xx error\n * - fix server infrastructure to avoid the 5xx error (e.g. Bad Gateway, Service Unavailable, Gateway Timeout)\n*/\nexport const isServerFailure = (status: HttpOrCommunicationStatus | null | undefined) => !!status && getCommunicationStatusDetails(status).serverFailure;\n\n/**\n * Returns true when request fails due to network connectivity issues\n *\n * HTTP Status Codes Covered: NONE (server was not reachable)\n *\n * Client Can Automatically:\n * - Prompt the user to fix the network connection\n * - Retry the request\n *\n * Client Developer Can:\n * - fix bad network constants (like address, ports, etc.)\n*/\nexport const isNetworkFailure = (status: HttpOrCommunicationStatus | null | undefined) => !!status && getCommunicationStatus(status) === networkFailure;\n\n/** Returns true for server errors, network failures and aborted requests; i.e. the client did nothing wrong (as far as we can tell); client can ask the user to do something OR retry the request */\nexport const isNonClientFailure = (status: HttpOrCommunicationStatus | null | undefined) => {\n if (!status) return false;\n const details = getCommunicationStatusDetails(status);\n return details.failure && !details.clientFailure;\n};\n\n/**\n * Returns true for unauthorized requests (not authenticated or not authorized)\n *\n * HTTP Status Codes Covered:\n * - 401: Unauthorized\n * - 403: Forbidden\n * - 407: Proxy Authentication Required\n * - 451: Unavailable For Legal Reasons\n * - 511: Network Authentication Required\n *\n * Client Can Automatically:\n * - refresh the request token\n * - prompt the user to re-login\n * - ask the user to contact the administrator for access\n *\n * Client and Server Developer Can:\n * - fix authorization / authentication bugs\n */\nexport const isClientFailureNotAuthorized = (status: HttpOrCommunicationStatus | null | undefined) =>\n !!status &&\n getCommunicationStatus(status) === clientFailureNotAuthorized;\n\n/**\n * Returns true when request was cancelled by client\n *\n * Client Can Automatically:\n * - notify the user that the request was cancelled\n * - prompt the user to try again\n *\n * Client Developer Can:\n * - fix the client to not abort the request\n */\nexport const isAborted = (status: HttpOrCommunicationStatus | null | undefined) => !!status && getCommunicationStatus(status) === aborted;\n\n/**\n * Returns true when resource not found / not available\n *\n * HTTP Status Codes Covered:\n * - 404: Not Found\n * - 501: Not Implemented\n *\n * Client Can Automatically:\n * - notify the user that the resource was not found\n * - prompt the user to request a different resource\n *\n * Client Developer Can:\n * - fix the bad resource paths\n */\nexport const isMissing = (status: HttpOrCommunicationStatus | null | undefined) => !!status && getCommunicationStatus(status) === missing;\n\n/**\n * Returns true while request is in progress\n *\n * Client Can Automatically:\n * - notify the user that the request is in progress\n * - show the user progress (if available)\n * - allow the user to cancel the request (trigging an \"aborted\" communication status)\n *\n * Client Developer Can:\n * - if \"pending\" was not expected, maybe the client needs to `wait` for the request to complete?\n */\nexport const isPending = (status: HttpOrCommunicationStatus | null | undefined) => !!status && getCommunicationStatus(status) === pending;\n\n/**\n * Returns true if the request timed out\n *\n * Client Can Automatically:\n * - notify the user that the request timed out\n * - try again (automatically or via user action)\n *\n * Client Developer Can:\n * - extend the timeoutFailure duration\n *\n * Server Developer Can:\n * - improve server performance and reliability\n */\nexport const isTimeout = (status: HttpOrCommunicationStatus | null | undefined) => !!status && getCommunicationStatus(status) === timeoutFailure;\n\n/**\n * Returns true if client can safely retry the request\n *\n * A a clearly-retryable failure:\n *\n * - network failure\n * - timeoutFailure\n * - aborted\n *\n * Note: some serverFailures will succeed on retry, but HTTP doesn't return clear indications which ones. To be safe, the client should not retry serverFailures indiscriminately.\n *\n * Client and Server Devs can\n * - investigate network, client and server performance and reliability issues\n */\nexport const isRetryableFailure = (status: HttpOrCommunicationStatus | null | undefined) => {\n if (!status) return false;\n const { status: communicationStatus, failure } = getCommunicationStatusDetails(status);\n return failure && (communicationStatus === networkFailure || communicationStatus === timeoutFailure || communicationStatus === aborted);\n};\n\n/**\n * Returns true if the status is a valid communication status\n */\nexport const isStatusValid = (status: string) => statusRegex.test(status);\n","import { clientFailure, clientFailureNotAuthorized, missing, networkFailure, serverFailure, success } from './CommunicationStatusConsts';\nimport { isStatusValid } from './CommunicationStatusTests';\nimport { CommunicationStatus, CommunicationStatusDetails, communicationStatuses } from './CommunicationStatusTypes';\n\n//***************************************************************************************************************\n// Private Helpers\n//***************************************************************************************************************\nconst getCommunicationStatusFromHttpStatusOrUndefined = (httpStatus: number): CommunicationStatus | undefined => {\n switch (Math.floor(httpStatus / 100)) {\n case 2: return success;\n case 3: return missing;\n case 4:\n switch (httpStatus) {\n case 401:\n case 403:\n case 407:\n case 451: return clientFailureNotAuthorized;\n case 404: return missing;\n default: return clientFailure;\n }\n case 5:\n switch (httpStatus) {\n case 502:\n case 503:\n case 504: return networkFailure;\n case 511: return clientFailureNotAuthorized;\n case 501: return missing; // 501 Not Implemented - i.e. it \"does not exist\" currently - i.e. missing\n case 505: // HTTP Version Not Supported - client should change the request\n case 530: return clientFailure;\n default: return serverFailure;\n }\n }\n return undefined;\n};\n\nconst getCommunicationStatusFromHttpStatus = (httpStatus: number): CommunicationStatus => {\n const status = getCommunicationStatusFromHttpStatusOrUndefined(httpStatus);\n if (!status) {\n throw new Error(`httpStatus ${httpStatus} is not a supported CommunicationStatus.`);\n }\n return status;\n};\n\n//***************************************************************************************************************\n// Public Functions\n//***************************************************************************************************************\nexport const getCommunicationStatusOrUndefined = <T extends number | CommunicationStatus | null | undefined>(\n status: T\n): T extends null | undefined ? undefined : (CommunicationStatus | undefined) => {\n if (status == null) return undefined as any;\n if (typeof status === 'string') {\n if (!isStatusValid(status)) {\n return undefined;\n }\n return status as any;\n }\n if (typeof status === 'number') {\n return getCommunicationStatusFromHttpStatusOrUndefined(status) as any;\n }\n return undefined;\n};\n\n/*\n * Returns the CommunicationStatus for a given CommunicationStatus or number\n * If the input is null or undefined, returns undefined, otherwise throws an error if the CommunicationStatus or number is not supported\n * @param status - The CommunicationStatus or number to get the CommunicationStatus for\n * @returns The CommunicationStatus for the given CommunicationStatus or number\n */\nexport const getCommunicationStatus = <T extends number | CommunicationStatus | null | undefined>(\n status: T\n): T extends null | undefined ? undefined : CommunicationStatus => {\n if (status == null) return undefined as any;\n if (typeof status === 'number') {\n return getCommunicationStatusFromHttpStatus(status) as any;\n }\n const communicationStatus: CommunicationStatus | undefined = getCommunicationStatusOrUndefined(status);\n if (!communicationStatus) {\n throw new Error(`${status} is not a valid CommunicationStatus.`);\n }\n return communicationStatus as any;\n};\n\n/**\n * Returns the HTTP status code for a given CommunicationStatus or number\n * If the input is null or undefined, returns undefined, otherwise throws an error if the CommunicationStatus or number is not supported\n * @param status - The CommunicationStatus or number to get the HTTP status code for\n * @returns The HTTP status code for the given CommunicationStatus or number\n */\nexport const getHttpStatus = <T extends CommunicationStatus | number | null | undefined>(status: T): T extends null | undefined ? undefined : number => {\n if (status == null) return undefined as any;\n const communicationStatus = getCommunicationStatus(status);\n const httpStatus = communicationStatuses[communicationStatus].httpStatus;\n if (httpStatus == null) {\n throw new Error(`There is no valid HttpStatus for ${status}.`);\n }\n return httpStatus as any;\n};\n\n/**\n * Returns CommunicationStatusDetails {status, httpStatus, message} given an HTTP status code\n *\n * Throws: Error if the HTTP status code is not supported (i.e. the 100 codes or non HTTP status code numbers)\n *\n * @param status - The HTTP status code to get the communication status for\n * @returns The CommunicationStatusDetails for the given status. Note, if an HTTP status is given, it won't necessarily be the httpStatus returned; HTTPStatuses are simplified along with CommunicationStatuses.\n */\nexport const getCommunicationStatusDetails = <T extends number | CommunicationStatus | null | undefined>(status: T):\n T extends null | undefined ? undefined : CommunicationStatusDetails => {\n if (status == null) return undefined as any;\n const communicationStatus = getCommunicationStatus(status);\n return communicationStatuses[communicationStatus] as any;\n};\n\nexport const getCommunicationStatusDetailsOrUndefined = <T extends number | CommunicationStatus | null | undefined>(\n status: T\n): T extends null | undefined ? undefined : (CommunicationStatusDetails | undefined) => {\n if (status == null) return undefined as any;\n const communicationStatus = getCommunicationStatusOrUndefined(status);\n if (communicationStatus == null) return undefined as any;\n return communicationStatuses[communicationStatus] as any;\n};\n"],"mappings":"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","names":["failure"]}
|
|
1
|
+
{"version":3,"sources":["../src/CommunicationStatusConsts.ts","../../art-core-ts-types/src/Types.ts","../../art-core-ts-comprehensions/src/Comprehensions.ts","../../art-core-ts-comprehensions/src/DeepComprehensions.ts","../src/CommunicationStatusTypes.ts","../src/CommunicationStatusTests.ts","../src/CommunicationStatusConversions.ts"],"sourcesContent":["// Export status constants\nimport type { CommunicationStatus } from './CommunicationStatusTypes';\n\n/**\n * HTTP 2xx responses\n *\n * Client Can Automatically:\n * - Process the successful response\n * - Update UI to reflect success\n *\n * Client Developer Can:\n * - Handle the successful response data\n */\nexport const success: CommunicationStatus = \"success\";\n\n/**\n * Resource not found\n *\n * HTTP Status Codes Covered:\n * - 404: Not Found\n *\n * Client Can Automatically:\n * - notify the user that the resource was not found\n * - prompt the user to request a different resource\n *\n * Client Developer Can:\n * - fix the bad resource paths\n */\nexport const missing: CommunicationStatus = \"missing\";\n\n/**\n * Client-side errors; i.e. the client needs to change the request somehow to succeed\n *\n * HTTP Status Codes Covered:\n * - 400: Bad Request\n * - 401: Unauthorized\n * - 403: Forbidden\n * - 407: Proxy Authentication Required\n * - 409: Conflict\n * - 422: Unprocessable Entity\n *\n * Client Can Automatically:\n * - Notify the user that the client is experiencing issues\n * - Prompt user to correct invalid input\n *\n * Client Developer Can:\n * - use isClientFailureNotAuthorized to check for 401/403/407/451\n * - fix the request to avoid the 4xx error\n * - validate input before sending requests\n */\nexport const clientFailure: CommunicationStatus = \"clientFailure\";\n\n/**\n * Unauthorized requests; i.e. client needs to change the credentials (or the grants for the current credentials) to succeed\n *\n * HTTP Status Codes Covered:\n * - 401: Unauthorized\n * - 403: Forbidden\n * - 407: Proxy Authentication Required\n * - 451: Unavailable For Legal Reasons\n *\n * Client Can Automatically:\n * - refresh the request token\n * - prompt the user to re-login\n * - ask the user to contact the administrator for access\n *\n * Client and Server Developer Can:\n * - fix authorization / authentication bugs\n */\nexport const clientFailureNotAuthorized: CommunicationStatus = \"clientFailureNotAuthorized\";\n\n/**\n * Server-side errors; i.e. internal server errors\n *\n * HTTP Status Codes Covered:\n * - 500: Internal Server Error\n * - 502: Bad Gateway\n * - 503: Service Unavailable\n * - 504: Gateway Timeout\n *\n * Client Can Automatically:\n * - Ask the user to try again later\n * - Notify the user that the server is experiencing issues\n * - Implement automatic retry with backoff\n *\n * Client Developer: (probably) can't fix\n *\n * Server Developer Can:\n * - fix the server to avoid the 5xx error\n * - fix server infrastructure to avoid the 5xx error\n */\nexport const serverFailure: CommunicationStatus = \"serverFailure\";\n\n/**\n * Request fails due to network connectivity issues\n *\n * HTTP Status Codes Covered: NONE (server was not reachable)\n *\n * Client Can Automatically:\n * - Prompt the user to fix the network connection\n * - Retry the request when network is available\n * - Monitor network status for recovery\n *\n * Client Developer Can:\n * - fix bad network constants (like address, ports, etc.)\n * - implement offline-first capabilities\n */\nexport const networkFailure: CommunicationStatus = \"networkFailure\";\n\n/**\n * Request was cancelled by client\n *\n * Client Can Automatically:\n * - notify the user that the request was cancelled\n * - prompt the user to try again\n * - cleanup any pending state\n *\n * Client Developer Can:\n * - fix the client to not abort the request unnecessarily\n * - implement proper cleanup on abort\n */\nexport const aborted: CommunicationStatus = \"aborted\";\n\n/**\n * Request is in progress\n *\n * Client Can Automatically:\n * - notify the user that the request is in progress\n * - show the user progress (if available)\n * - allow the user to cancel the request\n *\n * Client Developer Can:\n * - if \"pending\" was not expected, maybe the client needs to `wait` for the request to complete?\n * - implement proper loading states\n */\nexport const pending: CommunicationStatus = \"pending\";\n\n/**\n * Any error response (HTTP 4xx/5xx) or network/abort failures\n *\n * HTTP Status Codes Covered:\n * - 4xx: Client-side errors (except 404)\n * - 5xx: Server-side errors\n * - Network failures\n * - Abort failures\n *\n * Client Can Automatically:\n * - Show appropriate error message to user\n * - Implement generic error handling\n * - Log errors for debugging\n *\n * Client Developer Can:\n * - Use more specific is* functions for targeted error handling\n * - Implement proper error recovery strategies\n */\nexport const failure: CommunicationStatus = \"failure\";\n\n/**\n * Request timed out\n *\n * Client Can Automatically:\n * - notify the user that the request timed out\n * - try again (automatically or via user action)\n *\n * Client Developer Can:\n * - fix the client to not timeoutFailure the request\n * - implement proper timeoutFailure handling\n */\nexport const timeoutFailure: CommunicationStatus = \"timeoutFailure\";\n\n/**\n * Client has disabled the request explicitly.\n *\n * Client Can:\n * - re-enable the request\n */\nexport const disabled: CommunicationStatus = \"disabled\";\n\n/**\n * Unknown communication status\n *\n * Client Can:\n * - log the unknown status for debugging\n */\nexport const unknown: CommunicationStatus = \"unknown\";\n","import { PlainObject } from \"./TypeScriptTypes\"\n\ntype TypedArray = Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array\n\n/*\n\n @isPromise: (obj) => obj? && isFunction(obj.then) && !isFunction obj\n @isRegExp: (obj) => obj.constructor.name == \"RegExp\"\n @isNumber: isNumber = (obj) => typeof obj == \"number\"\n\n isNonNegativeInt: (x) ->\n ((x | 0) == x) &&\n x >= 0\n\n @isError: (obj) => obj? && obj instanceof Error\n @isDate: (obj) => obj?.constructor == Date\n @isString: isString = (obj) => typeof obj == \"string\"\n @isFunction: isFunction = (obj) => typeof obj == \"function\"\n @isEmptyObject: (obj) => Object.keys(obj).length == 0\n @isBoolean: (obj) => obj == true || obj == false\n\n @isArrayBuffer: isArrayBuffer = if global.ArrayBuffer\n (obj) -> obj? && obj.constructor == ArrayBuffer\n else -> false\n @isTypedArray: (obj) -> obj? && obj.length >= 0 && obj.length == (obj.length | 0) && isArrayBuffer obj.buffer\n\n */\n\n/**\n * Returns true if the value is an object. (note, Arrays are objects)\n * This is only false for null, undefined, functions, and primitives like strings, numbers, and booleans.\n * @param v\n * @returns\n */\nexport const isObject = (v: any): v is Record<string, any> => v != null && typeof v === 'object'\n\n/**\n * Returns true if the value is a plain object - i.e. an object who's prototype is Object\n * @param v\n * @returns\n */\nexport const isPlainObject = (v: any): v is PlainObject => {\n if (!isObject(v)) return false\n if (v.constructor === Object) return true // fast pass, but could fail if v was created in a different context with a different instance of Object\n const prototype = Object.getPrototypeOf(v)\n if (prototype === null) return true\n return null == Object.getPrototypeOf(prototype)\n}\n\nexport const asPlainObject = (v: any): PlainObject => isPlainObject(v) ? v : {}\n\nexport const isFunction = (obj: any): obj is Function => typeof obj === \"function\"\nexport const isNumber = (obj: any): obj is number => typeof obj === \"number\"\nexport const isString = (obj: any): obj is string => typeof obj === \"string\"\nexport const isArrayBuffer = (obj: any): obj is ArrayBuffer => obj != null && obj.constructor === ArrayBuffer\nexport const isArray = (obj: any): obj is any[] => Array.isArray(obj)\n\nexport const isPromise = (obj: any): obj is Promise<any> => obj != null && isFunction(obj.then) && !isFunction(obj)\nexport const isRegExp = (obj: any): obj is RegExp => obj?.constructor.name === \"RegExp\"\nexport const isError = (obj: any): obj is Error => obj != null && obj instanceof Error\nexport const isDate = (obj: any): obj is Date => obj?.constructor === Date\nexport const isEmptyObject = (obj: any): obj is Record<string, never> => Object.keys(obj).length === 0\nexport const isBoolean = (obj: any): obj is boolean => obj === true || obj === false\nexport const isTypedArray = (obj: any): obj is TypedArray =>\n obj != null &&\n obj.length >= 0 &&\n obj.length === (obj.length | 0) &&\n isArrayBuffer(obj.buffer)\n\nexport const isNonNegativeInt = (x: number): x is number => ((x | 0) === x) && x >= 0\n\nexport const stringIsPresent = (str: string): boolean => isString(str) && !/^(\\s+|)$/.test(str)\n\nexport const exists = (value: any): boolean => value != null\nexport const doesNotExist = (value: any): boolean => !exists(value)\n\nexport const isNull = (value: any): boolean => value === null\nexport const isNotNull = (value: any): boolean => !isNull(value)\n\nexport const isUndefined = (value: any): boolean => value === undefined\nexport const isNotUndefined = (value: any): boolean => !isUndefined(value)\n\nexport const isNullish = (value: any): boolean => value == null || value == undefined\nexport const isNotNullish = (value: any): boolean => !isNullish(value)\n\n/**\n * present returns true if \"there is a value _present_\"\n *\n * Specifically:\n * - if `value.getPresent()` is a function; it's called and it's value is returned\n * - if `value.present()` is a function; it's called and it's value is returned\n * - else: returns `true` if `!null`, `!undefined` and `!(string with only whitespace)`\n *\n * > Inspired by Ruby's `present?` method\n *\n * @param v\n * @returns\n */\nexport const present = <T>(v: T): v is NonNullable<T> => {\n if (v == null) return false\n if (isFunction((v as any).getPresent)) {\n return (v as any).getPresent()\n } else if (isFunction((v as any).present)) {\n return (v as any).present()\n } else if (isString(v)) {\n return stringIsPresent(v)\n } else return true\n}\n","import { isPlainObject, isFunction, exists } from '@art-suite/art-core-ts-types'\nimport { EachFunction, ArrayFunction, ObjectFunction, ReduceFunction, FindFunction, AnyContainer, ArrayInput, ObjectInput, NotPresent } from './ComprehensionTypes'\n\nconst isMap = (source: any): source is Map<any, any> => source instanceof Map;\nconst isSet = (source: any): source is Set<any> => source instanceof Set;\n\nexport const isArrayIterable = (source: any): source is any[] => {\n if (typeof source === 'string') return false\n if (isFunction(source)) return false\n return source != null && source.length >= 0;\n}\n\nexport const isOfIterable = (o: any): boolean => {\n if (typeof o === 'string') return false\n if (isFunction(o)) return false\n return isFunction(o[Symbol.iterator] || o.next)\n}\n\nconst returnFirstArg = (a: any) => a;\nconst returnSecondArg = (a: any, b: any) => b;\n\nconst emptyOptions = {};\n\ntype CoreIterationFunction = (value: any, key: any) => boolean; // returns true to stop iteration\n\n/**\n * Tight function to abstract away all possible iteration methods based on the source container type.\n *\n * Iterates over the source collection, calling the given function for each element.\n *\n * Stops when the body function returns true.\n * Does NOT return anything. If you need a return value, must set it as a side-effect of the body function.\n *\n * @param source - The collection to iterate (array, object, Map, Set, etc.)\n * @param body - The function to call for each element.\n * @returns void\n */\nconst iterate = (source: any, body: CoreIterationFunction): void => {\n if (exists(source))\n if (isArrayIterable(source)) for (let key = 0, { length } = source; key < length; key++) { if (body(source[key], key)) break; }\n else if (isPlainObject(source)) for (const key in source) { if (body(source[key], key)) break; }\n else if (isMap(source)) for (const [key, value] of source.entries()) { if (body(value, key)) break; }\n // else if (isSet(source)) for (const value of source) { if (body(value, value)) break; }\n else if (isOfIterable(source)) { let count = 0; for (const value of source) { if (body(value, count++)) break; } }\n else throw new Error(`Unsupported source type: ${typeof source}`);\n};\n\n/*\n Returns a function that handles \"with\", \"when\" and \"stopWhen\" comprehension clauses:\n\n 1. Returns true if the \"stopWhen\" is provided and returns true, otherwise returns it will return false\n 2. If stopWhen is false, \"when\" and \"with\" are processed\n 3. If there is no \"when\" or \"when\" returns true, \"with\" is called.\n*/\nconst normalizeBody = (withFunction: (value: any, key: any) => any, options: AcceptedComprehensionOptions): (value: any, key: any) => boolean => {\n let { when, stopWhen } = options;\n if (when && stopWhen) {\n return (v: any, k: any) => {\n if (stopWhen(v, k)) return true;\n if (when(v, k)) withFunction(v, k);\n return false;\n }\n }\n if (when) {\n return (v: any, k: any) => {\n if (when(v, k)) withFunction(v, k);\n return false;\n }\n }\n if (stopWhen) {\n return (v: any, k: any) => {\n if (stopWhen(v, k)) return true;\n withFunction(v, k);\n return false;\n }\n }\n return (v: any, k: any) => { withFunction(v, k); return false; };\n};\n\n\nlet normalizeKeyFunction = (source: any, options: AcceptedComprehensionOptions) =>\n options.withKey || (isArrayIterable(source) ? returnFirstArg : returnSecondArg)\n\nconst _each = (source: any, withFunction: (value: any, key: any) => any, options: AcceptedComprehensionOptions) => {\n iterate(source, normalizeBody(withFunction, options));\n};\n\n//************************************************************************\n// NORMALIZED COMPREHENSION FUNCTIONS\n//************************************************************************\ntype NormalizedIterationFunction = (source: any, options: NormalizedComprehensionOptions) => any;\n\nconst normalizedEach: NormalizedIterationFunction = (source: any, options: NormalizedComprehensionOptions) => {\n _each(source, options.with, options);\n return options.into;\n};\n\nconst normalizedArrayIteration: NormalizedIterationFunction = (source: any, options: NormalizedComprehensionOptions) => {\n let { into, with: withFunction } = options;\n if (into == null) into = [];\n _each(source, (v: any, k: any) => into.push(withFunction(v, k)), options);\n return into;\n};\n\nconst normalizedObjectIteration: NormalizedIterationFunction = (source: any, options: NormalizedComprehensionOptions) => {\n let { into, with: withFunction } = options;\n if (into == null) into = {};\n let withKey = normalizeKeyFunction(source, options);\n _each(source, (v, k) => (into[withKey(v, k)] = withFunction(v, k)), options);\n return into;\n};\n\nconst normalizedReduceIteration: NormalizedIterationFunction = (source: any, options: NormalizedComprehensionOptions) => {\n let { into, with: withFunction } = options;\n let first = into === undefined;\n _each(source, (v: any, k: any) => {\n if (first) { first = false; into = v; }\n else {\n into = withFunction(into, v, k)\n }\n }, options);\n return into;\n};\n\nconst normalizedFindIteration: NormalizedIterationFunction = (source: any, options: NormalizedComprehensionOptions) => {\n let { with: withFunction } = options;\n let { when } = options;\n let found: any | undefined = undefined;\n iterate(\n source,\n when\n ? (v, k) => {\n if (when(v, k)) {\n found = withFunction(v, k);\n return true; // signal to stop iteration\n }\n return false;\n }\n : (v, k) => {\n found = withFunction(v, k) // stops iteration if withFunction returns an value that \"exists\" (is not undefined, non null)\n return found != null;\n }\n );\n return found;\n};\n\n//####################\n// PRIVATE\n//####################\n\n// WithFunction has two signatures: value + key, or for reduce, accumulator + value + key\ntype ValueKeyFunction = (value?: any, key?: any) => any;\ntype AccumulatorValueKeyFunction = (accumulator?: any, value?: any, key?: any) => any;\ntype WithFunction = ValueKeyFunction | AccumulatorValueKeyFunction;\ntype WhenFunction = (value: any, key: any) => any;\ntype WithKeyFunction = (value: any, key: any) => any;\n\ntype AcceptedComprehensionOptions = {\n into?: any;\n inject?: any; // alias for into - used to make \"reduce\" calls make more sense\n returning?: any; // alias for into - used to make \"each\" calls make more sense\n with?: WithFunction;\n when?: WhenFunction;\n withKey?: WithKeyFunction;\n stopWhen?: (value: any, key: any) => any;\n}\n\ntype WithOrOptions = WithFunction | AcceptedComprehensionOptions;\n\nconst isAcceptedComprehensionOptions = (o: any): o is AcceptedComprehensionOptions => isPlainObject(o)\n\n// the 'with' param will always exist when normalized\ntype NormalizedComprehensionOptions = Omit<AcceptedComprehensionOptions, 'with' | 'inject' | 'returning'> & {\n with: WithFunction;\n}\n\n/**\n * Returns the first non-undefined value from into, inject, or returning\n *\n * @param into - The 'into' parameter.\n * @param inject - The 'inject' parameter.\n * @param returning - The 'returning' parameter.\n * @returns The normalized 'into' parameter.\n */\nconst firstNotUndefined = (into: any, inject: any, returning: any) => {\n if (into === undefined) into = inject\n if (into === undefined) into = returning\n return into\n}\n\nconst normalizeIterationParams = (withOrOptions?: WithOrOptions): NormalizedComprehensionOptions => {\n if (isAcceptedComprehensionOptions(withOrOptions)) {\n const { with: withFunction, into, inject, returning, ...rest } = withOrOptions;\n return { ...rest, into: firstNotUndefined(into, inject, returning), with: withFunction ?? returnFirstArg };\n }\n if (isFunction(withOrOptions)) {\n return { with: withOrOptions };\n }\n return { with: returnFirstArg };\n};\n\n/*\nNormalizes input params for the 'iteration' function.\nSince this normalizes multiple params, and therefor would need to return\nan new array or new object otherwise, we pass IN the iteration function\nand pass the params directly to it. This keeps the computed params on the\nstack and doesn't create new objects.\n\nIN signature 1: (iteration, source, withFunction) ->\nIN signature 2: (iteration, source, options) ->\nIN signature 3: (iteration, source) ->\n\nIN:\niteration: (source, into, withFunction, options) -> out\n\n The iteration function is invoked last with the computed args.\n Its results are returned.\n\n IN:\n source: passed directly through from inputs\n into: passed directly through from inputs OR from options.into\n withFunction: passed directly through from inputs OR from options.with\n options: passed directly through from inputs OR {}\n (guaranteed to be set and a plainObject)\n\nsource: the source collection to be iterated over. Passed directly through.\n\ninto: passed through to 'iteration'\nwithFunction: passed through to 'iteration'\noptions: passed through to 'iteration' AND:\n\n into: set 'into' from the options object\n with: set 'withFunction' from the options object\n\nOUT: out\n*/\nconst invokeNormalizedIteration = (\n normalizedIterationFunction: NormalizedIterationFunction,\n source: any,\n withOrOptions: WithOrOptions\n) => normalizedIterationFunction(source, normalizeIterationParams(withOrOptions));\n\n/**\n * Iterates over the provided collection, calling the given function for each element.\n *\n * Unlike other comprehensions, `each` is designed for side effects and does not build a new collection.\n *\n * **Return value:**\n * - If an `into`, `inject`, or `returning` option is provided (or as the second argument), that value is returned (not modified by `each` itself).\n * - If no such value is provided, returns `undefined`.\n *\n * This allows you to use `each` for side effects while optionally threading a value through the iteration.\n *\n * @param source The collection to iterate (array, object, Map, Set, etc.)\n * @param withOrOptions Optional: Either the `into` value or the function to call for each element.\n * @returns The `into`/`inject`/`returning` value if provided, otherwise `undefined`.\n */\nexport const each: EachFunction = ((source: any, withOrOptions: WithOrOptions) => invokeNormalizedIteration(normalizedEach, source, withOrOptions)) as EachFunction;\n\n/**\n * Builds a new array from the provided collection, optionally transforming or filtering elements.\n *\n * Options:\n * - `with`: function to transform each element (like map)\n * - `when`: function to filter elements (like filter)\n * - `into`: array to push results into (default: new array)\n *\n * @param source The collection to iterate (array, object, Map, Set, etc.)\n * @param withOrOptions Optional: `with` function, or options object, or `into` array.\n * @returns The resulting array.\n */\nexport const array: ArrayFunction = ((source: any, withOrOptions: WithOrOptions) => invokeNormalizedIteration(normalizedArrayIteration, source, withOrOptions)) as ArrayFunction;\n\n/**\n * Builds a new object from the provided collection, optionally transforming keys/values or filtering elements.\n *\n * Options:\n * - `with`: function to transform each value\n * - `when`: function to filter elements\n * - `key`/`withKey`: function to determine output keys\n * - `into`: object to assign results into (default: new object)\n *\n * Defaults:\n * - no `with`: uses the source container's \"values\" as the default\n * - no `withKey`: from arrays, uses the values as keys, from objects, uses the keys as keys\n * - no `into`: creates a new object\n *\n * Simplest example use: `object([\"sally\", \"billy\", \"chad\"])` => { \"sally\": \"sally\", \"billy\": \"billy\", \"chad\": \"chad\" }\n *\n * @param source The collection to iterate (array, object, Map, Set, etc.)\n * @param withOrOptions Optional: `with` function, or options object, or `into` object.\n * @returns The resulting object.\n */\nexport const object: ObjectFunction = ((source: any, withOrOptions: WithOrOptions) => invokeNormalizedIteration(normalizedObjectIteration, source, withOrOptions)) as ObjectFunction;\n\n/**\n * Reduces the provided collection to a single value, similar to Array.prototype.reduce.\n *\n * The first element is used as the initial value unless an `into`/`inject`/`returning` option is provided.\n *\n * Options:\n * - `with`: reducer function (receives accumulator, value, key)\n * - `when`: function to filter elements\n * - `into`/`inject`/`returning`: initial value for the reduction\n *\n * @param source The collection to reduce (array, object, Map, Set, etc.)\n * @param withOrOptions Optional: initial value or reducer function or options object.\n * @returns The reduced value.\n */\nexport const reduce: ReduceFunction = ((source: any, withOrOptions: WithOrOptions) => invokeNormalizedIteration(normalizedReduceIteration, source, withOrOptions)) as ReduceFunction;\n\n/**\n * Finds and returns the first value in the collection that matches the given criteria.\n *\n * Options:\n * - `with`: function to transform the found value\n * - `when`: function to filter elements (predicate)\n *\n * @param source The collection to search (array, object, Map, Set, etc.)\n * @param withOrOptions Optional: predicate or options object.\n * @returns The found value, or undefined if not found.\n */\nexport const find: FindFunction = ((source: any, withOrOptions: WithOrOptions) => invokeNormalizedIteration(normalizedFindIteration, source, withOrOptions)) as FindFunction;\n\n\n/**\n * Returns true if the source is a comprehension iterable.\n *\n * A comprehension iterable is any object that can be iterated over.\n *\n * This is different from isFullySupportedComprehensionIterable, which only checks if we can both generate and iterate over the source.\n *\n * NOTE strings are not considered comprehension iterables.\n *\n * @param source - The source to check.\n * @returns True if the source is a comprehension iterable, false otherwise.\n */\nexport const isComprehensionIterable = (source: any): source is AnyContainer<any> =>\n isArrayIterable(source) || isPlainObject(source) || isMap(source) || isSet(source) || isOfIterable(source)\n\n/**\n * Returns true if the source is a fully supported comprehension iterable.\n *\n * Fully supported means we can both generate as well as iterate over the source.\n *\n * This is different from isComprehensionIterable, which only checks if we can iterate over the source.\n *\n * This is useful for cases where we need to know if we can both generate and iterate over the source,\n * such as when we are using the source in a comprehension.\n *\n * Currently, this is only true for arrays and objects. TODO: add Map and Set support.\n * @param source - The source to check.\n * @returns True if the source is a fully supported comprehension iterable, false otherwise.\n */\nexport const isFullySupportedComprehensionIterable = (source: any): source is AnyContainer<any> =>\n isArrayIterable(source) || isPlainObject(source)\n","/**\n * DeepComprehensions is a library that provides a way to map and iterate over deeply nested comprehension iterables.\n *\n * It is useful for cases where you need to map or iterate over a deeply nested comprehension iterable.\n *\n * NOTE: due to their nature, deep comprehensions don't support TypeScript's type inference. You'll need to post-validate or coerce the results to the correct type.\n *\n * TODO: add Map and Set support.\n * TODO: add {when} support. Example usage: deepStripNull = deepMap(obj, {when: v => v !== null})\n */\nimport { isPlainObject } from '@art-suite/art-core-ts-types'\nimport { each, isComprehensionIterable, isFullySupportedComprehensionIterable, isArrayIterable, array, object } from './Comprehensions'\nimport { AnyContainer, FullySupportedContainer, ArrayInput, ObjectInput, NotPresent } from './ComprehensionTypes'\nimport { isFunction } from '@art-suite/art-core-ts-types'\n\nexport type DeepWithFunction = (value: any, key: any) => void\nexport type DeepWhenFunction = (value: any, key: any) => boolean\n\nexport type DeepOptions = {\n when?: DeepWhenFunction\n with?: DeepWithFunction\n}\n\nexport type DeepSecondParameter = DeepWithFunction | DeepOptions\n\n//******************************************************************************************************************\n// HELPERS\n//******************************************************************************************************************\n\nconst defaultWithFunction: DeepWithFunction = v => v\nconst defaultWhenFunction: DeepWhenFunction = () => true\n\ntype DeepOptionsFullSupport = {\n when: DeepWhenFunction\n with: DeepWithFunction\n}\n\nconst normalizeDeepOptions = (options: DeepSecondParameter): DeepOptionsFullSupport => {\n if (isFunction(options)) {\n return { with: options, when: defaultWhenFunction }\n }\n return { with: options.with ?? defaultWithFunction, when: options.when ?? defaultWhenFunction }\n}\n\nconst deepEachR = (obj: AnyContainer<any>, options: DeepOptionsFullSupport) =>\n each(obj, {\n when: options.when,\n with: (value: any, key: any) =>\n isComprehensionIterable(value)\n ? deepEachR(value, options)\n : options.with(value, key)\n })\n\nconst deepMapR = (obj: AnyContainer<any>, options: DeepOptionsFullSupport) =>\n mapInternal(obj, {\n when: options.when, with: (value: any, key: any) =>\n isFullySupportedComprehensionIterable(value)\n ? deepMapR(value, options)\n : options.with(value, key)\n })\n\nconst mapInternal = (source: ArrayInput<any> | ObjectInput<any> | NotPresent, options: DeepOptionsFullSupport) => {\n if (isArrayIterable(source)) return array(source, options)\n if (isPlainObject(source)) return object(source, options)\n throw new Error(`Unsupported source type: ${typeof source}`)\n}\n\n//******************************************************************************************************************\n// EXPORTS\n//******************************************************************************************************************\n/**\n * Maps over a fully supported comprehension iterable, shallowly.\n *\n * Returns the same container type (array or object) as the original object, but with the values mapped.\n *\n * @param source - The source to map over.\n * @param options - the map-function or {with: the map-function, when: the when-function}\n * @returns The mapped container.\n */\nexport const map = (source: ArrayInput<any> | ObjectInput<any> | NotPresent, options: DeepSecondParameter) =>\n mapInternal(source, normalizeDeepOptions(options))\n\n/**\n * Iterates over a fully supported comprehension iterable, and any nested isComprehensionIterable values.\n *\n * withFunction is called for each value that is NOT isComprehensionIterable and true for whenFunction (if provided).\n *\n * whenFunction is called on EVERY value, isComprehensionIterable or not. If it returns false, isComprehensionIterable values will be skipped.\n *\n * @param obj - The object to iterate over.\n * @param options - the with-function or {with: the with-function, when: the when-function}\n * @returns The object.\n */\nexport const deepEach = (obj: AnyContainer<any>, options: DeepSecondParameter) =>\n deepEachR(obj, normalizeDeepOptions(options))\n\n/**\n * Maps over a fully supported comprehension iterable, and any nested fully supported comprehension iterables.\n *\n * Returns the same structure (of fully supported comprehension iterables) as the original object, but with the values mapped.\n * If the source is not a fully supported comprehension iterable, it will return the source unchanged.\n * If the source is a fully supported comprehension iterable, it will return a new fully supported comprehension iterable with the values mapped.\n *\n * whenFunction is called on EVERY value, isComprehensionIterable or not. If it returns false, isComprehensionIterable values will be skipped.\n *\n * @param obj - The object to map over.\n * @param options - the map-function or {with: the map-function, when: the when-function}\n * @returns The mapped object.\n */\nexport const deepMap = (obj: FullySupportedContainer<any>, options: DeepSecondParameter) =>\n deepMapR(obj, normalizeDeepOptions(options))\n","import { object } from '@art-suite/art-core-ts-comprehensions';\n\nconst communicationStatusesPartials = {\n // HTTP Success Statuses\n success: { httpStatus: 200 },\n\n // HTTP Failure Statuses\n missing: { httpStatus: 404, failure: true },\n clientFailure: { httpStatus: 400, clientFailure: true, failure: true },\n clientFailureNotAuthorized: { httpStatus: 403, clientFailure: true, failure: true },\n serverFailure: { httpStatus: 500, failure: true, serverFailure: true },\n failure: { httpStatus: 500, failure: true },\n\n // Non-HTTP Statuses\n pending: { httpStatus: undefined },\n networkFailure: { httpStatus: undefined, failure: true },\n aborted: { httpStatus: undefined, failure: true },\n timeoutFailure: { httpStatus: undefined, failure: true },\n disabled: { httpStatus: undefined },\n unknown: { httpStatus: undefined, failure: true }\n};\n\n/**\n * The core of Art-core-ts-communication-status: A simplified set of statuses as a human-readable and machine-interpretable string\n * representing all the possible communication statuses that are pragmatically actionable.\n */\nexport type CommunicationStatus = keyof typeof communicationStatusesPartials;\n\nexport type HttpOrCommunicationStatus = CommunicationStatus | number;\n\n/**\n * Details about a communication status\n *\n * @param httpStatus - The HTTP status code for the communication status\n * @param failure - Whether the communication status is a failure\n * @param clientFailure - Whether the communication status is a client failure\n * @param serverFailure - Whether the communication status is a server failure\n * @param status - The communication status - alias for communicationStatus\n * @param communicationStatus - The communication status\n */\nexport interface CommunicationStatusDetails {\n httpStatus?: number;\n failure?: boolean;\n clientFailure?: boolean;\n serverFailure?: boolean;\n status: CommunicationStatus;\n communicationStatus: CommunicationStatus;\n message: string;\n}\n\nexport const UnknownCommunicationStatusDetails: CommunicationStatusDetails = {\n status: 'unknown',\n communicationStatus: 'unknown',\n message: 'Unknown communication status',\n failure: true\n};\n\nexport const communicationStatuses: Record<CommunicationStatus, CommunicationStatusDetails> = object(communicationStatusesPartials, (details: any, status) => ({\n ...details,\n failure: !!details.failure,\n clientFailure: !!details.clientFailure,\n serverFailure: !!details.serverFailure,\n status: status as CommunicationStatus,\n communicationStatus: status as CommunicationStatus,\n message: details.httpStatus ? `${status} (${details.httpStatus})` : status\n})) as Record<CommunicationStatus, CommunicationStatusDetails>;\n\nexport type CommunicationStatuses = typeof communicationStatuses;\n\n/**\n * RegEx returns true for all valid communication statuses\n */\nexport const statusRegex = new RegExp(`^(${Object.keys(communicationStatuses).join('|')})$`);\n","import { isString } from '@art-suite/art-core-ts-types';\nimport { aborted, clientFailureNotAuthorized, disabled, missing, networkFailure, pending, success, timeoutFailure } from './CommunicationStatusConsts';\nimport { getCommunicationStatus, getCommunicationStatusDetails } from './CommunicationStatusConversions';\nimport { HttpOrCommunicationStatus, statusRegex } from './CommunicationStatusTypes';\n\n// Core status check functions\n/** Returns true for HTTP 2xx responses */\nexport const isSuccess = (status: HttpOrCommunicationStatus | null | undefined): boolean => !!status && getCommunicationStatus(status) === success;\n\n/**\n * Returns true for any error response (HTTP 4xx/5xx) or network/abort failures\n *\n * HTTP Status Codes Covered:\n * - 4xx: Client-side errors (except 404)\n * - 5xx: Server-side errors\n * - Network failures\n * - Abort failures\n *\n * Client Can:\n * - Use a different is* function for more specific checks\n */\nexport const isFailure = (status: HttpOrCommunicationStatus | null | undefined): boolean => !!(status && getCommunicationStatusDetails(status).failure);\n\n/**\n * Returns true for client-side errors\n *\n * HTTP Status Codes Covered:\n * - 400: Bad Request\n * - 401: Unauthorized\n * - 403: Forbidden\n * - 407: Proxy Authentication Required\n * - 409: Conflict\n * - 422: Unprocessable Entity\n *\n * Client Can Automatically:\n * - Notify the user that the client is experiencing issues\n *\n * Client Developer Can:\n * - use isClientFailureNotAuthorized to check for 401/403/407/451\n * - fix the request to avoid the 4xx error\n*/\nexport const isClientFailure = (status: HttpOrCommunicationStatus | null | undefined): boolean => !!(status && getCommunicationStatusDetails(status).clientFailure);\n\n/**\n * Returns true for server-side errors\n *\n * HTTP Status Codes Covered:\n * - 500: Internal Server Error\n * - 502: Bad Gateway\n * - 503: Service Unavailable\n * - 504: Gateway Timeout\n *\n * Client Can Automatically:\n * - Ask the user to try again later\n * - Notify the user that the server is experiencing issues\n *\n * Client Developer: (probably) can't fix\n *\n * Server Developer Can:\n * - fix the server to avoid the 5xx error\n * - fix server infrastructure to avoid the 5xx error (e.g. Bad Gateway, Service Unavailable, Gateway Timeout)\n*/\nexport const isServerFailure = (status: HttpOrCommunicationStatus | null | undefined): boolean => !!(status && getCommunicationStatusDetails(status).serverFailure);\n\n/**\n * Returns true when request fails due to network connectivity issues\n *\n * HTTP Status Codes Covered: NONE (server was not reachable)\n *\n * Client Can Automatically:\n * - Prompt the user to fix the network connection\n * - Retry the request\n *\n * Client Developer Can:\n * - fix bad network constants (like address, ports, etc.)\n*/\nexport const isNetworkFailure = (status: HttpOrCommunicationStatus | null | undefined): boolean => !!(status && getCommunicationStatus(status) === networkFailure);\n\n/** Returns true for server errors, network failures and aborted requests; i.e. the client did nothing wrong (as far as we can tell); client can ask the user to do something OR retry the request */\nexport const isNonClientFailure = (status: HttpOrCommunicationStatus | null | undefined): boolean => {\n if (!status) return false;\n const details = getCommunicationStatusDetails(status);\n return !!(details.failure && !details.clientFailure);\n};\n\n/**\n * Returns true for unauthorized requests (not authenticated or not authorized)\n *\n * HTTP Status Codes Covered:\n * - 401: Unauthorized\n * - 403: Forbidden\n * - 407: Proxy Authentication Required\n * - 451: Unavailable For Legal Reasons\n * - 511: Network Authentication Required\n *\n * Client Can Automatically:\n * - refresh the request token\n * - prompt the user to re-login\n * - ask the user to contact the administrator for access\n *\n * Client and Server Developer Can:\n * - fix authorization / authentication bugs\n */\nexport const isClientFailureNotAuthorized = (status: HttpOrCommunicationStatus | null | undefined): boolean =>\n !!status &&\n getCommunicationStatus(status) === clientFailureNotAuthorized;\n\n/**\n * Returns true when request was cancelled by client\n *\n * Client Can Automatically:\n * - notify the user that the request was cancelled\n * - prompt the user to try again\n *\n * Client Developer Can:\n * - fix the client to not abort the request\n */\nexport const isAborted = (status: HttpOrCommunicationStatus | null | undefined): boolean => !!(status && getCommunicationStatus(status) === aborted);\n\n/**\n * Returns true when resource not found / not available\n *\n * HTTP Status Codes Covered:\n * - 404: Not Found\n * - 501: Not Implemented\n *\n * Client Can Automatically:\n * - notify the user that the resource was not found\n * - prompt the user to request a different resource\n *\n * Client Developer Can:\n * - fix the bad resource paths\n */\nexport const isMissing = (status: HttpOrCommunicationStatus | null | undefined): boolean => !!(status && getCommunicationStatus(status) === missing);\n\n/**\n * Returns true while request is in progress\n *\n * Client Can Automatically:\n * - notify the user that the request is in progress\n * - show the user progress (if available)\n * - allow the user to cancel the request (trigging an \"aborted\" communication status)\n *\n * Client Developer Can:\n * - if \"pending\" was not expected, maybe the client needs to `wait` for the request to complete?\n */\nexport const isPending = (status: HttpOrCommunicationStatus | null | undefined): boolean => !!(status && getCommunicationStatus(status) === pending);\n\n/**\n * Returns true if the request timed out\n *\n * Client Can Automatically:\n * - notify the user that the request timed out\n * - try again (automatically or via user action)\n *\n * Client Developer Can:\n * - extend the timeoutFailure duration\n *\n * Server Developer Can:\n * - improve server performance and reliability\n */\nexport const isTimeout = (status: HttpOrCommunicationStatus | null | undefined): boolean => !!(status && getCommunicationStatus(status) === timeoutFailure);\n\n/**\n * Returns true if client can safely retry the request\n *\n * A a clearly-retryable failure:\n *\n * - network failure\n * - timeoutFailure\n * - aborted\n *\n * Note: some serverFailures will succeed on retry, but HTTP doesn't return clear indications which ones. To be safe, the client should not retry serverFailures indiscriminately.\n *\n * Client and Server Devs can\n * - investigate network, client and server performance and reliability issues\n */\nexport const isRetryableFailure = (status: HttpOrCommunicationStatus | null | undefined): boolean => {\n if (!status) return false;\n const { status: communicationStatus, failure } = getCommunicationStatusDetails(status);\n return !!(failure && (communicationStatus === networkFailure || communicationStatus === timeoutFailure || communicationStatus === aborted));\n};\n\n/**\n * Returns true if the status is a valid communication status\n */\nexport const isStatusValid = (status: string | null | undefined): boolean => !!(isString(status) && statusRegex.test(status));\n\nexport const isDisabled = (status: HttpOrCommunicationStatus | null | undefined): boolean => !!(status && getCommunicationStatus(status) === disabled);\n","import { clientFailure, clientFailureNotAuthorized, disabled, missing, networkFailure, serverFailure, success } from './CommunicationStatusConsts';\nimport { isStatusValid } from './CommunicationStatusTests';\nimport { CommunicationStatus, CommunicationStatusDetails, communicationStatuses, UnknownCommunicationStatusDetails } from './CommunicationStatusTypes';\n\n//***************************************************************************************************************\n// Private Helpers\n//***************************************************************************************************************\nconst getCommunicationStatusFromHttpStatusOrUndefined = (httpStatus: number): CommunicationStatus | undefined => {\n if (httpStatus === 0) return disabled;\n switch (Math.floor(httpStatus / 100)) {\n case 2: return success;\n case 3: return missing;\n case 4:\n switch (httpStatus) {\n case 401:\n case 403:\n case 407:\n case 451: return clientFailureNotAuthorized;\n case 404: return missing;\n default: return clientFailure;\n }\n case 5:\n switch (httpStatus) {\n case 502:\n case 503:\n case 504: return networkFailure;\n case 511: return clientFailureNotAuthorized;\n case 501: return missing; // 501 Not Implemented - i.e. it \"does not exist\" currently - i.e. missing\n case 505: // HTTP Version Not Supported - client should change the request\n case 530: return clientFailure;\n default: return serverFailure;\n }\n }\n return undefined;\n};\n\nconst getCommunicationStatusFromHttpStatus = (httpStatus: number): CommunicationStatus => {\n const status = getCommunicationStatusFromHttpStatusOrUndefined(httpStatus);\n if (!status) {\n throw new Error(`httpStatus ${httpStatus} is not a supported CommunicationStatus.`);\n }\n return status;\n};\n\n//***************************************************************************************************************\n// Public Functions\n//***************************************************************************************************************\nexport const getCommunicationStatusOrUndefined = <T extends number | CommunicationStatus | null | undefined>(\n status: T\n): T extends null | undefined ? undefined : (CommunicationStatus | undefined) => {\n if (status == null) return undefined as any;\n if (typeof status === 'string') {\n if (!isStatusValid(status)) {\n return undefined;\n }\n return status as any;\n }\n if (typeof status === 'number') {\n return getCommunicationStatusFromHttpStatusOrUndefined(status) as any;\n }\n return undefined;\n};\n\n/*\n * Returns the CommunicationStatus for a given CommunicationStatus or number\n * If the input is null or undefined, returns undefined, otherwise throws an error if the CommunicationStatus or number is not supported\n * @param status - The CommunicationStatus or number to get the CommunicationStatus for\n * @returns The CommunicationStatus for the given CommunicationStatus or number\n */\nexport const getCommunicationStatus = <T extends number | CommunicationStatus | null | undefined>(\n status: T\n): T extends null | undefined ? undefined : CommunicationStatus => {\n if (status == null) return undefined as any;\n if (typeof status === 'number') {\n return getCommunicationStatusFromHttpStatus(status) as any;\n }\n const communicationStatus: CommunicationStatus | undefined = getCommunicationStatusOrUndefined(status);\n if (!communicationStatus) {\n throw new Error(`${status} is not a valid CommunicationStatus.`);\n }\n return communicationStatus as any;\n};\n\n/**\n * Returns the HTTP status code for a given CommunicationStatus or number\n * If the input is null or undefined, returns undefined, otherwise throws an error if the CommunicationStatus or number is not supported\n * @param status - The CommunicationStatus or number to get the HTTP status code for\n * @returns The HTTP status code for the given CommunicationStatus or number\n */\nexport const getHttpStatus = <T extends CommunicationStatus | number | null | undefined>(status: T): T extends null | undefined ? undefined : number => {\n if (status == null) return undefined as any;\n const communicationStatus = getCommunicationStatus(status);\n const httpStatus = communicationStatuses[communicationStatus].httpStatus;\n if (httpStatus == null) {\n throw new Error(`There is no valid HttpStatus for ${status}.`);\n }\n return httpStatus as any;\n};\n\n/**\n * Returns CommunicationStatusDetails {status, httpStatus, message} given an HTTP status code\n *\n * Never throws - returns UnknownCommunicationStatusDetails for invalid inputs\n *\n * @param status - The HTTP status code to get the communication status for\n * @returns The CommunicationStatusDetails for the given status. Note, if an HTTP status is given, it won't necessarily be the httpStatus returned; HTTPStatuses are simplified along with CommunicationStatuses.\n */\nexport function getCommunicationStatusDetails(status: null | undefined): undefined;\nexport function getCommunicationStatusDetails(status: number | CommunicationStatus): CommunicationStatusDetails;\nexport function getCommunicationStatusDetails(status: number | CommunicationStatus | null | undefined): CommunicationStatusDetails | undefined {\n if (status == null) return undefined;\n\n try {\n const communicationStatus = getCommunicationStatus(status);\n const details: CommunicationStatusDetails = communicationStatuses[communicationStatus] ?? UnknownCommunicationStatusDetails;\n return details;\n } catch {\n return UnknownCommunicationStatusDetails;\n }\n}\n\nexport function getCommunicationStatusDetailsOrUndefined(status: null | undefined): undefined;\nexport function getCommunicationStatusDetailsOrUndefined(status: number | CommunicationStatus): CommunicationStatusDetails | undefined;\nexport function getCommunicationStatusDetailsOrUndefined(status: number | CommunicationStatus | null | undefined): CommunicationStatusDetails | undefined {\n if (status == null) return undefined;\n const communicationStatus = getCommunicationStatusOrUndefined(status);\n if (communicationStatus == null) return undefined;\n const details: CommunicationStatusDetails | undefined = communicationStatuses[communicationStatus];\n return details;\n}\n"],"mappings":"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","names":["failure"]}
|