Fix StartOS 0.4 TypeScript packaging to match SDK API
This commit is contained in:
+226
@@ -0,0 +1,226 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.GetServiceInterface = exports.filledAddress = exports.addressHostToUrl = exports.getHostname = void 0;
|
||||
exports.filterNonLocal = filterNonLocal;
|
||||
exports.getOwnServiceInterface = getOwnServiceInterface;
|
||||
exports.getServiceInterface = getServiceInterface;
|
||||
const Host_1 = require("../interfaces/Host");
|
||||
const ip_1 = require("./ip");
|
||||
const deepEqual_1 = require("./deepEqual");
|
||||
const once_1 = require("./once");
|
||||
const Watchable_1 = require("./Watchable");
|
||||
const getHostnameRegex = /^(\w+:\/\/)?([^\/\:]+)(:\d{1,3})?(\/)?/;
|
||||
const getHostname = (url) => {
|
||||
const founds = url.match(getHostnameRegex)?.[2];
|
||||
if (!founds)
|
||||
return null;
|
||||
const parts = founds.split('@');
|
||||
const last = parts[parts.length - 1];
|
||||
return last;
|
||||
};
|
||||
exports.getHostname = getHostname;
|
||||
const nonLocalFilter = {
|
||||
exclude: {
|
||||
kind: ['localhost', 'link-local', 'bridge'],
|
||||
},
|
||||
};
|
||||
const publicFilter = {
|
||||
visibility: 'public',
|
||||
};
|
||||
const either = (...args) => (a) => args.some((x) => x(a));
|
||||
const negate = (fn) => (a) => !fn(a);
|
||||
const unique = (values) => Array.from(new Set(values));
|
||||
const addressHostToUrl = ({ scheme, sslScheme, username, suffix }, hostname) => {
|
||||
const effectiveScheme = hostname.ssl ? sslScheme : scheme;
|
||||
let host;
|
||||
if (hostname.metadata.kind === 'ipv6') {
|
||||
host = ip_1.IPV6_LINK_LOCAL.contains(hostname.hostname)
|
||||
? `[${hostname.hostname}%${hostname.metadata.scopeId}]`
|
||||
: `[${hostname.hostname}]`;
|
||||
}
|
||||
else {
|
||||
host = hostname.hostname;
|
||||
}
|
||||
let portStr = '';
|
||||
if (hostname.port !== null) {
|
||||
const excludePort = effectiveScheme &&
|
||||
effectiveScheme in Host_1.knownProtocols &&
|
||||
hostname.port ===
|
||||
Host_1.knownProtocols[effectiveScheme]
|
||||
.defaultPort;
|
||||
if (!excludePort)
|
||||
portStr = `:${hostname.port}`;
|
||||
}
|
||||
return `${effectiveScheme ? `${effectiveScheme}://` : ''}${username ? `${username}@` : ''}${host}${portStr}${suffix}`;
|
||||
};
|
||||
exports.addressHostToUrl = addressHostToUrl;
|
||||
function filterRec(hostnames, filter, invert) {
|
||||
if (filter.predicate) {
|
||||
const pred = filter.predicate;
|
||||
hostnames = hostnames.filter((h) => invert !== pred(h));
|
||||
}
|
||||
if (filter.visibility === 'public')
|
||||
hostnames = hostnames.filter((h) => invert !== h.public);
|
||||
if (filter.visibility === 'private')
|
||||
hostnames = hostnames.filter((h) => invert !== !h.public);
|
||||
if (filter.kind) {
|
||||
const kind = new Set(Array.isArray(filter.kind) ? filter.kind : [filter.kind]);
|
||||
if (kind.has('ip')) {
|
||||
kind.add('ipv4');
|
||||
kind.add('ipv6');
|
||||
}
|
||||
hostnames = hostnames.filter((h) => invert !==
|
||||
((kind.has('mdns') && h.metadata.kind === 'mdns') ||
|
||||
(kind.has('domain') &&
|
||||
(h.metadata.kind === 'private-domain' ||
|
||||
h.metadata.kind === 'public-domain')) ||
|
||||
(kind.has('ipv4') && h.metadata.kind === 'ipv4') ||
|
||||
(kind.has('ipv6') && h.metadata.kind === 'ipv6') ||
|
||||
(kind.has('localhost') &&
|
||||
['localhost', '127.0.0.1', '::1'].includes(h.hostname)) ||
|
||||
(kind.has('link-local') &&
|
||||
h.metadata.kind === 'ipv6' &&
|
||||
ip_1.IPV6_LINK_LOCAL.contains(ip_1.IpAddress.parse(h.hostname))) ||
|
||||
(kind.has('bridge') &&
|
||||
h.metadata.kind === 'ipv4' &&
|
||||
h.metadata.gateway === 'lxcbr0') ||
|
||||
(kind.has('plugin') && h.metadata.kind === 'plugin')));
|
||||
}
|
||||
if (filter.pluginId) {
|
||||
const id = filter.pluginId;
|
||||
hostnames = hostnames.filter((h) => invert !==
|
||||
(h.metadata.kind === 'plugin' && h.metadata.packageId === id));
|
||||
}
|
||||
if (filter.exclude)
|
||||
return filterRec(hostnames, filter.exclude, !invert);
|
||||
return hostnames;
|
||||
}
|
||||
function isPublicIp(h) {
|
||||
return h.public && (h.metadata.kind === 'ipv4' || h.metadata.kind === 'ipv6');
|
||||
}
|
||||
function enabledAddresses(addr) {
|
||||
return addr.available.filter((h) => {
|
||||
if (isPublicIp(h)) {
|
||||
// Public IPs: disabled by default, explicitly enabled via SocketAddr string
|
||||
if (h.port === null)
|
||||
return true;
|
||||
const sa = h.metadata.kind === 'ipv6'
|
||||
? `[${h.hostname}]:${h.port}`
|
||||
: `${h.hostname}:${h.port}`;
|
||||
return addr.enabled.includes(sa);
|
||||
}
|
||||
else {
|
||||
// Everything else: enabled by default, explicitly disabled via [hostname, port] tuple
|
||||
return !addr.disabled.some(([hostname, port]) => hostname === h.hostname && port === (h.port ?? 0));
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Filters out localhost and IPv6 link-local hostnames from a list.
|
||||
* Equivalent to the `nonLocal` filter on `Filled` addresses.
|
||||
*/
|
||||
function filterNonLocal(hostnames) {
|
||||
return filterRec(hostnames, nonLocalFilter, false);
|
||||
}
|
||||
const filledAddress = (host, addressInfo) => {
|
||||
const toUrl = exports.addressHostToUrl.bind(null, addressInfo);
|
||||
const binding = host.bindings[addressInfo.internalPort];
|
||||
const hostnames = binding ? enabledAddresses(binding.addresses) : [];
|
||||
function filledAddressFromHostnames(hostnames) {
|
||||
const getNonLocal = (0, once_1.once)(() => filledAddressFromHostnames(filterRec(hostnames, nonLocalFilter, false)));
|
||||
const getPublic = (0, once_1.once)(() => filledAddressFromHostnames(filterRec(hostnames, publicFilter, false)));
|
||||
return {
|
||||
...addressInfo,
|
||||
hostnames,
|
||||
toUrl,
|
||||
format: (format) => {
|
||||
let res = hostnames;
|
||||
if (format === 'hostname-info')
|
||||
return res;
|
||||
const urls = hostnames.map(toUrl);
|
||||
if (format === 'url')
|
||||
res = urls.map((u) => new URL(u));
|
||||
else
|
||||
res = urls;
|
||||
return res;
|
||||
},
|
||||
filter: (filter) => {
|
||||
return filledAddressFromHostnames(filterRec(hostnames, filter, false));
|
||||
},
|
||||
matchesAny: (filters) => {
|
||||
const seen = new Set();
|
||||
const union = [];
|
||||
for (const f of filters) {
|
||||
for (const h of filterRec(hostnames, f, false)) {
|
||||
if (!seen.has(h)) {
|
||||
seen.add(h);
|
||||
union.push(h);
|
||||
}
|
||||
}
|
||||
}
|
||||
return filledAddressFromHostnames(union);
|
||||
},
|
||||
get nonLocal() {
|
||||
return getNonLocal();
|
||||
},
|
||||
get public() {
|
||||
return getPublic();
|
||||
},
|
||||
};
|
||||
}
|
||||
return filledAddressFromHostnames(hostnames);
|
||||
};
|
||||
exports.filledAddress = filledAddress;
|
||||
const makeInterfaceFilled = async ({ effects, id, packageId, callback, }) => {
|
||||
const serviceInterfaceValue = await effects.getServiceInterface({
|
||||
serviceInterfaceId: id,
|
||||
packageId,
|
||||
callback,
|
||||
});
|
||||
if (!serviceInterfaceValue) {
|
||||
return null;
|
||||
}
|
||||
const hostId = serviceInterfaceValue.addressInfo.hostId;
|
||||
const host = await effects.getHostInfo({
|
||||
packageId,
|
||||
hostId,
|
||||
callback,
|
||||
});
|
||||
const interfaceFilled = {
|
||||
...serviceInterfaceValue,
|
||||
host,
|
||||
addressInfo: host
|
||||
? (0, exports.filledAddress)(host, serviceInterfaceValue.addressInfo)
|
||||
: null,
|
||||
};
|
||||
return interfaceFilled;
|
||||
};
|
||||
class GetServiceInterface extends Watchable_1.Watchable {
|
||||
constructor(effects, opts, options) {
|
||||
super(effects, options);
|
||||
this.opts = opts;
|
||||
this.label = 'GetServiceInterface';
|
||||
}
|
||||
fetch(callback) {
|
||||
return makeInterfaceFilled({
|
||||
effects: this.effects,
|
||||
id: this.opts.id,
|
||||
packageId: this.opts.packageId,
|
||||
callback,
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.GetServiceInterface = GetServiceInterface;
|
||||
function getOwnServiceInterface(effects, id, map, eq) {
|
||||
return new GetServiceInterface(effects, { id }, {
|
||||
map: map ?? ((a) => a),
|
||||
eq: eq ?? ((a, b) => (0, deepEqual_1.deepEqual)(a, b)),
|
||||
});
|
||||
}
|
||||
function getServiceInterface(effects, opts, map, eq) {
|
||||
return new GetServiceInterface(effects, opts, {
|
||||
map: map ?? ((a) => a),
|
||||
eq: eq ?? ((a, b) => (0, deepEqual_1.deepEqual)(a, b)),
|
||||
});
|
||||
}
|
||||
//# sourceMappingURL=getServiceInterface.js.map
|
||||
Reference in New Issue
Block a user