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

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.
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+
4
+ // src/cli/lint.ts
5
+ var import_node_child_process = require("child_process");
6
+ var import_node_path = require("path");
7
+ var devkitRoot = (0, import_node_path.resolve)(__dirname, "../..");
8
+ var oxlintConfig = (0, import_node_path.join)(devkitRoot, "oxlint-config.json");
9
+ var biomeConfig = (0, import_node_path.join)(devkitRoot, "biome-config.json");
10
+ var targets = process.argv.slice(2);
11
+ var lintTargets = targets.length > 0 ? targets : ["src/"];
12
+ var failed = false;
13
+ var oxlint = (0, import_node_child_process.spawnSync)("oxlint", ["--config", oxlintConfig, ...lintTargets], {
14
+ stdio: "inherit"
15
+ });
16
+ if ((oxlint.status ?? 1) !== 0) failed = true;
17
+ var biome = (0, import_node_child_process.spawnSync)("biome", ["lint", "--config-path", biomeConfig, ...lintTargets], {
18
+ stdio: "inherit"
19
+ });
20
+ if ((biome.status ?? 1) !== 0) failed = true;
21
+ process.exit(failed ? 1 : 0);
package/dist/metro.d.mts CHANGED
@@ -84,8 +84,8 @@ interface RouteEndpointOptions {
84
84
  * 端点返回格式:
85
85
  * {
86
86
  * "routes": [
87
- * { "title": "首页", "pageId": "/", "pageName": "index", "visible": true, "path": "index.tsx" },
88
- * { "title": "id", "pageId": "/user/[id]", "pageName": "user-[id]", "visible": false, "path": "user/[id].tsx" }
87
+ * { "title": "首页", "pageId": "/", "pageName": "index", "visible": true, "path": "src/app/index.tsx" },
88
+ * { "title": "id", "pageId": "/user/[id]", "pageName": "user-[id]", "visible": false, "path": "src/app/user/[id].tsx" }
89
89
  * ]
90
90
  * }
91
91
  *
package/dist/metro.d.ts CHANGED
@@ -84,8 +84,8 @@ interface RouteEndpointOptions {
84
84
  * 端点返回格式:
85
85
  * {
86
86
  * "routes": [
87
- * { "title": "首页", "pageId": "/", "pageName": "index", "visible": true, "path": "index.tsx" },
88
- * { "title": "id", "pageId": "/user/[id]", "pageName": "user-[id]", "visible": false, "path": "user/[id].tsx" }
87
+ * { "title": "首页", "pageId": "/", "pageName": "index", "visible": true, "path": "src/app/index.tsx" },
88
+ * { "title": "id", "pageId": "/user/[id]", "pageName": "user-[id]", "visible": false, "path": "src/app/user/[id].tsx" }
89
89
  * ]
90
90
  * }
91
91
  *
package/dist/metro.js CHANGED
@@ -44,7 +44,7 @@ var import_path2 = __toESM(require("path"));
44
44
  var import_fs = __toESM(require("fs"));
45
45
  var import_path = __toESM(require("path"));
46
46
  var ROUTE_EXT = /\.(tsx|ts|jsx|js)$/;
47
- function getRoutes(appDir) {
47
+ function getRoutes(appDir, rootDir) {
48
48
  const routes = [];
49
49
  function scan(dir, prefix) {
50
50
  let entries;
@@ -70,17 +70,17 @@ function getRoutes(appDir) {
70
70
  pageId: routePath,
71
71
  pageName: routePath,
72
72
  visible: !isDynamic,
73
- path: import_path.default.relative(appDir, fullPath)
73
+ path: import_path.default.relative(rootDir, fullPath)
74
74
  });
75
75
  }
76
76
  }
77
77
  }
78
78
  scan(appDir, "");
79
- return { routes };
79
+ return { data: routes };
80
80
  }
81
- function createRouteHandler(appDir) {
81
+ function createRouteHandler(appDir, rootDir) {
82
82
  return (_req, res) => {
83
- const routeTree = getRoutes(appDir);
83
+ const routeTree = getRoutes(appDir, rootDir);
84
84
  res.writeHead(200, { "Content-Type": "application/json" });
85
85
  res.end(JSON.stringify(routeTree, null, 2));
86
86
  };
@@ -139,10 +139,11 @@ function withEntryInjection(config, options) {
139
139
  var DEFAULT_ROUTE_ENDPOINT = "/__routes";
140
140
  function withRouteEndpoint(config, options) {
141
141
  const { appDir, endpoint = DEFAULT_ROUTE_ENDPOINT } = options;
142
+ const rootDir = config.projectRoot ?? process.cwd();
142
143
  const upstream = config.server?.enhanceMiddleware ?? null;
143
144
  const enhanceMiddleware = (middleware, metroServer) => {
144
145
  const enhanced = upstream ? upstream(middleware, metroServer) : middleware;
145
- return (0, import_connect.default)().use(enhanced).use(endpoint, createRouteHandler(appDir));
146
+ return (0, import_connect.default)().use(enhanced).use(endpoint, createRouteHandler(appDir, rootDir));
146
147
  };
147
148
  return {
148
149
  ...config,
package/dist/metro.mjs CHANGED
@@ -7,7 +7,7 @@ import path2 from "path";
7
7
  import fs from "fs";
8
8
  import path from "path";
9
9
  var ROUTE_EXT = /\.(tsx|ts|jsx|js)$/;
10
- function getRoutes(appDir) {
10
+ function getRoutes(appDir, rootDir) {
11
11
  const routes = [];
12
12
  function scan(dir, prefix) {
13
13
  let entries;
@@ -33,17 +33,17 @@ function getRoutes(appDir) {
33
33
  pageId: routePath,
34
34
  pageName: routePath,
35
35
  visible: !isDynamic,
36
- path: path.relative(appDir, fullPath)
36
+ path: path.relative(rootDir, fullPath)
37
37
  });
38
38
  }
39
39
  }
40
40
  }
41
41
  scan(appDir, "");
42
- return { routes };
42
+ return { data: routes };
43
43
  }
44
- function createRouteHandler(appDir) {
44
+ function createRouteHandler(appDir, rootDir) {
45
45
  return (_req, res) => {
46
- const routeTree = getRoutes(appDir);
46
+ const routeTree = getRoutes(appDir, rootDir);
47
47
  res.writeHead(200, { "Content-Type": "application/json" });
48
48
  res.end(JSON.stringify(routeTree, null, 2));
49
49
  };
@@ -102,10 +102,11 @@ function withEntryInjection(config, options) {
102
102
  var DEFAULT_ROUTE_ENDPOINT = "/__routes";
103
103
  function withRouteEndpoint(config, options) {
104
104
  const { appDir, endpoint = DEFAULT_ROUTE_ENDPOINT } = options;
105
+ const rootDir = config.projectRoot ?? process.cwd();
105
106
  const upstream = config.server?.enhanceMiddleware ?? null;
106
107
  const enhanceMiddleware = (middleware, metroServer) => {
107
108
  const enhanced = upstream ? upstream(middleware, metroServer) : middleware;
108
- return connect().use(enhanced).use(endpoint, createRouteHandler(appDir));
109
+ return connect().use(enhanced).use(endpoint, createRouteHandler(appDir, rootDir));
109
110
  };
110
111
  return {
111
112
  ...config,
@@ -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
  });
@@ -33,6 +33,20 @@ const THROTTLE_INTERVAL = 8;
33
33
  const THROTTLE_OPTIONS = {
34
34
  edges: ["leading", "trailing"]
35
35
  };
36
+ function isInsideSvgButNotSvgElement(el) {
37
+ const tag = el.tagName.toLowerCase();
38
+ return tag !== "svg" && el.closest("svg") !== null;
39
+ }
40
+ function getTargetElement(el) {
41
+ const tag = el.tagName.toLowerCase();
42
+ if (tag === "html") {
43
+ return null;
44
+ }
45
+ if (isInsideSvgButNotSvgElement(el)) {
46
+ return el.closest("svg");
47
+ }
48
+ return el;
49
+ }
36
50
  function isEditorMessage(data) {
37
51
  return typeof data === "object" && data !== null && typeof data.type === "string" && data.type.startsWith("editor-");
38
52
  }
@@ -124,7 +138,8 @@ class EditorController {
124
138
  * 设置当前悬停元素的 hover 样式
125
139
  */
126
140
  this.onMouseOver = (e) => {
127
- const node = e.target;
141
+ const rawNode = e.target;
142
+ const node = getTargetElement(rawNode);
128
143
  if (!isEditable(node)) return;
129
144
  if (this.hoverNode) {
130
145
  const isActive = this.activeNode === this.hoverNode;
@@ -150,7 +165,8 @@ class EditorController {
150
165
  this.onClick = (e) => {
151
166
  e.stopPropagation();
152
167
  e.preventDefault();
153
- const node = e.target;
168
+ const rawNode = e.target;
169
+ const node = getTargetElement(rawNode);
154
170
  if (!isEditable(node) || this.activeNode === node) return;
155
171
  this.stopObservingActiveNode();
156
172
  this.activeNode && removeActiveAttr(this.activeNode);
@@ -0,0 +1,47 @@
1
+ {
2
+ "plugins": ["typescript", "react"],
3
+ "jsPlugins": [
4
+ "eslint-plugin-expo",
5
+ { "name": "expo-config-plugin", "specifier": "miaoda-expo-devkit/rules/no-undeclared-expo-plugin" },
6
+ { "name": "expo-router", "specifier": "miaoda-expo-devkit/rules/no-unstable-expo-router" },
7
+ { "name": "rn-web", "specifier": "miaoda-expo-devkit/rules/no-rn-alert" },
8
+ { "name": "expo-router-url", "specifier": "miaoda-expo-devkit/rules/no-duplicate-expo-router-url" }
9
+ ],
10
+
11
+ "categories": {
12
+ "correctness": "allow"
13
+ },
14
+
15
+ "rules": {
16
+ "expo-config-plugin/no-undeclared-expo-plugin": "error",
17
+ "expo-router/no-unstable-expo-router": "error",
18
+ "rn-web/no-rn-alert": "error",
19
+ "expo-router-url/no-duplicate-expo-router-url": "error",
20
+
21
+ "expo/no-dynamic-env-var": "error",
22
+ "expo/no-env-var-destructuring": "error",
23
+ "expo/use-dom-exports": "error",
24
+
25
+ "no-undef": "error",
26
+ "use-isnan": "error",
27
+ "valid-typeof": "error",
28
+ "no-dupe-keys": "error",
29
+ "no-duplicate-case": "error",
30
+ "no-dupe-class-members": "error",
31
+
32
+ "react/react-in-jsx-scope": "off",
33
+ "react/jsx-no-duplicate-props": "error",
34
+ "react/jsx-no-undef": "error"
35
+ },
36
+
37
+ "env": {
38
+ "browser": true
39
+ },
40
+
41
+ "globals": {
42
+ "__DEV__": "readonly",
43
+ "process": "readonly",
44
+ "global": "readonly",
45
+ "localStorage": "readonly"
46
+ }
47
+ }
package/package.json CHANGED
@@ -1,11 +1,14 @@
1
1
  {
2
2
  "name": "miaoda-expo-devkit",
3
- "version": "0.1.1-beta.2",
3
+ "version": "0.1.1-beta.4",
4
4
  "description": "Expo 应用开发工具集:Sentry DSN 替换 stub、错误/网络捕获、Metro 符号化",
5
5
  "license": "MIT",
6
6
  "main": "./dist/index.js",
7
7
  "module": "./dist/index.mjs",
8
8
  "types": "./dist/index.d.ts",
9
+ "bin": {
10
+ "devkit-lint": "./dist/cli/lint.js"
11
+ },
9
12
  "exports": {
10
13
  ".": {
11
14
  "import": {
@@ -41,23 +44,24 @@
41
44
  "./rules/no-unstable-expo-router": "./dist/rules/no-unstable-expo-router.js",
42
45
  "./rules/no-rn-alert": "./dist/rules/no-rn-alert.js",
43
46
  "./rules/no-duplicate-expo-router-url": "./dist/rules/no-duplicate-expo-router-url.js",
44
- "./biome": "./biome-config.json"
47
+ "./biome": "./biome-config.json",
48
+ "./oxlint": "./oxlint-config.json"
45
49
  },
46
50
  "files": [
47
51
  "dist",
48
52
  "biome-config.json",
53
+ "oxlint-config.json",
49
54
  "pnpm-config.json",
50
55
  "!dist/**/*.map"
51
56
  ],
52
57
  "scripts": {
53
58
  "build": "tsup",
54
- "prepare": "tsup",
55
59
  "typecheck": "tsc --noEmit && tsc -p tsconfig.check.json --noEmit",
56
60
  "test": "vitest run",
57
61
  "test:rules": "node --test --test-reporter=./src/rules/test-reporter.mjs src/rules/__tests__/*.test.ts",
58
62
  "prepublishOnly": "pnpm run test && pnpm run build",
59
- "release": "pnpm run test && pnpm run build && npm publish",
60
- "release:beta": "npm version prerelease --preid=beta && pnpm run test && pnpm run build && npm publish --tag beta",
63
+ "release": "npm publish",
64
+ "release:beta": "npm version prerelease --preid=beta && npm publish --tag beta",
61
65
  "release:patch": "npm version patch && pnpm run release",
62
66
  "release:minor": "npm version minor && pnpm run release",
63
67
  "release:major": "npm version major && pnpm run release"