@usemotif/compiler-metro 1.0.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,17 @@
1
+ # @usemotif/compiler-metro
2
+
3
+ > Metro plugin for React Native — runs `@usemotif/compiler-babel` inside the Metro pipeline so compile-time style-prop extraction works under Expo and bare React Native.
4
+
5
+ ## Install
6
+
7
+ ```sh
8
+ yarn add -D @usemotif/compiler-metro
9
+ ```
10
+
11
+ ## Docs
12
+
13
+ <https://usemotif.dev>
14
+
15
+ ## License
16
+
17
+ [MIT](../../LICENSE)
package/dist/index.cjs ADDED
@@ -0,0 +1,22 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var motifBabelPlugin = require('@usemotif/compiler-babel');
6
+
7
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
8
+
9
+ var motifBabelPlugin__default = /*#__PURE__*/_interopDefault(motifBabelPlugin);
10
+
11
+ // src/index.ts
12
+ var motifMetro = (options = {}) => {
13
+ const { target = "native", ...rest } = options;
14
+ return [motifBabelPlugin__default.default, { ...rest, target }];
15
+ };
16
+ var index_default = motifMetro;
17
+ var PACKAGE_NAME = "@usemotif/compiler-metro";
18
+
19
+ exports.PACKAGE_NAME = PACKAGE_NAME;
20
+ exports.default = index_default;
21
+ //# sourceMappingURL=index.cjs.map
22
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"names":["motifBabelPlugin"],"mappings":";;;;;;;;;;;AAkCA,IAAM,UAAA,GAAa,CAAC,OAAA,GAA6B,EAAC,KAA6C;AAC7F,EAAA,MAAM,EAAE,MAAA,GAAS,QAAA,EAAU,GAAG,MAAK,GAAI,OAAA;AACvC,EAAA,OAAO,CAACA,iCAAA,EAAkB,EAAE,GAAG,IAAA,EAAM,QAAoC,CAAA;AAC3E,CAAA;AAEA,IAAO,aAAA,GAAQ;AACR,IAAM,YAAA,GAAe","file":"index.cjs","sourcesContent":["import motifBabelPlugin, { type MotifBabelOptions } from '@usemotif/compiler-babel';\n\n/**\n * The shape of a Babel plugin entry the way Metro / babel-preset-expo\n * expect: a tuple of `[plugin, options]`. Metro consumes this from the\n * project's `babel.config.js` so the motif transform layers into the\n * existing JS pipeline (no separate Metro transformer needed; Metro\n * already runs Babel for every file).\n *\n * Usage in a React Native / Expo project's `babel.config.js`:\n *\n * ```js\n * const motif = require('@usemotif/compiler-metro').default;\n * module.exports = function (api) {\n * api.cache(true);\n * return {\n * presets: ['babel-preset-expo'],\n * plugins: [motif({ target: 'native' })],\n * };\n * };\n * ```\n *\n * Conceptually this is just a renamed re-export of\n * `@usemotif/compiler-babel` with the `target` defaulted to `'native'`,\n * since that's what RN consumers always want. Keeping it as its own\n * package gives us a place to add Metro-specific configuration plumbing\n * later (CSS extraction is a no-op on native, but a per-file\n * `StyleSheet.create({...})` hoister will land here).\n */\nexport interface MotifMetroOptions extends Omit<MotifBabelOptions, 'target'> {\n /** Target. Defaults to `'native'`. Override only when sharing config. */\n readonly target?: 'web' | 'native';\n}\n\nconst motifMetro = (options: MotifMetroOptions = {}): readonly [unknown, MotifBabelOptions] => {\n const { target = 'native', ...rest } = options;\n return [motifBabelPlugin, { ...rest, target } satisfies MotifBabelOptions];\n};\n\nexport default motifMetro;\nexport const PACKAGE_NAME = '@usemotif/compiler-metro';\n"]}
@@ -0,0 +1,38 @@
1
+ import { MotifBabelOptions } from '@usemotif/compiler-babel';
2
+
3
+ /**
4
+ * The shape of a Babel plugin entry the way Metro / babel-preset-expo
5
+ * expect: a tuple of `[plugin, options]`. Metro consumes this from the
6
+ * project's `babel.config.js` so the motif transform layers into the
7
+ * existing JS pipeline (no separate Metro transformer needed; Metro
8
+ * already runs Babel for every file).
9
+ *
10
+ * Usage in a React Native / Expo project's `babel.config.js`:
11
+ *
12
+ * ```js
13
+ * const motif = require('@usemotif/compiler-metro').default;
14
+ * module.exports = function (api) {
15
+ * api.cache(true);
16
+ * return {
17
+ * presets: ['babel-preset-expo'],
18
+ * plugins: [motif({ target: 'native' })],
19
+ * };
20
+ * };
21
+ * ```
22
+ *
23
+ * Conceptually this is just a renamed re-export of
24
+ * `@usemotif/compiler-babel` with the `target` defaulted to `'native'`,
25
+ * since that's what RN consumers always want. Keeping it as its own
26
+ * package gives us a place to add Metro-specific configuration plumbing
27
+ * later (CSS extraction is a no-op on native, but a per-file
28
+ * `StyleSheet.create({...})` hoister will land here).
29
+ */
30
+ interface MotifMetroOptions extends Omit<MotifBabelOptions, 'target'> {
31
+ /** Target. Defaults to `'native'`. Override only when sharing config. */
32
+ readonly target?: 'web' | 'native';
33
+ }
34
+ declare const motifMetro: (options?: MotifMetroOptions) => readonly [unknown, MotifBabelOptions];
35
+
36
+ declare const PACKAGE_NAME = "@usemotif/compiler-metro";
37
+
38
+ export { type MotifMetroOptions, PACKAGE_NAME, motifMetro as default };
@@ -0,0 +1,38 @@
1
+ import { MotifBabelOptions } from '@usemotif/compiler-babel';
2
+
3
+ /**
4
+ * The shape of a Babel plugin entry the way Metro / babel-preset-expo
5
+ * expect: a tuple of `[plugin, options]`. Metro consumes this from the
6
+ * project's `babel.config.js` so the motif transform layers into the
7
+ * existing JS pipeline (no separate Metro transformer needed; Metro
8
+ * already runs Babel for every file).
9
+ *
10
+ * Usage in a React Native / Expo project's `babel.config.js`:
11
+ *
12
+ * ```js
13
+ * const motif = require('@usemotif/compiler-metro').default;
14
+ * module.exports = function (api) {
15
+ * api.cache(true);
16
+ * return {
17
+ * presets: ['babel-preset-expo'],
18
+ * plugins: [motif({ target: 'native' })],
19
+ * };
20
+ * };
21
+ * ```
22
+ *
23
+ * Conceptually this is just a renamed re-export of
24
+ * `@usemotif/compiler-babel` with the `target` defaulted to `'native'`,
25
+ * since that's what RN consumers always want. Keeping it as its own
26
+ * package gives us a place to add Metro-specific configuration plumbing
27
+ * later (CSS extraction is a no-op on native, but a per-file
28
+ * `StyleSheet.create({...})` hoister will land here).
29
+ */
30
+ interface MotifMetroOptions extends Omit<MotifBabelOptions, 'target'> {
31
+ /** Target. Defaults to `'native'`. Override only when sharing config. */
32
+ readonly target?: 'web' | 'native';
33
+ }
34
+ declare const motifMetro: (options?: MotifMetroOptions) => readonly [unknown, MotifBabelOptions];
35
+
36
+ declare const PACKAGE_NAME = "@usemotif/compiler-metro";
37
+
38
+ export { type MotifMetroOptions, PACKAGE_NAME, motifMetro as default };
package/dist/index.js ADDED
@@ -0,0 +1,13 @@
1
+ import motifBabelPlugin from '@usemotif/compiler-babel';
2
+
3
+ // src/index.ts
4
+ var motifMetro = (options = {}) => {
5
+ const { target = "native", ...rest } = options;
6
+ return [motifBabelPlugin, { ...rest, target }];
7
+ };
8
+ var index_default = motifMetro;
9
+ var PACKAGE_NAME = "@usemotif/compiler-metro";
10
+
11
+ export { PACKAGE_NAME, index_default as default };
12
+ //# sourceMappingURL=index.js.map
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":";;;AAkCA,IAAM,UAAA,GAAa,CAAC,OAAA,GAA6B,EAAC,KAA6C;AAC7F,EAAA,MAAM,EAAE,MAAA,GAAS,QAAA,EAAU,GAAG,MAAK,GAAI,OAAA;AACvC,EAAA,OAAO,CAAC,gBAAA,EAAkB,EAAE,GAAG,IAAA,EAAM,QAAoC,CAAA;AAC3E,CAAA;AAEA,IAAO,aAAA,GAAQ;AACR,IAAM,YAAA,GAAe","file":"index.js","sourcesContent":["import motifBabelPlugin, { type MotifBabelOptions } from '@usemotif/compiler-babel';\n\n/**\n * The shape of a Babel plugin entry the way Metro / babel-preset-expo\n * expect: a tuple of `[plugin, options]`. Metro consumes this from the\n * project's `babel.config.js` so the motif transform layers into the\n * existing JS pipeline (no separate Metro transformer needed; Metro\n * already runs Babel for every file).\n *\n * Usage in a React Native / Expo project's `babel.config.js`:\n *\n * ```js\n * const motif = require('@usemotif/compiler-metro').default;\n * module.exports = function (api) {\n * api.cache(true);\n * return {\n * presets: ['babel-preset-expo'],\n * plugins: [motif({ target: 'native' })],\n * };\n * };\n * ```\n *\n * Conceptually this is just a renamed re-export of\n * `@usemotif/compiler-babel` with the `target` defaulted to `'native'`,\n * since that's what RN consumers always want. Keeping it as its own\n * package gives us a place to add Metro-specific configuration plumbing\n * later (CSS extraction is a no-op on native, but a per-file\n * `StyleSheet.create({...})` hoister will land here).\n */\nexport interface MotifMetroOptions extends Omit<MotifBabelOptions, 'target'> {\n /** Target. Defaults to `'native'`. Override only when sharing config. */\n readonly target?: 'web' | 'native';\n}\n\nconst motifMetro = (options: MotifMetroOptions = {}): readonly [unknown, MotifBabelOptions] => {\n const { target = 'native', ...rest } = options;\n return [motifBabelPlugin, { ...rest, target } satisfies MotifBabelOptions];\n};\n\nexport default motifMetro;\nexport const PACKAGE_NAME = '@usemotif/compiler-metro';\n"]}
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@usemotif/compiler-metro",
3
+ "version": "1.0.0",
4
+ "description": "Metro transformer for motif-js static style extraction in React Native.",
5
+ "homepage": "https://github.com/foo-stack/usemotif/tree/main/packages/compiler-metro#readme",
6
+ "bugs": "https://github.com/foo-stack/usemotif/issues",
7
+ "license": "MIT",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/foo-stack/usemotif.git",
11
+ "directory": "packages/compiler-metro"
12
+ },
13
+ "files": [
14
+ "dist",
15
+ "src"
16
+ ],
17
+ "type": "module",
18
+ "sideEffects": false,
19
+ "main": "./dist/index.cjs",
20
+ "module": "./dist/index.js",
21
+ "types": "./dist/index.d.ts",
22
+ "exports": {
23
+ ".": {
24
+ "types": "./dist/index.d.ts",
25
+ "import": "./dist/index.js",
26
+ "require": "./dist/index.cjs"
27
+ }
28
+ },
29
+ "publishConfig": {
30
+ "access": "public"
31
+ },
32
+ "scripts": {
33
+ "build": "tsup",
34
+ "typecheck": "tsc --noEmit",
35
+ "clean": "rm -rf dist .turbo *.tsbuildinfo",
36
+ "test": "vitest run"
37
+ },
38
+ "dependencies": {
39
+ "@babel/core": "^7.29.0",
40
+ "@usemotif/compiler-babel": "1.0.0"
41
+ },
42
+ "devDependencies": {
43
+ "@types/babel__core": "^7.20.5",
44
+ "tsup": "^8.5.1",
45
+ "typescript": "^6.0.3",
46
+ "vitest": "^4.1.5"
47
+ }
48
+ }
@@ -0,0 +1,52 @@
1
+ import { transformSync } from '@babel/core';
2
+ import { describe, expect, it } from 'vitest';
3
+ import motifMetro from './index.js';
4
+
5
+ describe('@usemotif/compiler-metro', () => {
6
+ it('returns a [plugin, options] tuple Babel can consume', () => {
7
+ const tuple = motifMetro();
8
+ expect(Array.isArray(tuple)).toBe(true);
9
+ expect(tuple).toHaveLength(2);
10
+ expect(typeof tuple[0]).toBe('function');
11
+ expect(tuple[1]).toMatchObject({ target: 'native' });
12
+ });
13
+
14
+ it('hoists StyleSheet.create on native target', () => {
15
+ const tuple = motifMetro();
16
+ const result = transformSync(
17
+ `import { Box } from '@usemotif/react-native';\nconst X = () => <Box p={4} />;\n`,
18
+ {
19
+ babelrc: false,
20
+ configFile: false,
21
+ filename: 'test.tsx',
22
+ plugins: [tuple],
23
+ parserOpts: { plugins: ['jsx', 'typescript'] },
24
+ generatorOpts: { compact: false },
25
+ },
26
+ );
27
+ const code = result?.code ?? '';
28
+ expect(code).not.toMatch(/\bp=\{4\}/);
29
+ expect(code).toContain('StyleSheet');
30
+ expect(code).toContain('_motifStyles');
31
+ expect(code).toContain('padding: 4');
32
+ expect(code).toMatch(/style=\{_motifStyles\.id\d+\}/);
33
+ });
34
+
35
+ it('respects target override', () => {
36
+ const tuple = motifMetro({ target: 'web' });
37
+ const result = transformSync(
38
+ `import { Box } from '@usemotif/react';\nconst X = () => <Box p={4} />;\n`,
39
+ {
40
+ babelrc: false,
41
+ configFile: false,
42
+ filename: 'test.tsx',
43
+ plugins: [tuple],
44
+ parserOpts: { plugins: ['jsx', 'typescript'] },
45
+ generatorOpts: { compact: false },
46
+ },
47
+ );
48
+ // With target=web, the static prop should be extracted.
49
+ expect(result?.code).not.toMatch(/\bp=\{4\}/);
50
+ expect(result?.code).toContain('padding: 4');
51
+ });
52
+ });
package/src/index.ts ADDED
@@ -0,0 +1,41 @@
1
+ import motifBabelPlugin, { type MotifBabelOptions } from '@usemotif/compiler-babel';
2
+
3
+ /**
4
+ * The shape of a Babel plugin entry the way Metro / babel-preset-expo
5
+ * expect: a tuple of `[plugin, options]`. Metro consumes this from the
6
+ * project's `babel.config.js` so the motif transform layers into the
7
+ * existing JS pipeline (no separate Metro transformer needed; Metro
8
+ * already runs Babel for every file).
9
+ *
10
+ * Usage in a React Native / Expo project's `babel.config.js`:
11
+ *
12
+ * ```js
13
+ * const motif = require('@usemotif/compiler-metro').default;
14
+ * module.exports = function (api) {
15
+ * api.cache(true);
16
+ * return {
17
+ * presets: ['babel-preset-expo'],
18
+ * plugins: [motif({ target: 'native' })],
19
+ * };
20
+ * };
21
+ * ```
22
+ *
23
+ * Conceptually this is just a renamed re-export of
24
+ * `@usemotif/compiler-babel` with the `target` defaulted to `'native'`,
25
+ * since that's what RN consumers always want. Keeping it as its own
26
+ * package gives us a place to add Metro-specific configuration plumbing
27
+ * later (CSS extraction is a no-op on native, but a per-file
28
+ * `StyleSheet.create({...})` hoister will land here).
29
+ */
30
+ export interface MotifMetroOptions extends Omit<MotifBabelOptions, 'target'> {
31
+ /** Target. Defaults to `'native'`. Override only when sharing config. */
32
+ readonly target?: 'web' | 'native';
33
+ }
34
+
35
+ const motifMetro = (options: MotifMetroOptions = {}): readonly [unknown, MotifBabelOptions] => {
36
+ const { target = 'native', ...rest } = options;
37
+ return [motifBabelPlugin, { ...rest, target } satisfies MotifBabelOptions];
38
+ };
39
+
40
+ export default motifMetro;
41
+ export const PACKAGE_NAME = '@usemotif/compiler-metro';