@aws/nx-plugin 0.76.0 → 0.78.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE-THIRD-PARTY +96 -10
- package/package.json +9 -9
- package/src/infra/app/__snapshots__/generator.spec.ts.snap +378 -7
- package/src/infra/app/files/app/src/main.ts.template +17 -2
- package/src/infra/app/generator.js +34 -9
- package/src/infra/app/generator.js.map +1 -1
- package/src/infra/app/schema.d.ts +1 -0
- package/src/infra/app/schema.json +6 -0
- package/src/py/fast-api/__snapshots__/generator.spec.ts.snap +16 -13
- package/src/py/fast-api/react/__snapshots__/generator.spec.ts.snap +1 -1
- package/src/py/mcp-server/__snapshots__/generator.spec.ts.snap +2 -2
- package/src/py/strands-agent/__snapshots__/generator.spec.ts.snap +6 -6
- package/src/smithy/react-connection/__snapshots__/generator.spec.ts.snap +2 -2
- package/src/smithy/ts/api/__snapshots__/generator.spec.ts.snap +23 -17
- package/src/trpc/backend/__snapshots__/generator.spec.ts.snap +60 -34
- package/src/trpc/backend/files/src/handler.ts.template +48 -0
- package/src/trpc/backend/files/src/index.ts.template +1 -1
- package/src/trpc/backend/files/src/router.ts.template +0 -38
- package/src/trpc/backend/files/src/schema/z-async-iterable.ts.template +115 -0
- package/src/trpc/backend/generator.js +6 -2
- package/src/trpc/backend/generator.js.map +1 -1
- package/src/trpc/react/__snapshots__/generator.spec.ts.snap +274 -27
- package/src/trpc/react/files/src/components/__apiNameClassName__ClientProvider.tsx.template +57 -1
- package/src/trpc/react/generator.js +11 -1
- package/src/trpc/react/generator.js.map +1 -1
- package/src/ts/mcp-server/__snapshots__/generator.spec.ts.snap +1 -1
- package/src/ts/nx-plugin/__snapshots__/generator.spec.ts.snap +1 -1
- package/src/ts/react-website/app/__snapshots__/generator.spec.ts.snap +13 -13
- package/src/utils/api-constructs/files/cdk/app/apis/rest/__apiNameKebabCase__.ts.template +13 -1
- package/src/utils/api-constructs/files/cdk/core/api/trpc/trpc-utils.ts.template +3 -3
- package/src/utils/api-constructs/files/terraform/app/apis/rest/__apiNameKebabCase__/__apiNameKebabCase__.tf.template +8 -3
- package/src/utils/api-constructs/files/terraform/core/api/rest/rest-api/rest-api.tf.template +1 -1
- package/src/utils/connection/open-api/files/components/__apiNameClassName__Provider.tsx.template +1 -1
- package/src/utils/files/common/infra-config/src/index.ts.template +3 -0
- package/src/utils/files/common/infra-config/src/resolve-stage.ts.template +23 -0
- package/src/utils/files/common/infra-config/src/stages.config.ts.template +48 -0
- package/src/utils/files/common/infra-config/src/stages.types.ts.template +66 -0
- package/src/utils/files/common/scripts/src/index.ts.template +1 -0
- package/src/utils/files/common/scripts/src/infra-deploy.ts.template +2 -0
- package/src/utils/files/common/scripts/src/infra-destroy.ts.template +2 -0
- package/src/utils/files/common/scripts/src/stage-credentials/cdk-command.ts.template +18 -0
- package/src/utils/files/common/scripts/src/stage-credentials/credentials.ts.template +100 -0
- package/src/utils/files/common/scripts/src/stage-credentials/run.ts.template +52 -0
- package/src/utils/files/common/scripts/src/stage-credentials/stage-parser.ts.template +15 -0
- package/src/utils/files/website/hooks/sigv4/useSigV4.tsx.template +81 -33
- package/src/utils/shared-constructs-constants.d.ts +4 -0
- package/src/utils/shared-constructs-constants.js +5 -1
- package/src/utils/shared-constructs-constants.js.map +1 -1
- package/src/utils/shared-infra-config.d.ts +11 -0
- package/src/utils/shared-infra-config.js +47 -0
- package/src/utils/shared-infra-config.js.map +1 -0
- package/src/utils/shared-scripts.d.ts +12 -0
- package/src/utils/shared-scripts.js +49 -0
- package/src/utils/shared-scripts.js.map +1 -0
- package/src/utils/versions.d.ts +31 -28
- package/src/utils/versions.js +30 -27
- package/src/utils/versions.js.map +1 -1
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CreateAWSLambdaContextOptions,
|
|
3
|
+
<%_ if (computeType === 'ServerlessApiGatewayRestApi') { _%>
|
|
4
|
+
awsLambdaStreamingRequestHandler,
|
|
5
|
+
<%_ } else { _%>
|
|
6
|
+
awsLambdaRequestHandler,
|
|
7
|
+
<%_ } _%>
|
|
8
|
+
} from '@trpc/server/adapters/aws-lambda';
|
|
9
|
+
import type { <%- apiGatewayEventType %> } from 'aws-lambda';
|
|
10
|
+
import { appRouter } from './router.js';
|
|
11
|
+
|
|
12
|
+
<%_ if (computeType === 'ServerlessApiGatewayRestApi') { _%>
|
|
13
|
+
export const handler = awslambda.streamifyResponse(
|
|
14
|
+
awsLambdaStreamingRequestHandler({
|
|
15
|
+
router: appRouter,
|
|
16
|
+
createContext: (ctx: CreateAWSLambdaContextOptions<<%- apiGatewayEventType %>>) => ctx,
|
|
17
|
+
responseMeta: ({ ctx }) => ({
|
|
18
|
+
headers: {
|
|
19
|
+
'Access-Control-Allow-Origin': getAllowedOrigin(ctx?.event),
|
|
20
|
+
'Access-Control-Allow-Methods': '*',
|
|
21
|
+
},
|
|
22
|
+
}),
|
|
23
|
+
}),
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Restricts CORS origins to localhost and the domains specified in
|
|
28
|
+
* the ALLOWED_ORIGINS environment variable if set, or * otherwise.
|
|
29
|
+
* Customise using `restrictCorsTo` in your API CDK construct
|
|
30
|
+
*/
|
|
31
|
+
const getAllowedOrigin = (event: <%- apiGatewayEventType %> | undefined) => {
|
|
32
|
+
const origin = event?.headers?.origin ?? event?.headers?.Origin;
|
|
33
|
+
const allowedOrigins = process.env.ALLOWED_ORIGINS?.split(',') ?? [];
|
|
34
|
+
const isLocalHost =
|
|
35
|
+
origin && new Set(['localhost', '127.0.0.1']).has(new URL(origin).hostname);
|
|
36
|
+
const isAllowedOrigin = origin && allowedOrigins.includes(origin);
|
|
37
|
+
let corsOrigin = '*';
|
|
38
|
+
if (allowedOrigins.length > 0 && !isLocalHost) {
|
|
39
|
+
corsOrigin = isAllowedOrigin ? origin : allowedOrigins[0];
|
|
40
|
+
}
|
|
41
|
+
return corsOrigin;
|
|
42
|
+
};
|
|
43
|
+
<%_ } else { _%>
|
|
44
|
+
export const handler = awsLambdaRequestHandler({
|
|
45
|
+
router: appRouter,
|
|
46
|
+
createContext: (ctx: CreateAWSLambdaContextOptions<<%- apiGatewayEventType %>>) => ctx,
|
|
47
|
+
});
|
|
48
|
+
<%_ } _%>
|
|
@@ -1,10 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
awsLambdaRequestHandler,
|
|
3
|
-
CreateAWSLambdaContextOptions,
|
|
4
|
-
} from '@trpc/server/adapters/aws-lambda';
|
|
5
1
|
import { echo } from './procedures/echo.js';
|
|
6
2
|
import { t } from './init.js';
|
|
7
|
-
import type { <%- apiGatewayEventType %> } from 'aws-lambda';
|
|
8
3
|
|
|
9
4
|
export const router = t.router;
|
|
10
5
|
|
|
@@ -12,37 +7,4 @@ export const appRouter = router({
|
|
|
12
7
|
echo,
|
|
13
8
|
});
|
|
14
9
|
|
|
15
|
-
export const handler = awsLambdaRequestHandler({
|
|
16
|
-
router: appRouter,
|
|
17
|
-
createContext: (ctx: CreateAWSLambdaContextOptions<<%- apiGatewayEventType %>>) => ctx,
|
|
18
|
-
<%_ if (computeType === 'ServerlessApiGatewayRestApi') { _%>
|
|
19
|
-
responseMeta: ({ ctx }) => ({
|
|
20
|
-
headers: {
|
|
21
|
-
'Access-Control-Allow-Origin': getAllowedOrigin(ctx?.event),
|
|
22
|
-
'Access-Control-Allow-Methods': '*',
|
|
23
|
-
},
|
|
24
|
-
}),
|
|
25
|
-
<%_ } _%>
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
<%_ if (computeType === 'ServerlessApiGatewayRestApi') { _%>
|
|
29
|
-
/**
|
|
30
|
-
* Restricts CORS origins to localhost and the domains specified in
|
|
31
|
-
* the ALLOWED_ORIGINS environment variable if set, or * otherwise.
|
|
32
|
-
* Customise using `restrictCorsTo` in your API CDK construct
|
|
33
|
-
*/
|
|
34
|
-
const getAllowedOrigin = (event: <%- apiGatewayEventType %> | undefined) => {
|
|
35
|
-
const origin = event?.headers?.origin ?? event?.headers?.Origin;
|
|
36
|
-
const allowedOrigins = process.env.ALLOWED_ORIGINS?.split(',') ?? [];
|
|
37
|
-
const isLocalHost =
|
|
38
|
-
origin && new Set(['localhost', '127.0.0.1']).has(new URL(origin).hostname);
|
|
39
|
-
const isAllowedOrigin = origin && allowedOrigins.includes(origin);
|
|
40
|
-
let corsOrigin = '*';
|
|
41
|
-
if (allowedOrigins.length > 0 && !isLocalHost) {
|
|
42
|
-
corsOrigin = isAllowedOrigin ? origin : allowedOrigins[0];
|
|
43
|
-
}
|
|
44
|
-
return corsOrigin;
|
|
45
|
-
};
|
|
46
|
-
<%_ } _%>
|
|
47
|
-
|
|
48
10
|
export type AppRouter = typeof appRouter;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { isTrackedEnvelope, tracked, type TrackedEnvelope } from '@trpc/server';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
|
|
4
|
+
function isAsyncIterable<TValue, TReturn = unknown>(
|
|
5
|
+
value: unknown,
|
|
6
|
+
): value is AsyncIterable<TValue, TReturn> {
|
|
7
|
+
return !!value && typeof value === 'object' && Symbol.asyncIterator in value;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* A Zod schema helper designed specifically for validating async iterables. This schema ensures that:
|
|
12
|
+
* 1. The value being validated is an async iterable.
|
|
13
|
+
* 2. Each item yielded by the async iterable conforms to a specified type.
|
|
14
|
+
* 3. The return value of the async iterable, if any, also conforms to a specified type.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
// Non-tracked overload
|
|
18
|
+
export function ZodAsyncIterable<
|
|
19
|
+
TYieldIn,
|
|
20
|
+
TYieldOut,
|
|
21
|
+
TReturnIn = void,
|
|
22
|
+
TReturnOut = void,
|
|
23
|
+
>(opts: {
|
|
24
|
+
yield: z.ZodType<TYieldOut, TYieldIn>;
|
|
25
|
+
return?: z.ZodType<TReturnOut, TReturnIn>;
|
|
26
|
+
tracked?: false;
|
|
27
|
+
}): z.ZodPipe<
|
|
28
|
+
z.ZodCustom<
|
|
29
|
+
AsyncIterable<TYieldIn, TReturnIn>,
|
|
30
|
+
AsyncIterable<TYieldIn, TReturnIn>
|
|
31
|
+
>,
|
|
32
|
+
z.ZodTransform<
|
|
33
|
+
AsyncGenerator<
|
|
34
|
+
Awaited<TYieldOut>,
|
|
35
|
+
Awaited<TReturnOut> | undefined,
|
|
36
|
+
unknown
|
|
37
|
+
>,
|
|
38
|
+
AsyncIterable<TYieldIn, TReturnIn>
|
|
39
|
+
>
|
|
40
|
+
>;
|
|
41
|
+
|
|
42
|
+
// Tracked overload
|
|
43
|
+
export function ZodAsyncIterable<
|
|
44
|
+
TYieldIn,
|
|
45
|
+
TYieldOut,
|
|
46
|
+
TReturnIn = void,
|
|
47
|
+
TReturnOut = void,
|
|
48
|
+
>(opts: {
|
|
49
|
+
yield: z.ZodType<TYieldOut, TYieldIn>;
|
|
50
|
+
return?: z.ZodType<TReturnOut, TReturnIn>;
|
|
51
|
+
tracked: true;
|
|
52
|
+
}): z.ZodPipe<
|
|
53
|
+
z.ZodCustom<
|
|
54
|
+
AsyncIterable<TrackedEnvelope<TYieldIn>, TReturnIn>,
|
|
55
|
+
AsyncIterable<TrackedEnvelope<TYieldIn>, TReturnIn>
|
|
56
|
+
>,
|
|
57
|
+
z.ZodTransform<
|
|
58
|
+
AsyncGenerator<
|
|
59
|
+
TrackedEnvelope<Awaited<TYieldOut>>,
|
|
60
|
+
Awaited<TReturnOut> | undefined,
|
|
61
|
+
unknown
|
|
62
|
+
>,
|
|
63
|
+
AsyncIterable<TrackedEnvelope<TYieldIn>, TReturnIn>
|
|
64
|
+
>
|
|
65
|
+
>;
|
|
66
|
+
|
|
67
|
+
// Implementation
|
|
68
|
+
export function ZodAsyncIterable<
|
|
69
|
+
TYieldIn,
|
|
70
|
+
TYieldOut,
|
|
71
|
+
TReturnIn = void,
|
|
72
|
+
TReturnOut = void,
|
|
73
|
+
>(opts: {
|
|
74
|
+
/**
|
|
75
|
+
* Validate the value yielded by the async generator
|
|
76
|
+
*/
|
|
77
|
+
yield: z.ZodType<TYieldOut, TYieldIn>;
|
|
78
|
+
/**
|
|
79
|
+
* Validate the return value of the async generator
|
|
80
|
+
* @remark not applicable for subscriptions
|
|
81
|
+
*/
|
|
82
|
+
return?: z.ZodType<TReturnOut, TReturnIn>;
|
|
83
|
+
/**
|
|
84
|
+
* Whether if the yielded values are tracked
|
|
85
|
+
* @remark only applicable for subscriptions
|
|
86
|
+
*/
|
|
87
|
+
tracked?: boolean;
|
|
88
|
+
}) {
|
|
89
|
+
return z
|
|
90
|
+
.custom<AsyncIterable<TYieldIn | TrackedEnvelope<TYieldIn>, TReturnIn>>(
|
|
91
|
+
(val) => isAsyncIterable(val),
|
|
92
|
+
)
|
|
93
|
+
.transform(async function* (iter) {
|
|
94
|
+
const iterator = iter[Symbol.asyncIterator]();
|
|
95
|
+
try {
|
|
96
|
+
let next;
|
|
97
|
+
while ((next = await iterator.next()) && !next.done) {
|
|
98
|
+
if (opts.tracked) {
|
|
99
|
+
const [id, data] = z
|
|
100
|
+
.custom<TrackedEnvelope<unknown>>(isTrackedEnvelope)
|
|
101
|
+
.parse(next.value);
|
|
102
|
+
yield tracked(id, await opts.yield.parseAsync(data));
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
yield opts.yield.parseAsync(next.value);
|
|
106
|
+
}
|
|
107
|
+
if (opts.return) {
|
|
108
|
+
return await opts.return.parseAsync(next.value);
|
|
109
|
+
}
|
|
110
|
+
return;
|
|
111
|
+
} finally {
|
|
112
|
+
await iterator.return?.();
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
}
|
|
@@ -56,7 +56,7 @@ function tsTrpcApiGenerator(tree, options) {
|
|
|
56
56
|
auth: options.auth,
|
|
57
57
|
iacProvider,
|
|
58
58
|
});
|
|
59
|
-
projectConfig.metadata = Object.assign(Object.assign({}, projectConfig.metadata), { apiName: options.name, apiType: 'trpc', auth: options.auth });
|
|
59
|
+
projectConfig.metadata = Object.assign(Object.assign({}, projectConfig.metadata), { apiName: options.name, apiType: 'trpc', auth: options.auth, computeType: options.computeType });
|
|
60
60
|
projectConfig.targets.serve = {
|
|
61
61
|
executor: 'nx:run-commands',
|
|
62
62
|
options: {
|
|
@@ -66,7 +66,7 @@ function tsTrpcApiGenerator(tree, options) {
|
|
|
66
66
|
continuous: true,
|
|
67
67
|
};
|
|
68
68
|
(0, bundle_1.addTypeScriptBundleTarget)(tree, projectConfig, {
|
|
69
|
-
targetFilePath: 'src/
|
|
69
|
+
targetFilePath: 'src/handler.ts',
|
|
70
70
|
external: [/@aws-sdk\/.*/], // lambda runtime provides aws sdk
|
|
71
71
|
});
|
|
72
72
|
(0, nx_1.addDependencyToTargetIfNotPresent)(projectConfig, 'build', 'bundle');
|
|
@@ -76,6 +76,10 @@ function tsTrpcApiGenerator(tree, options) {
|
|
|
76
76
|
overwriteStrategy: devkit_1.OverwriteStrategy.Overwrite,
|
|
77
77
|
});
|
|
78
78
|
tree.delete((0, devkit_1.joinPathFragments)(backendRoot, 'src', 'lib'));
|
|
79
|
+
// Remove streaming schema helper for HTTP APIs (API Gateway HTTP API doesn't support streaming)
|
|
80
|
+
if (options.computeType !== 'ServerlessApiGatewayRestApi') {
|
|
81
|
+
tree.delete((0, devkit_1.joinPathFragments)(backendRoot, 'src', 'schema', 'z-async-iterable.ts'));
|
|
82
|
+
}
|
|
79
83
|
(0, devkit_1.addDependenciesToPackageJson)(tree, (0, versions_1.withVersions)([
|
|
80
84
|
'aws-xray-sdk-core',
|
|
81
85
|
'zod',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../../../packages/nx-plugin/src/trpc/backend/generator.ts"],"names":[],"mappings":";;;AAsCA,
|
|
1
|
+
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../../../packages/nx-plugin/src/trpc/backend/generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,224 @@
|
|
|
1
1
|
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
2
|
|
|
3
|
+
exports[`trpc react generator > REST API (ServerlessApiGatewayRestApi) > should generate REST API client provider with splitLink for Cognito auth > TestApiClientProvider-REST-Cognito.tsx 1`] = `
|
|
4
|
+
"import { AppRouter } from 'backend';
|
|
5
|
+
import { useQueryClient } from '@tanstack/react-query';
|
|
6
|
+
import { createTRPCOptionsProxy } from '@trpc/tanstack-react-query';
|
|
7
|
+
import { createContext, FC, PropsWithChildren, useMemo } from 'react';
|
|
8
|
+
import { useRuntimeConfig } from '../hooks/useRuntimeConfig';
|
|
9
|
+
import {
|
|
10
|
+
TRPCClient,
|
|
11
|
+
createTRPCClient,
|
|
12
|
+
httpLink,
|
|
13
|
+
httpSubscriptionLink,
|
|
14
|
+
splitLink,
|
|
15
|
+
} from '@trpc/client';
|
|
16
|
+
import { EventSourcePolyfill } from 'event-source-polyfill';
|
|
17
|
+
import { useAuth } from 'react-oidc-context';
|
|
18
|
+
|
|
19
|
+
interface TestApiTRPCContextValue {
|
|
20
|
+
optionsProxy: ReturnType<typeof createTRPCOptionsProxy<AppRouter>>;
|
|
21
|
+
client: TRPCClient<AppRouter>;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const TestApiTRPCContext = createContext<TestApiTRPCContextValue | null>(
|
|
25
|
+
null,
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
export const TestApiClientProvider: FC<PropsWithChildren> = ({ children }) => {
|
|
29
|
+
const queryClient = useQueryClient();
|
|
30
|
+
const runtimeConfig = useRuntimeConfig();
|
|
31
|
+
const apiUrl = runtimeConfig.apis.TestApi;
|
|
32
|
+
const auth = useAuth();
|
|
33
|
+
const user = auth?.user;
|
|
34
|
+
|
|
35
|
+
const container = useMemo<TestApiTRPCContextValue>(() => {
|
|
36
|
+
const client = createTRPCClient<AppRouter>({
|
|
37
|
+
links: [
|
|
38
|
+
splitLink({
|
|
39
|
+
condition: (op) => op.type === 'subscription',
|
|
40
|
+
true: httpSubscriptionLink({
|
|
41
|
+
url: apiUrl,
|
|
42
|
+
EventSource: EventSourcePolyfill,
|
|
43
|
+
eventSourceOptions: async ({ op }) => {
|
|
44
|
+
return {
|
|
45
|
+
headers: {
|
|
46
|
+
Authorization: \`Bearer \${user?.id_token}\`,
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
},
|
|
50
|
+
}),
|
|
51
|
+
false: httpLink({
|
|
52
|
+
url: apiUrl,
|
|
53
|
+
headers: {
|
|
54
|
+
Authorization: \`Bearer \${user?.id_token}\`,
|
|
55
|
+
},
|
|
56
|
+
}),
|
|
57
|
+
}),
|
|
58
|
+
],
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
const optionsProxy = createTRPCOptionsProxy<AppRouter>({
|
|
62
|
+
client,
|
|
63
|
+
queryClient,
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
return { optionsProxy, client };
|
|
67
|
+
}, [apiUrl, queryClient, user]);
|
|
68
|
+
|
|
69
|
+
return (
|
|
70
|
+
<TestApiTRPCContext.Provider value={container}>
|
|
71
|
+
{children}
|
|
72
|
+
</TestApiTRPCContext.Provider>
|
|
73
|
+
);
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
export default TestApiClientProvider;
|
|
77
|
+
"
|
|
78
|
+
`;
|
|
79
|
+
|
|
80
|
+
exports[`trpc react generator > REST API (ServerlessApiGatewayRestApi) > should generate REST API client provider with splitLink for IAM auth > TestApiClientProvider-REST-IAM.tsx 1`] = `
|
|
81
|
+
"import { AppRouter } from 'backend';
|
|
82
|
+
import { useQueryClient } from '@tanstack/react-query';
|
|
83
|
+
import { createTRPCOptionsProxy } from '@trpc/tanstack-react-query';
|
|
84
|
+
import { createContext, FC, PropsWithChildren, useMemo } from 'react';
|
|
85
|
+
import { useRuntimeConfig } from '../hooks/useRuntimeConfig';
|
|
86
|
+
import {
|
|
87
|
+
TRPCClient,
|
|
88
|
+
createTRPCClient,
|
|
89
|
+
httpLink,
|
|
90
|
+
httpSubscriptionLink,
|
|
91
|
+
splitLink,
|
|
92
|
+
} from '@trpc/client';
|
|
93
|
+
import { EventSourcePolyfill } from 'event-source-polyfill';
|
|
94
|
+
import { useSigV4 } from '../hooks/useSigV4';
|
|
95
|
+
|
|
96
|
+
interface TestApiTRPCContextValue {
|
|
97
|
+
optionsProxy: ReturnType<typeof createTRPCOptionsProxy<AppRouter>>;
|
|
98
|
+
client: TRPCClient<AppRouter>;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export const TestApiTRPCContext = createContext<TestApiTRPCContextValue | null>(
|
|
102
|
+
null,
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
export const TestApiClientProvider: FC<PropsWithChildren> = ({ children }) => {
|
|
106
|
+
const queryClient = useQueryClient();
|
|
107
|
+
const runtimeConfig = useRuntimeConfig();
|
|
108
|
+
const apiUrl = runtimeConfig.apis.TestApi;
|
|
109
|
+
const sigv4Client = useSigV4();
|
|
110
|
+
|
|
111
|
+
const container = useMemo<TestApiTRPCContextValue>(() => {
|
|
112
|
+
const client = createTRPCClient<AppRouter>({
|
|
113
|
+
links: [
|
|
114
|
+
splitLink({
|
|
115
|
+
condition: (op) => op.type === 'subscription',
|
|
116
|
+
true: httpSubscriptionLink({
|
|
117
|
+
url: apiUrl,
|
|
118
|
+
EventSource: EventSourcePolyfill,
|
|
119
|
+
eventSourceOptions: async ({ op }) => {
|
|
120
|
+
const url =
|
|
121
|
+
\`\${apiUrl.replace(/\\/$/, '')}/\${op.path}\` +
|
|
122
|
+
(op.input !== undefined
|
|
123
|
+
? \`?input=\${encodeURIComponent(JSON.stringify(op.input))}\`
|
|
124
|
+
: '');
|
|
125
|
+
const signed = await sigv4Client.sign(url, { method: 'GET' });
|
|
126
|
+
const headers: Record<string, string> = {};
|
|
127
|
+
signed.headers.forEach((v, k) => {
|
|
128
|
+
headers[k] = v;
|
|
129
|
+
});
|
|
130
|
+
return { headers };
|
|
131
|
+
},
|
|
132
|
+
}),
|
|
133
|
+
false: httpLink({
|
|
134
|
+
url: apiUrl,
|
|
135
|
+
fetch: sigv4Client.fetch,
|
|
136
|
+
}),
|
|
137
|
+
}),
|
|
138
|
+
],
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
const optionsProxy = createTRPCOptionsProxy<AppRouter>({
|
|
142
|
+
client,
|
|
143
|
+
queryClient,
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
return { optionsProxy, client };
|
|
147
|
+
}, [apiUrl, queryClient, sigv4Client]);
|
|
148
|
+
|
|
149
|
+
return (
|
|
150
|
+
<TestApiTRPCContext.Provider value={container}>
|
|
151
|
+
{children}
|
|
152
|
+
</TestApiTRPCContext.Provider>
|
|
153
|
+
);
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
export default TestApiClientProvider;
|
|
157
|
+
"
|
|
158
|
+
`;
|
|
159
|
+
|
|
160
|
+
exports[`trpc react generator > REST API (ServerlessApiGatewayRestApi) > should generate REST API client provider with splitLink for None auth > TestApiClientProvider-REST-None.tsx 1`] = `
|
|
161
|
+
"import { AppRouter } from 'backend';
|
|
162
|
+
import { useQueryClient } from '@tanstack/react-query';
|
|
163
|
+
import { createTRPCOptionsProxy } from '@trpc/tanstack-react-query';
|
|
164
|
+
import { createContext, FC, PropsWithChildren, useMemo } from 'react';
|
|
165
|
+
import { useRuntimeConfig } from '../hooks/useRuntimeConfig';
|
|
166
|
+
import {
|
|
167
|
+
TRPCClient,
|
|
168
|
+
createTRPCClient,
|
|
169
|
+
httpLink,
|
|
170
|
+
httpSubscriptionLink,
|
|
171
|
+
splitLink,
|
|
172
|
+
} from '@trpc/client';
|
|
173
|
+
|
|
174
|
+
interface TestApiTRPCContextValue {
|
|
175
|
+
optionsProxy: ReturnType<typeof createTRPCOptionsProxy<AppRouter>>;
|
|
176
|
+
client: TRPCClient<AppRouter>;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export const TestApiTRPCContext = createContext<TestApiTRPCContextValue | null>(
|
|
180
|
+
null,
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
export const TestApiClientProvider: FC<PropsWithChildren> = ({ children }) => {
|
|
184
|
+
const queryClient = useQueryClient();
|
|
185
|
+
const runtimeConfig = useRuntimeConfig();
|
|
186
|
+
const apiUrl = runtimeConfig.apis.TestApi;
|
|
187
|
+
|
|
188
|
+
const container = useMemo<TestApiTRPCContextValue>(() => {
|
|
189
|
+
const client = createTRPCClient<AppRouter>({
|
|
190
|
+
links: [
|
|
191
|
+
splitLink({
|
|
192
|
+
condition: (op) => op.type === 'subscription',
|
|
193
|
+
true: httpSubscriptionLink({
|
|
194
|
+
url: apiUrl,
|
|
195
|
+
}),
|
|
196
|
+
false: httpLink({
|
|
197
|
+
url: apiUrl,
|
|
198
|
+
}),
|
|
199
|
+
}),
|
|
200
|
+
],
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
const optionsProxy = createTRPCOptionsProxy<AppRouter>({
|
|
204
|
+
client,
|
|
205
|
+
queryClient,
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
return { optionsProxy, client };
|
|
209
|
+
}, [apiUrl, queryClient]);
|
|
210
|
+
|
|
211
|
+
return (
|
|
212
|
+
<TestApiTRPCContext.Provider value={container}>
|
|
213
|
+
{children}
|
|
214
|
+
</TestApiTRPCContext.Provider>
|
|
215
|
+
);
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
export default TestApiClientProvider;
|
|
219
|
+
"
|
|
220
|
+
`;
|
|
221
|
+
|
|
3
222
|
exports[`trpc react generator > should generate trpc react files > TestApiClientProvider.tsx 1`] = `
|
|
4
223
|
"import { AppRouter } from 'backend';
|
|
5
224
|
import { useQueryClient } from '@tanstack/react-query';
|
|
@@ -172,7 +391,7 @@ export const TestApiClientProvider: FC<PropsWithChildren> = ({ children }) => {
|
|
|
172
391
|
const container = useMemo<TestApiTRPCContextValue>(() => {
|
|
173
392
|
const linkOptions: HTTPLinkOptions<any> = {
|
|
174
393
|
url: apiUrl,
|
|
175
|
-
fetch: sigv4Client,
|
|
394
|
+
fetch: sigv4Client.fetch,
|
|
176
395
|
};
|
|
177
396
|
|
|
178
397
|
const client = createTRPCClient<AppRouter>({
|
|
@@ -213,7 +432,17 @@ import {
|
|
|
213
432
|
// Credential expiration grace time before considering credentials as expired
|
|
214
433
|
const CREDENTIAL_EXPIRY_OFFSET_MILLIS = 30 * 1000;
|
|
215
434
|
|
|
216
|
-
|
|
435
|
+
type AwsSignInput = Parameters<AwsClient['sign']>[0];
|
|
436
|
+
type AwsSignInit = Parameters<AwsClient['sign']>[1];
|
|
437
|
+
|
|
438
|
+
export interface SigV4Client {
|
|
439
|
+
/** A SigV4-signing fetch drop-in replacement. */
|
|
440
|
+
fetch: typeof globalThis.fetch;
|
|
441
|
+
/** Signs a request. Same parameters as AwsClient.sign(). Returns an unsigned Request when signing is skipped. */
|
|
442
|
+
sign: AwsClient['sign'];
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
export const useSigV4 = (): SigV4Client => {
|
|
217
446
|
const { cognitoProps } = useRuntimeConfig();
|
|
218
447
|
const auth = useAuth();
|
|
219
448
|
const user = auth?.user;
|
|
@@ -222,6 +451,8 @@ export const useSigV4 = () => {
|
|
|
222
451
|
{},
|
|
223
452
|
);
|
|
224
453
|
|
|
454
|
+
const skipSigning = !cognitoProps && import.meta.env.MODE === 'serve-local';
|
|
455
|
+
|
|
225
456
|
const withCachedCredentials = useCallback(
|
|
226
457
|
async (
|
|
227
458
|
provider: AwsCredentialIdentityProvider,
|
|
@@ -244,37 +475,53 @@ export const useSigV4 = () => {
|
|
|
244
475
|
[],
|
|
245
476
|
);
|
|
246
477
|
|
|
247
|
-
|
|
478
|
+
const getAwsClient = useCallback(async (): Promise<AwsClient> => {
|
|
479
|
+
if (!cognitoProps) {
|
|
480
|
+
throw new Error('cognitoProps is undefined!');
|
|
481
|
+
}
|
|
482
|
+
if (!user?.id_token) {
|
|
483
|
+
throw new Error('user.id_token is undefined!');
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
const credentialsFromCognitoIdentityPool = fromCognitoIdentityPool({
|
|
487
|
+
client: new CognitoIdentityClient({ region: cognitoProps.region }),
|
|
488
|
+
identityPoolId: cognitoProps.identityPoolId,
|
|
489
|
+
logins: {
|
|
490
|
+
[\`cognito-idp.\${cognitoProps.region}.amazonaws.com/\${cognitoProps.userPoolId}\`]:
|
|
491
|
+
user.id_token,
|
|
492
|
+
},
|
|
493
|
+
});
|
|
494
|
+
const credential = await withCachedCredentials(
|
|
495
|
+
credentialsFromCognitoIdentityPool,
|
|
496
|
+
cognitoProps.identityPoolId,
|
|
497
|
+
user.profile.sub,
|
|
498
|
+
);
|
|
499
|
+
return new AwsClient(credential);
|
|
500
|
+
}, [cognitoProps, user?.id_token, user?.profile.sub, withCachedCredentials]);
|
|
501
|
+
|
|
502
|
+
const sigv4Fetch: typeof globalThis.fetch = useCallback(
|
|
248
503
|
async (input: RequestInfo | URL, init?: RequestInit | undefined) => {
|
|
249
|
-
if (
|
|
250
|
-
// Skip request signing in serve-local mode when cognitoProps are not set
|
|
504
|
+
if (skipSigning) {
|
|
251
505
|
return fetch(input, init);
|
|
252
506
|
}
|
|
253
|
-
|
|
254
|
-
throw new Error('cognitoProps is undefined!');
|
|
255
|
-
}
|
|
256
|
-
if (!user?.id_token) {
|
|
257
|
-
throw new Error('user.id_token is undefined!');
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
const credentialsFromCognitoIdentityPool = fromCognitoIdentityPool({
|
|
261
|
-
client: new CognitoIdentityClient({ region: cognitoProps.region }),
|
|
262
|
-
identityPoolId: cognitoProps.identityPoolId,
|
|
263
|
-
logins: {
|
|
264
|
-
[\`cognito-idp.\${cognitoProps.region}.amazonaws.com/\${cognitoProps.userPoolId}\`]:
|
|
265
|
-
user.id_token,
|
|
266
|
-
},
|
|
267
|
-
});
|
|
268
|
-
const credential = await withCachedCredentials(
|
|
269
|
-
credentialsFromCognitoIdentityPool,
|
|
270
|
-
cognitoProps.identityPoolId,
|
|
271
|
-
user.profile.sub,
|
|
272
|
-
);
|
|
273
|
-
const awsClient = new AwsClient(credential);
|
|
507
|
+
const awsClient = await getAwsClient();
|
|
274
508
|
return awsClient.fetch(input, init);
|
|
275
509
|
},
|
|
276
|
-
[
|
|
510
|
+
[skipSigning, getAwsClient],
|
|
277
511
|
);
|
|
512
|
+
|
|
513
|
+
const sign = useCallback(
|
|
514
|
+
async (input: AwsSignInput, init?: AwsSignInit): Promise<Request> => {
|
|
515
|
+
if (skipSigning) {
|
|
516
|
+
return new Request(input.toString(), init ?? undefined);
|
|
517
|
+
}
|
|
518
|
+
const awsClient = await getAwsClient();
|
|
519
|
+
return awsClient.sign(input, init);
|
|
520
|
+
},
|
|
521
|
+
[skipSigning, getAwsClient],
|
|
522
|
+
);
|
|
523
|
+
|
|
524
|
+
return { fetch: sigv4Fetch, sign };
|
|
278
525
|
};
|
|
279
526
|
"
|
|
280
527
|
`;
|
|
@@ -3,7 +3,14 @@ import { useQueryClient } from "@tanstack/react-query";
|
|
|
3
3
|
import { createTRPCOptionsProxy } from "@trpc/tanstack-react-query";
|
|
4
4
|
import { createContext, FC, PropsWithChildren, useMemo } from "react";
|
|
5
5
|
import { useRuntimeConfig } from "../hooks/useRuntimeConfig";
|
|
6
|
+
<%_ if (isRestApi) { _%>
|
|
7
|
+
import { TRPCClient, createTRPCClient, httpLink, httpSubscriptionLink, splitLink } from "@trpc/client";
|
|
8
|
+
<%_ if (auth !== 'None') { _%>
|
|
9
|
+
import { EventSourcePolyfill } from "event-source-polyfill";
|
|
10
|
+
<%_ } _%>
|
|
11
|
+
<%_ } else { _%>
|
|
6
12
|
import { HTTPLinkOptions, TRPCClient, createTRPCClient, httpLink } from "@trpc/client";
|
|
13
|
+
<%_ } _%>
|
|
7
14
|
<%_ if (auth === 'IAM') { _%>
|
|
8
15
|
import { useSigV4 } from "../hooks/useSigV4";
|
|
9
16
|
<%_ } else if (auth === 'Cognito') { _%>
|
|
@@ -31,10 +38,58 @@ export const <%= apiNameClassName %>ClientProvider: FC<PropsWithChildren> = ({
|
|
|
31
38
|
<%_ } _%>
|
|
32
39
|
|
|
33
40
|
const container = useMemo<<%= apiNameClassName %>TRPCContextValue>(() => {
|
|
41
|
+
<%_ if (isRestApi) { _%>
|
|
42
|
+
const client = createTRPCClient<AppRouter>({
|
|
43
|
+
links: [
|
|
44
|
+
splitLink({
|
|
45
|
+
condition: (op) => op.type === 'subscription',
|
|
46
|
+
true: httpSubscriptionLink({
|
|
47
|
+
url: apiUrl,
|
|
48
|
+
<%_ if (auth !== 'None') { _%>
|
|
49
|
+
EventSource: EventSourcePolyfill,
|
|
50
|
+
eventSourceOptions: async ({ op }) => {
|
|
51
|
+
<%_ if (auth === 'IAM') { _%>
|
|
52
|
+
const url =
|
|
53
|
+
`${apiUrl.replace(/\/$/, '')}/${op.path}` +
|
|
54
|
+
(op.input !== undefined
|
|
55
|
+
? `?input=${encodeURIComponent(JSON.stringify(op.input))}`
|
|
56
|
+
: '');
|
|
57
|
+
const signed = await sigv4Client.sign(url, { method: 'GET' });
|
|
58
|
+
const headers: Record<string, string> = {};
|
|
59
|
+
signed.headers.forEach((v, k) => {
|
|
60
|
+
headers[k] = v;
|
|
61
|
+
});
|
|
62
|
+
return { headers };
|
|
63
|
+
<%_ } else if (auth === 'Cognito') { _%>
|
|
64
|
+
return {
|
|
65
|
+
headers: {
|
|
66
|
+
Authorization: `Bearer ${user?.id_token}`,
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
<%_ } else { _%>
|
|
70
|
+
return {};
|
|
71
|
+
<%_ } _%>
|
|
72
|
+
},
|
|
73
|
+
<%_ } _%>
|
|
74
|
+
}),
|
|
75
|
+
false: httpLink({
|
|
76
|
+
url: apiUrl,
|
|
77
|
+
<%_ if (auth === 'IAM') { _%>
|
|
78
|
+
fetch: sigv4Client.fetch,
|
|
79
|
+
<%_ } else if (auth === 'Cognito') { _%>
|
|
80
|
+
headers: {
|
|
81
|
+
Authorization: `Bearer ${user?.id_token}`,
|
|
82
|
+
},
|
|
83
|
+
<%_ } _%>
|
|
84
|
+
}),
|
|
85
|
+
}),
|
|
86
|
+
],
|
|
87
|
+
});
|
|
88
|
+
<%_ } else { _%>
|
|
34
89
|
const linkOptions: HTTPLinkOptions<any> = {
|
|
35
90
|
url: apiUrl,
|
|
36
91
|
<%_ if (auth === 'IAM') { _%>
|
|
37
|
-
fetch: sigv4Client,
|
|
92
|
+
fetch: sigv4Client.fetch,
|
|
38
93
|
<%_ } else if (auth === 'Cognito') { _%>
|
|
39
94
|
headers: {
|
|
40
95
|
Authorization: `Bearer ${user?.id_token}`,
|
|
@@ -45,6 +100,7 @@ export const <%= apiNameClassName %>ClientProvider: FC<PropsWithChildren> = ({
|
|
|
45
100
|
const client = createTRPCClient<AppRouter>({
|
|
46
101
|
links: [httpLink(linkOptions)],
|
|
47
102
|
});
|
|
103
|
+
<%_ } _%>
|
|
48
104
|
|
|
49
105
|
const optionsProxy = createTRPCOptionsProxy<AppRouter>({
|
|
50
106
|
client,
|