next-yak 5.6.0 → 5.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -210,12 +210,20 @@ async function parseFile(loader, filePath) {
210
210
  }
211
211
  async function parseExports(sourceContents) {
212
212
  let exports = {};
213
+ const variableDeclarations = {};
214
+ let defaultIdentifier = null;
213
215
  try {
214
216
  const ast = parse(sourceContents, {
215
217
  sourceType: "module",
216
218
  plugins: ["jsx", "typescript"]
217
219
  });
218
220
  traverse.default(ast, {
221
+ // Track all variable declarations in the file
222
+ VariableDeclarator({ node }) {
223
+ if (node.id.type === "Identifier" && node.init) {
224
+ variableDeclarations[node.id.name] = node.init;
225
+ }
226
+ },
219
227
  ExportNamedDeclaration({ node }) {
220
228
  if (node.source) {
221
229
  node.specifiers.forEach((specifier) => {
@@ -251,6 +259,20 @@ async function parseExports(sourceContents) {
251
259
  });
252
260
  }
253
261
  },
262
+ ExportDefaultDeclaration({ node }) {
263
+ if (node.declaration.type === "Identifier") {
264
+ defaultIdentifier = node.declaration.name;
265
+ } else if (node.declaration.type === "FunctionDeclaration" || node.declaration.type === "ClassDeclaration") {
266
+ exports["default"] = {
267
+ type: "unsupported",
268
+ hint: node.declaration.type
269
+ };
270
+ } else {
271
+ exports["default"] = parseExportValueExpression(
272
+ node.declaration
273
+ );
274
+ }
275
+ },
254
276
  ExportAllDeclaration({ node }) {
255
277
  if (Object.keys(exports).length === 0) {
256
278
  exports["*"] ||= {
@@ -264,6 +286,11 @@ async function parseExports(sourceContents) {
264
286
  }
265
287
  }
266
288
  });
289
+ if (defaultIdentifier && variableDeclarations[defaultIdentifier]) {
290
+ exports["default"] = parseExportValueExpression(
291
+ variableDeclarations[defaultIdentifier]
292
+ );
293
+ }
267
294
  return exports;
268
295
  } catch (error) {
269
296
  throw new Error(`Error parsing exports: ${error.message}`);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../loaders/css-loader.ts","../../loaders/lib/resolveCrossFileSelectors.ts"],"sourcesContent":["import { relative } from \"path\";\nimport type { LoaderContext } from \"webpack\";\nimport type { YakConfigOptions } from \"../withYak/index.js\";\nimport { resolveCrossFileConstant } from \"./lib/resolveCrossFileSelectors.js\";\n\n/**\n * Transform typescript to css\n *\n * This loader takes the cached result from the yak tsloader\n * and extracts the css from the generated comments\n */\nexport default async function cssExtractLoader(\n this: LoaderContext<YakConfigOptions>,\n // Instead of the source code, we receive the extracted css\n // from the yak-swc transformation\n _code: string,\n sourceMap: string | undefined,\n): Promise<string | void> {\n const callback = this.async();\n // Load the module from the original typescript request (without !=! and the query)\n return this.loadModule(this.resourcePath, (err, source) => {\n if (err) {\n return callback(err);\n }\n if (!source) {\n return callback(\n new Error(`Source code for ${this.resourcePath} is empty`),\n );\n }\n const { experiments } = this.getOptions();\n const debugLog = createDebugLogger(this, experiments?.debug);\n\n debugLog(\"ts\", source);\n const css = extractCss(source, experiments?.transpilationMode);\n debugLog(\"css\", css);\n\n return resolveCrossFileConstant(this, this.context, css).then((result) => {\n debugLog(\"css resolved\", css);\n return callback(null, result, sourceMap);\n }, callback);\n });\n}\n\nfunction extractCss(\n code: string | Buffer<ArrayBufferLike>,\n transpilationMode: NonNullable<\n YakConfigOptions[\"experiments\"]\n >[\"transpilationMode\"],\n): string {\n let codeString: string;\n\n if (typeof code === \"string\") {\n codeString = code;\n } else if (code instanceof Buffer) {\n codeString = code.toString(\"utf-8\");\n } else if (code instanceof ArrayBuffer) {\n codeString = new TextDecoder(\"utf-8\").decode(code);\n } else {\n throw new Error(\n \"Invalid input type: code must be string, Buffer, or ArrayBuffer\",\n );\n }\n\n const codeParts = codeString.split(\"/*YAK Extracted CSS:\\n\");\n let result = \"\";\n for (let i = 1; i < codeParts.length; i++) {\n const codeUntilEnd = codeParts[i].split(\"*/\")[0];\n result += codeUntilEnd;\n }\n if (result && transpilationMode !== \"Css\") {\n result = \"/* cssmodules-pure-no-check */\\n\" + result;\n }\n\n return result;\n}\n\nfunction createDebugLogger(\n loaderContext: LoaderContext<YakConfigOptions>,\n debugOptions: Required<YakConfigOptions>[\"experiments\"][\"debug\"],\n) {\n if (\n !debugOptions ||\n (debugOptions !== true &&\n debugOptions.filter &&\n !debugOptions.filter(loaderContext.resourcePath))\n ) {\n return () => {};\n }\n const debugType = debugOptions === true ? \"ts\" : debugOptions.type;\n return (\n messageType: \"ts\" | \"css\" | \"css resolved\",\n message: string | Buffer<ArrayBufferLike> | undefined,\n ) => {\n if (messageType === debugType || debugType === \"all\") {\n console.log(\n \"🐮 Yak\",\n messageType,\n \"\\n\",\n loaderContext._compiler\n ? relative(\n loaderContext._compiler.context,\n loaderContext.resourcePath,\n )\n : loaderContext.resourcePath,\n \"\\n\\n\",\n message,\n );\n }\n };\n}\n","import { parse } from \"@babel/parser\";\nimport traverse from \"@babel/traverse\";\nimport path from \"path\";\nimport type { Compilation, LoaderContext } from \"webpack\";\nimport { YakConfigOptions } from \"../../withYak/index.js\";\n\nconst yakCssImportRegex =\n // Make mixin and selector non optional once we dropped support for the babel plugin\n /--yak-css-import\\:\\s*url\\(\"([^\"]+)\",?(|mixin|selector)\\)(;?)/g;\n\nconst compilationCache = new WeakMap<\n Compilation,\n {\n parsedFiles: Map<string, ParsedFile>;\n }\n>();\n\nconst getCompilationCache = (loader: LoaderContext<YakConfigOptions>) => {\n const compilation = loader._compilation;\n if (!compilation) {\n throw new Error(\"Webpack compilation object not available\");\n }\n let cache = compilationCache.get(compilation);\n if (!cache) {\n cache = {\n parsedFiles: new Map(),\n };\n compilationCache.set(compilation, cache);\n }\n return cache;\n};\n\n/**\n * Resolves cross-file selectors in css files\n *\n * e.g.:\n * theme.ts:\n * ```ts\n * export const colors = {\n * primary: \"#ff0000\",\n * secondary: \"#00ff00\",\n * };\n * ```\n *\n * styles.ts:\n * ```ts\n * import { colors } from \"./theme\";\n * export const button = css`\n * background-color: ${colors.primary};\n * `;\n */\nexport async function resolveCrossFileConstant(\n loader: LoaderContext<{}>,\n pathContext: string,\n css: string,\n): Promise<string> {\n // Search for --yak-css-import: url(\"path/to/module\") in the css\n const matches = [...css.matchAll(yakCssImportRegex)].map((match) => {\n const [fullMatch, encodedArguments, importKind, semicolon] = match;\n const [moduleSpecifier, ...specifier] = encodedArguments\n .split(\":\")\n .map((entry) => decodeURIComponent(entry));\n return {\n encodedArguments,\n moduleSpecifier,\n specifier,\n importKind,\n semicolon,\n position: match.index!,\n size: fullMatch.length,\n };\n });\n if (matches.length === 0) return css;\n\n try {\n // Resolve all imports concurrently\n const resolvedValues = await Promise.all(\n matches.map(async ({ moduleSpecifier, specifier }) => {\n const parsedModule = await parseModule(\n loader,\n moduleSpecifier,\n pathContext,\n );\n\n const resolvedValue = await resolveModuleSpecifierRecursively(\n loader,\n parsedModule,\n specifier,\n );\n\n return resolvedValue;\n }),\n );\n\n // Replace the imports with the resolved values\n let result = css;\n for (let i = matches.length - 1; i >= 0; i--) {\n const { position, size, importKind, specifier, semicolon } = matches[i];\n const resolved = resolvedValues[i];\n\n if (importKind === \"selector\") {\n if (\n resolved.type !== \"styled-component\" &&\n resolved.type !== \"constant\"\n ) {\n throw new Error(\n `Found ${\n resolved.type\n } but expected a selector - did you forget a semicolon after \\`${specifier.join(\n \".\",\n )}\\`?`,\n );\n }\n }\n\n const replacement =\n resolved.type === \"styled-component\"\n ? resolved.value\n : resolved.value +\n // resolved.value can be of two different types:\n // - mixin:\n // ${mixinName};\n // - constant:\n // color: ${value};\n // For mixins the semicolon is already included in the value\n // but for constants it has to be added manually\n ([\"}\", \";\"].includes(String(resolved.value).trimEnd().slice(-1))\n ? \"\"\n : semicolon);\n\n result =\n result.slice(0, position) +\n String(replacement) +\n result.slice(position + size);\n }\n\n return result;\n } catch (error) {\n throw new Error(\n `Error resolving cross-file selectors: ${\n (error as Error).message\n }\\nFile: ${loader.resourcePath}`,\n );\n }\n}\n\n/**\n * Resolves a module by wrapping loader.resolve in a promise\n */\nexport async function resolveModule(\n loader: LoaderContext<{}>,\n moduleSpecifier: string,\n context: string,\n): Promise<string> {\n return new Promise<string>((resolve, reject) => {\n loader.resolve(context, moduleSpecifier, (err, result) => {\n if (err) return reject(err);\n if (!result)\n return reject(new Error(`Could not resolve ${moduleSpecifier}`));\n resolve(result);\n });\n });\n}\n\n/**\n * Resolves a module specifier to a parsed file\n *\n * e.g.:\n * ```\n * parseModule(loader, \"./theme\", \"/path/to/styles.ts\")\n * // -> { type: 'regular', secondary: { type: 'constant', value: '#00ff00' } } }, filePath: '/path/to/theme.ts' }\n * ```\n */\nasync function parseModule(\n loader: LoaderContext<YakConfigOptions>,\n moduleSpecifier: string,\n context: string,\n): Promise<ParsedFile> {\n const cache = getCompilationCache(loader).parsedFiles;\n\n // The cache key is valid for the entire project so it can be reused\n // for different source files\n const resolvedModule = await resolveModule(loader, moduleSpecifier, context);\n\n let parsedFile = cache.get(resolvedModule);\n if (!parsedFile) {\n parsedFile = await parseFile(loader, resolvedModule);\n\n // We cache the parsed file to avoid re-parsing it.\n // It's ok, that initial parallel requests to the same file will parse it multiple times.\n // This avoid deadlocks do to the fact that we load multiple modules in the chain for cross file references.\n cache.set(resolvedModule, parsedFile);\n }\n // on file change, invalidate the cache\n loader.addDependency(parsedFile.filePath);\n return parsedFile;\n}\n\nasync function parseFile(\n loader: LoaderContext<YakConfigOptions>,\n filePath: string,\n): Promise<ParsedFile> {\n const isYak =\n filePath.endsWith(\".yak.ts\") ||\n filePath.endsWith(\".yak.tsx\") ||\n filePath.endsWith(\".yak.js\") ||\n filePath.endsWith(\".yak.jsx\");\n\n try {\n if (isYak) {\n const module: Record<string, unknown> =\n await loader.importModule(filePath);\n const mappedModule = Object.fromEntries(\n Object.entries(module).map(([key, value]): [string, ParsedExport] => {\n if (typeof value === \"string\" || typeof value === \"number\") {\n return [key, { type: \"constant\" as const, value }];\n } else if (\n value &&\n (typeof value === \"object\" || Array.isArray(value))\n ) {\n return [key, { type: \"record\" as const, value }];\n } else {\n return [key, { type: \"unsupported\" as const, hint: String(value) }];\n }\n }),\n );\n return { type: \"yak\", exports: mappedModule, filePath };\n }\n const sourceContents = new Promise<string>((resolve, reject) =>\n loader.fs.readFile(filePath, \"utf-8\", (err, result) => {\n if (err) return reject(err);\n resolve(result || \"\");\n }),\n );\n\n const tranformedSource = new Promise<string>((resolve, reject) => {\n loader.loadModule(filePath, (err, source) => {\n if (err) return reject(err);\n let sourceString: string;\n if (typeof source === \"string\") {\n sourceString = source;\n } else if (source instanceof Buffer) {\n sourceString = source.toString(\"utf-8\");\n } else if (source instanceof ArrayBuffer) {\n sourceString = new TextDecoder(\"utf-8\").decode(source);\n } else {\n throw new Error(\n \"Invalid input type: code must be string, Buffer, or ArrayBuffer\",\n );\n }\n resolve(sourceString || \"\");\n });\n });\n\n const exports = await parseExports(await sourceContents);\n const mixins = parseMixins(await tranformedSource);\n Object.assign(\n exports,\n parseStyledComponents(\n await tranformedSource,\n loader.getOptions().experiments?.transpilationMode,\n ),\n );\n\n // Recursively resolve cross-file constants in mixins\n // e.g. cross file mixins inside a cross file mixin\n // or a cross file selector inside a cross file mixin\n await Promise.all(\n Object.entries(mixins).map(async ([name, { value, nameParts }]) => {\n const resolvedValue = await resolveCrossFileConstant(\n loader,\n path.dirname(filePath),\n value,\n );\n if (nameParts.length === 1) {\n exports[name] = { type: \"mixin\", value: resolvedValue };\n } else {\n let exportEntry: undefined | ParsedExport = exports[nameParts[0]];\n if (!exportEntry) {\n exportEntry = { type: \"record\", value: {} };\n exports[nameParts[0]] = exportEntry;\n } else if (exportEntry.type !== \"record\") {\n throw new Error(\n `Error parsing file ${filePath}: ${nameParts[0]} is not a record`,\n );\n }\n let current = exportEntry.value as Record<any, ParsedExport>;\n for (let i = 1; i < nameParts.length - 1; i++) {\n let next = current[nameParts[i]];\n if (!next) {\n next = { type: \"record\", value: {} };\n current[nameParts[i]] = next;\n } else if (next.type !== \"record\") {\n throw new Error(\n `Error parsing file ${filePath}: ${nameParts[i]} is not a record`,\n );\n }\n current = next.value;\n }\n current[nameParts[nameParts.length - 1]] = {\n type: \"mixin\",\n value: resolvedValue,\n };\n }\n }),\n );\n\n return {\n type: \"regular\",\n exports,\n filePath,\n };\n } catch (error) {\n throw new Error(\n `Error parsing file ${filePath}: ${(error as Error).message}`,\n );\n }\n}\n\nasync function parseExports(\n sourceContents: string,\n): Promise<Record<string, ParsedExport>> {\n let exports: Record<string, ParsedExport> = {};\n\n try {\n const ast = parse(sourceContents, {\n sourceType: \"module\",\n plugins: [\"jsx\", \"typescript\"] as const,\n });\n\n traverse.default(ast, {\n ExportNamedDeclaration({ node }) {\n if (node.source) {\n node.specifiers.forEach((specifier) => {\n if (\n specifier.type === \"ExportSpecifier\" &&\n specifier.exported.type === \"Identifier\" &&\n specifier.local.type === \"Identifier\"\n ) {\n exports[specifier.exported.name] = {\n type: \"re-export\",\n from: node.source!.value,\n imported: specifier.local.name,\n };\n }\n });\n } else if (node.declaration?.type === \"VariableDeclaration\") {\n node.declaration.declarations.forEach((declaration) => {\n if (declaration.id.type === \"Identifier\" && declaration.init) {\n const parsed = parseExportValueExpression(declaration.init);\n if (parsed) {\n exports[declaration.id.name] = parsed;\n }\n }\n });\n }\n },\n ExportDeclaration({ node }) {\n if (\"specifiers\" in node && node.source) {\n const { specifiers, source } = node;\n specifiers.forEach((specifier) => {\n // export * as color from \"./colors\";\n if (\n specifier.type === \"ExportNamespaceSpecifier\" &&\n specifier.exported.type === \"Identifier\"\n ) {\n exports[specifier.exported.name] = {\n type: \"star-export\",\n from: [source.value],\n };\n }\n });\n }\n },\n ExportAllDeclaration({ node }) {\n if (Object.keys(exports).length === 0) {\n exports[\"*\"] ||= {\n type: \"star-export\",\n from: [],\n };\n if (exports[\"*\"].type !== \"star-export\") {\n throw new Error(\"Invalid star export state\");\n }\n exports[\"*\"].from.push(node.source.value);\n }\n },\n });\n\n return exports;\n } catch (error) {\n throw new Error(`Error parsing exports: ${(error as Error).message}`);\n }\n}\n\nfunction parseMixins(\n sourceContents: string,\n): Record<string, { type: \"mixin\"; value: string; nameParts: string[] }> {\n // Mixins are always in the following format:\n // /*YAK EXPORTED MIXIN:fancy:aspectRatio:16:9\n // css\n // */\n const mixinParts = sourceContents.split(\"/*YAK EXPORTED MIXIN:\");\n let mixins: Record<\n string,\n { type: \"mixin\"; value: string; nameParts: string[] }\n > = {};\n\n for (let i = 1; i < mixinParts.length; i++) {\n const [comment] = mixinParts[i].split(\"*/\", 1);\n const position = comment.indexOf(\"\\n\");\n const name = comment.slice(0, position);\n const value = comment.slice(position + 1);\n mixins[name] = {\n type: \"mixin\",\n value,\n nameParts: name.split(\":\").map((part) => decodeURIComponent(part)),\n };\n }\n return mixins;\n}\n\nfunction parseStyledComponents(\n sourceContents: string,\n transpilationMode?: NonNullable<\n YakConfigOptions[\"experiments\"]\n >[\"transpilationMode\"],\n): Record<string, { type: \"styled-component\"; value: string }> {\n // cross-file Styled Components are always in the following format:\n // /*YAK EXPORTED STYLED:ComponentName:ClassName*/\n const styledParts = sourceContents.split(\"/*YAK EXPORTED STYLED:\");\n let styledComponents: Record<\n string,\n { type: \"styled-component\"; value: string }\n > = {};\n\n for (let i = 1; i < styledParts.length; i++) {\n const [comment] = styledParts[i].split(\"*/\", 1);\n const [componentName, className] = comment.split(\":\");\n styledComponents[componentName] = {\n type: \"styled-component\",\n value:\n transpilationMode === \"Css\"\n ? `.${className}`\n : `:global(.${className})`,\n };\n }\n\n return styledComponents;\n}\n\n/**\n * Unpacks a TSAsExpression to its expression value\n */\nfunction unpackTSAsExpression(\n node: babel.types.TSAsExpression | babel.types.Expression,\n): babel.types.Expression {\n if (node.type === \"TSAsExpression\") {\n return unpackTSAsExpression(node.expression);\n }\n return node;\n}\n\nfunction parseExportValueExpression(\n node: babel.types.Expression,\n): ParsedExport {\n // ignores `as` casts so it doesn't interfere with the ast node type detection\n const expression = unpackTSAsExpression(node);\n if (\n expression.type === \"CallExpression\" ||\n expression.type === \"TaggedTemplateExpression\"\n ) {\n // The value will be set by parseStyledComponents\n return { type: \"styled-component\", value: undefined };\n } else if (\n expression.type === \"StringLiteral\" ||\n expression.type === \"NumericLiteral\"\n ) {\n return { type: \"constant\", value: expression.value };\n } else if (\n expression.type === \"UnaryExpression\" &&\n expression.operator === \"-\" &&\n expression.argument.type === \"NumericLiteral\"\n ) {\n return { type: \"constant\", value: -expression.argument.value };\n } else if (\n expression.type === \"TemplateLiteral\" &&\n expression.quasis.length === 1\n ) {\n return { type: \"constant\", value: expression.quasis[0].value.raw };\n } else if (expression.type === \"ObjectExpression\") {\n return { type: \"record\", value: parseObjectExpression(expression) };\n }\n return { type: \"unsupported\", hint: expression.type };\n}\n\nfunction parseObjectExpression(\n node: babel.types.ObjectExpression,\n): Record<string, ParsedExport> {\n let result: Record<string, ParsedExport> = {};\n for (const property of node.properties) {\n if (\n property.type === \"ObjectProperty\" &&\n property.key.type === \"Identifier\"\n ) {\n const key = property.key.name;\n const parsed = parseExportValueExpression(\n property.value as babel.types.Expression,\n );\n if (parsed) {\n result[key] = parsed;\n }\n }\n }\n return result;\n}\n\n/**\n * Follows a specifier recursively until it finds its constant value\n * for example here it follows \"colors.primary\"\n *\n * ```\n * resolveModuleSpecifierRecursively(loader, \"@/theme\", [\"colors\", \"primary\"], \"colors:primary\")`\n * // -> { type: 'constant', value: '#ff0000' }\n * ```\n *\n * example structure:\n *\n * styles.ts:\n * ```\n * import { colors } from \"@/theme\";\n * export const button = css`color: ${colors.primary}`;\n * ```\n *\n * theme.ts:\n * ```\n * export { colors } from \"./colors\";\n * ```\n *\n * colors.ts:\n * ```\n * export const colors = { primary: \"#ff0000\" };\n * ```\n *\n */\nasync function resolveModuleSpecifierRecursively(\n loader: LoaderContext<{}>,\n module: ParsedFile,\n specifier: string[],\n): Promise<ResolvedExport> {\n try {\n const exportName = specifier[0];\n let exportValue = module.exports[exportName];\n // Follow star exports if there is only a single one\n // and the export does not exist in the current module\n if (exportValue === undefined) {\n const starExport = module.exports[\"*\"];\n if (starExport?.type === \"star-export\") {\n if (starExport.from.length > 1) {\n throw new Error(\n `Could not resolve ${specifier.join(\".\")} in module ${\n module.filePath\n } - Multiple star exports are not supported for performance reasons`,\n );\n }\n exportValue = {\n type: \"re-export\" as const,\n from: starExport.from[0],\n imported: exportName,\n };\n } else {\n throw new Error(\n `Could not resolve \"${specifier.join(\".\")}\" in module ${\n module.filePath\n }`,\n );\n }\n }\n // Follow reexport\n // e.g. export { colors as primaryColors } from \"./colors\";\n if (exportValue.type === \"re-export\") {\n const importedModule = await parseModule(\n loader,\n exportValue.from,\n path.dirname(module.filePath),\n );\n return resolveModuleSpecifierRecursively(loader, importedModule, [\n exportValue.imported,\n ...specifier.slice(1),\n ]);\n }\n // Namespace export\n // e.g. export * as colors from \"./colors\";\n else if (exportValue.type === \"star-export\") {\n const importedModule = await parseModule(\n loader,\n exportValue.from[0],\n path.dirname(module.filePath),\n );\n return resolveModuleSpecifierRecursively(\n loader,\n importedModule,\n specifier.slice(1),\n );\n }\n\n if (exportValue.type === \"styled-component\") {\n return {\n type: \"styled-component\",\n from: module.filePath,\n name: specifier[specifier.length - 1],\n value: exportValue.value,\n };\n } else if (exportValue.type === \"constant\") {\n return { type: \"constant\", value: exportValue.value };\n } else if (exportValue.type === \"record\") {\n let current: any = exportValue.value;\n let depth = 0;\n /// Drill down the specifier e.g. colors.primary\n do {\n if (typeof current === \"string\" || typeof current === \"number\") {\n return {\n type: \"constant\" as const,\n value: current,\n };\n } else if (\n !current ||\n (typeof current !== \"object\" && !Array.isArray(current))\n ) {\n throw new Error(\n `Error unpacking Record/Array \"${exportName}\".\\nKey \"${\n specifier[depth]\n }\" was of type \"${typeof current}\" but only String and Number are supported`,\n );\n }\n depth++;\n // mixins in .yak files are wrapped inside an object with a __yak key\n if (depth === specifier.length && \"__yak\" in current) {\n return { type: \"mixin\", value: current[\"__yak\"] };\n } else if (depth === specifier.length && \"value\" in current) {\n return { type: \"constant\", value: current[\"value\"] };\n } else if (\"value\" in current) {\n current = current.value[specifier[depth]];\n } else {\n current = current[specifier[depth]];\n }\n } while (current);\n if (specifier[depth] === undefined) {\n throw new Error(\n `Error unpacking Record/Array - could not extract \\`${specifier\n .slice(0, depth)\n .join(\".\")}\\` is not a string or number`,\n );\n }\n throw new Error(\n `Error unpacking Record/Array - could not extract \\`${\n specifier[depth]\n }\\` from \\`${specifier.slice(0, depth).join(\".\")}\\``,\n );\n } else if (exportValue.type === \"mixin\") {\n return { type: \"mixin\", value: exportValue.value };\n }\n throw new Error(\n `Error unpacking Record/Array - unexpected exportValue \"${\n exportValue.type\n }\" for specifier \"${specifier.join(\".\")}\"`,\n );\n } catch (error) {\n throw new Error(\n `Error resolving from module ${module.filePath}: ${\n (error as Error).message\n }\\nExtracted values: ${JSON.stringify(module.exports, null, 2)}`,\n );\n }\n}\n\ntype ParsedFile =\n | { type: \"regular\"; exports: Record<string, ParsedExport>; filePath: string }\n | { type: \"yak\"; exports: Record<string, ParsedExport>; filePath: string };\n\ntype ParsedExport =\n | { type: \"styled-component\"; value: string | undefined }\n | { type: \"mixin\"; value: string }\n | { type: \"constant\"; value: string | number }\n | { type: \"record\"; value: Record<any, ParsedExport> | {} }\n | { type: \"unsupported\"; hint?: string }\n | { type: \"re-export\"; from: string; imported: string }\n | { type: \"star-export\"; from: string[] };\n\ntype ResolvedExport =\n | {\n type: \"styled-component\";\n from: string;\n name: string;\n value: string | undefined;\n }\n | { type: \"mixin\"; value: string | number }\n | { type: \"constant\"; value: string | number };\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../loaders/css-loader.ts","../../loaders/lib/resolveCrossFileSelectors.ts"],"sourcesContent":["import { relative } from \"path\";\nimport type { LoaderContext } from \"webpack\";\nimport type { YakConfigOptions } from \"../withYak/index.js\";\nimport { resolveCrossFileConstant } from \"./lib/resolveCrossFileSelectors.js\";\n\n/**\n * Transform typescript to css\n *\n * This loader takes the cached result from the yak tsloader\n * and extracts the css from the generated comments\n */\nexport default async function cssExtractLoader(\n this: LoaderContext<YakConfigOptions>,\n // Instead of the source code, we receive the extracted css\n // from the yak-swc transformation\n _code: string,\n sourceMap: string | undefined,\n): Promise<string | void> {\n const callback = this.async();\n // Load the module from the original typescript request (without !=! and the query)\n return this.loadModule(this.resourcePath, (err, source) => {\n if (err) {\n return callback(err);\n }\n if (!source) {\n return callback(\n new Error(`Source code for ${this.resourcePath} is empty`),\n );\n }\n const { experiments } = this.getOptions();\n const debugLog = createDebugLogger(this, experiments?.debug);\n\n debugLog(\"ts\", source);\n const css = extractCss(source, experiments?.transpilationMode);\n debugLog(\"css\", css);\n\n return resolveCrossFileConstant(this, this.context, css).then((result) => {\n debugLog(\"css resolved\", css);\n return callback(null, result, sourceMap);\n }, callback);\n });\n}\n\nfunction extractCss(\n code: string | Buffer<ArrayBufferLike>,\n transpilationMode: NonNullable<\n YakConfigOptions[\"experiments\"]\n >[\"transpilationMode\"],\n): string {\n let codeString: string;\n\n if (typeof code === \"string\") {\n codeString = code;\n } else if (code instanceof Buffer) {\n codeString = code.toString(\"utf-8\");\n } else if (code instanceof ArrayBuffer) {\n codeString = new TextDecoder(\"utf-8\").decode(code);\n } else {\n throw new Error(\n \"Invalid input type: code must be string, Buffer, or ArrayBuffer\",\n );\n }\n\n const codeParts = codeString.split(\"/*YAK Extracted CSS:\\n\");\n let result = \"\";\n for (let i = 1; i < codeParts.length; i++) {\n const codeUntilEnd = codeParts[i].split(\"*/\")[0];\n result += codeUntilEnd;\n }\n if (result && transpilationMode !== \"Css\") {\n result = \"/* cssmodules-pure-no-check */\\n\" + result;\n }\n\n return result;\n}\n\nfunction createDebugLogger(\n loaderContext: LoaderContext<YakConfigOptions>,\n debugOptions: Required<YakConfigOptions>[\"experiments\"][\"debug\"],\n) {\n if (\n !debugOptions ||\n (debugOptions !== true &&\n debugOptions.filter &&\n !debugOptions.filter(loaderContext.resourcePath))\n ) {\n return () => {};\n }\n const debugType = debugOptions === true ? \"ts\" : debugOptions.type;\n return (\n messageType: \"ts\" | \"css\" | \"css resolved\",\n message: string | Buffer<ArrayBufferLike> | undefined,\n ) => {\n if (messageType === debugType || debugType === \"all\") {\n console.log(\n \"🐮 Yak\",\n messageType,\n \"\\n\",\n loaderContext._compiler\n ? relative(\n loaderContext._compiler.context,\n loaderContext.resourcePath,\n )\n : loaderContext.resourcePath,\n \"\\n\\n\",\n message,\n );\n }\n };\n}\n","import { parse } from \"@babel/parser\";\nimport traverse from \"@babel/traverse\";\nimport path from \"path\";\nimport type { Compilation, LoaderContext } from \"webpack\";\nimport { YakConfigOptions } from \"../../withYak/index.js\";\n\nconst yakCssImportRegex =\n // Make mixin and selector non optional once we dropped support for the babel plugin\n /--yak-css-import\\:\\s*url\\(\"([^\"]+)\",?(|mixin|selector)\\)(;?)/g;\n\nconst compilationCache = new WeakMap<\n Compilation,\n {\n parsedFiles: Map<string, ParsedFile>;\n }\n>();\n\nconst getCompilationCache = (loader: LoaderContext<YakConfigOptions>) => {\n const compilation = loader._compilation;\n if (!compilation) {\n throw new Error(\"Webpack compilation object not available\");\n }\n let cache = compilationCache.get(compilation);\n if (!cache) {\n cache = {\n parsedFiles: new Map(),\n };\n compilationCache.set(compilation, cache);\n }\n return cache;\n};\n\n/**\n * Resolves cross-file selectors in css files\n *\n * e.g.:\n * theme.ts:\n * ```ts\n * export const colors = {\n * primary: \"#ff0000\",\n * secondary: \"#00ff00\",\n * };\n * ```\n *\n * styles.ts:\n * ```ts\n * import { colors } from \"./theme\";\n * export const button = css`\n * background-color: ${colors.primary};\n * `;\n */\nexport async function resolveCrossFileConstant(\n loader: LoaderContext<{}>,\n pathContext: string,\n css: string,\n): Promise<string> {\n // Search for --yak-css-import: url(\"path/to/module\") in the css\n const matches = [...css.matchAll(yakCssImportRegex)].map((match) => {\n const [fullMatch, encodedArguments, importKind, semicolon] = match;\n const [moduleSpecifier, ...specifier] = encodedArguments\n .split(\":\")\n .map((entry) => decodeURIComponent(entry));\n return {\n encodedArguments,\n moduleSpecifier,\n specifier,\n importKind,\n semicolon,\n position: match.index!,\n size: fullMatch.length,\n };\n });\n if (matches.length === 0) return css;\n\n try {\n // Resolve all imports concurrently\n const resolvedValues = await Promise.all(\n matches.map(async ({ moduleSpecifier, specifier }) => {\n const parsedModule = await parseModule(\n loader,\n moduleSpecifier,\n pathContext,\n );\n\n const resolvedValue = await resolveModuleSpecifierRecursively(\n loader,\n parsedModule,\n specifier,\n );\n\n return resolvedValue;\n }),\n );\n\n // Replace the imports with the resolved values\n let result = css;\n for (let i = matches.length - 1; i >= 0; i--) {\n const { position, size, importKind, specifier, semicolon } = matches[i];\n const resolved = resolvedValues[i];\n\n if (importKind === \"selector\") {\n if (\n resolved.type !== \"styled-component\" &&\n resolved.type !== \"constant\"\n ) {\n throw new Error(\n `Found ${\n resolved.type\n } but expected a selector - did you forget a semicolon after \\`${specifier.join(\n \".\",\n )}\\`?`,\n );\n }\n }\n\n const replacement =\n resolved.type === \"styled-component\"\n ? resolved.value\n : resolved.value +\n // resolved.value can be of two different types:\n // - mixin:\n // ${mixinName};\n // - constant:\n // color: ${value};\n // For mixins the semicolon is already included in the value\n // but for constants it has to be added manually\n ([\"}\", \";\"].includes(String(resolved.value).trimEnd().slice(-1))\n ? \"\"\n : semicolon);\n\n result =\n result.slice(0, position) +\n String(replacement) +\n result.slice(position + size);\n }\n\n return result;\n } catch (error) {\n throw new Error(\n `Error resolving cross-file selectors: ${\n (error as Error).message\n }\\nFile: ${loader.resourcePath}`,\n );\n }\n}\n\n/**\n * Resolves a module by wrapping loader.resolve in a promise\n */\nexport async function resolveModule(\n loader: LoaderContext<{}>,\n moduleSpecifier: string,\n context: string,\n): Promise<string> {\n return new Promise<string>((resolve, reject) => {\n loader.resolve(context, moduleSpecifier, (err, result) => {\n if (err) return reject(err);\n if (!result)\n return reject(new Error(`Could not resolve ${moduleSpecifier}`));\n resolve(result);\n });\n });\n}\n\n/**\n * Resolves a module specifier to a parsed file\n *\n * e.g.:\n * ```\n * parseModule(loader, \"./theme\", \"/path/to/styles.ts\")\n * // -> { type: 'regular', secondary: { type: 'constant', value: '#00ff00' } } }, filePath: '/path/to/theme.ts' }\n * ```\n */\nasync function parseModule(\n loader: LoaderContext<YakConfigOptions>,\n moduleSpecifier: string,\n context: string,\n): Promise<ParsedFile> {\n const cache = getCompilationCache(loader).parsedFiles;\n\n // The cache key is valid for the entire project so it can be reused\n // for different source files\n const resolvedModule = await resolveModule(loader, moduleSpecifier, context);\n\n let parsedFile = cache.get(resolvedModule);\n if (!parsedFile) {\n parsedFile = await parseFile(loader, resolvedModule);\n\n // We cache the parsed file to avoid re-parsing it.\n // It's ok, that initial parallel requests to the same file will parse it multiple times.\n // This avoid deadlocks do to the fact that we load multiple modules in the chain for cross file references.\n cache.set(resolvedModule, parsedFile);\n }\n // on file change, invalidate the cache\n loader.addDependency(parsedFile.filePath);\n return parsedFile;\n}\n\nasync function parseFile(\n loader: LoaderContext<YakConfigOptions>,\n filePath: string,\n): Promise<ParsedFile> {\n const isYak =\n filePath.endsWith(\".yak.ts\") ||\n filePath.endsWith(\".yak.tsx\") ||\n filePath.endsWith(\".yak.js\") ||\n filePath.endsWith(\".yak.jsx\");\n\n try {\n if (isYak) {\n const module: Record<string, unknown> =\n await loader.importModule(filePath);\n const mappedModule = Object.fromEntries(\n Object.entries(module).map(([key, value]): [string, ParsedExport] => {\n if (typeof value === \"string\" || typeof value === \"number\") {\n return [key, { type: \"constant\" as const, value }];\n } else if (\n value &&\n (typeof value === \"object\" || Array.isArray(value))\n ) {\n return [key, { type: \"record\" as const, value }];\n } else {\n return [key, { type: \"unsupported\" as const, hint: String(value) }];\n }\n }),\n );\n return { type: \"yak\", exports: mappedModule, filePath };\n }\n const sourceContents = new Promise<string>((resolve, reject) =>\n loader.fs.readFile(filePath, \"utf-8\", (err, result) => {\n if (err) return reject(err);\n resolve(result || \"\");\n }),\n );\n\n const tranformedSource = new Promise<string>((resolve, reject) => {\n loader.loadModule(filePath, (err, source) => {\n if (err) return reject(err);\n let sourceString: string;\n if (typeof source === \"string\") {\n sourceString = source;\n } else if (source instanceof Buffer) {\n sourceString = source.toString(\"utf-8\");\n } else if (source instanceof ArrayBuffer) {\n sourceString = new TextDecoder(\"utf-8\").decode(source);\n } else {\n throw new Error(\n \"Invalid input type: code must be string, Buffer, or ArrayBuffer\",\n );\n }\n resolve(sourceString || \"\");\n });\n });\n\n const exports = await parseExports(await sourceContents);\n const mixins = parseMixins(await tranformedSource);\n Object.assign(\n exports,\n parseStyledComponents(\n await tranformedSource,\n loader.getOptions().experiments?.transpilationMode,\n ),\n );\n\n // Recursively resolve cross-file constants in mixins\n // e.g. cross file mixins inside a cross file mixin\n // or a cross file selector inside a cross file mixin\n await Promise.all(\n Object.entries(mixins).map(async ([name, { value, nameParts }]) => {\n const resolvedValue = await resolveCrossFileConstant(\n loader,\n path.dirname(filePath),\n value,\n );\n if (nameParts.length === 1) {\n exports[name] = { type: \"mixin\", value: resolvedValue };\n } else {\n let exportEntry: undefined | ParsedExport = exports[nameParts[0]];\n if (!exportEntry) {\n exportEntry = { type: \"record\", value: {} };\n exports[nameParts[0]] = exportEntry;\n } else if (exportEntry.type !== \"record\") {\n throw new Error(\n `Error parsing file ${filePath}: ${nameParts[0]} is not a record`,\n );\n }\n let current = exportEntry.value as Record<any, ParsedExport>;\n for (let i = 1; i < nameParts.length - 1; i++) {\n let next = current[nameParts[i]];\n if (!next) {\n next = { type: \"record\", value: {} };\n current[nameParts[i]] = next;\n } else if (next.type !== \"record\") {\n throw new Error(\n `Error parsing file ${filePath}: ${nameParts[i]} is not a record`,\n );\n }\n current = next.value;\n }\n current[nameParts[nameParts.length - 1]] = {\n type: \"mixin\",\n value: resolvedValue,\n };\n }\n }),\n );\n\n return {\n type: \"regular\",\n exports,\n filePath,\n };\n } catch (error) {\n throw new Error(\n `Error parsing file ${filePath}: ${(error as Error).message}`,\n );\n }\n}\n\nasync function parseExports(\n sourceContents: string,\n): Promise<Record<string, ParsedExport>> {\n let exports: Record<string, ParsedExport> = {};\n // Track variable declarations for lookup\n const variableDeclarations: Record<string, babel.types.Expression> = {};\n // Track default export identifier if present\n let defaultIdentifier: string | null = null;\n\n try {\n const ast = parse(sourceContents, {\n sourceType: \"module\",\n plugins: [\"jsx\", \"typescript\"] as const,\n });\n\n traverse.default(ast, {\n // Track all variable declarations in the file\n VariableDeclarator({ node }) {\n if (node.id.type === \"Identifier\" && node.init) {\n variableDeclarations[node.id.name] = node.init;\n }\n },\n\n ExportNamedDeclaration({ node }) {\n if (node.source) {\n node.specifiers.forEach((specifier) => {\n if (\n specifier.type === \"ExportSpecifier\" &&\n specifier.exported.type === \"Identifier\" &&\n specifier.local.type === \"Identifier\"\n ) {\n exports[specifier.exported.name] = {\n type: \"re-export\",\n from: node.source!.value,\n imported: specifier.local.name,\n };\n }\n });\n } else if (node.declaration?.type === \"VariableDeclaration\") {\n node.declaration.declarations.forEach((declaration) => {\n if (declaration.id.type === \"Identifier\" && declaration.init) {\n const parsed = parseExportValueExpression(declaration.init);\n if (parsed) {\n exports[declaration.id.name] = parsed;\n }\n }\n });\n }\n },\n ExportDeclaration({ node }) {\n if (\"specifiers\" in node && node.source) {\n const { specifiers, source } = node;\n specifiers.forEach((specifier) => {\n // export * as color from \"./colors\";\n if (\n specifier.type === \"ExportNamespaceSpecifier\" &&\n specifier.exported.type === \"Identifier\"\n ) {\n exports[specifier.exported.name] = {\n type: \"star-export\",\n from: [source.value],\n };\n }\n });\n }\n },\n ExportDefaultDeclaration({ node }) {\n if (node.declaration.type === \"Identifier\") {\n // e.g. export default variableName;\n // Save the identifier name to look up later\n defaultIdentifier = node.declaration.name;\n } else if (\n node.declaration.type === \"FunctionDeclaration\" ||\n node.declaration.type === \"ClassDeclaration\"\n ) {\n // e.g. export default function() {...} or export default class {...}\n exports[\"default\"] = {\n type: \"unsupported\",\n hint: node.declaration.type,\n };\n } else {\n // e.g. export default { ... } or export default \"value\"\n exports[\"default\"] = parseExportValueExpression(\n node.declaration as babel.types.Expression,\n );\n }\n },\n ExportAllDeclaration({ node }) {\n if (Object.keys(exports).length === 0) {\n exports[\"*\"] ||= {\n type: \"star-export\",\n from: [],\n };\n if (exports[\"*\"].type !== \"star-export\") {\n throw new Error(\"Invalid star export state\");\n }\n exports[\"*\"].from.push(node.source.value);\n }\n },\n });\n // If we found a default export that's an identifier, look up its value\n if (defaultIdentifier && variableDeclarations[defaultIdentifier]) {\n exports[\"default\"] = parseExportValueExpression(\n variableDeclarations[defaultIdentifier],\n );\n }\n\n return exports;\n } catch (error) {\n throw new Error(`Error parsing exports: ${(error as Error).message}`);\n }\n}\n\nfunction parseMixins(\n sourceContents: string,\n): Record<string, { type: \"mixin\"; value: string; nameParts: string[] }> {\n // Mixins are always in the following format:\n // /*YAK EXPORTED MIXIN:fancy:aspectRatio:16:9\n // css\n // */\n const mixinParts = sourceContents.split(\"/*YAK EXPORTED MIXIN:\");\n let mixins: Record<\n string,\n { type: \"mixin\"; value: string; nameParts: string[] }\n > = {};\n\n for (let i = 1; i < mixinParts.length; i++) {\n const [comment] = mixinParts[i].split(\"*/\", 1);\n const position = comment.indexOf(\"\\n\");\n const name = comment.slice(0, position);\n const value = comment.slice(position + 1);\n mixins[name] = {\n type: \"mixin\",\n value,\n nameParts: name.split(\":\").map((part) => decodeURIComponent(part)),\n };\n }\n return mixins;\n}\n\nfunction parseStyledComponents(\n sourceContents: string,\n transpilationMode?: NonNullable<\n YakConfigOptions[\"experiments\"]\n >[\"transpilationMode\"],\n): Record<string, { type: \"styled-component\"; value: string }> {\n // cross-file Styled Components are always in the following format:\n // /*YAK EXPORTED STYLED:ComponentName:ClassName*/\n const styledParts = sourceContents.split(\"/*YAK EXPORTED STYLED:\");\n let styledComponents: Record<\n string,\n { type: \"styled-component\"; value: string }\n > = {};\n\n for (let i = 1; i < styledParts.length; i++) {\n const [comment] = styledParts[i].split(\"*/\", 1);\n const [componentName, className] = comment.split(\":\");\n styledComponents[componentName] = {\n type: \"styled-component\",\n value:\n transpilationMode === \"Css\"\n ? `.${className}`\n : `:global(.${className})`,\n };\n }\n\n return styledComponents;\n}\n\n/**\n * Unpacks a TSAsExpression to its expression value\n */\nfunction unpackTSAsExpression(\n node: babel.types.TSAsExpression | babel.types.Expression,\n): babel.types.Expression {\n if (node.type === \"TSAsExpression\") {\n return unpackTSAsExpression(node.expression);\n }\n return node;\n}\n\nfunction parseExportValueExpression(\n node: babel.types.Expression,\n): ParsedExport {\n // ignores `as` casts so it doesn't interfere with the ast node type detection\n const expression = unpackTSAsExpression(node);\n if (\n expression.type === \"CallExpression\" ||\n expression.type === \"TaggedTemplateExpression\"\n ) {\n // The value will be set by parseStyledComponents\n return { type: \"styled-component\", value: undefined };\n } else if (\n expression.type === \"StringLiteral\" ||\n expression.type === \"NumericLiteral\"\n ) {\n return { type: \"constant\", value: expression.value };\n } else if (\n expression.type === \"UnaryExpression\" &&\n expression.operator === \"-\" &&\n expression.argument.type === \"NumericLiteral\"\n ) {\n return { type: \"constant\", value: -expression.argument.value };\n } else if (\n expression.type === \"TemplateLiteral\" &&\n expression.quasis.length === 1\n ) {\n return { type: \"constant\", value: expression.quasis[0].value.raw };\n } else if (expression.type === \"ObjectExpression\") {\n return { type: \"record\", value: parseObjectExpression(expression) };\n }\n return { type: \"unsupported\", hint: expression.type };\n}\n\nfunction parseObjectExpression(\n node: babel.types.ObjectExpression,\n): Record<string, ParsedExport> {\n let result: Record<string, ParsedExport> = {};\n for (const property of node.properties) {\n if (\n property.type === \"ObjectProperty\" &&\n property.key.type === \"Identifier\"\n ) {\n const key = property.key.name;\n const parsed = parseExportValueExpression(\n property.value as babel.types.Expression,\n );\n if (parsed) {\n result[key] = parsed;\n }\n }\n }\n return result;\n}\n\n/**\n * Follows a specifier recursively until it finds its constant value\n * for example here it follows \"colors.primary\"\n *\n * ```\n * resolveModuleSpecifierRecursively(loader, \"@/theme\", [\"colors\", \"primary\"], \"colors:primary\")`\n * // -> { type: 'constant', value: '#ff0000' }\n * ```\n *\n * example structure:\n *\n * styles.ts:\n * ```\n * import { colors } from \"@/theme\";\n * export const button = css`color: ${colors.primary}`;\n * ```\n *\n * theme.ts:\n * ```\n * export { colors } from \"./colors\";\n * ```\n *\n * colors.ts:\n * ```\n * export const colors = { primary: \"#ff0000\" };\n * ```\n *\n */\nasync function resolveModuleSpecifierRecursively(\n loader: LoaderContext<{}>,\n module: ParsedFile,\n specifier: string[],\n): Promise<ResolvedExport> {\n try {\n const exportName = specifier[0];\n let exportValue = module.exports[exportName];\n // Follow star exports if there is only a single one\n // and the export does not exist in the current module\n if (exportValue === undefined) {\n const starExport = module.exports[\"*\"];\n if (starExport?.type === \"star-export\") {\n if (starExport.from.length > 1) {\n throw new Error(\n `Could not resolve ${specifier.join(\".\")} in module ${\n module.filePath\n } - Multiple star exports are not supported for performance reasons`,\n );\n }\n exportValue = {\n type: \"re-export\" as const,\n from: starExport.from[0],\n imported: exportName,\n };\n } else {\n throw new Error(\n `Could not resolve \"${specifier.join(\".\")}\" in module ${\n module.filePath\n }`,\n );\n }\n }\n // Follow reexport\n // e.g. export { colors as primaryColors } from \"./colors\";\n if (exportValue.type === \"re-export\") {\n const importedModule = await parseModule(\n loader,\n exportValue.from,\n path.dirname(module.filePath),\n );\n return resolveModuleSpecifierRecursively(loader, importedModule, [\n exportValue.imported,\n ...specifier.slice(1),\n ]);\n }\n // Namespace export\n // e.g. export * as colors from \"./colors\";\n else if (exportValue.type === \"star-export\") {\n const importedModule = await parseModule(\n loader,\n exportValue.from[0],\n path.dirname(module.filePath),\n );\n return resolveModuleSpecifierRecursively(\n loader,\n importedModule,\n specifier.slice(1),\n );\n }\n\n if (exportValue.type === \"styled-component\") {\n return {\n type: \"styled-component\",\n from: module.filePath,\n name: specifier[specifier.length - 1],\n value: exportValue.value,\n };\n } else if (exportValue.type === \"constant\") {\n return { type: \"constant\", value: exportValue.value };\n } else if (exportValue.type === \"record\") {\n let current: any = exportValue.value;\n let depth = 0;\n /// Drill down the specifier e.g. colors.primary\n do {\n if (typeof current === \"string\" || typeof current === \"number\") {\n return {\n type: \"constant\" as const,\n value: current,\n };\n } else if (\n !current ||\n (typeof current !== \"object\" && !Array.isArray(current))\n ) {\n throw new Error(\n `Error unpacking Record/Array \"${exportName}\".\\nKey \"${\n specifier[depth]\n }\" was of type \"${typeof current}\" but only String and Number are supported`,\n );\n }\n depth++;\n // mixins in .yak files are wrapped inside an object with a __yak key\n if (depth === specifier.length && \"__yak\" in current) {\n return { type: \"mixin\", value: current[\"__yak\"] };\n } else if (depth === specifier.length && \"value\" in current) {\n return { type: \"constant\", value: current[\"value\"] };\n } else if (\"value\" in current) {\n current = current.value[specifier[depth]];\n } else {\n current = current[specifier[depth]];\n }\n } while (current);\n if (specifier[depth] === undefined) {\n throw new Error(\n `Error unpacking Record/Array - could not extract \\`${specifier\n .slice(0, depth)\n .join(\".\")}\\` is not a string or number`,\n );\n }\n throw new Error(\n `Error unpacking Record/Array - could not extract \\`${\n specifier[depth]\n }\\` from \\`${specifier.slice(0, depth).join(\".\")}\\``,\n );\n } else if (exportValue.type === \"mixin\") {\n return { type: \"mixin\", value: exportValue.value };\n }\n throw new Error(\n `Error unpacking Record/Array - unexpected exportValue \"${\n exportValue.type\n }\" for specifier \"${specifier.join(\".\")}\"`,\n );\n } catch (error) {\n throw new Error(\n `Error resolving from module ${module.filePath}: ${\n (error as Error).message\n }\\nExtracted values: ${JSON.stringify(module.exports, null, 2)}`,\n );\n }\n}\n\ntype ParsedFile =\n | { type: \"regular\"; exports: Record<string, ParsedExport>; filePath: string }\n | { type: \"yak\"; exports: Record<string, ParsedExport>; filePath: string };\n\ntype ParsedExport =\n | { type: \"styled-component\"; value: string | undefined }\n | { type: \"mixin\"; value: string }\n | { type: \"constant\"; value: string | number }\n | { type: \"record\"; value: Record<any, ParsedExport> | {} }\n | { type: \"unsupported\"; hint?: string }\n | { type: \"re-export\"; from: string; imported: string }\n | { type: \"star-export\"; from: string[] };\n\ntype ResolvedExport =\n | {\n type: \"styled-component\";\n from: string;\n name: string;\n value: string | undefined;\n }\n | { type: \"mixin\"; value: string | number }\n | { type: \"constant\"; value: string | number };\n"],"mappings":"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","names":[]}
@@ -321,6 +321,10 @@ async function parseExports(
321
321
  sourceContents: string,
322
322
  ): Promise<Record<string, ParsedExport>> {
323
323
  let exports: Record<string, ParsedExport> = {};
324
+ // Track variable declarations for lookup
325
+ const variableDeclarations: Record<string, babel.types.Expression> = {};
326
+ // Track default export identifier if present
327
+ let defaultIdentifier: string | null = null;
324
328
 
325
329
  try {
326
330
  const ast = parse(sourceContents, {
@@ -329,6 +333,13 @@ async function parseExports(
329
333
  });
330
334
 
331
335
  traverse.default(ast, {
336
+ // Track all variable declarations in the file
337
+ VariableDeclarator({ node }) {
338
+ if (node.id.type === "Identifier" && node.init) {
339
+ variableDeclarations[node.id.name] = node.init;
340
+ }
341
+ },
342
+
332
343
  ExportNamedDeclaration({ node }) {
333
344
  if (node.source) {
334
345
  node.specifiers.forEach((specifier) => {
@@ -372,6 +383,27 @@ async function parseExports(
372
383
  });
373
384
  }
374
385
  },
386
+ ExportDefaultDeclaration({ node }) {
387
+ if (node.declaration.type === "Identifier") {
388
+ // e.g. export default variableName;
389
+ // Save the identifier name to look up later
390
+ defaultIdentifier = node.declaration.name;
391
+ } else if (
392
+ node.declaration.type === "FunctionDeclaration" ||
393
+ node.declaration.type === "ClassDeclaration"
394
+ ) {
395
+ // e.g. export default function() {...} or export default class {...}
396
+ exports["default"] = {
397
+ type: "unsupported",
398
+ hint: node.declaration.type,
399
+ };
400
+ } else {
401
+ // e.g. export default { ... } or export default "value"
402
+ exports["default"] = parseExportValueExpression(
403
+ node.declaration as babel.types.Expression,
404
+ );
405
+ }
406
+ },
375
407
  ExportAllDeclaration({ node }) {
376
408
  if (Object.keys(exports).length === 0) {
377
409
  exports["*"] ||= {
@@ -385,6 +417,12 @@ async function parseExports(
385
417
  }
386
418
  },
387
419
  });
420
+ // If we found a default export that's an identifier, look up its value
421
+ if (defaultIdentifier && variableDeclarations[defaultIdentifier]) {
422
+ exports["default"] = parseExportValueExpression(
423
+ variableDeclarations[defaultIdentifier],
424
+ );
425
+ }
388
426
 
389
427
  return exports;
390
428
  } catch (error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "next-yak",
3
- "version": "5.6.0",
3
+ "version": "5.6.1",
4
4
  "type": "module",
5
5
  "types": "./dist/",
6
6
  "sideEffects": false,
@@ -65,7 +65,7 @@
65
65
  "dependencies": {
66
66
  "@babel/parser": "7.27.1",
67
67
  "@babel/traverse": "7.27.1",
68
- "yak-swc": "5.6.0"
68
+ "yak-swc": "5.6.1"
69
69
  },
70
70
  "devDependencies": {
71
71
  "@testing-library/jest-dom": "6.6.3",