Archify Diagram Viewer 0.1.0
VS Code extension that previews Archify diagrams from their JSON sources (live, as you type) and opens rendered Archify HTML in a viewer tab. Bundles the Archify 3.0.1 renderer and runs it on VS Code's Node runtime. Adds validation diagnostics, JSON schema help, source-link navigation, export saving, render-to-file and open-in-browser commands. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
// Repository identity and forge links are independent of local Git object checks.
|
||||
// This module never contacts a remote server or reads the user's SSH config.
|
||||
export function parseRepositoryRemote(value, { authored = false } = {}) {
|
||||
if (typeof value !== 'string') return null;
|
||||
const raw = authored ? value : value.trim();
|
||||
if (!raw || /[\s\\\u0000-\u001f\u007f?#]/.test(raw)) return null;
|
||||
const scp = raw.match(/^git@([^/:]+):(.+)$/);
|
||||
const scpAbsolute = Boolean(scp && scp[2].startsWith('/'));
|
||||
const expanded = scp ? `ssh://git@${scp[1]}/${scp[2].replace(/^\//, '')}` : raw;
|
||||
const match = expanded.match(/^(https?|ssh):\/\/([^/]+)\/(.+)$/i);
|
||||
if (!match) return null;
|
||||
// Validate the original path before URL parsing can collapse dot segments.
|
||||
let segments;
|
||||
try {
|
||||
segments = match[3].replace(/\/$/, '').split('/');
|
||||
// Git passes SCP paths literally; percent escapes are decoded only in URIs.
|
||||
if (!scp) segments = segments.map(decodeURIComponent);
|
||||
}
|
||||
catch { return null; }
|
||||
if (segments.some((part) => !part || part === '.' || part === '..' || /[/\\\s\u0000-\u001f\u007f?#]/.test(part))) return null;
|
||||
let url;
|
||||
try { url = new URL(expanded); } catch { return null; }
|
||||
const protocol = url.protocol;
|
||||
if (protocol === 'ssh:' && (url.username !== 'git' || url.password)) return null;
|
||||
if (authored && protocol !== 'ssh:' && (url.username || url.password)) return null;
|
||||
const hostname = url.hostname.toLowerCase();
|
||||
if (!hostname) return null;
|
||||
const provider = hostname === 'github.com' ? 'github' : hostname === 'gitee.com' ? 'gitee' : null;
|
||||
const last = segments.length - 1;
|
||||
if (provider) segments[last] = segments[last].replace(provider === 'github' ? /\.git$/i : /\.git$/, '');
|
||||
if (!segments[last] || segments[last] === '.' || segments[last] === '..') return null;
|
||||
const repositoryPath = segments.join('/');
|
||||
// Only known forges map HTTPS and SSH to one repository namespace. Other
|
||||
// hosts retain transport, port and remote-relative/absolute path semantics.
|
||||
const port = url.port || (protocol === 'ssh:' ? '22' : protocol === 'https:' ? '443' : '80');
|
||||
const endpoint = provider && ((protocol === 'https:' && port === '443') || (protocol === 'ssh:' && port === '22'))
|
||||
? 'standard' : `${protocol}${port}`;
|
||||
const pathKind = provider ? 'repository' : scp && !scpAbsolute ? 'relative' : 'absolute';
|
||||
// path-contract-allow: url-path -- GitHub repository names are case-insensitive URL identities.
|
||||
const identityPath = provider === 'github' ? repositoryPath.toLowerCase() : repositoryPath;
|
||||
const encodedPath = segments.map(encodeURIComponent).join('/');
|
||||
const canonicalUrl = scp ? `git@${hostname}:${scpAbsolute ? '/' : ''}${repositoryPath}`
|
||||
: `${protocol}//${protocol === 'ssh:' ? 'git@' : ''}${url.host}/${encodedPath}`;
|
||||
return { identity: JSON.stringify([hostname, endpoint, pathKind, identityPath]), url: canonicalUrl, provider, protocol, path: repositoryPath, endpoint };
|
||||
}
|
||||
|
||||
export function redactRepositoryRemote(value) {
|
||||
return String(value || '')
|
||||
.replace(/^((?:https?|ssh):\/\/)[^/]*@/i, '$1REDACTED@')
|
||||
.replace(/[?#].*$/s, '?REDACTED');
|
||||
}
|
||||
|
||||
export function repositorySourceHref(provider, url, revision, source) {
|
||||
const encodedPath = source.path.split('/').map(encodeURIComponent).join('/');
|
||||
const end = source.endLine && source.endLine !== source.line
|
||||
? `-${provider === 'github' ? 'L' : ''}${source.endLine}` : '';
|
||||
const fragment = source.line ? `#L${source.line}${end}` : '';
|
||||
return `${url}/blob/${revision}/${encodedPath}${fragment}`;
|
||||
}
|
||||
Reference in New Issue
Block a user