@hominis/fireforge 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/LICENSE.md +294 -0
- package/README.md +435 -0
- package/dist/bin/fireforge.d.ts +10 -0
- package/dist/bin/fireforge.js +29 -0
- package/dist/src/cli.d.ts +33 -0
- package/dist/src/cli.js +180 -0
- package/dist/src/commands/bootstrap.d.ts +9 -0
- package/dist/src/commands/bootstrap.js +73 -0
- package/dist/src/commands/build.d.ts +11 -0
- package/dist/src/commands/build.js +102 -0
- package/dist/src/commands/config.d.ts +13 -0
- package/dist/src/commands/config.js +135 -0
- package/dist/src/commands/discard.d.ts +12 -0
- package/dist/src/commands/discard.js +84 -0
- package/dist/src/commands/doctor.d.ts +18 -0
- package/dist/src/commands/doctor.js +356 -0
- package/dist/src/commands/download.d.ts +11 -0
- package/dist/src/commands/download.js +127 -0
- package/dist/src/commands/export-all.d.ts +11 -0
- package/dist/src/commands/export-all.js +122 -0
- package/dist/src/commands/export-shared.d.ts +48 -0
- package/dist/src/commands/export-shared.js +208 -0
- package/dist/src/commands/export.d.ts +13 -0
- package/dist/src/commands/export.js +178 -0
- package/dist/src/commands/furnace/apply.d.ts +7 -0
- package/dist/src/commands/furnace/apply.js +80 -0
- package/dist/src/commands/furnace/create.d.ts +8 -0
- package/dist/src/commands/furnace/create.js +377 -0
- package/dist/src/commands/furnace/deploy.d.ts +8 -0
- package/dist/src/commands/furnace/deploy.js +338 -0
- package/dist/src/commands/furnace/diff.d.ts +7 -0
- package/dist/src/commands/furnace/diff.js +119 -0
- package/dist/src/commands/furnace/index.d.ts +16 -0
- package/dist/src/commands/furnace/index.js +121 -0
- package/dist/src/commands/furnace/list.d.ts +5 -0
- package/dist/src/commands/furnace/list.js +65 -0
- package/dist/src/commands/furnace/override.d.ts +8 -0
- package/dist/src/commands/furnace/override.js +188 -0
- package/dist/src/commands/furnace/preview.d.ts +7 -0
- package/dist/src/commands/furnace/preview.js +96 -0
- package/dist/src/commands/furnace/remove.d.ts +8 -0
- package/dist/src/commands/furnace/remove.js +159 -0
- package/dist/src/commands/furnace/scan.d.ts +5 -0
- package/dist/src/commands/furnace/scan.js +112 -0
- package/dist/src/commands/furnace/status.d.ts +7 -0
- package/dist/src/commands/furnace/status.js +137 -0
- package/dist/src/commands/furnace/validate.d.ts +6 -0
- package/dist/src/commands/furnace/validate.js +91 -0
- package/dist/src/commands/furnace/validation-output.d.ts +7 -0
- package/dist/src/commands/furnace/validation-output.js +22 -0
- package/dist/src/commands/import.d.ts +11 -0
- package/dist/src/commands/import.js +241 -0
- package/dist/src/commands/lint.d.ts +10 -0
- package/dist/src/commands/lint.js +118 -0
- package/dist/src/commands/package.d.ts +11 -0
- package/dist/src/commands/package.js +80 -0
- package/dist/src/commands/re-export.d.ts +12 -0
- package/dist/src/commands/re-export.js +242 -0
- package/dist/src/commands/rebase/abort.d.ts +7 -0
- package/dist/src/commands/rebase/abort.js +49 -0
- package/dist/src/commands/rebase/confirm.d.ts +18 -0
- package/dist/src/commands/rebase/confirm.js +33 -0
- package/dist/src/commands/rebase/continue.d.ts +7 -0
- package/dist/src/commands/rebase/continue.js +81 -0
- package/dist/src/commands/rebase/index.d.ts +22 -0
- package/dist/src/commands/rebase/index.js +127 -0
- package/dist/src/commands/rebase/patch-loop.d.ts +9 -0
- package/dist/src/commands/rebase/patch-loop.js +135 -0
- package/dist/src/commands/rebase/summary.d.ts +12 -0
- package/dist/src/commands/rebase/summary.js +43 -0
- package/dist/src/commands/rebase.d.ts +4 -0
- package/dist/src/commands/rebase.js +6 -0
- package/dist/src/commands/register.d.ts +13 -0
- package/dist/src/commands/register.js +67 -0
- package/dist/src/commands/reset.d.ts +11 -0
- package/dist/src/commands/reset.js +83 -0
- package/dist/src/commands/resolve.d.ts +9 -0
- package/dist/src/commands/resolve.js +124 -0
- package/dist/src/commands/run.d.ts +9 -0
- package/dist/src/commands/run.js +91 -0
- package/dist/src/commands/setup-support.d.ts +23 -0
- package/dist/src/commands/setup-support.js +310 -0
- package/dist/src/commands/setup.d.ts +11 -0
- package/dist/src/commands/setup.js +94 -0
- package/dist/src/commands/status.d.ts +11 -0
- package/dist/src/commands/status.js +268 -0
- package/dist/src/commands/test.d.ts +12 -0
- package/dist/src/commands/test.js +182 -0
- package/dist/src/commands/token-coverage.d.ts +5 -0
- package/dist/src/commands/token-coverage.js +57 -0
- package/dist/src/commands/token.d.ts +14 -0
- package/dist/src/commands/token.js +121 -0
- package/dist/src/commands/watch.d.ts +9 -0
- package/dist/src/commands/watch.js +112 -0
- package/dist/src/commands/wire.d.ts +13 -0
- package/dist/src/commands/wire.js +149 -0
- package/dist/src/core/ast-utils.d.ts +47 -0
- package/dist/src/core/ast-utils.js +57 -0
- package/dist/src/core/brand-validation.d.ts +7 -0
- package/dist/src/core/brand-validation.js +15 -0
- package/dist/src/core/branding.d.ts +49 -0
- package/dist/src/core/branding.js +229 -0
- package/dist/src/core/browser-wire.d.ts +40 -0
- package/dist/src/core/browser-wire.js +66 -0
- package/dist/src/core/build-prepare.d.ts +25 -0
- package/dist/src/core/build-prepare.js +93 -0
- package/dist/src/core/config-mutate.d.ts +15 -0
- package/dist/src/core/config-mutate.js +51 -0
- package/dist/src/core/config-paths.d.ts +28 -0
- package/dist/src/core/config-paths.js +65 -0
- package/dist/src/core/config-state.d.ts +28 -0
- package/dist/src/core/config-state.js +152 -0
- package/dist/src/core/config-validate.d.ts +11 -0
- package/dist/src/core/config-validate.js +141 -0
- package/dist/src/core/config.d.ts +39 -0
- package/dist/src/core/config.js +70 -0
- package/dist/src/core/file-lock.d.ts +11 -0
- package/dist/src/core/file-lock.js +80 -0
- package/dist/src/core/firefox-archive.d.ts +40 -0
- package/dist/src/core/firefox-archive.js +63 -0
- package/dist/src/core/firefox-cache.d.ts +23 -0
- package/dist/src/core/firefox-cache.js +134 -0
- package/dist/src/core/firefox-download.d.ts +21 -0
- package/dist/src/core/firefox-download.js +129 -0
- package/dist/src/core/firefox-extract.d.ts +21 -0
- package/dist/src/core/firefox-extract.js +53 -0
- package/dist/src/core/firefox.d.ts +34 -0
- package/dist/src/core/firefox.js +78 -0
- package/dist/src/core/furnace-apply-helpers.d.ts +21 -0
- package/dist/src/core/furnace-apply-helpers.js +244 -0
- package/dist/src/core/furnace-apply.d.ts +16 -0
- package/dist/src/core/furnace-apply.js +147 -0
- package/dist/src/core/furnace-config.d.ts +94 -0
- package/dist/src/core/furnace-config.js +372 -0
- package/dist/src/core/furnace-constants.d.ts +4 -0
- package/dist/src/core/furnace-constants.js +6 -0
- package/dist/src/core/furnace-registration-ast.d.ts +24 -0
- package/dist/src/core/furnace-registration-ast.js +218 -0
- package/dist/src/core/furnace-registration-remove.d.ts +14 -0
- package/dist/src/core/furnace-registration-remove.js +89 -0
- package/dist/src/core/furnace-registration-validate.d.ts +20 -0
- package/dist/src/core/furnace-registration-validate.js +40 -0
- package/dist/src/core/furnace-registration.d.ts +29 -0
- package/dist/src/core/furnace-registration.js +96 -0
- package/dist/src/core/furnace-rollback.d.ts +20 -0
- package/dist/src/core/furnace-rollback.js +66 -0
- package/dist/src/core/furnace-scanner.d.ts +40 -0
- package/dist/src/core/furnace-scanner.js +143 -0
- package/dist/src/core/furnace-stories.d.ts +37 -0
- package/dist/src/core/furnace-stories.js +185 -0
- package/dist/src/core/furnace-validate-accessibility.d.ts +6 -0
- package/dist/src/core/furnace-validate-accessibility.js +32 -0
- package/dist/src/core/furnace-validate-checks.d.ts +4 -0
- package/dist/src/core/furnace-validate-checks.js +7 -0
- package/dist/src/core/furnace-validate-compatibility.d.ts +6 -0
- package/dist/src/core/furnace-validate-compatibility.js +57 -0
- package/dist/src/core/furnace-validate-helpers.d.ts +28 -0
- package/dist/src/core/furnace-validate-helpers.js +129 -0
- package/dist/src/core/furnace-validate-registration.d.ts +37 -0
- package/dist/src/core/furnace-validate-registration.js +220 -0
- package/dist/src/core/furnace-validate-structure.d.ts +6 -0
- package/dist/src/core/furnace-validate-structure.js +66 -0
- package/dist/src/core/furnace-validate.d.ts +16 -0
- package/dist/src/core/furnace-validate.js +103 -0
- package/dist/src/core/git-base.d.ts +47 -0
- package/dist/src/core/git-base.js +50 -0
- package/dist/src/core/git-diff.d.ts +63 -0
- package/dist/src/core/git-diff.js +246 -0
- package/dist/src/core/git-file-ops.d.ts +65 -0
- package/dist/src/core/git-file-ops.js +141 -0
- package/dist/src/core/git-status.d.ts +65 -0
- package/dist/src/core/git-status.js +163 -0
- package/dist/src/core/git.d.ts +113 -0
- package/dist/src/core/git.js +363 -0
- package/dist/src/core/license-headers.d.ts +36 -0
- package/dist/src/core/license-headers.js +83 -0
- package/dist/src/core/mach-build-artifacts.d.ts +29 -0
- package/dist/src/core/mach-build-artifacts.js +117 -0
- package/dist/src/core/mach-mozconfig.d.ts +17 -0
- package/dist/src/core/mach-mozconfig.js +50 -0
- package/dist/src/core/mach-python.d.ts +16 -0
- package/dist/src/core/mach-python.js +126 -0
- package/dist/src/core/mach.d.ts +106 -0
- package/dist/src/core/mach.js +166 -0
- package/dist/src/core/manifest-helpers.d.ts +25 -0
- package/dist/src/core/manifest-helpers.js +96 -0
- package/dist/src/core/manifest-register.d.ts +30 -0
- package/dist/src/core/manifest-register.js +65 -0
- package/dist/src/core/manifest-rules.d.ts +39 -0
- package/dist/src/core/manifest-rules.js +151 -0
- package/dist/src/core/manifest-tokenizers.d.ts +34 -0
- package/dist/src/core/manifest-tokenizers.js +84 -0
- package/dist/src/core/parser-fallback.d.ts +36 -0
- package/dist/src/core/parser-fallback.js +43 -0
- package/dist/src/core/patch-apply-fuzz.d.ts +29 -0
- package/dist/src/core/patch-apply-fuzz.js +70 -0
- package/dist/src/core/patch-apply.d.ts +46 -0
- package/dist/src/core/patch-apply.js +235 -0
- package/dist/src/core/patch-export.d.ts +99 -0
- package/dist/src/core/patch-export.js +314 -0
- package/dist/src/core/patch-files.d.ts +11 -0
- package/dist/src/core/patch-files.js +51 -0
- package/dist/src/core/patch-lint.d.ts +72 -0
- package/dist/src/core/patch-lint.js +403 -0
- package/dist/src/core/patch-lock.d.ts +8 -0
- package/dist/src/core/patch-lock.js +29 -0
- package/dist/src/core/patch-manifest-consistency.d.ts +24 -0
- package/dist/src/core/patch-manifest-consistency.js +135 -0
- package/dist/src/core/patch-manifest-io.d.ts +36 -0
- package/dist/src/core/patch-manifest-io.js +77 -0
- package/dist/src/core/patch-manifest-query.d.ts +48 -0
- package/dist/src/core/patch-manifest-query.js +124 -0
- package/dist/src/core/patch-manifest-validate.d.ts +22 -0
- package/dist/src/core/patch-manifest-validate.js +72 -0
- package/dist/src/core/patch-manifest.d.ts +11 -0
- package/dist/src/core/patch-manifest.js +12 -0
- package/dist/src/core/patch-parse.d.ts +43 -0
- package/dist/src/core/patch-parse.js +143 -0
- package/dist/src/core/patch-transform.d.ts +21 -0
- package/dist/src/core/patch-transform.js +138 -0
- package/dist/src/core/rebase-session.d.ts +47 -0
- package/dist/src/core/rebase-session.js +65 -0
- package/dist/src/core/register-browser-content.d.ts +11 -0
- package/dist/src/core/register-browser-content.js +116 -0
- package/dist/src/core/register-module.d.ts +11 -0
- package/dist/src/core/register-module.js +76 -0
- package/dist/src/core/register-shared-css.d.ts +11 -0
- package/dist/src/core/register-shared-css.js +117 -0
- package/dist/src/core/register-test-manifest.d.ts +18 -0
- package/dist/src/core/register-test-manifest.js +99 -0
- package/dist/src/core/state-file.d.ts +4 -0
- package/dist/src/core/state-file.js +25 -0
- package/dist/src/core/token-coverage.d.ts +12 -0
- package/dist/src/core/token-coverage.js +74 -0
- package/dist/src/core/token-manager.d.ts +55 -0
- package/dist/src/core/token-manager.js +387 -0
- package/dist/src/core/wire-destroy.d.ts +21 -0
- package/dist/src/core/wire-destroy.js +103 -0
- package/dist/src/core/wire-dom-fragment.d.ts +23 -0
- package/dist/src/core/wire-dom-fragment.js +129 -0
- package/dist/src/core/wire-init.d.ts +23 -0
- package/dist/src/core/wire-init.js +201 -0
- package/dist/src/core/wire-subscript.d.ts +20 -0
- package/dist/src/core/wire-subscript.js +134 -0
- package/dist/src/core/wire-targets.d.ts +7 -0
- package/dist/src/core/wire-targets.js +9 -0
- package/dist/src/core/wire-utils.d.ts +88 -0
- package/dist/src/core/wire-utils.js +279 -0
- package/dist/src/errors/base.d.ts +60 -0
- package/dist/src/errors/base.js +87 -0
- package/dist/src/errors/build.d.ts +52 -0
- package/dist/src/errors/build.js +114 -0
- package/dist/src/errors/codes.d.ts +29 -0
- package/dist/src/errors/codes.js +30 -0
- package/dist/src/errors/config.d.ts +31 -0
- package/dist/src/errors/config.js +61 -0
- package/dist/src/errors/download.d.ts +42 -0
- package/dist/src/errors/download.js +95 -0
- package/dist/src/errors/furnace.d.ts +10 -0
- package/dist/src/errors/furnace.js +22 -0
- package/dist/src/errors/git.d.ts +41 -0
- package/dist/src/errors/git.js +99 -0
- package/dist/src/errors/patch.d.ts +10 -0
- package/dist/src/errors/patch.js +26 -0
- package/dist/src/errors/rebase.d.ts +20 -0
- package/dist/src/errors/rebase.js +30 -0
- package/dist/src/index.d.ts +21 -0
- package/dist/src/index.js +21 -0
- package/dist/src/types/cli.d.ts +14 -0
- package/dist/src/types/cli.js +2 -0
- package/dist/src/types/commands/index.d.ts +6 -0
- package/dist/src/types/commands/index.js +6 -0
- package/dist/src/types/commands/options.d.ts +239 -0
- package/dist/src/types/commands/options.js +6 -0
- package/dist/src/types/commands/patches.d.ts +89 -0
- package/dist/src/types/commands/patches.js +6 -0
- package/dist/src/types/commands/project.d.ts +71 -0
- package/dist/src/types/commands/project.js +6 -0
- package/dist/src/types/config.d.ts +101 -0
- package/dist/src/types/config.js +2 -0
- package/dist/src/types/furnace.d.ts +158 -0
- package/dist/src/types/furnace.js +2 -0
- package/dist/src/types/index.d.ts +6 -0
- package/dist/src/types/index.js +6 -0
- package/dist/src/utils/errors.d.ts +2 -0
- package/dist/src/utils/errors.js +15 -0
- package/dist/src/utils/fs.d.ts +72 -0
- package/dist/src/utils/fs.js +179 -0
- package/dist/src/utils/logger.d.ts +58 -0
- package/dist/src/utils/logger.js +120 -0
- package/dist/src/utils/options.d.ts +8 -0
- package/dist/src/utils/options.js +16 -0
- package/dist/src/utils/package-root.d.ts +10 -0
- package/dist/src/utils/package-root.js +53 -0
- package/dist/src/utils/parse.d.ts +110 -0
- package/dist/src/utils/parse.js +200 -0
- package/dist/src/utils/paths.d.ts +10 -0
- package/dist/src/utils/paths.js +43 -0
- package/dist/src/utils/platform.d.ts +38 -0
- package/dist/src/utils/platform.js +56 -0
- package/dist/src/utils/process.d.ts +80 -0
- package/dist/src/utils/process.js +188 -0
- package/dist/src/utils/regex.d.ts +24 -0
- package/dist/src/utils/regex.js +40 -0
- package/dist/src/utils/validation.d.ts +133 -0
- package/dist/src/utils/validation.js +250 -0
- package/package.json +106 -0
- package/templates/configs/common.mozconfig +24 -0
- package/templates/configs/darwin.mozconfig +10 -0
- package/templates/configs/linux.mozconfig +12 -0
- package/templates/configs/win32.mozconfig +14 -0
- package/templates/licenses/0BSD.md +14 -0
- package/templates/licenses/EUPL-1.2.md +294 -0
- package/templates/licenses/GPL-2.0-or-later.md +339 -0
- package/templates/licenses/MPL-2.0.md +383 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// SPDX-License-Identifier: EUPL-1.2
|
|
2
|
+
/** Normalizes unknown throwables into an Error instance. */
|
|
3
|
+
export function toError(error) {
|
|
4
|
+
if (error instanceof Error) {
|
|
5
|
+
return error;
|
|
6
|
+
}
|
|
7
|
+
if (typeof error === 'object' &&
|
|
8
|
+
error !== null &&
|
|
9
|
+
'message' in error &&
|
|
10
|
+
typeof error.message === 'string') {
|
|
11
|
+
return new Error(error.message, { cause: error });
|
|
12
|
+
}
|
|
13
|
+
return new Error(typeof error === 'string' ? error : String(error), { cause: error });
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checks if a path exists.
|
|
3
|
+
* @param path - Path to check
|
|
4
|
+
*/
|
|
5
|
+
export declare function pathExists(path: string): Promise<boolean>;
|
|
6
|
+
/**
|
|
7
|
+
* Ensures a directory exists, creating it recursively if needed.
|
|
8
|
+
* @param path - Directory path to ensure
|
|
9
|
+
*/
|
|
10
|
+
export declare function ensureDir(path: string): Promise<void>;
|
|
11
|
+
/**
|
|
12
|
+
* Ensures the parent directory of a file exists.
|
|
13
|
+
* @param filePath - Path to a file
|
|
14
|
+
*/
|
|
15
|
+
export declare function ensureParentDir(filePath: string): Promise<void>;
|
|
16
|
+
/**
|
|
17
|
+
* Removes a directory recursively.
|
|
18
|
+
* @param path - Directory path to remove
|
|
19
|
+
*/
|
|
20
|
+
export declare function removeDir(path: string): Promise<void>;
|
|
21
|
+
/**
|
|
22
|
+
* Removes a file.
|
|
23
|
+
* @param path - File path to remove
|
|
24
|
+
*/
|
|
25
|
+
export declare function removeFile(path: string): Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
* Copies a file from source to destination.
|
|
28
|
+
* Creates parent directories if needed.
|
|
29
|
+
* @param src - Source file path
|
|
30
|
+
* @param dest - Destination file path
|
|
31
|
+
*/
|
|
32
|
+
export declare function copyFile(src: string, dest: string): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Reads a JSON file and parses it.
|
|
35
|
+
* @param path - Path to JSON file
|
|
36
|
+
* @returns Parsed JSON content
|
|
37
|
+
* @throws Error if file doesn't exist or contains invalid JSON
|
|
38
|
+
*/
|
|
39
|
+
export declare function readJson<T>(path: string): Promise<T>;
|
|
40
|
+
/**
|
|
41
|
+
* Writes data to a JSON file with pretty formatting.
|
|
42
|
+
* Creates parent directories if needed.
|
|
43
|
+
* @param path - Path to JSON file
|
|
44
|
+
* @param data - Data to write
|
|
45
|
+
*/
|
|
46
|
+
export declare function writeJson(path: string, data: unknown): Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* Reads a text file.
|
|
49
|
+
* @param path - Path to text file
|
|
50
|
+
* @returns File content as string
|
|
51
|
+
*/
|
|
52
|
+
export declare function readText(path: string): Promise<string>;
|
|
53
|
+
/**
|
|
54
|
+
* Writes text to a file.
|
|
55
|
+
* Creates parent directories if needed.
|
|
56
|
+
* @param path - Path to text file
|
|
57
|
+
* @param content - Content to write
|
|
58
|
+
*/
|
|
59
|
+
export declare function writeText(path: string, content: string): Promise<void>;
|
|
60
|
+
/**
|
|
61
|
+
* Writes content atomically using a temp-file-and-rename strategy.
|
|
62
|
+
* Temp files are created in the destination directory so rename stays atomic.
|
|
63
|
+
* @param path - Destination file path
|
|
64
|
+
* @param content - Content to write
|
|
65
|
+
*/
|
|
66
|
+
export declare function writeFileAtomic(path: string, content: string | Buffer): Promise<void>;
|
|
67
|
+
/**
|
|
68
|
+
* Copies a directory recursively.
|
|
69
|
+
* @param src - Source directory path
|
|
70
|
+
* @param dest - Destination directory path
|
|
71
|
+
*/
|
|
72
|
+
export declare function copyDir(src: string, dest: string): Promise<void>;
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
// SPDX-License-Identifier: EUPL-1.2
|
|
2
|
+
import { randomUUID } from 'node:crypto';
|
|
3
|
+
import { access, copyFile as fsCopyFile, mkdir, open, readdir, readFile, rename, rm, } from 'node:fs/promises';
|
|
4
|
+
import { dirname, join } from 'node:path';
|
|
5
|
+
const RETRIABLE_REMOVE_ERRORS = new Set(['ENOTEMPTY', 'EBUSY', 'EPERM']);
|
|
6
|
+
function sleep(ms) {
|
|
7
|
+
return new Promise((resolve) => {
|
|
8
|
+
setTimeout(resolve, ms);
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Checks if a path exists.
|
|
13
|
+
* @param path - Path to check
|
|
14
|
+
*/
|
|
15
|
+
export async function pathExists(path) {
|
|
16
|
+
try {
|
|
17
|
+
await access(path);
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
catch (error) {
|
|
21
|
+
void error;
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Ensures a directory exists, creating it recursively if needed.
|
|
27
|
+
* @param path - Directory path to ensure
|
|
28
|
+
*/
|
|
29
|
+
export async function ensureDir(path) {
|
|
30
|
+
await mkdir(path, { recursive: true });
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Ensures the parent directory of a file exists.
|
|
34
|
+
* @param filePath - Path to a file
|
|
35
|
+
*/
|
|
36
|
+
export async function ensureParentDir(filePath) {
|
|
37
|
+
const parent = dirname(filePath);
|
|
38
|
+
await ensureDir(parent);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Removes a directory recursively.
|
|
42
|
+
* @param path - Directory path to remove
|
|
43
|
+
*/
|
|
44
|
+
export async function removeDir(path) {
|
|
45
|
+
for (let attempt = 0; attempt < 5; attempt++) {
|
|
46
|
+
try {
|
|
47
|
+
await rm(path, { recursive: true, force: true });
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
const code = error instanceof Error && 'code' in error && typeof error.code === 'string'
|
|
52
|
+
? error.code
|
|
53
|
+
: undefined;
|
|
54
|
+
if (!code || !RETRIABLE_REMOVE_ERRORS.has(code) || attempt === 4) {
|
|
55
|
+
throw error;
|
|
56
|
+
}
|
|
57
|
+
await sleep(50 * (attempt + 1));
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Removes a file.
|
|
63
|
+
* @param path - File path to remove
|
|
64
|
+
*/
|
|
65
|
+
export async function removeFile(path) {
|
|
66
|
+
await rm(path, { force: true });
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Copies a file from source to destination.
|
|
70
|
+
* Creates parent directories if needed.
|
|
71
|
+
* @param src - Source file path
|
|
72
|
+
* @param dest - Destination file path
|
|
73
|
+
*/
|
|
74
|
+
export async function copyFile(src, dest) {
|
|
75
|
+
await ensureParentDir(dest);
|
|
76
|
+
await fsCopyFile(src, dest);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Reads a JSON file and parses it.
|
|
80
|
+
* @param path - Path to JSON file
|
|
81
|
+
* @returns Parsed JSON content
|
|
82
|
+
* @throws Error if file doesn't exist or contains invalid JSON
|
|
83
|
+
*/
|
|
84
|
+
export async function readJson(path) {
|
|
85
|
+
const content = await readFile(path, 'utf-8');
|
|
86
|
+
return JSON.parse(content, (key, value) => key === '__proto__' || key === 'constructor' || key === 'prototype' ? undefined : value);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Writes data to a JSON file with pretty formatting.
|
|
90
|
+
* Creates parent directories if needed.
|
|
91
|
+
* @param path - Path to JSON file
|
|
92
|
+
* @param data - Data to write
|
|
93
|
+
*/
|
|
94
|
+
export async function writeJson(path, data) {
|
|
95
|
+
const content = JSON.stringify(data, null, 2) + '\n';
|
|
96
|
+
await writeText(path, content);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Reads a text file.
|
|
100
|
+
* @param path - Path to text file
|
|
101
|
+
* @returns File content as string
|
|
102
|
+
*/
|
|
103
|
+
export async function readText(path) {
|
|
104
|
+
return readFile(path, 'utf-8');
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Writes text to a file.
|
|
108
|
+
* Creates parent directories if needed.
|
|
109
|
+
* @param path - Path to text file
|
|
110
|
+
* @param content - Content to write
|
|
111
|
+
*/
|
|
112
|
+
export async function writeText(path, content) {
|
|
113
|
+
await writeFileAtomic(path, content);
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Writes content atomically using a temp-file-and-rename strategy.
|
|
117
|
+
* Temp files are created in the destination directory so rename stays atomic.
|
|
118
|
+
* @param path - Destination file path
|
|
119
|
+
* @param content - Content to write
|
|
120
|
+
*/
|
|
121
|
+
export async function writeFileAtomic(path, content) {
|
|
122
|
+
await ensureParentDir(path);
|
|
123
|
+
const tempPath = createAtomicTempPath(path);
|
|
124
|
+
const handle = await open(tempPath, 'w');
|
|
125
|
+
try {
|
|
126
|
+
await handle.writeFile(content);
|
|
127
|
+
await handle.sync();
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
await handle.close();
|
|
131
|
+
await rm(tempPath, { force: true });
|
|
132
|
+
throw error;
|
|
133
|
+
}
|
|
134
|
+
await handle.close();
|
|
135
|
+
try {
|
|
136
|
+
await rename(tempPath, path);
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
await rm(tempPath, { force: true });
|
|
140
|
+
throw error;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Copies a directory recursively.
|
|
145
|
+
* @param src - Source directory path
|
|
146
|
+
* @param dest - Destination directory path
|
|
147
|
+
*/
|
|
148
|
+
export async function copyDir(src, dest) {
|
|
149
|
+
await ensureDir(dest);
|
|
150
|
+
const entries = await readdir(src, { withFileTypes: true });
|
|
151
|
+
for (const entry of entries) {
|
|
152
|
+
const srcPath = join(src, entry.name);
|
|
153
|
+
const destPath = join(dest, entry.name);
|
|
154
|
+
if (entry.isSymbolicLink()) {
|
|
155
|
+
// Skip symlinks to avoid circular recursion and symlink attacks
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
if (entry.isDirectory()) {
|
|
159
|
+
await copyDir(srcPath, destPath);
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
await fsCopyFile(srcPath, destPath);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Generates a unique temp file path for atomic writes.
|
|
168
|
+
*
|
|
169
|
+
* Each invocation gets its own path via PID + UUID, so concurrent writers
|
|
170
|
+
* targeting the same destination never interfere with each other. Cleanup of
|
|
171
|
+
* the temp file is the caller's responsibility on error; we intentionally do
|
|
172
|
+
* NOT glob-delete peer temp files here to avoid racing with other writers.
|
|
173
|
+
*/
|
|
174
|
+
function createAtomicTempPath(path) {
|
|
175
|
+
const directory = dirname(path);
|
|
176
|
+
const filename = path.slice(directory.length + 1);
|
|
177
|
+
return join(directory, `.${filename}.fireforge-tmp-${process.pid}-${randomUUID()}`);
|
|
178
|
+
}
|
|
179
|
+
//# sourceMappingURL=fs.js.map
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enables or disables verbose mode.
|
|
3
|
+
* @param enabled - Whether to enable verbose output
|
|
4
|
+
*/
|
|
5
|
+
export declare function setVerbose(enabled: boolean): void;
|
|
6
|
+
/**
|
|
7
|
+
* Checks if verbose mode is enabled.
|
|
8
|
+
* @returns True if verbose mode is enabled
|
|
9
|
+
*/
|
|
10
|
+
export declare function isVerbose(): boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Displays a verbose/debug message (only shown if verbose mode is enabled).
|
|
13
|
+
* @param message - Message to display
|
|
14
|
+
*/
|
|
15
|
+
export declare function verbose(message: string): void;
|
|
16
|
+
/**
|
|
17
|
+
* Handle returned by the spinner function.
|
|
18
|
+
*/
|
|
19
|
+
export interface SpinnerHandle {
|
|
20
|
+
/** Update the spinner message */
|
|
21
|
+
message: (msg: string) => void;
|
|
22
|
+
/** Stop the spinner with a success message */
|
|
23
|
+
stop: (msg?: string) => void;
|
|
24
|
+
/** Stop the spinner with an error message */
|
|
25
|
+
error: (msg?: string) => void;
|
|
26
|
+
}
|
|
27
|
+
/** Displays the top-level intro banner for a command. */
|
|
28
|
+
export declare function intro(message: string): void;
|
|
29
|
+
/** Displays the closing outro banner for a command. */
|
|
30
|
+
export declare function outro(message: string): void;
|
|
31
|
+
/** Logs an informational message. */
|
|
32
|
+
export declare function info(message: string): void;
|
|
33
|
+
/** Logs a success message. */
|
|
34
|
+
export declare function success(message: string): void;
|
|
35
|
+
/** Logs a warning message. */
|
|
36
|
+
export declare function warn(message: string): void;
|
|
37
|
+
/** Logs an error message. */
|
|
38
|
+
export declare function error(message: string): void;
|
|
39
|
+
/** Logs an in-progress step message. */
|
|
40
|
+
export declare function step(message: string): void;
|
|
41
|
+
/** Logs a plain message without a status prefix. */
|
|
42
|
+
export declare function message(message: string): void;
|
|
43
|
+
/** Formats text using the success color without logging it. */
|
|
44
|
+
export declare function formatSuccessText(message: string): string;
|
|
45
|
+
/** Formats text using the error color without logging it. */
|
|
46
|
+
export declare function formatErrorText(message: string): string;
|
|
47
|
+
/**
|
|
48
|
+
* Creates a spinner for long-running operations.
|
|
49
|
+
* @param initialMessage - Initial message to display
|
|
50
|
+
* @returns Spinner handle with message(), stop(), and error() methods
|
|
51
|
+
*/
|
|
52
|
+
export declare function spinner(initialMessage: string): SpinnerHandle;
|
|
53
|
+
/** Emits a cancellation message. */
|
|
54
|
+
export declare function cancel(message: string): void;
|
|
55
|
+
/** Checks whether a prompt result represents a user cancellation. */
|
|
56
|
+
export declare function isCancel(value: unknown): boolean;
|
|
57
|
+
/** Displays a titled note block for follow-up details. */
|
|
58
|
+
export declare function note(message: string, title?: string): void;
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
// SPDX-License-Identifier: EUPL-1.2
|
|
2
|
+
import * as p from '@clack/prompts';
|
|
3
|
+
import pc from 'picocolors';
|
|
4
|
+
/** Whether verbose mode is enabled */
|
|
5
|
+
let verboseMode = false;
|
|
6
|
+
/**
|
|
7
|
+
* Enables or disables verbose mode.
|
|
8
|
+
* @param enabled - Whether to enable verbose output
|
|
9
|
+
*/
|
|
10
|
+
export function setVerbose(enabled) {
|
|
11
|
+
verboseMode = enabled;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Checks if verbose mode is enabled.
|
|
15
|
+
* @returns True if verbose mode is enabled
|
|
16
|
+
*/
|
|
17
|
+
export function isVerbose() {
|
|
18
|
+
return verboseMode;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Displays a verbose/debug message (only shown if verbose mode is enabled).
|
|
22
|
+
* @param message - Message to display
|
|
23
|
+
*/
|
|
24
|
+
export function verbose(message) {
|
|
25
|
+
if (verboseMode) {
|
|
26
|
+
p.log.info(`[debug] ${message}`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function supportsInteractiveSpinner() {
|
|
30
|
+
return process.stdout.isTTY && process.stderr.isTTY;
|
|
31
|
+
}
|
|
32
|
+
/** Displays the top-level intro banner for a command. */
|
|
33
|
+
export function intro(message) {
|
|
34
|
+
p.intro(message);
|
|
35
|
+
}
|
|
36
|
+
/** Displays the closing outro banner for a command. */
|
|
37
|
+
export function outro(message) {
|
|
38
|
+
p.outro(message);
|
|
39
|
+
}
|
|
40
|
+
/** Logs an informational message. */
|
|
41
|
+
export function info(message) {
|
|
42
|
+
p.log.info(message);
|
|
43
|
+
}
|
|
44
|
+
/** Logs a success message. */
|
|
45
|
+
export function success(message) {
|
|
46
|
+
p.log.success(message);
|
|
47
|
+
}
|
|
48
|
+
/** Logs a warning message. */
|
|
49
|
+
export function warn(message) {
|
|
50
|
+
p.log.warn(message);
|
|
51
|
+
}
|
|
52
|
+
/** Logs an error message. */
|
|
53
|
+
export function error(message) {
|
|
54
|
+
p.log.error(message);
|
|
55
|
+
}
|
|
56
|
+
/** Logs an in-progress step message. */
|
|
57
|
+
export function step(message) {
|
|
58
|
+
p.log.step(message);
|
|
59
|
+
}
|
|
60
|
+
/** Logs a plain message without a status prefix. */
|
|
61
|
+
export function message(message) {
|
|
62
|
+
p.log.message(message);
|
|
63
|
+
}
|
|
64
|
+
/** Formats text using the success color without logging it. */
|
|
65
|
+
export function formatSuccessText(message) {
|
|
66
|
+
return pc.green(message);
|
|
67
|
+
}
|
|
68
|
+
/** Formats text using the error color without logging it. */
|
|
69
|
+
export function formatErrorText(message) {
|
|
70
|
+
return pc.red(message);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Creates a spinner for long-running operations.
|
|
74
|
+
* @param initialMessage - Initial message to display
|
|
75
|
+
* @returns Spinner handle with message(), stop(), and error() methods
|
|
76
|
+
*/
|
|
77
|
+
export function spinner(initialMessage) {
|
|
78
|
+
if (!supportsInteractiveSpinner()) {
|
|
79
|
+
let latestMessage = initialMessage;
|
|
80
|
+
return {
|
|
81
|
+
message: (msg) => {
|
|
82
|
+
latestMessage = msg;
|
|
83
|
+
p.log.step(msg);
|
|
84
|
+
},
|
|
85
|
+
stop: (msg) => {
|
|
86
|
+
p.log.step(msg ?? latestMessage);
|
|
87
|
+
},
|
|
88
|
+
error: (msg) => {
|
|
89
|
+
p.log.error(msg ?? 'Failed');
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
const s = p.spinner();
|
|
94
|
+
s.start(initialMessage);
|
|
95
|
+
return {
|
|
96
|
+
message: (msg) => {
|
|
97
|
+
s.message(msg);
|
|
98
|
+
},
|
|
99
|
+
stop: (msg) => {
|
|
100
|
+
s.stop(msg ?? initialMessage);
|
|
101
|
+
},
|
|
102
|
+
error: (msg) => {
|
|
103
|
+
s.stop();
|
|
104
|
+
p.log.error(msg ?? 'Failed');
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
/** Emits a cancellation message. */
|
|
109
|
+
export function cancel(message) {
|
|
110
|
+
p.cancel(message);
|
|
111
|
+
}
|
|
112
|
+
/** Checks whether a prompt result represents a user cancellation. */
|
|
113
|
+
export function isCancel(value) {
|
|
114
|
+
return p.isCancel(value);
|
|
115
|
+
}
|
|
116
|
+
/** Displays a titled note block for follow-up details. */
|
|
117
|
+
export function note(message, title) {
|
|
118
|
+
p.note(message, title);
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Filters an object to only include keys whose values are not undefined.
|
|
3
|
+
* Designed for use with exactOptionalPropertyTypes — the result can be
|
|
4
|
+
* spread into typed option objects without assigning undefined to optional properties.
|
|
5
|
+
*/
|
|
6
|
+
export declare function pickDefined<T extends Record<string, unknown>>(obj: T): {
|
|
7
|
+
[K in keyof T]+?: Exclude<T[K], undefined>;
|
|
8
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// SPDX-License-Identifier: EUPL-1.2
|
|
2
|
+
/**
|
|
3
|
+
* Filters an object to only include keys whose values are not undefined.
|
|
4
|
+
* Designed for use with exactOptionalPropertyTypes — the result can be
|
|
5
|
+
* spread into typed option objects without assigning undefined to optional properties.
|
|
6
|
+
*/
|
|
7
|
+
export function pickDefined(obj) {
|
|
8
|
+
const result = {};
|
|
9
|
+
for (const key of Object.keys(obj)) {
|
|
10
|
+
if (obj[key] !== undefined) {
|
|
11
|
+
result[key] = obj[key];
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
return result;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=options.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Finds the fireforge package root by walking up from the current module.
|
|
3
|
+
*
|
|
4
|
+
* Works from both the source tree (`src/utils/`) and the compiled
|
|
5
|
+
* tree (`dist/src/utils/`) by looking for a `package.json` whose
|
|
6
|
+
* `name` field is `"@hominis/fireforge"`.
|
|
7
|
+
*/
|
|
8
|
+
export declare function getPackageRoot(): string;
|
|
9
|
+
/** Reads the current package version from the repository root package manifest. */
|
|
10
|
+
export declare function getPackageVersion(): string;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// SPDX-License-Identifier: EUPL-1.2
|
|
2
|
+
import { readFileSync } from 'node:fs';
|
|
3
|
+
import { dirname, join } from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
function validatePackageMetadata(data, filePath) {
|
|
6
|
+
if (typeof data !== 'object' || data === null) {
|
|
7
|
+
throw new Error(`Invalid package metadata in ${filePath}: expected an object`);
|
|
8
|
+
}
|
|
9
|
+
const name = 'name' in data ? data.name : undefined;
|
|
10
|
+
const version = 'version' in data ? data.version : undefined;
|
|
11
|
+
if (typeof name !== 'string' || typeof version !== 'string') {
|
|
12
|
+
throw new Error(`Invalid package metadata in ${filePath}: expected string "name" and "version" fields`);
|
|
13
|
+
}
|
|
14
|
+
return { name, version };
|
|
15
|
+
}
|
|
16
|
+
function readPackageMetadata(filePath) {
|
|
17
|
+
const raw = readFileSync(filePath, 'utf-8');
|
|
18
|
+
return validatePackageMetadata(JSON.parse(raw), filePath);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Finds the fireforge package root by walking up from the current module.
|
|
22
|
+
*
|
|
23
|
+
* Works from both the source tree (`src/utils/`) and the compiled
|
|
24
|
+
* tree (`dist/src/utils/`) by looking for a `package.json` whose
|
|
25
|
+
* `name` field is `"@hominis/fireforge"`.
|
|
26
|
+
*/
|
|
27
|
+
export function getPackageRoot() {
|
|
28
|
+
let current = dirname(fileURLToPath(import.meta.url));
|
|
29
|
+
for (;;) {
|
|
30
|
+
try {
|
|
31
|
+
const packagePath = join(current, 'package.json');
|
|
32
|
+
const pkg = readPackageMetadata(packagePath);
|
|
33
|
+
if (pkg.name === '@hominis/fireforge') {
|
|
34
|
+
return current;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
void error;
|
|
39
|
+
// no package.json here — keep walking
|
|
40
|
+
}
|
|
41
|
+
const parent = dirname(current);
|
|
42
|
+
if (parent === current) {
|
|
43
|
+
throw new Error('Could not locate the fireforge package root');
|
|
44
|
+
}
|
|
45
|
+
current = parent;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/** Reads the current package version from the repository root package manifest. */
|
|
49
|
+
export function getPackageVersion() {
|
|
50
|
+
const packageRoot = getPackageRoot();
|
|
51
|
+
return readPackageMetadata(join(packageRoot, 'package.json')).version;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=package-root.js.map
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight runtime object parsing and field extraction helpers.
|
|
3
|
+
*
|
|
4
|
+
* Reduces repetitive "validate unknown → cast" boilerplate across
|
|
5
|
+
* config validation, manifest parsing, and metadata validation.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* A parsed record wrapper that provides typed field extraction
|
|
9
|
+
* with clear error messages. Construct via {@link parseObject}.
|
|
10
|
+
*/
|
|
11
|
+
export declare class ParsedRecord {
|
|
12
|
+
#private;
|
|
13
|
+
constructor(data: Record<string, unknown>, label: string);
|
|
14
|
+
/**
|
|
15
|
+
* Extracts a required string field.
|
|
16
|
+
* @param key - Field name
|
|
17
|
+
* @returns The string value
|
|
18
|
+
* @throws Error if the field is missing or not a string
|
|
19
|
+
*/
|
|
20
|
+
string(key: string): string;
|
|
21
|
+
/**
|
|
22
|
+
* Extracts an optional string field.
|
|
23
|
+
* @param key - Field name
|
|
24
|
+
* @returns The string value or undefined
|
|
25
|
+
* @throws Error if the field is present but not a string
|
|
26
|
+
*/
|
|
27
|
+
optionalString(key: string): string | undefined;
|
|
28
|
+
/**
|
|
29
|
+
* Extracts a required number field.
|
|
30
|
+
* @param key - Field name
|
|
31
|
+
* @returns The number value
|
|
32
|
+
* @throws Error if the field is missing or not a number
|
|
33
|
+
*/
|
|
34
|
+
number(key: string): number;
|
|
35
|
+
/**
|
|
36
|
+
* Extracts an optional number field.
|
|
37
|
+
* @param key - Field name
|
|
38
|
+
* @returns The number value or undefined
|
|
39
|
+
* @throws Error if the field is present but not a number
|
|
40
|
+
*/
|
|
41
|
+
optionalNumber(key: string): number | undefined;
|
|
42
|
+
/**
|
|
43
|
+
* Extracts a required non-negative integer field.
|
|
44
|
+
* @param key - Field name
|
|
45
|
+
* @returns The integer value
|
|
46
|
+
* @throws Error if the field is missing, not a number, or negative
|
|
47
|
+
*/
|
|
48
|
+
nonNegativeInteger(key: string): number;
|
|
49
|
+
/**
|
|
50
|
+
* Extracts an optional non-negative integer field.
|
|
51
|
+
* @param key - Field name
|
|
52
|
+
* @returns The integer value or undefined
|
|
53
|
+
* @throws Error if the field is present but not a non-negative integer
|
|
54
|
+
*/
|
|
55
|
+
optionalNonNegativeInteger(key: string): number | undefined;
|
|
56
|
+
/**
|
|
57
|
+
* Extracts a required string field and validates it against a predicate.
|
|
58
|
+
* @param key - Field name
|
|
59
|
+
* @param predicate - Validation function
|
|
60
|
+
* @param allowed - Description of allowed values for the error message
|
|
61
|
+
* @returns The validated string value
|
|
62
|
+
*/
|
|
63
|
+
stringEnum<T extends string>(key: string, predicate: (value: string) => value is T, allowed: string): T;
|
|
64
|
+
/**
|
|
65
|
+
* Extracts a required string field and validates it with a custom check.
|
|
66
|
+
* @param key - Field name
|
|
67
|
+
* @param check - Validation function returning true if valid
|
|
68
|
+
* @param constraint - Description of the constraint for the error message
|
|
69
|
+
* @returns The validated string value
|
|
70
|
+
*/
|
|
71
|
+
validatedString(key: string, check: (value: string) => boolean, constraint: string): string;
|
|
72
|
+
/**
|
|
73
|
+
* Extracts a required array-of-strings field.
|
|
74
|
+
* @param key - Field name
|
|
75
|
+
* @returns The string array
|
|
76
|
+
* @throws Error if the field is missing or not an array of strings
|
|
77
|
+
*/
|
|
78
|
+
stringArray(key: string): string[];
|
|
79
|
+
/**
|
|
80
|
+
* Extracts a required nested object field.
|
|
81
|
+
* @param key - Field name
|
|
82
|
+
* @returns A new ParsedRecord wrapping the nested object
|
|
83
|
+
* @throws Error if the field is missing or not an object
|
|
84
|
+
*/
|
|
85
|
+
object(key: string): ParsedRecord;
|
|
86
|
+
/**
|
|
87
|
+
* Extracts an optional nested object field.
|
|
88
|
+
* @param key - Field name
|
|
89
|
+
* @returns A new ParsedRecord wrapping the nested object, or undefined
|
|
90
|
+
* @throws Error if the field is present but not an object
|
|
91
|
+
*/
|
|
92
|
+
optionalObject(key: string): ParsedRecord | undefined;
|
|
93
|
+
/**
|
|
94
|
+
* Returns the raw value of a field without validation.
|
|
95
|
+
* @param key - Field name
|
|
96
|
+
*/
|
|
97
|
+
raw(key: string): unknown;
|
|
98
|
+
/**
|
|
99
|
+
* Returns all keys in the underlying record.
|
|
100
|
+
*/
|
|
101
|
+
keys(): string[];
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Wraps an unknown value as a ParsedRecord after verifying it is an object.
|
|
105
|
+
* @param data - The unknown value to parse
|
|
106
|
+
* @param label - Label for error messages (e.g. "Config", "patches[0]")
|
|
107
|
+
* @returns A ParsedRecord for typed field extraction
|
|
108
|
+
* @throws Error if data is not a plain object
|
|
109
|
+
*/
|
|
110
|
+
export declare function parseObject(data: unknown, label: string): ParsedRecord;
|