@absolutejs/absolute 0.20.0-beta.59 → 0.20.0-beta.60

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/index.js CHANGED
@@ -9049,7 +9049,8 @@ var init_loadConfig = __esm(() => {
9049
9049
 
9050
9050
  // src/mobile/config.ts
9051
9051
  import { resolve as resolve11 } from "path";
9052
- var APP_ID_PATTERN, SCHEME_PATTERN, APPLE_APP_ID_PREFIX_PATTERN, CERTIFICATE_FINGERPRINT_PATTERN, HOSTNAME_PATTERN, EXPO_RESERVED_ROUTE_PREFIXES, resolveProjectPath = (projectRoot, value, field) => {
9052
+ import { createPublicKey } from "crypto";
9053
+ var APP_ID_PATTERN, SCHEME_PATTERN, APPLE_APP_ID_PREFIX_PATTERN, CERTIFICATE_FINGERPRINT_PATTERN, UPDATE_NAME_PATTERN, UPDATE_PUBLIC_KEY_PATTERN, HOSTNAME_PATTERN, EXPO_RESERVED_ROUTE_PREFIXES, resolveProjectPath = (projectRoot, value, field) => {
9053
9054
  const root = resolve11(projectRoot);
9054
9055
  const path = resolve11(root, value);
9055
9056
  if (path !== root && !path.startsWith(`${root}/`)) {
@@ -9122,7 +9123,52 @@ var APP_ID_PATTERN, SCHEME_PATTERN, APPLE_APP_ID_PREFIX_PATTERN, CERTIFICATE_FIN
9122
9123
  }
9123
9124
  return value.match(/.{2}/g)?.join(":") ?? value;
9124
9125
  }))
9125
- ].sort(), validateExpoNativeRouteSegment = (path, segment, index, count, parameters) => {
9126
+ ].sort(), normalizeUpdates = (config, productionOrigin) => {
9127
+ if (!config.updates)
9128
+ return;
9129
+ const channel = requireText(config.updates.channel ?? "production", "mobile.updates.channel");
9130
+ if (!UPDATE_NAME_PATTERN.test(channel))
9131
+ throw new TypeError("mobile.updates.channel contains unsupported characters.");
9132
+ const manifestUrl = new URL(config.updates.manifestUrl ?? `/__absolute/mobile/updates/${encodeURIComponent(channel)}/update.json`, `${productionOrigin}/`);
9133
+ const loopback = manifestUrl.hostname === "localhost" || manifestUrl.hostname === "127.0.0.1" || manifestUrl.hostname === "[::1]";
9134
+ if (manifestUrl.protocol !== "https:" && !loopback)
9135
+ throw new TypeError("mobile.updates.manifestUrl must use HTTPS outside loopback development.");
9136
+ if (manifestUrl.username || manifestUrl.password || manifestUrl.hash)
9137
+ throw new TypeError("mobile.updates.manifestUrl cannot contain credentials or a fragment.");
9138
+ const entries = Object.entries(config.updates.publicKeys).sort(([left], [right]) => left.localeCompare(right));
9139
+ if (entries.length === 0)
9140
+ throw new TypeError("mobile.updates.publicKeys must contain at least one key.");
9141
+ const publicKeys = Object.fromEntries(entries.map(([keyId, key]) => {
9142
+ if (!UPDATE_NAME_PATTERN.test(keyId))
9143
+ throw new TypeError("mobile.updates.publicKeys contains an invalid key ID.");
9144
+ const normalized = requireText(key, `mobile.updates.publicKeys.${keyId}`);
9145
+ if (!UPDATE_PUBLIC_KEY_PATTERN.test(normalized))
9146
+ throw new TypeError(`mobile.updates.publicKeys.${keyId} must be base64-encoded ECDSA P-256 SPKI DER.`);
9147
+ let decoded;
9148
+ try {
9149
+ decoded = Buffer.from(normalized, "base64");
9150
+ } catch {
9151
+ throw new TypeError(`mobile.updates.publicKeys.${keyId} must be canonical base64.`);
9152
+ }
9153
+ let keyType;
9154
+ let namedCurve;
9155
+ try {
9156
+ const publicKey = createPublicKey({
9157
+ format: "der",
9158
+ key: decoded,
9159
+ type: "spki"
9160
+ });
9161
+ keyType = publicKey.asymmetricKeyType;
9162
+ namedCurve = publicKey.asymmetricKeyDetails?.namedCurve;
9163
+ } catch {
9164
+ keyType = undefined;
9165
+ }
9166
+ if (decoded.toString("base64") !== normalized || keyType !== "ec" || namedCurve !== "prime256v1")
9167
+ throw new TypeError(`mobile.updates.publicKeys.${keyId} is not an ECDSA P-256 SPKI public key.`);
9168
+ return [keyId, normalized];
9169
+ }));
9170
+ return { channel, manifestUrl: manifestUrl.href, publicKeys };
9171
+ }, validateExpoNativeRouteSegment = (path, segment, index, count, parameters) => {
9126
9172
  if (segment === "*" && (index !== count - 1 || count === 1)) {
9127
9173
  throw new TypeError(`mobile.routes.native route ${path} must use * once, as the final segment after a static or parameterized prefix.`);
9128
9174
  }
@@ -9180,6 +9226,7 @@ var APP_ID_PATTERN, SCHEME_PATTERN, APPLE_APP_ID_PREFIX_PATTERN, CERTIFICATE_FIN
9180
9226
  if (deepLinkScheme && !SCHEME_PATTERN.test(deepLinkScheme)) {
9181
9227
  throw new TypeError("mobile.deepLinks.scheme is not a valid URL scheme.");
9182
9228
  }
9229
+ const updates = normalizeUpdates(config, productionOrigin);
9183
9230
  return {
9184
9231
  androidCertificateFingerprints: normalizeCertificateFingerprints(config.deepLinks?.android?.sha256CertificateFingerprints),
9185
9232
  appId,
@@ -9196,7 +9243,8 @@ var APP_ID_PATTERN, SCHEME_PATTERN, APPLE_APP_ID_PREFIX_PATTERN, CERTIFICATE_FIN
9196
9243
  nativeProjectDirectory: resolveProjectPath(projectRoot, config.nativeProject?.directory ?? (config.engine === "expo" ? ".absolutejs/mobile/expo" : "mobile"), "mobile.nativeProject.directory"),
9197
9244
  platforms: normalizePlatforms(config.platforms),
9198
9245
  productionOrigin,
9199
- pushAndroidGoogleServicesFile: resolveProjectPath(projectRoot, config.pushNotifications?.android?.googleServicesFile ?? "google-services.json", "mobile.pushNotifications.android.googleServicesFile")
9246
+ pushAndroidGoogleServicesFile: resolveProjectPath(projectRoot, config.pushNotifications?.android?.googleServicesFile ?? "google-services.json", "mobile.pushNotifications.android.googleServicesFile"),
9247
+ ...updates ? { updates } : {}
9200
9248
  };
9201
9249
  };
9202
9250
  var init_config = __esm(() => {
@@ -9204,6 +9252,8 @@ var init_config = __esm(() => {
9204
9252
  SCHEME_PATTERN = /^[a-z][a-z0-9+.-]*$/;
9205
9253
  APPLE_APP_ID_PREFIX_PATTERN = /^[A-Z0-9]{10}$/;
9206
9254
  CERTIFICATE_FINGERPRINT_PATTERN = /^[0-9A-F]{64}$/;
9255
+ UPDATE_NAME_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/u;
9256
+ UPDATE_PUBLIC_KEY_PATTERN = /^[A-Za-z0-9+/]+={0,2}$/u;
9207
9257
  HOSTNAME_PATTERN = /^(?=.{1,253}$)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)(?:\.(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?))*$/;
9208
9258
  EXPO_RESERVED_ROUTE_PREFIXES = new Set([
9209
9259
  "_expo",
@@ -41177,5 +41227,5 @@ export {
41177
41227
  wrapPageHandlerWithStreamingSlots
41178
41228
  };
41179
41229
 
41180
- //# debugId=93E5701100F7F0FD64756E2164756E21
41230
+ //# debugId=AE2A866A06CFA8B064756E2164756E21
41181
41231
  //# sourceMappingURL=index.js.map