@apoa/core 0.2.1 → 0.2.3
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/README.md +53 -24
- package/dist/index.cjs +144 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +51 -1
- package/dist/index.d.ts +51 -1
- package/dist/index.js +143 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/errors.ts","../src/utils/crypto.ts","../src/utils/time.ts","../src/scope/patterns.ts","../src/revocation/store.ts","../src/audit/store.ts","../src/scope/check.ts","../src/token/parse.ts","../src/revocation/revoke.ts","../src/audit/log.ts","../src/audit/trail.ts","../src/token/sign.ts","../src/token/create.ts","../src/token/validate.ts","../src/revocation/cascade.ts","../src/scope/attenuate.ts","../src/delegation/chain.ts","../src/delegation/verify.ts","../src/delegation/ancestors.ts","../src/jwks/index.ts","../src/client.ts"],"sourcesContent":["/** Base error class for all APOA errors. */\nexport class APOAError extends Error {\n code: string;\n\n constructor(message: string, code: string) {\n super(message);\n this.code = code;\n this.name = 'APOAError';\n }\n}\n\n/** Thrown when a token has expired. */\nexport class TokenExpiredError extends APOAError {\n expiredAt: Date;\n\n constructor(message: string, expiredAt: Date) {\n super(message, 'TOKEN_EXPIRED');\n this.expiredAt = expiredAt;\n this.name = 'TokenExpiredError';\n }\n}\n\n/** Thrown when an action is outside the token's authorized scopes. */\nexport class ScopeViolationError extends APOAError {\n requestedScope: string;\n availableScopes: string[];\n\n constructor(message: string, requestedScope: string, availableScopes: string[]) {\n super(message, 'SCOPE_VIOLATION');\n this.requestedScope = requestedScope;\n this.availableScopes = availableScopes;\n this.name = 'ScopeViolationError';\n }\n}\n\n/** Thrown when a delegated token tries to exceed parent permissions. */\nexport class AttenuationViolationError extends APOAError {\n parentScope: string[];\n requestedScope: string[];\n\n constructor(message: string, parentScope: string[], requestedScope: string[]) {\n super(message, 'ATTENUATION_VIOLATION');\n this.parentScope = parentScope;\n this.requestedScope = requestedScope;\n this.name = 'AttenuationViolationError';\n }\n}\n\n/** Thrown when trying to use a revoked token. */\nexport class RevocationError extends APOAError {\n revokedAt: Date;\n revokedBy: string;\n\n constructor(message: string, revokedAt: Date, revokedBy: string) {\n super(message, 'TOKEN_REVOKED');\n this.revokedAt = revokedAt;\n this.revokedBy = revokedBy;\n this.name = 'RevocationError';\n }\n}\n\n/** Thrown when delegation chain verification fails. */\nexport class ChainVerificationError extends APOAError {\n failedAt: number;\n reason: string;\n\n constructor(message: string, failedAt: number, reason: string) {\n super(message, 'CHAIN_INVALID');\n this.failedAt = failedAt;\n this.reason = reason;\n this.name = 'ChainVerificationError';\n }\n}\n\n/** Thrown when token metadata fails validation. */\nexport class MetadataValidationError extends APOAError {\n field?: string;\n\n constructor(message: string, field?: string) {\n super(message, 'METADATA_INVALID');\n this.field = field;\n this.name = 'MetadataValidationError';\n }\n}\n\n/** Thrown when a hard rule is violated. */\nexport class RuleEnforcementError extends APOAError {\n ruleId: string;\n enforcement: 'hard' = 'hard' as const;\n\n constructor(message: string, ruleId: string) {\n super(message, 'RULE_VIOLATED');\n this.ruleId = ruleId;\n this.name = 'RuleEnforcementError';\n }\n}\n\n/** Thrown when a definition fails validation. */\nexport class DefinitionValidationError extends APOAError {\n errors: string[];\n\n constructor(message: string, errors: string[]) {\n super(message, 'DEFINITION_INVALID');\n this.errors = errors;\n this.name = 'DefinitionValidationError';\n }\n}\n","import * as jose from 'jose';\nimport type { SigningOptions } from '../types.js';\n\n/**\n * Generate an Ed25519 or ES256 key pair for signing and verifying tokens.\n */\nexport async function generateKeyPair(\n algorithm: 'EdDSA' | 'ES256' = 'EdDSA'\n): Promise<CryptoKeyPair> {\n const alg = algorithm === 'EdDSA' ? 'EdDSA' : 'ES256';\n const { publicKey, privateKey } = await jose.generateKeyPair(alg, {\n extractable: true,\n });\n return { publicKey, privateKey } as CryptoKeyPair;\n}\n\n/**\n * Sign a payload, producing a compact JWS string.\n */\nexport async function sign(\n payload: Record<string, unknown>,\n options: SigningOptions\n): Promise<string> {\n const alg = options.algorithm === 'ES256' ? 'ES256' : 'EdDSA';\n const header: Record<string, unknown> = { alg };\n if (options.kid) {\n header.kid = options.kid;\n }\n\n const jws = await new jose.CompactSign(\n new TextEncoder().encode(JSON.stringify(payload))\n )\n .setProtectedHeader(header as jose.CompactJWSHeaderParameters)\n .sign(options.privateKey);\n\n return jws;\n}\n\n/**\n * Verify a compact JWS string and return the decoded payload.\n */\nexport async function verify(\n token: string,\n key: CryptoKey\n): Promise<Record<string, unknown>> {\n const { payload } = await jose.compactVerify(token, key);\n return JSON.parse(new TextDecoder().decode(payload));\n}\n","const DEFAULT_CLOCK_SKEW = 30;\nconst MAX_CLOCK_SKEW = 300;\n\n/**\n * Normalize clock skew to a valid value in seconds.\n */\nfunction normalizeSkew(clockSkew?: number): number {\n if (clockSkew === undefined) return DEFAULT_CLOCK_SKEW;\n if (clockSkew < 0) return 0;\n return Math.min(clockSkew, MAX_CLOCK_SKEW);\n}\n\n/**\n * Parse a date value (Date object or ISO string) into a Date.\n */\nfunction toDate(value: Date | string): Date {\n return value instanceof Date ? value : new Date(value);\n}\n\n/**\n * Check if a token/date has expired, accounting for clock skew.\n * Returns true if the current time is past the expiration (plus tolerance).\n */\nexport function isExpired(\n expires: Date | string,\n clockSkew?: number,\n now?: Date\n): boolean {\n const expiresDate = toDate(expires);\n const skew = normalizeSkew(clockSkew);\n const currentTime = now ?? new Date();\n return currentTime.getTime() > expiresDate.getTime() + skew * 1000;\n}\n\n/**\n * Check if the current time is before the notBefore date, accounting for clock skew.\n * Returns true if it's too early to use this token.\n */\nexport function isBeforeNotBefore(\n notBefore: Date | string,\n clockSkew?: number,\n now?: Date\n): boolean {\n const notBeforeDate = toDate(notBefore);\n const skew = normalizeSkew(clockSkew);\n const currentTime = now ?? new Date();\n return currentTime.getTime() < notBeforeDate.getTime() - skew * 1000;\n}\n","/**\n * Parse a scope string into its segments.\n * e.g., \"appointments:read\" → [\"appointments\", \"read\"]\n */\nexport function parseScope(scope: string): string[] {\n if (!scope) return [];\n return scope.split(':');\n}\n\n/**\n * Check if a scope pattern matches a requested scope.\n *\n * Rules:\n * 1. Empty pattern or empty requested string never matches (a vacuous match\n * on `''` would let a token with `scopes: ['']` authorize an empty\n * action, or vice versa).\n * 2. Root wildcard \"*\" matches everything (non-empty)\n * 3. Exact match: \"appointments:read\" matches \"appointments:read\"\n * 4. Wildcard at level: \"appointments:*\" matches \"appointments:read\"\n * but NOT \"appointments:read:summary\" (wildcards don't cross levels)\n * 5. Segment-by-segment matching with wildcard support at each level\n */\nexport function matchScope(pattern: string, requested: string): boolean {\n if (!pattern || !requested) return false;\n\n // Root wildcard matches everything (non-empty, handled above).\n if (pattern === '*') return true;\n\n const patternParts = parseScope(pattern);\n const requestedParts = parseScope(requested);\n\n // Different number of segments — no match (wildcards don't cross levels)\n if (patternParts.length !== requestedParts.length) return false;\n\n // Match segment by segment. Empty segments (e.g. \"foo::bar\") never match.\n for (let i = 0; i < patternParts.length; i++) {\n if (patternParts[i] === '*') continue;\n if (!patternParts[i] || !requestedParts[i]) return false;\n if (patternParts[i] !== requestedParts[i]) return false;\n }\n\n return true;\n}\n","import type { RevocationRecord, RevocationStore } from '../types.js';\n\n/**\n * In-memory revocation store for dev/testing.\n * Data is lost when the process exits.\n */\nexport class MemoryRevocationStore implements RevocationStore {\n private records: Map<string, RevocationRecord> = new Map();\n\n async add(record: RevocationRecord): Promise<void> {\n this.records.set(record.tokenId, record);\n }\n\n async check(tokenId: string): Promise<RevocationRecord | null> {\n return this.records.get(tokenId) ?? null;\n }\n\n async list(principalId: string): Promise<RevocationRecord[]> {\n const results: RevocationRecord[] = [];\n for (const record of this.records.values()) {\n if (record.revokedBy === principalId) {\n results.push(record);\n }\n }\n return results;\n }\n}\n","import type { AuditEntry, AuditQueryOptions, AuditStore } from '../types.js';\n\n/**\n * In-memory audit store for dev/testing.\n * Data is lost when the process exits.\n */\nexport class MemoryAuditStore implements AuditStore {\n private entries: AuditEntry[] = [];\n\n async append(entry: AuditEntry): Promise<void> {\n this.entries.push(entry);\n }\n\n async query(tokenId: string, options?: AuditQueryOptions): Promise<AuditEntry[]> {\n const results = this.entries.filter((e) => e.tokenId === tokenId);\n return applyFilters(results, options);\n }\n\n async queryByService(\n service: string,\n options?: AuditQueryOptions\n ): Promise<AuditEntry[]> {\n const results = this.entries.filter((e) => e.service === service);\n return applyFilters(results, options);\n }\n}\n\nfunction applyFilters(\n entries: AuditEntry[],\n options?: AuditQueryOptions\n): AuditEntry[] {\n\n let results = entries;\n\n if (options?.from) {\n const from = options.from.getTime();\n results = results.filter((e) => e.timestamp.getTime() >= from);\n }\n if (options?.to) {\n const to = options.to.getTime();\n results = results.filter((e) => e.timestamp.getTime() <= to);\n }\n if (options?.action) {\n results = results.filter((e) => e.action === options.action);\n }\n if (options?.service) {\n results = results.filter((e) => e.service === options.service);\n }\n if (options?.result) {\n results = results.filter((e) => e.result === options.result);\n }\n\n const offset = options?.offset ?? 0;\n const limit = options?.limit ?? 100;\n results = results.slice(offset, offset + limit);\n\n return results;\n}\n","import type {\n APOAToken,\n AuthorizeOptions,\n AuthorizationResult,\n RuleViolation,\n ScopeCheckResult,\n} from '../types.js';\nimport { matchScope } from './patterns.js';\n\n/**\n * Check if an action is allowed under a token's scopes for a given service.\n * Synchronous — no rules, no revocation, just scope matching.\n */\nexport function checkScope(\n token: APOAToken,\n service: string,\n action: string\n): ScopeCheckResult {\n const serviceAuth = token.definition.services.find(\n (s) => s.service === service\n );\n\n if (!serviceAuth) {\n return {\n allowed: false,\n reason: `service '${service}' not found in token`,\n };\n }\n\n for (const scope of serviceAuth.scopes) {\n if (matchScope(scope, action)) {\n return {\n allowed: true,\n reason: `matched scope '${scope}'`,\n matchedScope: scope,\n };\n }\n }\n\n return {\n allowed: false,\n reason: `scope '${action}' not in authorized scopes`,\n };\n}\n\n/**\n * Check a specific constraint on a service.\n * Returns allowed: false if the constraint is explicitly set to false.\n * Returns allowed: true if the constraint is not set or is truthy.\n */\nexport function checkConstraint(\n token: APOAToken,\n service: string,\n constraint: string\n): ScopeCheckResult {\n const serviceAuth = token.definition.services.find(\n (s) => s.service === service\n );\n\n if (!serviceAuth) {\n return {\n allowed: false,\n reason: `service '${service}' not found in token`,\n };\n }\n\n if (!serviceAuth.constraints) {\n return {\n allowed: true,\n reason: `no constraints defined for service '${service}'`,\n };\n }\n\n const value = serviceAuth.constraints[constraint];\n\n if (value === undefined) {\n return {\n allowed: true,\n reason: `constraint '${constraint}' not defined`,\n };\n }\n\n if (value === false) {\n return {\n allowed: false,\n reason: `constraint '${constraint}' is set to false`,\n constraint,\n };\n }\n\n return {\n allowed: true,\n reason: `constraint '${constraint}' is set to ${JSON.stringify(value)}`,\n };\n}\n\n/**\n * One-stop authorization check: revocation + scope + constraints + rules.\n *\n * Enforcement order:\n * 1. Check revocation (is the token still alive?)\n * 2. Check scope (is the action in the authorized scope set?)\n * 3. Check constraints (only the action's top-level segment is checked\n * against constraint keys — e.g. action \"signing:submit\" checks\n * constraint \"signing\". Use checkConstraint() for explicit checks.)\n * 4. Check hard rules (hard rules whose id appears as a prefix of the\n * action → deny. e.g. rule \"no-messaging\" blocks \"messaging:send\")\n * 5. Check soft rules (all soft rules → log violation + continue)\n */\nexport async function authorize(\n token: APOAToken,\n service: string,\n action: string,\n options?: AuthorizeOptions\n): Promise<AuthorizationResult> {\n // 1. Check revocation\n if (options?.revocationStore) {\n const record = await options.revocationStore.check(token.jti);\n if (record) {\n return {\n authorized: false,\n reason: 'token has been revoked',\n checks: { revoked: true },\n };\n }\n }\n\n // 2. Check scope\n const scopeResult = checkScope(token, service, action);\n if (!scopeResult.allowed) {\n return {\n authorized: false,\n reason: scopeResult.reason,\n checks: { revoked: false, scopeAllowed: false },\n };\n }\n\n // 3. Check constraints — only deny if the action's top-level segment\n // matches a constraint key that is set to false.\n // e.g. action \"signing:submit\" is blocked by constraint { signing: false }\n // but action \"appointments:read\" is NOT blocked by { signing: false }\n const serviceAuth = token.definition.services.find(\n (s) => s.service === service\n );\n if (serviceAuth?.constraints) {\n const actionSegments = action.split(':');\n for (const [key, value] of Object.entries(serviceAuth.constraints)) {\n if (value === false && actionSegments.includes(key)) {\n return {\n authorized: false,\n reason: `constraint '${key}' is set to false`,\n checks: { revoked: false, scopeAllowed: true, constraintsPassed: false },\n };\n }\n }\n }\n\n // 4 & 5. Check rules\n const rules = token.definition.rules;\n const violations: RuleViolation[] = [];\n\n if (rules && rules.length > 0) {\n // 4. Hard rules — deny if the action matches the rule.\n // Matching: extract the key from the rule id (strip \"no-\" prefix if present)\n // and check if it appears as a SEGMENT in the action (split on ':').\n // e.g. rule \"no-messaging\" → key \"messaging\" → blocks \"messaging:send\"\n // e.g. rule \"no-signing\" → key \"signing\" → blocks \"signing:submit\"\n // e.g. rule \"no-signing\" → key \"signing\" → does NOT block \"appointments:read\"\n // e.g. rule \"no-read\" → key \"read\" → does NOT block \"threading:update\"\n for (const rule of rules) {\n if (rule.enforcement === 'hard') {\n const ruleKey = rule.id.startsWith('no-') ? rule.id.slice(3) : rule.id;\n const actionSegments = action.toLowerCase().split(':');\n if (actionSegments.includes(ruleKey.toLowerCase())) {\n return {\n authorized: false,\n reason: `hard rule '${rule.id}' violated`,\n checks: {\n revoked: false,\n scopeAllowed: true,\n constraintsPassed: true,\n rulesPassed: false,\n },\n };\n }\n }\n }\n\n // 5. Soft rules — log violations, invoke callbacks, continue\n for (const rule of rules) {\n if (rule.enforcement === 'soft') {\n const violation: RuleViolation = {\n ruleId: rule.id,\n tokenId: token.jti,\n action,\n service,\n timestamp: new Date(),\n details: rule.description,\n };\n violations.push(violation);\n\n // Log to audit store if available\n if (options?.auditStore) {\n await options.auditStore.append({\n tokenId: token.jti,\n timestamp: violation.timestamp,\n action,\n service,\n result: 'escalated',\n details: { ruleId: rule.id, ruleDescription: rule.description },\n });\n }\n\n // Invoke onViolation callback if provided\n if (rule.onViolation) {\n await rule.onViolation(violation);\n }\n }\n }\n }\n\n return {\n authorized: true,\n checks: {\n revoked: false,\n scopeAllowed: true,\n constraintsPassed: true,\n rulesPassed: true,\n },\n violations: violations.length > 0 ? violations : undefined,\n };\n}\n","import type { APOADefinition } from '../types.js';\nimport { DefinitionValidationError } from '../utils/errors.js';\n\n/**\n * Parse a YAML or JSON definition string into an APOADefinition.\n * Auto-detects format: starts with '{' = JSON, otherwise YAML.\n * Validates required fields, metadata constraints, browser mode config,\n * and legal framework fields. Throws DefinitionValidationError with all\n * problems found.\n */\nexport function parseDefinition(\n input: string,\n format?: 'yaml' | 'json'\n): APOADefinition {\n const detectedFormat = format ?? (input.trimStart().startsWith('{') ? 'json' : 'yaml');\n let raw: unknown;\n\n try {\n if (detectedFormat === 'json') {\n raw = JSON.parse(input);\n } else {\n // Lazy-load yaml to keep it optional\n throw new Error('YAML parsing requires the \"yaml\" package. Use JSON format or install \"yaml\".');\n }\n } catch (err) {\n if (err instanceof SyntaxError) {\n throw new DefinitionValidationError('Failed to parse definition', [\n `Invalid ${detectedFormat}: ${err.message}`,\n ]);\n }\n throw err;\n }\n\n return validateDefinition(raw);\n}\n\n/**\n * Validate a parsed object as an APOADefinition.\n * Returns the validated definition or throws DefinitionValidationError.\n */\nfunction validateDefinition(raw: unknown): APOADefinition {\n const errors: string[] = [];\n const warnings: string[] = [];\n\n if (!raw || typeof raw !== 'object') {\n throw new DefinitionValidationError('Definition must be an object', [\n 'Definition must be an object',\n ]);\n }\n\n const obj = raw as Record<string, unknown>;\n\n // Required fields\n if (!obj.principal || typeof obj.principal !== 'object') {\n errors.push(\"missing required field 'principal'\");\n } else {\n const p = obj.principal as Record<string, unknown>;\n if (!p.id || typeof p.id !== 'string') {\n errors.push(\"'principal.id' must be a non-empty string\");\n }\n }\n\n if (!obj.agent || typeof obj.agent !== 'object') {\n errors.push(\"missing required field 'agent'\");\n } else {\n const a = obj.agent as Record<string, unknown>;\n if (!a.id || typeof a.id !== 'string') {\n errors.push(\"'agent.id' must be a non-empty string\");\n }\n }\n\n if (!obj.services || !Array.isArray(obj.services) || obj.services.length === 0) {\n errors.push(\"'services' must be a non-empty array\");\n } else {\n for (let i = 0; i < obj.services.length; i++) {\n const svc = obj.services[i] as Record<string, unknown>;\n if (!svc.service || typeof svc.service !== 'string') {\n errors.push(`services[${i}].service must be a non-empty string`);\n }\n if (!svc.scopes || !Array.isArray(svc.scopes) || svc.scopes.length === 0) {\n errors.push(`services[${i}].scopes must be a non-empty array`);\n } else {\n for (let j = 0; j < svc.scopes.length; j++) {\n const s = svc.scopes[j];\n if (typeof s !== 'string' || s.length === 0) {\n errors.push(`services[${i}].scopes[${j}] must be a non-empty string`);\n }\n }\n }\n\n // Phase 2b: Browser mode validation\n validateServiceAccessMode(svc, i, errors, warnings);\n }\n }\n\n if (obj.expires === undefined || obj.expires === null) {\n errors.push(\"missing required field 'expires'\");\n }\n\n // Metadata validation\n if (obj.metadata !== undefined) {\n validateMetadata(obj.metadata, errors);\n }\n\n // Phase 2b: AgentProvider validation\n if (obj.agentProvider !== undefined) {\n validateAgentProvider(obj.agentProvider, errors);\n }\n\n // Phase 2b: Legal framework validation\n if (obj.legal !== undefined) {\n validateLegalFramework(obj.legal, errors);\n }\n\n if (errors.length > 0) {\n const err = new DefinitionValidationError(\n `Invalid definition: ${errors.length} problem(s) found`,\n errors\n );\n // Attach warnings for callers that want them\n (err as DefinitionValidationError & { warnings?: string[] }).warnings = warnings;\n throw err;\n }\n\n // Convert date strings to Date objects where needed\n const def = obj as unknown as APOADefinition;\n if (typeof def.expires === 'string') {\n def.expires = def.expires; // keep as string — the spec allows Date | string\n }\n if (typeof def.notBefore === 'string') {\n def.notBefore = def.notBefore;\n }\n\n return def;\n}\n\nfunction validateMetadata(metadata: unknown, errors: string[]): void {\n if (typeof metadata !== 'object' || metadata === null || Array.isArray(metadata)) {\n errors.push(\"'metadata' must be a plain object\");\n return;\n }\n\n const keys = Object.keys(metadata as Record<string, unknown>);\n if (keys.length > 20) {\n errors.push(`metadata has ${keys.length} keys (max 20)`);\n }\n\n const serialized = JSON.stringify(metadata);\n if (serialized.length > 1024) {\n errors.push(\n `metadata serialized size is ${serialized.length} bytes (max 1024)`\n );\n }\n\n const record = metadata as Record<string, unknown>;\n for (const key of keys) {\n // Keys starting with _ are reserved for SDK use (e.g., _delegationDepth).\n // Reject them in parsed definitions to prevent forgery.\n if (key.startsWith('_')) {\n errors.push(\n `metadata key '${key}' uses reserved prefix '_' (reserved for SDK internal use)`\n );\n }\n const value = record[key];\n if (\n value !== null &&\n typeof value !== 'string' &&\n typeof value !== 'number' &&\n typeof value !== 'boolean'\n ) {\n errors.push(\n `metadata['${key}'] has invalid type '${typeof value}' (must be string | number | boolean | null)`\n );\n }\n }\n}\n\nfunction validateServiceAccessMode(\n svc: Record<string, unknown>,\n index: number,\n errors: string[],\n warnings: string[]\n): void {\n const accessMode = svc.accessMode as string | undefined;\n\n if (accessMode === 'browser') {\n if (!svc.browserConfig || typeof svc.browserConfig !== 'object') {\n errors.push(\n `services[${index}] has accessMode 'browser' but no browserConfig. ` +\n `Browser-based access requires explicit URL restrictions and a credential vault reference.`\n );\n return;\n }\n\n const bc = svc.browserConfig as Record<string, unknown>;\n\n if (!bc.allowedUrls || !Array.isArray(bc.allowedUrls) || bc.allowedUrls.length === 0) {\n errors.push(\n `services[${index}].browserConfig.allowedUrls must be a non-empty array`\n );\n }\n\n if (!bc.credentialVaultRef || typeof bc.credentialVaultRef !== 'string') {\n errors.push(\n `services[${index}].browserConfig.credentialVaultRef must be a non-empty string`\n );\n }\n\n if (bc.maxSessionDuration !== undefined) {\n if (typeof bc.maxSessionDuration !== 'number' || bc.maxSessionDuration > 86400) {\n errors.push(\n `services[${index}].browserConfig.maxSessionDuration must be <= 86400 seconds`\n );\n }\n }\n }\n\n if (accessMode === 'api' && svc.browserConfig) {\n warnings.push(\n `services[${index}] has accessMode 'api' but browserConfig is present (will be ignored)`\n );\n }\n}\n\nfunction validateAgentProvider(provider: unknown, errors: string[]): void {\n if (typeof provider !== 'object' || provider === null) {\n errors.push(\"'agentProvider' must be an object\");\n return;\n }\n\n const p = provider as Record<string, unknown>;\n if (!p.name || typeof p.name !== 'string') {\n errors.push(\"'agentProvider.name' is required and must be a non-empty string\");\n }\n}\n\nfunction validateLegalFramework(legal: unknown, errors: string[]): void {\n if (typeof legal !== 'object' || legal === null) {\n errors.push(\"'legal' must be an object\");\n return;\n }\n\n const l = legal as Record<string, unknown>;\n\n if (l.model !== 'provider-as-agent') {\n errors.push(\"'legal.model' must be 'provider-as-agent'\");\n }\n\n if (l.jurisdiction !== undefined) {\n if (typeof l.jurisdiction !== 'string') {\n errors.push(\"'legal.jurisdiction' must be a string\");\n } else {\n // ISO 3166 format: 2-letter country code, optionally followed by -subdivision\n // Examples: \"US\", \"US-CA\", \"GB\", \"DE\"\n const iso3166Pattern = /^[A-Z]{2}(-[A-Z0-9]{1,3})?$/;\n if (!iso3166Pattern.test(l.jurisdiction)) {\n errors.push(\n `'legal.jurisdiction' must be ISO 3166 format (e.g., \"US\", \"US-CA\", \"GB\"), got '${l.jurisdiction}'`\n );\n }\n }\n }\n}\n","import type {\n RevocationOptions,\n RevocationRecord,\n RevocationStore,\n} from '../types.js';\n\n/**\n * Revoke a token. The caller MUST supply a RevocationStore so the revocation\n * is durable and visible to other parts of the system. There is no default\n * store: a process-shared singleton would silently diverge from the store\n * used by `createClient()` and any caller-supplied store, producing\n * \"succeeded but never enforced\" revocations.\n */\nexport async function revoke(\n tokenId: string,\n options: RevocationOptions,\n store: RevocationStore\n): Promise<RevocationRecord> {\n const record: RevocationRecord = {\n tokenId,\n revokedAt: new Date(),\n revokedBy: options.revokedBy,\n reason: options.reason,\n cascaded: [],\n };\n\n await store.add(record);\n return record;\n}\n\n/**\n * Check if a token has been revoked. Caller must supply the same\n * RevocationStore that revoke() wrote to.\n */\nexport async function isRevoked(\n tokenId: string,\n store: RevocationStore\n): Promise<boolean> {\n const record = await store.check(tokenId);\n return record !== null;\n}\n","import type { AuditEntry, AuditStore } from '../types.js';\nimport { MemoryAuditStore } from './store.js';\n\nconst defaultStore = new MemoryAuditStore();\n\n/**\n * Log an action against a token.\n */\nexport async function logAction(\n tokenId: string,\n entry: Omit<AuditEntry, 'tokenId' | 'timestamp'>,\n store?: AuditStore\n): Promise<void> {\n const s = store ?? defaultStore;\n\n const fullEntry: AuditEntry = {\n ...entry,\n tokenId,\n timestamp: new Date(),\n };\n\n await s.append(fullEntry);\n}\n","import type { AuditEntry, AuditQueryOptions, AuditStore } from '../types.js';\nimport { MemoryAuditStore } from './store.js';\n\nconst defaultStore = new MemoryAuditStore();\n\n/**\n * Get the audit trail for a token.\n */\nexport async function getAuditTrail(\n tokenId: string,\n options?: AuditQueryOptions,\n store?: AuditStore\n): Promise<AuditEntry[]> {\n const s = store ?? defaultStore;\n return s.query(tokenId, options);\n}\n\n/**\n * Get the audit trail for a service — across all tokens.\n */\nexport async function getAuditTrailByService(\n service: string,\n options?: AuditQueryOptions,\n store?: AuditStore\n): Promise<AuditEntry[]> {\n const s = store ?? defaultStore;\n return s.queryByService(service, options);\n}\n","import * as jose from 'jose';\nimport type { SigningOptions } from '../types.js';\n\n/**\n * Sign an APOA token payload as a compact JWS.\n * Embeds `kid` in the JWT header when provided.\n * Supports EdDSA (default) and ES256.\n */\nexport async function signToken(\n payload: Record<string, unknown>,\n options: SigningOptions\n): Promise<string> {\n const alg = options.algorithm === 'ES256' ? 'ES256' : 'EdDSA';\n\n const header: jose.CompactJWSHeaderParameters = { alg };\n if (options.kid) {\n header.kid = options.kid;\n }\n\n const jws = await new jose.CompactSign(\n new TextEncoder().encode(JSON.stringify(payload))\n )\n .setProtectedHeader(header)\n .sign(options.privateKey);\n\n return jws;\n}\n\n/**\n * Decode a compact JWS protected header without verifying the signature.\n * Used to extract `kid` and `alg` for key resolution.\n */\nexport function decodeHeader(\n token: string\n): Record<string, unknown> {\n const [headerB64] = token.split('.');\n if (!headerB64) throw new Error('Invalid JWS: missing header');\n return JSON.parse(\n new TextDecoder().decode(jose.base64url.decode(headerB64))\n );\n}\n\n/**\n * Verify a compact JWS and return the decoded payload.\n */\nexport async function verifySignature(\n token: string,\n key: CryptoKey\n): Promise<Record<string, unknown>> {\n const { payload } = await jose.compactVerify(token, key);\n return JSON.parse(new TextDecoder().decode(payload));\n}\n","import type { APOADefinition, APOAToken, SigningOptions } from '../types.js';\nimport { MetadataValidationError } from '../utils/errors.js';\nimport { signToken } from './sign.js';\n\n/**\n * Create an APOA token from a definition.\n * Generates a UUID for jti, validates metadata, derives audience,\n * warns at 4KB, rejects above 8KB.\n */\nexport async function createToken(\n definition: APOADefinition,\n options: SigningOptions,\n parentTokenId?: string\n): Promise<APOAToken> {\n // Validate metadata if present\n if (definition.metadata) {\n validateMetadata(definition.metadata);\n }\n\n const jti = crypto.randomUUID();\n const issuedAt = new Date();\n const issuer = definition.principal.id;\n const audience = definition.services.map((s) => s.service);\n\n // Build the payload that gets signed\n const payload: Record<string, unknown> = {\n jti,\n iss: issuer,\n aud: audience,\n iat: Math.floor(issuedAt.getTime() / 1000),\n exp: Math.floor(\n (typeof definition.expires === 'string'\n ? new Date(definition.expires)\n : definition.expires\n ).getTime() / 1000\n ),\n definition: {\n ...serializeDefinition(definition),\n ...(parentTokenId ? { parentToken: parentTokenId } : {}),\n },\n };\n\n if (definition.notBefore) {\n payload.nbf = Math.floor(\n (typeof definition.notBefore === 'string'\n ? new Date(definition.notBefore)\n : definition.notBefore\n ).getTime() / 1000\n );\n }\n\n // Sign the token\n const raw = await signToken(payload, options);\n\n // Size checks\n const sizeBytes = new TextEncoder().encode(raw).length;\n if (sizeBytes > 8192) {\n throw new MetadataValidationError(\n `Token size is ${sizeBytes} bytes (max 8192). Issue multiple tokens for large authorization surfaces.`\n );\n }\n\n const token: APOAToken = {\n jti,\n definition,\n issuedAt,\n signature: raw.split('.')[2],\n issuer,\n audience,\n parentToken: parentTokenId,\n raw,\n };\n\n return token;\n}\n\nfunction validateMetadata(metadata: Record<string, unknown>): void {\n const keys = Object.keys(metadata);\n if (keys.length > 20) {\n throw new MetadataValidationError(\n `Metadata has ${keys.length} keys (max 20)`\n );\n }\n\n const serialized = JSON.stringify(metadata);\n if (serialized.length > 1024) {\n throw new MetadataValidationError(\n `Metadata serialized size is ${serialized.length} bytes (max 1024)`\n );\n }\n\n for (const key of keys) {\n const value = metadata[key];\n if (\n value !== null &&\n typeof value !== 'string' &&\n typeof value !== 'number' &&\n typeof value !== 'boolean'\n ) {\n throw new MetadataValidationError(\n `Metadata key '${key}' has invalid type '${typeof value}'`,\n key\n );\n }\n }\n}\n\n/**\n * Serialize a definition for inclusion in the JWT payload.\n * Converts Date objects to ISO strings for JSON compatibility.\n */\nfunction serializeDefinition(\n def: APOADefinition\n): Record<string, unknown> {\n return {\n ...def,\n expires:\n def.expires instanceof Date\n ? def.expires.toISOString()\n : def.expires,\n notBefore:\n def.notBefore instanceof Date\n ? def.notBefore.toISOString()\n : def.notBefore,\n // Strip non-serializable onViolation callbacks from rules\n rules: def.rules?.map(({ onViolation: _, ...rest }) => rest),\n };\n}\n","import type {\n APOAToken,\n ValidationOptions,\n ValidationResult,\n} from '../types.js';\nimport { isExpired, isBeforeNotBefore } from '../utils/time.js';\nimport { decodeHeader, verifySignature } from './sign.js';\n\n/**\n * Validate a token — check signature, expiration, structure, revocation.\n * Returns a detailed result with all errors found.\n *\n * Accepts either a raw JWT string or an APOAToken object.\n * When given a string, decodes and verifies the signature.\n * When given an APOAToken, uses the .raw field for signature verification.\n */\nexport async function validateToken(\n token: string | APOAToken,\n options: ValidationOptions\n): Promise<ValidationResult> {\n const errors: string[] = [];\n const warnings: string[] = [];\n let parsedToken: APOAToken | undefined;\n\n const rawJwt = typeof token === 'string' ? token : token.raw;\n\n // --- Key resolution ---\n let publicKey: CryptoKey | undefined;\n\n if (options.publicKey) {\n publicKey = options.publicKey;\n } else if (options.keyResolver) {\n try {\n const header = decodeHeader(rawJwt);\n const kid = header.kid as string | undefined;\n if (kid) {\n const resolved = await options.keyResolver.resolve(kid);\n if (resolved) {\n publicKey = resolved;\n } else {\n errors.push(`Key resolver returned null for kid '${kid}'`);\n }\n } else {\n errors.push('Token has no kid in header and keyResolver requires one');\n }\n } catch {\n errors.push('Failed to decode token header for key resolution');\n }\n } else if (options.publicKeyResolver) {\n // Need issuer from the payload — decode without verification first\n try {\n const header = decodeHeader(rawJwt);\n // Decode payload without verification to get issuer\n const payloadB64 = rawJwt.split('.')[1];\n if (payloadB64) {\n const payloadJson = new TextDecoder().decode(\n base64urlDecode(payloadB64)\n );\n const payload = JSON.parse(payloadJson);\n const issuer = payload.iss as string | undefined;\n if (issuer) {\n publicKey = await options.publicKeyResolver(issuer);\n } else {\n errors.push('Token has no issuer (iss) claim for publicKeyResolver');\n }\n }\n } catch {\n errors.push('Failed to decode token for issuer-based key resolution');\n }\n } else {\n errors.push(\n 'No key provided: supply publicKey, keyResolver, or publicKeyResolver'\n );\n }\n\n // --- Algorithm policy check ---\n // The token's alg header must be in the permitted list. APOA's conformance\n // baseline is EdDSA + ES256; callers can pin to a single algorithm to\n // enforce an org policy (e.g. EdDSA-only).\n const permittedAlgorithms = options.algorithms ?? ['EdDSA', 'ES256'];\n let headerAlg: string | undefined;\n try {\n const header = decodeHeader(rawJwt);\n headerAlg = typeof header.alg === 'string' ? header.alg : undefined;\n } catch {\n // Header decode already produced an error above when key resolution ran;\n // if no resolver was used we still want to surface the malformed header.\n }\n if (headerAlg && !permittedAlgorithms.includes(headerAlg as 'EdDSA' | 'ES256')) {\n errors.push(\n `Token alg '${headerAlg}' is not in the permitted list [${permittedAlgorithms.join(', ')}]`\n );\n }\n\n // --- Signature verification ---\n let payload: Record<string, unknown> | undefined;\n let signatureVerified = false;\n\n if (publicKey && headerAlg && permittedAlgorithms.includes(headerAlg as 'EdDSA' | 'ES256')) {\n try {\n payload = await verifySignature(rawJwt, publicKey);\n signatureVerified = true;\n } catch {\n errors.push('Signature verification failed');\n }\n } else if (publicKey && !headerAlg) {\n // Header had no alg at all — still attempt verification so jose returns\n // a meaningful error, but flag the missing alg.\n errors.push('Token header missing alg');\n }\n\n // If we couldn't verify, decode payload for structural checks only.\n // result.token will NOT be populated (prevents operating on forged data).\n if (!payload) {\n try {\n const payloadB64 = rawJwt.split('.')[1];\n if (payloadB64) {\n payload = JSON.parse(\n new TextDecoder().decode(base64urlDecode(payloadB64))\n );\n }\n } catch {\n // Can't even decode the payload — nothing more to check\n }\n }\n\n if (!payload) {\n return { valid: false, errors: errors.length > 0 ? errors : ['Unable to decode token'], warnings };\n }\n\n // --- Build APOAToken from payload (only if signature was verified) ---\n if (signatureVerified) {\n try {\n parsedToken = payloadToToken(payload, rawJwt);\n } catch {\n errors.push('Token payload has invalid structure');\n }\n }\n\n // --- Temporal checks ---\n const clockSkew = options.clockSkew;\n\n if (payload.exp !== undefined) {\n const expiresDate = new Date((payload.exp as number) * 1000);\n if (isExpired(expiresDate, clockSkew)) {\n errors.push(`Token expired at ${expiresDate.toISOString()}`);\n }\n } else {\n errors.push('Token has no expiration (exp) claim');\n }\n\n if (payload.nbf !== undefined) {\n const notBeforeDate = new Date((payload.nbf as number) * 1000);\n if (isBeforeNotBefore(notBeforeDate, clockSkew)) {\n errors.push(`Token not valid before ${notBeforeDate.toISOString()}`);\n }\n }\n\n // --- Revocation check ---\n const checkRevocation = options.checkRevocation !== false;\n if (checkRevocation && options.revocationStore && payload.jti) {\n const revRecord = await options.revocationStore.check(\n payload.jti as string\n );\n if (revRecord) {\n errors.push(\n `Token has been revoked (at ${revRecord.revokedAt.toISOString()} by ${revRecord.revokedBy})`\n );\n }\n }\n\n // --- Size warning ---\n const sizeBytes = new TextEncoder().encode(rawJwt).length;\n if (sizeBytes > 4096) {\n warnings.push(`Token size is ${sizeBytes} bytes (exceeds 4KB recommended limit)`);\n }\n\n return {\n valid: errors.length === 0,\n errors,\n token: parsedToken,\n warnings: warnings.length > 0 ? warnings : undefined,\n };\n}\n\n/**\n * Reconstruct an APOAToken from a decoded JWT payload.\n */\nfunction payloadToToken(\n payload: Record<string, unknown>,\n raw: string\n): APOAToken {\n const definition = payload.definition as Record<string, unknown>;\n if (!definition) throw new Error('Missing definition in payload');\n\n return {\n jti: payload.jti as string,\n definition: definition as unknown as APOAToken['definition'],\n issuedAt: new Date((payload.iat as number) * 1000),\n signature: raw.split('.')[2],\n issuer: payload.iss as string,\n audience: payload.aud as string[] | undefined,\n parentToken: (definition.parentToken as string) ?? undefined,\n raw,\n };\n}\n\nfunction base64urlDecode(input: string): Uint8Array {\n // Pad if needed\n const padded = input + '='.repeat((4 - (input.length % 4)) % 4);\n const binary = atob(padded.replace(/-/g, '+').replace(/_/g, '/'));\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n}\n","import type {\n DelegationChain,\n RevocationOptions,\n RevocationRecord,\n RevocationStore,\n} from '../types.js';\n\n/**\n * Cascade revoke: revoke a parent token and all child tokens in a delegation\n * chain. Populates RevocationRecord.cascaded with child token IDs.\n *\n * The caller MUST supply a RevocationStore. There is no default store: a\n * process-shared singleton would silently diverge from the store used by\n * `createClient()` and any caller-supplied store.\n *\n * @param parentTokenId - The parent token's jti to revoke\n * @param childTokenIds - Array of child token jti values to cascade-revoke\n * @param options - Revocation options (revokedBy, reason)\n * @param store - The revocation store to write to\n */\nexport async function cascadeRevoke(\n parentTokenId: string,\n childTokenIds: string[],\n options: RevocationOptions,\n store: RevocationStore\n): Promise<RevocationRecord> {\n const revokedAt = new Date();\n\n // Revoke all children\n for (const childId of childTokenIds) {\n const childRecord: RevocationRecord = {\n tokenId: childId,\n revokedAt,\n revokedBy: options.revokedBy,\n reason: options.reason\n ? `Cascade: ${options.reason}`\n : `Cascade revocation from parent ${parentTokenId}`,\n cascaded: [],\n };\n await store.add(childRecord);\n }\n\n // Revoke parent with cascaded list\n const parentRecord: RevocationRecord = {\n tokenId: parentTokenId,\n revokedAt,\n revokedBy: options.revokedBy,\n reason: options.reason,\n cascaded: childTokenIds,\n };\n await store.add(parentRecord);\n\n return parentRecord;\n}\n","import type { APOAToken, DelegationDefinition, ServiceAuthorization } from '../types.js';\nimport { AttenuationViolationError } from '../utils/errors.js';\nimport { matchScope } from './patterns.js';\n\n/**\n * Verify that a delegation definition is a valid attenuation of a parent token.\n * Throws AttenuationViolationError on any violation.\n *\n * Checks:\n * 1. Child scopes are a subset of parent scopes (per service)\n * 2. Child constraints do not relax parent constraints\n * 3. Child expiration <= parent expiration\n * 4. maxDelegationDepth is not exceeded\n * 5. Child does not add services the parent doesn't have\n * 6. Child rules only add, never remove parent rules\n */\nexport function verifyAttenuation(\n parent: APOAToken,\n child: DelegationDefinition,\n currentDepth: number = 0\n): void {\n const parentDef = parent.definition;\n\n // Check delegation is allowed\n if (parentDef.delegatable === false) {\n throw new AttenuationViolationError(\n 'Parent token does not allow delegation',\n parentDef.services.flatMap((s) => s.scopes),\n child.services.flatMap((s) => s.scopes)\n );\n }\n\n // Check delegation depth\n if (parentDef.maxDelegationDepth !== undefined) {\n if (currentDepth >= parentDef.maxDelegationDepth) {\n throw new AttenuationViolationError(\n `Delegation depth ${currentDepth + 1} exceeds maxDelegationDepth ${parentDef.maxDelegationDepth}`,\n parentDef.services.flatMap((s) => s.scopes),\n child.services.flatMap((s) => s.scopes)\n );\n }\n }\n\n // Check expiration: child must expire at or before parent\n if (child.expires !== undefined) {\n const childExp = child.expires instanceof Date\n ? child.expires.getTime()\n : new Date(child.expires).getTime();\n const parentExp = parentDef.expires instanceof Date\n ? parentDef.expires.getTime()\n : new Date(parentDef.expires as string).getTime();\n\n if (childExp > parentExp) {\n throw new AttenuationViolationError(\n 'Child token expiration exceeds parent expiration',\n parentDef.services.flatMap((s) => s.scopes),\n child.services.flatMap((s) => s.scopes)\n );\n }\n }\n\n // Check each child service against parent\n for (const childService of child.services) {\n const parentService = parentDef.services.find(\n (s) => s.service === childService.service\n );\n\n if (!parentService) {\n throw new AttenuationViolationError(\n `Child requests service '${childService.service}' not in parent token`,\n parentDef.services.flatMap((s) => s.scopes),\n child.services.flatMap((s) => s.scopes)\n );\n }\n\n // Check scopes are a subset\n verifyScopeSubset(parentService, childService);\n\n // Check constraints are not relaxed\n verifyConstraintsNotRelaxed(parentService, childService);\n }\n\n // Check rules: child can only add, not remove\n if (parentDef.rules && parentDef.rules.length > 0) {\n verifyRulesNotRemoved(\n parentDef.rules.map((r) => r.id),\n child,\n parentDef.services.flatMap((s) => s.scopes),\n child.services.flatMap((s) => s.scopes)\n );\n }\n}\n\n/**\n * Verify every child scope is covered by at least one parent scope.\n */\nfunction verifyScopeSubset(\n parent: ServiceAuthorization,\n child: ServiceAuthorization\n): void {\n for (const childScope of child.scopes) {\n const matched = parent.scopes.some((parentScope) =>\n matchScope(parentScope, childScope)\n );\n if (!matched) {\n throw new AttenuationViolationError(\n `Child scope '${childScope}' on service '${child.service}' is not covered by parent scopes [${parent.scopes.join(', ')}]`,\n parent.scopes,\n child.scopes\n );\n }\n }\n}\n\n/**\n * Verify child constraints do not relax parent constraints.\n *\n * A constraint set to `false` in the parent must remain `false` in the child:\n * setting it to `true` flips it (relaxation), and omitting it makes the\n * child's authorize() skip the check entirely (silent relaxation). Both fail.\n *\n * New constraints can be added by the child (they only restrict further).\n */\nfunction verifyConstraintsNotRelaxed(\n parent: ServiceAuthorization,\n child: ServiceAuthorization\n): void {\n if (!parent.constraints) return;\n\n for (const [key, parentValue] of Object.entries(parent.constraints)) {\n if (parentValue === false) {\n const childValue = child.constraints?.[key];\n if (childValue === false) continue;\n throw new AttenuationViolationError(\n childValue === true\n ? `Child relaxes constraint '${key}' on service '${child.service}' (parent: false, child: true)`\n : `Child omits constraint '${key}' on service '${child.service}' (parent: false, child: undefined)`,\n parent.scopes,\n child.scopes\n );\n }\n }\n}\n\n/**\n * Verify child does not remove parent rules.\n * Child can add new rules but must preserve all parent rule IDs.\n */\nfunction verifyRulesNotRemoved(\n parentRuleIds: string[],\n child: DelegationDefinition,\n parentScopes: string[],\n childScopes: string[]\n): void {\n const childRuleIds = new Set(child.rules?.map((r) => r.id) ?? []);\n for (const parentRuleId of parentRuleIds) {\n if (!childRuleIds.has(parentRuleId)) {\n throw new AttenuationViolationError(\n `Child removes parent rule '${parentRuleId}'. Rules can only be added, not removed.`,\n parentScopes,\n childScopes\n );\n }\n }\n}\n","import type {\n APOAToken,\n APOADefinition,\n DelegationDefinition,\n SigningOptions,\n} from '../types.js';\nimport { createToken } from '../token/create.js';\nimport { verifyAttenuation } from '../scope/attenuate.js';\n\n/**\n * Create a delegated (attenuated) token from a parent token.\n *\n * - Inherits principal from parent (cannot be overridden)\n * - Sets parentToken on child to parent's jti\n * - Enforces attenuation rules\n * - Additional rules can only be added, not removed\n */\nexport async function delegate(\n parentToken: APOAToken,\n childDef: DelegationDefinition,\n options: SigningOptions\n): Promise<APOAToken> {\n // Calculate current delegation depth\n // For now, depth is 0 for direct children of the root.\n // In a full chain, this would be tracked. The parent's depth context\n // is determined by counting parentToken links, but for single-level\n // delegation we pass 0 (first delegation).\n const currentDepth = countDepth(parentToken);\n\n // Build the child definition, inheriting principal from parent\n const parentDef = parentToken.definition;\n\n // Merge rules: start with parent rules, add child-specific ones\n const parentRules = parentDef.rules ?? [];\n const childExtraRules = (childDef.rules ?? []).filter(\n (cr) => !parentRules.some((pr) => pr.id === cr.id)\n );\n const mergedRules = [...parentRules, ...childExtraRules];\n\n // Track delegation depth in metadata so deep chains are properly limited\n const childDepth = currentDepth + 1;\n const childMetadata = {\n ...childDef.metadata,\n _delegationDepth: childDepth,\n };\n\n // Inherit parent's false constraints into child services BEFORE attenuation\n // check. If parent says { signing: false }, the child MUST carry that\n // constraint even if the delegation definition omits it — otherwise the\n // child's authorize() would skip the constraint check entirely (privilege\n // escalation). verifyAttenuation now treats omission as relaxation, so\n // the inheritance must happen first or strict callers would fail here.\n const inheritedServices = childDef.services.map((childSvc) => {\n const parentSvc = parentDef.services.find((s) => s.service === childSvc.service);\n if (!parentSvc?.constraints) return childSvc;\n\n const inherited: Record<string, import('../types.js').ConstraintValue> = {};\n for (const [key, value] of Object.entries(parentSvc.constraints)) {\n if (value === false) {\n inherited[key] = false;\n }\n }\n if (Object.keys(inherited).length === 0) return childSvc;\n\n return {\n ...childSvc,\n constraints: { ...inherited, ...childSvc.constraints },\n };\n });\n\n // Now verify attenuation against the inherited (filled-in) child definition.\n verifyAttenuation(\n parentToken,\n { ...childDef, services: inheritedServices, rules: mergedRules },\n currentDepth\n );\n\n const fullDefinition: APOADefinition = {\n principal: parentDef.principal, // Inherited — cannot be overridden\n agent: childDef.agent,\n agentProvider: parentDef.agentProvider,\n services: inheritedServices,\n rules: mergedRules.length > 0 ? mergedRules : undefined,\n expires: childDef.expires ?? parentDef.expires,\n revocable: parentDef.revocable,\n delegatable: parentDef.delegatable,\n maxDelegationDepth: parentDef.maxDelegationDepth,\n metadata: childMetadata,\n legal: parentDef.legal,\n };\n\n // Pass parentTokenId so it's included in the signed JWT payload\n const childToken = await createToken(fullDefinition, options, parentToken.jti);\n\n return childToken;\n}\n\n/**\n * Count delegation depth from a token's definition.\n *\n * We track depth explicitly: when delegate() creates a child token,\n * it stores the current depth in metadata._delegationDepth.\n * A root token has no depth (0). A direct child has depth 1, etc.\n */\nfunction countDepth(token: APOAToken): number {\n const stored = token.definition.metadata?._delegationDepth;\n if (typeof stored === 'number') return stored;\n // No stored depth — this is either a root token or a legacy token.\n // Fall back to checking parentToken as a heuristic.\n return token.parentToken ? 1 : 0;\n}\n","import type {\n ChainVerificationResult,\n DelegationChain,\n RevocationStore,\n} from '../types.js';\nimport { isExpired } from '../utils/time.js';\nimport { matchScope } from '../scope/patterns.js';\n\n/**\n * Verify a full delegation chain.\n *\n * - Verifies every link attenuates the previous one (scopes are subsets)\n * - Checks expiration of every token (if any parent expired, chain is invalid)\n * - If RevocationStore provided, checks revocation of every token\n * - Reports all errors found, plus failedAt index\n *\n * IMPORTANT: This function checks structural integrity (attenuation, expiry,\n * revocation, parentToken links) but does NOT verify cryptographic signatures.\n * Each token in the chain MUST be validated via validateToken() before passing\n * to verifyChain(). Passing unvalidated APOAToken objects defeats chain security.\n */\nexport async function verifyChain(\n chain: DelegationChain,\n store?: RevocationStore\n): Promise<ChainVerificationResult> {\n const errors: string[] = [];\n let failedAt: number | undefined;\n\n if (chain.length === 0) {\n return {\n valid: false,\n depth: 0,\n errors: ['Chain is empty'],\n root: undefined as any,\n leaf: undefined as any,\n };\n }\n\n if (chain.length === 1) {\n // Single token — just check expiration and revocation\n const token = chain[0];\n await checkTokenValidity(token, 0, errors, store);\n return {\n valid: errors.length === 0,\n depth: 0,\n errors,\n failedAt: errors.length > 0 ? 0 : undefined,\n root: token,\n leaf: token,\n };\n }\n\n // Check each token in the chain\n for (let i = 0; i < chain.length; i++) {\n const token = chain[i];\n const errorsBefore = errors.length;\n\n // Check expiration\n await checkTokenValidity(token, i, errors, store);\n\n // Check attenuation against parent (skip root at index 0)\n if (i > 0) {\n const parent = chain[i - 1];\n checkAttenuation(parent, token, i, errors);\n\n // Check parentToken reference\n if (token.parentToken !== parent.jti) {\n errors.push(\n `Chain link ${i}: parentToken '${token.parentToken}' does not match parent jti '${parent.jti}'`\n );\n }\n }\n\n // Track first failure\n if (failedAt === undefined && errors.length > errorsBefore) {\n failedAt = i;\n }\n }\n\n return {\n valid: errors.length === 0,\n depth: chain.length - 1,\n errors,\n failedAt,\n root: chain[0],\n leaf: chain[chain.length - 1],\n };\n}\n\n/**\n * Check a single token's validity (expiration and revocation).\n */\nasync function checkTokenValidity(\n token: { jti: string; definition: { expires: Date | string } },\n index: number,\n errors: string[],\n store?: RevocationStore\n): Promise<void> {\n // Expiration check (no clock skew for chain verification — strict)\n if (isExpired(token.definition.expires, 0)) {\n errors.push(`Chain link ${index}: token '${token.jti}' has expired`);\n }\n\n // Revocation check\n if (store) {\n const record = await store.check(token.jti);\n if (record) {\n errors.push(\n `Chain link ${index}: token '${token.jti}' has been revoked`\n );\n }\n }\n}\n\n/**\n * Verify that a child token attenuates the parent: scopes are a subset,\n * constraints are not relaxed (a parent `false` must remain `false`), and\n * expiration does not extend beyond the parent.\n */\nfunction checkAttenuation(\n parent: {\n definition: {\n services: { service: string; scopes: string[]; constraints?: Record<string, unknown> }[];\n expires: Date | string;\n };\n },\n child: {\n definition: {\n services: { service: string; scopes: string[]; constraints?: Record<string, unknown> }[];\n expires: Date | string;\n };\n },\n index: number,\n errors: string[]\n): void {\n // Check each child service\n for (const childService of child.definition.services) {\n const parentService = parent.definition.services.find(\n (s) => s.service === childService.service\n );\n\n if (!parentService) {\n errors.push(\n `Chain link ${index}: service '${childService.service}' not in parent token`\n );\n continue;\n }\n\n // Check each child scope is covered by a parent scope\n for (const childScope of childService.scopes) {\n const covered = parentService.scopes.some((ps) =>\n matchScope(ps, childScope)\n );\n if (!covered) {\n errors.push(\n `Chain link ${index}: scope '${childScope}' on '${childService.service}' not covered by parent`\n );\n }\n }\n\n // Check constraints are not relaxed. Any parent constraint set to false\n // must also be false on the child — true flips it (relaxation), undefined\n // means the child's authorize() skips the check (silent relaxation).\n if (parentService.constraints) {\n for (const [key, parentValue] of Object.entries(parentService.constraints)) {\n if (parentValue === false) {\n const childValue = childService.constraints?.[key];\n if (childValue !== false) {\n errors.push(\n `Chain link ${index}: constraint '${key}' on '${childService.service}' relaxed by child (parent: false, child: ${childValue === undefined ? 'undefined' : JSON.stringify(childValue)})`\n );\n }\n }\n }\n }\n }\n\n // Check child expiration <= parent expiration\n const childExp = child.definition.expires instanceof Date\n ? child.definition.expires.getTime()\n : new Date(child.definition.expires as string).getTime();\n const parentExp = parent.definition.expires instanceof Date\n ? parent.definition.expires.getTime()\n : new Date(parent.definition.expires as string).getTime();\n\n if (childExp > parentExp) {\n errors.push(\n `Chain link ${index}: child expiration exceeds parent expiration`\n );\n }\n}\n","import type { APOAToken } from '../types.js';\n\ntype DelegationLink = {\n parentTokenId?: unknown;\n};\n\ntype DefinitionLike = {\n parentToken?: unknown;\n delegationChain?: unknown;\n};\n\ntype TokenLike = {\n parentToken?: unknown;\n definition?: DefinitionLike;\n};\n\n/**\n * Return ancestor token IDs referenced by a token-like object.\n *\n * Canonical SDK tokens use `parentToken` for the direct parent. Some transport\n * adapters also carry `definition.delegationChain` snapshots or message\n * metadata with ancestor IDs. This helper normalizes those forms so revocation\n * checks can consistently include every known ancestor.\n */\nexport function getDelegationAncestorIds(input: APOAToken | TokenLike | DefinitionLike): string[] {\n const ids: string[] = [];\n const seen = new Set<string>();\n\n const push = (value: unknown): void => {\n if (typeof value !== 'string' || value.length === 0 || seen.has(value)) {\n return;\n }\n seen.add(value);\n ids.push(value);\n };\n\n const token = input as TokenLike;\n const definition = hasDefinition(input) ? token.definition : (input as DefinitionLike);\n\n push(token.parentToken);\n push(definition?.parentToken);\n\n const chain = definition?.delegationChain;\n if (Array.isArray(chain)) {\n for (const link of chain) {\n if (typeof link === 'string') {\n push(link);\n } else if (link && typeof link === 'object') {\n push((link as DelegationLink).parentTokenId);\n }\n }\n }\n\n return ids;\n}\n\nfunction hasDefinition(input: unknown): input is TokenLike {\n return Boolean(input && typeof input === 'object' && 'definition' in input);\n}\n","import * as jose from 'jose';\nimport type { KeyResolver } from '../types.js';\n\n/** A JSON Web Key as defined by RFC 7517. */\nexport interface JWK {\n kty: string;\n crv?: string;\n x?: string;\n y?: string;\n kid: string;\n use?: 'sig' | 'enc';\n alg?: string;\n [key: string]: unknown;\n}\n\n/** A JSON Web Key Set as defined by RFC 7517 §5. */\nexport interface JWKS {\n keys: JWK[];\n}\n\nexport interface PublicKeyToJWKOptions {\n kid: string;\n use?: 'sig' | 'enc';\n alg?: 'EdDSA' | 'ES256';\n}\n\n/**\n * Convert a public CryptoKey into a JWK. The `kid` is required so callers\n * can match keys against the `kid` header on signed tokens. `alg` defaults\n * to the algorithm implied by the key type (`EdDSA` for Ed25519, `ES256`\n * for P-256).\n */\nexport async function publicKeyToJWK(\n publicKey: CryptoKey,\n options: PublicKeyToJWKOptions\n): Promise<JWK> {\n const exported = await jose.exportJWK(publicKey);\n const alg = options.alg ?? defaultAlgorithm(exported);\n return {\n ...(exported as Record<string, unknown>),\n kid: options.kid,\n use: options.use ?? 'sig',\n alg,\n } as JWK;\n}\n\n/** Wrap an array of JWKs in the JWKS envelope. */\nexport function buildJWKS(keys: JWK[]): JWKS {\n return { keys };\n}\n\nexport interface JWKSResolverOptions {\n /** How long a fetched JWKS is cached in memory before refetch. Default 1 hour. */\n cacheMaxAgeMs?: number;\n /** How long a fetched JWKS is reused if a refetch fails. Default 24 hours. */\n cooldownMs?: number;\n /** Custom fetch implementation; defaults to the global fetch. */\n fetch?: typeof fetch;\n /**\n * Allow non-https:// JWKS URLs. Off by default because APOA mandates TLS\n * for all communication (SPEC §13.2). Use only for local development.\n */\n allowInsecure?: boolean;\n}\n\n/**\n * Create a KeyResolver backed by a remote JWKS endpoint. The resolver fetches\n * `url`, caches the response, and returns the matching public key for a\n * given `kid` claim. Used in conjunction with `validateToken`'s `keyResolver`\n * option so a relying party can verify tokens signed by keys it discovers\n * at runtime.\n */\nexport function createJWKSResolver(\n url: string,\n options: JWKSResolverOptions = {}\n): KeyResolver {\n if (!options.fetch && !options.allowInsecure && !url.startsWith('https://')) {\n throw new Error(\n `JWKS URL must use https:// (got: ${JSON.stringify(url)}). ` +\n 'Pass allowInsecure: true or a custom fetch for local development.'\n );\n }\n const cacheMaxAgeMs = options.cacheMaxAgeMs ?? 60 * 60 * 1000;\n const cooldownMs = options.cooldownMs ?? 24 * 60 * 60 * 1000;\n const fetchImpl = options.fetch ?? fetch;\n\n let cache: { fetchedAt: number; jwks: JWKS } | null = null;\n let inflight: Promise<JWKS> | null = null;\n\n async function fetchJWKS(): Promise<JWKS> {\n const response = await fetchImpl(url, {\n headers: { accept: 'application/jwk-set+json, application/json' },\n });\n if (!response.ok) {\n throw new Error(`JWKS fetch failed: ${response.status} ${response.statusText}`);\n }\n const body = (await response.json()) as JWKS;\n if (!body || !Array.isArray(body.keys)) {\n throw new Error('JWKS response did not contain a `keys` array');\n }\n return body;\n }\n\n async function getJWKS(): Promise<JWKS> {\n const now = Date.now();\n if (cache && now - cache.fetchedAt < cacheMaxAgeMs) {\n return cache.jwks;\n }\n if (inflight) {\n return inflight;\n }\n inflight = fetchJWKS()\n .then((jwks) => {\n cache = { fetchedAt: Date.now(), jwks };\n return jwks;\n })\n .catch((err) => {\n if (cache && now - cache.fetchedAt < cooldownMs) {\n return cache.jwks;\n }\n throw err;\n })\n .finally(() => {\n inflight = null;\n });\n return inflight;\n }\n\n return {\n async resolve(kid: string): Promise<CryptoKey | null> {\n const jwks = await getJWKS();\n const match = jwks.keys.find((k) => k.kid === kid);\n if (!match) return null;\n const key = await jose.importJWK(match as jose.JWK, match.alg);\n return key as CryptoKey;\n },\n };\n}\n\nfunction defaultAlgorithm(jwk: jose.JWK): string {\n if (jwk.kty === 'OKP' && jwk.crv === 'Ed25519') return 'EdDSA';\n if (jwk.kty === 'EC' && jwk.crv === 'P-256') return 'ES256';\n return jwk.alg ?? 'EdDSA';\n}\n","import type {\n APOAClient,\n APOAClientOptions,\n APOADefinition,\n APOAToken,\n AuditEntry,\n AuditQueryOptions,\n AuthorizeOptions,\n AuthorizationResult,\n ChainVerificationResult,\n DelegationChain,\n DelegationDefinition,\n RevocationOptions,\n RevocationRecord,\n ScopeCheckResult,\n SigningOptions,\n ValidationOptions,\n ValidationResult,\n} from './types.js';\nimport { MemoryRevocationStore } from './revocation/store.js';\nimport { MemoryAuditStore } from './audit/store.js';\nimport { createToken } from './token/create.js';\nimport { validateToken } from './token/validate.js';\nimport { parseDefinition } from './token/parse.js';\nimport { generateKeyPair } from './utils/crypto.js';\nimport { checkScope, checkConstraint, authorize } from './scope/check.js';\nimport { delegate } from './delegation/chain.js';\nimport { verifyChain } from './delegation/verify.js';\nimport { revoke, isRevoked } from './revocation/revoke.js';\nimport { logAction } from './audit/log.js';\nimport { getAuditTrail, getAuditTrailByService } from './audit/trail.js';\n\n/**\n * Create a configured APOA client.\n * Wires up RevocationStore and AuditStore so methods don't need explicit store params.\n * Defaults to MemoryRevocationStore + MemoryAuditStore for zero-config dev/testing.\n */\nexport function createClient(options?: APOAClientOptions): APOAClient {\n const revocationStore = options?.revocationStore ?? new MemoryRevocationStore();\n const auditStore = options?.auditStore ?? new MemoryAuditStore();\n const keyResolver = options?.keyResolver;\n const defaultSigningOptions = options?.defaultSigningOptions;\n\n function mergeSigningOptions(opts?: SigningOptions): SigningOptions {\n if (!opts && !defaultSigningOptions?.privateKey) {\n throw new Error('No signing options provided and no defaultSigningOptions.privateKey configured');\n }\n return {\n ...defaultSigningOptions,\n ...opts,\n } as SigningOptions;\n }\n\n return {\n async createToken(\n definition: APOADefinition,\n opts?: SigningOptions\n ): Promise<APOAToken> {\n return createToken(definition, mergeSigningOptions(opts));\n },\n\n parseDefinition(\n input: string,\n format?: 'yaml' | 'json'\n ): APOADefinition {\n return parseDefinition(input, format);\n },\n\n async validateToken(\n token: string | APOAToken,\n opts?: Omit<ValidationOptions, 'revocationStore'>\n ): Promise<ValidationResult> {\n return validateToken(token, {\n ...opts,\n keyResolver: opts?.keyResolver ?? keyResolver,\n revocationStore,\n checkRevocation: opts?.checkRevocation ?? true,\n });\n },\n\n async generateKeyPair(\n algorithm?: 'EdDSA' | 'ES256'\n ): Promise<CryptoKeyPair> {\n return generateKeyPair(algorithm);\n },\n\n checkScope(\n token: APOAToken,\n service: string,\n action: string\n ): ScopeCheckResult {\n return checkScope(token, service, action);\n },\n\n checkConstraint(\n token: APOAToken,\n service: string,\n constraint: string\n ): ScopeCheckResult {\n return checkConstraint(token, service, constraint);\n },\n\n async authorize(\n token: APOAToken,\n service: string,\n action: string,\n opts?: Omit<AuthorizeOptions, 'revocationStore' | 'auditStore'>\n ): Promise<AuthorizationResult> {\n return authorize(token, service, action, {\n ...opts,\n revocationStore,\n auditStore,\n });\n },\n\n async delegate(\n parentToken: APOAToken,\n childDef: DelegationDefinition,\n opts?: SigningOptions\n ): Promise<APOAToken> {\n return delegate(parentToken, childDef, mergeSigningOptions(opts));\n },\n\n async verifyChain(\n chain: DelegationChain\n ): Promise<ChainVerificationResult> {\n return verifyChain(chain, revocationStore);\n },\n\n async revoke(\n tokenId: string,\n opts: RevocationOptions\n ): Promise<RevocationRecord> {\n return revoke(tokenId, opts, revocationStore);\n },\n\n async isRevoked(tokenId: string): Promise<boolean> {\n return isRevoked(tokenId, revocationStore);\n },\n\n async logAction(\n tokenId: string,\n entry: Omit<AuditEntry, 'tokenId' | 'timestamp'>\n ): Promise<void> {\n return logAction(tokenId, entry, auditStore);\n },\n\n async getAuditTrail(\n tokenId: string,\n opts?: AuditQueryOptions\n ): Promise<AuditEntry[]> {\n return getAuditTrail(tokenId, opts, auditStore);\n },\n\n async getAuditTrailByService(\n service: string,\n opts?: AuditQueryOptions\n ): Promise<AuditEntry[]> {\n return getAuditTrailByService(service, opts, auditStore);\n },\n };\n}\n"],"mappings":"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","names":["generateKeyPair","defaultStore","jose","validateMetadata","payload","jose","generateKeyPair"]}
|
|
1
|
+
{"version":3,"sources":["../src/utils/errors.ts","../src/utils/crypto.ts","../src/utils/time.ts","../src/scope/patterns.ts","../src/revocation/store.ts","../src/audit/store.ts","../src/scope/check.ts","../src/token/parse.ts","../src/revocation/revoke.ts","../src/audit/log.ts","../src/audit/trail.ts","../src/token/sign.ts","../src/token/create.ts","../src/token/validate.ts","../src/revocation/cascade.ts","../src/scope/attenuate.ts","../src/delegation/chain.ts","../src/delegation/verify.ts","../src/delegation/ancestors.ts","../src/jwks/index.ts","../src/client.ts","../src/apoa.ts"],"sourcesContent":["/** Base error class for all APOA errors. */\nexport class APOAError extends Error {\n code: string;\n\n constructor(message: string, code: string) {\n super(message);\n this.code = code;\n this.name = 'APOAError';\n }\n}\n\n/** Thrown when a token has expired. */\nexport class TokenExpiredError extends APOAError {\n expiredAt: Date;\n\n constructor(message: string, expiredAt: Date) {\n super(message, 'TOKEN_EXPIRED');\n this.expiredAt = expiredAt;\n this.name = 'TokenExpiredError';\n }\n}\n\n/** Thrown when an action is outside the token's authorized scopes. */\nexport class ScopeViolationError extends APOAError {\n requestedScope: string;\n availableScopes: string[];\n\n constructor(message: string, requestedScope: string, availableScopes: string[]) {\n super(message, 'SCOPE_VIOLATION');\n this.requestedScope = requestedScope;\n this.availableScopes = availableScopes;\n this.name = 'ScopeViolationError';\n }\n}\n\n/** Thrown when a delegated token tries to exceed parent permissions. */\nexport class AttenuationViolationError extends APOAError {\n parentScope: string[];\n requestedScope: string[];\n\n constructor(message: string, parentScope: string[], requestedScope: string[]) {\n super(message, 'ATTENUATION_VIOLATION');\n this.parentScope = parentScope;\n this.requestedScope = requestedScope;\n this.name = 'AttenuationViolationError';\n }\n}\n\n/** Thrown when trying to use a revoked token. */\nexport class RevocationError extends APOAError {\n revokedAt: Date;\n revokedBy: string;\n\n constructor(message: string, revokedAt: Date, revokedBy: string) {\n super(message, 'TOKEN_REVOKED');\n this.revokedAt = revokedAt;\n this.revokedBy = revokedBy;\n this.name = 'RevocationError';\n }\n}\n\n/** Thrown when delegation chain verification fails. */\nexport class ChainVerificationError extends APOAError {\n failedAt: number;\n reason: string;\n\n constructor(message: string, failedAt: number, reason: string) {\n super(message, 'CHAIN_INVALID');\n this.failedAt = failedAt;\n this.reason = reason;\n this.name = 'ChainVerificationError';\n }\n}\n\n/** Thrown when token metadata fails validation. */\nexport class MetadataValidationError extends APOAError {\n field?: string;\n\n constructor(message: string, field?: string) {\n super(message, 'METADATA_INVALID');\n this.field = field;\n this.name = 'MetadataValidationError';\n }\n}\n\n/** Thrown when a hard rule is violated. */\nexport class RuleEnforcementError extends APOAError {\n ruleId: string;\n enforcement: 'hard' = 'hard' as const;\n\n constructor(message: string, ruleId: string) {\n super(message, 'RULE_VIOLATED');\n this.ruleId = ruleId;\n this.name = 'RuleEnforcementError';\n }\n}\n\n/** Thrown when a definition fails validation. */\nexport class DefinitionValidationError extends APOAError {\n errors: string[];\n\n constructor(message: string, errors: string[]) {\n super(message, 'DEFINITION_INVALID');\n this.errors = errors;\n this.name = 'DefinitionValidationError';\n }\n}\n","import * as jose from 'jose';\nimport type { SigningOptions } from '../types.js';\n\n/**\n * Generate an Ed25519 or ES256 key pair for signing and verifying tokens.\n */\nexport async function generateKeyPair(\n algorithm: 'EdDSA' | 'ES256' = 'EdDSA'\n): Promise<CryptoKeyPair> {\n const alg = algorithm === 'EdDSA' ? 'EdDSA' : 'ES256';\n const { publicKey, privateKey } = await jose.generateKeyPair(alg, {\n extractable: true,\n });\n return { publicKey, privateKey } as CryptoKeyPair;\n}\n\n/**\n * Sign a payload, producing a compact JWS string.\n */\nexport async function sign(\n payload: Record<string, unknown>,\n options: SigningOptions\n): Promise<string> {\n const alg = options.algorithm === 'ES256' ? 'ES256' : 'EdDSA';\n const header: Record<string, unknown> = { alg };\n if (options.kid) {\n header.kid = options.kid;\n }\n\n const jws = await new jose.CompactSign(\n new TextEncoder().encode(JSON.stringify(payload))\n )\n .setProtectedHeader(header as jose.CompactJWSHeaderParameters)\n .sign(options.privateKey);\n\n return jws;\n}\n\n/**\n * Verify a compact JWS string and return the decoded payload.\n */\nexport async function verify(\n token: string,\n key: CryptoKey\n): Promise<Record<string, unknown>> {\n const { payload } = await jose.compactVerify(token, key);\n return JSON.parse(new TextDecoder().decode(payload));\n}\n","const DEFAULT_CLOCK_SKEW = 30;\nconst MAX_CLOCK_SKEW = 300;\n\n/**\n * Normalize clock skew to a valid value in seconds.\n */\nfunction normalizeSkew(clockSkew?: number): number {\n if (clockSkew === undefined) return DEFAULT_CLOCK_SKEW;\n if (clockSkew < 0) return 0;\n return Math.min(clockSkew, MAX_CLOCK_SKEW);\n}\n\n/**\n * Parse a date value (Date object or ISO string) into a Date.\n */\nfunction toDate(value: Date | string): Date {\n return value instanceof Date ? value : new Date(value);\n}\n\n/**\n * Check if a token/date has expired, accounting for clock skew.\n * Returns true if the current time is past the expiration (plus tolerance).\n */\nexport function isExpired(\n expires: Date | string,\n clockSkew?: number,\n now?: Date\n): boolean {\n const expiresDate = toDate(expires);\n const skew = normalizeSkew(clockSkew);\n const currentTime = now ?? new Date();\n return currentTime.getTime() > expiresDate.getTime() + skew * 1000;\n}\n\n/**\n * Check if the current time is before the notBefore date, accounting for clock skew.\n * Returns true if it's too early to use this token.\n */\nexport function isBeforeNotBefore(\n notBefore: Date | string,\n clockSkew?: number,\n now?: Date\n): boolean {\n const notBeforeDate = toDate(notBefore);\n const skew = normalizeSkew(clockSkew);\n const currentTime = now ?? new Date();\n return currentTime.getTime() < notBeforeDate.getTime() - skew * 1000;\n}\n","/**\n * Parse a scope string into its segments.\n * e.g., \"appointments:read\" → [\"appointments\", \"read\"]\n */\nexport function parseScope(scope: string): string[] {\n if (!scope) return [];\n return scope.split(':');\n}\n\n/**\n * Check if a scope pattern matches a requested scope.\n *\n * Rules:\n * 1. Empty pattern or empty requested string never matches (a vacuous match\n * on `''` would let a token with `scopes: ['']` authorize an empty\n * action, or vice versa).\n * 2. Root wildcard \"*\" matches everything (non-empty)\n * 3. Exact match: \"appointments:read\" matches \"appointments:read\"\n * 4. Wildcard at level: \"appointments:*\" matches \"appointments:read\"\n * but NOT \"appointments:read:summary\" (wildcards don't cross levels)\n * 5. Segment-by-segment matching with wildcard support at each level\n */\nexport function matchScope(pattern: string, requested: string): boolean {\n if (!pattern || !requested) return false;\n\n // Root wildcard matches everything (non-empty, handled above).\n if (pattern === '*') return true;\n\n const patternParts = parseScope(pattern);\n const requestedParts = parseScope(requested);\n\n // Different number of segments — no match (wildcards don't cross levels)\n if (patternParts.length !== requestedParts.length) return false;\n\n // Match segment by segment. Empty segments (e.g. \"foo::bar\") never match.\n for (let i = 0; i < patternParts.length; i++) {\n if (patternParts[i] === '*') continue;\n if (!patternParts[i] || !requestedParts[i]) return false;\n if (patternParts[i] !== requestedParts[i]) return false;\n }\n\n return true;\n}\n","import type { RevocationRecord, RevocationStore } from '../types.js';\n\n/**\n * In-memory revocation store for dev/testing.\n * Data is lost when the process exits.\n */\nexport class MemoryRevocationStore implements RevocationStore {\n private records: Map<string, RevocationRecord> = new Map();\n\n async add(record: RevocationRecord): Promise<void> {\n this.records.set(record.tokenId, record);\n }\n\n async check(tokenId: string): Promise<RevocationRecord | null> {\n return this.records.get(tokenId) ?? null;\n }\n\n async list(principalId: string): Promise<RevocationRecord[]> {\n const results: RevocationRecord[] = [];\n for (const record of this.records.values()) {\n if (record.revokedBy === principalId) {\n results.push(record);\n }\n }\n return results;\n }\n}\n","import type { AuditEntry, AuditQueryOptions, AuditStore } from '../types.js';\n\n/**\n * In-memory audit store for dev/testing.\n * Data is lost when the process exits.\n */\nexport class MemoryAuditStore implements AuditStore {\n private entries: AuditEntry[] = [];\n\n async append(entry: AuditEntry): Promise<void> {\n this.entries.push(entry);\n }\n\n async query(tokenId: string, options?: AuditQueryOptions): Promise<AuditEntry[]> {\n const results = this.entries.filter((e) => e.tokenId === tokenId);\n return applyFilters(results, options);\n }\n\n async queryByService(\n service: string,\n options?: AuditQueryOptions\n ): Promise<AuditEntry[]> {\n const results = this.entries.filter((e) => e.service === service);\n return applyFilters(results, options);\n }\n}\n\nfunction applyFilters(\n entries: AuditEntry[],\n options?: AuditQueryOptions\n): AuditEntry[] {\n\n let results = entries;\n\n if (options?.from) {\n const from = options.from.getTime();\n results = results.filter((e) => e.timestamp.getTime() >= from);\n }\n if (options?.to) {\n const to = options.to.getTime();\n results = results.filter((e) => e.timestamp.getTime() <= to);\n }\n if (options?.action) {\n results = results.filter((e) => e.action === options.action);\n }\n if (options?.service) {\n results = results.filter((e) => e.service === options.service);\n }\n if (options?.result) {\n results = results.filter((e) => e.result === options.result);\n }\n\n const offset = options?.offset ?? 0;\n const limit = options?.limit ?? 100;\n results = results.slice(offset, offset + limit);\n\n return results;\n}\n","import type {\n APOAToken,\n AuthorizeOptions,\n AuthorizationResult,\n RuleViolation,\n ScopeCheckResult,\n} from '../types.js';\nimport { matchScope } from './patterns.js';\n\n/**\n * Check if an action is allowed under a token's scopes for a given service.\n * Synchronous — no rules, no revocation, just scope matching.\n */\nexport function checkScope(\n token: APOAToken,\n service: string,\n action: string\n): ScopeCheckResult {\n const serviceAuth = token.definition.services.find(\n (s) => s.service === service\n );\n\n if (!serviceAuth) {\n return {\n allowed: false,\n reason: `service '${service}' not found in token`,\n };\n }\n\n for (const scope of serviceAuth.scopes) {\n if (matchScope(scope, action)) {\n return {\n allowed: true,\n reason: `matched scope '${scope}'`,\n matchedScope: scope,\n };\n }\n }\n\n return {\n allowed: false,\n reason: `scope '${action}' not in authorized scopes`,\n };\n}\n\n/**\n * Check a specific constraint on a service.\n * Returns allowed: false if the constraint is explicitly set to false.\n * Returns allowed: true if the constraint is not set or is truthy.\n */\nexport function checkConstraint(\n token: APOAToken,\n service: string,\n constraint: string\n): ScopeCheckResult {\n const serviceAuth = token.definition.services.find(\n (s) => s.service === service\n );\n\n if (!serviceAuth) {\n return {\n allowed: false,\n reason: `service '${service}' not found in token`,\n };\n }\n\n if (!serviceAuth.constraints) {\n return {\n allowed: true,\n reason: `no constraints defined for service '${service}'`,\n };\n }\n\n const value = serviceAuth.constraints[constraint];\n\n if (value === undefined) {\n return {\n allowed: true,\n reason: `constraint '${constraint}' not defined`,\n };\n }\n\n if (value === false) {\n return {\n allowed: false,\n reason: `constraint '${constraint}' is set to false`,\n constraint,\n };\n }\n\n return {\n allowed: true,\n reason: `constraint '${constraint}' is set to ${JSON.stringify(value)}`,\n };\n}\n\n/**\n * One-stop authorization check: revocation + scope + constraints + rules.\n *\n * Enforcement order:\n * 1. Check revocation (is the token still alive?)\n * 2. Check scope (is the action in the authorized scope set?)\n * 3. Check constraints (only the action's top-level segment is checked\n * against constraint keys — e.g. action \"signing:submit\" checks\n * constraint \"signing\". Use checkConstraint() for explicit checks.)\n * 4. Check hard rules (hard rules whose id appears as a prefix of the\n * action → deny. e.g. rule \"no-messaging\" blocks \"messaging:send\")\n * 5. Check soft rules (all soft rules → log violation + continue)\n */\nexport async function authorize(\n token: APOAToken,\n service: string,\n action: string,\n options?: AuthorizeOptions\n): Promise<AuthorizationResult> {\n // 1. Check revocation\n if (options?.revocationStore) {\n const record = await options.revocationStore.check(token.jti);\n if (record) {\n return {\n authorized: false,\n reason: 'token has been revoked',\n checks: { revoked: true },\n };\n }\n }\n\n // 2. Check scope\n const scopeResult = checkScope(token, service, action);\n if (!scopeResult.allowed) {\n return {\n authorized: false,\n reason: scopeResult.reason,\n checks: { revoked: false, scopeAllowed: false },\n };\n }\n\n // 3. Check constraints — only deny if the action's top-level segment\n // matches a constraint key that is set to false.\n // e.g. action \"signing:submit\" is blocked by constraint { signing: false }\n // but action \"appointments:read\" is NOT blocked by { signing: false }\n const serviceAuth = token.definition.services.find(\n (s) => s.service === service\n );\n if (serviceAuth?.constraints) {\n const actionSegments = action.split(':');\n for (const [key, value] of Object.entries(serviceAuth.constraints)) {\n if (value === false && actionSegments.includes(key)) {\n return {\n authorized: false,\n reason: `constraint '${key}' is set to false`,\n checks: { revoked: false, scopeAllowed: true, constraintsPassed: false },\n };\n }\n }\n }\n\n // 4 & 5. Check rules\n const rules = token.definition.rules;\n const violations: RuleViolation[] = [];\n\n if (rules && rules.length > 0) {\n // 4. Hard rules — deny if the action matches the rule.\n // Matching: extract the key from the rule id (strip \"no-\" prefix if present)\n // and check if it appears as a SEGMENT in the action (split on ':').\n // e.g. rule \"no-messaging\" → key \"messaging\" → blocks \"messaging:send\"\n // e.g. rule \"no-signing\" → key \"signing\" → blocks \"signing:submit\"\n // e.g. rule \"no-signing\" → key \"signing\" → does NOT block \"appointments:read\"\n // e.g. rule \"no-read\" → key \"read\" → does NOT block \"threading:update\"\n for (const rule of rules) {\n if (rule.enforcement === 'hard') {\n const ruleKey = rule.id.startsWith('no-') ? rule.id.slice(3) : rule.id;\n const actionSegments = action.toLowerCase().split(':');\n if (actionSegments.includes(ruleKey.toLowerCase())) {\n return {\n authorized: false,\n reason: `hard rule '${rule.id}' violated`,\n checks: {\n revoked: false,\n scopeAllowed: true,\n constraintsPassed: true,\n rulesPassed: false,\n },\n };\n }\n }\n }\n\n // 5. Soft rules — log violations, invoke callbacks, continue\n for (const rule of rules) {\n if (rule.enforcement === 'soft') {\n const violation: RuleViolation = {\n ruleId: rule.id,\n tokenId: token.jti,\n action,\n service,\n timestamp: new Date(),\n details: rule.description,\n };\n violations.push(violation);\n\n // Log to audit store if available\n if (options?.auditStore) {\n await options.auditStore.append({\n tokenId: token.jti,\n timestamp: violation.timestamp,\n action,\n service,\n result: 'escalated',\n details: { ruleId: rule.id, ruleDescription: rule.description },\n });\n }\n\n // Invoke onViolation callback if provided\n if (rule.onViolation) {\n await rule.onViolation(violation);\n }\n }\n }\n }\n\n return {\n authorized: true,\n checks: {\n revoked: false,\n scopeAllowed: true,\n constraintsPassed: true,\n rulesPassed: true,\n },\n violations: violations.length > 0 ? violations : undefined,\n };\n}\n","import type { APOADefinition } from '../types.js';\nimport { DefinitionValidationError } from '../utils/errors.js';\n\n/**\n * Parse a YAML or JSON definition string into an APOADefinition.\n * Auto-detects format: starts with '{' = JSON, otherwise YAML.\n * Validates required fields, metadata constraints, browser mode config,\n * and legal framework fields. Throws DefinitionValidationError with all\n * problems found.\n */\nexport function parseDefinition(\n input: string,\n format?: 'yaml' | 'json'\n): APOADefinition {\n const detectedFormat = format ?? (input.trimStart().startsWith('{') ? 'json' : 'yaml');\n let raw: unknown;\n\n try {\n if (detectedFormat === 'json') {\n raw = JSON.parse(input);\n } else {\n // Lazy-load yaml to keep it optional\n throw new Error('YAML parsing requires the \"yaml\" package. Use JSON format or install \"yaml\".');\n }\n } catch (err) {\n if (err instanceof SyntaxError) {\n throw new DefinitionValidationError('Failed to parse definition', [\n `Invalid ${detectedFormat}: ${err.message}`,\n ]);\n }\n throw err;\n }\n\n return validateDefinition(raw);\n}\n\n/**\n * Validate a parsed object as an APOADefinition.\n * Returns the validated definition or throws DefinitionValidationError.\n */\nfunction validateDefinition(raw: unknown): APOADefinition {\n const errors: string[] = [];\n const warnings: string[] = [];\n\n if (!raw || typeof raw !== 'object') {\n throw new DefinitionValidationError('Definition must be an object', [\n 'Definition must be an object',\n ]);\n }\n\n const obj = raw as Record<string, unknown>;\n\n // Required fields\n if (!obj.principal || typeof obj.principal !== 'object') {\n errors.push(\"missing required field 'principal'\");\n } else {\n const p = obj.principal as Record<string, unknown>;\n if (!p.id || typeof p.id !== 'string') {\n errors.push(\"'principal.id' must be a non-empty string\");\n }\n }\n\n if (!obj.agent || typeof obj.agent !== 'object') {\n errors.push(\"missing required field 'agent'\");\n } else {\n const a = obj.agent as Record<string, unknown>;\n if (!a.id || typeof a.id !== 'string') {\n errors.push(\"'agent.id' must be a non-empty string\");\n }\n }\n\n if (!obj.services || !Array.isArray(obj.services) || obj.services.length === 0) {\n errors.push(\"'services' must be a non-empty array\");\n } else {\n for (let i = 0; i < obj.services.length; i++) {\n const svc = obj.services[i] as Record<string, unknown>;\n if (!svc.service || typeof svc.service !== 'string') {\n errors.push(`services[${i}].service must be a non-empty string`);\n }\n if (!svc.scopes || !Array.isArray(svc.scopes) || svc.scopes.length === 0) {\n errors.push(`services[${i}].scopes must be a non-empty array`);\n } else {\n for (let j = 0; j < svc.scopes.length; j++) {\n const s = svc.scopes[j];\n if (typeof s !== 'string' || s.length === 0) {\n errors.push(`services[${i}].scopes[${j}] must be a non-empty string`);\n }\n }\n }\n\n // Phase 2b: Browser mode validation\n validateServiceAccessMode(svc, i, errors, warnings);\n }\n }\n\n if (obj.expires === undefined || obj.expires === null) {\n errors.push(\"missing required field 'expires'\");\n }\n\n // Metadata validation\n if (obj.metadata !== undefined) {\n validateMetadata(obj.metadata, errors);\n }\n\n // Phase 2b: AgentProvider validation\n if (obj.agentProvider !== undefined) {\n validateAgentProvider(obj.agentProvider, errors);\n }\n\n // Phase 2b: Legal framework validation\n if (obj.legal !== undefined) {\n validateLegalFramework(obj.legal, errors);\n }\n\n if (errors.length > 0) {\n const err = new DefinitionValidationError(\n `Invalid definition: ${errors.length} problem(s) found`,\n errors\n );\n // Attach warnings for callers that want them\n (err as DefinitionValidationError & { warnings?: string[] }).warnings = warnings;\n throw err;\n }\n\n // Convert date strings to Date objects where needed\n const def = obj as unknown as APOADefinition;\n if (typeof def.expires === 'string') {\n def.expires = def.expires; // keep as string — the spec allows Date | string\n }\n if (typeof def.notBefore === 'string') {\n def.notBefore = def.notBefore;\n }\n\n return def;\n}\n\nfunction validateMetadata(metadata: unknown, errors: string[]): void {\n if (typeof metadata !== 'object' || metadata === null || Array.isArray(metadata)) {\n errors.push(\"'metadata' must be a plain object\");\n return;\n }\n\n const keys = Object.keys(metadata as Record<string, unknown>);\n if (keys.length > 20) {\n errors.push(`metadata has ${keys.length} keys (max 20)`);\n }\n\n const serialized = JSON.stringify(metadata);\n if (serialized.length > 1024) {\n errors.push(\n `metadata serialized size is ${serialized.length} bytes (max 1024)`\n );\n }\n\n const record = metadata as Record<string, unknown>;\n for (const key of keys) {\n // Keys starting with _ are reserved for SDK use (e.g., _delegationDepth).\n // Reject them in parsed definitions to prevent forgery.\n if (key.startsWith('_')) {\n errors.push(\n `metadata key '${key}' uses reserved prefix '_' (reserved for SDK internal use)`\n );\n }\n const value = record[key];\n if (\n value !== null &&\n typeof value !== 'string' &&\n typeof value !== 'number' &&\n typeof value !== 'boolean'\n ) {\n errors.push(\n `metadata['${key}'] has invalid type '${typeof value}' (must be string | number | boolean | null)`\n );\n }\n }\n}\n\nfunction validateServiceAccessMode(\n svc: Record<string, unknown>,\n index: number,\n errors: string[],\n warnings: string[]\n): void {\n const accessMode = svc.accessMode as string | undefined;\n\n if (accessMode === 'browser') {\n if (!svc.browserConfig || typeof svc.browserConfig !== 'object') {\n errors.push(\n `services[${index}] has accessMode 'browser' but no browserConfig. ` +\n `Browser-based access requires explicit URL restrictions and a credential vault reference.`\n );\n return;\n }\n\n const bc = svc.browserConfig as Record<string, unknown>;\n\n if (!bc.allowedUrls || !Array.isArray(bc.allowedUrls) || bc.allowedUrls.length === 0) {\n errors.push(\n `services[${index}].browserConfig.allowedUrls must be a non-empty array`\n );\n }\n\n if (!bc.credentialVaultRef || typeof bc.credentialVaultRef !== 'string') {\n errors.push(\n `services[${index}].browserConfig.credentialVaultRef must be a non-empty string`\n );\n }\n\n if (bc.maxSessionDuration !== undefined) {\n if (typeof bc.maxSessionDuration !== 'number' || bc.maxSessionDuration > 86400) {\n errors.push(\n `services[${index}].browserConfig.maxSessionDuration must be <= 86400 seconds`\n );\n }\n }\n }\n\n if (accessMode === 'api' && svc.browserConfig) {\n warnings.push(\n `services[${index}] has accessMode 'api' but browserConfig is present (will be ignored)`\n );\n }\n}\n\nfunction validateAgentProvider(provider: unknown, errors: string[]): void {\n if (typeof provider !== 'object' || provider === null) {\n errors.push(\"'agentProvider' must be an object\");\n return;\n }\n\n const p = provider as Record<string, unknown>;\n if (!p.name || typeof p.name !== 'string') {\n errors.push(\"'agentProvider.name' is required and must be a non-empty string\");\n }\n}\n\nfunction validateLegalFramework(legal: unknown, errors: string[]): void {\n if (typeof legal !== 'object' || legal === null) {\n errors.push(\"'legal' must be an object\");\n return;\n }\n\n const l = legal as Record<string, unknown>;\n\n if (l.model !== 'provider-as-agent') {\n errors.push(\"'legal.model' must be 'provider-as-agent'\");\n }\n\n if (l.jurisdiction !== undefined) {\n if (typeof l.jurisdiction !== 'string') {\n errors.push(\"'legal.jurisdiction' must be a string\");\n } else {\n // ISO 3166 format: 2-letter country code, optionally followed by -subdivision\n // Examples: \"US\", \"US-CA\", \"GB\", \"DE\"\n const iso3166Pattern = /^[A-Z]{2}(-[A-Z0-9]{1,3})?$/;\n if (!iso3166Pattern.test(l.jurisdiction)) {\n errors.push(\n `'legal.jurisdiction' must be ISO 3166 format (e.g., \"US\", \"US-CA\", \"GB\"), got '${l.jurisdiction}'`\n );\n }\n }\n }\n}\n","import type {\n RevocationOptions,\n RevocationRecord,\n RevocationStore,\n} from '../types.js';\n\n/**\n * Revoke a token. The caller MUST supply a RevocationStore so the revocation\n * is durable and visible to other parts of the system. There is no default\n * store: a process-shared singleton would silently diverge from the store\n * used by `createClient()` and any caller-supplied store, producing\n * \"succeeded but never enforced\" revocations.\n */\nexport async function revoke(\n tokenId: string,\n options: RevocationOptions,\n store: RevocationStore\n): Promise<RevocationRecord> {\n const record: RevocationRecord = {\n tokenId,\n revokedAt: new Date(),\n revokedBy: options.revokedBy,\n reason: options.reason,\n cascaded: [],\n };\n\n await store.add(record);\n return record;\n}\n\n/**\n * Check if a token has been revoked. Caller must supply the same\n * RevocationStore that revoke() wrote to.\n */\nexport async function isRevoked(\n tokenId: string,\n store: RevocationStore\n): Promise<boolean> {\n const record = await store.check(tokenId);\n return record !== null;\n}\n","import type { AuditEntry, AuditStore } from '../types.js';\nimport { MemoryAuditStore } from './store.js';\n\nconst defaultStore = new MemoryAuditStore();\n\n/**\n * Log an action against a token.\n */\nexport async function logAction(\n tokenId: string,\n entry: Omit<AuditEntry, 'tokenId' | 'timestamp'>,\n store?: AuditStore\n): Promise<void> {\n const s = store ?? defaultStore;\n\n const fullEntry: AuditEntry = {\n ...entry,\n tokenId,\n timestamp: new Date(),\n };\n\n await s.append(fullEntry);\n}\n","import type { AuditEntry, AuditQueryOptions, AuditStore } from '../types.js';\nimport { MemoryAuditStore } from './store.js';\n\nconst defaultStore = new MemoryAuditStore();\n\n/**\n * Get the audit trail for a token.\n */\nexport async function getAuditTrail(\n tokenId: string,\n options?: AuditQueryOptions,\n store?: AuditStore\n): Promise<AuditEntry[]> {\n const s = store ?? defaultStore;\n return s.query(tokenId, options);\n}\n\n/**\n * Get the audit trail for a service — across all tokens.\n */\nexport async function getAuditTrailByService(\n service: string,\n options?: AuditQueryOptions,\n store?: AuditStore\n): Promise<AuditEntry[]> {\n const s = store ?? defaultStore;\n return s.queryByService(service, options);\n}\n","import * as jose from 'jose';\nimport type { SigningOptions } from '../types.js';\n\n/**\n * Sign an APOA token payload as a compact JWS.\n * Embeds `kid` in the JWT header when provided.\n * Supports EdDSA (default) and ES256.\n */\nexport async function signToken(\n payload: Record<string, unknown>,\n options: SigningOptions\n): Promise<string> {\n const alg = options.algorithm === 'ES256' ? 'ES256' : 'EdDSA';\n\n const header: jose.CompactJWSHeaderParameters = { alg };\n if (options.kid) {\n header.kid = options.kid;\n }\n\n const jws = await new jose.CompactSign(\n new TextEncoder().encode(JSON.stringify(payload))\n )\n .setProtectedHeader(header)\n .sign(options.privateKey);\n\n return jws;\n}\n\n/**\n * Decode a compact JWS protected header without verifying the signature.\n * Used to extract `kid` and `alg` for key resolution.\n */\nexport function decodeHeader(\n token: string\n): Record<string, unknown> {\n const [headerB64] = token.split('.');\n if (!headerB64) throw new Error('Invalid JWS: missing header');\n return JSON.parse(\n new TextDecoder().decode(jose.base64url.decode(headerB64))\n );\n}\n\n/**\n * Verify a compact JWS and return the decoded payload.\n */\nexport async function verifySignature(\n token: string,\n key: CryptoKey\n): Promise<Record<string, unknown>> {\n const { payload } = await jose.compactVerify(token, key);\n return JSON.parse(new TextDecoder().decode(payload));\n}\n","import type { APOADefinition, APOAToken, SigningOptions } from '../types.js';\nimport { MetadataValidationError } from '../utils/errors.js';\nimport { signToken } from './sign.js';\n\n/**\n * Create an APOA token from a definition.\n * Generates a UUID for jti, validates metadata, derives audience,\n * warns at 4KB, rejects above 8KB.\n */\nexport async function createToken(\n definition: APOADefinition,\n options: SigningOptions,\n parentTokenId?: string\n): Promise<APOAToken> {\n // Validate metadata if present\n if (definition.metadata) {\n validateMetadata(definition.metadata);\n }\n\n const jti = crypto.randomUUID();\n const issuedAt = new Date();\n const issuer = definition.principal.id;\n const audience = definition.services.map((s) => s.service);\n\n // Build the payload that gets signed\n const payload: Record<string, unknown> = {\n jti,\n iss: issuer,\n aud: audience,\n iat: Math.floor(issuedAt.getTime() / 1000),\n exp: Math.floor(\n (typeof definition.expires === 'string'\n ? new Date(definition.expires)\n : definition.expires\n ).getTime() / 1000\n ),\n definition: {\n ...serializeDefinition(definition),\n ...(parentTokenId ? { parentToken: parentTokenId } : {}),\n },\n };\n\n if (definition.notBefore) {\n payload.nbf = Math.floor(\n (typeof definition.notBefore === 'string'\n ? new Date(definition.notBefore)\n : definition.notBefore\n ).getTime() / 1000\n );\n }\n\n // Sign the token\n const raw = await signToken(payload, options);\n\n // Size checks\n const sizeBytes = new TextEncoder().encode(raw).length;\n if (sizeBytes > 8192) {\n throw new MetadataValidationError(\n `Token size is ${sizeBytes} bytes (max 8192). Issue multiple tokens for large authorization surfaces.`\n );\n }\n\n const token: APOAToken = {\n jti,\n definition,\n issuedAt,\n signature: raw.split('.')[2],\n issuer,\n audience,\n parentToken: parentTokenId,\n raw,\n };\n\n return token;\n}\n\nfunction validateMetadata(metadata: Record<string, unknown>): void {\n const keys = Object.keys(metadata);\n if (keys.length > 20) {\n throw new MetadataValidationError(\n `Metadata has ${keys.length} keys (max 20)`\n );\n }\n\n const serialized = JSON.stringify(metadata);\n if (serialized.length > 1024) {\n throw new MetadataValidationError(\n `Metadata serialized size is ${serialized.length} bytes (max 1024)`\n );\n }\n\n for (const key of keys) {\n const value = metadata[key];\n if (\n value !== null &&\n typeof value !== 'string' &&\n typeof value !== 'number' &&\n typeof value !== 'boolean'\n ) {\n throw new MetadataValidationError(\n `Metadata key '${key}' has invalid type '${typeof value}'`,\n key\n );\n }\n }\n}\n\n/**\n * Serialize a definition for inclusion in the JWT payload.\n * Converts Date objects to ISO strings for JSON compatibility.\n */\nfunction serializeDefinition(\n def: APOADefinition\n): Record<string, unknown> {\n return {\n ...def,\n expires:\n def.expires instanceof Date\n ? def.expires.toISOString()\n : def.expires,\n notBefore:\n def.notBefore instanceof Date\n ? def.notBefore.toISOString()\n : def.notBefore,\n // Strip non-serializable onViolation callbacks from rules\n rules: def.rules?.map(({ onViolation: _, ...rest }) => rest),\n };\n}\n","import type {\n APOAToken,\n ValidationOptions,\n ValidationResult,\n} from '../types.js';\nimport { isExpired, isBeforeNotBefore } from '../utils/time.js';\nimport { decodeHeader, verifySignature } from './sign.js';\n\n/**\n * Validate a token — check signature, expiration, structure, revocation.\n * Returns a detailed result with all errors found.\n *\n * Accepts either a raw JWT string or an APOAToken object.\n * When given a string, decodes and verifies the signature.\n * When given an APOAToken, uses the .raw field for signature verification.\n */\nexport async function validateToken(\n token: string | APOAToken,\n options: ValidationOptions\n): Promise<ValidationResult> {\n const errors: string[] = [];\n const warnings: string[] = [];\n let parsedToken: APOAToken | undefined;\n\n const rawJwt = typeof token === 'string' ? token : token.raw;\n\n // --- Key resolution ---\n let publicKey: CryptoKey | undefined;\n\n if (options.publicKey) {\n publicKey = options.publicKey;\n } else if (options.keyResolver) {\n try {\n const header = decodeHeader(rawJwt);\n const kid = header.kid as string | undefined;\n if (kid) {\n const resolved = await options.keyResolver.resolve(kid);\n if (resolved) {\n publicKey = resolved;\n } else {\n errors.push(`Key resolver returned null for kid '${kid}'`);\n }\n } else {\n errors.push('Token has no kid in header and keyResolver requires one');\n }\n } catch {\n errors.push('Failed to decode token header for key resolution');\n }\n } else if (options.publicKeyResolver) {\n // Need issuer from the payload — decode without verification first\n try {\n const header = decodeHeader(rawJwt);\n // Decode payload without verification to get issuer\n const payloadB64 = rawJwt.split('.')[1];\n if (payloadB64) {\n const payloadJson = new TextDecoder().decode(\n base64urlDecode(payloadB64)\n );\n const payload = JSON.parse(payloadJson);\n const issuer = payload.iss as string | undefined;\n if (issuer) {\n publicKey = await options.publicKeyResolver(issuer);\n } else {\n errors.push('Token has no issuer (iss) claim for publicKeyResolver');\n }\n }\n } catch {\n errors.push('Failed to decode token for issuer-based key resolution');\n }\n } else {\n errors.push(\n 'No key provided: supply publicKey, keyResolver, or publicKeyResolver'\n );\n }\n\n // --- Algorithm policy check ---\n // The token's alg header must be in the permitted list. APOA's conformance\n // baseline is EdDSA + ES256; callers can pin to a single algorithm to\n // enforce an org policy (e.g. EdDSA-only).\n const permittedAlgorithms = options.algorithms ?? ['EdDSA', 'ES256'];\n let headerAlg: string | undefined;\n try {\n const header = decodeHeader(rawJwt);\n headerAlg = typeof header.alg === 'string' ? header.alg : undefined;\n } catch {\n // Header decode already produced an error above when key resolution ran;\n // if no resolver was used we still want to surface the malformed header.\n }\n if (headerAlg && !permittedAlgorithms.includes(headerAlg as 'EdDSA' | 'ES256')) {\n errors.push(\n `Token alg '${headerAlg}' is not in the permitted list [${permittedAlgorithms.join(', ')}]`\n );\n }\n\n // --- Signature verification ---\n let payload: Record<string, unknown> | undefined;\n let signatureVerified = false;\n\n if (publicKey && headerAlg && permittedAlgorithms.includes(headerAlg as 'EdDSA' | 'ES256')) {\n try {\n payload = await verifySignature(rawJwt, publicKey);\n signatureVerified = true;\n } catch {\n errors.push('Signature verification failed');\n }\n } else if (publicKey && !headerAlg) {\n // Header had no alg at all — still attempt verification so jose returns\n // a meaningful error, but flag the missing alg.\n errors.push('Token header missing alg');\n }\n\n // If we couldn't verify, decode payload for structural checks only.\n // result.token will NOT be populated (prevents operating on forged data).\n if (!payload) {\n try {\n const payloadB64 = rawJwt.split('.')[1];\n if (payloadB64) {\n payload = JSON.parse(\n new TextDecoder().decode(base64urlDecode(payloadB64))\n );\n }\n } catch {\n // Can't even decode the payload — nothing more to check\n }\n }\n\n if (!payload) {\n return { valid: false, errors: errors.length > 0 ? errors : ['Unable to decode token'], warnings };\n }\n\n // --- Build APOAToken from payload (only if signature was verified) ---\n if (signatureVerified) {\n try {\n parsedToken = payloadToToken(payload, rawJwt);\n } catch {\n errors.push('Token payload has invalid structure');\n }\n }\n\n // --- Temporal checks ---\n const clockSkew = options.clockSkew;\n\n if (payload.exp !== undefined) {\n const expiresDate = new Date((payload.exp as number) * 1000);\n if (isExpired(expiresDate, clockSkew)) {\n errors.push(`Token expired at ${expiresDate.toISOString()}`);\n }\n } else {\n errors.push('Token has no expiration (exp) claim');\n }\n\n if (payload.nbf !== undefined) {\n const notBeforeDate = new Date((payload.nbf as number) * 1000);\n if (isBeforeNotBefore(notBeforeDate, clockSkew)) {\n errors.push(`Token not valid before ${notBeforeDate.toISOString()}`);\n }\n }\n\n // --- Revocation check ---\n const checkRevocation = options.checkRevocation !== false;\n if (checkRevocation && options.revocationStore && payload.jti) {\n const revRecord = await options.revocationStore.check(\n payload.jti as string\n );\n if (revRecord) {\n errors.push(\n `Token has been revoked (at ${revRecord.revokedAt.toISOString()} by ${revRecord.revokedBy})`\n );\n }\n }\n\n // --- Size warning ---\n const sizeBytes = new TextEncoder().encode(rawJwt).length;\n if (sizeBytes > 4096) {\n warnings.push(`Token size is ${sizeBytes} bytes (exceeds 4KB recommended limit)`);\n }\n\n return {\n valid: errors.length === 0,\n errors,\n token: parsedToken,\n warnings: warnings.length > 0 ? warnings : undefined,\n };\n}\n\n/**\n * Reconstruct an APOAToken from a decoded JWT payload.\n */\nfunction payloadToToken(\n payload: Record<string, unknown>,\n raw: string\n): APOAToken {\n const definition = payload.definition as Record<string, unknown>;\n if (!definition) throw new Error('Missing definition in payload');\n\n return {\n jti: payload.jti as string,\n definition: definition as unknown as APOAToken['definition'],\n issuedAt: new Date((payload.iat as number) * 1000),\n signature: raw.split('.')[2],\n issuer: payload.iss as string,\n audience: payload.aud as string[] | undefined,\n parentToken: (definition.parentToken as string) ?? undefined,\n raw,\n };\n}\n\nfunction base64urlDecode(input: string): Uint8Array {\n // Pad if needed\n const padded = input + '='.repeat((4 - (input.length % 4)) % 4);\n const binary = atob(padded.replace(/-/g, '+').replace(/_/g, '/'));\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n}\n","import type {\n DelegationChain,\n RevocationOptions,\n RevocationRecord,\n RevocationStore,\n} from '../types.js';\n\n/**\n * Cascade revoke: revoke a parent token and all child tokens in a delegation\n * chain. Populates RevocationRecord.cascaded with child token IDs.\n *\n * The caller MUST supply a RevocationStore. There is no default store: a\n * process-shared singleton would silently diverge from the store used by\n * `createClient()` and any caller-supplied store.\n *\n * @param parentTokenId - The parent token's jti to revoke\n * @param childTokenIds - Array of child token jti values to cascade-revoke\n * @param options - Revocation options (revokedBy, reason)\n * @param store - The revocation store to write to\n */\nexport async function cascadeRevoke(\n parentTokenId: string,\n childTokenIds: string[],\n options: RevocationOptions,\n store: RevocationStore\n): Promise<RevocationRecord> {\n const revokedAt = new Date();\n\n // Revoke all children\n for (const childId of childTokenIds) {\n const childRecord: RevocationRecord = {\n tokenId: childId,\n revokedAt,\n revokedBy: options.revokedBy,\n reason: options.reason\n ? `Cascade: ${options.reason}`\n : `Cascade revocation from parent ${parentTokenId}`,\n cascaded: [],\n };\n await store.add(childRecord);\n }\n\n // Revoke parent with cascaded list\n const parentRecord: RevocationRecord = {\n tokenId: parentTokenId,\n revokedAt,\n revokedBy: options.revokedBy,\n reason: options.reason,\n cascaded: childTokenIds,\n };\n await store.add(parentRecord);\n\n return parentRecord;\n}\n","import type { APOAToken, DelegationDefinition, ServiceAuthorization } from '../types.js';\nimport { AttenuationViolationError } from '../utils/errors.js';\nimport { matchScope } from './patterns.js';\n\n/**\n * Verify that a delegation definition is a valid attenuation of a parent token.\n * Throws AttenuationViolationError on any violation.\n *\n * Checks:\n * 1. Child scopes are a subset of parent scopes (per service)\n * 2. Child constraints do not relax parent constraints\n * 3. Child expiration <= parent expiration\n * 4. maxDelegationDepth is not exceeded\n * 5. Child does not add services the parent doesn't have\n * 6. Child rules only add, never remove parent rules\n */\nexport function verifyAttenuation(\n parent: APOAToken,\n child: DelegationDefinition,\n currentDepth: number = 0\n): void {\n const parentDef = parent.definition;\n\n // Check delegation is allowed\n if (parentDef.delegatable === false) {\n throw new AttenuationViolationError(\n 'Parent token does not allow delegation',\n parentDef.services.flatMap((s) => s.scopes),\n child.services.flatMap((s) => s.scopes)\n );\n }\n\n // Check delegation depth\n if (parentDef.maxDelegationDepth !== undefined) {\n if (currentDepth >= parentDef.maxDelegationDepth) {\n throw new AttenuationViolationError(\n `Delegation depth ${currentDepth + 1} exceeds maxDelegationDepth ${parentDef.maxDelegationDepth}`,\n parentDef.services.flatMap((s) => s.scopes),\n child.services.flatMap((s) => s.scopes)\n );\n }\n }\n\n // Check expiration: child must expire at or before parent\n if (child.expires !== undefined) {\n const childExp = child.expires instanceof Date\n ? child.expires.getTime()\n : new Date(child.expires).getTime();\n const parentExp = parentDef.expires instanceof Date\n ? parentDef.expires.getTime()\n : new Date(parentDef.expires as string).getTime();\n\n if (childExp > parentExp) {\n throw new AttenuationViolationError(\n 'Child token expiration exceeds parent expiration',\n parentDef.services.flatMap((s) => s.scopes),\n child.services.flatMap((s) => s.scopes)\n );\n }\n }\n\n // Check each child service against parent\n for (const childService of child.services) {\n const parentService = parentDef.services.find(\n (s) => s.service === childService.service\n );\n\n if (!parentService) {\n throw new AttenuationViolationError(\n `Child requests service '${childService.service}' not in parent token`,\n parentDef.services.flatMap((s) => s.scopes),\n child.services.flatMap((s) => s.scopes)\n );\n }\n\n // Check scopes are a subset\n verifyScopeSubset(parentService, childService);\n\n // Check constraints are not relaxed\n verifyConstraintsNotRelaxed(parentService, childService);\n }\n\n // Check rules: child can only add, not remove\n if (parentDef.rules && parentDef.rules.length > 0) {\n verifyRulesNotRemoved(\n parentDef.rules.map((r) => r.id),\n child,\n parentDef.services.flatMap((s) => s.scopes),\n child.services.flatMap((s) => s.scopes)\n );\n }\n}\n\n/**\n * Verify every child scope is covered by at least one parent scope.\n */\nfunction verifyScopeSubset(\n parent: ServiceAuthorization,\n child: ServiceAuthorization\n): void {\n for (const childScope of child.scopes) {\n const matched = parent.scopes.some((parentScope) =>\n matchScope(parentScope, childScope)\n );\n if (!matched) {\n throw new AttenuationViolationError(\n `Child scope '${childScope}' on service '${child.service}' is not covered by parent scopes [${parent.scopes.join(', ')}]`,\n parent.scopes,\n child.scopes\n );\n }\n }\n}\n\n/**\n * Verify child constraints do not relax parent constraints.\n *\n * A constraint set to `false` in the parent must remain `false` in the child:\n * setting it to `true` flips it (relaxation), and omitting it makes the\n * child's authorize() skip the check entirely (silent relaxation). Both fail.\n *\n * New constraints can be added by the child (they only restrict further).\n */\nfunction verifyConstraintsNotRelaxed(\n parent: ServiceAuthorization,\n child: ServiceAuthorization\n): void {\n if (!parent.constraints) return;\n\n for (const [key, parentValue] of Object.entries(parent.constraints)) {\n if (parentValue === false) {\n const childValue = child.constraints?.[key];\n if (childValue === false) continue;\n throw new AttenuationViolationError(\n childValue === true\n ? `Child relaxes constraint '${key}' on service '${child.service}' (parent: false, child: true)`\n : `Child omits constraint '${key}' on service '${child.service}' (parent: false, child: undefined)`,\n parent.scopes,\n child.scopes\n );\n }\n }\n}\n\n/**\n * Verify child does not remove parent rules.\n * Child can add new rules but must preserve all parent rule IDs.\n */\nfunction verifyRulesNotRemoved(\n parentRuleIds: string[],\n child: DelegationDefinition,\n parentScopes: string[],\n childScopes: string[]\n): void {\n const childRuleIds = new Set(child.rules?.map((r) => r.id) ?? []);\n for (const parentRuleId of parentRuleIds) {\n if (!childRuleIds.has(parentRuleId)) {\n throw new AttenuationViolationError(\n `Child removes parent rule '${parentRuleId}'. Rules can only be added, not removed.`,\n parentScopes,\n childScopes\n );\n }\n }\n}\n","import type {\n APOAToken,\n APOADefinition,\n DelegationDefinition,\n SigningOptions,\n} from '../types.js';\nimport { createToken } from '../token/create.js';\nimport { verifyAttenuation } from '../scope/attenuate.js';\n\n/**\n * Create a delegated (attenuated) token from a parent token.\n *\n * - Inherits principal from parent (cannot be overridden)\n * - Sets parentToken on child to parent's jti\n * - Enforces attenuation rules\n * - Additional rules can only be added, not removed\n */\nexport async function delegate(\n parentToken: APOAToken,\n childDef: DelegationDefinition,\n options: SigningOptions\n): Promise<APOAToken> {\n // Calculate current delegation depth\n // For now, depth is 0 for direct children of the root.\n // In a full chain, this would be tracked. The parent's depth context\n // is determined by counting parentToken links, but for single-level\n // delegation we pass 0 (first delegation).\n const currentDepth = countDepth(parentToken);\n\n // Build the child definition, inheriting principal from parent\n const parentDef = parentToken.definition;\n\n // Merge rules: start with parent rules, add child-specific ones\n const parentRules = parentDef.rules ?? [];\n const childExtraRules = (childDef.rules ?? []).filter(\n (cr) => !parentRules.some((pr) => pr.id === cr.id)\n );\n const mergedRules = [...parentRules, ...childExtraRules];\n\n // Track delegation depth in metadata so deep chains are properly limited\n const childDepth = currentDepth + 1;\n const childMetadata = {\n ...childDef.metadata,\n _delegationDepth: childDepth,\n };\n\n // Inherit parent's false constraints into child services BEFORE attenuation\n // check. If parent says { signing: false }, the child MUST carry that\n // constraint even if the delegation definition omits it — otherwise the\n // child's authorize() would skip the constraint check entirely (privilege\n // escalation). verifyAttenuation now treats omission as relaxation, so\n // the inheritance must happen first or strict callers would fail here.\n const inheritedServices = childDef.services.map((childSvc) => {\n const parentSvc = parentDef.services.find((s) => s.service === childSvc.service);\n if (!parentSvc?.constraints) return childSvc;\n\n const inherited: Record<string, import('../types.js').ConstraintValue> = {};\n for (const [key, value] of Object.entries(parentSvc.constraints)) {\n if (value === false) {\n inherited[key] = false;\n }\n }\n if (Object.keys(inherited).length === 0) return childSvc;\n\n return {\n ...childSvc,\n constraints: { ...inherited, ...childSvc.constraints },\n };\n });\n\n // Now verify attenuation against the inherited (filled-in) child definition.\n verifyAttenuation(\n parentToken,\n { ...childDef, services: inheritedServices, rules: mergedRules },\n currentDepth\n );\n\n const fullDefinition: APOADefinition = {\n principal: parentDef.principal, // Inherited — cannot be overridden\n agent: childDef.agent,\n agentProvider: parentDef.agentProvider,\n services: inheritedServices,\n rules: mergedRules.length > 0 ? mergedRules : undefined,\n expires: childDef.expires ?? parentDef.expires,\n revocable: parentDef.revocable,\n delegatable: parentDef.delegatable,\n maxDelegationDepth: parentDef.maxDelegationDepth,\n metadata: childMetadata,\n legal: parentDef.legal,\n };\n\n // Pass parentTokenId so it's included in the signed JWT payload\n const childToken = await createToken(fullDefinition, options, parentToken.jti);\n\n return childToken;\n}\n\n/**\n * Count delegation depth from a token's definition.\n *\n * We track depth explicitly: when delegate() creates a child token,\n * it stores the current depth in metadata._delegationDepth.\n * A root token has no depth (0). A direct child has depth 1, etc.\n */\nfunction countDepth(token: APOAToken): number {\n const stored = token.definition.metadata?._delegationDepth;\n if (typeof stored === 'number') return stored;\n // No stored depth — this is either a root token or a legacy token.\n // Fall back to checking parentToken as a heuristic.\n return token.parentToken ? 1 : 0;\n}\n","import type {\n ChainVerificationResult,\n DelegationChain,\n RevocationStore,\n} from '../types.js';\nimport { isExpired } from '../utils/time.js';\nimport { matchScope } from '../scope/patterns.js';\n\n/**\n * Verify a full delegation chain.\n *\n * - Verifies every link attenuates the previous one (scopes are subsets)\n * - Checks expiration of every token (if any parent expired, chain is invalid)\n * - If RevocationStore provided, checks revocation of every token\n * - Reports all errors found, plus failedAt index\n *\n * IMPORTANT: This function checks structural integrity (attenuation, expiry,\n * revocation, parentToken links) but does NOT verify cryptographic signatures.\n * Each token in the chain MUST be validated via validateToken() before passing\n * to verifyChain(). Passing unvalidated APOAToken objects defeats chain security.\n */\nexport async function verifyChain(\n chain: DelegationChain,\n store?: RevocationStore\n): Promise<ChainVerificationResult> {\n const errors: string[] = [];\n let failedAt: number | undefined;\n\n if (chain.length === 0) {\n return {\n valid: false,\n depth: 0,\n errors: ['Chain is empty'],\n root: undefined as any,\n leaf: undefined as any,\n };\n }\n\n if (chain.length === 1) {\n // Single token — just check expiration and revocation\n const token = chain[0];\n await checkTokenValidity(token, 0, errors, store);\n return {\n valid: errors.length === 0,\n depth: 0,\n errors,\n failedAt: errors.length > 0 ? 0 : undefined,\n root: token,\n leaf: token,\n };\n }\n\n // Check each token in the chain\n for (let i = 0; i < chain.length; i++) {\n const token = chain[i];\n const errorsBefore = errors.length;\n\n // Check expiration\n await checkTokenValidity(token, i, errors, store);\n\n // Check attenuation against parent (skip root at index 0)\n if (i > 0) {\n const parent = chain[i - 1];\n checkAttenuation(parent, token, i, errors);\n\n // Check parentToken reference\n if (token.parentToken !== parent.jti) {\n errors.push(\n `Chain link ${i}: parentToken '${token.parentToken}' does not match parent jti '${parent.jti}'`\n );\n }\n }\n\n // Track first failure\n if (failedAt === undefined && errors.length > errorsBefore) {\n failedAt = i;\n }\n }\n\n return {\n valid: errors.length === 0,\n depth: chain.length - 1,\n errors,\n failedAt,\n root: chain[0],\n leaf: chain[chain.length - 1],\n };\n}\n\n/**\n * Check a single token's validity (expiration and revocation).\n */\nasync function checkTokenValidity(\n token: { jti: string; definition: { expires: Date | string } },\n index: number,\n errors: string[],\n store?: RevocationStore\n): Promise<void> {\n // Expiration check (no clock skew for chain verification — strict)\n if (isExpired(token.definition.expires, 0)) {\n errors.push(`Chain link ${index}: token '${token.jti}' has expired`);\n }\n\n // Revocation check\n if (store) {\n const record = await store.check(token.jti);\n if (record) {\n errors.push(\n `Chain link ${index}: token '${token.jti}' has been revoked`\n );\n }\n }\n}\n\n/**\n * Verify that a child token attenuates the parent: scopes are a subset,\n * constraints are not relaxed (a parent `false` must remain `false`), and\n * expiration does not extend beyond the parent.\n */\nfunction checkAttenuation(\n parent: {\n definition: {\n services: { service: string; scopes: string[]; constraints?: Record<string, unknown> }[];\n expires: Date | string;\n };\n },\n child: {\n definition: {\n services: { service: string; scopes: string[]; constraints?: Record<string, unknown> }[];\n expires: Date | string;\n };\n },\n index: number,\n errors: string[]\n): void {\n // Check each child service\n for (const childService of child.definition.services) {\n const parentService = parent.definition.services.find(\n (s) => s.service === childService.service\n );\n\n if (!parentService) {\n errors.push(\n `Chain link ${index}: service '${childService.service}' not in parent token`\n );\n continue;\n }\n\n // Check each child scope is covered by a parent scope\n for (const childScope of childService.scopes) {\n const covered = parentService.scopes.some((ps) =>\n matchScope(ps, childScope)\n );\n if (!covered) {\n errors.push(\n `Chain link ${index}: scope '${childScope}' on '${childService.service}' not covered by parent`\n );\n }\n }\n\n // Check constraints are not relaxed. Any parent constraint set to false\n // must also be false on the child — true flips it (relaxation), undefined\n // means the child's authorize() skips the check (silent relaxation).\n if (parentService.constraints) {\n for (const [key, parentValue] of Object.entries(parentService.constraints)) {\n if (parentValue === false) {\n const childValue = childService.constraints?.[key];\n if (childValue !== false) {\n errors.push(\n `Chain link ${index}: constraint '${key}' on '${childService.service}' relaxed by child (parent: false, child: ${childValue === undefined ? 'undefined' : JSON.stringify(childValue)})`\n );\n }\n }\n }\n }\n }\n\n // Check child expiration <= parent expiration\n const childExp = child.definition.expires instanceof Date\n ? child.definition.expires.getTime()\n : new Date(child.definition.expires as string).getTime();\n const parentExp = parent.definition.expires instanceof Date\n ? parent.definition.expires.getTime()\n : new Date(parent.definition.expires as string).getTime();\n\n if (childExp > parentExp) {\n errors.push(\n `Chain link ${index}: child expiration exceeds parent expiration`\n );\n }\n}\n","import type { APOAToken } from '../types.js';\n\ntype DelegationLink = {\n parentTokenId?: unknown;\n};\n\ntype DefinitionLike = {\n parentToken?: unknown;\n delegationChain?: unknown;\n};\n\ntype TokenLike = {\n parentToken?: unknown;\n definition?: DefinitionLike;\n};\n\n/**\n * Return ancestor token IDs referenced by a token-like object.\n *\n * Canonical SDK tokens use `parentToken` for the direct parent. Some transport\n * adapters also carry `definition.delegationChain` snapshots or message\n * metadata with ancestor IDs. This helper normalizes those forms so revocation\n * checks can consistently include every known ancestor.\n */\nexport function getDelegationAncestorIds(input: APOAToken | TokenLike | DefinitionLike): string[] {\n const ids: string[] = [];\n const seen = new Set<string>();\n\n const push = (value: unknown): void => {\n if (typeof value !== 'string' || value.length === 0 || seen.has(value)) {\n return;\n }\n seen.add(value);\n ids.push(value);\n };\n\n const token = input as TokenLike;\n const definition = hasDefinition(input) ? token.definition : (input as DefinitionLike);\n\n push(token.parentToken);\n push(definition?.parentToken);\n\n const chain = definition?.delegationChain;\n if (Array.isArray(chain)) {\n for (const link of chain) {\n if (typeof link === 'string') {\n push(link);\n } else if (link && typeof link === 'object') {\n push((link as DelegationLink).parentTokenId);\n }\n }\n }\n\n return ids;\n}\n\nfunction hasDefinition(input: unknown): input is TokenLike {\n return Boolean(input && typeof input === 'object' && 'definition' in input);\n}\n","import * as jose from 'jose';\nimport type { KeyResolver } from '../types.js';\n\n/** A JSON Web Key as defined by RFC 7517. */\nexport interface JWK {\n kty: string;\n crv?: string;\n x?: string;\n y?: string;\n kid: string;\n use?: 'sig' | 'enc';\n alg?: string;\n [key: string]: unknown;\n}\n\n/** A JSON Web Key Set as defined by RFC 7517 §5. */\nexport interface JWKS {\n keys: JWK[];\n}\n\nexport interface PublicKeyToJWKOptions {\n kid: string;\n use?: 'sig' | 'enc';\n alg?: 'EdDSA' | 'ES256';\n}\n\n/**\n * Convert a public CryptoKey into a JWK. The `kid` is required so callers\n * can match keys against the `kid` header on signed tokens. `alg` defaults\n * to the algorithm implied by the key type (`EdDSA` for Ed25519, `ES256`\n * for P-256).\n */\nexport async function publicKeyToJWK(\n publicKey: CryptoKey,\n options: PublicKeyToJWKOptions\n): Promise<JWK> {\n const exported = await jose.exportJWK(publicKey);\n const alg = options.alg ?? defaultAlgorithm(exported);\n return {\n ...(exported as Record<string, unknown>),\n kid: options.kid,\n use: options.use ?? 'sig',\n alg,\n } as JWK;\n}\n\n/** Wrap an array of JWKs in the JWKS envelope. */\nexport function buildJWKS(keys: JWK[]): JWKS {\n return { keys };\n}\n\nexport interface JWKSResolverOptions {\n /** How long a fetched JWKS is cached in memory before refetch. Default 1 hour. */\n cacheMaxAgeMs?: number;\n /** How long a fetched JWKS is reused if a refetch fails. Default 24 hours. */\n cooldownMs?: number;\n /** Custom fetch implementation; defaults to the global fetch. */\n fetch?: typeof fetch;\n /**\n * Allow non-https:// JWKS URLs. Off by default because APOA mandates TLS\n * for all communication (SPEC §13.2). Use only for local development.\n */\n allowInsecure?: boolean;\n}\n\n/**\n * Create a KeyResolver backed by a remote JWKS endpoint. The resolver fetches\n * `url`, caches the response, and returns the matching public key for a\n * given `kid` claim. Used in conjunction with `validateToken`'s `keyResolver`\n * option so a relying party can verify tokens signed by keys it discovers\n * at runtime.\n */\nexport function createJWKSResolver(\n url: string,\n options: JWKSResolverOptions = {}\n): KeyResolver {\n if (!options.fetch && !options.allowInsecure && !url.startsWith('https://')) {\n throw new Error(\n `JWKS URL must use https:// (got: ${JSON.stringify(url)}). ` +\n 'Pass allowInsecure: true or a custom fetch for local development.'\n );\n }\n const cacheMaxAgeMs = options.cacheMaxAgeMs ?? 60 * 60 * 1000;\n const cooldownMs = options.cooldownMs ?? 24 * 60 * 60 * 1000;\n const fetchImpl = options.fetch ?? fetch;\n\n let cache: { fetchedAt: number; jwks: JWKS } | null = null;\n let inflight: Promise<JWKS> | null = null;\n\n async function fetchJWKS(): Promise<JWKS> {\n const response = await fetchImpl(url, {\n headers: { accept: 'application/jwk-set+json, application/json' },\n });\n if (!response.ok) {\n throw new Error(`JWKS fetch failed: ${response.status} ${response.statusText}`);\n }\n const body = (await response.json()) as JWKS;\n if (!body || !Array.isArray(body.keys)) {\n throw new Error('JWKS response did not contain a `keys` array');\n }\n return body;\n }\n\n async function getJWKS(): Promise<JWKS> {\n const now = Date.now();\n if (cache && now - cache.fetchedAt < cacheMaxAgeMs) {\n return cache.jwks;\n }\n if (inflight) {\n return inflight;\n }\n inflight = fetchJWKS()\n .then((jwks) => {\n cache = { fetchedAt: Date.now(), jwks };\n return jwks;\n })\n .catch((err) => {\n if (cache && now - cache.fetchedAt < cooldownMs) {\n return cache.jwks;\n }\n throw err;\n })\n .finally(() => {\n inflight = null;\n });\n return inflight;\n }\n\n return {\n async resolve(kid: string): Promise<CryptoKey | null> {\n const jwks = await getJWKS();\n const match = jwks.keys.find((k) => k.kid === kid);\n if (!match) return null;\n const key = await jose.importJWK(match as jose.JWK, match.alg);\n return key as CryptoKey;\n },\n };\n}\n\nfunction defaultAlgorithm(jwk: jose.JWK): string {\n if (jwk.kty === 'OKP' && jwk.crv === 'Ed25519') return 'EdDSA';\n if (jwk.kty === 'EC' && jwk.crv === 'P-256') return 'ES256';\n return jwk.alg ?? 'EdDSA';\n}\n","import type {\n APOAClient,\n APOAClientOptions,\n APOADefinition,\n APOAToken,\n AuditEntry,\n AuditQueryOptions,\n AuthorizeOptions,\n AuthorizationResult,\n ChainVerificationResult,\n DelegationChain,\n DelegationDefinition,\n RevocationOptions,\n RevocationRecord,\n ScopeCheckResult,\n SigningOptions,\n ValidationOptions,\n ValidationResult,\n} from './types.js';\nimport { MemoryRevocationStore } from './revocation/store.js';\nimport { MemoryAuditStore } from './audit/store.js';\nimport { createToken } from './token/create.js';\nimport { validateToken } from './token/validate.js';\nimport { parseDefinition } from './token/parse.js';\nimport { generateKeyPair } from './utils/crypto.js';\nimport { checkScope, checkConstraint, authorize } from './scope/check.js';\nimport { delegate } from './delegation/chain.js';\nimport { verifyChain } from './delegation/verify.js';\nimport { revoke, isRevoked } from './revocation/revoke.js';\nimport { logAction } from './audit/log.js';\nimport { getAuditTrail, getAuditTrailByService } from './audit/trail.js';\n\n/**\n * Create a configured APOA client.\n * Wires up RevocationStore and AuditStore so methods don't need explicit store params.\n * Defaults to MemoryRevocationStore + MemoryAuditStore for zero-config dev/testing.\n */\nexport function createClient(options?: APOAClientOptions): APOAClient {\n const revocationStore = options?.revocationStore ?? new MemoryRevocationStore();\n const auditStore = options?.auditStore ?? new MemoryAuditStore();\n const keyResolver = options?.keyResolver;\n const defaultSigningOptions = options?.defaultSigningOptions;\n\n function mergeSigningOptions(opts?: SigningOptions): SigningOptions {\n if (!opts && !defaultSigningOptions?.privateKey) {\n throw new Error(\n 'APOA needs a private key to create tokens. Pass `privateKey` to `new APOA({ privateKey })`, configure `createClient({ defaultSigningOptions: { privateKey } })`, or pass signing options to `createToken(...)`.'\n );\n }\n return {\n ...defaultSigningOptions,\n ...opts,\n } as SigningOptions;\n }\n\n return {\n async createToken(\n definition: APOADefinition,\n opts?: SigningOptions\n ): Promise<APOAToken> {\n return createToken(definition, mergeSigningOptions(opts));\n },\n\n parseDefinition(\n input: string,\n format?: 'yaml' | 'json'\n ): APOADefinition {\n return parseDefinition(input, format);\n },\n\n async validateToken(\n token: string | APOAToken,\n opts?: Omit<ValidationOptions, 'revocationStore'>\n ): Promise<ValidationResult> {\n return validateToken(token, {\n ...opts,\n keyResolver: opts?.keyResolver ?? keyResolver,\n revocationStore,\n checkRevocation: opts?.checkRevocation ?? true,\n });\n },\n\n async generateKeyPair(\n algorithm?: 'EdDSA' | 'ES256'\n ): Promise<CryptoKeyPair> {\n return generateKeyPair(algorithm);\n },\n\n checkScope(\n token: APOAToken,\n service: string,\n action: string\n ): ScopeCheckResult {\n return checkScope(token, service, action);\n },\n\n checkConstraint(\n token: APOAToken,\n service: string,\n constraint: string\n ): ScopeCheckResult {\n return checkConstraint(token, service, constraint);\n },\n\n async authorize(\n token: APOAToken,\n service: string,\n action: string,\n opts?: Omit<AuthorizeOptions, 'revocationStore' | 'auditStore'>\n ): Promise<AuthorizationResult> {\n return authorize(token, service, action, {\n ...opts,\n revocationStore,\n auditStore,\n });\n },\n\n async delegate(\n parentToken: APOAToken,\n childDef: DelegationDefinition,\n opts?: SigningOptions\n ): Promise<APOAToken> {\n return delegate(parentToken, childDef, mergeSigningOptions(opts));\n },\n\n async verifyChain(\n chain: DelegationChain\n ): Promise<ChainVerificationResult> {\n return verifyChain(chain, revocationStore);\n },\n\n async revoke(\n tokenId: string,\n opts: RevocationOptions\n ): Promise<RevocationRecord> {\n return revoke(tokenId, opts, revocationStore);\n },\n\n async isRevoked(tokenId: string): Promise<boolean> {\n return isRevoked(tokenId, revocationStore);\n },\n\n async logAction(\n tokenId: string,\n entry: Omit<AuditEntry, 'tokenId' | 'timestamp'>\n ): Promise<void> {\n return logAction(tokenId, entry, auditStore);\n },\n\n async getAuditTrail(\n tokenId: string,\n opts?: AuditQueryOptions\n ): Promise<AuditEntry[]> {\n return getAuditTrail(tokenId, opts, auditStore);\n },\n\n async getAuditTrailByService(\n service: string,\n opts?: AuditQueryOptions\n ): Promise<AuditEntry[]> {\n return getAuditTrailByService(service, opts, auditStore);\n },\n };\n}\n","import { createClient } from './client.js';\nimport type {\n APOAClient,\n APOADefinition,\n APOAOptions,\n APOAToken,\n AuthorizationResult,\n AuthorizeOptions,\n Principal,\n Agent,\n ServiceAuthorization,\n SimpleGrantInput,\n SigningOptions,\n ValidationOptions,\n ValidationResult,\n} from './types.js';\n\n/**\n * Application-facing APOA facade.\n *\n * This keeps the protocol-level APIs intact while giving app developers a\n * smaller first path: configure once, then use namespaced resources.\n */\nexport class APOA {\n private readonly client: APOAClient;\n\n readonly tokens: {\n create: (definition: APOADefinition, options?: SigningOptions) => Promise<APOAToken>;\n createGrant: (input: SimpleGrantInput, options?: SigningOptions) => Promise<APOAToken>;\n validate: (\n token: string | APOAToken,\n options?: Omit<ValidationOptions, 'revocationStore'>\n ) => Promise<ValidationResult>;\n parse: (input: string, format?: 'yaml' | 'json') => APOADefinition;\n };\n\n readonly authorizations: {\n check: (\n token: APOAToken,\n service: string,\n action: string,\n options?: Omit<AuthorizeOptions, 'revocationStore' | 'auditStore'>\n ) => Promise<AuthorizationResult>;\n };\n\n constructor(options: APOAOptions = {}) {\n const { privateKey, algorithm, kid, ...clientOptions } = options;\n\n this.client = createClient({\n ...clientOptions,\n defaultSigningOptions: privateKey\n ? { privateKey, algorithm, kid }\n : undefined,\n });\n\n this.tokens = {\n create: (definition, signingOptions) =>\n this.client.createToken(definition, signingOptions),\n createGrant: async (input, signingOptions) =>\n this.client.createToken(normalizeGrantInput(input), signingOptions),\n validate: (token, validationOptions) =>\n this.client.validateToken(token, validationOptions),\n parse: (input, format) =>\n this.client.parseDefinition(input, format),\n };\n\n this.authorizations = {\n check: (token, service, action, authorizeOptions) =>\n this.client.authorize(token, service, action, authorizeOptions),\n };\n }\n\n async generateKeyPair(algorithm?: 'EdDSA' | 'ES256'): Promise<CryptoKeyPair> {\n return this.client.generateKeyPair(algorithm);\n }\n}\n\nfunction normalizeGrantInput(input: SimpleGrantInput): APOADefinition {\n const errors: string[] = [];\n\n if (!input || typeof input !== 'object') {\n throw invalidGrantInput(['input must be an object']);\n }\n\n const principal = normalizePrincipal(input.principal, errors);\n const agent = normalizeAgent(input.agent, errors);\n const services = normalizeServices(input, errors);\n const expires = normalizeExpires(input, errors);\n\n if (errors.length > 0 || !principal || !agent || services.length === 0 || !expires) {\n throw invalidGrantInput(errors);\n }\n\n return {\n principal,\n agent,\n services,\n expires,\n ...(input.rules ? { rules: input.rules } : {}),\n ...(input.revocable !== undefined ? { revocable: input.revocable } : {}),\n ...(input.delegatable !== undefined ? { delegatable: input.delegatable } : {}),\n ...(input.maxDelegationDepth !== undefined\n ? { maxDelegationDepth: input.maxDelegationDepth }\n : {}),\n ...(input.metadata ? { metadata: input.metadata } : {}),\n ...(input.agentProvider ? { agentProvider: input.agentProvider } : {}),\n ...(input.legal ? { legal: input.legal } : {}),\n };\n}\n\nfunction normalizePrincipal(\n principal: SimpleGrantInput['principal'],\n errors: string[]\n): Principal | undefined {\n if (typeof principal === 'string' && principal.trim()) {\n return { id: principal.trim() };\n }\n if (principal && typeof principal === 'object' && principal.id) {\n return principal;\n }\n errors.push('principal is required; pass a DID string or { id }');\n return undefined;\n}\n\nfunction normalizeAgent(\n agent: SimpleGrantInput['agent'],\n errors: string[]\n): Agent | undefined {\n if (typeof agent === 'string' && agent.trim()) {\n return { id: agent.trim() };\n }\n if (agent && typeof agent === 'object' && agent.id) {\n return agent;\n }\n errors.push('agent is required; pass a DID string or { id }');\n return undefined;\n}\n\nfunction normalizeServices(\n input: SimpleGrantInput,\n errors: string[]\n): ServiceAuthorization[] {\n if (input.services) {\n if (!Array.isArray(input.services) || input.services.length === 0) {\n errors.push('services must be a non-empty array when provided');\n return [];\n }\n return input.services;\n }\n\n if (!input.service) {\n errors.push('service is required unless services is provided');\n return [];\n }\n if (!input.scopes || !Array.isArray(input.scopes) || input.scopes.length === 0) {\n errors.push('scopes must be a non-empty array unless services is provided');\n return [];\n }\n\n return [{\n service: input.service,\n scopes: input.scopes,\n ...(input.constraints ? { constraints: input.constraints } : {}),\n ...(input.accessMode ? { accessMode: input.accessMode } : {}),\n ...(input.browserConfig ? { browserConfig: input.browserConfig } : {}),\n ...(input.apiConfig ? { apiConfig: input.apiConfig } : {}),\n }];\n}\n\nfunction normalizeExpires(\n input: SimpleGrantInput,\n errors: string[]\n): Date | string | undefined {\n if (input.expires && input.expiresIn) {\n errors.push('pass either expires or expiresIn, not both');\n return undefined;\n }\n if (input.expires) {\n return input.expires;\n }\n if (input.expiresIn) {\n return parseDurationFromNow(input.expiresIn);\n }\n errors.push('expires or expiresIn is required');\n return undefined;\n}\n\nfunction parseDurationFromNow(duration: string): Date {\n const match = /^(\\d+)([smhd])$/.exec(duration);\n if (!match) {\n throw invalidGrantInput([\n `expiresIn must use a clear duration like '15m', '2h', or '30d'`,\n ]);\n }\n\n const amount = Number(match[1]);\n if (!Number.isSafeInteger(amount) || amount <= 0) {\n throw invalidGrantInput(['expiresIn duration must be a positive integer']);\n }\n\n const unitMs: Record<string, number> = {\n s: 1000,\n m: 60 * 1000,\n h: 60 * 60 * 1000,\n d: 24 * 60 * 60 * 1000,\n };\n\n return new Date(Date.now() + amount * unitMs[match[2]]);\n}\n\nfunction invalidGrantInput(errors: string[]): Error {\n return new Error(\n [\n 'Invalid APOA grant input.',\n ...errors.map((error) => `- ${error}`),\n 'Minimal shape: { principal, agent, service, scopes, expiresIn }',\n ].join('\\n')\n );\n}\n"],"mappings":";AACO,IAAM,YAAN,cAAwB,MAAM;AAAA,EACnC;AAAA,EAEA,YAAY,SAAiB,MAAc;AACzC,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,OAAO;AAAA,EACd;AACF;AAGO,IAAM,oBAAN,cAAgC,UAAU;AAAA,EAC/C;AAAA,EAEA,YAAY,SAAiB,WAAiB;AAC5C,UAAM,SAAS,eAAe;AAC9B,SAAK,YAAY;AACjB,SAAK,OAAO;AAAA,EACd;AACF;AAGO,IAAM,sBAAN,cAAkC,UAAU;AAAA,EACjD;AAAA,EACA;AAAA,EAEA,YAAY,SAAiB,gBAAwB,iBAA2B;AAC9E,UAAM,SAAS,iBAAiB;AAChC,SAAK,iBAAiB;AACtB,SAAK,kBAAkB;AACvB,SAAK,OAAO;AAAA,EACd;AACF;AAGO,IAAM,4BAAN,cAAwC,UAAU;AAAA,EACvD;AAAA,EACA;AAAA,EAEA,YAAY,SAAiB,aAAuB,gBAA0B;AAC5E,UAAM,SAAS,uBAAuB;AACtC,SAAK,cAAc;AACnB,SAAK,iBAAiB;AACtB,SAAK,OAAO;AAAA,EACd;AACF;AAGO,IAAM,kBAAN,cAA8B,UAAU;AAAA,EAC7C;AAAA,EACA;AAAA,EAEA,YAAY,SAAiB,WAAiB,WAAmB;AAC/D,UAAM,SAAS,eAAe;AAC9B,SAAK,YAAY;AACjB,SAAK,YAAY;AACjB,SAAK,OAAO;AAAA,EACd;AACF;AAGO,IAAM,yBAAN,cAAqC,UAAU;AAAA,EACpD;AAAA,EACA;AAAA,EAEA,YAAY,SAAiB,UAAkB,QAAgB;AAC7D,UAAM,SAAS,eAAe;AAC9B,SAAK,WAAW;AAChB,SAAK,SAAS;AACd,SAAK,OAAO;AAAA,EACd;AACF;AAGO,IAAM,0BAAN,cAAsC,UAAU;AAAA,EACrD;AAAA,EAEA,YAAY,SAAiB,OAAgB;AAC3C,UAAM,SAAS,kBAAkB;AACjC,SAAK,QAAQ;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAGO,IAAM,uBAAN,cAAmC,UAAU;AAAA,EAClD;AAAA,EACA,cAAsB;AAAA,EAEtB,YAAY,SAAiB,QAAgB;AAC3C,UAAM,SAAS,eAAe;AAC9B,SAAK,SAAS;AACd,SAAK,OAAO;AAAA,EACd;AACF;AAGO,IAAM,4BAAN,cAAwC,UAAU;AAAA,EACvD;AAAA,EAEA,YAAY,SAAiB,QAAkB;AAC7C,UAAM,SAAS,oBAAoB;AACnC,SAAK,SAAS;AACd,SAAK,OAAO;AAAA,EACd;AACF;;;AC1GA,YAAY,UAAU;AAMtB,eAAsBA,iBACpB,YAA+B,SACP;AACxB,QAAM,MAAM,cAAc,UAAU,UAAU;AAC9C,QAAM,EAAE,WAAW,WAAW,IAAI,MAAW,qBAAgB,KAAK;AAAA,IAChE,aAAa;AAAA,EACf,CAAC;AACD,SAAO,EAAE,WAAW,WAAW;AACjC;AAKA,eAAsB,KACpB,SACA,SACiB;AACjB,QAAM,MAAM,QAAQ,cAAc,UAAU,UAAU;AACtD,QAAM,SAAkC,EAAE,IAAI;AAC9C,MAAI,QAAQ,KAAK;AACf,WAAO,MAAM,QAAQ;AAAA,EACvB;AAEA,QAAM,MAAM,MAAM,IAAS;AAAA,IACzB,IAAI,YAAY,EAAE,OAAO,KAAK,UAAU,OAAO,CAAC;AAAA,EAClD,EACG,mBAAmB,MAAyC,EAC5D,KAAK,QAAQ,UAAU;AAE1B,SAAO;AACT;AAKA,eAAsB,OACpB,OACA,KACkC;AAClC,QAAM,EAAE,QAAQ,IAAI,MAAW,mBAAc,OAAO,GAAG;AACvD,SAAO,KAAK,MAAM,IAAI,YAAY,EAAE,OAAO,OAAO,CAAC;AACrD;;;AC/CA,IAAM,qBAAqB;AAC3B,IAAM,iBAAiB;AAKvB,SAAS,cAAc,WAA4B;AACjD,MAAI,cAAc,OAAW,QAAO;AACpC,MAAI,YAAY,EAAG,QAAO;AAC1B,SAAO,KAAK,IAAI,WAAW,cAAc;AAC3C;AAKA,SAAS,OAAO,OAA4B;AAC1C,SAAO,iBAAiB,OAAO,QAAQ,IAAI,KAAK,KAAK;AACvD;AAMO,SAAS,UACd,SACA,WACA,KACS;AACT,QAAM,cAAc,OAAO,OAAO;AAClC,QAAM,OAAO,cAAc,SAAS;AACpC,QAAM,cAAc,OAAO,oBAAI,KAAK;AACpC,SAAO,YAAY,QAAQ,IAAI,YAAY,QAAQ,IAAI,OAAO;AAChE;AAMO,SAAS,kBACd,WACA,WACA,KACS;AACT,QAAM,gBAAgB,OAAO,SAAS;AACtC,QAAM,OAAO,cAAc,SAAS;AACpC,QAAM,cAAc,OAAO,oBAAI,KAAK;AACpC,SAAO,YAAY,QAAQ,IAAI,cAAc,QAAQ,IAAI,OAAO;AAClE;;;AC3CO,SAAS,WAAW,OAAyB;AAClD,MAAI,CAAC,MAAO,QAAO,CAAC;AACpB,SAAO,MAAM,MAAM,GAAG;AACxB;AAeO,SAAS,WAAW,SAAiB,WAA4B;AACtE,MAAI,CAAC,WAAW,CAAC,UAAW,QAAO;AAGnC,MAAI,YAAY,IAAK,QAAO;AAE5B,QAAM,eAAe,WAAW,OAAO;AACvC,QAAM,iBAAiB,WAAW,SAAS;AAG3C,MAAI,aAAa,WAAW,eAAe,OAAQ,QAAO;AAG1D,WAAS,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;AAC5C,QAAI,aAAa,CAAC,MAAM,IAAK;AAC7B,QAAI,CAAC,aAAa,CAAC,KAAK,CAAC,eAAe,CAAC,EAAG,QAAO;AACnD,QAAI,aAAa,CAAC,MAAM,eAAe,CAAC,EAAG,QAAO;AAAA,EACpD;AAEA,SAAO;AACT;;;ACpCO,IAAM,wBAAN,MAAuD;AAAA,EACpD,UAAyC,oBAAI,IAAI;AAAA,EAEzD,MAAM,IAAI,QAAyC;AACjD,SAAK,QAAQ,IAAI,OAAO,SAAS,MAAM;AAAA,EACzC;AAAA,EAEA,MAAM,MAAM,SAAmD;AAC7D,WAAO,KAAK,QAAQ,IAAI,OAAO,KAAK;AAAA,EACtC;AAAA,EAEA,MAAM,KAAK,aAAkD;AAC3D,UAAM,UAA8B,CAAC;AACrC,eAAW,UAAU,KAAK,QAAQ,OAAO,GAAG;AAC1C,UAAI,OAAO,cAAc,aAAa;AACpC,gBAAQ,KAAK,MAAM;AAAA,MACrB;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACF;;;ACpBO,IAAM,mBAAN,MAA6C;AAAA,EAC1C,UAAwB,CAAC;AAAA,EAEjC,MAAM,OAAO,OAAkC;AAC7C,SAAK,QAAQ,KAAK,KAAK;AAAA,EACzB;AAAA,EAEA,MAAM,MAAM,SAAiB,SAAoD;AAC/E,UAAM,UAAU,KAAK,QAAQ,OAAO,CAAC,MAAM,EAAE,YAAY,OAAO;AAChE,WAAO,aAAa,SAAS,OAAO;AAAA,EACtC;AAAA,EAEA,MAAM,eACJ,SACA,SACuB;AACvB,UAAM,UAAU,KAAK,QAAQ,OAAO,CAAC,MAAM,EAAE,YAAY,OAAO;AAChE,WAAO,aAAa,SAAS,OAAO;AAAA,EACtC;AACF;AAEA,SAAS,aACP,SACA,SACc;AAEd,MAAI,UAAU;AAEd,MAAI,SAAS,MAAM;AACjB,UAAM,OAAO,QAAQ,KAAK,QAAQ;AAClC,cAAU,QAAQ,OAAO,CAAC,MAAM,EAAE,UAAU,QAAQ,KAAK,IAAI;AAAA,EAC/D;AACA,MAAI,SAAS,IAAI;AACf,UAAM,KAAK,QAAQ,GAAG,QAAQ;AAC9B,cAAU,QAAQ,OAAO,CAAC,MAAM,EAAE,UAAU,QAAQ,KAAK,EAAE;AAAA,EAC7D;AACA,MAAI,SAAS,QAAQ;AACnB,cAAU,QAAQ,OAAO,CAAC,MAAM,EAAE,WAAW,QAAQ,MAAM;AAAA,EAC7D;AACA,MAAI,SAAS,SAAS;AACpB,cAAU,QAAQ,OAAO,CAAC,MAAM,EAAE,YAAY,QAAQ,OAAO;AAAA,EAC/D;AACA,MAAI,SAAS,QAAQ;AACnB,cAAU,QAAQ,OAAO,CAAC,MAAM,EAAE,WAAW,QAAQ,MAAM;AAAA,EAC7D;AAEA,QAAM,SAAS,SAAS,UAAU;AAClC,QAAM,QAAQ,SAAS,SAAS;AAChC,YAAU,QAAQ,MAAM,QAAQ,SAAS,KAAK;AAE9C,SAAO;AACT;;;AC5CO,SAAS,WACd,OACA,SACA,QACkB;AAClB,QAAM,cAAc,MAAM,WAAW,SAAS;AAAA,IAC5C,CAAC,MAAM,EAAE,YAAY;AAAA,EACvB;AAEA,MAAI,CAAC,aAAa;AAChB,WAAO;AAAA,MACL,SAAS;AAAA,MACT,QAAQ,YAAY,OAAO;AAAA,IAC7B;AAAA,EACF;AAEA,aAAW,SAAS,YAAY,QAAQ;AACtC,QAAI,WAAW,OAAO,MAAM,GAAG;AAC7B,aAAO;AAAA,QACL,SAAS;AAAA,QACT,QAAQ,kBAAkB,KAAK;AAAA,QAC/B,cAAc;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,SAAS;AAAA,IACT,QAAQ,UAAU,MAAM;AAAA,EAC1B;AACF;AAOO,SAAS,gBACd,OACA,SACA,YACkB;AAClB,QAAM,cAAc,MAAM,WAAW,SAAS;AAAA,IAC5C,CAAC,MAAM,EAAE,YAAY;AAAA,EACvB;AAEA,MAAI,CAAC,aAAa;AAChB,WAAO;AAAA,MACL,SAAS;AAAA,MACT,QAAQ,YAAY,OAAO;AAAA,IAC7B;AAAA,EACF;AAEA,MAAI,CAAC,YAAY,aAAa;AAC5B,WAAO;AAAA,MACL,SAAS;AAAA,MACT,QAAQ,uCAAuC,OAAO;AAAA,IACxD;AAAA,EACF;AAEA,QAAM,QAAQ,YAAY,YAAY,UAAU;AAEhD,MAAI,UAAU,QAAW;AACvB,WAAO;AAAA,MACL,SAAS;AAAA,MACT,QAAQ,eAAe,UAAU;AAAA,IACnC;AAAA,EACF;AAEA,MAAI,UAAU,OAAO;AACnB,WAAO;AAAA,MACL,SAAS;AAAA,MACT,QAAQ,eAAe,UAAU;AAAA,MACjC;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,SAAS;AAAA,IACT,QAAQ,eAAe,UAAU,eAAe,KAAK,UAAU,KAAK,CAAC;AAAA,EACvE;AACF;AAeA,eAAsB,UACpB,OACA,SACA,QACA,SAC8B;AAE9B,MAAI,SAAS,iBAAiB;AAC5B,UAAM,SAAS,MAAM,QAAQ,gBAAgB,MAAM,MAAM,GAAG;AAC5D,QAAI,QAAQ;AACV,aAAO;AAAA,QACL,YAAY;AAAA,QACZ,QAAQ;AAAA,QACR,QAAQ,EAAE,SAAS,KAAK;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AAGA,QAAM,cAAc,WAAW,OAAO,SAAS,MAAM;AACrD,MAAI,CAAC,YAAY,SAAS;AACxB,WAAO;AAAA,MACL,YAAY;AAAA,MACZ,QAAQ,YAAY;AAAA,MACpB,QAAQ,EAAE,SAAS,OAAO,cAAc,MAAM;AAAA,IAChD;AAAA,EACF;AAMA,QAAM,cAAc,MAAM,WAAW,SAAS;AAAA,IAC5C,CAAC,MAAM,EAAE,YAAY;AAAA,EACvB;AACA,MAAI,aAAa,aAAa;AAC5B,UAAM,iBAAiB,OAAO,MAAM,GAAG;AACvC,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,YAAY,WAAW,GAAG;AAClE,UAAI,UAAU,SAAS,eAAe,SAAS,GAAG,GAAG;AACnD,eAAO;AAAA,UACL,YAAY;AAAA,UACZ,QAAQ,eAAe,GAAG;AAAA,UAC1B,QAAQ,EAAE,SAAS,OAAO,cAAc,MAAM,mBAAmB,MAAM;AAAA,QACzE;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,QAAM,QAAQ,MAAM,WAAW;AAC/B,QAAM,aAA8B,CAAC;AAErC,MAAI,SAAS,MAAM,SAAS,GAAG;AAQ7B,eAAW,QAAQ,OAAO;AACxB,UAAI,KAAK,gBAAgB,QAAQ;AAC/B,cAAM,UAAU,KAAK,GAAG,WAAW,KAAK,IAAI,KAAK,GAAG,MAAM,CAAC,IAAI,KAAK;AACpE,cAAM,iBAAiB,OAAO,YAAY,EAAE,MAAM,GAAG;AACrD,YAAI,eAAe,SAAS,QAAQ,YAAY,CAAC,GAAG;AAClD,iBAAO;AAAA,YACL,YAAY;AAAA,YACZ,QAAQ,cAAc,KAAK,EAAE;AAAA,YAC7B,QAAQ;AAAA,cACN,SAAS;AAAA,cACT,cAAc;AAAA,cACd,mBAAmB;AAAA,cACnB,aAAa;AAAA,YACf;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,eAAW,QAAQ,OAAO;AACxB,UAAI,KAAK,gBAAgB,QAAQ;AAC/B,cAAM,YAA2B;AAAA,UAC/B,QAAQ,KAAK;AAAA,UACb,SAAS,MAAM;AAAA,UACf;AAAA,UACA;AAAA,UACA,WAAW,oBAAI,KAAK;AAAA,UACpB,SAAS,KAAK;AAAA,QAChB;AACA,mBAAW,KAAK,SAAS;AAGzB,YAAI,SAAS,YAAY;AACvB,gBAAM,QAAQ,WAAW,OAAO;AAAA,YAC9B,SAAS,MAAM;AAAA,YACf,WAAW,UAAU;AAAA,YACrB;AAAA,YACA;AAAA,YACA,QAAQ;AAAA,YACR,SAAS,EAAE,QAAQ,KAAK,IAAI,iBAAiB,KAAK,YAAY;AAAA,UAChE,CAAC;AAAA,QACH;AAGA,YAAI,KAAK,aAAa;AACpB,gBAAM,KAAK,YAAY,SAAS;AAAA,QAClC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,YAAY;AAAA,IACZ,QAAQ;AAAA,MACN,SAAS;AAAA,MACT,cAAc;AAAA,MACd,mBAAmB;AAAA,MACnB,aAAa;AAAA,IACf;AAAA,IACA,YAAY,WAAW,SAAS,IAAI,aAAa;AAAA,EACnD;AACF;;;AC7NO,SAAS,gBACd,OACA,QACgB;AAChB,QAAM,iBAAiB,WAAW,MAAM,UAAU,EAAE,WAAW,GAAG,IAAI,SAAS;AAC/E,MAAI;AAEJ,MAAI;AACF,QAAI,mBAAmB,QAAQ;AAC7B,YAAM,KAAK,MAAM,KAAK;AAAA,IACxB,OAAO;AAEL,YAAM,IAAI,MAAM,8EAA8E;AAAA,IAChG;AAAA,EACF,SAAS,KAAK;AACZ,QAAI,eAAe,aAAa;AAC9B,YAAM,IAAI,0BAA0B,8BAA8B;AAAA,QAChE,WAAW,cAAc,KAAK,IAAI,OAAO;AAAA,MAC3C,CAAC;AAAA,IACH;AACA,UAAM;AAAA,EACR;AAEA,SAAO,mBAAmB,GAAG;AAC/B;AAMA,SAAS,mBAAmB,KAA8B;AACxD,QAAM,SAAmB,CAAC;AAC1B,QAAM,WAAqB,CAAC;AAE5B,MAAI,CAAC,OAAO,OAAO,QAAQ,UAAU;AACnC,UAAM,IAAI,0BAA0B,gCAAgC;AAAA,MAClE;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,MAAM;AAGZ,MAAI,CAAC,IAAI,aAAa,OAAO,IAAI,cAAc,UAAU;AACvD,WAAO,KAAK,oCAAoC;AAAA,EAClD,OAAO;AACL,UAAM,IAAI,IAAI;AACd,QAAI,CAAC,EAAE,MAAM,OAAO,EAAE,OAAO,UAAU;AACrC,aAAO,KAAK,2CAA2C;AAAA,IACzD;AAAA,EACF;AAEA,MAAI,CAAC,IAAI,SAAS,OAAO,IAAI,UAAU,UAAU;AAC/C,WAAO,KAAK,gCAAgC;AAAA,EAC9C,OAAO;AACL,UAAM,IAAI,IAAI;AACd,QAAI,CAAC,EAAE,MAAM,OAAO,EAAE,OAAO,UAAU;AACrC,aAAO,KAAK,uCAAuC;AAAA,IACrD;AAAA,EACF;AAEA,MAAI,CAAC,IAAI,YAAY,CAAC,MAAM,QAAQ,IAAI,QAAQ,KAAK,IAAI,SAAS,WAAW,GAAG;AAC9E,WAAO,KAAK,sCAAsC;AAAA,EACpD,OAAO;AACL,aAAS,IAAI,GAAG,IAAI,IAAI,SAAS,QAAQ,KAAK;AAC5C,YAAM,MAAM,IAAI,SAAS,CAAC;AAC1B,UAAI,CAAC,IAAI,WAAW,OAAO,IAAI,YAAY,UAAU;AACnD,eAAO,KAAK,YAAY,CAAC,sCAAsC;AAAA,MACjE;AACA,UAAI,CAAC,IAAI,UAAU,CAAC,MAAM,QAAQ,IAAI,MAAM,KAAK,IAAI,OAAO,WAAW,GAAG;AACxE,eAAO,KAAK,YAAY,CAAC,oCAAoC;AAAA,MAC/D,OAAO;AACL,iBAAS,IAAI,GAAG,IAAI,IAAI,OAAO,QAAQ,KAAK;AAC1C,gBAAM,IAAI,IAAI,OAAO,CAAC;AACtB,cAAI,OAAO,MAAM,YAAY,EAAE,WAAW,GAAG;AAC3C,mBAAO,KAAK,YAAY,CAAC,YAAY,CAAC,8BAA8B;AAAA,UACtE;AAAA,QACF;AAAA,MACF;AAGA,gCAA0B,KAAK,GAAG,QAAQ,QAAQ;AAAA,IACpD;AAAA,EACF;AAEA,MAAI,IAAI,YAAY,UAAa,IAAI,YAAY,MAAM;AACrD,WAAO,KAAK,kCAAkC;AAAA,EAChD;AAGA,MAAI,IAAI,aAAa,QAAW;AAC9B,qBAAiB,IAAI,UAAU,MAAM;AAAA,EACvC;AAGA,MAAI,IAAI,kBAAkB,QAAW;AACnC,0BAAsB,IAAI,eAAe,MAAM;AAAA,EACjD;AAGA,MAAI,IAAI,UAAU,QAAW;AAC3B,2BAAuB,IAAI,OAAO,MAAM;AAAA,EAC1C;AAEA,MAAI,OAAO,SAAS,GAAG;AACrB,UAAM,MAAM,IAAI;AAAA,MACd,uBAAuB,OAAO,MAAM;AAAA,MACpC;AAAA,IACF;AAEA,IAAC,IAA4D,WAAW;AACxE,UAAM;AAAA,EACR;AAGA,QAAM,MAAM;AACZ,MAAI,OAAO,IAAI,YAAY,UAAU;AACnC,QAAI,UAAU,IAAI;AAAA,EACpB;AACA,MAAI,OAAO,IAAI,cAAc,UAAU;AACrC,QAAI,YAAY,IAAI;AAAA,EACtB;AAEA,SAAO;AACT;AAEA,SAAS,iBAAiB,UAAmB,QAAwB;AACnE,MAAI,OAAO,aAAa,YAAY,aAAa,QAAQ,MAAM,QAAQ,QAAQ,GAAG;AAChF,WAAO,KAAK,mCAAmC;AAC/C;AAAA,EACF;AAEA,QAAM,OAAO,OAAO,KAAK,QAAmC;AAC5D,MAAI,KAAK,SAAS,IAAI;AACpB,WAAO,KAAK,gBAAgB,KAAK,MAAM,gBAAgB;AAAA,EACzD;AAEA,QAAM,aAAa,KAAK,UAAU,QAAQ;AAC1C,MAAI,WAAW,SAAS,MAAM;AAC5B,WAAO;AAAA,MACL,+BAA+B,WAAW,MAAM;AAAA,IAClD;AAAA,EACF;AAEA,QAAM,SAAS;AACf,aAAW,OAAO,MAAM;AAGtB,QAAI,IAAI,WAAW,GAAG,GAAG;AACvB,aAAO;AAAA,QACL,iBAAiB,GAAG;AAAA,MACtB;AAAA,IACF;AACA,UAAM,QAAQ,OAAO,GAAG;AACxB,QACE,UAAU,QACV,OAAO,UAAU,YACjB,OAAO,UAAU,YACjB,OAAO,UAAU,WACjB;AACA,aAAO;AAAA,QACL,aAAa,GAAG,wBAAwB,OAAO,KAAK;AAAA,MACtD;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,0BACP,KACA,OACA,QACA,UACM;AACN,QAAM,aAAa,IAAI;AAEvB,MAAI,eAAe,WAAW;AAC5B,QAAI,CAAC,IAAI,iBAAiB,OAAO,IAAI,kBAAkB,UAAU;AAC/D,aAAO;AAAA,QACL,YAAY,KAAK;AAAA,MAEnB;AACA;AAAA,IACF;AAEA,UAAM,KAAK,IAAI;AAEf,QAAI,CAAC,GAAG,eAAe,CAAC,MAAM,QAAQ,GAAG,WAAW,KAAK,GAAG,YAAY,WAAW,GAAG;AACpF,aAAO;AAAA,QACL,YAAY,KAAK;AAAA,MACnB;AAAA,IACF;AAEA,QAAI,CAAC,GAAG,sBAAsB,OAAO,GAAG,uBAAuB,UAAU;AACvE,aAAO;AAAA,QACL,YAAY,KAAK;AAAA,MACnB;AAAA,IACF;AAEA,QAAI,GAAG,uBAAuB,QAAW;AACvC,UAAI,OAAO,GAAG,uBAAuB,YAAY,GAAG,qBAAqB,OAAO;AAC9E,eAAO;AAAA,UACL,YAAY,KAAK;AAAA,QACnB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,MAAI,eAAe,SAAS,IAAI,eAAe;AAC7C,aAAS;AAAA,MACP,YAAY,KAAK;AAAA,IACnB;AAAA,EACF;AACF;AAEA,SAAS,sBAAsB,UAAmB,QAAwB;AACxE,MAAI,OAAO,aAAa,YAAY,aAAa,MAAM;AACrD,WAAO,KAAK,mCAAmC;AAC/C;AAAA,EACF;AAEA,QAAM,IAAI;AACV,MAAI,CAAC,EAAE,QAAQ,OAAO,EAAE,SAAS,UAAU;AACzC,WAAO,KAAK,iEAAiE;AAAA,EAC/E;AACF;AAEA,SAAS,uBAAuB,OAAgB,QAAwB;AACtE,MAAI,OAAO,UAAU,YAAY,UAAU,MAAM;AAC/C,WAAO,KAAK,2BAA2B;AACvC;AAAA,EACF;AAEA,QAAM,IAAI;AAEV,MAAI,EAAE,UAAU,qBAAqB;AACnC,WAAO,KAAK,2CAA2C;AAAA,EACzD;AAEA,MAAI,EAAE,iBAAiB,QAAW;AAChC,QAAI,OAAO,EAAE,iBAAiB,UAAU;AACtC,aAAO,KAAK,uCAAuC;AAAA,IACrD,OAAO;AAGL,YAAM,iBAAiB;AACvB,UAAI,CAAC,eAAe,KAAK,EAAE,YAAY,GAAG;AACxC,eAAO;AAAA,UACL,kFAAkF,EAAE,YAAY;AAAA,QAClG;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;ACzPA,eAAsB,OACpB,SACA,SACA,OAC2B;AAC3B,QAAM,SAA2B;AAAA,IAC/B;AAAA,IACA,WAAW,oBAAI,KAAK;AAAA,IACpB,WAAW,QAAQ;AAAA,IACnB,QAAQ,QAAQ;AAAA,IAChB,UAAU,CAAC;AAAA,EACb;AAEA,QAAM,MAAM,IAAI,MAAM;AACtB,SAAO;AACT;AAMA,eAAsB,UACpB,SACA,OACkB;AAClB,QAAM,SAAS,MAAM,MAAM,MAAM,OAAO;AACxC,SAAO,WAAW;AACpB;;;ACrCA,IAAM,eAAe,IAAI,iBAAiB;AAK1C,eAAsB,UACpB,SACA,OACA,OACe;AACf,QAAM,IAAI,SAAS;AAEnB,QAAM,YAAwB;AAAA,IAC5B,GAAG;AAAA,IACH;AAAA,IACA,WAAW,oBAAI,KAAK;AAAA,EACtB;AAEA,QAAM,EAAE,OAAO,SAAS;AAC1B;;;ACnBA,IAAMC,gBAAe,IAAI,iBAAiB;AAK1C,eAAsB,cACpB,SACA,SACA,OACuB;AACvB,QAAM,IAAI,SAASA;AACnB,SAAO,EAAE,MAAM,SAAS,OAAO;AACjC;AAKA,eAAsB,uBACpB,SACA,SACA,OACuB;AACvB,QAAM,IAAI,SAASA;AACnB,SAAO,EAAE,eAAe,SAAS,OAAO;AAC1C;;;AC3BA,YAAYC,WAAU;AAQtB,eAAsB,UACpB,SACA,SACiB;AACjB,QAAM,MAAM,QAAQ,cAAc,UAAU,UAAU;AAEtD,QAAM,SAA0C,EAAE,IAAI;AACtD,MAAI,QAAQ,KAAK;AACf,WAAO,MAAM,QAAQ;AAAA,EACvB;AAEA,QAAM,MAAM,MAAM,IAAS;AAAA,IACzB,IAAI,YAAY,EAAE,OAAO,KAAK,UAAU,OAAO,CAAC;AAAA,EAClD,EACG,mBAAmB,MAAM,EACzB,KAAK,QAAQ,UAAU;AAE1B,SAAO;AACT;AAMO,SAAS,aACd,OACyB;AACzB,QAAM,CAAC,SAAS,IAAI,MAAM,MAAM,GAAG;AACnC,MAAI,CAAC,UAAW,OAAM,IAAI,MAAM,6BAA6B;AAC7D,SAAO,KAAK;AAAA,IACV,IAAI,YAAY,EAAE,OAAY,gBAAU,OAAO,SAAS,CAAC;AAAA,EAC3D;AACF;AAKA,eAAsB,gBACpB,OACA,KACkC;AAClC,QAAM,EAAE,QAAQ,IAAI,MAAW,oBAAc,OAAO,GAAG;AACvD,SAAO,KAAK,MAAM,IAAI,YAAY,EAAE,OAAO,OAAO,CAAC;AACrD;;;AC1CA,eAAsB,YACpB,YACA,SACA,eACoB;AAEpB,MAAI,WAAW,UAAU;AACvB,IAAAC,kBAAiB,WAAW,QAAQ;AAAA,EACtC;AAEA,QAAM,MAAM,OAAO,WAAW;AAC9B,QAAM,WAAW,oBAAI,KAAK;AAC1B,QAAM,SAAS,WAAW,UAAU;AACpC,QAAM,WAAW,WAAW,SAAS,IAAI,CAAC,MAAM,EAAE,OAAO;AAGzD,QAAM,UAAmC;AAAA,IACvC;AAAA,IACA,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK,KAAK,MAAM,SAAS,QAAQ,IAAI,GAAI;AAAA,IACzC,KAAK,KAAK;AAAA,OACP,OAAO,WAAW,YAAY,WAC3B,IAAI,KAAK,WAAW,OAAO,IAC3B,WAAW,SACb,QAAQ,IAAI;AAAA,IAChB;AAAA,IACA,YAAY;AAAA,MACV,GAAG,oBAAoB,UAAU;AAAA,MACjC,GAAI,gBAAgB,EAAE,aAAa,cAAc,IAAI,CAAC;AAAA,IACxD;AAAA,EACF;AAEA,MAAI,WAAW,WAAW;AACxB,YAAQ,MAAM,KAAK;AAAA,OAChB,OAAO,WAAW,cAAc,WAC7B,IAAI,KAAK,WAAW,SAAS,IAC7B,WAAW,WACb,QAAQ,IAAI;AAAA,IAChB;AAAA,EACF;AAGA,QAAM,MAAM,MAAM,UAAU,SAAS,OAAO;AAG5C,QAAM,YAAY,IAAI,YAAY,EAAE,OAAO,GAAG,EAAE;AAChD,MAAI,YAAY,MAAM;AACpB,UAAM,IAAI;AAAA,MACR,iBAAiB,SAAS;AAAA,IAC5B;AAAA,EACF;AAEA,QAAM,QAAmB;AAAA,IACvB;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW,IAAI,MAAM,GAAG,EAAE,CAAC;AAAA,IAC3B;AAAA,IACA;AAAA,IACA,aAAa;AAAA,IACb;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAASA,kBAAiB,UAAyC;AACjE,QAAM,OAAO,OAAO,KAAK,QAAQ;AACjC,MAAI,KAAK,SAAS,IAAI;AACpB,UAAM,IAAI;AAAA,MACR,gBAAgB,KAAK,MAAM;AAAA,IAC7B;AAAA,EACF;AAEA,QAAM,aAAa,KAAK,UAAU,QAAQ;AAC1C,MAAI,WAAW,SAAS,MAAM;AAC5B,UAAM,IAAI;AAAA,MACR,+BAA+B,WAAW,MAAM;AAAA,IAClD;AAAA,EACF;AAEA,aAAW,OAAO,MAAM;AACtB,UAAM,QAAQ,SAAS,GAAG;AAC1B,QACE,UAAU,QACV,OAAO,UAAU,YACjB,OAAO,UAAU,YACjB,OAAO,UAAU,WACjB;AACA,YAAM,IAAI;AAAA,QACR,iBAAiB,GAAG,uBAAuB,OAAO,KAAK;AAAA,QACvD;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAMA,SAAS,oBACP,KACyB;AACzB,SAAO;AAAA,IACL,GAAG;AAAA,IACH,SACE,IAAI,mBAAmB,OACnB,IAAI,QAAQ,YAAY,IACxB,IAAI;AAAA,IACV,WACE,IAAI,qBAAqB,OACrB,IAAI,UAAU,YAAY,IAC1B,IAAI;AAAA;AAAA,IAEV,OAAO,IAAI,OAAO,IAAI,CAAC,EAAE,aAAa,GAAG,GAAG,KAAK,MAAM,IAAI;AAAA,EAC7D;AACF;;;AC/GA,eAAsB,cACpB,OACA,SAC2B;AAC3B,QAAM,SAAmB,CAAC;AAC1B,QAAM,WAAqB,CAAC;AAC5B,MAAI;AAEJ,QAAM,SAAS,OAAO,UAAU,WAAW,QAAQ,MAAM;AAGzD,MAAI;AAEJ,MAAI,QAAQ,WAAW;AACrB,gBAAY,QAAQ;AAAA,EACtB,WAAW,QAAQ,aAAa;AAC9B,QAAI;AACF,YAAM,SAAS,aAAa,MAAM;AAClC,YAAM,MAAM,OAAO;AACnB,UAAI,KAAK;AACP,cAAM,WAAW,MAAM,QAAQ,YAAY,QAAQ,GAAG;AACtD,YAAI,UAAU;AACZ,sBAAY;AAAA,QACd,OAAO;AACL,iBAAO,KAAK,uCAAuC,GAAG,GAAG;AAAA,QAC3D;AAAA,MACF,OAAO;AACL,eAAO,KAAK,yDAAyD;AAAA,MACvE;AAAA,IACF,QAAQ;AACN,aAAO,KAAK,kDAAkD;AAAA,IAChE;AAAA,EACF,WAAW,QAAQ,mBAAmB;AAEpC,QAAI;AACF,YAAM,SAAS,aAAa,MAAM;AAElC,YAAM,aAAa,OAAO,MAAM,GAAG,EAAE,CAAC;AACtC,UAAI,YAAY;AACd,cAAM,cAAc,IAAI,YAAY,EAAE;AAAA,UACpC,gBAAgB,UAAU;AAAA,QAC5B;AACA,cAAMC,WAAU,KAAK,MAAM,WAAW;AACtC,cAAM,SAASA,SAAQ;AACvB,YAAI,QAAQ;AACV,sBAAY,MAAM,QAAQ,kBAAkB,MAAM;AAAA,QACpD,OAAO;AACL,iBAAO,KAAK,uDAAuD;AAAA,QACrE;AAAA,MACF;AAAA,IACF,QAAQ;AACN,aAAO,KAAK,wDAAwD;AAAA,IACtE;AAAA,EACF,OAAO;AACL,WAAO;AAAA,MACL;AAAA,IACF;AAAA,EACF;AAMA,QAAM,sBAAsB,QAAQ,cAAc,CAAC,SAAS,OAAO;AACnE,MAAI;AACJ,MAAI;AACF,UAAM,SAAS,aAAa,MAAM;AAClC,gBAAY,OAAO,OAAO,QAAQ,WAAW,OAAO,MAAM;AAAA,EAC5D,QAAQ;AAAA,EAGR;AACA,MAAI,aAAa,CAAC,oBAAoB,SAAS,SAA8B,GAAG;AAC9E,WAAO;AAAA,MACL,cAAc,SAAS,mCAAmC,oBAAoB,KAAK,IAAI,CAAC;AAAA,IAC1F;AAAA,EACF;AAGA,MAAI;AACJ,MAAI,oBAAoB;AAExB,MAAI,aAAa,aAAa,oBAAoB,SAAS,SAA8B,GAAG;AAC1F,QAAI;AACF,gBAAU,MAAM,gBAAgB,QAAQ,SAAS;AACjD,0BAAoB;AAAA,IACtB,QAAQ;AACN,aAAO,KAAK,+BAA+B;AAAA,IAC7C;AAAA,EACF,WAAW,aAAa,CAAC,WAAW;AAGlC,WAAO,KAAK,0BAA0B;AAAA,EACxC;AAIA,MAAI,CAAC,SAAS;AACZ,QAAI;AACF,YAAM,aAAa,OAAO,MAAM,GAAG,EAAE,CAAC;AACtC,UAAI,YAAY;AACd,kBAAU,KAAK;AAAA,UACb,IAAI,YAAY,EAAE,OAAO,gBAAgB,UAAU,CAAC;AAAA,QACtD;AAAA,MACF;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AAEA,MAAI,CAAC,SAAS;AACZ,WAAO,EAAE,OAAO,OAAO,QAAQ,OAAO,SAAS,IAAI,SAAS,CAAC,wBAAwB,GAAG,SAAS;AAAA,EACnG;AAGA,MAAI,mBAAmB;AACrB,QAAI;AACF,oBAAc,eAAe,SAAS,MAAM;AAAA,IAC9C,QAAQ;AACN,aAAO,KAAK,qCAAqC;AAAA,IACnD;AAAA,EACF;AAGA,QAAM,YAAY,QAAQ;AAE1B,MAAI,QAAQ,QAAQ,QAAW;AAC7B,UAAM,cAAc,IAAI,KAAM,QAAQ,MAAiB,GAAI;AAC3D,QAAI,UAAU,aAAa,SAAS,GAAG;AACrC,aAAO,KAAK,oBAAoB,YAAY,YAAY,CAAC,EAAE;AAAA,IAC7D;AAAA,EACF,OAAO;AACL,WAAO,KAAK,qCAAqC;AAAA,EACnD;AAEA,MAAI,QAAQ,QAAQ,QAAW;AAC7B,UAAM,gBAAgB,IAAI,KAAM,QAAQ,MAAiB,GAAI;AAC7D,QAAI,kBAAkB,eAAe,SAAS,GAAG;AAC/C,aAAO,KAAK,0BAA0B,cAAc,YAAY,CAAC,EAAE;AAAA,IACrE;AAAA,EACF;AAGA,QAAM,kBAAkB,QAAQ,oBAAoB;AACpD,MAAI,mBAAmB,QAAQ,mBAAmB,QAAQ,KAAK;AAC7D,UAAM,YAAY,MAAM,QAAQ,gBAAgB;AAAA,MAC9C,QAAQ;AAAA,IACV;AACA,QAAI,WAAW;AACb,aAAO;AAAA,QACL,8BAA8B,UAAU,UAAU,YAAY,CAAC,OAAO,UAAU,SAAS;AAAA,MAC3F;AAAA,IACF;AAAA,EACF;AAGA,QAAM,YAAY,IAAI,YAAY,EAAE,OAAO,MAAM,EAAE;AACnD,MAAI,YAAY,MAAM;AACpB,aAAS,KAAK,iBAAiB,SAAS,wCAAwC;AAAA,EAClF;AAEA,SAAO;AAAA,IACL,OAAO,OAAO,WAAW;AAAA,IACzB;AAAA,IACA,OAAO;AAAA,IACP,UAAU,SAAS,SAAS,IAAI,WAAW;AAAA,EAC7C;AACF;AAKA,SAAS,eACP,SACA,KACW;AACX,QAAM,aAAa,QAAQ;AAC3B,MAAI,CAAC,WAAY,OAAM,IAAI,MAAM,+BAA+B;AAEhE,SAAO;AAAA,IACL,KAAK,QAAQ;AAAA,IACb;AAAA,IACA,UAAU,IAAI,KAAM,QAAQ,MAAiB,GAAI;AAAA,IACjD,WAAW,IAAI,MAAM,GAAG,EAAE,CAAC;AAAA,IAC3B,QAAQ,QAAQ;AAAA,IAChB,UAAU,QAAQ;AAAA,IAClB,aAAc,WAAW,eAA0B;AAAA,IACnD;AAAA,EACF;AACF;AAEA,SAAS,gBAAgB,OAA2B;AAElD,QAAM,SAAS,QAAQ,IAAI,QAAQ,IAAK,MAAM,SAAS,KAAM,CAAC;AAC9D,QAAM,SAAS,KAAK,OAAO,QAAQ,MAAM,GAAG,EAAE,QAAQ,MAAM,GAAG,CAAC;AAChE,QAAM,QAAQ,IAAI,WAAW,OAAO,MAAM;AAC1C,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,UAAM,CAAC,IAAI,OAAO,WAAW,CAAC;AAAA,EAChC;AACA,SAAO;AACT;;;ACpMA,eAAsB,cACpB,eACA,eACA,SACA,OAC2B;AAC3B,QAAM,YAAY,oBAAI,KAAK;AAG3B,aAAW,WAAW,eAAe;AACnC,UAAM,cAAgC;AAAA,MACpC,SAAS;AAAA,MACT;AAAA,MACA,WAAW,QAAQ;AAAA,MACnB,QAAQ,QAAQ,SACZ,YAAY,QAAQ,MAAM,KAC1B,kCAAkC,aAAa;AAAA,MACnD,UAAU,CAAC;AAAA,IACb;AACA,UAAM,MAAM,IAAI,WAAW;AAAA,EAC7B;AAGA,QAAM,eAAiC;AAAA,IACrC,SAAS;AAAA,IACT;AAAA,IACA,WAAW,QAAQ;AAAA,IACnB,QAAQ,QAAQ;AAAA,IAChB,UAAU;AAAA,EACZ;AACA,QAAM,MAAM,IAAI,YAAY;AAE5B,SAAO;AACT;;;ACrCO,SAAS,kBACd,QACA,OACA,eAAuB,GACjB;AACN,QAAM,YAAY,OAAO;AAGzB,MAAI,UAAU,gBAAgB,OAAO;AACnC,UAAM,IAAI;AAAA,MACR;AAAA,MACA,UAAU,SAAS,QAAQ,CAAC,MAAM,EAAE,MAAM;AAAA,MAC1C,MAAM,SAAS,QAAQ,CAAC,MAAM,EAAE,MAAM;AAAA,IACxC;AAAA,EACF;AAGA,MAAI,UAAU,uBAAuB,QAAW;AAC9C,QAAI,gBAAgB,UAAU,oBAAoB;AAChD,YAAM,IAAI;AAAA,QACR,oBAAoB,eAAe,CAAC,+BAA+B,UAAU,kBAAkB;AAAA,QAC/F,UAAU,SAAS,QAAQ,CAAC,MAAM,EAAE,MAAM;AAAA,QAC1C,MAAM,SAAS,QAAQ,CAAC,MAAM,EAAE,MAAM;AAAA,MACxC;AAAA,IACF;AAAA,EACF;AAGA,MAAI,MAAM,YAAY,QAAW;AAC/B,UAAM,WAAW,MAAM,mBAAmB,OACtC,MAAM,QAAQ,QAAQ,IACtB,IAAI,KAAK,MAAM,OAAO,EAAE,QAAQ;AACpC,UAAM,YAAY,UAAU,mBAAmB,OAC3C,UAAU,QAAQ,QAAQ,IAC1B,IAAI,KAAK,UAAU,OAAiB,EAAE,QAAQ;AAElD,QAAI,WAAW,WAAW;AACxB,YAAM,IAAI;AAAA,QACR;AAAA,QACA,UAAU,SAAS,QAAQ,CAAC,MAAM,EAAE,MAAM;AAAA,QAC1C,MAAM,SAAS,QAAQ,CAAC,MAAM,EAAE,MAAM;AAAA,MACxC;AAAA,IACF;AAAA,EACF;AAGA,aAAW,gBAAgB,MAAM,UAAU;AACzC,UAAM,gBAAgB,UAAU,SAAS;AAAA,MACvC,CAAC,MAAM,EAAE,YAAY,aAAa;AAAA,IACpC;AAEA,QAAI,CAAC,eAAe;AAClB,YAAM,IAAI;AAAA,QACR,2BAA2B,aAAa,OAAO;AAAA,QAC/C,UAAU,SAAS,QAAQ,CAAC,MAAM,EAAE,MAAM;AAAA,QAC1C,MAAM,SAAS,QAAQ,CAAC,MAAM,EAAE,MAAM;AAAA,MACxC;AAAA,IACF;AAGA,sBAAkB,eAAe,YAAY;AAG7C,gCAA4B,eAAe,YAAY;AAAA,EACzD;AAGA,MAAI,UAAU,SAAS,UAAU,MAAM,SAAS,GAAG;AACjD;AAAA,MACE,UAAU,MAAM,IAAI,CAAC,MAAM,EAAE,EAAE;AAAA,MAC/B;AAAA,MACA,UAAU,SAAS,QAAQ,CAAC,MAAM,EAAE,MAAM;AAAA,MAC1C,MAAM,SAAS,QAAQ,CAAC,MAAM,EAAE,MAAM;AAAA,IACxC;AAAA,EACF;AACF;AAKA,SAAS,kBACP,QACA,OACM;AACN,aAAW,cAAc,MAAM,QAAQ;AACrC,UAAM,UAAU,OAAO,OAAO;AAAA,MAAK,CAAC,gBAClC,WAAW,aAAa,UAAU;AAAA,IACpC;AACA,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI;AAAA,QACR,gBAAgB,UAAU,iBAAiB,MAAM,OAAO,sCAAsC,OAAO,OAAO,KAAK,IAAI,CAAC;AAAA,QACtH,OAAO;AAAA,QACP,MAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACF;AAWA,SAAS,4BACP,QACA,OACM;AACN,MAAI,CAAC,OAAO,YAAa;AAEzB,aAAW,CAAC,KAAK,WAAW,KAAK,OAAO,QAAQ,OAAO,WAAW,GAAG;AACnE,QAAI,gBAAgB,OAAO;AACzB,YAAM,aAAa,MAAM,cAAc,GAAG;AAC1C,UAAI,eAAe,MAAO;AAC1B,YAAM,IAAI;AAAA,QACR,eAAe,OACX,6BAA6B,GAAG,iBAAiB,MAAM,OAAO,mCAC9D,2BAA2B,GAAG,iBAAiB,MAAM,OAAO;AAAA,QAChE,OAAO;AAAA,QACP,MAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACF;AAMA,SAAS,sBACP,eACA,OACA,cACA,aACM;AACN,QAAM,eAAe,IAAI,IAAI,MAAM,OAAO,IAAI,CAAC,MAAM,EAAE,EAAE,KAAK,CAAC,CAAC;AAChE,aAAW,gBAAgB,eAAe;AACxC,QAAI,CAAC,aAAa,IAAI,YAAY,GAAG;AACnC,YAAM,IAAI;AAAA,QACR,8BAA8B,YAAY;AAAA,QAC1C;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;ACnJA,eAAsB,SACpB,aACA,UACA,SACoB;AAMpB,QAAM,eAAe,WAAW,WAAW;AAG3C,QAAM,YAAY,YAAY;AAG9B,QAAM,cAAc,UAAU,SAAS,CAAC;AACxC,QAAM,mBAAmB,SAAS,SAAS,CAAC,GAAG;AAAA,IAC7C,CAAC,OAAO,CAAC,YAAY,KAAK,CAAC,OAAO,GAAG,OAAO,GAAG,EAAE;AAAA,EACnD;AACA,QAAM,cAAc,CAAC,GAAG,aAAa,GAAG,eAAe;AAGvD,QAAM,aAAa,eAAe;AAClC,QAAM,gBAAgB;AAAA,IACpB,GAAG,SAAS;AAAA,IACZ,kBAAkB;AAAA,EACpB;AAQA,QAAM,oBAAoB,SAAS,SAAS,IAAI,CAAC,aAAa;AAC5D,UAAM,YAAY,UAAU,SAAS,KAAK,CAAC,MAAM,EAAE,YAAY,SAAS,OAAO;AAC/E,QAAI,CAAC,WAAW,YAAa,QAAO;AAEpC,UAAM,YAAmE,CAAC;AAC1E,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,UAAU,WAAW,GAAG;AAChE,UAAI,UAAU,OAAO;AACnB,kBAAU,GAAG,IAAI;AAAA,MACnB;AAAA,IACF;AACA,QAAI,OAAO,KAAK,SAAS,EAAE,WAAW,EAAG,QAAO;AAEhD,WAAO;AAAA,MACL,GAAG;AAAA,MACH,aAAa,EAAE,GAAG,WAAW,GAAG,SAAS,YAAY;AAAA,IACvD;AAAA,EACF,CAAC;AAGD;AAAA,IACE;AAAA,IACA,EAAE,GAAG,UAAU,UAAU,mBAAmB,OAAO,YAAY;AAAA,IAC/D;AAAA,EACF;AAEA,QAAM,iBAAiC;AAAA,IACrC,WAAW,UAAU;AAAA;AAAA,IACrB,OAAO,SAAS;AAAA,IAChB,eAAe,UAAU;AAAA,IACzB,UAAU;AAAA,IACV,OAAO,YAAY,SAAS,IAAI,cAAc;AAAA,IAC9C,SAAS,SAAS,WAAW,UAAU;AAAA,IACvC,WAAW,UAAU;AAAA,IACrB,aAAa,UAAU;AAAA,IACvB,oBAAoB,UAAU;AAAA,IAC9B,UAAU;AAAA,IACV,OAAO,UAAU;AAAA,EACnB;AAGA,QAAM,aAAa,MAAM,YAAY,gBAAgB,SAAS,YAAY,GAAG;AAE7E,SAAO;AACT;AASA,SAAS,WAAW,OAA0B;AAC5C,QAAM,SAAS,MAAM,WAAW,UAAU;AAC1C,MAAI,OAAO,WAAW,SAAU,QAAO;AAGvC,SAAO,MAAM,cAAc,IAAI;AACjC;;;ACzFA,eAAsB,YACpB,OACA,OACkC;AAClC,QAAM,SAAmB,CAAC;AAC1B,MAAI;AAEJ,MAAI,MAAM,WAAW,GAAG;AACtB,WAAO;AAAA,MACL,OAAO;AAAA,MACP,OAAO;AAAA,MACP,QAAQ,CAAC,gBAAgB;AAAA,MACzB,MAAM;AAAA,MACN,MAAM;AAAA,IACR;AAAA,EACF;AAEA,MAAI,MAAM,WAAW,GAAG;AAEtB,UAAM,QAAQ,MAAM,CAAC;AACrB,UAAM,mBAAmB,OAAO,GAAG,QAAQ,KAAK;AAChD,WAAO;AAAA,MACL,OAAO,OAAO,WAAW;AAAA,MACzB,OAAO;AAAA,MACP;AAAA,MACA,UAAU,OAAO,SAAS,IAAI,IAAI;AAAA,MAClC,MAAM;AAAA,MACN,MAAM;AAAA,IACR;AAAA,EACF;AAGA,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,UAAM,QAAQ,MAAM,CAAC;AACrB,UAAM,eAAe,OAAO;AAG5B,UAAM,mBAAmB,OAAO,GAAG,QAAQ,KAAK;AAGhD,QAAI,IAAI,GAAG;AACT,YAAM,SAAS,MAAM,IAAI,CAAC;AAC1B,uBAAiB,QAAQ,OAAO,GAAG,MAAM;AAGzC,UAAI,MAAM,gBAAgB,OAAO,KAAK;AACpC,eAAO;AAAA,UACL,cAAc,CAAC,kBAAkB,MAAM,WAAW,gCAAgC,OAAO,GAAG;AAAA,QAC9F;AAAA,MACF;AAAA,IACF;AAGA,QAAI,aAAa,UAAa,OAAO,SAAS,cAAc;AAC1D,iBAAW;AAAA,IACb;AAAA,EACF;AAEA,SAAO;AAAA,IACL,OAAO,OAAO,WAAW;AAAA,IACzB,OAAO,MAAM,SAAS;AAAA,IACtB;AAAA,IACA;AAAA,IACA,MAAM,MAAM,CAAC;AAAA,IACb,MAAM,MAAM,MAAM,SAAS,CAAC;AAAA,EAC9B;AACF;AAKA,eAAe,mBACb,OACA,OACA,QACA,OACe;AAEf,MAAI,UAAU,MAAM,WAAW,SAAS,CAAC,GAAG;AAC1C,WAAO,KAAK,cAAc,KAAK,YAAY,MAAM,GAAG,eAAe;AAAA,EACrE;AAGA,MAAI,OAAO;AACT,UAAM,SAAS,MAAM,MAAM,MAAM,MAAM,GAAG;AAC1C,QAAI,QAAQ;AACV,aAAO;AAAA,QACL,cAAc,KAAK,YAAY,MAAM,GAAG;AAAA,MAC1C;AAAA,IACF;AAAA,EACF;AACF;AAOA,SAAS,iBACP,QAMA,OAMA,OACA,QACM;AAEN,aAAW,gBAAgB,MAAM,WAAW,UAAU;AACpD,UAAM,gBAAgB,OAAO,WAAW,SAAS;AAAA,MAC/C,CAAC,MAAM,EAAE,YAAY,aAAa;AAAA,IACpC;AAEA,QAAI,CAAC,eAAe;AAClB,aAAO;AAAA,QACL,cAAc,KAAK,cAAc,aAAa,OAAO;AAAA,MACvD;AACA;AAAA,IACF;AAGA,eAAW,cAAc,aAAa,QAAQ;AAC5C,YAAM,UAAU,cAAc,OAAO;AAAA,QAAK,CAAC,OACzC,WAAW,IAAI,UAAU;AAAA,MAC3B;AACA,UAAI,CAAC,SAAS;AACZ,eAAO;AAAA,UACL,cAAc,KAAK,YAAY,UAAU,SAAS,aAAa,OAAO;AAAA,QACxE;AAAA,MACF;AAAA,IACF;AAKA,QAAI,cAAc,aAAa;AAC7B,iBAAW,CAAC,KAAK,WAAW,KAAK,OAAO,QAAQ,cAAc,WAAW,GAAG;AAC1E,YAAI,gBAAgB,OAAO;AACzB,gBAAM,aAAa,aAAa,cAAc,GAAG;AACjD,cAAI,eAAe,OAAO;AACxB,mBAAO;AAAA,cACL,cAAc,KAAK,iBAAiB,GAAG,SAAS,aAAa,OAAO,6CAA6C,eAAe,SAAY,cAAc,KAAK,UAAU,UAAU,CAAC;AAAA,YACtL;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,QAAM,WAAW,MAAM,WAAW,mBAAmB,OACjD,MAAM,WAAW,QAAQ,QAAQ,IACjC,IAAI,KAAK,MAAM,WAAW,OAAiB,EAAE,QAAQ;AACzD,QAAM,YAAY,OAAO,WAAW,mBAAmB,OACnD,OAAO,WAAW,QAAQ,QAAQ,IAClC,IAAI,KAAK,OAAO,WAAW,OAAiB,EAAE,QAAQ;AAE1D,MAAI,WAAW,WAAW;AACxB,WAAO;AAAA,MACL,cAAc,KAAK;AAAA,IACrB;AAAA,EACF;AACF;;;ACtKO,SAAS,yBAAyB,OAAyD;AAChG,QAAM,MAAgB,CAAC;AACvB,QAAM,OAAO,oBAAI,IAAY;AAE7B,QAAM,OAAO,CAAC,UAAyB;AACrC,QAAI,OAAO,UAAU,YAAY,MAAM,WAAW,KAAK,KAAK,IAAI,KAAK,GAAG;AACtE;AAAA,IACF;AACA,SAAK,IAAI,KAAK;AACd,QAAI,KAAK,KAAK;AAAA,EAChB;AAEA,QAAM,QAAQ;AACd,QAAM,aAAa,cAAc,KAAK,IAAI,MAAM,aAAc;AAE9D,OAAK,MAAM,WAAW;AACtB,OAAK,YAAY,WAAW;AAE5B,QAAM,QAAQ,YAAY;AAC1B,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,eAAW,QAAQ,OAAO;AACxB,UAAI,OAAO,SAAS,UAAU;AAC5B,aAAK,IAAI;AAAA,MACX,WAAW,QAAQ,OAAO,SAAS,UAAU;AAC3C,aAAM,KAAwB,aAAa;AAAA,MAC7C;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,cAAc,OAAoC;AACzD,SAAO,QAAQ,SAAS,OAAO,UAAU,YAAY,gBAAgB,KAAK;AAC5E;;;AC1DA,YAAYC,WAAU;AAgCtB,eAAsB,eACpB,WACA,SACc;AACd,QAAM,WAAW,MAAW,gBAAU,SAAS;AAC/C,QAAM,MAAM,QAAQ,OAAO,iBAAiB,QAAQ;AACpD,SAAO;AAAA,IACL,GAAI;AAAA,IACJ,KAAK,QAAQ;AAAA,IACb,KAAK,QAAQ,OAAO;AAAA,IACpB;AAAA,EACF;AACF;AAGO,SAAS,UAAU,MAAmB;AAC3C,SAAO,EAAE,KAAK;AAChB;AAuBO,SAAS,mBACd,KACA,UAA+B,CAAC,GACnB;AACb,MAAI,CAAC,QAAQ,SAAS,CAAC,QAAQ,iBAAiB,CAAC,IAAI,WAAW,UAAU,GAAG;AAC3E,UAAM,IAAI;AAAA,MACR,oCAAoC,KAAK,UAAU,GAAG,CAAC;AAAA,IAEzD;AAAA,EACF;AACA,QAAM,gBAAgB,QAAQ,iBAAiB,KAAK,KAAK;AACzD,QAAM,aAAa,QAAQ,cAAc,KAAK,KAAK,KAAK;AACxD,QAAM,YAAY,QAAQ,SAAS;AAEnC,MAAI,QAAkD;AACtD,MAAI,WAAiC;AAErC,iBAAe,YAA2B;AACxC,UAAM,WAAW,MAAM,UAAU,KAAK;AAAA,MACpC,SAAS,EAAE,QAAQ,6CAA6C;AAAA,IAClE,CAAC;AACD,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,IAAI,MAAM,sBAAsB,SAAS,MAAM,IAAI,SAAS,UAAU,EAAE;AAAA,IAChF;AACA,UAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,QAAI,CAAC,QAAQ,CAAC,MAAM,QAAQ,KAAK,IAAI,GAAG;AACtC,YAAM,IAAI,MAAM,8CAA8C;AAAA,IAChE;AACA,WAAO;AAAA,EACT;AAEA,iBAAe,UAAyB;AACtC,UAAM,MAAM,KAAK,IAAI;AACrB,QAAI,SAAS,MAAM,MAAM,YAAY,eAAe;AAClD,aAAO,MAAM;AAAA,IACf;AACA,QAAI,UAAU;AACZ,aAAO;AAAA,IACT;AACA,eAAW,UAAU,EAClB,KAAK,CAAC,SAAS;AACd,cAAQ,EAAE,WAAW,KAAK,IAAI,GAAG,KAAK;AACtC,aAAO;AAAA,IACT,CAAC,EACA,MAAM,CAAC,QAAQ;AACd,UAAI,SAAS,MAAM,MAAM,YAAY,YAAY;AAC/C,eAAO,MAAM;AAAA,MACf;AACA,YAAM;AAAA,IACR,CAAC,EACA,QAAQ,MAAM;AACb,iBAAW;AAAA,IACb,CAAC;AACH,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,MAAM,QAAQ,KAAwC;AACpD,YAAM,OAAO,MAAM,QAAQ;AAC3B,YAAM,QAAQ,KAAK,KAAK,KAAK,CAAC,MAAM,EAAE,QAAQ,GAAG;AACjD,UAAI,CAAC,MAAO,QAAO;AACnB,YAAM,MAAM,MAAW,gBAAU,OAAmB,MAAM,GAAG;AAC7D,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAEA,SAAS,iBAAiB,KAAuB;AAC/C,MAAI,IAAI,QAAQ,SAAS,IAAI,QAAQ,UAAW,QAAO;AACvD,MAAI,IAAI,QAAQ,QAAQ,IAAI,QAAQ,QAAS,QAAO;AACpD,SAAO,IAAI,OAAO;AACpB;;;AC1GO,SAAS,aAAa,SAAyC;AACpE,QAAM,kBAAkB,SAAS,mBAAmB,IAAI,sBAAsB;AAC9E,QAAM,aAAa,SAAS,cAAc,IAAI,iBAAiB;AAC/D,QAAM,cAAc,SAAS;AAC7B,QAAM,wBAAwB,SAAS;AAEvC,WAAS,oBAAoB,MAAuC;AAClE,QAAI,CAAC,QAAQ,CAAC,uBAAuB,YAAY;AAC/C,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,MACL,GAAG;AAAA,MACH,GAAG;AAAA,IACL;AAAA,EACF;AAEA,SAAO;AAAA,IACL,MAAM,YACJ,YACA,MACoB;AACpB,aAAO,YAAY,YAAY,oBAAoB,IAAI,CAAC;AAAA,IAC1D;AAAA,IAEA,gBACE,OACA,QACgB;AAChB,aAAO,gBAAgB,OAAO,MAAM;AAAA,IACtC;AAAA,IAEA,MAAM,cACJ,OACA,MAC2B;AAC3B,aAAO,cAAc,OAAO;AAAA,QAC1B,GAAG;AAAA,QACH,aAAa,MAAM,eAAe;AAAA,QAClC;AAAA,QACA,iBAAiB,MAAM,mBAAmB;AAAA,MAC5C,CAAC;AAAA,IACH;AAAA,IAEA,MAAM,gBACJ,WACwB;AACxB,aAAOC,iBAAgB,SAAS;AAAA,IAClC;AAAA,IAEA,WACE,OACA,SACA,QACkB;AAClB,aAAO,WAAW,OAAO,SAAS,MAAM;AAAA,IAC1C;AAAA,IAEA,gBACE,OACA,SACA,YACkB;AAClB,aAAO,gBAAgB,OAAO,SAAS,UAAU;AAAA,IACnD;AAAA,IAEA,MAAM,UACJ,OACA,SACA,QACA,MAC8B;AAC9B,aAAO,UAAU,OAAO,SAAS,QAAQ;AAAA,QACvC,GAAG;AAAA,QACH;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IAEA,MAAM,SACJ,aACA,UACA,MACoB;AACpB,aAAO,SAAS,aAAa,UAAU,oBAAoB,IAAI,CAAC;AAAA,IAClE;AAAA,IAEA,MAAM,YACJ,OACkC;AAClC,aAAO,YAAY,OAAO,eAAe;AAAA,IAC3C;AAAA,IAEA,MAAM,OACJ,SACA,MAC2B;AAC3B,aAAO,OAAO,SAAS,MAAM,eAAe;AAAA,IAC9C;AAAA,IAEA,MAAM,UAAU,SAAmC;AACjD,aAAO,UAAU,SAAS,eAAe;AAAA,IAC3C;AAAA,IAEA,MAAM,UACJ,SACA,OACe;AACf,aAAO,UAAU,SAAS,OAAO,UAAU;AAAA,IAC7C;AAAA,IAEA,MAAM,cACJ,SACA,MACuB;AACvB,aAAO,cAAc,SAAS,MAAM,UAAU;AAAA,IAChD;AAAA,IAEA,MAAM,uBACJ,SACA,MACuB;AACvB,aAAO,uBAAuB,SAAS,MAAM,UAAU;AAAA,IACzD;AAAA,EACF;AACF;;;AC5IO,IAAM,OAAN,MAAW;AAAA,EACC;AAAA,EAER;AAAA,EAUA;AAAA,EAST,YAAY,UAAuB,CAAC,GAAG;AACrC,UAAM,EAAE,YAAY,WAAW,KAAK,GAAG,cAAc,IAAI;AAEzD,SAAK,SAAS,aAAa;AAAA,MACzB,GAAG;AAAA,MACH,uBAAuB,aACnB,EAAE,YAAY,WAAW,IAAI,IAC7B;AAAA,IACN,CAAC;AAED,SAAK,SAAS;AAAA,MACZ,QAAQ,CAAC,YAAY,mBACnB,KAAK,OAAO,YAAY,YAAY,cAAc;AAAA,MACpD,aAAa,OAAO,OAAO,mBACzB,KAAK,OAAO,YAAY,oBAAoB,KAAK,GAAG,cAAc;AAAA,MACpE,UAAU,CAAC,OAAO,sBAChB,KAAK,OAAO,cAAc,OAAO,iBAAiB;AAAA,MACpD,OAAO,CAAC,OAAO,WACb,KAAK,OAAO,gBAAgB,OAAO,MAAM;AAAA,IAC7C;AAEA,SAAK,iBAAiB;AAAA,MACpB,OAAO,CAAC,OAAO,SAAS,QAAQ,qBAC9B,KAAK,OAAO,UAAU,OAAO,SAAS,QAAQ,gBAAgB;AAAA,IAClE;AAAA,EACF;AAAA,EAEA,MAAM,gBAAgB,WAAuD;AAC3E,WAAO,KAAK,OAAO,gBAAgB,SAAS;AAAA,EAC9C;AACF;AAEA,SAAS,oBAAoB,OAAyC;AACpE,QAAM,SAAmB,CAAC;AAE1B,MAAI,CAAC,SAAS,OAAO,UAAU,UAAU;AACvC,UAAM,kBAAkB,CAAC,yBAAyB,CAAC;AAAA,EACrD;AAEA,QAAM,YAAY,mBAAmB,MAAM,WAAW,MAAM;AAC5D,QAAM,QAAQ,eAAe,MAAM,OAAO,MAAM;AAChD,QAAM,WAAW,kBAAkB,OAAO,MAAM;AAChD,QAAM,UAAU,iBAAiB,OAAO,MAAM;AAE9C,MAAI,OAAO,SAAS,KAAK,CAAC,aAAa,CAAC,SAAS,SAAS,WAAW,KAAK,CAAC,SAAS;AAClF,UAAM,kBAAkB,MAAM;AAAA,EAChC;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAI,MAAM,QAAQ,EAAE,OAAO,MAAM,MAAM,IAAI,CAAC;AAAA,IAC5C,GAAI,MAAM,cAAc,SAAY,EAAE,WAAW,MAAM,UAAU,IAAI,CAAC;AAAA,IACtE,GAAI,MAAM,gBAAgB,SAAY,EAAE,aAAa,MAAM,YAAY,IAAI,CAAC;AAAA,IAC5E,GAAI,MAAM,uBAAuB,SAC7B,EAAE,oBAAoB,MAAM,mBAAmB,IAC/C,CAAC;AAAA,IACL,GAAI,MAAM,WAAW,EAAE,UAAU,MAAM,SAAS,IAAI,CAAC;AAAA,IACrD,GAAI,MAAM,gBAAgB,EAAE,eAAe,MAAM,cAAc,IAAI,CAAC;AAAA,IACpE,GAAI,MAAM,QAAQ,EAAE,OAAO,MAAM,MAAM,IAAI,CAAC;AAAA,EAC9C;AACF;AAEA,SAAS,mBACP,WACA,QACuB;AACvB,MAAI,OAAO,cAAc,YAAY,UAAU,KAAK,GAAG;AACrD,WAAO,EAAE,IAAI,UAAU,KAAK,EAAE;AAAA,EAChC;AACA,MAAI,aAAa,OAAO,cAAc,YAAY,UAAU,IAAI;AAC9D,WAAO;AAAA,EACT;AACA,SAAO,KAAK,oDAAoD;AAChE,SAAO;AACT;AAEA,SAAS,eACP,OACA,QACmB;AACnB,MAAI,OAAO,UAAU,YAAY,MAAM,KAAK,GAAG;AAC7C,WAAO,EAAE,IAAI,MAAM,KAAK,EAAE;AAAA,EAC5B;AACA,MAAI,SAAS,OAAO,UAAU,YAAY,MAAM,IAAI;AAClD,WAAO;AAAA,EACT;AACA,SAAO,KAAK,gDAAgD;AAC5D,SAAO;AACT;AAEA,SAAS,kBACP,OACA,QACwB;AACxB,MAAI,MAAM,UAAU;AAClB,QAAI,CAAC,MAAM,QAAQ,MAAM,QAAQ,KAAK,MAAM,SAAS,WAAW,GAAG;AACjE,aAAO,KAAK,kDAAkD;AAC9D,aAAO,CAAC;AAAA,IACV;AACA,WAAO,MAAM;AAAA,EACf;AAEA,MAAI,CAAC,MAAM,SAAS;AAClB,WAAO,KAAK,iDAAiD;AAC7D,WAAO,CAAC;AAAA,EACV;AACA,MAAI,CAAC,MAAM,UAAU,CAAC,MAAM,QAAQ,MAAM,MAAM,KAAK,MAAM,OAAO,WAAW,GAAG;AAC9E,WAAO,KAAK,8DAA8D;AAC1E,WAAO,CAAC;AAAA,EACV;AAEA,SAAO,CAAC;AAAA,IACN,SAAS,MAAM;AAAA,IACf,QAAQ,MAAM;AAAA,IACd,GAAI,MAAM,cAAc,EAAE,aAAa,MAAM,YAAY,IAAI,CAAC;AAAA,IAC9D,GAAI,MAAM,aAAa,EAAE,YAAY,MAAM,WAAW,IAAI,CAAC;AAAA,IAC3D,GAAI,MAAM,gBAAgB,EAAE,eAAe,MAAM,cAAc,IAAI,CAAC;AAAA,IACpE,GAAI,MAAM,YAAY,EAAE,WAAW,MAAM,UAAU,IAAI,CAAC;AAAA,EAC1D,CAAC;AACH;AAEA,SAAS,iBACP,OACA,QAC2B;AAC3B,MAAI,MAAM,WAAW,MAAM,WAAW;AACpC,WAAO,KAAK,4CAA4C;AACxD,WAAO;AAAA,EACT;AACA,MAAI,MAAM,SAAS;AACjB,WAAO,MAAM;AAAA,EACf;AACA,MAAI,MAAM,WAAW;AACnB,WAAO,qBAAqB,MAAM,SAAS;AAAA,EAC7C;AACA,SAAO,KAAK,kCAAkC;AAC9C,SAAO;AACT;AAEA,SAAS,qBAAqB,UAAwB;AACpD,QAAM,QAAQ,kBAAkB,KAAK,QAAQ;AAC7C,MAAI,CAAC,OAAO;AACV,UAAM,kBAAkB;AAAA,MACtB;AAAA,IACF,CAAC;AAAA,EACH;AAEA,QAAM,SAAS,OAAO,MAAM,CAAC,CAAC;AAC9B,MAAI,CAAC,OAAO,cAAc,MAAM,KAAK,UAAU,GAAG;AAChD,UAAM,kBAAkB,CAAC,+CAA+C,CAAC;AAAA,EAC3E;AAEA,QAAM,SAAiC;AAAA,IACrC,GAAG;AAAA,IACH,GAAG,KAAK;AAAA,IACR,GAAG,KAAK,KAAK;AAAA,IACb,GAAG,KAAK,KAAK,KAAK;AAAA,EACpB;AAEA,SAAO,IAAI,KAAK,KAAK,IAAI,IAAI,SAAS,OAAO,MAAM,CAAC,CAAC,CAAC;AACxD;AAEA,SAAS,kBAAkB,QAAyB;AAClD,SAAO,IAAI;AAAA,IACT;AAAA,MACE;AAAA,MACA,GAAG,OAAO,IAAI,CAAC,UAAU,KAAK,KAAK,EAAE;AAAA,MACrC;AAAA,IACF,EAAE,KAAK,IAAI;AAAA,EACb;AACF;","names":["generateKeyPair","defaultStore","jose","validateMetadata","payload","jose","generateKeyPair"]}
|