@wener/utils 1.1.24 → 1.1.25

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.
@@ -1 +1 @@
1
- {"version":3,"file":"hashing.js","sources":["../../src/crypto/hashing.ts"],"sourcesContent":["import { ArrayBuffers } from '../io/ArrayBuffers';\n\nexport function sha1(s: BinaryLike, o?: undefined): Promise<Buffer>;\nexport function sha1(s: BinaryLike, o: 'hex' | 'base64'): Promise<string>;\n\nexport function sha1(s: BinaryLike, o?: DigestOptions) {\n return digestOf('SHA-1', s, o);\n}\n\nexport function sha256(s: BinaryLike, o?: undefined): Promise<Buffer>;\nexport function sha256(s: BinaryLike, o: 'hex' | 'base64'): Promise<string>;\n\nexport function sha256(s: BinaryLike, o?: DigestOptions) {\n return digestOf('SHA-256', s, o);\n}\n\nexport function sha384(s: BinaryLike, o?: undefined): Promise<Buffer>;\nexport function sha384(s: BinaryLike, o: 'hex' | 'base64'): Promise<string>;\n\nexport function sha384(s: BinaryLike, o?: DigestOptions) {\n return digestOf('SHA-384', s, o);\n}\n\nexport function sha512(s: BinaryLike, o?: undefined): Promise<Buffer>;\nexport function sha512(s: BinaryLike, o: 'hex' | 'base64'): Promise<string>;\n\nexport function sha512(s: BinaryLike, o?: DigestOptions) {\n return digestOf('SHA-512', s, o);\n}\n\nfunction digestOf(a: string, s: BinaryLike, o?: DigestOptions) {\n let buffer = crypto.subtle.digest(a, binaryOf(s));\n return o ? buffer.then((v) => encode(v, o)) : o;\n}\n\nexport type DigestOptions =\n | 'hex'\n | 'base64'\n | {\n encoding: 'hex' | 'base64';\n };\n\ntype BinaryLike = string | BufferSource;\n\nfunction binaryOf(s: BinaryLike) {\n // ArrayBuffer, TypedArray, DataView\n if (typeof s === 'string') {\n return new TextEncoder().encode(s);\n }\n return s;\n}\n\nfunction encode(buf: BufferSource, o?: DigestOptions) {\n if (o) {\n switch (o) {\n case 'hex':\n case 'base64':\n return ArrayBuffers.toString(buf, o);\n }\n }\n return buf;\n}\n\ntype StringEncoding = 'hex' | 'base64';\ntype IsStringCoding<T> = T extends StringEncoding ? true : T extends { encoding: StringEncoding } ? true : false;\n\nexport function hmac<O extends DigestOptions>(\n hash: 'SHA-1' | 'SHA-256' | 'SHA-384' | 'SHA-512' | 'sha1' | 'sha256' | 'sha384' | 'sha512',\n key: BinaryLike | CryptoKey,\n data: BinaryLike,\n o?: O,\n): Promise<IsStringCoding<O> extends true ? string : Buffer>;\n\nexport async function hmac(\n hash: 'SHA-1' | 'SHA-256' | 'SHA-384' | 'SHA-512' | 'sha1' | 'sha256' | 'sha384' | 'sha512',\n key: BinaryLike | CryptoKey,\n data: BinaryLike,\n o?: DigestOptions,\n) {\n let ck =\n key instanceof CryptoKey\n ? key\n : await crypto.subtle.importKey(\n 'raw',\n binaryOf(key),\n {\n name: 'HMAC',\n hash: {\n name: normalizeHash(hash),\n },\n },\n false,\n ['sign'],\n );\n let buffer = await crypto.subtle.sign(\n {\n name: 'HMAC',\n hash: {\n name: hash,\n },\n },\n ck,\n binaryOf(data),\n );\n\n return encode(buffer, o);\n}\n\nfunction normalizeHash(hash: string) {\n return hash.replace(/^sha/i, 'SHA-');\n}\n"],"names":[],"mappings":";;AAKgB,SAAA,IAAA,CAAK,GAAe,CAAmB,EAAA;AACrD,EAAO,OAAA,QAAA,CAAS,OAAS,EAAA,CAAA,EAAG,CAAC,CAAA,CAAA;AAC/B,CAAA;AAKgB,SAAA,MAAA,CAAO,GAAe,CAAmB,EAAA;AACvD,EAAO,OAAA,QAAA,CAAS,SAAW,EAAA,CAAA,EAAG,CAAC,CAAA,CAAA;AACjC,CAAA;AAKgB,SAAA,MAAA,CAAO,GAAe,CAAmB,EAAA;AACvD,EAAO,OAAA,QAAA,CAAS,SAAW,EAAA,CAAA,EAAG,CAAC,CAAA,CAAA;AACjC,CAAA;AAKgB,SAAA,MAAA,CAAO,GAAe,CAAmB,EAAA;AACvD,EAAO,OAAA,QAAA,CAAS,SAAW,EAAA,CAAA,EAAG,CAAC,CAAA,CAAA;AACjC,CAAA;AAEA,SAAS,QAAA,CAAS,CAAW,EAAA,CAAA,EAAe,CAAmB,EAAA;AAC7D,EAAA,IAAI,SAAS,MAAO,CAAA,MAAA,CAAO,OAAO,CAAG,EAAA,QAAA,CAAS,CAAC,CAAC,CAAA,CAAA;AAChD,EAAO,OAAA,CAAA,GAAI,OAAO,IAAK,CAAA,CAAC,MAAM,MAAO,CAAA,CAAA,EAAG,CAAC,CAAC,CAAI,GAAA,CAAA,CAAA;AAChD,CAAA;AAWA,SAAS,SAAS,CAAe,EAAA;AAE/B,EAAI,IAAA,OAAO,MAAM,QAAU,EAAA;AACzB,IAAA,OAAO,IAAI,WAAA,EAAc,CAAA,MAAA,CAAO,CAAC,CAAA,CAAA;AAAA,GACnC;AACA,EAAO,OAAA,CAAA,CAAA;AACT,CAAA;AAEA,SAAS,MAAA,CAAO,KAAmB,CAAmB,EAAA;AACpD,EAAA,IAAI,CAAG,EAAA;AACL,IAAA,QAAQ,CAAG;AAAA,MACT,KAAK,KAAA,CAAA;AAAA,MACL,KAAK,QAAA;AACH,QAAO,OAAA,YAAA,CAAa,QAAS,CAAA,GAAA,EAAK,CAAC,CAAA,CAAA;AAAA,KACvC;AAAA,GACF;AACA,EAAO,OAAA,GAAA,CAAA;AACT,CAAA;AAYA,eAAsB,IACpB,CAAA,IAAA,EACA,GACA,EAAA,IAAA,EACA,CACA,EAAA;AACA,EAAA,IAAI,KACF,GAAe,YAAA,SAAA,GACX,GACA,GAAA,MAAM,OAAO,MAAO,CAAA,SAAA;AAAA,IAClB,KAAA;AAAA,IACA,SAAS,GAAG,CAAA;AAAA,IACZ;AAAA,MACE,IAAM,EAAA,MAAA;AAAA,MACN,IAAM,EAAA;AAAA,QACJ,IAAA,EAAM,cAAc,IAAI,CAAA;AAAA,OAC1B;AAAA,KACF;AAAA,IACA,KAAA;AAAA,IACA,CAAC,MAAM,CAAA;AAAA,GACT,CAAA;AACN,EAAI,IAAA,MAAA,GAAS,MAAM,MAAA,CAAO,MAAO,CAAA,IAAA;AAAA,IAC/B;AAAA,MACE,IAAM,EAAA,MAAA;AAAA,MACN,IAAM,EAAA;AAAA,QACJ,IAAM,EAAA,IAAA;AAAA,OACR;AAAA,KACF;AAAA,IACA,EAAA;AAAA,IACA,SAAS,IAAI,CAAA;AAAA,GACf,CAAA;AAEA,EAAO,OAAA,MAAA,CAAO,QAAQ,CAAC,CAAA,CAAA;AACzB,CAAA;AAEA,SAAS,cAAc,IAAc,EAAA;AACnC,EAAO,OAAA,IAAA,CAAK,OAAQ,CAAA,OAAA,EAAS,MAAM,CAAA,CAAA;AACrC;;;;"}
1
+ {"version":3,"file":"hashing.js","sources":["../../src/crypto/hashing.ts"],"sourcesContent":["import { ArrayBuffers } from '../io/ArrayBuffers';\n\nexport function sha1(s: BinaryLike, o?: undefined): Promise<Buffer>;\nexport function sha1(s: BinaryLike, o: 'hex' | 'base64'): Promise<string>;\n\nexport function sha1(s: BinaryLike, o?: DigestOptions) {\n return digestOf('SHA-1', s, o);\n}\n\nexport function sha256(s: BinaryLike, o?: undefined): Promise<Buffer>;\nexport function sha256(s: BinaryLike, o: 'hex' | 'base64'): Promise<string>;\n\nexport function sha256(s: BinaryLike, o?: DigestOptions) {\n return digestOf('SHA-256', s, o);\n}\n\nexport function sha384(s: BinaryLike, o?: undefined): Promise<Buffer>;\nexport function sha384(s: BinaryLike, o: 'hex' | 'base64'): Promise<string>;\n\nexport function sha384(s: BinaryLike, o?: DigestOptions) {\n return digestOf('SHA-384', s, o);\n}\n\nexport function sha512(s: BinaryLike, o?: undefined): Promise<Buffer>;\nexport function sha512(s: BinaryLike, o: 'hex' | 'base64'): Promise<string>;\n\nexport function sha512(s: BinaryLike, o?: DigestOptions) {\n return digestOf('SHA-512', s, o);\n}\n\nfunction digestOf(a: string, s: BinaryLike, o?: DigestOptions) {\n let buffer = crypto.subtle.digest(a, binaryOf(s));\n return o ? buffer.then((v) => encode(v, o)) : o;\n}\n\nexport type DigestOptions =\n | 'hex'\n | 'base64'\n | {\n encoding: 'hex' | 'base64';\n };\n\ntype BinaryLike = string | BufferSource;\n\nfunction binaryOf(s: BinaryLike) {\n // ArrayBuffer, TypedArray, DataView\n if (typeof s === 'string') {\n return new TextEncoder().encode(s);\n }\n // ArrayBuffer, Buffer, TypedArray, DataView\n return s;\n}\n\nfunction encode(buf: BufferSource, o?: DigestOptions) {\n if (o) {\n switch (o) {\n case 'hex':\n case 'base64':\n return ArrayBuffers.toString(buf, o);\n }\n }\n return buf;\n}\n\ntype StringEncoding = 'hex' | 'base64';\ntype IsStringCoding<T> = T extends StringEncoding ? true : T extends { encoding: StringEncoding } ? true : false;\n\nexport function hmac<O extends DigestOptions>(\n hash: 'SHA-1' | 'SHA-256' | 'SHA-384' | 'SHA-512' | 'sha1' | 'sha256' | 'sha384' | 'sha512',\n key: BinaryLike | CryptoKey,\n data: BinaryLike,\n o?: O,\n): Promise<IsStringCoding<O> extends true ? string : Buffer>;\n\nexport async function hmac(\n hash: 'SHA-1' | 'SHA-256' | 'SHA-384' | 'SHA-512' | 'sha1' | 'sha256' | 'sha384' | 'sha512',\n key: BinaryLike | CryptoKey,\n data: BinaryLike,\n o?: DigestOptions,\n) {\n let ck =\n key instanceof CryptoKey\n ? key\n : await crypto.subtle.importKey(\n 'raw',\n binaryOf(key),\n {\n name: 'HMAC',\n hash: {\n name: normalizeHash(hash),\n },\n },\n false,\n ['sign'],\n );\n let buffer = await crypto.subtle.sign(\n {\n name: 'HMAC',\n hash: {\n name: hash,\n },\n },\n ck,\n binaryOf(data),\n );\n\n return encode(buffer, o);\n}\n\nfunction normalizeHash(hash: string) {\n return hash.replace(/^sha/i, 'SHA-');\n}\n"],"names":[],"mappings":";;AAKgB,SAAA,IAAA,CAAK,GAAe,CAAmB,EAAA;AACrD,EAAO,OAAA,QAAA,CAAS,OAAS,EAAA,CAAA,EAAG,CAAC,CAAA,CAAA;AAC/B,CAAA;AAKgB,SAAA,MAAA,CAAO,GAAe,CAAmB,EAAA;AACvD,EAAO,OAAA,QAAA,CAAS,SAAW,EAAA,CAAA,EAAG,CAAC,CAAA,CAAA;AACjC,CAAA;AAKgB,SAAA,MAAA,CAAO,GAAe,CAAmB,EAAA;AACvD,EAAO,OAAA,QAAA,CAAS,SAAW,EAAA,CAAA,EAAG,CAAC,CAAA,CAAA;AACjC,CAAA;AAKgB,SAAA,MAAA,CAAO,GAAe,CAAmB,EAAA;AACvD,EAAO,OAAA,QAAA,CAAS,SAAW,EAAA,CAAA,EAAG,CAAC,CAAA,CAAA;AACjC,CAAA;AAEA,SAAS,QAAA,CAAS,CAAW,EAAA,CAAA,EAAe,CAAmB,EAAA;AAC7D,EAAA,IAAI,SAAS,MAAO,CAAA,MAAA,CAAO,OAAO,CAAG,EAAA,QAAA,CAAS,CAAC,CAAC,CAAA,CAAA;AAChD,EAAO,OAAA,CAAA,GAAI,OAAO,IAAK,CAAA,CAAC,MAAM,MAAO,CAAA,CAAA,EAAG,CAAC,CAAC,CAAI,GAAA,CAAA,CAAA;AAChD,CAAA;AAWA,SAAS,SAAS,CAAe,EAAA;AAE/B,EAAI,IAAA,OAAO,MAAM,QAAU,EAAA;AACzB,IAAA,OAAO,IAAI,WAAA,EAAc,CAAA,MAAA,CAAO,CAAC,CAAA,CAAA;AAAA,GACnC;AAEA,EAAO,OAAA,CAAA,CAAA;AACT,CAAA;AAEA,SAAS,MAAA,CAAO,KAAmB,CAAmB,EAAA;AACpD,EAAA,IAAI,CAAG,EAAA;AACL,IAAA,QAAQ,CAAG;AAAA,MACT,KAAK,KAAA,CAAA;AAAA,MACL,KAAK,QAAA;AACH,QAAO,OAAA,YAAA,CAAa,QAAS,CAAA,GAAA,EAAK,CAAC,CAAA,CAAA;AAAA,KACvC;AAAA,GACF;AACA,EAAO,OAAA,GAAA,CAAA;AACT,CAAA;AAYA,eAAsB,IACpB,CAAA,IAAA,EACA,GACA,EAAA,IAAA,EACA,CACA,EAAA;AACA,EAAA,IAAI,KACF,GAAe,YAAA,SAAA,GACX,GACA,GAAA,MAAM,OAAO,MAAO,CAAA,SAAA;AAAA,IAClB,KAAA;AAAA,IACA,SAAS,GAAG,CAAA;AAAA,IACZ;AAAA,MACE,IAAM,EAAA,MAAA;AAAA,MACN,IAAM,EAAA;AAAA,QACJ,IAAA,EAAM,cAAc,IAAI,CAAA;AAAA,OAC1B;AAAA,KACF;AAAA,IACA,KAAA;AAAA,IACA,CAAC,MAAM,CAAA;AAAA,GACT,CAAA;AACN,EAAI,IAAA,MAAA,GAAS,MAAM,MAAA,CAAO,MAAO,CAAA,IAAA;AAAA,IAC/B;AAAA,MACE,IAAM,EAAA,MAAA;AAAA,MACN,IAAM,EAAA;AAAA,QACJ,IAAM,EAAA,IAAA;AAAA,OACR;AAAA,KACF;AAAA,IACA,EAAA;AAAA,IACA,SAAS,IAAI,CAAA;AAAA,GACf,CAAA;AAEA,EAAO,OAAA,MAAA,CAAO,QAAQ,CAAC,CAAA,CAAA;AACzB,CAAA;AAEA,SAAS,cAAc,IAAc,EAAA;AACnC,EAAO,OAAA,IAAA,CAAK,OAAQ,CAAA,OAAA,EAAS,MAAM,CAAA,CAAA;AACrC;;;;"}
@@ -83,6 +83,25 @@ class DetailHolder {
83
83
  throw(o) {
84
84
  throw this.asError(o);
85
85
  }
86
+ toJSON() {
87
+ return {
88
+ code: this.code,
89
+ message: this.message,
90
+ status: this.status,
91
+ description: this.description,
92
+ cause: this.cause,
93
+ metadata: this.metadata
94
+ };
95
+ }
96
+ asResponse() {
97
+ return new Response(JSON.stringify(this.toJSON()), {
98
+ status: this.status,
99
+ statusText: this.description,
100
+ headers: {
101
+ "Content-Type": "application/json"
102
+ }
103
+ });
104
+ }
86
105
  }
87
106
  class Errors {
88
107
  static BadRequest = this.with({ status: 400 });
@@ -92,6 +111,7 @@ class Errors {
92
111
  static InternalServerError = this.with({ status: 501 });
93
112
  static NotImplemented = this.with({ status: 501 });
94
113
  static ServiceUnavailable = this.with({ status: 503 });
114
+ static resolvers = [];
95
115
  static with(init) {
96
116
  return new DetailHolder(init);
97
117
  }
@@ -116,6 +136,12 @@ class Errors {
116
136
  if (e instanceof DetailError) {
117
137
  return e.detail;
118
138
  }
139
+ for (const resolver of this.resolvers) {
140
+ const r = resolver(e);
141
+ if (r) {
142
+ return r;
143
+ }
144
+ }
119
145
  if (e instanceof Error) {
120
146
  const { message, code, status } = e;
121
147
  return new DetailHolder({
@@ -1 +1 @@
1
- {"version":3,"file":"Errors.js","sources":["../../src/errors/Errors.ts"],"sourcesContent":["import { getHttpStatusText } from '../http/HttpStatus';\n\nexport interface ErrorDetailInit {\n message?: string;\n status: number;\n description?: string;\n code?: number | string;\n metadata?: Record<string, any>;\n cause?: any;\n}\n\nexport class DetailError extends Error {\n readonly status: number;\n readonly description?: string;\n\n constructor(readonly detail: ErrorDetail) {\n super(detail.message, {\n cause: detail.cause,\n });\n this.status = detail.status;\n this.description = detail.description;\n }\n\n toJSON() {\n return {\n code: this.detail.code,\n message: this.message,\n status: this.status,\n description: this.description,\n cause: this.cause,\n };\n }\n}\n\nclass DetailHolder implements ErrorDetail {\n readonly message: string;\n readonly status: number;\n readonly code: number | string;\n readonly metadata?: Record<string, any>;\n readonly description?: string;\n readonly cause?: any;\n\n constructor({\n status,\n message = getHttpStatusText(status),\n code = status,\n metadata,\n description,\n cause,\n }: ErrorDetailInit) {\n this.message = message ?? String(status);\n this.status = status;\n this.code = code;\n this.description = description;\n this.metadata = metadata;\n this.cause = cause;\n }\n\n with(o?: Partial<ErrorDetailInit> | string): DetailHolder {\n if (typeof o === 'string') {\n o = { message: o };\n }\n\n if (o === undefined) {\n return new DetailHolder(this);\n }\n\n return new DetailHolder({\n status: this.status,\n code: this.code,\n message: this.message,\n metadata: this.metadata,\n cause: this.cause,\n ...o,\n });\n }\n\n asError(o?: Partial<ErrorDetailInit> | string): Error {\n if (typeof o === 'string') {\n o = { message: o };\n }\n\n return new DetailError(this.with(o));\n }\n\n require(v: any, o?: Partial<ErrorDetailInit> | string): any {\n if (v === undefined || v === null) {\n throw this.asError(o);\n }\n\n return v;\n }\n\n check(cond: any, o?: Partial<ErrorDetailInit> | string) {\n switch (cond) {\n case false:\n case undefined:\n case null: {\n throw this.asError(o);\n }\n }\n }\n\n throw(o?: Partial<ErrorDetailInit>): never {\n throw this.asError(o);\n }\n}\n\nexport interface ErrorDetail {\n readonly message: string;\n readonly status: number;\n readonly code?: number | string;\n readonly metadata?: Record<string, any>;\n readonly description?: string;\n readonly cause?: any;\n\n with(message: string): ErrorDetail;\n\n with(o?: Partial<ErrorDetailInit>): ErrorDetail;\n\n asError(o?: Partial<ErrorDetailInit>): Error;\n\n asError(message: string): Error;\n\n throw(o?: Partial<ErrorDetailInit>): never;\n\n require<T>(v: T | undefined, o?: Partial<ErrorDetailInit> | string): NonNullable<T>;\n\n // 不支持 return value\n // https://stackoverflow.com/a/73252858/1870054\n\n check(condition: boolean, o?: Partial<ErrorDetailInit> | string): asserts condition;\n\n check<T>(v: T | undefined | null, o?: Partial<ErrorDetailInit> | string): asserts v is NonNullable<T>;\n}\n\nexport class Errors {\n static BadRequest: ErrorDetail = this.with({ status: 400 });\n static Unauthorized: ErrorDetail = this.with({ status: 403 });\n static Forbidden: ErrorDetail = this.with({ status: 403 });\n static NotFound: ErrorDetail = this.with({ status: 404 });\n static InternalServerError: ErrorDetail = this.with({ status: 501 });\n static NotImplemented: ErrorDetail = this.with({ status: 501 });\n static ServiceUnavailable: ErrorDetail = this.with({ status: 503 });\n\n static with(init: ErrorDetailInit): ErrorDetail {\n return new DetailHolder(init);\n }\n\n static ok(res: Response, o?: Partial<ErrorDetailInit>) {\n if (res.ok) {\n return res;\n }\n throw this.with({\n description: res.statusText,\n status: res.status,\n ...o,\n metadata: {\n ...o?.metadata,\n response: res,\n },\n }).asError();\n }\n\n static resolve(e: any): ErrorDetail {\n if (e instanceof DetailHolder) {\n return e;\n }\n\n if (e instanceof DetailError) {\n return e.detail;\n }\n\n if (e instanceof Error) {\n const { message, code, status } = e as any;\n // can get status from NestJS HttpException\n return new DetailHolder({\n message,\n status: parseInt(status) || 500,\n code,\n cause: e,\n });\n }\n\n return new DetailHolder({\n message: e.message,\n status: 500,\n cause: e,\n });\n }\n}\n\n// interface ZodError {\n// path: Array<string | number>;\n// message: string;\n// code: string;\n// expected?: any;\n// received?: any;\n// }\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Errors.js","sources":["../../src/errors/Errors.ts"],"sourcesContent":["import { getHttpStatusText } from '../http/HttpStatus';\n\nexport interface ErrorDetailInit {\n message?: string;\n status: number;\n description?: string;\n code?: number | string;\n metadata?: Record<string, any>;\n cause?: any;\n}\n\nexport class DetailError extends Error {\n readonly status: number;\n readonly description?: string;\n\n constructor(readonly detail: ErrorDetail) {\n super(detail.message, {\n cause: detail.cause,\n });\n this.status = detail.status;\n this.description = detail.description;\n }\n\n toJSON() {\n return {\n code: this.detail.code,\n message: this.message,\n status: this.status,\n description: this.description,\n cause: this.cause,\n };\n }\n}\n\nclass DetailHolder implements ErrorDetail {\n readonly message: string;\n readonly status: number;\n readonly code: number | string;\n readonly metadata?: Record<string, any>;\n readonly description?: string;\n readonly cause?: any;\n\n constructor({\n status,\n message = getHttpStatusText(status),\n code = status,\n metadata,\n description,\n cause,\n }: ErrorDetailInit) {\n this.message = message ?? String(status);\n this.status = status;\n this.code = code;\n this.description = description;\n this.metadata = metadata;\n this.cause = cause;\n }\n\n with(o?: Partial<ErrorDetailInit> | string): DetailHolder {\n if (typeof o === 'string') {\n o = { message: o };\n }\n\n if (o === undefined) {\n return new DetailHolder(this);\n }\n\n return new DetailHolder({\n status: this.status,\n code: this.code,\n message: this.message,\n metadata: this.metadata,\n cause: this.cause,\n ...o,\n });\n }\n\n asError(o?: Partial<ErrorDetailInit> | string): Error {\n if (typeof o === 'string') {\n o = { message: o };\n }\n\n return new DetailError(this.with(o));\n }\n\n require(v: any, o?: Partial<ErrorDetailInit> | string): any {\n if (v === undefined || v === null) {\n throw this.asError(o);\n }\n\n return v;\n }\n\n check(cond: any, o?: Partial<ErrorDetailInit> | string) {\n switch (cond) {\n case false:\n case undefined:\n case null: {\n throw this.asError(o);\n }\n }\n }\n\n throw(o?: string | Partial<ErrorDetailInit>): never {\n throw this.asError(o);\n }\n\n toJSON() {\n return {\n code: this.code,\n message: this.message,\n status: this.status,\n description: this.description,\n cause: this.cause,\n metadata: this.metadata,\n };\n }\n\n asResponse(): Response {\n return new Response(JSON.stringify(this.toJSON()), {\n status: this.status,\n statusText: this.description,\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n }\n}\n\nexport interface ErrorDetail {\n readonly message: string;\n readonly status: number;\n readonly code?: number | string;\n readonly metadata?: Record<string, any>;\n readonly description?: string;\n readonly cause?: any;\n\n with(message: string): ErrorDetail;\n\n with(o?: Partial<ErrorDetailInit>): ErrorDetail;\n\n asError(o?: string | Partial<ErrorDetailInit>): Error;\n\n asResponse(): Response;\n\n throw(o?: string | Partial<ErrorDetailInit>): never;\n\n require<T>(v: T | undefined, o?: Partial<ErrorDetailInit> | string): NonNullable<T>;\n\n // 不支持 return value\n // https://stackoverflow.com/a/73252858/1870054\n\n check(condition: boolean, o?: Partial<ErrorDetailInit> | string): asserts condition;\n\n check<T>(v: T | undefined | null, o?: Partial<ErrorDetailInit> | string): asserts v is NonNullable<T>;\n}\n\nexport class Errors {\n static BadRequest: ErrorDetail = this.with({ status: 400 });\n static Unauthorized: ErrorDetail = this.with({ status: 403 });\n static Forbidden: ErrorDetail = this.with({ status: 403 });\n static NotFound: ErrorDetail = this.with({ status: 404 });\n static InternalServerError: ErrorDetail = this.with({ status: 501 });\n static NotImplemented: ErrorDetail = this.with({ status: 501 });\n static ServiceUnavailable: ErrorDetail = this.with({ status: 503 });\n\n static resolvers: ((e: any) => ErrorDetail | void)[] = [];\n\n static with(init: ErrorDetailInit): ErrorDetail {\n return new DetailHolder(init);\n }\n\n static ok(res: Response, o?: Partial<ErrorDetailInit>) {\n if (res.ok) {\n return res;\n }\n throw this.with({\n description: res.statusText,\n status: res.status,\n ...o,\n metadata: {\n ...o?.metadata,\n response: res,\n },\n }).asError();\n }\n\n static resolve(e: any): ErrorDetail {\n if (e instanceof DetailHolder) {\n return e;\n }\n\n if (e instanceof DetailError) {\n return e.detail;\n }\n\n for (const resolver of this.resolvers) {\n const r = resolver(e);\n if (r) {\n return r;\n }\n }\n\n if (e instanceof Error) {\n const { message, code, status } = e as any;\n // can get status from NestJS HttpException\n return new DetailHolder({\n message,\n status: parseInt(status) || 500,\n code,\n cause: e,\n });\n }\n\n return new DetailHolder({\n message: e.message,\n status: 500,\n cause: e,\n });\n }\n}\n\n// interface ZodError {\n// path: Array<string | number>;\n// message: string;\n// code: string;\n// expected?: any;\n// received?: any;\n// }\n"],"names":[],"mappings":"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"}
@@ -9,7 +9,9 @@ ${Array.from(new Headers(req.headers).entries()).map(([k, v]) => `${k}: ${v}`).j
9
9
  `;
10
10
  let done;
11
11
  if (req.body) {
12
- if (req.body instanceof ReadableStream) {
12
+ let hdr = new Headers(req.headers);
13
+ let ct = hdr.get("content-type");
14
+ if (ct === "application/octet-stream") ; else if (req.body instanceof ReadableStream) {
13
15
  const [a, b] = req.body.tee();
14
16
  req.body = a;
15
17
  const signal = req.signal;
@@ -1 +1 @@
1
- {"version":3,"file":"dumpRequest.js","sources":["../../src/fetch/dumpRequest.ts"],"sourcesContent":["export function dumpRequest({\n url,\n req = {},\n log = console.log,\n}: {\n url: string;\n req?: RequestInit;\n log?: (s: string) => void;\n}) {\n const { method = 'GET' } = req;\n let out = `-> ${method} ${url}\n${Array.from(new Headers(req.headers).entries())\n .map(([k, v]) => `${k}: ${v}`)\n .join('\\n')}\n`;\n\n let done: Promise<string> | undefined;\n if (req.body) {\n if (req.body instanceof ReadableStream) {\n const [a, b] = req.body.tee();\n req.body = a;\n const signal = req.signal;\n done = Promise.resolve().then(async () => {\n const reader = b.getReader();\n log(out);\n while (true) {\n if (signal?.aborted) {\n break;\n }\n\n let { done, value } = await reader.read();\n value instanceof Uint8Array && (value = new TextDecoder().decode(value));\n out += value;\n log(value);\n if (!done) {\n break;\n }\n }\n // maybe for archive\n out += `\\n`;\n return out;\n });\n } else {\n out += `\n${req.body}\n`;\n }\n log(out);\n }\n return done || Promise.resolve(out);\n}\n"],"names":["done"],"mappings":"AAAO,SAAS,WAAY,CAAA;AAAA,EAC1B,GAAA;AAAA,EACA,MAAM,EAAC;AAAA,EACP,MAAM,OAAQ,CAAA,GAAA;AAChB,CAIG,EAAA;AACD,EAAM,MAAA,EAAE,MAAS,GAAA,KAAA,EAAU,GAAA,GAAA,CAAA;AAC3B,EAAA,IAAI,GAAM,GAAA,CAAA,GAAA,EAAM,MAAM,CAAA,CAAA,EAAI,GAAG,CAAA;AAAA,EAC7B,KAAA,CAAM,IAAK,CAAA,IAAI,OAAQ,CAAA,GAAA,CAAI,OAAO,CAAE,CAAA,OAAA,EAAS,CAAA,CAC5C,GAAI,CAAA,CAAC,CAAC,CAAG,EAAA,CAAC,CAAM,KAAA,CAAA,EAAG,CAAC,CAAA,EAAA,EAAK,CAAC,CAAE,CAAA,CAAA,CAC5B,IAAK,CAAA,IAAI,CAAC,CAAA;AAAA,CAAA,CAAA;AAGX,EAAI,IAAA,IAAA,CAAA;AACJ,EAAA,IAAI,IAAI,IAAM,EAAA;AACZ,IAAI,IAAA,GAAA,CAAI,gBAAgB,cAAgB,EAAA;AACtC,MAAA,MAAM,CAAC,CAAG,EAAA,CAAC,CAAI,GAAA,GAAA,CAAI,KAAK,GAAI,EAAA,CAAA;AAC5B,MAAA,GAAA,CAAI,IAAO,GAAA,CAAA,CAAA;AACX,MAAA,MAAM,SAAS,GAAI,CAAA,MAAA,CAAA;AACnB,MAAA,IAAA,GAAO,OAAQ,CAAA,OAAA,EAAU,CAAA,IAAA,CAAK,YAAY;AACxC,QAAM,MAAA,MAAA,GAAS,EAAE,SAAU,EAAA,CAAA;AAC3B,QAAA,GAAA,CAAI,GAAG,CAAA,CAAA;AACP,QAAA,OAAO,IAAM,EAAA;AACX,UAAA,IAAI,iCAAQ,OAAS,EAAA;AACnB,YAAA,MAAA;AAAA,WACF;AAEA,UAAA,IAAI,EAAE,IAAAA,EAAAA,KAAAA,EAAM,OAAU,GAAA,MAAM,OAAO,IAAK,EAAA,CAAA;AACxC,UAAA,KAAA,YAAiB,eAAe,KAAQ,GAAA,IAAI,WAAY,EAAA,CAAE,OAAO,KAAK,CAAA,CAAA,CAAA;AACtE,UAAO,GAAA,IAAA,KAAA,CAAA;AACP,UAAA,GAAA,CAAI,KAAK,CAAA,CAAA;AACT,UAAA,IAAI,CAACA,KAAM,EAAA;AACT,YAAA,MAAA;AAAA,WACF;AAAA,SACF;AAEA,QAAO,GAAA,IAAA,CAAA;AAAA,CAAA,CAAA;AACP,QAAO,OAAA,GAAA,CAAA;AAAA,OACR,CAAA,CAAA;AAAA,KACI,MAAA;AACL,MAAO,GAAA,IAAA,CAAA;AAAA,EACX,IAAI,IAAI,CAAA;AAAA,CAAA,CAAA;AAAA,KAEN;AACA,IAAA,GAAA,CAAI,GAAG,CAAA,CAAA;AAAA,GACT;AACA,EAAO,OAAA,IAAA,IAAQ,OAAQ,CAAA,OAAA,CAAQ,GAAG,CAAA,CAAA;AACpC;;;;"}
1
+ {"version":3,"file":"dumpRequest.js","sources":["../../src/fetch/dumpRequest.ts"],"sourcesContent":["export function dumpRequest({\n url,\n req = {},\n log = console.log,\n}: {\n url: string;\n req?: RequestInit;\n log?: (s: string) => void;\n}) {\n const { method = 'GET' } = req;\n let out = `-> ${method} ${url}\n${Array.from(new Headers(req.headers).entries())\n .map(([k, v]) => `${k}: ${v}`)\n .join('\\n')}\n`;\n\n let done: Promise<string> | undefined;\n if (req.body) {\n let hdr = new Headers(req.headers);\n let ct = hdr.get('content-type');\n if (ct === 'application/octet-stream') {\n // skip\n } else if (req.body instanceof ReadableStream) {\n const [a, b] = req.body.tee();\n req.body = a;\n const signal = req.signal;\n done = Promise.resolve().then(async () => {\n const reader = b.getReader();\n log(out);\n while (true) {\n if (signal?.aborted) {\n break;\n }\n\n let { done, value } = await reader.read();\n value instanceof Uint8Array && (value = new TextDecoder().decode(value));\n out += value;\n log(value);\n if (!done) {\n break;\n }\n }\n // maybe for archive\n out += `\\n`;\n return out;\n });\n } else {\n out += `\n${req.body}\n`;\n }\n log(out);\n }\n return done || Promise.resolve(out);\n}\n"],"names":["done"],"mappings":"AAAO,SAAS,WAAY,CAAA;AAAA,EAC1B,GAAA;AAAA,EACA,MAAM,EAAC;AAAA,EACP,MAAM,OAAQ,CAAA,GAAA;AAChB,CAIG,EAAA;AACD,EAAM,MAAA,EAAE,MAAS,GAAA,KAAA,EAAU,GAAA,GAAA,CAAA;AAC3B,EAAA,IAAI,GAAM,GAAA,CAAA,GAAA,EAAM,MAAM,CAAA,CAAA,EAAI,GAAG,CAAA;AAAA,EAC7B,KAAA,CAAM,IAAK,CAAA,IAAI,OAAQ,CAAA,GAAA,CAAI,OAAO,CAAE,CAAA,OAAA,EAAS,CAAA,CAC5C,GAAI,CAAA,CAAC,CAAC,CAAG,EAAA,CAAC,CAAM,KAAA,CAAA,EAAG,CAAC,CAAA,EAAA,EAAK,CAAC,CAAE,CAAA,CAAA,CAC5B,IAAK,CAAA,IAAI,CAAC,CAAA;AAAA,CAAA,CAAA;AAGX,EAAI,IAAA,IAAA,CAAA;AACJ,EAAA,IAAI,IAAI,IAAM,EAAA;AACZ,IAAA,IAAI,GAAM,GAAA,IAAI,OAAQ,CAAA,GAAA,CAAI,OAAO,CAAA,CAAA;AACjC,IAAI,IAAA,EAAA,GAAK,GAAI,CAAA,GAAA,CAAI,cAAc,CAAA,CAAA;AAC/B,IAAA,IAAI,OAAO,0BAA4B,EAAA,CAEvC,MAAA,IAAW,GAAI,CAAA,IAAA,YAAgB,cAAgB,EAAA;AAC7C,MAAA,MAAM,CAAC,CAAG,EAAA,CAAC,CAAI,GAAA,GAAA,CAAI,KAAK,GAAI,EAAA,CAAA;AAC5B,MAAA,GAAA,CAAI,IAAO,GAAA,CAAA,CAAA;AACX,MAAA,MAAM,SAAS,GAAI,CAAA,MAAA,CAAA;AACnB,MAAA,IAAA,GAAO,OAAQ,CAAA,OAAA,EAAU,CAAA,IAAA,CAAK,YAAY;AACxC,QAAM,MAAA,MAAA,GAAS,EAAE,SAAU,EAAA,CAAA;AAC3B,QAAA,GAAA,CAAI,GAAG,CAAA,CAAA;AACP,QAAA,OAAO,IAAM,EAAA;AACX,UAAA,IAAI,iCAAQ,OAAS,EAAA;AACnB,YAAA,MAAA;AAAA,WACF;AAEA,UAAA,IAAI,EAAE,IAAAA,EAAAA,KAAAA,EAAM,OAAU,GAAA,MAAM,OAAO,IAAK,EAAA,CAAA;AACxC,UAAA,KAAA,YAAiB,eAAe,KAAQ,GAAA,IAAI,WAAY,EAAA,CAAE,OAAO,KAAK,CAAA,CAAA,CAAA;AACtE,UAAO,GAAA,IAAA,KAAA,CAAA;AACP,UAAA,GAAA,CAAI,KAAK,CAAA,CAAA;AACT,UAAA,IAAI,CAACA,KAAM,EAAA;AACT,YAAA,MAAA;AAAA,WACF;AAAA,SACF;AAEA,QAAO,GAAA,IAAA,CAAA;AAAA,CAAA,CAAA;AACP,QAAO,OAAA,GAAA,CAAA;AAAA,OACR,CAAA,CAAA;AAAA,KACI,MAAA;AACL,MAAO,GAAA,IAAA,CAAA;AAAA,EACX,IAAI,IAAI,CAAA;AAAA,CAAA,CAAA;AAAA,KAEN;AACA,IAAA,GAAA,CAAI,GAAG,CAAA,CAAA;AAAA,GACT;AACA,EAAO,OAAA,IAAA,IAAQ,OAAQ,CAAA,OAAA,CAAQ,GAAG,CAAA,CAAA;AACpC;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wener/utils",
3
- "version": "1.1.24",
3
+ "version": "1.1.25",
4
4
  "type": "module",
5
5
  "description": "Utils for daily use",
6
6
  "repository": {
@@ -47,6 +47,7 @@ function binaryOf(s: BinaryLike) {
47
47
  if (typeof s === 'string') {
48
48
  return new TextEncoder().encode(s);
49
49
  }
50
+ // ArrayBuffer, Buffer, TypedArray, DataView
50
51
  return s;
51
52
  }
52
53
 
@@ -101,9 +101,30 @@ class DetailHolder implements ErrorDetail {
101
101
  }
102
102
  }
103
103
 
104
- throw(o?: Partial<ErrorDetailInit>): never {
104
+ throw(o?: string | Partial<ErrorDetailInit>): never {
105
105
  throw this.asError(o);
106
106
  }
107
+
108
+ toJSON() {
109
+ return {
110
+ code: this.code,
111
+ message: this.message,
112
+ status: this.status,
113
+ description: this.description,
114
+ cause: this.cause,
115
+ metadata: this.metadata,
116
+ };
117
+ }
118
+
119
+ asResponse(): Response {
120
+ return new Response(JSON.stringify(this.toJSON()), {
121
+ status: this.status,
122
+ statusText: this.description,
123
+ headers: {
124
+ 'Content-Type': 'application/json',
125
+ },
126
+ });
127
+ }
107
128
  }
108
129
 
109
130
  export interface ErrorDetail {
@@ -118,11 +139,11 @@ export interface ErrorDetail {
118
139
 
119
140
  with(o?: Partial<ErrorDetailInit>): ErrorDetail;
120
141
 
121
- asError(o?: Partial<ErrorDetailInit>): Error;
142
+ asError(o?: string | Partial<ErrorDetailInit>): Error;
122
143
 
123
- asError(message: string): Error;
144
+ asResponse(): Response;
124
145
 
125
- throw(o?: Partial<ErrorDetailInit>): never;
146
+ throw(o?: string | Partial<ErrorDetailInit>): never;
126
147
 
127
148
  require<T>(v: T | undefined, o?: Partial<ErrorDetailInit> | string): NonNullable<T>;
128
149
 
@@ -143,6 +164,8 @@ export class Errors {
143
164
  static NotImplemented: ErrorDetail = this.with({ status: 501 });
144
165
  static ServiceUnavailable: ErrorDetail = this.with({ status: 503 });
145
166
 
167
+ static resolvers: ((e: any) => ErrorDetail | void)[] = [];
168
+
146
169
  static with(init: ErrorDetailInit): ErrorDetail {
147
170
  return new DetailHolder(init);
148
171
  }
@@ -171,6 +194,13 @@ export class Errors {
171
194
  return e.detail;
172
195
  }
173
196
 
197
+ for (const resolver of this.resolvers) {
198
+ const r = resolver(e);
199
+ if (r) {
200
+ return r;
201
+ }
202
+ }
203
+
174
204
  if (e instanceof Error) {
175
205
  const { message, code, status } = e as any;
176
206
  // can get status from NestJS HttpException
@@ -16,7 +16,11 @@ ${Array.from(new Headers(req.headers).entries())
16
16
 
17
17
  let done: Promise<string> | undefined;
18
18
  if (req.body) {
19
- if (req.body instanceof ReadableStream) {
19
+ let hdr = new Headers(req.headers);
20
+ let ct = hdr.get('content-type');
21
+ if (ct === 'application/octet-stream') {
22
+ // skip
23
+ } else if (req.body instanceof ReadableStream) {
20
24
  const [a, b] = req.body.tee();
21
25
  req.body = a;
22
26
  const signal = req.signal;