@art-suite/art-core-ts-communication-status 0.5.0 → 0.7.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 CHANGED
@@ -168,37 +168,52 @@ var object = ((source, withOrOptions) => invokeNormalizedIteration(normalizedObj
168
168
 
169
169
  // src/CommunicationStatusTypes.ts
170
170
  var communicationStatusesPartials = {
171
+ // HTTP Success Statuses
171
172
  success: { httpStatus: 200 },
173
+ // HTTP Failure Statuses
172
174
  missing: { httpStatus: 404, failure: true },
173
175
  clientFailure: { httpStatus: 400, clientFailure: true, failure: true },
174
176
  clientFailureNotAuthorized: { httpStatus: 403, clientFailure: true, failure: true },
175
177
  serverFailure: { httpStatus: 500, failure: true, serverFailure: true },
178
+ failure: { httpStatus: 500, failure: true },
179
+ // Non-HTTP Statuses
180
+ pending: { httpStatus: void 0 },
176
181
  networkFailure: { httpStatus: void 0, failure: true },
177
182
  aborted: { httpStatus: void 0, failure: true },
178
- pending: { httpStatus: void 0 },
179
- failure: { httpStatus: 500, failure: true },
180
183
  timeoutFailure: { httpStatus: void 0, failure: true }
181
184
  };
182
185
  var communicationStatuses = object(communicationStatusesPartials, (details, status) => ({
183
186
  ...details,
187
+ failure: !!details.failure,
188
+ clientFailure: !!details.clientFailure,
189
+ serverFailure: !!details.serverFailure,
184
190
  status,
191
+ communicationStatus: status,
185
192
  message: details.httpStatus ? `${status} (${details.httpStatus})` : status
186
193
  }));
187
194
  var statusRegex = new RegExp(`^(${Object.keys(communicationStatuses).join("|")})$`);
188
195
 
189
196
  // src/CommunicationStatusTests.ts
190
- var isSuccess = (status) => getCommunicationStatusOrUndefined(status) === success;
191
- var isFailure = (status) => !!communicationStatuses[status]?.failure;
192
- var isClientFailure = (status) => !!communicationStatuses[status]?.clientFailure;
193
- var isServerFailure = (status) => !!communicationStatuses[status]?.serverFailure;
194
- var isNetworkFailure = (status) => status === networkFailure;
195
- var isNonClientFailure = (status) => isFailure(status) && !isClientFailure(status);
196
- var isClientFailureNotAuthorized = (status) => status === clientFailureNotAuthorized;
197
- var isAborted = (status) => status === aborted;
198
- var isMissing = (status) => status === missing;
199
- var isPending = (status) => status === pending;
200
- var isTimeout = (status) => status === timeoutFailure;
201
- var isRetryableFailure = (status) => isNetworkFailure(status) || isTimeout(status) || isAborted(status);
197
+ 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;
202
+ var isNonClientFailure = (status) => {
203
+ if (!status) return false;
204
+ const details = getCommunicationStatusDetails(status);
205
+ return details.failure && !details.clientFailure;
206
+ };
207
+ 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;
212
+ var isRetryableFailure = (status) => {
213
+ if (!status) return false;
214
+ const { status: communicationStatus, failure: failure2 } = getCommunicationStatusDetails(status);
215
+ return failure2 && (communicationStatus === networkFailure || communicationStatus === timeoutFailure || communicationStatus === aborted);
216
+ };
202
217
  var isStatusValid = (status) => statusRegex.test(status);
203
218
 
204
219
  // src/CommunicationStatusConversions.ts
@@ -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';\nexport interface CommunicationStatusDetails {\n httpStatus?: number;\n failure?: boolean;\n clientFailure?: boolean;\n serverFailure?: boolean;\n status: CommunicationStatus;\n message: string;\n}\n\nconst communicationStatusesPartials = {\n success: { httpStatus: 200 },\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 networkFailure: { httpStatus: undefined, failure: true },\n aborted: { httpStatus: undefined, failure: true },\n pending: { httpStatus: undefined },\n failure: { httpStatus: 500, failure: true },\n timeoutFailure: { httpStatus: undefined, failure: true }\n};\n\nexport type CommunicationStatus = keyof typeof communicationStatusesPartials;\n\nexport const communicationStatuses: Record<CommunicationStatus, CommunicationStatusDetails> = object(communicationStatusesPartials, (details, status) => ({\n ...details,\n status: 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 { getCommunicationStatusOrUndefined } from './CommunicationStatusConversions';\nimport { CommunicationStatus, communicationStatuses, statusRegex } from './CommunicationStatusTypes';\n\n// Core status check functions\n/** Returns true for HTTP 2xx responses */\nexport const isSuccess = (status: CommunicationStatus | number) => getCommunicationStatusOrUndefined(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: CommunicationStatus) => !!communicationStatuses[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: CommunicationStatus) => !!communicationStatuses[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: CommunicationStatus) => !!communicationStatuses[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: CommunicationStatus) => 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: CommunicationStatus) => isFailure(status) && !isClientFailure(status);\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: CommunicationStatus) => 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: CommunicationStatus) => 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: CommunicationStatus) => 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: CommunicationStatus) => 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: CommunicationStatus) => 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: CommunicationStatus) => isNetworkFailure(status) || isTimeout(status) || isAborted(status);\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":[]}
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"]}
package/dist/index.d.cts CHANGED
@@ -1,11 +1,3 @@
1
- interface CommunicationStatusDetails {
2
- httpStatus?: number;
3
- failure?: boolean;
4
- clientFailure?: boolean;
5
- serverFailure?: boolean;
6
- status: CommunicationStatus;
7
- message: string;
8
- }
9
1
  declare const communicationStatusesPartials: {
10
2
  success: {
11
3
  httpStatus: number;
@@ -29,19 +21,19 @@ declare const communicationStatusesPartials: {
29
21
  failure: boolean;
30
22
  serverFailure: boolean;
31
23
  };
32
- networkFailure: {
33
- httpStatus: undefined;
24
+ failure: {
25
+ httpStatus: number;
34
26
  failure: boolean;
35
27
  };
36
- aborted: {
28
+ pending: {
37
29
  httpStatus: undefined;
38
- failure: boolean;
39
30
  };
40
- pending: {
31
+ networkFailure: {
41
32
  httpStatus: undefined;
33
+ failure: boolean;
42
34
  };
43
- failure: {
44
- httpStatus: number;
35
+ aborted: {
36
+ httpStatus: undefined;
45
37
  failure: boolean;
46
38
  };
47
39
  timeoutFailure: {
@@ -49,7 +41,31 @@ declare const communicationStatusesPartials: {
49
41
  failure: boolean;
50
42
  };
51
43
  };
44
+ /**
45
+ * The core of Art-core-ts-communication-status: A simplified set of statuses as a human-readable and machine-interpretable string
46
+ * representing all the possible communication statuses that are pragmatically actionable.
47
+ */
52
48
  type CommunicationStatus = keyof typeof communicationStatusesPartials;
49
+ type HttpOrCommunicationStatus = CommunicationStatus | number;
50
+ /**
51
+ * Details about a communication status
52
+ *
53
+ * @param httpStatus - The HTTP status code for the communication status
54
+ * @param failure - Whether the communication status is a failure
55
+ * @param clientFailure - Whether the communication status is a client failure
56
+ * @param serverFailure - Whether the communication status is a server failure
57
+ * @param status - The communication status - alias for communicationStatus
58
+ * @param communicationStatus - The communication status
59
+ */
60
+ interface CommunicationStatusDetails {
61
+ httpStatus?: number;
62
+ failure?: boolean;
63
+ clientFailure?: boolean;
64
+ serverFailure?: boolean;
65
+ status: CommunicationStatus;
66
+ communicationStatus: CommunicationStatus;
67
+ message: string;
68
+ }
53
69
  declare const communicationStatuses: Record<CommunicationStatus, CommunicationStatusDetails>;
54
70
  type CommunicationStatuses = typeof communicationStatuses;
55
71
  /**
@@ -236,7 +252,7 @@ declare const getCommunicationStatusDetails: <T extends number | CommunicationSt
236
252
  declare const getCommunicationStatusDetailsOrUndefined: <T extends number | CommunicationStatus | null | undefined>(status: T) => T extends null | undefined ? undefined : (CommunicationStatusDetails | undefined);
237
253
 
238
254
  /** Returns true for HTTP 2xx responses */
239
- declare const isSuccess: (status: CommunicationStatus | number) => boolean;
255
+ declare const isSuccess: (status: HttpOrCommunicationStatus | null | undefined) => boolean;
240
256
  /**
241
257
  * Returns true for any error response (HTTP 4xx/5xx) or network/abort failures
242
258
  *
@@ -249,7 +265,7 @@ declare const isSuccess: (status: CommunicationStatus | number) => boolean;
249
265
  * Client Can:
250
266
  * - Use a different is* function for more specific checks
251
267
  */
252
- declare const isFailure: (status: CommunicationStatus) => boolean;
268
+ declare const isFailure: (status: HttpOrCommunicationStatus | null | undefined) => boolean | undefined;
253
269
  /**
254
270
  * Returns true for client-side errors
255
271
  *
@@ -268,7 +284,7 @@ declare const isFailure: (status: CommunicationStatus) => boolean;
268
284
  * - use isClientFailureNotAuthorized to check for 401/403/407/451
269
285
  * - fix the request to avoid the 4xx error
270
286
  */
271
- declare const isClientFailure: (status: CommunicationStatus) => boolean;
287
+ declare const isClientFailure: (status: HttpOrCommunicationStatus | null | undefined) => boolean | undefined;
272
288
  /**
273
289
  * Returns true for server-side errors
274
290
  *
@@ -288,7 +304,7 @@ declare const isClientFailure: (status: CommunicationStatus) => boolean;
288
304
  * - fix the server to avoid the 5xx error
289
305
  * - fix server infrastructure to avoid the 5xx error (e.g. Bad Gateway, Service Unavailable, Gateway Timeout)
290
306
  */
291
- declare const isServerFailure: (status: CommunicationStatus) => boolean;
307
+ declare const isServerFailure: (status: HttpOrCommunicationStatus | null | undefined) => boolean | undefined;
292
308
  /**
293
309
  * Returns true when request fails due to network connectivity issues
294
310
  *
@@ -301,9 +317,9 @@ declare const isServerFailure: (status: CommunicationStatus) => boolean;
301
317
  * Client Developer Can:
302
318
  * - fix bad network constants (like address, ports, etc.)
303
319
  */
304
- declare const isNetworkFailure: (status: CommunicationStatus) => boolean;
320
+ declare const isNetworkFailure: (status: HttpOrCommunicationStatus | null | undefined) => boolean;
305
321
  /** 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 */
306
- declare const isNonClientFailure: (status: CommunicationStatus) => boolean;
322
+ declare const isNonClientFailure: (status: HttpOrCommunicationStatus | null | undefined) => boolean | undefined;
307
323
  /**
308
324
  * Returns true for unauthorized requests (not authenticated or not authorized)
309
325
  *
@@ -322,7 +338,7 @@ declare const isNonClientFailure: (status: CommunicationStatus) => boolean;
322
338
  * Client and Server Developer Can:
323
339
  * - fix authorization / authentication bugs
324
340
  */
325
- declare const isClientFailureNotAuthorized: (status: CommunicationStatus) => boolean;
341
+ declare const isClientFailureNotAuthorized: (status: HttpOrCommunicationStatus | null | undefined) => boolean;
326
342
  /**
327
343
  * Returns true when request was cancelled by client
328
344
  *
@@ -333,7 +349,7 @@ declare const isClientFailureNotAuthorized: (status: CommunicationStatus) => boo
333
349
  * Client Developer Can:
334
350
  * - fix the client to not abort the request
335
351
  */
336
- declare const isAborted: (status: CommunicationStatus) => boolean;
352
+ declare const isAborted: (status: HttpOrCommunicationStatus | null | undefined) => boolean;
337
353
  /**
338
354
  * Returns true when resource not found / not available
339
355
  *
@@ -348,7 +364,7 @@ declare const isAborted: (status: CommunicationStatus) => boolean;
348
364
  * Client Developer Can:
349
365
  * - fix the bad resource paths
350
366
  */
351
- declare const isMissing: (status: CommunicationStatus) => boolean;
367
+ declare const isMissing: (status: HttpOrCommunicationStatus | null | undefined) => boolean;
352
368
  /**
353
369
  * Returns true while request is in progress
354
370
  *
@@ -360,7 +376,7 @@ declare const isMissing: (status: CommunicationStatus) => boolean;
360
376
  * Client Developer Can:
361
377
  * - if "pending" was not expected, maybe the client needs to `wait` for the request to complete?
362
378
  */
363
- declare const isPending: (status: CommunicationStatus) => boolean;
379
+ declare const isPending: (status: HttpOrCommunicationStatus | null | undefined) => boolean;
364
380
  /**
365
381
  * Returns true if the request timed out
366
382
  *
@@ -374,7 +390,7 @@ declare const isPending: (status: CommunicationStatus) => boolean;
374
390
  * Server Developer Can:
375
391
  * - improve server performance and reliability
376
392
  */
377
- declare const isTimeout: (status: CommunicationStatus) => boolean;
393
+ declare const isTimeout: (status: HttpOrCommunicationStatus | null | undefined) => boolean;
378
394
  /**
379
395
  * Returns true if client can safely retry the request
380
396
  *
@@ -389,10 +405,10 @@ declare const isTimeout: (status: CommunicationStatus) => boolean;
389
405
  * Client and Server Devs can
390
406
  * - investigate network, client and server performance and reliability issues
391
407
  */
392
- declare const isRetryableFailure: (status: CommunicationStatus) => boolean;
408
+ declare const isRetryableFailure: (status: HttpOrCommunicationStatus | null | undefined) => boolean | undefined;
393
409
  /**
394
410
  * Returns true if the status is a valid communication status
395
411
  */
396
412
  declare const isStatusValid: (status: string) => boolean;
397
413
 
398
- export { type CommunicationStatus, type CommunicationStatusDetails, type CommunicationStatuses, 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 };
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 };
package/dist/index.d.ts CHANGED
@@ -1,11 +1,3 @@
1
- interface CommunicationStatusDetails {
2
- httpStatus?: number;
3
- failure?: boolean;
4
- clientFailure?: boolean;
5
- serverFailure?: boolean;
6
- status: CommunicationStatus;
7
- message: string;
8
- }
9
1
  declare const communicationStatusesPartials: {
10
2
  success: {
11
3
  httpStatus: number;
@@ -29,19 +21,19 @@ declare const communicationStatusesPartials: {
29
21
  failure: boolean;
30
22
  serverFailure: boolean;
31
23
  };
32
- networkFailure: {
33
- httpStatus: undefined;
24
+ failure: {
25
+ httpStatus: number;
34
26
  failure: boolean;
35
27
  };
36
- aborted: {
28
+ pending: {
37
29
  httpStatus: undefined;
38
- failure: boolean;
39
30
  };
40
- pending: {
31
+ networkFailure: {
41
32
  httpStatus: undefined;
33
+ failure: boolean;
42
34
  };
43
- failure: {
44
- httpStatus: number;
35
+ aborted: {
36
+ httpStatus: undefined;
45
37
  failure: boolean;
46
38
  };
47
39
  timeoutFailure: {
@@ -49,7 +41,31 @@ declare const communicationStatusesPartials: {
49
41
  failure: boolean;
50
42
  };
51
43
  };
44
+ /**
45
+ * The core of Art-core-ts-communication-status: A simplified set of statuses as a human-readable and machine-interpretable string
46
+ * representing all the possible communication statuses that are pragmatically actionable.
47
+ */
52
48
  type CommunicationStatus = keyof typeof communicationStatusesPartials;
49
+ type HttpOrCommunicationStatus = CommunicationStatus | number;
50
+ /**
51
+ * Details about a communication status
52
+ *
53
+ * @param httpStatus - The HTTP status code for the communication status
54
+ * @param failure - Whether the communication status is a failure
55
+ * @param clientFailure - Whether the communication status is a client failure
56
+ * @param serverFailure - Whether the communication status is a server failure
57
+ * @param status - The communication status - alias for communicationStatus
58
+ * @param communicationStatus - The communication status
59
+ */
60
+ interface CommunicationStatusDetails {
61
+ httpStatus?: number;
62
+ failure?: boolean;
63
+ clientFailure?: boolean;
64
+ serverFailure?: boolean;
65
+ status: CommunicationStatus;
66
+ communicationStatus: CommunicationStatus;
67
+ message: string;
68
+ }
53
69
  declare const communicationStatuses: Record<CommunicationStatus, CommunicationStatusDetails>;
54
70
  type CommunicationStatuses = typeof communicationStatuses;
55
71
  /**
@@ -236,7 +252,7 @@ declare const getCommunicationStatusDetails: <T extends number | CommunicationSt
236
252
  declare const getCommunicationStatusDetailsOrUndefined: <T extends number | CommunicationStatus | null | undefined>(status: T) => T extends null | undefined ? undefined : (CommunicationStatusDetails | undefined);
237
253
 
238
254
  /** Returns true for HTTP 2xx responses */
239
- declare const isSuccess: (status: CommunicationStatus | number) => boolean;
255
+ declare const isSuccess: (status: HttpOrCommunicationStatus | null | undefined) => boolean;
240
256
  /**
241
257
  * Returns true for any error response (HTTP 4xx/5xx) or network/abort failures
242
258
  *
@@ -249,7 +265,7 @@ declare const isSuccess: (status: CommunicationStatus | number) => boolean;
249
265
  * Client Can:
250
266
  * - Use a different is* function for more specific checks
251
267
  */
252
- declare const isFailure: (status: CommunicationStatus) => boolean;
268
+ declare const isFailure: (status: HttpOrCommunicationStatus | null | undefined) => boolean | undefined;
253
269
  /**
254
270
  * Returns true for client-side errors
255
271
  *
@@ -268,7 +284,7 @@ declare const isFailure: (status: CommunicationStatus) => boolean;
268
284
  * - use isClientFailureNotAuthorized to check for 401/403/407/451
269
285
  * - fix the request to avoid the 4xx error
270
286
  */
271
- declare const isClientFailure: (status: CommunicationStatus) => boolean;
287
+ declare const isClientFailure: (status: HttpOrCommunicationStatus | null | undefined) => boolean | undefined;
272
288
  /**
273
289
  * Returns true for server-side errors
274
290
  *
@@ -288,7 +304,7 @@ declare const isClientFailure: (status: CommunicationStatus) => boolean;
288
304
  * - fix the server to avoid the 5xx error
289
305
  * - fix server infrastructure to avoid the 5xx error (e.g. Bad Gateway, Service Unavailable, Gateway Timeout)
290
306
  */
291
- declare const isServerFailure: (status: CommunicationStatus) => boolean;
307
+ declare const isServerFailure: (status: HttpOrCommunicationStatus | null | undefined) => boolean | undefined;
292
308
  /**
293
309
  * Returns true when request fails due to network connectivity issues
294
310
  *
@@ -301,9 +317,9 @@ declare const isServerFailure: (status: CommunicationStatus) => boolean;
301
317
  * Client Developer Can:
302
318
  * - fix bad network constants (like address, ports, etc.)
303
319
  */
304
- declare const isNetworkFailure: (status: CommunicationStatus) => boolean;
320
+ declare const isNetworkFailure: (status: HttpOrCommunicationStatus | null | undefined) => boolean;
305
321
  /** 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 */
306
- declare const isNonClientFailure: (status: CommunicationStatus) => boolean;
322
+ declare const isNonClientFailure: (status: HttpOrCommunicationStatus | null | undefined) => boolean | undefined;
307
323
  /**
308
324
  * Returns true for unauthorized requests (not authenticated or not authorized)
309
325
  *
@@ -322,7 +338,7 @@ declare const isNonClientFailure: (status: CommunicationStatus) => boolean;
322
338
  * Client and Server Developer Can:
323
339
  * - fix authorization / authentication bugs
324
340
  */
325
- declare const isClientFailureNotAuthorized: (status: CommunicationStatus) => boolean;
341
+ declare const isClientFailureNotAuthorized: (status: HttpOrCommunicationStatus | null | undefined) => boolean;
326
342
  /**
327
343
  * Returns true when request was cancelled by client
328
344
  *
@@ -333,7 +349,7 @@ declare const isClientFailureNotAuthorized: (status: CommunicationStatus) => boo
333
349
  * Client Developer Can:
334
350
  * - fix the client to not abort the request
335
351
  */
336
- declare const isAborted: (status: CommunicationStatus) => boolean;
352
+ declare const isAborted: (status: HttpOrCommunicationStatus | null | undefined) => boolean;
337
353
  /**
338
354
  * Returns true when resource not found / not available
339
355
  *
@@ -348,7 +364,7 @@ declare const isAborted: (status: CommunicationStatus) => boolean;
348
364
  * Client Developer Can:
349
365
  * - fix the bad resource paths
350
366
  */
351
- declare const isMissing: (status: CommunicationStatus) => boolean;
367
+ declare const isMissing: (status: HttpOrCommunicationStatus | null | undefined) => boolean;
352
368
  /**
353
369
  * Returns true while request is in progress
354
370
  *
@@ -360,7 +376,7 @@ declare const isMissing: (status: CommunicationStatus) => boolean;
360
376
  * Client Developer Can:
361
377
  * - if "pending" was not expected, maybe the client needs to `wait` for the request to complete?
362
378
  */
363
- declare const isPending: (status: CommunicationStatus) => boolean;
379
+ declare const isPending: (status: HttpOrCommunicationStatus | null | undefined) => boolean;
364
380
  /**
365
381
  * Returns true if the request timed out
366
382
  *
@@ -374,7 +390,7 @@ declare const isPending: (status: CommunicationStatus) => boolean;
374
390
  * Server Developer Can:
375
391
  * - improve server performance and reliability
376
392
  */
377
- declare const isTimeout: (status: CommunicationStatus) => boolean;
393
+ declare const isTimeout: (status: HttpOrCommunicationStatus | null | undefined) => boolean;
378
394
  /**
379
395
  * Returns true if client can safely retry the request
380
396
  *
@@ -389,10 +405,10 @@ declare const isTimeout: (status: CommunicationStatus) => boolean;
389
405
  * Client and Server Devs can
390
406
  * - investigate network, client and server performance and reliability issues
391
407
  */
392
- declare const isRetryableFailure: (status: CommunicationStatus) => boolean;
408
+ declare const isRetryableFailure: (status: HttpOrCommunicationStatus | null | undefined) => boolean | undefined;
393
409
  /**
394
410
  * Returns true if the status is a valid communication status
395
411
  */
396
412
  declare const isStatusValid: (status: string) => boolean;
397
413
 
398
- export { type CommunicationStatus, type CommunicationStatusDetails, type CommunicationStatuses, 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 };
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 };
package/dist/index.js CHANGED
@@ -113,37 +113,52 @@ var object = ((source, withOrOptions) => invokeNormalizedIteration(normalizedObj
113
113
 
114
114
  // src/CommunicationStatusTypes.ts
115
115
  var communicationStatusesPartials = {
116
+ // HTTP Success Statuses
116
117
  success: { httpStatus: 200 },
118
+ // HTTP Failure Statuses
117
119
  missing: { httpStatus: 404, failure: true },
118
120
  clientFailure: { httpStatus: 400, clientFailure: true, failure: true },
119
121
  clientFailureNotAuthorized: { httpStatus: 403, clientFailure: true, failure: true },
120
122
  serverFailure: { httpStatus: 500, failure: true, serverFailure: true },
123
+ failure: { httpStatus: 500, failure: true },
124
+ // Non-HTTP Statuses
125
+ pending: { httpStatus: void 0 },
121
126
  networkFailure: { httpStatus: void 0, failure: true },
122
127
  aborted: { httpStatus: void 0, failure: true },
123
- pending: { httpStatus: void 0 },
124
- failure: { httpStatus: 500, failure: true },
125
128
  timeoutFailure: { httpStatus: void 0, failure: true }
126
129
  };
127
130
  var communicationStatuses = object(communicationStatusesPartials, (details, status) => ({
128
131
  ...details,
132
+ failure: !!details.failure,
133
+ clientFailure: !!details.clientFailure,
134
+ serverFailure: !!details.serverFailure,
129
135
  status,
136
+ communicationStatus: status,
130
137
  message: details.httpStatus ? `${status} (${details.httpStatus})` : status
131
138
  }));
132
139
  var statusRegex = new RegExp(`^(${Object.keys(communicationStatuses).join("|")})$`);
133
140
 
134
141
  // src/CommunicationStatusTests.ts
135
- var isSuccess = (status) => getCommunicationStatusOrUndefined(status) === success;
136
- var isFailure = (status) => !!communicationStatuses[status]?.failure;
137
- var isClientFailure = (status) => !!communicationStatuses[status]?.clientFailure;
138
- var isServerFailure = (status) => !!communicationStatuses[status]?.serverFailure;
139
- var isNetworkFailure = (status) => status === networkFailure;
140
- var isNonClientFailure = (status) => isFailure(status) && !isClientFailure(status);
141
- var isClientFailureNotAuthorized = (status) => status === clientFailureNotAuthorized;
142
- var isAborted = (status) => status === aborted;
143
- var isMissing = (status) => status === missing;
144
- var isPending = (status) => status === pending;
145
- var isTimeout = (status) => status === timeoutFailure;
146
- var isRetryableFailure = (status) => isNetworkFailure(status) || isTimeout(status) || isAborted(status);
142
+ 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;
147
+ var isNonClientFailure = (status) => {
148
+ if (!status) return false;
149
+ const details = getCommunicationStatusDetails(status);
150
+ return details.failure && !details.clientFailure;
151
+ };
152
+ 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;
157
+ var isRetryableFailure = (status) => {
158
+ if (!status) return false;
159
+ const { status: communicationStatus, failure: failure2 } = getCommunicationStatusDetails(status);
160
+ return failure2 && (communicationStatus === networkFailure || communicationStatus === timeoutFailure || communicationStatus === aborted);
161
+ };
147
162
  var isStatusValid = (status) => statusRegex.test(status);
148
163
 
149
164
  // src/CommunicationStatusConversions.ts
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';\nexport interface CommunicationStatusDetails {\n httpStatus?: number;\n failure?: boolean;\n clientFailure?: boolean;\n serverFailure?: boolean;\n status: CommunicationStatus;\n message: string;\n}\n\nconst communicationStatusesPartials = {\n success: { httpStatus: 200 },\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 networkFailure: { httpStatus: undefined, failure: true },\n aborted: { httpStatus: undefined, failure: true },\n pending: { httpStatus: undefined },\n failure: { httpStatus: 500, failure: true },\n timeoutFailure: { httpStatus: undefined, failure: true }\n};\n\nexport type CommunicationStatus = keyof typeof communicationStatusesPartials;\n\nexport const communicationStatuses: Record<CommunicationStatus, CommunicationStatusDetails> = object(communicationStatusesPartials, (details, status) => ({\n ...details,\n status: 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 { getCommunicationStatusOrUndefined } from './CommunicationStatusConversions';\nimport { CommunicationStatus, communicationStatuses, statusRegex } from './CommunicationStatusTypes';\n\n// Core status check functions\n/** Returns true for HTTP 2xx responses */\nexport const isSuccess = (status: CommunicationStatus | number) => getCommunicationStatusOrUndefined(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: CommunicationStatus) => !!communicationStatuses[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: CommunicationStatus) => !!communicationStatuses[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: CommunicationStatus) => !!communicationStatuses[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: CommunicationStatus) => 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: CommunicationStatus) => isFailure(status) && !isClientFailure(status);\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: CommunicationStatus) => 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: CommunicationStatus) => 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: CommunicationStatus) => 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: CommunicationStatus) => 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: CommunicationStatus) => 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: CommunicationStatus) => isNetworkFailure(status) || isTimeout(status) || isAborted(status);\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":[]}
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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@art-suite/art-core-ts-communication-status",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "description": "A TypeScript string utility library",
5
5
  "keywords": [],
6
6
  "repository": {