@proseql/rest 0.1.0
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/LICENSE +21 -0
- package/dist/error-mapping.d.ts +60 -0
- package/dist/error-mapping.d.ts.map +1 -0
- package/dist/error-mapping.js +183 -0
- package/dist/error-mapping.js.map +1 -0
- package/dist/handlers.d.ts +112 -0
- package/dist/handlers.d.ts.map +1 -0
- package/dist/handlers.js +402 -0
- package/dist/handlers.js.map +1 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +46 -0
- package/dist/index.js.map +1 -0
- package/dist/query-params.d.ts +132 -0
- package/dist/query-params.d.ts.map +1 -0
- package/dist/query-params.js +380 -0
- package/dist/query-params.js.map +1 -0
- package/dist/relationship-routes.d.ts +82 -0
- package/dist/relationship-routes.d.ts.map +1 -0
- package/dist/relationship-routes.js +273 -0
- package/dist/relationship-routes.js.map +1 -0
- package/package.json +49 -0
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* REST Relationship Route Generation for proseql databases.
|
|
3
|
+
*
|
|
4
|
+
* Generates framework-agnostic HTTP handlers for relationship sub-routes
|
|
5
|
+
* derived from collection relationship definitions in the DatabaseConfig.
|
|
6
|
+
*
|
|
7
|
+
* For `ref` relationships (e.g., books.author), generates:
|
|
8
|
+
* GET /books/:id/author — returns the related author entity
|
|
9
|
+
*
|
|
10
|
+
* For `inverse` relationships (e.g., authors.books), generates:
|
|
11
|
+
* GET /authors/:id/books — returns related book entities
|
|
12
|
+
*
|
|
13
|
+
* @module
|
|
14
|
+
*/
|
|
15
|
+
import { Cause, Chunk, Effect, Option, Runtime, Stream } from "effect";
|
|
16
|
+
// ============================================================================
|
|
17
|
+
// Relationship Inspection
|
|
18
|
+
// ============================================================================
|
|
19
|
+
/**
|
|
20
|
+
* Extract all relationship definitions from a database configuration.
|
|
21
|
+
*
|
|
22
|
+
* Iterates over all collections in the config and extracts relationship
|
|
23
|
+
* metadata for each defined relationship.
|
|
24
|
+
*
|
|
25
|
+
* @param config - The database configuration
|
|
26
|
+
* @returns Array of relationship route info objects
|
|
27
|
+
*/
|
|
28
|
+
export const extractRelationships = (config) => {
|
|
29
|
+
const relationships = [];
|
|
30
|
+
for (const [collectionName, collectionConfig] of Object.entries(config)) {
|
|
31
|
+
const collectionRelationships = collectionConfig.relationships;
|
|
32
|
+
if (!collectionRelationships)
|
|
33
|
+
continue;
|
|
34
|
+
for (const [relationshipName, relationship] of Object.entries(collectionRelationships)) {
|
|
35
|
+
relationships.push({
|
|
36
|
+
sourceCollection: collectionName,
|
|
37
|
+
relationshipName,
|
|
38
|
+
relationship: relationship,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return relationships;
|
|
43
|
+
};
|
|
44
|
+
// ============================================================================
|
|
45
|
+
// Handler Creation
|
|
46
|
+
// ============================================================================
|
|
47
|
+
/**
|
|
48
|
+
* Create a handler for a `ref` relationship route.
|
|
49
|
+
*
|
|
50
|
+
* For a `ref` relationship like `books.author`, this generates a handler for
|
|
51
|
+
* `GET /books/:id/author` that:
|
|
52
|
+
* 1. Finds the source entity (book) by ID
|
|
53
|
+
* 2. Follows the foreign key to the target collection (authors)
|
|
54
|
+
* 3. Returns the related entity
|
|
55
|
+
*
|
|
56
|
+
* @param sourceCollection - The collection object for the source entity
|
|
57
|
+
* @param targetCollection - The collection object for the target entity
|
|
58
|
+
* @param foreignKey - The foreign key field name on the source entity
|
|
59
|
+
* @returns A REST handler function
|
|
60
|
+
*/
|
|
61
|
+
const createRefRelationshipHandler = (
|
|
62
|
+
// biome-ignore lint/suspicious/noExplicitAny: Collection type is dynamic
|
|
63
|
+
sourceCollection,
|
|
64
|
+
// biome-ignore lint/suspicious/noExplicitAny: Collection type is dynamic
|
|
65
|
+
targetCollection, foreignKey) => {
|
|
66
|
+
return async (req) => {
|
|
67
|
+
const { id } = req.params;
|
|
68
|
+
try {
|
|
69
|
+
// Find the source entity
|
|
70
|
+
const findSourceEffect = sourceCollection.findById(id);
|
|
71
|
+
const sourceEntity = await Effect.runPromise(findSourceEffect);
|
|
72
|
+
// Get the foreign key value
|
|
73
|
+
const targetId = sourceEntity[foreignKey];
|
|
74
|
+
if (targetId === null || targetId === undefined) {
|
|
75
|
+
// No related entity (foreign key is null/undefined)
|
|
76
|
+
return { status: 200, body: null };
|
|
77
|
+
}
|
|
78
|
+
// Find the related entity
|
|
79
|
+
const findTargetEffect = targetCollection.findById(targetId);
|
|
80
|
+
const targetEntity = await Effect.runPromise(findTargetEffect);
|
|
81
|
+
return { status: 200, body: targetEntity };
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
if (isTaggedError(error, "NotFoundError")) {
|
|
85
|
+
return {
|
|
86
|
+
status: 404,
|
|
87
|
+
body: { error: "Not found", _tag: "NotFoundError" },
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
return { status: 500, body: { error: "Internal server error" } };
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* Create a handler for an `inverse` relationship route.
|
|
96
|
+
*
|
|
97
|
+
* For an `inverse` relationship like `authors.books`, this generates a handler
|
|
98
|
+
* for `GET /authors/:id/books` that:
|
|
99
|
+
* 1. Verifies the source entity (author) exists
|
|
100
|
+
* 2. Queries the target collection (books) filtered by the foreign key
|
|
101
|
+
* 3. Returns the related entities array
|
|
102
|
+
*
|
|
103
|
+
* @param sourceCollection - The collection object for the source entity
|
|
104
|
+
* @param targetCollection - The collection object for the target entity
|
|
105
|
+
* @param foreignKey - The foreign key field name on the target entity
|
|
106
|
+
* @returns A REST handler function
|
|
107
|
+
*/
|
|
108
|
+
const createInverseRelationshipHandler = (
|
|
109
|
+
// biome-ignore lint/suspicious/noExplicitAny: Collection type is dynamic
|
|
110
|
+
sourceCollection,
|
|
111
|
+
// biome-ignore lint/suspicious/noExplicitAny: Collection type is dynamic
|
|
112
|
+
targetCollection, foreignKey) => {
|
|
113
|
+
return async (req) => {
|
|
114
|
+
const { id } = req.params;
|
|
115
|
+
try {
|
|
116
|
+
// Verify the source entity exists
|
|
117
|
+
const findSourceEffect = sourceCollection.findById(id);
|
|
118
|
+
await Effect.runPromise(findSourceEffect);
|
|
119
|
+
// Query the target collection for related entities
|
|
120
|
+
const queryConfig = {
|
|
121
|
+
where: { [foreignKey]: id },
|
|
122
|
+
};
|
|
123
|
+
const stream = targetCollection.query(queryConfig);
|
|
124
|
+
const results = await Effect.runPromise(Stream.runCollect(stream).pipe(Effect.map(Chunk.toReadonlyArray)));
|
|
125
|
+
return { status: 200, body: results };
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
if (isTaggedError(error, "NotFoundError")) {
|
|
129
|
+
return {
|
|
130
|
+
status: 404,
|
|
131
|
+
body: { error: "Not found", _tag: "NotFoundError" },
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
return { status: 500, body: { error: "Internal server error" } };
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
};
|
|
138
|
+
// ============================================================================
|
|
139
|
+
// Route Generation
|
|
140
|
+
// ============================================================================
|
|
141
|
+
/**
|
|
142
|
+
* Create REST handlers for all relationship routes in a database.
|
|
143
|
+
*
|
|
144
|
+
* Generates sub-routes for navigating relationships:
|
|
145
|
+
* - `ref` relationships: `GET /:collection/:id/:relationshipName`
|
|
146
|
+
* - `inverse` relationships: `GET /:collection/:id/:relationshipName`
|
|
147
|
+
*
|
|
148
|
+
* @param config - The database configuration defining collections and relationships
|
|
149
|
+
* @param db - An EffectDatabase or EffectDatabaseWithPersistence instance
|
|
150
|
+
* @returns Array of route descriptors for relationship routes
|
|
151
|
+
*
|
|
152
|
+
* @example
|
|
153
|
+
* ```typescript
|
|
154
|
+
* const config = {
|
|
155
|
+
* books: {
|
|
156
|
+
* schema: BookSchema,
|
|
157
|
+
* relationships: {
|
|
158
|
+
* author: { type: "ref", target: "authors", foreignKey: "authorId" },
|
|
159
|
+
* },
|
|
160
|
+
* },
|
|
161
|
+
* authors: {
|
|
162
|
+
* schema: AuthorSchema,
|
|
163
|
+
* relationships: {
|
|
164
|
+
* books: { type: "inverse", target: "books", foreignKey: "authorId" },
|
|
165
|
+
* },
|
|
166
|
+
* },
|
|
167
|
+
* } as const
|
|
168
|
+
*
|
|
169
|
+
* const routes = createRelationshipRoutes(config, db)
|
|
170
|
+
* // Generates:
|
|
171
|
+
* // GET /books/:id/author — returns the author of a book
|
|
172
|
+
* // GET /authors/:id/books — returns all books by an author
|
|
173
|
+
* ```
|
|
174
|
+
*/
|
|
175
|
+
export const createRelationshipRoutes = (config, db) => {
|
|
176
|
+
const routes = [];
|
|
177
|
+
const relationships = extractRelationships(config);
|
|
178
|
+
for (const { sourceCollection, relationshipName, relationship, } of relationships) {
|
|
179
|
+
// Get the source and target collections from the database
|
|
180
|
+
// biome-ignore lint/suspicious/noExplicitAny: Collection type is dynamic
|
|
181
|
+
const source = db[sourceCollection];
|
|
182
|
+
// biome-ignore lint/suspicious/noExplicitAny: Collection type is dynamic
|
|
183
|
+
const target = db[relationship.target];
|
|
184
|
+
if (!source || !target) {
|
|
185
|
+
// Skip if collections don't exist (shouldn't happen with valid config)
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
const path = `/${sourceCollection}/:id/${relationshipName}`;
|
|
189
|
+
if (relationship.type === "ref") {
|
|
190
|
+
// For ref relationships, the foreign key is on the source entity
|
|
191
|
+
const foreignKey = relationship.foreignKey || `${relationshipName}Id`;
|
|
192
|
+
routes.push({
|
|
193
|
+
method: "GET",
|
|
194
|
+
path,
|
|
195
|
+
handler: createRefRelationshipHandler(source, target, foreignKey),
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
else if (relationship.type === "inverse") {
|
|
199
|
+
// For inverse relationships, the foreign key is on the target entity
|
|
200
|
+
// The foreignKey in the config specifies the field on the target that points back
|
|
201
|
+
const foreignKey = relationship.foreignKey || deriveForeignKey(sourceCollection);
|
|
202
|
+
routes.push({
|
|
203
|
+
method: "GET",
|
|
204
|
+
path,
|
|
205
|
+
handler: createInverseRelationshipHandler(source, target, foreignKey),
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return routes;
|
|
210
|
+
};
|
|
211
|
+
// ============================================================================
|
|
212
|
+
// Utility Functions
|
|
213
|
+
// ============================================================================
|
|
214
|
+
/**
|
|
215
|
+
* Derive a default foreign key name from a collection name.
|
|
216
|
+
*
|
|
217
|
+
* Converts plural collection names to singular + "Id":
|
|
218
|
+
* - "users" → "userId"
|
|
219
|
+
* - "companies" → "companyId"
|
|
220
|
+
* - "categories" → "categoryId"
|
|
221
|
+
*
|
|
222
|
+
* @param collectionName - The collection name (typically plural)
|
|
223
|
+
* @returns The derived foreign key field name
|
|
224
|
+
*/
|
|
225
|
+
const deriveForeignKey = (collectionName) => {
|
|
226
|
+
// Handle "-ies" plural (companies → companyId)
|
|
227
|
+
if (collectionName.endsWith("ies")) {
|
|
228
|
+
return `${collectionName.slice(0, -3)}yId`;
|
|
229
|
+
}
|
|
230
|
+
// Handle regular "-s" plural (users → userId)
|
|
231
|
+
if (collectionName.endsWith("s")) {
|
|
232
|
+
return `${collectionName.slice(0, -1)}Id`;
|
|
233
|
+
}
|
|
234
|
+
// Fallback: just append "Id"
|
|
235
|
+
return `${collectionName}Id`;
|
|
236
|
+
};
|
|
237
|
+
/**
|
|
238
|
+
* Extract a tagged error from an unknown error value.
|
|
239
|
+
*
|
|
240
|
+
* Effect.runPromise throws a FiberFailure when the Effect fails.
|
|
241
|
+
* This function extracts the underlying tagged error from the FiberFailure
|
|
242
|
+
* or returns the error directly if it's already a tagged error.
|
|
243
|
+
*/
|
|
244
|
+
const extractTaggedError = (error) => {
|
|
245
|
+
// Check if it's a FiberFailure (from Effect.runPromise)
|
|
246
|
+
if (Runtime.isFiberFailure(error)) {
|
|
247
|
+
// Get the cause from the FiberFailure using the well-known symbol
|
|
248
|
+
const causeSymbol = Symbol.for("effect/Runtime/FiberFailure/Cause");
|
|
249
|
+
const cause = error[causeSymbol];
|
|
250
|
+
// Extract the failure from the cause
|
|
251
|
+
const failure = Cause.failureOption(cause);
|
|
252
|
+
if (Option.isSome(failure)) {
|
|
253
|
+
const value = failure.value;
|
|
254
|
+
if (value !== null && typeof value === "object" && "_tag" in value) {
|
|
255
|
+
return value;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
// Check if it's already a tagged error
|
|
260
|
+
if (error !== null && typeof error === "object" && "_tag" in error) {
|
|
261
|
+
return error;
|
|
262
|
+
}
|
|
263
|
+
return null;
|
|
264
|
+
};
|
|
265
|
+
/**
|
|
266
|
+
* Type guard to check if an error has a specific _tag.
|
|
267
|
+
* Handles both direct tagged errors and FiberFailure wrappers.
|
|
268
|
+
*/
|
|
269
|
+
const isTaggedError = (error, tag) => {
|
|
270
|
+
const taggedError = extractTaggedError(error);
|
|
271
|
+
return taggedError !== null && taggedError._tag === tag;
|
|
272
|
+
};
|
|
273
|
+
//# sourceMappingURL=relationship-routes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relationship-routes.js","sourceRoot":"","sources":["../src/relationship-routes.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@proseql/rest",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "REST API handlers for ProseQL databases, framework-agnostic",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"build": "bunx tsc --build",
|
|
8
|
+
"clean": "rm -rf dist *.tsbuildinfo",
|
|
9
|
+
"prepublishOnly": "bun run build && bun test"
|
|
10
|
+
},
|
|
11
|
+
"main": "dist/index.js",
|
|
12
|
+
"types": "dist/index.d.ts",
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"import": "./dist/index.js"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"dist",
|
|
21
|
+
"LICENSE",
|
|
22
|
+
"README.md"
|
|
23
|
+
],
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"repository": {
|
|
26
|
+
"type": "git",
|
|
27
|
+
"url": "https://github.com/simonwjackson/proseql.git",
|
|
28
|
+
"directory": "packages/rest"
|
|
29
|
+
},
|
|
30
|
+
"keywords": [
|
|
31
|
+
"database",
|
|
32
|
+
"typescript",
|
|
33
|
+
"effect",
|
|
34
|
+
"rest",
|
|
35
|
+
"api",
|
|
36
|
+
"plain-text",
|
|
37
|
+
"type-safe"
|
|
38
|
+
],
|
|
39
|
+
"engines": {
|
|
40
|
+
"node": ">=18"
|
|
41
|
+
},
|
|
42
|
+
"sideEffects": false,
|
|
43
|
+
"dependencies": {
|
|
44
|
+
"@proseql/core": "workspace:*"
|
|
45
|
+
},
|
|
46
|
+
"peerDependencies": {
|
|
47
|
+
"effect": "^3.15.0"
|
|
48
|
+
}
|
|
49
|
+
}
|