miaoda-expo-devkit 0.1.1-beta.82 → 0.1.1-beta.84

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.d.mts CHANGED
@@ -141,6 +141,11 @@ interface DevkitOptions {
141
141
  * 默认:'./src/global.css'
142
142
  */
143
143
  input?: string;
144
+ /**
145
+ * stub 弹窗/提示文案的语言。
146
+ * 不设置时运行时自动检测(navigator.language / NativeModules)。
147
+ */
148
+ locale?: 'zh' | 'en';
144
149
  }
145
150
  /**
146
151
  * 一站式应用所有 devkit Metro wrapper。
package/dist/metro.d.ts CHANGED
@@ -141,6 +141,11 @@ interface DevkitOptions {
141
141
  * 默认:'./src/global.css'
142
142
  */
143
143
  input?: string;
144
+ /**
145
+ * stub 弹窗/提示文案的语言。
146
+ * 不设置时运行时自动检测(navigator.language / NativeModules)。
147
+ */
148
+ locale?: 'zh' | 'en';
144
149
  }
145
150
  /**
146
151
  * 一站式应用所有 devkit Metro wrapper。
package/dist/metro.js CHANGED
@@ -630,7 +630,10 @@ function withPersistentCache(config, options = {}) {
630
630
  // src/metro/withDevkit.ts
631
631
  function withDevkit(config, options = {}) {
632
632
  const projectRoot = config.projectRoot ?? process.cwd();
633
- const { input = "./src/global.css" } = options;
633
+ const { input = "./src/global.css", locale } = options;
634
+ if (locale) {
635
+ process.env["DEVKIT_LOCALE"] = locale;
636
+ }
634
637
  config = withTransformLogger(config);
635
638
  config = withPersistentCache(config);
636
639
  config = withWorkspaceNodeModules(config);
package/dist/metro.mjs CHANGED
@@ -581,7 +581,10 @@ function withPersistentCache(config, options = {}) {
581
581
  // src/metro/withDevkit.ts
582
582
  function withDevkit(config, options = {}) {
583
583
  const projectRoot = config.projectRoot ?? process.cwd();
584
- const { input = "./src/global.css" } = options;
584
+ const { input = "./src/global.css", locale } = options;
585
+ if (locale) {
586
+ process.env["DEVKIT_LOCALE"] = locale;
587
+ }
585
588
  config = withTransformLogger(config);
586
589
  config = withPersistentCache(config);
587
590
  config = withWorkspaceNodeModules(config);
@@ -0,0 +1,101 @@
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-gifted-charts-missing-linear-gradient.ts
31
+ var no_gifted_charts_missing_linear_gradient_exports = {};
32
+ __export(no_gifted_charts_missing_linear_gradient_exports, {
33
+ default: () => no_gifted_charts_missing_linear_gradient_default
34
+ });
35
+ module.exports = __toCommonJS(no_gifted_charts_missing_linear_gradient_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-gifted-charts-missing-linear-gradient.ts
48
+ var cache = /* @__PURE__ */ new Map();
49
+ function readProjectDeps(projectRoot) {
50
+ if (cache.has(projectRoot)) return cache.get(projectRoot);
51
+ const pkgPath = import_node_path2.default.join(projectRoot, "package.json");
52
+ try {
53
+ const pkg = JSON.parse(import_node_fs.default.readFileSync(pkgPath, "utf-8"));
54
+ const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
55
+ const result = {
56
+ hasGiftedCharts: "react-native-gifted-charts" in allDeps,
57
+ hasLinearGradient: "expo-linear-gradient" in allDeps
58
+ };
59
+ cache.set(projectRoot, result);
60
+ return result;
61
+ } catch {
62
+ const result = { hasGiftedCharts: false, hasLinearGradient: false };
63
+ cache.set(projectRoot, result);
64
+ return result;
65
+ }
66
+ }
67
+ var reportedProjects = /* @__PURE__ */ new Set();
68
+ var noGiftedChartsMissingLinearGradientRule = {
69
+ meta: {
70
+ type: "problem",
71
+ docs: {
72
+ description: "Error when react-native-gifted-charts is in package.json but expo-linear-gradient is not installed."
73
+ },
74
+ schema: [],
75
+ messages: {
76
+ missingLinearGradient: "react-native-gifted-charts requires expo-linear-gradient as a peer dependency, but it is not listed in package.json. Run `npx expo install expo-linear-gradient` to fix this."
77
+ }
78
+ },
79
+ create(context) {
80
+ const projectRoot = findProjectRoot(context.filename);
81
+ if (!projectRoot) return {};
82
+ const { hasGiftedCharts, hasLinearGradient } = readProjectDeps(projectRoot);
83
+ if (!hasGiftedCharts || hasLinearGradient) return {};
84
+ if (reportedProjects.has(projectRoot)) return {};
85
+ return {
86
+ Program(node) {
87
+ reportedProjects.add(projectRoot);
88
+ context.report({
89
+ node,
90
+ messageId: "missingLinearGradient"
91
+ });
92
+ }
93
+ };
94
+ }
95
+ };
96
+ var plugin = {
97
+ meta: { name: "gifted-charts-linear-gradient" },
98
+ rules: { "no-gifted-charts-missing-linear-gradient": noGiftedChartsMissingLinearGradientRule }
99
+ };
100
+ var no_gifted_charts_missing_linear_gradient_default = plugin;
101
+ module.exports = module.exports.default;
@@ -73,6 +73,9 @@ function getSplashPluginEntry(plugins) {
73
73
  }
74
74
  return { found: false };
75
75
  }
76
+ function hasIconAsset(projectRoot) {
77
+ return import_node_fs.default.existsSync(import_node_path2.default.join(projectRoot, "assets", "icon.png"));
78
+ }
76
79
  function hasImageFields(fields) {
77
80
  return !!(fields.image || fields.mdpi || fields.hdpi || fields.xhdpi || fields.xxhdpi || fields.xxxhdpi || fields.drawable?.icon);
78
81
  }
@@ -96,7 +99,17 @@ var noSplashScreenMissingImageRule = {
96
99
  },
97
100
  schema: [],
98
101
  messages: {
99
- missingImage: "'expo-splash-screen' is declared in plugins but no splash image is configured. Add expo.splash.image to app.json, or pass image via plugin options. Without an image Android builds fail with: resource drawable/splashscreen_logo not found."
102
+ missingImage: "'expo-splash-screen' is declared in plugins but no splash image is configured. Add expo.splash.image to app.json, or pass image via plugin options. Without an image Android builds fail with: resource drawable/splashscreen_logo not found.",
103
+ missingImageWithIconSuggestion: `'expo-splash-screen' is declared in plugins but no splash image is configured. Android builds will fail with: resource drawable/splashscreen_logo not found.
104
+
105
+ assets/icon.png was found. Recommended fix \u2014 replace the "expo-splash-screen" entry in app.json plugins with:
106
+
107
+ ["expo-splash-screen", {
108
+ "backgroundColor": "#ffffff",
109
+ "image": "./assets/icon.png",
110
+ "imageWidth": 200,
111
+ "resizeMode": "contain"
112
+ }]`
100
113
  }
101
114
  },
102
115
  create(context) {
@@ -112,7 +125,8 @@ var noSplashScreenMissingImageRule = {
112
125
  const entry = getSplashPluginEntry(plugins);
113
126
  if (!entry.found) return;
114
127
  if (!hasAndroidSplashImage(appJson, entry.options)) {
115
- context.report({ node, messageId: "missingImage" });
128
+ const messageId = hasIconAsset(projectRoot) ? "missingImageWithIconSuggestion" : "missingImage";
129
+ context.report({ node, messageId });
116
130
  }
117
131
  }
118
132
  };
@@ -1,10 +1,25 @@
1
1
  "use strict";
2
2
  var import_react_native = require("react-native");
3
3
  var import_web_stub_dialog = require("./web-stub-dialog");
4
+ var import_i18n = require("./i18n");
4
5
  if (import_react_native.Platform.OS !== "web") {
5
6
  module.exports = require("expo-calendar");
6
7
  } else {
7
- let showCalendarAlert = function(title, lines, isValid, errors) {
8
+ let createStubCalendar = function() {
9
+ return {
10
+ id: "stub-calendar",
11
+ title: (0, import_i18n.t)("calendar.previewCalendarTitle"),
12
+ color: "#1677FF",
13
+ entityType: "event",
14
+ source: { id: "stub", type: "local", name: (0, import_i18n.t)("calendar.sourceNameLocal") },
15
+ type: "local",
16
+ allowsModifications: true,
17
+ allowedAvailabilities: [],
18
+ allowedReminders: [],
19
+ allowedAttendeeTypes: [],
20
+ accessLevel: "owner"
21
+ };
22
+ }, showCalendarAlert = function(title, lines, isValid, errors) {
8
23
  (0, import_web_stub_dialog.showWebStubDialog)({
9
24
  title,
10
25
  details: lines,
@@ -13,17 +28,17 @@ if (import_react_native.Platform.OS !== "web") {
13
28
  }, validateId = function(id, label = "id") {
14
29
  const errors = [];
15
30
  if (typeof id !== "string" || id.trim().length === 0) {
16
- errors.push(`${label} \u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32`);
31
+ errors.push((0, import_i18n.t)("validation.mustBeNonEmptyString", { label }));
17
32
  }
18
33
  return { ok: errors.length === 0, errors };
19
34
  }, validateDate = function(value, label) {
20
35
  const errors = [];
21
36
  if (value == null) {
22
- errors.push(`${label} \u4E0D\u80FD\u4E3A\u7A7A`);
37
+ errors.push((0, import_i18n.t)("validation.cannotBeEmpty", { label }));
23
38
  } else if (!(value instanceof Date) && typeof value !== "string") {
24
- errors.push(`${label} \u5FC5\u987B\u662F Date \u6216\u65E5\u671F\u5B57\u7B26\u4E32`);
39
+ errors.push((0, import_i18n.t)("validation.mustBeDateOrString", { label }));
25
40
  } else if (value instanceof Date && isNaN(value.getTime())) {
26
- errors.push(`${label} \u662F\u65E0\u6548\u7684 Date \u5BF9\u8C61`);
41
+ errors.push((0, import_i18n.t)("validation.invalidDateObject", { label }));
27
42
  }
28
43
  return errors;
29
44
  }, formatDateArg = function(value) {
@@ -41,26 +56,13 @@ if (import_react_native.Platform.OS !== "web") {
41
56
  const getPermission = useCallback(async () => GRANTED_PERMISSION, []);
42
57
  return [permission, requestPermission, getPermission];
43
58
  };
44
- var showCalendarAlert2 = showCalendarAlert, validateId2 = validateId, validateDate2 = validateDate, formatDateArg2 = formatDateArg, useCalendarPermissions2 = useCalendarPermissions, useRemindersPermissions2 = useRemindersPermissions;
59
+ var createStubCalendar2 = createStubCalendar, showCalendarAlert2 = showCalendarAlert, validateId2 = validateId, validateDate2 = validateDate, formatDateArg2 = formatDateArg, useCalendarPermissions2 = useCalendarPermissions, useRemindersPermissions2 = useRemindersPermissions;
45
60
  const GRANTED_PERMISSION = {
46
61
  status: "granted",
47
62
  granted: true,
48
63
  canAskAgain: true,
49
64
  expires: "never"
50
65
  };
51
- const STUB_CALENDAR = {
52
- id: "stub-calendar",
53
- title: "\u9884\u89C8\u65E5\u5386\uFF08Web\uFF09",
54
- color: "#1677FF",
55
- entityType: "event",
56
- source: { id: "stub", type: "local", name: "\u672C\u5730" },
57
- type: "local",
58
- allowsModifications: true,
59
- allowedAvailabilities: [],
60
- allowedReminders: [],
61
- allowedAttendeeTypes: [],
62
- accessLevel: "owner"
63
- };
64
66
  const { useState, useCallback } = require("react");
65
67
  const requestCalendarPermissionsAsync = async () => GRANTED_PERMISSION;
66
68
  const getCalendarPermissionsAsync = async () => GRANTED_PERMISSION;
@@ -71,10 +73,10 @@ if (import_react_native.Platform.OS !== "web") {
71
73
  const isAvailableAsync = async () => true;
72
74
  const getCalendarsAsync = async (entityType) => {
73
75
  void entityType;
74
- return [STUB_CALENDAR];
76
+ return [createStubCalendar()];
75
77
  };
76
78
  const getDefaultCalendarAsync = async () => {
77
- showCalendarAlert("\u83B7\u53D6\u9ED8\u8BA4\u65E5\u5386", ["\u64CD\u4F5C: \u83B7\u53D6\u7CFB\u7EDF\u9ED8\u8BA4\u65E5\u5386", "\u79D2\u54D2\u9884\u89C8\u6A21\u5F0F\u4E0D\u652F\u6301"], false, ["\u65E0\u6CD5\u8BBF\u95EE\u7CFB\u7EDF\u65E5\u5386"]);
79
+ showCalendarAlert((0, import_i18n.t)("calendar.getDefaultCalendar"), [(0, import_i18n.t)("calendar.getDefaultCalendarDetail"), (0, import_i18n.t)("preview.unsupported")], false, [(0, import_i18n.t)("preview.cannotAccessCalendar")]);
78
80
  return void 0;
79
81
  };
80
82
  const createCalendarAsync = async (details) => {
@@ -82,13 +84,13 @@ if (import_react_native.Platform.OS !== "web") {
82
84
  const d = details && typeof details === "object" ? details : {};
83
85
  const titleVal = d["title"];
84
86
  if (typeof titleVal !== "string" || titleVal.trim().length === 0) {
85
- errors.push("details.title \u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");
87
+ errors.push((0, import_i18n.t)("validation.mustBeNonEmptyString", { label: "details.title" }));
86
88
  }
87
89
  const isValid = errors.length === 0;
88
- const titleDisplay = typeof titleVal === "string" ? titleVal : "(\u672A\u586B\u5199)";
90
+ const titleDisplay = typeof titleVal === "string" ? titleVal : (0, import_i18n.t)("common.notFilled");
89
91
  showCalendarAlert(
90
- "\u521B\u5EFA\u65E5\u5386",
91
- [`\u540D\u79F0: ${titleDisplay}`, `\u989C\u8272: ${d["color"] ?? "(\u672A\u8BBE\u7F6E)"}`],
92
+ (0, import_i18n.t)("calendar.createCalendar"),
93
+ [(0, import_i18n.t)("calendar.calendarName", { value: titleDisplay }), (0, import_i18n.t)("calendar.calendarColor", { value: String(d["color"] ?? (0, import_i18n.t)("common.notSet")) })],
92
94
  isValid,
93
95
  isValid ? void 0 : errors
94
96
  );
@@ -98,10 +100,10 @@ if (import_react_native.Platform.OS !== "web") {
98
100
  const { ok: idOk, errors: idErrors } = validateId(id, "calendarId");
99
101
  const d = details && typeof details === "object" ? details : {};
100
102
  showCalendarAlert(
101
- "\u66F4\u65B0\u65E5\u5386",
103
+ (0, import_i18n.t)("calendar.updateCalendar"),
102
104
  [
103
- `\u65E5\u5386 ID: ${typeof id === "string" ? id : String(id)}`,
104
- `\u66F4\u65B0\u5B57\u6BB5: ${Object.keys(d).join(", ") || "(\u65E0)"}`
105
+ (0, import_i18n.t)("calendar.calendarId", { value: typeof id === "string" ? id : String(id) }),
106
+ (0, import_i18n.t)("calendar.updateFields", { value: Object.keys(d).join(", ") || (0, import_i18n.t)("common.none") })
105
107
  ],
106
108
  idOk,
107
109
  idOk ? void 0 : idErrors
@@ -111,8 +113,8 @@ if (import_react_native.Platform.OS !== "web") {
111
113
  const deleteCalendarAsync = async (id) => {
112
114
  const { ok, errors } = validateId(id, "calendarId");
113
115
  showCalendarAlert(
114
- "\u5220\u9664\u65E5\u5386",
115
- [`\u65E5\u5386 ID: ${typeof id === "string" ? id : String(id)}`],
116
+ (0, import_i18n.t)("calendar.deleteCalendar"),
117
+ [(0, import_i18n.t)("calendar.calendarId", { value: typeof id === "string" ? id : String(id) })],
116
118
  ok,
117
119
  ok ? void 0 : errors
118
120
  );
@@ -120,19 +122,19 @@ if (import_react_native.Platform.OS !== "web") {
120
122
  const getEventsAsync = async (calendarIds, startDate, endDate) => {
121
123
  const errors = [];
122
124
  if (!Array.isArray(calendarIds) || calendarIds.length === 0) {
123
- errors.push("calendarIds \u5FC5\u987B\u662F\u975E\u7A7A\u6570\u7EC4");
125
+ errors.push((0, import_i18n.t)("validation.calendarIdsMustBeNonEmptyArray"));
124
126
  }
125
127
  errors.push(...validateDate(startDate, "startDate"));
126
128
  errors.push(...validateDate(endDate, "endDate"));
127
129
  const isValid = errors.length === 0;
128
130
  const idsStr = Array.isArray(calendarIds) ? `[${calendarIds.slice(0, 3).join(", ")}${calendarIds.length > 3 ? "\u2026" : ""}]` : String(calendarIds);
129
131
  showCalendarAlert(
130
- "\u67E5\u8BE2\u65E5\u5386\u4E8B\u4EF6",
132
+ (0, import_i18n.t)("calendar.queryEvents"),
131
133
  [
132
- `\u65E5\u5386 IDs: ${idsStr}`,
133
- `\u5F00\u59CB\u65F6\u95F4: ${formatDateArg(startDate)}`,
134
- `\u7ED3\u675F\u65F6\u95F4: ${formatDateArg(endDate)}`,
135
- "\u79D2\u54D2\u9884\u89C8\u6A21\u5F0F\u8FD4\u56DE\u7A7A\u5217\u8868"
134
+ (0, import_i18n.t)("calendar.calendarIds", { value: idsStr }),
135
+ (0, import_i18n.t)("calendar.startTime", { value: formatDateArg(startDate) }),
136
+ (0, import_i18n.t)("calendar.endTime", { value: formatDateArg(endDate) }),
137
+ (0, import_i18n.t)("preview.returnsEmptyList")
136
138
  ],
137
139
  isValid,
138
140
  isValid ? void 0 : errors
@@ -142,8 +144,8 @@ if (import_react_native.Platform.OS !== "web") {
142
144
  const getEventAsync = async (id) => {
143
145
  const { ok, errors } = validateId(id, "eventId");
144
146
  showCalendarAlert(
145
- "\u83B7\u53D6\u65E5\u5386\u4E8B\u4EF6",
146
- [`\u4E8B\u4EF6 ID: ${typeof id === "string" ? id : String(id)}`],
147
+ (0, import_i18n.t)("calendar.getEvent"),
148
+ [(0, import_i18n.t)("calendar.eventId", { value: typeof id === "string" ? id : String(id) })],
147
149
  ok,
148
150
  ok ? void 0 : errors
149
151
  );
@@ -159,17 +161,17 @@ if (import_react_native.Platform.OS !== "web") {
159
161
  errors.push(...validateDate(data["endDate"], "eventData.endDate"));
160
162
  }
161
163
  const titleVal = data["title"];
162
- const titleDisplay = typeof titleVal === "string" ? titleVal : "(\u672A\u586B\u5199)";
163
- const startDisplay = data["startDate"] != null ? formatDateArg(data["startDate"]) : "(\u672A\u8BBE\u7F6E)";
164
- const endDisplay = data["endDate"] != null ? formatDateArg(data["endDate"]) : "(\u672A\u8BBE\u7F6E)";
164
+ const titleDisplay = typeof titleVal === "string" ? titleVal : (0, import_i18n.t)("common.notFilled");
165
+ const startDisplay = data["startDate"] != null ? formatDateArg(data["startDate"]) : (0, import_i18n.t)("common.notSet");
166
+ const endDisplay = data["endDate"] != null ? formatDateArg(data["endDate"]) : (0, import_i18n.t)("common.notSet");
165
167
  const isValid = errors.length === 0;
166
168
  showCalendarAlert(
167
- "\u521B\u5EFA\u65E5\u5386\u4E8B\u4EF6",
169
+ (0, import_i18n.t)("calendar.createEvent"),
168
170
  [
169
- `\u65E5\u5386 ID: ${typeof calendarId === "string" ? calendarId : String(calendarId)}`,
170
- `\u6807\u9898: ${titleDisplay}`,
171
- `\u5F00\u59CB: ${startDisplay}`,
172
- `\u7ED3\u675F: ${endDisplay}`
171
+ (0, import_i18n.t)("calendar.calendarId", { value: typeof calendarId === "string" ? calendarId : String(calendarId) }),
172
+ (0, import_i18n.t)("calendar.eventTitle", { value: titleDisplay }),
173
+ (0, import_i18n.t)("calendar.eventStart", { value: startDisplay }),
174
+ (0, import_i18n.t)("calendar.eventEnd", { value: endDisplay })
173
175
  ],
174
176
  isValid,
175
177
  isValid ? void 0 : errors
@@ -180,10 +182,10 @@ if (import_react_native.Platform.OS !== "web") {
180
182
  const { ok, errors } = validateId(id, "eventId");
181
183
  const d = details && typeof details === "object" ? details : {};
182
184
  showCalendarAlert(
183
- "\u66F4\u65B0\u65E5\u5386\u4E8B\u4EF6",
185
+ (0, import_i18n.t)("calendar.updateEvent"),
184
186
  [
185
- `\u4E8B\u4EF6 ID: ${typeof id === "string" ? id : String(id)}`,
186
- `\u66F4\u65B0\u5B57\u6BB5: ${Object.keys(d).join(", ") || "(\u65E0)"}`
187
+ (0, import_i18n.t)("calendar.eventId", { value: typeof id === "string" ? id : String(id) }),
188
+ (0, import_i18n.t)("calendar.updateFields", { value: Object.keys(d).join(", ") || (0, import_i18n.t)("common.none") })
187
189
  ],
188
190
  ok,
189
191
  ok ? void 0 : errors
@@ -193,8 +195,8 @@ if (import_react_native.Platform.OS !== "web") {
193
195
  const deleteEventAsync = async (id) => {
194
196
  const { ok, errors } = validateId(id, "eventId");
195
197
  showCalendarAlert(
196
- "\u5220\u9664\u65E5\u5386\u4E8B\u4EF6",
197
- [`\u4E8B\u4EF6 ID: ${typeof id === "string" ? id : String(id)}`],
198
+ (0, import_i18n.t)("calendar.deleteEvent"),
199
+ [(0, import_i18n.t)("calendar.eventId", { value: typeof id === "string" ? id : String(id) })],
198
200
  ok,
199
201
  ok ? void 0 : errors
200
202
  );
@@ -2,6 +2,7 @@
2
2
  var import_react_native = require("react-native");
3
3
  var import_expo = require("expo");
4
4
  var import_web_stub_dialog = require("./web-stub-dialog");
5
+ var import_i18n = require("./i18n");
5
6
  if (import_react_native.Platform.OS !== "web" && !(0, import_expo.isRunningInExpoGo)()) {
6
7
  module.exports = require("expo-contacts");
7
8
  } else {
@@ -15,20 +16,20 @@ if (import_react_native.Platform.OS !== "web" && !(0, import_expo.isRunningInExp
15
16
  });
16
17
  return;
17
18
  }
18
- const statusLine = hasErrors ? "\u274C \u53C2\u6570\u6709\u8BEF" : "\u2705 \u53C2\u6570\u5408\u89C4";
19
- const parts = ["\u79D2\u54D2\u626B\u7801\u9884\u89C8\u4E0D\u652F\u6301\u8BBF\u95EE\u901A\u8BAF\u5F55", "", ...lines, "", statusLine];
19
+ const statusLine = hasErrors ? (0, import_i18n.t)("preview.statusInvalid") : (0, import_i18n.t)("preview.statusValid");
20
+ const parts = [(0, import_i18n.t)("preview.scanUnsupportedContacts"), "", ...lines, "", statusLine];
20
21
  if (hasErrors) {
21
- parts.push(`\u95EE\u9898: ${errors.join(" / ")}`);
22
+ parts.push((0, import_i18n.t)("alert.issues", { value: errors.join(" / ") }));
22
23
  parts.push("");
23
- parts.push("\u8BF7\u622A\u56FE\u53D1\u7ED9\u79D2\u54D2 Agent \u4FEE\u590D");
24
+ parts.push((0, import_i18n.t)("preview.screenshotForAgent"));
24
25
  } else {
25
26
  parts.push("");
26
- parts.push("\u53D1\u5E03\u4E3A\u6B63\u5F0F App \u540E\u53EF\u6B63\u5E38\u4F7F\u7528");
27
+ parts.push((0, import_i18n.t)("preview.availableAfterPublish"));
27
28
  }
28
- import_react_native.Alert.alert(title, parts.join("\n"), [{ text: "\u77E5\u9053\u4E86" }]);
29
+ import_react_native.Alert.alert(title, parts.join("\n"), [{ text: (0, import_i18n.t)("common.dismiss") }]);
29
30
  }, validateId = function(id, label = "id") {
30
31
  if (typeof id !== "string" || id.trim().length === 0) {
31
- return [`${label} \u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32`];
32
+ return [(0, import_i18n.t)("validation.mustBeNonEmptyString", { label })];
32
33
  }
33
34
  return [];
34
35
  };
@@ -115,85 +116,85 @@ if (import_react_native.Platform.OS !== "web" && !(0, import_expo.isRunningInExp
115
116
  };
116
117
  const getPermissionsAsync = async () => DENIED_PERMISSION;
117
118
  const requestPermissionsAsync = async () => {
118
- showContactsAlert("\u8BF7\u6C42\u901A\u8BAF\u5F55\u6743\u9650", ["\u64CD\u4F5C: requestPermissionsAsync()", "\u79D2\u54D2\u9884\u89C8\u6A21\u5F0F\u4E0D\u652F\u6301\u8BBF\u95EE\u901A\u8BAF\u5F55"]);
119
+ showContactsAlert((0, import_i18n.t)("contacts.requestPermission"), [(0, import_i18n.t)("contacts.requestPermissionDetail"), (0, import_i18n.t)("contacts.previewUnsupportedContacts")]);
119
120
  return UNDETERMINED_PERMISSION;
120
121
  };
121
122
  const isAvailableAsync = async () => false;
122
123
  const hasContactsAsync = async () => false;
123
124
  const getContactsAsync = async (query) => {
124
- const queryStr = query ? JSON.stringify(query) : "(\u65E0\u8FC7\u6EE4)";
125
- showContactsAlert("\u83B7\u53D6\u901A\u8BAF\u5F55\u8054\u7CFB\u4EBA", [
125
+ const queryStr = query ? JSON.stringify(query) : (0, import_i18n.t)("common.noFilter");
126
+ showContactsAlert((0, import_i18n.t)("contacts.getContacts"), [
126
127
  `query: ${queryStr}`,
127
- "\u79D2\u54D2\u9884\u89C8\u6A21\u5F0F\u8FD4\u56DE\u7A7A\u5217\u8868"
128
+ (0, import_i18n.t)("preview.returnsEmptyList")
128
129
  ]);
129
130
  return { data: [], hasNextPage: false, hasPreviousPage: false, total: 0 };
130
131
  };
131
132
  const getPagedContactsAsync = async (query) => {
132
- const queryStr = query ? JSON.stringify(query) : "(\u65E0\u8FC7\u6EE4)";
133
- showContactsAlert("\u5206\u9875\u83B7\u53D6\u8054\u7CFB\u4EBA", [
133
+ const queryStr = query ? JSON.stringify(query) : (0, import_i18n.t)("common.noFilter");
134
+ showContactsAlert((0, import_i18n.t)("contacts.getPagedContacts"), [
134
135
  `query: ${queryStr}`,
135
- "\u79D2\u54D2\u9884\u89C8\u6A21\u5F0F\u8FD4\u56DE\u7A7A\u5217\u8868"
136
+ (0, import_i18n.t)("preview.returnsEmptyList")
136
137
  ]);
137
138
  return { data: [], hasNextPage: false, hasPreviousPage: false, total: 0 };
138
139
  };
139
140
  const getContactByIdAsync = async (id) => {
140
141
  const errors = validateId(id, "contactId");
141
- showContactsAlert("\u901A\u8FC7 ID \u83B7\u53D6\u8054\u7CFB\u4EBA", [`contactId: ${JSON.stringify(id)}`], errors.length ? errors : void 0);
142
+ showContactsAlert((0, import_i18n.t)("contacts.getContactById"), [`contactId: ${JSON.stringify(id)}`], errors.length ? errors : void 0);
142
143
  return null;
143
144
  };
144
145
  const addContactAsync = async (contact) => {
145
- const nameStr = contact?.name ?? "(\u672A\u4F20\u59D3\u540D)";
146
- showContactsAlert("\u6DFB\u52A0\u8054\u7CFB\u4EBA", [`name: ${nameStr}`]);
146
+ const nameStr = contact?.name ?? (0, import_i18n.t)("contacts.noName");
147
+ showContactsAlert((0, import_i18n.t)("contacts.addContact"), [`name: ${nameStr}`]);
147
148
  return "stub-contact-id";
148
149
  };
149
150
  const updateContactAsync = async (contact) => {
150
- const idStr = contact?.id ?? "(\u672A\u4F20 id)";
151
+ const idStr = contact?.id ?? (0, import_i18n.t)("contacts.noId");
151
152
  const errors = validateId(idStr, "contact.id");
152
- showContactsAlert("\u66F4\u65B0\u8054\u7CFB\u4EBA", [`id: ${idStr}`], errors.length ? errors : void 0);
153
+ showContactsAlert((0, import_i18n.t)("contacts.updateContact"), [`id: ${idStr}`], errors.length ? errors : void 0);
153
154
  return {};
154
155
  };
155
156
  const removeContactAsync = async (contactId) => {
156
157
  const errors = validateId(contactId, "contactId");
157
- showContactsAlert("\u5220\u9664\u8054\u7CFB\u4EBA", [`contactId: ${JSON.stringify(contactId)}`], errors.length ? errors : void 0);
158
+ showContactsAlert((0, import_i18n.t)("contacts.removeContact"), [`contactId: ${JSON.stringify(contactId)}`], errors.length ? errors : void 0);
158
159
  return {};
159
160
  };
160
161
  const shareContactAsync = async (contactId, message) => {
161
162
  const errors = validateId(contactId, "contactId");
162
- showContactsAlert("\u5206\u4EAB\u8054\u7CFB\u4EBA", [
163
+ showContactsAlert((0, import_i18n.t)("contacts.shareContact"), [
163
164
  `contactId: ${JSON.stringify(contactId)}`,
164
- `message: ${message != null ? JSON.stringify(message) : "(\u65E0)"}`
165
+ `message: ${message != null ? JSON.stringify(message) : (0, import_i18n.t)("common.none")}`
165
166
  ], errors.length ? errors : void 0);
166
167
  };
167
168
  const writeContactToFileAsync = async (query) => {
168
- showContactsAlert("\u5BFC\u51FA\u8054\u7CFB\u4EBA\u5230\u6587\u4EF6", [
169
- `query: ${query ? JSON.stringify(query) : "(\u65E0)"}`,
170
- "\u79D2\u54D2\u9884\u89C8\u6A21\u5F0F\u4E0D\u652F\u6301\u6B64\u64CD\u4F5C"
169
+ showContactsAlert((0, import_i18n.t)("contacts.exportToFile"), [
170
+ `query: ${query ? JSON.stringify(query) : (0, import_i18n.t)("common.none")}`,
171
+ (0, import_i18n.t)("preview.unsupportedOperation")
171
172
  ]);
172
173
  return "file://stub/contact.vcf";
173
174
  };
174
175
  const presentFormAsync = async (contactId) => {
175
- showContactsAlert("\u663E\u793A\u8054\u7CFB\u4EBA\u8868\u5355", [
176
- `contactId: ${contactId != null ? JSON.stringify(contactId) : "(\u65B0\u5EFA)"}`,
177
- "Web \u5E73\u53F0\u4E0D\u652F\u6301\u7CFB\u7EDF\u8054\u7CFB\u4EBA\u8868\u5355"
176
+ showContactsAlert((0, import_i18n.t)("contacts.presentForm"), [
177
+ `contactId: ${contactId != null ? JSON.stringify(contactId) : (0, import_i18n.t)("contacts.newContact")}`,
178
+ (0, import_i18n.t)("contacts.webUnsupportedForm")
178
179
  ]);
179
180
  return {};
180
181
  };
181
182
  const presentContactPickerAsync = async () => {
182
- showContactsAlert("\u9009\u62E9\u8054\u7CFB\u4EBA", ["Web \u5E73\u53F0\u4E0D\u652F\u6301\u901A\u8BAF\u5F55\u9009\u62E9\u5668"]);
183
+ showContactsAlert((0, import_i18n.t)("contacts.presentPicker"), [(0, import_i18n.t)("contacts.webUnsupportedPicker")]);
183
184
  return null;
184
185
  };
185
186
  const createGroupAsync = async (name) => {
186
187
  const errors = [];
187
- if (typeof name !== "string" || !name.trim()) errors.push("name \u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");
188
- showContactsAlert("\u521B\u5EFA\u8054\u7CFB\u4EBA\u5206\u7EC4", [`name: ${JSON.stringify(name)}`], errors.length ? errors : void 0);
188
+ if (typeof name !== "string" || !name.trim()) errors.push((0, import_i18n.t)("validation.mustBeNonEmptyString", { label: "name" }));
189
+ showContactsAlert((0, import_i18n.t)("contacts.createGroup"), [`name: ${JSON.stringify(name)}`], errors.length ? errors : void 0);
189
190
  return "stub-group-id";
190
191
  };
191
192
  const updateGroupNameAsync = async (groupName, groupId) => {
192
193
  const errors = [
193
- ...typeof groupName !== "string" || !groupName.trim() ? ["groupName \u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32"] : [],
194
+ ...typeof groupName !== "string" || !groupName.trim() ? [(0, import_i18n.t)("validation.mustBeNonEmptyString", { label: "groupName" })] : [],
194
195
  ...validateId(groupId, "groupId")
195
196
  ];
196
- showContactsAlert("\u66F4\u65B0\u5206\u7EC4\u540D\u79F0", [
197
+ showContactsAlert((0, import_i18n.t)("contacts.updateGroupName"), [
197
198
  `groupName: ${JSON.stringify(groupName)}`,
198
199
  `groupId: ${JSON.stringify(groupId)}`
199
200
  ], errors.length ? errors : void 0);
@@ -201,13 +202,13 @@ if (import_react_native.Platform.OS !== "web" && !(0, import_expo.isRunningInExp
201
202
  };
202
203
  const removeGroupAsync = async (groupId) => {
203
204
  const errors = validateId(groupId, "groupId");
204
- showContactsAlert("\u5220\u9664\u5206\u7EC4", [`groupId: ${JSON.stringify(groupId)}`], errors.length ? errors : void 0);
205
+ showContactsAlert((0, import_i18n.t)("contacts.removeGroup"), [`groupId: ${JSON.stringify(groupId)}`], errors.length ? errors : void 0);
205
206
  return {};
206
207
  };
207
208
  const getGroupsAsync = async (query) => {
208
- showContactsAlert("\u83B7\u53D6\u8054\u7CFB\u4EBA\u5206\u7EC4", [
209
- `query: ${query ? JSON.stringify(query) : "(\u65E0)"}`,
210
- "\u79D2\u54D2\u9884\u89C8\u6A21\u5F0F\u8FD4\u56DE\u7A7A\u5217\u8868"
209
+ showContactsAlert((0, import_i18n.t)("contacts.getGroups"), [
210
+ `query: ${query ? JSON.stringify(query) : (0, import_i18n.t)("common.none")}`,
211
+ (0, import_i18n.t)("preview.returnsEmptyList")
211
212
  ]);
212
213
  return [];
213
214
  };
@@ -216,7 +217,7 @@ if (import_react_native.Platform.OS !== "web" && !(0, import_expo.isRunningInExp
216
217
  ...validateId(contactId, "contactId"),
217
218
  ...validateId(groupId, "groupId")
218
219
  ];
219
- showContactsAlert("\u6DFB\u52A0\u8054\u7CFB\u4EBA\u5230\u5206\u7EC4", [
220
+ showContactsAlert((0, import_i18n.t)("contacts.addToGroup"), [
220
221
  `contactId: ${JSON.stringify(contactId)}`,
221
222
  `groupId: ${JSON.stringify(groupId)}`
222
223
  ], errors.length ? errors : void 0);
@@ -227,7 +228,7 @@ if (import_react_native.Platform.OS !== "web" && !(0, import_expo.isRunningInExp
227
228
  ...validateId(contactId, "contactId"),
228
229
  ...validateId(groupId, "groupId")
229
230
  ];
230
- showContactsAlert("\u4ECE\u5206\u7EC4\u79FB\u9664\u8054\u7CFB\u4EBA", [
231
+ showContactsAlert((0, import_i18n.t)("contacts.removeFromGroup"), [
231
232
  `contactId: ${JSON.stringify(contactId)}`,
232
233
  `groupId: ${JSON.stringify(groupId)}`
233
234
  ], errors.length ? errors : void 0);
@@ -238,21 +239,21 @@ if (import_react_native.Platform.OS !== "web" && !(0, import_expo.isRunningInExp
238
239
  ...validateId(groupId, "groupId"),
239
240
  ...validateId(containerId, "containerId")
240
241
  ];
241
- showContactsAlert("\u5C06\u5206\u7EC4\u6DFB\u52A0\u5230\u5BB9\u5668", [
242
+ showContactsAlert((0, import_i18n.t)("contacts.addGroupToContainer"), [
242
243
  `groupId: ${JSON.stringify(groupId)}`,
243
244
  `containerId: ${JSON.stringify(containerId)}`
244
245
  ], errors.length ? errors : void 0);
245
246
  return {};
246
247
  };
247
248
  const getContainersAsync = async (query) => {
248
- showContactsAlert("\u83B7\u53D6\u8054\u7CFB\u4EBA\u5BB9\u5668", [
249
- `query: ${query ? JSON.stringify(query) : "(\u65E0)"}`,
250
- "\u79D2\u54D2\u9884\u89C8\u6A21\u5F0F\u8FD4\u56DE\u7A7A\u5217\u8868"
249
+ showContactsAlert((0, import_i18n.t)("contacts.getContainers"), [
250
+ `query: ${query ? JSON.stringify(query) : (0, import_i18n.t)("common.none")}`,
251
+ (0, import_i18n.t)("preview.returnsEmptyList")
251
252
  ]);
252
253
  return [];
253
254
  };
254
255
  const getDefaultContainerIdAsync = async () => {
255
- showContactsAlert("\u83B7\u53D6\u9ED8\u8BA4\u5BB9\u5668 ID", ["\u79D2\u54D2\u9884\u89C8\u6A21\u5F0F\u4E0D\u652F\u6301\u6B64\u64CD\u4F5C"]);
256
+ showContactsAlert((0, import_i18n.t)("contacts.getDefaultContainerId"), [(0, import_i18n.t)("preview.unsupportedOperation")]);
256
257
  return null;
257
258
  };
258
259
  const addContactsChangeListener = (_listener) => {
@@ -260,7 +261,7 @@ if (import_react_native.Platform.OS !== "web" && !(0, import_expo.isRunningInExp
260
261
  } };
261
262
  };
262
263
  const presentAccessPickerAsync = async () => {
263
- showContactsAlert("\u9009\u62E9\u901A\u8BAF\u5F55\u8BBF\u95EE\u6743\u9650", ["Web \u5E73\u53F0\u4E0D\u652F\u6301\u6B64\u64CD\u4F5C"]);
264
+ showContactsAlert((0, import_i18n.t)("contacts.presentAccessPicker"), [(0, import_i18n.t)("contacts.webUnsupportedOperation")]);
264
265
  return [];
265
266
  };
266
267
  const enums = {