@ptx-showcase/utils 0.5.0 → 1.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.
Files changed (54) hide show
  1. package/README.md +64 -12
  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/{handle-api-error-CMd_LxPS.es → handle-api-error-BYygTKYM.es} +1 -1
  21. package/dist/chunks/truncate-decimals-BPaTWeHm.es +7 -0
  22. package/dist/chunks/truncate-decimals-CArL-IeO.cjs +1 -0
  23. package/dist/clean-object/index.js +1 -1
  24. package/dist/core/index.cjs +1 -0
  25. package/dist/core/index.d.ts +9 -0
  26. package/dist/core/index.js +10 -0
  27. package/dist/core/truncate-decimals/constants/truncate-decimals.constant.d.ts +1 -0
  28. package/dist/core/truncate-decimals/index.d.ts +32 -0
  29. package/dist/currency-symbol/index.js +1 -1
  30. package/dist/download-file/index.js +1 -1
  31. package/dist/handle-api-error/index.js +1 -1
  32. package/dist/index.cjs +1 -1
  33. package/dist/index.d.ts +3 -9
  34. package/dist/index.js +13 -9
  35. package/dist/normalize-input/index.js +1 -1
  36. package/dist/truncate-decimals/index.cjs +1 -0
  37. package/dist/truncate-decimals/index.js +2 -0
  38. package/package.json +39 -22
  39. package/dist/types/index.cjs +0 -0
  40. package/dist/types/index.d.ts +0 -13
  41. package/dist/types/index.js +0 -0
  42. /package/dist/{build-query-params → core/build-query-params}/index.d.ts +0 -0
  43. /package/dist/{build-sort-param → core/build-sort-param}/index.d.ts +0 -0
  44. /package/dist/{clean-object → core/clean-object}/index.d.ts +0 -0
  45. /package/dist/{cookies → core/cookies}/index.d.ts +0 -0
  46. /package/dist/{currency-symbol → core/currency-symbol}/constants/currency-symbol.constant.d.ts +0 -0
  47. /package/dist/{currency-symbol → core/currency-symbol}/index.d.ts +0 -0
  48. /package/dist/{download-file → core/download-file}/index.d.ts +0 -0
  49. /package/dist/{handle-api-error → core/handle-api-error}/constants/handle-api-error.constant.d.ts +0 -0
  50. /package/dist/{handle-api-error → core/handle-api-error}/index.d.ts +0 -0
  51. /package/dist/{handle-api-error → core/handle-api-error}/libs/handle-api-error.lib.d.ts +0 -0
  52. /package/dist/{handle-api-error → core/handle-api-error}/libs/init-handle-api-error.lib.d.ts +0 -0
  53. /package/dist/{handle-api-error → core/handle-api-error}/types/handle-api-error.type.d.ts +0 -0
  54. /package/dist/{normalize-input → core/normalize-input}/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
 
@@ -183,6 +188,24 @@ try {
183
188
 
184
189
  ---
185
190
 
191
+ ### isAdminToken
192
+
193
+ 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.
194
+
195
+ ```ts
196
+ // from root
197
+ import { isAdminToken } from '@ptx-showcase/utils'
198
+
199
+ // from subpath
200
+ import { isAdminToken } from '@ptx-showcase/utils/admin'
201
+
202
+ isAdminToken(adminToken) // → true
203
+ isAdminToken(regularUserToken) // → false
204
+ isAdminToken('not-a-valid-jwt') // → false
205
+ ```
206
+
207
+ ---
208
+
186
209
  ### normalizeDecimalInput / normalizePhoneNumberInput
187
210
 
188
211
  In-place `input`/`change` event handlers that sanitize a text input's value as the user types.
@@ -208,19 +231,48 @@ import { normalizeDecimalInput, normalizePhoneNumberInput } from '@ptx-showcase/
208
231
 
209
232
  ---
210
233
 
234
+ ### truncateDecimals
235
+
236
+ Formats a number (or numeric string) to a fixed number of decimal places by cutting the extra digits off, **without rounding**. Accepts a string too, so values more precise than a JS `number` can hold (e.g. amounts from an API) can be truncated without a lossy float conversion first. Returns `'N/A'` for anything that isn't a finite number or a well-formed numeric string.
237
+
238
+ ```ts
239
+ // from root
240
+ import { truncateDecimals } from '@ptx-showcase/utils'
241
+
242
+ // from subpath
243
+ import { truncateDecimals } from '@ptx-showcase/utils/truncate-decimals'
244
+
245
+ truncateDecimals(4.21312312) // → '4.21'
246
+ truncateDecimals(4.995) // → '4.99' (not rounded to 5.00)
247
+ truncateDecimals(4.2) // → '4.2' (fewer decimals than requested — left untouched)
248
+ truncateDecimals(4.219, 0) // → '4'
249
+
250
+ // numeric string input — no float precision loss
251
+ truncateDecimals('4.219999999999999999999999', 2) // → '4.21'
252
+
253
+ // invalid input
254
+ truncateDecimals('not a number') // → 'N/A'
255
+ truncateDecimals(undefined) // → 'N/A'
256
+ ```
257
+
258
+ ---
259
+
211
260
  ## Available modules
212
261
 
213
- | Subpath | Exports |
214
- | ---------------------------------------- | ---------------------------------------------------------------- |
215
- | `@ptx-showcase/utils` | all utilities |
216
- | `@ptx-showcase/utils/build-query-params` | `buildQueryParams` |
217
- | `@ptx-showcase/utils/build-sort-param` | `buildSortParam` |
218
- | `@ptx-showcase/utils/cookies` | `setCookie`, `getCookie`, `deleteCookie`, `defaultCookieOptions` |
219
- | `@ptx-showcase/utils/currency-symbol` | `getCurrencySymbol` |
220
- | `@ptx-showcase/utils/download-file` | `downloadBlob` |
221
- | `@ptx-showcase/utils/handle-api-error` | `handleApiError`, `initHandleApiError` |
222
- | `@ptx-showcase/utils/normalize-input` | `normalizeDecimalInput`, `normalizePhoneNumberInput` |
223
- | `@ptx-showcase/utils/types` | `TableColumnConfig`, `PaginatedList` |
262
+ | Subpath | Exports |
263
+ | ---------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
264
+ | `@ptx-showcase/utils` | everything below |
265
+ | `@ptx-showcase/utils/base` | `TableColumnConfig`, `PaginatedList`, `ListQueryParams`, `DISCOUNT_TYPES`, `ORDER_STATUSES`, `SUPPORT_STATUSES` |
266
+ | `@ptx-showcase/utils/admin` | `isAdminToken`, `ADMIN_QUERY_KEYS` (admin-panel projects only) |
267
+ | `@ptx-showcase/utils/core` | every generic utility below, bundled together |
268
+ | `@ptx-showcase/utils/build-query-params` | `buildQueryParams` |
269
+ | `@ptx-showcase/utils/build-sort-param` | `buildSortParam` |
270
+ | `@ptx-showcase/utils/cookies` | `setCookie`, `getCookie`, `deleteCookie`, `defaultCookieOptions` |
271
+ | `@ptx-showcase/utils/currency-symbol` | `getCurrencySymbol` |
272
+ | `@ptx-showcase/utils/download-file` | `downloadBlob` |
273
+ | `@ptx-showcase/utils/handle-api-error` | `handleApiError`, `initHandleApiError` |
274
+ | `@ptx-showcase/utils/normalize-input` | `normalizeDecimalInput`, `normalizePhoneNumberInput` |
275
+ | `@ptx-showcase/utils/truncate-decimals` | `truncateDecimals` |
224
276
 
225
277
  ---
226
278
 
@@ -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$",
@@ -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",
@@ -0,0 +1,7 @@
1
+ //#region src/core/truncate-decimals/constants/truncate-decimals.constant.ts
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
+ let [n, r] = e.split(".");
4
+ return r === void 0 ? e : t > 0 ? `${n}.${r.slice(0, t)}` : n;
5
+ };
6
+ //#endregion
7
+ export { t };
@@ -0,0 +1 @@
1
+ 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)=>{let[n,r]=e.split(`.`);return r===void 0?e:t>0?`${n}.${r.slice(0,t)}`:n};Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return t}});
@@ -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 @@
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;
@@ -0,0 +1,9 @@
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 './handle-api-error';
8
+ export * from './normalize-input';
9
+ export * from './truncate-decimals';
@@ -0,0 +1,10 @@
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 { n as l, t as u } from "../chunks/handle-api-error-BYygTKYM.es";
8
+ import { normalizeDecimalInput as d, normalizePhoneNumberInput as f } from "../normalize-input/index.js";
9
+ import { t as p } from "../chunks/truncate-decimals-BPaTWeHm.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 };
@@ -0,0 +1 @@
1
+ export declare const NUMERIC_STRING_PATTERN: RegExp;
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Formats a number (or numeric string) to a fixed number of decimal places
3
+ * by cutting the extra digits off, without rounding.
4
+ *
5
+ * Unlike `toFixed`, `4.21312312` truncated to 2 decimals stays `4.21`
6
+ * instead of being rounded to `4.21`/`4.22` depending on the digits that follow.
7
+ *
8
+ * Accepts a string as well as a number so that values with more precision
9
+ * than a JS `number` can hold safely (e.g. amounts coming from an API as
10
+ * strings) can be truncated without going through a lossy float conversion first.
11
+ *
12
+ * Numbers large/small enough to be stringified in exponential notation
13
+ * (e.g. `1e+21`, `1e-7`) are returned as-is, since there's no decimal part to cut.
14
+ *
15
+ * @param value - The number (or numeric string) to truncate
16
+ * @param decimals - Number of digits to keep after the decimal point.
17
+ * Pass `0` to drop the decimal part entirely. Defaults to `2`.
18
+ * @returns The truncated value as a string; `'N/A'` if `value` isn't a finite
19
+ * number or a well-formed numeric string (e.g. `undefined`, `null`, `NaN`,
20
+ * `{}`, `[]`, `'not a number'`)
21
+ *
22
+ * @example
23
+ * ```ts
24
+ * truncateDecimals(4.21312312) // => '4.21'
25
+ * truncateDecimals(4.2) // => '4.2' (fewer decimals than requested — left untouched)
26
+ * truncateDecimals(4.219, 0) // => '4'
27
+ * truncateDecimals('4.219999999999999999999999', 2) // => '4.21' (string input, no float precision loss)
28
+ * truncateDecimals('not a number') // => 'N/A'
29
+ * truncateDecimals(undefined as unknown as number) // => 'N/A'
30
+ * ```
31
+ */
32
+ export declare const truncateDecimals: (value: number | string, decimals?: number) => string;
@@ -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("");
@@ -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");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;
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/handle-api-error-D714W9rp.cjs"),l=require("./normalize-input/index.cjs"),u=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.handleApiError=c.t,exports.initHandleApiError=c.n,exports.isAdminToken=t.t,exports.normalizeDecimalInput=l.normalizeDecimalInput,exports.normalizePhoneNumberInput=l.normalizePhoneNumberInput,exports.setCookie=i.setCookie,exports.truncateDecimals=u.t;
package/dist/index.d.ts CHANGED
@@ -1,9 +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';
1
+ export * from './base';
2
+ export * from './admin';
3
+ export * from './core';
package/dist/index.js CHANGED
@@ -1,9 +1,13 @@
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
- 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 };
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 { n as m, t as h } from "./chunks/handle-api-error-BYygTKYM.es";
10
+ import { normalizeDecimalInput as g, normalizePhoneNumberInput as _ } from "./normalize-input/index.js";
11
+ import { t as v } from "./chunks/truncate-decimals-BPaTWeHm.es";
12
+ import "./core/index.js";
13
+ 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, h as handleApiError, m as initHandleApiError, i as isAdminToken, g as normalizeDecimalInput, _ as normalizePhoneNumberInput, u as setCookie, v 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, "");
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../chunks/truncate-decimals-CArL-IeO.cjs");exports.truncateDecimals=e.t;
@@ -0,0 +1,2 @@
1
+ import { t as e } from "../chunks/truncate-decimals-BPaTWeHm.es";
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.5.0",
5
+ "version": "1.0.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,55 +32,70 @@
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"
63
79
  },
64
80
  "./handle-api-error": {
65
81
  "import": "./dist/handle-api-error/index.js",
66
82
  "require": "./dist/handle-api-error/index.cjs",
67
- "types": "./dist/handle-api-error/index.d.ts"
83
+ "types": "./dist/core/handle-api-error/index.d.ts"
68
84
  },
69
85
  "./normalize-input": {
70
86
  "import": "./dist/normalize-input/index.js",
71
87
  "require": "./dist/normalize-input/index.cjs",
72
- "types": "./dist/normalize-input/index.d.ts"
88
+ "types": "./dist/core/normalize-input/index.d.ts"
73
89
  },
74
- "./types": {
75
- "import": "./dist/types/index.js",
76
- "require": "./dist/types/index.cjs",
77
- "types": "./dist/types/index.d.ts"
90
+ "./truncate-decimals": {
91
+ "import": "./dist/truncate-decimals/index.js",
92
+ "require": "./dist/truncate-decimals/index.cjs",
93
+ "types": "./dist/core/truncate-decimals/index.d.ts"
78
94
  }
79
95
  },
80
96
  "scripts": {
81
97
  "dev": "vite",
82
- "test": "vitest",
98
+ "test": "vitest run",
83
99
  "build": "vite build",
84
100
  "lint": "oxlint",
85
101
  "lint:fix": "oxlint --fix",
@@ -92,20 +108,21 @@
92
108
  "access": "public"
93
109
  },
94
110
  "devDependencies": {
95
- "@types/node": "^26.1.2",
96
- "bumpp": "^12.2.0",
97
- "oxfmt": "^0.62.0",
98
- "oxlint": "^1.77.0",
111
+ "@types/node": "^26.6.1",
112
+ "bumpp": "^12.3.0",
113
+ "oxfmt": "^0.68.0",
114
+ "oxlint": "^1.83.0",
99
115
  "typescript": "~6.0.3",
100
- "vite": "^8.2.1",
101
- "vite-plugin-dts": "^5.0.3",
102
- "vitest": "^4.1.10"
116
+ "vite": "^8.3.0",
117
+ "vite-plugin-dts": "^5.1.0",
118
+ "vitest": "^5.0.1"
103
119
  },
104
120
  "dependencies": {
105
121
  "@types/file-saver": "^2.0.7",
106
122
  "@types/js-cookie": "^3.0.6",
107
123
  "file-saver": "^2.0.5",
108
124
  "js-cookie": "^3.0.8",
109
- "ky": "^2.0.2"
125
+ "jwt-decode": "^4.0.0",
126
+ "ky": "^2.1.0"
110
127
  }
111
128
  }
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