Skip to content

Commit

Permalink
Merge pull request #4 from Altroleum/crud-operations
Browse files Browse the repository at this point in the history
Crud operations
  • Loading branch information
charliecooper45 authored Aug 30, 2023
2 parents b945789 + 6d60dad commit 27e1a36
Show file tree
Hide file tree
Showing 19 changed files with 1,289 additions and 166 deletions.
42 changes: 35 additions & 7 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ const writeFiles = async (
supabaseFile: File,
hookFiles: HookFile[],
metadataFile: File,
componentFiles: File[]
componentFiles: {
tableComponents: File[];
joinTableComponents: File[];
viewComponents: File[];
}
) => {
await writeFile(
`${DIRECTORY}/${supabaseFile.fileName}`,
Expand All @@ -29,14 +33,36 @@ const writeFiles = async (
`${DIRECTORY}/${metadataFile.fileName}`,
metadataFile.content
);
await Promise.all(
componentFiles.map((hookFile) => {

const tableComponentPromises = componentFiles.tableComponents.map(
(componentFile) => {
return writeFile(
`${DIRECTORY}/components/${hookFile.fileName}`,
hookFile.content
`${DIRECTORY}/components/tables/${componentFile.fileName}`,
componentFile.content
);
})
}
);
const joinTableComponentPromises = componentFiles.joinTableComponents.map(
(componentFile) => {
return writeFile(
`${DIRECTORY}/components/joinTables/${componentFile.fileName}`,
componentFile.content
);
}
);
const viewComponentPromises = componentFiles.viewComponents.map(
(componentFile) => {
return writeFile(
`${DIRECTORY}/components/views/${componentFile.fileName}`,
componentFile.content
);
}
);
await Promise.all([
...tableComponentPromises,
...joinTableComponentPromises,
...viewComponentPromises,
]);
};

const run = async () => {
Expand All @@ -45,7 +71,9 @@ const run = async () => {

await remove(DIRECTORY);
await ensureDir(`${DIRECTORY}/hooks`);
await ensureDir(`${DIRECTORY}/components`);
await ensureDir(`${DIRECTORY}/components/tables`);
await ensureDir(`${DIRECTORY}/components/joinTables`);
await ensureDir(`${DIRECTORY}/components/views`);
await writeFile(`${DIRECTORY}/${types.fileName}`, types.content);

const supabaseFile = await parseSupabaseFile();
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@backengine/codegen",
"version": "1.0.16",
"version": "2.0.0",
"description": "Generate code for Backengine projects.",
"bin": "build/index.js",
"files": [
Expand Down
79 changes: 22 additions & 57 deletions src/components/index.ts
Original file line number Diff line number Diff line change
@@ -1,63 +1,28 @@
import comment from "../comment";
import { fetchTables } from "../pgMeta/fetchTables";
import type { File, HookFile } from "../types";
import prettier from "prettier";
import { parseNameFormats } from "../utils";
import { parseComponentFilesForTables } from "./tables";
import { parseComponentFilesForJoinTables } from "./joinTables";
import { parseComponentFilesForViews } from "./views";

const mapHookFileToComponent = async (hookFile: HookFile): Promise<File> => {
const {
file: { fileName },
} = hookFile;

const componentName = fileName.replace("use", "");
const { camelCasePlural } = parseNameFormats(componentName);

const content = `
${comment}
"use client";
import ${fileName} from "../hooks/${fileName}";
export default function ${componentName}() {
const { ${camelCasePlural} } = ${fileName}();
return (
<div
style={{
paddingTop: "20px",
}}
>
<code>${camelCasePlural}</code>
<pre
className="border rounded-md text-xs"
style={{
marginTop: "4px",
padding: "16px",
height: "200px",
overflowY: "auto",
}}
>
{JSON.stringify(${camelCasePlural}, null, 2)}
</pre>
</div>
)
};
`;

const formattedContent = await prettier.format(content, {
parser: "typescript",
});
export const parseComponentFiles = async (
hookFiles: HookFile[]
): Promise<{
tableComponents: File[];
joinTableComponents: File[];
viewComponents: File[];
}> => {
const { tables, joinTables } = await fetchTables();

const tableComponents = await parseComponentFilesForTables(hookFiles, tables);
const joinTableComponents = await parseComponentFilesForJoinTables(
hookFiles,
joinTables
);
const viewComponents = await parseComponentFilesForViews(hookFiles);

return {
fileName: `${componentName}.tsx`,
content: formattedContent,
tableComponents,
joinTableComponents,
viewComponents,
};
};

export const parseComponentFiles = async (
hookFiles: HookFile[]
): Promise<File[]> => {
const componentPromises = hookFiles.map(mapHookFileToComponent);
const files = await Promise.all(componentPromises);
return files;
};
164 changes: 164 additions & 0 deletions src/components/joinTables/get.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
import prettier from "prettier";
import comment from "../../comment";
import { TablesResponse } from "../../pgMeta/fetchTables";
import type { File, HookFile } from "../../types";
import { parseFetchFunctionNamesForJoinTable } from "./utils";

export const mapHookFileToGetComponent = async (
hookFile: HookFile,
joinTables: TablesResponse
): Promise<File> => {
const {
entityName,
file: { fileName },
} = hookFile;

const componentName = `${fileName.replace("use", "")}`;

const { tableOneFetchFunctionName, tableTwoFetchFunctionName } =
parseFetchFunctionNamesForJoinTable(joinTables, entityName);

const content = `
${comment}
import { useState } from "react";
import type { TableOneRow, TableTwoRow } from "../../hooks/${fileName}";
export default function Get${componentName}({
${tableOneFetchFunctionName},
${tableTwoFetchFunctionName}
}:
{
${tableOneFetchFunctionName}: (id: TableOneRow["id"]) => Promise<TableTwoRow[]>,
${tableTwoFetchFunctionName}: (id: TableTwoRow["id"]) => Promise<TableOneRow[]>
}) {
const [id, setId] = useState("");
const [data, setData] = useState<TableOneRow[] | TableTwoRow[]>();
return (
<div
style={{
paddingTop: "20px",
}}
>
<pre
className="border rounded-md text-xs"
style={{
marginTop: "4px",
padding: "16px",
height: "200px",
overflowY: "auto",
}}
>
{JSON.stringify(data, null, 2)}
</pre>
<div
className="flex items-center"
style={{
marginTop: "10px",
}}
>
<label
htmlFor="ID"
style={{
flexBasis: "120px",
}}
>
ID
</label>
<input
type="text"
id="ID"
style={{
background: "#000",
color: "#fff",
border: "1px solid #34383A",
marginLeft: "10px",
flex: "1",
borderRadius: "0.375rem",
padding: "4px 16px",
}}
value={id}
onChange={(event) => setId(event.target.value)}
/>
</div>
<div style={{
display: "flex",
marginTop: "10px",
}}>
<button
style={{
background: "#fff",
color: "#000",
padding: "8px 10px",
minWidth: "200px",
borderRadius: "0.375rem",
display: "flex",
alignItems: "center",
justifyContent: "center",
marginRight: "20px",
}}
onClick={() => ${tableOneFetchFunctionName}(id as any).then((data) => setData(data))}
>
<div style={{ marginRight: "10px" }}>Run ${tableOneFetchFunctionName}</div>
<svg
fill="none"
viewBox="0 0 24 24"
strokeWidth={1.5}
stroke="currentColor"
style={{
height: "20px",
}}
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M5.25 5.653c0-.856.917-1.398 1.667-.986l11.54 6.348a1.125 1.125 0 010 1.971l-11.54 6.347a1.125 1.125 0 01-1.667-.985V5.653z"
/>
</svg>
</button>
<button
style={{
background: "#fff",
color: "#000",
padding: "8px 10px",
minWidth: "200px",
borderRadius: "0.375rem",
display: "flex",
alignItems: "center",
justifyContent: "center",
}}
onClick={() => ${tableTwoFetchFunctionName}(id as any).then((data) => setData(data))}
>
<div style={{ marginRight: "10px" }}>Run ${tableTwoFetchFunctionName}</div>
<svg
fill="none"
viewBox="0 0 24 24"
strokeWidth={1.5}
stroke="currentColor"
style={{
height: "20px",
}}
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M5.25 5.653c0-.856.917-1.398 1.667-.986l11.54 6.348a1.125 1.125 0 010 1.971l-11.54 6.347a1.125 1.125 0 01-1.667-.985V5.653z"
/>
</svg>
</button>
</div>
</div>
)
};
`;

const formattedContent = await prettier.format(content, {
parser: "typescript",
});

return {
fileName: `Get${componentName}.tsx`,
content: formattedContent,
};
};
72 changes: 72 additions & 0 deletions src/components/joinTables/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import prettier from "prettier";
import comment from "../../comment";
import type { TablesResponse } from "../../pgMeta/fetchTables";
import type { File, HookFile } from "../../types";
import { mapHookFileToGetComponent } from "./get";
import { parseFetchFunctionNamesForJoinTable } from "./utils";

export const mapHookFileToComponent = async (
hookFile: HookFile,
joinTables: TablesResponse
): Promise<File> => {
const {
entityName,
file: { fileName },
} = hookFile;

const componentName = fileName.replace("use", "");
const getComponentName = `Get${componentName}`;

const { tableOneFetchFunctionName, tableTwoFetchFunctionName } =
parseFetchFunctionNamesForJoinTable(joinTables, entityName);

const content = `
${comment}
"use client";
import ${fileName} from "../../hooks/${fileName}";
import ${getComponentName} from "./${getComponentName}";
export default function ${componentName}() {
const { ${tableOneFetchFunctionName}, ${tableTwoFetchFunctionName} } = ${fileName}();
return (
<div>
<${getComponentName} ${tableOneFetchFunctionName}={${tableOneFetchFunctionName}} ${tableTwoFetchFunctionName}={${tableTwoFetchFunctionName}} />
</div>
)
};
`;

const formattedContent = await prettier.format(content, {
parser: "typescript",
});

return {
fileName: `${componentName}.tsx`,
content: formattedContent,
};
};

export const parseComponentFilesForJoinTables = async (
hookFiles: HookFile[],
joinTables: TablesResponse
): Promise<File[]> => {
const joinTableHookFiles = hookFiles.filter(
(hookFile) => hookFile.entityType === "JOIN_TABLE"
);

const componentPromises = joinTableHookFiles.map((joinTableHookFile) =>
mapHookFileToComponent(joinTableHookFile, joinTables)
);
const getComponentPromises = joinTableHookFiles.map((joinTableHookFile) =>
mapHookFileToGetComponent(joinTableHookFile, joinTables)
);

const files = await Promise.all([
...componentPromises,
...getComponentPromises,
]);
return files;
};
Loading

0 comments on commit 27e1a36

Please sign in to comment.