@spfn/core 0.3.0-beta.3 → 0.3.0-beta.31
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 +304 -12
- package/dist/app-config/index.d.ts +39 -1
- package/dist/app-config/index.js.map +1 -1
- package/dist/authz/index.js +47 -391
- package/dist/authz/index.js.map +1 -1
- package/dist/{boss-D16fO2oG.d.ts → boss-BiDCbbAQ.d.ts} +60 -7
- package/dist/codegen/index.d.ts +157 -16
- package/dist/codegen/index.js +772 -166
- package/dist/codegen/index.js.map +1 -1
- package/dist/config/index.js +4 -4
- package/dist/config/index.js.map +1 -1
- package/dist/contract/index.d.ts +39 -16
- package/dist/contract/index.js +147 -23
- package/dist/contract/index.js.map +1 -1
- package/dist/db/index.d.ts +230 -35
- package/dist/db/index.js +316 -160
- package/dist/db/index.js.map +1 -1
- package/dist/env/index.d.ts +6 -442
- package/dist/env/index.js +13 -16
- package/dist/env/index.js.map +1 -1
- package/dist/env/loader.js +24 -1
- package/dist/env/loader.js.map +1 -1
- package/dist/error-CIZlYJlL.d.ts +157 -0
- package/dist/errors/index.d.ts +18 -1
- package/dist/errors/index.js +47 -391
- package/dist/errors/index.js.map +1 -1
- package/dist/event/index.d.ts +5 -5
- package/dist/event/index.js +202 -3
- package/dist/event/index.js.map +1 -1
- package/dist/event/sse/client.d.ts +18 -4
- package/dist/event/sse/client.js +94 -18
- package/dist/event/sse/client.js.map +1 -1
- package/dist/event/sse/index.d.ts +18 -5
- package/dist/event/sse/index.js +452 -114
- package/dist/event/sse/index.js.map +1 -1
- package/dist/event/ws/client.d.ts +3 -2
- package/dist/event/ws/index.d.ts +4 -3
- package/dist/job/index.d.ts +48 -3
- package/dist/job/index.js +131 -52
- package/dist/job/index.js.map +1 -1
- package/dist/logger/index.js +0 -12
- package/dist/logger/index.js.map +1 -1
- package/dist/middleware/index.js +52 -397
- package/dist/middleware/index.js.map +1 -1
- package/dist/nextjs/index.d.ts +75 -14
- package/dist/nextjs/index.js +200 -84
- package/dist/nextjs/index.js.map +1 -1
- package/dist/nextjs/server.d.ts +46 -8
- package/dist/nextjs/server.js +15 -1
- package/dist/nextjs/server.js.map +1 -1
- package/dist/ops/index.d.ts +61 -42
- package/dist/ops/index.js +648 -97
- package/dist/ops/index.js.map +1 -1
- package/dist/registry-C2KQCh0m.d.ts +473 -0
- package/dist/route/index.d.ts +5 -2
- package/dist/route/index.js +107 -28
- package/dist/route/index.js.map +1 -1
- package/dist/route/types.d.ts +7 -1
- package/dist/{router-Cy7rAfmj.d.ts → route-builder-DRW-MSCJ.d.ts} +51 -126
- package/dist/router-C57y-vz1.d.ts +184 -0
- package/dist/router-CX5uVjmU.d.ts +406 -0
- package/dist/server/index.d.ts +130 -7
- package/dist/server/index.js +1174 -164
- package/dist/server/index.js.map +1 -1
- package/dist/state/client.d.ts +206 -0
- package/dist/state/client.js +678 -0
- package/dist/state/client.js.map +1 -0
- package/dist/state/index.d.ts +443 -0
- package/dist/state/index.js +644 -0
- package/dist/state/index.js.map +1 -0
- package/dist/state/react.d.ts +49 -0
- package/dist/state/react.js +50 -0
- package/dist/state/react.js.map +1 -0
- package/dist/surface/index.d.ts +115 -0
- package/dist/surface/index.js +1013 -0
- package/dist/surface/index.js.map +1 -0
- package/dist/token-manager-Ckjt2-qq.d.ts +122 -0
- package/dist/{types-CfYVhIQ9.d.ts → types-5Rl11_Nb.d.ts} +43 -4
- package/dist/types-CKH0D3Dy.d.ts +441 -0
- package/dist/{types-ZQODsBft.d.ts → types-CurMab2Q.d.ts} +52 -2
- package/dist/{types-2AbaW4Ie.d.ts → types-DncqXfWN.d.ts} +4 -3
- package/docs/file-upload.md +195 -333
- package/package.json +41 -11
- package/src/cache/README.md +330 -0
- package/src/codegen/README.md +721 -0
- package/src/config/README.md +333 -0
- package/src/contract/README.md +442 -0
- package/src/db/README.md +589 -0
- package/src/db/manager/README.md +500 -0
- package/src/db/schema/README.md +354 -0
- package/src/db/transaction/README.md +845 -0
- package/src/env/README.md +787 -0
- package/src/errors/README.md +445 -0
- package/src/event/README.md +994 -0
- package/src/job/README.md +613 -0
- package/src/logger/README.md +321 -0
- package/src/middleware/README.md +634 -0
- package/src/nextjs/README.md +756 -0
- package/src/route/README.md +763 -0
- package/src/security/README.md +100 -0
- package/src/server/README.md +704 -0
- package/src/state/README.md +806 -0
- package/dist/token-manager-BT5EnUAR.d.ts +0 -278
- package/dist/types-9oszaJqp.d.ts +0 -250
package/dist/middleware/index.js
CHANGED
|
@@ -2,7 +2,6 @@ import { randomBytes, createHmac, createHash, timingSafeEqual } from 'crypto';
|
|
|
2
2
|
import { SerializableError } from '@spfn/core/errors';
|
|
3
3
|
import { logger } from '@spfn/core/logger';
|
|
4
4
|
import { env } from '@spfn/core/config';
|
|
5
|
-
import { format } from 'util';
|
|
6
5
|
|
|
7
6
|
// src/middleware/error-handler.ts
|
|
8
7
|
var errorLogger = logger.child("@spfn/core:error-handler");
|
|
@@ -327,8 +326,27 @@ function isCacheDisabled() {
|
|
|
327
326
|
}
|
|
328
327
|
|
|
329
328
|
// src/errors/error-registry.ts
|
|
329
|
+
function probeName(ErrorClass) {
|
|
330
|
+
try {
|
|
331
|
+
return new ErrorClass({}).name;
|
|
332
|
+
} catch {
|
|
333
|
+
return void 0;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
function ownInstanceName(ErrorClass) {
|
|
337
|
+
const name = probeName(ErrorClass);
|
|
338
|
+
const Parent = Object.getPrototypeOf(ErrorClass);
|
|
339
|
+
return name !== void 0 && name !== probeName(Parent) ? name : void 0;
|
|
340
|
+
}
|
|
330
341
|
var ErrorRegistry = class _ErrorRegistry {
|
|
331
342
|
errors = /* @__PURE__ */ new Map();
|
|
343
|
+
/**
|
|
344
|
+
* The same classes keyed by the name their instances set for themselves.
|
|
345
|
+
* Consulted only when no class is registered under the constructor name, so
|
|
346
|
+
* an unminified registry resolves exactly as before and a minified one —
|
|
347
|
+
* whose constructor names are `Q`, `eA`, … — still resolves `__type`.
|
|
348
|
+
*/
|
|
349
|
+
instanceNames = /* @__PURE__ */ new Map();
|
|
332
350
|
constructor(initialErrors) {
|
|
333
351
|
if (initialErrors) {
|
|
334
352
|
for (const input of initialErrors) {
|
|
@@ -349,15 +367,22 @@ var ErrorRegistry = class _ErrorRegistry {
|
|
|
349
367
|
* @returns This registry for chaining
|
|
350
368
|
*/
|
|
351
369
|
append(input) {
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
this.errors.set(ErrorClass.name, ErrorClass);
|
|
355
|
-
}
|
|
356
|
-
} else {
|
|
357
|
-
this.errors.set(input.name, input);
|
|
370
|
+
for (const ErrorClass of Array.isArray(input) ? input : [input]) {
|
|
371
|
+
this.register(ErrorClass);
|
|
358
372
|
}
|
|
359
373
|
return this;
|
|
360
374
|
}
|
|
375
|
+
/**
|
|
376
|
+
* Key `ErrorClass` by its constructor name and, when its instances set one of
|
|
377
|
+
* their own, by that name too.
|
|
378
|
+
*/
|
|
379
|
+
register(ErrorClass) {
|
|
380
|
+
this.errors.set(ErrorClass.name, ErrorClass);
|
|
381
|
+
const name = ownInstanceName(ErrorClass);
|
|
382
|
+
if (name !== void 0) {
|
|
383
|
+
this.instanceNames.set(name, ErrorClass);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
361
386
|
/**
|
|
362
387
|
* Concatenate another ErrorRegistry into this one
|
|
363
388
|
*
|
|
@@ -368,15 +393,25 @@ var ErrorRegistry = class _ErrorRegistry {
|
|
|
368
393
|
for (const [name, ErrorClass] of registry.errors) {
|
|
369
394
|
this.errors.set(name, ErrorClass);
|
|
370
395
|
}
|
|
396
|
+
for (const [name, ErrorClass] of registry.instanceNames) {
|
|
397
|
+
this.instanceNames.set(name, ErrorClass);
|
|
398
|
+
}
|
|
371
399
|
return this;
|
|
372
400
|
}
|
|
401
|
+
/**
|
|
402
|
+
* The class registered for `type`: by constructor name first, then by the
|
|
403
|
+
* name its instances carry.
|
|
404
|
+
*/
|
|
405
|
+
find(type) {
|
|
406
|
+
return this.errors.get(type) ?? this.instanceNames.get(type);
|
|
407
|
+
}
|
|
373
408
|
/**
|
|
374
409
|
* Check if error type is registered
|
|
375
410
|
*
|
|
376
|
-
* @param name - Error class name
|
|
411
|
+
* @param name - Error class name, or the name its instances carry
|
|
377
412
|
*/
|
|
378
413
|
has(name) {
|
|
379
|
-
return this.
|
|
414
|
+
return this.find(name) !== void 0;
|
|
380
415
|
}
|
|
381
416
|
/**
|
|
382
417
|
* Deserialize error from JSON data
|
|
@@ -386,7 +421,7 @@ var ErrorRegistry = class _ErrorRegistry {
|
|
|
386
421
|
* @throws Error if error type is not registered
|
|
387
422
|
*/
|
|
388
423
|
deserialize(data) {
|
|
389
|
-
const ErrorClass = this.
|
|
424
|
+
const ErrorClass = this.find(data.__type);
|
|
390
425
|
if (!ErrorClass) {
|
|
391
426
|
throw new Error(`Unknown error type: ${data.__type}`);
|
|
392
427
|
}
|
|
@@ -413,389 +448,9 @@ var ErrorRegistry = class _ErrorRegistry {
|
|
|
413
448
|
* Get all registered error types
|
|
414
449
|
*/
|
|
415
450
|
getRegisteredTypes() {
|
|
416
|
-
return
|
|
417
|
-
}
|
|
418
|
-
};
|
|
419
|
-
|
|
420
|
-
// src/logger/types.ts
|
|
421
|
-
var LOG_LEVEL_PRIORITY = {
|
|
422
|
-
debug: 0,
|
|
423
|
-
info: 1,
|
|
424
|
-
warn: 2,
|
|
425
|
-
error: 3,
|
|
426
|
-
fatal: 4
|
|
427
|
-
};
|
|
428
|
-
|
|
429
|
-
// src/logger/formatters.ts
|
|
430
|
-
var SENSITIVE_KEYS = [
|
|
431
|
-
"password",
|
|
432
|
-
"passwd",
|
|
433
|
-
"pwd",
|
|
434
|
-
"secret",
|
|
435
|
-
"token",
|
|
436
|
-
"apikey",
|
|
437
|
-
"api_key",
|
|
438
|
-
"accesstoken",
|
|
439
|
-
"access_token",
|
|
440
|
-
"refreshtoken",
|
|
441
|
-
"refresh_token",
|
|
442
|
-
"authorization",
|
|
443
|
-
"auth",
|
|
444
|
-
"cookie",
|
|
445
|
-
"session",
|
|
446
|
-
"sessionid",
|
|
447
|
-
"session_id",
|
|
448
|
-
"privatekey",
|
|
449
|
-
"private_key",
|
|
450
|
-
"creditcard",
|
|
451
|
-
"credit_card",
|
|
452
|
-
"cardnumber",
|
|
453
|
-
"card_number",
|
|
454
|
-
"cvv",
|
|
455
|
-
"ssn",
|
|
456
|
-
"pin"
|
|
457
|
-
];
|
|
458
|
-
var MASKED_VALUE = "***MASKED***";
|
|
459
|
-
function isSensitiveKey(key) {
|
|
460
|
-
const lowerKey = key.toLowerCase();
|
|
461
|
-
return SENSITIVE_KEYS.some((sensitive) => lowerKey.includes(sensitive));
|
|
462
|
-
}
|
|
463
|
-
function maskSensitiveData(data, seen = /* @__PURE__ */ new WeakSet()) {
|
|
464
|
-
if (data === null || data === void 0) {
|
|
465
|
-
return data;
|
|
466
|
-
}
|
|
467
|
-
if (typeof data !== "object") {
|
|
468
|
-
return data;
|
|
469
|
-
}
|
|
470
|
-
if (seen.has(data)) {
|
|
471
|
-
return "[Circular]";
|
|
451
|
+
return [.../* @__PURE__ */ new Set([...this.errors.keys(), ...this.instanceNames.keys()])];
|
|
472
452
|
}
|
|
473
|
-
seen.add(data);
|
|
474
|
-
if (Array.isArray(data)) {
|
|
475
|
-
return data.map((item) => maskSensitiveData(item, seen));
|
|
476
|
-
}
|
|
477
|
-
const masked = {};
|
|
478
|
-
for (const [key, value] of Object.entries(data)) {
|
|
479
|
-
if (isSensitiveKey(key)) {
|
|
480
|
-
masked[key] = MASKED_VALUE;
|
|
481
|
-
} else if (typeof value === "object" && value !== null) {
|
|
482
|
-
masked[key] = maskSensitiveData(value, seen);
|
|
483
|
-
} else {
|
|
484
|
-
masked[key] = value;
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
|
-
return masked;
|
|
488
|
-
}
|
|
489
|
-
var COLORS = {
|
|
490
|
-
reset: "\x1B[0m",
|
|
491
|
-
bright: "\x1B[1m",
|
|
492
|
-
dim: "\x1B[2m",
|
|
493
|
-
// 로그 레벨 컬러
|
|
494
|
-
debug: "\x1B[36m",
|
|
495
|
-
// cyan
|
|
496
|
-
info: "\x1B[32m",
|
|
497
|
-
// green
|
|
498
|
-
warn: "\x1B[33m",
|
|
499
|
-
// yellow
|
|
500
|
-
error: "\x1B[31m",
|
|
501
|
-
// red
|
|
502
|
-
fatal: "\x1B[35m",
|
|
503
|
-
// magenta
|
|
504
|
-
// 추가 컬러
|
|
505
|
-
gray: "\x1B[90m"
|
|
506
453
|
};
|
|
507
|
-
function formatTimestampHuman(date) {
|
|
508
|
-
const year = date.getFullYear();
|
|
509
|
-
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
510
|
-
const day = String(date.getDate()).padStart(2, "0");
|
|
511
|
-
const hours = String(date.getHours()).padStart(2, "0");
|
|
512
|
-
const minutes = String(date.getMinutes()).padStart(2, "0");
|
|
513
|
-
const seconds = String(date.getSeconds()).padStart(2, "0");
|
|
514
|
-
const ms = String(date.getMilliseconds()).padStart(3, "0");
|
|
515
|
-
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}.${ms}`;
|
|
516
|
-
}
|
|
517
|
-
function formatError(error) {
|
|
518
|
-
const lines = [];
|
|
519
|
-
lines.push(`${error.name}: ${error.message}`);
|
|
520
|
-
if (error.stack) {
|
|
521
|
-
const stackLines = error.stack.split("\n").slice(1);
|
|
522
|
-
lines.push(...stackLines);
|
|
523
|
-
}
|
|
524
|
-
if (error.cause instanceof Error) {
|
|
525
|
-
lines.push(`Caused by: ${formatError(error.cause)}`);
|
|
526
|
-
} else if (error.cause !== void 0) {
|
|
527
|
-
lines.push(`Caused by: ${String(error.cause)}`);
|
|
528
|
-
}
|
|
529
|
-
return lines.join("\n");
|
|
530
|
-
}
|
|
531
|
-
function formatConsole(metadata, colorize = true) {
|
|
532
|
-
const parts = [];
|
|
533
|
-
const timestamp = formatTimestampHuman(metadata.timestamp);
|
|
534
|
-
if (colorize) {
|
|
535
|
-
parts.push(`${COLORS.gray}[${timestamp}]${COLORS.reset}`);
|
|
536
|
-
} else {
|
|
537
|
-
parts.push(`[${timestamp}]`);
|
|
538
|
-
}
|
|
539
|
-
const pid = process.pid;
|
|
540
|
-
if (colorize) {
|
|
541
|
-
parts.push(`${COLORS.dim}[pid=${pid}]${COLORS.reset}`);
|
|
542
|
-
} else {
|
|
543
|
-
parts.push(`[pid=${pid}]`);
|
|
544
|
-
}
|
|
545
|
-
if (metadata.module) {
|
|
546
|
-
if (colorize) {
|
|
547
|
-
parts.push(`${COLORS.dim}[module=${metadata.module}]${COLORS.reset}`);
|
|
548
|
-
} else {
|
|
549
|
-
parts.push(`[module=${metadata.module}]`);
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
if (metadata.context && Object.keys(metadata.context).length > 0) {
|
|
553
|
-
Object.entries(metadata.context).forEach(([key, value]) => {
|
|
554
|
-
let valueStr;
|
|
555
|
-
if (typeof value === "string") {
|
|
556
|
-
valueStr = value;
|
|
557
|
-
} else if (typeof value === "object" && value !== null) {
|
|
558
|
-
try {
|
|
559
|
-
valueStr = JSON.stringify(value);
|
|
560
|
-
} catch (error) {
|
|
561
|
-
valueStr = "[circular]";
|
|
562
|
-
}
|
|
563
|
-
} else {
|
|
564
|
-
valueStr = String(value);
|
|
565
|
-
}
|
|
566
|
-
if (colorize) {
|
|
567
|
-
parts.push(`${COLORS.dim}[${key}=${valueStr}]${COLORS.reset}`);
|
|
568
|
-
} else {
|
|
569
|
-
parts.push(`[${key}=${valueStr}]`);
|
|
570
|
-
}
|
|
571
|
-
});
|
|
572
|
-
}
|
|
573
|
-
const levelStr = metadata.level.toUpperCase();
|
|
574
|
-
if (colorize) {
|
|
575
|
-
const color = COLORS[metadata.level];
|
|
576
|
-
parts.push(`${color}(${levelStr})${COLORS.reset}:`);
|
|
577
|
-
} else {
|
|
578
|
-
parts.push(`(${levelStr}):`);
|
|
579
|
-
}
|
|
580
|
-
if (colorize) {
|
|
581
|
-
parts.push(`${COLORS.bright}${metadata.message}${COLORS.reset}`);
|
|
582
|
-
} else {
|
|
583
|
-
parts.push(metadata.message);
|
|
584
|
-
}
|
|
585
|
-
let output = parts.join(" ");
|
|
586
|
-
if (metadata.error) {
|
|
587
|
-
output += "\n" + formatError(metadata.error);
|
|
588
|
-
}
|
|
589
|
-
return output;
|
|
590
|
-
}
|
|
591
|
-
|
|
592
|
-
// src/logger/logger.ts
|
|
593
|
-
var FORMAT_PATTERN = /%[sdifjoOc%]/;
|
|
594
|
-
var Logger = class _Logger {
|
|
595
|
-
config;
|
|
596
|
-
module;
|
|
597
|
-
constructor(config) {
|
|
598
|
-
this.config = config;
|
|
599
|
-
this.module = config.module;
|
|
600
|
-
}
|
|
601
|
-
/**
|
|
602
|
-
* Convert unknown error to Error object
|
|
603
|
-
*/
|
|
604
|
-
toError(error) {
|
|
605
|
-
if (error instanceof Error) return error;
|
|
606
|
-
if (typeof error === "string") return new Error(error);
|
|
607
|
-
if (typeof error === "object" && error !== null) {
|
|
608
|
-
return new Error(JSON.stringify(error));
|
|
609
|
-
}
|
|
610
|
-
return new Error(String(error));
|
|
611
|
-
}
|
|
612
|
-
/**
|
|
613
|
-
* Check if value is a context object (not an error)
|
|
614
|
-
*/
|
|
615
|
-
isContext(value) {
|
|
616
|
-
if (typeof value !== "object" || value === null) return false;
|
|
617
|
-
if (value instanceof Error) return false;
|
|
618
|
-
const hasStack = "stack" in value && typeof value.stack === "string";
|
|
619
|
-
if (hasStack) {
|
|
620
|
-
return false;
|
|
621
|
-
}
|
|
622
|
-
return true;
|
|
623
|
-
}
|
|
624
|
-
/**
|
|
625
|
-
* Get current log level
|
|
626
|
-
*/
|
|
627
|
-
get level() {
|
|
628
|
-
return this.config.level;
|
|
629
|
-
}
|
|
630
|
-
/**
|
|
631
|
-
* Create child logger (per module)
|
|
632
|
-
*/
|
|
633
|
-
child(module) {
|
|
634
|
-
return new _Logger({
|
|
635
|
-
...this.config,
|
|
636
|
-
module
|
|
637
|
-
});
|
|
638
|
-
}
|
|
639
|
-
/**
|
|
640
|
-
* Common log method with error/context detection
|
|
641
|
-
*/
|
|
642
|
-
logWithLevel(level, message, errorOrContext, context) {
|
|
643
|
-
if (errorOrContext !== void 0 && FORMAT_PATTERN.test(message)) {
|
|
644
|
-
this.log(level, format(message, errorOrContext), void 0, context);
|
|
645
|
-
return;
|
|
646
|
-
}
|
|
647
|
-
if (errorOrContext instanceof Error) {
|
|
648
|
-
this.log(level, message, errorOrContext, context);
|
|
649
|
-
} else if (errorOrContext !== void 0 && typeof errorOrContext === "object" && !this.isContext(errorOrContext)) {
|
|
650
|
-
this.log(level, message, this.toError(errorOrContext), context);
|
|
651
|
-
} else if (typeof errorOrContext === "string" || typeof errorOrContext === "number" || typeof errorOrContext === "boolean") {
|
|
652
|
-
this.log(level, message, this.toError(errorOrContext), context);
|
|
653
|
-
} else {
|
|
654
|
-
this.log(level, message, void 0, errorOrContext);
|
|
655
|
-
}
|
|
656
|
-
}
|
|
657
|
-
debug(message, errorOrContext, context) {
|
|
658
|
-
this.logWithLevel("debug", message, errorOrContext, context);
|
|
659
|
-
}
|
|
660
|
-
info(message, errorOrContext, context) {
|
|
661
|
-
this.logWithLevel("info", message, errorOrContext, context);
|
|
662
|
-
}
|
|
663
|
-
warn(message, errorOrContext, context) {
|
|
664
|
-
this.logWithLevel("warn", message, errorOrContext, context);
|
|
665
|
-
}
|
|
666
|
-
error(message, errorOrContext, context) {
|
|
667
|
-
this.logWithLevel("error", message, errorOrContext, context);
|
|
668
|
-
}
|
|
669
|
-
fatal(message, errorOrContext, context) {
|
|
670
|
-
this.logWithLevel("fatal", message, errorOrContext, context);
|
|
671
|
-
}
|
|
672
|
-
/**
|
|
673
|
-
* Log processing (internal)
|
|
674
|
-
*/
|
|
675
|
-
log(level, message, error, context) {
|
|
676
|
-
if (LOG_LEVEL_PRIORITY[level] < LOG_LEVEL_PRIORITY[this.config.level]) {
|
|
677
|
-
return;
|
|
678
|
-
}
|
|
679
|
-
const metadata = {
|
|
680
|
-
timestamp: /* @__PURE__ */ new Date(),
|
|
681
|
-
level,
|
|
682
|
-
message,
|
|
683
|
-
module: this.module,
|
|
684
|
-
error,
|
|
685
|
-
// Mask sensitive information in context to prevent credential leaks
|
|
686
|
-
context: context ? maskSensitiveData(context) : void 0
|
|
687
|
-
};
|
|
688
|
-
this.processTransports(metadata);
|
|
689
|
-
}
|
|
690
|
-
/**
|
|
691
|
-
* Process Transports
|
|
692
|
-
*/
|
|
693
|
-
processTransports(metadata) {
|
|
694
|
-
const promises = this.config.transports.filter((transport) => transport.enabled).map((transport) => this.safeTransportLog(transport, metadata));
|
|
695
|
-
Promise.all(promises).catch((error) => {
|
|
696
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
697
|
-
process.stderr.write(`[Logger] Transport error: ${errorMessage}
|
|
698
|
-
`);
|
|
699
|
-
});
|
|
700
|
-
}
|
|
701
|
-
/**
|
|
702
|
-
* Transport log (error-safe)
|
|
703
|
-
*/
|
|
704
|
-
async safeTransportLog(transport, metadata) {
|
|
705
|
-
try {
|
|
706
|
-
await transport.log(metadata);
|
|
707
|
-
} catch (error) {
|
|
708
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
709
|
-
process.stderr.write(`[Logger] Transport "${transport.name}" failed: ${errorMessage}
|
|
710
|
-
`);
|
|
711
|
-
}
|
|
712
|
-
}
|
|
713
|
-
/**
|
|
714
|
-
* Close all Transports
|
|
715
|
-
*/
|
|
716
|
-
async close() {
|
|
717
|
-
const closePromises = this.config.transports.filter((transport) => transport.close).map((transport) => transport.close());
|
|
718
|
-
await Promise.all(closePromises);
|
|
719
|
-
}
|
|
720
|
-
};
|
|
721
|
-
|
|
722
|
-
// src/logger/transports/console.ts
|
|
723
|
-
var ConsoleTransport = class {
|
|
724
|
-
name = "console";
|
|
725
|
-
level;
|
|
726
|
-
enabled;
|
|
727
|
-
colorize;
|
|
728
|
-
constructor(config) {
|
|
729
|
-
this.level = config.level;
|
|
730
|
-
this.enabled = config.enabled;
|
|
731
|
-
this.colorize = config.colorize ?? true;
|
|
732
|
-
}
|
|
733
|
-
async log(metadata) {
|
|
734
|
-
if (!this.enabled) {
|
|
735
|
-
return;
|
|
736
|
-
}
|
|
737
|
-
if (LOG_LEVEL_PRIORITY[metadata.level] < LOG_LEVEL_PRIORITY[this.level]) {
|
|
738
|
-
return;
|
|
739
|
-
}
|
|
740
|
-
const message = formatConsole(metadata, this.colorize);
|
|
741
|
-
if (metadata.level === "warn" || metadata.level === "error" || metadata.level === "fatal") {
|
|
742
|
-
console.error(message);
|
|
743
|
-
} else {
|
|
744
|
-
console.log(message);
|
|
745
|
-
}
|
|
746
|
-
}
|
|
747
|
-
};
|
|
748
|
-
|
|
749
|
-
// src/logger/config.ts
|
|
750
|
-
function getConsoleConfig() {
|
|
751
|
-
const isProduction = process.env.NODE_ENV === "production";
|
|
752
|
-
return {
|
|
753
|
-
level: "debug",
|
|
754
|
-
enabled: true,
|
|
755
|
-
colorize: !isProduction
|
|
756
|
-
// Dev: colored output, Production: plain text
|
|
757
|
-
};
|
|
758
|
-
}
|
|
759
|
-
function validateEnvironment() {
|
|
760
|
-
const nodeEnv = process.env.NODE_ENV;
|
|
761
|
-
if (!nodeEnv) {
|
|
762
|
-
process.stderr.write(
|
|
763
|
-
"[Logger] Warning: NODE_ENV is not set. Defaulting to test environment.\n"
|
|
764
|
-
);
|
|
765
|
-
}
|
|
766
|
-
}
|
|
767
|
-
function validateConfig() {
|
|
768
|
-
validateEnvironment();
|
|
769
|
-
}
|
|
770
|
-
|
|
771
|
-
// src/logger/factory.ts
|
|
772
|
-
function initializeTransports() {
|
|
773
|
-
const transports = [];
|
|
774
|
-
const consoleConfig = getConsoleConfig();
|
|
775
|
-
transports.push(new ConsoleTransport(consoleConfig));
|
|
776
|
-
return transports;
|
|
777
|
-
}
|
|
778
|
-
function getLogLevel() {
|
|
779
|
-
const envLevel = process.env.SPFN_LOG_LEVEL || process.env.NEXT_PUBLIC_SPFN_LOG_LEVEL || "info";
|
|
780
|
-
if (envLevel in LOG_LEVEL_PRIORITY) {
|
|
781
|
-
return envLevel;
|
|
782
|
-
}
|
|
783
|
-
process.stderr.write(
|
|
784
|
-
`[Logger] Invalid log level "${envLevel}", defaulting to "info"
|
|
785
|
-
`
|
|
786
|
-
);
|
|
787
|
-
return "info";
|
|
788
|
-
}
|
|
789
|
-
function initializeLogger() {
|
|
790
|
-
validateConfig();
|
|
791
|
-
return new Logger({
|
|
792
|
-
level: getLogLevel(),
|
|
793
|
-
transports: initializeTransports()
|
|
794
|
-
});
|
|
795
|
-
}
|
|
796
|
-
var logger4 = initializeLogger();
|
|
797
|
-
|
|
798
|
-
// src/errors/serializable-error.ts
|
|
799
454
|
var RESERVED_RESPONSE_KEYS = /* @__PURE__ */ new Set(["__type", "message", "error"]);
|
|
800
455
|
var AUTHORING_ENVIRONMENTS = /* @__PURE__ */ new Set(["local", "development", "test"]);
|
|
801
456
|
function refuseReservedKey(className, key) {
|
|
@@ -803,7 +458,7 @@ function refuseReservedKey(className, key) {
|
|
|
803
458
|
if (AUTHORING_ENVIRONMENTS.has(process.env.NODE_ENV ?? "local")) {
|
|
804
459
|
throw new Error(detail);
|
|
805
460
|
}
|
|
806
|
-
|
|
461
|
+
logger.error(`[SerializableError] ${detail} The field is omitted from the response.`);
|
|
807
462
|
}
|
|
808
463
|
var SerializableError2 = class extends Error {
|
|
809
464
|
/**
|
|
@@ -1207,7 +862,7 @@ var MemoryRateLimitStore = class {
|
|
|
1207
862
|
};
|
|
1208
863
|
|
|
1209
864
|
// src/middleware/rate-limit.ts
|
|
1210
|
-
var rateLimitLogger =
|
|
865
|
+
var rateLimitLogger = logger.child("@spfn/core:rate-limit");
|
|
1211
866
|
var memoryStore = new MemoryRateLimitStore();
|
|
1212
867
|
function resetMemoryRateLimitStore() {
|
|
1213
868
|
memoryStore.clear();
|
|
@@ -1335,7 +990,7 @@ function generateRequestId() {
|
|
|
1335
990
|
const randomPart = randomBytes(6).toString("hex");
|
|
1336
991
|
return `req_${timestamp}_${randomPart}`;
|
|
1337
992
|
}
|
|
1338
|
-
function
|
|
993
|
+
function maskSensitiveData(obj, sensitiveFields, seen = /* @__PURE__ */ new WeakSet()) {
|
|
1339
994
|
if (!obj || typeof obj !== "object") return obj;
|
|
1340
995
|
if (seen.has(obj)) return "[Circular]";
|
|
1341
996
|
seen.add(obj);
|
|
@@ -1346,7 +1001,7 @@ function maskSensitiveData2(obj, sensitiveFields, seen = /* @__PURE__ */ new Wea
|
|
|
1346
1001
|
if (lowerFields.some((field) => lowerKey.includes(field))) {
|
|
1347
1002
|
masked[key] = "***MASKED***";
|
|
1348
1003
|
} else if (typeof masked[key] === "object" && masked[key] !== null) {
|
|
1349
|
-
masked[key] =
|
|
1004
|
+
masked[key] = maskSensitiveData(masked[key], sensitiveFields, seen);
|
|
1350
1005
|
}
|
|
1351
1006
|
}
|
|
1352
1007
|
return masked;
|
|
@@ -1398,7 +1053,7 @@ function RequestLogger(options) {
|
|
|
1398
1053
|
if (["POST", "PUT", "PATCH"].includes(method)) {
|
|
1399
1054
|
try {
|
|
1400
1055
|
const requestBody = await c.req.json();
|
|
1401
|
-
logData.request =
|
|
1056
|
+
logData.request = maskSensitiveData(requestBody, cfg.sensitiveFields);
|
|
1402
1057
|
} catch {
|
|
1403
1058
|
}
|
|
1404
1059
|
}
|
|
@@ -1601,6 +1256,6 @@ function reject(c, mode, next, reason) {
|
|
|
1601
1256
|
return next();
|
|
1602
1257
|
}
|
|
1603
1258
|
|
|
1604
|
-
export { CacheRateLimitStore, ErrorHandler, MemoryRateLimitStore, RequestLogger, createCacheNonceStore, createInMemoryNonceStore, createProxyGuard, getClientIp, getRateLimitPolicy,
|
|
1259
|
+
export { CacheRateLimitStore, ErrorHandler, MemoryRateLimitStore, RequestLogger, createCacheNonceStore, createInMemoryNonceStore, createProxyGuard, getClientIp, getRateLimitPolicy, maskSensitiveData, rateLimit, rateLimitPolicy, resetMemoryRateLimitStore, setRateLimitFailClosedDefault, setRateLimitPolicies };
|
|
1605
1260
|
//# sourceMappingURL=index.js.map
|
|
1606
1261
|
//# sourceMappingURL=index.js.map
|