miaoda-expo-devkit 0.1.1-beta.38 → 0.1.1-beta.39
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/README.md +54 -4
- package/dist/metro.d.mts +19 -1
- package/dist/metro.d.ts +19 -1
- package/dist/metro.js +25 -2
- package/dist/metro.mjs +24 -2
- package/dist/rules/no-pressable-without-on-press.js +77 -0
- package/dist/stubs/expo-calendar-stub.js +353 -0
- package/oxlint-config.json +3 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -9,6 +9,7 @@ Expo / React Native 开发环境工具集,通过 Metro 构建层注入以下
|
|
|
9
9
|
- **LogBox 屏蔽** — web 平台禁用 Expo 全屏错误遮罩
|
|
10
10
|
- **expo-notifications stub** — Expo Go(Android)中提供 no-op 实现,核心 API 调用时弹出带参数校验的调试 Alert,Dev Build 透传真实模块
|
|
11
11
|
- **expo-media-library stub** — Expo Go / Web 中提供 no-op 实现,`saveToLibraryAsync`、`createAssetAsync`、权限请求等 API 调用时弹出 Alert 提示,Dev Build 原生环境透传真实模块
|
|
12
|
+
- **expo-calendar stub** — Expo Go / Web 中提供 no-op 实现,`getEventsAsync`、`createEventAsync`、`getCalendarsAsync`、权限请求等核心 API 调用时弹出 Alert 提示并校验参数,Dev Build 原生环境透传真实模块
|
|
12
13
|
|
|
13
14
|
## 安装
|
|
14
15
|
|
|
@@ -39,11 +40,11 @@ const { withDevkit } = require('miaoda-expo-devkit/metro');
|
|
|
39
40
|
module.exports = withDevkit(getDefaultConfig(__dirname));
|
|
40
41
|
```
|
|
41
42
|
|
|
42
|
-
`withDevkit` 已内置所有 wrapper(含 expo-notifications、expo-media-library stub),无需手动叠加。也可单独使用各 wrapper:
|
|
43
|
+
`withDevkit` 已内置所有 wrapper(含 expo-notifications、expo-media-library、expo-calendar stub),无需手动叠加。也可单独使用各 wrapper:
|
|
43
44
|
|
|
44
45
|
```js
|
|
45
|
-
const { withDevStubs, withEntryInjection, withExpoMediaLibraryStub } = require('miaoda-expo-devkit/metro');
|
|
46
|
-
module.exports = withExpoMediaLibraryStub(withEntryInjection(withDevStubs(config)));
|
|
46
|
+
const { withDevStubs, withEntryInjection, withExpoMediaLibraryStub, withExpoCalendarStub } = require('miaoda-expo-devkit/metro');
|
|
47
|
+
module.exports = withExpoCalendarStub(withExpoMediaLibraryStub(withEntryInjection(withDevStubs(config))));
|
|
47
48
|
```
|
|
48
49
|
|
|
49
50
|
### Sentry 初始化
|
|
@@ -243,6 +244,11 @@ metro.config.js
|
|
|
243
244
|
│ ├─ Expo Go / Web:no-op + Alert 提示(不崩溃)
|
|
244
245
|
│ └─ Dev Build(原生):透传真实 expo-media-library
|
|
245
246
|
│
|
|
247
|
+
├─ withExpoCalendarStub → resolver.resolveRequest
|
|
248
|
+
│ └─ expo-calendar → dist/stubs/expo-calendar-stub.js (全平台)
|
|
249
|
+
│ ├─ Expo Go / Web:no-op + Alert 提示 + 参数校验(不崩溃)
|
|
250
|
+
│ └─ Dev Build(原生):透传真实 expo-calendar
|
|
251
|
+
│
|
|
246
252
|
└─ withEntryInjection → resolver.resolveRequest
|
|
247
253
|
└─ expo-router/entry-classic → dist/stubs/expo-router-entry-stub.js
|
|
248
254
|
├─ require('./entry-inject') ← 注入脚本(bundle 首部执行)
|
|
@@ -274,13 +280,14 @@ sentry-react-native-stub.js
|
|
|
274
280
|
| 子路径 | 文件 | 内容 |
|
|
275
281
|
|---|---|---|
|
|
276
282
|
| `.` | `dist/index.js` | `SentryCapture`、`MetroSymbolicator`、全部类型 |
|
|
277
|
-
| `./metro` | `dist/metro.js` | `withDevkit`、`withDevStubs`、`withEntryInjection`、`withExpoNotificationsStub`、`withExpoMediaLibraryStub` 等 |
|
|
283
|
+
| `./metro` | `dist/metro.js` | `withDevkit`、`withDevStubs`、`withEntryInjection`、`withExpoNotificationsStub`、`withExpoMediaLibraryStub`、`withExpoCalendarStub` 等 |
|
|
278
284
|
| `./babel-plugin-jsx-source` | `dist/babel/plugin-jsx-source.js` | Babel 插件:为 JSX 注入 source 信息 |
|
|
279
285
|
| `./babel-preset` | `dist/babel/preset.js` | Babel Preset:集成 jsx-source 和 lucide 插件 |
|
|
280
286
|
| `./sentry-react-native-stub` | `dist/stubs/sentry-react-native-stub.js` | `@sentry/react-native` 模块替换 stub |
|
|
281
287
|
| `./no-op-logbox` | `dist/stubs/no-op-logbox.js` | LogBox no-op stub |
|
|
282
288
|
| `./expo-notifications-stub` | `dist/stubs/expo-notifications-stub.js` | `expo-notifications` Expo Go Android stub |
|
|
283
289
|
| `./expo-media-library-stub` | `dist/stubs/expo-media-library-stub.js` | `expo-media-library` Expo Go / Web stub |
|
|
290
|
+
| `./expo-calendar-stub` | `dist/stubs/expo-calendar-stub.js` | `expo-calendar` Expo Go / Web stub |
|
|
284
291
|
|
|
285
292
|
---
|
|
286
293
|
|
|
@@ -445,6 +452,49 @@ Expo Go 扫码预览不支持访问手机相册
|
|
|
445
452
|
|
|
446
453
|
---
|
|
447
454
|
|
|
455
|
+
### expo-calendar-stub.js
|
|
456
|
+
|
|
457
|
+
`expo-calendar` 模块替换 stub,由 `withExpoCalendarStub()` 在 Metro 层注入(**全平台**)。
|
|
458
|
+
|
|
459
|
+
**背景:** `expo-calendar` 依赖原生系统日历 API,在 Expo Go 和 Web 环境中不可用,调用 `getEventsAsync` 等 API 会直接崩溃。
|
|
460
|
+
|
|
461
|
+
**运行时行为:**
|
|
462
|
+
- **Expo Go / Web**:提供 no-op 实现,以下 API 调用时弹出 Alert / Dialog 提示(不崩溃):
|
|
463
|
+
- `useCalendarPermissions()` / `useRemindersPermissions()` — 初始返回 `undetermined`,`requestPermission()` 弹 Alert
|
|
464
|
+
- `requestCalendarPermissionsAsync()` / `requestRemindersPermissionsAsync()` — 弹 Alert 提示,返回 denied
|
|
465
|
+
- `getCalendarPermissionsAsync()` / `getRemindersPermissionsAsync()` — 静默返回 denied
|
|
466
|
+
- `getCalendarsAsync(entityType?)` — 弹 Alert 显示查询类型,返回空数组
|
|
467
|
+
- `createCalendarAsync(details)` — 弹 Alert 含名称和颜色,校验 `details.title` 非空
|
|
468
|
+
- `updateCalendarAsync(id, details)` / `deleteCalendarAsync(id)` — 弹 Alert 含日历 ID,校验 ID 格式
|
|
469
|
+
- `getEventsAsync(calendarIds, startDate, endDate)` — 弹 Alert 含时间范围,校验 calendarIds 非空及日期合法性,返回空数组
|
|
470
|
+
- `createEventAsync(calendarId, eventData)` — 弹 Alert 含标题和时间,Android 下校验 startDate/endDate
|
|
471
|
+
- `updateEventAsync(id, details)` / `deleteEventAsync(id)` — 弹 Alert 含事件 ID,校验 ID 格式
|
|
472
|
+
- 其他未知 API — Proxy 兜底,静默返回 `undefined`;以 `PermissionsAsync` 结尾的 API 返回 denied 结构
|
|
473
|
+
- **Development Build(原生)**:透传真实 `expo-calendar`,功能完全正常
|
|
474
|
+
|
|
475
|
+
**枚举常量**(stub & Dev Build 均可用):
|
|
476
|
+
`EntityTypes`、`Frequency`、`Availability`、`CalendarType`、`EventStatus`、`SourceType`、
|
|
477
|
+
`AttendeeRole`、`AttendeeStatus`、`AttendeeType`、`AlarmMethod`、`EventAccessLevel`、
|
|
478
|
+
`CalendarAccessLevel`、`ReminderStatus`、`DayOfTheWeek`、`MonthOfTheYear`
|
|
479
|
+
|
|
480
|
+
**Alert 消息格式(合规示例):**
|
|
481
|
+
```
|
|
482
|
+
创建日历事件
|
|
483
|
+
秒哒扫码预览不支持访问手机日历
|
|
484
|
+
|
|
485
|
+
日历 ID: cal1
|
|
486
|
+
标题: 团队会议
|
|
487
|
+
开始: 2025/1/1 10:00:00
|
|
488
|
+
结束: 2025/1/1 11:00:00
|
|
489
|
+
|
|
490
|
+
✅ 参数合规
|
|
491
|
+
发布为正式 App 后可正常使用
|
|
492
|
+
```
|
|
493
|
+
|
|
494
|
+
**手动验证:** 在 `devkit-e2e` App 中扫码进入「Calendar Stub 验证」页面,逐按钮触发并对照期望结果。
|
|
495
|
+
|
|
496
|
+
---
|
|
497
|
+
|
|
448
498
|
## Babel 插件:jsx-source
|
|
449
499
|
|
|
450
500
|
`babel-plugin-jsx-source` 为 JSX 元素注入 source 属性(文件路径、行列号),用于开发调试。通过 `dataSet` 对象注入,这是 React Web 可识别的数据通道。
|
package/dist/metro.d.mts
CHANGED
|
@@ -118,6 +118,7 @@ declare function withRouteEndpoint(config: MetroConfig, options: RouteEndpointOp
|
|
|
118
118
|
* withLucideResolver — 消除 lucide 子路径未在 exports 声明时的 warning
|
|
119
119
|
* withExpoNotificationsStub — Android:expo-notifications → stub(Expo Go no-op,Dev Build 透传)
|
|
120
120
|
* withExpoMediaLibraryStub — Web / Expo Go:expo-media-library → stub(弹 Alert 提示,Dev Build 透传)
|
|
121
|
+
* withExpoCalendarStub — Web / Expo Go:expo-calendar → stub(弹 Alert 提示,Dev Build 透传)
|
|
121
122
|
* withEntryInjection — 在 expo-router 启动前注入脚本(仅 __DEV__)
|
|
122
123
|
* withDevStubs — 替换 Sentry DSN / 屏蔽 LogBox(仅 __DEV__)
|
|
123
124
|
* withRouteEndpoint — 添加 /__routes 端点(仅 __DEV__)
|
|
@@ -277,6 +278,23 @@ declare function withExpoNotificationsStub(config: MetroConfig): MetroConfig;
|
|
|
277
278
|
*/
|
|
278
279
|
declare function withExpoMediaLibraryStub(config: MetroConfig): MetroConfig;
|
|
279
280
|
|
|
281
|
+
/**
|
|
282
|
+
* withExpoCalendarStub — Web / Expo Go 将 expo-calendar 替换为 stub
|
|
283
|
+
*
|
|
284
|
+
* expo-calendar 依赖 native module,在 Web 和 Expo Go 中不可用。
|
|
285
|
+
* stub 在运行时通过 Platform.OS 和 isRunningInExpoGo() 判断:
|
|
286
|
+
* - Web / Expo Go:no-op(核心 API 弹 Alert 提示,不崩溃)
|
|
287
|
+
* - Development Build(原生):透传真实 expo-calendar,功能完全正常
|
|
288
|
+
*
|
|
289
|
+
* 此 wrapper 需要在开发和生产构建中均生效,因为 native module 缺失是运行时问题。
|
|
290
|
+
*/
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* @param config Metro config 对象
|
|
294
|
+
* @returns 注入 resolveRequest 后的新 Metro config
|
|
295
|
+
*/
|
|
296
|
+
declare function withExpoCalendarStub(config: MetroConfig): MetroConfig;
|
|
297
|
+
|
|
280
298
|
/**
|
|
281
299
|
* 将 Metro transformer 的 minifier 切换为 esbuild。
|
|
282
300
|
*
|
|
@@ -302,4 +320,4 @@ declare function withEsbuildMinify(config: MetroConfig): MetroConfig;
|
|
|
302
320
|
|
|
303
321
|
declare function withWasmSupport(config: MetroConfig): MetroConfig;
|
|
304
322
|
|
|
305
|
-
export { type DevkitOptions, type InjectOptions, type PatchNativeWindCacheOptions, type RouteEndpointOptions, patchNativeWindCachePath, withCssInterop, withDevStubs, withDevkit, withEntryInjection, withEsbuildMinify, withExpoMediaLibraryStub, withExpoNotificationsStub, withLucideResolver, withNativeWind, withRouteEndpoint, withWasmSupport, withWorkspaceNodeModules };
|
|
323
|
+
export { type DevkitOptions, type InjectOptions, type PatchNativeWindCacheOptions, type RouteEndpointOptions, patchNativeWindCachePath, withCssInterop, withDevStubs, withDevkit, withEntryInjection, withEsbuildMinify, withExpoCalendarStub, withExpoMediaLibraryStub, withExpoNotificationsStub, withLucideResolver, withNativeWind, withRouteEndpoint, withWasmSupport, withWorkspaceNodeModules };
|
package/dist/metro.d.ts
CHANGED
|
@@ -118,6 +118,7 @@ declare function withRouteEndpoint(config: MetroConfig, options: RouteEndpointOp
|
|
|
118
118
|
* withLucideResolver — 消除 lucide 子路径未在 exports 声明时的 warning
|
|
119
119
|
* withExpoNotificationsStub — Android:expo-notifications → stub(Expo Go no-op,Dev Build 透传)
|
|
120
120
|
* withExpoMediaLibraryStub — Web / Expo Go:expo-media-library → stub(弹 Alert 提示,Dev Build 透传)
|
|
121
|
+
* withExpoCalendarStub — Web / Expo Go:expo-calendar → stub(弹 Alert 提示,Dev Build 透传)
|
|
121
122
|
* withEntryInjection — 在 expo-router 启动前注入脚本(仅 __DEV__)
|
|
122
123
|
* withDevStubs — 替换 Sentry DSN / 屏蔽 LogBox(仅 __DEV__)
|
|
123
124
|
* withRouteEndpoint — 添加 /__routes 端点(仅 __DEV__)
|
|
@@ -277,6 +278,23 @@ declare function withExpoNotificationsStub(config: MetroConfig): MetroConfig;
|
|
|
277
278
|
*/
|
|
278
279
|
declare function withExpoMediaLibraryStub(config: MetroConfig): MetroConfig;
|
|
279
280
|
|
|
281
|
+
/**
|
|
282
|
+
* withExpoCalendarStub — Web / Expo Go 将 expo-calendar 替换为 stub
|
|
283
|
+
*
|
|
284
|
+
* expo-calendar 依赖 native module,在 Web 和 Expo Go 中不可用。
|
|
285
|
+
* stub 在运行时通过 Platform.OS 和 isRunningInExpoGo() 判断:
|
|
286
|
+
* - Web / Expo Go:no-op(核心 API 弹 Alert 提示,不崩溃)
|
|
287
|
+
* - Development Build(原生):透传真实 expo-calendar,功能完全正常
|
|
288
|
+
*
|
|
289
|
+
* 此 wrapper 需要在开发和生产构建中均生效,因为 native module 缺失是运行时问题。
|
|
290
|
+
*/
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* @param config Metro config 对象
|
|
294
|
+
* @returns 注入 resolveRequest 后的新 Metro config
|
|
295
|
+
*/
|
|
296
|
+
declare function withExpoCalendarStub(config: MetroConfig): MetroConfig;
|
|
297
|
+
|
|
280
298
|
/**
|
|
281
299
|
* 将 Metro transformer 的 minifier 切换为 esbuild。
|
|
282
300
|
*
|
|
@@ -302,4 +320,4 @@ declare function withEsbuildMinify(config: MetroConfig): MetroConfig;
|
|
|
302
320
|
|
|
303
321
|
declare function withWasmSupport(config: MetroConfig): MetroConfig;
|
|
304
322
|
|
|
305
|
-
export { type DevkitOptions, type InjectOptions, type PatchNativeWindCacheOptions, type RouteEndpointOptions, patchNativeWindCachePath, withCssInterop, withDevStubs, withDevkit, withEntryInjection, withEsbuildMinify, withExpoMediaLibraryStub, withExpoNotificationsStub, withLucideResolver, withNativeWind, withRouteEndpoint, withWasmSupport, withWorkspaceNodeModules };
|
|
323
|
+
export { type DevkitOptions, type InjectOptions, type PatchNativeWindCacheOptions, type RouteEndpointOptions, patchNativeWindCachePath, withCssInterop, withDevStubs, withDevkit, withEntryInjection, withEsbuildMinify, withExpoCalendarStub, withExpoMediaLibraryStub, withExpoNotificationsStub, withLucideResolver, withNativeWind, withRouteEndpoint, withWasmSupport, withWorkspaceNodeModules };
|
package/dist/metro.js
CHANGED
|
@@ -36,6 +36,7 @@ __export(metro_exports, {
|
|
|
36
36
|
withDevkit: () => withDevkit,
|
|
37
37
|
withEntryInjection: () => withEntryInjection,
|
|
38
38
|
withEsbuildMinify: () => withEsbuildMinify,
|
|
39
|
+
withExpoCalendarStub: () => withExpoCalendarStub,
|
|
39
40
|
withExpoMediaLibraryStub: () => withExpoMediaLibraryStub,
|
|
40
41
|
withExpoNotificationsStub: () => withExpoNotificationsStub,
|
|
41
42
|
withLucideResolver: () => withLucideResolver,
|
|
@@ -285,7 +286,7 @@ function withCssInterop(config) {
|
|
|
285
286
|
}
|
|
286
287
|
|
|
287
288
|
// src/metro/withDevkit.ts
|
|
288
|
-
var
|
|
289
|
+
var import_path11 = __toESM(require("path"));
|
|
289
290
|
|
|
290
291
|
// src/metro/withEsbuildMinify.ts
|
|
291
292
|
function withEsbuildMinify(config) {
|
|
@@ -384,6 +385,26 @@ function withExpoMediaLibraryStub(config) {
|
|
|
384
385
|
return { ...config, resolver: { ...config.resolver, resolveRequest } };
|
|
385
386
|
}
|
|
386
387
|
|
|
388
|
+
// src/metro/withExpoCalendarStub.ts
|
|
389
|
+
var import_path10 = __toESM(require("path"));
|
|
390
|
+
var EXPO_CALENDAR_STUB_FILENAME = "expo-calendar-stub.js";
|
|
391
|
+
var EXPO_CALENDAR_STUB_PATH = import_path10.default.resolve(
|
|
392
|
+
__dirname,
|
|
393
|
+
"stubs",
|
|
394
|
+
EXPO_CALENDAR_STUB_FILENAME
|
|
395
|
+
);
|
|
396
|
+
function withExpoCalendarStub(config) {
|
|
397
|
+
const upstream = config.resolver?.resolveRequest ?? null;
|
|
398
|
+
const resolveRequest = (context, moduleName, platform) => {
|
|
399
|
+
if (moduleName === "expo-calendar" && !context.originModulePath.includes(EXPO_CALENDAR_STUB_FILENAME)) {
|
|
400
|
+
return { filePath: EXPO_CALENDAR_STUB_PATH, type: "sourceFile" };
|
|
401
|
+
}
|
|
402
|
+
if (upstream) return upstream(context, moduleName, platform);
|
|
403
|
+
return context.resolveRequest(context, moduleName, platform);
|
|
404
|
+
};
|
|
405
|
+
return { ...config, resolver: { ...config.resolver, resolveRequest } };
|
|
406
|
+
}
|
|
407
|
+
|
|
387
408
|
// src/metro/withWasmSupport.ts
|
|
388
409
|
function withWasmSupport(config) {
|
|
389
410
|
const existing = config.resolver?.assetExts ?? [];
|
|
@@ -408,10 +429,11 @@ function withDevkit(config, options = {}) {
|
|
|
408
429
|
config = withLucideResolver(config);
|
|
409
430
|
config = withExpoNotificationsStub(config);
|
|
410
431
|
config = withExpoMediaLibraryStub(config);
|
|
432
|
+
config = withExpoCalendarStub(config);
|
|
411
433
|
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
412
434
|
config = withEntryInjection(config);
|
|
413
435
|
config = withDevStubs(config);
|
|
414
|
-
config = withRouteEndpoint(config, { appDir:
|
|
436
|
+
config = withRouteEndpoint(config, { appDir: import_path11.default.join(projectRoot, "src", "app") });
|
|
415
437
|
}
|
|
416
438
|
return withNativeWind(config, { input, inlineRem: 16 });
|
|
417
439
|
}
|
|
@@ -431,6 +453,7 @@ try {
|
|
|
431
453
|
withDevkit,
|
|
432
454
|
withEntryInjection,
|
|
433
455
|
withEsbuildMinify,
|
|
456
|
+
withExpoCalendarStub,
|
|
434
457
|
withExpoMediaLibraryStub,
|
|
435
458
|
withExpoNotificationsStub,
|
|
436
459
|
withLucideResolver,
|
package/dist/metro.mjs
CHANGED
|
@@ -244,7 +244,7 @@ function withCssInterop(config) {
|
|
|
244
244
|
}
|
|
245
245
|
|
|
246
246
|
// src/metro/withDevkit.ts
|
|
247
|
-
import
|
|
247
|
+
import path11 from "path";
|
|
248
248
|
|
|
249
249
|
// src/metro/withEsbuildMinify.ts
|
|
250
250
|
function withEsbuildMinify(config) {
|
|
@@ -343,6 +343,26 @@ function withExpoMediaLibraryStub(config) {
|
|
|
343
343
|
return { ...config, resolver: { ...config.resolver, resolveRequest } };
|
|
344
344
|
}
|
|
345
345
|
|
|
346
|
+
// src/metro/withExpoCalendarStub.ts
|
|
347
|
+
import path10 from "path";
|
|
348
|
+
var EXPO_CALENDAR_STUB_FILENAME = "expo-calendar-stub.js";
|
|
349
|
+
var EXPO_CALENDAR_STUB_PATH = path10.resolve(
|
|
350
|
+
__dirname,
|
|
351
|
+
"stubs",
|
|
352
|
+
EXPO_CALENDAR_STUB_FILENAME
|
|
353
|
+
);
|
|
354
|
+
function withExpoCalendarStub(config) {
|
|
355
|
+
const upstream = config.resolver?.resolveRequest ?? null;
|
|
356
|
+
const resolveRequest = (context, moduleName, platform) => {
|
|
357
|
+
if (moduleName === "expo-calendar" && !context.originModulePath.includes(EXPO_CALENDAR_STUB_FILENAME)) {
|
|
358
|
+
return { filePath: EXPO_CALENDAR_STUB_PATH, type: "sourceFile" };
|
|
359
|
+
}
|
|
360
|
+
if (upstream) return upstream(context, moduleName, platform);
|
|
361
|
+
return context.resolveRequest(context, moduleName, platform);
|
|
362
|
+
};
|
|
363
|
+
return { ...config, resolver: { ...config.resolver, resolveRequest } };
|
|
364
|
+
}
|
|
365
|
+
|
|
346
366
|
// src/metro/withWasmSupport.ts
|
|
347
367
|
function withWasmSupport(config) {
|
|
348
368
|
const existing = config.resolver?.assetExts ?? [];
|
|
@@ -367,10 +387,11 @@ function withDevkit(config, options = {}) {
|
|
|
367
387
|
config = withLucideResolver(config);
|
|
368
388
|
config = withExpoNotificationsStub(config);
|
|
369
389
|
config = withExpoMediaLibraryStub(config);
|
|
390
|
+
config = withExpoCalendarStub(config);
|
|
370
391
|
if (typeof __DEV__ !== "undefined" && __DEV__) {
|
|
371
392
|
config = withEntryInjection(config);
|
|
372
393
|
config = withDevStubs(config);
|
|
373
|
-
config = withRouteEndpoint(config, { appDir:
|
|
394
|
+
config = withRouteEndpoint(config, { appDir: path11.join(projectRoot, "src", "app") });
|
|
374
395
|
}
|
|
375
396
|
return withNativeWind(config, { input, inlineRem: 16 });
|
|
376
397
|
}
|
|
@@ -389,6 +410,7 @@ export {
|
|
|
389
410
|
withDevkit,
|
|
390
411
|
withEntryInjection,
|
|
391
412
|
withEsbuildMinify,
|
|
413
|
+
withExpoCalendarStub,
|
|
392
414
|
withExpoMediaLibraryStub,
|
|
393
415
|
withExpoNotificationsStub,
|
|
394
416
|
withLucideResolver,
|
|
@@ -0,0 +1,77 @@
|
|
|
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-pressable-without-on-press.ts
|
|
21
|
+
var no_pressable_without_on_press_exports = {};
|
|
22
|
+
__export(no_pressable_without_on_press_exports, {
|
|
23
|
+
default: () => no_pressable_without_on_press_default
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(no_pressable_without_on_press_exports);
|
|
26
|
+
var PRESSABLE_COMPONENTS = /* @__PURE__ */ new Set([
|
|
27
|
+
"Pressable",
|
|
28
|
+
"TouchableOpacity",
|
|
29
|
+
"TouchableHighlight",
|
|
30
|
+
"TouchableNativeFeedback",
|
|
31
|
+
"TouchableWithoutFeedback"
|
|
32
|
+
]);
|
|
33
|
+
function hasOnPress(attrs) {
|
|
34
|
+
return attrs.some((attr) => {
|
|
35
|
+
if (attr.type !== "JSXAttribute") return false;
|
|
36
|
+
const n = attr.name;
|
|
37
|
+
return n.type === "JSXIdentifier" && n.name === "onPress";
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
var noPressableWithoutOnPressRule = {
|
|
41
|
+
meta: {
|
|
42
|
+
type: "problem",
|
|
43
|
+
docs: {
|
|
44
|
+
description: "Pressable-family components must have an onPress handler."
|
|
45
|
+
},
|
|
46
|
+
schema: [],
|
|
47
|
+
messages: {
|
|
48
|
+
missingOnPress: "<{{name}}> is missing onPress. Add: onPress={() => { /* handler */ }}"
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
create(context) {
|
|
52
|
+
function check(node) {
|
|
53
|
+
const nameNode = node.name;
|
|
54
|
+
if (nameNode.type !== "JSXIdentifier") return;
|
|
55
|
+
const componentName = nameNode.name;
|
|
56
|
+
if (!componentName || !PRESSABLE_COMPONENTS.has(componentName)) return;
|
|
57
|
+
const attrs = node.attributes;
|
|
58
|
+
if (!hasOnPress(attrs)) {
|
|
59
|
+
context.report({
|
|
60
|
+
node,
|
|
61
|
+
messageId: "missingOnPress",
|
|
62
|
+
data: { name: componentName }
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return {
|
|
67
|
+
JSXOpeningElement: check,
|
|
68
|
+
JSXSelfClosingElement: check
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
var plugin = {
|
|
73
|
+
meta: { name: "rn-pressable" },
|
|
74
|
+
rules: { "no-pressable-without-on-press": noPressableWithoutOnPressRule }
|
|
75
|
+
};
|
|
76
|
+
var no_pressable_without_on_press_default = plugin;
|
|
77
|
+
module.exports = module.exports.default;
|
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var import_react_native = require("react-native");
|
|
3
|
+
var import_expo = require("expo");
|
|
4
|
+
var import_web_stub_dialog = require("./web-stub-dialog");
|
|
5
|
+
if (import_react_native.Platform.OS !== "web" && !(0, import_expo.isRunningInExpoGo)()) {
|
|
6
|
+
module.exports = require("expo-calendar");
|
|
7
|
+
} else {
|
|
8
|
+
let showCalendarAlert = function(title, lines, isValid, errors) {
|
|
9
|
+
if (import_react_native.Platform.OS === "web") {
|
|
10
|
+
(0, import_web_stub_dialog.showWebStubDialog)({
|
|
11
|
+
title,
|
|
12
|
+
details: lines,
|
|
13
|
+
errors: !isValid && errors && errors.length > 0 ? errors : void 0
|
|
14
|
+
});
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
const statusLine = isValid ? "\u2705 \u53C2\u6570\u5408\u89C4" : "\u274C \u53C2\u6570\u6709\u8BEF";
|
|
18
|
+
const parts = ["\u79D2\u54D2\u626B\u7801\u9884\u89C8\u4E0D\u652F\u6301\u8BBF\u95EE\u624B\u673A\u65E5\u5386", "", ...lines, "", statusLine];
|
|
19
|
+
if (!isValid && errors && errors.length > 0) {
|
|
20
|
+
parts.push(`\u95EE\u9898: ${errors.join(" / ")}`);
|
|
21
|
+
parts.push("");
|
|
22
|
+
parts.push("\u8BF7\u622A\u56FE\u53D1\u7ED9\u79D2\u54D2 Agent \u4FEE\u590D");
|
|
23
|
+
} else {
|
|
24
|
+
parts.push("");
|
|
25
|
+
parts.push("\u53D1\u5E03\u4E3A\u6B63\u5F0F App \u540E\u53EF\u6B63\u5E38\u4F7F\u7528");
|
|
26
|
+
}
|
|
27
|
+
import_react_native.Alert.alert(title, parts.join("\n"), [{ text: "\u77E5\u9053\u4E86" }]);
|
|
28
|
+
}, validateId = function(id, label = "id") {
|
|
29
|
+
const errors = [];
|
|
30
|
+
if (typeof id !== "string" || id.trim().length === 0) {
|
|
31
|
+
errors.push(`${label} \u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32`);
|
|
32
|
+
}
|
|
33
|
+
return { ok: errors.length === 0, errors };
|
|
34
|
+
}, validateDate = function(value, label) {
|
|
35
|
+
const errors = [];
|
|
36
|
+
if (value == null) {
|
|
37
|
+
errors.push(`${label} \u4E0D\u80FD\u4E3A\u7A7A`);
|
|
38
|
+
} else if (!(value instanceof Date) && typeof value !== "string") {
|
|
39
|
+
errors.push(`${label} \u5FC5\u987B\u662F Date \u6216\u65E5\u671F\u5B57\u7B26\u4E32`);
|
|
40
|
+
} else if (value instanceof Date && isNaN(value.getTime())) {
|
|
41
|
+
errors.push(`${label} \u662F\u65E0\u6548\u7684 Date \u5BF9\u8C61`);
|
|
42
|
+
}
|
|
43
|
+
return errors;
|
|
44
|
+
}, formatDateArg = function(value) {
|
|
45
|
+
if (value instanceof Date) return value.toLocaleString();
|
|
46
|
+
if (typeof value === "string") return value;
|
|
47
|
+
return String(value);
|
|
48
|
+
}, useCalendarPermissions = function() {
|
|
49
|
+
const [permission, setPermission] = useState(UNDETERMINED_PERMISSION);
|
|
50
|
+
const requestPermission = useCallback(async () => {
|
|
51
|
+
showCalendarAlert(
|
|
52
|
+
"\u8BF7\u6C42\u65E5\u5386\u6743\u9650",
|
|
53
|
+
["\u64CD\u4F5C: \u8BF7\u6C42\u8BBF\u95EE\u624B\u673A\u65E5\u5386\u6743\u9650", "\u79D2\u54D2\u9884\u89C8\u6A21\u5F0F\u4E0B\u6A21\u62DF\u8FD4\u56DE\u672A\u6388\u6743", "\u53D1\u5E03\u6B63\u5F0F App \u540E\u4F1A\u5F39\u51FA\u7CFB\u7EDF\u6388\u6743\u5F39\u7A97"],
|
|
54
|
+
true
|
|
55
|
+
);
|
|
56
|
+
setPermission(DENIED_PERMISSION);
|
|
57
|
+
return DENIED_PERMISSION;
|
|
58
|
+
}, []);
|
|
59
|
+
const getPermission = useCallback(async () => permission, [permission]);
|
|
60
|
+
return [permission, requestPermission, getPermission];
|
|
61
|
+
}, useRemindersPermissions = function() {
|
|
62
|
+
const [permission, setPermission] = useState(UNDETERMINED_PERMISSION);
|
|
63
|
+
const requestPermission = useCallback(async () => {
|
|
64
|
+
showCalendarAlert(
|
|
65
|
+
"\u8BF7\u6C42\u63D0\u9192\u4E8B\u9879\u6743\u9650",
|
|
66
|
+
["\u64CD\u4F5C: \u8BF7\u6C42\u8BBF\u95EE\u624B\u673A\u63D0\u9192\u4E8B\u9879\u6743\u9650\uFF08iOS \u4E13\u5C5E\uFF09", "\u79D2\u54D2\u9884\u89C8\u6A21\u5F0F\u4E0B\u6A21\u62DF\u8FD4\u56DE\u672A\u6388\u6743", "\u53D1\u5E03\u6B63\u5F0F App \u540E\u4F1A\u5F39\u51FA\u7CFB\u7EDF\u6388\u6743\u5F39\u7A97"],
|
|
67
|
+
true
|
|
68
|
+
);
|
|
69
|
+
setPermission(DENIED_PERMISSION);
|
|
70
|
+
return DENIED_PERMISSION;
|
|
71
|
+
}, []);
|
|
72
|
+
const getPermission = useCallback(async () => permission, [permission]);
|
|
73
|
+
return [permission, requestPermission, getPermission];
|
|
74
|
+
};
|
|
75
|
+
var showCalendarAlert2 = showCalendarAlert, validateId2 = validateId, validateDate2 = validateDate, formatDateArg2 = formatDateArg, useCalendarPermissions2 = useCalendarPermissions, useRemindersPermissions2 = useRemindersPermissions;
|
|
76
|
+
const UNDETERMINED_PERMISSION = {
|
|
77
|
+
status: "undetermined",
|
|
78
|
+
granted: false,
|
|
79
|
+
canAskAgain: true,
|
|
80
|
+
expires: "never"
|
|
81
|
+
};
|
|
82
|
+
const DENIED_PERMISSION = {
|
|
83
|
+
status: "denied",
|
|
84
|
+
granted: false,
|
|
85
|
+
canAskAgain: false,
|
|
86
|
+
expires: "never"
|
|
87
|
+
};
|
|
88
|
+
const { useState, useCallback } = require("react");
|
|
89
|
+
const requestCalendarPermissionsAsync = async () => {
|
|
90
|
+
showCalendarAlert(
|
|
91
|
+
"\u8BF7\u6C42\u65E5\u5386\u6743\u9650",
|
|
92
|
+
["\u64CD\u4F5C: \u8BF7\u6C42\u8BBF\u95EE\u624B\u673A\u65E5\u5386\u6743\u9650", "\u79D2\u54D2\u9884\u89C8\u6A21\u5F0F\u4E0B\u6A21\u62DF\u8FD4\u56DE\u672A\u6388\u6743", "\u53D1\u5E03\u6B63\u5F0F App \u540E\u4F1A\u5F39\u51FA\u7CFB\u7EDF\u6388\u6743\u5F39\u7A97"],
|
|
93
|
+
true
|
|
94
|
+
);
|
|
95
|
+
return DENIED_PERMISSION;
|
|
96
|
+
};
|
|
97
|
+
const getCalendarPermissionsAsync = async () => DENIED_PERMISSION;
|
|
98
|
+
const requestRemindersPermissionsAsync = async () => {
|
|
99
|
+
showCalendarAlert(
|
|
100
|
+
"\u8BF7\u6C42\u63D0\u9192\u4E8B\u9879\u6743\u9650",
|
|
101
|
+
["\u64CD\u4F5C: \u8BF7\u6C42\u8BBF\u95EE\u624B\u673A\u63D0\u9192\u4E8B\u9879\u6743\u9650\uFF08iOS \u4E13\u5C5E\uFF09", "\u79D2\u54D2\u9884\u89C8\u6A21\u5F0F\u4E0B\u6A21\u62DF\u8FD4\u56DE\u672A\u6388\u6743"],
|
|
102
|
+
true
|
|
103
|
+
);
|
|
104
|
+
return DENIED_PERMISSION;
|
|
105
|
+
};
|
|
106
|
+
const getRemindersPermissionsAsync = async () => DENIED_PERMISSION;
|
|
107
|
+
const requestPermissionsAsync = requestCalendarPermissionsAsync;
|
|
108
|
+
const getPermissionsAsync = getCalendarPermissionsAsync;
|
|
109
|
+
const isAvailableAsync = async () => false;
|
|
110
|
+
const getCalendarsAsync = async (entityType) => {
|
|
111
|
+
const typeStr = entityType != null ? String(entityType) : "\u5168\u90E8";
|
|
112
|
+
showCalendarAlert("\u83B7\u53D6\u65E5\u5386\u5217\u8868", [`\u7C7B\u578B: ${typeStr}`, "\u79D2\u54D2\u9884\u89C8\u6A21\u5F0F\u8FD4\u56DE\u7A7A\u5217\u8868"], true);
|
|
113
|
+
return [];
|
|
114
|
+
};
|
|
115
|
+
const getDefaultCalendarAsync = async () => {
|
|
116
|
+
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"]);
|
|
117
|
+
return void 0;
|
|
118
|
+
};
|
|
119
|
+
const createCalendarAsync = async (details) => {
|
|
120
|
+
const errors = [];
|
|
121
|
+
const d = details && typeof details === "object" ? details : {};
|
|
122
|
+
const titleVal = d["title"];
|
|
123
|
+
if (typeof titleVal !== "string" || titleVal.trim().length === 0) {
|
|
124
|
+
errors.push("details.title \u5FC5\u987B\u662F\u975E\u7A7A\u5B57\u7B26\u4E32");
|
|
125
|
+
}
|
|
126
|
+
const isValid = errors.length === 0;
|
|
127
|
+
const titleDisplay = typeof titleVal === "string" ? titleVal : "(\u672A\u586B\u5199)";
|
|
128
|
+
showCalendarAlert(
|
|
129
|
+
"\u521B\u5EFA\u65E5\u5386",
|
|
130
|
+
[`\u540D\u79F0: ${titleDisplay}`, `\u989C\u8272: ${d["color"] ?? "(\u672A\u8BBE\u7F6E)"}`],
|
|
131
|
+
isValid,
|
|
132
|
+
isValid ? void 0 : errors
|
|
133
|
+
);
|
|
134
|
+
return "stub";
|
|
135
|
+
};
|
|
136
|
+
const updateCalendarAsync = async (id, details) => {
|
|
137
|
+
const { ok: idOk, errors: idErrors } = validateId(id, "calendarId");
|
|
138
|
+
const d = details && typeof details === "object" ? details : {};
|
|
139
|
+
showCalendarAlert(
|
|
140
|
+
"\u66F4\u65B0\u65E5\u5386",
|
|
141
|
+
[
|
|
142
|
+
`\u65E5\u5386 ID: ${typeof id === "string" ? id : String(id)}`,
|
|
143
|
+
`\u66F4\u65B0\u5B57\u6BB5: ${Object.keys(d).join(", ") || "(\u65E0)"}`
|
|
144
|
+
],
|
|
145
|
+
idOk,
|
|
146
|
+
idOk ? void 0 : idErrors
|
|
147
|
+
);
|
|
148
|
+
return typeof id === "string" ? id : "stub";
|
|
149
|
+
};
|
|
150
|
+
const deleteCalendarAsync = async (id) => {
|
|
151
|
+
const { ok, errors } = validateId(id, "calendarId");
|
|
152
|
+
showCalendarAlert(
|
|
153
|
+
"\u5220\u9664\u65E5\u5386",
|
|
154
|
+
[`\u65E5\u5386 ID: ${typeof id === "string" ? id : String(id)}`],
|
|
155
|
+
ok,
|
|
156
|
+
ok ? void 0 : errors
|
|
157
|
+
);
|
|
158
|
+
};
|
|
159
|
+
const getEventsAsync = async (calendarIds, startDate, endDate) => {
|
|
160
|
+
const errors = [];
|
|
161
|
+
if (!Array.isArray(calendarIds) || calendarIds.length === 0) {
|
|
162
|
+
errors.push("calendarIds \u5FC5\u987B\u662F\u975E\u7A7A\u6570\u7EC4");
|
|
163
|
+
}
|
|
164
|
+
errors.push(...validateDate(startDate, "startDate"));
|
|
165
|
+
errors.push(...validateDate(endDate, "endDate"));
|
|
166
|
+
const isValid = errors.length === 0;
|
|
167
|
+
const idsStr = Array.isArray(calendarIds) ? `[${calendarIds.slice(0, 3).join(", ")}${calendarIds.length > 3 ? "\u2026" : ""}]` : String(calendarIds);
|
|
168
|
+
showCalendarAlert(
|
|
169
|
+
"\u67E5\u8BE2\u65E5\u5386\u4E8B\u4EF6",
|
|
170
|
+
[
|
|
171
|
+
`\u65E5\u5386 IDs: ${idsStr}`,
|
|
172
|
+
`\u5F00\u59CB\u65F6\u95F4: ${formatDateArg(startDate)}`,
|
|
173
|
+
`\u7ED3\u675F\u65F6\u95F4: ${formatDateArg(endDate)}`,
|
|
174
|
+
"\u79D2\u54D2\u9884\u89C8\u6A21\u5F0F\u8FD4\u56DE\u7A7A\u5217\u8868"
|
|
175
|
+
],
|
|
176
|
+
isValid,
|
|
177
|
+
isValid ? void 0 : errors
|
|
178
|
+
);
|
|
179
|
+
return [];
|
|
180
|
+
};
|
|
181
|
+
const getEventAsync = async (id) => {
|
|
182
|
+
const { ok, errors } = validateId(id, "eventId");
|
|
183
|
+
showCalendarAlert(
|
|
184
|
+
"\u83B7\u53D6\u65E5\u5386\u4E8B\u4EF6",
|
|
185
|
+
[`\u4E8B\u4EF6 ID: ${typeof id === "string" ? id : String(id)}`],
|
|
186
|
+
ok,
|
|
187
|
+
ok ? void 0 : errors
|
|
188
|
+
);
|
|
189
|
+
return void 0;
|
|
190
|
+
};
|
|
191
|
+
const createEventAsync = async (calendarId, eventData) => {
|
|
192
|
+
const errors = [];
|
|
193
|
+
const { errors: idErrors } = validateId(calendarId, "calendarId");
|
|
194
|
+
errors.push(...idErrors);
|
|
195
|
+
const data = eventData && typeof eventData === "object" ? eventData : {};
|
|
196
|
+
if (import_react_native.Platform.OS === "android") {
|
|
197
|
+
errors.push(...validateDate(data["startDate"], "eventData.startDate"));
|
|
198
|
+
errors.push(...validateDate(data["endDate"], "eventData.endDate"));
|
|
199
|
+
}
|
|
200
|
+
const titleVal = data["title"];
|
|
201
|
+
const titleDisplay = typeof titleVal === "string" ? titleVal : "(\u672A\u586B\u5199)";
|
|
202
|
+
const startDisplay = data["startDate"] != null ? formatDateArg(data["startDate"]) : "(\u672A\u8BBE\u7F6E)";
|
|
203
|
+
const endDisplay = data["endDate"] != null ? formatDateArg(data["endDate"]) : "(\u672A\u8BBE\u7F6E)";
|
|
204
|
+
const isValid = errors.length === 0;
|
|
205
|
+
showCalendarAlert(
|
|
206
|
+
"\u521B\u5EFA\u65E5\u5386\u4E8B\u4EF6",
|
|
207
|
+
[
|
|
208
|
+
`\u65E5\u5386 ID: ${typeof calendarId === "string" ? calendarId : String(calendarId)}`,
|
|
209
|
+
`\u6807\u9898: ${titleDisplay}`,
|
|
210
|
+
`\u5F00\u59CB: ${startDisplay}`,
|
|
211
|
+
`\u7ED3\u675F: ${endDisplay}`
|
|
212
|
+
],
|
|
213
|
+
isValid,
|
|
214
|
+
isValid ? void 0 : errors
|
|
215
|
+
);
|
|
216
|
+
return "stub";
|
|
217
|
+
};
|
|
218
|
+
const updateEventAsync = async (id, details) => {
|
|
219
|
+
const { ok, errors } = validateId(id, "eventId");
|
|
220
|
+
const d = details && typeof details === "object" ? details : {};
|
|
221
|
+
showCalendarAlert(
|
|
222
|
+
"\u66F4\u65B0\u65E5\u5386\u4E8B\u4EF6",
|
|
223
|
+
[
|
|
224
|
+
`\u4E8B\u4EF6 ID: ${typeof id === "string" ? id : String(id)}`,
|
|
225
|
+
`\u66F4\u65B0\u5B57\u6BB5: ${Object.keys(d).join(", ") || "(\u65E0)"}`
|
|
226
|
+
],
|
|
227
|
+
ok,
|
|
228
|
+
ok ? void 0 : errors
|
|
229
|
+
);
|
|
230
|
+
return typeof id === "string" ? id : "stub";
|
|
231
|
+
};
|
|
232
|
+
const deleteEventAsync = async (id) => {
|
|
233
|
+
const { ok, errors } = validateId(id, "eventId");
|
|
234
|
+
showCalendarAlert(
|
|
235
|
+
"\u5220\u9664\u65E5\u5386\u4E8B\u4EF6",
|
|
236
|
+
[`\u4E8B\u4EF6 ID: ${typeof id === "string" ? id : String(id)}`],
|
|
237
|
+
ok,
|
|
238
|
+
ok ? void 0 : errors
|
|
239
|
+
);
|
|
240
|
+
};
|
|
241
|
+
const enums = {
|
|
242
|
+
EntityTypes: { EVENT: "event", REMINDER: "reminder" },
|
|
243
|
+
Frequency: { DAILY: "daily", WEEKLY: "weekly", MONTHLY: "monthly", YEARLY: "yearly" },
|
|
244
|
+
Availability: {
|
|
245
|
+
NOT_SUPPORTED: "notSupported",
|
|
246
|
+
BUSY: "busy",
|
|
247
|
+
FREE: "free",
|
|
248
|
+
TENTATIVE: "tentative",
|
|
249
|
+
UNAVAILABLE: "unavailable"
|
|
250
|
+
},
|
|
251
|
+
CalendarType: {
|
|
252
|
+
LOCAL: "local",
|
|
253
|
+
CALDAV: "caldav",
|
|
254
|
+
EXCHANGE: "exchange",
|
|
255
|
+
SUBSCRIBED: "subscribed",
|
|
256
|
+
BIRTHDAYS: "birthdays",
|
|
257
|
+
UNKNOWN: "unknown"
|
|
258
|
+
},
|
|
259
|
+
EventStatus: { NONE: "none", CONFIRMED: "confirmed", TENTATIVE: "tentative", CANCELED: "canceled" },
|
|
260
|
+
SourceType: {
|
|
261
|
+
LOCAL: "local",
|
|
262
|
+
EXCHANGE: "exchange",
|
|
263
|
+
CALDAV: "caldav",
|
|
264
|
+
MOBILEME: "mobileme",
|
|
265
|
+
SUBSCRIBED: "subscribed",
|
|
266
|
+
BIRTHDAYS: "birthdays"
|
|
267
|
+
},
|
|
268
|
+
AttendeeRole: {
|
|
269
|
+
UNKNOWN: "unknown",
|
|
270
|
+
REQUIRED: "required",
|
|
271
|
+
OPTIONAL: "optional",
|
|
272
|
+
CHAIR: "chair",
|
|
273
|
+
NON_PARTICIPANT: "nonParticipant",
|
|
274
|
+
ATTENDEE: "attendee",
|
|
275
|
+
ORGANIZER: "organizer",
|
|
276
|
+
PERFORMER: "performer",
|
|
277
|
+
SPEAKER: "speaker",
|
|
278
|
+
NONE: "none"
|
|
279
|
+
},
|
|
280
|
+
AttendeeStatus: {
|
|
281
|
+
UNKNOWN: "unknown",
|
|
282
|
+
PENDING: "pending",
|
|
283
|
+
ACCEPTED: "accepted",
|
|
284
|
+
DECLINED: "declined",
|
|
285
|
+
TENTATIVE: "tentative",
|
|
286
|
+
DELEGATED: "delegated",
|
|
287
|
+
COMPLETED: "completed",
|
|
288
|
+
IN_PROCESS: "inProcess",
|
|
289
|
+
INVITED: "invited",
|
|
290
|
+
NONE: "none"
|
|
291
|
+
},
|
|
292
|
+
AttendeeType: {
|
|
293
|
+
UNKNOWN: "unknown",
|
|
294
|
+
PERSON: "person",
|
|
295
|
+
ROOM: "room",
|
|
296
|
+
GROUP: "group",
|
|
297
|
+
RESOURCE: "resource",
|
|
298
|
+
OPTIONAL: "optional",
|
|
299
|
+
REQUIRED: "required",
|
|
300
|
+
NONE: "none"
|
|
301
|
+
},
|
|
302
|
+
AlarmMethod: { ALARM: "alarm", ALERT: "alert", EMAIL: "email", SMS: "sms", DEFAULT: "default" },
|
|
303
|
+
EventAccessLevel: { CONFIDENTIAL: "confidential", PRIVATE: "private", PUBLIC: "public", DEFAULT: "default" },
|
|
304
|
+
CalendarAccessLevel: {
|
|
305
|
+
CONTRIBUTOR: "contributor",
|
|
306
|
+
EDITOR: "editor",
|
|
307
|
+
FREEBUSY: "freebusy",
|
|
308
|
+
OVERRIDE: "override",
|
|
309
|
+
OWNER: "owner",
|
|
310
|
+
READ: "read",
|
|
311
|
+
RESPOND: "respond",
|
|
312
|
+
ROOT: "root",
|
|
313
|
+
NONE: "none"
|
|
314
|
+
},
|
|
315
|
+
ReminderStatus: { COMPLETED: "completed", INCOMPLETE: "incomplete" },
|
|
316
|
+
PermissionStatus: { GRANTED: "granted", DENIED: "denied", UNDETERMINED: "undetermined" },
|
|
317
|
+
DayOfTheWeek: { SU: 1, MO: 2, TU: 3, WE: 4, TH: 5, FR: 6, SA: 7 },
|
|
318
|
+
MonthOfTheYear: { JAN: 1, FEB: 2, MAR: 3, APR: 4, MAY: 5, JUN: 6, JUL: 7, AUG: 8, SEP: 9, OCT: 10, NOV: 11, DEC: 12 },
|
|
319
|
+
CalendarDialogResultActions: { SAVED: "saved", CANCELED: "canceled", DELETED: "deleted" }
|
|
320
|
+
};
|
|
321
|
+
const coreHandlers = {
|
|
322
|
+
isAvailableAsync,
|
|
323
|
+
useCalendarPermissions,
|
|
324
|
+
useRemindersPermissions,
|
|
325
|
+
requestCalendarPermissionsAsync,
|
|
326
|
+
getCalendarPermissionsAsync,
|
|
327
|
+
requestRemindersPermissionsAsync,
|
|
328
|
+
getRemindersPermissionsAsync,
|
|
329
|
+
requestPermissionsAsync,
|
|
330
|
+
getPermissionsAsync,
|
|
331
|
+
getCalendarsAsync,
|
|
332
|
+
getDefaultCalendarAsync,
|
|
333
|
+
createCalendarAsync,
|
|
334
|
+
updateCalendarAsync,
|
|
335
|
+
deleteCalendarAsync,
|
|
336
|
+
getEventsAsync,
|
|
337
|
+
getEventAsync,
|
|
338
|
+
createEventAsync,
|
|
339
|
+
updateEventAsync,
|
|
340
|
+
deleteEventAsync
|
|
341
|
+
};
|
|
342
|
+
const noopPermission = async () => DENIED_PERMISSION;
|
|
343
|
+
const noop = async () => void 0;
|
|
344
|
+
module.exports = new Proxy(enums, {
|
|
345
|
+
get(target, key) {
|
|
346
|
+
if (key in target) return target[key];
|
|
347
|
+
if (key in coreHandlers) return coreHandlers[key];
|
|
348
|
+
if (key.endsWith("PermissionsAsync")) return noopPermission;
|
|
349
|
+
return noop;
|
|
350
|
+
}
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
//# sourceMappingURL=expo-calendar-stub.js.map
|
package/oxlint-config.json
CHANGED
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
{ "name": "expo-router-url", "specifier": "miaoda-expo-devkit/rules/no-duplicate-expo-router-url" },
|
|
9
9
|
{ "name": "css-import", "specifier": "miaoda-expo-devkit/rules/no-missing-css-import" },
|
|
10
10
|
{ "name": "expo-router-layout", "specifier": "miaoda-expo-devkit/rules/no-invalid-tabs-screen" },
|
|
11
|
-
{ "name": "expo-router-dynamic-tab", "specifier": "miaoda-expo-devkit/rules/no-unregistered-dynamic-tab-route" }
|
|
11
|
+
{ "name": "expo-router-dynamic-tab", "specifier": "miaoda-expo-devkit/rules/no-unregistered-dynamic-tab-route" },
|
|
12
|
+
{ "name": "rn-pressable", "specifier": "miaoda-expo-devkit/rules/no-pressable-without-on-press" }
|
|
12
13
|
],
|
|
13
14
|
|
|
14
15
|
"categories": {
|
|
@@ -23,6 +24,7 @@
|
|
|
23
24
|
"css-import/no-missing-css-import": "error",
|
|
24
25
|
"expo-router-layout/no-invalid-tabs-screen": "error",
|
|
25
26
|
"expo-router-dynamic-tab/no-unregistered-dynamic-tab-route": "error",
|
|
27
|
+
"rn-pressable/no-pressable-without-on-press": "error",
|
|
26
28
|
|
|
27
29
|
"expo/no-dynamic-env-var": "error",
|
|
28
30
|
"expo/no-env-var-destructuring": "error",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "miaoda-expo-devkit",
|
|
3
|
-
"version": "0.1.1-beta.
|
|
3
|
+
"version": "0.1.1-beta.39",
|
|
4
4
|
"description": "Expo 应用开发工具集:Sentry DSN 替换 stub、错误/网络捕获、Metro 符号化",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -46,6 +46,7 @@
|
|
|
46
46
|
"./no-op-logbox": "./dist/stubs/no-op-logbox.js",
|
|
47
47
|
"./expo-notifications-stub": "./dist/stubs/expo-notifications-stub.js",
|
|
48
48
|
"./expo-media-library-stub": "./dist/stubs/expo-media-library-stub.js",
|
|
49
|
+
"./expo-calendar-stub": "./dist/stubs/expo-calendar-stub.js",
|
|
49
50
|
"./rules/no-undeclared-expo-plugin": "./dist/rules/no-undeclared-expo-plugin.js",
|
|
50
51
|
"./rules/no-unused-expo-plugin": "./dist/rules/no-unused-expo-plugin.js",
|
|
51
52
|
"./rules/no-unstable-expo-router": "./dist/rules/no-unstable-expo-router.js",
|