@absolutejs/absolute 0.20.0-beta.23 → 0.20.0-beta.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/angular/components/core/streamingSlotRegistrar.js +1 -1
- package/dist/angular/components/core/streamingSlotRegistry.js +2 -2
- package/dist/cli/index.js +138 -13
- package/dist/index.js +3 -2
- package/dist/index.js.map +3 -3
- package/dist/mobile/index.js +134 -11
- package/dist/mobile/index.js.map +7 -7
- package/dist/mobile/remoteMacAgentEntry.js +10 -10
- package/dist/mobile/shellAuth.js +2 -1
- package/dist/mobile/shellBootstrap.js +5 -1
- package/dist/src/mobile/config.d.ts +1 -0
- package/dist/src/mobile/deviceCapabilities.d.ts +2 -0
- package/dist/src/mobile/shellAuth.d.ts +3 -1
- package/dist/src/mobile/shellBootstrap.d.ts +5 -1
- package/dist/src/mobile/shellPush.d.ts +11 -0
- package/dist/types/build.d.ts +7 -0
- package/package.json +7 -4
package/dist/mobile/index.js
CHANGED
|
@@ -3680,7 +3680,8 @@ var normalizeAbsoluteMobileConfig = (config, projectRoot) => {
|
|
|
3680
3680
|
iosVersion: normalizeIosVersion(config.ios?.version),
|
|
3681
3681
|
nativeProjectDirectory: resolveProjectPath(projectRoot, config.nativeProject?.directory ?? "mobile", "mobile.nativeProject.directory"),
|
|
3682
3682
|
platforms: normalizePlatforms(config.platforms),
|
|
3683
|
-
productionOrigin
|
|
3683
|
+
productionOrigin,
|
|
3684
|
+
pushAndroidGoogleServicesFile: resolveProjectPath(projectRoot, config.pushNotifications?.android?.googleServicesFile ?? "google-services.json", "mobile.pushNotifications.android.googleServicesFile")
|
|
3684
3685
|
};
|
|
3685
3686
|
};
|
|
3686
3687
|
|
|
@@ -4575,6 +4576,12 @@ var shellSyncModule = () => {
|
|
|
4575
4576
|
return candidate;
|
|
4576
4577
|
throw new TypeError("AbsoluteJS mobile Sync shell module is missing.");
|
|
4577
4578
|
};
|
|
4579
|
+
var shellPushModule = () => {
|
|
4580
|
+
const candidate = ["js", "ts"].map((extension) => join9(import.meta.dir, `shellPush.${extension}`)).find(existsSync2);
|
|
4581
|
+
if (candidate)
|
|
4582
|
+
return candidate;
|
|
4583
|
+
throw new TypeError("AbsoluteJS mobile push shell module is missing.");
|
|
4584
|
+
};
|
|
4578
4585
|
var escapeHtml = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """);
|
|
4579
4586
|
var indexHtml = (appName) => `<!doctype html>
|
|
4580
4587
|
<html>
|
|
@@ -4627,6 +4634,10 @@ var buildShellBootstrap = async (staging, auth, sync, storagePrefix, deviceCapab
|
|
|
4627
4634
|
` : "";
|
|
4628
4635
|
const options = auth ? `{ createAuth: createAbsoluteMobileShellAuth${sync ? ", installSync: installAbsoluteMobileShellSync" : ""} }` : "";
|
|
4629
4636
|
const syncImport = sync ? `import { installAbsoluteMobileShellSync } from ${JSON.stringify(shellSyncModule())};
|
|
4637
|
+
` : "";
|
|
4638
|
+
const pushIndex = deviceCapabilities.capabilities.indexOf("pushNotifications");
|
|
4639
|
+
const push = pushIndex !== -1;
|
|
4640
|
+
const pushImport = push ? `import { createAbsoluteMobileShellPush } from ${JSON.stringify(shellPushModule())};
|
|
4630
4641
|
` : "";
|
|
4631
4642
|
const capabilityImports = (await Promise.all(deviceCapabilities.capabilities.map(async (name, index) => {
|
|
4632
4643
|
const provider = deviceCapabilities.providers[name];
|
|
@@ -4635,14 +4646,17 @@ var buildShellBootstrap = async (staging, auth, sync, storagePrefix, deviceCapab
|
|
|
4635
4646
|
return `import { ${provider.factory} as absoluteDeviceCapability${index} } from ${JSON.stringify(await resolveProjectImport(projectRoot, provider.module))};`;
|
|
4636
4647
|
}))).join(`
|
|
4637
4648
|
`);
|
|
4638
|
-
const
|
|
4649
|
+
const pushSetup = push ? `const absoluteMobilePush = createAbsoluteMobileShellPush();
|
|
4650
|
+
const absoluteMobilePushCapability = absoluteDeviceCapability${pushIndex}(absoluteMobilePush.capabilityOptions);
|
|
4651
|
+
` : "";
|
|
4652
|
+
const capabilityOptions = deviceCapabilities.capabilities.map((name, index) => `${JSON.stringify(name)}: ${name === "pushNotifications" ? "absoluteMobilePushCapability" : `absoluteDeviceCapability${index}()`}`).join(", ");
|
|
4639
4653
|
const entryPath = join9(staging, ".absolute-mobile-entry.ts");
|
|
4640
4654
|
const baseAdapterModule = await resolveProjectImport(projectRoot, "@absolutejs/devices-capacitor");
|
|
4641
4655
|
await writeFile10(entryPath, `import { startAbsoluteMobileShell } from ${JSON.stringify(modulePath)};
|
|
4642
4656
|
import { installCapacitorDeviceAdapterIfNative } from ${JSON.stringify(baseAdapterModule)};
|
|
4643
|
-
${authImport}${syncImport}${capabilityImports}
|
|
4644
|
-
installCapacitorDeviceAdapterIfNative({ storagePrefix: ${JSON.stringify(storagePrefix)}${capabilityOptions ? `, ${capabilityOptions}` : ""} });
|
|
4645
|
-
void startAbsoluteMobileShell(${options});
|
|
4657
|
+
${authImport}${syncImport}${pushImport}${capabilityImports}
|
|
4658
|
+
${pushSetup}installCapacitorDeviceAdapterIfNative({ storagePrefix: ${JSON.stringify(storagePrefix)}${capabilityOptions ? `, ${capabilityOptions}` : ""} });
|
|
4659
|
+
void startAbsoluteMobileShell(${push ? `{ createAuth: (config, options) => createAbsoluteMobileShellAuth(config, options), beforeSignOut: absoluteMobilePush.beforeSignOut, connectPush: (auth) => absoluteMobilePush.connect(auth, absoluteMobilePushCapability)${sync ? ", installSync: installAbsoluteMobileShellSync" : ""} }` : options});
|
|
4646
4660
|
`);
|
|
4647
4661
|
const build = await Bun.build({
|
|
4648
4662
|
entrypoints: [entryPath],
|
|
@@ -5129,12 +5143,15 @@ var iosNativeRequirements = (value, field) => {
|
|
|
5129
5143
|
return;
|
|
5130
5144
|
if (!object2(value))
|
|
5131
5145
|
throw new TypeError(`${field} must be an object.`);
|
|
5132
|
-
const { privacyAccessedApis, usageDescriptions } = value;
|
|
5146
|
+
const { privacyAccessedApis, pushNotifications, usageDescriptions } = value;
|
|
5147
|
+
if (pushNotifications !== undefined && pushNotifications !== true)
|
|
5148
|
+
throw new TypeError(`${field}.pushNotifications must be true.`);
|
|
5133
5149
|
if (usageDescriptions !== undefined && (!Array.isArray(usageDescriptions) || !usageDescriptions.every((purpose) => typeof purpose === "string" && IOS_USAGE_DESCRIPTIONS.has(purpose))))
|
|
5134
5150
|
throw new TypeError(`${field}.usageDescriptions contains an unsupported purpose.`);
|
|
5135
5151
|
const privacy = iosPrivacyAccessedApis(privacyAccessedApis, `${field}.privacyAccessedApis`);
|
|
5136
5152
|
return {
|
|
5137
5153
|
...privacy === undefined ? {} : { privacyAccessedApis: privacy },
|
|
5154
|
+
...pushNotifications === true ? { pushNotifications: true } : {},
|
|
5138
5155
|
...usageDescriptions === undefined ? {} : { usageDescriptions: [...usageDescriptions] }
|
|
5139
5156
|
};
|
|
5140
5157
|
};
|
|
@@ -5192,6 +5209,7 @@ var absoluteDeviceNativeRequirements = (plan) => {
|
|
|
5192
5209
|
const reasons = privacy[api];
|
|
5193
5210
|
return reasons ? [{ api, reasons: [...reasons].sort() }] : [];
|
|
5194
5211
|
}),
|
|
5212
|
+
iosPushNotifications: plan.capabilities.some((name) => plan.providers[name]?.native?.ios?.pushNotifications === true),
|
|
5195
5213
|
iosUsageDescriptions: [
|
|
5196
5214
|
...new Set(plan.capabilities.flatMap((name) => plan.providers[name]?.native?.ios?.usageDescriptions ?? []))
|
|
5197
5215
|
].sort()
|
|
@@ -5380,6 +5398,11 @@ var finalizeAbsoluteMobileCompatibilityBuild = async (options) => {
|
|
|
5380
5398
|
const sync = auth !== undefined && projectUsesAbsoluteSync(options.projectRoot);
|
|
5381
5399
|
const syncSchema = sync ? discoverAbsoluteSyncSchema(options.projectRoot) : undefined;
|
|
5382
5400
|
const deviceCapabilities = resolveAbsoluteDeviceCapabilityPlan(options.projectRoot);
|
|
5401
|
+
const usesPush = deviceCapabilities.capabilities.includes("pushNotifications");
|
|
5402
|
+
if (usesPush && !auth)
|
|
5403
|
+
throw new TypeError("Portable push notifications require @absolutejs/auth so provider tokens can be registered without exposing identity controls to page code.");
|
|
5404
|
+
if (usesPush && !loaded.app.routes.some((route) => route.path === "/auth/mobile/push"))
|
|
5405
|
+
throw new TypeError("@absolutejs/devices pushNotifications is used, but Auth nativePush is not configured. Pass a server-side registrar to auth({ nativePush: ... }).");
|
|
5383
5406
|
assertAbsoluteDeviceCapabilityPackages(options.projectRoot, deviceCapabilities);
|
|
5384
5407
|
if (auth && !loaded.app.routes.some((route) => route.path === "/.well-known/openid-configuration")) {
|
|
5385
5408
|
throw new TypeError("@absolutejs/auth is installed, but its OIDC provider is not mounted. Native authentication requires the auth oidc configuration so AbsoluteJS can provision a public PKCE client.");
|
|
@@ -5829,6 +5852,8 @@ var END_MARKER2 = "<!-- absolutejs:device-capabilities:end -->";
|
|
|
5829
5852
|
var NOT_FOUND2 = -1;
|
|
5830
5853
|
var IOS_PRIVACY_FILE_REFERENCE = "A85D0C000000000000000001";
|
|
5831
5854
|
var IOS_PRIVACY_BUILD_FILE = "A85D0C000000000000000002";
|
|
5855
|
+
var PUSH_START_MARKER = "absolutejs:push-notifications:start";
|
|
5856
|
+
var PUSH_END_MARKER = "absolutejs:push-notifications:end";
|
|
5832
5857
|
var escapeXml2 = (value) => value.replaceAll("&", "&").replaceAll('"', """).replaceAll("'", "'").replaceAll("<", "<").replaceAll(">", ">");
|
|
5833
5858
|
var writeChangedFile2 = async (path, source) => {
|
|
5834
5859
|
const current = await readFile15(path, "utf8");
|
|
@@ -5839,6 +5864,16 @@ var writeChangedFile2 = async (path, source) => {
|
|
|
5839
5864
|
await rename12(temporary, path);
|
|
5840
5865
|
return true;
|
|
5841
5866
|
};
|
|
5867
|
+
var writeOptionalChangedFile = async (path, source) => {
|
|
5868
|
+
const current = await optionalSource(path);
|
|
5869
|
+
if (current === source)
|
|
5870
|
+
return false;
|
|
5871
|
+
if (current === null) {
|
|
5872
|
+
await writeFile13(path, source, { flag: "wx" });
|
|
5873
|
+
return true;
|
|
5874
|
+
}
|
|
5875
|
+
return writeChangedFile2(path, source);
|
|
5876
|
+
};
|
|
5842
5877
|
var optionalSource = async (path) => {
|
|
5843
5878
|
try {
|
|
5844
5879
|
return await readFile15(path, "utf8");
|
|
@@ -6028,11 +6063,73 @@ ${content}
|
|
|
6028
6063
|
const privacyPath = join16(config.nativeProjectDirectory, "ios/App/App/PrivacyInfo.xcprivacy");
|
|
6029
6064
|
const privacyCurrent = await optionalSource(privacyPath);
|
|
6030
6065
|
const privacySource = privacyManifestSource(privacyCurrent, requirements);
|
|
6031
|
-
const [privacyChanged, projectChanged] = await Promise.all([
|
|
6066
|
+
const [privacyChanged, projectChanged, pushChanged] = await Promise.all([
|
|
6032
6067
|
writeIosPrivacyManifest(privacyPath, privacyCurrent, privacySource),
|
|
6033
|
-
configureIosPrivacyProject(config, requirements)
|
|
6068
|
+
configureIosPrivacyProject(config, requirements),
|
|
6069
|
+
configureIosPushNotifications(config, requirements.iosPushNotifications)
|
|
6034
6070
|
]);
|
|
6035
|
-
return infoChanged || privacyChanged || projectChanged;
|
|
6071
|
+
return infoChanged || privacyChanged || projectChanged || pushChanged;
|
|
6072
|
+
};
|
|
6073
|
+
var configureIosPushNotifications = async (config, enabled) => {
|
|
6074
|
+
const entitlementsPath = join16(config.nativeProjectDirectory, "ios/App/AbsoluteJS.entitlements");
|
|
6075
|
+
const entitlements = await optionalSource(entitlementsPath);
|
|
6076
|
+
if (entitlements === null && !enabled)
|
|
6077
|
+
return false;
|
|
6078
|
+
if (entitlements === null)
|
|
6079
|
+
throw new TypeError("AbsoluteJS iOS entitlements are missing. Run native deep-link projection before device capabilities.");
|
|
6080
|
+
const entitlementRegion = enabled ? ` <!-- ${PUSH_START_MARKER} -->
|
|
6081
|
+
<key>aps-environment</key>
|
|
6082
|
+
<string>development</string>
|
|
6083
|
+
<!-- ${PUSH_END_MARKER} -->
|
|
6084
|
+
` : "";
|
|
6085
|
+
const nextEntitlements = replacePushRegion(entitlements, entitlementRegion, entitlements.lastIndexOf("</dict>"));
|
|
6086
|
+
const delegatePath = join16(config.nativeProjectDirectory, "ios/App/App/AppDelegate.swift");
|
|
6087
|
+
const delegate = await optionalSource(delegatePath);
|
|
6088
|
+
if (delegate === null && !enabled)
|
|
6089
|
+
return false;
|
|
6090
|
+
if (delegate === null)
|
|
6091
|
+
throw new TypeError("Capacitor AppDelegate.swift is missing for iOS push notifications.");
|
|
6092
|
+
const hasSuccess = delegate.includes("didRegisterForRemoteNotificationsWithDeviceToken");
|
|
6093
|
+
const hasFailure = delegate.includes("didFailToRegisterForRemoteNotificationsWithError");
|
|
6094
|
+
if (enabled && hasSuccess !== hasFailure && !delegate.includes(PUSH_START_MARKER))
|
|
6095
|
+
throw new TypeError("iOS AppDelegate has a partial custom remote-notification registration implementation.");
|
|
6096
|
+
const alreadyForwarded = enabled && hasSuccess && hasFailure && delegate.includes("capacitorDidRegisterForRemoteNotifications") && delegate.includes("capacitorDidFailToRegisterForRemoteNotifications");
|
|
6097
|
+
const swiftRegion = enabled && !alreadyForwarded ? `
|
|
6098
|
+
// ${PUSH_START_MARKER}
|
|
6099
|
+
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
|
|
6100
|
+
NotificationCenter.default.post(name: .capacitorDidRegisterForRemoteNotifications, object: deviceToken)
|
|
6101
|
+
}
|
|
6102
|
+
|
|
6103
|
+
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
|
|
6104
|
+
NotificationCenter.default.post(name: .capacitorDidFailToRegisterForRemoteNotifications, object: error)
|
|
6105
|
+
}
|
|
6106
|
+
// ${PUSH_END_MARKER}
|
|
6107
|
+
` : "";
|
|
6108
|
+
const nextDelegate = alreadyForwarded ? delegate : replacePushRegion(delegate, swiftRegion, delegate.lastIndexOf("}"));
|
|
6109
|
+
const changed = await Promise.all([
|
|
6110
|
+
writeChangedFile2(entitlementsPath, nextEntitlements),
|
|
6111
|
+
writeChangedFile2(delegatePath, nextDelegate)
|
|
6112
|
+
]);
|
|
6113
|
+
return changed.some(Boolean);
|
|
6114
|
+
};
|
|
6115
|
+
var replacePushRegion = (source, region, insertion) => {
|
|
6116
|
+
const start = source.indexOf(PUSH_START_MARKER);
|
|
6117
|
+
const end = source.indexOf(PUSH_END_MARKER);
|
|
6118
|
+
if (start < 0 !== end < 0 || start >= 0 && end < start)
|
|
6119
|
+
throw new TypeError("AbsoluteJS push-notification ownership markers are malformed.");
|
|
6120
|
+
if (start >= 0) {
|
|
6121
|
+
const lineStart = source.lastIndexOf(`
|
|
6122
|
+
`, start) + 1;
|
|
6123
|
+
const nextLine = source.indexOf(`
|
|
6124
|
+
`, end + PUSH_END_MARKER.length);
|
|
6125
|
+
const lineEnd = nextLine < 0 ? source.length : nextLine + 1;
|
|
6126
|
+
return `${source.slice(0, lineStart)}${region}${source.slice(lineEnd)}`;
|
|
6127
|
+
}
|
|
6128
|
+
if (!region)
|
|
6129
|
+
return source;
|
|
6130
|
+
if (insertion < 0)
|
|
6131
|
+
throw new TypeError("Could not find a safe native project location for push notifications.");
|
|
6132
|
+
return `${source.slice(0, insertion)}${region}${source.slice(insertion)}`;
|
|
6036
6133
|
};
|
|
6037
6134
|
var configureAndroid2 = async (config, plan) => {
|
|
6038
6135
|
const path = join16(config.nativeProjectDirectory, "android/app/src/main/AndroidManifest.xml");
|
|
@@ -6047,7 +6144,33 @@ ${content}
|
|
|
6047
6144
|
const application = source.indexOf("<application");
|
|
6048
6145
|
const insertion = application === NOT_FOUND2 ? NOT_FOUND2 : source.lastIndexOf(`
|
|
6049
6146
|
`, application) + 1;
|
|
6050
|
-
|
|
6147
|
+
const nextManifest = managed(source, region, insertion);
|
|
6148
|
+
if (!plan.capabilities.includes("pushNotifications"))
|
|
6149
|
+
return writeChangedFile2(path, nextManifest);
|
|
6150
|
+
const firebaseSource = await optionalSource(config.pushAndroidGoogleServicesFile);
|
|
6151
|
+
if (firebaseSource === null)
|
|
6152
|
+
throw new TypeError(`Push notifications require Firebase config at ${config.pushAndroidGoogleServicesFile}. Set mobile.pushNotifications.android.googleServicesFile to override it.`);
|
|
6153
|
+
let firebase;
|
|
6154
|
+
try {
|
|
6155
|
+
firebase = JSON.parse(firebaseSource);
|
|
6156
|
+
} catch (error) {
|
|
6157
|
+
throw new TypeError("Android google-services.json is invalid JSON.", {
|
|
6158
|
+
cause: error
|
|
6159
|
+
});
|
|
6160
|
+
}
|
|
6161
|
+
const clients = typeof firebase === "object" && firebase !== null ? Reflect.get(firebase, "client") : undefined;
|
|
6162
|
+
const matchesApp = Array.isArray(clients) && clients.some((client) => {
|
|
6163
|
+
const info = typeof client === "object" && client !== null ? Reflect.get(client, "client_info") : undefined;
|
|
6164
|
+
const android = typeof info === "object" && info !== null ? Reflect.get(info, "android_client_info") : undefined;
|
|
6165
|
+
return typeof android === "object" && android !== null && Reflect.get(android, "package_name") === config.appId;
|
|
6166
|
+
});
|
|
6167
|
+
if (!matchesApp)
|
|
6168
|
+
throw new TypeError(`Android google-services.json does not contain package ${config.appId}.`);
|
|
6169
|
+
const [manifestChanged, firebaseChanged] = await Promise.all([
|
|
6170
|
+
writeChangedFile2(path, nextManifest),
|
|
6171
|
+
writeOptionalChangedFile(join16(config.nativeProjectDirectory, "android/app/google-services.json"), firebaseSource)
|
|
6172
|
+
]);
|
|
6173
|
+
return manifestChanged || firebaseChanged;
|
|
6051
6174
|
};
|
|
6052
6175
|
var applyAbsoluteNativeDeviceCapabilities = async (projectRoot, config, platforms = config.platforms, plan = resolveAbsoluteDeviceCapabilityPlan(projectRoot)) => {
|
|
6053
6176
|
const results = await Promise.all(platforms.map(async (platform) => ({
|
|
@@ -6808,5 +6931,5 @@ export {
|
|
|
6808
6931
|
ABSOLUTE_ANDROID_RELEASE_FORMAT
|
|
6809
6932
|
};
|
|
6810
6933
|
|
|
6811
|
-
//# debugId=
|
|
6934
|
+
//# debugId=896911BF5E0E827564756E2164756E21
|
|
6812
6935
|
//# sourceMappingURL=index.js.map
|