qstd 0.3.23 → 0.3.25
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/dist/client/index.cjs +7 -3
- package/dist/client/index.js +7 -3
- package/dist/server/index.cjs +43 -5
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +43 -6
- package/dist/shared/time.d.ts +79 -18
- package/dist/shared/time.d.ts.map +1 -1
- package/package.json +21 -20
package/dist/client/index.cjs
CHANGED
|
@@ -264,14 +264,18 @@ __export(time_exports, {
|
|
|
264
264
|
startTimer: () => startTimer,
|
|
265
265
|
toMs: () => toMs
|
|
266
266
|
});
|
|
267
|
-
var formatDuration = (
|
|
268
|
-
if (
|
|
267
|
+
var formatDuration = (value, options = {}) => {
|
|
268
|
+
if (value === null || value === void 0 || !Number.isFinite(value) || value < 0) {
|
|
269
|
+
return "--:--";
|
|
270
|
+
}
|
|
269
271
|
const {
|
|
270
272
|
format: fmt = "clock",
|
|
273
|
+
unit = "ms",
|
|
271
274
|
showZero = false,
|
|
272
275
|
showMs = false,
|
|
273
276
|
spaces = true
|
|
274
277
|
} = options;
|
|
278
|
+
const ms = unit === "ss" ? value * 1e3 : unit === "mm" ? value * 60 * 1e3 : value;
|
|
275
279
|
const absMs = Math.abs(ms);
|
|
276
280
|
const totalSeconds = Math.floor(absMs / 1e3);
|
|
277
281
|
const hours = Math.floor(totalSeconds / 3600);
|
|
@@ -308,7 +312,7 @@ var formatDuration = (ms, options = {}) => {
|
|
|
308
312
|
return parts2.join(" ") || "0 seconds";
|
|
309
313
|
}
|
|
310
314
|
if (fmt === "fractional") {
|
|
311
|
-
const totalSecondsWithFraction =
|
|
315
|
+
const totalSecondsWithFraction = absMs / 1e3;
|
|
312
316
|
const totalMinutes = Math.floor(totalSecondsWithFraction / 60);
|
|
313
317
|
if (totalMinutes === 0) {
|
|
314
318
|
const fractionalSeconds = totalSecondsWithFraction.toFixed(1);
|
package/dist/client/index.js
CHANGED
|
@@ -262,14 +262,18 @@ __export(time_exports, {
|
|
|
262
262
|
startTimer: () => startTimer,
|
|
263
263
|
toMs: () => toMs
|
|
264
264
|
});
|
|
265
|
-
var formatDuration = (
|
|
266
|
-
if (
|
|
265
|
+
var formatDuration = (value, options = {}) => {
|
|
266
|
+
if (value === null || value === void 0 || !Number.isFinite(value) || value < 0) {
|
|
267
|
+
return "--:--";
|
|
268
|
+
}
|
|
267
269
|
const {
|
|
268
270
|
format: fmt = "clock",
|
|
271
|
+
unit = "ms",
|
|
269
272
|
showZero = false,
|
|
270
273
|
showMs = false,
|
|
271
274
|
spaces = true
|
|
272
275
|
} = options;
|
|
276
|
+
const ms = unit === "ss" ? value * 1e3 : unit === "mm" ? value * 60 * 1e3 : value;
|
|
273
277
|
const absMs = Math.abs(ms);
|
|
274
278
|
const totalSeconds = Math.floor(absMs / 1e3);
|
|
275
279
|
const hours = Math.floor(totalSeconds / 3600);
|
|
@@ -306,7 +310,7 @@ var formatDuration = (ms, options = {}) => {
|
|
|
306
310
|
return parts2.join(" ") || "0 seconds";
|
|
307
311
|
}
|
|
308
312
|
if (fmt === "fractional") {
|
|
309
|
-
const totalSecondsWithFraction =
|
|
313
|
+
const totalSecondsWithFraction = absMs / 1e3;
|
|
310
314
|
const totalMinutes = Math.floor(totalSecondsWithFraction / 60);
|
|
311
315
|
if (totalMinutes === 0) {
|
|
312
316
|
const fractionalSeconds = totalSecondsWithFraction.toFixed(1);
|
package/dist/server/index.cjs
CHANGED
|
@@ -7,6 +7,7 @@ var libDynamodb = require('@aws-sdk/lib-dynamodb');
|
|
|
7
7
|
var clientDynamodb = require('@aws-sdk/client-dynamodb');
|
|
8
8
|
var clientSns = require('@aws-sdk/client-sns');
|
|
9
9
|
var clientSqs = require('@aws-sdk/client-sqs');
|
|
10
|
+
var clientSes = require('@aws-sdk/client-ses');
|
|
10
11
|
var clientS3 = require('@aws-sdk/client-s3');
|
|
11
12
|
var s3RequestPresigner = require('@aws-sdk/s3-request-presigner');
|
|
12
13
|
var s3PresignedPost = require('@aws-sdk/s3-presigned-post');
|
|
@@ -273,14 +274,18 @@ __export(time_exports, {
|
|
|
273
274
|
startTimer: () => startTimer,
|
|
274
275
|
toMs: () => toMs
|
|
275
276
|
});
|
|
276
|
-
var formatDuration = (
|
|
277
|
-
if (
|
|
277
|
+
var formatDuration = (value, options = {}) => {
|
|
278
|
+
if (value === null || value === void 0 || !Number.isFinite(value) || value < 0) {
|
|
279
|
+
return "--:--";
|
|
280
|
+
}
|
|
278
281
|
const {
|
|
279
282
|
format: fmt = "clock",
|
|
283
|
+
unit = "ms",
|
|
280
284
|
showZero = false,
|
|
281
285
|
showMs = false,
|
|
282
286
|
spaces = true
|
|
283
287
|
} = options;
|
|
288
|
+
const ms = unit === "ss" ? value * 1e3 : unit === "mm" ? value * 60 * 1e3 : value;
|
|
284
289
|
const absMs = Math.abs(ms);
|
|
285
290
|
const totalSeconds = Math.floor(absMs / 1e3);
|
|
286
291
|
const hours = Math.floor(totalSeconds / 3600);
|
|
@@ -317,7 +322,7 @@ var formatDuration = (ms, options = {}) => {
|
|
|
317
322
|
return parts2.join(" ") || "0 seconds";
|
|
318
323
|
}
|
|
319
324
|
if (fmt === "fractional") {
|
|
320
|
-
const totalSecondsWithFraction =
|
|
325
|
+
const totalSecondsWithFraction = absMs / 1e3;
|
|
321
326
|
const totalMinutes = Math.floor(totalSecondsWithFraction / 60);
|
|
322
327
|
if (totalMinutes === 0) {
|
|
323
328
|
const fractionalSeconds = totalSecondsWithFraction.toFixed(1);
|
|
@@ -1427,11 +1432,43 @@ var send = (sqs, props) => sqs.client.send(
|
|
|
1427
1432
|
})
|
|
1428
1433
|
);
|
|
1429
1434
|
|
|
1435
|
+
// src/server/aws/ses/index.ts
|
|
1436
|
+
var ses_exports = {};
|
|
1437
|
+
__export(ses_exports, {
|
|
1438
|
+
create: () => create5,
|
|
1439
|
+
send: () => send2
|
|
1440
|
+
});
|
|
1441
|
+
|
|
1442
|
+
// src/server/aws/ses/fns.ts
|
|
1443
|
+
var stripHtml = (html) => html.replace(/<style[^>]*>[\s\S]*?<\/style>/gi, "").replace(/<script[^>]*>[\s\S]*?<\/script>/gi, "").replace(/<[^>]+>/g, " ").replace(/ /g, " ").replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/\s+/g, " ").trim();
|
|
1444
|
+
|
|
1445
|
+
// src/server/aws/ses/index.ts
|
|
1446
|
+
var create5 = () => new clientSes.SESClient({ apiVersion: "2010-12-01" });
|
|
1447
|
+
var send2 = (ses, email) => {
|
|
1448
|
+
const Source = `"${email.fromName}" <${email.from}>`;
|
|
1449
|
+
console.log(`[ses] Sending email to ${email.to} from ${email.from}`);
|
|
1450
|
+
const Destination = { ToAddresses: [email.to] };
|
|
1451
|
+
const Body = {
|
|
1452
|
+
Html: { Charset: "UTF-8", Data: email.content },
|
|
1453
|
+
Text: {
|
|
1454
|
+
Charset: "UTF-8",
|
|
1455
|
+
Data: email.textContent || stripHtml(email.content)
|
|
1456
|
+
}
|
|
1457
|
+
};
|
|
1458
|
+
const Subject = { Charset: "UTF-8", Data: email.subject };
|
|
1459
|
+
const command = new clientSes.SendEmailCommand({
|
|
1460
|
+
Message: { Subject, Body },
|
|
1461
|
+
Destination,
|
|
1462
|
+
Source
|
|
1463
|
+
});
|
|
1464
|
+
return ses.send(command);
|
|
1465
|
+
};
|
|
1466
|
+
|
|
1430
1467
|
// src/server/aws/s3/index.ts
|
|
1431
1468
|
var s3_exports = {};
|
|
1432
1469
|
__export(s3_exports, {
|
|
1433
1470
|
bucketHandle: () => bucketHandle,
|
|
1434
|
-
create: () =>
|
|
1471
|
+
create: () => create6,
|
|
1435
1472
|
createSignedUrl: () => createSignedUrl,
|
|
1436
1473
|
deleteFile: () => deleteFile,
|
|
1437
1474
|
getFile: () => getFile,
|
|
@@ -1452,7 +1489,7 @@ var getBucketNameOrThrow = (...candidates) => {
|
|
|
1452
1489
|
};
|
|
1453
1490
|
|
|
1454
1491
|
// src/server/aws/s3/domain.ts
|
|
1455
|
-
var
|
|
1492
|
+
var create6 = (props = {}) => {
|
|
1456
1493
|
const { cdn } = props;
|
|
1457
1494
|
const client = new clientS3.S3Client({});
|
|
1458
1495
|
const bucketName = getBucketNameOrThrow(props.bucketName);
|
|
@@ -1611,6 +1648,7 @@ exports.Log = log_exports;
|
|
|
1611
1648
|
exports.Money = money_exports;
|
|
1612
1649
|
exports.Random = random_exports;
|
|
1613
1650
|
exports.S3 = s3_exports;
|
|
1651
|
+
exports.SES = ses_exports;
|
|
1614
1652
|
exports.SNS = sns_exports;
|
|
1615
1653
|
exports.SQS = sqs_exports;
|
|
1616
1654
|
exports.Str = str_exports;
|
package/dist/server/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,IAAI,MAAM,gBAAgB,CAAC;AACvC,OAAO,KAAK,IAAI,MAAM,gBAAgB,CAAC;AACvC,OAAO,KAAK,GAAG,MAAM,eAAe,CAAC;AACrC,OAAO,KAAK,GAAG,MAAM,eAAe,CAAC;AACrC,OAAO,KAAK,KAAK,MAAM,iBAAiB,CAAC;AACzC,OAAO,KAAK,IAAI,MAAM,gBAAgB,CAAC;AACvC,OAAO,KAAK,IAAI,MAAM,gBAAgB,CAAC;AACvC,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAC;AAC3C,OAAO,KAAK,GAAG,MAAM,eAAe,CAAC;AAGrC,OAAO,KAAK,IAAI,MAAM,QAAQ,CAAC;AAC/B,OAAO,KAAK,MAAM,MAAM,cAAc,CAAC;AACvC,OAAO,KAAK,GAAG,MAAM,WAAW,CAAC;AACjC,OAAO,KAAK,GAAG,MAAM,WAAW,CAAC;AACjC,OAAO,KAAK,GAAG,MAAM,WAAW,CAAC;AACjC,OAAO,KAAK,EAAE,MAAM,UAAU,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,IAAI,MAAM,gBAAgB,CAAC;AACvC,OAAO,KAAK,IAAI,MAAM,gBAAgB,CAAC;AACvC,OAAO,KAAK,GAAG,MAAM,eAAe,CAAC;AACrC,OAAO,KAAK,GAAG,MAAM,eAAe,CAAC;AACrC,OAAO,KAAK,KAAK,MAAM,iBAAiB,CAAC;AACzC,OAAO,KAAK,IAAI,MAAM,gBAAgB,CAAC;AACvC,OAAO,KAAK,IAAI,MAAM,gBAAgB,CAAC;AACvC,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAC;AAC3C,OAAO,KAAK,GAAG,MAAM,eAAe,CAAC;AAGrC,OAAO,KAAK,IAAI,MAAM,QAAQ,CAAC;AAC/B,OAAO,KAAK,MAAM,MAAM,cAAc,CAAC;AACvC,OAAO,KAAK,GAAG,MAAM,WAAW,CAAC;AACjC,OAAO,KAAK,GAAG,MAAM,WAAW,CAAC;AACjC,OAAO,KAAK,GAAG,MAAM,WAAW,CAAC;AACjC,OAAO,KAAK,GAAG,MAAM,WAAW,CAAC;AACjC,OAAO,KAAK,EAAE,MAAM,UAAU,CAAC"}
|
package/dist/server/index.js
CHANGED
|
@@ -5,6 +5,7 @@ import { DynamoDBDocumentClient, ScanCommand, QueryCommand, DeleteCommand, PutCo
|
|
|
5
5
|
import { DynamoDBClient, DeleteTableCommand, DescribeTableCommand, DynamoDBServiceException } from '@aws-sdk/client-dynamodb';
|
|
6
6
|
import { SNSClient, PublishCommand } from '@aws-sdk/client-sns';
|
|
7
7
|
import { SQSClient, SendMessageCommand } from '@aws-sdk/client-sqs';
|
|
8
|
+
import { SESClient, SendEmailCommand } from '@aws-sdk/client-ses';
|
|
8
9
|
import { S3Client, GetObjectCommand, PutObjectCommand, DeleteObjectCommand, HeadObjectCommand, CreateBucketCommand, DeleteBucketCommand, HeadBucketCommand, ListObjectsV2Command, CopyObjectCommand } from '@aws-sdk/client-s3';
|
|
9
10
|
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
|
|
10
11
|
import { createPresignedPost } from '@aws-sdk/s3-presigned-post';
|
|
@@ -271,14 +272,18 @@ __export(time_exports, {
|
|
|
271
272
|
startTimer: () => startTimer,
|
|
272
273
|
toMs: () => toMs
|
|
273
274
|
});
|
|
274
|
-
var formatDuration = (
|
|
275
|
-
if (
|
|
275
|
+
var formatDuration = (value, options = {}) => {
|
|
276
|
+
if (value === null || value === void 0 || !Number.isFinite(value) || value < 0) {
|
|
277
|
+
return "--:--";
|
|
278
|
+
}
|
|
276
279
|
const {
|
|
277
280
|
format: fmt = "clock",
|
|
281
|
+
unit = "ms",
|
|
278
282
|
showZero = false,
|
|
279
283
|
showMs = false,
|
|
280
284
|
spaces = true
|
|
281
285
|
} = options;
|
|
286
|
+
const ms = unit === "ss" ? value * 1e3 : unit === "mm" ? value * 60 * 1e3 : value;
|
|
282
287
|
const absMs = Math.abs(ms);
|
|
283
288
|
const totalSeconds = Math.floor(absMs / 1e3);
|
|
284
289
|
const hours = Math.floor(totalSeconds / 3600);
|
|
@@ -315,7 +320,7 @@ var formatDuration = (ms, options = {}) => {
|
|
|
315
320
|
return parts2.join(" ") || "0 seconds";
|
|
316
321
|
}
|
|
317
322
|
if (fmt === "fractional") {
|
|
318
|
-
const totalSecondsWithFraction =
|
|
323
|
+
const totalSecondsWithFraction = absMs / 1e3;
|
|
319
324
|
const totalMinutes = Math.floor(totalSecondsWithFraction / 60);
|
|
320
325
|
if (totalMinutes === 0) {
|
|
321
326
|
const fractionalSeconds = totalSecondsWithFraction.toFixed(1);
|
|
@@ -1425,11 +1430,43 @@ var send = (sqs, props) => sqs.client.send(
|
|
|
1425
1430
|
})
|
|
1426
1431
|
);
|
|
1427
1432
|
|
|
1433
|
+
// src/server/aws/ses/index.ts
|
|
1434
|
+
var ses_exports = {};
|
|
1435
|
+
__export(ses_exports, {
|
|
1436
|
+
create: () => create5,
|
|
1437
|
+
send: () => send2
|
|
1438
|
+
});
|
|
1439
|
+
|
|
1440
|
+
// src/server/aws/ses/fns.ts
|
|
1441
|
+
var stripHtml = (html) => html.replace(/<style[^>]*>[\s\S]*?<\/style>/gi, "").replace(/<script[^>]*>[\s\S]*?<\/script>/gi, "").replace(/<[^>]+>/g, " ").replace(/ /g, " ").replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/\s+/g, " ").trim();
|
|
1442
|
+
|
|
1443
|
+
// src/server/aws/ses/index.ts
|
|
1444
|
+
var create5 = () => new SESClient({ apiVersion: "2010-12-01" });
|
|
1445
|
+
var send2 = (ses, email) => {
|
|
1446
|
+
const Source = `"${email.fromName}" <${email.from}>`;
|
|
1447
|
+
console.log(`[ses] Sending email to ${email.to} from ${email.from}`);
|
|
1448
|
+
const Destination = { ToAddresses: [email.to] };
|
|
1449
|
+
const Body = {
|
|
1450
|
+
Html: { Charset: "UTF-8", Data: email.content },
|
|
1451
|
+
Text: {
|
|
1452
|
+
Charset: "UTF-8",
|
|
1453
|
+
Data: email.textContent || stripHtml(email.content)
|
|
1454
|
+
}
|
|
1455
|
+
};
|
|
1456
|
+
const Subject = { Charset: "UTF-8", Data: email.subject };
|
|
1457
|
+
const command = new SendEmailCommand({
|
|
1458
|
+
Message: { Subject, Body },
|
|
1459
|
+
Destination,
|
|
1460
|
+
Source
|
|
1461
|
+
});
|
|
1462
|
+
return ses.send(command);
|
|
1463
|
+
};
|
|
1464
|
+
|
|
1428
1465
|
// src/server/aws/s3/index.ts
|
|
1429
1466
|
var s3_exports = {};
|
|
1430
1467
|
__export(s3_exports, {
|
|
1431
1468
|
bucketHandle: () => bucketHandle,
|
|
1432
|
-
create: () =>
|
|
1469
|
+
create: () => create6,
|
|
1433
1470
|
createSignedUrl: () => createSignedUrl,
|
|
1434
1471
|
deleteFile: () => deleteFile,
|
|
1435
1472
|
getFile: () => getFile,
|
|
@@ -1450,7 +1487,7 @@ var getBucketNameOrThrow = (...candidates) => {
|
|
|
1450
1487
|
};
|
|
1451
1488
|
|
|
1452
1489
|
// src/server/aws/s3/domain.ts
|
|
1453
|
-
var
|
|
1490
|
+
var create6 = (props = {}) => {
|
|
1454
1491
|
const { cdn } = props;
|
|
1455
1492
|
const client = new S3Client({});
|
|
1456
1493
|
const bucketName = getBucketNameOrThrow(props.bucketName);
|
|
@@ -1598,4 +1635,4 @@ var recordsFromSqs = (body) => {
|
|
|
1598
1635
|
}
|
|
1599
1636
|
};
|
|
1600
1637
|
|
|
1601
|
-
export { ddb_exports as DDB, dict_exports as Dict, file_exports as File, flow_exports as Flow, int_exports as Int, lambda_exports as Lambda, list_exports as List, log_exports as Log, money_exports as Money, random_exports as Random, s3_exports as S3, sns_exports as SNS, sqs_exports as SQS, str_exports as Str, time_exports as Time };
|
|
1638
|
+
export { ddb_exports as DDB, dict_exports as Dict, file_exports as File, flow_exports as Flow, int_exports as Int, lambda_exports as Lambda, list_exports as List, log_exports as Log, money_exports as Money, random_exports as Random, s3_exports as S3, ses_exports as SES, sns_exports as SNS, sqs_exports as SQS, str_exports as Str, time_exports as Time };
|
package/dist/shared/time.d.ts
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import type { Locale } from "date-fns";
|
|
2
2
|
type DurationFormat = "compact" | "full" | "clock" | "fractional";
|
|
3
|
+
type DurationUnit = "ms" | "ss" | "mm";
|
|
3
4
|
type DurationOptions = {
|
|
4
5
|
/** Format style: 'compact' (1h 2m), 'full' (1 hour 2 minutes), 'clock' (01:02:03), 'fractional' (1.4s, 1m4.4s) */
|
|
5
6
|
format?: DurationFormat;
|
|
7
|
+
/** Input unit: 'ms' (milliseconds, default), 'ss' (seconds), or 'mm' (minutes). Use 'ss' for audio/video currentTime. */
|
|
8
|
+
unit?: DurationUnit;
|
|
6
9
|
/** Show zero values for intermediate units (e.g., "1h 0m 30s" vs "1h 30s") */
|
|
7
10
|
showZero?: boolean;
|
|
8
11
|
/** Include milliseconds in compact format (e.g., "1s 200ms") */
|
|
@@ -11,30 +14,88 @@ type DurationOptions = {
|
|
|
11
14
|
spaces?: boolean;
|
|
12
15
|
};
|
|
13
16
|
/**
|
|
14
|
-
* Formats
|
|
15
|
-
* Supports compact (1h 2m), full (`1 hour 2 minutes`), clock (`01:02:03`), and fractional (1.4s, 1m4.4s) formats
|
|
17
|
+
* Formats durations into human-readable strings for audio players, timers, and recording UIs.
|
|
16
18
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
19
|
+
* Audio/video APIs typically provide time in seconds (e.g., `audio.currentTime`), while
|
|
20
|
+
* JavaScript timers use milliseconds. This function handles both via the `unit` option,
|
|
21
|
+
* eliminating manual conversion at call sites. Invalid inputs (null, undefined, NaN,
|
|
22
|
+
* Infinity, negative) return "--:--" for safe display in UIs.
|
|
23
|
+
*
|
|
24
|
+
* @param value - Duration value in the specified unit (defaults to milliseconds)
|
|
25
|
+
* @param options - Configuration options
|
|
26
|
+
* @param options.format - Output format: 'clock' (default), 'compact', 'full', or 'fractional'
|
|
27
|
+
* @param options.unit - Input unit: 'ms' (milliseconds, default), 'ss' (seconds), or 'mm' (minutes)
|
|
28
|
+
* @param options.showZero - Show zero intermediate units (e.g., "1h 0m 0s" vs "1h")
|
|
29
|
+
* @param options.showMs - Include milliseconds in compact format
|
|
30
|
+
* @param options.spaces - Use spaces between units in compact format (default: true)
|
|
22
31
|
*
|
|
23
32
|
* @example
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
33
|
+
* ```ts
|
|
34
|
+
* // ─────────────────────────────────────────────────────────────────────────────
|
|
35
|
+
* // CLOCK FORMAT (default) - "m:ss" or "h:mm:ss"
|
|
36
|
+
* // Best for: audio players, video players, media timelines
|
|
37
|
+
* // ─────────────────────────────────────────────────────────────────────────────
|
|
38
|
+
* formatDuration(90000) // "1:30"
|
|
39
|
+
* formatDuration(3661000) // "1:01:01"
|
|
40
|
+
* formatDuration(45, { unit: "ss" }) // "0:45"
|
|
41
|
+
* formatDuration(225, { unit: "ss" }) // "3:45"
|
|
42
|
+
* formatDuration(3661, { unit: "ss" }) // "1:01:01"
|
|
43
|
+
* formatDuration(90, { unit: "mm" }) // "1:30:00"
|
|
44
|
+
*
|
|
45
|
+
* // ─────────────────────────────────────────────────────────────────────────────
|
|
46
|
+
* // COMPACT FORMAT - "1h 2m 3s" or "1h2m3s"
|
|
47
|
+
* // Best for: recording timers, duration badges, compact displays
|
|
48
|
+
* // ─────────────────────────────────────────────────────────────────────────────
|
|
49
|
+
* formatDuration(90000, { format: "compact" }) // "1m 30s"
|
|
50
|
+
* formatDuration(3600000, { format: "compact" }) // "1h"
|
|
51
|
+
* formatDuration(3661000, { format: "compact" }) // "1h 1m 1s"
|
|
52
|
+
* formatDuration(45, { unit: "ss", format: "compact" }) // "45s"
|
|
53
|
+
* formatDuration(90, { unit: "ss", format: "compact" }) // "1m 30s"
|
|
54
|
+
* formatDuration(3661, { unit: "ss", format: "compact" }) // "1h 1m 1s"
|
|
55
|
+
*
|
|
56
|
+
* // Without spaces (recording timer style)
|
|
57
|
+
* formatDuration(3661, { unit: "ss", format: "compact", spaces: false }) // "1h1m1s"
|
|
58
|
+
* formatDuration(90, { unit: "ss", format: "compact", spaces: false }) // "1m30s"
|
|
59
|
+
* formatDuration(45, { unit: "ss", format: "compact", spaces: false }) // "45s"
|
|
60
|
+
*
|
|
61
|
+
* // With zero intermediate units
|
|
29
62
|
* formatDuration(3600000, { format: "compact", showZero: true }) // "1h 0m 0s"
|
|
30
|
-
* formatDuration(
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* formatDuration(
|
|
34
|
-
* formatDuration(1234, { format: "compact", showMs: true }) // "1s 234ms"
|
|
63
|
+
* formatDuration(3601000, { format: "compact", showZero: true }) // "1h 0m 1s"
|
|
64
|
+
*
|
|
65
|
+
* // With milliseconds
|
|
66
|
+
* formatDuration(1234, { format: "compact", showMs: true }) // "1s 234ms"
|
|
35
67
|
* formatDuration(1234, { format: "compact", showMs: true, spaces: false }) // "1s234ms"
|
|
68
|
+
*
|
|
69
|
+
* // ─────────────────────────────────────────────────────────────────────────────
|
|
70
|
+
* // FULL FORMAT - "1 hour 2 minutes 3 seconds"
|
|
71
|
+
* // Best for: accessibility, screen readers, verbose displays
|
|
72
|
+
* // ─────────────────────────────────────────────────────────────────────────────
|
|
73
|
+
* formatDuration(90000, { format: "full" }) // "1 minute 30 seconds"
|
|
74
|
+
* formatDuration(3600000, { format: "full" }) // "1 hour"
|
|
75
|
+
* formatDuration(3661000, { format: "full" }) // "1 hour 1 minute 1 second"
|
|
76
|
+
* formatDuration(7200000, { format: "full" }) // "2 hours"
|
|
77
|
+
* formatDuration(3660000, { format: "full", showZero: true }) // "1 hour 1 minute 0 seconds"
|
|
78
|
+
*
|
|
79
|
+
* // ─────────────────────────────────────────────────────────────────────────────
|
|
80
|
+
* // FRACTIONAL FORMAT - "1.4s" or "1m 4.4s"
|
|
81
|
+
* // Best for: precise timing, animations, performance metrics
|
|
82
|
+
* // ─────────────────────────────────────────────────────────────────────────────
|
|
83
|
+
* formatDuration(1400, { format: "fractional" }) // "1.4s"
|
|
84
|
+
* formatDuration(45300, { format: "fractional" }) // "45.3s"
|
|
85
|
+
* formatDuration(64400, { format: "fractional" }) // "1m 4.4s"
|
|
86
|
+
*
|
|
87
|
+
* // ─────────────────────────────────────────────────────────────────────────────
|
|
88
|
+
* // INVALID/LOADING STATES - Returns "--:--" for safe UI display
|
|
89
|
+
* // ─────────────────────────────────────────────────────────────────────────────
|
|
90
|
+
* formatDuration(null) // "--:--"
|
|
91
|
+
* formatDuration(undefined) // "--:--"
|
|
92
|
+
* formatDuration(NaN) // "--:--"
|
|
93
|
+
* formatDuration(Infinity) // "--:--"
|
|
94
|
+
* formatDuration(-5) // "--:--"
|
|
95
|
+
* formatDuration(-5, { unit: "ss" }) // "--:--"
|
|
96
|
+
* ```
|
|
36
97
|
*/
|
|
37
|
-
export declare const formatDuration: (
|
|
98
|
+
export declare const formatDuration: (value: number | null | undefined, options?: DurationOptions) => string;
|
|
38
99
|
type DateInput = Date | string | number;
|
|
39
100
|
type DateFormatStyle = "iso" | "short" | "medium" | "long" | "relative" | "year";
|
|
40
101
|
type DateOptions = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"time.d.ts","sourceRoot":"","sources":["../../src/shared/time.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAMvC,KAAK,cAAc,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"time.d.ts","sourceRoot":"","sources":["../../src/shared/time.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "qstd",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.25",
|
|
4
4
|
"description": "Standard Block component and utilities library with Panda CSS",
|
|
5
5
|
"author": "malin1",
|
|
6
6
|
"license": "MIT",
|
|
@@ -42,6 +42,24 @@
|
|
|
42
42
|
"sideEffects": [
|
|
43
43
|
"dist/react/index.css"
|
|
44
44
|
],
|
|
45
|
+
"scripts": {
|
|
46
|
+
"build": "panda codegen && panda cssgen && tsup && tsc -p tsconfig.build.json && node scripts/inject-css-import.js",
|
|
47
|
+
"build:js": "tsup",
|
|
48
|
+
"build:types": "tsc -p tsconfig.build.json",
|
|
49
|
+
"dev": "tsup --watch",
|
|
50
|
+
"prepublishOnly": "pnpm build",
|
|
51
|
+
"prepare:local": "pnpm build && cd playground && pnpm prepare",
|
|
52
|
+
"test": "vitest run",
|
|
53
|
+
"test:watch": "vitest",
|
|
54
|
+
"test:all": "pnpx tsx tests/test-all.ts",
|
|
55
|
+
"test:block": "node tests/test-block.tsx",
|
|
56
|
+
"test:playground": "node tests/playground-e2e.mjs",
|
|
57
|
+
"typecheck": "tsc --noEmit",
|
|
58
|
+
"typecheck:perf": "tsc --noEmit --extendedDiagnostics",
|
|
59
|
+
"typecheck:trace": "tsc --noEmit --generateTrace ./performance/ts-trace",
|
|
60
|
+
"analyze:tsserver": "bash performance/analyze-tsserver.sh",
|
|
61
|
+
"lint": "eslint ."
|
|
62
|
+
},
|
|
45
63
|
"peerDependencies": {
|
|
46
64
|
"react": "^18.0.0 || ^19.0.0",
|
|
47
65
|
"react-dom": "^18.0.0 || ^19.0.0"
|
|
@@ -108,22 +126,5 @@
|
|
|
108
126
|
"bugs": {
|
|
109
127
|
"url": "https://github.com/55cancri/qstd/issues"
|
|
110
128
|
},
|
|
111
|
-
"homepage": "https://github.com/55cancri/qstd#readme"
|
|
112
|
-
|
|
113
|
-
"build": "panda codegen && panda cssgen && tsup && tsc -p tsconfig.build.json && node scripts/inject-css-import.js",
|
|
114
|
-
"build:js": "tsup",
|
|
115
|
-
"build:types": "tsc -p tsconfig.build.json",
|
|
116
|
-
"dev": "tsup --watch",
|
|
117
|
-
"prepare:local": "pnpm build && cd playground && pnpm prepare",
|
|
118
|
-
"test": "vitest run",
|
|
119
|
-
"test:watch": "vitest",
|
|
120
|
-
"test:all": "pnpx tsx tests/test-all.ts",
|
|
121
|
-
"test:block": "node tests/test-block.tsx",
|
|
122
|
-
"test:playground": "node tests/playground-e2e.mjs",
|
|
123
|
-
"typecheck": "tsc --noEmit",
|
|
124
|
-
"typecheck:perf": "tsc --noEmit --extendedDiagnostics",
|
|
125
|
-
"typecheck:trace": "tsc --noEmit --generateTrace ./performance/ts-trace",
|
|
126
|
-
"analyze:tsserver": "bash performance/analyze-tsserver.sh",
|
|
127
|
-
"lint": "eslint ."
|
|
128
|
-
}
|
|
129
|
-
}
|
|
129
|
+
"homepage": "https://github.com/55cancri/qstd#readme"
|
|
130
|
+
}
|