react-native-iinstall 0.2.12 → 0.2.14
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/INTEGRATION_GUIDE.md +43 -5
- package/README.md +37 -2
- package/RELEASE_MANIFEST.json +8 -0
- package/lib/IInstallWrapper.d.ts +4 -0
- package/lib/IInstallWrapper.js +2 -2
- package/lib/index.d.ts +5 -0
- package/lib/index.js +56 -2
- package/lib/pushRegistration.d.ts +22 -0
- package/lib/pushRegistration.js +70 -0
- package/lib/scripts/check-release-manifest.d.mts +2 -0
- package/lib/scripts/check-release-manifest.mjs +38 -0
- package/lib/scripts/sync-release-manifest.d.mts +2 -0
- package/lib/scripts/sync-release-manifest.mjs +38 -0
- package/lib/src/FeedbackModal.d.ts +12 -0
- package/lib/src/FeedbackModal.js +393 -0
- package/lib/src/IInstallWrapper.d.ts +16 -0
- package/lib/src/IInstallWrapper.js +18 -0
- package/lib/src/ShakeDetector.d.ts +8 -0
- package/lib/src/ShakeDetector.js +68 -0
- package/lib/src/index.d.ts +17 -0
- package/lib/src/index.js +349 -0
- package/lib/src/nativeModules.d.ts +37 -0
- package/lib/src/nativeModules.js +231 -0
- package/lib/src/pushRegistration.d.ts +22 -0
- package/lib/src/pushRegistration.js +70 -0
- package/package.json +18 -8
- package/src/FeedbackModal.tsx +46 -41
- package/src/IInstallWrapper.tsx +12 -0
- package/src/index.tsx +92 -8
- package/src/nativeModules.ts +308 -0
- package/src/pushRegistration.ts +111 -0
package/INTEGRATION_GUIDE.md
CHANGED
|
@@ -48,14 +48,14 @@ yarn add react-native-iinstall
|
|
|
48
48
|
|
|
49
49
|
**Note**: The SDK automatically includes necessary dependencies like `react-native-sensors` and `react-native-view-shot`.
|
|
50
50
|
|
|
51
|
-
### Updating to Latest Version (v0.2.
|
|
51
|
+
### Updating to Latest Version (v0.2.13)
|
|
52
52
|
|
|
53
53
|
If you're using an older version, update to get the latest audio/video improvements:
|
|
54
54
|
|
|
55
55
|
```bash
|
|
56
|
-
npm install react-native-iinstall@0.2.
|
|
56
|
+
npm install react-native-iinstall@0.2.13
|
|
57
57
|
# OR
|
|
58
|
-
yarn add react-native-iinstall@0.2.
|
|
58
|
+
yarn add react-native-iinstall@0.2.13
|
|
59
59
|
```
|
|
60
60
|
|
|
61
61
|
**Key improvements in v0.2.7:**
|
|
@@ -98,7 +98,45 @@ export default App;
|
|
|
98
98
|
|
|
99
99
|
---
|
|
100
100
|
|
|
101
|
-
## 5.
|
|
101
|
+
## 5. Push Notification Token Registration (v0.2.13+)
|
|
102
|
+
|
|
103
|
+
If you pass `pushToken`, SDK auto-registers it to the backend using:
|
|
104
|
+
|
|
105
|
+
`POST /api/notifications/push/register`
|
|
106
|
+
|
|
107
|
+
```tsx
|
|
108
|
+
import React from 'react';
|
|
109
|
+
import messaging from '@react-native-firebase/messaging';
|
|
110
|
+
import { IInstall } from 'react-native-iinstall';
|
|
111
|
+
|
|
112
|
+
const App = () => {
|
|
113
|
+
const [pushToken, setPushToken] = React.useState<string>();
|
|
114
|
+
|
|
115
|
+
React.useEffect(() => {
|
|
116
|
+
messaging().getToken().then(setPushToken).catch(() => undefined);
|
|
117
|
+
}, []);
|
|
118
|
+
|
|
119
|
+
return (
|
|
120
|
+
<IInstall
|
|
121
|
+
apiKey="YOUR_COPIED_API_KEY_FROM_STEP_1"
|
|
122
|
+
apiEndpoint="https://iinstall.app"
|
|
123
|
+
pushToken={pushToken}
|
|
124
|
+
>
|
|
125
|
+
<AppNavigation />
|
|
126
|
+
</IInstall>
|
|
127
|
+
);
|
|
128
|
+
};
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Manual helpers are also exported:
|
|
132
|
+
|
|
133
|
+
```tsx
|
|
134
|
+
import { registerPushToken, unregisterPushToken } from 'react-native-iinstall';
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## 6. Audio & Video Feedback (v0.2.7+)
|
|
102
140
|
|
|
103
141
|
The SDK now supports **Audio Feedback** (Voice Notes) and **Screen Recording** with enhanced compatibility and reliability.
|
|
104
142
|
|
|
@@ -155,7 +193,7 @@ Add these keys inside the `<dict>` tag:
|
|
|
155
193
|
|
|
156
194
|
---
|
|
157
195
|
|
|
158
|
-
##
|
|
196
|
+
## 7. Generate & Upload Installer
|
|
159
197
|
|
|
160
198
|
1. **Build your app**:
|
|
161
199
|
* **Android**: `./gradlew assembleRelease` (outputs `.apk`)
|
package/README.md
CHANGED
|
@@ -34,9 +34,12 @@ Transform your app's feedback collection with our powerful shake-to-report SDK.
|
|
|
34
34
|
npm install react-native-iinstall
|
|
35
35
|
```
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
2. Install required native peer dependencies in your app root:
|
|
38
|
+
```bash
|
|
39
|
+
npm install react-native-sensors react-native-view-shot react-native-device-info react-native-audio-recorder-player react-native-record-screen
|
|
40
|
+
```
|
|
38
41
|
|
|
39
|
-
|
|
42
|
+
3. Link native modules (iOS only, non-Expo):
|
|
40
43
|
```bash
|
|
41
44
|
cd ios && pod install
|
|
42
45
|
```
|
|
@@ -49,13 +52,24 @@ Wrap your main app component with the `<IInstall>` provider.
|
|
|
49
52
|
import React from 'react';
|
|
50
53
|
import { IInstall } from 'react-native-iinstall';
|
|
51
54
|
import AppNavigation from './src/AppNavigation';
|
|
55
|
+
import messaging from '@react-native-firebase/messaging';
|
|
52
56
|
|
|
53
57
|
const App = () => {
|
|
58
|
+
const [pushToken, setPushToken] = React.useState<string>();
|
|
59
|
+
|
|
60
|
+
React.useEffect(() => {
|
|
61
|
+
messaging()
|
|
62
|
+
.getToken()
|
|
63
|
+
.then(setPushToken)
|
|
64
|
+
.catch(() => undefined);
|
|
65
|
+
}, []);
|
|
66
|
+
|
|
54
67
|
return (
|
|
55
68
|
// Get your API Key from the IInstall Dashboard (Project Settings)
|
|
56
69
|
<IInstall
|
|
57
70
|
apiKey="YOUR_PROJECT_API_KEY"
|
|
58
71
|
apiEndpoint="https://iinstall.app" // Optional, defaults to production
|
|
72
|
+
pushToken={pushToken} // Optional: auto-registers token to iinstall backend
|
|
59
73
|
enabled={__DEV__} // Optional: Only enable in dev/test builds
|
|
60
74
|
>
|
|
61
75
|
<AppNavigation />
|
|
@@ -131,6 +145,26 @@ Add to `Info.plist`:
|
|
|
131
145
|
</IInstall>
|
|
132
146
|
```
|
|
133
147
|
|
|
148
|
+
### Push Token Registration Helpers
|
|
149
|
+
|
|
150
|
+
You can also register/unregister tokens manually:
|
|
151
|
+
|
|
152
|
+
```tsx
|
|
153
|
+
import { registerPushToken, unregisterPushToken } from 'react-native-iinstall';
|
|
154
|
+
|
|
155
|
+
await registerPushToken({
|
|
156
|
+
token: fcmToken,
|
|
157
|
+
apiKey: 'YOUR_PROJECT_API_KEY',
|
|
158
|
+
apiEndpoint: 'https://iinstall.app',
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
await unregisterPushToken({
|
|
162
|
+
token: fcmToken,
|
|
163
|
+
apiKey: 'YOUR_PROJECT_API_KEY',
|
|
164
|
+
apiEndpoint: 'https://iinstall.app',
|
|
165
|
+
});
|
|
166
|
+
```
|
|
167
|
+
|
|
134
168
|
### Custom Triggers (Coming Soon)
|
|
135
169
|
- Button-based feedback
|
|
136
170
|
- Screenshot-only mode
|
|
@@ -143,6 +177,7 @@ Add to `Info.plist`:
|
|
|
143
177
|
- **Network errors?** Verify `apiEndpoint` is base URL only (not `/api/sdk/issue`)
|
|
144
178
|
- **Permissions denied?** Check platform-specific setup in integration guide
|
|
145
179
|
- **Audio issues?** Ensure SDK v0.2.7+ for AAC codec support
|
|
180
|
+
- **Native module is null/undefined?** Reinstall peer deps in app root, run `cd ios && pod install`, then rebuild the app
|
|
146
181
|
|
|
147
182
|
### Getting Help
|
|
148
183
|
- 📖 [Complete Integration Guide](INTEGRATION_GUIDE.md)
|
package/lib/IInstallWrapper.d.ts
CHANGED
|
@@ -7,6 +7,10 @@ interface IInstallWrapperProps {
|
|
|
7
7
|
showDebugButton?: boolean;
|
|
8
8
|
showFloatingButtonOnEmulator?: boolean;
|
|
9
9
|
floatingButtonLabel?: string;
|
|
10
|
+
pushToken?: string;
|
|
11
|
+
autoRegisterPushToken?: boolean;
|
|
12
|
+
projectId?: string;
|
|
13
|
+
onPushTokenRegisterError?: (error: string) => void;
|
|
10
14
|
}
|
|
11
15
|
export declare const IInstallWrapper: React.FC<IInstallWrapperProps>;
|
|
12
16
|
export default IInstallWrapper;
|
package/lib/IInstallWrapper.js
CHANGED
|
@@ -9,8 +9,8 @@ const index_1 = require("./index");
|
|
|
9
9
|
// Backward-compatible wrapper. The core IInstall component now handles:
|
|
10
10
|
// - shake gesture on real devices
|
|
11
11
|
// - floating manual trigger button on simulator/emulator
|
|
12
|
-
const IInstallWrapper = ({ apiKey, apiEndpoint = 'https://iinstall.app', children, enabled = true, showDebugButton: _showDebugButton = false, showFloatingButtonOnEmulator = true, floatingButtonLabel = 'Report Issue', }) => {
|
|
13
|
-
return (<index_1.IInstall apiKey={apiKey} apiEndpoint={apiEndpoint} enabled={enabled} showFloatingButtonOnEmulator={showFloatingButtonOnEmulator} floatingButtonLabel={floatingButtonLabel}>
|
|
12
|
+
const IInstallWrapper = ({ apiKey, apiEndpoint = 'https://iinstall.app', children, enabled = true, showDebugButton: _showDebugButton = false, showFloatingButtonOnEmulator = true, floatingButtonLabel = 'Report Issue', pushToken, autoRegisterPushToken = true, projectId, onPushTokenRegisterError, }) => {
|
|
13
|
+
return (<index_1.IInstall apiKey={apiKey} apiEndpoint={apiEndpoint} enabled={enabled} showFloatingButtonOnEmulator={showFloatingButtonOnEmulator} floatingButtonLabel={floatingButtonLabel} pushToken={pushToken} autoRegisterPushToken={autoRegisterPushToken} projectId={projectId} onPushTokenRegisterError={onPushTokenRegisterError}>
|
|
14
14
|
{children}
|
|
15
15
|
</index_1.IInstall>);
|
|
16
16
|
};
|
package/lib/index.d.ts
CHANGED
|
@@ -6,7 +6,12 @@ interface IInstallProps {
|
|
|
6
6
|
enabled?: boolean;
|
|
7
7
|
showFloatingButtonOnEmulator?: boolean;
|
|
8
8
|
floatingButtonLabel?: string;
|
|
9
|
+
pushToken?: string;
|
|
10
|
+
autoRegisterPushToken?: boolean;
|
|
11
|
+
projectId?: string;
|
|
12
|
+
onPushTokenRegisterError?: (error: string) => void;
|
|
9
13
|
}
|
|
10
14
|
export declare const IInstall: React.FC<IInstallProps>;
|
|
11
15
|
export default IInstall;
|
|
12
16
|
export { IInstallWrapper } from './IInstallWrapper';
|
|
17
|
+
export { registerPushToken, unregisterPushToken, type RegisterPushTokenParams, type UnregisterPushTokenParams, type PushRegistrationResult, type PushPlatform, } from './pushRegistration';
|
package/lib/index.js
CHANGED
|
@@ -36,7 +36,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
36
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
37
|
};
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.IInstallWrapper = exports.IInstall = void 0;
|
|
39
|
+
exports.unregisterPushToken = exports.registerPushToken = exports.IInstallWrapper = exports.IInstall = void 0;
|
|
40
40
|
const react_1 = __importStar(require("react"));
|
|
41
41
|
const react_native_1 = require("react-native");
|
|
42
42
|
const react_native_view_shot_1 = require("react-native-view-shot");
|
|
@@ -44,13 +44,15 @@ const ShakeDetector_1 = require("./ShakeDetector");
|
|
|
44
44
|
const FeedbackModal_1 = require("./FeedbackModal");
|
|
45
45
|
const react_native_record_screen_1 = __importDefault(require("react-native-record-screen"));
|
|
46
46
|
const react_native_device_info_1 = __importDefault(require("react-native-device-info"));
|
|
47
|
-
const
|
|
47
|
+
const pushRegistration_1 = require("./pushRegistration");
|
|
48
|
+
const IInstall = ({ apiKey, apiEndpoint = 'https://iinstall.app', children, enabled = true, showFloatingButtonOnEmulator = true, floatingButtonLabel = 'Report Issue', pushToken, autoRegisterPushToken = true, projectId, onPushTokenRegisterError, }) => {
|
|
48
49
|
const [modalVisible, setModalVisible] = (0, react_1.useState)(false);
|
|
49
50
|
const [screenshotUri, setScreenshotUri] = (0, react_1.useState)(null);
|
|
50
51
|
const [videoUri, setVideoUri] = (0, react_1.useState)(null);
|
|
51
52
|
const [isRecording, setIsRecording] = (0, react_1.useState)(false);
|
|
52
53
|
const [isEmulator, setIsEmulator] = (0, react_1.useState)(false);
|
|
53
54
|
const shakeDetectorRef = (0, react_1.useRef)(null);
|
|
55
|
+
const lastRegisteredPushTokenRef = (0, react_1.useRef)(null);
|
|
54
56
|
// Refs for stable access in shake callback
|
|
55
57
|
const isRecordingRef = (0, react_1.useRef)(isRecording);
|
|
56
58
|
const modalVisibleRef = (0, react_1.useRef)(modalVisible);
|
|
@@ -108,6 +110,55 @@ const IInstall = ({ apiKey, apiEndpoint = 'https://iinstall.app', children, enab
|
|
|
108
110
|
shakeDetectorRef.current?.stop();
|
|
109
111
|
};
|
|
110
112
|
}, [enabled, isEmulator]);
|
|
113
|
+
(0, react_1.useEffect)(() => {
|
|
114
|
+
if (!enabled || !autoRegisterPushToken || !pushToken)
|
|
115
|
+
return;
|
|
116
|
+
if (lastRegisteredPushTokenRef.current === pushToken)
|
|
117
|
+
return;
|
|
118
|
+
let cancelled = false;
|
|
119
|
+
const syncPushToken = async () => {
|
|
120
|
+
const deviceUdid = await react_native_device_info_1.default.getUniqueId().catch(() => undefined);
|
|
121
|
+
const result = await (0, pushRegistration_1.registerPushToken)({
|
|
122
|
+
token: pushToken,
|
|
123
|
+
apiKey,
|
|
124
|
+
apiEndpoint,
|
|
125
|
+
deviceUdid,
|
|
126
|
+
projectId,
|
|
127
|
+
});
|
|
128
|
+
if (cancelled)
|
|
129
|
+
return;
|
|
130
|
+
if (result.success) {
|
|
131
|
+
lastRegisteredPushTokenRef.current = pushToken;
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
const message = result.error || 'Failed to register push token';
|
|
135
|
+
console.warn('IInstall: push token registration failed', message);
|
|
136
|
+
if (onPushTokenRegisterError) {
|
|
137
|
+
onPushTokenRegisterError(message);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
syncPushToken().catch((error) => {
|
|
142
|
+
if (cancelled)
|
|
143
|
+
return;
|
|
144
|
+
const message = error instanceof Error ? error.message : 'Failed to register push token';
|
|
145
|
+
console.warn('IInstall: push token registration failed', message);
|
|
146
|
+
if (onPushTokenRegisterError) {
|
|
147
|
+
onPushTokenRegisterError(message);
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
return () => {
|
|
151
|
+
cancelled = true;
|
|
152
|
+
};
|
|
153
|
+
}, [
|
|
154
|
+
enabled,
|
|
155
|
+
autoRegisterPushToken,
|
|
156
|
+
pushToken,
|
|
157
|
+
apiKey,
|
|
158
|
+
apiEndpoint,
|
|
159
|
+
projectId,
|
|
160
|
+
onPushTokenRegisterError,
|
|
161
|
+
]);
|
|
111
162
|
const handleFloatingButtonPress = async () => {
|
|
112
163
|
await handleShakeCallback.current();
|
|
113
164
|
};
|
|
@@ -292,3 +343,6 @@ exports.default = exports.IInstall;
|
|
|
292
343
|
// Export the wrapper component for simulator/emulator support
|
|
293
344
|
var IInstallWrapper_1 = require("./IInstallWrapper");
|
|
294
345
|
Object.defineProperty(exports, "IInstallWrapper", { enumerable: true, get: function () { return IInstallWrapper_1.IInstallWrapper; } });
|
|
346
|
+
var pushRegistration_2 = require("./pushRegistration");
|
|
347
|
+
Object.defineProperty(exports, "registerPushToken", { enumerable: true, get: function () { return pushRegistration_2.registerPushToken; } });
|
|
348
|
+
Object.defineProperty(exports, "unregisterPushToken", { enumerable: true, get: function () { return pushRegistration_2.unregisterPushToken; } });
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export type PushPlatform = 'IOS' | 'ANDROID';
|
|
2
|
+
export interface RegisterPushTokenParams {
|
|
3
|
+
token: string;
|
|
4
|
+
apiKey: string;
|
|
5
|
+
apiEndpoint?: string;
|
|
6
|
+
deviceUdid?: string;
|
|
7
|
+
projectId?: string;
|
|
8
|
+
platform?: PushPlatform;
|
|
9
|
+
}
|
|
10
|
+
export interface UnregisterPushTokenParams {
|
|
11
|
+
token: string;
|
|
12
|
+
apiKey: string;
|
|
13
|
+
apiEndpoint?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface PushRegistrationResult {
|
|
16
|
+
success: boolean;
|
|
17
|
+
data?: any;
|
|
18
|
+
error?: string;
|
|
19
|
+
status: number;
|
|
20
|
+
}
|
|
21
|
+
export declare function registerPushToken({ token, apiKey, apiEndpoint, deviceUdid, projectId, platform, }: RegisterPushTokenParams): Promise<PushRegistrationResult>;
|
|
22
|
+
export declare function unregisterPushToken({ token, apiKey, apiEndpoint, }: UnregisterPushTokenParams): Promise<PushRegistrationResult>;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerPushToken = registerPushToken;
|
|
4
|
+
exports.unregisterPushToken = unregisterPushToken;
|
|
5
|
+
const react_native_1 = require("react-native");
|
|
6
|
+
function normalizeApiEndpoint(apiEndpoint) {
|
|
7
|
+
return apiEndpoint.replace(/\/+$/, '');
|
|
8
|
+
}
|
|
9
|
+
function resolvePlatform(platform) {
|
|
10
|
+
if (platform)
|
|
11
|
+
return platform;
|
|
12
|
+
return react_native_1.Platform.OS === 'ios' ? 'IOS' : 'ANDROID';
|
|
13
|
+
}
|
|
14
|
+
async function registerPushToken({ token, apiKey, apiEndpoint = 'https://iinstall.app', deviceUdid, projectId, platform, }) {
|
|
15
|
+
try {
|
|
16
|
+
const response = await fetch(`${normalizeApiEndpoint(apiEndpoint)}/api/notifications/push/register`, {
|
|
17
|
+
method: 'POST',
|
|
18
|
+
headers: { 'Content-Type': 'application/json' },
|
|
19
|
+
body: JSON.stringify({
|
|
20
|
+
token,
|
|
21
|
+
apiKey,
|
|
22
|
+
deviceUdid,
|
|
23
|
+
projectId,
|
|
24
|
+
platform: resolvePlatform(platform),
|
|
25
|
+
}),
|
|
26
|
+
});
|
|
27
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
28
|
+
const data = await response.json().catch(() => ({}));
|
|
29
|
+
return {
|
|
30
|
+
success: response.ok,
|
|
31
|
+
status: response.status,
|
|
32
|
+
data,
|
|
33
|
+
error: response.ok ? undefined : data?.error || 'Failed to register push token',
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
return {
|
|
38
|
+
success: false,
|
|
39
|
+
status: 500,
|
|
40
|
+
error: error instanceof Error ? error.message : 'Unknown register push error',
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
async function unregisterPushToken({ token, apiKey, apiEndpoint = 'https://iinstall.app', }) {
|
|
45
|
+
try {
|
|
46
|
+
const response = await fetch(`${normalizeApiEndpoint(apiEndpoint)}/api/notifications/push/register`, {
|
|
47
|
+
method: 'DELETE',
|
|
48
|
+
headers: { 'Content-Type': 'application/json' },
|
|
49
|
+
body: JSON.stringify({
|
|
50
|
+
token,
|
|
51
|
+
apiKey,
|
|
52
|
+
}),
|
|
53
|
+
});
|
|
54
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
55
|
+
const data = await response.json().catch(() => ({}));
|
|
56
|
+
return {
|
|
57
|
+
success: response.ok,
|
|
58
|
+
status: response.status,
|
|
59
|
+
data,
|
|
60
|
+
error: response.ok ? undefined : data?.error || 'Failed to unregister push token',
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
return {
|
|
65
|
+
success: false,
|
|
66
|
+
status: 500,
|
|
67
|
+
error: error instanceof Error ? error.message : 'Unknown unregister push error',
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
import fs from 'node:fs';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
const cwd = process.cwd();
|
|
6
|
+
const packagePath = path.join(cwd, 'package.json');
|
|
7
|
+
const manifestPath = path.join(cwd, 'RELEASE_MANIFEST.json');
|
|
8
|
+
function readJson(filePath) {
|
|
9
|
+
const raw = fs.readFileSync(filePath, 'utf8');
|
|
10
|
+
return JSON.parse(raw);
|
|
11
|
+
}
|
|
12
|
+
try {
|
|
13
|
+
if (!fs.existsSync(manifestPath)) {
|
|
14
|
+
console.error('RELEASE_MANIFEST.json not found');
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
const pkg = readJson(packagePath);
|
|
18
|
+
const manifest = readJson(manifestPath);
|
|
19
|
+
const packageVersion = String(pkg?.version || '').trim();
|
|
20
|
+
const manifestVersion = String(manifest?.version || '').trim();
|
|
21
|
+
if (!packageVersion) {
|
|
22
|
+
console.error('SDK package version missing in package.json');
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
if (!manifestVersion) {
|
|
26
|
+
console.error('RELEASE_MANIFEST version missing');
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
if (packageVersion !== manifestVersion) {
|
|
30
|
+
console.error(`Release mismatch: package.json=${packageVersion}, RELEASE_MANIFEST.json=${manifestVersion}`);
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
console.log(`Release manifest check OK: react-native-iinstall@${packageVersion}`);
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
console.error('Failed to verify RELEASE_MANIFEST:', error);
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
import fs from 'node:fs';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
const cwd = process.cwd();
|
|
6
|
+
const packagePath = path.join(cwd, 'package.json');
|
|
7
|
+
const manifestPath = path.join(cwd, 'RELEASE_MANIFEST.json');
|
|
8
|
+
function readJson(filePath) {
|
|
9
|
+
const raw = fs.readFileSync(filePath, 'utf8');
|
|
10
|
+
return JSON.parse(raw);
|
|
11
|
+
}
|
|
12
|
+
function writeJson(filePath, value) {
|
|
13
|
+
fs.writeFileSync(filePath, `${JSON.stringify(value, null, 2)}\n`, 'utf8');
|
|
14
|
+
}
|
|
15
|
+
try {
|
|
16
|
+
const pkg = readJson(packagePath);
|
|
17
|
+
const packageVersion = String(pkg?.version || '').trim();
|
|
18
|
+
if (!packageVersion) {
|
|
19
|
+
console.error('SDK package version missing in package.json');
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
let manifest = {
|
|
23
|
+
version: packageVersion,
|
|
24
|
+
highlights: [],
|
|
25
|
+
};
|
|
26
|
+
if (fs.existsSync(manifestPath)) {
|
|
27
|
+
manifest = {
|
|
28
|
+
...readJson(manifestPath),
|
|
29
|
+
version: packageVersion,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
writeJson(manifestPath, manifest);
|
|
33
|
+
console.log(`Synced RELEASE_MANIFEST -> react-native-iinstall@${packageVersion}`);
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
console.error('Failed to sync RELEASE_MANIFEST:', error);
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface FeedbackModalProps {
|
|
3
|
+
visible: boolean;
|
|
4
|
+
onClose: () => void;
|
|
5
|
+
screenshotUri: string | null;
|
|
6
|
+
videoUri?: string | null;
|
|
7
|
+
onStartRecording?: () => void;
|
|
8
|
+
apiKey: string;
|
|
9
|
+
apiEndpoint: string;
|
|
10
|
+
}
|
|
11
|
+
export declare const FeedbackModal: React.FC<FeedbackModalProps>;
|
|
12
|
+
export {};
|