@adviser/cement 0.4.2 → 0.4.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.
Files changed (46) hide show
  1. package/cf/index.js +2 -2
  2. package/{chunk-XJ3SFZPE.js → chunk-FURW5CDL.js} +2 -2
  3. package/{chunk-C5L2FW7O.js → chunk-NJMNJYN2.js} +2 -2
  4. package/{chunk-MBLJQD6G.js → chunk-NTOGMD33.js} +1 -1
  5. package/chunk-NTOGMD33.js.map +1 -0
  6. package/{chunk-S5OZRDIH.js → chunk-Z724JFU6.js} +86 -11
  7. package/chunk-Z724JFU6.js.map +1 -0
  8. package/deno/index.js +2 -2
  9. package/{index-TtYD7HhB.d.cts → index-BJwthmNK.d.cts} +12 -2
  10. package/{index-N0bkrgSt.d.ts → index-Bh_2ZgIk.d.ts} +12 -2
  11. package/index.cjs +83 -8
  12. package/index.cjs.map +1 -1
  13. package/index.d.cts +4 -3
  14. package/index.d.ts +4 -3
  15. package/index.js +4 -4
  16. package/metafile-cjs.json +1 -1
  17. package/metafile-esm.json +1 -1
  18. package/node/index.js +2 -2
  19. package/package.json +5 -4
  20. package/src/is-promise.ts +2 -0
  21. package/src/jsr.json +1 -1
  22. package/src/uri.ts +99 -9
  23. package/test/index.cjs +83 -8
  24. package/test/index.cjs.map +1 -1
  25. package/test/index.d.cts +1 -1
  26. package/test/index.d.ts +1 -1
  27. package/test/index.js +3 -3
  28. package/ts/src/is-promise.d.ts +1 -0
  29. package/ts/src/is-promise.d.ts.map +1 -1
  30. package/ts/src/is-promise.js.map +1 -1
  31. package/ts/src/uri.d.ts +12 -2
  32. package/ts/src/uri.d.ts.map +1 -1
  33. package/ts/src/uri.js +83 -5
  34. package/ts/src/uri.js.map +1 -1
  35. package/ts/src/uri.test.js +97 -0
  36. package/ts/src/uri.test.js.map +1 -1
  37. package/ts/vitest.browser.config.d.ts.map +1 -1
  38. package/ts/vitest.browser.config.js +6 -2
  39. package/ts/vitest.browser.config.js.map +1 -1
  40. package/utils/index.cjs.map +1 -1
  41. package/utils/index.js +2 -2
  42. package/web/index.js +2 -2
  43. package/chunk-MBLJQD6G.js.map +0 -1
  44. package/chunk-S5OZRDIH.js.map +0 -1
  45. /package/{chunk-XJ3SFZPE.js.map → chunk-FURW5CDL.js.map} +0 -0
  46. /package/{chunk-C5L2FW7O.js.map → chunk-NJMNJYN2.js.map} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adviser/cement",
3
- "version": "0.4.2",
3
+ "version": "0.4.4",
4
4
  "description": "better try/catch/finally handling",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -48,7 +48,7 @@
48
48
  "yaml": "^2.5.1"
49
49
  },
50
50
  "devDependencies": {
51
- "@cloudflare/vitest-pool-workers": "^0.7.1",
51
+ "@cloudflare/vitest-pool-workers": "^0.8.0",
52
52
  "@eslint/js": "^9.20.0",
53
53
  "@types/node": "^22.10.2",
54
54
  "@typescript-eslint/eslint-plugin": "^8.7.0",
@@ -57,14 +57,15 @@
57
57
  "esbuild-plugin-replace": "^1.4.0",
58
58
  "esbuild-plugin-resolve": "^2.0.0",
59
59
  "eslint": "9.22.0",
60
+ "playwright": "^1.51.0",
61
+ "playwright-chromium": "^1.51.0",
60
62
  "prettier": "^3.3.3",
61
63
  "tsup": "^8.3.0",
62
64
  "tsx": "^4.19.1",
63
65
  "typescript": "^5.8.0",
64
66
  "typescript-eslint": "^8.24.0",
65
67
  "vite-tsconfig-paths": "^5.0.1",
66
- "vitest": "^3.0.7",
67
- "webdriverio": "^9.9.0"
68
+ "vitest": "^3.0.8"
68
69
  },
69
70
  "engines": {
70
71
  "node": ">=20"
package/src/is-promise.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  export type UnPromisify<T> = T extends Promise<infer U> ? U : T;
2
2
 
3
+ export type Promisable<T> = T | Promise<T>;
4
+
3
5
  export function isPromise<T>(a: T): a is T extends Promise<unknown> ? T : never {
4
6
  const mayBe = a as unknown as { then: () => void; catch: () => void; finally: () => void };
5
7
  return (
package/src/jsr.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adviser/cement",
3
- "version": "0.4.2",
3
+ "version": "0.4.4",
4
4
  "exports": {
5
5
  ".": "./index.ts",
6
6
  "./web": "./web/index.ts",
package/src/uri.ts CHANGED
@@ -119,6 +119,16 @@ function coerceKey(key: string | OneKey<string>, def?: string): { key: string; d
119
119
  return { key, def: def };
120
120
  }
121
121
 
122
+ function resolveHash(hash: string): { getParam: (k: string) => string | undefined } {
123
+ const searchParams = new URLSearchParams(hash.replace(/^#/, ""));
124
+ return {
125
+ getParam: (k): string | undefined => {
126
+ const ret = searchParams.get(k);
127
+ return ret === null ? undefined : ret;
128
+ },
129
+ };
130
+ }
131
+
122
132
  export interface URIObject {
123
133
  readonly style: "host" | "path";
124
134
  readonly protocol: string;
@@ -168,6 +178,7 @@ export function isURL(value: unknown): value is URL {
168
178
 
169
179
  // due to that the System URL class is has a strange behavior
170
180
  // on different platforms, we need to implement our own URL class
181
+ const customInspectSymbol = Symbol.for("nodejs.util.inspect.custom");
171
182
  export class MutableURL extends URL {
172
183
  private readonly _sysURL: URL;
173
184
  // private readonly _urlStr: string;
@@ -176,7 +187,7 @@ export class MutableURL extends URL {
176
187
  private _pathname: string;
177
188
  private _hasHostpart: boolean;
178
189
 
179
- override readonly hash: string;
190
+ // override readonly hash: string;
180
191
 
181
192
  constructor(urlStr: string) {
182
193
  super("defect://does.not.exist");
@@ -200,7 +211,12 @@ export class MutableURL extends URL {
200
211
  } else {
201
212
  this._pathname = urlStr.replace(new RegExp(`^${this._protocol}//`), "").replace(/[#?].*$/, "");
202
213
  }
203
- this.hash = this._sysURL.hash;
214
+ // this.hash = this._sysURL.hash;
215
+ }
216
+
217
+ [customInspectSymbol](): string {
218
+ // make node inspect to show the URL and not crash if URI is not http/https/file
219
+ return this.toString();
204
220
  }
205
221
 
206
222
  clone(): MutableURL {
@@ -263,17 +279,30 @@ export class MutableURL extends URL {
263
279
  this._protocol = p;
264
280
  }
265
281
 
282
+ override get hash(): string {
283
+ return this._sysURL.hash;
284
+ }
285
+
286
+ override set hash(h: string) {
287
+ this._sysURL.hash = h;
288
+ }
289
+
266
290
  override get searchParams(): URLSearchParams {
267
291
  return this._sysURL.searchParams;
268
292
  }
269
293
 
270
- override toString(): string {
294
+ override get search(): string {
271
295
  let search = "";
272
296
  if (this._sysURL.searchParams.size) {
273
297
  for (const [key, value] of Array.from(this._sysURL.searchParams.entries()).sort((a, b) => a[0].localeCompare(b[0]))) {
274
298
  search += `${!search.length ? "?" : "&"}${key}=${encodeURIComponent(value)}`;
275
299
  }
276
300
  }
301
+ return search;
302
+ }
303
+
304
+ override toString(): string {
305
+ const search = this.search;
277
306
  let hostpart = "";
278
307
  if (this._hasHostpart) {
279
308
  hostpart = this._sysURL.hostname;
@@ -284,7 +313,7 @@ export class MutableURL extends URL {
284
313
  hostpart += "/";
285
314
  }
286
315
  }
287
- return `${this._protocol}//${hostpart}${this._pathname}${search}`;
316
+ return `${this._protocol}//${hostpart}${this._pathname}${search}${this.hash}`;
288
317
  }
289
318
  }
290
319
 
@@ -364,6 +393,11 @@ export class BuildURI implements URIInterface<BuildURI> {
364
393
  return this;
365
394
  }
366
395
 
396
+ hash(h: string): BuildURI {
397
+ this._url.hash = h;
398
+ return this;
399
+ }
400
+
367
401
  // could pass a relative path or a full URL
368
402
  // if relative path, it will be appended to the current path
369
403
  resolve(p: CoerceURI): BuildURI {
@@ -413,10 +447,54 @@ export class BuildURI implements URIInterface<BuildURI> {
413
447
  return this;
414
448
  }
415
449
 
416
- cleanParams(): BuildURI {
450
+ cleanParams(...remove: (string | string[])[]): BuildURI {
451
+ const keys = new Set(remove.flat());
417
452
  for (const key of Array.from(this._url.searchParams.keys())) {
418
- this._url.searchParams.delete(key);
453
+ if (keys.size === 0 || keys.has(key)) {
454
+ this._url.searchParams.delete(key);
455
+ }
456
+ }
457
+ return this;
458
+ }
459
+
460
+ hashParams(
461
+ val: Record<string, string | number | boolean | Date | null | undefined>,
462
+ mode: "reset" | "merge" = "reset",
463
+ ): BuildURI {
464
+ let preset: Record<string, string>;
465
+ switch (mode) {
466
+ case "reset":
467
+ this._url.hash = "";
468
+ preset = {};
469
+ break;
470
+ case "merge":
471
+ default:
472
+ preset = Object.fromEntries(new URLSearchParams(this._url.hash.replace(/^#/, "")).entries());
473
+ break;
474
+ }
475
+ const out = new URLSearchParams("");
476
+ for (const [key, value] of Object.entries({ ...preset, ...val }).sort((a, b) => a[0].localeCompare(b[0]))) {
477
+ switch (typeof value) {
478
+ case "string":
479
+ out.set(key, value);
480
+ break;
481
+ case "number":
482
+ out.set(key, value.toString());
483
+ break;
484
+ case "boolean":
485
+ out.set(key, value ? "true" : "false");
486
+ break;
487
+ default:
488
+ if (value instanceof Date) {
489
+ out.set(key, value.toISOString());
490
+ } else {
491
+ // eslint-disable-next-line no-console
492
+ console.error(`unsupported type: ${typeof value} ignore key: ${key}`);
493
+ }
494
+ break;
495
+ }
419
496
  }
497
+ this._url.hash = out.toString();
420
498
  return this;
421
499
  }
422
500
 
@@ -462,6 +540,10 @@ export class BuildURI implements URIInterface<BuildURI> {
462
540
  return getParamsResult(keys, this);
463
541
  }
464
542
 
543
+ getHashParams(...keys: KeysParam): Result<Record<string, string>> {
544
+ return getParamsResult(keys, resolveHash(this._url.hash));
545
+ }
546
+
465
547
  toString(): string {
466
548
  this._url.searchParams.sort();
467
549
  return this._url.toString();
@@ -573,6 +655,10 @@ export class URI implements URIInterface<URI> {
573
655
  return this._url.hostname;
574
656
  }
575
657
 
658
+ get local(): string {
659
+ return this._url.pathname + this._url.search;
660
+ }
661
+
576
662
  // get password(): string {
577
663
  // return this._url.password;
578
664
  // }
@@ -605,9 +691,9 @@ export class URI implements URIInterface<URI> {
605
691
  // .replace(/\?.*$/, "");
606
692
  }
607
693
 
608
- // get hash(): string {
609
- // return this._url.hash;
610
- // }
694
+ get hash(): string {
695
+ return this._url.hash;
696
+ }
611
697
 
612
698
  // get host(): string {
613
699
  // return this._url.host;
@@ -638,6 +724,10 @@ export class URI implements URIInterface<URI> {
638
724
  return getParamsResult(keys, this);
639
725
  }
640
726
 
727
+ getHashParams(...keys: KeysParam): Result<Record<string, string>> {
728
+ return getParamsResult(keys, resolveHash(this._url.hash));
729
+ }
730
+
641
731
  clone(): URI {
642
732
  return new URI(this._url);
643
733
  }
package/test/index.cjs CHANGED
@@ -1211,6 +1211,15 @@ function coerceKey(key, def) {
1211
1211
  }
1212
1212
  return { key, def };
1213
1213
  }
1214
+ function resolveHash(hash) {
1215
+ const searchParams = new URLSearchParams(hash.replace(/^#/, ""));
1216
+ return {
1217
+ getParam: (k) => {
1218
+ const ret = searchParams.get(k);
1219
+ return ret === null ? void 0 : ret;
1220
+ }
1221
+ };
1222
+ }
1214
1223
  function falsy2undef(value) {
1215
1224
  return value === void 0 || value === null ? void 0 : value;
1216
1225
  }
@@ -1231,7 +1240,9 @@ function ensureURLWithDefaultProto(url, defaultProtocol) {
1231
1240
  function isURL(value) {
1232
1241
  return value instanceof URL || !!value && typeof value.searchParams === "object" && typeof value.searchParams.sort === "function" && typeof value.hash === "string";
1233
1242
  }
1243
+ var customInspectSymbol = Symbol.for("nodejs.util.inspect.custom");
1234
1244
  var MutableURL = class _MutableURL extends URL {
1245
+ // override readonly hash: string;
1235
1246
  constructor(urlStr) {
1236
1247
  super("defect://does.not.exist");
1237
1248
  const partedURL = urlStr.split(":");
@@ -1254,7 +1265,9 @@ var MutableURL = class _MutableURL extends URL {
1254
1265
  } else {
1255
1266
  this._pathname = urlStr.replace(new RegExp(`^${this._protocol}//`), "").replace(/[#?].*$/, "");
1256
1267
  }
1257
- this.hash = this._sysURL.hash;
1268
+ }
1269
+ [customInspectSymbol]() {
1270
+ return this.toString();
1258
1271
  }
1259
1272
  clone() {
1260
1273
  return new _MutableURL(this.toString());
@@ -1306,16 +1319,26 @@ var MutableURL = class _MutableURL extends URL {
1306
1319
  }
1307
1320
  this._protocol = p;
1308
1321
  }
1322
+ get hash() {
1323
+ return this._sysURL.hash;
1324
+ }
1325
+ set hash(h) {
1326
+ this._sysURL.hash = h;
1327
+ }
1309
1328
  get searchParams() {
1310
1329
  return this._sysURL.searchParams;
1311
1330
  }
1312
- toString() {
1331
+ get search() {
1313
1332
  let search = "";
1314
1333
  if (this._sysURL.searchParams.size) {
1315
1334
  for (const [key, value] of Array.from(this._sysURL.searchParams.entries()).sort((a, b) => a[0].localeCompare(b[0]))) {
1316
1335
  search += `${!search.length ? "?" : "&"}${key}=${encodeURIComponent(value)}`;
1317
1336
  }
1318
1337
  }
1338
+ return search;
1339
+ }
1340
+ toString() {
1341
+ const search = this.search;
1319
1342
  let hostpart = "";
1320
1343
  if (this._hasHostpart) {
1321
1344
  hostpart = this._sysURL.hostname;
@@ -1326,7 +1349,7 @@ var MutableURL = class _MutableURL extends URL {
1326
1349
  hostpart += "/";
1327
1350
  }
1328
1351
  }
1329
- return `${this._protocol}//${hostpart}${this._pathname}${search}`;
1352
+ return `${this._protocol}//${hostpart}${this._pathname}${search}${this.hash}`;
1330
1353
  }
1331
1354
  };
1332
1355
  function from(fac, strURLUri, defaultProtocol) {
@@ -1389,6 +1412,10 @@ var BuildURI = class _BuildURI {
1389
1412
  this._url.pathname = p;
1390
1413
  return this;
1391
1414
  }
1415
+ hash(h) {
1416
+ this._url.hash = h;
1417
+ return this;
1418
+ }
1392
1419
  // could pass a relative path or a full URL
1393
1420
  // if relative path, it will be appended to the current path
1394
1421
  resolve(p) {
@@ -1417,12 +1444,51 @@ var BuildURI = class _BuildURI {
1417
1444
  }
1418
1445
  return this;
1419
1446
  }
1420
- cleanParams() {
1447
+ cleanParams(...remove) {
1448
+ const keys = new Set(remove.flat());
1421
1449
  for (const key of Array.from(this._url.searchParams.keys())) {
1422
- this._url.searchParams.delete(key);
1450
+ if (keys.size === 0 || keys.has(key)) {
1451
+ this._url.searchParams.delete(key);
1452
+ }
1423
1453
  }
1424
1454
  return this;
1425
1455
  }
1456
+ hashParams(val, mode = "reset") {
1457
+ let preset;
1458
+ switch (mode) {
1459
+ case "reset":
1460
+ this._url.hash = "";
1461
+ preset = {};
1462
+ break;
1463
+ case "merge":
1464
+ default:
1465
+ preset = Object.fromEntries(new URLSearchParams(this._url.hash.replace(/^#/, "")).entries());
1466
+ break;
1467
+ }
1468
+ const out = new URLSearchParams("");
1469
+ for (const [key, value] of Object.entries({ ...preset, ...val }).sort((a, b) => a[0].localeCompare(b[0]))) {
1470
+ switch (typeof value) {
1471
+ case "string":
1472
+ out.set(key, value);
1473
+ break;
1474
+ case "number":
1475
+ out.set(key, value.toString());
1476
+ break;
1477
+ case "boolean":
1478
+ out.set(key, value ? "true" : "false");
1479
+ break;
1480
+ default:
1481
+ if (value instanceof Date) {
1482
+ out.set(key, value.toISOString());
1483
+ } else {
1484
+ console.error(`unsupported type: ${typeof value} ignore key: ${key}`);
1485
+ }
1486
+ break;
1487
+ }
1488
+ }
1489
+ this._url.hash = out.toString();
1490
+ return this;
1491
+ }
1426
1492
  delParam(key) {
1427
1493
  this._url.searchParams.delete(key);
1428
1494
  return this;
@@ -1457,6 +1523,9 @@ var BuildURI = class _BuildURI {
1457
1523
  getParamsResult(...keys) {
1458
1524
  return getParamsResult(keys, this);
1459
1525
  }
1526
+ getHashParams(...keys) {
1527
+ return getParamsResult(keys, resolveHash(this._url.hash));
1528
+ }
1460
1529
  toString() {
1461
1530
  this._url.searchParams.sort();
1462
1531
  return this._url.toString();
@@ -1522,6 +1591,9 @@ var URI = class _URI {
1522
1591
  get hostname() {
1523
1592
  return this._url.hostname;
1524
1593
  }
1594
+ get local() {
1595
+ return this._url.pathname + this._url.search;
1596
+ }
1525
1597
  // get password(): string {
1526
1598
  // return this._url.password;
1527
1599
  // }
@@ -1543,9 +1615,9 @@ var URI = class _URI {
1543
1615
  get pathname() {
1544
1616
  return this._url.pathname;
1545
1617
  }
1546
- // get hash(): string {
1547
- // return this._url.hash;
1548
- // }
1618
+ get hash() {
1619
+ return this._url.hash;
1620
+ }
1549
1621
  // get host(): string {
1550
1622
  // return this._url.host;
1551
1623
  // }
@@ -1569,6 +1641,9 @@ var URI = class _URI {
1569
1641
  getParamsResult(...keys) {
1570
1642
  return getParamsResult(keys, this);
1571
1643
  }
1644
+ getHashParams(...keys) {
1645
+ return getParamsResult(keys, resolveHash(this._url.hash));
1646
+ }
1572
1647
  clone() {
1573
1648
  return new _URI(this._url);
1574
1649
  }