{"version":3,"file":"create-build-context.mjs","sources":["../../../src/node/create-build-context.ts"],"sourcesContent":["import os from 'node:os';\nimport path from 'node:path';\nimport fs from 'node:fs/promises';\nimport browserslist from 'browserslist';\nimport { createStrapi } from '@strapi/core';\nimport type { Core, Modules } from '@strapi/types';\nimport type { Server } from 'node:http';\n\nimport type { CLIContext } from '../cli/types';\nimport { getStrapiAdminEnvVars, loadEnv } from './core/env';\n\nimport { PluginMeta, getEnabledPlugins, getMapOfPluginsWithAdmin } from './core/plugins';\nimport { AppFile, loadUserAppFile } from './core/admin-customisations';\nimport type { BaseContext } from './types';\n\ninterface BaseOptions {\n  stats?: boolean;\n  minify?: boolean;\n  sourcemaps?: boolean;\n  bundler?: 'webpack' | 'vite';\n  open?: boolean;\n  hmrServer?: Server;\n  hmrClientPort?: number;\n}\n\ninterface BuildContext<TOptions = unknown> extends BaseContext {\n  /**\n   * The customisations defined by the user in their app.js file\n   */\n  customisations?: AppFile;\n  /**\n   * Features object with future flags\n   */\n  features?: Modules.Features.FeaturesService['config'];\n  /**\n   * The build options\n   */\n  options: BaseOptions & TOptions;\n  /**\n   * The plugins to be included in the JS bundle\n   * incl. internal plugins, third party plugins & local plugins\n   */\n  plugins: PluginMeta[];\n}\n\ninterface CreateBuildContextArgs<TOptions = unknown> extends CLIContext {\n  strapi?: Core.Strapi;\n  options?: TOptions;\n}\n\nconst DEFAULT_BROWSERSLIST = [\n  'last 3 major versions',\n  'Firefox ESR',\n  'last 2 Opera versions',\n  'not dead',\n];\n\nconst createBuildContext = async <TOptions extends BaseOptions>({\n  cwd,\n  logger,\n  tsconfig,\n  strapi,\n  options = {} as TOptions,\n}: CreateBuildContextArgs<TOptions>): Promise<BuildContext<TOptions>> => {\n  /**\n   * If you make a new strapi instance when one already exists,\n   * you will overwrite the global and the app will _most likely_\n   * crash and die.\n   */\n  const strapiInstance =\n    strapi ??\n    createStrapi({\n      // Directories\n      appDir: cwd,\n      distDir: tsconfig?.config.options.outDir ?? '',\n      // Options\n      autoReload: true,\n      serveAdminPanel: false,\n    });\n\n  const serverAbsoluteUrl = strapiInstance.config.get<string>('server.absoluteUrl');\n  const adminAbsoluteUrl = strapiInstance.config.get<string>('admin.absoluteUrl');\n  const adminPath = strapiInstance.config.get<string>('admin.path');\n\n  // NOTE: Checks that both the server and admin will be served from the same origin (protocol, host, port)\n  const sameOrigin = new URL(adminAbsoluteUrl).origin === new URL(serverAbsoluteUrl).origin;\n\n  const adminPublicPath = new URL(adminAbsoluteUrl).pathname;\n  const serverPublicPath = new URL(serverAbsoluteUrl).pathname;\n\n  const appDir = strapiInstance.dirs.app.root;\n\n  await loadEnv(cwd);\n\n  const env = getStrapiAdminEnvVars({\n    ADMIN_PATH: adminPublicPath,\n    STRAPI_ADMIN_BACKEND_URL: sameOrigin ? serverPublicPath : serverAbsoluteUrl,\n    STRAPI_TELEMETRY_DISABLED: String(strapiInstance.telemetry.isDisabled),\n    // TODO: Get this url from a utility/consts rather than duplicating it in AIChat constants.ts\n    STRAPI_AI_URL:\n      process.env.STRAPI_AI_URL?.replace(/\\/+$/, '') ?? 'https://strapi-ai.apps.strapi.io',\n    STRAPI_ANALYTICS_URL: process.env.STRAPI_ANALYTICS_URL || 'https://analytics.strapi.io',\n  });\n\n  const envKeys = Object.keys(env);\n\n  if (envKeys.length > 0) {\n    logger.info(\n      [\n        'Including the following ENV variables as part of the JS bundle:',\n        ...envKeys.map((key) => `    - ${key}`),\n      ].join(os.EOL)\n    );\n  }\n\n  const distPath = path.join(strapiInstance.dirs.dist.root, 'build');\n  const distDir = path.relative(cwd, distPath);\n\n  /**\n   * If the distPath already exists, clean it\n   */\n  try {\n    logger.debug(`Cleaning dist folder: ${distPath}`);\n    await fs.rm(distPath, { recursive: true, force: true });\n    logger.debug('Cleaned dist folder');\n  } catch {\n    // do nothing, it will fail if the folder does not exist\n    logger.debug('There was no dist folder to clean');\n  }\n\n  const runtimeDir = path.join(cwd, '.strapi', 'client');\n  const entry = path.relative(cwd, path.join(runtimeDir, 'app.js'));\n\n  const plugins = await getEnabledPlugins({ cwd, logger, runtimeDir, strapi: strapiInstance });\n\n  logger.debug('Enabled plugins', os.EOL, plugins);\n\n  const pluginsWithFront = getMapOfPluginsWithAdmin(plugins);\n\n  logger.debug('Enabled plugins with FE', os.EOL, pluginsWithFront);\n\n  const target = browserslist.loadConfig({ path: cwd }) ?? DEFAULT_BROWSERSLIST;\n\n  const customisations = await loadUserAppFile({ appDir, runtimeDir });\n\n  const features = strapiInstance.config.get('features', undefined);\n\n  const { bundler = 'vite', ...restOptions } = options;\n\n  const buildContext = {\n    appDir,\n    adminPath,\n    basePath: adminPublicPath,\n    bundler,\n    customisations,\n    cwd,\n    distDir,\n    distPath,\n    entry,\n    env,\n    features,\n    logger,\n    options: restOptions as BaseOptions & TOptions,\n    plugins: pluginsWithFront,\n    runtimeDir,\n    strapi: strapiInstance,\n    target,\n    tsconfig,\n  } satisfies BuildContext<TOptions>;\n\n  return buildContext;\n};\n\nexport { createBuildContext };\nexport type { BuildContext, CreateBuildContextArgs };\n"],"names":["DEFAULT_BROWSERSLIST","createBuildContext","cwd","logger","tsconfig","strapi","options","strapiInstance","createStrapi","appDir","distDir","config","outDir","autoReload","serveAdminPanel","serverAbsoluteUrl","get","adminAbsoluteUrl","adminPath","sameOrigin","URL","origin","adminPublicPath","pathname","serverPublicPath","dirs","app","root","loadEnv","env","getStrapiAdminEnvVars","ADMIN_PATH","STRAPI_ADMIN_BACKEND_URL","STRAPI_TELEMETRY_DISABLED","String","telemetry","isDisabled","STRAPI_AI_URL","process","replace","STRAPI_ANALYTICS_URL","envKeys","Object","keys","length","info","map","key","join","os","EOL","distPath","path","dist","relative","debug","fs","rm","recursive","force","runtimeDir","entry","plugins","getEnabledPlugins","pluginsWithFront","getMapOfPluginsWithAdmin","target","browserslist","loadConfig","customisations","loadUserAppFile","features","undefined","bundler","restOptions","buildContext","basePath"],"mappings":"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"}