@bluesky-social/syntax
Version:
Validation for atproto identifiers and formats: DID, handle, NSID, AT URI, etc
160 lines • 4.95 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AtUri = exports.ATP_URI_REGEX = void 0;
__exportStar(require("./aturi_validation"), exports);
exports.ATP_URI_REGEX =
// proto- --did-------------- --name---------------- --path---- --query-- --hash--
/^(at:\/\/)?((?:did:[a-z0-9:%-]+)|(?:[a-z0-9][a-z0-9.:-]*))(\/[^?#\s]*)?(\?[^#\s]+)?(#[^\s]+)?$/i;
// --path----- --query-- --hash--
const RELATIVE_REGEX = /^(\/[^?#\s]*)?(\?[^#\s]+)?(#[^\s]+)?$/i;
class AtUri {
constructor(uri, base) {
Object.defineProperty(this, "hash", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "host", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "pathname", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "searchParams", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
let parsed;
if (base) {
parsed = parse(base);
if (!parsed) {
throw new Error(`Invalid at uri: ${base}`);
}
const relativep = parseRelative(uri);
if (!relativep) {
throw new Error(`Invalid path: ${uri}`);
}
Object.assign(parsed, relativep);
}
else {
parsed = parse(uri);
if (!parsed) {
throw new Error(`Invalid at uri: ${uri}`);
}
}
this.hash = parsed.hash;
this.host = parsed.host;
this.pathname = parsed.pathname;
this.searchParams = parsed.searchParams;
}
static make(handleOrDid, collection, rkey) {
let str = handleOrDid;
if (collection)
str += '/' + collection;
if (rkey)
str += '/' + rkey;
return new AtUri(str);
}
get protocol() {
return 'at:';
}
get origin() {
return `at://${this.host}`;
}
get hostname() {
return this.host;
}
set hostname(v) {
this.host = v;
}
get search() {
return this.searchParams.toString();
}
set search(v) {
this.searchParams = new URLSearchParams(v);
}
get collection() {
return this.pathname.split('/').filter(Boolean)[0] || '';
}
set collection(v) {
const parts = this.pathname.split('/').filter(Boolean);
parts[0] = v;
this.pathname = parts.join('/');
}
get rkey() {
return this.pathname.split('/').filter(Boolean)[1] || '';
}
set rkey(v) {
const parts = this.pathname.split('/').filter(Boolean);
if (!parts[0])
parts[0] = 'undefined';
parts[1] = v;
this.pathname = parts.join('/');
}
get href() {
return this.toString();
}
toString() {
let path = this.pathname || '/';
if (!path.startsWith('/')) {
path = `/${path}`;
}
let qs = this.searchParams.toString();
if (qs && !qs.startsWith('?')) {
qs = `?${qs}`;
}
let hash = this.hash;
if (hash && !hash.startsWith('#')) {
hash = `#${hash}`;
}
return `at://${this.host}${path}${qs}${hash}`;
}
}
exports.AtUri = AtUri;
function parse(str) {
const match = exports.ATP_URI_REGEX.exec(str);
if (match) {
return {
hash: match[5] || '',
host: match[2] || '',
pathname: match[3] || '',
searchParams: new URLSearchParams(match[4] || ''),
};
}
return undefined;
}
function parseRelative(str) {
const match = RELATIVE_REGEX.exec(str);
if (match) {
return {
hash: match[3] || '',
pathname: match[1] || '',
searchParams: new URLSearchParams(match[2] || ''),
};
}
return undefined;
}
//# sourceMappingURL=aturi.js.map