@patchworkdev/pdk
Version:
Patchwork Development Kit
103 lines (97 loc) • 4.33 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateReactComponents = generateReactComponents;
const promises_1 = __importDefault(require("fs/promises"));
const path_1 = __importDefault(require("path"));
const api_1 = require("../../common/helpers/api");
const config_1 = require("../../common/helpers/config");
const error_1 = require("../../common/helpers/error");
const file_1 = require("../../common/helpers/file");
const logger_1 = require("../../common/helpers/logger");
const text_1 = require("../../common/helpers/text");
const trpcRouteToHookName = (route) => 'use' + (0, text_1.pascalCase)(route);
async function generateReactComponents(configPath) {
const configDir = path_1.default.dirname(configPath);
const trpcRouter = path_1.default.join(configDir, 'ponder', 'src', 'generated', 'api.ts');
const componentsDir = path_1.default.join(configDir, 'www', 'src', 'generated', 'components');
const ponderSchemaPath = path_1.default.join(configDir, 'ponder', 'ponder.schema.ts');
// Ensure components directory exists
try {
await promises_1.default.mkdir(componentsDir, { recursive: true });
}
catch (error) {
throw new error_1.PDKError(error_1.ErrorCode.DIR_NOT_FOUND, `Error creating components directory at ${componentsDir}`);
}
const ponderSchema = await (0, config_1.loadPonderSchema)(ponderSchemaPath);
const apiStructure = (0, api_1.analyzeAPI)(trpcRouter);
for (let key in apiStructure) {
if (key.includes('getPaginated')) {
const hook = trpcRouteToHookName(key);
const entity = key.split('.')[0];
const template = generateComponent('getPaginated', entity, hook, ponderSchema);
const componentFile = path_1.default.join(componentsDir, `${(0, text_1.pascalCase)(entity)}List.tsx`);
await (0, file_1.formatAndSaveFile)(componentFile, template);
logger_1.logger.debug(`Generated component: ${componentFile}`);
}
}
logger_1.logger.info('React components generation completed successfully.');
}
function generateComponent(template, entity, hook, ponderSchema) {
if (ponderSchema[entity].type == 'table') {
const td = ponderSchema[entity]._schema ?? {};
const vars = [];
const varOutputs = [];
for (const v in td) {
let optional = '';
let bigint = '';
if (td[v].type === 'one' || td[v].type === 'many') {
// ignore joins at the moment
continue;
}
if (v === 'timestamp') {
varOutputs.push(`<p>Timestamp: {new Date(Number(timestamp)).toLocaleString()}</p>`);
vars.push(v);
continue;
}
if (td[v].isOptional) {
optional = "|| ''";
if (td[v].type === 'bigint') {
bigint = '?.toString()';
}
}
else if (td[v].type === 'bigint') {
bigint = '.toString()';
}
varOutputs.push(`<p>${v}: {${v}${bigint}${optional}}</p>`);
vars.push(v);
}
const typeName = `${(0, text_1.pascalCase)(entity)}Item`;
const componentName = `${(0, text_1.pascalCase)(entity)}ItemComponent`;
return `
import React from 'react';
import { ${hook} } from '../hooks';
import PaginatedList from './PaginatedList';
import { inferProcedureOutput } from '@trpc/server';
import { AppRouter } from '../../../ponder/src/api';
type ${typeName} = inferProcedureOutput<AppRouter['${entity}']['getPaginated']>['items'][number];
const ${componentName}: React.FC<${typeName}> = ({ ${vars.join(',')}}) => (
<div key={id}>
${varOutputs.join('\n')}
</div>
);
const ${entity}List: React.FC = () => (
<PaginatedList<${typeName}>
useQueryHook={${hook}}
itemsPerPage={10}
renderItem={(item) => <${componentName} {...item} />}
title="${entity} List"
/>
);
export default ${entity}List;
`;
}
return ``;
}