@volter/world-core 3.0.18 → 3.0.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/vendor-hosts.cjs CHANGED
@@ -55,6 +55,39 @@ const COMPILED = new Map();
55
55
  /** The hand table's keys, before any pack's rules: a pack installed later replaces its hand entry in place (keeping its
56
56
  * position, which decides who answers a shared host first), where the built-in facts may not declare one twice. */
57
57
  const HAND = new Set(Object.keys(VENDOR_HOSTS));
58
+ /** One host rule as a predicate over (hostname, pathname?): its one selector (host | suffix | hostPattern) and its
59
+ * pathPattern, a path left out matching any. */
60
+ function compileHostRule(rule, where) {
61
+ const selectors = ['host', 'suffix', 'hostPattern'].filter((k) => rule[k] !== undefined).length;
62
+ if (selectors !== 1) throw new Error(`inject: ${where} rule ${JSON.stringify(rule)} — exactly one of host | suffix | hostPattern (pack-facts.json is hand-edited or stale)`);
63
+ const hostRe = rule.hostPattern === undefined ? null : new RegExp(rule.hostPattern);
64
+ const pathRe = rule.pathPattern === undefined ? null : new RegExp(rule.pathPattern);
65
+ return (h, p) =>
66
+ (rule.host !== undefined ? h === rule.host : rule.suffix !== undefined ? h.endsWith(rule.suffix) : hostRe.test(h))
67
+ && (pathRe === null || p === undefined || pathRe.test(p));
68
+ }
69
+
70
+ /** A pack's host rules (its descriptor's `hosts`) read as the injector reads them: `names(host)`, whether any include
71
+ * rule's selector names the host, whatever the path; `takes(host, path)`, whether the request is the pack's (under
72
+ * one of its keys, an include matches and no exclude does). The content route at a World's place holds a
73
+ * `<base>/@<host>/<path>` to it (pack-fetch.ts). */
74
+ function hostRules(rules) {
75
+ const byKey = new Map();
76
+ for (const rule of rules || []) {
77
+ const key = rule.key === undefined ? '' : rule.key;
78
+ if (!byKey.has(key)) byKey.set(key, []);
79
+ byKey.get(key).push(rule);
80
+ }
81
+ const keys = [...byKey.values()].map((keyRules) => ({
82
+ includes: keyRules.filter((r) => r.exclude !== true).map((r) => compileHostRule(r, 'a pack')),
83
+ excludes: keyRules.filter((r) => r.exclude === true).map((r) => compileHostRule(r, 'a pack')),
84
+ }));
85
+ return {
86
+ names: (h) => keys.some((k) => k.includes.some((m) => m(h))),
87
+ takes: (h, p) => keys.some((k) => k.includes.some((m) => m(h, p)) && !k.excludes.some((m) => m(h, p))),
88
+ };
89
+ }
90
+
58
91
  function compilePackHosts(packs, overlay) {
59
92
  for (const vendor of Object.keys(packs)) {
60
93
  const rules = packs[vendor].hosts;
@@ -77,15 +110,7 @@ function compilePackHosts(packs, overlay) {
77
110
  if (VENDOR_HOSTS[key] && !(overlay && HAND.has(key))) {
78
111
  throw new Error(`inject: key "${key}" (pack ${vendor}) is declared twice — on this descriptor and in the hand VENDOR_HOSTS table or another pack's descriptor; a key has one home.`);
79
112
  }
80
- const compile = (rule) => {
81
- const selectors = ['host', 'suffix', 'hostPattern'].filter((k) => rule[k] !== undefined).length;
82
- if (selectors !== 1) throw new Error(`inject: key "${key}" (pack ${vendor}) rule ${JSON.stringify(rule)} — exactly one of host | suffix | hostPattern (pack-facts.json is hand-edited or stale)`);
83
- const hostRe = rule.hostPattern === undefined ? null : new RegExp(rule.hostPattern);
84
- const pathRe = rule.pathPattern === undefined ? null : new RegExp(rule.pathPattern);
85
- return (h, p) =>
86
- (rule.host !== undefined ? h === rule.host : rule.suffix !== undefined ? h.endsWith(rule.suffix) : hostRe.test(h))
87
- && (pathRe === null || p === undefined || pathRe.test(p));
88
- };
113
+ const compile = (rule) => compileHostRule(rule, `key "${key}" (pack ${vendor})`);
89
114
  const includes = keyRules.filter((r) => r.exclude !== true).map(compile);
90
115
  const excludes = keyRules.filter((r) => r.exclude === true).map(compile);
91
116
  VENDOR_HOSTS[key] = (h, p) => includes.some((m) => m(h, p)) && !excludes.some((m) => m(h, p));
@@ -141,4 +166,4 @@ function twinOrigins(env) {
141
166
  return map;
142
167
  }
143
168
 
144
- module.exports = { VENDOR_HOSTS, addPackHosts, isVendorHost, vendorsOfHost, twinEnvStem, twinOrigins };
169
+ module.exports = { VENDOR_HOSTS, hostRules, addPackHosts, isVendorHost, vendorsOfHost, twinEnvStem, twinOrigins };
@@ -6,3 +6,6 @@ export function vendorsOfHost(hostname: string): string[];
6
6
  export function twinEnvStem(vendor: string): string;
7
7
  /** The vendors whose twin `env` points at, each with its origin. */
8
8
  export function twinOrigins(env: Readonly<Record<string, string | undefined>>): Record<string, string>;
9
+ /** A pack's host rules (its descriptor's `hosts`, as data) read as the injector reads them: whether any include names a
10
+ * host whatever the path, and whether a request to a host and path is the pack's. */
11
+ export function hostRules(rules: ReadonlyArray<{ host?: string; suffix?: string; hostPattern?: string; pathPattern?: string; key?: string; exclude?: true }> | undefined): { names(hostname: string): boolean; takes(hostname: string, pathname: string): boolean };