@pencroff-lab/kore 0.1.0 → 0.1.2
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 +228 -0
- package/dist/cjs/src/utils/format_dt.d.ts +69 -0
- package/dist/cjs/src/utils/format_dt.d.ts.map +1 -1
- package/dist/cjs/src/utils/format_dt.js +40 -0
- package/dist/cjs/src/utils/format_dt.js.map +1 -1
- package/dist/esm/src/utils/format_dt.d.ts +69 -0
- package/dist/esm/src/utils/format_dt.d.ts.map +1 -1
- package/dist/esm/src/utils/format_dt.js +40 -0
- package/dist/esm/src/utils/format_dt.js.map +1 -1
- package/docs/err.md +897 -0
- package/docs/format_dt.md +139 -0
- package/docs/outcome.md +831 -0
- package/llms.txt +22 -0
- package/package.json +4 -2
package/README.md
ADDED
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
# @pencroff-lab/kore
|
|
2
|
+
|
|
3
|
+
TypeScript core utilities library providing value-based error handling types inspired by Go-style error handling. Published as a dual ESM/CJS package.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @pencroff-lab/kore
|
|
9
|
+
# or
|
|
10
|
+
bun add @pencroff-lab/kore
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Requires TypeScript 5.9+ as a peer dependency.
|
|
14
|
+
|
|
15
|
+
## Documentation
|
|
16
|
+
|
|
17
|
+
Detailed API documentation for each module:
|
|
18
|
+
|
|
19
|
+
- [Err](docs/err.md) -- Immutable, value-based error type with wrapping, aggregation, and serialization
|
|
20
|
+
- [Outcome\<T\>](docs/outcome.md) -- Monadic container for type-safe error handling with tuple-first API
|
|
21
|
+
- [dtStamp](docs/format_dt.md) -- Filesystem/log-safe date formatting utility
|
|
22
|
+
|
|
23
|
+
## API
|
|
24
|
+
|
|
25
|
+
### Err
|
|
26
|
+
|
|
27
|
+
Immutable, value-based error type. Supports wrapping (cause chains), aggregation (multiple errors), hierarchical error codes, JSON serialization, and conversion to native `Error`.
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
import { Err } from "@pencroff-lab/kore";
|
|
31
|
+
|
|
32
|
+
// Create an error with a code
|
|
33
|
+
const err = Err.from("User not found", "NOT_FOUND");
|
|
34
|
+
|
|
35
|
+
// Wrap with context (returns a new instance)
|
|
36
|
+
const wrapped = err.wrap("Failed to load profile");
|
|
37
|
+
|
|
38
|
+
// Aggregate multiple errors
|
|
39
|
+
let errors = Err.aggregate("Validation failed");
|
|
40
|
+
errors = errors.add("Name is required");
|
|
41
|
+
errors = errors.add(Err.from("Invalid email", "INVALID_EMAIL"));
|
|
42
|
+
|
|
43
|
+
if (errors.count > 0) {
|
|
44
|
+
console.log(errors.toString());
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
#### Creating errors
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
// From string with code
|
|
52
|
+
Err.from("Timeout", "TIMEOUT");
|
|
53
|
+
|
|
54
|
+
// From string with options
|
|
55
|
+
Err.from("Connection failed", {
|
|
56
|
+
code: "DB_ERROR",
|
|
57
|
+
metadata: { host: "localhost" },
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
// From native Error (preserves stack and cause chain)
|
|
61
|
+
try {
|
|
62
|
+
riskyOperation();
|
|
63
|
+
} catch (e) {
|
|
64
|
+
Err.from(e as Error, { code: "OPERATION_FAILED" });
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Static wrap for catch blocks
|
|
68
|
+
try {
|
|
69
|
+
await db.query(sql);
|
|
70
|
+
} catch (e) {
|
|
71
|
+
Err.wrap("Database query failed", e as Error);
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
#### Error inspection
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
const err = Err.from("DB error", "DB:CONNECTION:TIMEOUT")
|
|
79
|
+
.wrap("Repository failed")
|
|
80
|
+
.wrap("Service unavailable");
|
|
81
|
+
|
|
82
|
+
err.hasCode("DB:CONNECTION:TIMEOUT"); // true - exact match in chain
|
|
83
|
+
err.hasCodePrefix("DB"); // true - hierarchical prefix match
|
|
84
|
+
err.root.message; // "DB error" - original error
|
|
85
|
+
err.chain(); // array from root to current
|
|
86
|
+
err.find((e) => e.code === "DB:CONNECTION:TIMEOUT"); // find in tree
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
#### Serialization
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
// Serialize for API responses
|
|
93
|
+
const json = err.toJSON({ stack: false }); // omit stack for public APIs
|
|
94
|
+
|
|
95
|
+
// Deserialize
|
|
96
|
+
const restored = Err.fromJSON(json);
|
|
97
|
+
|
|
98
|
+
// Convert to native Error
|
|
99
|
+
throw err.toError();
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Outcome\<T\>
|
|
103
|
+
|
|
104
|
+
Monadic container wrapping `ResultTuple<T>` (`[T, null] | [null, Err]`). Supports `map`/`mapErr`/`pipe`/`pipeAsync` chains, combinators (`all`, `any`), side effects (`effect`), and terminal operations (`toTuple`, `defaultTo`, `either`).
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
import { Outcome, Err } from "@pencroff-lab/kore";
|
|
108
|
+
|
|
109
|
+
// Create from callback
|
|
110
|
+
const outcome = Outcome.from(() => {
|
|
111
|
+
if (!isValid(input)) return Err.from("Invalid input", "VALIDATION");
|
|
112
|
+
return [processedValue, null];
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
// Extract with tuple destructuring
|
|
116
|
+
const [value, err] = outcome.toTuple();
|
|
117
|
+
if (err) {
|
|
118
|
+
console.error(err.message);
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
console.log(value);
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
#### Construction
|
|
125
|
+
|
|
126
|
+
```typescript
|
|
127
|
+
Outcome.ok(42); // success
|
|
128
|
+
Outcome.err("Failed", "ERROR_CODE"); // error
|
|
129
|
+
Outcome.unit(); // void success (null value)
|
|
130
|
+
|
|
131
|
+
// From sync callback (catches throws)
|
|
132
|
+
Outcome.from(() => {
|
|
133
|
+
const data = JSON.parse(input); // may throw
|
|
134
|
+
return [data, null];
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
// From async callback
|
|
138
|
+
await Outcome.fromAsync(async () => {
|
|
139
|
+
const res = await fetch("/api/data");
|
|
140
|
+
if (!res.ok) return Err.from("Request failed", "HTTP_ERROR");
|
|
141
|
+
return [await res.json(), null];
|
|
142
|
+
});
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
#### Transformations
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
const result = Outcome.ok(5)
|
|
149
|
+
.map((n) => [n * 2, null]) // transform success
|
|
150
|
+
.mapErr((err) => err.wrap("Added context")) // transform error
|
|
151
|
+
.toTuple();
|
|
152
|
+
|
|
153
|
+
// Pipe for sequential transformations with access to both value and error
|
|
154
|
+
const piped = Outcome.ok(rawInput).pipe(
|
|
155
|
+
([val, err]) => {
|
|
156
|
+
if (err) return err;
|
|
157
|
+
return [validate(val), null];
|
|
158
|
+
},
|
|
159
|
+
([val, err]) => {
|
|
160
|
+
if (err) return err;
|
|
161
|
+
return [transform(val), null];
|
|
162
|
+
},
|
|
163
|
+
);
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
#### Combinators
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
// All must succeed (collects all errors)
|
|
170
|
+
const all = Outcome.all([Outcome.ok(1), Outcome.ok(2), Outcome.ok(3)]);
|
|
171
|
+
// all.value === [1, 2, 3]
|
|
172
|
+
|
|
173
|
+
// First success wins
|
|
174
|
+
const any = Outcome.any([
|
|
175
|
+
Outcome.err("Failed"),
|
|
176
|
+
Outcome.ok(42),
|
|
177
|
+
Outcome.ok(100),
|
|
178
|
+
]);
|
|
179
|
+
// any.value === 42
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
#### Terminal operations
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
// Default value on error
|
|
186
|
+
const count = parseNumber(input).defaultTo(0);
|
|
187
|
+
|
|
188
|
+
// Computed fallback
|
|
189
|
+
const name = fetchUser(id).defaultTo((err) =>
|
|
190
|
+
err.hasCode("NOT_FOUND") ? "Guest" : "Unknown",
|
|
191
|
+
);
|
|
192
|
+
|
|
193
|
+
// Transform both cases
|
|
194
|
+
const response = processOrder(orderId).either(
|
|
195
|
+
(order) => ({ status: 200, body: order }),
|
|
196
|
+
(err) => ({ status: err.hasCode("NOT_FOUND") ? 404 : 500, body: { error: err.message } }),
|
|
197
|
+
);
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Utilities
|
|
201
|
+
|
|
202
|
+
#### dtStamp
|
|
203
|
+
|
|
204
|
+
Formats a `Date` into a compact timestamp string. Useful for filenames, logs, and identifiers.
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
import { dtStamp } from "@pencroff-lab/kore";
|
|
208
|
+
|
|
209
|
+
dtStamp(); // "20260218_153045"
|
|
210
|
+
dtStamp(new Date(), { parts: "date" }); // "20260218"
|
|
211
|
+
dtStamp(new Date(), { parts: "time", ms: true }); // "153045_123"
|
|
212
|
+
dtStamp(new Date(), { compact: true }); // "20260218153045"
|
|
213
|
+
dtStamp(new Date(), { tz: "local" }); // uses local timezone
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## Development
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
bun install # install dependencies
|
|
220
|
+
bun test # run tests
|
|
221
|
+
bun run test:coverage # run tests with coverage (>= 83%)
|
|
222
|
+
bun run lint # lint + type check (auto-fix)
|
|
223
|
+
bun run build # build ESM + CJS to dist/
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
## License
|
|
227
|
+
|
|
228
|
+
[Apache-2.0](LICENSE)
|
|
@@ -1,9 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options for configuring `dtStamp()` output format.
|
|
3
|
+
*/
|
|
1
4
|
export interface DtStampOptions {
|
|
5
|
+
/**
|
|
6
|
+
* Character(s) between date/time segments.
|
|
7
|
+
* Ignored when `compact` is `true`.
|
|
8
|
+
* @default "_"
|
|
9
|
+
*/
|
|
2
10
|
delimiter?: string;
|
|
11
|
+
/**
|
|
12
|
+
* Include milliseconds in the time portion.
|
|
13
|
+
* @default false
|
|
14
|
+
*/
|
|
3
15
|
ms?: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Timezone to use for extracting date/time components.
|
|
18
|
+
* - `"utc"` -- use UTC methods (`getUTCFullYear`, etc.)
|
|
19
|
+
* - `"local"` -- use local-time methods (`getFullYear`, etc.)
|
|
20
|
+
* @default "utc"
|
|
21
|
+
*/
|
|
4
22
|
tz?: "utc" | "local";
|
|
23
|
+
/**
|
|
24
|
+
* Which parts of the stamp to include.
|
|
25
|
+
* - `"datetime"` -- full stamp (date + time)
|
|
26
|
+
* - `"date"` -- date only (`YYYYMMDD`)
|
|
27
|
+
* - `"time"` -- time only (`HHmmss` or `HHmmss_SSS` with `ms`)
|
|
28
|
+
* @default "datetime"
|
|
29
|
+
*/
|
|
5
30
|
parts?: "datetime" | "date" | "time";
|
|
31
|
+
/**
|
|
32
|
+
* When `true`, omits the delimiter entirely (equivalent to `delimiter: ""`).
|
|
33
|
+
* @default false
|
|
34
|
+
*/
|
|
6
35
|
compact?: boolean;
|
|
7
36
|
}
|
|
37
|
+
/**
|
|
38
|
+
* Format a `Date` into a filesystem/log-safe timestamp string.
|
|
39
|
+
*
|
|
40
|
+
* Produces compact, sortable stamps suitable for file names, log prefixes,
|
|
41
|
+
* and anywhere a human-readable but machine-sortable date/time is needed.
|
|
42
|
+
*
|
|
43
|
+
* @param date - Date to format. Defaults to `new Date()` when `null` or omitted.
|
|
44
|
+
* @param options - Formatting options (delimiter, milliseconds, timezone, parts, compact)
|
|
45
|
+
* @returns Formatted timestamp string
|
|
46
|
+
*
|
|
47
|
+
* @example Default (UTC datetime with underscore delimiter)
|
|
48
|
+
* ```typescript
|
|
49
|
+
* dtStamp(new Date("2024-03-15T10:30:45.123Z"));
|
|
50
|
+
* // "20240315_103045"
|
|
51
|
+
* ```
|
|
52
|
+
*
|
|
53
|
+
* @example Compact with milliseconds
|
|
54
|
+
* ```typescript
|
|
55
|
+
* dtStamp(new Date("2024-03-15T10:30:45.123Z"), { compact: true, ms: true });
|
|
56
|
+
* // "20240315103045123"
|
|
57
|
+
* ```
|
|
58
|
+
*
|
|
59
|
+
* @example Date only
|
|
60
|
+
* ```typescript
|
|
61
|
+
* dtStamp(new Date("2024-03-15T10:30:45.123Z"), { parts: "date" });
|
|
62
|
+
* // "20240315"
|
|
63
|
+
* ```
|
|
64
|
+
*
|
|
65
|
+
* @example Time only with milliseconds
|
|
66
|
+
* ```typescript
|
|
67
|
+
* dtStamp(new Date("2024-03-15T10:30:45.123Z"), { parts: "time", ms: true });
|
|
68
|
+
* // "103045_123"
|
|
69
|
+
* ```
|
|
70
|
+
*
|
|
71
|
+
* @example Custom delimiter
|
|
72
|
+
* ```typescript
|
|
73
|
+
* dtStamp(new Date("2024-03-15T10:30:45.123Z"), { delimiter: "-" });
|
|
74
|
+
* // "20240315-103045"
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
8
77
|
export declare function dtStamp(date?: Date | null, options?: DtStampOptions): string;
|
|
9
78
|
//# sourceMappingURL=format_dt.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format_dt.d.ts","sourceRoot":"","sources":["../../../../src/utils/format_dt.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,EAAE,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC;IACrB,KAAK,CAAC,EAAE,UAAU,GAAG,MAAM,GAAG,MAAM,CAAC;IACrC,OAAO,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,wBAAgB,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,MAAM,CA8C5E"}
|
|
1
|
+
{"version":3,"file":"format_dt.d.ts","sourceRoot":"","sources":["../../../../src/utils/format_dt.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,cAAc;IAC9B;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,EAAE,CAAC,EAAE,OAAO,CAAC;IACb;;;;;OAKG;IACH,EAAE,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC;IACrB;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,UAAU,GAAG,MAAM,GAAG,MAAM,CAAC;IACrC;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,wBAAgB,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,MAAM,CA8C5E"}
|
|
@@ -1,6 +1,46 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.dtStamp = dtStamp;
|
|
4
|
+
/**
|
|
5
|
+
* Format a `Date` into a filesystem/log-safe timestamp string.
|
|
6
|
+
*
|
|
7
|
+
* Produces compact, sortable stamps suitable for file names, log prefixes,
|
|
8
|
+
* and anywhere a human-readable but machine-sortable date/time is needed.
|
|
9
|
+
*
|
|
10
|
+
* @param date - Date to format. Defaults to `new Date()` when `null` or omitted.
|
|
11
|
+
* @param options - Formatting options (delimiter, milliseconds, timezone, parts, compact)
|
|
12
|
+
* @returns Formatted timestamp string
|
|
13
|
+
*
|
|
14
|
+
* @example Default (UTC datetime with underscore delimiter)
|
|
15
|
+
* ```typescript
|
|
16
|
+
* dtStamp(new Date("2024-03-15T10:30:45.123Z"));
|
|
17
|
+
* // "20240315_103045"
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* @example Compact with milliseconds
|
|
21
|
+
* ```typescript
|
|
22
|
+
* dtStamp(new Date("2024-03-15T10:30:45.123Z"), { compact: true, ms: true });
|
|
23
|
+
* // "20240315103045123"
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* @example Date only
|
|
27
|
+
* ```typescript
|
|
28
|
+
* dtStamp(new Date("2024-03-15T10:30:45.123Z"), { parts: "date" });
|
|
29
|
+
* // "20240315"
|
|
30
|
+
* ```
|
|
31
|
+
*
|
|
32
|
+
* @example Time only with milliseconds
|
|
33
|
+
* ```typescript
|
|
34
|
+
* dtStamp(new Date("2024-03-15T10:30:45.123Z"), { parts: "time", ms: true });
|
|
35
|
+
* // "103045_123"
|
|
36
|
+
* ```
|
|
37
|
+
*
|
|
38
|
+
* @example Custom delimiter
|
|
39
|
+
* ```typescript
|
|
40
|
+
* dtStamp(new Date("2024-03-15T10:30:45.123Z"), { delimiter: "-" });
|
|
41
|
+
* // "20240315-103045"
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
4
44
|
function dtStamp(date, options) {
|
|
5
45
|
const d = date ?? new Date();
|
|
6
46
|
const { delimiter = "_", ms = false, tz = "utc", parts = "datetime", compact = false, } = options ?? {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format_dt.js","sourceRoot":"","sources":["../../../../src/utils/format_dt.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"format_dt.js","sourceRoot":"","sources":["../../../../src/utils/format_dt.ts"],"names":[],"mappings":";;AA6EA,0BA8CC;AAtFD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,SAAgB,OAAO,CAAC,IAAkB,EAAE,OAAwB;IACnE,MAAM,CAAC,GAAG,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;IAC7B,MAAM,EACL,SAAS,GAAG,GAAG,EACf,EAAE,GAAG,KAAK,EACV,EAAE,GAAG,KAAK,EACV,KAAK,GAAG,UAAU,EAClB,OAAO,GAAG,KAAK,GACf,GAAG,OAAO,IAAI,EAAE,CAAC;IAElB,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IACrC,MAAM,GAAG,GAAG,EAAE,KAAK,KAAK,CAAC;IAEzB,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IACxD,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CACxE,CAAC,EACD,GAAG,CACH,CAAC;IACF,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACxE,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC5E,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,QAAQ,CACxE,CAAC,EACD,GAAG,CACH,CAAC;IACF,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,QAAQ,CACxE,CAAC,EACD,GAAG,CACH,CAAC;IAEF,MAAM,QAAQ,GAAG,GAAG,IAAI,GAAG,KAAK,GAAG,GAAG,EAAE,CAAC;IACzC,IAAI,QAAQ,GAAG,GAAG,KAAK,GAAG,OAAO,GAAG,OAAO,EAAE,CAAC;IAE9C,IAAI,EAAE,EAAE,CAAC;QACR,MAAM,MAAM,GAAG,MAAM,CACpB,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,EAAE,CAClD,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QACnB,QAAQ,GAAG,GAAG,QAAQ,GAAG,GAAG,GAAG,MAAM,EAAE,CAAC;IACzC,CAAC;IAED,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO,QAAQ,CAAC;IACjB,CAAC;IACD,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO,QAAQ,CAAC;IACjB,CAAC;IACD,OAAO,GAAG,QAAQ,GAAG,GAAG,GAAG,QAAQ,EAAE,CAAC;AACvC,CAAC"}
|
|
@@ -1,9 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options for configuring `dtStamp()` output format.
|
|
3
|
+
*/
|
|
1
4
|
export interface DtStampOptions {
|
|
5
|
+
/**
|
|
6
|
+
* Character(s) between date/time segments.
|
|
7
|
+
* Ignored when `compact` is `true`.
|
|
8
|
+
* @default "_"
|
|
9
|
+
*/
|
|
2
10
|
delimiter?: string;
|
|
11
|
+
/**
|
|
12
|
+
* Include milliseconds in the time portion.
|
|
13
|
+
* @default false
|
|
14
|
+
*/
|
|
3
15
|
ms?: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Timezone to use for extracting date/time components.
|
|
18
|
+
* - `"utc"` -- use UTC methods (`getUTCFullYear`, etc.)
|
|
19
|
+
* - `"local"` -- use local-time methods (`getFullYear`, etc.)
|
|
20
|
+
* @default "utc"
|
|
21
|
+
*/
|
|
4
22
|
tz?: "utc" | "local";
|
|
23
|
+
/**
|
|
24
|
+
* Which parts of the stamp to include.
|
|
25
|
+
* - `"datetime"` -- full stamp (date + time)
|
|
26
|
+
* - `"date"` -- date only (`YYYYMMDD`)
|
|
27
|
+
* - `"time"` -- time only (`HHmmss` or `HHmmss_SSS` with `ms`)
|
|
28
|
+
* @default "datetime"
|
|
29
|
+
*/
|
|
5
30
|
parts?: "datetime" | "date" | "time";
|
|
31
|
+
/**
|
|
32
|
+
* When `true`, omits the delimiter entirely (equivalent to `delimiter: ""`).
|
|
33
|
+
* @default false
|
|
34
|
+
*/
|
|
6
35
|
compact?: boolean;
|
|
7
36
|
}
|
|
37
|
+
/**
|
|
38
|
+
* Format a `Date` into a filesystem/log-safe timestamp string.
|
|
39
|
+
*
|
|
40
|
+
* Produces compact, sortable stamps suitable for file names, log prefixes,
|
|
41
|
+
* and anywhere a human-readable but machine-sortable date/time is needed.
|
|
42
|
+
*
|
|
43
|
+
* @param date - Date to format. Defaults to `new Date()` when `null` or omitted.
|
|
44
|
+
* @param options - Formatting options (delimiter, milliseconds, timezone, parts, compact)
|
|
45
|
+
* @returns Formatted timestamp string
|
|
46
|
+
*
|
|
47
|
+
* @example Default (UTC datetime with underscore delimiter)
|
|
48
|
+
* ```typescript
|
|
49
|
+
* dtStamp(new Date("2024-03-15T10:30:45.123Z"));
|
|
50
|
+
* // "20240315_103045"
|
|
51
|
+
* ```
|
|
52
|
+
*
|
|
53
|
+
* @example Compact with milliseconds
|
|
54
|
+
* ```typescript
|
|
55
|
+
* dtStamp(new Date("2024-03-15T10:30:45.123Z"), { compact: true, ms: true });
|
|
56
|
+
* // "20240315103045123"
|
|
57
|
+
* ```
|
|
58
|
+
*
|
|
59
|
+
* @example Date only
|
|
60
|
+
* ```typescript
|
|
61
|
+
* dtStamp(new Date("2024-03-15T10:30:45.123Z"), { parts: "date" });
|
|
62
|
+
* // "20240315"
|
|
63
|
+
* ```
|
|
64
|
+
*
|
|
65
|
+
* @example Time only with milliseconds
|
|
66
|
+
* ```typescript
|
|
67
|
+
* dtStamp(new Date("2024-03-15T10:30:45.123Z"), { parts: "time", ms: true });
|
|
68
|
+
* // "103045_123"
|
|
69
|
+
* ```
|
|
70
|
+
*
|
|
71
|
+
* @example Custom delimiter
|
|
72
|
+
* ```typescript
|
|
73
|
+
* dtStamp(new Date("2024-03-15T10:30:45.123Z"), { delimiter: "-" });
|
|
74
|
+
* // "20240315-103045"
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
8
77
|
export declare function dtStamp(date?: Date | null, options?: DtStampOptions): string;
|
|
9
78
|
//# sourceMappingURL=format_dt.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format_dt.d.ts","sourceRoot":"","sources":["../../../../src/utils/format_dt.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,EAAE,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC;IACrB,KAAK,CAAC,EAAE,UAAU,GAAG,MAAM,GAAG,MAAM,CAAC;IACrC,OAAO,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,wBAAgB,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,MAAM,CA8C5E"}
|
|
1
|
+
{"version":3,"file":"format_dt.d.ts","sourceRoot":"","sources":["../../../../src/utils/format_dt.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,cAAc;IAC9B;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,EAAE,CAAC,EAAE,OAAO,CAAC;IACb;;;;;OAKG;IACH,EAAE,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC;IACrB;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,UAAU,GAAG,MAAM,GAAG,MAAM,CAAC;IACrC;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,wBAAgB,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,MAAM,CA8C5E"}
|
|
@@ -1,3 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Format a `Date` into a filesystem/log-safe timestamp string.
|
|
3
|
+
*
|
|
4
|
+
* Produces compact, sortable stamps suitable for file names, log prefixes,
|
|
5
|
+
* and anywhere a human-readable but machine-sortable date/time is needed.
|
|
6
|
+
*
|
|
7
|
+
* @param date - Date to format. Defaults to `new Date()` when `null` or omitted.
|
|
8
|
+
* @param options - Formatting options (delimiter, milliseconds, timezone, parts, compact)
|
|
9
|
+
* @returns Formatted timestamp string
|
|
10
|
+
*
|
|
11
|
+
* @example Default (UTC datetime with underscore delimiter)
|
|
12
|
+
* ```typescript
|
|
13
|
+
* dtStamp(new Date("2024-03-15T10:30:45.123Z"));
|
|
14
|
+
* // "20240315_103045"
|
|
15
|
+
* ```
|
|
16
|
+
*
|
|
17
|
+
* @example Compact with milliseconds
|
|
18
|
+
* ```typescript
|
|
19
|
+
* dtStamp(new Date("2024-03-15T10:30:45.123Z"), { compact: true, ms: true });
|
|
20
|
+
* // "20240315103045123"
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* @example Date only
|
|
24
|
+
* ```typescript
|
|
25
|
+
* dtStamp(new Date("2024-03-15T10:30:45.123Z"), { parts: "date" });
|
|
26
|
+
* // "20240315"
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* @example Time only with milliseconds
|
|
30
|
+
* ```typescript
|
|
31
|
+
* dtStamp(new Date("2024-03-15T10:30:45.123Z"), { parts: "time", ms: true });
|
|
32
|
+
* // "103045_123"
|
|
33
|
+
* ```
|
|
34
|
+
*
|
|
35
|
+
* @example Custom delimiter
|
|
36
|
+
* ```typescript
|
|
37
|
+
* dtStamp(new Date("2024-03-15T10:30:45.123Z"), { delimiter: "-" });
|
|
38
|
+
* // "20240315-103045"
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
1
41
|
export function dtStamp(date, options) {
|
|
2
42
|
const d = date ?? new Date();
|
|
3
43
|
const { delimiter = "_", ms = false, tz = "utc", parts = "datetime", compact = false, } = options ?? {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format_dt.js","sourceRoot":"","sources":["../../../../src/utils/format_dt.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"format_dt.js","sourceRoot":"","sources":["../../../../src/utils/format_dt.ts"],"names":[],"mappings":"AAqCA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,MAAM,UAAU,OAAO,CAAC,IAAkB,EAAE,OAAwB;IACnE,MAAM,CAAC,GAAG,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;IAC7B,MAAM,EACL,SAAS,GAAG,GAAG,EACf,EAAE,GAAG,KAAK,EACV,EAAE,GAAG,KAAK,EACV,KAAK,GAAG,UAAU,EAClB,OAAO,GAAG,KAAK,GACf,GAAG,OAAO,IAAI,EAAE,CAAC;IAElB,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IACrC,MAAM,GAAG,GAAG,EAAE,KAAK,KAAK,CAAC;IAEzB,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IACxD,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CACxE,CAAC,EACD,GAAG,CACH,CAAC;IACF,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACxE,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC5E,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,QAAQ,CACxE,CAAC,EACD,GAAG,CACH,CAAC;IACF,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,QAAQ,CACxE,CAAC,EACD,GAAG,CACH,CAAC;IAEF,MAAM,QAAQ,GAAG,GAAG,IAAI,GAAG,KAAK,GAAG,GAAG,EAAE,CAAC;IACzC,IAAI,QAAQ,GAAG,GAAG,KAAK,GAAG,OAAO,GAAG,OAAO,EAAE,CAAC;IAE9C,IAAI,EAAE,EAAE,CAAC;QACR,MAAM,MAAM,GAAG,MAAM,CACpB,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,EAAE,CAClD,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QACnB,QAAQ,GAAG,GAAG,QAAQ,GAAG,GAAG,GAAG,MAAM,EAAE,CAAC;IACzC,CAAC;IAED,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO,QAAQ,CAAC;IACjB,CAAC;IACD,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO,QAAQ,CAAC;IACjB,CAAC;IACD,OAAO,GAAG,QAAQ,GAAG,GAAG,GAAG,QAAQ,EAAE,CAAC;AACvC,CAAC"}
|