export type TangledErrorCode = | 'bad-ref' | 'repo-not-found' | 'no-knot' | 'remote-moved' | 'auth-failed' | 'push-rejected' | 'bad-change' | 'token-failed' | 'too-large' | 'insecure-knot'; /** Push tokens go only over https, or over plain http to loopback, which tests use. */ export function assertSecureKnot(url: string): void { const parsed = URL.parse(url); const loopback = parsed?.protocol === 'http:' && ['127.0.0.1', 'localhost', '[::1]'].includes(parsed.hostname); if (parsed?.protocol !== 'https:' && !loopback) { throw new TangledError('insecure-knot', `refusing to send a push token to ${url}, which is not https`); } } export class TangledError extends Error { readonly code: TangledErrorCode; constructor(code: TangledErrorCode, message: string, options?: { cause?: unknown }) { super(message, options); this.name = 'TangledError'; this.code = code; } }