@knapsack/utils 5.0.0--canary.6593.4738696.0 → 5.0.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/.lintstagedrc.mjs +2 -2
- package/CHANGELOG.md +151 -0
- package/dist/.tsbuildinfo-es +1 -1
- package/dist/arrays.d.ts.map +1 -1
- package/dist/arrays.js.map +1 -1
- package/dist/arrays.mjs.map +1 -1
- package/dist/dates.js.map +1 -1
- package/dist/dates.mjs +1 -1
- package/dist/dates.mjs.map +1 -1
- package/dist/fetcher.js.map +1 -1
- package/dist/fetcher.mjs.map +1 -1
- package/dist/functions.d.ts +15 -1
- package/dist/functions.d.ts.map +1 -1
- package/dist/functions.js +1 -1
- package/dist/functions.js.map +1 -1
- package/dist/functions.mjs +1 -1
- package/dist/functions.mjs.map +1 -1
- package/dist/ids.d.ts +1 -0
- package/dist/ids.d.ts.map +1 -1
- package/dist/ids.js +1 -1
- package/dist/ids.js.map +1 -1
- package/dist/ids.mjs +1 -1
- package/dist/ids.mjs.map +1 -1
- package/dist/immer.d.ts +1 -1
- package/dist/immer.d.ts.map +1 -1
- package/dist/immer.js +1 -1
- package/dist/immer.js.map +1 -1
- package/dist/immer.mjs +1 -1
- package/dist/immer.mjs.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +1 -1
- package/dist/is-types.js.map +1 -1
- package/dist/is-types.mjs.map +1 -1
- package/dist/js-env.js.map +1 -1
- package/dist/js-env.mjs.map +1 -1
- package/dist/loose-equal.js.map +1 -1
- package/dist/loose-equal.mjs.map +1 -1
- package/dist/misc.js.map +1 -1
- package/dist/misc.mjs.map +1 -1
- package/dist/objects.d.ts.map +1 -1
- package/dist/objects.js +1 -1
- package/dist/objects.js.map +1 -1
- package/dist/objects.mjs +1 -1
- package/dist/objects.mjs.map +1 -1
- package/dist/paths.js.map +1 -1
- package/dist/paths.mjs.map +1 -1
- package/dist/strings.js.map +1 -1
- package/dist/strings.mjs.map +1 -1
- package/dist/type-tools.d.ts.map +1 -1
- package/dist/type-tools.js.map +1 -1
- package/dist/type-tools.mjs.map +1 -1
- package/dist/urls.d.ts +12 -0
- package/dist/urls.d.ts.map +1 -1
- package/dist/urls.js +2 -2
- package/dist/urls.js.map +1 -1
- package/dist/urls.mjs +2 -2
- package/dist/urls.mjs.map +1 -1
- package/dist/validation.js.map +1 -1
- package/dist/validation.mjs.map +1 -1
- package/package.json +15 -17
- package/vitest.config.ts +7 -0
- package/.eslintrc.js +0 -4
- package/ava.config.cjs +0 -3
package/dist/arrays.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"arrays.d.ts","sourceRoot":"","sources":["../src/arrays.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAErD;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,CAM3C;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,GAAG,OAAO,EACjE,MAAM,EAAE,CAAC,EAAE,EACX,MAAM,EAAE,CAAC,EAAE,GACV,OAAO,CAET;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,GAAG,SAAS,MAAM,GAAG,MAAM,CAAC,EAAE,EACrE,KAAK,EACL,GAAG,EACH,cAAc,GACf,EAAE;IACD,KAAK,EAAE,CAAC,EAAE,GAAG,SAAS,CAAC,EAAE,CAAC;IAC1B,6BAA6B;IAC7B,GAAG,EAAE,GAAG,CAAC;IACT,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,QAoBA;AAED,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAG7D;AAED,wBAAgB,4BAA4B,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CASpE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAC/B,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM;AAE1B;;GAEG;AACH,KAAK,EAAE,CAAC,EAAE;AACV;;GAEG;AACH,OAAO,EAAE,CAAC,GACT,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"arrays.d.ts","sourceRoot":"","sources":["../src/arrays.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAErD;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,CAM3C;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,GAAG,OAAO,EACjE,MAAM,EAAE,CAAC,EAAE,EACX,MAAM,EAAE,CAAC,EAAE,GACV,OAAO,CAET;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,GAAG,SAAS,MAAM,GAAG,MAAM,CAAC,EAAE,EACrE,KAAK,EACL,GAAG,EACH,cAAc,GACf,EAAE;IACD,KAAK,EAAE,CAAC,EAAE,GAAG,SAAS,CAAC,EAAE,CAAC;IAC1B,6BAA6B;IAC7B,GAAG,EAAE,GAAG,CAAC;IACT,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,QAoBA;AAED,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAG7D;AAED,wBAAgB,4BAA4B,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CASpE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAC/B,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM;AAE1B;;GAEG;AACH,KAAK,EAAE,CAAC,EAAE;AACV;;GAEG;AACH,OAAO,EAAE,CAAC,GACT,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAYnB"}
|
package/dist/arrays.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/arrays.ts"],"names":["uniqueArray","ar","j","v","__name","hasItemsInItems","arrayA","arrayB","a","assertUniqueIdInArray","items","key","errorMsgPrefix","ids","duplicates","item","itemKey","duplicateIdList","d","isArrayOfStringsUnique","arr","unique","getNonUniqueStringsFromArray","arrayToDictionary","array","keyProp","acc"],"mappings":"wQAOO,SAASA,CAAAA,CAAeC,EAAc,CAC3C,IAAMC,CAAI,
|
|
1
|
+
{"version":3,"sources":["../src/arrays.ts"],"names":["uniqueArray","ar","j","v","__name","hasItemsInItems","arrayA","arrayB","a","assertUniqueIdInArray","items","key","errorMsgPrefix","ids","duplicates","item","itemKey","duplicateIdList","d","isArrayOfStringsUnique","arr","unique","getNonUniqueStringsFromArray","arrayToDictionary","array","keyProp","acc"],"mappings":"wQAOO,SAASA,CAAAA,CAAeC,EAAc,CAC3C,IAAMC,CAAAA,CAAI,EAAC,CACX,OAAAD,EAAG,OAAA,CAASE,CAAAA,EAAM,CAChBD,CAAAA,CAAE,CAAA,EAAGC,CAAC,KAAK,OAAOA,CAAC,CAAA,CAAE,CAAA,CAAIA,EAC3B,CAAC,EACM,MAAA,CAAO,IAAA,CAAKD,CAAC,CAAA,CAAE,GAAA,CAAKC,CAAAA,EAAMD,EAAEC,CAAC,CAAC,CACvC,CANgBC,CAAAA,CAAAJ,CAAAA,CAAA,eAYT,SAASK,CAAAA,CACdC,CAAAA,CACAC,CAAAA,CACS,CACT,OAAOD,CAAAA,CAAO,IAAA,CAAME,CAAAA,EAAMD,CAAAA,CAAO,QAAA,CAASC,CAAC,CAAC,CAC9C,CALgBJ,CAAAA,CAAAC,CAAAA,CAAA,iBAAA,CAAA,CAUT,SAASI,CAAAA,CAAuD,CACrE,MAAAC,CAAAA,CACA,GAAA,CAAAC,CAAAA,CACA,cAAA,CAAAC,CACF,CAAA,CAKG,CACD,IAAMC,CAAAA,CAAgB,EAAC,CACjBC,CAAAA,CAAkB,EAAC,CASzB,GARAJ,CAAAA,CAAM,OAAA,CAASK,CAAAA,EAAS,CACtB,IAAMC,CAAAA,CAAU,OAAOD,CAAAA,CAAKJ,CAAG,CAAC,CAAA,CAC5BE,CAAAA,CAAI,QAAA,CAASG,CAAO,CAAA,CACtBF,CAAAA,CAAW,IAAA,CAAKC,CAAI,CAAA,CAEpBF,CAAAA,CAAI,KAAKG,CAAO,EAEpB,CAAC,CAAA,CACGF,CAAAA,CAAW,MAAA,CAAS,CAAA,CAAG,CACzB,IAAMG,CAAAA,CAAkBH,CAAAA,CAAW,GAAA,CAAKI,CAAAA,EAAM,CAAA,CAAA,EAAIA,EAAEP,CAAG,CAAC,CAAA,CAAA,CAAG,CAAA,CAAE,IAAA,CAAK,IAAI,EACtE,MAAM,IAAI,KAAA,CACR,CAAA,EACEC,CAAAA,EACA,CAAA,wCAAA,EAA2CD,CAAG,CAAA,OAAA,CAChD,CAAA,2BAAA,EAA8BM,CAAe,CAAA,CAC/C,CACF,CACF,CA7BgBb,CAAAA,CAAAK,CAAAA,CAAA,uBAAA,CAAA,CA+BT,SAASU,CAAAA,CAAuBC,CAAAA,CAAwB,CAC7D,IAAMC,CAAAA,CAAS,IAAI,GAAA,CAAID,CAAG,CAAA,CAC1B,OAAOA,EAAI,MAAA,GAAWC,CAAAA,CAAO,IAC/B,CAHgBjB,CAAAA,CAAAe,CAAAA,CAAA,0BAKT,SAASG,CAAAA,CAA6BF,CAAAA,CAAyB,CACpE,IAAMC,CAAAA,CAAS,IAAI,GAAA,CACnB,OAAOD,CAAAA,CAAI,MAAA,CAAQZ,CAAAA,EACba,CAAAA,CAAO,GAAA,CAAIb,CAAC,CAAA,CACP,IAAA,EAETa,CAAAA,CAAO,GAAA,CAAIb,CAAC,CAAA,CACL,MACR,CACH,CATgBJ,CAAAA,CAAAkB,CAAAA,CAAA,8BAAA,CAAA,CA2BT,SAASC,EAOdC,CAAAA,CAIAC,CAAAA,CACmB,CACnB,OAAOD,CAAAA,CAAM,MAAA,CACX,CAACE,CAAAA,CAAKX,CAAAA,GAAS,CACb,GAAM,CAAE,CAACU,CAAO,EAAGd,CAAI,CAAA,CAAII,CAAAA,CAC3B,GAAIW,CAAAA,CAAIf,CAAa,EACnB,MAAM,IAAI,KAAA,CAAM,CAAA,eAAA,EAAkBA,CAAG,CAAA,CAAE,EAEzC,OAAAe,CAAAA,CAAIf,CAAa,CAAA,CAAII,CAAAA,CACdW,CACT,CAAA,CACA,EACF,CACF,CAxBgBtB,CAAAA,CAAAmB,CAAAA,CAAA,mBAAA,CAAA","file":"arrays.js","sourcesContent":["export { default as uniqBy } from 'lodash/uniqBy.js';\n\n/**\n * Make an array unique by removing duplicate entries.\n * @param ar - Array to make unique\n * @returns A unique array\n */\nexport function uniqueArray<T>(ar: T[]): T[] {\n const j = {};\n ar.forEach((v) => {\n j[`${v}::${typeof v}`] = v;\n });\n return Object.keys(j).map((v) => j[v]);\n}\n\n/**\n * Is Some Of This Array In That Array?\n * Are any of the items in arrayA in arrayB?\n */\nexport function hasItemsInItems<T extends string | number | boolean>(\n arrayA: T[],\n arrayB: T[],\n): boolean {\n return arrayA.some((a) => arrayB.includes(a));\n}\n\n/**\n * Used to ensure that the `id` prop in each object in an array is unique\n */\nexport function assertUniqueIdInArray<T, Key extends string & keyof T>({\n items,\n key,\n errorMsgPrefix,\n}: {\n items: T[] | readonly T[];\n /** Can be `id` or `value` */\n key: Key;\n errorMsgPrefix?: string;\n}) {\n const ids: string[] = [];\n const duplicates: T[] = [];\n items.forEach((item) => {\n const itemKey = String(item[key]);\n if (ids.includes(itemKey)) {\n duplicates.push(item);\n } else {\n ids.push(itemKey);\n }\n });\n if (duplicates.length > 0) {\n const duplicateIdList = duplicates.map((d) => `\"${d[key]}\"`).join(', ');\n throw new Error(\n `${\n errorMsgPrefix ||\n `Each item in the array requires unique \"${key}\" prop.`\n } These ids are duplicates: ${duplicateIdList}`,\n );\n }\n}\n\nexport function isArrayOfStringsUnique(arr: string[]): boolean {\n const unique = new Set(arr);\n return arr.length === unique.size;\n}\n\nexport function getNonUniqueStringsFromArray(arr: string[]): string[] {\n const unique = new Set<string>();\n return arr.filter((a) => {\n if (unique.has(a)) {\n return true;\n }\n unique.add(a);\n return false;\n });\n}\n\n/**\n * Converts an array of objects to a dictionary using a specified key.\n *\n * @see {@link dictionaryToArray}\n *\n * @example\n * const array = [\n * { id: '123', name: 'foo' },\n * { id: '456', name: 'bar' }\n * ];\n * const result = arrayToDictionary(array);\n * // Result: { '123': { name: 'foo' }, '456': { name: 'bar' } }\n *\n * const customResult = arrayToDictionary(array, 'name');\n * // Result: { 'foo': { id: '123' }, 'bar': { id: '456' } }\n */\nexport function arrayToDictionary<\n T extends Record<string, unknown>,\n K extends keyof T & string,\n>(\n /**\n * The array of objects to convert\n */\n array: T[],\n /**\n * The property to use as the dictionary key\n */\n keyProp: K,\n): Record<string, T> {\n return array.reduce(\n (acc, item) => {\n const { [keyProp]: key } = item;\n if (acc[key as string]) {\n throw new Error(`Duplicate key: ${key}`);\n }\n acc[key as string] = item;\n return acc;\n },\n {} as Record<string, T>,\n );\n}\n"]}
|
package/dist/arrays.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/arrays.ts"],"names":["uniqueArray","ar","j","v","__name","hasItemsInItems","arrayA","arrayB","a","assertUniqueIdInArray","items","key","errorMsgPrefix","ids","duplicates","item","itemKey","duplicateIdList","d","isArrayOfStringsUnique","arr","unique","getNonUniqueStringsFromArray","arrayToDictionary","array","keyProp","acc"],"mappings":"iIAOO,SAASA,CAAAA,CAAeC,EAAc,CAC3C,IAAMC,CAAI,
|
|
1
|
+
{"version":3,"sources":["../src/arrays.ts"],"names":["uniqueArray","ar","j","v","__name","hasItemsInItems","arrayA","arrayB","a","assertUniqueIdInArray","items","key","errorMsgPrefix","ids","duplicates","item","itemKey","duplicateIdList","d","isArrayOfStringsUnique","arr","unique","getNonUniqueStringsFromArray","arrayToDictionary","array","keyProp","acc"],"mappings":"iIAOO,SAASA,CAAAA,CAAeC,EAAc,CAC3C,IAAMC,CAAAA,CAAI,EAAC,CACX,OAAAD,EAAG,OAAA,CAASE,CAAAA,EAAM,CAChBD,CAAAA,CAAE,CAAA,EAAGC,CAAC,KAAK,OAAOA,CAAC,CAAA,CAAE,CAAA,CAAIA,EAC3B,CAAC,EACM,MAAA,CAAO,IAAA,CAAKD,CAAC,CAAA,CAAE,GAAA,CAAKC,CAAAA,EAAMD,EAAEC,CAAC,CAAC,CACvC,CANgBC,CAAAA,CAAAJ,CAAAA,CAAA,eAYT,SAASK,CAAAA,CACdC,CAAAA,CACAC,CAAAA,CACS,CACT,OAAOD,CAAAA,CAAO,IAAA,CAAME,CAAAA,EAAMD,CAAAA,CAAO,QAAA,CAASC,CAAC,CAAC,CAC9C,CALgBJ,CAAAA,CAAAC,CAAAA,CAAA,iBAAA,CAAA,CAUT,SAASI,CAAAA,CAAuD,CACrE,MAAAC,CAAAA,CACA,GAAA,CAAAC,CAAAA,CACA,cAAA,CAAAC,CACF,CAAA,CAKG,CACD,IAAMC,CAAAA,CAAgB,EAAC,CACjBC,CAAAA,CAAkB,EAAC,CASzB,GARAJ,CAAAA,CAAM,OAAA,CAASK,CAAAA,EAAS,CACtB,IAAMC,CAAAA,CAAU,OAAOD,CAAAA,CAAKJ,CAAG,CAAC,CAAA,CAC5BE,CAAAA,CAAI,QAAA,CAASG,CAAO,CAAA,CACtBF,CAAAA,CAAW,IAAA,CAAKC,CAAI,CAAA,CAEpBF,CAAAA,CAAI,KAAKG,CAAO,EAEpB,CAAC,CAAA,CACGF,CAAAA,CAAW,MAAA,CAAS,CAAA,CAAG,CACzB,IAAMG,CAAAA,CAAkBH,CAAAA,CAAW,GAAA,CAAKI,CAAAA,EAAM,CAAA,CAAA,EAAIA,EAAEP,CAAG,CAAC,CAAA,CAAA,CAAG,CAAA,CAAE,IAAA,CAAK,IAAI,EACtE,MAAM,IAAI,KAAA,CACR,CAAA,EACEC,CAAAA,EACA,CAAA,wCAAA,EAA2CD,CAAG,CAAA,OAAA,CAChD,CAAA,2BAAA,EAA8BM,CAAe,CAAA,CAC/C,CACF,CACF,CA7BgBb,CAAAA,CAAAK,CAAAA,CAAA,uBAAA,CAAA,CA+BT,SAASU,CAAAA,CAAuBC,CAAAA,CAAwB,CAC7D,IAAMC,CAAAA,CAAS,IAAI,GAAA,CAAID,CAAG,CAAA,CAC1B,OAAOA,EAAI,MAAA,GAAWC,CAAAA,CAAO,IAC/B,CAHgBjB,CAAAA,CAAAe,CAAAA,CAAA,0BAKT,SAASG,CAAAA,CAA6BF,CAAAA,CAAyB,CACpE,IAAMC,CAAAA,CAAS,IAAI,GAAA,CACnB,OAAOD,CAAAA,CAAI,MAAA,CAAQZ,CAAAA,EACba,CAAAA,CAAO,GAAA,CAAIb,CAAC,CAAA,CACP,IAAA,EAETa,CAAAA,CAAO,GAAA,CAAIb,CAAC,CAAA,CACL,MACR,CACH,CATgBJ,CAAAA,CAAAkB,CAAAA,CAAA,8BAAA,CAAA,CA2BT,SAASC,EAOdC,CAAAA,CAIAC,CAAAA,CACmB,CACnB,OAAOD,CAAAA,CAAM,MAAA,CACX,CAACE,CAAAA,CAAKX,CAAAA,GAAS,CACb,GAAM,CAAE,CAACU,CAAO,EAAGd,CAAI,CAAA,CAAII,CAAAA,CAC3B,GAAIW,CAAAA,CAAIf,CAAa,EACnB,MAAM,IAAI,KAAA,CAAM,CAAA,eAAA,EAAkBA,CAAG,CAAA,CAAE,EAEzC,OAAAe,CAAAA,CAAIf,CAAa,CAAA,CAAII,CAAAA,CACdW,CACT,CAAA,CACA,EACF,CACF,CAxBgBtB,CAAAA,CAAAmB,CAAAA,CAAA,mBAAA,CAAA","file":"arrays.mjs","sourcesContent":["export { default as uniqBy } from 'lodash/uniqBy.js';\n\n/**\n * Make an array unique by removing duplicate entries.\n * @param ar - Array to make unique\n * @returns A unique array\n */\nexport function uniqueArray<T>(ar: T[]): T[] {\n const j = {};\n ar.forEach((v) => {\n j[`${v}::${typeof v}`] = v;\n });\n return Object.keys(j).map((v) => j[v]);\n}\n\n/**\n * Is Some Of This Array In That Array?\n * Are any of the items in arrayA in arrayB?\n */\nexport function hasItemsInItems<T extends string | number | boolean>(\n arrayA: T[],\n arrayB: T[],\n): boolean {\n return arrayA.some((a) => arrayB.includes(a));\n}\n\n/**\n * Used to ensure that the `id` prop in each object in an array is unique\n */\nexport function assertUniqueIdInArray<T, Key extends string & keyof T>({\n items,\n key,\n errorMsgPrefix,\n}: {\n items: T[] | readonly T[];\n /** Can be `id` or `value` */\n key: Key;\n errorMsgPrefix?: string;\n}) {\n const ids: string[] = [];\n const duplicates: T[] = [];\n items.forEach((item) => {\n const itemKey = String(item[key]);\n if (ids.includes(itemKey)) {\n duplicates.push(item);\n } else {\n ids.push(itemKey);\n }\n });\n if (duplicates.length > 0) {\n const duplicateIdList = duplicates.map((d) => `\"${d[key]}\"`).join(', ');\n throw new Error(\n `${\n errorMsgPrefix ||\n `Each item in the array requires unique \"${key}\" prop.`\n } These ids are duplicates: ${duplicateIdList}`,\n );\n }\n}\n\nexport function isArrayOfStringsUnique(arr: string[]): boolean {\n const unique = new Set(arr);\n return arr.length === unique.size;\n}\n\nexport function getNonUniqueStringsFromArray(arr: string[]): string[] {\n const unique = new Set<string>();\n return arr.filter((a) => {\n if (unique.has(a)) {\n return true;\n }\n unique.add(a);\n return false;\n });\n}\n\n/**\n * Converts an array of objects to a dictionary using a specified key.\n *\n * @see {@link dictionaryToArray}\n *\n * @example\n * const array = [\n * { id: '123', name: 'foo' },\n * { id: '456', name: 'bar' }\n * ];\n * const result = arrayToDictionary(array);\n * // Result: { '123': { name: 'foo' }, '456': { name: 'bar' } }\n *\n * const customResult = arrayToDictionary(array, 'name');\n * // Result: { 'foo': { id: '123' }, 'bar': { id: '456' } }\n */\nexport function arrayToDictionary<\n T extends Record<string, unknown>,\n K extends keyof T & string,\n>(\n /**\n * The array of objects to convert\n */\n array: T[],\n /**\n * The property to use as the dictionary key\n */\n keyProp: K,\n): Record<string, T> {\n return array.reduce(\n (acc, item) => {\n const { [keyProp]: key } = item;\n if (acc[key as string]) {\n throw new Error(`Duplicate key: ${key}`);\n }\n acc[key as string] = item;\n return acc;\n },\n {} as Record<string, T>,\n );\n}\n"]}
|
package/dist/dates.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/dates.ts"],"names":["now","__name","formatDate","date","relative","includeTime","prefix","isValid","dateFormat","output","differenceInSeconds","formatDistanceToNowStrict","isCurrentYear","format","nowInIsoDate","yesterdayInIsoDate","subDays","sortDateAsc","a","b","compareAsc","parseISO","sortDateDesc","compareDesc","minutesFromNowInIsoDate","minutes","toMilliseconds","hours","seconds"],"mappings":"8HAiBO,IAAMA,EAAMC,
|
|
1
|
+
{"version":3,"sources":["../src/dates.ts"],"names":["now","__name","formatDate","date","relative","includeTime","prefix","isValid","dateFormat","output","differenceInSeconds","formatDistanceToNowStrict","isCurrentYear","format","nowInIsoDate","yesterdayInIsoDate","subDays","sortDateAsc","a","b","compareAsc","parseISO","sortDateDesc","compareDesc","minutesFromNowInIsoDate","minutes","toMilliseconds","hours","seconds"],"mappings":"8HAiBO,IAAMA,EAAMC,CAAAA,CAAA,IAAc,IAAI,IAAA,EAAK,CAAE,WAAA,GAAzB,KAAA,EA6BZ,SAASC,EAAW,CACzB,IAAA,CAAAC,EACA,QAAA,CAAAC,CAAAA,CACA,WAAA,CAAAC,CAAAA,CACA,MAAA,CAAAC,CACF,EAKkB,CAChB,GAAI,CAACC,eAAAA,CAAQJ,CAAI,CAAA,CACf,eAAQ,KAAA,CAAM,oCAAA,CAAsCA,CAAI,CAAA,CACjD,IAAA,CAGT,IAAIK,EACAC,CAAAA,CAEJ,GAAIL,EAEFK,CAAAA,CADoB,IAAA,CAAK,IAAIC,2BAAAA,CAAoB,IAAI,IAAA,CAAQP,CAAI,CAAC,CAAA,CAElD,GACV,UAAA,CACAQ,iCAAAA,CAA0BR,CAAAA,CAAM,CAAE,SAAA,CAAW,IAAK,CAAC,CAAA,CAAA,KACpD,CACL,IAAMS,CAAAA,CAAgBT,CAAAA,CAAK,WAAA,KAAkB,IAAI,IAAA,GAAO,WAAA,EAAY,CAChEE,EACFG,CAAAA,CAAaI,CAAAA,CACT,uBAAA,CACA,6BAAA,CAEJJ,CAAAA,CAAaI,CAAAA,CAAgB,SAAW,cAAA,CAE1CH,CAAAA,CAASI,cAAAA,CAAOV,CAAAA,CAAMK,CAAU,EAClC,CAEA,OAAOF,CAAAA,CAAS,CAAA,EAAGA,CAAM,CAAA,CAAA,EAAIG,CAAM,GAAKA,CAC1C,CAtCgBR,EAAAC,CAAAA,CAAA,YAAA,CAAA,KAyCHY,CAAAA,CAAeb,CAAAA,CAAA,IAAc,IAAI,IAAA,EAAK,CAAE,aAAY,CAArC,cAAA,CAAA,CAEfc,CAAAA,CAAqBd,CAAAA,CAAA,IAChCe,eAAAA,CAAQ,IAAI,IAAA,CAAQ,CAAC,CAAA,CAAE,WAAA,EAAY,CADH,oBAAA,EAG3B,SAASC,CAAAA,CAAYC,CAAAA,CAAqBC,EAA6B,CAC5E,OAAOC,mBAAWC,gBAAAA,CAASH,CAAAA,CAAE,IAAI,CAAA,CAAGG,gBAAAA,CAASF,CAAAA,CAAE,IAAI,CAAC,CACtD,CAFgBlB,CAAAA,CAAAgB,CAAAA,CAAA,aAAA,CAAA,CAIT,SAASK,CAAAA,CAAaJ,CAAAA,CAAqBC,CAAAA,CAA6B,CAC7E,OAAOI,mBAAAA,CAAYF,iBAASH,CAAAA,CAAE,IAAI,EAAGG,gBAAAA,CAASF,CAAAA,CAAE,IAAI,CAAC,CACvD,CAFgBlB,CAAAA,CAAAqB,CAAAA,CAAA,cAAA,CAAA,KAIHE,CAAAA,CAA0BvB,CAAAA,CAACwB,CAAAA,EAC/B,IAAI,IAAA,CAAK,IAAA,CAAK,KAAI,CAAIA,CAAAA,CAAU,EAAA,CAAK,GAAI,CAAA,CAAE,WAAA,GADb,yBAAA,EAWhC,SAASC,EAAe,CAC7B,KAAA,CAAAC,EAAQ,CAAA,CACR,OAAA,CAAAF,CAAAA,CAAU,CAAA,CACV,OAAA,CAAAG,CAAAA,CAAU,CACZ,CAAA,CAIG,CAKD,OACED,CAAAA,CAAQ,IAAA,CAAcF,CAAAA,CAAU,IAAgBG,CAAAA,CAAU,GAE9D,CAhBgB3B,CAAAA,CAAAyB,CAAAA,CAAA,gBAAA,CAAA","file":"dates.js","sourcesContent":["import {\n format,\n parseISO,\n compareAsc,\n compareDesc,\n subDays,\n formatDistanceToNowStrict,\n differenceInSeconds,\n isValid,\n} from 'date-fns';\n\n/**\n * ISO date string (`2021-10-15T15:42:43.083Z`)\n */\nexport type DateIsoString =\n `${number}-${number}-${number}T${number}:${number}:${number}.${number}Z`;\n\nexport const now = (): string => new Date().toISOString();\n\n/**\n * Formats a date as a human-readable string.\n *\n * Options:\n * - If `relative` is true, returns a relative time string like:\n * - 'just now' (within 60 seconds)\n * - '4 days ago', 'in 2 hours', etc.\n * - If `relative` is false or omitted:\n * - Dates from the current year are formatted as 'MMM dd' (e.g., 'Apr 16')\n * - Dates from other years are formatted as 'MMM dd, yyyy' (e.g., 'Oct 24, 2024')\n * - If `includeTime` is true, the time is appended (e.g., 'Apr 16 at 03:45 PM')\n *\n * If `prefix` is provided, it will be prepended to the result (e.g., 'Updated Apr 16').\n *\n * If the provided date is invalid, logs an error and returns null.\n *\n * @param date - The date to format\n * @param relative - Whether to format the date as a relative time string\n * @param includeTime - Whether to include time in the formatted date\n * @param prefix - Optional prefix to prepend to the output string\n *\n * @example\n * formatDate({ date: new Date('2025-04-16') }) // 'Apr 16'\n * formatDate({ date: new Date('2024-10-24') }) // 'Oct 24, 2024'\n * formatDate({ date: new Date(), relative: true }) // 'just now'\n * formatDate({ date: new Date(), prefix: 'Updated', relative: true }) // 'Updated just now'\n */\nexport function formatDate({\n date,\n relative,\n includeTime,\n prefix,\n}: {\n date: Date;\n relative?: boolean;\n includeTime?: boolean;\n prefix?: string;\n}): string | null {\n if (!isValid(date)) {\n console.error('formatDate: Invalid date provided:', date);\n return null;\n }\n\n let dateFormat: string;\n let output: string;\n\n if (relative) {\n const secondsDiff = Math.abs(differenceInSeconds(new Date(), date));\n output =\n secondsDiff < 60\n ? 'just now'\n : formatDistanceToNowStrict(date, { addSuffix: true });\n } else {\n const isCurrentYear = date.getFullYear() === new Date().getFullYear();\n if (includeTime) {\n dateFormat = isCurrentYear\n ? `MMM dd 'at' hh:mm aaa`\n : `MMM dd, yyyy 'at' hh:mm aaa`;\n } else {\n dateFormat = isCurrentYear ? 'MMM dd' : 'MMM dd, yyyy';\n }\n output = format(date, dateFormat);\n }\n\n return prefix ? `${prefix} ${output}` : output;\n}\n\n/** Get the ISO date string (`2021-10-15T15:42:43.083Z`) for right now */\nexport const nowInIsoDate = (): string => new Date().toISOString();\n\nexport const yesterdayInIsoDate = (): string =>\n subDays(new Date(), 1).toISOString();\n\nexport function sortDateAsc(a: { date: string }, b: { date: string }): number {\n return compareAsc(parseISO(a.date), parseISO(b.date));\n}\n\nexport function sortDateDesc(a: { date: string }, b: { date: string }): number {\n return compareDesc(parseISO(a.date), parseISO(b.date));\n}\n\nexport const minutesFromNowInIsoDate = (minutes: number): string => {\n return new Date(Date.now() + minutes * 60 * 1000).toISOString();\n};\n\n/**\n * Converts hours, minutes, and seconds to milliseconds\n * @param h - hours (optional)\n * @param m - minutes (optional)\n * @param s - seconds (optional)\n * @returns total milliseconds\n */\nexport function toMilliseconds({\n hours = 0,\n minutes = 0,\n seconds = 0,\n}: {\n hours?: number;\n minutes?: number;\n seconds?: number;\n}) {\n const MS_PER_SECOND = 1000;\n const MS_PER_MINUTE = 60 * MS_PER_SECOND;\n const MS_PER_HOUR = 60 * MS_PER_MINUTE;\n\n return (\n hours * MS_PER_HOUR + minutes * MS_PER_MINUTE + seconds * MS_PER_SECOND\n );\n}\n"]}
|
package/dist/dates.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {isValid,formatDistanceToNowStrict,
|
|
1
|
+
import {isValid,differenceInSeconds,formatDistanceToNowStrict,format,subDays,compareAsc,parseISO,compareDesc}from'date-fns';var m=Object.defineProperty;var n=(t,e)=>m(t,"name",{value:e,configurable:true});var I=n(()=>new Date().toISOString(),"now");function p({date:t,relative:e,includeTime:a,prefix:i}){if(!isValid(t))return console.error("formatDate: Invalid date provided:",t),null;let o,r;if(e)r=Math.abs(differenceInSeconds(new Date,t))<60?"just now":formatDistanceToNowStrict(t,{addSuffix:true});else {let u=t.getFullYear()===new Date().getFullYear();a?o=u?"MMM dd 'at' hh:mm aaa":"MMM dd, yyyy 'at' hh:mm aaa":o=u?"MMM dd":"MMM dd, yyyy",r=format(t,o);}return i?`${i} ${r}`:r}n(p,"formatDate");var _=n(()=>new Date().toISOString(),"nowInIsoDate"),E=n(()=>subDays(new Date,1).toISOString(),"yesterdayInIsoDate");function w(t,e){return compareAsc(parseISO(t.date),parseISO(e.date))}n(w,"sortDateAsc");function y(t,e){return compareDesc(parseISO(t.date),parseISO(e.date))}n(y,"sortDateDesc");var x=n(t=>new Date(Date.now()+t*60*1e3).toISOString(),"minutesFromNowInIsoDate");function O({hours:t=0,minutes:e=0,seconds:a=0}){return t*36e5+e*6e4+a*1e3}n(O,"toMilliseconds");export{p as formatDate,x as minutesFromNowInIsoDate,I as now,_ as nowInIsoDate,w as sortDateAsc,y as sortDateDesc,O as toMilliseconds,E as yesterdayInIsoDate};//# sourceMappingURL=dates.mjs.map
|
|
2
2
|
//# sourceMappingURL=dates.mjs.map
|
package/dist/dates.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/dates.ts"],"names":["now","__name","formatDate","date","relative","includeTime","prefix","isValid","dateFormat","output","differenceInSeconds","formatDistanceToNowStrict","isCurrentYear","format","nowInIsoDate","yesterdayInIsoDate","subDays","sortDateAsc","a","b","compareAsc","parseISO","sortDateDesc","compareDesc","minutesFromNowInIsoDate","minutes","toMilliseconds","hours","seconds"],"mappings":"6MAiBO,IAAMA,EAAMC,
|
|
1
|
+
{"version":3,"sources":["../src/dates.ts"],"names":["now","__name","formatDate","date","relative","includeTime","prefix","isValid","dateFormat","output","differenceInSeconds","formatDistanceToNowStrict","isCurrentYear","format","nowInIsoDate","yesterdayInIsoDate","subDays","sortDateAsc","a","b","compareAsc","parseISO","sortDateDesc","compareDesc","minutesFromNowInIsoDate","minutes","toMilliseconds","hours","seconds"],"mappings":"6MAiBO,IAAMA,EAAMC,CAAAA,CAAA,IAAc,IAAI,IAAA,EAAK,CAAE,WAAA,GAAzB,KAAA,EA6BZ,SAASC,EAAW,CACzB,IAAA,CAAAC,EACA,QAAA,CAAAC,CAAAA,CACA,WAAA,CAAAC,CAAAA,CACA,MAAA,CAAAC,CACF,EAKkB,CAChB,GAAI,CAACC,OAAAA,CAAQJ,CAAI,CAAA,CACf,eAAQ,KAAA,CAAM,oCAAA,CAAsCA,CAAI,CAAA,CACjD,IAAA,CAGT,IAAIK,EACAC,CAAAA,CAEJ,GAAIL,EAEFK,CAAAA,CADoB,IAAA,CAAK,IAAIC,mBAAAA,CAAoB,IAAI,IAAA,CAAQP,CAAI,CAAC,CAAA,CAElD,GACV,UAAA,CACAQ,yBAAAA,CAA0BR,CAAAA,CAAM,CAAE,SAAA,CAAW,IAAK,CAAC,CAAA,CAAA,KACpD,CACL,IAAMS,CAAAA,CAAgBT,CAAAA,CAAK,WAAA,KAAkB,IAAI,IAAA,GAAO,WAAA,EAAY,CAChEE,EACFG,CAAAA,CAAaI,CAAAA,CACT,uBAAA,CACA,6BAAA,CAEJJ,CAAAA,CAAaI,CAAAA,CAAgB,SAAW,cAAA,CAE1CH,CAAAA,CAASI,MAAAA,CAAOV,CAAAA,CAAMK,CAAU,EAClC,CAEA,OAAOF,CAAAA,CAAS,CAAA,EAAGA,CAAM,CAAA,CAAA,EAAIG,CAAM,GAAKA,CAC1C,CAtCgBR,EAAAC,CAAAA,CAAA,YAAA,CAAA,KAyCHY,CAAAA,CAAeb,CAAAA,CAAA,IAAc,IAAI,IAAA,EAAK,CAAE,aAAY,CAArC,cAAA,CAAA,CAEfc,CAAAA,CAAqBd,CAAAA,CAAA,IAChCe,OAAAA,CAAQ,IAAI,IAAA,CAAQ,CAAC,CAAA,CAAE,WAAA,EAAY,CADH,oBAAA,EAG3B,SAASC,CAAAA,CAAYC,CAAAA,CAAqBC,EAA6B,CAC5E,OAAOC,WAAWC,QAAAA,CAASH,CAAAA,CAAE,IAAI,CAAA,CAAGG,QAAAA,CAASF,CAAAA,CAAE,IAAI,CAAC,CACtD,CAFgBlB,CAAAA,CAAAgB,CAAAA,CAAA,aAAA,CAAA,CAIT,SAASK,CAAAA,CAAaJ,CAAAA,CAAqBC,CAAAA,CAA6B,CAC7E,OAAOI,WAAAA,CAAYF,SAASH,CAAAA,CAAE,IAAI,EAAGG,QAAAA,CAASF,CAAAA,CAAE,IAAI,CAAC,CACvD,CAFgBlB,CAAAA,CAAAqB,CAAAA,CAAA,cAAA,CAAA,KAIHE,CAAAA,CAA0BvB,CAAAA,CAACwB,CAAAA,EAC/B,IAAI,IAAA,CAAK,IAAA,CAAK,KAAI,CAAIA,CAAAA,CAAU,EAAA,CAAK,GAAI,CAAA,CAAE,WAAA,GADb,yBAAA,EAWhC,SAASC,EAAe,CAC7B,KAAA,CAAAC,EAAQ,CAAA,CACR,OAAA,CAAAF,CAAAA,CAAU,CAAA,CACV,OAAA,CAAAG,CAAAA,CAAU,CACZ,CAAA,CAIG,CAKD,OACED,CAAAA,CAAQ,IAAA,CAAcF,CAAAA,CAAU,IAAgBG,CAAAA,CAAU,GAE9D,CAhBgB3B,CAAAA,CAAAyB,CAAAA,CAAA,gBAAA,CAAA","file":"dates.mjs","sourcesContent":["import {\n format,\n parseISO,\n compareAsc,\n compareDesc,\n subDays,\n formatDistanceToNowStrict,\n differenceInSeconds,\n isValid,\n} from 'date-fns';\n\n/**\n * ISO date string (`2021-10-15T15:42:43.083Z`)\n */\nexport type DateIsoString =\n `${number}-${number}-${number}T${number}:${number}:${number}.${number}Z`;\n\nexport const now = (): string => new Date().toISOString();\n\n/**\n * Formats a date as a human-readable string.\n *\n * Options:\n * - If `relative` is true, returns a relative time string like:\n * - 'just now' (within 60 seconds)\n * - '4 days ago', 'in 2 hours', etc.\n * - If `relative` is false or omitted:\n * - Dates from the current year are formatted as 'MMM dd' (e.g., 'Apr 16')\n * - Dates from other years are formatted as 'MMM dd, yyyy' (e.g., 'Oct 24, 2024')\n * - If `includeTime` is true, the time is appended (e.g., 'Apr 16 at 03:45 PM')\n *\n * If `prefix` is provided, it will be prepended to the result (e.g., 'Updated Apr 16').\n *\n * If the provided date is invalid, logs an error and returns null.\n *\n * @param date - The date to format\n * @param relative - Whether to format the date as a relative time string\n * @param includeTime - Whether to include time in the formatted date\n * @param prefix - Optional prefix to prepend to the output string\n *\n * @example\n * formatDate({ date: new Date('2025-04-16') }) // 'Apr 16'\n * formatDate({ date: new Date('2024-10-24') }) // 'Oct 24, 2024'\n * formatDate({ date: new Date(), relative: true }) // 'just now'\n * formatDate({ date: new Date(), prefix: 'Updated', relative: true }) // 'Updated just now'\n */\nexport function formatDate({\n date,\n relative,\n includeTime,\n prefix,\n}: {\n date: Date;\n relative?: boolean;\n includeTime?: boolean;\n prefix?: string;\n}): string | null {\n if (!isValid(date)) {\n console.error('formatDate: Invalid date provided:', date);\n return null;\n }\n\n let dateFormat: string;\n let output: string;\n\n if (relative) {\n const secondsDiff = Math.abs(differenceInSeconds(new Date(), date));\n output =\n secondsDiff < 60\n ? 'just now'\n : formatDistanceToNowStrict(date, { addSuffix: true });\n } else {\n const isCurrentYear = date.getFullYear() === new Date().getFullYear();\n if (includeTime) {\n dateFormat = isCurrentYear\n ? `MMM dd 'at' hh:mm aaa`\n : `MMM dd, yyyy 'at' hh:mm aaa`;\n } else {\n dateFormat = isCurrentYear ? 'MMM dd' : 'MMM dd, yyyy';\n }\n output = format(date, dateFormat);\n }\n\n return prefix ? `${prefix} ${output}` : output;\n}\n\n/** Get the ISO date string (`2021-10-15T15:42:43.083Z`) for right now */\nexport const nowInIsoDate = (): string => new Date().toISOString();\n\nexport const yesterdayInIsoDate = (): string =>\n subDays(new Date(), 1).toISOString();\n\nexport function sortDateAsc(a: { date: string }, b: { date: string }): number {\n return compareAsc(parseISO(a.date), parseISO(b.date));\n}\n\nexport function sortDateDesc(a: { date: string }, b: { date: string }): number {\n return compareDesc(parseISO(a.date), parseISO(b.date));\n}\n\nexport const minutesFromNowInIsoDate = (minutes: number): string => {\n return new Date(Date.now() + minutes * 60 * 1000).toISOString();\n};\n\n/**\n * Converts hours, minutes, and seconds to milliseconds\n * @param h - hours (optional)\n * @param m - minutes (optional)\n * @param s - seconds (optional)\n * @returns total milliseconds\n */\nexport function toMilliseconds({\n hours = 0,\n minutes = 0,\n seconds = 0,\n}: {\n hours?: number;\n minutes?: number;\n seconds?: number;\n}) {\n const MS_PER_SECOND = 1000;\n const MS_PER_MINUTE = 60 * MS_PER_SECOND;\n const MS_PER_HOUR = 60 * MS_PER_MINUTE;\n\n return (\n hours * MS_PER_HOUR + minutes * MS_PER_MINUTE + seconds * MS_PER_SECOND\n );\n}\n"]}
|
package/dist/fetcher.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/strings.ts","../src/fetcher.ts"],"names":["isUrl","url","__name","FetcherError","message","status","statusText","cause","fetcher","query","body","customHeaders","signal","method","fetchUrl","u","key","value","error","headers","res","resIsJson","resp","text"],"mappings":"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","file":"fetcher.js","sourcesContent":["import camelCase from 'lodash/camelCase.js';\nimport kebabCase from 'just-kebab-case'; // Why not lodash/kebabCase? https://github.com/lodash/lodash/issues/2843#issuecomment-262255270\nimport upperFirst from 'lodash/upperFirst.js';\nimport { isNode } from './js-env';\nimport { isEmpty } from './type-tools';\n\nexport { default as snakeCase } from 'lodash/snakeCase.js';\nexport { default as capitalize } from 'lodash/capitalize.js';\nexport { camelCase, kebabCase, kebabCase as paramCase };\n\n/**\n * Lower and split on dots, that's it. Do NOT split standalone strings on\n * numbers, caps, etc. Note that we split/join specifically to process each\n * segment of a token name, ie if `color.primary`, we process 'color' and 'primary'\n * individually\n */\nexport const cssKebabCase = (str: string) =>\n str.split('.').map(kebabCase).join('-');\nexport const cssVarName = (name: string) => `--${cssKebabCase(name)}`;\n\n/**\n * This function takes a string and escapes any regex related characters\n * Intended to be used to \"cleanse\" user input of regex that causes failures when using string operators\n */\nexport function escapeRegEx(string: string): string {\n return string.replace(/[*+?^${}()|[\\]\\\\]/g, '\\\\$&'); // $& means the whole matched string\n}\n\n/**\n * Basic \"fuzzy\" search of one string within another.\n * Both the haystack and needle are escaped for regex characters, then converted to lower case\n * If the needle appears in the haystack, will return true, otherwise returns false\n * @param {string} haystack - string to seach within\n * @param {string} needle - string being searched for\n * @returns {boolean}\n */\nexport function containsString(haystack: string, needle: string): boolean {\n const needleNormalized = escapeRegEx(needle).toLowerCase();\n const haystackNormalized = escapeRegEx(haystack).toLowerCase();\n return haystackNormalized.search(needleNormalized) !== -1;\n}\n\nexport function capitalizeFirstLetter(string: string): string {\n return upperFirst(string);\n}\n\nexport function isFirstLetterCapital(str: string): boolean {\n if (!str || str.length === 0) return false;\n return str[0] === str[0].toUpperCase();\n}\n\n/**\n * Transform into a string of capitalized words without separators. How React Component names are transformed.\n * aka PascalCase\n */\nexport function upperCamelCase(str: string): string {\n return capitalizeFirstLetter(camelCase(str));\n}\nexport const pascalCase = upperCamelCase;\n\nexport function base64ToString(b64: string): string {\n return isNode ? Buffer.from(b64, 'base64').toString() : atob(b64);\n}\n\nexport function stringToBase64(string: string): string {\n return isNode ? Buffer.from(string).toString('base64') : btoa(string);\n}\n\n/**\n * check if a value is a valid Base64 string\n */\nexport function isBase64(src: unknown): src is string {\n if (typeof src !== 'string') return false;\n const s = src.replace(/\\s+/g, '').replace(/={0,2}$/, '');\n return !/[^\\s0-9a-zA-Z+/]/.test(s) || !/[^\\s0-9a-zA-Z\\-_]/.test(s);\n}\n\nexport function stringHasSpaces(string: string): boolean {\n return string.indexOf(' ') !== -1;\n}\n\n/**\n * Removes the NPM \"@scope\" in pkg names\n * `@scope/name` => `name`\n * `name` => `name`\n */\nexport function removeNpmScope(pkgName: string): string {\n if (!pkgName.startsWith('@') && !pkgName.includes('/')) {\n return pkgName;\n }\n const [, name] = pkgName.split('/');\n if (!name) return pkgName;\n return name;\n}\n\nexport function isUrl(url: unknown): url is string {\n if (typeof url !== 'string') return false;\n try {\n const _u = new URL(url);\n return true;\n } catch {\n return false;\n }\n}\n// RFC 5322 spec, https://emailregex.com/\nconst emailMatcher =\n /^(([^<>()[\\]\\\\.,;:\\s@\"]+(\\.[^<>()[\\]\\\\.,;:\\s@\"]+)*)|(\".+\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$/;\n/**\n * Check that email is < 320 chars (according to spec), then if passes regex.\n * @link https://www.rfc-editor.org/errata/eid1690#:~:text=It%20should%20say%3A-,In%20addition%20to%20restrictions%20on%20syntax%2C%20there%20is%20a%20length,total%20length%20of%20320%20characters.\n */\nexport const isEmail = (email: unknown): email is string =>\n typeof email === 'string' && email.length <= 320 && emailMatcher.test(email);\n\n/**\n * Returns \"knapsack.cloud\" from \"bloom@knapsack.cloud\", if valid email\n */\nexport const getDomainFromEmail = (email: string): string | null =>\n isEmail(email) ? email.substring(email.indexOf('@') + 1) : null;\n\n/**\n * Basic auth headers are username:password in base64, decode and compare\n */\nexport const decodeBasicAuth = (\n auth: string,\n): { username: string; password: string } => {\n const [username, password] = base64ToString(auth).split(':');\n return { username, password };\n};\n\n/**\n * Parse a string that may contain a unit, like \"10px\" or \"10%\"\n */\nexport function parseNumberWithUnit(value: string | number): {\n value: number;\n unit?: string;\n} {\n const stringValue = String(value).trim();\n const unitRegex = /([a-zA-Z%])+$/;\n const match = stringValue.match(unitRegex);\n\n let numberValue: number;\n let unit: string;\n\n if (match) {\n const unitIndex = match.index;\n numberValue = parseFloat(stringValue.slice(0, unitIndex));\n [unit] = match;\n } else {\n numberValue = parseFloat(stringValue);\n unit = '';\n }\n if (Number.isNaN(numberValue)) {\n throw new Error(`Invalid value, not a number: ${value}`);\n }\n\n return { value: numberValue, unit };\n}\n\n/**\n * Check if a strings first character is a letter\n */\nexport function startsWithLetter(str: string): boolean {\n return /^[a-zA-Z]/.test(str);\n}\n\n/**\n * Removes wrapping single or double quotes from a string\n */\nexport function removeWrappingQuotes(str: string): string {\n if (!str || typeof str !== 'string') return str;\n return (\n str\n // remove double quotes\n .replace(/^\"(.*)\"$/, '$1')\n // remove single quotes\n .replace(/^'(.*)'$/, '$1')\n );\n}\n\n/**\n * Transforms a name string containing key-value pairs into a shortened version.\n *\n * Example:\n * Input: \"mode=dark, status=on, debug=false\"\n * Output: \"dark, status\"\n */\nexport const getShortName = (name: string) => {\n if (!name || isEmpty(name)) return;\n\n if (!name.includes('=')) {\n return name;\n }\n\n const nameParts = name.split(',');\n const shortNameParts: string[] = [];\n\n nameParts.forEach((part) => {\n const [key, value] = part.split('=');\n\n if (!value || ['false', 'off', 'no'].includes(value)) {\n return;\n }\n if (['true', 'on', 'yes'].includes(value)) {\n return shortNameParts.push(key);\n }\n return shortNameParts.push(value);\n });\n return shortNameParts.join(', ');\n};\n","import { isUrl } from './strings';\n\nexport class FetcherError extends Error {\n status?: number;\n statusText?: string;\n url: string;\n constructor(\n message: string,\n {\n status,\n statusText,\n url,\n cause,\n }: { status?: number; statusText?: string; url: string; cause?: Error },\n ) {\n super(message, { cause });\n this.status = status;\n this.statusText = statusText;\n this.url = url;\n }\n}\n\nexport async function fetcher<T = Record<string, unknown>>({\n url,\n query,\n body,\n headers: customHeaders = {},\n signal,\n}: {\n url: string | URL;\n query?: Record<string, string | boolean | number>;\n body?: Record<string, any>;\n headers?: RequestInit['headers'];\n signal?: AbortSignal;\n}): Promise<T> {\n try {\n if (typeof url === 'string' && !isUrl(url)) {\n throw new Error(`Cannot fetch from an invalid url: \"${url}\"`);\n }\n if (typeof url !== 'string' && !(url instanceof URL)) {\n throw new Error(`Url must be a string or URL instance: \"${url}\"`);\n }\n const method = body ? 'POST' : 'GET';\n let fetchUrl = '';\n try {\n const u = url instanceof URL ? url : new URL(url);\n if (query) {\n Object.entries(query).forEach(([key, value]) => {\n if (typeof value === 'undefined') return;\n if (value === null) return;\n u.searchParams.set(key, `${value}`);\n });\n }\n fetchUrl = u.toString();\n } catch (error) {\n throw new Error(\n `Could not start fetcher because was not able to add query params to URL successfully. Url: ${url}, Query params: ${JSON.stringify(\n query ?? {},\n )}. ${error instanceof Error ? error.message : ''}`,\n );\n }\n\n const headers: RequestInit['headers'] = {\n Accept: 'application/json',\n };\n if (body) headers['Content-Type'] = 'application/json';\n\n const res = await fetch(fetchUrl, {\n method,\n headers: { ...headers, ...customHeaders },\n body: body ? JSON.stringify(body) : undefined,\n signal,\n });\n const resIsJson = res.headers.get('Content-Type')?.includes('json');\n\n if (!res.ok) {\n const resp = resIsJson ? await res.json() : {};\n if (resp?.error?.message) {\n throw new FetcherError(resp.error.message, {\n status: res.status,\n statusText: res.statusText,\n url: fetchUrl,\n });\n } else if (resp?.message) {\n throw new FetcherError(resp.message, {\n status: res.status,\n statusText: res.statusText,\n url: fetchUrl,\n });\n } else {\n throw new FetcherError(`${res.statusText} ${res.status}`, {\n status: res.status,\n statusText: res.statusText,\n url: fetchUrl,\n });\n }\n }\n\n if (!resIsJson) {\n const text = await res.text();\n throw new FetcherError(\n `Expected JSON response but received text instead: ${text}`,\n {\n status: res.status,\n statusText: res.statusText,\n url: fetchUrl,\n },\n );\n }\n\n const data: T = await res.json();\n return data;\n } catch (error) {\n if (error instanceof FetcherError) {\n throw error;\n }\n throw new FetcherError(error.message, {\n url: url.toString(),\n cause: error,\n });\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/strings.ts","../src/fetcher.ts"],"names":["isUrl","url","__name","FetcherError","message","status","statusText","cause","fetcher","query","body","customHeaders","signal","method","fetchUrl","u","key","value","error","headers","res","resIsJson","resp","text"],"mappings":"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","file":"fetcher.js","sourcesContent":["import camelCase from 'lodash/camelCase.js';\nimport kebabCase from 'just-kebab-case'; // Why not lodash/kebabCase? https://github.com/lodash/lodash/issues/2843#issuecomment-262255270\nimport upperFirst from 'lodash/upperFirst.js';\nimport { isNode } from './js-env';\nimport { isEmpty } from './type-tools';\n\nexport { default as snakeCase } from 'lodash/snakeCase.js';\nexport { default as capitalize } from 'lodash/capitalize.js';\nexport { camelCase, kebabCase, kebabCase as paramCase };\n\n/**\n * Lower and split on dots, that's it. Do NOT split standalone strings on\n * numbers, caps, etc. Note that we split/join specifically to process each\n * segment of a token name, ie if `color.primary`, we process 'color' and 'primary'\n * individually\n */\nexport const cssKebabCase = (str: string) =>\n str.split('.').map(kebabCase).join('-');\nexport const cssVarName = (name: string) => `--${cssKebabCase(name)}`;\n\n/**\n * This function takes a string and escapes any regex related characters\n * Intended to be used to \"cleanse\" user input of regex that causes failures when using string operators\n */\nexport function escapeRegEx(string: string): string {\n return string.replace(/[*+?^${}()|[\\]\\\\]/g, '\\\\$&'); // $& means the whole matched string\n}\n\n/**\n * Basic \"fuzzy\" search of one string within another.\n * Both the haystack and needle are escaped for regex characters, then converted to lower case\n * If the needle appears in the haystack, will return true, otherwise returns false\n * @param {string} haystack - string to seach within\n * @param {string} needle - string being searched for\n * @returns {boolean}\n */\nexport function containsString(haystack: string, needle: string): boolean {\n const needleNormalized = escapeRegEx(needle).toLowerCase();\n const haystackNormalized = escapeRegEx(haystack).toLowerCase();\n return haystackNormalized.search(needleNormalized) !== -1;\n}\n\nexport function capitalizeFirstLetter(string: string): string {\n return upperFirst(string);\n}\n\nexport function isFirstLetterCapital(str: string): boolean {\n if (!str || str.length === 0) return false;\n return str[0] === str[0].toUpperCase();\n}\n\n/**\n * Transform into a string of capitalized words without separators. How React Component names are transformed.\n * aka PascalCase\n */\nexport function upperCamelCase(str: string): string {\n return capitalizeFirstLetter(camelCase(str));\n}\nexport const pascalCase = upperCamelCase;\n\nexport function base64ToString(b64: string): string {\n return isNode ? Buffer.from(b64, 'base64').toString() : atob(b64);\n}\n\nexport function stringToBase64(string: string): string {\n return isNode ? Buffer.from(string).toString('base64') : btoa(string);\n}\n\n/**\n * check if a value is a valid Base64 string\n */\nexport function isBase64(src: unknown): src is string {\n if (typeof src !== 'string') return false;\n const s = src.replace(/\\s+/g, '').replace(/={0,2}$/, '');\n return !/[^\\s0-9a-zA-Z+/]/.test(s) || !/[^\\s0-9a-zA-Z\\-_]/.test(s);\n}\n\nexport function stringHasSpaces(string: string): boolean {\n return string.indexOf(' ') !== -1;\n}\n\n/**\n * Removes the NPM \"@scope\" in pkg names\n * `@scope/name` => `name`\n * `name` => `name`\n */\nexport function removeNpmScope(pkgName: string): string {\n if (!pkgName.startsWith('@') && !pkgName.includes('/')) {\n return pkgName;\n }\n const [, name] = pkgName.split('/');\n if (!name) return pkgName;\n return name;\n}\n\nexport function isUrl(url: unknown): url is string {\n if (typeof url !== 'string') return false;\n try {\n const _u = new URL(url);\n return true;\n } catch {\n return false;\n }\n}\n// RFC 5322 spec, https://emailregex.com/\nconst emailMatcher =\n /^(([^<>()[\\]\\\\.,;:\\s@\"]+(\\.[^<>()[\\]\\\\.,;:\\s@\"]+)*)|(\".+\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$/;\n/**\n * Check that email is < 320 chars (according to spec), then if passes regex.\n * @link https://www.rfc-editor.org/errata/eid1690#:~:text=It%20should%20say%3A-,In%20addition%20to%20restrictions%20on%20syntax%2C%20there%20is%20a%20length,total%20length%20of%20320%20characters.\n */\nexport const isEmail = (email: unknown): email is string =>\n typeof email === 'string' && email.length <= 320 && emailMatcher.test(email);\n\n/**\n * Returns \"knapsack.cloud\" from \"bloom@knapsack.cloud\", if valid email\n */\nexport const getDomainFromEmail = (email: string): string | null =>\n isEmail(email) ? email.substring(email.indexOf('@') + 1) : null;\n\n/**\n * Basic auth headers are username:password in base64, decode and compare\n */\nexport const decodeBasicAuth = (\n auth: string,\n): { username: string; password: string } => {\n const [username, password] = base64ToString(auth).split(':');\n return { username, password };\n};\n\n/**\n * Parse a string that may contain a unit, like \"10px\" or \"10%\"\n */\nexport function parseNumberWithUnit(value: string | number): {\n value: number;\n unit?: string;\n} {\n const stringValue = String(value).trim();\n const unitRegex = /([a-zA-Z%])+$/;\n const match = stringValue.match(unitRegex);\n\n let numberValue: number;\n let unit: string;\n\n if (match) {\n const unitIndex = match.index;\n numberValue = parseFloat(stringValue.slice(0, unitIndex));\n [unit] = match;\n } else {\n numberValue = parseFloat(stringValue);\n unit = '';\n }\n if (Number.isNaN(numberValue)) {\n throw new Error(`Invalid value, not a number: ${value}`);\n }\n\n return { value: numberValue, unit };\n}\n\n/**\n * Check if a strings first character is a letter\n */\nexport function startsWithLetter(str: string): boolean {\n return /^[a-zA-Z]/.test(str);\n}\n\n/**\n * Removes wrapping single or double quotes from a string\n */\nexport function removeWrappingQuotes(str: string): string {\n if (!str || typeof str !== 'string') return str;\n return (\n str\n // remove double quotes\n .replace(/^\"(.*)\"$/, '$1')\n // remove single quotes\n .replace(/^'(.*)'$/, '$1')\n );\n}\n\n/**\n * Transforms a name string containing key-value pairs into a shortened version.\n *\n * Example:\n * Input: \"mode=dark, status=on, debug=false\"\n * Output: \"dark, status\"\n */\nexport const getShortName = (name: string) => {\n if (!name || isEmpty(name)) return;\n\n if (!name.includes('=')) {\n return name;\n }\n\n const nameParts = name.split(',');\n const shortNameParts: string[] = [];\n\n nameParts.forEach((part) => {\n const [key, value] = part.split('=');\n\n if (!value || ['false', 'off', 'no'].includes(value)) {\n return;\n }\n if (['true', 'on', 'yes'].includes(value)) {\n return shortNameParts.push(key);\n }\n return shortNameParts.push(value);\n });\n return shortNameParts.join(', ');\n};\n","import { isUrl } from './strings';\n\nexport class FetcherError extends Error {\n status?: number;\n statusText?: string;\n url: string;\n constructor(\n message: string,\n {\n status,\n statusText,\n url,\n cause,\n }: { status?: number; statusText?: string; url: string; cause?: Error },\n ) {\n super(message, { cause });\n this.status = status;\n this.statusText = statusText;\n this.url = url;\n }\n}\n\nexport async function fetcher<T = Record<string, unknown>>({\n url,\n query,\n body,\n headers: customHeaders = {},\n signal,\n}: {\n url: string | URL;\n query?: Record<string, string | boolean | number>;\n body?: Record<string, any>;\n headers?: RequestInit['headers'];\n signal?: AbortSignal;\n}): Promise<T> {\n try {\n if (typeof url === 'string' && !isUrl(url)) {\n throw new Error(`Cannot fetch from an invalid url: \"${url}\"`);\n }\n if (typeof url !== 'string' && !(url instanceof URL)) {\n throw new Error(`Url must be a string or URL instance: \"${url}\"`);\n }\n const method = body ? 'POST' : 'GET';\n let fetchUrl = '';\n try {\n const u = url instanceof URL ? url : new URL(url);\n if (query) {\n Object.entries(query).forEach(([key, value]) => {\n if (typeof value === 'undefined') return;\n if (value === null) return;\n u.searchParams.set(key, `${value}`);\n });\n }\n fetchUrl = u.toString();\n } catch (error) {\n throw new Error(\n `Could not start fetcher because was not able to add query params to URL successfully. Url: ${url}, Query params: ${JSON.stringify(\n query ?? {},\n )}. ${error instanceof Error ? error.message : ''}`,\n );\n }\n\n const headers: RequestInit['headers'] = {\n Accept: 'application/json',\n };\n if (body) headers['Content-Type'] = 'application/json';\n\n const res = await fetch(fetchUrl, {\n method,\n headers: { ...headers, ...customHeaders },\n body: body ? JSON.stringify(body) : undefined,\n signal,\n });\n const resIsJson = res.headers.get('Content-Type')?.includes('json');\n\n if (!res.ok) {\n const resp = resIsJson ? await res.json() : {};\n if (resp?.error?.message) {\n throw new FetcherError(resp.error.message, {\n status: res.status,\n statusText: res.statusText,\n url: fetchUrl,\n });\n } else if (resp?.message) {\n throw new FetcherError(resp.message, {\n status: res.status,\n statusText: res.statusText,\n url: fetchUrl,\n });\n } else {\n throw new FetcherError(`${res.statusText} ${res.status}`, {\n status: res.status,\n statusText: res.statusText,\n url: fetchUrl,\n });\n }\n }\n\n if (!resIsJson) {\n const text = await res.text();\n throw new FetcherError(\n `Expected JSON response but received text instead: ${text}`,\n {\n status: res.status,\n statusText: res.statusText,\n url: fetchUrl,\n },\n );\n }\n\n const data: T = await res.json();\n return data;\n } catch (error) {\n if (error instanceof FetcherError) {\n throw error;\n }\n throw new FetcherError(error.message, {\n url: url.toString(),\n cause: error,\n });\n }\n}\n"]}
|
package/dist/fetcher.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/strings.ts","../src/fetcher.ts"],"names":["isUrl","url","__name","FetcherError","message","status","statusText","cause","fetcher","query","body","customHeaders","signal","method","fetchUrl","u","key","value","error","headers","res","resIsJson","resp","text"],"mappings":"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","file":"fetcher.mjs","sourcesContent":["import camelCase from 'lodash/camelCase.js';\nimport kebabCase from 'just-kebab-case'; // Why not lodash/kebabCase? https://github.com/lodash/lodash/issues/2843#issuecomment-262255270\nimport upperFirst from 'lodash/upperFirst.js';\nimport { isNode } from './js-env';\nimport { isEmpty } from './type-tools';\n\nexport { default as snakeCase } from 'lodash/snakeCase.js';\nexport { default as capitalize } from 'lodash/capitalize.js';\nexport { camelCase, kebabCase, kebabCase as paramCase };\n\n/**\n * Lower and split on dots, that's it. Do NOT split standalone strings on\n * numbers, caps, etc. Note that we split/join specifically to process each\n * segment of a token name, ie if `color.primary`, we process 'color' and 'primary'\n * individually\n */\nexport const cssKebabCase = (str: string) =>\n str.split('.').map(kebabCase).join('-');\nexport const cssVarName = (name: string) => `--${cssKebabCase(name)}`;\n\n/**\n * This function takes a string and escapes any regex related characters\n * Intended to be used to \"cleanse\" user input of regex that causes failures when using string operators\n */\nexport function escapeRegEx(string: string): string {\n return string.replace(/[*+?^${}()|[\\]\\\\]/g, '\\\\$&'); // $& means the whole matched string\n}\n\n/**\n * Basic \"fuzzy\" search of one string within another.\n * Both the haystack and needle are escaped for regex characters, then converted to lower case\n * If the needle appears in the haystack, will return true, otherwise returns false\n * @param {string} haystack - string to seach within\n * @param {string} needle - string being searched for\n * @returns {boolean}\n */\nexport function containsString(haystack: string, needle: string): boolean {\n const needleNormalized = escapeRegEx(needle).toLowerCase();\n const haystackNormalized = escapeRegEx(haystack).toLowerCase();\n return haystackNormalized.search(needleNormalized) !== -1;\n}\n\nexport function capitalizeFirstLetter(string: string): string {\n return upperFirst(string);\n}\n\nexport function isFirstLetterCapital(str: string): boolean {\n if (!str || str.length === 0) return false;\n return str[0] === str[0].toUpperCase();\n}\n\n/**\n * Transform into a string of capitalized words without separators. How React Component names are transformed.\n * aka PascalCase\n */\nexport function upperCamelCase(str: string): string {\n return capitalizeFirstLetter(camelCase(str));\n}\nexport const pascalCase = upperCamelCase;\n\nexport function base64ToString(b64: string): string {\n return isNode ? Buffer.from(b64, 'base64').toString() : atob(b64);\n}\n\nexport function stringToBase64(string: string): string {\n return isNode ? Buffer.from(string).toString('base64') : btoa(string);\n}\n\n/**\n * check if a value is a valid Base64 string\n */\nexport function isBase64(src: unknown): src is string {\n if (typeof src !== 'string') return false;\n const s = src.replace(/\\s+/g, '').replace(/={0,2}$/, '');\n return !/[^\\s0-9a-zA-Z+/]/.test(s) || !/[^\\s0-9a-zA-Z\\-_]/.test(s);\n}\n\nexport function stringHasSpaces(string: string): boolean {\n return string.indexOf(' ') !== -1;\n}\n\n/**\n * Removes the NPM \"@scope\" in pkg names\n * `@scope/name` => `name`\n * `name` => `name`\n */\nexport function removeNpmScope(pkgName: string): string {\n if (!pkgName.startsWith('@') && !pkgName.includes('/')) {\n return pkgName;\n }\n const [, name] = pkgName.split('/');\n if (!name) return pkgName;\n return name;\n}\n\nexport function isUrl(url: unknown): url is string {\n if (typeof url !== 'string') return false;\n try {\n const _u = new URL(url);\n return true;\n } catch {\n return false;\n }\n}\n// RFC 5322 spec, https://emailregex.com/\nconst emailMatcher =\n /^(([^<>()[\\]\\\\.,;:\\s@\"]+(\\.[^<>()[\\]\\\\.,;:\\s@\"]+)*)|(\".+\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$/;\n/**\n * Check that email is < 320 chars (according to spec), then if passes regex.\n * @link https://www.rfc-editor.org/errata/eid1690#:~:text=It%20should%20say%3A-,In%20addition%20to%20restrictions%20on%20syntax%2C%20there%20is%20a%20length,total%20length%20of%20320%20characters.\n */\nexport const isEmail = (email: unknown): email is string =>\n typeof email === 'string' && email.length <= 320 && emailMatcher.test(email);\n\n/**\n * Returns \"knapsack.cloud\" from \"bloom@knapsack.cloud\", if valid email\n */\nexport const getDomainFromEmail = (email: string): string | null =>\n isEmail(email) ? email.substring(email.indexOf('@') + 1) : null;\n\n/**\n * Basic auth headers are username:password in base64, decode and compare\n */\nexport const decodeBasicAuth = (\n auth: string,\n): { username: string; password: string } => {\n const [username, password] = base64ToString(auth).split(':');\n return { username, password };\n};\n\n/**\n * Parse a string that may contain a unit, like \"10px\" or \"10%\"\n */\nexport function parseNumberWithUnit(value: string | number): {\n value: number;\n unit?: string;\n} {\n const stringValue = String(value).trim();\n const unitRegex = /([a-zA-Z%])+$/;\n const match = stringValue.match(unitRegex);\n\n let numberValue: number;\n let unit: string;\n\n if (match) {\n const unitIndex = match.index;\n numberValue = parseFloat(stringValue.slice(0, unitIndex));\n [unit] = match;\n } else {\n numberValue = parseFloat(stringValue);\n unit = '';\n }\n if (Number.isNaN(numberValue)) {\n throw new Error(`Invalid value, not a number: ${value}`);\n }\n\n return { value: numberValue, unit };\n}\n\n/**\n * Check if a strings first character is a letter\n */\nexport function startsWithLetter(str: string): boolean {\n return /^[a-zA-Z]/.test(str);\n}\n\n/**\n * Removes wrapping single or double quotes from a string\n */\nexport function removeWrappingQuotes(str: string): string {\n if (!str || typeof str !== 'string') return str;\n return (\n str\n // remove double quotes\n .replace(/^\"(.*)\"$/, '$1')\n // remove single quotes\n .replace(/^'(.*)'$/, '$1')\n );\n}\n\n/**\n * Transforms a name string containing key-value pairs into a shortened version.\n *\n * Example:\n * Input: \"mode=dark, status=on, debug=false\"\n * Output: \"dark, status\"\n */\nexport const getShortName = (name: string) => {\n if (!name || isEmpty(name)) return;\n\n if (!name.includes('=')) {\n return name;\n }\n\n const nameParts = name.split(',');\n const shortNameParts: string[] = [];\n\n nameParts.forEach((part) => {\n const [key, value] = part.split('=');\n\n if (!value || ['false', 'off', 'no'].includes(value)) {\n return;\n }\n if (['true', 'on', 'yes'].includes(value)) {\n return shortNameParts.push(key);\n }\n return shortNameParts.push(value);\n });\n return shortNameParts.join(', ');\n};\n","import { isUrl } from './strings';\n\nexport class FetcherError extends Error {\n status?: number;\n statusText?: string;\n url: string;\n constructor(\n message: string,\n {\n status,\n statusText,\n url,\n cause,\n }: { status?: number; statusText?: string; url: string; cause?: Error },\n ) {\n super(message, { cause });\n this.status = status;\n this.statusText = statusText;\n this.url = url;\n }\n}\n\nexport async function fetcher<T = Record<string, unknown>>({\n url,\n query,\n body,\n headers: customHeaders = {},\n signal,\n}: {\n url: string | URL;\n query?: Record<string, string | boolean | number>;\n body?: Record<string, any>;\n headers?: RequestInit['headers'];\n signal?: AbortSignal;\n}): Promise<T> {\n try {\n if (typeof url === 'string' && !isUrl(url)) {\n throw new Error(`Cannot fetch from an invalid url: \"${url}\"`);\n }\n if (typeof url !== 'string' && !(url instanceof URL)) {\n throw new Error(`Url must be a string or URL instance: \"${url}\"`);\n }\n const method = body ? 'POST' : 'GET';\n let fetchUrl = '';\n try {\n const u = url instanceof URL ? url : new URL(url);\n if (query) {\n Object.entries(query).forEach(([key, value]) => {\n if (typeof value === 'undefined') return;\n if (value === null) return;\n u.searchParams.set(key, `${value}`);\n });\n }\n fetchUrl = u.toString();\n } catch (error) {\n throw new Error(\n `Could not start fetcher because was not able to add query params to URL successfully. Url: ${url}, Query params: ${JSON.stringify(\n query ?? {},\n )}. ${error instanceof Error ? error.message : ''}`,\n );\n }\n\n const headers: RequestInit['headers'] = {\n Accept: 'application/json',\n };\n if (body) headers['Content-Type'] = 'application/json';\n\n const res = await fetch(fetchUrl, {\n method,\n headers: { ...headers, ...customHeaders },\n body: body ? JSON.stringify(body) : undefined,\n signal,\n });\n const resIsJson = res.headers.get('Content-Type')?.includes('json');\n\n if (!res.ok) {\n const resp = resIsJson ? await res.json() : {};\n if (resp?.error?.message) {\n throw new FetcherError(resp.error.message, {\n status: res.status,\n statusText: res.statusText,\n url: fetchUrl,\n });\n } else if (resp?.message) {\n throw new FetcherError(resp.message, {\n status: res.status,\n statusText: res.statusText,\n url: fetchUrl,\n });\n } else {\n throw new FetcherError(`${res.statusText} ${res.status}`, {\n status: res.status,\n statusText: res.statusText,\n url: fetchUrl,\n });\n }\n }\n\n if (!resIsJson) {\n const text = await res.text();\n throw new FetcherError(\n `Expected JSON response but received text instead: ${text}`,\n {\n status: res.status,\n statusText: res.statusText,\n url: fetchUrl,\n },\n );\n }\n\n const data: T = await res.json();\n return data;\n } catch (error) {\n if (error instanceof FetcherError) {\n throw error;\n }\n throw new FetcherError(error.message, {\n url: url.toString(),\n cause: error,\n });\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/strings.ts","../src/fetcher.ts"],"names":["isUrl","url","__name","FetcherError","message","status","statusText","cause","fetcher","query","body","customHeaders","signal","method","fetchUrl","u","key","value","error","headers","res","resIsJson","resp","text"],"mappings":"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","file":"fetcher.mjs","sourcesContent":["import camelCase from 'lodash/camelCase.js';\nimport kebabCase from 'just-kebab-case'; // Why not lodash/kebabCase? https://github.com/lodash/lodash/issues/2843#issuecomment-262255270\nimport upperFirst from 'lodash/upperFirst.js';\nimport { isNode } from './js-env';\nimport { isEmpty } from './type-tools';\n\nexport { default as snakeCase } from 'lodash/snakeCase.js';\nexport { default as capitalize } from 'lodash/capitalize.js';\nexport { camelCase, kebabCase, kebabCase as paramCase };\n\n/**\n * Lower and split on dots, that's it. Do NOT split standalone strings on\n * numbers, caps, etc. Note that we split/join specifically to process each\n * segment of a token name, ie if `color.primary`, we process 'color' and 'primary'\n * individually\n */\nexport const cssKebabCase = (str: string) =>\n str.split('.').map(kebabCase).join('-');\nexport const cssVarName = (name: string) => `--${cssKebabCase(name)}`;\n\n/**\n * This function takes a string and escapes any regex related characters\n * Intended to be used to \"cleanse\" user input of regex that causes failures when using string operators\n */\nexport function escapeRegEx(string: string): string {\n return string.replace(/[*+?^${}()|[\\]\\\\]/g, '\\\\$&'); // $& means the whole matched string\n}\n\n/**\n * Basic \"fuzzy\" search of one string within another.\n * Both the haystack and needle are escaped for regex characters, then converted to lower case\n * If the needle appears in the haystack, will return true, otherwise returns false\n * @param {string} haystack - string to seach within\n * @param {string} needle - string being searched for\n * @returns {boolean}\n */\nexport function containsString(haystack: string, needle: string): boolean {\n const needleNormalized = escapeRegEx(needle).toLowerCase();\n const haystackNormalized = escapeRegEx(haystack).toLowerCase();\n return haystackNormalized.search(needleNormalized) !== -1;\n}\n\nexport function capitalizeFirstLetter(string: string): string {\n return upperFirst(string);\n}\n\nexport function isFirstLetterCapital(str: string): boolean {\n if (!str || str.length === 0) return false;\n return str[0] === str[0].toUpperCase();\n}\n\n/**\n * Transform into a string of capitalized words without separators. How React Component names are transformed.\n * aka PascalCase\n */\nexport function upperCamelCase(str: string): string {\n return capitalizeFirstLetter(camelCase(str));\n}\nexport const pascalCase = upperCamelCase;\n\nexport function base64ToString(b64: string): string {\n return isNode ? Buffer.from(b64, 'base64').toString() : atob(b64);\n}\n\nexport function stringToBase64(string: string): string {\n return isNode ? Buffer.from(string).toString('base64') : btoa(string);\n}\n\n/**\n * check if a value is a valid Base64 string\n */\nexport function isBase64(src: unknown): src is string {\n if (typeof src !== 'string') return false;\n const s = src.replace(/\\s+/g, '').replace(/={0,2}$/, '');\n return !/[^\\s0-9a-zA-Z+/]/.test(s) || !/[^\\s0-9a-zA-Z\\-_]/.test(s);\n}\n\nexport function stringHasSpaces(string: string): boolean {\n return string.indexOf(' ') !== -1;\n}\n\n/**\n * Removes the NPM \"@scope\" in pkg names\n * `@scope/name` => `name`\n * `name` => `name`\n */\nexport function removeNpmScope(pkgName: string): string {\n if (!pkgName.startsWith('@') && !pkgName.includes('/')) {\n return pkgName;\n }\n const [, name] = pkgName.split('/');\n if (!name) return pkgName;\n return name;\n}\n\nexport function isUrl(url: unknown): url is string {\n if (typeof url !== 'string') return false;\n try {\n const _u = new URL(url);\n return true;\n } catch {\n return false;\n }\n}\n// RFC 5322 spec, https://emailregex.com/\nconst emailMatcher =\n /^(([^<>()[\\]\\\\.,;:\\s@\"]+(\\.[^<>()[\\]\\\\.,;:\\s@\"]+)*)|(\".+\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}])|(([a-zA-Z\\-0-9]+\\.)+[a-zA-Z]{2,}))$/;\n/**\n * Check that email is < 320 chars (according to spec), then if passes regex.\n * @link https://www.rfc-editor.org/errata/eid1690#:~:text=It%20should%20say%3A-,In%20addition%20to%20restrictions%20on%20syntax%2C%20there%20is%20a%20length,total%20length%20of%20320%20characters.\n */\nexport const isEmail = (email: unknown): email is string =>\n typeof email === 'string' && email.length <= 320 && emailMatcher.test(email);\n\n/**\n * Returns \"knapsack.cloud\" from \"bloom@knapsack.cloud\", if valid email\n */\nexport const getDomainFromEmail = (email: string): string | null =>\n isEmail(email) ? email.substring(email.indexOf('@') + 1) : null;\n\n/**\n * Basic auth headers are username:password in base64, decode and compare\n */\nexport const decodeBasicAuth = (\n auth: string,\n): { username: string; password: string } => {\n const [username, password] = base64ToString(auth).split(':');\n return { username, password };\n};\n\n/**\n * Parse a string that may contain a unit, like \"10px\" or \"10%\"\n */\nexport function parseNumberWithUnit(value: string | number): {\n value: number;\n unit?: string;\n} {\n const stringValue = String(value).trim();\n const unitRegex = /([a-zA-Z%])+$/;\n const match = stringValue.match(unitRegex);\n\n let numberValue: number;\n let unit: string;\n\n if (match) {\n const unitIndex = match.index;\n numberValue = parseFloat(stringValue.slice(0, unitIndex));\n [unit] = match;\n } else {\n numberValue = parseFloat(stringValue);\n unit = '';\n }\n if (Number.isNaN(numberValue)) {\n throw new Error(`Invalid value, not a number: ${value}`);\n }\n\n return { value: numberValue, unit };\n}\n\n/**\n * Check if a strings first character is a letter\n */\nexport function startsWithLetter(str: string): boolean {\n return /^[a-zA-Z]/.test(str);\n}\n\n/**\n * Removes wrapping single or double quotes from a string\n */\nexport function removeWrappingQuotes(str: string): string {\n if (!str || typeof str !== 'string') return str;\n return (\n str\n // remove double quotes\n .replace(/^\"(.*)\"$/, '$1')\n // remove single quotes\n .replace(/^'(.*)'$/, '$1')\n );\n}\n\n/**\n * Transforms a name string containing key-value pairs into a shortened version.\n *\n * Example:\n * Input: \"mode=dark, status=on, debug=false\"\n * Output: \"dark, status\"\n */\nexport const getShortName = (name: string) => {\n if (!name || isEmpty(name)) return;\n\n if (!name.includes('=')) {\n return name;\n }\n\n const nameParts = name.split(',');\n const shortNameParts: string[] = [];\n\n nameParts.forEach((part) => {\n const [key, value] = part.split('=');\n\n if (!value || ['false', 'off', 'no'].includes(value)) {\n return;\n }\n if (['true', 'on', 'yes'].includes(value)) {\n return shortNameParts.push(key);\n }\n return shortNameParts.push(value);\n });\n return shortNameParts.join(', ');\n};\n","import { isUrl } from './strings';\n\nexport class FetcherError extends Error {\n status?: number;\n statusText?: string;\n url: string;\n constructor(\n message: string,\n {\n status,\n statusText,\n url,\n cause,\n }: { status?: number; statusText?: string; url: string; cause?: Error },\n ) {\n super(message, { cause });\n this.status = status;\n this.statusText = statusText;\n this.url = url;\n }\n}\n\nexport async function fetcher<T = Record<string, unknown>>({\n url,\n query,\n body,\n headers: customHeaders = {},\n signal,\n}: {\n url: string | URL;\n query?: Record<string, string | boolean | number>;\n body?: Record<string, any>;\n headers?: RequestInit['headers'];\n signal?: AbortSignal;\n}): Promise<T> {\n try {\n if (typeof url === 'string' && !isUrl(url)) {\n throw new Error(`Cannot fetch from an invalid url: \"${url}\"`);\n }\n if (typeof url !== 'string' && !(url instanceof URL)) {\n throw new Error(`Url must be a string or URL instance: \"${url}\"`);\n }\n const method = body ? 'POST' : 'GET';\n let fetchUrl = '';\n try {\n const u = url instanceof URL ? url : new URL(url);\n if (query) {\n Object.entries(query).forEach(([key, value]) => {\n if (typeof value === 'undefined') return;\n if (value === null) return;\n u.searchParams.set(key, `${value}`);\n });\n }\n fetchUrl = u.toString();\n } catch (error) {\n throw new Error(\n `Could not start fetcher because was not able to add query params to URL successfully. Url: ${url}, Query params: ${JSON.stringify(\n query ?? {},\n )}. ${error instanceof Error ? error.message : ''}`,\n );\n }\n\n const headers: RequestInit['headers'] = {\n Accept: 'application/json',\n };\n if (body) headers['Content-Type'] = 'application/json';\n\n const res = await fetch(fetchUrl, {\n method,\n headers: { ...headers, ...customHeaders },\n body: body ? JSON.stringify(body) : undefined,\n signal,\n });\n const resIsJson = res.headers.get('Content-Type')?.includes('json');\n\n if (!res.ok) {\n const resp = resIsJson ? await res.json() : {};\n if (resp?.error?.message) {\n throw new FetcherError(resp.error.message, {\n status: res.status,\n statusText: res.statusText,\n url: fetchUrl,\n });\n } else if (resp?.message) {\n throw new FetcherError(resp.message, {\n status: res.status,\n statusText: res.statusText,\n url: fetchUrl,\n });\n } else {\n throw new FetcherError(`${res.statusText} ${res.status}`, {\n status: res.status,\n statusText: res.statusText,\n url: fetchUrl,\n });\n }\n }\n\n if (!resIsJson) {\n const text = await res.text();\n throw new FetcherError(\n `Expected JSON response but received text instead: ${text}`,\n {\n status: res.status,\n statusText: res.statusText,\n url: fetchUrl,\n },\n );\n }\n\n const data: T = await res.json();\n return data;\n } catch (error) {\n if (error instanceof FetcherError) {\n throw error;\n }\n throw new FetcherError(error.message, {\n url: url.toString(),\n cause: error,\n });\n }\n}\n"]}
|
package/dist/functions.d.ts
CHANGED
|
@@ -19,16 +19,30 @@ type Failure<E> = {
|
|
|
19
19
|
};
|
|
20
20
|
type Result<T, E = Error> = Success<T> | Failure<E>;
|
|
21
21
|
/**
|
|
22
|
-
* Wraps a promise in a try/catch and returns a result object with the data or error
|
|
22
|
+
* Wraps a function or promise in a try/catch and returns a result object with the data or error.
|
|
23
|
+
*
|
|
24
|
+
* Works with both sync and async functions:
|
|
25
|
+
* - Sync functions return `Result<T, E>` directly
|
|
26
|
+
* - Async functions/promises return `Promise<Result<T, E>>`
|
|
23
27
|
*
|
|
24
28
|
* As long as `strictNullChecks: true` then doing something like `if (error) throw error` is required to use `data`
|
|
25
29
|
*
|
|
26
30
|
* @example
|
|
31
|
+
* // Async usage
|
|
27
32
|
* const { data, error } = await tryCatch(() => someAsyncFunction({ id: 42 }));
|
|
28
33
|
* if (error) {
|
|
29
34
|
* throw error;
|
|
30
35
|
* }
|
|
31
36
|
* data.info;
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* // Sync usage
|
|
40
|
+
* const { data, error } = tryCatch(() => JSON.parse(jsonString));
|
|
41
|
+
* if (error) {
|
|
42
|
+
* console.error('Invalid JSON');
|
|
43
|
+
* }
|
|
32
44
|
*/
|
|
45
|
+
export declare function tryCatch<T, E = Error>(fn: () => Promise<T>): Promise<Result<T, E>>;
|
|
33
46
|
export declare function tryCatch<T, E = Error>(promise: Promise<T>): Promise<Result<T, E>>;
|
|
47
|
+
export declare function tryCatch<T, E = Error>(fn: () => T): Result<T, E>;
|
|
34
48
|
//# sourceMappingURL=functions.d.ts.map
|
package/dist/functions.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"functions.d.ts","sourceRoot":"","sources":["../src/functions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAGzD,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAE7C;;;;GAIG;AACH,eAAO,MAAM,KAAK,GAAI,IAAI,MAAM,qBAA0C,CAAC;AAG3E,KAAK,OAAO,CAAC,CAAC,IAAI;IAChB,IAAI,EAAE,CAAC,CAAC;IACR,KAAK,EAAE,IAAI,CAAC;CACb,CAAC;AAEF,KAAK,OAAO,CAAC,CAAC,IAAI;IAChB,IAAI,EAAE,IAAI,CAAC;IACX,KAAK,EAAE,CAAC,CAAC;CACV,CAAC;AAEF,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,KAAK,IAAI,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;AAEpD
|
|
1
|
+
{"version":3,"file":"functions.d.ts","sourceRoot":"","sources":["../src/functions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAGzD,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAE7C;;;;GAIG;AACH,eAAO,MAAM,KAAK,GAAI,IAAI,MAAM,qBAA0C,CAAC;AAG3E,KAAK,OAAO,CAAC,CAAC,IAAI;IAChB,IAAI,EAAE,CAAC,CAAC;IACR,KAAK,EAAE,IAAI,CAAC;CACb,CAAC;AAEF,KAAK,OAAO,CAAC,CAAC,IAAI;IAChB,IAAI,EAAE,IAAI,CAAC;IACX,KAAK,EAAE,CAAC,CAAC;CACV,CAAC;AAEF,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,KAAK,IAAI,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;AAEpD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,KAAK,EACnC,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACnB,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAEzB,wBAAgB,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,KAAK,EACnC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAClB,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAEzB,wBAAgB,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC"}
|
package/dist/functions.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
'use strict';var debounce_js=require('lodash/debounce.js'),throttle_js=require('lodash/throttle.js'),memoizee=require('memoizee'),profile_js=require('memoizee/profile.js'),function_js=require('fp-ts/lib/function.js');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var debounce_js__default=/*#__PURE__*/_interopDefault(debounce_js);var throttle_js__default=/*#__PURE__*/_interopDefault(throttle_js);var memoizee__default=/*#__PURE__*/_interopDefault(memoizee);var profile_js__default=/*#__PURE__*/_interopDefault(profile_js);var
|
|
1
|
+
'use strict';var debounce_js=require('lodash/debounce.js'),throttle_js=require('lodash/throttle.js'),memoizee=require('memoizee'),profile_js=require('memoizee/profile.js'),function_js=require('fp-ts/lib/function.js');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var debounce_js__default=/*#__PURE__*/_interopDefault(debounce_js);var throttle_js__default=/*#__PURE__*/_interopDefault(throttle_js);var memoizee__default=/*#__PURE__*/_interopDefault(memoizee);var profile_js__default=/*#__PURE__*/_interopDefault(profile_js);var u=Object.defineProperty;var o=(e,r)=>u(e,"name",{value:r,configurable:true});var a=o(e=>new Promise(r=>setTimeout(r,e)),"delay");function n(e){if(typeof e=="function")try{let r=e();return r instanceof Promise?r.then(t=>({data:t,error:null}),t=>({data:null,error:t})):{data:r,error:null}}catch(r){return {data:null,error:r}}return e.then(r=>({data:r,error:null}),r=>({data:null,error:r}))}o(n,"tryCatch");Object.defineProperty(exports,"debounce",{enumerable:true,get:function(){return debounce_js__default.default}});Object.defineProperty(exports,"throttle",{enumerable:true,get:function(){return throttle_js__default.default}});Object.defineProperty(exports,"memoize",{enumerable:true,get:function(){return memoizee__default.default}});Object.defineProperty(exports,"memoizeeProfile",{enumerable:true,get:function(){return profile_js__default.default}});Object.defineProperty(exports,"flow",{enumerable:true,get:function(){return function_js.flow}});exports.delay=a;exports.tryCatch=n;//# sourceMappingURL=functions.js.map
|
|
2
2
|
//# sourceMappingURL=functions.js.map
|
package/dist/functions.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/functions.ts"],"names":["delay","__name","ms","tryCatch","
|
|
1
|
+
{"version":3,"sources":["../src/functions.ts"],"names":["delay","__name","ms","tryCatch","promiseOrFn","result","data","error"],"mappings":"+mBAaO,IAAMA,CAAAA,CAAQC,CAAAA,CAACC,CAAAA,EAAe,IAAI,QAAS,CAAA,EAAM,UAAA,CAAW,EAAGA,CAAE,CAAC,EAApD,OAAA,EAkDd,SAASC,CAAAA,CACdC,CAAAA,CACsC,CACtC,GAAI,OAAOA,CAAAA,EAAgB,UAAA,CACzB,GAAI,CACF,IAAMC,CAAAA,CAASD,GAAY,CAE3B,OAAIC,CAAAA,YAAkB,OAAA,CACbA,CAAAA,CAAO,IAAA,CACXC,IAAU,CAAE,IAAA,CAAAA,EAAM,KAAA,CAAO,IAAK,GAC9BC,CAAAA,GAAW,CAAE,IAAA,CAAM,IAAA,CAAM,KAAA,CAAOA,CAAW,EAC9C,CAAA,CAEK,CAAE,IAAA,CAAMF,CAAAA,CAAQ,KAAA,CAAO,IAAK,CACrC,CAAA,MAASE,CAAAA,CAAO,CACd,OAAO,CAAE,IAAA,CAAM,KAAM,KAAA,CAAOA,CAAW,CACzC,CAGF,OAAOH,EAAY,IAAA,CAChBE,CAAAA,GAAU,CAAE,IAAA,CAAAA,CAAAA,CAAM,KAAA,CAAO,IAAK,CAAA,CAAA,CAC9BC,CAAAA,GAAW,CAAE,IAAA,CAAM,IAAA,CAAM,KAAA,CAAOA,CAAW,CAAA,CAC9C,CACF,CAvBgBN,CAAAA,CAAAE,CAAAA,CAAA,UAAA,CAAA","file":"functions.js","sourcesContent":["export { default as debounce } from 'lodash/debounce.js';\nexport { default as throttle } from 'lodash/throttle.js';\n\n// https://www.npmjs.com/package/memoizee\nexport { default as memoize } from 'memoizee';\nexport { default as memoizeeProfile } from 'memoizee/profile.js';\nexport { flow } from 'fp-ts/lib/function.js';\n\n/**\n * Create a fake time delay in an async function useful for testing\n * @example\n * await delay(1000);\n */\nexport const delay = (ms: number) => new Promise((r) => setTimeout(r, ms));\n\n// Types for the result object with discriminated union\ntype Success<T> = {\n data: T;\n error: null;\n};\n\ntype Failure<E> = {\n data: null;\n error: E;\n};\n\ntype Result<T, E = Error> = Success<T> | Failure<E>;\n\n/**\n * Wraps a function or promise in a try/catch and returns a result object with the data or error.\n *\n * Works with both sync and async functions:\n * - Sync functions return `Result<T, E>` directly\n * - Async functions/promises return `Promise<Result<T, E>>`\n *\n * As long as `strictNullChecks: true` then doing something like `if (error) throw error` is required to use `data`\n *\n * @example\n * // Async usage\n * const { data, error } = await tryCatch(() => someAsyncFunction({ id: 42 }));\n * if (error) {\n * throw error;\n * }\n * data.info;\n *\n * @example\n * // Sync usage\n * const { data, error } = tryCatch(() => JSON.parse(jsonString));\n * if (error) {\n * console.error('Invalid JSON');\n * }\n */\n// Overload: async function returning Promise<T>\nexport function tryCatch<T, E = Error>(\n fn: () => Promise<T>,\n): Promise<Result<T, E>>;\n// Overload: direct Promise<T>\nexport function tryCatch<T, E = Error>(\n promise: Promise<T>,\n): Promise<Result<T, E>>;\n// Overload: sync function returning T\nexport function tryCatch<T, E = Error>(fn: () => T): Result<T, E>;\n// Implementation\nexport function tryCatch<T, E = Error>(\n promiseOrFn: Promise<T> | (() => T | Promise<T>),\n): Result<T, E> | Promise<Result<T, E>> {\n if (typeof promiseOrFn === 'function') {\n try {\n const result = promiseOrFn();\n // If the function returned a promise, handle it asynchronously\n if (result instanceof Promise) {\n return result.then(\n (data) => ({ data, error: null }),\n (error) => ({ data: null, error: error as E }),\n );\n }\n return { data: result, error: null };\n } catch (error) {\n return { data: null, error: error as E };\n }\n }\n // It's a promise\n return promiseOrFn.then(\n (data) => ({ data, error: null }),\n (error) => ({ data: null, error: error as E }),\n );\n}\n"]}
|
package/dist/functions.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export{default as debounce}from'lodash/debounce.js';export{default as throttle}from'lodash/throttle.js';export{default as memoize}from'memoizee';export{default as memoizeeProfile}from'memoizee/profile.js';export{flow}from'fp-ts/lib/function.js';var
|
|
1
|
+
export{default as debounce}from'lodash/debounce.js';export{default as throttle}from'lodash/throttle.js';export{default as memoize}from'memoizee';export{default as memoizeeProfile}from'memoizee/profile.js';export{flow}from'fp-ts/lib/function.js';var u=Object.defineProperty;var o=(e,r)=>u(e,"name",{value:r,configurable:true});var a=o(e=>new Promise(r=>setTimeout(r,e)),"delay");function n(e){if(typeof e=="function")try{let r=e();return r instanceof Promise?r.then(t=>({data:t,error:null}),t=>({data:null,error:t})):{data:r,error:null}}catch(r){return {data:null,error:r}}return e.then(r=>({data:r,error:null}),r=>({data:null,error:r}))}o(n,"tryCatch");export{a as delay,n as tryCatch};//# sourceMappingURL=functions.mjs.map
|
|
2
2
|
//# sourceMappingURL=functions.mjs.map
|
package/dist/functions.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/functions.ts"],"names":["delay","__name","ms","tryCatch","
|
|
1
|
+
{"version":3,"sources":["../src/functions.ts"],"names":["delay","__name","ms","tryCatch","promiseOrFn","result","data","error"],"mappings":"sUAaO,IAAMA,CAAAA,CAAQC,CAAAA,CAACC,CAAAA,EAAe,IAAI,QAAS,CAAA,EAAM,UAAA,CAAW,EAAGA,CAAE,CAAC,EAApD,OAAA,EAkDd,SAASC,CAAAA,CACdC,CAAAA,CACsC,CACtC,GAAI,OAAOA,CAAAA,EAAgB,UAAA,CACzB,GAAI,CACF,IAAMC,CAAAA,CAASD,GAAY,CAE3B,OAAIC,CAAAA,YAAkB,OAAA,CACbA,CAAAA,CAAO,IAAA,CACXC,IAAU,CAAE,IAAA,CAAAA,EAAM,KAAA,CAAO,IAAK,GAC9BC,CAAAA,GAAW,CAAE,IAAA,CAAM,IAAA,CAAM,KAAA,CAAOA,CAAW,EAC9C,CAAA,CAEK,CAAE,IAAA,CAAMF,CAAAA,CAAQ,KAAA,CAAO,IAAK,CACrC,CAAA,MAASE,CAAAA,CAAO,CACd,OAAO,CAAE,IAAA,CAAM,KAAM,KAAA,CAAOA,CAAW,CACzC,CAGF,OAAOH,EAAY,IAAA,CAChBE,CAAAA,GAAU,CAAE,IAAA,CAAAA,CAAAA,CAAM,KAAA,CAAO,IAAK,CAAA,CAAA,CAC9BC,CAAAA,GAAW,CAAE,IAAA,CAAM,IAAA,CAAM,KAAA,CAAOA,CAAW,CAAA,CAC9C,CACF,CAvBgBN,CAAAA,CAAAE,CAAAA,CAAA,UAAA,CAAA","file":"functions.mjs","sourcesContent":["export { default as debounce } from 'lodash/debounce.js';\nexport { default as throttle } from 'lodash/throttle.js';\n\n// https://www.npmjs.com/package/memoizee\nexport { default as memoize } from 'memoizee';\nexport { default as memoizeeProfile } from 'memoizee/profile.js';\nexport { flow } from 'fp-ts/lib/function.js';\n\n/**\n * Create a fake time delay in an async function useful for testing\n * @example\n * await delay(1000);\n */\nexport const delay = (ms: number) => new Promise((r) => setTimeout(r, ms));\n\n// Types for the result object with discriminated union\ntype Success<T> = {\n data: T;\n error: null;\n};\n\ntype Failure<E> = {\n data: null;\n error: E;\n};\n\ntype Result<T, E = Error> = Success<T> | Failure<E>;\n\n/**\n * Wraps a function or promise in a try/catch and returns a result object with the data or error.\n *\n * Works with both sync and async functions:\n * - Sync functions return `Result<T, E>` directly\n * - Async functions/promises return `Promise<Result<T, E>>`\n *\n * As long as `strictNullChecks: true` then doing something like `if (error) throw error` is required to use `data`\n *\n * @example\n * // Async usage\n * const { data, error } = await tryCatch(() => someAsyncFunction({ id: 42 }));\n * if (error) {\n * throw error;\n * }\n * data.info;\n *\n * @example\n * // Sync usage\n * const { data, error } = tryCatch(() => JSON.parse(jsonString));\n * if (error) {\n * console.error('Invalid JSON');\n * }\n */\n// Overload: async function returning Promise<T>\nexport function tryCatch<T, E = Error>(\n fn: () => Promise<T>,\n): Promise<Result<T, E>>;\n// Overload: direct Promise<T>\nexport function tryCatch<T, E = Error>(\n promise: Promise<T>,\n): Promise<Result<T, E>>;\n// Overload: sync function returning T\nexport function tryCatch<T, E = Error>(fn: () => T): Result<T, E>;\n// Implementation\nexport function tryCatch<T, E = Error>(\n promiseOrFn: Promise<T> | (() => T | Promise<T>),\n): Result<T, E> | Promise<Result<T, E>> {\n if (typeof promiseOrFn === 'function') {\n try {\n const result = promiseOrFn();\n // If the function returned a promise, handle it asynchronously\n if (result instanceof Promise) {\n return result.then(\n (data) => ({ data, error: null }),\n (error) => ({ data: null, error: error as E }),\n );\n }\n return { data: result, error: null };\n } catch (error) {\n return { data: null, error: error as E };\n }\n }\n // It's a promise\n return promiseOrFn.then(\n (data) => ({ data, error: null }),\n (error) => ({ data: null, error: error as E }),\n );\n}\n"]}
|
package/dist/ids.d.ts
CHANGED
package/dist/ids.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ids.d.ts","sourceRoot":"","sources":["../src/ids.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,QAAQ,
|
|
1
|
+
{"version":3,"file":"ids.d.ts","sourceRoot":"","sources":["../src/ids.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,QAAQ,cAAiB,CAAC;AACvC,eAAO,MAAM,UAAU,cAAiB,CAAC;AAEzC;;GAEG;AACH,eAAO,MAAM,WAAW,cAIpB,CAAC"}
|
package/dist/ids.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
'use strict';var nanoid=require('nanoid'),uuid=require('uuid'),a=require('slugify');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var a__default=/*#__PURE__*/_interopDefault(a);var o=Object.defineProperty;var
|
|
1
|
+
'use strict';var nanoid=require('nanoid'),uuid=require('uuid'),a=require('slugify');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var a__default=/*#__PURE__*/_interopDefault(a);var o=Object.defineProperty;var t=(r,e)=>o(r,"name",{value:e,configurable:true});var n=t(r=>{let{string:e,strict:s=true,lowerCase:i=true}=typeof r=="string"?{string:r}:r;return a__default.default(e,{lower:i,trim:true,strict:s})},"slugify");var P=t(()=>uuid.v4(),"makeUuid"),U=t(()=>uuid.v7(),"makeUuidV7"),x=t(()=>n({string:nanoid.nanoid(10),lowerCase:false}),"makeShortId");exports.makeShortId=x;exports.makeUuid=P;exports.makeUuidV7=U;//# sourceMappingURL=ids.js.map
|
|
2
2
|
//# sourceMappingURL=ids.js.map
|
package/dist/ids.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/ids.ts","../src/urls.ts"],"names":["slugify","__name","opt","string","strict","lowerCase","slugifyBase","makeUuid","
|
|
1
|
+
{"version":3,"sources":["../src/ids.ts","../src/urls.ts"],"names":["slugify","__name","opt","string","strict","lowerCase","slugifyBase","makeUuid","uuidV4","makeUuidV7","uuidV7","makeShortId","nanoid"],"mappings":"oMAAA,IAAA,CAAA,CAAA,MAAA,CAAA,cAAA,CAAA,IAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,GAAA,CAAA,CAAA,CAAA,CAAA,MAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,YAAA,CAAA,IAAA,CAAA,CAAA,CC+IO,IAAMA,CAAAA,CAAUC,EACrBC,CAAAA,EAWW,CACX,GAAM,CACJ,OAAAC,CAAAA,CACA,MAAA,CAAAC,CAAAA,CAAS,IAAA,CACT,UAAAC,CAAAA,CAAY,IACd,CAAA,CAAI,OAAOH,GAAQ,QAAA,CAAW,CAAE,MAAA,CAAQA,CAAI,EAAIA,CAAAA,CAChD,OAAOI,kBAAAA,CAAYH,CAAAA,CAAQ,CACzB,KAAA,CAAOE,CAAAA,CACP,IAAA,CAAM,IAAA,CACN,OAAAD,CACF,CAAC,CACH,CAAA,CAvBuB,WD3IhB,IAAMG,CAAAA,CAAWN,CAAAA,CAAA,IAAMO,SAAO,CAAb,UAAA,CAAA,CACXC,CAAAA,CAAaR,CAAAA,CAAA,IAAMS,OAAAA,EAAO,CAAb,YAAA,CAAA,CAKbC,CAAAA,CAAcV,EAAA,IACzBD,CAAAA,CAAQ,CACN,MAAA,CAAQY,cAAO,EAAE,CAAA,CACjB,SAAA,CAAW,KACb,CAAC,CAAA,CAJwB,aAAA","file":"ids.js","sourcesContent":["import { nanoid } from 'nanoid';\nimport { v4 as uuidV4, v7 as uuidV7 } from 'uuid';\nimport { slugify } from './urls';\n\nexport const makeUuid = () => uuidV4();\nexport const makeUuidV7 = () => uuidV7();\n\n/**\n * Short ID that is also slugified\n */\nexport const makeShortId = () =>\n slugify({\n string: nanoid(10),\n lowerCase: false,\n });\n","import slugifyBase from 'slugify';\n\nexport type QueryParamsInput = Record<\n string,\n string | number | boolean | undefined | null | string[] | URL\n>;\n\n/**\n * Util to add query params in a type safe way\n * URL's will be stringified\n * `booleans` & `numbers` will be stringified\n * `null` & `undefined` will be ommitted\n * Arrays of strings will be joined with a space\n *\n * @example\n * ```ts\n * const urlSearchParams = new URLSearchParams();\n * addQueryParams({\n * params: { foo: 'bar', count: 42, tags: ['one', 'two'] },\n * urlSearchParams,\n * });\n * ```\n *\n * @see {@link createUrlWithParams} for creating a full URL\n */\nexport function addQueryParams<Params extends QueryParamsInput>({\n params,\n urlSearchParams,\n}: {\n params: Params;\n /**\n * This will be mutated in place AND returned\n */\n urlSearchParams: URLSearchParams;\n}) {\n Object.entries(params ?? {}).forEach(([key, value]) => {\n if (value === undefined || value === null) return;\n if (value instanceof URL) {\n urlSearchParams.set(key, value.toString());\n } else if (Array.isArray(value)) {\n urlSearchParams.set(key, value.join(' '));\n } else {\n const v = `${value}`;\n if (v === '') return;\n urlSearchParams.set(key, v);\n }\n });\n return urlSearchParams;\n}\n\n/**\n * Creates a URL with query parameters, supporting both full URLs and relative paths\n * @example\n * ```ts\n * createUrlWithParams({\n * url: 'https://example.com',\n * queryParams: { foo: 'bar', count: 42, tags: ['one', 'two'] }\n * })\n * // => URL('https://example.com?foo=bar&count=42&tags=one%20two')\n * ```\n *\n * @see {@link addQueryParams} for adding just query params\n */\nexport function createUrlWithParams<Params extends QueryParamsInput>({\n /** Can either be a full URL or a relative one (but that requires passing in \"origin\") */\n url,\n /** Base URL to use when url is a relative path */\n origin,\n /**\n * URL's will be stringified\n * Arrays of strings will be joined with a space\n * Other values will be stringified\n */\n queryParams,\n}: {\n /**\n * Can either be a full URL or a relative one (but that requires passing in \"origin\")\n */\n url: string | URL;\n /**\n * URL's will be stringified\n * Arrays of strings will be joined with a space\n * Other values will be stringified\n */\n queryParams: Params;\n origin?: string;\n}) {\n if (!origin && typeof url === 'string' && !url.startsWith('http')) {\n throw new Error(\n `When using \"createUrl\" either pass in a full \"url\" or provide an \"origin\"`,\n );\n }\n\n const u =\n // eslint-disable-next-line no-nested-ternary\n typeof url === 'string'\n ? new URL(url, origin)\n : origin\n ? new URL(url.toString(), origin)\n : url;\n addQueryParams({ params: queryParams, urlSearchParams: u.searchParams });\n return u;\n}\n\nexport interface GitLabParsedUrl {\n fullPath: string;\n}\n\nexport interface BitbucketParsedUrl {\n fullPath: string;\n}\n\nexport interface GitHubParsedUrl {\n owner: string;\n repoName: string;\n}\n\nexport function areUrlsSame({ a, b }: { a: string; b: string }) {\n return new URL(a).toString() === new URL(b).toString();\n}\n\nexport function isRemoteUrl(url: string): boolean {\n if (typeof url !== 'string') return false;\n try {\n // Throws here if malformed URL\n const pathUrl = new URL(url);\n // Be VERY specific with protocols here, since URL() does no protocol validation\n return (\n pathUrl.protocol.startsWith('http:') ||\n pathUrl.protocol.startsWith('https:')\n );\n } catch (e) {\n // Starting a url with '//' is invalid to URL(), but we support it\n return url.startsWith('//');\n }\n}\n\n/**\n * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs\n */\nexport const isDataUrl = (dataString: string): boolean =>\n dataString.startsWith('data:');\n\nexport const slugify = (\n opt:\n | string\n | {\n string: string;\n /**\n * Removes all special characters. Necessary when used to create JS targets\n * that are invalid when special characters are present.\n */\n strict?: boolean;\n lowerCase?: boolean;\n },\n): string => {\n const {\n string,\n strict = true,\n lowerCase = true,\n } = typeof opt === 'string' ? { string: opt } : opt;\n return slugifyBase(string, {\n lower: lowerCase,\n trim: true,\n strict,\n });\n};\n\n/**\n * When dealing with nav paths, we need to find the entity type of the link (first\n * part, e.g. 'page' or 'pattern') and the entity id (second part, e.g. 'home').\n */\nexport const extractPathParts = (path: string): string[] | null => {\n const regex = /^\\/([^/]+)\\/([^/]+)/;\n const match = path.match(regex);\n\n if (!match) return null;\n\n const [_, entityType, entityId] = match;\n return [entityType, entityId];\n};\n\nexport function createFigmaUrl({\n fileId,\n nodeId,\n version,\n}: {\n fileId: string;\n nodeId?: string;\n version?: string | number;\n}) {\n if (!fileId || fileId.trim().length === 0) {\n throw new Error(`Invalid Figma URL, missing file id: ${fileId}`);\n }\n const url = new URL(`https://www.figma.com/file/${fileId}`);\n if (nodeId) {\n url.searchParams.set('node-id', nodeId);\n }\n if (version) {\n url.searchParams.set('version-id', version.toString());\n }\n return url.toString();\n}\n\nexport function parseFigmaUrl(figmaUrl: string): {\n type: 'proto' | 'file' | 'design' | 'board';\n fileId: string;\n nodeId?: string;\n version?: string;\n} {\n const url = new URL(figmaUrl);\n // tried to update to use the regex from figma, but it ended up being too strict\n // noting here in case we revisit\n // /https:\\/\\/[\\w\\.-]+\\.?figma.com\\/([\\w-]+)\\/([0-9a-zA-Z]{22,128})(?:\\/.*)?$/;\n if (\n (url.hostname !== 'www.figma.com' && url.hostname !== 'figma.com') ||\n !isRemoteUrl(figmaUrl) // Ensure it's a http/https URL.\n ) {\n throw new Error(`Please provide a valid Figma URL, got ${figmaUrl}`);\n }\n const nodeId = url.searchParams.get('node-id') || undefined;\n const version = url.searchParams.get('version-id') || undefined;\n const [, type, fileId] = url.pathname.split('/');\n switch (type) {\n case 'proto':\n case 'file':\n case 'board':\n case 'design': {\n if (!fileId) {\n throw new Error(`Invalid Figma URL, missing file id: ${figmaUrl}`);\n }\n return {\n type,\n fileId,\n nodeId,\n version,\n };\n }\n default:\n throw new Error(`Please provide a valid Figma URL, got ${figmaUrl}`);\n }\n}\n\n/**\n * Create a query string from an object of params\n * Does not include undefined, null, or empty string values\n * Does not include leading `?`\n */\nexport function createQueryParams(\n params: Record<string, string | number | boolean | undefined | null>,\n) {\n return new URLSearchParams(\n Object.fromEntries(\n Object.entries(params)\n .filter(([, v]) => {\n if (typeof v === 'string') {\n // removing empty strings\n return v.length > 0;\n }\n // removing null or undefined\n return v !== undefined && v !== null;\n })\n .map(([k, v]): [string, string] => [\n k,\n // sending up non-strings as strings\n `${v}`,\n ]),\n ),\n ).toString();\n}\n\n/**\n * Creates a safe filename by slugifying the filename and removing any special characters\n * Will throw if the filename does not exist or is just an extension (e.g. '.jpg')\n * @example\n * ```ts\n * createSafeFilename({ filename: 'test.jpg' }) // => 'test.jpg'\n * createSafeFilename({ filename: 'test.jpg.png' }) // => 'testjpg.png'\n * createSafeFilename({ filename: 'test jpg.pdf' }) // => 'test-jpg.pdf'\n */\nexport function createSafeFilename({ filename }: { filename: string }): string {\n const ext = slugify([...filename.split('.')].pop() || '');\n const base = ext\n ? slugify(filename.substring(0, filename.lastIndexOf('.')))\n : slugify(filename);\n if (!base) {\n throw new Error(`Invalid filename: ${filename}`);\n }\n return ext ? `${base}.${ext}` : base;\n}\n"]}
|
package/dist/ids.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {nanoid}from'nanoid';import {v4}from'uuid';import a from'slugify';var o=Object.defineProperty;var
|
|
1
|
+
import {nanoid}from'nanoid';import {v4,v7}from'uuid';import a from'slugify';var o=Object.defineProperty;var t=(r,e)=>o(r,"name",{value:e,configurable:true});var n=t(r=>{let{string:e,strict:s=true,lowerCase:i=true}=typeof r=="string"?{string:r}:r;return a(e,{lower:i,trim:true,strict:s})},"slugify");var P=t(()=>v4(),"makeUuid"),U=t(()=>v7(),"makeUuidV7"),x=t(()=>n({string:nanoid(10),lowerCase:false}),"makeShortId");export{x as makeShortId,P as makeUuid,U as makeUuidV7};//# sourceMappingURL=ids.mjs.map
|
|
2
2
|
//# sourceMappingURL=ids.mjs.map
|
package/dist/ids.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/ids.ts","../src/urls.ts"],"names":["slugify","__name","opt","string","strict","lowerCase","slugifyBase","makeUuid","
|
|
1
|
+
{"version":3,"sources":["../src/ids.ts","../src/urls.ts"],"names":["slugify","__name","opt","string","strict","lowerCase","slugifyBase","makeUuid","uuidV4","makeUuidV7","uuidV7","makeShortId","nanoid"],"mappings":"4EAAA,IAAA,CAAA,CAAA,MAAA,CAAA,cAAA,CAAA,IAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,GAAA,CAAA,CAAA,CAAA,CAAA,MAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,YAAA,CAAA,IAAA,CAAA,CAAA,CC+IO,IAAMA,CAAAA,CAAUC,EACrBC,CAAAA,EAWW,CACX,GAAM,CACJ,OAAAC,CAAAA,CACA,MAAA,CAAAC,CAAAA,CAAS,IAAA,CACT,UAAAC,CAAAA,CAAY,IACd,CAAA,CAAI,OAAOH,GAAQ,QAAA,CAAW,CAAE,MAAA,CAAQA,CAAI,EAAIA,CAAAA,CAChD,OAAOI,CAAAA,CAAYH,CAAAA,CAAQ,CACzB,KAAA,CAAOE,CAAAA,CACP,IAAA,CAAM,IAAA,CACN,OAAAD,CACF,CAAC,CACH,CAAA,CAvBuB,WD3IhB,IAAMG,CAAAA,CAAWN,CAAAA,CAAA,IAAMO,IAAO,CAAb,UAAA,CAAA,CACXC,CAAAA,CAAaR,CAAAA,CAAA,IAAMS,EAAAA,EAAO,CAAb,YAAA,CAAA,CAKbC,CAAAA,CAAcV,EAAA,IACzBD,CAAAA,CAAQ,CACN,MAAA,CAAQY,OAAO,EAAE,CAAA,CACjB,SAAA,CAAW,KACb,CAAC,CAAA,CAJwB,aAAA","file":"ids.mjs","sourcesContent":["import { nanoid } from 'nanoid';\nimport { v4 as uuidV4, v7 as uuidV7 } from 'uuid';\nimport { slugify } from './urls';\n\nexport const makeUuid = () => uuidV4();\nexport const makeUuidV7 = () => uuidV7();\n\n/**\n * Short ID that is also slugified\n */\nexport const makeShortId = () =>\n slugify({\n string: nanoid(10),\n lowerCase: false,\n });\n","import slugifyBase from 'slugify';\n\nexport type QueryParamsInput = Record<\n string,\n string | number | boolean | undefined | null | string[] | URL\n>;\n\n/**\n * Util to add query params in a type safe way\n * URL's will be stringified\n * `booleans` & `numbers` will be stringified\n * `null` & `undefined` will be ommitted\n * Arrays of strings will be joined with a space\n *\n * @example\n * ```ts\n * const urlSearchParams = new URLSearchParams();\n * addQueryParams({\n * params: { foo: 'bar', count: 42, tags: ['one', 'two'] },\n * urlSearchParams,\n * });\n * ```\n *\n * @see {@link createUrlWithParams} for creating a full URL\n */\nexport function addQueryParams<Params extends QueryParamsInput>({\n params,\n urlSearchParams,\n}: {\n params: Params;\n /**\n * This will be mutated in place AND returned\n */\n urlSearchParams: URLSearchParams;\n}) {\n Object.entries(params ?? {}).forEach(([key, value]) => {\n if (value === undefined || value === null) return;\n if (value instanceof URL) {\n urlSearchParams.set(key, value.toString());\n } else if (Array.isArray(value)) {\n urlSearchParams.set(key, value.join(' '));\n } else {\n const v = `${value}`;\n if (v === '') return;\n urlSearchParams.set(key, v);\n }\n });\n return urlSearchParams;\n}\n\n/**\n * Creates a URL with query parameters, supporting both full URLs and relative paths\n * @example\n * ```ts\n * createUrlWithParams({\n * url: 'https://example.com',\n * queryParams: { foo: 'bar', count: 42, tags: ['one', 'two'] }\n * })\n * // => URL('https://example.com?foo=bar&count=42&tags=one%20two')\n * ```\n *\n * @see {@link addQueryParams} for adding just query params\n */\nexport function createUrlWithParams<Params extends QueryParamsInput>({\n /** Can either be a full URL or a relative one (but that requires passing in \"origin\") */\n url,\n /** Base URL to use when url is a relative path */\n origin,\n /**\n * URL's will be stringified\n * Arrays of strings will be joined with a space\n * Other values will be stringified\n */\n queryParams,\n}: {\n /**\n * Can either be a full URL or a relative one (but that requires passing in \"origin\")\n */\n url: string | URL;\n /**\n * URL's will be stringified\n * Arrays of strings will be joined with a space\n * Other values will be stringified\n */\n queryParams: Params;\n origin?: string;\n}) {\n if (!origin && typeof url === 'string' && !url.startsWith('http')) {\n throw new Error(\n `When using \"createUrl\" either pass in a full \"url\" or provide an \"origin\"`,\n );\n }\n\n const u =\n // eslint-disable-next-line no-nested-ternary\n typeof url === 'string'\n ? new URL(url, origin)\n : origin\n ? new URL(url.toString(), origin)\n : url;\n addQueryParams({ params: queryParams, urlSearchParams: u.searchParams });\n return u;\n}\n\nexport interface GitLabParsedUrl {\n fullPath: string;\n}\n\nexport interface BitbucketParsedUrl {\n fullPath: string;\n}\n\nexport interface GitHubParsedUrl {\n owner: string;\n repoName: string;\n}\n\nexport function areUrlsSame({ a, b }: { a: string; b: string }) {\n return new URL(a).toString() === new URL(b).toString();\n}\n\nexport function isRemoteUrl(url: string): boolean {\n if (typeof url !== 'string') return false;\n try {\n // Throws here if malformed URL\n const pathUrl = new URL(url);\n // Be VERY specific with protocols here, since URL() does no protocol validation\n return (\n pathUrl.protocol.startsWith('http:') ||\n pathUrl.protocol.startsWith('https:')\n );\n } catch (e) {\n // Starting a url with '//' is invalid to URL(), but we support it\n return url.startsWith('//');\n }\n}\n\n/**\n * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs\n */\nexport const isDataUrl = (dataString: string): boolean =>\n dataString.startsWith('data:');\n\nexport const slugify = (\n opt:\n | string\n | {\n string: string;\n /**\n * Removes all special characters. Necessary when used to create JS targets\n * that are invalid when special characters are present.\n */\n strict?: boolean;\n lowerCase?: boolean;\n },\n): string => {\n const {\n string,\n strict = true,\n lowerCase = true,\n } = typeof opt === 'string' ? { string: opt } : opt;\n return slugifyBase(string, {\n lower: lowerCase,\n trim: true,\n strict,\n });\n};\n\n/**\n * When dealing with nav paths, we need to find the entity type of the link (first\n * part, e.g. 'page' or 'pattern') and the entity id (second part, e.g. 'home').\n */\nexport const extractPathParts = (path: string): string[] | null => {\n const regex = /^\\/([^/]+)\\/([^/]+)/;\n const match = path.match(regex);\n\n if (!match) return null;\n\n const [_, entityType, entityId] = match;\n return [entityType, entityId];\n};\n\nexport function createFigmaUrl({\n fileId,\n nodeId,\n version,\n}: {\n fileId: string;\n nodeId?: string;\n version?: string | number;\n}) {\n if (!fileId || fileId.trim().length === 0) {\n throw new Error(`Invalid Figma URL, missing file id: ${fileId}`);\n }\n const url = new URL(`https://www.figma.com/file/${fileId}`);\n if (nodeId) {\n url.searchParams.set('node-id', nodeId);\n }\n if (version) {\n url.searchParams.set('version-id', version.toString());\n }\n return url.toString();\n}\n\nexport function parseFigmaUrl(figmaUrl: string): {\n type: 'proto' | 'file' | 'design' | 'board';\n fileId: string;\n nodeId?: string;\n version?: string;\n} {\n const url = new URL(figmaUrl);\n // tried to update to use the regex from figma, but it ended up being too strict\n // noting here in case we revisit\n // /https:\\/\\/[\\w\\.-]+\\.?figma.com\\/([\\w-]+)\\/([0-9a-zA-Z]{22,128})(?:\\/.*)?$/;\n if (\n (url.hostname !== 'www.figma.com' && url.hostname !== 'figma.com') ||\n !isRemoteUrl(figmaUrl) // Ensure it's a http/https URL.\n ) {\n throw new Error(`Please provide a valid Figma URL, got ${figmaUrl}`);\n }\n const nodeId = url.searchParams.get('node-id') || undefined;\n const version = url.searchParams.get('version-id') || undefined;\n const [, type, fileId] = url.pathname.split('/');\n switch (type) {\n case 'proto':\n case 'file':\n case 'board':\n case 'design': {\n if (!fileId) {\n throw new Error(`Invalid Figma URL, missing file id: ${figmaUrl}`);\n }\n return {\n type,\n fileId,\n nodeId,\n version,\n };\n }\n default:\n throw new Error(`Please provide a valid Figma URL, got ${figmaUrl}`);\n }\n}\n\n/**\n * Create a query string from an object of params\n * Does not include undefined, null, or empty string values\n * Does not include leading `?`\n */\nexport function createQueryParams(\n params: Record<string, string | number | boolean | undefined | null>,\n) {\n return new URLSearchParams(\n Object.fromEntries(\n Object.entries(params)\n .filter(([, v]) => {\n if (typeof v === 'string') {\n // removing empty strings\n return v.length > 0;\n }\n // removing null or undefined\n return v !== undefined && v !== null;\n })\n .map(([k, v]): [string, string] => [\n k,\n // sending up non-strings as strings\n `${v}`,\n ]),\n ),\n ).toString();\n}\n\n/**\n * Creates a safe filename by slugifying the filename and removing any special characters\n * Will throw if the filename does not exist or is just an extension (e.g. '.jpg')\n * @example\n * ```ts\n * createSafeFilename({ filename: 'test.jpg' }) // => 'test.jpg'\n * createSafeFilename({ filename: 'test.jpg.png' }) // => 'testjpg.png'\n * createSafeFilename({ filename: 'test jpg.pdf' }) // => 'test-jpg.pdf'\n */\nexport function createSafeFilename({ filename }: { filename: string }): string {\n const ext = slugify([...filename.split('.')].pop() || '');\n const base = ext\n ? slugify(filename.substring(0, filename.lastIndexOf('.')))\n : slugify(filename);\n if (!base) {\n throw new Error(`Invalid filename: ${filename}`);\n }\n return ext ? `${base}.${ext}` : base;\n}\n"]}
|
package/dist/immer.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Patch, applyPatches, produceWithPatches, produce, isDraft, type Draft, type Objectish } from 'immer';
|
|
1
|
+
import { type Patch, applyPatches, produceWithPatches, produce, isDraft, type Draft, type Objectish } from 'immer';
|
|
2
2
|
export { produce, produceWithPatches, applyPatches, isDraft };
|
|
3
3
|
export type { Patch, Draft };
|
|
4
4
|
/**
|
package/dist/immer.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"immer.d.ts","sourceRoot":"","sources":["../src/immer.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,
|
|
1
|
+
{"version":3,"file":"immer.d.ts","sourceRoot":"","sources":["../src/immer.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,KAAK,EACV,YAAY,EAEZ,kBAAkB,EAClB,OAAO,EACP,OAAO,EACP,KAAK,KAAK,EACV,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAEf,OAAO,EAAE,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC;AAC9D,YAAY,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;AAI7B;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,SAAS,SAAS,EAAE,EACtD,QAAQ,EACR,OAAO,EAAE,UAAU,GACpB,EAAE;IACD,QAAQ,EAAE,IAAI,CAAC;IACf,OAAO,EAAE,KAAK,EAAE,EAAE,GAAG,KAAK,EAAE,CAAC;CAC9B,qCAIA;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,SAAS,SAAS,EAAE,EACzD,IAAI,EACJ,OAAO,EACP,QAAwB,EACxB,gBAAwB,GACzB,EAAE;IACD,IAAI,EAAE,IAAI,CAAC;IACX,OAAO,EAAE;QAAE,OAAO,EAAE,KAAK,EAAE,CAAA;KAAE,EAAE,CAAC;IAChC,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,YAAY,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IAC9D,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B,GAAG,IAAI,CAmBP"}
|
package/dist/immer.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
'use strict';var immer=require('immer');var P=Object.defineProperty;var r=(t,e)=>P(t,"name",{value:e,configurable:true});immer.enablePatches();function
|
|
1
|
+
'use strict';var immer=require('immer');var P=Object.defineProperty;var r=(t,e)=>P(t,"name",{value:e,configurable:true});immer.enablePatches();function m({baseData:t,patches:e}){return immer.produceWithPatches(t,a=>{immer.applyPatches(a,e.flat());})}r(m,"compressPatches");function x({data:t,changes:e,logError:a=console.error,logAppClientData:p=false}){return e.reduce((o,s,h)=>{try{return immer.applyPatches(o,s.patches)}catch(c){let{LOG_IMMER_APP_CLIENT_DATA:i}=process.env,l=p||i?{data:t,change:s}:s;return a(`applyPatchesSafely had issues (and so will skip) with patches in change ${h}: ${c instanceof Error?c.message:""}`,l),o}},t)}r(x,"applyPatchesSafely");Object.defineProperty(exports,"applyPatches",{enumerable:true,get:function(){return immer.applyPatches}});Object.defineProperty(exports,"isDraft",{enumerable:true,get:function(){return immer.isDraft}});Object.defineProperty(exports,"produce",{enumerable:true,get:function(){return immer.produce}});Object.defineProperty(exports,"produceWithPatches",{enumerable:true,get:function(){return immer.produceWithPatches}});exports.applyPatchesSafely=x;exports.compressPatches=m;//# sourceMappingURL=immer.js.map
|
|
2
2
|
//# sourceMappingURL=immer.js.map
|