Code clean up and add tests

This commit is contained in:
Jill Regan
2026-02-20 15:59:25 -05:00
parent 41f600a118
commit 3c643fe809
5 changed files with 454 additions and 101 deletions

View File

@@ -19,7 +19,7 @@ interface ParsedOpRef {
field: string;
}
const parseOpRef = (ref: string): ParsedOpRef => {
export const parseOpRef = (ref: string): ParsedOpRef => {
// Safety check: refs are validated by validateSecretRefs before this runs
// this guards against parseOpRef being called directly with invalid input
if (!ref.startsWith("op://")) {
@@ -113,7 +113,7 @@ const getSecretFromConnectItem = async (
);
};
const findSectionIdsByQuery = (
export const findSectionIdsByQuery = (
sections: FullItem["sections"],
sectionQuery: string | undefined,
): string[] => {
@@ -126,8 +126,7 @@ const findSectionIdsByQuery = (
const ids = sections
.filter((s) => s.id === sectionQuery || s.label === sectionQuery)
.map((s) => s.id!)
.filter(Boolean);
.flatMap((s) => (s.id ? [s.id] : []));
// If no sections were found with the given query throw an error
if (ids.length === 0) {
@@ -139,116 +138,76 @@ const findSectionIdsByQuery = (
return ids;
};
const findMatchingFieldAndFile = (
export const findMatchingFieldAndFile = (
item: FullItem,
fieldOrFileQuery: string,
sectionIds: string[],
): { fieldValue?: string; fileId?: string } => {
const errMultiple = `multiple fields ${fieldOrFileQuery} that match the provided reference have been found`;
// Get the fields/files from the item and check if the ref has a section filter
const fields = item.fields ?? [];
const files = item.files ?? [];
const sectionFilter = sectionIds.length > 0;
const fieldMatchesQuery = (f: (typeof fields)[0]) =>
f.id === fieldOrFileQuery || f.label === fieldOrFileQuery;
const fileMatchesQuery = (f: (typeof files)[0]) =>
f.id === fieldOrFileQuery || f.name === fieldOrFileQuery;
let matchedField: (typeof fields)[0] | undefined;
let matchedFile: (typeof files)[0] | undefined;
if (sectionFilter) {
// Filter fields by section
// If the ref has a section filter only accept matches inside the referenced sections
const matchingFields = fields.filter((f) => {
const fieldIdOrLabelMatchesQuery =
f.id === fieldOrFileQuery || f.label === fieldOrFileQuery;
const sectionId = f.section?.id;
const fieldSectionIsInRefSections =
const inRefSections =
sectionId !== null &&
sectionId !== undefined &&
sectionIds.includes(sectionId);
return fieldIdOrLabelMatchesQuery && fieldSectionIsInRefSections;
return fieldMatchesQuery(f) && inRefSections;
});
// If multiple fields match the query throw an error otherwise set first matching field
if (matchingFields.length > 1) {
throw new Error(errMultiple);
}
matchedField = matchingFields[0];
matchedField = findSingleMatch(matchingFields);
const matchingFiles = files.filter((f) => {
const fileIdOrNameMatchesQuery =
f.id === fieldOrFileQuery || f.name === fieldOrFileQuery;
const sectionId = f.section?.id;
const fileSectionIsInRefSections =
const inRefSections =
sectionId !== null &&
sectionId !== undefined &&
sectionIds.includes(sectionId);
return fileIdOrNameMatchesQuery && fileSectionIsInRefSections;
return fileMatchesQuery(f) && inRefSections;
});
// If multiple files match the query throw an error otherwise set first matching file
if (matchingFiles.length > 1) {
throw new Error(errMultiple);
}
matchedFile = matchingFiles[0];
matchedFile = findSingleMatch(matchingFiles);
} else {
// If the ref has no section filter search for matches with no section
const matchingFields = fields.filter((f) => {
const fieldIdOrLabelMatchesQuery =
f.id === fieldOrFileQuery || f.label === fieldOrFileQuery;
const fieldHasNoSection =
const hasNoSection =
f.section?.id === null || f.section?.id === undefined;
return fieldIdOrLabelMatchesQuery && fieldHasNoSection;
return fieldMatchesQuery(f) && hasNoSection;
});
matchedField = findSingleMatch(matchingFields);
// If multiple fields match the query throw an error otherwise set first matching field
if (matchingFields.length > 1) {
throw new Error(errMultiple);
}
matchedField = matchingFields[0];
// If no field was found with no section, find a field in any section
// If no matches were found with no section, search for matches in any section
if (!matchedField) {
const matchingFieldsInAnySection = fields.filter((f) => {
const fieldIdOrLabelMatchesQuery =
f.id === fieldOrFileQuery || f.label === fieldOrFileQuery;
return fieldIdOrLabelMatchesQuery;
});
if (matchingFieldsInAnySection.length > 1) {
throw new Error(errMultiple);
}
matchedField = matchingFieldsInAnySection[0];
const matchingFieldsInAnySection = fields.filter(fieldMatchesQuery);
matchedField = findSingleMatch(matchingFieldsInAnySection);
}
const matchingFiles = files.filter((f) => {
const fileIdOrNameMatchesQuery =
f.id === fieldOrFileQuery || f.name === fieldOrFileQuery;
const fileHasNoSection =
const hasNoSection =
f.section?.id === null || f.section?.id === undefined;
return fileIdOrNameMatchesQuery && fileHasNoSection;
return fileMatchesQuery(f) && hasNoSection;
});
matchedFile = findSingleMatch(matchingFiles);
// If multiple files match the query throw an error otherwise set first matching file
if (matchingFiles.length > 1) {
throw new Error(errMultiple);
}
matchedFile = matchingFiles[0];
// If no file was found with no section, find a file in any section
if (!matchedFile) {
const matchingFilesInAnySection = files.filter((f) => {
const fileIdOrNameMatchesQuery =
f.id === fieldOrFileQuery || f.name === fieldOrFileQuery;
return fileIdOrNameMatchesQuery;
});
if (matchingFilesInAnySection.length > 1) {
throw new Error(errMultiple);
}
matchedFile = matchingFilesInAnySection[0];
const matchingFilesInAnySection = files.filter(fileMatchesQuery);
matchedFile = findSingleMatch(matchingFilesInAnySection);
}
}
if (matchedField && matchedFile) {
throw new Error(
`you cannot query fields/files that are identically named.`,
`Both a field and a file match "${fieldOrFileQuery}". Rename one or use the ID in your op:// reference.`,
);
}
@@ -262,16 +221,24 @@ const findMatchingFieldAndFile = (
}
if (matchedFile?.id) {
const fileId = matchedFile.id;
return { fileId };
return { fileId: matchedFile.id };
}
return {};
};
const findSingleMatch = <T>(matches: T[]): T | undefined => {
if (matches.length > 1) {
throw new Error(
"Multiple matches found. Rename one or use an ID in your op:// reference.",
);
}
return matches[0];
};
// #endregion
// #region Shared helpers and auth
const getEnvVarNamesWithSecretRefs = (): string[] =>
export const getEnvVarNamesWithSecretRefs = (): string[] =>
Object.keys(process.env).filter(
(key) =>
typeof process.env[key] === "string" &&
@@ -364,6 +331,29 @@ export const unsetPrevious = (): void => {
}
}
};
const fetchVaultId = async (
client: OPConnect,
vaultQuery: string,
ref: string,
cache: Map<string, string>,
): Promise<string> => {
// Check if the vault ID is already cached
const cached = cache.get(vaultQuery);
if (cached !== undefined) {
return cached;
}
const vault = await client.getVault(vaultQuery);
if (!vault.id) {
throw new Error(
`Could not find valid vault "${vaultQuery}" for ref "${ref}"`,
);
}
cache.set(vaultQuery, vault.id);
return vault.id;
};
// #endregion
// #region Load secrets
@@ -397,25 +387,33 @@ const loadSecretsViaConnect = async (
throw new Error(`Connect authentication failed: ${message}`);
}
const vaultIdByQuery = new Map<string, string>();
for (const envName of envs) {
const ref = process.env[envName];
if (!ref) {
continue;
}
// Parse the op ref and get the item from the Connect SDK
const parsed = parseOpRef(ref);
const vault = await client.getVault(parsed.vault);
if (!vault.id) {
throw new Error(
`Could not find valid vault "${parsed.vault}" for ref "${ref}"`,
);
}
const item = await client.getItem(vault.id, parsed.item);
try {
// Parse the op ref and get the item from the Connect SDK
const parsed = parseOpRef(ref);
// Get the secret value from the item as Connect returns a full item object
const secretValue = await getSecretFromConnectItem(client, item, parsed);
setResolvedSecret(envName, secretValue, shouldExportEnv);
const vaultId = await fetchVaultId(
client,
parsed.vault,
ref,
vaultIdByQuery,
);
const item = await client.getItem(vaultId, parsed.item);
// Get the secret value from the item as Connect returns a full item object
const secretValue = await getSecretFromConnectItem(client, item, parsed);
setResolvedSecret(envName, secretValue, shouldExportEnv);
} catch (err) {
const msg = err instanceof Error ? err.message : String(err);
throw new Error(`Failed to load ref "${ref}": ${msg}`);
}
}
if (shouldExportEnv) {