meadow-endpoints 4.0.22 → 4.0.23
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/README.md +8 -15
- package/diagrams/how-it-works.excalidraw +1462 -0
- package/diagrams/how-it-works.mmd +9 -0
- package/diagrams/how-it-works.svg +2 -0
- package/dist/meadow-endpoints.js +516 -221
- package/dist/meadow-endpoints.js.map +1 -1
- package/dist/meadow-endpoints.min.js +18 -18
- package/dist/meadow-endpoints.min.js.map +1 -1
- package/docs/README.md +9 -25
- package/docs/_cover.md +9 -0
- package/docs/_sidebar.md +1 -0
- package/docs/_version.json +3 -3
- package/docs/architecture.md +119 -0
- package/docs/crud/README.md +6 -6
- package/docs/diagrams/behavior-injection-hook-points.excalidraw +677 -0
- package/docs/diagrams/behavior-injection-hook-points.mmd +9 -0
- package/docs/diagrams/behavior-injection-hook-points.svg +2 -0
- package/docs/diagrams/how-it-works.excalidraw +2777 -0
- package/docs/diagrams/how-it-works.mmd +16 -0
- package/docs/diagrams/how-it-works.svg +2 -0
- package/docs/diagrams/how-routes-are-generated.excalidraw +1237 -0
- package/docs/diagrams/how-routes-are-generated.mmd +13 -0
- package/docs/diagrams/how-routes-are-generated.svg +2 -0
- package/docs/diagrams/request-lifecycle.excalidraw +1897 -0
- package/docs/diagrams/request-lifecycle.mmd +22 -0
- package/docs/diagrams/request-lifecycle.svg +2 -0
- package/docs/diagrams/where-it-sits-in-the-stack.excalidraw +2068 -0
- package/docs/diagrams/where-it-sits-in-the-stack.mmd +19 -0
- package/docs/diagrams/where-it-sits-in-the-stack.svg +2 -0
- package/docs/index.html +2 -2
- package/docs/quickstart.md +151 -0
- package/docs/retold-catalog.json +155 -174
- package/docs/retold-keyword-index.json +6593 -2920
- package/package.json +8 -8
- package/source/controller/Meadow-Endpoints-Controller-Base.js +40 -0
- package/source/endpoints/count/Meadow-Endpoint-Count.js +1 -0
- package/source/endpoints/count/Meadow-Endpoint-CountBy.js +1 -0
- package/source/endpoints/create/Meadow-Operation-Create.js +1 -0
- package/source/endpoints/delete/Meadow-Endpoint-Delete.js +1 -0
- package/source/endpoints/delete/Meadow-Endpoint-Undelete.js +1 -0
- package/source/endpoints/read/Meadow-Endpoint-Read.js +1 -0
- package/source/endpoints/read/Meadow-Endpoint-ReadDistinctList.js +1 -0
- package/source/endpoints/read/Meadow-Endpoint-ReadLiteList.js +1 -0
- package/source/endpoints/read/Meadow-Endpoint-ReadMax.js +1 -0
- package/source/endpoints/read/Meadow-Endpoint-ReadSelectList.js +1 -0
- package/source/endpoints/read/Meadow-Endpoint-Reads.js +1 -0
- package/source/endpoints/read/Meadow-Endpoint-ReadsBy.js +1 -0
- package/source/endpoints/update/Meadow-Operation-Update.js +2 -0
- package/source/endpoints/upsert/Meadow-Operation-Upsert.js +1 -0
- package/test/MeadowEndpoints_SessionOverride_tests.js +75 -0
- package/dist/indoctrinate_content_staging/Indoctrinate-Catalog-AppData.json +0 -4808
package/docs/README.md
CHANGED
|
@@ -83,24 +83,8 @@ npm install meadow-endpoints
|
|
|
83
83
|
|
|
84
84
|
Meadow Endpoints takes a configured Meadow DAL instance and registers HTTP routes with an Orator service server. Each route follows an async waterfall pattern with behavior injection points, allowing you to customize any step of the request lifecycle without replacing the endpoint implementation.
|
|
85
85
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
└── Meadow Endpoints (Route Registration)
|
|
89
|
-
├── Controller (Request Lifecycle)
|
|
90
|
-
│ ├── Session Marshaler (Authentication)
|
|
91
|
-
│ ├── Behavior Injection (Authorization & Custom Logic)
|
|
92
|
-
│ ├── Error Handler (Error Responses)
|
|
93
|
-
│ └── Log Controller (Request Logging)
|
|
94
|
-
├── Endpoints (Route Handlers)
|
|
95
|
-
│ ├── Create / BulkCreate
|
|
96
|
-
│ ├── Read / Reads / ReadSelectList / ReadLiteList / ReadDistinctList
|
|
97
|
-
│ ├── Update / BulkUpdate / Upsert / BulkUpsert
|
|
98
|
-
│ ├── Delete / Undelete
|
|
99
|
-
│ ├── Count / CountBy
|
|
100
|
-
│ └── Schema / New / Validate
|
|
101
|
-
└── Meadow DAL (Data Access)
|
|
102
|
-
└── Database Provider
|
|
103
|
-
```
|
|
86
|
+
<!-- bespoke diagram: edit diagrams/how-it-works.mmd or .hints.json, then: npx pict-renderer-graph build modules/meadow/meadow-endpoints/docs -->
|
|
87
|
+

|
|
104
88
|
|
|
105
89
|
## Generated Routes
|
|
106
90
|
|
|
@@ -317,10 +301,10 @@ npx docsify-cli serve docs
|
|
|
317
301
|
|
|
318
302
|
## Related Packages
|
|
319
303
|
|
|
320
|
-
- [meadow](https://github.
|
|
321
|
-
- [meadow-filter](https://github.com/
|
|
322
|
-
- [orator](https://github.
|
|
323
|
-
- [orator-serviceserver-restify](https://github.
|
|
324
|
-
- [stricture](https://github.
|
|
325
|
-
- [foxhound](https://github.
|
|
326
|
-
- [fable](https://github.
|
|
304
|
+
- [meadow](https://fable-retold.github.io/meadow/) - Data access layer (required)
|
|
305
|
+
- [meadow-filter](https://github.com/fable-retold/meadow-filter) - URL filter expression parser
|
|
306
|
+
- [orator](https://fable-retold.github.io/orator/) - API server abstraction
|
|
307
|
+
- [orator-serviceserver-restify](https://fable-retold.github.io/orator-serviceserver-restify/) - Restify service server
|
|
308
|
+
- [stricture](https://fable-retold.github.io/stricture/) - Schema definition language
|
|
309
|
+
- [foxhound](https://fable-retold.github.io/foxhound/) - Query DSL for SQL generation
|
|
310
|
+
- [fable](https://fable-retold.github.io/fable/) - Service provider framework
|
package/docs/_cover.md
ADDED
package/docs/_sidebar.md
CHANGED
package/docs/_version.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"Name": "meadow-endpoints",
|
|
3
|
-
"Version": "4.0.
|
|
3
|
+
"Version": "4.0.22",
|
|
4
4
|
"Description": "Automatic API endpoints for Meadow data.",
|
|
5
|
-
"GeneratedAt": "2026-05-
|
|
6
|
-
"GitCommit": "
|
|
5
|
+
"GeneratedAt": "2026-05-30T22:11:58.853Z",
|
|
6
|
+
"GitCommit": "dc9ec80"
|
|
7
7
|
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
This document describes how Meadow Endpoints turns a single Meadow entity into a full suite of RESTful routes, the request lifecycle each route follows, the behavior-injection hook points that make that lifecycle customizable, and where the module sits in the Retold stack.
|
|
4
|
+
|
|
5
|
+
## Where It Sits in the Stack
|
|
6
|
+
|
|
7
|
+
Meadow Endpoints is the Layer-3 keystone of the data tier. It binds a Meadow data access layer (the data broker below it) to an Orator service server (the API host above it), registering one HTTP route per generated endpoint.
|
|
8
|
+
|
|
9
|
+
<!-- bespoke diagram: edit diagrams/where-it-sits-in-the-stack.mmd or .hints.json, then: npx pict-renderer-graph build modules/meadow/meadow-endpoints/docs -->
|
|
10
|
+

|
|
11
|
+
|
|
12
|
+
Orator hosts the routes and supplies the HTTP request and response objects. Meadow Endpoints owns the request lifecycle through its controller. Meadow executes the data operation against whichever database provider is configured. Fable underpins all of it, supplying configuration, logging, and the async utilities the controller uses.
|
|
13
|
+
|
|
14
|
+
## How Routes Are Generated
|
|
15
|
+
|
|
16
|
+
A `MeadowEndpoints` instance is constructed from a configured Meadow DAL. The DAL scope (for example `Book`) and the configured version (default `1.0`) form the route prefix `/{version}/{entity}` -- so `Book` becomes `/1.0/Book`.
|
|
17
|
+
|
|
18
|
+
<!-- bespoke diagram: edit diagrams/how-routes-are-generated.mmd or .hints.json, then: npx pict-renderer-graph build modules/meadow/meadow-endpoints/docs -->
|
|
19
|
+

|
|
20
|
+
|
|
21
|
+
Calling `connectRoutes(_Orator.serviceServer)` walks the enabled behavior sets and registers every route through the internal `connectRoute()` helper, which binds each endpoint handler to the controller instance. Endpoints are grouped into behavior sets -- `Create`, `Read`, `Reads`, `Update`, `Delete`, `Count`, `Schema`, `Validate`, and `New` -- and any set can be turned off before `connectRoutes()` is called so its routes are never registered.
|
|
22
|
+
|
|
23
|
+
Route ordering matters: the `Schema`, `Schema/New`, and `Schema/Validate` routes are registered before the `/:IDRecord` read route so the literal `Schema` path is not captured as a record identifier. For the same reason, the literal `Upsert` and `Upserts` PUT routes are registered before the by-id `PUT /:IDRecord` route. For the full generated route table, see [Generated Routes](generated-routes.md) and the [CRUD Deep Dive](crud/README.md).
|
|
24
|
+
|
|
25
|
+
## Request Lifecycle
|
|
26
|
+
|
|
27
|
+
Every generated endpoint runs the same async waterfall. Each stage either advances to the next or short-circuits to the shared error handler. Behavior-injection hooks are interleaved between the built-in stages, so custom logic runs at well-defined points without replacing any built-in step.
|
|
28
|
+
|
|
29
|
+
<!-- bespoke diagram: edit diagrams/request-lifecycle.mmd or .hints.json, then: npx pict-renderer-graph build modules/meadow/meadow-endpoints/docs -->
|
|
30
|
+

|
|
31
|
+
|
|
32
|
+
Not every endpoint exposes all three hook phases. A single-record read, for example, runs `Read-PreOperation`, then `Read-QueryConfiguration`, then `Read-PostOperation`; a multi-record read runs `Reads-QueryConfiguration` and `Reads-PostOperation`. See [Behavior Injection](behavior-injection.md) for the complete hook matrix.
|
|
33
|
+
|
|
34
|
+
### Request State
|
|
35
|
+
|
|
36
|
+
`initializeRequestState()` creates the `pRequestState` object that travels through the waterfall. It carries the operation verb and the marshalled `SessionData`, and each stage attaches what it produces -- `Query`, then `Record` or `Records`, then `Result` for counts, and so on. The hook functions receive this object as their second argument and read or mutate it in place.
|
|
37
|
+
|
|
38
|
+
### Session Marshalling
|
|
39
|
+
|
|
40
|
+
Before any hook runs, the session marshaler populates `pRequestState.SessionData` from a configurable source, selected with `MeadowEndpointsSessionDataSource`:
|
|
41
|
+
|
|
42
|
+
| Source | Origin |
|
|
43
|
+
|--------|--------|
|
|
44
|
+
| `Request` (default) | `pRequest.UserSession`, set by Orator session middleware |
|
|
45
|
+
| `Header` | JSON parsed from the `x-trusted-session` HTTP header |
|
|
46
|
+
| `None` | The default session object only |
|
|
47
|
+
|
|
48
|
+
The marshaler always starts from the `MeadowEndpointsDefaultSessionObject` template and extends it with the resolved source, guaranteeing every operation sees a complete session shape (`UserID`, `CustomerID`, `SessionID`, `UserRole`, `UserRoleIndex`, `LoggedIn`). See [Session Management](session-management.md) for details.
|
|
49
|
+
|
|
50
|
+
## Behavior-Injection Hook Points
|
|
51
|
+
|
|
52
|
+
Behavior injection is the primary extension mechanism: it lets you hook the lifecycle of any endpoint without subclassing or replacing the built-in handler. Hooks are registered by name on the controller's `BehaviorInjection` component, and each name follows the pattern `{Verb}-{Phase}`.
|
|
53
|
+
|
|
54
|
+
<!-- bespoke diagram: edit diagrams/behavior-injection-hook-points.mmd or .hints.json, then: npx pict-renderer-graph build modules/meadow/meadow-endpoints/docs -->
|
|
55
|
+

|
|
56
|
+
|
|
57
|
+
A registered hook receives `(pRequest, pRequestState, fCallback)`. Call `fCallback()` with no argument to continue the waterfall, or call it with an error to halt and route to the error handler. Because the hook is invoked with the controller as its `this`, register hooks as standard functions rather than arrow functions when you need that scope.
|
|
58
|
+
|
|
59
|
+
```javascript
|
|
60
|
+
const tmpEndpoints = new libMeadowEndpoints(tmpMeadow);
|
|
61
|
+
|
|
62
|
+
// Scope every multi-record read to the caller's customer
|
|
63
|
+
tmpEndpoints.controller.BehaviorInjection.setBehavior('Reads-QueryConfiguration',
|
|
64
|
+
function (pRequest, pRequestState, fCallback)
|
|
65
|
+
{
|
|
66
|
+
if (pRequestState.SessionData.UserRoleIndex < 5)
|
|
67
|
+
{
|
|
68
|
+
pRequestState.Query.addFilter('IDCustomer', pRequestState.SessionData.CustomerID);
|
|
69
|
+
}
|
|
70
|
+
return fCallback();
|
|
71
|
+
});
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
The hook phases map onto the operations as follows:
|
|
75
|
+
|
|
76
|
+
| Phase | Runs |
|
|
77
|
+
|-------|------|
|
|
78
|
+
| `{Verb}-PreOperation` | Before the query is built -- ideal for authentication, authorization, and input validation |
|
|
79
|
+
| `{Verb}-QueryConfiguration` | After the query is built but before it executes -- ideal for adding tenant or role filters |
|
|
80
|
+
| `{Verb}-PostOperation` | After the data operation completes -- ideal for transforming results, auditing, or notifications |
|
|
81
|
+
|
|
82
|
+
The available verbs are `Create`, `Read`, `Reads`, `Update`, `Delete`, `Undelete`, `Count`, `CountBy`, `Schema`, `New`, and `Validate`. The exact set of phases each verb exposes is listed in the [Behavior Injection](behavior-injection.md) hook matrix and the [CRUD Deep Dive](crud/README.md).
|
|
83
|
+
|
|
84
|
+
## Controller Architecture
|
|
85
|
+
|
|
86
|
+
The controller owns the request lifecycle and is composed of replaceable components. The default `BaseController` wires up sensible defaults for each:
|
|
87
|
+
|
|
88
|
+
| Component | Responsibility |
|
|
89
|
+
|-----------|----------------|
|
|
90
|
+
| Behavior Injection | Stores and runs the named `{Verb}-{Phase}` hooks |
|
|
91
|
+
| Session Marshaler | Resolves `SessionData` from the configured source |
|
|
92
|
+
| Error Handler | Formats errors and optionally sets HTTP status codes |
|
|
93
|
+
| Log Controller | Emits structured request logging through Fable |
|
|
94
|
+
| Filter Parser | Parses `FilteredTo` URL expressions into query filters |
|
|
95
|
+
|
|
96
|
+
For deep customization, supply your own controller through the constructor options -- either an instantiated `ControllerInstance` or a `ControllerClass` extending the exported `BaseController`. See [Custom Controllers](custom-controllers.md).
|
|
97
|
+
|
|
98
|
+
```javascript
|
|
99
|
+
const libMeadowEndpoints = require('meadow-endpoints');
|
|
100
|
+
const BaseController = libMeadowEndpoints.BaseController;
|
|
101
|
+
|
|
102
|
+
class CustomController extends BaseController
|
|
103
|
+
{
|
|
104
|
+
constructor(pMeadowEndpoints, pControllerOptions)
|
|
105
|
+
{
|
|
106
|
+
super(pMeadowEndpoints, pControllerOptions);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const tmpEndpoints = new libMeadowEndpoints(tmpMeadow,
|
|
111
|
+
{ ControllerClass: CustomController });
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Related Modules
|
|
115
|
+
|
|
116
|
+
- [meadow](https://fable-retold.github.io/meadow/) -- the data access layer Meadow Endpoints generates routes from
|
|
117
|
+
- [orator](https://fable-retold.github.io/orator/) -- the API server that hosts the generated routes
|
|
118
|
+
- [retold-data-service](https://fable-retold.github.io/retold-data-service/) -- assembles Meadow Endpoints into a complete, schema-driven REST service
|
|
119
|
+
- [pict-section-recordset](https://fable-retold.github.io/pict-section-recordset/) -- browser-side UI that consumes these CRUD endpoints
|
package/docs/crud/README.md
CHANGED
|
@@ -8,12 +8,12 @@ Meadow Endpoints generates a full suite of RESTful routes from a configured Mead
|
|
|
8
8
|
|
|
9
9
|
| Group | Operations | Description |
|
|
10
10
|
|-------|-----------|-------------|
|
|
11
|
-
| [Create](
|
|
12
|
-
| [Read](
|
|
13
|
-
| [Update](
|
|
14
|
-
| [Delete](
|
|
15
|
-
| [Count](
|
|
16
|
-
| [Schema](
|
|
11
|
+
| [Create](create.md) | Create, BulkCreate | Insert new records |
|
|
12
|
+
| [Read](read.md) | Read, Reads, ReadsBy, ReadMax, ReadSelectList, ReadLiteList, ReadDistinctList | Retrieve records with pagination, filtering, and projections |
|
|
13
|
+
| [Update](update.md) | Update, BulkUpdate, Upsert, BulkUpsert | Modify existing records |
|
|
14
|
+
| [Delete](delete.md) | Delete, Undelete | Soft-delete and restore records |
|
|
15
|
+
| [Count](count.md) | Count, CountBy | Aggregate record counts |
|
|
16
|
+
| [Schema](schema.md) | Schema, New, Validate | Serve schema metadata, default objects, and validation |
|
|
17
17
|
|
|
18
18
|
## Complete Route Table
|
|
19
19
|
|