@feasibleone/blong-openapi 1.1.3 → 1.2.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/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.2.0](https://github.com/feasibleone/blong/compare/blong-openapi-v1.1.4...blong-openapi-v1.2.0) (2026-05-19)
4
+
5
+
6
+ ### Features
7
+
8
+ * blong-dev ([8eb1aa4](https://github.com/feasibleone/blong/commit/8eb1aa4a8acb6a3dcdd52fb51582e0403efa4064))
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * lint ([e566423](https://github.com/feasibleone/blong/commit/e5664233dee91b8f66eef8fc8ae1f40a33d6c59f))
14
+ * linting ([46d7549](https://github.com/feasibleone/blong/commit/46d7549477c6b863e09972e8c6903a38b5836a8e))
15
+
16
+ ## [1.1.4](https://github.com/feasibleone/blong/compare/blong-openapi-v1.1.3...blong-openapi-v1.1.4) (2026-04-26)
17
+
18
+
19
+ ### Bug Fixes
20
+
21
+ * dependencies ([705b2f7](https://github.com/feasibleone/blong/commit/705b2f7a72ac2dc93aea0f586394dde71192c1b6))
22
+ * eslint ([a3b9f2b](https://github.com/feasibleone/blong/commit/a3b9f2bed4f958abfb378d97d372b3e7a6cd5a21))
23
+ * remove heft lint ([c4d0eaa](https://github.com/feasibleone/blong/commit/c4d0eaa81714c04e9f9adec01c6ae7fa068f1948))
24
+
3
25
  ## [1.1.3](https://github.com/feasibleone/blong/compare/blong-openapi-v1.1.2...blong-openapi-v1.1.3) (2026-03-02)
4
26
 
5
27
 
package/README.md ADDED
@@ -0,0 +1,266 @@
1
+ <!-- markdownlint-disable MD033 MD041 -->
2
+ <div align="center">
3
+
4
+ ![Blong logo](https://raw.githubusercontent.com/feasibleone/blong/refs/heads/main/img/manta200.png)
5
+
6
+ # Blong OpenAPI
7
+
8
+ OpenAPI/Swagger integration for the Blong framework
9
+
10
+ [![docs](https://raw.githubusercontent.com/feasibleone/blong/refs/heads/main/img/button.png)](https://feasibleone.github.io/blong-docs/)
11
+
12
+ </div>
13
+
14
+ ## Overview
15
+
16
+ `@feasibleone/blong-openapi` provides seamless integration with external REST
17
+ APIs using OpenAPI 2.0/3.0 (Swagger) definitions. It automatically generates
18
+ type-safe handlers from API specifications, enabling you to call external
19
+ services without writing manual HTTP request code.
20
+
21
+ ## Features
22
+
23
+ - **Automatic Handler Generation**: Parse OpenAPI/Swagger definitions and
24
+ generate callable handlers
25
+ - **Type-Safe Integration**: Use `operationId` from API specs as handler names
26
+ - **Multiple API Support**: Configure multiple API namespaces in a single orchestrator
27
+ - **URL & File Support**: Load specifications from local files or remote URLs
28
+ - **Flexible Configuration**: Override servers, paths, and other API properties
29
+ - **Microservice Ready**: Deployable as standalone service or part of monolith
30
+
31
+ ## Installation
32
+
33
+ ```bash
34
+ # Using pnpm (recommended)
35
+ pnpm add @feasibleone/blong-openapi
36
+
37
+ # Using npm
38
+ npm install @feasibleone/blong-openapi
39
+ ```
40
+
41
+ ## Quick Start
42
+
43
+ ### 1. Create OpenAPI Orchestrator
44
+
45
+ ```typescript
46
+ // realmname/orchestrator/openapi.ts
47
+ import {orchestrator} from '@feasibleone/blong';
48
+
49
+ export default orchestrator(() => ({
50
+ extends: 'orchestrator.openapi',
51
+ }));
52
+ ```
53
+
54
+ ### 2. Configure API Namespace
55
+
56
+ ```typescript
57
+ // realmname/server.ts
58
+ import {realm} from '@feasibleone/blong';
59
+
60
+ export default realm(blong => ({
61
+ url: import.meta.url,
62
+ validation: blong.type.Object({
63
+ openapi: blong.type.Object({}),
64
+ }),
65
+ children: ['./orchestrator'],
66
+ config: {
67
+ default: {
68
+ openapi: {
69
+ logLevel: 'info',
70
+ namespace: ['api'],
71
+ api: {
72
+ namespace: {
73
+ weather: [
74
+ './definitions/weather-api.yaml',
75
+ './definitions/weather-operations.yaml',
76
+ ],
77
+ },
78
+ },
79
+ },
80
+ },
81
+ },
82
+ }));
83
+ ```
84
+
85
+ ### 3. Call the API
86
+
87
+ Handlers are automatically generated using the pattern: `namespace + operationId`
88
+
89
+ ```typescript
90
+ // In your orchestrator/adapter
91
+ const result = await this.bus.weatherGetCurrentWeather({
92
+ params: {city: 'London'},
93
+ });
94
+ ```
95
+
96
+ ## Configuration
97
+
98
+ ### Basic Configuration
99
+
100
+ ```yaml
101
+ openapi:
102
+ logLevel: info # Log level for the orchestrator
103
+ namespace: ['api'] # Namespace prefix for calling handlers
104
+ api:
105
+ namespace:
106
+ weather: # API namespace identifier
107
+ - ./api/weather.yaml # OpenAPI/Swagger definition (local)
108
+ - https://api.example.com/swagger.json # or remote URL
109
+ ```
110
+
111
+ ### Advanced Configuration
112
+
113
+ Configure multiple APIs with custom settings:
114
+
115
+ ```yaml
116
+ openapi:
117
+ api:
118
+ namespace:
119
+ # External API with custom server override
120
+ payment:
121
+ - https://payment-api.example.com/openapi.json
122
+ - host: 'api.production.com'
123
+ basePath: '/v2'
124
+ x-blong:
125
+ destination: 'paymentService'
126
+ namespace: 'payment'
127
+
128
+ # Kubernetes API integration
129
+ k8s:
130
+ - https://kubernetes.io/api/v1/swagger.json
131
+ - servers:
132
+ - url: 'https://k8s-cluster:6443'
133
+ ```
134
+
135
+ ### Multiple Definition Files
136
+
137
+ Split large API definitions across multiple files:
138
+
139
+ ```yaml
140
+ api:
141
+ namespace:
142
+ time:
143
+ - ./api/world-time.yaml # Base OpenAPI definition
144
+ - ./api/world-time.operations.yaml # Additional operationId mappings
145
+ - servers:
146
+ - url: 'http://worldtimeapi.org'
147
+ ```
148
+
149
+ ## Usage Patterns
150
+
151
+ ### With HTTP Adapter
152
+
153
+ Combine with HTTP adapter for external API integration:
154
+
155
+ ```typescript
156
+ // adapter/weather.ts
157
+ import {adapter} from '@feasibleone/blong';
158
+
159
+ export default adapter(() => ({
160
+ extends: 'adapter.http',
161
+ }));
162
+ ```
163
+
164
+ ```typescript
165
+ // server.ts
166
+ config: {
167
+ default: {
168
+ weather: {
169
+ imports: ['codec.openapi'],
170
+ namespace: ['weather'],
171
+ 'codec.openapi': {
172
+ namespace: {
173
+ weather: ['./api/weather.yaml']
174
+ }
175
+ }
176
+ }
177
+ }
178
+ }
179
+ ```
180
+
181
+ ### Microservice Deployment
182
+
183
+ Deploy as standalone microservice:
184
+
185
+ ```yaml
186
+ microservice:
187
+ orchestrator: true # Enable orchestrator mode
188
+ gateway:
189
+ port: 8081 # Expose on port 8081
190
+ ```
191
+
192
+ ### Custom Operation IDs
193
+
194
+ If API doesn't define `operationId`, create mapping file:
195
+
196
+ ```yaml
197
+ # weather-operations.yaml
198
+ paths:
199
+ /weather/current:
200
+ get:
201
+ operationId: getCurrentWeather
202
+ x-blong-method: weatherCurrent # Alternative method name
203
+ ```
204
+
205
+ ## Handler Naming Convention
206
+
207
+ Generated handlers follow the pattern: `{namespace}{operationId}`
208
+
209
+ **Examples:**
210
+
211
+ | Namespace | operationId | Handler Name |
212
+ | ----------- | ------------- | -------------- |
213
+ | weather | GetForecast | `weatherGetForecast` |
214
+ | payment | CreateTransaction | `paymentCreateTransaction` |
215
+ | k8s | listNamespaces | `k8sListNamespaces` |
216
+
217
+ Names are case-sensitive and trimmed of whitespace.
218
+
219
+ ## Integration Examples
220
+
221
+ ### REST API Client
222
+
223
+ See [REST Client Pattern](https://feasibleone.github.io/blong-docs/patterns/rest/#client) in docs
224
+
225
+ ### Webhook Integration
226
+
227
+ ```typescript
228
+ // adapter/webhook.ts
229
+ import {adapter} from '@feasibleone/blong';
230
+
231
+ export default adapter(() => ({
232
+ extends: 'adapter.webhook',
233
+ }));
234
+ ```
235
+
236
+ Configure incoming webhooks with OpenAPI definitions:
237
+
238
+ ```yaml
239
+ webhook:
240
+ imports: ['codec.openapi']
241
+ 'codec.openapi':
242
+ namespace:
243
+ github:
244
+ - ./api/github-webhooks.yaml
245
+ ```
246
+
247
+ ## Related Packages
248
+
249
+ - **[@feasibleone/blong](https://www.npmjs.com/package/@feasibleone/blong)** -
250
+ Core framework
251
+ - **[@feasibleone/blong-gogo](https://www.npmjs.com/package/@feasibleone/blong-gogo)** -
252
+ Contains base `orchestrator.openapi` and `codec.openapi`
253
+ - **[openapi-types](https://www.npmjs.com/package/openapi-types)** - TypeScript
254
+ types for OpenAPI
255
+
256
+ ## Documentation
257
+
258
+ - **[Blong Documentation](https://feasibleone.github.io/blong-docs/)**
259
+ - **[OpenAPI Codec Pattern](https://feasibleone.github.io/blong-docs/patterns/codec/#openapi)**
260
+ - **[REST API Pattern](https://feasibleone.github.io/blong-docs/patterns/rest/)**
261
+ - **[Adapter Pattern](https://feasibleone.github.io/blong-docs/patterns/adapter/)**
262
+
263
+ ## Example Projects
264
+
265
+ See the [test/api](../../core/test/api/) folder for working examples with
266
+ world-time API integration.
package/dist/index.js CHANGED
@@ -10,11 +10,11 @@ const openapiServer = server(blong => ({
10
10
  },
11
11
  }));
12
12
  const openapi = async (load, config) => {
13
- const realms = await Promise.all([
13
+ const platforms = await Promise.all([
14
14
  load(openapiServer, 'impl', config, ['microservice', 'integration', 'dev']),
15
15
  ]);
16
- for (const realm of realms)
17
- await realm.start();
16
+ for (const platform of platforms)
17
+ await platform.start();
18
18
  };
19
19
  export default async (load) => openapi(load, {
20
20
  'blong-openapi': {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,oBAAoB,CAAC;AAE1C,MAAM,aAAa,GAAG,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACnC,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG;IACpB,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;QAC1B,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;KACjC,CAAC;IACF,QAAQ,EAAE,CAAC,kBAAkB,CAAC;IAC9B,MAAM,EAAE;QACJ,OAAO,EAAE,EAAE;KACd;CACJ,CAAC,CAAC,CAAC;AAIJ,MAAM,OAAO,GAAG,KAAK,EAAE,IAAU,EAAE,MAAe,EAAiB,EAAE;IACjE,MAAM,MAAM,GAAuC,MAAM,OAAO,CAAC,GAAG,CAAC;QACjE,IAAI,CAAC,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,cAAc,EAAE,aAAa,EAAE,KAAK,CAAC,CAAC;KAC9E,CAAC,CAAC;IACH,KAAK,MAAM,KAAK,IAAI,MAAM;QAAE,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC;AACpD,CAAC,CAAC;AAEF,eAAe,KAAK,EAAE,IAAU,EAAiB,EAAE,CAC/C,OAAO,CAAC,IAAI,EAAE;IACV,eAAe,EAAE;QACb,OAAO,EAAE;YACL,GAAG,EAAE;gBACD,SAAS,EAAE;oBACP,IAAI,EAAE;wBACF,6BAA6B;wBAC7B,wCAAwC;wBACxC,+CAA+C;qBAClD;iBACJ;aACJ;SACJ;KACJ;CACJ,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,MAAM,EAAC,MAAM,oBAAoB,CAAC;AAE1C,MAAM,aAAa,GAAG,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACnC,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG;IACpB,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;QAC1B,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;KACjC,CAAC;IACF,QAAQ,EAAE,CAAC,kBAAkB,CAAC;IAC9B,MAAM,EAAE;QACJ,OAAO,EAAE,EAAE;KACd;CACJ,CAAC,CAAC,CAAC;AAIJ,MAAM,OAAO,GAAG,KAAK,EAAE,IAAU,EAAE,MAAe,EAAiB,EAAE;IACjE,MAAM,SAAS,GAAuC,MAAM,OAAO,CAAC,GAAG,CAAC;QACpE,IAAI,CAAC,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,cAAc,EAAE,aAAa,EAAE,KAAK,CAAC,CAAC;KAC9E,CAAC,CAAC;IACH,KAAK,MAAM,QAAQ,IAAI,SAAS;QAAE,MAAM,QAAQ,CAAC,KAAK,EAAE,CAAC;AAC7D,CAAC,CAAC;AAEF,eAAe,KAAK,EAAE,IAAU,EAAiB,EAAE,CAC/C,OAAO,CAAC,IAAI,EAAE;IACV,eAAe,EAAE;QACb,OAAO,EAAE;YACL,GAAG,EAAE;gBACD,SAAS,EAAE;oBACP,IAAI,EAAE;wBACF,6BAA6B;wBAC7B,wCAAwC;wBACxC,+CAA+C;qBAClD;iBACJ;aACJ;SACJ;KACJ;CACJ,CAAC,CAAC"}
@@ -1,5 +1,7 @@
1
1
  declare const _default: import("@feasibleone/blong").IAdapterFactory<{
2
2
  logLevel: "info";
3
- }, import("@feasibleone/blong").ServerContext>;
3
+ }, import("@feasibleone/blong").AdapterContext> & {
4
+ [x: symbol]: "orchestrator";
5
+ };
4
6
  export default _default;
5
7
  //# sourceMappingURL=openapi.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"openapi.d.ts","sourceRoot":"","sources":["../../orchestrator/openapi.ts"],"names":[],"mappings":";;;AAEA,wBAOI"}
1
+ {"version":3,"file":"openapi.d.ts","sourceRoot":"","sources":["../../orchestrator/openapi.ts"],"names":[],"mappings":";;;;;AAEA,wBAOI"}
package/dist/package.json CHANGED
@@ -1,9 +1,10 @@
1
1
  {
2
2
  "name": "@feasibleone/blong-openapi",
3
- "scripts": {
4
- "build": "heft build --clean",
5
- "ci-publish": "node ../../common/scripts/install-run-rush-pnpm.js publish --access public --provenance"
3
+ "version": "1.2.0",
4
+ "repository": {
5
+ "url": "git+https://github.com/feasibleone/blong.git"
6
6
  },
7
+ "type": "module",
7
8
  "exports": {
8
9
  "./server.js": "./dist/server.js",
9
10
  "./server.d.ts": "./dist/server.d.ts",
@@ -14,20 +15,19 @@
14
15
  "./dist/package.json": "./package.json",
15
16
  "./package.json": "./package.json"
16
17
  },
17
- "repository": {
18
- "url": "git+https://github.com/feasibleone/blong.git"
18
+ "scripts": {
19
+ "build": "heft build --clean",
20
+ "ci-lint": "blong-dev lint",
21
+ "ci-publish": "node ../../common/scripts/install-run-rush-pnpm.js publish --access public --provenance"
19
22
  },
20
- "type": "module",
21
- "version": "1.1.3",
22
23
  "dependencies": {
23
24
  "@feasibleone/blong": "workspace:^1.0.0"
24
25
  },
25
26
  "devDependencies": {
26
- "@rushstack/eslint-config": "^4.6.4",
27
+ "@feasibleone/blong-dev": "workspace:*",
27
28
  "@rushstack/heft": "^1.2.6",
28
29
  "@rushstack/heft-lint-plugin": "^1.2.6",
29
30
  "@rushstack/heft-typescript-plugin": "^1.3.1",
30
- "eslint": "~9.39.2",
31
31
  "typescript": "^5.9.3"
32
32
  }
33
33
  }
package/dist/server.d.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  declare const _default: import("@feasibleone/blong").SolutionFactory<import("typebox").TObject<{
2
2
  openapi: import("typebox").TObject<{}>;
3
- }>>;
3
+ }>> & {
4
+ [x: symbol]: "solution";
5
+ };
4
6
  export default _default;
5
7
  //# sourceMappingURL=server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../server.ts"],"names":[],"mappings":";;;AAEA,wBAiBI"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../server.ts"],"names":[],"mappings":";;;;;AAEA,wBAiBI"}
package/package.json CHANGED
@@ -1,5 +1,10 @@
1
1
  {
2
2
  "name": "@feasibleone/blong-openapi",
3
+ "version": "1.2.0",
4
+ "repository": {
5
+ "url": "git+https://github.com/feasibleone/blong.git"
6
+ },
7
+ "type": "module",
3
8
  "exports": {
4
9
  "./server.js": "./dist/server.js",
5
10
  "./server.d.ts": "./dist/server.d.ts",
@@ -10,24 +15,19 @@
10
15
  "./dist/package.json": "./package.json",
11
16
  "./package.json": "./package.json"
12
17
  },
13
- "repository": {
14
- "url": "git+https://github.com/feasibleone/blong.git"
15
- },
16
- "type": "module",
17
- "version": "1.1.3",
18
18
  "dependencies": {
19
19
  "@feasibleone/blong": "^1.0.0"
20
20
  },
21
21
  "devDependencies": {
22
- "@rushstack/eslint-config": "^4.6.4",
23
22
  "@rushstack/heft": "^1.2.6",
24
23
  "@rushstack/heft-lint-plugin": "^1.2.6",
25
24
  "@rushstack/heft-typescript-plugin": "^1.3.1",
26
- "eslint": "~9.39.2",
27
- "typescript": "^5.9.3"
25
+ "typescript": "^5.9.3",
26
+ "@feasibleone/blong-dev": "1.0.0"
28
27
  },
29
28
  "scripts": {
30
29
  "build": "heft build --clean",
30
+ "ci-lint": "blong-dev lint",
31
31
  "ci-publish": "node ../../common/scripts/install-run-rush-pnpm.js publish --access public --provenance"
32
32
  }
33
33
  }