Page MenuHomeSealhub

add-crud.ts
No OneTemporary

add-crud.ts

import _locreq from "locreq";
import prompts from "prompts";
import { escape_url_params } from "./utils/escape-url-params.js";
import { toKebabCase, toPascalCase } from "js-convert-case";
import { listCollections } from "./utils/list-collections.js";
import {
makeDefaultDisplayFields,
makeDefaultFilterFields,
} from "./templates/shared/collection-list.js";
import { writeFile } from "./utils/write-file.js";
import { extractCollectionClassname } from "./generate-collections.js";
import extract_fields_from_collection from "./utils/extract-fields-from-collection.js";
import { getFieldHandler } from "./templates/shared/shared-crud-form-fields.js";
import { generateRoutes } from "./generate-routes.js";
import { formatWithPrettier } from "./utils/prettier.js";
export async function addCRUD(
params: Partial<{ [key in "collection" | "url"]: string }>,
app_directory: string = process.cwd()
) {
const target_locreq = _locreq(app_directory);
prompts.override(params);
const response = await prompts([
{
type: "autocomplete",
name: "collection",
message:
"Which sealious collection do you like to add CRUD forms for?",
choices: (
await listCollections()
).map((collection) => ({
title: collection,
value: collection,
})),
},
{
type: "text",
name: "url",
message:
"Enter a full absolute path for the new route (for example: /admin/users/): ",
validate: (s: string) =>
s.trim()[0] == "/" ? true : "Should start with a '/'",
initial: function (_, { collection }: { collection: string }) {
return "/" + toKebabCase(collection);
},
},
]);
const collection_name = response.collection as string;
const url = response.url as string;
/* create the list endpoint */
const list_path = target_locreq.resolve(
`src/back/routes/${escape_url_params(url)}/index.page.ts`
);
const [uppercase_collection, collection_fields] = await Promise.all([
extractCollectionClassname(
target_locreq.resolve(
"src/back/collections/" + collection_name + ".ts"
)
),
extract_fields_from_collection(collection_name),
]);
const field_handler_results = await Promise.all(
collection_fields.map(async (field) => {
return getFieldHandler(
collection_name,
field,
(p) => p,
"edit_fields"
);
})
);
const list_content = `import { CRUD } from "@sealcode/crud-ui";
import type { CollectionItem } from "sealious";
import type { ListFilterRender } from "@sealcode/sealgen";
import { Controls, DefaultListFilters, Fields } from "@sealcode/sealgen";
import { ${toPascalCase(
collection_name
)} } from "src/back/collections/collections.js";
import html from "src/back/html.js";
export const actionName = "${toPascalCase(collection_name)}CRUD";
const edit_fields = <const>
{
${field_handler_results
.filter(({ hide_field }) => !hide_field)
.map(({ field }) => field)
.filter((e) => e != "")
.join(",\n")}
};
const edit_controls = [
${field_handler_results
.filter(({ hide_control }) => !hide_control)
.map(({ controls }) => controls)
.filter((e) => e != "")
.join(",\n")}
]
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
const fields_for_display = [
${makeDefaultDisplayFields(collection_fields)}
] as {
field: keyof (typeof ${toPascalCase(collection_name)})["fields"];
label: string;
format?: (value: unknown, item: CollectionItem<typeof ${toPascalCase(
collection_name
)}>) => string | Promise<string>;
}[];
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
const fields_for_filters = [
${makeDefaultFilterFields(collection_fields)}
] as {
field: keyof (typeof ${uppercase_collection})["fields"];
render?: ListFilterRender;
prepareValue?: (filter_value: unknown)=>unknown; // set this function to change what filter value is passed to Sealious
}[];
export default new CRUD({
collection: ${toPascalCase(collection_name)},
nice_collection_name: "${toPascalCase(collection_name)}",
fields_for_display,
fields_for_filters,
html,
list_title: "${toPascalCase(collection_name)} list",
edit_title: "Edit",
edit_button_text: "Edit",
delete_button_text: "Delete",
back_to_list_button_text: "← Back to ${toPascalCase(collection_name)} list",
edit_fields,
edit_controls,
form_value_to_sealious_value: {},
sealious_value_to_form_value: {},
post_edit: async () => {},
post_create: async () => {},
});
`;
await writeFile(list_path, await formatWithPrettier(list_content));
await generateRoutes();
}

File Metadata

Mime Type
text/x-java
Expires
Thu, Jul 3, 20:31 (8 h, 3 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
632585
Default Alt Text
add-crud.ts (4 KB)

Event Timeline