ts-utility-kit 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Shion Terunaga
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 ADDED
@@ -0,0 +1,202 @@
1
+ # ts-utility-kit
2
+
3
+ Shared TypeScript utilities packaged.
4
+
5
+ [日本語 README](./README.ja.md)
6
+
7
+ ## Install From npm
8
+
9
+ ```bash
10
+ npm i ts-utility-kit
11
+ ```
12
+
13
+ Use this when you want to install the latest published version from the npm registry.
14
+
15
+ ## Install From GitHub
16
+
17
+ ```bash
18
+ npm i github:ShionTerunaga/ts-utility-kit#release
19
+ ```
20
+
21
+ Use this when you want to install directly from the built `release` branch on GitHub.
22
+
23
+ To pin a specific version, install from a version tag instead of `release`.
24
+
25
+ ```bash
26
+ npm i github:ShionTerunaga/ts-utility-kit#v1.5.1
27
+ ```
28
+
29
+ ## Usage
30
+
31
+ ```ts
32
+ import { envParse, optionUtility, resultUtility } from "ts-utility-kit";
33
+
34
+ const env = envParse(process.env.API_TOKEN);
35
+
36
+ if (env.isSome) {
37
+ console.log("token exists:", env.value);
38
+ }
39
+ ```
40
+
41
+ The built files are committed to the `release` branch, so the package can be installed directly from this GitHub repository without running build scripts.
42
+ Version tags are created in the `vxx.yy.zz` format, for example `v2.0.0`.
43
+
44
+ ## Included Utilities
45
+
46
+ All public APIs are exported from the package root.
47
+
48
+ ### `optionUtility` and `envParse`
49
+
50
+ Use `optionUtility` when you want to represent nullable values as an explicit `Some | None` union.
51
+ Use `envParse` when you want to convert `process.env` style values into an `Option<string>`.
52
+
53
+ ```ts
54
+ import { envParse, optionUtility } from "ts-utility-kit";
55
+
56
+ const token = envParse(process.env.API_TOKEN);
57
+ const nickname = optionUtility.optionConversion(user.nickname);
58
+
59
+ if (token.isSome) {
60
+ console.log(token.value);
61
+ }
62
+
63
+ const fallback = nickname.isSome ? nickname.value : "guest";
64
+ ```
65
+
66
+ Available helpers:
67
+
68
+ - `optionUtility.createSome(value)`
69
+ - `optionUtility.createNone()`
70
+ - `optionUtility.optionConversion(value)`
71
+
72
+ ### `resultUtility`
73
+
74
+ Use `resultUtility` when you want functions to return `Ok | Err` values instead of throwing directly.
75
+
76
+ ```ts
77
+ import { resultUtility } from "ts-utility-kit";
78
+
79
+ const result = await resultUtility.checkPromiseReturn({
80
+ fn: async () => {
81
+ return await fetchUser();
82
+ },
83
+ err: (error) => {
84
+ return resultUtility.createNg(error);
85
+ },
86
+ });
87
+
88
+ if (result.isOk) {
89
+ console.log(result.value);
90
+ } else {
91
+ console.error(result.err);
92
+ }
93
+ ```
94
+
95
+ Available helpers:
96
+
97
+ - `resultUtility.createOk(value)`
98
+ - `resultUtility.createNg(error)`
99
+ - `resultUtility.checkResultReturn({ fn, err, finalFn? })`
100
+ - `resultUtility.checkResultVoid({ fn, err, finalFn? })`
101
+ - `resultUtility.checkPromiseReturn({ fn, err, finalFn? })`
102
+ - `resultUtility.checkPromiseVoid({ fn, err, finalFn? })`
103
+ - `resultUtility.UNIT`
104
+
105
+ ### Error classes
106
+
107
+ Use the custom error classes when you want consistent error names, codes, and metadata.
108
+
109
+ ```ts
110
+ import { BadRequestError, SchemeError, ValidationError } from "ts-utility-kit";
111
+
112
+ throw new ValidationError({
113
+ field: "email",
114
+ issues: [{ path: "email", message: "Invalid format" }],
115
+ });
116
+
117
+ throw new SchemeError({
118
+ allowedSchemes: ["https"],
119
+ receivedScheme: "http",
120
+ });
121
+
122
+ throw new BadRequestError({
123
+ details: { reason: "Missing query parameter" },
124
+ });
125
+ ```
126
+
127
+ Included error exports:
128
+
129
+ - `BaseError`
130
+ - `BaseHttpError` and HTTP subclasses such as `BadRequestError`, `UnauthorizedError`, `NotFoundError`, `ConflictError`, `TooManyRequestsError`, and `InternalServerError`
131
+ - `SchemeError`
132
+ - `ValidationError`
133
+
134
+ ### `classMerger`
135
+
136
+ Use `classMerger` to deduplicate class names while preserving order.
137
+
138
+ ```ts
139
+ import { classMerger } from "ts-utility-kit";
140
+
141
+ const className = classMerger(["button", "", "button", "primary"]);
142
+ // "button primary"
143
+ ```
144
+
145
+ ### `omitElementObject`
146
+
147
+ Use `omitElementObject` to create a new object without specific keys.
148
+
149
+ ```ts
150
+ import { omitElementObject } from "ts-utility-kit";
151
+
152
+ const user = {
153
+ id: 1,
154
+ name: "Shion",
155
+ password: "secret",
156
+ };
157
+
158
+ const safeUser = omitElementObject(user, ["password"]);
159
+ ```
160
+
161
+ ### `isNull` and `isUndefined`
162
+
163
+ Use the type guards when narrowing unknown values.
164
+
165
+ ```ts
166
+ import { isNull, isUndefined } from "ts-utility-kit";
167
+
168
+ function normalize(value: unknown) {
169
+ if (isNull(value) || isUndefined(value)) {
170
+ return "empty";
171
+ }
172
+
173
+ return String(value);
174
+ }
175
+ ```
176
+
177
+ ### Utility types
178
+
179
+ The package also exports these TypeScript-only utility types:
180
+
181
+ - `Dict<T>`
182
+ - `Without<T, K>`
183
+
184
+ ## Development
185
+
186
+ ```bash
187
+ vp install
188
+ vp check
189
+ vp test
190
+ vp build
191
+ ```
192
+
193
+ ## Release Flow
194
+
195
+ Create a changeset for user-facing changes before opening or merging a PR.
196
+
197
+ ```bash
198
+ vp run changeset
199
+ ```
200
+
201
+ The `Release PR` workflow opens or updates the Changesets release PR into `main`. When that release PR branch (`changeset-release/main`) is merged into `main`, the `Sync Release` workflow reflects the merged commit to `release`. After `release` is updated, the `Publish Release` workflow generates release notes from the latest `CHANGELOG.md` entry and then creates or updates the Git tag and GitHub Release.
202
+ Each generated changelog item will also include the source PR and the contributor's GitHub username.
@@ -0,0 +1,232 @@
1
+ //#region src/merger/class-merger.d.ts
2
+ declare function classMerger(classes: ReadonlyArray<string>): string;
3
+ //#endregion
4
+ //#region src/error/base-error.d.ts
5
+ interface BaseErrorOptions {
6
+ cause?: unknown;
7
+ code?: string;
8
+ details?: unknown;
9
+ message?: string;
10
+ name?: string;
11
+ }
12
+ declare class BaseError extends Error {
13
+ cause?: unknown;
14
+ code?: string;
15
+ details?: unknown;
16
+ constructor(options?: BaseErrorOptions);
17
+ }
18
+ //#endregion
19
+ //#region src/error/http-error.d.ts
20
+ interface HttpErrorOptions extends BaseErrorOptions {
21
+ expose?: boolean;
22
+ status?: number;
23
+ statusText?: string;
24
+ }
25
+ declare class BaseHttpError extends BaseError {
26
+ expose: boolean;
27
+ status: number;
28
+ statusText: string;
29
+ constructor(options?: HttpErrorOptions);
30
+ }
31
+ declare class UnauthorizedError extends BaseHttpError {
32
+ constructor(options?: HttpErrorOptions);
33
+ }
34
+ declare class BadRequestError extends BaseHttpError {
35
+ constructor(options?: HttpErrorOptions);
36
+ }
37
+ declare class PaymentRequiredError extends BaseHttpError {
38
+ constructor(options?: HttpErrorOptions);
39
+ }
40
+ declare class ForbiddenError extends BaseHttpError {
41
+ constructor(options?: HttpErrorOptions);
42
+ }
43
+ declare class MethodNotAllowedError extends BaseHttpError {
44
+ constructor(options?: HttpErrorOptions);
45
+ }
46
+ declare class NotAcceptableError extends BaseHttpError {
47
+ constructor(options?: HttpErrorOptions);
48
+ }
49
+ declare class ProxyAuthenticationRequiredError extends BaseHttpError {
50
+ constructor(options?: HttpErrorOptions);
51
+ }
52
+ declare class NotFoundError extends BaseHttpError {
53
+ constructor(options?: HttpErrorOptions);
54
+ }
55
+ declare class ConflictError extends BaseHttpError {
56
+ constructor(options?: HttpErrorOptions);
57
+ }
58
+ declare class GoneError extends BaseHttpError {
59
+ constructor(options?: HttpErrorOptions);
60
+ }
61
+ declare class PreconditionFailedError extends BaseHttpError {
62
+ constructor(options?: HttpErrorOptions);
63
+ }
64
+ declare class PayloadTooLargeError extends BaseHttpError {
65
+ constructor(options?: HttpErrorOptions);
66
+ }
67
+ declare class UnsupportedMediaTypeError extends BaseHttpError {
68
+ constructor(options?: HttpErrorOptions);
69
+ }
70
+ declare class UnprocessableEntityError extends BaseHttpError {
71
+ constructor(options?: HttpErrorOptions);
72
+ }
73
+ declare class TooManyRequestsError extends BaseHttpError {
74
+ constructor(options?: HttpErrorOptions);
75
+ }
76
+ declare class TimeoutError extends BaseHttpError {
77
+ constructor(options?: HttpErrorOptions);
78
+ }
79
+ declare class InternalServerError extends BaseHttpError {
80
+ constructor(options?: HttpErrorOptions);
81
+ }
82
+ declare class NotImplementedError extends BaseHttpError {
83
+ constructor(options?: HttpErrorOptions);
84
+ }
85
+ declare class BadGatewayError extends BaseHttpError {
86
+ constructor(options?: HttpErrorOptions);
87
+ }
88
+ declare class ServiceUnavailableError extends BaseHttpError {
89
+ constructor(options?: HttpErrorOptions);
90
+ }
91
+ declare class GatewayTimeoutError extends BaseHttpError {
92
+ constructor(options?: HttpErrorOptions);
93
+ }
94
+ //#endregion
95
+ //#region src/error/scheme-error.d.ts
96
+ interface SchemeErrorOptions extends BaseErrorOptions {
97
+ allowedSchemes?: string[];
98
+ receivedScheme?: string;
99
+ }
100
+ declare class SchemeError extends BaseError {
101
+ readonly allowedSchemes: string[];
102
+ readonly receivedScheme?: string;
103
+ constructor(options?: SchemeErrorOptions);
104
+ }
105
+ //#endregion
106
+ //#region src/error/validation-error.d.ts
107
+ interface ValidationIssue {
108
+ message: string;
109
+ path?: string;
110
+ }
111
+ interface ValidationErrorOptions extends BaseErrorOptions {
112
+ field?: string;
113
+ issues?: ValidationIssue[];
114
+ }
115
+ declare class ValidationError extends BaseError {
116
+ readonly field?: string;
117
+ readonly issues: ValidationIssue[];
118
+ constructor(options?: ValidationErrorOptions);
119
+ }
120
+ //#endregion
121
+ //#region src/common/is.d.ts
122
+ declare function isNull(value: unknown): value is null;
123
+ declare function isUndefined(value: unknown): value is undefined;
124
+ //#endregion
125
+ //#region src/object/object.d.ts
126
+ declare function omitElementObject<T extends object, S extends keyof T>(obj: T, keys: S[]): Omit<T, S>;
127
+ //#endregion
128
+ //#region src/non-nullable/option.d.ts
129
+ declare const basic$1: {
130
+ readonly OPTION_SOME: "some";
131
+ readonly OPTION_NONE: "none";
132
+ };
133
+ interface Some<T> {
134
+ readonly kind: typeof basic$1.OPTION_SOME;
135
+ readonly isSome: true;
136
+ readonly isNone: false;
137
+ readonly value: T;
138
+ }
139
+ interface None {
140
+ readonly kind: typeof basic$1.OPTION_NONE;
141
+ readonly isSome: false;
142
+ readonly isNone: true;
143
+ }
144
+ type Option<T> = Some<NonNullable<T>> | None;
145
+ declare const optionUtility: Readonly<{
146
+ createSome: <T>(value: NonNullable<T>) => Option<T>;
147
+ createNone: () => Option<never>;
148
+ optionConversion: <T>(value: T) => Option<T>;
149
+ }>;
150
+ //#endregion
151
+ //#region src/non-nullable/env-parse.d.ts
152
+ declare function envParse(env: string | undefined): Option<string>;
153
+ //#endregion
154
+ //#region src/non-nullable/result.d.ts
155
+ declare const basic: {
156
+ readonly RESULT_OK: "ok";
157
+ readonly RESULT_NG: "ng";
158
+ };
159
+ interface OK<T> {
160
+ readonly kind: typeof basic.RESULT_OK;
161
+ readonly isOk: true;
162
+ readonly isErr: false;
163
+ readonly value: T;
164
+ }
165
+ interface NG<E> {
166
+ readonly kind: typeof basic.RESULT_NG;
167
+ readonly isOk: false;
168
+ readonly isErr: true;
169
+ readonly err: E;
170
+ }
171
+ interface CheckResultReturn<T, E> {
172
+ fn: () => NonNullable<T>;
173
+ err: (e: unknown) => Result<never, NonNullable<E>>;
174
+ finalFn?: () => void;
175
+ }
176
+ interface CheckResultVoid<E> {
177
+ fn: () => void;
178
+ err: (e: unknown) => Result<never, NonNullable<E>>;
179
+ finalFn?: () => void;
180
+ }
181
+ interface CheckPromiseReturn<T, E> {
182
+ fn: () => Promise<NonNullable<T>>;
183
+ err: (e: unknown) => Result<never, NonNullable<E>>;
184
+ finalFn?: () => void;
185
+ }
186
+ interface CheckPromiseVoid<E> {
187
+ fn: () => Promise<void>;
188
+ err: (e: unknown) => Result<never, NonNullable<E>>;
189
+ finalFn?: () => void;
190
+ }
191
+ declare const UNIT_SYMBOL: unique symbol;
192
+ interface Unit {
193
+ readonly _unit: typeof UNIT_SYMBOL;
194
+ }
195
+ type Result<T, E> = OK<NonNullable<T>> | NG<NonNullable<E>>;
196
+ declare const resultUtility: Readonly<{
197
+ UNIT: Unit;
198
+ checkResultReturn: <T, E>({
199
+ fn,
200
+ err,
201
+ finalFn
202
+ }: CheckResultReturn<T, E>) => Result<T, E>;
203
+ checkResultVoid: <E>({
204
+ fn,
205
+ err,
206
+ finalFn
207
+ }: CheckResultVoid<E>) => Result<Unit, E>;
208
+ checkPromiseReturn: <T, E>({
209
+ fn,
210
+ err,
211
+ finalFn
212
+ }: CheckPromiseReturn<T, E>) => Promise<Result<T, E>>;
213
+ checkPromiseVoid: <E>({
214
+ fn,
215
+ err,
216
+ finalFn
217
+ }: CheckPromiseVoid<E>) => Promise<Result<Unit, E>>;
218
+ createOk: <T>(value: NonNullable<T>) => Result<T, never>;
219
+ createNg: <E>(err: NonNullable<E>) => Result<never, E>;
220
+ }>;
221
+ //#endregion
222
+ //#region src/types/object.d.ts
223
+ /**
224
+ * 柔軟なオブジェクト
225
+ */
226
+ type Dict<T> = Record<string, T>;
227
+ /**
228
+ * Omitよりも厳密に型をチェックする(Omitは余計なプロパティを許容してしまう)
229
+ */
230
+ type Without<T, K extends keyof T> = { [P in Exclude<keyof T, K>]: T[P] } & { [P in K]?: never };
231
+ //#endregion
232
+ export { BadGatewayError, BadRequestError, BaseError, type BaseErrorOptions, BaseHttpError, ConflictError, type Dict, ForbiddenError, GatewayTimeoutError, GoneError, type HttpErrorOptions, InternalServerError, MethodNotAllowedError, NotAcceptableError, NotFoundError, NotImplementedError, type Option, PayloadTooLargeError, PaymentRequiredError, PreconditionFailedError, ProxyAuthenticationRequiredError, type Result, SchemeError, type SchemeErrorOptions, ServiceUnavailableError, TimeoutError, TooManyRequestsError, UnauthorizedError, type Unit, UnprocessableEntityError, UnsupportedMediaTypeError, ValidationError, type ValidationErrorOptions, type ValidationIssue, type Without, classMerger, envParse, isNull, isUndefined, omitElementObject, optionUtility, resultUtility };
package/dist/index.mjs ADDED
@@ -0,0 +1,495 @@
1
+ //#region src/merger/class-merger.ts
2
+ function classMerger(classes) {
3
+ const length = classes.length;
4
+ if (length === 0) return "";
5
+ const firstClass = classes[0];
6
+ if (length === 1) return firstClass;
7
+ const seen = /* @__PURE__ */ new Set();
8
+ const out = [];
9
+ for (let index = 0; index < length; index += 1) {
10
+ const cls = classes[index];
11
+ if (cls === "" || seen.has(cls)) continue;
12
+ seen.add(cls);
13
+ out.push(cls);
14
+ }
15
+ return out.length === 1 ? out[0] : out.join(" ");
16
+ }
17
+ //#endregion
18
+ //#region src/error/base-error.ts
19
+ var BaseError = class extends Error {
20
+ constructor(options = {}) {
21
+ const { cause, code, details, message = "Application Error", name = "BaseError" } = options;
22
+ super(message, cause === void 0 ? void 0 : { cause });
23
+ this.name = name;
24
+ this.code = code;
25
+ this.details = details;
26
+ if (cause !== void 0 && !("cause" in this)) Object.defineProperty(this, "cause", {
27
+ configurable: true,
28
+ enumerable: false,
29
+ value: cause,
30
+ writable: true
31
+ });
32
+ }
33
+ };
34
+ //#endregion
35
+ //#region src/error/http-error.ts
36
+ var BaseHttpError = class extends BaseError {
37
+ expose;
38
+ status;
39
+ statusText;
40
+ constructor(options = {}) {
41
+ const { cause, code, details, expose, message, name = "BaseHttpError", status, statusText } = options;
42
+ super({
43
+ cause,
44
+ code,
45
+ details,
46
+ message,
47
+ name
48
+ });
49
+ this.expose = expose ?? false;
50
+ this.status = status ?? 500;
51
+ this.statusText = statusText ?? "Internal Server Error";
52
+ }
53
+ };
54
+ var UnauthorizedError = class extends BaseHttpError {
55
+ constructor(options = {}) {
56
+ super({
57
+ code: "UNAUTHORIZED",
58
+ expose: true,
59
+ message: "Unauthorized",
60
+ name: "UnauthorizedError",
61
+ status: 401,
62
+ statusText: "Unauthorized",
63
+ ...options
64
+ });
65
+ }
66
+ };
67
+ var BadRequestError = class extends BaseHttpError {
68
+ constructor(options = {}) {
69
+ super({
70
+ code: "BAD_REQUEST",
71
+ expose: true,
72
+ message: "Bad Request",
73
+ name: "BadRequestError",
74
+ status: 400,
75
+ statusText: "Bad Request",
76
+ ...options
77
+ });
78
+ }
79
+ };
80
+ var PaymentRequiredError = class extends BaseHttpError {
81
+ constructor(options = {}) {
82
+ super({
83
+ code: "PAYMENT_REQUIRED",
84
+ expose: true,
85
+ message: "Payment Required",
86
+ name: "PaymentRequiredError",
87
+ status: 402,
88
+ statusText: "Payment Required",
89
+ ...options
90
+ });
91
+ }
92
+ };
93
+ var ForbiddenError = class extends BaseHttpError {
94
+ constructor(options = {}) {
95
+ super({
96
+ code: "FORBIDDEN",
97
+ expose: true,
98
+ message: "Forbidden",
99
+ name: "ForbiddenError",
100
+ status: 403,
101
+ statusText: "Forbidden",
102
+ ...options
103
+ });
104
+ }
105
+ };
106
+ var MethodNotAllowedError = class extends BaseHttpError {
107
+ constructor(options = {}) {
108
+ super({
109
+ code: "METHOD_NOT_ALLOWED",
110
+ expose: true,
111
+ message: "Method Not Allowed",
112
+ name: "MethodNotAllowedError",
113
+ status: 405,
114
+ statusText: "Method Not Allowed",
115
+ ...options
116
+ });
117
+ }
118
+ };
119
+ var NotAcceptableError = class extends BaseHttpError {
120
+ constructor(options = {}) {
121
+ super({
122
+ code: "NOT_ACCEPTABLE",
123
+ expose: true,
124
+ message: "Not Acceptable",
125
+ name: "NotAcceptableError",
126
+ status: 406,
127
+ statusText: "Not Acceptable",
128
+ ...options
129
+ });
130
+ }
131
+ };
132
+ var ProxyAuthenticationRequiredError = class extends BaseHttpError {
133
+ constructor(options = {}) {
134
+ super({
135
+ code: "PROXY_AUTHENTICATION_REQUIRED",
136
+ expose: true,
137
+ message: "Proxy Authentication Required",
138
+ name: "ProxyAuthenticationRequiredError",
139
+ status: 407,
140
+ statusText: "Proxy Authentication Required",
141
+ ...options
142
+ });
143
+ }
144
+ };
145
+ var NotFoundError = class extends BaseHttpError {
146
+ constructor(options = {}) {
147
+ super({
148
+ code: "NOT_FOUND",
149
+ expose: true,
150
+ message: "Not Found",
151
+ name: "NotFoundError",
152
+ status: 404,
153
+ statusText: "Not Found",
154
+ ...options
155
+ });
156
+ }
157
+ };
158
+ var ConflictError = class extends BaseHttpError {
159
+ constructor(options = {}) {
160
+ super({
161
+ code: "CONFLICT",
162
+ expose: true,
163
+ message: "Conflict",
164
+ name: "ConflictError",
165
+ status: 409,
166
+ statusText: "Conflict",
167
+ ...options
168
+ });
169
+ }
170
+ };
171
+ var GoneError = class extends BaseHttpError {
172
+ constructor(options = {}) {
173
+ super({
174
+ code: "GONE",
175
+ expose: true,
176
+ message: "Gone",
177
+ name: "GoneError",
178
+ status: 410,
179
+ statusText: "Gone",
180
+ ...options
181
+ });
182
+ }
183
+ };
184
+ var PreconditionFailedError = class extends BaseHttpError {
185
+ constructor(options = {}) {
186
+ super({
187
+ code: "PRECONDITION_FAILED",
188
+ expose: true,
189
+ message: "Precondition Failed",
190
+ name: "PreconditionFailedError",
191
+ status: 412,
192
+ statusText: "Precondition Failed",
193
+ ...options
194
+ });
195
+ }
196
+ };
197
+ var PayloadTooLargeError = class extends BaseHttpError {
198
+ constructor(options = {}) {
199
+ super({
200
+ code: "PAYLOAD_TOO_LARGE",
201
+ expose: true,
202
+ message: "Payload Too Large",
203
+ name: "PayloadTooLargeError",
204
+ status: 413,
205
+ statusText: "Payload Too Large",
206
+ ...options
207
+ });
208
+ }
209
+ };
210
+ var UnsupportedMediaTypeError = class extends BaseHttpError {
211
+ constructor(options = {}) {
212
+ super({
213
+ code: "UNSUPPORTED_MEDIA_TYPE",
214
+ expose: true,
215
+ message: "Unsupported Media Type",
216
+ name: "UnsupportedMediaTypeError",
217
+ status: 415,
218
+ statusText: "Unsupported Media Type",
219
+ ...options
220
+ });
221
+ }
222
+ };
223
+ var UnprocessableEntityError = class extends BaseHttpError {
224
+ constructor(options = {}) {
225
+ super({
226
+ code: "UNPROCESSABLE_ENTITY",
227
+ expose: true,
228
+ message: "Unprocessable Entity",
229
+ name: "UnprocessableEntityError",
230
+ status: 422,
231
+ statusText: "Unprocessable Entity",
232
+ ...options
233
+ });
234
+ }
235
+ };
236
+ var TooManyRequestsError = class extends BaseHttpError {
237
+ constructor(options = {}) {
238
+ super({
239
+ code: "TOO_MANY_REQUESTS",
240
+ expose: true,
241
+ message: "Too Many Requests",
242
+ name: "TooManyRequestsError",
243
+ status: 429,
244
+ statusText: "Too Many Requests",
245
+ ...options
246
+ });
247
+ }
248
+ };
249
+ var TimeoutError = class extends BaseHttpError {
250
+ constructor(options = {}) {
251
+ super({
252
+ code: "REQUEST_TIMEOUT",
253
+ expose: true,
254
+ message: "Request Timeout",
255
+ name: "TimeoutError",
256
+ status: 408,
257
+ statusText: "Request Timeout",
258
+ ...options
259
+ });
260
+ }
261
+ };
262
+ var InternalServerError = class extends BaseHttpError {
263
+ constructor(options = {}) {
264
+ super({
265
+ code: "INTERNAL_SERVER_ERROR",
266
+ expose: false,
267
+ message: "Internal Server Error",
268
+ name: "InternalServerError",
269
+ status: 500,
270
+ statusText: "Internal Server Error",
271
+ ...options
272
+ });
273
+ }
274
+ };
275
+ var NotImplementedError = class extends BaseHttpError {
276
+ constructor(options = {}) {
277
+ super({
278
+ code: "NOT_IMPLEMENTED",
279
+ expose: false,
280
+ message: "Not Implemented",
281
+ name: "NotImplementedError",
282
+ status: 501,
283
+ statusText: "Not Implemented",
284
+ ...options
285
+ });
286
+ }
287
+ };
288
+ var BadGatewayError = class extends BaseHttpError {
289
+ constructor(options = {}) {
290
+ super({
291
+ code: "BAD_GATEWAY",
292
+ expose: false,
293
+ message: "Bad Gateway",
294
+ name: "BadGatewayError",
295
+ status: 502,
296
+ statusText: "Bad Gateway",
297
+ ...options
298
+ });
299
+ }
300
+ };
301
+ var ServiceUnavailableError = class extends BaseHttpError {
302
+ constructor(options = {}) {
303
+ super({
304
+ code: "SERVICE_UNAVAILABLE",
305
+ expose: false,
306
+ message: "Service Unavailable",
307
+ name: "ServiceUnavailableError",
308
+ status: 503,
309
+ statusText: "Service Unavailable",
310
+ ...options
311
+ });
312
+ }
313
+ };
314
+ var GatewayTimeoutError = class extends BaseHttpError {
315
+ constructor(options = {}) {
316
+ super({
317
+ code: "GATEWAY_TIMEOUT",
318
+ expose: false,
319
+ message: "Gateway Timeout",
320
+ name: "GatewayTimeoutError",
321
+ status: 504,
322
+ statusText: "Gateway Timeout",
323
+ ...options
324
+ });
325
+ }
326
+ };
327
+ //#endregion
328
+ //#region src/error/scheme-error.ts
329
+ var SchemeError = class extends BaseError {
330
+ allowedSchemes;
331
+ receivedScheme;
332
+ constructor(options = {}) {
333
+ const { allowedSchemes = [], receivedScheme, ...baseOptions } = options;
334
+ const allowedText = allowedSchemes.length === 0 ? "none" : allowedSchemes.join(", ");
335
+ super({
336
+ code: "INVALID_SCHEME",
337
+ message: `Invalid scheme: expected one of [${allowedText}], received "${receivedScheme ?? "unknown"}"`,
338
+ name: "SchemeError",
339
+ ...baseOptions
340
+ });
341
+ this.allowedSchemes = allowedSchemes;
342
+ this.receivedScheme = receivedScheme;
343
+ }
344
+ };
345
+ //#endregion
346
+ //#region src/error/validation-error.ts
347
+ var ValidationError = class extends BaseError {
348
+ field;
349
+ issues;
350
+ constructor(options = {}) {
351
+ const { field, issues = [], ...baseOptions } = options;
352
+ const message = baseOptions.message ?? (field ? `Validation failed for "${field}"` : "Validation failed");
353
+ super({
354
+ code: "VALIDATION_ERROR",
355
+ ...baseOptions,
356
+ message,
357
+ name: "ValidationError"
358
+ });
359
+ this.field = field;
360
+ this.issues = issues;
361
+ }
362
+ };
363
+ //#endregion
364
+ //#region src/common/is.ts
365
+ function isNull(value) {
366
+ return value === null;
367
+ }
368
+ function isUndefined(value) {
369
+ return value === void 0;
370
+ }
371
+ //#endregion
372
+ //#region src/object/object.ts
373
+ function omitElementObject(obj, keys) {
374
+ const entries = Object.entries(obj).filter(([k]) => {
375
+ return !keys.some((key) => String(key) === k);
376
+ });
377
+ const typedResult = {};
378
+ for (const [k, v] of entries) typedResult[k] = v;
379
+ return typedResult;
380
+ }
381
+ //#endregion
382
+ //#region src/non-nullable/option.ts
383
+ const basic$1 = {
384
+ OPTION_SOME: "some",
385
+ OPTION_NONE: "none"
386
+ };
387
+ const optionUtility = (function() {
388
+ const { OPTION_SOME, OPTION_NONE } = basic$1;
389
+ const createSome = (value) => {
390
+ return Object.freeze({
391
+ kind: OPTION_SOME,
392
+ isSome: true,
393
+ isNone: false,
394
+ value
395
+ });
396
+ };
397
+ const createNone = () => {
398
+ return Object.freeze({
399
+ kind: OPTION_NONE,
400
+ isSome: false,
401
+ isNone: true
402
+ });
403
+ };
404
+ const optionConversion = (value) => {
405
+ if (value === null || value === void 0) return createNone();
406
+ return createSome(value);
407
+ };
408
+ return Object.freeze({
409
+ createSome,
410
+ createNone,
411
+ optionConversion
412
+ });
413
+ })();
414
+ //#endregion
415
+ //#region src/non-nullable/env-parse.ts
416
+ function envParse(env) {
417
+ const { optionConversion } = optionUtility;
418
+ return optionConversion(env);
419
+ }
420
+ //#endregion
421
+ //#region src/non-nullable/result.ts
422
+ const basic = {
423
+ RESULT_OK: "ok",
424
+ RESULT_NG: "ng"
425
+ };
426
+ const UNIT_SYMBOL = Symbol("UNIT_SYMBOL");
427
+ const resultUtility = (function() {
428
+ const { RESULT_NG, RESULT_OK } = basic;
429
+ const UNIT = Object.freeze({ _unit: UNIT_SYMBOL });
430
+ const checkPromiseReturn = async ({ fn, err, finalFn = () => {} }) => {
431
+ try {
432
+ return createOk(await fn());
433
+ } catch (e) {
434
+ return err(e);
435
+ } finally {
436
+ finalFn();
437
+ }
438
+ };
439
+ const checkPromiseVoid = async ({ fn, err, finalFn = () => {} }) => {
440
+ try {
441
+ await fn();
442
+ return createOk(UNIT);
443
+ } catch (e) {
444
+ return err(e);
445
+ } finally {
446
+ finalFn();
447
+ }
448
+ };
449
+ const checkResultReturn = ({ fn, err, finalFn = () => {} }) => {
450
+ try {
451
+ return createOk(fn());
452
+ } catch (e) {
453
+ return err(e);
454
+ } finally {
455
+ finalFn();
456
+ }
457
+ };
458
+ const checkResultVoid = ({ fn, err, finalFn = () => {} }) => {
459
+ try {
460
+ fn();
461
+ return createOk(UNIT);
462
+ } catch (e) {
463
+ return err(e);
464
+ } finally {
465
+ finalFn();
466
+ }
467
+ };
468
+ const createOk = (value) => {
469
+ return Object.freeze({
470
+ kind: RESULT_OK,
471
+ isOk: true,
472
+ isErr: false,
473
+ value
474
+ });
475
+ };
476
+ const createNg = (err) => {
477
+ return Object.freeze({
478
+ kind: RESULT_NG,
479
+ isOk: false,
480
+ isErr: true,
481
+ err
482
+ });
483
+ };
484
+ return Object.freeze({
485
+ UNIT,
486
+ checkResultReturn,
487
+ checkResultVoid,
488
+ checkPromiseReturn,
489
+ checkPromiseVoid,
490
+ createOk,
491
+ createNg
492
+ });
493
+ })();
494
+ //#endregion
495
+ export { BadGatewayError, BadRequestError, BaseError, BaseHttpError, ConflictError, ForbiddenError, GatewayTimeoutError, GoneError, InternalServerError, MethodNotAllowedError, NotAcceptableError, NotFoundError, NotImplementedError, PayloadTooLargeError, PaymentRequiredError, PreconditionFailedError, ProxyAuthenticationRequiredError, SchemeError, ServiceUnavailableError, TimeoutError, TooManyRequestsError, UnauthorizedError, UnprocessableEntityError, UnsupportedMediaTypeError, ValidationError, classMerger, envParse, isNull, isUndefined, omitElementObject, optionUtility, resultUtility };
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "ts-utility-kit",
3
+ "version": "1.4.0",
4
+ "description": "Shared TypeScript utilities with generated type definitions.",
5
+ "homepage": "https://github.com/ShionTerunaga/ts-shared#readme",
6
+ "bugs": {
7
+ "url": "https://github.com/ShionTerunaga/ts-shared/issues"
8
+ },
9
+ "license": "MIT",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/ShionTerunaga/ts-shared.git"
13
+ },
14
+ "files": [
15
+ "dist",
16
+ "LICENSE",
17
+ "package.json",
18
+ "README.md"
19
+ ],
20
+ "type": "module",
21
+ "types": "./dist/index.d.mts",
22
+ "exports": {
23
+ ".": "./dist/index.mjs",
24
+ "./package.json": "./package.json"
25
+ },
26
+ "engines": {
27
+ "node": ">=22.12.0"
28
+ }
29
+ }