@expo/expo-modules-macros-plugin 0.10.0 → 0.12.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.
Files changed (29) hide show
  1. package/.github/resources/expo-modules-macros.svg +23 -0
  2. package/.github/workflows/publish.yml +4 -0
  3. package/.github/workflows/swift.yml +6 -0
  4. package/README.md +119 -0
  5. package/apple/ExpoModulesMacros-tool +0 -0
  6. package/apple/Sources/ExpoModulesMacros/DecorateModuleBuilder.swift +3 -1
  7. package/apple/Sources/ExpoModulesMacros/ExpoModuleMacro.swift +10 -0
  8. package/apple/Sources/ExpoModulesMacros/ExpoViewMacro.swift +259 -0
  9. package/apple/Sources/ExpoModulesMacros/JSMacro.swift +2 -2
  10. package/apple/Sources/ExpoModulesMacros/MacroHelpers.swift +24 -2
  11. package/apple/Sources/ExpoModulesMacros/Plugin.swift +2 -0
  12. package/apple/Sources/ExpoModulesMacros/RecordMacro.swift +0 -16
  13. package/apple/Sources/ExpoModulesMacros/ViewPropsMacro.swift +487 -0
  14. package/apple/Sources/ExpoModulesScanner/CLI.swift +8 -4
  15. package/apple/Sources/ExpoModulesScanner/Core/Detection.swift +6 -4
  16. package/apple/Sources/ExpoModulesScanner/Core/DetectionVisitor.swift +28 -7
  17. package/apple/Sources/ExpoModulesScanner/Core/ScanBuildConfiguration.swift +3 -9
  18. package/apple/Sources/ExpoModulesScanner/Core/SourceScan.swift +24 -8
  19. package/apple/Sources/ExpoModulesScanner/Exports/ExportedSurface.swift +133 -0
  20. package/apple/Sources/ExpoModulesScanner/Exports/ResolveRefs.swift +199 -0
  21. package/apple/Sources/ExpoModulesScanner/Exports/ScanExports.swift +25 -6
  22. package/apple/Sources/ExpoModulesScanner/Exports/SurfaceVisitor.swift +315 -6
  23. package/apple/Sources/ExpoModulesScanner/Exports/TypeNode.swift +35 -6
  24. package/apple/Sources/ExpoModulesScanner/Modules/ScanModules.swift +89 -22
  25. package/build/index.d.ts +51 -0
  26. package/build/index.js +153 -0
  27. package/build/types.d.ts +264 -0
  28. package/build/types.js +15 -0
  29. package/package.json +12 -2
@@ -0,0 +1,51 @@
1
+ import { ScanExportsResult, ScanModulesResult } from './types';
2
+ export * from './types';
3
+ /** Options accepted by `scanModules`, mirroring the CLI's `scan-modules` flags. */
4
+ export interface ScanModulesOptions {
5
+ /** Conditional compilation flags to treat as set, e.g. `['DEBUG']`. */
6
+ defines?: string[];
7
+ /** Overrides the scanner binary path. Defaults to the one shipped with this package. */
8
+ binaryPath?: string;
9
+ }
10
+ /** Options accepted by `scanExports`. The deep scan doesn't evaluate `#if`, so it takes no flags. */
11
+ export interface ScanExportsOptions {
12
+ /** Overrides the scanner binary path. Defaults to the one shipped with this package. */
13
+ binaryPath?: string;
14
+ }
15
+ /**
16
+ * Thrown when the scanner exits non-zero. Exit code 2 is a usage error (bad subcommand or flags) and
17
+ * 1 means the report couldn't be encoded; both put a message on stderr, carried here as `stderr`.
18
+ */
19
+ export declare class ScannerError extends Error {
20
+ readonly exitCode: number | null;
21
+ readonly stderr: string;
22
+ constructor(message: string, exitCode: number | null, stderr: string);
23
+ }
24
+ /** Thrown when the binary's output schema doesn't match what these types were written against. */
25
+ export declare class ScannerSchemaVersionError extends Error {
26
+ readonly command: string;
27
+ readonly found: number;
28
+ readonly expected: number;
29
+ constructor(command: string, found: number, expected: number);
30
+ }
31
+ /**
32
+ * Absolute path to the scanner binary shipped with this package. It doubles as the macro plugin
33
+ * executable, so it lives next to the Swift package rather than in a `bin` directory.
34
+ */
35
+ export declare function getScannerBinaryPath(): string;
36
+ /**
37
+ * Fast scan for top-level `@ExpoModule` types, for autolinking. Each path is a `.swift` file or a
38
+ * directory, scanned recursively.
39
+ *
40
+ * Conditions the scan can't answer statically come back in `warnings` rather than throwing, so the
41
+ * caller can surface them alongside its own diagnostics.
42
+ */
43
+ export declare function scanModules(paths: string[], options?: ScanModulesOptions): Promise<ScanModulesResult>;
44
+ /**
45
+ * Deep scan of the full JS-exported surface, for TypeScript type generation. Each path is a `.swift`
46
+ * file or a directory, scanned recursively.
47
+ *
48
+ * Unlike `scanModules`, this doesn't evaluate `#if` blocks, so it takes no define option:
49
+ * conditional declarations are reported as if their conditions held.
50
+ */
51
+ export declare function scanExports(paths: string[], options?: ScanExportsOptions): Promise<ScanExportsResult>;
package/build/index.js ADDED
@@ -0,0 +1,153 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ var __importDefault = (this && this.__importDefault) || function (mod) {
17
+ return (mod && mod.__esModule) ? mod : { "default": mod };
18
+ };
19
+ Object.defineProperty(exports, "__esModule", { value: true });
20
+ exports.ScannerSchemaVersionError = exports.ScannerError = void 0;
21
+ exports.getScannerBinaryPath = getScannerBinaryPath;
22
+ exports.scanModules = scanModules;
23
+ exports.scanExports = scanExports;
24
+ const node_child_process_1 = require("node:child_process");
25
+ const node_path_1 = __importDefault(require("node:path"));
26
+ const types_1 = require("./types");
27
+ __exportStar(require("./types"), exports);
28
+ /**
29
+ * Thrown when the scanner exits non-zero. Exit code 2 is a usage error (bad subcommand or flags) and
30
+ * 1 means the report couldn't be encoded; both put a message on stderr, carried here as `stderr`.
31
+ */
32
+ class ScannerError extends Error {
33
+ constructor(message, exitCode, stderr) {
34
+ super(message);
35
+ this.exitCode = exitCode;
36
+ this.stderr = stderr;
37
+ this.name = 'ScannerError';
38
+ }
39
+ }
40
+ exports.ScannerError = ScannerError;
41
+ /** Thrown when the binary's output schema doesn't match what these types were written against. */
42
+ class ScannerSchemaVersionError extends Error {
43
+ constructor(command, found, expected) {
44
+ super(`\`${command}\` returned schema version ${found}, but this package understands ${expected}. ` +
45
+ 'The scanner binary and this wrapper are out of sync; align their versions.');
46
+ this.command = command;
47
+ this.found = found;
48
+ this.expected = expected;
49
+ this.name = 'ScannerSchemaVersionError';
50
+ }
51
+ }
52
+ exports.ScannerSchemaVersionError = ScannerSchemaVersionError;
53
+ /**
54
+ * Absolute path to the scanner binary shipped with this package. It doubles as the macro plugin
55
+ * executable, so it lives next to the Swift package rather than in a `bin` directory.
56
+ */
57
+ function getScannerBinaryPath() {
58
+ return node_path_1.default.join(__dirname, '..', 'apple', 'ExpoModulesMacros-tool');
59
+ }
60
+ /**
61
+ * Runs a scanner subcommand and parses its JSON report.
62
+ *
63
+ * Paths are passed after the options. The CLI has no `--` separator, so a path spelled exactly
64
+ * `--define` would be read as that option instead; such a path isn't representable and the scan
65
+ * fails with a usage error rather than scanning the wrong thing. `-h`/`--help` are worse, since the
66
+ * CLI answers them from anywhere in argv by printing usage and exiting 0, which would surface as an
67
+ * opaque parse failure. `assertRepresentablePaths` rejects those before spawning.
68
+ *
69
+ * Output is buffered rather than streamed: the report is only usable once complete. Scanning all of
70
+ * `expo/packages` produces ~17 KB, so the raised `maxBuffer` is headroom for a far larger tree
71
+ * rather than a limit anything is expected to approach.
72
+ */
73
+ /**
74
+ * Rejects paths the CLI can't receive as paths. `-h`/`--help` are recognized anywhere in argv, so
75
+ * passing one as a path prints usage and exits 0: the scan never runs, and without this the caller
76
+ * would see a JSON parse failure pointing at the wrong cause.
77
+ */
78
+ function assertRepresentablePaths(command, paths) {
79
+ const helpFlag = paths.find((candidate) => candidate === '-h' || candidate === '--help');
80
+ if (helpFlag !== undefined) {
81
+ throw new TypeError(`${command} cannot scan a path named \`${helpFlag}\`: the scanner reads it as a help ` +
82
+ 'request. Pass a path that resolves to the same file, such as `./' +
83
+ helpFlag +
84
+ '`.');
85
+ }
86
+ }
87
+ function runScanner(binaryPath, args) {
88
+ return new Promise((resolve, reject) => {
89
+ (0, node_child_process_1.execFile)(binaryPath, args, { maxBuffer: 64 * 1024 * 1024, encoding: 'utf8' }, (error, stdout, stderr) => {
90
+ if (error) {
91
+ // A spawn failure reports a string `code` (e.g. 'ENOENT'); a non-zero exit reports a
92
+ // number. Only the latter is an exit status.
93
+ const exitCode = typeof error.code === 'number' ? error.code : null;
94
+ if (error.code === 'ENOENT') {
95
+ reject(new ScannerError(`The scanner binary is missing at ${binaryPath}. Run \`npm run build\` in this package to build it.`, null, stderr));
96
+ return;
97
+ }
98
+ reject(new ScannerError(`\`${node_path_1.default.basename(binaryPath)} ${args.join(' ')}\` failed: ${stderr.trim() || error.message}`, exitCode, stderr));
99
+ return;
100
+ }
101
+ try {
102
+ resolve(JSON.parse(stdout));
103
+ }
104
+ catch (parseError) {
105
+ reject(new ScannerError(`Could not parse the scanner's JSON output: ${parseError.message}`, null, stderr));
106
+ }
107
+ });
108
+ });
109
+ }
110
+ /**
111
+ * Fast scan for top-level `@ExpoModule` types, for autolinking. Each path is a `.swift` file or a
112
+ * directory, scanned recursively.
113
+ *
114
+ * Conditions the scan can't answer statically come back in `warnings` rather than throwing, so the
115
+ * caller can surface them alongside its own diagnostics.
116
+ */
117
+ async function scanModules(paths, options = {}) {
118
+ if (paths.length === 0) {
119
+ throw new TypeError('scanModules requires at least one path');
120
+ }
121
+ assertRepresentablePaths('scanModules', paths);
122
+ const args = ['scan-modules'];
123
+ for (const define of options.defines ?? []) {
124
+ args.push('--define', define);
125
+ }
126
+ args.push(...paths);
127
+ const result = await runScanner(options.binaryPath ?? getScannerBinaryPath(), args);
128
+ if (result.schemaVersion !== types_1.SUPPORTED_SCAN_MODULES_SCHEMA_VERSION) {
129
+ throw new ScannerSchemaVersionError('scan-modules', result.schemaVersion, types_1.SUPPORTED_SCAN_MODULES_SCHEMA_VERSION);
130
+ }
131
+ return result;
132
+ }
133
+ /**
134
+ * Deep scan of the full JS-exported surface, for TypeScript type generation. Each path is a `.swift`
135
+ * file or a directory, scanned recursively.
136
+ *
137
+ * Unlike `scanModules`, this doesn't evaluate `#if` blocks, so it takes no define option:
138
+ * conditional declarations are reported as if their conditions held.
139
+ */
140
+ async function scanExports(paths, options = {}) {
141
+ if (paths.length === 0) {
142
+ throw new TypeError('scanExports requires at least one path');
143
+ }
144
+ assertRepresentablePaths('scanExports', paths);
145
+ const result = await runScanner(options.binaryPath ?? getScannerBinaryPath(), [
146
+ 'scan-exports',
147
+ ...paths,
148
+ ]);
149
+ if (result.schemaVersion !== types_1.SUPPORTED_SCAN_EXPORTS_SCHEMA_VERSION) {
150
+ throw new ScannerSchemaVersionError('scan-exports', result.schemaVersion, types_1.SUPPORTED_SCAN_EXPORTS_SCHEMA_VERSION);
151
+ }
152
+ return result;
153
+ }
@@ -0,0 +1,264 @@
1
+ /**
2
+ * Hand-written mirrors of the scanner's JSON output. The Swift `Codable` types in
3
+ * `apple/Sources/ExpoModulesScanner` are the source of truth; these are kept in sync by hand, which
4
+ * is why each command carries a `schemaVersion` the wrapper checks at runtime.
5
+ */
6
+ /** The JS `typeof` category a boundary type reports, mirroring `JSType`. */
7
+ export type JSType = 'undefined' | 'object' | 'boolean' | 'number' | 'bigint' | 'string' | 'symbol' | 'function';
8
+ /**
9
+ * A boundary type as a tagged tree, mirroring `TypeNode`. Discriminate on `kind`.
10
+ *
11
+ * `unknown` carries no `typeof`, and an `optional` reports its *wrapped* node's category, so
12
+ * `(Int, String)?` (an optional around an unknown) has none either. Every other node always has one.
13
+ * The absent (`undefined`) case is carried by the `optional` wrapper itself rather than by its
14
+ * wrapped node.
15
+ */
16
+ export type TypeNode = {
17
+ kind: 'primitive';
18
+ typeof: JSType;
19
+ name: string;
20
+ } | {
21
+ kind: 'optional';
22
+ typeof?: JSType;
23
+ wrapped: TypeNode;
24
+ } | {
25
+ kind: 'array';
26
+ typeof: JSType;
27
+ element: TypeNode;
28
+ } | {
29
+ kind: 'dictionary';
30
+ typeof: JSType;
31
+ key: TypeNode;
32
+ value: TypeNode;
33
+ } | {
34
+ kind: 'promise';
35
+ typeof: JSType;
36
+ value: TypeNode;
37
+ } | {
38
+ kind: 'function';
39
+ typeof: JSType;
40
+ parameters: TypeNode[];
41
+ /** Absent for a `Void` result. */
42
+ returns?: TypeNode;
43
+ async: boolean;
44
+ throws: boolean;
45
+ }
46
+ /**
47
+ * Any other named type; `name` may be qualified.
48
+ *
49
+ * `refKind` says which of this surface's arrays declares that name, so you don't have to look it
50
+ * up. It is absent when the scan declares no such type: a platform convertible (`CGPoint`, `URL`)
51
+ * or a type from another module, which your own catalog resolves.
52
+ *
53
+ * `typeof` follows the resolved kind, so a raw-value enum reports `string` or `number` rather than
54
+ * `object`. Only the scanner can determine that, since it comes from the declaration's `rawType`.
55
+ */
56
+ | {
57
+ kind: 'ref';
58
+ typeof: JSType;
59
+ name: string;
60
+ refKind?: 'record' | 'sharedObject' | 'enum' | 'union';
61
+ }
62
+ /** A type the scanner couldn't interpret; `text` is its source spelling. */
63
+ | {
64
+ kind: 'unknown';
65
+ text: string;
66
+ };
67
+ /** One parameter of a `@JS` function or `@JS init`. */
68
+ export interface ExportedParameter {
69
+ /** The argument label, or `_` when unlabeled. */
70
+ label: string;
71
+ /** The internal parameter name. */
72
+ name: string;
73
+ type: TypeNode;
74
+ /** True when the caller may omit it: a default value or an optional type. */
75
+ optional: boolean;
76
+ }
77
+ /** One `@JS func` on a module or shared object. */
78
+ export interface ExportedFunction {
79
+ name: string;
80
+ /** The JS name it binds under: the `@JS("x")` override, else `name`. */
81
+ jsName: string;
82
+ parameters: ExportedParameter[];
83
+ /** Absent for a `Void` return. */
84
+ returns?: TypeNode;
85
+ async: boolean;
86
+ throws: boolean;
87
+ static: boolean;
88
+ }
89
+ /** One `@JS var` on a module or shared object. */
90
+ export interface ExportedProperty {
91
+ name: string;
92
+ jsName: string;
93
+ /** Absent when the type isn't determinable syntactically; the macro binds it getter-only. */
94
+ type?: TypeNode;
95
+ readonly: boolean;
96
+ static: boolean;
97
+ }
98
+ /** One `@Record` property: a data slot, not a JS accessor. */
99
+ export interface ExportedRecordProperty {
100
+ name: string;
101
+ type: TypeNode;
102
+ /** Optional-typed. */
103
+ optional: boolean;
104
+ /** Whether JS must supply it: neither defaulted nor optional. */
105
+ required: boolean;
106
+ }
107
+ /** An `@ExpoModule` type and its `@JS` surface. */
108
+ export interface ExportedModule {
109
+ name: string;
110
+ /** The JS module name: `@ExpoModule("Foo")` override, else the class name. */
111
+ jsName: string;
112
+ functions: ExportedFunction[];
113
+ properties: ExportedProperty[];
114
+ events: ExportedEvent[];
115
+ /** Absolute source path. */
116
+ file: string;
117
+ }
118
+ /** One `@Event var`: a typed event JS listens for by name, rather than calls. */
119
+ export interface ExportedEvent {
120
+ /** The Swift property name, e.g. `onStatusChange`. */
121
+ name: string;
122
+ /**
123
+ * The name JS listens under: the `@Event("x")` override, else `name` with a conventional `on`
124
+ * prefix stripped and decapitalized (`onStatusChange` -> `statusChange`).
125
+ */
126
+ jsName: string;
127
+ /** The payload type, absent for a no-payload `() -> Void` event. */
128
+ payload?: TypeNode;
129
+ /** `@Event(sync: true)`, dispatching inline on the JS thread instead of scheduling. */
130
+ sync: boolean;
131
+ }
132
+ /** A `@SharedObject` type: a JS class with an optional constructor plus its `@JS` members. */
133
+ export interface ExportedSharedObject {
134
+ name: string;
135
+ jsName: string;
136
+ /** The `@JS init` parameters, or absent when there's none. At most one constructor. */
137
+ constructorParameters?: ExportedParameter[];
138
+ functions: ExportedFunction[];
139
+ properties: ExportedProperty[];
140
+ events: ExportedEvent[];
141
+ file: string;
142
+ }
143
+ /** A `@Record` type and its properties. */
144
+ export interface ExportedRecord {
145
+ name: string;
146
+ properties: ExportedRecordProperty[];
147
+ file: string;
148
+ }
149
+ /**
150
+ * One case of a reported enum.
151
+ *
152
+ * What `rawValue` carries depends on the enum's raw type:
153
+ * - `String`: always present, and decoded (`case active = "act"` reports `act`, unquoted). A case
154
+ * writing none takes its own name, so nothing is left to derive.
155
+ * - an integer type: present only where written, as source text (`1`, `1 << 3`), since the value may
156
+ * be an expression a syntactic scan cannot evaluate. Swift also continues from the preceding case's
157
+ * value (`case a = 1; case b` makes `b` 2), and that carry is yours to apply.
158
+ * - no raw type: always absent, since the enum has no raw values.
159
+ */
160
+ export interface ExportedEnumCase {
161
+ /** The case name as declared. */
162
+ name: string;
163
+ /** The raw value, decoded for a string and verbatim source text otherwise, or absent per the rule above. */
164
+ rawValue?: string;
165
+ }
166
+ /**
167
+ * An `Enumerable` enum: a type crossing the boundary as its raw value rather than as an object.
168
+ * Detected by conformance, not by a macro attribute, so it carries no `jsName`.
169
+ */
170
+ export interface ExportedEnum {
171
+ name: string;
172
+ /** The raw value type as written, absent for a bare `Enumerable` conformance with no raw type. */
173
+ rawType?: TypeNode;
174
+ cases: ExportedEnumCase[];
175
+ file: string;
176
+ }
177
+ /**
178
+ * One alternative a `@Union` may hold. Not a member in the sense a module or shared object has members
179
+ * (functions, properties, events).
180
+ */
181
+ export interface ExportedUnionMember {
182
+ /** The Swift case name. Swift-side only: discrimination is structural, so it never reaches JS. */
183
+ name: string;
184
+ /** The associated value's type: what this alternative decodes from. */
185
+ type: TypeNode;
186
+ }
187
+ /**
188
+ * A `@Union` enum: a typed union of its members' payload types (`A | B | C`).
189
+ *
190
+ * `members` is ordered, and the order is part of the contract: decode takes the first payload that
191
+ * succeeds, so where two shapes overlap (`Int` and `Double`, two compatible records) the earlier one
192
+ * wins. Reordering them describes a different union than the one the module runs.
193
+ */
194
+ export interface ExportedUnion {
195
+ name: string;
196
+ members: ExportedUnionMember[];
197
+ file: string;
198
+ }
199
+ /** The exported types grouped by kind. */
200
+ export interface ExportedSurface {
201
+ modules: ExportedModule[];
202
+ sharedObjects: ExportedSharedObject[];
203
+ records: ExportedRecord[];
204
+ enums: ExportedEnum[];
205
+ unions: ExportedUnion[];
206
+ }
207
+ /** A `#if` condition the scan couldn't answer statically. */
208
+ export interface ScanWarning {
209
+ message: string;
210
+ file: string;
211
+ line: number;
212
+ }
213
+ /** Counts describing how much work a scan did. */
214
+ export interface ScanStats {
215
+ /** `.swift` files the walk found and read. */
216
+ filesScanned: number;
217
+ /** Of those, how many matched the pre-filter (a macro attribute or a scanned conformance). */
218
+ filesParsed: number;
219
+ /** Wall-clock duration of the scan, in milliseconds. */
220
+ durationMs: number;
221
+ }
222
+ /**
223
+ * An Apple OS the scanner attributes modules to, spelled as `os(...)` spells it. The casing is part
224
+ * of the output contract, so consumers with a lowercase convention must fold the case themselves.
225
+ */
226
+ export type ScannedPlatform = 'iOS' | 'macOS' | 'tvOS' | 'watchOS' | 'visionOS';
227
+ /** One module in the `scan-modules` output. */
228
+ export interface ScannedModule {
229
+ name: string;
230
+ /** The resolved JS name: the `@ExpoModule("Foo")` override, else the class name. */
231
+ jsName: string;
232
+ /**
233
+ * The spelled access level, or `internal` when none is written. The generated provider references
234
+ * the class from the app target, so anything below `public` can't be registered.
235
+ */
236
+ accessLevel: string;
237
+ /**
238
+ * The OSes whose builds include this class, resolved from the enclosing `#if` conditions. An
239
+ * unconditional module lists every OS. Empty means no build is known to include it, so don't
240
+ * register it.
241
+ */
242
+ platforms: ScannedPlatform[];
243
+ file: string;
244
+ }
245
+ /** The `scan-modules` result. */
246
+ export interface ScanModulesResult {
247
+ schemaVersion: number;
248
+ modules: ScannedModule[];
249
+ warnings: ScanWarning[];
250
+ stats: ScanStats;
251
+ }
252
+ /** The `scan-exports` result. */
253
+ export interface ScanExportsResult {
254
+ schemaVersion: number;
255
+ exports: ExportedSurface;
256
+ stats: ScanStats;
257
+ }
258
+ /**
259
+ * The output schema versions this package was written against. The wrapper compares these to the
260
+ * `schemaVersion` in each report and throws on a mismatch, so a binary/wrapper version skew surfaces
261
+ * as a clear error instead of silently misread fields.
262
+ */
263
+ export declare const SUPPORTED_SCAN_MODULES_SCHEMA_VERSION = 2;
264
+ export declare const SUPPORTED_SCAN_EXPORTS_SCHEMA_VERSION = 5;
package/build/types.js ADDED
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ /**
3
+ * Hand-written mirrors of the scanner's JSON output. The Swift `Codable` types in
4
+ * `apple/Sources/ExpoModulesScanner` are the source of truth; these are kept in sync by hand, which
5
+ * is why each command carries a `schemaVersion` the wrapper checks at runtime.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.SUPPORTED_SCAN_EXPORTS_SCHEMA_VERSION = exports.SUPPORTED_SCAN_MODULES_SCHEMA_VERSION = void 0;
9
+ /**
10
+ * The output schema versions this package was written against. The wrapper compares these to the
11
+ * `schemaVersion` in each report and throws on a mismatch, so a binary/wrapper version skew surfaces
12
+ * as a clear error instead of silently misread fields.
13
+ */
14
+ exports.SUPPORTED_SCAN_MODULES_SCHEMA_VERSION = 2;
15
+ exports.SUPPORTED_SCAN_EXPORTS_SCHEMA_VERSION = 5;
package/package.json CHANGED
@@ -1,7 +1,9 @@
1
1
  {
2
2
  "name": "@expo/expo-modules-macros-plugin",
3
- "version": "0.10.0",
3
+ "version": "0.12.0",
4
4
  "description": "Swift macro plugin for Expo modules",
5
+ "main": "build/index.js",
6
+ "types": "build/index.d.ts",
5
7
  "license": "MIT",
6
8
  "author": "650 Industries, Inc.",
7
9
  "homepage": "https://github.com/expo/expo-modules-macros-plugin",
@@ -10,6 +12,14 @@
10
12
  "url": "git+https://github.com/expo/expo-modules-macros-plugin.git"
11
13
  },
12
14
  "scripts": {
13
- "build": "node apple/build.js"
15
+ "build": "node apple/build.js",
16
+ "build:ts": "tsc -p tsconfig.json",
17
+ "clean": "rm -rf build",
18
+ "typecheck": "tsc -p tsconfig.json --noEmit",
19
+ "prepublishOnly": "npm run build:ts"
20
+ },
21
+ "devDependencies": {
22
+ "@types/node": "^20.11.0",
23
+ "typescript": "^5.4.0"
14
24
  }
15
25
  }