@pikku/core 0.12.13 → 0.12.15
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/CHANGELOG.md +46 -0
- package/dist/errors/errors.d.ts +18 -0
- package/dist/errors/errors.js +33 -0
- package/dist/function/function-runner.d.ts +1 -1
- package/dist/function/function-runner.js +10 -5
- package/dist/function/functions.types.js +1 -0
- package/dist/function/index.d.ts +2 -1
- package/dist/function/index.js +1 -0
- package/dist/handle-error.d.ts +2 -2
- package/dist/handle-error.js +8 -8
- package/dist/index.d.ts +1 -2
- package/dist/index.js +1 -2
- package/dist/middleware/index.d.ts +2 -0
- package/dist/middleware/index.js +2 -0
- package/dist/middleware/remote-auth.js +5 -2
- package/dist/permissions.d.ts +13 -1
- package/dist/permissions.js +51 -0
- package/dist/pikku-state.d.ts +0 -1
- package/dist/pikku-state.js +2 -4
- package/dist/remote.d.ts +10 -0
- package/dist/remote.js +32 -0
- package/dist/schema.js +2 -0
- package/dist/services/credential-service.d.ts +11 -0
- package/dist/services/credential-wire-service.d.ts +14 -3
- package/dist/services/credential-wire-service.js +49 -6
- package/dist/services/deployment-service.d.ts +12 -1
- package/dist/services/in-memory-queue-service.d.ts +7 -0
- package/dist/services/in-memory-queue-service.js +28 -0
- package/dist/services/index.d.ts +4 -1
- package/dist/services/index.js +2 -1
- package/dist/services/local-credential-service.d.ts +2 -0
- package/dist/services/local-credential-service.js +20 -0
- package/dist/services/logger-console.d.ts +26 -40
- package/dist/services/logger-console.js +102 -46
- package/dist/services/logger.d.ts +5 -0
- package/dist/services/meta-service.d.ts +175 -0
- package/dist/services/meta-service.js +310 -0
- package/dist/services/pikku-user-id.d.ts +3 -0
- package/dist/services/pikku-user-id.js +16 -0
- package/dist/services/typed-credential-service.d.ts +2 -0
- package/dist/services/typed-credential-service.js +6 -0
- package/dist/services/workflow-service.d.ts +6 -1
- package/dist/testing/service-tests.js +0 -8
- package/dist/types/core.types.d.ts +14 -2
- package/dist/types/state.types.d.ts +9 -2
- package/dist/wirings/ai-agent/ai-agent-prepare.d.ts +21 -0
- package/dist/wirings/ai-agent/ai-agent-prepare.js +90 -21
- package/dist/wirings/ai-agent/ai-agent-registry.js +2 -2
- package/dist/wirings/ai-agent/ai-agent-runner.js +24 -2
- package/dist/wirings/ai-agent/ai-agent-stream.d.ts +2 -1
- package/dist/wirings/ai-agent/ai-agent-stream.js +61 -3
- package/dist/wirings/ai-agent/ai-agent.types.d.ts +25 -4
- package/dist/wirings/ai-agent/index.d.ts +1 -1
- package/dist/wirings/ai-agent/index.js +1 -1
- package/dist/wirings/channel/channel-runner.js +3 -3
- package/dist/wirings/cli/cli-runner.js +4 -3
- package/dist/wirings/cli/command-parser.js +7 -3
- package/dist/wirings/http/http-runner.d.ts +1 -1
- package/dist/wirings/http/http-runner.js +23 -15
- package/dist/wirings/http/http.types.d.ts +2 -0
- package/dist/wirings/mcp/mcp-runner.js +5 -3
- package/dist/wirings/queue/queue-runner.d.ts +3 -1
- package/dist/wirings/queue/queue-runner.js +8 -3
- package/dist/wirings/queue/queue.types.d.ts +6 -0
- package/dist/wirings/rpc/rpc-runner.js +57 -90
- package/dist/wirings/scheduler/scheduler-runner.d.ts +3 -1
- package/dist/wirings/scheduler/scheduler-runner.js +9 -5
- package/dist/wirings/trigger/trigger-runner.js +4 -2
- package/dist/wirings/workflow/dsl/workflow-dsl.types.d.ts +2 -0
- package/dist/wirings/workflow/dsl/workflow-runner.d.ts +1 -1
- package/dist/wirings/workflow/dsl/workflow-runner.js +6 -9
- package/dist/wirings/workflow/graph/graph-runner.d.ts +1 -1
- package/dist/wirings/workflow/graph/graph-runner.js +18 -4
- package/dist/wirings/workflow/index.d.ts +4 -2
- package/dist/wirings/workflow/index.js +4 -2
- package/dist/wirings/workflow/pikku-workflow-service.d.ts +16 -4
- package/dist/wirings/workflow/pikku-workflow-service.js +218 -24
- package/dist/wirings/workflow/workflow-queue-workers.d.ts +40 -0
- package/dist/wirings/workflow/workflow-queue-workers.js +41 -0
- package/dist/wirings/workflow/workflow.types.d.ts +19 -1
- package/package.json +4 -1
- package/src/errors/errors.ts +44 -0
- package/src/function/function-runner.ts +24 -13
- package/src/function/functions.types.ts +1 -0
- package/src/function/index.ts +10 -0
- package/src/handle-error.test.ts +2 -2
- package/src/handle-error.ts +8 -8
- package/src/index.ts +1 -2
- package/src/middleware/index.ts +2 -0
- package/src/middleware/remote-auth.test.ts +4 -4
- package/src/middleware/remote-auth.ts +7 -2
- package/src/permissions.ts +70 -0
- package/src/pikku-state.test.ts +0 -26
- package/src/pikku-state.ts +2 -5
- package/src/remote.ts +46 -0
- package/src/schema.ts +1 -0
- package/src/services/credential-service.ts +13 -0
- package/src/services/credential-wire-service.test.ts +174 -0
- package/src/services/credential-wire-service.ts +52 -8
- package/src/services/deployment-service.ts +17 -1
- package/src/services/in-memory-queue-service.ts +46 -0
- package/src/services/index.ts +21 -1
- package/src/services/local-credential-service.ts +22 -0
- package/src/services/logger-console.ts +127 -47
- package/src/services/logger.ts +6 -0
- package/src/services/meta-service.ts +523 -0
- package/src/services/pikku-user-id.test.ts +62 -0
- package/src/services/pikku-user-id.ts +17 -0
- package/src/services/typed-credential-service.ts +8 -0
- package/src/services/workflow-service.ts +8 -0
- package/src/testing/service-tests.ts +0 -10
- package/src/types/core.types.ts +16 -2
- package/src/types/state.types.ts +7 -2
- package/src/wirings/ai-agent/ai-agent-prepare.ts +122 -41
- package/src/wirings/ai-agent/ai-agent-registry.ts +3 -3
- package/src/wirings/ai-agent/ai-agent-runner.ts +22 -3
- package/src/wirings/ai-agent/ai-agent-stream.ts +115 -3
- package/src/wirings/ai-agent/ai-agent.types.ts +27 -4
- package/src/wirings/ai-agent/index.ts +1 -0
- package/src/wirings/channel/channel-handler.ts +0 -1
- package/src/wirings/channel/channel-runner.ts +4 -5
- package/src/wirings/cli/cli-runner.test.ts +8 -7
- package/src/wirings/cli/cli-runner.ts +5 -4
- package/src/wirings/cli/command-parser.ts +8 -3
- package/src/wirings/http/http-runner.ts +27 -18
- package/src/wirings/http/http.types.ts +2 -0
- package/src/wirings/mcp/mcp-runner.ts +7 -10
- package/src/wirings/queue/queue-runner.test.ts +5 -11
- package/src/wirings/queue/queue-runner.ts +12 -4
- package/src/wirings/queue/queue.types.ts +6 -0
- package/src/wirings/rpc/rpc-runner.ts +91 -118
- package/src/wirings/scheduler/scheduler-runner.test.ts +5 -11
- package/src/wirings/scheduler/scheduler-runner.ts +13 -5
- package/src/wirings/trigger/trigger-runner.test.ts +10 -11
- package/src/wirings/trigger/trigger-runner.ts +6 -4
- package/src/wirings/workflow/dsl/workflow-dsl.types.ts +2 -0
- package/src/wirings/workflow/dsl/workflow-runner.ts +11 -10
- package/src/wirings/workflow/graph/graph-runner.ts +19 -4
- package/src/wirings/workflow/index.ts +17 -6
- package/src/wirings/workflow/pikku-workflow-service.ts +286 -24
- package/src/wirings/workflow/workflow-queue-workers.ts +85 -0
- package/src/wirings/workflow/workflow.types.ts +18 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/wirings/ai-agent/agent-dynamic-workflow.d.ts +0 -6
- package/dist/wirings/ai-agent/agent-dynamic-workflow.js +0 -468
- package/dist/wirings/workflow/workflow-helpers.d.ts +0 -36
- package/dist/wirings/workflow/workflow-helpers.js +0 -38
- package/src/wirings/ai-agent/agent-dynamic-workflow.ts +0 -610
- package/src/wirings/workflow/workflow-helpers.test.ts +0 -129
- package/src/wirings/workflow/workflow-helpers.ts +0 -79
|
@@ -1,22 +1,65 @@
|
|
|
1
|
+
import type { CredentialService } from './credential-service.js'
|
|
2
|
+
import { defaultPikkuUserIdResolver } from './pikku-user-id.js'
|
|
3
|
+
import type { PikkuWire } from '../types/core.types.js'
|
|
4
|
+
|
|
1
5
|
export class PikkuCredentialWireService {
|
|
2
6
|
private credentials: Record<string, unknown> = {}
|
|
7
|
+
private loaded = false
|
|
8
|
+
private loadPromise: Promise<void> | undefined
|
|
9
|
+
|
|
10
|
+
constructor(
|
|
11
|
+
private credentialService?: CredentialService,
|
|
12
|
+
private wire?: PikkuWire
|
|
13
|
+
) {}
|
|
3
14
|
|
|
4
15
|
set(name: string, value: unknown): void {
|
|
5
16
|
this.credentials[name] = value
|
|
6
17
|
}
|
|
7
18
|
|
|
8
|
-
|
|
9
|
-
return this.credentials
|
|
19
|
+
get<T = unknown>(name: string): T | null | Promise<T | null> {
|
|
20
|
+
if (this.loaded) return (this.credentials[name] as T) ?? null
|
|
21
|
+
return this.lazyLoad().then(() => (this.credentials[name] as T) ?? null)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
getAll(): Record<string, unknown> | Promise<Record<string, unknown>> {
|
|
25
|
+
if (this.loaded) return this.credentials
|
|
26
|
+
return this.lazyLoad().then(() => this.credentials)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
getScoped(
|
|
30
|
+
allowedNames: string[]
|
|
31
|
+
): Record<string, unknown> | Promise<Record<string, unknown>> {
|
|
32
|
+
const buildScoped = () => {
|
|
33
|
+
const scoped: Record<string, unknown> = {}
|
|
34
|
+
for (const name of allowedNames) {
|
|
35
|
+
if (name in this.credentials) {
|
|
36
|
+
scoped[name] = this.credentials[name]
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return scoped
|
|
40
|
+
}
|
|
41
|
+
if (this.loaded) return buildScoped()
|
|
42
|
+
return this.lazyLoad().then(buildScoped)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
private lazyLoad(): Promise<void> {
|
|
46
|
+
if (this.loadPromise) return this.loadPromise
|
|
47
|
+
this.loadPromise = this.doLoad()
|
|
48
|
+
return this.loadPromise
|
|
10
49
|
}
|
|
11
50
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
51
|
+
private async doLoad(): Promise<void> {
|
|
52
|
+
this.loaded = true
|
|
53
|
+
if (!this.credentialService || !this.wire) return
|
|
54
|
+
const userId = defaultPikkuUserIdResolver(this.wire)
|
|
55
|
+
if (!userId) return
|
|
56
|
+
this.wire.pikkuUserId = userId
|
|
57
|
+
const allCreds = await this.credentialService.getAll(userId)
|
|
58
|
+
for (const [name, value] of Object.entries(allCreds)) {
|
|
59
|
+
if (!(name in this.credentials)) {
|
|
60
|
+
this.credentials[name] = value
|
|
17
61
|
}
|
|
18
62
|
}
|
|
19
|
-
return scoped
|
|
20
63
|
}
|
|
21
64
|
}
|
|
22
65
|
|
|
@@ -36,6 +79,7 @@ export function createWireServicesCredentialWireProps(
|
|
|
36
79
|
return {
|
|
37
80
|
setCredential: (name: string, value: unknown) =>
|
|
38
81
|
credentialWire.set(name, value),
|
|
82
|
+
getCredential: <T = unknown>(name: string) => credentialWire.get<T>(name),
|
|
39
83
|
getCredentials: () =>
|
|
40
84
|
allowedNames
|
|
41
85
|
? credentialWire.getScoped(allowedNames)
|
|
@@ -18,5 +18,21 @@ export interface DeploymentService {
|
|
|
18
18
|
init(): Promise<void>
|
|
19
19
|
start(config: DeploymentConfig): Promise<void>
|
|
20
20
|
stop(): Promise<void>
|
|
21
|
-
|
|
21
|
+
/**
|
|
22
|
+
* Dispatch a remote RPC call to a function.
|
|
23
|
+
* The deployment service owns the full transport:
|
|
24
|
+
* - Resolving the target (endpoint, service binding, etc.)
|
|
25
|
+
* - Session propagation (JWT signing, headers)
|
|
26
|
+
* - The actual network call
|
|
27
|
+
*
|
|
28
|
+
* @param funcName - The function to invoke
|
|
29
|
+
* @param data - Input data for the function
|
|
30
|
+
* @param session - User session to propagate (optional)
|
|
31
|
+
*/
|
|
32
|
+
invoke(
|
|
33
|
+
funcName: string,
|
|
34
|
+
data: unknown,
|
|
35
|
+
session?: unknown,
|
|
36
|
+
traceId?: string
|
|
37
|
+
): Promise<unknown>
|
|
22
38
|
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
QueueService,
|
|
3
|
+
QueueJob,
|
|
4
|
+
JobOptions,
|
|
5
|
+
} from '../wirings/queue/queue.types.js'
|
|
6
|
+
import { runQueueJob } from '../wirings/queue/queue-runner.js'
|
|
7
|
+
|
|
8
|
+
export class InMemoryQueueService implements QueueService {
|
|
9
|
+
readonly supportsResults = false
|
|
10
|
+
private jobCounter = 0
|
|
11
|
+
|
|
12
|
+
async add<T>(
|
|
13
|
+
queueName: string,
|
|
14
|
+
data: T,
|
|
15
|
+
options?: JobOptions
|
|
16
|
+
): Promise<string> {
|
|
17
|
+
const jobId = `inmem-${++this.jobCounter}`
|
|
18
|
+
|
|
19
|
+
const job: QueueJob<T> = {
|
|
20
|
+
id: jobId,
|
|
21
|
+
queueName,
|
|
22
|
+
data,
|
|
23
|
+
status: () => 'active',
|
|
24
|
+
pikkuUserId: options?.pikkuUserId,
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const delay = options?.delay ?? 0
|
|
28
|
+
|
|
29
|
+
setTimeout(async () => {
|
|
30
|
+
try {
|
|
31
|
+
await runQueueJob({ job })
|
|
32
|
+
} catch (e: any) {
|
|
33
|
+
console.error(
|
|
34
|
+
`[InMemoryQueue] Job ${jobId} on ${queueName} failed:`,
|
|
35
|
+
e.message
|
|
36
|
+
)
|
|
37
|
+
}
|
|
38
|
+
}, delay)
|
|
39
|
+
|
|
40
|
+
return jobId
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async getJob(): Promise<null> {
|
|
44
|
+
return null
|
|
45
|
+
}
|
|
46
|
+
}
|
package/src/services/index.ts
CHANGED
|
@@ -19,8 +19,9 @@ export { TypedVariablesService } from './typed-variables-service.js'
|
|
|
19
19
|
export { LocalSecretService } from './local-secrets.js'
|
|
20
20
|
export { LocalCredentialService } from './local-credential-service.js'
|
|
21
21
|
export { LocalVariablesService } from './local-variables.js'
|
|
22
|
-
export { ConsoleLogger } from './logger-console.js'
|
|
22
|
+
export { ConsoleLogger, JsonConsoleLogger } from './logger-console.js'
|
|
23
23
|
export { InMemoryWorkflowService } from './in-memory-workflow-service.js'
|
|
24
|
+
export { InMemoryQueueService } from './in-memory-queue-service.js'
|
|
24
25
|
export { InMemoryTriggerService } from './in-memory-trigger-service.js'
|
|
25
26
|
export { InMemoryAIRunStateService } from './in-memory-ai-run-state-service.js'
|
|
26
27
|
export { LocalGatewayService } from './local-gateway-service.js'
|
|
@@ -66,3 +67,22 @@ export type {
|
|
|
66
67
|
CredentialMetaInfo,
|
|
67
68
|
} from './typed-credential-service.js'
|
|
68
69
|
export type { VariableStatus, VariableMeta } from './typed-variables-service.js'
|
|
70
|
+
export type { MetaService } from './meta-service.js'
|
|
71
|
+
export type {
|
|
72
|
+
MCPMeta,
|
|
73
|
+
RPCMetaRecord,
|
|
74
|
+
ServiceMeta,
|
|
75
|
+
ServicesMetaRecord,
|
|
76
|
+
MiddlewareDefinitionMeta,
|
|
77
|
+
MiddlewareInstanceMeta,
|
|
78
|
+
GroupMeta,
|
|
79
|
+
MiddlewareGroupsMeta,
|
|
80
|
+
PermissionDefinitionMeta,
|
|
81
|
+
PermissionsGroupsMeta,
|
|
82
|
+
FunctionsMeta,
|
|
83
|
+
FunctionMeta,
|
|
84
|
+
MiddlewareMeta,
|
|
85
|
+
PermissionMeta,
|
|
86
|
+
AgentsMeta,
|
|
87
|
+
AgentMeta,
|
|
88
|
+
} from './meta-service.js'
|
|
@@ -38,4 +38,26 @@ export class LocalCredentialService implements CredentialService {
|
|
|
38
38
|
}
|
|
39
39
|
return result
|
|
40
40
|
}
|
|
41
|
+
|
|
42
|
+
async getUsersWithCredential(name: string): Promise<string[]> {
|
|
43
|
+
const suffix = `:${name}`
|
|
44
|
+
const users: string[] = []
|
|
45
|
+
for (const key of this.store.keys()) {
|
|
46
|
+
if (key.endsWith(suffix)) {
|
|
47
|
+
users.push(key.slice(0, -suffix.length))
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return users
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async getAllUsers(): Promise<string[]> {
|
|
54
|
+
const users = new Set<string>()
|
|
55
|
+
for (const key of this.store.keys()) {
|
|
56
|
+
const colonIndex = key.indexOf(':')
|
|
57
|
+
if (colonIndex > 0) {
|
|
58
|
+
users.add(key.slice(0, colonIndex))
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return [...users]
|
|
62
|
+
}
|
|
41
63
|
}
|
|
@@ -2,97 +2,177 @@ import type { Logger } from './logger.js'
|
|
|
2
2
|
import { LogLevel } from './logger.js'
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
5
|
+
* Text-mode console logger.
|
|
6
|
+
* Output: `INFO: message` or `[traceId] INFO: message`
|
|
6
7
|
*/
|
|
7
8
|
export class ConsoleLogger implements Logger {
|
|
8
|
-
/**
|
|
9
|
-
* The current logging level.
|
|
10
|
-
*/
|
|
11
9
|
private level: LogLevel = LogLevel.info
|
|
10
|
+
private prefix: string
|
|
11
|
+
|
|
12
|
+
constructor(traceId?: string) {
|
|
13
|
+
this.prefix = traceId ? `[${traceId}]` : ''
|
|
14
|
+
}
|
|
12
15
|
|
|
13
|
-
/**
|
|
14
|
-
* Sets the logging level.
|
|
15
|
-
* @param level - The logging level to set.
|
|
16
|
-
*/
|
|
17
16
|
setLevel(level: LogLevel): void {
|
|
18
17
|
this.level = level
|
|
19
18
|
}
|
|
20
19
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
20
|
+
scope(traceId: string): Logger {
|
|
21
|
+
const scoped = new ConsoleLogger(traceId)
|
|
22
|
+
scoped.level = this.level
|
|
23
|
+
return scoped
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
private log_(
|
|
27
|
+
fn: (...args: unknown[]) => void,
|
|
28
|
+
label: string,
|
|
29
|
+
...args: unknown[]
|
|
30
|
+
): void {
|
|
31
|
+
if (this.prefix) {
|
|
32
|
+
fn(this.prefix, label, ...args)
|
|
33
|
+
} else {
|
|
34
|
+
fn(label, ...args)
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
trace(message: string, ...meta: any[]): void {
|
|
27
39
|
if (this.level <= LogLevel.trace) {
|
|
28
|
-
console.trace
|
|
40
|
+
this.log_(console.trace, 'TRACE:', message, ...meta)
|
|
29
41
|
}
|
|
30
42
|
}
|
|
31
43
|
|
|
32
|
-
/**
|
|
33
|
-
* Logs a debug message.
|
|
34
|
-
* @param message - The message to log.
|
|
35
|
-
* @param meta - Additional metadata to log.
|
|
36
|
-
*/
|
|
37
44
|
debug(message: string, ...meta: any[]): void {
|
|
38
45
|
if (this.level <= LogLevel.debug) {
|
|
39
|
-
console.debug
|
|
46
|
+
this.log_(console.debug, 'DEBUG:', message, ...meta)
|
|
40
47
|
}
|
|
41
48
|
}
|
|
42
49
|
|
|
43
|
-
/**
|
|
44
|
-
* Logs an informational message.
|
|
45
|
-
* @param messageOrObj - The message or object to log.
|
|
46
|
-
* @param meta - Additional metadata to log.
|
|
47
|
-
*/
|
|
48
50
|
info(messageOrObj: string | Record<string, any>, ...meta: any[]): void {
|
|
49
51
|
if (this.level <= LogLevel.info) {
|
|
50
|
-
console.info
|
|
52
|
+
this.log_(console.info, 'INFO:', messageOrObj, ...meta)
|
|
51
53
|
}
|
|
52
54
|
}
|
|
53
55
|
|
|
54
|
-
/**
|
|
55
|
-
* Logs a warning message.
|
|
56
|
-
* @param messageOrObj - The message or object to log.
|
|
57
|
-
* @param meta - Additional metadata to log.
|
|
58
|
-
*/
|
|
59
56
|
warn(messageOrObj: string | Record<string, any>, ...meta: any[]): void {
|
|
60
57
|
if (this.level <= LogLevel.warn) {
|
|
61
|
-
console.warn
|
|
58
|
+
this.log_(console.warn, 'WARN:', messageOrObj, ...meta)
|
|
62
59
|
}
|
|
63
60
|
}
|
|
64
61
|
|
|
65
|
-
/**
|
|
66
|
-
* Logs an error message.
|
|
67
|
-
* @param messageOrObj - The message, object, or error to log.
|
|
68
|
-
* @param meta - Additional metadata to log.
|
|
69
|
-
*/
|
|
70
62
|
error(
|
|
71
63
|
messageOrObj: string | Record<string, any> | Error,
|
|
72
64
|
...meta: any[]
|
|
73
65
|
): void {
|
|
74
66
|
if (this.level <= LogLevel.error) {
|
|
75
|
-
|
|
67
|
+
this.log_(
|
|
68
|
+
console.error,
|
|
76
69
|
'ERROR:',
|
|
77
70
|
messageOrObj instanceof Error ? messageOrObj.message : messageOrObj,
|
|
78
71
|
...meta
|
|
79
72
|
)
|
|
80
73
|
if (messageOrObj instanceof Error) {
|
|
81
|
-
console.error
|
|
74
|
+
this.log_(console.error, 'STACK:', messageOrObj.stack)
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
log(level: string, message: string, ...meta: any[]): void {
|
|
80
|
+
const logLevel = LogLevel[level as keyof typeof LogLevel]
|
|
81
|
+
if (this.level <= logLevel) {
|
|
82
|
+
this.log_(console.log, `${level.toUpperCase()}:`, message, ...meta)
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* JSON-mode console logger.
|
|
89
|
+
* Output: `{"level":"info","message":"...","traceId":"..."}`
|
|
90
|
+
* CF Workers Logs auto-indexes JSON keys for filtering.
|
|
91
|
+
*/
|
|
92
|
+
export class JsonConsoleLogger implements Logger {
|
|
93
|
+
private level: LogLevel = LogLevel.info
|
|
94
|
+
private traceId: string | undefined
|
|
95
|
+
|
|
96
|
+
constructor(traceId?: string) {
|
|
97
|
+
this.traceId = traceId
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
setLevel(level: LogLevel): void {
|
|
101
|
+
this.level = level
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
scope(traceId: string): Logger {
|
|
105
|
+
const scoped = new JsonConsoleLogger(traceId)
|
|
106
|
+
scoped.level = this.level
|
|
107
|
+
return scoped
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
trace(message: string, ...meta: any[]): void {
|
|
111
|
+
if (this.level <= LogLevel.trace) {
|
|
112
|
+
this.emit(console.debug, 'trace', message, meta)
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
debug(message: string, ...meta: any[]): void {
|
|
117
|
+
if (this.level <= LogLevel.debug) {
|
|
118
|
+
this.emit(console.debug, 'debug', message, meta)
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
info(messageOrObj: string | Record<string, any>, ...meta: any[]): void {
|
|
123
|
+
if (this.level <= LogLevel.info) {
|
|
124
|
+
this.emit(console.info, 'info', messageOrObj, meta)
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
warn(messageOrObj: string | Record<string, any>, ...meta: any[]): void {
|
|
129
|
+
if (this.level <= LogLevel.warn) {
|
|
130
|
+
this.emit(console.warn, 'warn', messageOrObj, meta)
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
error(
|
|
135
|
+
messageOrObj: string | Record<string, any> | Error,
|
|
136
|
+
...meta: any[]
|
|
137
|
+
): void {
|
|
138
|
+
if (this.level <= LogLevel.error) {
|
|
139
|
+
if (messageOrObj instanceof Error) {
|
|
140
|
+
this.emit(console.error, 'error', messageOrObj.message, meta)
|
|
141
|
+
console.error(
|
|
142
|
+
JSON.stringify({
|
|
143
|
+
level: 'error',
|
|
144
|
+
message: 'stack',
|
|
145
|
+
stack: messageOrObj.stack,
|
|
146
|
+
...(this.traceId ? { traceId: this.traceId } : {}),
|
|
147
|
+
})
|
|
148
|
+
)
|
|
149
|
+
} else {
|
|
150
|
+
this.emit(console.error, 'error', messageOrObj, meta)
|
|
82
151
|
}
|
|
83
152
|
}
|
|
84
153
|
}
|
|
85
154
|
|
|
86
|
-
/**
|
|
87
|
-
* Logs a message at a specified level.
|
|
88
|
-
* @param level - The logging level.
|
|
89
|
-
* @param message - The message to log.
|
|
90
|
-
* @param meta - Additional metadata to log.
|
|
91
|
-
*/
|
|
92
155
|
log(level: string, message: string, ...meta: any[]): void {
|
|
93
156
|
const logLevel = LogLevel[level as keyof typeof LogLevel]
|
|
94
157
|
if (this.level <= logLevel) {
|
|
95
|
-
console.log
|
|
158
|
+
this.emit(console.log, level, message, meta)
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
private emit(
|
|
163
|
+
fn: (...args: any[]) => void,
|
|
164
|
+
level: string,
|
|
165
|
+
messageOrObj: string | Record<string, any>,
|
|
166
|
+
meta: any[]
|
|
167
|
+
): void {
|
|
168
|
+
const entry: Record<string, unknown> = { level }
|
|
169
|
+
if (this.traceId) entry.traceId = this.traceId
|
|
170
|
+
if (typeof messageOrObj === 'string') {
|
|
171
|
+
entry.message = messageOrObj
|
|
172
|
+
} else {
|
|
173
|
+
Object.assign(entry, messageOrObj)
|
|
96
174
|
}
|
|
175
|
+
if (meta.length > 0) entry.meta = meta
|
|
176
|
+
fn(JSON.stringify(entry))
|
|
97
177
|
}
|
|
98
178
|
}
|
package/src/services/logger.ts
CHANGED
|
@@ -54,4 +54,10 @@ export interface Logger {
|
|
|
54
54
|
* @param level - The logging level to set.
|
|
55
55
|
*/
|
|
56
56
|
setLevel(level: LogLevel): void
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Creates a scoped logger with a traceId included in every log entry.
|
|
60
|
+
* Used per-request to correlate logs across function calls.
|
|
61
|
+
*/
|
|
62
|
+
scope?(traceId: string): Logger
|
|
57
63
|
}
|