gen and build working I think

This commit is contained in:
Kurt Hutten IrevDev
2022-08-02 05:55:20 +10:00
parent 733d244f7c
commit 97bf5a8a1b
5 changed files with 203 additions and 164 deletions

View File

@ -1,6 +1,6 @@
{
"name": "@kittycad/lib",
"version": "0.0.6",
"version": "0.0.7",
"description": "ts lib",
"exports": {
".": {
@ -50,7 +50,8 @@
"tsc": "tsc",
"build2": "rimraf dist && npm run build:types && npm run build:js",
"build:js": "rollup -c",
"build:types": "tsc --emitDeclarationOnly"
"build:types": "tsc --emitDeclarationOnly",
"modelsGen": "ts-node --project ./tsconfig.gen.json ./src/modelsGen.ts && prettier --config .prettierrc --write ./src"
},
"author": "Kurt Hutten <kurt@kittycad.io>",
"license": "MIT",

View File

@ -42,145 +42,160 @@ export default async function apiGen(lookup: any) {
exportsStr: string[];
};
} = {};
const writePromises = Object.entries(operations).map(async ([operationId, operation]) => {
if ('hidden' === (operation.specSection as any).tags[0]) {
return;
}
let template: string = await fsp.readFile('./src/template.ts.txt', 'utf8');
const path = operation.path;
const params = operation.specSection
.parameters as OpenAPIV3.ParameterObject[];
template = template.replaceAll(',', ',');
const inputTypes: string[] = [];
const inputParams: string[] = [];
let urlPathParams: string[] = path.split('/');
const urlQueryParams: string[] = [];
(params || []).forEach(({ name, in: _in }) => {
inputTypes.push(`${name}: string`);
if (!name) {
throw 'no name for param';
const writePromises = Object.entries(operations).map(
async ([operationId, operation]) => {
if ('hidden' === (operation.specSection as any).tags[0]) {
return;
}
inputParams.push(name);
if (_in === 'path') {
urlPathParams = urlPathParams.map((p) => {
if (p === `{${name}}`) {
return `\${${name}}`;
}
return p;
});
let template: string = await fsp.readFile(
'./src/template.ts.txt',
'utf8',
);
const path = operation.path;
const params = operation.specSection
.parameters as OpenAPIV3.ParameterObject[];
template = template.replaceAll(',', ',');
const inputTypes: string[] = [];
const inputParams: string[] = [];
let urlPathParams: string[] = path.split('/');
const urlQueryParams: string[] = [];
(params || []).forEach(({ name, in: _in }) => {
inputTypes.push(`${name}: string`);
if (!name) {
throw 'no name for param';
}
inputParams.push(name);
if (_in === 'path') {
urlPathParams = urlPathParams.map((p) => {
if (p === `{${name}}`) {
return `\${${name}}`;
}
return p;
});
} else {
urlQueryParams.push(`${name}=\${${name}}`);
}
});
const templateUrlPath = wrapInBacktics(
`${urlPathParams.join('/')}${
urlQueryParams.length ? `?${urlQueryParams.join('&')}` : ''
}`,
);
const requestBody = operation.specSection
?.requestBody as OpenAPIV3.ResponseObject;
if (requestBody?.content?.['application/octet-stream']) {
const schema = requestBody.content['application/octet-stream']
.schema as OpenAPIV3.SchemaObject;
if (schema?.type !== 'string') {
throw 'requestBody type not implemented';
}
inputTypes.push('body: string');
inputParams.push('body');
template = template.replaceAll("body: 'BODY'", 'body');
} else {
urlQueryParams.push(`${name}=\${${name}}`);
template = template.replaceAll(/body: 'BODY'.+/g, '');
}
});
const templateUrlPath = wrapInBacktics(
`${urlPathParams.join('/')}${
urlQueryParams.length ? `?${urlQueryParams.join('&')}` : ''
}`,
);
const requestBody = operation.specSection
?.requestBody as OpenAPIV3.ResponseObject;
if (requestBody?.content?.['application/octet-stream']) {
const schema = requestBody.content['application/octet-stream']
.schema as OpenAPIV3.SchemaObject;
if (schema?.type !== 'string') {
throw 'requestBody type not implemented';
if (!inputParams.length) {
template = replacer(template, [
[/interface FunctionNameParams(.|\n)+?}/g, ''],
[/functionNameParams: FunctionNameParams.+/g, ''],
]);
}
inputTypes.push('body: string');
inputParams.push('body');
template = template.replaceAll("body: 'BODY'", 'body');
} else {
template = template.replaceAll(/body: 'BODY'.+/g, '');
}
if (!inputParams.length) {
template = replacer(template, [
[/interface FunctionNameParams(.|\n)+?}/g, ''],
[/functionNameParams: FunctionNameParams.+/g, ''],
]);
}
const importedTypes: string[] = [];
Object.values(operation.specSection?.responses).forEach((response) => {
const schema = (response as any)?.content?.['application/json']
?.schema as OpenAPIV3.SchemaObject;
if (!schema) {
let ref = (response as any)?.$ref || '';
ref = ref.replace('responses', 'schemas');
const typeReference = lookup[ref];
const importedTypes: string[] = [];
Object.values(operation.specSection?.responses).forEach((response) => {
const schema = (response as any)?.content?.['application/json']
?.schema as OpenAPIV3.SchemaObject;
if (!schema) {
let ref = (response as any)?.$ref || '';
ref = ref.replace('responses', 'schemas');
const typeReference = lookup[ref];
if (!importedTypes.includes(typeReference) && ref) {
importedTypes.push(typeReference);
}
} else if ((response as any)?.content['application/json']?.schema?.$ref) {
const ref = (response as any)?.content['application/json']?.schema
?.$ref;
const typeReference = lookup[ref];
if (!importedTypes.includes(typeReference)) {
importedTypes.push(typeReference);
}
} else if (Object.keys(schema).length === 0) {
// do nothing
} else if (schema.type === 'array') {
const items = schema.items as OpenAPIV3.SchemaObject;
if ((items as any).$ref) {
const typeReference = lookup[(items as any).$ref];
if (!importedTypes.includes(typeReference + '[]')) {
importedTypes.push(typeReference + '[]');
if (!importedTypes.includes(typeReference) && ref) {
importedTypes.push(typeReference);
}
} else if (
(response as any)?.content['application/json']?.schema?.$ref
) {
const ref = (response as any)?.content['application/json']?.schema
?.$ref;
const typeReference = lookup[ref];
if (!importedTypes.includes(typeReference)) {
importedTypes.push(typeReference);
}
} else if (Object.keys(schema).length === 0) {
// do nothing
} else if (schema.type === 'array') {
const items = schema.items as OpenAPIV3.SchemaObject;
if ((items as any).$ref) {
const typeReference = lookup[(items as any).$ref];
if (!importedTypes.includes(typeReference + '[]')) {
importedTypes.push(typeReference + '[]');
}
} else {
throw 'not implemented';
}
} else {
console.log(schema);
throw 'not implemented';
}
} else {
console.log(schema);
throw 'not implemented';
});
const returnTyping = `type ${FC(operationId)}_return = ${
importedTypes.length ? importedTypes.join(' | ') : 'any'
}`;
template = replacer(template, [
[/interface FunctionNameReturn(.|\n)+?}/g, returnTyping],
[`'string' + functionNameParams.exampleParam`, templateUrlPath],
[
`functionNameParams:`,
`{${inputParams.filter((a) => a).join(', ')}}:`,
],
[`exampleParam: string`, inputTypes.join('; ')],
["method: 'METHOD'", `method: 'POST'`],
['function functionName', `function ${operationId}`],
['FunctionNameReturn', `${FC(operationId)}_return`],
['FunctionNameParams', `${FC(operationId)}_params`],
[
"import * as types from './src/models.ts';",
`import {${importedTypes
.map((a) => (a || '').replaceAll('[', '').replaceAll(']', ''))
.join(', ')}} from '../../models.js';`,
],
]);
const tag = operation.specSection?.tags?.[0] || 'err';
const safeTag = tag.replaceAll('-', '_');
if (!indexFile[safeTag]) {
indexFile[safeTag] = {
importsStr: [],
exportsStr: [],
};
}
});
const returnTyping = `type ${FC(operationId)}_return = ${
importedTypes.length ? importedTypes.join(' | ') : 'any'
}`;
template = replacer(template, [
[/interface FunctionNameReturn(.|\n)+?}/g, returnTyping],
[`'string' + functionNameParams.exampleParam`, templateUrlPath],
[`functionNameParams:`, `{${inputParams.filter((a) => a).join(', ')}}:`],
[`exampleParam: string`, inputTypes.join('; ')],
["method: 'METHOD'", `method: 'POST'`],
['function functionName', `function ${operationId}`],
['FunctionNameReturn', `${FC(operationId)}_return`],
['FunctionNameParams', `${FC(operationId)}_params`],
[
"import * as types from './src/models.ts';",
`import {${importedTypes
.map((a) => (a || '').replaceAll('[', '').replaceAll(']', ''))
.join(', ')}} from '../../models.js';`,
],
]);
const tag = operation.specSection?.tags?.[0] || 'err';
const safeTag = tag.replaceAll('-', '_');
if (!indexFile[safeTag]) {
indexFile[safeTag] = {
importsStr: [],
exportsStr: [],
};
}
indexFile[safeTag].importsStr.push(
`import ${operationId} from './api/${tag}/${operationId}.js';`,
indexFile[safeTag].importsStr.push(
`import ${operationId} from './api/${tag}/${operationId}.js';`,
);
indexFile[safeTag].exportsStr.push(operationId)
return fsp.writeFile(`./src/api/${tag}/${operationId}.ts`, template, 'utf8');
});
indexFile[safeTag].exportsStr.push(operationId);
return fsp.writeFile(
`./src/api/${tag}/${operationId}.ts`,
template,
'utf8',
);
},
);
await Promise.all(writePromises);
console.log('HEYY yo')
let indexFileString = ''
Object.entries(indexFile).forEach(([tag, { importsStr: imports, exportsStr: exports }]) => {
indexFileString += imports.join('\n') + '\n';
indexFileString += `export const ${tag} = { ${exports.join(', ')} };\n\n`;
})
console.log('hmm', indexFile, indexFileString);
await fsp.writeFile(`./src/main.ts`, indexFileString, 'utf8');
let indexFileString = '';
Object.entries(indexFile).forEach(
([tag, { importsStr: imports, exportsStr: exports }]) => {
indexFileString += imports.join('\n') + '\n';
indexFileString += `export const ${tag} = { ${exports.join(', ')} };\n\n`;
},
);
indexFileString += `export * as Models from './models.js';\n`;
await fsp.writeFile(`./src/index.ts`, indexFileString, 'utf8');
}
function wrapInBacktics(str: string) {

View File

@ -1,8 +1,3 @@
import get_schema from './api/meta/get_schema.js';
import ping from './api/meta/ping.js';
import get_metadata from './api/meta/get_metadata.js';
export const meta = { get_schema, ping, get_metadata };
import get_api_call_metrics from './api/api-calls/get_api_call_metrics.js';
import get_api_call from './api/api-calls/get_api_call.js';
import get_async_operation from './api/api-calls/get_async_operation.js';
@ -22,91 +17,98 @@ export const api_calls = {
list_api_calls_for_user,
};
import get_file_conversion from './api/file/get_file_conversion.js';
import get_schema from './api/meta/get_schema.js';
import get_metadata from './api/meta/get_metadata.js';
import ping from './api/meta/ping.js';
export const meta = { get_schema, get_metadata, ping };
import create_file_conversion from './api/file/create_file_conversion.js';
import create_file_execution from './api/file/create_file_execution.js';
import create_file_density from './api/file/create_file_density.js';
import create_file_mass from './api/file/create_file_mass.js';
import create_file_volume from './api/file/create_file_volume.js';
import create_file_density from './api/file/create_file_density.js';
import create_file_execution from './api/file/create_file_execution.js';
import get_file_conversion from './api/file/get_file_conversion.js';
import get_file_conversion_for_user from './api/file/get_file_conversion_for_user.js';
export const file = {
get_file_conversion,
create_file_conversion,
create_file_execution,
create_file_density,
create_file_mass,
create_file_volume,
create_file_density,
create_file_execution,
get_file_conversion,
get_file_conversion_for_user,
};
import device_auth_request from './api/oauth2/device_auth_request.js';
import device_auth_confirm from './api/oauth2/device_auth_confirm.js';
import device_access_token from './api/oauth2/device_access_token.js';
import device_auth_verify from './api/oauth2/device_auth_verify.js';
import listen_oauth2_provider_callback from './api/oauth2/listen_oauth2_provider_callback.js';
import device_access_token from './api/oauth2/device_access_token.js';
import listen_oauth2_provider_consent from './api/oauth2/listen_oauth2_provider_consent.js';
import device_auth_verify from './api/oauth2/device_auth_verify.js';
export const oauth2 = {
device_auth_request,
device_auth_confirm,
device_access_token,
device_auth_verify,
listen_oauth2_provider_callback,
device_access_token,
listen_oauth2_provider_consent,
device_auth_verify,
};
import create_unit_conversion from './api/unit/create_unit_conversion.js';
export const unit = { create_unit_conversion };
import delete_user_self from './api/users/delete_user_self.js';
import update_user_self from './api/users/update_user_self.js';
import get_user_self from './api/users/get_user_self.js';
import update_user_self from './api/users/update_user_self.js';
import get_user_self_extended from './api/users/get_user_self_extended.js';
import list_users from './api/users/list_users.js';
import list_users_extended from './api/users/list_users_extended.js';
import list_users from './api/users/list_users.js';
import get_user_extended from './api/users/get_user_extended.js';
import get_user from './api/users/get_user.js';
import delete_user_self from './api/users/delete_user_self.js';
export const users = {
delete_user_self,
update_user_self,
get_user_self,
update_user_self,
get_user_self_extended,
list_users,
list_users_extended,
list_users,
get_user_extended,
get_user,
delete_user_self,
};
import create_api_token_for_user from './api/api-tokens/create_api_token_for_user.js';
import list_api_tokens_for_user from './api/api-tokens/list_api_tokens_for_user.js';
import delete_api_token_for_user from './api/api-tokens/delete_api_token_for_user.js';
import create_api_token_for_user from './api/api-tokens/create_api_token_for_user.js';
import get_api_token_for_user from './api/api-tokens/get_api_token_for_user.js';
import delete_api_token_for_user from './api/api-tokens/delete_api_token_for_user.js';
export const api_tokens = {
create_api_token_for_user,
list_api_tokens_for_user,
delete_api_token_for_user,
create_api_token_for_user,
get_api_token_for_user,
delete_api_token_for_user,
};
import delete_payment_information_for_user from './api/payments/delete_payment_information_for_user.js';
import get_payment_information_for_user from './api/payments/get_payment_information_for_user.js';
import create_payment_information_for_user from './api/payments/create_payment_information_for_user.js';
import update_payment_information_for_user from './api/payments/update_payment_information_for_user.js';
import create_payment_intent_for_user from './api/payments/create_payment_intent_for_user.js';
import get_payment_balance_for_user from './api/payments/get_payment_balance_for_user.js';
import list_payment_methods_for_user from './api/payments/list_payment_methods_for_user.js';
import update_payment_information_for_user from './api/payments/update_payment_information_for_user.js';
import list_invoices_for_user from './api/payments/list_invoices_for_user.js';
import list_payment_methods_for_user from './api/payments/list_payment_methods_for_user.js';
import create_payment_intent_for_user from './api/payments/create_payment_intent_for_user.js';
import delete_payment_method_for_user from './api/payments/delete_payment_method_for_user.js';
export const payments = {
delete_payment_information_for_user,
get_payment_information_for_user,
create_payment_information_for_user,
update_payment_information_for_user,
create_payment_intent_for_user,
get_payment_balance_for_user,
list_payment_methods_for_user,
update_payment_information_for_user,
list_invoices_for_user,
list_payment_methods_for_user,
create_payment_intent_for_user,
delete_payment_method_for_user,
};
import get_session_for_user from './api/sessions/get_session_for_user.js';
export const sessions = { get_session_for_user };
export * as Models from './models.js';

View File

@ -1,6 +1,6 @@
import fsp from 'node:fs/promises';
import fsp from 'fs/promises';
import { OpenAPIV3 } from 'openapi-types';
import apiGen from './apiGen.js';
import apiGen from './apiGen';
main();
@ -62,7 +62,10 @@ async function main() {
const items = subSchema.items;
if ((items as any).$ref) {
const ref = (items as any).$ref;
return addCommentInfo(subSchema, `${key}: ${typeNameReference[ref]}[]`);
return addCommentInfo(
subSchema,
`${key}: ${typeNameReference[ref]}[]`,
);
}
return `${makeTypeStringForNode(
items as OpenAPIV3.SchemaObject,
@ -74,7 +77,10 @@ async function main() {
) {
if ((subSchema.additionalProperties as any).$ref) {
const ref = (subSchema.additionalProperties as any).$ref;
return addCommentInfo(subSchema, `${key}: {[key: string] : ${typeNameReference[ref]}}`);
return addCommentInfo(
subSchema,
`${key}: {[key: string] : ${typeNameReference[ref]}}`,
);
}
return `${key}: {[key: string] : ${makeTypeStringForNode(
subSchema.additionalProperties as any,
@ -142,11 +148,20 @@ async function main() {
// console.log(typeReference);
// console.log(typeNameReference);
await fsp.writeFile(`./src/models.ts`, template, 'utf8');
apiGen(typeNameReference)
apiGen(typeNameReference);
}
function addCommentInfo(schema: any, typeString: string) {
const { enum: _enum, type, allOf, items, properties, additionalProperties, description, ...newSchema } = schema;
const {
enum: _enum,
type,
allOf,
items,
properties,
additionalProperties,
description,
...newSchema
} = schema;
if (!Object.keys(newSchema).length && !description) {
return typeString;
} else if (!Object.keys(newSchema).length && description) {

6
tsconfig.gen.json Normal file
View File

@ -0,0 +1,6 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "CommonJS"
}
}