@fjall/util 2.9.1 → 2.11.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.
- package/dist/.minified +1 -1
- package/dist/Config.d.ts +15 -0
- package/dist/Config.js +1 -1
- package/dist/manifest/schemas.d.ts +4 -0
- package/dist/manifest/schemas.js +1 -1
- package/dist/mcpProtocol/index.d.ts +2 -2
- package/dist/securityHelpers.js +1 -1
- package/package.json +2 -2
package/dist/.minified
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
59 files minified at 2026-06-
|
|
1
|
+
59 files minified at 2026-06-07T01:01:57.688Z
|
package/dist/Config.d.ts
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Backup Vault Lock modes for an account's DisasterRecovery vault.
|
|
4
|
+
* See decisions/2026-06-03-backup-vault-lock-mode-by-intent.md.
|
|
5
|
+
*/
|
|
6
|
+
export declare const VAULT_LOCK_MODES: readonly ["compliance", "governance", "none"];
|
|
7
|
+
export type VaultLockMode = (typeof VAULT_LOCK_MODES)[number];
|
|
2
8
|
export type ProviderAccount = {
|
|
3
9
|
id: string;
|
|
4
10
|
name: string;
|
|
@@ -11,6 +17,15 @@ export type ProviderAccount = {
|
|
|
11
17
|
* lookup (accountId+region), so it must be stamped before cascade deploy.
|
|
12
18
|
*/
|
|
13
19
|
region?: string;
|
|
20
|
+
/**
|
|
21
|
+
* Backup Vault Lock mode for this account's DisasterRecovery vault. Defaults
|
|
22
|
+
* to "governance" (lock-protected but removable by privileged IAM).
|
|
23
|
+
* "compliance" is permanently immutable after a 3-day cooling-off and
|
|
24
|
+
* requires acknowledgeImmutableVaultLock. "none" disables the lock.
|
|
25
|
+
*/
|
|
26
|
+
vaultLock?: VaultLockMode;
|
|
27
|
+
/** Explicit acknowledgement that vaultLock: "compliance" is irreversible. */
|
|
28
|
+
acknowledgeImmutableVaultLock?: boolean;
|
|
14
29
|
};
|
|
15
30
|
export type Profile = {
|
|
16
31
|
type: "sso" | "oidc";
|
package/dist/Config.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import*as r from"fs";import*as s from"path";import{z as e}from"zod";import{logger as g}from"./logger.js";const l=10,m=e.object({name:e.string(),type:e.enum(["apex","delegated"]),parentDomain:e.string().optional(),account:e.string().optional()}).strict(),d=e.object({activeTarget:e.string().optional(),domains:e.array(m).optional()}).strict();class a{rootConfig;configPath=null;constructor(o,t){this.rootConfig=o??{},this.configPath=t??null}static findConfigDirectory(){let o=process.cwd();for(let t=0;t<l;t++){const n=s.join(o,"fjall"),i=s.join(n,"fjall-config.json");if(r.existsSync(i))return n;const c=s.join(o,"fjall-config.json");if(r.existsSync(c))return o;const f=s.dirname(o);if(f===o)break;o=f}return null}static loadConfigFile(o){try{return r.accessSync(o,r.constants.R_OK|r.constants.W_OK),r.readFileSync(o,{encoding:"utf8"})}catch(t){return g.debug("Config","Config file not accessible",{file:o,error:t instanceof Error?t.message:String(t)}),null}}static loadConfig(){const o=a.findConfigDirectory();if(!o)return new a;const t=s.join(o,"fjall-config.json"),n=a.loadConfigFile(t);let i;if(n)try{i=d.parse(JSON.parse(n))}catch(c){throw a.formatZodError(c,"fjall-config.json")}return new a(i,t)}static formatZodError(o,t){if(o instanceof e.ZodError&&o.issues.length>0){const c=o.issues.map(f=>`${f.path.join(".")}: ${f.message}`).join("; ");return new Error(`Failed to parse ${t}: ${c}`)}const i=(o instanceof Error?o.message:String(o)).replace(/\n/g," ").substring(0,500);return new Error(`Failed to parse ${t}: ${i}`)}saveConfig(){let o=this.configPath;if(!o){const c=a.findConfigDirectory()||s.join(process.cwd(),"fjall");o=s.join(c,"fjall-config.json")}const t=s.dirname(o);r.mkdirSync(t,{recursive:!0});const n=JSON.stringify(this.rootConfig,null,2),i=`${o}.tmp`;r.writeFileSync(i,n,{mode:384}),r.renameSync(i,o)}static getConfigDirectory(){return a.findConfigDirectory()}getActiveTarget(){return this.rootConfig.activeTarget}setActiveTarget(o){this.rootConfig.activeTarget=o}clearActiveTarget(){this.rootConfig.activeTarget=void 0}getDomains(){return this.rootConfig.domains??[]}setDomains(o){this.rootConfig.domains=o}addDomain(o){this.rootConfig.domains||(this.rootConfig.domains=[]),this.rootConfig.domains.push(o)}getDomain(o){return this.rootConfig.domains?.find(t=>t.name.toLowerCase()===o.toLowerCase())}removeDomain(o){if(!this.rootConfig.domains)return!1;const t=this.rootConfig.domains.findIndex(n=>n.name.toLowerCase()===o.toLowerCase());return t===-1?!1:(this.rootConfig.domains.splice(t,1),!0)}}export{a as Config,d as RootConfigSchema};
|
|
1
|
+
import*as r from"fs";import*as s from"path";import{z as e}from"zod";import{logger as g}from"./logger.js";const l=10,h=["compliance","governance","none"],m=e.object({name:e.string(),type:e.enum(["apex","delegated"]),parentDomain:e.string().optional(),account:e.string().optional()}).strict(),d=e.object({activeTarget:e.string().optional(),domains:e.array(m).optional()}).strict();class a{rootConfig;configPath=null;constructor(o,t){this.rootConfig=o??{},this.configPath=t??null}static findConfigDirectory(){let o=process.cwd();for(let t=0;t<l;t++){const n=s.join(o,"fjall"),i=s.join(n,"fjall-config.json");if(r.existsSync(i))return n;const c=s.join(o,"fjall-config.json");if(r.existsSync(c))return o;const f=s.dirname(o);if(f===o)break;o=f}return null}static loadConfigFile(o){try{return r.accessSync(o,r.constants.R_OK|r.constants.W_OK),r.readFileSync(o,{encoding:"utf8"})}catch(t){return g.debug("Config","Config file not accessible",{file:o,error:t instanceof Error?t.message:String(t)}),null}}static loadConfig(){const o=a.findConfigDirectory();if(!o)return new a;const t=s.join(o,"fjall-config.json"),n=a.loadConfigFile(t);let i;if(n)try{i=d.parse(JSON.parse(n))}catch(c){throw a.formatZodError(c,"fjall-config.json")}return new a(i,t)}static formatZodError(o,t){if(o instanceof e.ZodError&&o.issues.length>0){const c=o.issues.map(f=>`${f.path.join(".")}: ${f.message}`).join("; ");return new Error(`Failed to parse ${t}: ${c}`)}const i=(o instanceof Error?o.message:String(o)).replace(/\n/g," ").substring(0,500);return new Error(`Failed to parse ${t}: ${i}`)}saveConfig(){let o=this.configPath;if(!o){const c=a.findConfigDirectory()||s.join(process.cwd(),"fjall");o=s.join(c,"fjall-config.json")}const t=s.dirname(o);r.mkdirSync(t,{recursive:!0});const n=JSON.stringify(this.rootConfig,null,2),i=`${o}.tmp`;r.writeFileSync(i,n,{mode:384}),r.renameSync(i,o)}static getConfigDirectory(){return a.findConfigDirectory()}getActiveTarget(){return this.rootConfig.activeTarget}setActiveTarget(o){this.rootConfig.activeTarget=o}clearActiveTarget(){this.rootConfig.activeTarget=void 0}getDomains(){return this.rootConfig.domains??[]}setDomains(o){this.rootConfig.domains=o}addDomain(o){this.rootConfig.domains||(this.rootConfig.domains=[]),this.rootConfig.domains.push(o)}getDomain(o){return this.rootConfig.domains?.find(t=>t.name.toLowerCase()===o.toLowerCase())}removeDomain(o){if(!this.rootConfig.domains)return!1;const t=this.rootConfig.domains.findIndex(n=>n.name.toLowerCase()===o.toLowerCase());return t===-1?!1:(this.rootConfig.domains.splice(t,1),!0)}}export{a as Config,d as RootConfigSchema,h as VAULT_LOCK_MODES};
|
|
@@ -76,6 +76,7 @@ declare const ManifestServiceSchema: z.ZodObject<{
|
|
|
76
76
|
containerPort: z.ZodOptional<z.ZodNumber>;
|
|
77
77
|
secrets: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
78
78
|
ssmSecretsPath: z.ZodOptional<z.ZodString>;
|
|
79
|
+
importedSecretNames: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
79
80
|
}, z.core.$strict>;
|
|
80
81
|
export type ManifestService = z.infer<typeof ManifestServiceSchema>;
|
|
81
82
|
declare const ManifestPatternSchema: z.ZodObject<{
|
|
@@ -94,6 +95,7 @@ declare const ManifestLambdaSchema: z.ZodObject<{
|
|
|
94
95
|
name: z.ZodString;
|
|
95
96
|
secrets: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
96
97
|
ssmSecretsPath: z.ZodOptional<z.ZodString>;
|
|
98
|
+
importedSecretNames: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
97
99
|
}, z.core.$strict>;
|
|
98
100
|
export type ManifestLambda = z.infer<typeof ManifestLambdaSchema>;
|
|
99
101
|
declare const ManifestStackHashSchema: z.ZodObject<{
|
|
@@ -133,11 +135,13 @@ export declare const FjallManifestSchema: z.ZodObject<{
|
|
|
133
135
|
containerPort: z.ZodOptional<z.ZodNumber>;
|
|
134
136
|
secrets: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
135
137
|
ssmSecretsPath: z.ZodOptional<z.ZodString>;
|
|
138
|
+
importedSecretNames: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
136
139
|
}, z.core.$strict>>;
|
|
137
140
|
lambdas: z.ZodArray<z.ZodObject<{
|
|
138
141
|
name: z.ZodString;
|
|
139
142
|
secrets: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
140
143
|
ssmSecretsPath: z.ZodOptional<z.ZodString>;
|
|
144
|
+
importedSecretNames: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
141
145
|
}, z.core.$strict>>;
|
|
142
146
|
pattern: z.ZodOptional<z.ZodObject<{
|
|
143
147
|
type: z.ZodEnum<{
|
package/dist/manifest/schemas.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{z as t}from"zod";const h="fjall-manifest.json",
|
|
1
|
+
import{z as t}from"zod";const h="fjall-manifest.json",d=1,s=t.object({path:t.string(),context:t.string().min(1,"context cannot be empty").optional(),target:t.string().min(1,"target cannot be empty").optional(),buildArgs:t.record(t.string(),t.string()).optional()}).strict(),S=s.partial();function b(e,r){if(r===void 0)return e;const n=r.context??e.context,a=r.target??e.target,o=r.buildArgs??e.buildArgs;return{path:r.path??e.path,...n!==void 0&&{context:n},...a!==void 0&&{target:a},...o!==void 0&&{buildArgs:o}}}const c=t.object({name:t.string(),clusterName:t.string().optional(),docker:s.optional(),containerPort:t.number().optional(),secrets:t.array(t.string()).optional(),ssmSecretsPath:t.string().optional(),importedSecretNames:t.array(t.string()).optional()}).strict(),i=t.object({type:t.enum(["payload"]),name:t.string(),source:t.string()}).strict(),p=t.object({repositoryName:t.string()}).strict(),g=t.object({name:t.string(),secrets:t.array(t.string()).optional(),ssmSecretsPath:t.string().optional(),importedSecretNames:t.array(t.string()).optional()}).strict(),m=t.object({templateHash:t.string(),synthTimestamp:t.string()}).strict(),l=t.object({constructPath:t.string().max(512),group:t.string().max(128),resourceType:t.string().max(256)}).strict(),x=t.object({version:t.literal(d),generatedAt:t.string(),appName:t.string(),services:t.array(c),lambdas:t.array(g),pattern:i.optional(),ecr:p.optional(),stacks:t.record(t.string(),m),resourceMap:t.record(t.string(),l).optional()}).strict();export{S as DockerBuildPartialSchema,s as DockerBuildSchema,h as FJALL_MANIFEST_FILENAME,x as FjallManifestSchema,d as MANIFEST_SCHEMA_VERSION,p as ManifestEcrSchema,g as ManifestLambdaSchema,i as ManifestPatternSchema,c as ManifestServiceSchema,m as ManifestStackHashSchema,l as ResourceMapEntrySchema,b as mergeDockerBuild};
|
|
@@ -189,11 +189,11 @@ export declare const ResolvedInputsSchema: z.ZodObject<{
|
|
|
189
189
|
}>>;
|
|
190
190
|
patternDomain: z.ZodOptional<z.ZodString>;
|
|
191
191
|
network: z.ZodOptional<z.ZodEnum<{
|
|
192
|
+
none: "none";
|
|
192
193
|
lightweight: "lightweight";
|
|
193
194
|
standard: "standard";
|
|
194
195
|
resilient: "resilient";
|
|
195
196
|
enterprise: "enterprise";
|
|
196
|
-
none: "none";
|
|
197
197
|
}>>;
|
|
198
198
|
template: z.ZodOptional<z.ZodString>;
|
|
199
199
|
docker: z.ZodOptional<z.ZodObject<{
|
|
@@ -225,11 +225,11 @@ export declare const ScaffoldPlanSchema: z.ZodObject<{
|
|
|
225
225
|
}>>;
|
|
226
226
|
patternDomain: z.ZodOptional<z.ZodString>;
|
|
227
227
|
network: z.ZodOptional<z.ZodEnum<{
|
|
228
|
+
none: "none";
|
|
228
229
|
lightweight: "lightweight";
|
|
229
230
|
standard: "standard";
|
|
230
231
|
resilient: "resilient";
|
|
231
232
|
enterprise: "enterprise";
|
|
232
|
-
none: "none";
|
|
233
233
|
}>>;
|
|
234
234
|
template: z.ZodOptional<z.ZodString>;
|
|
235
235
|
docker: z.ZodOptional<z.ZodObject<{
|
package/dist/securityHelpers.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const n=new Set(["NODE_OPTIONS","NODE_PATH","NODE_EXTRA_CA_CERTS","NODE_DEBUG","NODE_PRESERVE_SYMLINKS","LD_PRELOAD","LD_LIBRARY_PATH","LD_AUDIT","LD_BIND_NOW","DYLD_INSERT_LIBRARIES","DYLD_LIBRARY_PATH","DYLD_FRAMEWORK_PATH","PYTHONPATH","PYTHONSTARTUP","PERL5LIB","PERL5OPT","RUBYLIB","RUBYOPT","HOME","XDG_CONFIG_HOME","AWS_SHARED_CREDENTIALS_FILE","AWS_CONFIG_FILE","SHELL","BASH_ENV","ENV","ZDOTDIR"]);function
|
|
1
|
+
const n=new Set(["NODE_OPTIONS","NODE_PATH","NODE_EXTRA_CA_CERTS","NODE_DEBUG","NODE_PRESERVE_SYMLINKS","LD_PRELOAD","LD_LIBRARY_PATH","LD_AUDIT","LD_BIND_NOW","DYLD_INSERT_LIBRARIES","DYLD_LIBRARY_PATH","DYLD_FRAMEWORK_PATH","PYTHONPATH","PYTHONSTARTUP","PERL5LIB","PERL5OPT","RUBYLIB","RUBYOPT","HOME","XDG_CONFIG_HOME","AWS_SHARED_CREDENTIALS_FILE","AWS_CONFIG_FILE","SHELL","BASH_ENV","ENV","ZDOTDIR"]);function c(e){return Object.fromEntries(Object.entries(e).filter(([t])=>!n.has(t.toUpperCase())))}const i=/fjall_ak_[A-Z2-7]{16}\.[A-Z2-7]{40}/,l=/fjall_ak_[A-Z2-7]{16}\.[A-Z2-7]{40}/g;function o(e){return e.replace(/-----BEGIN [A-Z ]*PRIVATE KEY-----(?:[^"\\]|\\[\\nrt"])*?-----END [A-Z ]*PRIVATE KEY-----/g,"-----BEGIN [REDACTED] PRIVATE KEY-----...-----END [REDACTED] PRIVATE KEY-----").replace(/-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----/g,"-----BEGIN [REDACTED] PRIVATE KEY-----...-----END [REDACTED] PRIVATE KEY-----").replace(/(\w+:\/\/[^:]+:)[^@]+(@)/gi,"$1***$2").replace(/(?<![a-zA-Z])(password|passwd|secret|api[_-]?key|token|auth|credential)([=:])["']?[^\s"']+/gi,"$1$2***").replace(/\b(ghu_|ghs_|ghp_|gho_|github_pat_)[A-Za-z0-9_]+/g,"$1***").replace(/\b(sk|rk)_(live|test)_[A-Za-z0-9]{8,}/g,"$1_$2_***").replace(/\bwhsec_[A-Za-z0-9]{8,}/g,"whsec_***").replace(/(?<=Authorization:\s*Bearer\s+)[A-Za-z0-9._~+/=-]+/gi,"***").replace(/\b(AKIA|ASIA)[A-Z0-9]{12,}\b/g,"$1***").replace(/(?<=AWS_SECRET_ACCESS_KEY=|SecretAccessKey[=:]\s*|"secretAccessKey":\s*")[A-Za-z0-9/+=]{40,}/g,"***").replace(/(arn:aws[^:]*:[^:]*:[^:]*:)(\d{12})(:[^\s]*)/g,"$1***$3").replace(/(?<="(aws)?[Ss]essionToken":\s*")[^"]+/g,"***").replace(/(?<="(internal[Aa]piKey|fjallCallbackToken)":\s*")[^"]+/g,"***").replace(l,"fjall_ak_***")}function D(e){const t=[];let E="",r=!1,A=!1,_=!1,s=!1;for(const a of e){if(_){E+=a,_=!1;continue}if(a==="\\"&&!r){_=!0;continue}if(a==="'"&&!A){r=!r,s=!0;continue}if(a==='"'&&!r){A=!A,s=!0;continue}if(a===" "&&!r&&!A){(E||s)&&(t.push(E),E="",s=!1);continue}E+=a}if(r||A)throw new Error(`Unbalanced ${r?"single":"double"} quote in command: ${e.slice(0,80)}`);if(_)throw new Error(`Trailing backslash in command: ${e.slice(0,80)}`);return(E||s)&&t.push(E),t}export{n as DANGEROUS_ENV_VARS,i as SCOPED_TOKEN_REGEX,c as filterDangerousEnvVars,o as maskSensitiveOutput,D as parseShellArgs};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fjall/util",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.11.1",
|
|
4
4
|
"description": "Common utility methods",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -117,5 +117,5 @@
|
|
|
117
117
|
"engines": {
|
|
118
118
|
"node": ">=22.0.0"
|
|
119
119
|
},
|
|
120
|
-
"gitHead": "
|
|
120
|
+
"gitHead": "69823c3d7f2eacba419657464381119c5b5b5fd6"
|
|
121
121
|
}
|