@padmaj/duration 1.0.0 → 1.0.1
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 +5 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +12 -3
package/README.md
CHANGED
package/dist/index.js
CHANGED
|
@@ -43,6 +43,7 @@ var DurationError = class extends Error {
|
|
|
43
43
|
function parseDuration(input) {
|
|
44
44
|
const str = input.trim();
|
|
45
45
|
if (!str) throw new DurationError(input);
|
|
46
|
+
if (str.length > 100) throw new DurationError(input);
|
|
46
47
|
let total = 0;
|
|
47
48
|
let matched = false;
|
|
48
49
|
PARSE_RE.lastIndex = 0;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["const UNITS: Record<string, number> = {\n ms: 1,\n s: 1_000,\n m: 60_000,\n h: 3_600_000,\n d: 86_400_000,\n w: 604_800_000,\n}\n\nconst PARSE_RE = /(\\d+(?:\\.\\d+)?)\\s*(ms|s|m|h|d|w)/g\n\nexport class DurationError extends Error {\n constructor(input: string) {\n super(`Invalid duration string: \"${input}\"`)\n this.name = 'DurationError'\n }\n}\n\nexport function parseDuration(input: string): number {\n const str = input.trim()\n if (!str) throw new DurationError(input)\n\n let total = 0\n let matched = false\n\n PARSE_RE.lastIndex = 0\n for (const match of str.matchAll(PARSE_RE)) {\n total += parseFloat(match[1]) * UNITS[match[2]]\n matched = true\n }\n\n if (!matched) throw new DurationError(input)\n return Math.round(total)\n}\n\nexport function formatDuration(ms: number): string {\n if (!Number.isFinite(ms) || ms < 0) {\n throw new RangeError(`formatDuration expects a non-negative finite number, got ${ms}`)\n }\n\n if (ms === 0) return '0ms'\n\n const units: [string, number][] = [\n ['w', UNITS.w],\n ['d', UNITS.d],\n ['h', UNITS.h],\n ['m', UNITS.m],\n ['s', UNITS.s],\n ['ms', UNITS.ms],\n ]\n\n const parts: string[] = []\n let remaining = Math.round(ms)\n\n for (const [unit, value] of units) {\n if (remaining >= value) {\n const count = Math.floor(remaining / value)\n parts.push(`${count}${unit}`)\n remaining %= value\n }\n }\n\n return parts.join(' ')\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAM,QAAgC;AAAA,EACpC,IAAI;AAAA,EACJ,GAAI;AAAA,EACJ,GAAI;AAAA,EACJ,GAAI;AAAA,EACJ,GAAI;AAAA,EACJ,GAAI;AACN;AAEA,IAAM,WAAW;AAEV,IAAM,gBAAN,cAA4B,MAAM;AAAA,EACvC,YAAY,OAAe;AACzB,UAAM,6BAA6B,KAAK,GAAG;AAC3C,SAAK,OAAO;AAAA,EACd;AACF;AAEO,SAAS,cAAc,OAAuB;AACnD,QAAM,MAAM,MAAM,KAAK;AACvB,MAAI,CAAC,IAAK,OAAM,IAAI,cAAc,KAAK;
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["const UNITS: Record<string, number> = {\n ms: 1,\n s: 1_000,\n m: 60_000,\n h: 3_600_000,\n d: 86_400_000,\n w: 604_800_000,\n}\n\nconst PARSE_RE = /(\\d+(?:\\.\\d+)?)\\s*(ms|s|m|h|d|w)/g\n\nexport class DurationError extends Error {\n constructor(input: string) {\n super(`Invalid duration string: \"${input}\"`)\n this.name = 'DurationError'\n }\n}\n\nexport function parseDuration(input: string): number {\n const str = input.trim()\n if (!str) throw new DurationError(input)\n if (str.length > 100) throw new DurationError(input)\n\n let total = 0\n let matched = false\n\n PARSE_RE.lastIndex = 0\n for (const match of str.matchAll(PARSE_RE)) {\n total += parseFloat(match[1]) * UNITS[match[2]]\n matched = true\n }\n\n if (!matched) throw new DurationError(input)\n return Math.round(total)\n}\n\nexport function formatDuration(ms: number): string {\n if (!Number.isFinite(ms) || ms < 0) {\n throw new RangeError(`formatDuration expects a non-negative finite number, got ${ms}`)\n }\n\n if (ms === 0) return '0ms'\n\n const units: [string, number][] = [\n ['w', UNITS.w],\n ['d', UNITS.d],\n ['h', UNITS.h],\n ['m', UNITS.m],\n ['s', UNITS.s],\n ['ms', UNITS.ms],\n ]\n\n const parts: string[] = []\n let remaining = Math.round(ms)\n\n for (const [unit, value] of units) {\n if (remaining >= value) {\n const count = Math.floor(remaining / value)\n parts.push(`${count}${unit}`)\n remaining %= value\n }\n }\n\n return parts.join(' ')\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAAM,QAAgC;AAAA,EACpC,IAAI;AAAA,EACJ,GAAI;AAAA,EACJ,GAAI;AAAA,EACJ,GAAI;AAAA,EACJ,GAAI;AAAA,EACJ,GAAI;AACN;AAEA,IAAM,WAAW;AAEV,IAAM,gBAAN,cAA4B,MAAM;AAAA,EACvC,YAAY,OAAe;AACzB,UAAM,6BAA6B,KAAK,GAAG;AAC3C,SAAK,OAAO;AAAA,EACd;AACF;AAEO,SAAS,cAAc,OAAuB;AACnD,QAAM,MAAM,MAAM,KAAK;AACvB,MAAI,CAAC,IAAK,OAAM,IAAI,cAAc,KAAK;AACvC,MAAI,IAAI,SAAS,IAAK,OAAM,IAAI,cAAc,KAAK;AAEnD,MAAI,QAAQ;AACZ,MAAI,UAAU;AAEd,WAAS,YAAY;AACrB,aAAW,SAAS,IAAI,SAAS,QAAQ,GAAG;AAC1C,aAAS,WAAW,MAAM,CAAC,CAAC,IAAI,MAAM,MAAM,CAAC,CAAC;AAC9C,cAAU;AAAA,EACZ;AAEA,MAAI,CAAC,QAAS,OAAM,IAAI,cAAc,KAAK;AAC3C,SAAO,KAAK,MAAM,KAAK;AACzB;AAEO,SAAS,eAAe,IAAoB;AACjD,MAAI,CAAC,OAAO,SAAS,EAAE,KAAK,KAAK,GAAG;AAClC,UAAM,IAAI,WAAW,4DAA4D,EAAE,EAAE;AAAA,EACvF;AAEA,MAAI,OAAO,EAAG,QAAO;AAErB,QAAM,QAA4B;AAAA,IAChC,CAAC,KAAK,MAAM,CAAC;AAAA,IACb,CAAC,KAAK,MAAM,CAAC;AAAA,IACb,CAAC,KAAK,MAAM,CAAC;AAAA,IACb,CAAC,KAAK,MAAM,CAAC;AAAA,IACb,CAAC,KAAK,MAAM,CAAC;AAAA,IACb,CAAC,MAAM,MAAM,EAAE;AAAA,EACjB;AAEA,QAAM,QAAkB,CAAC;AACzB,MAAI,YAAY,KAAK,MAAM,EAAE;AAE7B,aAAW,CAAC,MAAM,KAAK,KAAK,OAAO;AACjC,QAAI,aAAa,OAAO;AACtB,YAAM,QAAQ,KAAK,MAAM,YAAY,KAAK;AAC1C,YAAM,KAAK,GAAG,KAAK,GAAG,IAAI,EAAE;AAC5B,mBAAa;AAAA,IACf;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,GAAG;AACvB;","names":[]}
|
package/dist/index.mjs
CHANGED
|
@@ -17,6 +17,7 @@ var DurationError = class extends Error {
|
|
|
17
17
|
function parseDuration(input) {
|
|
18
18
|
const str = input.trim();
|
|
19
19
|
if (!str) throw new DurationError(input);
|
|
20
|
+
if (str.length > 100) throw new DurationError(input);
|
|
20
21
|
let total = 0;
|
|
21
22
|
let matched = false;
|
|
22
23
|
PARSE_RE.lastIndex = 0;
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["const UNITS: Record<string, number> = {\n ms: 1,\n s: 1_000,\n m: 60_000,\n h: 3_600_000,\n d: 86_400_000,\n w: 604_800_000,\n}\n\nconst PARSE_RE = /(\\d+(?:\\.\\d+)?)\\s*(ms|s|m|h|d|w)/g\n\nexport class DurationError extends Error {\n constructor(input: string) {\n super(`Invalid duration string: \"${input}\"`)\n this.name = 'DurationError'\n }\n}\n\nexport function parseDuration(input: string): number {\n const str = input.trim()\n if (!str) throw new DurationError(input)\n\n let total = 0\n let matched = false\n\n PARSE_RE.lastIndex = 0\n for (const match of str.matchAll(PARSE_RE)) {\n total += parseFloat(match[1]) * UNITS[match[2]]\n matched = true\n }\n\n if (!matched) throw new DurationError(input)\n return Math.round(total)\n}\n\nexport function formatDuration(ms: number): string {\n if (!Number.isFinite(ms) || ms < 0) {\n throw new RangeError(`formatDuration expects a non-negative finite number, got ${ms}`)\n }\n\n if (ms === 0) return '0ms'\n\n const units: [string, number][] = [\n ['w', UNITS.w],\n ['d', UNITS.d],\n ['h', UNITS.h],\n ['m', UNITS.m],\n ['s', UNITS.s],\n ['ms', UNITS.ms],\n ]\n\n const parts: string[] = []\n let remaining = Math.round(ms)\n\n for (const [unit, value] of units) {\n if (remaining >= value) {\n const count = Math.floor(remaining / value)\n parts.push(`${count}${unit}`)\n remaining %= value\n }\n }\n\n return parts.join(' ')\n}\n"],"mappings":";AAAA,IAAM,QAAgC;AAAA,EACpC,IAAI;AAAA,EACJ,GAAI;AAAA,EACJ,GAAI;AAAA,EACJ,GAAI;AAAA,EACJ,GAAI;AAAA,EACJ,GAAI;AACN;AAEA,IAAM,WAAW;AAEV,IAAM,gBAAN,cAA4B,MAAM;AAAA,EACvC,YAAY,OAAe;AACzB,UAAM,6BAA6B,KAAK,GAAG;AAC3C,SAAK,OAAO;AAAA,EACd;AACF;AAEO,SAAS,cAAc,OAAuB;AACnD,QAAM,MAAM,MAAM,KAAK;AACvB,MAAI,CAAC,IAAK,OAAM,IAAI,cAAc,KAAK;
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["const UNITS: Record<string, number> = {\n ms: 1,\n s: 1_000,\n m: 60_000,\n h: 3_600_000,\n d: 86_400_000,\n w: 604_800_000,\n}\n\nconst PARSE_RE = /(\\d+(?:\\.\\d+)?)\\s*(ms|s|m|h|d|w)/g\n\nexport class DurationError extends Error {\n constructor(input: string) {\n super(`Invalid duration string: \"${input}\"`)\n this.name = 'DurationError'\n }\n}\n\nexport function parseDuration(input: string): number {\n const str = input.trim()\n if (!str) throw new DurationError(input)\n if (str.length > 100) throw new DurationError(input)\n\n let total = 0\n let matched = false\n\n PARSE_RE.lastIndex = 0\n for (const match of str.matchAll(PARSE_RE)) {\n total += parseFloat(match[1]) * UNITS[match[2]]\n matched = true\n }\n\n if (!matched) throw new DurationError(input)\n return Math.round(total)\n}\n\nexport function formatDuration(ms: number): string {\n if (!Number.isFinite(ms) || ms < 0) {\n throw new RangeError(`formatDuration expects a non-negative finite number, got ${ms}`)\n }\n\n if (ms === 0) return '0ms'\n\n const units: [string, number][] = [\n ['w', UNITS.w],\n ['d', UNITS.d],\n ['h', UNITS.h],\n ['m', UNITS.m],\n ['s', UNITS.s],\n ['ms', UNITS.ms],\n ]\n\n const parts: string[] = []\n let remaining = Math.round(ms)\n\n for (const [unit, value] of units) {\n if (remaining >= value) {\n const count = Math.floor(remaining / value)\n parts.push(`${count}${unit}`)\n remaining %= value\n }\n }\n\n return parts.join(' ')\n}\n"],"mappings":";AAAA,IAAM,QAAgC;AAAA,EACpC,IAAI;AAAA,EACJ,GAAI;AAAA,EACJ,GAAI;AAAA,EACJ,GAAI;AAAA,EACJ,GAAI;AAAA,EACJ,GAAI;AACN;AAEA,IAAM,WAAW;AAEV,IAAM,gBAAN,cAA4B,MAAM;AAAA,EACvC,YAAY,OAAe;AACzB,UAAM,6BAA6B,KAAK,GAAG;AAC3C,SAAK,OAAO;AAAA,EACd;AACF;AAEO,SAAS,cAAc,OAAuB;AACnD,QAAM,MAAM,MAAM,KAAK;AACvB,MAAI,CAAC,IAAK,OAAM,IAAI,cAAc,KAAK;AACvC,MAAI,IAAI,SAAS,IAAK,OAAM,IAAI,cAAc,KAAK;AAEnD,MAAI,QAAQ;AACZ,MAAI,UAAU;AAEd,WAAS,YAAY;AACrB,aAAW,SAAS,IAAI,SAAS,QAAQ,GAAG;AAC1C,aAAS,WAAW,MAAM,CAAC,CAAC,IAAI,MAAM,MAAM,CAAC,CAAC;AAC9C,cAAU;AAAA,EACZ;AAEA,MAAI,CAAC,QAAS,OAAM,IAAI,cAAc,KAAK;AAC3C,SAAO,KAAK,MAAM,KAAK;AACzB;AAEO,SAAS,eAAe,IAAoB;AACjD,MAAI,CAAC,OAAO,SAAS,EAAE,KAAK,KAAK,GAAG;AAClC,UAAM,IAAI,WAAW,4DAA4D,EAAE,EAAE;AAAA,EACvF;AAEA,MAAI,OAAO,EAAG,QAAO;AAErB,QAAM,QAA4B;AAAA,IAChC,CAAC,KAAK,MAAM,CAAC;AAAA,IACb,CAAC,KAAK,MAAM,CAAC;AAAA,IACb,CAAC,KAAK,MAAM,CAAC;AAAA,IACb,CAAC,KAAK,MAAM,CAAC;AAAA,IACb,CAAC,KAAK,MAAM,CAAC;AAAA,IACb,CAAC,MAAM,MAAM,EAAE;AAAA,EACjB;AAEA,QAAM,QAAkB,CAAC;AACzB,MAAI,YAAY,KAAK,MAAM,EAAE;AAE7B,aAAW,CAAC,MAAM,KAAK,KAAK,OAAO;AACjC,QAAI,aAAa,OAAO;AACtB,YAAM,QAAQ,KAAK,MAAM,YAAY,KAAK;AAC1C,YAAM,KAAK,GAAG,KAAK,GAAG,IAAI,EAAE;AAC5B,mBAAa;AAAA,IACf;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,GAAG;AACvB;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@padmaj/duration",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Parse and format duration strings. '2h30m' ↔ 9000000ms. Zero dependencies. TypeScript-first.",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -12,7 +12,9 @@
|
|
|
12
12
|
"require": "./dist/index.js"
|
|
13
13
|
}
|
|
14
14
|
},
|
|
15
|
-
"files": [
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
16
18
|
"repository": {
|
|
17
19
|
"type": "git",
|
|
18
20
|
"url": "https://github.com/padmajp4/duration.git"
|
|
@@ -23,7 +25,14 @@
|
|
|
23
25
|
"test:watch": "vitest",
|
|
24
26
|
"prepublishOnly": "npm run build && npm test"
|
|
25
27
|
},
|
|
26
|
-
"keywords": [
|
|
28
|
+
"keywords": [
|
|
29
|
+
"duration",
|
|
30
|
+
"time",
|
|
31
|
+
"parse",
|
|
32
|
+
"format",
|
|
33
|
+
"ms",
|
|
34
|
+
"human-readable"
|
|
35
|
+
],
|
|
27
36
|
"author": "Padmaj P Kumar",
|
|
28
37
|
"license": "MIT",
|
|
29
38
|
"devDependencies": {
|