@mercuryo-ai/agentbrowse 0.2.50
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 +15 -0
- package/README.md +335 -0
- package/dist/assistive-runtime.d.ts +110 -0
- package/dist/assistive-runtime.d.ts.map +1 -0
- package/dist/assistive-runtime.js +79 -0
- package/dist/assistive-runtime.test-support.d.ts +7 -0
- package/dist/assistive-runtime.test-support.d.ts.map +1 -0
- package/dist/assistive-runtime.test-support.js +106 -0
- package/dist/assistive-stagehand.d.ts +12 -0
- package/dist/assistive-stagehand.d.ts.map +1 -0
- package/dist/assistive-stagehand.js +10 -0
- package/dist/browser-session-state.d.ts +95 -0
- package/dist/browser-session-state.d.ts.map +1 -0
- package/dist/browser-session-state.js +279 -0
- package/dist/client-bindings.d.ts +10 -0
- package/dist/client-bindings.d.ts.map +1 -0
- package/dist/client-bindings.js +18 -0
- package/dist/client.d.ts +49 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +63 -0
- package/dist/command-api-tracing.d.ts +20 -0
- package/dist/command-api-tracing.d.ts.map +1 -0
- package/dist/command-api-tracing.js +149 -0
- package/dist/command-name.d.ts +3 -0
- package/dist/command-name.d.ts.map +1 -0
- package/dist/command-name.js +11 -0
- package/dist/commands/act.d.ts +43 -0
- package/dist/commands/act.d.ts.map +1 -0
- package/dist/commands/act.js +1107 -0
- package/dist/commands/action-acceptance.d.ts +93 -0
- package/dist/commands/action-acceptance.d.ts.map +1 -0
- package/dist/commands/action-acceptance.js +1938 -0
- package/dist/commands/action-artifacts.d.ts +33 -0
- package/dist/commands/action-artifacts.d.ts.map +1 -0
- package/dist/commands/action-artifacts.js +104 -0
- package/dist/commands/action-execution-guards.d.ts +5 -0
- package/dist/commands/action-execution-guards.d.ts.map +1 -0
- package/dist/commands/action-execution-guards.js +3 -0
- package/dist/commands/action-executor-helpers.d.ts +21 -0
- package/dist/commands/action-executor-helpers.d.ts.map +1 -0
- package/dist/commands/action-executor-helpers.js +265 -0
- package/dist/commands/action-executor.d.ts +14 -0
- package/dist/commands/action-executor.d.ts.map +1 -0
- package/dist/commands/action-executor.js +46 -0
- package/dist/commands/action-fallbacks.d.ts +6 -0
- package/dist/commands/action-fallbacks.d.ts.map +1 -0
- package/dist/commands/action-fallbacks.js +43 -0
- package/dist/commands/action-result-resolution.d.ts +17 -0
- package/dist/commands/action-result-resolution.d.ts.map +1 -0
- package/dist/commands/action-result-resolution.js +132 -0
- package/dist/commands/action-value-projection.d.ts +32 -0
- package/dist/commands/action-value-projection.d.ts.map +1 -0
- package/dist/commands/action-value-projection.js +151 -0
- package/dist/commands/attach.d.ts +41 -0
- package/dist/commands/attach.d.ts.map +1 -0
- package/dist/commands/attach.js +103 -0
- package/dist/commands/browse-actions.d.ts +4 -0
- package/dist/commands/browse-actions.d.ts.map +1 -0
- package/dist/commands/browse-actions.js +4 -0
- package/dist/commands/browser-status.d.ts +57 -0
- package/dist/commands/browser-status.d.ts.map +1 -0
- package/dist/commands/browser-status.js +243 -0
- package/dist/commands/click-action-executor.d.ts +12 -0
- package/dist/commands/click-action-executor.d.ts.map +1 -0
- package/dist/commands/click-action-executor.js +111 -0
- package/dist/commands/click-activation-policy.d.ts +5 -0
- package/dist/commands/click-activation-policy.d.ts.map +1 -0
- package/dist/commands/click-activation-policy.js +13 -0
- package/dist/commands/close.d.ts +26 -0
- package/dist/commands/close.d.ts.map +1 -0
- package/dist/commands/close.js +124 -0
- package/dist/commands/datepicker-action-executor.d.ts +12 -0
- package/dist/commands/datepicker-action-executor.d.ts.map +1 -0
- package/dist/commands/datepicker-action-executor.js +218 -0
- package/dist/commands/descriptor-validation.d.ts +27 -0
- package/dist/commands/descriptor-validation.d.ts.map +1 -0
- package/dist/commands/descriptor-validation.js +192 -0
- package/dist/commands/extract-scope-resolution.d.ts +20 -0
- package/dist/commands/extract-scope-resolution.d.ts.map +1 -0
- package/dist/commands/extract-scope-resolution.js +109 -0
- package/dist/commands/extract-scoped-dialog-text.d.ts +3 -0
- package/dist/commands/extract-scoped-dialog-text.d.ts.map +1 -0
- package/dist/commands/extract-scoped-dialog-text.js +210 -0
- package/dist/commands/extract-snapshot-sanitizer.d.ts +5 -0
- package/dist/commands/extract-snapshot-sanitizer.d.ts.map +1 -0
- package/dist/commands/extract-snapshot-sanitizer.js +98 -0
- package/dist/commands/extract-stagehand-executor.d.ts +17 -0
- package/dist/commands/extract-stagehand-executor.d.ts.map +1 -0
- package/dist/commands/extract-stagehand-executor.js +112 -0
- package/dist/commands/extract.d.ts +57 -0
- package/dist/commands/extract.d.ts.map +1 -0
- package/dist/commands/extract.js +668 -0
- package/dist/commands/interaction-kernel.d.ts +46 -0
- package/dist/commands/interaction-kernel.d.ts.map +1 -0
- package/dist/commands/interaction-kernel.js +215 -0
- package/dist/commands/launch.d.ts +41 -0
- package/dist/commands/launch.d.ts.map +1 -0
- package/dist/commands/launch.js +182 -0
- package/dist/commands/navigate.d.ts +31 -0
- package/dist/commands/navigate.d.ts.map +1 -0
- package/dist/commands/navigate.js +202 -0
- package/dist/commands/observe-accessibility.d.ts +22 -0
- package/dist/commands/observe-accessibility.d.ts.map +1 -0
- package/dist/commands/observe-accessibility.js +566 -0
- package/dist/commands/observe-display-label.d.ts +4 -0
- package/dist/commands/observe-display-label.d.ts.map +1 -0
- package/dist/commands/observe-display-label.js +26 -0
- package/dist/commands/observe-dom-label-contract.d.ts +2 -0
- package/dist/commands/observe-dom-label-contract.d.ts.map +1 -0
- package/dist/commands/observe-dom-label-contract.js +564 -0
- package/dist/commands/observe-fallback-semantics.d.ts +6 -0
- package/dist/commands/observe-fallback-semantics.d.ts.map +1 -0
- package/dist/commands/observe-fallback-semantics.js +86 -0
- package/dist/commands/observe-inventory.d.ts +149 -0
- package/dist/commands/observe-inventory.d.ts.map +1 -0
- package/dist/commands/observe-inventory.js +3545 -0
- package/dist/commands/observe-label-policy.d.ts +8 -0
- package/dist/commands/observe-label-policy.d.ts.map +1 -0
- package/dist/commands/observe-label-policy.js +21 -0
- package/dist/commands/observe-page-state.d.ts +11 -0
- package/dist/commands/observe-page-state.d.ts.map +1 -0
- package/dist/commands/observe-page-state.js +89 -0
- package/dist/commands/observe-persistence.d.ts +15 -0
- package/dist/commands/observe-persistence.d.ts.map +1 -0
- package/dist/commands/observe-persistence.js +238 -0
- package/dist/commands/observe-projection.d.ts +119 -0
- package/dist/commands/observe-projection.d.ts.map +1 -0
- package/dist/commands/observe-projection.js +726 -0
- package/dist/commands/observe-protected.d.ts +6 -0
- package/dist/commands/observe-protected.d.ts.map +1 -0
- package/dist/commands/observe-protected.js +31 -0
- package/dist/commands/observe-semantics.d.ts +10 -0
- package/dist/commands/observe-semantics.d.ts.map +1 -0
- package/dist/commands/observe-semantics.js +535 -0
- package/dist/commands/observe-signals.d.ts +48 -0
- package/dist/commands/observe-signals.d.ts.map +1 -0
- package/dist/commands/observe-signals.js +461 -0
- package/dist/commands/observe-stagehand.d.ts +49 -0
- package/dist/commands/observe-stagehand.d.ts.map +1 -0
- package/dist/commands/observe-stagehand.js +94 -0
- package/dist/commands/observe-surfaces.d.ts +11 -0
- package/dist/commands/observe-surfaces.d.ts.map +1 -0
- package/dist/commands/observe-surfaces.js +290 -0
- package/dist/commands/observe.d.ts +113 -0
- package/dist/commands/observe.d.ts.map +1 -0
- package/dist/commands/observe.js +556 -0
- package/dist/commands/screenshot.d.ts +37 -0
- package/dist/commands/screenshot.d.ts.map +1 -0
- package/dist/commands/screenshot.js +269 -0
- package/dist/commands/select-action-executor.d.ts +10 -0
- package/dist/commands/select-action-executor.d.ts.map +1 -0
- package/dist/commands/select-action-executor.js +156 -0
- package/dist/commands/semantic-observe-lexical.d.ts +31 -0
- package/dist/commands/semantic-observe-lexical.d.ts.map +1 -0
- package/dist/commands/semantic-observe-lexical.js +186 -0
- package/dist/commands/semantic-observe.d.ts +37 -0
- package/dist/commands/semantic-observe.d.ts.map +1 -0
- package/dist/commands/semantic-observe.js +1339 -0
- package/dist/commands/structured-grid-action-executor.d.ts +3 -0
- package/dist/commands/structured-grid-action-executor.d.ts.map +1 -0
- package/dist/commands/structured-grid-action-executor.js +4 -0
- package/dist/commands/target-resolution.d.ts +4 -0
- package/dist/commands/target-resolution.d.ts.map +1 -0
- package/dist/commands/target-resolution.js +33 -0
- package/dist/commands/text-input-action-executor.d.ts +5 -0
- package/dist/commands/text-input-action-executor.d.ts.map +1 -0
- package/dist/commands/text-input-action-executor.js +116 -0
- package/dist/commands/user-actionable.d.ts +4 -0
- package/dist/commands/user-actionable.d.ts.map +1 -0
- package/dist/commands/user-actionable.js +216 -0
- package/dist/control-semantics.d.ts +30 -0
- package/dist/control-semantics.d.ts.map +1 -0
- package/dist/control-semantics.js +419 -0
- package/dist/diagnostics.d.ts +132 -0
- package/dist/diagnostics.d.ts.map +1 -0
- package/dist/diagnostics.js +120 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +350 -0
- package/dist/library.d.ts +17 -0
- package/dist/library.d.ts.map +1 -0
- package/dist/library.js +14 -0
- package/dist/output.d.ts +32 -0
- package/dist/output.d.ts.map +1 -0
- package/dist/output.js +33 -0
- package/dist/owned-browser.d.ts +12 -0
- package/dist/owned-browser.d.ts.map +1 -0
- package/dist/owned-browser.js +69 -0
- package/dist/owned-process.d.ts +19 -0
- package/dist/owned-process.d.ts.map +1 -0
- package/dist/owned-process.js +145 -0
- package/dist/playwright-runtime.d.ts +43 -0
- package/dist/playwright-runtime.d.ts.map +1 -0
- package/dist/playwright-runtime.js +339 -0
- package/dist/protected-fill-browser.d.ts +22 -0
- package/dist/protected-fill-browser.d.ts.map +1 -0
- package/dist/protected-fill-browser.js +52 -0
- package/dist/protected-fill.d.ts +82 -0
- package/dist/protected-fill.d.ts.map +1 -0
- package/dist/protected-fill.js +20 -0
- package/dist/runtime-metrics.d.ts +27 -0
- package/dist/runtime-metrics.d.ts.map +1 -0
- package/dist/runtime-metrics.js +66 -0
- package/dist/runtime-page-state.d.ts +11 -0
- package/dist/runtime-page-state.d.ts.map +1 -0
- package/dist/runtime-page-state.js +62 -0
- package/dist/runtime-protected-state.d.ts +14 -0
- package/dist/runtime-protected-state.d.ts.map +1 -0
- package/dist/runtime-protected-state.js +148 -0
- package/dist/runtime-resolution.d.ts +9 -0
- package/dist/runtime-resolution.d.ts.map +1 -0
- package/dist/runtime-resolution.js +19 -0
- package/dist/runtime-state.d.ts +251 -0
- package/dist/runtime-state.d.ts.map +1 -0
- package/dist/runtime-state.js +599 -0
- package/dist/secrets/catalog-applicability.d.ts +5 -0
- package/dist/secrets/catalog-applicability.d.ts.map +1 -0
- package/dist/secrets/catalog-applicability.js +59 -0
- package/dist/secrets/field-policy.d.ts +3 -0
- package/dist/secrets/field-policy.d.ts.map +1 -0
- package/dist/secrets/field-policy.js +3 -0
- package/dist/secrets/fill-ordering.d.ts +10 -0
- package/dist/secrets/fill-ordering.d.ts.map +1 -0
- package/dist/secrets/fill-ordering.js +41 -0
- package/dist/secrets/form-matcher.d.ts +60 -0
- package/dist/secrets/form-matcher.d.ts.map +1 -0
- package/dist/secrets/form-matcher.js +948 -0
- package/dist/secrets/protected-artifact-guard.d.ts +39 -0
- package/dist/secrets/protected-artifact-guard.d.ts.map +1 -0
- package/dist/secrets/protected-artifact-guard.js +44 -0
- package/dist/secrets/protected-bindings.d.ts +14 -0
- package/dist/secrets/protected-bindings.d.ts.map +1 -0
- package/dist/secrets/protected-bindings.js +29 -0
- package/dist/secrets/protected-exact-value-redaction.d.ts +14 -0
- package/dist/secrets/protected-exact-value-redaction.d.ts.map +1 -0
- package/dist/secrets/protected-exact-value-redaction.js +360 -0
- package/dist/secrets/protected-field-semantics.d.ts +9 -0
- package/dist/secrets/protected-field-semantics.d.ts.map +1 -0
- package/dist/secrets/protected-field-semantics.js +154 -0
- package/dist/secrets/protected-field-values.d.ts +15 -0
- package/dist/secrets/protected-field-values.d.ts.map +1 -0
- package/dist/secrets/protected-field-values.js +131 -0
- package/dist/secrets/protected-fill.d.ts +47 -0
- package/dist/secrets/protected-fill.d.ts.map +1 -0
- package/dist/secrets/protected-fill.js +446 -0
- package/dist/secrets/protected-value-adapters.d.ts +4 -0
- package/dist/secrets/protected-value-adapters.d.ts.map +1 -0
- package/dist/secrets/protected-value-adapters.js +118 -0
- package/dist/secrets/types.d.ts +70 -0
- package/dist/secrets/types.d.ts.map +1 -0
- package/dist/secrets/types.js +30 -0
- package/dist/session.d.ts +19 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +120 -0
- package/dist/solver/browser-launcher.d.ts +14 -0
- package/dist/solver/browser-launcher.d.ts.map +1 -0
- package/dist/solver/browser-launcher.js +799 -0
- package/dist/solver/config.d.ts +18 -0
- package/dist/solver/config.d.ts.map +1 -0
- package/dist/solver/config.js +67 -0
- package/dist/solver/fingerprint.d.ts +9 -0
- package/dist/solver/fingerprint.d.ts.map +1 -0
- package/dist/solver/fingerprint.js +96 -0
- package/dist/solver/profile-manager.d.ts +8 -0
- package/dist/solver/profile-manager.d.ts.map +1 -0
- package/dist/solver/profile-manager.js +74 -0
- package/dist/solver/turnstile-challenge.d.ts +3 -0
- package/dist/solver/turnstile-challenge.d.ts.map +1 -0
- package/dist/solver/turnstile-challenge.js +173 -0
- package/dist/solver/types.d.ts +67 -0
- package/dist/solver/types.d.ts.map +1 -0
- package/dist/solver/types.js +1 -0
- package/dist/stagehand-runtime.d.ts +4 -0
- package/dist/stagehand-runtime.d.ts.map +1 -0
- package/dist/stagehand-runtime.js +10 -0
- package/dist/stagehand.d.ts +15 -0
- package/dist/stagehand.d.ts.map +1 -0
- package/dist/stagehand.js +19 -0
- package/dist/testing.d.ts +5 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +4 -0
- package/dist/update-check.d.ts +14 -0
- package/dist/update-check.d.ts.map +1 -0
- package/dist/update-check.js +182 -0
- package/dist/workflow-session-state.d.ts +30 -0
- package/dist/workflow-session-state.d.ts.map +1 -0
- package/dist/workflow-session-state.js +74 -0
- package/docs/README.md +25 -0
- package/docs/api-reference.md +242 -0
- package/docs/assistive-runtime.md +148 -0
- package/docs/configuration.md +287 -0
- package/docs/getting-started.md +237 -0
- package/docs/integration-checklist.md +36 -0
- package/docs/protected-fill.md +112 -0
- package/docs/testing.md +50 -0
- package/docs/troubleshooting.md +71 -0
- package/examples/README.md +18 -0
- package/examples/attach.ts +27 -0
- package/examples/basic.ts +36 -0
- package/examples/extract.ts +50 -0
- package/package.json +83 -0
|
@@ -0,0 +1,446 @@
|
|
|
1
|
+
import { AgentbrowseAssistiveRuntimeMissingError } from '../assistive-runtime.js';
|
|
2
|
+
import { getSurface, getTarget } from '../runtime-state.js';
|
|
3
|
+
import { createAcceptanceProbe, waitForAcceptanceProbe } from '../commands/action-acceptance.js';
|
|
4
|
+
import { applyActionWithFallbacks } from '../commands/action-executor.js';
|
|
5
|
+
import { normalizePageSignature, readLocatorDomSignature, } from '../commands/descriptor-validation.js';
|
|
6
|
+
import { assertStoredBindingStillValid, resolvePreparedLocatorCandidates, resolveInteractionRoots, } from '../commands/interaction-kernel.js';
|
|
7
|
+
import { resolveProtectedFieldPolicy } from './field-policy.js';
|
|
8
|
+
import { protectedBindingKey } from './protected-bindings.js';
|
|
9
|
+
import { resolveAssistedProtectedFieldValues } from './protected-field-values.js';
|
|
10
|
+
import { resolveDeterministicProtectedBindingValue } from './protected-value-adapters.js';
|
|
11
|
+
import { sortProtectedBindingsForExecution } from './fill-ordering.js';
|
|
12
|
+
function actionForTarget(target) {
|
|
13
|
+
if (target.controlFamily === 'select') {
|
|
14
|
+
return 'select';
|
|
15
|
+
}
|
|
16
|
+
if (target.allowedActions.includes('fill')) {
|
|
17
|
+
return 'fill';
|
|
18
|
+
}
|
|
19
|
+
if (target.allowedActions.includes('type')) {
|
|
20
|
+
return 'type';
|
|
21
|
+
}
|
|
22
|
+
if (target.allowedActions.includes('select')) {
|
|
23
|
+
return 'select';
|
|
24
|
+
}
|
|
25
|
+
return 'fill';
|
|
26
|
+
}
|
|
27
|
+
function formatCardExpiry(month, year) {
|
|
28
|
+
const normalizedMonth = month.trim().padStart(2, '0');
|
|
29
|
+
const normalizedYear = year.trim().length > 2 ? year.trim().slice(-2) : year.trim().padStart(2, '0');
|
|
30
|
+
return `${normalizedMonth}/${normalizedYear}`;
|
|
31
|
+
}
|
|
32
|
+
function resolveBindingValue(fields, target, protectedValues, fieldPolicies, assistedValues) {
|
|
33
|
+
if (fields.length === 1) {
|
|
34
|
+
const field = fields[0];
|
|
35
|
+
const policy = resolveProtectedFieldPolicy(fieldPolicies, field.fieldKey);
|
|
36
|
+
const deterministicValue = resolveDeterministicProtectedBindingValue(field, protectedValues, target);
|
|
37
|
+
if (policy === 'llm_assisted') {
|
|
38
|
+
const assistedValue = assistedValues.get(protectedBindingKey(field));
|
|
39
|
+
if (typeof assistedValue === 'string' && assistedValue.length > 0) {
|
|
40
|
+
return assistedValue;
|
|
41
|
+
}
|
|
42
|
+
throw new Error('assisted_value_resolution_failed');
|
|
43
|
+
}
|
|
44
|
+
if (typeof deterministicValue === 'string' && deterministicValue.length > 0) {
|
|
45
|
+
return deterministicValue;
|
|
46
|
+
}
|
|
47
|
+
if ((field.valueHint ?? 'direct') !== 'direct') {
|
|
48
|
+
throw new Error('deterministic_only_resolution_failed');
|
|
49
|
+
}
|
|
50
|
+
const value = protectedValues[field.fieldKey];
|
|
51
|
+
if (typeof value === 'string' && value.length > 0) {
|
|
52
|
+
return value;
|
|
53
|
+
}
|
|
54
|
+
throw new Error('missing_protected_value');
|
|
55
|
+
}
|
|
56
|
+
const includesExpiry = fields.some((field) => field.fieldKey === 'exp_month') &&
|
|
57
|
+
fields.some((field) => field.fieldKey === 'exp_year') &&
|
|
58
|
+
fields.length === 2;
|
|
59
|
+
if (includesExpiry) {
|
|
60
|
+
const month = protectedValues.exp_month;
|
|
61
|
+
const year = protectedValues.exp_year;
|
|
62
|
+
if (typeof month === 'string' &&
|
|
63
|
+
month.length > 0 &&
|
|
64
|
+
typeof year === 'string' &&
|
|
65
|
+
year.length > 0) {
|
|
66
|
+
return formatCardExpiry(month, year);
|
|
67
|
+
}
|
|
68
|
+
throw new Error('missing_protected_value');
|
|
69
|
+
}
|
|
70
|
+
throw new Error('unsupported_protected_field_group');
|
|
71
|
+
}
|
|
72
|
+
function flattenFilledFields(fieldKeys, targetRef) {
|
|
73
|
+
return fieldKeys.map((fieldKey) => ({
|
|
74
|
+
fieldKey,
|
|
75
|
+
targetRef,
|
|
76
|
+
}));
|
|
77
|
+
}
|
|
78
|
+
function buildProtectedValidationDetails(validationText) {
|
|
79
|
+
return validationText ? { validationTextRedacted: true } : {};
|
|
80
|
+
}
|
|
81
|
+
function shouldIgnoreNativeInvalidForTarget(target) {
|
|
82
|
+
return Array.isArray(target.framePath) && target.framePath.length > 0;
|
|
83
|
+
}
|
|
84
|
+
async function readValidationState(locator) {
|
|
85
|
+
const payload = await locator
|
|
86
|
+
.evaluate((element) => {
|
|
87
|
+
if (!(element instanceof HTMLElement)) {
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
const maybeControl = element instanceof HTMLInputElement ||
|
|
91
|
+
element instanceof HTMLTextAreaElement ||
|
|
92
|
+
element instanceof HTMLSelectElement
|
|
93
|
+
? element
|
|
94
|
+
: null;
|
|
95
|
+
const validationMessage = maybeControl?.validationMessage?.trim() ?? '';
|
|
96
|
+
const describedByIds = (element.getAttribute('aria-describedby') ?? '')
|
|
97
|
+
.split(/\s+/)
|
|
98
|
+
.map((value) => value.trim())
|
|
99
|
+
.filter(Boolean);
|
|
100
|
+
const describedByText = describedByIds
|
|
101
|
+
.map((id) => element.ownerDocument?.getElementById(id)?.textContent?.trim() ?? '')
|
|
102
|
+
.filter(Boolean)
|
|
103
|
+
.join(' ');
|
|
104
|
+
const ariaInvalid = element.getAttribute('aria-invalid') === 'true';
|
|
105
|
+
const candidate = validationMessage || describedByText || '';
|
|
106
|
+
return {
|
|
107
|
+
validationText: candidate || undefined,
|
|
108
|
+
ariaInvalid,
|
|
109
|
+
invalid: ariaInvalid ||
|
|
110
|
+
Boolean(maybeControl &&
|
|
111
|
+
typeof maybeControl.checkValidity === 'function' &&
|
|
112
|
+
maybeControl.checkValidity() === false),
|
|
113
|
+
};
|
|
114
|
+
})
|
|
115
|
+
.catch(() => null);
|
|
116
|
+
if (!payload) {
|
|
117
|
+
return {
|
|
118
|
+
invalid: false,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
return {
|
|
122
|
+
invalid: payload.invalid,
|
|
123
|
+
validationText: payload.validationText ||
|
|
124
|
+
(payload.ariaInvalid ? 'Field rejected by client-side validation.' : undefined),
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
function groupBindingsByTarget(fillableForm, session) {
|
|
128
|
+
const grouped = new Map();
|
|
129
|
+
for (const field of fillableForm.fields) {
|
|
130
|
+
const target = getTarget(session, field.targetRef);
|
|
131
|
+
if (!target) {
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
const existing = grouped.get(field.targetRef);
|
|
135
|
+
if (existing) {
|
|
136
|
+
existing.fields.push(field);
|
|
137
|
+
existing.fieldKeys.push(field.fieldKey);
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
grouped.set(field.targetRef, {
|
|
141
|
+
targetRef: field.targetRef,
|
|
142
|
+
fields: [field],
|
|
143
|
+
fieldKeys: [field.fieldKey],
|
|
144
|
+
target,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
return sortProtectedBindingsForExecution(fillableForm.purpose, [...grouped.values()]);
|
|
148
|
+
}
|
|
149
|
+
async function prepareBindings(session, page, fillableForm) {
|
|
150
|
+
const groupedBindings = groupBindingsByTarget(fillableForm, session);
|
|
151
|
+
if (!groupedBindings) {
|
|
152
|
+
const firstField = fillableForm.fields[0];
|
|
153
|
+
return {
|
|
154
|
+
kind: 'binding_stale',
|
|
155
|
+
targetRef: firstField?.targetRef ?? 'unknown',
|
|
156
|
+
fieldKeys: firstField ? [firstField.fieldKey] : [],
|
|
157
|
+
reason: 'target_missing',
|
|
158
|
+
attempts: [],
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
const preparedBindings = [];
|
|
162
|
+
for (const binding of groupedBindings) {
|
|
163
|
+
const attempts = [];
|
|
164
|
+
const { target } = binding;
|
|
165
|
+
if (target.lifecycle !== 'live') {
|
|
166
|
+
return {
|
|
167
|
+
kind: 'binding_stale',
|
|
168
|
+
targetRef: binding.targetRef,
|
|
169
|
+
fieldKeys: [...binding.fieldKeys],
|
|
170
|
+
reason: 'target_not_live',
|
|
171
|
+
attempts,
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
if (target.pageSignature && normalizePageSignature(page.url()) !== target.pageSignature) {
|
|
175
|
+
attempts.push('stale.page-signature:before-fill');
|
|
176
|
+
return {
|
|
177
|
+
kind: 'binding_stale',
|
|
178
|
+
targetRef: binding.targetRef,
|
|
179
|
+
fieldKeys: [...binding.fieldKeys],
|
|
180
|
+
reason: 'page_signature_mismatch',
|
|
181
|
+
attempts,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
const surface = target.surfaceRef ? getSurface(session, target.surfaceRef) : null;
|
|
185
|
+
const { baseRoot, locatorRoot, surfaceRoot } = await resolveInteractionRoots(page, target, surface, attempts);
|
|
186
|
+
let resolvedLocator = null;
|
|
187
|
+
let sawDomSignatureMismatch = false;
|
|
188
|
+
let sawBlockedTarget = false;
|
|
189
|
+
const action = actionForTarget(target);
|
|
190
|
+
const resolution = await resolvePreparedLocatorCandidates({
|
|
191
|
+
target,
|
|
192
|
+
action,
|
|
193
|
+
baseRoot,
|
|
194
|
+
locatorRoot,
|
|
195
|
+
surfaceRoot,
|
|
196
|
+
attempts,
|
|
197
|
+
prepareOptions: {
|
|
198
|
+
allowReadonlyFallback: action === 'fill' && target.controlFamily === 'datepicker',
|
|
199
|
+
},
|
|
200
|
+
onPreparedLocator: async (preparedLocator, strategy) => {
|
|
201
|
+
if (target.domSignature) {
|
|
202
|
+
const liveSignature = await readLocatorDomSignature(preparedLocator).catch(() => null);
|
|
203
|
+
if (liveSignature && liveSignature !== target.domSignature) {
|
|
204
|
+
sawDomSignatureMismatch = true;
|
|
205
|
+
attempts.push(`domSignature.mismatch:${strategy}`);
|
|
206
|
+
return false;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
resolvedLocator = preparedLocator;
|
|
210
|
+
attempts.push(`resolve:${strategy}`);
|
|
211
|
+
return true;
|
|
212
|
+
},
|
|
213
|
+
});
|
|
214
|
+
if (resolution.sawDisabledTarget || resolution.sawReadonlyTarget) {
|
|
215
|
+
sawBlockedTarget = true;
|
|
216
|
+
}
|
|
217
|
+
if (!resolvedLocator) {
|
|
218
|
+
return {
|
|
219
|
+
kind: 'binding_stale',
|
|
220
|
+
targetRef: binding.targetRef,
|
|
221
|
+
fieldKeys: [...binding.fieldKeys],
|
|
222
|
+
reason: sawDomSignatureMismatch
|
|
223
|
+
? 'dom_signature_mismatch'
|
|
224
|
+
: sawBlockedTarget
|
|
225
|
+
? 'target_blocked'
|
|
226
|
+
: 'locator_resolution_failed',
|
|
227
|
+
attempts,
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
preparedBindings.push({
|
|
231
|
+
targetRef: binding.targetRef,
|
|
232
|
+
fields: [...binding.fields],
|
|
233
|
+
fieldKeys: [...binding.fieldKeys],
|
|
234
|
+
action,
|
|
235
|
+
target,
|
|
236
|
+
root: locatorRoot,
|
|
237
|
+
locator: resolvedLocator,
|
|
238
|
+
attempts,
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
return preparedBindings;
|
|
242
|
+
}
|
|
243
|
+
function staleReasonFromError(error) {
|
|
244
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
245
|
+
if (message.includes('page_signature_mismatch')) {
|
|
246
|
+
return 'page_signature_mismatch';
|
|
247
|
+
}
|
|
248
|
+
if (message.includes('dom_signature_mismatch')) {
|
|
249
|
+
return 'dom_signature_mismatch';
|
|
250
|
+
}
|
|
251
|
+
if (message.includes('locator_resolution_failed')) {
|
|
252
|
+
return 'locator_resolution_failed';
|
|
253
|
+
}
|
|
254
|
+
return null;
|
|
255
|
+
}
|
|
256
|
+
export async function executeProtectedFill(params) {
|
|
257
|
+
const preparedBindings = await prepareBindings(params.session, params.page, params.fillableForm);
|
|
258
|
+
if (!Array.isArray(preparedBindings)) {
|
|
259
|
+
return preparedBindings;
|
|
260
|
+
}
|
|
261
|
+
let assistedValues;
|
|
262
|
+
try {
|
|
263
|
+
assistedValues = await resolveAssistedProtectedFieldValues({
|
|
264
|
+
session: params.session,
|
|
265
|
+
page: params.page,
|
|
266
|
+
bindings: preparedBindings.map((binding) => ({
|
|
267
|
+
binding: binding.fields[0],
|
|
268
|
+
target: binding.target,
|
|
269
|
+
})),
|
|
270
|
+
protectedValues: params.protectedValues,
|
|
271
|
+
fieldPolicies: params.fieldPolicies,
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
catch (error) {
|
|
275
|
+
const assistiveRuntimeMissing = error instanceof AgentbrowseAssistiveRuntimeMissingError ||
|
|
276
|
+
(error instanceof Error && error.name === 'AgentbrowseAssistiveRuntimeMissingError');
|
|
277
|
+
if (assistiveRuntimeMissing) {
|
|
278
|
+
assistedValues = new Map();
|
|
279
|
+
for (const binding of preparedBindings) {
|
|
280
|
+
for (const field of binding.fields) {
|
|
281
|
+
const deterministicValue = resolveDeterministicProtectedBindingValue(field, params.protectedValues, binding.target) ??
|
|
282
|
+
((field.valueHint ?? 'direct') === 'direct'
|
|
283
|
+
? params.protectedValues[field.fieldKey]
|
|
284
|
+
: null);
|
|
285
|
+
if (typeof deterministicValue !== 'string' || deterministicValue.trim().length === 0) {
|
|
286
|
+
continue;
|
|
287
|
+
}
|
|
288
|
+
assistedValues.set(protectedBindingKey(field), deterministicValue.trim());
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
else {
|
|
293
|
+
return {
|
|
294
|
+
kind: 'unexpected_error',
|
|
295
|
+
reason: 'assisted_value_resolution_failed',
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
const filledFields = [];
|
|
300
|
+
for (const binding of preparedBindings) {
|
|
301
|
+
let actionValue;
|
|
302
|
+
let acceptanceProbe = null;
|
|
303
|
+
let acceptanceResult = null;
|
|
304
|
+
try {
|
|
305
|
+
actionValue = resolveBindingValue(binding.fields, binding.target, params.protectedValues, params.fieldPolicies, assistedValues);
|
|
306
|
+
}
|
|
307
|
+
catch (error) {
|
|
308
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
309
|
+
if (message === 'missing_protected_value') {
|
|
310
|
+
return {
|
|
311
|
+
kind: 'unexpected_error',
|
|
312
|
+
reason: 'missing_protected_value',
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
if (message === 'deterministic_only_resolution_failed') {
|
|
316
|
+
return {
|
|
317
|
+
kind: 'unexpected_error',
|
|
318
|
+
reason: 'deterministic_only_resolution_failed',
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
if (message === 'assisted_value_resolution_failed') {
|
|
322
|
+
return {
|
|
323
|
+
kind: 'unexpected_error',
|
|
324
|
+
reason: 'assisted_value_resolution_failed',
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
return {
|
|
328
|
+
kind: 'unexpected_error',
|
|
329
|
+
reason: 'unsupported_protected_field_group',
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
try {
|
|
333
|
+
acceptanceProbe = await createAcceptanceProbe({
|
|
334
|
+
session: params.session,
|
|
335
|
+
page: params.page,
|
|
336
|
+
target: binding.target,
|
|
337
|
+
action: binding.action,
|
|
338
|
+
actionValue,
|
|
339
|
+
locator: binding.locator,
|
|
340
|
+
beforePageObservation: null,
|
|
341
|
+
});
|
|
342
|
+
await applyActionWithFallbacks(params.page, binding.root, binding.locator, binding.action, actionValue, binding.attempts, binding.target.controlFamily, {
|
|
343
|
+
guards: {
|
|
344
|
+
assertStillValid: async (stage) => {
|
|
345
|
+
await assertStoredBindingStillValid(params.page, binding.locator, binding.target, stage, {
|
|
346
|
+
errorForReason: (reason, validationStage) => `binding_stale:${reason}:${validationStage}`,
|
|
347
|
+
});
|
|
348
|
+
},
|
|
349
|
+
},
|
|
350
|
+
});
|
|
351
|
+
if (acceptanceProbe) {
|
|
352
|
+
acceptanceResult = await waitForAcceptanceProbe(acceptanceProbe);
|
|
353
|
+
const acceptance = acceptanceResult;
|
|
354
|
+
if (!acceptance.accepted) {
|
|
355
|
+
const validationState = await readValidationState(acceptanceProbe.readLocator);
|
|
356
|
+
return {
|
|
357
|
+
kind: 'validation_failed',
|
|
358
|
+
filledFields,
|
|
359
|
+
fieldErrors: binding.fieldKeys.map((fieldKey) => ({
|
|
360
|
+
fieldKey,
|
|
361
|
+
targetRef: binding.targetRef,
|
|
362
|
+
reason: validationState.validationText
|
|
363
|
+
? 'client_validation_rejected'
|
|
364
|
+
: 'value_not_applied',
|
|
365
|
+
...buildProtectedValidationDetails(validationState.validationText),
|
|
366
|
+
})),
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
const validationState = await readValidationState(acceptanceProbe.readLocator);
|
|
370
|
+
if (validationState.invalid && !shouldIgnoreNativeInvalidForTarget(binding.target)) {
|
|
371
|
+
return {
|
|
372
|
+
kind: 'validation_failed',
|
|
373
|
+
filledFields,
|
|
374
|
+
fieldErrors: binding.fieldKeys.map((fieldKey) => ({
|
|
375
|
+
fieldKey,
|
|
376
|
+
targetRef: binding.targetRef,
|
|
377
|
+
reason: 'client_validation_rejected',
|
|
378
|
+
...buildProtectedValidationDetails(validationState.validationText),
|
|
379
|
+
})),
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
filledFields.push(...flattenFilledFields(binding.fieldKeys, binding.targetRef));
|
|
384
|
+
}
|
|
385
|
+
catch (error) {
|
|
386
|
+
if (acceptanceProbe) {
|
|
387
|
+
acceptanceResult =
|
|
388
|
+
acceptanceResult ?? (await waitForAcceptanceProbe(acceptanceProbe).catch(() => null));
|
|
389
|
+
if (acceptanceResult?.accepted) {
|
|
390
|
+
const validationState = await readValidationState(acceptanceProbe.readLocator);
|
|
391
|
+
if (validationState.invalid && !shouldIgnoreNativeInvalidForTarget(binding.target)) {
|
|
392
|
+
return {
|
|
393
|
+
kind: 'validation_failed',
|
|
394
|
+
filledFields,
|
|
395
|
+
fieldErrors: binding.fieldKeys.map((fieldKey) => ({
|
|
396
|
+
fieldKey,
|
|
397
|
+
targetRef: binding.targetRef,
|
|
398
|
+
reason: 'client_validation_rejected',
|
|
399
|
+
...buildProtectedValidationDetails(validationState.validationText),
|
|
400
|
+
})),
|
|
401
|
+
};
|
|
402
|
+
}
|
|
403
|
+
filledFields.push(...flattenFilledFields(binding.fieldKeys, binding.targetRef));
|
|
404
|
+
continue;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
const staleReason = staleReasonFromError(error);
|
|
408
|
+
if (staleReason) {
|
|
409
|
+
return {
|
|
410
|
+
kind: 'binding_stale',
|
|
411
|
+
targetRef: binding.targetRef,
|
|
412
|
+
fieldKeys: [...binding.fieldKeys],
|
|
413
|
+
reason: staleReason,
|
|
414
|
+
attempts: [...binding.attempts],
|
|
415
|
+
};
|
|
416
|
+
}
|
|
417
|
+
return {
|
|
418
|
+
kind: 'unexpected_error',
|
|
419
|
+
reason: 'action_failed',
|
|
420
|
+
};
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
return {
|
|
424
|
+
kind: 'success',
|
|
425
|
+
filledFields,
|
|
426
|
+
};
|
|
427
|
+
}
|
|
428
|
+
export const __testProtectedFill = {
|
|
429
|
+
actionForTarget,
|
|
430
|
+
formatCardExpiry,
|
|
431
|
+
resolveBindingValue: (fieldKeys, protectedValues, target) => resolveBindingValue(fieldKeys.map((fieldKey) => ({
|
|
432
|
+
fieldKey,
|
|
433
|
+
targetRef: 't_test',
|
|
434
|
+
valueHint: 'direct',
|
|
435
|
+
})), target ??
|
|
436
|
+
{
|
|
437
|
+
ref: 't_test',
|
|
438
|
+
pageRef: 'p0',
|
|
439
|
+
capability: 'actionable',
|
|
440
|
+
lifecycle: 'live',
|
|
441
|
+
availability: { state: 'available' },
|
|
442
|
+
allowedActions: ['fill'],
|
|
443
|
+
locatorCandidates: [],
|
|
444
|
+
createdAt: 0,
|
|
445
|
+
}, protectedValues, undefined, new Map()),
|
|
446
|
+
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { TargetDescriptor } from '../runtime-state.js';
|
|
2
|
+
import type { FillableFormFieldBinding } from './types.js';
|
|
3
|
+
export declare function resolveDeterministicProtectedBindingValue(binding: Pick<FillableFormFieldBinding, 'fieldKey' | 'valueHint'>, protectedValues: Record<string, string>, target?: Pick<TargetDescriptor, 'label' | 'displayLabel' | 'context'>): string | null;
|
|
4
|
+
//# sourceMappingURL=protected-value-adapters.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protected-value-adapters.d.ts","sourceRoot":"","sources":["../../src/secrets/protected-value-adapters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,KAAK,EAAE,wBAAwB,EAAwB,MAAM,YAAY,CAAC;AAwFjF,wBAAgB,yCAAyC,CACvD,OAAO,EAAE,IAAI,CAAC,wBAAwB,EAAE,UAAU,GAAG,WAAW,CAAC,EACjE,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACvC,MAAM,CAAC,EAAE,IAAI,CAAC,gBAAgB,EAAE,OAAO,GAAG,cAAc,GAAG,SAAS,CAAC,GACpE,MAAM,GAAG,IAAI,CAqEf"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
function normalizeWhitespace(value) {
|
|
2
|
+
return value.replace(/\s+/g, ' ').trim();
|
|
3
|
+
}
|
|
4
|
+
function splitFullName(value) {
|
|
5
|
+
return normalizeWhitespace(value)
|
|
6
|
+
.split(' ')
|
|
7
|
+
.map((part) => part.trim())
|
|
8
|
+
.filter(Boolean);
|
|
9
|
+
}
|
|
10
|
+
function directStoredValue(protectedValues, fieldKey) {
|
|
11
|
+
const value = protectedValues[fieldKey];
|
|
12
|
+
return typeof value === 'string' && value.trim().length > 0 ? value : null;
|
|
13
|
+
}
|
|
14
|
+
function parseIsoDate(value) {
|
|
15
|
+
const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(value.trim());
|
|
16
|
+
if (!match) {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
const year = match[1];
|
|
20
|
+
const month = match[2];
|
|
21
|
+
const day = match[3];
|
|
22
|
+
if (!year || !month || !day) {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
return { year, month, day };
|
|
26
|
+
}
|
|
27
|
+
function monthName(month) {
|
|
28
|
+
const names = [
|
|
29
|
+
'January',
|
|
30
|
+
'February',
|
|
31
|
+
'March',
|
|
32
|
+
'April',
|
|
33
|
+
'May',
|
|
34
|
+
'June',
|
|
35
|
+
'July',
|
|
36
|
+
'August',
|
|
37
|
+
'September',
|
|
38
|
+
'October',
|
|
39
|
+
'November',
|
|
40
|
+
'December',
|
|
41
|
+
];
|
|
42
|
+
return names[Number(month) - 1] ?? month;
|
|
43
|
+
}
|
|
44
|
+
function monthShortName(month) {
|
|
45
|
+
return monthName(month).slice(0, 3);
|
|
46
|
+
}
|
|
47
|
+
function monthProjectionStyle(target) {
|
|
48
|
+
const context = [target?.label, target?.displayLabel, target?.context?.hintText]
|
|
49
|
+
.filter(Boolean)
|
|
50
|
+
.join(' ')
|
|
51
|
+
.replace(/\s+/g, ' ')
|
|
52
|
+
.trim()
|
|
53
|
+
.toLowerCase();
|
|
54
|
+
if (/\bjanuary\b|\bfebruary\b|\bmarch\b|\bapril\b|\bmay\b|\bjune\b|\bjuly\b|\baugust\b|\bseptember\b|\boctober\b|\bnovember\b|\bdecember\b/.test(context)) {
|
|
55
|
+
return 'name';
|
|
56
|
+
}
|
|
57
|
+
if (/\bjan\b|\bfeb\b|\bmar\b|\bapr\b|\bjun\b|\bjul\b|\baug\b|\bsep\b|\boct\b|\bnov\b|\bdec\b/.test(context)) {
|
|
58
|
+
return 'short';
|
|
59
|
+
}
|
|
60
|
+
return 'numeric';
|
|
61
|
+
}
|
|
62
|
+
export function resolveDeterministicProtectedBindingValue(binding, protectedValues, target) {
|
|
63
|
+
if (binding.fieldKey === 'date_of_birth') {
|
|
64
|
+
const dateOfBirth = directStoredValue(protectedValues, 'date_of_birth');
|
|
65
|
+
if (!dateOfBirth) {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
const valueHint = binding.valueHint ?? 'direct';
|
|
69
|
+
if (valueHint === 'direct') {
|
|
70
|
+
return dateOfBirth;
|
|
71
|
+
}
|
|
72
|
+
const parsed = parseIsoDate(dateOfBirth);
|
|
73
|
+
if (!parsed) {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
if (valueHint === 'date_of_birth.day') {
|
|
77
|
+
return String(Number(parsed.day));
|
|
78
|
+
}
|
|
79
|
+
if (valueHint === 'date_of_birth.year') {
|
|
80
|
+
return parsed.year;
|
|
81
|
+
}
|
|
82
|
+
if (valueHint === 'date_of_birth.month') {
|
|
83
|
+
const style = monthProjectionStyle(target);
|
|
84
|
+
if (style === 'name') {
|
|
85
|
+
return monthName(parsed.month);
|
|
86
|
+
}
|
|
87
|
+
if (style === 'short') {
|
|
88
|
+
return monthShortName(parsed.month);
|
|
89
|
+
}
|
|
90
|
+
return parsed.month;
|
|
91
|
+
}
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
if (binding.fieldKey !== 'full_name') {
|
|
95
|
+
return binding.valueHint === 'direct'
|
|
96
|
+
? directStoredValue(protectedValues, binding.fieldKey)
|
|
97
|
+
: null;
|
|
98
|
+
}
|
|
99
|
+
const fullName = directStoredValue(protectedValues, 'full_name');
|
|
100
|
+
if (!fullName) {
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
const valueHint = binding.valueHint ?? 'direct';
|
|
104
|
+
if (valueHint === 'direct') {
|
|
105
|
+
return fullName;
|
|
106
|
+
}
|
|
107
|
+
const parts = splitFullName(fullName);
|
|
108
|
+
if (parts.length === 0) {
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
if (valueHint === 'full_name.given') {
|
|
112
|
+
return parts[0] ?? fullName;
|
|
113
|
+
}
|
|
114
|
+
if (valueHint === 'full_name.family') {
|
|
115
|
+
return parts.length > 1 ? (parts.at(-1) ?? fullName) : fullName;
|
|
116
|
+
}
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
export declare const LOGIN_FIELD_KEYS: readonly ["username", "password"];
|
|
2
|
+
export declare const IDENTITY_FIELD_KEYS: readonly ["full_name", "document_number", "date_of_birth", "nationality", "issue_date", "expiry_date", "issuing_country"];
|
|
3
|
+
export declare const PAYMENT_CARD_FIELD_KEYS: readonly ["cardholder", "pan", "exp_month", "exp_year", "cvv"];
|
|
4
|
+
export type StoredSecretKind = 'login' | 'identity' | 'payment_card';
|
|
5
|
+
export declare const STORED_SECRET_FIELD_KEYS_BY_KIND: {
|
|
6
|
+
readonly login: readonly ["username", "password"];
|
|
7
|
+
readonly identity: readonly ["full_name", "document_number", "date_of_birth", "nationality", "issue_date", "expiry_date", "issuing_country"];
|
|
8
|
+
readonly payment_card: readonly ["cardholder", "pan", "exp_month", "exp_year", "cvv"];
|
|
9
|
+
};
|
|
10
|
+
export type LoginFieldKey = (typeof LOGIN_FIELD_KEYS)[number];
|
|
11
|
+
export type IdentityFieldKey = (typeof IDENTITY_FIELD_KEYS)[number];
|
|
12
|
+
export type PaymentCardFieldKey = (typeof PAYMENT_CARD_FIELD_KEYS)[number];
|
|
13
|
+
export type StoredSecretFieldKey = LoginFieldKey | IdentityFieldKey | PaymentCardFieldKey;
|
|
14
|
+
export type StoredSecretScope = 'site' | 'global';
|
|
15
|
+
export type ProtectedFieldPolicy = 'deterministic_only' | 'llm_assisted';
|
|
16
|
+
export declare const PROTECTED_BINDING_VALUE_HINTS: readonly ["direct", "full_name.given", "full_name.family", "date_of_birth.day", "date_of_birth.month", "date_of_birth.year"];
|
|
17
|
+
export type ProtectedBindingValueHint = (typeof PROTECTED_BINDING_VALUE_HINTS)[number];
|
|
18
|
+
export type StoredSecretApplicabilityTarget = 'host' | 'site' | 'global';
|
|
19
|
+
export interface StoredSecretApplicability {
|
|
20
|
+
target: StoredSecretApplicabilityTarget;
|
|
21
|
+
value?: string;
|
|
22
|
+
}
|
|
23
|
+
export type StoredSecretFieldPolicies = Partial<Record<StoredSecretFieldKey, ProtectedFieldPolicy>>;
|
|
24
|
+
export interface StoredSecretMetadata {
|
|
25
|
+
storedSecretRef: string;
|
|
26
|
+
kind: StoredSecretKind;
|
|
27
|
+
scope: StoredSecretScope;
|
|
28
|
+
displayName: string;
|
|
29
|
+
fieldKeys: StoredSecretFieldKey[];
|
|
30
|
+
fieldPolicies?: StoredSecretFieldPolicies;
|
|
31
|
+
intentRequired: boolean;
|
|
32
|
+
applicability: StoredSecretApplicability;
|
|
33
|
+
preferredForMerchantKeys?: string[];
|
|
34
|
+
}
|
|
35
|
+
export interface SecretCatalogSnapshot {
|
|
36
|
+
source: 'mock' | 'remote_api';
|
|
37
|
+
host: string;
|
|
38
|
+
syncedAt: string;
|
|
39
|
+
storedSecrets: StoredSecretMetadata[];
|
|
40
|
+
}
|
|
41
|
+
export interface FillableFormFieldBinding {
|
|
42
|
+
fieldKey: StoredSecretFieldKey;
|
|
43
|
+
targetRef: string;
|
|
44
|
+
label?: string;
|
|
45
|
+
required?: boolean;
|
|
46
|
+
valueHint?: ProtectedBindingValueHint;
|
|
47
|
+
}
|
|
48
|
+
export interface FillableFormStoredSecretCandidate {
|
|
49
|
+
storedSecretRef: string;
|
|
50
|
+
kind: StoredSecretKind;
|
|
51
|
+
scope: StoredSecretScope;
|
|
52
|
+
displayName: string;
|
|
53
|
+
matchConfidence: 'high' | 'medium' | 'low';
|
|
54
|
+
intentRequired: boolean;
|
|
55
|
+
fieldKeys?: StoredSecretFieldKey[];
|
|
56
|
+
fieldPolicies?: StoredSecretFieldPolicies;
|
|
57
|
+
}
|
|
58
|
+
export type FillableFormPresence = 'present' | 'unknown' | 'absent';
|
|
59
|
+
export interface PersistedFillableForm {
|
|
60
|
+
fillRef: string;
|
|
61
|
+
pageRef: string;
|
|
62
|
+
scopeRef?: string;
|
|
63
|
+
purpose: string;
|
|
64
|
+
presence?: FillableFormPresence;
|
|
65
|
+
scopeEpoch?: number;
|
|
66
|
+
fields: FillableFormFieldBinding[];
|
|
67
|
+
storedSecretCandidates: FillableFormStoredSecretCandidate[];
|
|
68
|
+
observedAt: string;
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/secrets/types.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,mCAAoC,CAAC;AAClE,eAAO,MAAM,mBAAmB,2HAQtB,CAAC;AACX,eAAO,MAAM,uBAAuB,gEAM1B,CAAC;AAEX,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,UAAU,GAAG,cAAc,CAAC;AAErE,eAAO,MAAM,gCAAgC;;;;CAInC,CAAC;AAEX,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAC9D,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AACpE,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,uBAAuB,CAAC,CAAC,MAAM,CAAC,CAAC;AAC3E,MAAM,MAAM,oBAAoB,GAAG,aAAa,GAAG,gBAAgB,GAAG,mBAAmB,CAAC;AAE1F,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,QAAQ,CAAC;AAClD,MAAM,MAAM,oBAAoB,GAAG,oBAAoB,GAAG,cAAc,CAAC;AACzE,eAAO,MAAM,6BAA6B,8HAOhC,CAAC;AACX,MAAM,MAAM,yBAAyB,GAAG,CAAC,OAAO,6BAA6B,CAAC,CAAC,MAAM,CAAC,CAAC;AAEvF,MAAM,MAAM,+BAA+B,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEzE,MAAM,WAAW,yBAAyB;IACxC,MAAM,EAAE,+BAA+B,CAAC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,yBAAyB,GAAG,OAAO,CAAC,MAAM,CAAC,oBAAoB,EAAE,oBAAoB,CAAC,CAAC,CAAC;AAEpG,MAAM,WAAW,oBAAoB;IACnC,eAAe,EAAE,MAAM,CAAC;IACxB,IAAI,EAAE,gBAAgB,CAAC;IACvB,KAAK,EAAE,iBAAiB,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,oBAAoB,EAAE,CAAC;IAClC,aAAa,CAAC,EAAE,yBAAyB,CAAC;IAC1C,cAAc,EAAE,OAAO,CAAC;IACxB,aAAa,EAAE,yBAAyB,CAAC;IACzC,wBAAwB,CAAC,EAAE,MAAM,EAAE,CAAC;CACrC;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,GAAG,YAAY,CAAC;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,oBAAoB,EAAE,CAAC;CACvC;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,yBAAyB,CAAC;CACvC;AAED,MAAM,WAAW,iCAAiC;IAChD,eAAe,EAAE,MAAM,CAAC;IACxB,IAAI,EAAE,gBAAgB,CAAC;IACvB,KAAK,EAAE,iBAAiB,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IAC3C,cAAc,EAAE,OAAO,CAAC;IACxB,SAAS,CAAC,EAAE,oBAAoB,EAAE,CAAC;IACnC,aAAa,CAAC,EAAE,yBAAyB,CAAC;CAC3C;AAED,MAAM,MAAM,oBAAoB,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEpE,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,oBAAoB,CAAC;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,wBAAwB,EAAE,CAAC;IACnC,sBAAsB,EAAE,iCAAiC,EAAE,CAAC;IAC5D,UAAU,EAAE,MAAM,CAAC;CACpB"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export const LOGIN_FIELD_KEYS = ['username', 'password'];
|
|
2
|
+
export const IDENTITY_FIELD_KEYS = [
|
|
3
|
+
'full_name',
|
|
4
|
+
'document_number',
|
|
5
|
+
'date_of_birth',
|
|
6
|
+
'nationality',
|
|
7
|
+
'issue_date',
|
|
8
|
+
'expiry_date',
|
|
9
|
+
'issuing_country',
|
|
10
|
+
];
|
|
11
|
+
export const PAYMENT_CARD_FIELD_KEYS = [
|
|
12
|
+
'cardholder',
|
|
13
|
+
'pan',
|
|
14
|
+
'exp_month',
|
|
15
|
+
'exp_year',
|
|
16
|
+
'cvv',
|
|
17
|
+
];
|
|
18
|
+
export const STORED_SECRET_FIELD_KEYS_BY_KIND = {
|
|
19
|
+
login: LOGIN_FIELD_KEYS,
|
|
20
|
+
identity: IDENTITY_FIELD_KEYS,
|
|
21
|
+
payment_card: PAYMENT_CARD_FIELD_KEYS,
|
|
22
|
+
};
|
|
23
|
+
export const PROTECTED_BINDING_VALUE_HINTS = [
|
|
24
|
+
'direct',
|
|
25
|
+
'full_name.given',
|
|
26
|
+
'full_name.family',
|
|
27
|
+
'date_of_birth.day',
|
|
28
|
+
'date_of_birth.month',
|
|
29
|
+
'date_of_birth.year',
|
|
30
|
+
];
|