@soda-gql/metro-plugin 0.2.0

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/README.md ADDED
@@ -0,0 +1,165 @@
1
+ # @soda-gql/metro-plugin
2
+
3
+ Metro bundler plugin for soda-gql with support for Expo and React Native projects.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @soda-gql/metro-plugin
9
+ # or
10
+ yarn add @soda-gql/metro-plugin
11
+ # or
12
+ bun add @soda-gql/metro-plugin
13
+ ```
14
+
15
+ ## Usage
16
+
17
+ ### Expo Projects
18
+
19
+ ```javascript
20
+ // metro.config.js
21
+ const { getDefaultConfig } = require("expo/metro-config");
22
+ const { withSodaGql } = require("@soda-gql/metro-plugin");
23
+
24
+ const config = getDefaultConfig(__dirname);
25
+ module.exports = withSodaGql(config);
26
+ ```
27
+
28
+ ### React Native (bare) Projects
29
+
30
+ ```javascript
31
+ // metro.config.js
32
+ const { getDefaultConfig, mergeConfig } = require("@react-native/metro-config");
33
+ const { withSodaGql } = require("@soda-gql/metro-plugin");
34
+
35
+ const config = getDefaultConfig(__dirname);
36
+ module.exports = withSodaGql(config);
37
+ ```
38
+
39
+ ### With Options
40
+
41
+ ```javascript
42
+ // metro.config.js
43
+ const { getDefaultConfig } = require("expo/metro-config");
44
+ const { withSodaGql } = require("@soda-gql/metro-plugin");
45
+
46
+ const config = getDefaultConfig(__dirname);
47
+ module.exports = withSodaGql(config, {
48
+ // Optional: Path to soda-gql config file
49
+ configPath: "./soda-gql.config.ts",
50
+
51
+ // Optional: Enable/disable the plugin (default: true)
52
+ enabled: process.env.NODE_ENV !== "test",
53
+
54
+ // Optional: Enable debug logging (default: false)
55
+ debug: process.env.DEBUG === "true",
56
+ });
57
+ ```
58
+
59
+ ## How It Works
60
+
61
+ 1. **Transformer Wrapping**: The plugin wraps Metro's default Babel transformer.
62
+
63
+ 2. **Build-Time Transformation**: When Metro processes a file:
64
+ - Checks if the file contains soda-gql elements
65
+ - If yes, applies the soda-gql Babel transformation
66
+ - Passes the result to the upstream transformer for final processing
67
+
68
+ 3. **Cache Invalidation**: The transformer includes a `getCacheKey()` function that:
69
+ - Incorporates the artifact generation number
70
+ - Ensures Metro invalidates cache when soda-gql models change
71
+
72
+ ## Upstream Transformer Detection
73
+
74
+ The plugin automatically detects and uses the appropriate upstream transformer:
75
+
76
+ 1. **Expo**: `@expo/metro-config/babel-transformer`
77
+ 2. **React Native 0.73+**: `@react-native/metro-babel-transformer`
78
+ 3. **Legacy React Native**: `metro-react-native-babel-transformer`
79
+
80
+ ## Options
81
+
82
+ | Option | Type | Default | Description |
83
+ |--------|------|---------|-------------|
84
+ | `configPath` | `string` | `undefined` | Path to soda-gql config file |
85
+ | `enabled` | `boolean` | `true` | Enable/disable the plugin |
86
+ | `debug` | `boolean` | `false` | Enable verbose logging |
87
+
88
+ ## Watch Mode Considerations
89
+
90
+ Metro's watch mode behavior differs from webpack:
91
+
92
+ - **Cache Key Based**: When soda-gql files change, the transformer's cache key changes, triggering re-transformation of affected files.
93
+
94
+ - **Development Server**: During active development, if you modify model files and don't see changes reflected:
95
+ 1. Save the file again to trigger a rebuild
96
+ 2. If needed, restart Metro with `--reset-cache` flag
97
+
98
+ ```bash
99
+ # Expo
100
+ npx expo start --clear
101
+
102
+ # React Native
103
+ npx react-native start --reset-cache
104
+ ```
105
+
106
+ ## Chaining with Other Transformers
107
+
108
+ If you need to chain with other transformers (e.g., react-native-svg-transformer), ensure soda-gql's transformer is applied first:
109
+
110
+ ```javascript
111
+ // metro.config.js
112
+ const { getDefaultConfig } = require("expo/metro-config");
113
+ const { withSodaGql } = require("@soda-gql/metro-plugin");
114
+
115
+ const config = getDefaultConfig(__dirname);
116
+
117
+ // Apply soda-gql first
118
+ const sodaGqlConfig = withSodaGql(config);
119
+
120
+ // Then chain other transformers
121
+ module.exports = {
122
+ ...sodaGqlConfig,
123
+ transformer: {
124
+ ...sodaGqlConfig.transformer,
125
+ // Additional transformer customizations
126
+ },
127
+ };
128
+ ```
129
+
130
+ ## Troubleshooting
131
+
132
+ ### "No compatible Metro Babel transformer found"
133
+
134
+ This error occurs when none of the supported upstream transformers are installed. Ensure you have one of:
135
+
136
+ - `@expo/metro-config` (Expo projects)
137
+ - `@react-native/metro-babel-transformer` (React Native 0.73+)
138
+ - `metro-react-native-babel-transformer` (Legacy React Native)
139
+
140
+ ### Changes not reflected in development
141
+
142
+ 1. Try saving the file again
143
+ 2. Restart Metro with cache clearing:
144
+ ```bash
145
+ npx expo start --clear
146
+ # or
147
+ npx react-native start --reset-cache
148
+ ```
149
+
150
+ ### Type errors in metro.config.js
151
+
152
+ If using TypeScript for your Metro config, you may need to add type annotations:
153
+
154
+ ```typescript
155
+ // metro.config.ts
156
+ import { getDefaultConfig } from "expo/metro-config";
157
+ import { withSodaGql } from "@soda-gql/metro-plugin";
158
+
159
+ const config = getDefaultConfig(__dirname);
160
+ export default withSodaGql(config);
161
+ ```
162
+
163
+ ## License
164
+
165
+ MIT
@@ -0,0 +1,7 @@
1
+ import { createRequire } from "node:module";
2
+
3
+ //#region rolldown:runtime
4
+ var __require = /* @__PURE__ */ createRequire(import.meta.url);
5
+
6
+ //#endregion
7
+ export { __require as t };
package/dist/index.cjs ADDED
@@ -0,0 +1,78 @@
1
+ const require_transformer = require('./transformer.cjs');
2
+ let __soda_gql_plugin_common = require("@soda-gql/plugin-common");
3
+
4
+ //#region packages/metro-plugin/src/index.ts
5
+ /**
6
+ * Wrap Metro configuration with soda-gql support.
7
+ *
8
+ * This function modifies the Metro configuration to use the soda-gql
9
+ * transformer, which applies GraphQL code transformations at build time.
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * // Expo project (metro.config.js)
14
+ * const { getDefaultConfig } = require("expo/metro-config");
15
+ * const { withSodaGql } = require("@soda-gql/metro-plugin");
16
+ *
17
+ * const config = getDefaultConfig(__dirname);
18
+ * module.exports = withSodaGql(config);
19
+ * ```
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * // React Native bare project (metro.config.js)
24
+ * const { getDefaultConfig, mergeConfig } = require("@react-native/metro-config");
25
+ * const { withSodaGql } = require("@soda-gql/metro-plugin");
26
+ *
27
+ * const config = getDefaultConfig(__dirname);
28
+ * module.exports = withSodaGql(config);
29
+ * ```
30
+ *
31
+ * @example
32
+ * ```typescript
33
+ * // With options
34
+ * const config = getDefaultConfig(__dirname);
35
+ * module.exports = withSodaGql(config, {
36
+ * configPath: "./soda-gql.config.ts",
37
+ * debug: true,
38
+ * });
39
+ * ```
40
+ *
41
+ * @param config - The Metro configuration to wrap
42
+ * @param options - Optional plugin configuration
43
+ * @returns Modified Metro configuration with soda-gql transformer
44
+ */
45
+ function withSodaGql(config, options = {}) {
46
+ const transformerPath = require.resolve("@soda-gql/metro-plugin/transformer");
47
+ const stateKey = (0, __soda_gql_plugin_common.getStateKey)(options.configPath);
48
+ if (options.transformer) (0, __soda_gql_plugin_common.setSharedTransformerType)(stateKey, options.transformer);
49
+ return {
50
+ ...config,
51
+ transformer: {
52
+ ...config.transformer,
53
+ babelTransformerPath: transformerPath
54
+ }
55
+ };
56
+ }
57
+
58
+ //#endregion
59
+ Object.defineProperty(exports, 'getSharedArtifact', {
60
+ enumerable: true,
61
+ get: function () {
62
+ return __soda_gql_plugin_common.getSharedArtifact;
63
+ }
64
+ });
65
+ Object.defineProperty(exports, 'getSharedState', {
66
+ enumerable: true,
67
+ get: function () {
68
+ return __soda_gql_plugin_common.getSharedState;
69
+ }
70
+ });
71
+ Object.defineProperty(exports, 'getStateKey', {
72
+ enumerable: true,
73
+ get: function () {
74
+ return __soda_gql_plugin_common.getStateKey;
75
+ }
76
+ });
77
+ exports.withSodaGql = withSodaGql;
78
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["import { getStateKey, setSharedTransformerType } from \"@soda-gql/plugin-common\";\nimport type { MetroConfig, MetroPluginOptions } from \"./types\";\n\n// Re-export shared state utilities for advanced usage\nexport { getSharedArtifact, getSharedState, getStateKey } from \"@soda-gql/plugin-common\";\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 * @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 * // With options\n * const config = getDefaultConfig(__dirname);\n * module.exports = withSodaGql(config, {\n * configPath: \"./soda-gql.config.ts\",\n * debug: true,\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 // Use package export path to ensure correct resolution from any location\n const transformerPath = require.resolve(\"@soda-gql/metro-plugin/transformer\");\n\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 return {\n ...config,\n transformer: {\n ...config.transformer,\n babelTransformerPath: transformerPath,\n },\n } as T;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsDA,SAAgB,YAAmC,QAAW,UAA8B,EAAE,EAAK;CAEjG,MAAM,kBAAkB,QAAQ,QAAQ,qCAAqC;CAG7E,MAAM,qDAAuB,QAAQ,WAAW;AAChD,KAAI,QAAQ,YACV,wDAAyB,UAAU,QAAQ,YAAY;AAGzD,QAAO;EACL,GAAG;EACH,aAAa;GACX,GAAG,OAAO;GACV,sBAAsB;GACvB;EACF"}
@@ -0,0 +1,49 @@
1
+ import { a as MetroTransformer, i as MetroTransformResult, n as MetroPluginOptions, o as TransformerType, r as MetroTransformParams, t as MetroConfig } from "./types-DrVbRHyR.cjs";
2
+ import { getSharedArtifact, getSharedState, getStateKey } from "@soda-gql/plugin-common";
3
+
4
+ //#region packages/metro-plugin/src/index.d.ts
5
+
6
+ /**
7
+ * Wrap Metro configuration with soda-gql support.
8
+ *
9
+ * This function modifies the Metro configuration to use the soda-gql
10
+ * transformer, which applies GraphQL code transformations at build time.
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * // Expo project (metro.config.js)
15
+ * const { getDefaultConfig } = require("expo/metro-config");
16
+ * const { withSodaGql } = require("@soda-gql/metro-plugin");
17
+ *
18
+ * const config = getDefaultConfig(__dirname);
19
+ * module.exports = withSodaGql(config);
20
+ * ```
21
+ *
22
+ * @example
23
+ * ```typescript
24
+ * // React Native bare project (metro.config.js)
25
+ * const { getDefaultConfig, mergeConfig } = require("@react-native/metro-config");
26
+ * const { withSodaGql } = require("@soda-gql/metro-plugin");
27
+ *
28
+ * const config = getDefaultConfig(__dirname);
29
+ * module.exports = withSodaGql(config);
30
+ * ```
31
+ *
32
+ * @example
33
+ * ```typescript
34
+ * // With options
35
+ * const config = getDefaultConfig(__dirname);
36
+ * module.exports = withSodaGql(config, {
37
+ * configPath: "./soda-gql.config.ts",
38
+ * debug: true,
39
+ * });
40
+ * ```
41
+ *
42
+ * @param config - The Metro configuration to wrap
43
+ * @param options - Optional plugin configuration
44
+ * @returns Modified Metro configuration with soda-gql transformer
45
+ */
46
+ declare function withSodaGql<T extends MetroConfig>(config: T, options?: MetroPluginOptions): T;
47
+ //#endregion
48
+ export { type MetroConfig, type MetroPluginOptions, type MetroTransformParams, type MetroTransformResult, type MetroTransformer, type TransformerType, getSharedArtifact, getSharedState, getStateKey, withSodaGql };
49
+ //# sourceMappingURL=index.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/index.ts"],"sourcesContent":[],"mappings":";;;;;;AAsDA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAgB,sBAAsB,qBAAqB,aAAY,qBAA0B"}
@@ -0,0 +1,49 @@
1
+ import { a as MetroTransformer, i as MetroTransformResult, n as MetroPluginOptions, o as TransformerType, r as MetroTransformParams, t as MetroConfig } from "./types-DvXBqw4W.mjs";
2
+ import { getSharedArtifact, getSharedState, getStateKey } from "@soda-gql/plugin-common";
3
+
4
+ //#region packages/metro-plugin/src/index.d.ts
5
+
6
+ /**
7
+ * Wrap Metro configuration with soda-gql support.
8
+ *
9
+ * This function modifies the Metro configuration to use the soda-gql
10
+ * transformer, which applies GraphQL code transformations at build time.
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * // Expo project (metro.config.js)
15
+ * const { getDefaultConfig } = require("expo/metro-config");
16
+ * const { withSodaGql } = require("@soda-gql/metro-plugin");
17
+ *
18
+ * const config = getDefaultConfig(__dirname);
19
+ * module.exports = withSodaGql(config);
20
+ * ```
21
+ *
22
+ * @example
23
+ * ```typescript
24
+ * // React Native bare project (metro.config.js)
25
+ * const { getDefaultConfig, mergeConfig } = require("@react-native/metro-config");
26
+ * const { withSodaGql } = require("@soda-gql/metro-plugin");
27
+ *
28
+ * const config = getDefaultConfig(__dirname);
29
+ * module.exports = withSodaGql(config);
30
+ * ```
31
+ *
32
+ * @example
33
+ * ```typescript
34
+ * // With options
35
+ * const config = getDefaultConfig(__dirname);
36
+ * module.exports = withSodaGql(config, {
37
+ * configPath: "./soda-gql.config.ts",
38
+ * debug: true,
39
+ * });
40
+ * ```
41
+ *
42
+ * @param config - The Metro configuration to wrap
43
+ * @param options - Optional plugin configuration
44
+ * @returns Modified Metro configuration with soda-gql transformer
45
+ */
46
+ declare function withSodaGql<T extends MetroConfig>(config: T, options?: MetroPluginOptions): T;
47
+ //#endregion
48
+ export { type MetroConfig, type MetroPluginOptions, type MetroTransformParams, type MetroTransformResult, type MetroTransformer, type TransformerType, getSharedArtifact, getSharedState, getStateKey, withSodaGql };
49
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"sourcesContent":[],"mappings":";;;;;;AAsDA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAgB,sBAAsB,qBAAqB,aAAY,qBAA0B"}
package/dist/index.mjs ADDED
@@ -0,0 +1,60 @@
1
+ import { t as __require } from "./chunk--GtjC1aJ.mjs";
2
+ import { getSharedArtifact, getSharedState, getStateKey, getStateKey as getStateKey$1, setSharedTransformerType } from "@soda-gql/plugin-common";
3
+
4
+ //#region packages/metro-plugin/src/index.ts
5
+ /**
6
+ * Wrap Metro configuration with soda-gql support.
7
+ *
8
+ * This function modifies the Metro configuration to use the soda-gql
9
+ * transformer, which applies GraphQL code transformations at build time.
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * // Expo project (metro.config.js)
14
+ * const { getDefaultConfig } = require("expo/metro-config");
15
+ * const { withSodaGql } = require("@soda-gql/metro-plugin");
16
+ *
17
+ * const config = getDefaultConfig(__dirname);
18
+ * module.exports = withSodaGql(config);
19
+ * ```
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * // React Native bare project (metro.config.js)
24
+ * const { getDefaultConfig, mergeConfig } = require("@react-native/metro-config");
25
+ * const { withSodaGql } = require("@soda-gql/metro-plugin");
26
+ *
27
+ * const config = getDefaultConfig(__dirname);
28
+ * module.exports = withSodaGql(config);
29
+ * ```
30
+ *
31
+ * @example
32
+ * ```typescript
33
+ * // With options
34
+ * const config = getDefaultConfig(__dirname);
35
+ * module.exports = withSodaGql(config, {
36
+ * configPath: "./soda-gql.config.ts",
37
+ * debug: true,
38
+ * });
39
+ * ```
40
+ *
41
+ * @param config - The Metro configuration to wrap
42
+ * @param options - Optional plugin configuration
43
+ * @returns Modified Metro configuration with soda-gql transformer
44
+ */
45
+ function withSodaGql(config, options = {}) {
46
+ const transformerPath = __require.resolve("@soda-gql/metro-plugin/transformer");
47
+ const stateKey = getStateKey$1(options.configPath);
48
+ if (options.transformer) setSharedTransformerType(stateKey, options.transformer);
49
+ return {
50
+ ...config,
51
+ transformer: {
52
+ ...config.transformer,
53
+ babelTransformerPath: transformerPath
54
+ }
55
+ };
56
+ }
57
+
58
+ //#endregion
59
+ export { getSharedArtifact, getSharedState, getStateKey, withSodaGql };
60
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":["getStateKey"],"sources":["../src/index.ts"],"sourcesContent":["import { getStateKey, setSharedTransformerType } from \"@soda-gql/plugin-common\";\nimport type { MetroConfig, MetroPluginOptions } from \"./types\";\n\n// Re-export shared state utilities for advanced usage\nexport { getSharedArtifact, getSharedState, getStateKey } from \"@soda-gql/plugin-common\";\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 * @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 * // With options\n * const config = getDefaultConfig(__dirname);\n * module.exports = withSodaGql(config, {\n * configPath: \"./soda-gql.config.ts\",\n * debug: true,\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 // Use package export path to ensure correct resolution from any location\n const transformerPath = require.resolve(\"@soda-gql/metro-plugin/transformer\");\n\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 return {\n ...config,\n transformer: {\n ...config.transformer,\n babelTransformerPath: transformerPath,\n },\n } as T;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsDA,SAAgB,YAAmC,QAAW,UAA8B,EAAE,EAAK;CAEjG,MAAM,4BAA0B,QAAQ,qCAAqC;CAG7E,MAAM,WAAWA,cAAY,QAAQ,WAAW;AAChD,KAAI,QAAQ,YACV,0BAAyB,UAAU,QAAQ,YAAY;AAGzD,QAAO;EACL,GAAG;EACH,aAAa;GACX,GAAG,OAAO;GACV,sBAAsB;GACvB;EACF"}