@soda-gql/metro-plugin 0.11.9 → 0.11.11

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.
package/dist/index.cjs CHANGED
@@ -13,25 +13,27 @@ const WRAPPER_FILE = "metro-transformer-wrapper.js";
13
13
  * Generate a deterministic hash for cache key.
14
14
  * Includes version prefix for cache invalidation on plugin updates.
15
15
  */
16
- function generateCacheKey(upstreamPath) {
16
+ function generateCacheKey(upstreamPath, configPath) {
17
17
  const hash = (0, node_crypto.createHash)("md5");
18
- hash.update("@soda-gql/metro-plugin:wrapper:v1");
18
+ hash.update("@soda-gql/metro-plugin:wrapper:v2");
19
19
  hash.update(upstreamPath);
20
+ hash.update(configPath ?? "");
20
21
  return hash.digest("hex").slice(0, 12);
21
22
  }
22
23
  /**
23
24
  * Generate wrapper transformer content.
24
25
  * The generated file imports soda-gql transformer factory and creates
25
- * a transformer instance with the hardcoded upstream path.
26
+ * a transformer instance with the hardcoded upstream path and config path.
26
27
  */
27
- function generateWrapperContent(upstreamPath) {
28
+ function generateWrapperContent(upstreamPath, configPath) {
28
29
  return `// Generated by @soda-gql/metro-plugin
29
30
  // DO NOT EDIT - This file is auto-generated
30
31
  // Upstream: ${upstreamPath}
32
+ // ConfigPath: ${configPath ?? "(default)"}
31
33
 
32
34
  const { createTransformerWithUpstream } = require("@soda-gql/metro-plugin/transformer");
33
35
 
34
- const transformer = createTransformerWithUpstream(${JSON.stringify(upstreamPath)});
36
+ const transformer = createTransformerWithUpstream(${JSON.stringify(upstreamPath)}, ${JSON.stringify(configPath)});
35
37
 
36
38
  module.exports = transformer;
37
39
  module.exports.transform = transformer.transform;
@@ -42,17 +44,17 @@ module.exports.getCacheKey = transformer.getCacheKey;
42
44
  * Get or create wrapper transformer file.
43
45
  * Returns the absolute path to the wrapper file.
44
46
  *
45
- * The wrapper file is cached based on the upstream transformer path.
47
+ * The wrapper file is cached based on the upstream transformer path and config path.
46
48
  * If the file already exists with the same content, it is reused.
47
49
  *
48
50
  * @param options - Wrapper generator options
49
51
  * @returns Absolute path to the wrapper transformer file
50
52
  */
51
53
  function ensureWrapperTransformer(options) {
52
- const { upstreamTransformerPath, projectRoot } = options;
54
+ const { upstreamTransformerPath, projectRoot, configPath } = options;
53
55
  const cacheDir = (0, node_path.join)(projectRoot, CACHE_DIR);
54
- const wrapperPath = (0, node_path.join)(cacheDir, `${generateCacheKey(upstreamTransformerPath)}-${WRAPPER_FILE}`);
55
- const expectedContent = generateWrapperContent(upstreamTransformerPath);
56
+ const wrapperPath = (0, node_path.join)(cacheDir, `${generateCacheKey(upstreamTransformerPath, configPath)}-${WRAPPER_FILE}`);
57
+ const expectedContent = generateWrapperContent(upstreamTransformerPath, configPath);
56
58
  if ((0, node_fs.existsSync)(wrapperPath)) try {
57
59
  if ((0, node_fs.readFileSync)(wrapperPath, "utf-8") === expectedContent) return wrapperPath;
58
60
  } catch {}
@@ -122,18 +124,18 @@ function withSodaGql(config, options = {}) {
122
124
  if (options.transformer) (0, __soda_gql_builder_plugin_support.setSharedTransformerType)(stateKey, options.transformer);
123
125
  const upstreamTransformer = options.upstreamTransformer ?? config.transformer?.babelTransformerPath;
124
126
  let transformerPath;
125
- if (upstreamTransformer) {
126
- let resolvedUpstream;
127
- try {
128
- resolvedUpstream = require.resolve(upstreamTransformer, { paths: [process.cwd()] });
129
- } catch {
130
- resolvedUpstream = upstreamTransformer;
131
- }
132
- transformerPath = ensureWrapperTransformer({
133
- upstreamTransformerPath: resolvedUpstream,
134
- projectRoot: process.cwd()
135
- });
136
- } else transformerPath = require.resolve("@soda-gql/metro-plugin/transformer");
127
+ let resolvedUpstream;
128
+ if (upstreamTransformer) try {
129
+ resolvedUpstream = require.resolve(upstreamTransformer, { paths: [process.cwd()] });
130
+ } catch {
131
+ resolvedUpstream = upstreamTransformer;
132
+ }
133
+ if (resolvedUpstream || options.configPath) transformerPath = ensureWrapperTransformer({
134
+ upstreamTransformerPath: resolvedUpstream ?? require.resolve("@soda-gql/metro-plugin/transformer"),
135
+ projectRoot: process.cwd(),
136
+ configPath: options.configPath
137
+ });
138
+ else transformerPath = require.resolve("@soda-gql/metro-plugin/transformer");
137
139
  return {
138
140
  ...config,
139
141
  transformer: {
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["transformerPath: string","resolvedUpstream: string"],"sources":["../src/wrapper-generator.ts","../src/index.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\n/** Cache directory location relative to project root */\nconst CACHE_DIR = \"node_modules/.cache/soda-gql\";\n\n/** Wrapper file name suffix */\nconst WRAPPER_FILE = \"metro-transformer-wrapper.js\";\n\n/**\n * Options for generating wrapper transformer.\n */\nexport type WrapperGeneratorOptions = {\n /** Absolute path to the upstream transformer to chain */\n readonly upstreamTransformerPath: string;\n /** Absolute path to the project root */\n readonly projectRoot: string;\n};\n\n/**\n * Generate a deterministic hash for cache key.\n * Includes version prefix for cache invalidation on plugin updates.\n */\nexport function generateCacheKey(upstreamPath: string): string {\n const hash = createHash(\"md5\");\n hash.update(\"@soda-gql/metro-plugin:wrapper:v1\");\n hash.update(upstreamPath);\n return hash.digest(\"hex\").slice(0, 12);\n}\n\n/**\n * Generate wrapper transformer content.\n * The generated file imports soda-gql transformer factory and creates\n * a transformer instance with the hardcoded upstream path.\n */\nexport function generateWrapperContent(upstreamPath: string): string {\n return `// Generated by @soda-gql/metro-plugin\n// DO NOT EDIT - This file is auto-generated\n// Upstream: ${upstreamPath}\n\nconst { createTransformerWithUpstream } = require(\"@soda-gql/metro-plugin/transformer\");\n\nconst transformer = createTransformerWithUpstream(${JSON.stringify(upstreamPath)});\n\nmodule.exports = transformer;\nmodule.exports.transform = transformer.transform;\nmodule.exports.getCacheKey = transformer.getCacheKey;\n`;\n}\n\n/**\n * Get or create wrapper transformer file.\n * Returns the absolute path to the wrapper file.\n *\n * The wrapper file is cached based on the upstream transformer path.\n * If the file already exists with the same content, it is reused.\n *\n * @param options - Wrapper generator options\n * @returns Absolute path to the wrapper transformer file\n */\nexport function ensureWrapperTransformer(options: WrapperGeneratorOptions): string {\n const { upstreamTransformerPath, projectRoot } = options;\n\n const cacheDir = join(projectRoot, CACHE_DIR);\n const cacheKey = generateCacheKey(upstreamTransformerPath);\n const wrapperPath = join(cacheDir, `${cacheKey}-${WRAPPER_FILE}`);\n\n // Generate expected content\n const expectedContent = generateWrapperContent(upstreamTransformerPath);\n\n // Check if wrapper needs regeneration\n if (existsSync(wrapperPath)) {\n try {\n const existingContent = readFileSync(wrapperPath, \"utf-8\");\n if (existingContent === expectedContent) {\n return wrapperPath;\n }\n } catch {\n // File exists but couldn't be read, regenerate\n }\n }\n\n // Create cache directory if it doesn't exist\n mkdirSync(cacheDir, { recursive: true });\n\n // Write wrapper file\n writeFileSync(wrapperPath, expectedContent, \"utf-8\");\n\n return wrapperPath;\n}\n","import { getStateKey, setSharedTransformerType } from \"@soda-gql/builder/plugin-support\";\nimport type { MetroConfig, MetroPluginOptions } from \"./types\";\nimport { ensureWrapperTransformer } from \"./wrapper-generator\";\n\n// Re-export shared state utilities for advanced usage\nexport { getSharedArtifact, getSharedState, getStateKey } from \"@soda-gql/builder/plugin-support\";\nexport type {\n MetroConfig,\n MetroPluginOptions,\n MetroTransformer,\n MetroTransformParams,\n MetroTransformResult,\n TransformerType,\n} from \"./types\";\n\n/**\n * Wrap Metro configuration with soda-gql support.\n *\n * This function modifies the Metro configuration to use the soda-gql\n * transformer, which applies GraphQL code transformations at build time.\n *\n * If the config already has a custom `babelTransformerPath` set (e.g., from\n * react-native-svg-transformer), soda-gql will automatically chain with it.\n *\n * @example\n * ```typescript\n * // Expo project (metro.config.js)\n * const { getDefaultConfig } = require(\"expo/metro-config\");\n * const { withSodaGql } = require(\"@soda-gql/metro-plugin\");\n *\n * const config = getDefaultConfig(__dirname);\n * module.exports = withSodaGql(config);\n * ```\n *\n * @example\n * ```typescript\n * // React Native bare project (metro.config.js)\n * const { getDefaultConfig, mergeConfig } = require(\"@react-native/metro-config\");\n * const { withSodaGql } = require(\"@soda-gql/metro-plugin\");\n *\n * const config = getDefaultConfig(__dirname);\n * module.exports = withSodaGql(config);\n * ```\n *\n * @example\n * ```typescript\n * // Chaining with another transformer (e.g., react-native-svg-transformer)\n * // The existing babelTransformerPath is automatically detected and chained.\n * const { getDefaultConfig } = require(\"expo/metro-config\");\n * const { withSodaGql } = require(\"@soda-gql/metro-plugin\");\n *\n * const config = getDefaultConfig(__dirname);\n * config.transformer.babelTransformerPath = require.resolve(\"react-native-svg-transformer\");\n * module.exports = withSodaGql(config);\n * ```\n *\n * @example\n * ```typescript\n * // Explicitly specifying upstream transformer\n * const config = getDefaultConfig(__dirname);\n * module.exports = withSodaGql(config, {\n * upstreamTransformer: require.resolve(\"react-native-svg-transformer\"),\n * });\n * ```\n *\n * @param config - The Metro configuration to wrap\n * @param options - Optional plugin configuration\n * @returns Modified Metro configuration with soda-gql transformer\n */\nexport function withSodaGql<T extends MetroConfig>(config: T, options: MetroPluginOptions = {}): T {\n // Store transformer type in shared state for the transformer module to read\n const stateKey = getStateKey(options.configPath);\n if (options.transformer) {\n setSharedTransformerType(stateKey, options.transformer);\n }\n\n // Determine upstream transformer path:\n // 1. Explicit option takes precedence\n // 2. Fall back to existing babelTransformerPath from config (auto-detect)\n const upstreamTransformer = options.upstreamTransformer ?? config.transformer?.babelTransformerPath;\n\n let transformerPath: string;\n\n if (upstreamTransformer) {\n // Resolve upstream to absolute path for reliable worker loading\n let resolvedUpstream: string;\n try {\n resolvedUpstream = require.resolve(upstreamTransformer, {\n paths: [process.cwd()],\n });\n } catch {\n // If resolution fails, use the path as-is (might be an absolute path already)\n resolvedUpstream = upstreamTransformer;\n }\n\n // Generate wrapper transformer with hardcoded upstream\n transformerPath = ensureWrapperTransformer({\n upstreamTransformerPath: resolvedUpstream,\n projectRoot: process.cwd(),\n });\n } else {\n // No upstream - use main transformer directly\n transformerPath = require.resolve(\"@soda-gql/metro-plugin/transformer\");\n }\n\n return {\n ...config,\n transformer: {\n ...config.transformer,\n babelTransformerPath: transformerPath,\n },\n } as T;\n}\n"],"mappings":";;;;;;;;AAKA,MAAM,YAAY;;AAGlB,MAAM,eAAe;;;;;AAgBrB,SAAgB,iBAAiB,cAA8B;CAC7D,MAAM,mCAAkB,MAAM;AAC9B,MAAK,OAAO,oCAAoC;AAChD,MAAK,OAAO,aAAa;AACzB,QAAO,KAAK,OAAO,MAAM,CAAC,MAAM,GAAG,GAAG;;;;;;;AAQxC,SAAgB,uBAAuB,cAA8B;AACnE,QAAO;;eAEM,aAAa;;;;oDAIwB,KAAK,UAAU,aAAa,CAAC;;;;;;;;;;;;;;;;;AAkBjF,SAAgB,yBAAyB,SAA0C;CACjF,MAAM,EAAE,yBAAyB,gBAAgB;CAEjD,MAAM,+BAAgB,aAAa,UAAU;CAE7C,MAAM,kCAAmB,UAAU,GADlB,iBAAiB,wBAAwB,CACX,GAAG,eAAe;CAGjE,MAAM,kBAAkB,uBAAuB,wBAAwB;AAGvE,6BAAe,YAAY,CACzB,KAAI;AAEF,gCADqC,aAAa,QAAQ,KAClC,gBACtB,QAAO;SAEH;AAMV,wBAAU,UAAU,EAAE,WAAW,MAAM,CAAC;AAGxC,4BAAc,aAAa,iBAAiB,QAAQ;AAEpD,QAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACpBT,SAAgB,YAAmC,QAAW,UAA8B,EAAE,EAAK;CAEjG,MAAM,8DAAuB,QAAQ,WAAW;AAChD,KAAI,QAAQ,YACV,iEAAyB,UAAU,QAAQ,YAAY;CAMzD,MAAM,sBAAsB,QAAQ,uBAAuB,OAAO,aAAa;CAE/E,IAAIA;AAEJ,KAAI,qBAAqB;EAEvB,IAAIC;AACJ,MAAI;AACF,sBAAmB,QAAQ,QAAQ,qBAAqB,EACtD,OAAO,CAAC,QAAQ,KAAK,CAAC,EACvB,CAAC;UACI;AAEN,sBAAmB;;AAIrB,oBAAkB,yBAAyB;GACzC,yBAAyB;GACzB,aAAa,QAAQ,KAAK;GAC3B,CAAC;OAGF,mBAAkB,QAAQ,QAAQ,qCAAqC;AAGzE,QAAO;EACL,GAAG;EACH,aAAa;GACX,GAAG,OAAO;GACV,sBAAsB;GACvB;EACF"}
1
+ {"version":3,"file":"index.cjs","names":["transformerPath: string","resolvedUpstream: string | undefined"],"sources":["../src/wrapper-generator.ts","../src/index.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\n/** Cache directory location relative to project root */\nconst CACHE_DIR = \"node_modules/.cache/soda-gql\";\n\n/** Wrapper file name suffix */\nconst WRAPPER_FILE = \"metro-transformer-wrapper.js\";\n\n/**\n * Options for generating wrapper transformer.\n */\nexport type WrapperGeneratorOptions = {\n /** Absolute path to the upstream transformer to chain */\n readonly upstreamTransformerPath: string;\n /** Absolute path to the project root */\n readonly projectRoot: string;\n /** Path to soda-gql config file (optional) */\n readonly configPath?: string;\n};\n\n/**\n * Generate a deterministic hash for cache key.\n * Includes version prefix for cache invalidation on plugin updates.\n */\nexport function generateCacheKey(upstreamPath: string, configPath?: string): string {\n const hash = createHash(\"md5\");\n hash.update(\"@soda-gql/metro-plugin:wrapper:v2\");\n hash.update(upstreamPath);\n hash.update(configPath ?? \"\");\n return hash.digest(\"hex\").slice(0, 12);\n}\n\n/**\n * Generate wrapper transformer content.\n * The generated file imports soda-gql transformer factory and creates\n * a transformer instance with the hardcoded upstream path and config path.\n */\nexport function generateWrapperContent(upstreamPath: string, configPath?: string): string {\n return `// Generated by @soda-gql/metro-plugin\n// DO NOT EDIT - This file is auto-generated\n// Upstream: ${upstreamPath}\n// ConfigPath: ${configPath ?? \"(default)\"}\n\nconst { createTransformerWithUpstream } = require(\"@soda-gql/metro-plugin/transformer\");\n\nconst transformer = createTransformerWithUpstream(${JSON.stringify(upstreamPath)}, ${JSON.stringify(configPath)});\n\nmodule.exports = transformer;\nmodule.exports.transform = transformer.transform;\nmodule.exports.getCacheKey = transformer.getCacheKey;\n`;\n}\n\n/**\n * Get or create wrapper transformer file.\n * Returns the absolute path to the wrapper file.\n *\n * The wrapper file is cached based on the upstream transformer path and config path.\n * If the file already exists with the same content, it is reused.\n *\n * @param options - Wrapper generator options\n * @returns Absolute path to the wrapper transformer file\n */\nexport function ensureWrapperTransformer(options: WrapperGeneratorOptions): string {\n const { upstreamTransformerPath, projectRoot, configPath } = options;\n\n const cacheDir = join(projectRoot, CACHE_DIR);\n const cacheKey = generateCacheKey(upstreamTransformerPath, configPath);\n const wrapperPath = join(cacheDir, `${cacheKey}-${WRAPPER_FILE}`);\n\n // Generate expected content\n const expectedContent = generateWrapperContent(upstreamTransformerPath, configPath);\n\n // Check if wrapper needs regeneration\n if (existsSync(wrapperPath)) {\n try {\n const existingContent = readFileSync(wrapperPath, \"utf-8\");\n if (existingContent === expectedContent) {\n return wrapperPath;\n }\n } catch {\n // File exists but couldn't be read, regenerate\n }\n }\n\n // Create cache directory if it doesn't exist\n mkdirSync(cacheDir, { recursive: true });\n\n // Write wrapper file\n writeFileSync(wrapperPath, expectedContent, \"utf-8\");\n\n return wrapperPath;\n}\n","import { getStateKey, setSharedTransformerType } from \"@soda-gql/builder/plugin-support\";\nimport type { MetroConfig, MetroPluginOptions } from \"./types\";\nimport { ensureWrapperTransformer } from \"./wrapper-generator\";\n\n// Re-export shared state utilities for advanced usage\nexport { getSharedArtifact, getSharedState, getStateKey } from \"@soda-gql/builder/plugin-support\";\nexport type {\n MetroConfig,\n MetroPluginOptions,\n MetroTransformer,\n MetroTransformParams,\n MetroTransformResult,\n TransformerType,\n} from \"./types\";\n\n/**\n * Wrap Metro configuration with soda-gql support.\n *\n * This function modifies the Metro configuration to use the soda-gql\n * transformer, which applies GraphQL code transformations at build time.\n *\n * If the config already has a custom `babelTransformerPath` set (e.g., from\n * react-native-svg-transformer), soda-gql will automatically chain with it.\n *\n * @example\n * ```typescript\n * // Expo project (metro.config.js)\n * const { getDefaultConfig } = require(\"expo/metro-config\");\n * const { withSodaGql } = require(\"@soda-gql/metro-plugin\");\n *\n * const config = getDefaultConfig(__dirname);\n * module.exports = withSodaGql(config);\n * ```\n *\n * @example\n * ```typescript\n * // React Native bare project (metro.config.js)\n * const { getDefaultConfig, mergeConfig } = require(\"@react-native/metro-config\");\n * const { withSodaGql } = require(\"@soda-gql/metro-plugin\");\n *\n * const config = getDefaultConfig(__dirname);\n * module.exports = withSodaGql(config);\n * ```\n *\n * @example\n * ```typescript\n * // Chaining with another transformer (e.g., react-native-svg-transformer)\n * // The existing babelTransformerPath is automatically detected and chained.\n * const { getDefaultConfig } = require(\"expo/metro-config\");\n * const { withSodaGql } = require(\"@soda-gql/metro-plugin\");\n *\n * const config = getDefaultConfig(__dirname);\n * config.transformer.babelTransformerPath = require.resolve(\"react-native-svg-transformer\");\n * module.exports = withSodaGql(config);\n * ```\n *\n * @example\n * ```typescript\n * // Explicitly specifying upstream transformer\n * const config = getDefaultConfig(__dirname);\n * module.exports = withSodaGql(config, {\n * upstreamTransformer: require.resolve(\"react-native-svg-transformer\"),\n * });\n * ```\n *\n * @param config - The Metro configuration to wrap\n * @param options - Optional plugin configuration\n * @returns Modified Metro configuration with soda-gql transformer\n */\nexport function withSodaGql<T extends MetroConfig>(config: T, options: MetroPluginOptions = {}): T {\n // Store transformer type in shared state for the transformer module to read\n const stateKey = getStateKey(options.configPath);\n if (options.transformer) {\n setSharedTransformerType(stateKey, options.transformer);\n }\n\n // Determine upstream transformer path:\n // 1. Explicit option takes precedence\n // 2. Fall back to existing babelTransformerPath from config (auto-detect)\n const upstreamTransformer = options.upstreamTransformer ?? config.transformer?.babelTransformerPath;\n\n let transformerPath: string;\n\n // Resolve upstream to absolute path for reliable worker loading\n let resolvedUpstream: string | undefined;\n if (upstreamTransformer) {\n try {\n resolvedUpstream = require.resolve(upstreamTransformer, {\n paths: [process.cwd()],\n });\n } catch {\n // If resolution fails, use the path as-is (might be an absolute path already)\n resolvedUpstream = upstreamTransformer;\n }\n }\n\n // Always generate wrapper to embed configPath (and optionally upstream)\n if (resolvedUpstream || options.configPath) {\n transformerPath = ensureWrapperTransformer({\n upstreamTransformerPath: resolvedUpstream ?? require.resolve(\"@soda-gql/metro-plugin/transformer\"),\n projectRoot: process.cwd(),\n configPath: options.configPath,\n });\n } else {\n // No upstream and no configPath - use main transformer directly\n transformerPath = require.resolve(\"@soda-gql/metro-plugin/transformer\");\n }\n\n return {\n ...config,\n transformer: {\n ...config.transformer,\n babelTransformerPath: transformerPath,\n },\n } as T;\n}\n"],"mappings":";;;;;;;;AAKA,MAAM,YAAY;;AAGlB,MAAM,eAAe;;;;;AAkBrB,SAAgB,iBAAiB,cAAsB,YAA6B;CAClF,MAAM,mCAAkB,MAAM;AAC9B,MAAK,OAAO,oCAAoC;AAChD,MAAK,OAAO,aAAa;AACzB,MAAK,OAAO,cAAc,GAAG;AAC7B,QAAO,KAAK,OAAO,MAAM,CAAC,MAAM,GAAG,GAAG;;;;;;;AAQxC,SAAgB,uBAAuB,cAAsB,YAA6B;AACxF,QAAO;;eAEM,aAAa;iBACX,cAAc,YAAY;;;;oDAIS,KAAK,UAAU,aAAa,CAAC,IAAI,KAAK,UAAU,WAAW,CAAC;;;;;;;;;;;;;;;;;AAkBhH,SAAgB,yBAAyB,SAA0C;CACjF,MAAM,EAAE,yBAAyB,aAAa,eAAe;CAE7D,MAAM,+BAAgB,aAAa,UAAU;CAE7C,MAAM,kCAAmB,UAAU,GADlB,iBAAiB,yBAAyB,WAAW,CACvB,GAAG,eAAe;CAGjE,MAAM,kBAAkB,uBAAuB,yBAAyB,WAAW;AAGnF,6BAAe,YAAY,CACzB,KAAI;AAEF,gCADqC,aAAa,QAAQ,KAClC,gBACtB,QAAO;SAEH;AAMV,wBAAU,UAAU,EAAE,WAAW,MAAM,CAAC;AAGxC,4BAAc,aAAa,iBAAiB,QAAQ;AAEpD,QAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACxBT,SAAgB,YAAmC,QAAW,UAA8B,EAAE,EAAK;CAEjG,MAAM,8DAAuB,QAAQ,WAAW;AAChD,KAAI,QAAQ,YACV,iEAAyB,UAAU,QAAQ,YAAY;CAMzD,MAAM,sBAAsB,QAAQ,uBAAuB,OAAO,aAAa;CAE/E,IAAIA;CAGJ,IAAIC;AACJ,KAAI,oBACF,KAAI;AACF,qBAAmB,QAAQ,QAAQ,qBAAqB,EACtD,OAAO,CAAC,QAAQ,KAAK,CAAC,EACvB,CAAC;SACI;AAEN,qBAAmB;;AAKvB,KAAI,oBAAoB,QAAQ,WAC9B,mBAAkB,yBAAyB;EACzC,yBAAyB,oBAAoB,QAAQ,QAAQ,qCAAqC;EAClG,aAAa,QAAQ,KAAK;EAC1B,YAAY,QAAQ;EACrB,CAAC;KAGF,mBAAkB,QAAQ,QAAQ,qCAAqC;AAGzE,QAAO;EACL,GAAG;EACH,aAAa;GACX,GAAG,OAAO;GACV,sBAAsB;GACvB;EACF"}
package/dist/index.mjs CHANGED
@@ -13,25 +13,27 @@ const WRAPPER_FILE = "metro-transformer-wrapper.js";
13
13
  * Generate a deterministic hash for cache key.
14
14
  * Includes version prefix for cache invalidation on plugin updates.
15
15
  */
16
- function generateCacheKey(upstreamPath) {
16
+ function generateCacheKey(upstreamPath, configPath) {
17
17
  const hash = createHash("md5");
18
- hash.update("@soda-gql/metro-plugin:wrapper:v1");
18
+ hash.update("@soda-gql/metro-plugin:wrapper:v2");
19
19
  hash.update(upstreamPath);
20
+ hash.update(configPath ?? "");
20
21
  return hash.digest("hex").slice(0, 12);
21
22
  }
22
23
  /**
23
24
  * Generate wrapper transformer content.
24
25
  * The generated file imports soda-gql transformer factory and creates
25
- * a transformer instance with the hardcoded upstream path.
26
+ * a transformer instance with the hardcoded upstream path and config path.
26
27
  */
27
- function generateWrapperContent(upstreamPath) {
28
+ function generateWrapperContent(upstreamPath, configPath) {
28
29
  return `// Generated by @soda-gql/metro-plugin
29
30
  // DO NOT EDIT - This file is auto-generated
30
31
  // Upstream: ${upstreamPath}
32
+ // ConfigPath: ${configPath ?? "(default)"}
31
33
 
32
34
  const { createTransformerWithUpstream } = require("@soda-gql/metro-plugin/transformer");
33
35
 
34
- const transformer = createTransformerWithUpstream(${JSON.stringify(upstreamPath)});
36
+ const transformer = createTransformerWithUpstream(${JSON.stringify(upstreamPath)}, ${JSON.stringify(configPath)});
35
37
 
36
38
  module.exports = transformer;
37
39
  module.exports.transform = transformer.transform;
@@ -42,17 +44,17 @@ module.exports.getCacheKey = transformer.getCacheKey;
42
44
  * Get or create wrapper transformer file.
43
45
  * Returns the absolute path to the wrapper file.
44
46
  *
45
- * The wrapper file is cached based on the upstream transformer path.
47
+ * The wrapper file is cached based on the upstream transformer path and config path.
46
48
  * If the file already exists with the same content, it is reused.
47
49
  *
48
50
  * @param options - Wrapper generator options
49
51
  * @returns Absolute path to the wrapper transformer file
50
52
  */
51
53
  function ensureWrapperTransformer(options) {
52
- const { upstreamTransformerPath, projectRoot } = options;
54
+ const { upstreamTransformerPath, projectRoot, configPath } = options;
53
55
  const cacheDir = join(projectRoot, CACHE_DIR);
54
- const wrapperPath = join(cacheDir, `${generateCacheKey(upstreamTransformerPath)}-${WRAPPER_FILE}`);
55
- const expectedContent = generateWrapperContent(upstreamTransformerPath);
56
+ const wrapperPath = join(cacheDir, `${generateCacheKey(upstreamTransformerPath, configPath)}-${WRAPPER_FILE}`);
57
+ const expectedContent = generateWrapperContent(upstreamTransformerPath, configPath);
56
58
  if (existsSync(wrapperPath)) try {
57
59
  if (readFileSync(wrapperPath, "utf-8") === expectedContent) return wrapperPath;
58
60
  } catch {}
@@ -122,18 +124,18 @@ function withSodaGql(config, options = {}) {
122
124
  if (options.transformer) setSharedTransformerType(stateKey, options.transformer);
123
125
  const upstreamTransformer = options.upstreamTransformer ?? config.transformer?.babelTransformerPath;
124
126
  let transformerPath;
125
- if (upstreamTransformer) {
126
- let resolvedUpstream;
127
- try {
128
- resolvedUpstream = __require.resolve(upstreamTransformer, { paths: [process.cwd()] });
129
- } catch {
130
- resolvedUpstream = upstreamTransformer;
131
- }
132
- transformerPath = ensureWrapperTransformer({
133
- upstreamTransformerPath: resolvedUpstream,
134
- projectRoot: process.cwd()
135
- });
136
- } else transformerPath = __require.resolve("@soda-gql/metro-plugin/transformer");
127
+ let resolvedUpstream;
128
+ if (upstreamTransformer) try {
129
+ resolvedUpstream = __require.resolve(upstreamTransformer, { paths: [process.cwd()] });
130
+ } catch {
131
+ resolvedUpstream = upstreamTransformer;
132
+ }
133
+ if (resolvedUpstream || options.configPath) transformerPath = ensureWrapperTransformer({
134
+ upstreamTransformerPath: resolvedUpstream ?? __require.resolve("@soda-gql/metro-plugin/transformer"),
135
+ projectRoot: process.cwd(),
136
+ configPath: options.configPath
137
+ });
138
+ else transformerPath = __require.resolve("@soda-gql/metro-plugin/transformer");
137
139
  return {
138
140
  ...config,
139
141
  transformer: {
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["getStateKey","transformerPath: string","resolvedUpstream: string"],"sources":["../src/wrapper-generator.ts","../src/index.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\n/** Cache directory location relative to project root */\nconst CACHE_DIR = \"node_modules/.cache/soda-gql\";\n\n/** Wrapper file name suffix */\nconst WRAPPER_FILE = \"metro-transformer-wrapper.js\";\n\n/**\n * Options for generating wrapper transformer.\n */\nexport type WrapperGeneratorOptions = {\n /** Absolute path to the upstream transformer to chain */\n readonly upstreamTransformerPath: string;\n /** Absolute path to the project root */\n readonly projectRoot: string;\n};\n\n/**\n * Generate a deterministic hash for cache key.\n * Includes version prefix for cache invalidation on plugin updates.\n */\nexport function generateCacheKey(upstreamPath: string): string {\n const hash = createHash(\"md5\");\n hash.update(\"@soda-gql/metro-plugin:wrapper:v1\");\n hash.update(upstreamPath);\n return hash.digest(\"hex\").slice(0, 12);\n}\n\n/**\n * Generate wrapper transformer content.\n * The generated file imports soda-gql transformer factory and creates\n * a transformer instance with the hardcoded upstream path.\n */\nexport function generateWrapperContent(upstreamPath: string): string {\n return `// Generated by @soda-gql/metro-plugin\n// DO NOT EDIT - This file is auto-generated\n// Upstream: ${upstreamPath}\n\nconst { createTransformerWithUpstream } = require(\"@soda-gql/metro-plugin/transformer\");\n\nconst transformer = createTransformerWithUpstream(${JSON.stringify(upstreamPath)});\n\nmodule.exports = transformer;\nmodule.exports.transform = transformer.transform;\nmodule.exports.getCacheKey = transformer.getCacheKey;\n`;\n}\n\n/**\n * Get or create wrapper transformer file.\n * Returns the absolute path to the wrapper file.\n *\n * The wrapper file is cached based on the upstream transformer path.\n * If the file already exists with the same content, it is reused.\n *\n * @param options - Wrapper generator options\n * @returns Absolute path to the wrapper transformer file\n */\nexport function ensureWrapperTransformer(options: WrapperGeneratorOptions): string {\n const { upstreamTransformerPath, projectRoot } = options;\n\n const cacheDir = join(projectRoot, CACHE_DIR);\n const cacheKey = generateCacheKey(upstreamTransformerPath);\n const wrapperPath = join(cacheDir, `${cacheKey}-${WRAPPER_FILE}`);\n\n // Generate expected content\n const expectedContent = generateWrapperContent(upstreamTransformerPath);\n\n // Check if wrapper needs regeneration\n if (existsSync(wrapperPath)) {\n try {\n const existingContent = readFileSync(wrapperPath, \"utf-8\");\n if (existingContent === expectedContent) {\n return wrapperPath;\n }\n } catch {\n // File exists but couldn't be read, regenerate\n }\n }\n\n // Create cache directory if it doesn't exist\n mkdirSync(cacheDir, { recursive: true });\n\n // Write wrapper file\n writeFileSync(wrapperPath, expectedContent, \"utf-8\");\n\n return wrapperPath;\n}\n","import { getStateKey, setSharedTransformerType } from \"@soda-gql/builder/plugin-support\";\nimport type { MetroConfig, MetroPluginOptions } from \"./types\";\nimport { ensureWrapperTransformer } from \"./wrapper-generator\";\n\n// Re-export shared state utilities for advanced usage\nexport { getSharedArtifact, getSharedState, getStateKey } from \"@soda-gql/builder/plugin-support\";\nexport type {\n MetroConfig,\n MetroPluginOptions,\n MetroTransformer,\n MetroTransformParams,\n MetroTransformResult,\n TransformerType,\n} from \"./types\";\n\n/**\n * Wrap Metro configuration with soda-gql support.\n *\n * This function modifies the Metro configuration to use the soda-gql\n * transformer, which applies GraphQL code transformations at build time.\n *\n * If the config already has a custom `babelTransformerPath` set (e.g., from\n * react-native-svg-transformer), soda-gql will automatically chain with it.\n *\n * @example\n * ```typescript\n * // Expo project (metro.config.js)\n * const { getDefaultConfig } = require(\"expo/metro-config\");\n * const { withSodaGql } = require(\"@soda-gql/metro-plugin\");\n *\n * const config = getDefaultConfig(__dirname);\n * module.exports = withSodaGql(config);\n * ```\n *\n * @example\n * ```typescript\n * // React Native bare project (metro.config.js)\n * const { getDefaultConfig, mergeConfig } = require(\"@react-native/metro-config\");\n * const { withSodaGql } = require(\"@soda-gql/metro-plugin\");\n *\n * const config = getDefaultConfig(__dirname);\n * module.exports = withSodaGql(config);\n * ```\n *\n * @example\n * ```typescript\n * // Chaining with another transformer (e.g., react-native-svg-transformer)\n * // The existing babelTransformerPath is automatically detected and chained.\n * const { getDefaultConfig } = require(\"expo/metro-config\");\n * const { withSodaGql } = require(\"@soda-gql/metro-plugin\");\n *\n * const config = getDefaultConfig(__dirname);\n * config.transformer.babelTransformerPath = require.resolve(\"react-native-svg-transformer\");\n * module.exports = withSodaGql(config);\n * ```\n *\n * @example\n * ```typescript\n * // Explicitly specifying upstream transformer\n * const config = getDefaultConfig(__dirname);\n * module.exports = withSodaGql(config, {\n * upstreamTransformer: require.resolve(\"react-native-svg-transformer\"),\n * });\n * ```\n *\n * @param config - The Metro configuration to wrap\n * @param options - Optional plugin configuration\n * @returns Modified Metro configuration with soda-gql transformer\n */\nexport function withSodaGql<T extends MetroConfig>(config: T, options: MetroPluginOptions = {}): T {\n // Store transformer type in shared state for the transformer module to read\n const stateKey = getStateKey(options.configPath);\n if (options.transformer) {\n setSharedTransformerType(stateKey, options.transformer);\n }\n\n // Determine upstream transformer path:\n // 1. Explicit option takes precedence\n // 2. Fall back to existing babelTransformerPath from config (auto-detect)\n const upstreamTransformer = options.upstreamTransformer ?? config.transformer?.babelTransformerPath;\n\n let transformerPath: string;\n\n if (upstreamTransformer) {\n // Resolve upstream to absolute path for reliable worker loading\n let resolvedUpstream: string;\n try {\n resolvedUpstream = require.resolve(upstreamTransformer, {\n paths: [process.cwd()],\n });\n } catch {\n // If resolution fails, use the path as-is (might be an absolute path already)\n resolvedUpstream = upstreamTransformer;\n }\n\n // Generate wrapper transformer with hardcoded upstream\n transformerPath = ensureWrapperTransformer({\n upstreamTransformerPath: resolvedUpstream,\n projectRoot: process.cwd(),\n });\n } else {\n // No upstream - use main transformer directly\n transformerPath = require.resolve(\"@soda-gql/metro-plugin/transformer\");\n }\n\n return {\n ...config,\n transformer: {\n ...config.transformer,\n babelTransformerPath: transformerPath,\n },\n } as T;\n}\n"],"mappings":";;;;;;;;AAKA,MAAM,YAAY;;AAGlB,MAAM,eAAe;;;;;AAgBrB,SAAgB,iBAAiB,cAA8B;CAC7D,MAAM,OAAO,WAAW,MAAM;AAC9B,MAAK,OAAO,oCAAoC;AAChD,MAAK,OAAO,aAAa;AACzB,QAAO,KAAK,OAAO,MAAM,CAAC,MAAM,GAAG,GAAG;;;;;;;AAQxC,SAAgB,uBAAuB,cAA8B;AACnE,QAAO;;eAEM,aAAa;;;;oDAIwB,KAAK,UAAU,aAAa,CAAC;;;;;;;;;;;;;;;;;AAkBjF,SAAgB,yBAAyB,SAA0C;CACjF,MAAM,EAAE,yBAAyB,gBAAgB;CAEjD,MAAM,WAAW,KAAK,aAAa,UAAU;CAE7C,MAAM,cAAc,KAAK,UAAU,GADlB,iBAAiB,wBAAwB,CACX,GAAG,eAAe;CAGjE,MAAM,kBAAkB,uBAAuB,wBAAwB;AAGvE,KAAI,WAAW,YAAY,CACzB,KAAI;AAEF,MADwB,aAAa,aAAa,QAAQ,KAClC,gBACtB,QAAO;SAEH;AAMV,WAAU,UAAU,EAAE,WAAW,MAAM,CAAC;AAGxC,eAAc,aAAa,iBAAiB,QAAQ;AAEpD,QAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACpBT,SAAgB,YAAmC,QAAW,UAA8B,EAAE,EAAK;CAEjG,MAAM,WAAWA,cAAY,QAAQ,WAAW;AAChD,KAAI,QAAQ,YACV,0BAAyB,UAAU,QAAQ,YAAY;CAMzD,MAAM,sBAAsB,QAAQ,uBAAuB,OAAO,aAAa;CAE/E,IAAIC;AAEJ,KAAI,qBAAqB;EAEvB,IAAIC;AACJ,MAAI;AACF,gCAA2B,QAAQ,qBAAqB,EACtD,OAAO,CAAC,QAAQ,KAAK,CAAC,EACvB,CAAC;UACI;AAEN,sBAAmB;;AAIrB,oBAAkB,yBAAyB;GACzC,yBAAyB;GACzB,aAAa,QAAQ,KAAK;GAC3B,CAAC;OAGF,6BAA0B,QAAQ,qCAAqC;AAGzE,QAAO;EACL,GAAG;EACH,aAAa;GACX,GAAG,OAAO;GACV,sBAAsB;GACvB;EACF"}
1
+ {"version":3,"file":"index.mjs","names":["getStateKey","transformerPath: string","resolvedUpstream: string | undefined"],"sources":["../src/wrapper-generator.ts","../src/index.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\n/** Cache directory location relative to project root */\nconst CACHE_DIR = \"node_modules/.cache/soda-gql\";\n\n/** Wrapper file name suffix */\nconst WRAPPER_FILE = \"metro-transformer-wrapper.js\";\n\n/**\n * Options for generating wrapper transformer.\n */\nexport type WrapperGeneratorOptions = {\n /** Absolute path to the upstream transformer to chain */\n readonly upstreamTransformerPath: string;\n /** Absolute path to the project root */\n readonly projectRoot: string;\n /** Path to soda-gql config file (optional) */\n readonly configPath?: string;\n};\n\n/**\n * Generate a deterministic hash for cache key.\n * Includes version prefix for cache invalidation on plugin updates.\n */\nexport function generateCacheKey(upstreamPath: string, configPath?: string): string {\n const hash = createHash(\"md5\");\n hash.update(\"@soda-gql/metro-plugin:wrapper:v2\");\n hash.update(upstreamPath);\n hash.update(configPath ?? \"\");\n return hash.digest(\"hex\").slice(0, 12);\n}\n\n/**\n * Generate wrapper transformer content.\n * The generated file imports soda-gql transformer factory and creates\n * a transformer instance with the hardcoded upstream path and config path.\n */\nexport function generateWrapperContent(upstreamPath: string, configPath?: string): string {\n return `// Generated by @soda-gql/metro-plugin\n// DO NOT EDIT - This file is auto-generated\n// Upstream: ${upstreamPath}\n// ConfigPath: ${configPath ?? \"(default)\"}\n\nconst { createTransformerWithUpstream } = require(\"@soda-gql/metro-plugin/transformer\");\n\nconst transformer = createTransformerWithUpstream(${JSON.stringify(upstreamPath)}, ${JSON.stringify(configPath)});\n\nmodule.exports = transformer;\nmodule.exports.transform = transformer.transform;\nmodule.exports.getCacheKey = transformer.getCacheKey;\n`;\n}\n\n/**\n * Get or create wrapper transformer file.\n * Returns the absolute path to the wrapper file.\n *\n * The wrapper file is cached based on the upstream transformer path and config path.\n * If the file already exists with the same content, it is reused.\n *\n * @param options - Wrapper generator options\n * @returns Absolute path to the wrapper transformer file\n */\nexport function ensureWrapperTransformer(options: WrapperGeneratorOptions): string {\n const { upstreamTransformerPath, projectRoot, configPath } = options;\n\n const cacheDir = join(projectRoot, CACHE_DIR);\n const cacheKey = generateCacheKey(upstreamTransformerPath, configPath);\n const wrapperPath = join(cacheDir, `${cacheKey}-${WRAPPER_FILE}`);\n\n // Generate expected content\n const expectedContent = generateWrapperContent(upstreamTransformerPath, configPath);\n\n // Check if wrapper needs regeneration\n if (existsSync(wrapperPath)) {\n try {\n const existingContent = readFileSync(wrapperPath, \"utf-8\");\n if (existingContent === expectedContent) {\n return wrapperPath;\n }\n } catch {\n // File exists but couldn't be read, regenerate\n }\n }\n\n // Create cache directory if it doesn't exist\n mkdirSync(cacheDir, { recursive: true });\n\n // Write wrapper file\n writeFileSync(wrapperPath, expectedContent, \"utf-8\");\n\n return wrapperPath;\n}\n","import { getStateKey, setSharedTransformerType } from \"@soda-gql/builder/plugin-support\";\nimport type { MetroConfig, MetroPluginOptions } from \"./types\";\nimport { ensureWrapperTransformer } from \"./wrapper-generator\";\n\n// Re-export shared state utilities for advanced usage\nexport { getSharedArtifact, getSharedState, getStateKey } from \"@soda-gql/builder/plugin-support\";\nexport type {\n MetroConfig,\n MetroPluginOptions,\n MetroTransformer,\n MetroTransformParams,\n MetroTransformResult,\n TransformerType,\n} from \"./types\";\n\n/**\n * Wrap Metro configuration with soda-gql support.\n *\n * This function modifies the Metro configuration to use the soda-gql\n * transformer, which applies GraphQL code transformations at build time.\n *\n * If the config already has a custom `babelTransformerPath` set (e.g., from\n * react-native-svg-transformer), soda-gql will automatically chain with it.\n *\n * @example\n * ```typescript\n * // Expo project (metro.config.js)\n * const { getDefaultConfig } = require(\"expo/metro-config\");\n * const { withSodaGql } = require(\"@soda-gql/metro-plugin\");\n *\n * const config = getDefaultConfig(__dirname);\n * module.exports = withSodaGql(config);\n * ```\n *\n * @example\n * ```typescript\n * // React Native bare project (metro.config.js)\n * const { getDefaultConfig, mergeConfig } = require(\"@react-native/metro-config\");\n * const { withSodaGql } = require(\"@soda-gql/metro-plugin\");\n *\n * const config = getDefaultConfig(__dirname);\n * module.exports = withSodaGql(config);\n * ```\n *\n * @example\n * ```typescript\n * // Chaining with another transformer (e.g., react-native-svg-transformer)\n * // The existing babelTransformerPath is automatically detected and chained.\n * const { getDefaultConfig } = require(\"expo/metro-config\");\n * const { withSodaGql } = require(\"@soda-gql/metro-plugin\");\n *\n * const config = getDefaultConfig(__dirname);\n * config.transformer.babelTransformerPath = require.resolve(\"react-native-svg-transformer\");\n * module.exports = withSodaGql(config);\n * ```\n *\n * @example\n * ```typescript\n * // Explicitly specifying upstream transformer\n * const config = getDefaultConfig(__dirname);\n * module.exports = withSodaGql(config, {\n * upstreamTransformer: require.resolve(\"react-native-svg-transformer\"),\n * });\n * ```\n *\n * @param config - The Metro configuration to wrap\n * @param options - Optional plugin configuration\n * @returns Modified Metro configuration with soda-gql transformer\n */\nexport function withSodaGql<T extends MetroConfig>(config: T, options: MetroPluginOptions = {}): T {\n // Store transformer type in shared state for the transformer module to read\n const stateKey = getStateKey(options.configPath);\n if (options.transformer) {\n setSharedTransformerType(stateKey, options.transformer);\n }\n\n // Determine upstream transformer path:\n // 1. Explicit option takes precedence\n // 2. Fall back to existing babelTransformerPath from config (auto-detect)\n const upstreamTransformer = options.upstreamTransformer ?? config.transformer?.babelTransformerPath;\n\n let transformerPath: string;\n\n // Resolve upstream to absolute path for reliable worker loading\n let resolvedUpstream: string | undefined;\n if (upstreamTransformer) {\n try {\n resolvedUpstream = require.resolve(upstreamTransformer, {\n paths: [process.cwd()],\n });\n } catch {\n // If resolution fails, use the path as-is (might be an absolute path already)\n resolvedUpstream = upstreamTransformer;\n }\n }\n\n // Always generate wrapper to embed configPath (and optionally upstream)\n if (resolvedUpstream || options.configPath) {\n transformerPath = ensureWrapperTransformer({\n upstreamTransformerPath: resolvedUpstream ?? require.resolve(\"@soda-gql/metro-plugin/transformer\"),\n projectRoot: process.cwd(),\n configPath: options.configPath,\n });\n } else {\n // No upstream and no configPath - use main transformer directly\n transformerPath = require.resolve(\"@soda-gql/metro-plugin/transformer\");\n }\n\n return {\n ...config,\n transformer: {\n ...config.transformer,\n babelTransformerPath: transformerPath,\n },\n } as T;\n}\n"],"mappings":";;;;;;;;AAKA,MAAM,YAAY;;AAGlB,MAAM,eAAe;;;;;AAkBrB,SAAgB,iBAAiB,cAAsB,YAA6B;CAClF,MAAM,OAAO,WAAW,MAAM;AAC9B,MAAK,OAAO,oCAAoC;AAChD,MAAK,OAAO,aAAa;AACzB,MAAK,OAAO,cAAc,GAAG;AAC7B,QAAO,KAAK,OAAO,MAAM,CAAC,MAAM,GAAG,GAAG;;;;;;;AAQxC,SAAgB,uBAAuB,cAAsB,YAA6B;AACxF,QAAO;;eAEM,aAAa;iBACX,cAAc,YAAY;;;;oDAIS,KAAK,UAAU,aAAa,CAAC,IAAI,KAAK,UAAU,WAAW,CAAC;;;;;;;;;;;;;;;;;AAkBhH,SAAgB,yBAAyB,SAA0C;CACjF,MAAM,EAAE,yBAAyB,aAAa,eAAe;CAE7D,MAAM,WAAW,KAAK,aAAa,UAAU;CAE7C,MAAM,cAAc,KAAK,UAAU,GADlB,iBAAiB,yBAAyB,WAAW,CACvB,GAAG,eAAe;CAGjE,MAAM,kBAAkB,uBAAuB,yBAAyB,WAAW;AAGnF,KAAI,WAAW,YAAY,CACzB,KAAI;AAEF,MADwB,aAAa,aAAa,QAAQ,KAClC,gBACtB,QAAO;SAEH;AAMV,WAAU,UAAU,EAAE,WAAW,MAAM,CAAC;AAGxC,eAAc,aAAa,iBAAiB,QAAQ;AAEpD,QAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACxBT,SAAgB,YAAmC,QAAW,UAA8B,EAAE,EAAK;CAEjG,MAAM,WAAWA,cAAY,QAAQ,WAAW;AAChD,KAAI,QAAQ,YACV,0BAAyB,UAAU,QAAQ,YAAY;CAMzD,MAAM,sBAAsB,QAAQ,uBAAuB,OAAO,aAAa;CAE/E,IAAIC;CAGJ,IAAIC;AACJ,KAAI,oBACF,KAAI;AACF,+BAA2B,QAAQ,qBAAqB,EACtD,OAAO,CAAC,QAAQ,KAAK,CAAC,EACvB,CAAC;SACI;AAEN,qBAAmB;;AAKvB,KAAI,oBAAoB,QAAQ,WAC9B,mBAAkB,yBAAyB;EACzC,yBAAyB,8BAA4B,QAAQ,qCAAqC;EAClG,aAAa,QAAQ,KAAK;EAC1B,YAAY,QAAQ;EACrB,CAAC;KAGF,6BAA0B,QAAQ,qCAAqC;AAGzE,QAAO;EACL,GAAG;EACH,aAAa;GACX,GAAG,OAAO;GACV,sBAAsB;GACvB;EACF"}
@@ -29,6 +29,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
29
29
  let __soda_gql_builder_plugin_support = require("@soda-gql/builder/plugin-support");
30
30
  let node_crypto = require("node:crypto");
31
31
  node_crypto = __toESM(node_crypto);
32
+ let node_path = require("node:path");
32
33
  let __babel_core = require("@babel/core");
33
34
  let __soda_gql_babel_plugin = require("@soda-gql/babel/plugin");
34
35
  let __soda_gql_common = require("@soda-gql/common");
@@ -44,7 +45,7 @@ for (let i = 0; i < chars.length; i++) {
44
45
  intToChar[i] = c;
45
46
  charToInt[c] = i;
46
47
  }
47
- function decodeInteger(reader, relative) {
48
+ function decodeInteger(reader, relative$1) {
48
49
  let value = 0;
49
50
  let shift = 0;
50
51
  let integer = 0;
@@ -56,10 +57,10 @@ function decodeInteger(reader, relative) {
56
57
  const shouldNegate = value & 1;
57
58
  value >>>= 1;
58
59
  if (shouldNegate) value = -2147483648 | -value;
59
- return relative + value;
60
+ return relative$1 + value;
60
61
  }
61
- function encodeInteger(builder, num, relative) {
62
- let delta = num - relative;
62
+ function encodeInteger(builder, num, relative$1) {
63
+ let delta = num - relative$1;
63
64
  delta = delta < 0 ? -delta << 1 | 1 : delta << 1;
64
65
  do {
65
66
  let clamped = delta & 31;
@@ -856,8 +857,8 @@ let sessionInitialized = false;
856
857
  * Ensure plugin session is initialized.
857
858
  * First tries to use shared session, falls back to creating own.
858
859
  */
859
- const ensurePluginSession = () => {
860
- const stateKey = (0, __soda_gql_builder_plugin_support.getStateKey)();
860
+ const ensurePluginSession = (configPath) => {
861
+ const stateKey = (0, __soda_gql_builder_plugin_support.getStateKey)(configPath);
861
862
  const sharedSession = (0, __soda_gql_builder_plugin_support.getSharedPluginSession)(stateKey);
862
863
  if (sharedSession) return sharedSession;
863
864
  if (!sessionInitialized) {
@@ -874,8 +875,8 @@ let swcInitialized = false;
874
875
  /**
875
876
  * Initialize SWC transformer if configured.
876
877
  */
877
- const initializeSwcTransformer = async (artifact, config) => {
878
- const stateKey = (0, __soda_gql_builder_plugin_support.getStateKey)();
878
+ const initializeSwcTransformer = async (artifact, config, configPath) => {
879
+ const stateKey = (0, __soda_gql_builder_plugin_support.getStateKey)(configPath);
879
880
  const existing = (0, __soda_gql_builder_plugin_support.getSharedSwcTransformer)(stateKey);
880
881
  if (existing || swcInitialized) return existing;
881
882
  swcInitialized = true;
@@ -905,11 +906,11 @@ async function transform(params) {
905
906
  * Core transformation logic.
906
907
  * @internal
907
908
  */
908
- async function transformCore(params, getUpstream) {
909
+ async function transformCore(params, getUpstream, configPath) {
909
910
  const { src, filename, options } = params;
910
- const stateKey = (0, __soda_gql_builder_plugin_support.getStateKey)();
911
+ const stateKey = (0, __soda_gql_builder_plugin_support.getStateKey)(configPath);
911
912
  const upstream = getUpstream();
912
- const session = ensurePluginSession();
913
+ const session = ensurePluginSession(configPath);
913
914
  if (!session) return upstream.transform(params);
914
915
  let artifact = (0, __soda_gql_builder_plugin_support.getSharedArtifact)(stateKey);
915
916
  if (!artifact) {
@@ -917,9 +918,9 @@ async function transformCore(params, getUpstream) {
917
918
  if (artifact) (0, __soda_gql_builder_plugin_support.setSharedArtifact)(stateKey, artifact);
918
919
  }
919
920
  if (!artifact) return upstream.transform(params);
920
- const normalizedPath = (0, __soda_gql_common.normalizePath)(filename);
921
- if (!Object.values(artifact.elements).some((element) => (0, __soda_gql_common.normalizePath)(element.metadata.sourcePath) === normalizedPath)) return upstream.transform(params);
922
- const swcTransformer = await initializeSwcTransformer(artifact, session.config);
921
+ const relativePath = (0, __soda_gql_common.normalizePath)((0, node_path.relative)(session.config.baseDir, filename));
922
+ if (!Object.values(artifact.elements).some((element) => (0, __soda_gql_common.normalizePath)(element.metadata.sourcePath) === relativePath)) return upstream.transform(params);
923
+ const swcTransformer = await initializeSwcTransformer(artifact, session.config, configPath);
923
924
  if (swcTransformer) {
924
925
  const swcResult = swcTransformer.transform({
925
926
  sourceCode: src,
@@ -986,8 +987,8 @@ function getCacheKey() {
986
987
  * Core cache key generation logic.
987
988
  * @internal
988
989
  */
989
- function getCacheKeyCore(getUpstream, upstreamPath) {
990
- const state = (0, __soda_gql_builder_plugin_support.getSharedState)((0, __soda_gql_builder_plugin_support.getStateKey)());
990
+ function getCacheKeyCore(getUpstream, upstreamPath, configPath) {
991
+ const state = (0, __soda_gql_builder_plugin_support.getSharedState)((0, __soda_gql_builder_plugin_support.getStateKey)(configPath));
991
992
  const artifact = state.currentArtifact;
992
993
  const upstream = getUpstream();
993
994
  const hash = node_crypto.default.createHash("md5");
@@ -1003,12 +1004,13 @@ function getCacheKeyCore(getUpstream, upstreamPath) {
1003
1004
  }
1004
1005
  /**
1005
1006
  * Create a transformer with a specific upstream transformer path.
1006
- * Used by generated wrapper files to inject the upstream path at build time.
1007
+ * Used by generated wrapper files to inject the upstream path and config path at build time.
1007
1008
  *
1008
1009
  * @param upstreamPath - Absolute path to the upstream transformer module
1010
+ * @param configPath - Path to soda-gql config file (optional)
1009
1011
  * @returns MetroTransformer instance configured with the specified upstream
1010
1012
  */
1011
- function createTransformerWithUpstream(upstreamPath) {
1013
+ function createTransformerWithUpstream(upstreamPath, configPath) {
1012
1014
  let cachedUpstream = null;
1013
1015
  const getUpstream = () => {
1014
1016
  if (cachedUpstream) return cachedUpstream;
@@ -1018,8 +1020,8 @@ function createTransformerWithUpstream(upstreamPath) {
1018
1020
  return cachedUpstream;
1019
1021
  };
1020
1022
  return {
1021
- transform: (params) => transformCore(params, getUpstream),
1022
- getCacheKey: () => getCacheKeyCore(getUpstream, upstreamPath)
1023
+ transform: (params) => transformCore(params, getUpstream, configPath),
1024
+ getCacheKey: () => getCacheKeyCore(getUpstream, upstreamPath, configPath)
1023
1025
  };
1024
1026
  }
1025
1027
  /**