miaoda-expo-devkit 0.1.1-beta.96 → 0.1.1-beta.97

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/cli/lint.js CHANGED
@@ -9089,29 +9089,27 @@ var require_has_flag = __commonJS({
9089
9089
  }
9090
9090
  });
9091
9091
 
9092
- // ../../node_modules/.pnpm/supports-color@8.1.1/node_modules/supports-color/index.js
9092
+ // ../../node_modules/.pnpm/supports-color@7.2.0/node_modules/supports-color/index.js
9093
9093
  var require_supports_color = __commonJS({
9094
- "../../node_modules/.pnpm/supports-color@8.1.1/node_modules/supports-color/index.js"(exports2, module2) {
9094
+ "../../node_modules/.pnpm/supports-color@7.2.0/node_modules/supports-color/index.js"(exports2, module2) {
9095
9095
  "use strict";
9096
9096
  var os = require("os");
9097
9097
  var tty = require("tty");
9098
9098
  var hasFlag = require_has_flag();
9099
9099
  var { env } = process;
9100
- var flagForceColor;
9100
+ var forceColor;
9101
9101
  if (hasFlag("no-color") || hasFlag("no-colors") || hasFlag("color=false") || hasFlag("color=never")) {
9102
- flagForceColor = 0;
9102
+ forceColor = 0;
9103
9103
  } else if (hasFlag("color") || hasFlag("colors") || hasFlag("color=true") || hasFlag("color=always")) {
9104
- flagForceColor = 1;
9104
+ forceColor = 1;
9105
9105
  }
9106
- function envForceColor() {
9107
- if ("FORCE_COLOR" in env) {
9108
- if (env.FORCE_COLOR === "true") {
9109
- return 1;
9110
- }
9111
- if (env.FORCE_COLOR === "false") {
9112
- return 0;
9113
- }
9114
- return env.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3);
9106
+ if ("FORCE_COLOR" in env) {
9107
+ if (env.FORCE_COLOR === "true") {
9108
+ forceColor = 1;
9109
+ } else if (env.FORCE_COLOR === "false") {
9110
+ forceColor = 0;
9111
+ } else {
9112
+ forceColor = env.FORCE_COLOR.length === 0 ? 1 : Math.min(parseInt(env.FORCE_COLOR, 10), 3);
9115
9113
  }
9116
9114
  }
9117
9115
  function translateLevel(level) {
@@ -9125,22 +9123,15 @@ var require_supports_color = __commonJS({
9125
9123
  has16m: level >= 3
9126
9124
  };
9127
9125
  }
9128
- function supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
9129
- const noFlagForceColor = envForceColor();
9130
- if (noFlagForceColor !== void 0) {
9131
- flagForceColor = noFlagForceColor;
9132
- }
9133
- const forceColor = sniffFlags ? flagForceColor : noFlagForceColor;
9126
+ function supportsColor(haveStream, streamIsTTY) {
9134
9127
  if (forceColor === 0) {
9135
9128
  return 0;
9136
9129
  }
9137
- if (sniffFlags) {
9138
- if (hasFlag("color=16m") || hasFlag("color=full") || hasFlag("color=truecolor")) {
9139
- return 3;
9140
- }
9141
- if (hasFlag("color=256")) {
9142
- return 2;
9143
- }
9130
+ if (hasFlag("color=16m") || hasFlag("color=full") || hasFlag("color=truecolor")) {
9131
+ return 3;
9132
+ }
9133
+ if (hasFlag("color=256")) {
9134
+ return 2;
9144
9135
  }
9145
9136
  if (haveStream && !streamIsTTY && forceColor === void 0) {
9146
9137
  return 0;
@@ -9157,7 +9148,7 @@ var require_supports_color = __commonJS({
9157
9148
  return 1;
9158
9149
  }
9159
9150
  if ("CI" in env) {
9160
- if (["TRAVIS", "CIRCLECI", "APPVEYOR", "GITLAB_CI", "GITHUB_ACTIONS", "BUILDKITE", "DRONE"].some((sign) => sign in env) || env.CI_NAME === "codeship") {
9151
+ if (["TRAVIS", "CIRCLECI", "APPVEYOR", "GITLAB_CI", "GITHUB_ACTIONS", "BUILDKITE"].some((sign) => sign in env) || env.CI_NAME === "codeship") {
9161
9152
  return 1;
9162
9153
  }
9163
9154
  return min;
@@ -9169,7 +9160,7 @@ var require_supports_color = __commonJS({
9169
9160
  return 3;
9170
9161
  }
9171
9162
  if ("TERM_PROGRAM" in env) {
9172
- const version = Number.parseInt((env.TERM_PROGRAM_VERSION || "").split(".")[0], 10);
9163
+ const version = parseInt((env.TERM_PROGRAM_VERSION || "").split(".")[0], 10);
9173
9164
  switch (env.TERM_PROGRAM) {
9174
9165
  case "iTerm.app":
9175
9166
  return version >= 3 ? 3 : 2;
@@ -9188,17 +9179,14 @@ var require_supports_color = __commonJS({
9188
9179
  }
9189
9180
  return min;
9190
9181
  }
9191
- function getSupportLevel(stream, options = {}) {
9192
- const level = supportsColor(stream, {
9193
- streamIsTTY: stream && stream.isTTY,
9194
- ...options
9195
- });
9182
+ function getSupportLevel(stream) {
9183
+ const level = supportsColor(stream, stream && stream.isTTY);
9196
9184
  return translateLevel(level);
9197
9185
  }
9198
9186
  module2.exports = {
9199
9187
  supportsColor: getSupportLevel,
9200
- stdout: getSupportLevel({ isTTY: tty.isatty(1) }),
9201
- stderr: getSupportLevel({ isTTY: tty.isatty(2) })
9188
+ stdout: translateLevel(supportsColor(true, tty.isatty(1))),
9189
+ stderr: translateLevel(supportsColor(true, tty.isatty(2)))
9202
9190
  };
9203
9191
  }
9204
9192
  });
@@ -0,0 +1,141 @@
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-invalid-expo-config-value.ts
31
+ var no_invalid_expo_config_value_exports = {};
32
+ __export(no_invalid_expo_config_value_exports, {
33
+ default: () => no_invalid_expo_config_value_default
34
+ });
35
+ module.exports = __toCommonJS(no_invalid_expo_config_value_exports);
36
+ var import_node_fs = __toESM(require("fs"));
37
+ var import_node_path2 = __toESM(require("path"));
38
+
39
+ // src/rules/utils.ts
40
+ var import_node_path = __toESM(require("path"));
41
+ var import_package_up = require("package-up");
42
+ function findProjectRoot(startPath) {
43
+ const pkgPath = (0, import_package_up.packageUpSync)({ cwd: import_node_path.default.dirname(startPath) });
44
+ return pkgPath ? import_node_path.default.dirname(pkgPath) : null;
45
+ }
46
+
47
+ // src/rules/no-invalid-expo-config-value.ts
48
+ var USER_INTERFACE_STYLE = /* @__PURE__ */ new Set(["light", "dark", "automatic"]);
49
+ var ORIENTATION = /* @__PURE__ */ new Set(["default", "portrait", "landscape"]);
50
+ var SPLASH_RESIZE_MODE = /* @__PURE__ */ new Set(["contain", "cover"]);
51
+ var INITIAL_ORIENTATION = /* @__PURE__ */ new Set([
52
+ "DEFAULT",
53
+ "ALL",
54
+ "PORTRAIT",
55
+ "PORTRAIT_UP",
56
+ "PORTRAIT_DOWN",
57
+ "LANDSCAPE",
58
+ "LANDSCAPE_LEFT",
59
+ "LANDSCAPE_RIGHT"
60
+ ]);
61
+ function collectEnumIssues(appJson) {
62
+ const issues = [];
63
+ const expo = appJson.expo ?? {};
64
+ const push = (field, value, allowed, allowedLabel) => {
65
+ if (typeof value === "string" && value.length > 0 && !allowed.has(value)) {
66
+ issues.push({ field, value, allowed: allowedLabel });
67
+ }
68
+ };
69
+ push("expo.orientation", expo.orientation, ORIENTATION, "default, portrait, landscape");
70
+ push("expo.userInterfaceStyle", expo.userInterfaceStyle, USER_INTERFACE_STYLE, "light, dark, automatic");
71
+ push(
72
+ "expo.android.userInterfaceStyle",
73
+ expo.android?.userInterfaceStyle,
74
+ USER_INTERFACE_STYLE,
75
+ "light, dark, automatic"
76
+ );
77
+ const splashes = [
78
+ ["expo.splash", expo.splash],
79
+ ["expo.android.splash", expo.android?.splash],
80
+ ["expo.ios.splash", expo.ios?.splash]
81
+ ];
82
+ for (const [prefix, splash] of splashes) {
83
+ if (!splash) continue;
84
+ push(`${prefix}.resizeMode`, splash.resizeMode, SPLASH_RESIZE_MODE, "contain, cover");
85
+ }
86
+ for (const entry of expo.plugins ?? []) {
87
+ if (!Array.isArray(entry) || entry[0] !== "expo-screen-orientation") continue;
88
+ const opts = entry[1];
89
+ if (opts != null && typeof opts === "object") {
90
+ const initial = opts.initialOrientation;
91
+ push(
92
+ "plugins[expo-screen-orientation].initialOrientation",
93
+ initial,
94
+ INITIAL_ORIENTATION,
95
+ "DEFAULT, ALL, PORTRAIT, PORTRAIT_UP, PORTRAIT_DOWN, LANDSCAPE, LANDSCAPE_LEFT, LANDSCAPE_RIGHT"
96
+ );
97
+ }
98
+ }
99
+ return issues;
100
+ }
101
+ var noInvalidExpoConfigValueRule = {
102
+ meta: {
103
+ type: "problem",
104
+ docs: {
105
+ description: "Validate enum/string fields in app.json that `expo prebuild` consumes (userInterfaceStyle, orientation, splash.resizeMode, screen-orientation.initialOrientation)."
106
+ },
107
+ schema: [],
108
+ messages: {
109
+ invalidEnum: '{{field}} has invalid value "{{value}}". `expo prebuild` expects one of: {{allowed}}. Using an unrecognized value will either abort prebuild or be silently ignored.'
110
+ }
111
+ },
112
+ create(context) {
113
+ const projectRoot = findProjectRoot(context.filename);
114
+ if (!projectRoot) return {};
115
+ return {
116
+ Program(node) {
117
+ let appJson;
118
+ try {
119
+ appJson = JSON.parse(
120
+ import_node_fs.default.readFileSync(import_node_path2.default.join(projectRoot, "app.json"), "utf-8")
121
+ );
122
+ } catch {
123
+ return;
124
+ }
125
+ for (const issue of collectEnumIssues(appJson)) {
126
+ context.report({
127
+ node,
128
+ messageId: "invalidEnum",
129
+ data: { field: issue.field, value: issue.value, allowed: issue.allowed }
130
+ });
131
+ }
132
+ }
133
+ };
134
+ }
135
+ };
136
+ var plugin = {
137
+ meta: { name: "expo-config-value" },
138
+ rules: { "no-invalid-expo-config-value": noInvalidExpoConfigValueRule }
139
+ };
140
+ var no_invalid_expo_config_value_default = plugin;
141
+ module.exports = module.exports.default;
@@ -0,0 +1,228 @@
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-invalid-notification-config.ts
31
+ var no_invalid_notification_config_exports = {};
32
+ __export(no_invalid_notification_config_exports, {
33
+ default: () => no_invalid_notification_config_default
34
+ });
35
+ module.exports = __toCommonJS(no_invalid_notification_config_exports);
36
+ var import_node_fs2 = __toESM(require("fs"));
37
+ var import_node_path2 = __toESM(require("path"));
38
+
39
+ // src/rules/utils.ts
40
+ var import_node_path = __toESM(require("path"));
41
+ var import_package_up = require("package-up");
42
+ function findProjectRoot(startPath) {
43
+ const pkgPath = (0, import_package_up.packageUpSync)({ cwd: import_node_path.default.dirname(startPath) });
44
+ return pkgPath ? import_node_path.default.dirname(pkgPath) : null;
45
+ }
46
+
47
+ // src/rules/image-format.ts
48
+ var import_node_fs = __toESM(require("fs"));
49
+ var PNG_SIGNATURE = Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]);
50
+ var JPEG_SIGNATURE = Buffer.from([255, 216, 255]);
51
+ var GIF87_SIGNATURE = Buffer.from("GIF87a", "ascii");
52
+ var GIF89_SIGNATURE = Buffer.from("GIF89a", "ascii");
53
+ var RIFF_SIGNATURE = Buffer.from("RIFF", "ascii");
54
+ var WEBP_SIGNATURE = Buffer.from("WEBP", "ascii");
55
+ function detectImageFormat(filePath) {
56
+ let fd;
57
+ try {
58
+ fd = import_node_fs.default.openSync(filePath, "r");
59
+ } catch {
60
+ return null;
61
+ }
62
+ try {
63
+ const buf = Buffer.alloc(12);
64
+ const bytesRead = import_node_fs.default.readSync(fd, buf, 0, buf.length, 0);
65
+ if (bytesRead >= 8 && buf.subarray(0, 8).equals(PNG_SIGNATURE)) {
66
+ return "png";
67
+ }
68
+ if (bytesRead >= 3 && buf.subarray(0, 3).equals(JPEG_SIGNATURE)) {
69
+ return "jpeg";
70
+ }
71
+ if (bytesRead >= 6 && (buf.subarray(0, 6).equals(GIF87_SIGNATURE) || buf.subarray(0, 6).equals(GIF89_SIGNATURE))) {
72
+ return "gif";
73
+ }
74
+ if (bytesRead >= 12 && buf.subarray(0, 4).equals(RIFF_SIGNATURE) && buf.subarray(8, 12).equals(WEBP_SIGNATURE)) {
75
+ return "webp";
76
+ }
77
+ return null;
78
+ } catch {
79
+ return null;
80
+ } finally {
81
+ import_node_fs.default.closeSync(fd);
82
+ }
83
+ }
84
+
85
+ // src/rules/no-invalid-notification-config.ts
86
+ var SUPPORTED_FORMATS = /* @__PURE__ */ new Set([
87
+ "png",
88
+ "jpeg",
89
+ "webp",
90
+ "gif"
91
+ ]);
92
+ var EXT_TO_FORMAT = {
93
+ png: "png",
94
+ jpg: "jpeg",
95
+ jpeg: "jpeg",
96
+ jpe: "jpeg",
97
+ webp: "webp",
98
+ gif: "gif"
99
+ };
100
+ function isRemoteUrl(value) {
101
+ return value.startsWith("http://") || value.startsWith("https://");
102
+ }
103
+ var HEX_COLOR = /^#[0-9a-fA-F]{3}([0-9a-fA-F]{3}([0-9a-fA-F]{2})?)?$/;
104
+ function isHexColor(value) {
105
+ return HEX_COLOR.test(value);
106
+ }
107
+ function looksLikeColorName(value) {
108
+ if (!/^[a-z][a-z0-9_]*$/i.test(value) || value.includes(" ")) return false;
109
+ return !/^[0-9a-f]+$/i.test(value);
110
+ }
111
+ function getNotificationPluginOptions(plugins) {
112
+ for (const entry of plugins) {
113
+ if (entry === "expo-notifications") return {};
114
+ if (Array.isArray(entry) && entry[0] === "expo-notifications") {
115
+ const opts = entry[1];
116
+ if (opts != null && typeof opts === "object") return opts;
117
+ return {};
118
+ }
119
+ }
120
+ return null;
121
+ }
122
+ function checkIcon(projectRoot, icon) {
123
+ if (typeof icon !== "string") return null;
124
+ if (isRemoteUrl(icon)) return null;
125
+ const abs = import_node_path2.default.resolve(projectRoot, icon);
126
+ if (!import_node_fs2.default.existsSync(abs)) return { kind: "iconMissing" };
127
+ const ext = import_node_path2.default.extname(icon).replace(/^\./, "").toLowerCase();
128
+ const declared = EXT_TO_FORMAT[ext];
129
+ if (!declared) {
130
+ return { kind: "iconUnsupported", format: ext || "unknown" };
131
+ }
132
+ const actual = detectImageFormat(abs);
133
+ if (actual === null || !SUPPORTED_FORMATS.has(actual)) {
134
+ return { kind: "iconUnsupported", format: actual ?? "unknown" };
135
+ }
136
+ if (declared !== actual) {
137
+ return { kind: "iconMasquerade", declared, actual };
138
+ }
139
+ return null;
140
+ }
141
+ function collectIssues(projectRoot, options) {
142
+ const issues = [];
143
+ if (options.sounds !== void 0 && options.sounds !== null) {
144
+ if (!Array.isArray(options.sounds) && typeof options.sounds !== "string") {
145
+ issues.push({ kind: "soundsNotArray", actualType: typeof options.sounds });
146
+ }
147
+ }
148
+ if (typeof options.color === "string" && options.color.length > 0) {
149
+ if (!isHexColor(options.color) && !looksLikeColorName(options.color)) {
150
+ issues.push({ kind: "invalidColor", value: options.color });
151
+ }
152
+ }
153
+ if (options.icon !== void 0 && options.icon !== null) {
154
+ const iconIssue = checkIcon(projectRoot, options.icon);
155
+ if (iconIssue) issues.push(iconIssue);
156
+ }
157
+ return issues;
158
+ }
159
+ var noInvalidNotificationConfigRule = {
160
+ meta: {
161
+ type: "problem",
162
+ docs: {
163
+ description: "Validate expo-notifications plugin config: sounds must be an array, color must be a valid hex/name, icon must be a supported image format and not masquerading."
164
+ },
165
+ schema: [],
166
+ messages: {
167
+ soundsNotArray: 'expo-notifications `sounds` must be an array of file paths, found {{actualType}}. `expo prebuild` throws: "Must provide an array of sound files in your app config".',
168
+ invalidColor: 'expo-notifications `color` "{{value}}" is not a valid color. Use a hex color like "#E63946" (supports #RGB / #RRGGBB / #AARRGGBB) or a lowercase color name.',
169
+ iconMissing: "expo-notifications `icon` references a file that does not exist.",
170
+ iconUnsupported: 'expo-notifications `icon` has unsupported image format "{{format}}". `expo prebuild` (via @expo/image-utils) only supports png, jpeg, webp, gif.',
171
+ iconMasquerade: "expo-notifications `icon` is declared as .{{declared}} but the file content is actually {{actual}}. This format masquerade fails prebuild. Convert the file to match its extension."
172
+ }
173
+ },
174
+ create(context) {
175
+ const projectRoot = findProjectRoot(context.filename);
176
+ if (!projectRoot) return {};
177
+ return {
178
+ Program(node) {
179
+ let appJson;
180
+ try {
181
+ appJson = JSON.parse(
182
+ import_node_fs2.default.readFileSync(import_node_path2.default.join(projectRoot, "app.json"), "utf-8")
183
+ );
184
+ } catch {
185
+ return;
186
+ }
187
+ const plugins = appJson.expo?.plugins ?? [];
188
+ const options = getNotificationPluginOptions(plugins);
189
+ if (!options) return;
190
+ for (const issue of collectIssues(projectRoot, options)) {
191
+ if (issue.kind === "soundsNotArray") {
192
+ context.report({
193
+ node,
194
+ messageId: "soundsNotArray",
195
+ data: { actualType: issue.actualType }
196
+ });
197
+ } else if (issue.kind === "invalidColor") {
198
+ context.report({
199
+ node,
200
+ messageId: "invalidColor",
201
+ data: { value: issue.value }
202
+ });
203
+ } else if (issue.kind === "iconMissing") {
204
+ context.report({ node, messageId: "iconMissing" });
205
+ } else if (issue.kind === "iconUnsupported") {
206
+ context.report({
207
+ node,
208
+ messageId: "iconUnsupported",
209
+ data: { format: issue.format }
210
+ });
211
+ } else {
212
+ context.report({
213
+ node,
214
+ messageId: "iconMasquerade",
215
+ data: { declared: issue.declared, actual: issue.actual }
216
+ });
217
+ }
218
+ }
219
+ }
220
+ };
221
+ }
222
+ };
223
+ var plugin = {
224
+ meta: { name: "expo-notifications-config" },
225
+ rules: { "no-invalid-notification-config": noInvalidNotificationConfigRule }
226
+ };
227
+ var no_invalid_notification_config_default = plugin;
228
+ module.exports = module.exports.default;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "miaoda-expo-devkit",
3
- "version": "0.1.1-beta.96",
3
+ "version": "0.1.1-beta.97",
4
4
  "description": "Expo 应用开发工具集:Sentry DSN 替换 stub、错误/网络捕获、Metro 符号化",
5
5
  "license": "MIT",
6
6
  "main": "./dist/index.js",
@@ -64,6 +64,8 @@
64
64
  "./rules/no-missing-image-import": "./dist/rules/no-missing-image-import.js",
65
65
  "./rules/no-splash-screen-missing-image": "./dist/rules/no-splash-screen-missing-image.js",
66
66
  "./rules/no-missing-notification-asset": "./dist/rules/no-missing-notification-asset.js",
67
+ "./rules/no-invalid-notification-config": "./dist/rules/no-invalid-notification-config.js",
68
+ "./rules/no-invalid-expo-config-value": "./dist/rules/no-invalid-expo-config-value.js",
67
69
  "./rules/no-gifted-charts-missing-linear-gradient": "./dist/rules/no-gifted-charts-missing-linear-gradient.js",
68
70
  "./biome": "./biome-config.json",
69
71
  "./oxlint": "./oxlint-config.json",