@aws/nx-plugin 0.26.0 → 0.28.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/package.json +1 -1
- package/src/api-connection/generator.js +0 -2
- package/src/api-connection/generator.js.map +1 -1
- package/src/api-connection/schema.d.ts +0 -1
- package/src/api-connection/schema.json +0 -7
- package/src/cloudscape-website/app/generator.js +1 -0
- package/src/cloudscape-website/app/generator.js.map +1 -1
- package/src/infra/app/__snapshots__/generator.spec.ts.snap +9 -0
- package/src/infra/app/generator.js +1 -0
- package/src/infra/app/generator.js.map +1 -1
- package/src/py/fast-api/__snapshots__/generator.spec.ts.snap +31 -30
- package/src/py/fast-api/generator.js +3 -0
- package/src/py/fast-api/generator.js.map +1 -1
- package/src/py/fast-api/react/__snapshots__/generator.spec.ts.snap +68 -1
- package/src/py/fast-api/react/files/website/components/__apiNameClassName__Provider.tsx.template +27 -1
- package/src/py/fast-api/react/generator.js +7 -17
- package/src/py/fast-api/react/generator.js.map +1 -1
- package/src/py/fast-api/react/schema.d.ts +0 -1
- package/src/py/fast-api/react/schema.json +0 -7
- package/src/py/fast-api/schema.d.ts +1 -0
- package/src/py/fast-api/schema.json +9 -1
- package/src/py/project/generator.js +1 -0
- package/src/py/project/generator.js.map +1 -1
- package/src/py/project/schema.json +7 -2
- package/src/trpc/backend/__snapshots__/generator.spec.ts.snap +680 -84
- package/src/trpc/backend/files/backend/src/client/index.ts.template +22 -2
- package/src/trpc/backend/files/backend/src/middleware/index.ts.template +2 -3
- package/src/trpc/backend/files/backend/src/router.ts.template +2 -3
- package/src/trpc/backend/generator.js +21 -5
- package/src/trpc/backend/generator.js.map +1 -1
- package/src/trpc/backend/schema.d.ts +2 -1
- package/src/trpc/backend/schema.json +10 -2
- package/src/trpc/react/__snapshots__/generator.spec.ts.snap +186 -73
- package/src/trpc/react/files/src/components/__apiNameClassName__ClientProvider.tsx.template +54 -0
- package/src/trpc/react/files/src/hooks/use__apiNameClassName__.tsx.template +2 -2
- package/src/trpc/react/generator.js +13 -69
- package/src/trpc/react/generator.js.map +1 -1
- package/src/trpc/react/schema.d.ts +0 -1
- package/src/trpc/react/schema.json +0 -7
- package/src/ts/lib/__snapshots__/generator.spec.ts.snap +9 -0
- package/src/ts/lib/generator.js +1 -0
- package/src/ts/lib/generator.js.map +1 -1
- package/src/ts/lib/schema.json +7 -2
- package/src/ts/mcp-server/__snapshots__/generator.spec.ts.snap +3 -0
- package/src/ts/mcp-server/generator.js +1 -0
- package/src/ts/mcp-server/generator.js.map +1 -1
- package/src/ts/mcp-server/schema.json +5 -0
- package/src/utils/api-constructs/api-constructs.d.ts +1 -0
- package/src/utils/api-constructs/api-constructs.js.map +1 -1
- package/src/utils/api-constructs/files/app/apis/http/__apiNameKebabCase__.ts.template +53 -2
- package/src/utils/api-constructs/files/app/apis/rest/__apiNameKebabCase__.ts.template +57 -2
- package/src/utils/api-constructs/files/core/api/http/http-api.ts.template +1 -15
- package/src/utils/api-constructs/files/core/api/rest/rest-api.ts.template +0 -14
- package/src/utils/nx.d.ts +4 -0
- package/src/utils/nx.js +9 -1
- package/src/utils/nx.js.map +1 -1
- package/src/api-connection/README.md +0 -0
- package/src/cloudscape-website/app/README.md +0 -289
- package/src/cloudscape-website/cognito-auth/README.md +0 -193
- package/src/infra/app/README.md +0 -200
- package/src/license/README.md +0 -290
- package/src/trpc/backend/README.md +0 -571
- package/src/trpc/backend/files/backend/src/client/sigv4.ts.template +0 -9
- package/src/trpc/react/README.md +0 -330
- package/src/trpc/react/files/src/components/TrpcClients/TrpcApis.tsx.template +0 -1
- package/src/trpc/react/files/src/components/TrpcClients/TrpcClientProviders.tsx.template +0 -10
- package/src/trpc/react/files/src/components/TrpcClients/TrpcProvider.tsx.template +0 -55
- package/src/trpc/react/files/src/components/TrpcClients/index.tsx.template +0 -5
|
@@ -3,18 +3,38 @@ import {
|
|
|
3
3
|
httpLink,
|
|
4
4
|
HTTPLinkOptions,
|
|
5
5
|
} from '@trpc/client';
|
|
6
|
-
|
|
6
|
+
<%_ if (auth === 'IAM') { _%>
|
|
7
|
+
import { AwsClient } from 'aws4fetch';
|
|
8
|
+
import { fromNodeProviderChain } from '@aws-sdk/credential-providers';
|
|
9
|
+
<%_ } _%>
|
|
7
10
|
import { AppRouter } from "../router.js";
|
|
8
|
-
import { sigv4Fetch } from './sigv4.js';
|
|
9
11
|
|
|
12
|
+
<%_ if (auth === 'IAM') { %>
|
|
13
|
+
const credentialProvider = fromNodeProviderChain();
|
|
14
|
+
|
|
15
|
+
const sigv4Fetch = (async (...args) => {
|
|
16
|
+
const client = new AwsClient(await credentialProvider());
|
|
17
|
+
return client.fetch(...args);
|
|
18
|
+
}) satisfies AwsClient['fetch'];
|
|
19
|
+
|
|
20
|
+
<%_ } _%>
|
|
10
21
|
export interface <%= apiNameClassName %>ClientConfig {
|
|
11
22
|
readonly url: string;
|
|
23
|
+
<%_ if (auth === 'Cognito') { _%>
|
|
24
|
+
readonly token: string;
|
|
25
|
+
<%_ } _%>
|
|
12
26
|
}
|
|
13
27
|
|
|
14
28
|
export const create<%= apiNameClassName %>Client = (config: <%= apiNameClassName %>ClientConfig) => {
|
|
15
29
|
const linkOptions: HTTPLinkOptions<any> = {
|
|
16
30
|
url: config.url,
|
|
31
|
+
<%_ if (auth === 'IAM') { _%>
|
|
17
32
|
fetch: sigv4Fetch,
|
|
33
|
+
<%_ } else if (auth === 'Cognito') { _%>
|
|
34
|
+
headers: {
|
|
35
|
+
Authorization: `Bearer ${config.token}`,
|
|
36
|
+
},
|
|
37
|
+
<%_ } _%>
|
|
18
38
|
};
|
|
19
39
|
return createTRPCClient<AppRouter>({
|
|
20
40
|
links: [httpLink(linkOptions)],
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { CreateAWSLambdaContextOptions } from '@trpc/server/adapters/aws-lambda';
|
|
2
|
-
|
|
3
|
-
import type { <%- eventType %> } from 'aws-lambda';
|
|
2
|
+
import type { <%- apiGatewayEventType %> } from 'aws-lambda';
|
|
4
3
|
import { ILoggerContext } from './logger.js';
|
|
5
4
|
import { IMetricsContext } from './metrics.js';
|
|
6
5
|
import { ITracerContext } from './tracer.js';
|
|
@@ -10,7 +9,7 @@ export * from './metrics.js';
|
|
|
10
9
|
export * from './tracer.js';
|
|
11
10
|
export * from './error.js';
|
|
12
11
|
|
|
13
|
-
export type IMiddlewareContext = CreateAWSLambdaContextOptions<<%-
|
|
12
|
+
export type IMiddlewareContext = CreateAWSLambdaContextOptions<<%- apiGatewayEventType %>>
|
|
14
13
|
& ILoggerContext
|
|
15
14
|
& IMetricsContext
|
|
16
15
|
& ITracerContext;
|
|
@@ -4,8 +4,7 @@ import {
|
|
|
4
4
|
} from '@trpc/server/adapters/aws-lambda';
|
|
5
5
|
import { echo } from './procedures/echo.js';
|
|
6
6
|
import { t } from './init.js';
|
|
7
|
-
|
|
8
|
-
import type { <%- eventType %> } from 'aws-lambda';
|
|
7
|
+
import type { <%- apiGatewayEventType %> } from 'aws-lambda';
|
|
9
8
|
|
|
10
9
|
export const router = t.router;
|
|
11
10
|
|
|
@@ -15,7 +14,7 @@ export const appRouter = router({
|
|
|
15
14
|
|
|
16
15
|
export const handler = awsLambdaRequestHandler({
|
|
17
16
|
router: appRouter,
|
|
18
|
-
createContext: (ctx: CreateAWSLambdaContextOptions<<%-
|
|
17
|
+
createContext: (ctx: CreateAWSLambdaContextOptions<<%- apiGatewayEventType %>>) => ctx,
|
|
19
18
|
<%_ if (computeType === 'ServerlessApiGatewayRestApi') { _%>
|
|
20
19
|
responseMeta: () => ({
|
|
21
20
|
headers: {
|
|
@@ -26,18 +26,18 @@ function tsTrpcApiGenerator(tree, options) {
|
|
|
26
26
|
var _a;
|
|
27
27
|
yield (0, shared_constructs_1.sharedConstructsGenerator)(tree);
|
|
28
28
|
const apiNamespace = (0, npm_scope_1.getNpmScopePrefix)(tree);
|
|
29
|
-
const apiNameKebabCase = (0, lodash_kebabcase_1.default)(options.
|
|
30
|
-
const apiNameClassName = (0, names_1.toClassName)(options.
|
|
29
|
+
const apiNameKebabCase = (0, lodash_kebabcase_1.default)(options.name);
|
|
30
|
+
const apiNameClassName = (0, names_1.toClassName)(options.name);
|
|
31
31
|
const projectRoot = (0, devkit_1.joinPathFragments)((_a = options.directory) !== null && _a !== void 0 ? _a : '.', apiNameKebabCase);
|
|
32
32
|
const schemaRoot = (0, devkit_1.joinPathFragments)(projectRoot, 'schema');
|
|
33
33
|
const backendRoot = (0, devkit_1.joinPathFragments)(projectRoot, 'backend');
|
|
34
|
-
const backendName =
|
|
34
|
+
const backendName = apiNameKebabCase;
|
|
35
35
|
const schemaName = `${apiNameKebabCase}-schema`;
|
|
36
36
|
const backendProjectName = `${apiNamespace}${backendName}`;
|
|
37
37
|
const schemaProjectName = `${apiNamespace}${schemaName}`;
|
|
38
38
|
const enhancedOptions = Object.assign({ backendProjectName, backendProjectAlias: (0, npm_scope_1.toScopeAlias)(backendProjectName), schemaProjectName, schemaProjectAlias: (0, npm_scope_1.toScopeAlias)(schemaProjectName), apiNameKebabCase,
|
|
39
39
|
apiNameClassName,
|
|
40
|
-
backendRoot, pkgMgrCmd: (0, devkit_1.getPackageManagerCommand)().exec }, options);
|
|
40
|
+
backendRoot, pkgMgrCmd: (0, devkit_1.getPackageManagerCommand)().exec, apiGatewayEventType: getApiGatewayEventType(options) }, options);
|
|
41
41
|
yield (0, generator_1.default)(tree, {
|
|
42
42
|
name: backendName,
|
|
43
43
|
directory: projectRoot,
|
|
@@ -57,12 +57,14 @@ function tsTrpcApiGenerator(tree, options) {
|
|
|
57
57
|
projectAlias: enhancedOptions.backendProjectAlias,
|
|
58
58
|
dir: backendRoot,
|
|
59
59
|
},
|
|
60
|
+
auth: options.auth,
|
|
60
61
|
});
|
|
61
62
|
(0, devkit_1.updateJson)(tree, (0, devkit_1.joinPathFragments)(backendRoot, 'project.json'), (config) => {
|
|
62
63
|
var _a;
|
|
63
64
|
config.metadata = {
|
|
64
|
-
apiName: options.
|
|
65
|
+
apiName: options.name,
|
|
65
66
|
apiType: 'trpc',
|
|
67
|
+
auth: options.auth,
|
|
66
68
|
};
|
|
67
69
|
config.targets.serve = {
|
|
68
70
|
executor: 'nx:run-commands',
|
|
@@ -121,6 +123,8 @@ function tsTrpcApiGenerator(tree, options) {
|
|
|
121
123
|
]), (0, versions_1.withVersions)(['@types/aws-lambda', 'esbuild', 'tsx']));
|
|
122
124
|
tree.delete((0, devkit_1.joinPathFragments)(backendRoot, 'package.json'));
|
|
123
125
|
tree.delete((0, devkit_1.joinPathFragments)(schemaRoot, 'package.json'));
|
|
126
|
+
(0, nx_1.addGeneratorMetadata)(tree, backendName, exports.TRPC_BACKEND_GENERATOR_INFO);
|
|
127
|
+
(0, nx_1.addGeneratorMetadata)(tree, schemaName, exports.TRPC_BACKEND_GENERATOR_INFO);
|
|
124
128
|
yield (0, metrics_1.addGeneratorMetricsIfApplicable)(tree, [exports.TRPC_BACKEND_GENERATOR_INFO]);
|
|
125
129
|
yield (0, format_1.formatFilesInSubtree)(tree);
|
|
126
130
|
return () => {
|
|
@@ -128,5 +132,17 @@ function tsTrpcApiGenerator(tree, options) {
|
|
|
128
132
|
};
|
|
129
133
|
});
|
|
130
134
|
}
|
|
135
|
+
const getApiGatewayEventType = (options) => {
|
|
136
|
+
if (options.computeType === 'ServerlessApiGatewayRestApi') {
|
|
137
|
+
return 'APIGatewayProxyEvent';
|
|
138
|
+
}
|
|
139
|
+
if (options.auth === 'IAM') {
|
|
140
|
+
return 'APIGatewayProxyEventV2WithIAMAuthorizer';
|
|
141
|
+
}
|
|
142
|
+
else if (options.auth === 'Cognito') {
|
|
143
|
+
return 'APIGatewayProxyEventV2WithJWTAuthorizer';
|
|
144
|
+
}
|
|
145
|
+
return 'APIGatewayProxyEventV2';
|
|
146
|
+
};
|
|
131
147
|
exports.default = tsTrpcApiGenerator;
|
|
132
148
|
//# sourceMappingURL=generator.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../../../packages/nx-plugin/src/trpc/backend/generator.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../../../../packages/nx-plugin/src/trpc/backend/generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
import { Linter } from '@nx/eslint';
|
|
6
6
|
|
|
7
7
|
export interface TsTrpcApiGeneratorSchema {
|
|
8
|
-
|
|
8
|
+
name: string;
|
|
9
9
|
computeType: 'ServerlessApiGatewayRestApi' | 'ServerlessApiGatewayHttpApi';
|
|
10
|
+
auth: 'IAM' | 'Cognito' | 'None';
|
|
10
11
|
directory?: TsLibGeneratorSchema['directory'];
|
|
11
12
|
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"title": "",
|
|
5
5
|
"type": "object",
|
|
6
6
|
"properties": {
|
|
7
|
-
"
|
|
7
|
+
"name": {
|
|
8
8
|
"type": "string",
|
|
9
9
|
"description": "The name of the API (required). Used to generate class names and file paths.",
|
|
10
10
|
"$default": {
|
|
@@ -21,6 +21,14 @@
|
|
|
21
21
|
"x-prompt": "What compute type would you like to deploy your API with?",
|
|
22
22
|
"x-priority": "important"
|
|
23
23
|
},
|
|
24
|
+
"auth": {
|
|
25
|
+
"type": "string",
|
|
26
|
+
"description": "The method used to authenticate with your API. Choose between IAM (default), Cognito or None.",
|
|
27
|
+
"default": "IAM",
|
|
28
|
+
"enum": ["IAM", "Cognito", "None"],
|
|
29
|
+
"x-prompt": "How would you like users to authenticate with your API?",
|
|
30
|
+
"x-priority": "important"
|
|
31
|
+
},
|
|
24
32
|
"directory": {
|
|
25
33
|
"description": "The directory to store the application in.",
|
|
26
34
|
"type": "string",
|
|
@@ -30,5 +38,5 @@
|
|
|
30
38
|
"x-prompt": "What directory would you like to store your application in?"
|
|
31
39
|
}
|
|
32
40
|
},
|
|
33
|
-
"required": ["
|
|
41
|
+
"required": ["name"]
|
|
34
42
|
}
|
|
@@ -1,104 +1,217 @@
|
|
|
1
1
|
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
2
|
|
|
3
|
-
exports[`trpc react generator > should generate trpc react files >
|
|
4
|
-
"import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
} from '
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
};
|
|
12
|
-
"
|
|
13
|
-
`;
|
|
3
|
+
exports[`trpc react generator > should generate trpc react files > TestApiClientProvider.tsx 1`] = `
|
|
4
|
+
"import { AppRouter } from 'backend';
|
|
5
|
+
import { useQueryClient } from '@tanstack/react-query';
|
|
6
|
+
import { createTRPCContext } from '@trpc/tanstack-react-query';
|
|
7
|
+
import { FC, PropsWithChildren, useMemo } from 'react';
|
|
8
|
+
import { useRuntimeConfig } from '../hooks/useRuntimeConfig';
|
|
9
|
+
import { HTTPLinkOptions, createTRPCClient, httpLink } from '@trpc/client';
|
|
10
|
+
|
|
11
|
+
const { TRPCProvider, useTRPC } = createTRPCContext<AppRouter>();
|
|
14
12
|
|
|
15
|
-
|
|
16
|
-
"import TrpcApis from './TrpcApis';
|
|
17
|
-
import { useRuntimeConfig } from '../../hooks/useRuntimeConfig';
|
|
18
|
-
import { FC, PropsWithChildren } from 'react';
|
|
13
|
+
export const useTestApi = useTRPC;
|
|
19
14
|
|
|
20
|
-
const
|
|
15
|
+
export const TestApiClientProvider: FC<PropsWithChildren> = ({ children }) => {
|
|
16
|
+
const queryClient = useQueryClient();
|
|
21
17
|
const runtimeConfig = useRuntimeConfig();
|
|
18
|
+
const apiUrl = runtimeConfig.apis.TestApi;
|
|
19
|
+
|
|
20
|
+
const trpcClient = useMemo(() => {
|
|
21
|
+
const linkOptions: HTTPLinkOptions<any> = {
|
|
22
|
+
url: apiUrl,
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
return createTRPCClient<AppRouter>({
|
|
26
|
+
links: [httpLink(linkOptions)],
|
|
27
|
+
});
|
|
28
|
+
}, [apiUrl]);
|
|
29
|
+
|
|
22
30
|
return (
|
|
23
|
-
<
|
|
31
|
+
<TRPCProvider trpcClient={trpcClient} queryClient={queryClient}>
|
|
24
32
|
{children}
|
|
25
|
-
</
|
|
33
|
+
</TRPCProvider>
|
|
26
34
|
);
|
|
27
35
|
};
|
|
28
36
|
|
|
29
|
-
export default
|
|
37
|
+
export default TestApiClientProvider;
|
|
38
|
+
"
|
|
39
|
+
`;
|
|
40
|
+
|
|
41
|
+
exports[`trpc react generator > should generate trpc react files > useTestApi.tsx 1`] = `
|
|
42
|
+
"import { useTestApi as useClient } from '../components/TestApiClientProvider';
|
|
43
|
+
|
|
44
|
+
export const useTestApi = useClient;
|
|
30
45
|
"
|
|
31
46
|
`;
|
|
32
47
|
|
|
33
|
-
exports[`trpc react generator > should
|
|
34
|
-
"import {
|
|
48
|
+
exports[`trpc react generator > should handle Cognito auth option > TestApiClientProvider-Cognito.tsx 1`] = `
|
|
49
|
+
"import { AppRouter } from 'backend';
|
|
50
|
+
import { useQueryClient } from '@tanstack/react-query';
|
|
35
51
|
import { createTRPCContext } from '@trpc/tanstack-react-query';
|
|
36
|
-
import {
|
|
37
|
-
import {
|
|
52
|
+
import { FC, PropsWithChildren, useMemo } from 'react';
|
|
53
|
+
import { useRuntimeConfig } from '../hooks/useRuntimeConfig';
|
|
54
|
+
import { HTTPLinkOptions, createTRPCClient, httpLink } from '@trpc/client';
|
|
55
|
+
import { useAuth } from 'react-oidc-context';
|
|
38
56
|
|
|
39
|
-
|
|
57
|
+
const { TRPCProvider, useTRPC } = createTRPCContext<AppRouter>();
|
|
40
58
|
|
|
41
|
-
export
|
|
42
|
-
readonly apiUrl: string;
|
|
43
|
-
}
|
|
59
|
+
export const useTestApi = useTRPC;
|
|
44
60
|
|
|
45
|
-
export const
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
</TRPCProvider>
|
|
71
|
-
);
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
return {
|
|
75
|
-
useTRPC,
|
|
76
|
-
Provider: TrpcClientProvider,
|
|
77
|
-
};
|
|
61
|
+
export const TestApiClientProvider: FC<PropsWithChildren> = ({ children }) => {
|
|
62
|
+
const queryClient = useQueryClient();
|
|
63
|
+
const runtimeConfig = useRuntimeConfig();
|
|
64
|
+
const apiUrl = runtimeConfig.apis.TestApi;
|
|
65
|
+
|
|
66
|
+
const { user } = useAuth();
|
|
67
|
+
|
|
68
|
+
const trpcClient = useMemo(() => {
|
|
69
|
+
const linkOptions: HTTPLinkOptions<any> = {
|
|
70
|
+
url: apiUrl,
|
|
71
|
+
headers: {
|
|
72
|
+
Authorization: \`Bearer \${user?.id_token}\`,
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
return createTRPCClient<AppRouter>({
|
|
77
|
+
links: [httpLink(linkOptions)],
|
|
78
|
+
});
|
|
79
|
+
}, [apiUrl, user]);
|
|
80
|
+
|
|
81
|
+
return (
|
|
82
|
+
<TRPCProvider trpcClient={trpcClient} queryClient={queryClient}>
|
|
83
|
+
{children}
|
|
84
|
+
</TRPCProvider>
|
|
85
|
+
);
|
|
78
86
|
};
|
|
87
|
+
|
|
88
|
+
export default TestApiClientProvider;
|
|
79
89
|
"
|
|
80
90
|
`;
|
|
81
91
|
|
|
82
|
-
exports[`trpc react generator > should
|
|
83
|
-
"import
|
|
84
|
-
import
|
|
92
|
+
exports[`trpc react generator > should handle IAM auth option > TestApiClientProvider-IAM.tsx 1`] = `
|
|
93
|
+
"import { AppRouter } from 'backend';
|
|
94
|
+
import { useQueryClient } from '@tanstack/react-query';
|
|
95
|
+
import { createTRPCContext } from '@trpc/tanstack-react-query';
|
|
96
|
+
import { FC, PropsWithChildren, useMemo } from 'react';
|
|
97
|
+
import { useRuntimeConfig } from '../hooks/useRuntimeConfig';
|
|
98
|
+
import { HTTPLinkOptions, createTRPCClient, httpLink } from '@trpc/client';
|
|
99
|
+
import { useSigV4 } from '../hooks/useSigV4';
|
|
100
|
+
|
|
101
|
+
const { TRPCProvider, useTRPC } = createTRPCContext<AppRouter>();
|
|
102
|
+
|
|
103
|
+
export const useTestApi = useTRPC;
|
|
104
|
+
|
|
105
|
+
export const TestApiClientProvider: FC<PropsWithChildren> = ({ children }) => {
|
|
106
|
+
const queryClient = useQueryClient();
|
|
107
|
+
const runtimeConfig = useRuntimeConfig();
|
|
108
|
+
const apiUrl = runtimeConfig.apis.TestApi;
|
|
109
|
+
|
|
110
|
+
const sigv4Client = useSigV4();
|
|
111
|
+
|
|
112
|
+
const trpcClient = useMemo(() => {
|
|
113
|
+
const linkOptions: HTTPLinkOptions<any> = {
|
|
114
|
+
url: apiUrl,
|
|
115
|
+
fetch: sigv4Client,
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
return createTRPCClient<AppRouter>({
|
|
119
|
+
links: [httpLink(linkOptions)],
|
|
120
|
+
});
|
|
121
|
+
}, [apiUrl, sigv4Client]);
|
|
122
|
+
|
|
123
|
+
return (
|
|
124
|
+
<TRPCProvider trpcClient={trpcClient} queryClient={queryClient}>
|
|
125
|
+
{children}
|
|
126
|
+
</TRPCProvider>
|
|
127
|
+
);
|
|
128
|
+
};
|
|
85
129
|
|
|
86
|
-
export
|
|
87
|
-
export default TrpcClientProviders;
|
|
130
|
+
export default TestApiClientProvider;
|
|
88
131
|
"
|
|
89
132
|
`;
|
|
90
133
|
|
|
91
|
-
exports[`trpc react generator > should
|
|
92
|
-
"import {
|
|
134
|
+
exports[`trpc react generator > should handle IAM auth option > useSigV4.tsx 1`] = `
|
|
135
|
+
"import { AwsClient } from 'aws4fetch';
|
|
136
|
+
import { CognitoIdentityClient } from '@aws-sdk/client-cognito-identity';
|
|
137
|
+
import { fromCognitoIdentityPool } from '@aws-sdk/credential-provider-cognito-identity';
|
|
138
|
+
import { useCallback, useState } from 'react';
|
|
139
|
+
import { useAuth } from 'react-oidc-context';
|
|
140
|
+
import { useRuntimeConfig } from './useRuntimeConfig';
|
|
141
|
+
import {
|
|
142
|
+
AwsCredentialIdentity,
|
|
143
|
+
AwsCredentialIdentityProvider,
|
|
144
|
+
} from '@smithy/types';
|
|
145
|
+
|
|
146
|
+
// Credential expiration grace time before considering credentials as expired
|
|
147
|
+
const CREDENTIAL_EXPIRY_OFFSET_MILLIS = 30 * 1000;
|
|
148
|
+
|
|
149
|
+
export const useSigV4 = () => {
|
|
150
|
+
const { cognitoProps } = useRuntimeConfig();
|
|
151
|
+
const { user } = useAuth();
|
|
152
|
+
|
|
153
|
+
const [cachedCredentials, setCachedCredentials] = useState<{
|
|
154
|
+
[key: string]: AwsCredentialIdentity;
|
|
155
|
+
}>({});
|
|
156
|
+
|
|
157
|
+
const withCachedCredentials = useCallback(
|
|
158
|
+
async (
|
|
159
|
+
provider: AwsCredentialIdentityProvider,
|
|
160
|
+
...cacheKeys: string[]
|
|
161
|
+
): Promise<AwsCredentialIdentity> => {
|
|
162
|
+
const key = \`sigv4/\${cacheKeys.join('/')}\`;
|
|
163
|
+
const cachedCreds = cachedCredentials[key];
|
|
164
|
+
if (
|
|
165
|
+
cachedCreds &&
|
|
166
|
+
cachedCreds.expiration &&
|
|
167
|
+
cachedCreds.expiration.getTime() >
|
|
168
|
+
Date.now() + CREDENTIAL_EXPIRY_OFFSET_MILLIS
|
|
169
|
+
) {
|
|
170
|
+
return cachedCreds;
|
|
171
|
+
}
|
|
172
|
+
const credentials = await provider();
|
|
173
|
+
setCachedCredentials((prev) => ({ ...prev, [key]: credentials }));
|
|
174
|
+
return credentials;
|
|
175
|
+
},
|
|
176
|
+
[cachedCredentials, setCachedCredentials],
|
|
177
|
+
);
|
|
93
178
|
|
|
94
|
-
|
|
179
|
+
return useCallback(
|
|
180
|
+
async (input: RequestInfo | URL, init?: RequestInit | undefined) => {
|
|
181
|
+
if (!cognitoProps) {
|
|
182
|
+
throw new Error('cognitoProps is undefined!');
|
|
183
|
+
}
|
|
184
|
+
if (!user?.id_token) {
|
|
185
|
+
throw new Error('user.id_token is undefined!');
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const credentialsFromCognitoIdentityPool = fromCognitoIdentityPool({
|
|
189
|
+
client: new CognitoIdentityClient({ region: cognitoProps.region }),
|
|
190
|
+
identityPoolId: cognitoProps.identityPoolId,
|
|
191
|
+
logins: {
|
|
192
|
+
[\`cognito-idp.\${cognitoProps.region}.amazonaws.com/\${cognitoProps.userPoolId}\`]:
|
|
193
|
+
user.id_token,
|
|
194
|
+
},
|
|
195
|
+
});
|
|
196
|
+
const cognitoidentity = new CognitoIdentityClient({
|
|
197
|
+
credentials: credentialsFromCognitoIdentityPool,
|
|
198
|
+
});
|
|
199
|
+
const credential = await withCachedCredentials(
|
|
200
|
+
cognitoidentity.config.credentials,
|
|
201
|
+
cognitoProps.identityPoolId,
|
|
202
|
+
user.profile.sub,
|
|
203
|
+
);
|
|
204
|
+
const awsClient = new AwsClient(credential);
|
|
205
|
+
return awsClient.fetch(input, init);
|
|
206
|
+
},
|
|
207
|
+
[cognitoProps, user?.id_token, user?.profile.sub, withCachedCredentials],
|
|
208
|
+
);
|
|
209
|
+
};
|
|
95
210
|
"
|
|
96
211
|
`;
|
|
97
212
|
|
|
98
|
-
exports[`trpc react generator > should handle IAM auth option > TRPCClientProvider-IAM.tsx 1`] = `null`;
|
|
99
|
-
|
|
100
213
|
exports[`trpc react generator > should modify main.tsx correctly > main.tsx 1`] = `
|
|
101
|
-
"import
|
|
214
|
+
"import TestApiClientProvider from './components/TestApiClientProvider';
|
|
102
215
|
import QueryClientProvider from './components/QueryClientProvider';
|
|
103
216
|
import RuntimeConfigProvider from './components/RuntimeConfig';
|
|
104
217
|
import { App } from './app';
|
|
@@ -108,9 +221,9 @@ export function Main() {
|
|
|
108
221
|
return (
|
|
109
222
|
<RuntimeConfigProvider>
|
|
110
223
|
<QueryClientProvider>
|
|
111
|
-
<
|
|
224
|
+
<TestApiClientProvider>
|
|
112
225
|
<RouterProvider router={router} />
|
|
113
|
-
</
|
|
226
|
+
</TestApiClientProvider>
|
|
114
227
|
</QueryClientProvider>
|
|
115
228
|
</RuntimeConfigProvider>
|
|
116
229
|
);
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { AppRouter } from "<%- backendProjectAlias %>";
|
|
2
|
+
import { useQueryClient } from "@tanstack/react-query";
|
|
3
|
+
import { createTRPCContext } from "@trpc/tanstack-react-query";
|
|
4
|
+
import { FC, PropsWithChildren, useMemo } from "react";
|
|
5
|
+
import { useRuntimeConfig } from "../hooks/useRuntimeConfig";
|
|
6
|
+
import { HTTPLinkOptions, createTRPCClient, httpLink } from "@trpc/client";
|
|
7
|
+
<%_ if (auth === 'IAM') { _%>
|
|
8
|
+
import { useSigV4 } from "../hooks/useSigV4";
|
|
9
|
+
<%_ } else if (auth === 'Cognito') { _%>
|
|
10
|
+
import { useAuth } from "react-oidc-context";
|
|
11
|
+
<%_ } _%>
|
|
12
|
+
|
|
13
|
+
const { TRPCProvider, useTRPC } = createTRPCContext<AppRouter>();
|
|
14
|
+
|
|
15
|
+
export const use<%= apiNameClassName %> = useTRPC;
|
|
16
|
+
|
|
17
|
+
export const <%= apiNameClassName %>ClientProvider: FC<PropsWithChildren> = ({
|
|
18
|
+
children,
|
|
19
|
+
}) => {
|
|
20
|
+
const queryClient = useQueryClient();
|
|
21
|
+
const runtimeConfig = useRuntimeConfig();
|
|
22
|
+
const apiUrl = runtimeConfig.apis.<%= apiNameClassName %>;
|
|
23
|
+
|
|
24
|
+
<%_ if (auth === 'IAM') { _%>
|
|
25
|
+
const sigv4Client = useSigV4();
|
|
26
|
+
<%_ } else if (auth === 'Cognito') { _%>
|
|
27
|
+
const { user } = useAuth();
|
|
28
|
+
<%_ } _%>
|
|
29
|
+
|
|
30
|
+
const trpcClient = useMemo(() => {
|
|
31
|
+
const linkOptions: HTTPLinkOptions<any> = {
|
|
32
|
+
url: apiUrl,
|
|
33
|
+
<%_ if (auth === 'IAM') { _%>
|
|
34
|
+
fetch: sigv4Client,
|
|
35
|
+
<%_ } else if (auth === 'Cognito') { _%>
|
|
36
|
+
headers: {
|
|
37
|
+
Authorization: `Bearer ${user?.id_token}`,
|
|
38
|
+
},
|
|
39
|
+
<%_ } _%>
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
return createTRPCClient<AppRouter>({
|
|
43
|
+
links: [httpLink(linkOptions)],
|
|
44
|
+
});
|
|
45
|
+
}, [apiUrl<% if (auth === 'IAM') { %>, sigv4Client<% } else if (auth === 'Cognito') { %>, user<% } %>]);
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<TRPCProvider trpcClient={trpcClient} queryClient={queryClient}>
|
|
49
|
+
{children}
|
|
50
|
+
</TRPCProvider>
|
|
51
|
+
);
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export default <%= apiNameClassName %>ClientProvider;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { use<%- apiNameClassName %> as useClient } from '../components/<%- apiNameClassName %>ClientProvider';
|
|
2
2
|
|
|
3
|
-
export const use
|
|
3
|
+
export const use<%- apiNameClassName %> = useClient;
|