@azure-utils/storybooks
Version:
Utils to upload and manage Storybooks via Azure Functions and storage.
1 lines • 24.6 kB
Source Map (JSON)
{"version":3,"file":"projects-DDVy3_77.mjs","names":["context: InvocationContext","connectionString: string","projectId: string","#context","#projectId","#tableClient","#blobService","options?: ListAzureTableEntitiesOptions<BuildType>","groupedBuilds: BuildType[]","sha: string","labelSlug?: string","data: BuildUploadType","labelSlug: string","context: InvocationContext","connectionString: string","projectId: string","#context","#projectId","#tableClient","options?: ListAzureTableEntitiesOptions<LabelType>","slug: string","data: LabelCreateType","data: LabelUpdateType","value: string","context: InvocationContext","connectionString: string","#connectionString","#context","#blobService","#tableClient","projectId: string","options?: ListAzureTableEntitiesOptions<ProjectType>","id: string","data: ProjectCreateType","data: Partial<ProjectType>"],"sources":["../src/models/builds.tsx","../src/models/labels.tsx","../src/models/projects.tsx"],"sourcesContent":["import z from \"zod\";\nimport { TableClient } from \"@azure/data-tables\";\nimport type { InvocationContext } from \"@azure/functions\";\nimport { BlobServiceClient } from \"@azure/storage-blob\";\nimport {\n generateProjectAzureTableName,\n listAzureTableEntities,\n ListAzureTableEntitiesOptions,\n} from \"../utils/azure-data-tables\";\nimport {\n deleteBlobsFromAzureStorageContainerOrThrow,\n generateAzureStorageContainerName,\n} from \"../utils/azure-storage-blob\";\nimport { BuildSHASchema, type BaseModel } from \"./shared\";\nimport { ProjectModel } from \"./projects\";\n\nexport type BuildType = z.infer<typeof BuildSchema>;\n/** @private */\nexport const BuildSchema = z.object({\n label: z.string(),\n sha: BuildSHASchema,\n authorName: z.string(),\n authorEmail: z\n .string()\n .refine((val) => val.includes(\"@\"), \"Invalid email format\")\n .meta({ description: \"Email of the author\" }),\n message: z.optional(z.string()),\n timestamp: z.string().optional(),\n});\n\n/** @private */\nexport type BuildUploadType = z.infer<typeof BuildUploadSchema>;\nexport const BuildUploadSchema = BuildSchema.omit({ label: true }).extend({\n labels: z.string().array().meta({\n description:\n \"Label slugs associated with the build. Must be created beforehand.\",\n }),\n});\nexport type BuildUploadFormType = z.infer<typeof BuildUploadSchema>;\nexport const BuildUploadFormSchema = BuildUploadSchema.extend({\n zipFile: z.file(),\n});\n\n/**\n * - partitionKey: label\n * - rowKey: sha\n */\nexport class BuildModel implements BaseModel<BuildType, BuildUploadType> {\n #context: InvocationContext;\n #projectId: string;\n #tableClient: TableClient;\n #blobService: BlobServiceClient;\n projectModel: ProjectModel;\n\n constructor(\n context: InvocationContext,\n connectionString: string,\n projectId: string\n ) {\n this.#context = context;\n this.#projectId = projectId;\n this.#tableClient = TableClient.fromConnectionString(\n connectionString,\n generateProjectAzureTableName(projectId, \"Builds\")\n );\n this.#blobService =\n BlobServiceClient.fromConnectionString(connectionString);\n this.projectModel = new ProjectModel(context, connectionString);\n }\n\n parse = BuildSchema.parse;\n\n async list(\n options?: ListAzureTableEntitiesOptions<BuildType>\n ): Promise<BuildType[]> {\n this.#context.log(\"List builds for project '%s'...\", this.#projectId);\n const entities = await listAzureTableEntities(\n this.#context,\n this.#tableClient,\n options\n );\n\n const builds = BuildSchema.array().parse(entities);\n\n const groupBySHA = Object.groupBy(builds, (b) => b.sha);\n const groupedBuilds: BuildType[] = Object.values(groupBySHA)\n .map((group) =>\n group && group.length > 0\n ? { ...group[0]!, label: group.map((b) => b.label).join(\",\") }\n : undefined\n )\n .filter((build) => build !== undefined);\n\n return groupedBuilds;\n }\n\n async get(sha: string, labelSlug?: string): Promise<BuildType> {\n this.#context.log(\n \"Get build: '%s' for project '%s'...\",\n sha,\n this.#projectId\n );\n const entity = labelSlug\n ? await this.#tableClient.getEntity(labelSlug, sha)\n : (await this.list({ filter: `RowKey eq '${sha}'` })).at(0);\n\n return BuildSchema.parse(entity);\n }\n\n async has(sha: string): Promise<boolean> {\n try {\n await this.get(sha);\n return true;\n } catch {\n return false;\n }\n }\n\n async create(data: BuildUploadType): Promise<void> {\n const { labels, sha, ...rest } = data;\n this.#context.log(\n \"Create build '%s' for project '%s'...\",\n sha,\n this.#projectId\n );\n\n for (const labelSlug of labels.filter(Boolean)) {\n await this.#tableClient.createEntity({\n partitionKey: labelSlug,\n rowKey: sha,\n ...rest,\n label: labelSlug,\n sha,\n });\n\n const labelModel = this.projectModel.labelModel(this.#projectId);\n try {\n await labelModel.update(labelSlug, { buildSHA: sha });\n } catch {\n this.#context.log(\n \"A new label '$s' is being created, please update its information\",\n labelSlug\n );\n await labelModel.create({\n value: labelSlug,\n buildSHA: sha,\n type: /\\d+/.test(labelSlug) ? \"pr\" : \"branch\",\n });\n }\n }\n\n try {\n const project = await this.projectModel.get(this.#projectId);\n if (labels.includes(project.gitHubDefaultBranch))\n this.projectModel.update(project.id, { buildSHA: sha });\n } catch (error) {\n this.#context.error(error);\n }\n }\n\n async update(): Promise<void> {\n throw new Error(\"Update operation is not supported for builds.\");\n }\n\n async delete(sha: string): Promise<void> {\n this.#context.log(\n \"Delete build: '%s' for project '%s'...\",\n sha,\n this.#projectId\n );\n const matchingEntities = await listAzureTableEntities(\n this.#context,\n this.#tableClient,\n { filter: `sha eq '${sha}'` }\n );\n\n for (const entity of matchingEntities) {\n if (entity.partitionKey && entity.rowKey)\n await this.#tableClient.deleteEntity(\n entity.partitionKey,\n entity.rowKey\n );\n }\n\n const containerClient = this.#blobService.getContainerClient(\n generateAzureStorageContainerName(this.#projectId)\n );\n await deleteBlobsFromAzureStorageContainerOrThrow(\n this.#context,\n containerClient,\n sha\n );\n }\n\n async deleteByLabel(labelSlug: string): Promise<void> {\n this.#context.log(\n \"Delete build by label: '%s' for project '%s'...\",\n labelSlug,\n this.#projectId\n );\n const matchingEntities = await listAzureTableEntities(\n this.#context,\n this.#tableClient,\n { filter: `label eq '${labelSlug}'` }\n );\n\n const containerClient = this.#blobService.getContainerClient(\n generateAzureStorageContainerName(this.#projectId)\n );\n\n for (const entity of matchingEntities) {\n if (entity.partitionKey && entity.rowKey) {\n await this.#tableClient.deleteEntity(\n entity.partitionKey,\n entity.rowKey\n );\n\n const remainingLabelsForSHA = await listAzureTableEntities(\n this.#context,\n this.#tableClient,\n { filter: `sha eq '${entity.rowKey}'` }\n );\n\n if (remainingLabelsForSHA.length === 0) {\n await deleteBlobsFromAzureStorageContainerOrThrow(\n this.#context,\n containerClient,\n entity.rowKey // sha\n );\n }\n }\n }\n }\n}\n","import z from \"zod\";\nimport { TableClient } from \"@azure/data-tables\";\nimport type { InvocationContext } from \"@azure/functions\";\nimport {\n generateProjectAzureTableName,\n listAzureTableEntities,\n ListAzureTableEntitiesOptions,\n} from \"../utils/azure-data-tables\";\nimport { BuildSHASchema, LabelSlugSchema, type BaseModel } from \"./shared\";\nimport { ProjectModel } from \"./projects\";\n\nexport const labelTypes = [\"branch\", \"pr\"] as const;\n\nexport type LabelType = z.infer<typeof LabelSchema>;\n/** @private */\nexport const LabelSchema = z\n .object({\n slug: LabelSlugSchema,\n value: z.string().meta({ description: \"The value of the label.\" }),\n type: z.enum(labelTypes),\n buildSHA: BuildSHASchema.optional(),\n timestamp: z.string().optional(),\n })\n .meta({ id: \"storybook-label\", description: \"A Storybook label.\" });\n\ntype LabelCreateType = z.infer<typeof LabelCreateSchema>;\nexport const LabelCreateSchema = LabelSchema.omit({\n slug: true,\n timestamp: true,\n});\n\ntype LabelUpdateType = z.infer<typeof LabelUpdateSchema>;\nexport const LabelUpdateSchema = LabelSchema.omit({\n slug: true,\n timestamp: true,\n}).partial();\n\nexport class LabelModel\n implements BaseModel<LabelType, LabelCreateType, LabelUpdateType>\n{\n #context: InvocationContext;\n #projectId: string;\n #tableClient: TableClient;\n projectModel: ProjectModel;\n\n constructor(\n context: InvocationContext,\n connectionString: string,\n projectId: string\n ) {\n this.#context = context;\n this.#projectId = projectId;\n this.#tableClient = TableClient.fromConnectionString(\n connectionString,\n generateProjectAzureTableName(projectId, \"Labels\")\n );\n this.projectModel = new ProjectModel(context, connectionString);\n }\n\n async list(\n options?: ListAzureTableEntitiesOptions<LabelType>\n ): Promise<LabelType[]> {\n this.#context.log(\"List labels for project '%s'...\", this.#projectId);\n const entities = await listAzureTableEntities(\n this.#context,\n this.#tableClient,\n options\n );\n\n return LabelSchema.array().parse(entities);\n }\n\n async get(slug: string): Promise<LabelType> {\n this.#context.log(\n \"Get label '%s' for project '%s'...\",\n slug,\n this.#projectId\n );\n const entity = await this.#tableClient.getEntity(this.#projectId, slug);\n\n return LabelSchema.parse(entity);\n }\n\n async has(slug: string): Promise<boolean> {\n try {\n await this.get(slug);\n return true;\n } catch {\n return false;\n }\n }\n\n async create(data: LabelCreateType): Promise<void> {\n this.#context.log(\n \"Create label '%s' for project '%s'...\",\n data.value,\n this.#projectId\n );\n\n const slug = LabelModel.createSlug(data.value);\n await this.#tableClient.createEntity({\n ...data,\n partitionKey: this.#projectId,\n rowKey: slug,\n slug,\n });\n }\n\n async update(slug: string, data: LabelUpdateType): Promise<void> {\n this.#context.log(\n \"Update label '%s' for project '%s'...\",\n slug,\n this.#projectId\n );\n\n await this.#tableClient.updateEntity(\n { ...data, partitionKey: this.#projectId, rowKey: slug, slug },\n \"Merge\"\n );\n }\n\n async delete(slug: string): Promise<void> {\n this.#context.log(\n \"Delete label '%s' for project '%s'...\",\n slug,\n this.#projectId\n );\n\n const { gitHubDefaultBranch } = await this.projectModel.get(\n this.#projectId\n );\n if (slug === LabelModel.createSlug(gitHubDefaultBranch)) {\n const message = `Cannot delete the label associated with default branch (${gitHubDefaultBranch}) of the project '${\n this.#projectId\n }'.`;\n this.#context.warn(message);\n throw new Error(message);\n }\n\n await this.#tableClient.deleteEntity(this.#projectId, slug);\n await this.projectModel.buildModel(this.#projectId).deleteByLabel(slug);\n }\n\n static createSlug(value: string) {\n return value.trim().toLowerCase().replace(/\\W+/, \"-\");\n }\n}\n","import z from \"zod\";\nimport { TableClient } from \"@azure/data-tables\";\nimport type { InvocationContext } from \"@azure/functions\";\nimport { BlobServiceClient } from \"@azure/storage-blob\";\nimport {\n DEFAULT_GITHUB_BRANCH,\n DEFAULT_PURGE_AFTER_DAYS,\n DEFAULT_SERVICE_NAME,\n} from \"../utils/constants\";\nimport {\n generateProjectAzureTableName,\n listAzureTableEntities,\n ListAzureTableEntitiesOptions,\n} from \"../utils/azure-data-tables\";\nimport { generateAzureStorageContainerName } from \"../utils/azure-storage-blob\";\nimport { BuildSHASchema, ProjectIdSchema, type BaseModel } from \"./shared\";\nimport { BuildModel } from \"./builds\";\nimport { LabelModel } from \"./labels\";\n\nexport type ProjectType = z.infer<typeof ProjectSchema>;\n/** @private */\nexport const ProjectSchema = z\n .object({\n id: ProjectIdSchema,\n name: z.string().meta({ description: \"Name of the project.\" }),\n purgeBuildsAfterDays: z.coerce\n .number()\n .min(1)\n .default(DEFAULT_PURGE_AFTER_DAYS)\n .meta({\n description:\n \"Days after which the builds in the project should be purged.\",\n }),\n gitHubRepo: z.string().check(\n z.minLength(1, \"Query-param 'gitHubRepo' is required.\"),\n z.refine(\n (val) => val.split(\"/\").length === 2,\n \"Query-param 'gitHubRepo' should be in the format 'owner/repo'.\"\n )\n ),\n gitHubPath: z.string().optional().meta({\n description:\n \"Path to the storybook project with respect to repository root.\",\n }),\n gitHubDefaultBranch: z\n .string()\n .default(DEFAULT_GITHUB_BRANCH)\n .meta({ description: \"Default branch to use for GitHub repository\" }),\n buildSHA: BuildSHASchema.optional(),\n timestamp: z.string().optional(),\n })\n .meta({\n id: \"storybook-project\",\n description: \"Storybook project\",\n });\n\ntype ProjectCreateType = z.infer<typeof ProjectCreateSchema>;\nexport const ProjectCreateSchema = ProjectSchema.omit({\n buildSHA: true,\n timestamp: true,\n});\n\nconst partitionKey = \"projects\";\n\nexport class ProjectModel implements BaseModel<ProjectType, ProjectCreateType> {\n #connectionString: string;\n #context: InvocationContext;\n #blobService: BlobServiceClient;\n #tableClient: TableClient;\n\n constructor(context: InvocationContext, connectionString: string) {\n this.#connectionString = connectionString;\n this.#context = context;\n this.#blobService =\n BlobServiceClient.fromConnectionString(connectionString);\n this.#tableClient = TableClient.fromConnectionString(\n connectionString,\n DEFAULT_SERVICE_NAME\n );\n }\n\n parse = ProjectSchema.parse;\n buildModel(projectId: string) {\n return new BuildModel(this.#context, this.#connectionString, projectId);\n }\n labelModel(projectId: string) {\n return new LabelModel(this.#context, this.#connectionString, projectId);\n }\n\n async list(\n options?: ListAzureTableEntitiesOptions<ProjectType>\n ): Promise<ProjectType[]> {\n this.#context.log(\"List projects...\");\n const entities = await listAzureTableEntities(\n this.#context,\n this.#tableClient,\n options\n );\n\n return ProjectSchema.array().parse(entities);\n }\n\n async get(id: string): Promise<ProjectType> {\n this.#context.log(\"Get project: '%s'...\", id);\n const entity = await this.#tableClient.getEntity(partitionKey, id);\n\n return ProjectSchema.parse(entity);\n }\n\n async has(id: string): Promise<boolean> {\n try {\n await this.get(id);\n return true;\n } catch {\n return false;\n }\n }\n\n async create(data: ProjectCreateType): Promise<void> {\n this.#context.log(\"Create project: '%s'...\", data.id);\n const gitHubDefaultBranch =\n data.gitHubDefaultBranch || DEFAULT_GITHUB_BRANCH;\n\n await this.#tableClient.createTable();\n await this.#tableClient.createEntity({\n partitionKey,\n rowKey: data.id,\n ...data,\n gitHubDefaultBranch,\n });\n\n await TableClient.fromConnectionString(\n this.#connectionString,\n generateProjectAzureTableName(data.id, \"Labels\")\n ).createTable();\n await TableClient.fromConnectionString(\n this.#connectionString,\n generateProjectAzureTableName(data.id, \"Builds\")\n ).createTable();\n await this.#blobService.createContainer(\n generateAzureStorageContainerName(data.id)\n );\n await this.labelModel(data.id).create({\n type: \"branch\",\n value: gitHubDefaultBranch,\n });\n }\n\n async update(id: string, data: Partial<ProjectType>): Promise<void> {\n this.#context.log(\"Update project: '%s'...\", id);\n await this.#tableClient.updateEntity(\n { partitionKey, rowKey: id, ...data, id },\n \"Merge\"\n );\n }\n\n async delete(id: string): Promise<void> {\n this.#context.log(\"Delete project: '%s'...\", id);\n await this.#tableClient.deleteEntity(partitionKey, id);\n await TableClient.fromConnectionString(\n this.#connectionString,\n generateProjectAzureTableName(id, \"Labels\")\n ).deleteTable();\n await TableClient.fromConnectionString(\n this.#connectionString,\n generateProjectAzureTableName(id, \"Builds\")\n ).deleteTable();\n await this.#blobService.deleteContainer(\n generateAzureStorageContainerName(id)\n );\n }\n}\n"],"mappings":"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"}