@shware/http 0.2.3 → 0.2.5
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/dist/index.cjs +407 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +269 -0
- package/dist/index.mjs +35 -20
- package/dist/index.mjs.map +1 -0
- package/dist/polyfills/index.cjs +7 -0
- package/dist/polyfills/index.cjs.map +1 -0
- package/dist/polyfills/index.d.ts +2 -0
- package/dist/{polyfills.mjs → polyfills/index.mjs} +2 -0
- package/dist/polyfills/index.mjs.map +1 -0
- package/package.json +15 -7
- /package/dist/{index.d.mts → index.d.cts} +0 -0
- /package/dist/{polyfills.d.mts → polyfills/index.d.cts} +0 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var src_exports = {};
|
|
22
|
+
__export(src_exports, {
|
|
23
|
+
Code: () => Code,
|
|
24
|
+
DEFAULT_MESSAGES: () => DEFAULT_MESSAGES,
|
|
25
|
+
DetailType: () => DetailType,
|
|
26
|
+
Details: () => Details,
|
|
27
|
+
Status: () => Status,
|
|
28
|
+
StatusCode: () => StatusCode,
|
|
29
|
+
StatusError: () => StatusError,
|
|
30
|
+
UidGenerator: () => UidGenerator,
|
|
31
|
+
uid: () => uid,
|
|
32
|
+
valid: () => valid
|
|
33
|
+
});
|
|
34
|
+
module.exports = __toCommonJS(src_exports);
|
|
35
|
+
|
|
36
|
+
// src/detail.ts
|
|
37
|
+
var DetailType = /* @__PURE__ */ ((DetailType2) => {
|
|
38
|
+
DetailType2["ERROR_INFO"] = "ERROR_INFO";
|
|
39
|
+
DetailType2["RETRY_INFO"] = "RETRY_INFO";
|
|
40
|
+
DetailType2["DEBUG_INFO"] = "DEBUG_INFO";
|
|
41
|
+
DetailType2["QUOTA_FAILURE"] = "QUOTA_FAILURE";
|
|
42
|
+
DetailType2["PRECONDITION_FAILURE"] = "PRECONDITION_FAILURE";
|
|
43
|
+
DetailType2["BAD_REQUEST"] = "BAD_REQUEST";
|
|
44
|
+
DetailType2["REQUEST_INFO"] = "REQUEST_INFO";
|
|
45
|
+
DetailType2["RESOURCE_INFO"] = "RESOURCE_INFO";
|
|
46
|
+
DetailType2["HELP"] = "HELP";
|
|
47
|
+
DetailType2["LOCALIZED_MESSAGE"] = "LOCALIZED_MESSAGE";
|
|
48
|
+
return DetailType2;
|
|
49
|
+
})(DetailType || {});
|
|
50
|
+
var Details = class _Details {
|
|
51
|
+
list = [];
|
|
52
|
+
constructor() {
|
|
53
|
+
}
|
|
54
|
+
static new() {
|
|
55
|
+
return new _Details();
|
|
56
|
+
}
|
|
57
|
+
errorInfo(detail) {
|
|
58
|
+
this.list.push({ type: "ERROR_INFO" /* ERROR_INFO */, ...detail });
|
|
59
|
+
return this;
|
|
60
|
+
}
|
|
61
|
+
retryInfo(detail) {
|
|
62
|
+
this.list.push({ type: "RETRY_INFO" /* RETRY_INFO */, ...detail });
|
|
63
|
+
return this;
|
|
64
|
+
}
|
|
65
|
+
debugInfo(detail) {
|
|
66
|
+
this.list.push({ type: "DEBUG_INFO" /* DEBUG_INFO */, ...detail });
|
|
67
|
+
return this;
|
|
68
|
+
}
|
|
69
|
+
quotaFailure(detail) {
|
|
70
|
+
this.list.push({ type: "QUOTA_FAILURE" /* QUOTA_FAILURE */, ...detail });
|
|
71
|
+
return this;
|
|
72
|
+
}
|
|
73
|
+
preconditionFailure(detail) {
|
|
74
|
+
this.list.push({ type: "PRECONDITION_FAILURE" /* PRECONDITION_FAILURE */, ...detail });
|
|
75
|
+
return this;
|
|
76
|
+
}
|
|
77
|
+
badRequest(detail) {
|
|
78
|
+
this.list.push({ type: "BAD_REQUEST" /* BAD_REQUEST */, ...detail });
|
|
79
|
+
return this;
|
|
80
|
+
}
|
|
81
|
+
requestInfo(detail) {
|
|
82
|
+
this.list.push({ type: "REQUEST_INFO" /* REQUEST_INFO */, ...detail });
|
|
83
|
+
return this;
|
|
84
|
+
}
|
|
85
|
+
resourceInfo(detail) {
|
|
86
|
+
this.list.push({ type: "RESOURCE_INFO" /* RESOURCE_INFO */, ...detail });
|
|
87
|
+
return this;
|
|
88
|
+
}
|
|
89
|
+
help(detail) {
|
|
90
|
+
this.list.push({ type: "HELP" /* HELP */, ...detail });
|
|
91
|
+
return this;
|
|
92
|
+
}
|
|
93
|
+
localizedMessage(detail) {
|
|
94
|
+
this.list.push({ type: "LOCALIZED_MESSAGE" /* LOCALIZED_MESSAGE */, ...detail });
|
|
95
|
+
return this;
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
// src/status.ts
|
|
100
|
+
var Code = {
|
|
101
|
+
// Not an error; returned on success
|
|
102
|
+
//
|
|
103
|
+
// HTTP Mapping: 200 OK
|
|
104
|
+
OK: 200,
|
|
105
|
+
// The operation was cancelled, typically by the caller.
|
|
106
|
+
//
|
|
107
|
+
// HTTP Mapping: 499 Client Closed Request
|
|
108
|
+
CANCELLED: 499,
|
|
109
|
+
// Unknown error. For example, this error may be returned when
|
|
110
|
+
// a `Status` value received from another address space belongs to
|
|
111
|
+
// an error space that is not known in this address space. Also,
|
|
112
|
+
// errors raised by APIs that do not return enough error information
|
|
113
|
+
// may be converted to this error.
|
|
114
|
+
//
|
|
115
|
+
// HTTP Mapping: 500 Internal Server Error
|
|
116
|
+
UNKNOWN: 500,
|
|
117
|
+
// The client specified an invalid argument. Note that this differs
|
|
118
|
+
// from `FAILED_PRECONDITION`. `INVALID_ARGUMENT` indicates arguments
|
|
119
|
+
// that are problematic regardless of the state of the system
|
|
120
|
+
// (e.g., a malformed file name).
|
|
121
|
+
//
|
|
122
|
+
// HTTP Mapping: 400 Bad Request
|
|
123
|
+
INVALID_ARGUMENT: 400,
|
|
124
|
+
// The deadline expired before the operation could complete. For operations
|
|
125
|
+
// that change the state of the system, this error may be returned
|
|
126
|
+
// even if the operation has completed successfully. For example, a
|
|
127
|
+
// successful response from a server could have been delayed long
|
|
128
|
+
// enough for the deadline to expire.
|
|
129
|
+
//
|
|
130
|
+
// HTTP Mapping: 504 Gateway Timeout
|
|
131
|
+
DEADLINE_EXCEEDED: 504,
|
|
132
|
+
// Some requested entity (e.g., file or directory) was not found.
|
|
133
|
+
//
|
|
134
|
+
// Note to server developers: if a request is denied for an entire class
|
|
135
|
+
// of users, such as gradual feature rollout or undocumented whitelist,
|
|
136
|
+
// `NOT_FOUND` may be used. If a request is denied for some users within
|
|
137
|
+
// a class of users, such as user-based access control, `PERMISSION_DENIED`
|
|
138
|
+
// must be used.
|
|
139
|
+
//
|
|
140
|
+
// HTTP Mapping: 404 Not Found
|
|
141
|
+
NOT_FOUND: 404,
|
|
142
|
+
// The entity that a client attempted to create (e.g., file or directory)
|
|
143
|
+
// already exists.
|
|
144
|
+
//
|
|
145
|
+
// HTTP Mapping: 409 Conflict
|
|
146
|
+
ALREADY_EXISTS: 409,
|
|
147
|
+
// The caller does not have permission to execute the specified
|
|
148
|
+
// operation. `PERMISSION_DENIED` must not be used for rejections
|
|
149
|
+
// caused by exhausting some resource (use `RESOURCE_EXHAUSTED`
|
|
150
|
+
// instead for those errors). `PERMISSION_DENIED` must not be
|
|
151
|
+
// used if the caller can not be identified (use `UNAUTHENTICATED`
|
|
152
|
+
// instead for those errors). This error code does not imply the
|
|
153
|
+
// request is valid or the requested entity exists or satisfies
|
|
154
|
+
// other pre-conditions.
|
|
155
|
+
//
|
|
156
|
+
// HTTP Mapping: 403 Forbidden
|
|
157
|
+
PERMISSION_DENIED: 403,
|
|
158
|
+
// Some resource has been exhausted, perhaps a per-user quota, or
|
|
159
|
+
// perhaps the entire file system is out of space.
|
|
160
|
+
//
|
|
161
|
+
// HTTP Mapping: 429 Too Many Requests
|
|
162
|
+
RESOURCE_EXHAUSTED: 429,
|
|
163
|
+
// The operation was rejected because the system is not in a state
|
|
164
|
+
// required for the operation's execution. For example, the directory
|
|
165
|
+
// to be deleted is non-empty, a rmdir operation is applied to
|
|
166
|
+
// a non-directory, etc.
|
|
167
|
+
//
|
|
168
|
+
// Service implementors can use the following guidelines to decide
|
|
169
|
+
// between `FAILED_PRECONDITION`, `ABORTED`, and `UNAVAILABLE`:
|
|
170
|
+
// (a) Use `UNAVAILABLE` if the client can retry just the failing call.
|
|
171
|
+
// (b) Use `ABORTED` if the client should retry at a higher level
|
|
172
|
+
// (e.g., when a client-specified test-and-set fails, indicating the
|
|
173
|
+
// client should restart a read-modify-write sequence).
|
|
174
|
+
// (c) Use `FAILED_PRECONDITION` if the client should not retry until
|
|
175
|
+
// the system state has been explicitly fixed. E.g., if a "rmdir"
|
|
176
|
+
// fails because the directory is non-empty, `FAILED_PRECONDITION`
|
|
177
|
+
// should be returned since the client should not retry unless
|
|
178
|
+
// the files are deleted from the directory.
|
|
179
|
+
//
|
|
180
|
+
// HTTP Mapping: 400 Bad Request
|
|
181
|
+
FAILED_PRECONDITION: 400,
|
|
182
|
+
// The operation was aborted, typically due to a concurrency issue such as
|
|
183
|
+
// a sequencer check failure or transaction abort.
|
|
184
|
+
//
|
|
185
|
+
// See the guidelines above for deciding between `FAILED_PRECONDITION`,
|
|
186
|
+
// `ABORTED`, and `UNAVAILABLE`.
|
|
187
|
+
//
|
|
188
|
+
// HTTP Mapping: 409 Conflict
|
|
189
|
+
ABORTED: 409,
|
|
190
|
+
// The operation was attempted past the valid range. E.g., seeking or
|
|
191
|
+
// reading past end-of-file.
|
|
192
|
+
//
|
|
193
|
+
// Unlike `INVALID_ARGUMENT`, this error indicates a problem that may
|
|
194
|
+
// be fixed if the system state changes. For example, a 32-bit file
|
|
195
|
+
// system will generate `INVALID_ARGUMENT` if asked to read at an
|
|
196
|
+
// offset that is not in the range [0,2^32-1], but it will generate
|
|
197
|
+
// `OUT_OF_RANGE` if asked to read from an offset past the current
|
|
198
|
+
// file size.
|
|
199
|
+
//
|
|
200
|
+
// There is a fair bit of overlap between `FAILED_PRECONDITION` and
|
|
201
|
+
// `OUT_OF_RANGE`. We recommend using `OUT_OF_RANGE` (the more specific
|
|
202
|
+
// error) when it applies so that callers who are iterating through
|
|
203
|
+
// a space can easily look for an `OUT_OF_RANGE` error to detect when
|
|
204
|
+
// they are done.
|
|
205
|
+
//
|
|
206
|
+
// HTTP Mapping: 400 Bad Request
|
|
207
|
+
OUT_OF_RANGE: 400,
|
|
208
|
+
// The operation is not implemented or is not supported/enabled in this
|
|
209
|
+
// service.
|
|
210
|
+
//
|
|
211
|
+
// HTTP Mapping: 501 Not Implemented
|
|
212
|
+
UNIMPLEMENTED: 501,
|
|
213
|
+
// Internal errors. This means that some invariants expected by the
|
|
214
|
+
// underlying system have been broken. This error code is reserved
|
|
215
|
+
// for serious errors.
|
|
216
|
+
//
|
|
217
|
+
// HTTP Mapping: 500 Internal Server Error
|
|
218
|
+
INTERNAL: 500,
|
|
219
|
+
// The service is currently unavailable. This is most likely a
|
|
220
|
+
// transient condition, which can be corrected by retrying with
|
|
221
|
+
// a backoff. Note that it is not always safe to retry
|
|
222
|
+
// non-idempotent operations.
|
|
223
|
+
//
|
|
224
|
+
// See the guidelines above for deciding between `FAILED_PRECONDITION`,
|
|
225
|
+
// `ABORTED`, and `UNAVAILABLE`.
|
|
226
|
+
//
|
|
227
|
+
// HTTP Mapping: 503 Service Unavailable
|
|
228
|
+
UNAVAILABLE: 503,
|
|
229
|
+
// Unrecoverable data loss or corruption.
|
|
230
|
+
//
|
|
231
|
+
// HTTP Mapping: 500 Internal Server Error
|
|
232
|
+
DATA_LOSS: 500,
|
|
233
|
+
// The request does not have valid authentication credentials for the
|
|
234
|
+
// operation.
|
|
235
|
+
//
|
|
236
|
+
// HTTP Mapping: 401 Unauthorized
|
|
237
|
+
UNAUTHENTICATED: 401,
|
|
238
|
+
// The request method is not supported by the server and cannot be handled.
|
|
239
|
+
//
|
|
240
|
+
// HTTP Mapping: 405 Method Not Allowed
|
|
241
|
+
METHOD_NOT_ALLOWED: 405
|
|
242
|
+
};
|
|
243
|
+
var DEFAULT_MESSAGES = {
|
|
244
|
+
OK: "OK",
|
|
245
|
+
CANCELLED: "The operation was cancelled",
|
|
246
|
+
UNKNOWN: "Unknown error",
|
|
247
|
+
INVALID_ARGUMENT: "The client specified an invalid argument",
|
|
248
|
+
DEADLINE_EXCEEDED: "The deadline expired before the operation could complete",
|
|
249
|
+
NOT_FOUND: "Some requested entity was not found",
|
|
250
|
+
ALREADY_EXISTS: "The entity that a client attempted to create already exists",
|
|
251
|
+
PERMISSION_DENIED: "The caller does not have permission to execute the specified operation",
|
|
252
|
+
RESOURCE_EXHAUSTED: "Some resource has been exhausted",
|
|
253
|
+
FAILED_PRECONDITION: "The operation was rejected because the system is not in a state required for the operation's execution",
|
|
254
|
+
ABORTED: "The operation was aborted",
|
|
255
|
+
OUT_OF_RANGE: "The operation was attempted past the valid range",
|
|
256
|
+
UNIMPLEMENTED: "The operation is not implemented or is not supported/enabled in this service",
|
|
257
|
+
INTERNAL: "Internal errors",
|
|
258
|
+
UNAVAILABLE: "The service is currently unavailable",
|
|
259
|
+
DATA_LOSS: "Unrecoverable data loss or corruption",
|
|
260
|
+
UNAUTHENTICATED: "The request does not have valid authentication credentials for the operation",
|
|
261
|
+
METHOD_NOT_ALLOWED: "The request method is not supported by the server and cannot be handled"
|
|
262
|
+
};
|
|
263
|
+
var StatusError = class _StatusError extends Error {
|
|
264
|
+
status;
|
|
265
|
+
body;
|
|
266
|
+
constructor(status, body) {
|
|
267
|
+
super(body?.error?.message ?? `Status Error: ${status}`);
|
|
268
|
+
this.name = "StatusError";
|
|
269
|
+
this.status = status;
|
|
270
|
+
this.body = body;
|
|
271
|
+
if (Error.captureStackTrace) {
|
|
272
|
+
Error.captureStackTrace(this, _StatusError);
|
|
273
|
+
}
|
|
274
|
+
Object.setPrototypeOf(this, _StatusError.prototype);
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
var StatusCode = class _StatusCode {
|
|
278
|
+
code;
|
|
279
|
+
message;
|
|
280
|
+
constructor(code, message) {
|
|
281
|
+
this.code = code;
|
|
282
|
+
this.message = message;
|
|
283
|
+
}
|
|
284
|
+
static of(code, message) {
|
|
285
|
+
return new _StatusCode(code, message ?? DEFAULT_MESSAGES[code]);
|
|
286
|
+
}
|
|
287
|
+
body(details) {
|
|
288
|
+
return {
|
|
289
|
+
error: {
|
|
290
|
+
code: Code[this.code],
|
|
291
|
+
status: this.code,
|
|
292
|
+
message: this.message ?? "",
|
|
293
|
+
details: details?.list ?? []
|
|
294
|
+
}
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
error(details) {
|
|
298
|
+
const body = this.body(details);
|
|
299
|
+
if (Status.adapter) return Status.adapter(Code[this.code], body);
|
|
300
|
+
return new StatusError(Code[this.code], body);
|
|
301
|
+
}
|
|
302
|
+
response(details) {
|
|
303
|
+
const body = this.body(details);
|
|
304
|
+
return Response.json(body, { status: body.error.code });
|
|
305
|
+
}
|
|
306
|
+
};
|
|
307
|
+
var Status = class {
|
|
308
|
+
static adapter;
|
|
309
|
+
static ok = (message) => StatusCode.of("OK", message);
|
|
310
|
+
static cancelled = (message) => StatusCode.of("CANCELLED", message);
|
|
311
|
+
static unknown = (message) => StatusCode.of("UNKNOWN", message);
|
|
312
|
+
static invalidArgument = (message) => StatusCode.of("INVALID_ARGUMENT", message);
|
|
313
|
+
static deadlineExceeded = (message) => StatusCode.of("DEADLINE_EXCEEDED", message);
|
|
314
|
+
static notFound = (message) => StatusCode.of("NOT_FOUND", message);
|
|
315
|
+
static alreadyExists = (message) => StatusCode.of("ALREADY_EXISTS", message);
|
|
316
|
+
static permissionDenied = (message) => StatusCode.of("PERMISSION_DENIED", message);
|
|
317
|
+
static unauthorized = (message) => StatusCode.of("UNAUTHENTICATED", message);
|
|
318
|
+
static resourceExhausted = (message) => StatusCode.of("RESOURCE_EXHAUSTED", message);
|
|
319
|
+
static failedPrecondition = (message) => StatusCode.of("FAILED_PRECONDITION", message);
|
|
320
|
+
static aborted = (message) => StatusCode.of("ABORTED", message);
|
|
321
|
+
static outOfRange = (message) => StatusCode.of("OUT_OF_RANGE", message);
|
|
322
|
+
static unimplemented = (message) => StatusCode.of("UNIMPLEMENTED", message);
|
|
323
|
+
static internal = (message) => StatusCode.of("INTERNAL", message);
|
|
324
|
+
static unavailable = (message) => StatusCode.of("UNAVAILABLE", message);
|
|
325
|
+
static dataLoss = (message) => StatusCode.of("DATA_LOSS", message);
|
|
326
|
+
static methodNotAllowed = (message) => StatusCode.of("METHOD_NOT_ALLOWED", message);
|
|
327
|
+
};
|
|
328
|
+
|
|
329
|
+
// src/vaild.ts
|
|
330
|
+
async function getTarget(request, target) {
|
|
331
|
+
switch (target) {
|
|
332
|
+
case "json":
|
|
333
|
+
return request.json();
|
|
334
|
+
default:
|
|
335
|
+
throw new Error(`Unsupported target: ${target}`);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
async function valid(request, target, schema) {
|
|
339
|
+
const value = await getTarget(request, target);
|
|
340
|
+
const validator = await schema.safeParseAsync(value);
|
|
341
|
+
if (validator.success) return { data: validator.data, error: null };
|
|
342
|
+
const fieldViolations = validator.error.issues.map(
|
|
343
|
+
({ path, message }) => ({ field: path.join("."), description: message })
|
|
344
|
+
);
|
|
345
|
+
const details = Details.new().badRequest({ fieldViolations });
|
|
346
|
+
const error = Status.invalidArgument().response(details);
|
|
347
|
+
return { data: null, error };
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// src/snowflake.ts
|
|
351
|
+
function getNextMillisecond(timestamp) {
|
|
352
|
+
let now = BigInt(Date.now());
|
|
353
|
+
while (now < timestamp) {
|
|
354
|
+
now = BigInt(Date.now());
|
|
355
|
+
}
|
|
356
|
+
return now;
|
|
357
|
+
}
|
|
358
|
+
var UidGenerator = class {
|
|
359
|
+
MAX = (1n << 63n) - 1n;
|
|
360
|
+
machineBits = BigInt(10);
|
|
361
|
+
sequenceBits = BigInt(12);
|
|
362
|
+
epochMillisecond = BigInt(1577808e6);
|
|
363
|
+
// 2020-1-1 00:00:00
|
|
364
|
+
sequenceMask = ~(BigInt(-1) << this.sequenceBits);
|
|
365
|
+
maxMachineId = ~(BigInt(-1) << this.machineBits);
|
|
366
|
+
machineIdShift = this.sequenceBits;
|
|
367
|
+
timeStampShift = this.machineBits + this.sequenceBits;
|
|
368
|
+
machineId;
|
|
369
|
+
sequence = BigInt(0);
|
|
370
|
+
lastTimestamp = BigInt(-1);
|
|
371
|
+
constructor(mackineId) {
|
|
372
|
+
this.machineId = BigInt(mackineId) % this.maxMachineId;
|
|
373
|
+
}
|
|
374
|
+
next = () => {
|
|
375
|
+
let timestamp = BigInt(Date.now());
|
|
376
|
+
if (timestamp < this.lastTimestamp) {
|
|
377
|
+
console.error(`Clock moved backwards. time gap = ${this.lastTimestamp - timestamp}`);
|
|
378
|
+
timestamp = getNextMillisecond(this.lastTimestamp);
|
|
379
|
+
}
|
|
380
|
+
if (timestamp === this.lastTimestamp) {
|
|
381
|
+
this.sequence = this.sequence + BigInt(1) & this.sequenceMask;
|
|
382
|
+
if (this.sequence === BigInt(0)) {
|
|
383
|
+
timestamp = getNextMillisecond(timestamp);
|
|
384
|
+
}
|
|
385
|
+
} else {
|
|
386
|
+
this.sequence = BigInt(0);
|
|
387
|
+
}
|
|
388
|
+
this.lastTimestamp = timestamp;
|
|
389
|
+
return timestamp - this.epochMillisecond << this.timeStampShift | this.machineId << this.machineIdShift | this.sequence;
|
|
390
|
+
};
|
|
391
|
+
};
|
|
392
|
+
var machineId = Math.floor(Math.random() * 1024);
|
|
393
|
+
var uid = new UidGenerator(machineId);
|
|
394
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
395
|
+
0 && (module.exports = {
|
|
396
|
+
Code,
|
|
397
|
+
DEFAULT_MESSAGES,
|
|
398
|
+
DetailType,
|
|
399
|
+
Details,
|
|
400
|
+
Status,
|
|
401
|
+
StatusCode,
|
|
402
|
+
StatusError,
|
|
403
|
+
UidGenerator,
|
|
404
|
+
uid,
|
|
405
|
+
valid
|
|
406
|
+
});
|
|
407
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/detail.ts","../src/status.ts","../src/vaild.ts","../src/snowflake.ts"],"sourcesContent":["/**\n * @example\n * import { Details, Status } from '@repo/error';\n *\n * Status.adapter = () => new Error('Error');\n *\n * const details = Details.new()\n * .requestInfo({ requestId: '1234567890', servingData: '/v1/tests' })\n * .errorInfo({ reason: 'ACCOUNT_LOCKED' });\n *\n * throw Status.alreadyExists('xxx').error(details);\n */\n\nexport * from './reason';\nexport * from './detail';\nexport * from './status';\nexport * from './vaild';\nexport * from './snowflake';\n","import type { ErrorReason } from './reason';\n\nexport enum DetailType {\n ERROR_INFO = 'ERROR_INFO',\n RETRY_INFO = 'RETRY_INFO',\n DEBUG_INFO = 'DEBUG_INFO',\n QUOTA_FAILURE = 'QUOTA_FAILURE',\n PRECONDITION_FAILURE = 'PRECONDITION_FAILURE',\n BAD_REQUEST = 'BAD_REQUEST',\n REQUEST_INFO = 'REQUEST_INFO',\n RESOURCE_INFO = 'RESOURCE_INFO',\n HELP = 'HELP',\n LOCALIZED_MESSAGE = 'LOCALIZED_MESSAGE',\n}\n\nexport interface ErrorInfo {\n type: DetailType.ERROR_INFO;\n reason: keyof ErrorReason;\n domain?: string;\n metadata?: { [key: string]: string };\n}\n\nexport interface RetryInfo {\n type: DetailType.RETRY_INFO;\n retryDelay: number;\n}\n\nexport interface DebugInfo {\n type: DetailType.DEBUG_INFO;\n stackEntries: string[];\n detail?: string;\n}\n\nexport interface QuotaFailure {\n type: DetailType.QUOTA_FAILURE;\n violations: { subject: string; description: string }[];\n}\n\nexport interface PreconditionFailure {\n type: DetailType.PRECONDITION_FAILURE;\n violations: { type: string; subject: string; description: string }[];\n}\n\nexport interface BadRequest {\n type: DetailType.BAD_REQUEST;\n fieldViolations: { field: string; description: string }[];\n}\n\nexport interface RequestInfo {\n type: DetailType.REQUEST_INFO;\n requestId: string;\n servingData: string;\n}\n\nexport interface ResourceInfo {\n type: DetailType.RESOURCE_INFO;\n resourceType: string;\n resourceName: string;\n owner: string;\n description: string;\n}\n\nexport interface Help {\n type: DetailType.HELP;\n links: { url: string; description: string }[];\n}\n\nexport interface LocalizedMessage {\n type: DetailType.LOCALIZED_MESSAGE;\n locale: string;\n message: string;\n}\n\nexport type Detail =\n | RetryInfo\n | DebugInfo\n | QuotaFailure\n | ErrorInfo\n | PreconditionFailure\n | BadRequest\n | RequestInfo\n | ResourceInfo\n | Help\n | LocalizedMessage;\n\n/**\n * Example usage:\n * const details = Details.new()\n * .requestInfo({ requestId: '1234567890', servingData: '/v1/tests' })\n * .errorInfo({ reason: 'ACCOUNT_LOCKED' });\n * */\nexport class Details {\n readonly list: Detail[] = [];\n private constructor() {}\n\n static new() {\n return new Details();\n }\n\n errorInfo(detail: Omit<ErrorInfo, 'type'>) {\n this.list.push({ type: DetailType.ERROR_INFO, ...detail });\n return this;\n }\n\n retryInfo(detail: Omit<RetryInfo, 'type'>) {\n this.list.push({ type: DetailType.RETRY_INFO, ...detail });\n return this;\n }\n\n debugInfo(detail: Omit<DebugInfo, 'type'>) {\n this.list.push({ type: DetailType.DEBUG_INFO, ...detail });\n return this;\n }\n\n quotaFailure(detail: Omit<QuotaFailure, 'type'>) {\n this.list.push({ type: DetailType.QUOTA_FAILURE, ...detail });\n return this;\n }\n\n preconditionFailure(detail: Omit<PreconditionFailure, 'type'>) {\n this.list.push({ type: DetailType.PRECONDITION_FAILURE, ...detail });\n return this;\n }\n\n badRequest(detail: Omit<BadRequest, 'type'>) {\n this.list.push({ type: DetailType.BAD_REQUEST, ...detail });\n return this;\n }\n\n requestInfo(detail: Omit<RequestInfo, 'type'>) {\n this.list.push({ type: DetailType.REQUEST_INFO, ...detail });\n return this;\n }\n\n resourceInfo(detail: Omit<ResourceInfo, 'type'>) {\n this.list.push({ type: DetailType.RESOURCE_INFO, ...detail });\n return this;\n }\n\n help(detail: Omit<Help, 'type'>) {\n this.list.push({ type: DetailType.HELP, ...detail });\n return this;\n }\n\n localizedMessage(detail: Omit<LocalizedMessage, 'type'>) {\n this.list.push({ type: DetailType.LOCALIZED_MESSAGE, ...detail });\n return this;\n }\n}\n","import type { Detail, Details } from './detail';\n\nexport const Code = {\n // Not an error; returned on success\n //\n // HTTP Mapping: 200 OK\n OK: 200,\n\n // The operation was cancelled, typically by the caller.\n //\n // HTTP Mapping: 499 Client Closed Request\n CANCELLED: 499,\n\n // Unknown error. For example, this error may be returned when\n // a `Status` value received from another address space belongs to\n // an error space that is not known in this address space. Also,\n // errors raised by APIs that do not return enough error information\n // may be converted to this error.\n //\n // HTTP Mapping: 500 Internal Server Error\n UNKNOWN: 500,\n\n // The client specified an invalid argument. Note that this differs\n // from `FAILED_PRECONDITION`. `INVALID_ARGUMENT` indicates arguments\n // that are problematic regardless of the state of the system\n // (e.g., a malformed file name).\n //\n // HTTP Mapping: 400 Bad Request\n INVALID_ARGUMENT: 400,\n\n // The deadline expired before the operation could complete. For operations\n // that change the state of the system, this error may be returned\n // even if the operation has completed successfully. For example, a\n // successful response from a server could have been delayed long\n // enough for the deadline to expire.\n //\n // HTTP Mapping: 504 Gateway Timeout\n DEADLINE_EXCEEDED: 504,\n\n // Some requested entity (e.g., file or directory) was not found.\n //\n // Note to server developers: if a request is denied for an entire class\n // of users, such as gradual feature rollout or undocumented whitelist,\n // `NOT_FOUND` may be used. If a request is denied for some users within\n // a class of users, such as user-based access control, `PERMISSION_DENIED`\n // must be used.\n //\n // HTTP Mapping: 404 Not Found\n NOT_FOUND: 404,\n\n // The entity that a client attempted to create (e.g., file or directory)\n // already exists.\n //\n // HTTP Mapping: 409 Conflict\n ALREADY_EXISTS: 409,\n\n // The caller does not have permission to execute the specified\n // operation. `PERMISSION_DENIED` must not be used for rejections\n // caused by exhausting some resource (use `RESOURCE_EXHAUSTED`\n // instead for those errors). `PERMISSION_DENIED` must not be\n // used if the caller can not be identified (use `UNAUTHENTICATED`\n // instead for those errors). This error code does not imply the\n // request is valid or the requested entity exists or satisfies\n // other pre-conditions.\n //\n // HTTP Mapping: 403 Forbidden\n PERMISSION_DENIED: 403,\n\n // Some resource has been exhausted, perhaps a per-user quota, or\n // perhaps the entire file system is out of space.\n //\n // HTTP Mapping: 429 Too Many Requests\n RESOURCE_EXHAUSTED: 429,\n\n // The operation was rejected because the system is not in a state\n // required for the operation's execution. For example, the directory\n // to be deleted is non-empty, a rmdir operation is applied to\n // a non-directory, etc.\n //\n // Service implementors can use the following guidelines to decide\n // between `FAILED_PRECONDITION`, `ABORTED`, and `UNAVAILABLE`:\n // (a) Use `UNAVAILABLE` if the client can retry just the failing call.\n // (b) Use `ABORTED` if the client should retry at a higher level\n // (e.g., when a client-specified test-and-set fails, indicating the\n // client should restart a read-modify-write sequence).\n // (c) Use `FAILED_PRECONDITION` if the client should not retry until\n // the system state has been explicitly fixed. E.g., if a \"rmdir\"\n // fails because the directory is non-empty, `FAILED_PRECONDITION`\n // should be returned since the client should not retry unless\n // the files are deleted from the directory.\n //\n // HTTP Mapping: 400 Bad Request\n FAILED_PRECONDITION: 400,\n\n // The operation was aborted, typically due to a concurrency issue such as\n // a sequencer check failure or transaction abort.\n //\n // See the guidelines above for deciding between `FAILED_PRECONDITION`,\n // `ABORTED`, and `UNAVAILABLE`.\n //\n // HTTP Mapping: 409 Conflict\n ABORTED: 409,\n\n // The operation was attempted past the valid range. E.g., seeking or\n // reading past end-of-file.\n //\n // Unlike `INVALID_ARGUMENT`, this error indicates a problem that may\n // be fixed if the system state changes. For example, a 32-bit file\n // system will generate `INVALID_ARGUMENT` if asked to read at an\n // offset that is not in the range [0,2^32-1], but it will generate\n // `OUT_OF_RANGE` if asked to read from an offset past the current\n // file size.\n //\n // There is a fair bit of overlap between `FAILED_PRECONDITION` and\n // `OUT_OF_RANGE`. We recommend using `OUT_OF_RANGE` (the more specific\n // error) when it applies so that callers who are iterating through\n // a space can easily look for an `OUT_OF_RANGE` error to detect when\n // they are done.\n //\n // HTTP Mapping: 400 Bad Request\n OUT_OF_RANGE: 400,\n\n // The operation is not implemented or is not supported/enabled in this\n // service.\n //\n // HTTP Mapping: 501 Not Implemented\n UNIMPLEMENTED: 501,\n\n // Internal errors. This means that some invariants expected by the\n // underlying system have been broken. This error code is reserved\n // for serious errors.\n //\n // HTTP Mapping: 500 Internal Server Error\n INTERNAL: 500,\n\n // The service is currently unavailable. This is most likely a\n // transient condition, which can be corrected by retrying with\n // a backoff. Note that it is not always safe to retry\n // non-idempotent operations.\n //\n // See the guidelines above for deciding between `FAILED_PRECONDITION`,\n // `ABORTED`, and `UNAVAILABLE`.\n //\n // HTTP Mapping: 503 Service Unavailable\n UNAVAILABLE: 503,\n\n // Unrecoverable data loss or corruption.\n //\n // HTTP Mapping: 500 Internal Server Error\n DATA_LOSS: 500,\n\n // The request does not have valid authentication credentials for the\n // operation.\n //\n // HTTP Mapping: 401 Unauthorized\n UNAUTHENTICATED: 401,\n\n // The request method is not supported by the server and cannot be handled.\n //\n // HTTP Mapping: 405 Method Not Allowed\n METHOD_NOT_ALLOWED: 405,\n} as const;\n\nexport const DEFAULT_MESSAGES: Record<keyof typeof Code, string> = {\n OK: 'OK',\n CANCELLED: 'The operation was cancelled',\n UNKNOWN: 'Unknown error',\n INVALID_ARGUMENT: 'The client specified an invalid argument',\n DEADLINE_EXCEEDED: 'The deadline expired before the operation could complete',\n NOT_FOUND: 'Some requested entity was not found',\n ALREADY_EXISTS: 'The entity that a client attempted to create already exists',\n PERMISSION_DENIED: 'The caller does not have permission to execute the specified operation',\n RESOURCE_EXHAUSTED: 'Some resource has been exhausted',\n FAILED_PRECONDITION:\n \"The operation was rejected because the system is not in a state required for the operation's execution\",\n ABORTED: 'The operation was aborted',\n OUT_OF_RANGE: 'The operation was attempted past the valid range',\n UNIMPLEMENTED: 'The operation is not implemented or is not supported/enabled in this service',\n INTERNAL: 'Internal errors',\n UNAVAILABLE: 'The service is currently unavailable',\n DATA_LOSS: 'Unrecoverable data loss or corruption',\n UNAUTHENTICATED: 'The request does not have valid authentication credentials for the operation',\n METHOD_NOT_ALLOWED: 'The request method is not supported by the server and cannot be handled',\n};\n\nexport interface ErrorBody {\n error: {\n code: number;\n status: keyof typeof Code;\n message: string;\n details: Detail[];\n };\n}\n\nexport class StatusError extends Error {\n readonly status: number;\n readonly body?: ErrorBody;\n\n constructor(status: number, body?: ErrorBody) {\n super(body?.error?.message ?? `Status Error: ${status}`);\n this.name = 'StatusError';\n this.status = status;\n this.body = body;\n if ((Error as any).captureStackTrace) {\n (Error as any).captureStackTrace(this, StatusError);\n }\n Object.setPrototypeOf(this, StatusError.prototype);\n }\n}\n\nexport class StatusCode {\n code: keyof typeof Code;\n message?: string;\n private constructor(code: keyof typeof Code, message?: string) {\n this.code = code;\n this.message = message;\n }\n\n static of(code: keyof typeof Code, message?: string) {\n return new StatusCode(code, message ?? DEFAULT_MESSAGES[code]);\n }\n\n body(details?: Details): ErrorBody {\n return {\n error: {\n code: Code[this.code],\n status: this.code,\n message: this.message ?? '',\n details: details?.list ?? [],\n },\n };\n }\n\n error(details?: Details): Error {\n const body = this.body(details);\n if (Status.adapter) return Status.adapter(Code[this.code], body);\n return new StatusError(Code[this.code], body);\n }\n\n response(details?: Details): Response {\n const body = this.body(details);\n return Response.json(body, { status: body.error.code });\n }\n}\n\nexport class Status {\n static adapter?: (status: number, response: ErrorBody) => Error;\n\n static ok = (message?: string) => StatusCode.of('OK', message);\n static cancelled = (message?: string) => StatusCode.of('CANCELLED', message);\n static unknown = (message?: string) => StatusCode.of('UNKNOWN', message);\n static invalidArgument = (message?: string) => StatusCode.of('INVALID_ARGUMENT', message);\n static deadlineExceeded = (message?: string) => StatusCode.of('DEADLINE_EXCEEDED', message);\n static notFound = (message?: string) => StatusCode.of('NOT_FOUND', message);\n static alreadyExists = (message?: string) => StatusCode.of('ALREADY_EXISTS', message);\n static permissionDenied = (message?: string) => StatusCode.of('PERMISSION_DENIED', message);\n static unauthorized = (message?: string) => StatusCode.of('UNAUTHENTICATED', message);\n static resourceExhausted = (message?: string) => StatusCode.of('RESOURCE_EXHAUSTED', message);\n static failedPrecondition = (message?: string) => StatusCode.of('FAILED_PRECONDITION', message);\n static aborted = (message?: string) => StatusCode.of('ABORTED', message);\n static outOfRange = (message?: string) => StatusCode.of('OUT_OF_RANGE', message);\n static unimplemented = (message?: string) => StatusCode.of('UNIMPLEMENTED', message);\n static internal = (message?: string) => StatusCode.of('INTERNAL', message);\n static unavailable = (message?: string) => StatusCode.of('UNAVAILABLE', message);\n static dataLoss = (message?: string) => StatusCode.of('DATA_LOSS', message);\n static methodNotAllowed = (message?: string) => StatusCode.of('METHOD_NOT_ALLOWED', message);\n}\n","import type { z, ZodSchema } from 'zod';\nimport { Details } from './detail';\nimport { BadRequest } from './detail';\nimport { Status } from './status';\n\nexport type Result<S extends ZodSchema> =\n | { data: z.infer<S>; error: null }\n | { data: null; error: Response };\n\ntype Target = 'json' | 'form' | 'query' | 'param' | 'header' | 'cookie';\n\nasync function getTarget(request: Request, target: Target): Promise<any> {\n switch (target) {\n case 'json':\n return request.json();\n default:\n throw new Error(`Unsupported target: ${target}`);\n }\n}\n\nexport async function valid<S extends ZodSchema>(\n request: Request,\n target: Target,\n schema: S\n): Promise<Result<S>> {\n const value = await getTarget(request, target);\n const validator = await schema.safeParseAsync(value);\n if (validator.success) return { data: validator.data, error: null };\n const fieldViolations: BadRequest['fieldViolations'] = validator.error.issues.map(\n ({ path, message }) => ({ field: path.join('.'), description: message })\n );\n const details = Details.new().badRequest({ fieldViolations });\n const error = Status.invalidArgument().response(details);\n return { data: null, error };\n}\n","/**\n * A distributed unique ID generator inspired by Twitter's Snowflake.\n *\n * ID data bits:\n * +----------------------+----------------+-----------+\n * | delta millisecond | machine id | sequence |\n * +----------------------+----------------+-----------+\n * | 41bits | 10bits | 12bits |\n * +----------------------+----------------+-----------+\n *\n */\n\nfunction getNextMillisecond(timestamp: bigint) {\n let now = BigInt(Date.now());\n while (now < timestamp) {\n now = BigInt(Date.now());\n }\n return now;\n}\n\nexport class UidGenerator {\n public readonly MAX = (1n << 63n) - 1n;\n private readonly machineBits = BigInt(10);\n private readonly sequenceBits = BigInt(12);\n private readonly epochMillisecond = BigInt(1577808000000); // 2020-1-1 00:00:00\n private readonly sequenceMask = ~(BigInt(-1) << this.sequenceBits);\n private readonly maxMachineId = ~(BigInt(-1) << this.machineBits);\n private readonly machineIdShift = this.sequenceBits;\n private readonly timeStampShift = this.machineBits + this.sequenceBits;\n private readonly machineId: bigint;\n private sequence = BigInt(0);\n private lastTimestamp = BigInt(-1);\n\n constructor(mackineId: number) {\n this.machineId = BigInt(mackineId) % this.maxMachineId;\n }\n\n public readonly next = (): bigint => {\n let timestamp = BigInt(Date.now());\n if (timestamp < this.lastTimestamp) {\n console.error(`Clock moved backwards. time gap = ${this.lastTimestamp - timestamp}`);\n timestamp = getNextMillisecond(this.lastTimestamp);\n }\n if (timestamp === this.lastTimestamp) {\n this.sequence = (this.sequence + BigInt(1)) & this.sequenceMask;\n if (this.sequence === BigInt(0)) {\n timestamp = getNextMillisecond(timestamp);\n }\n } else {\n this.sequence = BigInt(0);\n }\n this.lastTimestamp = timestamp;\n return (\n ((timestamp - this.epochMillisecond) << this.timeStampShift) |\n (this.machineId << this.machineIdShift) |\n this.sequence\n );\n };\n}\n\nconst machineId = Math.floor(Math.random() * 1024);\nexport const uid = new UidGenerator(machineId);\n"],"mappings":"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","names":["DetailType"]}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
import { ZodSchema, z } from 'zod';
|
|
2
|
+
|
|
3
|
+
interface NetworkErrorReason {
|
|
4
|
+
DNS_ERROR: string;
|
|
5
|
+
MISCONFIGURATION: string;
|
|
6
|
+
CONNECTION_ERROR: string;
|
|
7
|
+
}
|
|
8
|
+
interface StatusErrorReason {
|
|
9
|
+
OK: string;
|
|
10
|
+
CANCELLED: string;
|
|
11
|
+
UNKNOWN: string;
|
|
12
|
+
INVALID_ARGUMENT: string;
|
|
13
|
+
DEADLINE_EXCEEDED: string;
|
|
14
|
+
NOT_FOUND: string;
|
|
15
|
+
ALREADY_EXISTS: string;
|
|
16
|
+
PERMISSION_DENIED: string;
|
|
17
|
+
RESOURCE_EXHAUSTED: string;
|
|
18
|
+
FAILED_PRECONDITION: string;
|
|
19
|
+
ABORTED: string;
|
|
20
|
+
OUT_OF_RANGE: string;
|
|
21
|
+
UNIMPLEMENTED: string;
|
|
22
|
+
INTERNAL: string;
|
|
23
|
+
UNAVAILABLE: string;
|
|
24
|
+
DATA_LOSS: string;
|
|
25
|
+
UNAUTHENTICATED: string;
|
|
26
|
+
}
|
|
27
|
+
interface AuthenticationErrorReason {
|
|
28
|
+
ACCOUNT_LOCKED: string;
|
|
29
|
+
ACCOUNT_EXPIRED: string;
|
|
30
|
+
ACCOUNT_INACTIVE: string;
|
|
31
|
+
ACCOUNT_DISABLED: string;
|
|
32
|
+
ACCOUNT_SUSPENDED: string;
|
|
33
|
+
ACCESS_DENIED: string;
|
|
34
|
+
ACCESS_TOKEN_REQUIRED: string;
|
|
35
|
+
PASSWORD_MISMATCH: string;
|
|
36
|
+
USERNAME_ALREADY_EXISTS: string;
|
|
37
|
+
VERIFICATION_CODE_MISMATCH: string;
|
|
38
|
+
VERIFICATION_CODE_SEND_FAILED: string;
|
|
39
|
+
}
|
|
40
|
+
interface ModerationErrorReason {
|
|
41
|
+
POSSIBLY_SENSITIVE: string;
|
|
42
|
+
ADULT_CONTENT: string;
|
|
43
|
+
NUDITY_CONTENT: string;
|
|
44
|
+
SEXUAL_CONTENT: string;
|
|
45
|
+
BLOODY_CONTENT: string;
|
|
46
|
+
WEAPON_CONTENT: string;
|
|
47
|
+
POLITICS_CONTENT: string;
|
|
48
|
+
VIOLENCE_CONTENT: string;
|
|
49
|
+
ABUSE_CONTENT: string;
|
|
50
|
+
ADVERTISEMENT_CONTENT: string;
|
|
51
|
+
CONTRABAND_CONTENT: string;
|
|
52
|
+
SPAM_CONTENT: string;
|
|
53
|
+
MEANINGLESS_CONTENT: string;
|
|
54
|
+
UNSAFE_TEXT_DETECTED: string;
|
|
55
|
+
}
|
|
56
|
+
interface MultipartErrorReason {
|
|
57
|
+
MAX_UPLOAD_SIZE_EXCEEDED: string;
|
|
58
|
+
MEDIA_TYPE_NOT_SUPPORTED: string;
|
|
59
|
+
MEDIA_TYPE_NOT_ACCEPTABLE: string;
|
|
60
|
+
}
|
|
61
|
+
interface AppErrorReason {
|
|
62
|
+
NOT_SUBSCRIBED: string;
|
|
63
|
+
CREDIT_NOT_ENOUGH: string;
|
|
64
|
+
ALREADY_SUBSCRIBED_AT_OTHER_PLATFORM: string;
|
|
65
|
+
}
|
|
66
|
+
type ErrorReason = NetworkErrorReason & StatusErrorReason & AuthenticationErrorReason & ModerationErrorReason & MultipartErrorReason & AppErrorReason;
|
|
67
|
+
|
|
68
|
+
declare enum DetailType {
|
|
69
|
+
ERROR_INFO = "ERROR_INFO",
|
|
70
|
+
RETRY_INFO = "RETRY_INFO",
|
|
71
|
+
DEBUG_INFO = "DEBUG_INFO",
|
|
72
|
+
QUOTA_FAILURE = "QUOTA_FAILURE",
|
|
73
|
+
PRECONDITION_FAILURE = "PRECONDITION_FAILURE",
|
|
74
|
+
BAD_REQUEST = "BAD_REQUEST",
|
|
75
|
+
REQUEST_INFO = "REQUEST_INFO",
|
|
76
|
+
RESOURCE_INFO = "RESOURCE_INFO",
|
|
77
|
+
HELP = "HELP",
|
|
78
|
+
LOCALIZED_MESSAGE = "LOCALIZED_MESSAGE"
|
|
79
|
+
}
|
|
80
|
+
interface ErrorInfo {
|
|
81
|
+
type: DetailType.ERROR_INFO;
|
|
82
|
+
reason: keyof ErrorReason;
|
|
83
|
+
domain?: string;
|
|
84
|
+
metadata?: {
|
|
85
|
+
[key: string]: string;
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
interface RetryInfo {
|
|
89
|
+
type: DetailType.RETRY_INFO;
|
|
90
|
+
retryDelay: number;
|
|
91
|
+
}
|
|
92
|
+
interface DebugInfo {
|
|
93
|
+
type: DetailType.DEBUG_INFO;
|
|
94
|
+
stackEntries: string[];
|
|
95
|
+
detail?: string;
|
|
96
|
+
}
|
|
97
|
+
interface QuotaFailure {
|
|
98
|
+
type: DetailType.QUOTA_FAILURE;
|
|
99
|
+
violations: {
|
|
100
|
+
subject: string;
|
|
101
|
+
description: string;
|
|
102
|
+
}[];
|
|
103
|
+
}
|
|
104
|
+
interface PreconditionFailure {
|
|
105
|
+
type: DetailType.PRECONDITION_FAILURE;
|
|
106
|
+
violations: {
|
|
107
|
+
type: string;
|
|
108
|
+
subject: string;
|
|
109
|
+
description: string;
|
|
110
|
+
}[];
|
|
111
|
+
}
|
|
112
|
+
interface BadRequest {
|
|
113
|
+
type: DetailType.BAD_REQUEST;
|
|
114
|
+
fieldViolations: {
|
|
115
|
+
field: string;
|
|
116
|
+
description: string;
|
|
117
|
+
}[];
|
|
118
|
+
}
|
|
119
|
+
interface RequestInfo {
|
|
120
|
+
type: DetailType.REQUEST_INFO;
|
|
121
|
+
requestId: string;
|
|
122
|
+
servingData: string;
|
|
123
|
+
}
|
|
124
|
+
interface ResourceInfo {
|
|
125
|
+
type: DetailType.RESOURCE_INFO;
|
|
126
|
+
resourceType: string;
|
|
127
|
+
resourceName: string;
|
|
128
|
+
owner: string;
|
|
129
|
+
description: string;
|
|
130
|
+
}
|
|
131
|
+
interface Help {
|
|
132
|
+
type: DetailType.HELP;
|
|
133
|
+
links: {
|
|
134
|
+
url: string;
|
|
135
|
+
description: string;
|
|
136
|
+
}[];
|
|
137
|
+
}
|
|
138
|
+
interface LocalizedMessage {
|
|
139
|
+
type: DetailType.LOCALIZED_MESSAGE;
|
|
140
|
+
locale: string;
|
|
141
|
+
message: string;
|
|
142
|
+
}
|
|
143
|
+
type Detail = RetryInfo | DebugInfo | QuotaFailure | ErrorInfo | PreconditionFailure | BadRequest | RequestInfo | ResourceInfo | Help | LocalizedMessage;
|
|
144
|
+
/**
|
|
145
|
+
* Example usage:
|
|
146
|
+
* const details = Details.new()
|
|
147
|
+
* .requestInfo({ requestId: '1234567890', servingData: '/v1/tests' })
|
|
148
|
+
* .errorInfo({ reason: 'ACCOUNT_LOCKED' });
|
|
149
|
+
* */
|
|
150
|
+
declare class Details {
|
|
151
|
+
readonly list: Detail[];
|
|
152
|
+
private constructor();
|
|
153
|
+
static new(): Details;
|
|
154
|
+
errorInfo(detail: Omit<ErrorInfo, 'type'>): this;
|
|
155
|
+
retryInfo(detail: Omit<RetryInfo, 'type'>): this;
|
|
156
|
+
debugInfo(detail: Omit<DebugInfo, 'type'>): this;
|
|
157
|
+
quotaFailure(detail: Omit<QuotaFailure, 'type'>): this;
|
|
158
|
+
preconditionFailure(detail: Omit<PreconditionFailure, 'type'>): this;
|
|
159
|
+
badRequest(detail: Omit<BadRequest, 'type'>): this;
|
|
160
|
+
requestInfo(detail: Omit<RequestInfo, 'type'>): this;
|
|
161
|
+
resourceInfo(detail: Omit<ResourceInfo, 'type'>): this;
|
|
162
|
+
help(detail: Omit<Help, 'type'>): this;
|
|
163
|
+
localizedMessage(detail: Omit<LocalizedMessage, 'type'>): this;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
declare const Code: {
|
|
167
|
+
readonly OK: 200;
|
|
168
|
+
readonly CANCELLED: 499;
|
|
169
|
+
readonly UNKNOWN: 500;
|
|
170
|
+
readonly INVALID_ARGUMENT: 400;
|
|
171
|
+
readonly DEADLINE_EXCEEDED: 504;
|
|
172
|
+
readonly NOT_FOUND: 404;
|
|
173
|
+
readonly ALREADY_EXISTS: 409;
|
|
174
|
+
readonly PERMISSION_DENIED: 403;
|
|
175
|
+
readonly RESOURCE_EXHAUSTED: 429;
|
|
176
|
+
readonly FAILED_PRECONDITION: 400;
|
|
177
|
+
readonly ABORTED: 409;
|
|
178
|
+
readonly OUT_OF_RANGE: 400;
|
|
179
|
+
readonly UNIMPLEMENTED: 501;
|
|
180
|
+
readonly INTERNAL: 500;
|
|
181
|
+
readonly UNAVAILABLE: 503;
|
|
182
|
+
readonly DATA_LOSS: 500;
|
|
183
|
+
readonly UNAUTHENTICATED: 401;
|
|
184
|
+
readonly METHOD_NOT_ALLOWED: 405;
|
|
185
|
+
};
|
|
186
|
+
declare const DEFAULT_MESSAGES: Record<keyof typeof Code, string>;
|
|
187
|
+
interface ErrorBody {
|
|
188
|
+
error: {
|
|
189
|
+
code: number;
|
|
190
|
+
status: keyof typeof Code;
|
|
191
|
+
message: string;
|
|
192
|
+
details: Detail[];
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
declare class StatusError extends Error {
|
|
196
|
+
readonly status: number;
|
|
197
|
+
readonly body?: ErrorBody;
|
|
198
|
+
constructor(status: number, body?: ErrorBody);
|
|
199
|
+
}
|
|
200
|
+
declare class StatusCode {
|
|
201
|
+
code: keyof typeof Code;
|
|
202
|
+
message?: string;
|
|
203
|
+
private constructor();
|
|
204
|
+
static of(code: keyof typeof Code, message?: string): StatusCode;
|
|
205
|
+
body(details?: Details): ErrorBody;
|
|
206
|
+
error(details?: Details): Error;
|
|
207
|
+
response(details?: Details): Response;
|
|
208
|
+
}
|
|
209
|
+
declare class Status {
|
|
210
|
+
static adapter?: (status: number, response: ErrorBody) => Error;
|
|
211
|
+
static ok: (message?: string) => StatusCode;
|
|
212
|
+
static cancelled: (message?: string) => StatusCode;
|
|
213
|
+
static unknown: (message?: string) => StatusCode;
|
|
214
|
+
static invalidArgument: (message?: string) => StatusCode;
|
|
215
|
+
static deadlineExceeded: (message?: string) => StatusCode;
|
|
216
|
+
static notFound: (message?: string) => StatusCode;
|
|
217
|
+
static alreadyExists: (message?: string) => StatusCode;
|
|
218
|
+
static permissionDenied: (message?: string) => StatusCode;
|
|
219
|
+
static unauthorized: (message?: string) => StatusCode;
|
|
220
|
+
static resourceExhausted: (message?: string) => StatusCode;
|
|
221
|
+
static failedPrecondition: (message?: string) => StatusCode;
|
|
222
|
+
static aborted: (message?: string) => StatusCode;
|
|
223
|
+
static outOfRange: (message?: string) => StatusCode;
|
|
224
|
+
static unimplemented: (message?: string) => StatusCode;
|
|
225
|
+
static internal: (message?: string) => StatusCode;
|
|
226
|
+
static unavailable: (message?: string) => StatusCode;
|
|
227
|
+
static dataLoss: (message?: string) => StatusCode;
|
|
228
|
+
static methodNotAllowed: (message?: string) => StatusCode;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
type Result<S extends ZodSchema> = {
|
|
232
|
+
data: z.infer<S>;
|
|
233
|
+
error: null;
|
|
234
|
+
} | {
|
|
235
|
+
data: null;
|
|
236
|
+
error: Response;
|
|
237
|
+
};
|
|
238
|
+
type Target = 'json' | 'form' | 'query' | 'param' | 'header' | 'cookie';
|
|
239
|
+
declare function valid<S extends ZodSchema>(request: Request, target: Target, schema: S): Promise<Result<S>>;
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* A distributed unique ID generator inspired by Twitter's Snowflake.
|
|
243
|
+
*
|
|
244
|
+
* ID data bits:
|
|
245
|
+
* +----------------------+----------------+-----------+
|
|
246
|
+
* | delta millisecond | machine id | sequence |
|
|
247
|
+
* +----------------------+----------------+-----------+
|
|
248
|
+
* | 41bits | 10bits | 12bits |
|
|
249
|
+
* +----------------------+----------------+-----------+
|
|
250
|
+
*
|
|
251
|
+
*/
|
|
252
|
+
declare class UidGenerator {
|
|
253
|
+
readonly MAX: bigint;
|
|
254
|
+
private readonly machineBits;
|
|
255
|
+
private readonly sequenceBits;
|
|
256
|
+
private readonly epochMillisecond;
|
|
257
|
+
private readonly sequenceMask;
|
|
258
|
+
private readonly maxMachineId;
|
|
259
|
+
private readonly machineIdShift;
|
|
260
|
+
private readonly timeStampShift;
|
|
261
|
+
private readonly machineId;
|
|
262
|
+
private sequence;
|
|
263
|
+
private lastTimestamp;
|
|
264
|
+
constructor(mackineId: number);
|
|
265
|
+
readonly next: () => bigint;
|
|
266
|
+
}
|
|
267
|
+
declare const uid: UidGenerator;
|
|
268
|
+
|
|
269
|
+
export { type AppErrorReason, type AuthenticationErrorReason, type BadRequest, Code, DEFAULT_MESSAGES, type DebugInfo, type Detail, DetailType, Details, type ErrorBody, type ErrorInfo, type ErrorReason, type Help, type LocalizedMessage, type ModerationErrorReason, type MultipartErrorReason, type NetworkErrorReason, type PreconditionFailure, type QuotaFailure, type RequestInfo, type ResourceInfo, type Result, type RetryInfo, Status, StatusCode, StatusError, type StatusErrorReason, UidGenerator, uid, valid };
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// src/detail.ts
|
|
1
2
|
var DetailType = /* @__PURE__ */ ((DetailType2) => {
|
|
2
3
|
DetailType2["ERROR_INFO"] = "ERROR_INFO";
|
|
3
4
|
DetailType2["RETRY_INFO"] = "RETRY_INFO";
|
|
@@ -11,12 +12,12 @@ var DetailType = /* @__PURE__ */ ((DetailType2) => {
|
|
|
11
12
|
DetailType2["LOCALIZED_MESSAGE"] = "LOCALIZED_MESSAGE";
|
|
12
13
|
return DetailType2;
|
|
13
14
|
})(DetailType || {});
|
|
14
|
-
|
|
15
|
+
var Details = class _Details {
|
|
15
16
|
list = [];
|
|
16
17
|
constructor() {
|
|
17
18
|
}
|
|
18
19
|
static new() {
|
|
19
|
-
return new
|
|
20
|
+
return new _Details();
|
|
20
21
|
}
|
|
21
22
|
errorInfo(detail) {
|
|
22
23
|
this.list.push({ type: "ERROR_INFO" /* ERROR_INFO */, ...detail });
|
|
@@ -58,9 +59,10 @@ class Details {
|
|
|
58
59
|
this.list.push({ type: "LOCALIZED_MESSAGE" /* LOCALIZED_MESSAGE */, ...detail });
|
|
59
60
|
return this;
|
|
60
61
|
}
|
|
61
|
-
}
|
|
62
|
+
};
|
|
62
63
|
|
|
63
|
-
|
|
64
|
+
// src/status.ts
|
|
65
|
+
var Code = {
|
|
64
66
|
// Not an error; returned on success
|
|
65
67
|
//
|
|
66
68
|
// HTTP Mapping: 200 OK
|
|
@@ -203,7 +205,7 @@ const Code = {
|
|
|
203
205
|
// HTTP Mapping: 405 Method Not Allowed
|
|
204
206
|
METHOD_NOT_ALLOWED: 405
|
|
205
207
|
};
|
|
206
|
-
|
|
208
|
+
var DEFAULT_MESSAGES = {
|
|
207
209
|
OK: "OK",
|
|
208
210
|
CANCELLED: "The operation was cancelled",
|
|
209
211
|
UNKNOWN: "Unknown error",
|
|
@@ -223,7 +225,7 @@ const DEFAULT_MESSAGES = {
|
|
|
223
225
|
UNAUTHENTICATED: "The request does not have valid authentication credentials for the operation",
|
|
224
226
|
METHOD_NOT_ALLOWED: "The request method is not supported by the server and cannot be handled"
|
|
225
227
|
};
|
|
226
|
-
|
|
228
|
+
var StatusError = class _StatusError extends Error {
|
|
227
229
|
status;
|
|
228
230
|
body;
|
|
229
231
|
constructor(status, body) {
|
|
@@ -232,12 +234,12 @@ class StatusError extends Error {
|
|
|
232
234
|
this.status = status;
|
|
233
235
|
this.body = body;
|
|
234
236
|
if (Error.captureStackTrace) {
|
|
235
|
-
Error.captureStackTrace(this,
|
|
237
|
+
Error.captureStackTrace(this, _StatusError);
|
|
236
238
|
}
|
|
237
|
-
Object.setPrototypeOf(this,
|
|
239
|
+
Object.setPrototypeOf(this, _StatusError.prototype);
|
|
238
240
|
}
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
+
};
|
|
242
|
+
var StatusCode = class _StatusCode {
|
|
241
243
|
code;
|
|
242
244
|
message;
|
|
243
245
|
constructor(code, message) {
|
|
@@ -245,7 +247,7 @@ class StatusCode {
|
|
|
245
247
|
this.message = message;
|
|
246
248
|
}
|
|
247
249
|
static of(code, message) {
|
|
248
|
-
return new
|
|
250
|
+
return new _StatusCode(code, message ?? DEFAULT_MESSAGES[code]);
|
|
249
251
|
}
|
|
250
252
|
body(details) {
|
|
251
253
|
return {
|
|
@@ -266,8 +268,8 @@ class StatusCode {
|
|
|
266
268
|
const body = this.body(details);
|
|
267
269
|
return Response.json(body, { status: body.error.code });
|
|
268
270
|
}
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
+
};
|
|
272
|
+
var Status = class {
|
|
271
273
|
static adapter;
|
|
272
274
|
static ok = (message) => StatusCode.of("OK", message);
|
|
273
275
|
static cancelled = (message) => StatusCode.of("CANCELLED", message);
|
|
@@ -287,8 +289,9 @@ class Status {
|
|
|
287
289
|
static unavailable = (message) => StatusCode.of("UNAVAILABLE", message);
|
|
288
290
|
static dataLoss = (message) => StatusCode.of("DATA_LOSS", message);
|
|
289
291
|
static methodNotAllowed = (message) => StatusCode.of("METHOD_NOT_ALLOWED", message);
|
|
290
|
-
}
|
|
292
|
+
};
|
|
291
293
|
|
|
294
|
+
// src/vaild.ts
|
|
292
295
|
async function getTarget(request, target) {
|
|
293
296
|
switch (target) {
|
|
294
297
|
case "json":
|
|
@@ -309,6 +312,7 @@ async function valid(request, target, schema) {
|
|
|
309
312
|
return { data: null, error };
|
|
310
313
|
}
|
|
311
314
|
|
|
315
|
+
// src/snowflake.ts
|
|
312
316
|
function getNextMillisecond(timestamp) {
|
|
313
317
|
let now = BigInt(Date.now());
|
|
314
318
|
while (now < timestamp) {
|
|
@@ -316,7 +320,7 @@ function getNextMillisecond(timestamp) {
|
|
|
316
320
|
}
|
|
317
321
|
return now;
|
|
318
322
|
}
|
|
319
|
-
|
|
323
|
+
var UidGenerator = class {
|
|
320
324
|
MAX = (1n << 63n) - 1n;
|
|
321
325
|
machineBits = BigInt(10);
|
|
322
326
|
sequenceBits = BigInt(12);
|
|
@@ -349,8 +353,19 @@ class UidGenerator {
|
|
|
349
353
|
this.lastTimestamp = timestamp;
|
|
350
354
|
return timestamp - this.epochMillisecond << this.timeStampShift | this.machineId << this.machineIdShift | this.sequence;
|
|
351
355
|
};
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
356
|
+
};
|
|
357
|
+
var machineId = Math.floor(Math.random() * 1024);
|
|
358
|
+
var uid = new UidGenerator(machineId);
|
|
359
|
+
export {
|
|
360
|
+
Code,
|
|
361
|
+
DEFAULT_MESSAGES,
|
|
362
|
+
DetailType,
|
|
363
|
+
Details,
|
|
364
|
+
Status,
|
|
365
|
+
StatusCode,
|
|
366
|
+
StatusError,
|
|
367
|
+
UidGenerator,
|
|
368
|
+
uid,
|
|
369
|
+
valid
|
|
370
|
+
};
|
|
371
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/detail.ts","../src/status.ts","../src/vaild.ts","../src/snowflake.ts"],"sourcesContent":["import type { ErrorReason } from './reason';\n\nexport enum DetailType {\n ERROR_INFO = 'ERROR_INFO',\n RETRY_INFO = 'RETRY_INFO',\n DEBUG_INFO = 'DEBUG_INFO',\n QUOTA_FAILURE = 'QUOTA_FAILURE',\n PRECONDITION_FAILURE = 'PRECONDITION_FAILURE',\n BAD_REQUEST = 'BAD_REQUEST',\n REQUEST_INFO = 'REQUEST_INFO',\n RESOURCE_INFO = 'RESOURCE_INFO',\n HELP = 'HELP',\n LOCALIZED_MESSAGE = 'LOCALIZED_MESSAGE',\n}\n\nexport interface ErrorInfo {\n type: DetailType.ERROR_INFO;\n reason: keyof ErrorReason;\n domain?: string;\n metadata?: { [key: string]: string };\n}\n\nexport interface RetryInfo {\n type: DetailType.RETRY_INFO;\n retryDelay: number;\n}\n\nexport interface DebugInfo {\n type: DetailType.DEBUG_INFO;\n stackEntries: string[];\n detail?: string;\n}\n\nexport interface QuotaFailure {\n type: DetailType.QUOTA_FAILURE;\n violations: { subject: string; description: string }[];\n}\n\nexport interface PreconditionFailure {\n type: DetailType.PRECONDITION_FAILURE;\n violations: { type: string; subject: string; description: string }[];\n}\n\nexport interface BadRequest {\n type: DetailType.BAD_REQUEST;\n fieldViolations: { field: string; description: string }[];\n}\n\nexport interface RequestInfo {\n type: DetailType.REQUEST_INFO;\n requestId: string;\n servingData: string;\n}\n\nexport interface ResourceInfo {\n type: DetailType.RESOURCE_INFO;\n resourceType: string;\n resourceName: string;\n owner: string;\n description: string;\n}\n\nexport interface Help {\n type: DetailType.HELP;\n links: { url: string; description: string }[];\n}\n\nexport interface LocalizedMessage {\n type: DetailType.LOCALIZED_MESSAGE;\n locale: string;\n message: string;\n}\n\nexport type Detail =\n | RetryInfo\n | DebugInfo\n | QuotaFailure\n | ErrorInfo\n | PreconditionFailure\n | BadRequest\n | RequestInfo\n | ResourceInfo\n | Help\n | LocalizedMessage;\n\n/**\n * Example usage:\n * const details = Details.new()\n * .requestInfo({ requestId: '1234567890', servingData: '/v1/tests' })\n * .errorInfo({ reason: 'ACCOUNT_LOCKED' });\n * */\nexport class Details {\n readonly list: Detail[] = [];\n private constructor() {}\n\n static new() {\n return new Details();\n }\n\n errorInfo(detail: Omit<ErrorInfo, 'type'>) {\n this.list.push({ type: DetailType.ERROR_INFO, ...detail });\n return this;\n }\n\n retryInfo(detail: Omit<RetryInfo, 'type'>) {\n this.list.push({ type: DetailType.RETRY_INFO, ...detail });\n return this;\n }\n\n debugInfo(detail: Omit<DebugInfo, 'type'>) {\n this.list.push({ type: DetailType.DEBUG_INFO, ...detail });\n return this;\n }\n\n quotaFailure(detail: Omit<QuotaFailure, 'type'>) {\n this.list.push({ type: DetailType.QUOTA_FAILURE, ...detail });\n return this;\n }\n\n preconditionFailure(detail: Omit<PreconditionFailure, 'type'>) {\n this.list.push({ type: DetailType.PRECONDITION_FAILURE, ...detail });\n return this;\n }\n\n badRequest(detail: Omit<BadRequest, 'type'>) {\n this.list.push({ type: DetailType.BAD_REQUEST, ...detail });\n return this;\n }\n\n requestInfo(detail: Omit<RequestInfo, 'type'>) {\n this.list.push({ type: DetailType.REQUEST_INFO, ...detail });\n return this;\n }\n\n resourceInfo(detail: Omit<ResourceInfo, 'type'>) {\n this.list.push({ type: DetailType.RESOURCE_INFO, ...detail });\n return this;\n }\n\n help(detail: Omit<Help, 'type'>) {\n this.list.push({ type: DetailType.HELP, ...detail });\n return this;\n }\n\n localizedMessage(detail: Omit<LocalizedMessage, 'type'>) {\n this.list.push({ type: DetailType.LOCALIZED_MESSAGE, ...detail });\n return this;\n }\n}\n","import type { Detail, Details } from './detail';\n\nexport const Code = {\n // Not an error; returned on success\n //\n // HTTP Mapping: 200 OK\n OK: 200,\n\n // The operation was cancelled, typically by the caller.\n //\n // HTTP Mapping: 499 Client Closed Request\n CANCELLED: 499,\n\n // Unknown error. For example, this error may be returned when\n // a `Status` value received from another address space belongs to\n // an error space that is not known in this address space. Also,\n // errors raised by APIs that do not return enough error information\n // may be converted to this error.\n //\n // HTTP Mapping: 500 Internal Server Error\n UNKNOWN: 500,\n\n // The client specified an invalid argument. Note that this differs\n // from `FAILED_PRECONDITION`. `INVALID_ARGUMENT` indicates arguments\n // that are problematic regardless of the state of the system\n // (e.g., a malformed file name).\n //\n // HTTP Mapping: 400 Bad Request\n INVALID_ARGUMENT: 400,\n\n // The deadline expired before the operation could complete. For operations\n // that change the state of the system, this error may be returned\n // even if the operation has completed successfully. For example, a\n // successful response from a server could have been delayed long\n // enough for the deadline to expire.\n //\n // HTTP Mapping: 504 Gateway Timeout\n DEADLINE_EXCEEDED: 504,\n\n // Some requested entity (e.g., file or directory) was not found.\n //\n // Note to server developers: if a request is denied for an entire class\n // of users, such as gradual feature rollout or undocumented whitelist,\n // `NOT_FOUND` may be used. If a request is denied for some users within\n // a class of users, such as user-based access control, `PERMISSION_DENIED`\n // must be used.\n //\n // HTTP Mapping: 404 Not Found\n NOT_FOUND: 404,\n\n // The entity that a client attempted to create (e.g., file or directory)\n // already exists.\n //\n // HTTP Mapping: 409 Conflict\n ALREADY_EXISTS: 409,\n\n // The caller does not have permission to execute the specified\n // operation. `PERMISSION_DENIED` must not be used for rejections\n // caused by exhausting some resource (use `RESOURCE_EXHAUSTED`\n // instead for those errors). `PERMISSION_DENIED` must not be\n // used if the caller can not be identified (use `UNAUTHENTICATED`\n // instead for those errors). This error code does not imply the\n // request is valid or the requested entity exists or satisfies\n // other pre-conditions.\n //\n // HTTP Mapping: 403 Forbidden\n PERMISSION_DENIED: 403,\n\n // Some resource has been exhausted, perhaps a per-user quota, or\n // perhaps the entire file system is out of space.\n //\n // HTTP Mapping: 429 Too Many Requests\n RESOURCE_EXHAUSTED: 429,\n\n // The operation was rejected because the system is not in a state\n // required for the operation's execution. For example, the directory\n // to be deleted is non-empty, a rmdir operation is applied to\n // a non-directory, etc.\n //\n // Service implementors can use the following guidelines to decide\n // between `FAILED_PRECONDITION`, `ABORTED`, and `UNAVAILABLE`:\n // (a) Use `UNAVAILABLE` if the client can retry just the failing call.\n // (b) Use `ABORTED` if the client should retry at a higher level\n // (e.g., when a client-specified test-and-set fails, indicating the\n // client should restart a read-modify-write sequence).\n // (c) Use `FAILED_PRECONDITION` if the client should not retry until\n // the system state has been explicitly fixed. E.g., if a \"rmdir\"\n // fails because the directory is non-empty, `FAILED_PRECONDITION`\n // should be returned since the client should not retry unless\n // the files are deleted from the directory.\n //\n // HTTP Mapping: 400 Bad Request\n FAILED_PRECONDITION: 400,\n\n // The operation was aborted, typically due to a concurrency issue such as\n // a sequencer check failure or transaction abort.\n //\n // See the guidelines above for deciding between `FAILED_PRECONDITION`,\n // `ABORTED`, and `UNAVAILABLE`.\n //\n // HTTP Mapping: 409 Conflict\n ABORTED: 409,\n\n // The operation was attempted past the valid range. E.g., seeking or\n // reading past end-of-file.\n //\n // Unlike `INVALID_ARGUMENT`, this error indicates a problem that may\n // be fixed if the system state changes. For example, a 32-bit file\n // system will generate `INVALID_ARGUMENT` if asked to read at an\n // offset that is not in the range [0,2^32-1], but it will generate\n // `OUT_OF_RANGE` if asked to read from an offset past the current\n // file size.\n //\n // There is a fair bit of overlap between `FAILED_PRECONDITION` and\n // `OUT_OF_RANGE`. We recommend using `OUT_OF_RANGE` (the more specific\n // error) when it applies so that callers who are iterating through\n // a space can easily look for an `OUT_OF_RANGE` error to detect when\n // they are done.\n //\n // HTTP Mapping: 400 Bad Request\n OUT_OF_RANGE: 400,\n\n // The operation is not implemented or is not supported/enabled in this\n // service.\n //\n // HTTP Mapping: 501 Not Implemented\n UNIMPLEMENTED: 501,\n\n // Internal errors. This means that some invariants expected by the\n // underlying system have been broken. This error code is reserved\n // for serious errors.\n //\n // HTTP Mapping: 500 Internal Server Error\n INTERNAL: 500,\n\n // The service is currently unavailable. This is most likely a\n // transient condition, which can be corrected by retrying with\n // a backoff. Note that it is not always safe to retry\n // non-idempotent operations.\n //\n // See the guidelines above for deciding between `FAILED_PRECONDITION`,\n // `ABORTED`, and `UNAVAILABLE`.\n //\n // HTTP Mapping: 503 Service Unavailable\n UNAVAILABLE: 503,\n\n // Unrecoverable data loss or corruption.\n //\n // HTTP Mapping: 500 Internal Server Error\n DATA_LOSS: 500,\n\n // The request does not have valid authentication credentials for the\n // operation.\n //\n // HTTP Mapping: 401 Unauthorized\n UNAUTHENTICATED: 401,\n\n // The request method is not supported by the server and cannot be handled.\n //\n // HTTP Mapping: 405 Method Not Allowed\n METHOD_NOT_ALLOWED: 405,\n} as const;\n\nexport const DEFAULT_MESSAGES: Record<keyof typeof Code, string> = {\n OK: 'OK',\n CANCELLED: 'The operation was cancelled',\n UNKNOWN: 'Unknown error',\n INVALID_ARGUMENT: 'The client specified an invalid argument',\n DEADLINE_EXCEEDED: 'The deadline expired before the operation could complete',\n NOT_FOUND: 'Some requested entity was not found',\n ALREADY_EXISTS: 'The entity that a client attempted to create already exists',\n PERMISSION_DENIED: 'The caller does not have permission to execute the specified operation',\n RESOURCE_EXHAUSTED: 'Some resource has been exhausted',\n FAILED_PRECONDITION:\n \"The operation was rejected because the system is not in a state required for the operation's execution\",\n ABORTED: 'The operation was aborted',\n OUT_OF_RANGE: 'The operation was attempted past the valid range',\n UNIMPLEMENTED: 'The operation is not implemented or is not supported/enabled in this service',\n INTERNAL: 'Internal errors',\n UNAVAILABLE: 'The service is currently unavailable',\n DATA_LOSS: 'Unrecoverable data loss or corruption',\n UNAUTHENTICATED: 'The request does not have valid authentication credentials for the operation',\n METHOD_NOT_ALLOWED: 'The request method is not supported by the server and cannot be handled',\n};\n\nexport interface ErrorBody {\n error: {\n code: number;\n status: keyof typeof Code;\n message: string;\n details: Detail[];\n };\n}\n\nexport class StatusError extends Error {\n readonly status: number;\n readonly body?: ErrorBody;\n\n constructor(status: number, body?: ErrorBody) {\n super(body?.error?.message ?? `Status Error: ${status}`);\n this.name = 'StatusError';\n this.status = status;\n this.body = body;\n if ((Error as any).captureStackTrace) {\n (Error as any).captureStackTrace(this, StatusError);\n }\n Object.setPrototypeOf(this, StatusError.prototype);\n }\n}\n\nexport class StatusCode {\n code: keyof typeof Code;\n message?: string;\n private constructor(code: keyof typeof Code, message?: string) {\n this.code = code;\n this.message = message;\n }\n\n static of(code: keyof typeof Code, message?: string) {\n return new StatusCode(code, message ?? DEFAULT_MESSAGES[code]);\n }\n\n body(details?: Details): ErrorBody {\n return {\n error: {\n code: Code[this.code],\n status: this.code,\n message: this.message ?? '',\n details: details?.list ?? [],\n },\n };\n }\n\n error(details?: Details): Error {\n const body = this.body(details);\n if (Status.adapter) return Status.adapter(Code[this.code], body);\n return new StatusError(Code[this.code], body);\n }\n\n response(details?: Details): Response {\n const body = this.body(details);\n return Response.json(body, { status: body.error.code });\n }\n}\n\nexport class Status {\n static adapter?: (status: number, response: ErrorBody) => Error;\n\n static ok = (message?: string) => StatusCode.of('OK', message);\n static cancelled = (message?: string) => StatusCode.of('CANCELLED', message);\n static unknown = (message?: string) => StatusCode.of('UNKNOWN', message);\n static invalidArgument = (message?: string) => StatusCode.of('INVALID_ARGUMENT', message);\n static deadlineExceeded = (message?: string) => StatusCode.of('DEADLINE_EXCEEDED', message);\n static notFound = (message?: string) => StatusCode.of('NOT_FOUND', message);\n static alreadyExists = (message?: string) => StatusCode.of('ALREADY_EXISTS', message);\n static permissionDenied = (message?: string) => StatusCode.of('PERMISSION_DENIED', message);\n static unauthorized = (message?: string) => StatusCode.of('UNAUTHENTICATED', message);\n static resourceExhausted = (message?: string) => StatusCode.of('RESOURCE_EXHAUSTED', message);\n static failedPrecondition = (message?: string) => StatusCode.of('FAILED_PRECONDITION', message);\n static aborted = (message?: string) => StatusCode.of('ABORTED', message);\n static outOfRange = (message?: string) => StatusCode.of('OUT_OF_RANGE', message);\n static unimplemented = (message?: string) => StatusCode.of('UNIMPLEMENTED', message);\n static internal = (message?: string) => StatusCode.of('INTERNAL', message);\n static unavailable = (message?: string) => StatusCode.of('UNAVAILABLE', message);\n static dataLoss = (message?: string) => StatusCode.of('DATA_LOSS', message);\n static methodNotAllowed = (message?: string) => StatusCode.of('METHOD_NOT_ALLOWED', message);\n}\n","import type { z, ZodSchema } from 'zod';\nimport { Details } from './detail';\nimport { BadRequest } from './detail';\nimport { Status } from './status';\n\nexport type Result<S extends ZodSchema> =\n | { data: z.infer<S>; error: null }\n | { data: null; error: Response };\n\ntype Target = 'json' | 'form' | 'query' | 'param' | 'header' | 'cookie';\n\nasync function getTarget(request: Request, target: Target): Promise<any> {\n switch (target) {\n case 'json':\n return request.json();\n default:\n throw new Error(`Unsupported target: ${target}`);\n }\n}\n\nexport async function valid<S extends ZodSchema>(\n request: Request,\n target: Target,\n schema: S\n): Promise<Result<S>> {\n const value = await getTarget(request, target);\n const validator = await schema.safeParseAsync(value);\n if (validator.success) return { data: validator.data, error: null };\n const fieldViolations: BadRequest['fieldViolations'] = validator.error.issues.map(\n ({ path, message }) => ({ field: path.join('.'), description: message })\n );\n const details = Details.new().badRequest({ fieldViolations });\n const error = Status.invalidArgument().response(details);\n return { data: null, error };\n}\n","/**\n * A distributed unique ID generator inspired by Twitter's Snowflake.\n *\n * ID data bits:\n * +----------------------+----------------+-----------+\n * | delta millisecond | machine id | sequence |\n * +----------------------+----------------+-----------+\n * | 41bits | 10bits | 12bits |\n * +----------------------+----------------+-----------+\n *\n */\n\nfunction getNextMillisecond(timestamp: bigint) {\n let now = BigInt(Date.now());\n while (now < timestamp) {\n now = BigInt(Date.now());\n }\n return now;\n}\n\nexport class UidGenerator {\n public readonly MAX = (1n << 63n) - 1n;\n private readonly machineBits = BigInt(10);\n private readonly sequenceBits = BigInt(12);\n private readonly epochMillisecond = BigInt(1577808000000); // 2020-1-1 00:00:00\n private readonly sequenceMask = ~(BigInt(-1) << this.sequenceBits);\n private readonly maxMachineId = ~(BigInt(-1) << this.machineBits);\n private readonly machineIdShift = this.sequenceBits;\n private readonly timeStampShift = this.machineBits + this.sequenceBits;\n private readonly machineId: bigint;\n private sequence = BigInt(0);\n private lastTimestamp = BigInt(-1);\n\n constructor(mackineId: number) {\n this.machineId = BigInt(mackineId) % this.maxMachineId;\n }\n\n public readonly next = (): bigint => {\n let timestamp = BigInt(Date.now());\n if (timestamp < this.lastTimestamp) {\n console.error(`Clock moved backwards. time gap = ${this.lastTimestamp - timestamp}`);\n timestamp = getNextMillisecond(this.lastTimestamp);\n }\n if (timestamp === this.lastTimestamp) {\n this.sequence = (this.sequence + BigInt(1)) & this.sequenceMask;\n if (this.sequence === BigInt(0)) {\n timestamp = getNextMillisecond(timestamp);\n }\n } else {\n this.sequence = BigInt(0);\n }\n this.lastTimestamp = timestamp;\n return (\n ((timestamp - this.epochMillisecond) << this.timeStampShift) |\n (this.machineId << this.machineIdShift) |\n this.sequence\n );\n };\n}\n\nconst machineId = Math.floor(Math.random() * 1024);\nexport const uid = new UidGenerator(machineId);\n"],"mappings":"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","names":["DetailType"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/polyfills/index.ts"],"sourcesContent":["// @ts-expect-error fixed: Do not know how to serialize a BigInt\nBigInt.prototype.toJSON = function () {\n return this.toString();\n};\n"],"mappings":";;;AACA,OAAO,UAAU,SAAS,WAAY;AACpC,SAAO,KAAK,SAAS;AACvB;","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/polyfills/index.ts"],"sourcesContent":["// @ts-expect-error fixed: Do not know how to serialize a BigInt\nBigInt.prototype.toJSON = function () {\n return this.toString();\n};\n"],"mappings":";AACA,OAAO,UAAU,SAAS,WAAY;AACpC,SAAO,KAAK,SAAS;AACvB;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,18 +1,26 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shware/http",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"dev": "tsc --watch",
|
|
7
|
-
"build": "
|
|
7
|
+
"build": "tsup",
|
|
8
8
|
"test": "jest"
|
|
9
9
|
},
|
|
10
|
-
"main": "./dist/index.
|
|
11
|
-
"module": "./dist/index.
|
|
12
|
-
"types": "./dist/index.d.
|
|
10
|
+
"main": "./dist/index.js",
|
|
11
|
+
"module": "./dist/index.js",
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
13
|
"exports": {
|
|
14
|
-
".":
|
|
15
|
-
|
|
14
|
+
".": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"import": "./dist/index.js",
|
|
17
|
+
"require": "./dist/index.cjs"
|
|
18
|
+
},
|
|
19
|
+
"./polyfills": {
|
|
20
|
+
"types": "./dist/polyfills/index.d.ts",
|
|
21
|
+
"import": "./dist/polyfills/index.js",
|
|
22
|
+
"require": "./dist/polyfills/index.cjs"
|
|
23
|
+
}
|
|
16
24
|
},
|
|
17
25
|
"files": [
|
|
18
26
|
"dist"
|
|
File without changes
|
|
File without changes
|