@aesop-fables/triginta 0.9.1 → 0.9.3

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.
@@ -77,6 +77,15 @@ let SqsLambdaFactory = class SqsLambdaFactory {
77
77
  const message = yield deserializer.deserializeMessage(record);
78
78
  yield innerHandler.handle(message, record, event);
79
79
  }
80
+ catch (e) {
81
+ const failureHandler = childContainer.get(SqsLambdaServices_1.SqsLambdaServices.FailureHandler);
82
+ const shouldReport = yield failureHandler.onError(record, e);
83
+ if (shouldReport) {
84
+ response.batchItemFailures.push({
85
+ itemIdentifier: record.messageId,
86
+ });
87
+ }
88
+ }
80
89
  finally {
81
90
  if (childContainer) {
82
91
  try {
@@ -89,13 +98,9 @@ let SqsLambdaFactory = class SqsLambdaFactory {
89
98
  }
90
99
  }
91
100
  catch (e) {
92
- const failureHandler = this.container.get(SqsLambdaServices_1.SqsLambdaServices.FailureHandler);
93
- const shouldReport = yield failureHandler.onError(record, e);
94
- if (shouldReport) {
95
- response.batchItemFailures.push({
96
- itemIdentifier: record.messageId,
97
- });
98
- }
101
+ // We need to revisit this
102
+ // https://github.com/aesop-fables/triginta/issues/199
103
+ throw e;
99
104
  }
100
105
  }
101
106
  return response;
@@ -0,0 +1,9 @@
1
+ import { IConfiguredValidationRule } from './IConfiguredValidationRule';
2
+ import { IValidationRule } from './IValidationRule';
3
+ import { ValidationContext } from './ValidationContext';
4
+ export declare class ArrayContinuationRule implements IValidationRule {
5
+ private readonly field;
6
+ private readonly schema;
7
+ constructor(field: string, schema: IConfiguredValidationRule[]);
8
+ validate(context: ValidationContext): Promise<void>;
9
+ }
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.ArrayContinuationRule = void 0;
13
+ const ValidationServices_1 = require("./ValidationServices");
14
+ class ArrayContinuationRule {
15
+ constructor(field, schema) {
16
+ this.field = field;
17
+ this.schema = schema;
18
+ }
19
+ validate(context) {
20
+ return __awaiter(this, void 0, void 0, function* () {
21
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
22
+ const array = context.value();
23
+ if (!array || !Array.isArray(array) || !array.length) {
24
+ return;
25
+ }
26
+ const factory = context.container.get(ValidationServices_1.ValidationServices.ValidatorFactory);
27
+ const validator = factory.create(this.schema);
28
+ const arrayNotification = context.notification.forArray(this.field);
29
+ for (let i = 0; i < array.length; i++) {
30
+ const child = arrayNotification.forIndex(i);
31
+ yield validator.validate(array[i], child);
32
+ arrayNotification.importAll(child);
33
+ }
34
+ context.notification.importAll(arrayNotification);
35
+ });
36
+ }
37
+ }
38
+ exports.ArrayContinuationRule = ArrayContinuationRule;
@@ -1,4 +1,4 @@
1
1
  import { ValidationNotification } from './ValidationNotification';
2
2
  export interface IValidator {
3
- validate<Model extends object>(model: Model): Promise<ValidationNotification>;
3
+ validate<Model extends object>(model: Model, notification?: ValidationNotification): Promise<ValidationNotification>;
4
4
  }
@@ -3,6 +3,7 @@ import { IValidationRule } from './IValidationRule';
3
3
  export declare type ValidationExpression<T> = {
4
4
  required?: boolean;
5
5
  custom?: IValidationRule[];
6
+ array?: IConfiguredValidationRule[];
6
7
  };
7
8
  export declare type ValidationSchema<Model> = {
8
9
  [Property in keyof Model]: ValidationExpression<Model[Property]>;
@@ -1,12 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.parseRules = void 0;
4
+ const ArrayContinuationRule_1 = require("./ArrayContinuationRule");
4
5
  const RequiredRule_1 = require("./RequiredRule");
5
6
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
6
7
  function parseRules(schema) {
7
8
  const rules = [];
8
9
  Object.keys(schema).forEach((field) => {
9
- var _a;
10
+ var _a, _b;
10
11
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
11
12
  const fieldSchema = schema[field];
12
13
  if (typeof fieldSchema !== 'object') {
@@ -23,6 +24,12 @@ function parseRules(schema) {
23
24
  field,
24
25
  rule,
25
26
  }));
27
+ if (typeof fieldSchema.array !== 'undefined') {
28
+ rules.push({
29
+ field,
30
+ rule: new ArrayContinuationRule_1.ArrayContinuationRule(field, (_b = fieldSchema.array) !== null && _b !== void 0 ? _b : []),
31
+ });
32
+ }
26
33
  });
27
34
  return rules;
28
35
  }
@@ -2,10 +2,21 @@ import { LocalizedString } from '../localization';
2
2
  import { ValidationMessage } from './ValidationMessage';
3
3
  export declare class ValidationNotification {
4
4
  private readonly messages;
5
+ _getOrCreateMessages(field: string): ValidationMessage[];
5
6
  messagesFor(field: string): ValidationMessage[];
6
7
  registerMessage(field: string, localizedString: LocalizedString): ValidationMessage;
7
8
  allMessages(): ValidationMessage[];
8
9
  eachMessage(action: (message: ValidationMessage) => void): void;
9
10
  isValid(): boolean;
10
11
  importForField(field: string, notification: ValidationNotification): void;
12
+ forArray(field: string): PrefixedValidationNotification;
13
+ importAll(notification: ValidationNotification): void;
14
+ }
15
+ export declare class PrefixedValidationNotification extends ValidationNotification {
16
+ protected readonly prefix: string;
17
+ private readonly prefixRegistration;
18
+ constructor(prefix: string, prefixRegistration?: boolean);
19
+ resolveFieldName(field: string): string;
20
+ registerMessage(field: string, localizedString: LocalizedString): ValidationMessage;
21
+ forIndex(index: number): PrefixedValidationNotification;
11
22
  }
@@ -1,12 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ValidationNotification = void 0;
3
+ exports.PrefixedValidationNotification = exports.ValidationNotification = void 0;
4
4
  const ValidationMessage_1 = require("./ValidationMessage");
5
5
  class ValidationNotification {
6
6
  constructor() {
7
7
  this.messages = {};
8
8
  }
9
- messagesFor(field) {
9
+ _getOrCreateMessages(field) {
10
10
  let messages = this.messages[field];
11
11
  if (typeof messages === 'undefined') {
12
12
  messages = [];
@@ -14,6 +14,9 @@ class ValidationNotification {
14
14
  }
15
15
  return messages;
16
16
  }
17
+ messagesFor(field) {
18
+ return this._getOrCreateMessages(field);
19
+ }
17
20
  registerMessage(field, localizedString) {
18
21
  const message = new ValidationMessage_1.ValidationMessage(field, localizedString);
19
22
  let existing = null;
@@ -24,7 +27,7 @@ class ValidationNotification {
24
27
  });
25
28
  if (existing != null)
26
29
  return existing;
27
- const messages = this.messagesFor(field);
30
+ const messages = this._getOrCreateMessages(field);
28
31
  messages.push(message);
29
32
  return message;
30
33
  }
@@ -39,7 +42,7 @@ class ValidationNotification {
39
42
  const keys = Object.keys(this.messages);
40
43
  for (let i = 0; i < keys.length; i++) {
41
44
  const key = keys[i];
42
- const values = this.messagesFor(key);
45
+ const values = this._getOrCreateMessages(key);
43
46
  values.forEach((value) => {
44
47
  action(value);
45
48
  });
@@ -52,5 +55,32 @@ class ValidationNotification {
52
55
  const current = this.messagesFor(field);
53
56
  notification.messagesFor(field).forEach((_) => current.push(_));
54
57
  }
58
+ forArray(field) {
59
+ return new PrefixedValidationNotification(field, false);
60
+ }
61
+ importAll(notification) {
62
+ notification.eachMessage((msg) => {
63
+ this.registerMessage(msg.field, msg.localizedString);
64
+ });
65
+ }
55
66
  }
56
67
  exports.ValidationNotification = ValidationNotification;
68
+ class PrefixedValidationNotification extends ValidationNotification {
69
+ constructor(prefix, prefixRegistration = true) {
70
+ super();
71
+ this.prefix = prefix;
72
+ this.prefixRegistration = prefixRegistration;
73
+ }
74
+ resolveFieldName(field) {
75
+ var _a;
76
+ return `${(_a = this.prefix) !== null && _a !== void 0 ? _a : ''}${field}`;
77
+ }
78
+ registerMessage(field, localizedString) {
79
+ const resolvedField = this.prefixRegistration ? this.resolveFieldName(field) : field;
80
+ return super.registerMessage(resolvedField, localizedString);
81
+ }
82
+ forIndex(index) {
83
+ return new PrefixedValidationNotification(this.resolveFieldName(`[${index}].`));
84
+ }
85
+ }
86
+ exports.PrefixedValidationNotification = PrefixedValidationNotification;
@@ -7,6 +7,6 @@ export declare class Validator implements IValidator {
7
7
  private readonly rules;
8
8
  private readonly keys;
9
9
  constructor(container: IServiceContainer, rules: IConfiguredValidationRule[]);
10
- validate<Model extends object>(model: Model): Promise<ValidationNotification>;
10
+ validate<Model extends object>(model: Model, notification?: ValidationNotification): Promise<ValidationNotification>;
11
11
  private validateField;
12
12
  }
@@ -24,20 +24,18 @@ class Validator {
24
24
  });
25
25
  }
26
26
  // not worrying about defensive coding on the model right now
27
- validate(model) {
27
+ validate(model, notification = new ValidationNotification_1.ValidationNotification()) {
28
28
  return __awaiter(this, void 0, void 0, function* () {
29
- const notification = new ValidationNotification_1.ValidationNotification();
30
29
  const promises = this.keys.map((field) => __awaiter(this, void 0, void 0, function* () {
31
- const child = yield this.validateField(field, model);
32
- notification.importForField(field, child);
30
+ yield this.validateField(field, model, notification);
31
+ // notification.importForField(field, child);
33
32
  }));
34
33
  yield Promise.all(promises);
35
34
  return notification;
36
35
  });
37
36
  }
38
- validateField(field, model) {
37
+ validateField(field, model, child) {
39
38
  return __awaiter(this, void 0, void 0, function* () {
40
- const child = new ValidationNotification_1.ValidationNotification();
41
39
  const context = new ValidationContext_1.ValidationContext(field, model, child, this.container);
42
40
  const fieldRules = this.rules.filter((_) => _.field === field);
43
41
  yield Promise.all(fieldRules.map(({ rule }) => rule.validate(context)));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aesop-fables/triginta",
3
- "version": "0.9.1",
3
+ "version": "0.9.3",
4
4
  "description": "A lightweight framework that wraps the basic infrastructure usages of AWS Lambda (SQS, Kinesis, etc.).",
5
5
  "type": "commonjs",
6
6
  "exports": {