@ptx-showcase/utils 0.6.0 → 1.1.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.
Files changed (58) hide show
  1. package/README.md +68 -13
  2. package/dist/admin/constants/admin.constant.d.ts +18 -0
  3. package/dist/admin/index.cjs +1 -0
  4. package/dist/admin/index.d.ts +2 -0
  5. package/dist/admin/index.js +2 -0
  6. package/dist/admin/libs/is-admin-token/index.d.ts +20 -0
  7. package/dist/admin/libs/is-admin-token/types/is-admin-token.type.d.ts +4 -0
  8. package/dist/base/constants/base.constant.d.ts +15 -0
  9. package/dist/base/index.cjs +1 -0
  10. package/dist/base/index.d.ts +2 -0
  11. package/dist/base/index.js +2 -0
  12. package/dist/base/types/base.type.d.ts +23 -0
  13. package/dist/build-query-params/index.js +1 -1
  14. package/dist/build-sort-param/index.js +1 -1
  15. package/dist/chunks/admin-B3AZrTOb.es +28 -0
  16. package/dist/chunks/admin-DR1tBkNV.cjs +1 -0
  17. package/dist/chunks/base-C5926Kyt.es +16 -0
  18. package/dist/chunks/base-DLHy3wps.cjs +1 -0
  19. package/dist/chunks/{currency-symbol-CBowgXv-.es → currency-symbol-CJp1EcR5.es} +1 -1
  20. package/dist/chunks/flags-BRQ9Jims.cjs +1 -0
  21. package/dist/chunks/flags-C5E6W9lm.es +52 -0
  22. package/dist/chunks/{handle-api-error-CMd_LxPS.es → handle-api-error-BYygTKYM.es} +1 -1
  23. package/dist/chunks/{truncate-decimals-BFMoEzul.es → truncate-decimals-BPaTWeHm.es} +1 -1
  24. package/dist/clean-object/index.js +1 -1
  25. package/dist/core/flags/constants/flags.constant.d.ts +15 -0
  26. package/dist/core/flags/index.d.ts +48 -0
  27. package/dist/core/index.cjs +1 -0
  28. package/dist/core/index.d.ts +10 -0
  29. package/dist/core/index.js +11 -0
  30. package/dist/currency-symbol/index.js +1 -1
  31. package/dist/download-file/index.js +1 -1
  32. package/dist/flags/index.cjs +1 -0
  33. package/dist/flags/index.js +2 -0
  34. package/dist/handle-api-error/index.js +1 -1
  35. package/dist/index.cjs +1 -1
  36. package/dist/index.d.ts +3 -10
  37. package/dist/index.js +14 -10
  38. package/dist/normalize-input/index.js +1 -1
  39. package/dist/truncate-decimals/index.js +1 -1
  40. package/package.json +40 -23
  41. package/dist/types/index.cjs +0 -0
  42. package/dist/types/index.d.ts +0 -13
  43. package/dist/types/index.js +0 -0
  44. /package/dist/{build-query-params → core/build-query-params}/index.d.ts +0 -0
  45. /package/dist/{build-sort-param → core/build-sort-param}/index.d.ts +0 -0
  46. /package/dist/{clean-object → core/clean-object}/index.d.ts +0 -0
  47. /package/dist/{cookies → core/cookies}/index.d.ts +0 -0
  48. /package/dist/{currency-symbol → core/currency-symbol}/constants/currency-symbol.constant.d.ts +0 -0
  49. /package/dist/{currency-symbol → core/currency-symbol}/index.d.ts +0 -0
  50. /package/dist/{download-file → core/download-file}/index.d.ts +0 -0
  51. /package/dist/{handle-api-error → core/handle-api-error}/constants/handle-api-error.constant.d.ts +0 -0
  52. /package/dist/{handle-api-error → core/handle-api-error}/index.d.ts +0 -0
  53. /package/dist/{handle-api-error → core/handle-api-error}/libs/handle-api-error.lib.d.ts +0 -0
  54. /package/dist/{handle-api-error → core/handle-api-error}/libs/init-handle-api-error.lib.d.ts +0 -0
  55. /package/dist/{handle-api-error → core/handle-api-error}/types/handle-api-error.type.d.ts +0 -0
  56. /package/dist/{normalize-input → core/normalize-input}/index.d.ts +0 -0
  57. /package/dist/{truncate-decimals → core/truncate-decimals}/constants/truncate-decimals.constant.d.ts +0 -0
  58. /package/dist/{truncate-decimals → core/truncate-decimals}/index.d.ts +0 -0
package/README.md CHANGED
@@ -20,7 +20,12 @@ bun add @ptx-showcase/utils
20
20
 
21
21
  ## Usage
22
22
 
23
- All utilities can be imported from the root package or from a specific subpath.
23
+ All utilities can be imported from the root package, from a grouping subpath (`/base`, `/admin`, `/core`), or from each utility's own subpath.
24
+
25
+ - `/base` — types and enums shared across projects (`TableColumnConfig`, `PaginatedList`, `ListQueryParams`, `DISCOUNT_TYPES`, `ORDER_STATUSES`, `SUPPORT_STATUSES`)
26
+ - `/admin` — admin-panel-only concerns (`isAdminToken`, `ADMIN_QUERY_KEYS`); only relevant to admin projects
27
+ - `/core` — every generic utility below, bundled together
28
+ - Each generic utility is also importable on its own (`/cookies`, `/build-query-params`, etc.)
24
29
 
25
30
  ---
26
31
 
@@ -126,6 +131,35 @@ await downloadBlob(blob, { hash: 12345 })
126
131
 
127
132
  ---
128
133
 
134
+ ### Flags
135
+
136
+ Resolves a flag icon URL for a language/country code, with a three-tier fallback: primary source ([flagcdn.com](https://flagcdn.com)) → secondary source ([flagicons.lipis.dev](https://flagicons.lipis.dev)) → an "unknown flag" placeholder. The placeholder is also returned directly when `languageCode` isn't a usable string at runtime (`null`, `undefined`, `NaN`, an object, an empty/whitespace string, etc.) — the functions never throw.
137
+
138
+ `FLAG_CODE_ALIASES` maps language codes that differ from their representative country's ISO code (e.g. `en` → `gb`, `ja` → `jp`); codes with no entry are used as-is.
139
+
140
+ ```ts
141
+ // from root
142
+ import { getFlagUrl, handleFlagImageError } from '@ptx-showcase/utils'
143
+
144
+ // from subpath
145
+ import { getFlagUrl, handleFlagImageError } from '@ptx-showcase/utils/flags'
146
+
147
+ getFlagUrl('fr') // → 'https://flagcdn.com/fr.svg'
148
+ getFlagUrl('en') // → 'https://flagcdn.com/gb.svg' (resolved via FLAG_CODE_ALIASES)
149
+ getFlagUrl(null as unknown as string) // → unknown-flag placeholder URL
150
+
151
+ // React — escalates primary → fallback → unknown placeholder on load failure
152
+ <img src={getFlagUrl(code)} onError={(e) => handleFlagImageError(e, code)} />
153
+
154
+ // Vue
155
+ <img :src="getFlagUrl(code)" @error="(e) => handleFlagImageError(e, code)" />
156
+
157
+ // Svelte
158
+ <img src={getFlagUrl(code)} on:error={(e) => handleFlagImageError(e, code)} />
159
+ ```
160
+
161
+ ---
162
+
129
163
  ### getCurrencySymbol
130
164
 
131
165
  Resolves the symbol for an ISO 4217 currency code via `Intl`. A handful of currencies (`AUD`, `CAD`, `NZD`, `CHF`, etc.) are overridden where the `Intl` narrow symbol would be ambiguous.
@@ -183,6 +217,24 @@ try {
183
217
 
184
218
  ---
185
219
 
220
+ ### isAdminToken
221
+
222
+ Checks whether a JWT access token's payload has the `is_admin` claim set to `true`. Decodes the token locally without verifying its signature, so it only reflects what the token claims — signature verification is expected to have already happened server-side.
223
+
224
+ ```ts
225
+ // from root
226
+ import { isAdminToken } from '@ptx-showcase/utils'
227
+
228
+ // from subpath
229
+ import { isAdminToken } from '@ptx-showcase/utils/admin'
230
+
231
+ isAdminToken(adminToken) // → true
232
+ isAdminToken(regularUserToken) // → false
233
+ isAdminToken('not-a-valid-jwt') // → false
234
+ ```
235
+
236
+ ---
237
+
186
238
  ### normalizeDecimalInput / normalizePhoneNumberInput
187
239
 
188
240
  In-place `input`/`change` event handlers that sanitize a text input's value as the user types.
@@ -236,18 +288,21 @@ truncateDecimals(undefined) // → 'N/A'
236
288
 
237
289
  ## Available modules
238
290
 
239
- | Subpath | Exports |
240
- | ---------------------------------------- | ---------------------------------------------------------------- |
241
- | `@ptx-showcase/utils` | all utilities |
242
- | `@ptx-showcase/utils/build-query-params` | `buildQueryParams` |
243
- | `@ptx-showcase/utils/build-sort-param` | `buildSortParam` |
244
- | `@ptx-showcase/utils/cookies` | `setCookie`, `getCookie`, `deleteCookie`, `defaultCookieOptions` |
245
- | `@ptx-showcase/utils/currency-symbol` | `getCurrencySymbol` |
246
- | `@ptx-showcase/utils/download-file` | `downloadBlob` |
247
- | `@ptx-showcase/utils/handle-api-error` | `handleApiError`, `initHandleApiError` |
248
- | `@ptx-showcase/utils/normalize-input` | `normalizeDecimalInput`, `normalizePhoneNumberInput` |
249
- | `@ptx-showcase/utils/truncate-decimals` | `truncateDecimals` |
250
- | `@ptx-showcase/utils/types` | `TableColumnConfig`, `PaginatedList` |
291
+ | Subpath | Exports |
292
+ | ---------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
293
+ | `@ptx-showcase/utils` | everything below |
294
+ | `@ptx-showcase/utils/base` | `TableColumnConfig`, `PaginatedList`, `ListQueryParams`, `DISCOUNT_TYPES`, `ORDER_STATUSES`, `SUPPORT_STATUSES` |
295
+ | `@ptx-showcase/utils/admin` | `isAdminToken`, `ADMIN_QUERY_KEYS` (admin-panel projects only) |
296
+ | `@ptx-showcase/utils/core` | every generic utility below, bundled together |
297
+ | `@ptx-showcase/utils/build-query-params` | `buildQueryParams` |
298
+ | `@ptx-showcase/utils/build-sort-param` | `buildSortParam` |
299
+ | `@ptx-showcase/utils/cookies` | `setCookie`, `getCookie`, `deleteCookie`, `defaultCookieOptions` |
300
+ | `@ptx-showcase/utils/currency-symbol` | `getCurrencySymbol` |
301
+ | `@ptx-showcase/utils/download-file` | `downloadBlob` |
302
+ | `@ptx-showcase/utils/flags` | `getFlagUrl`, `getFlagFallbackUrl`, `getFlagUnknownUrl`, `handleFlagImageError`, `FLAG_CODE_ALIASES` |
303
+ | `@ptx-showcase/utils/handle-api-error` | `handleApiError`, `initHandleApiError` |
304
+ | `@ptx-showcase/utils/normalize-input` | `normalizeDecimalInput`, `normalizePhoneNumberInput` |
305
+ | `@ptx-showcase/utils/truncate-decimals` | `truncateDecimals` |
251
306
 
252
307
  ---
253
308
 
@@ -0,0 +1,18 @@
1
+ export declare const ADMIN_QUERY_KEYS: {
2
+ readonly USERS: string;
3
+ readonly SINGLE_USER: string;
4
+ readonly ORDERS: string;
5
+ readonly SINGLE_ORDER: string;
6
+ readonly DISCOUNTS: string;
7
+ readonly SINGLE_DISCOUNT: string;
8
+ readonly STATIC: string;
9
+ readonly SINGLE_STATIC: string;
10
+ readonly SUPPORT_REQUESTS: string;
11
+ readonly SINGLE_SUPPORT_REQUEST: string;
12
+ readonly AVALIABLE_CURRENCIES: string;
13
+ readonly ACTIVE_CURRENCIES: string;
14
+ readonly GATEWAYS: string;
15
+ readonly BANS: string;
16
+ readonly SWAGGER: string;
17
+ readonly BULK_EDIT: string;
18
+ };
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../chunks/admin-DR1tBkNV.cjs");exports.ADMIN_QUERY_KEYS=e.n,exports.isAdminToken=e.t;
@@ -0,0 +1,2 @@
1
+ export { ADMIN_QUERY_KEYS } from './constants/admin.constant';
2
+ export { isAdminToken } from './libs/is-admin-token';
@@ -0,0 +1,2 @@
1
+ import { n as e, t } from "../chunks/admin-B3AZrTOb.es";
2
+ export { e as ADMIN_QUERY_KEYS, t as isAdminToken };
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Checks whether a JWT access token carries the `is_admin` claim set to `true`.
3
+ *
4
+ * Decodes the token locally without verifying its signature, so this only
5
+ * tells you what the token claims, not whether the token is trustworthy —
6
+ * signature verification is expected to have happened server-side already.
7
+ *
8
+ * @param accessToken - The JWT access token to check
9
+ * @returns `true` only if the token decodes successfully and its payload has
10
+ * `is_admin: true`; `false` if the claim is `false`, missing, or the token
11
+ * can't be decoded at all
12
+ *
13
+ * @example
14
+ * ```ts
15
+ * isAdminToken(adminToken) // => true
16
+ * isAdminToken(regularUserToken) // => false
17
+ * isAdminToken('not-a-valid-jwt') // => false
18
+ * ```
19
+ */
20
+ export declare const isAdminToken: (accessToken: string) => boolean;
@@ -0,0 +1,4 @@
1
+ import { JwtPayload } from 'jwt-decode';
2
+ export interface JwtAdminPayload extends JwtPayload {
3
+ is_admin?: boolean;
4
+ }
@@ -0,0 +1,15 @@
1
+ export declare const DISCOUNT_TYPES: {
2
+ readonly MONEY: "money";
3
+ readonly PERCENT: "percent";
4
+ };
5
+ export declare const ORDER_STATUSES: {
6
+ readonly PENDING: "PENDING";
7
+ readonly COMPLETED: "COMPLETED";
8
+ readonly FAILED: "FAILED";
9
+ readonly CANCELED: "CANCELED";
10
+ };
11
+ export declare const SUPPORT_STATUSES: {
12
+ readonly PENDING: "PENDING";
13
+ readonly SOLVED: "SOLVED";
14
+ readonly CLOSED: "CLOSED";
15
+ };
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../chunks/base-DLHy3wps.cjs");exports.DISCOUNT_TYPES=e.t,exports.ORDER_STATUSES=e.n,exports.SUPPORT_STATUSES=e.r;
@@ -0,0 +1,2 @@
1
+ export { DISCOUNT_TYPES, ORDER_STATUSES, SUPPORT_STATUSES } from './constants/base.constant';
2
+ export type { DiscountType, OrderStatus, SupportStatus, TableColumnConfig, PaginatedList, ListQueryParams } from './types/base.type';
@@ -0,0 +1,2 @@
1
+ import { n as e, r as t, t as n } from "../chunks/base-C5926Kyt.es";
2
+ export { n as DISCOUNT_TYPES, e as ORDER_STATUSES, t as SUPPORT_STATUSES };
@@ -0,0 +1,23 @@
1
+ import { DISCOUNT_TYPES, ORDER_STATUSES, SUPPORT_STATUSES } from '../constants/base.constant';
2
+ export interface TableColumnConfig<T, ExtraKeys extends string = never> {
3
+ id?: number;
4
+ label: string;
5
+ key: keyof T | ExtraKeys;
6
+ sortable?: boolean;
7
+ }
8
+ export interface PaginatedList<T> {
9
+ items: T[];
10
+ page: number;
11
+ per_page: number;
12
+ total_items: number;
13
+ total_pages: number;
14
+ }
15
+ export interface ListQueryParams {
16
+ search?: string;
17
+ sort?: string;
18
+ page?: number;
19
+ per_page?: number;
20
+ }
21
+ export type OrderStatus = (typeof ORDER_STATUSES)[keyof typeof ORDER_STATUSES];
22
+ export type SupportStatus = (typeof SUPPORT_STATUSES)[keyof typeof SUPPORT_STATUSES];
23
+ export type DiscountType = (typeof DISCOUNT_TYPES)[keyof typeof DISCOUNT_TYPES];
@@ -1,4 +1,4 @@
1
- //#region src/build-query-params/index.ts
1
+ //#region src/core/build-query-params/index.ts
2
2
  var e = (e) => {
3
3
  let t = new URLSearchParams();
4
4
  Object.entries(e).forEach(([e, n]) => {
@@ -1,4 +1,4 @@
1
- //#region src/build-sort-param/index.ts
1
+ //#region src/core/build-sort-param/index.ts
2
2
  var e = (e, t) => {
3
3
  let n = "-" + e, r = (t ?? "").split(",").filter(Boolean);
4
4
  return r.includes(n) ? r.filter((e) => e !== n).join(",") : r.includes(e) ? r.map((t) => t === e ? n : t).join(",") : [e, ...r].join(",");
@@ -0,0 +1,28 @@
1
+ import { jwtDecode as e } from "jwt-decode";
2
+ //#region src/admin/constants/admin.constant.ts
3
+ var t = {
4
+ USERS: "admin-users",
5
+ SINGLE_USER: "admin-single-user",
6
+ ORDERS: "admin-orders",
7
+ SINGLE_ORDER: "admin-single-order",
8
+ DISCOUNTS: "admin-discounts",
9
+ SINGLE_DISCOUNT: "admin-single-discount",
10
+ STATIC: "admin-static",
11
+ SINGLE_STATIC: "admin-single-static",
12
+ SUPPORT_REQUESTS: "admin-support-requests",
13
+ SINGLE_SUPPORT_REQUEST: "admin-support-request",
14
+ AVALIABLE_CURRENCIES: "admin-available-currencies",
15
+ ACTIVE_CURRENCIES: "admin-active-currencies",
16
+ GATEWAYS: "admin-gateways",
17
+ BANS: "admin-bans",
18
+ SWAGGER: "admin-swagger",
19
+ BULK_EDIT: "admin-products-bulk-edit"
20
+ }, n = (t) => {
21
+ try {
22
+ return e(t).is_admin === !0;
23
+ } catch {
24
+ return !1;
25
+ }
26
+ };
27
+ //#endregion
28
+ export { t as n, n as t };
@@ -0,0 +1 @@
1
+ let e=require("jwt-decode");var t={USERS:`admin-users`,SINGLE_USER:`admin-single-user`,ORDERS:`admin-orders`,SINGLE_ORDER:`admin-single-order`,DISCOUNTS:`admin-discounts`,SINGLE_DISCOUNT:`admin-single-discount`,STATIC:`admin-static`,SINGLE_STATIC:`admin-single-static`,SUPPORT_REQUESTS:`admin-support-requests`,SINGLE_SUPPORT_REQUEST:`admin-support-request`,AVALIABLE_CURRENCIES:`admin-available-currencies`,ACTIVE_CURRENCIES:`admin-active-currencies`,GATEWAYS:`admin-gateways`,BANS:`admin-bans`,SWAGGER:`admin-swagger`,BULK_EDIT:`admin-products-bulk-edit`},n=t=>{try{return(0,e.jwtDecode)(t).is_admin===!0}catch{return!1}};Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return t}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return n}});
@@ -0,0 +1,16 @@
1
+ //#region src/base/constants/base.constant.ts
2
+ var e = {
3
+ MONEY: "money",
4
+ PERCENT: "percent"
5
+ }, t = {
6
+ PENDING: "PENDING",
7
+ COMPLETED: "COMPLETED",
8
+ FAILED: "FAILED",
9
+ CANCELED: "CANCELED"
10
+ }, n = {
11
+ PENDING: "PENDING",
12
+ SOLVED: "SOLVED",
13
+ CLOSED: "CLOSED"
14
+ };
15
+ //#endregion
16
+ export { t as n, n as r, e as t };
@@ -0,0 +1 @@
1
+ var e={MONEY:`money`,PERCENT:`percent`},t={PENDING:`PENDING`,COMPLETED:`COMPLETED`,FAILED:`FAILED`,CANCELED:`CANCELED`},n={PENDING:`PENDING`,SOLVED:`SOLVED`,CLOSED:`CLOSED`};Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return t}}),Object.defineProperty(exports,"r",{enumerable:!0,get:function(){return n}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return e}});
@@ -1,4 +1,4 @@
1
- //#region src/currency-symbol/constants/currency-symbol.constant.ts
1
+ //#region src/core/currency-symbol/constants/currency-symbol.constant.ts
2
2
  var e = {
3
3
  CHF: "₣",
4
4
  AUD: "A$",
@@ -0,0 +1 @@
1
+ var e={uk:`gb`,en:`gb`,ja:`jp`,zh:`cn`,fr:`fr`,es:`es`,de:`de`,cn:`cn`,ko:`kr`,ar:`sa`,he:`il`,hi:`in`,vi:`vn`,el:`gr`,cs:`cz`,sv:`se`,da:`dk`,fa:`ir`,ur:`pk`,bn:`bd`,ms:`my`,nb:`no`,nn:`no`,ca:`es`,cy:`gb`,ga:`ie`,gd:`gb`,lb:`lu`,eu:`es`,gl:`es`,rm:`ch`,kk:`kz`,hy:`am`,ka:`ge`,sq:`al`,sl:`si`,sr:`rs`,et:`ee`,fil:`ph`,tl:`ph`,sw:`ke`},t=`https://flagcdn.com`,n=`https://flagicons.lipis.dev/flags/4x3`,r=e=>typeof e==`string`&&e.trim().length>0,i=t=>{let n=t.trim().toLowerCase();return Object.hasOwn(e,n)?e[n]:n},a=()=>`${n}/xx.svg`,o=e=>r(e)?`${t}/${i(e)}.svg`:a(),s=e=>r(e)?`${n}/${i(e)}.svg`:a(),c=(e,t)=>{let n=s(t),r=a(),i=e.currentTarget.src;i!==r&&(e.currentTarget.src=i===n?r:n)};Object.defineProperty(exports,"i",{enumerable:!0,get:function(){return c}}),Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return a}}),Object.defineProperty(exports,"r",{enumerable:!0,get:function(){return o}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return s}});
@@ -0,0 +1,52 @@
1
+ //#region src/core/flags/constants/flags.constant.ts
2
+ var e = {
3
+ uk: "gb",
4
+ en: "gb",
5
+ ja: "jp",
6
+ zh: "cn",
7
+ fr: "fr",
8
+ es: "es",
9
+ de: "de",
10
+ cn: "cn",
11
+ ko: "kr",
12
+ ar: "sa",
13
+ he: "il",
14
+ hi: "in",
15
+ vi: "vn",
16
+ el: "gr",
17
+ cs: "cz",
18
+ sv: "se",
19
+ da: "dk",
20
+ fa: "ir",
21
+ ur: "pk",
22
+ bn: "bd",
23
+ ms: "my",
24
+ nb: "no",
25
+ nn: "no",
26
+ ca: "es",
27
+ cy: "gb",
28
+ ga: "ie",
29
+ gd: "gb",
30
+ lb: "lu",
31
+ eu: "es",
32
+ gl: "es",
33
+ rm: "ch",
34
+ kk: "kz",
35
+ hy: "am",
36
+ ka: "ge",
37
+ sq: "al",
38
+ sl: "si",
39
+ sr: "rs",
40
+ et: "ee",
41
+ fil: "ph",
42
+ tl: "ph",
43
+ sw: "ke"
44
+ }, t = "https://flagcdn.com", n = "https://flagicons.lipis.dev/flags/4x3", r = (e) => typeof e == "string" && e.trim().length > 0, i = (t) => {
45
+ let n = t.trim().toLowerCase();
46
+ return Object.hasOwn(e, n) ? e[n] : n;
47
+ }, a = () => `${n}/xx.svg`, o = (e) => r(e) ? `${t}/${i(e)}.svg` : a(), s = (e) => r(e) ? `${n}/${i(e)}.svg` : a(), c = (e, t) => {
48
+ let n = s(t), r = a(), i = e.currentTarget.src;
49
+ i !== r && (e.currentTarget.src = i === n ? r : n);
50
+ };
51
+ //#endregion
52
+ export { c as i, a as n, o as r, s as t };
@@ -1,5 +1,5 @@
1
1
  import { isHTTPError as e } from "ky";
2
- //#region src/handle-api-error/constants/handle-api-error.constant.ts
2
+ //#region src/core/handle-api-error/constants/handle-api-error.constant.ts
3
3
  var t = "Something went wrong", n = /* @__PURE__ */ new Set([
4
4
  "message",
5
5
  "detail",
@@ -1,4 +1,4 @@
1
- //#region src/truncate-decimals/constants/truncate-decimals.constant.ts
1
+ //#region src/core/truncate-decimals/constants/truncate-decimals.constant.ts
2
2
  var e = /^-?\d+(\.\d+)?$/, t = (t, r = 2) => typeof t == "number" ? Number.isFinite(t) ? n(String(t), r) : "N/A" : typeof t == "string" && e.test(t.trim()) ? n(t.trim(), r) : "N/A", n = (e, t) => {
3
3
  let [n, r] = e.split(".");
4
4
  return r === void 0 ? e : t > 0 ? `${n}.${r.slice(0, t)}` : n;
@@ -1,4 +1,4 @@
1
- //#region src/clean-object/index.ts
1
+ //#region src/core/clean-object/index.ts
2
2
  var e = (e) => {
3
3
  let t = {};
4
4
  return Object.entries(e).forEach(([e, n]) => {
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Maps an ISO 639-1 language code to the ISO 3166-1 country code of the flag
3
+ * that should represent it, for languages where the two codes differ.
4
+ *
5
+ * Some mappings are inherently ambiguous (e.g. Arabic, Swahili are official in
6
+ * many countries) — the chosen country is the most common default for that case.
7
+ */
8
+ export declare const FLAG_CODE_ALIASES: Record<string, string>;
9
+ export declare const FLAGS_BASE_URL: "https://flagcdn.com";
10
+ export declare const FLAGS_FALLBACK_URL: "https://flagicons.lipis.dev/flags/4x3";
11
+ /**
12
+ * Code for the "unknown flag" placeholder (a plain flag with no country emblem),
13
+ * only available on {@link FLAGS_FALLBACK_URL} — flagcdn.com has no equivalent.
14
+ */
15
+ export declare const FLAG_UNKNOWN_CODE: "xx";
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Returns the "unknown flag" placeholder URL, used when both {@link getFlagUrl}
3
+ * and {@link getFlagFallbackUrl} fail to load, and as the direct result of either
4
+ * when `languageCode` isn't a usable string (e.g. `null`, `undefined`, `NaN`, an object).
5
+ */
6
+ export declare const getFlagUnknownUrl: () => string;
7
+ /**
8
+ * Returns the primary flag icon URL ({@link FLAGS_BASE_URL}) for the given language/country code.
9
+ * Falls back to {@link getFlagUnknownUrl} if `languageCode` isn't a non-empty string at runtime.
10
+ *
11
+ * @param languageCode - Language or country code (e.g. `en`, `uk`, `fr`)
12
+ */
13
+ export declare const getFlagUrl: (languageCode: string) => string;
14
+ /**
15
+ * Returns the fallback flag icon URL ({@link FLAGS_FALLBACK_URL}), used when
16
+ * the image from {@link getFlagUrl} fails to load. Falls back to {@link getFlagUnknownUrl}
17
+ * if `languageCode` isn't a non-empty string at runtime.
18
+ *
19
+ * @param languageCode - Language or country code (e.g. `en`, `uk`, `fr`)
20
+ */
21
+ export declare const getFlagFallbackUrl: (languageCode: string) => string;
22
+ /**
23
+ * `onError` handler for an `<img>` displaying a flag from {@link getFlagUrl}. Escalates
24
+ * through three tiers, stopping once it reaches the last one to avoid an infinite loop:
25
+ * primary ({@link getFlagUrl}) → fallback ({@link getFlagFallbackUrl}) → unknown-flag
26
+ * placeholder ({@link getFlagUnknownUrl}).
27
+ *
28
+ * @param event - Image error event (DOM `Event` or React's `SyntheticEvent<HTMLImageElement>`)
29
+ * @param languageCode - Same code that was passed to {@link getFlagUrl}
30
+ *
31
+ * @example React
32
+ * ```tsx
33
+ * <img src={getFlagUrl(code)} onError={(e) => handleFlagImageError(e, code)} />
34
+ * ```
35
+ *
36
+ * @example Vue
37
+ * ```vue
38
+ * <img :src="getFlagUrl(code)" @error="(e) => handleFlagImageError(e, code)" />
39
+ * ```
40
+ *
41
+ * @example Svelte
42
+ * ```svelte
43
+ * <img src={getFlagUrl(code)} on:error={(e) => handleFlagImageError(e, code)} />
44
+ * ```
45
+ */
46
+ export declare const handleFlagImageError: (event: {
47
+ currentTarget: HTMLImageElement;
48
+ }, languageCode: string) => void;
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../build-query-params/index.cjs"),t=require("../clean-object/index.cjs"),n=require("../cookies/index.cjs"),r=require("../build-sort-param/index.cjs"),i=require("../chunks/currency-symbol-gb63Q_9Q.cjs"),a=require("../download-file/index.cjs"),o=require("../chunks/flags-BRQ9Jims.cjs"),s=require("../chunks/handle-api-error-D714W9rp.cjs"),c=require("../normalize-input/index.cjs"),l=require("../chunks/truncate-decimals-CArL-IeO.cjs");exports.buildQueryParams=e.buildQueryParams,exports.buildSortParam=r.buildSortParam,exports.cleanObject=t.cleanObject,exports.defaultCookieOptions=n.defaultCookieOptions,exports.deleteCookie=n.deleteCookie,exports.downloadBlob=a.downloadBlob,exports.getCookie=n.getCookie,exports.getCurrencySymbol=i.t,exports.getFlagFallbackUrl=o.t,exports.getFlagUnknownUrl=o.n,exports.getFlagUrl=o.r,exports.handleApiError=s.t,exports.handleFlagImageError=o.i,exports.initHandleApiError=s.n,exports.normalizeDecimalInput=c.normalizeDecimalInput,exports.normalizePhoneNumberInput=c.normalizePhoneNumberInput,exports.setCookie=n.setCookie,exports.truncateDecimals=l.t;
@@ -0,0 +1,10 @@
1
+ export * from './build-query-params';
2
+ export * from './clean-object';
3
+ export * from './cookies';
4
+ export * from './build-sort-param';
5
+ export * from './currency-symbol';
6
+ export * from './download-file';
7
+ export * from './flags';
8
+ export * from './handle-api-error';
9
+ export * from './normalize-input';
10
+ export * from './truncate-decimals';
@@ -0,0 +1,11 @@
1
+ import { buildQueryParams as e } from "../build-query-params/index.js";
2
+ import { cleanObject as t } from "../clean-object/index.js";
3
+ import { defaultCookieOptions as n, deleteCookie as r, getCookie as i, setCookie as a } from "../cookies/index.js";
4
+ import { buildSortParam as o } from "../build-sort-param/index.js";
5
+ import { t as s } from "../chunks/currency-symbol-CJp1EcR5.es";
6
+ import { downloadBlob as c } from "../download-file/index.js";
7
+ import { i as l, n as u, r as d, t as f } from "../chunks/flags-C5E6W9lm.es";
8
+ import { n as p, t as m } from "../chunks/handle-api-error-BYygTKYM.es";
9
+ import { normalizeDecimalInput as h, normalizePhoneNumberInput as g } from "../normalize-input/index.js";
10
+ import { t as _ } from "../chunks/truncate-decimals-BPaTWeHm.es";
11
+ export { e as buildQueryParams, o as buildSortParam, t as cleanObject, n as defaultCookieOptions, r as deleteCookie, c as downloadBlob, i as getCookie, s as getCurrencySymbol, f as getFlagFallbackUrl, u as getFlagUnknownUrl, d as getFlagUrl, m as handleApiError, l as handleFlagImageError, p as initHandleApiError, h as normalizeDecimalInput, g as normalizePhoneNumberInput, a as setCookie, _ as truncateDecimals };
@@ -1,2 +1,2 @@
1
- import { t as e } from "../chunks/currency-symbol-CBowgXv-.es";
1
+ import { t as e } from "../chunks/currency-symbol-CJp1EcR5.es";
2
2
  export { e as getCurrencySymbol };
@@ -1,5 +1,5 @@
1
1
  import { saveAs as e } from "file-saver";
2
- //#region src/download-file/index.ts
2
+ //#region src/core/download-file/index.ts
3
3
  var t = async (e) => {
4
4
  let t = new TextEncoder().encode(String(e)), n = await crypto.subtle.digest("SHA-1", t);
5
5
  return Array.from(new Uint8Array(n)).map((e) => e.toString(16).padStart(2, "0")).join("");
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../chunks/flags-BRQ9Jims.cjs");exports.getFlagFallbackUrl=e.t,exports.getFlagUnknownUrl=e.n,exports.getFlagUrl=e.r,exports.handleFlagImageError=e.i;
@@ -0,0 +1,2 @@
1
+ import { i as e, n as t, r as n, t as r } from "../chunks/flags-C5E6W9lm.es";
2
+ export { r as getFlagFallbackUrl, t as getFlagUnknownUrl, n as getFlagUrl, e as handleFlagImageError };
@@ -1,2 +1,2 @@
1
- import { n as e, t } from "../chunks/handle-api-error-CMd_LxPS.es";
1
+ import { n as e, t } from "../chunks/handle-api-error-BYygTKYM.es";
2
2
  export { t as handleApiError, e as initHandleApiError };
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./build-query-params/index.cjs"),t=require("./clean-object/index.cjs"),n=require("./cookies/index.cjs"),r=require("./build-sort-param/index.cjs"),i=require("./chunks/currency-symbol-gb63Q_9Q.cjs"),a=require("./download-file/index.cjs"),o=require("./chunks/handle-api-error-D714W9rp.cjs"),s=require("./normalize-input/index.cjs"),c=require("./chunks/truncate-decimals-CArL-IeO.cjs");exports.buildQueryParams=e.buildQueryParams,exports.buildSortParam=r.buildSortParam,exports.cleanObject=t.cleanObject,exports.defaultCookieOptions=n.defaultCookieOptions,exports.deleteCookie=n.deleteCookie,exports.downloadBlob=a.downloadBlob,exports.getCookie=n.getCookie,exports.getCurrencySymbol=i.t,exports.handleApiError=o.t,exports.initHandleApiError=o.n,exports.normalizeDecimalInput=s.normalizeDecimalInput,exports.normalizePhoneNumberInput=s.normalizePhoneNumberInput,exports.setCookie=n.setCookie,exports.truncateDecimals=c.t;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./chunks/base-DLHy3wps.cjs"),t=require("./chunks/admin-DR1tBkNV.cjs"),n=require("./build-query-params/index.cjs"),r=require("./clean-object/index.cjs"),i=require("./cookies/index.cjs"),a=require("./build-sort-param/index.cjs"),o=require("./chunks/currency-symbol-gb63Q_9Q.cjs"),s=require("./download-file/index.cjs"),c=require("./chunks/flags-BRQ9Jims.cjs"),l=require("./chunks/handle-api-error-D714W9rp.cjs"),u=require("./normalize-input/index.cjs"),d=require("./chunks/truncate-decimals-CArL-IeO.cjs");require("./core/index.cjs"),exports.ADMIN_QUERY_KEYS=t.n,exports.DISCOUNT_TYPES=e.t,exports.ORDER_STATUSES=e.n,exports.SUPPORT_STATUSES=e.r,exports.buildQueryParams=n.buildQueryParams,exports.buildSortParam=a.buildSortParam,exports.cleanObject=r.cleanObject,exports.defaultCookieOptions=i.defaultCookieOptions,exports.deleteCookie=i.deleteCookie,exports.downloadBlob=s.downloadBlob,exports.getCookie=i.getCookie,exports.getCurrencySymbol=o.t,exports.getFlagFallbackUrl=c.t,exports.getFlagUnknownUrl=c.n,exports.getFlagUrl=c.r,exports.handleApiError=l.t,exports.handleFlagImageError=c.i,exports.initHandleApiError=l.n,exports.isAdminToken=t.t,exports.normalizeDecimalInput=u.normalizeDecimalInput,exports.normalizePhoneNumberInput=u.normalizePhoneNumberInput,exports.setCookie=i.setCookie,exports.truncateDecimals=d.t;
package/dist/index.d.ts CHANGED
@@ -1,10 +1,3 @@
1
- export * from './build-query-params';
2
- export * from './clean-object';
3
- export * from './cookies';
4
- export type * from './types';
5
- export * from './build-sort-param';
6
- export * from './currency-symbol';
7
- export * from './download-file';
8
- export * from './handle-api-error';
9
- export * from './normalize-input';
10
- export * from './truncate-decimals';
1
+ export * from './base';
2
+ export * from './admin';
3
+ export * from './core';
package/dist/index.js CHANGED
@@ -1,10 +1,14 @@
1
- import { buildQueryParams as e } from "./build-query-params/index.js";
2
- import { cleanObject as t } from "./clean-object/index.js";
3
- import { defaultCookieOptions as n, deleteCookie as r, getCookie as i, setCookie as a } from "./cookies/index.js";
4
- import { buildSortParam as o } from "./build-sort-param/index.js";
5
- import { t as s } from "./chunks/currency-symbol-CBowgXv-.es";
6
- import { downloadBlob as c } from "./download-file/index.js";
7
- import { n as l, t as u } from "./chunks/handle-api-error-CMd_LxPS.es";
8
- import { normalizeDecimalInput as d, normalizePhoneNumberInput as f } from "./normalize-input/index.js";
9
- import { t as p } from "./chunks/truncate-decimals-BFMoEzul.es";
10
- export { e as buildQueryParams, o as buildSortParam, t as cleanObject, n as defaultCookieOptions, r as deleteCookie, c as downloadBlob, i as getCookie, s as getCurrencySymbol, u as handleApiError, l as initHandleApiError, d as normalizeDecimalInput, f as normalizePhoneNumberInput, a as setCookie, p as truncateDecimals };
1
+ import { n as e, r as t, t as n } from "./chunks/base-C5926Kyt.es";
2
+ import { n as r, t as i } from "./chunks/admin-B3AZrTOb.es";
3
+ import { buildQueryParams as a } from "./build-query-params/index.js";
4
+ import { cleanObject as o } from "./clean-object/index.js";
5
+ import { defaultCookieOptions as s, deleteCookie as c, getCookie as l, setCookie as u } from "./cookies/index.js";
6
+ import { buildSortParam as d } from "./build-sort-param/index.js";
7
+ import { t as f } from "./chunks/currency-symbol-CJp1EcR5.es";
8
+ import { downloadBlob as p } from "./download-file/index.js";
9
+ import { i as m, n as h, r as g, t as _ } from "./chunks/flags-C5E6W9lm.es";
10
+ import { n as v, t as y } from "./chunks/handle-api-error-BYygTKYM.es";
11
+ import { normalizeDecimalInput as b, normalizePhoneNumberInput as x } from "./normalize-input/index.js";
12
+ import { t as S } from "./chunks/truncate-decimals-BPaTWeHm.es";
13
+ import "./core/index.js";
14
+ export { r as ADMIN_QUERY_KEYS, n as DISCOUNT_TYPES, e as ORDER_STATUSES, t as SUPPORT_STATUSES, a as buildQueryParams, d as buildSortParam, o as cleanObject, s as defaultCookieOptions, c as deleteCookie, p as downloadBlob, l as getCookie, f as getCurrencySymbol, _ as getFlagFallbackUrl, h as getFlagUnknownUrl, g as getFlagUrl, y as handleApiError, m as handleFlagImageError, v as initHandleApiError, i as isAdminToken, b as normalizeDecimalInput, x as normalizePhoneNumberInput, u as setCookie, S as truncateDecimals };
@@ -1,4 +1,4 @@
1
- //#region src/normalize-input/index.ts
1
+ //#region src/core/normalize-input/index.ts
2
2
  var e = (e, t = 2) => {
3
3
  let n = e.target, r = n.value;
4
4
  r = r.replace(",", "."), r = r.replace(/[^0-9.]/g, "");
@@ -1,2 +1,2 @@
1
- import { t as e } from "../chunks/truncate-decimals-BFMoEzul.es";
1
+ import { t as e } from "../chunks/truncate-decimals-BPaTWeHm.es";
2
2
  export { e as truncateDecimals };
package/package.json CHANGED
@@ -2,10 +2,11 @@
2
2
  "name": "@ptx-showcase/utils",
3
3
  "author": "ptx-showcase",
4
4
  "description": "Shared utilities for PTX Showcase projects",
5
- "version": "0.6.0",
5
+ "version": "1.1.0",
6
6
  "private": false,
7
7
  "type": "module",
8
8
  "license": "MIT",
9
+ "sideEffects": false,
9
10
  "repository": {
10
11
  "type": "git",
11
12
  "url": "git+https://github.com/gibPerviy/ptx-showcase-utils.git"
@@ -31,60 +32,75 @@
31
32
  "require": "./dist/index.cjs",
32
33
  "types": "./dist/index.d.ts"
33
34
  },
35
+ "./admin": {
36
+ "import": "./dist/admin/index.js",
37
+ "require": "./dist/admin/index.cjs",
38
+ "types": "./dist/admin/index.d.ts"
39
+ },
40
+ "./base": {
41
+ "import": "./dist/base/index.js",
42
+ "require": "./dist/base/index.cjs",
43
+ "types": "./dist/base/index.d.ts"
44
+ },
45
+ "./core": {
46
+ "import": "./dist/core/index.js",
47
+ "require": "./dist/core/index.cjs",
48
+ "types": "./dist/core/index.d.ts"
49
+ },
34
50
  "./cookies": {
35
51
  "import": "./dist/cookies/index.js",
36
52
  "require": "./dist/cookies/index.cjs",
37
- "types": "./dist/cookies/index.d.ts"
53
+ "types": "./dist/core/cookies/index.d.ts"
38
54
  },
39
55
  "./build-query-params": {
40
56
  "import": "./dist/build-query-params/index.js",
41
57
  "require": "./dist/build-query-params/index.cjs",
42
- "types": "./dist/build-query-params/index.d.ts"
58
+ "types": "./dist/core/build-query-params/index.d.ts"
43
59
  },
44
60
  "./build-sort-param": {
45
61
  "import": "./dist/build-sort-param/index.js",
46
62
  "require": "./dist/build-sort-param/index.cjs",
47
- "types": "./dist/build-sort-param/index.d.ts"
63
+ "types": "./dist/core/build-sort-param/index.d.ts"
48
64
  },
49
65
  "./clean-object": {
50
66
  "import": "./dist/clean-object/index.js",
51
67
  "require": "./dist/clean-object/index.cjs",
52
- "types": "./dist/clean-object/index.d.ts"
68
+ "types": "./dist/core/clean-object/index.d.ts"
53
69
  },
54
70
  "./currency-symbol": {
55
71
  "import": "./dist/currency-symbol/index.js",
56
72
  "require": "./dist/currency-symbol/index.cjs",
57
- "types": "./dist/currency-symbol/index.d.ts"
73
+ "types": "./dist/core/currency-symbol/index.d.ts"
58
74
  },
59
75
  "./download-file": {
60
76
  "import": "./dist/download-file/index.js",
61
77
  "require": "./dist/download-file/index.cjs",
62
- "types": "./dist/download-file/index.d.ts"
78
+ "types": "./dist/core/download-file/index.d.ts"
79
+ },
80
+ "./flags": {
81
+ "import": "./dist/flags/index.js",
82
+ "require": "./dist/flags/index.cjs",
83
+ "types": "./dist/core/flags/index.d.ts"
63
84
  },
64
85
  "./handle-api-error": {
65
86
  "import": "./dist/handle-api-error/index.js",
66
87
  "require": "./dist/handle-api-error/index.cjs",
67
- "types": "./dist/handle-api-error/index.d.ts"
88
+ "types": "./dist/core/handle-api-error/index.d.ts"
68
89
  },
69
90
  "./normalize-input": {
70
91
  "import": "./dist/normalize-input/index.js",
71
92
  "require": "./dist/normalize-input/index.cjs",
72
- "types": "./dist/normalize-input/index.d.ts"
93
+ "types": "./dist/core/normalize-input/index.d.ts"
73
94
  },
74
95
  "./truncate-decimals": {
75
96
  "import": "./dist/truncate-decimals/index.js",
76
97
  "require": "./dist/truncate-decimals/index.cjs",
77
- "types": "./dist/truncate-decimals/index.d.ts"
78
- },
79
- "./types": {
80
- "import": "./dist/types/index.js",
81
- "require": "./dist/types/index.cjs",
82
- "types": "./dist/types/index.d.ts"
98
+ "types": "./dist/core/truncate-decimals/index.d.ts"
83
99
  }
84
100
  },
85
101
  "scripts": {
86
102
  "dev": "vite",
87
- "test": "vitest",
103
+ "test": "vitest run",
88
104
  "build": "vite build",
89
105
  "lint": "oxlint",
90
106
  "lint:fix": "oxlint --fix",
@@ -97,20 +113,21 @@
97
113
  "access": "public"
98
114
  },
99
115
  "devDependencies": {
100
- "@types/node": "^26.4.0",
101
- "bumpp": "^12.2.2",
102
- "oxfmt": "^0.65.0",
103
- "oxlint": "^1.80.0",
116
+ "@types/node": "^26.6.1",
117
+ "bumpp": "^12.3.0",
118
+ "oxfmt": "^0.68.0",
119
+ "oxlint": "^1.83.0",
104
120
  "typescript": "~6.0.3",
105
- "vite": "^8.2.2",
106
- "vite-plugin-dts": "^5.0.3",
107
- "vitest": "^4.1.11"
121
+ "vite": "^8.3.0",
122
+ "vite-plugin-dts": "^5.1.0",
123
+ "vitest": "^5.0.1"
108
124
  },
109
125
  "dependencies": {
110
126
  "@types/file-saver": "^2.0.7",
111
127
  "@types/js-cookie": "^3.0.6",
112
128
  "file-saver": "^2.0.5",
113
129
  "js-cookie": "^3.0.8",
130
+ "jwt-decode": "^4.0.0",
114
131
  "ky": "^2.1.0"
115
132
  }
116
133
  }
File without changes
@@ -1,13 +0,0 @@
1
- export interface TableColumnConfig<T, ExtraKeys extends string = never> {
2
- id?: number;
3
- label: string;
4
- key: keyof T | ExtraKeys;
5
- sortable?: boolean;
6
- }
7
- export interface PaginatedList<T> {
8
- items: T[];
9
- page: number;
10
- per_page: number;
11
- total_items: number;
12
- total_pages: number;
13
- }
File without changes
File without changes