From bce557cc2dc767628bed6aac87301a1be7c5431b Mon Sep 17 00:00:00 2001 From: rxliuli Date: Tue, 4 Nov 2025 05:03:50 +0800 Subject: init commit --- .../tmp/src/foundation/util/array-util.js | 32 +++ .../tmp/src/foundation/util/color-util.js | 231 +++++++++++++++++++++ .../app-store/tmp/src/foundation/util/constants.js | 26 +++ .../app-store/tmp/src/foundation/util/date-util.js | 127 +++++++++++ .../app-store/tmp/src/foundation/util/errors.js | 13 ++ .../app-store/tmp/src/foundation/util/math-util.js | 32 +++ .../app-store/tmp/src/foundation/util/objects.js | 33 +++ .../tmp/src/foundation/util/promise-util.js | 215 +++++++++++++++++++ .../tmp/src/foundation/util/string-util.js | 127 +++++++++++ .../tmp/src/foundation/util/validation-util.js | 30 +++ 10 files changed, 866 insertions(+) create mode 100644 node_modules/@jet-app/app-store/tmp/src/foundation/util/array-util.js create mode 100644 node_modules/@jet-app/app-store/tmp/src/foundation/util/color-util.js create mode 100644 node_modules/@jet-app/app-store/tmp/src/foundation/util/constants.js create mode 100644 node_modules/@jet-app/app-store/tmp/src/foundation/util/date-util.js create mode 100644 node_modules/@jet-app/app-store/tmp/src/foundation/util/errors.js create mode 100644 node_modules/@jet-app/app-store/tmp/src/foundation/util/math-util.js create mode 100644 node_modules/@jet-app/app-store/tmp/src/foundation/util/objects.js create mode 100644 node_modules/@jet-app/app-store/tmp/src/foundation/util/promise-util.js create mode 100644 node_modules/@jet-app/app-store/tmp/src/foundation/util/string-util.js create mode 100644 node_modules/@jet-app/app-store/tmp/src/foundation/util/validation-util.js (limited to 'node_modules/@jet-app/app-store/tmp/src/foundation/util') 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 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 -- cgit v1.2.3