@gtkx/utils 0.21.0 → 1.0.0-rc.1
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 +173 -0
- package/dist/class.d.ts +17 -11
- package/dist/class.d.ts.map +1 -1
- package/dist/class.js +27 -1
- package/dist/class.js.map +1 -1
- package/dist/collection.d.ts +17 -45
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +42 -76
- package/dist/collection.js.map +1 -1
- package/dist/error.d.ts +16 -8
- package/dist/error.d.ts.map +1 -1
- package/dist/error.js +35 -8
- package/dist/error.js.map +1 -1
- package/dist/graceful-shutdown.d.ts +9 -57
- package/dist/graceful-shutdown.d.ts.map +1 -1
- package/dist/graceful-shutdown.js +70 -75
- package/dist/graceful-shutdown.js.map +1 -1
- package/dist/index.d.ts +9 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -5
- package/dist/index.js.map +1 -1
- package/dist/log.d.ts +103 -0
- package/dist/log.d.ts.map +1 -0
- package/dist/log.js +129 -0
- package/dist/log.js.map +1 -0
- package/dist/package-version.d.ts +7 -0
- package/dist/package-version.d.ts.map +1 -0
- package/dist/package-version.js +8 -0
- package/dist/package-version.js.map +1 -0
- package/dist/reflect.d.ts +11 -0
- package/dist/reflect.d.ts.map +1 -0
- package/dist/reflect.js +14 -0
- package/dist/reflect.js.map +1 -0
- package/dist/source.d.ts +12 -25
- package/dist/source.d.ts.map +1 -1
- package/dist/source.js +20 -41
- package/dist/source.js.map +1 -1
- package/dist/string.d.ts +13 -40
- package/dist/string.d.ts.map +1 -1
- package/dist/string.js +18 -48
- package/dist/string.js.map +1 -1
- package/package.json +20 -7
- package/src/class.ts +30 -11
- package/src/collection.ts +43 -81
- package/src/error.ts +38 -8
- package/src/graceful-shutdown.ts +87 -114
- package/src/index.ts +18 -9
- package/src/log.ts +164 -0
- package/src/package-version.ts +9 -0
- package/src/reflect.ts +13 -0
- package/src/source.ts +24 -43
- package/src/string.ts +19 -47
package/README.md
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="https://raw.githubusercontent.com/gtkx-org/gtkx/main/logo.svg" alt="GTKX" width="100" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h1 align="center">GTKX</h1>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
The React framework for Linux.<br />
|
|
9
|
+
Build GTK4 and Adwaita apps in TypeScript, with React components and hooks driving GNOME's own widgets. What you ship is a GNOME app.
|
|
10
|
+
</p>
|
|
11
|
+
|
|
12
|
+
<p align="center">
|
|
13
|
+
<a href="https://www.npmjs.com/package/create-gtkx"><img src="https://img.shields.io/npm/v/create-gtkx?color=cb3837&logo=npm&label=create-gtkx" alt="npm version" /></a>
|
|
14
|
+
<a href="https://www.npmjs.com/package/create-gtkx"><img src="https://img.shields.io/npm/dm/create-gtkx?color=cb3837&logo=npm&label=downloads" alt="npm downloads" /></a>
|
|
15
|
+
<img src="https://img.shields.io/badge/node-%E2%89%A524-339933?logo=node.js&logoColor=white" alt="Node >= 24" />
|
|
16
|
+
<a href="https://github.com/gtkx-org/gtkx/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MPL--2.0-blue.svg" alt="License: MPL-2.0" /></a>
|
|
17
|
+
<a href="https://github.com/gtkx-org/gtkx/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/gtkx-org/gtkx/ci.yml?branch=main&logo=github&label=CI" alt="CI status" /></a>
|
|
18
|
+
<img src="https://img.shields.io/badge/TypeScript-strict-3178c6?logo=typescript&logoColor=white" alt="TypeScript" />
|
|
19
|
+
</p>
|
|
20
|
+
|
|
21
|
+
<p align="center">
|
|
22
|
+
<a href="https://gtkx.dev">Homepage</a> ·
|
|
23
|
+
<a href="https://gtkx.dev/guide/why-gtkx">Documentation</a> ·
|
|
24
|
+
<a href="https://github.com/gtkx-org/gtkx/tree/main/examples">Examples</a> ·
|
|
25
|
+
<a href="https://github.com/gtkx-org/gtkx/blob/main/CONTRIBUTING.md">Contributing</a>
|
|
26
|
+
</p>
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
GTKX generates fully typed bindings for the entire GTK4 and Adwaita surface directly from GObject-Introspection. On top of those bindings you get the React programming model: components and hooks driving GObject instances, with Fast Refresh while you develop.
|
|
31
|
+
|
|
32
|
+
<p align="center">
|
|
33
|
+
<img src="https://raw.githubusercontent.com/gtkx-org/gtkx/main/examples/tutorial/assets/screenshot.png" alt="The Tasks app: an Adwaita window with a sidebar of smart views and colored lists on the left, and a boxed task list on the right." />
|
|
34
|
+
</p>
|
|
35
|
+
|
|
36
|
+
<p align="center">
|
|
37
|
+
<em>The Tasks app you build in the <a href="https://gtkx.dev/tutorial/">tutorial</a>.</em>
|
|
38
|
+
</p>
|
|
39
|
+
|
|
40
|
+
## Demo
|
|
41
|
+
|
|
42
|
+
The intrinsic elements in this snippet render GTK4 widgets, and ordinary React hooks and events drive them:
|
|
43
|
+
|
|
44
|
+
```tsx
|
|
45
|
+
import * as Gtk from "@gtkx/gi/gtk";
|
|
46
|
+
import { GtkApplication, GtkApplicationWindow, GtkBox, GtkButton, GtkLabel } from "@gtkx/jsx/gtk";
|
|
47
|
+
import { createRoot, quit } from "@gtkx/react";
|
|
48
|
+
import { useState } from "react";
|
|
49
|
+
|
|
50
|
+
const Counter = () => {
|
|
51
|
+
const [count, setCount] = useState(0);
|
|
52
|
+
|
|
53
|
+
return (
|
|
54
|
+
<GtkApplicationWindow
|
|
55
|
+
title="Hello GTKX"
|
|
56
|
+
defaultWidth={400}
|
|
57
|
+
defaultHeight={300}
|
|
58
|
+
onCloseRequest={quit}
|
|
59
|
+
>
|
|
60
|
+
<GtkBox
|
|
61
|
+
orientation={Gtk.Orientation.VERTICAL}
|
|
62
|
+
spacing={20}
|
|
63
|
+
marginTop={40}
|
|
64
|
+
marginBottom={40}
|
|
65
|
+
marginStart={40}
|
|
66
|
+
marginEnd={40}
|
|
67
|
+
valign={Gtk.Align.CENTER}
|
|
68
|
+
halign={Gtk.Align.CENTER}
|
|
69
|
+
>
|
|
70
|
+
<GtkLabel cssClasses={["title-1"]}>Welcome to GTKX!</GtkLabel>
|
|
71
|
+
<GtkLabel cssClasses={["title-2"]}>{`Count: ${count}`}</GtkLabel>
|
|
72
|
+
<GtkButton
|
|
73
|
+
label="Increment"
|
|
74
|
+
onClicked={() => setCount((c) => c + 1)}
|
|
75
|
+
cssClasses={["suggested-action", "pill"]}
|
|
76
|
+
/>
|
|
77
|
+
</GtkBox>
|
|
78
|
+
</GtkApplicationWindow>
|
|
79
|
+
);
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const App = () => (
|
|
83
|
+
<GtkApplication>
|
|
84
|
+
<Counter />
|
|
85
|
+
</GtkApplication>
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
createRoot().render(<App />);
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
This is the [`hello-world`](https://github.com/gtkx-org/gtkx/tree/main/examples/hello-world) example, with `app.tsx` and `index.tsx` combined into a single snippet. `@gtkx/gi` and `@gtkx/jsx` are per-project bindings generated by the CLI, not packages you install from npm.
|
|
92
|
+
|
|
93
|
+
## Why GTKX
|
|
94
|
+
|
|
95
|
+
### A declarative layer for the GNOME stack
|
|
96
|
+
|
|
97
|
+
GTK4 is mature, and GtkBuilder XML can lay out a static interface, but nothing re-renders that interface when your application state changes, and nothing hot-reloads it as you work. GTKX adds that missing layer, and the tooling around it, on top of the stack you already know:
|
|
98
|
+
|
|
99
|
+
- a React reconciler that exposes every GObject as a JSX element,
|
|
100
|
+
- a CLI for scaffolding, development, and production builds,
|
|
101
|
+
- a dev server with Fast Refresh that patches your running UI in place,
|
|
102
|
+
- CSS-in-JS styling and high-level list, grid, and dialog components,
|
|
103
|
+
- a Testing Library-style API for querying and driving your widgets in tests,
|
|
104
|
+
- and a Model Context Protocol (MCP) server that exposes your live app to AI agents.
|
|
105
|
+
|
|
106
|
+
### The full GNOME API surface
|
|
107
|
+
|
|
108
|
+
React Native and similar frameworks hide the native toolkit so one API can run everywhere. GTKX exposes it: GTK4, Adwaita, and any other GObject-Introspection library on your system. Linux-only by design.
|
|
109
|
+
|
|
110
|
+
### Why Node.js, and why generated bindings
|
|
111
|
+
|
|
112
|
+
GTKX runs on Node.js, which puts native modules, the npm ecosystem, and the tooling built for Node.js APIs within reach. GJS is GNOME's own runtime, built on SpiderMonkey rather than V8; node-gtk runs on Node.js but is lightly maintained, on the older nan/V8 ABI rather than N-API, and still centered on GTK3. The [why-gtkx guide](https://gtkx.dev/guide/why-gtkx) covers the comparison in full.
|
|
113
|
+
|
|
114
|
+
GTKX generates the TypeScript types and the native FFI calls from the same GObject-Introspection data, so the types cannot drift from the calls they back. Codegen covers the whole GTK4 and Adwaita surface.
|
|
115
|
+
|
|
116
|
+
At runtime, the native Rust core calls straight into the system GTK4, Adwaita, and GLib libraries through libffi, without loading libgirepository at all.
|
|
117
|
+
|
|
118
|
+
## Quick start
|
|
119
|
+
|
|
120
|
+
GTKX is Linux-only and needs Node.js 24 or later. See [Requirements](#requirements).
|
|
121
|
+
|
|
122
|
+
Scaffold a new app with the `create-gtkx` initializer:
|
|
123
|
+
|
|
124
|
+
```sh
|
|
125
|
+
npm create gtkx@rc
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
The same command works with other package managers: `pnpm create gtkx@rc` or `yarn create gtkx@rc`.
|
|
129
|
+
|
|
130
|
+
Then run your new app:
|
|
131
|
+
|
|
132
|
+
```sh
|
|
133
|
+
cd my-app
|
|
134
|
+
npm run dev
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
To go further, follow the [tutorial](https://gtkx.dev/tutorial/).
|
|
138
|
+
|
|
139
|
+
## Documentation
|
|
140
|
+
|
|
141
|
+
The documentation at **[gtkx.dev](https://gtkx.dev)** includes a step-by-step tutorial that builds a complete GNOME app, from scaffolding to packaging and shipping, plus guides and a full API reference.
|
|
142
|
+
|
|
143
|
+
**[Read the docs →](https://gtkx.dev/guide/why-gtkx)**
|
|
144
|
+
|
|
145
|
+
## Requirements
|
|
146
|
+
|
|
147
|
+
GTKX is Linux-only. You need:
|
|
148
|
+
|
|
149
|
+
- Linux with the GTK4 (4.20 or later), Adwaita (1.8 or later), and GLib development libraries
|
|
150
|
+
- Node.js 24 or later
|
|
151
|
+
|
|
152
|
+
The `@gtkx/native` addon ships prebuilt for x64 and arm64 glibc Linux; other targets need to build it from the GTKX repository, which requires a Rust toolchain.
|
|
153
|
+
|
|
154
|
+
## Examples
|
|
155
|
+
|
|
156
|
+
Explore the [example apps](https://github.com/gtkx-org/gtkx/tree/main/examples):
|
|
157
|
+
|
|
158
|
+
- [`hello-world`](https://github.com/gtkx-org/gtkx/tree/main/examples/hello-world): the counter above.
|
|
159
|
+
- [`gtk-demo`](https://github.com/gtkx-org/gtkx/tree/main/examples/gtk-demo): a React port of the official GTK4 widget showcase, covering lists, dialogs, gestures, CSS, and OpenGL.
|
|
160
|
+
- [`browser`](https://github.com/gtkx-org/gtkx/tree/main/examples/browser): a WebKitWebView-based web browser.
|
|
161
|
+
- [`tutorial`](https://github.com/gtkx-org/gtkx/tree/main/examples/tutorial): the Tasks app the documentation builds.
|
|
162
|
+
|
|
163
|
+
## Status
|
|
164
|
+
|
|
165
|
+
GTKX 1.0 is at the release candidate stage.
|
|
166
|
+
|
|
167
|
+
## Contributing
|
|
168
|
+
|
|
169
|
+
Contributions are welcome. See [CONTRIBUTING.md](https://github.com/gtkx-org/gtkx/blob/main/CONTRIBUTING.md), the [Code of Conduct](https://github.com/gtkx-org/gtkx/blob/main/CODE_OF_CONDUCT.md), and the [security policy](https://github.com/gtkx-org/gtkx/blob/main/SECURITY.md). Building the repo needs Node.js 24 or later, pnpm, and a Rust toolchain.
|
|
170
|
+
|
|
171
|
+
## License
|
|
172
|
+
|
|
173
|
+
GTKX is licensed under [MPL-2.0](https://github.com/gtkx-org/gtkx/blob/main/LICENSE).
|
package/dist/class.d.ts
CHANGED
|
@@ -1,16 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* have type `T`.
|
|
4
|
-
*
|
|
5
|
-
* A class value carries a construct signature plus a `prototype`, but a bare
|
|
6
|
-
* construct signature types `prototype` as `any`. The `& { prototype: T }`
|
|
7
|
-
* intersection recovers the precise instance type so callers can read
|
|
8
|
-
* `cls.prototype` as `T`, and the `abstract new` form accepts both abstract and
|
|
9
|
-
* concrete classes, making this the widest supertype of every class value. The
|
|
10
|
-
* `never[]` constructor parameters admit any class while documenting that the
|
|
11
|
-
* type is used as an identity token, not to construct instances.
|
|
2
|
+
* A constructor value of any (possibly abstract) class producing instances of `T`.
|
|
12
3
|
*/
|
|
13
4
|
export type AnyClass<T extends object = object> = (abstract new (...args: never[]) => T) & {
|
|
14
|
-
|
|
5
|
+
prototype: T;
|
|
15
6
|
};
|
|
7
|
+
/**
|
|
8
|
+
* Returns the direct superclass of `cls`, or `null` when it has no class ancestor.
|
|
9
|
+
*
|
|
10
|
+
* @param cls The class whose prototype parent to inspect.
|
|
11
|
+
*/
|
|
12
|
+
export declare function getParentClass(cls: AnyClass): AnyClass | null;
|
|
13
|
+
/**
|
|
14
|
+
* Walks the class chain from `cls` up through its ancestors, calling `visit` on each and
|
|
15
|
+
* returning the first result that is not `undefined`.
|
|
16
|
+
*
|
|
17
|
+
* @param cls The class to start from, or `null` to visit nothing.
|
|
18
|
+
* @param visit Called with each class in the chain; a defined return value stops the walk.
|
|
19
|
+
* @returns The first defined result from `visit`, or `undefined` if none was produced.
|
|
20
|
+
*/
|
|
21
|
+
export declare function walkClassChain<T>(cls: AnyClass | null, visit: (ancestor: AnyClass) => T | undefined): T | undefined;
|
|
16
22
|
//# sourceMappingURL=class.d.ts.map
|
package/dist/class.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"class.d.ts","sourceRoot":"","sources":["../src/class.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"class.d.ts","sourceRoot":"","sources":["../src/class.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,QAAQ,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,MACvD,GAAG,IAAI,EAAE,KAAK,EAAE,KACf,CAAC,CAAC,GAAG;IACN,SAAS,EAAE,CAAC,CAAC;CAChB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,QAAQ,GAAG,QAAQ,GAAG,IAAI,CAG7D;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,GAAG,EAAE,QAAQ,GAAG,IAAI,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,CAAC,GAAG,SAAS,GAAG,CAAC,GAAG,SAAS,CAQnH"}
|
package/dist/class.js
CHANGED
|
@@ -1,2 +1,28 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Returns the direct superclass of `cls`, or `null` when it has no class ancestor.
|
|
3
|
+
*
|
|
4
|
+
* @param cls The class whose prototype parent to inspect.
|
|
5
|
+
*/
|
|
6
|
+
export function getParentClass(cls) {
|
|
7
|
+
const parent = Object.getPrototypeOf(cls);
|
|
8
|
+
return typeof parent === "function" && parent !== Function.prototype ? parent : null;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Walks the class chain from `cls` up through its ancestors, calling `visit` on each and
|
|
12
|
+
* returning the first result that is not `undefined`.
|
|
13
|
+
*
|
|
14
|
+
* @param cls The class to start from, or `null` to visit nothing.
|
|
15
|
+
* @param visit Called with each class in the chain; a defined return value stops the walk.
|
|
16
|
+
* @returns The first defined result from `visit`, or `undefined` if none was produced.
|
|
17
|
+
*/
|
|
18
|
+
export function walkClassChain(cls, visit) {
|
|
19
|
+
let current = cls;
|
|
20
|
+
while (current !== null) {
|
|
21
|
+
const result = visit(current);
|
|
22
|
+
if (result !== undefined)
|
|
23
|
+
return result;
|
|
24
|
+
current = getParentClass(current);
|
|
25
|
+
}
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
2
28
|
//# sourceMappingURL=class.js.map
|
package/dist/class.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"class.js","sourceRoot":"","sources":["../src/class.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"class.js","sourceRoot":"","sources":["../src/class.ts"],"names":[],"mappings":"AASA;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,GAAa;IACxC,MAAM,MAAM,GAAY,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;IACnD,OAAO,OAAO,MAAM,KAAK,UAAU,IAAI,MAAM,KAAK,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAE,MAAmB,CAAC,CAAC,CAAC,IAAI,CAAC;AACvG,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAAI,GAAoB,EAAE,KAA4C;IAChG,IAAI,OAAO,GAAG,GAAG,CAAC;IAClB,OAAO,OAAO,KAAK,IAAI,EAAE,CAAC;QACtB,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC;QAC9B,IAAI,MAAM,KAAK,SAAS;YAAE,OAAO,MAAM,CAAC;QACxC,OAAO,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IACtC,CAAC;IACD,OAAO,SAAS,CAAC;AACrB,CAAC","sourcesContent":["/**\n * A constructor value of any (possibly abstract) class producing instances of `T`.\n */\nexport type AnyClass<T extends object = object> = (abstract new (\n ...args: never[]\n) => T) & {\n prototype: T;\n};\n\n/**\n * Returns the direct superclass of `cls`, or `null` when it has no class ancestor.\n *\n * @param cls The class whose prototype parent to inspect.\n */\nexport function getParentClass(cls: AnyClass): AnyClass | null {\n const parent: unknown = Object.getPrototypeOf(cls);\n return typeof parent === \"function\" && parent !== Function.prototype ? (parent as AnyClass) : null;\n}\n\n/**\n * Walks the class chain from `cls` up through its ancestors, calling `visit` on each and\n * returning the first result that is not `undefined`.\n *\n * @param cls The class to start from, or `null` to visit nothing.\n * @param visit Called with each class in the chain; a defined return value stops the walk.\n * @returns The first defined result from `visit`, or `undefined` if none was produced.\n */\nexport function walkClassChain<T>(cls: AnyClass | null, visit: (ancestor: AnyClass) => T | undefined): T | undefined {\n let current = cls;\n while (current !== null) {\n const result = visit(current);\n if (result !== undefined) return result;\n current = getParentClass(current);\n }\n return undefined;\n}\n"]}
|
package/dist/collection.d.ts
CHANGED
|
@@ -1,58 +1,30 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*/
|
|
4
|
-
/**
|
|
5
|
-
* Returns a shallow copy of `record` with the given `keys` removed.
|
|
6
|
-
*
|
|
7
|
-
* Keys absent from `record` are ignored, and `record` is not mutated. The
|
|
8
|
-
* result is typed as the input shape because callers treat the excluded keys
|
|
9
|
-
* as runtime-only concerns absent from the static type.
|
|
2
|
+
* Returns the items with duplicates removed, keeping the first item for each distinct key.
|
|
10
3
|
*
|
|
11
|
-
* @
|
|
12
|
-
* @param
|
|
13
|
-
* @param keys - The keys to exclude from the copy.
|
|
14
|
-
* @returns A new object holding every own enumerable key of `record` except
|
|
15
|
-
* those listed in `keys`.
|
|
4
|
+
* @param items The items to deduplicate.
|
|
5
|
+
* @param key Computes the identity string used to detect duplicates.
|
|
16
6
|
*/
|
|
17
|
-
export declare const
|
|
7
|
+
export declare const uniqBy: <T>(items: T[], key: (item: T) => string) => T[];
|
|
8
|
+
export declare const isSameArray: <T>(a: T[], b: T[]) => boolean;
|
|
18
9
|
/**
|
|
19
|
-
*
|
|
10
|
+
* Returns a new array of the given strings sorted with locale-aware comparison.
|
|
20
11
|
*
|
|
21
|
-
*
|
|
22
|
-
* being `null` or `undefined`), or when they have equal length and every
|
|
23
|
-
* element is strictly equal (`===`) at the same index. A `null`/`undefined`
|
|
24
|
-
* argument is equal only to another `null`/`undefined` argument.
|
|
25
|
-
*
|
|
26
|
-
* @typeParam T - The primitive element type.
|
|
27
|
-
* @param a - The first array, or `null`/`undefined`.
|
|
28
|
-
* @param b - The second array, or `null`/`undefined`.
|
|
29
|
-
* @returns Whether the two arrays are shallowly equal.
|
|
12
|
+
* @param values The strings to sort.
|
|
30
13
|
*/
|
|
31
|
-
export declare const
|
|
14
|
+
export declare const sortStrings: (values: Iterable<string>) => string[];
|
|
32
15
|
/**
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* Returns `true` when both arrays have equal length and, at every index, the
|
|
36
|
-
* two records expose the same set of keys with strictly equal (`===`) values.
|
|
37
|
-
* Values are compared one level deep only; nested objects are compared by
|
|
38
|
-
* reference.
|
|
16
|
+
* Returns a new array of the given items sorted by a locale-aware comparison of their keys.
|
|
39
17
|
*
|
|
40
|
-
* @
|
|
41
|
-
* @param
|
|
42
|
-
* @param b - The second array of records.
|
|
43
|
-
* @returns Whether the two arrays are element-wise shallowly equal.
|
|
18
|
+
* @param items The items to sort.
|
|
19
|
+
* @param key Computes the string to sort each item by.
|
|
44
20
|
*/
|
|
45
|
-
export declare const
|
|
21
|
+
export declare const sortStringsBy: <T>(items: Iterable<T>, key: (item: T) => string) => T[];
|
|
46
22
|
/**
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
* A TypeScript numeric enum's runtime object carries both name-to-value and
|
|
50
|
-
* value-to-name entries; this keeps only the name-to-value direction and
|
|
51
|
-
* inverts it, yielding a `Map` from each numeric value to the name that
|
|
52
|
-
* declared it.
|
|
23
|
+
* Determines whether two records have the same keys and strictly equal values.
|
|
53
24
|
*
|
|
54
|
-
* @param
|
|
55
|
-
* @
|
|
25
|
+
* @param a The first record, or `undefined`.
|
|
26
|
+
* @param b The second record, or `undefined`.
|
|
27
|
+
* @returns `true` when both are the same reference, or both are defined with identical own keys and values.
|
|
56
28
|
*/
|
|
57
|
-
export declare const
|
|
29
|
+
export declare const isShallowEqual: <T extends Record<string, unknown>>(a?: T, b?: T) => boolean;
|
|
58
30
|
//# sourceMappingURL=collection.d.ts.map
|
package/dist/collection.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collection.d.ts","sourceRoot":"","sources":["../src/collection.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"collection.d.ts","sourceRoot":"","sources":["../src/collection.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,eAAO,MAAM,MAAM,GAAI,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,KAAG,CAAC,EAUjE,CAAC;AAEF,eAAO,MAAM,WAAW,GAAI,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,EAAE,KAAG,OAM/C,CAAC;AAIF;;;;GAIG;AACH,eAAO,MAAM,WAAW,WAAY,QAAQ,CAAC,MAAM,CAAC,KAAG,MAAM,EAAsC,CAAC;AAEpG;;;;;GAKG;AACH,eAAO,MAAM,aAAa,GAAI,CAAC,SAAS,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,KAAG,CAAC,EACpB,CAAC;AAE9D;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,GAAI,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,KAAG,OAahF,CAAC"}
|
package/dist/collection.js
CHANGED
|
@@ -1,98 +1,64 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*/
|
|
4
|
-
/**
|
|
5
|
-
* Returns a shallow copy of `record` with the given `keys` removed.
|
|
2
|
+
* Returns the items with duplicates removed, keeping the first item for each distinct key.
|
|
6
3
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* as runtime-only concerns absent from the static type.
|
|
10
|
-
*
|
|
11
|
-
* @typeParam T - The record shape.
|
|
12
|
-
* @param record - The source object.
|
|
13
|
-
* @param keys - The keys to exclude from the copy.
|
|
14
|
-
* @returns A new object holding every own enumerable key of `record` except
|
|
15
|
-
* those listed in `keys`.
|
|
4
|
+
* @param items The items to deduplicate.
|
|
5
|
+
* @param key Computes the identity string used to detect duplicates.
|
|
16
6
|
*/
|
|
17
|
-
export const
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
7
|
+
export const uniqBy = (items, key) => {
|
|
8
|
+
const seen = new Set();
|
|
9
|
+
const result = [];
|
|
10
|
+
for (const item of items) {
|
|
11
|
+
const identity = key(item);
|
|
12
|
+
if (seen.has(identity))
|
|
13
|
+
continue;
|
|
14
|
+
seen.add(identity);
|
|
15
|
+
result.push(item);
|
|
23
16
|
}
|
|
24
17
|
return result;
|
|
25
18
|
};
|
|
26
|
-
|
|
27
|
-
* Compares two arrays of primitives for element-wise strict equality.
|
|
28
|
-
*
|
|
29
|
-
* Returns `true` when both arguments are the same reference (including both
|
|
30
|
-
* being `null` or `undefined`), or when they have equal length and every
|
|
31
|
-
* element is strictly equal (`===`) at the same index. A `null`/`undefined`
|
|
32
|
-
* argument is equal only to another `null`/`undefined` argument.
|
|
33
|
-
*
|
|
34
|
-
* @typeParam T - The primitive element type.
|
|
35
|
-
* @param a - The first array, or `null`/`undefined`.
|
|
36
|
-
* @param b - The second array, or `null`/`undefined`.
|
|
37
|
-
* @returns Whether the two arrays are shallowly equal.
|
|
38
|
-
*/
|
|
39
|
-
export const isShallowEqual = (a, b) => {
|
|
40
|
-
if (a === b)
|
|
41
|
-
return true;
|
|
42
|
-
if (!a || !b)
|
|
43
|
-
return false;
|
|
19
|
+
export const isSameArray = (a, b) => {
|
|
44
20
|
if (a.length !== b.length)
|
|
45
21
|
return false;
|
|
46
|
-
for (let
|
|
47
|
-
if (a[
|
|
22
|
+
for (let index = 0; index < a.length; index++) {
|
|
23
|
+
if (a[index] !== b[index])
|
|
48
24
|
return false;
|
|
49
25
|
}
|
|
50
26
|
return true;
|
|
51
27
|
};
|
|
28
|
+
const compareStrings = (a, b) => a.localeCompare(b);
|
|
29
|
+
/**
|
|
30
|
+
* Returns a new array of the given strings sorted with locale-aware comparison.
|
|
31
|
+
*
|
|
32
|
+
* @param values The strings to sort.
|
|
33
|
+
*/
|
|
34
|
+
export const sortStrings = (values) => [...values].sort(compareStrings);
|
|
52
35
|
/**
|
|
53
|
-
*
|
|
36
|
+
* Returns a new array of the given items sorted by a locale-aware comparison of their keys.
|
|
54
37
|
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
|
|
58
|
-
|
|
38
|
+
* @param items The items to sort.
|
|
39
|
+
* @param key Computes the string to sort each item by.
|
|
40
|
+
*/
|
|
41
|
+
export const sortStringsBy = (items, key) => [...items].sort((a, b) => compareStrings(key(a), key(b)));
|
|
42
|
+
/**
|
|
43
|
+
* Determines whether two records have the same keys and strictly equal values.
|
|
59
44
|
*
|
|
60
|
-
* @
|
|
61
|
-
* @param
|
|
62
|
-
* @
|
|
63
|
-
* @returns Whether the two arrays are element-wise shallowly equal.
|
|
45
|
+
* @param a The first record, or `undefined`.
|
|
46
|
+
* @param b The second record, or `undefined`.
|
|
47
|
+
* @returns `true` when both are the same reference, or both are defined with identical own keys and values.
|
|
64
48
|
*/
|
|
65
|
-
export const
|
|
66
|
-
if (a
|
|
49
|
+
export const isShallowEqual = (a, b) => {
|
|
50
|
+
if (a === b)
|
|
51
|
+
return true;
|
|
52
|
+
if (!a || !b)
|
|
67
53
|
return false;
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
const keysB = Object.keys(itemB);
|
|
75
|
-
if (keysA.length !== keysB.length)
|
|
54
|
+
const keysA = Object.keys(a);
|
|
55
|
+
const keysB = Object.keys(b);
|
|
56
|
+
if (keysA.length !== keysB.length)
|
|
57
|
+
return false;
|
|
58
|
+
for (const key of keysA) {
|
|
59
|
+
if (a[key] !== b[key])
|
|
76
60
|
return false;
|
|
77
|
-
for (const key of keysA) {
|
|
78
|
-
if (itemA[key] !== itemB[key])
|
|
79
|
-
return false;
|
|
80
|
-
}
|
|
81
61
|
}
|
|
82
62
|
return true;
|
|
83
63
|
};
|
|
84
|
-
/**
|
|
85
|
-
* Builds a reverse lookup from a numeric enum's values to their member names.
|
|
86
|
-
*
|
|
87
|
-
* A TypeScript numeric enum's runtime object carries both name-to-value and
|
|
88
|
-
* value-to-name entries; this keeps only the name-to-value direction and
|
|
89
|
-
* inverts it, yielding a `Map` from each numeric value to the name that
|
|
90
|
-
* declared it.
|
|
91
|
-
*
|
|
92
|
-
* @param enumObject - A numeric enum's runtime object.
|
|
93
|
-
* @returns A map from each numeric enum value to its declared member name.
|
|
94
|
-
*/
|
|
95
|
-
export const reverseNumericEnum = (enumObject) => new Map(Object.entries(enumObject)
|
|
96
|
-
.filter((entry) => typeof entry[1] === "number")
|
|
97
|
-
.map(([name, value]) => [value, name]));
|
|
98
64
|
//# sourceMappingURL=collection.js.map
|
package/dist/collection.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collection.js","sourceRoot":"","sources":["../src/collection.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"collection.js","sourceRoot":"","sources":["../src/collection.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,CAAI,KAAU,EAAE,GAAwB,EAAO,EAAE;IACnE,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,MAAM,GAAQ,EAAE,CAAC;IACvB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACvB,MAAM,QAAQ,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC;QAC3B,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC;YAAE,SAAS;QACjC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACnB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACtB,CAAC;IACD,OAAO,MAAM,CAAC;AAClB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAG,CAAI,CAAM,EAAE,CAAM,EAAW,EAAE;IACtD,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IACxC,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;QAC5C,IAAI,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC;YAAE,OAAO,KAAK,CAAC;IAC5C,CAAC;IACD,OAAO,IAAI,CAAC;AAChB,CAAC,CAAC;AAEF,MAAM,cAAc,GAAG,CAAC,CAAS,EAAE,CAAS,EAAU,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;AAE5E;;;;GAIG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,MAAwB,EAAY,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;AAEpG;;;;;GAKG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAI,KAAkB,EAAE,GAAwB,EAAO,EAAE,CAClF,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAE9D;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAoC,CAAK,EAAE,CAAK,EAAW,EAAE;IACvF,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACzB,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IAE3B,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC7B,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC7B,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAEhD,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC;IACxC,CAAC;IAED,OAAO,IAAI,CAAC;AAChB,CAAC,CAAC","sourcesContent":["/**\n * Returns the items with duplicates removed, keeping the first item for each distinct key.\n *\n * @param items The items to deduplicate.\n * @param key Computes the identity string used to detect duplicates.\n */\nexport const uniqBy = <T>(items: T[], key: (item: T) => string): T[] => {\n const seen = new Set<string>();\n const result: T[] = [];\n for (const item of items) {\n const identity = key(item);\n if (seen.has(identity)) continue;\n seen.add(identity);\n result.push(item);\n }\n return result;\n};\n\nexport const isSameArray = <T>(a: T[], b: T[]): boolean => {\n if (a.length !== b.length) return false;\n for (let index = 0; index < a.length; index++) {\n if (a[index] !== b[index]) return false;\n }\n return true;\n};\n\nconst compareStrings = (a: string, b: string): number => a.localeCompare(b);\n\n/**\n * Returns a new array of the given strings sorted with locale-aware comparison.\n *\n * @param values The strings to sort.\n */\nexport const sortStrings = (values: Iterable<string>): string[] => [...values].sort(compareStrings);\n\n/**\n * Returns a new array of the given items sorted by a locale-aware comparison of their keys.\n *\n * @param items The items to sort.\n * @param key Computes the string to sort each item by.\n */\nexport const sortStringsBy = <T>(items: Iterable<T>, key: (item: T) => string): T[] =>\n [...items].sort((a, b) => compareStrings(key(a), key(b)));\n\n/**\n * Determines whether two records have the same keys and strictly equal values.\n *\n * @param a The first record, or `undefined`.\n * @param b The second record, or `undefined`.\n * @returns `true` when both are the same reference, or both are defined with identical own keys and values.\n */\nexport const isShallowEqual = <T extends Record<string, unknown>>(a?: T, b?: T): boolean => {\n if (a === b) return true;\n if (!a || !b) return false;\n\n const keysA = Object.keys(a);\n const keysB = Object.keys(b);\n if (keysA.length !== keysB.length) return false;\n\n for (const key of keysA) {\n if (a[key] !== b[key]) return false;\n }\n\n return true;\n};\n"]}
|
package/dist/error.d.ts
CHANGED
|
@@ -1,13 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Extracts a human-readable message from an unknown thrown value, falling back to its string form.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* delegates to `String(error)`. Use at boundaries where exceptions are
|
|
6
|
-
* surfaced to logs, IPC frames, or user-facing output and the type cannot
|
|
7
|
-
* be narrowed otherwise.
|
|
8
|
-
*
|
|
9
|
-
* @param error - The caught value of unknown shape.
|
|
10
|
-
* @returns A string describing the error.
|
|
4
|
+
* @param error The caught value to describe.
|
|
11
5
|
*/
|
|
12
6
|
export declare const errorMessage: (error: unknown) => string;
|
|
7
|
+
/**
|
|
8
|
+
* Coerces an unknown thrown value into an `Error`, reusing it if it already is one and otherwise
|
|
9
|
+
* wrapping its message while copying any error-like own properties.
|
|
10
|
+
*
|
|
11
|
+
* @param error The caught value to normalize.
|
|
12
|
+
*/
|
|
13
|
+
export declare const normalizeError: (error: unknown) => Error;
|
|
14
|
+
/**
|
|
15
|
+
* Combines the `stderr` and `stdout` fields of a failed child-process error into a single trimmed string.
|
|
16
|
+
*
|
|
17
|
+
* @param error The child-process error to read output from.
|
|
18
|
+
* @returns The joined output, or `undefined` when neither stream carried any text.
|
|
19
|
+
*/
|
|
20
|
+
export declare const formatChildProcessError: (error: unknown) => string | undefined;
|
|
13
21
|
//# sourceMappingURL=error.d.ts.map
|
package/dist/error.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"AAKA;;;;GAIG;AACH,eAAO,MAAM,YAAY,UAAW,OAAO,KAAG,MACgC,CAAC;AAE/E;;;;;GAKG;AACH,eAAO,MAAM,cAAc,UAAW,OAAO,KAAG,KAG/C,CAAC;AAQF;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,UAAW,OAAO,KAAG,MAAM,GAAG,SAKjE,CAAC"}
|
package/dist/error.js
CHANGED
|
@@ -1,13 +1,40 @@
|
|
|
1
|
+
const isObject = (value) => typeof value === "object" && value !== null;
|
|
2
|
+
const isErrorLike = (value) => isObject(value) && "message" in value && typeof value.message === "string";
|
|
1
3
|
/**
|
|
2
|
-
*
|
|
4
|
+
* Extracts a human-readable message from an unknown thrown value, falling back to its string form.
|
|
3
5
|
*
|
|
4
|
-
*
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
* @param error The caught value to describe.
|
|
7
|
+
*/
|
|
8
|
+
export const errorMessage = (error) => Error.isError(error) || isErrorLike(error) ? error.message : String(error);
|
|
9
|
+
/**
|
|
10
|
+
* Coerces an unknown thrown value into an `Error`, reusing it if it already is one and otherwise
|
|
11
|
+
* wrapping its message while copying any error-like own properties.
|
|
12
|
+
*
|
|
13
|
+
* @param error The caught value to normalize.
|
|
14
|
+
*/
|
|
15
|
+
export const normalizeError = (error) => {
|
|
16
|
+
if (Error.isError(error))
|
|
17
|
+
return error;
|
|
18
|
+
return Object.assign(new Error(errorMessage(error)), isErrorLike(error) ? error : {});
|
|
19
|
+
};
|
|
20
|
+
const readStream = (value) => {
|
|
21
|
+
if (typeof value === "string")
|
|
22
|
+
return value;
|
|
23
|
+
if (value instanceof Uint8Array || Buffer.isBuffer(value))
|
|
24
|
+
return value.toString();
|
|
25
|
+
return "";
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Combines the `stderr` and `stdout` fields of a failed child-process error into a single trimmed string.
|
|
8
29
|
*
|
|
9
|
-
* @param error -
|
|
10
|
-
* @returns
|
|
30
|
+
* @param error The child-process error to read output from.
|
|
31
|
+
* @returns The joined output, or `undefined` when neither stream carried any text.
|
|
11
32
|
*/
|
|
12
|
-
export const
|
|
33
|
+
export const formatChildProcessError = (error) => {
|
|
34
|
+
if (!isObject(error))
|
|
35
|
+
return undefined;
|
|
36
|
+
const { stderr, stdout } = error;
|
|
37
|
+
const details = [readStream(stderr), readStream(stdout)].filter(Boolean).join("\n").trim();
|
|
38
|
+
return details.length > 0 ? details : undefined;
|
|
39
|
+
};
|
|
13
40
|
//# sourceMappingURL=error.js.map
|
package/dist/error.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error.js","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"error.js","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"AAAA,MAAM,QAAQ,GAAG,CAAC,KAAc,EAAoC,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC;AAEnH,MAAM,WAAW,GAAG,CAAC,KAAc,EAAgC,EAAE,CACjE,QAAQ,CAAC,KAAK,CAAC,IAAI,SAAS,IAAI,KAAK,IAAI,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ,CAAC;AAE/E;;;;GAIG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,KAAc,EAAU,EAAE,CACnD,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAE/E;;;;;GAKG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,KAAc,EAAS,EAAE;IACpD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACvC,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AAC1F,CAAC,CAAC;AAEF,MAAM,UAAU,GAAG,CAAC,KAAc,EAAU,EAAE;IAC1C,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5C,IAAI,KAAK,YAAY,UAAU,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,QAAQ,EAAE,CAAC;IACnF,OAAO,EAAE,CAAC;AACd,CAAC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,KAAc,EAAsB,EAAE;IAC1E,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IACvC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;IACjC,MAAM,OAAO,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;IAC3F,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;AACpD,CAAC,CAAC","sourcesContent":["const isObject = (value: unknown): value is Record<string, unknown> => typeof value === \"object\" && value !== null;\n\nconst isErrorLike = (value: unknown): value is { message: string } =>\n isObject(value) && \"message\" in value && typeof value.message === \"string\";\n\n/**\n * Extracts a human-readable message from an unknown thrown value, falling back to its string form.\n *\n * @param error The caught value to describe.\n */\nexport const errorMessage = (error: unknown): string =>\n Error.isError(error) || isErrorLike(error) ? error.message : String(error);\n\n/**\n * Coerces an unknown thrown value into an `Error`, reusing it if it already is one and otherwise\n * wrapping its message while copying any error-like own properties.\n *\n * @param error The caught value to normalize.\n */\nexport const normalizeError = (error: unknown): Error => {\n if (Error.isError(error)) return error;\n return Object.assign(new Error(errorMessage(error)), isErrorLike(error) ? error : {});\n};\n\nconst readStream = (value: unknown): string => {\n if (typeof value === \"string\") return value;\n if (value instanceof Uint8Array || Buffer.isBuffer(value)) return value.toString();\n return \"\";\n};\n\n/**\n * Combines the `stderr` and `stdout` fields of a failed child-process error into a single trimmed string.\n *\n * @param error The child-process error to read output from.\n * @returns The joined output, or `undefined` when neither stream carried any text.\n */\nexport const formatChildProcessError = (error: unknown): string | undefined => {\n if (!isObject(error)) return undefined;\n const { stderr, stdout } = error;\n const details = [readStream(stderr), readStream(stdout)].filter(Boolean).join(\"\\n\").trim();\n return details.length > 0 ? details : undefined;\n};\n"]}
|