applyTemplate function exported
Last updated: 2026-03-04T23:21:38.398Z
Location
Metrics
LOC: 140
Complexity: 54
Params: 2
Signature
applyTemplate(
form: SavedForm,
): : Promise<{ filled: number }>
Summary
Applies a saved form template to the current page. Uses templateFields (new format) if available, otherwise falls back to legacy fields. For generator-mode fields, calls the appropriate generator to produce a fresh value.
Architecture violations
- [warning] max-cyclomatic-complexity: 'applyTemplate' has cyclomatic complexity 54 (max 10)
- [warning] max-lines: 'applyTemplate' has 140 lines (max 80)
Source Code
export async function applyTemplate(
form: SavedForm,
): Promise<{ filled: number }> {
const { fields: allDetectedFields } = await detectAllFieldsAsync();
const settings = await getSettings();
const url = window.location.href;
// Skip fields the user has marked as ignored
const ignoredFields = await getIgnoredFieldsForUrl(url);
const ignoredSelectors = new Set(ignoredFields.map((f) => f.selector));
const detectedFields = allDetectedFields.filter(
(f) => !ignoredSelectors.has(f.selector),
);
let filled = 0;
if (form.templateFields && form.templateFields.length > 0) {
// Pre-generate ONE consistent value per field type (fixed or generator).
// Generator fields are produced once so that derivations remain coherent —
// e.g. first-name and last-name derived from the same generated full-name.
const templateValueMap = new Map<FieldType, string>();
for (const tField of form.templateFields) {
if (!tField.matchByFieldType) continue;
if (tField.mode === "generator" && tField.generatorType) {
templateValueMap.set(
tField.matchByFieldType,
generate(tField.generatorType, tField.generatorParams ?? undefined),
);
} else if (tField.mode === "fixed" && tField.fixedValue) {
templateValueMap.set(tField.matchByFieldType, tField.fixedValue);
}
}
// For type-based templates (matchByFieldType), track which fields were already handled
const handledSelectors = new Set<string>();
for (const tField of form.templateFields) {
// Type-based matching: find ALL fields of the given type
if (tField.matchByFieldType) {
const matchedFields = detectedFields.filter(
(f) =>
f.fieldType === tField.matchByFieldType &&
!handledSelectors.has(f.selector),
);
for (const matchedField of matchedFields) {
// Use the pre-generated value to keep derived fields coherent
const value = templateValueMap.get(tField.matchByFieldType) ?? "";
if (!value) continue;
await applyValueToField(matchedField, value);
if (settings.highlightFilled) {
highlightField(
matchedField.element,
matchedField.label ?? matchedField.fieldType ?? undefined,
);
}
handledSelectors.add(matchedField.selector);
filled++;
}
continue;
}
// Selector-based matching (legacy / saved-from-page templates)
const matchedField = detectedFields.find(
(f) =>
f.selector === tField.key ||
f.id === tField.key ||
f.name === tField.key,
);
if (!matchedField) continue;
let value: string;
if (tField.mode === "generator" && tField.generatorType) {
value = generate(
tField.generatorType,
tField.generatorParams ?? undefined,
);
} else {
value = tField.fixedValue ?? "";
}
if (!value && tField.mode === "fixed") continue;
await applyValueToField(matchedField, value);
if (settings.highlightFilled) {
highlightField(
matchedField.element,
matchedField.label ?? matchedField.fieldType ?? undefined,
);
}
handledSelectors.add(matchedField.selector);
filled++;
}
// Fallback: fill detected fields not covered by the template.
// Priority: (1) direct match in map (same type, missed the loop somehow)
// (2) smart derivation from a related type (e.g. first-name ← full-name)
for (const field of detectedFields) {
if (handledSelectors.has(field.selector) || !field.fieldType) continue;
const value =
templateValueMap.get(field.fieldType) ??
deriveFieldValueFromTemplate(field.fieldType, templateValueMap);
if (!value) continue;
await applyValueToField(field, value);
if (settings.highlightFilled) {
highlightField(
field.element,
field.label ?? field.fieldType ?? undefined,
);
}
filled++;
}
} else {
// Legacy format: fields Record<string, string>
for (const detectedField of detectedFields) {
const key =
detectedField.id || detectedField.name || detectedField.selector;
const value =
form.fields[detectedField.selector] ??
form.fields[key] ??
(detectedField.name ? form.fields[detectedField.name] : undefined) ??
(detectedField.id ? form.fields[detectedField.id] : undefined);
if (value === undefined) continue;
await applyValueToField(detectedField, value);
if (settings.highlightFilled) {
highlightField(
detectedField.element,
detectedField.label ?? detectedField.fieldType ?? undefined,
);
}
filled++;
}
}
log.info(`Template "${form.name}" aplicado: ${filled} campos`);
return { filled };
}
Dependencies (Outgoing)
| Target | Type |
|---|---|
| detectAllFieldsAsync | calls |
| applyValueToField | calls |
| highlightField | calls |
Impact (Incoming)
| Source | Type |
|---|---|
| FillableElement | uses |
| makeInput | uses |