@pikku/cli 0.8.0 → 0.8.2
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 +37 -0
- package/bin/pikku-all.ts +122 -64
- package/bin/pikku-fetch.ts +5 -1
- package/bin/pikku-nextjs.ts +6 -2
- package/bin/pikku-openapi.ts +3 -1
- package/bin/pikku-queue-service.ts +5 -1
- package/bin/pikku-websocket.ts +5 -1
- package/cli.schema.json +131 -10
- package/dist/bin/pikku-all.js +51 -50
- package/dist/bin/pikku-fetch.js +5 -1
- package/dist/bin/pikku-nextjs.js +6 -2
- package/dist/bin/pikku-openapi.js +3 -1
- package/dist/bin/pikku-queue-service.js +5 -1
- package/dist/bin/pikku-websocket.js +5 -1
- package/dist/src/events/functions/pikku-command-services.d.ts +3 -0
- package/dist/src/events/functions/pikku-command-services.js +73 -0
- package/dist/src/events/http/serialize-typed-http-map.d.ts +0 -1
- package/dist/src/events/http/serialize-typed-http-map.js +1 -14
- package/dist/src/events/rpc/pikku-command-rpc-client.d.ts +2 -0
- package/dist/src/events/rpc/pikku-command-rpc-client.js +12 -0
- package/dist/src/events/rpc/serialize-rpc-wrapper.d.ts +1 -0
- package/dist/src/events/rpc/serialize-rpc-wrapper.js +29 -0
- package/dist/src/events/rpc/serialize-typed-rpc-map.js +1 -1
- package/dist/src/inspector-glob.js +1 -1
- package/dist/src/pikku-cli-config.d.ts +4 -1
- package/dist/src/pikku-cli-config.js +26 -14
- package/dist/src/schema-generator.js +2 -2
- package/dist/src/utils.d.ts +3 -0
- package/dist/src/utils.js +25 -6
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/src/events/functions/pikku-command-services.ts +125 -0
- package/src/events/http/serialize-typed-http-map.ts +1 -18
- package/src/events/rpc/pikku-command-rpc-client.ts +33 -0
- package/src/events/rpc/serialize-rpc-wrapper.ts +29 -0
- package/src/events/rpc/serialize-typed-rpc-map.ts +1 -1
- package/src/inspector-glob.ts +1 -1
- package/src/pikku-cli-config.ts +33 -17
- package/src/schema-generator.ts +2 -2
- package/src/utils.test.ts +137 -0
- package/src/utils.ts +31 -6
- package/dist/src/events/http/pikku-command-nextjs.d.ts +0 -2
- package/dist/src/events/http/pikku-command-nextjs.js +0 -36
- package/src/events/http/pikku-command-nextjs.ts +0 -111
package/dist/src/utils.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { relative, dirname } from 'path';
|
|
1
|
+
import { relative, dirname, resolve } from 'path';
|
|
2
2
|
import { mkdir, writeFile } from 'fs/promises';
|
|
3
3
|
import chalk from 'chalk';
|
|
4
4
|
import { fileURLToPath } from 'url';
|
|
@@ -33,6 +33,11 @@ export class CLILogger {
|
|
|
33
33
|
warn(message) {
|
|
34
34
|
console.error(chalk.yellow(message));
|
|
35
35
|
}
|
|
36
|
+
debug(message) {
|
|
37
|
+
if (process.env.DEBUG) {
|
|
38
|
+
console.log(chalk.gray(message));
|
|
39
|
+
}
|
|
40
|
+
}
|
|
36
41
|
logPikkuLogo() {
|
|
37
42
|
this.primary(logo);
|
|
38
43
|
const packageJson = JSON.parse(readFileSync(`${dirname(__filename)}/../../package.json`, 'utf-8'));
|
|
@@ -44,14 +49,28 @@ export const getFileImportRelativePath = (from, to, packageMappings) => {
|
|
|
44
49
|
if (!/^\.+\//.test(filePath)) {
|
|
45
50
|
filePath = `./${filePath}`;
|
|
46
51
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
+
const absolutePath = resolve(dirname(from), to);
|
|
53
|
+
const fromAbsolutePath = resolve(dirname(from));
|
|
54
|
+
// Check if both files are in the same package directory
|
|
55
|
+
// If so, skip packageMappings to use relative paths
|
|
56
|
+
let inSamePackage = false;
|
|
57
|
+
for (const [path] of Object.entries(packageMappings)) {
|
|
58
|
+
if (absolutePath.includes(path) && fromAbsolutePath.includes(path)) {
|
|
59
|
+
inSamePackage = true;
|
|
52
60
|
break;
|
|
53
61
|
}
|
|
54
62
|
}
|
|
63
|
+
// Only apply packageMappings if files are not in the same package
|
|
64
|
+
if (!inSamePackage) {
|
|
65
|
+
// let usesPackageName = false
|
|
66
|
+
for (const [path, packageName] of Object.entries(packageMappings)) {
|
|
67
|
+
if (absolutePath.includes(path)) {
|
|
68
|
+
// usesPackageName = true
|
|
69
|
+
filePath = absolutePath.replace(new RegExp(`.*${path}`), packageName);
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
55
74
|
// if (usesPackageName) {
|
|
56
75
|
// return filePath.replace('.ts', '')
|
|
57
76
|
// }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"root":["../bin/pikku-all.ts","../bin/pikku-fetch.ts","../bin/pikku-nextjs.ts","../bin/pikku-openapi.ts","../bin/pikku-queue-service.ts","../bin/pikku-schemas.ts","../bin/pikku-websocket.ts","../bin/pikku.ts","../src/inspector-glob.ts","../src/pikku-cli-config.ts","../src/pikku-command-schemas.ts","../src/schema-generator.ts","../src/schemas.ts","../src/serialize-import-map.ts","../src/serialize-pikku-types.ts","../src/types.ts","../src/utils.ts","../src/events/channels/pikku-channels.ts","../src/events/channels/pikku-command-channels-map.ts","../src/events/channels/pikku-command-channels.ts","../src/events/channels/pikku-command-websocket-typed.ts","../src/events/channels/serialize-typed-channel-map.ts","../src/events/channels/serialize-websocket-wrapper.ts","../src/events/fetch/index.ts","../src/events/functions/pikku-command-function-types.ts","../src/events/functions/pikku-command-functions.ts","../src/events/functions/pikku-
|
|
1
|
+
{"root":["../bin/pikku-all.ts","../bin/pikku-fetch.ts","../bin/pikku-nextjs.ts","../bin/pikku-openapi.ts","../bin/pikku-queue-service.ts","../bin/pikku-schemas.ts","../bin/pikku-websocket.ts","../bin/pikku.ts","../src/inspector-glob.ts","../src/pikku-cli-config.ts","../src/pikku-command-schemas.ts","../src/schema-generator.ts","../src/schemas.ts","../src/serialize-import-map.ts","../src/serialize-pikku-types.ts","../src/types.ts","../src/utils.ts","../src/events/channels/pikku-channels.ts","../src/events/channels/pikku-command-channels-map.ts","../src/events/channels/pikku-command-channels.ts","../src/events/channels/pikku-command-websocket-typed.ts","../src/events/channels/serialize-typed-channel-map.ts","../src/events/channels/serialize-websocket-wrapper.ts","../src/events/fetch/index.ts","../src/events/functions/pikku-command-function-types.ts","../src/events/functions/pikku-command-functions.ts","../src/events/functions/pikku-command-services.ts","../src/events/functions/pikku-function-types.ts","../src/events/functions/pikku-functions.ts","../src/events/http/openapi-spec-generator.ts","../src/events/http/pikku-command-http-map.ts","../src/events/http/pikku-command-http-routes.ts","../src/events/http/pikku-command-openapi.ts","../src/events/http/pikku-http-routes.ts","../src/events/http/serialize-fetch-wrapper.ts","../src/events/http/serialize-typed-http-map.ts","../src/events/mcp/pikku-command-mcp-json.ts","../src/events/mcp/pikku-command-mcp.ts","../src/events/mcp/serialize-mcp-json.ts","../src/events/queue/pikku-command-queue-map.ts","../src/events/queue/pikku-command-queue-service.ts","../src/events/queue/pikku-command-queue.ts","../src/events/queue/pikku-queue-map.ts","../src/events/queue/pikku-queue.ts","../src/events/queue/serialize-queue-map.ts","../src/events/queue/serialize-queue-meta.ts","../src/events/queue/serialize-queue-wrapper.ts","../src/events/rpc/pikku-command-rpc-client.ts","../src/events/rpc/pikku-command-rpc-map.ts","../src/events/rpc/pikku-command-rpc.ts","../src/events/rpc/pikku-rpc.ts","../src/events/rpc/serialize-rpc-wrapper.ts","../src/events/rpc/serialize-typed-rpc-map.ts","../src/events/scheduler/pikku-command-scheduler.ts","../src/events/scheduler/serialize-scheduler-meta.ts","../src/runtimes/nextjs/pikku-command-nextjs.ts","../src/runtimes/nextjs/serialize-nextjs-backend-wrapper.ts","../src/runtimes/nextjs/serialize-nextjs-http-wrapper.ts"],"version":"5.8.3"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pikku/cli",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.2",
|
|
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.8.
|
|
26
|
-
"@pikku/inspector": "^0.8.
|
|
25
|
+
"@pikku/core": "^0.8.2",
|
|
26
|
+
"@pikku/inspector": "^0.8.1",
|
|
27
27
|
"@types/cookie": "^0.6.0",
|
|
28
28
|
"@types/uuid": "^10.0.0",
|
|
29
29
|
"chalk": "^5.4.1",
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getFileImportRelativePath,
|
|
3
|
+
getPikkuFilesAndMethods,
|
|
4
|
+
logCommandInfoAndTime,
|
|
5
|
+
writeFileInDir,
|
|
6
|
+
} from '../../utils.js'
|
|
7
|
+
import { PikkuCommand } from '../../types.js'
|
|
8
|
+
import { PikkuCLIConfig } from '../../pikku-cli-config.js'
|
|
9
|
+
import { InspectorState } from '@pikku/inspector'
|
|
10
|
+
|
|
11
|
+
export const serializeServicesMap = (
|
|
12
|
+
functionsMetaData: Record<string, any>,
|
|
13
|
+
middlewareServices: string[] = [],
|
|
14
|
+
servicesImport: string,
|
|
15
|
+
sessionServicesImport: string
|
|
16
|
+
): string => {
|
|
17
|
+
// Extract all unique services from all functions
|
|
18
|
+
const usedServices = new Set<string>()
|
|
19
|
+
|
|
20
|
+
// Internal services that are created internally and not via the create service script
|
|
21
|
+
const internalServices = new Set(['rpc', 'mcp', 'channel', 'userSession'])
|
|
22
|
+
|
|
23
|
+
for (const funcMeta of Object.values(functionsMetaData)) {
|
|
24
|
+
if (funcMeta.services && Array.isArray(funcMeta.services.services)) {
|
|
25
|
+
funcMeta.services.services.forEach((service: string) => {
|
|
26
|
+
// Only include services that are not internal
|
|
27
|
+
if (!internalServices.has(service)) {
|
|
28
|
+
usedServices.add(service)
|
|
29
|
+
}
|
|
30
|
+
})
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Add middleware services that might not be detected from function inspection
|
|
35
|
+
middlewareServices.forEach((service) => {
|
|
36
|
+
if (!internalServices.has(service)) {
|
|
37
|
+
usedServices.add(service)
|
|
38
|
+
}
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
// Create a map of services with true for all needed services
|
|
42
|
+
const servicesMap = Object.fromEntries(
|
|
43
|
+
Array.from(usedServices)
|
|
44
|
+
.sort()
|
|
45
|
+
.map((service) => [service, true])
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
// Generate the TypeScript code
|
|
49
|
+
const serviceKeys = Object.keys(servicesMap).sort()
|
|
50
|
+
|
|
51
|
+
// Services that are always required internally by the framework
|
|
52
|
+
const defaultServices = ['config', 'logger', 'variables', 'schema']
|
|
53
|
+
|
|
54
|
+
// Combine default services with detected services
|
|
55
|
+
const allRequiredServices = [
|
|
56
|
+
...new Set([...defaultServices, ...serviceKeys]),
|
|
57
|
+
].sort()
|
|
58
|
+
|
|
59
|
+
// For RequiredSingletonServices, we need to pick from the actual SingletonServices interface
|
|
60
|
+
// This will be resolved at compile time based on what's actually in the SingletonServices interface
|
|
61
|
+
// We don't need to hardcode which services are singletons beyond the core framework ones
|
|
62
|
+
|
|
63
|
+
const code = [
|
|
64
|
+
'/**',
|
|
65
|
+
' * This file was generated by the @pikku/cli',
|
|
66
|
+
' */',
|
|
67
|
+
'',
|
|
68
|
+
servicesImport,
|
|
69
|
+
sessionServicesImport,
|
|
70
|
+
"import type { PikkuInteraction } from '@pikku/core'",
|
|
71
|
+
'',
|
|
72
|
+
'export const singletonServices = {',
|
|
73
|
+
...Object.keys(servicesMap).map((service) => ` '${service}': true,`),
|
|
74
|
+
'} as const',
|
|
75
|
+
'',
|
|
76
|
+
'// Singleton services (created once at startup)',
|
|
77
|
+
'// Only includes services that are both required and available in SingletonServices',
|
|
78
|
+
`export type RequiredSingletonServices = Pick<SingletonServices, Extract<keyof SingletonServices, ${allRequiredServices.map((key) => `'${key}'`).join(' | ')}>> & Partial<Omit<SingletonServices, ${allRequiredServices.map((key) => `'${key}'`).join(' | ')}>>`,
|
|
79
|
+
'',
|
|
80
|
+
'// Session services (created per request, can access singleton services)',
|
|
81
|
+
'// Omits singleton services and PikkuInteraction (mcp, rpc, http, channel)',
|
|
82
|
+
`export type RequiredSessionServices = Omit<Services, keyof SingletonServices | keyof PikkuInteraction>`,
|
|
83
|
+
'',
|
|
84
|
+
].join('\n')
|
|
85
|
+
|
|
86
|
+
return code
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export const pikkuServices: PikkuCommand = async (
|
|
90
|
+
logger,
|
|
91
|
+
cliConfig: PikkuCLIConfig,
|
|
92
|
+
visitState: InspectorState
|
|
93
|
+
) => {
|
|
94
|
+
return await logCommandInfoAndTime(
|
|
95
|
+
logger,
|
|
96
|
+
'Generating Pikku services map',
|
|
97
|
+
'Generated Pikku services map',
|
|
98
|
+
[visitState.functions.files.size === 0],
|
|
99
|
+
async () => {
|
|
100
|
+
const { sessionServicesType, singletonServicesType } =
|
|
101
|
+
await getPikkuFilesAndMethods(
|
|
102
|
+
logger,
|
|
103
|
+
visitState,
|
|
104
|
+
cliConfig.packageMappings,
|
|
105
|
+
cliConfig.typesDeclarationFile,
|
|
106
|
+
{},
|
|
107
|
+
{
|
|
108
|
+
sessionServiceType: true,
|
|
109
|
+
singletonServicesType: true,
|
|
110
|
+
}
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
const servicesImport = `import type { ${singletonServicesType.type} } from '${getFileImportRelativePath(cliConfig.typesDeclarationFile, singletonServicesType.typePath, cliConfig.packageMappings)}'`
|
|
114
|
+
const sessionServicesImport = `import type { ${sessionServicesType.type} } from '${getFileImportRelativePath(cliConfig.typesDeclarationFile, sessionServicesType.typePath, cliConfig.packageMappings)}'`
|
|
115
|
+
|
|
116
|
+
const servicesCode = serializeServicesMap(
|
|
117
|
+
visitState.functions.meta,
|
|
118
|
+
cliConfig.middlewareServices,
|
|
119
|
+
servicesImport,
|
|
120
|
+
sessionServicesImport
|
|
121
|
+
)
|
|
122
|
+
await writeFileInDir(logger, cliConfig.servicesFile, servicesCode)
|
|
123
|
+
}
|
|
124
|
+
)
|
|
125
|
+
}
|
|
@@ -2,6 +2,7 @@ import { HTTPRoutesMeta } from '@pikku/core/http'
|
|
|
2
2
|
import { serializeImportMap } from '../../serialize-import-map.js'
|
|
3
3
|
import { MetaInputTypes, TypesMap } from '@pikku/inspector'
|
|
4
4
|
import { FunctionsMeta } from '@pikku/core'
|
|
5
|
+
import { generateCustomTypes } from '../../utils.js'
|
|
5
6
|
|
|
6
7
|
export const serializeTypedRoutesMap = (
|
|
7
8
|
relativeToPath: string,
|
|
@@ -54,24 +55,6 @@ export type RoutesWithMethod<Method extends string> = {
|
|
|
54
55
|
`
|
|
55
56
|
}
|
|
56
57
|
|
|
57
|
-
export function generateCustomTypes(
|
|
58
|
-
typesMap: TypesMap,
|
|
59
|
-
requiredTypes: Set<string>
|
|
60
|
-
) {
|
|
61
|
-
return `
|
|
62
|
-
// Custom types are those that are defined directly within generics
|
|
63
|
-
// or are broken into simpler types
|
|
64
|
-
${Array.from(typesMap.customTypes.entries())
|
|
65
|
-
.map(([name, { type, references }]) => {
|
|
66
|
-
references.forEach((name) => {
|
|
67
|
-
const originalName = typesMap.getTypeMeta(name).originalName
|
|
68
|
-
requiredTypes.add(originalName)
|
|
69
|
-
})
|
|
70
|
-
return `export type ${name} = ${type}`
|
|
71
|
-
})
|
|
72
|
-
.join('\n')}`
|
|
73
|
-
}
|
|
74
|
-
|
|
75
58
|
function generateRoutes(
|
|
76
59
|
routesMeta: HTTPRoutesMeta,
|
|
77
60
|
functionsMeta: FunctionsMeta,
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { serializeRPCWrapper } from './serialize-rpc-wrapper.js'
|
|
2
|
+
import {
|
|
3
|
+
getFileImportRelativePath,
|
|
4
|
+
logCommandInfoAndTime,
|
|
5
|
+
writeFileInDir,
|
|
6
|
+
} from '../../utils.js'
|
|
7
|
+
import { PikkuCommandWithoutState } from '../../types.js'
|
|
8
|
+
|
|
9
|
+
export const pikkuRPCClient: PikkuCommandWithoutState = async (
|
|
10
|
+
logger,
|
|
11
|
+
{ rpcFile, rpcMapDeclarationFile, packageMappings }
|
|
12
|
+
) => {
|
|
13
|
+
return await logCommandInfoAndTime(
|
|
14
|
+
logger,
|
|
15
|
+
'Generating RPC wrapper',
|
|
16
|
+
'Generated RPC wrapper',
|
|
17
|
+
[rpcFile === undefined, "rpcFile isn't set in the pikku config"],
|
|
18
|
+
async () => {
|
|
19
|
+
if (!rpcFile) {
|
|
20
|
+
throw new Error("rpcFile isn't set in the pikku config")
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const rpcMapDeclarationPath = getFileImportRelativePath(
|
|
24
|
+
rpcFile,
|
|
25
|
+
rpcMapDeclarationFile,
|
|
26
|
+
packageMappings
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
const content = [serializeRPCWrapper(rpcMapDeclarationPath)]
|
|
30
|
+
await writeFileInDir(logger, rpcFile, content.join('\n'))
|
|
31
|
+
}
|
|
32
|
+
)
|
|
33
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export const serializeRPCWrapper = (rpcMapPath: string) => {
|
|
2
|
+
return `
|
|
3
|
+
import { PikkuFetch } from "./pikku-fetch.gen.js"
|
|
4
|
+
import type { RPCInvoke } from '${rpcMapPath}'
|
|
5
|
+
|
|
6
|
+
export class PikkuRPC {
|
|
7
|
+
pikkuFetch = new PikkuFetch()
|
|
8
|
+
|
|
9
|
+
setPikkuFetch(pikkuFetch: PikkuFetch): void {
|
|
10
|
+
this.pikkuFetch = pikkuFetch
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
setServerUrl(serverUrl: string): void {
|
|
14
|
+
this.pikkuFetch.setServerUrl(serverUrl)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
setAuthorizationJWT(jwt: string | null): void {
|
|
18
|
+
this.pikkuFetch.setAuthorizationJWT(jwt)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Generic RPC invoke method
|
|
22
|
+
invoke: RPCInvoke = async (name, data) => {
|
|
23
|
+
return await this.pikkuFetch.post('/rpc', { name, data })
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export const pikkuRPC = new PikkuRPC();
|
|
28
|
+
`
|
|
29
|
+
}
|
package/src/inspector-glob.ts
CHANGED
package/src/pikku-cli-config.ts
CHANGED
|
@@ -43,6 +43,9 @@ export interface PikkuCLICoreOutputFiles {
|
|
|
43
43
|
mcpEndpointsFile: string
|
|
44
44
|
mcpEndpointsMetaFile: string
|
|
45
45
|
|
|
46
|
+
// Services
|
|
47
|
+
servicesFile: string
|
|
48
|
+
|
|
46
49
|
// Application bootstrap
|
|
47
50
|
bootstrapFile: string
|
|
48
51
|
bootstrapFiles: Record<PikkuEventTypes, string>
|
|
@@ -65,6 +68,7 @@ export type PikkuCLIConfig = {
|
|
|
65
68
|
nextHTTPFile?: string
|
|
66
69
|
fetchFile?: string
|
|
67
70
|
websocketFile?: string
|
|
71
|
+
rpcFile?: string
|
|
68
72
|
queueFile?: string
|
|
69
73
|
mcpJsonFile?: string
|
|
70
74
|
|
|
@@ -73,6 +77,8 @@ export type PikkuCLIConfig = {
|
|
|
73
77
|
additionalInfo: OpenAPISpecInfo
|
|
74
78
|
}
|
|
75
79
|
|
|
80
|
+
middlewareServices?: string[]
|
|
81
|
+
|
|
76
82
|
filters: InspectorFilters
|
|
77
83
|
} & PikkuCLICoreOutputFiles
|
|
78
84
|
|
|
@@ -81,6 +87,7 @@ const CONFIG_DIR_FILES = [
|
|
|
81
87
|
'nextHTTPFile',
|
|
82
88
|
'fetchFile',
|
|
83
89
|
'websocketFile',
|
|
90
|
+
'rpcFile',
|
|
84
91
|
'queueFile',
|
|
85
92
|
'mcpJsonFile',
|
|
86
93
|
]
|
|
@@ -88,13 +95,13 @@ const CONFIG_DIR_FILES = [
|
|
|
88
95
|
export const getPikkuCLIConfig = async (
|
|
89
96
|
configFile: string | undefined = undefined,
|
|
90
97
|
requiredFields: Array<keyof PikkuCLIConfig>,
|
|
91
|
-
|
|
98
|
+
filters: InspectorFilters = {},
|
|
92
99
|
exitProcess: boolean = false
|
|
93
100
|
): Promise<PikkuCLIConfig> => {
|
|
94
101
|
const config = await _getPikkuCLIConfig(
|
|
95
102
|
configFile,
|
|
96
103
|
requiredFields,
|
|
97
|
-
|
|
104
|
+
filters,
|
|
98
105
|
exitProcess
|
|
99
106
|
)
|
|
100
107
|
return config
|
|
@@ -103,7 +110,7 @@ export const getPikkuCLIConfig = async (
|
|
|
103
110
|
const _getPikkuCLIConfig = async (
|
|
104
111
|
configFile: string | undefined = undefined,
|
|
105
112
|
requiredFields: Array<keyof PikkuCLIConfig>,
|
|
106
|
-
|
|
113
|
+
filters: InspectorFilters = {},
|
|
107
114
|
exitProcess: boolean = false
|
|
108
115
|
): Promise<PikkuCLIConfig> => {
|
|
109
116
|
if (!configFile) {
|
|
@@ -131,7 +138,7 @@ const _getPikkuCLIConfig = async (
|
|
|
131
138
|
const extendedConfig = await getPikkuCLIConfig(
|
|
132
139
|
resolve(configDir, config.extends),
|
|
133
140
|
[],
|
|
134
|
-
|
|
141
|
+
filters,
|
|
135
142
|
exitProcess
|
|
136
143
|
)
|
|
137
144
|
result = {
|
|
@@ -156,8 +163,9 @@ const _getPikkuCLIConfig = async (
|
|
|
156
163
|
|
|
157
164
|
if (result.outDir) {
|
|
158
165
|
// Create transport/event directories
|
|
166
|
+
const functionDir = join(result.outDir, 'function')
|
|
159
167
|
const httpDir = join(result.outDir, 'http')
|
|
160
|
-
const
|
|
168
|
+
const channelDir = join(result.outDir, 'channel')
|
|
161
169
|
const rpcDir = join(result.outDir, 'rpc')
|
|
162
170
|
const schedulerDir = join(result.outDir, 'scheduler')
|
|
163
171
|
const queueDir = join(result.outDir, 'queue')
|
|
@@ -171,11 +179,11 @@ const _getPikkuCLIConfig = async (
|
|
|
171
179
|
|
|
172
180
|
// Functions
|
|
173
181
|
if (!result.functionsFile) {
|
|
174
|
-
result.functionsFile = join(
|
|
182
|
+
result.functionsFile = join(functionDir, 'pikku-functions.gen.ts')
|
|
175
183
|
}
|
|
176
184
|
if (!result.functionsMetaFile) {
|
|
177
185
|
result.functionsMetaFile = join(
|
|
178
|
-
|
|
186
|
+
functionDir,
|
|
179
187
|
'pikku-functions-meta.gen.ts'
|
|
180
188
|
)
|
|
181
189
|
}
|
|
@@ -202,17 +210,14 @@ const _getPikkuCLIConfig = async (
|
|
|
202
210
|
|
|
203
211
|
// Channels/WebSocket
|
|
204
212
|
if (!result.channelsFile) {
|
|
205
|
-
result.channelsFile = join(
|
|
213
|
+
result.channelsFile = join(channelDir, 'pikku-channels.gen.ts')
|
|
206
214
|
}
|
|
207
215
|
if (!result.channelsMetaFile) {
|
|
208
|
-
result.channelsMetaFile = join(
|
|
209
|
-
channelsDir,
|
|
210
|
-
'pikku-channels-meta.gen.ts'
|
|
211
|
-
)
|
|
216
|
+
result.channelsMetaFile = join(channelDir, 'pikku-channels-meta.gen.ts')
|
|
212
217
|
}
|
|
213
218
|
if (!result.channelsMapDeclarationFile) {
|
|
214
219
|
result.channelsMapDeclarationFile = join(
|
|
215
|
-
|
|
220
|
+
channelDir,
|
|
216
221
|
'pikku-channels-map.gen.d.ts'
|
|
217
222
|
)
|
|
218
223
|
}
|
|
@@ -227,12 +232,12 @@ const _getPikkuCLIConfig = async (
|
|
|
227
232
|
|
|
228
233
|
// Scheduler
|
|
229
234
|
if (!result.schedulersFile) {
|
|
230
|
-
result.schedulersFile = join(schedulerDir, 'pikku-
|
|
235
|
+
result.schedulersFile = join(schedulerDir, 'pikku-scheduler.gen.ts')
|
|
231
236
|
}
|
|
232
237
|
if (!result.schedulersMetaFile) {
|
|
233
238
|
result.schedulersMetaFile = join(
|
|
234
239
|
schedulerDir,
|
|
235
|
-
'pikku-
|
|
240
|
+
'pikku-scheduler-meta.gen.ts'
|
|
236
241
|
)
|
|
237
242
|
}
|
|
238
243
|
|
|
@@ -253,6 +258,11 @@ const _getPikkuCLIConfig = async (
|
|
|
253
258
|
)
|
|
254
259
|
}
|
|
255
260
|
|
|
261
|
+
// Services
|
|
262
|
+
if (!result.servicesFile) {
|
|
263
|
+
result.servicesFile = join(result.outDir, 'pikku-services.gen.ts')
|
|
264
|
+
}
|
|
265
|
+
|
|
256
266
|
// Bootstrap files
|
|
257
267
|
if (!result.bootstrapFile) {
|
|
258
268
|
result.bootstrapFile = join(result.outDir, 'pikku-bootstrap.gen.ts')
|
|
@@ -297,8 +307,14 @@ const _getPikkuCLIConfig = async (
|
|
|
297
307
|
}
|
|
298
308
|
|
|
299
309
|
result.filters = result.filters || {}
|
|
300
|
-
if (tags.length > 0) {
|
|
301
|
-
result.filters.tags = tags
|
|
310
|
+
if (filters.tags && filters.tags.length > 0) {
|
|
311
|
+
result.filters.tags = filters.tags
|
|
312
|
+
}
|
|
313
|
+
if (filters.types && filters.types.length > 0) {
|
|
314
|
+
result.filters.types = filters.types
|
|
315
|
+
}
|
|
316
|
+
if (filters.directories && filters.directories.length > 0) {
|
|
317
|
+
result.filters.directories = filters.directories
|
|
302
318
|
}
|
|
303
319
|
|
|
304
320
|
if (!isAbsolute(result.tsconfig)) {
|
package/src/schema-generator.ts
CHANGED
|
@@ -53,10 +53,10 @@ export async function generateSchemas(
|
|
|
53
53
|
} catch (e) {
|
|
54
54
|
// Ignore rootless errors
|
|
55
55
|
if (e instanceof RootlessError) {
|
|
56
|
-
|
|
56
|
+
logger.error(`Error generating schema since it has no root: ${schema}`)
|
|
57
57
|
return
|
|
58
58
|
}
|
|
59
|
-
|
|
59
|
+
logger.error(`Error generating schema: ${schema}`)
|
|
60
60
|
}
|
|
61
61
|
})
|
|
62
62
|
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { strict as assert } from 'assert'
|
|
2
|
+
import { describe, test } from 'node:test'
|
|
3
|
+
import { getFileImportRelativePath } from './utils.js'
|
|
4
|
+
|
|
5
|
+
describe('getFileImportRelativePath', () => {
|
|
6
|
+
test('should return relative path for files in same directory', () => {
|
|
7
|
+
const from = '/project/src/file1.ts'
|
|
8
|
+
const to = '/project/src/file2.ts'
|
|
9
|
+
const packageMappings = {}
|
|
10
|
+
|
|
11
|
+
const result = getFileImportRelativePath(from, to, packageMappings)
|
|
12
|
+
|
|
13
|
+
assert.strictEqual(result, './file2.js')
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
test('should return relative path for files in different directories', () => {
|
|
17
|
+
const from = '/project/src/file1.ts'
|
|
18
|
+
const to = '/project/lib/file2.ts'
|
|
19
|
+
const packageMappings = {}
|
|
20
|
+
|
|
21
|
+
const result = getFileImportRelativePath(from, to, packageMappings)
|
|
22
|
+
|
|
23
|
+
assert.strictEqual(result, '../lib/file2.js')
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
test('should use package mapping when files are in different packages', () => {
|
|
27
|
+
const from = '/project/packages/app/src/file1.ts'
|
|
28
|
+
const to = '/project/packages/sdk/src/file2.ts'
|
|
29
|
+
const packageMappings = {
|
|
30
|
+
'packages/sdk': '@myorg/sdk',
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const result = getFileImportRelativePath(from, to, packageMappings)
|
|
34
|
+
|
|
35
|
+
assert.strictEqual(result, '@myorg/sdk/src/file2.js')
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
test('should NOT use package mapping when files are in same package', () => {
|
|
39
|
+
const from = '/project/packages/sdk/src/file1.ts'
|
|
40
|
+
const to = '/project/packages/sdk/lib/file2.ts'
|
|
41
|
+
const packageMappings = {
|
|
42
|
+
'packages/sdk': '@myorg/sdk',
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const result = getFileImportRelativePath(from, to, packageMappings)
|
|
46
|
+
|
|
47
|
+
assert.strictEqual(result, '../lib/file2.js')
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
test('should use package mapping when only target file is in mapped package', () => {
|
|
51
|
+
const from = '/project/apps/web/src/file1.ts'
|
|
52
|
+
const to = '/project/packages/sdk/src/file2.ts'
|
|
53
|
+
const packageMappings = {
|
|
54
|
+
'packages/sdk': '@myorg/sdk',
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const result = getFileImportRelativePath(from, to, packageMappings)
|
|
58
|
+
|
|
59
|
+
assert.strictEqual(result, '@myorg/sdk/src/file2.js')
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
test('should handle multiple package mappings correctly', () => {
|
|
63
|
+
const from = '/project/packages/app/src/file1.ts'
|
|
64
|
+
const to = '/project/packages/utils/src/file2.ts'
|
|
65
|
+
const packageMappings = {
|
|
66
|
+
'packages/app': '@myorg/app',
|
|
67
|
+
'packages/utils': '@myorg/utils',
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const result = getFileImportRelativePath(from, to, packageMappings)
|
|
71
|
+
|
|
72
|
+
assert.strictEqual(result, '@myorg/utils/src/file2.js')
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
test('should preserve relative path when both files are in same package directory', () => {
|
|
76
|
+
const from = '/project/packages/sdk/src/components/file1.ts'
|
|
77
|
+
const to = '/project/packages/sdk/src/utils/file2.ts'
|
|
78
|
+
const packageMappings = {
|
|
79
|
+
'packages/sdk': '@myorg/sdk',
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const result = getFileImportRelativePath(from, to, packageMappings)
|
|
83
|
+
|
|
84
|
+
assert.strictEqual(result, '../utils/file2.js')
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
test('should work with nested package structures', () => {
|
|
88
|
+
const from = '/project/packages/app/src/file1.ts'
|
|
89
|
+
const to = '/project/packages/app/lib/nested/file2.ts'
|
|
90
|
+
const packageMappings = {
|
|
91
|
+
'packages/app': '@myorg/app',
|
|
92
|
+
'packages/sdk': '@myorg/sdk',
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const result = getFileImportRelativePath(from, to, packageMappings)
|
|
96
|
+
|
|
97
|
+
assert.strictEqual(result, '../lib/nested/file2.js')
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
test('should handle complex path structures', () => {
|
|
101
|
+
const from =
|
|
102
|
+
'/Users/user/project/workspace-starter/packages/sdk/.pikku/pikku-fetch.gen.ts'
|
|
103
|
+
const to =
|
|
104
|
+
'/Users/user/project/workspace-starter/packages/functions/.pikku/http/pikku-http-routes-map.gen.d.ts'
|
|
105
|
+
const packageMappings = {
|
|
106
|
+
'packages/sdk': '@workspace/sdk',
|
|
107
|
+
'packages/functions': '@workspace/functions',
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const result = getFileImportRelativePath(from, to, packageMappings)
|
|
111
|
+
|
|
112
|
+
assert.strictEqual(
|
|
113
|
+
result,
|
|
114
|
+
'@workspace/functions/.pikku/http/pikku-http-routes-map.gen.d.js'
|
|
115
|
+
)
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
test('should handle empty package mappings', () => {
|
|
119
|
+
const from = '/project/src/file1.ts'
|
|
120
|
+
const to = '/project/lib/file2.ts'
|
|
121
|
+
const packageMappings = {}
|
|
122
|
+
|
|
123
|
+
const result = getFileImportRelativePath(from, to, packageMappings)
|
|
124
|
+
|
|
125
|
+
assert.strictEqual(result, '../lib/file2.js')
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
test('should replace .ts extension with .js', () => {
|
|
129
|
+
const from = '/project/src/file1.ts'
|
|
130
|
+
const to = '/project/src/file2.tsx'
|
|
131
|
+
const packageMappings = {}
|
|
132
|
+
|
|
133
|
+
const result = getFileImportRelativePath(from, to, packageMappings)
|
|
134
|
+
|
|
135
|
+
assert.strictEqual(result, './file2.tsx'.replace('.ts', '.js'))
|
|
136
|
+
})
|
|
137
|
+
})
|