@stonecrop/graphql-middleware 0.7.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/README.md ADDED
@@ -0,0 +1,142 @@
1
+ # @stonecrop/graphql-middleware
2
+
3
+ GraphQL backend for the Stonecrop framework. Provides a generic, ORM-like interface over PostGraphile.
4
+
5
+ ## Usage
6
+
7
+ ### Server Setup
8
+
9
+ ```typescript
10
+ import { createServer } from 'postgraphile/grafserv/h3/v1'
11
+ import { grafserv } from 'postgraphile/grafserv'
12
+ import { PostGraphileAmberPreset } from 'postgraphile/presets/amber'
13
+ import { makePgService } from 'postgraphile/adaptors/pg'
14
+ import {
15
+ createStonecropPlugin,
16
+ loadDoctypes,
17
+ registerBuiltinHandlers,
18
+ registerHandler,
19
+ } from '@stonecrop/graphql-middleware'
20
+
21
+ // Load doctype definitions from JSON files
22
+ loadDoctypes('./doctypes')
23
+
24
+ // Register action handlers
25
+ registerBuiltinHandlers()
26
+ registerHandler('submitOrder', async (args, ctx) => {
27
+ const [orderId] = args as [string]
28
+ // Custom business logic
29
+ return { submitted: true }
30
+ })
31
+
32
+ // Create executor for the plugin to use
33
+ const executor = {
34
+ async query(query: string, variables?: Record<string, unknown>) {
35
+ // Execute against PostGraphile's internal schema
36
+ return graphqlExecute(schema, query, variables)
37
+ },
38
+ async mutate(mutation: string, variables?: Record<string, unknown>) {
39
+ return this.query(mutation, variables)
40
+ },
41
+ }
42
+
43
+ const preset: GraphileConfig.Preset = {
44
+ extends: [PostGraphileAmberPreset],
45
+ plugins: [createStonecropPlugin({ executor })],
46
+ pgServices: [
47
+ makePgService({
48
+ connectionString: process.env.DATABASE_URL,
49
+ }),
50
+ ],
51
+ }
52
+ ```
53
+
54
+ ### Client Usage
55
+
56
+ ```typescript
57
+ import { StonecropClient } from '@stonecrop/graphql-middleware'
58
+
59
+ const client = new StonecropClient({
60
+ endpoint: 'http://localhost:4000/graphql',
61
+ })
62
+
63
+ // Get doctype metadata
64
+ const meta = await client.getMeta({ doctype: 'SalesOrder' })
65
+
66
+ // Fetch records
67
+ const orders = await client.getRecords(meta, {
68
+ limit: 10,
69
+ orderBy: 'createdAt',
70
+ })
71
+
72
+ // Fetch single record
73
+ const order = await client.getRecord(meta, 'uuid-here')
74
+
75
+ // Run an action
76
+ const result = await client.runAction(meta, 'submit', [order.id])
77
+ ```
78
+
79
+ ### Doctype Definition
80
+
81
+ ```json
82
+ {
83
+ "name": "SalesOrder",
84
+ "tableName": "sales_orders",
85
+ "fields": [
86
+ { "fieldname": "id", "fieldtype": "UUID" },
87
+ { "fieldname": "customer", "fieldtype": "Link", "required": true },
88
+ { "fieldname": "status", "fieldtype": "Select" },
89
+ { "fieldname": "total", "fieldtype": "Currency" }
90
+ ],
91
+ "workflow": {
92
+ "states": ["Draft", "Submitted", "Cancelled"],
93
+ "actions": {
94
+ "submit": {
95
+ "label": "Submit",
96
+ "handler": "submitOrder",
97
+ "requiredFields": ["customer"],
98
+ "allowedStates": ["Draft"]
99
+ }
100
+ }
101
+ }
102
+ }
103
+ ```
104
+
105
+ ## API
106
+
107
+ ### Registry Functions
108
+
109
+ - `loadDoctypes(dir: string)` - Load doctype JSON files from directory
110
+ - `loadDoctypesFromObject(doctypes)` - Load doctypes from an object
111
+ - `getMeta(name: string)` - Get a single doctype definition
112
+ - `getAllMeta()` - Get all loaded doctypes
113
+ - `registerHandler(name, handler)` - Register an action handler
114
+ - `registerBuiltinHandlers()` - Register built-in handlers
115
+
116
+ ### Built-in Handlers
117
+
118
+ - `validateRequiredFields` - Validates that required fields are present
119
+ - `noop` - Does nothing, returns `{ ok: true }`
120
+
121
+ ### GraphQL Schema
122
+
123
+ The plugin adds these operations:
124
+
125
+ ```graphql
126
+ type Query {
127
+ stonecropMeta(doctype: String!): DoctypeMeta
128
+ stonecropAllMeta: [DoctypeMeta!]!
129
+ stonecropRecord(doctype: String!, id: String!): RecordResult
130
+ stonecropRecords(
131
+ doctype: String!
132
+ filters: JSON
133
+ orderBy: String
134
+ limit: Int
135
+ offset: Int
136
+ ): RecordsResult
137
+ }
138
+
139
+ type Mutation {
140
+ stonecropAction(doctype: String!, action: String!, args: JSON): ActionResult!
141
+ }
142
+ ```