@dbx-tools/shared-core 0.6.82 → 0.6.85
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 +0 -40
- package/index.ts +2 -3
- package/lib/index.d.ts +2 -3
- package/lib/index.js +2 -3
- package/lib/src/context.d.ts +64 -0
- package/lib/src/context.js +148 -0
- package/lib/src/object.d.ts +2 -2
- package/lib/src/object.js +3 -3
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/context.ts +164 -0
- package/src/object.ts +4 -3
- package/lib/src/env.d.ts +0 -101
- package/lib/src/env.js +0 -153
- package/src/env.ts +0 -177
package/README.md
CHANGED
|
@@ -10,7 +10,6 @@ namespaces so call sites stay explicit:
|
|
|
10
10
|
import {
|
|
11
11
|
async,
|
|
12
12
|
brand,
|
|
13
|
-
env,
|
|
14
13
|
error,
|
|
15
14
|
hash,
|
|
16
15
|
http,
|
|
@@ -156,41 +155,6 @@ field off parsed JSON. `parseList()` normalizes a config value that may arrive a
|
|
|
156
155
|
an array or as one comma/whitespace-separated env string, de-duplicating as it
|
|
157
156
|
goes.
|
|
158
157
|
|
|
159
|
-
## Configuration From The Environment
|
|
160
|
-
|
|
161
|
-
```ts
|
|
162
|
-
const config = {
|
|
163
|
-
isDatabricksApp: env.isAppEnv(),
|
|
164
|
-
host: env.string(options.host, "SMTP_HOST"),
|
|
165
|
-
// Several names for one setting; earlier names win.
|
|
166
|
-
appId: env.string(options.appId, ["TEAMS_APP_ID", "MICROSOFT_APP_ID"]),
|
|
167
|
-
timeoutMs: env.positiveInt(options.timeoutMs, "SEARCH_TIMEOUT_MS", 30_000),
|
|
168
|
-
threshold: env.positiveNumber(options.threshold, "FUZZY_THRESHOLD", 0.4),
|
|
169
|
-
fuzzy: env.boolean(options.fuzzy, "SEARCH_FUZZY") ?? true,
|
|
170
|
-
fallbacks: env.list(options.fallbacks, "MODEL_FALLBACKS"),
|
|
171
|
-
};
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
Every plugin resolves config the same way - the caller's typed value, else one or
|
|
175
|
-
more environment variables, else a default - and hand-writing that chain per
|
|
176
|
-
field is how `config.x ?? Number(process.env.X)` bugs get in. `positiveInt()`
|
|
177
|
-
floors, so a count cannot go fractional; `positiveNumber()` keeps the fraction
|
|
178
|
-
for a threshold or ratio. `boolean()` goes through `object.toBoolean()`, so the
|
|
179
|
-
loose spellings an env var actually carries (`1`, `on`, `yes`) are accepted, and
|
|
180
|
-
returns `undefined` when neither source is interpretable so `??` picks the
|
|
181
|
-
default. A name that is SET but unusable is not skipped for a later name in the
|
|
182
|
-
chain - ignoring what a deployment explicitly configured hides the mistake.
|
|
183
|
-
|
|
184
|
-
Browser-safe: `process` is reached through `globalThis` and guarded, so every
|
|
185
|
-
lookup simply misses off-process and the caller's fallback applies.
|
|
186
|
-
`isAppEnv()` checks the required Databricks App name, workspace host, and valid
|
|
187
|
-
TCP port shape without adding Node types to this shared package.
|
|
188
|
-
|
|
189
|
-
Pair it with `object.optional()` when a resolved value is an optional field -
|
|
190
|
-
`...object.optional("endpoint", env.string(...))` keeps an absent field ABSENT
|
|
191
|
-
rather than setting it to an explicit `undefined`, which
|
|
192
|
-
`exactOptionalPropertyTypes` rejects.
|
|
193
|
-
|
|
194
158
|
## Objects And Predicates
|
|
195
159
|
|
|
196
160
|
```ts
|
|
@@ -442,10 +406,6 @@ without paying formatting cost when disabled.
|
|
|
442
406
|
field spreading, deep equality, JSON-round-trip guards
|
|
443
407
|
(`isSerializableValue`), canonical identity keys (`toStableKey`), shape types,
|
|
444
408
|
and lazy sequence transforms + collection helpers.
|
|
445
|
-
- `env` - config-over-environment resolution, Databricks App runtime detection,
|
|
446
|
-
and TCP port bounds. `name()` gives the primary variable name for a log line
|
|
447
|
-
or error - an `EnvKey` may be a bare string, so indexing `keys[0]` yields a
|
|
448
|
-
character, not a name.
|
|
449
409
|
- `predicate` - composable boolean/type predicates.
|
|
450
410
|
- `pattern` - literal / glob / `/regex/` allow-list matching compiled to a
|
|
451
411
|
predicate.
|
package/index.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
export * as async from "./src/async.ts";
|
|
6
6
|
export * as brand from "./src/brand.ts";
|
|
7
|
-
export * as
|
|
7
|
+
export * as context from "./src/context.ts";
|
|
8
8
|
export * as error from "./src/error.ts";
|
|
9
9
|
export * as execution from "./src/execution.ts";
|
|
10
10
|
export * as functionModule from "./src/function.ts";
|
|
@@ -21,8 +21,7 @@ export * as token from "./src/token.ts";
|
|
|
21
21
|
export type { PollContext, PollProducer, PollOptions } from "./src/async.ts";
|
|
22
22
|
export { DEFAULT_BRAND_ASSETS, BrandAssetSetSchema, BrandColorsSchema, BrandVoiceSchema, BrandContextSchema, defaultBrandContext } from "./src/brand.ts";
|
|
23
23
|
export type { BrandContext, BrandContextInput, BrandAssetSet } from "./src/brand.ts";
|
|
24
|
-
export {
|
|
25
|
-
export type { EnvKey } from "./src/env.ts";
|
|
24
|
+
export type { ContextLoader } from "./src/context.ts";
|
|
26
25
|
export type { ErrorContext } from "./src/error.ts";
|
|
27
26
|
export type { ExecutionResult, Executor, ExecutionFailure, RunOptions } from "./src/execution.ts";
|
|
28
27
|
export type { MemoizeOptions } from "./src/function.ts";
|
package/lib/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export * as async from "./src/async.ts";
|
|
2
2
|
export * as brand from "./src/brand.ts";
|
|
3
|
-
export * as
|
|
3
|
+
export * as context from "./src/context.ts";
|
|
4
4
|
export * as error from "./src/error.ts";
|
|
5
5
|
export * as execution from "./src/execution.ts";
|
|
6
6
|
export * as functionModule from "./src/function.ts";
|
|
@@ -17,8 +17,7 @@ export * as token from "./src/token.ts";
|
|
|
17
17
|
export type { PollContext, PollProducer, PollOptions } from "./src/async.ts";
|
|
18
18
|
export { DEFAULT_BRAND_ASSETS, BrandAssetSetSchema, BrandColorsSchema, BrandVoiceSchema, BrandContextSchema, defaultBrandContext } from "./src/brand.ts";
|
|
19
19
|
export type { BrandContext, BrandContextInput, BrandAssetSet } from "./src/brand.ts";
|
|
20
|
-
export {
|
|
21
|
-
export type { EnvKey } from "./src/env.ts";
|
|
20
|
+
export type { ContextLoader } from "./src/context.ts";
|
|
22
21
|
export type { ErrorContext } from "./src/error.ts";
|
|
23
22
|
export type { ExecutionResult, Executor, ExecutionFailure, RunOptions } from "./src/execution.ts";
|
|
24
23
|
export type { MemoizeOptions } from "./src/function.ts";
|
package/lib/index.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// Hand edits are overwritten on the next watch; this file is read-only.
|
|
4
4
|
export * as async from "./src/async.js";
|
|
5
5
|
export * as brand from "./src/brand.js";
|
|
6
|
-
export * as
|
|
6
|
+
export * as context from "./src/context.js";
|
|
7
7
|
export * as error from "./src/error.js";
|
|
8
8
|
export * as execution from "./src/execution.js";
|
|
9
9
|
export * as functionModule from "./src/function.js";
|
|
@@ -18,6 +18,5 @@ export * as predicate from "./src/predicate.js";
|
|
|
18
18
|
export * as string from "./src/string.js";
|
|
19
19
|
export * as token from "./src/token.js";
|
|
20
20
|
export { DEFAULT_BRAND_ASSETS, BrandAssetSetSchema, BrandColorsSchema, BrandVoiceSchema, BrandContextSchema, defaultBrandContext } from "./src/brand.js";
|
|
21
|
-
export { MAX_TCP_PORT } from "./src/env.js";
|
|
22
21
|
export { ACCESS_TOKEN_HEADER, USER_ID_HEADER, USER_EMAIL_HEADER } from "./src/token.js";
|
|
23
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
22
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwyQ0FBMkM7QUFDM0MsbURBQW1EO0FBQ25ELHdFQUF3RTtBQUV4RSxPQUFPLEtBQUssS0FBSyxNQUFNLGdCQUFnQixDQUFDO0FBQ3hDLE9BQU8sS0FBSyxLQUFLLE1BQU0sZ0JBQWdCLENBQUM7QUFDeEMsT0FBTyxLQUFLLE9BQU8sTUFBTSxrQkFBa0IsQ0FBQztBQUM1QyxPQUFPLEtBQUssS0FBSyxNQUFNLGdCQUFnQixDQUFDO0FBQ3hDLE9BQU8sS0FBSyxTQUFTLE1BQU0sb0JBQW9CLENBQUM7QUFDaEQsT0FBTyxLQUFLLGNBQWMsTUFBTSxtQkFBbUIsQ0FBQztBQUNwRCxPQUFPLEtBQUssSUFBSSxNQUFNLGVBQWUsQ0FBQztBQUN0QyxPQUFPLEtBQUssSUFBSSxNQUFNLGVBQWUsQ0FBQztBQUN0QyxPQUFPLEtBQUssSUFBSSxNQUFNLGVBQWUsQ0FBQztBQUN0QyxPQUFPLEtBQUssR0FBRyxNQUFNLGNBQWMsQ0FBQztBQUNwQyxPQUFPLEtBQUssR0FBRyxNQUFNLGNBQWMsQ0FBQztBQUNwQyxPQUFPLEtBQUssTUFBTSxNQUFNLGlCQUFpQixDQUFDO0FBQzFDLE9BQU8sS0FBSyxPQUFPLE1BQU0sa0JBQWtCLENBQUM7QUFDNUMsT0FBTyxLQUFLLFNBQVMsTUFBTSxvQkFBb0IsQ0FBQztBQUNoRCxPQUFPLEtBQUssTUFBTSxNQUFNLGlCQUFpQixDQUFDO0FBQzFDLE9BQU8sS0FBSyxLQUFLLE1BQU0sZ0JBQWdCLENBQUM7QUFFeEMsT0FBTyxFQUFFLG9CQUFvQixFQUFFLG1CQUFtQixFQUFFLGlCQUFpQixFQUFFLGdCQUFnQixFQUFFLGtCQUFrQixFQUFFLG1CQUFtQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFhekosT0FBTyxFQUFFLG1CQUFtQixFQUFFLGNBQWMsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gR0VORVJBVEVEIGJ5IHByb2plbiB3YXRjaCAtIERPIE5PVCBFRElULlxuLy8gUmVnZW5lcmF0ZWQgZnJvbSB0aGUgZXhwb3J0aW5nIG1vZHVsZXMgaW4gLi9zcmMuXG4vLyBIYW5kIGVkaXRzIGFyZSBvdmVyd3JpdHRlbiBvbiB0aGUgbmV4dCB3YXRjaDsgdGhpcyBmaWxlIGlzIHJlYWQtb25seS5cblxuZXhwb3J0ICogYXMgYXN5bmMgZnJvbSBcIi4vc3JjL2FzeW5jLnRzXCI7XG5leHBvcnQgKiBhcyBicmFuZCBmcm9tIFwiLi9zcmMvYnJhbmQudHNcIjtcbmV4cG9ydCAqIGFzIGNvbnRleHQgZnJvbSBcIi4vc3JjL2NvbnRleHQudHNcIjtcbmV4cG9ydCAqIGFzIGVycm9yIGZyb20gXCIuL3NyYy9lcnJvci50c1wiO1xuZXhwb3J0ICogYXMgZXhlY3V0aW9uIGZyb20gXCIuL3NyYy9leGVjdXRpb24udHNcIjtcbmV4cG9ydCAqIGFzIGZ1bmN0aW9uTW9kdWxlIGZyb20gXCIuL3NyYy9mdW5jdGlvbi50c1wiO1xuZXhwb3J0ICogYXMgaGFzaCBmcm9tIFwiLi9zcmMvaGFzaC50c1wiO1xuZXhwb3J0ICogYXMgaHR0cCBmcm9tIFwiLi9zcmMvaHR0cC50c1wiO1xuZXhwb3J0ICogYXMganNvbiBmcm9tIFwiLi9zcmMvanNvbi50c1wiO1xuZXhwb3J0ICogYXMgbG9nIGZyb20gXCIuL3NyYy9sb2cudHNcIjtcbmV4cG9ydCAqIGFzIG5ldCBmcm9tIFwiLi9zcmMvbmV0LnRzXCI7XG5leHBvcnQgKiBhcyBvYmplY3QgZnJvbSBcIi4vc3JjL29iamVjdC50c1wiO1xuZXhwb3J0ICogYXMgcGF0dGVybiBmcm9tIFwiLi9zcmMvcGF0dGVybi50c1wiO1xuZXhwb3J0ICogYXMgcHJlZGljYXRlIGZyb20gXCIuL3NyYy9wcmVkaWNhdGUudHNcIjtcbmV4cG9ydCAqIGFzIHN0cmluZyBmcm9tIFwiLi9zcmMvc3RyaW5nLnRzXCI7XG5leHBvcnQgKiBhcyB0b2tlbiBmcm9tIFwiLi9zcmMvdG9rZW4udHNcIjtcbmV4cG9ydCB0eXBlIHsgUG9sbENvbnRleHQsIFBvbGxQcm9kdWNlciwgUG9sbE9wdGlvbnMgfSBmcm9tIFwiLi9zcmMvYXN5bmMudHNcIjtcbmV4cG9ydCB7IERFRkFVTFRfQlJBTkRfQVNTRVRTLCBCcmFuZEFzc2V0U2V0U2NoZW1hLCBCcmFuZENvbG9yc1NjaGVtYSwgQnJhbmRWb2ljZVNjaGVtYSwgQnJhbmRDb250ZXh0U2NoZW1hLCBkZWZhdWx0QnJhbmRDb250ZXh0IH0gZnJvbSBcIi4vc3JjL2JyYW5kLnRzXCI7XG5leHBvcnQgdHlwZSB7IEJyYW5kQ29udGV4dCwgQnJhbmRDb250ZXh0SW5wdXQsIEJyYW5kQXNzZXRTZXQgfSBmcm9tIFwiLi9zcmMvYnJhbmQudHNcIjtcbmV4cG9ydCB0eXBlIHsgQ29udGV4dExvYWRlciB9IGZyb20gXCIuL3NyYy9jb250ZXh0LnRzXCI7XG5leHBvcnQgdHlwZSB7IEVycm9yQ29udGV4dCB9IGZyb20gXCIuL3NyYy9lcnJvci50c1wiO1xuZXhwb3J0IHR5cGUgeyBFeGVjdXRpb25SZXN1bHQsIEV4ZWN1dG9yLCBFeGVjdXRpb25GYWlsdXJlLCBSdW5PcHRpb25zIH0gZnJvbSBcIi4vc3JjL2V4ZWN1dGlvbi50c1wiO1xuZXhwb3J0IHR5cGUgeyBNZW1vaXplT3B0aW9ucyB9IGZyb20gXCIuL3NyYy9mdW5jdGlvbi50c1wiO1xuZXhwb3J0IHR5cGUgeyBIZWFkZXJMaWtlIH0gZnJvbSBcIi4vc3JjL2h0dHAudHNcIjtcbmV4cG9ydCB0eXBlIHsgTG9nTGV2ZWwsIExvZ2dlciB9IGZyb20gXCIuL3NyYy9sb2cudHNcIjtcbmV4cG9ydCB0eXBlIHsgVXJsTGlrZSwgSXBWZXJzaW9uLCBQYXJzZWRJcCwgQ2lkciwgVXJsQnVpbGRlciwgUGFyc2VFbWFpbHNPcHRpb25zIH0gZnJvbSBcIi4vc3JjL25ldC50c1wiO1xuZXhwb3J0IHR5cGUgeyBTZXF1ZW5jZSwgQ29udGFpbmVyLCBDb2xsZWN0aW9uLCBPbmVPck1hbnksIE5hbWVMaWtlLCBOb25GdW5jdGlvbktleXMsIFNlcmlhbGl6YWJsZVByaW1pdGl2ZSwgU2VyaWFsaXphYmxlVmFsdWUsIFRvTnVtYmVyT3B0aW9ucywgVG9EYXRlT3B0aW9ucywgVG9EdXJhdGlvbk9wdGlvbnMsIERlZXBFcXVhbENvbXBhcmF0b3IgfSBmcm9tIFwiLi9zcmMvb2JqZWN0LnRzXCI7XG5leHBvcnQgdHlwZSB7IFBhdHRlcm5PcHRpb25zIH0gZnJvbSBcIi4vc3JjL3BhdHRlcm4udHNcIjtcbmV4cG9ydCB0eXBlIHsgUHJlZGljYXRlRnVuY3Rpb24sIFR5cGVQcmVkaWNhdGVGdW5jdGlvbiwgUHJlZGljYXRlSW5wdXQsIFByZWRpY2F0ZSB9IGZyb20gXCIuL3NyYy9wcmVkaWNhdGUudHNcIjtcbmV4cG9ydCB0eXBlIHsgVG9rZW5pemVPcHRpb25zLCBLZXlPcHRpb25zLCBJZGVudGlmaWVyT3B0aW9ucywgRGVzY3JpcHRpb24gfSBmcm9tIFwiLi9zcmMvc3RyaW5nLnRzXCI7XG5leHBvcnQgeyBBQ0NFU1NfVE9LRU5fSEVBREVSLCBVU0VSX0lEX0hFQURFUiwgVVNFUl9FTUFJTF9IRUFERVIgfSBmcm9tIFwiLi9zcmMvdG9rZW4udHNcIjtcbiJdfQ==
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The ambient CONTEXT a cached value belongs to, and a cache keyed by it.
|
|
3
|
+
*
|
|
4
|
+
* Most of the expensive lookups in this repo are pure functions of the directory
|
|
5
|
+
* (or the page) they were asked from: `npm prefix`, `git rev-parse`, a `.env`
|
|
6
|
+
* file, `databricks bundle validate`. Memoizing them with
|
|
7
|
+
* {@link functionModule.memoize} is wrong in exactly one situation, and it is the
|
|
8
|
+
* situation a CLI hits: the process changes directory, and the cached answer now
|
|
9
|
+
* describes somewhere else. Every caller therefore grew the same guard - resolve
|
|
10
|
+
* `cwd`, compare it against `process.cwd()`, and skip the cache when they differ
|
|
11
|
+
* (see the `cacheEnabled` dance this module replaced in node-core's `project`).
|
|
12
|
+
*
|
|
13
|
+
* This is that guard, once. A cache slot stores the context it was loaded under,
|
|
14
|
+
* so a context change (a moved `cwd`, a different origin) MISSES rather than
|
|
15
|
+
* returns a stale value, and a lookup for some OTHER directory is not cached at
|
|
16
|
+
* all - one off-context call must not evict or poison the hot path.
|
|
17
|
+
*
|
|
18
|
+
* The context is the process working directory on a server and
|
|
19
|
+
* `location.origin` in a browser, whichever this runtime has. Browser-safe:
|
|
20
|
+
* `process` and `location` are reached through `globalThis` and guarded, so this
|
|
21
|
+
* module needs no Node types and simply has no context off-process.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* const roots = context.cached(["project", "npm", "prefix"], (cwd) =>
|
|
25
|
+
* spawnSync("npm", ["prefix"], { cwd }),
|
|
26
|
+
* );
|
|
27
|
+
*
|
|
28
|
+
* @module
|
|
29
|
+
*/
|
|
30
|
+
import type { OneOrMany } from "./object.ts";
|
|
31
|
+
/** A loader for a cached value; receives the resolved context. */
|
|
32
|
+
export type ContextLoader<T> = (context: string | undefined) => T;
|
|
33
|
+
/**
|
|
34
|
+
* The current context: the process working directory, else `location.origin`,
|
|
35
|
+
* else `undefined` (a runtime with neither, where nothing is cacheable).
|
|
36
|
+
*/
|
|
37
|
+
export declare function getContext(): string | undefined;
|
|
38
|
+
/**
|
|
39
|
+
* Whether `value` names a context this runtime is CURRENTLY in - the live `cwd`
|
|
40
|
+
* or origin. This is the cacheability test: a value loaded for some other
|
|
41
|
+
* directory is correct but not shareable, so it is never stored.
|
|
42
|
+
*/
|
|
43
|
+
export declare function isContext(value: unknown): boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Load `name` through `loader`, reusing the cached value while the context is
|
|
46
|
+
* unchanged.
|
|
47
|
+
*
|
|
48
|
+
* `context` selects what the value is loaded FOR: omitted, `null`, or `"."` mean
|
|
49
|
+
* the current context. It is passed straight to `loader`, so a loader never has
|
|
50
|
+
* to reach for `process.cwd()` itself.
|
|
51
|
+
*
|
|
52
|
+
* Caching happens only when the resolved context is one this runtime is in
|
|
53
|
+
* ({@link isContext}), so `cached(name, loader, "/somewhere/else")` always calls
|
|
54
|
+
* `loader` and stores nothing. A stored entry remembers its context and is
|
|
55
|
+
* discarded on the next call once that context changes. A thrown error is never
|
|
56
|
+
* cached; a rejected promise evicts its entry so a later call retries.
|
|
57
|
+
*
|
|
58
|
+
* `name` identifies the slot and must be stable across calls - pass a
|
|
59
|
+
* module-qualified list of string parts (`["project", command, ...args]`) so two
|
|
60
|
+
* modules cannot collide on one slot.
|
|
61
|
+
*/
|
|
62
|
+
export declare function cached<T>(name: OneOrMany<string>, loader: ContextLoader<T>, context?: string | null): T;
|
|
63
|
+
/** Drop one cached slot, or the whole cache when `name` is omitted. */
|
|
64
|
+
export declare function clear(name?: OneOrMany<string>): void;
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The ambient CONTEXT a cached value belongs to, and a cache keyed by it.
|
|
3
|
+
*
|
|
4
|
+
* Most of the expensive lookups in this repo are pure functions of the directory
|
|
5
|
+
* (or the page) they were asked from: `npm prefix`, `git rev-parse`, a `.env`
|
|
6
|
+
* file, `databricks bundle validate`. Memoizing them with
|
|
7
|
+
* {@link functionModule.memoize} is wrong in exactly one situation, and it is the
|
|
8
|
+
* situation a CLI hits: the process changes directory, and the cached answer now
|
|
9
|
+
* describes somewhere else. Every caller therefore grew the same guard - resolve
|
|
10
|
+
* `cwd`, compare it against `process.cwd()`, and skip the cache when they differ
|
|
11
|
+
* (see the `cacheEnabled` dance this module replaced in node-core's `project`).
|
|
12
|
+
*
|
|
13
|
+
* This is that guard, once. A cache slot stores the context it was loaded under,
|
|
14
|
+
* so a context change (a moved `cwd`, a different origin) MISSES rather than
|
|
15
|
+
* returns a stale value, and a lookup for some OTHER directory is not cached at
|
|
16
|
+
* all - one off-context call must not evict or poison the hot path.
|
|
17
|
+
*
|
|
18
|
+
* The context is the process working directory on a server and
|
|
19
|
+
* `location.origin` in a browser, whichever this runtime has. Browser-safe:
|
|
20
|
+
* `process` and `location` are reached through `globalThis` and guarded, so this
|
|
21
|
+
* module needs no Node types and simply has no context off-process.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* const roots = context.cached(["project", "npm", "prefix"], (cwd) =>
|
|
25
|
+
* spawnSync("npm", ["prefix"], { cwd }),
|
|
26
|
+
* );
|
|
27
|
+
*
|
|
28
|
+
* @module
|
|
29
|
+
*/
|
|
30
|
+
const CACHE = new Map();
|
|
31
|
+
/**
|
|
32
|
+
* The current context: the process working directory, else `location.origin`,
|
|
33
|
+
* else `undefined` (a runtime with neither, where nothing is cacheable).
|
|
34
|
+
*/
|
|
35
|
+
export function getContext() {
|
|
36
|
+
for (const context of getContexts())
|
|
37
|
+
return context;
|
|
38
|
+
return undefined;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Whether `value` names a context this runtime is CURRENTLY in - the live `cwd`
|
|
42
|
+
* or origin. This is the cacheability test: a value loaded for some other
|
|
43
|
+
* directory is correct but not shareable, so it is never stored.
|
|
44
|
+
*/
|
|
45
|
+
export function isContext(value) {
|
|
46
|
+
const context = toContext(value);
|
|
47
|
+
if (context === undefined)
|
|
48
|
+
return false;
|
|
49
|
+
for (const candidate of getContexts()) {
|
|
50
|
+
if (candidate === context)
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Load `name` through `loader`, reusing the cached value while the context is
|
|
57
|
+
* unchanged.
|
|
58
|
+
*
|
|
59
|
+
* `context` selects what the value is loaded FOR: omitted, `null`, or `"."` mean
|
|
60
|
+
* the current context. It is passed straight to `loader`, so a loader never has
|
|
61
|
+
* to reach for `process.cwd()` itself.
|
|
62
|
+
*
|
|
63
|
+
* Caching happens only when the resolved context is one this runtime is in
|
|
64
|
+
* ({@link isContext}), so `cached(name, loader, "/somewhere/else")` always calls
|
|
65
|
+
* `loader` and stores nothing. A stored entry remembers its context and is
|
|
66
|
+
* discarded on the next call once that context changes. A thrown error is never
|
|
67
|
+
* cached; a rejected promise evicts its entry so a later call retries.
|
|
68
|
+
*
|
|
69
|
+
* `name` identifies the slot and must be stable across calls - pass a
|
|
70
|
+
* module-qualified list of string parts (`["project", command, ...args]`) so two
|
|
71
|
+
* modules cannot collide on one slot.
|
|
72
|
+
*/
|
|
73
|
+
export function cached(name, loader, context) {
|
|
74
|
+
const resolved = toContext(context) ?? getContext();
|
|
75
|
+
const key = resolved !== undefined && isContext(resolved) ? cacheKey(name) : undefined;
|
|
76
|
+
if (key !== undefined) {
|
|
77
|
+
const entry = CACHE.get(key);
|
|
78
|
+
if (entry && entry.context === resolved)
|
|
79
|
+
return entry.value;
|
|
80
|
+
}
|
|
81
|
+
const value = loader(resolved);
|
|
82
|
+
if (key !== undefined && resolved !== undefined) {
|
|
83
|
+
const entry = { context: resolved, value };
|
|
84
|
+
CACHE.set(key, entry);
|
|
85
|
+
if (isThenable(value)) {
|
|
86
|
+
void Promise.resolve(value).catch(() => {
|
|
87
|
+
if (CACHE.get(key) === entry)
|
|
88
|
+
CACHE.delete(key);
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return value;
|
|
93
|
+
}
|
|
94
|
+
/** Drop one cached slot, or the whole cache when `name` is omitted. */
|
|
95
|
+
export function clear(name) {
|
|
96
|
+
if (name === undefined)
|
|
97
|
+
CACHE.clear();
|
|
98
|
+
else
|
|
99
|
+
CACHE.delete(cacheKey(name));
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Canonical slot key. `JSON.stringify` over the parts rather than a hash: the
|
|
103
|
+
* parts are already strings, and an exact key cannot collide two unrelated
|
|
104
|
+
* lookups onto one slot the way a truncated digest can.
|
|
105
|
+
*/
|
|
106
|
+
function cacheKey(name) {
|
|
107
|
+
return JSON.stringify(typeof name === "string" ? [name] : name);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Every context this runtime reports, in precedence order. A server yields its
|
|
111
|
+
* `cwd`; a browser yields `location.origin`. A hybrid (a worker with both) yields
|
|
112
|
+
* both, which is what makes {@link isContext} accept either.
|
|
113
|
+
*/
|
|
114
|
+
function* getContexts() {
|
|
115
|
+
const global = globalThis;
|
|
116
|
+
const cwd = global.process?.cwd;
|
|
117
|
+
if (typeof cwd === "function") {
|
|
118
|
+
let current;
|
|
119
|
+
try {
|
|
120
|
+
current = cwd();
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
current = undefined;
|
|
124
|
+
}
|
|
125
|
+
const context = toContext(current);
|
|
126
|
+
if (context !== undefined)
|
|
127
|
+
yield context;
|
|
128
|
+
}
|
|
129
|
+
const origin = toContext(global.location?.origin);
|
|
130
|
+
if (origin !== undefined)
|
|
131
|
+
yield origin;
|
|
132
|
+
}
|
|
133
|
+
/** A non-blank string, with `"."` treated as "the current context" (unresolved). */
|
|
134
|
+
function toContext(value) {
|
|
135
|
+
if (typeof value !== "string")
|
|
136
|
+
return undefined;
|
|
137
|
+
const trimmed = value.trim();
|
|
138
|
+
return trimmed && trimmed !== "." ? trimmed : undefined;
|
|
139
|
+
}
|
|
140
|
+
/** Duck-type any value with a callable `.then` as a thenable. */
|
|
141
|
+
function isThenable(value) {
|
|
142
|
+
return (value instanceof Promise ||
|
|
143
|
+
(typeof value === "object" &&
|
|
144
|
+
value !== null &&
|
|
145
|
+
"then" in value &&
|
|
146
|
+
typeof value.then === "function"));
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udGV4dC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb250ZXh0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBNEJHO0FBWUgsTUFBTSxLQUFLLEdBQUcsSUFBSSxHQUFHLEVBQXNCLENBQUM7QUFFNUM7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLFVBQVU7SUFDeEIsS0FBSyxNQUFNLE9BQU8sSUFBSSxXQUFXLEVBQUU7UUFBRSxPQUFPLE9BQU8sQ0FBQztJQUNwRCxPQUFPLFNBQVMsQ0FBQztBQUNuQixDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILE1BQU0sVUFBVSxTQUFTLENBQUMsS0FBYztJQUN0QyxNQUFNLE9BQU8sR0FBRyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDakMsSUFBSSxPQUFPLEtBQUssU0FBUztRQUFFLE9BQU8sS0FBSyxDQUFDO0lBQ3hDLEtBQUssTUFBTSxTQUFTLElBQUksV0FBVyxFQUFFLEVBQUUsQ0FBQztRQUN0QyxJQUFJLFNBQVMsS0FBSyxPQUFPO1lBQUUsT0FBTyxJQUFJLENBQUM7SUFDekMsQ0FBQztJQUNELE9BQU8sS0FBSyxDQUFDO0FBQ2YsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7OztHQWlCRztBQUNILE1BQU0sVUFBVSxNQUFNLENBQ3BCLElBQXVCLEVBQ3ZCLE1BQXdCLEVBQ3hCLE9BQXVCO0lBRXZCLE1BQU0sUUFBUSxHQUFHLFNBQVMsQ0FBQyxPQUFPLENBQUMsSUFBSSxVQUFVLEVBQUUsQ0FBQztJQUNwRCxNQUFNLEdBQUcsR0FBRyxRQUFRLEtBQUssU0FBUyxJQUFJLFNBQVMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7SUFDdkYsSUFBSSxHQUFHLEtBQUssU0FBUyxFQUFFLENBQUM7UUFDdEIsTUFBTSxLQUFLLEdBQUcsS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUM3QixJQUFJLEtBQUssSUFBSSxLQUFLLENBQUMsT0FBTyxLQUFLLFFBQVE7WUFBRSxPQUFPLEtBQUssQ0FBQyxLQUFVLENBQUM7SUFDbkUsQ0FBQztJQUNELE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUMvQixJQUFJLEdBQUcsS0FBSyxTQUFTLElBQUksUUFBUSxLQUFLLFNBQVMsRUFBRSxDQUFDO1FBQ2hELE1BQU0sS0FBSyxHQUFlLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsQ0FBQztRQUN2RCxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUN0QixJQUFJLFVBQVUsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ3RCLEtBQUssT0FBTyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFO2dCQUNyQyxJQUFJLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEtBQUssS0FBSztvQkFBRSxLQUFLLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ2xELENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztJQUNILENBQUM7SUFDRCxPQUFPLEtBQUssQ0FBQztBQUNmLENBQUM7QUFFRCx1RUFBdUU7QUFDdkUsTUFBTSxVQUFVLEtBQUssQ0FBQyxJQUF3QjtJQUM1QyxJQUFJLElBQUksS0FBSyxTQUFTO1FBQUUsS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDOztRQUNqQyxLQUFLLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0FBQ3BDLENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsU0FBUyxRQUFRLENBQUMsSUFBdUI7SUFDdkMsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sSUFBSSxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDbEUsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxRQUFRLENBQUMsQ0FBQyxXQUFXO0lBQ25CLE1BQU0sTUFBTSxHQUFHLFVBR2QsQ0FBQztJQUNGLE1BQU0sR0FBRyxHQUFHLE1BQU0sQ0FBQyxPQUFPLEVBQUUsR0FBRyxDQUFDO0lBQ2hDLElBQUksT0FBTyxHQUFHLEtBQUssVUFBVSxFQUFFLENBQUM7UUFDOUIsSUFBSSxPQUFnQixDQUFDO1FBQ3JCLElBQUksQ0FBQztZQUNILE9BQU8sR0FBRyxHQUFHLEVBQUUsQ0FBQztRQUNsQixDQUFDO1FBQUMsTUFBTSxDQUFDO1lBQ1AsT0FBTyxHQUFHLFNBQVMsQ0FBQztRQUN0QixDQUFDO1FBQ0QsTUFBTSxPQUFPLEdBQUcsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ25DLElBQUksT0FBTyxLQUFLLFNBQVM7WUFBRSxNQUFNLE9BQU8sQ0FBQztJQUMzQyxDQUFDO0lBQ0QsTUFBTSxNQUFNLEdBQUcsU0FBUyxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDbEQsSUFBSSxNQUFNLEtBQUssU0FBUztRQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ3pDLENBQUM7QUFFRCxvRkFBb0Y7QUFDcEYsU0FBUyxTQUFTLENBQUMsS0FBYztJQUMvQixJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVE7UUFBRSxPQUFPLFNBQVMsQ0FBQztJQUNoRCxNQUFNLE9BQU8sR0FBRyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDN0IsT0FBTyxPQUFPLElBQUksT0FBTyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7QUFDMUQsQ0FBQztBQUVELGlFQUFpRTtBQUNqRSxTQUFTLFVBQVUsQ0FBQyxLQUFjO0lBQ2hDLE9BQU8sQ0FDTCxLQUFLLFlBQVksT0FBTztRQUN4QixDQUFDLE9BQU8sS0FBSyxLQUFLLFFBQVE7WUFDeEIsS0FBSyxLQUFLLElBQUk7WUFDZCxNQUFNLElBQUksS0FBSztZQUNmLE9BQVEsS0FBOEIsQ0FBQyxJQUFJLEtBQUssVUFBVSxDQUFDLENBQzlELENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBUaGUgYW1iaWVudCBDT05URVhUIGEgY2FjaGVkIHZhbHVlIGJlbG9uZ3MgdG8sIGFuZCBhIGNhY2hlIGtleWVkIGJ5IGl0LlxuICpcbiAqIE1vc3Qgb2YgdGhlIGV4cGVuc2l2ZSBsb29rdXBzIGluIHRoaXMgcmVwbyBhcmUgcHVyZSBmdW5jdGlvbnMgb2YgdGhlIGRpcmVjdG9yeVxuICogKG9yIHRoZSBwYWdlKSB0aGV5IHdlcmUgYXNrZWQgZnJvbTogYG5wbSBwcmVmaXhgLCBgZ2l0IHJldi1wYXJzZWAsIGEgYC5lbnZgXG4gKiBmaWxlLCBgZGF0YWJyaWNrcyBidW5kbGUgdmFsaWRhdGVgLiBNZW1vaXppbmcgdGhlbSB3aXRoXG4gKiB7QGxpbmsgZnVuY3Rpb25Nb2R1bGUubWVtb2l6ZX0gaXMgd3JvbmcgaW4gZXhhY3RseSBvbmUgc2l0dWF0aW9uLCBhbmQgaXQgaXMgdGhlXG4gKiBzaXR1YXRpb24gYSBDTEkgaGl0czogdGhlIHByb2Nlc3MgY2hhbmdlcyBkaXJlY3RvcnksIGFuZCB0aGUgY2FjaGVkIGFuc3dlciBub3dcbiAqIGRlc2NyaWJlcyBzb21ld2hlcmUgZWxzZS4gRXZlcnkgY2FsbGVyIHRoZXJlZm9yZSBncmV3IHRoZSBzYW1lIGd1YXJkIC0gcmVzb2x2ZVxuICogYGN3ZGAsIGNvbXBhcmUgaXQgYWdhaW5zdCBgcHJvY2Vzcy5jd2QoKWAsIGFuZCBza2lwIHRoZSBjYWNoZSB3aGVuIHRoZXkgZGlmZmVyXG4gKiAoc2VlIHRoZSBgY2FjaGVFbmFibGVkYCBkYW5jZSB0aGlzIG1vZHVsZSByZXBsYWNlZCBpbiBub2RlLWNvcmUncyBgcHJvamVjdGApLlxuICpcbiAqIFRoaXMgaXMgdGhhdCBndWFyZCwgb25jZS4gQSBjYWNoZSBzbG90IHN0b3JlcyB0aGUgY29udGV4dCBpdCB3YXMgbG9hZGVkIHVuZGVyLFxuICogc28gYSBjb250ZXh0IGNoYW5nZSAoYSBtb3ZlZCBgY3dkYCwgYSBkaWZmZXJlbnQgb3JpZ2luKSBNSVNTRVMgcmF0aGVyIHRoYW5cbiAqIHJldHVybnMgYSBzdGFsZSB2YWx1ZSwgYW5kIGEgbG9va3VwIGZvciBzb21lIE9USEVSIGRpcmVjdG9yeSBpcyBub3QgY2FjaGVkIGF0XG4gKiBhbGwgLSBvbmUgb2ZmLWNvbnRleHQgY2FsbCBtdXN0IG5vdCBldmljdCBvciBwb2lzb24gdGhlIGhvdCBwYXRoLlxuICpcbiAqIFRoZSBjb250ZXh0IGlzIHRoZSBwcm9jZXNzIHdvcmtpbmcgZGlyZWN0b3J5IG9uIGEgc2VydmVyIGFuZFxuICogYGxvY2F0aW9uLm9yaWdpbmAgaW4gYSBicm93c2VyLCB3aGljaGV2ZXIgdGhpcyBydW50aW1lIGhhcy4gQnJvd3Nlci1zYWZlOlxuICogYHByb2Nlc3NgIGFuZCBgbG9jYXRpb25gIGFyZSByZWFjaGVkIHRocm91Z2ggYGdsb2JhbFRoaXNgIGFuZCBndWFyZGVkLCBzbyB0aGlzXG4gKiBtb2R1bGUgbmVlZHMgbm8gTm9kZSB0eXBlcyBhbmQgc2ltcGx5IGhhcyBubyBjb250ZXh0IG9mZi1wcm9jZXNzLlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCByb290cyA9IGNvbnRleHQuY2FjaGVkKFtcInByb2plY3RcIiwgXCJucG1cIiwgXCJwcmVmaXhcIl0sIChjd2QpID0+XG4gKiAgIHNwYXduU3luYyhcIm5wbVwiLCBbXCJwcmVmaXhcIl0sIHsgY3dkIH0pLFxuICogKTtcbiAqXG4gKiBAbW9kdWxlXG4gKi9cblxuaW1wb3J0IHR5cGUgeyBPbmVPck1hbnkgfSBmcm9tIFwiLi9vYmplY3QudHNcIjtcblxuLyoqIEEgbG9hZGVyIGZvciBhIGNhY2hlZCB2YWx1ZTsgcmVjZWl2ZXMgdGhlIHJlc29sdmVkIGNvbnRleHQuICovXG5leHBvcnQgdHlwZSBDb250ZXh0TG9hZGVyPFQ+ID0gKGNvbnRleHQ6IHN0cmluZyB8IHVuZGVmaW5lZCkgPT4gVDtcblxuaW50ZXJmYWNlIENhY2hlRW50cnkge1xuICBjb250ZXh0OiBzdHJpbmc7XG4gIHZhbHVlOiB1bmtub3duO1xufVxuXG5jb25zdCBDQUNIRSA9IG5ldyBNYXA8c3RyaW5nLCBDYWNoZUVudHJ5PigpO1xuXG4vKipcbiAqIFRoZSBjdXJyZW50IGNvbnRleHQ6IHRoZSBwcm9jZXNzIHdvcmtpbmcgZGlyZWN0b3J5LCBlbHNlIGBsb2NhdGlvbi5vcmlnaW5gLFxuICogZWxzZSBgdW5kZWZpbmVkYCAoYSBydW50aW1lIHdpdGggbmVpdGhlciwgd2hlcmUgbm90aGluZyBpcyBjYWNoZWFibGUpLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q29udGV4dCgpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBmb3IgKGNvbnN0IGNvbnRleHQgb2YgZ2V0Q29udGV4dHMoKSkgcmV0dXJuIGNvbnRleHQ7XG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogV2hldGhlciBgdmFsdWVgIG5hbWVzIGEgY29udGV4dCB0aGlzIHJ1bnRpbWUgaXMgQ1VSUkVOVExZIGluIC0gdGhlIGxpdmUgYGN3ZGBcbiAqIG9yIG9yaWdpbi4gVGhpcyBpcyB0aGUgY2FjaGVhYmlsaXR5IHRlc3Q6IGEgdmFsdWUgbG9hZGVkIGZvciBzb21lIG90aGVyXG4gKiBkaXJlY3RvcnkgaXMgY29ycmVjdCBidXQgbm90IHNoYXJlYWJsZSwgc28gaXQgaXMgbmV2ZXIgc3RvcmVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNDb250ZXh0KHZhbHVlOiB1bmtub3duKTogYm9vbGVhbiB7XG4gIGNvbnN0IGNvbnRleHQgPSB0b0NvbnRleHQodmFsdWUpO1xuICBpZiAoY29udGV4dCA9PT0gdW5kZWZpbmVkKSByZXR1cm4gZmFsc2U7XG4gIGZvciAoY29uc3QgY2FuZGlkYXRlIG9mIGdldENvbnRleHRzKCkpIHtcbiAgICBpZiAoY2FuZGlkYXRlID09PSBjb250ZXh0KSByZXR1cm4gdHJ1ZTtcbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogTG9hZCBgbmFtZWAgdGhyb3VnaCBgbG9hZGVyYCwgcmV1c2luZyB0aGUgY2FjaGVkIHZhbHVlIHdoaWxlIHRoZSBjb250ZXh0IGlzXG4gKiB1bmNoYW5nZWQuXG4gKlxuICogYGNvbnRleHRgIHNlbGVjdHMgd2hhdCB0aGUgdmFsdWUgaXMgbG9hZGVkIEZPUjogb21pdHRlZCwgYG51bGxgLCBvciBgXCIuXCJgIG1lYW5cbiAqIHRoZSBjdXJyZW50IGNvbnRleHQuIEl0IGlzIHBhc3NlZCBzdHJhaWdodCB0byBgbG9hZGVyYCwgc28gYSBsb2FkZXIgbmV2ZXIgaGFzXG4gKiB0byByZWFjaCBmb3IgYHByb2Nlc3MuY3dkKClgIGl0c2VsZi5cbiAqXG4gKiBDYWNoaW5nIGhhcHBlbnMgb25seSB3aGVuIHRoZSByZXNvbHZlZCBjb250ZXh0IGlzIG9uZSB0aGlzIHJ1bnRpbWUgaXMgaW5cbiAqICh7QGxpbmsgaXNDb250ZXh0fSksIHNvIGBjYWNoZWQobmFtZSwgbG9hZGVyLCBcIi9zb21ld2hlcmUvZWxzZVwiKWAgYWx3YXlzIGNhbGxzXG4gKiBgbG9hZGVyYCBhbmQgc3RvcmVzIG5vdGhpbmcuIEEgc3RvcmVkIGVudHJ5IHJlbWVtYmVycyBpdHMgY29udGV4dCBhbmQgaXNcbiAqIGRpc2NhcmRlZCBvbiB0aGUgbmV4dCBjYWxsIG9uY2UgdGhhdCBjb250ZXh0IGNoYW5nZXMuIEEgdGhyb3duIGVycm9yIGlzIG5ldmVyXG4gKiBjYWNoZWQ7IGEgcmVqZWN0ZWQgcHJvbWlzZSBldmljdHMgaXRzIGVudHJ5IHNvIGEgbGF0ZXIgY2FsbCByZXRyaWVzLlxuICpcbiAqIGBuYW1lYCBpZGVudGlmaWVzIHRoZSBzbG90IGFuZCBtdXN0IGJlIHN0YWJsZSBhY3Jvc3MgY2FsbHMgLSBwYXNzIGFcbiAqIG1vZHVsZS1xdWFsaWZpZWQgbGlzdCBvZiBzdHJpbmcgcGFydHMgKGBbXCJwcm9qZWN0XCIsIGNvbW1hbmQsIC4uLmFyZ3NdYCkgc28gdHdvXG4gKiBtb2R1bGVzIGNhbm5vdCBjb2xsaWRlIG9uIG9uZSBzbG90LlxuICovXG5leHBvcnQgZnVuY3Rpb24gY2FjaGVkPFQ+KFxuICBuYW1lOiBPbmVPck1hbnk8c3RyaW5nPixcbiAgbG9hZGVyOiBDb250ZXh0TG9hZGVyPFQ+LFxuICBjb250ZXh0Pzogc3RyaW5nIHwgbnVsbCxcbik6IFQge1xuICBjb25zdCByZXNvbHZlZCA9IHRvQ29udGV4dChjb250ZXh0KSA/PyBnZXRDb250ZXh0KCk7XG4gIGNvbnN0IGtleSA9IHJlc29sdmVkICE9PSB1bmRlZmluZWQgJiYgaXNDb250ZXh0KHJlc29sdmVkKSA/IGNhY2hlS2V5KG5hbWUpIDogdW5kZWZpbmVkO1xuICBpZiAoa2V5ICE9PSB1bmRlZmluZWQpIHtcbiAgICBjb25zdCBlbnRyeSA9IENBQ0hFLmdldChrZXkpO1xuICAgIGlmIChlbnRyeSAmJiBlbnRyeS5jb250ZXh0ID09PSByZXNvbHZlZCkgcmV0dXJuIGVudHJ5LnZhbHVlIGFzIFQ7XG4gIH1cbiAgY29uc3QgdmFsdWUgPSBsb2FkZXIocmVzb2x2ZWQpO1xuICBpZiAoa2V5ICE9PSB1bmRlZmluZWQgJiYgcmVzb2x2ZWQgIT09IHVuZGVmaW5lZCkge1xuICAgIGNvbnN0IGVudHJ5OiBDYWNoZUVudHJ5ID0geyBjb250ZXh0OiByZXNvbHZlZCwgdmFsdWUgfTtcbiAgICBDQUNIRS5zZXQoa2V5LCBlbnRyeSk7XG4gICAgaWYgKGlzVGhlbmFibGUodmFsdWUpKSB7XG4gICAgICB2b2lkIFByb21pc2UucmVzb2x2ZSh2YWx1ZSkuY2F0Y2goKCkgPT4ge1xuICAgICAgICBpZiAoQ0FDSEUuZ2V0KGtleSkgPT09IGVudHJ5KSBDQUNIRS5kZWxldGUoa2V5KTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdmFsdWU7XG59XG5cbi8qKiBEcm9wIG9uZSBjYWNoZWQgc2xvdCwgb3IgdGhlIHdob2xlIGNhY2hlIHdoZW4gYG5hbWVgIGlzIG9taXR0ZWQuICovXG5leHBvcnQgZnVuY3Rpb24gY2xlYXIobmFtZT86IE9uZU9yTWFueTxzdHJpbmc+KTogdm9pZCB7XG4gIGlmIChuYW1lID09PSB1bmRlZmluZWQpIENBQ0hFLmNsZWFyKCk7XG4gIGVsc2UgQ0FDSEUuZGVsZXRlKGNhY2hlS2V5KG5hbWUpKTtcbn1cblxuLyoqXG4gKiBDYW5vbmljYWwgc2xvdCBrZXkuIGBKU09OLnN0cmluZ2lmeWAgb3ZlciB0aGUgcGFydHMgcmF0aGVyIHRoYW4gYSBoYXNoOiB0aGVcbiAqIHBhcnRzIGFyZSBhbHJlYWR5IHN0cmluZ3MsIGFuZCBhbiBleGFjdCBrZXkgY2Fubm90IGNvbGxpZGUgdHdvIHVucmVsYXRlZFxuICogbG9va3VwcyBvbnRvIG9uZSBzbG90IHRoZSB3YXkgYSB0cnVuY2F0ZWQgZGlnZXN0IGNhbi5cbiAqL1xuZnVuY3Rpb24gY2FjaGVLZXkobmFtZTogT25lT3JNYW55PHN0cmluZz4pOiBzdHJpbmcge1xuICByZXR1cm4gSlNPTi5zdHJpbmdpZnkodHlwZW9mIG5hbWUgPT09IFwic3RyaW5nXCIgPyBbbmFtZV0gOiBuYW1lKTtcbn1cblxuLyoqXG4gKiBFdmVyeSBjb250ZXh0IHRoaXMgcnVudGltZSByZXBvcnRzLCBpbiBwcmVjZWRlbmNlIG9yZGVyLiBBIHNlcnZlciB5aWVsZHMgaXRzXG4gKiBgY3dkYDsgYSBicm93c2VyIHlpZWxkcyBgbG9jYXRpb24ub3JpZ2luYC4gQSBoeWJyaWQgKGEgd29ya2VyIHdpdGggYm90aCkgeWllbGRzXG4gKiBib3RoLCB3aGljaCBpcyB3aGF0IG1ha2VzIHtAbGluayBpc0NvbnRleHR9IGFjY2VwdCBlaXRoZXIuXG4gKi9cbmZ1bmN0aW9uKiBnZXRDb250ZXh0cygpOiBHZW5lcmF0b3I8c3RyaW5nLCB2b2lkLCB2b2lkPiB7XG4gIGNvbnN0IGdsb2JhbCA9IGdsb2JhbFRoaXMgYXMge1xuICAgIHByb2Nlc3M/OiB7IGN3ZD86ICgpID0+IHN0cmluZyB9O1xuICAgIGxvY2F0aW9uPzogeyBvcmlnaW4/OiBzdHJpbmcgfTtcbiAgfTtcbiAgY29uc3QgY3dkID0gZ2xvYmFsLnByb2Nlc3M/LmN3ZDtcbiAgaWYgKHR5cGVvZiBjd2QgPT09IFwiZnVuY3Rpb25cIikge1xuICAgIGxldCBjdXJyZW50OiB1bmtub3duO1xuICAgIHRyeSB7XG4gICAgICBjdXJyZW50ID0gY3dkKCk7XG4gICAgfSBjYXRjaCB7XG4gICAgICBjdXJyZW50ID0gdW5kZWZpbmVkO1xuICAgIH1cbiAgICBjb25zdCBjb250ZXh0ID0gdG9Db250ZXh0KGN1cnJlbnQpO1xuICAgIGlmIChjb250ZXh0ICE9PSB1bmRlZmluZWQpIHlpZWxkIGNvbnRleHQ7XG4gIH1cbiAgY29uc3Qgb3JpZ2luID0gdG9Db250ZXh0KGdsb2JhbC5sb2NhdGlvbj8ub3JpZ2luKTtcbiAgaWYgKG9yaWdpbiAhPT0gdW5kZWZpbmVkKSB5aWVsZCBvcmlnaW47XG59XG5cbi8qKiBBIG5vbi1ibGFuayBzdHJpbmcsIHdpdGggYFwiLlwiYCB0cmVhdGVkIGFzIFwidGhlIGN1cnJlbnQgY29udGV4dFwiICh1bnJlc29sdmVkKS4gKi9cbmZ1bmN0aW9uIHRvQ29udGV4dCh2YWx1ZTogdW5rbm93bik6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGlmICh0eXBlb2YgdmFsdWUgIT09IFwic3RyaW5nXCIpIHJldHVybiB1bmRlZmluZWQ7XG4gIGNvbnN0IHRyaW1tZWQgPSB2YWx1ZS50cmltKCk7XG4gIHJldHVybiB0cmltbWVkICYmIHRyaW1tZWQgIT09IFwiLlwiID8gdHJpbW1lZCA6IHVuZGVmaW5lZDtcbn1cblxuLyoqIER1Y2stdHlwZSBhbnkgdmFsdWUgd2l0aCBhIGNhbGxhYmxlIGAudGhlbmAgYXMgYSB0aGVuYWJsZS4gKi9cbmZ1bmN0aW9uIGlzVGhlbmFibGUodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBQcm9taXNlTGlrZTx1bmtub3duPiB7XG4gIHJldHVybiAoXG4gICAgdmFsdWUgaW5zdGFuY2VvZiBQcm9taXNlIHx8XG4gICAgKHR5cGVvZiB2YWx1ZSA9PT0gXCJvYmplY3RcIiAmJlxuICAgICAgdmFsdWUgIT09IG51bGwgJiZcbiAgICAgIFwidGhlblwiIGluIHZhbHVlICYmXG4gICAgICB0eXBlb2YgKHZhbHVlIGFzIFByb21pc2VMaWtlPHVua25vd24+KS50aGVuID09PSBcImZ1bmN0aW9uXCIpXG4gICk7XG59XG4iXX0=
|
package/lib/src/object.d.ts
CHANGED
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
*/
|
|
25
25
|
/** Lazy sequence over iterable source(s). See {@link sequence}. */
|
|
26
26
|
export type Sequence<T> = SequenceImpl<T>;
|
|
27
|
-
type SequenceSource<T> = Iterable<T> | ReadonlyMap<unknown, T> | OneOrMany<T> | null | undefined;
|
|
27
|
+
type SequenceSource<T> = Iterable<T> | ReadonlyMap<unknown, T> | OneOrMany<T> | Extract<T, string> | null | undefined;
|
|
28
28
|
/**
|
|
29
29
|
* A non-scalar {@link Iterable} - one to treat as a collection of elements
|
|
30
30
|
* rather than a scalar. {@link isContainer} narrows to this, excluding strings,
|
|
@@ -449,7 +449,7 @@ export declare function toStableKey(value: unknown, seen?: Set<object>): string;
|
|
|
449
449
|
*
|
|
450
450
|
* @example
|
|
451
451
|
* return {
|
|
452
|
-
* ...optional("appId",
|
|
452
|
+
* ...optional("appId", configuredAppId),
|
|
453
453
|
* ...optional("endpoint", config.endpoint),
|
|
454
454
|
* };
|
|
455
455
|
*/
|