@intrig/plugin-react 0.0.1 → 0.0.2-0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/package.json +6 -3
  2. package/.swcrc +0 -29
  3. package/eslint.config.mjs +0 -19
  4. package/project.json +0 -29
  5. package/rollup.config.cjs +0 -54
  6. package/rollup.config.mjs +0 -33
  7. package/src/index.ts +0 -2
  8. package/src/lib/code-generator.ts +0 -79
  9. package/src/lib/get-endpoint-documentation.ts +0 -35
  10. package/src/lib/get-schema-documentation.ts +0 -11
  11. package/src/lib/internal-types.ts +0 -15
  12. package/src/lib/plugin-react.ts +0 -22
  13. package/src/lib/templates/context.template.ts +0 -74
  14. package/src/lib/templates/docs/__snapshots__/async-hook.spec.ts.snap +0 -889
  15. package/src/lib/templates/docs/__snapshots__/download-hook.spec.ts.snap +0 -1445
  16. package/src/lib/templates/docs/__snapshots__/react-hook.spec.ts.snap +0 -1371
  17. package/src/lib/templates/docs/__snapshots__/sse-hook.spec.ts.snap +0 -2008
  18. package/src/lib/templates/docs/async-hook.spec.ts +0 -92
  19. package/src/lib/templates/docs/async-hook.ts +0 -226
  20. package/src/lib/templates/docs/download-hook.spec.ts +0 -182
  21. package/src/lib/templates/docs/download-hook.ts +0 -170
  22. package/src/lib/templates/docs/react-hook.spec.ts +0 -97
  23. package/src/lib/templates/docs/react-hook.ts +0 -323
  24. package/src/lib/templates/docs/schema.ts +0 -105
  25. package/src/lib/templates/docs/sse-hook.spec.ts +0 -207
  26. package/src/lib/templates/docs/sse-hook.ts +0 -221
  27. package/src/lib/templates/extra.template.ts +0 -198
  28. package/src/lib/templates/index.template.ts +0 -14
  29. package/src/lib/templates/intrigMiddleware.template.ts +0 -21
  30. package/src/lib/templates/logger.template.ts +0 -67
  31. package/src/lib/templates/media-type-utils.template.ts +0 -191
  32. package/src/lib/templates/network-state.template.ts +0 -702
  33. package/src/lib/templates/packageJson.template.ts +0 -63
  34. package/src/lib/templates/provider/__tests__/provider-templates.spec.ts +0 -209
  35. package/src/lib/templates/provider/axios-config.template.ts +0 -49
  36. package/src/lib/templates/provider/hooks.template.ts +0 -240
  37. package/src/lib/templates/provider/interfaces.template.ts +0 -72
  38. package/src/lib/templates/provider/intrig-provider-stub.template.ts +0 -73
  39. package/src/lib/templates/provider/intrig-provider.template.ts +0 -185
  40. package/src/lib/templates/provider/main.template.ts +0 -48
  41. package/src/lib/templates/provider/reducer.template.ts +0 -50
  42. package/src/lib/templates/provider/status-trap.template.ts +0 -80
  43. package/src/lib/templates/provider.template.ts +0 -698
  44. package/src/lib/templates/source/controller/method/asyncFunctionHook.template.ts +0 -196
  45. package/src/lib/templates/source/controller/method/clientIndex.template.ts +0 -38
  46. package/src/lib/templates/source/controller/method/download.template.ts +0 -256
  47. package/src/lib/templates/source/controller/method/params.template.ts +0 -31
  48. package/src/lib/templates/source/controller/method/requestHook.template.ts +0 -220
  49. package/src/lib/templates/source/type/typeTemplate.ts +0 -257
  50. package/src/lib/templates/swcrc.template.ts +0 -25
  51. package/src/lib/templates/tsconfig.template.ts +0 -37
  52. package/src/lib/templates/type-utils.template.ts +0 -28
  53. package/tsconfig.json +0 -13
  54. package/tsconfig.lib.json +0 -20
@@ -1,196 +0,0 @@
1
- import {
2
- camelCase,
3
- generatePostfix,
4
- pascalCase, ResourceDescriptor, RestData,
5
- typescript,
6
- Variable
7
- } from "@intrig/plugin-sdk";
8
- import * as path from 'path';
9
- import {InternalGeneratorContext} from "../../../../internal-types.js";
10
-
11
- function extractAsyncHookShape(response: string | undefined, requestBody: string | undefined, imports: Set<string>) {
12
- if (response) {
13
- if (requestBody) {
14
- imports.add(`import { BinaryFunctionAsyncHook } from "@intrig/react"`);
15
- return `BinaryFunctionAsyncHook<Params, RequestBody, Response>`;
16
- } else {
17
- imports.add(`import { UnaryFunctionAsyncHook } from "@intrig/react"`);
18
- return `UnaryFunctionAsyncHook<Params, Response>`;
19
- }
20
- } else {
21
- if (requestBody) {
22
- imports.add(`import { BinaryProduceAsyncHook } from "@intrig/react"`);
23
- return `BinaryProduceAsyncHook<Params, RequestBody>`;
24
- } else {
25
- imports.add(`import { UnaryProduceAsyncHook } from "@intrig/react"`);
26
- return `UnaryProduceAsyncHook<Params>`;
27
- }
28
- }
29
- }
30
-
31
- function extractErrorParams(errorTypes: string[]) {
32
- switch (errorTypes.length) {
33
- case 0:
34
- return `
35
- export type _ErrorType = any
36
- const errorSchema = z.any()`
37
- case 1:
38
- return `
39
- export type _ErrorType = ${errorTypes[0]}
40
- const errorSchema = ${errorTypes[0]}Schema`
41
- default:
42
- return `
43
- export type _ErrorType = ${errorTypes.join(' | ')}
44
- const errorSchema = z.union([${errorTypes.map(a => `${a}Schema`).join(', ')}])`
45
- }
46
- }
47
-
48
- function extractParamDeconstruction(variables: Variable[], requestBody?: string) {
49
- const isParamMandatory = variables?.some(a => a.in === 'path') || false;
50
-
51
- if (requestBody) {
52
- if (isParamMandatory) {
53
- return {
54
- paramExpression: 'data, p',
55
- paramType: 'data: RequestBody, params: Params'
56
- }
57
- } else {
58
- return {
59
- paramExpression: 'data, p = {}',
60
- paramType: 'data: RequestBody, params?: Params'
61
- }
62
- }
63
- } else {
64
- if (isParamMandatory) {
65
- return {
66
- paramExpression: 'p',
67
- paramType: 'params: Params'
68
- }
69
- } else {
70
- return {
71
- paramExpression: 'p = {}',
72
- paramType: 'params?: Params'
73
- }
74
- }
75
- }
76
- }
77
-
78
-
79
- export async function asyncFunctionHookTemplate(
80
- {source,
81
- data: {
82
- paths,
83
- operationId,
84
- response,
85
- requestUrl,
86
- variables,
87
- requestBody,
88
- contentType,
89
- responseType,
90
- errorResponses,
91
- method
92
- }
93
- }: ResourceDescriptor<RestData>, ctx: InternalGeneratorContext) {
94
- const postfix = ctx.potentiallyConflictingDescriptors.includes(operationId) ? generatePostfix(contentType, responseType) : ''
95
- const ts = typescript(path.resolve('src', source, ...paths, camelCase(operationId), `use${pascalCase(operationId)}Async${postfix}.ts`));
96
- ctx.getCounter(source)?.inc("Stateless Hooks")
97
- const modifiedRequestUrl = `${requestUrl?.replace(/\{/g, "${")}`;
98
- const imports = new Set<string>();
99
-
100
- // Basic imports
101
- imports.add(`import { z } from 'zod'`);
102
- imports.add(`import { useCallback } from 'react'`);
103
- imports.add(`import { useTransitionCall, encode, isError, isSuccess } from '@intrig/react'`);
104
-
105
- // Hook signature type
106
- const hookShape = extractAsyncHookShape(response, requestBody, imports);
107
-
108
- // Add body/response param imports
109
- if (requestBody) {
110
- imports.add(`import { ${requestBody} as RequestBody, ${requestBody}Schema as requestBodySchema } from "@intrig/react/${source}/components/schemas/${requestBody}"`);
111
- }
112
-
113
- if (response) {
114
- imports.add(`import { ${response} as Response, ${response}Schema as schema } from "@intrig/react/${source}/components/schemas/${response}"`);
115
- }
116
-
117
- imports.add(`import { ${pascalCase(operationId)}Params as Params } from './${pascalCase(operationId)}.params'`);
118
-
119
- // Error types
120
- const errorTypes = [...new Set(Object.values(errorResponses ?? {}).map((a) => a.response))];
121
- errorTypes.forEach((ref) => imports.add(`import { ${ref}, ${ref}Schema } from "@intrig/react/${source}/components/schemas/${ref}"`));
122
-
123
- // Error schema block
124
- const errorSchemaBlock = extractErrorParams(errorTypes.map((a) => a as string));
125
-
126
- // Param deconstruction
127
- const { paramExpression, paramType } = extractParamDeconstruction(variables ?? [], requestBody);
128
-
129
- const paramExplode = [
130
- ...(variables?.filter((a) => a.in === 'path').map((a) => a.name) ?? []),
131
- '...params',
132
- ].join(',');
133
-
134
- const finalRequestBodyBlock = requestBody ? `, data: encode(data, "${contentType}", requestBodySchema)` : '';
135
-
136
- function responseTypePart() {
137
- switch (responseType) {
138
- case "application/octet-stream":
139
- return `responseType: 'blob', adapter: 'fetch',`;
140
- case "text/event-stream":
141
- return `responseType: 'stream', adapter: 'fetch',`;
142
- }
143
- return ''
144
- }
145
-
146
- return ts`
147
- ${[...imports].join('\n')}
148
-
149
- ${!response ? `
150
- type Response = any;
151
- const schema = z.any();
152
- ` : ''}
153
-
154
- ${errorSchemaBlock}
155
-
156
- const operation = "${method.toUpperCase()} ${requestUrl}| ${contentType} -> ${responseType}";
157
- const source = "${source}";
158
-
159
- function use${pascalCase(operationId)}AsyncHook(): [(${paramType}) => Promise<Response>, () => void] {
160
- const [call, abort] = useTransitionCall<Response>({
161
- schema,
162
- errorSchema
163
- });
164
-
165
- const doExecute = useCallback<(${paramType}) => Promise<Response>>(async (${paramExpression}) => {
166
- const { ${paramExplode} } = p;
167
-
168
- ${requestBody ? `
169
- const validationResult = requestBodySchema.safeParse(data);
170
- if (!validationResult.success) {
171
- return Promise.reject(validationResult.error);
172
- }
173
- ` : ''}
174
-
175
- return await call({
176
- method: '${method}',
177
- url: \`${modifiedRequestUrl}\`,
178
- headers: {
179
- ${contentType ? `"Content-Type": "${contentType}",` : ''}
180
- },
181
- params,
182
- key: \`${"${source}: ${operation}"}\`,
183
- source: '${source}'
184
- ${requestBody ? finalRequestBodyBlock : ''},
185
- ${(responseTypePart())}
186
- });
187
- }, [call]);
188
-
189
- return [doExecute, abort];
190
- }
191
-
192
- use${pascalCase(operationId)}AsyncHook.key = \`${"${source}: ${operation}"}\`;
193
-
194
- export const use${pascalCase(operationId)}Async: ${hookShape} = use${pascalCase(operationId)}AsyncHook;
195
- `;
196
- }
@@ -1,38 +0,0 @@
1
- import {
2
- camelCase,
3
- generatePostfix,
4
- pascalCase,
5
- ResourceDescriptor, RestData,
6
- typescript
7
- } from "@intrig/plugin-sdk";
8
- import * as path from 'path'
9
- import {InternalGeneratorContext} from "../../../../internal-types.js"
10
-
11
- export async function clientIndexTemplate(descriptors: ResourceDescriptor<RestData>[], ctx: InternalGeneratorContext) {
12
- const {source, data: {paths, operationId, responseType, contentType}} = descriptors[0]
13
-
14
- ctx.getCounter(source)?.inc("Endpoints");
15
-
16
- const ts = typescript(path.resolve('src', source, ...paths, camelCase(operationId), `client.ts`))
17
-
18
- const postfix = ctx.potentiallyConflictingDescriptors.includes(operationId) ? generatePostfix(contentType, responseType) : ''
19
-
20
- if (descriptors.length === 1) return ts`
21
- export { use${pascalCase(operationId)} } from './use${pascalCase(operationId)}${postfix}'
22
- export { use${pascalCase(operationId)}Async } from './use${pascalCase(operationId)}Async${postfix}'
23
- `
24
-
25
- const exports = descriptors
26
- .map(({data: {contentType, responseType}}) => {
27
- const postfix = ctx.potentiallyConflictingDescriptors.includes(operationId) ? generatePostfix(contentType, responseType) : ''
28
- return `
29
- export { use${pascalCase(operationId)} as use${pascalCase(operationId)}${postfix} } from './use${pascalCase(operationId)}${postfix}'
30
- export { use${pascalCase(operationId)}Async as use${pascalCase(operationId)}Async${postfix} } from './use${pascalCase(operationId)}Async${postfix}'
31
- `
32
- })
33
- .join('\n');
34
-
35
- return ts`
36
- ${exports}
37
- `
38
- }
@@ -1,256 +0,0 @@
1
- import {
2
- camelCase,
3
- generatePostfix,
4
- pascalCase,
5
- ResourceDescriptor, RestData,
6
- typescript, Variable
7
- } from "@intrig/plugin-sdk";
8
- import * as path from 'path';
9
- import * as mimeType from 'mime-types'
10
- import {InternalGeneratorContext} from "../../../../internal-types.js"
11
-
12
- function extractHookShapeAndOptionsShape(response: string | undefined, requestBody: string | undefined, imports: Set<string>) {
13
- if (response) {
14
- if (requestBody) {
15
- imports.add(`import { BinaryFunctionHook, BinaryHookOptions } from "@intrig/react"`);
16
- return {
17
- hookShape: `BinaryFunctionHook<Params, RequestBody, Response>`,
18
- optionsShape: `BinaryHookOptions<Params, RequestBody>`
19
- };
20
- } else {
21
- imports.add(`import { UnaryFunctionHook, UnaryHookOptions } from "@intrig/react"`);
22
- return {
23
- hookShape: `UnaryFunctionHook<Params, Response>`,
24
- optionsShape: `UnaryHookOptions<Params>`
25
- };
26
- }
27
- } else {
28
- if (requestBody) {
29
- imports.add(`import { BinaryProduceHook, BinaryHookOptions } from "@intrig/react"`);
30
- return {
31
- hookShape: `BinaryProduceHook<Params, RequestBody>`,
32
- optionsShape: `BinaryHookOptions<Params, RequestBody>`
33
- };
34
- } else {
35
- imports.add(`import { UnaryProduceHook, UnaryHookOptions } from "@intrig/react"`);
36
- return {
37
- hookShape: `UnaryProduceHook<Params>`,
38
- optionsShape: `UnaryHookOptions<Params>`
39
- };
40
- }
41
- }
42
- }
43
-
44
- function extractParamDeconstruction(variables: Variable[] | undefined, requestBody: string | undefined) {
45
- const isParamMandatory = variables?.some(a => a.in === 'path') || false;
46
-
47
- if (requestBody) {
48
- if (isParamMandatory) {
49
- return {
50
- paramExpression: 'data, p',
51
- paramType: 'data: RequestBody, params: Params'
52
- }
53
- } else {
54
- return {
55
- paramExpression: 'data, p = {}',
56
- paramType: 'data: RequestBody, params?: Params'
57
- }
58
- }
59
- } else {
60
- if (isParamMandatory) {
61
- return {
62
- paramExpression: 'p',
63
- paramType: 'params: Params'
64
- }
65
- } else {
66
- return {
67
- paramExpression: 'p = {}',
68
- paramType: 'params?: Params'
69
- }
70
- }
71
- }
72
- }
73
-
74
- function extractErrorParams(errorTypes: string[]) {
75
- switch (errorTypes.length) {
76
- case 0:
77
- return `
78
- export type _ErrorType = any
79
- const errorSchema = z.any()`
80
- case 1:
81
- return `
82
- export type _ErrorType = ${errorTypes[0]}
83
- const errorSchema = ${errorTypes[0]}Schema`
84
- default:
85
- return `
86
- export type _ErrorType = ${errorTypes.join(' | ')}
87
- const errorSchema = z.union([${errorTypes.map(a => `${a}Schema`).join(', ')}])`
88
- }
89
- }
90
-
91
-
92
- export async function downloadHookTemplate({source,
93
- data: {
94
- paths,
95
- operationId,
96
- response,
97
- requestUrl,
98
- variables,
99
- requestBody,
100
- contentType,
101
- responseType,
102
- errorResponses,
103
- method
104
- }
105
- }: ResourceDescriptor<RestData>, ctx: InternalGeneratorContext) {
106
- const postfix = ctx.potentiallyConflictingDescriptors.includes(operationId) ? generatePostfix(contentType, responseType) : ''
107
- const ts = typescript(path.resolve('src', source, ...paths, camelCase(operationId), `use${pascalCase(operationId)}${postfix}Download.ts`))
108
- ctx.getCounter(source)?.inc("Download Hooks")
109
-
110
- const modifiedRequestUrl = `${requestUrl?.replace(/\{/g, "${")}`
111
-
112
- const imports = new Set<string>();
113
- imports.add(`import { z } from 'zod'`)
114
- imports.add(`import { useCallback, useEffect } from 'react'`)
115
- imports.add(`import {useNetworkState, NetworkState, DispatchState, pending, success, error, init, successfulDispatch, validationError, encode, isSuccess, requestValidationError} from "@intrig/react"`)
116
-
117
- const { hookShape, optionsShape } = extractHookShapeAndOptionsShape(response, requestBody, imports);
118
-
119
- const { paramExpression, paramType } = extractParamDeconstruction(variables, requestBody);
120
-
121
- if (requestBody) {
122
- imports.add(`import { ${requestBody} as RequestBody, ${requestBody}Schema as requestBodySchema } from "@intrig/react/${source}/components/schemas/${requestBody}"`)
123
- }
124
-
125
- if (response) {
126
- imports.add(`import { ${response} as Response, ${response}Schema as schema } from "@intrig/react/${source}/components/schemas/${response}"`)
127
- }
128
-
129
- imports.add(`import {${pascalCase(operationId)}Params as Params} from './${pascalCase(operationId)}.params'`)
130
-
131
- const errorTypes = [...new Set(Object.values(errorResponses ?? {}).map(a => a.response))]
132
- errorTypes.forEach(ref => imports.add(`import {${ref}, ${ref}Schema } from "@intrig/react/${source}/components/schemas/${ref}"`))
133
-
134
- const paramExplode = [
135
- ...variables?.filter(a => a.in === "path").map(a => a.name) ?? [],
136
- "...params"
137
- ].join(",")
138
-
139
- const finalRequestBodyBlock = requestBody ? `,data: encode(data, "${contentType}", requestBodySchema)` : ''
140
-
141
- function responseTypePart() {
142
- switch (responseType) {
143
- case "application/octet-stream":
144
- return `responseType: 'blob', adapter: 'fetch',`;
145
- case "text/event-stream":
146
- return `responseType: 'stream', adapter: 'fetch',`;
147
- }
148
- return ''
149
- }
150
-
151
- return ts`
152
- ${[...imports].join('\n')}
153
-
154
- ${!response ? `
155
- type Response = any;
156
- const schema = z.any();
157
- ` : ''}
158
-
159
- ${extractErrorParams(errorTypes.map(a => a as string))}
160
-
161
- const operation = "${method.toUpperCase()} ${requestUrl}| ${contentType} -> ${responseType}"
162
- const source = "${source}"
163
-
164
- function use${pascalCase(operationId)}Hook(options: ${optionsShape} = {}): [NetworkState<Response>, (${paramType}) => DispatchState<any>, () => void] {
165
- let [state, dispatch, clear, dispatchState] = useNetworkState<Response>({
166
- key: options?.key ?? 'default',
167
- operation,
168
- source,
169
- schema,
170
- errorSchema
171
- });
172
-
173
- useEffect(() => {
174
- if (isSuccess(state)) {
175
- let a = document.createElement('a');
176
- const ct =
177
- state.headers?.['content-type'] ?? 'application/octet-stream';
178
- let data: any = state.data;
179
- if (ct.startsWith('application/json')) {
180
- let data: any[];
181
- if (ct.startsWith('application/json')) {
182
- data = [JSON.stringify(state.data, null, 2)];
183
- } else {
184
- data = [state.data];
185
- }
186
- }
187
- a.href = URL.createObjectURL(new Blob(Array.isArray(data) ? data : [data], {type: ct}));
188
- const contentDisposition = state.headers?.['content-disposition'];
189
- let filename = '${pascalCase(operationId)}.${mimeType.extension(contentType)}';
190
- if (contentDisposition) {
191
- const rx = /filename\\*=(?:UTF-8'')?([^;\\r\\n]+)|filename="?([^";\\r\\n]+)"?/i;
192
- const m = contentDisposition.match(rx);
193
- if (m && m[1]) {
194
- filename = decodeURIComponent(m[1].replace(/\\+/g, ' '));
195
- } else if (m && m[2]) {
196
- filename = decodeURIComponent(m[2].replace(/\\+/g, ' '));
197
- }
198
- }
199
- a.download = filename;
200
- document.body.appendChild(a);
201
- a.click();
202
- document.body.removeChild(a);
203
- dispatchState(init())
204
- }
205
- }, [state])
206
-
207
- let doExecute = useCallback<(${paramType}) => DispatchState<any>>((${paramExpression}) => {
208
- let { ${paramExplode}} = p
209
-
210
- ${requestBody ? `
211
- const validationResult = requestBodySchema.safeParse(data);
212
- if (!validationResult.success) {
213
- dispatchState(error(requestValidationError(validationResult.error)));
214
- return validationError(validationResult.error.errors);
215
- }
216
- ` : ``}
217
-
218
- dispatch({
219
- method: '${method}',
220
- url: \`${modifiedRequestUrl}\`,
221
- headers: {
222
- ${contentType ? `"Content-Type": "${contentType}",` : ''}
223
- },
224
- params,
225
- key: \`${"${source}: ${operation}"}\`,
226
- source: '${source}'
227
- ${requestBody ? finalRequestBodyBlock : ''},
228
- ${(responseTypePart())}
229
- })
230
- return successfulDispatch();
231
- }, [dispatch])
232
-
233
- useEffect(() => {
234
- if (options.fetchOnMount) {
235
- doExecute(${[requestBody ? `options.body!` : undefined, "options.params!"].filter(a => a).join(",")});
236
- }
237
-
238
- return () => {
239
- if (options.clearOnUnmount) {
240
- clear();
241
- }
242
- }
243
- }, [])
244
-
245
- return [
246
- state,
247
- doExecute,
248
- clear
249
- ]
250
- }
251
-
252
- use${pascalCase(operationId)}Hook.key = \`${"${source}: ${operation}"}\`
253
-
254
- export const use${pascalCase(operationId)}Download: ${hookShape} = use${pascalCase(operationId)}Hook;
255
- `
256
- }
@@ -1,31 +0,0 @@
1
- import {
2
- camelCase,
3
- decodeVariables,
4
- pascalCase,
5
- ResourceDescriptor,
6
- RestData,
7
- typescript
8
- } from "@intrig/plugin-sdk";
9
- import * as path from "path";
10
- import {InternalGeneratorContext} from "../../../../internal-types.js";
11
-
12
- export async function paramsTemplate({
13
- source,
14
- data: {paths, operationId, variables}
15
- }: ResourceDescriptor<RestData>, ctx: InternalGeneratorContext) {
16
- const ts = typescript(path.resolve('src', source, ...paths, camelCase(operationId), `${pascalCase(operationId)}.params.ts`))
17
-
18
- const {variableImports, variableTypes} = decodeVariables(variables ?? [], source, "@intrig/react");
19
-
20
- if (variableTypes.length === 0) return ts`
21
- export type ${pascalCase(operationId)}Params = Record<string, any>
22
- `
23
-
24
- return ts`
25
- ${variableImports}
26
-
27
- export interface ${pascalCase(operationId)}Params extends Record<string, any> {
28
- ${variableTypes}
29
- }
30
- `
31
- }