@absolutejs/absolute 0.20.0-beta.179 → 0.20.0-beta.180
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/CHANGELOG.md +23 -0
- package/changelog.json +45 -0
- package/dist/angular/browser.js +2 -2
- package/dist/angular/browser.js.map +3 -3
- package/dist/angular/components/core/streamingSlotRegistrar.js +1 -1
- package/dist/angular/components/core/streamingSlotRegistry.js +2 -2
- package/dist/angular/index.js +21 -6
- package/dist/angular/index.js.map +6 -6
- package/dist/angular/server.js +21 -6
- package/dist/angular/server.js.map +6 -6
- package/dist/build.js +5357 -4945
- package/dist/build.js.map +27 -24
- package/dist/cli/build-fntmf42w.js +495 -0
- package/dist/cli/{buildDepVendor-qvsh6dsj.js → buildDepVendor-qnwfct22.js} +5 -3
- package/dist/cli/buildReactServerComponents-fq6mw10d.js +13 -0
- package/dist/cli/{compile-p5yv6ecp.js → compile-54rb8szn.js} +94 -125
- package/dist/cli/config/server.js +10 -5
- package/dist/cli/{dev-2hbcsvkp.js → dev-6s6g5tnk.js} +13 -14
- package/dist/cli/{expoProject-1qtw97js.js → expoProject-acgfaj3f.js} +2 -1
- package/dist/cli/generatedDir-239r7csr.js +9 -0
- package/dist/cli/{index-cksezef8.js → index-0gd30trc.js} +105 -851
- package/dist/cli/index-2wvysvjc.js +40 -0
- package/dist/cli/index-42xjh6gg.js +282 -0
- package/dist/cli/{index-qw98g1p6.js → index-47e8fwha.js} +4 -1
- package/dist/cli/index-65kqn88a.js +8 -0
- package/dist/cli/{index-2bxfhs32.js → index-6f448d7m.js} +0 -26
- package/dist/cli/index-972xxwgj.js +16 -0
- package/dist/cli/index-aqe25w4h.js +39 -0
- package/dist/cli/index-assqancr.js +51 -0
- package/dist/cli/{index-2shf4aya.js → index-c8rcfe5a.js} +4 -6
- package/dist/cli/index-cba1cemz.js +8 -0
- package/dist/cli/{index-3ff5ztt3.js → index-djkrb7pc.js} +1 -7
- package/dist/cli/index-dkfwkpc8.js +138 -0
- package/dist/cli/{index-92g14j47.js → index-dw44xa4x.js} +2 -1
- package/dist/cli/index-evsnq0n2.js +17 -0
- package/dist/cli/index-fxwf3n2v.js +224 -0
- package/dist/cli/{index-zyd80s3h.js → index-js2hksgv.js} +21 -295
- package/dist/cli/{index-bp60baze.js → index-jyap0bhv.js} +1 -1
- package/dist/cli/{index-9dzdbbfc.js → index-kx2d067c.js} +8 -6
- package/dist/cli/index-pb31zan6.js +9 -0
- package/dist/cli/index-sq0478b0.js +281 -0
- package/dist/cli/index-va274tsf.js +7 -0
- package/dist/cli/{index-yd672jyq.js → index-w6xsk8cv.js} +4 -1
- package/dist/cli/index-w79snsxv.js +461 -0
- package/dist/cli/index-x1vvn549.js +835 -0
- package/dist/cli/index-xf9sfr8a.js +243 -0
- package/dist/cli/index-ycqdxy55.js +754 -0
- package/dist/cli/index-z74cqxz0.js +131 -0
- package/dist/cli/index.js +10 -9
- package/dist/cli/{islands-6zgb7501.js → islands-17tfx8jf.js} +6 -17
- package/dist/cli/{ls-0hfx323m.js → ls-0wr74w0b.js} +10 -58
- package/dist/cli/{mobile-93vaawcz.js → mobile-hpqpy61f.js} +11 -8
- package/dist/cli/{prerender-010z771p.js → prerender-w65xp6h8.js} +2 -1
- package/dist/cli/{rewriteImports-z6629aww.js → rewriteImports-np2d2kvc.js} +4 -11
- package/dist/cli/rewriteImportsPlugin-c6hcb3x6.js +12 -0
- package/dist/cli/{start-asxb79rc.js → start-mbn2zgs2.js} +6 -4
- package/dist/cli/staticAnalyzeSpaRoutes-2nev05m1.js +8 -0
- package/dist/cli/staticAnalyzeSpaRoutes-6vgzp0rs.js +8 -0
- package/dist/cli/staticAnalyzeSpaRoutes-f85q9dqk.js +8 -0
- package/dist/cli/staticAnalyzeSpaRoutes-yakmg22g.js +7 -0
- package/dist/cli/{typecheck-m2j4tkdk.js → typecheck-488txsfc.js} +92 -18
- package/dist/cli/vueCompiler-8bzdmf08.js +7 -0
- package/dist/client/chunks/{react-khr6ewhr.js → react-g8r290b8.js} +37 -2
- package/dist/client/chunks/react-g8r290b8.js.map +10 -0
- package/dist/client/chunks/vue-zcpmka32.js +85 -0
- package/dist/client/chunks/vue-zcpmka32.js.map +10 -0
- package/dist/client/index.js +58 -10
- package/dist/client/index.js.map +4 -4
- package/dist/dev/client/handlers/vue.ts +116 -0
- package/dist/index.js +2472 -2058
- package/dist/index.js.map +26 -23
- package/dist/islands/browser.js +2 -2
- package/dist/islands/browser.js.map +3 -3
- package/dist/islands/index.js +2 -2
- package/dist/islands/index.js.map +3 -3
- package/dist/react/browser.js +2 -2
- package/dist/react/browser.js.map +3 -3
- package/dist/react/index.js +42 -11
- package/dist/react/index.js.map +10 -10
- package/dist/react/server.js +42 -11
- package/dist/react/server.js.map +10 -10
- package/dist/src/angular/ssrRender.d.ts +2 -2
- package/dist/src/angular/staticAnalyzeSpaRoutes.d.ts +6 -1
- package/dist/src/build/generateManifest.d.ts +15 -0
- package/dist/src/build/manifestKeys.d.ts +22 -0
- package/dist/src/cli/add/dependencies.d.ts +1 -1
- package/dist/src/cli/scripts/typecheck.d.ts +11 -0
- package/dist/src/client/hydrators/react.d.ts +10 -0
- package/dist/src/client/hydrators/vue.d.ts +13 -0
- package/dist/src/client/islandRuntime.d.ts +1 -1
- package/dist/src/core/islandManifest.d.ts +4 -0
- package/dist/src/core/islandPageContext.d.ts +8 -2
- package/dist/src/core/lookup.d.ts +16 -1
- package/dist/src/dev/importCost/instrument.d.ts +1 -1
- package/dist/src/dev/manifestKeysRefresher.d.ts +6 -0
- package/dist/src/dev/spaRouteRefresh.d.ts +13 -0
- package/dist/src/mobile/androidConformance.d.ts +1 -1
- package/dist/src/react/staticAnalyzeSpaRoutes.d.ts +6 -1
- package/dist/src/svelte/staticAnalyzeSpaRoutes.d.ts +1 -0
- package/dist/src/utils/logger.d.ts +5 -0
- package/dist/src/utils/spaRouteManifest.d.ts +1 -0
- package/dist/src/vue/components/Image.d.ts +4 -4
- package/dist/src/vue/components/StreamSlot.d.ts +1 -1
- package/dist/src/vue/components/SuspenseSlot.d.ts +2 -2
- package/dist/src/vue/staticAnalyzeSpaRoutes.d.ts +4 -0
- package/dist/svelte/browser.js +2 -2
- package/dist/svelte/browser.js.map +3 -3
- package/dist/svelte/index.js +25 -9
- package/dist/svelte/index.js.map +8 -8
- package/dist/svelte/server.js +25 -9
- package/dist/svelte/server.js.map +8 -8
- package/dist/types/globals.d.ts +4 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/island.d.ts +1 -1
- package/dist/types/manifest.d.ts +25 -0
- package/dist/vue/browser.js +2 -2
- package/dist/vue/browser.js.map +3 -3
- package/dist/vue/index.js +21 -6
- package/dist/vue/index.js.map +6 -6
- package/dist/vue/server.js +21 -6
- package/dist/vue/server.js.map +6 -6
- package/package.json +1 -1
- package/dist/client/chunks/react-khr6ewhr.js.map +0 -10
- package/dist/client/chunks/vue-db6ppn1f.js +0 -32
- package/dist/client/chunks/vue-db6ppn1f.js.map +0 -10
|
@@ -10,8 +10,10 @@ import {
|
|
|
10
10
|
resolveAbsoluteMobileAuthManifest2
|
|
11
11
|
} from "./index-pch0v1z6.js";
|
|
12
12
|
import {
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
discoverAbsoluteSyncSchema,
|
|
14
|
+
absoluteDeviceNativeRequirements,
|
|
15
|
+
resolveAbsoluteDeviceCapabilityPlan
|
|
16
|
+
} from "./index-ycqdxy55.js";
|
|
15
17
|
|
|
16
18
|
// src/mobile/expoProject.ts
|
|
17
19
|
import {
|
|
@@ -25,7 +27,7 @@ import {
|
|
|
25
27
|
writeFile as writeFile2
|
|
26
28
|
} from "fs/promises";
|
|
27
29
|
import { createHash as createHash3 } from "crypto";
|
|
28
|
-
import { basename, dirname as
|
|
30
|
+
import { basename, dirname as dirname3, join as join6, relative as relative2, resolve as resolve3, sep } from "path";
|
|
29
31
|
|
|
30
32
|
// src/mobile/nativePackages.ts
|
|
31
33
|
import { readFile } from "fs/promises";
|
|
@@ -100,754 +102,6 @@ var packagesNeedingExactInstall = async (projectRoot, specs, installed, exactPac
|
|
|
100
102
|
return spec;
|
|
101
103
|
}))).filter((spec) => spec !== undefined);
|
|
102
104
|
|
|
103
|
-
// src/mobile/syncSchema.ts
|
|
104
|
-
import { readFileSync } from "fs";
|
|
105
|
-
import { dirname as dirname2, join as join2, resolve as resolve2 } from "path";
|
|
106
|
-
|
|
107
|
-
// node_modules/@absolutejs/sync/dist/client/index.js
|
|
108
|
-
var pools = new Map;
|
|
109
|
-
class SyncLocalDataPolicyError extends Error {
|
|
110
|
-
code;
|
|
111
|
-
constructor(code, message) {
|
|
112
|
-
super(message);
|
|
113
|
-
this.name = "SyncLocalDataPolicyError";
|
|
114
|
-
this.code = code;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
class SyncLocalStoreSchemaError extends Error {
|
|
119
|
-
code;
|
|
120
|
-
storedVersion;
|
|
121
|
-
targetVersion;
|
|
122
|
-
constructor(code, message, versions = {}) {
|
|
123
|
-
super(message);
|
|
124
|
-
this.name = "SyncLocalStoreSchemaError";
|
|
125
|
-
this.code = code;
|
|
126
|
-
this.storedVersion = versions.storedVersion;
|
|
127
|
-
this.targetVersion = versions.targetVersion;
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
var positiveVersion = (value, label) => {
|
|
131
|
-
if (!Number.isSafeInteger(value) || value < 1)
|
|
132
|
-
throw new SyncLocalStoreSchemaError("INVALID_PLAN", `${label} must be a positive safe integer`);
|
|
133
|
-
return value;
|
|
134
|
-
};
|
|
135
|
-
var isSchemaBundle = (schema) => ("components" in schema);
|
|
136
|
-
var validatePolicyMatch = (match, label) => {
|
|
137
|
-
if (match.length === 0 || match.trim() !== match || /^\*+$/.test(match) || match.includes("**"))
|
|
138
|
-
throw new SyncLocalDataPolicyError("INVALID_POLICY", `${label}.match must be an exact name or a non-empty glob without adjacent wildcards.`);
|
|
139
|
-
};
|
|
140
|
-
var validateSyncLocalDataPolicy = (policy, label = "localData") => {
|
|
141
|
-
if (policy.maxBytesPerNamespace !== undefined && (!Number.isSafeInteger(policy.maxBytesPerNamespace) || policy.maxBytesPerNamespace < 1))
|
|
142
|
-
throw new SyncLocalDataPolicyError("INVALID_POLICY", `${label}.maxBytesPerNamespace must be a positive safe integer.`);
|
|
143
|
-
for (const [index, rule] of (policy.collections ?? []).entries()) {
|
|
144
|
-
validatePolicyMatch(rule.match, `${label}.collections[${index}]`);
|
|
145
|
-
if (rule.maxAgeMs !== undefined && (!Number.isSafeInteger(rule.maxAgeMs) || rule.maxAgeMs < 1))
|
|
146
|
-
throw new SyncLocalDataPolicyError("INVALID_POLICY", `${label}.collections[${index}].maxAgeMs must be a positive safe integer.`);
|
|
147
|
-
if (rule.persistence === "memory-only" && rule.protection === "required")
|
|
148
|
-
throw new SyncLocalDataPolicyError("INVALID_POLICY", `${label}.collections[${index}] cannot require at-rest protection when it is memory-only.`);
|
|
149
|
-
if (rule.sensitivity !== undefined && rule.sensitivity !== "public" && rule.protection !== "required" && rule.persistence !== "memory-only")
|
|
150
|
-
throw new SyncLocalDataPolicyError("INVALID_POLICY", `${label}.collections[${index}] declares ${rule.sensitivity} data without required protection or memory-only persistence.`);
|
|
151
|
-
}
|
|
152
|
-
for (const [index, rule] of (policy.mutations ?? []).entries()) {
|
|
153
|
-
validatePolicyMatch(rule.match, `${label}.mutations[${index}]`);
|
|
154
|
-
if (rule.conflict !== undefined && rule.conflict.strategy !== "client-wins" && rule.conflict.strategy !== "manual" && rule.conflict.strategy !== "server-wins")
|
|
155
|
-
throw new SyncLocalDataPolicyError("INVALID_POLICY", `${label}.mutations[${index}].conflict.strategy is invalid.`);
|
|
156
|
-
if (rule.conflict?.maxAttempts !== undefined && (!Number.isSafeInteger(rule.conflict.maxAttempts) || rule.conflict.maxAttempts < 1))
|
|
157
|
-
throw new SyncLocalDataPolicyError("INVALID_POLICY", `${label}.mutations[${index}].conflict.maxAttempts must be a positive safe integer.`);
|
|
158
|
-
if (rule.conflict?.maxAttempts !== undefined && rule.conflict.strategy !== "client-wins")
|
|
159
|
-
throw new SyncLocalDataPolicyError("INVALID_POLICY", `${label}.mutations[${index}].conflict.maxAttempts is only valid for client-wins.`);
|
|
160
|
-
if (rule.persistence === "memory-only" && rule.protection === "required")
|
|
161
|
-
throw new SyncLocalDataPolicyError("INVALID_POLICY", `${label}.mutations[${index}] cannot require at-rest protection when it is memory-only.`);
|
|
162
|
-
if (rule.sensitivity !== undefined && rule.sensitivity !== "public" && rule.protection !== "required" && rule.persistence !== "memory-only")
|
|
163
|
-
throw new SyncLocalDataPolicyError("INVALID_POLICY", `${label}.mutations[${index}] declares ${rule.sensitivity} arguments without required protection.`);
|
|
164
|
-
}
|
|
165
|
-
return policy;
|
|
166
|
-
};
|
|
167
|
-
var normalizeSyncLocalSchemaComponents = (schema = { version: 1 }) => {
|
|
168
|
-
const components = isSchemaBundle(schema) ? [...schema.components] : [{ ...schema, id: "@absolutejs/app" }];
|
|
169
|
-
const ids = new Set;
|
|
170
|
-
for (const component of components) {
|
|
171
|
-
if (typeof component.id !== "string" || component.id.trim() !== component.id || component.id.length === 0)
|
|
172
|
-
throw new SyncLocalStoreSchemaError("INVALID_PLAN", "Sync schema component id must be non-empty and trimmed");
|
|
173
|
-
if (ids.has(component.id))
|
|
174
|
-
throw new SyncLocalStoreSchemaError("INVALID_PLAN", `Sync schema component "${component.id}" is declared more than once`);
|
|
175
|
-
ids.add(component.id);
|
|
176
|
-
if (component.localData)
|
|
177
|
-
validateSyncLocalDataPolicy(component.localData, `${component.id}.localData`);
|
|
178
|
-
}
|
|
179
|
-
return components.sort((a, b) => a.id.localeCompare(b.id));
|
|
180
|
-
};
|
|
181
|
-
var resolveSyncLocalSchemaComponents = (storedVersions, schema = { version: 1 }) => {
|
|
182
|
-
const components = normalizeSyncLocalSchemaComponents(schema).map((component) => {
|
|
183
|
-
const current = resolveSyncLocalMigrations(component.version, component);
|
|
184
|
-
return {
|
|
185
|
-
id: component.id,
|
|
186
|
-
...resolveSyncLocalMigrations(storedVersions[component.id] ?? current.minimumCompatibleVersion, component)
|
|
187
|
-
};
|
|
188
|
-
});
|
|
189
|
-
const active = new Set(components.map((component) => component.id));
|
|
190
|
-
const orphanedComponents = Object.keys(storedVersions).filter((id) => !active.has(id)).sort();
|
|
191
|
-
return { components, orphanedComponents };
|
|
192
|
-
};
|
|
193
|
-
var resolveSyncLocalMigrations = (storedVersion, schema = { version: 1 }) => {
|
|
194
|
-
positiveVersion(storedVersion, "Stored Sync schema version");
|
|
195
|
-
const targetVersion = positiveVersion(schema.version, "Target Sync schema version");
|
|
196
|
-
const migrations = [...schema.migrations ?? []].sort((a, b) => a.toVersion - b.toVersion);
|
|
197
|
-
const versions = new Set;
|
|
198
|
-
for (const migration of migrations) {
|
|
199
|
-
positiveVersion(migration.toVersion, "Sync migration toVersion");
|
|
200
|
-
if (versions.has(migration.toVersion))
|
|
201
|
-
throw new SyncLocalStoreSchemaError("INVALID_PLAN", `Sync migration ${migration.toVersion} is declared more than once`);
|
|
202
|
-
versions.add(migration.toVersion);
|
|
203
|
-
}
|
|
204
|
-
const inferredMinimum = migrations[0] ? migrations[0].toVersion - 1 : targetVersion;
|
|
205
|
-
const minimumCompatibleVersion = positiveVersion(schema.minimumCompatibleVersion ?? inferredMinimum, "Minimum compatible Sync schema version");
|
|
206
|
-
if (minimumCompatibleVersion > targetVersion)
|
|
207
|
-
throw new SyncLocalStoreSchemaError("INVALID_PLAN", "Minimum compatible Sync schema version cannot exceed its target");
|
|
208
|
-
if (storedVersion > targetVersion)
|
|
209
|
-
throw new SyncLocalStoreSchemaError("SCHEMA_TOO_NEW", `Stored Sync schema ${storedVersion} is newer than this runtime's schema ${targetVersion}`, { storedVersion, targetVersion });
|
|
210
|
-
if (storedVersion < minimumCompatibleVersion)
|
|
211
|
-
throw new SyncLocalStoreSchemaError("SCHEMA_TOO_OLD", `Stored Sync schema ${storedVersion} is older than the minimum compatible schema ${minimumCompatibleVersion}`, { storedVersion, targetVersion });
|
|
212
|
-
const steps = [];
|
|
213
|
-
for (let version = storedVersion + 1;version <= targetVersion; version++) {
|
|
214
|
-
const migration = migrations.find((candidate) => candidate.toVersion === version);
|
|
215
|
-
if (migration === undefined)
|
|
216
|
-
throw new SyncLocalStoreSchemaError("MIGRATION_MISSING", `Sync migration ${version - 1} -> ${version} is missing`, { storedVersion, targetVersion });
|
|
217
|
-
steps.push(migration);
|
|
218
|
-
}
|
|
219
|
-
return { minimumCompatibleVersion, steps, targetVersion };
|
|
220
|
-
};
|
|
221
|
-
var RUNTIME_TRANSPORT = Symbol.for("@absolutejs/sync/client-runtime-transport");
|
|
222
|
-
var host = globalThis;
|
|
223
|
-
var isRegistry = (value) => typeof value === "object" && value !== null && Array.isArray(Reflect.get(value, "installations")) && Array.isArray(Reflect.get(value, "clients"));
|
|
224
|
-
var registry = (() => {
|
|
225
|
-
const existing = host[RUNTIME_TRANSPORT];
|
|
226
|
-
if (isRegistry(existing))
|
|
227
|
-
return existing;
|
|
228
|
-
if (typeof existing === "object" && existing !== null && Array.isArray(Reflect.get(existing, "installations"))) {
|
|
229
|
-
Reflect.set(existing, "clients", []);
|
|
230
|
-
return existing;
|
|
231
|
-
}
|
|
232
|
-
const created = { clients: [], installations: [] };
|
|
233
|
-
Object.defineProperty(host, RUNTIME_TRANSPORT, {
|
|
234
|
-
configurable: false,
|
|
235
|
-
enumerable: false,
|
|
236
|
-
value: created,
|
|
237
|
-
writable: false
|
|
238
|
-
});
|
|
239
|
-
return created;
|
|
240
|
-
})();
|
|
241
|
-
|
|
242
|
-
// src/mobile/syncSchema.ts
|
|
243
|
-
var object = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
244
|
-
var manifestAt = (path) => {
|
|
245
|
-
try {
|
|
246
|
-
const value = JSON.parse(readFileSync(path, "utf8"));
|
|
247
|
-
return object(value) ? value : undefined;
|
|
248
|
-
} catch {
|
|
249
|
-
return;
|
|
250
|
-
}
|
|
251
|
-
};
|
|
252
|
-
var localSchemaMetadata = (manifest) => {
|
|
253
|
-
const absolutejs = Reflect.get(manifest, "absolutejs");
|
|
254
|
-
if (!object(absolutejs))
|
|
255
|
-
return;
|
|
256
|
-
const sync = Reflect.get(absolutejs, "sync");
|
|
257
|
-
if (!object(sync))
|
|
258
|
-
return;
|
|
259
|
-
return Reflect.get(sync, "localSchema");
|
|
260
|
-
};
|
|
261
|
-
var packageManifestPath = (projectRoot, packageName) => {
|
|
262
|
-
let directory = resolve2(projectRoot);
|
|
263
|
-
while (true) {
|
|
264
|
-
const candidate = join2(directory, "node_modules", packageName, "package.json");
|
|
265
|
-
const manifest = manifestAt(candidate);
|
|
266
|
-
if (manifest && Reflect.get(manifest, "name") === packageName)
|
|
267
|
-
return candidate;
|
|
268
|
-
const parent = dirname2(directory);
|
|
269
|
-
if (parent === directory)
|
|
270
|
-
return;
|
|
271
|
-
directory = parent;
|
|
272
|
-
}
|
|
273
|
-
};
|
|
274
|
-
var metadataError = (id, detail) => new TypeError(`Invalid AbsoluteJS Sync schema metadata for ${id}: ${detail}`);
|
|
275
|
-
var positiveVersion2 = (value, id, field) => {
|
|
276
|
-
if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 1)
|
|
277
|
-
throw metadataError(id, `${field} must be a positive safe integer.`);
|
|
278
|
-
return value;
|
|
279
|
-
};
|
|
280
|
-
var nonEmpty = (value, id, field) => {
|
|
281
|
-
if (typeof value !== "string" || value.trim() !== value || value.length === 0)
|
|
282
|
-
throw metadataError(id, `${field} must be a non-empty trimmed string.`);
|
|
283
|
-
return value;
|
|
284
|
-
};
|
|
285
|
-
var requireObject = (value, id, detail) => {
|
|
286
|
-
if (!object(value))
|
|
287
|
-
throw metadataError(id, detail);
|
|
288
|
-
return value;
|
|
289
|
-
};
|
|
290
|
-
var unknownField = (record, key) => record[key];
|
|
291
|
-
var normalizeJsonValue = (value, id, field) => {
|
|
292
|
-
if (value === null || typeof value === "string" || typeof value === "boolean")
|
|
293
|
-
return value;
|
|
294
|
-
if (typeof value === "number" && Number.isFinite(value))
|
|
295
|
-
return value;
|
|
296
|
-
if (Array.isArray(value))
|
|
297
|
-
return value.map((entry) => normalizeJsonValue(entry, id, field));
|
|
298
|
-
if (object(value))
|
|
299
|
-
return Object.fromEntries(Object.entries(value).map(([key, entry]) => [
|
|
300
|
-
key,
|
|
301
|
-
normalizeJsonValue(entry, id, field)
|
|
302
|
-
]));
|
|
303
|
-
throw metadataError(id, `${field} must be JSON-safe.`);
|
|
304
|
-
};
|
|
305
|
-
var operation = (value, id, index) => {
|
|
306
|
-
const record = requireObject(value, id, `migration operation ${index} must be an object.`);
|
|
307
|
-
const type = Reflect.get(record, "type");
|
|
308
|
-
const collection = nonEmpty(Reflect.get(record, "collection"), id, `operation ${index}.collection`);
|
|
309
|
-
if (type === "delete-collection")
|
|
310
|
-
return { collection, type };
|
|
311
|
-
if (type === "rename-field")
|
|
312
|
-
return {
|
|
313
|
-
collection,
|
|
314
|
-
from: nonEmpty(Reflect.get(record, "from"), id, `operation ${index}.from`),
|
|
315
|
-
to: nonEmpty(Reflect.get(record, "to"), id, `operation ${index}.to`),
|
|
316
|
-
type
|
|
317
|
-
};
|
|
318
|
-
const field = nonEmpty(Reflect.get(record, "field"), id, `operation ${index}.field`);
|
|
319
|
-
if (type === "remove-field")
|
|
320
|
-
return { collection, field, type };
|
|
321
|
-
if (type === "set-default")
|
|
322
|
-
return {
|
|
323
|
-
collection,
|
|
324
|
-
field,
|
|
325
|
-
type,
|
|
326
|
-
value: normalizeJsonValue(Reflect.get(record, "value"), id, `operation ${index}.value`)
|
|
327
|
-
};
|
|
328
|
-
throw metadataError(id, `operation ${index}.type is not supported.`);
|
|
329
|
-
};
|
|
330
|
-
var migration = (value, id, index) => {
|
|
331
|
-
const record = requireObject(value, id, `migration ${index} must be an object.`);
|
|
332
|
-
const allowed = new Set(["operations", "toVersion"]);
|
|
333
|
-
const unsupported = Object.keys(record).find((key) => !allowed.has(key));
|
|
334
|
-
if (unsupported)
|
|
335
|
-
throw metadataError(id, `migration ${index}.${unsupported} is not declarative metadata.`);
|
|
336
|
-
const declaredOperations = Reflect.get(record, "operations");
|
|
337
|
-
if (declaredOperations !== undefined && !Array.isArray(declaredOperations))
|
|
338
|
-
throw metadataError(id, `migration ${index}.operations must be an array.`);
|
|
339
|
-
const operations = Array.isArray(declaredOperations) ? declaredOperations : [];
|
|
340
|
-
return {
|
|
341
|
-
operations: operations.map((entry, operationIndex) => operation(entry, id, operationIndex)),
|
|
342
|
-
toVersion: positiveVersion2(Reflect.get(record, "toVersion"), id, `migration ${index}.toVersion`)
|
|
343
|
-
};
|
|
344
|
-
};
|
|
345
|
-
var localDataPolicy = (value, id) => {
|
|
346
|
-
const record = requireObject(value, id, "localData must be an object.");
|
|
347
|
-
const allowed = new Set([
|
|
348
|
-
"collections",
|
|
349
|
-
"maxBytesPerNamespace",
|
|
350
|
-
"mutations"
|
|
351
|
-
]);
|
|
352
|
-
const unsupported = Object.keys(record).find((key) => !allowed.has(key));
|
|
353
|
-
if (unsupported)
|
|
354
|
-
throw metadataError(id, `localData.${unsupported} is not supported.`);
|
|
355
|
-
const collectionRules = Reflect.get(record, "collections");
|
|
356
|
-
const mutationRules = Reflect.get(record, "mutations");
|
|
357
|
-
if (collectionRules !== undefined && !Array.isArray(collectionRules))
|
|
358
|
-
throw metadataError(id, "localData.collections must be an array.");
|
|
359
|
-
if (mutationRules !== undefined && !Array.isArray(mutationRules))
|
|
360
|
-
throw metadataError(id, "localData.mutations must be an array.");
|
|
361
|
-
const collections = Array.isArray(collectionRules) ? collectionRules.map((entry, index) => {
|
|
362
|
-
const rule = requireObject(entry, id, `localData.collections[${index}] must be an object.`);
|
|
363
|
-
const allowedRuleKeys = new Set([
|
|
364
|
-
"evictionPriority",
|
|
365
|
-
"match",
|
|
366
|
-
"maxAgeMs",
|
|
367
|
-
"onProtectionUnavailable",
|
|
368
|
-
"persistence",
|
|
369
|
-
"protection",
|
|
370
|
-
"sensitivity"
|
|
371
|
-
]);
|
|
372
|
-
const unsupportedRuleKey = Object.keys(rule).find((key) => !allowedRuleKeys.has(key));
|
|
373
|
-
if (unsupportedRuleKey)
|
|
374
|
-
throw metadataError(id, `localData.collections[${index}].${unsupportedRuleKey} is not supported.`);
|
|
375
|
-
const match = nonEmpty(Reflect.get(rule, "match"), id, `localData.collections[${index}].match`);
|
|
376
|
-
const persistence = unknownField(rule, "persistence");
|
|
377
|
-
const sensitivity = unknownField(rule, "sensitivity");
|
|
378
|
-
const protection = unknownField(rule, "protection");
|
|
379
|
-
const onProtectionUnavailable = unknownField(rule, "onProtectionUnavailable");
|
|
380
|
-
const evictionPriority = unknownField(rule, "evictionPriority");
|
|
381
|
-
const maxAge = unknownField(rule, "maxAgeMs");
|
|
382
|
-
if (persistence !== undefined && persistence !== "durable" && persistence !== "memory-only")
|
|
383
|
-
throw metadataError(id, `localData.collections[${index}].persistence is invalid.`);
|
|
384
|
-
if (sensitivity !== undefined && sensitivity !== "public" && sensitivity !== "private" && sensitivity !== "secret")
|
|
385
|
-
throw metadataError(id, `localData.collections[${index}].sensitivity is invalid.`);
|
|
386
|
-
if (protection !== undefined && protection !== "none" && protection !== "required")
|
|
387
|
-
throw metadataError(id, `localData.collections[${index}].protection is invalid.`);
|
|
388
|
-
if (onProtectionUnavailable !== undefined && onProtectionUnavailable !== "error" && onProtectionUnavailable !== "memory-only")
|
|
389
|
-
throw metadataError(id, `localData.collections[${index}].onProtectionUnavailable is invalid.`);
|
|
390
|
-
if (evictionPriority !== undefined && evictionPriority !== "critical" && evictionPriority !== "normal" && evictionPriority !== "disposable")
|
|
391
|
-
throw metadataError(id, `localData.collections[${index}].evictionPriority is invalid.`);
|
|
392
|
-
return {
|
|
393
|
-
match,
|
|
394
|
-
...sensitivity ? { sensitivity } : {},
|
|
395
|
-
...persistence ? { persistence } : {},
|
|
396
|
-
...protection ? { protection } : {},
|
|
397
|
-
...onProtectionUnavailable ? {
|
|
398
|
-
onProtectionUnavailable
|
|
399
|
-
} : {},
|
|
400
|
-
...evictionPriority ? { evictionPriority } : {},
|
|
401
|
-
...maxAge === undefined ? {} : {
|
|
402
|
-
maxAgeMs: positiveVersion2(maxAge, id, `localData.collections[${index}].maxAgeMs`)
|
|
403
|
-
}
|
|
404
|
-
};
|
|
405
|
-
}) : undefined;
|
|
406
|
-
const mutations = Array.isArray(mutationRules) ? mutationRules.map((entry, index) => {
|
|
407
|
-
const rule = requireObject(entry, id, `localData.mutations[${index}] must be an object.`);
|
|
408
|
-
const allowedRuleKeys = new Set([
|
|
409
|
-
"conflict",
|
|
410
|
-
"match",
|
|
411
|
-
"onProtectionUnavailable",
|
|
412
|
-
"persistence",
|
|
413
|
-
"protection",
|
|
414
|
-
"sensitivity"
|
|
415
|
-
]);
|
|
416
|
-
const unsupportedRuleKey = Object.keys(rule).find((key) => !allowedRuleKeys.has(key));
|
|
417
|
-
if (unsupportedRuleKey)
|
|
418
|
-
throw metadataError(id, `localData.mutations[${index}].${unsupportedRuleKey} is not supported.`);
|
|
419
|
-
const protection = unknownField(rule, "protection");
|
|
420
|
-
const sensitivity = unknownField(rule, "sensitivity");
|
|
421
|
-
const persistence = unknownField(rule, "persistence");
|
|
422
|
-
const onProtectionUnavailable = unknownField(rule, "onProtectionUnavailable");
|
|
423
|
-
const declaredConflict = unknownField(rule, "conflict");
|
|
424
|
-
let conflict;
|
|
425
|
-
if (declaredConflict !== undefined) {
|
|
426
|
-
const conflictRecord = requireObject(declaredConflict, id, `localData.mutations[${index}].conflict must be an object.`);
|
|
427
|
-
const unsupportedConflictKey = Object.keys(conflictRecord).find((key) => key !== "maxAttempts" && key !== "strategy");
|
|
428
|
-
if (unsupportedConflictKey)
|
|
429
|
-
throw metadataError(id, `localData.mutations[${index}].conflict.${unsupportedConflictKey} is not supported.`);
|
|
430
|
-
const strategy = unknownField(conflictRecord, "strategy");
|
|
431
|
-
if (strategy !== "client-wins" && strategy !== "manual" && strategy !== "server-wins")
|
|
432
|
-
throw metadataError(id, `localData.mutations[${index}].conflict.strategy is invalid.`);
|
|
433
|
-
const maxAttempts = unknownField(conflictRecord, "maxAttempts");
|
|
434
|
-
if (maxAttempts !== undefined && strategy !== "client-wins")
|
|
435
|
-
throw metadataError(id, `localData.mutations[${index}].conflict.maxAttempts requires client-wins.`);
|
|
436
|
-
conflict = {
|
|
437
|
-
strategy,
|
|
438
|
-
...maxAttempts === undefined ? {} : {
|
|
439
|
-
maxAttempts: positiveVersion2(maxAttempts, id, `localData.mutations[${index}].conflict.maxAttempts`)
|
|
440
|
-
}
|
|
441
|
-
};
|
|
442
|
-
}
|
|
443
|
-
if (protection !== undefined && protection !== "none" && protection !== "required")
|
|
444
|
-
throw metadataError(id, `localData.mutations[${index}].protection is invalid.`);
|
|
445
|
-
if (sensitivity !== undefined && sensitivity !== "public" && sensitivity !== "private" && sensitivity !== "secret")
|
|
446
|
-
throw metadataError(id, `localData.mutations[${index}].sensitivity is invalid.`);
|
|
447
|
-
if (onProtectionUnavailable !== undefined && onProtectionUnavailable !== "error" && onProtectionUnavailable !== "memory-only")
|
|
448
|
-
throw metadataError(id, `localData.mutations[${index}].onProtectionUnavailable is invalid.`);
|
|
449
|
-
if (persistence !== undefined && persistence !== "durable" && persistence !== "memory-only")
|
|
450
|
-
throw metadataError(id, `localData.mutations[${index}].persistence is invalid.`);
|
|
451
|
-
return {
|
|
452
|
-
match: nonEmpty(Reflect.get(rule, "match"), id, `localData.mutations[${index}].match`),
|
|
453
|
-
...conflict ? { conflict } : {},
|
|
454
|
-
...sensitivity ? { sensitivity } : {},
|
|
455
|
-
...onProtectionUnavailable ? { onProtectionUnavailable } : {},
|
|
456
|
-
...persistence ? {
|
|
457
|
-
persistence
|
|
458
|
-
} : {},
|
|
459
|
-
...protection ? { protection } : {}
|
|
460
|
-
};
|
|
461
|
-
}) : undefined;
|
|
462
|
-
const quota = Reflect.get(record, "maxBytesPerNamespace");
|
|
463
|
-
return {
|
|
464
|
-
...collections ? { collections } : {},
|
|
465
|
-
...mutations ? { mutations } : {},
|
|
466
|
-
...quota === undefined ? {} : {
|
|
467
|
-
maxBytesPerNamespace: positiveVersion2(quota, id, "localData.maxBytesPerNamespace")
|
|
468
|
-
}
|
|
469
|
-
};
|
|
470
|
-
};
|
|
471
|
-
var component = (id, value) => {
|
|
472
|
-
const record = requireObject(value, id, "localSchema must be an object.");
|
|
473
|
-
const allowed = new Set([
|
|
474
|
-
"localData",
|
|
475
|
-
"migrations",
|
|
476
|
-
"minimumCompatibleVersion",
|
|
477
|
-
"version"
|
|
478
|
-
]);
|
|
479
|
-
const unsupported = Object.keys(record).find((key) => !allowed.has(key));
|
|
480
|
-
if (unsupported)
|
|
481
|
-
throw metadataError(id, `${unsupported} is not supported.`);
|
|
482
|
-
const version = positiveVersion2(Reflect.get(record, "version"), id, "version");
|
|
483
|
-
const declaredMinimum = Reflect.get(record, "minimumCompatibleVersion");
|
|
484
|
-
const minimumCompatibleVersion = declaredMinimum === undefined ? Math.max(1, version - 2) : positiveVersion2(declaredMinimum, id, "minimumCompatibleVersion");
|
|
485
|
-
const declaredMigrations = Reflect.get(record, "migrations");
|
|
486
|
-
const declaredLocalData = Reflect.get(record, "localData");
|
|
487
|
-
if (declaredMigrations !== undefined && !Array.isArray(declaredMigrations))
|
|
488
|
-
throw metadataError(id, "migrations must be an array.");
|
|
489
|
-
const migrations = Array.isArray(declaredMigrations) ? declaredMigrations : undefined;
|
|
490
|
-
return {
|
|
491
|
-
id,
|
|
492
|
-
...declaredLocalData === undefined ? {} : { localData: localDataPolicy(declaredLocalData, id) },
|
|
493
|
-
minimumCompatibleVersion,
|
|
494
|
-
...Array.isArray(migrations) ? {
|
|
495
|
-
migrations: migrations.map((entry, index) => migration(entry, id, index))
|
|
496
|
-
} : {},
|
|
497
|
-
version
|
|
498
|
-
};
|
|
499
|
-
};
|
|
500
|
-
var dependencyNames = (manifest) => [
|
|
501
|
-
Reflect.get(manifest, "dependencies"),
|
|
502
|
-
Reflect.get(manifest, "optionalDependencies"),
|
|
503
|
-
Reflect.get(manifest, "devDependencies"),
|
|
504
|
-
Reflect.get(manifest, "peerDependencies")
|
|
505
|
-
].flatMap((dependencies) => object(dependencies) ? Object.keys(dependencies) : []).filter((name, index, names) => names.indexOf(name) === index).sort();
|
|
506
|
-
var discoverAbsoluteSyncSchema = (projectRoot) => {
|
|
507
|
-
const appManifestPath = join2(resolve2(projectRoot), "package.json");
|
|
508
|
-
const appManifest = manifestAt(appManifestPath);
|
|
509
|
-
if (!appManifest)
|
|
510
|
-
return {
|
|
511
|
-
components: [
|
|
512
|
-
{
|
|
513
|
-
id: "@absolutejs/app",
|
|
514
|
-
minimumCompatibleVersion: 1,
|
|
515
|
-
version: 1
|
|
516
|
-
}
|
|
517
|
-
],
|
|
518
|
-
sources: []
|
|
519
|
-
};
|
|
520
|
-
const appMetadata = localSchemaMetadata(appManifest);
|
|
521
|
-
const components = [
|
|
522
|
-
appMetadata === undefined ? { id: "@absolutejs/app", minimumCompatibleVersion: 1, version: 1 } : component("@absolutejs/app", appMetadata)
|
|
523
|
-
];
|
|
524
|
-
const sources = [
|
|
525
|
-
{ id: "@absolutejs/app", manifestPath: appManifestPath }
|
|
526
|
-
];
|
|
527
|
-
for (const name of dependencyNames(appManifest)) {
|
|
528
|
-
const manifestPath = packageManifestPath(projectRoot, name);
|
|
529
|
-
if (!manifestPath)
|
|
530
|
-
continue;
|
|
531
|
-
const manifest = manifestAt(manifestPath);
|
|
532
|
-
if (!manifest)
|
|
533
|
-
continue;
|
|
534
|
-
const metadata = localSchemaMetadata(manifest);
|
|
535
|
-
if (metadata === undefined)
|
|
536
|
-
continue;
|
|
537
|
-
components.push(component(name, metadata));
|
|
538
|
-
sources.push({ id: name, manifestPath });
|
|
539
|
-
}
|
|
540
|
-
components.sort((left, right) => left.id.localeCompare(right.id));
|
|
541
|
-
sources.sort((left, right) => left.id.localeCompare(right.id));
|
|
542
|
-
resolveSyncLocalSchemaComponents({}, { components });
|
|
543
|
-
return { components, sources };
|
|
544
|
-
};
|
|
545
|
-
|
|
546
|
-
// src/mobile/deviceCapabilities.ts
|
|
547
|
-
import { existsSync, readFileSync as readFileSync2 } from "fs";
|
|
548
|
-
import { extname, join as join3, relative, resolve as resolve3 } from "path";
|
|
549
|
-
import { fileURLToPath } from "url";
|
|
550
|
-
var DEVICES_PACKAGE = "@absolutejs/devices";
|
|
551
|
-
var ABSOLUTE_MOBILE_SHELL_DEVICE_CAPABILITIES = [
|
|
552
|
-
"keyboard",
|
|
553
|
-
"systemBars"
|
|
554
|
-
];
|
|
555
|
-
var ADAPTERS = {
|
|
556
|
-
capacitor: "@absolutejs/devices-capacitor",
|
|
557
|
-
expo: "@absolutejs/devices-expo"
|
|
558
|
-
};
|
|
559
|
-
var SOURCE_GLOB = new Bun.Glob("**/*.{js,jsx,ts,tsx,svelte,vue}");
|
|
560
|
-
var IGNORED_DIRECTORIES = new Set([
|
|
561
|
-
".absolutejs",
|
|
562
|
-
".git",
|
|
563
|
-
".test-builds",
|
|
564
|
-
".test-shards",
|
|
565
|
-
"build",
|
|
566
|
-
"dist",
|
|
567
|
-
"node_modules",
|
|
568
|
-
"test",
|
|
569
|
-
"tests"
|
|
570
|
-
]);
|
|
571
|
-
var IDENTIFIER_PATTERN = /^[A-Za-z_$][\w$]*$/u;
|
|
572
|
-
var providerModulePattern = (provider) => new RegExp(`^@absolutejs/devices-${provider}/[a-z][a-z0-9-]*$`, "u");
|
|
573
|
-
var providerPackagePattern = (provider) => provider === "capacitor" ? /^@capacitor\/[a-z][a-z0-9-]*@\d+\.\d+\.\d+$/u : /^(?:expo-[a-z][a-z0-9-]*|@react-native-[a-z0-9-]+\/[a-z][a-z0-9-]*)@\d+\.\d+\.\d+$/u;
|
|
574
|
-
var providerLabel = (provider) => provider === "capacitor" ? "Capacitor" : "Expo";
|
|
575
|
-
var ANDROID_PERMISSION_PATTERN = /^android\.permission\.[A-Z][A-Z0-9_]*$/u;
|
|
576
|
-
var IOS_USAGE_DESCRIPTIONS = new Set([
|
|
577
|
-
"camera",
|
|
578
|
-
"location-always",
|
|
579
|
-
"location-when-in-use",
|
|
580
|
-
"photo-library",
|
|
581
|
-
"photo-library-add"
|
|
582
|
-
]);
|
|
583
|
-
var IOS_PRIVACY_ACCESSED_API_REASONS = {
|
|
584
|
-
NSPrivacyAccessedAPICategoryFileTimestamp: new Set(["C617.1"])
|
|
585
|
-
};
|
|
586
|
-
var IOS_PRIVACY_ACCESSED_APIS = [
|
|
587
|
-
"NSPrivacyAccessedAPICategoryFileTimestamp"
|
|
588
|
-
];
|
|
589
|
-
var object2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
590
|
-
var readJson = (path) => {
|
|
591
|
-
const value = JSON.parse(readFileSync2(path, "utf8"));
|
|
592
|
-
if (!object2(value))
|
|
593
|
-
throw new TypeError(`${path} must contain an object.`);
|
|
594
|
-
return value;
|
|
595
|
-
};
|
|
596
|
-
var text = (value, field) => {
|
|
597
|
-
if (typeof value !== "string" || value.length === 0)
|
|
598
|
-
throw new TypeError(`${field} must be a non-empty string.`);
|
|
599
|
-
return value;
|
|
600
|
-
};
|
|
601
|
-
var androidPermissions = (value, field) => {
|
|
602
|
-
if (value === undefined)
|
|
603
|
-
return;
|
|
604
|
-
if (!object2(value))
|
|
605
|
-
throw new TypeError(`${field} must be an object.`);
|
|
606
|
-
const { permissions } = value;
|
|
607
|
-
if (!Array.isArray(permissions) || !permissions.every((permission) => typeof permission === "string" && ANDROID_PERMISSION_PATTERN.test(permission)))
|
|
608
|
-
throw new TypeError(`${field}.permissions must contain Android permission names.`);
|
|
609
|
-
return [...permissions];
|
|
610
|
-
};
|
|
611
|
-
var iosPrivacyAccessedApis = (value, field) => {
|
|
612
|
-
if (value === undefined)
|
|
613
|
-
return;
|
|
614
|
-
if (!object2(value))
|
|
615
|
-
throw new TypeError(`${field} must be an object.`);
|
|
616
|
-
const privacy = {};
|
|
617
|
-
for (const api of IOS_PRIVACY_ACCESSED_APIS) {
|
|
618
|
-
const reasons = value[api];
|
|
619
|
-
if (reasons === undefined)
|
|
620
|
-
continue;
|
|
621
|
-
const supported = IOS_PRIVACY_ACCESSED_API_REASONS[api];
|
|
622
|
-
if (!Array.isArray(reasons) || reasons.length === 0 || !reasons.every((reason) => typeof reason === "string" && supported.has(reason)))
|
|
623
|
-
throw new TypeError(`${field} contains an unsupported API or reason.`);
|
|
624
|
-
privacy[api] = [...reasons];
|
|
625
|
-
}
|
|
626
|
-
if (Object.keys(value).some((api) => !IOS_PRIVACY_ACCESSED_APIS.some((known) => known === api)))
|
|
627
|
-
throw new TypeError(`${field} contains an unsupported API or reason.`);
|
|
628
|
-
return privacy;
|
|
629
|
-
};
|
|
630
|
-
var iosNativeRequirements = (value, field) => {
|
|
631
|
-
if (value === undefined)
|
|
632
|
-
return;
|
|
633
|
-
if (!object2(value))
|
|
634
|
-
throw new TypeError(`${field} must be an object.`);
|
|
635
|
-
const {
|
|
636
|
-
privacyAccessedApis,
|
|
637
|
-
pushNotifications,
|
|
638
|
-
systemBars,
|
|
639
|
-
usageDescriptions
|
|
640
|
-
} = value;
|
|
641
|
-
if (pushNotifications !== undefined && pushNotifications !== true)
|
|
642
|
-
throw new TypeError(`${field}.pushNotifications must be true.`);
|
|
643
|
-
if (systemBars !== undefined && systemBars !== true)
|
|
644
|
-
throw new TypeError(`${field}.systemBars must be true.`);
|
|
645
|
-
if (usageDescriptions !== undefined && (!Array.isArray(usageDescriptions) || !usageDescriptions.every((purpose) => typeof purpose === "string" && IOS_USAGE_DESCRIPTIONS.has(purpose))))
|
|
646
|
-
throw new TypeError(`${field}.usageDescriptions contains an unsupported purpose.`);
|
|
647
|
-
const privacy = iosPrivacyAccessedApis(privacyAccessedApis, `${field}.privacyAccessedApis`);
|
|
648
|
-
return {
|
|
649
|
-
...privacy === undefined ? {} : { privacyAccessedApis: privacy },
|
|
650
|
-
...pushNotifications === true ? { pushNotifications: true } : {},
|
|
651
|
-
...systemBars === true ? { systemBars: true } : {},
|
|
652
|
-
...usageDescriptions === undefined ? {} : { usageDescriptions: [...usageDescriptions] }
|
|
653
|
-
};
|
|
654
|
-
};
|
|
655
|
-
var parseProvider = (name, value, providerName) => {
|
|
656
|
-
if (!IDENTIFIER_PATTERN.test(name))
|
|
657
|
-
throw new TypeError("Device capability names must be identifiers.");
|
|
658
|
-
if (!object2(value))
|
|
659
|
-
throw new TypeError(`Device capability ${name} must be an object.`);
|
|
660
|
-
const factory = text(value.factory, `${name}.factory`);
|
|
661
|
-
const module = text(value.module, `${name}.module`);
|
|
662
|
-
if (!IDENTIFIER_PATTERN.test(factory))
|
|
663
|
-
throw new TypeError(`${name}.factory must be a JavaScript identifier.`);
|
|
664
|
-
if (!providerModulePattern(providerName).test(module))
|
|
665
|
-
throw new TypeError(`${name}.module must be an official devices-${providerName} subpath.`);
|
|
666
|
-
if (!Array.isArray(value.packages) || !value.packages.every((spec) => typeof spec === "string" && providerPackagePattern(providerName).test(spec)))
|
|
667
|
-
throw new TypeError(`${name}.packages must contain exact official ${providerLabel(providerName)} package versions.`);
|
|
668
|
-
const { plugins } = value;
|
|
669
|
-
if (plugins !== undefined && (!Array.isArray(plugins) || !plugins.every((plugin) => typeof plugin === "string" && /^expo-[a-z][a-z0-9-]*$/u.test(plugin))))
|
|
670
|
-
throw new TypeError(`${name}.plugins must contain Expo config plugin names.`);
|
|
671
|
-
let native;
|
|
672
|
-
const { native: nativeMetadata } = value;
|
|
673
|
-
if (nativeMetadata !== undefined) {
|
|
674
|
-
if (!object2(nativeMetadata))
|
|
675
|
-
throw new TypeError(`${name}.native must be an object.`);
|
|
676
|
-
const { android, ios } = nativeMetadata;
|
|
677
|
-
const permissions = androidPermissions(android, `${name}.native.android`);
|
|
678
|
-
const iosRequirements = iosNativeRequirements(ios, `${name}.native.ios`);
|
|
679
|
-
native = {
|
|
680
|
-
...permissions === undefined ? {} : { android: { permissions } },
|
|
681
|
-
...iosRequirements === undefined ? {} : { ios: iosRequirements }
|
|
682
|
-
};
|
|
683
|
-
}
|
|
684
|
-
return {
|
|
685
|
-
factory,
|
|
686
|
-
module,
|
|
687
|
-
...native === undefined ? {} : { native },
|
|
688
|
-
...plugins === undefined ? {} : { plugins: [...plugins] },
|
|
689
|
-
packages: [...value.packages]
|
|
690
|
-
};
|
|
691
|
-
};
|
|
692
|
-
var absoluteDeviceNativeRequirements = (plan) => {
|
|
693
|
-
const privacy = plan.capabilities.reduce((requirements, name) => {
|
|
694
|
-
for (const api of IOS_PRIVACY_ACCESSED_APIS) {
|
|
695
|
-
const reasons = plan.providers[name]?.native?.ios?.privacyAccessedApis?.[api] ?? [];
|
|
696
|
-
if (reasons.length === 0)
|
|
697
|
-
continue;
|
|
698
|
-
const current = requirements[api] ?? new Set;
|
|
699
|
-
for (const reason of reasons)
|
|
700
|
-
current.add(reason);
|
|
701
|
-
requirements[api] = current;
|
|
702
|
-
}
|
|
703
|
-
return requirements;
|
|
704
|
-
}, {});
|
|
705
|
-
return {
|
|
706
|
-
androidPermissions: [
|
|
707
|
-
...new Set(plan.capabilities.flatMap((name) => plan.providers[name]?.native?.android?.permissions ?? []))
|
|
708
|
-
].sort(),
|
|
709
|
-
iosPrivacyAccessedApis: IOS_PRIVACY_ACCESSED_APIS.flatMap((api) => {
|
|
710
|
-
const reasons = privacy[api];
|
|
711
|
-
return reasons ? [{ api, reasons: [...reasons].sort() }] : [];
|
|
712
|
-
}),
|
|
713
|
-
iosPushNotifications: plan.capabilities.some((name) => plan.providers[name]?.native?.ios?.pushNotifications === true),
|
|
714
|
-
iosSystemBars: plan.capabilities.some((name) => plan.providers[name]?.native?.ios?.systemBars === true),
|
|
715
|
-
iosUsageDescriptions: [
|
|
716
|
-
...new Set(plan.capabilities.flatMap((name) => plan.providers[name]?.native?.ios?.usageDescriptions ?? []))
|
|
717
|
-
].sort()
|
|
718
|
-
};
|
|
719
|
-
};
|
|
720
|
-
var resolveAdapterManifest = (adapter, provider) => {
|
|
721
|
-
try {
|
|
722
|
-
return fileURLToPath(import.meta.resolve(`${adapter}/package.json`));
|
|
723
|
-
} catch {
|
|
724
|
-
throw new TypeError(`${adapter} is not installed. Run \`absolute mobile init\` to install the ${provider === "expo" ? "Expo" : "Capacitor"} device adapters.`);
|
|
725
|
-
}
|
|
726
|
-
};
|
|
727
|
-
var loadAbsoluteDeviceCapabilityProviders = (projectRoot, provider = "capacitor") => {
|
|
728
|
-
const adapter = ADAPTERS[provider];
|
|
729
|
-
let path = join3(resolve3(projectRoot), "node_modules", adapter, "package.json");
|
|
730
|
-
try {
|
|
731
|
-
readFileSync2(path, "utf8");
|
|
732
|
-
} catch {
|
|
733
|
-
path = resolveAdapterManifest(adapter, provider);
|
|
734
|
-
}
|
|
735
|
-
const manifest = readJson(path);
|
|
736
|
-
const { absolutejs } = manifest;
|
|
737
|
-
const devices = object2(absolutejs) ? absolutejs.devices : undefined;
|
|
738
|
-
if (!object2(devices) || devices.format !== 1 || devices.provider !== provider || !object2(devices.capabilities))
|
|
739
|
-
throw new TypeError(`${adapter} does not publish supported capability metadata.`);
|
|
740
|
-
const entries = Object.entries(devices.capabilities).map(([name, capability]) => ({
|
|
741
|
-
name,
|
|
742
|
-
provider: parseProvider(name, capability, provider)
|
|
743
|
-
}));
|
|
744
|
-
return Object.fromEntries(entries.sort((left, right) => left.name.localeCompare(right.name)).map(({ name, provider: capabilityProvider }) => [
|
|
745
|
-
name,
|
|
746
|
-
capabilityProvider
|
|
747
|
-
]));
|
|
748
|
-
};
|
|
749
|
-
var isIgnored = (path) => path.split("/").some((segment) => IGNORED_DIRECTORIES.has(segment));
|
|
750
|
-
var importedCapabilities = (source, file) => {
|
|
751
|
-
const names = new Set;
|
|
752
|
-
const namespaces = new Set;
|
|
753
|
-
const visit = (node) => {
|
|
754
|
-
if (lazyTypescript.isImportDeclaration(node) && lazyTypescript.isStringLiteral(node.moduleSpecifier) && node.moduleSpecifier.text === DEVICES_PACKAGE && !node.importClause?.isTypeOnly) {
|
|
755
|
-
const bindings = node.importClause?.namedBindings;
|
|
756
|
-
if (bindings && lazyTypescript.isNamedImports(bindings)) {
|
|
757
|
-
for (const element of bindings.elements)
|
|
758
|
-
if (!element.isTypeOnly)
|
|
759
|
-
names.add((element.propertyName ?? element.name).text);
|
|
760
|
-
}
|
|
761
|
-
if (bindings && lazyTypescript.isNamespaceImport(bindings))
|
|
762
|
-
namespaces.add(bindings.name.text);
|
|
763
|
-
}
|
|
764
|
-
if (lazyTypescript.isExportDeclaration(node) && !node.isTypeOnly && node.moduleSpecifier !== undefined && lazyTypescript.isStringLiteral(node.moduleSpecifier) && node.moduleSpecifier.text === DEVICES_PACKAGE && node.exportClause && lazyTypescript.isNamedExports(node.exportClause)) {
|
|
765
|
-
for (const element of node.exportClause.elements)
|
|
766
|
-
if (!element.isTypeOnly)
|
|
767
|
-
names.add((element.propertyName ?? element.name).text);
|
|
768
|
-
}
|
|
769
|
-
if (lazyTypescript.isPropertyAccessExpression(node) && lazyTypescript.isIdentifier(node.expression) && namespaces.has(node.expression.text))
|
|
770
|
-
names.add(node.name.text);
|
|
771
|
-
lazyTypescript.forEachChild(node, visit);
|
|
772
|
-
};
|
|
773
|
-
const extension = extname(file).toLowerCase();
|
|
774
|
-
const sources = extension === ".svelte" || extension === ".vue" ? [...source.matchAll(/<script\b[^>]*>([\s\S]*?)<\/script\s*>/giu)].map((match) => match[1]).filter((value) => value !== undefined) : [source];
|
|
775
|
-
for (const [index, script] of sources.entries())
|
|
776
|
-
visit(lazyTypescript.createSourceFile(`${file}#script-${index}`, script, lazyTypescript.ScriptTarget.Latest, true, lazyTypescript.ScriptKind.TSX));
|
|
777
|
-
return names;
|
|
778
|
-
};
|
|
779
|
-
var assertAbsoluteDeviceCapabilityPackages = (projectRoot, plan) => {
|
|
780
|
-
const missing = missingAbsoluteDeviceCapabilityPackages(plan, directAbsoluteProjectPackages(projectRoot));
|
|
781
|
-
const mismatched = plan.requiredPackages.filter((spec) => {
|
|
782
|
-
const separator = spec.lastIndexOf("@");
|
|
783
|
-
const packageName = spec.slice(0, separator);
|
|
784
|
-
if (missing.includes(spec))
|
|
785
|
-
return false;
|
|
786
|
-
try {
|
|
787
|
-
return readJson(join3(resolve3(projectRoot), "node_modules", packageName, "package.json")).version !== spec.slice(separator + 1);
|
|
788
|
-
} catch {
|
|
789
|
-
return true;
|
|
790
|
-
}
|
|
791
|
-
});
|
|
792
|
-
const unmet = [...missing, ...mismatched];
|
|
793
|
-
if (unmet.length > 0)
|
|
794
|
-
throw new TypeError(`Device capabilities ${plan.capabilities.join(", ")} require ${unmet.join(", ")}. Run absolute mobile sync and approve the detected capability plugins.`);
|
|
795
|
-
};
|
|
796
|
-
var directAbsoluteProjectPackages = (projectRoot) => {
|
|
797
|
-
const manifest = readJson(join3(resolve3(projectRoot), "package.json"));
|
|
798
|
-
const packages = new Set;
|
|
799
|
-
for (const field of ["dependencies", "devDependencies"]) {
|
|
800
|
-
const dependencies = manifest[field];
|
|
801
|
-
if (object2(dependencies))
|
|
802
|
-
for (const name of Object.keys(dependencies))
|
|
803
|
-
packages.add(name);
|
|
804
|
-
}
|
|
805
|
-
return packages;
|
|
806
|
-
};
|
|
807
|
-
var discoverAbsoluteDeviceCapabilities = (projectRoot, providers = loadAbsoluteDeviceCapabilityProviders(projectRoot)) => {
|
|
808
|
-
const root = resolve3(projectRoot);
|
|
809
|
-
if (!existsSync(root))
|
|
810
|
-
return [];
|
|
811
|
-
const known = new Set(Object.keys(providers));
|
|
812
|
-
const capabilities = new Set;
|
|
813
|
-
for (const path of SOURCE_GLOB.scanSync({ cwd: root })) {
|
|
814
|
-
const portable = relative(root, resolve3(root, path)).replaceAll("\\", "/");
|
|
815
|
-
if (isIgnored(portable))
|
|
816
|
-
continue;
|
|
817
|
-
const source = readFileSync2(resolve3(root, portable), "utf8");
|
|
818
|
-
for (const name of importedCapabilities(source, portable))
|
|
819
|
-
if (known.has(name))
|
|
820
|
-
capabilities.add(name);
|
|
821
|
-
}
|
|
822
|
-
return [...capabilities].sort();
|
|
823
|
-
};
|
|
824
|
-
var missingAbsoluteDeviceCapabilityPackages = (plan, directPackages) => plan.requiredPackages.filter((spec) => {
|
|
825
|
-
const packageName = spec.slice(0, spec.lastIndexOf("@"));
|
|
826
|
-
return !directPackages.has(packageName);
|
|
827
|
-
});
|
|
828
|
-
var resolveAbsoluteDeviceCapabilityPlan = (projectRoot, provider = "capacitor") => {
|
|
829
|
-
const allProviders = loadAbsoluteDeviceCapabilityProviders(projectRoot, provider);
|
|
830
|
-
const capabilities = discoverAbsoluteDeviceCapabilities(projectRoot, allProviders);
|
|
831
|
-
for (const capability of ABSOLUTE_MOBILE_SHELL_DEVICE_CAPABILITIES) {
|
|
832
|
-
if (allProviders[capability] && !capabilities.includes(capability))
|
|
833
|
-
capabilities.push(capability);
|
|
834
|
-
}
|
|
835
|
-
capabilities.sort();
|
|
836
|
-
const providers = {};
|
|
837
|
-
for (const name of capabilities) {
|
|
838
|
-
const capabilityProvider = allProviders[name];
|
|
839
|
-
if (capabilityProvider)
|
|
840
|
-
providers[name] = capabilityProvider;
|
|
841
|
-
}
|
|
842
|
-
return {
|
|
843
|
-
capabilities,
|
|
844
|
-
providers,
|
|
845
|
-
requiredPackages: [
|
|
846
|
-
...new Set(capabilities.flatMap((name) => providers[name]?.packages ?? []))
|
|
847
|
-
].sort()
|
|
848
|
-
};
|
|
849
|
-
};
|
|
850
|
-
|
|
851
105
|
// src/mobile/updateRuntime.ts
|
|
852
106
|
import { createHash } from "crypto";
|
|
853
107
|
|
|
@@ -862,11 +116,11 @@ var RELEASE_PATTERN = /^amu_[a-f0-9]{64}$/u;
|
|
|
862
116
|
var KEY_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/u;
|
|
863
117
|
var CHANNEL_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/u;
|
|
864
118
|
var isClassification = (value) => value === "bug-fix" || value === "content" || value === "security";
|
|
865
|
-
var
|
|
119
|
+
var object = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
866
120
|
var canonicalValue = (value) => {
|
|
867
121
|
if (Array.isArray(value))
|
|
868
122
|
return value.map(canonicalValue);
|
|
869
|
-
if (!
|
|
123
|
+
if (!object(value))
|
|
870
124
|
return value;
|
|
871
125
|
return Object.fromEntries(Object.keys(value).sort().map((key) => [key, canonicalValue(value[key])]));
|
|
872
126
|
};
|
|
@@ -885,7 +139,7 @@ var normalizeAbsoluteMobileUpdatePath = (value) => {
|
|
|
885
139
|
return path;
|
|
886
140
|
};
|
|
887
141
|
var parseFile = (value) => {
|
|
888
|
-
if (!
|
|
142
|
+
if (!object(value))
|
|
889
143
|
throw new TypeError("Update files must be objects.");
|
|
890
144
|
const path = normalizeAbsoluteMobileUpdatePath(value.path);
|
|
891
145
|
if (typeof value.bytes !== "number" || !Number.isSafeInteger(value.bytes) || value.bytes < 0 || value.bytes > ABSOLUTE_MOBILE_UPDATE_MAX_FILE_BYTES) {
|
|
@@ -896,7 +150,7 @@ var parseFile = (value) => {
|
|
|
896
150
|
return { bytes: value.bytes, path, sha256: value.sha256 };
|
|
897
151
|
};
|
|
898
152
|
var parseAbsoluteMobileUnsignedUpdateManifest = (value) => {
|
|
899
|
-
if (!
|
|
153
|
+
if (!object(value) || value.format !== ABSOLUTE_MOBILE_UPDATE_FORMAT)
|
|
900
154
|
throw new TypeError("Invalid AbsoluteJS mobile update manifest.");
|
|
901
155
|
const appId = requireText(value.appId, "Update appId");
|
|
902
156
|
const channel = requireText(value.channel, "Update channel");
|
|
@@ -938,11 +192,11 @@ var parseAbsoluteMobileUnsignedUpdateManifest = (value) => {
|
|
|
938
192
|
};
|
|
939
193
|
};
|
|
940
194
|
var parseAbsoluteMobileUpdateManifest = (value) => {
|
|
941
|
-
if (!
|
|
195
|
+
if (!object(value))
|
|
942
196
|
throw new TypeError("Invalid AbsoluteJS mobile update manifest.");
|
|
943
197
|
const { signature: signatureValue, ...unsignedValue } = value;
|
|
944
198
|
const unsigned = parseAbsoluteMobileUnsignedUpdateManifest(unsignedValue);
|
|
945
|
-
if (!
|
|
199
|
+
if (!object(signatureValue))
|
|
946
200
|
throw new TypeError("Update signature is missing.");
|
|
947
201
|
if (signatureValue.algorithm !== ABSOLUTE_MOBILE_UPDATE_SIGNATURE_ALGORITHM)
|
|
948
202
|
throw new TypeError("Update signature algorithm is unsupported.");
|
|
@@ -1013,7 +267,7 @@ var resolveAbsoluteMobileUpdateRuntime = (config, projectRoot) => {
|
|
|
1013
267
|
};
|
|
1014
268
|
|
|
1015
269
|
// src/mobile/expoNativeObservability.ts
|
|
1016
|
-
import { join as
|
|
270
|
+
import { join as join2 } from "path";
|
|
1017
271
|
var HEADER = `// Generated by AbsoluteJS. Edit absolute.config.ts, then run absolute mobile sync.
|
|
1018
272
|
`;
|
|
1019
273
|
var XML_HEADER = `<!-- Generated by AbsoluteJS. Edit absolute.config.ts, then run absolute mobile sync. -->
|
|
@@ -1455,31 +709,31 @@ export const enqueueAbsoluteExpoNativeObservabilityForTesting = async (testId: s
|
|
|
1455
709
|
`;
|
|
1456
710
|
var absoluteExpoNativeObservabilityFiles = (project) => new Map([
|
|
1457
711
|
[
|
|
1458
|
-
|
|
712
|
+
join2(project, "modules/absolute-mobile-observability/expo-module.config.json"),
|
|
1459
713
|
moduleConfig
|
|
1460
714
|
],
|
|
1461
715
|
[
|
|
1462
|
-
|
|
716
|
+
join2(project, "modules/absolute-mobile-observability/ios/AbsoluteMobileObservability.podspec"),
|
|
1463
717
|
podspec
|
|
1464
718
|
],
|
|
1465
719
|
[
|
|
1466
|
-
|
|
720
|
+
join2(project, "modules/absolute-mobile-observability/ios/AbsoluteMobileObservabilityModule.swift"),
|
|
1467
721
|
iosModule
|
|
1468
722
|
],
|
|
1469
723
|
[
|
|
1470
|
-
|
|
724
|
+
join2(project, "modules/absolute-mobile-observability/android/build.gradle"),
|
|
1471
725
|
androidBuild
|
|
1472
726
|
],
|
|
1473
727
|
[
|
|
1474
|
-
|
|
728
|
+
join2(project, "modules/absolute-mobile-observability/android/src/main/AndroidManifest.xml"),
|
|
1475
729
|
androidManifest
|
|
1476
730
|
],
|
|
1477
731
|
[
|
|
1478
|
-
|
|
732
|
+
join2(project, "modules/absolute-mobile-observability/android/src/main/java/expo/modules/absolutemobileobservability/AbsoluteMobileObservabilityModule.kt"),
|
|
1479
733
|
androidModule
|
|
1480
734
|
],
|
|
1481
735
|
[
|
|
1482
|
-
|
|
736
|
+
join2(project, "src/generated/AbsoluteNativeObservability.ts"),
|
|
1483
737
|
expoNativeObservabilityRuntimeSource
|
|
1484
738
|
]
|
|
1485
739
|
]);
|
|
@@ -1488,7 +742,7 @@ var absoluteExpoNativeObservabilityPaths = (project) => [
|
|
|
1488
742
|
];
|
|
1489
743
|
|
|
1490
744
|
// src/mobile/expoActivityResultRecovery.ts
|
|
1491
|
-
import { join as
|
|
745
|
+
import { join as join3 } from "path";
|
|
1492
746
|
var HEADER2 = `// Generated by AbsoluteJS. Edit absolute.config.ts, then run absolute mobile sync.
|
|
1493
747
|
`;
|
|
1494
748
|
var XML_HEADER2 = `<!-- Generated by AbsoluteJS. Edit absolute.config.ts, then run absolute mobile sync. -->
|
|
@@ -1725,37 +979,37 @@ export const takeAbsoluteActivityResultCancellation = () =>
|
|
|
1725
979
|
`;
|
|
1726
980
|
var absoluteExpoActivityResultRecoveryFiles = (project) => new Map([
|
|
1727
981
|
[
|
|
1728
|
-
|
|
982
|
+
join3(project, "modules/absolute-activity-result-recovery/expo-module.config.json"),
|
|
1729
983
|
moduleConfig2
|
|
1730
984
|
],
|
|
1731
985
|
[
|
|
1732
|
-
|
|
986
|
+
join3(project, "modules/absolute-activity-result-recovery/ios/AbsoluteActivityResultRecovery.podspec"),
|
|
1733
987
|
podspec2
|
|
1734
988
|
],
|
|
1735
989
|
[
|
|
1736
|
-
|
|
990
|
+
join3(project, "modules/absolute-activity-result-recovery/ios/AbsoluteActivityResultRecoveryModule.swift"),
|
|
1737
991
|
iosModule2
|
|
1738
992
|
],
|
|
1739
993
|
[
|
|
1740
|
-
|
|
994
|
+
join3(project, "modules/absolute-activity-result-recovery/android/build.gradle"),
|
|
1741
995
|
androidBuild2
|
|
1742
996
|
],
|
|
1743
997
|
[
|
|
1744
|
-
|
|
998
|
+
join3(project, "modules/absolute-activity-result-recovery/android/src/main/AndroidManifest.xml"),
|
|
1745
999
|
androidManifest2
|
|
1746
1000
|
],
|
|
1747
1001
|
[
|
|
1748
|
-
|
|
1002
|
+
join3(project, "modules/absolute-activity-result-recovery/android/src/main/java/expo/modules/absoluteactivityresultrecovery/AbsoluteActivityResultRecoveryModule.kt"),
|
|
1749
1003
|
androidModule2
|
|
1750
1004
|
],
|
|
1751
1005
|
[
|
|
1752
|
-
|
|
1006
|
+
join3(project, "src/generated/AbsoluteActivityResultRecovery.ts"),
|
|
1753
1007
|
runtime
|
|
1754
1008
|
]
|
|
1755
1009
|
]);
|
|
1756
1010
|
|
|
1757
1011
|
// src/mobile/expoEmbeddedAssets.ts
|
|
1758
|
-
import { join as
|
|
1012
|
+
import { join as join4 } from "path";
|
|
1759
1013
|
var header = `// Generated by AbsoluteJS. Edit absolute.config.ts, then run absolute mobile sync.
|
|
1760
1014
|
`;
|
|
1761
1015
|
var android = `${header}package expo.modules.absoluteembeddedassets
|
|
@@ -1969,10 +1223,10 @@ export const registerAbsoluteEmbeddedBundle = async (rootUri: string, paths: str
|
|
|
1969
1223
|
};
|
|
1970
1224
|
`;
|
|
1971
1225
|
var absoluteExpoEmbeddedAssetsFiles = (project) => {
|
|
1972
|
-
const root =
|
|
1226
|
+
const root = join4(project, "modules/absolute-embedded-assets");
|
|
1973
1227
|
return new Map([
|
|
1974
1228
|
[
|
|
1975
|
-
|
|
1229
|
+
join4(root, "expo-module.config.json"),
|
|
1976
1230
|
`${JSON.stringify({
|
|
1977
1231
|
android: {
|
|
1978
1232
|
modules: [
|
|
@@ -1984,7 +1238,7 @@ var absoluteExpoEmbeddedAssetsFiles = (project) => {
|
|
|
1984
1238
|
`
|
|
1985
1239
|
],
|
|
1986
1240
|
[
|
|
1987
|
-
|
|
1241
|
+
join4(root, "android/build.gradle"),
|
|
1988
1242
|
`${header}plugins { id 'com.android.library'; id 'expo-module-gradle-plugin' }
|
|
1989
1243
|
group = 'expo.modules.absoluteembeddedassets'
|
|
1990
1244
|
version = '0.0.1'
|
|
@@ -2000,16 +1254,16 @@ dependencies {
|
|
|
2000
1254
|
`
|
|
2001
1255
|
],
|
|
2002
1256
|
[
|
|
2003
|
-
|
|
1257
|
+
join4(root, "android/src/main/AndroidManifest.xml"),
|
|
2004
1258
|
`<manifest xmlns:android="http://schemas.android.com/apk/res/android" />
|
|
2005
1259
|
`
|
|
2006
1260
|
],
|
|
2007
1261
|
[
|
|
2008
|
-
|
|
1262
|
+
join4(root, "android/src/main/java/expo/modules/absoluteembeddedassets/AbsoluteEmbeddedAssetsModule.kt"),
|
|
2009
1263
|
android
|
|
2010
1264
|
],
|
|
2011
|
-
[
|
|
2012
|
-
[
|
|
1265
|
+
[join4(project, "plugins/withAbsoluteEmbeddedAssets.js"), plugin],
|
|
1266
|
+
[join4(project, "src/generated/AbsoluteEmbeddedAssets.ts"), runtime2]
|
|
2013
1267
|
]);
|
|
2014
1268
|
};
|
|
2015
1269
|
|
|
@@ -2024,7 +1278,7 @@ import {
|
|
|
2024
1278
|
rm,
|
|
2025
1279
|
writeFile
|
|
2026
1280
|
} from "fs/promises";
|
|
2027
|
-
import { dirname as
|
|
1281
|
+
import { dirname as dirname2, join as join5, relative, resolve as resolve2 } from "path";
|
|
2028
1282
|
var ABSOLUTE_MOBILE_BRANDING_FORMAT = 1;
|
|
2029
1283
|
var ABSOLUTE_CAPACITOR_ASSETS_VERSION = "3.0.5";
|
|
2030
1284
|
var ABSOLUTE_CAPACITOR_ASSETS_SPEC = `@capacitor/assets@${ABSOLUTE_CAPACITOR_ASSETS_VERSION}`;
|
|
@@ -2047,8 +1301,8 @@ var exists = async (path) => {
|
|
|
2047
1301
|
return false;
|
|
2048
1302
|
}
|
|
2049
1303
|
};
|
|
2050
|
-
var portableRelative = (root, path) =>
|
|
2051
|
-
var absoluteMobileBrandingManifestPath = (projectRoot) =>
|
|
1304
|
+
var portableRelative = (root, path) => relative(root, path).replaceAll("\\", "/");
|
|
1305
|
+
var absoluteMobileBrandingManifestPath = (projectRoot) => join5(resolve2(projectRoot), ".absolutejs", "mobile", "branding", "manifest.json");
|
|
2052
1306
|
var brandingEntries = (branding) => [
|
|
2053
1307
|
{ kind: "icon", path: branding.icon, size: ICON_SIZE },
|
|
2054
1308
|
branding.android.foreground ? {
|
|
@@ -2141,7 +1395,7 @@ var createAbsoluteMobileBrandingManifest = async (config, projectRoot) => {
|
|
|
2141
1395
|
};
|
|
2142
1396
|
var writeManifest = async (projectRoot, manifest) => {
|
|
2143
1397
|
const destination = absoluteMobileBrandingManifestPath(projectRoot);
|
|
2144
|
-
await mkdir(
|
|
1398
|
+
await mkdir(dirname2(destination), { recursive: true });
|
|
2145
1399
|
const temporary = `${destination}.${crypto.randomUUID()}.tmp`;
|
|
2146
1400
|
await writeFile(temporary, `${JSON.stringify(manifest, null, 2)}
|
|
2147
1401
|
`, {
|
|
@@ -2151,7 +1405,7 @@ var writeManifest = async (projectRoot, manifest) => {
|
|
|
2151
1405
|
return destination;
|
|
2152
1406
|
};
|
|
2153
1407
|
var copyManaged = async (source, destination) => {
|
|
2154
|
-
await mkdir(
|
|
1408
|
+
await mkdir(dirname2(destination), { recursive: true });
|
|
2155
1409
|
await copyFile(source, destination);
|
|
2156
1410
|
};
|
|
2157
1411
|
var absoluteExpoBrandingConfig = (config) => {
|
|
@@ -2195,10 +1449,10 @@ var writeAbsoluteExpoBrandingInputs = async (config, projectRoot) => {
|
|
|
2195
1449
|
if (!branding)
|
|
2196
1450
|
return;
|
|
2197
1451
|
const manifest = await createAbsoluteMobileBrandingManifest(config, projectRoot);
|
|
2198
|
-
const destination =
|
|
1452
|
+
const destination = join5(config.nativeProjectDirectory, "assets", "absolute-branding");
|
|
2199
1453
|
await rm(destination, { force: true, recursive: true });
|
|
2200
1454
|
await mkdir(destination, { recursive: true });
|
|
2201
|
-
await copyManaged(branding.icon,
|
|
1455
|
+
await copyManaged(branding.icon, join5(destination, "icon.png"));
|
|
2202
1456
|
const copies = [
|
|
2203
1457
|
[branding.android.backgroundImage, "android-background.png"],
|
|
2204
1458
|
[branding.android.foreground, "android-foreground.png"],
|
|
@@ -2208,19 +1462,19 @@ var writeAbsoluteExpoBrandingInputs = async (config, projectRoot) => {
|
|
|
2208
1462
|
[branding.splash.image, "splash-light.png"],
|
|
2209
1463
|
[branding.splash.darkImage, "splash-dark.png"]
|
|
2210
1464
|
];
|
|
2211
|
-
await Promise.all(copies.map(([source, name]) => source ? copyManaged(source,
|
|
1465
|
+
await Promise.all(copies.map(([source, name]) => source ? copyManaged(source, join5(destination, name)) : undefined));
|
|
2212
1466
|
await writeManifest(projectRoot, manifest);
|
|
2213
1467
|
return { manifest, path: destination };
|
|
2214
1468
|
};
|
|
2215
1469
|
var stageCapacitorInputs = async (branding, projectRoot) => {
|
|
2216
|
-
const destination =
|
|
1470
|
+
const destination = join5(projectRoot, ".absolutejs", "mobile", "branding", "input");
|
|
2217
1471
|
await rm(destination, { force: true, recursive: true });
|
|
2218
1472
|
await mkdir(destination, { recursive: true });
|
|
2219
|
-
await copyManaged(branding.icon,
|
|
1473
|
+
await copyManaged(branding.icon, join5(destination, "logo.png"));
|
|
2220
1474
|
if (branding.splash.image)
|
|
2221
|
-
await copyManaged(branding.splash.image,
|
|
1475
|
+
await copyManaged(branding.splash.image, join5(destination, "splash.png"));
|
|
2222
1476
|
if (branding.splash.darkImage)
|
|
2223
|
-
await copyManaged(branding.splash.darkImage,
|
|
1477
|
+
await copyManaged(branding.splash.darkImage, join5(destination, "splash-dark.png"));
|
|
2224
1478
|
return destination;
|
|
2225
1479
|
};
|
|
2226
1480
|
var defaultRunner = async (command, options) => {
|
|
@@ -2247,20 +1501,20 @@ ${stderr}`))
|
|
|
2247
1501
|
};
|
|
2248
1502
|
var resizePng = async (source, destination, size) => {
|
|
2249
1503
|
const output = await new Bun.Image(await readFile2(source)).resize(size, size).png({ compressionLevel: 9 }).toBuffer();
|
|
2250
|
-
await mkdir(
|
|
1504
|
+
await mkdir(dirname2(destination), { recursive: true });
|
|
2251
1505
|
await writeFile(destination, output);
|
|
2252
1506
|
};
|
|
2253
1507
|
var applyAndroidLayers = async (branding, nativeDirectory) => {
|
|
2254
|
-
const resources =
|
|
1508
|
+
const resources = join5(nativeDirectory, "android", "app", "src", "main", "res");
|
|
2255
1509
|
await Promise.all(ANDROID_ADAPTIVE_SIZES.flatMap(([density, size]) => [
|
|
2256
1510
|
...branding.android.foreground ? [
|
|
2257
|
-
resizePng(branding.android.foreground,
|
|
1511
|
+
resizePng(branding.android.foreground, join5(resources, `mipmap-${density}`, "ic_launcher_foreground.png"), size)
|
|
2258
1512
|
] : [],
|
|
2259
1513
|
...branding.android.backgroundImage ? [
|
|
2260
|
-
resizePng(branding.android.backgroundImage,
|
|
1514
|
+
resizePng(branding.android.backgroundImage, join5(resources, `mipmap-${density}`, "ic_launcher_background.png"), size)
|
|
2261
1515
|
] : [],
|
|
2262
1516
|
...branding.android.monochrome ? [
|
|
2263
|
-
resizePng(branding.android.monochrome,
|
|
1517
|
+
resizePng(branding.android.monochrome, join5(resources, `mipmap-${density}`, "ic_launcher_monochrome.png"), size)
|
|
2264
1518
|
] : []
|
|
2265
1519
|
]));
|
|
2266
1520
|
if (!branding.android.monochrome)
|
|
@@ -2272,13 +1526,13 @@ var applyAndroidLayers = async (branding, nativeDirectory) => {
|
|
|
2272
1526
|
<monochrome android:drawable="@mipmap/ic_launcher_monochrome" />
|
|
2273
1527
|
</adaptive-icon>
|
|
2274
1528
|
`;
|
|
2275
|
-
await Promise.all(["ic_launcher.xml", "ic_launcher_round.xml"].map((name) => writeFile(
|
|
1529
|
+
await Promise.all(["ic_launcher.xml", "ic_launcher_round.xml"].map((name) => writeFile(join5(resources, "mipmap-anydpi-v26", name), iconXml)));
|
|
2276
1530
|
};
|
|
2277
1531
|
var applyIosAppearances = async (branding, nativeDirectory) => {
|
|
2278
1532
|
if (!branding.ios.darkIcon && !branding.ios.tintedIcon)
|
|
2279
1533
|
return;
|
|
2280
|
-
const assetSet =
|
|
2281
|
-
const contentsPath =
|
|
1534
|
+
const assetSet = join5(nativeDirectory, "ios", "App", "App", "Assets.xcassets", "AppIcon.appiconset");
|
|
1535
|
+
const contentsPath = join5(assetSet, "Contents.json");
|
|
2282
1536
|
const contents = JSON.parse(await readFile2(contentsPath, "utf8"));
|
|
2283
1537
|
const images = typeof contents === "object" && contents !== null ? Reflect.get(contents, "images") : undefined;
|
|
2284
1538
|
if (typeof contents !== "object" || contents === null || !Array.isArray(images))
|
|
@@ -2291,7 +1545,7 @@ var applyIosAppearances = async (branding, nativeDirectory) => {
|
|
|
2291
1545
|
if (!source)
|
|
2292
1546
|
return;
|
|
2293
1547
|
const filename = `AppIcon-1024-${appearance}.png`;
|
|
2294
|
-
await resizePng(source,
|
|
1548
|
+
await resizePng(source, join5(assetSet, filename), ICON_SIZE);
|
|
2295
1549
|
return {
|
|
2296
1550
|
appearances: [{ appearance: "luminosity", value: appearance }],
|
|
2297
1551
|
filename,
|
|
@@ -2313,7 +1567,7 @@ var applyIosAppearances = async (branding, nativeDirectory) => {
|
|
|
2313
1567
|
await writeFile(contentsPath, `${JSON.stringify(contents, null, 2)}
|
|
2314
1568
|
`);
|
|
2315
1569
|
};
|
|
2316
|
-
var nativeBrandingSentinels = (config, platforms) => platforms.map((platform) => platform === "android" ?
|
|
1570
|
+
var nativeBrandingSentinels = (config, platforms) => platforms.map((platform) => platform === "android" ? join5(config.nativeProjectDirectory, "android", "app", "src", "main", "res", "mipmap-xxxhdpi", "ic_launcher.png") : join5(config.nativeProjectDirectory, "ios", "App", "App", "Assets.xcassets", "AppIcon.appiconset", "AppIcon-512@2x.png"));
|
|
2317
1571
|
var requireGeneratedBranding = async (config, platforms) => {
|
|
2318
1572
|
const missing = (await Promise.all(nativeBrandingSentinels(config, platforms).map(async (path) => ({
|
|
2319
1573
|
path,
|
|
@@ -2358,9 +1612,9 @@ var generateAbsoluteCapacitorBranding = async (config, projectRoot, options = {}
|
|
|
2358
1612
|
"--assetPath",
|
|
2359
1613
|
portableRelative(projectRoot, input),
|
|
2360
1614
|
"--androidProject",
|
|
2361
|
-
portableRelative(projectRoot,
|
|
1615
|
+
portableRelative(projectRoot, join5(config.nativeProjectDirectory, "android")),
|
|
2362
1616
|
"--iosProject",
|
|
2363
|
-
portableRelative(projectRoot,
|
|
1617
|
+
portableRelative(projectRoot, join5(config.nativeProjectDirectory, "ios", "App")),
|
|
2364
1618
|
"--iconBackgroundColor",
|
|
2365
1619
|
branding.android.backgroundColor,
|
|
2366
1620
|
"--splashBackgroundColor",
|
|
@@ -2441,7 +1695,7 @@ var inspectAbsoluteMobileBranding = async (config, projectRoot) => {
|
|
|
2441
1695
|
status: "stale"
|
|
2442
1696
|
});
|
|
2443
1697
|
const nativeSentinels = config.engine === "expo" ? [
|
|
2444
|
-
|
|
1698
|
+
join5(config.nativeProjectDirectory, "assets", "absolute-branding", "icon.png")
|
|
2445
1699
|
] : nativeBrandingSentinels(config, config.platforms);
|
|
2446
1700
|
if ((await Promise.all(nativeSentinels.map((path) => exists(path)))).some((present) => !present))
|
|
2447
1701
|
return brandingInspection({
|
|
@@ -2474,7 +1728,7 @@ var renderAbsoluteMobileBrandingPreview = async (config, projectRoot) => {
|
|
|
2474
1728
|
const { branding } = config;
|
|
2475
1729
|
if (!branding)
|
|
2476
1730
|
throw new TypeError("mobile.branding is not configured.");
|
|
2477
|
-
const destination =
|
|
1731
|
+
const destination = join5(projectRoot, ".absolutejs", "mobile", "branding", "preview.html");
|
|
2478
1732
|
const icon = `data:image/png;base64,${(await readFile2(branding.icon)).toString("base64")}`;
|
|
2479
1733
|
const appName = escapeHtml(config.appName);
|
|
2480
1734
|
const html = `<!doctype html>
|
|
@@ -2484,7 +1738,7 @@ var renderAbsoluteMobileBrandingPreview = async (config, projectRoot) => {
|
|
|
2484
1738
|
<style>body{font:16px system-ui;margin:2rem;background:#eee;color:#111}main{display:flex;flex-wrap:wrap;gap:2rem}.card{background:white;border-radius:20px;padding:1.5rem;box-shadow:0 8px 30px #0002}.icon{width:192px;height:192px;object-fit:cover}.circle{border-radius:50%}.squircle{border-radius:24%}.splash{width:240px;height:480px;display:grid;place-items:center;background:${branding.splash.backgroundColor}}.splash img{width:${branding.splash.logoScale * 100}%}code{display:block;margin-top:1rem}</style>
|
|
2485
1739
|
<h1>${appName}</h1><main><section class="card"><img class="icon squircle" src="${icon}" alt="Square app icon preview"><code>Apple / legacy Android</code></section><section class="card"><img class="icon circle" src="${icon}" alt="Circular Android icon preview"><code>Android circular mask</code></section><section class="card splash"><img src="${icon}" alt="Launch screen preview"></section></main><p>Fingerprint: <code>${manifest.fingerprint}</code></p>
|
|
2486
1740
|
`;
|
|
2487
|
-
await mkdir(
|
|
1741
|
+
await mkdir(dirname2(destination), { recursive: true });
|
|
2488
1742
|
await writeFile(destination, html);
|
|
2489
1743
|
return destination;
|
|
2490
1744
|
};
|
|
@@ -2553,7 +1807,7 @@ var expoNativeDataManifest = (value) => {
|
|
|
2553
1807
|
};
|
|
2554
1808
|
};
|
|
2555
1809
|
var portableRelative2 = (from, destination) => {
|
|
2556
|
-
const value =
|
|
1810
|
+
const value = relative2(from, destination).replaceAll("\\", "/");
|
|
2557
1811
|
return value.startsWith(".") ? value : `./${value}`;
|
|
2558
1812
|
};
|
|
2559
1813
|
var routeSegments = (route) => {
|
|
@@ -2569,7 +1823,7 @@ var routeSegments = (route) => {
|
|
|
2569
1823
|
return segment;
|
|
2570
1824
|
});
|
|
2571
1825
|
};
|
|
2572
|
-
var routeFile = (project, route) =>
|
|
1826
|
+
var routeFile = (project, route) => join6(project, "app", ...routeSegments(route), "index.tsx");
|
|
2573
1827
|
var packageDependencies = (plan) => Object.fromEntries(plan.requiredPackages.map((spec) => {
|
|
2574
1828
|
const separator = spec.lastIndexOf("@");
|
|
2575
1829
|
return [spec.slice(0, separator), spec.slice(separator + 1)];
|
|
@@ -3916,8 +3170,8 @@ const styles = StyleSheet.create({
|
|
|
3916
3170
|
error: { color: '#b91c1c', fontSize: 16, textAlign: 'center' }
|
|
3917
3171
|
});
|
|
3918
3172
|
`;
|
|
3919
|
-
var nativeWrapperSource = (wrapper, module, runtime, route) => `${EXPO_GENERATED_HEADER}import ApplicationNativeRoute from ${JSON.stringify(portableRelative2(
|
|
3920
|
-
import { createAbsoluteNativeRoute, createAbsoluteNativeRouteErrorBoundary } from ${JSON.stringify(portableRelative2(
|
|
3173
|
+
var nativeWrapperSource = (wrapper, module, runtime, route) => `${EXPO_GENERATED_HEADER}import ApplicationNativeRoute from ${JSON.stringify(portableRelative2(dirname3(wrapper), module).replace(/\.(?:[cm]?[jt]sx?)$/u, ""))};
|
|
3174
|
+
import { createAbsoluteNativeRoute, createAbsoluteNativeRouteErrorBoundary } from ${JSON.stringify(portableRelative2(dirname3(wrapper), runtime).replace(/\.(?:[cm]?[jt]sx?)$/u, ""))};
|
|
3921
3175
|
|
|
3922
3176
|
export const ErrorBoundary = createAbsoluteNativeRouteErrorBoundary(${JSON.stringify(route)});
|
|
3923
3177
|
export default createAbsoluteNativeRoute(ApplicationNativeRoute, ${JSON.stringify(route)});
|
|
@@ -3959,7 +3213,7 @@ var expoTsConfig = (projectRoot, project, auth, sync) => ({
|
|
|
3959
3213
|
extends: "expo/tsconfig.base"
|
|
3960
3214
|
});
|
|
3961
3215
|
var writeManagedFile = async (path, source, force) => {
|
|
3962
|
-
await mkdir2(
|
|
3216
|
+
await mkdir2(dirname3(path), { recursive: true });
|
|
3963
3217
|
if (await exists2(path)) {
|
|
3964
3218
|
const current = await readFile3(path, "utf8");
|
|
3965
3219
|
if (current === source)
|
|
@@ -3986,7 +3240,7 @@ var pruneManagedFiles = async (paths) => {
|
|
|
3986
3240
|
return removed.filter(Boolean).length;
|
|
3987
3241
|
};
|
|
3988
3242
|
var pruneStaleManagedExpoRoutes = async (project, expected) => {
|
|
3989
|
-
const appDirectory =
|
|
3243
|
+
const appDirectory = join6(project, "app");
|
|
3990
3244
|
if (!await exists2(appDirectory))
|
|
3991
3245
|
return 0;
|
|
3992
3246
|
const files = await walkFiles(appDirectory);
|
|
@@ -4017,7 +3271,7 @@ export const ABSOLUTE_MOBILE_MANIFEST: AbsoluteMobileManifest | undefined = unde
|
|
|
4017
3271
|
var writeAbsoluteExpoProject2 = async (config, options) => {
|
|
4018
3272
|
if (config.engine !== "expo")
|
|
4019
3273
|
throw new TypeError("Expo project generation requires mobile.engine: expo.");
|
|
4020
|
-
const projectRoot =
|
|
3274
|
+
const projectRoot = resolve3(options.projectRoot);
|
|
4021
3275
|
const project = config.nativeProjectDirectory;
|
|
4022
3276
|
const auth = resolveAbsoluteMobileAuthManifest2(projectRoot, config);
|
|
4023
3277
|
const devices = resolveAbsoluteDeviceCapabilityPlan(projectRoot, "expo");
|
|
@@ -4034,7 +3288,7 @@ var writeAbsoluteExpoProject2 = async (config, options) => {
|
|
|
4034
3288
|
if (missing) {
|
|
4035
3289
|
throw new TypeError(`Expo native route ${missing.route} references missing module ${missing.module}.`);
|
|
4036
3290
|
}
|
|
4037
|
-
const marker =
|
|
3291
|
+
const marker = join6(project, EXPO_PROJECT_MARKER);
|
|
4038
3292
|
if (await exists2(project) && !await exists2(marker)) {
|
|
4039
3293
|
const entries = await readdir(project);
|
|
4040
3294
|
if (entries.length > 0 && !options.force) {
|
|
@@ -4047,7 +3301,7 @@ var writeAbsoluteExpoProject2 = async (config, options) => {
|
|
|
4047
3301
|
const authEnabled = Boolean(auth);
|
|
4048
3302
|
const files = new Map([
|
|
4049
3303
|
[
|
|
4050
|
-
|
|
3304
|
+
join6(project, ".gitignore"),
|
|
4051
3305
|
`.expo/
|
|
4052
3306
|
android/
|
|
4053
3307
|
ios/
|
|
@@ -4055,45 +3309,45 @@ node_modules/
|
|
|
4055
3309
|
`
|
|
4056
3310
|
],
|
|
4057
3311
|
[
|
|
4058
|
-
|
|
3312
|
+
join6(project, "app.json"),
|
|
4059
3313
|
jsonSource(expoAppConfig(config, authEnabled, syncEnabled, devices, runtimeFingerprint))
|
|
4060
3314
|
],
|
|
4061
|
-
[
|
|
3315
|
+
[join6(project, "app.config.js"), expoDynamicAppConfig],
|
|
4062
3316
|
[
|
|
4063
|
-
|
|
3317
|
+
join6(project, "package.json"),
|
|
4064
3318
|
jsonSource(expoPackage(authEnabled, config.branding !== undefined, syncEnabled, devices, config.updates !== undefined))
|
|
4065
3319
|
],
|
|
4066
|
-
[
|
|
3320
|
+
[join6(project, "metro.config.js"), metroConfig(projectRoot)],
|
|
4067
3321
|
[
|
|
4068
|
-
|
|
3322
|
+
join6(project, "plugins", "withAbsoluteDevelopmentCa.js"),
|
|
4069
3323
|
expoDevelopmentCaPlugin
|
|
4070
3324
|
],
|
|
4071
3325
|
[
|
|
4072
|
-
|
|
3326
|
+
join6(project, "plugins", "withAbsoluteActivityResultRecovery.js"),
|
|
4073
3327
|
expoActivityResultRecoveryPlugin
|
|
4074
3328
|
],
|
|
4075
3329
|
[
|
|
4076
|
-
|
|
3330
|
+
join6(project, "tsconfig.json"),
|
|
4077
3331
|
jsonSource(expoTsConfig(projectRoot, project, authEnabled, syncEnabled))
|
|
4078
3332
|
],
|
|
4079
3333
|
[
|
|
4080
|
-
|
|
3334
|
+
join6(project, "app", "_layout.tsx"),
|
|
4081
3335
|
layoutSource(authEnabled, syncEnabled, config.updates !== undefined, config.observability !== undefined)
|
|
4082
3336
|
],
|
|
4083
3337
|
[
|
|
4084
|
-
|
|
3338
|
+
join6(project, "app", "__absolute", "native", "index.tsx"),
|
|
4085
3339
|
nativeDiagnosticSource
|
|
4086
3340
|
],
|
|
4087
3341
|
[
|
|
4088
|
-
|
|
3342
|
+
join6(project, "src", "generated", "AbsoluteDevices.ts"),
|
|
4089
3343
|
devicesRuntimeSource(config, devices, authEnabled)
|
|
4090
3344
|
],
|
|
4091
3345
|
[
|
|
4092
|
-
|
|
3346
|
+
join6(project, "src", "generated", "AbsoluteNativeRoute.tsx"),
|
|
4093
3347
|
nativeRouteRuntimeSource(authEnabled)
|
|
4094
3348
|
],
|
|
4095
3349
|
[
|
|
4096
|
-
|
|
3350
|
+
join6(project, "src", "generated", "AbsoluteWebHost.tsx"),
|
|
4097
3351
|
webHostSource(config, auth, syncEnabled)
|
|
4098
3352
|
]
|
|
4099
3353
|
]);
|
|
@@ -4106,31 +3360,31 @@ node_modules/
|
|
|
4106
3360
|
files.set(path, source);
|
|
4107
3361
|
}
|
|
4108
3362
|
if (config.updates) {
|
|
4109
|
-
files.set(
|
|
3363
|
+
files.set(join6(project, "src", "generated", "AbsoluteUpdates.ts"), updatesRuntimeSource(config));
|
|
4110
3364
|
}
|
|
4111
3365
|
const expoCodeSigning = config.updates?.expoCodeSigning;
|
|
4112
3366
|
if (expoCodeSigning)
|
|
4113
|
-
files.set(
|
|
3367
|
+
files.set(join6(project, "certs", "absolute-mobile-update.pem"), expoCodeSigning.certificatePem);
|
|
4114
3368
|
if (auth) {
|
|
4115
|
-
files.set(
|
|
3369
|
+
files.set(join6(project, "src", "generated", "AbsoluteAuth.ts"), authRuntimeSource(auth, config.appId));
|
|
4116
3370
|
}
|
|
4117
3371
|
if (syncSchema) {
|
|
4118
|
-
files.set(
|
|
3372
|
+
files.set(join6(project, "src", "generated", "AbsoluteSync.ts"), syncRuntimeSource(config, syncSchema));
|
|
4119
3373
|
}
|
|
4120
|
-
const webAssetsPath =
|
|
3374
|
+
const webAssetsPath = join6(project, "src", "generated", "webAssets.ts");
|
|
4121
3375
|
if (!await exists2(webAssetsPath)) {
|
|
4122
3376
|
files.set(webAssetsPath, emptyWebAssetsSource);
|
|
4123
3377
|
}
|
|
4124
3378
|
if (!config.expoNativeRoutes["/"]) {
|
|
4125
|
-
files.set(
|
|
3379
|
+
files.set(join6(project, "app", "index.tsx"), webRouteSource);
|
|
4126
3380
|
}
|
|
4127
|
-
files.set(
|
|
4128
|
-
const nativeRouteRuntime =
|
|
3381
|
+
files.set(join6(project, "app", "[...absolute].tsx"), catchAllRouteSource);
|
|
3382
|
+
const nativeRouteRuntime = join6(project, "src", "generated", "AbsoluteNativeRoute.tsx");
|
|
4129
3383
|
for (const [route, module] of routeModules) {
|
|
4130
|
-
const wrapper = route === "/" ?
|
|
3384
|
+
const wrapper = route === "/" ? join6(project, "app", "index.tsx") : routeFile(project, route);
|
|
4131
3385
|
files.set(wrapper, nativeWrapperSource(wrapper, module, nativeRouteRuntime, route));
|
|
4132
3386
|
}
|
|
4133
|
-
const removedRoutes = await pruneStaleManagedExpoRoutes(project, new Set([...files.keys()].filter((path) => path.startsWith(`${
|
|
3387
|
+
const removedRoutes = await pruneStaleManagedExpoRoutes(project, new Set([...files.keys()].filter((path) => path.startsWith(`${join6(project, "app")}${sep}`))));
|
|
4134
3388
|
const removedObservability = config.observability ? 0 : await pruneManagedFiles(absoluteExpoNativeObservabilityPaths(project));
|
|
4135
3389
|
const changes = await Promise.all([...files].map(([path, source]) => writeManagedFile(path, source, true)));
|
|
4136
3390
|
await writeAbsoluteExpoBrandingInputs(config, projectRoot);
|
|
@@ -4140,7 +3394,7 @@ node_modules/
|
|
|
4140
3394
|
var walkFiles = async (root, directory = root) => {
|
|
4141
3395
|
const entries = await readdir(directory, { withFileTypes: true });
|
|
4142
3396
|
const nested = await Promise.all(entries.map((entry) => {
|
|
4143
|
-
const path =
|
|
3397
|
+
const path = join6(directory, entry.name);
|
|
4144
3398
|
if (entry.isDirectory())
|
|
4145
3399
|
return walkFiles(root, path);
|
|
4146
3400
|
if (entry.isFile())
|
|
@@ -4257,11 +3511,11 @@ export const materializeAbsoluteWebBundle = async () => {
|
|
|
4257
3511
|
var syncAbsoluteExpoWebAssets2 = async (config) => {
|
|
4258
3512
|
if (config.engine !== "expo")
|
|
4259
3513
|
throw new TypeError("Expo asset sync requires mobile.engine: expo.");
|
|
4260
|
-
const marker =
|
|
3514
|
+
const marker = join6(config.nativeProjectDirectory, EXPO_PROJECT_MARKER);
|
|
4261
3515
|
if (!await exists2(marker)) {
|
|
4262
3516
|
throw new TypeError("Expo asset sync requires an AbsoluteJS-managed Expo project. Run mobile init first.");
|
|
4263
3517
|
}
|
|
4264
|
-
const manifestPath =
|
|
3518
|
+
const manifestPath = join6(config.bundleDirectory, "absolute-mobile-manifest.json");
|
|
4265
3519
|
const manifest = JSON.parse(await readFile3(manifestPath, "utf8"));
|
|
4266
3520
|
const nativeDataManifest = expoNativeDataManifest(manifest);
|
|
4267
3521
|
const { appBuild } = nativeDataManifest;
|
|
@@ -4269,15 +3523,15 @@ var syncAbsoluteExpoWebAssets2 = async (config) => {
|
|
|
4269
3523
|
const bundleHash = createHash3("sha256");
|
|
4270
3524
|
const filesWithContents = await Promise.all(files.map(async (file) => ({ contents: await readFile3(file), file })));
|
|
4271
3525
|
filesWithContents.forEach(({ contents, file }) => {
|
|
4272
|
-
bundleHash.update(
|
|
3526
|
+
bundleHash.update(relative2(config.bundleDirectory, file).replaceAll("\\", "/"));
|
|
4273
3527
|
bundleHash.update("\x00");
|
|
4274
3528
|
bundleHash.update(contents);
|
|
4275
3529
|
bundleHash.update("\x00");
|
|
4276
3530
|
});
|
|
4277
3531
|
const bundleId = `amexpo_${bundleHash.digest("hex")}`;
|
|
4278
|
-
const destination =
|
|
4279
|
-
await mkdir2(
|
|
4280
|
-
const staging = await mkdtemp(
|
|
3532
|
+
const destination = join6(config.nativeProjectDirectory, "assets", "absolute");
|
|
3533
|
+
await mkdir2(dirname3(destination), { recursive: true });
|
|
3534
|
+
const staging = await mkdtemp(join6(dirname3(destination), `.${basename(destination)}.stage-`));
|
|
4281
3535
|
let assets;
|
|
4282
3536
|
let archiveAsset;
|
|
4283
3537
|
let archiveMd5;
|
|
@@ -4288,7 +3542,7 @@ var syncAbsoluteExpoWebAssets2 = async (config) => {
|
|
|
4288
3542
|
length: contents.byteLength,
|
|
4289
3543
|
md5: createHash3("md5").update(contents).digest("hex"),
|
|
4290
3544
|
offset,
|
|
4291
|
-
path:
|
|
3545
|
+
path: relative2(config.bundleDirectory, file).replaceAll("\\", "/")
|
|
4292
3546
|
};
|
|
4293
3547
|
offset += contents.byteLength;
|
|
4294
3548
|
return entry;
|
|
@@ -4296,16 +3550,16 @@ var syncAbsoluteExpoWebAssets2 = async (config) => {
|
|
|
4296
3550
|
const name = `bundle${EXPO_ASSET_EXTENSION}`;
|
|
4297
3551
|
const archiveContents = Buffer.concat(filesWithContents.map(({ contents }) => contents));
|
|
4298
3552
|
archiveMd5 = createHash3("md5").update(archiveContents).digest("hex");
|
|
4299
|
-
await writeFile2(
|
|
4300
|
-
archiveAsset = portableRelative2(
|
|
3553
|
+
await writeFile2(join6(staging, name), archiveContents);
|
|
3554
|
+
archiveAsset = portableRelative2(join6(config.nativeProjectDirectory, "src", "generated"), join6(destination, name));
|
|
4301
3555
|
await installStagedDirectory(staging, destination);
|
|
4302
3556
|
} catch (error) {
|
|
4303
3557
|
await rm2(staging, { force: true, recursive: true });
|
|
4304
3558
|
throw error;
|
|
4305
3559
|
}
|
|
4306
|
-
const generated =
|
|
3560
|
+
const generated = join6(config.nativeProjectDirectory, "src", "generated", "webAssets.ts");
|
|
4307
3561
|
await writeManagedFile(generated, assetModuleSource(assets, archiveAsset, bundleId, archiveMd5, nativeDataManifest), true);
|
|
4308
3562
|
return { appBuild, assets: assets.length, bundleId, path: destination };
|
|
4309
3563
|
};
|
|
4310
3564
|
|
|
4311
|
-
export { ABSOLUTE_DEPLOY_VERSION, ABSOLUTE_NATIVE_EXACT_PACKAGES, CAPACITOR_PACKAGE_SPECS, CAPACITOR_SYNC_PACKAGE_SPECS, EXPO_APP_EXACT_PACKAGES, EXPO_APP_PACKAGE_SPECS, EXPO_CODE_SIGNING_PACKAGE_SPEC, assertNativePackageVersions, packageNameFromSpec, packagesNeedingExactInstall,
|
|
3565
|
+
export { ABSOLUTE_DEPLOY_VERSION, ABSOLUTE_NATIVE_EXACT_PACKAGES, CAPACITOR_PACKAGE_SPECS, CAPACITOR_SYNC_PACKAGE_SPECS, EXPO_APP_EXACT_PACKAGES, EXPO_APP_PACKAGE_SPECS, EXPO_CODE_SIGNING_PACKAGE_SPEC, assertNativePackageVersions, packageNameFromSpec, packagesNeedingExactInstall, ABSOLUTE_MOBILE_UPDATE_FORMAT, absoluteMobileUpdateSigningPayload, canonicalizeAbsoluteMobileUpdate, parseAbsoluteMobileUpdateManifest, unsignedAbsoluteMobileUpdate, resolveAbsoluteMobileUpdateRuntime, ABSOLUTE_CAPACITOR_ASSETS_SPEC, generateAbsoluteCapacitorBranding, inspectAbsoluteMobileBranding, renderAbsoluteMobileBrandingPreview, writeAbsoluteExpoProject2, syncAbsoluteExpoWebAssets2 };
|