@sot1986/appsync-precognition 0.5.2 → 0.5.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.
Files changed (2) hide show
  1. package/README.md +309 -1
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,3 +1,311 @@
1
1
  # appsync-precognition
2
2
 
3
- Lean validation library for Appsync JS runtime, implementing Precognition protocol.
3
+ Lean validation library for AppSync JS runtime, implementing Precognition protocol for real-time form validation.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Installation](#installation)
8
+ - [Basic Usage](#basic-usage)
9
+ - [Simple Validation](#simple-validation)
10
+ - [Precognitive Validation (Real-time)](#precognitive-validation-real-time)
11
+ - [Validation Rules](#validation-rules)
12
+ - [Basic Rules](#basic-rules)
13
+ - [Type Rules](#type-rules)
14
+ - [String Validation](#string-validation)
15
+ - [Date/Time Validation](#datetime-validation)
16
+ - [Numeric Validation](#numeric-validation)
17
+ - [Size Constraints](#size-constraints)
18
+ - [Pattern Matching](#pattern-matching)
19
+ - [Date Comparisons](#date-comparisons)
20
+ - [Nested Object Validation](#nested-object-validation)
21
+ - [Array Validation](#array-validation)
22
+ - [Custom Error Messages](#custom-error-messages)
23
+ - [Custom Attribute Names](#custom-attribute-names)
24
+ - [Validation Options](#validation-options)
25
+ - [Precognitive Validation Features](#precognitive-validation-features)
26
+ - [Client Integration](#client-integration)
27
+ - [Internationalization](#internationalization)
28
+ - [Error Handling](#error-handling)
29
+ - [Advanced Usage](#advanced-usage)
30
+ - [Assert Validated Data](#assert-validated-data)
31
+ - [Check Localization](#check-localization)
32
+
33
+ ## Installation
34
+
35
+ ```bash
36
+ npm install appsync-precognition
37
+ ```
38
+
39
+ ## Basic Usage
40
+
41
+ ### Simple Validation
42
+ Any valid object can be validated, using simplified validation rules.
43
+
44
+ ```javascript
45
+ import { validate } from 'appsync-precognition'
46
+
47
+ export function request(ctx) {
48
+ const validatedArgs = validate({
49
+ name: 'Marco',
50
+ age: 15,
51
+ email: 'marco@email.it',
52
+ }, {
53
+ name: ['required', ['min', 3]],
54
+ age: ['required', ['min', 18]],
55
+ email: ['required', 'email'],
56
+ phone: ['sometimes', 'phone']
57
+ })
58
+
59
+ return {
60
+ operation: 'PutItem',
61
+ key: util.dynamodb.toMapValues({ id: util.autoId() }),
62
+ attributeValues: util.dynamodb.toMapValues(validatedArgs)
63
+ }
64
+ }
65
+ ```
66
+ This validation will throw an Error of type `ValidationError`.
67
+
68
+ ```typescript
69
+ util.error(
70
+ 'age min value is 18',
71
+ 'ValidationError',
72
+ null,
73
+ {
74
+ path: 'age',
75
+ value: 15
76
+ }
77
+ )
78
+ ```
79
+
80
+ ### Precognitive Validation (Real-time)
81
+ If your frontend application supports precognitive validation like [Nuxt precognition](https://nuxt.com/modules/precognition), everything will be handled automatically.
82
+
83
+ ```javascript
84
+ import { precognitiveValidation } from 'appsync-precognition'
85
+
86
+ export function request(ctx) {
87
+ const validatedArgs = precognitiveValidation(ctx, {
88
+ name: ['required', ['min', 3]],
89
+ age: ['required', ['min', 18]],
90
+ email: ['required', 'email'],
91
+ phone: ['nullable', 'phone']
92
+ })
93
+
94
+ return {
95
+ operation: 'PutItem',
96
+ key: util.dynamodb.toMapValues({ id: util.autoId() }),
97
+ attributeValues: util.dynamodb.toMapValues(validatedArgs)
98
+ }
99
+ }
100
+ ```
101
+ 1. Module checks for precognition headers and/or keys.
102
+ 2. Validates the request payload accordingly
103
+ 3. In case of success and precognitive requests, it will immediately return with `{ data: null, errors: undefined }`
104
+
105
+ ## Validation Rules
106
+
107
+ ### Basic Rules
108
+ - `required` - Field must have a value
109
+ - `nullable` - Field can be null but validates if present
110
+ - `sometimes` - Field is optional but validates if present
111
+
112
+ ### Type Rules
113
+ - `string` - Must be a string
114
+ - `number` - Must be a number
115
+ - `boolean` - Must be a boolean
116
+ - `array` - Must be an array
117
+ - `object` - Must be an object
118
+
119
+ ### String Validation
120
+ - `email` - Valid email format
121
+ - `phone` - Valid phone number (+123...)
122
+ - `url` - Valid URL format
123
+ - `uuid` - Valid UUID format
124
+ - `ulid` - Valid ULID format
125
+
126
+ ### Date/Time Validation
127
+ - `date` - Valid date (YYYY-MM-DD)
128
+ - `time` - Valid time (HH:MM:SS)
129
+ - `datetime` - Valid ISO datetime
130
+
131
+ ### Numeric Validation
132
+ - `integer` - Valid integer
133
+ - `numeric` - Valid number format
134
+
135
+ ### Size Constraints
136
+ - `['min', number]` - Minimum value/length
137
+ - `['max', number]` - Maximum value/length
138
+ - `['between', min, max]` - Between values (inclusive)
139
+ - `['bigger', number]` - Strictly greater than
140
+ - `['lower', number]` - Strictly less than
141
+ - `['within', min, max]` - Strictly between values
142
+
143
+ ### Pattern Matching
144
+ - `['regex', pattern]` - Match regex pattern
145
+ - `['in', ...values]` - Value must be in list
146
+ - `['notIn', ...values]` - Value must not be in list
147
+
148
+ ### Date Comparisons
149
+ - `['before', date]` - Before specified date
150
+ - `['after', date]` - After specified date
151
+ - `['beforeOrEqual', date]` - Before or equal to date
152
+ - `['afterOrEqual', date]` - After or equal to date
153
+
154
+ ## Nested Object Validation
155
+
156
+ ```javascript
157
+ const validatedArgs = validate(ctx.args, {
158
+ 'user.name': ['required', ['min', 3]],
159
+ 'user.email': ['required', 'email'],
160
+ 'address.street': ['required'],
161
+ 'address.zipCode': ['required', ['between', 5, 10]]
162
+ })
163
+ ```
164
+
165
+ ## Array Validation
166
+
167
+ To simplify error rules definition, the shortcut `*` is supported.
168
+
169
+ ```javascript
170
+ const validatedArgs = validate(ctx.args, {
171
+ 'hobbies': ['required', 'array', ['min', 1]],
172
+ 'hobbies.*': ['required', 'string', ['max', 50]], // Validates each array item
173
+ 'tags': ['sometimes', 'array'],
174
+ 'tags.*.value': ['string']
175
+ })
176
+ ```
177
+
178
+ ## Custom Error Messages
179
+
180
+ ```javascript
181
+ const validatedArgs = validate(ctx.args, {
182
+ email: [{ rule: 'email', msg: 'Please enter a valid email address' }],
183
+ age: [{ rule: ['min', 18], msg: 'You must be at least 18 years old' }]
184
+ })
185
+ ```
186
+
187
+ ## Custom Attribute Names
188
+ Attribute names can be customized by adding a third parameter to the `validate` function.
189
+
190
+ ```javascript
191
+ const validatedArgs = validate(ctx.args, {
192
+ 'email': ['required', 'email'],
193
+ 'phone': ['required', 'phone'],
194
+ 'hobbies.*': ['required', ['min', 2]] // each hobbies should have at least 2 chars
195
+ }, {
196
+ attributes: {
197
+ ':email': 'Email Address',
198
+ ':phone': 'Phone Number',
199
+ ':hobbies.*': 'Hobby' // 'Hobby must have at least 2 characters'
200
+ }
201
+ })
202
+ ```
203
+
204
+ ## Validation Options
205
+
206
+ ```javascript
207
+ const validatedArgs = validate(ctx.args, rules, {
208
+ trim: true, // Trim string values (default: true)
209
+ allowEmptyString: false, // Allow empty strings (default: false)
210
+ errors: {
211
+ required: ':attr is mandatory',
212
+ email: ':attr must be a valid email'
213
+ },
214
+ attributes: {
215
+ ':email': 'Email Address'
216
+ }
217
+ })
218
+ ```
219
+
220
+ ## Precognitive Validation Features
221
+
222
+ The `precognitiveValidation` function automatically handles:
223
+ - **Full validation** when `precognition` header is not present
224
+ - **Selective validation** when `precognition-validate-only` header specifies fields
225
+ - **Early return** for precognitive requests with proper headers
226
+ - **Response headers** for client-side precognition handling
227
+
228
+ ### Client Integration
229
+
230
+ Your frontend should send these headers for precognitive validation:
231
+ ```json
232
+ {
233
+ "Precognition": "true",
234
+ "Precognition-Validate-Only": "email,name"
235
+ }
236
+ ```
237
+
238
+ In addition, these headers must be enabled in the CORS policy of AppSync.
239
+
240
+ ## Internationalization
241
+
242
+ ```javascript
243
+ import { localize } from 'appsync-precognition/i18n'
244
+
245
+ export function request(ctx) {
246
+ // Set up localization based on Accept-Language header
247
+ localize(ctx, {
248
+ errors: {
249
+ en: { required: ':attr is required' },
250
+ es: { required: ':attr es requerido' },
251
+ it: { required: 'il campo :attr è obbligatorio' }
252
+ },
253
+ attributes: {
254
+ en: { ':name': 'Name', ':email': 'Email' },
255
+ es: { ':name': 'Nombre', ':email': 'Correo' },
256
+ it: { ':name': 'Nome', ':email': 'Email' }
257
+ }
258
+ }) // locale details will be added in stash object
259
+
260
+ const validatedArgs = precognitiveValidation(ctx, {
261
+ name: ['required'],
262
+ email: ['required', 'email']
263
+ })
264
+
265
+ return { /* your operation */ }
266
+ }
267
+ ```
268
+ If needed, it can be useful to split the localization and validation in separate resolvers of the same pipeline.
269
+
270
+ ## Error Handling
271
+
272
+ Validation errors are thrown as AppSync errors with detailed information:
273
+
274
+ ```javascript
275
+ // When validation fails, the error contains:
276
+ // - message: Human-readable error message
277
+ // - errorType: 'ValidationError'
278
+ // - errorInfo: { path: 'field.name', value: invalidValue }
279
+ ```
280
+
281
+ ## Advanced Usage
282
+
283
+ ### Assert Validated Data
284
+
285
+ ```javascript
286
+ import { assertValidated } from 'appsync-precognition'
287
+
288
+ export function request(ctx) {
289
+ precognitiveValidation(ctx, rules)
290
+ return { /* operation */ }
291
+ }
292
+
293
+ export function response(ctx) {
294
+ assertValidated(ctx) // Ensures validation was performed
295
+ return ctx.stash.__validated
296
+ }
297
+ ```
298
+
299
+ ### Check Localization
300
+
301
+ ```javascript
302
+ import { assertLocalized, isLocalized } from 'appsync-precognition'
303
+
304
+ export function request(ctx) {
305
+ if (isLocalized(ctx, 'es')) {
306
+ // Handle Spanish localization
307
+ }
308
+
309
+ assertLocalized(ctx) // Throws if not localized
310
+ }
311
+ ```
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@sot1986/appsync-precognition",
3
3
  "type": "module",
4
- "version": "0.5.2",
4
+ "version": "0.5.3",
5
5
  "description": "JavaScript resolver validation utilities for AWS AppSync",
6
6
  "author": "sot1986",
7
7
  "license": "MIT",