@hot-updater/firebase 1.0.0-rc.42 → 1.0.0-rc.44
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/firebase/functions/index.cjs +69 -108
- package/dist/index.cjs +4 -6
- package/dist/index.mjs +1 -3
- package/dist/init/index.cjs +15 -18
- package/dist/init/index.mjs +12 -15
- package/package.json +7 -7
|
@@ -1426,31 +1426,6 @@ var ReleaseCatalogMutationError = class extends Error {
|
|
|
1426
1426
|
}
|
|
1427
1427
|
};
|
|
1428
1428
|
//#endregion
|
|
1429
|
-
//#region ../plugin-core/dist/storageDownloadPath.mjs
|
|
1430
|
-
const decodeBase64Url$1 = (value) => {
|
|
1431
|
-
try {
|
|
1432
|
-
const base64 = value.replaceAll("-", "+").replaceAll("_", "/");
|
|
1433
|
-
const binary = atob(base64.padEnd(Math.ceil(base64.length / 4) * 4, "="));
|
|
1434
|
-
return new TextDecoder(void 0, { fatal: true }).decode(Uint8Array.from(binary, (character) => character.charCodeAt(0)));
|
|
1435
|
-
} catch {
|
|
1436
|
-
return null;
|
|
1437
|
-
}
|
|
1438
|
-
};
|
|
1439
|
-
const parseStorageDownloadPath = (path) => {
|
|
1440
|
-
const match = /^\/storage\/([^/]+)\/([^/]+)$/.exec(path);
|
|
1441
|
-
if (!match) return null;
|
|
1442
|
-
const storageUri = decodeBase64Url$1(match[1]);
|
|
1443
|
-
if (storageUri === null) return null;
|
|
1444
|
-
try {
|
|
1445
|
-
return {
|
|
1446
|
-
signature: decodeURIComponent(match[2]),
|
|
1447
|
-
storageUri
|
|
1448
|
-
};
|
|
1449
|
-
} catch {
|
|
1450
|
-
return null;
|
|
1451
|
-
}
|
|
1452
|
-
};
|
|
1453
|
-
//#endregion
|
|
1454
1429
|
//#region ../plugin-core/dist/serverPlugin/definePlugin.mjs
|
|
1455
1430
|
/** Declares a plugin; Hot Updater's own plugins and third-party ones use the same contract. */
|
|
1456
1431
|
const definePlugin = (plugin) => plugin;
|
|
@@ -4591,7 +4566,7 @@ const createKvAdapter = ({ store, tablePrefix = "" }) => {
|
|
|
4591
4566
|
};
|
|
4592
4567
|
//#endregion
|
|
4593
4568
|
//#region ../../packages/server/dist/version.mjs
|
|
4594
|
-
const HOT_UPDATER_SERVER_VERSION = "1.0.0-rc.
|
|
4569
|
+
const HOT_UPDATER_SERVER_VERSION = "1.0.0-rc.44";
|
|
4595
4570
|
//#endregion
|
|
4596
4571
|
//#region ../../packages/server/dist/handlerVersionRoutes.mjs
|
|
4597
4572
|
/**
|
|
@@ -6757,10 +6732,42 @@ const ORIGIN_CACHE_MAX_ENTRIES = 128;
|
|
|
6757
6732
|
const NO_CATALOG_HEADER = "x-hot-updater-catalog";
|
|
6758
6733
|
/** A shared cache keeps a catalog, or a scope's lack of one, five seconds. */
|
|
6759
6734
|
const CATALOG_CACHE_CONTROL = "public, max-age=0, s-maxage=5";
|
|
6735
|
+
/**
|
|
6736
|
+
* The same five seconds for a CDN that reads `CDN-Cache-Control` (RFC 9213),
|
|
6737
|
+
* such as Cloudflare's Workers Cache, which then ignores `Cache-Control`.
|
|
6738
|
+
* `s-maxage` forbids serving stale, so there an expired catalog held requests
|
|
6739
|
+
* at that location until the origin answered. Here, for five more seconds,
|
|
6740
|
+
* the CDN answers with the expired copy while it revalidates in the
|
|
6741
|
+
* background. `stale-if-error=0` keeps origin errors visible: without it,
|
|
6742
|
+
* Cloudflare serves a stale copy on error indefinitely.
|
|
6743
|
+
*
|
|
6744
|
+
* A device can see a catalog up to 15 seconds after a deploy or a Roll back
|
|
6745
|
+
* replaced it: the origin's 5-second catalog memo, then 5 seconds fresh and
|
|
6746
|
+
* 5 stale at the CDN. A revoked API key can read a cached catalog up to
|
|
6747
|
+
* 10 seconds. Devices and caches that don't read the header keep
|
|
6748
|
+
* `Cache-Control`.
|
|
6749
|
+
*/
|
|
6750
|
+
const CATALOG_CDN_CACHE_CONTROL = "public, max-age=5, stale-while-revalidate=5, stale-if-error=0";
|
|
6760
6751
|
const privateNotFound = () => Response.json({ error: "Not found" }, {
|
|
6761
6752
|
status: 404,
|
|
6762
6753
|
headers: { "cache-control": "private, no-store" }
|
|
6763
6754
|
});
|
|
6755
|
+
const badRequest = (error) => Response.json({ error }, {
|
|
6756
|
+
status: 400,
|
|
6757
|
+
headers: { "cache-control": "private, no-store" }
|
|
6758
|
+
});
|
|
6759
|
+
/**
|
|
6760
|
+
* A 400 for a catalog path whose scope is malformed, such as a channel name
|
|
6761
|
+
* where its base64url key belongs; null for a well-formed scope.
|
|
6762
|
+
*/
|
|
6763
|
+
const invalidScope = (input) => {
|
|
6764
|
+
try {
|
|
6765
|
+
createReleaseCatalogScopeKey(input);
|
|
6766
|
+
return null;
|
|
6767
|
+
} catch (error) {
|
|
6768
|
+
return badRequest(error instanceof Error ? error.message : "Invalid Release Catalog scope");
|
|
6769
|
+
}
|
|
6770
|
+
};
|
|
6764
6771
|
/**
|
|
6765
6772
|
* A scope with no catalog yet, such as a store version before its first
|
|
6766
6773
|
* OTA release: cached like a catalog, so its update checks don't all reach
|
|
@@ -6772,6 +6779,7 @@ const missingCatalog = () => Response.json({ error: "Not found" }, {
|
|
|
6772
6779
|
status: 404,
|
|
6773
6780
|
headers: {
|
|
6774
6781
|
"cache-control": CATALOG_CACHE_CONTROL,
|
|
6782
|
+
"cdn-cache-control": CATALOG_CDN_CACHE_CONTROL,
|
|
6775
6783
|
vary: "Accept-Encoding",
|
|
6776
6784
|
[NO_CATALOG_HEADER]: "none"
|
|
6777
6785
|
}
|
|
@@ -6786,6 +6794,7 @@ const catalogResponse = async (catalog, request) => {
|
|
|
6786
6794
|
const etag = `"sha256:${await responseHash(body)}"`;
|
|
6787
6795
|
const headers = {
|
|
6788
6796
|
"cache-control": CATALOG_CACHE_CONTROL,
|
|
6797
|
+
"cdn-cache-control": CATALOG_CDN_CACHE_CONTROL,
|
|
6789
6798
|
"content-type": CATALOG_CONTENT_TYPE,
|
|
6790
6799
|
etag,
|
|
6791
6800
|
vary: "Accept-Encoding"
|
|
@@ -6837,16 +6846,15 @@ const createReleaseCatalogRouteHandlers = () => {
|
|
|
6837
6846
|
appVersionReleaseCatalog: async (params, request, { core }) => {
|
|
6838
6847
|
const rawAppVersion = requireRouteParam(params, "appVersion");
|
|
6839
6848
|
const appVersion = canonicalizeAppVersion(rawAppVersion);
|
|
6840
|
-
if (appVersion === null || appVersion !== rawAppVersion) return
|
|
6841
|
-
status: 400,
|
|
6842
|
-
headers: { "cache-control": "private, no-store" }
|
|
6843
|
-
});
|
|
6849
|
+
if (appVersion === null || appVersion !== rawAppVersion) return badRequest("Invalid app version");
|
|
6844
6850
|
const input = {
|
|
6845
6851
|
appVersion,
|
|
6846
6852
|
channelKey: requireRouteParam(params, "channelKey"),
|
|
6847
6853
|
platform: requirePlatformParam(params),
|
|
6848
6854
|
strategy: "APP_VERSION"
|
|
6849
6855
|
};
|
|
6856
|
+
const invalid = invalidScope(input);
|
|
6857
|
+
if (invalid) return invalid;
|
|
6850
6858
|
return catalogResponse(await loadCatalog(`app-version:${JSON.stringify(input)}`, () => core.getReleaseCatalog(input)), request);
|
|
6851
6859
|
},
|
|
6852
6860
|
fingerprintReleaseCatalog: async (params, request, { core }) => {
|
|
@@ -6856,6 +6864,8 @@ const createReleaseCatalogRouteHandlers = () => {
|
|
|
6856
6864
|
platform: requirePlatformParam(params),
|
|
6857
6865
|
strategy: "FINGERPRINT"
|
|
6858
6866
|
};
|
|
6867
|
+
const invalid = invalidScope(input);
|
|
6868
|
+
if (invalid) return invalid;
|
|
6859
6869
|
return catalogResponse(await loadCatalog(`fingerprint:${JSON.stringify(input)}`, () => core.getReleaseCatalog(input)), request);
|
|
6860
6870
|
},
|
|
6861
6871
|
artifactV1: async (params, _request, { core }) => {
|
|
@@ -6937,8 +6947,8 @@ const errorResponse = (error, status) => Response.json({ error }, {
|
|
|
6937
6947
|
headers: { "cache-control": "private, no-store" },
|
|
6938
6948
|
status
|
|
6939
6949
|
});
|
|
6940
|
-
/** `/version`
|
|
6941
|
-
const PUBLIC_CLIENT_ROUTES = /* @__PURE__ */ new Set(["version"
|
|
6950
|
+
/** `/version` never passes through the client policy. */
|
|
6951
|
+
const PUBLIC_CLIENT_ROUTES = /* @__PURE__ */ new Set(["version"]);
|
|
6942
6952
|
const routesOf = Symbol.for("@hot-updater/server/routes");
|
|
6943
6953
|
const withVary = (response, varyHeaders) => {
|
|
6944
6954
|
const cacheControl = response.headers.get("cache-control") ?? "";
|
|
@@ -6983,26 +6993,11 @@ const createRequestHandler = ({ api, clientPolicy, privateResponses = false, rou
|
|
|
6983
6993
|
});
|
|
6984
6994
|
}
|
|
6985
6995
|
};
|
|
6986
|
-
|
|
6987
|
-
const token = params.token;
|
|
6988
|
-
const signature = params.signature;
|
|
6989
|
-
if (!token || !signature) return errorResponse("Not found", 404);
|
|
6990
|
-
const response = await downloadStorageObject(token, signature);
|
|
6991
|
-
if (!response) return errorResponse("Not found", 404);
|
|
6992
|
-
const headers = new Headers(response.headers);
|
|
6993
|
-
if (!headers.has("cache-control")) headers.set("cache-control", "public, max-age=31536000, immutable");
|
|
6994
|
-
return new Response(response.body, {
|
|
6995
|
-
headers,
|
|
6996
|
-
status: response.status,
|
|
6997
|
-
statusText: response.statusText
|
|
6998
|
-
});
|
|
6999
|
-
};
|
|
7000
|
-
function createHotUpdaterHandlers({ api, clientPolicy, downloadStorageObject, endpoints = [], plugins = [] }) {
|
|
6996
|
+
function createHotUpdaterHandlers({ api, clientPolicy, endpoints = [], plugins = [] }) {
|
|
7001
6997
|
const routeHandlers = {
|
|
7002
6998
|
...createVersionRouteHandlers(plugins),
|
|
7003
6999
|
...createReleaseCatalogRouteHandlers(),
|
|
7004
|
-
...createAdminRouteHandlers()
|
|
7005
|
-
...downloadStorageObject === void 0 ? {} : { downloadStorageObject: createDownloadStorageRouteHandler(downloadStorageObject) }
|
|
7000
|
+
...createAdminRouteHandlers()
|
|
7006
7001
|
};
|
|
7007
7002
|
const routes = [];
|
|
7008
7003
|
const shapes = /* @__PURE__ */ new Map();
|
|
@@ -7021,7 +7016,6 @@ function createHotUpdaterHandlers({ api, clientPolicy, downloadStorageObject, en
|
|
|
7021
7016
|
const clientRouter = createRouter();
|
|
7022
7017
|
const addClientRoute = mount(clientRouter, false);
|
|
7023
7018
|
addClientRoute("GET", "/version", "version");
|
|
7024
|
-
if (downloadStorageObject !== void 0) addClientRoute("GET", "/storage/:token/:signature", "downloadStorageObject");
|
|
7025
7019
|
addClientRoute("GET", "/release-catalogs/app-version/:platform/:channelKey/:appVersion", "appVersionReleaseCatalog");
|
|
7026
7020
|
addClientRoute("GET", "/release-catalogs/fingerprint/:platform/:channelKey/:fingerprintHash", "fingerprintReleaseCatalog");
|
|
7027
7021
|
addClientRoute("GET", "/artifacts/v1/:targetBundleId/from/:currentBundleId", "artifactV1");
|
|
@@ -7053,33 +7047,23 @@ function createHotUpdaterHandlers({ api, clientPolicy, downloadStorageObject, en
|
|
|
7053
7047
|
}
|
|
7054
7048
|
//#endregion
|
|
7055
7049
|
//#region ../../packages/server/dist/storageAccess.mjs
|
|
7050
|
+
/** A URL devices download from, which only an absolute HTTP(S) URL can be. */
|
|
7056
7051
|
const assertRemoteUrl = (value) => {
|
|
7057
|
-
|
|
7058
|
-
|
|
7052
|
+
let protocol;
|
|
7053
|
+
try {
|
|
7054
|
+
protocol = new URL(value).protocol;
|
|
7055
|
+
} catch {}
|
|
7056
|
+
if (protocol !== "http:" && protocol !== "https:") throw new Error("Storage getDownloadUrl must resolve to an absolute HTTP(S) URL.");
|
|
7059
7057
|
return value;
|
|
7060
7058
|
};
|
|
7061
7059
|
const getStorageProtocol = (storageUri) => new URL(storageUri).protocol.replace(":", "");
|
|
7062
7060
|
const isRemoteUrlProtocol = (protocol) => protocol === "http" || protocol === "https";
|
|
7063
|
-
|
|
7064
|
-
|
|
7065
|
-
|
|
7066
|
-
|
|
7067
|
-
|
|
7068
|
-
const
|
|
7069
|
-
const leftBytes = new TextEncoder().encode(left);
|
|
7070
|
-
const rightBytes = new TextEncoder().encode(right);
|
|
7071
|
-
let difference = leftBytes.length ^ rightBytes.length;
|
|
7072
|
-
const length = Math.max(leftBytes.length, rightBytes.length);
|
|
7073
|
-
for (let index = 0; index < length; index += 1) difference |= (leftBytes[index] ?? 0) ^ (rightBytes[index] ?? 0);
|
|
7074
|
-
return difference === 0;
|
|
7075
|
-
};
|
|
7076
|
-
const createStorageAccess = (storageAdapters) => {
|
|
7077
|
-
const protocols = /* @__PURE__ */ new Set();
|
|
7078
|
-
for (const storage of storageAdapters) {
|
|
7079
|
-
if (protocols.has(storage.protocol)) throw new Error(`Multiple storage adapters handle protocol: ${storage.protocol}`);
|
|
7080
|
-
protocols.add(storage.protocol);
|
|
7081
|
-
}
|
|
7082
|
-
const findStorage = (protocol) => storageAdapters.find((item) => item.protocol === protocol);
|
|
7061
|
+
/**
|
|
7062
|
+
* Reads and download URLs over the server's storage, for the URIs of its
|
|
7063
|
+
* protocol; an HTTP(S) URI is used as it is.
|
|
7064
|
+
*/
|
|
7065
|
+
const createStorageAccess = (storageAdapter) => {
|
|
7066
|
+
const findStorage = (protocol) => storageAdapter.protocol === protocol ? storageAdapter : void 0;
|
|
7083
7067
|
const readStorageResponse = async (storageUri) => {
|
|
7084
7068
|
const protocol = getStorageProtocol(storageUri);
|
|
7085
7069
|
const storage = findStorage(protocol);
|
|
@@ -7103,38 +7087,12 @@ const createStorageAccess = (storageAdapters) => {
|
|
|
7103
7087
|
}
|
|
7104
7088
|
if (!storage.getDownloadUrl) return null;
|
|
7105
7089
|
const { url: downloadUrl } = await storage.getDownloadUrl({ storageUri });
|
|
7106
|
-
|
|
7107
|
-
return assertRemoteUrl(downloadUrl);
|
|
7108
|
-
} catch (error) {
|
|
7109
|
-
if (/^[a-z][a-z\d+.-]*:/i.test(downloadUrl)) throw error;
|
|
7110
|
-
}
|
|
7111
|
-
return resolveDownloadPath(downloadUrl, storageUri);
|
|
7090
|
+
return assertRemoteUrl(downloadUrl);
|
|
7112
7091
|
};
|
|
7113
7092
|
const readStorageText = async (storageUri) => {
|
|
7114
7093
|
return (await readStorageResponse(storageUri))?.text() ?? null;
|
|
7115
7094
|
};
|
|
7116
7095
|
return {
|
|
7117
|
-
downloadStorageObject: storageAdapters.some((storage) => storage.getDownloadUrl !== void 0) ? async (storageUriToken, encodedSignature) => {
|
|
7118
|
-
const requestedPath = `/storage/${storageUriToken}/${encodedSignature}`;
|
|
7119
|
-
const requested = parseStorageDownloadPath(requestedPath);
|
|
7120
|
-
if (!requested) return null;
|
|
7121
|
-
let storage;
|
|
7122
|
-
try {
|
|
7123
|
-
storage = findStorage(getStorageProtocol(requested.storageUri));
|
|
7124
|
-
} catch {
|
|
7125
|
-
return null;
|
|
7126
|
-
}
|
|
7127
|
-
if (!storage?.getDownloadUrl || !storage.get) return null;
|
|
7128
|
-
const { url: downloadUrl } = await storage.getDownloadUrl({ storageUri: requested.storageUri });
|
|
7129
|
-
try {
|
|
7130
|
-
new URL(downloadUrl);
|
|
7131
|
-
return null;
|
|
7132
|
-
} catch {
|
|
7133
|
-
if (/^[a-z][a-z\d+.-]*:/i.test(downloadUrl)) return null;
|
|
7134
|
-
}
|
|
7135
|
-
if (!tokensEqual(downloadUrl, requestedPath)) return null;
|
|
7136
|
-
return (await storage.get({ storageUri: requested.storageUri })).response;
|
|
7137
|
-
} : void 0,
|
|
7138
7096
|
readStorageText,
|
|
7139
7097
|
resolveFileUrl
|
|
7140
7098
|
};
|
|
@@ -7156,17 +7114,21 @@ const databaseOf = (value) => {
|
|
|
7156
7114
|
}
|
|
7157
7115
|
throw new HotUpdaterConfigError("database must be a Hot Updater 1.0 database, such as kyselyAdapter(...) or postgres(...). Upgrade the provider package that created it.");
|
|
7158
7116
|
};
|
|
7159
|
-
/**
|
|
7117
|
+
/** The configured storage, when it is a storage adapter. */
|
|
7118
|
+
const storageOf = (value) => {
|
|
7119
|
+
if (isRecord$4(value) && typeof value.name === "string" && typeof value.protocol === "string") return value;
|
|
7120
|
+
throw new HotUpdaterConfigError("storage must be a storage adapter, such as s3Storage(...): the one hot-updater.config.ts uploads with.");
|
|
7121
|
+
};
|
|
7122
|
+
/** `"public"`, or nothing. */
|
|
7160
7123
|
const isPublic = (value) => {
|
|
7161
7124
|
if (value === void 0) return false;
|
|
7162
7125
|
if (value === "public") return true;
|
|
7163
|
-
throw new HotUpdaterConfigError(
|
|
7126
|
+
throw new HotUpdaterConfigError("clientAccess must be \"public\"; to protect client routes, add a plugin that provides clientAuth to plugins.");
|
|
7164
7127
|
};
|
|
7165
7128
|
function createHotUpdater(options) {
|
|
7166
|
-
for (const key of ["authorityId", "catalogId"]) if (Object.hasOwn(options, key)) throw new TypeError(`Remove ${key} from createHotUpdater options. Catalog identity is managed internally.`);
|
|
7167
7129
|
const database = databaseOf(options.database);
|
|
7168
|
-
const storage =
|
|
7169
|
-
const {
|
|
7130
|
+
const storage = storageOf(options.storage);
|
|
7131
|
+
const { readStorageText, resolveFileUrl } = createStorageAccess(storage);
|
|
7170
7132
|
const publicClients = isPublic(options.clientAccess);
|
|
7171
7133
|
const configured = Object.freeze([...options.plugins ?? []]);
|
|
7172
7134
|
const plugins = assemblePlugins(configured, database, { storage: {
|
|
@@ -7185,7 +7147,6 @@ function createHotUpdater(options) {
|
|
|
7185
7147
|
const handlers = createHotUpdaterHandlers({
|
|
7186
7148
|
api: { core: plugins.core },
|
|
7187
7149
|
...clientPolicy === void 0 ? {} : { clientPolicy },
|
|
7188
|
-
downloadStorageObject,
|
|
7189
7150
|
endpoints: plugins.endpoints,
|
|
7190
7151
|
plugins: Object.keys(plugins.api)
|
|
7191
7152
|
});
|
|
@@ -7194,7 +7155,7 @@ function createHotUpdater(options) {
|
|
|
7194
7155
|
adapterName: database.name,
|
|
7195
7156
|
get handlers() {
|
|
7196
7157
|
if (!serving) {
|
|
7197
|
-
|
|
7158
|
+
assertStorageOperations(storage, ["get", "getDownloadUrl"]);
|
|
7198
7159
|
serving = true;
|
|
7199
7160
|
}
|
|
7200
7161
|
return handlers;
|
|
@@ -11645,11 +11606,11 @@ if (!storageBucket) throw new Error("Firebase runtime requires storageBucket to
|
|
|
11645
11606
|
const hotUpdater = createHotUpdater({
|
|
11646
11607
|
database: firebaseDatabase({ ...adminOptions }),
|
|
11647
11608
|
plugins,
|
|
11648
|
-
storage:
|
|
11609
|
+
storage: firebaseStorage({
|
|
11649
11610
|
...adminOptions,
|
|
11650
11611
|
storageBucket,
|
|
11651
11612
|
cdnUrl
|
|
11652
|
-
})
|
|
11613
|
+
})
|
|
11653
11614
|
});
|
|
11654
11615
|
const app = new hono.Hono();
|
|
11655
11616
|
app.get("/ping", (c) => {
|
package/dist/index.cjs
CHANGED
|
@@ -4,9 +4,7 @@ let firebase_admin_app = require("firebase-admin/app");
|
|
|
4
4
|
let firebase_admin_firestore = require("firebase-admin/firestore");
|
|
5
5
|
let node_crypto = require("node:crypto");
|
|
6
6
|
let firebase_admin_storage = require("firebase-admin/storage");
|
|
7
|
-
let
|
|
8
|
-
let _hot_updater_server_plugins_insights = require("@hot-updater/server/plugins/insights");
|
|
9
|
-
let _hot_updater_server_plugins_remote_config = require("@hot-updater/server/plugins/remote-config");
|
|
7
|
+
let _hot_updater_server_plugins = require("@hot-updater/server/plugins");
|
|
10
8
|
//#region src/firebaseInfrastructureNames.ts
|
|
11
9
|
/**
|
|
12
10
|
* The one collection the storage engine keeps every item in. It namespaces
|
|
@@ -268,9 +266,9 @@ const firebaseStorage = (config) => {
|
|
|
268
266
|
* client route, and Remote Config. Its Cloud Function imports this list.
|
|
269
267
|
*/
|
|
270
268
|
const plugins = [
|
|
271
|
-
(0,
|
|
272
|
-
(0,
|
|
273
|
-
(0,
|
|
269
|
+
(0, _hot_updater_server_plugins.insights)(),
|
|
270
|
+
(0, _hot_updater_server_plugins.apiKeys)(),
|
|
271
|
+
(0, _hot_updater_server_plugins.remoteConfig)()
|
|
274
272
|
];
|
|
275
273
|
//#endregion
|
|
276
274
|
exports.firebaseDatabase = firebaseDatabase;
|
package/dist/index.mjs
CHANGED
|
@@ -3,9 +3,7 @@ import { getApp, getApps, initializeApp } from "firebase-admin/app";
|
|
|
3
3
|
import { FieldPath, FieldValue, Timestamp, getFirestore } from "firebase-admin/firestore";
|
|
4
4
|
import { createHash } from "node:crypto";
|
|
5
5
|
import { getStorage } from "firebase-admin/storage";
|
|
6
|
-
import { apiKeys } from "@hot-updater/server/plugins
|
|
7
|
-
import { insights } from "@hot-updater/server/plugins/insights";
|
|
8
|
-
import { remoteConfig } from "@hot-updater/server/plugins/remote-config";
|
|
6
|
+
import { apiKeys, insights, remoteConfig } from "@hot-updater/server/plugins";
|
|
9
7
|
//#region src/firebaseInfrastructureNames.ts
|
|
10
8
|
/**
|
|
11
9
|
* The one collection the storage engine keeps every item in. It namespaces
|
package/dist/init/index.cjs
CHANGED
|
@@ -50,9 +50,7 @@ let firebase_admin_app = require("firebase-admin/app");
|
|
|
50
50
|
let _hot_updater_plugin_core = require("@hot-updater/plugin-core");
|
|
51
51
|
let firebase_admin_firestore = require("firebase-admin/firestore");
|
|
52
52
|
let node_crypto = require("node:crypto");
|
|
53
|
-
let
|
|
54
|
-
let _hot_updater_server_plugins_insights = require("@hot-updater/server/plugins/insights");
|
|
55
|
-
let _hot_updater_server_plugins_remote_config = require("@hot-updater/server/plugins/remote-config");
|
|
53
|
+
let _hot_updater_server_plugins = require("@hot-updater/server/plugins");
|
|
56
54
|
let fs_promises = require("fs/promises");
|
|
57
55
|
fs_promises = __toESM(fs_promises, 1);
|
|
58
56
|
let node_fs_promises = require("node:fs/promises");
|
|
@@ -6904,9 +6902,9 @@ const firebaseDatabase = (config) => (0, _hot_updater_plugin_core.createEngineDa
|
|
|
6904
6902
|
* client route, and Remote Config. Its Cloud Function imports this list.
|
|
6905
6903
|
*/
|
|
6906
6904
|
const plugins = [
|
|
6907
|
-
(0,
|
|
6908
|
-
(0,
|
|
6909
|
-
(0,
|
|
6905
|
+
(0, _hot_updater_server_plugins.insights)(),
|
|
6906
|
+
(0, _hot_updater_server_plugins.apiKeys)(),
|
|
6907
|
+
(0, _hot_updater_server_plugins.remoteConfig)()
|
|
6910
6908
|
];
|
|
6911
6909
|
//#endregion
|
|
6912
6910
|
//#region iac/init/index.ts
|
|
@@ -7239,10 +7237,14 @@ const credential = applicationDefault();`.trim()
|
|
|
7239
7237
|
}];
|
|
7240
7238
|
const builder = new _hot_updater_cli_tools.ConfigBuilder().setBuildType(build).setStorage(storageConfig).setDatabase(databaseConfig).setPlugins({
|
|
7241
7239
|
imports: [{
|
|
7242
|
-
pkg: "
|
|
7243
|
-
named: [
|
|
7240
|
+
pkg: "hot-updater/plugins",
|
|
7241
|
+
named: [
|
|
7242
|
+
"apiKeys",
|
|
7243
|
+
"insights",
|
|
7244
|
+
"remoteConfig"
|
|
7245
|
+
]
|
|
7244
7246
|
}],
|
|
7245
|
-
configString: "
|
|
7247
|
+
configString: "[apiKeys(), insights(), remoteConfig()]"
|
|
7246
7248
|
}).addImport({
|
|
7247
7249
|
pkg: "firebase-admin/app",
|
|
7248
7250
|
named: ["applicationDefault"]
|
|
@@ -7262,15 +7264,10 @@ const setEnv = async ({ applicationCredentials, projectId, storageBucket, build,
|
|
|
7262
7264
|
HOT_UPDATER_FIREBASE_STORAGE_BUCKET: storageBucket
|
|
7263
7265
|
}, ".env.hotupdater", { preserveKeys: applicationCredentials ? [] : [initProvider.inputs.applicationCredentials.envKey] });
|
|
7264
7266
|
_hot_updater_cli_tools.p.log.success("Firebase credentials have been successfully configured.");
|
|
7265
|
-
|
|
7266
|
-
|
|
7267
|
-
|
|
7268
|
-
|
|
7269
|
-
});
|
|
7270
|
-
} catch (error) {
|
|
7271
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
7272
|
-
console.error("Error writing configuration file:", message);
|
|
7273
|
-
}
|
|
7267
|
+
await (0, _hot_updater_cli_tools.writeHotUpdaterFiles)(getConfigScaffold(build), {
|
|
7268
|
+
cwd: process.cwd(),
|
|
7269
|
+
settings: "Firebase"
|
|
7270
|
+
});
|
|
7274
7271
|
};
|
|
7275
7272
|
const handleError = (err) => {
|
|
7276
7273
|
if (err instanceof ExecaError) _hot_updater_cli_tools.p.log.error(err.stderr || err.stdout || err.message);
|
package/dist/init/index.mjs
CHANGED
|
@@ -21,9 +21,7 @@ import { applicationDefault, cert, deleteApp, getApp, getApps, initializeApp } f
|
|
|
21
21
|
import { SETTINGS_TABLE, coreSettings, createEngineDatabase, createKvAdapter, encodeKvKey, migrateCoreSchema } from "@hot-updater/plugin-core";
|
|
22
22
|
import { FieldPath, FieldValue, Timestamp, getFirestore } from "firebase-admin/firestore";
|
|
23
23
|
import { createHash } from "node:crypto";
|
|
24
|
-
import { apiKeys } from "@hot-updater/server/plugins
|
|
25
|
-
import { insights } from "@hot-updater/server/plugins/insights";
|
|
26
|
-
import { remoteConfig } from "@hot-updater/server/plugins/remote-config";
|
|
24
|
+
import { apiKeys, insights, remoteConfig } from "@hot-updater/server/plugins";
|
|
27
25
|
import fs$1 from "fs/promises";
|
|
28
26
|
import fs$2 from "node:fs/promises";
|
|
29
27
|
//#region \0rolldown/runtime.js
|
|
@@ -7232,10 +7230,14 @@ const credential = applicationDefault();`.trim()
|
|
|
7232
7230
|
}];
|
|
7233
7231
|
const builder = new ConfigBuilder().setBuildType(build).setStorage(storageConfig).setDatabase(databaseConfig).setPlugins({
|
|
7234
7232
|
imports: [{
|
|
7235
|
-
pkg: "
|
|
7236
|
-
named: [
|
|
7233
|
+
pkg: "hot-updater/plugins",
|
|
7234
|
+
named: [
|
|
7235
|
+
"apiKeys",
|
|
7236
|
+
"insights",
|
|
7237
|
+
"remoteConfig"
|
|
7238
|
+
]
|
|
7237
7239
|
}],
|
|
7238
|
-
configString: "
|
|
7240
|
+
configString: "[apiKeys(), insights(), remoteConfig()]"
|
|
7239
7241
|
}).addImport({
|
|
7240
7242
|
pkg: "firebase-admin/app",
|
|
7241
7243
|
named: ["applicationDefault"]
|
|
@@ -7255,15 +7257,10 @@ const setEnv = async ({ applicationCredentials, projectId, storageBucket, build,
|
|
|
7255
7257
|
HOT_UPDATER_FIREBASE_STORAGE_BUCKET: storageBucket
|
|
7256
7258
|
}, ".env.hotupdater", { preserveKeys: applicationCredentials ? [] : [initProvider.inputs.applicationCredentials.envKey] });
|
|
7257
7259
|
p.log.success("Firebase credentials have been successfully configured.");
|
|
7258
|
-
|
|
7259
|
-
|
|
7260
|
-
|
|
7261
|
-
|
|
7262
|
-
});
|
|
7263
|
-
} catch (error) {
|
|
7264
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
7265
|
-
console.error("Error writing configuration file:", message);
|
|
7266
|
-
}
|
|
7260
|
+
await writeHotUpdaterFiles(getConfigScaffold(build), {
|
|
7261
|
+
cwd: process.cwd(),
|
|
7262
|
+
settings: "Firebase"
|
|
7263
|
+
});
|
|
7267
7264
|
};
|
|
7268
7265
|
const handleError = (err) => {
|
|
7269
7266
|
if (err instanceof ExecaError) p.log.error(err.stderr || err.stdout || err.message);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hot-updater/firebase",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.0.0-rc.
|
|
4
|
+
"version": "1.0.0-rc.44",
|
|
5
5
|
"description": "React Native OTA solution for self-hosted",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
7
7
|
"types": "dist/index.d.cts",
|
|
@@ -37,10 +37,10 @@
|
|
|
37
37
|
],
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"hono": "4.12.34",
|
|
40
|
-
"@hot-updater/
|
|
41
|
-
"@hot-updater/
|
|
42
|
-
"@hot-updater/
|
|
43
|
-
"@hot-updater/server": "1.0.0-rc.
|
|
40
|
+
"@hot-updater/cli-tools": "1.0.0-rc.44",
|
|
41
|
+
"@hot-updater/protocol": "1.0.0-rc.44",
|
|
42
|
+
"@hot-updater/plugin-core": "1.0.0-rc.44",
|
|
43
|
+
"@hot-updater/server": "1.0.0-rc.44"
|
|
44
44
|
},
|
|
45
45
|
"publishConfig": {
|
|
46
46
|
"access": "public"
|
|
@@ -55,8 +55,8 @@
|
|
|
55
55
|
"firebase-tools": "15.29.0",
|
|
56
56
|
"fkill": "^9.0.0",
|
|
57
57
|
"mime": "^4.0.4",
|
|
58
|
-
"@hot-updater/mock": "1.0.0-rc.
|
|
59
|
-
"@hot-updater/test-utils": "1.0.0-rc.
|
|
58
|
+
"@hot-updater/mock": "1.0.0-rc.44",
|
|
59
|
+
"@hot-updater/test-utils": "1.0.0-rc.44"
|
|
60
60
|
},
|
|
61
61
|
"peerDependencies": {
|
|
62
62
|
"firebase-admin": "*",
|