summaryrefslogtreecommitdiff
path: root/node_modules/@jet-app/app-store/tmp/src/foundation/util
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/@jet-app/app-store/tmp/src/foundation/util')
-rw-r--r--node_modules/@jet-app/app-store/tmp/src/foundation/util/array-util.js32
-rw-r--r--node_modules/@jet-app/app-store/tmp/src/foundation/util/color-util.js231
-rw-r--r--node_modules/@jet-app/app-store/tmp/src/foundation/util/constants.js26
-rw-r--r--node_modules/@jet-app/app-store/tmp/src/foundation/util/date-util.js127
-rw-r--r--node_modules/@jet-app/app-store/tmp/src/foundation/util/errors.js13
-rw-r--r--node_modules/@jet-app/app-store/tmp/src/foundation/util/math-util.js32
-rw-r--r--node_modules/@jet-app/app-store/tmp/src/foundation/util/objects.js33
-rw-r--r--node_modules/@jet-app/app-store/tmp/src/foundation/util/promise-util.js215
-rw-r--r--node_modules/@jet-app/app-store/tmp/src/foundation/util/string-util.js127
-rw-r--r--node_modules/@jet-app/app-store/tmp/src/foundation/util/validation-util.js30
10 files changed, 866 insertions, 0 deletions
diff --git a/node_modules/@jet-app/app-store/tmp/src/foundation/util/array-util.js b/node_modules/@jet-app/app-store/tmp/src/foundation/util/array-util.js
new file mode 100644
index 0000000..57c8e84
--- /dev/null
+++ b/node_modules/@jet-app/app-store/tmp/src/foundation/util/array-util.js
@@ -0,0 +1,32 @@
+/**
+ * Creates an array containing multiple copies of the elements of another array.
+ *
+ * For example, if A = [Q, W, E, R, T, Y], then calling repeating(A, 3) would return
+ * [Q, W, E, R, T, Y, Q, W, E, R, T, Y, Q, W, E, R, T, Y]
+ *
+ * @param elements The elements that will be repeated
+ * @param times The number of times all of the elements should appear in the new array.
+ */
+export function arrayByRepeating(elements, times) {
+ if (times <= 0) {
+ return [];
+ }
+ let newArray = [];
+ for (let i = 0; i < times; i++) {
+ newArray = newArray.concat(elements);
+ }
+ return newArray;
+}
+export function partition(array, predicate) {
+ const part1 = [];
+ const part2 = [];
+ array.forEach((item) => (predicate(item) ? part1.push(item) : part2.push(item)));
+ return [part1, part2];
+}
+export function isEmpty(elements) {
+ return elements.length === 0;
+}
+export function isNotEmpty(elements) {
+ return !isEmpty(elements);
+}
+//# sourceMappingURL=array-util.js.map \ No newline at end of file
diff --git a/node_modules/@jet-app/app-store/tmp/src/foundation/util/color-util.js b/node_modules/@jet-app/app-store/tmp/src/foundation/util/color-util.js
new file mode 100644
index 0000000..84e3815
--- /dev/null
+++ b/node_modules/@jet-app/app-store/tmp/src/foundation/util/color-util.js
@@ -0,0 +1,231 @@
+import { isNothing, isSome } from "@jet/environment/types/optional";
+const HEX_PARSER = new RegExp("#?([0-9,a-f,A-F][0-9,a-f,A-F])([0-9,a-f,A-F][0-9,a-f,A-F])([0-9,a-f,A-F][0-9,a-f,A-F])([0-9,a-f,A-F][0-9,a-f,A-F])?");
+export function fromHex(hexString) {
+ if (isNothing(hexString) || hexString === "") {
+ return null;
+ }
+ const results = HEX_PARSER.exec(hexString);
+ if (results === null || !(results.length === 4 || results.length === 5)) {
+ return null;
+ }
+ const red = parseInt(results[1], 16) / 255;
+ const green = parseInt(results[2], 16) / 255;
+ const blue = parseInt(results[3], 16) / 255;
+ const alpha = isSome(results[4]) ? parseInt(results[4], 16) / 255 : undefined;
+ const newColor = {
+ red: red,
+ green: green,
+ blue: blue,
+ alpha: alpha,
+ type: "rgb",
+ };
+ return newColor;
+}
+export const black = rgbWith(0, 0, 0);
+export const white = rgbWith(1, 1, 1);
+export function rgbWith(red, green, blue, alpha) {
+ const newColor = {
+ red: red,
+ green: green,
+ blue: blue,
+ alpha: alpha,
+ type: "rgb",
+ };
+ return newColor;
+}
+export function luminanceFrom(rgbColor) {
+ // Note: This is lifted from UIColor_Private
+ // Using RGB color components, calculates and returns (0.2126 * r) + (0.7152 * g) + (0.0722 * b).
+ return rgbColor.red * 0.2126 + rgbColor.green * 0.7152 + rgbColor.blue * 0.0722;
+}
+/**
+ * Determines whether the given color is considered dark.
+ * @param color The color to test.
+ * @param darkColorCutoff The cutoff value, which ought to be between 0 and 100.
+ */
+export function isDarkColor(color, darkColorCutoff = 84) {
+ if (isNothing(color)) {
+ return false;
+ }
+ switch (color.type) {
+ case "rgb":
+ // Multiplying 100 because the rest of the codebase now works off darkColorCutoff 0-100.
+ // Before this change it used to be darkColorCutoff 0.0-1.0
+ return luminanceFrom(color) * 100 < darkColorCutoff;
+ case "named":
+ return isNamedColorDarkColor(color);
+ default:
+ return false;
+ }
+}
+function isNamedColorDarkColor(namedColor) {
+ switch (namedColor.name) {
+ case "black":
+ return true;
+ default:
+ return false;
+ }
+}
+export function named(name) {
+ const newColor = {
+ name: name,
+ type: "named",
+ };
+ return newColor;
+}
+export function dynamicWith(lightColor, darkColor) {
+ const newColor = {
+ lightColor: lightColor,
+ darkColor: darkColor,
+ type: "dynamic",
+ };
+ return newColor;
+}
+/**
+ * A convenience for comparing two colors to see if they are equal.
+ * @param firstColor The first color to compare
+ * @param secondColor The second color to compare
+ * @returns True if the colors are considered equal
+ */
+export function isColorEqualToColor(firstColor, secondColor) {
+ if (isNothing(firstColor) || isNothing(secondColor)) {
+ return false;
+ }
+ if (firstColor.type === "rgb" && secondColor.type === "rgb") {
+ return (firstColor.red === secondColor.red &&
+ firstColor.green === secondColor.green &&
+ firstColor.blue === secondColor.blue &&
+ firstColor.alpha === secondColor.alpha);
+ }
+ else if (firstColor.type === "named" && secondColor.type === "named") {
+ return firstColor.name === secondColor.name;
+ }
+ else if (firstColor.type === "dynamic" && secondColor.type === "dynamic") {
+ return (isColorEqualToColor(firstColor.lightColor, secondColor.lightColor) &&
+ isColorEqualToColor(firstColor.darkColor, secondColor.darkColor));
+ }
+ return false;
+}
+/**
+ * Type guard to check if a value is a ColorBucketSaturationBrightnessCriteria.
+ * @param value The value to check.
+ * @returns True if the value is a ColorBucketSaturationBrightnessCriteria, false otherwise.
+ */
+function isSaturationBrightnessCriteria(value) {
+ if (typeof value !== "object" || value === null) {
+ return false;
+ }
+ const obj = value; // Cast for easier property access
+ // Check if all required properties exist and have the correct types
+ return ("colorHex" in obj &&
+ typeof obj.colorHex === "string" &&
+ "maxSaturation" in obj &&
+ typeof obj.maxSaturation === "number" &&
+ "maxBrightness" in obj &&
+ typeof obj.maxBrightness === "number");
+}
+/**
+ * Finds the closest matching color from a list of hex colors using LAB color space
+ * for more perceptually accurate matching
+ */
+export function findColorBucketForColor(targetRGB, saturationBrightnessBasedBuckets, hueBasedBuckets) {
+ if (isNothing(targetRGB) || (saturationBrightnessBasedBuckets.length === 0 && hueBasedBuckets.length === 0)) {
+ return null;
+ }
+ const targetColor = targetRGB;
+ if (isNothing(targetColor)) {
+ return null;
+ }
+ const targetHsb = rgbToHsb(targetColor);
+ for (const saturationBrightnessBasedBucket of saturationBrightnessBasedBuckets) {
+ if (doesColorMeetCriteria(targetHsb, saturationBrightnessBasedBucket)) {
+ return fromHex(saturationBrightnessBasedBucket.colorHex);
+ }
+ }
+ for (const hueBasedBucket of hueBasedBuckets) {
+ if (doesColorMeetCriteria(targetHsb, hueBasedBucket)) {
+ return fromHex(hueBasedBucket.colorHex);
+ }
+ }
+ return null;
+}
+/**
+ * Determines whether a color meets the specified criteria.
+ *
+ * For saturation/brightness criteria, the color passes if either its saturation or brightness
+ * is less than or equal to the maximum allowed values.
+ *
+ * For hue criteria, the color passes if its hue falls within the specified range (inclusive).
+ *
+ * @param color The RGB color to evaluate
+ * @param criteria The criteria to check against (either hue-based or saturation/brightness-based)
+ * @returns True if the color passes the criteria, false otherwise or if color is null/undefined
+ */
+export function doesColorMeetCriteria(color, criteria) {
+ if (isNothing(color)) {
+ return false;
+ }
+ const hsbColor = isHSBColor(color) ? color : rgbToHsb(color);
+ // Check saturation / brightness buckets first, using <= for inclusive range checks
+ if (isSaturationBrightnessCriteria(criteria)) {
+ return hsbColor.saturation <= criteria.maxSaturation || hsbColor.brightness <= criteria.maxBrightness;
+ }
+ else {
+ // Check if the hue falls within the min/max bounds (inclusive)
+ // Special handling for the Pink range potentially including 360 if needed,
+ // but mapping 360->0 covers the Coral case correctly.
+ return hsbColor.hue >= criteria.minHue && hsbColor.hue <= criteria.maxHue;
+ }
+}
+function isHSBColor(value) {
+ if (typeof value !== "object" || value === null) {
+ return false;
+ }
+ const obj = value; // Cast for easier property access
+ // Check if the type property exists and has the correct value
+ return "type" in obj && obj.type === "hsb";
+}
+/**
+ * Converts RGB color to HSB color space.
+ * HSL is particularly good at representing relationships between colors
+ * as humans perceive them, especially for determining similar hues
+ * across different brightness levels.
+ */
+function rgbToHsb(rgb) {
+ const r = rgb.red;
+ const g = rgb.green;
+ const b = rgb.blue;
+ const max = Math.max(r, g, b);
+ const min = Math.min(r, g, b);
+ const delta = max - min;
+ // Calculate brightness (value in HSV)
+ const brightness = max * 100;
+ // Calculate saturation
+ const saturation = max === 0 ? 0 : (delta / max) * 100;
+ // Calculate hue
+ let hue = 0;
+ if (delta !== 0) {
+ switch (max) {
+ case r:
+ hue = ((g - b) / delta + (g < b ? 6 : 0)) * 60;
+ break;
+ case g:
+ hue = ((b - r) / delta + 2) * 60;
+ break;
+ case b:
+ hue = ((r - g) / delta + 4) * 60;
+ break;
+ default:
+ break;
+ }
+ }
+ // Ensure hue is in [0, 360)
+ hue = (hue + 360) % 360;
+ return {
+ type: "hsb",
+ hue: hue,
+ saturation: saturation,
+ brightness: brightness,
+ };
+}
+//# sourceMappingURL=color-util.js.map \ No newline at end of file
diff --git a/node_modules/@jet-app/app-store/tmp/src/foundation/util/constants.js b/node_modules/@jet-app/app-store/tmp/src/foundation/util/constants.js
new file mode 100644
index 0000000..86522d5
--- /dev/null
+++ b/node_modules/@jet-app/app-store/tmp/src/foundation/util/constants.js
@@ -0,0 +1,26 @@
+/**
+ * Created by keithpk on 2/9/17.
+ */
+/**
+ * These are the developer IDs for apps that Apple works on internally
+ * The IDs in the list below are CPIDs (content provider IDs), which are not exposed
+ * to the client. So, we use the developer.id field that we have available instead.
+ * Note that Dark Sky both the same developer ID as Apple Inc.
+ * 2003 Apple Inc
+ * 120076162 Apple Health Research
+ * 244848 The Dark Sky Company LLC
+ * 115216 Claris International Inc.
+ * 14275 Shazam Entertainment Limited
+ * 118988565 AC Wellness Network LLC
+ */
+export const appleOwnedDeveloperIds = [
+ "284417353",
+ "1464590764",
+ "314638464",
+ "284993479",
+ "1351056256", // AC Wellness Network LLC
+];
+export const iAdRequestDataHeaderName = "X-Apple-iAd-Request-Data";
+export const appStoreClientRequestIdName = "X-Apple-App-Store-Client-Request-Id";
+export const iAdRoutingInfoHeaderName = "X-Apple-iAd-Env-Name";
+//# sourceMappingURL=constants.js.map \ No newline at end of file
diff --git a/node_modules/@jet-app/app-store/tmp/src/foundation/util/date-util.js b/node_modules/@jet-app/app-store/tmp/src/foundation/util/date-util.js
new file mode 100644
index 0000000..182dd63
--- /dev/null
+++ b/node_modules/@jet-app/app-store/tmp/src/foundation/util/date-util.js
@@ -0,0 +1,127 @@
+//
+// date.ts
+// AppStoreKit
+//
+// Created by Sam Vafaee on 10/25/17.
+// Copyright (c) 2017 Apple Inc. All rights reserved.
+//
+import * as serverData from "../json-parsing/server-data";
+/**
+ * Returns the date representation for a string ignoring the time. For preorders, it
+ * is vital that any date string be passed through this before being used.
+ * @param dateString The date string to parse
+ * @returns A date in local time zone.
+ */
+export function parseDateOmittingTimeFromString(dateString) {
+ // Sanity check
+ if (serverData.isNull(dateString) || dateString === "") {
+ return null;
+ }
+ // Only consider date
+ if (dateString.indexOf("T") !== -1) {
+ dateString = dateString.split("T")[0];
+ }
+ // This string replacement is needed to ensure midnight in the local time zone
+ // is used, rather than UTC-midnight.
+ return new Date(dateString.replace(/-/g, "/"));
+}
+/**
+ * Strips time from the given date and returns it as midnight UTC of the same day.
+ * @param date Local date.
+ * @returns UTC date
+ */
+export function convertLocalDateToUTCMidnight(date) {
+ // Sanity check
+ if (serverData.isNull(date)) {
+ return null;
+ }
+ return new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
+}
+/**
+ * Returns the number of milliseconds from epoch to UTC midnight of the given date.
+ * @param date Local date.
+ * @returns Milliseconds from epoch.
+ */
+export function millisecondsToUTCMidnightFromLocalDate(date) {
+ // Sanity check
+ if (serverData.isNull(date)) {
+ return null;
+ }
+ const utcDate = convertLocalDateToUTCMidnight(date);
+ if (serverData.isNull(utcDate)) {
+ return null;
+ }
+ return utcDate.getTime();
+}
+/**
+ * Removes the time portion from the given date and returns it as midnight of the same day.
+ * @param date Local date
+ * @returns Local date
+ */
+export function convertLocalDateToLocalMidnight(date) {
+ // Sanity check
+ if (serverData.isNull(date)) {
+ return null;
+ }
+ const midnight = new Date(date);
+ midnight.setHours(0, 0, 0, 0);
+ return midnight;
+}
+/**
+ * Sets the minutes, seconds and milliseconds of the given date to 0.
+ * @param date Local date
+ * @returns Local date
+ */
+export function convertLocalDateByFlooringToHour(date) {
+ // Sanity check
+ if (serverData.isNull(date)) {
+ return null;
+ }
+ return dateFlooredToHour(date);
+}
+/**
+ * Creates a new date with the minutes, seconds and milliseconds of the given date set to 0.
+ * @param date The date to remove minutes, seconds, and milliseconds from.
+ * @returns The new date with minutes, seconds, and milliseconds removed using local device time zone.
+ */
+export function dateFlooredToHour(date) {
+ const dateCopy = new Date(date.getTime());
+ dateCopy.setMinutes(0);
+ dateCopy.setSeconds(0);
+ dateCopy.setMilliseconds(0);
+ return dateCopy;
+}
+/**
+ * Returns the number of hours between two dates, or null if either date is null.
+ * @param fromDate The date to calculate from.
+ * @param toDate The date to calculate to.
+ */
+export function numberOfHoursBetween(fromDate, toDate) {
+ // Sanity check
+ if (serverData.isNull(fromDate) || serverData.isNull(toDate)) {
+ return null;
+ }
+ return Math.ceil((toDate.getTime() - dateFlooredToHour(fromDate).getTime()) / (60 * 60 * 1000));
+}
+/**
+ * Returns the number of days between two dates, or null if either date is null.
+ * @param fromDate The date to calculate from.
+ * @param toDate The date to calculate to.
+ */
+export function numberOfDaysBetween(fromDate, toDate) {
+ // Sanity check
+ if (serverData.isNull(fromDate) || serverData.isNull(toDate)) {
+ return null;
+ }
+ return Math.floor((toDate.getTime() - fromDate.getTime()) / (60 * 60 * 1000 * 24));
+}
+/**
+ * Whether or not two dates occur on the same day.
+ * @param date A date that will be compared to the second input.
+ * @param otherDate A date that will be compared to the first input.
+ */
+export function areLocalDatesSameDay(date, otherDate) {
+ var _a, _b;
+ return ((_a = convertLocalDateToLocalMidnight(date)) === null || _a === void 0 ? void 0 : _a.getTime()) === ((_b = convertLocalDateToLocalMidnight(otherDate)) === null || _b === void 0 ? void 0 : _b.getTime());
+}
+//# sourceMappingURL=date-util.js.map \ No newline at end of file
diff --git a/node_modules/@jet-app/app-store/tmp/src/foundation/util/errors.js b/node_modules/@jet-app/app-store/tmp/src/foundation/util/errors.js
new file mode 100644
index 0000000..d1a3482
--- /dev/null
+++ b/node_modules/@jet-app/app-store/tmp/src/foundation/util/errors.js
@@ -0,0 +1,13 @@
+/**
+ * Created by Ben Williams on 3/13/19.
+ */
+/**
+ * Enables compile time detection for code that should be unreachable
+ * For example, calling this function in the default case of a switch statement
+ * will provide compile time checking that the switch is exhaustive
+ * @return never
+ */
+export function unreachable(value) {
+ throw new Error(`This method should never be called with value: ${value}`);
+}
+//# sourceMappingURL=errors.js.map \ No newline at end of file
diff --git a/node_modules/@jet-app/app-store/tmp/src/foundation/util/math-util.js b/node_modules/@jet-app/app-store/tmp/src/foundation/util/math-util.js
new file mode 100644
index 0000000..92b4992
--- /dev/null
+++ b/node_modules/@jet-app/app-store/tmp/src/foundation/util/math-util.js
@@ -0,0 +1,32 @@
+/**
+ * Given an integer m > 1, called a modulus, two integers are said to be congruent modulo m,
+ * if m is a divisor of their difference (i.e., if there is an integer k such that a \u2212 b = km).
+ *
+ * Unlike JavaScript's remainder operator (%), this mod function never returns negative values.
+ *
+ * @param n An integer
+ * @param m The modulous
+ */
+export function mod(n, m) {
+ return ((n % m) + m) % m;
+}
+/**
+ * Reduce sig fig of `value` to `significantDigits`.
+ * @param value Value to reduce precision of.
+ * @param significantDigits Significant digits to keep.
+ */
+export function reduceSignificantDigits(value, significantDigits) {
+ const roundFactor = Math.pow(10.0, significantDigits);
+ const roundingFunction = value > 0.0 ? Math.floor : Math.ceil;
+ return roundingFunction(value / roundFactor) * roundFactor;
+}
+/**
+ * Clamps a value between an upper and lower bound.
+ * @param value The preferred value.
+ * @param min The minimum allowed value.
+ * @param max The maximum allowed value.
+ */
+export function clamp(value, min, max) {
+ return Math.max(min, Math.min(max, value));
+}
+//# sourceMappingURL=math-util.js.map \ No newline at end of file
diff --git a/node_modules/@jet-app/app-store/tmp/src/foundation/util/objects.js b/node_modules/@jet-app/app-store/tmp/src/foundation/util/objects.js
new file mode 100644
index 0000000..6740572
--- /dev/null
+++ b/node_modules/@jet-app/app-store/tmp/src/foundation/util/objects.js
@@ -0,0 +1,33 @@
+/* eslint-disable @typescript-eslint/no-explicit-any */
+/**
+ * Created by km on 3/6/17.
+ */
+/**
+ * Creates and returns a shallow copy of a given object.
+ * @param object The object to create a shallow copy of.
+ * @returns The new copy of object.
+ */
+export function shallowCopyOf(object) {
+ if (object === null || object === undefined) {
+ return object;
+ }
+ const copy = Object.create(Object.getPrototypeOf(object));
+ Object.assign(copy, object);
+ return copy;
+}
+/**
+ * Returns whether or not a given object is an instance of
+ * a specified type, modifying the type of the object in
+ * TypeScript's type system.
+ *
+ * Prefer this function to using `instanceof` directly as it
+ * will retype the passed in object if the check succeeds.
+ *
+ * @param object The object whose nominal type will be checked.
+ * @param type The metatype that `object` is expected to be an instance of.
+ * @returns Whether object is an instance of type, updating the type of object accordingly.
+ */
+export function isTypeOf(object, type) {
+ return object instanceof type;
+}
+//# sourceMappingURL=objects.js.map \ No newline at end of file
diff --git a/node_modules/@jet-app/app-store/tmp/src/foundation/util/promise-util.js b/node_modules/@jet-app/app-store/tmp/src/foundation/util/promise-util.js
new file mode 100644
index 0000000..d661559
--- /dev/null
+++ b/node_modules/@jet-app/app-store/tmp/src/foundation/util/promise-util.js
@@ -0,0 +1,215 @@
+/**
+ * This module provides enhanced promise handling capabilities beyond native JavaScript Promises.
+ * It focuses on distinguishing between required and optional promises, standardizing results,
+ * and simplifying error handling for complex async operations.
+ */
+/**
+ * Symbol used to uniquely identify PromiseResult objects.
+ * This allows for reliable type checking.
+ */
+export const PROMISE_RESULT_SYMBOL = Symbol("PromiseResult");
+/**
+ * Type guard to check if a value is a PromiseResult.
+ *
+ * @param value - The value to check
+ * @returns True if the value is a PromiseResult, false otherwise
+ */
+function isPromiseResult(value) {
+ return value !== null && typeof value === "object" && PROMISE_RESULT_SYMBOL in value;
+}
+/**
+ * Custom error class that aggregates multiple promise failures.
+ * Provides access to all underlying errors while presenting a combined error message.
+ */
+export class MultiPromiseError extends Error {
+ constructor(reasons) {
+ super(errorMessageForReasons(reasons));
+ this.reasons = reasons;
+ this.reasons = reasons;
+ }
+}
+/**
+ * Helper function to create a standardized fulfilled result object.
+ * Ensures the result has the PROMISE_RESULT_SYMBOL for type checking.
+ *
+ * @param value - The value to wrap in a fulfilled result
+ * @returns A standardized fulfilled result object
+ */
+export function makeFulfilledResult(value) {
+ return {
+ success: true,
+ value,
+ error: null,
+ [PROMISE_RESULT_SYMBOL]: true,
+ };
+}
+/**
+ * Helper function to create a standardized rejected result object.
+ * Ensures the result has the PROMISE_RESULT_SYMBOL for type checking.
+ *
+ * @param error - The error to wrap in a rejected result
+ * @returns A standardized rejected result object
+ */
+export function makeRejectedResult(error) {
+ const normalizedError = error instanceof Error ? error : new Error(String(error));
+ return {
+ success: false,
+ value: null,
+ error: normalizedError,
+ [PROMISE_RESULT_SYMBOL]: true,
+ };
+}
+/**
+ * Custom error class that indicates that a required promise failed.
+ */
+export class RequiredPromiseError extends Error {
+ constructor(reason) {
+ super(reason.message);
+ this.reason = reason;
+ this.reason = reason;
+ }
+}
+/**
+ * Transforms a promise into one that never throws, instead returning a standardized result.
+ * Use this for optional operations that shouldn't cause the overall process to fail.
+ * This is a convenience alias for tryAwait with a more semantic name.
+ *
+ * @param promise - The promise to make optional
+ * @returns A promise that resolves to a PromiseResult instead of throwing
+ */
+export async function optional(promise) {
+ return await tryAwait(promise);
+}
+/**
+ * Marks a promise as required (will throw on rejection).
+ * This is mainly for code clarity as regular promises are already required by default.
+ *
+ * @param promise - The promise to mark as required
+ * @returns The original promise (identity function)
+ */
+export async function required(promise) {
+ return await promise;
+}
+/**
+ * Executes a mix of required and optional promises, returning standardized results.
+ * Regular promises are treated as required and will cause this function to throw if they fail.
+ * Promises wrapped with optional() will never cause this function to throw.
+ *
+ * This implementation handles both regular promises and promises that resolve to PromiseResult.
+ *
+ * @param promises - Array of promises (both required and optional)
+ * @returns Promise resolving to an array of standardized results
+ * @throws Original error if a single required promise fails
+ * @throws MultiPromiseError if multiple required promises fail
+ * @note For homogeneous promise arrays, prefer using more specific functions:
+ * - Use allRequired() when all promises should be treated as required
+ * - Use allOptional() when all promises should be treated as optional
+ * - Only use allMixed() when you need to combine both required and optional promises
+ */
+export async function allMixed(promises) {
+ // Process each promise
+ const results = await Promise.all(promises.map(async (promise) => {
+ try {
+ const value = await promise;
+ // If it's a PromiseResult (from optional()/tryAwait), use it directly
+ if (isPromiseResult(value)) {
+ // Handle the case where T is already a PromiseResult
+ // This fixes the double-wrapping issue when all promises are optional
+ return value;
+ }
+ else {
+ // It's a regular promise that succeeded
+ return makeFulfilledResult(value);
+ }
+ }
+ catch (error) {
+ // This was a required promise that failed
+ return makeRejectedResult(error instanceof Error ? error : new Error(String(error)));
+ }
+ }));
+ const requiredFailures = [];
+ results.forEach((result) => {
+ if (!result.success) {
+ requiredFailures.push(result.error);
+ }
+ });
+ // If any required promises failed, throw an error
+ if (requiredFailures.length > 0) {
+ if (requiredFailures.length === 1) {
+ throw requiredFailures[0];
+ }
+ else {
+ throw new MultiPromiseError(requiredFailures);
+ }
+ }
+ return results;
+}
+/**
+ * Executes all promises and returns their values.
+ * All promises are treated as required and will cause this function to throw if any fail.
+ *
+ * @param promises - Array of promises
+ * @returns Promise resolving to an array of values
+ * @throws Original error if a single promise fails
+ * @throws MultiPromiseError if multiple promises fail
+ */
+export async function allRequired(promises) {
+ return await Promise.all(promises);
+}
+/**
+ * Makes all promises optional and then executes them, returning standardized results.
+ * This function is specifically designed for cases where you want all promises to be treated as optional.
+ * It avoids the double-wrapping issue that can occur when using allMixed with arrays of optional promises.
+ *
+ * @param promises - Array of promises to make optional
+ * @returns Promise resolving to an array of standardized results
+ * @example
+ * ```
+ * const promises = urls.map(fetchData);
+ * const results = await allOptional(promises);
+ * // Each result is a PromiseResult<T> that won't cause the overall operation to fail
+ * ```
+ */
+export async function allOptional(promises) {
+ // Use Promise.all with optional() for each promise
+ return await Promise.all(promises.map(optional));
+}
+/**
+ * Creates an error message from multiple rejection reasons.
+ * Formats multiple error reasons into a single error message string,
+ * handling both Error objects and other rejection values.
+ *
+ * @param reasons - Array of error reasons that caused promise rejections
+ * @returns Concatenated error message string
+ */
+function errorMessageForReasons(reasons) {
+ return reasons
+ .map((reason) => {
+ if (reason instanceof Error) {
+ return reason.message;
+ }
+ else {
+ return JSON.stringify(reason);
+ }
+ })
+ .join("");
+}
+/**
+ * Safely awaits a promise and returns a standardized result object.
+ * Eliminates the need for repetitive try/catch blocks throughout the codebase.
+ *
+ * @param promiseOrFn - Either a promise or a function that returns a promise
+ * @returns A standardized PromiseResult object indicating success or failure
+ */
+export async function tryAwait(promiseOrFn) {
+ try {
+ // Handle both promise and function that returns a promise
+ const promise = typeof promiseOrFn === "function" ? promiseOrFn() : promiseOrFn;
+ const value = await promise;
+ return makeFulfilledResult(value);
+ }
+ catch (error) {
+ return makeRejectedResult(error);
+ }
+}
+//# sourceMappingURL=promise-util.js.map \ No newline at end of file
diff --git a/node_modules/@jet-app/app-store/tmp/src/foundation/util/string-util.js b/node_modules/@jet-app/app-store/tmp/src/foundation/util/string-util.js
new file mode 100644
index 0000000..affeba3
--- /dev/null
+++ b/node_modules/@jet-app/app-store/tmp/src/foundation/util/string-util.js
@@ -0,0 +1,127 @@
+/**
+ * Created by dabolfathi on 4/26/17.
+ */
+/**
+ * Returns a single string, which is the result of joining together all
+ * the strings in the list with the provided separator.
+ * @param strings The list of strings to be joined.
+ * @param separator The separator to use when joining them together.
+ * @returns {string} The joined string.
+ */
+export function join(strings, separator) {
+ if (strings == null || separator == null) {
+ return null;
+ }
+ if (strings.length === 0) {
+ return "";
+ }
+ let stringCount = strings.length;
+ let joinedString = "";
+ strings.forEach((element, index) => {
+ if (element === null) {
+ stringCount -= 1;
+ }
+ else {
+ joinedString += element;
+ if (index < stringCount - 1) {
+ joinedString += separator;
+ }
+ }
+ });
+ return joinedString;
+}
+/**
+ * Generate a normalized string for robust multilingual search that properly handles
+ * CJK (Chinese, Japanese, Korean), Arabic, Cyrillic, and Latin-based scripts.
+ * Preserves Unicode characters while normalizing diacritics and case appropriately.
+ *
+ * @param input The input string to normalize
+ * @returns A normalized string suitable for search matching
+ */
+export function normalizeForSearch(input) {
+ if (!input) {
+ return "";
+ }
+ try {
+ // Remove special characters
+ // \u2122 -> (Trade Mark Sign)
+ // \u2120 -> (Service Mark)
+ // \u03a9 -> (Greek Capital Letter Omega)
+ // \u00a9 -> (Copyright Sign)
+ // \u00ae -> (Registered Sign)
+ // \u30fc -> (Katakana-Hiragana Prolonged Sound Mark)
+ // \u03c9 -> (Greek Small Letter Omega)
+ const removedSpecialUnicodesRegex = /[\u2122\u2120\u03a9\u00a9\u00ae\u30fc\u03c9]/g;
+ return (input
+ .toLowerCase() // Case insensitivity
+ .replace(removedSpecialUnicodesRegex, "")
+ // Apply normalization only to Latin characters to preserve CJK integrity
+ // Handle Latin characters safely with basic ranges A-Za-z
+ // \u00C0-\u00FF - Latin-1 Supplement (Upper Half)
+ // \u0100-\u017F - Latin Extended-A (includes dotless i \u0131)
+ // \u0180-\u024F - Latin Extended-B
+ // \u1E00-\u1EFF - Latin Extended Additional
+ .replace(/[A-Za-z\u00A0-\u00FF\u0100-\u017F\u0180-\u024F\u1E00-\u1EFF\p{Diacritic}]+/gu, (latinText) => {
+ return (latinText
+ .normalize("NFKD")
+ .replace(/\p{Diacritic}/gu, "")
+ // Convert specific characters that don't match basic Latin
+ .replace(/\u0131/g, "i") // Convert dotless i to regular i
+ // Keep only actual Latin characters and numbers after normalization
+ .replace(/[^A-Za-z0-9]/g, ""));
+ })
+ // Remove punctuation, symbols, and control characters but preserve:
+ // - Letters from all writing systems (\p{L})
+ // - Numbers (\p{N})
+ // - Whitespace (\s)
+ // - Underscores (_)
+ .replace(/[^\p{L}\p{N}\s_]/gu, "")
+ // Normalize multiple whitespace to single spaces
+ .replace(/\s+/g, " ")
+ // Trim leading/trailing whitespace
+ .trim());
+ }
+ catch (error) {
+ // Fallback: use basic character classes
+ return (input
+ .toLowerCase()
+ // Remove punctuation, symbols, and control characters but preserve:
+ // - Letters from all writing systems (\p{L})
+ // - Numbers (\p{N})
+ // - Whitespace (\s)
+ // - Underscores (_)
+ .replace(/[^\p{L}\p{N}\s_]/gu, "")
+ // Normalize multiple whitespace to single spaces
+ .replace(/\s+/g, " ")
+ // Trim leading/trailing whitespace
+ .trim());
+ }
+}
+/**
+ * Whether or not the input string is contains search term using normalized string which comparing using case insensitive, locale insensitive and ignore all special characters.
+ *
+ * @param input
+ * @param normalizedTerm
+ * @returns
+ */
+export function containsSearchTerm(input, normalizedTerm) {
+ const normalizedInput = normalizeForSearch(input);
+ return normalizedInput.includes(normalizedTerm);
+}
+/**
+ * Wraps a string with bidirectional isolate characters to ensure proper text direction handling.
+ * This is particularly useful for user-generated content like display names that may contain
+ * mixed left-to-right and right-to-left text.
+ *
+ * @param text The string to wrap with bidi isolates
+ * @returns The string wrapped with Left-to-Right Isolate (U+2066) and Pop Directional Isolate (U+2069)
+ */
+export function withBidiIsolates(text) {
+ if (!text) {
+ return text;
+ }
+ // U+2068: First Strong Isolate
+ // U+2069: Pop Directional Isolate
+ return "\u2068" + text + "\u2069";
+}
+//# sourceMappingURL=string-util.js.map \ No newline at end of file
diff --git a/node_modules/@jet-app/app-store/tmp/src/foundation/util/validation-util.js b/node_modules/@jet-app/app-store/tmp/src/foundation/util/validation-util.js
new file mode 100644
index 0000000..fe9bd93
--- /dev/null
+++ b/node_modules/@jet-app/app-store/tmp/src/foundation/util/validation-util.js
@@ -0,0 +1,30 @@
+import { isSome } from "@jet/environment";
+import * as validation from "@jet/environment/json/validation";
+import { tryAwait } from "./promise-util";
+/**
+ * Creates a validation context for async operations and ensures proper cleanup.
+ *
+ * Wraps an async operation in a validation context, automatically handling
+ * context cleanup even when errors occur. Optionally processes errors through
+ * a provided error handler.
+ *
+ * @param name - The name for the validation context
+ * @param producer - Async function that produces the result
+ * @param errorHandler - Optional function to handle errors from the producer
+ * @returns The result of the async operation
+ */
+export async function withAsyncValidationContext(name, producer, errorHandler) {
+ validation.beginContext(name);
+ let result = await tryAwait(producer());
+ if (!result.success && isSome(errorHandler)) {
+ result = await tryAwait(errorHandler(result.error));
+ }
+ validation.endContext();
+ if (!result.success) {
+ throw result.error;
+ }
+ else {
+ return result.value;
+ }
+}
+//# sourceMappingURL=validation-util.js.map \ No newline at end of file