miaoda-expo-devkit 0.1.1-beta.2 → 0.1.1-beta.21

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/metro.mjs CHANGED
@@ -1,55 +1,47 @@
1
- // src/metro.ts
2
- import connect from "connect";
3
- import fs2 from "fs";
4
- import path2 from "path";
1
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined") return require.apply(this, arguments);
5
+ throw Error('Dynamic require of "' + x + '" is not supported');
6
+ });
5
7
 
6
- // src/routes.ts
7
- import fs from "fs";
8
+ // src/metro/withNativeWind.ts
8
9
  import path from "path";
9
- var ROUTE_EXT = /\.(tsx|ts|jsx|js)$/;
10
- function getRoutes(appDir) {
11
- const routes = [];
12
- function scan(dir, prefix) {
13
- let entries;
14
- try {
15
- entries = fs.readdirSync(dir, { withFileTypes: true });
16
- } catch {
17
- return;
18
- }
19
- for (const entry of entries) {
20
- const fullPath = path.join(dir, entry.name);
21
- if (entry.isDirectory()) {
22
- const isGroup = /^\(.*\)$/.test(entry.name);
23
- const nextPrefix = isGroup ? prefix : `${prefix}/${entry.name}`;
24
- scan(fullPath, nextPrefix);
25
- } else if (ROUTE_EXT.test(entry.name)) {
26
- const baseName = entry.name.replace(ROUTE_EXT, "");
27
- if (baseName === "_layout") continue;
28
- const segment = baseName === "index" ? "" : `/${baseName}`;
29
- const routePath = `${prefix}${segment}` || "/";
30
- const isDynamic = /\[.*\]/.test(baseName);
31
- routes.push({
32
- title: routePath,
33
- pageId: routePath,
34
- pageName: routePath,
35
- visible: !isDynamic,
36
- path: path.relative(appDir, fullPath)
37
- });
38
- }
10
+ function patchNativeWindCachePath(options = {}) {
11
+ const projectRoot = process.cwd();
12
+ const ourCacheDir = path.resolve(projectRoot, options.cacheDir ?? ".native-wind-cache");
13
+ const nativewindPkgDir = path.dirname(__require.resolve("react-native-css-interop/package.json"));
14
+ const nativewindCacheDir = path.resolve(nativewindPkgDir, ".cache");
15
+ const moduleId = __require.resolve("react-native-css-interop/dist/metro");
16
+ delete __require.cache[moduleId];
17
+ let intercepted = false;
18
+ const originalResolve = path.resolve;
19
+ path.resolve = ((...args) => {
20
+ const result = originalResolve(...args);
21
+ if (result === nativewindCacheDir) {
22
+ intercepted = true;
23
+ return ourCacheDir;
39
24
  }
25
+ return result;
26
+ });
27
+ try {
28
+ __require(moduleId);
29
+ } finally {
30
+ path.resolve = originalResolve;
31
+ }
32
+ if (!intercepted) {
33
+ throw new Error(
34
+ "patchNativeWindCachePath: patch \u672A\u751F\u6548\u2014\u2014react-native-css-interop \u53EF\u80FD\u5DF2\u4E0D\u518D\u901A\u8FC7 path.resolve \u8BA1\u7B97\u7F13\u5B58\u8DEF\u5F84\u3002\u5347\u7EA7\u8BE5\u4F9D\u8D56\u540E\u8BF7\u68C0\u67E5 dist/metro/index.js \u4E2D\u7684\u5B9E\u73B0\u3002"
35
+ );
40
36
  }
41
- scan(appDir, "");
42
- return { routes };
43
37
  }
44
- function createRouteHandler(appDir) {
45
- return (_req, res) => {
46
- const routeTree = getRoutes(appDir);
47
- res.writeHead(200, { "Content-Type": "application/json" });
48
- res.end(JSON.stringify(routeTree, null, 2));
49
- };
38
+ function withNativeWind(config, options) {
39
+ const { withNativeWind: nwWithNativeWind } = __require("nativewind/metro");
40
+ return nwWithNativeWind(config, options);
50
41
  }
51
42
 
52
- // src/metro.ts
43
+ // src/metro/withDevStubs.ts
44
+ import path2 from "path";
53
45
  var SENTRY_STUB_FILENAME = "sentry-react-native-stub.js";
54
46
  var SENTRY_STUB_PATH = path2.resolve(__dirname, "stubs", SENTRY_STUB_FILENAME);
55
47
  var NO_OP_LOGBOX_STUB_PATH = path2.resolve(__dirname, "stubs", "no-op-logbox.js");
@@ -77,7 +69,10 @@ function withDevStubs(config) {
77
69
  }
78
70
  };
79
71
  }
80
- var EXPO_ROUTER_ENTRY_STUB_PATH = path2.resolve(__dirname, "stubs", "expo-router-entry-stub.js");
72
+
73
+ // src/metro/withEntryInjection.ts
74
+ import path3 from "path";
75
+ var EXPO_ROUTER_ENTRY_STUB_PATH = path3.resolve(__dirname, "stubs", "expo-router-entry-stub.js");
81
76
  var EXPO_ROUTER_ENTRY_STUB_FILENAME = "expo-router-entry-stub.js";
82
77
  function withEntryInjection(config, options) {
83
78
  void options;
@@ -99,13 +94,63 @@ function withEntryInjection(config, options) {
99
94
  }
100
95
  };
101
96
  }
97
+
98
+ // src/metro/withRouteEndpoint.ts
99
+ import connect from "connect";
100
+
101
+ // src/routes.ts
102
+ import fs from "fs";
103
+ import path4 from "path";
104
+ var ROUTE_EXT = /\.(tsx|ts|jsx|js)$/;
105
+ function getRoutes(appDir, rootDir) {
106
+ const routes = [];
107
+ function scan(dir, prefix) {
108
+ let entries;
109
+ try {
110
+ entries = fs.readdirSync(dir, { withFileTypes: true });
111
+ } catch {
112
+ return;
113
+ }
114
+ for (const entry of entries) {
115
+ const fullPath = path4.join(dir, entry.name);
116
+ if (entry.isDirectory()) {
117
+ const isGroup = /^\(.*\)$/.test(entry.name);
118
+ const nextPrefix = isGroup ? prefix : `${prefix}/${entry.name}`;
119
+ scan(fullPath, nextPrefix);
120
+ } else if (ROUTE_EXT.test(entry.name)) {
121
+ const baseName = entry.name.replace(ROUTE_EXT, "");
122
+ if (baseName === "_layout" || /\[.*\]/.test(baseName)) continue;
123
+ const segment = baseName === "index" ? "" : `/${baseName}`;
124
+ const routePath = `${prefix}${segment}` || "/";
125
+ routes.push({
126
+ title: routePath.replace(/^\//, "") || "/",
127
+ pageId: routePath,
128
+ pageName: routePath,
129
+ path: path4.relative(rootDir, fullPath)
130
+ });
131
+ }
132
+ }
133
+ }
134
+ scan(appDir, "");
135
+ return { data: routes };
136
+ }
137
+ function createRouteHandler(appDir, rootDir) {
138
+ return (_req, res) => {
139
+ const routeTree = getRoutes(appDir, rootDir);
140
+ res.writeHead(200, { "Content-Type": "application/json" });
141
+ res.end(JSON.stringify(routeTree, null, 2));
142
+ };
143
+ }
144
+
145
+ // src/metro/withRouteEndpoint.ts
102
146
  var DEFAULT_ROUTE_ENDPOINT = "/__routes";
103
147
  function withRouteEndpoint(config, options) {
104
148
  const { appDir, endpoint = DEFAULT_ROUTE_ENDPOINT } = options;
149
+ const rootDir = config.projectRoot ?? process.cwd();
105
150
  const upstream = config.server?.enhanceMiddleware ?? null;
106
151
  const enhanceMiddleware = (middleware, metroServer) => {
107
152
  const enhanced = upstream ? upstream(middleware, metroServer) : middleware;
108
- return connect().use(enhanced).use(endpoint, createRouteHandler(appDir));
153
+ return connect().use(enhanced).use(endpoint, createRouteHandler(appDir, rootDir));
109
154
  };
110
155
  return {
111
156
  ...config,
@@ -115,40 +160,152 @@ function withRouteEndpoint(config, options) {
115
160
  }
116
161
  };
117
162
  }
118
- function withWorkspaceNodeModules(config) {
119
- const projectRoot = config.projectRoot ?? process.cwd();
120
- if (fs2.existsSync(path2.join(projectRoot, "node_modules"))) {
121
- return config;
122
- }
123
- let dir = path2.dirname(projectRoot);
124
- let found = null;
163
+
164
+ // src/metro/withWorkspaceNodeModules.ts
165
+ import fs2 from "fs";
166
+ import path5 from "path";
167
+ function findAncestorNodeModulesDir(projectRoot) {
168
+ let dir = path5.dirname(projectRoot);
125
169
  while (true) {
126
- const candidate = path2.join(dir, "node_modules");
127
- if (fs2.existsSync(candidate)) {
128
- found = candidate;
129
- break;
130
- }
131
- const parent = path2.dirname(dir);
170
+ const candidate = path5.join(dir, "node_modules");
171
+ if (fs2.existsSync(candidate)) return candidate;
172
+ const parent = path5.dirname(dir);
132
173
  if (parent === dir) break;
133
174
  dir = parent;
134
175
  }
135
- if (!found) {
136
- return config;
176
+ return null;
177
+ }
178
+ function resolveExternalPnpmStore(nodeModulesDir) {
179
+ const pnpmDir = path5.join(nodeModulesDir, ".pnpm");
180
+ try {
181
+ const realPnpmDir = fs2.realpathSync(pnpmDir);
182
+ const realNmDir = path5.dirname(realPnpmDir);
183
+ if (realNmDir !== nodeModulesDir) {
184
+ return realNmDir;
185
+ }
186
+ } catch {
187
+ }
188
+ return null;
189
+ }
190
+ function withWorkspaceNodeModules(config) {
191
+ const projectRoot = config.projectRoot ?? process.cwd();
192
+ const found = findAncestorNodeModulesDir(projectRoot);
193
+ if (!found) return config;
194
+ const foldersToAdd = [found];
195
+ const externalStore = resolveExternalPnpmStore(found);
196
+ if (externalStore) {
197
+ foldersToAdd.push(externalStore);
137
198
  }
138
- const existingWatchFolders = config.watchFolders ?? [];
139
- const existingNodeModulesPaths = config.resolver?.nodeModulesPaths ?? [];
140
199
  return {
141
200
  ...config,
142
- watchFolders: [...existingWatchFolders, found],
201
+ watchFolders: [...config.watchFolders ?? [], ...foldersToAdd],
202
+ resolver: {
203
+ ...config.resolver,
204
+ nodeModulesPaths: [...config.resolver?.nodeModulesPaths ?? [], ...foldersToAdd]
205
+ }
206
+ };
207
+ }
208
+
209
+ // src/metro/withCssInterop.ts
210
+ import path6 from "path";
211
+ var EXPO_IMAGE_STUB_FILENAME = "expo-image-stub.js";
212
+ var EXPO_IMAGE_STUB_PATH = path6.resolve(__dirname, "stubs", EXPO_IMAGE_STUB_FILENAME);
213
+ var EXPO_CAMERA_STUB_FILENAME = "expo-camera-stub.js";
214
+ var EXPO_CAMERA_STUB_PATH = path6.resolve(__dirname, "stubs", EXPO_CAMERA_STUB_FILENAME);
215
+ var EXPO_LINEAR_GRADIENT_STUB_FILENAME = "expo-linear-gradient-stub.js";
216
+ var EXPO_LINEAR_GRADIENT_STUB_PATH = path6.resolve(__dirname, "stubs", EXPO_LINEAR_GRADIENT_STUB_FILENAME);
217
+ var EXPO_BLUR_STUB_FILENAME = "expo-blur-stub.js";
218
+ var EXPO_BLUR_STUB_PATH = path6.resolve(__dirname, "stubs", EXPO_BLUR_STUB_FILENAME);
219
+ function withCssInterop(config) {
220
+ const upstream = config.resolver?.resolveRequest ?? null;
221
+ const resolveRequest = (context, moduleName, platform) => {
222
+ if (moduleName === "expo-image" && !context.originModulePath.includes(EXPO_IMAGE_STUB_FILENAME)) {
223
+ return { filePath: EXPO_IMAGE_STUB_PATH, type: "sourceFile" };
224
+ }
225
+ if (moduleName === "expo-camera" && !context.originModulePath.includes(EXPO_CAMERA_STUB_FILENAME)) {
226
+ return { filePath: EXPO_CAMERA_STUB_PATH, type: "sourceFile" };
227
+ }
228
+ if (moduleName === "expo-linear-gradient" && !context.originModulePath.includes(EXPO_LINEAR_GRADIENT_STUB_FILENAME)) {
229
+ return { filePath: EXPO_LINEAR_GRADIENT_STUB_PATH, type: "sourceFile" };
230
+ }
231
+ if (moduleName === "expo-blur" && !context.originModulePath.includes(EXPO_BLUR_STUB_FILENAME)) {
232
+ return { filePath: EXPO_BLUR_STUB_PATH, type: "sourceFile" };
233
+ }
234
+ if (upstream) {
235
+ return upstream(context, moduleName, platform);
236
+ }
237
+ return context.resolveRequest(context, moduleName, platform);
238
+ };
239
+ return {
240
+ ...config,
143
241
  resolver: {
144
242
  ...config.resolver,
145
- nodeModulesPaths: [...existingNodeModulesPaths, found]
243
+ resolveRequest
146
244
  }
147
245
  };
148
246
  }
247
+
248
+ // src/metro/withDevkit.ts
249
+ import path7 from "path";
250
+
251
+ // src/metro/withEsbuildMinify.ts
252
+ function withEsbuildMinify(config) {
253
+ return {
254
+ ...config,
255
+ transformer: {
256
+ ...config.transformer,
257
+ minifierPath: __require.resolve("metro-minify-esbuild"),
258
+ // 清空 terser 默认选项,esbuild 用自己的默认压缩配置
259
+ minifierConfig: {}
260
+ }
261
+ };
262
+ }
263
+
264
+ // src/metro/withDevkit.ts
265
+ var EXPO_NOTIFICATIONS_STUB_FILENAME = "expo-notifications-stub.js";
266
+ var EXPO_NOTIFICATIONS_STUB_PATH = path7.resolve(__dirname, "stubs", EXPO_NOTIFICATIONS_STUB_FILENAME);
267
+ function withExpoNotificationsStub(config) {
268
+ const upstream = config.resolver?.resolveRequest ?? null;
269
+ const resolveRequest = (context, moduleName, platform) => {
270
+ if (platform === "android" && moduleName === "expo-notifications" && !context.originModulePath.includes(EXPO_NOTIFICATIONS_STUB_FILENAME)) {
271
+ return { filePath: EXPO_NOTIFICATIONS_STUB_PATH, type: "sourceFile" };
272
+ }
273
+ if (upstream) return upstream(context, moduleName, platform);
274
+ return context.resolveRequest(context, moduleName, platform);
275
+ };
276
+ return { ...config, resolver: { ...config.resolver, resolveRequest } };
277
+ }
278
+ function withDevkit(config, options = {}) {
279
+ const projectRoot = config.projectRoot ?? process.cwd();
280
+ const { input = "./src/global.css" } = options;
281
+ config = withWorkspaceNodeModules(config);
282
+ config = withCssInterop(config);
283
+ config = withEsbuildMinify(config);
284
+ config = withExpoNotificationsStub(config);
285
+ if (typeof __DEV__ !== "undefined" && __DEV__) {
286
+ config = withEntryInjection(config);
287
+ config = withDevStubs(config);
288
+ config = withRouteEndpoint(config, { appDir: path7.join(projectRoot, "src", "app") });
289
+ }
290
+ return withNativeWind(config, { input, inlineRem: 16 });
291
+ }
292
+
293
+ // src/metro/index.ts
294
+ try {
295
+ __require.resolve("react-native-css-interop/package.json");
296
+ patchNativeWindCachePath();
297
+ } catch (e) {
298
+ if (e.code !== "MODULE_NOT_FOUND") throw e;
299
+ }
149
300
  export {
301
+ patchNativeWindCachePath,
302
+ withCssInterop,
150
303
  withDevStubs,
304
+ withDevkit,
151
305
  withEntryInjection,
306
+ withEsbuildMinify,
307
+ withExpoNotificationsStub,
308
+ withNativeWind,
152
309
  withRouteEndpoint,
153
310
  withWorkspaceNodeModules
154
311
  };
@@ -103,7 +103,7 @@ var noDuplicateExpoRouterUrlRule = {
103
103
  },
104
104
  create(context) {
105
105
  return {
106
- Program(node) {
106
+ Program() {
107
107
  const projectRoot = findProjectRoot(context.filename);
108
108
  if (!projectRoot) return;
109
109
  const routerRoot = getRouterRoot(projectRoot);
@@ -118,7 +118,7 @@ var noDuplicateExpoRouterUrlRule = {
118
118
  const others = files.filter((f) => f !== rel);
119
119
  if (others.length === 0) return;
120
120
  context.report({
121
- loc: { line: 1, column: 0 },
121
+ loc: { start: { line: 1, column: 0 }, end: { line: 1, column: 0 } },
122
122
  messageId: "duplicateUrl",
123
123
  data: { url, other: others.join(", ") }
124
124
  });
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/rules/no-missing-css-import.ts
31
+ var no_missing_css_import_exports = {};
32
+ __export(no_missing_css_import_exports, {
33
+ default: () => no_missing_css_import_default
34
+ });
35
+ module.exports = __toCommonJS(no_missing_css_import_exports);
36
+ var import_node_fs = __toESM(require("fs"));
37
+ var import_node_path = __toESM(require("path"));
38
+ var import_oxc_resolver = require("oxc-resolver");
39
+ var CSS_EXTENSION = /\.css$/i;
40
+ var resolverCache = /* @__PURE__ */ new Map();
41
+ function getResolver(projectRoot) {
42
+ let resolver = resolverCache.get(projectRoot);
43
+ if (!resolver) {
44
+ resolver = new import_oxc_resolver.ResolverFactory({
45
+ extensions: [".css"],
46
+ conditionNames: ["import", "require", "node", "default"]
47
+ });
48
+ resolverCache.set(projectRoot, resolver);
49
+ }
50
+ return resolver;
51
+ }
52
+ function findProjectRoot(startPath) {
53
+ let dir = import_node_path.default.dirname(startPath);
54
+ while (dir !== import_node_path.default.dirname(dir)) {
55
+ if (import_node_fs.default.existsSync(import_node_path.default.join(dir, "package.json"))) return dir;
56
+ dir = import_node_path.default.dirname(dir);
57
+ }
58
+ return dir;
59
+ }
60
+ var noMissingCssImportRule = {
61
+ meta: {
62
+ type: "problem",
63
+ docs: {
64
+ description: "Disallow CSS imports that reference non-existent files."
65
+ },
66
+ schema: [],
67
+ messages: {
68
+ cssNotFound: "CSS file '{{source}}' does not exist."
69
+ }
70
+ },
71
+ create(context) {
72
+ const projectRoot = findProjectRoot(context.filename);
73
+ const resolver = getResolver(projectRoot);
74
+ const currentDir = import_node_path.default.dirname(context.filename);
75
+ function check(node, source) {
76
+ if (!CSS_EXTENSION.test(source)) return;
77
+ try {
78
+ const result = resolver.sync(currentDir, source);
79
+ if (!result.path || !import_node_fs.default.existsSync(result.path)) {
80
+ context.report({ node, messageId: "cssNotFound", data: { source } });
81
+ }
82
+ } catch {
83
+ context.report({ node, messageId: "cssNotFound", data: { source } });
84
+ }
85
+ }
86
+ return {
87
+ ImportDeclaration(node) {
88
+ check(node, node.source.value);
89
+ }
90
+ };
91
+ }
92
+ };
93
+ var plugin = {
94
+ meta: { name: "css-import" },
95
+ rules: { "no-missing-css-import": noMissingCssImportRule }
96
+ };
97
+ var no_missing_css_import_default = plugin;
98
+ module.exports = module.exports.default;
@@ -81,6 +81,7 @@ var KNOWN_CONFIG_PLUGIN_PACKAGES = /* @__PURE__ */ new Set([
81
81
  "expo-widgets"
82
82
  ]);
83
83
  var pluginsCache = /* @__PURE__ */ new Map();
84
+ var reportedPackages = /* @__PURE__ */ new Set();
84
85
  function findProjectRoot(startPath) {
85
86
  let dir = import_node_path.default.dirname(startPath);
86
87
  while (dir !== import_node_path.default.dirname(dir)) {
@@ -132,6 +133,9 @@ var requireExpoPluginRule = {
132
133
  if (!pkg) return;
133
134
  if (!KNOWN_CONFIG_PLUGIN_PACKAGES.has(pkg)) return;
134
135
  if (declaredPlugins.includes(pkg)) return;
136
+ const reportKey = `${projectRoot}::${pkg}`;
137
+ if (reportedPackages.has(reportKey)) return;
138
+ reportedPackages.add(reportKey);
135
139
  context.report({
136
140
  node,
137
141
  messageId: "missingPlugin",
@@ -0,0 +1,162 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/rules/no-unused-expo-plugin.ts
31
+ var no_unused_expo_plugin_exports = {};
32
+ __export(no_unused_expo_plugin_exports, {
33
+ default: () => no_unused_expo_plugin_default
34
+ });
35
+ module.exports = __toCommonJS(no_unused_expo_plugin_exports);
36
+ var import_node_fs = __toESM(require("fs"));
37
+ var import_node_path = __toESM(require("path"));
38
+ var KNOWN_CONFIG_PLUGIN_PACKAGES = /* @__PURE__ */ new Set([
39
+ "expo-apple-authentication",
40
+ "expo-asset",
41
+ "expo-audio",
42
+ "expo-background-fetch",
43
+ "expo-background-task",
44
+ "expo-brightness",
45
+ "expo-brownfield",
46
+ "expo-build-properties",
47
+ "expo-calendar",
48
+ "expo-camera",
49
+ "expo-cellular",
50
+ "expo-contacts",
51
+ "expo-dev-client",
52
+ "expo-dev-launcher",
53
+ "expo-dev-menu",
54
+ "expo-document-picker",
55
+ "expo-file-system",
56
+ "expo-font",
57
+ "expo-image",
58
+ "expo-image-picker",
59
+ "expo-local-authentication",
60
+ "expo-localization",
61
+ "expo-location",
62
+ "expo-mail-composer",
63
+ "expo-maps",
64
+ "expo-media-library",
65
+ "expo-modules-test-core",
66
+ "expo-navigation-bar",
67
+ "expo-notifications",
68
+ "expo-router",
69
+ "expo-screen-orientation",
70
+ "expo-secure-store",
71
+ "expo-sensors",
72
+ "expo-sharing",
73
+ "expo-splash-screen",
74
+ "expo-sqlite",
75
+ "expo-system-ui",
76
+ "expo-task-manager",
77
+ "expo-tracking-transparency",
78
+ "expo-updates",
79
+ "expo-video",
80
+ "expo-web-browser",
81
+ "expo-widgets"
82
+ ]);
83
+ var pluginsCache = /* @__PURE__ */ new Map();
84
+ var depsCache = /* @__PURE__ */ new Map();
85
+ function findProjectRoot(startPath) {
86
+ let dir = import_node_path.default.dirname(startPath);
87
+ while (dir !== import_node_path.default.dirname(dir)) {
88
+ if (import_node_fs.default.existsSync(import_node_path.default.join(dir, "package.json"))) {
89
+ return dir;
90
+ }
91
+ dir = import_node_path.default.dirname(dir);
92
+ }
93
+ return dir;
94
+ }
95
+ function getPluginsFromAppJson(projectRoot) {
96
+ if (pluginsCache.has(projectRoot)) return pluginsCache.get(projectRoot);
97
+ const appJsonPath = import_node_path.default.join(projectRoot, "app.json");
98
+ try {
99
+ const raw = JSON.parse(import_node_fs.default.readFileSync(appJsonPath, "utf-8"));
100
+ const entries = raw?.expo?.plugins ?? [];
101
+ const names = entries.map((entry) => Array.isArray(entry) ? entry[0] : entry);
102
+ pluginsCache.set(projectRoot, names);
103
+ return names;
104
+ } catch {
105
+ pluginsCache.set(projectRoot, []);
106
+ return [];
107
+ }
108
+ }
109
+ function getInstalledDeps(projectRoot) {
110
+ if (depsCache.has(projectRoot)) return depsCache.get(projectRoot);
111
+ const pkgPath = import_node_path.default.join(projectRoot, "package.json");
112
+ try {
113
+ const raw = JSON.parse(import_node_fs.default.readFileSync(pkgPath, "utf-8"));
114
+ const deps = /* @__PURE__ */ new Set([
115
+ ...Object.keys(raw["dependencies"] ?? {}),
116
+ ...Object.keys(raw["devDependencies"] ?? {}),
117
+ ...Object.keys(raw["peerDependencies"] ?? {}),
118
+ ...Object.keys(raw["optionalDependencies"] ?? {})
119
+ ]);
120
+ depsCache.set(projectRoot, deps);
121
+ return deps;
122
+ } catch {
123
+ depsCache.set(projectRoot, /* @__PURE__ */ new Set());
124
+ return /* @__PURE__ */ new Set();
125
+ }
126
+ }
127
+ var noUnusedExpoPluginRule = {
128
+ meta: {
129
+ type: "problem",
130
+ docs: {
131
+ description: "Ensure Expo Config Plugins declared in app.json's plugins array are installed in package.json."
132
+ },
133
+ schema: [],
134
+ messages: {
135
+ notInstalled: "'{{packageName}}' is declared in app.json \u2192 expo.plugins but is not installed in package.json."
136
+ }
137
+ },
138
+ create(context) {
139
+ const projectRoot = findProjectRoot(context.filename);
140
+ const declaredPlugins = getPluginsFromAppJson(projectRoot);
141
+ const installedDeps = getInstalledDeps(projectRoot);
142
+ return {
143
+ Program(node) {
144
+ for (const pkg of declaredPlugins) {
145
+ if (!KNOWN_CONFIG_PLUGIN_PACKAGES.has(pkg)) continue;
146
+ if (installedDeps.has(pkg)) continue;
147
+ context.report({
148
+ node,
149
+ messageId: "notInstalled",
150
+ data: { packageName: pkg }
151
+ });
152
+ }
153
+ }
154
+ };
155
+ }
156
+ };
157
+ var plugin = {
158
+ meta: { name: "expo-unused-config-plugin" },
159
+ rules: { "no-unused-expo-plugin": noUnusedExpoPluginRule }
160
+ };
161
+ var no_unused_expo_plugin_default = plugin;
162
+ module.exports = module.exports.default;
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") {
10
+ for (let key of __getOwnPropNames(from))
11
+ if (!__hasOwnProp.call(to, key) && key !== except)
12
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
13
+ }
14
+ return to;
15
+ };
16
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
17
+ // If the importer is in node compatibility mode or this is not an ESM
18
+ // file that has been converted to a CommonJS file using a Babel-
19
+ // compatible transform (i.e. "__esModule" has not been set), then set
20
+ // "default" to the CommonJS "module.exports" for node compatibility.
21
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
22
+ mod
23
+ ));
24
+ var ExpoBlur = __toESM(require("expo-blur"));
25
+ var import_nativewind = require("nativewind");
26
+ if (ExpoBlur.BlurView) (0, import_nativewind.cssInterop)(ExpoBlur.BlurView, { className: "style" });
27
+ if (ExpoBlur.BlurTargetView) (0, import_nativewind.cssInterop)(ExpoBlur.BlurTargetView, { className: "style" });
28
+ module.exports = ExpoBlur;
29
+ //# sourceMappingURL=expo-blur-stub.js.map