@pikku/cli 0.7.4 → 0.7.6

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 CHANGED
@@ -1,5 +1,27 @@
1
1
  # @pikku/cli
2
2
 
3
+ ## 0.7.6
4
+
5
+ ### Patch Changes
6
+
7
+ - 8b4f52e: refactor: moving schemas in channels to functions
8
+ - 1d70184: feat: adding multiple bootstrap files for different transports
9
+ - 5c4f56f: fix: adding more options to schema generator to support complex types
10
+ - a9427b8: fix: import bootstrap file to include all rpc/function code in nextjs wrapper
11
+ - Updated dependencies [8b4f52e]
12
+ - Updated dependencies [8b4f52e]
13
+ - Updated dependencies [1d70184]
14
+ - @pikku/core@0.7.8
15
+ - @pikku/inspector@0.7.7
16
+
17
+ ## 0.7.5
18
+
19
+ ### Patch Changes
20
+
21
+ - faa1369: refactor: moving function imports into pikku-fun.gen file
22
+ - Updated dependencies [faa1369]
23
+ - @pikku/inspector@0.7.6
24
+
3
25
  ## 0.7.4
4
26
 
5
27
  ### Patch Changes
package/bin/pikku-all.ts CHANGED
@@ -24,16 +24,39 @@ import chokidar from 'chokidar'
24
24
  import { pikkuFunctions } from './pikku-functions.js'
25
25
  import { pikkuRPC } from './pikku-rpc.js'
26
26
  import { pikkuRPCMap } from './pikku-rpc-map.js'
27
+ import { PikkuEventTypes } from '@pikku/core'
27
28
 
28
29
  const runAll = async (cliConfig: PikkuCLIConfig, options: PikkuCLIOptions) => {
29
- const metaImports: string[] = []
30
- const imports: string[] = []
31
- const addImport = (from: string, type: 'meta' | 'events' | 'other') => {
30
+ const boostrapImports: Partial<
31
+ Record<PikkuEventTypes, { meta: string[]; events: string[] }>
32
+ > & { all: { meta: string[]; events: string[] } } = {
33
+ all: { meta: [], events: [] },
34
+ }
35
+
36
+ const addImport = (
37
+ from: string,
38
+ type: 'meta' | 'events' | 'other',
39
+ addTo?: PikkuEventTypes[]
40
+ ) => {
32
41
  const statement = `import '${getFileImportRelativePath(cliConfig.bootstrapFile, from, cliConfig.packageMappings)}'`
33
42
  if (type === 'meta') {
34
- metaImports.push(statement)
43
+ boostrapImports.all.meta.push(statement)
35
44
  } else {
36
- imports.push(statement)
45
+ boostrapImports.all.events.push(statement)
46
+ }
47
+
48
+ for (const transport of Object.keys(PikkuEventTypes)) {
49
+ if (!addTo || addTo?.includes(transport as PikkuEventTypes)) {
50
+ boostrapImports[transport] = boostrapImports[transport] || {
51
+ meta: [],
52
+ events: [],
53
+ }
54
+ if (type === 'meta') {
55
+ boostrapImports[transport].meta.push(statement)
56
+ } else {
57
+ boostrapImports[transport].events.push(statement)
58
+ }
59
+ }
37
60
  }
38
61
  }
39
62
 
@@ -69,34 +92,33 @@ const runAll = async (cliConfig: PikkuCLIConfig, options: PikkuCLIOptions) => {
69
92
 
70
93
  await pikkuRPC(cliConfig, visitState)
71
94
  await pikkuRPCMap(cliConfig, visitState)
72
- addImport(cliConfig.rpcMetaFile, 'meta')
73
- addImport(cliConfig.rpcFile, 'events')
95
+ addImport(cliConfig.rpcMetaFile, 'meta', [PikkuEventTypes.rpc])
96
+
97
+ const schemas = await pikkuSchemas(cliConfig, visitState)
98
+ if (schemas) {
99
+ addImport(`${cliConfig.schemaDirectory}/register.gen.ts`, 'other')
100
+ }
74
101
 
75
- const routes = await pikkuHTTP(cliConfig, visitState)
76
- if (routes) {
102
+ const http = await pikkuHTTP(cliConfig, visitState)
103
+ if (http) {
77
104
  await pikkuHTTPMap(cliConfig, visitState)
78
105
  await pikkuFetch(cliConfig)
79
- addImport(cliConfig.httpRoutesMetaFile, 'meta')
80
- addImport(cliConfig.httpRoutesFile, 'events')
106
+ addImport(cliConfig.httpRoutesMetaFile, 'meta', [PikkuEventTypes.http])
107
+ addImport(cliConfig.httpRoutesFile, 'events', [PikkuEventTypes.http])
81
108
  }
82
109
 
83
110
  const scheduled = await pikkuScheduler(cliConfig, visitState)
84
111
  if (scheduled) {
85
- addImport(cliConfig.schedulersMetaFile, 'meta')
86
- addImport(cliConfig.schedulersFile, 'events')
112
+ addImport(cliConfig.schedulersMetaFile, 'meta', [PikkuEventTypes.scheduled])
113
+ addImport(cliConfig.schedulersFile, 'events', [PikkuEventTypes.scheduled])
87
114
  }
88
115
 
89
116
  const channels = await pikkuChannels(cliConfig, visitState)
90
117
  if (channels) {
91
118
  await pikkuChannelsMap(cliConfig, visitState)
92
119
  await pikkuWebSocket(cliConfig)
93
- addImport(cliConfig.channelsMetaFile, 'meta')
94
- addImport(cliConfig.channelsFile, 'events')
95
- }
96
-
97
- const schemas = await pikkuSchemas(cliConfig, visitState)
98
- if (schemas) {
99
- addImport(`${cliConfig.schemaDirectory}/register.gen.ts`, 'other')
120
+ addImport(cliConfig.channelsMetaFile, 'meta', [PikkuEventTypes.channel])
121
+ addImport(cliConfig.channelsFile, 'events', [PikkuEventTypes.channel])
100
122
  }
101
123
 
102
124
  if (cliConfig.nextBackendFile || cliConfig.nextHTTPFile) {
@@ -113,10 +135,12 @@ const runAll = async (cliConfig: PikkuCLIConfig, options: PikkuCLIOptions) => {
113
135
  await pikkuOpenAPI(cliConfig, visitState)
114
136
  }
115
137
 
116
- await writeFileInDir(
117
- cliConfig.bootstrapFile,
118
- [...metaImports, ...imports].join('\n')
119
- )
138
+ for (const [type, { meta, events }] of Object.entries(boostrapImports)) {
139
+ await writeFileInDir(
140
+ type === 'all' ? cliConfig.bootstrapFile : cliConfig.bootstrapFiles[type],
141
+ [...meta, ...events].join('\n')
142
+ )
143
+ }
120
144
  }
121
145
 
122
146
  const watch = (cliConfig: PikkuCLIConfig, options: PikkuCLIOptions) => {
@@ -16,6 +16,7 @@ export const pikkuChannelsMap = async (
16
16
  channelsMapDeclarationFile,
17
17
  packageMappings,
18
18
  state.functions.typesMap,
19
+ state.functions.meta,
19
20
  state.channels.meta
20
21
  )
21
22
  await writeFileInDir(channelsMapDeclarationFile, content)
@@ -1,9 +1,62 @@
1
1
  import { PikkuCLIConfig } from '../src/pikku-cli-config.js'
2
2
  import { InspectorState } from '@pikku/inspector'
3
- import { logCommandInfoAndTime, writeFileInDir } from '../src/utils/utils.js'
3
+ import {
4
+ getFileImportRelativePath,
5
+ logCommandInfoAndTime,
6
+ writeFileInDir,
7
+ } from '../src/utils/utils.js'
8
+
9
+ export const serializeFunctionImports = (
10
+ outputPath: string,
11
+ functionsMap: Map<string, { path: string; exportedName: string }>,
12
+ packageMappings: Record<string, string> = {}
13
+ ) => {
14
+ const serializedImports: string[] = [
15
+ `/* Import and register RPCs */`,
16
+ `import { addFunction } from '@pikku/core'`,
17
+ ]
18
+
19
+ const serializedRegistrations: string[] = []
20
+
21
+ // Sort by function name for consistent output
22
+ const sortedEntries = Array.from(functionsMap.entries()).sort((a, b) =>
23
+ a[0].localeCompare(b[0])
24
+ )
25
+
26
+ for (const [name, { path, exportedName }] of sortedEntries) {
27
+ const filePath = getFileImportRelativePath(
28
+ outputPath,
29
+ path,
30
+ packageMappings
31
+ )
32
+
33
+ // For directly exported functions, we can just import and register them
34
+ if (name === exportedName) {
35
+ serializedImports.push(`import { ${exportedName} } from '${filePath}'`)
36
+ serializedRegistrations.push(
37
+ `addFunction('${name}', { func: ${exportedName} })`
38
+ )
39
+ }
40
+ // For renamed functions, we need to import and alias them
41
+ else {
42
+ serializedImports.push(
43
+ `import { ${exportedName} as ${name} } from '${filePath}'`
44
+ )
45
+ serializedRegistrations.push(`addFunction('${name}', ${name})`)
46
+ }
47
+ }
48
+
49
+ // Add a blank line between imports and registrations
50
+ if (serializedImports.length > 0 && serializedRegistrations.length > 0) {
51
+ serializedImports.push('')
52
+ }
53
+
54
+ // Combine the imports and registrations
55
+ return [...serializedImports, ...serializedRegistrations].join('\n')
56
+ }
4
57
 
5
58
  export const pikkuFunctions = async (
6
- { functionsMetaFile }: PikkuCLIConfig,
59
+ { functionsMetaFile, functionsFile, packageMappings }: PikkuCLIConfig,
7
60
  { functions }: InspectorState
8
61
  ) => {
9
62
  return await logCommandInfoAndTime(
@@ -11,6 +64,14 @@ export const pikkuFunctions = async (
11
64
  'Serialized Pikku functions',
12
65
  [false],
13
66
  async () => {
67
+ await writeFileInDir(
68
+ functionsFile,
69
+ serializeFunctionImports(
70
+ functionsFile,
71
+ functions.files,
72
+ packageMappings
73
+ )
74
+ )
14
75
  await writeFileInDir(
15
76
  functionsMetaFile,
16
77
  `import { pikkuState } from '@pikku/core'\npikkuState('function', 'meta', ${JSON.stringify(functions.meta, null, 2)})`
@@ -17,11 +17,10 @@ export const pikkuNext = async (
17
17
  {
18
18
  nextBackendFile,
19
19
  nextHTTPFile,
20
- httpRoutesFile,
21
20
  httpRoutesMapDeclarationFile,
22
- schemaDirectory,
23
21
  packageMappings,
24
22
  fetchFile,
23
+ bootstrapFiles,
25
24
  }: PikkuCLIConfig,
26
25
  visitState: InspectorState,
27
26
  options: PikkuCLIOptions
@@ -67,9 +66,9 @@ export const pikkuNext = async (
67
66
  const singletonServicesImport = `import { ${singletonServicesFactory.variable} as createSingletonServices } from '${getFileImportRelativePath(nextBackendFile, singletonServicesFactory.file, packageMappings)}'`
68
67
  const sessionServicesImport = `import { ${sessionServicesFactory.variable} as createSessionServices } from '${getFileImportRelativePath(nextBackendFile, sessionServicesFactory.file, packageMappings)}'`
69
68
 
70
- const routesPath = getFileImportRelativePath(
69
+ const httpBootstrapPath = getFileImportRelativePath(
71
70
  nextBackendFile,
72
- httpRoutesFile,
71
+ bootstrapFiles.http,
73
72
  packageMappings
74
73
  )
75
74
 
@@ -78,16 +77,10 @@ export const pikkuNext = async (
78
77
  httpRoutesMapDeclarationFile,
79
78
  packageMappings
80
79
  )
81
- const schemasPath = getFileImportRelativePath(
82
- nextBackendFile,
83
- `${schemaDirectory}/register.gen.ts`,
84
- packageMappings
85
- )
86
80
 
87
81
  const content = serializeNextBackendWrapper(
88
- routesPath,
82
+ httpBootstrapPath,
89
83
  routesMapDeclarationPath,
90
- schemasPath,
91
84
  pikkuConfigImport,
92
85
  singletonServicesImport,
93
86
  sessionServicesImport
@@ -95,22 +88,22 @@ export const pikkuNext = async (
95
88
  await writeFileInDir(nextBackendFile, content)
96
89
  }
97
90
 
98
- if (nextHTTPFile) {
99
- const routesPath = getFileImportRelativePath(
91
+ if (nextHTTPFile && fetchFile) {
92
+ const routesMapDeclarationPath = getFileImportRelativePath(
100
93
  nextHTTPFile,
101
- httpRoutesFile,
94
+ httpRoutesMapDeclarationFile,
102
95
  packageMappings
103
96
  )
104
97
 
105
- const routesMapDeclarationPath = getFileImportRelativePath(
98
+ const fetchPath = getFileImportRelativePath(
106
99
  nextHTTPFile,
107
- httpRoutesMapDeclarationFile,
100
+ fetchFile,
108
101
  packageMappings
109
102
  )
110
103
 
111
104
  const content = serializeNextHTTPWrapper(
112
- routesPath,
113
- routesMapDeclarationPath
105
+ routesMapDeclarationPath,
106
+ fetchPath
114
107
  )
115
108
  await writeFileInDir(nextHTTPFile, content)
116
109
  }
@@ -10,7 +10,7 @@ export const pikkuRPCMap = async (
10
10
  return await logCommandInfoAndTime(
11
11
  'Creating RPC map',
12
12
  'Created RPC map',
13
- [rpc.files.size === 0],
13
+ [false],
14
14
  async () => {
15
15
  const content = serializeTypedRPCMap(
16
16
  rpcMapDeclarationFile,
package/bin/pikku-rpc.ts CHANGED
@@ -1,73 +1,16 @@
1
1
  import { PikkuCLIConfig } from '../src/pikku-cli-config.js'
2
2
  import { InspectorState } from '@pikku/inspector'
3
- import {
4
- getFileImportRelativePath,
5
- logCommandInfoAndTime,
6
- writeFileInDir,
7
- } from '../src/utils/utils.js'
8
-
9
- export const serializeRPCImports = (
10
- outputPath: string,
11
- functionsMap: Map<string, { path: string; exportedName: string }>,
12
- packageMappings: Record<string, string> = {}
13
- ) => {
14
- const serializedImports: string[] = [
15
- `/* Import and register RPCs */`,
16
- `import { addFunction } from '@pikku/core'`,
17
- ]
18
-
19
- const serializedRegistrations: string[] = []
20
-
21
- // Sort by function name for consistent output
22
- const sortedEntries = Array.from(functionsMap.entries()).sort((a, b) =>
23
- a[0].localeCompare(b[0])
24
- )
25
-
26
- for (const [name, { path, exportedName }] of sortedEntries) {
27
- const filePath = getFileImportRelativePath(
28
- outputPath,
29
- path,
30
- packageMappings
31
- )
32
-
33
- // For directly exported functions, we can just import and register them
34
- if (name === exportedName) {
35
- serializedImports.push(`import { ${exportedName} } from '${filePath}'`)
36
- serializedRegistrations.push(
37
- `addFunction('${name}', { func: ${exportedName} })`
38
- )
39
- }
40
- // For renamed functions, we need to import and alias them
41
- else {
42
- serializedImports.push(
43
- `import { ${exportedName} as ${name} } from '${filePath}'`
44
- )
45
- serializedRegistrations.push(`addFunction('${name}', ${name})`)
46
- }
47
- }
48
-
49
- // Add a blank line between imports and registrations
50
- if (serializedImports.length > 0 && serializedRegistrations.length > 0) {
51
- serializedImports.push('')
52
- }
53
-
54
- // Combine the imports and registrations
55
- return [...serializedImports, ...serializedRegistrations].join('\n')
56
- }
3
+ import { logCommandInfoAndTime, writeFileInDir } from '../src/utils/utils.js'
57
4
 
58
5
  export const pikkuRPC = async (
59
- { rpcFile, rpcMetaFile, packageMappings }: PikkuCLIConfig,
6
+ { rpcMetaFile }: PikkuCLIConfig,
60
7
  { rpc }: InspectorState
61
8
  ) => {
62
9
  return await logCommandInfoAndTime(
63
10
  'Finding RPCs tasks',
64
11
  'Found RPCs',
65
- [rpc.files.size === 0],
12
+ [false],
66
13
  async () => {
67
- await writeFileInDir(
68
- rpcFile,
69
- serializeRPCImports(rpcFile, rpc.files, packageMappings)
70
- )
71
14
  await writeFileInDir(
72
15
  rpcMetaFile,
73
16
  `import { pikkuState } from '@pikku/core'\npikkuState('rpc', 'meta', ${JSON.stringify(rpc.meta, null, 2)})`
@@ -17,16 +17,32 @@ import chokidar from 'chokidar';
17
17
  import { pikkuFunctions } from './pikku-functions.js';
18
18
  import { pikkuRPC } from './pikku-rpc.js';
19
19
  import { pikkuRPCMap } from './pikku-rpc-map.js';
20
+ import { PikkuEventTypes } from '@pikku/core';
20
21
  const runAll = async (cliConfig, options) => {
21
- const metaImports = [];
22
- const imports = [];
23
- const addImport = (from, type) => {
22
+ const boostrapImports = {
23
+ all: { meta: [], events: [] },
24
+ };
25
+ const addImport = (from, type, addTo) => {
24
26
  const statement = `import '${getFileImportRelativePath(cliConfig.bootstrapFile, from, cliConfig.packageMappings)}'`;
25
27
  if (type === 'meta') {
26
- metaImports.push(statement);
28
+ boostrapImports.all.meta.push(statement);
27
29
  }
28
30
  else {
29
- imports.push(statement);
31
+ boostrapImports.all.events.push(statement);
32
+ }
33
+ for (const transport of Object.keys(PikkuEventTypes)) {
34
+ if (!addTo || addTo?.includes(transport)) {
35
+ boostrapImports[transport] = boostrapImports[transport] || {
36
+ meta: [],
37
+ events: [],
38
+ };
39
+ if (type === 'meta') {
40
+ boostrapImports[transport].meta.push(statement);
41
+ }
42
+ else {
43
+ boostrapImports[transport].events.push(statement);
44
+ }
45
+ }
30
46
  }
31
47
  };
32
48
  let typesDeclarationFileExists = true;
@@ -49,30 +65,29 @@ const runAll = async (cliConfig, options) => {
49
65
  addImport(cliConfig.functionsFile, 'events');
50
66
  await pikkuRPC(cliConfig, visitState);
51
67
  await pikkuRPCMap(cliConfig, visitState);
52
- addImport(cliConfig.rpcMetaFile, 'meta');
53
- addImport(cliConfig.rpcFile, 'events');
54
- const routes = await pikkuHTTP(cliConfig, visitState);
55
- if (routes) {
68
+ addImport(cliConfig.rpcMetaFile, 'meta', [PikkuEventTypes.rpc]);
69
+ const schemas = await pikkuSchemas(cliConfig, visitState);
70
+ if (schemas) {
71
+ addImport(`${cliConfig.schemaDirectory}/register.gen.ts`, 'other');
72
+ }
73
+ const http = await pikkuHTTP(cliConfig, visitState);
74
+ if (http) {
56
75
  await pikkuHTTPMap(cliConfig, visitState);
57
76
  await pikkuFetch(cliConfig);
58
- addImport(cliConfig.httpRoutesMetaFile, 'meta');
59
- addImport(cliConfig.httpRoutesFile, 'events');
77
+ addImport(cliConfig.httpRoutesMetaFile, 'meta', [PikkuEventTypes.http]);
78
+ addImport(cliConfig.httpRoutesFile, 'events', [PikkuEventTypes.http]);
60
79
  }
61
80
  const scheduled = await pikkuScheduler(cliConfig, visitState);
62
81
  if (scheduled) {
63
- addImport(cliConfig.schedulersMetaFile, 'meta');
64
- addImport(cliConfig.schedulersFile, 'events');
82
+ addImport(cliConfig.schedulersMetaFile, 'meta', [PikkuEventTypes.scheduled]);
83
+ addImport(cliConfig.schedulersFile, 'events', [PikkuEventTypes.scheduled]);
65
84
  }
66
85
  const channels = await pikkuChannels(cliConfig, visitState);
67
86
  if (channels) {
68
87
  await pikkuChannelsMap(cliConfig, visitState);
69
88
  await pikkuWebSocket(cliConfig);
70
- addImport(cliConfig.channelsMetaFile, 'meta');
71
- addImport(cliConfig.channelsFile, 'events');
72
- }
73
- const schemas = await pikkuSchemas(cliConfig, visitState);
74
- if (schemas) {
75
- addImport(`${cliConfig.schemaDirectory}/register.gen.ts`, 'other');
89
+ addImport(cliConfig.channelsMetaFile, 'meta', [PikkuEventTypes.channel]);
90
+ addImport(cliConfig.channelsFile, 'events', [PikkuEventTypes.channel]);
76
91
  }
77
92
  if (cliConfig.nextBackendFile || cliConfig.nextHTTPFile) {
78
93
  await pikkuNext(cliConfig, visitState, options);
@@ -82,7 +97,9 @@ const runAll = async (cliConfig, options) => {
82
97
  visitState = await inspectorGlob(cliConfig.rootDir, cliConfig.srcDirectories, cliConfig.filters);
83
98
  await pikkuOpenAPI(cliConfig, visitState);
84
99
  }
85
- await writeFileInDir(cliConfig.bootstrapFile, [...metaImports, ...imports].join('\n'));
100
+ for (const [type, { meta, events }] of Object.entries(boostrapImports)) {
101
+ await writeFileInDir(type === 'all' ? cliConfig.bootstrapFile : cliConfig.bootstrapFiles[type], [...meta, ...events].join('\n'));
102
+ }
86
103
  };
87
104
  const watch = (cliConfig, options) => {
88
105
  const configWatcher = chokidar.watch(cliConfig.srcDirectories, {
@@ -2,7 +2,7 @@ import { logCommandInfoAndTime, writeFileInDir } from '../src/utils/utils.js';
2
2
  import { serializeTypedChannelsMap } from '../src/serialize-typed-channel-map.js';
3
3
  export const pikkuChannelsMap = async ({ channelsMapDeclarationFile, packageMappings }, state) => {
4
4
  return await logCommandInfoAndTime('Creating channels map', 'Created channels map', [state.channels.files.size === 0], async () => {
5
- const content = serializeTypedChannelsMap(channelsMapDeclarationFile, packageMappings, state.functions.typesMap, state.channels.meta);
5
+ const content = serializeTypedChannelsMap(channelsMapDeclarationFile, packageMappings, state.functions.typesMap, state.functions.meta, state.channels.meta);
6
6
  await writeFileInDir(channelsMapDeclarationFile, content);
7
7
  });
8
8
  };
@@ -1,3 +1,7 @@
1
1
  import { PikkuCLIConfig } from '../src/pikku-cli-config.js';
2
2
  import { InspectorState } from '@pikku/inspector';
3
- export declare const pikkuFunctions: ({ functionsMetaFile }: PikkuCLIConfig, { functions }: InspectorState) => Promise<boolean>;
3
+ export declare const serializeFunctionImports: (outputPath: string, functionsMap: Map<string, {
4
+ path: string;
5
+ exportedName: string;
6
+ }>, packageMappings?: Record<string, string>) => string;
7
+ export declare const pikkuFunctions: ({ functionsMetaFile, functionsFile, packageMappings }: PikkuCLIConfig, { functions }: InspectorState) => Promise<boolean>;
@@ -1,6 +1,35 @@
1
- import { logCommandInfoAndTime, writeFileInDir } from '../src/utils/utils.js';
2
- export const pikkuFunctions = async ({ functionsMetaFile }, { functions }) => {
1
+ import { getFileImportRelativePath, logCommandInfoAndTime, writeFileInDir, } from '../src/utils/utils.js';
2
+ export const serializeFunctionImports = (outputPath, functionsMap, packageMappings = {}) => {
3
+ const serializedImports = [
4
+ `/* Import and register RPCs */`,
5
+ `import { addFunction } from '@pikku/core'`,
6
+ ];
7
+ const serializedRegistrations = [];
8
+ // Sort by function name for consistent output
9
+ const sortedEntries = Array.from(functionsMap.entries()).sort((a, b) => a[0].localeCompare(b[0]));
10
+ for (const [name, { path, exportedName }] of sortedEntries) {
11
+ const filePath = getFileImportRelativePath(outputPath, path, packageMappings);
12
+ // For directly exported functions, we can just import and register them
13
+ if (name === exportedName) {
14
+ serializedImports.push(`import { ${exportedName} } from '${filePath}'`);
15
+ serializedRegistrations.push(`addFunction('${name}', { func: ${exportedName} })`);
16
+ }
17
+ // For renamed functions, we need to import and alias them
18
+ else {
19
+ serializedImports.push(`import { ${exportedName} as ${name} } from '${filePath}'`);
20
+ serializedRegistrations.push(`addFunction('${name}', ${name})`);
21
+ }
22
+ }
23
+ // Add a blank line between imports and registrations
24
+ if (serializedImports.length > 0 && serializedRegistrations.length > 0) {
25
+ serializedImports.push('');
26
+ }
27
+ // Combine the imports and registrations
28
+ return [...serializedImports, ...serializedRegistrations].join('\n');
29
+ };
30
+ export const pikkuFunctions = async ({ functionsMetaFile, functionsFile, packageMappings }, { functions }) => {
3
31
  return await logCommandInfoAndTime('Serializing Pikku functions', 'Serialized Pikku functions', [false], async () => {
32
+ await writeFileInDir(functionsFile, serializeFunctionImports(functionsFile, functions.files, packageMappings));
4
33
  await writeFileInDir(functionsMetaFile, `import { pikkuState } from '@pikku/core'\npikkuState('function', 'meta', ${JSON.stringify(functions.meta, null, 2)})`);
5
34
  });
6
35
  };
@@ -2,6 +2,6 @@ import { Command } from 'commander';
2
2
  import { PikkuCLIOptions } from '../src/utils/utils.js';
3
3
  import { PikkuCLIConfig } from '../src/pikku-cli-config.js';
4
4
  import { InspectorState } from '@pikku/inspector';
5
- export declare const pikkuNext: ({ nextBackendFile, nextHTTPFile, httpRoutesFile, httpRoutesMapDeclarationFile, schemaDirectory, packageMappings, fetchFile, }: PikkuCLIConfig, visitState: InspectorState, options: PikkuCLIOptions) => Promise<boolean>;
5
+ export declare const pikkuNext: ({ nextBackendFile, nextHTTPFile, httpRoutesMapDeclarationFile, packageMappings, fetchFile, bootstrapFiles, }: PikkuCLIConfig, visitState: InspectorState, options: PikkuCLIOptions) => Promise<boolean>;
6
6
  export declare const action: (options: PikkuCLIOptions) => Promise<void>;
7
7
  export declare const nextjs: (program: Command) => void;
@@ -3,7 +3,7 @@ import { serializeNextJsHTTPWrapper as serializeNextHTTPWrapper } from '../src/s
3
3
  import { getFileImportRelativePath, getPikkuFilesAndMethods, logCommandInfoAndTime, logPikkuLogo, writeFileInDir, } from '../src/utils/utils.js';
4
4
  import { getPikkuCLIConfig } from '../src/pikku-cli-config.js';
5
5
  import { inspectorGlob } from '../src/inspector-glob.js';
6
- export const pikkuNext = async ({ nextBackendFile, nextHTTPFile, httpRoutesFile, httpRoutesMapDeclarationFile, schemaDirectory, packageMappings, fetchFile, }, visitState, options) => {
6
+ export const pikkuNext = async ({ nextBackendFile, nextHTTPFile, httpRoutesMapDeclarationFile, packageMappings, fetchFile, bootstrapFiles, }, visitState, options) => {
7
7
  return await logCommandInfoAndTime('Generating nextjs wrapper', 'Generated nextjs wrapper', [
8
8
  nextBackendFile === undefined && nextHTTPFile === undefined,
9
9
  'nextjs outfile is not defined',
@@ -23,16 +23,15 @@ export const pikkuNext = async ({ nextBackendFile, nextHTTPFile, httpRoutesFile,
23
23
  const pikkuConfigImport = `import { ${pikkuConfigFactory.variable} as createConfig } from '${getFileImportRelativePath(nextBackendFile, pikkuConfigFactory.file, packageMappings)}'`;
24
24
  const singletonServicesImport = `import { ${singletonServicesFactory.variable} as createSingletonServices } from '${getFileImportRelativePath(nextBackendFile, singletonServicesFactory.file, packageMappings)}'`;
25
25
  const sessionServicesImport = `import { ${sessionServicesFactory.variable} as createSessionServices } from '${getFileImportRelativePath(nextBackendFile, sessionServicesFactory.file, packageMappings)}'`;
26
- const routesPath = getFileImportRelativePath(nextBackendFile, httpRoutesFile, packageMappings);
26
+ const httpBootstrapPath = getFileImportRelativePath(nextBackendFile, bootstrapFiles.http, packageMappings);
27
27
  const routesMapDeclarationPath = getFileImportRelativePath(nextBackendFile, httpRoutesMapDeclarationFile, packageMappings);
28
- const schemasPath = getFileImportRelativePath(nextBackendFile, `${schemaDirectory}/register.gen.ts`, packageMappings);
29
- const content = serializeNextBackendWrapper(routesPath, routesMapDeclarationPath, schemasPath, pikkuConfigImport, singletonServicesImport, sessionServicesImport);
28
+ const content = serializeNextBackendWrapper(httpBootstrapPath, routesMapDeclarationPath, pikkuConfigImport, singletonServicesImport, sessionServicesImport);
30
29
  await writeFileInDir(nextBackendFile, content);
31
30
  }
32
- if (nextHTTPFile) {
33
- const routesPath = getFileImportRelativePath(nextHTTPFile, httpRoutesFile, packageMappings);
31
+ if (nextHTTPFile && fetchFile) {
34
32
  const routesMapDeclarationPath = getFileImportRelativePath(nextHTTPFile, httpRoutesMapDeclarationFile, packageMappings);
35
- const content = serializeNextHTTPWrapper(routesPath, routesMapDeclarationPath);
33
+ const fetchPath = getFileImportRelativePath(nextHTTPFile, fetchFile, packageMappings);
34
+ const content = serializeNextHTTPWrapper(routesMapDeclarationPath, fetchPath);
36
35
  await writeFileInDir(nextHTTPFile, content);
37
36
  }
38
37
  });
@@ -1,7 +1,7 @@
1
1
  import { logCommandInfoAndTime, writeFileInDir } from '../src/utils/utils.js';
2
2
  import { serializeTypedRPCMap } from '../src/serialize-typed-rpc-map.js';
3
3
  export const pikkuRPCMap = async ({ rpcMapDeclarationFile, packageMappings }, { functions, rpc }) => {
4
- return await logCommandInfoAndTime('Creating RPC map', 'Created RPC map', [rpc.files.size === 0], async () => {
4
+ return await logCommandInfoAndTime('Creating RPC map', 'Created RPC map', [false], async () => {
5
5
  const content = serializeTypedRPCMap(rpcMapDeclarationFile, packageMappings, functions.typesMap, functions.meta, rpc.meta);
6
6
  await writeFileInDir(rpcMapDeclarationFile, content);
7
7
  });
@@ -1,7 +1,3 @@
1
1
  import { PikkuCLIConfig } from '../src/pikku-cli-config.js';
2
2
  import { InspectorState } from '@pikku/inspector';
3
- export declare const serializeRPCImports: (outputPath: string, functionsMap: Map<string, {
4
- path: string;
5
- exportedName: string;
6
- }>, packageMappings?: Record<string, string>) => string;
7
- export declare const pikkuRPC: ({ rpcFile, rpcMetaFile, packageMappings }: PikkuCLIConfig, { rpc }: InspectorState) => Promise<boolean>;
3
+ export declare const pikkuRPC: ({ rpcMetaFile }: PikkuCLIConfig, { rpc }: InspectorState) => Promise<boolean>;
@@ -1,35 +1,6 @@
1
- import { getFileImportRelativePath, logCommandInfoAndTime, writeFileInDir, } from '../src/utils/utils.js';
2
- export const serializeRPCImports = (outputPath, functionsMap, packageMappings = {}) => {
3
- const serializedImports = [
4
- `/* Import and register RPCs */`,
5
- `import { addFunction } from '@pikku/core'`,
6
- ];
7
- const serializedRegistrations = [];
8
- // Sort by function name for consistent output
9
- const sortedEntries = Array.from(functionsMap.entries()).sort((a, b) => a[0].localeCompare(b[0]));
10
- for (const [name, { path, exportedName }] of sortedEntries) {
11
- const filePath = getFileImportRelativePath(outputPath, path, packageMappings);
12
- // For directly exported functions, we can just import and register them
13
- if (name === exportedName) {
14
- serializedImports.push(`import { ${exportedName} } from '${filePath}'`);
15
- serializedRegistrations.push(`addFunction('${name}', { func: ${exportedName} })`);
16
- }
17
- // For renamed functions, we need to import and alias them
18
- else {
19
- serializedImports.push(`import { ${exportedName} as ${name} } from '${filePath}'`);
20
- serializedRegistrations.push(`addFunction('${name}', ${name})`);
21
- }
22
- }
23
- // Add a blank line between imports and registrations
24
- if (serializedImports.length > 0 && serializedRegistrations.length > 0) {
25
- serializedImports.push('');
26
- }
27
- // Combine the imports and registrations
28
- return [...serializedImports, ...serializedRegistrations].join('\n');
29
- };
30
- export const pikkuRPC = async ({ rpcFile, rpcMetaFile, packageMappings }, { rpc }) => {
31
- return await logCommandInfoAndTime('Finding RPCs tasks', 'Found RPCs', [rpc.files.size === 0], async () => {
32
- await writeFileInDir(rpcFile, serializeRPCImports(rpcFile, rpc.files, packageMappings));
1
+ import { logCommandInfoAndTime, writeFileInDir } from '../src/utils/utils.js';
2
+ export const pikkuRPC = async ({ rpcMetaFile }, { rpc }) => {
3
+ return await logCommandInfoAndTime('Finding RPCs tasks', 'Found RPCs', [false], async () => {
33
4
  await writeFileInDir(rpcMetaFile, `import { pikkuState } from '@pikku/core'\npikkuState('rpc', 'meta', ${JSON.stringify(rpc.meta, null, 2)})`);
34
5
  });
35
6
  };
@@ -1,5 +1,6 @@
1
1
  import { OpenAPISpecInfo } from './openapi-spec-generator.js';
2
2
  import { InspectorFilters } from '@pikku/inspector';
3
+ import { PikkuEventTypes } from '@pikku/core';
3
4
  export interface PikkuCLICoreOutputFiles {
4
5
  outDir?: string;
5
6
  schemaDirectory: string;
@@ -12,12 +13,12 @@ export interface PikkuCLICoreOutputFiles {
12
13
  channelsFile: string;
13
14
  channelsMetaFile: string;
14
15
  channelsMapDeclarationFile: string;
15
- rpcFile: string;
16
16
  rpcMetaFile: string;
17
17
  rpcMapDeclarationFile: string;
18
18
  schedulersFile: string;
19
19
  schedulersMetaFile: string;
20
20
  bootstrapFile: string;
21
+ bootstrapFiles: Record<PikkuEventTypes, string>;
21
22
  }
22
23
  export type PikkuCLIConfig = {
23
24
  $schema?: string;
@@ -1,5 +1,6 @@
1
1
  import { join, dirname, resolve, isAbsolute } from 'path';
2
2
  import { readdir, readFile } from 'fs/promises';
3
+ import { PikkuEventTypes } from '@pikku/core';
3
4
  const CONFIG_DIR_FILES = [
4
5
  'nextBackendFile',
5
6
  'nextHTTPFile',
@@ -62,9 +63,6 @@ const _getPikkuCLIConfig = async (configFile = undefined, requiredFields, tags =
62
63
  if (!result.functionsMetaFile) {
63
64
  result.functionsMetaFile = join(result.outDir, 'pikku-functions-meta.gen.ts');
64
65
  }
65
- if (!result.rpcFile) {
66
- result.rpcFile = join(result.outDir, 'pikku-rpc.gen.ts');
67
- }
68
66
  if (!result.rpcMetaFile) {
69
67
  result.rpcMetaFile = join(result.outDir, 'pikku-rpc-meta.gen.ts');
70
68
  }
@@ -101,6 +99,10 @@ const _getPikkuCLIConfig = async (configFile = undefined, requiredFields, tags =
101
99
  if (!result.bootstrapFile) {
102
100
  result.bootstrapFile = join(result.outDir, 'pikku-bootstrap.gen.ts');
103
101
  }
102
+ result.bootstrapFiles = result.bootstrapFiles || {};
103
+ for (const key of Object.keys(PikkuEventTypes)) {
104
+ result.bootstrapFiles[key] = join(result.outDir, `pikku-bootstrap-${key}.gen.ts`);
105
+ }
104
106
  }
105
107
  if (requiredFields.length > 0) {
106
108
  validateCLIConfig(result, requiredFields);
@@ -28,6 +28,12 @@ export async function generateSchemas(tsconfig, typesMap, functionMeta, httpRout
28
28
  skipTypeCheck: true,
29
29
  topRef: false,
30
30
  discriminatorType: 'open-api',
31
+ expose: 'export',
32
+ jsDoc: 'extended',
33
+ sortProps: true,
34
+ strictTuples: false,
35
+ encodeRefs: false,
36
+ additionalProperties: false,
31
37
  });
32
38
  const schemas = {};
33
39
  schemasSet.forEach((schema) => {
@@ -1 +1 @@
1
- export declare const serializeNextJsBackendWrapper: (routesPath: string, routesMapPath: string, schemasPath: string, configImport: string, singleServicesFactoryImport: string, sessionServicesImport: string) => string;
1
+ export declare const serializeNextJsBackendWrapper: (httpBootstrapPath: string, routesMapPath: string, configImport: string, singleServicesFactoryImport: string, sessionServicesImport: string) => string;
@@ -1,4 +1,4 @@
1
- export const serializeNextJsBackendWrapper = (routesPath, routesMapPath, schemasPath, configImport, singleServicesFactoryImport, sessionServicesImport) => {
1
+ export const serializeNextJsBackendWrapper = (httpBootstrapPath, routesMapPath, configImport, singleServicesFactoryImport, sessionServicesImport) => {
2
2
  return `'server-only'
3
3
 
4
4
  /**
@@ -12,8 +12,7 @@ ${configImport}
12
12
  ${singleServicesFactoryImport}
13
13
  ${sessionServicesImport}
14
14
 
15
- import '${routesPath}'
16
- import '${schemasPath}'
15
+ import '${httpBootstrapPath}'
17
16
 
18
17
  let _pikku: PikkuNextJS | undefined
19
18
 
@@ -1,3 +1,4 @@
1
1
  import { ChannelsMeta } from '@pikku/core/channel';
2
2
  import { TypesMap } from '@pikku/inspector';
3
- export declare const serializeTypedChannelsMap: (relativeToPath: string, packageMappings: Record<string, string>, typesMap: TypesMap, channelsMeta: ChannelsMeta) => string;
3
+ import { FunctionsMeta } from '@pikku/core';
4
+ export declare const serializeTypedChannelsMap: (relativeToPath: string, packageMappings: Record<string, string>, typesMap: TypesMap, functionsMeta: FunctionsMeta, channelsMeta: ChannelsMeta) => string;
@@ -1,7 +1,7 @@
1
1
  import { serializeImportMap } from './utils/serialize-import-map.js';
2
2
  import { generateCustomTypes } from './utils/utils.js';
3
- export const serializeTypedChannelsMap = (relativeToPath, packageMappings, typesMap, channelsMeta) => {
4
- const { channels, requiredTypes } = generateChannels(channelsMeta);
3
+ export const serializeTypedChannelsMap = (relativeToPath, packageMappings, typesMap, functionsMeta, channelsMeta) => {
4
+ const { channels, requiredTypes } = generateChannels(functionsMeta, channelsMeta);
5
5
  typesMap.customTypes.forEach(({ references }) => {
6
6
  for (const reference of references) {
7
7
  requiredTypes.add(reference);
@@ -38,21 +38,39 @@ export type ChannelRouteHandlerOf<
38
38
  : never;
39
39
  `;
40
40
  };
41
- function generateChannels(channelsMeta) {
41
+ function generateChannels(functionsMeta, channelsMeta) {
42
42
  const requiredTypes = new Set();
43
43
  const channelsObject = {};
44
44
  for (const meta of Object.values(channelsMeta)) {
45
45
  const { name, messageRoutes, message } = meta;
46
46
  if (!channelsObject[name]) {
47
- channelsObject[name] = { message, routes: {} };
47
+ channelsObject[name] = { message: null, routes: {} };
48
+ }
49
+ if (message) {
50
+ const func = functionsMeta[message.pikkuFuncName];
51
+ if (!func) {
52
+ throw new Error(`Function ${message.pikkuFuncName} not found in functionsMeta for channel ${name}`);
53
+ }
54
+ const inputTypes = func.inputs || null;
55
+ const outputTypes = func.outputs || null;
56
+ channelsObject[name].message = {
57
+ inputs: inputTypes,
58
+ outputs: outputTypes,
59
+ };
60
+ inputTypes?.forEach((type) => requiredTypes.add(type));
61
+ outputTypes?.forEach((type) => requiredTypes.add(type));
48
62
  }
49
63
  for (const [key, route] of Object.entries(messageRoutes)) {
50
64
  if (!channelsObject[name].routes[key]) {
51
65
  channelsObject[name].routes[key] = {};
52
66
  }
53
- for (const [method, { inputs, outputs }] of Object.entries(route)) {
54
- const inputTypes = inputs || null;
55
- const outputTypes = outputs || null;
67
+ for (const [method, { pikkuFuncName }] of Object.entries(route)) {
68
+ const func = functionsMeta[pikkuFuncName];
69
+ if (!func) {
70
+ throw new Error(`Function ${pikkuFuncName} not found in functionsMeta for channel ${name}, route ${key}, method ${method}`);
71
+ }
72
+ const inputTypes = func.inputs || null;
73
+ const outputTypes = func.outputs || null;
56
74
  channelsObject[name].routes[key][method] = {
57
75
  inputTypes,
58
76
  outputTypes,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pikku/cli",
3
- "version": "0.7.4",
3
+ "version": "0.7.6",
4
4
  "author": "yasser.fadl@gmail.com",
5
5
  "license": "MIT",
6
6
  "bin": {
@@ -22,8 +22,8 @@
22
22
  },
23
23
  "dependencies": {
24
24
  "@openapi-contrib/json-schema-to-openapi-schema": "^3.0.2",
25
- "@pikku/core": "^0.7.7",
26
- "@pikku/inspector": "^0.7.4",
25
+ "@pikku/core": "^0.7.8",
26
+ "@pikku/inspector": "^0.7.7",
27
27
  "@types/cookie": "^0.6.0",
28
28
  "@types/uuid": "^10.0.0",
29
29
  "chalk": "^5.4.1",
@@ -2,6 +2,7 @@ import { join, dirname, resolve, isAbsolute } from 'path'
2
2
  import { readdir, readFile } from 'fs/promises'
3
3
  import { OpenAPISpecInfo } from './openapi-spec-generator.js'
4
4
  import { InspectorFilters } from '@pikku/inspector'
5
+ import { PikkuEventTypes } from '@pikku/core'
5
6
 
6
7
  export interface PikkuCLICoreOutputFiles {
7
8
  // Base directory
@@ -26,7 +27,6 @@ export interface PikkuCLICoreOutputFiles {
26
27
  channelsMapDeclarationFile: string
27
28
 
28
29
  // RPC
29
- rpcFile: string
30
30
  rpcMetaFile: string
31
31
  rpcMapDeclarationFile: string
32
32
 
@@ -36,6 +36,7 @@ export interface PikkuCLICoreOutputFiles {
36
36
 
37
37
  // Application bootstrap
38
38
  bootstrapFile: string
39
+ bootstrapFiles: Record<PikkuEventTypes, string>
39
40
  }
40
41
 
41
42
  export type PikkuCLIConfig = {
@@ -153,9 +154,6 @@ const _getPikkuCLIConfig = async (
153
154
  'pikku-functions-meta.gen.ts'
154
155
  )
155
156
  }
156
- if (!result.rpcFile) {
157
- result.rpcFile = join(result.outDir, 'pikku-rpc.gen.ts')
158
- }
159
157
  if (!result.rpcMetaFile) {
160
158
  result.rpcMetaFile = join(result.outDir, 'pikku-rpc-meta.gen.ts')
161
159
  }
@@ -210,6 +208,14 @@ const _getPikkuCLIConfig = async (
210
208
  if (!result.bootstrapFile) {
211
209
  result.bootstrapFile = join(result.outDir, 'pikku-bootstrap.gen.ts')
212
210
  }
211
+
212
+ result.bootstrapFiles = result.bootstrapFiles || {}
213
+ for (const key of Object.keys(PikkuEventTypes)) {
214
+ result.bootstrapFiles[key] = join(
215
+ result.outDir,
216
+ `pikku-bootstrap-${key}.gen.ts`
217
+ )
218
+ }
213
219
  }
214
220
 
215
221
  if (requiredFields.length > 0) {
@@ -38,6 +38,12 @@ export async function generateSchemas(
38
38
  skipTypeCheck: true,
39
39
  topRef: false,
40
40
  discriminatorType: 'open-api',
41
+ expose: 'export',
42
+ jsDoc: 'extended',
43
+ sortProps: true,
44
+ strictTuples: false,
45
+ encodeRefs: false,
46
+ additionalProperties: false,
41
47
  })
42
48
  const schemas: Record<string, JSONValue> = {}
43
49
  schemasSet.forEach((schema) => {
@@ -1,7 +1,6 @@
1
1
  export const serializeNextJsBackendWrapper = (
2
- routesPath: string,
2
+ httpBootstrapPath: string,
3
3
  routesMapPath: string,
4
- schemasPath: string,
5
4
  configImport: string,
6
5
  singleServicesFactoryImport: string,
7
6
  sessionServicesImport: string
@@ -19,8 +18,7 @@ ${configImport}
19
18
  ${singleServicesFactoryImport}
20
19
  ${sessionServicesImport}
21
20
 
22
- import '${routesPath}'
23
- import '${schemasPath}'
21
+ import '${httpBootstrapPath}'
24
22
 
25
23
  let _pikku: PikkuNextJS | undefined
26
24
 
@@ -2,14 +2,19 @@ import { ChannelsMeta } from '@pikku/core/channel'
2
2
  import { serializeImportMap } from './utils/serialize-import-map.js'
3
3
  import { TypesMap } from '@pikku/inspector'
4
4
  import { generateCustomTypes } from './utils/utils.js'
5
+ import { FunctionsMeta } from '@pikku/core'
5
6
 
6
7
  export const serializeTypedChannelsMap = (
7
8
  relativeToPath: string,
8
9
  packageMappings: Record<string, string>,
9
10
  typesMap: TypesMap,
11
+ functionsMeta: FunctionsMeta,
10
12
  channelsMeta: ChannelsMeta
11
13
  ): string => {
12
- const { channels, requiredTypes } = generateChannels(channelsMeta)
14
+ const { channels, requiredTypes } = generateChannels(
15
+ functionsMeta,
16
+ channelsMeta
17
+ )
13
18
  typesMap.customTypes.forEach(({ references }) => {
14
19
  for (const reference of references) {
15
20
  requiredTypes.add(reference)
@@ -52,7 +57,10 @@ export type ChannelRouteHandlerOf<
52
57
  `
53
58
  }
54
59
 
55
- function generateChannels(channelsMeta: ChannelsMeta) {
60
+ function generateChannels(
61
+ functionsMeta: FunctionsMeta,
62
+ channelsMeta: ChannelsMeta
63
+ ) {
56
64
  const requiredTypes = new Set<string>()
57
65
  const channelsObject: Record<
58
66
  string,
@@ -75,16 +83,39 @@ function generateChannels(channelsMeta: ChannelsMeta) {
75
83
  const { name, messageRoutes, message } = meta
76
84
 
77
85
  if (!channelsObject[name]) {
78
- channelsObject[name] = { message, routes: {} }
86
+ channelsObject[name] = { message: null, routes: {} }
87
+ }
88
+
89
+ if (message) {
90
+ const func = functionsMeta[message.pikkuFuncName]
91
+ if (!func) {
92
+ throw new Error(
93
+ `Function ${message.pikkuFuncName} not found in functionsMeta for channel ${name}`
94
+ )
95
+ }
96
+ const inputTypes = func.inputs || null
97
+ const outputTypes = func.outputs || null
98
+ channelsObject[name].message = {
99
+ inputs: inputTypes,
100
+ outputs: outputTypes,
101
+ }
102
+ inputTypes?.forEach((type) => requiredTypes.add(type))
103
+ outputTypes?.forEach((type) => requiredTypes.add(type))
79
104
  }
80
105
 
81
106
  for (const [key, route] of Object.entries(messageRoutes)) {
82
107
  if (!channelsObject[name].routes[key]) {
83
108
  channelsObject[name].routes[key] = {}
84
109
  }
85
- for (const [method, { inputs, outputs }] of Object.entries(route)) {
86
- const inputTypes = inputs || null
87
- const outputTypes = outputs || null
110
+ for (const [method, { pikkuFuncName }] of Object.entries(route)) {
111
+ const func = functionsMeta[pikkuFuncName]
112
+ if (!func) {
113
+ throw new Error(
114
+ `Function ${pikkuFuncName} not found in functionsMeta for channel ${name}, route ${key}, method ${method}`
115
+ )
116
+ }
117
+ const inputTypes = func.inputs || null
118
+ const outputTypes = func.outputs || null
88
119
  channelsObject[name].routes[key][method] = {
89
120
  inputTypes,
90
121
  outputTypes,