@hot-updater/cli-tools 1.1.4 → 1.2.0-rc.1

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.
Files changed (3) hide show
  1. package/dist/index.d.mts +539 -15
  2. package/dist/index.mjs +1541 -187
  3. package/package.json +5 -5
package/dist/index.d.mts CHANGED
@@ -1,26 +1,78 @@
1
1
  import { Readable } from "stream";
2
2
  import { Key as Key$1 } from "node:readline";
3
- import { AnyHotUpdaterPlugin, BundleSigningAdapter, ConfigInput, ConfiguredDatabase, EngineDatabase, HotUpdaterCoreApi, LocalSigningConfig, Migrator, NativeFingerprint, NativeFingerprintOptions, Platform, PluginClientPlugin, RequiredDeep, SchemaGenerator, SigningConfig, StorageAdapter, StorageAdapterWith, StoragePutResult, ToolingDatabase } from "@hot-updater/plugin-core";
3
+ import { AnyHotUpdaterPlugin, BundleSigningAdapter, ConfigInput, ConfiguredDatabase, EngineDatabase, HotUpdaterCoreApi, LocalSigningConfig, Migrator, NativeFingerprint, NativeFingerprintOptions, Platform, PluginClientPlugin, RequiredDeep, SchemaGenerator, SecretsAdapter, SigningConfig, StorageAdapter, StorageAdapterWith, StoragePutResult, ToolingDatabase } from "@hot-updater/plugin-core";
4
4
  import { Readable as Readable$1, Writable } from "node:stream";
5
5
  import { ManifestArchive } from "@hot-updater/protocol";
6
6
  //#region src/BuildLogger.d.ts
7
7
  type LinePattern = string | RegExp;
8
+ /** The tool's output a failed build prints: its errors, else its last lines. */
9
+ interface BuildFailureSummaryConfig {
10
+ /** Lines kept wherever they are, such as a compiler's `error:` lines. */
11
+ lines: LinePattern[];
12
+ /**
13
+ * Blocks kept whole: from a line matching `start` through one matching
14
+ * `end`, or up to it without `includeEnd`.
15
+ */
16
+ blocks: {
17
+ start: LinePattern;
18
+ end: LinePattern;
19
+ includeEnd: boolean;
20
+ }[];
21
+ }
8
22
  interface BuildLoggerConfig {
9
23
  logPrefix: string;
10
24
  /** Lines that should be surfaced in prompt output as important events. */
11
25
  importantLogPatterns: LinePattern[];
12
26
  /** Progress stages: stage index advances when corresponding output patterns are observed. */
13
27
  progressStages: LinePattern[][];
28
+ /** What a failure prints from the tool's raw output. */
29
+ failureSummary: BuildFailureSummaryConfig;
30
+ }
31
+ /**
32
+ * A native build that failed, after its logger printed the summary of the
33
+ * tool's output and the log file's path, so its message is one line.
34
+ */
35
+ declare class BuildFailedError extends Error {
36
+ name: string;
37
+ /** The build log, relative to the project, or null without one. */
38
+ readonly logPath: string | null;
39
+ /** The lines of the tool's output the summary printed. */
40
+ readonly summary: string[];
41
+ constructor(message: string, { logPath, summary, cause }: {
42
+ logPath: string | null;
43
+ summary: string[];
44
+ cause?: unknown;
45
+ });
14
46
  }
15
47
  declare class BuildLogger {
16
48
  private readonly config;
17
49
  private state;
18
50
  private logWriter?;
51
+ private summaryLines;
52
+ private tailLines;
53
+ private openBlock?;
19
54
  private readonly promptProgress;
20
55
  private readonly stageCount;
21
56
  constructor(config: BuildLoggerConfig);
22
57
  start(): Promise<void>;
23
- processStream(input: Readable): Promise<void>;
58
+ /**
59
+ * Writes the tool's raw output to the log file and reads its failure
60
+ * summary from it, and shows progress from `display`, a formatter's
61
+ * output of it such as xcbeautify's, or from the raw output without one.
62
+ */
63
+ processStream(input: Readable, { display }?: {
64
+ display?: Readable;
65
+ }): Promise<void>;
66
+ /** The build log, relative to the project, or null without one. */
67
+ get logPath(): string | null;
68
+ /**
69
+ * The lines of the raw output a failure prints: the ones the config's
70
+ * `failureSummary` keeps, deduplicated, or the last lines without any.
71
+ */
72
+ get failureSummary(): string[];
73
+ private consumeSummaryStream;
74
+ private processSummaryLine;
75
+ private keepSummaryLine;
24
76
  private consumeProgressStream;
25
77
  private processProgressLine;
26
78
  stop(message?: string, success?: boolean): void;
@@ -29,6 +81,11 @@ declare class BuildLogger {
29
81
  private updateProgress;
30
82
  private finishRemainingProgress;
31
83
  private shouldLogLine;
84
+ /**
85
+ * Prints the failure summary and the log's path to stderr, so a `--json`
86
+ * command's stdout stays its JSON.
87
+ */
88
+ private showFailureSummary;
32
89
  private showLogFileLocation;
33
90
  }
34
91
  //#endregion
@@ -277,6 +334,165 @@ declare const createZip: ({ outfile, targetDir, excludeExts }: {
277
334
  excludeExts?: string[];
278
335
  }) => Promise<string>;
279
336
  //#endregion
337
+ //#region src/credentialFiles.d.ts
338
+ /**
339
+ * Temporary files holding credential values a tool reads from disk, such as
340
+ * an App Store Connect `.p8` key or an Android keystore.
341
+ */
342
+ interface CredentialFiles {
343
+ /**
344
+ * Writes `contents` to a new file named `fileName`, readable only by the
345
+ * current user (0600), and returns its path. String contents are masked in
346
+ * logs.
347
+ */
348
+ write(fileName: string, contents: string | Uint8Array): Promise<string>;
349
+ /** Deletes every file written so far; nothing can be written after it. */
350
+ dispose(): Promise<void>;
351
+ }
352
+ //#endregion
353
+ //#region src/credentialEnvNames.d.ts
354
+ /**
355
+ * The environment variables that override each kind, one entry per field.
356
+ * A field with two names takes a file path or the file's contents; the path
357
+ * wins when both are set.
358
+ */
359
+ declare const CREDENTIAL_ENV_NAMES: {
360
+ readonly "asc-api-key": readonly [readonly ["HOT_UPDATER_ASC_KEY_PATH", "HOT_UPDATER_ASC_KEY"], readonly ["HOT_UPDATER_ASC_KEY_ID"], readonly ["HOT_UPDATER_ASC_ISSUER_ID"]];
361
+ readonly "android-keystore": readonly [readonly ["HOT_UPDATER_ANDROID_KEYSTORE_PATH", "HOT_UPDATER_ANDROID_KEYSTORE_BASE64"], readonly ["HOT_UPDATER_ANDROID_KEYSTORE_PASSWORD"], readonly ["HOT_UPDATER_ANDROID_KEY_ALIAS"], readonly ["HOT_UPDATER_ANDROID_KEY_PASSWORD"]];
362
+ readonly "play-service-account": readonly [readonly ["HOT_UPDATER_PLAY_SERVICE_ACCOUNT_PATH", "HOT_UPDATER_PLAY_SERVICE_ACCOUNT_JSON"]];
363
+ };
364
+ //#endregion
365
+ //#region src/credentialResolver.d.ts
366
+ /**
367
+ * The build credentials the CLI resolves by name. Deploy credentials reach
368
+ * the config's adapters through `secretEnv`.
369
+ */
370
+ interface Credentials {
371
+ /** App Store Connect API key, for automatic signing and uploads. */
372
+ "asc-api-key": {
373
+ /** A 0600 temporary file or the path the user set. */
374
+ readonly keyPath: string;
375
+ readonly keyId: string;
376
+ readonly issuerId: string;
377
+ };
378
+ /** Android release keystore, for Gradle signing. */
379
+ "android-keystore": {
380
+ /** A 0600 temporary file or the path the user set. */
381
+ readonly storeFile: string;
382
+ readonly storePassword: string;
383
+ readonly keyAlias: string;
384
+ readonly keyPassword: string;
385
+ };
386
+ /** Google Play service account, kept in memory. */
387
+ "play-service-account": {
388
+ readonly json: string;
389
+ };
390
+ }
391
+ type CredentialKind = keyof Credentials;
392
+ interface CredentialRequest<TKind extends CredentialKind> {
393
+ readonly kind: TKind;
394
+ /**
395
+ * The item's name, for a project with several items of one kind (such as
396
+ * `widget-keystore`). Defaults to the kind. Environment overrides apply to
397
+ * every item of a kind.
398
+ */
399
+ readonly name?: string;
400
+ }
401
+ /**
402
+ * Resolves the credentials a command needs. Commands call `dispose` in a
403
+ * `finally` (or use `withCredentialResolver`); temporary files are also
404
+ * deleted when the process exits.
405
+ */
406
+ interface CredentialResolver {
407
+ resolve<TKind extends CredentialKind>(request: CredentialRequest<TKind>): Promise<Credentials[TKind]>;
408
+ /**
409
+ * Waits for resolutions in flight, then deletes every temporary file this
410
+ * resolver wrote. The resolver resolves nothing after it.
411
+ */
412
+ dispose(): Promise<void>;
413
+ }
414
+ /**
415
+ * The sentence every "credential unavailable" message ends with: the
416
+ * environment variables that provide `kind` whatever the secrets adapter.
417
+ */
418
+ declare const credentialOverrideHint: (kind: CredentialKind) => string;
419
+ /**
420
+ * The command that stores a credential of `kind` you have as `name` through
421
+ * the config's `secrets` adapter, from its files.
422
+ */
423
+ declare const credentialPutCommand: (kind: CredentialKind, name?: string) => string;
424
+ /** The credentials Hot Updater issues itself after a sign-in. */
425
+ type IssuedCredentialKind = Exclude<CredentialKind, "android-keystore">;
426
+ /**
427
+ * The command that signs in once, at a terminal, and stores the key Hot
428
+ * Updater issues as `name`: an App Store Connect API key after an Apple
429
+ * Account sign-in, a Play service account after a Google one.
430
+ */
431
+ declare const credentialIssueCommand: (kind: IssuedCredentialKind, name?: string) => string;
432
+ /** The command group of each issued kind's shortcut, `<group> login`. */
433
+ declare const CREDENTIAL_LOGIN_GROUPS: {
434
+ readonly "asc-api-key": "apple";
435
+ readonly "play-service-account": "google-play";
436
+ };
437
+ /**
438
+ * The command people meet first that issues `kind` as `name`: its shortcut,
439
+ * `apple login` for an App Store Connect API key or `google-play login`
440
+ * for a Play service account, which takes nothing and stores the kind's
441
+ * own name; for another name, `credentialIssueCommand`.
442
+ */
443
+ declare const credentialLoginCommand: (kind: IssuedCredentialKind, name?: string) => string;
444
+ /**
445
+ * The command that stores a missing credential of `kind` as `name`: the
446
+ * keystore you have, or the key Hot Updater issues after a sign-in.
447
+ */
448
+ declare const credentialStoreCommand: (kind: CredentialKind, name?: string) => string;
449
+ declare class CredentialUnavailableError extends Error {
450
+ readonly kind: CredentialKind;
451
+ /** The environment variables that can provide this credential. */
452
+ readonly envNames: readonly string[];
453
+ constructor(kind: CredentialKind, message: string, options?: {
454
+ cause?: unknown;
455
+ });
456
+ }
457
+ /**
458
+ * Masks a credential's JSON value in the CLI's output: the whole value, and
459
+ * each field but those that identify it, such as `keyId` and `keyAlias`,
460
+ * so a password or a key a log prints alone stays masked. A value that is
461
+ * no JSON object is masked whole.
462
+ */
463
+ declare const registerCredentialValue: (value: string) => void;
464
+ interface CreateCredentialResolverOptions {
465
+ /**
466
+ * Environment values read after `process.env`, the same lookup as
467
+ * `getHotUpdaterEnvValue`.
468
+ */
469
+ readonly env?: Readonly<Record<string, string>>;
470
+ /**
471
+ * Where to find an item no environment override sets, or a function that
472
+ * returns it when an item resolves, for a command whose config loads
473
+ * after the resolver is created. Defaults to the config `loadConfig` last
474
+ * loaded, the default store when it sets none.
475
+ */
476
+ readonly secrets?: SecretsAdapter | (() => SecretsAdapter);
477
+ /** The project directory the adapter is given. Defaults to `getCwd()`. */
478
+ readonly cwd?: string;
479
+ }
480
+ /**
481
+ * Resolves each item from its environment overrides when any is set, and
482
+ * otherwise from the config's `secrets` adapter as one value named by the
483
+ * item, so overrides never reach the store. When the adapter fails or holds
484
+ * no such value, the error names the environment variables that can
485
+ * provide the item instead. Nothing is cached, values are never written to
486
+ * disk except as 0600 temporary files, are never set in `process.env`, and
487
+ * every secret is masked in logs.
488
+ */
489
+ declare const createCredentialResolver: ({ env, secrets, cwd }?: CreateCredentialResolverOptions) => CredentialResolver;
490
+ /**
491
+ * Runs `run` with a credential resolver and deletes its temporary files
492
+ * when `run` settles.
493
+ */
494
+ declare const withCredentialResolver: <T>(run: (resolver: CredentialResolver) => Promise<T>, options?: CreateCredentialResolverOptions) => Promise<T>;
495
+ //#endregion
280
496
  //#region src/crypto.d.ts
281
497
  declare const encryptJson: (jsonData: Record<string, any>, secretKey: string) => string;
282
498
  declare const decryptJson: <T>(encryptedData: string, secretKey: string) => T;
@@ -386,8 +602,15 @@ type HotUpdaterInitEnv = {
386
602
  };
387
603
  declare const getHotUpdaterInitInputEnv: ({ env, managedEnv }: HotUpdaterInitEnv, nonInteractive: boolean) => Readonly<Record<string, string>>;
388
604
  declare const readHotUpdaterInitEnv: (cwd: string, envFile?: string) => Promise<HotUpdaterInitEnv>;
389
- declare const readHotUpdaterEnv: (cwd: string) => Promise<Readonly<Record<string, string>>>;
390
605
  declare const getHotUpdaterEnvValue: (env: Readonly<Record<string, string>>, key: string) => string | undefined;
606
+ /**
607
+ * An env file's variables as `process.loadEnvFile` sets them, the way
608
+ * `hot-updater.config.ts` loads `.env.hotupdater`: inline comments, quotes,
609
+ * and `export` prefixes included.
610
+ */
611
+ declare const parseLoadedEnv: (content: string) => Readonly<Record<string, string>>;
612
+ /** `cwd`'s `.env.hotupdater` as the config loads it; empty when there is none. */
613
+ declare const readLoadedHotUpdaterEnv: (cwd: string) => Promise<Readonly<Record<string, string>>>;
391
614
  //#endregion
392
615
  //#region src/HotUpdateDirUtil.d.ts
393
616
  declare const HotUpdateDirUtil: {
@@ -510,6 +733,25 @@ declare const assertInitInputs: ({ inputs, strict }: {
510
733
  }) => void;
511
734
  declare const getMissingInitInputs: (inputs: Readonly<Record<string, string | undefined>>) => readonly string[];
512
735
  //#endregion
736
+ //#region src/interactive.d.ts
737
+ /**
738
+ * Whether the environment is a CI run: `CI` is set to anything but empty,
739
+ * `0`, or `false`. GitHub Actions, GitLab CI, CircleCI, Buildkite, Bitrise,
740
+ * and Codemagic set it.
741
+ */
742
+ declare const isCI: (env?: Readonly<Record<string, string | undefined>>) => boolean;
743
+ /**
744
+ * Why the CLI can't ask anything here, or undefined when it can: in CI,
745
+ * where a runner may give the job a terminal nobody answers in, and without
746
+ * a terminal on stdin. Prompts and sign-ins both check it.
747
+ */
748
+ declare const nonInteractiveReason: ({ env, input }?: {
749
+ readonly env?: Readonly<Record<string, string | undefined>>;
750
+ readonly input?: {
751
+ readonly isTTY?: boolean;
752
+ };
753
+ }) => string | undefined;
754
+ //#endregion
513
755
  //#region src/interfaceFingerprint.d.ts
514
756
  /**
515
757
  * The engine fingerprint.json records for the interface fingerprint. Change
@@ -549,7 +791,37 @@ interface NativeInterface {
549
791
  * engine, read from the files the framework itself reads.
550
792
  */
551
793
  settings?: Record<string, string>;
794
+ /**
795
+ * What autolinking printed, as parsed: the React Native config, and
796
+ * expo-modules-autolinking's `resolve` when the app links Expo modules.
797
+ */
798
+ autolinking?: {
799
+ reactNative: unknown;
800
+ expoModules: unknown;
801
+ };
552
802
  }
803
+ /**
804
+ * The command, run with Node.js, that lists the React Native packages a
805
+ * build links, chosen as Expo and @expo/fingerprint choose it: Expo's
806
+ * autolinking from expo-modules-autolinking 1.12 (SDK 52), else React Native
807
+ * CLI, as for an app without Expo. The native templates also fall back to
808
+ * React Native CLI when `EXPO_USE_COMMUNITY_AUTOLINKING=1`, as Expo
809
+ * documents.
810
+ */
811
+ declare const reactNativeConfigCommand: (cwd: string, platform: Platform, env?: NodeJS.ProcessEnv) => string[];
812
+ /**
813
+ * The command that lists the React Native packages the native project of a
814
+ * build adapter links, as the adapter's own fingerprint runs it: `rock config`
815
+ * for Rock, React Native CLI's `config` for the bare adapter, and
816
+ * {@link reactNativeConfigCommand} for Expo and any other adapter.
817
+ */
818
+ declare const autolinkingConfigCommand: (cwd: string, platform: Platform, { buildAdapter, env }?: {
819
+ buildAdapter?: string;
820
+ env?: NodeJS.ProcessEnv;
821
+ }) => {
822
+ command: string;
823
+ args: string[];
824
+ };
553
825
  /**
554
826
  * The expo-modules-autolinking an Expo app builds with, resolved from its
555
827
  * `expo` package as the native templates resolve it.
@@ -617,16 +889,22 @@ declare const createLogWriter: ({ prefix, logFilePath }: {
617
889
  }) => Promise<HotUpdaterLogWriter>;
618
890
  //#endregion
619
891
  //#region src/localBundleSigning.d.ts
620
- declare const normalizeSigningConfig: (signing: SigningConfig | undefined) => BundleSigningAdapter | Extract<LocalSigningConfig, {
892
+ /** The secret `keys generate --secret` stores the private key as by default. */
893
+ declare const DEFAULT_SIGNING_KEY_SECRET = "bundle-signing-key";
894
+ /** Local signing enabled, with its private key from a file or a secret. */
895
+ type EnabledLocalSigningConfig = Extract<LocalSigningConfig, {
621
896
  enabled: true;
622
- }> | undefined;
897
+ }>;
898
+ declare const normalizeSigningConfig: (signing: SigningConfig | undefined, { secrets }?: {
899
+ readonly secrets?: SecretsAdapter;
900
+ }) => BundleSigningAdapter | EnabledLocalSigningConfig | undefined;
623
901
  //#endregion
624
902
  //#region src/loadConfig.d.ts
625
903
  type HotUpdaterConfigOptions = {
626
904
  platform: Platform;
627
905
  channel: string;
628
906
  } | null;
629
- type ConfigResponse = RequiredDeep<Omit<ConfigInput, "database" | "storage" | "plugins" | "signing">> & {
907
+ type ConfigResponse = RequiredDeep<Omit<ConfigInput, "database" | "storage" | "plugins" | "signing" | "secrets">> & {
630
908
  /** The server's database, or `standaloneRepository(...)`; absent when the config names none. */
631
909
  database?: ConfiguredDatabase;
632
910
  /** Where the CLI uploads bundles; absent when the config names none. */
@@ -634,6 +912,12 @@ type ConfigResponse = RequiredDeep<Omit<ConfigInput, "database" | "storage" | "p
634
912
  /** The plugins the server runs; none when the config lists none. */
635
913
  plugins: readonly AnyHotUpdaterPlugin[];
636
914
  signing?: ReturnType<typeof normalizeSigningConfig>;
915
+ /**
916
+ * Where `secret:` references and issued keys are read and stored: the
917
+ * config's adapter with `localSecrets()`'s store after it (`withLocalKeyStore`),
918
+ * or `localSecrets()` when it sets none.
919
+ */
920
+ secrets: SecretsAdapter;
637
921
  };
638
922
  declare const loadConfig: (options: HotUpdaterConfigOptions) => Promise<ConfigResponse>;
639
923
  /**
@@ -745,13 +1029,14 @@ declare const createMigrator: ({ database, plugins }: ToolingSource) => Migrator
745
1029
  declare const generateSchema: ({ database, plugins }: ToolingSource, version: Parameters<SchemaGenerator>[0], name?: Parameters<SchemaGenerator>[1]) => ReturnType<SchemaGenerator>;
746
1030
  //#endregion
747
1031
  //#region src/log.d.ts
1032
+ type LogMessage = string | number | null | undefined;
748
1033
  declare const log: {
749
- normal: (message: string | number | null | undefined) => void;
750
- success: (message: string | number | null | undefined) => void;
751
- info: (message: string | number | null | undefined) => void;
752
- error: (message: string | number | null | undefined) => void;
753
- warn: (message: string | number | null | undefined) => void;
754
- debug: (message: string | number | null | undefined) => void;
1034
+ normal: (message: LogMessage) => void;
1035
+ success: (message: LogMessage) => void;
1036
+ info: (message: LogMessage) => void;
1037
+ error: (message: LogMessage) => void;
1038
+ warn: (message: LogMessage) => void;
1039
+ debug: (message: LogMessage) => void;
755
1040
  };
756
1041
  //#endregion
757
1042
  //#region src/makeEnv.d.ts
@@ -762,8 +1047,24 @@ type EnvVarValue = string | {
762
1047
  declare const makeEnv: (newEnvVars: Record<string, EnvVarValue>, filePath?: string, options?: {
763
1048
  readonly preserveKeys?: readonly string[];
764
1049
  readonly removeKeys?: readonly string[];
1050
+ /** Rewrites only a file that holds exactly this, else throws. */
1051
+ readonly expectedContent?: string;
765
1052
  }) => Promise<string>;
766
1053
  //#endregion
1054
+ //#region src/minBundleId.d.ts
1055
+ /**
1056
+ * The MIN_BUNDLE_ID a native build compiles in, which is also the ID of its
1057
+ * built-in bundle: a UUIDv7 of the build's millisecond whose random bits are
1058
+ * all zero, `<ts>-<ts>-7000-8000-000000000000`, as the SDK's podspec script
1059
+ * phase and Gradle task generate it. The bundles `hot-updater deploy` issued
1060
+ * before the build sort before it, and the ones it issues afterwards sort
1061
+ * after it. Bundle IDs share one space across platforms, so two builds that
1062
+ * start in the same millisecond get the same one: `native-build ios|android`
1063
+ * steps past an ID the registry holds before it builds, and the registry
1064
+ * refuses a second registration of one.
1065
+ */
1066
+ declare const createMinBundleId: (nowMs?: number) => string;
1067
+ //#endregion
767
1068
  //#region src/moduleSpecifiers.d.ts
768
1069
  /**
769
1070
  * The modules `source` imports or re-exports, statically or with an
@@ -1063,10 +1364,10 @@ declare class AutocompletePrompt<T extends OptionLike$1> extends Prompt<T['value
1063
1364
  type DateFormat = 'YMD' | 'MDY' | 'DMY';
1064
1365
  declare function isCancel(value: unknown): value is symbol;
1065
1366
  declare namespace index_d_exports {
1066
- export { AutocompleteMultiSelectOptions, AutocompleteOptions, BoxAlignment, BoxOptions, ClackSettings, CommonOptions, ConfirmOptions, DateFormat, DateOptions, GroupMultiSelectOptions, LimitOptionsParams, LogMessageOptions, MULTISELECT_INSTRUCTIONS, MultiLineOptions, MultiSelectOptions, NoteOptions, Option, PasswordOptions, PathOptions, ProgressOptions, ProgressResult, PromptGroup, PromptGroupAwaitedReturn, PromptGroupOptions, SELECT_INSTRUCTIONS, S_BAR, S_BAR_END, S_BAR_END_RIGHT, S_BAR_H, S_BAR_START, S_BAR_START_RIGHT, S_CHECKBOX_ACTIVE, S_CHECKBOX_INACTIVE, S_CHECKBOX_SELECTED, S_CONNECT_LEFT, S_CORNER_BOTTOM_LEFT, S_CORNER_BOTTOM_RIGHT, S_CORNER_TOP_LEFT, S_CORNER_TOP_RIGHT, S_ERROR, S_INFO, S_PASSWORD_MASK, S_RADIO_ACTIVE, S_RADIO_INACTIVE, S_STEP_ACTIVE, S_STEP_CANCEL, S_STEP_ERROR, S_STEP_SUBMIT, S_SUCCESS, S_WARN, SelectKeyOptions, SelectOptions, SpinnerOptions, SpinnerResult, Task, TaskLogCompletionOptions, TaskLogMessageOptions, TaskLogOptions, TextOptions, autocomplete, autocompleteMultiselect, box, cancel, confirm, date, formatInstructionFooter, group, groupMultiselect, intro, isCI, isCancel, isTTY, limitOptions, log$1 as log, multiline, multiselect, note, outro, password, path, progress, select, selectKey, settings$1 as settings, spinner, stream, symbol, symbolBar, taskLog, tasks, text, unicode, unicodeOr, updateSettings };
1367
+ export { AutocompleteMultiSelectOptions, AutocompleteOptions, BoxAlignment, BoxOptions, ClackSettings, CommonOptions, ConfirmOptions, DateFormat, DateOptions, GroupMultiSelectOptions, LimitOptionsParams, LogMessageOptions, MULTISELECT_INSTRUCTIONS, MultiLineOptions, MultiSelectOptions, NoteOptions, Option, PasswordOptions, PathOptions, ProgressOptions, ProgressResult, PromptGroup, PromptGroupAwaitedReturn, PromptGroupOptions, SELECT_INSTRUCTIONS, S_BAR, S_BAR_END, S_BAR_END_RIGHT, S_BAR_H, S_BAR_START, S_BAR_START_RIGHT, S_CHECKBOX_ACTIVE, S_CHECKBOX_INACTIVE, S_CHECKBOX_SELECTED, S_CONNECT_LEFT, S_CORNER_BOTTOM_LEFT, S_CORNER_BOTTOM_RIGHT, S_CORNER_TOP_LEFT, S_CORNER_TOP_RIGHT, S_ERROR, S_INFO, S_PASSWORD_MASK, S_RADIO_ACTIVE, S_RADIO_INACTIVE, S_STEP_ACTIVE, S_STEP_CANCEL, S_STEP_ERROR, S_STEP_SUBMIT, S_SUCCESS, S_WARN, SelectKeyOptions, SelectOptions, SpinnerOptions, SpinnerResult, Task, TaskLogCompletionOptions, TaskLogMessageOptions, TaskLogOptions, TextOptions, autocomplete, autocompleteMultiselect, box, cancel, confirm, date, formatInstructionFooter, group, groupMultiselect, intro, isCI$1 as isCI, isCancel, isTTY, limitOptions, log$1 as log, multiline, multiselect, note, outro, password, path, progress, select, selectKey, settings$1 as settings, spinner, stream, symbol, symbolBar, taskLog, tasks, text, unicode, unicodeOr, updateSettings };
1067
1368
  }
1068
1369
  declare const unicode: boolean;
1069
- declare const isCI: () => boolean;
1370
+ declare const isCI$1: () => boolean;
1070
1371
  declare const isTTY: (output: Writable) => boolean;
1071
1372
  declare const unicodeOr: (c: string, fallback: string) => string;
1072
1373
  declare const S_STEP_ACTIVE: string;
@@ -1975,6 +2276,11 @@ declare const taskLog: (opts: TaskLogOptions) => {
1975
2276
  };
1976
2277
  //#endregion
1977
2278
  //#region src/prompts.d.ts
2279
+ /**
2280
+ * `@clack/prompts` with CI-safe spinners, with every message a registered
2281
+ * credential value appears in masked (`registerSecretValue`), and with
2282
+ * prompts that refuse to ask without a terminal.
2283
+ */
1978
2284
  declare const p: typeof index_d_exports;
1979
2285
  type PromptProgress = ReturnType<typeof p.progress>;
1980
2286
  type PromptSpinner = ReturnType<typeof p.spinner>;
@@ -1986,6 +2292,23 @@ interface ReadPackageUpResult<T = unknown> {
1986
2292
  }
1987
2293
  declare const readPackageUp: <T = unknown>(cwd: string) => Promise<ReadPackageUpResult<T> | undefined>;
1988
2294
  //#endregion
2295
+ //#region src/reservedVariables.d.ts
2296
+ /**
2297
+ * Whether `name` is a variable no secret may set: one a loader or
2298
+ * interpreter reads (`NODE_*` but `NODE_ENV`, `PATH`, `LD_*`, `DYLD_*`,
2299
+ * `BASH_ENV`, `ENV`, `GIT_*`, `npm_config_*`, the JVM's, Gradle's, Ruby's,
2300
+ * Python's, and Perl's options), or one Hot Updater reads its credentials
2301
+ * from. `secretEnv` refuses these names, and so does every environment the
2302
+ * CLI gives a child process from resolved secrets.
2303
+ */
2304
+ declare const isReservedVariableName: (name: string) => boolean;
2305
+ /**
2306
+ * Throws when `env`, an environment the CLI gives a child process from
2307
+ * resolved secrets, sets a reserved variable, naming it and `what` sets it.
2308
+ * Returns `env`.
2309
+ */
2310
+ declare const assertUnreservedEnv: <T extends Readonly<Record<string, string>>>(env: T, what: string) => T;
2311
+ //#endregion
1989
2312
  //#region src/resolvePackageVersion.d.ts
1990
2313
  declare const HOT_UPDATER_SERVER_PACKAGE_VERSION_ENV = "HOT_UPDATER_SERVER_PACKAGE_VERSION";
1991
2314
  declare const resolvePackageVersion: (packageName: string, options?: {
@@ -1995,6 +2318,207 @@ declare const resolveHotUpdaterServerVersion: (currentPackageName: string, optio
1995
2318
  searchFrom?: string;
1996
2319
  }) => string;
1997
2320
  //#endregion
2321
+ //#region src/secretMasking.d.ts
2322
+ /**
2323
+ * Registers a credential value so every CLI log sink (`p`, `log`, and the
2324
+ * build log files) prints it masked, however short it is. A multi-line value
2325
+ * is also registered line by line, so a PEM printed one line at a time stays
2326
+ * masked.
2327
+ */
2328
+ declare const registerSecretValue: (value: string) => void;
2329
+ /** Replaces every registered credential value in `text` with a mask. */
2330
+ declare const maskSecretValues: (text: string) => string;
2331
+ //#endregion
2332
+ //#region src/localKeyStore.d.ts
2333
+ /**
2334
+ * Relocates Hot Updater's per-user directory, `~/.hot-updater` by default,
2335
+ * such as for CI caches or tests.
2336
+ */
2337
+ declare const HOT_UPDATER_HOME_ENV = "HOT_UPDATER_HOME";
2338
+ /** Hot Updater's per-user directory: `$HOT_UPDATER_HOME`, else `~/.hot-updater`. */
2339
+ declare const getHotUpdaterHome: () => string;
2340
+ /**
2341
+ * The project's directory name in the store: the project directory's name
2342
+ * and the first 12 hex digits of the SHA-256 of its real path, such as
2343
+ * `my-app-3f2a9c1d04be`. Each checkout of an app has its own.
2344
+ */
2345
+ declare const getProjectKey: (cwd: string) => string;
2346
+ /**
2347
+ * The directory `localSecrets()` keeps a project's secrets in without a
2348
+ * `path`: `<home>/secrets/<project-key>` (`getHotUpdaterHome`,
2349
+ * `getProjectKey`).
2350
+ */
2351
+ declare const getLocalKeyStoreDir: (cwd: string) => string;
2352
+ /**
2353
+ * `localSecrets({ path })`'s directory: `~` is the home directory, and a
2354
+ * relative path is the project's (`cwd`).
2355
+ */
2356
+ declare const resolveLocalSecretsPath: (value: string, cwd: string) => string;
2357
+ /** Where `localSecrets()` keeps a project's secrets, one file per name. */
2358
+ interface LocalSecretsStore {
2359
+ /** The project's directory. */
2360
+ readonly directory: (cwd: string) => string;
2361
+ /**
2362
+ * The file `name` is kept in, `<name>.json`. A secret's name has no path
2363
+ * separator and does not start with a dot.
2364
+ */
2365
+ readonly file: (name: string, cwd: string) => string;
2366
+ /** `name`'s value, or undefined. */
2367
+ readonly read: (name: string, cwd: string) => Promise<string | undefined>;
2368
+ /**
2369
+ * Stores `value` as `name`: the directory is 0700 and the file 0600,
2370
+ * readable by this user alone, and a write replaces the file whole or
2371
+ * not at all. Returns the file.
2372
+ */
2373
+ readonly write: (name: string, value: string, cwd: string) => Promise<string>;
2374
+ }
2375
+ /**
2376
+ * The store `localSecrets({ path })` reads and writes: `path`, or
2377
+ * `getLocalKeyStoreDir` without one. Its first use refuses a directory
2378
+ * secrets must not go in (`assertPrivateDirectory`).
2379
+ */
2380
+ declare const createLocalSecretsStore: ({ path: configured }?: {
2381
+ readonly path?: string;
2382
+ }) => LocalSecretsStore;
2383
+ /** The file `localSecrets()` without a `path` keeps `name` in. */
2384
+ declare const getLocalKeyFile: (name: string, cwd: string) => string;
2385
+ /** `name`'s value in `localSecrets()`'s default store, or undefined. */
2386
+ declare const readLocalKey: (name: string, cwd: string) => Promise<string | undefined>;
2387
+ /** Stores `value` as `name` in `localSecrets()`'s default store. */
2388
+ declare const writeLocalKey: (name: string, value: string, cwd: string) => Promise<string>;
2389
+ //#endregion
2390
+ //#region src/secrets.d.ts
2391
+ /** Whether `name` is a secret's name, as `secret:<name>` takes one. */
2392
+ declare const isSecretName: (name: string) => boolean;
2393
+ /**
2394
+ * The secret name a config's `secret:<name>` reference names, such as
2395
+ * `release-keystore` for `"secret:release-keystore"`. `field` is the config
2396
+ * field the reference is in, which the error names.
2397
+ */
2398
+ declare const parseSecretReference: (reference: string, field: string) => string;
2399
+ /**
2400
+ * The environment variable the default store reads a secret from: a name
2401
+ * that is a variable name already, such as `CLOUDFLARE_API_TOKEN`, as it
2402
+ * is, and any other, such as `asc-api-key`, upper-cased with `HOT_UPDATER_`
2403
+ * before it and every character but letters and digits as `_`
2404
+ * (`HOT_UPDATER_ASC_API_KEY`).
2405
+ */
2406
+ declare const secretVariableName: (name: string) => string;
2407
+ /** `name` from its variable in `process.env` or the project's `.env.hotupdater`. */
2408
+ declare const readSecretVariables: (names: readonly string[], cwd: string) => Promise<Record<string, string | undefined>>;
2409
+ /** `localSecrets()`'s name, the `secrets` adapter when the config sets none. */
2410
+ declare const LOCAL_SECRETS_NAME = "localSecrets";
2411
+ /**
2412
+ * Secrets in JSON files on this machine, the `secrets` adapter when the
2413
+ * config sets none: `get` reads each name from its environment variable
2414
+ * (`secretVariableName`, in `process.env` or `.env.hotupdater`), then from
2415
+ * `~/.hot-updater/secrets/<project-key>/<name>.json`; `set` writes that
2416
+ * file, 0600 in a 0700 directory, outside the project, so it survives
2417
+ * `node_modules` and is never committed. `HOT_UPDATER_HOME` moves
2418
+ * `~/.hot-updater`. The project key is the same for every clone of one app
2419
+ * on a machine (its `origin` remote and its directory in the repository),
2420
+ * so another machine signs in and issues a key of its own.
2421
+ *
2422
+ * @example
2423
+ * export default defineConfig({ secrets: localSecrets(), ... });
2424
+ */
2425
+ declare const localSecrets: (options?: LocalSecretsOptions) => SecretsAdapter;
2426
+ interface LocalSecretsOptions {
2427
+ /**
2428
+ * The directory that holds this project's secrets, one `<name>.json`
2429
+ * each, such as `~/.hot-updater/secrets/my-app`: `~` is the home
2430
+ * directory, and a relative path is the project's. A directory in a git
2431
+ * work tree must be one git ignores. Defaults to
2432
+ * `~/.hot-updater/secrets/<project-key>`, whose key is the same for every
2433
+ * clone of the app on a machine (`getProjectKey`).
2434
+ */
2435
+ readonly path?: string;
2436
+ }
2437
+ /**
2438
+ * The config's `secrets` adapter with `localSecrets()`'s store after it:
2439
+ * `get` reads each name the adapter does not hold from
2440
+ * `~/.hot-updater/secrets/<project-key>/<name>.json`, and `set` stores there
2441
+ * when the adapter stores nothing. Without an adapter, it is
2442
+ * `localSecrets()` itself. Keys Hot Updater issues, and credentials
2443
+ * `secrets put` imports, are reused by the next build on this machine with
2444
+ * no step in between.
2445
+ */
2446
+ declare const withLocalKeyStore: (configured?: SecretsAdapter) => SecretsAdapter;
2447
+ /**
2448
+ * The `localSecrets()` store `secrets` reads after its adapter, and stores
2449
+ * in when the adapter stores nothing: `localSecrets({ path })`'s, else the
2450
+ * default one.
2451
+ */
2452
+ declare const getLocalSecretsStore: (secrets: SecretsAdapter) => LocalSecretsStore;
2453
+ /**
2454
+ * The config's own `secrets` adapter, without `localSecrets()`'s store
2455
+ * after it: undefined for `localSecrets()`, and when the config sets none.
2456
+ * `secretEnv` reads deploy credentials from it.
2457
+ */
2458
+ declare const getConfiguredAdapter: (secrets: SecretsAdapter) => SecretsAdapter | undefined;
2459
+ /**
2460
+ * Where `secrets.set` stores `name`, for messages: the config's adapter
2461
+ * when it stores values, else `localSecrets()`'s file.
2462
+ */
2463
+ declare const describeStoredSecret: (secrets: SecretsAdapter, name: string) => string;
2464
+ /**
2465
+ * Whether a key `secrets` stores stays on this machine: it is `localSecrets()`,
2466
+ * whose files no other machine reads.
2467
+ */
2468
+ declare const keepsKeysOnThisMachine: (secrets: SecretsAdapter) => boolean;
2469
+ /**
2470
+ * The `secrets` adapter of one config load, filled once the config it
2471
+ * evaluates resolves: each `secretEnv` the evaluation creates reads from it.
2472
+ */
2473
+ interface SecretsScope {
2474
+ secrets?: SecretsAdapter;
2475
+ }
2476
+ /**
2477
+ * Evaluates a config, the file or a config function, with `scope` as the
2478
+ * scope of every `secretEnv` it creates, so each reads the `secrets` of the
2479
+ * config that created it, whatever config loads after. It is kept on
2480
+ * `globalThis`: the config file loads its own copy of Hot Updater's modules.
2481
+ */
2482
+ declare const withSecretsScope: <T>(scope: SecretsScope, evaluate: () => Promise<T> | T) => Promise<T>;
2483
+ /**
2484
+ * Makes `secrets` the adapter a credential resolver reads from by default,
2485
+ * and a `secretEnv` created outside any config load, as `loadConfig` does
2486
+ * with the config's. It is kept on `globalThis`: the config file loads Hot
2487
+ * Updater's modules again, as its own copies.
2488
+ */
2489
+ declare const setConfiguredSecrets: (secrets: SecretsAdapter) => void;
2490
+ /**
2491
+ * The config's `secrets` adapter with `localSecrets()`'s store after it
2492
+ * (`withLocalKeyStore`), `localSecrets()` until a config loads.
2493
+ */
2494
+ declare const getConfiguredSecrets: () => SecretsAdapter;
2495
+ /** Where an adapter keeps `name`, for messages. */
2496
+ declare const describeSecret: (secrets: SecretsAdapter, name: string) => string;
2497
+ /**
2498
+ * Environment variables from the `secrets` adapter of the config that
2499
+ * creates it, as a function a config calls when an adapter needs them, so loading
2500
+ * `hot-updater.config.ts` reads no secret. Each name set in the environment
2501
+ * or `.env.hotupdater` wins; the others are read from the config's
2502
+ * `secrets` adapter in one call, and without one they must be set. The values go only to the caller: they are never set in
2503
+ * `process.env`, and are masked in the CLI's logs. Names a loader or
2504
+ * interpreter reads, such as `NODE_OPTIONS`, are refused.
2505
+ *
2506
+ * @example
2507
+ * const deploy = secretEnv(["S3_ACCESS_KEY_ID", "S3_SECRET_ACCESS_KEY"]);
2508
+ * s3Storage({
2509
+ * bucketName: "bundles",
2510
+ * region: "us-east-1",
2511
+ * credentials: async () => {
2512
+ * const env = await deploy();
2513
+ * return {
2514
+ * accessKeyId: env.S3_ACCESS_KEY_ID,
2515
+ * secretAccessKey: env.S3_SECRET_ACCESS_KEY,
2516
+ * };
2517
+ * },
2518
+ * });
2519
+ */
2520
+ declare const secretEnv: <const TName extends string>(names: readonly TName[]) => (() => Promise<Readonly<Record<TName, string>>>);
2521
+ //#endregion
1998
2522
  //#region src/storageFiles.d.ts
1999
2523
  declare const getStorageFileByteSize: (filePath: string) => Promise<number>;
2000
2524
  declare const putStorageFile: (storage: StorageAdapterWith<"put">, key: string, filePath: string) => Promise<StoragePutResult & {
@@ -2018,4 +2542,4 @@ type TransformTemplateArgs<T extends string> = { [Key in ExtractPlaceholders<T>]
2018
2542
  */
2019
2543
  declare function transformTemplate<T extends string>(templateString: T, values: TransformTemplateArgs<T>): string;
2020
2544
  //#endregion
2021
- export { AppClientCredential, AppClientPlugin, AssembleServerOptions, AssembledServer, BuildLogger, BuildLoggerConfig, BuildType, BundleSigningSession, ClientAuthSpec, ClientCredentialSpec, ConfigBuilder, ConfigBuilderScaffold, ConfigResponse, CreateHotUpdaterConfigScaffoldFromBuilderOptions, CreateHotUpdaterConfigScaffoldOptions, HOT_UPDATER_SERVER_PACKAGE_VERSION_ENV, HotUpdateDirUtil, HotUpdaterConfigOptions, HotUpdaterConfigScaffold, HotUpdaterInitEnv, HotUpdaterLogWriter, INTERFACE_FINGERPRINT_ENGINE, ImportInfo, InitEnvFileError, InitError, InitProviderDefinition, InitProviderInputDefinition, InitProviderInputPersistence, LegacyInfrastructureError, ManagedHelperStatement, ManagedHelperStrategy, MissingInitInputsError, NativeDependency, NativeInterface, PromptProgress, PromptSpinner, ProviderConfig, ProvisionedClientCredential, ReactNativeMetadata, ReadPackageUpResult, RunInitOptions, ServerClientEndpoint, ServerDefinition, ServerDefinitionError, WriteHotUpdaterConfigResult, assembleServer, assertInfrastructureGenerationAtUrl, assertInfrastructureGenerationPayload, assertInitInputs, assertInitProviderInputs, banner, clientAuthOf, typedColors as colors, confirmInitInputPersistence, copyDirToTmp, createHotUpdaterConfigScaffold, createHotUpdaterConfigScaffoldFromBuilder, createInterfaceFingerprint, createLogWriter, createMigrator, createTarBrTargetFiles, createZip, decryptJson, defineInitProvider, encryptJson, ensureInstallPackages, generateClientCredential, generateSchema, generatesSchema, getAndroidSdkPath, getBundleSigningPublicKey, getCwd, getHotUpdaterEnvValue, getHotUpdaterInitInputEnv, getInitProviderEnvVars, getInitProviderTextPromptValues, getMissingInitInputs, getMissingInitProviderInputs, getPackageManager, getReactNativeMetadatas, getStorageFileByteSize, isCodegenSpecFile, isServerDefinition, link, loadConfig, loadPlatformConfigs, log, makeEnv, moduleSpecifiersOf, p, prepareBundleSigning, printAppSetup, printBanner, provisionClientCredential, putStorageFile, reactNativeCliFingerprint, readBundleSigningPublicKeyFile, readHotUpdaterEnv, readHotUpdaterInitEnv, readPackageUp, readReactNativeInterface, renderAppImports, renderAppSetup, renderImportStatements, resolveExpoAutolinking, resolveHotUpdaterServerVersion, resolveInitProviderInput, resolveInitProviderInputs, resolvePackageVersion, serverDefinitionOf, shouldAutoSelectOnlyInitResource, stripAnsi, transformEnv, transformTemplate, writeHotUpdaterConfig, writeHotUpdaterFiles };
2545
+ export { AppClientCredential, AppClientPlugin, AssembleServerOptions, AssembledServer, BuildFailedError, BuildFailureSummaryConfig, BuildLogger, BuildLoggerConfig, BuildType, BundleSigningSession, CREDENTIAL_ENV_NAMES, CREDENTIAL_LOGIN_GROUPS, ClientAuthSpec, ClientCredentialSpec, ConfigBuilder, ConfigBuilderScaffold, ConfigResponse, CreateCredentialResolverOptions, CreateHotUpdaterConfigScaffoldFromBuilderOptions, CreateHotUpdaterConfigScaffoldOptions, type CredentialFiles, CredentialKind, CredentialRequest, CredentialResolver, CredentialUnavailableError, Credentials, DEFAULT_SIGNING_KEY_SECRET, HOT_UPDATER_HOME_ENV, HOT_UPDATER_SERVER_PACKAGE_VERSION_ENV, HotUpdateDirUtil, HotUpdaterConfigOptions, HotUpdaterConfigScaffold, HotUpdaterInitEnv, HotUpdaterLogWriter, INTERFACE_FINGERPRINT_ENGINE, ImportInfo, InitEnvFileError, InitError, InitProviderDefinition, InitProviderInputDefinition, InitProviderInputPersistence, IssuedCredentialKind, LOCAL_SECRETS_NAME, LegacyInfrastructureError, LocalSecretsOptions, LocalSecretsStore, ManagedHelperStatement, ManagedHelperStrategy, MissingInitInputsError, NativeDependency, NativeInterface, PromptProgress, PromptSpinner, ProviderConfig, ProvisionedClientCredential, ReactNativeMetadata, ReadPackageUpResult, RunInitOptions, SecretsScope, ServerClientEndpoint, ServerDefinition, ServerDefinitionError, WriteHotUpdaterConfigResult, assembleServer, assertInfrastructureGenerationAtUrl, assertInfrastructureGenerationPayload, assertInitInputs, assertInitProviderInputs, assertUnreservedEnv, autolinkingConfigCommand, banner, clientAuthOf, typedColors as colors, confirmInitInputPersistence, copyDirToTmp, createCredentialResolver, createHotUpdaterConfigScaffold, createHotUpdaterConfigScaffoldFromBuilder, createInterfaceFingerprint, createLocalSecretsStore, createLogWriter, createMigrator, createMinBundleId, createTarBrTargetFiles, createZip, credentialIssueCommand, credentialLoginCommand, credentialOverrideHint, credentialPutCommand, credentialStoreCommand, decryptJson, defineInitProvider, describeSecret, describeStoredSecret, encryptJson, ensureInstallPackages, generateClientCredential, generateSchema, generatesSchema, getAndroidSdkPath, getBundleSigningPublicKey, getConfiguredAdapter, getConfiguredSecrets, getCwd, getHotUpdaterEnvValue, getHotUpdaterHome, getHotUpdaterInitInputEnv, getInitProviderEnvVars, getInitProviderTextPromptValues, getLocalKeyFile, getLocalKeyStoreDir, getLocalSecretsStore, getMissingInitInputs, getMissingInitProviderInputs, getPackageManager, getProjectKey, getReactNativeMetadatas, getStorageFileByteSize, isCI, isCodegenSpecFile, isReservedVariableName, isSecretName, isServerDefinition, keepsKeysOnThisMachine, link, loadConfig, loadPlatformConfigs, localSecrets, log, makeEnv, maskSecretValues, moduleSpecifiersOf, nonInteractiveReason, p, parseLoadedEnv, parseSecretReference, prepareBundleSigning, printAppSetup, printBanner, provisionClientCredential, putStorageFile, reactNativeCliFingerprint, reactNativeConfigCommand, readBundleSigningPublicKeyFile, readHotUpdaterInitEnv, readLoadedHotUpdaterEnv, readLocalKey, readPackageUp, readReactNativeInterface, readSecretVariables, registerCredentialValue, registerSecretValue, renderAppImports, renderAppSetup, renderImportStatements, resolveExpoAutolinking, resolveHotUpdaterServerVersion, resolveInitProviderInput, resolveInitProviderInputs, resolveLocalSecretsPath, resolvePackageVersion, secretEnv, secretVariableName, serverDefinitionOf, setConfiguredSecrets, shouldAutoSelectOnlyInitResource, stripAnsi, transformEnv, transformTemplate, withCredentialResolver, withLocalKeyStore, withSecretsScope, writeHotUpdaterConfig, writeHotUpdaterFiles, writeLocalKey };