@radhya/mach 2.0.44 → 2.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/docs/push.md ADDED
@@ -0,0 +1,76 @@
1
+ # MACH Push
2
+
3
+ MACH Push sends directly through APNs and FCM from MACH's SQS-triggered
4
+ delivery Lambda. Notification content is transient; MACH stores encrypted
5
+ device/provider credentials and daily aggregate counters, not message history.
6
+
7
+ ## Setup
8
+
9
+ Link the mobile project, then run the complete setup:
10
+
11
+ ```bash
12
+ mach link
13
+ mach push setup
14
+ ```
15
+
16
+ `push setup` detects Expo, bare React Native, or Flutter; reads the native app
17
+ identifiers; creates or reuses the matching MACH Push app; installs the mobile
18
+ SDK; and starts permission, registration, and notification listeners from the
19
+ application entry point.
20
+
21
+ The command writes public SDK values to a generated file. It creates a separate
22
+ application-owned callback file for foreground notifications, notification
23
+ taps, registration, permission changes, and errors. Running setup again
24
+ refreshes generated configuration but never overwrites those callbacks.
25
+
26
+ Expo setup also installs and wires `@radhya/mach/expo-plugin`. The plugin adds
27
+ the APNs entitlement, Android notification permission, Firebase config path,
28
+ and public MACH Push configuration during prebuild. Expo Go cannot load custom
29
+ native modules, so create a new development or production build after setup.
30
+
31
+ Use `mach push init` only when you intentionally want to create the server-side
32
+ push app without installing or wiring a mobile SDK.
33
+
34
+ ## Provider credentials
35
+
36
+ ```bash
37
+ mach push credentials apns \
38
+ --file AuthKey_ABC123DEFG.p8 \
39
+ --team-id ABC123DEFG \
40
+ --key-id ABC123DEFG \
41
+ --environment development
42
+
43
+ mach push credentials fcm \
44
+ --file firebase-service-account.json \
45
+ --environment production
46
+ ```
47
+
48
+ Provider credentials are encrypted and never returned by the API.
49
+
50
+ ## Send
51
+
52
+ ```bash
53
+ mach push send \
54
+ --user user_123 \
55
+ --title "Invoice paid" \
56
+ --body "Invoice INV-1042 was paid."
57
+
58
+ mach push send \
59
+ --all \
60
+ --platform android \
61
+ --title "New release" \
62
+ --body "Version 4.2 is ready." \
63
+ --collapse-key release
64
+ ```
65
+
66
+ Choose exactly one target kind: repeatable `--token`, repeatable `--user`, or
67
+ `--all`.
68
+
69
+ ## Aggregate status
70
+
71
+ ```bash
72
+ mach push status --days 30
73
+ ```
74
+
75
+ `Provider accepted` means APNs/FCM accepted the request; it is not an open or
76
+ device-display receipt.
@@ -112,9 +112,24 @@ const resolveOta = config => {
112
112
  return { ...ota, enabled: Boolean(url), projectId, engine, url, runtimeVersion, runtimeVersionPolicy, channel }
113
113
  }
114
114
 
115
+ const resolvePush = config => {
116
+ const machConfig = readMachConfig(config)
117
+ const push = machConfig.push || {}
118
+ return {
119
+ ...push,
120
+ enabled: push.enabled !== false && Boolean(push.appId && push.publishableKey),
121
+ projectId: machConfig.projectId,
122
+ apiUrl: first(process.env.MACH_PUSH_API_URL, push.apiUrl) || 'https://mach-api.securejs.in',
123
+ environment: nonEmpty(push.environment) || 'production',
124
+ iosEnvironment: nonEmpty(push.iosEnvironment) ||
125
+ (push.environment === 'development' ? 'development' : 'production'),
126
+ }
127
+ }
128
+
115
129
  module.exports = function withMachDeepLinks(config) {
116
130
  const deepLinks = resolveDeepLinks(config)
117
131
  const ota = resolveOta(config)
132
+ const push = resolvePush(config)
118
133
 
119
134
  config.extra = { ...(config.extra || {}) }
120
135
 
@@ -148,6 +163,32 @@ module.exports = function withMachDeepLinks(config) {
148
163
  }
149
164
  }
150
165
 
166
+ if (push.enabled) {
167
+ config.extra.mach = {
168
+ ...(config.extra.mach || {}),
169
+ push: {
170
+ projectId: push.projectId,
171
+ appId: push.appId,
172
+ publishableKey: push.publishableKey,
173
+ apiUrl: push.apiUrl,
174
+ environment: push.environment,
175
+ },
176
+ }
177
+ config.ios = config.ios || {}
178
+ config.ios.entitlements = {
179
+ ...(config.ios.entitlements || {}),
180
+ 'aps-environment': push.iosEnvironment,
181
+ }
182
+ config.android = config.android || {}
183
+ config.android.permissions = unique([
184
+ ...(config.android.permissions || []),
185
+ 'android.permission.POST_NOTIFICATIONS',
186
+ ])
187
+ if (push.googleServicesFile) {
188
+ config.android.googleServicesFile = push.googleServicesFile
189
+ }
190
+ }
191
+
151
192
  if (!deepLinks.baseUrl || !deepLinks.domain) return config
152
193
 
153
194
  config.scheme = deepLinks.scheme
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@radhya/mach",
3
- "version": "2.0.44",
3
+ "version": "2.1.0",
4
4
  "description": "Mach CLI: Cloud Build Orchestrator for React Native & Expo",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -12,11 +12,13 @@
12
12
  "expo-plugin/",
13
13
  "docs/frameworks/",
14
14
  "docs/deep-links.md",
15
- "docs/ota.md"
15
+ "docs/ota.md",
16
+ "docs/push.md"
16
17
  ],
17
18
  "scripts": {
18
19
  "build": "tsup src/index.ts src/commands/isolated-upload.ts --format esm --clean --minify --dts",
19
- "test": "tsx --test src/**/*.test.ts && node --test tests/*.test.cjs",
20
+ "test": "npm run typecheck:ota && tsx --test src/**/*.test.ts && node --test tests/*.test.cjs",
21
+ "typecheck:ota": "tsc --noEmit --skipLibCheck --moduleResolution Bundler --module ESNext --target ES2022 --esModuleInterop --noImplicitAny false src/commands/ota.ts",
20
22
  "start": "node dist/index.js",
21
23
  "dev": "tsx src/index.ts",
22
24
  "release": "semantic-release"