60 lines
2.2 KiB
TypeScript
60 lines
2.2 KiB
TypeScript
import type {
|
|
DomainRuntimeHandoffCandidate,
|
|
DomainRuntimeHandoffSource,
|
|
} from './domain-access-orchestrator.js';
|
|
|
|
const IDENTIFIER_PATTERN = /^[A-Z0-9][A-Z0-9._:-]{1,159}$/;
|
|
|
|
export interface DomainRuntimeHandoffRequest {
|
|
domainId: string;
|
|
nodeId: string;
|
|
}
|
|
|
|
export interface DomainRuntimeHandoffTransport {
|
|
request(input: Readonly<DomainRuntimeHandoffRequest>): Promise<unknown>;
|
|
}
|
|
|
|
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
}
|
|
|
|
function hasExactKeys(value: Record<string, unknown>, expected: readonly string[]): boolean {
|
|
const actual = Object.keys(value).sort();
|
|
const keys = [...expected].sort();
|
|
return actual.length === keys.length && actual.every((key, index) => key === keys[index]);
|
|
}
|
|
|
|
function parseResponse(input: unknown): Readonly<DomainRuntimeHandoffCandidate> | null {
|
|
if (!isRecord(input)
|
|
|| !hasExactKeys(input, ['handoff', 'schema', 'signer_lookup'])
|
|
|| input.schema !== 'gh-aios.domain-runtime-handoff-response/v1'
|
|
|| !isRecord(input.handoff)
|
|
|| !isRecord(input.signer_lookup)
|
|
|| !hasExactKeys(input.signer_lookup, ['repository_id', 'signer_id'])
|
|
|| typeof input.signer_lookup.repository_id !== 'string'
|
|
|| !IDENTIFIER_PATTERN.test(input.signer_lookup.repository_id)
|
|
|| typeof input.signer_lookup.signer_id !== 'string'
|
|
|| !IDENTIFIER_PATTERN.test(input.signer_lookup.signer_id)) {
|
|
return null;
|
|
}
|
|
return Object.freeze({
|
|
handoff: input.handoff,
|
|
signerLookup: Object.freeze({
|
|
repositoryId: input.signer_lookup.repository_id,
|
|
signerId: input.signer_lookup.signer_id,
|
|
}),
|
|
});
|
|
}
|
|
|
|
export class StrictDomainRuntimeHandoffSource implements DomainRuntimeHandoffSource {
|
|
constructor(private readonly transport: DomainRuntimeHandoffTransport) {}
|
|
|
|
async read(domainId: string, nodeId: string): Promise<Readonly<DomainRuntimeHandoffCandidate> | null> {
|
|
if (!IDENTIFIER_PATTERN.test(domainId) || !IDENTIFIER_PATTERN.test(nodeId)) return null;
|
|
try {
|
|
return parseResponse(await this.transport.request(Object.freeze({ domainId, nodeId })));
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
}
|