@skmtc/core 0.0.793 → 0.0.795
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/esm/context/StackTrail.d.ts +293 -0
- package/esm/context/StackTrail.d.ts.map +1 -1
- package/esm/context/StackTrail.js +294 -0
- package/esm/helpers/ResultsLog.d.ts +193 -0
- package/esm/helpers/ResultsLog.d.ts.map +1 -1
- package/esm/helpers/ResultsLog.js +213 -0
- package/esm/helpers/tracer.d.ts +124 -0
- package/esm/helpers/tracer.d.ts.map +1 -1
- package/esm/helpers/tracer.js +124 -0
- package/esm/types/Modifiers.d.ts +68 -0
- package/esm/types/Modifiers.d.ts.map +1 -1
- package/esm/types/TypeSystem.d.ts +419 -0
- package/esm/types/TypeSystem.d.ts.map +1 -1
- package/esm/typescript/FunctionParameter.d.ts +313 -0
- package/esm/typescript/FunctionParameter.d.ts.map +1 -1
- package/esm/typescript/FunctionParameter.js +328 -0
- package/esm/typescript/PathParams.d.ts +198 -0
- package/esm/typescript/PathParams.d.ts.map +1 -1
- package/esm/typescript/PathParams.js +190 -0
- package/esm/typescript/ReactRouterPathParams.d.ts +190 -0
- package/esm/typescript/ReactRouterPathParams.d.ts.map +1 -1
- package/esm/typescript/ReactRouterPathParams.js +183 -0
- package/esm/typescript/keyValues.d.ts +125 -0
- package/esm/typescript/keyValues.d.ts.map +1 -1
- package/esm/typescript/keyValues.js +125 -1
- package/esm/typescript/toPathParams.d.ts +179 -0
- package/esm/typescript/toPathParams.d.ts.map +1 -1
- package/esm/typescript/toPathParams.js +179 -0
- package/esm/typescript/toPathTemplate.d.ts +114 -0
- package/esm/typescript/toPathTemplate.d.ts.map +1 -1
- package/esm/typescript/toPathTemplate.js +114 -0
- package/package.json +1 -1
- package/script/context/StackTrail.d.ts +293 -0
- package/script/context/StackTrail.d.ts.map +1 -1
- package/script/context/StackTrail.js +294 -0
- package/script/helpers/ResultsLog.d.ts +193 -0
- package/script/helpers/ResultsLog.d.ts.map +1 -1
- package/script/helpers/ResultsLog.js +213 -0
- package/script/helpers/tracer.d.ts +124 -0
- package/script/helpers/tracer.d.ts.map +1 -1
- package/script/helpers/tracer.js +124 -0
- package/script/types/Modifiers.d.ts +68 -0
- package/script/types/Modifiers.d.ts.map +1 -1
- package/script/types/TypeSystem.d.ts +419 -0
- package/script/types/TypeSystem.d.ts.map +1 -1
- package/script/typescript/FunctionParameter.d.ts +313 -0
- package/script/typescript/FunctionParameter.d.ts.map +1 -1
- package/script/typescript/FunctionParameter.js +328 -0
- package/script/typescript/PathParams.d.ts +198 -0
- package/script/typescript/PathParams.d.ts.map +1 -1
- package/script/typescript/PathParams.js +190 -0
- package/script/typescript/ReactRouterPathParams.d.ts +190 -0
- package/script/typescript/ReactRouterPathParams.d.ts.map +1 -1
- package/script/typescript/ReactRouterPathParams.js +183 -0
- package/script/typescript/keyValues.d.ts +125 -0
- package/script/typescript/keyValues.d.ts.map +1 -1
- package/script/typescript/keyValues.js +125 -1
- package/script/typescript/toPathParams.d.ts +179 -0
- package/script/typescript/toPathParams.d.ts.map +1 -1
- package/script/typescript/toPathParams.js +179 -0
- package/script/typescript/toPathTemplate.d.ts +114 -0
- package/script/typescript/toPathTemplate.d.ts.map +1 -1
- package/script/typescript/toPathTemplate.js +114 -0
|
@@ -2,26 +2,216 @@ import { Definition } from '../dsl/Definition.js';
|
|
|
2
2
|
import { Identifier } from '../dsl/Identifier.js';
|
|
3
3
|
import { FunctionParameter } from './FunctionParameter.js';
|
|
4
4
|
import { toPathTemplate } from './toPathTemplate.js';
|
|
5
|
+
/**
|
|
6
|
+
* Manages path parameter type definitions and function parameters for API endpoints.
|
|
7
|
+
*
|
|
8
|
+
* `PathParams` is a utility class that combines type generation, function parameter
|
|
9
|
+
* handling, and path templating for OpenAPI path parameters. It creates TypeScript
|
|
10
|
+
* type definitions for path parameters and generates the corresponding function
|
|
11
|
+
* parameters that can be used in API client methods.
|
|
12
|
+
*
|
|
13
|
+
* This class is essential for generating type-safe API clients where path parameters
|
|
14
|
+
* are properly typed and validated at compile time. It handles both destructured
|
|
15
|
+
* parameters (when no argument name is provided) and named parameters.
|
|
16
|
+
*
|
|
17
|
+
* ## Key Features
|
|
18
|
+
*
|
|
19
|
+
* - **Type Definition Generation**: Creates TypeScript types for path parameters
|
|
20
|
+
* - **Function Parameter Integration**: Generates properly typed function parameters
|
|
21
|
+
* - **Path Template Processing**: Converts OpenAPI paths to template literals
|
|
22
|
+
* - **Destructuring Support**: Handles both named and destructured parameter patterns
|
|
23
|
+
* - **Context Integration**: Fully integrated with the SKMTC generation pipeline
|
|
24
|
+
*
|
|
25
|
+
* @example Basic path parameters with destructuring
|
|
26
|
+
* ```typescript
|
|
27
|
+
* import { PathParams } from '@skmtc/core';
|
|
28
|
+
*
|
|
29
|
+
* const pathParams = new PathParams({
|
|
30
|
+
* context: generateContext,
|
|
31
|
+
* typeName: 'GetUserParams',
|
|
32
|
+
* typeValue: {
|
|
33
|
+
* type: 'object',
|
|
34
|
+
* objectProperties: {
|
|
35
|
+
* properties: {
|
|
36
|
+
* id: { type: 'string' },
|
|
37
|
+
* format: { type: 'string' }
|
|
38
|
+
* }
|
|
39
|
+
* }
|
|
40
|
+
* },
|
|
41
|
+
* pathTemplate: '/users/{id}'
|
|
42
|
+
* });
|
|
43
|
+
*
|
|
44
|
+
* console.log(pathParams.path); // '/users/${id}'
|
|
45
|
+
* ```
|
|
46
|
+
*
|
|
47
|
+
* @example Named parameter usage
|
|
48
|
+
* ```typescript
|
|
49
|
+
* const namedPathParams = new PathParams({
|
|
50
|
+
* context: generateContext,
|
|
51
|
+
* argName: 'params',
|
|
52
|
+
* typeName: 'UserPathParams',
|
|
53
|
+
* typeValue: {
|
|
54
|
+
* type: 'object',
|
|
55
|
+
* objectProperties: {
|
|
56
|
+
* properties: {
|
|
57
|
+
* userId: { type: 'string' },
|
|
58
|
+
* projectId: { type: 'string' }
|
|
59
|
+
* }
|
|
60
|
+
* }
|
|
61
|
+
* },
|
|
62
|
+
* pathTemplate: '/users/{userId}/projects/{projectId}'
|
|
63
|
+
* });
|
|
64
|
+
*
|
|
65
|
+
* console.log(pathParams.path); // '/users/${params.userId}/projects/${params.projectId}'
|
|
66
|
+
* ```
|
|
67
|
+
*
|
|
68
|
+
* @example API client method generation
|
|
69
|
+
* ```typescript
|
|
70
|
+
* class ApiMethodGenerator {
|
|
71
|
+
* generateGetMethod(operationPath: string, parameters: any) {
|
|
72
|
+
* const pathParams = new PathParams({
|
|
73
|
+
* context: this.context,
|
|
74
|
+
* argName: 'pathParams',
|
|
75
|
+
* typeName: 'PathParameters',
|
|
76
|
+
* typeValue: parameters,
|
|
77
|
+
* pathTemplate: operationPath
|
|
78
|
+
* });
|
|
79
|
+
*
|
|
80
|
+
* return `
|
|
81
|
+
* async getData(${pathParams.parameter.toString()}) {
|
|
82
|
+
* const url = \`${pathParams.path}\`;
|
|
83
|
+
* return this.client.get(url);
|
|
84
|
+
* }`;
|
|
85
|
+
* }
|
|
86
|
+
* }
|
|
87
|
+
*
|
|
88
|
+
* // Generates:
|
|
89
|
+
* // async getData(pathParams: PathParameters) {
|
|
90
|
+
* // const url = `/users/${pathParams.userId}/projects/${pathParams.projectId}`;
|
|
91
|
+
* // return this.client.get(url);
|
|
92
|
+
* // }
|
|
93
|
+
* ```
|
|
94
|
+
*
|
|
95
|
+
* @example With destructured parameters
|
|
96
|
+
* ```typescript
|
|
97
|
+
* const destructuredParams = new PathParams({
|
|
98
|
+
* context: generateContext,
|
|
99
|
+
* // No argName provided, so uses destructuring
|
|
100
|
+
* typeName: 'OrderParams',
|
|
101
|
+
* typeValue: {
|
|
102
|
+
* type: 'object',
|
|
103
|
+
* objectProperties: {
|
|
104
|
+
* properties: {
|
|
105
|
+
* orderId: { type: 'string' },
|
|
106
|
+
* customerId: { type: 'string' }
|
|
107
|
+
* }
|
|
108
|
+
* }
|
|
109
|
+
* },
|
|
110
|
+
* pathTemplate: '/customers/{customerId}/orders/{orderId}'
|
|
111
|
+
* });
|
|
112
|
+
*
|
|
113
|
+
* // Function parameter will be: { orderId, customerId }: OrderParams
|
|
114
|
+
* // Path template will be: '/customers/${customerId}/orders/${orderId}'
|
|
115
|
+
* ```
|
|
116
|
+
*
|
|
117
|
+
* @example Complex nested path parameters
|
|
118
|
+
* ```typescript
|
|
119
|
+
* const complexPathParams = new PathParams({
|
|
120
|
+
* context: generateContext,
|
|
121
|
+
* argName: 'pathData',
|
|
122
|
+
* typeName: 'ComplexPathParams',
|
|
123
|
+
* typeValue: {
|
|
124
|
+
* type: 'object',
|
|
125
|
+
* objectProperties: {
|
|
126
|
+
* properties: {
|
|
127
|
+
* orgId: { type: 'string' },
|
|
128
|
+
* projectId: { type: 'string' },
|
|
129
|
+
* issueId: { type: 'number' },
|
|
130
|
+
* commentId: { type: 'string' }
|
|
131
|
+
* }
|
|
132
|
+
* }
|
|
133
|
+
* },
|
|
134
|
+
* pathTemplate: '/orgs/{orgId}/projects/{projectId}/issues/{issueId}/comments/{commentId}'
|
|
135
|
+
* });
|
|
136
|
+
*
|
|
137
|
+
* // Generates path: '/orgs/${pathData.orgId}/projects/${pathData.projectId}/issues/${pathData.issueId}/comments/${pathData.commentId}'
|
|
138
|
+
* ```
|
|
139
|
+
*
|
|
140
|
+
* @example Integration with operation generation
|
|
141
|
+
* ```typescript
|
|
142
|
+
* class OperationGenerator {
|
|
143
|
+
* generateOperation(operation: OasOperation) {
|
|
144
|
+
* const pathParameters = this.extractPathParameters(operation);
|
|
145
|
+
*
|
|
146
|
+
* if (pathParameters.length > 0) {
|
|
147
|
+
* const pathParams = new PathParams({
|
|
148
|
+
* context: this.context,
|
|
149
|
+
* typeName: `${operation.operationId}PathParams`,
|
|
150
|
+
* typeValue: this.buildParametersType(pathParameters),
|
|
151
|
+
* pathTemplate: operation.path
|
|
152
|
+
* });
|
|
153
|
+
*
|
|
154
|
+
* return this.generateMethodWithPathParams(operation, pathParams);
|
|
155
|
+
* }
|
|
156
|
+
*
|
|
157
|
+
* return this.generateSimpleMethod(operation);
|
|
158
|
+
* }
|
|
159
|
+
* }
|
|
160
|
+
* ```
|
|
161
|
+
*/
|
|
5
162
|
export class PathParams {
|
|
163
|
+
/**
|
|
164
|
+
* Creates a new PathParams instance with type definitions and path processing.
|
|
165
|
+
*
|
|
166
|
+
* The constructor sets up the complete parameter handling pipeline:
|
|
167
|
+
* 1. Creates a TypeScript type definition for the parameters
|
|
168
|
+
* 2. Generates a function parameter (either named or destructured)
|
|
169
|
+
* 3. Processes the path template for runtime interpolation
|
|
170
|
+
*
|
|
171
|
+
* @param args - Configuration for path parameter generation
|
|
172
|
+
*
|
|
173
|
+
* @example
|
|
174
|
+
* ```typescript
|
|
175
|
+
* const pathParams = new PathParams({
|
|
176
|
+
* context: generateContext,
|
|
177
|
+
* argName: 'params',
|
|
178
|
+
* typeName: 'UserPathParams',
|
|
179
|
+
* typeValue: {
|
|
180
|
+
* type: 'object',
|
|
181
|
+
* objectProperties: {
|
|
182
|
+
* properties: {
|
|
183
|
+
* id: { type: 'string' },
|
|
184
|
+
* format: { type: 'string' }
|
|
185
|
+
* }
|
|
186
|
+
* }
|
|
187
|
+
* },
|
|
188
|
+
* pathTemplate: '/users/{id}/profile'
|
|
189
|
+
* });
|
|
190
|
+
* ```
|
|
191
|
+
*/
|
|
6
192
|
constructor({ context, argName, typeName, typeValue, pathTemplate }) {
|
|
193
|
+
/** The generation context used for type registration and imports */
|
|
7
194
|
Object.defineProperty(this, "context", {
|
|
8
195
|
enumerable: true,
|
|
9
196
|
configurable: true,
|
|
10
197
|
writable: true,
|
|
11
198
|
value: void 0
|
|
12
199
|
});
|
|
200
|
+
/** The TypeScript type definition for the path parameters */
|
|
13
201
|
Object.defineProperty(this, "typeDefinition", {
|
|
14
202
|
enumerable: true,
|
|
15
203
|
configurable: true,
|
|
16
204
|
writable: true,
|
|
17
205
|
value: void 0
|
|
18
206
|
});
|
|
207
|
+
/** The function parameter representation for method signatures */
|
|
19
208
|
Object.defineProperty(this, "parameter", {
|
|
20
209
|
enumerable: true,
|
|
21
210
|
configurable: true,
|
|
22
211
|
writable: true,
|
|
23
212
|
value: void 0
|
|
24
213
|
});
|
|
214
|
+
/** The processed path template with parameter substitutions */
|
|
25
215
|
Object.defineProperty(this, "path", {
|
|
26
216
|
enumerable: true,
|
|
27
217
|
configurable: true,
|
|
@@ -2,18 +2,208 @@ import { ContentBase } from '../dsl/ContentBase.js';
|
|
|
2
2
|
import type { GenerateContext } from '../context/GenerateContext.js';
|
|
3
3
|
import type { OasOperation } from '../oas/operation/Operation.js';
|
|
4
4
|
import type { GeneratorKey } from '../types/GeneratorKeys.js';
|
|
5
|
+
/**
|
|
6
|
+
* Constructor arguments for {@link ReactRouterPathParams}.
|
|
7
|
+
*/
|
|
5
8
|
type CreateArgs = {
|
|
9
|
+
/** The generation context for registering imports and handling dependencies */
|
|
6
10
|
context: GenerateContext;
|
|
11
|
+
/** The generator key identifying this component */
|
|
7
12
|
generatorKey: GeneratorKey;
|
|
13
|
+
/** The OpenAPI operation containing path parameters */
|
|
8
14
|
operation: OasOperation;
|
|
15
|
+
/** The destination file path for import registration */
|
|
9
16
|
destinationPath: string;
|
|
10
17
|
};
|
|
18
|
+
/**
|
|
19
|
+
* Generates React Router path parameter handling code for OpenAPI operations.
|
|
20
|
+
*
|
|
21
|
+
* `ReactRouterPathParams` is a specialized content generator that creates the necessary
|
|
22
|
+
* React code for extracting and validating path parameters from React Router's `useParams`
|
|
23
|
+
* hook. It automatically generates parameter extraction, assertion logic, and prop passing
|
|
24
|
+
* code based on OpenAPI operation path parameters.
|
|
25
|
+
*
|
|
26
|
+
* This class is essential for generating type-safe React components that need to access
|
|
27
|
+
* URL path parameters, ensuring runtime validation and proper TypeScript typing. It
|
|
28
|
+
* integrates with React Router's `useParams` hook and adds runtime assertions using
|
|
29
|
+
* the `tiny-invariant` library.
|
|
30
|
+
*
|
|
31
|
+
* ## Key Features
|
|
32
|
+
*
|
|
33
|
+
* - **Automatic Parameter Extraction**: Generates `useParams()` destructuring code
|
|
34
|
+
* - **Runtime Assertions**: Creates invariant checks for required parameters
|
|
35
|
+
* - **Prop Passing**: Generates prop spreading syntax for component integration
|
|
36
|
+
* - **Import Management**: Automatically registers required imports
|
|
37
|
+
* - **Type Safety**: Ensures parameters are properly validated at runtime
|
|
38
|
+
*
|
|
39
|
+
* @example Basic usage with single path parameter
|
|
40
|
+
* ```typescript
|
|
41
|
+
* import { ReactRouterPathParams } from '@skmtc/core';
|
|
42
|
+
*
|
|
43
|
+
* const operation = new OasOperation({
|
|
44
|
+
* path: '/users/{id}',
|
|
45
|
+
* method: 'get',
|
|
46
|
+
* // ... other operation properties
|
|
47
|
+
* });
|
|
48
|
+
*
|
|
49
|
+
* const pathParams = new ReactRouterPathParams({
|
|
50
|
+
* context: generateContext,
|
|
51
|
+
* generatorKey: 'react-router-params',
|
|
52
|
+
* operation,
|
|
53
|
+
* destinationPath: './UserDetail.tsx'
|
|
54
|
+
* });
|
|
55
|
+
*
|
|
56
|
+
* console.log(pathParams.getParams);
|
|
57
|
+
* // 'const { id } = useParams()'
|
|
58
|
+
*
|
|
59
|
+
* console.log(pathParams.assertParams);
|
|
60
|
+
* // 'invariant(id, 'Expected id to be defined')'
|
|
61
|
+
*
|
|
62
|
+
* console.log(pathParams.passProps);
|
|
63
|
+
* // 'id={id}'
|
|
64
|
+
* ```
|
|
65
|
+
*
|
|
66
|
+
* @example Multiple path parameters
|
|
67
|
+
* ```typescript
|
|
68
|
+
* const complexOperation = new OasOperation({
|
|
69
|
+
* path: '/organizations/{orgId}/projects/{projectId}/issues/{issueId}',
|
|
70
|
+
* method: 'get',
|
|
71
|
+
* // ... other properties
|
|
72
|
+
* });
|
|
73
|
+
*
|
|
74
|
+
* const multiParams = new ReactRouterPathParams({
|
|
75
|
+
* context: generateContext,
|
|
76
|
+
* generatorKey: 'react-router-params',
|
|
77
|
+
* operation: complexOperation,
|
|
78
|
+
* destinationPath: './IssueDetail.tsx'
|
|
79
|
+
* });
|
|
80
|
+
*
|
|
81
|
+
* console.log(multiParams.getParams);
|
|
82
|
+
* // 'const { orgId, projectId, issueId } = useParams()'
|
|
83
|
+
*
|
|
84
|
+
* console.log(multiParams.assertParams);
|
|
85
|
+
* // 'invariant(orgId, 'Expected orgId to be defined')
|
|
86
|
+
* // invariant(projectId, 'Expected projectId to be defined')
|
|
87
|
+
* // invariant(issueId, 'Expected issueId to be defined')'
|
|
88
|
+
*
|
|
89
|
+
* console.log(multiParams.passProps);
|
|
90
|
+
* // 'orgId={orgId} projectId={projectId} issueId={issueId}'
|
|
91
|
+
* ```
|
|
92
|
+
*
|
|
93
|
+
* @example Generated React component integration
|
|
94
|
+
* ```typescript
|
|
95
|
+
* // Generated component might look like:
|
|
96
|
+
* import { useParams } from 'react-router-dom';
|
|
97
|
+
* import invariant from 'tiny-invariant';
|
|
98
|
+
*
|
|
99
|
+
* function UserDetail() {
|
|
100
|
+
* const { id } = useParams();
|
|
101
|
+
* invariant(id, 'Expected id to be defined');
|
|
102
|
+
*
|
|
103
|
+
* return <UserDetailView id={id} />;
|
|
104
|
+
* }
|
|
105
|
+
* ```
|
|
106
|
+
*
|
|
107
|
+
* @example No path parameters (empty generation)
|
|
108
|
+
* ```typescript
|
|
109
|
+
* const simpleOperation = new OasOperation({
|
|
110
|
+
* path: '/users',
|
|
111
|
+
* method: 'get',
|
|
112
|
+
* // ... other properties
|
|
113
|
+
* });
|
|
114
|
+
*
|
|
115
|
+
* const emptyParams = new ReactRouterPathParams({
|
|
116
|
+
* context: generateContext,
|
|
117
|
+
* generatorKey: 'react-router-params',
|
|
118
|
+
* operation: simpleOperation,
|
|
119
|
+
* destinationPath: './UserList.tsx'
|
|
120
|
+
* });
|
|
121
|
+
*
|
|
122
|
+
* console.log(emptyParams.getParams); // ''
|
|
123
|
+
* console.log(emptyParams.assertParams); // ''
|
|
124
|
+
* console.log(emptyParams.passProps); // ''
|
|
125
|
+
* // No imports registered for this case
|
|
126
|
+
* ```
|
|
127
|
+
*
|
|
128
|
+
* @example Integration in component generation
|
|
129
|
+
* ```typescript
|
|
130
|
+
* class ReactComponentGenerator {
|
|
131
|
+
* generateDetailComponent(operation: OasOperation) {
|
|
132
|
+
* const pathParams = new ReactRouterPathParams({
|
|
133
|
+
* context: this.context,
|
|
134
|
+
* generatorKey: 'react-component',
|
|
135
|
+
* operation,
|
|
136
|
+
* destinationPath: this.getDestinationPath(operation)
|
|
137
|
+
* });
|
|
138
|
+
*
|
|
139
|
+
* if (pathParams.names.length === 0) {
|
|
140
|
+
* // Generate simple component without parameters
|
|
141
|
+
* return this.generateSimpleComponent(operation);
|
|
142
|
+
* }
|
|
143
|
+
*
|
|
144
|
+
* return `
|
|
145
|
+
* function ${operation.operationId}() {
|
|
146
|
+
* ${pathParams.getParams}
|
|
147
|
+
* ${pathParams.assertParams}
|
|
148
|
+
*
|
|
149
|
+
* return (
|
|
150
|
+
* <DetailView ${pathParams.passProps} />
|
|
151
|
+
* );
|
|
152
|
+
* }`;
|
|
153
|
+
* }
|
|
154
|
+
* }
|
|
155
|
+
* ```
|
|
156
|
+
*
|
|
157
|
+
* @example Custom parameter validation
|
|
158
|
+
* ```typescript
|
|
159
|
+
* class CustomReactRouterParams extends ReactRouterPathParams {
|
|
160
|
+
* generateCustomAssertions(paramName: string): string {
|
|
161
|
+
* return `
|
|
162
|
+
* invariant(${paramName}, 'Expected ${paramName} to be defined');
|
|
163
|
+
* invariant(typeof ${paramName} === 'string', '${paramName} must be a string');
|
|
164
|
+
* invariant(${paramName}.length > 0, '${paramName} cannot be empty');`;
|
|
165
|
+
* }
|
|
166
|
+
* }
|
|
167
|
+
* ```
|
|
168
|
+
*/
|
|
11
169
|
export declare class ReactRouterPathParams extends ContentBase {
|
|
170
|
+
/** Generated code for extracting parameters from useParams() */
|
|
12
171
|
getParams: string;
|
|
172
|
+
/** Generated code for runtime parameter assertions */
|
|
13
173
|
assertParams: string;
|
|
174
|
+
/** Generated code for passing parameters as component props */
|
|
14
175
|
passProps: string;
|
|
176
|
+
/** Array of parameter names extracted from the operation path */
|
|
15
177
|
names: string[];
|
|
178
|
+
/**
|
|
179
|
+
* Creates a new ReactRouterPathParams instance with generated parameter handling code.
|
|
180
|
+
*
|
|
181
|
+
* The constructor analyzes the OpenAPI operation to extract path parameters and
|
|
182
|
+
* generates the necessary React code for parameter extraction, validation, and
|
|
183
|
+
* prop passing. It automatically registers required imports when parameters are present.
|
|
184
|
+
*
|
|
185
|
+
* @param args - Configuration for React Router parameter generation
|
|
186
|
+
*
|
|
187
|
+
* @example
|
|
188
|
+
* ```typescript
|
|
189
|
+
* const pathParams = new ReactRouterPathParams({
|
|
190
|
+
* context: generateContext,
|
|
191
|
+
* generatorKey: 'react-params',
|
|
192
|
+
* operation: userDetailOperation, // has path '/users/{id}'
|
|
193
|
+
* destinationPath: './UserDetail.tsx'
|
|
194
|
+
* });
|
|
195
|
+
* ```
|
|
196
|
+
*/
|
|
16
197
|
constructor({ context, operation, generatorKey, destinationPath }: CreateArgs);
|
|
198
|
+
/**
|
|
199
|
+
* Returns an empty string as this class provides code through its properties.
|
|
200
|
+
*
|
|
201
|
+
* The ReactRouterPathParams class doesn't generate output through toString(),
|
|
202
|
+
* instead providing generated code through the `getParams`, `assertParams`,
|
|
203
|
+
* and `passProps` properties which can be used directly in template generation.
|
|
204
|
+
*
|
|
205
|
+
* @returns Empty string
|
|
206
|
+
*/
|
|
17
207
|
toString(): string;
|
|
18
208
|
}
|
|
19
209
|
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReactRouterPathParams.d.ts","sourceRoot":"","sources":["../../src/typescript/ReactRouterPathParams.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAA;AACpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAA;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAE7D,KAAK,UAAU,GAAG;IAChB,OAAO,EAAE,eAAe,CAAA;IACxB,YAAY,EAAE,YAAY,CAAA;IAC1B,SAAS,EAAE,YAAY,CAAA;IACvB,eAAe,EAAE,MAAM,CAAA;CACxB,CAAA;AAED,qBAAa,qBAAsB,SAAQ,WAAW;IACpD,SAAS,EAAE,MAAM,CAAK;IAEtB,YAAY,EAAE,MAAM,CAAK;IAEzB,SAAS,EAAE,MAAM,CAAK;IAEtB,KAAK,EAAE,MAAM,EAAE,CAAA;
|
|
1
|
+
{"version":3,"file":"ReactRouterPathParams.d.ts","sourceRoot":"","sources":["../../src/typescript/ReactRouterPathParams.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAA;AACpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAA;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAE7D;;GAEG;AACH,KAAK,UAAU,GAAG;IAChB,+EAA+E;IAC/E,OAAO,EAAE,eAAe,CAAA;IACxB,mDAAmD;IACnD,YAAY,EAAE,YAAY,CAAA;IAC1B,uDAAuD;IACvD,SAAS,EAAE,YAAY,CAAA;IACvB,wDAAwD;IACxD,eAAe,EAAE,MAAM,CAAA;CACxB,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsJG;AACH,qBAAa,qBAAsB,SAAQ,WAAW;IACpD,gEAAgE;IAChE,SAAS,EAAE,MAAM,CAAK;IAEtB,sDAAsD;IACtD,YAAY,EAAE,MAAM,CAAK;IAEzB,+DAA+D;IAC/D,SAAS,EAAE,MAAM,CAAK;IAEtB,iEAAiE;IACjE,KAAK,EAAE,MAAM,EAAE,CAAA;IAEf;;;;;;;;;;;;;;;;;;OAkBG;gBACS,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,eAAe,EAAE,EAAE,UAAU;IAwB7E;;;;;;;;OAQG;IACM,QAAQ,IAAI,MAAM;CAG5B"}
|
|
@@ -1,25 +1,199 @@
|
|
|
1
1
|
import { ContentBase } from '../dsl/ContentBase.js';
|
|
2
|
+
/**
|
|
3
|
+
* Generates React Router path parameter handling code for OpenAPI operations.
|
|
4
|
+
*
|
|
5
|
+
* `ReactRouterPathParams` is a specialized content generator that creates the necessary
|
|
6
|
+
* React code for extracting and validating path parameters from React Router's `useParams`
|
|
7
|
+
* hook. It automatically generates parameter extraction, assertion logic, and prop passing
|
|
8
|
+
* code based on OpenAPI operation path parameters.
|
|
9
|
+
*
|
|
10
|
+
* This class is essential for generating type-safe React components that need to access
|
|
11
|
+
* URL path parameters, ensuring runtime validation and proper TypeScript typing. It
|
|
12
|
+
* integrates with React Router's `useParams` hook and adds runtime assertions using
|
|
13
|
+
* the `tiny-invariant` library.
|
|
14
|
+
*
|
|
15
|
+
* ## Key Features
|
|
16
|
+
*
|
|
17
|
+
* - **Automatic Parameter Extraction**: Generates `useParams()` destructuring code
|
|
18
|
+
* - **Runtime Assertions**: Creates invariant checks for required parameters
|
|
19
|
+
* - **Prop Passing**: Generates prop spreading syntax for component integration
|
|
20
|
+
* - **Import Management**: Automatically registers required imports
|
|
21
|
+
* - **Type Safety**: Ensures parameters are properly validated at runtime
|
|
22
|
+
*
|
|
23
|
+
* @example Basic usage with single path parameter
|
|
24
|
+
* ```typescript
|
|
25
|
+
* import { ReactRouterPathParams } from '@skmtc/core';
|
|
26
|
+
*
|
|
27
|
+
* const operation = new OasOperation({
|
|
28
|
+
* path: '/users/{id}',
|
|
29
|
+
* method: 'get',
|
|
30
|
+
* // ... other operation properties
|
|
31
|
+
* });
|
|
32
|
+
*
|
|
33
|
+
* const pathParams = new ReactRouterPathParams({
|
|
34
|
+
* context: generateContext,
|
|
35
|
+
* generatorKey: 'react-router-params',
|
|
36
|
+
* operation,
|
|
37
|
+
* destinationPath: './UserDetail.tsx'
|
|
38
|
+
* });
|
|
39
|
+
*
|
|
40
|
+
* console.log(pathParams.getParams);
|
|
41
|
+
* // 'const { id } = useParams()'
|
|
42
|
+
*
|
|
43
|
+
* console.log(pathParams.assertParams);
|
|
44
|
+
* // 'invariant(id, 'Expected id to be defined')'
|
|
45
|
+
*
|
|
46
|
+
* console.log(pathParams.passProps);
|
|
47
|
+
* // 'id={id}'
|
|
48
|
+
* ```
|
|
49
|
+
*
|
|
50
|
+
* @example Multiple path parameters
|
|
51
|
+
* ```typescript
|
|
52
|
+
* const complexOperation = new OasOperation({
|
|
53
|
+
* path: '/organizations/{orgId}/projects/{projectId}/issues/{issueId}',
|
|
54
|
+
* method: 'get',
|
|
55
|
+
* // ... other properties
|
|
56
|
+
* });
|
|
57
|
+
*
|
|
58
|
+
* const multiParams = new ReactRouterPathParams({
|
|
59
|
+
* context: generateContext,
|
|
60
|
+
* generatorKey: 'react-router-params',
|
|
61
|
+
* operation: complexOperation,
|
|
62
|
+
* destinationPath: './IssueDetail.tsx'
|
|
63
|
+
* });
|
|
64
|
+
*
|
|
65
|
+
* console.log(multiParams.getParams);
|
|
66
|
+
* // 'const { orgId, projectId, issueId } = useParams()'
|
|
67
|
+
*
|
|
68
|
+
* console.log(multiParams.assertParams);
|
|
69
|
+
* // 'invariant(orgId, 'Expected orgId to be defined')
|
|
70
|
+
* // invariant(projectId, 'Expected projectId to be defined')
|
|
71
|
+
* // invariant(issueId, 'Expected issueId to be defined')'
|
|
72
|
+
*
|
|
73
|
+
* console.log(multiParams.passProps);
|
|
74
|
+
* // 'orgId={orgId} projectId={projectId} issueId={issueId}'
|
|
75
|
+
* ```
|
|
76
|
+
*
|
|
77
|
+
* @example Generated React component integration
|
|
78
|
+
* ```typescript
|
|
79
|
+
* // Generated component might look like:
|
|
80
|
+
* import { useParams } from 'react-router-dom';
|
|
81
|
+
* import invariant from 'tiny-invariant';
|
|
82
|
+
*
|
|
83
|
+
* function UserDetail() {
|
|
84
|
+
* const { id } = useParams();
|
|
85
|
+
* invariant(id, 'Expected id to be defined');
|
|
86
|
+
*
|
|
87
|
+
* return <UserDetailView id={id} />;
|
|
88
|
+
* }
|
|
89
|
+
* ```
|
|
90
|
+
*
|
|
91
|
+
* @example No path parameters (empty generation)
|
|
92
|
+
* ```typescript
|
|
93
|
+
* const simpleOperation = new OasOperation({
|
|
94
|
+
* path: '/users',
|
|
95
|
+
* method: 'get',
|
|
96
|
+
* // ... other properties
|
|
97
|
+
* });
|
|
98
|
+
*
|
|
99
|
+
* const emptyParams = new ReactRouterPathParams({
|
|
100
|
+
* context: generateContext,
|
|
101
|
+
* generatorKey: 'react-router-params',
|
|
102
|
+
* operation: simpleOperation,
|
|
103
|
+
* destinationPath: './UserList.tsx'
|
|
104
|
+
* });
|
|
105
|
+
*
|
|
106
|
+
* console.log(emptyParams.getParams); // ''
|
|
107
|
+
* console.log(emptyParams.assertParams); // ''
|
|
108
|
+
* console.log(emptyParams.passProps); // ''
|
|
109
|
+
* // No imports registered for this case
|
|
110
|
+
* ```
|
|
111
|
+
*
|
|
112
|
+
* @example Integration in component generation
|
|
113
|
+
* ```typescript
|
|
114
|
+
* class ReactComponentGenerator {
|
|
115
|
+
* generateDetailComponent(operation: OasOperation) {
|
|
116
|
+
* const pathParams = new ReactRouterPathParams({
|
|
117
|
+
* context: this.context,
|
|
118
|
+
* generatorKey: 'react-component',
|
|
119
|
+
* operation,
|
|
120
|
+
* destinationPath: this.getDestinationPath(operation)
|
|
121
|
+
* });
|
|
122
|
+
*
|
|
123
|
+
* if (pathParams.names.length === 0) {
|
|
124
|
+
* // Generate simple component without parameters
|
|
125
|
+
* return this.generateSimpleComponent(operation);
|
|
126
|
+
* }
|
|
127
|
+
*
|
|
128
|
+
* return `
|
|
129
|
+
* function ${operation.operationId}() {
|
|
130
|
+
* ${pathParams.getParams}
|
|
131
|
+
* ${pathParams.assertParams}
|
|
132
|
+
*
|
|
133
|
+
* return (
|
|
134
|
+
* <DetailView ${pathParams.passProps} />
|
|
135
|
+
* );
|
|
136
|
+
* }`;
|
|
137
|
+
* }
|
|
138
|
+
* }
|
|
139
|
+
* ```
|
|
140
|
+
*
|
|
141
|
+
* @example Custom parameter validation
|
|
142
|
+
* ```typescript
|
|
143
|
+
* class CustomReactRouterParams extends ReactRouterPathParams {
|
|
144
|
+
* generateCustomAssertions(paramName: string): string {
|
|
145
|
+
* return `
|
|
146
|
+
* invariant(${paramName}, 'Expected ${paramName} to be defined');
|
|
147
|
+
* invariant(typeof ${paramName} === 'string', '${paramName} must be a string');
|
|
148
|
+
* invariant(${paramName}.length > 0, '${paramName} cannot be empty');`;
|
|
149
|
+
* }
|
|
150
|
+
* }
|
|
151
|
+
* ```
|
|
152
|
+
*/
|
|
2
153
|
export class ReactRouterPathParams extends ContentBase {
|
|
154
|
+
/**
|
|
155
|
+
* Creates a new ReactRouterPathParams instance with generated parameter handling code.
|
|
156
|
+
*
|
|
157
|
+
* The constructor analyzes the OpenAPI operation to extract path parameters and
|
|
158
|
+
* generates the necessary React code for parameter extraction, validation, and
|
|
159
|
+
* prop passing. It automatically registers required imports when parameters are present.
|
|
160
|
+
*
|
|
161
|
+
* @param args - Configuration for React Router parameter generation
|
|
162
|
+
*
|
|
163
|
+
* @example
|
|
164
|
+
* ```typescript
|
|
165
|
+
* const pathParams = new ReactRouterPathParams({
|
|
166
|
+
* context: generateContext,
|
|
167
|
+
* generatorKey: 'react-params',
|
|
168
|
+
* operation: userDetailOperation, // has path '/users/{id}'
|
|
169
|
+
* destinationPath: './UserDetail.tsx'
|
|
170
|
+
* });
|
|
171
|
+
* ```
|
|
172
|
+
*/
|
|
3
173
|
constructor({ context, operation, generatorKey, destinationPath }) {
|
|
4
174
|
super({ context, generatorKey });
|
|
175
|
+
/** Generated code for extracting parameters from useParams() */
|
|
5
176
|
Object.defineProperty(this, "getParams", {
|
|
6
177
|
enumerable: true,
|
|
7
178
|
configurable: true,
|
|
8
179
|
writable: true,
|
|
9
180
|
value: ''
|
|
10
181
|
});
|
|
182
|
+
/** Generated code for runtime parameter assertions */
|
|
11
183
|
Object.defineProperty(this, "assertParams", {
|
|
12
184
|
enumerable: true,
|
|
13
185
|
configurable: true,
|
|
14
186
|
writable: true,
|
|
15
187
|
value: ''
|
|
16
188
|
});
|
|
189
|
+
/** Generated code for passing parameters as component props */
|
|
17
190
|
Object.defineProperty(this, "passProps", {
|
|
18
191
|
enumerable: true,
|
|
19
192
|
configurable: true,
|
|
20
193
|
writable: true,
|
|
21
194
|
value: ''
|
|
22
195
|
});
|
|
196
|
+
/** Array of parameter names extracted from the operation path */
|
|
23
197
|
Object.defineProperty(this, "names", {
|
|
24
198
|
enumerable: true,
|
|
25
199
|
configurable: true,
|
|
@@ -43,6 +217,15 @@ export class ReactRouterPathParams extends ContentBase {
|
|
|
43
217
|
});
|
|
44
218
|
}
|
|
45
219
|
}
|
|
220
|
+
/**
|
|
221
|
+
* Returns an empty string as this class provides code through its properties.
|
|
222
|
+
*
|
|
223
|
+
* The ReactRouterPathParams class doesn't generate output through toString(),
|
|
224
|
+
* instead providing generated code through the `getParams`, `assertParams`,
|
|
225
|
+
* and `passProps` properties which can be used directly in template generation.
|
|
226
|
+
*
|
|
227
|
+
* @returns Empty string
|
|
228
|
+
*/
|
|
46
229
|
toString() {
|
|
47
230
|
return ``;
|
|
48
231
|
}
|