@shware/http 1.0.4 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -21,6 +21,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var hono_exports = {};
22
22
  __export(hono_exports, {
23
23
  Authorizer: () => import_authorizer.Authorizer,
24
+ bigintId: () => import_validator.bigintId,
24
25
  errorHandler: () => import_handler.errorHandler,
25
26
  geolocation: () => import_geolocation.geolocation,
26
27
  zValidator: () => import_validator.zValidator
@@ -33,6 +34,7 @@ var import_authorizer = require("./authorizer.cjs");
33
34
  // Annotate the CommonJS export names for ESM import in node:
34
35
  0 && (module.exports = {
35
36
  Authorizer,
37
+ bigintId,
36
38
  errorHandler,
37
39
  geolocation,
38
40
  zValidator
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/hono/index.ts"],"sourcesContent":["export { zValidator } from './validator';\nexport { errorHandler } from './handler';\nexport { geolocation } from './geolocation';\nexport { Authorizer } from './authorizer';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,uBAA2B;AAC3B,qBAA6B;AAC7B,yBAA4B;AAC5B,wBAA2B;","names":[]}
1
+ {"version":3,"sources":["../../src/hono/index.ts"],"sourcesContent":["export { zValidator, bigintId } from './validator';\nexport { errorHandler } from './handler';\nexport { geolocation } from './geolocation';\nexport { Authorizer } from './authorizer';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,uBAAqC;AACrC,qBAA6B;AAC7B,yBAA4B;AAC5B,wBAA2B;","names":[]}
@@ -1,12 +1,12 @@
1
- export { zValidator } from './validator.cjs';
1
+ export { bigintId, zValidator } from './validator.cjs';
2
2
  export { errorHandler } from './handler.cjs';
3
3
  export { geolocation } from './geolocation.cjs';
4
4
  export { Authorizer } from './authorizer.cjs';
5
+ import 'zod/v4-mini';
5
6
  import 'hono/utils/headers';
6
7
  import 'hono/types';
7
8
  import 'hono';
8
9
  import 'zod/v4/core';
9
10
  import 'zod/v4';
10
- import 'zod/v4-mini';
11
11
  import 'hono/request-id';
12
12
  import 'axios';
@@ -1,12 +1,12 @@
1
- export { zValidator } from './validator.js';
1
+ export { bigintId, zValidator } from './validator.js';
2
2
  export { errorHandler } from './handler.js';
3
3
  export { geolocation } from './geolocation.js';
4
4
  export { Authorizer } from './authorizer.js';
5
+ import 'zod/v4-mini';
5
6
  import 'hono/utils/headers';
6
7
  import 'hono/types';
7
8
  import 'hono';
8
9
  import 'zod/v4/core';
9
10
  import 'zod/v4';
10
- import 'zod/v4-mini';
11
11
  import 'hono/request-id';
12
12
  import 'axios';
@@ -1,10 +1,11 @@
1
1
  // src/hono/index.ts
2
- import { zValidator } from "./validator.mjs";
2
+ import { zValidator, bigintId } from "./validator.mjs";
3
3
  import { errorHandler } from "./handler.mjs";
4
4
  import { geolocation } from "./geolocation.mjs";
5
5
  import { Authorizer } from "./authorizer.mjs";
6
6
  export {
7
7
  Authorizer,
8
+ bigintId,
8
9
  errorHandler,
9
10
  geolocation,
10
11
  zValidator
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/hono/index.ts"],"sourcesContent":["export { zValidator } from './validator';\nexport { errorHandler } from './handler';\nexport { geolocation } from './geolocation';\nexport { Authorizer } from './authorizer';\n"],"mappings":";AAAA,SAAS,kBAAkB;AAC3B,SAAS,oBAAoB;AAC7B,SAAS,mBAAmB;AAC5B,SAAS,kBAAkB;","names":[]}
1
+ {"version":3,"sources":["../../src/hono/index.ts"],"sourcesContent":["export { zValidator, bigintId } from './validator';\nexport { errorHandler } from './handler';\nexport { geolocation } from './geolocation';\nexport { Authorizer } from './authorizer';\n"],"mappings":";AAAA,SAAS,YAAY,gBAAgB;AACrC,SAAS,oBAAoB;AAC7B,SAAS,mBAAmB;AAC5B,SAAS,kBAAkB;","names":[]}
@@ -20,9 +20,12 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/hono/validator.ts
21
21
  var validator_exports = {};
22
22
  __export(validator_exports, {
23
+ bigintId: () => bigintId,
23
24
  zValidator: () => zValidator
24
25
  });
25
26
  module.exports = __toCommonJS(validator_exports);
27
+ var import_v4_mini = require("zod/v4-mini");
28
+ var import_v4 = require("zod/v4");
26
29
  var import_validator = require("hono/validator");
27
30
  var import_status = require("../status.cjs");
28
31
  var import_detail = require("../detail.cjs");
@@ -37,8 +40,26 @@ function zValidator(target, schema) {
37
40
  throw import_status.Status.invalidArgument().error(details);
38
41
  });
39
42
  }
43
+ var bigintId = (0, import_v4_mini.pipe)(
44
+ (0, import_v4_mini.string)(),
45
+ (0, import_v4_mini.transform)((input, ctx) => {
46
+ if (!/^(0|[1-9]\d{0,19})$/.test(input)) {
47
+ const message = `Invalid bigint id: ${input}`;
48
+ ctx.issues.push({ code: "custom", input, message });
49
+ return import_v4.NEVER;
50
+ }
51
+ try {
52
+ return BigInt(input);
53
+ } catch (_) {
54
+ const message = `Parse bigint id: ${input} failed`;
55
+ ctx.issues.push({ code: "custom", input, message });
56
+ return import_v4.NEVER;
57
+ }
58
+ })
59
+ );
40
60
  // Annotate the CommonJS export names for ESM import in node:
41
61
  0 && (module.exports = {
62
+ bigintId,
42
63
  zValidator
43
64
  });
44
65
  //# sourceMappingURL=validator.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/hono/validator.ts"],"sourcesContent":["import type { output as outputV4, ZodType } from 'zod/v4';\nimport type { output as outputMini, ZodMiniType } from 'zod/v4-mini';\nimport type { ValidationTargets } from 'hono';\nimport { validator } from 'hono/validator';\nimport { Status } from '../status';\nimport { Details } from '../detail';\nimport type { BadRequest } from '../detail';\n\nexport function zValidator<S extends ZodType | ZodMiniType>(\n target: keyof ValidationTargets,\n schema: S\n) {\n return validator(target, async (value) => {\n const result = await schema.safeParseAsync(value);\n if (result.success) return result.data as S extends ZodType ? outputV4<S> : outputMini<S>;\n\n const fieldViolations: BadRequest['fieldViolations'] = result.error.issues.map(\n ({ path, message }) => ({ field: path.join('.'), description: message })\n );\n const details = Details.new().badRequest({ fieldViolations });\n throw Status.invalidArgument().error(details);\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,uBAA0B;AAC1B,oBAAuB;AACvB,oBAAwB;AAGjB,SAAS,WACd,QACA,QACA;AACA,aAAO,4BAAU,QAAQ,OAAO,UAAU;AACxC,UAAM,SAAS,MAAM,OAAO,eAAe,KAAK;AAChD,QAAI,OAAO,QAAS,QAAO,OAAO;AAElC,UAAM,kBAAiD,OAAO,MAAM,OAAO;AAAA,MACzE,CAAC,EAAE,MAAM,QAAQ,OAAO,EAAE,OAAO,KAAK,KAAK,GAAG,GAAG,aAAa,QAAQ;AAAA,IACxE;AACA,UAAM,UAAU,sBAAQ,IAAI,EAAE,WAAW,EAAE,gBAAgB,CAAC;AAC5D,UAAM,qBAAO,gBAAgB,EAAE,MAAM,OAAO;AAAA,EAC9C,CAAC;AACH;","names":[]}
1
+ {"version":3,"sources":["../../src/hono/validator.ts"],"sourcesContent":["import { transform, pipe, string } from 'zod/v4-mini';\nimport { NEVER } from 'zod/v4';\nimport { validator } from 'hono/validator';\nimport { Status } from '../status';\nimport { Details } from '../detail';\nimport type { ValidationTargets } from 'hono';\nimport type { output as outputV4, ZodType } from 'zod/v4';\nimport type { output as outputMini, ZodMiniType } from 'zod/v4-mini';\nimport type { BadRequest } from '../detail';\n\nexport function zValidator<S extends ZodType | ZodMiniType>(\n target: keyof ValidationTargets,\n schema: S\n) {\n return validator(target, async (value) => {\n const result = await schema.safeParseAsync(value);\n if (result.success) return result.data as S extends ZodType ? outputV4<S> : outputMini<S>;\n\n const fieldViolations: BadRequest['fieldViolations'] = result.error.issues.map(\n ({ path, message }) => ({ field: path.join('.'), description: message })\n );\n const details = Details.new().badRequest({ fieldViolations });\n throw Status.invalidArgument().error(details);\n });\n}\n\nexport const bigintId = pipe(\n string(),\n transform((input, ctx) => {\n if (!/^(0|[1-9]\\d{0,19})$/.test(input)) {\n const message = `Invalid bigint id: ${input}`;\n ctx.issues.push({ code: 'custom', input, message });\n return NEVER;\n }\n try {\n return BigInt(input);\n } catch (_) {\n const message = `Parse bigint id: ${input} failed`;\n ctx.issues.push({ code: 'custom', input, message });\n return NEVER;\n }\n })\n);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,qBAAwC;AACxC,gBAAsB;AACtB,uBAA0B;AAC1B,oBAAuB;AACvB,oBAAwB;AAMjB,SAAS,WACd,QACA,QACA;AACA,aAAO,4BAAU,QAAQ,OAAO,UAAU;AACxC,UAAM,SAAS,MAAM,OAAO,eAAe,KAAK;AAChD,QAAI,OAAO,QAAS,QAAO,OAAO;AAElC,UAAM,kBAAiD,OAAO,MAAM,OAAO;AAAA,MACzE,CAAC,EAAE,MAAM,QAAQ,OAAO,EAAE,OAAO,KAAK,KAAK,GAAG,GAAG,aAAa,QAAQ;AAAA,IACxE;AACA,UAAM,UAAU,sBAAQ,IAAI,EAAE,WAAW,EAAE,gBAAgB,CAAC;AAC5D,UAAM,qBAAO,gBAAgB,EAAE,MAAM,OAAO;AAAA,EAC9C,CAAC;AACH;AAEO,IAAM,eAAW;AAAA,MACtB,uBAAO;AAAA,MACP,0BAAU,CAAC,OAAO,QAAQ;AACxB,QAAI,CAAC,sBAAsB,KAAK,KAAK,GAAG;AACtC,YAAM,UAAU,sBAAsB,KAAK;AAC3C,UAAI,OAAO,KAAK,EAAE,MAAM,UAAU,OAAO,QAAQ,CAAC;AAClD,aAAO;AAAA,IACT;AACA,QAAI;AACF,aAAO,OAAO,KAAK;AAAA,IACrB,SAAS,GAAG;AACV,YAAM,UAAU,oBAAoB,KAAK;AACzC,UAAI,OAAO,KAAK,EAAE,MAAM,UAAU,OAAO,QAAQ,CAAC;AAClD,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AACH;","names":[]}
@@ -1,10 +1,11 @@
1
+ import * as zod_v4_mini from 'zod/v4-mini';
2
+ import { ZodMiniType } from 'zod/v4-mini';
1
3
  import * as hono_utils_headers from 'hono/utils/headers';
2
4
  import * as hono_types from 'hono/types';
3
5
  import * as hono from 'hono';
4
6
  import { ValidationTargets } from 'hono';
5
7
  import * as zod_v4_core from 'zod/v4/core';
6
8
  import { ZodType, output } from 'zod/v4';
7
- import { ZodMiniType } from 'zod/v4-mini';
8
9
 
9
10
  declare function zValidator<S extends ZodType | ZodMiniType>(target: keyof ValidationTargets, schema: S): hono.MiddlewareHandler<any, string, {
10
11
  in: {
@@ -24,5 +25,6 @@ declare function zValidator<S extends ZodType | ZodMiniType>(target: keyof Valid
24
25
  cookie: (S extends ZodType<unknown, unknown, zod_v4_core.$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) extends infer T_16 ? T_16 extends (S extends ZodType<unknown, unknown, zod_v4_core.$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) ? T_16 extends Response & hono.TypedResponse<any> ? never : T_16 : never : never;
25
26
  };
26
27
  }>;
28
+ declare const bigintId: zod_v4_mini.ZodMiniPipe<zod_v4_mini.ZodMiniString<string>, zod_v4_mini.ZodMiniTransform<bigint, string>>;
27
29
 
28
- export { zValidator };
30
+ export { bigintId, zValidator };
@@ -1,10 +1,11 @@
1
+ import * as zod_v4_mini from 'zod/v4-mini';
2
+ import { ZodMiniType } from 'zod/v4-mini';
1
3
  import * as hono_utils_headers from 'hono/utils/headers';
2
4
  import * as hono_types from 'hono/types';
3
5
  import * as hono from 'hono';
4
6
  import { ValidationTargets } from 'hono';
5
7
  import * as zod_v4_core from 'zod/v4/core';
6
8
  import { ZodType, output } from 'zod/v4';
7
- import { ZodMiniType } from 'zod/v4-mini';
8
9
 
9
10
  declare function zValidator<S extends ZodType | ZodMiniType>(target: keyof ValidationTargets, schema: S): hono.MiddlewareHandler<any, string, {
10
11
  in: {
@@ -24,5 +25,6 @@ declare function zValidator<S extends ZodType | ZodMiniType>(target: keyof Valid
24
25
  cookie: (S extends ZodType<unknown, unknown, zod_v4_core.$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) extends infer T_16 ? T_16 extends (S extends ZodType<unknown, unknown, zod_v4_core.$ZodTypeInternals<unknown, unknown>> ? output<S> : output<S>) ? T_16 extends Response & hono.TypedResponse<any> ? never : T_16 : never : never;
25
26
  };
26
27
  }>;
28
+ declare const bigintId: zod_v4_mini.ZodMiniPipe<zod_v4_mini.ZodMiniString<string>, zod_v4_mini.ZodMiniTransform<bigint, string>>;
27
29
 
28
- export { zValidator };
30
+ export { bigintId, zValidator };
@@ -1,4 +1,6 @@
1
1
  // src/hono/validator.ts
2
+ import { transform, pipe, string } from "zod/v4-mini";
3
+ import { NEVER } from "zod/v4";
2
4
  import { validator } from "hono/validator";
3
5
  import { Status } from "../status.mjs";
4
6
  import { Details } from "../detail.mjs";
@@ -13,7 +15,25 @@ function zValidator(target, schema) {
13
15
  throw Status.invalidArgument().error(details);
14
16
  });
15
17
  }
18
+ var bigintId = pipe(
19
+ string(),
20
+ transform((input, ctx) => {
21
+ if (!/^(0|[1-9]\d{0,19})$/.test(input)) {
22
+ const message = `Invalid bigint id: ${input}`;
23
+ ctx.issues.push({ code: "custom", input, message });
24
+ return NEVER;
25
+ }
26
+ try {
27
+ return BigInt(input);
28
+ } catch (_) {
29
+ const message = `Parse bigint id: ${input} failed`;
30
+ ctx.issues.push({ code: "custom", input, message });
31
+ return NEVER;
32
+ }
33
+ })
34
+ );
16
35
  export {
36
+ bigintId,
17
37
  zValidator
18
38
  };
19
39
  //# sourceMappingURL=validator.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/hono/validator.ts"],"sourcesContent":["import type { output as outputV4, ZodType } from 'zod/v4';\nimport type { output as outputMini, ZodMiniType } from 'zod/v4-mini';\nimport type { ValidationTargets } from 'hono';\nimport { validator } from 'hono/validator';\nimport { Status } from '../status';\nimport { Details } from '../detail';\nimport type { BadRequest } from '../detail';\n\nexport function zValidator<S extends ZodType | ZodMiniType>(\n target: keyof ValidationTargets,\n schema: S\n) {\n return validator(target, async (value) => {\n const result = await schema.safeParseAsync(value);\n if (result.success) return result.data as S extends ZodType ? outputV4<S> : outputMini<S>;\n\n const fieldViolations: BadRequest['fieldViolations'] = result.error.issues.map(\n ({ path, message }) => ({ field: path.join('.'), description: message })\n );\n const details = Details.new().badRequest({ fieldViolations });\n throw Status.invalidArgument().error(details);\n });\n}\n"],"mappings":";AAGA,SAAS,iBAAiB;AAC1B,SAAS,cAAc;AACvB,SAAS,eAAe;AAGjB,SAAS,WACd,QACA,QACA;AACA,SAAO,UAAU,QAAQ,OAAO,UAAU;AACxC,UAAM,SAAS,MAAM,OAAO,eAAe,KAAK;AAChD,QAAI,OAAO,QAAS,QAAO,OAAO;AAElC,UAAM,kBAAiD,OAAO,MAAM,OAAO;AAAA,MACzE,CAAC,EAAE,MAAM,QAAQ,OAAO,EAAE,OAAO,KAAK,KAAK,GAAG,GAAG,aAAa,QAAQ;AAAA,IACxE;AACA,UAAM,UAAU,QAAQ,IAAI,EAAE,WAAW,EAAE,gBAAgB,CAAC;AAC5D,UAAM,OAAO,gBAAgB,EAAE,MAAM,OAAO;AAAA,EAC9C,CAAC;AACH;","names":[]}
1
+ {"version":3,"sources":["../../src/hono/validator.ts"],"sourcesContent":["import { transform, pipe, string } from 'zod/v4-mini';\nimport { NEVER } from 'zod/v4';\nimport { validator } from 'hono/validator';\nimport { Status } from '../status';\nimport { Details } from '../detail';\nimport type { ValidationTargets } from 'hono';\nimport type { output as outputV4, ZodType } from 'zod/v4';\nimport type { output as outputMini, ZodMiniType } from 'zod/v4-mini';\nimport type { BadRequest } from '../detail';\n\nexport function zValidator<S extends ZodType | ZodMiniType>(\n target: keyof ValidationTargets,\n schema: S\n) {\n return validator(target, async (value) => {\n const result = await schema.safeParseAsync(value);\n if (result.success) return result.data as S extends ZodType ? outputV4<S> : outputMini<S>;\n\n const fieldViolations: BadRequest['fieldViolations'] = result.error.issues.map(\n ({ path, message }) => ({ field: path.join('.'), description: message })\n );\n const details = Details.new().badRequest({ fieldViolations });\n throw Status.invalidArgument().error(details);\n });\n}\n\nexport const bigintId = pipe(\n string(),\n transform((input, ctx) => {\n if (!/^(0|[1-9]\\d{0,19})$/.test(input)) {\n const message = `Invalid bigint id: ${input}`;\n ctx.issues.push({ code: 'custom', input, message });\n return NEVER;\n }\n try {\n return BigInt(input);\n } catch (_) {\n const message = `Parse bigint id: ${input} failed`;\n ctx.issues.push({ code: 'custom', input, message });\n return NEVER;\n }\n })\n);\n"],"mappings":";AAAA,SAAS,WAAW,MAAM,cAAc;AACxC,SAAS,aAAa;AACtB,SAAS,iBAAiB;AAC1B,SAAS,cAAc;AACvB,SAAS,eAAe;AAMjB,SAAS,WACd,QACA,QACA;AACA,SAAO,UAAU,QAAQ,OAAO,UAAU;AACxC,UAAM,SAAS,MAAM,OAAO,eAAe,KAAK;AAChD,QAAI,OAAO,QAAS,QAAO,OAAO;AAElC,UAAM,kBAAiD,OAAO,MAAM,OAAO;AAAA,MACzE,CAAC,EAAE,MAAM,QAAQ,OAAO,EAAE,OAAO,KAAK,KAAK,GAAG,GAAG,aAAa,QAAQ;AAAA,IACxE;AACA,UAAM,UAAU,QAAQ,IAAI,EAAE,WAAW,EAAE,gBAAgB,CAAC;AAC5D,UAAM,OAAO,gBAAgB,EAAE,MAAM,OAAO;AAAA,EAC9C,CAAC;AACH;AAEO,IAAM,WAAW;AAAA,EACtB,OAAO;AAAA,EACP,UAAU,CAAC,OAAO,QAAQ;AACxB,QAAI,CAAC,sBAAsB,KAAK,KAAK,GAAG;AACtC,YAAM,UAAU,sBAAsB,KAAK;AAC3C,UAAI,OAAO,KAAK,EAAE,MAAM,UAAU,OAAO,QAAQ,CAAC;AAClD,aAAO;AAAA,IACT;AACA,QAAI;AACF,aAAO,OAAO,KAAK;AAAA,IACrB,SAAS,GAAG;AACV,YAAM,UAAU,oBAAoB,KAAK;AACzC,UAAI,OAAO,KAAK,EAAE,MAAM,UAAU,OAAO,QAAQ,CAAC;AAClD,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AACH;","names":[]}
package/dist/index.cjs CHANGED
@@ -39,8 +39,7 @@ __export(index_exports, {
39
39
  TokenBucket: () => import_token_bucket.TokenBucket,
40
40
  hasText: () => import_string.hasText,
41
41
  invariant: () => import_invariant.invariant,
42
- timing: () => import_timing.timing,
43
- verifyStandardWebhook: () => import_webhook.verifyStandardWebhook
42
+ timing: () => import_timing.timing
44
43
  });
45
44
  module.exports = __toCommonJS(index_exports);
46
45
  __reExport(index_exports, require("./detail.cjs"), module.exports);
@@ -51,7 +50,6 @@ __reExport(index_exports, require("./response.cjs"), module.exports);
51
50
  var MAX_LENGTH = __toESM(require("./max-length/index.cjs"), 1);
52
51
  var import_string = require("./utils/string.cjs");
53
52
  var import_timing = require("./utils/timing.cjs");
54
- var import_webhook = require("./webhook.cjs");
55
53
  var import_invariant = require("./utils/invariant.cjs");
56
54
  var import_token_bucket = require("./utils/token-bucket.cjs");
57
55
  var import_error = require("./error/index.cjs");
@@ -66,7 +64,6 @@ var import_error = require("./error/index.cjs");
66
64
  hasText,
67
65
  invariant,
68
66
  timing,
69
- verifyStandardWebhook,
70
67
  ...require("./detail.cjs"),
71
68
  ...require("./status.cjs"),
72
69
  ...require("./vaild.cjs"),
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.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 type {\n NetworkErrorReason,\n StatusErrorReason,\n AuthenticationErrorReason,\n ModerationErrorReason,\n MultipartErrorReason,\n AppErrorReason,\n ErrorReason,\n} from './reason';\n\nexport * from './detail';\nexport * from './status';\nexport * from './vaild';\nexport * from './snowflake';\nexport * from './response';\nexport * as MAX_LENGTH from './max-length/index';\nexport { hasText } from './utils/string';\nexport { timing } from './utils/timing';\nexport { verifyStandardWebhook } from './webhook';\nexport { invariant } from './utils/invariant';\nexport { TokenBucket, type TokenBucketOptions } from './utils/token-bucket';\n\nexport {\n LoginTimeoutError,\n LoginCanceledError,\n CheckoutCreateError,\n PurchaseError,\n} from './error/index';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAuBA,0BAAc,yBAvBd;AAwBA,0BAAc,yBAxBd;AAyBA,0BAAc,wBAzBd;AA0BA,0BAAc,4BA1Bd;AA2BA,0BAAc,2BA3Bd;AA4BA,iBAA4B;AAC5B,oBAAwB;AACxB,oBAAuB;AACvB,qBAAsC;AACtC,uBAA0B;AAC1B,0BAAqD;AAErD,mBAKO;","names":[]}
1
+ {"version":3,"sources":["../src/index.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 type {\n NetworkErrorReason,\n StatusErrorReason,\n AuthenticationErrorReason,\n ModerationErrorReason,\n MultipartErrorReason,\n AppErrorReason,\n ErrorReason,\n} from './reason';\n\nexport * from './detail';\nexport * from './status';\nexport * from './vaild';\nexport * from './snowflake';\nexport * from './response';\nexport * as MAX_LENGTH from './max-length/index';\nexport { hasText } from './utils/string';\nexport { timing } from './utils/timing';\nexport { invariant } from './utils/invariant';\nexport { TokenBucket, type TokenBucketOptions } from './utils/token-bucket';\n\nexport {\n LoginTimeoutError,\n LoginCanceledError,\n CheckoutCreateError,\n PurchaseError,\n} from './error/index';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAuBA,0BAAc,yBAvBd;AAwBA,0BAAc,yBAxBd;AAyBA,0BAAc,wBAzBd;AA0BA,0BAAc,4BA1Bd;AA2BA,0BAAc,2BA3Bd;AA4BA,iBAA4B;AAC5B,oBAAwB;AACxB,oBAAuB;AACvB,uBAA0B;AAC1B,0BAAqD;AAErD,mBAKO;","names":[]}
package/dist/index.d.cts CHANGED
@@ -7,7 +7,6 @@ export { Cursor, Empty, Entity, EntityId, InitParams, NextParams, PageParams, Pa
7
7
  export { i as MAX_LENGTH } from './index-BnPgRQDl.cjs';
8
8
  export { hasText } from './utils/string.cjs';
9
9
  export { timing } from './utils/timing.cjs';
10
- export { verifyStandardWebhook } from './webhook.cjs';
11
10
  export { invariant } from './utils/invariant.cjs';
12
11
  export { TokenBucket, TokenBucketOptions } from './utils/token-bucket.cjs';
13
12
  export { CheckoutCreateError, LoginCanceledError, LoginTimeoutError, PurchaseError } from './error/index.cjs';
package/dist/index.d.ts CHANGED
@@ -7,7 +7,6 @@ export { Cursor, Empty, Entity, EntityId, InitParams, NextParams, PageParams, Pa
7
7
  export { i as MAX_LENGTH } from './index-BnPgRQDl.js';
8
8
  export { hasText } from './utils/string.js';
9
9
  export { timing } from './utils/timing.js';
10
- export { verifyStandardWebhook } from './webhook.js';
11
10
  export { invariant } from './utils/invariant.js';
12
11
  export { TokenBucket, TokenBucketOptions } from './utils/token-bucket.js';
13
12
  export { CheckoutCreateError, LoginCanceledError, LoginTimeoutError, PurchaseError } from './error/index.js';
package/dist/index.mjs CHANGED
@@ -7,7 +7,6 @@ export * from "./response.mjs";
7
7
  import * as MAX_LENGTH from "./max-length/index.mjs";
8
8
  import { hasText } from "./utils/string.mjs";
9
9
  import { timing } from "./utils/timing.mjs";
10
- import { verifyStandardWebhook } from "./webhook.mjs";
11
10
  import { invariant } from "./utils/invariant.mjs";
12
11
  import { TokenBucket } from "./utils/token-bucket.mjs";
13
12
  import {
@@ -25,7 +24,6 @@ export {
25
24
  TokenBucket,
26
25
  hasText,
27
26
  invariant,
28
- timing,
29
- verifyStandardWebhook
27
+ timing
30
28
  };
31
29
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.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 type {\n NetworkErrorReason,\n StatusErrorReason,\n AuthenticationErrorReason,\n ModerationErrorReason,\n MultipartErrorReason,\n AppErrorReason,\n ErrorReason,\n} from './reason';\n\nexport * from './detail';\nexport * from './status';\nexport * from './vaild';\nexport * from './snowflake';\nexport * from './response';\nexport * as MAX_LENGTH from './max-length/index';\nexport { hasText } from './utils/string';\nexport { timing } from './utils/timing';\nexport { verifyStandardWebhook } from './webhook';\nexport { invariant } from './utils/invariant';\nexport { TokenBucket, type TokenBucketOptions } from './utils/token-bucket';\n\nexport {\n LoginTimeoutError,\n LoginCanceledError,\n CheckoutCreateError,\n PurchaseError,\n} from './error/index';\n"],"mappings":";AAuBA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,YAAY,gBAAgB;AAC5B,SAAS,eAAe;AACxB,SAAS,cAAc;AACvB,SAAS,6BAA6B;AACtC,SAAS,iBAAiB;AAC1B,SAAS,mBAA4C;AAErD;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;","names":[]}
1
+ {"version":3,"sources":["../src/index.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 type {\n NetworkErrorReason,\n StatusErrorReason,\n AuthenticationErrorReason,\n ModerationErrorReason,\n MultipartErrorReason,\n AppErrorReason,\n ErrorReason,\n} from './reason';\n\nexport * from './detail';\nexport * from './status';\nexport * from './vaild';\nexport * from './snowflake';\nexport * from './response';\nexport * as MAX_LENGTH from './max-length/index';\nexport { hasText } from './utils/string';\nexport { timing } from './utils/timing';\nexport { invariant } from './utils/invariant';\nexport { TokenBucket, type TokenBucketOptions } from './utils/token-bucket';\n\nexport {\n LoginTimeoutError,\n LoginCanceledError,\n CheckoutCreateError,\n PurchaseError,\n} from './error/index';\n"],"mappings":";AAuBA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,YAAY,gBAAgB;AAC5B,SAAS,eAAe;AACxB,SAAS,cAAc;AACvB,SAAS,iBAAiB;AAC1B,SAAS,mBAA4C;AAErD;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;","names":[]}
@@ -17,14 +17,14 @@ var __copyProps = (to, from, except, desc) => {
17
17
  };
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
 
20
- // src/webhook.ts
20
+ // src/webhook/index.ts
21
21
  var webhook_exports = {};
22
22
  __export(webhook_exports, {
23
23
  verifyStandardWebhook: () => verifyStandardWebhook
24
24
  });
25
25
  module.exports = __toCommonJS(webhook_exports);
26
26
  var import_crypto = require("crypto");
27
- var import_status = require("./status.cjs");
27
+ var import_status = require("../status.cjs");
28
28
  var WEBHOOK_TOLERANCE_IN_SECONDS = 5 * 60;
29
29
  function verifyTimestamp(webhookTimestamp) {
30
30
  const now = Math.floor(Date.now() / 1e3);
@@ -74,4 +74,4 @@ function verifyStandardWebhook(headers, payload, secret) {
74
74
  0 && (module.exports = {
75
75
  verifyStandardWebhook
76
76
  });
77
- //# sourceMappingURL=webhook.cjs.map
77
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/webhook/index.ts"],"sourcesContent":["import { createHmac, timingSafeEqual } from 'crypto';\nimport { Status } from '../status';\n\nconst WEBHOOK_TOLERANCE_IN_SECONDS = 5 * 60; // 5 minutes\n\nfunction verifyTimestamp(webhookTimestamp: string) {\n const now = Math.floor(Date.now() / 1000);\n const timestamp = parseInt(webhookTimestamp, 10);\n if (isNaN(timestamp)) {\n throw Status.invalidArgument('invalid webhook timestamp').error();\n }\n if (timestamp < now - WEBHOOK_TOLERANCE_IN_SECONDS) {\n throw Status.invalidArgument('webhook timestamp is too old').error();\n }\n if (timestamp > now + WEBHOOK_TOLERANCE_IN_SECONDS) {\n throw Status.invalidArgument('webhook timestamp is too new').error();\n }\n return timestamp;\n}\n\n/**\n * reference: https://github.com/standard-webhooks/standard-webhooks/tree/main/libraries/javascript\n * hono usage:\n * ```ts\n * const webhook = verifyStandardWebhook(c.req.header(), await c.req.text(), 'secret');\n * ```\n */\nexport function verifyStandardWebhook<T = unknown>(\n headers: Record<string, string>,\n payload: string,\n secret: string\n): T {\n const webhookId = headers['webhook-id'];\n const webhookTimestamp = headers['webhook-timestamp'];\n const webhookSignature = headers['webhook-signature'];\n if (!webhookId || !webhookTimestamp || !webhookSignature) {\n throw Status.invalidArgument('invalid webhook').error();\n }\n const timestamp = verifyTimestamp(webhookTimestamp);\n\n const encoder = new TextEncoder();\n const toSign = encoder.encode(`${webhookId}.${timestamp}.${payload}`);\n const hmac = createHmac('sha256', Buffer.from(secret, 'base64'));\n const digest = hmac.update(toSign).digest();\n\n const computedSignature = `v1,${Buffer.from(digest).toString('base64')}`;\n const expectedSignature = computedSignature.split(',')[1];\n const passedSignatures = webhookSignature.split(' ');\n\n for (const versionedSignature of passedSignatures) {\n const [version, signature] = versionedSignature.split(',');\n if (version !== 'v1') continue;\n if (timingSafeEqual(encoder.encode(signature), encoder.encode(expectedSignature))) {\n try {\n return JSON.parse(payload) as T;\n } catch (_) {\n console.error('invalid payload', payload);\n throw Status.invalidArgument('invalid webhook payload').error();\n }\n }\n }\n console.error('webhook verification failed');\n throw Status.invalidArgument('invalid webhook signature').error();\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAA4C;AAC5C,oBAAuB;AAEvB,IAAM,+BAA+B,IAAI;AAEzC,SAAS,gBAAgB,kBAA0B;AACjD,QAAM,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AACxC,QAAM,YAAY,SAAS,kBAAkB,EAAE;AAC/C,MAAI,MAAM,SAAS,GAAG;AACpB,UAAM,qBAAO,gBAAgB,2BAA2B,EAAE,MAAM;AAAA,EAClE;AACA,MAAI,YAAY,MAAM,8BAA8B;AAClD,UAAM,qBAAO,gBAAgB,8BAA8B,EAAE,MAAM;AAAA,EACrE;AACA,MAAI,YAAY,MAAM,8BAA8B;AAClD,UAAM,qBAAO,gBAAgB,8BAA8B,EAAE,MAAM;AAAA,EACrE;AACA,SAAO;AACT;AASO,SAAS,sBACd,SACA,SACA,QACG;AACH,QAAM,YAAY,QAAQ,YAAY;AACtC,QAAM,mBAAmB,QAAQ,mBAAmB;AACpD,QAAM,mBAAmB,QAAQ,mBAAmB;AACpD,MAAI,CAAC,aAAa,CAAC,oBAAoB,CAAC,kBAAkB;AACxD,UAAM,qBAAO,gBAAgB,iBAAiB,EAAE,MAAM;AAAA,EACxD;AACA,QAAM,YAAY,gBAAgB,gBAAgB;AAElD,QAAM,UAAU,IAAI,YAAY;AAChC,QAAM,SAAS,QAAQ,OAAO,GAAG,SAAS,IAAI,SAAS,IAAI,OAAO,EAAE;AACpE,QAAM,WAAO,0BAAW,UAAU,OAAO,KAAK,QAAQ,QAAQ,CAAC;AAC/D,QAAM,SAAS,KAAK,OAAO,MAAM,EAAE,OAAO;AAE1C,QAAM,oBAAoB,MAAM,OAAO,KAAK,MAAM,EAAE,SAAS,QAAQ,CAAC;AACtE,QAAM,oBAAoB,kBAAkB,MAAM,GAAG,EAAE,CAAC;AACxD,QAAM,mBAAmB,iBAAiB,MAAM,GAAG;AAEnD,aAAW,sBAAsB,kBAAkB;AACjD,UAAM,CAAC,SAAS,SAAS,IAAI,mBAAmB,MAAM,GAAG;AACzD,QAAI,YAAY,KAAM;AACtB,YAAI,+BAAgB,QAAQ,OAAO,SAAS,GAAG,QAAQ,OAAO,iBAAiB,CAAC,GAAG;AACjF,UAAI;AACF,eAAO,KAAK,MAAM,OAAO;AAAA,MAC3B,SAAS,GAAG;AACV,gBAAQ,MAAM,mBAAmB,OAAO;AACxC,cAAM,qBAAO,gBAAgB,yBAAyB,EAAE,MAAM;AAAA,MAChE;AAAA,IACF;AAAA,EACF;AACA,UAAQ,MAAM,6BAA6B;AAC3C,QAAM,qBAAO,gBAAgB,2BAA2B,EAAE,MAAM;AAClE;","names":[]}
@@ -1,6 +1,6 @@
1
- // src/webhook.ts
1
+ // src/webhook/index.ts
2
2
  import { createHmac, timingSafeEqual } from "crypto";
3
- import { Status } from "./status.mjs";
3
+ import { Status } from "../status.mjs";
4
4
  var WEBHOOK_TOLERANCE_IN_SECONDS = 5 * 60;
5
5
  function verifyTimestamp(webhookTimestamp) {
6
6
  const now = Math.floor(Date.now() / 1e3);
@@ -49,4 +49,4 @@ function verifyStandardWebhook(headers, payload, secret) {
49
49
  export {
50
50
  verifyStandardWebhook
51
51
  };
52
- //# sourceMappingURL=webhook.mjs.map
52
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/webhook/index.ts"],"sourcesContent":["import { createHmac, timingSafeEqual } from 'crypto';\nimport { Status } from '../status';\n\nconst WEBHOOK_TOLERANCE_IN_SECONDS = 5 * 60; // 5 minutes\n\nfunction verifyTimestamp(webhookTimestamp: string) {\n const now = Math.floor(Date.now() / 1000);\n const timestamp = parseInt(webhookTimestamp, 10);\n if (isNaN(timestamp)) {\n throw Status.invalidArgument('invalid webhook timestamp').error();\n }\n if (timestamp < now - WEBHOOK_TOLERANCE_IN_SECONDS) {\n throw Status.invalidArgument('webhook timestamp is too old').error();\n }\n if (timestamp > now + WEBHOOK_TOLERANCE_IN_SECONDS) {\n throw Status.invalidArgument('webhook timestamp is too new').error();\n }\n return timestamp;\n}\n\n/**\n * reference: https://github.com/standard-webhooks/standard-webhooks/tree/main/libraries/javascript\n * hono usage:\n * ```ts\n * const webhook = verifyStandardWebhook(c.req.header(), await c.req.text(), 'secret');\n * ```\n */\nexport function verifyStandardWebhook<T = unknown>(\n headers: Record<string, string>,\n payload: string,\n secret: string\n): T {\n const webhookId = headers['webhook-id'];\n const webhookTimestamp = headers['webhook-timestamp'];\n const webhookSignature = headers['webhook-signature'];\n if (!webhookId || !webhookTimestamp || !webhookSignature) {\n throw Status.invalidArgument('invalid webhook').error();\n }\n const timestamp = verifyTimestamp(webhookTimestamp);\n\n const encoder = new TextEncoder();\n const toSign = encoder.encode(`${webhookId}.${timestamp}.${payload}`);\n const hmac = createHmac('sha256', Buffer.from(secret, 'base64'));\n const digest = hmac.update(toSign).digest();\n\n const computedSignature = `v1,${Buffer.from(digest).toString('base64')}`;\n const expectedSignature = computedSignature.split(',')[1];\n const passedSignatures = webhookSignature.split(' ');\n\n for (const versionedSignature of passedSignatures) {\n const [version, signature] = versionedSignature.split(',');\n if (version !== 'v1') continue;\n if (timingSafeEqual(encoder.encode(signature), encoder.encode(expectedSignature))) {\n try {\n return JSON.parse(payload) as T;\n } catch (_) {\n console.error('invalid payload', payload);\n throw Status.invalidArgument('invalid webhook payload').error();\n }\n }\n }\n console.error('webhook verification failed');\n throw Status.invalidArgument('invalid webhook signature').error();\n}\n"],"mappings":";AAAA,SAAS,YAAY,uBAAuB;AAC5C,SAAS,cAAc;AAEvB,IAAM,+BAA+B,IAAI;AAEzC,SAAS,gBAAgB,kBAA0B;AACjD,QAAM,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AACxC,QAAM,YAAY,SAAS,kBAAkB,EAAE;AAC/C,MAAI,MAAM,SAAS,GAAG;AACpB,UAAM,OAAO,gBAAgB,2BAA2B,EAAE,MAAM;AAAA,EAClE;AACA,MAAI,YAAY,MAAM,8BAA8B;AAClD,UAAM,OAAO,gBAAgB,8BAA8B,EAAE,MAAM;AAAA,EACrE;AACA,MAAI,YAAY,MAAM,8BAA8B;AAClD,UAAM,OAAO,gBAAgB,8BAA8B,EAAE,MAAM;AAAA,EACrE;AACA,SAAO;AACT;AASO,SAAS,sBACd,SACA,SACA,QACG;AACH,QAAM,YAAY,QAAQ,YAAY;AACtC,QAAM,mBAAmB,QAAQ,mBAAmB;AACpD,QAAM,mBAAmB,QAAQ,mBAAmB;AACpD,MAAI,CAAC,aAAa,CAAC,oBAAoB,CAAC,kBAAkB;AACxD,UAAM,OAAO,gBAAgB,iBAAiB,EAAE,MAAM;AAAA,EACxD;AACA,QAAM,YAAY,gBAAgB,gBAAgB;AAElD,QAAM,UAAU,IAAI,YAAY;AAChC,QAAM,SAAS,QAAQ,OAAO,GAAG,SAAS,IAAI,SAAS,IAAI,OAAO,EAAE;AACpE,QAAM,OAAO,WAAW,UAAU,OAAO,KAAK,QAAQ,QAAQ,CAAC;AAC/D,QAAM,SAAS,KAAK,OAAO,MAAM,EAAE,OAAO;AAE1C,QAAM,oBAAoB,MAAM,OAAO,KAAK,MAAM,EAAE,SAAS,QAAQ,CAAC;AACtE,QAAM,oBAAoB,kBAAkB,MAAM,GAAG,EAAE,CAAC;AACxD,QAAM,mBAAmB,iBAAiB,MAAM,GAAG;AAEnD,aAAW,sBAAsB,kBAAkB;AACjD,UAAM,CAAC,SAAS,SAAS,IAAI,mBAAmB,MAAM,GAAG;AACzD,QAAI,YAAY,KAAM;AACtB,QAAI,gBAAgB,QAAQ,OAAO,SAAS,GAAG,QAAQ,OAAO,iBAAiB,CAAC,GAAG;AACjF,UAAI;AACF,eAAO,KAAK,MAAM,OAAO;AAAA,MAC3B,SAAS,GAAG;AACV,gBAAQ,MAAM,mBAAmB,OAAO;AACxC,cAAM,OAAO,gBAAgB,yBAAyB,EAAE,MAAM;AAAA,MAChE;AAAA,IACF;AAAA,EACF;AACA,UAAQ,MAAM,6BAA6B;AAC3C,QAAM,OAAO,gBAAgB,2BAA2B,EAAE,MAAM;AAClE;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shware/http",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "scripts": {
@@ -28,6 +28,11 @@
28
28
  "import": "./dist/hono/index.mjs",
29
29
  "require": "./dist/hono/index.cjs"
30
30
  },
31
+ "./webhook": {
32
+ "types": "./dist/webhook/index.d.ts",
33
+ "import": "./dist/webhook/index.mjs",
34
+ "require": "./dist/webhook/index.cjs"
35
+ },
31
36
  "./google-one-tap": {
32
37
  "types": "./dist/google-one-tap/index.d.ts",
33
38
  "import": "./dist/google-one-tap/index.mjs",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/webhook.ts"],"sourcesContent":["import { createHmac, timingSafeEqual } from 'crypto';\nimport { Status } from './status';\n\nconst WEBHOOK_TOLERANCE_IN_SECONDS = 5 * 60; // 5 minutes\n\nfunction verifyTimestamp(webhookTimestamp: string) {\n const now = Math.floor(Date.now() / 1000);\n const timestamp = parseInt(webhookTimestamp, 10);\n if (isNaN(timestamp)) {\n throw Status.invalidArgument('invalid webhook timestamp').error();\n }\n if (timestamp < now - WEBHOOK_TOLERANCE_IN_SECONDS) {\n throw Status.invalidArgument('webhook timestamp is too old').error();\n }\n if (timestamp > now + WEBHOOK_TOLERANCE_IN_SECONDS) {\n throw Status.invalidArgument('webhook timestamp is too new').error();\n }\n return timestamp;\n}\n\n/**\n * reference: https://github.com/standard-webhooks/standard-webhooks/tree/main/libraries/javascript\n * hono usage:\n * ```ts\n * const webhook = verifyStandardWebhook(c.req.header(), await c.req.text(), 'secret');\n * ```\n */\nexport function verifyStandardWebhook<T = unknown>(\n headers: Record<string, string>,\n payload: string,\n secret: string\n): T {\n const webhookId = headers['webhook-id'];\n const webhookTimestamp = headers['webhook-timestamp'];\n const webhookSignature = headers['webhook-signature'];\n if (!webhookId || !webhookTimestamp || !webhookSignature) {\n throw Status.invalidArgument('invalid webhook').error();\n }\n const timestamp = verifyTimestamp(webhookTimestamp);\n\n const encoder = new TextEncoder();\n const toSign = encoder.encode(`${webhookId}.${timestamp}.${payload}`);\n const hmac = createHmac('sha256', Buffer.from(secret, 'base64'));\n const digest = hmac.update(toSign).digest();\n\n const computedSignature = `v1,${Buffer.from(digest).toString('base64')}`;\n const expectedSignature = computedSignature.split(',')[1];\n const passedSignatures = webhookSignature.split(' ');\n\n for (const versionedSignature of passedSignatures) {\n const [version, signature] = versionedSignature.split(',');\n if (version !== 'v1') continue;\n if (timingSafeEqual(encoder.encode(signature), encoder.encode(expectedSignature))) {\n try {\n return JSON.parse(payload) as T;\n } catch (_) {\n console.error('invalid payload', payload);\n throw Status.invalidArgument('invalid webhook payload').error();\n }\n }\n }\n console.error('webhook verification failed');\n throw Status.invalidArgument('invalid webhook signature').error();\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAA4C;AAC5C,oBAAuB;AAEvB,IAAM,+BAA+B,IAAI;AAEzC,SAAS,gBAAgB,kBAA0B;AACjD,QAAM,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AACxC,QAAM,YAAY,SAAS,kBAAkB,EAAE;AAC/C,MAAI,MAAM,SAAS,GAAG;AACpB,UAAM,qBAAO,gBAAgB,2BAA2B,EAAE,MAAM;AAAA,EAClE;AACA,MAAI,YAAY,MAAM,8BAA8B;AAClD,UAAM,qBAAO,gBAAgB,8BAA8B,EAAE,MAAM;AAAA,EACrE;AACA,MAAI,YAAY,MAAM,8BAA8B;AAClD,UAAM,qBAAO,gBAAgB,8BAA8B,EAAE,MAAM;AAAA,EACrE;AACA,SAAO;AACT;AASO,SAAS,sBACd,SACA,SACA,QACG;AACH,QAAM,YAAY,QAAQ,YAAY;AACtC,QAAM,mBAAmB,QAAQ,mBAAmB;AACpD,QAAM,mBAAmB,QAAQ,mBAAmB;AACpD,MAAI,CAAC,aAAa,CAAC,oBAAoB,CAAC,kBAAkB;AACxD,UAAM,qBAAO,gBAAgB,iBAAiB,EAAE,MAAM;AAAA,EACxD;AACA,QAAM,YAAY,gBAAgB,gBAAgB;AAElD,QAAM,UAAU,IAAI,YAAY;AAChC,QAAM,SAAS,QAAQ,OAAO,GAAG,SAAS,IAAI,SAAS,IAAI,OAAO,EAAE;AACpE,QAAM,WAAO,0BAAW,UAAU,OAAO,KAAK,QAAQ,QAAQ,CAAC;AAC/D,QAAM,SAAS,KAAK,OAAO,MAAM,EAAE,OAAO;AAE1C,QAAM,oBAAoB,MAAM,OAAO,KAAK,MAAM,EAAE,SAAS,QAAQ,CAAC;AACtE,QAAM,oBAAoB,kBAAkB,MAAM,GAAG,EAAE,CAAC;AACxD,QAAM,mBAAmB,iBAAiB,MAAM,GAAG;AAEnD,aAAW,sBAAsB,kBAAkB;AACjD,UAAM,CAAC,SAAS,SAAS,IAAI,mBAAmB,MAAM,GAAG;AACzD,QAAI,YAAY,KAAM;AACtB,YAAI,+BAAgB,QAAQ,OAAO,SAAS,GAAG,QAAQ,OAAO,iBAAiB,CAAC,GAAG;AACjF,UAAI;AACF,eAAO,KAAK,MAAM,OAAO;AAAA,MAC3B,SAAS,GAAG;AACV,gBAAQ,MAAM,mBAAmB,OAAO;AACxC,cAAM,qBAAO,gBAAgB,yBAAyB,EAAE,MAAM;AAAA,MAChE;AAAA,IACF;AAAA,EACF;AACA,UAAQ,MAAM,6BAA6B;AAC3C,QAAM,qBAAO,gBAAgB,2BAA2B,EAAE,MAAM;AAClE;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/webhook.ts"],"sourcesContent":["import { createHmac, timingSafeEqual } from 'crypto';\nimport { Status } from './status';\n\nconst WEBHOOK_TOLERANCE_IN_SECONDS = 5 * 60; // 5 minutes\n\nfunction verifyTimestamp(webhookTimestamp: string) {\n const now = Math.floor(Date.now() / 1000);\n const timestamp = parseInt(webhookTimestamp, 10);\n if (isNaN(timestamp)) {\n throw Status.invalidArgument('invalid webhook timestamp').error();\n }\n if (timestamp < now - WEBHOOK_TOLERANCE_IN_SECONDS) {\n throw Status.invalidArgument('webhook timestamp is too old').error();\n }\n if (timestamp > now + WEBHOOK_TOLERANCE_IN_SECONDS) {\n throw Status.invalidArgument('webhook timestamp is too new').error();\n }\n return timestamp;\n}\n\n/**\n * reference: https://github.com/standard-webhooks/standard-webhooks/tree/main/libraries/javascript\n * hono usage:\n * ```ts\n * const webhook = verifyStandardWebhook(c.req.header(), await c.req.text(), 'secret');\n * ```\n */\nexport function verifyStandardWebhook<T = unknown>(\n headers: Record<string, string>,\n payload: string,\n secret: string\n): T {\n const webhookId = headers['webhook-id'];\n const webhookTimestamp = headers['webhook-timestamp'];\n const webhookSignature = headers['webhook-signature'];\n if (!webhookId || !webhookTimestamp || !webhookSignature) {\n throw Status.invalidArgument('invalid webhook').error();\n }\n const timestamp = verifyTimestamp(webhookTimestamp);\n\n const encoder = new TextEncoder();\n const toSign = encoder.encode(`${webhookId}.${timestamp}.${payload}`);\n const hmac = createHmac('sha256', Buffer.from(secret, 'base64'));\n const digest = hmac.update(toSign).digest();\n\n const computedSignature = `v1,${Buffer.from(digest).toString('base64')}`;\n const expectedSignature = computedSignature.split(',')[1];\n const passedSignatures = webhookSignature.split(' ');\n\n for (const versionedSignature of passedSignatures) {\n const [version, signature] = versionedSignature.split(',');\n if (version !== 'v1') continue;\n if (timingSafeEqual(encoder.encode(signature), encoder.encode(expectedSignature))) {\n try {\n return JSON.parse(payload) as T;\n } catch (_) {\n console.error('invalid payload', payload);\n throw Status.invalidArgument('invalid webhook payload').error();\n }\n }\n }\n console.error('webhook verification failed');\n throw Status.invalidArgument('invalid webhook signature').error();\n}\n"],"mappings":";AAAA,SAAS,YAAY,uBAAuB;AAC5C,SAAS,cAAc;AAEvB,IAAM,+BAA+B,IAAI;AAEzC,SAAS,gBAAgB,kBAA0B;AACjD,QAAM,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AACxC,QAAM,YAAY,SAAS,kBAAkB,EAAE;AAC/C,MAAI,MAAM,SAAS,GAAG;AACpB,UAAM,OAAO,gBAAgB,2BAA2B,EAAE,MAAM;AAAA,EAClE;AACA,MAAI,YAAY,MAAM,8BAA8B;AAClD,UAAM,OAAO,gBAAgB,8BAA8B,EAAE,MAAM;AAAA,EACrE;AACA,MAAI,YAAY,MAAM,8BAA8B;AAClD,UAAM,OAAO,gBAAgB,8BAA8B,EAAE,MAAM;AAAA,EACrE;AACA,SAAO;AACT;AASO,SAAS,sBACd,SACA,SACA,QACG;AACH,QAAM,YAAY,QAAQ,YAAY;AACtC,QAAM,mBAAmB,QAAQ,mBAAmB;AACpD,QAAM,mBAAmB,QAAQ,mBAAmB;AACpD,MAAI,CAAC,aAAa,CAAC,oBAAoB,CAAC,kBAAkB;AACxD,UAAM,OAAO,gBAAgB,iBAAiB,EAAE,MAAM;AAAA,EACxD;AACA,QAAM,YAAY,gBAAgB,gBAAgB;AAElD,QAAM,UAAU,IAAI,YAAY;AAChC,QAAM,SAAS,QAAQ,OAAO,GAAG,SAAS,IAAI,SAAS,IAAI,OAAO,EAAE;AACpE,QAAM,OAAO,WAAW,UAAU,OAAO,KAAK,QAAQ,QAAQ,CAAC;AAC/D,QAAM,SAAS,KAAK,OAAO,MAAM,EAAE,OAAO;AAE1C,QAAM,oBAAoB,MAAM,OAAO,KAAK,MAAM,EAAE,SAAS,QAAQ,CAAC;AACtE,QAAM,oBAAoB,kBAAkB,MAAM,GAAG,EAAE,CAAC;AACxD,QAAM,mBAAmB,iBAAiB,MAAM,GAAG;AAEnD,aAAW,sBAAsB,kBAAkB;AACjD,UAAM,CAAC,SAAS,SAAS,IAAI,mBAAmB,MAAM,GAAG;AACzD,QAAI,YAAY,KAAM;AACtB,QAAI,gBAAgB,QAAQ,OAAO,SAAS,GAAG,QAAQ,OAAO,iBAAiB,CAAC,GAAG;AACjF,UAAI;AACF,eAAO,KAAK,MAAM,OAAO;AAAA,MAC3B,SAAS,GAAG;AACV,gBAAQ,MAAM,mBAAmB,OAAO;AACxC,cAAM,OAAO,gBAAgB,yBAAyB,EAAE,MAAM;AAAA,MAChE;AAAA,IACF;AAAA,EACF;AACA,UAAQ,MAAM,6BAA6B;AAC3C,QAAM,OAAO,gBAAgB,2BAA2B,EAAE,MAAM;AAClE;","names":[]}
File without changes
File without changes