@containerbase/base 14.61.0 → 14.63.0

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/README.md CHANGED
@@ -121,6 +121,20 @@ replaceUrl(
121
121
  );
122
122
  ```
123
123
 
124
+ `replaceUrl` replaces the first occurrence of a `from` anywhere in the url; the next major only matches at the start of the url, see [#8160](https://github.com/containerbase/base/issues/8160).
125
+ `replaceUrlPrefix(url, rules)` already does: the rules apply in order, each to the result of the previous ones, and only when the url starts with its `from`.
126
+ It has no cdn step and returns the replaced url with the rules that matched, other fields of the rules are kept.
127
+ End `from` and `to` with a `/`, like `https://example.com/`, so a rule only matches that host: `https://example.com` also matches `https://example.com.test/`.
128
+
129
+ ```ts
130
+ import { replaceUrlPrefix } from '@containerbase/base';
131
+
132
+ const { url, applied } = replaceUrlPrefix('https://registry.npmjs.org/foo', [
133
+ { from: 'https://registry.npmjs.org/', to: 'https://npm.example.test/' },
134
+ ]);
135
+ // url: 'https://npm.example.test/foo', applied: [the rule]
136
+ ```
137
+
124
138
  A tool's data may list `minCb` ranges, the oldest containerbase version which can install a version and every version above it.
125
139
  `filterByMinCb(data, cbVersion)` returns the `versions` the given containerbase version can install, in the order of the data, and the `cb` values of the unmet ranges as `needed`.
126
140
  A `cbVersion` which isn't a release, like `0.0.0-PLACEHOLDER` (see `isReleaseVersion(version)`), skips the filter:
@@ -157,6 +171,7 @@ configure({ logger });
157
171
  ```
158
172
 
159
173
  `getLogger()` returns the configured logger, so a package building on `@containerbase/base` can log to the same one.
174
+ All installed copies of the package share the logger, also when they have different versions, so such a package logs to it even when it uses another copy.
160
175
  `isConfigured()` tells whether a logger was set, so that package can configure a fallback when nobody did:
161
176
 
162
177
  ```ts
package/dist/index.d.ts CHANGED
@@ -8,8 +8,8 @@ export { configure, getLogger, isConfigured } from './logger.ts';
8
8
  export { filterByMinCb, minCbByVersion } from './min-cb.ts';
9
9
  export { isReleaseVersion } from './release-version.ts';
10
10
  export { isToolVersionsFormat, toolVersionsFormat, toolVersionsFormatPath, } from './tool-versions-format.ts';
11
- export type { UrlReplacement, UrlReplacements } from './url.ts';
12
- export { getUrlReplacements, replaceUrl } from './url.ts';
11
+ export type { UrlPrefixResult, UrlPrefixRule, UrlReplacement, UrlReplacements, } from './url.ts';
12
+ export { getUrlReplacements, replaceUrl, replaceUrlPrefix } from './url.ts';
13
13
  export { tools };
14
14
  /**
15
15
  * The Ubuntu release the default containerbase image is built from, the
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@ export { configure, getLogger, isConfigured } from "./logger.js";
4
4
  export { filterByMinCb, minCbByVersion } from "./min-cb.js";
5
5
  export { isReleaseVersion } from "./release-version.js";
6
6
  export { isToolVersionsFormat, toolVersionsFormat, toolVersionsFormatPath, } from "./tool-versions-format.js";
7
- export { getUrlReplacements, replaceUrl } from "./url.js";
7
+ export { getUrlReplacements, replaceUrl, replaceUrlPrefix } from "./url.js";
8
8
  export { tools };
9
9
  /**
10
10
  * The Ubuntu release the default containerbase image is built from, the
package/dist/logger.d.ts CHANGED
@@ -21,7 +21,9 @@ export interface ConfigureOptions {
21
21
  }
22
22
  /**
23
23
  * Configures the package, eg. sets the logger its functions log to. Options
24
- * which are left out are reset to their defaults.
24
+ * which are left out are reset to their defaults. Every installed copy of the
25
+ * package shares the logger, so a package building on another version of this
26
+ * one logs to it too.
25
27
  *
26
28
  * @param options the options to set
27
29
  */
package/dist/logger.js CHANGED
@@ -8,26 +8,40 @@ const silentLogger = {
8
8
  warn: noop,
9
9
  error: noop,
10
10
  };
11
- let current = silentLogger;
12
- let configured = false;
11
+ /** The global key of the shared {@link LoggerState}. */
12
+ const registryKey = Symbol.for('containerbase.logger');
13
+ /**
14
+ * The shared logger state, created as a silent and unconfigured one by the
15
+ * first copy which needs it.
16
+ */
17
+ function state() {
18
+ const registry = globalThis;
19
+ return (registry[registryKey] ??= {
20
+ logger: silentLogger,
21
+ configured: false,
22
+ });
23
+ }
13
24
  /**
14
25
  * Configures the package, eg. sets the logger its functions log to. Options
15
- * which are left out are reset to their defaults.
26
+ * which are left out are reset to their defaults. Every installed copy of the
27
+ * package shares the logger, so a package building on another version of this
28
+ * one logs to it too.
16
29
  *
17
30
  * @param options the options to set
18
31
  */
19
32
  export function configure(options = {}) {
20
- current = options.logger ?? silentLogger;
21
- configured = options.logger !== undefined;
33
+ const current = state();
34
+ current.logger = options.logger ?? silentLogger;
35
+ current.configured = options.logger !== undefined;
22
36
  }
23
37
  /** The logger set by `configure`, a silent one by default. */
24
38
  export function getLogger() {
25
- return current;
39
+ return state().logger;
26
40
  }
27
41
  /**
28
42
  * Whether `configure` has set a logger, so a package building on this one can
29
43
  * configure a fallback logger itself when nobody else did.
30
44
  */
31
45
  export function isConfigured() {
32
- return configured;
46
+ return state().configured;
33
47
  }
package/dist/url.d.ts CHANGED
@@ -29,3 +29,30 @@ export declare function getUrlReplacements(env?: Record<string, string | undefin
29
29
  * @returns the replaced url
30
30
  */
31
31
  export declare function replaceUrl(url: string, replacements: readonly UrlReplacement[], cdn?: string): string;
32
+ /** A url prefix replacement rule, other fields are kept as they are. */
33
+ export interface UrlPrefixRule {
34
+ /** The url prefix to replace. */
35
+ from: string;
36
+ /** Its replacement. */
37
+ to: string;
38
+ }
39
+ /** The result of `replaceUrlPrefix`. */
40
+ export interface UrlPrefixResult<T extends UrlPrefixRule> {
41
+ /** The replaced url. */
42
+ url: string;
43
+ /** The rules which matched, in order. */
44
+ applied: T[];
45
+ }
46
+ /**
47
+ * Replaces url prefixes: the rules are applied in order, each one to the
48
+ * result of the previous ones, and a rule only applies when the url starts
49
+ * with its `from`, which is then replaced by its `to`. Unlike `replaceUrl`,
50
+ * a `from` elsewhere in the url never matches, and there is no cdn. End `from`
51
+ * and `to` with a `/`, like `https://example.com/`, so a rule only matches that
52
+ * host: `https://example.com` also matches `https://example.com.test/`.
53
+ *
54
+ * @param url the url to replace
55
+ * @param rules the rules, in order
56
+ * @returns the replaced url and the rules which matched
57
+ */
58
+ export declare function replaceUrlPrefix<T extends UrlPrefixRule>(url: string, rules: readonly T[]): UrlPrefixResult<T>;
package/dist/url.js CHANGED
@@ -37,6 +37,7 @@ export function getUrlReplacements(env = process.env) {
37
37
  * @param cdn the cdn url, eg. from `CONTAINERBASE_CDN`, skipped when empty
38
38
  * @returns the replaced url
39
39
  */
40
+ // TODO: match only at the start of the url in the next major, like `replaceUrlPrefix` (#8160)
40
41
  export function replaceUrl(url, replacements, cdn) {
41
42
  let result = url;
42
43
  if (cdn) {
@@ -47,3 +48,26 @@ export function replaceUrl(url, replacements, cdn) {
47
48
  }
48
49
  return result;
49
50
  }
51
+ /**
52
+ * Replaces url prefixes: the rules are applied in order, each one to the
53
+ * result of the previous ones, and a rule only applies when the url starts
54
+ * with its `from`, which is then replaced by its `to`. Unlike `replaceUrl`,
55
+ * a `from` elsewhere in the url never matches, and there is no cdn. End `from`
56
+ * and `to` with a `/`, like `https://example.com/`, so a rule only matches that
57
+ * host: `https://example.com` also matches `https://example.com.test/`.
58
+ *
59
+ * @param url the url to replace
60
+ * @param rules the rules, in order
61
+ * @returns the replaced url and the rules which matched
62
+ */
63
+ export function replaceUrlPrefix(url, rules) {
64
+ let result = url;
65
+ const applied = [];
66
+ for (const rule of rules) {
67
+ if (result.startsWith(rule.from)) {
68
+ result = rule.to + result.slice(rule.from.length);
69
+ applied.push(rule);
70
+ }
71
+ }
72
+ return { url: result, applied };
73
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@containerbase/base",
3
- "version": "14.61.0",
3
+ "version": "14.63.0",
4
4
  "description": "Metadata about the tools supported by containerbase",
5
5
  "keywords": [
6
6
  "containerbase",