@thymian/plugin-openapi 0.0.0-PLACEHOLDER
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 +59 -0
- package/dist/cli/commands/openapi/info.d.ts +11 -0
- package/dist/cli/commands/openapi/info.d.ts.map +1 -0
- package/dist/cli/commands/openapi/info.js +36 -0
- package/dist/cli/commands/openapi/info.js.map +1 -0
- package/dist/cli/commands/openapi/load.d.ts +11 -0
- package/dist/cli/commands/openapi/load.d.ts.map +1 -0
- package/dist/cli/commands/openapi/load.js +33 -0
- package/dist/cli/commands/openapi/load.js.map +1 -0
- package/dist/cli/commands/openapi/validate.d.ts +11 -0
- package/dist/cli/commands/openapi/validate.d.ts.map +1 -0
- package/dist/cli/commands/openapi/validate.js +29 -0
- package/dist/cli/commands/openapi/validate.js.map +1 -0
- package/dist/cli/spec-search-hook.d.ts +4 -0
- package/dist/cli/spec-search-hook.d.ts.map +1 -0
- package/dist/cli/spec-search-hook.js +11 -0
- package/dist/cli/spec-search-hook.js.map +1 -0
- package/dist/error.d.ts +4 -0
- package/dist/error.d.ts.map +1 -0
- package/dist/error.js +4 -0
- package/dist/error.js.map +1 -0
- package/dist/http-filter-expression-to-operation-filter.d.ts +14 -0
- package/dist/http-filter-expression-to-operation-filter.d.ts.map +1 -0
- package/dist/http-filter-expression-to-operation-filter.js +221 -0
- package/dist/http-filter-expression-to-operation-filter.js.map +1 -0
- package/dist/index.d.ts +44 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +63 -0
- package/dist/index.js.map +1 -0
- package/dist/load-openapi.d.ts +31 -0
- package/dist/load-openapi.d.ts.map +1 -0
- package/dist/load-openapi.js +159 -0
- package/dist/load-openapi.js.map +1 -0
- package/dist/loc-mapper/json-loc-mapper.d.ts +15 -0
- package/dist/loc-mapper/json-loc-mapper.d.ts.map +1 -0
- package/dist/loc-mapper/json-loc-mapper.js +105 -0
- package/dist/loc-mapper/json-loc-mapper.js.map +1 -0
- package/dist/loc-mapper/loc-mapper-for-file.d.ts +4 -0
- package/dist/loc-mapper/loc-mapper-for-file.d.ts.map +1 -0
- package/dist/loc-mapper/loc-mapper-for-file.js +20 -0
- package/dist/loc-mapper/loc-mapper-for-file.js.map +1 -0
- package/dist/loc-mapper/loc-mapper.d.ts +9 -0
- package/dist/loc-mapper/loc-mapper.d.ts.map +1 -0
- package/dist/loc-mapper/loc-mapper.js +22 -0
- package/dist/loc-mapper/loc-mapper.js.map +1 -0
- package/dist/loc-mapper/noop-loc-mapper.d.ts +6 -0
- package/dist/loc-mapper/noop-loc-mapper.d.ts.map +1 -0
- package/dist/loc-mapper/noop-loc-mapper.js +10 -0
- package/dist/loc-mapper/noop-loc-mapper.js.map +1 -0
- package/dist/loc-mapper/yaml-loc-mapper.d.ts +13 -0
- package/dist/loc-mapper/yaml-loc-mapper.d.ts.map +1 -0
- package/dist/loc-mapper/yaml-loc-mapper.js +105 -0
- package/dist/loc-mapper/yaml-loc-mapper.js.map +1 -0
- package/dist/processors/extract-server-info.d.ts +10 -0
- package/dist/processors/extract-server-info.d.ts.map +1 -0
- package/dist/processors/extract-server-info.js +40 -0
- package/dist/processors/extract-server-info.js.map +1 -0
- package/dist/processors/headers-object.processor.d.ts +4 -0
- package/dist/processors/headers-object.processor.d.ts.map +1 -0
- package/dist/processors/headers-object.processor.js +20 -0
- package/dist/processors/headers-object.processor.js.map +1 -0
- package/dist/processors/json-schema.processor.d.ts +19 -0
- package/dist/processors/json-schema.processor.d.ts.map +1 -0
- package/dist/processors/json-schema.processor.js +40 -0
- package/dist/processors/json-schema.processor.js.map +1 -0
- package/dist/processors/link-object.processor.d.ts +5 -0
- package/dist/processors/link-object.processor.d.ts.map +1 -0
- package/dist/processors/link-object.processor.js +58 -0
- package/dist/processors/link-object.processor.js.map +1 -0
- package/dist/processors/media-type-object.processor.d.ts +9 -0
- package/dist/processors/media-type-object.processor.d.ts.map +1 -0
- package/dist/processors/media-type-object.processor.js +43 -0
- package/dist/processors/media-type-object.processor.js.map +1 -0
- package/dist/processors/openapi.processor.d.ts +27 -0
- package/dist/processors/openapi.processor.d.ts.map +1 -0
- package/dist/processors/openapi.processor.js +166 -0
- package/dist/processors/openapi.processor.js.map +1 -0
- package/dist/processors/parameter-object.processor.d.ts +6 -0
- package/dist/processors/parameter-object.processor.d.ts.map +1 -0
- package/dist/processors/parameter-object.processor.js +90 -0
- package/dist/processors/parameter-object.processor.js.map +1 -0
- package/dist/processors/request-body-object.processor.d.ts +14 -0
- package/dist/processors/request-body-object.processor.d.ts.map +1 -0
- package/dist/processors/request-body-object.processor.js +61 -0
- package/dist/processors/request-body-object.processor.js.map +1 -0
- package/dist/processors/response-object.processor.d.ts +12 -0
- package/dist/processors/response-object.processor.d.ts.map +1 -0
- package/dist/processors/response-object.processor.js +44 -0
- package/dist/processors/response-object.processor.js.map +1 -0
- package/dist/processors/responses-object.processor.d.ts +5 -0
- package/dist/processors/responses-object.processor.d.ts.map +1 -0
- package/dist/processors/responses-object.processor.js +27 -0
- package/dist/processors/responses-object.processor.js.map +1 -0
- package/dist/processors/runtime-expression.processor.d.ts +4 -0
- package/dist/processors/runtime-expression.processor.d.ts.map +1 -0
- package/dist/processors/runtime-expression.processor.js +24 -0
- package/dist/processors/runtime-expression.processor.js.map +1 -0
- package/dist/processors/security-scheme-object.processor.d.ts +4 -0
- package/dist/processors/security-scheme-object.processor.d.ts.map +1 -0
- package/dist/processors/security-scheme-object.processor.js +50 -0
- package/dist/processors/security-scheme-object.processor.js.map +1 -0
- package/dist/processors/utils.d.ts +9 -0
- package/dist/processors/utils.d.ts.map +1 -0
- package/dist/processors/utils.js +21 -0
- package/dist/processors/utils.js.map +1 -0
- package/dist/runtime-expression.d.ts +8 -0
- package/dist/runtime-expression.d.ts.map +1 -0
- package/dist/runtime-expression.js +2 -0
- package/dist/runtime-expression.js.map +1 -0
- package/dist/search-for-openapi-files.d.ts +8 -0
- package/dist/search-for-openapi-files.d.ts.map +1 -0
- package/dist/search-for-openapi-files.js +44 -0
- package/dist/search-for-openapi-files.js.map +1 -0
- package/package.json +61 -0
package/README.md
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
<!-- HEADER:START - Do not remove or modify this section -->
|
|
2
|
+
<div align="center">
|
|
3
|
+
<img src="https://raw.githubusercontent.com/thymianofficial/thymian/main/astro-docs/src/assets/logo.svg" alt="Thymian Logo" width="200"/>
|
|
4
|
+
|
|
5
|
+
# Thymian
|
|
6
|
+
|
|
7
|
+
**Add resilience and HTTP conformance to your API development workflow**
|
|
8
|
+
|
|
9
|
+
[](https://github.com/thymianofficial/thymian/blob/main/LICENSE)
|
|
10
|
+
[](https://github.com/thymianofficial/thymian/actions/workflows/ci.yaml)
|
|
11
|
+
[](https://thymian.dev)
|
|
12
|
+
[](https://discord.gg/TRSwCxbz9f)
|
|
13
|
+
[](https://www.reddit.com/r/ThymianOfficial/)
|
|
14
|
+
[](https://x.com/thymiandev)
|
|
15
|
+
|
|
16
|
+
</div>
|
|
17
|
+
<!-- HEADER:END -->
|
|
18
|
+
|
|
19
|
+
## @thymian/plugin-openapi
|
|
20
|
+
|
|
21
|
+
Parses OpenAPI specification documents and converts them into Thymian's internal format for analysis. Supports OpenAPI 3.x documents in YAML or JSON, resolving `$ref` references and extracting HTTP endpoints for conformance validation.
|
|
22
|
+
|
|
23
|
+
## Installation
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install @thymian/plugin-openapi
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
> **Getting started with Thymian?** See the [main Thymian package](https://www.npmjs.com/package/thymian) for quick installation and first-run instructions.
|
|
30
|
+
|
|
31
|
+
<!-- FOOTER:START - Do not remove or modify this section -->
|
|
32
|
+
|
|
33
|
+
## 📚 Documentation
|
|
34
|
+
|
|
35
|
+
- **[Getting Started](https://thymian.dev/introduction/getting-started)** - Set up Thymian in minutes
|
|
36
|
+
- **[Documentation](https://thymian.dev)** - Comprehensive guides and API reference
|
|
37
|
+
- **[CLI Reference](https://thymian.dev/references/cli)** - Complete CLI command documentation
|
|
38
|
+
- **[HTTP Rules](https://thymian.dev/guides/http-rules/how-to-use-rules)** - Learn about HTTP conformance validation
|
|
39
|
+
|
|
40
|
+
## 🏢 Enterprise Support
|
|
41
|
+
|
|
42
|
+
Get professional consulting and dedicated support from the creators of Thymian. We offer:
|
|
43
|
+
|
|
44
|
+
- API design and governance strategies
|
|
45
|
+
- HTTP standards compliance auditing
|
|
46
|
+
- Custom plugin development
|
|
47
|
+
- Custom rule development
|
|
48
|
+
- Team training and workshops
|
|
49
|
+
|
|
50
|
+
**[Learn more about Enterprise Support](https://thymian.dev/enterprise)** | **Email: [support@thymian.dev](mailto:support@thymian.dev)**
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
<div align="center">
|
|
55
|
+
|
|
56
|
+
**Shipped with 🌱 by [qupaya](https://qupaya.com)**
|
|
57
|
+
|
|
58
|
+
</div>
|
|
59
|
+
<!-- FOOTER:END -->
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { BaseCliRunCommand } from '@thymian/common-cli';
|
|
2
|
+
export default class Info extends BaseCliRunCommand<typeof Info> {
|
|
3
|
+
static requiresSpecifications: boolean;
|
|
4
|
+
static args: {
|
|
5
|
+
content: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
6
|
+
};
|
|
7
|
+
static description: string;
|
|
8
|
+
static examples: string[];
|
|
9
|
+
run(): Promise<void>;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=info.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"info.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/openapi/info.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAMxD,MAAM,CAAC,OAAO,OAAO,IAAK,SAAQ,iBAAiB,CAAC,OAAO,IAAI,CAAC;IAC9D,OAAgB,sBAAsB,UAAS;IAE/C,OAAgB,IAAI;;MAMlB;IACF,OAAgB,WAAW,SAC8C;IACzE,OAAgB,QAAQ,WAEtB;IAEa,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAmBpC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { validate } from '@scalar/openapi-parser';
|
|
2
|
+
import { BaseCliRunCommand } from '@thymian/common-cli';
|
|
3
|
+
import { Args } from '@thymian/common-cli/oclif';
|
|
4
|
+
import { ThymianBaseError } from '@thymian/core';
|
|
5
|
+
import { loadOpenApi } from '../../../load-openapi.js';
|
|
6
|
+
export default class Info extends BaseCliRunCommand {
|
|
7
|
+
static requiresSpecifications = false;
|
|
8
|
+
static args = {
|
|
9
|
+
content: Args.string({
|
|
10
|
+
description: 'file to read',
|
|
11
|
+
required: true,
|
|
12
|
+
ignoreStdin: false,
|
|
13
|
+
}),
|
|
14
|
+
};
|
|
15
|
+
static description = 'Load and parse the given Swagger/OpenAPI file to the Thymian format.';
|
|
16
|
+
static examples = [
|
|
17
|
+
'<%= config.bin %> <%= command.id %> openapi.yaml',
|
|
18
|
+
];
|
|
19
|
+
async run() {
|
|
20
|
+
const { document } = await loadOpenApi(this.args.content, this.flags.cwd);
|
|
21
|
+
const { valid, version, specification } = await validate(document);
|
|
22
|
+
if (!valid || !specification) {
|
|
23
|
+
throw new ThymianBaseError('Invalid OpenAPI document.', {
|
|
24
|
+
name: 'InvalidOpenAPIDocumentError',
|
|
25
|
+
ref: 'https://thymian.dev/references/errors/invalid-openapi-document-error/',
|
|
26
|
+
suggestions: [
|
|
27
|
+
'Use thymian openapi:validate to validate your OpenAPI document.',
|
|
28
|
+
],
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
this.log(`OpenAPI version: ${version}`);
|
|
32
|
+
this.log(`API Title: ${specification.info.title}`);
|
|
33
|
+
this.log(`API Version: ${specification.info.version}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=info.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"info.js","sourceRoot":"","sources":["../../../../src/cli/commands/openapi/info.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,IAAI,EAAE,MAAM,2BAA2B,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEjD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAEvD,MAAM,CAAC,OAAO,OAAO,IAAK,SAAQ,iBAA8B;IAC9D,MAAM,CAAU,sBAAsB,GAAG,KAAK,CAAC;IAE/C,MAAM,CAAU,IAAI,GAAG;QACrB,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC;YACnB,WAAW,EAAE,cAAc;YAC3B,QAAQ,EAAE,IAAI;YACd,WAAW,EAAE,KAAK;SACnB,CAAC;KACH,CAAC;IACF,MAAM,CAAU,WAAW,GACzB,sEAAsE,CAAC;IACzE,MAAM,CAAU,QAAQ,GAAG;QACzB,kDAAkD;KACnD,CAAC;IAEO,KAAK,CAAC,GAAG;QAChB,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAE1E,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAEnE,IAAI,CAAC,KAAK,IAAI,CAAC,aAAa,EAAE,CAAC;YAC7B,MAAM,IAAI,gBAAgB,CAAC,2BAA2B,EAAE;gBACtD,IAAI,EAAE,6BAA6B;gBACnC,GAAG,EAAE,uEAAuE;gBAC5E,WAAW,EAAE;oBACX,iEAAiE;iBAClE;aACF,CAAC,CAAC;QACL,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,oBAAoB,OAAO,EAAE,CAAC,CAAC;QACxC,IAAI,CAAC,GAAG,CAAC,cAAc,aAAa,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QACnD,IAAI,CAAC,GAAG,CAAC,gBAAgB,aAAa,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;IACzD,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { BaseCliRunCommand } from '@thymian/common-cli';
|
|
2
|
+
export default class Load extends BaseCliRunCommand<typeof Load> {
|
|
3
|
+
static requiresSpecifications: boolean;
|
|
4
|
+
static args: {
|
|
5
|
+
content: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
6
|
+
};
|
|
7
|
+
static description: string;
|
|
8
|
+
static examples: string[];
|
|
9
|
+
run(): Promise<void>;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=load.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/openapi/load.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAMxD,MAAM,CAAC,OAAO,OAAO,IAAK,SAAQ,iBAAiB,CAAC,OAAO,IAAI,CAAC;IAC9D,OAAgB,sBAAsB,UAAS;IAE/C,OAAgB,IAAI;;MAMlB;IACF,OAAgB,WAAW,SAC8C;IACzE,OAAgB,QAAQ,WAEtB;IAEa,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAepC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { BaseCliRunCommand } from '@thymian/common-cli';
|
|
2
|
+
import { Args } from '@thymian/common-cli/oclif';
|
|
3
|
+
import { constant } from '@thymian/core';
|
|
4
|
+
import { loadAndTransform } from '../../../load-openapi.js';
|
|
5
|
+
export default class Load extends BaseCliRunCommand {
|
|
6
|
+
static requiresSpecifications = false;
|
|
7
|
+
static args = {
|
|
8
|
+
content: Args.string({
|
|
9
|
+
description: 'file to read',
|
|
10
|
+
required: true,
|
|
11
|
+
ignoreStdin: false,
|
|
12
|
+
}),
|
|
13
|
+
};
|
|
14
|
+
static description = 'Load and parse the given Swagger/OpenAPI file to the Thymian format.';
|
|
15
|
+
static examples = [
|
|
16
|
+
'<%= config.bin %> <%= command.id %> openapi.yaml',
|
|
17
|
+
];
|
|
18
|
+
async run() {
|
|
19
|
+
const [, format] = await loadAndTransform(this.args.content, {
|
|
20
|
+
filter: constant(true),
|
|
21
|
+
cwd: this.flags.cwd,
|
|
22
|
+
logger: this.logger,
|
|
23
|
+
serverInfo: {
|
|
24
|
+
port: 8080,
|
|
25
|
+
host: 'localhost',
|
|
26
|
+
protocol: 'http',
|
|
27
|
+
basePath: '',
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
this.log(JSON.stringify(format.export()));
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=load.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load.js","sourceRoot":"","sources":["../../../../src/cli/commands/openapi/load.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,IAAI,EAAE,MAAM,2BAA2B,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAE5D,MAAM,CAAC,OAAO,OAAO,IAAK,SAAQ,iBAA8B;IAC9D,MAAM,CAAU,sBAAsB,GAAG,KAAK,CAAC;IAE/C,MAAM,CAAU,IAAI,GAAG;QACrB,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC;YACnB,WAAW,EAAE,cAAc;YAC3B,QAAQ,EAAE,IAAI;YACd,WAAW,EAAE,KAAK;SACnB,CAAC;KACH,CAAC;IACF,MAAM,CAAU,WAAW,GACzB,sEAAsE,CAAC;IACzE,MAAM,CAAU,QAAQ,GAAG;QACzB,kDAAkD;KACnD,CAAC;IAEO,KAAK,CAAC,GAAG;QAChB,MAAM,CAAC,EAAE,MAAM,CAAC,GAAG,MAAM,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;YAC3D,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC;YACtB,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG;YACnB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,UAAU,EAAE;gBACV,IAAI,EAAE,IAAI;gBACV,IAAI,EAAE,WAAW;gBACjB,QAAQ,EAAE,MAAM;gBAChB,QAAQ,EAAE,EAAE;aACb;SACF,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC5C,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { BaseCliRunCommand } from '@thymian/common-cli';
|
|
2
|
+
export default class Validate extends BaseCliRunCommand<typeof Validate> {
|
|
3
|
+
static requiresSpecifications: boolean;
|
|
4
|
+
static args: {
|
|
5
|
+
file: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
6
|
+
};
|
|
7
|
+
static description: string;
|
|
8
|
+
static examples: string[];
|
|
9
|
+
run(): Promise<void>;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=validate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/openapi/validate.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAGxD,MAAM,CAAC,OAAO,OAAO,QAAS,SAAQ,iBAAiB,CAAC,OAAO,QAAQ,CAAC;IACtE,OAAgB,sBAAsB,UAAS;IAE/C,OAAgB,IAAI;;MAElB;IACF,OAAgB,WAAW,SAC8C;IACzE,OAAgB,QAAQ,WAEtB;IAEa,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAqBpC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { load, validate } from '@scalar/openapi-parser';
|
|
2
|
+
import { readFiles } from '@scalar/openapi-parser/plugins/read-files';
|
|
3
|
+
import { BaseCliRunCommand } from '@thymian/common-cli';
|
|
4
|
+
import { Args } from '@thymian/common-cli/oclif';
|
|
5
|
+
export default class Validate extends BaseCliRunCommand {
|
|
6
|
+
static requiresSpecifications = false;
|
|
7
|
+
static args = {
|
|
8
|
+
file: Args.string({ description: 'file to read', required: true }),
|
|
9
|
+
};
|
|
10
|
+
static description = 'Load and parse the given Swagger/OpenAPI file to the Thymian format.';
|
|
11
|
+
static examples = [
|
|
12
|
+
'<%= config.bin %> <%= command.id %> openapi.yaml',
|
|
13
|
+
];
|
|
14
|
+
async run() {
|
|
15
|
+
const filesystem = (await load(this.args.file, { plugins: [readFiles()], throwOnError: true })).filesystem;
|
|
16
|
+
const result = await validate(filesystem);
|
|
17
|
+
if (!result.valid) {
|
|
18
|
+
if (result.errors) {
|
|
19
|
+
this.log('\u274C Invalid Swagger/OpenAPI file with errors:');
|
|
20
|
+
console.group();
|
|
21
|
+
result.errors.forEach((e) => this.log(`* ${e.message}${'path' in e ? ` (at "${e.path}")` : ''}`));
|
|
22
|
+
console.groupEnd();
|
|
23
|
+
}
|
|
24
|
+
this.exit(1);
|
|
25
|
+
}
|
|
26
|
+
this.log('\u2705 Valid Swagger/OpenAPI file.');
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../../src/cli/commands/openapi/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,2CAA2C,CAAC;AACtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,IAAI,EAAE,MAAM,2BAA2B,CAAC;AAEjD,MAAM,CAAC,OAAO,OAAO,QAAS,SAAQ,iBAAkC;IACtE,MAAM,CAAU,sBAAsB,GAAG,KAAK,CAAC;IAE/C,MAAM,CAAU,IAAI,GAAG;QACrB,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,cAAc,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;KACnE,CAAC;IACF,MAAM,CAAU,WAAW,GACzB,sEAAsE,CAAC;IACzE,MAAM,CAAU,QAAQ,GAAG;QACzB,kDAAkD;KACnD,CAAC;IAEO,KAAK,CAAC,GAAG;QAChB,MAAM,UAAU,GAAG,CACjB,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC,SAAS,EAAE,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAC3E,CAAC,UAAU,CAAC;QAEb,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,UAAU,CAAC,CAAC;QAE1C,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YAClB,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;gBAClB,IAAI,CAAC,GAAG,CAAC,kDAAkD,CAAC,CAAC;gBAC7D,OAAO,CAAC,KAAK,EAAE,CAAC;gBAChB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAC1B,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,GAAG,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CACpE,CAAC;gBACF,OAAO,CAAC,QAAQ,EAAE,CAAC;YACrB,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACf,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;IACjD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec-search-hook.d.ts","sourceRoot":"","sources":["../../src/cli/spec-search-hook.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAKjE,QAAA,MAAM,IAAI,EAAE,qBAOX,CAAC;AAEF,eAAe,IAAI,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { openApiPlugin } from '../index.js';
|
|
2
|
+
import { searchForOpenApiFiles } from '../search-for-openapi-files.js';
|
|
3
|
+
const hook = async function (opts) {
|
|
4
|
+
const files = await searchForOpenApiFiles(opts.cwd);
|
|
5
|
+
return {
|
|
6
|
+
pluginName: openApiPlugin.name,
|
|
7
|
+
specifications: files.map((file) => ({ type: 'openapi', location: file })),
|
|
8
|
+
};
|
|
9
|
+
};
|
|
10
|
+
export default hook;
|
|
11
|
+
//# sourceMappingURL=spec-search-hook.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec-search-hook.js","sourceRoot":"","sources":["../../src/cli/spec-search-hook.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAEvE,MAAM,IAAI,GAA0B,KAAK,WAAW,IAAI;IACtD,MAAM,KAAK,GAAG,MAAM,qBAAqB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAEpD,OAAO;QACL,UAAU,EAAE,aAAa,CAAC,IAAI;QAC9B,cAAc,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;KAC3E,CAAC;AACJ,CAAC,CAAC;AAEF,eAAe,IAAI,CAAC"}
|
package/dist/error.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEjD,qBAAa,YAAa,SAAQ,gBAAgB;CAAG"}
|
package/dist/error.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error.js","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEjD,MAAM,OAAO,YAAa,SAAQ,gBAAgB;CAAG"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { HttpFilterExpression } from '@thymian/core';
|
|
2
|
+
import type { OpenAPIV3_1 as OpenApiV31 } from 'openapi-types';
|
|
3
|
+
import type { ServerInfo } from './processors/extract-server-info.js';
|
|
4
|
+
import type { Parameters } from './processors/utils.js';
|
|
5
|
+
export type OperationObjectFilterFn = (args: {
|
|
6
|
+
operationObject: OpenApiV31.OperationObject;
|
|
7
|
+
params: Parameters;
|
|
8
|
+
method: string;
|
|
9
|
+
path: string;
|
|
10
|
+
serverInfo: ServerInfo;
|
|
11
|
+
document: OpenApiV31.Document;
|
|
12
|
+
}) => boolean;
|
|
13
|
+
export declare function httpFilterExpressionToOperationFilter(expression: HttpFilterExpression): OperationObjectFilterFn;
|
|
14
|
+
//# sourceMappingURL=http-filter-expression-to-operation-filter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-filter-expression-to-operation-filter.d.ts","sourceRoot":"","sources":["../src/http-filter-expression-to-operation-filter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAM1D,OAAO,KAAK,EAAE,WAAW,IAAI,UAAU,EAAE,MAAM,eAAe,CAAC;AAE/D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qCAAqC,CAAC;AACtE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAExD,MAAM,MAAM,uBAAuB,GAAG,CAAC,IAAI,EAAE;IAC3C,eAAe,EAAE,UAAU,CAAC,eAAe,CAAC;IAC5C,MAAM,EAAE,UAAU,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,UAAU,CAAC;IACvB,QAAQ,EAAE,UAAU,CAAC,QAAQ,CAAC;CAC/B,KAAK,OAAO,CAAC;AAyRd,wBAAgB,qCAAqC,CACnD,UAAU,EAAE,oBAAoB,GAC/B,uBAAuB,CAEzB"}
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
import { createFilterVisitor, equalsIgnoreCase, visitHttpFilter, } from '@thymian/core';
|
|
2
|
+
function joinUrls(baseUrl, path) {
|
|
3
|
+
return (baseUrl + path).replace(/\/\//g, '/');
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Helper to check if params contain a specific query parameter
|
|
7
|
+
*/
|
|
8
|
+
function hasQueryParam(params, param) {
|
|
9
|
+
return Object.keys(params.queryParameters).some((p) => equalsIgnoreCase(p, param));
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Helper to check if params contain a specific request header
|
|
13
|
+
*/
|
|
14
|
+
function hasRequestHeader(params, header) {
|
|
15
|
+
return Object.keys(params.headers).some((h) => equalsIgnoreCase(h, header));
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Helper to check if operation has response with specific status code
|
|
19
|
+
*/
|
|
20
|
+
function hasResponseWithStatusCode(operationObject, code) {
|
|
21
|
+
if (!operationObject.responses) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
return Object.keys(operationObject.responses).some((statusCode) => {
|
|
25
|
+
// Handle 'default' or numeric status codes
|
|
26
|
+
if (statusCode === 'default') {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
return parseInt(statusCode, 10) === code;
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Helper to check if operation has response in status code range
|
|
34
|
+
*/
|
|
35
|
+
function hasResponseInStatusCodeRange(operationObject, start, end) {
|
|
36
|
+
if (!operationObject.responses) {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
return Object.keys(operationObject.responses).some((statusCode) => {
|
|
40
|
+
if (statusCode === 'default') {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
const code = parseInt(statusCode, 10);
|
|
44
|
+
return Number.isInteger(code) && code >= start && code <= end;
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Helper to check if operation has request body
|
|
49
|
+
*/
|
|
50
|
+
function hasRequestBody(operationObject) {
|
|
51
|
+
return !!operationObject.requestBody;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Helper to check if operation has request with specific media type
|
|
55
|
+
*/
|
|
56
|
+
function hasRequestMediaType(operationObject, mediaType) {
|
|
57
|
+
if (!operationObject.requestBody) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
if ('$ref' in operationObject.requestBody) {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
const content = operationObject.requestBody.content;
|
|
64
|
+
if (!content) {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
return Object.keys(content).some((mt) => equalsIgnoreCase(mt, mediaType));
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Helper to check if operation has response with specific media type
|
|
71
|
+
*/
|
|
72
|
+
function hasResponseMediaType(operationObject, mediaType) {
|
|
73
|
+
if (!operationObject.responses) {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
return Object.values(operationObject.responses).some((response) => {
|
|
77
|
+
if ('$ref' in response) {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
if (!response.content) {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
return Object.keys(response.content).some((mt) => equalsIgnoreCase(mt, mediaType));
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Helper to check if operation has response header
|
|
88
|
+
*/
|
|
89
|
+
function hasResponseHeader(operationObject, header) {
|
|
90
|
+
if (!operationObject.responses) {
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
return Object.values(operationObject.responses).some((response) => {
|
|
94
|
+
if ('$ref' in response) {
|
|
95
|
+
return false;
|
|
96
|
+
}
|
|
97
|
+
if (!response.headers) {
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
return Object.keys(response.headers).some((h) => equalsIgnoreCase(h, header));
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Helper to check if operation has response body
|
|
105
|
+
*/
|
|
106
|
+
function hasResponseBody(operationObject) {
|
|
107
|
+
if (!operationObject.responses) {
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
return Object.values(operationObject.responses).some((response) => {
|
|
111
|
+
if ('$ref' in response) {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
return !!response.content && Object.keys(response.content).length > 0;
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Helper to check if operation is secured (has security requirement)
|
|
119
|
+
*/
|
|
120
|
+
function isOperationSecured(operationObject, document) {
|
|
121
|
+
// Check operation-level security
|
|
122
|
+
if (operationObject.security) {
|
|
123
|
+
return operationObject.security.length > 0;
|
|
124
|
+
}
|
|
125
|
+
// Check document-level security
|
|
126
|
+
if (document.security) {
|
|
127
|
+
return document.security.length > 0;
|
|
128
|
+
}
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
const visitor = createFilterVisitor({
|
|
132
|
+
visitMethod({ method }) {
|
|
133
|
+
if (typeof method === 'undefined') {
|
|
134
|
+
return () => false;
|
|
135
|
+
}
|
|
136
|
+
return ({ method: m }) => equalsIgnoreCase(m, method);
|
|
137
|
+
},
|
|
138
|
+
visitRequestHeader({ header }) {
|
|
139
|
+
if (typeof header === 'undefined') {
|
|
140
|
+
return () => false;
|
|
141
|
+
}
|
|
142
|
+
return ({ params }) => hasRequestHeader(params, header);
|
|
143
|
+
},
|
|
144
|
+
visitQueryParam({ param }) {
|
|
145
|
+
if (typeof param === 'undefined') {
|
|
146
|
+
return () => false;
|
|
147
|
+
}
|
|
148
|
+
return ({ params }) => hasQueryParam(params, param);
|
|
149
|
+
},
|
|
150
|
+
visitPath({ path }) {
|
|
151
|
+
if (typeof path === 'undefined') {
|
|
152
|
+
return () => false;
|
|
153
|
+
}
|
|
154
|
+
return ({ path: p, serverInfo }) => joinUrls(serverInfo.basePath, p).endsWith(path);
|
|
155
|
+
},
|
|
156
|
+
visitHasResponse({ filter }) {
|
|
157
|
+
const nestedFilter = httpFilterExpressionToOperationFilter(filter);
|
|
158
|
+
return (args) => nestedFilter(args);
|
|
159
|
+
},
|
|
160
|
+
visitIsAuthorized({ isAuthorized }) {
|
|
161
|
+
return ({ operationObject, document }) => isOperationSecured(operationObject, document) === isAuthorized;
|
|
162
|
+
},
|
|
163
|
+
visitOrigin({ origin }) {
|
|
164
|
+
return ({ serverInfo }) => {
|
|
165
|
+
return (`${serverInfo.protocol}://${serverInfo.host}:${serverInfo.port}` ===
|
|
166
|
+
origin);
|
|
167
|
+
};
|
|
168
|
+
},
|
|
169
|
+
visitHasBody({ hasBody }) {
|
|
170
|
+
return ({ operationObject }) => hasRequestBody(operationObject) === hasBody;
|
|
171
|
+
},
|
|
172
|
+
visitPort({ port }) {
|
|
173
|
+
return ({ serverInfo }) => serverInfo.port === port;
|
|
174
|
+
},
|
|
175
|
+
visitRequestMediaType({ mediaType }) {
|
|
176
|
+
if (typeof mediaType === 'undefined') {
|
|
177
|
+
return () => false;
|
|
178
|
+
}
|
|
179
|
+
return ({ operationObject }) => hasRequestMediaType(operationObject, mediaType);
|
|
180
|
+
},
|
|
181
|
+
visitUrl({ url }) {
|
|
182
|
+
return ({ serverInfo, path }) => {
|
|
183
|
+
const fullUrl = `${serverInfo.protocol}://${serverInfo.host}:${serverInfo.port}${path.startsWith('/') ? path : '/' + path}`;
|
|
184
|
+
return fullUrl === url;
|
|
185
|
+
};
|
|
186
|
+
},
|
|
187
|
+
visitProtocol({ protocol }) {
|
|
188
|
+
return ({ serverInfo }) => serverInfo.protocol === protocol;
|
|
189
|
+
},
|
|
190
|
+
visitStatusCode({ code }) {
|
|
191
|
+
if (typeof code === 'undefined') {
|
|
192
|
+
return () => false;
|
|
193
|
+
}
|
|
194
|
+
return ({ operationObject }) => hasResponseWithStatusCode(operationObject, code);
|
|
195
|
+
},
|
|
196
|
+
visitHasResponseBody({ hasBody }) {
|
|
197
|
+
return ({ operationObject }) => hasResponseBody(operationObject) === hasBody;
|
|
198
|
+
},
|
|
199
|
+
visitResponseHeader({ header }) {
|
|
200
|
+
if (typeof header === 'undefined') {
|
|
201
|
+
return () => false;
|
|
202
|
+
}
|
|
203
|
+
return ({ operationObject }) => hasResponseHeader(operationObject, header);
|
|
204
|
+
},
|
|
205
|
+
visitStatusCodeRange({ start, end }) {
|
|
206
|
+
return ({ operationObject }) => hasResponseInStatusCodeRange(operationObject, start, end);
|
|
207
|
+
},
|
|
208
|
+
visitResponseMediaType({ mediaType }) {
|
|
209
|
+
if (typeof mediaType === 'undefined') {
|
|
210
|
+
return () => false;
|
|
211
|
+
}
|
|
212
|
+
return ({ operationObject }) => hasResponseMediaType(operationObject, mediaType);
|
|
213
|
+
},
|
|
214
|
+
visitResponseTrailer() {
|
|
215
|
+
throw new Error('Response trailers are not currently supported.');
|
|
216
|
+
},
|
|
217
|
+
});
|
|
218
|
+
export function httpFilterExpressionToOperationFilter(expression) {
|
|
219
|
+
return visitHttpFilter(expression, visitor);
|
|
220
|
+
}
|
|
221
|
+
//# sourceMappingURL=http-filter-expression-to-operation-filter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-filter-expression-to-operation-filter.js","sourceRoot":"","sources":["../src/http-filter-expression-to-operation-filter.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { type HttpFilterExpression, type SerializedThymianFormat, type ThymianNode, type ThymianPlugin } from '@thymian/core';
|
|
2
|
+
import type { OpenAPI } from 'openapi-types';
|
|
3
|
+
import type { ServerInfo } from './processors/extract-server-info.js';
|
|
4
|
+
declare module '@thymian/core' {
|
|
5
|
+
interface ThymianHttpRequest {
|
|
6
|
+
extensions: {
|
|
7
|
+
openapi: {
|
|
8
|
+
operationId?: string;
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
interface SecurityScheme {
|
|
13
|
+
extensions: {
|
|
14
|
+
openapi: {
|
|
15
|
+
schemeName: string;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
interface ThymianFormat {
|
|
20
|
+
getNodeByExtension(extensionName: 'openapi', values: {
|
|
21
|
+
operationId: string;
|
|
22
|
+
}): ThymianNode | undefined;
|
|
23
|
+
}
|
|
24
|
+
interface ThymianEvents {
|
|
25
|
+
'openapi.document': {
|
|
26
|
+
document: OpenAPI.Document;
|
|
27
|
+
filePath?: string;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
interface ThymianActions {
|
|
31
|
+
'openapi.transform': {
|
|
32
|
+
event: {
|
|
33
|
+
filter?: HttpFilterExpression;
|
|
34
|
+
content: string;
|
|
35
|
+
};
|
|
36
|
+
response: SerializedThymianFormat;
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export declare const defaultServerInfo: ServerInfo;
|
|
41
|
+
export declare const openApiPlugin: ThymianPlugin;
|
|
42
|
+
export default openApiPlugin;
|
|
43
|
+
export { searchForOpenApiFiles } from './search-for-openapi-files.js';
|
|
44
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,oBAAoB,EACzB,KAAK,uBAAuB,EAE5B,KAAK,WAAW,EAChB,KAAK,aAAa,EACnB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAG7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qCAAqC,CAAC;AAEtE,OAAO,QAAQ,eAAe,CAAC;IAC7B,UAAU,kBAAkB;QAC1B,UAAU,EAAE;YACV,OAAO,EAAE;gBACP,WAAW,CAAC,EAAE,MAAM,CAAC;aACtB,CAAC;SACH,CAAC;KACH;IAED,UAAU,cAAc;QACtB,UAAU,EAAE;YACV,OAAO,EAAE;gBACP,UAAU,EAAE,MAAM,CAAC;aACpB,CAAC;SACH,CAAC;KACH;IAED,UAAU,aAAa;QACrB,kBAAkB,CAChB,aAAa,EAAE,SAAS,EACxB,MAAM,EAAE;YAAE,WAAW,EAAE,MAAM,CAAA;SAAE,GAC9B,WAAW,GAAG,SAAS,CAAC;KAC5B;IAED,UAAU,aAAa;QACrB,kBAAkB,EAAE;YAClB,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC;YAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;SACnB,CAAC;KACH;IAED,UAAU,cAAc;QACtB,mBAAmB,EAAE;YACnB,KAAK,EAAE;gBACL,MAAM,CAAC,EAAE,oBAAoB,CAAC;gBAC9B,OAAO,EAAE,MAAM,CAAC;aACjB,CAAC;YACF,QAAQ,EAAE,uBAAuB,CAAC;SACnC,CAAC;KACH;CACF;AAED,eAAO,MAAM,iBAAiB,EAAE,UAK/B,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,aA+D3B,CAAC;AAEF,eAAe,aAAa,CAAC;AAE7B,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { constant, ThymianFormat, } from '@thymian/core';
|
|
2
|
+
import { loadAndTransform } from './load-openapi.js';
|
|
3
|
+
export const defaultServerInfo = {
|
|
4
|
+
port: 8080,
|
|
5
|
+
host: 'localhost',
|
|
6
|
+
protocol: 'http',
|
|
7
|
+
basePath: '',
|
|
8
|
+
};
|
|
9
|
+
export const openApiPlugin = {
|
|
10
|
+
name: '@thymian/plugin-openapi',
|
|
11
|
+
version: '0.x',
|
|
12
|
+
plugin: async (emitter, logger, opts) => {
|
|
13
|
+
emitter.onAction('openapi.transform', async ({ content, filter }, ctx) => {
|
|
14
|
+
const [, thymianFormat] = await loadAndTransform(content, {
|
|
15
|
+
logger,
|
|
16
|
+
serverInfo: defaultServerInfo,
|
|
17
|
+
cwd: opts.cwd,
|
|
18
|
+
filter: filter ?? constant(true),
|
|
19
|
+
});
|
|
20
|
+
ctx.reply(thymianFormat.export());
|
|
21
|
+
});
|
|
22
|
+
emitter.onAction('core.format.load', async ({ inputs }, ctx) => {
|
|
23
|
+
let format = new ThymianFormat();
|
|
24
|
+
const descriptions = inputs.length
|
|
25
|
+
? inputs
|
|
26
|
+
.filter((input) => input.type === 'openapi')
|
|
27
|
+
.map((input) => ({
|
|
28
|
+
source: String(input.location),
|
|
29
|
+
sourceName: typeof input.options?.['sourceName'] === 'string'
|
|
30
|
+
? input.options['sourceName']
|
|
31
|
+
: undefined,
|
|
32
|
+
serverInfo: typeof input.options?.['serverInfo'] === 'object' &&
|
|
33
|
+
input.options['serverInfo'] !== null
|
|
34
|
+
? input.options['serverInfo']
|
|
35
|
+
: undefined,
|
|
36
|
+
}))
|
|
37
|
+
: [];
|
|
38
|
+
if (descriptions.length === 0) {
|
|
39
|
+
ctx.reply(format.export());
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
for (const description of descriptions) {
|
|
43
|
+
const [document, thymianFormat, filePath] = await loadAndTransform(description.source, {
|
|
44
|
+
logger,
|
|
45
|
+
format,
|
|
46
|
+
serverInfo: description.serverInfo ?? defaultServerInfo,
|
|
47
|
+
sourceName: description.sourceName,
|
|
48
|
+
cwd: opts.cwd,
|
|
49
|
+
filter: constant(true),
|
|
50
|
+
});
|
|
51
|
+
format = thymianFormat;
|
|
52
|
+
emitter.emit('openapi.document', {
|
|
53
|
+
document,
|
|
54
|
+
filePath,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
ctx.reply(format.export());
|
|
58
|
+
});
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
export default openApiPlugin;
|
|
62
|
+
export { searchForOpenApiFiles } from './search-for-openapi-files.js';
|
|
63
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|