UNPKG

@azure-utils/storybooks

Version:

Utils to upload and manage Storybooks via Azure Functions and storage.

1 lines 25.1 kB
{"version":3,"file":"projects-router-B4T5MHdN.mjs","names":["_request: HttpRequest","context: InvocationContext","request: HttpRequest","options: RouterOptions"],"sources":["../src/components/project-form.tsx","../src/handlers/project-handlers.tsx","../src/routers/projects-router.ts"],"sourcesContent":["import { ProjectSchema, ProjectType } from \"../models/projects\";\nimport { DEFAULT_PURGE_AFTER_DAYS, PATTERNS } from \"../utils/constants\";\nimport { urlBuilder } from \"../utils/url-builder\";\nimport { ErrorMessage } from \"./error-message\";\n\nexport interface ProjectsFormProps {\n project: ProjectType | undefined;\n}\n\nexport async function ProjectForm({ project }: ProjectsFormProps) {\n return (\n <form\n hx-ext=\"response-targets\"\n hx-patch={project ? urlBuilder.projectId(project.id) : undefined}\n hx-post={project ? undefined : urlBuilder.allProjects()}\n hx-target-error=\"#form-error\"\n style={{ maxWidth: \"60ch\" }}\n >\n <fieldset>\n <legend>Details</legend>\n\n {project?.id ? null : (\n <div class=\"field\">\n <label for=\"id\">Project ID</label>\n <input\n id=\"id\"\n name=\"id\"\n pattern={PATTERNS.projectId.pattern}\n required\n />\n <span class=\"description\">\n Only lowercase alphabets, numbers and hyphen (-) allowed. Max\n length: 60 chars\n </span>\n </div>\n )}\n\n <div class=\"field\">\n <label for=\"name\">Project Name</label>\n <input id=\"name\" name=\"name\" required value={project?.name} />\n </div>\n </fieldset>\n\n <fieldset>\n <legend>GitHub</legend>\n\n <div class=\"field\">\n <label for=\"gitHubRepo\">Repo name</label>\n <input\n id=\"gitHubRepo\"\n name=\"gitHubRepo\"\n placeholder=\"owner/repo\"\n required\n pattern=\"^.+\\/.+$\"\n value={project?.gitHubRepo}\n />\n </div>\n\n <div class=\"field\">\n <label for=\"gitHubPath\">Instance path</label>\n <input\n id=\"gitHubPath\"\n name=\"gitHubPath\"\n placeholder=\"packages/ui\"\n value={project?.gitHubPath}\n />\n <span class={\"description\"}>\n Optional. If the Storybook is not is the root of repo.\n </span>\n </div>\n\n <div class=\"field\">\n <label for=\"gitHubDefaultBranch\">Default branch</label>\n <input\n id=\"gitHubDefaultBranch\"\n name=\"gitHubDefaultBranch\"\n placeholder=\"main\"\n value={project?.gitHubDefaultBranch}\n />\n <span class={\"description\"}>\n Optional. If the default branch is not 'main'.\n </span>\n </div>\n </fieldset>\n\n <fieldset>\n <legend>Purge</legend>\n <div class=\"field\">\n <label for=\"purgeBuildsAfterDays\">Purge builds after days</label>\n <input\n id=\"purgeBuildsAfterDays\"\n name=\"purgeBuildsAfterDays\"\n required\n type=\"number\"\n inputmode=\"numeric\"\n value={(\n project?.purgeBuildsAfterDays || DEFAULT_PURGE_AFTER_DAYS\n ).toString()}\n />\n <span class={\"description\"} safe>\n {ProjectSchema.def.shape.purgeBuildsAfterDays.description || \"\"}\n </span>\n </div>\n </fieldset>\n\n <div style={{ display: \"flex\", gap: \"1rem\" }}>\n <button type=\"submit\">{project ? \"Update\" : \"Create\"} Project</button>\n <button type=\"reset\">Reset</button>\n </div>\n\n <ErrorMessage id=\"form-error\" />\n </form>\n );\n}\n","import type {\n HttpRequest,\n HttpResponseInit,\n InvocationContext,\n} from \"@azure/functions\";\nimport { CONTENT_TYPES } from \"../utils/constants\";\nimport { ProjectsTable } from \"../components/projects-table\";\nimport { DocumentLayout } from \"../components/layout\";\nimport {\n responseError,\n responseHTML,\n responseRedirect,\n} from \"../utils/response-utils\";\nimport { RawDataPreview } from \"../components/raw-data\";\nimport { BuildTable } from \"../components/builds-table\";\nimport { getStore } from \"../utils/store\";\nimport { LabelsTable } from \"../components/labels-table\";\nimport {\n ProjectModel,\n ProjectCreateSchema,\n ProjectSchema,\n} from \"../models/projects\";\nimport { urlSearchParamsToObject } from \"../utils/url-utils\";\nimport { urlBuilder } from \"../utils/url-builder\";\nimport { ProjectForm } from \"../components/project-form\";\nimport {\n checkIsEditMode,\n checkIsHTMLRequest,\n checkIsHXRequest,\n checkIsNewMode,\n} from \"../utils/request-utils\";\n\nexport async function listProjects(\n _request: HttpRequest,\n context: InvocationContext\n): Promise<HttpResponseInit> {\n try {\n if (checkIsNewMode()) {\n return responseHTML(\n <DocumentLayout\n title=\"Create Project\"\n breadcrumbs={[{ label: \"Projects\", href: urlBuilder.allProjects() }]}\n >\n <ProjectForm project={undefined} />\n </DocumentLayout>\n );\n }\n\n const { connectionString } = getStore();\n const projectModel = new ProjectModel(context, connectionString);\n const projects = await projectModel.list();\n\n if (checkIsHTMLRequest()) {\n return responseHTML(\n <DocumentLayout\n title=\"All Projects\"\n toolbar={<a href={urlBuilder.projectCreate()}>+ Create</a>}\n >\n <ProjectsTable projects={projects} />\n </DocumentLayout>\n );\n }\n\n return { status: 200, jsonBody: projects };\n } catch (error) {\n return responseError(error, context, 500);\n }\n}\n\nexport async function getProject(\n request: HttpRequest,\n context: InvocationContext\n): Promise<HttpResponseInit> {\n const { projectId } = request.params;\n const { connectionString } = getStore();\n\n if (!projectId) {\n return { status: 400, body: \"Missing project ID\" };\n }\n\n try {\n const projectModel = new ProjectModel(context, connectionString);\n const project = await projectModel.get(projectId);\n\n if (checkIsEditMode()) {\n return responseHTML(\n <DocumentLayout\n title=\"Edit Project\"\n breadcrumbs={[\n { label: \"Projects\", href: urlBuilder.allProjects() },\n { label: projectId, href: urlBuilder.projectId(projectId) },\n ]}\n >\n <ProjectForm project={project} />\n </DocumentLayout>\n );\n }\n\n const builds = await projectModel.buildModel(projectId).list({ limit: 25 });\n const labels = await projectModel.labelModel(projectId).list({ limit: 25 });\n\n if (checkIsHTMLRequest()) {\n return responseHTML(\n <DocumentLayout\n title={project.name}\n breadcrumbs={[{ label: \"Projects\", href: urlBuilder.allProjects() }]}\n toolbar={\n <div style={{ display: \"flex\", gap: \"1rem\", alignItems: \"center\" }}>\n <a href={urlBuilder.projectIdEdit(projectId)}>Edit</a>\n <form\n hx-delete={request.url}\n hx-confirm=\"Are you sure about deleting the project?\"\n >\n <button>Delete</button>\n </form>\n </div>\n }\n >\n <>\n <RawDataPreview data={project} summary={\"Project details\"} />\n <LabelsTable\n caption={\"Latest labels\"}\n toolbar={<a href={urlBuilder.allLabels(projectId)}>View all</a>}\n labels={labels}\n projectId={projectId}\n />\n <BuildTable\n toolbar={<a href={urlBuilder.allBuilds(projectId)}>View all</a>}\n caption={\"Latest builds\"}\n project={project}\n builds={builds}\n labels={labels}\n />\n </>\n </DocumentLayout>\n );\n }\n\n return {\n status: 200,\n jsonBody: { ...project, latestBuilds: builds, labels },\n };\n } catch (error) {\n return responseError(error, context, 404);\n }\n}\n\nexport async function createProject(\n request: HttpRequest,\n context: InvocationContext\n): Promise<HttpResponseInit> {\n try {\n const { connectionString } = getStore();\n\n const contentType = request.headers.get(\"content-type\");\n if (!contentType) {\n return responseError(\"Content-Type header is required\", context, 400);\n }\n if (!contentType.includes(CONTENT_TYPES.FORM_ENCODED)) {\n return responseError(\n `Invalid Content-Type, expected ${CONTENT_TYPES.FORM_ENCODED}`,\n context,\n 415\n );\n }\n\n const data = ProjectCreateSchema.parse(\n urlSearchParamsToObject(await request.formData())\n );\n\n const projectModel = new ProjectModel(context, connectionString);\n await projectModel.create(data);\n\n const projectUrl = urlBuilder.projectId(data.id);\n\n if (checkIsHTMLRequest() || checkIsHXRequest()) {\n return responseRedirect(projectUrl, 303);\n }\n\n return {\n status: 201,\n headers: { Location: projectUrl },\n jsonBody: { data: data, links: { self: projectUrl } },\n };\n } catch (error) {\n return responseError(error, context);\n }\n}\n\nexport async function updateProject(\n request: HttpRequest,\n context: InvocationContext\n): Promise<HttpResponseInit> {\n try {\n const { projectId } = request.params;\n const { connectionString } = getStore();\n\n if (!projectId) {\n return { status: 400, body: \"Missing project ID\" };\n }\n\n const contentType = request.headers.get(\"content-type\");\n if (!contentType) {\n return responseError(\"Content-Type header is required\", context, 400);\n }\n if (!contentType.includes(CONTENT_TYPES.FORM_ENCODED)) {\n return responseError(\n `Invalid Content-Type, expected ${CONTENT_TYPES.FORM_ENCODED}`,\n context,\n 415\n );\n }\n\n const data = ProjectSchema.partial().parse(\n urlSearchParamsToObject(await request.formData())\n );\n\n const model = new ProjectModel(context, connectionString);\n await model.update(projectId, data);\n\n if (checkIsHTMLRequest() || checkIsHXRequest()) {\n return responseRedirect(request.url, 303);\n }\n\n return {\n status: 202,\n headers: { Location: request.url },\n jsonBody: {\n data: await model.get(projectId),\n links: { self: request.url },\n },\n };\n } catch (error) {\n return responseError(error, context, 404);\n }\n}\n\nexport async function deleteProject(\n request: HttpRequest,\n context: InvocationContext\n): Promise<HttpResponseInit> {\n try {\n const { projectId } = request.params;\n if (!projectId) {\n return { status: 400, body: \"Missing project ID\" };\n }\n\n const { connectionString } = getStore();\n const model = new ProjectModel(context, connectionString);\n await model.delete(projectId);\n\n const projectsUrl = urlBuilder.allProjects();\n if (checkIsHTMLRequest() || checkIsHXRequest()) {\n return responseRedirect(projectsUrl, 303);\n }\n\n return { status: 204, headers: { Location: projectsUrl } };\n } catch (error) {\n return responseError(error, context, 404);\n }\n}\n","import { app } from \"@azure/functions\";\nimport { commonErrorResponses, CONTENT_TYPES } from \"../utils/constants\";\nimport { openAPITags, registerOpenAPIPath } from \"../utils/openapi-utils\";\nimport z from \"zod\";\nimport type { RouterOptions } from \"../utils/types\";\nimport * as handlers from \"../handlers/project-handlers\";\nimport { joinUrl } from \"../utils/url-utils\";\nimport { ProjectIdSchema } from \"../models/shared\";\nimport { ProjectCreateSchema, ProjectSchema } from \"../models/projects\";\n\nconst TAG = openAPITags.projects.name;\n\nexport function registerProjectsRouter(options: RouterOptions) {\n const {\n authLevel,\n baseRoute,\n basePathParamsSchema,\n handlerWrapper,\n openAPIEnabled,\n serviceName,\n } = options;\n\n const projectIdRoute = joinUrl(baseRoute, \"{projectId}\");\n\n app.get(`${serviceName}-projects-list`, {\n authLevel,\n route: baseRoute,\n handler: handlerWrapper(handlers.listProjects, [\n { resource: \"project\", action: \"read\" },\n { resource: \"ui\", action: \"read\" },\n ]),\n });\n app.post(`${serviceName}-project-create`, {\n authLevel,\n route: baseRoute,\n handler: handlerWrapper(handlers.createProject, [\n { resource: \"project\", action: \"create\" },\n ]),\n });\n app.get(`${serviceName}-project-get`, {\n authLevel,\n route: projectIdRoute,\n handler: handlerWrapper(handlers.getProject, [\n { resource: \"project\", action: \"read\" },\n { resource: \"ui\", action: \"read\" },\n ]),\n });\n app.patch(`${serviceName}-project-update`, {\n authLevel,\n route: projectIdRoute,\n handler: handlerWrapper(handlers.updateProject, [\n { resource: \"project\", action: \"update\" },\n ]),\n });\n app.deleteRequest(`${serviceName}-project-delete`, {\n authLevel,\n route: projectIdRoute,\n handler: handlerWrapper(handlers.deleteProject, [\n { resource: \"project\", action: \"delete\" },\n ]),\n });\n\n if (openAPIEnabled) {\n const projectPathParameterSchema = basePathParamsSchema.extend({\n projectId: ProjectIdSchema,\n });\n\n registerOpenAPIPath(baseRoute, {\n get: {\n tags: [TAG],\n summary: \"List all projects\",\n description: \"Retrieves a list of projects.\",\n requestParams: { path: basePathParamsSchema },\n responses: {\n ...commonErrorResponses,\n 200: {\n description: \"A list of projects.\",\n content: {\n [CONTENT_TYPES.JSON]: {\n schema: ProjectSchema.array(),\n example: [{ project: \"project-id\" }],\n },\n [CONTENT_TYPES.HTML]: { example: \"<!DOCTYPE html>\" },\n },\n },\n },\n },\n post: {\n tags: [TAG],\n summary: \"Create a new project\",\n description: \"Creates a new project with the provided metadata.\",\n requestBody: {\n required: true,\n description: \"Data about the project\",\n content: {\n [CONTENT_TYPES.FORM_ENCODED]: {\n schema: ProjectCreateSchema,\n },\n },\n },\n requestParams: { path: basePathParamsSchema },\n responses: {\n ...commonErrorResponses,\n 201: {\n description: \"Project created successfully\",\n content: {\n [CONTENT_TYPES.JSON]: {\n schema: z.object({\n data: ProjectSchema,\n links: z.object({ self: z.url() }),\n }),\n },\n },\n },\n 303: {\n description: \"Project created, redirecting...\",\n headers: { Location: z.url() },\n },\n 415: { description: \"Unsupported Media Type\" },\n },\n },\n });\n\n registerOpenAPIPath(projectIdRoute, {\n get: {\n tags: [TAG],\n summary: \"Get project details\",\n description: \"Retrieves the details of a specific project.\",\n requestParams: { path: projectPathParameterSchema },\n responses: {\n ...commonErrorResponses,\n 200: {\n description: \"Project details retrieved successfully\",\n content: {\n [CONTENT_TYPES.JSON]: {\n schema: ProjectSchema,\n },\n [CONTENT_TYPES.HTML]: { example: \"<!DOCTYPE html>\" },\n },\n },\n 404: { description: \"Matching project not found.\" },\n },\n },\n patch: {\n tags: [TAG],\n summary: \"Update project details\",\n description: \"Updates the details of a specific project.\",\n requestParams: { path: projectPathParameterSchema },\n requestBody: {\n required: true,\n description: \"Updated project data\",\n content: {\n [CONTENT_TYPES.FORM_ENCODED]: {\n schema: ProjectSchema.partial(),\n },\n },\n },\n responses: {\n ...commonErrorResponses,\n 202: {\n description: \"Project updated successfully\",\n content: {\n [CONTENT_TYPES.JSON]: {\n schema: z.object({\n data: ProjectSchema,\n links: z.object({ self: z.url() }),\n }),\n },\n },\n },\n 303: {\n description: \"Project updated, redirecting...\",\n headers: { Location: z.url() },\n },\n 404: { description: \"Matching project not found.\" },\n 415: { description: \"Unsupported Media Type\" },\n },\n },\n delete: {\n tags: [TAG],\n summary: \"Delete a project\",\n description: \"Deletes a specific project.\",\n requestParams: { path: projectPathParameterSchema },\n responses: {\n ...commonErrorResponses,\n 204: { description: \"Project deleted successfully\" },\n 404: { description: \"Matching project not found.\" },\n },\n },\n });\n }\n}\n"],"mappings":"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"}