{"version":3,"file":"index.mjs","names":["options: RegisterStorybooksRouterOptions","name: string","options: HttpFunctionOptions","options"],"sources":["../src/index.ts"],"sourcesContent":["/**\n * Module exports a single function to register\n * the Storybooks management endpoints.\n *\n * @module\n */\n\nimport { app, type HttpFunctionOptions } from \"@azure/functions\";\nimport z from \"zod\";\nimport { timerPurgeHandler } from \"./handlers/timer-purge-handler\";\nimport { registerProjectsRouter } from \"./routers/projects-router\";\nimport { registerBuildsRouter } from \"./routers/builds-router\";\nimport { registerLabelsRouter } from \"./routers/labels-router\";\nimport { registerWebUIRouter } from \"./routers/web-ui-router\";\nimport { registerStorybookRouter } from \"./routers/storybook-router\";\nimport {\n  DEFAULT_CHECK_PERMISSIONS_CALLBACK,\n  DEFAULT_PURGE_SCHEDULE_CRON,\n  DEFAULT_STORAGE_CONN_STR_ENV_VAR,\n  DEFAULT_SERVICE_NAME,\n} from \"./utils/constants\";\nimport type { CheckPermissionsCallback, OpenAPIOptions } from \"./utils/types\";\nimport { joinUrl } from \"./utils/url-utils\";\nimport { wrapHttpHandlerWithStore } from \"./utils/store\";\nimport { EmptyObjectSchema, ProjectIdSchema } from \"./models/shared\";\n\nexport type { CheckPermissionsCallback, OpenAPIOptions };\n\n/**\n * Options to register the storybooks router\n */\nexport type RegisterStorybooksRouterOptions = {\n  /**\n   * Name of the service. @default \"storybooks\"\n   */\n  serviceName?: string;\n\n  /**\n   * Define the route on which all router is placed.\n   * Can be a sub-path of the main API route.\n   *\n   * @default ''\n   */\n  baseRoute?: string;\n\n  /**\n   * Set the Azure Functions authentication level for all routes.\n   *\n   * This is a good option to set if the service is used in\n   * Headless mode and requires single token authentication\n   * for all the requests.\n   *\n   * This setting does not affect health-check route.\n   */\n  authLevel?: \"admin\";\n\n  /**\n   * Name of the Environment variable which stores\n   * the connection string to the Azure Storage resource.\n   * @default 'AzureWebJobsStorage'\n   */\n  storageConnectionStringEnvVar?: string;\n\n  /**\n   * Modify the cron-schedule of timer function\n   * which purge outdated storybooks.\n   *\n   * Pass `null` to disable auto-purge functionality.\n   *\n   * @default \"0 0 0 * * *\" // Every midnight\n   */\n  purgeScheduleCron?: string | null;\n\n  /**\n   * Options to configure OpenAPI schema\n   */\n  openapi?: OpenAPIOptions;\n\n  /**\n   * Directories to serve static files from relative to project root (package.json)\n   * @default './public'\n   */\n  staticDirs?: string[];\n\n  /**\n   * Callback function to check permissions. The function receives following params\n   * @param permission - object containing resource and action to permit\n   * @param context - Invocation context of Azure Function\n   * @param request - the HTTP request object\n   *\n   * @return `true` to allow access, or following to deny:\n   * - `false` - returns 403 response\n   * - `HttpResponse` - returns the specified HTTP response\n   */\n  checkPermissions?: CheckPermissionsCallback;\n};\n\n/**\n * Function to register all routes required to manage the Storybooks including\n * GET, POST and DELETE methods.\n *\n * @returns a function to register additional HTTP handlers for the service.\n */\nexport function registerStorybooksRouter(\n  options: RegisterStorybooksRouterOptions = {}\n): (name: string, options: HttpFunctionOptions) => void {\n  const {\n    serviceName = DEFAULT_SERVICE_NAME,\n    baseRoute = \"\",\n    authLevel,\n    storageConnectionStringEnvVar = DEFAULT_STORAGE_CONN_STR_ENV_VAR,\n    purgeScheduleCron,\n    openapi,\n    checkPermissions = DEFAULT_CHECK_PERMISSIONS_CALLBACK,\n  } = options;\n\n  const storageConnectionString = process.env[storageConnectionStringEnvVar];\n\n  if (!storageConnectionString) {\n    throw new Error(\n      \"Missing env-var '${storageConnectionStringEnvVar}' value.\\n\" +\n        \"It is required to connect with Azure Storage resource.\"\n    );\n  }\n\n  console.log(\"Registering Storybooks Router\");\n\n  const openAPIEnabled = !openapi?.disabled;\n\n  app.setup({ enableHttpStream: true });\n\n  const handlerWrapper = wrapHttpHandlerWithStore.bind(null, {\n    serviceName,\n    baseRoute,\n    authLevel,\n    connectionString: storageConnectionString,\n    openapi,\n    staticDirs: options.staticDirs || [\"./public\"],\n    checkPermissions,\n  });\n\n  const normalisedServiceName = serviceName.toLowerCase().replace(/\\s+/g, \"_\");\n  registerProjectsRouter({\n    serviceName: normalisedServiceName,\n    baseRoute: joinUrl(baseRoute, \"projects\"),\n    basePathParamsSchema: EmptyObjectSchema,\n    openAPIEnabled,\n    handlerWrapper,\n  });\n\n  registerBuildsRouter({\n    serviceName: normalisedServiceName,\n    baseRoute: joinUrl(baseRoute, \"projects\", \"{projectId}\", \"builds\"),\n    basePathParamsSchema: z.object({ projectId: ProjectIdSchema }),\n    openAPIEnabled,\n    handlerWrapper,\n  });\n\n  registerLabelsRouter({\n    serviceName: normalisedServiceName,\n    baseRoute: joinUrl(baseRoute, \"projects\", \"{projectId}\", \"labels\"),\n    basePathParamsSchema: z.object({ projectId: ProjectIdSchema }),\n    openAPIEnabled,\n    handlerWrapper,\n  });\n\n  registerStorybookRouter({\n    serviceName: normalisedServiceName,\n    baseRoute: joinUrl(baseRoute, \"_\"),\n    basePathParamsSchema: EmptyObjectSchema,\n    openAPIEnabled,\n    handlerWrapper,\n  });\n\n  registerWebUIRouter({\n    serviceName: normalisedServiceName,\n    baseRoute,\n    basePathParamsSchema: EmptyObjectSchema,\n    openAPIEnabled,\n    handlerWrapper,\n  });\n\n  if (purgeScheduleCron !== null) {\n    app.timer(`${normalisedServiceName}-timer_purge`, {\n      schedule: purgeScheduleCron || DEFAULT_PURGE_SCHEDULE_CRON,\n      handler: timerPurgeHandler(storageConnectionString),\n    });\n  }\n\n  /**\n   * Register an HTTP function.\n   *\n   * The baseRoute and authLevel is inherited.\n   *\n   * @param name unique name for the HTTP function\n   * @param options Options for Azure HTTP function\n   */\n  function registerRoute(name: string, options: HttpFunctionOptions) {\n    app.http(`${normalisedServiceName}-${name}`, {\n      authLevel,\n      ...options,\n      route: joinUrl(baseRoute, options.route || name),\n      handler: handlerWrapper(options.handler, []),\n      methods: options.methods || [\"GET\"],\n    });\n  }\n\n  return registerRoute;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuGA,SAAgB,yBACdA,UAA2C,CAAE,GACS;CACtD,MAAM,EACJ,cAAc,sBACd,YAAY,IACZ,WACA,gCAAgC,kCAChC,mBACA,SACA,mBAAmB,oCACpB,GAAG;CAEJ,MAAM,0BAA0B,QAAQ,IAAI;AAE5C,KAAI,CAAC,wBACH,OAAM,IAAI,MACR;CAKJ,QAAQ,IAAI,gCAAgC;CAE5C,MAAM,iBAAiB,CAAC,SAAS;CAEjC,IAAI,MAAM,EAAE,kBAAkB,KAAM,EAAC;CAErC,MAAM,iBAAiB,yBAAyB,KAAK,MAAM;EACzD;EACA;EACA;EACA,kBAAkB;EAClB;EACA,YAAY,QAAQ,cAAc,CAAC,UAAW;EAC9C;CACD,EAAC;CAEF,MAAM,wBAAwB,YAAY,aAAa,CAAC,QAAQ,QAAQ,IAAI;CAC5E,uBAAuB;EACrB,aAAa;EACb,WAAW,QAAQ,WAAW,WAAW;EACzC,sBAAsB;EACtB;EACA;CACD,EAAC;CAEF,qBAAqB;EACnB,aAAa;EACb,WAAW,QAAQ,WAAW,YAAY,eAAe,SAAS;EAClE,sBAAsB,EAAE,OAAO,EAAE,WAAW,gBAAiB,EAAC;EAC9D;EACA;CACD,EAAC;CAEF,qBAAqB;EACnB,aAAa;EACb,WAAW,QAAQ,WAAW,YAAY,eAAe,SAAS;EAClE,sBAAsB,EAAE,OAAO,EAAE,WAAW,gBAAiB,EAAC;EAC9D;EACA;CACD,EAAC;CAEF,wBAAwB;EACtB,aAAa;EACb,WAAW,QAAQ,WAAW,IAAI;EAClC,sBAAsB;EACtB;EACA;CACD,EAAC;CAEF,oBAAoB;EAClB,aAAa;EACb;EACA,sBAAsB;EACtB;EACA;CACD,EAAC;AAEF,KAAI,sBAAsB,MACxB,IAAI,MAAM,GAAG,sBAAsB,YAAY,CAAC,EAAE;EAChD,UAAU,qBAAqB;EAC/B,SAAS,kBAAkB,wBAAwB;CACpD,EAAC;;;;;;;;;CAWJ,SAAS,cAAcC,MAAcC,WAA8B;EACjE,IAAI,KAAK,GAAG,sBAAsB,CAAC,EAAE,MAAM,EAAE;GAC3C;GACA,GAAGC;GACH,OAAO,QAAQ,WAAWA,UAAQ,SAAS,KAAK;GAChD,SAAS,eAAeA,UAAQ,SAAS,CAAE,EAAC;GAC5C,SAASA,UAAQ,WAAW,CAAC,KAAM;EACpC,EAAC;CACH;AAED,QAAO;AACR"}