native-update 2.0.0 → 3.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.
Files changed (258) hide show
  1. package/Readme.md +28 -14
  2. package/android/manifest-additions.xml +28 -0
  3. package/android/src/main/AndroidManifest.xml +3 -7
  4. package/android/src/main/java/com/aoneahsan/nativeupdate/BackgroundNotificationManager.kt +21 -13
  5. package/android/src/main/java/com/aoneahsan/nativeupdate/LiveUpdatePlugin.kt +196 -29
  6. package/android/src/main/java/com/aoneahsan/nativeupdate/NativeUpdatePlugin.kt +21 -36
  7. package/cli/AGENTS.md +15 -1
  8. package/cli/CLAUDE.md +15 -1
  9. package/cli/commands/backend-create.js +56 -15
  10. package/cli/commands/bundle-create.js +39 -7
  11. package/cli/commands/monitor.js +72 -51
  12. package/cli/index.js +10 -24
  13. package/cli/package.json +11 -3
  14. package/dist/esm/app-review/app-review-manager.js +0 -1
  15. package/dist/esm/app-review/index.js +0 -1
  16. package/dist/esm/app-review/platform-review-handler.js +0 -1
  17. package/dist/esm/app-review/review-conditions-checker.js +0 -1
  18. package/dist/esm/app-review/review-rate-limiter.js +0 -1
  19. package/dist/esm/app-review/types.js +0 -1
  20. package/dist/esm/app-update/app-update-checker.js +0 -1
  21. package/dist/esm/app-update/app-update-installer.d.ts +1 -0
  22. package/dist/esm/app-update/app-update-installer.js +19 -8
  23. package/dist/esm/app-update/app-update-manager.js +0 -1
  24. package/dist/esm/app-update/app-update-notifier.js +0 -1
  25. package/dist/esm/app-update/index.js +0 -1
  26. package/dist/esm/app-update/platform-app-update.js +12 -3
  27. package/dist/esm/app-update/types.js +0 -1
  28. package/dist/esm/background-update/background-scheduler.js +0 -1
  29. package/dist/esm/background-update/index.js +0 -1
  30. package/dist/esm/background-update/notification-manager.js +0 -1
  31. package/dist/esm/config/support.js +0 -1
  32. package/dist/esm/core/analytics.d.ts +13 -0
  33. package/dist/esm/core/analytics.js +15 -1
  34. package/dist/esm/core/cache-manager.js +0 -1
  35. package/dist/esm/core/config.d.ts +0 -15
  36. package/dist/esm/core/config.js +0 -4
  37. package/dist/esm/core/errors.d.ts +1 -0
  38. package/dist/esm/core/errors.js +1 -1
  39. package/dist/esm/core/event-emitter.d.ts +0 -3
  40. package/dist/esm/core/event-emitter.js +8 -3
  41. package/dist/esm/core/logger.js +0 -1
  42. package/dist/esm/core/performance.js +0 -1
  43. package/dist/esm/core/plugin-manager.js +3 -1
  44. package/dist/esm/core/security.d.ts +11 -0
  45. package/dist/esm/core/security.js +27 -1
  46. package/dist/esm/definitions.d.ts +0 -11
  47. package/dist/esm/definitions.js +0 -1
  48. package/dist/esm/index.d.ts +3 -2
  49. package/dist/esm/index.js +3 -1
  50. package/dist/esm/live-update/bundle-manager.d.ts +8 -0
  51. package/dist/esm/live-update/bundle-manager.js +20 -1
  52. package/dist/esm/live-update/certificate-pinning.js +0 -1
  53. package/dist/esm/live-update/delta-processor.d.ts +1 -1
  54. package/dist/esm/live-update/delta-processor.js +3 -1
  55. package/dist/esm/live-update/download-manager.js +9 -2
  56. package/dist/esm/live-update/rollout-checker.d.ts +1 -1
  57. package/dist/esm/live-update/rollout-checker.js +5 -6
  58. package/dist/esm/live-update/update-manager.js +0 -1
  59. package/dist/esm/live-update/version-manager.d.ts +0 -12
  60. package/dist/esm/live-update/version-manager.js +0 -68
  61. package/dist/esm/plugin.js +69 -43
  62. package/dist/esm/security/crypto.js +11 -7
  63. package/dist/esm/security/validator.js +0 -1
  64. package/dist/esm/types/rollout.d.ts +85 -0
  65. package/dist/esm/types/rollout.js +25 -0
  66. package/dist/esm/web.d.ts +8 -0
  67. package/dist/esm/web.js +148 -54
  68. package/dist/plugin.cjs.js +1 -2
  69. package/dist/plugin.esm.js +1 -2
  70. package/dist/plugin.js +2 -3
  71. package/docs/CHANGELOG.md +124 -0
  72. package/docs/CLAUDE.md +1 -1
  73. package/docs/MANUAL-TASKS.md +17 -0
  74. package/docs/MARKETING_WEBSITE_TRACKER.md +18 -2
  75. package/docs/MIGRATION.md +83 -0
  76. package/docs/PACKAGES.md +167 -0
  77. package/docs/PERFORMANCE.md +110 -0
  78. package/docs/PROJECT_COMPLETION_TRACKER.md +4 -35
  79. package/docs/README.md +0 -1
  80. package/docs/REMAINING_FEATURES.md +123 -76
  81. package/docs/ROADMAP.md +200 -120
  82. package/docs/SECURITY-IF-REPO-PUBLIC.md +232 -0
  83. package/docs/TESTING_REQUIREMENTS.md +1 -112
  84. package/docs/ai-knowledge-base/00-project-profile.md +38 -0
  85. package/docs/ai-knowledge-base/01-features.md +46 -0
  86. package/docs/ai-knowledge-base/02-routes.md +72 -0
  87. package/docs/ai-knowledge-base/03-tech-stack.md +57 -0
  88. package/docs/ai-knowledge-base/README.md +23 -0
  89. package/docs/analytics-tracking.md +37 -0
  90. package/docs/capacitor-official-plugins.md +46 -0
  91. package/docs/capawesome-plugins.md +29 -0
  92. package/docs/deployment/HOSTINGER_DEPLOY.md +75 -34
  93. package/docs/deployment/PRODUCTION-DEPLOY-CHECKLIST.md +184 -0
  94. package/docs/docs-site/plan.md +201 -0
  95. package/docs/docs-site/scope.md +127 -0
  96. package/docs/docs-site/tracker.json +235 -0
  97. package/docs/error-handling-tracking.md +37 -0
  98. package/docs/guides/testing-guide.md +15 -41
  99. package/docs/package-audit.md +41 -0
  100. package/docs/play-store/ASO-METADATA.md +5 -0
  101. package/docs/play-store/DATA-SAFETY.md +5 -0
  102. package/docs/play-store/DECLARATIONS.md +5 -0
  103. package/docs/play-store/README.md +27 -0
  104. package/docs/play-store/RELEASE-NOTES.md +99 -0
  105. package/docs/play-store/RELEASE-STEPS.md +6 -0
  106. package/docs/play-store/STORE-LISTING.md +7 -0
  107. package/docs/play-store/SUBMISSION-CHECKLIST.md +5 -0
  108. package/docs/production-readiness.md +1 -1
  109. package/docs/project-audit/2026-05-16/00-FINALIZATION-PLAN.md +123 -0
  110. package/docs/project-audit/2026-05-16/01-BATCH-PLAN.md +227 -0
  111. package/docs/project-audit/2026-05-16/02-AUDIT-FINDINGS.md +144 -0
  112. package/docs/project-audit/2026-05-16/sessions/batch-01.md +42 -0
  113. package/docs/project-audit/2026-05-16/sessions/batch-02.md +74 -0
  114. package/docs/project-audit/2026-05-16/sessions/batch-03.md +71 -0
  115. package/docs/project-audit/2026-05-16/sessions/batch-04.md +88 -0
  116. package/docs/project-audit/2026-05-16/sessions/batch-05.md +63 -0
  117. package/docs/project-audit/2026-05-16/sessions/batch-06.md +103 -0
  118. package/docs/project-audit/2026-05-16/sessions/batch-07.md +61 -0
  119. package/docs/project-audit/2026-05-16/sessions/batch-08.md +101 -0
  120. package/docs/project-audit/2026-05-16/sessions/batch-09.md +105 -0
  121. package/docs/project-audit/2026-05-16/sessions/batch-10.md +102 -0
  122. package/docs/project-audit/AUDIT-HISTORY.md +74 -0
  123. package/docs/project-audit/BATCH-PLAN.md +168 -0
  124. package/docs/project-audit/MARKETING-WEBSITE-FINDINGS-2026-05-11.md +73 -0
  125. package/docs/project-audit/PRODUCTION-READINESS-AUDIT-2026-05-08.md +275 -0
  126. package/docs/project-finalization/00-tracker.json +60 -0
  127. package/docs/project-knowledge-base/01-system-overview.md +39 -30
  128. package/docs/project-knowledge-base/02-routes-pages-forms-users.md +87 -81
  129. package/docs/project-knowledge-base/03-tech-stack-modules-services.md +140 -108
  130. package/docs/project-knowledge-base/04-data-models-integrations.md +191 -254
  131. package/docs/project-knowledge-base/05-docs-corpus-inventory.md +83 -20
  132. package/docs/project-knowledge-base/06-operations-testing-legal-content.md +67 -29
  133. package/docs/project-knowledge-base/README.md +27 -14
  134. package/docs/project-profiles/native-update-capacitor-update-platform-project-profile-last-updated-2026-05-19.md +81 -0
  135. package/docs/rules-tracker.md +102 -0
  136. package/docs/security/PRE-LAUNCH-PENTEST-CHECKLIST.md +116 -0
  137. package/docs/social-media-marketing/README.md +81 -0
  138. package/docs/social-media-marketing/posts-batch-01.md +613 -0
  139. package/docs/social-media-marketing/posts-batch-02.md +528 -0
  140. package/docs/social-media-marketing/whatsapp-messages-batch-01.md +458 -0
  141. package/docs/social-media-marketing/whatsapp-status-batch-01.md +355 -0
  142. package/docs/tracking/finalization-2026-05-16-tracker.json +346 -0
  143. package/docs/tracking/full-audit-tracker.json +121 -0
  144. package/docs/tracking/production-readiness-audit-tracker.json +429 -0
  145. package/ios/Plugin/BackgroundUpdate/BackgroundUpdatePlugin.swift +16 -3
  146. package/ios/Plugin/LiveUpdate/LiveUpdatePlugin.swift +71 -47
  147. package/ios/Plugin/NativeUpdatePlugin.swift +14 -9
  148. package/package.json +29 -29
  149. package/cli/node_modules/.yarn-integrity +0 -16
  150. package/cli/node_modules/commander/LICENSE +0 -22
  151. package/cli/node_modules/commander/Readme.md +0 -1148
  152. package/cli/node_modules/commander/esm.mjs +0 -16
  153. package/cli/node_modules/commander/index.js +0 -26
  154. package/cli/node_modules/commander/lib/argument.js +0 -145
  155. package/cli/node_modules/commander/lib/command.js +0 -2179
  156. package/cli/node_modules/commander/lib/error.js +0 -43
  157. package/cli/node_modules/commander/lib/help.js +0 -462
  158. package/cli/node_modules/commander/lib/option.js +0 -329
  159. package/cli/node_modules/commander/lib/suggestSimilar.js +0 -100
  160. package/cli/node_modules/commander/package-support.json +0 -16
  161. package/cli/node_modules/commander/package.json +0 -80
  162. package/cli/node_modules/commander/typings/esm.d.mts +0 -3
  163. package/cli/node_modules/commander/typings/index.d.ts +0 -884
  164. package/cli/yarn.lock +0 -8
  165. package/dist/esm/__tests__/bundle-manager.test.d.ts +0 -1
  166. package/dist/esm/__tests__/bundle-manager.test.js +0 -151
  167. package/dist/esm/__tests__/bundle-manager.test.js.map +0 -1
  168. package/dist/esm/__tests__/config.test.d.ts +0 -1
  169. package/dist/esm/__tests__/config.test.js +0 -70
  170. package/dist/esm/__tests__/config.test.js.map +0 -1
  171. package/dist/esm/__tests__/delta-processor.test.d.ts +0 -1
  172. package/dist/esm/__tests__/delta-processor.test.js +0 -77
  173. package/dist/esm/__tests__/delta-processor.test.js.map +0 -1
  174. package/dist/esm/__tests__/firestore-schema.test.d.ts +0 -1
  175. package/dist/esm/__tests__/firestore-schema.test.js +0 -74
  176. package/dist/esm/__tests__/firestore-schema.test.js.map +0 -1
  177. package/dist/esm/__tests__/integration.test.d.ts +0 -1
  178. package/dist/esm/__tests__/integration.test.js +0 -78
  179. package/dist/esm/__tests__/integration.test.js.map +0 -1
  180. package/dist/esm/__tests__/manifest-reader.test.d.ts +0 -1
  181. package/dist/esm/__tests__/manifest-reader.test.js +0 -271
  182. package/dist/esm/__tests__/manifest-reader.test.js.map +0 -1
  183. package/dist/esm/__tests__/rollout-checker.test.d.ts +0 -1
  184. package/dist/esm/__tests__/rollout-checker.test.js +0 -210
  185. package/dist/esm/__tests__/rollout-checker.test.js.map +0 -1
  186. package/dist/esm/__tests__/security-enforcement.test.d.ts +0 -1
  187. package/dist/esm/__tests__/security-enforcement.test.js +0 -95
  188. package/dist/esm/__tests__/security-enforcement.test.js.map +0 -1
  189. package/dist/esm/__tests__/security.test.d.ts +0 -1
  190. package/dist/esm/__tests__/security.test.js +0 -54
  191. package/dist/esm/__tests__/security.test.js.map +0 -1
  192. package/dist/esm/__tests__/version-manager.test.d.ts +0 -1
  193. package/dist/esm/__tests__/version-manager.test.js +0 -45
  194. package/dist/esm/__tests__/version-manager.test.js.map +0 -1
  195. package/dist/esm/app-review/app-review-manager.js.map +0 -1
  196. package/dist/esm/app-review/index.js.map +0 -1
  197. package/dist/esm/app-review/platform-review-handler.js.map +0 -1
  198. package/dist/esm/app-review/review-conditions-checker.js.map +0 -1
  199. package/dist/esm/app-review/review-rate-limiter.js.map +0 -1
  200. package/dist/esm/app-review/types.js.map +0 -1
  201. package/dist/esm/app-update/app-update-checker.js.map +0 -1
  202. package/dist/esm/app-update/app-update-installer.js.map +0 -1
  203. package/dist/esm/app-update/app-update-manager.js.map +0 -1
  204. package/dist/esm/app-update/app-update-notifier.js.map +0 -1
  205. package/dist/esm/app-update/index.js.map +0 -1
  206. package/dist/esm/app-update/platform-app-update.js.map +0 -1
  207. package/dist/esm/app-update/types.js.map +0 -1
  208. package/dist/esm/background-update/background-scheduler.js.map +0 -1
  209. package/dist/esm/background-update/index.js.map +0 -1
  210. package/dist/esm/background-update/notification-manager.js.map +0 -1
  211. package/dist/esm/config/support.js.map +0 -1
  212. package/dist/esm/core/analytics.js.map +0 -1
  213. package/dist/esm/core/cache-manager.js.map +0 -1
  214. package/dist/esm/core/config.js.map +0 -1
  215. package/dist/esm/core/errors.js.map +0 -1
  216. package/dist/esm/core/event-emitter.js.map +0 -1
  217. package/dist/esm/core/logger.js.map +0 -1
  218. package/dist/esm/core/performance.js.map +0 -1
  219. package/dist/esm/core/plugin-manager.js.map +0 -1
  220. package/dist/esm/core/security.js.map +0 -1
  221. package/dist/esm/definitions.js.map +0 -1
  222. package/dist/esm/firestore/firestore-client.d.ts +0 -109
  223. package/dist/esm/firestore/firestore-client.js +0 -264
  224. package/dist/esm/firestore/firestore-client.js.map +0 -1
  225. package/dist/esm/firestore/index.d.ts +0 -11
  226. package/dist/esm/firestore/index.js +0 -11
  227. package/dist/esm/firestore/index.js.map +0 -1
  228. package/dist/esm/firestore/manifest-reader.d.ts +0 -87
  229. package/dist/esm/firestore/manifest-reader.js +0 -294
  230. package/dist/esm/firestore/manifest-reader.js.map +0 -1
  231. package/dist/esm/firestore/schema.d.ts +0 -507
  232. package/dist/esm/firestore/schema.js +0 -73
  233. package/dist/esm/firestore/schema.js.map +0 -1
  234. package/dist/esm/index.js.map +0 -1
  235. package/dist/esm/live-update/bundle-manager.js.map +0 -1
  236. package/dist/esm/live-update/certificate-pinning.js.map +0 -1
  237. package/dist/esm/live-update/delta-processor.js.map +0 -1
  238. package/dist/esm/live-update/download-manager.js.map +0 -1
  239. package/dist/esm/live-update/rollout-checker.js.map +0 -1
  240. package/dist/esm/live-update/update-manager.js.map +0 -1
  241. package/dist/esm/live-update/version-manager.js.map +0 -1
  242. package/dist/esm/plugin.js.map +0 -1
  243. package/dist/esm/security/crypto.js.map +0 -1
  244. package/dist/esm/security/validator.js.map +0 -1
  245. package/dist/esm/web.js.map +0 -1
  246. package/dist/plugin.cjs.js.map +0 -1
  247. package/dist/plugin.esm.js.map +0 -1
  248. package/dist/plugin.js.map +0 -1
  249. package/docs/FIREBASE_INTEGRATION_TRACKER.md +0 -321
  250. package/docs/FIREBASE_QUERIES_AND_INDEXES_AUDIT.md +0 -221
  251. package/docs/examples/firebase-backend-example.md +0 -27
  252. package/docs/features/laravel-nova-backend/credentials.ignore.md +0 -34
  253. package/docs/guides/no-cost-backend-implementation-plan.md +0 -77
  254. package/docs/guides/no-cost-firestore-google-drive-backend.md +0 -60
  255. package/docs/project-profiles/native-update-capacitor-update-platform-project-profile-last-updated-2026-03-16.md +0 -454
  256. package/docs/project-profiles/native-update-capacitor-update-platform-project-profile-last-updated-2026-03-24.md +0 -66
  257. package/docs/project-profiles/native-update-capacitor-update-platform-project-profile-last-updated-2026-03-25.md +0 -67
  258. /package/docs/{MARKETING_WEBSITE_PLAN.md → archive/MARKETING_WEBSITE_PLAN.md} +0 -0
package/cli/CLAUDE.md CHANGED
@@ -5,6 +5,15 @@ Command-line interface for native-update release management and bundle operation
5
5
  ## 🔴 3-Day Freshness Rule
6
6
  Check and update this file at least every 3 days. See root CLAUDE.md.
7
7
 
8
+ ## Package Manager Hierarchy: nvm → npm (global) → yarn (local) (IRON-SOLID)
9
+
10
+ Three tiers, each tool ONLY for its tier — for the best, most reproducible dev results:
11
+ - **`nvm`** → install/update Node.js (which bundles `npm`): `nvm install --lts`. Use nvm to get/update `npm` itself.
12
+ - **`npm`** → ALL global packages: `npm install -g yarn` (install yarn globally if missing) + `npm install -g <pkg>` (every other global CLI).
13
+ - **`yarn`** → ALL local project work: `yarn`, `yarn add <pkg>`, `yarn add -D <pkg>` inside the project.
14
+
15
+ ❌ NEVER use `npm`/`pnpm` for LOCAL installs. NEVER use `pnpm` at all. ✅ Only `yarn.lock` in the project — delete `package-lock.json` and `pnpm-lock.yaml`.
16
+
8
17
  ## Structure
9
18
 
10
19
  | File/Folder | Purpose |
@@ -48,4 +57,9 @@ All file storage uses FilesHub API. See root CLAUDE.md.
48
57
 
49
58
  ---
50
59
 
51
- **Last Updated**: 2026-04-02
60
+ ## Gitignore Hygiene (IRON-SOLID)
61
+ `.gitignore` stays current with the project structure — ignore only recoverable artifacts (build/`dist`/`www`/`node_modules`/logs/caches/IDE), never lose source. Custom rules always present: `*.ignore.*`, `project-record-ignore/`. This is a **PRIVATE** repo -> `.env`/secrets/keystores ARE tracked in git. Capacitor: track `android`/`ios` source, ignore native build.
62
+ Full rule + private/public protocol: `~/.claude/rules/project-config.md`.
63
+ Gitignore Last Verified: 2026-06-24
64
+
65
+ **Last Updated**: 2026-04-25
@@ -8,6 +8,46 @@ import ora from 'ora';
8
8
  const __filename = fileURLToPath(import.meta.url);
9
9
  const __dirname = dirname(__filename);
10
10
 
11
+ /**
12
+ * Banner injected at the top of every generated server-side file. The
13
+ * generator emits SCAFFOLDS, not turn-key production code: bundle
14
+ * lookup, persistent storage, signature verification, and rollout
15
+ * gating are all left as `TODO[SCAFFOLD-IMPLEMENT-BEFORE-DEPLOY]`
16
+ * markers because the right answer depends on the host's storage +
17
+ * DB choices. Fully working references:
18
+ * - example-apps/node-express (minimal HTTP contract)
19
+ * - backend/ (Laravel + Nova production app)
20
+ */
21
+ const SCAFFOLD_BANNER = `/**
22
+ * ⚠️ SCAFFOLD — IMPLEMENT BEFORE DEPLOYING ⚠️
23
+ *
24
+ * This file was generated by \`native-update backend-create\` as a
25
+ * STARTING POINT, not a deploy-ready service. Every block tagged
26
+ * \`TODO[SCAFFOLD-IMPLEMENT-BEFORE-DEPLOY]\` MUST be replaced with
27
+ * real persistence + storage + signature verification before this
28
+ * runs in production.
29
+ *
30
+ * Working references:
31
+ * • example-apps/node-express — minimal HTTP-contract reference
32
+ * • backend/ (Laravel + Nova) — full SaaS implementation
33
+ *
34
+ * Deploying this file as-is will respond with hard-coded sample
35
+ * payloads and silently drop uploaded bundles.
36
+ */
37
+ `;
38
+
39
+ const POST_GENERATION_WARNING = [
40
+ '',
41
+ chalk.yellow.bold('⚠️ SCAFFOLD — NOT PRODUCTION READY ⚠️'),
42
+ chalk.gray('This template ships with placeholder bundle lookup + storage logic.'),
43
+ chalk.gray('Search the generated code for `TODO[SCAFFOLD-IMPLEMENT-BEFORE-DEPLOY]`'),
44
+ chalk.gray('and replace each block with your real DB / storage / signing logic.'),
45
+ chalk.gray('See:'),
46
+ chalk.gray(' • example-apps/node-express (minimal HTTP-contract reference)'),
47
+ chalk.gray(' • backend/ (Laravel + Nova) (full SaaS implementation)'),
48
+ '',
49
+ ].join('\n');
50
+
11
51
  export async function createBackend(type, options) {
12
52
  const spinner = ora(`Creating ${type} backend template...`).start();
13
53
 
@@ -40,14 +80,15 @@ export async function createBackend(type, options) {
40
80
  throw new Error(`Unknown backend type: ${type}`);
41
81
  }
42
82
 
43
- spinner.succeed(`${type} backend created successfully!`);
44
-
45
- console.log('');
83
+ spinner.succeed(`${type} backend scaffold created!`);
84
+
85
+ console.log(POST_GENERATION_WARNING);
46
86
  console.log(chalk.bold('Next steps:'));
47
87
  console.log(chalk.gray(` 1. cd ${options.output}`));
48
88
  console.log(chalk.gray(` 2. npm install`));
49
89
  console.log(chalk.gray(` 3. Configure your environment variables`));
50
- console.log(chalk.gray(` 4. npm run dev`));
90
+ console.log(chalk.gray(` 4. Replace every TODO[SCAFFOLD-IMPLEMENT-BEFORE-DEPLOY] block`));
91
+ console.log(chalk.gray(` 5. npm run dev`));
51
92
 
52
93
  } catch (error) {
53
94
  spinner.fail(`Failed to create backend: ${error.message}`);
@@ -90,7 +131,7 @@ async function createExpressBackend(outputDir, options) {
90
131
  );
91
132
 
92
133
  // Create server.js
93
- const serverCode = `import express from 'express';
134
+ const serverCode = `${SCAFFOLD_BANNER}import express from 'express';
94
135
  import cors from 'cors';
95
136
  import dotenv from 'dotenv';
96
137
  import { router as bundleRouter } from './routes/bundles.js';
@@ -141,7 +182,7 @@ router.get('/latest', async (req, res) => {
141
182
  try {
142
183
  const { appId, version, channel = 'production' } = req.query;
143
184
 
144
- // TODO: Implement bundle lookup logic
185
+ // TODO[SCAFFOLD-IMPLEMENT-BEFORE-DEPLOY]: replace with real bundle lookup (DB query against your apps + builds tables)
145
186
  // This is a simplified example
146
187
  const bundle = {
147
188
  version: '1.0.1',
@@ -173,8 +214,8 @@ router.post('/upload', upload.single('bundle'), async (req, res) => {
173
214
  const fileBuffer = await fs.readFile(file.path);
174
215
  const checksum = crypto.createHash('sha256').update(fileBuffer).digest('hex');
175
216
 
176
- // TODO: Store bundle metadata in database
177
- // TODO: Move file to permanent storage
217
+ // TODO[SCAFFOLD-IMPLEMENT-BEFORE-DEPLOY]: persist build metadata (channel, version, checksum, signature, fileshub_public_id) — see backend/ Laravel migrations for the canonical shape
218
+ // TODO[SCAFFOLD-IMPLEMENT-BEFORE-DEPLOY]: upload to FilesHub (preferred) or your CDN; multer drops to /uploads/ which is ephemeral
178
219
 
179
220
  res.json({
180
221
  success: true,
@@ -268,7 +309,7 @@ async function createVercelBackend(outputDir, options) {
268
309
  );
269
310
 
270
311
  // Create bundles API endpoint
271
- const bundlesApi = `export default async function handler(req, res) {
312
+ const bundlesApi = `${SCAFFOLD_BANNER}export default async function handler(req, res) {
272
313
  // Enable CORS
273
314
  res.setHeader('Access-Control-Allow-Credentials', true);
274
315
  res.setHeader('Access-Control-Allow-Origin', '*');
@@ -287,7 +328,7 @@ async function createVercelBackend(outputDir, options) {
287
328
  // Get latest bundle
288
329
  const { appId, version, channel = 'production' } = req.query;
289
330
 
290
- // TODO: Implement bundle lookup from your storage solution
331
+ // TODO[SCAFFOLD-IMPLEMENT-BEFORE-DEPLOY]: replace with real bundle lookup against your KV / DB store
291
332
  // This is a simplified example
292
333
  const bundle = {
293
334
  version: '1.0.1',
@@ -306,8 +347,8 @@ async function createVercelBackend(outputDir, options) {
306
347
  // Handle bundle upload
307
348
  const { version, channel, metadata } = req.body;
308
349
 
309
- // TODO: Handle file upload to storage (Vercel Blob, S3, etc.)
310
- // TODO: Save metadata to database (Vercel KV, external DB, etc.)
350
+ // TODO[SCAFFOLD-IMPLEMENT-BEFORE-DEPLOY]: upload to Vercel Blob / S3 / FilesHub; verify signature against your signing key registry
351
+ // TODO[SCAFFOLD-IMPLEMENT-BEFORE-DEPLOY]: persist build metadata to Vercel KV / Postgres / your DB of choice
311
352
 
312
353
  return res.status(200).json({
313
354
  success: true,
@@ -448,7 +489,7 @@ async function createFirebaseBackend(outputDir, options) {
448
489
  );
449
490
 
450
491
  // Create index.js
451
- const indexJs = `import { onRequest } from 'firebase-functions/v2/https';
492
+ const indexJs = `${SCAFFOLD_BANNER}import { onRequest } from 'firebase-functions/v2/https';
452
493
  import * as admin from 'firebase-admin';
453
494
  import express from 'express';
454
495
  import cors from 'cors';
@@ -490,8 +531,8 @@ app.post('/api/bundles/upload', async (req, res) => {
490
531
  try {
491
532
  const { version, channel, metadata } = req.body;
492
533
 
493
- // TODO: Handle file upload to Cloud Storage
494
- // TODO: Save metadata to Firestore
534
+ // TODO[SCAFFOLD-IMPLEMENT-BEFORE-DEPLOY]: upload to Cloud Storage; verify signature; enforce monotonic version per channel
535
+ // TODO[SCAFFOLD-IMPLEMENT-BEFORE-DEPLOY]: write to Firestore; remember Firestore rules must be locked down (no public writes)
495
536
 
496
537
  res.json({ success: true, version });
497
538
  } catch (error) {
@@ -3,13 +3,15 @@ import fs from 'fs/promises';
3
3
  import path from 'path';
4
4
  import crypto from 'crypto';
5
5
  import archiver from 'archiver';
6
- import { createWriteStream } from 'fs';
6
+ import { createWriteStream, createReadStream } from 'fs';
7
7
  import { fileURLToPath } from 'url';
8
8
  import { dirname, join } from 'path';
9
9
 
10
10
  const __filename = fileURLToPath(import.meta.url);
11
11
  const __dirname = dirname(__filename);
12
12
 
13
+ const NEVER_BUNDLE = ['node_modules', '.git', '.env', '.env.local', '.env.production'];
14
+
13
15
  export async function createBundle(webDir, options) {
14
16
  console.log(chalk.blue('🔨 Creating update bundle...'));
15
17
 
@@ -28,6 +30,18 @@ export async function createBundle(webDir, options) {
28
30
  throw new Error(`No index.html found in ${webDir}. Is this a valid web build directory?`);
29
31
  }
30
32
 
33
+ // Refuse to bundle a project root by mistake — `node_modules`, `.git`,
34
+ // and `.env*` should never end up in an OTA bundle. Catches the common
35
+ // mistake of pointing at the project root instead of `dist/` or `www/`.
36
+ const entries = await fs.readdir(webDir);
37
+ const dangerous = entries.filter((e) => NEVER_BUNDLE.includes(e));
38
+ if (dangerous.length > 0) {
39
+ throw new Error(
40
+ `Refusing to bundle: ${webDir} contains ${dangerous.join(', ')}. ` +
41
+ `Point at your built web output (e.g. ./dist or ./www), not the project root.`
42
+ );
43
+ }
44
+
31
45
  // Create output directory
32
46
  const outputDir = path.resolve(options.output);
33
47
  await fs.mkdir(outputDir, { recursive: true });
@@ -44,13 +58,24 @@ export async function createBundle(webDir, options) {
44
58
  }
45
59
  }
46
60
 
61
+ // Parse --metadata separately so we can give a clearer error than
62
+ // a bare "Unexpected token" if the user passes invalid JSON.
63
+ let extraMetadata = {};
64
+ if (options.metadata) {
65
+ try {
66
+ extraMetadata = JSON.parse(options.metadata);
67
+ } catch (e) {
68
+ throw new Error(`Invalid JSON in --metadata: ${e.message}`);
69
+ }
70
+ }
71
+
47
72
  // Create bundle metadata
48
73
  const metadata = {
49
74
  version,
50
75
  channel: options.channel,
51
76
  created: new Date().toISOString(),
52
77
  platform: 'web',
53
- ...(options.metadata ? JSON.parse(options.metadata) : {})
78
+ ...extraMetadata,
54
79
  };
55
80
 
56
81
  const bundleId = `${version}-${Date.now()}`;
@@ -81,13 +106,20 @@ export async function createBundle(webDir, options) {
81
106
  await archive.finalize();
82
107
  await archivePromise;
83
108
 
84
- // Calculate checksum
85
- const fileBuffer = await fs.readFile(bundlePath);
86
- const checksum = crypto.createHash('sha256').update(fileBuffer).digest('hex');
109
+ // Stream the bundle through the SHA-256 hasher so a 100MB+ bundle
110
+ // doesn't get slurped into RAM all at once. Size comes from fs.stat.
111
+ const bundleStat = await fs.stat(bundlePath);
112
+ const checksum = await new Promise((resolve, reject) => {
113
+ const hash = crypto.createHash('sha256');
114
+ createReadStream(bundlePath)
115
+ .on('data', (chunk) => hash.update(chunk))
116
+ .on('end', () => resolve(hash.digest('hex')))
117
+ .on('error', reject);
118
+ });
87
119
 
88
120
  // Update metadata with file info
89
121
  metadata.checksum = checksum;
90
- metadata.size = fileBuffer.length;
122
+ metadata.size = bundleStat.size;
91
123
  metadata.filename = bundleFileName;
92
124
 
93
125
  // Save metadata
@@ -97,7 +129,7 @@ export async function createBundle(webDir, options) {
97
129
  console.log('');
98
130
  console.log(chalk.bold('Bundle Details:'));
99
131
  console.log(chalk.gray(` File: ${bundlePath}`));
100
- console.log(chalk.gray(` Size: ${(fileBuffer.length / 1024 / 1024).toFixed(2)} MB`));
132
+ console.log(chalk.gray(` Size: ${(bundleStat.size / 1024 / 1024).toFixed(2)} MB`));
101
133
  console.log(chalk.gray(` Checksum: ${checksum}`));
102
134
  console.log(chalk.gray(` Metadata: ${metadataPath}`));
103
135
  console.log('');
@@ -1,6 +1,9 @@
1
1
  import chalk from 'chalk';
2
2
  import ora from 'ora';
3
3
 
4
+ const POLL_MS = 5000;
5
+ const MAX_CONSECUTIVE_FAILURES = 5;
6
+
4
7
  export async function monitor(options) {
5
8
  if (!options.server) {
6
9
  console.error(chalk.red('Error: --server URL is required'));
@@ -12,57 +15,75 @@ export async function monitor(options) {
12
15
  console.log('');
13
16
 
14
17
  const spinner = ora('Fetching update statistics...').start();
18
+ let intervalId = null;
19
+ let consecutiveFailures = 0;
20
+ let stopping = false;
21
+
22
+ const stop = (code = 0) => {
23
+ if (stopping) return;
24
+ stopping = true;
25
+ if (intervalId) clearInterval(intervalId);
26
+ if (spinner.isSpinning) spinner.stop();
27
+ process.exit(code);
28
+ };
29
+
30
+ process.on('SIGINT', () => stop(0));
31
+ process.on('SIGTERM', () => stop(0));
32
+
33
+ const headers = options.key ? { Authorization: `Bearer ${options.key}` } : {};
34
+
35
+ const tick = async () => {
36
+ try {
37
+ const response = await fetch(`${options.server}/api/stats`, { headers });
38
+ if (!response.ok) throw new Error(`Server returned ${response.status}`);
39
+
40
+ const stats = await response.json();
41
+ consecutiveFailures = 0;
42
+
43
+ spinner.stop();
44
+ console.clear();
45
+ console.log(chalk.blue(`📊 Update Monitor - ${new Date().toLocaleTimeString()}`));
46
+ console.log(chalk.gray('─'.repeat(50)));
47
+ console.log('');
15
48
 
16
- try {
17
- // Poll server for stats
18
- setInterval(async () => {
19
- try {
20
- const headers = options.key ? { 'Authorization': `Bearer ${options.key}` } : {};
21
-
22
- const response = await fetch(`${options.server}/api/stats`, { headers });
23
-
24
- if (!response.ok) {
25
- throw new Error(`Server returned ${response.status}`);
26
- }
27
-
28
- const stats = await response.json();
29
-
30
- spinner.stop();
31
- console.clear();
32
- console.log(chalk.blue(`📊 Update Monitor - ${new Date().toLocaleTimeString()}`));
33
- console.log(chalk.gray('─'.repeat(50)));
34
- console.log('');
35
-
36
- console.log(chalk.bold('Current Version:'));
37
- console.log(chalk.gray(` Latest: ${stats.latestVersion || 'N/A'}`));
38
- console.log(chalk.gray(` Channel: ${stats.channel || 'production'}`));
39
- console.log('');
40
-
41
- console.log(chalk.bold('Download Statistics:'));
42
- console.log(chalk.gray(` Total Downloads: ${stats.totalDownloads || 0}`));
43
- console.log(chalk.gray(` Downloads Today: ${stats.downloadsToday || 0}`));
44
- console.log(chalk.gray(` Active Installs: ${stats.activeInstalls || 0}`));
45
- console.log('');
46
-
47
- if (stats.recentActivity) {
48
- console.log(chalk.bold('Recent Activity:'));
49
- stats.recentActivity.forEach(activity => {
50
- console.log(chalk.gray(` ${activity.time} - ${activity.action} (${activity.version})`));
51
- });
52
- }
53
-
54
- console.log('');
55
- console.log(chalk.gray('Press Ctrl+C to stop'));
56
-
57
- spinner.start('Updating...');
58
- } catch (error) {
59
- spinner.fail(`Failed to fetch stats: ${error.message}`);
60
- spinner.start('Retrying...');
49
+ console.log(chalk.bold('Current Version:'));
50
+ console.log(chalk.gray(` Latest: ${stats.latestVersion || 'N/A'}`));
51
+ console.log(chalk.gray(` Channel: ${stats.channel || 'production'}`));
52
+ console.log('');
53
+
54
+ console.log(chalk.bold('Download Statistics:'));
55
+ console.log(chalk.gray(` Total Downloads: ${stats.totalDownloads || 0}`));
56
+ console.log(chalk.gray(` Downloads Today: ${stats.downloadsToday || 0}`));
57
+ console.log(chalk.gray(` Active Installs: ${stats.activeInstalls || 0}`));
58
+ console.log('');
59
+
60
+ if (stats.recentActivity) {
61
+ console.log(chalk.bold('Recent Activity:'));
62
+ stats.recentActivity.forEach((activity) => {
63
+ console.log(chalk.gray(` ${activity.time} - ${activity.action} (${activity.version})`));
64
+ });
61
65
  }
62
- }, 5000); // Update every 5 seconds
63
66
 
64
- } catch (error) {
65
- spinner.fail(`Monitor failed: ${error.message}`);
66
- process.exit(1);
67
- }
68
- }
67
+ console.log('');
68
+ console.log(chalk.gray('Press Ctrl+C to stop'));
69
+
70
+ spinner.start('Updating...');
71
+ } catch (error) {
72
+ consecutiveFailures += 1;
73
+ spinner.fail(
74
+ `Failed to fetch stats (${consecutiveFailures}/${MAX_CONSECUTIVE_FAILURES}): ${error.message}`,
75
+ );
76
+ if (consecutiveFailures >= MAX_CONSECUTIVE_FAILURES) {
77
+ console.error(
78
+ chalk.red(`\nGiving up after ${MAX_CONSECUTIVE_FAILURES} consecutive failures.`),
79
+ );
80
+ stop(1);
81
+ return;
82
+ }
83
+ spinner.start('Retrying...');
84
+ }
85
+ };
86
+
87
+ await tick();
88
+ intervalId = setInterval(tick, POLL_MS);
89
+ }
package/cli/index.js CHANGED
@@ -188,29 +188,6 @@ ${chalk.bold('Examples:')}
188
188
  await createBackend(type, options);
189
189
  });
190
190
 
191
- // Config Commands
192
- const configCmd = program
193
- .command('config')
194
- .description('Configuration commands');
195
-
196
- configCmd
197
- .command('check')
198
- .description('Validate your native-update configuration')
199
- .action(async () => {
200
- const { checkConfig } = await import('./commands/config-check.js');
201
- await checkConfig();
202
- });
203
-
204
- // Migration Commands
205
- program
206
- .command('migrate')
207
- .description('Migrate from other OTA solutions')
208
- .option('--from <solution>', 'Source solution (codepush, appflow)', 'codepush')
209
- .action(async (options) => {
210
- const { migrate } = await import('./commands/migrate.js');
211
- await migrate(options);
212
- });
213
-
214
191
  // Monitoring Commands
215
192
  program
216
193
  .command('monitor')
@@ -264,6 +241,15 @@ program.exitOverride();
264
241
  try {
265
242
  await program.parseAsync(process.argv);
266
243
  } catch (error) {
244
+ // With exitOverride(), Commander throws for normal help/version output too
245
+ // (exitCode 0). Those are successful displays, not errors — exit quietly.
246
+ if (
247
+ error.code === 'commander.helpDisplayed' ||
248
+ error.code === 'commander.help' ||
249
+ error.code === 'commander.version'
250
+ ) {
251
+ process.exit(0);
252
+ }
267
253
  if (error.code === 'commander.missingArgument') {
268
254
  console.error(chalk.red(`Error: ${error.message}`));
269
255
  } else if (error.code === 'commander.unknownCommand') {
@@ -272,5 +258,5 @@ try {
272
258
  } else {
273
259
  console.error(chalk.red(`Error: ${error.message}`));
274
260
  }
275
- process.exit(1);
261
+ process.exit(error.exitCode ?? 1);
276
262
  }
package/cli/package.json CHANGED
@@ -1,12 +1,20 @@
1
1
  {
2
2
  "name": "native-update-cli",
3
- "version": "1.0.0",
3
+ "version": "3.1.0",
4
4
  "description": "CLI for Native Update",
5
5
  "type": "module",
6
+ "engines": {
7
+ "node": ">=24.16.0"
8
+ },
6
9
  "bin": {
7
10
  "native-update": "./index.js"
8
11
  },
9
12
  "dependencies": {
10
- "commander": "^11.0.0"
13
+ "archiver": "^8.0.0",
14
+ "chalk": "^5.6.2",
15
+ "commander": "^15.0.0",
16
+ "express": "^5.2.1",
17
+ "ora": "^9.4.0",
18
+ "prompts": "^2.4.2"
11
19
  }
12
- }
20
+ }
@@ -192,4 +192,3 @@ export class AppReviewManager {
192
192
  }
193
193
  }
194
194
  }
195
- //# sourceMappingURL=app-review-manager.js.map
@@ -3,4 +3,3 @@ export { ReviewConditionsChecker } from './review-conditions-checker';
3
3
  export { ReviewRateLimiter } from './review-rate-limiter';
4
4
  export { PlatformReviewHandler } from './platform-review-handler';
5
5
  export * from './types';
6
- //# sourceMappingURL=index.js.map
@@ -135,4 +135,3 @@ export class PlatformReviewHandler {
135
135
  return true;
136
136
  }
137
137
  }
138
- //# sourceMappingURL=platform-review-handler.js.map
@@ -152,4 +152,3 @@ export class ReviewConditionsChecker {
152
152
  }
153
153
  }
154
154
  }
155
- //# sourceMappingURL=review-conditions-checker.js.map
@@ -161,4 +161,3 @@ export class ReviewRateLimiter {
161
161
  return now;
162
162
  }
163
163
  }
164
- //# sourceMappingURL=review-rate-limiter.js.map
@@ -1,2 +1 @@
1
1
  export {};
2
- //# sourceMappingURL=types.js.map
@@ -206,4 +206,3 @@ export class AppUpdateChecker {
206
206
  return 'web';
207
207
  }
208
208
  }
209
- //# sourceMappingURL=app-update-checker.js.map
@@ -4,6 +4,7 @@ export declare class AppUpdateInstaller {
4
4
  private logger;
5
5
  private progressCallback?;
6
6
  private currentState;
7
+ private flexibleUpdateInterval;
7
8
  constructor(_: PluginConfig);
8
9
  startImmediateUpdate(): Promise<void>;
9
10
  startFlexibleUpdate(): Promise<void>;
@@ -2,7 +2,7 @@ import { Logger } from '../core/logger';
2
2
  import { AppUpdateInstallStatus, } from './types';
3
3
  export class AppUpdateInstaller {
4
4
  constructor(_) {
5
- // config parameter is kept for compatibility but not used
5
+ this.flexibleUpdateInterval = null;
6
6
  this.logger = new Logger('AppUpdateInstaller');
7
7
  this.currentState = {
8
8
  installStatus: AppUpdateInstallStatus.UNKNOWN,
@@ -67,6 +67,13 @@ export class AppUpdateInstaller {
67
67
  }
68
68
  async cancelUpdate() {
69
69
  this.logger.log('Cancelling update');
70
+ // Stop the simulated download interval. Without this, the interval
71
+ // runs forever even after cancel because the only previous exit was
72
+ // a "download finished" branch.
73
+ if (this.flexibleUpdateInterval) {
74
+ clearInterval(this.flexibleUpdateInterval);
75
+ this.flexibleUpdateInterval = null;
76
+ }
70
77
  if (this.currentState.installStatus === AppUpdateInstallStatus.DOWNLOADING) {
71
78
  this.updateState(AppUpdateInstallStatus.CANCELED);
72
79
  }
@@ -85,22 +92,27 @@ export class AppUpdateInstaller {
85
92
  this.logger.log('Update state changed', this.currentState);
86
93
  }
87
94
  simulateFlexibleUpdate() {
88
- // Simulate download progress for web platform
89
95
  let downloaded = 0;
90
- const totalSize = 50 * 1024 * 1024; // 50MB
91
- const chunkSize = 1024 * 1024; // 1MB per tick
92
- const interval = setInterval(() => {
96
+ const totalSize = 50 * 1024 * 1024;
97
+ const chunkSize = 1024 * 1024;
98
+ if (this.flexibleUpdateInterval) {
99
+ clearInterval(this.flexibleUpdateInterval);
100
+ }
101
+ this.flexibleUpdateInterval = setInterval(() => {
93
102
  downloaded += chunkSize;
94
103
  if (downloaded >= totalSize) {
95
104
  downloaded = totalSize;
96
- clearInterval(interval);
105
+ if (this.flexibleUpdateInterval) {
106
+ clearInterval(this.flexibleUpdateInterval);
107
+ this.flexibleUpdateInterval = null;
108
+ }
97
109
  this.updateState(AppUpdateInstallStatus.DOWNLOADED);
98
110
  }
99
111
  const progress = {
100
112
  bytesDownloaded: downloaded,
101
113
  totalBytesToDownload: totalSize,
102
114
  percentComplete: Math.round((downloaded / totalSize) * 100),
103
- downloadSpeed: chunkSize, // 1MB/s
115
+ downloadSpeed: chunkSize,
104
116
  estimatedTime: Math.ceil((totalSize - downloaded) / chunkSize),
105
117
  };
106
118
  if (this.progressCallback) {
@@ -120,4 +132,3 @@ export class AppUpdateInstaller {
120
132
  return !this.isAndroid() && !this.isIOS();
121
133
  }
122
134
  }
123
- //# sourceMappingURL=app-update-installer.js.map
@@ -196,4 +196,3 @@ export class AppUpdateManager {
196
196
  return Object.assign(Object.assign(Object.assign({}, nativeInfo), serverInfo), { updateAvailable: nativeInfo.updateAvailable || !!serverInfo.availableVersion, availableVersion: serverInfo.availableVersion || nativeInfo.availableVersion });
197
197
  }
198
198
  }
199
- //# sourceMappingURL=app-update-manager.js.map
@@ -97,4 +97,3 @@ export class AppUpdateNotifier {
97
97
  }
98
98
  }
99
99
  }
100
- //# sourceMappingURL=app-update-notifier.js.map
@@ -4,4 +4,3 @@ export { AppUpdateInstaller } from './app-update-installer';
4
4
  export { AppUpdateNotifier } from './app-update-notifier';
5
5
  export { PlatformAppUpdate } from './platform-app-update';
6
6
  export * from './types';
7
- //# sourceMappingURL=index.js.map
@@ -1,5 +1,6 @@
1
1
  import { Logger } from '../core/logger';
2
2
  import { Capacitor } from '@capacitor/core';
3
+ import { SecurityValidator } from '../core/security';
3
4
  export class PlatformAppUpdate {
4
5
  constructor(config) {
5
6
  this.config = config;
@@ -31,13 +32,19 @@ export class PlatformAppUpdate {
31
32
  // Web platform - check configured update URL
32
33
  if (this.config.webUpdateUrl) {
33
34
  try {
35
+ SecurityValidator.validateDownloadUrl(this.config.webUpdateUrl);
34
36
  const response = await fetch(this.config.webUpdateUrl);
35
37
  const data = await response.json();
36
38
  if (data.version && data.version !== versionInfo.currentVersion) {
37
39
  updateInfo.updateAvailable = true;
38
40
  updateInfo.availableVersion = data.version;
39
41
  updateInfo.releaseNotes = data.releaseNotes;
40
- updateInfo.updateURL = data.downloadUrl;
42
+ // Validate downloadUrl scheme — server-controlled value, must
43
+ // not be allowed to smuggle javascript: into a later openUrl.
44
+ if (data.downloadUrl) {
45
+ SecurityValidator.validateStoreUrl(data.downloadUrl);
46
+ updateInfo.updateURL = data.downloadUrl;
47
+ }
41
48
  }
42
49
  }
43
50
  catch (error) {
@@ -85,8 +92,11 @@ export class PlatformAppUpdate {
85
92
  return { url, platform: platform };
86
93
  }
87
94
  async openUrl(url) {
95
+ // Reject any non-HTTPS / non-store URL — protects against
96
+ // `javascript:` payloads handed back from a compromised server.
97
+ SecurityValidator.validateStoreUrl(url);
88
98
  if (typeof window !== 'undefined' && window.open) {
89
- window.open(url, '_blank');
99
+ window.open(url, '_blank', 'noopener,noreferrer');
90
100
  }
91
101
  else {
92
102
  throw new Error('Cannot open URL on this platform');
@@ -126,4 +136,3 @@ export class PlatformAppUpdate {
126
136
  return capabilities;
127
137
  }
128
138
  }
129
- //# sourceMappingURL=platform-app-update.js.map
@@ -9,4 +9,3 @@ export var AppUpdateInstallStatus;
9
9
  AppUpdateInstallStatus[AppUpdateInstallStatus["CANCELED"] = 6] = "CANCELED";
10
10
  AppUpdateInstallStatus[AppUpdateInstallStatus["DOWNLOADED"] = 11] = "DOWNLOADED";
11
11
  })(AppUpdateInstallStatus || (AppUpdateInstallStatus = {}));
12
- //# sourceMappingURL=types.js.map