@pikku/cli 0.10.1 → 0.11.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/.pikku/channel/pikku-channel-types.gen.ts +4 -3
- package/.pikku/channel/pikku-channels-map.gen.d.ts +5 -2
- package/.pikku/channel/pikku-channels-meta.gen.ts +1 -1
- package/.pikku/channel/pikku-channels.gen.ts +1 -1
- package/.pikku/cli/pikku-cli-types.gen.ts +23 -1
- package/.pikku/cli/pikku-cli-wirings-meta.gen.ts +8 -116
- package/.pikku/cli/pikku-cli-wirings.gen.ts +2 -3
- package/.pikku/function/pikku-function-types.gen.ts +1 -1
- package/.pikku/function/pikku-functions-meta.gen.ts +265 -138
- package/.pikku/function/pikku-functions-meta.min.gen.ts +62 -32
- package/.pikku/function/pikku-functions.gen.ts +9 -1
- package/.pikku/http/pikku-http-types.gen.ts +1 -1
- package/.pikku/http/pikku-http-wirings-map.gen.d.ts +5 -2
- package/.pikku/http/pikku-http-wirings-meta.gen.ts +1 -1
- package/.pikku/http/pikku-http-wirings.gen.ts +1 -1
- package/.pikku/mcp/pikku-mcp-types.gen.ts +1 -1
- package/.pikku/mcp/pikku-mcp-wirings-meta.gen.ts +1 -1
- package/.pikku/mcp/pikku-mcp-wirings.gen.ts +1 -1
- package/.pikku/pikku-bootstrap.gen.ts +4 -1
- package/.pikku/pikku-services.gen.ts +21 -12
- package/.pikku/pikku-types.gen.ts +1 -1
- package/.pikku/pikku-websocket.gen.ts +15 -1
- package/.pikku/queue/pikku-queue-types.gen.ts +1 -1
- package/.pikku/queue/pikku-queue-workers-wirings-map.gen.d.ts +5 -2
- package/.pikku/queue/pikku-queue-workers-wirings-meta.gen.ts +7 -2
- package/.pikku/queue/pikku-queue-workers-wirings.gen.ts +1 -1
- package/.pikku/rpc/pikku-remote-rpc-workers.gen.ts +27 -0
- package/.pikku/rpc/pikku-rpc-wirings-map.gen.d.ts +13 -3
- package/.pikku/rpc/pikku-rpc-wirings-map.internal.gen.d.ts +26 -10
- package/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.ts +15 -9
- package/.pikku/scheduler/pikku-scheduler-types.gen.ts +1 -1
- package/.pikku/scheduler/pikku-schedulers-wirings-meta.gen.ts +1 -1
- package/.pikku/scheduler/pikku-schedulers-wirings.gen.ts +1 -1
- package/.pikku/schemas/register.gen.ts +17 -5
- package/.pikku/schemas/schemas/PikkuCLIConfig.schema.json +1 -1
- package/.pikku/schemas/schemas/PikkuChannelsOutput.schema.json +1 -1
- package/.pikku/schemas/schemas/PikkuPublicRPCOutput.schema.json +1 -0
- package/.pikku/schemas/schemas/PikkuRemoteRPCOutput.schema.json +1 -0
- package/.pikku/schemas/schemas/PikkuSchemasOutput.schema.json +1 -1
- package/.pikku/schemas/schemas/PikkuWorkflowOutput.schema.json +1 -0
- package/.pikku/workflow/pikku-workflow-map.gen.d.ts +62 -0
- package/.pikku/workflow/pikku-workflow-types.gen.ts +92 -0
- package/.pikku/workflow/pikku-workflow-wirings-meta.gen.ts +5 -0
- package/.pikku/workflow/pikku-workflow-wirings.gen.ts +4 -0
- package/CHANGELOG.md +57 -0
- package/bin/pikku.ts +30 -21
- package/cli.schema.json +1 -1
- package/dist/.pikku/channel/pikku-channel-types.gen.d.ts +4 -3
- package/dist/.pikku/channel/pikku-channel-types.gen.js +1 -1
- package/dist/.pikku/channel/pikku-channels-meta.gen.js +1 -1
- package/dist/.pikku/channel/pikku-channels.gen.d.ts +1 -1
- package/dist/.pikku/channel/pikku-channels.gen.js +1 -1
- package/dist/.pikku/cli/pikku-cli-types.gen.d.ts +18 -1
- package/dist/.pikku/cli/pikku-cli-types.gen.js +20 -1
- package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.js +8 -116
- package/dist/.pikku/cli/pikku-cli-wirings.gen.d.ts +1 -2
- package/dist/.pikku/cli/pikku-cli-wirings.gen.js +1 -2
- package/dist/.pikku/function/pikku-function-types.gen.d.ts +1 -1
- package/dist/.pikku/function/pikku-function-types.gen.js +1 -1
- package/dist/.pikku/function/pikku-functions-meta.gen.js +265 -138
- package/dist/.pikku/function/pikku-functions-meta.min.gen.js +62 -32
- package/dist/.pikku/function/pikku-functions.gen.js +9 -1
- package/dist/.pikku/http/pikku-http-types.gen.d.ts +1 -1
- package/dist/.pikku/http/pikku-http-types.gen.js +1 -1
- package/dist/.pikku/http/pikku-http-wirings-meta.gen.js +1 -1
- package/dist/.pikku/http/pikku-http-wirings.gen.d.ts +1 -1
- package/dist/.pikku/http/pikku-http-wirings.gen.js +1 -1
- package/dist/.pikku/mcp/pikku-mcp-types.gen.d.ts +1 -1
- package/dist/.pikku/mcp/pikku-mcp-types.gen.js +1 -1
- package/dist/.pikku/mcp/pikku-mcp-wirings-meta.gen.js +1 -1
- package/dist/.pikku/mcp/pikku-mcp-wirings.gen.d.ts +1 -1
- package/dist/.pikku/mcp/pikku-mcp-wirings.gen.js +1 -1
- package/dist/.pikku/pikku-bootstrap.gen.d.ts +4 -1
- package/dist/.pikku/pikku-bootstrap.gen.js +4 -1
- package/dist/.pikku/pikku-services.gen.d.ts +15 -6
- package/dist/.pikku/pikku-services.gen.js +14 -2
- package/dist/.pikku/pikku-types.gen.d.ts +1 -1
- package/dist/.pikku/pikku-types.gen.js +1 -1
- package/dist/.pikku/pikku-websocket.gen.d.ts +15 -1
- package/dist/.pikku/pikku-websocket.gen.js +15 -1
- package/dist/.pikku/queue/pikku-queue-types.gen.d.ts +1 -1
- package/dist/.pikku/queue/pikku-queue-types.gen.js +1 -1
- package/dist/.pikku/queue/pikku-queue-workers-wirings-meta.gen.js +7 -2
- package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.d.ts +1 -1
- package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.js +1 -1
- package/dist/.pikku/rpc/pikku-remote-rpc-workers.gen.d.ts +17 -0
- package/dist/.pikku/rpc/pikku-remote-rpc-workers.gen.js +22 -0
- package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.js +15 -9
- package/dist/.pikku/scheduler/pikku-scheduler-types.gen.d.ts +1 -1
- package/dist/.pikku/scheduler/pikku-scheduler-types.gen.js +1 -1
- package/dist/.pikku/scheduler/pikku-schedulers-wirings-meta.gen.js +1 -1
- package/dist/.pikku/scheduler/pikku-schedulers-wirings.gen.d.ts +1 -1
- package/dist/.pikku/scheduler/pikku-schedulers-wirings.gen.js +1 -1
- package/dist/.pikku/schemas/register.gen.js +9 -3
- package/dist/.pikku/schemas/schemas/PikkuCLIConfig.schema.json +1 -1
- package/dist/.pikku/schemas/schemas/PikkuChannelsOutput.schema.json +1 -1
- package/dist/.pikku/schemas/schemas/PikkuPublicRPCOutput.schema.json +1 -0
- package/dist/.pikku/schemas/schemas/PikkuRemoteInternalRPCInput.schema.json +1 -0
- package/dist/.pikku/schemas/schemas/PikkuRemoteRPCOutput.schema.json +1 -0
- package/dist/.pikku/schemas/schemas/PikkuSchemasOutput.schema.json +1 -1
- package/dist/.pikku/schemas/schemas/PikkuWorkflowOutput.schema.json +1 -0
- package/dist/.pikku/workflow/pikku-workflow-types.gen.d.ts +58 -0
- package/dist/.pikku/workflow/pikku-workflow-types.gen.js +28 -0
- package/dist/.pikku/workflow/pikku-workflow-wirings-meta.gen.js +5 -0
- package/dist/.pikku/workflow/pikku-workflow-wirings.gen.d.ts +4 -0
- package/dist/.pikku/workflow/pikku-workflow-wirings.gen.js +5 -0
- package/dist/bin/pikku.js +24 -19
- package/dist/src/cli.wiring.js +107 -99
- package/dist/src/functions/commands/all.js +51 -2
- package/dist/src/functions/commands/bootstrap.d.ts +1 -0
- package/dist/src/functions/commands/bootstrap.js +24 -0
- package/dist/src/functions/runtimes/nextjs/serialize-nextjs-backend-wrapper.js +46 -2
- package/dist/src/functions/wirings/channels/serialize-channel-types.js +3 -2
- package/dist/src/functions/wirings/channels/serialize-websocket-wrapper.js +14 -0
- package/dist/src/functions/wirings/cli/pikku-command-cli-entry.js +4 -4
- package/dist/src/functions/wirings/cli/serialize-channel-cli-client.js +20 -7
- package/dist/src/functions/wirings/cli/serialize-channel-cli.js +32 -7
- package/dist/src/functions/wirings/cli/serialize-cli-types.js +22 -0
- package/dist/src/functions/wirings/functions/pikku-command-services.d.ts +1 -1
- package/dist/src/functions/wirings/functions/pikku-command-services.js +54 -26
- package/dist/src/functions/wirings/functions/schemas.js +2 -2
- package/dist/src/functions/wirings/http/pikku-command-openapi.js +1 -1
- package/dist/src/functions/wirings/middleware/pikku-command-middleware.js +3 -10
- package/dist/src/functions/wirings/queue/pikku-queue.js +9 -1
- package/dist/src/functions/wirings/queue/serialize-queue-map.d.ts +2 -2
- package/dist/src/functions/wirings/queue/serialize-queue-meta.d.ts +2 -2
- package/dist/src/functions/wirings/rpc/pikku-command-public-rpc.d.ts +1 -0
- package/dist/src/functions/wirings/rpc/pikku-command-public-rpc.js +23 -0
- package/dist/src/functions/wirings/rpc/pikku-command-remote-rpc.d.ts +1 -0
- package/dist/src/functions/wirings/rpc/pikku-command-remote-rpc.js +23 -0
- package/dist/src/functions/wirings/rpc/serialize-public-rpc.d.ts +4 -0
- package/dist/src/functions/wirings/rpc/serialize-public-rpc.js +30 -0
- package/dist/src/functions/wirings/rpc/serialize-remote-rpc.d.ts +4 -0
- package/dist/src/functions/wirings/rpc/serialize-remote-rpc.js +30 -0
- package/dist/src/functions/wirings/rpc/serialize-rpc-wrapper.js +2 -2
- package/dist/src/functions/wirings/rpc/serialize-typed-rpc-map.js +27 -3
- package/dist/src/functions/wirings/workflow/pikku-command-workflow-map.d.ts +1 -0
- package/dist/src/functions/wirings/workflow/pikku-command-workflow-map.js +12 -0
- package/dist/src/functions/wirings/workflow/pikku-command-workflow-types.d.ts +1 -0
- package/dist/src/functions/wirings/workflow/pikku-command-workflow-types.js +11 -0
- package/dist/src/functions/wirings/workflow/pikku-command-workflow.d.ts +1 -0
- package/dist/src/functions/wirings/workflow/pikku-command-workflow.js +55 -0
- package/dist/src/functions/wirings/workflow/serialize-workflow-map.d.ts +4 -0
- package/dist/src/functions/wirings/workflow/serialize-workflow-map.js +79 -0
- package/dist/src/functions/wirings/workflow/serialize-workflow-meta.d.ts +2 -0
- package/dist/src/functions/wirings/workflow/serialize-workflow-meta.js +10 -0
- package/dist/src/functions/wirings/workflow/serialize-workflow-types.d.ts +4 -0
- package/dist/src/functions/wirings/workflow/serialize-workflow-types.js +95 -0
- package/dist/src/functions/wirings/workflow/serialize-workflow-workers.d.ts +4 -0
- package/dist/src/functions/wirings/workflow/serialize-workflow-workers.js +60 -0
- package/dist/src/middleware/log-command-info-and-time.d.ts +1 -1
- package/dist/src/middleware/log-command-info-and-time.js +8 -5
- package/dist/src/services/cli-logger-forwarder.service.js +1 -1
- package/dist/src/services/cli-logger.service.d.ts +7 -2
- package/dist/src/services/cli-logger.service.js +17 -5
- package/dist/src/services.js +77 -12
- package/dist/src/utils/command-summary.d.ts +44 -0
- package/dist/src/utils/command-summary.js +74 -0
- package/dist/src/utils/file-writer.js +2 -2
- package/dist/src/utils/pikku-cli-config.js +48 -0
- package/dist/src/utils/schema-generator.d.ts +2 -2
- package/dist/src/utils/schema-generator.js +31 -10
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -4
- package/pikku.config.json +5 -2
- package/src/cli.wiring.ts +106 -101
- package/src/functions/commands/all.ts +66 -2
- package/src/functions/commands/bootstrap.ts +28 -0
- package/src/functions/runtimes/nextjs/serialize-nextjs-backend-wrapper.ts +46 -2
- package/src/functions/wirings/channels/serialize-channel-types.ts +3 -2
- package/src/functions/wirings/channels/serialize-websocket-wrapper.ts +14 -0
- package/src/functions/wirings/cli/pikku-command-cli-entry.ts +4 -4
- package/src/functions/wirings/cli/serialize-channel-cli-client.ts +20 -7
- package/src/functions/wirings/cli/serialize-channel-cli.ts +40 -8
- package/src/functions/wirings/cli/serialize-cli-types.ts +22 -0
- package/src/functions/wirings/functions/pikku-command-services.ts +57 -28
- package/src/functions/wirings/functions/schemas.ts +4 -3
- package/src/functions/wirings/http/pikku-command-openapi.ts +2 -1
- package/src/functions/wirings/middleware/pikku-command-middleware.ts +11 -22
- package/src/functions/wirings/queue/pikku-queue.ts +10 -1
- package/src/functions/wirings/queue/serialize-queue-map.ts +3 -3
- package/src/functions/wirings/queue/serialize-queue-meta.ts +2 -2
- package/src/functions/wirings/rpc/pikku-command-public-rpc.ts +32 -0
- package/src/functions/wirings/rpc/pikku-command-remote-rpc.ts +35 -0
- package/src/functions/wirings/rpc/serialize-public-rpc.ts +30 -0
- package/src/functions/wirings/rpc/serialize-remote-rpc.ts +30 -0
- package/src/functions/wirings/rpc/serialize-rpc-wrapper.ts +2 -2
- package/src/functions/wirings/rpc/serialize-typed-rpc-map.ts +26 -3
- package/src/functions/wirings/workflow/pikku-command-workflow-map.ts +24 -0
- package/src/functions/wirings/workflow/pikku-command-workflow-types.ts +22 -0
- package/src/functions/wirings/workflow/pikku-command-workflow.ts +123 -0
- package/src/functions/wirings/workflow/serialize-workflow-map.ts +123 -0
- package/src/functions/wirings/workflow/serialize-workflow-meta.ts +16 -0
- package/src/functions/wirings/workflow/serialize-workflow-types.ts +95 -0
- package/src/functions/wirings/workflow/serialize-workflow-workers.ts +60 -0
- package/src/middleware/log-command-info-and-time.ts +8 -5
- package/src/services/cli-logger-forwarder.service.ts +1 -1
- package/src/services/cli-logger.service.ts +21 -6
- package/src/services.ts +86 -11
- package/src/utils/command-summary.ts +103 -0
- package/src/utils/file-writer.ts +2 -2
- package/src/utils/pikku-cli-config.ts +68 -0
- package/src/utils/schema-generator.ts +30 -11
- package/types/application-types.d.ts +5 -1
- package/types/config.d.ts +61 -6
- package/.pikku/cli/pikku-cli-channel.gen.ts +0 -34
- package/.pikku/cli/pikku-cli-client.gen.ts +0 -43
- package/.pikku/cli/pikku-cli.gen.ts +0 -41
- package/dist/.pikku/cli/pikku-cli-channel.gen.js +0 -33
- package/dist/.pikku/cli/pikku-cli-client.gen.d.ts +0 -10
- package/dist/.pikku/cli/pikku-cli-client.gen.js +0 -34
- package/dist/.pikku/cli/pikku-cli.gen.d.ts +0 -10
- package/dist/.pikku/cli/pikku-cli.gen.js +0 -38
- /package/dist/.pikku/{cli/pikku-cli-channel.gen.d.ts → workflow/pikku-workflow-wirings-meta.gen.d.ts} +0 -0
|
@@ -27,11 +27,18 @@ export type RPCInvoke = <Name extends keyof RPCMap>(
|
|
|
27
27
|
}
|
|
28
28
|
) => Promise<RPCMap[Name]['output']>
|
|
29
29
|
|
|
30
|
+
// Import WorkflowMap for workflow typing
|
|
31
|
+
import type { WorkflowMap } from '../workflow/pikku-workflow-map.gen.js'
|
|
32
|
+
|
|
30
33
|
export type TypedPikkuRPC = {
|
|
31
34
|
depth: number;
|
|
32
35
|
global: boolean;
|
|
33
36
|
invoke: RPCInvoke;
|
|
34
|
-
invokeExposed: (name: string, data: any) => Promise<any
|
|
37
|
+
invokeExposed: (name: string, data: any) => Promise<any>;
|
|
38
|
+
startWorkflow: <Name extends keyof WorkflowMap>(
|
|
39
|
+
name: Name,
|
|
40
|
+
input: WorkflowMap[Name]['input']
|
|
41
|
+
) => Promise<{ runId: string }>;
|
|
35
42
|
}
|
|
36
43
|
`;
|
|
37
44
|
};
|
|
@@ -47,8 +54,25 @@ function generateRPCs(rpcMeta, functionsMeta, typesMap, requiredTypes) {
|
|
|
47
54
|
const input = functionMeta.inputs ? functionMeta.inputs[0] : undefined;
|
|
48
55
|
const output = functionMeta.outputs ? functionMeta.outputs[0] : undefined;
|
|
49
56
|
// Store the input and output types for RPCHandler
|
|
50
|
-
|
|
51
|
-
|
|
57
|
+
// Use 'any' for types not in typesMap (e.g., inline types in generated workflow workers)
|
|
58
|
+
let inputType = 'null';
|
|
59
|
+
if (input) {
|
|
60
|
+
try {
|
|
61
|
+
inputType = typesMap.getTypeMeta(input).uniqueName;
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
inputType = 'any';
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
let outputType = 'null';
|
|
68
|
+
if (output) {
|
|
69
|
+
try {
|
|
70
|
+
outputType = typesMap.getTypeMeta(output).uniqueName;
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
outputType = 'any';
|
|
74
|
+
}
|
|
75
|
+
}
|
|
52
76
|
requiredTypes.add(inputType);
|
|
53
77
|
requiredTypes.add(outputType);
|
|
54
78
|
// Add RPC entry
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const pikkuWorkflowMap: any;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { pikkuSessionlessFunc } from '../../../../.pikku/pikku-types.gen.js';
|
|
2
|
+
import { writeFileInDir } from '../../../utils/file-writer.js';
|
|
3
|
+
import { serializeWorkflowMap } from './serialize-workflow-map.js';
|
|
4
|
+
export const pikkuWorkflowMap = pikkuSessionlessFunc({
|
|
5
|
+
func: async ({ logger, config, getInspectorState }) => {
|
|
6
|
+
const visitState = await getInspectorState();
|
|
7
|
+
const { workflowMapDeclarationFile, packageMappings } = config;
|
|
8
|
+
const { workflows, functions: functionState } = visitState;
|
|
9
|
+
const { typesMap } = functionState;
|
|
10
|
+
await writeFileInDir(logger, workflowMapDeclarationFile, serializeWorkflowMap(workflowMapDeclarationFile, packageMappings, typesMap, functionState.meta, workflows.meta));
|
|
11
|
+
},
|
|
12
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const pikkuWorkflowTypes: any;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { pikkuSessionlessFunc } from '../../../../.pikku/pikku-types.gen.js';
|
|
2
|
+
import { writeFileInDir } from '../../../utils/file-writer.js';
|
|
3
|
+
import { serializeWorkflowTypes } from './serialize-workflow-types.js';
|
|
4
|
+
import { getFileImportRelativePath } from '../../../utils/file-import-path.js';
|
|
5
|
+
export const pikkuWorkflowTypes = pikkuSessionlessFunc({
|
|
6
|
+
func: async ({ logger, config }) => {
|
|
7
|
+
const { workflowTypesFile, functionTypesFile, packageMappings } = config;
|
|
8
|
+
const functionTypesImportPath = getFileImportRelativePath(workflowTypesFile, functionTypesFile, packageMappings);
|
|
9
|
+
await writeFileInDir(logger, workflowTypesFile, serializeWorkflowTypes(functionTypesImportPath));
|
|
10
|
+
},
|
|
11
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const pikkuWorkflow: any;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { pikkuSessionlessFunc } from '../../../../.pikku/pikku-types.gen.js';
|
|
2
|
+
import { ErrorCode } from '@pikku/inspector';
|
|
3
|
+
import { serializeFileImports } from '../../../utils/file-imports-serializer.js';
|
|
4
|
+
import { writeFileInDir } from '../../../utils/file-writer.js';
|
|
5
|
+
import { logCommandInfoAndTime } from '../../../middleware/log-command-info-and-time.js';
|
|
6
|
+
import { serializeWorkflowMeta } from './serialize-workflow-meta.js';
|
|
7
|
+
import { serializeWorkflowTypes } from './serialize-workflow-types.js';
|
|
8
|
+
import { serializeWorkflowMap } from './serialize-workflow-map.js';
|
|
9
|
+
import { serializeWorkflowWorkers } from './serialize-workflow-workers.js';
|
|
10
|
+
import { getFileImportRelativePath } from '../../../utils/file-import-path.js';
|
|
11
|
+
import { join } from 'path';
|
|
12
|
+
export const pikkuWorkflow = pikkuSessionlessFunc({
|
|
13
|
+
func: async ({ logger, config, getInspectorState }) => {
|
|
14
|
+
const visitState = await getInspectorState();
|
|
15
|
+
const { workflowsWiringFile, workflowsWiringMetaFile, workflowMapDeclarationFile, workflowTypesFile, functionTypesFile, typesDeclarationFile, packageMappings, } = config;
|
|
16
|
+
const { workflows, functions: functionState } = visitState;
|
|
17
|
+
const { typesMap } = functionState;
|
|
18
|
+
// Validate that workflowService service is configured if workflows are defined
|
|
19
|
+
const hasWorkflows = Object.keys(workflows.meta).length > 0;
|
|
20
|
+
if (hasWorkflows) {
|
|
21
|
+
const hasWorkflowState = visitState.serviceAggregation.allSingletonServices.includes('workflowService');
|
|
22
|
+
if (!hasWorkflowState) {
|
|
23
|
+
logger.critical(ErrorCode.WORKFLOW_ORCHESTRATOR_NOT_CONFIGURED, 'Workflows detected but workflowService service not configured. Please add workflowService to your singleton services');
|
|
24
|
+
throw new Error('WorkflowState service not configured but workflows are defined');
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
// Write workflow metadata
|
|
28
|
+
await writeFileInDir(logger, workflowsWiringMetaFile, serializeWorkflowMeta(workflows.meta));
|
|
29
|
+
// Write workflow wirings (imports)
|
|
30
|
+
await writeFileInDir(logger, workflowsWiringFile, serializeFileImports('wireWorkflow', workflowsWiringFile, workflows.files, packageMappings));
|
|
31
|
+
// Write workflow types
|
|
32
|
+
const functionTypesImportPath = getFileImportRelativePath(workflowTypesFile, functionTypesFile, packageMappings);
|
|
33
|
+
await writeFileInDir(logger, workflowTypesFile, serializeWorkflowTypes(functionTypesImportPath));
|
|
34
|
+
// Write workflow map (type-safe client API)
|
|
35
|
+
await writeFileInDir(logger, workflowMapDeclarationFile, serializeWorkflowMap(workflowMapDeclarationFile, packageMappings, typesMap, functionState.meta, workflows.meta));
|
|
36
|
+
if (config.workflows) {
|
|
37
|
+
if (config.workflows.singleQueue) {
|
|
38
|
+
const workflowPath = join(config.rootDir, config.workflows.path);
|
|
39
|
+
const pathToPikkuTypes = getFileImportRelativePath(workflowPath, typesDeclarationFile, packageMappings);
|
|
40
|
+
await writeFileInDir(logger, workflowPath, serializeWorkflowWorkers(pathToPikkuTypes));
|
|
41
|
+
}
|
|
42
|
+
else if (workflows.files.size > 0) {
|
|
43
|
+
logger.critical(ErrorCode.WORKFLOW_MULTI_QUEUE_NOT_SUPPORTED, 'Multi-queue workflows are not supported when workflows.singleQueue is false. Please enable singleQueue in your configuration.');
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return true;
|
|
48
|
+
},
|
|
49
|
+
middleware: [
|
|
50
|
+
logCommandInfoAndTime({
|
|
51
|
+
commandStart: 'Finding Workflows',
|
|
52
|
+
commandEnd: 'Found Workflows',
|
|
53
|
+
}),
|
|
54
|
+
],
|
|
55
|
+
});
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { WorkflowsMeta } from '@pikku/core/workflow';
|
|
2
|
+
import { TypesMap } from '@pikku/inspector';
|
|
3
|
+
import { FunctionsMeta } from '@pikku/core';
|
|
4
|
+
export declare const serializeWorkflowMap: (relativeToPath: string, packageMappings: Record<string, string>, typesMap: TypesMap, functionsMeta: FunctionsMeta, workflowsMeta: WorkflowsMeta) => string;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { serializeImportMap } from '../../../utils/serialize-import-map.js';
|
|
2
|
+
import { generateCustomTypes } from '../../../utils/custom-types-generator.js';
|
|
3
|
+
export const serializeWorkflowMap = (relativeToPath, packageMappings, typesMap, functionsMeta, workflowsMeta) => {
|
|
4
|
+
const requiredTypes = new Set();
|
|
5
|
+
const serializedCustomTypes = generateCustomTypes(typesMap, requiredTypes);
|
|
6
|
+
const serializedWorkflows = generateWorkflows(workflowsMeta, functionsMeta, typesMap, requiredTypes);
|
|
7
|
+
const serializedImportMap = serializeImportMap(relativeToPath, packageMappings, typesMap, requiredTypes);
|
|
8
|
+
return `/**
|
|
9
|
+
* This provides the structure needed for TypeScript to be aware of workflows and their input/output types
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
${serializedImportMap}
|
|
13
|
+
${serializedCustomTypes}
|
|
14
|
+
|
|
15
|
+
interface WorkflowHandler<I, O> {
|
|
16
|
+
input: I;
|
|
17
|
+
output: O;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
${serializedWorkflows}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Type-safe workflow client API
|
|
24
|
+
*/
|
|
25
|
+
export type WorkflowClient<Name extends keyof WorkflowMap> = {
|
|
26
|
+
/**
|
|
27
|
+
* Start a new workflow run
|
|
28
|
+
*/
|
|
29
|
+
start: (input: WorkflowMap[Name]['input']) => Promise<{ runId: string }>;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Get a workflow run by ID
|
|
33
|
+
*/
|
|
34
|
+
getRun: <output extends keyof WorkflowMap[Name]>(runId: string) => Promise<WorkflowMap[Name][output]>;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Cancel a running workflow
|
|
38
|
+
*/
|
|
39
|
+
cancelRun: (runId: string) => Promise<boolean>;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Map of all registered workflows with type-safe client APIs
|
|
44
|
+
*/
|
|
45
|
+
export type TypedWorkflowClients = {
|
|
46
|
+
[Name in keyof WorkflowMap]: WorkflowClient<Name>;
|
|
47
|
+
}
|
|
48
|
+
`;
|
|
49
|
+
};
|
|
50
|
+
function generateWorkflows(workflowsMeta, functionsMeta, typesMap, requiredTypes) {
|
|
51
|
+
// Initialize an object to collect workflows
|
|
52
|
+
const workflowsObj = {};
|
|
53
|
+
// Iterate through workflow metadata
|
|
54
|
+
for (const [workflowName, { pikkuFuncName }] of Object.entries(workflowsMeta)) {
|
|
55
|
+
const functionMeta = functionsMeta[pikkuFuncName];
|
|
56
|
+
if (!functionMeta) {
|
|
57
|
+
throw new Error(`Function ${workflowName} not found in functionsMeta. Please check your configuration.`);
|
|
58
|
+
}
|
|
59
|
+
const input = functionMeta.inputs ? functionMeta.inputs[0] : undefined;
|
|
60
|
+
const output = functionMeta.outputs ? functionMeta.outputs[0] : undefined;
|
|
61
|
+
// Store the input and output types for WorkflowHandler
|
|
62
|
+
const inputType = input ? typesMap.getTypeMeta(input).uniqueName : 'void';
|
|
63
|
+
const outputType = output ? typesMap.getTypeMeta(output).uniqueName : 'void';
|
|
64
|
+
requiredTypes.add(inputType);
|
|
65
|
+
requiredTypes.add(outputType);
|
|
66
|
+
// Add workflow entry
|
|
67
|
+
workflowsObj[workflowName] = {
|
|
68
|
+
inputType,
|
|
69
|
+
outputType,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
// Build the Workflows object as a string
|
|
73
|
+
let workflowsStr = 'export type WorkflowMap = {\n';
|
|
74
|
+
for (const [workflowName, handler] of Object.entries(workflowsObj)) {
|
|
75
|
+
workflowsStr += ` readonly '${workflowName}': WorkflowHandler<${handler.inputType}, ${handler.outputType}>,\n`;
|
|
76
|
+
}
|
|
77
|
+
workflowsStr += '};\n';
|
|
78
|
+
return workflowsStr;
|
|
79
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export const serializeWorkflowMeta = (workflowsMeta) => {
|
|
2
|
+
const serializedOutput = [];
|
|
3
|
+
serializedOutput.push("import { pikkuState } from '@pikku/core'");
|
|
4
|
+
serializedOutput.push(`pikkuState('workflows', 'meta', ${JSON.stringify(workflowsMeta, null, 2)})`);
|
|
5
|
+
const workflowsMetaValues = Object.values(workflowsMeta);
|
|
6
|
+
if (workflowsMetaValues.length > 0) {
|
|
7
|
+
serializedOutput.push(`export type WorkflowNames = '${workflowsMetaValues.map((w) => w.workflowName).join("' | '")}'`);
|
|
8
|
+
}
|
|
9
|
+
return serializedOutput.join('\n');
|
|
10
|
+
};
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generates type definitions for workflow wirings
|
|
3
|
+
*/
|
|
4
|
+
export const serializeWorkflowTypes = (functionTypesImportPath) => {
|
|
5
|
+
return `/**
|
|
6
|
+
* Workflow-specific type definitions for tree-shaking optimization
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { CoreWorkflow, wireWorkflow as wireWorkflowCore, PikkuWorkflowInteraction, WorkflowStepOptions } from '@pikku/core/workflow'
|
|
10
|
+
import { CorePikkuFunctionConfig, CorePikkuFunctionSessionless } from '@pikku/core'
|
|
11
|
+
import type { PikkuPermission, PikkuMiddleware } from '${functionTypesImportPath}'
|
|
12
|
+
import type { UserSession, SingletonServices } from '../../types/application-types.d.js'
|
|
13
|
+
import type { TypedPikkuRPC, RPCMap } from '../rpc/pikku-rpc-wirings-map.internal.gen.d.js'
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Type definition for workflows that orchestrate multi-step processes.
|
|
17
|
+
* Workflows support both inline and remote execution modes with step caching.
|
|
18
|
+
*/
|
|
19
|
+
type WorkflowWiring = CoreWorkflow<
|
|
20
|
+
CorePikkuFunctionConfig<PikkuFunctionWorkflow<any, any>, PikkuPermission<any>, PikkuMiddleware>
|
|
21
|
+
>
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Typed workflow interaction with RPC awareness
|
|
25
|
+
* Provides type-safe workflow.do() for RPC steps
|
|
26
|
+
*/
|
|
27
|
+
export interface TypedWorkflow extends PikkuWorkflowInteraction {
|
|
28
|
+
/**
|
|
29
|
+
* Execute a workflow step with RPC invocation (typed based on available RPCs)
|
|
30
|
+
* @template K - RPC name from the RPC map
|
|
31
|
+
*/
|
|
32
|
+
do<K extends keyof RPCMap>(
|
|
33
|
+
stepName: string,
|
|
34
|
+
rpcName: K,
|
|
35
|
+
data: RPCMap[K]['input'],
|
|
36
|
+
options?: WorkflowStepOptions
|
|
37
|
+
): Promise<RPCMap[K]['output']>
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Execute a workflow step with inline function
|
|
41
|
+
* @template T - Return type of the inline function
|
|
42
|
+
*/
|
|
43
|
+
do<T>(
|
|
44
|
+
stepName: string,
|
|
45
|
+
fn: () => T | Promise<T>,
|
|
46
|
+
options?: WorkflowStepOptions
|
|
47
|
+
): Promise<T>
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Workflow function type with typed workflow service
|
|
52
|
+
* Includes the workflow interaction object with typed RPC methods
|
|
53
|
+
*/
|
|
54
|
+
export type PikkuFunctionWorkflow<
|
|
55
|
+
In = unknown,
|
|
56
|
+
Out = never
|
|
57
|
+
> = CorePikkuFunctionSessionless<
|
|
58
|
+
In,
|
|
59
|
+
Out,
|
|
60
|
+
null,
|
|
61
|
+
SingletonServices & {
|
|
62
|
+
rpc: TypedPikkuRPC
|
|
63
|
+
workflow: TypedWorkflow
|
|
64
|
+
},
|
|
65
|
+
UserSession
|
|
66
|
+
>
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Creates a workflow function with typed input and output.
|
|
70
|
+
* Workflow functions have access to the workflow interaction object for step execution.
|
|
71
|
+
*
|
|
72
|
+
* @template In - Input type for the workflow
|
|
73
|
+
* @template Out - Output type for the workflow
|
|
74
|
+
* @param func - Function definition, either direct function or configuration object
|
|
75
|
+
* @returns The normalized configuration object
|
|
76
|
+
*/
|
|
77
|
+
export const pikkuWorkflowFunc = <In, Out = unknown>(
|
|
78
|
+
func:
|
|
79
|
+
| PikkuFunctionWorkflow<In, Out>
|
|
80
|
+
| CorePikkuFunctionConfig<PikkuFunctionWorkflow<In, Out>, PikkuPermission<In>, PikkuMiddleware>
|
|
81
|
+
) => {
|
|
82
|
+
return typeof func === 'function' ? { func } : func
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Registers a workflow with the Pikku framework.
|
|
87
|
+
* Workflows can run in 'inline' (synchronous) or 'remote' (queue-based) execution modes.
|
|
88
|
+
*
|
|
89
|
+
* @param workflow - Workflow definition with name, execution mode, and handler function
|
|
90
|
+
*/
|
|
91
|
+
export const wireWorkflow = (workflow: WorkflowWiring) => {
|
|
92
|
+
wireWorkflowCore(workflow as any)
|
|
93
|
+
}
|
|
94
|
+
`;
|
|
95
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate queue workers and RPC functions for workflow steps and orchestrator
|
|
3
|
+
*/
|
|
4
|
+
export const serializeWorkflowWorkers = (pathToPikkuTypes) => {
|
|
5
|
+
return `/**
|
|
6
|
+
* Auto-generated workflow queue workers and RPC functions
|
|
7
|
+
* Do not edit manually - regenerate with 'npx pikku'
|
|
8
|
+
*/
|
|
9
|
+
import { pikkuSessionlessFunc, wireQueueWorker } from '${pathToPikkuTypes}'
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Worker input types for generated queue workers
|
|
13
|
+
*/
|
|
14
|
+
export type WorkflowStepInput = {
|
|
15
|
+
runId: string
|
|
16
|
+
stepName: string
|
|
17
|
+
rpcName: string
|
|
18
|
+
data: any
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export const pikkuWorkflowWorker = pikkuSessionlessFunc<
|
|
22
|
+
WorkflowStepInput,
|
|
23
|
+
void
|
|
24
|
+
>({
|
|
25
|
+
func: async ({ workflowService, rpc }, { runId, stepName, rpcName, data }) => {
|
|
26
|
+
await workflowService!.executeWorkflowStep(runId, stepName, rpcName, data, rpc)
|
|
27
|
+
}
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
export const pikkuWorkflowOrchestrator = pikkuSessionlessFunc<
|
|
31
|
+
{ runId: string },
|
|
32
|
+
void
|
|
33
|
+
>({
|
|
34
|
+
func: async ({ workflowService, rpc }, { runId }) => {
|
|
35
|
+
await workflowService!.orchestrateWorkflow(runId, rpc)
|
|
36
|
+
}
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
export const pikkuWorkflowSleeper = pikkuSessionlessFunc<
|
|
40
|
+
{ runId: string, stepId: string },
|
|
41
|
+
void
|
|
42
|
+
>({
|
|
43
|
+
func: async ({ workflowService }, { runId, stepId }) => {
|
|
44
|
+
await workflowService!.executeWorkflowSleep(runId, stepId)
|
|
45
|
+
},
|
|
46
|
+
name: 'pikkuWorkflowStepSleeper',
|
|
47
|
+
internal: true,
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
wireQueueWorker({
|
|
51
|
+
queueName: 'pikku-workflow-step-worker',
|
|
52
|
+
func: pikkuWorkflowWorker,
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
wireQueueWorker({
|
|
56
|
+
queueName: 'pikku-workflow-orchestrator',
|
|
57
|
+
func: pikkuWorkflowOrchestrator,
|
|
58
|
+
})
|
|
59
|
+
`;
|
|
60
|
+
};
|
|
@@ -7,7 +7,7 @@ export interface LogCommandInfoOptions {
|
|
|
7
7
|
}
|
|
8
8
|
/**
|
|
9
9
|
* Middleware to log command execution timing and status
|
|
10
|
-
*
|
|
10
|
+
* Uses debug level so it only shows with --verbose flag
|
|
11
11
|
*/
|
|
12
12
|
export declare const logCommandInfoAndTime: ({ commandStart, commandEnd, }: LogCommandInfoOptions) => PikkuMiddleware;
|
|
13
13
|
export {};
|
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Middleware to log command execution timing and status
|
|
3
|
-
*
|
|
3
|
+
* Uses debug level so it only shows with --verbose flag
|
|
4
4
|
*/
|
|
5
5
|
export const logCommandInfoAndTime = ({ commandStart, commandEnd, }) => {
|
|
6
6
|
return async ({ logger }, _interaction, next) => {
|
|
7
|
-
// Log start
|
|
7
|
+
// Log start (debug level - only shows with --verbose)
|
|
8
8
|
const start = Date.now();
|
|
9
|
-
logger.
|
|
9
|
+
logger.debug(`• ${commandStart}...`);
|
|
10
10
|
// Execute the function
|
|
11
11
|
await next();
|
|
12
|
-
// Log completion
|
|
13
|
-
logger.
|
|
12
|
+
// Log completion (debug level - only shows with --verbose)
|
|
13
|
+
logger.debug({
|
|
14
|
+
type: 'success',
|
|
15
|
+
message: `✓ ${commandEnd} in ${Date.now() - start}ms.`,
|
|
16
|
+
});
|
|
14
17
|
};
|
|
15
18
|
};
|
|
@@ -53,7 +53,7 @@ export class CLILoggerForwarder {
|
|
|
53
53
|
this.log('trace', LogLevel.trace, message);
|
|
54
54
|
}
|
|
55
55
|
critical(code, message) {
|
|
56
|
-
const url = `https://pikku.dev/docs/cli
|
|
56
|
+
const url = `https://pikku.dev/docs/pikku-cli/errors/${code.toLowerCase()}`;
|
|
57
57
|
const formattedMessage = `[${code}] ${message}\n → ${url}`;
|
|
58
58
|
this.error(formattedMessage);
|
|
59
59
|
}
|
|
@@ -9,15 +9,20 @@ export declare class CLILogger implements Logger {
|
|
|
9
9
|
silent?: boolean;
|
|
10
10
|
});
|
|
11
11
|
setLevel(level: LogLevel): void;
|
|
12
|
+
setSilent(silent: boolean): void;
|
|
13
|
+
isSilent(): boolean;
|
|
12
14
|
info(message: string | {
|
|
13
15
|
message: string;
|
|
14
16
|
type?: string;
|
|
15
17
|
}): void;
|
|
16
18
|
error(message: string): void;
|
|
17
19
|
warn(message: string): void;
|
|
18
|
-
debug(message: string
|
|
20
|
+
debug(message: string | {
|
|
21
|
+
message: string;
|
|
22
|
+
type?: string;
|
|
23
|
+
}): void;
|
|
19
24
|
critical(code: ErrorCode, message: string): void;
|
|
20
25
|
hasCriticalErrors(): boolean;
|
|
21
|
-
|
|
26
|
+
logLogo(): void;
|
|
22
27
|
private primary;
|
|
23
28
|
}
|
|
@@ -8,20 +8,26 @@ const logo = `
|
|
|
8
8
|
| | | | _ (| _ (| _ (| |_| |
|
|
9
9
|
|_| |_|_| _)_| _)____/
|
|
10
10
|
`;
|
|
11
|
-
const BASE_ERROR_URL = 'https://pikku.dev/errors';
|
|
11
|
+
const BASE_ERROR_URL = 'https://pikku.dev/docs/pikku-cli/errors';
|
|
12
12
|
export class CLILogger {
|
|
13
13
|
silent;
|
|
14
|
-
level = LogLevel.
|
|
14
|
+
level = LogLevel.warn; // default to warn level
|
|
15
15
|
criticalErrors = [];
|
|
16
16
|
constructor({ logLogo, silent = false, }) {
|
|
17
17
|
this.silent = silent;
|
|
18
18
|
if (logLogo && !silent) {
|
|
19
|
-
this.
|
|
19
|
+
this.logLogo();
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
setLevel(level) {
|
|
23
23
|
this.level = level;
|
|
24
24
|
}
|
|
25
|
+
setSilent(silent) {
|
|
26
|
+
this.silent = silent;
|
|
27
|
+
}
|
|
28
|
+
isSilent() {
|
|
29
|
+
return this.silent;
|
|
30
|
+
}
|
|
25
31
|
info(message) {
|
|
26
32
|
if (this.level > LogLevel.info || this.silent)
|
|
27
33
|
return;
|
|
@@ -49,7 +55,13 @@ export class CLILogger {
|
|
|
49
55
|
debug(message) {
|
|
50
56
|
if (this.level > LogLevel.debug || this.silent)
|
|
51
57
|
return;
|
|
52
|
-
|
|
58
|
+
let c = chalk.gray;
|
|
59
|
+
if (typeof message === 'object') {
|
|
60
|
+
if (message.type === 'success') {
|
|
61
|
+
c = chalk.green;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
console.log(c(typeof message === 'string' ? message : message.message));
|
|
53
65
|
}
|
|
54
66
|
critical(code, message) {
|
|
55
67
|
const url = `${BASE_ERROR_URL}/${code.toLowerCase()}`;
|
|
@@ -60,7 +72,7 @@ export class CLILogger {
|
|
|
60
72
|
hasCriticalErrors() {
|
|
61
73
|
return this.criticalErrors.length > 0;
|
|
62
74
|
}
|
|
63
|
-
|
|
75
|
+
logLogo() {
|
|
64
76
|
this.primary(logo);
|
|
65
77
|
// // When running from dist/, __filename is dist/src/services/cli-logger.service.js
|
|
66
78
|
// // So we need to go up 3 levels: dist/src/services -> dist/src -> dist -> package.json
|
package/dist/src/services.js
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { pikkuCLIRender } from '@pikku/core/cli';
|
|
2
|
-
import { LocalVariablesService } from '@pikku/core/services';
|
|
2
|
+
import { LocalVariablesService, LogLevel } from '@pikku/core/services';
|
|
3
3
|
import { CLILogger } from './services/cli-logger.service.js';
|
|
4
4
|
import { getPikkuCLIConfig } from './utils/pikku-cli-config.js';
|
|
5
|
-
import { inspect, serializeInspectorState, deserializeInspectorState, filterInspectorState, } from '@pikku/inspector';
|
|
5
|
+
import { inspect, serializeInspectorState, deserializeInspectorState, filterInspectorState, getInitialInspectorState, } from '@pikku/inspector';
|
|
6
6
|
import { glob } from 'tinyglobby';
|
|
7
7
|
import path from 'path';
|
|
8
8
|
import { CLILoggerForwarder, } from './services/cli-logger-forwarder.service.js';
|
|
9
9
|
import { readFile, writeFile } from 'fs/promises';
|
|
10
|
-
|
|
10
|
+
// Logger instance will be configured with log level from CLI flags in createConfig
|
|
11
|
+
// Logo will be displayed conditionally in createConfig based on --silent flag
|
|
12
|
+
const logger = new CLILogger({ logLogo: false, silent: false });
|
|
11
13
|
/**
|
|
12
14
|
* Parse a comma-separated string or array into an array of trimmed, non-empty strings
|
|
13
15
|
* Returns undefined if the input is empty/undefined or results in an empty array
|
|
@@ -63,7 +65,7 @@ function parseCLIFilters(data) {
|
|
|
63
65
|
/**
|
|
64
66
|
* Default CLI renderer that logs output using the logger
|
|
65
67
|
*/
|
|
66
|
-
export const defaultCLIRenderer = pikkuCLIRender((
|
|
68
|
+
export const defaultCLIRenderer = pikkuCLIRender(({ logger }, data) => {
|
|
67
69
|
if (data) {
|
|
68
70
|
logger[data.level]({ message: data.message, type: data.type });
|
|
69
71
|
}
|
|
@@ -72,14 +74,41 @@ export const defaultCLIRenderer = pikkuCLIRender((_services, data) => {
|
|
|
72
74
|
* Client-safe CLI renderer that outputs to console (no service dependencies)
|
|
73
75
|
* This renderer can be used in CLI-over-channel clients
|
|
74
76
|
*/
|
|
75
|
-
export const clientCLIRenderer = pikkuCLIRender((
|
|
77
|
+
export const clientCLIRenderer = pikkuCLIRender(({ logger }, data) => {
|
|
76
78
|
if (data) {
|
|
77
|
-
|
|
78
|
-
const prefix = data.type ? `[${data.type}] ` : '';
|
|
79
|
-
console.log(`${prefix}${data.message}`);
|
|
79
|
+
logger[data.level]?.({ message: data.message, type: data.type });
|
|
80
80
|
}
|
|
81
81
|
});
|
|
82
82
|
export const createConfig = async (_variablesService, data) => {
|
|
83
|
+
// Determine log level based on CLI flags with precedence:
|
|
84
|
+
// --silent > --loglevel > --verbose > --info > default (warn)
|
|
85
|
+
let logLevel = LogLevel.warn; // default
|
|
86
|
+
let isSilent = false;
|
|
87
|
+
if (data.silent) {
|
|
88
|
+
logLevel = LogLevel.critical;
|
|
89
|
+
isSilent = true;
|
|
90
|
+
}
|
|
91
|
+
else if (data.loglevel) {
|
|
92
|
+
const levelStr = data.loglevel;
|
|
93
|
+
if (LogLevel[levelStr] !== undefined) {
|
|
94
|
+
logLevel = LogLevel[levelStr];
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
logger.warn(`Invalid log level "${levelStr}". Valid levels: trace, debug, info, warn, error, critical. Using default (warn).`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
else if (data.verbose) {
|
|
101
|
+
logLevel = LogLevel.debug;
|
|
102
|
+
}
|
|
103
|
+
else if (data.info) {
|
|
104
|
+
logLevel = LogLevel.info;
|
|
105
|
+
}
|
|
106
|
+
logger.setLevel(logLevel);
|
|
107
|
+
logger.setSilent(isSilent);
|
|
108
|
+
// Display logo unless in silent mode
|
|
109
|
+
if (!isSilent) {
|
|
110
|
+
logger.logLogo();
|
|
111
|
+
}
|
|
83
112
|
const cliConfig = await getPikkuCLIConfig(logger, data.configFile, [], true);
|
|
84
113
|
// Load inspector state from file if stateInput is provided
|
|
85
114
|
let preloadedInspectorState = undefined;
|
|
@@ -112,13 +141,49 @@ export const createSingletonServices = async (config) => {
|
|
|
112
141
|
const variables = new LocalVariablesService();
|
|
113
142
|
// Store unfiltered state
|
|
114
143
|
let unfilteredState = preloadedInspectorState;
|
|
115
|
-
const getInspectorState = async (refresh = false) => {
|
|
144
|
+
const getInspectorState = async (refresh = false, setupOnly = false, bootstrapMode = false) => {
|
|
145
|
+
// In bootstrap mode, return a minimal "zero state" with core types
|
|
146
|
+
// This allows bootstrap to run immediately without inspecting the codebase
|
|
147
|
+
if (bootstrapMode) {
|
|
148
|
+
const corePackagePath = '@pikku/core';
|
|
149
|
+
const initialState = getInitialInspectorState(rootDir);
|
|
150
|
+
// Populate filesAndMethods with core types from @pikku/core
|
|
151
|
+
initialState.filesAndMethods = {
|
|
152
|
+
userSessionType: {
|
|
153
|
+
file: corePackagePath,
|
|
154
|
+
variable: 'CoreUserSession',
|
|
155
|
+
type: 'CoreUserSession',
|
|
156
|
+
typePath: corePackagePath,
|
|
157
|
+
},
|
|
158
|
+
sessionServicesType: {
|
|
159
|
+
file: corePackagePath,
|
|
160
|
+
variable: 'CoreServices',
|
|
161
|
+
type: 'CoreServices',
|
|
162
|
+
typePath: corePackagePath,
|
|
163
|
+
},
|
|
164
|
+
singletonServicesType: {
|
|
165
|
+
file: corePackagePath,
|
|
166
|
+
variable: 'CoreSingletonServices',
|
|
167
|
+
type: 'CoreSingletonServices',
|
|
168
|
+
typePath: corePackagePath,
|
|
169
|
+
},
|
|
170
|
+
pikkuConfigType: {
|
|
171
|
+
file: corePackagePath,
|
|
172
|
+
variable: 'CoreConfig',
|
|
173
|
+
type: 'CoreConfig',
|
|
174
|
+
typePath: corePackagePath,
|
|
175
|
+
},
|
|
176
|
+
};
|
|
177
|
+
return initialState;
|
|
178
|
+
}
|
|
116
179
|
// Get or refresh the unfiltered state
|
|
117
180
|
if (!unfilteredState || refresh) {
|
|
118
181
|
// Run inspector WITHOUT filters to get full state
|
|
119
|
-
const wiringFiles = (await Promise.all(srcDirectories.map((dir) => glob(`${path.join(rootDir, dir)}/**/*.ts
|
|
120
|
-
|
|
121
|
-
|
|
182
|
+
const wiringFiles = (await Promise.all(srcDirectories.map((dir) => glob(`${path.join(rootDir, dir)}/**/*.ts`, {
|
|
183
|
+
ignore: config.ignoreFiles || [],
|
|
184
|
+
})))).flat();
|
|
185
|
+
unfilteredState = inspect(logger, wiringFiles, {
|
|
186
|
+
setupOnly,
|
|
122
187
|
types: {
|
|
123
188
|
configFileType: config.configFile,
|
|
124
189
|
userSessionType: config.userSessionType,
|