miaoda-expo-devkit 0.1.1-beta.99 → 0.1.1-dev.development-build.2

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 (48) hide show
  1. package/README.md +163 -111
  2. package/dist/babel/plugin-lucide-react-native.js +185 -185
  3. package/dist/cli/lint.js +317 -309
  4. package/dist/index.d.mts +1 -110
  5. package/dist/index.d.ts +1 -110
  6. package/dist/index.js +0 -159
  7. package/dist/index.mjs +0 -132
  8. package/dist/metro.d.mts +25 -5
  9. package/dist/metro.d.ts +25 -5
  10. package/dist/metro.js +49 -18
  11. package/dist/metro.mjs +50 -20
  12. package/dist/rules/no-bare-web-crypto.js +235 -0
  13. package/dist/rules/no-expo-audio-compat.js +90 -90
  14. package/dist/rules/no-expo-file-system-compat.js +2130 -0
  15. package/dist/rules/no-expo-video-compat.js +90 -90
  16. package/dist/rules/no-lucide-star-import.js +78 -0
  17. package/dist/rules/no-sentry-default-import.js +83 -0
  18. package/dist/rules/no-typeof-window-check.js +85 -0
  19. package/dist/stubs/entry-inject.js +0 -2
  20. package/dist/stubs/expo-native-wechat-stub.js +116 -0
  21. package/dist/stubs/expo-router-entry-native-stub.js +4 -0
  22. package/dist/stubs/i18n/en.js +16 -1
  23. package/dist/stubs/i18n/zh.js +16 -1
  24. package/dist/stubs/logbox-control.js +9 -0
  25. package/dist/stubs/screenshot-control.js +1 -1
  26. package/dist/stubs/sentry-react-native-stub.js +15 -180
  27. package/oxlint-config.json +20 -5
  28. package/package.json +65 -5
  29. package/pnpm-patches/@expo__cli@55.0.16-55.0.22.patch +712 -0
  30. package/pnpm-patches/@expo__cli@55.0.16.patch +218 -0
  31. package/pnpm-patches/@expo__cli@55.0.17.patch +218 -0
  32. package/pnpm-patches/@expo__cli@55.0.18.patch +218 -0
  33. package/pnpm-patches/@expo__cli@55.0.19.patch +218 -0
  34. package/pnpm-patches/@expo__cli@55.0.20.patch +218 -0
  35. package/pnpm-patches/@expo__cli@55.0.21.patch +218 -0
  36. package/pnpm-patches/@expo__cli@55.0.22.patch +218 -0
  37. package/pnpm-patches/@shopify__react-native-skia@2.4.18.patch +14 -0
  38. package/pnpm-patches/expo-modules-core@55.0.15.patch +21 -0
  39. package/pnpm-patches/expo@55.0.6.patch +283 -0
  40. package/pnpm-patches/metro-file-map@0.83.3.patch +28 -0
  41. package/pnpm-patches/metro-runtime@0.83.3.patch +17 -0
  42. package/pnpm-patches/react-native-css-interop@0.2.6.patch +12 -0
  43. package/pnpm-patches/react-native-reanimated@4.2.1.patch +53 -0
  44. package/pnpm-patches/react-native-worklets@0.7.2.patch +91 -0
  45. package/pnpm-patches/react-native-worklets@0.7.4.patch +91 -0
  46. package/pnpm-patches/react-native@0.83.2.patch +384 -0
  47. package/pnpmfile.cjs +251 -0
  48. package/dist/stubs/preview-control.js +0 -60
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/rules/no-sentry-default-import.ts
21
+ var no_sentry_default_import_exports = {};
22
+ __export(no_sentry_default_import_exports, {
23
+ default: () => no_sentry_default_import_default
24
+ });
25
+ module.exports = __toCommonJS(no_sentry_default_import_exports);
26
+ var SENTRY_REACT_NATIVE = "@sentry/react-native";
27
+ function isDefaultBinding(name) {
28
+ return name.type === "Identifier" && name.name === "default" || name.type === "Literal" && name.value === "default";
29
+ }
30
+ var noSentryDefaultImportRule = {
31
+ meta: {
32
+ type: "problem",
33
+ docs: {
34
+ description: "Disallow default imports from '@sentry/react-native' \u2014 the package has no default export, so the binding is undefined in production builds and Sentry.init() crashes the root layout (full white screen on Web)."
35
+ },
36
+ schema: [],
37
+ messages: {
38
+ unsupportedImport: "Default import from '@sentry/react-native' resolves to undefined in production \u2014 the package only has named exports, and DevKit's dev-only CJS stub masks this in development. Use a namespace import instead: import * as Sentry from '@sentry/react-native'.",
39
+ unsupportedReExport: "Re-exporting 'default' from '@sentry/react-native' does not work \u2014 the package has no default export, so the binding is undefined in production. Re-export named APIs instead: export { init, wrap } from '@sentry/react-native'."
40
+ }
41
+ },
42
+ create(context) {
43
+ return {
44
+ // 拦截 `import Sentry from '@sentry/react-native'`
45
+ // 以及 `import { default as Sentry } from '@sentry/react-native'`(等价写法)
46
+ ImportDeclaration(node) {
47
+ if (node.source.value !== SENTRY_REACT_NATIVE) return;
48
+ for (const spec of node.specifiers) {
49
+ if (spec.type === "ImportDefaultSpecifier") {
50
+ context.report({
51
+ node: spec,
52
+ messageId: "unsupportedImport"
53
+ });
54
+ } else if (spec.type === "ImportSpecifier" && isDefaultBinding(spec.imported)) {
55
+ context.report({
56
+ node: spec,
57
+ messageId: "unsupportedImport"
58
+ });
59
+ }
60
+ }
61
+ },
62
+ // 拦截 `export { default as Sentry } from '@sentry/react-native'`
63
+ ExportNamedDeclaration(node) {
64
+ if (!node.source || node.source.value !== SENTRY_REACT_NATIVE) return;
65
+ for (const spec of node.specifiers) {
66
+ if (spec.type === "ExportSpecifier" && // ExportSpecifier.local 指向被导出的源绑定,'default' 即默认导出
67
+ isDefaultBinding(spec.local)) {
68
+ context.report({
69
+ node: spec,
70
+ messageId: "unsupportedReExport"
71
+ });
72
+ }
73
+ }
74
+ }
75
+ };
76
+ }
77
+ };
78
+ var plugin = {
79
+ meta: { name: "sentry-rn" },
80
+ rules: { "no-sentry-default-import": noSentryDefaultImportRule }
81
+ };
82
+ var no_sentry_default_import_default = plugin;
83
+ module.exports = module.exports.default;
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/rules/no-typeof-window-check.ts
21
+ var no_typeof_window_check_exports = {};
22
+ __export(no_typeof_window_check_exports, {
23
+ default: () => no_typeof_window_check_default
24
+ });
25
+ module.exports = __toCommonJS(no_typeof_window_check_exports);
26
+ var SNIFF_GLOBALS = /* @__PURE__ */ new Set(["window", "document"]);
27
+ var HOST_GLOBALS = /* @__PURE__ */ new Set(["global", "globalThis"]);
28
+ var EQUALITY_OPERATORS = /* @__PURE__ */ new Set(["===", "!==", "==", "!="]);
29
+ var WEB_ONLY_FILE = /\.web\.[jt]sx?$/;
30
+ function sniffedGlobalName(node) {
31
+ if (!node) return null;
32
+ if (node.type === "Identifier" && node.name && SNIFF_GLOBALS.has(node.name)) {
33
+ return node.name;
34
+ }
35
+ if (node.type === "MemberExpression" && !node.computed && node.object?.type === "Identifier" && node.object.name !== void 0 && HOST_GLOBALS.has(node.object.name) && node.property?.type === "Identifier" && node.property.name !== void 0 && SNIFF_GLOBALS.has(node.property.name)) {
36
+ return node.property.name;
37
+ }
38
+ return null;
39
+ }
40
+ function typeofSniffedGlobal(node) {
41
+ if (!node || node.type !== "UnaryExpression" || node.operator !== "typeof") return null;
42
+ return sniffedGlobalName(node.argument);
43
+ }
44
+ var noTypeofWindowCheckRule = {
45
+ meta: {
46
+ type: "problem",
47
+ docs: {
48
+ description: "Disallow typeof window/document checks for platform detection; they are unreliable in React Native and cause runtime crashes on native."
49
+ },
50
+ schema: [],
51
+ messages: {
52
+ unreliableEnvCheck: "'typeof {{name}}' cannot detect the browser in React Native \u2014 RN sets global.window = global (and some libraries install incomplete window/document shims), so this check also passes on native, and browser-only APIs will crash at runtime. Use Platform.OS from 'react-native' or process.env.EXPO_OS === 'web' instead."
53
+ }
54
+ },
55
+ create(context) {
56
+ const isWebOnlyFile = typeof context.filename === "string" && WEB_ONLY_FILE.test(context.filename);
57
+ return {
58
+ BinaryExpression(node) {
59
+ if (isWebOnlyFile) return;
60
+ const binary = node;
61
+ if (!binary.operator || !EQUALITY_OPERATORS.has(binary.operator)) return;
62
+ for (const [typeofSide, otherSide] of [
63
+ [binary.left, binary.right],
64
+ [binary.right, binary.left]
65
+ ]) {
66
+ const name = typeofSniffedGlobal(typeofSide);
67
+ if (!name) continue;
68
+ if (otherSide?.type !== "Literal" || typeof otherSide.value !== "string") continue;
69
+ context.report({
70
+ node: typeofSide,
71
+ messageId: "unreliableEnvCheck",
72
+ data: { name }
73
+ });
74
+ return;
75
+ }
76
+ }
77
+ };
78
+ }
79
+ };
80
+ var plugin = {
81
+ meta: { name: "no-typeof-window-check" },
82
+ rules: { "no-typeof-window-check": noTypeofWindowCheckRule }
83
+ };
84
+ var no_typeof_window_check_default = plugin;
85
+ module.exports = module.exports.default;
@@ -4,12 +4,10 @@ var import_lgui_control = require("./lgui-control");
4
4
  var import_css_control = require("./css-control");
5
5
  var import_router_control = require("./router-control");
6
6
  var import_screenshot_control = require("./screenshot-control");
7
- var import_preview_control = require("./preview-control");
8
7
  globalThis.__DEVKIT_INJECTED__ = true;
9
8
  (0, import_hmr_control.setupHMRMessageControl)();
10
9
  (0, import_lgui_control.setupLGUIMessageControl)();
11
10
  (0, import_css_control.setupCSSInjectionControl)();
12
11
  (0, import_router_control.setupRouterControl)();
13
12
  (0, import_screenshot_control.setupScreenshotControl)();
14
- (0, import_preview_control.setupPreviewControl)();
15
13
  //# sourceMappingURL=entry-inject.js.map
@@ -0,0 +1,116 @@
1
+ "use strict";
2
+ var import_react = require("react");
3
+ var import_react_native = require("react-native");
4
+ var import_web_stub_dialog = require("./web-stub-dialog");
5
+ var import_i18n = require("./i18n");
6
+ if (import_react_native.Platform.OS !== "web") {
7
+ module.exports = require("expo-native-wechat");
8
+ } else {
9
+ let showWechatUnavailable = function(title, lines) {
10
+ (0, import_web_stub_dialog.showWebStubDialog)({
11
+ title,
12
+ details: lines
13
+ });
14
+ }, rejectUnavailable = function(title, lines) {
15
+ showWechatUnavailable(title, lines);
16
+ return Promise.reject(new Error((0, import_i18n.t)("wechat.unavailable")));
17
+ };
18
+ var showWechatUnavailable2 = showWechatUnavailable, rejectUnavailable2 = rejectUnavailable;
19
+ const NativeWechatShareScene = {
20
+ WXSceneSession: 0,
21
+ WXSceneTimeline: 1,
22
+ WXSceneFavorite: 2
23
+ };
24
+ const NativeWechatMiniprogramType = {
25
+ WXMiniProgramTypeRelease: 0,
26
+ WXMiniProgramTypeTest: 1,
27
+ WXMiniProgramTypePreview: 2
28
+ };
29
+ const NativeWechatConstants = {
30
+ ...NativeWechatShareScene,
31
+ ...NativeWechatMiniprogramType
32
+ };
33
+ const checkUniversalLinkReady = async () => ({
34
+ suggestion: (0, import_i18n.t)("wechat.checkUniversalLinkReadyDetail"),
35
+ errorInfo: ""
36
+ });
37
+ const registerApp = async (request) => {
38
+ if (!request?.appid) {
39
+ console.warn("[expo-native-wechat-stub] registerApp: appid \u4E3A\u7A7A\uFF0CDevelopment Build \u771F\u673A\u4E0A\u4F1A\u6CE8\u518C\u5931\u8D25");
40
+ }
41
+ if (import_react_native.Platform.OS === "ios" && !request?.universalLink) {
42
+ console.warn("[expo-native-wechat-stub] registerApp: iOS \u7F3A\u5C11 universalLink\uFF0CDevelopment Build \u771F\u673A\u4E0A\u652F\u4ED8/\u5206\u4EAB\u4F1A\u5931\u8D25");
43
+ }
44
+ return true;
45
+ };
46
+ const isWechatInstalled = async () => false;
47
+ const useWechatInstalled = () => {
48
+ const [hasInstalledWechat] = (0, import_react.useState)(false);
49
+ return hasInstalledWechat;
50
+ };
51
+ const sendAuthRequest = async (request) => {
52
+ return rejectUnavailable((0, import_i18n.t)("wechat.sendAuthRequest"), [`request: ${request ? JSON.stringify(request) : (0, import_i18n.t)("common.none")}`]);
53
+ };
54
+ const shareText = async (request) => {
55
+ return rejectUnavailable((0, import_i18n.t)("wechat.shareText"), [`text: ${JSON.stringify(request?.text)}`]);
56
+ };
57
+ const shareImage = async (request) => {
58
+ return rejectUnavailable((0, import_i18n.t)("wechat.shareImage"), [`src: ${JSON.stringify(request?.src)}`]);
59
+ };
60
+ const shareVideo = async (request) => {
61
+ return rejectUnavailable((0, import_i18n.t)("wechat.shareVideo"), [`videoUrl: ${JSON.stringify(request?.videoUrl)}`]);
62
+ };
63
+ const shareWebpage = async (request) => {
64
+ return rejectUnavailable((0, import_i18n.t)("wechat.shareWebpage"), [`webpageUrl: ${JSON.stringify(request?.webpageUrl)}`]);
65
+ };
66
+ const shareMiniProgram = async (request) => {
67
+ return rejectUnavailable((0, import_i18n.t)("wechat.shareMiniProgram"), [`userName: ${JSON.stringify(request?.userName)}`, `path: ${JSON.stringify(request?.path)}`]);
68
+ };
69
+ const requestPayment = async (request) => {
70
+ return rejectUnavailable((0, import_i18n.t)("wechat.requestPayment"), [`partnerId: ${JSON.stringify(request?.partnerId)}`, `prepayId: ${JSON.stringify(request?.prepayId)}`]);
71
+ };
72
+ const requestSubscribeMessage = async (request) => {
73
+ return rejectUnavailable((0, import_i18n.t)("wechat.requestSubscribeMessage"), [`templateId: ${JSON.stringify(request?.templateId)}`]);
74
+ };
75
+ const openCustomerService = async (request) => {
76
+ return rejectUnavailable((0, import_i18n.t)("wechat.openCustomerService"), [`corpid: ${JSON.stringify(request?.corpid)}`]);
77
+ };
78
+ const launchMiniProgram = async (request) => {
79
+ return rejectUnavailable((0, import_i18n.t)("wechat.launchMiniProgram"), [`userName: ${JSON.stringify(request?.userName)}`, `path: ${JSON.stringify(request?.path)}`]);
80
+ };
81
+ const appPureSignContract = async (request) => {
82
+ return rejectUnavailable((0, import_i18n.t)("wechat.appPureSignContract"), [`preEntrustwebId: ${JSON.stringify(request?.preEntrustwebId)}`]);
83
+ };
84
+ const requestMerchantTransfer = async (request) => {
85
+ return rejectUnavailable((0, import_i18n.t)("wechat.requestMerchantTransfer"), [`mchId: ${JSON.stringify(request?.mchId)}`]);
86
+ };
87
+ const api = {
88
+ checkUniversalLinkReady,
89
+ registerApp,
90
+ isWechatInstalled,
91
+ useWechatInstalled,
92
+ sendAuthRequest,
93
+ shareText,
94
+ shareImage,
95
+ shareVideo,
96
+ shareWebpage,
97
+ shareMiniProgram,
98
+ requestPayment,
99
+ requestSubscribeMessage,
100
+ openCustomerService,
101
+ launchMiniProgram,
102
+ appPureSignContract,
103
+ requestMerchantTransfer,
104
+ NativeWechatConstants,
105
+ NativeWechatShareScene,
106
+ NativeWechatMiniprogramType
107
+ };
108
+ const noop = async () => void 0;
109
+ module.exports = new Proxy(api, {
110
+ get(target, key) {
111
+ if (key in target) return target[key];
112
+ return noop;
113
+ }
114
+ });
115
+ }
116
+ //# sourceMappingURL=expo-native-wechat-stub.js.map
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ var import_logbox_control = require("./logbox-control");
3
+ var import_entry_classic = require("expo-router/entry-classic");
4
+ //# sourceMappingURL=expo-router-entry-native-stub.js.map
@@ -186,7 +186,22 @@ const en = {
186
186
  "haptics.webUnsupported": "Haptic feedback is not supported on Web, skipped",
187
187
  "haptics.styleMustBeEnum": "style must be one of ImpactFeedbackStyle enum values ({valid}), received: {received}",
188
188
  "haptics.typeMustBeEnum": "type must be one of NotificationFeedbackType enum values ({valid}), received: {received}",
189
- "validation.uriMustStartWithHttp": "uri must start with http:// or https://"
189
+ "validation.uriMustStartWithHttp": "uri must start with http:// or https://",
190
+ // ─── expo-native-wechat-stub ────────────────────────────────────────────────
191
+ "wechat.unavailable": "WeChat Pay is not available in this environment. Export the app and install it on a phone to use it.",
192
+ "wechat.checkUniversalLinkReadyDetail": "Universal Link check is not supported on Web",
193
+ "wechat.sendAuthRequest": "WeChat Auth Login",
194
+ "wechat.shareText": "Share Text",
195
+ "wechat.shareImage": "Share Image",
196
+ "wechat.shareVideo": "Share Video",
197
+ "wechat.shareWebpage": "Share Webpage",
198
+ "wechat.shareMiniProgram": "Share Mini Program",
199
+ "wechat.requestPayment": "Request WeChat Payment",
200
+ "wechat.requestSubscribeMessage": "Request Subscribe Message",
201
+ "wechat.openCustomerService": "Open Customer Service",
202
+ "wechat.launchMiniProgram": "Launch Mini Program",
203
+ "wechat.appPureSignContract": "WeChat Pure Sign Contract",
204
+ "wechat.requestMerchantTransfer": "WeChat Merchant Transfer"
190
205
  };
191
206
  // Annotate the CommonJS export names for ESM import in node:
192
207
  0 && (module.exports = {
@@ -189,7 +189,22 @@ const zh = {
189
189
  "haptics.webUnsupported": "Web \u5E73\u53F0\u4E0D\u652F\u6301\u89E6\u89C9\u53CD\u9988\uFF0C\u5DF2\u8DF3\u8FC7",
190
190
  "haptics.styleMustBeEnum": "style \u5FC5\u987B\u662F ImpactFeedbackStyle \u679A\u4E3E\u503C\u4E4B\u4E00\uFF08{valid}\uFF09\uFF0C\u6536\u5230: {received}",
191
191
  "haptics.typeMustBeEnum": "type \u5FC5\u987B\u662F NotificationFeedbackType \u679A\u4E3E\u503C\u4E4B\u4E00\uFF08{valid}\uFF09\uFF0C\u6536\u5230: {received}",
192
- "validation.uriMustStartWithHttp": "uri \u5FC5\u987B\u4EE5 http:// \u6216 https:// \u5F00\u5934"
192
+ "validation.uriMustStartWithHttp": "uri \u5FC5\u987B\u4EE5 http:// \u6216 https:// \u5F00\u5934",
193
+ // ─── expo-native-wechat-stub ────────────────────────────────────────────────
194
+ "wechat.unavailable": "\u5FAE\u4FE1\u652F\u4ED8\u65E0\u6CD5\u5728\u5F53\u524D\u73AF\u5883\u4F7F\u7528\uFF0C\u9700\u5C06\u5E94\u7528\u5BFC\u51FA\u5E76\u5B89\u88C5\u5230\u624B\u673A\u540E\u624D\u80FD\u4F7F\u7528",
195
+ "wechat.checkUniversalLinkReadyDetail": "Web \u5E73\u53F0\u4E0D\u652F\u6301 Universal Link \u6821\u9A8C",
196
+ "wechat.sendAuthRequest": "\u5FAE\u4FE1\u6388\u6743\u767B\u5F55",
197
+ "wechat.shareText": "\u5206\u4EAB\u6587\u5B57",
198
+ "wechat.shareImage": "\u5206\u4EAB\u56FE\u7247",
199
+ "wechat.shareVideo": "\u5206\u4EAB\u89C6\u9891",
200
+ "wechat.shareWebpage": "\u5206\u4EAB\u7F51\u9875",
201
+ "wechat.shareMiniProgram": "\u5206\u4EAB\u5C0F\u7A0B\u5E8F",
202
+ "wechat.requestPayment": "\u53D1\u8D77\u5FAE\u4FE1\u652F\u4ED8",
203
+ "wechat.requestSubscribeMessage": "\u8BF7\u6C42\u8BA2\u9605\u6D88\u606F",
204
+ "wechat.openCustomerService": "\u6253\u5F00\u5FAE\u4FE1\u5BA2\u670D",
205
+ "wechat.launchMiniProgram": "\u8DF3\u8F6C\u5C0F\u7A0B\u5E8F",
206
+ "wechat.appPureSignContract": "\u5FAE\u4FE1\u514D\u5BC6\u7B7E\u7EA6",
207
+ "wechat.requestMerchantTransfer": "\u5FAE\u4FE1\u5546\u5BB6\u8F6C\u8D26"
193
208
  };
194
209
  // Annotate the CommonJS export names for ESM import in node:
195
210
  0 && (module.exports = {
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ var import_react_native = require("react-native");
3
+ const DISABLED_MARKER = "__MIAODA_DEVKIT_LOGBOX_NOTIFICATIONS_DISABLED__";
4
+ const runtime = globalThis;
5
+ if (!runtime[DISABLED_MARKER]) {
6
+ import_react_native.LogBox.ignoreAllLogs(true);
7
+ runtime[DISABLED_MARKER] = true;
8
+ }
9
+ //# sourceMappingURL=logbox-control.js.map
@@ -24,7 +24,7 @@ __export(screenshot_control_exports, {
24
24
  });
25
25
  module.exports = __toCommonJS(screenshot_control_exports);
26
26
 
27
- // ../../node_modules/.pnpm/@zumer+snapdom@2.12.9/node_modules/@zumer/snapdom/dist/snapdom.mjs
27
+ // ../../node_modules/@zumer/snapdom/dist/snapdom.mjs
28
28
  var Ho = Object.defineProperty;
29
29
  var q = (t, e) => () => (t && (e = t(t = 0)), e);
30
30
  var Rt = (t, e) => {
@@ -24,193 +24,28 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
24
24
 
25
25
  // src/stubs/sentry-react-native-stub.ts
26
26
  var RealSentry = __toESM(require("@sentry/react-native"));
27
-
28
- // src/capture.ts
29
- var import_stacktrace_parser = require("stacktrace-parser");
27
+ var import_core = require("@sentry/core");
30
28
  var import_react_native = require("react-native");
31
- var MetroSymbolicator = class _MetroSymbolicator {
32
- constructor({ baseUrl } = {}) {
33
- this.baseUrl = baseUrl ?? _MetroSymbolicator._getDefaultBaseUrl();
34
- }
35
- /**
36
- * 从 NativeModules.SourceCode.scriptURL 推断 Metro server base URL。
37
- * web 平台使用相对路径;native 回退到 localhost:8081。
38
- */
39
- static _getDefaultBaseUrl() {
40
- try {
41
- const scriptURL = import_react_native.NativeModules?.SourceCode?.scriptURL;
42
- if (scriptURL) {
43
- const url = new URL(scriptURL);
44
- return `${url.protocol}//${url.host}`;
45
- }
46
- } catch (_) {
47
- }
48
- return import_react_native.Platform.OS === "web" ? "" : "http://localhost:8081";
49
- }
50
- /**
51
- * 解析 Error.stack 字符串为 Metro 所需的帧数组。
52
- *
53
- * 使用 stacktrace-parser 覆盖各 JS 引擎的格式:
54
- * V8/Node.js/Hermes(新):at methodName (url:line:col)
55
- * Gecko/Firefox/Hermes(旧):methodName@url:line:col
56
- * JavaScriptCore(iOS):methodName@url:line:col
57
- *
58
- * 无法符号化的帧(file 或 lineNumber 为 null)会被过滤掉。
59
- */
60
- parseErrorStack(stack) {
61
- return (0, import_stacktrace_parser.parse)(stack).filter(
62
- (f) => f.file != null && f.lineNumber != null
63
- ).map((f) => ({
64
- file: f.file,
65
- lineNumber: f.lineNumber,
66
- column: f.column != null ? f.column - 1 : 0,
67
- methodName: f.methodName === "<unknown>" ? "(anonymous)" : f.methodName
68
- }));
69
- }
70
- /**
71
- * 将帧列表发送到 Metro /symbolicate,返回符号化后的帧数组。
72
- */
73
- async symbolicate(stack) {
74
- if (stack.length === 0) return null;
75
- const endpoint = `${this.baseUrl}/symbolicate`;
76
- try {
77
- const res = await fetch(endpoint, {
78
- method: "POST",
79
- headers: { "Content-Type": "application/json" },
80
- body: JSON.stringify({ stack })
81
- });
82
- if (!res.ok) {
83
- console.warn(`[SentryCapture] /symbolicate returned ${res.status}`);
84
- return null;
85
- }
86
- const data = await res.json();
87
- return data.stack ?? null;
88
- } catch (e) {
89
- console.warn("[SentryCapture] symbolication failed:", e?.message ?? e);
90
- return null;
91
- }
92
- }
93
- };
94
- var SentryCapture = class {
95
- constructor({ onError, onNetwork, symbolicator } = {}) {
96
- this.onError = onError;
97
- this.onNetwork = onNetwork;
98
- this.symbolicator = symbolicator ?? new MetroSymbolicator();
99
- this.beforeSend = this.beforeSend.bind(this);
100
- this.beforeBreadcrumb = this.beforeBreadcrumb.bind(this);
101
- }
102
- /**
103
- * Sentry beforeSend hook。
104
- * 优先使用原始 Error.stack 进行符号化;若无法获取则回退到 Sentry 事件帧。
105
- * 符号化完成后触发 onError 回调,原样返回 event。
106
- */
107
- async beforeSend(event, hint) {
108
- globalThis.__SENTRY_LAST_RAW__ = { event, hint };
109
- const message = event.exception?.values?.[0]?.value ?? event.message ?? "(unknown)";
110
- let symbolicatedFrames = null;
111
- const originalException = hint?.originalException;
112
- const rawStack = originalException instanceof Error && typeof originalException.stack === "string" ? originalException.stack : null;
113
- if (rawStack !== null) {
114
- const frames = this.symbolicator.parseErrorStack(rawStack);
115
- if (frames.length > 0) {
116
- symbolicatedFrames = await this.symbolicator.symbolicate(frames);
117
- }
118
- }
119
- if (symbolicatedFrames === null) {
120
- const sentryFrames = event.exception?.values?.[0]?.stacktrace?.frames ?? [];
121
- const mapped = sentryFrames.filter(
122
- (f) => f.filename != null && f.lineno != null
123
- ).map(
124
- (f) => ({
125
- file: f.filename,
126
- lineNumber: f.lineno,
127
- column: f.colno ?? 0,
128
- methodName: f.function ?? "(anonymous)"
129
- })
130
- );
131
- if (mapped.length > 0) {
132
- symbolicatedFrames = await this.symbolicator.symbolicate(mapped);
133
- }
134
- }
135
- const componentStack = event.contexts?.react?.componentStack ?? null;
136
- const mechanismType = event.exception?.values?.[0]?.mechanism?.type ?? null;
137
- this.onError?.({ message, symbolicatedFrames, componentStack, mechanismType });
138
- return event;
139
- }
140
- /**
141
- * Sentry beforeBreadcrumb hook。
142
- * 识别 HTTP 类型的 breadcrumb,触发 onNetwork 回调,原样返回 breadcrumb。
143
- */
144
- beforeBreadcrumb(breadcrumb, _hint) {
145
- if (breadcrumb.type === "http") {
146
- const data = breadcrumb.data;
147
- this.onNetwork?.({
148
- method: data?.method ?? null,
149
- url: data?.url ?? null,
150
- statusCode: data?.status_code ?? null
151
- });
152
- }
153
- return breadcrumb;
154
- }
155
- };
156
-
157
- // src/stubs/sentry-react-native-stub.ts
158
- function getParentOrigin() {
159
- try {
160
- const w = globalThis.window;
161
- if (!w) return "*";
162
- return new URLSearchParams(w.location.search).get("parentOrigin") || "*";
163
- } catch {
164
- return "*";
165
- }
29
+ var SANDBOX_MARKER = /* @__PURE__ */ Symbol.for("vite-sandbox.expo-browser-observability.v2");
30
+ var FALLBACK_DSN = process.env["INJECT_SENTRY_DSN"] ?? "https://stubPublicKey@o0.ingest.sentry.io/0";
31
+ function reportVersionMismatch(expected, actual) {
32
+ const message = `Sentry SDK \u7248\u672C\u4E0D\u4E00\u81F4\uFF1Asandbox=${expected}\uFF0C@sentry/react-native core=${actual || "unknown"}\u3002\u89C2\u6D4B\u4E8B\u4EF6\u53EF\u80FD\u9759\u9ED8\u4E22\u5931\u3002`;
33
+ console.error(`[miaoda-expo-devkit] ${message}`);
166
34
  }
167
- var OVERRIDE_DSN = process.env["INJECT_SENTRY_DSN"] ?? "https://stubPublicKey@o0.ingest.sentry.io/0";
168
- var _capture = new SentryCapture({
169
- onError(info) {
170
- console.warn("[SentryStub] \u6355\u83B7\u5230\u9519\u8BEF\uFF1A", info.message);
171
- if (info.symbolicatedFrames?.length) {
172
- const top = info.symbolicatedFrames[0];
173
- console.warn(` at ${top.methodName} (${top.file}:${top.lineNumber}:${top.column})`);
174
- }
175
- const w = globalThis.window;
176
- if (w !== void 0 && w !== w.parent) {
177
- w.parent.postMessage(
178
- {
179
- type: "GLOBAL_ERROR",
180
- error: {
181
- message: info.message,
182
- symbolicatedFrames: info.symbolicatedFrames,
183
- componentStack: info.componentStack,
184
- mechanismType: info.mechanismType
185
- }
186
- },
187
- getParentOrigin()
188
- );
189
- }
190
- }
191
- });
192
35
  var stub = {
193
36
  ...RealSentry,
194
37
  /**
195
- * 拦截 init():替换 DSN 并注入内置捕获器。
196
- * 调用方传入的 beforeSend / beforeBreadcrumb 在内置捕获器之后串联执行。
38
+ * Native 保留应用初始化;独立 Web 使用安全 DSN;sandbox Web 已由前置运行时
39
+ * 初始化,因此这里只校验版本并阻止第二次初始化。
197
40
  */
198
41
  init: ((options) => {
199
- const upstreamBeforeSend = options?.beforeSend;
200
- const upstreamBeforeBreadcrumb = options?.beforeBreadcrumb;
201
- const initOptions = {
202
- ...options,
203
- dsn: OVERRIDE_DSN,
204
- async beforeSend(event, hint) {
205
- const processed = await _capture.beforeSend(event, hint);
206
- return upstreamBeforeSend ? await upstreamBeforeSend(processed, hint) : processed;
207
- },
208
- beforeBreadcrumb(breadcrumb, hint) {
209
- const processed = _capture.beforeBreadcrumb(breadcrumb, hint);
210
- return upstreamBeforeBreadcrumb ? upstreamBeforeBreadcrumb(processed, hint) : processed;
211
- }
212
- };
213
- return RealSentry.init(initOptions);
42
+ if (import_react_native.Platform.OS !== "web") return RealSentry.init(options);
43
+ const sandboxVersion = globalThis[SANDBOX_MARKER];
44
+ if (typeof sandboxVersion === "string") {
45
+ if (sandboxVersion !== import_core.SDK_VERSION) reportVersionMismatch(sandboxVersion, import_core.SDK_VERSION);
46
+ return void 0;
47
+ }
48
+ return RealSentry.init({ ...options, dsn: FALLBACK_DSN });
214
49
  })
215
50
  };
216
51
  module.exports = stub;
@@ -19,7 +19,12 @@
19
19
  { "name": "expo-notifications-assets", "specifier": "miaoda-expo-devkit/rules/no-missing-notification-asset" },
20
20
  { "name": "expo-config-value", "specifier": "miaoda-expo-devkit/rules/no-invalid-expo-config-value" },
21
21
  { "name": "expo-notifications-config", "specifier": "miaoda-expo-devkit/rules/no-invalid-notification-config" },
22
- { "name": "gifted-charts-linear-gradient", "specifier": "miaoda-expo-devkit/rules/no-gifted-charts-missing-linear-gradient" }
22
+ { "name": "gifted-charts-linear-gradient", "specifier": "miaoda-expo-devkit/rules/no-gifted-charts-missing-linear-gradient" },
23
+ { "name": "rn-web-env", "specifier": "miaoda-expo-devkit/rules/no-typeof-window-check" },
24
+ { "name": "lucide-icons", "specifier": "miaoda-expo-devkit/rules/no-lucide-star-import" },
25
+ { "name": "web-crypto", "specifier": "miaoda-expo-devkit/rules/no-bare-web-crypto" },
26
+ { "name": "sentry-rn", "specifier": "miaoda-expo-devkit/rules/no-sentry-default-import" },
27
+ { "name": "expo-file-system-compat", "specifier": "miaoda-expo-devkit/rules/no-expo-file-system-compat" }
23
28
  ],
24
29
 
25
30
  "categories": {
@@ -45,6 +50,11 @@
45
50
  "expo-config-value/no-invalid-expo-config-value": "error",
46
51
  "expo-notifications-config/no-invalid-notification-config": "error",
47
52
  "gifted-charts-linear-gradient/no-gifted-charts-missing-linear-gradient": "error",
53
+ "rn-web-env/no-typeof-window-check": "error",
54
+ "lucide-icons/no-lucide-star-import": "error",
55
+ "web-crypto/no-bare-web-crypto": "error",
56
+ "sentry-rn/no-sentry-default-import": "error",
57
+ "expo-file-system-compat/no-expo-file-system-compat": "error",
48
58
 
49
59
  "expo/no-dynamic-env-var": "error",
50
60
  "expo/no-env-var-destructuring": "error",
@@ -63,10 +73,11 @@
63
73
  },
64
74
 
65
75
  "ignorePatterns": [
66
- "metro.config.js",
67
- "babel.config.js",
68
- ".pnpmfile.cjs",
69
76
  "output/**",
77
+ "packages/expo-dev-client/**",
78
+ "packages/expo-dev-launcher/**",
79
+ "packages/expo-dev-menu/**",
80
+ "packages/expo-dev-menu-interface/**",
70
81
  "supabase/**",
71
82
  "src/components/ui/**",
72
83
  ".skills/**"
@@ -74,7 +85,11 @@
74
85
 
75
86
  "overrides": [
76
87
  {
77
- "files": ["tailwind.config.js", "**/tailwind.config.js"],
88
+ "files": [
89
+ "*.config.{js,cjs,mjs,ts,cts,mts}",
90
+ "**/*.config.{js,cjs,mjs,ts,cts,mts}",
91
+ ".pnpmfile.cjs"
92
+ ],
78
93
  "env": {
79
94
  "node": true
80
95
  }