x-openapi-flow 1.2.2 → 1.3.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 CHANGED
@@ -1,5 +1,7 @@
1
1
  # x-openapi-flow
2
2
 
3
+ ![x-openapi-flow logo](../docs/assets/x-openapi-flow-logo.svg)
4
+
3
5
  CLI and extension contract for documenting and validating resource lifecycle workflows in OpenAPI using `x-openapi-flow`.
4
6
 
5
7
  ## Overview
@@ -10,7 +12,7 @@ CLI and extension contract for documenting and validating resource lifecycle wor
10
12
  - Lifecycle graph consistency
11
13
  - Optional quality checks for transitions and references
12
14
 
13
- It also supports a sidecar workflow (`init` + `apply`) to preserve lifecycle metadata when OpenAPI files are regenerated.
15
+ It also supports a sidecar workflow (`init` + `apply`) so lifecycle metadata stays preserved when OpenAPI source files are regenerated.
14
16
 
15
17
  ## Installation
16
18
 
@@ -36,7 +38,7 @@ Use a GitHub PAT with `read:packages` (install) and `write:packages` (publish).
36
38
  ## Quick Start
37
39
 
38
40
  ```bash
39
- npx x-openapi-flow init openapi.yaml
41
+ npx x-openapi-flow init
40
42
  npx x-openapi-flow apply openapi.yaml
41
43
  ```
42
44
 
@@ -44,34 +46,226 @@ Optional checks:
44
46
 
45
47
  ```bash
46
48
  npx x-openapi-flow validate openapi.yaml --profile strict
49
+ npx x-openapi-flow lint openapi.yaml
47
50
  npx x-openapi-flow graph openapi.yaml
48
51
  ```
49
52
 
50
53
  ## CLI Commands
51
54
 
52
55
  ```bash
53
- x-openapi-flow validate <openapi-file> [--format pretty|json] [--profile core|relaxed|strict] [--strict-quality] [--config path]
54
- x-openapi-flow init [openapi-file] [--flows path]
55
- x-openapi-flow apply [openapi-file] [--flows path] [--out path]
56
- x-openapi-flow graph <openapi-file> [--format mermaid|json]
57
- x-openapi-flow doctor [--config path]
56
+ npx x-openapi-flow validate <openapi-file> [--format pretty|json] [--profile core|relaxed|strict] [--strict-quality] [--config path]
57
+ npx x-openapi-flow init [--flows path] [--force] [--dry-run]
58
+ npx x-openapi-flow apply [openapi-file] [--flows path] [--out path]
59
+ npx x-openapi-flow diff [openapi-file] [--flows path] [--format pretty|json]
60
+ npx x-openapi-flow lint [openapi-file] [--format pretty|json] [--config path]
61
+ npx x-openapi-flow graph <openapi-file> [--format mermaid|json]
62
+ npx x-openapi-flow doctor [--config path]
63
+ ```
64
+
65
+ `diff` now reports field-level changes for operations that already exist in the sidecar.
66
+ In `pretty` format, this appears under `Changed details` with changed paths per operation (for example, `current_state` or `transitions[0].target_state`).
67
+ In `json` format, this appears in `diff.changedOperationDetails`:
68
+
69
+ ```json
70
+ {
71
+ "diff": {
72
+ "changedOperationDetails": [
73
+ {
74
+ "operationId": "listItems",
75
+ "changedPaths": ["current_state"]
76
+ }
77
+ ]
78
+ }
79
+ }
80
+ ```
81
+
82
+ ### CI usage (`diff` as a gate)
83
+
84
+ Fail the pipeline when sidecar drift is detected:
85
+
86
+ ```bash
87
+ npx x-openapi-flow diff openapi.yaml --format json | node -e '
88
+ const fs = require("fs");
89
+ const payload = JSON.parse(fs.readFileSync(0, "utf8"));
90
+ const diff = payload.diff || {};
91
+ const changes = (diff.added || 0) + (diff.removed || 0) + (diff.changed || 0);
92
+ if (changes > 0) {
93
+ console.error("x-openapi-flow diff detected changes. Run init/apply and commit sidecar updates.");
94
+ process.exit(1);
95
+ }
96
+ '
97
+ ```
98
+
99
+ This keeps `.x` sidecar data aligned with the OpenAPI source in pull requests.
100
+
101
+ ## Semantic lint (`lint`)
102
+
103
+ Use `lint` to run semantic checks focused on flow modeling quality.
104
+
105
+ ```bash
106
+ npx x-openapi-flow lint openapi.yaml
107
+ npx x-openapi-flow lint openapi.yaml --format json
108
+ ```
109
+
110
+ MVP semantic rules:
111
+
112
+ - `next_operation_id_exists`
113
+ - `prerequisite_operation_ids_exist`
114
+ - `duplicate_transitions`
115
+ - `terminal_path` (states without path to terminal)
116
+
117
+ Disable individual rules with config (`x-openapi-flow.config.json`):
118
+
119
+ ```json
120
+ {
121
+ "lint": {
122
+ "rules": {
123
+ "next_operation_id_exists": true,
124
+ "prerequisite_operation_ids_exist": true,
125
+ "duplicate_transitions": false,
126
+ "terminal_path": true
127
+ }
128
+ }
129
+ }
58
130
  ```
59
131
 
132
+ ## Graph JSON contract (`graph --format json`)
133
+
134
+ `graph --format json` returns a stable contract for CI/pipeline integrations:
135
+
136
+ - `format_version`: output contract version (currently `"1.0"`).
137
+ - `flowCount`: number of operations with `x-openapi-flow`.
138
+ - `nodes`: sorted state names (deterministic order).
139
+ - `edges`: sorted transitions by `from`, `to`, `next_operation_id`, and prerequisites.
140
+ - `mermaid`: deterministic Mermaid rendering of the same graph.
141
+
142
+ Example:
143
+
144
+ ```json
145
+ {
146
+ "format_version": "1.0",
147
+ "flowCount": 3,
148
+ "nodes": ["CONFIRMED", "CREATED", "SHIPPED"],
149
+ "edges": [
150
+ {
151
+ "from": "CONFIRMED",
152
+ "to": "SHIPPED",
153
+ "next_operation_id": "shipOrder",
154
+ "prerequisite_operation_ids": []
155
+ }
156
+ ],
157
+ "mermaid": "stateDiagram-v2\n state CONFIRMED\n state CREATED\n state SHIPPED\n CONFIRMED --> SHIPPED: next:shipOrder"
158
+ }
159
+ ```
160
+
161
+ ## HTTP Methods Support
162
+
163
+ `init`, `apply`, and `graph` support all OpenAPI 3 HTTP operation methods:
164
+
165
+ - `get`
166
+ - `put`
167
+ - `post`
168
+ - `delete`
169
+ - `options`
170
+ - `head`
171
+ - `patch`
172
+ - `trace`
173
+
60
174
  ## Sidecar Workflow
61
175
 
62
- `init` always works on an existing OpenAPI file in your repository.
63
- `init` creates/synchronizes `{context}-openapi-flow.(json|yaml)` as a persistent sidecar for your `x-openapi-flow` data.
64
- Use `apply` to inject sidecar flows back into regenerated OpenAPI files.
65
- If no OpenAPI/Swagger file exists yet, generate one first with your framework's official OpenAPI/Swagger tooling.
176
+ Behavior summary:
177
+
178
+ - `init` works on an existing OpenAPI source file in your repository.
179
+ - `init` creates/synchronizes `{context}.x.(json|yaml)` as a persistent sidecar for `x-openapi-flow` data.
180
+ - If `{context}.flow.(json|yaml)` does not exist, `init` generates it automatically (same merge result as `apply`).
181
+ - If `{context}.flow.(json|yaml)` already exists, `init` asks in interactive mode whether to recreate it.
182
+ - On confirmation (or with `--force`), `init` creates a sidecar backup as `{context}.x.(json|yaml).backup-N` before regenerating `{context}.flow.(json|yaml)`.
183
+ - In non-interactive mode, `init` fails when flow output already exists unless `--force` is provided.
184
+ - With `--dry-run`, `init` prints a summary of sidecar/flow behavior without writing files.
185
+ - Use `apply` to inject sidecar flows back into regenerated OpenAPI source files.
186
+ - If no OpenAPI/Swagger source file exists yet, generate one first with your framework's official tooling.
66
187
 
67
188
  ### Recommended Sequence
68
189
 
69
190
  ```bash
70
- x-openapi-flow init openapi.yaml
71
- # edit {context}-openapi-flow.(json|yaml)
72
- x-openapi-flow apply openapi.yaml
191
+ npx x-openapi-flow init
192
+ npx x-openapi-flow init --dry-run
193
+ # edit {context}.x.(json|yaml)
194
+ npx x-openapi-flow diff openapi.yaml
195
+ npx x-openapi-flow apply openapi.yaml
73
196
  ```
74
197
 
198
+ ## Sidecar File Contract (all supported fields)
199
+
200
+ Sidecar top-level shape:
201
+
202
+ ```yaml
203
+ version: "1.0"
204
+ operations:
205
+ - operationId: createOrder
206
+ x-openapi-flow:
207
+ version: "1.0"
208
+ id: create-order
209
+ current_state: CREATED
210
+ description: Creates an order and starts its lifecycle
211
+ idempotency:
212
+ header: Idempotency-Key
213
+ required: true
214
+ transitions:
215
+ - target_state: PAID
216
+ trigger_type: synchronous
217
+ condition: Payment approved
218
+ next_operation_id: payOrder
219
+ prerequisite_operation_ids:
220
+ - createOrder
221
+ prerequisite_field_refs:
222
+ - createOrder:request.body.customer_id
223
+ propagated_field_refs:
224
+ - createOrder:response.201.body.order_id
225
+ ```
226
+
227
+ Top-level (sidecar document):
228
+
229
+ - `version` (optional, string): sidecar contract version. Default is `"1.0"`.
230
+ - `operations` (optional, array): entries keyed by operation.
231
+
232
+ Per operation entry:
233
+
234
+ - `operationId` (recommended, string): target operation identifier in OpenAPI.
235
+ - `x-openapi-flow` (object): lifecycle metadata for that operation.
236
+ - `key` (optional, legacy): backward-compatibility fallback key used by apply.
237
+
238
+ `x-openapi-flow` fields:
239
+
240
+ - Required:
241
+ - `version` (string): currently `"1.0"`.
242
+ - `id` (string): unique flow id.
243
+ - `current_state` (string): state represented by this operation.
244
+ - Optional:
245
+ - `description` (string): human-readable purpose.
246
+ - `idempotency` (object):
247
+ - `header` (required, string)
248
+ - `required` (optional, boolean)
249
+ - `transitions` (array of transition objects)
250
+
251
+ Transition object fields:
252
+
253
+ - Required:
254
+ - `target_state` (string)
255
+ - `trigger_type` (enum): `synchronous`, `webhook`, `polling`
256
+ - Optional:
257
+ - `condition` (string)
258
+ - `next_operation_id` (string)
259
+ - `prerequisite_operation_ids` (array of strings)
260
+ - `prerequisite_field_refs` (array of strings)
261
+ - `propagated_field_refs` (array of strings)
262
+
263
+ Field refs format:
264
+
265
+ - `operationId:request.body.field`
266
+ - `operationId:request.path.paramName`
267
+ - `operationId:response.<status>.body.field`
268
+
75
269
  ## Configuration
76
270
 
77
271
  Create `x-openapi-flow.config.json` in your project directory:
@@ -106,18 +300,18 @@ Field reference format:
106
300
  ### Swagger UI
107
301
 
108
302
  - There is no Swagger UI-based automated test in this repo today (tests are CLI-only).
109
- - For UI interpretation of `x-openapi-flow`, use `showExtensions: true` plus the example plugin at `examples/swagger-ui/x-openapi-flow-plugin.js`.
303
+ - For UI interpretation of `x-openapi-flow`, use `showExtensions: true` with the plugin at `lib/swagger-ui/x-openapi-flow-plugin.js`.
110
304
  - A ready HTML example is available at `examples/swagger-ui/index.html`.
111
305
  - The plugin renders a global **Flow Overview** (Mermaid image) near the top of the docs, plus operation-level flow cards.
112
306
 
113
- ![Swagger UI integration result](../docs/assets/swagger-ui-integration-result-v2.svg)
307
+ ![Swagger UI integration result](../docs/assets/x-openapi-flow-extension.png)
114
308
 
115
309
  ### Graph Output Example
116
310
 
117
311
  `x-openapi-flow graph` includes transition guidance labels in Mermaid output when present (`next_operation_id`, `prerequisite_operation_ids`).
118
- The `graph` command accepts both full OpenAPI files and sidecar files (`{context}-openapi-flow.(json|yaml)`).
312
+ The `graph` command accepts both full OpenAPI source files and sidecar files (`{context}.x.(json|yaml)` and legacy `{context}-openapi-flow.(json|yaml)`).
119
313
 
120
- ![Guided graph example](../docs/assets/graph-order-guided.svg)
314
+ ![Guided graph example](../docs/assets/x-openapi-flow-overview.png)
121
315
 
122
316
  ## Repository and Documentation
123
317