@hot-updater/cli-tools 1.0.0-rc.14 → 1.0.0-rc.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +68 -35
- package/dist/index.mjs +246 -409
- package/package.json +5 -5
package/dist/index.d.mts
CHANGED
|
@@ -2,6 +2,7 @@ import { Readable } from "stream";
|
|
|
2
2
|
import { Key as Key$1 } from "node:readline";
|
|
3
3
|
import { Readable as Readable$1, Writable } from "node:stream";
|
|
4
4
|
import { Bundle, BundleSigningPlugin, ConfigInput, LocalSigningConfig, Platform, RequiredDeep, SigningConfig, StoragePluginWith, StoragePutResult } from "@hot-updater/plugin-core";
|
|
5
|
+
import { ManifestArchive } from "@hot-updater/core";
|
|
5
6
|
//#region src/BuildLogger.d.ts
|
|
6
7
|
type LinePattern = string | RegExp;
|
|
7
8
|
interface BuildLoggerConfig {
|
|
@@ -31,8 +32,40 @@ declare class BuildLogger {
|
|
|
31
32
|
private showLogFileLocation;
|
|
32
33
|
}
|
|
33
34
|
//#endregion
|
|
34
|
-
//#region src/
|
|
35
|
-
|
|
35
|
+
//#region src/appSetup.d.ts
|
|
36
|
+
/** The credential init gives an app, through the server's clientAuth plugin. */
|
|
37
|
+
interface AppClientCredential {
|
|
38
|
+
/** Its name in output, such as "API key". */
|
|
39
|
+
readonly label: string;
|
|
40
|
+
/** The request header that carries it. */
|
|
41
|
+
readonly header: string;
|
|
42
|
+
readonly value: string;
|
|
43
|
+
}
|
|
44
|
+
/** A client plugin the server's plugins ask an app to add. */
|
|
45
|
+
interface AppClientPlugin {
|
|
46
|
+
/** The module that exports it. */
|
|
47
|
+
readonly module: string;
|
|
48
|
+
/** The export, which the app calls with no arguments. */
|
|
49
|
+
readonly name: string;
|
|
50
|
+
}
|
|
51
|
+
interface AppSetup {
|
|
52
|
+
readonly credential?: AppClientCredential;
|
|
53
|
+
readonly clientPlugins?: readonly AppClientPlugin[];
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* The App.tsx code init prints: `HotUpdater.init` with the server's URL,
|
|
57
|
+
* the header that carries the client credential when the server takes one,
|
|
58
|
+
* and the client plugins the server's plugins ask for.
|
|
59
|
+
*/
|
|
60
|
+
declare const renderAppSetup: ({ baseURL, credential, clientPlugins }: AppSetup & {
|
|
61
|
+
readonly baseURL: string;
|
|
62
|
+
}) => string;
|
|
63
|
+
/** Prints the App.tsx code, when the URL is known, and the app's credential. */
|
|
64
|
+
declare const printAppSetup: ({ baseURL, ...setup }: AppSetup & {
|
|
65
|
+
readonly baseURL?: string;
|
|
66
|
+
/** Required, so each init passes its server plugins' client plugins. */
|
|
67
|
+
readonly clientPlugins: readonly AppClientPlugin[];
|
|
68
|
+
}) => void;
|
|
36
69
|
//#endregion
|
|
37
70
|
//#region src/banner.d.ts
|
|
38
71
|
declare const link: (url: string) => string;
|
|
@@ -163,41 +196,16 @@ declare const copyDirToTmp: (dir: string, childDirname?: string) => Promise<{
|
|
|
163
196
|
}>;
|
|
164
197
|
//#endregion
|
|
165
198
|
//#region src/createTarBr.d.ts
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
path: string;
|
|
169
|
-
name: string;
|
|
170
|
-
}[];
|
|
199
|
+
/** Build the one supported bulk transport from the exact manifest file set. */
|
|
200
|
+
declare function createTarBrTargetFiles({ outfile, targetFiles }: {
|
|
171
201
|
outfile: string;
|
|
172
|
-
}) => Promise<string>;
|
|
173
|
-
declare const createTarBr: ({ outfile, targetDir, excludeExts }: {
|
|
174
|
-
targetDir: string;
|
|
175
|
-
outfile: string;
|
|
176
|
-
excludeExts?: string[];
|
|
177
|
-
}) => Promise<string>;
|
|
178
|
-
//#endregion
|
|
179
|
-
//#region src/createTarGz.d.ts
|
|
180
|
-
declare const createTarGzTargetFiles: ({ outfile, targetFiles }: {
|
|
181
202
|
targetFiles: {
|
|
182
203
|
path: string;
|
|
183
204
|
name: string;
|
|
184
205
|
}[];
|
|
185
|
-
|
|
186
|
-
}) => Promise<string>;
|
|
187
|
-
declare const createTarGz: ({ outfile, targetDir, excludeExts }: {
|
|
188
|
-
targetDir: string;
|
|
189
|
-
outfile: string;
|
|
190
|
-
excludeExts?: string[];
|
|
191
|
-
}) => Promise<string>;
|
|
206
|
+
}): Promise<ManifestArchive>;
|
|
192
207
|
//#endregion
|
|
193
208
|
//#region src/createZip.d.ts
|
|
194
|
-
declare const createZipTargetFiles: ({ outfile, targetFiles }: {
|
|
195
|
-
targetFiles: {
|
|
196
|
-
path: string;
|
|
197
|
-
name: string;
|
|
198
|
-
}[];
|
|
199
|
-
outfile: string;
|
|
200
|
-
}) => Promise<string>;
|
|
201
209
|
declare const createZip: ({ outfile, targetDir, excludeExts }: {
|
|
202
210
|
targetDir: string;
|
|
203
211
|
outfile: string;
|
|
@@ -295,6 +303,34 @@ declare const readHotUpdaterInitEnv: (cwd: string, envFile?: string) => Promise<
|
|
|
295
303
|
declare const readHotUpdaterEnv: (cwd: string) => Promise<Readonly<Record<string, string>>>;
|
|
296
304
|
declare const getHotUpdaterEnvValue: (env: Readonly<Record<string, string>>, key: string) => string | undefined;
|
|
297
305
|
//#endregion
|
|
306
|
+
//#region src/hotUpdaterPlugins.d.ts
|
|
307
|
+
/** Where `hot-updater init` writes a managed server's plugin list. */
|
|
308
|
+
declare const HOT_UPDATER_PLUGINS_PATH = "hotUpdater.plugins.ts";
|
|
309
|
+
/**
|
|
310
|
+
* The plugins file for a managed provider: a re-export of the fixed list its
|
|
311
|
+
* package ships, which its prebuilt server runs too.
|
|
312
|
+
*/
|
|
313
|
+
declare const renderHotUpdaterPlugins: (pkg: string) => string;
|
|
314
|
+
type WriteHotUpdaterPluginsResult = {
|
|
315
|
+
readonly status: "created" | "unchanged";
|
|
316
|
+
readonly path: string;
|
|
317
|
+
} | {
|
|
318
|
+
readonly status: "skipped";
|
|
319
|
+
readonly path: string;
|
|
320
|
+
readonly reason: string;
|
|
321
|
+
};
|
|
322
|
+
/** Writes the plugins file; an existing file that differs is kept. */
|
|
323
|
+
declare const writeHotUpdaterPlugins: (pkg: string, filePath?: string) => Promise<WriteHotUpdaterPluginsResult>;
|
|
324
|
+
/** Writes the plugins file for `pkg` and reports what happened. */
|
|
325
|
+
declare const generateHotUpdaterPlugins: (pkg: string, filePath?: string) => Promise<WriteHotUpdaterPluginsResult>;
|
|
326
|
+
/**
|
|
327
|
+
* The plugins a project's `hotUpdater.plugins.ts` exports, which its server
|
|
328
|
+
* runs; undefined when the project has no such file. The console and the CLI
|
|
329
|
+
* assemble them in process as the server does, for the features and commands
|
|
330
|
+
* the plugins add.
|
|
331
|
+
*/
|
|
332
|
+
declare const loadHotUpdaterPlugins: (cwd?: string) => Promise<readonly unknown[] | undefined>;
|
|
333
|
+
//#endregion
|
|
298
334
|
//#region src/HotUpdateDirUtil.d.ts
|
|
299
335
|
declare const HotUpdateDirUtil: {
|
|
300
336
|
readonly dirName: ".hot-updater";
|
|
@@ -467,7 +503,7 @@ declare const makeEnv: (newEnvVars: Record<string, EnvVarValue>, filePath?: stri
|
|
|
467
503
|
//#region src/promoteBundle.d.ts
|
|
468
504
|
type PromoteStoragePlugin = StoragePluginWith<"get" | "put" | "exists" | "delete">;
|
|
469
505
|
declare const LEGACY_BUNDLE_ERROR = "This OTA bundle was created by a version that does not support manifest.json. Copy bundle is not available.";
|
|
470
|
-
declare function
|
|
506
|
+
declare function createCopiedBundleArtifacts({ bundle, config, nextBundleId, storagePlugin }: {
|
|
471
507
|
bundle: Bundle;
|
|
472
508
|
config: ConfigResponse;
|
|
473
509
|
nextBundleId: string;
|
|
@@ -475,9 +511,6 @@ declare function createCopiedBundleArchive({ bundle, config, nextBundleId, stora
|
|
|
475
511
|
}): Promise<{
|
|
476
512
|
bundle: {
|
|
477
513
|
id: string;
|
|
478
|
-
archiveByteSize: number;
|
|
479
|
-
storageUri: string;
|
|
480
|
-
fileHash: string;
|
|
481
514
|
metadata: import("@hot-updater/core").BundleMetadata | undefined;
|
|
482
515
|
assetBaseStorageUri: string;
|
|
483
516
|
patches: never[];
|
|
@@ -1733,4 +1766,4 @@ type TransformTemplateArgs<T extends string> = { [Key in ExtractPlaceholders<T>]
|
|
|
1733
1766
|
*/
|
|
1734
1767
|
declare function transformTemplate<T extends string>(templateString: T, values: TransformTemplateArgs<T>): string;
|
|
1735
1768
|
//#endregion
|
|
1736
|
-
export { BuildLogger, BuildLoggerConfig, BuildType, BundleSigningSession, ConfigBuilder, ConfigBuilderScaffold, ConfigResponse, CreateHotUpdaterConfigScaffoldFromBuilderOptions, CreateHotUpdaterConfigScaffoldOptions, HOT_UPDATER_SERVER_PACKAGE_VERSION_ENV, HotUpdateDirUtil, HotUpdaterConfigOptions, HotUpdaterConfigScaffold, HotUpdaterInitEnv, HotUpdaterLogWriter, IConfigBuilder, ImportInfo, InitEnvFileError, InitError, InitProviderDefinition, InitProviderInputDefinition, InitProviderInputPersistence, LEGACY_BUNDLE_ERROR, LegacyInfrastructureError, ManagedHelperStatement, ManagedHelperStrategy, MissingInitInputsError, PromptProgress, PromptSpinner, ProviderConfig, ReactNativeMetadata, ReadPackageUpResult, RunInitOptions, WriteHotUpdaterConfigResult, assertInfrastructureGenerationAtUrl, assertInfrastructureGenerationPayload, assertInitInputs, assertInitProviderInputs, banner, typedColors as colors, confirmInitInputPersistence, copyDirToTmp,
|
|
1769
|
+
export { AppClientCredential, AppClientPlugin, BuildLogger, BuildLoggerConfig, BuildType, BundleSigningSession, ConfigBuilder, ConfigBuilderScaffold, ConfigResponse, CreateHotUpdaterConfigScaffoldFromBuilderOptions, CreateHotUpdaterConfigScaffoldOptions, HOT_UPDATER_PLUGINS_PATH, HOT_UPDATER_SERVER_PACKAGE_VERSION_ENV, HotUpdateDirUtil, HotUpdaterConfigOptions, HotUpdaterConfigScaffold, HotUpdaterInitEnv, HotUpdaterLogWriter, IConfigBuilder, ImportInfo, InitEnvFileError, InitError, InitProviderDefinition, InitProviderInputDefinition, InitProviderInputPersistence, LEGACY_BUNDLE_ERROR, LegacyInfrastructureError, ManagedHelperStatement, ManagedHelperStrategy, MissingInitInputsError, PromptProgress, PromptSpinner, ProviderConfig, ReactNativeMetadata, ReadPackageUpResult, RunInitOptions, WriteHotUpdaterConfigResult, WriteHotUpdaterPluginsResult, assertInfrastructureGenerationAtUrl, assertInfrastructureGenerationPayload, assertInitInputs, assertInitProviderInputs, banner, typedColors as colors, confirmInitInputPersistence, copyDirToTmp, createCopiedBundleArtifacts, createHotUpdaterConfigScaffold, createHotUpdaterConfigScaffoldFromBuilder, createLogWriter, createTarBrTargetFiles, createZip, decryptJson, defineInitProvider, encryptJson, ensureInstallPackages, generateHotUpdaterPlugins, getAndroidSdkPath, getBundleSigningPublicKey, getCwd, getHotUpdaterEnvValue, getHotUpdaterInitInputEnv, getInitProviderEnvVars, getInitProviderTextPromptValues, getMissingInitInputs, getMissingInitProviderInputs, getPackageManager, getReactNativeMetadatas, getStorageFileByteSize, link, loadConfig, loadHotUpdaterPlugins, log, makeEnv, p, prepareBundleSigning, printAppSetup, printBanner, putStorageFile, readBundleSigningPublicKeyFile, readHotUpdaterEnv, readHotUpdaterInitEnv, readPackageUp, renderAppSetup, renderHotUpdaterPlugins, renderImportStatements, resolveHotUpdaterServerVersion, resolveInitProviderInput, resolveInitProviderInputs, resolvePackageVersion, shouldAutoSelectOnlyInitResource, stripAnsi, transformEnv, transformTemplate, writeHotUpdaterConfig, writeHotUpdaterPlugins, writeStorageFile, writeStorageResponseFile };
|
package/dist/index.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import { createRequire } from "node:module";
|
|
|
3
3
|
import path, { dirname, parse } from "path";
|
|
4
4
|
import { createInterface } from "readline";
|
|
5
5
|
import { PassThrough } from "stream";
|
|
6
|
-
import fs
|
|
6
|
+
import fs from "fs";
|
|
7
7
|
import fs$1 from "fs/promises";
|
|
8
8
|
import $r, { EventEmitter } from "events";
|
|
9
9
|
import Pi from "assert";
|
|
@@ -14,28 +14,27 @@ import process$1, { execArgv, execPath, hrtime, platform, stdin, stdout } from "
|
|
|
14
14
|
import * as l from "node:readline";
|
|
15
15
|
import l__default from "node:readline";
|
|
16
16
|
import tty, { ReadStream } from "node:tty";
|
|
17
|
-
import Ei, { appendFileSync, createReadStream, createWriteStream
|
|
17
|
+
import Ei, { appendFileSync, createReadStream, createWriteStream, existsSync, lstatSync, readFileSync, readdirSync, statSync, writeFileSync } from "node:fs";
|
|
18
18
|
import path$1, { basename, dirname as dirname$1, join, posix, win32 } from "node:path";
|
|
19
19
|
import os, { constants } from "node:os";
|
|
20
|
-
import crypto$1, { randomBytes, randomUUID } from "node:crypto";
|
|
20
|
+
import crypto$1, { createHash, randomBytes, randomUUID } from "node:crypto";
|
|
21
21
|
import fs$2 from "node:fs/promises";
|
|
22
|
-
import { pipeline } from "stream/promises";
|
|
23
|
-
import * as Ms from "zlib";
|
|
24
|
-
import Jr, { constants as constants$1, createBrotliCompress } from "zlib";
|
|
25
|
-
import { EventEmitter as EventEmitter$1, addAbortListener, on, once, setMaxListeners } from "node:events";
|
|
26
22
|
import As, { Duplex, PassThrough as PassThrough$1, Readable as Readable$1, Transform, Writable, getDefaultHighWaterMark } from "node:stream";
|
|
23
|
+
import { finished, pipeline } from "node:stream/promises";
|
|
24
|
+
import { brotliDecompressSync, constants as constants$1, createBrotliCompress } from "node:zlib";
|
|
25
|
+
import { EventEmitter as EventEmitter$1, addAbortListener, on, once, setMaxListeners } from "node:events";
|
|
27
26
|
import { StringDecoder } from "node:string_decoder";
|
|
27
|
+
import * as Ms from "zlib";
|
|
28
|
+
import Jr from "zlib";
|
|
28
29
|
import no from "node:assert";
|
|
29
30
|
import { fileURLToPath } from "node:url";
|
|
30
31
|
import { ChildProcess, execFile, spawn, spawnSync } from "node:child_process";
|
|
31
32
|
import { scheduler, setImmediate as setImmediate$1, setTimeout as setTimeout$1 } from "node:timers/promises";
|
|
32
33
|
import { serialize } from "node:v8";
|
|
33
|
-
import { finished, pipeline as pipeline$1 } from "node:stream/promises";
|
|
34
34
|
import { Buffer as Buffer$2 } from "node:buffer";
|
|
35
35
|
import { parseSync } from "oxc-parser";
|
|
36
|
-
import { createBundleStorageKey, createDatabasePlugin, createStoragePlugin, createStorageRootUriWithPath, detectCompressionFormat, getContentType, getManifestAssetDownloadPath, getManifestAssetStoragePath, isContentAddressedAssetFileHash, parseStorageUri, resolveManifestAssetStorageUri } from "@hot-updater/plugin-core";
|
|
37
36
|
import { loadConfig as loadConfig$1 } from "unconfig";
|
|
38
|
-
import {
|
|
37
|
+
import { createBundleStorageKey, createStoragePlugin, createStorageRootUriWithPath, getContentType, getManifestAssetDownloadPath, getManifestAssetStoragePath, isContentAddressedAssetFileHash, resolveManifestAssetStorageUri } from "@hot-updater/plugin-core";
|
|
39
38
|
import { getManifestFileHash, stripBundleArtifactMetadata } from "@hot-updater/core";
|
|
40
39
|
import { transformSync } from "oxc-transform";
|
|
41
40
|
//#endregion
|
|
@@ -22906,8 +22905,47 @@ var BuildLogger = class {
|
|
|
22906
22905
|
}
|
|
22907
22906
|
};
|
|
22908
22907
|
//#endregion
|
|
22909
|
-
//#region src/
|
|
22910
|
-
|
|
22908
|
+
//#region src/appSetup.ts
|
|
22909
|
+
/**
|
|
22910
|
+
* The App.tsx code init prints: `HotUpdater.init` with the server's URL,
|
|
22911
|
+
* the header that carries the client credential when the server takes one,
|
|
22912
|
+
* and the client plugins the server's plugins ask for.
|
|
22913
|
+
*/
|
|
22914
|
+
const renderAppSetup = ({ baseURL, credential, clientPlugins = [] }) => [
|
|
22915
|
+
"// Add this to your App.tsx",
|
|
22916
|
+
"import { HotUpdater } from \"@hot-updater/react-native\";",
|
|
22917
|
+
...clientPlugins.map(({ module, name }) => `import { ${name} } from ${JSON.stringify(module)};`),
|
|
22918
|
+
"",
|
|
22919
|
+
"function App() {",
|
|
22920
|
+
" return null; // Replace with your app root.",
|
|
22921
|
+
"}",
|
|
22922
|
+
"",
|
|
22923
|
+
"HotUpdater.init({",
|
|
22924
|
+
` baseURL: ${JSON.stringify(baseURL)},`,
|
|
22925
|
+
...credential === void 0 ? [] : [
|
|
22926
|
+
" requestHeaders: {",
|
|
22927
|
+
` ${JSON.stringify(credential.header)}: ${JSON.stringify(credential.value)},`,
|
|
22928
|
+
" },"
|
|
22929
|
+
],
|
|
22930
|
+
...clientPlugins.length === 0 ? [] : [` plugins: [${clientPlugins.map(({ name }) => `${name}()`).join(", ")}],`],
|
|
22931
|
+
"});",
|
|
22932
|
+
"",
|
|
22933
|
+
"// Call HotUpdater.checkForUpdate({ updateStrategy: \"appVersion\" })",
|
|
22934
|
+
"// when your app is ready to check.",
|
|
22935
|
+
"export default App;"
|
|
22936
|
+
].join("\n");
|
|
22937
|
+
/** Prints the App.tsx code, when the URL is known, and the app's credential. */
|
|
22938
|
+
const printAppSetup = ({ baseURL, ...setup }) => {
|
|
22939
|
+
if (baseURL !== void 0) p.note(renderAppSetup({
|
|
22940
|
+
baseURL,
|
|
22941
|
+
...setup
|
|
22942
|
+
}));
|
|
22943
|
+
const { credential } = setup;
|
|
22944
|
+
if (credential !== void 0) {
|
|
22945
|
+
p.note(credential.value, credential.label);
|
|
22946
|
+
p.log.message(`Store this ${credential.label} separately in a secure place.`);
|
|
22947
|
+
}
|
|
22948
|
+
};
|
|
22911
22949
|
//#endregion
|
|
22912
22950
|
//#region ../../node_modules/.pnpm/ansi-regex@6.2.2/node_modules/ansi-regex/index.js
|
|
22913
22951
|
function ansiRegex({ onlyFirst = false } = {}) {
|
|
@@ -25043,14 +25081,14 @@ var ConfigBuilder = class {
|
|
|
25043
25081
|
intermediateCode = "";
|
|
25044
25082
|
collectedImports = /* @__PURE__ */ new Map();
|
|
25045
25083
|
constructor() {
|
|
25046
|
-
this.addImport({
|
|
25047
|
-
pkg: "dotenv",
|
|
25048
|
-
named: ["config"]
|
|
25049
|
-
});
|
|
25050
25084
|
this.addImport({
|
|
25051
25085
|
pkg: "hot-updater",
|
|
25052
25086
|
named: ["defineConfig"]
|
|
25053
25087
|
});
|
|
25088
|
+
this.addImport({
|
|
25089
|
+
pkg: "node:fs",
|
|
25090
|
+
named: ["existsSync"]
|
|
25091
|
+
});
|
|
25054
25092
|
}
|
|
25055
25093
|
addImport(info) {
|
|
25056
25094
|
const pkg = info.pkg;
|
|
@@ -25127,7 +25165,9 @@ var ConfigBuilder = class {
|
|
|
25127
25165
|
const text = `
|
|
25128
25166
|
${importStatements}
|
|
25129
25167
|
|
|
25130
|
-
|
|
25168
|
+
if (existsSync(".env.hotupdater")) {
|
|
25169
|
+
process.loadEnvFile(".env.hotupdater");
|
|
25170
|
+
}
|
|
25131
25171
|
|
|
25132
25172
|
${this.intermediateCode ? `${this.intermediateCode}\n` : ""}
|
|
25133
25173
|
export default defineConfig({
|
|
@@ -28325,7 +28365,7 @@ var fo = (s, t) => {
|
|
|
28325
28365
|
});
|
|
28326
28366
|
});
|
|
28327
28367
|
};
|
|
28328
|
-
|
|
28368
|
+
K(co, fo, (s) => new Te(s), (s) => new Xt(s), (s, t) => {
|
|
28329
28369
|
t?.length && Xi(s, t);
|
|
28330
28370
|
});
|
|
28331
28371
|
var mo = (s, t) => {
|
|
@@ -28439,150 +28479,47 @@ var Ro = (s) => {
|
|
|
28439
28479
|
};
|
|
28440
28480
|
//#endregion
|
|
28441
28481
|
//#region src/createTarBr.ts
|
|
28442
|
-
|
|
28443
|
-
|
|
28444
|
-
|
|
28445
|
-
await fs$1.
|
|
28482
|
+
/** Build the one supported bulk transport from the exact manifest file set. */
|
|
28483
|
+
async function createTarBrTargetFiles({ outfile, targetFiles }) {
|
|
28484
|
+
await fs$2.mkdir(path$1.dirname(outfile), { recursive: true });
|
|
28485
|
+
const staging = await fs$2.mkdtemp(path$1.join(path$1.dirname(outfile), ".tar-br-"));
|
|
28446
28486
|
try {
|
|
28487
|
+
const names = /* @__PURE__ */ new Set();
|
|
28447
28488
|
for (const target of targetFiles) {
|
|
28448
|
-
const
|
|
28449
|
-
|
|
28450
|
-
await fs$
|
|
28451
|
-
|
|
28452
|
-
|
|
28453
|
-
|
|
28454
|
-
|
|
28489
|
+
const name = target.name;
|
|
28490
|
+
if (!name || name !== name.trim() || name.includes("\\") || name.includes("\0") || name.startsWith("/") || /^[A-Za-z]:/.test(name) || name.split("/").some((part) => !part || part === "." || part === "..") || name === "manifest.json" || name === "bundle.tar.br" || names.has(name)) throw new Error(`Invalid or duplicate archive asset path: ${name}`);
|
|
28491
|
+
if (!(await fs$2.lstat(target.path)).isFile()) throw new Error(`Archive asset is not a regular file: ${name}`);
|
|
28492
|
+
names.add(name);
|
|
28493
|
+
const destination = path$1.join(staging, name);
|
|
28494
|
+
await fs$2.mkdir(path$1.dirname(destination), { recursive: true });
|
|
28495
|
+
await fs$2.copyFile(target.path, destination);
|
|
28496
|
+
await fs$2.chmod(destination, 420);
|
|
28497
|
+
}
|
|
28498
|
+
let tarByteSize = 0;
|
|
28499
|
+
const countTarBytes = new Transform({ transform(chunk, _encoding, callback) {
|
|
28500
|
+
tarByteSize += chunk.length;
|
|
28501
|
+
callback(null, chunk);
|
|
28502
|
+
} });
|
|
28455
28503
|
await pipeline(Kn({
|
|
28456
|
-
cwd:
|
|
28504
|
+
cwd: staging,
|
|
28457
28505
|
portable: true,
|
|
28458
28506
|
mtime: /* @__PURE__ */ new Date(0),
|
|
28459
28507
|
gzip: false
|
|
28460
|
-
},
|
|
28461
|
-
|
|
28462
|
-
|
|
28463
|
-
|
|
28464
|
-
|
|
28465
|
-
|
|
28466
|
-
|
|
28467
|
-
|
|
28468
|
-
force: true
|
|
28469
|
-
});
|
|
28470
|
-
}
|
|
28471
|
-
};
|
|
28472
|
-
async function copyDir$1(src, dest) {
|
|
28473
|
-
await fs$1.mkdir(dest, { recursive: true });
|
|
28474
|
-
const entries = await fs$1.readdir(src, { withFileTypes: true });
|
|
28475
|
-
for (const entry of entries) {
|
|
28476
|
-
const srcPath = path.join(src, entry.name);
|
|
28477
|
-
const destPath = path.join(dest, entry.name);
|
|
28478
|
-
if (entry.isDirectory()) await copyDir$1(srcPath, destPath);
|
|
28479
|
-
else await fs$1.copyFile(srcPath, destPath);
|
|
28480
|
-
}
|
|
28481
|
-
}
|
|
28482
|
-
const createBrotliTar = async ({ cwd, files, outfile }) => {
|
|
28483
|
-
await fs$1.mkdir(path.dirname(outfile), { recursive: true });
|
|
28484
|
-
await pipeline(Kn({
|
|
28485
|
-
cwd,
|
|
28486
|
-
portable: true,
|
|
28487
|
-
mtime: /* @__PURE__ */ new Date(0),
|
|
28488
|
-
gzip: false
|
|
28489
|
-
}, files), createBrotliCompress({ params: {
|
|
28490
|
-
[constants$1.BROTLI_PARAM_QUALITY]: 11,
|
|
28491
|
-
[constants$1.BROTLI_PARAM_LGWIN]: 24
|
|
28492
|
-
} }), createWriteStream(outfile));
|
|
28493
|
-
};
|
|
28494
|
-
const createTarBr = async ({ outfile, targetDir, excludeExts = [] }) => {
|
|
28495
|
-
await fs$1.rm(outfile, { force: true });
|
|
28496
|
-
async function getFiles(dir, baseDir = "") {
|
|
28497
|
-
const entries = await fs$1.readdir(dir, { withFileTypes: true });
|
|
28498
|
-
const files = [];
|
|
28499
|
-
for (const entry of entries) {
|
|
28500
|
-
if (excludeExts.some((pattern) => entry.name.includes(pattern))) continue;
|
|
28501
|
-
const fullPath = path.join(dir, entry.name);
|
|
28502
|
-
const relativePath = path.join(baseDir, entry.name);
|
|
28503
|
-
if (entry.isDirectory()) {
|
|
28504
|
-
const subFiles = await getFiles(fullPath, relativePath);
|
|
28505
|
-
files.push(...subFiles);
|
|
28506
|
-
} else files.push(relativePath);
|
|
28507
|
-
}
|
|
28508
|
-
return files;
|
|
28509
|
-
}
|
|
28510
|
-
const filesToInclude = await getFiles(targetDir);
|
|
28511
|
-
filesToInclude.sort();
|
|
28512
|
-
await createBrotliTar({
|
|
28513
|
-
cwd: targetDir,
|
|
28514
|
-
files: filesToInclude,
|
|
28515
|
-
outfile
|
|
28516
|
-
});
|
|
28517
|
-
return outfile;
|
|
28518
|
-
};
|
|
28519
|
-
//#endregion
|
|
28520
|
-
//#region src/createTarGz.ts
|
|
28521
|
-
const createTarGzTargetFiles = async ({ outfile, targetFiles }) => {
|
|
28522
|
-
await fs$1.rm(outfile, { force: true });
|
|
28523
|
-
const tmpDir = path.join(path.dirname(outfile), `.tmp-tar-${Date.now()}`);
|
|
28524
|
-
await fs$1.mkdir(tmpDir, { recursive: true });
|
|
28525
|
-
try {
|
|
28526
|
-
for (const target of targetFiles) {
|
|
28527
|
-
const sourcePath = target.path;
|
|
28528
|
-
const destPath = path.join(tmpDir, target.name);
|
|
28529
|
-
await fs$1.mkdir(path.dirname(destPath), { recursive: true });
|
|
28530
|
-
if ((await fs$1.stat(sourcePath)).isDirectory()) await copyDir(sourcePath, destPath);
|
|
28531
|
-
else await fs$1.copyFile(sourcePath, destPath);
|
|
28532
|
-
}
|
|
28533
|
-
await fs$1.mkdir(path.dirname(outfile), { recursive: true });
|
|
28534
|
-
await Kn({
|
|
28535
|
-
file: outfile,
|
|
28536
|
-
cwd: tmpDir,
|
|
28537
|
-
portable: true,
|
|
28538
|
-
mtime: /* @__PURE__ */ new Date(0),
|
|
28539
|
-
gzip: true
|
|
28540
|
-
}, await fs$1.readdir(tmpDir));
|
|
28541
|
-
return outfile;
|
|
28508
|
+
}, [...names].sort()), countTarBytes, createBrotliCompress({ params: { [constants$1.BROTLI_PARAM_QUALITY]: 11 } }), createWriteStream(outfile));
|
|
28509
|
+
const hash = createHash("sha256");
|
|
28510
|
+
for await (const chunk of createReadStream(outfile)) hash.update(chunk);
|
|
28511
|
+
return {
|
|
28512
|
+
downloadFileHash: hash.digest("hex"),
|
|
28513
|
+
downloadByteSize: (await fs$2.stat(outfile)).size,
|
|
28514
|
+
tarByteSize
|
|
28515
|
+
};
|
|
28542
28516
|
} finally {
|
|
28543
|
-
await fs$
|
|
28517
|
+
await fs$2.rm(staging, {
|
|
28544
28518
|
recursive: true,
|
|
28545
28519
|
force: true
|
|
28546
28520
|
});
|
|
28547
28521
|
}
|
|
28548
|
-
};
|
|
28549
|
-
async function copyDir(src, dest) {
|
|
28550
|
-
await fs$1.mkdir(dest, { recursive: true });
|
|
28551
|
-
const entries = await fs$1.readdir(src, { withFileTypes: true });
|
|
28552
|
-
for (const entry of entries) {
|
|
28553
|
-
const srcPath = path.join(src, entry.name);
|
|
28554
|
-
const destPath = path.join(dest, entry.name);
|
|
28555
|
-
if (entry.isDirectory()) await copyDir(srcPath, destPath);
|
|
28556
|
-
else await fs$1.copyFile(srcPath, destPath);
|
|
28557
|
-
}
|
|
28558
28522
|
}
|
|
28559
|
-
const createTarGz = async ({ outfile, targetDir, excludeExts = [] }) => {
|
|
28560
|
-
await fs$1.rm(outfile, { force: true });
|
|
28561
|
-
async function getFiles(dir, baseDir = "") {
|
|
28562
|
-
const entries = await fs$1.readdir(dir, { withFileTypes: true });
|
|
28563
|
-
const files = [];
|
|
28564
|
-
for (const entry of entries) {
|
|
28565
|
-
if (excludeExts.some((pattern) => entry.name.includes(pattern))) continue;
|
|
28566
|
-
const fullPath = path.join(dir, entry.name);
|
|
28567
|
-
const relativePath = path.join(baseDir, entry.name);
|
|
28568
|
-
if (entry.isDirectory()) {
|
|
28569
|
-
const subFiles = await getFiles(fullPath, relativePath);
|
|
28570
|
-
files.push(...subFiles);
|
|
28571
|
-
} else files.push(relativePath);
|
|
28572
|
-
}
|
|
28573
|
-
return files;
|
|
28574
|
-
}
|
|
28575
|
-
const filesToInclude = await getFiles(targetDir);
|
|
28576
|
-
filesToInclude.sort();
|
|
28577
|
-
await Kn({
|
|
28578
|
-
file: outfile,
|
|
28579
|
-
cwd: targetDir,
|
|
28580
|
-
portable: true,
|
|
28581
|
-
mtime: /* @__PURE__ */ new Date(0),
|
|
28582
|
-
gzip: true
|
|
28583
|
-
}, filesToInclude);
|
|
28584
|
-
return outfile;
|
|
28585
|
-
};
|
|
28586
28523
|
//#endregion
|
|
28587
28524
|
//#region ../../node_modules/.pnpm/process-nextick-args@2.0.1/node_modules/process-nextick-args/index.js
|
|
28588
28525
|
var require_process_nextick_args = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
@@ -37664,41 +37601,6 @@ var import_lib = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((export
|
|
|
37664
37601
|
JSZip.external = require_external();
|
|
37665
37602
|
module.exports = JSZip;
|
|
37666
37603
|
})))(), 1);
|
|
37667
|
-
const createZipTargetFiles = async ({ outfile, targetFiles }) => {
|
|
37668
|
-
const zip = new import_lib.default();
|
|
37669
|
-
await fs$1.rm(outfile, { force: true });
|
|
37670
|
-
async function addFiles(dir, zipFolder) {
|
|
37671
|
-
const files = await fs$1.readdir(dir);
|
|
37672
|
-
files.sort();
|
|
37673
|
-
for (const file of files) {
|
|
37674
|
-
const fullPath = path.join(dir, file);
|
|
37675
|
-
if ((await fs$1.stat(fullPath)).isDirectory()) {
|
|
37676
|
-
const folder = zipFolder.folder(file);
|
|
37677
|
-
if (!folder) continue;
|
|
37678
|
-
await addFiles(fullPath, folder);
|
|
37679
|
-
} else {
|
|
37680
|
-
const data = await fs$1.readFile(fullPath);
|
|
37681
|
-
zipFolder.file(file, data);
|
|
37682
|
-
}
|
|
37683
|
-
}
|
|
37684
|
-
}
|
|
37685
|
-
for (const target of targetFiles) if ((await fs$1.stat(target.path)).isDirectory()) {
|
|
37686
|
-
const folder = zip.folder(target.name);
|
|
37687
|
-
if (folder) await addFiles(target.path, folder);
|
|
37688
|
-
} else {
|
|
37689
|
-
const data = await fs$1.readFile(target.path);
|
|
37690
|
-
zip.file(target.name, data);
|
|
37691
|
-
}
|
|
37692
|
-
const content = await zip.generateAsync({
|
|
37693
|
-
type: "nodebuffer",
|
|
37694
|
-
compression: "DEFLATE",
|
|
37695
|
-
compressionOptions: { level: 9 },
|
|
37696
|
-
platform: "UNIX"
|
|
37697
|
-
});
|
|
37698
|
-
await fs$1.mkdir(path.dirname(outfile), { recursive: true });
|
|
37699
|
-
await fs$1.writeFile(outfile, content);
|
|
37700
|
-
return outfile;
|
|
37701
|
-
};
|
|
37702
37604
|
const createZip = async ({ outfile, targetDir, excludeExts = [] }) => {
|
|
37703
37605
|
const zip = new import_lib.default();
|
|
37704
37606
|
await fs$1.rm(outfile, { force: true });
|
|
@@ -42298,8 +42200,8 @@ const addPropertiesAsync = {
|
|
|
42298
42200
|
},
|
|
42299
42201
|
output: {
|
|
42300
42202
|
...addProperties,
|
|
42301
|
-
fileUrl: ({ value }) => ({ stream: createWriteStream
|
|
42302
|
-
filePath: ({ value: { file, append } }) => ({ stream: createWriteStream
|
|
42203
|
+
fileUrl: ({ value }) => ({ stream: createWriteStream(value) }),
|
|
42204
|
+
filePath: ({ value: { file, append } }) => ({ stream: createWriteStream(file, append ? { flags: "a" } : {}) }),
|
|
42303
42205
|
webStream: ({ value }) => ({ stream: Writable.fromWeb(value) }),
|
|
42304
42206
|
iterable: forbiddenIfAsync,
|
|
42305
42207
|
asyncIterable: forbiddenIfAsync,
|
|
@@ -44175,7 +44077,6 @@ const getReactNativeMetadatas = (cwd) => {
|
|
|
44175
44077
|
const HOT_UPDATER_CONFIG_PATH = "hot-updater.config.ts";
|
|
44176
44078
|
const CONFIG_FILE_NAME = "hot-updater.config.ts";
|
|
44177
44079
|
const MANAGED_IMPORT_PACKAGES = /* @__PURE__ */ new Set([
|
|
44178
|
-
"dotenv",
|
|
44179
44080
|
"firebase-admin",
|
|
44180
44081
|
"firebase-admin/app",
|
|
44181
44082
|
"hot-updater",
|
|
@@ -44428,7 +44329,6 @@ const updateManagedObject = (existing, next) => {
|
|
|
44428
44329
|
for (const edit of propertyEdits.sort((left, right) => right.start - left.start)) mergedText = mergedText.slice(0, edit.start) + edit.text + mergedText.slice(edit.end);
|
|
44429
44330
|
return appendMissingProperties(mergedText, missingPropertyTexts, existing.objectExpression.properties.length > 0);
|
|
44430
44331
|
};
|
|
44431
|
-
const isConfigCallStatement = (statement) => statement.type === "ExpressionStatement" && statement.expression.type === "CallExpression" && statement.expression.callee.type === "Identifier" && statement.expression.callee.name === "config";
|
|
44432
44332
|
const getManagedHelperName = (statement) => {
|
|
44433
44333
|
if (statement.type !== "VariableDeclaration") return null;
|
|
44434
44334
|
const declaration = statement.declarations[0];
|
|
@@ -44436,16 +44336,20 @@ const getManagedHelperName = (statement) => {
|
|
|
44436
44336
|
return declaration.id.name;
|
|
44437
44337
|
};
|
|
44438
44338
|
const rebuildImportBlock = (source, scaffold) => {
|
|
44339
|
+
const imports = scaffold.imports.map((info) => info.pkg === "node:fs" ? {
|
|
44340
|
+
...info,
|
|
44341
|
+
named: info.named?.filter((name) => name !== "existsSync")
|
|
44342
|
+
} : info);
|
|
44439
44343
|
const importDeclarations = source.program.body.filter((statement) => statement.type === "ImportDeclaration");
|
|
44440
44344
|
const firstImport = importDeclarations[0];
|
|
44441
44345
|
const lastImport = importDeclarations.at(-1);
|
|
44442
44346
|
if (!firstImport || !lastImport) return {
|
|
44443
44347
|
start: 0,
|
|
44444
44348
|
end: 0,
|
|
44445
|
-
text: `${renderImportStatements(
|
|
44349
|
+
text: `${renderImportStatements(imports)}\n\n`
|
|
44446
44350
|
};
|
|
44447
44351
|
const preservedImportTexts = importDeclarations.filter((declaration) => !MANAGED_IMPORT_PACKAGES.has(declaration.source.value)).map((declaration) => source.text.slice(getTopLevelFullStart(source, declaration), declaration.end).trim());
|
|
44448
|
-
const managedImportText = renderImportStatements(
|
|
44352
|
+
const managedImportText = renderImportStatements(imports);
|
|
44449
44353
|
const nextImportBlock = [...preservedImportTexts, managedImportText].filter(Boolean).join("\n");
|
|
44450
44354
|
return {
|
|
44451
44355
|
start: getTopLevelFullStart(source, firstImport),
|
|
@@ -44458,12 +44362,7 @@ const rebuildManagedBody = (source, exportStart, scaffold) => {
|
|
|
44458
44362
|
const managedHelpers = new Map(scaffold.helperStatements.map((statement) => [statement.name, statement]));
|
|
44459
44363
|
const emittedHelpers = /* @__PURE__ */ new Set();
|
|
44460
44364
|
const bodyStatements = [];
|
|
44461
|
-
const configStatements = [];
|
|
44462
44365
|
for (const statement of statementsBeforeExport) {
|
|
44463
|
-
if (isConfigCallStatement(statement)) {
|
|
44464
|
-
configStatements.push(getStatementText(source, statement));
|
|
44465
|
-
continue;
|
|
44466
|
-
}
|
|
44467
44366
|
const helperName = getManagedHelperName(statement);
|
|
44468
44367
|
if (!helperName || !MANAGED_HELPER_NAMES.has(helperName)) {
|
|
44469
44368
|
bodyStatements.push(getStatementText(source, statement));
|
|
@@ -44478,8 +44377,7 @@ const rebuildManagedBody = (source, exportStart, scaffold) => {
|
|
|
44478
44377
|
}
|
|
44479
44378
|
for (const helper of scaffold.helperStatements) if (!emittedHelpers.has(helper.name)) bodyStatements.push(helper.code.trim());
|
|
44480
44379
|
const bodyText = bodyStatements.filter(Boolean).join("\n\n");
|
|
44481
|
-
const
|
|
44482
|
-
const managedBody = bodyText ? `\n\n${configStatement}\n\n${bodyText}\n\n` : `\n\n${configStatement}\n\n`;
|
|
44380
|
+
const managedBody = bodyText ? `\n\n${bodyText}\n\n` : "\n\n";
|
|
44483
44381
|
return {
|
|
44484
44382
|
start: source.program.body.filter((statement) => statement.type === "ImportDeclaration").at(-1)?.end ?? 0,
|
|
44485
44383
|
end: exportStart,
|
|
@@ -44678,6 +44576,78 @@ const getHotUpdaterEnvValue = (env, key) => {
|
|
|
44678
44576
|
return env[key]?.trim() || void 0;
|
|
44679
44577
|
};
|
|
44680
44578
|
//#endregion
|
|
44579
|
+
//#region src/hotUpdaterPlugins.ts
|
|
44580
|
+
/** Where `hot-updater init` writes a managed server's plugin list. */
|
|
44581
|
+
const HOT_UPDATER_PLUGINS_PATH = "hotUpdater.plugins.ts";
|
|
44582
|
+
/**
|
|
44583
|
+
* The plugins file for a managed provider: a re-export of the fixed list its
|
|
44584
|
+
* package ships, which its prebuilt server runs too.
|
|
44585
|
+
*/
|
|
44586
|
+
const renderHotUpdaterPlugins = (pkg) => [
|
|
44587
|
+
"// Generated by `hot-updater init`. The managed server runs these plugins,",
|
|
44588
|
+
`// and ${pkg} fixes the list, so the server, CLI, and console agree.`,
|
|
44589
|
+
`export { plugins } from "${pkg}";`,
|
|
44590
|
+
""
|
|
44591
|
+
].join("\n");
|
|
44592
|
+
/** Writes the plugins file; an existing file that differs is kept. */
|
|
44593
|
+
const writeHotUpdaterPlugins = async (pkg, filePath = HOT_UPDATER_PLUGINS_PATH) => {
|
|
44594
|
+
const text = renderHotUpdaterPlugins(pkg);
|
|
44595
|
+
const existingText = await fs$1.readFile(filePath, "utf-8").catch((error) => {
|
|
44596
|
+
if (error instanceof Error && "code" in error && error.code === "ENOENT") return null;
|
|
44597
|
+
throw error;
|
|
44598
|
+
});
|
|
44599
|
+
if (existingText === null) {
|
|
44600
|
+
await fs$1.writeFile(filePath, text, "utf-8");
|
|
44601
|
+
return {
|
|
44602
|
+
status: "created",
|
|
44603
|
+
path: filePath
|
|
44604
|
+
};
|
|
44605
|
+
}
|
|
44606
|
+
if (existingText === text) return {
|
|
44607
|
+
status: "unchanged",
|
|
44608
|
+
path: filePath
|
|
44609
|
+
};
|
|
44610
|
+
return {
|
|
44611
|
+
status: "skipped",
|
|
44612
|
+
path: filePath,
|
|
44613
|
+
reason: `it does not re-export the plugins ${pkg} runs; replace it with \`export { plugins } from "${pkg}";\``
|
|
44614
|
+
};
|
|
44615
|
+
};
|
|
44616
|
+
/** Writes the plugins file for `pkg` and reports what happened. */
|
|
44617
|
+
const generateHotUpdaterPlugins = async (pkg, filePath = HOT_UPDATER_PLUGINS_PATH) => {
|
|
44618
|
+
const result = await writeHotUpdaterPlugins(pkg, filePath);
|
|
44619
|
+
if (result.status === "created") p.log.success(`Generated '${filePath}' with the plugins the server runs.`);
|
|
44620
|
+
else if (result.status === "skipped") p.log.warn(`Kept existing '${filePath}' unchanged: ${result.reason}`);
|
|
44621
|
+
return result;
|
|
44622
|
+
};
|
|
44623
|
+
/**
|
|
44624
|
+
* The plugins a project's `hotUpdater.plugins.ts` exports, which its server
|
|
44625
|
+
* runs; undefined when the project has no such file. The console and the CLI
|
|
44626
|
+
* assemble them in process as the server does, for the features and commands
|
|
44627
|
+
* the plugins add.
|
|
44628
|
+
*/
|
|
44629
|
+
const loadHotUpdaterPlugins = async (cwd = getCwd()) => {
|
|
44630
|
+
const { config, sources } = await loadConfig$1({
|
|
44631
|
+
cwd,
|
|
44632
|
+
stopAt: path.dirname(cwd),
|
|
44633
|
+
merge: false,
|
|
44634
|
+
sources: [{
|
|
44635
|
+
files: "hotUpdater.plugins",
|
|
44636
|
+
extensions: [
|
|
44637
|
+
"ts",
|
|
44638
|
+
"mts",
|
|
44639
|
+
"cts",
|
|
44640
|
+
"js",
|
|
44641
|
+
"mjs",
|
|
44642
|
+
"cjs"
|
|
44643
|
+
]
|
|
44644
|
+
}]
|
|
44645
|
+
});
|
|
44646
|
+
if (sources.length === 0) return void 0;
|
|
44647
|
+
if (!Array.isArray(config?.plugins)) throw new Error(`${path.basename(sources[0])} must export plugins, an array of plugins.`);
|
|
44648
|
+
return config.plugins;
|
|
44649
|
+
};
|
|
44650
|
+
//#endregion
|
|
44681
44651
|
//#region src/infrastructureGeneration.ts
|
|
44682
44652
|
const assertInfrastructureGenerationPayload = ({ payload, provider, resource }) => {
|
|
44683
44653
|
if (typeof payload !== "object" || payload === null || !("infrastructureGeneration" in payload) || payload.infrastructureGeneration !== 1) throw new LegacyInfrastructureError(provider, resource);
|
|
@@ -44873,89 +44843,20 @@ function isMergeableValue(value) {
|
|
|
44873
44843
|
//#endregion
|
|
44874
44844
|
//#region src/loadConfig.ts
|
|
44875
44845
|
var import_out = /* @__PURE__ */ __toESM(require_out(), 1);
|
|
44876
|
-
const
|
|
44846
|
+
const missingDatabaseError = async () => {
|
|
44847
|
+
throw new Error("database is required");
|
|
44848
|
+
};
|
|
44849
|
+
/** The default until the config names a database: every read and write refuses. */
|
|
44850
|
+
const missingDatabase = {
|
|
44877
44851
|
name: "missingDatabase",
|
|
44878
|
-
|
|
44879
|
-
|
|
44880
|
-
|
|
44881
|
-
|
|
44882
|
-
|
|
44883
|
-
|
|
44884
|
-
throw new Error("database plugin is required");
|
|
44885
|
-
},
|
|
44886
|
-
count: async () => {
|
|
44887
|
-
throw new Error("database plugin is required");
|
|
44888
|
-
}
|
|
44889
|
-
},
|
|
44890
|
-
bundlePatches: { findByBundleIds: async () => {
|
|
44891
|
-
throw new Error("database plugin is required");
|
|
44892
|
-
} },
|
|
44893
|
-
releases: {
|
|
44894
|
-
findById: async () => {
|
|
44895
|
-
throw new Error("database plugin is required");
|
|
44896
|
-
},
|
|
44897
|
-
findMany: async () => {
|
|
44898
|
-
throw new Error("database plugin is required");
|
|
44899
|
-
},
|
|
44900
|
-
findManyByScope: async () => {
|
|
44901
|
-
throw new Error("database plugin is required");
|
|
44902
|
-
}
|
|
44903
|
-
},
|
|
44904
|
-
releaseCatalogs: {
|
|
44905
|
-
findByScopeKey: async () => {
|
|
44906
|
-
throw new Error("database plugin is required");
|
|
44907
|
-
},
|
|
44908
|
-
findMany: async () => {
|
|
44909
|
-
throw new Error("database plugin is required");
|
|
44910
|
-
}
|
|
44911
|
-
},
|
|
44912
|
-
channels: {
|
|
44913
|
-
insert: async () => {
|
|
44914
|
-
throw new Error("database plugin is required");
|
|
44915
|
-
},
|
|
44916
|
-
list: async () => {
|
|
44917
|
-
throw new Error("database plugin is required");
|
|
44918
|
-
},
|
|
44919
|
-
delete: async () => {
|
|
44920
|
-
throw new Error("database plugin is required");
|
|
44921
|
-
}
|
|
44922
|
-
},
|
|
44923
|
-
insights: {
|
|
44924
|
-
recordEvent: async () => {
|
|
44925
|
-
throw new Error("database plugin is required");
|
|
44926
|
-
},
|
|
44927
|
-
listEvents: async () => {
|
|
44928
|
-
throw new Error("database plugin is required");
|
|
44929
|
-
},
|
|
44930
|
-
findLatestEvents: async () => {
|
|
44931
|
-
throw new Error("database plugin is required");
|
|
44932
|
-
},
|
|
44933
|
-
countLatestEvents: async () => {
|
|
44934
|
-
throw new Error("database plugin is required");
|
|
44935
|
-
},
|
|
44936
|
-
countEvents: async () => {
|
|
44937
|
-
throw new Error("database plugin is required");
|
|
44938
|
-
}
|
|
44939
|
-
},
|
|
44940
|
-
apiKeys: {
|
|
44941
|
-
create: async () => {
|
|
44942
|
-
throw new Error("database plugin is required");
|
|
44943
|
-
},
|
|
44944
|
-
findByHash: async () => {
|
|
44945
|
-
throw new Error("database plugin is required");
|
|
44946
|
-
},
|
|
44947
|
-
list: async () => {
|
|
44948
|
-
throw new Error("database plugin is required");
|
|
44949
|
-
},
|
|
44950
|
-
revoke: async () => {
|
|
44951
|
-
throw new Error("database plugin is required");
|
|
44952
|
-
}
|
|
44953
|
-
}
|
|
44954
|
-
},
|
|
44955
|
-
commit: async () => {
|
|
44956
|
-
throw new Error("database plugin is required");
|
|
44852
|
+
adapter: {
|
|
44853
|
+
id: "missing",
|
|
44854
|
+
fits: () => true,
|
|
44855
|
+
get: missingDatabaseError,
|
|
44856
|
+
query: missingDatabaseError,
|
|
44857
|
+
write: missingDatabaseError
|
|
44957
44858
|
}
|
|
44958
|
-
}
|
|
44859
|
+
};
|
|
44959
44860
|
const missingStorageError = async () => {
|
|
44960
44861
|
throw new Error("storage plugin is required");
|
|
44961
44862
|
};
|
|
@@ -45003,7 +44904,6 @@ const getDefaultConfig = () => {
|
|
|
45003
44904
|
return {
|
|
45004
44905
|
cacheDir: path.join("node_modules", ".hot-updater"),
|
|
45005
44906
|
updateStrategy: "appVersion",
|
|
45006
|
-
compressStrategy: "zip",
|
|
45007
44907
|
fingerprint: {},
|
|
45008
44908
|
patch: {
|
|
45009
44909
|
enabled: true,
|
|
@@ -45059,6 +44959,7 @@ const getConfigLoaderOptions = (options) => {
|
|
|
45059
44959
|
const loadConfig = async (options) => {
|
|
45060
44960
|
const { config } = await loadConfig$1(getConfigLoaderOptions(options));
|
|
45061
44961
|
for (const key of ["authorityId", "catalogId"]) if (config && Object.hasOwn(config, key)) throw new Error(`Remove ${key} from hot-updater.config. Catalog identity is managed internally.`);
|
|
44962
|
+
if (config && Object.hasOwn(config, "compressStrategy")) throw new Error("Remove compressStrategy from hot-updater.config. OTA artifacts use manifest files with per-file Brotli compression.");
|
|
45062
44963
|
const mergedConfig = mergeConfigSources(config, getDefaultConfig());
|
|
45063
44964
|
const signing = normalizeSigningConfig(mergedConfig.signing);
|
|
45064
44965
|
return {
|
|
@@ -45216,7 +45117,7 @@ const writeStorageResponseFile = async (response, filePath) => {
|
|
|
45216
45117
|
return;
|
|
45217
45118
|
}
|
|
45218
45119
|
try {
|
|
45219
|
-
await pipeline
|
|
45120
|
+
await pipeline(Readable$1.fromWeb(response.body), createWriteStream(filePath));
|
|
45220
45121
|
} catch (error) {
|
|
45221
45122
|
await fs$2.rm(filePath, { force: true });
|
|
45222
45123
|
throw error;
|
|
@@ -45252,11 +45153,6 @@ function verifySignedFileHash({ actualFileHash, publicKey, signedFileHash }) {
|
|
|
45252
45153
|
return false;
|
|
45253
45154
|
}
|
|
45254
45155
|
}
|
|
45255
|
-
function getArchiveFilename(storageUri) {
|
|
45256
|
-
const protocol = new URL(storageUri).protocol.replace(":", "");
|
|
45257
|
-
const { key } = parseStorageUri(storageUri, protocol);
|
|
45258
|
-
return path$1.posix.basename(key) || "bundle.zip";
|
|
45259
|
-
}
|
|
45260
45156
|
const getRelativeStorageDir = (relativePath) => {
|
|
45261
45157
|
const normalized = relativePath.replace(/\\/g, "/");
|
|
45262
45158
|
const dirname = path$1.posix.dirname(normalized);
|
|
@@ -45273,7 +45169,7 @@ async function prepareManifestAssetUploadFile({ assetPath, sourcePath, workDir }
|
|
|
45273
45169
|
if (getManifestAssetDownloadPath(assetPath) === assetPath) return sourcePath;
|
|
45274
45170
|
const uploadPath = resolvePreparedUploadPath(workDir, assetPath);
|
|
45275
45171
|
await fs$2.mkdir(path$1.dirname(uploadPath), { recursive: true });
|
|
45276
|
-
await pipeline
|
|
45172
|
+
await pipeline(createReadStream(sourcePath), createBrotliCompress({ params: { [constants$1.BROTLI_PARAM_QUALITY]: 11 } }), createWriteStream(uploadPath));
|
|
45277
45173
|
return uploadPath;
|
|
45278
45174
|
}
|
|
45279
45175
|
async function prepareContentAddressedUploadFile({ sourcePath, storagePath, workDir }) {
|
|
@@ -45290,9 +45186,10 @@ async function prepareManifestAssetUploadTargets({ extractDir, manifest, workDir
|
|
|
45290
45186
|
for (const assetPath of assetPaths) {
|
|
45291
45187
|
const asset = manifest.assets?.[assetPath];
|
|
45292
45188
|
if (!asset?.fileHash) throw new Error(`Manifest file hash not found for ${assetPath}`);
|
|
45189
|
+
const sourcePath = resolveExtractedPath(extractDir, assetPath);
|
|
45293
45190
|
const uploadSourcePath = await prepareManifestAssetUploadFile({
|
|
45294
45191
|
assetPath,
|
|
45295
|
-
sourcePath
|
|
45192
|
+
sourcePath,
|
|
45296
45193
|
workDir
|
|
45297
45194
|
});
|
|
45298
45195
|
const downloadByteSize = await getStorageFileByteSize(uploadSourcePath);
|
|
@@ -45301,6 +45198,7 @@ async function prepareManifestAssetUploadTargets({ extractDir, manifest, workDir
|
|
|
45301
45198
|
if (downloadFileHash !== void 0 && !isContentAddressedAssetFileHash(downloadFileHash)) throw new Error(`Prepared asset hash must be a lowercase SHA-256 hash: ${assetPath}`);
|
|
45302
45199
|
const nextAsset = {
|
|
45303
45200
|
...asset,
|
|
45201
|
+
byteSize: (await fs$2.stat(sourcePath)).size,
|
|
45304
45202
|
downloadByteSize
|
|
45305
45203
|
};
|
|
45306
45204
|
delete nextAsset.downloadFileHash;
|
|
@@ -45330,143 +45228,81 @@ function resolveExtractedPath(rootDir, entryName) {
|
|
|
45330
45228
|
const normalizedEntryName = entryName.replaceAll("\\", "/");
|
|
45331
45229
|
const entryPath = path$1.resolve(rootDir, normalizedEntryName);
|
|
45332
45230
|
const relativePath = path$1.relative(rootDir, entryPath);
|
|
45333
|
-
if (relativePath.startsWith("..") || path$1.isAbsolute(relativePath) || normalizedEntryName.startsWith("/")) throw new Error(`Invalid
|
|
45231
|
+
if (relativePath.startsWith("..") || path$1.isAbsolute(relativePath) || normalizedEntryName.startsWith("/")) throw new Error(`Invalid manifest asset path: ${entryName}`);
|
|
45334
45232
|
return entryPath;
|
|
45335
45233
|
}
|
|
45336
|
-
async function
|
|
45234
|
+
async function downloadStorageObject(storageUri, storagePlugin, outputPath) {
|
|
45337
45235
|
const protocol = new URL(storageUri).protocol.replace(":", "");
|
|
45338
45236
|
if (storagePlugin?.protocol === protocol) {
|
|
45339
|
-
await writeStorageFile(storagePlugin, storageUri,
|
|
45237
|
+
await writeStorageFile(storagePlugin, storageUri, outputPath);
|
|
45340
45238
|
return;
|
|
45341
45239
|
}
|
|
45342
45240
|
if (protocol === "http" || protocol === "https") {
|
|
45343
|
-
await downloadFromUrl(storageUri,
|
|
45241
|
+
await downloadFromUrl(storageUri, outputPath);
|
|
45344
45242
|
return;
|
|
45345
45243
|
}
|
|
45346
45244
|
throw new Error(`No storage plugin for protocol: ${protocol}`);
|
|
45347
45245
|
}
|
|
45348
45246
|
async function downloadFromUrl(fileUrl, filePath) {
|
|
45349
45247
|
const response = await fetch(fileUrl);
|
|
45350
|
-
if (!response.ok) throw new Error(`Failed to download
|
|
45248
|
+
if (!response.ok) throw new Error(`Failed to download storage object: ${response.statusText}`);
|
|
45351
45249
|
await writeStorageResponseFile(response, filePath);
|
|
45352
45250
|
}
|
|
45353
|
-
async function
|
|
45354
|
-
|
|
45355
|
-
|
|
45356
|
-
|
|
45357
|
-
const
|
|
45358
|
-
|
|
45359
|
-
|
|
45360
|
-
|
|
45251
|
+
async function downloadManifestAssets({ bundle, manifest, outputDir, storagePlugin, workDir }) {
|
|
45252
|
+
await runWithConcurrency(Object.keys(manifest.assets ?? {}).sort((left, right) => left.localeCompare(right)), PROMOTE_ASSET_CONCURRENCY, async (assetPath) => {
|
|
45253
|
+
const asset = manifest.assets?.[assetPath];
|
|
45254
|
+
if (!asset?.fileHash) throw new Error(`Manifest file hash not found for ${assetPath}`);
|
|
45255
|
+
const downloadPath = getManifestAssetDownloadPath(assetPath);
|
|
45256
|
+
const storageUri = resolveManifestAssetStorageUri({
|
|
45257
|
+
assetBaseStorageUri: bundle.assetBaseStorageUri,
|
|
45258
|
+
assetPath: downloadPath,
|
|
45259
|
+
downloadFileHash: asset.downloadFileHash,
|
|
45260
|
+
fileHash: asset.fileHash
|
|
45261
|
+
});
|
|
45262
|
+
const transferPath = resolveExtractedPath(workDir, `downloads/${downloadPath}`);
|
|
45263
|
+
await fs$2.mkdir(path$1.dirname(transferPath), { recursive: true });
|
|
45264
|
+
await downloadStorageObject(storageUri, storagePlugin, transferPath);
|
|
45265
|
+
if (asset.downloadFileHash) {
|
|
45266
|
+
if (await getFileHash(transferPath) !== asset.downloadFileHash.toLowerCase()) throw new Error(`Manifest download hash mismatch for ${assetPath}`);
|
|
45361
45267
|
}
|
|
45268
|
+
const outputPath = resolveExtractedPath(outputDir, assetPath);
|
|
45362
45269
|
await fs$2.mkdir(path$1.dirname(outputPath), { recursive: true });
|
|
45363
|
-
await fs$2.
|
|
45364
|
-
|
|
45365
|
-
}
|
|
45366
|
-
|
|
45367
|
-
const tarPath = path$1.join(extractDir, "bundle.tar");
|
|
45368
|
-
const compressedBuffer = await fs$2.readFile(archivePath);
|
|
45369
|
-
const tarBuffer = brotliDecompressSync(compressedBuffer);
|
|
45370
|
-
await fs$2.writeFile(tarPath, tarBuffer);
|
|
45371
|
-
try {
|
|
45372
|
-
await uo({
|
|
45373
|
-
file: tarPath,
|
|
45374
|
-
cwd: extractDir,
|
|
45375
|
-
gzip: false,
|
|
45376
|
-
strict: true
|
|
45377
|
-
});
|
|
45378
|
-
} finally {
|
|
45379
|
-
await fs$2.rm(tarPath, { force: true });
|
|
45380
|
-
}
|
|
45381
|
-
}
|
|
45382
|
-
async function extractArchive(archivePath, extractDir) {
|
|
45383
|
-
const { format } = detectCompressionFormat(path$1.basename(archivePath));
|
|
45384
|
-
switch (format) {
|
|
45385
|
-
case "zip":
|
|
45386
|
-
await extractZipArchive(archivePath, extractDir);
|
|
45387
|
-
return format;
|
|
45388
|
-
case "tar.gz":
|
|
45389
|
-
await uo({
|
|
45390
|
-
file: archivePath,
|
|
45391
|
-
cwd: extractDir,
|
|
45392
|
-
gzip: true,
|
|
45393
|
-
strict: true
|
|
45394
|
-
});
|
|
45395
|
-
return format;
|
|
45396
|
-
case "tar.br":
|
|
45397
|
-
await extractTarBrArchive(archivePath, extractDir);
|
|
45398
|
-
return format;
|
|
45399
|
-
}
|
|
45400
|
-
}
|
|
45401
|
-
async function getArchiveTargetFiles(bundleDir) {
|
|
45402
|
-
const entries = await fs$2.readdir(bundleDir, { withFileTypes: true });
|
|
45403
|
-
entries.sort((left, right) => left.name.localeCompare(right.name));
|
|
45404
|
-
return entries.map((entry) => ({
|
|
45405
|
-
path: path$1.join(bundleDir, entry.name),
|
|
45406
|
-
name: entry.name
|
|
45407
|
-
}));
|
|
45408
|
-
}
|
|
45409
|
-
async function createArchiveFromDirectory(sourceDir, archivePath, format) {
|
|
45410
|
-
const targetFiles = await getArchiveTargetFiles(sourceDir);
|
|
45411
|
-
switch (format) {
|
|
45412
|
-
case "zip":
|
|
45413
|
-
await createZipTargetFiles({
|
|
45414
|
-
outfile: archivePath,
|
|
45415
|
-
targetFiles
|
|
45416
|
-
});
|
|
45417
|
-
return;
|
|
45418
|
-
case "tar.gz":
|
|
45419
|
-
await createTarGzTargetFiles({
|
|
45420
|
-
outfile: archivePath,
|
|
45421
|
-
targetFiles
|
|
45422
|
-
});
|
|
45423
|
-
return;
|
|
45424
|
-
case "tar.br":
|
|
45425
|
-
await createTarBrTargetFiles({
|
|
45426
|
-
outfile: archivePath,
|
|
45427
|
-
targetFiles
|
|
45428
|
-
});
|
|
45429
|
-
return;
|
|
45430
|
-
}
|
|
45431
|
-
}
|
|
45432
|
-
async function readCopiedBundleManifest(extractDir, nextBundleId) {
|
|
45433
|
-
const manifestPath = path$1.join(extractDir, "manifest.json");
|
|
45434
|
-
try {
|
|
45435
|
-
await fs$2.access(manifestPath);
|
|
45436
|
-
} catch {
|
|
45437
|
-
throw new Error(LEGACY_BUNDLE_ERROR);
|
|
45438
|
-
}
|
|
45439
|
-
const manifest = JSON.parse(await fs$2.readFile(manifestPath, "utf8"));
|
|
45440
|
-
manifest.bundleId = nextBundleId;
|
|
45441
|
-
return {
|
|
45442
|
-
manifest,
|
|
45443
|
-
manifestPath
|
|
45444
|
-
};
|
|
45270
|
+
if (downloadPath === assetPath) await fs$2.copyFile(transferPath, outputPath);
|
|
45271
|
+
else await fs$2.writeFile(outputPath, brotliDecompressSync(await fs$2.readFile(transferPath)));
|
|
45272
|
+
if (await getFileHash(outputPath) !== asset.fileHash.toLowerCase()) throw new Error(`Manifest file hash mismatch for ${assetPath}`);
|
|
45273
|
+
});
|
|
45445
45274
|
}
|
|
45446
|
-
async function
|
|
45447
|
-
const archiveFilename = getArchiveFilename(bundle.storageUri);
|
|
45275
|
+
async function createCopiedBundleArtifacts({ bundle, config, nextBundleId, storagePlugin }) {
|
|
45448
45276
|
const workDir = await fs$2.mkdtemp(path$1.join(os.tmpdir(), "hot-updater-console-promote-"));
|
|
45449
|
-
const sourceArchivePath = path$1.join(workDir, archiveFilename);
|
|
45450
45277
|
const extractDir = path$1.join(workDir, "bundle");
|
|
45451
|
-
const
|
|
45278
|
+
const sourceManifestPath = path$1.join(workDir, "source-manifest.json");
|
|
45279
|
+
const manifestPath = path$1.join(extractDir, "manifest.json");
|
|
45452
45280
|
const uploadedStorageUris = [];
|
|
45453
45281
|
await fs$2.mkdir(extractDir, { recursive: true });
|
|
45454
45282
|
try {
|
|
45455
|
-
await
|
|
45456
|
-
const
|
|
45283
|
+
await downloadStorageObject(bundle.manifestStorageUri, storagePlugin, sourceManifestPath);
|
|
45284
|
+
const actualManifestHash = await getFileHash(sourceManifestPath);
|
|
45457
45285
|
const signingSession = await prepareBundleSigning(config.signing);
|
|
45458
|
-
if (isSignedFileHash(bundle.
|
|
45286
|
+
if (isSignedFileHash(bundle.manifestFileHash)) {
|
|
45459
45287
|
if (!signingSession) throw new Error("Cannot copy a signed bundle without enabled bundle signing configuration.");
|
|
45460
45288
|
if (!verifySignedFileHash({
|
|
45461
|
-
actualFileHash:
|
|
45289
|
+
actualFileHash: actualManifestHash,
|
|
45462
45290
|
publicKey: signingSession.publicKey,
|
|
45463
|
-
signedFileHash: bundle.
|
|
45464
|
-
})) throw new Error("Source
|
|
45465
|
-
} else if (
|
|
45466
|
-
const
|
|
45467
|
-
|
|
45291
|
+
signedFileHash: bundle.manifestFileHash
|
|
45292
|
+
})) throw new Error("Source manifest signature verification failed.");
|
|
45293
|
+
} else if (actualManifestHash !== bundle.manifestFileHash.toLowerCase()) throw new Error("Source manifest file hash verification failed.");
|
|
45294
|
+
const manifest = JSON.parse(await fs$2.readFile(sourceManifestPath, "utf8"));
|
|
45295
|
+
if (!manifest.assets || typeof manifest.assets !== "object") throw new Error(LEGACY_BUNDLE_ERROR);
|
|
45296
|
+
await downloadManifestAssets({
|
|
45297
|
+
bundle,
|
|
45298
|
+
manifest,
|
|
45299
|
+
outputDir: extractDir,
|
|
45300
|
+
storagePlugin,
|
|
45301
|
+
workDir
|
|
45302
|
+
});
|
|
45303
|
+
manifest.bundleId = nextBundleId;
|
|
45468
45304
|
const assetPaths = Object.keys(manifest.assets ?? {}).sort((left, right) => left.localeCompare(right));
|
|
45469
|
-
const sourceIsSigned =
|
|
45305
|
+
const sourceIsSigned = isSignedFileHash(getManifestFileHash(bundle));
|
|
45470
45306
|
const manifestHasSignatures = assetPaths.some((assetPath) => Boolean(manifest.assets?.[assetPath]?.signature));
|
|
45471
45307
|
if (!signingSession && (sourceIsSigned || manifestHasSignatures)) throw new Error("Cannot copy a signed bundle without enabled bundle signing configuration.");
|
|
45472
45308
|
if (signingSession) {
|
|
@@ -45486,16 +45322,22 @@ async function createCopiedBundleArchive({ bundle, config, nextBundleId, storage
|
|
|
45486
45322
|
manifest,
|
|
45487
45323
|
workDir
|
|
45488
45324
|
});
|
|
45325
|
+
const archivePath = path$1.join(workDir, "bundle.tar.br");
|
|
45326
|
+
manifest.archive = await createTarBrTargetFiles({
|
|
45327
|
+
outfile: archivePath,
|
|
45328
|
+
targetFiles: assetPaths.map((name) => ({
|
|
45329
|
+
name,
|
|
45330
|
+
path: resolveExtractedPath(extractDir, name)
|
|
45331
|
+
}))
|
|
45332
|
+
});
|
|
45489
45333
|
await fs$2.writeFile(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`);
|
|
45490
|
-
await fs$2.rm(sourceArchivePath, { force: true });
|
|
45491
|
-
await createArchiveFromDirectory(extractDir, outputArchivePath, format);
|
|
45492
|
-
const fileHash = await getFileHash(outputArchivePath);
|
|
45493
45334
|
const manifestHash = await getFileHash(manifestPath);
|
|
45494
|
-
const nextFileHash = signingSession ? `${SIGNED_HASH_PREFIX}${await signingSession.signFileHash(fileHash)}` : fileHash;
|
|
45495
45335
|
const nextManifestFileHash = signingSession ? `${SIGNED_HASH_PREFIX}${await signingSession.signFileHash(manifestHash)}` : manifestHash;
|
|
45496
|
-
const archiveUpload = await putStorageFile(storagePlugin, createBundleStorageKey(nextBundleId),
|
|
45336
|
+
const archiveUpload = await putStorageFile(storagePlugin, createBundleStorageKey(nextBundleId), archivePath);
|
|
45497
45337
|
uploadedStorageUris.push(archiveUpload.storageUri);
|
|
45498
|
-
const
|
|
45338
|
+
const manifestUpload = await putStorageFile(storagePlugin, createBundleStorageKey(nextBundleId), manifestPath);
|
|
45339
|
+
uploadedStorageUris.push(manifestUpload.storageUri);
|
|
45340
|
+
const assetBaseStorageUri = createStorageRootUriWithPath(manifestUpload.storageUri, nextBundleId, "assets");
|
|
45499
45341
|
for (const assetUploadTarget of assetUploadTargets) {
|
|
45500
45342
|
const storageUri = resolveManifestAssetStorageUri({
|
|
45501
45343
|
assetBaseStorageUri,
|
|
@@ -45506,15 +45348,10 @@ async function createCopiedBundleArchive({ bundle, config, nextBundleId, storage
|
|
|
45506
45348
|
const { exists } = await storagePlugin.exists({ storageUri });
|
|
45507
45349
|
if (!exists) await putStorageFile(storagePlugin, getRelativeStorageDir(assetUploadTarget.storagePath) ? `assets/${getRelativeStorageDir(assetUploadTarget.storagePath)}` : "assets", assetUploadTarget.uploadSourcePath);
|
|
45508
45350
|
}
|
|
45509
|
-
const manifestUpload = await putStorageFile(storagePlugin, createBundleStorageKey(nextBundleId), manifestPath);
|
|
45510
|
-
uploadedStorageUris.push(manifestUpload.storageUri);
|
|
45511
45351
|
return {
|
|
45512
45352
|
bundle: {
|
|
45513
45353
|
...bundle,
|
|
45514
45354
|
id: nextBundleId,
|
|
45515
|
-
archiveByteSize: archiveUpload.byteSize,
|
|
45516
|
-
storageUri: archiveUpload.storageUri,
|
|
45517
|
-
fileHash: nextFileHash,
|
|
45518
45355
|
metadata: stripBundleArtifactMetadata(bundle.metadata),
|
|
45519
45356
|
assetBaseStorageUri,
|
|
45520
45357
|
patches: [],
|
|
@@ -45611,4 +45448,4 @@ function transformTemplate(templateString, values) {
|
|
|
45611
45448
|
return result;
|
|
45612
45449
|
}
|
|
45613
45450
|
//#endregion
|
|
45614
|
-
export { BuildLogger, ConfigBuilder, HOT_UPDATER_SERVER_PACKAGE_VERSION_ENV, HotUpdateDirUtil, InitEnvFileError, InitError, LEGACY_BUNDLE_ERROR, LegacyInfrastructureError, MissingInitInputsError, assertInfrastructureGenerationAtUrl, assertInfrastructureGenerationPayload, assertInitInputs, assertInitProviderInputs, banner, typedColors as colors, confirmInitInputPersistence, copyDirToTmp,
|
|
45451
|
+
export { BuildLogger, ConfigBuilder, HOT_UPDATER_PLUGINS_PATH, HOT_UPDATER_SERVER_PACKAGE_VERSION_ENV, HotUpdateDirUtil, InitEnvFileError, InitError, LEGACY_BUNDLE_ERROR, LegacyInfrastructureError, MissingInitInputsError, assertInfrastructureGenerationAtUrl, assertInfrastructureGenerationPayload, assertInitInputs, assertInitProviderInputs, banner, typedColors as colors, confirmInitInputPersistence, copyDirToTmp, createCopiedBundleArtifacts, createHotUpdaterConfigScaffold, createHotUpdaterConfigScaffoldFromBuilder, createLogWriter, createTarBrTargetFiles, createZip, decryptJson, defineInitProvider, encryptJson, ensureInstallPackages, generateHotUpdaterPlugins, getAndroidSdkPath, getBundleSigningPublicKey, getCwd, getHotUpdaterEnvValue, getHotUpdaterInitInputEnv, getInitProviderEnvVars, getInitProviderTextPromptValues, getMissingInitInputs, getMissingInitProviderInputs, getPackageManager, getReactNativeMetadatas, getStorageFileByteSize, link, loadConfig, loadHotUpdaterPlugins, log, makeEnv, p, prepareBundleSigning, printAppSetup, printBanner, putStorageFile, readBundleSigningPublicKeyFile, readHotUpdaterEnv, readHotUpdaterInitEnv, readPackageUp, renderAppSetup, renderHotUpdaterPlugins, renderImportStatements, resolveHotUpdaterServerVersion, resolveInitProviderInput, resolveInitProviderInputs, resolvePackageVersion, shouldAutoSelectOnlyInitResource, stripAnsi, transformEnv, transformTemplate, writeHotUpdaterConfig, writeHotUpdaterPlugins, writeStorageFile, writeStorageResponseFile };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hot-updater/cli-tools",
|
|
3
|
-
"version": "1.0.0-rc.
|
|
3
|
+
"version": "1.0.0-rc.17",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=20.19.0"
|
|
@@ -49,8 +49,8 @@
|
|
|
49
49
|
"oxc-parser": "0.141.0",
|
|
50
50
|
"oxc-transform": "0.141.0",
|
|
51
51
|
"unconfig": "7.5.0",
|
|
52
|
-
"@hot-updater/core": "1.0.0-rc.
|
|
53
|
-
"@hot-updater/plugin-core": "1.0.0-rc.
|
|
52
|
+
"@hot-updater/core": "1.0.0-rc.15",
|
|
53
|
+
"@hot-updater/plugin-core": "1.0.0-rc.17"
|
|
54
54
|
},
|
|
55
55
|
"devDependencies": {
|
|
56
56
|
"@clack/prompts": "1.7.0",
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"tar": "^7.5.16",
|
|
65
65
|
"verkit": "0.4.0",
|
|
66
66
|
"workspace-tools": "^0.41.7",
|
|
67
|
-
"@hot-updater/test-utils": "1.0.0-rc.
|
|
67
|
+
"@hot-updater/test-utils": "1.0.0-rc.17"
|
|
68
68
|
},
|
|
69
69
|
"inlinedDependencies": {
|
|
70
70
|
"@babel/code-frame": "7.29.0",
|
|
@@ -174,7 +174,7 @@
|
|
|
174
174
|
"7.1.0"
|
|
175
175
|
],
|
|
176
176
|
"strip-final-newline": "4.0.0",
|
|
177
|
-
"tar": "7.5.
|
|
177
|
+
"tar": "7.5.16",
|
|
178
178
|
"to-regex-range": "5.0.1",
|
|
179
179
|
"unicorn-magic": [
|
|
180
180
|
"0.1.0",
|