@intrig/plugin-react 0.0.1 → 0.0.2-2

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 (58) hide show
  1. package/dist/index.cjs +4260 -0
  2. package/dist/index.d.ts +2 -0
  3. package/dist/index.js +4235 -0
  4. package/package.json +6 -3
  5. package/.swcrc +0 -29
  6. package/README.md +0 -7
  7. package/eslint.config.mjs +0 -19
  8. package/project.json +0 -29
  9. package/rollup.config.cjs +0 -54
  10. package/rollup.config.mjs +0 -33
  11. package/src/index.ts +0 -2
  12. package/src/lib/code-generator.ts +0 -79
  13. package/src/lib/get-endpoint-documentation.ts +0 -35
  14. package/src/lib/get-schema-documentation.ts +0 -11
  15. package/src/lib/internal-types.ts +0 -15
  16. package/src/lib/plugin-react.ts +0 -22
  17. package/src/lib/templates/context.template.ts +0 -74
  18. package/src/lib/templates/docs/__snapshots__/async-hook.spec.ts.snap +0 -889
  19. package/src/lib/templates/docs/__snapshots__/download-hook.spec.ts.snap +0 -1445
  20. package/src/lib/templates/docs/__snapshots__/react-hook.spec.ts.snap +0 -1371
  21. package/src/lib/templates/docs/__snapshots__/sse-hook.spec.ts.snap +0 -2008
  22. package/src/lib/templates/docs/async-hook.spec.ts +0 -92
  23. package/src/lib/templates/docs/async-hook.ts +0 -226
  24. package/src/lib/templates/docs/download-hook.spec.ts +0 -182
  25. package/src/lib/templates/docs/download-hook.ts +0 -170
  26. package/src/lib/templates/docs/react-hook.spec.ts +0 -97
  27. package/src/lib/templates/docs/react-hook.ts +0 -323
  28. package/src/lib/templates/docs/schema.ts +0 -105
  29. package/src/lib/templates/docs/sse-hook.spec.ts +0 -207
  30. package/src/lib/templates/docs/sse-hook.ts +0 -221
  31. package/src/lib/templates/extra.template.ts +0 -198
  32. package/src/lib/templates/index.template.ts +0 -14
  33. package/src/lib/templates/intrigMiddleware.template.ts +0 -21
  34. package/src/lib/templates/logger.template.ts +0 -67
  35. package/src/lib/templates/media-type-utils.template.ts +0 -191
  36. package/src/lib/templates/network-state.template.ts +0 -702
  37. package/src/lib/templates/packageJson.template.ts +0 -63
  38. package/src/lib/templates/provider/__tests__/provider-templates.spec.ts +0 -209
  39. package/src/lib/templates/provider/axios-config.template.ts +0 -49
  40. package/src/lib/templates/provider/hooks.template.ts +0 -240
  41. package/src/lib/templates/provider/interfaces.template.ts +0 -72
  42. package/src/lib/templates/provider/intrig-provider-stub.template.ts +0 -73
  43. package/src/lib/templates/provider/intrig-provider.template.ts +0 -185
  44. package/src/lib/templates/provider/main.template.ts +0 -48
  45. package/src/lib/templates/provider/reducer.template.ts +0 -50
  46. package/src/lib/templates/provider/status-trap.template.ts +0 -80
  47. package/src/lib/templates/provider.template.ts +0 -698
  48. package/src/lib/templates/source/controller/method/asyncFunctionHook.template.ts +0 -196
  49. package/src/lib/templates/source/controller/method/clientIndex.template.ts +0 -38
  50. package/src/lib/templates/source/controller/method/download.template.ts +0 -256
  51. package/src/lib/templates/source/controller/method/params.template.ts +0 -31
  52. package/src/lib/templates/source/controller/method/requestHook.template.ts +0 -220
  53. package/src/lib/templates/source/type/typeTemplate.ts +0 -257
  54. package/src/lib/templates/swcrc.template.ts +0 -25
  55. package/src/lib/templates/tsconfig.template.ts +0 -37
  56. package/src/lib/templates/type-utils.template.ts +0 -28
  57. package/tsconfig.json +0 -13
  58. 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
- }