@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.
Files changed (104) hide show
  1. package/README.md +304 -12
  2. package/dist/app-config/index.d.ts +39 -1
  3. package/dist/app-config/index.js.map +1 -1
  4. package/dist/authz/index.js +47 -391
  5. package/dist/authz/index.js.map +1 -1
  6. package/dist/{boss-D16fO2oG.d.ts → boss-BiDCbbAQ.d.ts} +60 -7
  7. package/dist/codegen/index.d.ts +157 -16
  8. package/dist/codegen/index.js +772 -166
  9. package/dist/codegen/index.js.map +1 -1
  10. package/dist/config/index.js +4 -4
  11. package/dist/config/index.js.map +1 -1
  12. package/dist/contract/index.d.ts +39 -16
  13. package/dist/contract/index.js +147 -23
  14. package/dist/contract/index.js.map +1 -1
  15. package/dist/db/index.d.ts +230 -35
  16. package/dist/db/index.js +316 -160
  17. package/dist/db/index.js.map +1 -1
  18. package/dist/env/index.d.ts +6 -442
  19. package/dist/env/index.js +13 -16
  20. package/dist/env/index.js.map +1 -1
  21. package/dist/env/loader.js +24 -1
  22. package/dist/env/loader.js.map +1 -1
  23. package/dist/error-CIZlYJlL.d.ts +157 -0
  24. package/dist/errors/index.d.ts +18 -1
  25. package/dist/errors/index.js +47 -391
  26. package/dist/errors/index.js.map +1 -1
  27. package/dist/event/index.d.ts +5 -5
  28. package/dist/event/index.js +202 -3
  29. package/dist/event/index.js.map +1 -1
  30. package/dist/event/sse/client.d.ts +18 -4
  31. package/dist/event/sse/client.js +94 -18
  32. package/dist/event/sse/client.js.map +1 -1
  33. package/dist/event/sse/index.d.ts +18 -5
  34. package/dist/event/sse/index.js +452 -114
  35. package/dist/event/sse/index.js.map +1 -1
  36. package/dist/event/ws/client.d.ts +3 -2
  37. package/dist/event/ws/index.d.ts +4 -3
  38. package/dist/job/index.d.ts +48 -3
  39. package/dist/job/index.js +131 -52
  40. package/dist/job/index.js.map +1 -1
  41. package/dist/logger/index.js +0 -12
  42. package/dist/logger/index.js.map +1 -1
  43. package/dist/middleware/index.js +52 -397
  44. package/dist/middleware/index.js.map +1 -1
  45. package/dist/nextjs/index.d.ts +75 -14
  46. package/dist/nextjs/index.js +200 -84
  47. package/dist/nextjs/index.js.map +1 -1
  48. package/dist/nextjs/server.d.ts +46 -8
  49. package/dist/nextjs/server.js +15 -1
  50. package/dist/nextjs/server.js.map +1 -1
  51. package/dist/ops/index.d.ts +61 -42
  52. package/dist/ops/index.js +648 -97
  53. package/dist/ops/index.js.map +1 -1
  54. package/dist/registry-C2KQCh0m.d.ts +473 -0
  55. package/dist/route/index.d.ts +5 -2
  56. package/dist/route/index.js +107 -28
  57. package/dist/route/index.js.map +1 -1
  58. package/dist/route/types.d.ts +7 -1
  59. package/dist/{router-Cy7rAfmj.d.ts → route-builder-DRW-MSCJ.d.ts} +51 -126
  60. package/dist/router-C57y-vz1.d.ts +184 -0
  61. package/dist/router-CX5uVjmU.d.ts +406 -0
  62. package/dist/server/index.d.ts +130 -7
  63. package/dist/server/index.js +1174 -164
  64. package/dist/server/index.js.map +1 -1
  65. package/dist/state/client.d.ts +206 -0
  66. package/dist/state/client.js +678 -0
  67. package/dist/state/client.js.map +1 -0
  68. package/dist/state/index.d.ts +443 -0
  69. package/dist/state/index.js +644 -0
  70. package/dist/state/index.js.map +1 -0
  71. package/dist/state/react.d.ts +49 -0
  72. package/dist/state/react.js +50 -0
  73. package/dist/state/react.js.map +1 -0
  74. package/dist/surface/index.d.ts +115 -0
  75. package/dist/surface/index.js +1013 -0
  76. package/dist/surface/index.js.map +1 -0
  77. package/dist/token-manager-Ckjt2-qq.d.ts +122 -0
  78. package/dist/{types-CfYVhIQ9.d.ts → types-5Rl11_Nb.d.ts} +43 -4
  79. package/dist/types-CKH0D3Dy.d.ts +441 -0
  80. package/dist/{types-ZQODsBft.d.ts → types-CurMab2Q.d.ts} +52 -2
  81. package/dist/{types-2AbaW4Ie.d.ts → types-DncqXfWN.d.ts} +4 -3
  82. package/docs/file-upload.md +195 -333
  83. package/package.json +41 -11
  84. package/src/cache/README.md +330 -0
  85. package/src/codegen/README.md +721 -0
  86. package/src/config/README.md +333 -0
  87. package/src/contract/README.md +442 -0
  88. package/src/db/README.md +589 -0
  89. package/src/db/manager/README.md +500 -0
  90. package/src/db/schema/README.md +354 -0
  91. package/src/db/transaction/README.md +845 -0
  92. package/src/env/README.md +787 -0
  93. package/src/errors/README.md +445 -0
  94. package/src/event/README.md +994 -0
  95. package/src/job/README.md +613 -0
  96. package/src/logger/README.md +321 -0
  97. package/src/middleware/README.md +634 -0
  98. package/src/nextjs/README.md +756 -0
  99. package/src/route/README.md +763 -0
  100. package/src/security/README.md +100 -0
  101. package/src/server/README.md +704 -0
  102. package/src/state/README.md +806 -0
  103. package/dist/token-manager-BT5EnUAR.d.ts +0 -278
  104. package/dist/types-9oszaJqp.d.ts +0 -250
@@ -1,8 +1,27 @@
1
- import { format } from 'util';
1
+ import { logger } from '@spfn/core/logger';
2
2
 
3
3
  // src/errors/error-registry.ts
4
+ function probeName(ErrorClass) {
5
+ try {
6
+ return new ErrorClass({}).name;
7
+ } catch {
8
+ return void 0;
9
+ }
10
+ }
11
+ function ownInstanceName(ErrorClass) {
12
+ const name = probeName(ErrorClass);
13
+ const Parent = Object.getPrototypeOf(ErrorClass);
14
+ return name !== void 0 && name !== probeName(Parent) ? name : void 0;
15
+ }
4
16
  var ErrorRegistry = class _ErrorRegistry {
5
17
  errors = /* @__PURE__ */ new Map();
18
+ /**
19
+ * The same classes keyed by the name their instances set for themselves.
20
+ * Consulted only when no class is registered under the constructor name, so
21
+ * an unminified registry resolves exactly as before and a minified one —
22
+ * whose constructor names are `Q`, `eA`, … — still resolves `__type`.
23
+ */
24
+ instanceNames = /* @__PURE__ */ new Map();
6
25
  constructor(initialErrors) {
7
26
  if (initialErrors) {
8
27
  for (const input of initialErrors) {
@@ -23,15 +42,22 @@ var ErrorRegistry = class _ErrorRegistry {
23
42
  * @returns This registry for chaining
24
43
  */
25
44
  append(input) {
26
- if (Array.isArray(input)) {
27
- for (const ErrorClass of input) {
28
- this.errors.set(ErrorClass.name, ErrorClass);
29
- }
30
- } else {
31
- this.errors.set(input.name, input);
45
+ for (const ErrorClass of Array.isArray(input) ? input : [input]) {
46
+ this.register(ErrorClass);
32
47
  }
33
48
  return this;
34
49
  }
50
+ /**
51
+ * Key `ErrorClass` by its constructor name and, when its instances set one of
52
+ * their own, by that name too.
53
+ */
54
+ register(ErrorClass) {
55
+ this.errors.set(ErrorClass.name, ErrorClass);
56
+ const name = ownInstanceName(ErrorClass);
57
+ if (name !== void 0) {
58
+ this.instanceNames.set(name, ErrorClass);
59
+ }
60
+ }
35
61
  /**
36
62
  * Concatenate another ErrorRegistry into this one
37
63
  *
@@ -42,15 +68,25 @@ var ErrorRegistry = class _ErrorRegistry {
42
68
  for (const [name, ErrorClass] of registry.errors) {
43
69
  this.errors.set(name, ErrorClass);
44
70
  }
71
+ for (const [name, ErrorClass] of registry.instanceNames) {
72
+ this.instanceNames.set(name, ErrorClass);
73
+ }
45
74
  return this;
46
75
  }
76
+ /**
77
+ * The class registered for `type`: by constructor name first, then by the
78
+ * name its instances carry.
79
+ */
80
+ find(type) {
81
+ return this.errors.get(type) ?? this.instanceNames.get(type);
82
+ }
47
83
  /**
48
84
  * Check if error type is registered
49
85
  *
50
- * @param name - Error class name
86
+ * @param name - Error class name, or the name its instances carry
51
87
  */
52
88
  has(name) {
53
- return this.errors.has(name);
89
+ return this.find(name) !== void 0;
54
90
  }
55
91
  /**
56
92
  * Deserialize error from JSON data
@@ -60,7 +96,7 @@ var ErrorRegistry = class _ErrorRegistry {
60
96
  * @throws Error if error type is not registered
61
97
  */
62
98
  deserialize(data) {
63
- const ErrorClass = this.errors.get(data.__type);
99
+ const ErrorClass = this.find(data.__type);
64
100
  if (!ErrorClass) {
65
101
  throw new Error(`Unknown error type: ${data.__type}`);
66
102
  }
@@ -87,389 +123,9 @@ var ErrorRegistry = class _ErrorRegistry {
87
123
  * Get all registered error types
88
124
  */
89
125
  getRegisteredTypes() {
90
- return Array.from(this.errors.keys());
91
- }
92
- };
93
-
94
- // src/logger/types.ts
95
- var LOG_LEVEL_PRIORITY = {
96
- debug: 0,
97
- info: 1,
98
- warn: 2,
99
- error: 3,
100
- fatal: 4
101
- };
102
-
103
- // src/logger/formatters.ts
104
- var SENSITIVE_KEYS = [
105
- "password",
106
- "passwd",
107
- "pwd",
108
- "secret",
109
- "token",
110
- "apikey",
111
- "api_key",
112
- "accesstoken",
113
- "access_token",
114
- "refreshtoken",
115
- "refresh_token",
116
- "authorization",
117
- "auth",
118
- "cookie",
119
- "session",
120
- "sessionid",
121
- "session_id",
122
- "privatekey",
123
- "private_key",
124
- "creditcard",
125
- "credit_card",
126
- "cardnumber",
127
- "card_number",
128
- "cvv",
129
- "ssn",
130
- "pin"
131
- ];
132
- var MASKED_VALUE = "***MASKED***";
133
- function isSensitiveKey(key) {
134
- const lowerKey = key.toLowerCase();
135
- return SENSITIVE_KEYS.some((sensitive) => lowerKey.includes(sensitive));
136
- }
137
- function maskSensitiveData(data, seen = /* @__PURE__ */ new WeakSet()) {
138
- if (data === null || data === void 0) {
139
- return data;
140
- }
141
- if (typeof data !== "object") {
142
- return data;
143
- }
144
- if (seen.has(data)) {
145
- return "[Circular]";
146
- }
147
- seen.add(data);
148
- if (Array.isArray(data)) {
149
- return data.map((item) => maskSensitiveData(item, seen));
150
- }
151
- const masked = {};
152
- for (const [key, value] of Object.entries(data)) {
153
- if (isSensitiveKey(key)) {
154
- masked[key] = MASKED_VALUE;
155
- } else if (typeof value === "object" && value !== null) {
156
- masked[key] = maskSensitiveData(value, seen);
157
- } else {
158
- masked[key] = value;
159
- }
126
+ return [.../* @__PURE__ */ new Set([...this.errors.keys(), ...this.instanceNames.keys()])];
160
127
  }
161
- return masked;
162
- }
163
- var COLORS = {
164
- reset: "\x1B[0m",
165
- bright: "\x1B[1m",
166
- dim: "\x1B[2m",
167
- // 로그 레벨 컬러
168
- debug: "\x1B[36m",
169
- // cyan
170
- info: "\x1B[32m",
171
- // green
172
- warn: "\x1B[33m",
173
- // yellow
174
- error: "\x1B[31m",
175
- // red
176
- fatal: "\x1B[35m",
177
- // magenta
178
- // 추가 컬러
179
- gray: "\x1B[90m"
180
128
  };
181
- function formatTimestampHuman(date) {
182
- const year = date.getFullYear();
183
- const month = String(date.getMonth() + 1).padStart(2, "0");
184
- const day = String(date.getDate()).padStart(2, "0");
185
- const hours = String(date.getHours()).padStart(2, "0");
186
- const minutes = String(date.getMinutes()).padStart(2, "0");
187
- const seconds = String(date.getSeconds()).padStart(2, "0");
188
- const ms = String(date.getMilliseconds()).padStart(3, "0");
189
- return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}.${ms}`;
190
- }
191
- function formatError(error) {
192
- const lines = [];
193
- lines.push(`${error.name}: ${error.message}`);
194
- if (error.stack) {
195
- const stackLines = error.stack.split("\n").slice(1);
196
- lines.push(...stackLines);
197
- }
198
- if (error.cause instanceof Error) {
199
- lines.push(`Caused by: ${formatError(error.cause)}`);
200
- } else if (error.cause !== void 0) {
201
- lines.push(`Caused by: ${String(error.cause)}`);
202
- }
203
- return lines.join("\n");
204
- }
205
- function formatConsole(metadata, colorize = true) {
206
- const parts = [];
207
- const timestamp = formatTimestampHuman(metadata.timestamp);
208
- if (colorize) {
209
- parts.push(`${COLORS.gray}[${timestamp}]${COLORS.reset}`);
210
- } else {
211
- parts.push(`[${timestamp}]`);
212
- }
213
- const pid = process.pid;
214
- if (colorize) {
215
- parts.push(`${COLORS.dim}[pid=${pid}]${COLORS.reset}`);
216
- } else {
217
- parts.push(`[pid=${pid}]`);
218
- }
219
- if (metadata.module) {
220
- if (colorize) {
221
- parts.push(`${COLORS.dim}[module=${metadata.module}]${COLORS.reset}`);
222
- } else {
223
- parts.push(`[module=${metadata.module}]`);
224
- }
225
- }
226
- if (metadata.context && Object.keys(metadata.context).length > 0) {
227
- Object.entries(metadata.context).forEach(([key, value]) => {
228
- let valueStr;
229
- if (typeof value === "string") {
230
- valueStr = value;
231
- } else if (typeof value === "object" && value !== null) {
232
- try {
233
- valueStr = JSON.stringify(value);
234
- } catch (error) {
235
- valueStr = "[circular]";
236
- }
237
- } else {
238
- valueStr = String(value);
239
- }
240
- if (colorize) {
241
- parts.push(`${COLORS.dim}[${key}=${valueStr}]${COLORS.reset}`);
242
- } else {
243
- parts.push(`[${key}=${valueStr}]`);
244
- }
245
- });
246
- }
247
- const levelStr = metadata.level.toUpperCase();
248
- if (colorize) {
249
- const color = COLORS[metadata.level];
250
- parts.push(`${color}(${levelStr})${COLORS.reset}:`);
251
- } else {
252
- parts.push(`(${levelStr}):`);
253
- }
254
- if (colorize) {
255
- parts.push(`${COLORS.bright}${metadata.message}${COLORS.reset}`);
256
- } else {
257
- parts.push(metadata.message);
258
- }
259
- let output = parts.join(" ");
260
- if (metadata.error) {
261
- output += "\n" + formatError(metadata.error);
262
- }
263
- return output;
264
- }
265
-
266
- // src/logger/logger.ts
267
- var FORMAT_PATTERN = /%[sdifjoOc%]/;
268
- var Logger = class _Logger {
269
- config;
270
- module;
271
- constructor(config) {
272
- this.config = config;
273
- this.module = config.module;
274
- }
275
- /**
276
- * Convert unknown error to Error object
277
- */
278
- toError(error) {
279
- if (error instanceof Error) return error;
280
- if (typeof error === "string") return new Error(error);
281
- if (typeof error === "object" && error !== null) {
282
- return new Error(JSON.stringify(error));
283
- }
284
- return new Error(String(error));
285
- }
286
- /**
287
- * Check if value is a context object (not an error)
288
- */
289
- isContext(value) {
290
- if (typeof value !== "object" || value === null) return false;
291
- if (value instanceof Error) return false;
292
- const hasStack = "stack" in value && typeof value.stack === "string";
293
- if (hasStack) {
294
- return false;
295
- }
296
- return true;
297
- }
298
- /**
299
- * Get current log level
300
- */
301
- get level() {
302
- return this.config.level;
303
- }
304
- /**
305
- * Create child logger (per module)
306
- */
307
- child(module) {
308
- return new _Logger({
309
- ...this.config,
310
- module
311
- });
312
- }
313
- /**
314
- * Common log method with error/context detection
315
- */
316
- logWithLevel(level, message, errorOrContext, context) {
317
- if (errorOrContext !== void 0 && FORMAT_PATTERN.test(message)) {
318
- this.log(level, format(message, errorOrContext), void 0, context);
319
- return;
320
- }
321
- if (errorOrContext instanceof Error) {
322
- this.log(level, message, errorOrContext, context);
323
- } else if (errorOrContext !== void 0 && typeof errorOrContext === "object" && !this.isContext(errorOrContext)) {
324
- this.log(level, message, this.toError(errorOrContext), context);
325
- } else if (typeof errorOrContext === "string" || typeof errorOrContext === "number" || typeof errorOrContext === "boolean") {
326
- this.log(level, message, this.toError(errorOrContext), context);
327
- } else {
328
- this.log(level, message, void 0, errorOrContext);
329
- }
330
- }
331
- debug(message, errorOrContext, context) {
332
- this.logWithLevel("debug", message, errorOrContext, context);
333
- }
334
- info(message, errorOrContext, context) {
335
- this.logWithLevel("info", message, errorOrContext, context);
336
- }
337
- warn(message, errorOrContext, context) {
338
- this.logWithLevel("warn", message, errorOrContext, context);
339
- }
340
- error(message, errorOrContext, context) {
341
- this.logWithLevel("error", message, errorOrContext, context);
342
- }
343
- fatal(message, errorOrContext, context) {
344
- this.logWithLevel("fatal", message, errorOrContext, context);
345
- }
346
- /**
347
- * Log processing (internal)
348
- */
349
- log(level, message, error, context) {
350
- if (LOG_LEVEL_PRIORITY[level] < LOG_LEVEL_PRIORITY[this.config.level]) {
351
- return;
352
- }
353
- const metadata = {
354
- timestamp: /* @__PURE__ */ new Date(),
355
- level,
356
- message,
357
- module: this.module,
358
- error,
359
- // Mask sensitive information in context to prevent credential leaks
360
- context: context ? maskSensitiveData(context) : void 0
361
- };
362
- this.processTransports(metadata);
363
- }
364
- /**
365
- * Process Transports
366
- */
367
- processTransports(metadata) {
368
- const promises = this.config.transports.filter((transport) => transport.enabled).map((transport) => this.safeTransportLog(transport, metadata));
369
- Promise.all(promises).catch((error) => {
370
- const errorMessage = error instanceof Error ? error.message : String(error);
371
- process.stderr.write(`[Logger] Transport error: ${errorMessage}
372
- `);
373
- });
374
- }
375
- /**
376
- * Transport log (error-safe)
377
- */
378
- async safeTransportLog(transport, metadata) {
379
- try {
380
- await transport.log(metadata);
381
- } catch (error) {
382
- const errorMessage = error instanceof Error ? error.message : String(error);
383
- process.stderr.write(`[Logger] Transport "${transport.name}" failed: ${errorMessage}
384
- `);
385
- }
386
- }
387
- /**
388
- * Close all Transports
389
- */
390
- async close() {
391
- const closePromises = this.config.transports.filter((transport) => transport.close).map((transport) => transport.close());
392
- await Promise.all(closePromises);
393
- }
394
- };
395
-
396
- // src/logger/transports/console.ts
397
- var ConsoleTransport = class {
398
- name = "console";
399
- level;
400
- enabled;
401
- colorize;
402
- constructor(config) {
403
- this.level = config.level;
404
- this.enabled = config.enabled;
405
- this.colorize = config.colorize ?? true;
406
- }
407
- async log(metadata) {
408
- if (!this.enabled) {
409
- return;
410
- }
411
- if (LOG_LEVEL_PRIORITY[metadata.level] < LOG_LEVEL_PRIORITY[this.level]) {
412
- return;
413
- }
414
- const message = formatConsole(metadata, this.colorize);
415
- if (metadata.level === "warn" || metadata.level === "error" || metadata.level === "fatal") {
416
- console.error(message);
417
- } else {
418
- console.log(message);
419
- }
420
- }
421
- };
422
-
423
- // src/logger/config.ts
424
- function getConsoleConfig() {
425
- const isProduction = process.env.NODE_ENV === "production";
426
- return {
427
- level: "debug",
428
- enabled: true,
429
- colorize: !isProduction
430
- // Dev: colored output, Production: plain text
431
- };
432
- }
433
- function validateEnvironment() {
434
- const nodeEnv = process.env.NODE_ENV;
435
- if (!nodeEnv) {
436
- process.stderr.write(
437
- "[Logger] Warning: NODE_ENV is not set. Defaulting to test environment.\n"
438
- );
439
- }
440
- }
441
- function validateConfig() {
442
- validateEnvironment();
443
- }
444
-
445
- // src/logger/factory.ts
446
- function initializeTransports() {
447
- const transports = [];
448
- const consoleConfig = getConsoleConfig();
449
- transports.push(new ConsoleTransport(consoleConfig));
450
- return transports;
451
- }
452
- function getLogLevel() {
453
- const envLevel = process.env.SPFN_LOG_LEVEL || process.env.NEXT_PUBLIC_SPFN_LOG_LEVEL || "info";
454
- if (envLevel in LOG_LEVEL_PRIORITY) {
455
- return envLevel;
456
- }
457
- process.stderr.write(
458
- `[Logger] Invalid log level "${envLevel}", defaulting to "info"
459
- `
460
- );
461
- return "info";
462
- }
463
- function initializeLogger() {
464
- validateConfig();
465
- return new Logger({
466
- level: getLogLevel(),
467
- transports: initializeTransports()
468
- });
469
- }
470
- var logger = initializeLogger();
471
-
472
- // src/errors/serializable-error.ts
473
129
  var RESERVED_RESPONSE_KEYS = /* @__PURE__ */ new Set(["__type", "message", "error"]);
474
130
  var AUTHORING_ENVIRONMENTS = /* @__PURE__ */ new Set(["local", "development", "test"]);
475
131
  function refuseReservedKey(className, key) {