@pikku/cli 0.7.1 → 0.7.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 +9 -0
- package/bin/pikku-http-map.ts +1 -0
- package/bin/pikku-openapi.ts +3 -1
- package/bin/pikku-schemas.ts +3 -2
- package/dist/bin/pikku-http-map.js +1 -1
- package/dist/bin/pikku-openapi.js +2 -2
- package/dist/bin/pikku-schemas.js +2 -2
- package/dist/src/openapi-spec-generator.d.ts +2 -2
- package/dist/src/openapi-spec-generator.js +14 -5
- package/dist/src/schema-generator.d.ts +3 -3
- package/dist/src/schema-generator.js +15 -33
- package/dist/src/serialize-typed-function-map.d.ts +2 -1
- package/dist/src/serialize-typed-function-map.js +6 -4
- package/dist/src/serialize-typed-http-map.d.ts +2 -1
- package/dist/src/serialize-typed-http-map.js +10 -4
- package/package.json +3 -3
- package/src/openapi-spec-generator.ts +23 -4
- package/src/schema-generator.ts +17 -35
- package/src/serialize-typed-function-map.ts +12 -2
- package/src/serialize-typed-http-map.ts +18 -2
package/CHANGELOG.md
CHANGED
package/bin/pikku-http-map.ts
CHANGED
package/bin/pikku-openapi.ts
CHANGED
|
@@ -26,10 +26,12 @@ export const pikkuOpenAPI = async (
|
|
|
26
26
|
}
|
|
27
27
|
const schemas = await generateSchemas(
|
|
28
28
|
tsconfig,
|
|
29
|
-
|
|
29
|
+
functions.typesMap,
|
|
30
|
+
functions.meta,
|
|
30
31
|
http.meta
|
|
31
32
|
)
|
|
32
33
|
const openAPISpec = await generateOpenAPISpec(
|
|
34
|
+
functions.meta,
|
|
33
35
|
http.meta,
|
|
34
36
|
schemas,
|
|
35
37
|
openAPI.additionalInfo
|
package/bin/pikku-schemas.ts
CHANGED
|
@@ -17,14 +17,15 @@ export const pikkuSchemas = async (
|
|
|
17
17
|
async () => {
|
|
18
18
|
const schemas = await generateSchemas(
|
|
19
19
|
tsconfig,
|
|
20
|
-
|
|
20
|
+
functions.typesMap,
|
|
21
|
+
functions.meta,
|
|
21
22
|
http.meta
|
|
22
23
|
)
|
|
23
24
|
await saveSchemas(
|
|
24
25
|
schemaDirectory,
|
|
25
26
|
schemas,
|
|
26
27
|
functions.typesMap,
|
|
27
|
-
|
|
28
|
+
functions.meta,
|
|
28
29
|
supportsImportAttributes
|
|
29
30
|
)
|
|
30
31
|
}
|
|
@@ -4,7 +4,7 @@ import { serializeTypedRoutesMap } from '../src/serialize-typed-http-map.js';
|
|
|
4
4
|
import { inspectorGlob } from '../src/inspector-glob.js';
|
|
5
5
|
export const pikkuHTTPMap = async ({ httpRoutesMapDeclarationFile, packageMappings }, { http, functions }) => {
|
|
6
6
|
return await logCommandInfoAndTime('Creating HTTP map', 'Created HTTP map', [http.files.size === 0], async () => {
|
|
7
|
-
const content = serializeTypedRoutesMap(httpRoutesMapDeclarationFile, packageMappings, functions.typesMap, http.meta, http.metaInputTypes);
|
|
7
|
+
const content = serializeTypedRoutesMap(httpRoutesMapDeclarationFile, packageMappings, functions.typesMap, functions.meta, http.meta, http.metaInputTypes);
|
|
8
8
|
await writeFileInDir(httpRoutesMapDeclarationFile, content);
|
|
9
9
|
});
|
|
10
10
|
};
|
|
@@ -9,8 +9,8 @@ export const pikkuOpenAPI = async ({ tsconfig, openAPI }, { http, functions }) =
|
|
|
9
9
|
if (!openAPI?.outputFile) {
|
|
10
10
|
throw new Error('openAPI is required');
|
|
11
11
|
}
|
|
12
|
-
const schemas = await generateSchemas(tsconfig,
|
|
13
|
-
const openAPISpec = await generateOpenAPISpec(http.meta, schemas, openAPI.additionalInfo);
|
|
12
|
+
const schemas = await generateSchemas(tsconfig, functions.typesMap, functions.meta, http.meta);
|
|
13
|
+
const openAPISpec = await generateOpenAPISpec(functions.meta, http.meta, schemas, openAPI.additionalInfo);
|
|
14
14
|
if (openAPI.outputFile.endsWith('.json')) {
|
|
15
15
|
await writeFileInDir(openAPI.outputFile, JSON.stringify(openAPISpec, null, 2), true);
|
|
16
16
|
}
|
|
@@ -4,8 +4,8 @@ import { logCommandInfoAndTime, logPikkuLogo } from '../src/utils.js';
|
|
|
4
4
|
import { inspectorGlob } from '../src/inspector-glob.js';
|
|
5
5
|
export const pikkuSchemas = async ({ tsconfig, schemaDirectory, supportsImportAttributes }, { functions, http, channels }) => {
|
|
6
6
|
return await logCommandInfoAndTime('Creating schemas', 'Created schemas', [false], async () => {
|
|
7
|
-
const schemas = await generateSchemas(tsconfig,
|
|
8
|
-
await saveSchemas(schemaDirectory, schemas, functions.typesMap,
|
|
7
|
+
const schemas = await generateSchemas(tsconfig, functions.typesMap, functions.meta, http.meta);
|
|
8
|
+
await saveSchemas(schemaDirectory, schemas, functions.typesMap, functions.meta, supportsImportAttributes);
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
async function action({ config }) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { HTTPRoutesMeta } from '@pikku/core';
|
|
1
|
+
import { FunctionsMeta, HTTPRoutesMeta } from '@pikku/core';
|
|
2
2
|
interface OpenAPISpec {
|
|
3
3
|
openapi: string;
|
|
4
4
|
info: {
|
|
@@ -75,5 +75,5 @@ export interface OpenAPISpecInfo {
|
|
|
75
75
|
[key: string]: any[];
|
|
76
76
|
}[];
|
|
77
77
|
}
|
|
78
|
-
export declare function generateOpenAPISpec(routeMeta: HTTPRoutesMeta, schemas: Record<string, any>, additionalInfo: OpenAPISpecInfo): Promise<OpenAPISpec>;
|
|
78
|
+
export declare function generateOpenAPISpec(functionsMeta: FunctionsMeta, routeMeta: HTTPRoutesMeta, schemas: Record<string, any>, additionalInfo: OpenAPISpecInfo): Promise<OpenAPISpec>;
|
|
79
79
|
export {};
|
|
@@ -9,9 +9,12 @@ const getErrorResponseForConstructorName = (constructorName) => {
|
|
|
9
9
|
}
|
|
10
10
|
return undefined;
|
|
11
11
|
};
|
|
12
|
-
const convertSchemasToBodyPayloads = async (routesMeta, schemas) => {
|
|
12
|
+
const convertSchemasToBodyPayloads = async (functionsMeta, routesMeta, schemas) => {
|
|
13
13
|
const requiredSchemas = new Set(routesMeta
|
|
14
|
-
.map(({ inputTypes,
|
|
14
|
+
.map(({ inputTypes, pikkuFuncName }) => {
|
|
15
|
+
const output = functionsMeta[pikkuFuncName]?.outputs?.[0];
|
|
16
|
+
return [inputTypes?.body, output];
|
|
17
|
+
})
|
|
15
18
|
.flat()
|
|
16
19
|
.filter((schema) => !!schema));
|
|
17
20
|
const convertedEntries = await Promise.all(Object.entries(schemas).map(async ([key, schema]) => {
|
|
@@ -26,10 +29,16 @@ const convertSchemasToBodyPayloads = async (routesMeta, schemas) => {
|
|
|
26
29
|
}));
|
|
27
30
|
return Object.fromEntries(convertedEntries.filter((s) => !!s));
|
|
28
31
|
};
|
|
29
|
-
export async function generateOpenAPISpec(routeMeta, schemas, additionalInfo) {
|
|
32
|
+
export async function generateOpenAPISpec(functionsMeta, routeMeta, schemas, additionalInfo) {
|
|
30
33
|
const paths = {};
|
|
31
34
|
routeMeta.forEach((meta) => {
|
|
32
|
-
const { route, method, inputTypes,
|
|
35
|
+
const { route, method, inputTypes, pikkuFuncName, params, query, docs } = meta;
|
|
36
|
+
const functionMeta = functionsMeta[pikkuFuncName];
|
|
37
|
+
if (!functionMeta) {
|
|
38
|
+
console.error(`• No function metadata found for '${pikkuFuncName}' in route '${route}'.`);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const output = functionMeta.outputs ? functionMeta.outputs[0] : undefined;
|
|
33
42
|
const path = route.replace(/:(\w+)/g, '{$1}'); // Convert ":param" to "{param}"
|
|
34
43
|
if (!paths[path]) {
|
|
35
44
|
paths[path] = {};
|
|
@@ -103,7 +112,7 @@ export async function generateOpenAPISpec(routeMeta, schemas, additionalInfo) {
|
|
|
103
112
|
servers: additionalInfo.servers,
|
|
104
113
|
paths,
|
|
105
114
|
components: {
|
|
106
|
-
schemas: await convertSchemasToBodyPayloads(routeMeta, schemas),
|
|
115
|
+
schemas: await convertSchemasToBodyPayloads(functionsMeta, routeMeta, schemas),
|
|
107
116
|
responses: {},
|
|
108
117
|
parameters: {},
|
|
109
118
|
examples: {},
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { JSONValue } from '@pikku/core';
|
|
1
|
+
import { FunctionsMeta, JSONValue } from '@pikku/core';
|
|
2
2
|
import { HTTPRoutesMeta } from '@pikku/core/http';
|
|
3
3
|
import { TypesMap } from '@pikku/inspector';
|
|
4
|
-
export declare function generateSchemas(tsconfig: string,
|
|
5
|
-
export declare function saveSchemas(schemaParentDir: string, schemas: Record<string, JSONValue>, typesMap: TypesMap,
|
|
4
|
+
export declare function generateSchemas(tsconfig: string, typesMap: TypesMap, functionMeta: FunctionsMeta, httpRoutesMeta: HTTPRoutesMeta): Promise<Record<string, JSONValue>>;
|
|
5
|
+
export declare function saveSchemas(schemaParentDir: string, schemas: Record<string, JSONValue>, typesMap: TypesMap, functionsMeta: FunctionsMeta, supportsImportAttributes: boolean): Promise<void>;
|
|
@@ -1,36 +1,18 @@
|
|
|
1
1
|
import { createGenerator, RootlessError } from 'ts-json-schema-generator';
|
|
2
2
|
import { logInfo, writeFileInDir } from './utils.js';
|
|
3
3
|
import { mkdir, writeFile } from 'fs/promises';
|
|
4
|
-
export async function generateSchemas(tsconfig,
|
|
5
|
-
const schemasSet = new Set(
|
|
6
|
-
for (const {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
if (uniqueName) {
|
|
13
|
-
found = true;
|
|
14
|
-
schemasSet.add(uniqueName);
|
|
15
|
-
break;
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
catch (e) { }
|
|
19
|
-
}
|
|
20
|
-
if (!found) {
|
|
21
|
-
console.error('Input type not found in any types map:', input);
|
|
4
|
+
export async function generateSchemas(tsconfig, typesMap, functionMeta, httpRoutesMeta) {
|
|
5
|
+
const schemasSet = new Set(typesMap.customTypes.keys());
|
|
6
|
+
for (const { inputs, outputs } of Object.values(functionMeta)) {
|
|
7
|
+
const types = [...(inputs || []), ...(outputs || [])];
|
|
8
|
+
for (const type of types) {
|
|
9
|
+
const uniqueName = typesMap.getUniqueName(type);
|
|
10
|
+
if (uniqueName) {
|
|
11
|
+
schemasSet.add(uniqueName);
|
|
22
12
|
}
|
|
23
13
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
// const uniqueName = typesMap.getUniqueName(output)
|
|
27
|
-
// if (uniqueName) {
|
|
28
|
-
// console.log('Adding output schema:', uniqueName)
|
|
29
|
-
// schemasSet.add(uniqueName)
|
|
30
|
-
// break
|
|
31
|
-
// }
|
|
32
|
-
// }
|
|
33
|
-
// }
|
|
14
|
+
}
|
|
15
|
+
for (const { inputTypes } of httpRoutesMeta) {
|
|
34
16
|
if (inputTypes?.body) {
|
|
35
17
|
schemasSet.add(inputTypes.body);
|
|
36
18
|
}
|
|
@@ -63,13 +45,13 @@ export async function generateSchemas(tsconfig, typesMaps, httpRoutesMeta) {
|
|
|
63
45
|
});
|
|
64
46
|
return schemas;
|
|
65
47
|
}
|
|
66
|
-
export async function saveSchemas(schemaParentDir, schemas, typesMap,
|
|
48
|
+
export async function saveSchemas(schemaParentDir, schemas, typesMap, functionsMeta, supportsImportAttributes) {
|
|
67
49
|
await writeFileInDir(`${schemaParentDir}/register.gen.ts`, 'export const empty = null;');
|
|
68
50
|
const desiredSchemas = new Set([
|
|
69
|
-
...
|
|
70
|
-
.map(({
|
|
71
|
-
|
|
72
|
-
|
|
51
|
+
...Object.values(functionsMeta)
|
|
52
|
+
.map(({ inputs, outputs }) => [
|
|
53
|
+
inputs?.[0] ? typesMap.getUniqueName(inputs[0]) : undefined,
|
|
54
|
+
outputs?.[0] ? typesMap.getUniqueName(outputs[0]) : undefined,
|
|
73
55
|
])
|
|
74
56
|
.flat()
|
|
75
57
|
.filter((s) => !!s &&
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { HTTPRoutesMeta } from '@pikku/core/http';
|
|
2
2
|
import { MetaInputTypes, TypesMap } from '@pikku/inspector';
|
|
3
|
-
|
|
3
|
+
import { FunctionsMeta } from '@pikku/core';
|
|
4
|
+
export declare const serializeTypedRoutesMap: (relativeToPath: string, packageMappings: Record<string, string>, typesMap: TypesMap, functionsMeta: FunctionsMeta, routesMeta: HTTPRoutesMeta, metaTypes: MetaInputTypes) => string;
|
|
4
5
|
export declare function generateCustomTypes(typesMap: TypesMap, requiredTypes: Set<string>): string;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { serializeImportMap } from './serialize-import-map.js';
|
|
2
|
-
export const serializeTypedRoutesMap = (relativeToPath, packageMappings, typesMap, routesMeta, metaTypes) => {
|
|
2
|
+
export const serializeTypedRoutesMap = (relativeToPath, packageMappings, typesMap, functionsMeta, routesMeta, metaTypes) => {
|
|
3
3
|
const requiredTypes = new Set();
|
|
4
4
|
const serializedCustomTypes = generateCustomTypes(typesMap, requiredTypes);
|
|
5
5
|
const serializedMetaTypes = generateMetaTypes(metaTypes, typesMap);
|
|
6
|
-
const serializedRoutes = generateRoutes(routesMeta, typesMap, requiredTypes);
|
|
6
|
+
const serializedRoutes = generateRoutes(functionsMeta, routesMeta, typesMap, requiredTypes);
|
|
7
7
|
const serializedImportMap = serializeImportMap(relativeToPath, packageMappings, typesMap, requiredTypes);
|
|
8
8
|
return `/**
|
|
9
9
|
* This provides the structure needed for typescript to be aware of routes and their return types
|
|
@@ -44,11 +44,13 @@ ${Array.from(typesMap.customTypes.entries())
|
|
|
44
44
|
})
|
|
45
45
|
.join('\n')}`;
|
|
46
46
|
}
|
|
47
|
-
function generateRoutes(routesMeta, typesMap, requiredTypes) {
|
|
47
|
+
function generateRoutes(functionsMeta, routesMeta, typesMap, requiredTypes) {
|
|
48
48
|
// Initialize an object to collect routes
|
|
49
49
|
const routesObj = {};
|
|
50
50
|
for (const meta of routesMeta) {
|
|
51
|
-
const { route, method,
|
|
51
|
+
const { route, method, pikkuFuncName } = meta;
|
|
52
|
+
const input = functionsMeta[pikkuFuncName]?.inputs?.[0];
|
|
53
|
+
const output = functionsMeta[pikkuFuncName]?.outputs?.[0];
|
|
52
54
|
// Initialize the route entry if it doesn't exist
|
|
53
55
|
if (!routesObj[route]) {
|
|
54
56
|
routesObj[route] = {};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { HTTPRoutesMeta } from '@pikku/core/http';
|
|
2
2
|
import { MetaInputTypes, TypesMap } from '@pikku/inspector';
|
|
3
|
-
|
|
3
|
+
import { FunctionsMeta } from '@pikku/core';
|
|
4
|
+
export declare const serializeTypedRoutesMap: (relativeToPath: string, packageMappings: Record<string, string>, typesMap: TypesMap, functionsMeta: FunctionsMeta, routesMeta: HTTPRoutesMeta, metaTypes: MetaInputTypes) => string;
|
|
4
5
|
export declare function generateCustomTypes(typesMap: TypesMap, requiredTypes: Set<string>): string;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { serializeImportMap } from './serialize-import-map.js';
|
|
2
|
-
export const serializeTypedRoutesMap = (relativeToPath, packageMappings, typesMap, routesMeta, metaTypes) => {
|
|
2
|
+
export const serializeTypedRoutesMap = (relativeToPath, packageMappings, typesMap, functionsMeta, routesMeta, metaTypes) => {
|
|
3
3
|
const requiredTypes = new Set();
|
|
4
4
|
const serializedCustomTypes = generateCustomTypes(typesMap, requiredTypes);
|
|
5
5
|
const serializedMetaTypes = generateMetaTypes(metaTypes, typesMap);
|
|
6
|
-
const serializedRoutes = generateRoutes(routesMeta, typesMap, requiredTypes);
|
|
6
|
+
const serializedRoutes = generateRoutes(routesMeta, functionsMeta, typesMap, requiredTypes);
|
|
7
7
|
const serializedImportMap = serializeImportMap(relativeToPath, packageMappings, typesMap, requiredTypes);
|
|
8
8
|
return `/**
|
|
9
9
|
* This provides the structure needed for typescript to be aware of routes and their return types
|
|
@@ -44,11 +44,17 @@ ${Array.from(typesMap.customTypes.entries())
|
|
|
44
44
|
})
|
|
45
45
|
.join('\n')}`;
|
|
46
46
|
}
|
|
47
|
-
function generateRoutes(routesMeta, typesMap, requiredTypes) {
|
|
47
|
+
function generateRoutes(routesMeta, functionsMeta, typesMap, requiredTypes) {
|
|
48
48
|
// Initialize an object to collect routes
|
|
49
49
|
const routesObj = {};
|
|
50
50
|
for (const meta of routesMeta) {
|
|
51
|
-
const { route, method,
|
|
51
|
+
const { route, method, pikkuFuncName } = meta;
|
|
52
|
+
const functionMeta = functionsMeta[pikkuFuncName];
|
|
53
|
+
if (!functionMeta) {
|
|
54
|
+
throw new Error(`Function ${pikkuFuncName} not found in functionsMeta. Please check your configuration.`);
|
|
55
|
+
}
|
|
56
|
+
const input = functionMeta.inputs ? functionMeta.inputs[0] : undefined;
|
|
57
|
+
const output = functionMeta.outputs ? functionMeta.outputs[0] : undefined;
|
|
52
58
|
// Initialize the route entry if it doesn't exist
|
|
53
59
|
if (!routesObj[route]) {
|
|
54
60
|
routesObj[route] = {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pikku/cli",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.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.7.
|
|
26
|
-
"@pikku/inspector": "^0.7.
|
|
25
|
+
"@pikku/core": "^0.7.4",
|
|
26
|
+
"@pikku/inspector": "^0.7.4",
|
|
27
27
|
"@types/cookie": "^0.6.0",
|
|
28
28
|
"@types/uuid": "^10.0.0",
|
|
29
29
|
"chalk": "^5.4.1",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { HTTPRoutesMeta, pikkuState } from '@pikku/core'
|
|
1
|
+
import { FunctionsMeta, HTTPRoutesMeta, pikkuState } from '@pikku/core'
|
|
2
2
|
import _convertSchema from '@openapi-contrib/json-schema-to-openapi-schema'
|
|
3
3
|
const convertSchema =
|
|
4
4
|
'default' in _convertSchema ? (_convertSchema.default as any) : _convertSchema
|
|
@@ -75,12 +75,16 @@ const getErrorResponseForConstructorName = (constructorName: string) => {
|
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
const convertSchemasToBodyPayloads = async (
|
|
78
|
+
functionsMeta: FunctionsMeta,
|
|
78
79
|
routesMeta: HTTPRoutesMeta,
|
|
79
80
|
schemas: Record<string, any>
|
|
80
81
|
) => {
|
|
81
82
|
const requiredSchemas = new Set(
|
|
82
83
|
routesMeta
|
|
83
|
-
.map(({ inputTypes,
|
|
84
|
+
.map(({ inputTypes, pikkuFuncName }) => {
|
|
85
|
+
const output = functionsMeta[pikkuFuncName]?.outputs?.[0]
|
|
86
|
+
return [inputTypes?.body, output]
|
|
87
|
+
})
|
|
84
88
|
.flat()
|
|
85
89
|
.filter((schema) => !!schema)
|
|
86
90
|
)
|
|
@@ -100,6 +104,7 @@ const convertSchemasToBodyPayloads = async (
|
|
|
100
104
|
}
|
|
101
105
|
|
|
102
106
|
export async function generateOpenAPISpec(
|
|
107
|
+
functionsMeta: FunctionsMeta,
|
|
103
108
|
routeMeta: HTTPRoutesMeta,
|
|
104
109
|
schemas: Record<string, any>,
|
|
105
110
|
additionalInfo: OpenAPISpecInfo
|
|
@@ -107,7 +112,17 @@ export async function generateOpenAPISpec(
|
|
|
107
112
|
const paths: Record<string, any> = {}
|
|
108
113
|
|
|
109
114
|
routeMeta.forEach((meta) => {
|
|
110
|
-
const { route, method, inputTypes,
|
|
115
|
+
const { route, method, inputTypes, pikkuFuncName, params, query, docs } =
|
|
116
|
+
meta
|
|
117
|
+
const functionMeta = functionsMeta[pikkuFuncName]
|
|
118
|
+
if (!functionMeta) {
|
|
119
|
+
console.error(
|
|
120
|
+
`• No function metadata found for '${pikkuFuncName}' in route '${route}'.`
|
|
121
|
+
)
|
|
122
|
+
return
|
|
123
|
+
}
|
|
124
|
+
const output = functionMeta.outputs ? functionMeta.outputs[0] : undefined
|
|
125
|
+
|
|
111
126
|
const path = route.replace(/:(\w+)/g, '{$1}') // Convert ":param" to "{param}"
|
|
112
127
|
|
|
113
128
|
if (!paths[path]) {
|
|
@@ -194,7 +209,11 @@ export async function generateOpenAPISpec(
|
|
|
194
209
|
servers: additionalInfo.servers,
|
|
195
210
|
paths,
|
|
196
211
|
components: {
|
|
197
|
-
schemas: await convertSchemasToBodyPayloads(
|
|
212
|
+
schemas: await convertSchemasToBodyPayloads(
|
|
213
|
+
functionsMeta,
|
|
214
|
+
routeMeta,
|
|
215
|
+
schemas
|
|
216
|
+
),
|
|
198
217
|
responses: {},
|
|
199
218
|
parameters: {},
|
|
200
219
|
examples: {},
|
package/src/schema-generator.ts
CHANGED
|
@@ -1,45 +1,27 @@
|
|
|
1
1
|
import { createGenerator, RootlessError } from 'ts-json-schema-generator'
|
|
2
2
|
import { logInfo, writeFileInDir } from './utils.js'
|
|
3
3
|
import { mkdir, writeFile } from 'fs/promises'
|
|
4
|
-
import { JSONValue } from '@pikku/core'
|
|
4
|
+
import { FunctionsMeta, JSONValue } from '@pikku/core'
|
|
5
5
|
import { HTTPRoutesMeta } from '@pikku/core/http'
|
|
6
6
|
import { TypesMap } from '@pikku/inspector'
|
|
7
7
|
|
|
8
8
|
export async function generateSchemas(
|
|
9
9
|
tsconfig: string,
|
|
10
|
-
|
|
10
|
+
typesMap: TypesMap,
|
|
11
|
+
functionMeta: FunctionsMeta,
|
|
11
12
|
httpRoutesMeta: HTTPRoutesMeta
|
|
12
13
|
): Promise<Record<string, JSONValue>> {
|
|
13
|
-
const schemasSet = new Set(
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
try {
|
|
21
|
-
const uniqueName = typesMap.getUniqueName(input)
|
|
22
|
-
if (uniqueName) {
|
|
23
|
-
found = true
|
|
24
|
-
schemasSet.add(uniqueName)
|
|
25
|
-
break
|
|
26
|
-
}
|
|
27
|
-
} catch (e) {}
|
|
28
|
-
}
|
|
29
|
-
if (!found) {
|
|
30
|
-
console.error('Input type not found in any types map:', input)
|
|
14
|
+
const schemasSet = new Set(typesMap.customTypes.keys())
|
|
15
|
+
for (const { inputs, outputs } of Object.values(functionMeta)) {
|
|
16
|
+
const types = [...(inputs || []), ...(outputs || [])]
|
|
17
|
+
for (const type of types) {
|
|
18
|
+
const uniqueName = typesMap.getUniqueName(type)
|
|
19
|
+
if (uniqueName) {
|
|
20
|
+
schemasSet.add(uniqueName)
|
|
31
21
|
}
|
|
32
22
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
// const uniqueName = typesMap.getUniqueName(output)
|
|
36
|
-
// if (uniqueName) {
|
|
37
|
-
// console.log('Adding output schema:', uniqueName)
|
|
38
|
-
// schemasSet.add(uniqueName)
|
|
39
|
-
// break
|
|
40
|
-
// }
|
|
41
|
-
// }
|
|
42
|
-
// }
|
|
23
|
+
}
|
|
24
|
+
for (const { inputTypes } of httpRoutesMeta) {
|
|
43
25
|
if (inputTypes?.body) {
|
|
44
26
|
schemasSet.add(inputTypes.body)
|
|
45
27
|
}
|
|
@@ -78,7 +60,7 @@ export async function saveSchemas(
|
|
|
78
60
|
schemaParentDir: string,
|
|
79
61
|
schemas: Record<string, JSONValue>,
|
|
80
62
|
typesMap: TypesMap,
|
|
81
|
-
|
|
63
|
+
functionsMeta: FunctionsMeta,
|
|
82
64
|
supportsImportAttributes: boolean
|
|
83
65
|
) {
|
|
84
66
|
await writeFileInDir(
|
|
@@ -87,10 +69,10 @@ export async function saveSchemas(
|
|
|
87
69
|
)
|
|
88
70
|
|
|
89
71
|
const desiredSchemas = new Set([
|
|
90
|
-
...
|
|
91
|
-
.map(({
|
|
92
|
-
|
|
93
|
-
|
|
72
|
+
...Object.values(functionsMeta)
|
|
73
|
+
.map(({ inputs, outputs }) => [
|
|
74
|
+
inputs?.[0] ? typesMap.getUniqueName(inputs[0]) : undefined,
|
|
75
|
+
outputs?.[0] ? typesMap.getUniqueName(outputs[0]) : undefined,
|
|
94
76
|
])
|
|
95
77
|
.flat()
|
|
96
78
|
.filter(
|
|
@@ -1,18 +1,25 @@
|
|
|
1
1
|
import { HTTPRoutesMeta } from '@pikku/core/http'
|
|
2
2
|
import { serializeImportMap } from './serialize-import-map.js'
|
|
3
3
|
import { MetaInputTypes, TypesMap } from '@pikku/inspector'
|
|
4
|
+
import { FunctionsMeta } from '@pikku/core'
|
|
4
5
|
|
|
5
6
|
export const serializeTypedRoutesMap = (
|
|
6
7
|
relativeToPath: string,
|
|
7
8
|
packageMappings: Record<string, string>,
|
|
8
9
|
typesMap: TypesMap,
|
|
10
|
+
functionsMeta: FunctionsMeta,
|
|
9
11
|
routesMeta: HTTPRoutesMeta,
|
|
10
12
|
metaTypes: MetaInputTypes
|
|
11
13
|
) => {
|
|
12
14
|
const requiredTypes = new Set<string>()
|
|
13
15
|
const serializedCustomTypes = generateCustomTypes(typesMap, requiredTypes)
|
|
14
16
|
const serializedMetaTypes = generateMetaTypes(metaTypes, typesMap)
|
|
15
|
-
const serializedRoutes = generateRoutes(
|
|
17
|
+
const serializedRoutes = generateRoutes(
|
|
18
|
+
functionsMeta,
|
|
19
|
+
routesMeta,
|
|
20
|
+
typesMap,
|
|
21
|
+
requiredTypes
|
|
22
|
+
)
|
|
16
23
|
|
|
17
24
|
const serializedImportMap = serializeImportMap(
|
|
18
25
|
relativeToPath,
|
|
@@ -66,6 +73,7 @@ ${Array.from(typesMap.customTypes.entries())
|
|
|
66
73
|
}
|
|
67
74
|
|
|
68
75
|
function generateRoutes(
|
|
76
|
+
functionsMeta: FunctionsMeta,
|
|
69
77
|
routesMeta: HTTPRoutesMeta,
|
|
70
78
|
typesMap: TypesMap,
|
|
71
79
|
requiredTypes: Set<string>
|
|
@@ -77,7 +85,9 @@ function generateRoutes(
|
|
|
77
85
|
> = {}
|
|
78
86
|
|
|
79
87
|
for (const meta of routesMeta) {
|
|
80
|
-
const { route, method,
|
|
88
|
+
const { route, method, pikkuFuncName } = meta
|
|
89
|
+
const input = functionsMeta[pikkuFuncName]?.inputs?.[0]
|
|
90
|
+
const output = functionsMeta[pikkuFuncName]?.outputs?.[0]
|
|
81
91
|
|
|
82
92
|
// Initialize the route entry if it doesn't exist
|
|
83
93
|
if (!routesObj[route]) {
|
|
@@ -1,18 +1,25 @@
|
|
|
1
1
|
import { HTTPRoutesMeta } from '@pikku/core/http'
|
|
2
2
|
import { serializeImportMap } from './serialize-import-map.js'
|
|
3
3
|
import { MetaInputTypes, TypesMap } from '@pikku/inspector'
|
|
4
|
+
import { FunctionsMeta } from '@pikku/core'
|
|
4
5
|
|
|
5
6
|
export const serializeTypedRoutesMap = (
|
|
6
7
|
relativeToPath: string,
|
|
7
8
|
packageMappings: Record<string, string>,
|
|
8
9
|
typesMap: TypesMap,
|
|
10
|
+
functionsMeta: FunctionsMeta,
|
|
9
11
|
routesMeta: HTTPRoutesMeta,
|
|
10
12
|
metaTypes: MetaInputTypes
|
|
11
13
|
) => {
|
|
12
14
|
const requiredTypes = new Set<string>()
|
|
13
15
|
const serializedCustomTypes = generateCustomTypes(typesMap, requiredTypes)
|
|
14
16
|
const serializedMetaTypes = generateMetaTypes(metaTypes, typesMap)
|
|
15
|
-
const serializedRoutes = generateRoutes(
|
|
17
|
+
const serializedRoutes = generateRoutes(
|
|
18
|
+
routesMeta,
|
|
19
|
+
functionsMeta,
|
|
20
|
+
typesMap,
|
|
21
|
+
requiredTypes
|
|
22
|
+
)
|
|
16
23
|
|
|
17
24
|
const serializedImportMap = serializeImportMap(
|
|
18
25
|
relativeToPath,
|
|
@@ -67,6 +74,7 @@ ${Array.from(typesMap.customTypes.entries())
|
|
|
67
74
|
|
|
68
75
|
function generateRoutes(
|
|
69
76
|
routesMeta: HTTPRoutesMeta,
|
|
77
|
+
functionsMeta: FunctionsMeta,
|
|
70
78
|
typesMap: TypesMap,
|
|
71
79
|
requiredTypes: Set<string>
|
|
72
80
|
) {
|
|
@@ -77,7 +85,15 @@ function generateRoutes(
|
|
|
77
85
|
> = {}
|
|
78
86
|
|
|
79
87
|
for (const meta of routesMeta) {
|
|
80
|
-
const { route, method,
|
|
88
|
+
const { route, method, pikkuFuncName } = meta
|
|
89
|
+
const functionMeta = functionsMeta[pikkuFuncName]
|
|
90
|
+
if (!functionMeta) {
|
|
91
|
+
throw new Error(
|
|
92
|
+
`Function ${pikkuFuncName} not found in functionsMeta. Please check your configuration.`
|
|
93
|
+
)
|
|
94
|
+
}
|
|
95
|
+
const input = functionMeta.inputs ? functionMeta.inputs[0] : undefined
|
|
96
|
+
const output = functionMeta.outputs ? functionMeta.outputs[0] : undefined
|
|
81
97
|
|
|
82
98
|
// Initialize the route entry if it doesn't exist
|
|
83
99
|
if (!routesObj[route]) {
|