{"version":3,"file":"index.cjs","names":["path"],"sources":["../../withYak/index.ts"],"sourcesContent":["/// <reference types=\"node\" />\nimport type { NextConfig } from \"next\";\nimport { existsSync } from \"node:fs\";\nimport path, { dirname } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nconst currentDir =\n  typeof __dirname !== \"undefined\" ? __dirname : dirname(fileURLToPath(import.meta.url));\n\nexport type YakConfigOptions = {\n  /**\n   * Generate compact CSS class and variable names.\n   * @defaultValue\n   * enabled if NODE_ENV is set to `production`, otherwise disabled\n   */\n  minify?: boolean;\n  contextPath?: string;\n  /**\n   * Optional prefix for generated CSS identifiers.\n   * This can be used to ensure unique class names across different applications\n   * or to add organization-specific prefixes.\n   */\n  prefix?: string;\n  /**\n   * Adds `displayName` to each component for better React DevTools debugging\n   * - Enabled by default in development mode\n   * - Disabled by default in production\n   * - Increases bundle size slightly when enabled\n   */\n  displayNames?: boolean;\n  /**\n   * Fold statically known styles at build time: JSX usages of fully static\n   * styled components become plain DOM elements, and a static `css` prop\n   * becomes a plain `className`. Both skip the runtime wrapper and merge calls.\n   * @defaultValue true\n   */\n  foldStatic?: boolean;\n  /**\n   * Fail the build when a `css` prop has a value next-yak can't handle\n   * (e.g. a plain string). next-yak claims the `css` prop, so a malformed\n   * value is almost always a mistake worth surfacing.\n   *\n   * Set to `false` to leave such props untouched instead, e.g. when another\n   * library on the same element uses its own `css` prop.\n   * @defaultValue true\n   */\n  strictCssProp?: boolean;\n  experiments?: {\n    /**\n     * Debug logging for transformed files.\n     * - `true` - log all files\n     * - `object` - filter by pattern and/or output types (at least one required)\n     */\n    debug?:\n      | true\n      | { pattern: string; types?: Array<\"ts\" | \"css\" | \"css-resolved\"> }\n      | { pattern?: string; types: Array<\"ts\" | \"css\" | \"css-resolved\"> };\n    transpilationMode?: \"CssModule\" | \"Css\";\n    /**\n     * Suppress deprecation warnings for :global() selectors during migration period\n     * @defaultValue false\n     */\n    suppressDeprecationWarnings?: boolean;\n  };\n};\n\n/**\n * Build the base yak-swc plugin options shared by every bundler integration\n * (webpack, turbopack, vite, rsbuild). The caller adds the bundler-specific\n * `importMode` on top.\n *\n * @param yakOptions - Yak configuration options\n * @param basePath - Base path used by yak-swc to derive stable identifiers\n */\nexport function buildYakPluginOptions(yakOptions: YakConfigOptions, basePath: string) {\n  const minify = yakOptions.minify ?? process.env.NODE_ENV === \"production\";\n  return {\n    minify,\n    basePath,\n    prefix: yakOptions.prefix,\n    displayNames: yakOptions.displayNames ?? !minify,\n    foldStatic: yakOptions.foldStatic ?? true,\n    strictCssProp: yakOptions.strictCssProp ?? true,\n    suppressDeprecationWarnings: yakOptions.experiments?.suppressDeprecationWarnings ?? false,\n    reactRefreshReg: true,\n  };\n}\n\nconst addYak = (yakOptions: YakConfigOptions, nextConfig: NextConfig) => {\n  const yakPluginOptions = buildYakPluginOptions(yakOptions, currentDir);\n\n  const transpilation = yakOptions.experiments?.transpilationMode ?? \"CssModule\";\n  const cssExtension = transpilation === \"CssModule\" ? \".yak.module.css\" : \".yak.css\";\n\n  if (process.env.TURBOPACK === \"1\" || process.env.TURBOPACK === \"auto\") {\n    addYakTurbopack(nextConfig, yakOptions, {\n      ...yakPluginOptions,\n      importMode: {\n        value: \"data:text/css;base64,\",\n        transpilation: \"Css\",\n        encoding: \"Base64\",\n      },\n    });\n  } else {\n    addYakWebpack(nextConfig, yakOptions, {\n      ...yakPluginOptions,\n      importMode: {\n        value: `./{{__BASE_NAME__}}${cssExtension}!=!./{{__BASE_NAME__}}?./{{__BASE_NAME__}}${cssExtension}`,\n        transpilation,\n        encoding: \"None\",\n      },\n    });\n  }\n  return nextConfig;\n};\n\n/**\n * Configure Turbopack with yak loader for CSS-in-JS transformation\n * @param nextConfig - Next.js configuration object\n * @param yakOptions - Yak configuration options\n * @param yakPluginOptions - Processed plugin options for yak-swc\n */\nfunction addYakTurbopack(\n  nextConfig: NextConfig,\n  yakOptions: YakConfigOptions,\n  yakPluginOptions: {\n    minify: boolean;\n    basePath: string;\n    prefix?: string;\n    displayNames: boolean;\n    foldStatic: boolean;\n    strictCssProp: boolean;\n    importMode: {\n      value: string;\n      transpilation: string;\n      encoding: string;\n    };\n  },\n) {\n  // turbopack can't handle options with undefined values, so we remove them\n  const yakLoader = removeUndefinedRecursive({\n    loader: path.join(currentDir, \"../loaders/turbo-loader.cjs\"),\n    options: {\n      yakOptions: yakOptions,\n      yakPluginOptions: yakPluginOptions,\n    },\n  }) as { loader: string; options: {} };\n\n  nextConfig.turbopack ||= {};\n  nextConfig.turbopack.rules ||= {};\n\n  const ruleKey = \"*.{js,jsx,cjs,mjs,ts,tsx,cts,mts}\";\n  const rule = {\n    loaders: [] as { loader: string; options: {} }[],\n    ...nextConfig.turbopack.rules[ruleKey],\n  };\n  rule.loaders.push(yakLoader);\n  nextConfig.turbopack.rules[ruleKey] = rule;\n\n  // Configure resolveAlias for custom yak context (similar to webpack)\n  // This allows users to provide a custom context file that will be used\n  // instead of the default baseContext\n  const yakContext = resolveYakContext(yakOptions.contextPath, process.cwd());\n  if (yakContext) {\n    nextConfig.turbopack.resolveAlias ||= {};\n    nextConfig.turbopack.resolveAlias[\"next-yak/context/baseContext\"] =\n      // This is a hack around the fact that turbopack currently only supports relative paths\n      // turbopack: \"server relative imports are not implemented yet\"\n      // Relative is quite dangerous here as it relies on the cwd being the starting point\n      `./${path.relative(process.cwd(), yakContext)}`;\n  }\n}\n\n/**\n * Configure Webpack with yak SWC plugin and webpack loader for CSS-in-JS transformation\n * @param nextConfig - Next.js configuration object\n * @param yakOptions - Yak configuration options\n * @param yakPluginOptions - Processed plugin options for yak-swc\n */\nfunction addYakWebpack(\n  nextConfig: NextConfig,\n  yakOptions: YakConfigOptions,\n  yakPluginOptions: {\n    minify: boolean;\n    basePath: string;\n    prefix?: string;\n    displayNames: boolean;\n    foldStatic: boolean;\n    strictCssProp: boolean;\n    importMode: {\n      value: string;\n      transpilation: string;\n      encoding: string;\n    };\n  },\n) {\n  // Add SWC plugin for Webpack\n  nextConfig.experimental ||= {};\n  nextConfig.experimental.swcPlugins ||= [];\n  nextConfig.experimental.swcPlugins.push([\"yak-swc\", yakPluginOptions]);\n\n  // Configure webpack loader\n  const previousConfig = nextConfig.webpack;\n  nextConfig.webpack = (webpackConfig, options) => {\n    if (previousConfig) {\n      webpackConfig = previousConfig(webpackConfig, options);\n    }\n\n    webpackConfig.module.rules.push({\n      test:\n        yakOptions.experiments?.transpilationMode === \"Css\" ? /\\.yak\\.css$/ : /\\.yak\\.module\\.css$/,\n      loader: path.join(currentDir, \"../loaders/webpack-loader.cjs\"),\n      options: yakOptions,\n    });\n\n    // With the following alias the internal next-yak code\n    // is able to import a context which works for server components\n    const yakContext = resolveYakContext(\n      yakOptions.contextPath,\n      webpackConfig.context || process.cwd(),\n    );\n    if (yakContext) {\n      webpackConfig.resolve.alias[\"next-yak/context/baseContext\"] = yakContext;\n    }\n\n    return webpackConfig;\n  };\n}\n\n/**\n * Recursively removes undefined values from an object or array.\n *\n * This function deeply traverses the input object/array and creates a new structure\n * with all undefined values filtered out. For objects, properties with undefined values\n * are omitted. For arrays, undefined elements are removed from the result.\n *\n * @param obj - The object or array to process\n * @returns A new object/array with undefined values removed, or the original value if no changes were needed\n */\nfunction removeUndefinedRecursive<T>(obj: T): {} {\n  if (typeof obj !== \"object\" || obj === null) {\n    return obj as {};\n  }\n\n  if (Array.isArray(obj)) {\n    const filtered: unknown[] = [];\n    for (let i = 0; i < obj.length; i++) {\n      const processed = removeUndefinedRecursive(obj[i]);\n      if (processed !== undefined) {\n        filtered.push(processed);\n      }\n    }\n    return filtered as {};\n  }\n\n  const newObj: Record<string, unknown> = {};\n  let hasChanges = false;\n\n  for (const key in obj) {\n    if (Object.prototype.hasOwnProperty.call(obj, key)) {\n      const value = removeUndefinedRecursive((obj as any)[key]);\n      if (value !== undefined) {\n        newObj[key] = value;\n        hasChanges = true;\n      }\n    }\n  }\n\n  return hasChanges ? (newObj as {}) : obj;\n}\n\n/**\n * Try to resolve yak\n */\nexport function resolveYakContext(contextPath: string | undefined, cwd: string) {\n  const yakContext = contextPath\n    ? path.resolve(cwd, contextPath)\n    : path.resolve(cwd, \"yak.context\");\n  const extensions = [\"\", \".ts\", \".tsx\", \".js\", \".jsx\"];\n  for (const extension in extensions) {\n    const fileName = yakContext + extensions[extension];\n    if (existsSync(fileName)) {\n      return fileName;\n    }\n  }\n  if (contextPath) {\n    throw new Error(`Could not find yak context file at ${yakContext}`);\n  }\n}\n\n// Wrapper to allow sync, async, and function configuration of Next.js\n/**\n * Add Yak to your Next.js app\n *\n * @usage\n *\n * ```ts\n * // next.config.js\n * const { withYak } = require(\"next-yak/withYak\");\n * const nextConfig = {\n *   // your next config here\n * };\n * module.exports = withYak(nextConfig);\n * ```\n *\n * With a custom yakConfig\n *\n * ```ts\n * // next.config.js\n * const { withYak } = require(\"next-yak/withYak\");\n * const nextConfig = {\n *   // your next config here\n * };\n * const yakConfig = {\n *   // Optional prefix for generated CSS identifiers\n *   prefix: \"my-app\",\n *   // Other yak config options...\n * };\n * module.exports = withYak(yakConfig, nextConfig);\n * ```\n */\nexport const withYak: {\n  <\n    T extends\n      | Record<string, any>\n      | ((...args: any[]) => Record<string, any>)\n      | ((...args: any[]) => Promise<Record<string, any>>),\n  >(\n    yakOptions: YakConfigOptions,\n    nextConfig: T,\n  ): T;\n  // no yakConfig\n  <\n    T extends\n      | Record<string, any>\n      | ((...args: any[]) => Record<string, any>)\n      | ((...args: any[]) => Promise<Record<string, any>>),\n  >(\n    nextConfig: T,\n    _?: undefined,\n  ): T;\n} = (maybeYakOptions, nextConfig) => {\n  if (nextConfig === undefined) {\n    return withYak({}, maybeYakOptions);\n  }\n  // If the second parameter is present the first parameter must be a YakConfigOptions\n  const yakOptions = maybeYakOptions as YakConfigOptions;\n  if (typeof nextConfig === \"function\") {\n    /**\n     * A NextConfig can be a sync or async function\n     * https://nextjs.org/docs/pages/api-reference/next-config-js\n     * @param {any[]} args\n     */\n    return (...args) => {\n      /** Dynamic Next Configs can be async or sync */\n      const config = nextConfig(...args) as NextConfig | Promise<NextConfig>;\n      return config instanceof Promise\n        ? config.then((config) => addYak(yakOptions, config))\n        : addYak(yakOptions, config);\n    };\n  }\n  return addYak(yakOptions, nextConfig);\n};\n"],"mappings":"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"}