@marktiderman/genesis-native 0.2.0 → 0.4.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 (98) hide show
  1. package/README.md +470 -10
  2. package/dist/block-Onqx7NiK.d.ts +223 -0
  3. package/dist/blocks-C2RDpvaN.d.ts +1595 -0
  4. package/dist/chunk-65P7RU4V.js +49 -0
  5. package/dist/chunk-65P7RU4V.js.map +1 -0
  6. package/dist/chunk-6BT4PTGH.js +37 -0
  7. package/dist/chunk-6BT4PTGH.js.map +1 -0
  8. package/dist/chunk-75YP72G6.js +374 -0
  9. package/dist/chunk-75YP72G6.js.map +1 -0
  10. package/dist/chunk-NGYNYJPL.js +90 -0
  11. package/dist/chunk-NGYNYJPL.js.map +1 -0
  12. package/dist/chunk-ONAXQHNG.js +23 -0
  13. package/dist/chunk-ONAXQHNG.js.map +1 -0
  14. package/dist/chunk-VKTIHNAV.js +95 -0
  15. package/dist/chunk-VKTIHNAV.js.map +1 -0
  16. package/dist/{chunk-MMTPWUWI.js → chunk-VTJDIKFC.js} +9 -6
  17. package/dist/chunk-VTJDIKFC.js.map +1 -0
  18. package/dist/chunk-XE7LC7K6.js +29 -0
  19. package/dist/chunk-XE7LC7K6.js.map +1 -0
  20. package/dist/dev-warnings.d.ts +34 -0
  21. package/dist/dev-warnings.js +15 -0
  22. package/dist/dev-warnings.js.map +1 -0
  23. package/dist/devtools.d.ts +144 -0
  24. package/dist/devtools.js +390 -0
  25. package/dist/devtools.js.map +1 -0
  26. package/dist/index.d.ts +12 -368
  27. package/dist/index.js +88 -191
  28. package/dist/index.js.map +1 -1
  29. package/dist/observability.d.ts +170 -0
  30. package/dist/observability.js +123 -0
  31. package/dist/observability.js.map +1 -0
  32. package/dist/persist.d.ts +1 -1
  33. package/dist/persist.js +1 -1
  34. package/dist/push-payload.d.ts +43 -0
  35. package/dist/push-payload.js +3 -0
  36. package/dist/push-payload.js.map +1 -0
  37. package/dist/push.d.ts +187 -0
  38. package/dist/push.js +1069 -0
  39. package/dist/push.js.map +1 -0
  40. package/dist/{query-DhH3lLFa.d.ts → query-DUmVAfsF.d.ts} +11 -6
  41. package/dist/rich-push-plugin.d.ts +74 -0
  42. package/dist/rich-push-plugin.js +209 -0
  43. package/dist/rich-push-plugin.js.map +1 -0
  44. package/dist/updates.d.ts +8 -1
  45. package/dist/updates.js +44 -69
  46. package/dist/updates.js.map +1 -1
  47. package/ios/notification-service/NotificationService.swift +309 -0
  48. package/package.json +238 -5
  49. package/src/app.tsx +491 -0
  50. package/src/auth.tsx +176 -0
  51. package/src/blocks.tsx +144 -0
  52. package/src/boot.tsx +188 -0
  53. package/src/dev-warnings.ts +43 -0
  54. package/src/devtools/block.tsx +488 -0
  55. package/src/devtools/gestures.ts +107 -0
  56. package/src/devtools/index.ts +22 -0
  57. package/src/devtools/info.ts +45 -0
  58. package/src/devtools/slots.ts +21 -0
  59. package/src/errors.tsx +195 -0
  60. package/src/held-link.ts +90 -0
  61. package/src/hydration-gate.ts +88 -0
  62. package/src/index.ts +83 -0
  63. package/src/links.ts +140 -0
  64. package/src/nativewind.d.ts +41 -0
  65. package/src/observability/block.tsx +300 -0
  66. package/src/observability/events.ts +89 -0
  67. package/src/observability/index.ts +44 -0
  68. package/src/observability/scrub.ts +166 -0
  69. package/src/observability/sentry.ts +222 -0
  70. package/src/observability/sink.ts +147 -0
  71. package/src/persist.ts +83 -0
  72. package/src/plugin/rich-push.ts +312 -0
  73. package/src/push/backend.ts +137 -0
  74. package/src/push/block.tsx +604 -0
  75. package/src/push/index.ts +105 -0
  76. package/src/push/modules.ts +123 -0
  77. package/src/push/payload.ts +61 -0
  78. package/src/push/permission.ts +191 -0
  79. package/src/push/preferences.ts +136 -0
  80. package/src/push/quiet-hours.ts +71 -0
  81. package/src/push/registration.ts +225 -0
  82. package/src/push/routing.ts +57 -0
  83. package/src/push/screens.tsx +46 -0
  84. package/src/push/settings.tsx +378 -0
  85. package/src/query.ts +100 -0
  86. package/src/updates/block.tsx +442 -0
  87. package/src/updates/channels.ts +131 -0
  88. package/src/updates/checker.ts +190 -0
  89. package/src/updates/index.ts +87 -0
  90. package/src/updates/modules.ts +64 -0
  91. package/src/updates/policy.ts +314 -0
  92. package/src/updates/screens.tsx +159 -0
  93. package/src/updates/signature.ts +80 -0
  94. package/src/updates/store.ts +33 -0
  95. package/src/updates/version.ts +39 -0
  96. package/src/updates/whats-new.ts +122 -0
  97. package/dist/block-Dh5ny06W.d.ts +0 -535
  98. package/dist/chunk-MMTPWUWI.js.map +0 -1
@@ -0,0 +1,209 @@
1
+ import { existsSync, readFileSync, mkdirSync, copyFileSync, writeFileSync } from 'fs';
2
+ import * as path from 'path';
3
+ import { fileURLToPath } from 'url';
4
+ import { withDangerousMod, withXcodeProject } from 'expo/config-plugins';
5
+
6
+ // src/plugin/rich-push.ts
7
+ var COMMUNICATION_ENTITLEMENT = "com.apple.developer.usernotifications.communication";
8
+ var SEND_MESSAGE_INTENT = "INSendMessageIntent";
9
+ var DEFAULT_TARGET_NAME = "GenesisNotificationService";
10
+ var DEFAULT_BUNDLE_SUFFIX = "NotificationService";
11
+ var SWIFT_FILE = "NotificationService.swift";
12
+ function resolve(options) {
13
+ const targetName = options?.targetName ?? DEFAULT_TARGET_NAME;
14
+ const bundleIdSuffix = options?.bundleIdSuffix ?? DEFAULT_BUNDLE_SUFFIX;
15
+ if (!/^[A-Za-z][A-Za-z0-9_]*$/.test(targetName)) throw new Error(`rich-push-plugin: targetName "${targetName}" must be letters, digits and _`);
16
+ if (!/^[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*$/.test(bundleIdSuffix)) throw new Error(`rich-push-plugin: bundleIdSuffix "${bundleIdSuffix}" isn't a bundle id part`);
17
+ const imageHosts = (options?.imageHosts ?? []).map((h) => h.trim().toLowerCase());
18
+ for (const h of imageHosts) if (!/^[a-z0-9-]+(\.[a-z0-9-]+)+$/.test(h)) throw new Error(`rich-push-plugin: imageHosts "${h}" isn't a host name`);
19
+ return { targetName, bundleIdSuffix, communication: options?.communication ?? true, deploymentTarget: options?.deploymentTarget, imageHosts };
20
+ }
21
+ function extensionBundleId(appBundleId, suffix = DEFAULT_BUNDLE_SUFFIX) {
22
+ return `${appBundleId}.${suffix}`;
23
+ }
24
+ function extensionEntitlements(communication) {
25
+ return communication ? { [COMMUNICATION_ENTITLEMENT]: true } : {};
26
+ }
27
+ function applyRichPushConfig(config, options) {
28
+ const o = resolve(options);
29
+ const bundleId = config.ios?.bundleIdentifier;
30
+ if (!bundleId) throw new Error("rich-push-plugin: ios.bundleIdentifier is required (the extension's id is built from it)");
31
+ const ios = { ...config.ios };
32
+ if (o.communication) {
33
+ ios.entitlements = { ...ios.entitlements, [COMMUNICATION_ENTITLEMENT]: true };
34
+ const types = Array.isArray(ios.infoPlist?.NSUserActivityTypes) ? ios.infoPlist.NSUserActivityTypes : [];
35
+ ios.infoPlist = { ...ios.infoPlist, NSUserActivityTypes: types.includes(SEND_MESSAGE_INTENT) ? types : [...types, SEND_MESSAGE_INTENT] };
36
+ }
37
+ const extra = { ...config.extra };
38
+ const eas = { ...extra.eas };
39
+ const build = { ...eas.build };
40
+ const experimental = { ...build.experimental };
41
+ const easIos = { ...experimental.ios };
42
+ const existing = Array.isArray(easIos.appExtensions) ? easIos.appExtensions : [];
43
+ const entry = { targetName: o.targetName, bundleIdentifier: extensionBundleId(bundleId, o.bundleIdSuffix), entitlements: extensionEntitlements(o.communication) };
44
+ easIos.appExtensions = [...existing.filter((e) => e?.targetName !== o.targetName), entry];
45
+ extra.eas = { ...eas, build: { ...build, experimental: { ...experimental, ios: easIos } } };
46
+ return { ...config, ios, extra };
47
+ }
48
+ function extensionInfoPlist(displayName, options = {}) {
49
+ const esc = (s) => s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
50
+ return `<?xml version="1.0" encoding="UTF-8"?>
51
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
52
+ <plist version="1.0">
53
+ <dict>
54
+ <key>CFBundleDevelopmentRegion</key>
55
+ <string>$(DEVELOPMENT_LANGUAGE)</string>
56
+ <key>CFBundleDisplayName</key>
57
+ <string>${esc(displayName)}</string>
58
+ <key>CFBundleExecutable</key>
59
+ <string>$(EXECUTABLE_NAME)</string>
60
+ <key>CFBundleIdentifier</key>
61
+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
62
+ <key>CFBundleInfoDictionaryVersion</key>
63
+ <string>6.0</string>
64
+ <key>CFBundleName</key>
65
+ <string>$(PRODUCT_NAME)</string>
66
+ <key>CFBundlePackageType</key>
67
+ <string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
68
+ <key>CFBundleShortVersionString</key>
69
+ <string>$(MARKETING_VERSION)</string>
70
+ <key>CFBundleVersion</key>
71
+ <string>$(CURRENT_PROJECT_VERSION)</string>
72
+ <key>NSExtension</key>
73
+ <dict>
74
+ <key>NSExtensionPointIdentifier</key>
75
+ <string>com.apple.usernotifications.service</string>
76
+ <key>NSExtensionPrincipalClass</key>
77
+ <string>$(PRODUCT_MODULE_NAME).NotificationService</string>${options.communication ? `
78
+ <key>NSExtensionAttributes</key>
79
+ <dict>
80
+ <key>IntentsSupported</key>
81
+ <array>
82
+ <string>${SEND_MESSAGE_INTENT}</string>
83
+ </array>
84
+ </dict>` : ""}
85
+ </dict>${options.imageHosts?.length ? `
86
+ <key>GenesisRichPushImageHosts</key>
87
+ <array>
88
+ ${options.imageHosts.map((h) => ` <string>${esc(h)}</string>`).join("\n")}
89
+ </array>` : ""}
90
+ </dict>
91
+ </plist>
92
+ `;
93
+ }
94
+ function entitlementsPlist(entitlements) {
95
+ const body = Object.entries(entitlements).map(([k, v]) => ` <key>${k}</key>
96
+ <${v ? "true" : "false"}/>`).join("\n");
97
+ return `<?xml version="1.0" encoding="UTF-8"?>
98
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
99
+ <plist version="1.0">
100
+ <dict>
101
+ ${body}
102
+ </dict>
103
+ </plist>
104
+ `;
105
+ }
106
+ function packageRoot(from = path.dirname(fileURLToPath(import.meta.url))) {
107
+ let dir = from;
108
+ for (; ; ) {
109
+ const pkg = path.join(dir, "package.json");
110
+ if (existsSync(pkg) && JSON.parse(readFileSync(pkg, "utf8")).name === "@marktiderman/genesis-native") return dir;
111
+ const parent = path.dirname(dir);
112
+ if (parent === dir) throw new Error("rich-push-plugin: can't find @marktiderman/genesis-native's folder");
113
+ dir = parent;
114
+ }
115
+ }
116
+ function serviceSwiftPath(root = packageRoot()) {
117
+ return path.join(root, "ios", "notification-service", SWIFT_FILE);
118
+ }
119
+ function writeExtensionFiles(iosRoot, options) {
120
+ const dir = path.join(iosRoot, options.targetName);
121
+ mkdirSync(dir, { recursive: true });
122
+ copyFileSync(options.swiftSource ?? serviceSwiftPath(), path.join(dir, SWIFT_FILE));
123
+ writeFileSync(path.join(dir, "Info.plist"), extensionInfoPlist(options.displayName, { communication: options.communication, imageHosts: options.imageHosts ?? [] }));
124
+ writeFileSync(path.join(dir, `${options.targetName}.entitlements`), entitlementsPlist(extensionEntitlements(options.communication)));
125
+ }
126
+ var unquote = (v) => typeof v === "string" ? v.replace(/^"(.*)"$/, "$1") : v;
127
+ function appSetting(project, key) {
128
+ const app = project.getFirstTarget();
129
+ const listId = app?.firstTarget?.buildConfigurationList;
130
+ const lists = project.pbxXCConfigurationList();
131
+ const configs = project.pbxXCBuildConfigurationSection();
132
+ for (const ref of lists[listId]?.buildConfigurations ?? []) {
133
+ const value = configs[ref.value]?.buildSettings?.[key];
134
+ if (value !== void 0) return String(unquote(value));
135
+ }
136
+ return void 0;
137
+ }
138
+ function addNotificationServiceTarget(project, options) {
139
+ const { targetName } = options;
140
+ if (project.pbxTargetByName(targetName) || project.pbxTargetByName(`"${targetName}"`)) return { added: false };
141
+ const objects = project.hash.project.objects;
142
+ objects.PBXTargetDependency ??= {};
143
+ objects.PBXContainerItemProxy ??= {};
144
+ const deploymentTarget = options.deploymentTarget ?? appSetting(project, "IPHONEOS_DEPLOYMENT_TARGET") ?? "15.1";
145
+ const marketingVersion = options.marketingVersion ?? appSetting(project, "MARKETING_VERSION") ?? "1.0";
146
+ const buildNumber = options.buildNumber ?? appSetting(project, "CURRENT_PROJECT_VERSION") ?? "1";
147
+ const developmentTeam = options.developmentTeam ?? appSetting(project, "DEVELOPMENT_TEAM");
148
+ const group = project.addPbxGroup([SWIFT_FILE], targetName, targetName);
149
+ project.addFile("Info.plist", group.uuid, { lastKnownFileType: "text.plist.xml" });
150
+ project.addFile(`${targetName}.entitlements`, group.uuid, { lastKnownFileType: "text.plist.entitlements" });
151
+ const mainGroup = project.getFirstProject().firstProject.mainGroup;
152
+ project.addToPbxGroup(group.uuid, mainGroup);
153
+ const target = project.addTarget(targetName, "app_extension", targetName, options.bundleId);
154
+ project.addBuildPhase([SWIFT_FILE], "PBXSourcesBuildPhase", "Sources", target.uuid);
155
+ project.addBuildPhase([], "PBXFrameworksBuildPhase", "Frameworks", target.uuid);
156
+ project.addBuildPhase([], "PBXResourcesBuildPhase", "Resources", target.uuid);
157
+ const configs = project.pbxXCBuildConfigurationSection();
158
+ const listId = target.pbxNativeTarget.buildConfigurationList;
159
+ for (const ref of project.pbxXCConfigurationList()[listId].buildConfigurations) {
160
+ const settings = configs[ref.value].buildSettings;
161
+ Object.assign(settings, {
162
+ INFOPLIST_FILE: `${targetName}/Info.plist`,
163
+ CODE_SIGN_ENTITLEMENTS: `${targetName}/${targetName}.entitlements`,
164
+ CODE_SIGN_STYLE: "Automatic",
165
+ IPHONEOS_DEPLOYMENT_TARGET: deploymentTarget,
166
+ TARGETED_DEVICE_FAMILY: '"1,2"',
167
+ SWIFT_VERSION: "5.0",
168
+ MARKETING_VERSION: marketingVersion,
169
+ CURRENT_PROJECT_VERSION: buildNumber,
170
+ GENERATE_INFOPLIST_FILE: "NO",
171
+ PRODUCT_BUNDLE_IDENTIFIER: `"${options.bundleId}"`,
172
+ SDKROOT: "iphoneos",
173
+ CLANG_ENABLE_MODULES: "YES",
174
+ SWIFT_EMIT_LOC_STRINGS: "YES",
175
+ ...developmentTeam ? { DEVELOPMENT_TEAM: developmentTeam } : {}
176
+ });
177
+ }
178
+ if (developmentTeam) project.addTargetAttribute("DevelopmentTeam", developmentTeam, target);
179
+ return { added: true };
180
+ }
181
+ var withRichPush = (config, options) => {
182
+ const o = resolve(options ?? void 0);
183
+ config = applyRichPushConfig(config, o);
184
+ const bundleId = extensionBundleId(config.ios.bundleIdentifier, o.bundleIdSuffix);
185
+ config = withDangerousMod(config, [
186
+ "ios",
187
+ (c) => {
188
+ writeExtensionFiles(c.modRequest.platformProjectRoot, { targetName: o.targetName, displayName: c.name, communication: o.communication, imageHosts: o.imageHosts });
189
+ return c;
190
+ }
191
+ ]);
192
+ config = withXcodeProject(config, (c) => {
193
+ addNotificationServiceTarget(c.modResults, {
194
+ targetName: o.targetName,
195
+ bundleId,
196
+ ...o.deploymentTarget ? { deploymentTarget: o.deploymentTarget } : {},
197
+ ...c.ios?.appleTeamId ? { developmentTeam: c.ios.appleTeamId } : {},
198
+ ...c.version ? { marketingVersion: c.version } : {},
199
+ ...c.ios?.buildNumber ? { buildNumber: c.ios.buildNumber } : {}
200
+ });
201
+ return c;
202
+ });
203
+ return config;
204
+ };
205
+ var rich_push_default = withRichPush;
206
+
207
+ export { COMMUNICATION_ENTITLEMENT, DEFAULT_BUNDLE_SUFFIX, DEFAULT_TARGET_NAME, SEND_MESSAGE_INTENT, addNotificationServiceTarget, applyRichPushConfig, rich_push_default as default, entitlementsPlist, extensionBundleId, extensionEntitlements, extensionInfoPlist, packageRoot, serviceSwiftPath, writeExtensionFiles };
208
+ //# sourceMappingURL=rich-push-plugin.js.map
209
+ //# sourceMappingURL=rich-push-plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/plugin/rich-push.ts"],"names":[],"mappings":";;;;;;AA2BO,IAAM,yBAAA,GAA4B;AAClC,IAAM,mBAAA,GAAsB;AAC5B,IAAM,mBAAA,GAAsB;AAC5B,IAAM,qBAAA,GAAwB;AACrC,IAAM,UAAA,GAAa,2BAAA;AA8BnB,SAAS,QAAQ,OAAA,EAAsD;AACrE,EAAA,MAAM,UAAA,GAAa,SAAS,UAAA,IAAc,mBAAA;AAC1C,EAAA,MAAM,cAAA,GAAiB,SAAS,cAAA,IAAkB,qBAAA;AAClD,EAAA,IAAI,CAAC,yBAAA,CAA0B,IAAA,CAAK,UAAU,CAAA,QAAS,IAAI,KAAA,CAAM,CAAA,8BAAA,EAAiC,UAAU,CAAA,+BAAA,CAAiC,CAAA;AAC7I,EAAA,IAAI,CAAC,mCAAA,CAAoC,IAAA,CAAK,cAAc,CAAA,QAAS,IAAI,KAAA,CAAM,CAAA,kCAAA,EAAqC,cAAc,CAAA,wBAAA,CAA0B,CAAA;AAC5J,EAAA,MAAM,UAAA,GAAA,CAAc,OAAA,EAAS,UAAA,IAAc,EAAC,EAAG,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,IAAA,EAAK,CAAE,WAAA,EAAa,CAAA;AAChF,EAAA,KAAA,MAAW,CAAA,IAAK,UAAA,EAAY,IAAI,CAAC,6BAAA,CAA8B,IAAA,CAAK,CAAC,CAAA,EAAG,MAAM,IAAI,KAAA,CAAM,CAAA,8BAAA,EAAiC,CAAC,CAAA,mBAAA,CAAqB,CAAA;AAC/I,EAAA,OAAO,EAAE,UAAA,EAAY,cAAA,EAAgB,aAAA,EAAe,OAAA,EAAS,iBAAiB,IAAA,EAAM,gBAAA,EAAkB,OAAA,EAAS,gBAAA,EAAkB,UAAA,EAAW;AAC9I;AAGO,SAAS,iBAAA,CAAkB,WAAA,EAAqB,MAAA,GAAS,qBAAA,EAA+B;AAC7F,EAAA,OAAO,CAAA,EAAG,WAAW,CAAA,CAAA,EAAI,MAAM,CAAA,CAAA;AACjC;AAGO,SAAS,sBAAsB,aAAA,EAAiD;AACrF,EAAA,OAAO,gBAAgB,EAAE,CAAC,yBAAyB,GAAG,IAAA,KAAS,EAAC;AAClE;AAOO,SAAS,mBAAA,CAAoB,QAAoB,OAAA,EAA6C;AACnG,EAAA,MAAM,CAAA,GAAI,QAAQ,OAAO,CAAA;AACzB,EAAA,MAAM,QAAA,GAAW,OAAO,GAAA,EAAK,gBAAA;AAC7B,EAAA,IAAI,CAAC,QAAA,EAAU,MAAM,IAAI,MAAM,0FAA0F,CAAA;AACzH,EAAA,MAAM,GAAA,GAAM,EAAE,GAAG,MAAA,CAAO,GAAA,EAAI;AAC5B,EAAA,IAAI,EAAE,aAAA,EAAe;AACnB,IAAA,GAAA,CAAI,YAAA,GAAe,EAAE,GAAG,GAAA,CAAI,cAAc,CAAC,yBAAyB,GAAG,IAAA,EAAK;AAC5E,IAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,OAAA,CAAQ,GAAA,CAAI,SAAA,EAAW,mBAAmB,CAAA,GAAK,GAAA,CAAI,SAAA,CAAW,mBAAA,GAAoC,EAAC;AACvH,IAAA,GAAA,CAAI,SAAA,GAAY,EAAE,GAAG,GAAA,CAAI,WAAW,mBAAA,EAAqB,KAAA,CAAM,QAAA,CAAS,mBAAmB,IAAI,KAAA,GAAQ,CAAC,GAAG,KAAA,EAAO,mBAAmB,CAAA,EAAE;AAAA,EACzI;AACA,EAAA,MAAM,KAAA,GAAQ,EAAE,GAAG,MAAA,CAAO,KAAA,EAAM;AAChC,EAAA,MAAM,GAAA,GAAM,EAAE,GAAI,KAAA,CAAM,GAAA,EAA4C;AACpE,EAAA,MAAM,KAAA,GAAQ,EAAE,GAAI,GAAA,CAAI,KAAA,EAA8C;AACtE,EAAA,MAAM,YAAA,GAAe,EAAE,GAAI,KAAA,CAAM,YAAA,EAAqD;AACtF,EAAA,MAAM,MAAA,GAAS,EAAE,GAAI,YAAA,CAAa,GAAA,EAA4C;AAC9E,EAAA,MAAM,QAAA,GAAW,MAAM,OAAA,CAAQ,MAAA,CAAO,aAAa,CAAA,GAAK,MAAA,CAAO,gBAA8C,EAAC;AAC9G,EAAA,MAAM,KAAA,GAAQ,EAAE,UAAA,EAAY,CAAA,CAAE,YAAY,gBAAA,EAAkB,iBAAA,CAAkB,QAAA,EAAU,CAAA,CAAE,cAAc,CAAA,EAAG,YAAA,EAAc,qBAAA,CAAsB,CAAA,CAAE,aAAa,CAAA,EAAE;AAChK,EAAA,MAAA,CAAO,aAAA,GAAgB,CAAC,GAAG,QAAA,CAAS,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,EAAG,UAAA,KAAe,CAAA,CAAE,UAAU,CAAA,EAAG,KAAK,CAAA;AACxF,EAAA,KAAA,CAAM,GAAA,GAAM,EAAE,GAAG,GAAA,EAAK,OAAO,EAAE,GAAG,KAAA,EAAO,YAAA,EAAc,EAAE,GAAG,YAAA,EAAc,GAAA,EAAK,MAAA,IAAS,EAAE;AAC1F,EAAA,OAAO,EAAE,GAAG,MAAA,EAAQ,GAAA,EAAK,KAAA,EAAM;AACjC;AAGO,SAAS,kBAAA,CAAmB,WAAA,EAAqB,OAAA,GAA8D,EAAC,EAAW;AAChI,EAAA,MAAM,GAAA,GAAM,CAAC,CAAA,KAAc,CAAA,CAAE,QAAQ,IAAA,EAAM,OAAO,CAAA,CAAE,OAAA,CAAQ,IAAA,EAAM,MAAM,CAAA,CAAE,OAAA,CAAQ,MAAM,MAAM,CAAA;AAC9F,EAAA,OAAO,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAAA,EAOG,GAAA,CAAI,WAAW,CAAC,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,+DAAA,EAqBtB,QAAQ,aAAA,GACJ;AAAA;AAAA;AAAA;AAAA;AAAA,gBAAA,EAKQ,mBAAmB,CAAA;AAAA;AAAA,WAAA,CAAA,GAG3B,EACN;AAAA,SAAA,EAEA,OAAA,CAAQ,YAAY,MAAA,GAChB;AAAA;AAAA;AAAA,EAGN,OAAA,CAAQ,UAAA,CAAW,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,YAAA,EAAe,GAAA,CAAI,CAAC,CAAC,CAAA,SAAA,CAAW,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC;AAAA,UAAA,CAAA,GAEpE,EACN;AAAA;AAAA;AAAA,CAAA;AAIF;AAEO,SAAS,kBAAkB,YAAA,EAA+C;AAC/E,EAAA,MAAM,IAAA,GAAO,MAAA,CAAO,OAAA,CAAQ,YAAY,CAAA,CACrC,GAAA,CAAI,CAAC,CAAC,CAAA,EAAG,CAAC,CAAA,KAAM,CAAA,OAAA,EAAU,CAAC,CAAA;AAAA,GAAA,EAAc,IAAI,MAAA,GAAS,OAAO,CAAA,EAAA,CAAI,CAAA,CACjE,KAAK,IAAI,CAAA;AACZ,EAAA,OAAO,CAAA;AAAA;AAAA;AAAA;AAAA,EAIP,IAAI;AAAA;AAAA;AAAA,CAAA;AAIN;AAGO,SAAS,YAAY,IAAA,GAAY,IAAA,CAAA,OAAA,CAAQ,cAAc,MAAA,CAAA,IAAA,CAAY,GAAG,CAAC,CAAA,EAAW;AACvF,EAAA,IAAI,GAAA,GAAM,IAAA;AACV,EAAA,WAAS;AACP,IAAA,MAAM,GAAA,GAAW,IAAA,CAAA,IAAA,CAAK,GAAA,EAAK,cAAc,CAAA;AACzC,IAAA,IAAI,UAAA,CAAW,GAAG,CAAA,IAAM,IAAA,CAAK,KAAA,CAAM,YAAA,CAAa,GAAA,EAAK,MAAM,CAAC,CAAA,CAAwB,IAAA,KAAS,8BAAA,EAAgC,OAAO,GAAA;AACpI,IAAA,MAAM,MAAA,GAAc,aAAQ,GAAG,CAAA;AAC/B,IAAA,IAAI,MAAA,KAAW,GAAA,EAAK,MAAM,IAAI,MAAM,oEAAoE,CAAA;AACxG,IAAA,GAAA,GAAM,MAAA;AAAA,EACR;AACF;AAGO,SAAS,gBAAA,CAAiB,IAAA,GAAO,WAAA,EAAY,EAAW;AAC7D,EAAA,OAAY,IAAA,CAAA,IAAA,CAAK,IAAA,EAAM,KAAA,EAAO,sBAAA,EAAwB,UAAU,CAAA;AAClE;AAGO,SAAS,mBAAA,CACd,SACA,OAAA,EACM;AACN,EAAA,MAAM,GAAA,GAAW,IAAA,CAAA,IAAA,CAAK,OAAA,EAAS,OAAA,CAAQ,UAAU,CAAA;AACjD,EAAA,SAAA,CAAU,GAAA,EAAK,EAAE,SAAA,EAAW,IAAA,EAAM,CAAA;AAClC,EAAA,YAAA,CAAa,QAAQ,WAAA,IAAe,gBAAA,IAAyB,IAAA,CAAA,IAAA,CAAK,GAAA,EAAK,UAAU,CAAC,CAAA;AAClF,EAAA,aAAA,CAAmB,UAAK,GAAA,EAAK,YAAY,CAAA,EAAG,kBAAA,CAAmB,QAAQ,WAAA,EAAa,EAAE,aAAA,EAAe,OAAA,CAAQ,eAAe,UAAA,EAAY,OAAA,CAAQ,cAAc,EAAC,EAAG,CAAC,CAAA;AACnK,EAAA,aAAA,CAAmB,IAAA,CAAA,IAAA,CAAK,GAAA,EAAK,CAAA,EAAG,OAAA,CAAQ,UAAU,CAAA,aAAA,CAAe,CAAA,EAAG,iBAAA,CAAkB,qBAAA,CAAsB,OAAA,CAAQ,aAAa,CAAC,CAAC,CAAA;AACrI;AAMA,IAAM,OAAA,GAAU,CAAC,CAAA,KAAgB,OAAO,CAAA,KAAM,WAAW,CAAA,CAAE,OAAA,CAAQ,UAAA,EAAY,IAAI,CAAA,GAAI,CAAA;AAGvF,SAAS,UAAA,CAAW,SAAuB,GAAA,EAAiC;AAC1E,EAAA,MAAM,GAAA,GAAM,QAAQ,cAAA,EAAe;AACnC,EAAA,MAAM,MAAA,GAAS,KAAK,WAAA,EAAa,sBAAA;AACjC,EAAA,MAAM,KAAA,GAAQ,QAAQ,sBAAA,EAAuB;AAC7C,EAAA,MAAM,OAAA,GAAU,QAAQ,8BAAA,EAA+B;AACvD,EAAA,KAAA,MAAW,OAAO,KAAA,CAAM,MAAM,CAAA,EAAG,mBAAA,IAAuB,EAAC,EAAG;AAC1D,IAAA,MAAM,QAAQ,OAAA,CAAQ,GAAA,CAAI,KAAK,CAAA,EAAG,gBAAgB,GAAG,CAAA;AACrD,IAAA,IAAI,UAAU,MAAA,EAAW,OAAO,MAAA,CAAO,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EACvD;AACA,EAAA,OAAO,MAAA;AACT;AAOO,SAAS,4BAAA,CACd,SACA,OAAA,EACoB;AACpB,EAAA,MAAM,EAAE,YAAW,GAAI,OAAA;AACvB,EAAA,IAAI,OAAA,CAAQ,eAAA,CAAgB,UAAU,CAAA,IAAK,OAAA,CAAQ,eAAA,CAAgB,CAAA,CAAA,EAAI,UAAU,CAAA,CAAA,CAAG,CAAA,EAAG,OAAO,EAAE,OAAO,KAAA,EAAM;AAE7G,EAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,IAAA,CAAK,OAAA,CAAQ,OAAA;AAErC,EAAA,OAAA,CAAQ,wBAAwB,EAAC;AACjC,EAAA,OAAA,CAAQ,0BAA0B,EAAC;AAEnC,EAAA,MAAM,mBAAmB,OAAA,CAAQ,gBAAA,IAAoB,UAAA,CAAW,OAAA,EAAS,4BAA4B,CAAA,IAAK,MAAA;AAC1G,EAAA,MAAM,mBAAmB,OAAA,CAAQ,gBAAA,IAAoB,UAAA,CAAW,OAAA,EAAS,mBAAmB,CAAA,IAAK,KAAA;AACjG,EAAA,MAAM,cAAc,OAAA,CAAQ,WAAA,IAAe,UAAA,CAAW,OAAA,EAAS,yBAAyB,CAAA,IAAK,GAAA;AAC7F,EAAA,MAAM,eAAA,GAAkB,OAAA,CAAQ,eAAA,IAAmB,UAAA,CAAW,SAAS,kBAAkB,CAAA;AAGzF,EAAA,MAAM,QAAQ,OAAA,CAAQ,WAAA,CAAY,CAAC,UAAU,CAAA,EAAG,YAAY,UAAU,CAAA;AACtE,EAAA,OAAA,CAAQ,QAAQ,YAAA,EAAc,KAAA,CAAM,MAAM,EAAE,iBAAA,EAAmB,kBAAkB,CAAA;AACjF,EAAA,OAAA,CAAQ,OAAA,CAAQ,GAAG,UAAU,CAAA,aAAA,CAAA,EAAiB,MAAM,IAAA,EAAM,EAAE,iBAAA,EAAmB,yBAAA,EAA2B,CAAA;AAC1G,EAAA,MAAM,SAAA,GAAY,OAAA,CAAQ,eAAA,EAAgB,CAAE,YAAA,CAAa,SAAA;AACzD,EAAA,OAAA,CAAQ,aAAA,CAAc,KAAA,CAAM,IAAA,EAAM,SAAS,CAAA;AAE3C,EAAA,MAAM,SAAS,OAAA,CAAQ,SAAA,CAAU,YAAY,eAAA,EAAiB,UAAA,EAAY,QAAQ,QAAQ,CAAA;AAC1F,EAAA,OAAA,CAAQ,cAAc,CAAC,UAAU,GAAG,sBAAA,EAAwB,SAAA,EAAW,OAAO,IAAI,CAAA;AAClF,EAAA,OAAA,CAAQ,cAAc,EAAC,EAAG,yBAAA,EAA2B,YAAA,EAAc,OAAO,IAAI,CAAA;AAC9E,EAAA,OAAA,CAAQ,cAAc,EAAC,EAAG,wBAAA,EAA0B,WAAA,EAAa,OAAO,IAAI,CAAA;AAE5E,EAAA,MAAM,OAAA,GAAU,QAAQ,8BAAA,EAA+B;AACvD,EAAA,MAAM,MAAA,GAAS,OAAO,eAAA,CAAgB,sBAAA;AACtC,EAAA,KAAA,MAAW,OAAO,OAAA,CAAQ,sBAAA,EAAuB,CAAE,MAAM,EAAE,mBAAA,EAAqB;AAC9E,IAAA,MAAM,QAAA,GAAW,OAAA,CAAQ,GAAA,CAAI,KAAK,CAAA,CAAE,aAAA;AACpC,IAAA,MAAA,CAAO,OAAO,QAAA,EAAU;AAAA,MACtB,cAAA,EAAgB,GAAG,UAAU,CAAA,WAAA,CAAA;AAAA,MAC7B,sBAAA,EAAwB,CAAA,EAAG,UAAU,CAAA,CAAA,EAAI,UAAU,CAAA,aAAA,CAAA;AAAA,MACnD,eAAA,EAAiB,WAAA;AAAA,MACjB,0BAAA,EAA4B,gBAAA;AAAA,MAC5B,sBAAA,EAAwB,OAAA;AAAA,MACxB,aAAA,EAAe,KAAA;AAAA,MACf,iBAAA,EAAmB,gBAAA;AAAA,MACnB,uBAAA,EAAyB,WAAA;AAAA,MACzB,uBAAA,EAAyB,IAAA;AAAA,MACzB,yBAAA,EAA2B,CAAA,CAAA,EAAI,OAAA,CAAQ,QAAQ,CAAA,CAAA,CAAA;AAAA,MAC/C,OAAA,EAAS,UAAA;AAAA,MACT,oBAAA,EAAsB,KAAA;AAAA,MACtB,sBAAA,EAAwB,KAAA;AAAA,MACxB,GAAI,eAAA,GAAkB,EAAE,gBAAA,EAAkB,eAAA,KAAoB;AAAC,KAChE,CAAA;AAAA,EACH;AACA,EAAA,IAAI,eAAA,EAAiB,OAAA,CAAQ,kBAAA,CAAmB,iBAAA,EAAmB,iBAAiB,MAAM,CAAA;AAC1F,EAAA,OAAO,EAAE,OAAO,IAAA,EAAK;AACvB;AAEA,IAAM,YAAA,GAA2D,CAAC,MAAA,EAAQ,OAAA,KAAY;AACpF,EAAA,MAAM,CAAA,GAAI,OAAA,CAAQ,OAAA,IAAW,MAAS,CAAA;AACtC,EAAA,MAAA,GAAS,mBAAA,CAAoB,QAAQ,CAAC,CAAA;AACtC,EAAA,MAAM,WAAW,iBAAA,CAAkB,MAAA,CAAO,GAAA,CAAK,gBAAA,EAAmB,EAAE,cAAc,CAAA;AAElF,EAAA,MAAA,GAAS,iBAAiB,MAAA,EAAQ;AAAA,IAChC,KAAA;AAAA,IACA,CAAC,CAAA,KAAM;AACL,MAAA,mBAAA,CAAoB,EAAE,UAAA,CAAW,mBAAA,EAAqB,EAAE,UAAA,EAAY,EAAE,UAAA,EAAY,WAAA,EAAa,CAAA,CAAE,IAAA,EAAM,eAAe,CAAA,CAAE,aAAA,EAAe,UAAA,EAAY,CAAA,CAAE,YAAY,CAAA;AACjK,MAAA,OAAO,CAAA;AAAA,IACT;AAAA,GACD,CAAA;AACD,EAAA,MAAA,GAAS,gBAAA,CAAiB,MAAA,EAAQ,CAAC,CAAA,KAAM;AACvC,IAAA,4BAAA,CAA6B,EAAE,UAAA,EAAY;AAAA,MACzC,YAAY,CAAA,CAAE,UAAA;AAAA,MACd,QAAA;AAAA,MACA,GAAI,EAAE,gBAAA,GAAmB,EAAE,kBAAkB,CAAA,CAAE,gBAAA,KAAqB,EAAC;AAAA,MACrE,GAAI,CAAA,CAAE,GAAA,EAAK,WAAA,GAAc,EAAE,iBAAiB,CAAA,CAAE,GAAA,CAAI,WAAA,EAAY,GAAI,EAAC;AAAA,MACnE,GAAI,EAAE,OAAA,GAAU,EAAE,kBAAkB,CAAA,CAAE,OAAA,KAAY,EAAC;AAAA,MACnD,GAAI,CAAA,CAAE,GAAA,EAAK,WAAA,GAAc,EAAE,aAAa,CAAA,CAAE,GAAA,CAAI,WAAA,EAAY,GAAI;AAAC,KAChE,CAAA;AACD,IAAA,OAAO,CAAA;AAAA,EACT,CAAC,CAAA;AACD,EAAA,OAAO,MAAA;AACT,CAAA;AAEA,IAAO,iBAAA,GAAQ","file":"rich-push-plugin.js","sourcesContent":["/**\n * `@marktiderman/genesis-native/rich-push-plugin`: the Expo config plugin for\n * iOS rich push. It adds a Notification Service Extension target (the Swift in\n * `ios/notification-service/`) that downloads `data.image` / `data.senderAvatar`\n * and turns `messages` pushes into Communication Notifications (the sender's\n * photo, Focus treats them as messages), and it sets what they need:\n *\n * - the app: `com.apple.developer.usernotifications.communication` and\n * `NSUserActivityTypes: [INSendMessageIntent]`;\n * - the extension: its own bundle id (`<app>.NotificationService`), Info.plist\n * and entitlements, embedded in the app;\n * - EAS: `extra.eas.build.experimental.ios.appExtensions`, so EAS Build makes\n * the extension's provisioning profile with the app's.\n *\n * plugins: [..., \"@marktiderman/genesis-cli\", \"@marktiderman/genesis-native/rich-push-plugin\"]\n *\n * List it after any plugin that changes the bundle id (the Genesis plugin's\n * APP_VARIANT suffix): the extension's id is the app's plus a suffix, read\n * when this plugin runs. Running it twice changes nothing.\n */\nimport { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport * as path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n// Expo's own copy (the app's `expo`), so the mods run on the same config-plugins as prebuild.\nimport { withDangerousMod, withXcodeProject, type ConfigPlugin } from \"expo/config-plugins\";\nimport type { ExpoConfig } from \"expo/config\";\n\nexport const COMMUNICATION_ENTITLEMENT = \"com.apple.developer.usernotifications.communication\";\nexport const SEND_MESSAGE_INTENT = \"INSendMessageIntent\";\nexport const DEFAULT_TARGET_NAME = \"GenesisNotificationService\";\nexport const DEFAULT_BUNDLE_SUFFIX = \"NotificationService\";\nconst SWIFT_FILE = \"NotificationService.swift\";\n\nexport interface RichPushPluginOptions {\n /** The extension's Xcode target and folder under ios/. Default `GenesisNotificationService`. */\n targetName?: string;\n /** Appended to the app's bundle id with a dot. Default `NotificationService`. */\n bundleIdSuffix?: string;\n /**\n * Communication Notifications (the sender's photo, Focus): the entitlement and\n * `NSUserActivityTypes`. Default true; false keeps image attachments only.\n */\n communication?: boolean;\n /** The extension's minimum iOS. Default: the app target's. */\n deploymentTarget?: string;\n /**\n * The hosts images may be downloaded from (`cdn.example.com`, or `example.com`\n * for it and its subdomains). Unset, any https host: a sender who puts a URL\n * a person chose (their avatar) in a push lets that host see each delivery.\n */\n imageHosts?: string[];\n}\n\ninterface Resolved {\n targetName: string;\n bundleIdSuffix: string;\n communication: boolean;\n deploymentTarget: string | undefined;\n imageHosts: string[];\n}\n\nfunction resolve(options: RichPushPluginOptions | undefined): Resolved {\n const targetName = options?.targetName ?? DEFAULT_TARGET_NAME;\n const bundleIdSuffix = options?.bundleIdSuffix ?? DEFAULT_BUNDLE_SUFFIX;\n if (!/^[A-Za-z][A-Za-z0-9_]*$/.test(targetName)) throw new Error(`rich-push-plugin: targetName \"${targetName}\" must be letters, digits and _`);\n if (!/^[A-Za-z0-9-]+(\\.[A-Za-z0-9-]+)*$/.test(bundleIdSuffix)) throw new Error(`rich-push-plugin: bundleIdSuffix \"${bundleIdSuffix}\" isn't a bundle id part`);\n const imageHosts = (options?.imageHosts ?? []).map((h) => h.trim().toLowerCase());\n for (const h of imageHosts) if (!/^[a-z0-9-]+(\\.[a-z0-9-]+)+$/.test(h)) throw new Error(`rich-push-plugin: imageHosts \"${h}\" isn't a host name`);\n return { targetName, bundleIdSuffix, communication: options?.communication ?? true, deploymentTarget: options?.deploymentTarget, imageHosts };\n}\n\n/** The extension's bundle id: the app's plus the suffix. */\nexport function extensionBundleId(appBundleId: string, suffix = DEFAULT_BUNDLE_SUFFIX): string {\n return `${appBundleId}.${suffix}`;\n}\n\n/** The extension's entitlements (also what EAS provisions it with). */\nexport function extensionEntitlements(communication: boolean): Record<string, unknown> {\n return communication ? { [COMMUNICATION_ENTITLEMENT]: true } : {};\n}\n\n/**\n * The config-time part, visible in `expo config`: the app's entitlement and\n * `NSUserActivityTypes`, and the extension for EAS. Fills gaps and appends;\n * never removes what the app set.\n */\nexport function applyRichPushConfig(config: ExpoConfig, options?: RichPushPluginOptions): ExpoConfig {\n const o = resolve(options);\n const bundleId = config.ios?.bundleIdentifier;\n if (!bundleId) throw new Error(\"rich-push-plugin: ios.bundleIdentifier is required (the extension's id is built from it)\");\n const ios = { ...config.ios };\n if (o.communication) {\n ios.entitlements = { ...ios.entitlements, [COMMUNICATION_ENTITLEMENT]: true };\n const types = Array.isArray(ios.infoPlist?.NSUserActivityTypes) ? (ios.infoPlist!.NSUserActivityTypes as unknown[]) : [];\n ios.infoPlist = { ...ios.infoPlist, NSUserActivityTypes: types.includes(SEND_MESSAGE_INTENT) ? types : [...types, SEND_MESSAGE_INTENT] };\n }\n const extra = { ...config.extra };\n const eas = { ...(extra.eas as Record<string, unknown> | undefined) };\n const build = { ...(eas.build as Record<string, unknown> | undefined) };\n const experimental = { ...(build.experimental as Record<string, unknown> | undefined) };\n const easIos = { ...(experimental.ios as Record<string, unknown> | undefined) };\n const existing = Array.isArray(easIos.appExtensions) ? (easIos.appExtensions as { targetName?: string }[]) : [];\n const entry = { targetName: o.targetName, bundleIdentifier: extensionBundleId(bundleId, o.bundleIdSuffix), entitlements: extensionEntitlements(o.communication) };\n easIos.appExtensions = [...existing.filter((e) => e?.targetName !== o.targetName), entry];\n extra.eas = { ...eas, build: { ...build, experimental: { ...experimental, ios: easIos } } };\n return { ...config, ios, extra };\n}\n\n/** The extension's Info.plist. Versions follow the app's (App Store Connect rejects a mismatch). */\nexport function extensionInfoPlist(displayName: string, options: { communication?: boolean; imageHosts?: string[] } = {}): string {\n const esc = (s: string) => s.replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\");\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>CFBundleDevelopmentRegion</key>\n <string>$(DEVELOPMENT_LANGUAGE)</string>\n <key>CFBundleDisplayName</key>\n <string>${esc(displayName)}</string>\n <key>CFBundleExecutable</key>\n <string>$(EXECUTABLE_NAME)</string>\n <key>CFBundleIdentifier</key>\n <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n <key>CFBundleInfoDictionaryVersion</key>\n <string>6.0</string>\n <key>CFBundleName</key>\n <string>$(PRODUCT_NAME)</string>\n <key>CFBundlePackageType</key>\n <string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>\n <key>CFBundleShortVersionString</key>\n <string>$(MARKETING_VERSION)</string>\n <key>CFBundleVersion</key>\n <string>$(CURRENT_PROJECT_VERSION)</string>\n <key>NSExtension</key>\n <dict>\n <key>NSExtensionPointIdentifier</key>\n <string>com.apple.usernotifications.service</string>\n <key>NSExtensionPrincipalClass</key>\n <string>$(PRODUCT_MODULE_NAME).NotificationService</string>${\n options.communication\n ? `\n <key>NSExtensionAttributes</key>\n <dict>\n <key>IntentsSupported</key>\n <array>\n <string>${SEND_MESSAGE_INTENT}</string>\n </array>\n </dict>`\n : \"\"\n }\n </dict>${\n options.imageHosts?.length\n ? `\n <key>GenesisRichPushImageHosts</key>\n <array>\n${options.imageHosts.map((h) => ` <string>${esc(h)}</string>`).join(\"\\n\")}\n </array>`\n : \"\"\n }\n</dict>\n</plist>\n`;\n}\n\nexport function entitlementsPlist(entitlements: Record<string, unknown>): string {\n const body = Object.entries(entitlements)\n .map(([k, v]) => ` <key>${k}</key>\\n <${v ? \"true\" : \"false\"}/>`)\n .join(\"\\n\");\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n${body}\n</dict>\n</plist>\n`;\n}\n\n/** This package's root, found from this file (src/plugin in tests, dist when built). */\nexport function packageRoot(from = path.dirname(fileURLToPath(import.meta.url))): string {\n let dir = from;\n for (;;) {\n const pkg = path.join(dir, \"package.json\");\n if (existsSync(pkg) && (JSON.parse(readFileSync(pkg, \"utf8\")) as { name?: string }).name === \"@marktiderman/genesis-native\") return dir;\n const parent = path.dirname(dir);\n if (parent === dir) throw new Error(\"rich-push-plugin: can't find @marktiderman/genesis-native's folder\");\n dir = parent;\n }\n}\n\n/** The extension's Swift source, shipped in this package. */\nexport function serviceSwiftPath(root = packageRoot()): string {\n return path.join(root, \"ios\", \"notification-service\", SWIFT_FILE);\n}\n\n/** Writes the extension's folder under ios/: the Swift, its Info.plist and its entitlements. */\nexport function writeExtensionFiles(\n iosRoot: string,\n options: { targetName: string; displayName: string; communication: boolean; imageHosts?: string[]; swiftSource?: string },\n): void {\n const dir = path.join(iosRoot, options.targetName);\n mkdirSync(dir, { recursive: true });\n copyFileSync(options.swiftSource ?? serviceSwiftPath(), path.join(dir, SWIFT_FILE));\n writeFileSync(path.join(dir, \"Info.plist\"), extensionInfoPlist(options.displayName, { communication: options.communication, imageHosts: options.imageHosts ?? [] }));\n writeFileSync(path.join(dir, `${options.targetName}.entitlements`), entitlementsPlist(extensionEntitlements(options.communication)));\n}\n\n/** The parts of the `xcode` package's project this uses. */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype XcodeProject = any;\n\nconst unquote = (v: unknown) => (typeof v === \"string\" ? v.replace(/^\"(.*)\"$/, \"$1\") : v);\n\n/** The app target's build setting (its first configuration that has it). */\nfunction appSetting(project: XcodeProject, key: string): string | undefined {\n const app = project.getFirstTarget();\n const listId = app?.firstTarget?.buildConfigurationList;\n const lists = project.pbxXCConfigurationList();\n const configs = project.pbxXCBuildConfigurationSection();\n for (const ref of lists[listId]?.buildConfigurations ?? []) {\n const value = configs[ref.value]?.buildSettings?.[key];\n if (value !== undefined) return String(unquote(value));\n }\n return undefined;\n}\n\n/**\n * Adds the extension target to the project (once): its group and files, the\n * sources, frameworks and resources phases, its build settings, a dependency\n * from the app and the app's phase that embeds it.\n */\nexport function addNotificationServiceTarget(\n project: XcodeProject,\n options: { targetName: string; bundleId: string; deploymentTarget?: string; developmentTeam?: string; marketingVersion?: string; buildNumber?: string },\n): { added: boolean } {\n const { targetName } = options;\n if (project.pbxTargetByName(targetName) || project.pbxTargetByName(`\"${targetName}\"`)) return { added: false };\n\n const objects = project.hash.project.objects;\n // The xcode package assumes these sections exist; Expo's template has none.\n objects.PBXTargetDependency ??= {};\n objects.PBXContainerItemProxy ??= {};\n\n const deploymentTarget = options.deploymentTarget ?? appSetting(project, \"IPHONEOS_DEPLOYMENT_TARGET\") ?? \"15.1\";\n const marketingVersion = options.marketingVersion ?? appSetting(project, \"MARKETING_VERSION\") ?? \"1.0\";\n const buildNumber = options.buildNumber ?? appSetting(project, \"CURRENT_PROJECT_VERSION\") ?? \"1\";\n const developmentTeam = options.developmentTeam ?? appSetting(project, \"DEVELOPMENT_TEAM\");\n\n // The Swift is compiled; the Info.plist and entitlements are build settings, so they are in the group only.\n const group = project.addPbxGroup([SWIFT_FILE], targetName, targetName);\n project.addFile(\"Info.plist\", group.uuid, { lastKnownFileType: \"text.plist.xml\" });\n project.addFile(`${targetName}.entitlements`, group.uuid, { lastKnownFileType: \"text.plist.entitlements\" });\n const mainGroup = project.getFirstProject().firstProject.mainGroup;\n project.addToPbxGroup(group.uuid, mainGroup);\n\n const target = project.addTarget(targetName, \"app_extension\", targetName, options.bundleId);\n project.addBuildPhase([SWIFT_FILE], \"PBXSourcesBuildPhase\", \"Sources\", target.uuid);\n project.addBuildPhase([], \"PBXFrameworksBuildPhase\", \"Frameworks\", target.uuid);\n project.addBuildPhase([], \"PBXResourcesBuildPhase\", \"Resources\", target.uuid);\n\n const configs = project.pbxXCBuildConfigurationSection();\n const listId = target.pbxNativeTarget.buildConfigurationList;\n for (const ref of project.pbxXCConfigurationList()[listId].buildConfigurations) {\n const settings = configs[ref.value].buildSettings;\n Object.assign(settings, {\n INFOPLIST_FILE: `${targetName}/Info.plist`,\n CODE_SIGN_ENTITLEMENTS: `${targetName}/${targetName}.entitlements`,\n CODE_SIGN_STYLE: \"Automatic\",\n IPHONEOS_DEPLOYMENT_TARGET: deploymentTarget,\n TARGETED_DEVICE_FAMILY: '\"1,2\"',\n SWIFT_VERSION: \"5.0\",\n MARKETING_VERSION: marketingVersion,\n CURRENT_PROJECT_VERSION: buildNumber,\n GENERATE_INFOPLIST_FILE: \"NO\",\n PRODUCT_BUNDLE_IDENTIFIER: `\"${options.bundleId}\"`,\n SDKROOT: \"iphoneos\",\n CLANG_ENABLE_MODULES: \"YES\",\n SWIFT_EMIT_LOC_STRINGS: \"YES\",\n ...(developmentTeam ? { DEVELOPMENT_TEAM: developmentTeam } : {}),\n });\n }\n if (developmentTeam) project.addTargetAttribute(\"DevelopmentTeam\", developmentTeam, target);\n return { added: true };\n}\n\nconst withRichPush: ConfigPlugin<RichPushPluginOptions | void> = (config, options) => {\n const o = resolve(options ?? undefined);\n config = applyRichPushConfig(config, o);\n const bundleId = extensionBundleId(config.ios!.bundleIdentifier!, o.bundleIdSuffix);\n\n config = withDangerousMod(config, [\n \"ios\",\n (c) => {\n writeExtensionFiles(c.modRequest.platformProjectRoot, { targetName: o.targetName, displayName: c.name, communication: o.communication, imageHosts: o.imageHosts });\n return c;\n },\n ]);\n config = withXcodeProject(config, (c) => {\n addNotificationServiceTarget(c.modResults, {\n targetName: o.targetName,\n bundleId,\n ...(o.deploymentTarget ? { deploymentTarget: o.deploymentTarget } : {}),\n ...(c.ios?.appleTeamId ? { developmentTeam: c.ios.appleTeamId } : {}),\n ...(c.version ? { marketingVersion: c.version } : {}),\n ...(c.ios?.buildNumber ? { buildNumber: c.ios.buildNumber } : {}),\n });\n return c;\n });\n return config;\n};\n\nexport default withRichPush;\n"]}
package/dist/updates.d.ts CHANGED
@@ -1,6 +1,13 @@
1
- export { A as ApplicationLike, C as CLOCK_SKEW_MS, b as ChannelSwitchResult, c as ChannelSwitcher, d as ChannelSwitcherOptions, E as EvaluatePolicyOptions, F as ForceUpgradeProps, e as ForceUpgradeScreen, M as MaintenanceProps, f as MaintenanceScreen, P as PolicyClientLike, g as PolicyOrigin, h as PolicyState, i as PolicyStore, j as PolicyStoreOptions, R as ReleaseNote, k as ReloadGuard, S as SupabasePolicySourceOptions, l as UpdateBanner, m as UpdateBannerProps, n as UpdateCheckState, o as UpdateCheckStatus, p as UpdateChecker, q as UpdateCheckerOptions, r as UpdatePlatform, s as UpdatePolicy, t as UpdatePolicySource, u as UpdateVerdict, v as UpdatesAppStateLike, U as UpdatesBlock, w as UpdatesErrorSource, x as UpdatesModuleLike, y as UpdatesOnError, z as UpdatesOptions, B as UpdatesProvider, D as UpdatesRoot, G as UpdatesRootProps, a as UpdatesSlots, H as UpdatesStorageLike, V as VersionSignature, I as VersionSignatureInput, W as WEEK_MS, J as WhatsNewOptions, K as WhatsNewProps, L as WhatsNewSheet, N as WhatsNewState, O as WhatsNewStore, Q as createChannelSwitcher, T as createPolicyStore, X as createReloadGuard, Y as createUpdateChecker, Z as createUpdates, _ as createWhatsNewStore, $ as evaluatePolicy, a0 as notesSince, a1 as sanitizePolicy, a2 as staticPolicySource, a3 as supabasePolicySource, a4 as useBlockReload, a5 as useCanReload, a6 as useForceUpgrade, a7 as useMaintenance, a8 as useUpdateBanner, a9 as useUpdateCheck, aa as useUpdatePolicy, ab as useUpdateVerdict, ac as useUpdates, ad as useVersionSignature, ae as useWhatsNew, af as versionSignature } from './block-Dh5ny06W.js';
1
+ export { b5 as ApplicationLike, b6 as CLOCK_SKEW_MS, b7 as ChannelSwitchResult, b8 as ChannelSwitcher, b9 as ChannelSwitcherOptions, ba as EvaluatePolicyOptions, bb as ForceUpgradeProps, bc as ForceUpgradeScreen, bd as MaintenanceProps, be as MaintenanceScreen, bf as PolicyClientLike, bg as PolicyOrigin, bh as PolicyState, bi as PolicyStore, bj as PolicyStoreOptions, bk as ReleaseNote, bl as ReloadGuard, bm as SupabasePolicySourceOptions, bn as UPDATES_BLOCK_ID, bo as UpdateBanner, bp as UpdateBannerProps, bq as UpdateCheckState, br as UpdateCheckStatus, bs as UpdateChecker, bt as UpdateCheckerOptions, bu as UpdatePlatform, bv as UpdatePolicy, bw as UpdatePolicySource, bx as UpdateVerdict, by as UpdatesAppStateLike, U as UpdatesBlock, bz as UpdatesErrorSource, bA as UpdatesModuleLike, bB as UpdatesOnError, bC as UpdatesOptions, bD as UpdatesProvider, bE as UpdatesRoot, bF as UpdatesRootProps, bG as UpdatesSlots, bH as UpdatesStorageLike, V as VersionSignature, bI as VersionSignatureInput, bJ as WEEK_MS, bK as WhatsNewOptions, bL as WhatsNewProps, bM as WhatsNewSheet, bN as WhatsNewState, bO as WhatsNewStore, bP as createChannelSwitcher, bQ as createPolicyStore, bR as createReloadGuard, bS as createUpdateChecker, bT as createUpdates, bU as createWhatsNewStore, bV as evaluatePolicy, bW as notesSince, bX as sanitizePolicy, bY as staticPolicySource, bZ as supabasePolicySource, b_ as useBlockReload, b$ as useCanReload, c0 as useForceUpgrade, c1 as useMaintenance, c2 as useUpdateBanner, c3 as useUpdateCheck, c4 as useUpdatePolicy, c5 as useUpdateVerdict, c6 as useUpdates, c7 as useVersionSignature, c8 as useWhatsNew, c9 as versionSignature } from './blocks-C2RDpvaN.js';
2
2
  import 'react';
3
3
  import '@marktiderman/genesis-core/slots';
4
+ import '@marktiderman/genesis-features/blocks';
5
+ import '@tanstack/react-query';
6
+ import '@marktiderman/genesis-design-system';
7
+ import '@marktiderman/genesis-core/provider';
8
+ import '@marktiderman/genesis-ui-native/layouts';
9
+ import '@marktiderman/genesis-ui-native/components';
10
+ import './query-DUmVAfsF.js';
4
11
 
5
12
  /**
6
13
  * Version numbers: the store version an app reports (`1.4.0`, `1.10`) and
package/dist/updates.js CHANGED
@@ -1,38 +1,14 @@
1
+ import { createStore, delay } from './chunk-XE7LC7K6.js';
2
+ import { versionSignature } from './chunk-6BT4PTGH.js';
3
+ export { versionSignature } from './chunk-6BT4PTGH.js';
1
4
  import { createContext, useContext, useEffect, useSyncExternalStore, useMemo, useState } from 'react';
2
5
  import { View } from 'react-native';
3
6
  import { renderSlot } from '@marktiderman/genesis-core/slots';
7
+ import { defineBlock } from '@marktiderman/genesis-features/blocks';
4
8
  import { SafeAreaView } from 'react-native-safe-area-context';
5
- import { NativeEmptyState, NativeButton, NativeBanner, NativeSheet, NativeText } from '@marktiderman/genesis-ui-native/components';
9
+ import { NativeEmptyState, NativeButton, useLiquidGlass, NativeGlassSurface, NativeBanner, NativeSheet, NativeSheetScrollView, NativeText } from '@marktiderman/genesis-ui-native/components';
6
10
  import { jsx, jsxs } from 'react/jsx-runtime';
7
11
 
8
- // src/updates/block.tsx
9
-
10
- // src/updates/store.ts
11
- function createStore(initial) {
12
- let state = initial;
13
- const listeners = /* @__PURE__ */ new Set();
14
- return {
15
- getState: () => state,
16
- setState(next) {
17
- const merged = { ...state, ...next };
18
- if (Object.keys(merged).every((key) => Object.is(merged[key], state[key]))) return;
19
- state = merged;
20
- for (const listener of [...listeners]) listener();
21
- },
22
- subscribe(listener) {
23
- listeners.add(listener);
24
- return () => {
25
- listeners.delete(listener);
26
- };
27
- }
28
- };
29
- }
30
- function delay(ms) {
31
- return new Promise((resolve) => {
32
- if (Number.isFinite(ms)) setTimeout(resolve, Math.max(0, ms));
33
- });
34
- }
35
-
36
12
  // src/updates/modules.ts
37
13
  function toError(value) {
38
14
  return value instanceof Error ? value : new Error(typeof value === "string" ? value : "Unknown error");
@@ -444,39 +420,6 @@ function evaluatePolicy(state, options) {
444
420
  return { kind: "ok" };
445
421
  }
446
422
 
447
- // src/updates/signature.ts
448
- var UNKNOWN = "unknown";
449
- function versionSignature({ application, updates, platform, requestedChannel = null }) {
450
- const version = application?.nativeApplicationVersion ?? null;
451
- const build = application?.nativeBuildVersion ?? null;
452
- const on = Boolean(updates?.isEnabled);
453
- const channel = on ? updates?.channel ?? null : null;
454
- const updateId = on ? updates?.updateId ?? null : null;
455
- const runtimeVersion = updates?.runtimeVersion ?? null;
456
- const launch = !on ? "off" : updates?.isEmbeddedLaunch ? "embedded" : "update";
457
- const emergency = on && updates?.isEmergencyLaunch === true;
458
- const shownChannel = requestedChannel ?? channel;
459
- const head = `${version ?? UNKNOWN} (${build ?? UNKNOWN})`;
460
- const parts = [head];
461
- if (launch === "off") {
462
- parts.push("updates off");
463
- } else {
464
- parts.push(shownChannel ?? "no channel");
465
- parts.push(launch === "embedded" ? "embedded" : updateId?.slice(0, 8) ?? UNKNOWN);
466
- }
467
- if (emergency) parts.push("emergency launch");
468
- const short = parts.join(" \xB7 ");
469
- const lines = [
470
- `Version ${head}`,
471
- `Platform ${platform}`,
472
- `Channel ${channel ?? (on ? UNKNOWN : "none")}${requestedChannel && requestedChannel !== channel ? ` (switched to ${requestedChannel})` : ""}`,
473
- `Runtime ${runtimeVersion ?? UNKNOWN}`,
474
- `Update ${launch === "off" ? "updates off" : launch === "embedded" ? "embedded" : updateId ?? UNKNOWN}`
475
- ];
476
- if (emergency) lines.push(`Emergency launch: ${updates?.emergencyLaunchReason ?? UNKNOWN}`);
477
- return { version, build, platform, channel, requestedChannel, runtimeVersion, updateId, launch, emergency, short, text: lines.join("\n") };
478
- }
479
-
480
423
  // src/updates/whats-new.ts
481
424
  function notesSince(notes, seen, version) {
482
425
  return notes.filter((note) => {
@@ -574,14 +517,15 @@ function MaintenanceScreen({ message, retry, retrying }) {
574
517
  ) });
575
518
  }
576
519
  function UpdateBanner({ reload, dismiss, canReload, blocked, reloading }) {
577
- return /* @__PURE__ */ jsx(SafeAreaView, { edges: ["top"], pointerEvents: "box-none", style: { position: "absolute", top: 0, left: 0, right: 0 }, children: /* @__PURE__ */ jsxs(View, { testID: "genesis-update-banner", className: "mx-3 mt-2 overflow-hidden rounded-lg border border-border bg-secondary", children: [
520
+ const onGlass = useLiquidGlass() !== null;
521
+ return /* @__PURE__ */ jsx(SafeAreaView, { edges: ["top"], pointerEvents: "box-none", style: { position: "absolute", top: 0, left: 0, right: 0 }, children: /* @__PURE__ */ jsx(View, { className: "mx-3 mt-2", children: /* @__PURE__ */ jsxs(NativeGlassSurface, { testID: "genesis-update-banner", fallbackClassName: "overflow-hidden rounded-lg border border-border bg-secondary", children: [
578
522
  /* @__PURE__ */ jsx(
579
523
  NativeBanner,
580
524
  {
581
525
  variant: "info",
582
526
  title: "An update is ready",
583
527
  description: blocked || !canReload ? "Finish what you're doing, then restart to use it." : "Restart to use the latest version.",
584
- className: "border-b-0",
528
+ className: onGlass ? "border-b-0 border-transparent bg-transparent" : "border-b-0",
585
529
  testID: "genesis-update-banner-message"
586
530
  }
587
531
  ),
@@ -589,10 +533,10 @@ function UpdateBanner({ reload, dismiss, canReload, blocked, reloading }) {
589
533
  /* @__PURE__ */ jsx(NativeButton, { variant: "ghost", size: "sm", onPress: dismiss, testID: "genesis-update-banner-later", children: "Later" }),
590
534
  /* @__PURE__ */ jsx(NativeButton, { size: "sm", onPress: reload, disabled: !canReload, loading: reloading, testID: "genesis-update-banner-restart", children: "Restart" })
591
535
  ] })
592
- ] }) });
536
+ ] }) }) });
593
537
  }
594
538
  function WhatsNewSheet({ notes, dismiss }) {
595
- return /* @__PURE__ */ jsx(NativeSheet, { open: true, onOpenChange: (open) => open ? void 0 : dismiss(), testID: "genesis-whats-new", children: /* @__PURE__ */ jsxs(View, { className: "gap-4 p-6", children: [
539
+ return /* @__PURE__ */ jsx(NativeSheet, { open: true, onOpenChange: (open) => open ? void 0 : dismiss(), testID: "genesis-whats-new", children: /* @__PURE__ */ jsxs(NativeSheetScrollView, { contentContainerClassName: "gap-4 p-6", children: [
596
540
  /* @__PURE__ */ jsx(NativeText, { preset: "h3", accessibilityRole: "header", children: "What's new" }),
597
541
  notes.map((note) => /* @__PURE__ */ jsxs(View, { className: "gap-1", testID: `genesis-whats-new-${note.version}`, children: [
598
542
  /* @__PURE__ */ jsx(NativeText, { preset: "label", children: note.title ?? `Version ${note.version}` }),
@@ -601,6 +545,7 @@ function WhatsNewSheet({ notes, dismiss }) {
601
545
  /* @__PURE__ */ jsx(NativeButton, { onPress: dismiss, testID: "genesis-whats-new-done", children: "Got it" })
602
546
  ] }) });
603
547
  }
548
+ var UPDATES_BLOCK_ID = "app-updates";
604
549
  function createUpdates(options) {
605
550
  const {
606
551
  platform,
@@ -661,7 +606,34 @@ function createUpdates(options) {
661
606
  });
662
607
  return loaded;
663
608
  };
609
+ const bootStep = { id: "genesis:updates", run: load, timeoutMs: policyTimeoutMs + 5e3 };
610
+ const { versionRow } = options;
611
+ const declaration = defineBlock({
612
+ id: UPDATES_BLOCK_ID,
613
+ platforms: ["native"],
614
+ contributes: {
615
+ settings: versionRow === false ? [] : [
616
+ {
617
+ id: "app-version",
618
+ section: versionRow?.section ?? "about",
619
+ title: versionRow?.title ?? "Version",
620
+ testID: "genesis-app-version",
621
+ // Bound to this block, so it needs no provider above the Settings screen.
622
+ useSubtitle: () => useVersionSignatureOf(block).short
623
+ }
624
+ ],
625
+ migrations: [
626
+ {
627
+ package: "@marktiderman/genesis-supabase",
628
+ file: "migrations/0002_genesis_app_release_policy.sql",
629
+ test: "migrations/tests/0002_genesis_app_release_policy.test.sql"
630
+ }
631
+ ],
632
+ privacy: { notes: ["Reads the installed version and update ids on the device to decide on a force upgrade; sends nothing about the person."] }
633
+ }
634
+ });
664
635
  const block = {
636
+ ...declaration,
665
637
  options,
666
638
  policy,
667
639
  checker,
@@ -669,7 +641,8 @@ function createUpdates(options) {
669
641
  whatsNew,
670
642
  channels: switcher,
671
643
  signature,
672
- bootStep: { id: "genesis:updates", run: load, timeoutMs: policyTimeoutMs + 5e3 },
644
+ bootStep,
645
+ bootSteps: [bootStep],
673
646
  start() {
674
647
  void load();
675
648
  void checker.check();
@@ -765,7 +738,9 @@ function useWhatsNew() {
765
738
  return { notes: state.notes, version: block.options.application?.nativeApplicationVersion ?? null, dismiss: () => block.whatsNew.dismiss() };
766
739
  }
767
740
  function useVersionSignature() {
768
- const block = useUpdates();
741
+ return useVersionSignatureOf(useUpdates());
742
+ }
743
+ function useVersionSignatureOf(block) {
769
744
  const [requested, setRequested] = useState(null);
770
745
  useEffect(() => {
771
746
  let alive = true;
@@ -808,6 +783,6 @@ function UpdatesParts({ slots, slotProps, children }) {
808
783
  ] });
809
784
  }
810
785
 
811
- export { CLOCK_SKEW_MS, ForceUpgradeScreen, MaintenanceScreen, UpdateBanner, UpdatesProvider, UpdatesRoot, WEEK_MS, WhatsNewSheet, compareVersions, createChannelSwitcher, createPolicyStore, createReloadGuard, createUpdateChecker, createUpdates, createWhatsNewStore, evaluatePolicy, isBelowMinimum, notesSince, parseVersion, sanitizePolicy, staticPolicySource, supabasePolicySource, useBlockReload, useCanReload, useForceUpgrade, useMaintenance, useUpdateBanner, useUpdateCheck, useUpdatePolicy, useUpdateVerdict, useUpdates, useVersionSignature, useWhatsNew, versionSignature };
786
+ export { CLOCK_SKEW_MS, ForceUpgradeScreen, MaintenanceScreen, UPDATES_BLOCK_ID, UpdateBanner, UpdatesProvider, UpdatesRoot, WEEK_MS, WhatsNewSheet, compareVersions, createChannelSwitcher, createPolicyStore, createReloadGuard, createUpdateChecker, createUpdates, createWhatsNewStore, evaluatePolicy, isBelowMinimum, notesSince, parseVersion, sanitizePolicy, staticPolicySource, supabasePolicySource, useBlockReload, useCanReload, useForceUpgrade, useMaintenance, useUpdateBanner, useUpdateCheck, useUpdatePolicy, useUpdateVerdict, useUpdates, useVersionSignature, useWhatsNew };
812
787
  //# sourceMappingURL=updates.js.map
813
788
  //# sourceMappingURL=updates.js.map