@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,73 +0,0 @@
1
- import { IntrigSourceConfig, typescript } from "@intrig/plugin-sdk";
2
- import * as path from 'path';
3
-
4
- export function reactIntrigProviderStubTemplate(_apisToSync: IntrigSourceConfig[]) {
5
- const ts = typescript(path.resolve('src', 'intrig-provider-stub.tsx'));
6
- return ts`import { useMemo, useReducer } from 'react';
7
- import { ZodSchema } from 'zod';
8
- import { Context, RequestType, GlobalState } from './intrig-context';
9
- import { IntrigProviderStubProps } from './interfaces';
10
- import { error, configError, init, NetworkState } from './network-state';
11
- import { requestReducer } from './reducer';
12
-
13
- export function IntrigProviderStub({
14
- children,
15
- configs = {},
16
- stubs = () => {
17
- //intentionally left blank
18
- },
19
- }: IntrigProviderStubProps) {
20
- const [state, dispatch] = useReducer(requestReducer, {} as GlobalState);
21
-
22
- const collectedStubs = useMemo(() => {
23
- const fns: Record<string, (
24
- params: any,
25
- body: any,
26
- dispatch: (state: NetworkState<any>) => void,
27
- ) => Promise<void>> = {};
28
- function stub<P, B, T>(
29
- hook: any,
30
- fn: (
31
- params: P,
32
- body: B,
33
- dispatch: (state: NetworkState<T>) => void,
34
- ) => Promise<void>,
35
- ) {
36
- fns[hook.key] = fn;
37
- }
38
- stubs(stub);
39
- return fns;
40
- }, [stubs]);
41
-
42
- const contextValue = useMemo(() => {
43
- async function execute<T>(
44
- request: RequestType,
45
- dispatch: (state: NetworkState<T>) => void,
46
- schema: ZodSchema<T> | undefined,
47
- ) {
48
- const stub = collectedStubs[request.key];
49
-
50
- if (stub) {
51
- try {
52
- await stub(request.params, request.data, dispatch);
53
- } catch (e: any) {
54
- dispatch(error(configError(e?.message ?? '')));
55
- }
56
- } else {
57
- dispatch(init());
58
- }
59
- }
60
-
61
- return {
62
- state,
63
- dispatch,
64
- filteredState: state,
65
- configs,
66
- execute,
67
- };
68
- }, [state, dispatch, configs, collectedStubs]);
69
-
70
- return <Context.Provider value={contextValue}>{children}</Context.Provider>;
71
- }
72
- `;
73
- }
@@ -1,185 +0,0 @@
1
- import { IntrigSourceConfig, typescript } from "@intrig/plugin-sdk";
2
- import * as path from 'path';
3
-
4
- export function reactIntrigProviderTemplate(_apisToSync: IntrigSourceConfig[]) {
5
- const ts = typescript(path.resolve('src', 'intrig-provider.tsx'));
6
- return ts`import React, { useMemo, useReducer } from 'react';
7
- import {
8
- error,
9
- NetworkState,
10
- pending,
11
- success,
12
- responseValidationError,
13
- configError,
14
- httpError,
15
- networkError,
16
- } from './network-state';
17
- import { Axios, AxiosResponse, isAxiosError } from 'axios';
18
- import { ZodError, ZodSchema } from 'zod';
19
- import { flushSync } from 'react-dom';
20
- import { createParser } from 'eventsource-parser';
21
-
22
- import { Context, RequestType, GlobalState } from './intrig-context';
23
- import { IntrigProviderProps } from './interfaces';
24
- import { createAxiosInstances } from './axios-config';
25
- import { requestReducer, inferNetworkReason } from './reducer';
26
-
27
- /**
28
- * IntrigProvider is a context provider component that sets up global state management
29
- * and provides Axios instances for API requests.
30
- */
31
- export function IntrigProvider({ children, configs = {} }: IntrigProviderProps) {
32
- const [state, dispatch] = useReducer(requestReducer, {} as GlobalState);
33
-
34
- const axiosInstances: Record<string, Axios> = useMemo(() => {
35
- return createAxiosInstances(configs);
36
- }, [configs]);
37
-
38
- const contextValue = useMemo(() => {
39
- async function execute<T>(
40
- request: RequestType,
41
- setState: (s: NetworkState<T>) => void,
42
- schema?: ZodSchema<T>, // success payload schema (optional)
43
- errorSchema?: ZodSchema<any>, // error-body schema for non-2xx (optional)
44
- ) {
45
- try {
46
- setState(pending());
47
-
48
- const axios = axiosInstances[request.source];
49
- if (!axios) {
50
- setState(error(configError(${"`Unknown axios source '${request.source}'`"})));
51
- return;
52
- }
53
-
54
- const response = await axios.request(request);
55
- const status = response.status;
56
- const method = (response.config?.method || 'GET').toUpperCase();
57
- const url = response.config?.url || '';
58
- const ctype = String(response.headers?.['content-type'] || '');
59
-
60
- // -------------------- 2xx branch --------------------
61
- if (status >= 200 && status < 300) {
62
- // SSE stream
63
- if (ctype.includes('text/event-stream')) {
64
- const reader = response.data.getReader();
65
- const decoder = new TextDecoder();
66
-
67
- let lastMessage: any;
68
-
69
- const parser = createParser({
70
- onEvent(evt) {
71
- let decoded: unknown = evt.data;
72
-
73
- // Try JSON parse; if schema is defined, we require valid JSON for validation
74
- try {
75
- let parsed: unknown = JSON.parse(String(decoded));
76
- if (schema) {
77
- const vr = schema.safeParse(parsed);
78
- if (!vr.success) {
79
- setState(error(responseValidationError(vr.error, parsed)));
80
- return;
81
- }
82
- parsed = vr.data;
83
- }
84
- decoded = parsed;
85
- } catch (ignore) {
86
- if (schema) {
87
- // schema expects structured data but chunk wasn't JSON
88
- setState(error(responseValidationError(new ZodError([]), decoded)));
89
- return;
90
- }
91
- // if no schema, pass raw text
92
- }
93
-
94
- lastMessage = decoded;
95
- flushSync(() => setState(pending(undefined, decoded as T)));
96
- },
97
- });
98
-
99
- while (true) {
100
- const { done, value } = await reader.read();
101
- if (done) {
102
- flushSync(() => setState(success(lastMessage as T, response.headers)));
103
- break;
104
- }
105
- parser.feed(decoder.decode(value, { stream: true }));
106
- }
107
- return;
108
- }
109
-
110
- // Non-SSE: validate body if a schema is provided
111
- if (schema) {
112
- const parsed = schema.safeParse(response.data);
113
- if (!parsed.success) {
114
- setState(error(responseValidationError(parsed.error, response.data)));
115
- return;
116
- }
117
- setState(success(parsed.data, response.headers));
118
- return;
119
- }
120
-
121
- // No schema → pass through
122
- setState(success(response.data as T, response.headers));
123
- return;
124
- }
125
-
126
- // -------------------- non-2xx (HTTP error) --------------------
127
- let errorBody: unknown = response.data;
128
-
129
- if (errorSchema) {
130
- const ev = errorSchema.safeParse(errorBody ?? {});
131
- if (!ev.success) {
132
- setState(error(responseValidationError(ev.error, errorBody)));
133
- return;
134
- }
135
- errorBody = ev.data;
136
- }
137
-
138
- setState(error(httpError(status, url, method, response.headers, errorBody)));
139
-
140
- } catch (e: any) {
141
- // -------------------- thrown / transport --------------------
142
- if (isAxiosError(e)) {
143
- const status = e.response?.status;
144
- const method = (e.config?.method || 'GET').toUpperCase();
145
- const url = e.config?.url || '';
146
-
147
- if (status != null) {
148
- // HTTP error with response
149
- let errorBody: unknown = e.response?.data;
150
-
151
- if (errorSchema) {
152
- const ev = errorSchema.safeParse(errorBody ?? {});
153
- if (!ev.success) {
154
- setState(error(responseValidationError(ev.error, errorBody)));
155
- return;
156
- }
157
- errorBody = ev.data;
158
- }
159
-
160
- setState(error(httpError(status, url, method, e.response?.headers, errorBody)));
161
- return;
162
- }
163
-
164
- // No response → network layer
165
- setState(error(networkError(inferNetworkReason(e), e.request)));
166
- return;
167
- }
168
-
169
- // Non-Axios exception → treat as unknown network-ish failure
170
- setState(error(networkError('unknown')));
171
- }
172
- }
173
- return {
174
- state,
175
- dispatch,
176
- filteredState: state,
177
- configs,
178
- execute,
179
- };
180
- }, [state, axiosInstances]);
181
-
182
- return <Context.Provider value={contextValue}>{children}</Context.Provider>;
183
- }
184
- `;
185
- }
@@ -1,48 +0,0 @@
1
- import {IntrigSourceConfig, typescript} from "@intrig/plugin-sdk";
2
- import * as path from 'path'
3
-
4
- export function providerMainTemplate(apisToSync: IntrigSourceConfig[]) {
5
- const ts = typescript(path.resolve("src", "intrig-provider-main.tsx"))
6
- return ts`// Re-export all provider functionality from modular templates
7
- export * from './interfaces';
8
- export * from './reducer';
9
- export * from './axios-config';
10
- export * from './intrig-provider';
11
- export * from './intrig-provider-stub';
12
- export * from './status-trap';
13
- export * from './provider-hooks';
14
-
15
- // Main provider exports for backward compatibility
16
- export { IntrigProvider } from './intrig-provider';
17
- export { IntrigProviderStub } from './intrig-provider-stub';
18
- export { StatusTrap } from './status-trap';
19
-
20
- export {
21
- useNetworkState,
22
- useTransitionCall,
23
- useCentralError,
24
- useCentralPendingState,
25
- } from './provider-hooks';
26
-
27
- export {
28
- requestReducer,
29
- inferNetworkReason,
30
- debounce,
31
- } from './reducer';
32
-
33
- export {
34
- createAxiosInstance,
35
- createAxiosInstances,
36
- } from './axios-config';
37
-
38
- export type {
39
- DefaultConfigs,
40
- IntrigProviderProps,
41
- IntrigProviderStubProps,
42
- StatusTrapProps,
43
- NetworkStateProps,
44
- StubType,
45
- WithStubSupport,
46
- } from './interfaces';
47
- `
48
- }
@@ -1,50 +0,0 @@
1
- import {typescript} from "@intrig/plugin-sdk";
2
- import * as path from 'path'
3
-
4
- export function providerReducerTemplate() {
5
- const ts = typescript(path.resolve("src", "reducer.ts"))
6
- return ts`import {
7
- NetworkAction,
8
- } from './network-state';
9
- import { GlobalState } from './intrig-context';
10
-
11
- /**
12
- * Handles state updates for network requests based on the provided action.
13
- *
14
- * @param {GlobalState} state - The current state of the application.
15
- * @param {NetworkAction<unknown>} action - The action containing source, operation, key, and state.
16
- * @return {GlobalState} - The updated state after applying the action.
17
- */
18
- export function requestReducer(
19
- state: GlobalState,
20
- action: NetworkAction<unknown>,
21
- ): GlobalState {
22
- return {
23
- ...state,
24
- [${"`${action.source}:${action.operation}:${action.key}`"}]: action.state,
25
- };
26
- }
27
-
28
- function inferNetworkReason(e: any): 'timeout' | 'dns' | 'offline' | 'aborted' | 'unknown' {
29
- if (e?.code === 'ECONNABORTED') return 'timeout';
30
- if (typeof navigator !== 'undefined' && navigator.onLine === false) return 'offline';
31
- if (e?.name === 'AbortError') return 'aborted';
32
- return 'unknown';
33
- }
34
-
35
- function debounce<T extends (...args: any[]) => void>(func: T, delay: number) {
36
- let timeoutId: any;
37
-
38
- return (...args: Parameters<T>) => {
39
- if (timeoutId) {
40
- clearTimeout(timeoutId);
41
- }
42
- timeoutId = setTimeout(() => {
43
- func(...args);
44
- }, delay);
45
- };
46
- }
47
-
48
- export { inferNetworkReason, debounce };
49
- `
50
- }
@@ -1,80 +0,0 @@
1
- import { IntrigSourceConfig, typescript } from "@intrig/plugin-sdk";
2
- import * as path from 'path';
3
-
4
- export function reactStatusTrapTemplate(_apisToSync: IntrigSourceConfig[]) {
5
- const ts = typescript(path.resolve('src', 'status-trap.tsx'));
6
- return ts`import React, { PropsWithChildren, useCallback, useContext, useMemo, useState } from 'react';
7
- import { isError, isPending, NetworkState } from './network-state';
8
- import { Context } from './intrig-context';
9
- import { StatusTrapProps } from './interfaces';
10
-
11
- /**
12
- * StatusTrap component is used to track and manage network request states.
13
- */
14
- export function StatusTrap({
15
- children,
16
- type,
17
- propagate = true,
18
- }: PropsWithChildren<StatusTrapProps>) {
19
- const ctx = useContext(Context);
20
-
21
- const [requests, setRequests] = useState<string[]>([]);
22
-
23
- const shouldHandleEvent = useCallback(
24
- (state: NetworkState) => {
25
- switch (type) {
26
- case 'error':
27
- return isError(state);
28
- case 'pending':
29
- return isPending(state);
30
- case 'pending + error':
31
- return isPending(state) || isError(state);
32
- default:
33
- return false;
34
- }
35
- },
36
- [type],
37
- );
38
-
39
- const dispatch = useCallback(
40
- (event: any) => {
41
- const composite = ${"`${event.source}:${event.operation}:${event.key}`"};
42
- if (!event.handled) {
43
- if (shouldHandleEvent(event.state)) {
44
- setRequests((prev) => [...prev, composite]);
45
- if (!propagate) {
46
- ctx.dispatch({
47
- ...event,
48
- handled: true,
49
- });
50
- return;
51
- }
52
- } else {
53
- setRequests((prev) => prev.filter((k) => k !== composite));
54
- }
55
- }
56
- ctx.dispatch(event);
57
- },
58
- [ctx, propagate, shouldHandleEvent],
59
- );
60
-
61
- const filteredState = useMemo(() => {
62
- return Object.fromEntries(
63
- Object.entries(ctx.state).filter(([key]) => requests.includes(key)),
64
- );
65
- }, [ctx.state, requests]);
66
-
67
- return (
68
- <Context.Provider
69
- value={{
70
- ...ctx,
71
- dispatch,
72
- filteredState,
73
- }}
74
- >
75
- {children}
76
- </Context.Provider>
77
- );
78
- }
79
- `;
80
- }