piper-utils 1.1.61 → 1.1.63
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.
- package/CLAUDE.md +107 -0
- package/README.md +846 -759
- package/bin/main.js +420 -2075
- package/bin/main.js.map +1 -1
- package/package.json +1 -1
- package/src/requestResponse/requestResponse.js +2 -3
- package/src/requestResponse/requestResponse.test.js +1 -1
- package/WHITE_LABEL.md +0 -60
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Forbidden Cognito Operations
|
|
6
|
+
|
|
7
|
+
NEVER use `UpdateUserPoolClient` or `DescribeUserPoolClient` from the AWS Cognito SDK or AWS CLI. The `UpdateUserPoolClient` API is a full replacement — any omitted property resets to its default. This has caused production outages twice (March 4 and March 17, 2026) by wiping `ExplicitAuthFlows` (removing `ALLOW_USER_SRP_AUTH`) and `ReadAttributes` from both dev and prod app clients. Cognito app client configuration must only be managed via the AWS Console (where all fields are visible) or via IaC that specifies every property.
|
|
8
|
+
|
|
9
|
+
## Build & Test Commands
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm test # Unit tests (BUILD_ENV=test) with NYC coverage
|
|
13
|
+
npm run itest # Integration tests (BUILD_ENV=development)
|
|
14
|
+
npm run build # Dev build via webpack -> bin/main.js
|
|
15
|
+
npm run build-prod # Production build (BUILD_ENV=production, minified)
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Run a single test file by passing `--filter`:
|
|
19
|
+
```bash
|
|
20
|
+
npx cross-env BUILD_ENV='test' nyc jasmine JASMINE_CONFIG_PATH=jasmine.json --filter="**/accessRightsUtils.test*"
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Tests use **Jasmine 5** with **NYC** coverage. Coverage thresholds: branches ≥ 70%, functions ≥ 70%, statements ≥ 85%, lines ≥ 80%. Test files live next to their source files as `*.test.js`.
|
|
24
|
+
|
|
25
|
+
## Architecture
|
|
26
|
+
|
|
27
|
+
This is a shared utility library (`piper-utils`) consumed by AWS Lambda microservices via npm. It is built with Babel (targeting Node 22) and bundled with webpack into `bin/main.js` (CommonJS output).
|
|
28
|
+
|
|
29
|
+
### Source Layout (`src/`)
|
|
30
|
+
|
|
31
|
+
- **`index.js`** — Single barrel export file. Every public function is re-exported here. Internal modules (S3Utils, SNSUtils, dynamoUtils) are NOT exported.
|
|
32
|
+
- **`requestResponse/`** — API Gateway Lambda proxy response formatting (`success`, `failure`, `successHtml`, `parseBody`, `parseEvent`, `getCurrentUser`). Includes security headers (HSTS, CSP, etc.) and auto-detection of Joi/Sequelize/Dynamoose errors in `failure()`.
|
|
33
|
+
- **`database/dbUtils/queryStringUtils/`** — Core query DSL translating API query strings into Sequelize queries:
|
|
34
|
+
- `defaultFilters.js` — Maps Sequelize column types to operators (iLike for strings, Op.between for dates, etc.)
|
|
35
|
+
- `createFilters.js` — Builds WHERE clauses with automatic business ID scoping, active-record filtering, date ranges, and full-text search
|
|
36
|
+
- `createSort.js` — Converts `sort` query param to ORDER BY arrays
|
|
37
|
+
- `createIncludes.js` — Auto-detects relation includes from dot-notation in filters/sort
|
|
38
|
+
- `findAll.js` — Paginated findAll (fetches limit+1 to detect `hasMore`)
|
|
39
|
+
- `accessRightsUtils.js` — All auth/access control functions (accessRightsUtils, checkWriteAccess, checkModule, checkIsSuper, isSuperUser, isSystemUser, partner functions, getCompanySettings). Reads JWT claims from `event.requestContext.authorizer.claims`.
|
|
40
|
+
- **`database/dbSetUp/migrations.js`** — Umzug-based migration runner with auto-rollback on failure.
|
|
41
|
+
- **`eventManager/`** — S3 file processing pipeline: `watchBucket` routes events (SNS/S3/cron) → `publishEvents` scans S3 and publishes file batches to SNS → `handleEvents` processes files in parallel via `handleFile`. Failed files move through `failed-once/` → `failed-twice/` → `error/` retry folders.
|
|
42
|
+
- **`s3/S3Utils/`**, **`sns/SNSUtils.js`**, **`dynamo/dynamoUtils.js`** — Internal AWS SDK v3 wrappers (not publicly exported).
|
|
43
|
+
|
|
44
|
+
### Key Design Patterns
|
|
45
|
+
|
|
46
|
+
- **`BUILD_ENV` gating**: Auth checks are relaxed when `BUILD_ENV=local` (injects default business ID `'1'` with admin access). Tests use `BUILD_ENV=test`.
|
|
47
|
+
- **Synchronous access control**: All access control functions are synchronous (read JWT claims from the event). The `enrichEventWithPartnerAccess` function mutates the event in-memory before calling sync auth functions — this avoids making the entire auth stack async.
|
|
48
|
+
- **Error convention**: Errors are plain objects with `{ statusCode, errorCode, message }`. Built-in error codes are in `requestResponse/errorCodes.js`. The `failure()` function auto-detects error types (Joi, Sequelize, etc.) and formats them.
|
|
49
|
+
|
|
50
|
+
## CI
|
|
51
|
+
|
|
52
|
+
Bitbucket Pipelines runs `npm test` on the `master` branch using a Node 22 image (`kevinlbatchelor/flow-22`).
|
|
53
|
+
|
|
54
|
+
## Peer Dependencies
|
|
55
|
+
|
|
56
|
+
Consuming projects must provide: `bluebird` (≥3.7.0), `dayjs` (^1.11.13), `lodash` (≥4.17.15), `sequelize` (≥6.6.2), `umzug` (≥3.2.1).
|
|
57
|
+
|
|
58
|
+
## Testing Guidelines
|
|
59
|
+
|
|
60
|
+
### Spy rules — only mock external boundaries
|
|
61
|
+
|
|
62
|
+
**DO spy on:** database model methods (`Model.findOne`, `Model.create`, `Model.findAll`, `Model.update`, `Model.destroy`), HTTP calls (`axios.get/post/put`), AWS SDK clients (S3, SNS), and external services.
|
|
63
|
+
|
|
64
|
+
**DO NOT spy on** auth/access functions (`checkModule`, `checkWriteAccess`, `accessRightsUtils`, `getCurrentUser`, `parseBody`, `createFilters`, `createSort`). Instead, build a proper mock event with `requestContext.authorizer.claims['custom:AR']`:
|
|
65
|
+
|
|
66
|
+
```javascript
|
|
67
|
+
const mockEvent = {
|
|
68
|
+
body: { /* ... */ },
|
|
69
|
+
pathParameters: { id: 1 },
|
|
70
|
+
queryStringParameters: { businessId: 'ABC' },
|
|
71
|
+
requestContext: {
|
|
72
|
+
authorizer: {
|
|
73
|
+
claims: {
|
|
74
|
+
'custom:AR': JSON.stringify({
|
|
75
|
+
businessIds: { 'ABC': 'A' },
|
|
76
|
+
module: { payment: { read: true, write: true } }
|
|
77
|
+
})
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
headers: { Authorization: 'Bearer mock-jwt-token' }
|
|
82
|
+
};
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Test structure rules
|
|
86
|
+
|
|
87
|
+
- **No `beforeEach`** — define all spies and setup inline within each `it()` block so tests are self-contained
|
|
88
|
+
- **Inline spies per test** — each test creates its own spies, not shared across tests
|
|
89
|
+
- Use `jasmine.createSpy()` for standalone function spies, `spyOn(obj, 'method')` for existing objects
|
|
90
|
+
- Verify spy calls with `toHaveBeenCalledWith()` for important arguments
|
|
91
|
+
|
|
92
|
+
### Spy patterns
|
|
93
|
+
|
|
94
|
+
```javascript
|
|
95
|
+
// Success
|
|
96
|
+
spyOn(Model, 'findOne').and.returnValue(Promise.resolve(mockData));
|
|
97
|
+
// Failure
|
|
98
|
+
spyOn(Model, 'findOne').and.returnValue(Promise.reject(new Error('DB Error')));
|
|
99
|
+
// Null/empty
|
|
100
|
+
spyOn(Model, 'findOne').and.returnValue(Promise.resolve(null));
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Code Style
|
|
104
|
+
|
|
105
|
+
- 4-space indentation, single quotes, trailing semicolons, no trailing commas
|
|
106
|
+
- No `lodash.get` — use optional chaining instead
|
|
107
|
+
- No nested ternaries — use if/else
|