@ptx-showcase/utils 0.2.2 → 0.2.4

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/README.md CHANGED
@@ -4,7 +4,7 @@ Shared utilities for PTX Showcase projects.
4
4
 
5
5
  ---
6
6
 
7
- ## 📦 Installation
7
+ ## Installation
8
8
 
9
9
  ```bash
10
10
  npm install @ptx-showcase/utils
@@ -18,42 +18,128 @@ bun add @ptx-showcase/utils
18
18
 
19
19
  ---
20
20
 
21
- ## 🚀 Usage
21
+ ## Usage
22
22
 
23
- ### Cookie utilities
23
+ All utilities can be imported from the root package or from a specific subpath.
24
+
25
+ ---
26
+
27
+ ### buildQueryParams
28
+
29
+ Builds a URL query string from an object. Skips `null`, `undefined`, empty strings, and empty arrays.
30
+
31
+ ```ts
32
+ // from root
33
+ import { buildQueryParams } from '@ptx-showcase/utils'
34
+
35
+ // from subpath
36
+ import { buildQueryParams } from '@ptx-showcase/utils/build-query-params'
37
+
38
+ buildQueryParams({ page: 1, search: 'test', empty: '' })
39
+ // → '?page=1&search=test'
40
+
41
+ buildQueryParams({ ids: [], status: 'active' })
42
+ // → '?status=active'
43
+
44
+ buildQueryParams({})
45
+ // → ''
46
+ ```
47
+
48
+ ---
49
+
50
+ ### buildSortParam
51
+
52
+ Builds a comma-separated sort string with toggle logic: first call adds the field, second toggles to descending (`-field`), third removes it.
53
+
54
+ ```ts
55
+ // from root
56
+ import { buildSortParam } from '@ptx-showcase/utils'
57
+
58
+ // from subpath
59
+ import { buildSortParam } from '@ptx-showcase/utils/build-sort-param'
60
+
61
+ buildSortParam('name') // → 'name'
62
+ buildSortParam('name', 'name') // → '-name'
63
+ buildSortParam('name', '-name') // → ''
64
+
65
+ // combining with existing sort
66
+ buildSortParam('age', 'name') // → 'age,name'
67
+ buildSortParam('age', 'age,name') // → '-age,name'
68
+ ```
69
+
70
+ ---
71
+
72
+ ### Cookies
73
+
74
+ Cookie helpers with secure defaults (`expires: 1h`, `secure: true`, `sameSite: Strict`).
24
75
 
25
76
  ```ts
77
+ // from root
78
+ import { setCookie, getCookie, deleteCookie } from '@ptx-showcase/utils'
79
+
80
+ // from subpath
26
81
  import { setCookie, getCookie, deleteCookie } from '@ptx-showcase/utils/cookies'
27
82
 
28
- // set cookie
29
- setCookie('token', '123')
83
+ // set (uses default options)
84
+ setCookie('token', 'abc123')
85
+
86
+ // set with custom options
87
+ setCookie('session', 'xyz', { expires: 7, sameSite: 'Lax' })
30
88
 
31
- // get cookie
32
- const token = getCookie('token')
89
+ // get
90
+ const token = getCookie('token') // → 'abc123' | undefined
33
91
 
34
- // delete cookie
92
+ // delete
35
93
  deleteCookie('token')
36
94
  ```
37
95
 
96
+ Default options:
97
+
98
+ | Option | Value |
99
+ |------------|------------|
100
+ | `expires` | 1 hour |
101
+ | `secure` | `true` |
102
+ | `sameSite` | `'Strict'` |
103
+
38
104
  ---
39
105
 
40
- ## 📁 Available modules
106
+ ### downloadBlob
107
+
108
+ Downloads a `Blob` as a file in the browser. Accepts either an explicit filename or a hash value (auto-generates a SHA-1 filename).
109
+
110
+ ```ts
111
+ // from root
112
+ import { downloadBlob } from '@ptx-showcase/utils'
41
113
 
42
- - `@ptx-showcase/utils` — base utilities
43
- - `@ptx-showcase/utils/cookie` — cookie helpers
114
+ // from subpath
115
+ import { downloadBlob } from '@ptx-showcase/utils/download-file'
116
+
117
+ const blob = new Blob(['Hello, World!'], { type: 'text/plain' })
118
+
119
+ // with explicit filename
120
+ await downloadBlob(blob, { filename: 'report.txt' })
121
+
122
+ // with auto-generated SHA-1 filename
123
+ await downloadBlob(blob, { hash: 12345 })
124
+ // → saves as e.g. '17b840d9...'
125
+ ```
44
126
 
45
127
  ---
46
128
 
47
- ## 🧠 Features
129
+ ## Available modules
48
130
 
49
- - TypeScript support out of the box
50
- - ESM + CommonJS compatibility
51
- - Modular architecture (subpath imports)
52
- - Lightweight and reusable across projects
131
+ | Subpath | Exports |
132
+ |---------------------------------------------|------------------------------------------------------|
133
+ | `@ptx-showcase/utils` | all utilities |
134
+ | `@ptx-showcase/utils/build-query-params` | `buildQueryParams` |
135
+ | `@ptx-showcase/utils/build-sort-param` | `buildSortParam` |
136
+ | `@ptx-showcase/utils/cookies` | `setCookie`, `getCookie`, `deleteCookie`, `defaultCookieOptions` |
137
+ | `@ptx-showcase/utils/download-file` | `downloadBlob` |
138
+ | `@ptx-showcase/utils/types` | `TableColumnConfig` |
53
139
 
54
140
  ---
55
141
 
56
- ## 🔄 Versioning
142
+ ## Versioning
57
143
 
58
144
  This package follows [Semantic Versioning](https://semver.org/):
59
145
 
@@ -63,12 +149,12 @@ This package follows [Semantic Versioning](https://semver.org/):
63
149
 
64
150
  ---
65
151
 
66
- ## 📜 Changelog
152
+ ## Changelog
67
153
 
68
154
  See [CHANGELOG.md](./CHANGELOG.md) for all changes.
69
155
 
70
156
  ---
71
157
 
72
- ## 📄 License
158
+ ## License
73
159
 
74
160
  MIT
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=e=>{let t=new URLSearchParams;Object.entries(e).forEach(([e,n])=>{n==null||n===``||t.append(e,String(n))});let n=t.toString();return n?`?${n}`:``};exports.buildQueryParams=e;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=e=>{let t=new URLSearchParams;Object.entries(e).forEach(([e,n])=>{n==null||n===``||Array.isArray(n)&&n.length===0||t.append(e,String(n))});let n=t.toString();return n?`?${n}`:``};exports.buildQueryParams=e;
@@ -2,7 +2,7 @@
2
2
  var e = (e) => {
3
3
  let t = new URLSearchParams();
4
4
  Object.entries(e).forEach(([e, n]) => {
5
- n == null || n === "" || t.append(e, String(n));
5
+ n == null || n === "" || Array.isArray(n) && n.length === 0 || t.append(e, String(n));
6
6
  });
7
7
  let n = t.toString();
8
8
  return n ? `?${n}` : "";
@@ -0,0 +1 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("file-saver");var t=async e=>{let t=new TextEncoder().encode(String(e)),n=await crypto.subtle.digest(`SHA-1`,t);return Array.from(new Uint8Array(n)).map(e=>e.toString(16).padStart(2,`0`)).join(``)},n=async(n,r)=>{if(!(n instanceof Blob))throw Error(`downloadBlob: expected Blob, got ${typeof n}`);(0,e.saveAs)(n,`filename`in r?r.filename:await t(r.hash))};exports.downloadBlob=n;
@@ -0,0 +1,7 @@
1
+ type DownloadBlobOptions = {
2
+ filename: string;
3
+ } | {
4
+ hash: string | number;
5
+ };
6
+ export declare const downloadBlob: (blob: Blob, options: DownloadBlobOptions) => Promise<void>;
7
+ export {};
@@ -0,0 +1,11 @@
1
+ import { saveAs as e } from "file-saver";
2
+ //#region src/download-file/index.ts
3
+ var t = async (e) => {
4
+ let t = new TextEncoder().encode(String(e)), n = await crypto.subtle.digest("SHA-1", t);
5
+ return Array.from(new Uint8Array(n)).map((e) => e.toString(16).padStart(2, "0")).join("");
6
+ }, n = async (n, r) => {
7
+ if (!(n instanceof Blob)) throw Error(`downloadBlob: expected Blob, got ${typeof n}`);
8
+ e(n, "filename" in r ? r.filename : await t(r.hash));
9
+ };
10
+ //#endregion
11
+ export { n as downloadBlob };
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./chunks/cookies-BayERMbH.cjs"),t=require("./build-query-params/index.cjs"),n=require("./clean-object/index.cjs"),r=require("./build-sort-param/index.cjs");exports.buildQueryParams=t.buildQueryParams,exports.buildSortParam=r.buildSortParam,exports.cleanObject=n.cleanObject,exports.defaultCookieOptions=e.t,exports.deleteCookie=e.n,exports.getCookie=e.r,exports.setCookie=e.i;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./chunks/cookies-BayERMbH.cjs"),t=require("./build-query-params/index.cjs"),n=require("./clean-object/index.cjs"),r=require("./build-sort-param/index.cjs"),i=require("./download-file/index.cjs");exports.buildQueryParams=t.buildQueryParams,exports.buildSortParam=r.buildSortParam,exports.cleanObject=n.cleanObject,exports.defaultCookieOptions=e.t,exports.deleteCookie=e.n,exports.downloadBlob=i.downloadBlob,exports.getCookie=e.r,exports.setCookie=e.i;
package/dist/index.d.ts CHANGED
@@ -3,3 +3,4 @@ export * from './clean-object';
3
3
  export * from './cookies';
4
4
  export type * from './types';
5
5
  export * from './build-sort-param';
6
+ export * from './download-file';
package/dist/index.js CHANGED
@@ -2,4 +2,5 @@ import { buildQueryParams as e } from "./build-query-params/index.js";
2
2
  import { cleanObject as t } from "./clean-object/index.js";
3
3
  import { defaultCookieOptions as n, deleteCookie as r, getCookie as i, setCookie as a } from "./cookies/index.js";
4
4
  import { buildSortParam as o } from "./build-sort-param/index.js";
5
- export { e as buildQueryParams, o as buildSortParam, t as cleanObject, n as defaultCookieOptions, r as deleteCookie, i as getCookie, a as setCookie };
5
+ import { downloadBlob as s } from "./download-file/index.js";
6
+ export { e as buildQueryParams, o as buildSortParam, t as cleanObject, n as defaultCookieOptions, r as deleteCookie, s as downloadBlob, i as getCookie, a as setCookie };
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@ptx-showcase/utils",
3
3
  "author": "ptx-showcase",
4
4
  "description": "Shared utilities for PTX Showcase projects",
5
- "version": "0.2.2",
5
+ "version": "0.2.4",
6
6
  "private": false,
7
7
  "type": "module",
8
8
  "license": "MIT",
@@ -51,6 +51,11 @@
51
51
  "require": "./dist/clean-object/index.cjs",
52
52
  "types": "./dist/clean-object/index.d.ts"
53
53
  },
54
+ "./download-file": {
55
+ "import": "./dist/download-file/index.js",
56
+ "require": "./dist/download-file/index.cjs",
57
+ "types": "./dist/download-file/index.d.ts"
58
+ },
54
59
  "./types": {
55
60
  "import": "./dist/types/index.js",
56
61
  "require": "./dist/types/index.cjs",
@@ -67,16 +72,18 @@
67
72
  "access": "public"
68
73
  },
69
74
  "devDependencies": {
70
- "@types/node": "^25.9.1",
75
+ "@types/node": "^25.9.2",
71
76
  "bumpp": "^11.1.0",
72
- "oxlint": "^1.67.0",
77
+ "oxlint": "^1.68.0",
73
78
  "typescript": "~6.0.3",
74
- "vite": "^8.0.14",
75
- "vite-plugin-dts": "^5.0.1",
76
- "vitest": "^4.1.7"
79
+ "vite": "^8.0.16",
80
+ "vite-plugin-dts": "^5.0.2",
81
+ "vitest": "^4.1.8"
77
82
  },
78
83
  "dependencies": {
84
+ "@types/file-saver": "^2.0.7",
79
85
  "@types/js-cookie": "^3.0.6",
80
- "js-cookie": "^3.0.7"
86
+ "file-saver": "^2.0.5",
87
+ "js-cookie": "^3.0.8"
81
88
  }
82
89
  }