@tochii/errors 0.0.0-stage → 0.1.6

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/CHANGELOG.md ADDED
@@ -0,0 +1,49 @@
1
+ # Changelog
2
+
3
+ ## 0.1.6 (October 2026)
4
+
5
+ <!-- release:start -->
6
+
7
+ ### CI
8
+ - Updated workflows ([#b1a1b89](https://github.com/tochiResources/errors/commit/b1a1b89) by [T0chi](https://github.com/T0chi))
9
+
10
+ <!-- release:end -->
11
+
12
+
13
+ ## 0.1.5 (October 2026)
14
+
15
+ ### CI
16
+ - Added `dev` to `ci.yml`'s push branches ([#ff15308](https://github.com/tochiResources/errors/commit/ff15308) by [T0chi](https://github.com/T0chi))
17
+
18
+ ## 0.1.4 (October 2026)
19
+
20
+ ### CI
21
+ - Updated workflows ([#b2e3380](https://github.com/tochiResources/errors/commit/b2e3380) by [T0chi](https://github.com/T0chi))
22
+
23
+ ## 0.1.3 (October 2026)
24
+
25
+ ### Chores
26
+ - Set package to public ([#a8428d3](https://github.com/tochiResources/errors/commit/a8428d3) by [T0chi](https://github.com/T0chi))
27
+
28
+ ## 0.1.2 (October 2026)
29
+
30
+ ### CI
31
+ - Updated added `dev` branch ([#4b928a6](https://github.com/tochiResources/errors/commit/4b928a6) by [T0chi](https://github.com/T0chi))
32
+ - Updated changelog branch ([#59a6f69](https://github.com/tochiResources/errors/commit/59a6f69) by [T0chi](https://github.com/T0chi))
33
+ - Updated packaging flow ([#b4f3dbb](https://github.com/tochiResources/errors/commit/b4f3dbb) by [T0chi](https://github.com/T0chi))
34
+ ### Chores
35
+ - Added `CHANGELOG.md` ([#1b53d03](https://github.com/tochiResources/errors/commit/1b53d03) by [T0chi](https://github.com/T0chi))
36
+ - Code cleanup ([#e914f15](https://github.com/tochiResources/errors/commit/e914f15) by [T0chi](https://github.com/T0chi))
37
+ - Update package.json description ([#edf61d0](https://github.com/tochiResources/errors/commit/edf61d0) by [T0chi](https://github.com/T0chi))
38
+ #### Errors
39
+ - Initialize repository ([#e39bad5](https://github.com/tochiResources/errors/commit/e39bad5) by [T0chi](https://github.com/T0chi))
40
+
41
+ ## 0.1.1 (October 2026)
42
+
43
+ ### CI
44
+ - Updated packaging flow ([#b4f3dbb](https://github.com/tochiResources/errors/commit/b4f3dbb) by T0chi)
45
+ ### Chores
46
+ - Code cleanup ([#e914f15](https://github.com/tochiResources/errors/commit/e914f15) by T0chi)
47
+ - Update package.json description ([#edf61d0](https://github.com/tochiResources/errors/commit/edf61d0) by T0chi)
48
+ #### Errors
49
+ - Initialize repository ([#e39bad5](https://github.com/tochiResources/errors/commit/e39bad5) by T0chi)
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 tochiResources
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,52 @@
1
- # Temporary Holding Version
1
+ # @tochii/errors
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ [![tests](https://img.shields.io/github/actions/workflow/status/tochiResources/errors/ci.yml?label=tests&logo=github)](https://github.com/tochiResources/errors/actions/workflows/ci.yml)
4
+ [![npm version](https://img.shields.io/npm/v/@tochii/errors.svg?color=cb3837&label=npm)](https://www.npmjs.com/package/@tochii/errors)
5
+
6
+ Shared typed errors and stable error codes used in official tochiResources proejcts.
7
+
8
+ - **Stable codes**: the string value is part of the contract; never reuse or rename one. Both TS and C# switch on it.
9
+ - **Typed classes**: `instanceof ConfigError`, `instanceof IpcError`, per domain, all extending `TochiResError`.
10
+ - **Serializable**: `serializeError` / `deserializeError` move errors across JSON-RPC unchanged (message, code, context, cause chain).
11
+ - **Context**: every error can carry structured `context` for logging/telemetry.
12
+
13
+ ## Projects using @tochii/errors
14
+
15
+ - [AeToOsb](https://github.com/tochiResources/AeToOsb)
16
+ - [AeBrew](https://github.com/tochiResources/AeBrew)
17
+ - [osu! Storyboarding toolkit](https://github.com/tochiResources/osb-toolkit)
18
+ - [tochiResources Adobe CEP](https://github.com/tochiResources/cep)
19
+
20
+ ## Usage
21
+
22
+ ```ts
23
+ import { ConfigError, ErrorCode, isTochiResError, serializeError } from '@tochii/errors';
24
+
25
+ try {
26
+ throw new ConfigError('app.name is required', {
27
+ code: ErrorCode.ConfigMissing,
28
+ context: { field: 'name' },
29
+ });
30
+ } catch (error) {
31
+ if (isTochiResError(error)) {
32
+ console.error(error.code, error.message, error.context);
33
+ socket.send(JSON.stringify(serializeError(error)));
34
+ }
35
+ }
36
+ ```
37
+
38
+ ## Development
39
+
40
+ - **node 22.5+**, **yarn 4**, **vitest 5**, **tsdown**
41
+
42
+ ```sh
43
+ yarn install
44
+ yarn build
45
+ yarn lint
46
+ yarn typecheck
47
+ yarn test
48
+ ```
49
+
50
+ ## License
51
+
52
+ MIT. See [LICENSE](/LICENSE).
@@ -0,0 +1,275 @@
1
+ using System;
2
+ using System.Collections.Generic;
3
+
4
+ namespace TochiRes.Errors;
5
+
6
+ /// <summary>
7
+ /// Stable error codes shared with the TypeScript side (<c>@tochii/errors</c>).
8
+ /// Keep in sync with <c>src/codes.ts</c>. A code is part of the
9
+ /// public contract: never rename or reuse one — add a new code instead.
10
+ /// </summary>
11
+ public static class ErrorCodes
12
+ {
13
+ // General
14
+ public const string Unknown = "TOCHIRES_UNKNOWN";
15
+ public const string Internal = "TOCHIRES_INTERNAL";
16
+
17
+ // Config
18
+ public const string ConfigInvalid = "TOCHIRES_CONFIG_INVALID";
19
+ public const string ConfigMissing = "TOCHIRES_CONFIG_MISSING";
20
+
21
+ // Validation
22
+ public const string ValidationFailed = "TOCHIRES_VALIDATION_FAILED";
23
+
24
+ // API / HTTP boundary
25
+ public const string ApiBadRequest = "TOCHIRES_API_BAD_REQUEST";
26
+ public const string ApiUnauthorized = "TOCHIRES_API_UNAUTHORIZED";
27
+ public const string ApiForbidden = "TOCHIRES_API_FORBIDDEN";
28
+ public const string ApiNotFound = "TOCHIRES_API_NOT_FOUND";
29
+ public const string ApiConflict = "TOCHIRES_API_CONFLICT";
30
+ public const string ApiUnprocessable = "TOCHIRES_API_UNPROCESSABLE";
31
+ public const string ApiTooManyRequests = "TOCHIRES_API_TOO_MANY_REQUESTS";
32
+ public const string ApiTimeout = "TOCHIRES_API_TIMEOUT";
33
+ public const string ApiUnavailable = "TOCHIRES_API_UNAVAILABLE";
34
+
35
+ // IPC
36
+ public const string IpcTransport = "TOCHIRES_IPC_TRANSPORT";
37
+ public const string IpcProtocol = "TOCHIRES_IPC_PROTOCOL";
38
+ public const string IpcTimeout = "TOCHIRES_IPC_TIMEOUT";
39
+ public const string IpcAuth = "TOCHIRES_IPC_AUTH";
40
+ public const string IpcDisconnected = "TOCHIRES_IPC_DISCONNECTED";
41
+ public const string IpcBackpressure = "TOCHIRES_IPC_BACKPRESSURE";
42
+
43
+ // Codegen
44
+ public const string CodegenUnsupported = "TOCHIRES_CODEGEN_UNSUPPORTED";
45
+ public const string CodegenEmit = "TOCHIRES_CODEGEN_EMIT";
46
+ public const string CodegenRoundtrip = "TOCHIRES_CODEGEN_ROUNDTRIP";
47
+
48
+ // CSS
49
+ public const string CssParse = "TOCHIRES_CSS_PARSE";
50
+ public const string CssUnsupportedProperty = "TOCHIRES_CSS_UNSUPPORTED_PROPERTY";
51
+ public const string CssUnsupportedSelector = "TOCHIRES_CSS_UNSUPPORTED_SELECTOR";
52
+
53
+ // Native
54
+ public const string NativeModuleNotFound = "TOCHIRES_NATIVE_MODULE_NOT_FOUND";
55
+ public const string NativeMethodNotFound = "TOCHIRES_NATIVE_METHOD_NOT_FOUND";
56
+ public const string NativeCallFailed = "TOCHIRES_NATIVE_CALL_FAILED";
57
+
58
+ // Build
59
+ public const string BuildFailed = "TOCHIRES_BUILD_FAILED";
60
+ public const string BuildToolMissing = "TOCHIRES_BUILD_TOOL_MISSING";
61
+
62
+ // Package
63
+ public const string PackageFailed = "TOCHIRES_PACKAGE_FAILED";
64
+ public const string PackageSigning = "TOCHIRES_PACKAGE_SIGNING";
65
+
66
+ // Settings
67
+ public const string SettingsParse = "TOCHIRES_SETTINGS_PARSE";
68
+ public const string SettingsInvalid = "TOCHIRES_SETTINGS_INVALID";
69
+
70
+ // Path
71
+ public const string PathInvalid = "TOCHIRES_PATH_INVALID";
72
+ public const string PathAbsolute = "TOCHIRES_PATH_ABSOLUTE";
73
+
74
+ /// <summary>Every known code, for validation and diagnostics.</summary>
75
+ public static readonly IReadOnlyList<string> All = new[]
76
+ {
77
+ Unknown, Internal,
78
+ ConfigInvalid, ConfigMissing,
79
+ ValidationFailed,
80
+ ApiBadRequest, ApiUnauthorized, ApiForbidden, ApiNotFound, ApiConflict,
81
+ ApiUnprocessable, ApiTooManyRequests, ApiTimeout, ApiUnavailable,
82
+ IpcTransport, IpcProtocol, IpcTimeout, IpcAuth, IpcDisconnected, IpcBackpressure,
83
+ CodegenUnsupported, CodegenEmit, CodegenRoundtrip,
84
+ CssParse, CssUnsupportedProperty, CssUnsupportedSelector,
85
+ NativeModuleNotFound, NativeMethodNotFound, NativeCallFailed,
86
+ BuildFailed, BuildToolMissing,
87
+ PackageFailed, PackageSigning,
88
+ SettingsParse, SettingsInvalid,
89
+ PathInvalid, PathAbsolute,
90
+ };
91
+
92
+ private static readonly IReadOnlyDictionary<string, string> CategoryByCode =
93
+ new Dictionary<string, string>(StringComparer.Ordinal)
94
+ {
95
+ [Unknown] = "general",
96
+ [Internal] = "general",
97
+ [ConfigInvalid] = "config",
98
+ [ConfigMissing] = "config",
99
+ [ValidationFailed] = "validation",
100
+ [ApiBadRequest] = "api",
101
+ [ApiUnauthorized] = "api",
102
+ [ApiForbidden] = "api",
103
+ [ApiNotFound] = "api",
104
+ [ApiConflict] = "api",
105
+ [ApiUnprocessable] = "api",
106
+ [ApiTooManyRequests] = "api",
107
+ [ApiTimeout] = "api",
108
+ [ApiUnavailable] = "api",
109
+ [IpcTransport] = "ipc",
110
+ [IpcProtocol] = "ipc",
111
+ [IpcTimeout] = "ipc",
112
+ [IpcAuth] = "ipc",
113
+ [IpcDisconnected] = "ipc",
114
+ [IpcBackpressure] = "ipc",
115
+ [CodegenUnsupported] = "codegen",
116
+ [CodegenEmit] = "codegen",
117
+ [CodegenRoundtrip] = "codegen",
118
+ [CssParse] = "css",
119
+ [CssUnsupportedProperty] = "css",
120
+ [CssUnsupportedSelector] = "css",
121
+ [NativeModuleNotFound] = "native",
122
+ [NativeMethodNotFound] = "native",
123
+ [NativeCallFailed] = "native",
124
+ [BuildFailed] = "build",
125
+ [BuildToolMissing] = "build",
126
+ [PackageFailed] = "package",
127
+ [PackageSigning] = "package",
128
+ [SettingsParse] = "settings",
129
+ [SettingsInvalid] = "settings",
130
+ [PathInvalid] = "path",
131
+ [PathAbsolute] = "path",
132
+ };
133
+
134
+ /// <summary>Whether <paramref name="code"/> is one of the known stable codes.</summary>
135
+ public static bool IsKnown(string? code) => code is not null && CategoryByCode.ContainsKey(code);
136
+
137
+ /// <summary>The category a code belongs to, or <c>"general"</c> when unknown.</summary>
138
+ public static string CategoryOf(string? code) =>
139
+ code is not null && CategoryByCode.TryGetValue(code, out var category) ? category : "general";
140
+ }
141
+
142
+ /// <summary>
143
+ /// Base exception for every error defined by this package.
144
+ /// Mirrors <c>TochiResError</c> from the TypeScript implementation.
145
+ /// </summary>
146
+ public class TochiResException : Exception
147
+ {
148
+ /// <summary>Stable error code — part of the public contract.</summary>
149
+ public string Code { get; }
150
+
151
+ /// <summary>Coarse category derived from <see cref="Code"/>.</summary>
152
+ public string Category { get; }
153
+
154
+ /// <summary>Structured, JSON-safe context for logging and telemetry.</summary>
155
+ public IReadOnlyDictionary<string, object?>? Context { get; }
156
+
157
+ public TochiResException(
158
+ string code,
159
+ string message,
160
+ Exception? innerException = null,
161
+ IReadOnlyDictionary<string, object?>? context = null)
162
+ : base(message, innerException)
163
+ {
164
+ Code = code;
165
+ Category = ErrorCodes.CategoryOf(code);
166
+ Context = context;
167
+ }
168
+ }
169
+
170
+ /// <summary>Configuration is missing or failed validation.</summary>
171
+ public sealed class ConfigException : TochiResException
172
+ {
173
+ public ConfigException(string message, Exception? inner = null, IReadOnlyDictionary<string, object?>? context = null)
174
+ : base(ErrorCodes.ConfigInvalid, message, inner, context) { }
175
+
176
+ public ConfigException(string code, string message, Exception? inner = null, IReadOnlyDictionary<string, object?>? context = null)
177
+ : base(code, message, inner, context) { }
178
+ }
179
+
180
+ /// <summary>A payload, schema or argument failed validation.</summary>
181
+ public sealed class ValidationException : TochiResException
182
+ {
183
+ public ValidationException(string message, Exception? inner = null, IReadOnlyDictionary<string, object?>? context = null)
184
+ : base(ErrorCodes.ValidationFailed, message, inner, context) { }
185
+ }
186
+
187
+ /// <summary>An API/HTTP boundary failure (bad request, auth, not found, conflict, …).</summary>
188
+ public sealed class ApiException : TochiResException
189
+ {
190
+ public ApiException(string message, Exception? inner = null, IReadOnlyDictionary<string, object?>? context = null)
191
+ : base(ErrorCodes.ApiBadRequest, message, inner, context) { }
192
+
193
+ public ApiException(string code, string message, Exception? inner = null, IReadOnlyDictionary<string, object?>? context = null)
194
+ : base(code, message, inner, context) { }
195
+ }
196
+
197
+ /// <summary>An IPC transport, protocol, authentication or timeout failure.</summary>
198
+ public sealed class IpcException : TochiResException
199
+ {
200
+ public IpcException(string message, Exception? inner = null, IReadOnlyDictionary<string, object?>? context = null)
201
+ : base(ErrorCodes.IpcTransport, message, inner, context) { }
202
+
203
+ public IpcException(string code, string message, Exception? inner = null, IReadOnlyDictionary<string, object?>? context = null)
204
+ : base(code, message, inner, context) { }
205
+ }
206
+
207
+ /// <summary>A TS→C# code generator failed or hit an unsupported construct.</summary>
208
+ public sealed class CodegenException : TochiResException
209
+ {
210
+ public CodegenException(string message, Exception? inner = null, IReadOnlyDictionary<string, object?>? context = null)
211
+ : base(ErrorCodes.CodegenEmit, message, inner, context) { }
212
+
213
+ public CodegenException(string code, string message, Exception? inner = null, IReadOnlyDictionary<string, object?>? context = null)
214
+ : base(code, message, inner, context) { }
215
+ }
216
+
217
+ /// <summary>CSS input is invalid or outside the supported subset.</summary>
218
+ public sealed class CssException : TochiResException
219
+ {
220
+ public CssException(string message, Exception? inner = null, IReadOnlyDictionary<string, object?>? context = null)
221
+ : base(ErrorCodes.CssParse, message, inner, context) { }
222
+
223
+ public CssException(string code, string message, Exception? inner = null, IReadOnlyDictionary<string, object?>? context = null)
224
+ : base(code, message, inner, context) { }
225
+ }
226
+
227
+ /// <summary>A native module or method was missing, or a native call failed.</summary>
228
+ public sealed class NativeException : TochiResException
229
+ {
230
+ public NativeException(string message, Exception? inner = null, IReadOnlyDictionary<string, object?>? context = null)
231
+ : base(ErrorCodes.NativeCallFailed, message, inner, context) { }
232
+
233
+ public NativeException(string code, string message, Exception? inner = null, IReadOnlyDictionary<string, object?>? context = null)
234
+ : base(code, message, inner, context) { }
235
+ }
236
+
237
+ /// <summary>A build pipeline step failed or a required tool is missing.</summary>
238
+ public sealed class BuildException : TochiResException
239
+ {
240
+ public BuildException(string message, Exception? inner = null, IReadOnlyDictionary<string, object?>? context = null)
241
+ : base(ErrorCodes.BuildFailed, message, inner, context) { }
242
+
243
+ public BuildException(string code, string message, Exception? inner = null, IReadOnlyDictionary<string, object?>? context = null)
244
+ : base(code, message, inner, context) { }
245
+ }
246
+
247
+ /// <summary>A packaging, signing or notarization step failed.</summary>
248
+ public sealed class PackageException : TochiResException
249
+ {
250
+ public PackageException(string message, Exception? inner = null, IReadOnlyDictionary<string, object?>? context = null)
251
+ : base(ErrorCodes.PackageFailed, message, inner, context) { }
252
+
253
+ public PackageException(string code, string message, Exception? inner = null, IReadOnlyDictionary<string, object?>? context = null)
254
+ : base(code, message, inner, context) { }
255
+ }
256
+
257
+ /// <summary>Settings text could not be parsed or failed validation.</summary>
258
+ public sealed class SettingsException : TochiResException
259
+ {
260
+ public SettingsException(string message, Exception? inner = null, IReadOnlyDictionary<string, object?>? context = null)
261
+ : base(ErrorCodes.SettingsInvalid, message, inner, context) { }
262
+
263
+ public SettingsException(string code, string message, Exception? inner = null, IReadOnlyDictionary<string, object?>? context = null)
264
+ : base(code, message, inner, context) { }
265
+ }
266
+
267
+ /// <summary>A path was malformed or violated the relative-path rule.</summary>
268
+ public sealed class PathException : TochiResException
269
+ {
270
+ public PathException(string message, Exception? inner = null, IReadOnlyDictionary<string, object?>? context = null)
271
+ : base(ErrorCodes.PathInvalid, message, inner, context) { }
272
+
273
+ public PathException(string code, string message, Exception? inner = null, IReadOnlyDictionary<string, object?>? context = null)
274
+ : base(code, message, inner, context) { }
275
+ }
@@ -0,0 +1,40 @@
1
+ <Project Sdk="Microsoft.NET.Sdk">
2
+ <PropertyGroup>
3
+ <TargetFrameworks>netstandard2.0;net8.0</TargetFrameworks>
4
+ <LangVersion>latest</LangVersion>
5
+ <Nullable>enable</Nullable>
6
+ <ImplicitUsings>disable</ImplicitUsings>
7
+ <GenerateDocumentationFile>true</GenerateDocumentationFile>
8
+ <NoWarn>$(NoWarn);CS1591</NoWarn>
9
+
10
+ <PackageJsonPath>$(MSBuildThisFileDirectory)../package.json</PackageJsonPath>
11
+
12
+ <PackageJsonVersion>$([System.Text.RegularExpressions.Regex]::Match($([System.IO.File]::ReadAllText('$(PackageJsonPath)')), '"version"\s*:\s*"([^"]+)"').Groups[1].Value)</PackageJsonVersion>
13
+ <PackageJsonDescription>$([System.Text.RegularExpressions.Regex]::Match($([System.IO.File]::ReadAllText('$(PackageJsonPath)')), '"description"\s*:\s*"([^"]*)"').Groups[1].Value)</PackageJsonDescription>
14
+ <PackageJsonRepositoryUrl>$([System.Text.RegularExpressions.Regex]::Match($([System.IO.File]::ReadAllText('$(PackageJsonPath)')), '"repository"\s*:\s*\{[^}]*"url"\s*:\s*"(?:git\+)?(https?://[^"]+?)(?:\.git)?"').Groups[1].Value)</PackageJsonRepositoryUrl>
15
+ <PackageJsonAuthor>$([System.Text.RegularExpressions.Regex]::Match($([System.IO.File]::ReadAllText('$(PackageJsonPath)')), '"author"\s*:\s*"([^"]*)"').Groups[1].Value)</PackageJsonAuthor>
16
+ <PackageJsonLicense>$([System.Text.RegularExpressions.Regex]::Match($([System.IO.File]::ReadAllText('$(PackageJsonPath)')), '"license"\s*:\s*"([^"]*)"').Groups[1].Value)</PackageJsonLicense>
17
+
18
+ <PackageId>TochiRes.Errors</PackageId>
19
+ <Version>$(PackageJsonVersion)</Version>
20
+ <Authors>$(PackageJsonAuthor)</Authors>
21
+ <Description>$(PackageJsonDescription)</Description>
22
+ <PackageLicenseExpression>$(PackageJsonLicense)</PackageLicenseExpression>
23
+ <RepositoryUrl>$(PackageJsonRepositoryUrl)</RepositoryUrl>
24
+ <RepositoryType>git</RepositoryType>
25
+ <PackageProjectUrl>$(PackageJsonRepositoryUrl)</PackageProjectUrl>
26
+ <PackageReadmeFile>README.md</PackageReadmeFile>
27
+ <PackageTags>errors;exceptions;error-codes</PackageTags>
28
+
29
+ <IncludeSymbols>true</IncludeSymbols>
30
+ <SymbolPackageFormat>snupkg</SymbolPackageFormat>
31
+ <PublishRepositoryUrl>true</PublishRepositoryUrl>
32
+ <EmbedUntrackedSources>true</EmbedUntrackedSources>
33
+ <ContinuousIntegrationBuild Condition="'$(CI)' == 'true'">true</ContinuousIntegrationBuild>
34
+ </PropertyGroup>
35
+
36
+ <ItemGroup>
37
+ <None Include="../README.md" Pack="true" PackagePath="\" />
38
+ <PackageReference Include="Microsoft.SourceLink.GitHub" Version="10.0.403" PrivateAssets="all" />
39
+ </ItemGroup>
40
+ </Project>
@@ -0,0 +1,97 @@
1
+ //#region src/codes.d.ts
2
+ /**
3
+ * Stable error codes shared by the TypeScript and C# implementations.
4
+ *
5
+ * A code is part of the public contract: it is persisted in logs, sent across
6
+ * the JSON-RPC boundary and switched on by consumers (including the C# mirror
7
+ * in `Errors.cs`).
8
+ * Never rename or reuse a code — add a new one and deprecate the old.
9
+ */
10
+ declare const ErrorCode: {
11
+ /** An error that could not be classified. */
12
+ readonly Unknown: "TOCHIRES_UNKNOWN";
13
+ /** An invariant inside the library was violated. */
14
+ readonly Internal: "TOCHIRES_INTERNAL";
15
+ /** A configuration object failed validation. */
16
+ readonly ConfigInvalid: "TOCHIRES_CONFIG_INVALID";
17
+ /** A required configuration field is missing. */
18
+ readonly ConfigMissing: "TOCHIRES_CONFIG_MISSING";
19
+ /** A generic validation failure (payload, schema, argument). */
20
+ readonly ValidationFailed: "TOCHIRES_VALIDATION_FAILED";
21
+ /** The request was malformed or failed validation at an API boundary. */
22
+ readonly ApiBadRequest: "TOCHIRES_API_BAD_REQUEST";
23
+ /** Authentication is required, or the session/token is invalid. */
24
+ readonly ApiUnauthorized: "TOCHIRES_API_UNAUTHORIZED";
25
+ /** The authenticated principal is not allowed to perform the action. */
26
+ readonly ApiForbidden: "TOCHIRES_API_FORBIDDEN";
27
+ /** The requested resource does not exist. */
28
+ readonly ApiNotFound: "TOCHIRES_API_NOT_FOUND";
29
+ /** The request conflicts with the current state of the resource. */
30
+ readonly ApiConflict: "TOCHIRES_API_CONFLICT";
31
+ /** The payload was well-formed but is semantically invalid. */
32
+ readonly ApiUnprocessable: "TOCHIRES_API_UNPROCESSABLE";
33
+ /** The caller exceeded an imposed rate limit. */
34
+ readonly ApiTooManyRequests: "TOCHIRES_API_TOO_MANY_REQUESTS";
35
+ /** An upstream dependency did not respond in time. */
36
+ readonly ApiTimeout: "TOCHIRES_API_TIMEOUT";
37
+ /** A downstream dependency is unavailable. */
38
+ readonly ApiUnavailable: "TOCHIRES_API_UNAVAILABLE";
39
+ /** The IPC transport could not be opened or used. */
40
+ readonly IpcTransport: "TOCHIRES_IPC_TRANSPORT";
41
+ /** A JSON-RPC envelope was malformed or violated the protocol. */
42
+ readonly IpcProtocol: "TOCHIRES_IPC_PROTOCOL";
43
+ /** A request did not receive a response in time. */
44
+ readonly IpcTimeout: "TOCHIRES_IPC_TIMEOUT";
45
+ /** Token authentication failed. */
46
+ readonly IpcAuth: "TOCHIRES_IPC_AUTH";
47
+ /** The peer disconnected before the operation completed. */
48
+ readonly IpcDisconnected: "TOCHIRES_IPC_DISCONNECTED";
49
+ /** A stream was paused because the consumer fell behind. */
50
+ readonly IpcBackpressure: "TOCHIRES_IPC_BACKPRESSURE";
51
+ /** A TypeScript construct has no C# codegen mapping. */
52
+ readonly CodegenUnsupported: "TOCHIRES_CODEGEN_UNSUPPORTED";
53
+ /** A generator failed while emitting an artifact. */
54
+ readonly CodegenEmit: "TOCHIRES_CODEGEN_EMIT";
55
+ /** Generated output did not round-trip back to its source. */
56
+ readonly CodegenRoundtrip: "TOCHIRES_CODEGEN_ROUNDTRIP";
57
+ /** CSS input could not be parsed. */
58
+ readonly CssParse: "TOCHIRES_CSS_PARSE";
59
+ /** A CSS property is outside the supported subset. */
60
+ readonly CssUnsupportedProperty: "TOCHIRES_CSS_UNSUPPORTED_PROPERTY";
61
+ /** A CSS selector is outside the supported subset. */
62
+ readonly CssUnsupportedSelector: "TOCHIRES_CSS_UNSUPPORTED_SELECTOR";
63
+ /** A native module was not registered on the C# host. */
64
+ readonly NativeModuleNotFound: "TOCHIRES_NATIVE_MODULE_NOT_FOUND";
65
+ /** A native method was not registered on a module. */
66
+ readonly NativeMethodNotFound: "TOCHIRES_NATIVE_METHOD_NOT_FOUND";
67
+ /** A native method threw or returned an error. */
68
+ readonly NativeCallFailed: "TOCHIRES_NATIVE_CALL_FAILED";
69
+ /** A build pipeline step failed. */
70
+ readonly BuildFailed: "TOCHIRES_BUILD_FAILED";
71
+ /** A required build tool (dotnet, esbuild, …) is unavailable. */
72
+ readonly BuildToolMissing: "TOCHIRES_BUILD_TOOL_MISSING";
73
+ /** A packaging step failed. */
74
+ readonly PackageFailed: "TOCHIRES_PACKAGE_FAILED";
75
+ /** Signing or notarization failed. */
76
+ readonly PackageSigning: "TOCHIRES_PACKAGE_SIGNING";
77
+ /** Settings text could not be parsed. */
78
+ readonly SettingsParse: "TOCHIRES_SETTINGS_PARSE";
79
+ /** Settings values failed validation against their spec. */
80
+ readonly SettingsInvalid: "TOCHIRES_SETTINGS_INVALID";
81
+ /** A path was malformed. */
82
+ readonly PathInvalid: "TOCHIRES_PATH_INVALID";
83
+ /** An absolute path was supplied where only relative paths are allowed. */
84
+ readonly PathAbsolute: "TOCHIRES_PATH_ABSOLUTE";
85
+ };
86
+ /** Union of every stable error code. */
87
+ type ErrorCode = (typeof ErrorCode)[keyof typeof ErrorCode];
88
+ /** Coarse grouping used for reporting, filtering and C# exception types. */
89
+ type ErrorCategory = 'general' | 'config' | 'validation' | 'api' | 'ipc' | 'codegen' | 'css' | 'native' | 'build' | 'package' | 'settings' | 'path';
90
+ /** All codes, as an array — handy for exhaustiveness checks and docs. */
91
+ declare const ERROR_CODES: ErrorCode[];
92
+ /** Whether a value is one of the known stable codes. */
93
+ declare function isErrorCode(value: unknown): value is ErrorCode;
94
+ /** The category a code belongs to, or `'general'` for unknown codes. */
95
+ declare function categoryOf(code: ErrorCode): ErrorCategory;
96
+ //#endregion
97
+ export { isErrorCode as a, categoryOf as i, ErrorCategory as n, ErrorCode as r, ERROR_CODES as t };
@@ -0,0 +1,2 @@
1
+ import { a as isErrorCode, i as categoryOf, n as ErrorCategory, r as ErrorCode, t as ERROR_CODES } from "./codes-CCNEPVSz.js";
2
+ export { ERROR_CODES, ErrorCategory, ErrorCode, categoryOf, isErrorCode };
package/dist/codes.js ADDED
@@ -0,0 +1,136 @@
1
+ //#region src/codes.ts
2
+ /**
3
+ * Stable error codes shared by the TypeScript and C# implementations.
4
+ *
5
+ * A code is part of the public contract: it is persisted in logs, sent across
6
+ * the JSON-RPC boundary and switched on by consumers (including the C# mirror
7
+ * in `Errors.cs`).
8
+ * Never rename or reuse a code — add a new one and deprecate the old.
9
+ */
10
+ const ErrorCode = {
11
+ /** An error that could not be classified. */
12
+ Unknown: "TOCHIRES_UNKNOWN",
13
+ /** An invariant inside the library was violated. */
14
+ Internal: "TOCHIRES_INTERNAL",
15
+ /** A configuration object failed validation. */
16
+ ConfigInvalid: "TOCHIRES_CONFIG_INVALID",
17
+ /** A required configuration field is missing. */
18
+ ConfigMissing: "TOCHIRES_CONFIG_MISSING",
19
+ /** A generic validation failure (payload, schema, argument). */
20
+ ValidationFailed: "TOCHIRES_VALIDATION_FAILED",
21
+ /** The request was malformed or failed validation at an API boundary. */
22
+ ApiBadRequest: "TOCHIRES_API_BAD_REQUEST",
23
+ /** Authentication is required, or the session/token is invalid. */
24
+ ApiUnauthorized: "TOCHIRES_API_UNAUTHORIZED",
25
+ /** The authenticated principal is not allowed to perform the action. */
26
+ ApiForbidden: "TOCHIRES_API_FORBIDDEN",
27
+ /** The requested resource does not exist. */
28
+ ApiNotFound: "TOCHIRES_API_NOT_FOUND",
29
+ /** The request conflicts with the current state of the resource. */
30
+ ApiConflict: "TOCHIRES_API_CONFLICT",
31
+ /** The payload was well-formed but is semantically invalid. */
32
+ ApiUnprocessable: "TOCHIRES_API_UNPROCESSABLE",
33
+ /** The caller exceeded an imposed rate limit. */
34
+ ApiTooManyRequests: "TOCHIRES_API_TOO_MANY_REQUESTS",
35
+ /** An upstream dependency did not respond in time. */
36
+ ApiTimeout: "TOCHIRES_API_TIMEOUT",
37
+ /** A downstream dependency is unavailable. */
38
+ ApiUnavailable: "TOCHIRES_API_UNAVAILABLE",
39
+ /** The IPC transport could not be opened or used. */
40
+ IpcTransport: "TOCHIRES_IPC_TRANSPORT",
41
+ /** A JSON-RPC envelope was malformed or violated the protocol. */
42
+ IpcProtocol: "TOCHIRES_IPC_PROTOCOL",
43
+ /** A request did not receive a response in time. */
44
+ IpcTimeout: "TOCHIRES_IPC_TIMEOUT",
45
+ /** Token authentication failed. */
46
+ IpcAuth: "TOCHIRES_IPC_AUTH",
47
+ /** The peer disconnected before the operation completed. */
48
+ IpcDisconnected: "TOCHIRES_IPC_DISCONNECTED",
49
+ /** A stream was paused because the consumer fell behind. */
50
+ IpcBackpressure: "TOCHIRES_IPC_BACKPRESSURE",
51
+ /** A TypeScript construct has no C# codegen mapping. */
52
+ CodegenUnsupported: "TOCHIRES_CODEGEN_UNSUPPORTED",
53
+ /** A generator failed while emitting an artifact. */
54
+ CodegenEmit: "TOCHIRES_CODEGEN_EMIT",
55
+ /** Generated output did not round-trip back to its source. */
56
+ CodegenRoundtrip: "TOCHIRES_CODEGEN_ROUNDTRIP",
57
+ /** CSS input could not be parsed. */
58
+ CssParse: "TOCHIRES_CSS_PARSE",
59
+ /** A CSS property is outside the supported subset. */
60
+ CssUnsupportedProperty: "TOCHIRES_CSS_UNSUPPORTED_PROPERTY",
61
+ /** A CSS selector is outside the supported subset. */
62
+ CssUnsupportedSelector: "TOCHIRES_CSS_UNSUPPORTED_SELECTOR",
63
+ /** A native module was not registered on the C# host. */
64
+ NativeModuleNotFound: "TOCHIRES_NATIVE_MODULE_NOT_FOUND",
65
+ /** A native method was not registered on a module. */
66
+ NativeMethodNotFound: "TOCHIRES_NATIVE_METHOD_NOT_FOUND",
67
+ /** A native method threw or returned an error. */
68
+ NativeCallFailed: "TOCHIRES_NATIVE_CALL_FAILED",
69
+ /** A build pipeline step failed. */
70
+ BuildFailed: "TOCHIRES_BUILD_FAILED",
71
+ /** A required build tool (dotnet, esbuild, …) is unavailable. */
72
+ BuildToolMissing: "TOCHIRES_BUILD_TOOL_MISSING",
73
+ /** A packaging step failed. */
74
+ PackageFailed: "TOCHIRES_PACKAGE_FAILED",
75
+ /** Signing or notarization failed. */
76
+ PackageSigning: "TOCHIRES_PACKAGE_SIGNING",
77
+ /** Settings text could not be parsed. */
78
+ SettingsParse: "TOCHIRES_SETTINGS_PARSE",
79
+ /** Settings values failed validation against their spec. */
80
+ SettingsInvalid: "TOCHIRES_SETTINGS_INVALID",
81
+ /** A path was malformed. */
82
+ PathInvalid: "TOCHIRES_PATH_INVALID",
83
+ /** An absolute path was supplied where only relative paths are allowed. */
84
+ PathAbsolute: "TOCHIRES_PATH_ABSOLUTE"
85
+ };
86
+ const CATEGORY_BY_CODE = {
87
+ [ErrorCode.Unknown]: "general",
88
+ [ErrorCode.Internal]: "general",
89
+ [ErrorCode.ConfigInvalid]: "config",
90
+ [ErrorCode.ConfigMissing]: "config",
91
+ [ErrorCode.ValidationFailed]: "validation",
92
+ [ErrorCode.ApiBadRequest]: "api",
93
+ [ErrorCode.ApiUnauthorized]: "api",
94
+ [ErrorCode.ApiForbidden]: "api",
95
+ [ErrorCode.ApiNotFound]: "api",
96
+ [ErrorCode.ApiConflict]: "api",
97
+ [ErrorCode.ApiUnprocessable]: "api",
98
+ [ErrorCode.ApiTooManyRequests]: "api",
99
+ [ErrorCode.ApiTimeout]: "api",
100
+ [ErrorCode.ApiUnavailable]: "api",
101
+ [ErrorCode.IpcTransport]: "ipc",
102
+ [ErrorCode.IpcProtocol]: "ipc",
103
+ [ErrorCode.IpcTimeout]: "ipc",
104
+ [ErrorCode.IpcAuth]: "ipc",
105
+ [ErrorCode.IpcDisconnected]: "ipc",
106
+ [ErrorCode.IpcBackpressure]: "ipc",
107
+ [ErrorCode.CodegenUnsupported]: "codegen",
108
+ [ErrorCode.CodegenEmit]: "codegen",
109
+ [ErrorCode.CodegenRoundtrip]: "codegen",
110
+ [ErrorCode.CssParse]: "css",
111
+ [ErrorCode.CssUnsupportedProperty]: "css",
112
+ [ErrorCode.CssUnsupportedSelector]: "css",
113
+ [ErrorCode.NativeModuleNotFound]: "native",
114
+ [ErrorCode.NativeMethodNotFound]: "native",
115
+ [ErrorCode.NativeCallFailed]: "native",
116
+ [ErrorCode.BuildFailed]: "build",
117
+ [ErrorCode.BuildToolMissing]: "build",
118
+ [ErrorCode.PackageFailed]: "package",
119
+ [ErrorCode.PackageSigning]: "package",
120
+ [ErrorCode.SettingsParse]: "settings",
121
+ [ErrorCode.SettingsInvalid]: "settings",
122
+ [ErrorCode.PathInvalid]: "path",
123
+ [ErrorCode.PathAbsolute]: "path"
124
+ };
125
+ /** All codes, as an array — handy for exhaustiveness checks and docs. */
126
+ const ERROR_CODES = Object.values(ErrorCode);
127
+ /** Whether a value is one of the known stable codes. */
128
+ function isErrorCode(value) {
129
+ return typeof value === "string" && Object.hasOwn(CATEGORY_BY_CODE, value);
130
+ }
131
+ /** The category a code belongs to, or `'general'` for unknown codes. */
132
+ function categoryOf(code) {
133
+ return CATEGORY_BY_CODE[code] ?? "general";
134
+ }
135
+ //#endregion
136
+ export { ERROR_CODES, ErrorCode, categoryOf, isErrorCode };
@@ -0,0 +1,100 @@
1
+ import { a as isErrorCode, i as categoryOf, n as ErrorCategory, r as ErrorCode, t as ERROR_CODES } from "./codes-CCNEPVSz.js";
2
+ import { a as TochiResErrorOptions, i as TochiResError, n as isSerializedError, o as serializeCause, r as serializeError, s as SerializedError, t as deserializeError } from "./serialize-xEOKnPuJ.js";
3
+ //#region src/errors/options.d.ts
4
+ /** Options shared by every domain error class (adds an optional code override). */
5
+ interface DomainErrorOptions extends TochiResErrorOptions {
6
+ /** Override the class's default code. */
7
+ code?: ErrorCode;
8
+ }
9
+ //#endregion
10
+ //#region src/errors/api.d.ts
11
+ /** An API/HTTP boundary failure (bad request, auth, not found, conflict, …). */
12
+ export declare class ApiError extends TochiResError {
13
+ constructor(message: string, options?: DomainErrorOptions);
14
+ }
15
+ //#endregion
16
+ //#region src/errors/build.d.ts
17
+ /** A build pipeline step failed or a required tool is missing. */
18
+ export declare class BuildError extends TochiResError {
19
+ constructor(message: string, options?: DomainErrorOptions);
20
+ }
21
+ //#endregion
22
+ //#region src/errors/codegen.d.ts
23
+ /** A TS→C# code generator failed or hit an unsupported construct. */
24
+ export declare class CodegenError extends TochiResError {
25
+ constructor(message: string, options?: DomainErrorOptions);
26
+ }
27
+ //#endregion
28
+ //#region src/errors/config.d.ts
29
+ /** Configuration is missing or failed validation. */
30
+ export declare class ConfigError extends TochiResError {
31
+ constructor(message: string, options?: DomainErrorOptions);
32
+ }
33
+ //#endregion
34
+ //#region src/errors/css.d.ts
35
+ /** CSS input is invalid or outside the supported subset. */
36
+ export declare class CssError extends TochiResError {
37
+ constructor(message: string, options?: DomainErrorOptions);
38
+ }
39
+ //#endregion
40
+ //#region src/errors/ipc.d.ts
41
+ /** An IPC transport, protocol, authentication or timeout failure. */
42
+ export declare class IpcError extends TochiResError {
43
+ constructor(message: string, options?: DomainErrorOptions);
44
+ }
45
+ //#endregion
46
+ //#region src/errors/native.d.ts
47
+ /** A native module or method was missing, or a native call failed. */
48
+ export declare class NativeError extends TochiResError {
49
+ constructor(message: string, options?: DomainErrorOptions);
50
+ }
51
+ //#endregion
52
+ //#region src/errors/package.d.ts
53
+ /** A packaging, signing or notarization step failed. */
54
+ export declare class PackageError extends TochiResError {
55
+ constructor(message: string, options?: DomainErrorOptions);
56
+ }
57
+ //#endregion
58
+ //#region src/errors/path.d.ts
59
+ /** A path was malformed or violated the relative-path rule. */
60
+ export declare class PathError extends TochiResError {
61
+ constructor(message: string, options?: DomainErrorOptions);
62
+ }
63
+ //#endregion
64
+ //#region src/errors/settings.d.ts
65
+ /** Settings text could not be parsed or failed validation. */
66
+ export declare class SettingsError extends TochiResError {
67
+ constructor(message: string, options?: DomainErrorOptions);
68
+ }
69
+ //#endregion
70
+ //#region src/errors/validation.d.ts
71
+ /** A payload, schema or argument failed validation. */
72
+ export declare class ValidationError extends TochiResError {
73
+ constructor(message: string, options?: DomainErrorOptions);
74
+ }
75
+ //#endregion
76
+ //#region src/errors/index.d.ts
77
+ /** Constructor shape shared by every domain error class. */
78
+ type DomainErrorConstructor = new (message: string, options?: DomainErrorOptions) => TochiResError;
79
+ /**
80
+ * The domain error class responsible for a code, or `undefined` for generic
81
+ * codes (which use {@link TochiResError} directly).
82
+ */
83
+ export declare function errorClassFor(code: ErrorCode): DomainErrorConstructor | undefined;
84
+ //#endregion
85
+ //#region src/guard.d.ts
86
+ /** Narrow a value to {@link TochiResError}. */
87
+ export declare function isTochiResError(value: unknown): value is TochiResError;
88
+ /** Whether a value is a {@link TochiResError} carrying one of the given codes. */
89
+ export declare function hasErrorCode(value: unknown, ...codes: ErrorCode[]): boolean;
90
+ /**
91
+ * Coerce any thrown value into a {@link TochiResError}.
92
+ *
93
+ * Already-typed errors pass through unchanged; native `Error`s and arbitrary
94
+ * thrown values are wrapped with {@link ErrorCode.Unknown} and kept as `cause`.
95
+ */
96
+ export declare function toTochiResError(value: unknown, fallbackMessage?: string): TochiResError;
97
+ /** Assert a condition, throwing a {@link TochiResError} with the given code if falsy. */
98
+ export declare function assertTochiRes(condition: unknown, code: ErrorCode, message: string, options?: TochiResErrorOptions): asserts condition;
99
+ //#endregion
100
+ export { type DomainErrorConstructor, type DomainErrorOptions, ERROR_CODES, type ErrorCategory, ErrorCode, type SerializedError, TochiResError, type TochiResErrorOptions, categoryOf, deserializeError, isErrorCode, isSerializedError, serializeCause, serializeError };
package/dist/index.js ADDED
@@ -0,0 +1,28 @@
1
+ import { ERROR_CODES, ErrorCode, categoryOf, isErrorCode } from "./codes.js";
2
+ import { _ as serializeCause, a as ValidationError, c as PackageError, d as CssError, f as ConfigError, g as TochiResError, h as ApiError, i as errorClassFor, l as NativeError, m as BuildError, n as isSerializedError, o as SettingsError, p as CodegenError, r as serializeError, s as PathError, t as deserializeError, u as IpcError } from "./serialize-D7PDJ704.js";
3
+ //#region src/guard.ts
4
+ /** Narrow a value to {@link TochiResError}. */
5
+ function isTochiResError(value) {
6
+ return value instanceof TochiResError;
7
+ }
8
+ /** Whether a value is a {@link TochiResError} carrying one of the given codes. */
9
+ function hasErrorCode(value, ...codes) {
10
+ return value instanceof TochiResError && codes.includes(value.code);
11
+ }
12
+ /**
13
+ * Coerce any thrown value into a {@link TochiResError}.
14
+ *
15
+ * Already-typed errors pass through unchanged; native `Error`s and arbitrary
16
+ * thrown values are wrapped with {@link ErrorCode.Unknown} and kept as `cause`.
17
+ */
18
+ function toTochiResError(value, fallbackMessage = "Unknown error") {
19
+ if (value instanceof TochiResError) return value;
20
+ if (value instanceof Error) return new TochiResError(ErrorCode.Unknown, value.message, { cause: value });
21
+ return new TochiResError(ErrorCode.Unknown, typeof value === "string" ? value : fallbackMessage, { cause: value });
22
+ }
23
+ /** Assert a condition, throwing a {@link TochiResError} with the given code if falsy. */
24
+ function assertTochiRes(condition, code, message, options = {}) {
25
+ if (!condition) throw new TochiResError(code, message, options);
26
+ }
27
+ //#endregion
28
+ export { ApiError, BuildError, CodegenError, ConfigError, CssError, ERROR_CODES, ErrorCode, IpcError, NativeError, PackageError, PathError, SettingsError, TochiResError, ValidationError, assertTochiRes, categoryOf, deserializeError, errorClassFor, hasErrorCode, isErrorCode, isSerializedError, isTochiResError, serializeCause, serializeError, toTochiResError };
@@ -0,0 +1,249 @@
1
+ import { ErrorCode, categoryOf, isErrorCode } from "./codes.js";
2
+ //#region src/base.ts
3
+ /**
4
+ * Base class for every typed error in this package.
5
+ *
6
+ * Carries a stable {@link ErrorCode} (mirrored in C#), a derived
7
+ * {@link ErrorCategory}, optional structured context and an optional cause
8
+ * chain, and serializes to a {@link SerializedError} that survives JSON-RPC.
9
+ */
10
+ var TochiResError = class extends Error {
11
+ /** Stable code — part of the public contract. */
12
+ code;
13
+ /** Coarse category derived from {@link code}. */
14
+ category;
15
+ /** Structured, JSON-safe context. */
16
+ context;
17
+ /** Underlying cause, if any. */
18
+ cause;
19
+ constructor(code, message, options = {}) {
20
+ super(message);
21
+ this.name = "TochiResError";
22
+ this.code = code;
23
+ this.category = categoryOf(code);
24
+ if (options.context !== void 0) this.context = options.context;
25
+ if (options.cause !== void 0) this.cause = options.cause;
26
+ Object.setPrototypeOf(this, new.target.prototype);
27
+ }
28
+ /** Serialize this error (and its cause chain) to a wire-safe object. */
29
+ toJSON() {
30
+ const json = {
31
+ name: this.name,
32
+ code: this.code,
33
+ category: this.category,
34
+ message: this.message
35
+ };
36
+ if (this.stack) json.stack = this.stack;
37
+ if (this.context) json.context = this.context;
38
+ const cause = serializeCause(this.cause);
39
+ if (cause) json.cause = cause;
40
+ return json;
41
+ }
42
+ };
43
+ /** Serialize any value used as a `cause` into a {@link SerializedError}. */
44
+ function serializeCause(value) {
45
+ if (value === void 0) return void 0;
46
+ if (value instanceof TochiResError) return value.toJSON();
47
+ if (value instanceof Error) {
48
+ const json = {
49
+ name: value.name || "Error",
50
+ code: ErrorCode.Unknown,
51
+ category: "general",
52
+ message: value.message
53
+ };
54
+ if (value.stack) json.stack = value.stack;
55
+ return json;
56
+ }
57
+ return {
58
+ name: "Error",
59
+ code: ErrorCode.Unknown,
60
+ category: "general",
61
+ message: stringifyUnknown$1(value)
62
+ };
63
+ }
64
+ function stringifyUnknown$1(value) {
65
+ if (typeof value === "string") return value;
66
+ try {
67
+ return JSON.stringify(value) ?? String(value);
68
+ } catch {
69
+ return String(value);
70
+ }
71
+ }
72
+ //#endregion
73
+ //#region src/errors/api.ts
74
+ /** An API/HTTP boundary failure (bad request, auth, not found, conflict, …). */
75
+ var ApiError = class extends TochiResError {
76
+ constructor(message, options = {}) {
77
+ super(options.code ?? ErrorCode.ApiBadRequest, message, options);
78
+ this.name = "ApiError";
79
+ }
80
+ };
81
+ //#endregion
82
+ //#region src/errors/build.ts
83
+ /** A build pipeline step failed or a required tool is missing. */
84
+ var BuildError = class extends TochiResError {
85
+ constructor(message, options = {}) {
86
+ super(options.code ?? ErrorCode.BuildFailed, message, options);
87
+ this.name = "BuildError";
88
+ }
89
+ };
90
+ //#endregion
91
+ //#region src/errors/codegen.ts
92
+ /** A TS→C# code generator failed or hit an unsupported construct. */
93
+ var CodegenError = class extends TochiResError {
94
+ constructor(message, options = {}) {
95
+ super(options.code ?? ErrorCode.CodegenEmit, message, options);
96
+ this.name = "CodegenError";
97
+ }
98
+ };
99
+ //#endregion
100
+ //#region src/errors/config.ts
101
+ /** Configuration is missing or failed validation. */
102
+ var ConfigError = class extends TochiResError {
103
+ constructor(message, options = {}) {
104
+ super(options.code ?? ErrorCode.ConfigInvalid, message, options);
105
+ this.name = "ConfigError";
106
+ }
107
+ };
108
+ //#endregion
109
+ //#region src/errors/css.ts
110
+ /** CSS input is invalid or outside the supported subset. */
111
+ var CssError = class extends TochiResError {
112
+ constructor(message, options = {}) {
113
+ super(options.code ?? ErrorCode.CssParse, message, options);
114
+ this.name = "CssError";
115
+ }
116
+ };
117
+ //#endregion
118
+ //#region src/errors/ipc.ts
119
+ /** An IPC transport, protocol, authentication or timeout failure. */
120
+ var IpcError = class extends TochiResError {
121
+ constructor(message, options = {}) {
122
+ super(options.code ?? ErrorCode.IpcTransport, message, options);
123
+ this.name = "IpcError";
124
+ }
125
+ };
126
+ //#endregion
127
+ //#region src/errors/native.ts
128
+ /** A native module or method was missing, or a native call failed. */
129
+ var NativeError = class extends TochiResError {
130
+ constructor(message, options = {}) {
131
+ super(options.code ?? ErrorCode.NativeCallFailed, message, options);
132
+ this.name = "NativeError";
133
+ }
134
+ };
135
+ //#endregion
136
+ //#region src/errors/package.ts
137
+ /** A packaging, signing or notarization step failed. */
138
+ var PackageError = class extends TochiResError {
139
+ constructor(message, options = {}) {
140
+ super(options.code ?? ErrorCode.PackageFailed, message, options);
141
+ this.name = "PackageError";
142
+ }
143
+ };
144
+ //#endregion
145
+ //#region src/errors/path.ts
146
+ /** A path was malformed or violated the relative-path rule. */
147
+ var PathError = class extends TochiResError {
148
+ constructor(message, options = {}) {
149
+ super(options.code ?? ErrorCode.PathInvalid, message, options);
150
+ this.name = "PathError";
151
+ }
152
+ };
153
+ //#endregion
154
+ //#region src/errors/settings.ts
155
+ /** Settings text could not be parsed or failed validation. */
156
+ var SettingsError = class extends TochiResError {
157
+ constructor(message, options = {}) {
158
+ super(options.code ?? ErrorCode.SettingsInvalid, message, options);
159
+ this.name = "SettingsError";
160
+ }
161
+ };
162
+ //#endregion
163
+ //#region src/errors/validation.ts
164
+ /** A payload, schema or argument failed validation. */
165
+ var ValidationError = class extends TochiResError {
166
+ constructor(message, options = {}) {
167
+ super(options.code ?? ErrorCode.ValidationFailed, message, options);
168
+ this.name = "ValidationError";
169
+ }
170
+ };
171
+ //#endregion
172
+ //#region src/errors/index.ts
173
+ const CLASS_BY_CATEGORY = {
174
+ config: ConfigError,
175
+ validation: ValidationError,
176
+ api: ApiError,
177
+ ipc: IpcError,
178
+ codegen: CodegenError,
179
+ css: CssError,
180
+ native: NativeError,
181
+ build: BuildError,
182
+ package: PackageError,
183
+ settings: SettingsError,
184
+ path: PathError
185
+ };
186
+ /**
187
+ * The domain error class responsible for a code, or `undefined` for generic
188
+ * codes (which use {@link TochiResError} directly).
189
+ */
190
+ function errorClassFor(code) {
191
+ const category = categoryOf(code);
192
+ return category === "general" ? void 0 : CLASS_BY_CATEGORY[category];
193
+ }
194
+ //#endregion
195
+ //#region src/serialize.ts
196
+ /** Serialize any thrown value into a {@link SerializedError}. */
197
+ function serializeError(value) {
198
+ if (value instanceof TochiResError) return value.toJSON();
199
+ if (value instanceof Error) {
200
+ const json = {
201
+ name: value.name || "Error",
202
+ code: ErrorCode.Unknown,
203
+ category: "general",
204
+ message: value.message
205
+ };
206
+ if (value.stack) json.stack = value.stack;
207
+ return json;
208
+ }
209
+ return {
210
+ name: "Error",
211
+ code: ErrorCode.Unknown,
212
+ category: "general",
213
+ message: stringifyUnknown(value)
214
+ };
215
+ }
216
+ /** Whether a value looks like a {@link SerializedError}. */
217
+ function isSerializedError(value) {
218
+ if (typeof value !== "object" || value === null) return false;
219
+ const record = value;
220
+ return isErrorCode(record.code) && typeof record.message === "string";
221
+ }
222
+ /**
223
+ * Rebuild a {@link TochiResError} (with the right domain subclass) from a
224
+ * {@link SerializedError}, preserving the cause chain.
225
+ */
226
+ function deserializeError(value) {
227
+ const record = typeof value === "object" && value !== null ? value : {};
228
+ const code = isErrorCode(record.code) ? record.code : ErrorCode.Unknown;
229
+ const message = typeof record.message === "string" ? record.message : "Unknown error";
230
+ const ErrorClass = errorClassFor(code);
231
+ const context = record.context;
232
+ const error = ErrorClass ? new ErrorClass(message, {
233
+ code,
234
+ context
235
+ }) : new TochiResError(code, message, context ? { context } : {});
236
+ if (record.stack) error.stack = record.stack;
237
+ if (record.cause) error.cause = deserializeError(record.cause);
238
+ return error;
239
+ }
240
+ function stringifyUnknown(value) {
241
+ if (typeof value === "string") return value;
242
+ try {
243
+ return JSON.stringify(value) ?? String(value);
244
+ } catch {
245
+ return String(value);
246
+ }
247
+ }
248
+ //#endregion
249
+ export { serializeCause as _, ValidationError as a, PackageError as c, CssError as d, ConfigError as f, TochiResError as g, ApiError as h, errorClassFor as i, NativeError as l, BuildError as m, isSerializedError as n, SettingsError as o, CodegenError as p, serializeError as r, PathError as s, deserializeError as t, IpcError as u };
@@ -0,0 +1,66 @@
1
+ import { n as ErrorCategory, r as ErrorCode } from "./codes-CCNEPVSz.js";
2
+ //#region src/types.d.ts
3
+ /**
4
+ * The wire representation of an error. Produced by {@link serializeError} and
5
+ * accepted by `deserializeError`; safe to embed in a JSON-RPC error object.
6
+ */
7
+ interface SerializedError {
8
+ /** The error class name, e.g. `ConfigError`. */
9
+ name: string;
10
+ /** Stable {@link ErrorCode}. */
11
+ code: ErrorCode;
12
+ /** Coarse category derived from the code. */
13
+ category: ErrorCategory;
14
+ /** Human-readable message. */
15
+ message: string;
16
+ /** Stack trace, when available. */
17
+ stack?: string;
18
+ /** Structured, JSON-safe context for logging/telemetry. */
19
+ context?: Record<string, unknown>;
20
+ /** Serialized cause chain. */
21
+ cause?: SerializedError;
22
+ }
23
+ //#endregion
24
+ //#region src/base.d.ts
25
+ /** Options accepted by every {@link TochiResError}. */
26
+ interface TochiResErrorOptions {
27
+ /** Underlying error/value that caused this one. */
28
+ cause?: unknown;
29
+ /** Structured, JSON-safe context for logging and telemetry. */
30
+ context?: Record<string, unknown>;
31
+ }
32
+ /**
33
+ * Base class for every typed error in this package.
34
+ *
35
+ * Carries a stable {@link ErrorCode} (mirrored in C#), a derived
36
+ * {@link ErrorCategory}, optional structured context and an optional cause
37
+ * chain, and serializes to a {@link SerializedError} that survives JSON-RPC.
38
+ */
39
+ declare class TochiResError extends Error {
40
+ /** Stable code — part of the public contract. */
41
+ readonly code: ErrorCode;
42
+ /** Coarse category derived from {@link code}. */
43
+ readonly category: ErrorCategory;
44
+ /** Structured, JSON-safe context. */
45
+ readonly context?: Record<string, unknown>;
46
+ /** Underlying cause, if any. */
47
+ readonly cause?: unknown;
48
+ constructor(code: ErrorCode, message: string, options?: TochiResErrorOptions);
49
+ /** Serialize this error (and its cause chain) to a wire-safe object. */
50
+ toJSON(): SerializedError;
51
+ }
52
+ /** Serialize any value used as a `cause` into a {@link SerializedError}. */
53
+ declare function serializeCause(value: unknown): SerializedError | undefined;
54
+ //#endregion
55
+ //#region src/serialize.d.ts
56
+ /** Serialize any thrown value into a {@link SerializedError}. */
57
+ declare function serializeError(value: unknown): SerializedError;
58
+ /** Whether a value looks like a {@link SerializedError}. */
59
+ declare function isSerializedError(value: unknown): value is SerializedError;
60
+ /**
61
+ * Rebuild a {@link TochiResError} (with the right domain subclass) from a
62
+ * {@link SerializedError}, preserving the cause chain.
63
+ */
64
+ declare function deserializeError(value: unknown): TochiResError;
65
+ //#endregion
66
+ export { TochiResErrorOptions as a, TochiResError as i, isSerializedError as n, serializeCause as o, serializeError as r, SerializedError as s, deserializeError as t };
@@ -0,0 +1,2 @@
1
+ import { n as isSerializedError, r as serializeError, t as deserializeError } from "./serialize-xEOKnPuJ.js";
2
+ export { deserializeError, isSerializedError, serializeError };
@@ -0,0 +1,3 @@
1
+ import "./codes.js";
2
+ import { n as isSerializedError, r as serializeError, t as deserializeError } from "./serialize-D7PDJ704.js";
3
+ export { deserializeError, isSerializedError, serializeError };
package/package.json CHANGED
@@ -1,6 +1,56 @@
1
1
  {
2
2
  "name": "@tochii/errors",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.1.6",
4
+ "description": "Shared typed errors and stable error codes used in official tochiResources proejcts.",
5
+ "license": "MIT",
6
+ "author": "T0chi",
7
+ "type": "module",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/tochiResources/errors.git"
11
+ },
12
+ "scripts": {
13
+ "build": "tsdown --config-loader unrun",
14
+ "format": "dbx fmt",
15
+ "lint": "dbx lint --fix",
16
+ "check": "dbx check",
17
+ "test": "vitest run",
18
+ "typecheck": "tsc -p tsconfig.build.json --noEmit",
19
+ "dbx": "dbx",
20
+ "commitlint": "commitlint",
21
+ "prepare": "husky"
22
+ },
23
+ "devDependencies": {
24
+ "@commitlint/cli": "^21.2.2",
25
+ "@commitlint/config-conventional": "^21.2.2",
26
+ "@deltabox/toolchain": "^1.11.3",
27
+ "@types/node": "^22.10.2",
28
+ "@typescript/native-preview": "7.0.0-dev.20260707.2",
29
+ "husky": "^9.1.7",
30
+ "tsdown": "^0.23.0",
31
+ "tsx": "^4.23.13",
32
+ "typescript": "^6.0.3",
33
+ "unrun": "^0.3.1",
34
+ "vite": "^8.3.0",
35
+ "vite-plus": "^1.2.0",
36
+ "vitest": "^5.0.0"
37
+ },
38
+ "publishConfig": {
39
+ "access": "public"
40
+ },
41
+ "packageManager": "yarn@4.17.1",
42
+ "engines": {
43
+ "node": ">=22.5.0"
44
+ },
45
+ "files": [
46
+ "dist",
47
+ "csharp"
48
+ ],
49
+ "types": "./dist/index.d.ts",
50
+ "exports": {
51
+ ".": "./dist/index.js",
52
+ "./codes": "./dist/codes.js",
53
+ "./serialize": "./dist/serialize.js",
54
+ "./package.json": "./package.json"
55
+ }
6
56
  }