@redmix/api 0.0.1

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.
Files changed (99) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +51 -0
  3. package/dist/auth/index.d.ts +51 -0
  4. package/dist/auth/index.d.ts.map +1 -0
  5. package/dist/auth/index.js +129 -0
  6. package/dist/auth/parseJWT.d.ts +6 -0
  7. package/dist/auth/parseJWT.d.ts.map +1 -0
  8. package/dist/auth/parseJWT.js +57 -0
  9. package/dist/auth/verifiers/base64Sha1Verifier.d.ts +19 -0
  10. package/dist/auth/verifiers/base64Sha1Verifier.d.ts.map +1 -0
  11. package/dist/auth/verifiers/base64Sha1Verifier.js +77 -0
  12. package/dist/auth/verifiers/base64Sha256Verifier.d.ts +19 -0
  13. package/dist/auth/verifiers/base64Sha256Verifier.d.ts.map +1 -0
  14. package/dist/auth/verifiers/base64Sha256Verifier.js +77 -0
  15. package/dist/auth/verifiers/common.d.ts +104 -0
  16. package/dist/auth/verifiers/common.d.ts.map +1 -0
  17. package/dist/auth/verifiers/common.js +99 -0
  18. package/dist/auth/verifiers/index.d.ts +8 -0
  19. package/dist/auth/verifiers/index.d.ts.map +1 -0
  20. package/dist/auth/verifiers/index.js +38 -0
  21. package/dist/auth/verifiers/jwtVerifier.d.ts +26 -0
  22. package/dist/auth/verifiers/jwtVerifier.d.ts.map +1 -0
  23. package/dist/auth/verifiers/jwtVerifier.js +86 -0
  24. package/dist/auth/verifiers/secretKeyVerifier.d.ts +14 -0
  25. package/dist/auth/verifiers/secretKeyVerifier.d.ts.map +1 -0
  26. package/dist/auth/verifiers/secretKeyVerifier.js +40 -0
  27. package/dist/auth/verifiers/sha1Verifier.d.ts +25 -0
  28. package/dist/auth/verifiers/sha1Verifier.d.ts.map +1 -0
  29. package/dist/auth/verifiers/sha1Verifier.js +85 -0
  30. package/dist/auth/verifiers/sha256Verifier.d.ts +25 -0
  31. package/dist/auth/verifiers/sha256Verifier.d.ts.map +1 -0
  32. package/dist/auth/verifiers/sha256Verifier.js +85 -0
  33. package/dist/auth/verifiers/skipVerifier.d.ts +13 -0
  34. package/dist/auth/verifiers/skipVerifier.d.ts.map +1 -0
  35. package/dist/auth/verifiers/skipVerifier.js +37 -0
  36. package/dist/auth/verifiers/timestampSchemeVerifier.d.ts +16 -0
  37. package/dist/auth/verifiers/timestampSchemeVerifier.d.ts.map +1 -0
  38. package/dist/auth/verifiers/timestampSchemeVerifier.js +81 -0
  39. package/dist/bins/redwood.d.ts +3 -0
  40. package/dist/bins/redwood.d.ts.map +1 -0
  41. package/dist/bins/redwood.js +33 -0
  42. package/dist/bins/rwfw.d.ts +3 -0
  43. package/dist/bins/rwfw.d.ts.map +1 -0
  44. package/dist/bins/rwfw.js +33 -0
  45. package/dist/bins/tsc.d.ts +3 -0
  46. package/dist/bins/tsc.d.ts.map +1 -0
  47. package/dist/bins/tsc.js +30 -0
  48. package/dist/cache/clients/BaseClient.d.ts +11 -0
  49. package/dist/cache/clients/BaseClient.d.ts.map +1 -0
  50. package/dist/cache/clients/BaseClient.js +27 -0
  51. package/dist/cache/clients/InMemoryClient.d.ts +31 -0
  52. package/dist/cache/clients/InMemoryClient.d.ts.map +1 -0
  53. package/dist/cache/clients/InMemoryClient.js +100 -0
  54. package/dist/cache/clients/MemcachedClient.d.ts +16 -0
  55. package/dist/cache/clients/MemcachedClient.d.ts.map +1 -0
  56. package/dist/cache/clients/MemcachedClient.js +75 -0
  57. package/dist/cache/clients/RedisClient.d.ts +20 -0
  58. package/dist/cache/clients/RedisClient.d.ts.map +1 -0
  59. package/dist/cache/clients/RedisClient.js +79 -0
  60. package/dist/cache/errors.d.ts +4 -0
  61. package/dist/cache/errors.d.ts.map +1 -0
  62. package/dist/cache/errors.js +33 -0
  63. package/dist/cache/index.d.ts +35 -0
  64. package/dist/cache/index.d.ts.map +1 -0
  65. package/dist/cache/index.js +171 -0
  66. package/dist/cors.d.ts +16 -0
  67. package/dist/cors.d.ts.map +1 -0
  68. package/dist/cors.js +93 -0
  69. package/dist/errors.d.ts +5 -0
  70. package/dist/errors.d.ts.map +1 -0
  71. package/dist/errors.js +38 -0
  72. package/dist/event.d.ts +3 -0
  73. package/dist/event.d.ts.map +1 -0
  74. package/dist/event.js +34 -0
  75. package/dist/functions/fixtures/apiGatewayProxyEvent.fixture.d.ts +4 -0
  76. package/dist/functions/fixtures/apiGatewayProxyEvent.fixture.d.ts.map +1 -0
  77. package/dist/functions/fixtures/apiGatewayProxyEvent.fixture.js +72 -0
  78. package/dist/index.d.ts +11 -0
  79. package/dist/index.d.ts.map +1 -0
  80. package/dist/index.js +49 -0
  81. package/dist/logger/index.d.ts +179 -0
  82. package/dist/logger/index.d.ts.map +1 -0
  83. package/dist/logger/index.js +195 -0
  84. package/dist/transforms.d.ts +35 -0
  85. package/dist/transforms.d.ts.map +1 -0
  86. package/dist/transforms.js +98 -0
  87. package/dist/types.d.ts +25 -0
  88. package/dist/types.d.ts.map +1 -0
  89. package/dist/types.js +16 -0
  90. package/dist/validations/errors.d.ts +101 -0
  91. package/dist/validations/errors.d.ts.map +1 -0
  92. package/dist/validations/errors.js +298 -0
  93. package/dist/validations/validations.d.ts +222 -0
  94. package/dist/validations/validations.d.ts.map +1 -0
  95. package/dist/validations/validations.js +351 -0
  96. package/dist/webhooks/index.d.ts +76 -0
  97. package/dist/webhooks/index.d.ts.map +1 -0
  98. package/dist/webhooks/index.js +107 -0
  99. package/package.json +95 -0
@@ -0,0 +1,351 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var validations_exports = {};
30
+ __export(validations_exports, {
31
+ validate: () => validate,
32
+ validateUniqueness: () => validateUniqueness,
33
+ validateWith: () => validateWith,
34
+ validateWithSync: () => validateWithSync
35
+ });
36
+ module.exports = __toCommonJS(validations_exports);
37
+ var import_client = require("@prisma/client");
38
+ var import_pascalcase = __toESM(require("pascalcase"));
39
+ var ValidationErrors = __toESM(require("./errors"));
40
+ const VALIDATORS = {
41
+ // Requires that the given value is `null` or `undefined`
42
+ //
43
+ // `allowEmptyString`: if true, counts "" as being absent (does not throw)
44
+ //
45
+ // { absence: true }
46
+ // { absence: { allowEmptyString: true, message: '...' } }
47
+ absence: (value, name, options) => {
48
+ const absenceOptions = { allowEmptyString: false };
49
+ Object.assign(absenceOptions, options);
50
+ if (value === "") {
51
+ if (!absenceOptions.allowEmptyString) {
52
+ validationError("absence", name, options);
53
+ }
54
+ } else if (value != null) {
55
+ validationError("absence", name, options);
56
+ }
57
+ },
58
+ // Requires that the given field be `true` and nothing else, unless an array
59
+ // of valid values is included with an `in` option
60
+ //
61
+ // { acceptance: true }
62
+ // { acceptance: { in: ['true','1'], message: '...' } }
63
+ acceptance: (value, name, options) => {
64
+ let acceptedValues;
65
+ if (typeof options === "object") {
66
+ acceptedValues = options.in || [];
67
+ } else {
68
+ acceptedValues = [true];
69
+ }
70
+ if (!acceptedValues.includes(value)) {
71
+ validationError("acceptance", name, options);
72
+ }
73
+ },
74
+ // Requires that the given value be formatted like an email address. Uses a
75
+ // very simple regex which checks for at least 1 character that is not an @,
76
+ // then an @, then at least one character that isn't a period, then a period,
77
+ // then any character. There cannot be any spaces present.
78
+ //
79
+ // { email: true }
80
+ // { email: { message: '...' } }
81
+ email: (value, name, options) => {
82
+ const pattern = /^[^@\s]+@[^.\s]+\.[^\s]+$/;
83
+ if (!pattern.test(String(value))) {
84
+ validationError("email", name, options);
85
+ }
86
+ },
87
+ // Requires that the given value NOT be in the list of possible values
88
+ //
89
+ // { exclusion: ['foo', 'bar'] }
90
+ // { exclusion: { in: ['foo','bar'], message: '...' } }
91
+ exclusion: (value, name, options) => {
92
+ const [exclusionList, val] = prepareExclusionInclusion(value, options);
93
+ if (exclusionList.includes(val)) {
94
+ validationError("exclusion", name, options);
95
+ }
96
+ },
97
+ // Requires that the given value match a regular expression
98
+ //
99
+ // { format: /^foobar$/ }
100
+ // { format: { pattern: /^foobar$/, message: '...' } }
101
+ format: (value, name, options) => {
102
+ const pattern = options instanceof RegExp ? options : options.pattern;
103
+ if (pattern == null) {
104
+ throw new ValidationErrors.FormatValidationError(
105
+ name,
106
+ "No pattern for format validation"
107
+ );
108
+ }
109
+ if (!pattern.test(String(value))) {
110
+ validationError("format", name, options);
111
+ }
112
+ },
113
+ // Requires that the given value be in the list of possible values
114
+ //
115
+ // { inclusion: ['foo', 'bar'] }
116
+ // { inclusion: { in: ['foo','bar'], message: '...' } }
117
+ inclusion: (value, name, options) => {
118
+ const [inclusionList, val] = prepareExclusionInclusion(value, options);
119
+ if (!inclusionList.includes(val)) {
120
+ validationError("inclusion", name, options);
121
+ }
122
+ },
123
+ // Requires that the given string be a certain length:
124
+ //
125
+ // `min`: must be at least `min` characters
126
+ // `max`: must be no more than `max` characters
127
+ // `equal`: must be exactly `equal` characters
128
+ // `between`: an array consisting of the `min` and `max` length
129
+ //
130
+ // { length: { min: 4 } }
131
+ // { length: { min: 2, max: 16 } }
132
+ // { length: { between: [2, 16], message: '...' } }
133
+ length: (value, name, options) => {
134
+ const len = String(value).length;
135
+ if (options.min && len < options.min) {
136
+ validationError("minLength", name, options, { min: options.min });
137
+ }
138
+ if (options.max && len > options.max) {
139
+ validationError("maxLength", name, options, { max: options.max });
140
+ }
141
+ if (options.equal && len !== options.equal) {
142
+ validationError("equalLength", name, options, { equal: options.equal });
143
+ }
144
+ if (options.between && (len < options.between[0] || len > options.between[1])) {
145
+ validationError("betweenLength", name, options, {
146
+ min: options.between[0],
147
+ max: options.between[1]
148
+ });
149
+ }
150
+ },
151
+ // Requires that number value meets some criteria:
152
+ //
153
+ // `integer`: value must be an integer
154
+ // `lessThan`: value must be less than `lessThan`
155
+ // `lessThanOrEqual`: value must be less than or equal to `lessThanOrEqual`
156
+ // `greaterThan`: value must be greater than `greaterThan`
157
+ // `greaterThanOrEqual`: value must be greater than or equal to `greaterThanOrEqual`
158
+ // `equal`: value must equal `equal`
159
+ // `otherThan`: value must be anything other than `otherThan`
160
+ // `even`: value must be an even number
161
+ // `odd`: value must be an odd number
162
+ // `positive`: value must be a positive number
163
+ // `negative`: value must be a negative number
164
+ //
165
+ // { numericality: true }
166
+ // { numericality: { integer: true } }
167
+ // { numericality: { greaterThan: 3.5, message: '...' } }
168
+ numericality: (value, name, options) => {
169
+ if (typeof value !== "number") {
170
+ validationError("typeNumericality", name, options);
171
+ }
172
+ if (typeof options === "boolean") {
173
+ return;
174
+ } else {
175
+ if (options.integer && !Number.isInteger(value)) {
176
+ validationError("integerNumericality", name, options);
177
+ }
178
+ if (options.lessThan != null && value >= options.lessThan) {
179
+ validationError("lessThanNumericality", name, options, {
180
+ lessThan: options.lessThan
181
+ });
182
+ }
183
+ if (options.lessThanOrEqual != null && value > options.lessThanOrEqual) {
184
+ validationError("lessThanOrEqualNumericality", name, options, {
185
+ lessThanOrEqual: options.lessThanOrEqual
186
+ });
187
+ }
188
+ if (options.greaterThan != null && value <= options.greaterThan) {
189
+ validationError("greaterThanNumericality", name, options, {
190
+ greaterThan: options.greaterThan
191
+ });
192
+ }
193
+ if (options.greaterThanOrEqual != null && value < options.greaterThanOrEqual) {
194
+ validationError("greaterThanOrEqualNumericality", name, options, {
195
+ greaterThanOrEqual: options.greaterThanOrEqual
196
+ });
197
+ }
198
+ if (options.equal != null && value !== options.equal) {
199
+ validationError("equalNumericality", name, options, {
200
+ equal: options.equal
201
+ });
202
+ }
203
+ if (options.otherThan != null && value === options.otherThan) {
204
+ validationError("otherThanNumericality", name, options, {
205
+ otherThan: options.otherThan
206
+ });
207
+ }
208
+ if (options.even && value % 2 !== 0) {
209
+ validationError("evenNumericality", name, options);
210
+ }
211
+ if (options.odd && value % 2 !== 1) {
212
+ validationError("oddNumericality", name, options);
213
+ }
214
+ if (options.positive && value <= 0) {
215
+ validationError("positiveNumericality", name, options);
216
+ }
217
+ if (options.negative && value >= 0) {
218
+ validationError("negativeNumericality", name, options);
219
+ }
220
+ }
221
+ },
222
+ // Requires that the given value is not `null` or `undefined`. By default will
223
+ // consider an empty string to pass
224
+ //
225
+ // `allowEmptyString`: if set to `false` will throw an error if value is ""
226
+ // `allowNull`: if `true` will allow `null`
227
+ // `allowUndefined`: if `true` will allow `undefined`
228
+ //
229
+ // Default behavior is equivalent to:
230
+ // { allowNull: false, allowUndefined: false, allowEmptyString: true }
231
+ //
232
+ // { presence: true }
233
+ // { presence: { allowEmptyString: false, message: '...' } }
234
+ presence: (value, name, options) => {
235
+ const presenceOptions = {
236
+ allowNull: false,
237
+ allowUndefined: false,
238
+ allowEmptyString: true
239
+ };
240
+ Object.assign(presenceOptions, options);
241
+ if (!presenceOptions.allowNull && value === null || !presenceOptions.allowUndefined && value === void 0 || !presenceOptions.allowEmptyString && value === "") {
242
+ validationError("presence", name, options);
243
+ }
244
+ },
245
+ custom: (_value, name, options) => {
246
+ try {
247
+ options.with();
248
+ } catch (e) {
249
+ const message = options.message || e.message || e;
250
+ validationError("custom", name, { message });
251
+ }
252
+ }
253
+ };
254
+ const fieldsToString = (fields) => {
255
+ const output = [];
256
+ for (const [key, _value] of Object.entries(fields)) {
257
+ output.push(key);
258
+ }
259
+ return output.join(", ");
260
+ };
261
+ const validationError = (type, name, options, substitutions = {}) => {
262
+ const errorClassName = `${(0, import_pascalcase.default)(
263
+ type
264
+ )}ValidationError`;
265
+ const ErrorClass = ValidationErrors[errorClassName];
266
+ const errorMessage = typeof options === "object" ? options.message : void 0;
267
+ throw new ErrorClass(name, errorMessage, substitutions);
268
+ };
269
+ const prepareExclusionInclusion = (value, options) => {
270
+ const inputList = Array.isArray(options) && options || options.in || [];
271
+ const caseSensitive = Array.isArray(options) ? true : options.caseSensitive ?? true;
272
+ return caseSensitive ? [inputList, value] : [
273
+ inputList.map((s) => s.toLowerCase()),
274
+ value.toLowerCase()
275
+ ];
276
+ };
277
+ function validate(value, labelOrRecipe, recipe) {
278
+ let label, validationRecipe;
279
+ if (typeof labelOrRecipe === "object") {
280
+ label = "";
281
+ validationRecipe = labelOrRecipe;
282
+ } else {
283
+ label = labelOrRecipe;
284
+ validationRecipe = recipe;
285
+ }
286
+ for (const [validator, options] of Object.entries(validationRecipe)) {
287
+ if (typeof options === "undefined") {
288
+ continue;
289
+ }
290
+ VALIDATORS[validator](value, label, options);
291
+ }
292
+ }
293
+ const validateWithSync = (func) => {
294
+ try {
295
+ func();
296
+ } catch (e) {
297
+ const message = e.message || e;
298
+ throw new ValidationErrors.ServiceValidationError(message);
299
+ }
300
+ };
301
+ const validateWith = async (func) => {
302
+ try {
303
+ await func();
304
+ } catch (e) {
305
+ const message = e.message || e;
306
+ throw new ValidationErrors.ServiceValidationError(message);
307
+ }
308
+ };
309
+ async function validateUniqueness(model, fields, optionsOrCallback, callback) {
310
+ const { $self, $scope, ...rest } = fields;
311
+ let options = {};
312
+ let validCallback;
313
+ let db = null;
314
+ if (typeof optionsOrCallback === "function") {
315
+ validCallback = optionsOrCallback;
316
+ } else {
317
+ options = optionsOrCallback;
318
+ validCallback = callback;
319
+ }
320
+ if (options.db) {
321
+ const { db: customDb, ...restOptions } = options;
322
+ options = restOptions;
323
+ db = customDb;
324
+ } else {
325
+ db = new import_client.PrismaClient();
326
+ }
327
+ const where = {
328
+ AND: [rest],
329
+ NOT: []
330
+ };
331
+ if ($scope) {
332
+ where.AND.push($scope);
333
+ }
334
+ if ($self) {
335
+ where.NOT.push($self);
336
+ }
337
+ return await db.$transaction(async (tx) => {
338
+ const found = await tx[model].findFirst({ where });
339
+ if (found) {
340
+ validationError("uniqueness", fieldsToString(fields), options);
341
+ }
342
+ return validCallback(tx);
343
+ });
344
+ }
345
+ // Annotate the CommonJS export names for ESM import in node:
346
+ 0 && (module.exports = {
347
+ validate,
348
+ validateUniqueness,
349
+ validateWith,
350
+ validateWithSync
351
+ });
@@ -0,0 +1,76 @@
1
+ import type { APIGatewayProxyEvent } from 'aws-lambda';
2
+ import type { VerifyOptions, SupportedVerifierTypes } from '../auth/verifiers';
3
+ import { WebhookVerificationError } from '../auth/verifiers';
4
+ export { VerifyOptions, WebhookVerificationError, DEFAULT_WEBHOOK_SECRET, SupportedVerifierTypes, } from '../auth/verifiers';
5
+ export declare const DEFAULT_WEBHOOK_SIGNATURE_HEADER = "RW-WEBHOOK-SIGNATURE";
6
+ /**
7
+ * Extracts signature from Lambda Event.
8
+ *
9
+ * @param {APIGatewayProxyEvent} event - The event that includes the request details, like headers
10
+ * @param {string} signatureHeader - The name of header key that contains the signature; defaults to DEFAULT_WEBHOOK_SIGNATURE_HEADER
11
+ * @return {string} - The signature found in the headers specified by signatureHeader
12
+ *
13
+ * @example
14
+ *
15
+ * signatureFromEvent({ event: event })
16
+ */
17
+ export declare const signatureFromEvent: ({ event, signatureHeader, }: {
18
+ event: APIGatewayProxyEvent;
19
+ signatureHeader: string;
20
+ }) => string;
21
+ /**
22
+ * Verifies event payload is signed with a valid webhook signature.
23
+ *
24
+ * @param {APIGatewayProxyEvent} event - The event that includes the body for the verification payload and request details, like headers.
25
+ * @param {string} payload - If provided, the payload will be used to verify the signature instead of the event body.
26
+ * @param {string} secret - The secret that will verify the signature according to the verifier type
27
+ * @param {VerifyOptions} options - Options to specify the verifier type the header key that contains the signature, timestamp leeway.
28
+ * @return {boolean | WebhookVerificationError} - Returns true if the signature is verified, or raises WebhookVerificationError.
29
+ *
30
+ * @example
31
+ *
32
+ * verifyEvent({ event: event, options: {} })*
33
+ */
34
+ export declare const verifyEvent: (type: SupportedVerifierTypes, { event, payload, secret, options, }: {
35
+ event: APIGatewayProxyEvent;
36
+ payload?: string;
37
+ secret?: string;
38
+ options?: VerifyOptions | undefined;
39
+ }) => boolean | WebhookVerificationError;
40
+ /**
41
+ * Standalone verification of webhook signature given a payload, secret, verifier type and options.
42
+ *
43
+ * @param {string} payload - Body content of the event
44
+ * @param {string} secret - The secret that will verify the signature according to the verifier type
45
+ * @param {string} signature - Signature that verifies that the event
46
+ * @param {VerifyOptions} options - Options to specify the verifier type the header key that contains the signature, timestamp leeway.
47
+ * @return {boolean | WebhookVerificationError} - Returns true if the signature is verified, or raises WebhookVerificationError.
48
+ *
49
+ * @example
50
+ *
51
+ * verifySignature({ payload, secret, signature, options: {} })*
52
+ */
53
+ export declare const verifySignature: (type: SupportedVerifierTypes, { payload, secret, signature, options, }: {
54
+ payload: string | Record<string, unknown>;
55
+ secret: string;
56
+ signature: string;
57
+ options?: VerifyOptions | undefined;
58
+ }) => boolean | WebhookVerificationError;
59
+ /**
60
+ * Signs a payload with a secret and verifier type method
61
+ *
62
+ * @param {string} payload - Body content of the event to sign
63
+ * @param {string} secret - The secret that will verify the signature according to the verifier type
64
+ * @param {VerifyOptions} options - Options to specify the verifier type the header key that contains the signature, timestamp leeway.
65
+ * @return {string} - Returns signature
66
+ *
67
+ * @example
68
+ *
69
+ * signPayload({ payload, secret, options: {} })*
70
+ */
71
+ export declare const signPayload: (type: SupportedVerifierTypes, { payload, secret, options, }: {
72
+ payload: string;
73
+ secret: string;
74
+ options?: VerifyOptions | undefined;
75
+ }) => string;
76
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/webhooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AAEtD,OAAO,KAAK,EAAE,aAAa,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAA;AAC9E,OAAO,EAEL,wBAAwB,EAGzB,MAAM,mBAAmB,CAAA;AAE1B,OAAO,EACL,aAAa,EACb,wBAAwB,EACxB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,mBAAmB,CAAA;AAE1B,eAAO,MAAM,gCAAgC,yBAAyB,CAAA;AActE;;;;;;;;;;GAUG;AACH,eAAO,MAAM,kBAAkB,gCAG5B;IACD,KAAK,EAAE,oBAAoB,CAAA;IAC3B,eAAe,EAAE,MAAM,CAAA;CACxB,KAAG,MAGH,CAAA;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,WAAW,SAChB,sBAAsB,wCAMzB;IACD,KAAK,EAAE,oBAAoB,CAAA;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,aAAa,GAAG,SAAS,CAAA;CACpC,KACA,OAAO,GAAG,wBAgCZ,CAAA;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,eAAe,SACpB,sBAAsB,4CAMzB;IACD,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACzC,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE,aAAa,GAAG,SAAS,CAAA;CACpC,KACA,OAAO,GAAG,wBAIZ,CAAA;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,WAAW,SAChB,sBAAsB,iCAKzB;IACD,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,aAAa,GAAG,SAAS,CAAA;CACpC,KACA,MAIF,CAAA"}
@@ -0,0 +1,107 @@
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
+ var webhooks_exports = {};
20
+ __export(webhooks_exports, {
21
+ DEFAULT_WEBHOOK_SECRET: () => import_verifiers2.DEFAULT_WEBHOOK_SECRET,
22
+ DEFAULT_WEBHOOK_SIGNATURE_HEADER: () => DEFAULT_WEBHOOK_SIGNATURE_HEADER,
23
+ SupportedVerifierTypes: () => import_verifiers2.SupportedVerifierTypes,
24
+ VerifyOptions: () => import_verifiers2.VerifyOptions,
25
+ WebhookVerificationError: () => import_verifiers2.WebhookVerificationError,
26
+ signPayload: () => signPayload,
27
+ signatureFromEvent: () => signatureFromEvent,
28
+ verifyEvent: () => verifyEvent,
29
+ verifySignature: () => verifySignature
30
+ });
31
+ module.exports = __toCommonJS(webhooks_exports);
32
+ var import_verifiers = require("../auth/verifiers");
33
+ var import_verifiers2 = require("../auth/verifiers");
34
+ const DEFAULT_WEBHOOK_SIGNATURE_HEADER = "RW-WEBHOOK-SIGNATURE";
35
+ const eventBody = (event) => {
36
+ if (event.isBase64Encoded) {
37
+ return Buffer.from(event.body || "", "base64").toString("utf-8");
38
+ } else {
39
+ return event.body || "";
40
+ }
41
+ };
42
+ const signatureFromEvent = ({
43
+ event,
44
+ signatureHeader = DEFAULT_WEBHOOK_SIGNATURE_HEADER
45
+ }) => {
46
+ const header = signatureHeader.toLocaleLowerCase();
47
+ return event.headers[header];
48
+ };
49
+ const verifyEvent = (type, {
50
+ event,
51
+ payload,
52
+ secret = import_verifiers.DEFAULT_WEBHOOK_SECRET,
53
+ options
54
+ }) => {
55
+ let body = "";
56
+ if (payload) {
57
+ body = payload;
58
+ } else {
59
+ body = eventBody(event);
60
+ }
61
+ let signature = signatureFromEvent({
62
+ event,
63
+ signatureHeader: options?.signatureHeader || DEFAULT_WEBHOOK_SIGNATURE_HEADER
64
+ });
65
+ if (options?.signatureTransformer) {
66
+ signature = options.signatureTransformer(signature);
67
+ }
68
+ if (options?.eventTimestamp) {
69
+ const timestamp = options?.currentTimestampOverride ?? Date.now();
70
+ const difference = Math.abs(timestamp - options?.eventTimestamp);
71
+ const tolerance = options?.tolerance ?? import_verifiers.DEFAULT_TOLERANCE;
72
+ if (difference > tolerance) {
73
+ throw new import_verifiers.WebhookVerificationError();
74
+ }
75
+ }
76
+ const { verify } = (0, import_verifiers.createVerifier)(type, options);
77
+ return verify({ payload: body, secret, signature });
78
+ };
79
+ const verifySignature = (type, {
80
+ payload,
81
+ secret = import_verifiers.DEFAULT_WEBHOOK_SECRET,
82
+ signature,
83
+ options
84
+ }) => {
85
+ const { verify } = (0, import_verifiers.createVerifier)(type, options);
86
+ return verify({ payload, secret, signature });
87
+ };
88
+ const signPayload = (type, {
89
+ payload,
90
+ secret = import_verifiers.DEFAULT_WEBHOOK_SECRET,
91
+ options
92
+ }) => {
93
+ const { sign } = (0, import_verifiers.createVerifier)(type, options);
94
+ return sign({ payload, secret });
95
+ };
96
+ // Annotate the CommonJS export names for ESM import in node:
97
+ 0 && (module.exports = {
98
+ DEFAULT_WEBHOOK_SECRET,
99
+ DEFAULT_WEBHOOK_SIGNATURE_HEADER,
100
+ SupportedVerifierTypes,
101
+ VerifyOptions,
102
+ WebhookVerificationError,
103
+ signPayload,
104
+ signatureFromEvent,
105
+ verifyEvent,
106
+ verifySignature
107
+ });
package/package.json ADDED
@@ -0,0 +1,95 @@
1
+ {
2
+ "name": "@redmix/api",
3
+ "version": "0.0.1",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "git+https://github.com/redmix-run/redmix.git",
7
+ "directory": "packages/api"
8
+ },
9
+ "license": "MIT",
10
+ "type": "commonjs",
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "default": "./dist/index.js"
15
+ },
16
+ "./package.json": "./package.json",
17
+ "./cache": {
18
+ "types": "./dist/cache/index.d.ts",
19
+ "default": "./dist/cache/index.js"
20
+ },
21
+ "./logger": {
22
+ "types": "./dist/logger/index.d.ts",
23
+ "default": "./dist/logger/index.js"
24
+ },
25
+ "./webhooks": {
26
+ "types": "./dist/webhooks/index.d.ts",
27
+ "default": "./dist/webhooks/index.js"
28
+ }
29
+ },
30
+ "main": "./dist/index.js",
31
+ "types": "./dist/index.d.ts",
32
+ "bin": {
33
+ "redwood": "./dist/bins/redwood.js",
34
+ "rw": "./dist/bins/redwood.js",
35
+ "rwfw": "./dist/bins/rwfw.js",
36
+ "tsc": "./dist/bins/tsc.js"
37
+ },
38
+ "files": [
39
+ "dist"
40
+ ],
41
+ "scripts": {
42
+ "build": "tsx ./build.mts && yarn build:types",
43
+ "build:pack": "yarn pack -o redmix-api.tgz",
44
+ "build:types": "tsc --build --verbose ./tsconfig.json",
45
+ "build:watch": "nodemon --watch src --ext \"js,jsx,ts,tsx\" --ignore dist --exec \"yarn build\"",
46
+ "check:attw": "yarn rw-fwtools-attw",
47
+ "check:package": "concurrently npm:check:attw yarn:publint",
48
+ "prepublishOnly": "NODE_ENV=production yarn build",
49
+ "test": "vitest run",
50
+ "test:watch": "vitest watch"
51
+ },
52
+ "dependencies": {
53
+ "@prisma/client": "5.20.0",
54
+ "@whatwg-node/fetch": "0.9.21",
55
+ "cookie": "0.7.2",
56
+ "humanize-string": "2.1.0",
57
+ "jsonwebtoken": "9.0.2",
58
+ "pascalcase": "1.0.0",
59
+ "pino": "9.4.0",
60
+ "title-case": "3.0.3"
61
+ },
62
+ "devDependencies": {
63
+ "@redmix/framework-tools": "0.0.1",
64
+ "@types/aws-lambda": "8.10.145",
65
+ "@types/jsonwebtoken": "9.0.8",
66
+ "@types/memjs": "1",
67
+ "@types/pascalcase": "1.0.3",
68
+ "@types/split2": "4.2.3",
69
+ "concurrently": "8.2.2",
70
+ "memjs": "1.3.2",
71
+ "publint": "0.3.11",
72
+ "redis": "4.7.0",
73
+ "split2": "4.2.0",
74
+ "ts-toolbelt": "9.6.0",
75
+ "tsx": "4.19.3",
76
+ "typescript": "5.6.2",
77
+ "vitest": "2.1.9"
78
+ },
79
+ "peerDependencies": {
80
+ "memjs": "1.3.2",
81
+ "redis": "4.7.0"
82
+ },
83
+ "peerDependenciesMeta": {
84
+ "memjs": {
85
+ "optional": true
86
+ },
87
+ "redis": {
88
+ "optional": true
89
+ }
90
+ },
91
+ "publishConfig": {
92
+ "access": "public"
93
+ },
94
+ "gitHead": "688027c97502c500ebbede9cdc7cc51545a8dcf3"
95
+ }