target-supabase-sdk 0.1.9 → 0.2.0
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 +66 -0
- package/dist/browser.d.ts +52 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +45 -0
- package/dist/browser.js.map +1 -0
- package/dist/command/command.api.js +5 -5
- package/dist/command/command.api.js.map +1 -1
- package/dist/index.d.ts +2 -48
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -41
- package/dist/index.js.map +1 -1
- package/dist/link/link.interface.d.ts +1 -1
- package/dist/link/link.interface.d.ts.map +1 -1
- package/dist/node/node-log-scope.d.ts +11 -0
- package/dist/node/node-log-scope.d.ts.map +1 -0
- package/dist/node/node-log-scope.js +7 -0
- package/dist/node/node-log-scope.js.map +1 -0
- package/dist/node/node-runtime.base.d.ts +42 -0
- package/dist/node/node-runtime.base.d.ts.map +1 -0
- package/dist/node/node-runtime.base.js +397 -0
- package/dist/node/node-runtime.base.js.map +1 -0
- package/dist/node/node.api.d.ts +3 -3
- package/dist/node/node.api.js +3 -3
- package/dist/node/node.api.js.map +1 -1
- package/dist/node/task-node.d.ts +20 -0
- package/dist/node/task-node.d.ts.map +1 -0
- package/dist/node/task-node.js +245 -0
- package/dist/node/task-node.js.map +1 -0
- package/dist/node/trigger-node.d.ts +18 -0
- package/dist/node/trigger-node.d.ts.map +1 -0
- package/dist/node/trigger-node.js +150 -0
- package/dist/node/trigger-node.js.map +1 -0
- package/dist/node.d.ts +22 -0
- package/dist/node.d.ts.map +1 -0
- package/dist/node.js +19 -0
- package/dist/node.js.map +1 -0
- package/dist/repo/repo-manager.d.ts +14 -3
- package/dist/repo/repo-manager.d.ts.map +1 -1
- package/dist/repo/repo-manager.js +27 -17
- package/dist/repo/repo-manager.js.map +1 -1
- package/dist/repo/repo.script-loader.d.ts +3 -3
- package/dist/repo/repo.script-loader.d.ts.map +1 -1
- package/dist/repo/repo.script-loader.js +10 -10
- package/dist/repo/repo.script-loader.js.map +1 -1
- package/dist/shared/log/create-api-logger.d.ts +10 -6
- package/dist/shared/log/create-api-logger.d.ts.map +1 -1
- package/dist/shared/log/create-api-logger.js +10 -6
- package/dist/shared/log/create-api-logger.js.map +1 -1
- package/dist/shared/log/index.d.ts +10 -0
- package/dist/shared/log/index.d.ts.map +1 -0
- package/dist/shared/log/index.js +10 -0
- package/dist/shared/log/index.js.map +1 -0
- package/dist/shared/log/log-manager.d.ts +25 -46
- package/dist/shared/log/log-manager.d.ts.map +1 -1
- package/dist/shared/log/log-manager.js +59 -40
- package/dist/shared/log/log-manager.js.map +1 -1
- package/dist/shared/log/log-scope.d.ts +49 -0
- package/dist/shared/log/log-scope.d.ts.map +1 -0
- package/dist/shared/log/log-scope.js +70 -0
- package/dist/shared/log/log-scope.js.map +1 -0
- package/dist/task/index.d.ts +15 -0
- package/dist/task/index.d.ts.map +1 -0
- package/dist/task/index.js +14 -0
- package/dist/task/index.js.map +1 -0
- package/dist/task/local-task-registry.d.ts +10 -0
- package/dist/task/local-task-registry.d.ts.map +1 -1
- package/dist/task/local-task-registry.js +83 -22
- package/dist/task/local-task-registry.js.map +1 -1
- package/dist/task/task-manager.d.ts +18 -6
- package/dist/task/task-manager.d.ts.map +1 -1
- package/dist/task/task-manager.js +46 -67
- package/dist/task/task-manager.js.map +1 -1
- package/dist/task/task-post.api.d.ts +49 -0
- package/dist/task/task-post.api.d.ts.map +1 -0
- package/dist/task/task-post.api.js +91 -0
- package/dist/task/task-post.api.js.map +1 -0
- package/dist/task/task-repo-context.d.ts +2 -0
- package/dist/task/task-repo-context.d.ts.map +1 -1
- package/dist/task/task-repo-context.js.map +1 -1
- package/dist/task/task-repo-validation.d.ts +46 -0
- package/dist/task/task-repo-validation.d.ts.map +1 -0
- package/dist/task/task-repo-validation.js +96 -0
- package/dist/task/task-repo-validation.js.map +1 -0
- package/dist/task/task.api.d.ts +11 -53
- package/dist/task/task.api.d.ts.map +1 -1
- package/dist/task/task.api.js +13 -61
- package/dist/task/task.api.js.map +1 -1
- package/dist/task/task.interface.d.ts +2 -0
- package/dist/task/task.interface.d.ts.map +1 -1
- package/dist/task/task.interface.js.map +1 -1
- package/dist/trigger/trigger.api.d.ts +140 -0
- package/dist/trigger/trigger.api.d.ts.map +1 -0
- package/dist/trigger/trigger.api.js +125 -0
- package/dist/trigger/trigger.api.js.map +1 -0
- package/dist/trigger/trigger.interface.d.ts +43 -0
- package/dist/trigger/trigger.interface.d.ts.map +1 -0
- package/dist/trigger/trigger.interface.js +11 -0
- package/dist/trigger/trigger.interface.js.map +1 -0
- package/dist/trigger/trigger.utils.d.ts +6 -0
- package/dist/trigger/trigger.utils.d.ts.map +1 -0
- package/dist/trigger/trigger.utils.js +39 -0
- package/dist/trigger/trigger.utils.js.map +1 -0
- package/package.json +21 -6
- package/src/browser.ts +100 -0
- package/src/command/command.api.ts +5 -5
- package/src/index.ts +2 -79
- package/src/link/link.interface.ts +1 -1
- package/src/node/node-log-scope.ts +15 -0
- package/src/node/node-runtime.base.ts +450 -0
- package/src/node/node.api.ts +3 -3
- package/src/node/task-node.ts +284 -0
- package/src/node/trigger-node.ts +180 -0
- package/src/node.ts +62 -0
- package/src/repo/repo-manager.ts +49 -21
- package/src/repo/repo.script-loader.ts +13 -13
- package/src/shared/log/create-api-logger.ts +23 -12
- package/src/shared/log/index.ts +23 -0
- package/src/shared/log/log-manager.ts +85 -90
- package/src/shared/log/log-scope.ts +123 -0
- package/src/task/index.ts +48 -0
- package/src/task/local-task-registry.ts +110 -23
- package/src/task/task-manager.ts +73 -84
- package/src/task/task-post.api.ts +116 -0
- package/src/task/task-repo-context.ts +2 -0
- package/src/task/task-repo-validation.ts +171 -0
- package/src/task/task.api.ts +13 -73
- package/src/task/task.interface.ts +2 -0
- package/src/trigger/trigger.api.ts +166 -0
- package/src/trigger/trigger.interface.ts +50 -0
- package/src/trigger/trigger.utils.ts +56 -0
- package/dist/node/node-manager.d.ts +0 -48
- package/dist/node/node-manager.d.ts.map +0 -1
- package/dist/node/node-manager.js +0 -619
- package/dist/node/node-manager.js.map +0 -1
- package/src/node/node-manager.ts +0 -673
|
@@ -3,7 +3,7 @@ import { mkdir, writeFile } from "node:fs/promises";
|
|
|
3
3
|
import { join, resolve } from "node:path";
|
|
4
4
|
import { tmpdir } from "node:os";
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import { LoggerWithScope } from "../shared/log";
|
|
7
7
|
import { resolvePathFromCwd, toFileImportHref } from "../shared/utils/config-path.utils";
|
|
8
8
|
import { TaskRepoScriptRecord } from "../task/task-repo-context";
|
|
9
9
|
import {
|
|
@@ -41,7 +41,7 @@ export async function loadRepoContextFromScript({
|
|
|
41
41
|
script,
|
|
42
42
|
taskTypeKey,
|
|
43
43
|
}: {
|
|
44
|
-
logger:
|
|
44
|
+
logger: LoggerWithScope;
|
|
45
45
|
script: TaskRepoScriptRecord;
|
|
46
46
|
taskTypeKey: string;
|
|
47
47
|
}): Promise<LoadedRepoContext | null> {
|
|
@@ -49,7 +49,7 @@ export async function loadRepoContextFromScript({
|
|
|
49
49
|
const cacheKey = `${taskTypeKey}@${loadKey}`;
|
|
50
50
|
const cached = importedModuleCache.get(cacheKey);
|
|
51
51
|
if (cached != null) {
|
|
52
|
-
logger.info("命中 Repo 脚本模块缓存", { topic: "repo",
|
|
52
|
+
logger.info("命中 Repo 脚本模块缓存", { topic: "repo", data: { cacheKey } });
|
|
53
53
|
return cached;
|
|
54
54
|
}
|
|
55
55
|
|
|
@@ -58,16 +58,16 @@ export async function loadRepoContextFromScript({
|
|
|
58
58
|
try {
|
|
59
59
|
let moduleExports: unknown;
|
|
60
60
|
if (source != null && source.trim() !== "") {
|
|
61
|
-
logger.info("从 source 动态加载 Repo 脚本", { topic: "repo",
|
|
61
|
+
logger.info("从 source 动态加载 Repo 脚本", { topic: "repo", data: { scriptId: script.id } });
|
|
62
62
|
moduleExports = await importFromSource(source, cacheKey);
|
|
63
63
|
} else if (modulePath != null && modulePath.trim() !== "") {
|
|
64
64
|
logger.info("从 modulePath 动态加载 Repo 脚本", {
|
|
65
65
|
topic: "repo",
|
|
66
|
-
|
|
66
|
+
data: { scriptId: script.id, modulePath },
|
|
67
67
|
});
|
|
68
68
|
moduleExports = await importFromFilePath(modulePath);
|
|
69
69
|
} else {
|
|
70
|
-
logger.warn("脚本缺少 source 或 modulePath", { topic: "repo",
|
|
70
|
+
logger.warn("脚本缺少 source 或 modulePath", { topic: "repo", data: { scriptId: script.id } });
|
|
71
71
|
return null;
|
|
72
72
|
}
|
|
73
73
|
|
|
@@ -75,7 +75,7 @@ export async function loadRepoContextFromScript({
|
|
|
75
75
|
if (context == null) {
|
|
76
76
|
logger.warn("脚本模块未导出合法的 TaskRepoContext", {
|
|
77
77
|
topic: "repo",
|
|
78
|
-
|
|
78
|
+
data: { scriptId: script.id, exportName: exportName ?? "default" },
|
|
79
79
|
});
|
|
80
80
|
return null;
|
|
81
81
|
}
|
|
@@ -86,7 +86,7 @@ export async function loadRepoContextFromScript({
|
|
|
86
86
|
} catch (error) {
|
|
87
87
|
logger.error("动态加载 Repo 脚本失败", {
|
|
88
88
|
topic: "repo",
|
|
89
|
-
|
|
89
|
+
data: { scriptId: script.id, error: error instanceof Error ? error.message : error },
|
|
90
90
|
});
|
|
91
91
|
return null;
|
|
92
92
|
}
|
|
@@ -98,7 +98,7 @@ export async function loadRepoContextFromUrl({
|
|
|
98
98
|
taskTypeKey,
|
|
99
99
|
exportName,
|
|
100
100
|
}: {
|
|
101
|
-
logger:
|
|
101
|
+
logger: LoggerWithScope;
|
|
102
102
|
url: string;
|
|
103
103
|
taskTypeKey: string;
|
|
104
104
|
exportName?: string;
|
|
@@ -107,18 +107,18 @@ export async function loadRepoContextFromUrl({
|
|
|
107
107
|
const cacheKey = `${taskTypeKey}@url:${href}`;
|
|
108
108
|
const cached = importedModuleCache.get(cacheKey);
|
|
109
109
|
if (cached != null) {
|
|
110
|
-
logger.info("命中 Repo URL 模块缓存", { topic: "repo",
|
|
110
|
+
logger.info("命中 Repo URL 模块缓存", { topic: "repo", data: { cacheKey } });
|
|
111
111
|
return cached;
|
|
112
112
|
}
|
|
113
113
|
|
|
114
114
|
try {
|
|
115
|
-
logger.info("从 Repo URL 动态加载脚本", { topic: "repo",
|
|
115
|
+
logger.info("从 Repo URL 动态加载脚本", { topic: "repo", data: { url, href } });
|
|
116
116
|
const moduleExports = await import(href);
|
|
117
117
|
const context = normalizeRepoContextModule(moduleExports, taskTypeKey, exportName);
|
|
118
118
|
if (context == null) {
|
|
119
119
|
logger.warn("Repo URL 模块未导出合法的 TaskRepoContext", {
|
|
120
120
|
topic: "repo",
|
|
121
|
-
|
|
121
|
+
data: { url, exportName: exportName ?? "default" },
|
|
122
122
|
});
|
|
123
123
|
return null;
|
|
124
124
|
}
|
|
@@ -128,7 +128,7 @@ export async function loadRepoContextFromUrl({
|
|
|
128
128
|
} catch (error) {
|
|
129
129
|
logger.error("从 Repo URL 动态加载失败", {
|
|
130
130
|
topic: "repo",
|
|
131
|
-
|
|
131
|
+
data: { url, error: error instanceof Error ? error.message : error },
|
|
132
132
|
});
|
|
133
133
|
return null;
|
|
134
134
|
}
|
|
@@ -1,25 +1,36 @@
|
|
|
1
|
-
import { logManager, type
|
|
1
|
+
import { logManager, type LoggerWithScope } from "./log-manager";
|
|
2
|
+
import { normalizeScope, type LogScope, type LogScopePatch } from "./log-scope";
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Options for {@link createApiLogger}.
|
|
5
6
|
*
|
|
6
|
-
* - **
|
|
7
|
-
* - **
|
|
7
|
+
* - **Trace:** optional `traceId` / `traceParentId` (generated root when traceId omitted)
|
|
8
|
+
* - **Labels:** optional `labels` (e.g. `{ nodeId }`)
|
|
8
9
|
*/
|
|
9
10
|
export type CreateApiLoggerOptions = {
|
|
10
11
|
traceId?: string;
|
|
11
|
-
|
|
12
|
+
traceParentId?: string | null;
|
|
13
|
+
labels?: Record<string, string>;
|
|
14
|
+
} & Partial<Omit<LogScope, "module" | "traceId" | "traceParentId" | "labels">>;
|
|
12
15
|
|
|
13
16
|
/**
|
|
14
17
|
* Logger for one SDK API invocation.
|
|
15
18
|
*
|
|
16
|
-
* Binds
|
|
19
|
+
* Binds `module` + normalized {@link LogScope}.
|
|
17
20
|
*/
|
|
18
|
-
export function createApiLogger(module: string, options?: CreateApiLoggerOptions):
|
|
19
|
-
const { traceId, ...
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
export function createApiLogger(module: string, options?: CreateApiLoggerOptions): LoggerWithScope {
|
|
22
|
+
const { traceId, traceParentId, labels, ...rest } = options ?? {};
|
|
23
|
+
const scope = normalizeScope(
|
|
24
|
+
{
|
|
25
|
+
module,
|
|
26
|
+
traceId,
|
|
27
|
+
traceParentId: traceParentId ?? null,
|
|
28
|
+
labels,
|
|
29
|
+
...rest,
|
|
30
|
+
},
|
|
31
|
+
{ generateTraceId: true }
|
|
32
|
+
);
|
|
33
|
+
return logManager.withScope(scope).logger;
|
|
25
34
|
}
|
|
35
|
+
|
|
36
|
+
export type { LogScopePatch };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Log domain public API — curated re-exports only.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
// log-manager
|
|
6
|
+
export { logManager, LogManager, LogLevel } from "./log-manager";
|
|
7
|
+
export type { LogEntry, LogOptions, LoggerWithScope, LogRestParams } from "./log-manager";
|
|
8
|
+
|
|
9
|
+
// create-api-logger
|
|
10
|
+
export { createApiLogger } from "./create-api-logger";
|
|
11
|
+
export type { CreateApiLoggerOptions } from "./create-api-logger";
|
|
12
|
+
|
|
13
|
+
// log-scope
|
|
14
|
+
export {
|
|
15
|
+
applyScopePatch,
|
|
16
|
+
createChildScope,
|
|
17
|
+
createRootScope,
|
|
18
|
+
formatScopeLabels,
|
|
19
|
+
normalizeScope,
|
|
20
|
+
resolveLogData,
|
|
21
|
+
withModule,
|
|
22
|
+
} from "./log-scope";
|
|
23
|
+
export type { LogScope, LogScopeInput, LogScopePatch, CreateRootScopeInput, CreateChildScopeInput } from "./log-scope";
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { isDevEnvironment } from "../../core.utils";
|
|
2
2
|
import { generateUniqueId } from "../utils/id.utils";
|
|
3
|
+
import {
|
|
4
|
+
applyScopePatch,
|
|
5
|
+
formatScopeLabels,
|
|
6
|
+
resolveLogData,
|
|
7
|
+
type LogScope,
|
|
8
|
+
type LogScopePatch,
|
|
9
|
+
} from "./log-scope";
|
|
3
10
|
|
|
4
11
|
/**
|
|
5
12
|
* Log severity and semantics (low → high). `minLevel` filters by {@link LOG_LEVEL_RANK}.
|
|
@@ -31,44 +38,32 @@ const LOG_LEVEL_RANK: Record<LogLevel, number> = {
|
|
|
31
38
|
[LogLevel.CRITICAL]: 5,
|
|
32
39
|
};
|
|
33
40
|
|
|
34
|
-
interface LogEntry {
|
|
41
|
+
interface LogEntry extends LogScope {
|
|
35
42
|
timestamp: number;
|
|
36
43
|
level: LogLevel;
|
|
37
|
-
/** Tell people what happened, but more structured */
|
|
38
44
|
message: string;
|
|
39
|
-
/** Category of a kind of log */
|
|
40
45
|
topic: string | null;
|
|
41
|
-
/** Where the log comes from */
|
|
42
|
-
module: string;
|
|
43
|
-
/** Specific process — correlates one logical chain (loop, request). */
|
|
44
|
-
traceId: string;
|
|
45
|
-
/** Worker node id when the log is node-scoped; omit for scheduler / admin / API-only paths. */
|
|
46
|
-
nodeId?: string;
|
|
47
46
|
extra?: string;
|
|
48
|
-
|
|
47
|
+
/** Per-line structured business payload. */
|
|
48
|
+
data?: unknown;
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
51
|
+
type LogRestParams = {
|
|
52
|
+
topic?: LogEntry["topic"];
|
|
53
|
+
extra?: LogEntry["extra"];
|
|
54
|
+
data?: unknown;
|
|
55
|
+
};
|
|
56
56
|
|
|
57
|
-
type
|
|
57
|
+
type LogParams = { message: LogEntry["message"] } & LogRestParams;
|
|
58
58
|
|
|
59
|
-
interface LogEntryPayload {
|
|
59
|
+
interface LogEntryPayload extends LogScope {
|
|
60
60
|
message: LogEntry["message"];
|
|
61
61
|
topic?: LogEntry["topic"];
|
|
62
62
|
extra?: LogEntry["extra"];
|
|
63
|
-
|
|
63
|
+
data?: LogEntry["data"];
|
|
64
64
|
level: LogEntry["level"];
|
|
65
|
-
module: LogEntry["module"];
|
|
66
|
-
traceId: LogEntry["traceId"];
|
|
67
|
-
nodeId?: LogEntry["nodeId"];
|
|
68
65
|
}
|
|
69
66
|
|
|
70
|
-
type LogParams = Pick<LogEntryPayload, "message" | "topic" | "extra" | "context">;
|
|
71
|
-
|
|
72
67
|
interface LogOptions {
|
|
73
68
|
defaultTopic: LogEntry["topic"];
|
|
74
69
|
formatTimestamp: boolean;
|
|
@@ -89,28 +84,24 @@ const DEFAULT_OPTIONS: LogOptions = {
|
|
|
89
84
|
minLevel: isDevEnvironment() ? LogLevel.DEBUG : LogLevel.INFO,
|
|
90
85
|
};
|
|
91
86
|
|
|
92
|
-
interface
|
|
93
|
-
/** Rank 0 — diagnostic detail; dev/troubleshooting only. */
|
|
87
|
+
interface LoggerWithScope {
|
|
94
88
|
debug: (message: LogParams["message"], restParams?: LogRestParams) => void;
|
|
95
|
-
/** Rank 1 — normal operational flow. */
|
|
96
89
|
info: (message: LogParams["message"], restParams?: LogRestParams) => void;
|
|
97
|
-
/** Rank 2 — positive milestone (semantic INFO, not higher severity). */
|
|
98
90
|
success: (message: LogParams["message"], restParams?: LogRestParams) => void;
|
|
99
|
-
/** Rank 3 — recoverable anomaly; system continues. */
|
|
100
91
|
warn: (message: LogParams["message"], restParams?: LogRestParams) => void;
|
|
101
|
-
/** Rank 4 — a concrete operation failed; needs investigation. */
|
|
102
92
|
error: (message: LogParams["message"], restParams?: LogRestParams) => void;
|
|
103
|
-
/** Rank 5 — invariant / design / integrity breach; escalate immediately. */
|
|
104
93
|
critical: (message: LogParams["message"], restParams?: LogRestParams) => void;
|
|
105
|
-
/** Merge partial fields into this logger's bound
|
|
106
|
-
|
|
94
|
+
/** Merge partial fields into this logger's bound scope. */
|
|
95
|
+
resetScope: (fields: LogScopePatch) => void;
|
|
96
|
+
/** @deprecated use {@link LoggerWithScope.resetScope} */
|
|
97
|
+
resetContext: (fields: LogScopePatch) => void;
|
|
107
98
|
}
|
|
108
99
|
|
|
109
100
|
function mergeLogOptions(options?: Partial<LogOptions>): LogOptions {
|
|
110
101
|
return { ...DEFAULT_OPTIONS, ...options };
|
|
111
102
|
}
|
|
112
103
|
|
|
113
|
-
function
|
|
104
|
+
function formatDataValue(value: unknown): string {
|
|
114
105
|
if (value === undefined) {
|
|
115
106
|
return "";
|
|
116
107
|
}
|
|
@@ -124,16 +115,19 @@ function formatContextValue(value: unknown): string {
|
|
|
124
115
|
}
|
|
125
116
|
}
|
|
126
117
|
|
|
127
|
-
function
|
|
118
|
+
function validateLogScope(logScope: LogScope): void {
|
|
128
119
|
const missing: string[] = [];
|
|
129
|
-
if (!
|
|
120
|
+
if (!logScope.module?.trim()) {
|
|
130
121
|
missing.push("module");
|
|
131
122
|
}
|
|
132
|
-
if (!
|
|
123
|
+
if (!logScope.traceId?.trim()) {
|
|
133
124
|
missing.push("traceId");
|
|
134
125
|
}
|
|
126
|
+
if (logScope.traceParentId !== null && typeof logScope.traceParentId !== "string") {
|
|
127
|
+
missing.push("traceParentId");
|
|
128
|
+
}
|
|
135
129
|
if (missing.length > 0) {
|
|
136
|
-
console.warn(`[LogManager]
|
|
130
|
+
console.warn(`[LogManager] LogScope missing or invalid: ${missing.join(", ")}`, logScope);
|
|
137
131
|
}
|
|
138
132
|
}
|
|
139
133
|
|
|
@@ -183,16 +177,8 @@ class LogManager {
|
|
|
183
177
|
return LOG_LEVEL_RANK[level] >= LOG_LEVEL_RANK[this.getMinLevel()];
|
|
184
178
|
}
|
|
185
179
|
|
|
186
|
-
private createLogEntry({
|
|
187
|
-
level,
|
|
188
|
-
message,
|
|
189
|
-
topic,
|
|
190
|
-
module,
|
|
191
|
-
traceId,
|
|
192
|
-
nodeId,
|
|
193
|
-
extra,
|
|
194
|
-
context,
|
|
195
|
-
}: LogEntryPayload): LogEntry {
|
|
180
|
+
private createLogEntry(payload: LogEntryPayload): LogEntry {
|
|
181
|
+
const { level, message, topic, extra, data, module, traceId, traceParentId, labels } = payload;
|
|
196
182
|
return {
|
|
197
183
|
timestamp: Date.now(),
|
|
198
184
|
level,
|
|
@@ -200,9 +186,10 @@ class LogManager {
|
|
|
200
186
|
topic: topic === undefined ? this.options.defaultTopic : topic,
|
|
201
187
|
module,
|
|
202
188
|
traceId,
|
|
203
|
-
|
|
189
|
+
traceParentId,
|
|
190
|
+
labels,
|
|
204
191
|
extra,
|
|
205
|
-
|
|
192
|
+
data,
|
|
206
193
|
};
|
|
207
194
|
}
|
|
208
195
|
|
|
@@ -223,7 +210,7 @@ class LogManager {
|
|
|
223
210
|
|
|
224
211
|
parts.push(this.formatLevelTag(entry));
|
|
225
212
|
parts.push(
|
|
226
|
-
`traceId=${entry.traceId}
|
|
213
|
+
`traceId=${entry.traceId} parent=${entry.traceParentId ?? "null"} labels=${formatScopeLabels(entry.labels)} module=${entry.module} topic=${entry.topic ?? "--"}`
|
|
227
214
|
);
|
|
228
215
|
|
|
229
216
|
if (this.options.formatPrefix) {
|
|
@@ -238,9 +225,9 @@ class LogManager {
|
|
|
238
225
|
parts.push(`| extra=${entry.extra}`);
|
|
239
226
|
}
|
|
240
227
|
|
|
241
|
-
const
|
|
242
|
-
if (
|
|
243
|
-
parts.push(`|
|
|
228
|
+
const dataText = formatDataValue(entry.data);
|
|
229
|
+
if (dataText) {
|
|
230
|
+
parts.push(`| data=${dataText}`);
|
|
244
231
|
}
|
|
245
232
|
|
|
246
233
|
return parts.join(" ");
|
|
@@ -260,21 +247,23 @@ class LogManager {
|
|
|
260
247
|
}
|
|
261
248
|
}
|
|
262
249
|
|
|
263
|
-
private log(
|
|
264
|
-
level: LogLevel,
|
|
265
|
-
message: LogParams["message"],
|
|
266
|
-
logContext: LogContext,
|
|
267
|
-
restParams?: LogRestParams
|
|
268
|
-
) {
|
|
250
|
+
private log(level: LogLevel, message: LogParams["message"], logScope: LogScope, restParams?: LogRestParams) {
|
|
269
251
|
if (!this.shouldLog(level)) {
|
|
270
252
|
return;
|
|
271
253
|
}
|
|
272
254
|
|
|
273
|
-
|
|
255
|
+
validateLogScope(logScope);
|
|
274
256
|
|
|
275
|
-
const { topic, extra
|
|
276
|
-
const
|
|
277
|
-
const entry = this.createLogEntry({
|
|
257
|
+
const { topic, extra } = restParams ?? {};
|
|
258
|
+
const data = resolveLogData(restParams);
|
|
259
|
+
const entry = this.createLogEntry({
|
|
260
|
+
level,
|
|
261
|
+
message,
|
|
262
|
+
topic,
|
|
263
|
+
extra,
|
|
264
|
+
data,
|
|
265
|
+
...logScope,
|
|
266
|
+
});
|
|
278
267
|
|
|
279
268
|
this.history.push(entry);
|
|
280
269
|
if (this.history.length > this.options.maxHistoryLength) {
|
|
@@ -290,51 +279,57 @@ class LogManager {
|
|
|
290
279
|
return generateUniqueId();
|
|
291
280
|
}
|
|
292
281
|
|
|
293
|
-
public debug(message: LogParams["message"],
|
|
294
|
-
this.log(LogLevel.DEBUG, message,
|
|
282
|
+
public debug(message: LogParams["message"], logScope: LogScope, restParams?: LogRestParams) {
|
|
283
|
+
this.log(LogLevel.DEBUG, message, logScope, restParams);
|
|
295
284
|
}
|
|
296
285
|
|
|
297
|
-
public info(message: LogParams["message"],
|
|
298
|
-
this.log(LogLevel.INFO, message,
|
|
286
|
+
public info(message: LogParams["message"], logScope: LogScope, restParams?: LogRestParams) {
|
|
287
|
+
this.log(LogLevel.INFO, message, logScope, restParams);
|
|
299
288
|
}
|
|
300
289
|
|
|
301
|
-
public success(message: LogParams["message"],
|
|
302
|
-
this.log(LogLevel.SUCCESS, message,
|
|
290
|
+
public success(message: LogParams["message"], logScope: LogScope, restParams?: LogRestParams) {
|
|
291
|
+
this.log(LogLevel.SUCCESS, message, logScope, restParams);
|
|
303
292
|
}
|
|
304
293
|
|
|
305
|
-
public warn(message: LogParams["message"],
|
|
306
|
-
this.log(LogLevel.WARN, message,
|
|
294
|
+
public warn(message: LogParams["message"], logScope: LogScope, restParams?: LogRestParams) {
|
|
295
|
+
this.log(LogLevel.WARN, message, logScope, restParams);
|
|
307
296
|
}
|
|
308
297
|
|
|
309
|
-
public error(message: LogParams["message"],
|
|
310
|
-
this.log(LogLevel.ERROR, message,
|
|
298
|
+
public error(message: LogParams["message"], logScope: LogScope, restParams?: LogRestParams) {
|
|
299
|
+
this.log(LogLevel.ERROR, message, logScope, restParams);
|
|
311
300
|
}
|
|
312
301
|
|
|
313
|
-
public critical(message: LogParams["message"],
|
|
314
|
-
this.log(LogLevel.CRITICAL, message,
|
|
302
|
+
public critical(message: LogParams["message"], logScope: LogScope, restParams?: LogRestParams) {
|
|
303
|
+
this.log(LogLevel.CRITICAL, message, logScope, restParams);
|
|
315
304
|
}
|
|
316
305
|
|
|
317
|
-
public
|
|
318
|
-
const
|
|
319
|
-
|
|
320
|
-
const logger:
|
|
321
|
-
debug: (message, restParams) => this.debug(message,
|
|
322
|
-
info: (message, restParams) => this.info(message,
|
|
323
|
-
success: (message, restParams) => this.success(message,
|
|
324
|
-
warn: (message, restParams) => this.warn(message,
|
|
325
|
-
error: (message, restParams) => this.error(message,
|
|
326
|
-
critical: (message, restParams) => this.critical(message,
|
|
306
|
+
public withScope(scope: LogScope): { logger: LoggerWithScope; scope: LogScope } {
|
|
307
|
+
const boundScope: LogScope = { ...scope, labels: scope.labels ? { ...scope.labels } : undefined };
|
|
308
|
+
|
|
309
|
+
const logger: LoggerWithScope = {
|
|
310
|
+
debug: (message, restParams) => this.debug(message, boundScope, restParams),
|
|
311
|
+
info: (message, restParams) => this.info(message, boundScope, restParams),
|
|
312
|
+
success: (message, restParams) => this.success(message, boundScope, restParams),
|
|
313
|
+
warn: (message, restParams) => this.warn(message, boundScope, restParams),
|
|
314
|
+
error: (message, restParams) => this.error(message, boundScope, restParams),
|
|
315
|
+
critical: (message, restParams) => this.critical(message, boundScope, restParams),
|
|
316
|
+
resetScope: (fields) => {
|
|
317
|
+
const next = applyScopePatch(boundScope, fields);
|
|
318
|
+
boundScope.module = next.module;
|
|
319
|
+
boundScope.traceId = next.traceId;
|
|
320
|
+
boundScope.traceParentId = next.traceParentId;
|
|
321
|
+
boundScope.labels = next.labels;
|
|
322
|
+
},
|
|
327
323
|
resetContext: (fields) => {
|
|
328
|
-
|
|
324
|
+
logger.resetScope(fields);
|
|
329
325
|
},
|
|
330
326
|
};
|
|
331
327
|
|
|
332
|
-
return { logger,
|
|
328
|
+
return { logger, scope: boundScope };
|
|
333
329
|
}
|
|
330
|
+
|
|
334
331
|
}
|
|
335
332
|
|
|
336
333
|
export const logManager = LogManager.getInstance();
|
|
337
334
|
export { LogManager, LogLevel };
|
|
338
|
-
export {
|
|
339
|
-
export type { CreateApiLoggerOptions } from "./create-api-logger";
|
|
340
|
-
export type { LogOptions, LogEntry, LogContext, LoggerWithContext, LogRestParams };
|
|
335
|
+
export type { LogOptions, LogEntry, LoggerWithScope, LogRestParams };
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { generateUniqueId } from "../utils/id.utils";
|
|
2
|
+
|
|
3
|
+
/** Logger-bound scope: module + trace chain + optional labels. */
|
|
4
|
+
export interface LogScope {
|
|
5
|
+
module: string;
|
|
6
|
+
traceId: string;
|
|
7
|
+
traceParentId: string | null;
|
|
8
|
+
labels?: Readonly<Record<string, string>>;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/** Partial update for {@link LogScope} / {@link applyScopePatch}. */
|
|
12
|
+
export type LogScopePatch = Partial<Omit<LogScope, "labels">> & {
|
|
13
|
+
labels?: Record<string, string>;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export type LogScopeInput = LogScopePatch & Pick<LogScope, "module">;
|
|
17
|
+
|
|
18
|
+
interface NormalizeScopeOptions {
|
|
19
|
+
/** When true and traceId is missing, generate a new id. */
|
|
20
|
+
generateTraceId?: boolean;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function mergeLabels(
|
|
24
|
+
base?: Readonly<Record<string, string>>,
|
|
25
|
+
patch?: Record<string, string>
|
|
26
|
+
): Record<string, string> | undefined {
|
|
27
|
+
const merged: Record<string, string> = { ...base, ...patch };
|
|
28
|
+
return Object.keys(merged).length > 0 ? merged : undefined;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** Coerce partial input into a {@link LogScope}. */
|
|
32
|
+
export function normalizeScope(input: LogScopeInput, options?: NormalizeScopeOptions): LogScope {
|
|
33
|
+
const generateTraceId = options?.generateTraceId ?? false;
|
|
34
|
+
const traceId = input.traceId?.trim() || (generateTraceId ? generateUniqueId() : "");
|
|
35
|
+
if (!traceId) {
|
|
36
|
+
throw new Error("[LogScope] traceId is required (or enable generateTraceId)");
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return {
|
|
40
|
+
module: input.module,
|
|
41
|
+
traceId,
|
|
42
|
+
traceParentId: input.traceParentId ?? null,
|
|
43
|
+
labels: mergeLabels(undefined, input.labels),
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** Input for {@link createRootScope}. */
|
|
48
|
+
export type CreateRootScopeInput = {
|
|
49
|
+
module: string;
|
|
50
|
+
traceId?: string;
|
|
51
|
+
labels?: Record<string, string>;
|
|
52
|
+
traceParentId?: string | null;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
/** Root scope: traceParentId defaults to null. */
|
|
56
|
+
export function createRootScope(input: CreateRootScopeInput): LogScope {
|
|
57
|
+
return normalizeScope(
|
|
58
|
+
{
|
|
59
|
+
module: input.module,
|
|
60
|
+
traceId: input.traceId,
|
|
61
|
+
traceParentId: input.traceParentId ?? null,
|
|
62
|
+
labels: input.labels,
|
|
63
|
+
},
|
|
64
|
+
{ generateTraceId: true }
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** Input for {@link createChildScope}. */
|
|
69
|
+
export type CreateChildScopeInput = {
|
|
70
|
+
module: string;
|
|
71
|
+
parent: LogScope;
|
|
72
|
+
traceId?: string;
|
|
73
|
+
traceParentId?: string | null;
|
|
74
|
+
labels?: Record<string, string>;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
/** Child scope: parent link defaults to parent.traceId; labels merge with parent. */
|
|
78
|
+
export function createChildScope(input: CreateChildScopeInput): LogScope {
|
|
79
|
+
const { module, parent, traceId, traceParentId, labels } = input;
|
|
80
|
+
return normalizeScope(
|
|
81
|
+
{
|
|
82
|
+
module,
|
|
83
|
+
traceId,
|
|
84
|
+
traceParentId: traceParentId ?? parent.traceId,
|
|
85
|
+
labels: mergeLabels(parent.labels, labels),
|
|
86
|
+
},
|
|
87
|
+
{ generateTraceId: true }
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/** Same trace chain, different module (e.g. prepareTask vs executeTask). */
|
|
92
|
+
export function withModule(scope: LogScope, module: string): LogScope {
|
|
93
|
+
return { ...scope, module };
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** Merge patch into scope (labels deep-merge). */
|
|
97
|
+
export function applyScopePatch(scope: LogScope, patch: LogScopePatch): LogScope {
|
|
98
|
+
return normalizeScope({
|
|
99
|
+
module: patch.module ?? scope.module,
|
|
100
|
+
traceId: patch.traceId ?? scope.traceId,
|
|
101
|
+
traceParentId: patch.traceParentId !== undefined ? patch.traceParentId : scope.traceParentId,
|
|
102
|
+
labels: mergeLabels(scope.labels, patch.labels),
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
export function formatScopeLabels(labels?: Readonly<Record<string, string>>): string {
|
|
106
|
+
if (labels == null || Object.keys(labels).length === 0) {
|
|
107
|
+
return "--";
|
|
108
|
+
}
|
|
109
|
+
return Object.entries(labels)
|
|
110
|
+
.map(([key, value]) => `${key}:${value}`)
|
|
111
|
+
.join(",");
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/** Prefer `data`; fall back to deprecated `context` on log rest params. */
|
|
115
|
+
export function resolveLogData(rest?: { data?: unknown; context?: unknown }): unknown | undefined {
|
|
116
|
+
if (rest?.data !== undefined) {
|
|
117
|
+
return rest.data;
|
|
118
|
+
}
|
|
119
|
+
if (rest?.context !== undefined) {
|
|
120
|
+
return rest.context;
|
|
121
|
+
}
|
|
122
|
+
return undefined;
|
|
123
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Task domain public API — curated re-exports only.
|
|
3
|
+
* Internal modules (local-task-registry, task-repo-context, task.utils) stay private.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// task.interface
|
|
7
|
+
export {
|
|
8
|
+
CategoryTask,
|
|
9
|
+
ResultCode,
|
|
10
|
+
TaskStatus,
|
|
11
|
+
TaskStatusAction,
|
|
12
|
+
} from "./task.interface";
|
|
13
|
+
export type { Task, TaskDetails, TaskFlow } from "./task.interface";
|
|
14
|
+
|
|
15
|
+
// task.api
|
|
16
|
+
export {
|
|
17
|
+
patchChangeTaskStatus,
|
|
18
|
+
patchChangeTaskStatusSchema,
|
|
19
|
+
patchClaimTask,
|
|
20
|
+
patchClaimTaskSchema,
|
|
21
|
+
patchTaskProgress,
|
|
22
|
+
patchTaskProgressSchema,
|
|
23
|
+
} from "./task.api";
|
|
24
|
+
export type {
|
|
25
|
+
PatchChangeTaskStatusPayload,
|
|
26
|
+
PatchClaimTaskPayload,
|
|
27
|
+
PatchTaskProgressPayload,
|
|
28
|
+
} from "./task.api";
|
|
29
|
+
export { postTask, postTaskSchema } from "./task-post.api";
|
|
30
|
+
export type { PostTaskPayload } from "./task-post.api";
|
|
31
|
+
|
|
32
|
+
// task-manager
|
|
33
|
+
export { TaskManager } from "./task-manager";
|
|
34
|
+
export type {
|
|
35
|
+
PrepareTaskFailureReason,
|
|
36
|
+
PrepareTaskParams,
|
|
37
|
+
PrepareTaskResponse,
|
|
38
|
+
RegisterTasksOptions,
|
|
39
|
+
RegisterTasksResult,
|
|
40
|
+
} from "./task-manager";
|
|
41
|
+
|
|
42
|
+
// task-repo-validation
|
|
43
|
+
export { TaskRepoValidation } from "./task-repo-validation";
|
|
44
|
+
export type {
|
|
45
|
+
TaskRepoValidationFailureReason,
|
|
46
|
+
ValidateTaskRepoAndParamsInput,
|
|
47
|
+
ValidateTaskRepoAndParamsResult,
|
|
48
|
+
} from "./task-repo-validation";
|