@speakeasy-api/openapi-linter-types 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/README.md ADDED
@@ -0,0 +1,141 @@
1
+ # @speakeasy-api/openapi-linter-types
2
+
3
+ TypeScript types for writing custom OpenAPI linter rules.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @speakeasy-api/openapi-linter-types
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ Create a TypeScript file with your custom rule:
14
+
15
+ ```typescript
16
+ import { Rule, registerRule, createValidationError } from '@speakeasy-api/openapi-linter-types';
17
+ import type { Context, DocumentInfo, RuleConfig, Severity, ValidationError } from '@speakeasy-api/openapi-linter-types';
18
+
19
+ class RequireOperationSummary extends Rule {
20
+ id(): string { return 'custom-require-operation-summary'; }
21
+ category(): string { return 'style'; }
22
+ description(): string { return 'All operations must have a summary.'; }
23
+ summary(): string { return 'Operations must have summary'; }
24
+ defaultSeverity(): Severity { return 'warning'; }
25
+
26
+ run(ctx: Context, docInfo: DocumentInfo, config: RuleConfig): ValidationError[] {
27
+ const errors: ValidationError[] = [];
28
+
29
+ for (const opNode of docInfo.index.operations) {
30
+ const op = opNode.node;
31
+ if (!op.getSummary()) {
32
+ errors.push(createValidationError(
33
+ config.getSeverity(this.defaultSeverity()),
34
+ this.id(),
35
+ 'Operation is missing a summary',
36
+ op.getRootNode()
37
+ ));
38
+ }
39
+ }
40
+
41
+ return errors;
42
+ }
43
+ }
44
+
45
+ registerRule(new RequireOperationSummary());
46
+ ```
47
+
48
+ ## Rule Base Class
49
+
50
+ Extend the `Rule` base class to create custom rules. The following methods must be implemented:
51
+
52
+ | Method | Description |
53
+ |--------|-------------|
54
+ | `id()` | Unique identifier for the rule (e.g., `custom-require-summary`) |
55
+ | `category()` | Category for grouping rules (e.g., `style`, `security`, `naming`) |
56
+ | `description()` | Full description of what the rule checks |
57
+ | `summary()` | Short summary for display |
58
+ | `run(ctx, docInfo, config)` | Main rule logic that returns validation errors |
59
+
60
+ Optional methods with defaults:
61
+
62
+ | Method | Default | Description |
63
+ |--------|---------|-------------|
64
+ | `link()` | `''` | URL to rule documentation |
65
+ | `defaultSeverity()` | `'warning'` | Default severity (`'error'`, `'warning'`, `'hint'`) |
66
+ | `versions()` | `null` | OpenAPI versions this rule applies to (e.g., `['3.0', '3.1']`) |
67
+
68
+ ## Document Access
69
+
70
+ The `DocumentInfo` object provides access to the parsed OpenAPI document:
71
+
72
+ ```typescript
73
+ // The OpenAPI document root
74
+ docInfo.document
75
+
76
+ // File location
77
+ docInfo.location
78
+
79
+ // Pre-computed index with collections for efficient iteration
80
+ docInfo.index.operations // All operations
81
+ docInfo.index.componentSchemas // All component schemas
82
+ docInfo.index.inlineSchemas // All inline schemas
83
+ docInfo.index.parameters // All parameters (inline + component)
84
+ docInfo.index.requestBodies // All request bodies
85
+ docInfo.index.responses // All responses
86
+ docInfo.index.headers // All headers
87
+ docInfo.index.securitySchemes // All security schemes
88
+ // ... and many more collections
89
+ ```
90
+
91
+ ## Creating Validation Errors
92
+
93
+ Use `createValidationError()` to create properly formatted errors:
94
+
95
+ ```typescript
96
+ import { createValidationError } from '@speakeasy-api/openapi-linter-types';
97
+
98
+ const error = createValidationError(
99
+ 'warning', // severity
100
+ 'custom-my-rule', // rule ID
101
+ 'Description of the issue', // message
102
+ node.getRootNode() // YAML node for location
103
+ );
104
+ ```
105
+
106
+ ## Console Logging
107
+
108
+ The `console` global is available for debugging:
109
+
110
+ ```typescript
111
+ console.log('Processing operation:', op.getOperationID());
112
+ console.warn('Missing recommended field');
113
+ console.error('Invalid configuration');
114
+ ```
115
+
116
+ ## Configuration
117
+
118
+ Configure custom rules in your `lint.yaml`:
119
+
120
+ ```yaml
121
+ extends: recommended
122
+
123
+ custom_rules:
124
+ paths:
125
+ - ./rules/*.ts
126
+ - ./rules/security/*.ts
127
+
128
+ rules:
129
+ - id: custom-require-operation-summary
130
+ severity: error
131
+ ```
132
+
133
+ ## API Notes
134
+
135
+ - Field and method names use lowercase JavaScript conventions (e.g., `getSummary()`, not `GetSummary()`)
136
+ - All Go struct fields and methods are automatically exposed to JavaScript
137
+ - Arrays from the Index use JavaScript array methods (`.forEach()`, `.map()`, etc.)
138
+
139
+ ## License
140
+
141
+ Apache-2.0
@@ -0,0 +1,17 @@
1
+ import type { Severity } from './severity';
2
+ /**
3
+ * RuleConfig provides configuration for a rule execution.
4
+ */
5
+ export interface RuleConfig {
6
+ /**
7
+ * Get the effective severity, respecting user overrides.
8
+ * @param defaultSeverity The rule's default severity
9
+ * @returns The severity to use (user override or default)
10
+ */
11
+ getSeverity(defaultSeverity: Severity): Severity;
12
+ /**
13
+ * Whether the rule is enabled.
14
+ */
15
+ enabled(): boolean;
16
+ }
17
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB;;;;OAIG;IACH,WAAW,CAAC,eAAe,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAEjD;;OAEG;IACH,OAAO,IAAI,OAAO,CAAC;CACpB"}
package/dist/config.js ADDED
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Context provides cancellation and deadline information.
3
+ *
4
+ * Since JavaScript has no channel equivalent to Go's Done(),
5
+ * rules performing long operations should poll isCancelled() periodically.
6
+ */
7
+ export interface Context {
8
+ /**
9
+ * Check if the context has been cancelled.
10
+ * Rules performing long operations should poll this periodically.
11
+ */
12
+ isCancelled(): boolean;
13
+ /**
14
+ * Deadline in milliseconds since epoch, or undefined if no deadline.
15
+ */
16
+ deadline(): number | undefined;
17
+ }
18
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,WAAW,OAAO;IACtB;;;OAGG;IACH,WAAW,IAAI,OAAO,CAAC;IAEvB;;OAEG;IACH,QAAQ,IAAI,MAAM,GAAG,SAAS,CAAC;CAChC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,254 @@
1
+ import type { Index } from './index-types';
2
+ /**
3
+ * DocumentInfo provides access to the OpenAPI document and its index.
4
+ *
5
+ * Note: All field and method names are lowercased when accessed from JavaScript
6
+ * due to goja's UncapFieldNameMapper.
7
+ */
8
+ export interface DocumentInfo {
9
+ /** The parsed OpenAPI document */
10
+ readonly document: OpenAPI;
11
+ /** Absolute path or URL of the document */
12
+ readonly location: string;
13
+ /** Pre-computed index for efficient document traversal */
14
+ readonly index: Index;
15
+ }
16
+ /**
17
+ * OpenAPI document root object.
18
+ * Access nested elements via fields or getter methods.
19
+ */
20
+ export interface OpenAPI {
21
+ /** OpenAPI version (e.g., "3.1.0") */
22
+ readonly openAPI: string;
23
+ /** Document info section */
24
+ getInfo(): Info | null;
25
+ /** Document paths */
26
+ getPaths(): Paths | null;
27
+ /** Document components */
28
+ getComponents(): Components | null;
29
+ /** Document servers */
30
+ getServers(): Server[] | null;
31
+ /** Document tags */
32
+ getTags(): Tag[] | null;
33
+ /** Document security requirements */
34
+ getSecurity(): SecurityRequirement[] | null;
35
+ /** Get the root YAML node */
36
+ getRootNode(): any;
37
+ }
38
+ export interface Info {
39
+ readonly title: string;
40
+ readonly version: string;
41
+ getDescription(): string;
42
+ getSummary(): string;
43
+ getTermsOfService(): string;
44
+ getContact(): Contact | null;
45
+ getLicense(): License | null;
46
+ getRootNode(): any;
47
+ }
48
+ export interface Contact {
49
+ getName(): string;
50
+ getURL(): string;
51
+ getEmail(): string;
52
+ getRootNode(): any;
53
+ }
54
+ export interface License {
55
+ readonly name: string;
56
+ getIdentifier(): string;
57
+ getURL(): string;
58
+ getRootNode(): any;
59
+ }
60
+ export interface Paths {
61
+ /** Get all path item entries */
62
+ all(): IterableIterator<[string, PathItem]>;
63
+ getRootNode(): any;
64
+ }
65
+ export interface PathItem {
66
+ getSummary(): string;
67
+ getDescription(): string;
68
+ getParameters(): Parameter[];
69
+ getServers(): Server[];
70
+ /** Get a specific operation by HTTP method */
71
+ getOperation(method: string): Operation | null;
72
+ /** Get all operations */
73
+ all(): IterableIterator<[string, Operation]>;
74
+ getRootNode(): any;
75
+ }
76
+ export interface Operation {
77
+ getOperationID(): string;
78
+ getSummary(): string;
79
+ getDescription(): string;
80
+ getTags(): string[];
81
+ getParameters(): Parameter[];
82
+ getRequestBody(): RequestBody | null;
83
+ getResponses(): Responses | null;
84
+ getSecurity(): SecurityRequirement[] | null;
85
+ getServers(): Server[];
86
+ getDeprecated(): boolean;
87
+ getRootNode(): any;
88
+ }
89
+ export interface Parameter {
90
+ readonly name: string;
91
+ readonly in: string;
92
+ getDescription(): string;
93
+ getRequired(): boolean;
94
+ getDeprecated(): boolean;
95
+ getSchema(): Schema | null;
96
+ getRootNode(): any;
97
+ }
98
+ export interface RequestBody {
99
+ getDescription(): string;
100
+ getRequired(): boolean;
101
+ getContent(): Map<string, MediaType>;
102
+ getRootNode(): any;
103
+ }
104
+ export interface Responses {
105
+ /** Get all response entries */
106
+ all(): IterableIterator<[string, Response]>;
107
+ getDefault(): Response | null;
108
+ getRootNode(): any;
109
+ }
110
+ export interface Response {
111
+ readonly description: string;
112
+ getHeaders(): Map<string, Header>;
113
+ getContent(): Map<string, MediaType>;
114
+ getLinks(): Map<string, Link>;
115
+ getRootNode(): any;
116
+ }
117
+ export interface Header {
118
+ getDescription(): string;
119
+ getRequired(): boolean;
120
+ getDeprecated(): boolean;
121
+ getSchema(): Schema | null;
122
+ getRootNode(): any;
123
+ }
124
+ export interface MediaType {
125
+ getSchema(): Schema | null;
126
+ getExample(): any;
127
+ getExamples(): Map<string, Example>;
128
+ getEncoding(): Map<string, Encoding>;
129
+ getRootNode(): any;
130
+ }
131
+ export interface Encoding {
132
+ getContentType(): string;
133
+ getHeaders(): Map<string, Header>;
134
+ getStyle(): string;
135
+ getExplode(): boolean;
136
+ getAllowReserved(): boolean;
137
+ getRootNode(): any;
138
+ }
139
+ export interface Example {
140
+ getSummary(): string;
141
+ getDescription(): string;
142
+ getValue(): any;
143
+ getExternalValue(): string;
144
+ getRootNode(): any;
145
+ }
146
+ export interface Link {
147
+ getOperationID(): string;
148
+ getOperationRef(): string;
149
+ getDescription(): string;
150
+ getServer(): Server | null;
151
+ getRootNode(): any;
152
+ }
153
+ export interface Components {
154
+ getSchemas(): Map<string, Schema>;
155
+ getResponses(): Map<string, Response>;
156
+ getParameters(): Map<string, Parameter>;
157
+ getRequestBodies(): Map<string, RequestBody>;
158
+ getHeaders(): Map<string, Header>;
159
+ getSecuritySchemes(): Map<string, SecurityScheme>;
160
+ getLinks(): Map<string, Link>;
161
+ getCallbacks(): Map<string, Callback>;
162
+ getPathItems(): Map<string, PathItem>;
163
+ getRootNode(): any;
164
+ }
165
+ export interface Schema {
166
+ getType(): string | string[];
167
+ getFormat(): string;
168
+ getTitle(): string;
169
+ getDescription(): string;
170
+ getDefault(): any;
171
+ getEnum(): any[];
172
+ getRequired(): string[];
173
+ getProperties(): Map<string, Schema>;
174
+ getItems(): Schema | null;
175
+ getAdditionalProperties(): Schema | boolean | null;
176
+ getMinimum(): number | null;
177
+ getMaximum(): number | null;
178
+ getMinLength(): number | null;
179
+ getMaxLength(): number | null;
180
+ getMinItems(): number | null;
181
+ getMaxItems(): number | null;
182
+ getPattern(): string;
183
+ getNullable(): boolean;
184
+ getDeprecated(): boolean;
185
+ getAllOf(): Schema[];
186
+ getAnyOf(): Schema[];
187
+ getOneOf(): Schema[];
188
+ getNot(): Schema | null;
189
+ getRootNode(): any;
190
+ }
191
+ export interface Server {
192
+ readonly url: string;
193
+ getDescription(): string;
194
+ getVariables(): Map<string, ServerVariable>;
195
+ getRootNode(): any;
196
+ }
197
+ export interface ServerVariable {
198
+ readonly default: string;
199
+ getEnum(): string[];
200
+ getDescription(): string;
201
+ getRootNode(): any;
202
+ }
203
+ export interface Tag {
204
+ readonly name: string;
205
+ getDescription(): string;
206
+ getExternalDocs(): ExternalDocumentation | null;
207
+ getRootNode(): any;
208
+ }
209
+ export interface ExternalDocumentation {
210
+ readonly url: string;
211
+ getDescription(): string;
212
+ getRootNode(): any;
213
+ }
214
+ export interface SecurityScheme {
215
+ readonly type: string;
216
+ getDescription(): string;
217
+ getName(): string;
218
+ getIn(): string;
219
+ getScheme(): string;
220
+ getBearerFormat(): string;
221
+ getFlows(): OAuthFlows | null;
222
+ getOpenIdConnectUrl(): string;
223
+ getRootNode(): any;
224
+ }
225
+ export interface OAuthFlows {
226
+ getImplicit(): OAuthFlow | null;
227
+ getPassword(): OAuthFlow | null;
228
+ getClientCredentials(): OAuthFlow | null;
229
+ getAuthorizationCode(): OAuthFlow | null;
230
+ getRootNode(): any;
231
+ }
232
+ export interface OAuthFlow {
233
+ getAuthorizationUrl(): string;
234
+ getTokenUrl(): string;
235
+ getRefreshUrl(): string;
236
+ getScopes(): Map<string, string>;
237
+ getRootNode(): any;
238
+ }
239
+ export interface SecurityRequirement {
240
+ /** Get all security requirement entries */
241
+ all(): IterableIterator<[string, string[]]>;
242
+ getRootNode(): any;
243
+ }
244
+ export interface Callback {
245
+ /** Get all callback entries */
246
+ all(): IterableIterator<[string, PathItem]>;
247
+ getRootNode(): any;
248
+ }
249
+ export interface Discriminator {
250
+ readonly propertyName: string;
251
+ getMapping(): Map<string, string>;
252
+ getRootNode(): any;
253
+ }
254
+ //# sourceMappingURL=document.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"document.d.ts","sourceRoot":"","sources":["../src/document.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAE3C;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,kCAAkC;IAClC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAE3B,2CAA2C;IAC3C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B,0DAA0D;IAC1D,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;CACvB;AAED;;;GAGG;AACH,MAAM,WAAW,OAAO;IACtB,sCAAsC;IACtC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB,4BAA4B;IAC5B,OAAO,IAAI,IAAI,GAAG,IAAI,CAAC;IAEvB,qBAAqB;IACrB,QAAQ,IAAI,KAAK,GAAG,IAAI,CAAC;IAEzB,0BAA0B;IAC1B,aAAa,IAAI,UAAU,GAAG,IAAI,CAAC;IAEnC,uBAAuB;IACvB,UAAU,IAAI,MAAM,EAAE,GAAG,IAAI,CAAC;IAE9B,oBAAoB;IACpB,OAAO,IAAI,GAAG,EAAE,GAAG,IAAI,CAAC;IAExB,qCAAqC;IACrC,WAAW,IAAI,mBAAmB,EAAE,GAAG,IAAI,CAAC;IAE5C,6BAA6B;IAC7B,WAAW,IAAI,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,IAAI;IACnB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,cAAc,IAAI,MAAM,CAAC;IACzB,UAAU,IAAI,MAAM,CAAC;IACrB,iBAAiB,IAAI,MAAM,CAAC;IAC5B,UAAU,IAAI,OAAO,GAAG,IAAI,CAAC;IAC7B,UAAU,IAAI,OAAO,GAAG,IAAI,CAAC;IAC7B,WAAW,IAAI,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,OAAO;IACtB,OAAO,IAAI,MAAM,CAAC;IAClB,MAAM,IAAI,MAAM,CAAC;IACjB,QAAQ,IAAI,MAAM,CAAC;IACnB,WAAW,IAAI,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,aAAa,IAAI,MAAM,CAAC;IACxB,MAAM,IAAI,MAAM,CAAC;IACjB,WAAW,IAAI,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,KAAK;IACpB,gCAAgC;IAChC,GAAG,IAAI,gBAAgB,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC5C,WAAW,IAAI,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,QAAQ;IACvB,UAAU,IAAI,MAAM,CAAC;IACrB,cAAc,IAAI,MAAM,CAAC;IACzB,aAAa,IAAI,SAAS,EAAE,CAAC;IAC7B,UAAU,IAAI,MAAM,EAAE,CAAC;IAEvB,8CAA8C;IAC9C,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;IAE/C,yBAAyB;IACzB,GAAG,IAAI,gBAAgB,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;IAE7C,WAAW,IAAI,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,SAAS;IACxB,cAAc,IAAI,MAAM,CAAC;IACzB,UAAU,IAAI,MAAM,CAAC;IACrB,cAAc,IAAI,MAAM,CAAC;IACzB,OAAO,IAAI,MAAM,EAAE,CAAC;IACpB,aAAa,IAAI,SAAS,EAAE,CAAC;IAC7B,cAAc,IAAI,WAAW,GAAG,IAAI,CAAC;IACrC,YAAY,IAAI,SAAS,GAAG,IAAI,CAAC;IACjC,WAAW,IAAI,mBAAmB,EAAE,GAAG,IAAI,CAAC;IAC5C,UAAU,IAAI,MAAM,EAAE,CAAC;IACvB,aAAa,IAAI,OAAO,CAAC;IACzB,WAAW,IAAI,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,cAAc,IAAI,MAAM,CAAC;IACzB,WAAW,IAAI,OAAO,CAAC;IACvB,aAAa,IAAI,OAAO,CAAC;IACzB,SAAS,IAAI,MAAM,GAAG,IAAI,CAAC;IAC3B,WAAW,IAAI,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,cAAc,IAAI,MAAM,CAAC;IACzB,WAAW,IAAI,OAAO,CAAC;IACvB,UAAU,IAAI,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACrC,WAAW,IAAI,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,SAAS;IACxB,+BAA+B;IAC/B,GAAG,IAAI,gBAAgB,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC5C,UAAU,IAAI,QAAQ,GAAG,IAAI,CAAC;IAC9B,WAAW,IAAI,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,UAAU,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,UAAU,IAAI,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACrC,QAAQ,IAAI,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC9B,WAAW,IAAI,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,MAAM;IACrB,cAAc,IAAI,MAAM,CAAC;IACzB,WAAW,IAAI,OAAO,CAAC;IACvB,aAAa,IAAI,OAAO,CAAC;IACzB,SAAS,IAAI,MAAM,GAAG,IAAI,CAAC;IAC3B,WAAW,IAAI,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,SAAS;IACxB,SAAS,IAAI,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,IAAI,GAAG,CAAC;IAClB,WAAW,IAAI,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,WAAW,IAAI,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACrC,WAAW,IAAI,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,QAAQ;IACvB,cAAc,IAAI,MAAM,CAAC;IACzB,UAAU,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,QAAQ,IAAI,MAAM,CAAC;IACnB,UAAU,IAAI,OAAO,CAAC;IACtB,gBAAgB,IAAI,OAAO,CAAC;IAC5B,WAAW,IAAI,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,OAAO;IACtB,UAAU,IAAI,MAAM,CAAC;IACrB,cAAc,IAAI,MAAM,CAAC;IACzB,QAAQ,IAAI,GAAG,CAAC;IAChB,gBAAgB,IAAI,MAAM,CAAC;IAC3B,WAAW,IAAI,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,IAAI;IACnB,cAAc,IAAI,MAAM,CAAC;IACzB,eAAe,IAAI,MAAM,CAAC;IAC1B,cAAc,IAAI,MAAM,CAAC;IACzB,SAAS,IAAI,MAAM,GAAG,IAAI,CAAC;IAC3B,WAAW,IAAI,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,UAAU,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,YAAY,IAAI,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACtC,aAAa,IAAI,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACxC,gBAAgB,IAAI,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAC7C,UAAU,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,kBAAkB,IAAI,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAClD,QAAQ,IAAI,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC9B,YAAY,IAAI,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACtC,YAAY,IAAI,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACtC,WAAW,IAAI,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,MAAM;IACrB,OAAO,IAAI,MAAM,GAAG,MAAM,EAAE,CAAC;IAC7B,SAAS,IAAI,MAAM,CAAC;IACpB,QAAQ,IAAI,MAAM,CAAC;IACnB,cAAc,IAAI,MAAM,CAAC;IACzB,UAAU,IAAI,GAAG,CAAC;IAClB,OAAO,IAAI,GAAG,EAAE,CAAC;IACjB,WAAW,IAAI,MAAM,EAAE,CAAC;IACxB,aAAa,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,QAAQ,IAAI,MAAM,GAAG,IAAI,CAAC;IAC1B,uBAAuB,IAAI,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;IACnD,UAAU,IAAI,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,IAAI,MAAM,GAAG,IAAI,CAAC;IAC5B,YAAY,IAAI,MAAM,GAAG,IAAI,CAAC;IAC9B,YAAY,IAAI,MAAM,GAAG,IAAI,CAAC;IAC9B,WAAW,IAAI,MAAM,GAAG,IAAI,CAAC;IAC7B,WAAW,IAAI,MAAM,GAAG,IAAI,CAAC;IAC7B,UAAU,IAAI,MAAM,CAAC;IACrB,WAAW,IAAI,OAAO,CAAC;IACvB,aAAa,IAAI,OAAO,CAAC;IACzB,QAAQ,IAAI,MAAM,EAAE,CAAC;IACrB,QAAQ,IAAI,MAAM,EAAE,CAAC;IACrB,QAAQ,IAAI,MAAM,EAAE,CAAC;IACrB,MAAM,IAAI,MAAM,GAAG,IAAI,CAAC;IACxB,WAAW,IAAI,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,cAAc,IAAI,MAAM,CAAC;IACzB,YAAY,IAAI,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC5C,WAAW,IAAI,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,OAAO,IAAI,MAAM,EAAE,CAAC;IACpB,cAAc,IAAI,MAAM,CAAC;IACzB,WAAW,IAAI,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,GAAG;IAClB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,cAAc,IAAI,MAAM,CAAC;IACzB,eAAe,IAAI,qBAAqB,GAAG,IAAI,CAAC;IAChD,WAAW,IAAI,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,cAAc,IAAI,MAAM,CAAC;IACzB,WAAW,IAAI,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,cAAc,IAAI,MAAM,CAAC;IACzB,OAAO,IAAI,MAAM,CAAC;IAClB,KAAK,IAAI,MAAM,CAAC;IAChB,SAAS,IAAI,MAAM,CAAC;IACpB,eAAe,IAAI,MAAM,CAAC;IAC1B,QAAQ,IAAI,UAAU,GAAG,IAAI,CAAC;IAC9B,mBAAmB,IAAI,MAAM,CAAC;IAC9B,WAAW,IAAI,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,WAAW,IAAI,SAAS,GAAG,IAAI,CAAC;IAChC,WAAW,IAAI,SAAS,GAAG,IAAI,CAAC;IAChC,oBAAoB,IAAI,SAAS,GAAG,IAAI,CAAC;IACzC,oBAAoB,IAAI,SAAS,GAAG,IAAI,CAAC;IACzC,WAAW,IAAI,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,SAAS;IACxB,mBAAmB,IAAI,MAAM,CAAC;IAC9B,WAAW,IAAI,MAAM,CAAC;IACtB,aAAa,IAAI,MAAM,CAAC;IACxB,SAAS,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,WAAW,IAAI,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,2CAA2C;IAC3C,GAAG,IAAI,gBAAgB,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;IAC5C,WAAW,IAAI,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,QAAQ;IACvB,+BAA+B;IAC/B,GAAG,IAAI,gBAAgB,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC5C,WAAW,IAAI,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,UAAU,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,WAAW,IAAI,GAAG,CAAC;CACpB"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Global declarations for the custom rules runtime environment.
3
+ * These are provided by the Go runtime (goja).
4
+ *
5
+ * When you import from '@speakeasy-api/openapi-linter-types', the global
6
+ * `console` object is automatically typed.
7
+ */
8
+ /**
9
+ * Console interface for logging from custom rules.
10
+ * Messages are routed to the configured Logger in Go.
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * console.log('Processing operation:', op.getOperationID());
15
+ * console.warn('Missing recommended field');
16
+ * console.error('Invalid configuration');
17
+ * ```
18
+ */
19
+ export interface Console {
20
+ /** Log informational messages */
21
+ log(...args: any[]): void;
22
+ /** Log warning messages */
23
+ warn(...args: any[]): void;
24
+ /** Log error messages */
25
+ error(...args: any[]): void;
26
+ }
27
+ declare global {
28
+ /** Console object for logging. Provided by the goja runtime. */
29
+ var console: Console;
30
+ }
31
+ //# sourceMappingURL=globals.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"globals.d.ts","sourceRoot":"","sources":["../src/globals.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;GAUG;AACH,MAAM,WAAW,OAAO;IACtB,iCAAiC;IACjC,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAC1B,2BAA2B;IAC3B,IAAI,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAC3B,yBAAyB;IACzB,KAAK,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;CAC7B;AAID,OAAO,CAAC,MAAM,CAAC;IACb,gEAAgE;IAChE,IAAI,OAAO,EAAE,OAAO,CAAC;CACtB"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Global declarations for the custom rules runtime environment.
3
+ * These are provided by the Go runtime (goja).
4
+ *
5
+ * When you import from '@speakeasy-api/openapi-linter-types', the global
6
+ * `console` object is automatically typed.
7
+ */
8
+ export {};
@@ -0,0 +1,108 @@
1
+ import type { OpenAPI, Operation, Parameter, Response, RequestBody, Header, Example, Link, Callback, PathItem, SecurityScheme, SecurityRequirement, Server, ServerVariable, Tag, Schema, MediaType, Encoding, ExternalDocumentation, Discriminator } from './document';
2
+ /**
3
+ * Index provides pre-computed collections of document elements
4
+ * for efficient rule iteration.
5
+ *
6
+ * Note: All field names are lowercased when accessed from JavaScript
7
+ * due to goja's UncapFieldNameMapper.
8
+ */
9
+ export interface Index {
10
+ /** Reference to the root document */
11
+ readonly doc: OpenAPI;
12
+ readonly externalDocumentation: IndexNode<ExternalDocumentation>[];
13
+ readonly tags: IndexNode<Tag>[];
14
+ readonly servers: IndexNode<Server>[];
15
+ readonly serverVariables: IndexNode<ServerVariable>[];
16
+ readonly booleanSchemas: IndexNode<Schema>[];
17
+ readonly inlineSchemas: IndexNode<Schema>[];
18
+ readonly componentSchemas: IndexNode<Schema>[];
19
+ readonly externalSchemas: IndexNode<Schema>[];
20
+ readonly schemaReferences: IndexNode<Schema>[];
21
+ readonly inlinePathItems: IndexNode<PathItem>[];
22
+ readonly componentPathItems: IndexNode<PathItem>[];
23
+ readonly externalPathItems: IndexNode<PathItem>[];
24
+ readonly pathItemReferences: IndexNode<PathItem>[];
25
+ readonly operations: IndexNode<Operation>[];
26
+ readonly inlineParameters: IndexNode<Parameter>[];
27
+ readonly componentParameters: IndexNode<Parameter>[];
28
+ readonly externalParameters: IndexNode<Parameter>[];
29
+ readonly parameterReferences: IndexNode<Parameter>[];
30
+ readonly responses: IndexNode<any>[];
31
+ readonly inlineResponses: IndexNode<Response>[];
32
+ readonly componentResponses: IndexNode<Response>[];
33
+ readonly externalResponses: IndexNode<Response>[];
34
+ readonly responseReferences: IndexNode<Response>[];
35
+ readonly inlineRequestBodies: IndexNode<RequestBody>[];
36
+ readonly componentRequestBodies: IndexNode<RequestBody>[];
37
+ readonly externalRequestBodies: IndexNode<RequestBody>[];
38
+ readonly requestBodyReferences: IndexNode<RequestBody>[];
39
+ readonly inlineHeaders: IndexNode<Header>[];
40
+ readonly componentHeaders: IndexNode<Header>[];
41
+ readonly externalHeaders: IndexNode<Header>[];
42
+ readonly headerReferences: IndexNode<Header>[];
43
+ readonly inlineExamples: IndexNode<Example>[];
44
+ readonly componentExamples: IndexNode<Example>[];
45
+ readonly externalExamples: IndexNode<Example>[];
46
+ readonly exampleReferences: IndexNode<Example>[];
47
+ readonly inlineLinks: IndexNode<Link>[];
48
+ readonly componentLinks: IndexNode<Link>[];
49
+ readonly externalLinks: IndexNode<Link>[];
50
+ readonly linkReferences: IndexNode<Link>[];
51
+ readonly inlineCallbacks: IndexNode<Callback>[];
52
+ readonly componentCallbacks: IndexNode<Callback>[];
53
+ readonly externalCallbacks: IndexNode<Callback>[];
54
+ readonly callbackReferences: IndexNode<Callback>[];
55
+ readonly componentSecuritySchemes: IndexNode<SecurityScheme>[];
56
+ readonly securitySchemeReferences: IndexNode<SecurityScheme>[];
57
+ readonly securityRequirements: IndexNode<SecurityRequirement>[];
58
+ readonly discriminators: IndexNode<Discriminator>[];
59
+ readonly mediaTypes: IndexNode<MediaType>[];
60
+ readonly encodings: IndexNode<Encoding>[];
61
+ readonly descriptionNodes: IndexNode<Descriptioner>[];
62
+ readonly summaryNodes: IndexNode<Summarizer>[];
63
+ readonly descriptionAndSummaryNodes: IndexNode<DescriptionAndSummary>[];
64
+ }
65
+ /**
66
+ * IndexNode wraps a document element with its location.
67
+ */
68
+ export interface IndexNode<T> {
69
+ /** The document element */
70
+ readonly node: T;
71
+ /** Location path to this element */
72
+ readonly location: Locations;
73
+ }
74
+ /**
75
+ * Locations is the path from root to an element.
76
+ */
77
+ export type Locations = LocationContext[];
78
+ /**
79
+ * LocationContext represents one level in the path.
80
+ */
81
+ export interface LocationContext {
82
+ /** Parent field name (e.g., "paths", "responses") */
83
+ parentField(): string;
84
+ /** Parent key if in a map (e.g., "/users/{id}") */
85
+ parentKey(): string;
86
+ /** Parent index if in an array */
87
+ parentIndex(): number;
88
+ /** Convert to JSON pointer string */
89
+ toJSONPointer(): string;
90
+ }
91
+ /**
92
+ * Interface for elements with a description.
93
+ */
94
+ export interface Descriptioner {
95
+ getDescription(): string;
96
+ }
97
+ /**
98
+ * Interface for elements with a summary.
99
+ */
100
+ export interface Summarizer {
101
+ getSummary(): string;
102
+ }
103
+ /**
104
+ * Interface for elements with both description and summary.
105
+ */
106
+ export interface DescriptionAndSummary extends Descriptioner, Summarizer {
107
+ }
108
+ //# sourceMappingURL=index-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-types.d.ts","sourceRoot":"","sources":["../src/index-types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,51 @@
1
+ /**
2
+ * @speakeasy-api/openapi-linter-types
3
+ *
4
+ * TypeScript types for writing custom OpenAPI linter rules.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import { Rule, registerRule, createValidationError } from '@speakeasy-api/openapi-linter-types';
9
+ * import type { Context, DocumentInfo, RuleConfig, Severity, ValidationError } from '@speakeasy-api/openapi-linter-types';
10
+ *
11
+ * class RequireOperationSummary extends Rule {
12
+ * id(): string { return 'custom-require-operation-summary'; }
13
+ * category(): string { return 'style'; }
14
+ * description(): string { return 'All operations must have a summary.'; }
15
+ * summary(): string { return 'Operations must have summary'; }
16
+ *
17
+ * run(ctx: Context, docInfo: DocumentInfo, config: RuleConfig): ValidationError[] {
18
+ * const errors: ValidationError[] = [];
19
+ *
20
+ * for (const opNode of docInfo.index.operations) {
21
+ * const op = opNode.node;
22
+ * if (!op.getSummary()) {
23
+ * errors.push(createValidationError(
24
+ * config.getSeverity(this.defaultSeverity()),
25
+ * this.id(),
26
+ * 'Operation is missing a summary',
27
+ * op.getRootNode()
28
+ * ));
29
+ * }
30
+ * }
31
+ *
32
+ * return errors;
33
+ * }
34
+ * }
35
+ *
36
+ * registerRule(new RequireOperationSummary());
37
+ * ```
38
+ */
39
+ export type { Severity } from './severity';
40
+ export type { Context } from './context';
41
+ export type { RuleConfig } from './config';
42
+ export { Rule, registerRule } from './rule';
43
+ export type { RuleRunner } from './rule';
44
+ export { createValidationError } from './validation';
45
+ export type { ValidationError, YamlNode } from './validation';
46
+ export type { DocumentInfo } from './document';
47
+ export type { OpenAPI, Info, Contact, License, Paths, PathItem, Operation, Parameter, RequestBody, Responses, Response, Header, MediaType, Encoding, Example, Link, Components, Schema, Server, ServerVariable, Tag, ExternalDocumentation, SecurityScheme, OAuthFlows, OAuthFlow, SecurityRequirement, Callback, Discriminator, } from './document';
48
+ export type { Index, IndexNode, Locations, LocationContext, Descriptioner, Summarizer, DescriptionAndSummary, } from './index-types';
49
+ import './globals';
50
+ export type { Console } from './globals';
51
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAGH,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,YAAY,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,YAAY,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAG3C,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAC5C,YAAY,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAGzC,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACrD,YAAY,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAG9D,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,YAAY,EACV,OAAO,EACP,IAAI,EACJ,OAAO,EACP,OAAO,EACP,KAAK,EACL,QAAQ,EACR,SAAS,EACT,SAAS,EACT,WAAW,EACX,SAAS,EACT,QAAQ,EACR,MAAM,EACN,SAAS,EACT,QAAQ,EACR,OAAO,EACP,IAAI,EACJ,UAAU,EACV,MAAM,EACN,MAAM,EACN,cAAc,EACd,GAAG,EACH,qBAAqB,EACrB,cAAc,EACd,UAAU,EACV,SAAS,EACT,mBAAmB,EACnB,QAAQ,EACR,aAAa,GACd,MAAM,YAAY,CAAC;AAGpB,YAAY,EACV,KAAK,EACL,SAAS,EACT,SAAS,EACT,eAAe,EACf,aAAa,EACb,UAAU,EACV,qBAAqB,GACtB,MAAM,eAAe,CAAC;AAIvB,OAAO,WAAW,CAAC;AACnB,YAAY,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,45 @@
1
+ /**
2
+ * @speakeasy-api/openapi-linter-types
3
+ *
4
+ * TypeScript types for writing custom OpenAPI linter rules.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import { Rule, registerRule, createValidationError } from '@speakeasy-api/openapi-linter-types';
9
+ * import type { Context, DocumentInfo, RuleConfig, Severity, ValidationError } from '@speakeasy-api/openapi-linter-types';
10
+ *
11
+ * class RequireOperationSummary extends Rule {
12
+ * id(): string { return 'custom-require-operation-summary'; }
13
+ * category(): string { return 'style'; }
14
+ * description(): string { return 'All operations must have a summary.'; }
15
+ * summary(): string { return 'Operations must have summary'; }
16
+ *
17
+ * run(ctx: Context, docInfo: DocumentInfo, config: RuleConfig): ValidationError[] {
18
+ * const errors: ValidationError[] = [];
19
+ *
20
+ * for (const opNode of docInfo.index.operations) {
21
+ * const op = opNode.node;
22
+ * if (!op.getSummary()) {
23
+ * errors.push(createValidationError(
24
+ * config.getSeverity(this.defaultSeverity()),
25
+ * this.id(),
26
+ * 'Operation is missing a summary',
27
+ * op.getRootNode()
28
+ * ));
29
+ * }
30
+ * }
31
+ *
32
+ * return errors;
33
+ * }
34
+ * }
35
+ *
36
+ * registerRule(new RequireOperationSummary());
37
+ * ```
38
+ */
39
+ // Rule interface and base class
40
+ export { Rule, registerRule } from './rule';
41
+ // Validation errors
42
+ export { createValidationError } from './validation';
43
+ // Global runtime types (console, etc.)
44
+ // Import for side effects to register global types
45
+ import './globals';
package/dist/rule.d.ts ADDED
@@ -0,0 +1,108 @@
1
+ import type { Context } from './context';
2
+ import type { RuleConfig } from './config';
3
+ import type { DocumentInfo } from './document';
4
+ import type { Severity } from './severity';
5
+ import type { ValidationError } from './validation';
6
+ /**
7
+ * RuleRunner is the interface that custom rules must implement.
8
+ */
9
+ export interface RuleRunner {
10
+ /**
11
+ * Unique identifier for this rule (e.g., "custom-require-summary").
12
+ * Should be prefixed with "custom-" to avoid conflicts with built-in rules.
13
+ */
14
+ id(): string;
15
+ /**
16
+ * Rule category (e.g., "style", "semantic", "security", "schemas").
17
+ */
18
+ category(): string;
19
+ /**
20
+ * Detailed description of what the rule checks.
21
+ */
22
+ description(): string;
23
+ /**
24
+ * Short summary of what the rule checks.
25
+ */
26
+ summary(): string;
27
+ /**
28
+ * Optional URL to documentation for this rule.
29
+ */
30
+ link(): string;
31
+ /**
32
+ * Default severity level for this rule.
33
+ */
34
+ defaultSeverity(): Severity;
35
+ /**
36
+ * OpenAPI versions this rule applies to, or null for all versions.
37
+ * Example: ["3.0", "3.1"] to only run on OpenAPI 3.x documents.
38
+ */
39
+ versions(): string[] | null;
40
+ /**
41
+ * Execute the rule against the document.
42
+ *
43
+ * @param ctx - Context for cancellation checking
44
+ * @param docInfo - Document information including the parsed document and index
45
+ * @param config - Rule configuration including severity overrides
46
+ * @returns Array of validation errors found
47
+ */
48
+ run(ctx: Context, docInfo: DocumentInfo, config: RuleConfig): ValidationError[];
49
+ }
50
+ /**
51
+ * Base class for implementing custom rules.
52
+ * Provides default implementations for optional methods.
53
+ *
54
+ * @example
55
+ * ```typescript
56
+ * class RequireOperationSummary extends Rule {
57
+ * id(): string { return 'custom-require-operation-summary'; }
58
+ * category(): string { return 'style'; }
59
+ * description(): string { return 'All operations must have a summary.'; }
60
+ * summary(): string { return 'Operations must have summary'; }
61
+ *
62
+ * run(ctx: Context, docInfo: DocumentInfo, config: RuleConfig) {
63
+ * const errors: ValidationError[] = [];
64
+ * for (const opNode of docInfo.index.operations) {
65
+ * const op = opNode.node;
66
+ * if (!op.getSummary()) {
67
+ * errors.push(createValidationError(
68
+ * config.getSeverity(this.defaultSeverity()),
69
+ * this.id(),
70
+ * 'Operation is missing a summary',
71
+ * op.getRootNode()
72
+ * ));
73
+ * }
74
+ * }
75
+ * return errors;
76
+ * }
77
+ * }
78
+ *
79
+ * registerRule(new RequireOperationSummary());
80
+ * ```
81
+ */
82
+ export declare abstract class Rule implements RuleRunner {
83
+ abstract id(): string;
84
+ abstract category(): string;
85
+ abstract description(): string;
86
+ abstract summary(): string;
87
+ /** Default implementation returns empty string (no documentation link). */
88
+ link(): string;
89
+ /** Default implementation returns 'warning'. */
90
+ defaultSeverity(): Severity;
91
+ /** Default implementation returns null (applies to all versions). */
92
+ versions(): string[] | null;
93
+ abstract run(ctx: Context, docInfo: DocumentInfo, config: RuleConfig): ValidationError[];
94
+ }
95
+ /**
96
+ * Register a rule with the linter.
97
+ * Call this at the end of your rule file to make it available.
98
+ *
99
+ * @param rule - The rule instance to register
100
+ *
101
+ * @example
102
+ * ```typescript
103
+ * registerRule(new MyCustomRule());
104
+ * ```
105
+ */
106
+ declare function registerRule(rule: RuleRunner): void;
107
+ export { registerRule };
108
+ //# sourceMappingURL=rule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rule.d.ts","sourceRoot":"","sources":["../src/rule.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpD;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB;;;OAGG;IACH,EAAE,IAAI,MAAM,CAAC;IAEb;;OAEG;IACH,QAAQ,IAAI,MAAM,CAAC;IAEnB;;OAEG;IACH,WAAW,IAAI,MAAM,CAAC;IAEtB;;OAEG;IACH,OAAO,IAAI,MAAM,CAAC;IAElB;;OAEG;IACH,IAAI,IAAI,MAAM,CAAC;IAEf;;OAEG;IACH,eAAe,IAAI,QAAQ,CAAC;IAE5B;;;OAGG;IACH,QAAQ,IAAI,MAAM,EAAE,GAAG,IAAI,CAAC;IAE5B;;;;;;;OAOG;IACH,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,GAAG,eAAe,EAAE,CAAC;CACjF;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,8BAAsB,IAAK,YAAW,UAAU;IAC9C,QAAQ,CAAC,EAAE,IAAI,MAAM;IACrB,QAAQ,CAAC,QAAQ,IAAI,MAAM;IAC3B,QAAQ,CAAC,WAAW,IAAI,MAAM;IAC9B,QAAQ,CAAC,OAAO,IAAI,MAAM;IAE1B,2EAA2E;IAC3E,IAAI,IAAI,MAAM;IAId,gDAAgD;IAChD,eAAe,IAAI,QAAQ;IAI3B,qEAAqE;IACrE,QAAQ,IAAI,MAAM,EAAE,GAAG,IAAI;IAI3B,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,UAAU,GAAG,eAAe,EAAE;CACzF;AAED;;;;;;;;;;GAUG;AACH,OAAO,UAAU,YAAY,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,CAAC;AAEtD,OAAO,EAAE,YAAY,EAAE,CAAC"}
package/dist/rule.js ADDED
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Base class for implementing custom rules.
3
+ * Provides default implementations for optional methods.
4
+ *
5
+ * @example
6
+ * ```typescript
7
+ * class RequireOperationSummary extends Rule {
8
+ * id(): string { return 'custom-require-operation-summary'; }
9
+ * category(): string { return 'style'; }
10
+ * description(): string { return 'All operations must have a summary.'; }
11
+ * summary(): string { return 'Operations must have summary'; }
12
+ *
13
+ * run(ctx: Context, docInfo: DocumentInfo, config: RuleConfig) {
14
+ * const errors: ValidationError[] = [];
15
+ * for (const opNode of docInfo.index.operations) {
16
+ * const op = opNode.node;
17
+ * if (!op.getSummary()) {
18
+ * errors.push(createValidationError(
19
+ * config.getSeverity(this.defaultSeverity()),
20
+ * this.id(),
21
+ * 'Operation is missing a summary',
22
+ * op.getRootNode()
23
+ * ));
24
+ * }
25
+ * }
26
+ * return errors;
27
+ * }
28
+ * }
29
+ *
30
+ * registerRule(new RequireOperationSummary());
31
+ * ```
32
+ */
33
+ export class Rule {
34
+ /** Default implementation returns empty string (no documentation link). */
35
+ link() {
36
+ return '';
37
+ }
38
+ /** Default implementation returns 'warning'. */
39
+ defaultSeverity() {
40
+ return 'warning';
41
+ }
42
+ /** Default implementation returns null (applies to all versions). */
43
+ versions() {
44
+ return null;
45
+ }
46
+ }
47
+ export { registerRule };
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Severity levels for validation errors.
3
+ */
4
+ export type Severity = 'error' | 'warning' | 'hint';
5
+ //# sourceMappingURL=severity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"severity.d.ts","sourceRoot":"","sources":["../src/severity.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,55 @@
1
+ import type { Severity } from './severity';
2
+ /**
3
+ * ValidationError represents a linting error.
4
+ * Created using createValidationError().
5
+ */
6
+ export interface ValidationError {
7
+ /** Error message */
8
+ error(): string;
9
+ /** Rule ID that produced this error */
10
+ rule: string;
11
+ /** Severity level */
12
+ severity: Severity;
13
+ /** Line number (1-indexed) */
14
+ getLineNumber(): number;
15
+ /** Column number (1-indexed) */
16
+ getColumnNumber(): number;
17
+ }
18
+ /**
19
+ * YamlNode represents a YAML node from the parsed document.
20
+ * This is the node type returned by getRootNode() methods.
21
+ */
22
+ export interface YamlNode {
23
+ /** Node kind (scalar, mapping, sequence, etc.) */
24
+ kind: number;
25
+ /** Line number where this node starts (1-indexed) */
26
+ line: number;
27
+ /** Column number where this node starts (1-indexed) */
28
+ column: number;
29
+ /** Node value for scalar nodes */
30
+ value?: string;
31
+ /** Node tag */
32
+ tag?: string;
33
+ }
34
+ /**
35
+ * Creates a validation error that can be returned from a rule's run() method.
36
+ *
37
+ * @param severity - The error severity ('error', 'warning', or 'hint')
38
+ * @param ruleId - The rule ID (should match rule.id())
39
+ * @param message - The error message
40
+ * @param node - The YAML node where the error occurred (from getRootNode())
41
+ * @returns A validation error object
42
+ *
43
+ * @example
44
+ * ```typescript
45
+ * const error = createValidationError(
46
+ * 'warning',
47
+ * this.id(),
48
+ * 'Operation is missing a summary',
49
+ * operation.getRootNode()
50
+ * );
51
+ * ```
52
+ */
53
+ declare function createValidationError(severity: Severity, ruleId: string, message: string, node: YamlNode | null): ValidationError;
54
+ export { createValidationError };
55
+ //# sourceMappingURL=validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,oBAAoB;IACpB,KAAK,IAAI,MAAM,CAAC;IAEhB,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAC;IAEb,qBAAqB;IACrB,QAAQ,EAAE,QAAQ,CAAC;IAEnB,8BAA8B;IAC9B,aAAa,IAAI,MAAM,CAAC;IAExB,gCAAgC;IAChC,eAAe,IAAI,MAAM,CAAC;CAC3B;AAED;;;GAGG;AACH,MAAM,WAAW,QAAQ;IACvB,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAC;IAEb,qDAAqD;IACrD,IAAI,EAAE,MAAM,CAAC;IAEb,uDAAuD;IACvD,MAAM,EAAE,MAAM,CAAC;IAEf,kCAAkC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,eAAe;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,UAAU,qBAAqB,CACpC,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,QAAQ,GAAG,IAAI,GACpB,eAAe,CAAC;AAEnB,OAAO,EAAE,qBAAqB,EAAE,CAAC"}
@@ -0,0 +1 @@
1
+ export { createValidationError };
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "@speakeasy-api/openapi-linter-types",
3
+ "version": "0.1.0",
4
+ "description": "TypeScript types for writing custom OpenAPI linter rules",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "files": [
8
+ "dist"
9
+ ],
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "prepublishOnly": "npm run build"
13
+ },
14
+ "devDependencies": {
15
+ "typescript": "^5.0.0"
16
+ },
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "https://github.com/speakeasy-api/openapi.git",
20
+ "directory": "openapi/linter/customrules/types"
21
+ },
22
+ "keywords": [
23
+ "openapi",
24
+ "linter",
25
+ "types",
26
+ "typescript",
27
+ "custom-rules"
28
+ ],
29
+ "license": "Apache-2.0",
30
+ "publishConfig": {
31
+ "access": "public"
32
+ }
33
+ }