expo-invoke 1.0.0 → 1.1.0

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 CHANGED
@@ -10,6 +10,9 @@ The complete native-surface-to-JS bridge for Expo. Define one intent in `app.jso
10
10
 
11
11
  - [Requirements](#requirements)
12
12
  - [Installation](#installation)
13
+ - [Local build](#local-build)
14
+ - [EAS Build (cloud)](#eas-build-cloud)
15
+ - [EAS Build local](#eas-build-local)
13
16
  - [Quick Start](#quick-start)
14
17
  - [useInvoke() — Full API](#useinvoke--full-api)
15
18
  - [Hooks](#hooks)
@@ -59,14 +62,69 @@ The complete native-surface-to-JS bridge for Expo. Define one intent in `app.jso
59
62
  npx expo install expo-invoke
60
63
  ```
61
64
 
62
- Then rebuild your native app:
65
+ Then rebuild your native app. Choose the workflow that fits your project:
66
+
67
+ ### Local build
63
68
 
64
69
  ```bash
65
- npx expo prebuild
66
- npx expo run:ios
70
+ npx expo prebuild # generates native code from your app.json
71
+ npx expo run:ios # build + run on simulator or device
67
72
  npx expo run:android
68
73
  ```
69
74
 
75
+ ### EAS Build (cloud)
76
+
77
+ expo-invoke works fully with [EAS Build](https://docs.expo.dev/build/introduction/). EAS automatically runs `expo prebuild` before each build, so the config plugin generates all Swift and Kotlin code in the cloud — no local Xcode or Android Studio required.
78
+
79
+ ```bash
80
+ # Install EAS CLI
81
+ npm install -g eas-cli
82
+
83
+ # Configure your project (first time only)
84
+ eas build:configure
85
+
86
+ # Build for both platforms
87
+ eas build --platform all
88
+
89
+ # Or build for a specific platform
90
+ eas build --platform ios
91
+ eas build --platform android
92
+ ```
93
+
94
+ A minimal `eas.json` to get started:
95
+
96
+ ```json
97
+ {
98
+ "cli": {
99
+ "version": ">= 10.0.0"
100
+ },
101
+ "build": {
102
+ "development": {
103
+ "developmentClient": true,
104
+ "distribution": "internal"
105
+ },
106
+ "preview": {
107
+ "distribution": "internal"
108
+ },
109
+ "production": {}
110
+ },
111
+ "submit": {
112
+ "production": {}
113
+ }
114
+ }
115
+ ```
116
+
117
+ > **Development builds:** For the fastest iteration loop during development, use `eas build --profile development` to create a [development build](https://docs.expo.dev/develop/development-builds/introduction/) — a custom Expo Go that includes your native modules including expo-invoke.
118
+
119
+ ### EAS Build local
120
+
121
+ Run the EAS build pipeline locally (requires Xcode / Android Studio):
122
+
123
+ ```bash
124
+ eas build --platform ios --local
125
+ eas build --platform android --local
126
+ ```
127
+
70
128
  ---
71
129
 
72
130
  ## Quick Start
package/app.plugin.js ADDED
@@ -0,0 +1,2 @@
1
+ const mod = require('./build/plugin/src/withInvoke');
2
+ module.exports = mod.default ?? mod;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-invoke",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "The complete native-surface-to-JS bridge for Expo. One intent config → Siri, Google Assistant, home screen widgets, Dynamic Island, app icon menus, notification actions, NFC, QR, deep links and more — all through a single useInvoke() hook.",
5
5
  "main": "build/src/index.js",
6
6
  "module": "build/src/index.js",
@@ -10,12 +10,15 @@
10
10
  "require": "./build/src/index.js",
11
11
  "import": "./build/src/index.js",
12
12
  "types": "./build/src/index.d.ts"
13
- }
13
+ },
14
+ "./app.plugin": "./app.plugin.js",
15
+ "./app.plugin.js": "./app.plugin.js"
14
16
  },
15
17
  "expo": {
16
18
  "plugin": "./build/plugin/src/withInvoke"
17
19
  },
18
20
  "files": [
21
+ "app.plugin.js",
19
22
  "build",
20
23
  "ios",
21
24
  "android/src",
package/MIGRATION.md DELETED
@@ -1,125 +0,0 @@
1
- # Migration Guide
2
-
3
- ## From `expo-errands-assistant`
4
-
5
- The `expo-errands-assistant` local module was hardcoded for a single Siri action with no parameters, no Android support, and no reusability. `expo-invoke` replaces it entirely.
6
-
7
- ### Step 1 — Replace the import
8
-
9
- ```diff
10
- - import { useErrandsAssistant } from '../modules/expo-errands-assistant';
11
- + import { useInvokeInit, useInvoke } from 'expo-invoke';
12
- ```
13
-
14
- ### Step 2 — Replace the root-level init
15
-
16
- ```diff
17
- // app/_layout.tsx
18
- - useErrandsAssistant(); // old
19
- + useInvokeInit(); // new — same cold/warm start behaviour
20
- ```
21
-
22
- ### Step 3 — Replace the intent listener
23
-
24
- ```diff
25
- // Before
26
- - const { action } = useErrandsAssistant();
27
- - if (action === 'CreateErrand') { router.push('/create'); }
28
-
29
- // After
30
- + const { intent } = useInvoke({ intentId: 'create_errand' });
31
- + useEffect(() => { if (intent) router.push('/create'); }, [intent]);
32
- ```
33
-
34
- ### Step 4 — Move the native intent to app.json
35
-
36
- Delete the hardcoded Swift intent file. The config plugin generates it:
37
-
38
- ```json
39
- // app.json
40
- {
41
- "plugins": [["expo-invoke", {
42
- "intents": [{
43
- "id": "create_errand",
44
- "title": "Create an Errand",
45
- "phrases": ["Create an errand in ${applicationName}"]
46
- }]
47
- }]]
48
- }
49
- ```
50
-
51
- ---
52
-
53
- ## From `react-native-siri-shortcut`
54
-
55
- ### Install expo-invoke
56
-
57
- ```bash
58
- npx expo install expo-invoke
59
- npx expo uninstall react-native-siri-shortcut
60
- ```
61
-
62
- ### Replace donation calls
63
-
64
- ```diff
65
- - import SiriShortcuts from 'react-native-siri-shortcut';
66
- - SiriShortcuts.donateShortcut({ identifier: 'create', title: 'Create', userInfo: {} });
67
-
68
- + import { useDonation } from 'expo-invoke';
69
- + const { donate } = useDonation();
70
- + donate({ intentId: 'create_errand', title: 'Create an Errand' });
71
- ```
72
-
73
- ### Replace the shortcut listener
74
-
75
- ```diff
76
- - import { ShortcutListener } from 'react-native-siri-shortcut';
77
- - <ShortcutListener onShortcutReceived={({ identifier }) => { ... }} />
78
-
79
- + import { useInvoke } from 'expo-invoke';
80
- + const { intent } = useInvoke();
81
- + // intent.intentId === 'create_errand' when fired
82
- ```
83
-
84
- ---
85
-
86
- ## From `expo-siri-shortcut`
87
-
88
- ### Install expo-invoke
89
-
90
- ```bash
91
- npx expo install expo-invoke
92
- npx expo uninstall expo-siri-shortcut
93
- ```
94
-
95
- ### Replace the shortcut button
96
-
97
- ```diff
98
- - import { SiriShortcutButton } from 'expo-siri-shortcut';
99
- - <SiriShortcutButton shortcut={{ activityType: 'create', title: 'Create' }} />
100
-
101
- + import { AddToSiriButton } from 'expo-invoke';
102
- + <AddToSiriButton intentId="create_errand" />
103
- ```
104
-
105
- ### Replace the activity listener
106
-
107
- The old `expo-siri-shortcut` used `NSUserActivity`. `expo-invoke` uses the modern App Intents API. Replace the app delegate hook with `useInvokeInit()` and receive via `useInvoke()`.
108
-
109
- ---
110
-
111
- ## Key Behavioural Differences
112
-
113
- | Behaviour | Old packages | expo-invoke |
114
- |---|---|---|
115
- | iOS API | SiriKit (deprecated) | App Intents (iOS 16+) |
116
- | Android | None | Google App Actions BII |
117
- | Multi-intent | No | Yes — unlimited |
118
- | Parameters | None / manual | 8 typed parameter types |
119
- | Widget bridge | No | Yes — WidgetKit + AppWidgetProvider |
120
- | Dynamic Island | No | Yes |
121
- | Cold start TTL | None | 30s default, configurable |
122
- | Intent deduplication | No | Yes (2s window) |
123
- | Source attribution | No | 20 surfaces |
124
- | Testing utilities | No | mockInvoke, simulateColdStart |
125
- | CLI | No | validate, generate, test |
package/SECURITY.md DELETED
@@ -1,35 +0,0 @@
1
- # Security Policy
2
-
3
- ## Supported Versions
4
-
5
- | Version | Supported |
6
- |---|---|
7
- | 1.x (current) | ✓ |
8
-
9
- ## Reporting a Vulnerability
10
-
11
- **Do not open a public GitHub issue for security vulnerabilities.**
12
-
13
- Email: security@smarthivelabs.dev
14
-
15
- Please include:
16
- - Description of the vulnerability
17
- - Steps to reproduce
18
- - Affected versions
19
- - Potential impact
20
-
21
- We will acknowledge your report within 48 hours and aim to release a fix within 14 days for critical issues.
22
-
23
- ## Security Considerations for Users
24
-
25
- ### Intent ID exposure
26
- Intent IDs defined in `app.json` are visible in the compiled binary. Do not use intent IDs as security boundaries. Treat them as public routing tokens.
27
-
28
- ### Deep link → intent mapping
29
- Deep links that map to intents (`deepLinkPatterns` in config) process user-supplied URLs. Validate any parameters extracted from deep links before acting on them in your app.
30
-
31
- ### Widget / shared storage
32
- `useWidgetData()` stores values in a shared App Group container (iOS) or SharedPreferences (Android). Do not store sensitive data (tokens, PII) using this API.
33
-
34
- ### Notification action intents
35
- Notification action buttons trigger intents based on category IDs in the push payload. Ensure your push notification server validates recipient identity before sending notifications with action categories.