{"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  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\nconst addYak = (yakOptions: YakConfigOptions, nextConfig: NextConfig) => {\n  const minify = yakOptions.minify ?? process.env.NODE_ENV === \"production\";\n  const yakPluginOptions = {\n    minify,\n    basePath: currentDir,\n    prefix: yakOptions.prefix,\n    displayNames: yakOptions.displayNames ?? !minify,\n    suppressDeprecationWarnings: yakOptions.experiments?.suppressDeprecationWarnings ?? false,\n    reactRefreshReg: true,\n  };\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    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    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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"}