@hot-updater/azure 1.2.0-rc.8 → 1.2.0-rc.9
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/functions/index.mjs +2 -3
- package/dist/index.cjs +81 -16
- package/dist/index.mjs +80 -15
- package/package.json +6 -6
package/dist/functions/index.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
2
|
import { EventEmitter } from "events";
|
|
3
|
+
import Stream, { Duplex, Readable, Transform } from "node:stream";
|
|
3
4
|
import { createCipheriv, createDecipheriv, createHash, createHmac, randomBytes } from "node:crypto";
|
|
4
5
|
import process$1 from "node:process";
|
|
5
6
|
import os, { EOL } from "node:os";
|
|
@@ -7,7 +8,6 @@ import util, { inspect } from "node:util";
|
|
|
7
8
|
import http from "node:http";
|
|
8
9
|
import https from "node:https";
|
|
9
10
|
import zlib from "node:zlib";
|
|
10
|
-
import Stream, { Duplex, Readable, Transform } from "node:stream";
|
|
11
11
|
import { Readable as Readable$1 } from "stream";
|
|
12
12
|
import buffer from "node:buffer";
|
|
13
13
|
import { Buffer as Buffer$1 } from "buffer";
|
|
@@ -8118,7 +8118,7 @@ const createKvAdapter = ({ store, tablePrefix = "" }) => {
|
|
|
8118
8118
|
};
|
|
8119
8119
|
//#endregion
|
|
8120
8120
|
//#region ../../packages/server/dist/version.mjs
|
|
8121
|
-
const HOT_UPDATER_SERVER_VERSION = "1.2.0-rc.
|
|
8121
|
+
const HOT_UPDATER_SERVER_VERSION = "1.2.0-rc.9";
|
|
8122
8122
|
//#endregion
|
|
8123
8123
|
//#region ../../packages/server/dist/handlerVersionRoutes.mjs
|
|
8124
8124
|
const createVersionRouteHandlers = (plugins = []) => {
|
|
@@ -57555,7 +57555,6 @@ function azureBlobStorage(config) {
|
|
|
57555
57555
|
const headers = new Headers();
|
|
57556
57556
|
if (download.contentType) headers.set("content-type", download.contentType);
|
|
57557
57557
|
if (download.contentLength !== void 0) headers.set("content-length", String(download.contentLength));
|
|
57558
|
-
const { Readable } = await import("node:stream");
|
|
57559
57558
|
return { response: new Response(Readable.toWeb(body), { headers }) };
|
|
57560
57559
|
} catch (error) {
|
|
57561
57560
|
if (isNotFound(error)) return { response: null };
|
package/dist/index.cjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
let node_stream = require("node:stream");
|
|
2
3
|
let _azure_core_auth = require("@azure/core-auth");
|
|
3
4
|
let _azure_storage_blob = require("@azure/storage-blob");
|
|
4
5
|
let _hot_updater_plugin_core = require("@hot-updater/plugin-core");
|
|
@@ -158,8 +159,7 @@ function azureBlobStorage(config) {
|
|
|
158
159
|
const headers = new Headers();
|
|
159
160
|
if (download.contentType) headers.set("content-type", download.contentType);
|
|
160
161
|
if (download.contentLength !== void 0) headers.set("content-length", String(download.contentLength));
|
|
161
|
-
|
|
162
|
-
return { response: new Response(Readable.toWeb(body), { headers }) };
|
|
162
|
+
return { response: new Response(node_stream.Readable.toWeb(body), { headers }) };
|
|
163
163
|
} catch (error) {
|
|
164
164
|
if (isNotFound(error)) return { response: null };
|
|
165
165
|
throw error;
|
|
@@ -811,7 +811,26 @@ const NO_CREDENTIAL_ERRORS = /* @__PURE__ */ new Set([
|
|
|
811
811
|
"AuthenticationRequiredError",
|
|
812
812
|
"CredentialUnavailableError"
|
|
813
813
|
]);
|
|
814
|
-
const SIGN_IN_HINT =
|
|
814
|
+
const SIGN_IN_HINT = [
|
|
815
|
+
"In CI, sign in with azure/login.",
|
|
816
|
+
"On your machine, run az login.",
|
|
817
|
+
"Or set AZURE_TENANT_ID, AZURE_CLIENT_ID, and AZURE_CLIENT_SECRET."
|
|
818
|
+
];
|
|
819
|
+
/** The widest line a message has: the CLI prints no wider. */
|
|
820
|
+
const LINE_WIDTH = 76;
|
|
821
|
+
/** `text`, such as Azure's own message, in lines that fit, broken at spaces. */
|
|
822
|
+
const wrap = (text) => {
|
|
823
|
+
const lines = [];
|
|
824
|
+
let line = "";
|
|
825
|
+
for (const word of text.split(/\s+/u).filter(Boolean)) if (line && line.length + 1 + word.length > LINE_WIDTH) {
|
|
826
|
+
lines.push(line);
|
|
827
|
+
line = word;
|
|
828
|
+
} else line = line ? `${line} ${word}` : word;
|
|
829
|
+
if (line) lines.push(line);
|
|
830
|
+
return lines;
|
|
831
|
+
};
|
|
832
|
+
/** An error of one line each, for a terminal. */
|
|
833
|
+
const failure = (lines, cause) => new Error(lines.join("\n"), cause === void 0 ? void 0 : { cause });
|
|
815
834
|
const READ_ROLE = "Key Vault Secrets User";
|
|
816
835
|
const WRITE_ROLE = "Key Vault Secrets Officer";
|
|
817
836
|
const errorName = (error) => error instanceof Error ? error.name : "";
|
|
@@ -830,7 +849,7 @@ const isLoopback = (hostname) => (/* @__PURE__ */ new Set([
|
|
|
830
849
|
const resolveVaultUrl = (vaultName, vaultUrl) => {
|
|
831
850
|
if (vaultName === void 0 === (vaultUrl === void 0)) throw new Error(`${NAME} needs a vaultName or a vaultUrl, and not both.`);
|
|
832
851
|
if (vaultName !== void 0) {
|
|
833
|
-
if (typeof vaultName !== "string" || !VAULT_NAME_PATTERN.test(vaultName)) throw
|
|
852
|
+
if (typeof vaultName !== "string" || !VAULT_NAME_PATTERN.test(vaultName)) throw failure([`${NAME} can't use the vault name ${JSON.stringify(vaultName)}.`, "Use 3 to 24 letters, digits, and single hyphens; start with a letter."]);
|
|
834
853
|
return new URL(`https://${vaultName.toLowerCase()}.vault.azure.net`);
|
|
835
854
|
}
|
|
836
855
|
let url;
|
|
@@ -839,7 +858,11 @@ const resolveVaultUrl = (vaultName, vaultUrl) => {
|
|
|
839
858
|
} catch {
|
|
840
859
|
throw new Error(`${NAME} vaultUrl must be a valid URL.`);
|
|
841
860
|
}
|
|
842
|
-
if (url.protocol !== "https:" || url.username || url.password || url.search || url.hash || url.pathname !== "/" && url.pathname !== "") throw
|
|
861
|
+
if (url.protocol !== "https:" || url.username || url.password || url.search || url.hash || url.pathname !== "/" && url.pathname !== "") throw failure([
|
|
862
|
+
`${NAME} can't use its vaultUrl.`,
|
|
863
|
+
"Use an HTTPS origin, such as https://my-vault.vault.azure.net.",
|
|
864
|
+
"Leave out credentials, a path, a query, and a fragment."
|
|
865
|
+
]);
|
|
843
866
|
return url;
|
|
844
867
|
};
|
|
845
868
|
/** Masks a value in the CLI's output, which loads `@hot-updater/cli-tools`. */
|
|
@@ -898,7 +921,7 @@ const keyVault = ({ credential, prefix = "hot-updater-", vaultName, vaultUrl })
|
|
|
898
921
|
const secretName = (name) => {
|
|
899
922
|
vault();
|
|
900
923
|
const id = keyVaultSecretName(name, prefix);
|
|
901
|
-
if (id.length > MAX_SECRET_NAME_LENGTH) throw
|
|
924
|
+
if (id.length > MAX_SECRET_NAME_LENGTH) throw failure([`${NAME} can't name a secret ${JSON.stringify(id)} for ${JSON.stringify(name)}.`, `Key Vault takes up to ${MAX_SECRET_NAME_LENGTH} characters.`]);
|
|
902
925
|
return id;
|
|
903
926
|
};
|
|
904
927
|
/** The vault's name, for the az commands messages suggest. */
|
|
@@ -917,14 +940,56 @@ const keyVault = ({ credential, prefix = "hot-updater-", vaultName, vaultUrl })
|
|
|
917
940
|
const name = errorName(error);
|
|
918
941
|
const status = statusOf(error);
|
|
919
942
|
const code = innerCode(error) ?? error?.code;
|
|
920
|
-
const detail = `${code || name || "Error"}${status ? ` (${status})` : ""}: ${errorMessage(error)}
|
|
921
|
-
|
|
922
|
-
if (
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
943
|
+
const detail = wrap(`${code || name || "Error"}${status ? ` (${status})` : ""}: ${errorMessage(error)}.`);
|
|
944
|
+
const secret = `Secret: ${id}`;
|
|
945
|
+
if (NO_CREDENTIAL_ERRORS.has(name)) return failure([
|
|
946
|
+
`${NAME} found no Azure identity to ${verb} a secret.`,
|
|
947
|
+
secret,
|
|
948
|
+
...wrap(`${errorMessage(error)}.`),
|
|
949
|
+
...SIGN_IN_HINT
|
|
950
|
+
], error);
|
|
951
|
+
if (status === 401) return failure([
|
|
952
|
+
`Azure Key Vault refused the sign-in to ${verb} a secret.`,
|
|
953
|
+
secret,
|
|
954
|
+
...detail,
|
|
955
|
+
"Sign in again.",
|
|
956
|
+
...SIGN_IN_HINT
|
|
957
|
+
], error);
|
|
958
|
+
if (code === "SecretDisabled") return failure([
|
|
959
|
+
`Azure Key Vault can't ${verb} a secret.`,
|
|
960
|
+
secret,
|
|
961
|
+
"Its current version is disabled. Enable it, or store a new value."
|
|
962
|
+
], error);
|
|
963
|
+
if (status === 403) return failure([
|
|
964
|
+
`Azure Key Vault refused to ${verb} a secret.`,
|
|
965
|
+
secret,
|
|
966
|
+
...detail,
|
|
967
|
+
`The Azure identity needs the ${role} role on the vault.`,
|
|
968
|
+
`With access policies, it needs the secret permissions ${role === READ_ROLE ? "get" : "get and set"}.`,
|
|
969
|
+
"A firewall may also refuse this network."
|
|
970
|
+
], error);
|
|
971
|
+
if (code === "ObjectIsBeingDeleted" || /being deleted/iu.test(errorMessage(error))) return failure([
|
|
972
|
+
`Azure Key Vault can't ${verb} a secret: it is being deleted.`,
|
|
973
|
+
secret,
|
|
974
|
+
"Try again in a minute."
|
|
975
|
+
], error);
|
|
976
|
+
if (status === 409 || code === "ObjectIsDeletedButRecoverable") {
|
|
977
|
+
const vaultName = vaultLabel();
|
|
978
|
+
return failure([
|
|
979
|
+
`Azure Key Vault can't ${verb} a secret: it was deleted.`,
|
|
980
|
+
secret,
|
|
981
|
+
"Recover it, or purge it:",
|
|
982
|
+
`az keyvault secret recover --vault-name ${vaultName} \\`,
|
|
983
|
+
` --name ${id}`,
|
|
984
|
+
`az keyvault secret purge --vault-name ${vaultName} \\`,
|
|
985
|
+
` --name ${id}`
|
|
986
|
+
], error);
|
|
987
|
+
}
|
|
988
|
+
return failure([
|
|
989
|
+
`Azure Key Vault failed to ${verb} a secret.`,
|
|
990
|
+
secret,
|
|
991
|
+
...detail
|
|
992
|
+
], error);
|
|
928
993
|
};
|
|
929
994
|
const read = async (client, id) => {
|
|
930
995
|
let value;
|
|
@@ -953,8 +1018,8 @@ const keyVault = ({ credential, prefix = "hot-updater-", vaultName, vaultUrl })
|
|
|
953
1018
|
},
|
|
954
1019
|
set: async (name, value) => {
|
|
955
1020
|
const id = secretName(name);
|
|
956
|
-
if (typeof value !== "string" || value === "") throw new Error(`${NAME}
|
|
957
|
-
if (value.length > MAX_SECRET_LENGTH) throw
|
|
1021
|
+
if (typeof value !== "string" || value === "") throw new Error(`${NAME} can't store an empty ${id}.`);
|
|
1022
|
+
if (value.length > MAX_SECRET_LENGTH) throw failure([`${NAME} can't store ${id}: it has ${value.length} characters.`, `Key Vault takes up to ${MAX_SECRET_LENGTH} characters per secret.`]);
|
|
958
1023
|
await mask([value]);
|
|
959
1024
|
const client = await open();
|
|
960
1025
|
try {
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Readable } from "node:stream";
|
|
1
2
|
import { isTokenCredential } from "@azure/core-auth";
|
|
2
3
|
import { BlobSASPermissions, BlobServiceClient, RestError, StorageSharedKeyCredential, generateBlobSASQueryParameters } from "@azure/storage-blob";
|
|
3
4
|
import { SETTINGS_TABLE, createEngineDatabase, createKvAdapter, createStorageAdapter, createStorageKeyBuilder, createStorageUri, encodeKvKey, migrateCoreSchema, parseStorageUri, toolingTargetOf } from "@hot-updater/plugin-core";
|
|
@@ -157,7 +158,6 @@ function azureBlobStorage(config) {
|
|
|
157
158
|
const headers = new Headers();
|
|
158
159
|
if (download.contentType) headers.set("content-type", download.contentType);
|
|
159
160
|
if (download.contentLength !== void 0) headers.set("content-length", String(download.contentLength));
|
|
160
|
-
const { Readable } = await import("node:stream");
|
|
161
161
|
return { response: new Response(Readable.toWeb(body), { headers }) };
|
|
162
162
|
} catch (error) {
|
|
163
163
|
if (isNotFound(error)) return { response: null };
|
|
@@ -810,7 +810,26 @@ const NO_CREDENTIAL_ERRORS = /* @__PURE__ */ new Set([
|
|
|
810
810
|
"AuthenticationRequiredError",
|
|
811
811
|
"CredentialUnavailableError"
|
|
812
812
|
]);
|
|
813
|
-
const SIGN_IN_HINT =
|
|
813
|
+
const SIGN_IN_HINT = [
|
|
814
|
+
"In CI, sign in with azure/login.",
|
|
815
|
+
"On your machine, run az login.",
|
|
816
|
+
"Or set AZURE_TENANT_ID, AZURE_CLIENT_ID, and AZURE_CLIENT_SECRET."
|
|
817
|
+
];
|
|
818
|
+
/** The widest line a message has: the CLI prints no wider. */
|
|
819
|
+
const LINE_WIDTH = 76;
|
|
820
|
+
/** `text`, such as Azure's own message, in lines that fit, broken at spaces. */
|
|
821
|
+
const wrap = (text) => {
|
|
822
|
+
const lines = [];
|
|
823
|
+
let line = "";
|
|
824
|
+
for (const word of text.split(/\s+/u).filter(Boolean)) if (line && line.length + 1 + word.length > LINE_WIDTH) {
|
|
825
|
+
lines.push(line);
|
|
826
|
+
line = word;
|
|
827
|
+
} else line = line ? `${line} ${word}` : word;
|
|
828
|
+
if (line) lines.push(line);
|
|
829
|
+
return lines;
|
|
830
|
+
};
|
|
831
|
+
/** An error of one line each, for a terminal. */
|
|
832
|
+
const failure = (lines, cause) => new Error(lines.join("\n"), cause === void 0 ? void 0 : { cause });
|
|
814
833
|
const READ_ROLE = "Key Vault Secrets User";
|
|
815
834
|
const WRITE_ROLE = "Key Vault Secrets Officer";
|
|
816
835
|
const errorName = (error) => error instanceof Error ? error.name : "";
|
|
@@ -829,7 +848,7 @@ const isLoopback = (hostname) => (/* @__PURE__ */ new Set([
|
|
|
829
848
|
const resolveVaultUrl = (vaultName, vaultUrl) => {
|
|
830
849
|
if (vaultName === void 0 === (vaultUrl === void 0)) throw new Error(`${NAME} needs a vaultName or a vaultUrl, and not both.`);
|
|
831
850
|
if (vaultName !== void 0) {
|
|
832
|
-
if (typeof vaultName !== "string" || !VAULT_NAME_PATTERN.test(vaultName)) throw
|
|
851
|
+
if (typeof vaultName !== "string" || !VAULT_NAME_PATTERN.test(vaultName)) throw failure([`${NAME} can't use the vault name ${JSON.stringify(vaultName)}.`, "Use 3 to 24 letters, digits, and single hyphens; start with a letter."]);
|
|
833
852
|
return new URL(`https://${vaultName.toLowerCase()}.vault.azure.net`);
|
|
834
853
|
}
|
|
835
854
|
let url;
|
|
@@ -838,7 +857,11 @@ const resolveVaultUrl = (vaultName, vaultUrl) => {
|
|
|
838
857
|
} catch {
|
|
839
858
|
throw new Error(`${NAME} vaultUrl must be a valid URL.`);
|
|
840
859
|
}
|
|
841
|
-
if (url.protocol !== "https:" || url.username || url.password || url.search || url.hash || url.pathname !== "/" && url.pathname !== "") throw
|
|
860
|
+
if (url.protocol !== "https:" || url.username || url.password || url.search || url.hash || url.pathname !== "/" && url.pathname !== "") throw failure([
|
|
861
|
+
`${NAME} can't use its vaultUrl.`,
|
|
862
|
+
"Use an HTTPS origin, such as https://my-vault.vault.azure.net.",
|
|
863
|
+
"Leave out credentials, a path, a query, and a fragment."
|
|
864
|
+
]);
|
|
842
865
|
return url;
|
|
843
866
|
};
|
|
844
867
|
/** Masks a value in the CLI's output, which loads `@hot-updater/cli-tools`. */
|
|
@@ -897,7 +920,7 @@ const keyVault = ({ credential, prefix = "hot-updater-", vaultName, vaultUrl })
|
|
|
897
920
|
const secretName = (name) => {
|
|
898
921
|
vault();
|
|
899
922
|
const id = keyVaultSecretName(name, prefix);
|
|
900
|
-
if (id.length > MAX_SECRET_NAME_LENGTH) throw
|
|
923
|
+
if (id.length > MAX_SECRET_NAME_LENGTH) throw failure([`${NAME} can't name a secret ${JSON.stringify(id)} for ${JSON.stringify(name)}.`, `Key Vault takes up to ${MAX_SECRET_NAME_LENGTH} characters.`]);
|
|
901
924
|
return id;
|
|
902
925
|
};
|
|
903
926
|
/** The vault's name, for the az commands messages suggest. */
|
|
@@ -916,14 +939,56 @@ const keyVault = ({ credential, prefix = "hot-updater-", vaultName, vaultUrl })
|
|
|
916
939
|
const name = errorName(error);
|
|
917
940
|
const status = statusOf(error);
|
|
918
941
|
const code = innerCode(error) ?? error?.code;
|
|
919
|
-
const detail = `${code || name || "Error"}${status ? ` (${status})` : ""}: ${errorMessage(error)}
|
|
920
|
-
|
|
921
|
-
if (
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
942
|
+
const detail = wrap(`${code || name || "Error"}${status ? ` (${status})` : ""}: ${errorMessage(error)}.`);
|
|
943
|
+
const secret = `Secret: ${id}`;
|
|
944
|
+
if (NO_CREDENTIAL_ERRORS.has(name)) return failure([
|
|
945
|
+
`${NAME} found no Azure identity to ${verb} a secret.`,
|
|
946
|
+
secret,
|
|
947
|
+
...wrap(`${errorMessage(error)}.`),
|
|
948
|
+
...SIGN_IN_HINT
|
|
949
|
+
], error);
|
|
950
|
+
if (status === 401) return failure([
|
|
951
|
+
`Azure Key Vault refused the sign-in to ${verb} a secret.`,
|
|
952
|
+
secret,
|
|
953
|
+
...detail,
|
|
954
|
+
"Sign in again.",
|
|
955
|
+
...SIGN_IN_HINT
|
|
956
|
+
], error);
|
|
957
|
+
if (code === "SecretDisabled") return failure([
|
|
958
|
+
`Azure Key Vault can't ${verb} a secret.`,
|
|
959
|
+
secret,
|
|
960
|
+
"Its current version is disabled. Enable it, or store a new value."
|
|
961
|
+
], error);
|
|
962
|
+
if (status === 403) return failure([
|
|
963
|
+
`Azure Key Vault refused to ${verb} a secret.`,
|
|
964
|
+
secret,
|
|
965
|
+
...detail,
|
|
966
|
+
`The Azure identity needs the ${role} role on the vault.`,
|
|
967
|
+
`With access policies, it needs the secret permissions ${role === READ_ROLE ? "get" : "get and set"}.`,
|
|
968
|
+
"A firewall may also refuse this network."
|
|
969
|
+
], error);
|
|
970
|
+
if (code === "ObjectIsBeingDeleted" || /being deleted/iu.test(errorMessage(error))) return failure([
|
|
971
|
+
`Azure Key Vault can't ${verb} a secret: it is being deleted.`,
|
|
972
|
+
secret,
|
|
973
|
+
"Try again in a minute."
|
|
974
|
+
], error);
|
|
975
|
+
if (status === 409 || code === "ObjectIsDeletedButRecoverable") {
|
|
976
|
+
const vaultName = vaultLabel();
|
|
977
|
+
return failure([
|
|
978
|
+
`Azure Key Vault can't ${verb} a secret: it was deleted.`,
|
|
979
|
+
secret,
|
|
980
|
+
"Recover it, or purge it:",
|
|
981
|
+
`az keyvault secret recover --vault-name ${vaultName} \\`,
|
|
982
|
+
` --name ${id}`,
|
|
983
|
+
`az keyvault secret purge --vault-name ${vaultName} \\`,
|
|
984
|
+
` --name ${id}`
|
|
985
|
+
], error);
|
|
986
|
+
}
|
|
987
|
+
return failure([
|
|
988
|
+
`Azure Key Vault failed to ${verb} a secret.`,
|
|
989
|
+
secret,
|
|
990
|
+
...detail
|
|
991
|
+
], error);
|
|
927
992
|
};
|
|
928
993
|
const read = async (client, id) => {
|
|
929
994
|
let value;
|
|
@@ -952,8 +1017,8 @@ const keyVault = ({ credential, prefix = "hot-updater-", vaultName, vaultUrl })
|
|
|
952
1017
|
},
|
|
953
1018
|
set: async (name, value) => {
|
|
954
1019
|
const id = secretName(name);
|
|
955
|
-
if (typeof value !== "string" || value === "") throw new Error(`${NAME}
|
|
956
|
-
if (value.length > MAX_SECRET_LENGTH) throw
|
|
1020
|
+
if (typeof value !== "string" || value === "") throw new Error(`${NAME} can't store an empty ${id}.`);
|
|
1021
|
+
if (value.length > MAX_SECRET_LENGTH) throw failure([`${NAME} can't store ${id}: it has ${value.length} characters.`, `Key Vault takes up to ${MAX_SECRET_LENGTH} characters per secret.`]);
|
|
957
1022
|
await mask([value]);
|
|
958
1023
|
const client = await open();
|
|
959
1024
|
try {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hot-updater/azure",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.2.0-rc.
|
|
4
|
+
"version": "1.2.0-rc.9",
|
|
5
5
|
"description": "React Native OTA solution for self-hosted",
|
|
6
6
|
"engines": {
|
|
7
7
|
"node": "^22.23.4 || ^24.22.1 || >=26.12.1"
|
|
@@ -44,10 +44,10 @@
|
|
|
44
44
|
"@azure/identity": "4.14.0",
|
|
45
45
|
"@azure/keyvault-secrets": "4.11.2",
|
|
46
46
|
"@azure/storage-blob": "12.34.0",
|
|
47
|
-
"@hot-updater/
|
|
48
|
-
"@hot-updater/
|
|
49
|
-
"@hot-updater/
|
|
50
|
-
"@hot-updater/
|
|
47
|
+
"@hot-updater/cli-tools": "1.2.0-rc.9",
|
|
48
|
+
"@hot-updater/protocol": "1.2.0-rc.9",
|
|
49
|
+
"@hot-updater/server": "1.2.0-rc.9",
|
|
50
|
+
"@hot-updater/plugin-core": "1.2.0-rc.9"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@azure/functions": "4.16.5",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"execa": "9.5.2",
|
|
56
56
|
"jszip": "^3.10.1",
|
|
57
57
|
"vitest": "4.1.4",
|
|
58
|
-
"@hot-updater/test-utils": "1.2.0-rc.
|
|
58
|
+
"@hot-updater/test-utils": "1.2.0-rc.9"
|
|
59
59
|
},
|
|
60
60
|
"scripts": {
|
|
61
61
|
"build": "tsdown",
|