@aws/nx-plugin 0.37.1 → 0.38.1
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/README.md +2 -2
- package/generators.json +14 -14
- package/package.json +1 -1
- package/sdk/ts.d.ts +6 -6
- package/sdk/ts.js +8 -8
- package/sdk/ts.js.map +1 -1
- package/src/mcp-server/tools/general-guidance.js +1 -1
- package/src/preset/__snapshots__/generator.spec.ts.snap +2 -2
- package/src/py/fast-api/react/__snapshots__/generator.spec.ts.snap +0 -1
- package/src/py/fast-api/react/generator.js +1 -1
- package/src/py/fast-api/react/generator.js.map +1 -1
- package/src/py/project/generator.js +1 -1
- package/src/py/project/generator.js.map +1 -1
- package/src/trpc/react/__snapshots__/generator.spec.ts.snap +0 -1
- package/src/trpc/react/generator.js +1 -1
- package/src/trpc/react/generator.js.map +1 -1
- package/src/ts/lib/generator.js +1 -1
- package/src/ts/lib/generator.js.map +1 -1
- package/src/ts/react-website/app/__snapshots__/generator.spec.ts.snap +4038 -0
- package/src/{cloudscape-website → ts/react-website}/app/files/app/README.md.template +1 -1
- package/src/ts/react-website/app/files/app/src/app.tsx.template +17 -0
- package/src/{cloudscape-website → ts/react-website}/app/files/app/src/components/AppLayout/index.tsx.template +20 -19
- package/src/{cloudscape-website → ts/react-website}/app/files/app/src/main.tsx.template +3 -4
- package/src/ts/react-website/app/files/app/src/styles.css.template +2 -0
- package/src/{cloudscape-website/app/files/app → ts/react-website/app/files/tanstack-router}/src/routes/__root.tsx.template +6 -1
- package/src/{cloudscape-website/app/files/app/src/routes/welcome → ts/react-website/app/files/tanstack-router/src/routes}/index.tsx.template +2 -2
- package/src/ts/react-website/app/generator.d.ts +10 -0
- package/src/{cloudscape-website → ts/react-website}/app/generator.js +69 -40
- package/src/ts/react-website/app/generator.js.map +1 -0
- package/src/{cloudscape-website → ts/react-website}/app/schema.d.ts +3 -1
- package/src/{cloudscape-website → ts/react-website}/app/schema.json +17 -3
- package/src/{cloudscape-website → ts/react-website}/cognito-auth/__snapshots__/generator.spec.ts.snap +1 -3
- package/src/ts/react-website/cognito-auth/generator.d.ts +10 -0
- package/src/{cloudscape-website → ts/react-website}/cognito-auth/generator.js +11 -11
- package/src/ts/react-website/cognito-auth/generator.js.map +1 -0
- package/src/{cloudscape-website → ts/react-website}/cognito-auth/schema.d.ts +1 -1
- package/src/{cloudscape-website → ts/react-website}/cognito-auth/schema.json +5 -5
- package/src/{cloudscape-website → ts/react-website}/runtime-config/__snapshots__/generator.spec.ts.snap +1 -2
- package/src/{cloudscape-website → ts/react-website}/runtime-config/generator.d.ts +1 -1
- package/src/{cloudscape-website → ts/react-website}/runtime-config/generator.js +7 -7
- package/src/ts/react-website/runtime-config/generator.js.map +1 -0
- package/src/utils/ast/website.js +1 -1
- package/src/utils/ast/website.js.map +1 -1
- package/src/utils/versions.d.ts +4 -1
- package/src/utils/versions.js +2 -0
- package/src/utils/versions.js.map +1 -1
- package/src/cloudscape-website/app/__snapshots__/generator.spec.ts.snap +0 -590
- package/src/cloudscape-website/app/files/app/src/components/AppLayout/navitems.ts.template +0 -8
- package/src/cloudscape-website/app/files/app/src/routes/index.tsx.template +0 -5
- package/src/cloudscape-website/app/files/app/src/styles.css.template +0 -1
- package/src/cloudscape-website/app/generator.d.ts +0 -10
- package/src/cloudscape-website/app/generator.js.map +0 -1
- package/src/cloudscape-website/cognito-auth/generator.d.ts +0 -10
- package/src/cloudscape-website/cognito-auth/generator.js.map +0 -1
- package/src/cloudscape-website/runtime-config/generator.js.map +0 -1
- /package/src/{cloudscape-website → ts/react-website}/app/files/app/src/config.ts.template +0 -0
- /package/src/{cloudscape-website → ts/react-website}/app/files/app/src/hooks/useAppLayout.tsx.template +0 -0
- /package/src/{cloudscape-website → ts/react-website}/app/files/common/constructs/src/app/static-websites/__websiteNameKebabCase__.ts.template +0 -0
- /package/src/{cloudscape-website → ts/react-website}/app/files/common/constructs/src/core/static-website.ts.template +0 -0
- /package/src/{cloudscape-website → ts/react-website}/app/files/e2e/cypress/src/e2e/app.cy.ts.template +0 -0
- /package/src/{cloudscape-website → ts/react-website}/app/files/e2e/cypress/src/support/app.po.ts.template +0 -0
- /package/src/{cloudscape-website → ts/react-website}/app/files/e2e/playwright/src/example.spec.ts.template +0 -0
- /package/src/{cloudscape-website/app/files/app → ts/react-website/app/files/tanstack-router}/src/routeTree.gen.ts.template +0 -0
- /package/src/{cloudscape-website → ts/react-website}/cognito-auth/files/app/components/CognitoAuth/index.tsx.template +0 -0
- /package/src/{cloudscape-website → ts/react-website}/cognito-auth/files/common/constructs/src/core/user-identity.ts.template +0 -0
- /package/src/{cloudscape-website → ts/react-website}/runtime-config/files/app/components/RuntimeConfig/index.tsx.template +0 -0
- /package/src/{cloudscape-website → ts/react-website}/runtime-config/files/app/hooks/useRuntimeConfig.tsx.template +0 -0
- /package/src/{cloudscape-website → ts/react-website}/runtime-config/schema.d.ts +0 -0
- /package/src/{cloudscape-website → ts/react-website}/runtime-config/schema.json +0 -0
|
@@ -0,0 +1,4038 @@
|
|
|
1
|
+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
|
+
|
|
3
|
+
exports[`react-website generator > TailwindCSS integration > should configure vite with TailwindCSS plugin by default > vite.config.ts-with-tailwind 1`] = `
|
|
4
|
+
"import tailwindcss from '@tailwindcss/vite';
|
|
5
|
+
import tsconfigPaths from 'vite-tsconfig-paths';
|
|
6
|
+
import { resolve } from 'path';
|
|
7
|
+
import { tanstackRouter } from '@tanstack/router-plugin/vite';
|
|
8
|
+
/// <reference types='vitest' />
|
|
9
|
+
import { defineConfig } from 'vite';
|
|
10
|
+
import react from '@vitejs/plugin-react';
|
|
11
|
+
|
|
12
|
+
export default defineConfig(() => ({
|
|
13
|
+
define: {
|
|
14
|
+
global: {},
|
|
15
|
+
},
|
|
16
|
+
root: __dirname,
|
|
17
|
+
cacheDir: '../node_modules/.vite/test-app',
|
|
18
|
+
server: {
|
|
19
|
+
port: 4200,
|
|
20
|
+
host: 'localhost',
|
|
21
|
+
},
|
|
22
|
+
preview: {
|
|
23
|
+
port: 4300,
|
|
24
|
+
host: 'localhost',
|
|
25
|
+
},
|
|
26
|
+
plugins: [
|
|
27
|
+
tanstackRouter({
|
|
28
|
+
routesDirectory: resolve(__dirname, 'src/routes'),
|
|
29
|
+
generatedRouteTree: resolve(__dirname, 'src/routeTree.gen.ts'),
|
|
30
|
+
}),
|
|
31
|
+
react(),
|
|
32
|
+
tailwindcss(),
|
|
33
|
+
tsconfigPaths(),
|
|
34
|
+
],
|
|
35
|
+
build: {
|
|
36
|
+
outDir: '../dist/test-app',
|
|
37
|
+
emptyOutDir: true,
|
|
38
|
+
reportCompressedSize: true,
|
|
39
|
+
commonjsOptions: {
|
|
40
|
+
transformMixedEsModules: true,
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
test: {
|
|
44
|
+
watch: false,
|
|
45
|
+
globals: true,
|
|
46
|
+
environment: 'jsdom',
|
|
47
|
+
include: ['{src,tests}/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
|
48
|
+
reporters: ['default'],
|
|
49
|
+
coverage: {
|
|
50
|
+
reportsDirectory: './test-output/vitest/coverage',
|
|
51
|
+
provider: 'v8' as const,
|
|
52
|
+
},
|
|
53
|
+
passWithNoTests: true,
|
|
54
|
+
},
|
|
55
|
+
}));
|
|
56
|
+
"
|
|
57
|
+
`;
|
|
58
|
+
|
|
59
|
+
exports[`react-website generator > TailwindCSS integration > should configure vite without TailwindCSS plugin when disabled > vite.config.ts-without-tailwind 1`] = `
|
|
60
|
+
"import tsconfigPaths from 'vite-tsconfig-paths';
|
|
61
|
+
import { resolve } from 'path';
|
|
62
|
+
import { tanstackRouter } from '@tanstack/router-plugin/vite';
|
|
63
|
+
/// <reference types='vitest' />
|
|
64
|
+
import { defineConfig } from 'vite';
|
|
65
|
+
import react from '@vitejs/plugin-react';
|
|
66
|
+
|
|
67
|
+
export default defineConfig(() => ({
|
|
68
|
+
define: {
|
|
69
|
+
global: {},
|
|
70
|
+
},
|
|
71
|
+
root: __dirname,
|
|
72
|
+
cacheDir: '../node_modules/.vite/test-app',
|
|
73
|
+
server: {
|
|
74
|
+
port: 4200,
|
|
75
|
+
host: 'localhost',
|
|
76
|
+
},
|
|
77
|
+
preview: {
|
|
78
|
+
port: 4300,
|
|
79
|
+
host: 'localhost',
|
|
80
|
+
},
|
|
81
|
+
plugins: [
|
|
82
|
+
tanstackRouter({
|
|
83
|
+
routesDirectory: resolve(__dirname, 'src/routes'),
|
|
84
|
+
generatedRouteTree: resolve(__dirname, 'src/routeTree.gen.ts'),
|
|
85
|
+
}),
|
|
86
|
+
react(),
|
|
87
|
+
tsconfigPaths(),
|
|
88
|
+
],
|
|
89
|
+
build: {
|
|
90
|
+
outDir: '../dist/test-app',
|
|
91
|
+
emptyOutDir: true,
|
|
92
|
+
reportCompressedSize: true,
|
|
93
|
+
commonjsOptions: {
|
|
94
|
+
transformMixedEsModules: true,
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
test: {
|
|
98
|
+
watch: false,
|
|
99
|
+
globals: true,
|
|
100
|
+
environment: 'jsdom',
|
|
101
|
+
include: ['{src,tests}/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
|
102
|
+
reporters: ['default'],
|
|
103
|
+
coverage: {
|
|
104
|
+
reportsDirectory: './test-output/vitest/coverage',
|
|
105
|
+
provider: 'v8' as const,
|
|
106
|
+
},
|
|
107
|
+
passWithNoTests: true,
|
|
108
|
+
},
|
|
109
|
+
}));
|
|
110
|
+
"
|
|
111
|
+
`;
|
|
112
|
+
|
|
113
|
+
exports[`react-website generator > TailwindCSS integration > should include TailwindCSS import in styles.css by default > styles.css-with-tailwind 1`] = `
|
|
114
|
+
"@import 'tailwindcss';
|
|
115
|
+
/* You can add global styles to this file, and also import other style files */
|
|
116
|
+
"
|
|
117
|
+
`;
|
|
118
|
+
|
|
119
|
+
exports[`react-website generator > TailwindCSS integration > should not include TailwindCSS import in styles.css when disabled > styles.css-without-tailwind 1`] = `
|
|
120
|
+
"/* You can add global styles to this file, and also import other style files */
|
|
121
|
+
"
|
|
122
|
+
`;
|
|
123
|
+
|
|
124
|
+
exports[`react-website generator > Tanstack router integration > should generate website with no router correctly > .gitignore 1`] = `
|
|
125
|
+
"vite.config.*.timestamp*
|
|
126
|
+
vitest.config.*.timestamp*
|
|
127
|
+
|
|
128
|
+
runtime-config.json"
|
|
129
|
+
`;
|
|
130
|
+
|
|
131
|
+
exports[`react-website generator > Tanstack router integration > should generate website with no router correctly > .prettierrc 1`] = `
|
|
132
|
+
"{ "singleQuote": true }
|
|
133
|
+
"
|
|
134
|
+
`;
|
|
135
|
+
|
|
136
|
+
exports[`react-website generator > Tanstack router integration > should generate website with no router correctly > eslint.config.mjs 1`] = `
|
|
137
|
+
"import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended';
|
|
138
|
+
import nx from '@nx/eslint-plugin';
|
|
139
|
+
|
|
140
|
+
export default [
|
|
141
|
+
eslintPluginPrettierRecommended,
|
|
142
|
+
...nx.configs['flat/base'],
|
|
143
|
+
...nx.configs['flat/typescript'],
|
|
144
|
+
...nx.configs['flat/javascript'],
|
|
145
|
+
{
|
|
146
|
+
ignores: [
|
|
147
|
+
'**/dist',
|
|
148
|
+
'**/vite.config.*.timestamp*',
|
|
149
|
+
'**/vitest.config.*.timestamp*',
|
|
150
|
+
'**/vite.config.ts.timestamp*',
|
|
151
|
+
],
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
files: ['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx'],
|
|
155
|
+
rules: {
|
|
156
|
+
'@nx/enforce-module-boundaries': [
|
|
157
|
+
'error',
|
|
158
|
+
{
|
|
159
|
+
enforceBuildableLibDependency: true,
|
|
160
|
+
allow: ['^.*/eslint(\\\\.base)?\\\\.config\\\\.[cm]?js$'],
|
|
161
|
+
depConstraints: [
|
|
162
|
+
{
|
|
163
|
+
sourceTag: '*',
|
|
164
|
+
onlyDependOnLibsWithTags: ['*'],
|
|
165
|
+
},
|
|
166
|
+
],
|
|
167
|
+
},
|
|
168
|
+
],
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
files: [
|
|
173
|
+
'**/*.ts',
|
|
174
|
+
'**/*.tsx',
|
|
175
|
+
'**/*.cts',
|
|
176
|
+
'**/*.mts',
|
|
177
|
+
'**/*.js',
|
|
178
|
+
'**/*.jsx',
|
|
179
|
+
'**/*.cjs',
|
|
180
|
+
'**/*.mjs',
|
|
181
|
+
],
|
|
182
|
+
rules: {},
|
|
183
|
+
},
|
|
184
|
+
];
|
|
185
|
+
"
|
|
186
|
+
`;
|
|
187
|
+
|
|
188
|
+
exports[`react-website generator > Tanstack router integration > should generate website with no router correctly > nx.json 1`] = `
|
|
189
|
+
"{
|
|
190
|
+
"affected": {
|
|
191
|
+
"defaultBase": "main"
|
|
192
|
+
},
|
|
193
|
+
"targetDefaults": {
|
|
194
|
+
"build": {
|
|
195
|
+
"cache": true,
|
|
196
|
+
"dependsOn": ["^build"],
|
|
197
|
+
"inputs": ["default"]
|
|
198
|
+
},
|
|
199
|
+
"lint": {
|
|
200
|
+
"cache": true,
|
|
201
|
+
"configurations": {
|
|
202
|
+
"fix": {
|
|
203
|
+
"fix": true
|
|
204
|
+
}
|
|
205
|
+
},
|
|
206
|
+
"inputs": [
|
|
207
|
+
"default",
|
|
208
|
+
"{workspaceRoot}/eslint.config.mjs",
|
|
209
|
+
"{projectRoot}/eslint.config.mjs"
|
|
210
|
+
]
|
|
211
|
+
},
|
|
212
|
+
"@nx/eslint:lint": {
|
|
213
|
+
"cache": true,
|
|
214
|
+
"inputs": [
|
|
215
|
+
"default",
|
|
216
|
+
"{workspaceRoot}/.eslintrc.json",
|
|
217
|
+
"{workspaceRoot}/.eslintignore",
|
|
218
|
+
"{workspaceRoot}/eslint.config.mjs"
|
|
219
|
+
]
|
|
220
|
+
},
|
|
221
|
+
"@nx/vite:test": {
|
|
222
|
+
"cache": true,
|
|
223
|
+
"inputs": ["default", "^default"],
|
|
224
|
+
"configurations": {
|
|
225
|
+
"update-snapshot": {
|
|
226
|
+
"args": "--update"
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
},
|
|
230
|
+
"@nx/vite:build": {
|
|
231
|
+
"cache": true,
|
|
232
|
+
"dependsOn": ["^build"],
|
|
233
|
+
"inputs": ["default", "^default"]
|
|
234
|
+
},
|
|
235
|
+
"test": {
|
|
236
|
+
"dependsOn": ["^build"],
|
|
237
|
+
"inputs": ["default"]
|
|
238
|
+
},
|
|
239
|
+
"compile": {
|
|
240
|
+
"cache": true,
|
|
241
|
+
"inputs": ["default"]
|
|
242
|
+
}
|
|
243
|
+
},
|
|
244
|
+
"generators": {
|
|
245
|
+
"@nx/react": {
|
|
246
|
+
"application": {
|
|
247
|
+
"babel": true,
|
|
248
|
+
"style": "css",
|
|
249
|
+
"linter": "eslint",
|
|
250
|
+
"bundler": "vite"
|
|
251
|
+
},
|
|
252
|
+
"component": {
|
|
253
|
+
"style": "css"
|
|
254
|
+
},
|
|
255
|
+
"library": {
|
|
256
|
+
"style": "css",
|
|
257
|
+
"linter": "eslint"
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
},
|
|
261
|
+
"plugins": [
|
|
262
|
+
{
|
|
263
|
+
"plugin": "@nx/js/typescript",
|
|
264
|
+
"options": {
|
|
265
|
+
"typecheck": {
|
|
266
|
+
"targetName": "typecheck"
|
|
267
|
+
},
|
|
268
|
+
"build": {
|
|
269
|
+
"targetName": "compile",
|
|
270
|
+
"configName": "tsconfig.lib.json",
|
|
271
|
+
"buildDepsName": "build-deps",
|
|
272
|
+
"watchDepsName": "watch-deps"
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
"plugin": "@nx/eslint/plugin",
|
|
278
|
+
"options": {
|
|
279
|
+
"targetName": "lint"
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
],
|
|
283
|
+
"namedInputs": {
|
|
284
|
+
"default": [
|
|
285
|
+
{
|
|
286
|
+
"dependentTasksOutputFiles": "**/*",
|
|
287
|
+
"transitive": true
|
|
288
|
+
}
|
|
289
|
+
]
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
"
|
|
293
|
+
`;
|
|
294
|
+
|
|
295
|
+
exports[`react-website generator > Tanstack router integration > should generate website with no router correctly > package.json 1`] = `
|
|
296
|
+
"{
|
|
297
|
+
"name": "@proj/source",
|
|
298
|
+
"dependencies": {
|
|
299
|
+
"@cloudscape-design/board-components": "^3.0.94",
|
|
300
|
+
"@cloudscape-design/components": "^3.0.928",
|
|
301
|
+
"@cloudscape-design/global-styles": "^1.0.38",
|
|
302
|
+
"aws-cdk-lib": "^2.200.0",
|
|
303
|
+
"constructs": "^10.4.2",
|
|
304
|
+
"react": "19.0.0",
|
|
305
|
+
"react-dom": "19.0.0",
|
|
306
|
+
"tailwindcss": "^4.1.11"
|
|
307
|
+
},
|
|
308
|
+
"devDependencies": {
|
|
309
|
+
"@eslint/js": "^9.8.0",
|
|
310
|
+
"@nx/eslint": "21.0.3",
|
|
311
|
+
"@nx/eslint-plugin": "21.0.3",
|
|
312
|
+
"@nx/js": "21.0.3",
|
|
313
|
+
"@nx/react": "21.0.3",
|
|
314
|
+
"@nx/vite": "21.0.3",
|
|
315
|
+
"@nx/web": "21.0.3",
|
|
316
|
+
"@swc-node/register": "~1.9.1",
|
|
317
|
+
"@swc/cli": "~0.6.0",
|
|
318
|
+
"@swc/core": "~1.5.7",
|
|
319
|
+
"@swc/helpers": "~0.5.11",
|
|
320
|
+
"@tailwindcss/vite": "^4.1.11",
|
|
321
|
+
"@testing-library/dom": "10.4.0",
|
|
322
|
+
"@testing-library/react": "16.1.0",
|
|
323
|
+
"@types/node": "^22.13.13",
|
|
324
|
+
"@types/react": "19.0.0",
|
|
325
|
+
"@types/react-dom": "19.0.0",
|
|
326
|
+
"@vitejs/plugin-react": "^4.2.0",
|
|
327
|
+
"@vitest/coverage-v8": "^3.0.5",
|
|
328
|
+
"@vitest/ui": "^3.0.0",
|
|
329
|
+
"eslint": "^9.8.0",
|
|
330
|
+
"eslint-config-prettier": "^10.0.0",
|
|
331
|
+
"eslint-plugin-import": "2.31.0",
|
|
332
|
+
"eslint-plugin-jsx-a11y": "6.10.1",
|
|
333
|
+
"eslint-plugin-prettier": "^5.2.5",
|
|
334
|
+
"eslint-plugin-react": "7.35.0",
|
|
335
|
+
"eslint-plugin-react-hooks": "5.0.0",
|
|
336
|
+
"jiti": "2.4.2",
|
|
337
|
+
"jsdom": "~22.1.0",
|
|
338
|
+
"jsonc-eslint-parser": "^2.4.0",
|
|
339
|
+
"prettier": "^3.5.3",
|
|
340
|
+
"typescript": "~5.7.2",
|
|
341
|
+
"typescript-eslint": "^8.19.0",
|
|
342
|
+
"vite": "^6.0.0",
|
|
343
|
+
"vite-tsconfig-paths": "^5.1.4",
|
|
344
|
+
"vitest": "^3.0.0"
|
|
345
|
+
},
|
|
346
|
+
"type": "module"
|
|
347
|
+
}
|
|
348
|
+
"
|
|
349
|
+
`;
|
|
350
|
+
|
|
351
|
+
exports[`react-website generator > Tanstack router integration > should generate website with no router correctly > packages/common/constructs/README.md 1`] = `
|
|
352
|
+
"# @proj/common-constructs
|
|
353
|
+
|
|
354
|
+
This library was generated with [@aws/nx-plugin](https://github.com/awslabs/nx-plugin-for-aws/).
|
|
355
|
+
|
|
356
|
+
## Building
|
|
357
|
+
|
|
358
|
+
Run \`npx nx build @proj/common-constructs [--skip-nx-cache]\` to build the application.
|
|
359
|
+
|
|
360
|
+
## Running unit tests
|
|
361
|
+
|
|
362
|
+
Run \`npx nx test @proj/common-constructs\` to execute the unit tests via Vitest.
|
|
363
|
+
|
|
364
|
+
### Updating snapshots
|
|
365
|
+
|
|
366
|
+
To update snapshots, run the following command:
|
|
367
|
+
|
|
368
|
+
\`npx nx test @proj/common-constructs --configuration=update-snapshot\`
|
|
369
|
+
|
|
370
|
+
## Run lint
|
|
371
|
+
|
|
372
|
+
Run \`npx nx lint @proj/common-constructs\`
|
|
373
|
+
|
|
374
|
+
### Fixable issues
|
|
375
|
+
|
|
376
|
+
You can also automatiaclly fix some lint errors by running the following command:
|
|
377
|
+
|
|
378
|
+
\`npx nx lint @proj/common-constructs --configuration=fix\`
|
|
379
|
+
|
|
380
|
+
## Useful links
|
|
381
|
+
|
|
382
|
+
- [common-constructs reference docs](TODO)
|
|
383
|
+
- [Learn more about NX](https://nx.dev/getting-started/intro)
|
|
384
|
+
"
|
|
385
|
+
`;
|
|
386
|
+
|
|
387
|
+
exports[`react-website generator > Tanstack router integration > should generate website with no router correctly > packages/common/constructs/eslint.config.mjs 1`] = `
|
|
388
|
+
"import baseConfig from '../../../eslint.config.mjs';
|
|
389
|
+
|
|
390
|
+
export default [
|
|
391
|
+
...baseConfig,
|
|
392
|
+
{
|
|
393
|
+
files: ['**/*.json'],
|
|
394
|
+
rules: {
|
|
395
|
+
'@nx/dependency-checks': [
|
|
396
|
+
'warn',
|
|
397
|
+
{
|
|
398
|
+
ignoredFiles: [
|
|
399
|
+
'{projectRoot}/eslint.config.{js,cjs,mjs}',
|
|
400
|
+
'{projectRoot}/vite.config.{js,ts,mjs,mts}',
|
|
401
|
+
],
|
|
402
|
+
},
|
|
403
|
+
],
|
|
404
|
+
},
|
|
405
|
+
languageOptions: {
|
|
406
|
+
parser: await import('jsonc-eslint-parser'),
|
|
407
|
+
},
|
|
408
|
+
},
|
|
409
|
+
];
|
|
410
|
+
"
|
|
411
|
+
`;
|
|
412
|
+
|
|
413
|
+
exports[`react-website generator > Tanstack router integration > should generate website with no router correctly > packages/common/constructs/project.json 1`] = `
|
|
414
|
+
"{
|
|
415
|
+
"name": "@proj/common-constructs",
|
|
416
|
+
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
|
|
417
|
+
"sourceRoot": "packages/common/constructs/src",
|
|
418
|
+
"projectType": "library",
|
|
419
|
+
"tags": [],
|
|
420
|
+
"targets": {
|
|
421
|
+
"build": {
|
|
422
|
+
"dependsOn": ["lint", "compile", "test", "@proj/test-app:build"]
|
|
423
|
+
},
|
|
424
|
+
"compile": {
|
|
425
|
+
"executor": "nx:run-commands",
|
|
426
|
+
"outputs": ["{workspaceRoot}/dist/packages/common/constructs/tsc"],
|
|
427
|
+
"options": {
|
|
428
|
+
"command": "tsc --build tsconfig.lib.json",
|
|
429
|
+
"cwd": "{projectRoot}"
|
|
430
|
+
}
|
|
431
|
+
},
|
|
432
|
+
"test": {
|
|
433
|
+
"executor": "@nx/vite:test",
|
|
434
|
+
"outputs": ["{options.reportsDirectory}"],
|
|
435
|
+
"options": {
|
|
436
|
+
"reportsDirectory": "../../../coverage/packages/common/constructs"
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
},
|
|
440
|
+
"metadata": {
|
|
441
|
+
"generator": "ts#project"
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
"
|
|
445
|
+
`;
|
|
446
|
+
|
|
447
|
+
exports[`react-website generator > Tanstack router integration > should generate website with no router correctly > packages/common/constructs/src/app/index.ts 1`] = `
|
|
448
|
+
"export * from './static-websites/index.js';
|
|
449
|
+
"
|
|
450
|
+
`;
|
|
451
|
+
|
|
452
|
+
exports[`react-website generator > Tanstack router integration > should generate website with no router correctly > packages/common/constructs/src/app/static-websites/index.ts 1`] = `
|
|
453
|
+
"export * from './test-app.js';
|
|
454
|
+
"
|
|
455
|
+
`;
|
|
456
|
+
|
|
457
|
+
exports[`react-website generator > Tanstack router integration > should generate website with no router correctly > packages/common/constructs/src/app/static-websites/test-app.ts 1`] = `
|
|
458
|
+
"import * as url from 'url';
|
|
459
|
+
import { Construct } from 'constructs';
|
|
460
|
+
import { StaticWebsite } from '../../core/index.js';
|
|
461
|
+
|
|
462
|
+
export class TestApp extends StaticWebsite {
|
|
463
|
+
constructor(scope: Construct, id: string) {
|
|
464
|
+
super(scope, id, {
|
|
465
|
+
websiteFilePath: url.fileURLToPath(
|
|
466
|
+
new URL('../../../../../../dist/test-app/bundle', import.meta.url),
|
|
467
|
+
),
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
"
|
|
472
|
+
`;
|
|
473
|
+
|
|
474
|
+
exports[`react-website generator > Tanstack router integration > should generate website with no router correctly > packages/common/constructs/src/core/app.ts 1`] = `
|
|
475
|
+
"import { App as _App, AppProps, Aspects, IAspect, Stack } from 'aws-cdk-lib';
|
|
476
|
+
import { IConstruct } from 'constructs';
|
|
477
|
+
|
|
478
|
+
export class App extends _App {
|
|
479
|
+
constructor(props?: AppProps) {
|
|
480
|
+
super(props);
|
|
481
|
+
|
|
482
|
+
Aspects.of(this).add(new MetricsAspect());
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
/**
|
|
487
|
+
* Adds information to CloudFormation stack descriptions to provide usage metrics for @aws/nx-plugin
|
|
488
|
+
*/
|
|
489
|
+
class MetricsAspect implements IAspect {
|
|
490
|
+
visit(node: IConstruct): void {
|
|
491
|
+
if (node instanceof Stack) {
|
|
492
|
+
const id = 'uksb-4wk0bqpg5s';
|
|
493
|
+
const version = '0.0.0';
|
|
494
|
+
const tags: string[] = ['g5'];
|
|
495
|
+
node.templateOptions.description =
|
|
496
|
+
\`\${node.templateOptions.description ?? ''} (\${id}) (version:\${version}) (tag:\${tags.join(',')})\`.trim();
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
"
|
|
501
|
+
`;
|
|
502
|
+
|
|
503
|
+
exports[`react-website generator > Tanstack router integration > should generate website with no router correctly > packages/common/constructs/src/core/index.ts 1`] = `
|
|
504
|
+
"export * from './static-website.js';
|
|
505
|
+
export * from './app.js';
|
|
506
|
+
export * from './runtime-config.js';
|
|
507
|
+
"
|
|
508
|
+
`;
|
|
509
|
+
|
|
510
|
+
exports[`react-website generator > Tanstack router integration > should generate website with no router correctly > packages/common/constructs/src/core/runtime-config.ts 1`] = `
|
|
511
|
+
"import type { IRuntimeConfig } from ':proj/common-types';
|
|
512
|
+
import { Stack } from 'aws-cdk-lib';
|
|
513
|
+
import { Construct } from 'constructs';
|
|
514
|
+
|
|
515
|
+
const RuntimeConfigKey = '__RuntimeConfig__';
|
|
516
|
+
|
|
517
|
+
export class RuntimeConfig extends Construct {
|
|
518
|
+
private readonly _runtimeConfig: Partial<IRuntimeConfig> = {};
|
|
519
|
+
|
|
520
|
+
static ensure(scope: Construct): RuntimeConfig {
|
|
521
|
+
const stack = Stack.of(scope);
|
|
522
|
+
return (
|
|
523
|
+
RuntimeConfig.of(scope) ?? new RuntimeConfig(stack, RuntimeConfigKey)
|
|
524
|
+
);
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
static of(scope: Construct): RuntimeConfig | undefined {
|
|
528
|
+
const stack = Stack.of(scope);
|
|
529
|
+
return stack.node.tryFindChild(RuntimeConfigKey) as
|
|
530
|
+
| RuntimeConfig
|
|
531
|
+
| undefined;
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
constructor(scope: Construct, id: string) {
|
|
535
|
+
super(scope, id);
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
get config(): Partial<IRuntimeConfig> {
|
|
539
|
+
return this._runtimeConfig;
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
"
|
|
543
|
+
`;
|
|
544
|
+
|
|
545
|
+
exports[`react-website generator > Tanstack router integration > should generate website with no router correctly > packages/common/constructs/src/core/static-website.ts 1`] = `
|
|
546
|
+
"import { CfnJson, CfnOutput, RemovalPolicy, Stack, Token } from 'aws-cdk-lib';
|
|
547
|
+
import { Distribution, ViewerProtocolPolicy } from 'aws-cdk-lib/aws-cloudfront';
|
|
548
|
+
import { S3BucketOrigin } from 'aws-cdk-lib/aws-cloudfront-origins';
|
|
549
|
+
import {
|
|
550
|
+
BlockPublicAccess,
|
|
551
|
+
Bucket,
|
|
552
|
+
BucketEncryption,
|
|
553
|
+
IBucket,
|
|
554
|
+
ObjectOwnership,
|
|
555
|
+
} from 'aws-cdk-lib/aws-s3';
|
|
556
|
+
import { BucketDeployment, Source } from 'aws-cdk-lib/aws-s3-deployment';
|
|
557
|
+
import { Construct } from 'constructs';
|
|
558
|
+
import { RuntimeConfig } from './runtime-config.js';
|
|
559
|
+
import { Key } from 'aws-cdk-lib/aws-kms';
|
|
560
|
+
import { CfnWebACL } from 'aws-cdk-lib/aws-wafv2';
|
|
561
|
+
const DEFAULT_RUNTIME_CONFIG_FILENAME = 'runtime-config.json';
|
|
562
|
+
|
|
563
|
+
export interface StaticWebsiteProps {
|
|
564
|
+
readonly websiteFilePath: string;
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
/**
|
|
568
|
+
* Deploys a Static Website using by default a private S3 bucket as an origin and Cloudfront as the entrypoint.
|
|
569
|
+
*
|
|
570
|
+
* This construct configures a webAcl containing rules that are generally applicable to web applications. This
|
|
571
|
+
* provides protection against exploitation of a wide range of vulnerabilities, including some of the high risk
|
|
572
|
+
* and commonly occurring vulnerabilities described in OWASP publications such as OWASP Top 10.
|
|
573
|
+
*
|
|
574
|
+
*/
|
|
575
|
+
export class StaticWebsite extends Construct {
|
|
576
|
+
public readonly websiteBucket: IBucket;
|
|
577
|
+
public readonly cloudFrontDistribution: Distribution;
|
|
578
|
+
public readonly bucketDeployment: BucketDeployment;
|
|
579
|
+
|
|
580
|
+
constructor(
|
|
581
|
+
scope: Construct,
|
|
582
|
+
id: string,
|
|
583
|
+
{ websiteFilePath }: StaticWebsiteProps,
|
|
584
|
+
) {
|
|
585
|
+
super(scope, id);
|
|
586
|
+
this.node.setContext(
|
|
587
|
+
'@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy',
|
|
588
|
+
true,
|
|
589
|
+
);
|
|
590
|
+
|
|
591
|
+
const websiteKey = new Key(this, 'WebsiteKey', {
|
|
592
|
+
enableKeyRotation: true,
|
|
593
|
+
});
|
|
594
|
+
|
|
595
|
+
const accessLogsBucket = new Bucket(this, 'AccessLogsBucket', {
|
|
596
|
+
versioned: false,
|
|
597
|
+
enforceSSL: true,
|
|
598
|
+
autoDeleteObjects: true,
|
|
599
|
+
removalPolicy: RemovalPolicy.DESTROY,
|
|
600
|
+
encryption: BucketEncryption.KMS,
|
|
601
|
+
encryptionKey: websiteKey,
|
|
602
|
+
objectOwnership: ObjectOwnership.OBJECT_WRITER,
|
|
603
|
+
publicReadAccess: false,
|
|
604
|
+
blockPublicAccess: BlockPublicAccess.BLOCK_ALL,
|
|
605
|
+
});
|
|
606
|
+
// S3 Bucket to hold website files
|
|
607
|
+
this.websiteBucket = new Bucket(this, 'WebsiteBucket', {
|
|
608
|
+
versioned: true,
|
|
609
|
+
enforceSSL: true,
|
|
610
|
+
autoDeleteObjects: true,
|
|
611
|
+
removalPolicy: RemovalPolicy.DESTROY,
|
|
612
|
+
encryption: BucketEncryption.KMS,
|
|
613
|
+
encryptionKey: websiteKey,
|
|
614
|
+
objectOwnership: ObjectOwnership.BUCKET_OWNER_ENFORCED,
|
|
615
|
+
publicReadAccess: false,
|
|
616
|
+
blockPublicAccess: BlockPublicAccess.BLOCK_ALL,
|
|
617
|
+
serverAccessLogsPrefix: 'website-access-logs',
|
|
618
|
+
serverAccessLogsBucket: accessLogsBucket,
|
|
619
|
+
});
|
|
620
|
+
// Web ACL
|
|
621
|
+
const wafStack = new CloudfrontWebAcl(this, 'waf');
|
|
622
|
+
|
|
623
|
+
// Cloudfront Distribution
|
|
624
|
+
const logBucket = new Bucket(this, 'DistributionLogBucket', {
|
|
625
|
+
enforceSSL: true,
|
|
626
|
+
autoDeleteObjects: true,
|
|
627
|
+
removalPolicy: RemovalPolicy.DESTROY,
|
|
628
|
+
encryption: BucketEncryption.KMS,
|
|
629
|
+
encryptionKey: websiteKey,
|
|
630
|
+
objectOwnership: ObjectOwnership.BUCKET_OWNER_PREFERRED,
|
|
631
|
+
publicReadAccess: false,
|
|
632
|
+
blockPublicAccess: BlockPublicAccess.BLOCK_ALL,
|
|
633
|
+
serverAccessLogsPrefix: 'distribution-access-logs',
|
|
634
|
+
serverAccessLogsBucket: accessLogsBucket,
|
|
635
|
+
});
|
|
636
|
+
const defaultRootObject = 'index.html';
|
|
637
|
+
this.cloudFrontDistribution = new Distribution(
|
|
638
|
+
this,
|
|
639
|
+
'CloudfrontDistribution',
|
|
640
|
+
{
|
|
641
|
+
webAclId: wafStack.wafArn,
|
|
642
|
+
enableLogging: true,
|
|
643
|
+
logBucket: logBucket,
|
|
644
|
+
defaultBehavior: {
|
|
645
|
+
origin: S3BucketOrigin.withOriginAccessControl(this.websiteBucket),
|
|
646
|
+
viewerProtocolPolicy: ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
|
|
647
|
+
},
|
|
648
|
+
defaultRootObject,
|
|
649
|
+
errorResponses: [
|
|
650
|
+
{
|
|
651
|
+
httpStatus: 404, // We need to redirect "key not found errors" to index.html for single page apps
|
|
652
|
+
responseHttpStatus: 200,
|
|
653
|
+
responsePagePath: \`/\${defaultRootObject}\`,
|
|
654
|
+
},
|
|
655
|
+
{
|
|
656
|
+
httpStatus: 403, // We need to redirect reloads from paths (e.g. /foo/bar) to index.html for single page apps
|
|
657
|
+
responseHttpStatus: 200,
|
|
658
|
+
responsePagePath: \`/\${defaultRootObject}\`,
|
|
659
|
+
},
|
|
660
|
+
],
|
|
661
|
+
},
|
|
662
|
+
);
|
|
663
|
+
// Deploy Website
|
|
664
|
+
this.bucketDeployment = new BucketDeployment(this, 'WebsiteDeployment', {
|
|
665
|
+
sources: [
|
|
666
|
+
Source.asset(websiteFilePath),
|
|
667
|
+
Source.jsonData(
|
|
668
|
+
DEFAULT_RUNTIME_CONFIG_FILENAME,
|
|
669
|
+
this.resolveTokens(RuntimeConfig.ensure(this).config),
|
|
670
|
+
),
|
|
671
|
+
],
|
|
672
|
+
destinationBucket: this.websiteBucket,
|
|
673
|
+
// Files in the distribution's edge caches will be invalidated after files are uploaded to the destination bucket.
|
|
674
|
+
distribution: this.cloudFrontDistribution,
|
|
675
|
+
memoryLimit: 1024,
|
|
676
|
+
});
|
|
677
|
+
new CfnOutput(this, 'DistributionDomainName', {
|
|
678
|
+
value: this.cloudFrontDistribution.domainName,
|
|
679
|
+
});
|
|
680
|
+
new CfnOutput(this, 'WebsiteBucketName', {
|
|
681
|
+
value: this.websiteBucket.bucketName,
|
|
682
|
+
});
|
|
683
|
+
}
|
|
684
|
+
private resolveTokens = (payload: any) => {
|
|
685
|
+
const _payload: Record<string, any> = {};
|
|
686
|
+
Object.entries(payload).forEach(([key, value]) => {
|
|
687
|
+
if (
|
|
688
|
+
Token.isUnresolved(value) ||
|
|
689
|
+
(typeof value === 'string' && value.endsWith('}}'))
|
|
690
|
+
) {
|
|
691
|
+
_payload[key] = new CfnJson(this, \`ResolveToken-\${key}\`, {
|
|
692
|
+
value,
|
|
693
|
+
}).value;
|
|
694
|
+
} else if (typeof value === 'object') {
|
|
695
|
+
_payload[key] = this.resolveTokens(value);
|
|
696
|
+
} else if (Array.isArray(value)) {
|
|
697
|
+
_payload[key] = value.map((v) => this.resolveTokens(v));
|
|
698
|
+
} else {
|
|
699
|
+
_payload[key] = value;
|
|
700
|
+
}
|
|
701
|
+
});
|
|
702
|
+
return _payload;
|
|
703
|
+
};
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
export class CloudfrontWebAcl extends Stack {
|
|
707
|
+
public readonly wafArn;
|
|
708
|
+
constructor(scope: Construct, id: string) {
|
|
709
|
+
super(scope, id, {
|
|
710
|
+
env: {
|
|
711
|
+
region: 'us-east-1',
|
|
712
|
+
account: Stack.of(scope).account,
|
|
713
|
+
},
|
|
714
|
+
crossRegionReferences: true,
|
|
715
|
+
});
|
|
716
|
+
|
|
717
|
+
this.wafArn = new CfnWebACL(this, 'WebAcl', {
|
|
718
|
+
defaultAction: { allow: {} },
|
|
719
|
+
scope: 'CLOUDFRONT',
|
|
720
|
+
visibilityConfig: {
|
|
721
|
+
cloudWatchMetricsEnabled: true,
|
|
722
|
+
metricName: id,
|
|
723
|
+
sampledRequestsEnabled: true,
|
|
724
|
+
},
|
|
725
|
+
rules: [
|
|
726
|
+
{
|
|
727
|
+
name: 'CRSRule',
|
|
728
|
+
priority: 0,
|
|
729
|
+
statement: {
|
|
730
|
+
managedRuleGroupStatement: {
|
|
731
|
+
name: 'AWSManagedRulesCommonRuleSet',
|
|
732
|
+
vendorName: 'AWS',
|
|
733
|
+
},
|
|
734
|
+
},
|
|
735
|
+
visibilityConfig: {
|
|
736
|
+
cloudWatchMetricsEnabled: true,
|
|
737
|
+
metricName: 'MetricForWebACLCDK-CRS',
|
|
738
|
+
sampledRequestsEnabled: true,
|
|
739
|
+
},
|
|
740
|
+
overrideAction: {
|
|
741
|
+
none: {},
|
|
742
|
+
},
|
|
743
|
+
},
|
|
744
|
+
],
|
|
745
|
+
}).attrArn;
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
"
|
|
749
|
+
`;
|
|
750
|
+
|
|
751
|
+
exports[`react-website generator > Tanstack router integration > should generate website with no router correctly > packages/common/constructs/src/index.ts 1`] = `
|
|
752
|
+
"export * from './app/index.js';
|
|
753
|
+
export * from './core/index.js';
|
|
754
|
+
"
|
|
755
|
+
`;
|
|
756
|
+
|
|
757
|
+
exports[`react-website generator > Tanstack router integration > should generate website with no router correctly > packages/common/constructs/tsconfig.json 1`] = `
|
|
758
|
+
"{
|
|
759
|
+
"extends": "../../../tsconfig.base.json",
|
|
760
|
+
"files": [],
|
|
761
|
+
"include": [],
|
|
762
|
+
"references": [
|
|
763
|
+
{
|
|
764
|
+
"path": "./tsconfig.lib.json"
|
|
765
|
+
},
|
|
766
|
+
{
|
|
767
|
+
"path": "./tsconfig.spec.json"
|
|
768
|
+
}
|
|
769
|
+
],
|
|
770
|
+
"compilerOptions": {}
|
|
771
|
+
}
|
|
772
|
+
"
|
|
773
|
+
`;
|
|
774
|
+
|
|
775
|
+
exports[`react-website generator > Tanstack router integration > should generate website with no router correctly > packages/common/constructs/tsconfig.lib.json 1`] = `
|
|
776
|
+
"{
|
|
777
|
+
"extends": "../../../tsconfig.base.json",
|
|
778
|
+
"compilerOptions": {
|
|
779
|
+
"rootDir": ".",
|
|
780
|
+
"outDir": "../../../dist/packages/common/constructs/tsc",
|
|
781
|
+
"tsBuildInfoFile": "../../../dist/packages/common/constructs/tsc/tsconfig.lib.tsbuildinfo",
|
|
782
|
+
"emitDeclarationOnly": false,
|
|
783
|
+
"module": "nodenext",
|
|
784
|
+
"moduleResolution": "nodenext",
|
|
785
|
+
"types": ["node"]
|
|
786
|
+
},
|
|
787
|
+
"include": ["src/**/*.ts"],
|
|
788
|
+
"references": [],
|
|
789
|
+
"exclude": [
|
|
790
|
+
"vite.config.ts",
|
|
791
|
+
"vite.config.mts",
|
|
792
|
+
"vitest.config.ts",
|
|
793
|
+
"vitest.config.mts",
|
|
794
|
+
"src/**/*.test.ts",
|
|
795
|
+
"src/**/*.spec.ts",
|
|
796
|
+
"src/**/*.test.tsx",
|
|
797
|
+
"src/**/*.spec.tsx",
|
|
798
|
+
"src/**/*.test.js",
|
|
799
|
+
"src/**/*.spec.js",
|
|
800
|
+
"src/**/*.test.jsx",
|
|
801
|
+
"src/**/*.spec.jsx"
|
|
802
|
+
]
|
|
803
|
+
}
|
|
804
|
+
"
|
|
805
|
+
`;
|
|
806
|
+
|
|
807
|
+
exports[`react-website generator > Tanstack router integration > should generate website with no router correctly > packages/common/constructs/tsconfig.spec.json 1`] = `
|
|
808
|
+
"{
|
|
809
|
+
"extends": "../../../tsconfig.base.json",
|
|
810
|
+
"compilerOptions": {
|
|
811
|
+
"outDir": "./out-tsc/vitest",
|
|
812
|
+
"types": [
|
|
813
|
+
"vitest/globals",
|
|
814
|
+
"vitest/importMeta",
|
|
815
|
+
"vite/client",
|
|
816
|
+
"node",
|
|
817
|
+
"vitest"
|
|
818
|
+
],
|
|
819
|
+
"module": "nodenext",
|
|
820
|
+
"moduleResolution": "nodenext"
|
|
821
|
+
},
|
|
822
|
+
"include": [
|
|
823
|
+
"vite.config.ts",
|
|
824
|
+
"vite.config.mts",
|
|
825
|
+
"vitest.config.ts",
|
|
826
|
+
"vitest.config.mts",
|
|
827
|
+
"src/**/*.test.ts",
|
|
828
|
+
"src/**/*.spec.ts",
|
|
829
|
+
"src/**/*.test.tsx",
|
|
830
|
+
"src/**/*.spec.tsx",
|
|
831
|
+
"src/**/*.test.js",
|
|
832
|
+
"src/**/*.spec.js",
|
|
833
|
+
"src/**/*.test.jsx",
|
|
834
|
+
"src/**/*.spec.jsx",
|
|
835
|
+
"src/**/*.d.ts"
|
|
836
|
+
],
|
|
837
|
+
"references": [
|
|
838
|
+
{
|
|
839
|
+
"path": "./tsconfig.lib.json"
|
|
840
|
+
}
|
|
841
|
+
]
|
|
842
|
+
}
|
|
843
|
+
"
|
|
844
|
+
`;
|
|
845
|
+
|
|
846
|
+
exports[`react-website generator > Tanstack router integration > should generate website with no router correctly > packages/common/constructs/vite.config.ts 1`] = `
|
|
847
|
+
"import { defineConfig } from 'vite';
|
|
848
|
+
|
|
849
|
+
export default defineConfig(() => ({
|
|
850
|
+
root: __dirname,
|
|
851
|
+
cacheDir: '../../../node_modules/.vite/packages/common/constructs',
|
|
852
|
+
plugins: [],
|
|
853
|
+
// Uncomment this if you are using workers.
|
|
854
|
+
// worker: {
|
|
855
|
+
// plugins: [ nxViteTsPaths() ],
|
|
856
|
+
// },
|
|
857
|
+
test: {
|
|
858
|
+
watch: false,
|
|
859
|
+
globals: true,
|
|
860
|
+
environment: 'jsdom',
|
|
861
|
+
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
|
862
|
+
reporters: ['default'],
|
|
863
|
+
coverage: {
|
|
864
|
+
reportsDirectory: './test-output/vitest/coverage',
|
|
865
|
+
provider: 'v8' as const,
|
|
866
|
+
},
|
|
867
|
+
passWithNoTests: true,
|
|
868
|
+
},
|
|
869
|
+
}));
|
|
870
|
+
"
|
|
871
|
+
`;
|
|
872
|
+
|
|
873
|
+
exports[`react-website generator > Tanstack router integration > should generate website with no router correctly > packages/common/types/README.md 1`] = `
|
|
874
|
+
"# @proj/common-types
|
|
875
|
+
|
|
876
|
+
This library was generated with [@aws/nx-plugin](https://github.com/awslabs/nx-plugin-for-aws/).
|
|
877
|
+
|
|
878
|
+
## Building
|
|
879
|
+
|
|
880
|
+
Run \`npx nx build @proj/common-types [--skip-nx-cache]\` to build the application.
|
|
881
|
+
|
|
882
|
+
## Running unit tests
|
|
883
|
+
|
|
884
|
+
Run \`npx nx test @proj/common-types\` to execute the unit tests via Vitest.
|
|
885
|
+
|
|
886
|
+
### Updating snapshots
|
|
887
|
+
|
|
888
|
+
To update snapshots, run the following command:
|
|
889
|
+
|
|
890
|
+
\`npx nx test @proj/common-types --configuration=update-snapshot\`
|
|
891
|
+
|
|
892
|
+
## Run lint
|
|
893
|
+
|
|
894
|
+
Run \`npx nx lint @proj/common-types\`
|
|
895
|
+
|
|
896
|
+
### Fixable issues
|
|
897
|
+
|
|
898
|
+
You can also automatiaclly fix some lint errors by running the following command:
|
|
899
|
+
|
|
900
|
+
\`npx nx lint @proj/common-types --configuration=fix\`
|
|
901
|
+
|
|
902
|
+
## Useful links
|
|
903
|
+
|
|
904
|
+
- [common-types reference docs](TODO)
|
|
905
|
+
- [Learn more about NX](https://nx.dev/getting-started/intro)
|
|
906
|
+
"
|
|
907
|
+
`;
|
|
908
|
+
|
|
909
|
+
exports[`react-website generator > Tanstack router integration > should generate website with no router correctly > packages/common/types/eslint.config.mjs 1`] = `
|
|
910
|
+
"import baseConfig from '../../../eslint.config.mjs';
|
|
911
|
+
|
|
912
|
+
export default [
|
|
913
|
+
...baseConfig,
|
|
914
|
+
{
|
|
915
|
+
files: ['**/*.json'],
|
|
916
|
+
rules: {
|
|
917
|
+
'@nx/dependency-checks': [
|
|
918
|
+
'warn',
|
|
919
|
+
{
|
|
920
|
+
ignoredFiles: [
|
|
921
|
+
'{projectRoot}/eslint.config.{js,cjs,mjs}',
|
|
922
|
+
'{projectRoot}/vite.config.{js,ts,mjs,mts}',
|
|
923
|
+
],
|
|
924
|
+
},
|
|
925
|
+
],
|
|
926
|
+
},
|
|
927
|
+
languageOptions: {
|
|
928
|
+
parser: await import('jsonc-eslint-parser'),
|
|
929
|
+
},
|
|
930
|
+
},
|
|
931
|
+
];
|
|
932
|
+
"
|
|
933
|
+
`;
|
|
934
|
+
|
|
935
|
+
exports[`react-website generator > Tanstack router integration > should generate website with no router correctly > packages/common/types/project.json 1`] = `
|
|
936
|
+
"{
|
|
937
|
+
"name": "@proj/common-types",
|
|
938
|
+
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
|
|
939
|
+
"sourceRoot": "packages/common/types/src",
|
|
940
|
+
"projectType": "library",
|
|
941
|
+
"tags": [],
|
|
942
|
+
"targets": {
|
|
943
|
+
"build": {
|
|
944
|
+
"dependsOn": ["lint", "compile", "test"]
|
|
945
|
+
},
|
|
946
|
+
"compile": {
|
|
947
|
+
"executor": "nx:run-commands",
|
|
948
|
+
"outputs": ["{workspaceRoot}/dist/packages/common/types/tsc"],
|
|
949
|
+
"options": {
|
|
950
|
+
"command": "tsc --build tsconfig.lib.json",
|
|
951
|
+
"cwd": "{projectRoot}"
|
|
952
|
+
}
|
|
953
|
+
},
|
|
954
|
+
"test": {
|
|
955
|
+
"executor": "@nx/vite:test",
|
|
956
|
+
"outputs": ["{options.reportsDirectory}"],
|
|
957
|
+
"options": {
|
|
958
|
+
"reportsDirectory": "../../../coverage/packages/common/types"
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
},
|
|
962
|
+
"metadata": {
|
|
963
|
+
"generator": "ts#project"
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
"
|
|
967
|
+
`;
|
|
968
|
+
|
|
969
|
+
exports[`react-website generator > Tanstack router integration > should generate website with no router correctly > packages/common/types/src/index.ts 1`] = `
|
|
970
|
+
"export * from './runtime-config.js';
|
|
971
|
+
"
|
|
972
|
+
`;
|
|
973
|
+
|
|
974
|
+
exports[`react-website generator > Tanstack router integration > should generate website with no router correctly > packages/common/types/src/runtime-config.ts 1`] = `
|
|
975
|
+
"// eslint-disable-next-line @typescript-eslint/no-empty-object-type, @typescript-eslint/no-empty-interface
|
|
976
|
+
export interface IRuntimeConfig {}
|
|
977
|
+
"
|
|
978
|
+
`;
|
|
979
|
+
|
|
980
|
+
exports[`react-website generator > Tanstack router integration > should generate website with no router correctly > packages/common/types/tsconfig.json 1`] = `
|
|
981
|
+
"{
|
|
982
|
+
"extends": "../../../tsconfig.base.json",
|
|
983
|
+
"files": [],
|
|
984
|
+
"include": [],
|
|
985
|
+
"references": [
|
|
986
|
+
{
|
|
987
|
+
"path": "./tsconfig.lib.json"
|
|
988
|
+
},
|
|
989
|
+
{
|
|
990
|
+
"path": "./tsconfig.spec.json"
|
|
991
|
+
}
|
|
992
|
+
],
|
|
993
|
+
"compilerOptions": {}
|
|
994
|
+
}
|
|
995
|
+
"
|
|
996
|
+
`;
|
|
997
|
+
|
|
998
|
+
exports[`react-website generator > Tanstack router integration > should generate website with no router correctly > packages/common/types/tsconfig.lib.json 1`] = `
|
|
999
|
+
"{
|
|
1000
|
+
"extends": "../../../tsconfig.base.json",
|
|
1001
|
+
"compilerOptions": {
|
|
1002
|
+
"rootDir": ".",
|
|
1003
|
+
"outDir": "../../../dist/packages/common/types/tsc",
|
|
1004
|
+
"tsBuildInfoFile": "../../../dist/packages/common/types/tsc/tsconfig.lib.tsbuildinfo",
|
|
1005
|
+
"emitDeclarationOnly": false,
|
|
1006
|
+
"module": "nodenext",
|
|
1007
|
+
"moduleResolution": "nodenext",
|
|
1008
|
+
"types": ["node"]
|
|
1009
|
+
},
|
|
1010
|
+
"include": ["src/**/*.ts"],
|
|
1011
|
+
"references": [],
|
|
1012
|
+
"exclude": [
|
|
1013
|
+
"vite.config.ts",
|
|
1014
|
+
"vite.config.mts",
|
|
1015
|
+
"vitest.config.ts",
|
|
1016
|
+
"vitest.config.mts",
|
|
1017
|
+
"src/**/*.test.ts",
|
|
1018
|
+
"src/**/*.spec.ts",
|
|
1019
|
+
"src/**/*.test.tsx",
|
|
1020
|
+
"src/**/*.spec.tsx",
|
|
1021
|
+
"src/**/*.test.js",
|
|
1022
|
+
"src/**/*.spec.js",
|
|
1023
|
+
"src/**/*.test.jsx",
|
|
1024
|
+
"src/**/*.spec.jsx"
|
|
1025
|
+
]
|
|
1026
|
+
}
|
|
1027
|
+
"
|
|
1028
|
+
`;
|
|
1029
|
+
|
|
1030
|
+
exports[`react-website generator > Tanstack router integration > should generate website with no router correctly > packages/common/types/tsconfig.spec.json 1`] = `
|
|
1031
|
+
"{
|
|
1032
|
+
"extends": "../../../tsconfig.base.json",
|
|
1033
|
+
"compilerOptions": {
|
|
1034
|
+
"outDir": "./out-tsc/vitest",
|
|
1035
|
+
"types": [
|
|
1036
|
+
"vitest/globals",
|
|
1037
|
+
"vitest/importMeta",
|
|
1038
|
+
"vite/client",
|
|
1039
|
+
"node",
|
|
1040
|
+
"vitest"
|
|
1041
|
+
],
|
|
1042
|
+
"module": "nodenext",
|
|
1043
|
+
"moduleResolution": "nodenext"
|
|
1044
|
+
},
|
|
1045
|
+
"include": [
|
|
1046
|
+
"vite.config.ts",
|
|
1047
|
+
"vite.config.mts",
|
|
1048
|
+
"vitest.config.ts",
|
|
1049
|
+
"vitest.config.mts",
|
|
1050
|
+
"src/**/*.test.ts",
|
|
1051
|
+
"src/**/*.spec.ts",
|
|
1052
|
+
"src/**/*.test.tsx",
|
|
1053
|
+
"src/**/*.spec.tsx",
|
|
1054
|
+
"src/**/*.test.js",
|
|
1055
|
+
"src/**/*.spec.js",
|
|
1056
|
+
"src/**/*.test.jsx",
|
|
1057
|
+
"src/**/*.spec.jsx",
|
|
1058
|
+
"src/**/*.d.ts"
|
|
1059
|
+
],
|
|
1060
|
+
"references": [
|
|
1061
|
+
{
|
|
1062
|
+
"path": "./tsconfig.lib.json"
|
|
1063
|
+
}
|
|
1064
|
+
]
|
|
1065
|
+
}
|
|
1066
|
+
"
|
|
1067
|
+
`;
|
|
1068
|
+
|
|
1069
|
+
exports[`react-website generator > Tanstack router integration > should generate website with no router correctly > packages/common/types/vite.config.ts 1`] = `
|
|
1070
|
+
"import { defineConfig } from 'vite';
|
|
1071
|
+
|
|
1072
|
+
export default defineConfig(() => ({
|
|
1073
|
+
root: __dirname,
|
|
1074
|
+
cacheDir: '../../../node_modules/.vite/packages/common/types',
|
|
1075
|
+
plugins: [],
|
|
1076
|
+
// Uncomment this if you are using workers.
|
|
1077
|
+
// worker: {
|
|
1078
|
+
// plugins: [ nxViteTsPaths() ],
|
|
1079
|
+
// },
|
|
1080
|
+
test: {
|
|
1081
|
+
watch: false,
|
|
1082
|
+
globals: true,
|
|
1083
|
+
environment: 'jsdom',
|
|
1084
|
+
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
|
1085
|
+
reporters: ['default'],
|
|
1086
|
+
coverage: {
|
|
1087
|
+
reportsDirectory: './test-output/vitest/coverage',
|
|
1088
|
+
provider: 'v8' as const,
|
|
1089
|
+
},
|
|
1090
|
+
passWithNoTests: true,
|
|
1091
|
+
},
|
|
1092
|
+
}));
|
|
1093
|
+
"
|
|
1094
|
+
`;
|
|
1095
|
+
|
|
1096
|
+
exports[`react-website generator > Tanstack router integration > should generate website with no router correctly > pnpm-workspace.yaml 1`] = `
|
|
1097
|
+
"packages:
|
|
1098
|
+
- 'packages/*'
|
|
1099
|
+
- 'test-app'
|
|
1100
|
+
- 'packages/common/*'
|
|
1101
|
+
- 'packages/common/constructs'
|
|
1102
|
+
"
|
|
1103
|
+
`;
|
|
1104
|
+
|
|
1105
|
+
exports[`react-website generator > Tanstack router integration > should generate website with no router correctly > test-app/README.md 1`] = `
|
|
1106
|
+
"# @proj/test-app
|
|
1107
|
+
|
|
1108
|
+
This library was generated with [@aws/nx-plugin](https://github.com/awslabs/nx-plugin-for-aws/).
|
|
1109
|
+
|
|
1110
|
+
## Building
|
|
1111
|
+
|
|
1112
|
+
Run \`npx nx build @proj/test-app [--skip-nx-cache]\` to build the application.
|
|
1113
|
+
|
|
1114
|
+
## Run dev server
|
|
1115
|
+
|
|
1116
|
+
Run \`npx nx serve @proj/test-app\`
|
|
1117
|
+
|
|
1118
|
+
## Running unit tests
|
|
1119
|
+
|
|
1120
|
+
Run \`npx nx test @proj/test-app\` to execute the unit tests via Vitest.
|
|
1121
|
+
|
|
1122
|
+
### Updating snapshots
|
|
1123
|
+
|
|
1124
|
+
To update snapshots, run the following command:
|
|
1125
|
+
|
|
1126
|
+
\`npx nx test @proj/test-app --configuration=update-snapshot\`
|
|
1127
|
+
|
|
1128
|
+
## Run lint
|
|
1129
|
+
|
|
1130
|
+
Run \`npx nx lint @proj/test-app\`
|
|
1131
|
+
|
|
1132
|
+
### Fixable issues
|
|
1133
|
+
|
|
1134
|
+
You can also automatically fix some lint errors by running the following command:
|
|
1135
|
+
|
|
1136
|
+
\`npx nx lint @proj/test-app --configuration=fix\`
|
|
1137
|
+
|
|
1138
|
+
### Runtime config
|
|
1139
|
+
|
|
1140
|
+
In order to integrate with cognito or trpc backends, you need to have a \`runtime-config.json\` file in your \`/public\` website directory. You can fetch this is follows:
|
|
1141
|
+
|
|
1142
|
+
\`npx nx run @proj/test-app:load:runtime-config\`
|
|
1143
|
+
|
|
1144
|
+
> [!IMPORTANT]
|
|
1145
|
+
> Ensure you have AWS CLI and curl installed
|
|
1146
|
+
> You have deployed your CDK infrastructure into the appropriate account
|
|
1147
|
+
> You have assumed a role in the AWS account with sufficient permissions to call describe-stacks from cloudformation
|
|
1148
|
+
|
|
1149
|
+
## Useful links
|
|
1150
|
+
|
|
1151
|
+
- [React website reference docs](TODO)
|
|
1152
|
+
- [Learn more about NX](https://nx.dev/getting-started/intro)
|
|
1153
|
+
"
|
|
1154
|
+
`;
|
|
1155
|
+
|
|
1156
|
+
exports[`react-website generator > Tanstack router integration > should generate website with no router correctly > test-app/eslint.config.mjs 1`] = `
|
|
1157
|
+
"import nx from '@nx/eslint-plugin';
|
|
1158
|
+
import baseConfig from '../eslint.config.mjs';
|
|
1159
|
+
|
|
1160
|
+
export default [
|
|
1161
|
+
...baseConfig,
|
|
1162
|
+
...nx.configs['flat/react'],
|
|
1163
|
+
{
|
|
1164
|
+
files: ['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx'],
|
|
1165
|
+
// Override or add rules here
|
|
1166
|
+
rules: {},
|
|
1167
|
+
},
|
|
1168
|
+
];
|
|
1169
|
+
"
|
|
1170
|
+
`;
|
|
1171
|
+
|
|
1172
|
+
exports[`react-website generator > Tanstack router integration > should generate website with no router correctly > test-app/index.html 1`] = `
|
|
1173
|
+
"<!doctype html>
|
|
1174
|
+
<html lang="en">
|
|
1175
|
+
<head>
|
|
1176
|
+
<meta charset="utf-8" />
|
|
1177
|
+
<title>TestApp</title>
|
|
1178
|
+
<base href="/" />
|
|
1179
|
+
|
|
1180
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
1181
|
+
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
|
|
1182
|
+
<link rel="stylesheet" href="/src/styles.css" />
|
|
1183
|
+
</head>
|
|
1184
|
+
<body>
|
|
1185
|
+
<div id="root"></div>
|
|
1186
|
+
<script type="module" src="/src/main.tsx"></script>
|
|
1187
|
+
</body>
|
|
1188
|
+
</html>
|
|
1189
|
+
"
|
|
1190
|
+
`;
|
|
1191
|
+
|
|
1192
|
+
exports[`react-website generator > Tanstack router integration > should generate website with no router correctly > test-app/project.json 1`] = `
|
|
1193
|
+
"{
|
|
1194
|
+
"name": "@proj/test-app",
|
|
1195
|
+
"$schema": "../node_modules/nx/schemas/project-schema.json",
|
|
1196
|
+
"sourceRoot": "test-app/src",
|
|
1197
|
+
"projectType": "application",
|
|
1198
|
+
"tags": [],
|
|
1199
|
+
"targets": {
|
|
1200
|
+
"build": {
|
|
1201
|
+
"dependsOn": ["lint", "compile", "bundle", "test"],
|
|
1202
|
+
"options": {
|
|
1203
|
+
"outputPath": "dist/test-app/bundle"
|
|
1204
|
+
}
|
|
1205
|
+
},
|
|
1206
|
+
"bundle": {
|
|
1207
|
+
"executor": "@nx/vite:build",
|
|
1208
|
+
"outputs": ["{options.outputPath}"],
|
|
1209
|
+
"defaultConfiguration": "production",
|
|
1210
|
+
"options": {
|
|
1211
|
+
"outputPath": "dist/test-app/bundle"
|
|
1212
|
+
},
|
|
1213
|
+
"configurations": {
|
|
1214
|
+
"development": {
|
|
1215
|
+
"mode": "development"
|
|
1216
|
+
},
|
|
1217
|
+
"production": {
|
|
1218
|
+
"mode": "production"
|
|
1219
|
+
}
|
|
1220
|
+
}
|
|
1221
|
+
},
|
|
1222
|
+
"compile": {
|
|
1223
|
+
"executor": "nx:run-commands",
|
|
1224
|
+
"outputs": ["{workspaceRoot}/dist/{projectRoot}/tsc"],
|
|
1225
|
+
"options": {
|
|
1226
|
+
"command": "tsc --build tsconfig.app.json",
|
|
1227
|
+
"cwd": "{projectRoot}"
|
|
1228
|
+
}
|
|
1229
|
+
},
|
|
1230
|
+
"lint": {
|
|
1231
|
+
"executor": "@nx/eslint:lint"
|
|
1232
|
+
},
|
|
1233
|
+
"load:runtime-config": {
|
|
1234
|
+
"executor": "nx:run-commands",
|
|
1235
|
+
"metadata": {
|
|
1236
|
+
"description": "Load runtime config from your deployed stack for dev purposes. You must set your AWS CLI credentials whilst calling 'pnpm exec nx run @proj/test-app:load:runtime-config'"
|
|
1237
|
+
},
|
|
1238
|
+
"options": {
|
|
1239
|
+
"command": "aws s3 cp s3://\`aws cloudformation describe-stacks --query \\"Stacks[?StackName=='proj-infra-sandbox'][].Outputs[?contains(OutputKey, 'WebsiteBucketName')].OutputValue\\" --output text\`/runtime-config.json './test-app/public/runtime-config.json'"
|
|
1240
|
+
}
|
|
1241
|
+
},
|
|
1242
|
+
"preview": {
|
|
1243
|
+
"dependsOn": ["build"],
|
|
1244
|
+
"executor": "@nx/vite:preview-server",
|
|
1245
|
+
"defaultConfiguration": "development",
|
|
1246
|
+
"options": {
|
|
1247
|
+
"buildTarget": "@proj/test-app:build"
|
|
1248
|
+
},
|
|
1249
|
+
"configurations": {
|
|
1250
|
+
"development": {
|
|
1251
|
+
"buildTarget": "@proj/test-app:build:development"
|
|
1252
|
+
},
|
|
1253
|
+
"production": {
|
|
1254
|
+
"buildTarget": "@proj/test-app:build:production"
|
|
1255
|
+
}
|
|
1256
|
+
}
|
|
1257
|
+
},
|
|
1258
|
+
"serve": {
|
|
1259
|
+
"executor": "@nx/vite:dev-server",
|
|
1260
|
+
"defaultConfiguration": "development",
|
|
1261
|
+
"options": {
|
|
1262
|
+
"buildTarget": "@proj/test-app:build"
|
|
1263
|
+
},
|
|
1264
|
+
"configurations": {
|
|
1265
|
+
"development": {
|
|
1266
|
+
"buildTarget": "@proj/test-app:build:development",
|
|
1267
|
+
"hmr": true
|
|
1268
|
+
},
|
|
1269
|
+
"production": {
|
|
1270
|
+
"buildTarget": "@proj/test-app:build:production",
|
|
1271
|
+
"hmr": false
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1274
|
+
},
|
|
1275
|
+
"serve-local": {
|
|
1276
|
+
"executor": "@nx/vite:dev-server",
|
|
1277
|
+
"options": {
|
|
1278
|
+
"buildTarget": "@proj/test-app:build:development",
|
|
1279
|
+
"hmr": true,
|
|
1280
|
+
"mode": "serve-local"
|
|
1281
|
+
},
|
|
1282
|
+
"continuous": true
|
|
1283
|
+
},
|
|
1284
|
+
"serve-static": {
|
|
1285
|
+
"executor": "@nx/web:file-server",
|
|
1286
|
+
"dependsOn": ["build"],
|
|
1287
|
+
"options": {
|
|
1288
|
+
"buildTarget": "@proj/test-app:build",
|
|
1289
|
+
"spa": true
|
|
1290
|
+
}
|
|
1291
|
+
},
|
|
1292
|
+
"test": {
|
|
1293
|
+
"executor": "@nx/vite:test",
|
|
1294
|
+
"outputs": ["{options.reportsDirectory}"],
|
|
1295
|
+
"options": {
|
|
1296
|
+
"reportsDirectory": "../coverage/test-app"
|
|
1297
|
+
}
|
|
1298
|
+
}
|
|
1299
|
+
},
|
|
1300
|
+
"metadata": {
|
|
1301
|
+
"generator": "ts#react-website"
|
|
1302
|
+
}
|
|
1303
|
+
}
|
|
1304
|
+
"
|
|
1305
|
+
`;
|
|
1306
|
+
|
|
1307
|
+
exports[`react-website generator > Tanstack router integration > should generate website with no router correctly > test-app/public/favicon.ico 1`] = `
|
|
1308
|
+
"00 �%6 ��% h�6(0\` $V/V/cV/�V/�V/�V/�V/�W0�Y1'B#pH[�f��i��i��i��i��i��ia�j�c�^R�\\��Y��U��R�|N�xKuI&V/
|
|
1309
|
+
V/�V/�V/�V/�V/�V/�X1�Y2Ld=9_;�X��l��k��k��k��k��k�kH�c8�a�]��Z��W��S�}P�zM�vIV/
|
|
1310
|
+
V/�V/�V/�V/�V/�W0�Y1�Z3LoDjA�\`;�_=��c��l��k��k��k��k��kÞk�j�f��c��\`��]��Y��V��R�}OCV/
|
|
1311
|
+
V/�V/�V/�V/�V/�W0�Z2�[3LoD[nD�iA�X7�oI��j��k��k��k��k��k��k��m�ks�i��f��b��_��[��W��T�yLV/
|
|
1312
|
+
V/�V/�V/�V/�V/�X1�Z3�\\4MnDoE�qF�oE�f@�X8��Z��l��k��k��k��k��k�ks�k��k��h��d��a��]��Y˅WV/
|
|
1313
|
+
V/�V/�V/�V/�V/�Y1�[3�\\4Ph=nD�pE�rG�sH�oF�a=�cA��f��k��k��k��k��k��k��k��k��j��f��b��_�\\SV/
|
|
1314
|
+
V/�V/�V/�V/�W0�Y2�[4�]5QmC6oD�qF�sH�uJ�uJ�nF�];�wO��k��k��k��k��k��k��k��k��k��h��d��\`��\\V/
|
|
1315
|
+
V/V/
|
|
1316
|
+
V/�V/�V/�V/�W0�Y2�\\4�]5QkA
|
|
1317
|
+
mC�oD�qF�tH�vJ�xL�vK�kD�^=��_��l��k��k��k��k��k��k��k��i��eؔb(V/ V/�V/eV/
|
|
1318
|
+
V/�V/�V/�V/�W0�Z2�\\4�^6QlAXmC�oE�rG�tI�wK�yM�zN�uK�eA�jF��h��k��k��k��k��k��k��k��j��geW0V/RV/�V/
|
|
1319
|
+
V/�V/�V/�V/�W0�Z2�\\4�^6Qj@kA�mC�pE�rG�uI�wK�yM�|O�{O�rJ�^=�|S��k��k��k��k��k��k��k��j��h�Z]5iY1�V/GV/
|
|
1320
|
+
V/�V/�V/�V/�X0�Z2�\\5�^6Qi?kA�mC�pE�rG�uI�wK�zM�|O�}P�xN�eB�W:��c��k��k��k��k��k��o���$W��H��H��KHɦ9�f>�X1�V/�V/
|
|
1321
|
+
V/�V/�V/�V/�X0�Z2�\\4�^6Qg>4i?�kA�mC�pE�rG�uI�wK�zM�|O�|P�vM�b@�bA��g��k��k��k��k��k��s �ӵ]������H-��H���J���G���*�\`8�Y1�V/�V/
|
|
1322
|
+
V/�V/�V/�V/�W0�Z2�\\4�^6Qd; f=�h?�kA�mC�pE�rG�tI�wK�yM�{O�yN�mF�^>��]��l��k��k��k��k��k��l�ͫH��ڔ��ٛ�ؖ�ؖ�ؖ.�ؘr�֏���O�߾D���/��h�i@�]5�Y1�V/�V/
|
|
1323
|
+
V/�V/�V/�V/�W0�Z2�\\4�^5Qd;Uf<�h>�j@�mC�oE�rG�tH�wK�yL�xM�qI�_=�vO��k��k��k��k��k��k��k��j������i��א��ؗ��ؘ��ؗ��֏���k���G��w�mC�e;�a8�]5�X1�V/]V/
|
|
1324
|
+
V/�V/�V/�V/�W0�Y2�\\4�]5Pb:c:�e<�h>�j@�lB�oD�qF�rGDwK}wK�sI�d@�cA��f��k��k��k��k��k��k��k��k��i���$���W���p���v���n���Y���I���*�rG�j@�f<�a8�\\4�X1�V/ V/
|
|
1325
|
+
V/�V/�V/�V/�W0�Y1�[3�\\5Qa8wb:�e<�g>�i@�lB�nD�pE�oCuI}sH�iB�Z:��Z��l��k��k��k��k��k��k��k��j��f��e����Ω4�ܹA�B�״=���(�}R�nC�j@�e<�\`8�[4�X1�V/
|
|
1326
|
+
V/�V/�V/�V/�V/�X1�[3�]5�\`7�b9�d;�f=�i?�kA�mC�oD*qG}kD�Z9�oI��j��k��k��k��k��k��k�k��k��i��e��a��]��_��g��g
|
|
1327
|
+
��[�xK�rF�nC�i?�d;�_7�[3�X1V/
|
|
1328
|
+
V/�V/�V/�V/�V/�X0�Z2�\\4�_6�a8�c:�f<�h>�j@�lBqjB}_<�\\;��c��l��k��k��k��k��k۞kC�k��j��g��c��\`��\\��X��S�}O�yL�uI�qE�lA�g>�c:�^6�[3JV/
|
|
1329
|
+
V/�V/�V/�V/�V/�W0�Y2�\\4�^6�\`8�b:�e;�g=�i?�kA\`;}U6�U��l��k��k��k��k��k��kl�k$�h��d��a��^��Z��V��S�}O�xK�tH�oD�j@�f<�a9�^6ZS,V/
|
|
1330
|
+
V/�V/�V/�V/�V/�V/�X1�[3�]5�_7�a9�d;�f<�g>MT4~kE��i��k��k��k��k��k��k��k�e�b��_�[��X��T�Q�zM�vJ�rF�mB�i?�e;�a8BW0V/
|
|
1331
|
+
V/�V/�V/�V/�V/�V/�W0�Z2�\\4�^6�\`8�b:�d;�g=iC~�a��k��k��k��k��k��k�k:�\`�]@�Y��VڀR�|O�xK�tH�pD�lA�h>he;V/
|
|
1332
|
+
V/�V/�V/�V/�V/�V/�W0�Y1�[3�]5�_7�a8�c:.xL~Q��R��S��T��T��U��W��o�W�TQ={MTwJYsGJoD+kAV/
|
|
1333
|
+
V/�V/�V/�V/�V/�V/�V/�X0�Z2�\\4�^6�\`7wkA}lB�nC�oD�pF�rG�sH�sH�V/
|
|
1334
|
+
V/�V/�V/�V/�V/�V/�V/�W/�X1�Z3�\\4�^6j@}kA�lB�nC�oD�pE�qF�rG�V/
|
|
1335
|
+
V/�V/�V/�V/�V/�V/�V/�V/�W0�Y2�[3Rh>}i?�j@�lB�mC�nC�oD�pE�V/
|
|
1336
|
+
V/�V/�V/�V/�V/�V/�V/�V/�V/�W0�Z2f=}g=�h?�j@�kA�lB�mB�mC�V/
|
|
1337
|
+
V/�V/�V/�V/�V/�V/�V/�V/�V/�V/2d;}e<�f=�g>�i?�j@�j@�kA�V/
|
|
1338
|
+
V/�V/�V/�V/�V/�V/�V/�V/�V/~b9}c:�d;�e<�f=�g>�h>�i?�V/
|
|
1339
|
+
V/�V/�V/�V/�V/�V/�V/�V/�V/\`7}a8�b9�c:�d;�e<�f<�f=�V/V/TV/pV/nV/nV/nV/nV/oV/:_66\`7oa8nb9nc:nd;nd;pe;C�������������������������������������������������������������������������>��������������������?����������������>����\`��\`����������?���?����?����?����?����?���?�?����?����?��������������������������������������������������( @ V/V/XV/\\V/\\V/]X1/L,~SI�i\`�i_�i_�i[�i�_�\\V�X\\�S\\{N^wJ,V/KV/�V/�V/�W0�Y1�d=BgA�b��k��k��k��k��k�s�c��_��Z��U�}P�xL6V/KV/�V/�V/�X1�Z3�pEmC�b=�pJ��j��k��k��k�kJ�kA�g�c��]��X��TyV/KV/�V/�V/�Y1�[3�oDfqF�nE�\`=��Y��l��k��k��kϞk˝j��f��\`��[��VV/KV/�V/�W/�Z2�\\4�mC#oD�rG�uI�lE�hD��e��k��k��k��k��k��h��c�^FV/V/V/KV/�V/�W0�Z3�]5�h>mC�pE�sH�wK�wL�hC�yP��k��k��k��k��k��i��e��[V/*V/zV/KV/�V/�W0�[3�]5�kA@mB�pE�tI�xL�{N�wL�fC��]��l��k��k��k��j͚g�w ]5\\W0oV/KV/�V/�W0�[3�]5�g>j@�mB�qF�tI�xL�|O�|P�hC�mI��k��k��k��l������F��J ��NIĢ6�d<�V/�V/KV/�V/�W0�[3�]5�g=ci?�mB�pE�tH�xL�{N�wM�eB��[��k��k��k��j���3��ڑU�ݩ�ڜ�ٜF��uk߾Dҽ�1��c�]5�W0�V/KV/�V/�W0�Z3�]5�d;e<�i?�lB�pE�sH�wK�wL�hC�vN��j��k��k��k��j��z�ܿ^��ֈ����Ԃ���Z���!�mC�a8�[4�W0�V/KV/�V/�W/�Z2�\\4�b9�d;�h>�kA�oD�qFBuJ�mE�fB��d��k��k��k��k��k��g��{�Ϊ=�ܽM�ٸD���'�uJ�h>�b9�[3�W06V/KV/�V/�V/�Y1�\\4�\`8�c:�g=�j@�mC�zKlD�_<��W��l��k��k��k��k؝j��f��_��_��e
|
|
1340
|
+
��] �wK�nC�g=�\`7�[3L'V/KV/�V/�V/�X1�[3�_6�b9�e<�h?�kA%\\9�mG��i��k��k��k��ke�k9�gՔb��]��W�Q�yL�sG�lA�e<�\`7�[3V/KV/�V/�V/�W0�Z2�]5�a8�d;�f=jeA��a��l��l��k��k��k�d.�_��Z�U�}O�vJ�pE�j?�d;v_7V/KV/�V/�V/�V/�X1�\\4�_7�b9�e;|P��Y��Z��[��\\�aA�\\�W7�RnzM�tH�nC\\i?!a9V/KV/�V/�V/�V/�W0�Z2�]5�_7Gj?lA�mC�oD�qF�sG�sH+V/KV/�V/�V/�V/�V/�X1�[3�\`7b8i?�j@�mB�nD�pE�pE+V/KV/�V/�V/�V/�V/�V/�X1)_6f=�g>�i@�kA�lB�mC+V/LV/�V/�V/�V/�V/�V/q]4c:�d;�f=�h>�i?�i?+V/@V/�V/�V/�V/�V/�V/[2\`8�b9�c:�e;�f<�f=$V/V/V/V/V/V/_6\`7a9c:d;d;����������������������������������0��0���������������������00�p8�p?�����������������������������������( V/'V/;W0*Z3^:�]2�k=�j%�]#�V<{N(j?V/�V/�X1�\\4h@LvM�i��kʞkA�cƉY�QaV/�V/�Z2�[4nCqF�lE��Z��l��k�h��\`��VV/ V/�W0�[3�[4mCrrG�wK�tL��e��k��j�d8��(
|
|
1341
|
+
\\5VV/�W0�[3�f=1kA�rG�zM�qI��^��k��z���z0��#��R^�}#�b:�V/�W0�Z3�d;�j@�qF�qH�zP��j��k��r�ƤB�ڽ]㫆*�lC�[3�V/�V/�Z2�a8�g>�jAGlFc��l��k��e�a��^�sH�c:�[47V/�V/�X1�^6�c:�^:�TŒa��d��n
|
|
1342
|
+
�\`@�V�xK�mB�d;-V/�V/�V/�Z2�_6 mB
|
|
1343
|
+
mC�pE�sG�yLtHlAV/�V/�V/�W/dc:e<�h?�j@�V/RV/|V/hV/_7a9^d;}f<A��������Oc������"
|
|
1344
|
+
`;
|
|
1345
|
+
|
|
1346
|
+
exports[`react-website generator > Tanstack router integration > should generate website with no router correctly > test-app/src/app.tsx 1`] = `
|
|
1347
|
+
"import AppLayout from './components/AppLayout';
|
|
1348
|
+
import {
|
|
1349
|
+
ContentLayout,
|
|
1350
|
+
Header,
|
|
1351
|
+
SpaceBetween,
|
|
1352
|
+
Container,
|
|
1353
|
+
} from '@cloudscape-design/components';
|
|
1354
|
+
|
|
1355
|
+
export const App = () => (
|
|
1356
|
+
<AppLayout>
|
|
1357
|
+
<ContentLayout header={<Header>Welcome</Header>}>
|
|
1358
|
+
<SpaceBetween size="l">
|
|
1359
|
+
<Container>Welcome to your new React website!</Container>
|
|
1360
|
+
</SpaceBetween>
|
|
1361
|
+
</ContentLayout>
|
|
1362
|
+
</AppLayout>
|
|
1363
|
+
);
|
|
1364
|
+
"
|
|
1365
|
+
`;
|
|
1366
|
+
|
|
1367
|
+
exports[`react-website generator > Tanstack router integration > should generate website with no router correctly > test-app/src/components/AppLayout/index.tsx 1`] = `
|
|
1368
|
+
"import * as React from 'react';
|
|
1369
|
+
import { createContext, useCallback, useState } from 'react';
|
|
1370
|
+
import Config from '../../config';
|
|
1371
|
+
|
|
1372
|
+
import { TopNavigation } from '@cloudscape-design/components';
|
|
1373
|
+
import CloudscapeAppLayout, {
|
|
1374
|
+
AppLayoutProps,
|
|
1375
|
+
} from '@cloudscape-design/components/app-layout';
|
|
1376
|
+
|
|
1377
|
+
export interface AppLayoutContext {
|
|
1378
|
+
appLayoutProps: AppLayoutProps;
|
|
1379
|
+
setAppLayoutProps: (props: AppLayoutProps) => void;
|
|
1380
|
+
displayHelpPanel: (helpContent: React.ReactNode) => void;
|
|
1381
|
+
}
|
|
1382
|
+
|
|
1383
|
+
/**
|
|
1384
|
+
* Context for updating/retrieving the AppLayout.
|
|
1385
|
+
*/
|
|
1386
|
+
export const AppLayoutContext = createContext({
|
|
1387
|
+
appLayoutProps: {},
|
|
1388
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
1389
|
+
setAppLayoutProps: (_: AppLayoutProps) => {},
|
|
1390
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
1391
|
+
displayHelpPanel: (_: React.ReactNode) => {},
|
|
1392
|
+
});
|
|
1393
|
+
|
|
1394
|
+
/**
|
|
1395
|
+
* Defines the App layout and contains logic for routing.
|
|
1396
|
+
*/
|
|
1397
|
+
const AppLayout: React.FC<React.PropsWithChildren> = ({ children }) => {
|
|
1398
|
+
const appLayout = React.useRef<AppLayoutProps.Ref>(null);
|
|
1399
|
+
const [appLayoutProps, setAppLayoutProps] = useState<AppLayoutProps>({});
|
|
1400
|
+
const setAppLayoutPropsSafe = useCallback(
|
|
1401
|
+
(props: AppLayoutProps) => {
|
|
1402
|
+
JSON.stringify(appLayoutProps) !== JSON.stringify(props) &&
|
|
1403
|
+
setAppLayoutProps(props);
|
|
1404
|
+
},
|
|
1405
|
+
[appLayoutProps],
|
|
1406
|
+
);
|
|
1407
|
+
|
|
1408
|
+
return (
|
|
1409
|
+
<AppLayoutContext.Provider
|
|
1410
|
+
value={{
|
|
1411
|
+
appLayoutProps,
|
|
1412
|
+
setAppLayoutProps: setAppLayoutPropsSafe,
|
|
1413
|
+
displayHelpPanel: (helpContent: React.ReactNode) => {
|
|
1414
|
+
setAppLayoutPropsSafe({ tools: helpContent, toolsHide: false });
|
|
1415
|
+
appLayout.current?.openTools();
|
|
1416
|
+
},
|
|
1417
|
+
}}
|
|
1418
|
+
>
|
|
1419
|
+
<TopNavigation
|
|
1420
|
+
identity={{
|
|
1421
|
+
href: '/',
|
|
1422
|
+
title: Config.applicationName,
|
|
1423
|
+
logo: {
|
|
1424
|
+
src: Config.logo,
|
|
1425
|
+
},
|
|
1426
|
+
}}
|
|
1427
|
+
/>
|
|
1428
|
+
<CloudscapeAppLayout
|
|
1429
|
+
ref={appLayout}
|
|
1430
|
+
navigationHide
|
|
1431
|
+
toolsHide
|
|
1432
|
+
content={children}
|
|
1433
|
+
{...appLayoutProps}
|
|
1434
|
+
/>
|
|
1435
|
+
</AppLayoutContext.Provider>
|
|
1436
|
+
);
|
|
1437
|
+
};
|
|
1438
|
+
|
|
1439
|
+
export default AppLayout;
|
|
1440
|
+
"
|
|
1441
|
+
`;
|
|
1442
|
+
|
|
1443
|
+
exports[`react-website generator > Tanstack router integration > should generate website with no router correctly > test-app/src/config.ts 1`] = `
|
|
1444
|
+
"export default {
|
|
1445
|
+
applicationName: 'test-app',
|
|
1446
|
+
logo: 'data:image/svg+xml;base64,PCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj4KDTwhLS0gVXBsb2FkZWQgdG86IFNWRyBSZXBvLCB3d3cuc3ZncmVwby5jb20sIFRyYW5zZm9ybWVkIGJ5OiBTVkcgUmVwbyBNaXhlciBUb29scyAtLT4KPHN2ZyBmaWxsPSIjMjQ4YmFlIiB3aWR0aD0iODAwcHgiIGhlaWdodD0iODAwcHgiIHZpZXdCb3g9IjAgMCA1MTIgNTEyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0cm9rZT0iIzI0OGJhZSI+Cg08ZyBpZD0iU1ZHUmVwb19iZ0NhcnJpZXIiIHN0cm9rZS13aWR0aD0iMCIvPgoNPGcgaWQ9IlNWR1JlcG9fdHJhY2VyQ2FycmllciIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+Cg08ZyBpZD0iU1ZHUmVwb19pY29uQ2FycmllciI+Cg08dGl0bGU+aW9uaWNvbnMtdjVfbG9nb3M8L3RpdGxlPgoNPHBhdGggZD0iTTQxMC42NiwxODAuNzJoMHEtNy42Ny0yLjYyLTE1LjQ1LTQuODgsMS4yOS01LjI1LDIuMzgtMTAuNTZjMTEuNy01Ni45LDQuMDUtMTAyLjc0LTIyLjA2LTExNy44My0yNS0xNC40OC02NiwuNjEtMTA3LjM2LDM2LjY5cS02LjEsNS4zNC0xMS45NSwxMS0zLjktMy43Ni04LTcuMzZjLTQzLjM1LTM4LjU4LTg2LjgtNTQuODMtMTEyLjg4LTM5LjY5LTI1LDE0LjUxLTMyLjQzLDU3LjYtMjEuOSwxMTEuNTNxMS41OCw4LDMuNTUsMTUuOTNjLTYuMTUsMS43NS0xMi4wOSwzLjYyLTE3Ljc3LDUuNkM0OC40NiwxOTguOSwxNiwyMjYuNzMsMTYsMjU1LjU5YzAsMjkuODIsMzQuODQsNTkuNzIsODcuNzcsNzcuODVxNi40NCwyLjE5LDEzLDQuMDdRMTE0LjY0LDM0NiwxMTMsMzU0LjY4Yy0xMCw1My0yLjIsOTUuMDcsMjIuNzUsMTA5LjQ5LDI1Ljc3LDE0Ljg5LDY5LS40MSwxMTEuMTQtMzcuMzFxNS00LjM4LDEwLTkuMjUsNi4zMiw2LjExLDEzLDExLjg2YzQwLjgsMzUuMTgsODEuMDksNDkuMzksMTA2LDM0LjkzLDI1Ljc1LTE0Ljk0LDM0LjEyLTYwLjE0LDIzLjI1LTExNS4xM3EtMS4yNS02LjMtMi44OC0xMi44Niw0LjU2LTEuMzUsOC45My0yLjc5YzU1LTE4LjI3LDkwLjgzLTQ3LjgxLDkwLjgzLTc4QzQ5NiwyMjYuNjIsNDYyLjUsMTk4LjYxLDQxMC42NiwxODAuNzJabS0xMjktODEuMDhjMzUuNDMtMzAuOTEsNjguNTUtNDMuMTEsODMuNjUtMzQuMzloMGMxNi4wNyw5LjI5LDIyLjMyLDQ2Ljc1LDEyLjIyLDk1Ljg4cS0xLDQuOC0yLjE2LDkuNTdhNDg3LjgzLDQ4Ny44MywwLDAsMC02NC4xOC0xMC4xNiw0ODEuMjcsNDgxLjI3LDAsMCwwLTQwLjU3LTUwLjc1UTI3NiwxMDQuNTcsMjgxLjY0LDk5LjY0Wk0xNTcuNzMsMjgwLjI1cTYuNTEsMTIuNiwxMy42MSwyNC44OSw3LjIzLDEyLjU0LDE1LjA3LDI0LjcxYTQzNS4yOCw0MzUuMjgsMCwwLDEtNDQuMjQtNy4xM0MxNDYuNDEsMzA5LDE1MS42MywyOTQuNzUsMTU3LjczLDI4MC4yNVptMC00OC4zM2MtNi0xNC4xOS0xMS4wOC0yOC4xNS0xNS4yNS00MS42MywxMy43LTMuMDcsMjguMy01LjU4LDQzLjUyLTcuNDhxLTcuNjUsMTEuOTQtMTQuNzIsMjQuMjNUMTU3LjcsMjMxLjkyWm0xMC45LDI0LjE3cTkuNDgtMTkuNzcsMjAuNDItMzguNzhoMHExMC45My0xOSwyMy4yNy0zNy4xM2MxNC4yOC0xLjA4LDI4LjkyLTEuNjUsNDMuNzEtMS42NXMyOS41Mi41Nyw0My43OSwxLjY2cTEyLjIxLDE4LjA5LDIzLjEzLDM3dDIwLjY5LDM4LjZRMzM0LDI3NS42MywzMjMsMjk0LjczaDBxLTEwLjkxLDE5LTIzLDM3LjI0Yy0xNC4yNSwxLTI5LDEuNTUtNDQsMS41NXMtMjkuNDctLjQ3LTQzLjQ2LTEuMzhxLTEyLjQzLTE4LjE5LTIzLjQ2LTM3LjI5VDE2OC42LDI1Ni4wOVpNMzQwLjc1LDMwNXE3LjI1LTEyLjU4LDEzLjkyLTI1LjQ5aDBhNDQwLjQxLDQ0MC40MSwwLDAsMSwxNi4xMiw0Mi4zMkE0MzQuNDQsNDM0LjQ0LDAsMCwxLDMyNiwzMjkuNDhRMzMzLjYyLDMxNy4zOSwzNDAuNzUsMzA1Wm0xMy43Mi03My4wN3EtNi42NC0xMi42NS0xMy44MS0yNWgwcS03LTEyLjE4LTE0LjU5LTI0LjA2YzE1LjMxLDEuOTQsMzAsNC41Miw0My43Nyw3LjY3QTQzOS44OSw0MzkuODksMCwwLDEsMzU0LjQ3LDIzMS45M1pNMjU2LjIzLDEyNC40OGgwYTQzOS43NSw0MzkuNzUsMCwwLDEsMjguMjUsMzQuMThxLTI4LjM1LTEuMzUtNTYuNzQsMEMyMzcuMDcsMTQ2LjMyLDI0Ni42MiwxMzQuODcsMjU2LjIzLDEyNC40OFpNMTQ1LjY2LDY1Ljg2YzE2LjA2LTkuMzIsNTEuNTcsNCw4OSwzNy4yNywyLjM5LDIuMTMsNC44LDQuMzYsNy4yLDYuNjdBNDkxLjM3LDQ5MS4zNywwLDAsMCwyMDEsMTYwLjUxYTQ5OS4xMiw0OTkuMTIsMCwwLDAtNjQuMDYsMTBxLTEuODMtNy4zNi0zLjMtMTQuODJoMEMxMjQuNTksMTA5LjQ2LDEzMC41OCw3NC42MSwxNDUuNjYsNjUuODZaTTEyMi4yNSwzMTcuNzFxLTYtMS43MS0xMS44NS0zLjcxYy0yMy40LTgtNDIuNzMtMTguNDQtNTYtMjkuODFDNDIuNTIsMjc0LDM2LjUsMjYzLjgzLDM2LjUsMjU1LjU5YzAtMTcuNTEsMjYuMDYtMzkuODUsNjkuNTItNTVxOC4xOS0yLjg1LDE2LjUyLTUuMjFhNDkzLjU0LDQ5My41NCwwLDAsMCwyMy40LDYwLjc1QTUwMi40Niw1MDIuNDYsMCwwLDAsMTIyLjI1LDMxNy43MVptMTExLjEzLDkzLjY3Yy0xOC42MywxNi4zMi0zNy4yOSwyNy44OS01My43NCwzMy43MmgwYy0xNC43OCw1LjIzLTI2LjU1LDUuMzgtMzMuNjYsMS4yNy0xNS4xNC04Ljc1LTIxLjQ0LTQyLjU0LTEyLjg1LTg3Ljg2cTEuNTMtOCwzLjUtMTZhNDgwLjg1LDQ4MC44NSwwLDAsMCw2NC42OSw5LjM5LDUwMS4yLDUwMS4yLDAsMCwwLDQxLjIsNTFDMjM5LjU0LDQwNS44MywyMzYuNDksNDA4LjY1LDIzMy4zOCw0MTEuMzhabTIzLjQyLTIzLjIyYy05LjcyLTEwLjUxLTE5LjQyLTIyLjE0LTI4Ljg4LTM0LjY0cTEzLjc5LjU0LDI4LjA4LjU0YzkuNzgsMCwxOS40Ni0uMjEsMjktLjY0QTQzOS4zMyw0MzkuMzMsMCwwLDEsMjU2LjgsMzg4LjE2Wm0xMjQuNTIsMjguNTljLTIuODYsMTUuNDQtOC42MSwyNS43NC0xNS43MiwyOS44Ni0xNS4xMyw4Ljc4LTQ3LjQ4LTIuNjMtODIuMzYtMzIuNzItNC0zLjQ0LTgtNy4xMy0xMi4wNy0xMWE0ODQuNTQsNDg0LjU0LDAsMCwwLDQwLjIzLTUxLjIsNDc3Ljg0LDQ3Ny44NCwwLDAsMCw2NS0xMC4wNXExLjQ3LDUuOTQsMi42LDExLjY0aDBDMzgzLjgxLDM3Ny41OCwzODQuNSwzOTkuNTYsMzgxLjMyLDQxNi43NVptMTcuNC0xMDIuNjRoMGMtMi42Mi44Ny01LjMyLDEuNzEtOC4wNiwyLjUzYTQ4My4yNiw0ODMuMjYsMCwwLDAtMjQuMzEtNjAuOTQsNDgxLjUyLDQ4MS41MiwwLDAsMCwyMy4zNi02MC4wNmM0LjkxLDEuNDMsOS42OCwyLjkzLDE0LjI3LDQuNTIsNDQuNDIsMTUuMzIsNzEuNTIsMzgsNzEuNTIsNTUuNDNDNDc1LjUsMjc0LjE5LDQ0Ni4yMywyOTguMzMsMzk4LjcyLDMxNC4xMVoiLz4KDTxwYXRoIGQ9Ik0yNTYsMjk4LjU1YTQzLDQzLDAsMSwwLTQyLjg2LTQzQTQyLjkxLDQyLjkxLDAsMCwwLDI1NiwyOTguNTVaIi8+Cg08L2c+Cg08L3N2Zz4=',
|
|
1447
|
+
};
|
|
1448
|
+
"
|
|
1449
|
+
`;
|
|
1450
|
+
|
|
1451
|
+
exports[`react-website generator > Tanstack router integration > should generate website with no router correctly > test-app/src/hooks/useAppLayout.tsx 1`] = `
|
|
1452
|
+
"import { useContext } from 'react';
|
|
1453
|
+
import { AppLayoutContext } from '../components/AppLayout';
|
|
1454
|
+
|
|
1455
|
+
export const useAppLayout = (): AppLayoutContext =>
|
|
1456
|
+
useContext(AppLayoutContext);
|
|
1457
|
+
"
|
|
1458
|
+
`;
|
|
1459
|
+
|
|
1460
|
+
exports[`react-website generator > Tanstack router integration > should generate website with no router correctly > test-app/src/main.tsx 1`] = `
|
|
1461
|
+
"import React from 'react';
|
|
1462
|
+
import { createRoot } from 'react-dom/client';
|
|
1463
|
+
import { I18nProvider } from '@cloudscape-design/components/i18n';
|
|
1464
|
+
import messages from '@cloudscape-design/components/i18n/messages/all.en';
|
|
1465
|
+
import '@cloudscape-design/global-styles/index.css';
|
|
1466
|
+
import { App } from './app';
|
|
1467
|
+
|
|
1468
|
+
const root = document.getElementById('root');
|
|
1469
|
+
root &&
|
|
1470
|
+
createRoot(root).render(
|
|
1471
|
+
<React.StrictMode>
|
|
1472
|
+
<I18nProvider locale="en" messages={[messages]}>
|
|
1473
|
+
<App />
|
|
1474
|
+
</I18nProvider>
|
|
1475
|
+
</React.StrictMode>,
|
|
1476
|
+
);
|
|
1477
|
+
"
|
|
1478
|
+
`;
|
|
1479
|
+
|
|
1480
|
+
exports[`react-website generator > Tanstack router integration > should generate website with no router correctly > test-app/src/styles.css 1`] = `
|
|
1481
|
+
"@import 'tailwindcss';
|
|
1482
|
+
/* You can add global styles to this file, and also import other style files */
|
|
1483
|
+
"
|
|
1484
|
+
`;
|
|
1485
|
+
|
|
1486
|
+
exports[`react-website generator > Tanstack router integration > should generate website with no router correctly > test-app/tsconfig.app.json 1`] = `
|
|
1487
|
+
"{
|
|
1488
|
+
"extends": "../tsconfig.base.json",
|
|
1489
|
+
"compilerOptions": {
|
|
1490
|
+
"outDir": "../dist/test-app/tsc",
|
|
1491
|
+
"tsBuildInfoFile": "../dist/test-app/tsc/tsconfig.lib.tsbuildinfo",
|
|
1492
|
+
"jsx": "react-jsx",
|
|
1493
|
+
"lib": ["DOM"],
|
|
1494
|
+
"types": [
|
|
1495
|
+
"node",
|
|
1496
|
+
"@nx/react/typings/cssmodule.d.ts",
|
|
1497
|
+
"@nx/react/typings/image.d.ts",
|
|
1498
|
+
"vite/client"
|
|
1499
|
+
]
|
|
1500
|
+
},
|
|
1501
|
+
"exclude": [
|
|
1502
|
+
"src/**/*.spec.ts",
|
|
1503
|
+
"src/**/*.test.ts",
|
|
1504
|
+
"src/**/*.spec.tsx",
|
|
1505
|
+
"src/**/*.test.tsx",
|
|
1506
|
+
"src/**/*.spec.js",
|
|
1507
|
+
"src/**/*.test.js",
|
|
1508
|
+
"src/**/*.spec.jsx",
|
|
1509
|
+
"src/**/*.test.jsx",
|
|
1510
|
+
"vite.config.ts",
|
|
1511
|
+
"vite.config.mts",
|
|
1512
|
+
"vitest.config.ts",
|
|
1513
|
+
"vitest.config.mts"
|
|
1514
|
+
],
|
|
1515
|
+
"include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"]
|
|
1516
|
+
}
|
|
1517
|
+
"
|
|
1518
|
+
`;
|
|
1519
|
+
|
|
1520
|
+
exports[`react-website generator > Tanstack router integration > should generate website with no router correctly > test-app/tsconfig.json 1`] = `
|
|
1521
|
+
"{
|
|
1522
|
+
"files": [],
|
|
1523
|
+
"include": [],
|
|
1524
|
+
"references": [
|
|
1525
|
+
{
|
|
1526
|
+
"path": "./tsconfig.app.json"
|
|
1527
|
+
},
|
|
1528
|
+
{
|
|
1529
|
+
"path": "./tsconfig.spec.json"
|
|
1530
|
+
}
|
|
1531
|
+
],
|
|
1532
|
+
"extends": "../tsconfig.base.json",
|
|
1533
|
+
"compilerOptions": {
|
|
1534
|
+
"moduleResolution": "Bundler",
|
|
1535
|
+
"module": "Preserve"
|
|
1536
|
+
}
|
|
1537
|
+
}
|
|
1538
|
+
"
|
|
1539
|
+
`;
|
|
1540
|
+
|
|
1541
|
+
exports[`react-website generator > Tanstack router integration > should generate website with no router correctly > test-app/tsconfig.spec.json 1`] = `
|
|
1542
|
+
"{
|
|
1543
|
+
"extends": "../tsconfig.base.json",
|
|
1544
|
+
"compilerOptions": {
|
|
1545
|
+
"outDir": "./out-tsc/vitest",
|
|
1546
|
+
"types": [
|
|
1547
|
+
"vitest/globals",
|
|
1548
|
+
"vitest/importMeta",
|
|
1549
|
+
"vite/client",
|
|
1550
|
+
"node",
|
|
1551
|
+
"vitest",
|
|
1552
|
+
"@nx/react/typings/cssmodule.d.ts",
|
|
1553
|
+
"@nx/react/typings/image.d.ts"
|
|
1554
|
+
]
|
|
1555
|
+
},
|
|
1556
|
+
"include": [
|
|
1557
|
+
"vite.config.ts",
|
|
1558
|
+
"vite.config.mts",
|
|
1559
|
+
"vitest.config.ts",
|
|
1560
|
+
"vitest.config.mts",
|
|
1561
|
+
"src/**/*.test.ts",
|
|
1562
|
+
"src/**/*.spec.ts",
|
|
1563
|
+
"src/**/*.test.tsx",
|
|
1564
|
+
"src/**/*.spec.tsx",
|
|
1565
|
+
"src/**/*.test.js",
|
|
1566
|
+
"src/**/*.spec.js",
|
|
1567
|
+
"src/**/*.test.jsx",
|
|
1568
|
+
"src/**/*.spec.jsx",
|
|
1569
|
+
"src/**/*.d.ts"
|
|
1570
|
+
],
|
|
1571
|
+
"references": [
|
|
1572
|
+
{
|
|
1573
|
+
"path": "./tsconfig.app.json"
|
|
1574
|
+
}
|
|
1575
|
+
]
|
|
1576
|
+
}
|
|
1577
|
+
"
|
|
1578
|
+
`;
|
|
1579
|
+
|
|
1580
|
+
exports[`react-website generator > Tanstack router integration > should generate website with no router correctly > test-app/vite.config.ts 1`] = `
|
|
1581
|
+
"import tailwindcss from '@tailwindcss/vite';
|
|
1582
|
+
import tsconfigPaths from 'vite-tsconfig-paths';
|
|
1583
|
+
/// <reference types='vitest' />
|
|
1584
|
+
import { defineConfig } from 'vite';
|
|
1585
|
+
import react from '@vitejs/plugin-react';
|
|
1586
|
+
|
|
1587
|
+
export default defineConfig(() => ({
|
|
1588
|
+
define: {
|
|
1589
|
+
global: {},
|
|
1590
|
+
},
|
|
1591
|
+
root: __dirname,
|
|
1592
|
+
cacheDir: '../node_modules/.vite/test-app',
|
|
1593
|
+
server: {
|
|
1594
|
+
port: 4200,
|
|
1595
|
+
host: 'localhost',
|
|
1596
|
+
},
|
|
1597
|
+
preview: {
|
|
1598
|
+
port: 4300,
|
|
1599
|
+
host: 'localhost',
|
|
1600
|
+
},
|
|
1601
|
+
plugins: [react(), tailwindcss(), tsconfigPaths()],
|
|
1602
|
+
build: {
|
|
1603
|
+
outDir: '../dist/test-app',
|
|
1604
|
+
emptyOutDir: true,
|
|
1605
|
+
reportCompressedSize: true,
|
|
1606
|
+
commonjsOptions: {
|
|
1607
|
+
transformMixedEsModules: true,
|
|
1608
|
+
},
|
|
1609
|
+
},
|
|
1610
|
+
test: {
|
|
1611
|
+
watch: false,
|
|
1612
|
+
globals: true,
|
|
1613
|
+
environment: 'jsdom',
|
|
1614
|
+
include: ['{src,tests}/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
|
1615
|
+
reporters: ['default'],
|
|
1616
|
+
coverage: {
|
|
1617
|
+
reportsDirectory: './test-output/vitest/coverage',
|
|
1618
|
+
provider: 'v8' as const,
|
|
1619
|
+
},
|
|
1620
|
+
passWithNoTests: true,
|
|
1621
|
+
},
|
|
1622
|
+
}));
|
|
1623
|
+
"
|
|
1624
|
+
`;
|
|
1625
|
+
|
|
1626
|
+
exports[`react-website generator > Tanstack router integration > should generate website with no router correctly > tsconfig.base.json 1`] = `
|
|
1627
|
+
"{
|
|
1628
|
+
"compilerOptions": {
|
|
1629
|
+
"paths": {
|
|
1630
|
+
":proj/common-types": ["packages/common/types/src/index.ts"],
|
|
1631
|
+
":proj/test-app": ["test-app/src/index.ts"],
|
|
1632
|
+
":proj/common-constructs": ["packages/common/constructs/src/index.ts"]
|
|
1633
|
+
},
|
|
1634
|
+
"baseUrl": ".",
|
|
1635
|
+
"rootDir": "."
|
|
1636
|
+
}
|
|
1637
|
+
}
|
|
1638
|
+
"
|
|
1639
|
+
`;
|
|
1640
|
+
|
|
1641
|
+
exports[`react-website generator > Tanstack router integration > should generate website with no router correctly > tsconfig.json 1`] = `
|
|
1642
|
+
"{
|
|
1643
|
+
"references": [
|
|
1644
|
+
{
|
|
1645
|
+
"path": "./test-app"
|
|
1646
|
+
},
|
|
1647
|
+
{
|
|
1648
|
+
"path": "./packages/common/types"
|
|
1649
|
+
},
|
|
1650
|
+
{
|
|
1651
|
+
"path": "./packages/common/constructs"
|
|
1652
|
+
}
|
|
1653
|
+
]
|
|
1654
|
+
}
|
|
1655
|
+
"
|
|
1656
|
+
`;
|
|
1657
|
+
|
|
1658
|
+
exports[`react-website generator > Tanstack router integration > should generate website with no router correctly > vitest.workspace.ts 1`] = `
|
|
1659
|
+
"export default [
|
|
1660
|
+
'**/vite.config.{mjs,js,ts,mts}',
|
|
1661
|
+
'**/vitest.config.{mjs,js,ts,mts}',
|
|
1662
|
+
];
|
|
1663
|
+
"
|
|
1664
|
+
`;
|
|
1665
|
+
|
|
1666
|
+
exports[`react-website generator > Tanstack router integration > should generate website with router correctly > .gitignore 1`] = `
|
|
1667
|
+
"vite.config.*.timestamp*
|
|
1668
|
+
vitest.config.*.timestamp*
|
|
1669
|
+
|
|
1670
|
+
runtime-config.json"
|
|
1671
|
+
`;
|
|
1672
|
+
|
|
1673
|
+
exports[`react-website generator > Tanstack router integration > should generate website with router correctly > .prettierrc 1`] = `
|
|
1674
|
+
"{ "singleQuote": true }
|
|
1675
|
+
"
|
|
1676
|
+
`;
|
|
1677
|
+
|
|
1678
|
+
exports[`react-website generator > Tanstack router integration > should generate website with router correctly > eslint.config.mjs 1`] = `
|
|
1679
|
+
"import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended';
|
|
1680
|
+
import nx from '@nx/eslint-plugin';
|
|
1681
|
+
|
|
1682
|
+
export default [
|
|
1683
|
+
eslintPluginPrettierRecommended,
|
|
1684
|
+
...nx.configs['flat/base'],
|
|
1685
|
+
...nx.configs['flat/typescript'],
|
|
1686
|
+
...nx.configs['flat/javascript'],
|
|
1687
|
+
{
|
|
1688
|
+
ignores: [
|
|
1689
|
+
'**/dist',
|
|
1690
|
+
'**/vite.config.*.timestamp*',
|
|
1691
|
+
'**/vitest.config.*.timestamp*',
|
|
1692
|
+
'**/vite.config.ts.timestamp*',
|
|
1693
|
+
],
|
|
1694
|
+
},
|
|
1695
|
+
{
|
|
1696
|
+
files: ['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx'],
|
|
1697
|
+
rules: {
|
|
1698
|
+
'@nx/enforce-module-boundaries': [
|
|
1699
|
+
'error',
|
|
1700
|
+
{
|
|
1701
|
+
enforceBuildableLibDependency: true,
|
|
1702
|
+
allow: ['^.*/eslint(\\\\.base)?\\\\.config\\\\.[cm]?js$'],
|
|
1703
|
+
depConstraints: [
|
|
1704
|
+
{
|
|
1705
|
+
sourceTag: '*',
|
|
1706
|
+
onlyDependOnLibsWithTags: ['*'],
|
|
1707
|
+
},
|
|
1708
|
+
],
|
|
1709
|
+
},
|
|
1710
|
+
],
|
|
1711
|
+
},
|
|
1712
|
+
},
|
|
1713
|
+
{
|
|
1714
|
+
files: [
|
|
1715
|
+
'**/*.ts',
|
|
1716
|
+
'**/*.tsx',
|
|
1717
|
+
'**/*.cts',
|
|
1718
|
+
'**/*.mts',
|
|
1719
|
+
'**/*.js',
|
|
1720
|
+
'**/*.jsx',
|
|
1721
|
+
'**/*.cjs',
|
|
1722
|
+
'**/*.mjs',
|
|
1723
|
+
],
|
|
1724
|
+
rules: {},
|
|
1725
|
+
},
|
|
1726
|
+
];
|
|
1727
|
+
"
|
|
1728
|
+
`;
|
|
1729
|
+
|
|
1730
|
+
exports[`react-website generator > Tanstack router integration > should generate website with router correctly > nx.json 1`] = `
|
|
1731
|
+
"{
|
|
1732
|
+
"affected": {
|
|
1733
|
+
"defaultBase": "main"
|
|
1734
|
+
},
|
|
1735
|
+
"targetDefaults": {
|
|
1736
|
+
"build": {
|
|
1737
|
+
"cache": true,
|
|
1738
|
+
"dependsOn": ["^build"],
|
|
1739
|
+
"inputs": ["default"]
|
|
1740
|
+
},
|
|
1741
|
+
"lint": {
|
|
1742
|
+
"cache": true,
|
|
1743
|
+
"configurations": {
|
|
1744
|
+
"fix": {
|
|
1745
|
+
"fix": true
|
|
1746
|
+
}
|
|
1747
|
+
},
|
|
1748
|
+
"inputs": [
|
|
1749
|
+
"default",
|
|
1750
|
+
"{workspaceRoot}/eslint.config.mjs",
|
|
1751
|
+
"{projectRoot}/eslint.config.mjs"
|
|
1752
|
+
]
|
|
1753
|
+
},
|
|
1754
|
+
"@nx/eslint:lint": {
|
|
1755
|
+
"cache": true,
|
|
1756
|
+
"inputs": [
|
|
1757
|
+
"default",
|
|
1758
|
+
"{workspaceRoot}/.eslintrc.json",
|
|
1759
|
+
"{workspaceRoot}/.eslintignore",
|
|
1760
|
+
"{workspaceRoot}/eslint.config.mjs"
|
|
1761
|
+
]
|
|
1762
|
+
},
|
|
1763
|
+
"@nx/vite:test": {
|
|
1764
|
+
"cache": true,
|
|
1765
|
+
"inputs": ["default", "^default"],
|
|
1766
|
+
"configurations": {
|
|
1767
|
+
"update-snapshot": {
|
|
1768
|
+
"args": "--update"
|
|
1769
|
+
}
|
|
1770
|
+
}
|
|
1771
|
+
},
|
|
1772
|
+
"@nx/vite:build": {
|
|
1773
|
+
"cache": true,
|
|
1774
|
+
"dependsOn": ["^build"],
|
|
1775
|
+
"inputs": ["default", "^default"]
|
|
1776
|
+
},
|
|
1777
|
+
"test": {
|
|
1778
|
+
"dependsOn": ["^build"],
|
|
1779
|
+
"inputs": ["default"]
|
|
1780
|
+
},
|
|
1781
|
+
"compile": {
|
|
1782
|
+
"cache": true,
|
|
1783
|
+
"inputs": ["default"]
|
|
1784
|
+
}
|
|
1785
|
+
},
|
|
1786
|
+
"generators": {
|
|
1787
|
+
"@nx/react": {
|
|
1788
|
+
"application": {
|
|
1789
|
+
"babel": true,
|
|
1790
|
+
"style": "css",
|
|
1791
|
+
"linter": "eslint",
|
|
1792
|
+
"bundler": "vite"
|
|
1793
|
+
},
|
|
1794
|
+
"component": {
|
|
1795
|
+
"style": "css"
|
|
1796
|
+
},
|
|
1797
|
+
"library": {
|
|
1798
|
+
"style": "css",
|
|
1799
|
+
"linter": "eslint"
|
|
1800
|
+
}
|
|
1801
|
+
}
|
|
1802
|
+
},
|
|
1803
|
+
"plugins": [
|
|
1804
|
+
{
|
|
1805
|
+
"plugin": "@nx/js/typescript",
|
|
1806
|
+
"options": {
|
|
1807
|
+
"typecheck": {
|
|
1808
|
+
"targetName": "typecheck"
|
|
1809
|
+
},
|
|
1810
|
+
"build": {
|
|
1811
|
+
"targetName": "compile",
|
|
1812
|
+
"configName": "tsconfig.lib.json",
|
|
1813
|
+
"buildDepsName": "build-deps",
|
|
1814
|
+
"watchDepsName": "watch-deps"
|
|
1815
|
+
}
|
|
1816
|
+
}
|
|
1817
|
+
},
|
|
1818
|
+
{
|
|
1819
|
+
"plugin": "@nx/eslint/plugin",
|
|
1820
|
+
"options": {
|
|
1821
|
+
"targetName": "lint"
|
|
1822
|
+
}
|
|
1823
|
+
}
|
|
1824
|
+
],
|
|
1825
|
+
"namedInputs": {
|
|
1826
|
+
"default": [
|
|
1827
|
+
{
|
|
1828
|
+
"dependentTasksOutputFiles": "**/*",
|
|
1829
|
+
"transitive": true
|
|
1830
|
+
}
|
|
1831
|
+
]
|
|
1832
|
+
}
|
|
1833
|
+
}
|
|
1834
|
+
"
|
|
1835
|
+
`;
|
|
1836
|
+
|
|
1837
|
+
exports[`react-website generator > Tanstack router integration > should generate website with router correctly > package.json 1`] = `
|
|
1838
|
+
"{
|
|
1839
|
+
"name": "@proj/source",
|
|
1840
|
+
"dependencies": {
|
|
1841
|
+
"@cloudscape-design/board-components": "^3.0.94",
|
|
1842
|
+
"@cloudscape-design/components": "^3.0.928",
|
|
1843
|
+
"@cloudscape-design/global-styles": "^1.0.38",
|
|
1844
|
+
"@tanstack/react-router": "^1.121.16",
|
|
1845
|
+
"aws-cdk-lib": "^2.200.0",
|
|
1846
|
+
"constructs": "^10.4.2",
|
|
1847
|
+
"react": "19.0.0",
|
|
1848
|
+
"react-dom": "19.0.0",
|
|
1849
|
+
"tailwindcss": "^4.1.11"
|
|
1850
|
+
},
|
|
1851
|
+
"devDependencies": {
|
|
1852
|
+
"@eslint/js": "^9.8.0",
|
|
1853
|
+
"@nx/eslint": "21.0.3",
|
|
1854
|
+
"@nx/eslint-plugin": "21.0.3",
|
|
1855
|
+
"@nx/js": "21.0.3",
|
|
1856
|
+
"@nx/react": "21.0.3",
|
|
1857
|
+
"@nx/vite": "21.0.3",
|
|
1858
|
+
"@nx/web": "21.0.3",
|
|
1859
|
+
"@swc-node/register": "~1.9.1",
|
|
1860
|
+
"@swc/cli": "~0.6.0",
|
|
1861
|
+
"@swc/core": "~1.5.7",
|
|
1862
|
+
"@swc/helpers": "~0.5.11",
|
|
1863
|
+
"@tailwindcss/vite": "^4.1.11",
|
|
1864
|
+
"@tanstack/router-generator": "^1.121.16",
|
|
1865
|
+
"@tanstack/router-plugin": "^1.121.16",
|
|
1866
|
+
"@tanstack/router-utils": "^1.121.0",
|
|
1867
|
+
"@tanstack/virtual-file-routes": "^1.120.17",
|
|
1868
|
+
"@testing-library/dom": "10.4.0",
|
|
1869
|
+
"@testing-library/react": "16.1.0",
|
|
1870
|
+
"@types/node": "^22.13.13",
|
|
1871
|
+
"@types/react": "19.0.0",
|
|
1872
|
+
"@types/react-dom": "19.0.0",
|
|
1873
|
+
"@vitejs/plugin-react": "^4.2.0",
|
|
1874
|
+
"@vitest/coverage-v8": "^3.0.5",
|
|
1875
|
+
"@vitest/ui": "^3.0.0",
|
|
1876
|
+
"eslint": "^9.8.0",
|
|
1877
|
+
"eslint-config-prettier": "^10.0.0",
|
|
1878
|
+
"eslint-plugin-import": "2.31.0",
|
|
1879
|
+
"eslint-plugin-jsx-a11y": "6.10.1",
|
|
1880
|
+
"eslint-plugin-prettier": "^5.2.5",
|
|
1881
|
+
"eslint-plugin-react": "7.35.0",
|
|
1882
|
+
"eslint-plugin-react-hooks": "5.0.0",
|
|
1883
|
+
"jiti": "2.4.2",
|
|
1884
|
+
"jsdom": "~22.1.0",
|
|
1885
|
+
"jsonc-eslint-parser": "^2.4.0",
|
|
1886
|
+
"prettier": "^3.5.3",
|
|
1887
|
+
"typescript": "~5.7.2",
|
|
1888
|
+
"typescript-eslint": "^8.19.0",
|
|
1889
|
+
"vite": "^6.0.0",
|
|
1890
|
+
"vite-tsconfig-paths": "^5.1.4",
|
|
1891
|
+
"vitest": "^3.0.0"
|
|
1892
|
+
},
|
|
1893
|
+
"type": "module"
|
|
1894
|
+
}
|
|
1895
|
+
"
|
|
1896
|
+
`;
|
|
1897
|
+
|
|
1898
|
+
exports[`react-website generator > Tanstack router integration > should generate website with router correctly > packages/common/constructs/README.md 1`] = `
|
|
1899
|
+
"# @proj/common-constructs
|
|
1900
|
+
|
|
1901
|
+
This library was generated with [@aws/nx-plugin](https://github.com/awslabs/nx-plugin-for-aws/).
|
|
1902
|
+
|
|
1903
|
+
## Building
|
|
1904
|
+
|
|
1905
|
+
Run \`npx nx build @proj/common-constructs [--skip-nx-cache]\` to build the application.
|
|
1906
|
+
|
|
1907
|
+
## Running unit tests
|
|
1908
|
+
|
|
1909
|
+
Run \`npx nx test @proj/common-constructs\` to execute the unit tests via Vitest.
|
|
1910
|
+
|
|
1911
|
+
### Updating snapshots
|
|
1912
|
+
|
|
1913
|
+
To update snapshots, run the following command:
|
|
1914
|
+
|
|
1915
|
+
\`npx nx test @proj/common-constructs --configuration=update-snapshot\`
|
|
1916
|
+
|
|
1917
|
+
## Run lint
|
|
1918
|
+
|
|
1919
|
+
Run \`npx nx lint @proj/common-constructs\`
|
|
1920
|
+
|
|
1921
|
+
### Fixable issues
|
|
1922
|
+
|
|
1923
|
+
You can also automatiaclly fix some lint errors by running the following command:
|
|
1924
|
+
|
|
1925
|
+
\`npx nx lint @proj/common-constructs --configuration=fix\`
|
|
1926
|
+
|
|
1927
|
+
## Useful links
|
|
1928
|
+
|
|
1929
|
+
- [common-constructs reference docs](TODO)
|
|
1930
|
+
- [Learn more about NX](https://nx.dev/getting-started/intro)
|
|
1931
|
+
"
|
|
1932
|
+
`;
|
|
1933
|
+
|
|
1934
|
+
exports[`react-website generator > Tanstack router integration > should generate website with router correctly > packages/common/constructs/eslint.config.mjs 1`] = `
|
|
1935
|
+
"import baseConfig from '../../../eslint.config.mjs';
|
|
1936
|
+
|
|
1937
|
+
export default [
|
|
1938
|
+
...baseConfig,
|
|
1939
|
+
{
|
|
1940
|
+
files: ['**/*.json'],
|
|
1941
|
+
rules: {
|
|
1942
|
+
'@nx/dependency-checks': [
|
|
1943
|
+
'warn',
|
|
1944
|
+
{
|
|
1945
|
+
ignoredFiles: [
|
|
1946
|
+
'{projectRoot}/eslint.config.{js,cjs,mjs}',
|
|
1947
|
+
'{projectRoot}/vite.config.{js,ts,mjs,mts}',
|
|
1948
|
+
],
|
|
1949
|
+
},
|
|
1950
|
+
],
|
|
1951
|
+
},
|
|
1952
|
+
languageOptions: {
|
|
1953
|
+
parser: await import('jsonc-eslint-parser'),
|
|
1954
|
+
},
|
|
1955
|
+
},
|
|
1956
|
+
];
|
|
1957
|
+
"
|
|
1958
|
+
`;
|
|
1959
|
+
|
|
1960
|
+
exports[`react-website generator > Tanstack router integration > should generate website with router correctly > packages/common/constructs/project.json 1`] = `
|
|
1961
|
+
"{
|
|
1962
|
+
"name": "@proj/common-constructs",
|
|
1963
|
+
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
|
|
1964
|
+
"sourceRoot": "packages/common/constructs/src",
|
|
1965
|
+
"projectType": "library",
|
|
1966
|
+
"tags": [],
|
|
1967
|
+
"targets": {
|
|
1968
|
+
"build": {
|
|
1969
|
+
"dependsOn": ["lint", "compile", "test", "@proj/test-app:build"]
|
|
1970
|
+
},
|
|
1971
|
+
"compile": {
|
|
1972
|
+
"executor": "nx:run-commands",
|
|
1973
|
+
"outputs": ["{workspaceRoot}/dist/packages/common/constructs/tsc"],
|
|
1974
|
+
"options": {
|
|
1975
|
+
"command": "tsc --build tsconfig.lib.json",
|
|
1976
|
+
"cwd": "{projectRoot}"
|
|
1977
|
+
}
|
|
1978
|
+
},
|
|
1979
|
+
"test": {
|
|
1980
|
+
"executor": "@nx/vite:test",
|
|
1981
|
+
"outputs": ["{options.reportsDirectory}"],
|
|
1982
|
+
"options": {
|
|
1983
|
+
"reportsDirectory": "../../../coverage/packages/common/constructs"
|
|
1984
|
+
}
|
|
1985
|
+
}
|
|
1986
|
+
},
|
|
1987
|
+
"metadata": {
|
|
1988
|
+
"generator": "ts#project"
|
|
1989
|
+
}
|
|
1990
|
+
}
|
|
1991
|
+
"
|
|
1992
|
+
`;
|
|
1993
|
+
|
|
1994
|
+
exports[`react-website generator > Tanstack router integration > should generate website with router correctly > packages/common/constructs/src/app/index.ts 1`] = `
|
|
1995
|
+
"export * from './static-websites/index.js';
|
|
1996
|
+
"
|
|
1997
|
+
`;
|
|
1998
|
+
|
|
1999
|
+
exports[`react-website generator > Tanstack router integration > should generate website with router correctly > packages/common/constructs/src/app/static-websites/index.ts 1`] = `
|
|
2000
|
+
"export * from './test-app.js';
|
|
2001
|
+
"
|
|
2002
|
+
`;
|
|
2003
|
+
|
|
2004
|
+
exports[`react-website generator > Tanstack router integration > should generate website with router correctly > packages/common/constructs/src/app/static-websites/test-app.ts 1`] = `
|
|
2005
|
+
"import * as url from 'url';
|
|
2006
|
+
import { Construct } from 'constructs';
|
|
2007
|
+
import { StaticWebsite } from '../../core/index.js';
|
|
2008
|
+
|
|
2009
|
+
export class TestApp extends StaticWebsite {
|
|
2010
|
+
constructor(scope: Construct, id: string) {
|
|
2011
|
+
super(scope, id, {
|
|
2012
|
+
websiteFilePath: url.fileURLToPath(
|
|
2013
|
+
new URL('../../../../../../dist/test-app/bundle', import.meta.url),
|
|
2014
|
+
),
|
|
2015
|
+
});
|
|
2016
|
+
}
|
|
2017
|
+
}
|
|
2018
|
+
"
|
|
2019
|
+
`;
|
|
2020
|
+
|
|
2021
|
+
exports[`react-website generator > Tanstack router integration > should generate website with router correctly > packages/common/constructs/src/core/app.ts 1`] = `
|
|
2022
|
+
"import { App as _App, AppProps, Aspects, IAspect, Stack } from 'aws-cdk-lib';
|
|
2023
|
+
import { IConstruct } from 'constructs';
|
|
2024
|
+
|
|
2025
|
+
export class App extends _App {
|
|
2026
|
+
constructor(props?: AppProps) {
|
|
2027
|
+
super(props);
|
|
2028
|
+
|
|
2029
|
+
Aspects.of(this).add(new MetricsAspect());
|
|
2030
|
+
}
|
|
2031
|
+
}
|
|
2032
|
+
|
|
2033
|
+
/**
|
|
2034
|
+
* Adds information to CloudFormation stack descriptions to provide usage metrics for @aws/nx-plugin
|
|
2035
|
+
*/
|
|
2036
|
+
class MetricsAspect implements IAspect {
|
|
2037
|
+
visit(node: IConstruct): void {
|
|
2038
|
+
if (node instanceof Stack) {
|
|
2039
|
+
const id = 'uksb-4wk0bqpg5s';
|
|
2040
|
+
const version = '0.0.0';
|
|
2041
|
+
const tags: string[] = ['g5'];
|
|
2042
|
+
node.templateOptions.description =
|
|
2043
|
+
\`\${node.templateOptions.description ?? ''} (\${id}) (version:\${version}) (tag:\${tags.join(',')})\`.trim();
|
|
2044
|
+
}
|
|
2045
|
+
}
|
|
2046
|
+
}
|
|
2047
|
+
"
|
|
2048
|
+
`;
|
|
2049
|
+
|
|
2050
|
+
exports[`react-website generator > Tanstack router integration > should generate website with router correctly > packages/common/constructs/src/core/index.ts 1`] = `
|
|
2051
|
+
"export * from './static-website.js';
|
|
2052
|
+
export * from './app.js';
|
|
2053
|
+
export * from './runtime-config.js';
|
|
2054
|
+
"
|
|
2055
|
+
`;
|
|
2056
|
+
|
|
2057
|
+
exports[`react-website generator > Tanstack router integration > should generate website with router correctly > packages/common/constructs/src/core/runtime-config.ts 1`] = `
|
|
2058
|
+
"import type { IRuntimeConfig } from ':proj/common-types';
|
|
2059
|
+
import { Stack } from 'aws-cdk-lib';
|
|
2060
|
+
import { Construct } from 'constructs';
|
|
2061
|
+
|
|
2062
|
+
const RuntimeConfigKey = '__RuntimeConfig__';
|
|
2063
|
+
|
|
2064
|
+
export class RuntimeConfig extends Construct {
|
|
2065
|
+
private readonly _runtimeConfig: Partial<IRuntimeConfig> = {};
|
|
2066
|
+
|
|
2067
|
+
static ensure(scope: Construct): RuntimeConfig {
|
|
2068
|
+
const stack = Stack.of(scope);
|
|
2069
|
+
return (
|
|
2070
|
+
RuntimeConfig.of(scope) ?? new RuntimeConfig(stack, RuntimeConfigKey)
|
|
2071
|
+
);
|
|
2072
|
+
}
|
|
2073
|
+
|
|
2074
|
+
static of(scope: Construct): RuntimeConfig | undefined {
|
|
2075
|
+
const stack = Stack.of(scope);
|
|
2076
|
+
return stack.node.tryFindChild(RuntimeConfigKey) as
|
|
2077
|
+
| RuntimeConfig
|
|
2078
|
+
| undefined;
|
|
2079
|
+
}
|
|
2080
|
+
|
|
2081
|
+
constructor(scope: Construct, id: string) {
|
|
2082
|
+
super(scope, id);
|
|
2083
|
+
}
|
|
2084
|
+
|
|
2085
|
+
get config(): Partial<IRuntimeConfig> {
|
|
2086
|
+
return this._runtimeConfig;
|
|
2087
|
+
}
|
|
2088
|
+
}
|
|
2089
|
+
"
|
|
2090
|
+
`;
|
|
2091
|
+
|
|
2092
|
+
exports[`react-website generator > Tanstack router integration > should generate website with router correctly > packages/common/constructs/src/core/static-website.ts 1`] = `
|
|
2093
|
+
"import { CfnJson, CfnOutput, RemovalPolicy, Stack, Token } from 'aws-cdk-lib';
|
|
2094
|
+
import { Distribution, ViewerProtocolPolicy } from 'aws-cdk-lib/aws-cloudfront';
|
|
2095
|
+
import { S3BucketOrigin } from 'aws-cdk-lib/aws-cloudfront-origins';
|
|
2096
|
+
import {
|
|
2097
|
+
BlockPublicAccess,
|
|
2098
|
+
Bucket,
|
|
2099
|
+
BucketEncryption,
|
|
2100
|
+
IBucket,
|
|
2101
|
+
ObjectOwnership,
|
|
2102
|
+
} from 'aws-cdk-lib/aws-s3';
|
|
2103
|
+
import { BucketDeployment, Source } from 'aws-cdk-lib/aws-s3-deployment';
|
|
2104
|
+
import { Construct } from 'constructs';
|
|
2105
|
+
import { RuntimeConfig } from './runtime-config.js';
|
|
2106
|
+
import { Key } from 'aws-cdk-lib/aws-kms';
|
|
2107
|
+
import { CfnWebACL } from 'aws-cdk-lib/aws-wafv2';
|
|
2108
|
+
const DEFAULT_RUNTIME_CONFIG_FILENAME = 'runtime-config.json';
|
|
2109
|
+
|
|
2110
|
+
export interface StaticWebsiteProps {
|
|
2111
|
+
readonly websiteFilePath: string;
|
|
2112
|
+
}
|
|
2113
|
+
|
|
2114
|
+
/**
|
|
2115
|
+
* Deploys a Static Website using by default a private S3 bucket as an origin and Cloudfront as the entrypoint.
|
|
2116
|
+
*
|
|
2117
|
+
* This construct configures a webAcl containing rules that are generally applicable to web applications. This
|
|
2118
|
+
* provides protection against exploitation of a wide range of vulnerabilities, including some of the high risk
|
|
2119
|
+
* and commonly occurring vulnerabilities described in OWASP publications such as OWASP Top 10.
|
|
2120
|
+
*
|
|
2121
|
+
*/
|
|
2122
|
+
export class StaticWebsite extends Construct {
|
|
2123
|
+
public readonly websiteBucket: IBucket;
|
|
2124
|
+
public readonly cloudFrontDistribution: Distribution;
|
|
2125
|
+
public readonly bucketDeployment: BucketDeployment;
|
|
2126
|
+
|
|
2127
|
+
constructor(
|
|
2128
|
+
scope: Construct,
|
|
2129
|
+
id: string,
|
|
2130
|
+
{ websiteFilePath }: StaticWebsiteProps,
|
|
2131
|
+
) {
|
|
2132
|
+
super(scope, id);
|
|
2133
|
+
this.node.setContext(
|
|
2134
|
+
'@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy',
|
|
2135
|
+
true,
|
|
2136
|
+
);
|
|
2137
|
+
|
|
2138
|
+
const websiteKey = new Key(this, 'WebsiteKey', {
|
|
2139
|
+
enableKeyRotation: true,
|
|
2140
|
+
});
|
|
2141
|
+
|
|
2142
|
+
const accessLogsBucket = new Bucket(this, 'AccessLogsBucket', {
|
|
2143
|
+
versioned: false,
|
|
2144
|
+
enforceSSL: true,
|
|
2145
|
+
autoDeleteObjects: true,
|
|
2146
|
+
removalPolicy: RemovalPolicy.DESTROY,
|
|
2147
|
+
encryption: BucketEncryption.KMS,
|
|
2148
|
+
encryptionKey: websiteKey,
|
|
2149
|
+
objectOwnership: ObjectOwnership.OBJECT_WRITER,
|
|
2150
|
+
publicReadAccess: false,
|
|
2151
|
+
blockPublicAccess: BlockPublicAccess.BLOCK_ALL,
|
|
2152
|
+
});
|
|
2153
|
+
// S3 Bucket to hold website files
|
|
2154
|
+
this.websiteBucket = new Bucket(this, 'WebsiteBucket', {
|
|
2155
|
+
versioned: true,
|
|
2156
|
+
enforceSSL: true,
|
|
2157
|
+
autoDeleteObjects: true,
|
|
2158
|
+
removalPolicy: RemovalPolicy.DESTROY,
|
|
2159
|
+
encryption: BucketEncryption.KMS,
|
|
2160
|
+
encryptionKey: websiteKey,
|
|
2161
|
+
objectOwnership: ObjectOwnership.BUCKET_OWNER_ENFORCED,
|
|
2162
|
+
publicReadAccess: false,
|
|
2163
|
+
blockPublicAccess: BlockPublicAccess.BLOCK_ALL,
|
|
2164
|
+
serverAccessLogsPrefix: 'website-access-logs',
|
|
2165
|
+
serverAccessLogsBucket: accessLogsBucket,
|
|
2166
|
+
});
|
|
2167
|
+
// Web ACL
|
|
2168
|
+
const wafStack = new CloudfrontWebAcl(this, 'waf');
|
|
2169
|
+
|
|
2170
|
+
// Cloudfront Distribution
|
|
2171
|
+
const logBucket = new Bucket(this, 'DistributionLogBucket', {
|
|
2172
|
+
enforceSSL: true,
|
|
2173
|
+
autoDeleteObjects: true,
|
|
2174
|
+
removalPolicy: RemovalPolicy.DESTROY,
|
|
2175
|
+
encryption: BucketEncryption.KMS,
|
|
2176
|
+
encryptionKey: websiteKey,
|
|
2177
|
+
objectOwnership: ObjectOwnership.BUCKET_OWNER_PREFERRED,
|
|
2178
|
+
publicReadAccess: false,
|
|
2179
|
+
blockPublicAccess: BlockPublicAccess.BLOCK_ALL,
|
|
2180
|
+
serverAccessLogsPrefix: 'distribution-access-logs',
|
|
2181
|
+
serverAccessLogsBucket: accessLogsBucket,
|
|
2182
|
+
});
|
|
2183
|
+
const defaultRootObject = 'index.html';
|
|
2184
|
+
this.cloudFrontDistribution = new Distribution(
|
|
2185
|
+
this,
|
|
2186
|
+
'CloudfrontDistribution',
|
|
2187
|
+
{
|
|
2188
|
+
webAclId: wafStack.wafArn,
|
|
2189
|
+
enableLogging: true,
|
|
2190
|
+
logBucket: logBucket,
|
|
2191
|
+
defaultBehavior: {
|
|
2192
|
+
origin: S3BucketOrigin.withOriginAccessControl(this.websiteBucket),
|
|
2193
|
+
viewerProtocolPolicy: ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
|
|
2194
|
+
},
|
|
2195
|
+
defaultRootObject,
|
|
2196
|
+
errorResponses: [
|
|
2197
|
+
{
|
|
2198
|
+
httpStatus: 404, // We need to redirect "key not found errors" to index.html for single page apps
|
|
2199
|
+
responseHttpStatus: 200,
|
|
2200
|
+
responsePagePath: \`/\${defaultRootObject}\`,
|
|
2201
|
+
},
|
|
2202
|
+
{
|
|
2203
|
+
httpStatus: 403, // We need to redirect reloads from paths (e.g. /foo/bar) to index.html for single page apps
|
|
2204
|
+
responseHttpStatus: 200,
|
|
2205
|
+
responsePagePath: \`/\${defaultRootObject}\`,
|
|
2206
|
+
},
|
|
2207
|
+
],
|
|
2208
|
+
},
|
|
2209
|
+
);
|
|
2210
|
+
// Deploy Website
|
|
2211
|
+
this.bucketDeployment = new BucketDeployment(this, 'WebsiteDeployment', {
|
|
2212
|
+
sources: [
|
|
2213
|
+
Source.asset(websiteFilePath),
|
|
2214
|
+
Source.jsonData(
|
|
2215
|
+
DEFAULT_RUNTIME_CONFIG_FILENAME,
|
|
2216
|
+
this.resolveTokens(RuntimeConfig.ensure(this).config),
|
|
2217
|
+
),
|
|
2218
|
+
],
|
|
2219
|
+
destinationBucket: this.websiteBucket,
|
|
2220
|
+
// Files in the distribution's edge caches will be invalidated after files are uploaded to the destination bucket.
|
|
2221
|
+
distribution: this.cloudFrontDistribution,
|
|
2222
|
+
memoryLimit: 1024,
|
|
2223
|
+
});
|
|
2224
|
+
new CfnOutput(this, 'DistributionDomainName', {
|
|
2225
|
+
value: this.cloudFrontDistribution.domainName,
|
|
2226
|
+
});
|
|
2227
|
+
new CfnOutput(this, 'WebsiteBucketName', {
|
|
2228
|
+
value: this.websiteBucket.bucketName,
|
|
2229
|
+
});
|
|
2230
|
+
}
|
|
2231
|
+
private resolveTokens = (payload: any) => {
|
|
2232
|
+
const _payload: Record<string, any> = {};
|
|
2233
|
+
Object.entries(payload).forEach(([key, value]) => {
|
|
2234
|
+
if (
|
|
2235
|
+
Token.isUnresolved(value) ||
|
|
2236
|
+
(typeof value === 'string' && value.endsWith('}}'))
|
|
2237
|
+
) {
|
|
2238
|
+
_payload[key] = new CfnJson(this, \`ResolveToken-\${key}\`, {
|
|
2239
|
+
value,
|
|
2240
|
+
}).value;
|
|
2241
|
+
} else if (typeof value === 'object') {
|
|
2242
|
+
_payload[key] = this.resolveTokens(value);
|
|
2243
|
+
} else if (Array.isArray(value)) {
|
|
2244
|
+
_payload[key] = value.map((v) => this.resolveTokens(v));
|
|
2245
|
+
} else {
|
|
2246
|
+
_payload[key] = value;
|
|
2247
|
+
}
|
|
2248
|
+
});
|
|
2249
|
+
return _payload;
|
|
2250
|
+
};
|
|
2251
|
+
}
|
|
2252
|
+
|
|
2253
|
+
export class CloudfrontWebAcl extends Stack {
|
|
2254
|
+
public readonly wafArn;
|
|
2255
|
+
constructor(scope: Construct, id: string) {
|
|
2256
|
+
super(scope, id, {
|
|
2257
|
+
env: {
|
|
2258
|
+
region: 'us-east-1',
|
|
2259
|
+
account: Stack.of(scope).account,
|
|
2260
|
+
},
|
|
2261
|
+
crossRegionReferences: true,
|
|
2262
|
+
});
|
|
2263
|
+
|
|
2264
|
+
this.wafArn = new CfnWebACL(this, 'WebAcl', {
|
|
2265
|
+
defaultAction: { allow: {} },
|
|
2266
|
+
scope: 'CLOUDFRONT',
|
|
2267
|
+
visibilityConfig: {
|
|
2268
|
+
cloudWatchMetricsEnabled: true,
|
|
2269
|
+
metricName: id,
|
|
2270
|
+
sampledRequestsEnabled: true,
|
|
2271
|
+
},
|
|
2272
|
+
rules: [
|
|
2273
|
+
{
|
|
2274
|
+
name: 'CRSRule',
|
|
2275
|
+
priority: 0,
|
|
2276
|
+
statement: {
|
|
2277
|
+
managedRuleGroupStatement: {
|
|
2278
|
+
name: 'AWSManagedRulesCommonRuleSet',
|
|
2279
|
+
vendorName: 'AWS',
|
|
2280
|
+
},
|
|
2281
|
+
},
|
|
2282
|
+
visibilityConfig: {
|
|
2283
|
+
cloudWatchMetricsEnabled: true,
|
|
2284
|
+
metricName: 'MetricForWebACLCDK-CRS',
|
|
2285
|
+
sampledRequestsEnabled: true,
|
|
2286
|
+
},
|
|
2287
|
+
overrideAction: {
|
|
2288
|
+
none: {},
|
|
2289
|
+
},
|
|
2290
|
+
},
|
|
2291
|
+
],
|
|
2292
|
+
}).attrArn;
|
|
2293
|
+
}
|
|
2294
|
+
}
|
|
2295
|
+
"
|
|
2296
|
+
`;
|
|
2297
|
+
|
|
2298
|
+
exports[`react-website generator > Tanstack router integration > should generate website with router correctly > packages/common/constructs/src/index.ts 1`] = `
|
|
2299
|
+
"export * from './app/index.js';
|
|
2300
|
+
export * from './core/index.js';
|
|
2301
|
+
"
|
|
2302
|
+
`;
|
|
2303
|
+
|
|
2304
|
+
exports[`react-website generator > Tanstack router integration > should generate website with router correctly > packages/common/constructs/tsconfig.json 1`] = `
|
|
2305
|
+
"{
|
|
2306
|
+
"extends": "../../../tsconfig.base.json",
|
|
2307
|
+
"files": [],
|
|
2308
|
+
"include": [],
|
|
2309
|
+
"references": [
|
|
2310
|
+
{
|
|
2311
|
+
"path": "./tsconfig.lib.json"
|
|
2312
|
+
},
|
|
2313
|
+
{
|
|
2314
|
+
"path": "./tsconfig.spec.json"
|
|
2315
|
+
}
|
|
2316
|
+
],
|
|
2317
|
+
"compilerOptions": {}
|
|
2318
|
+
}
|
|
2319
|
+
"
|
|
2320
|
+
`;
|
|
2321
|
+
|
|
2322
|
+
exports[`react-website generator > Tanstack router integration > should generate website with router correctly > packages/common/constructs/tsconfig.lib.json 1`] = `
|
|
2323
|
+
"{
|
|
2324
|
+
"extends": "../../../tsconfig.base.json",
|
|
2325
|
+
"compilerOptions": {
|
|
2326
|
+
"rootDir": ".",
|
|
2327
|
+
"outDir": "../../../dist/packages/common/constructs/tsc",
|
|
2328
|
+
"tsBuildInfoFile": "../../../dist/packages/common/constructs/tsc/tsconfig.lib.tsbuildinfo",
|
|
2329
|
+
"emitDeclarationOnly": false,
|
|
2330
|
+
"module": "nodenext",
|
|
2331
|
+
"moduleResolution": "nodenext",
|
|
2332
|
+
"types": ["node"]
|
|
2333
|
+
},
|
|
2334
|
+
"include": ["src/**/*.ts"],
|
|
2335
|
+
"references": [],
|
|
2336
|
+
"exclude": [
|
|
2337
|
+
"vite.config.ts",
|
|
2338
|
+
"vite.config.mts",
|
|
2339
|
+
"vitest.config.ts",
|
|
2340
|
+
"vitest.config.mts",
|
|
2341
|
+
"src/**/*.test.ts",
|
|
2342
|
+
"src/**/*.spec.ts",
|
|
2343
|
+
"src/**/*.test.tsx",
|
|
2344
|
+
"src/**/*.spec.tsx",
|
|
2345
|
+
"src/**/*.test.js",
|
|
2346
|
+
"src/**/*.spec.js",
|
|
2347
|
+
"src/**/*.test.jsx",
|
|
2348
|
+
"src/**/*.spec.jsx"
|
|
2349
|
+
]
|
|
2350
|
+
}
|
|
2351
|
+
"
|
|
2352
|
+
`;
|
|
2353
|
+
|
|
2354
|
+
exports[`react-website generator > Tanstack router integration > should generate website with router correctly > packages/common/constructs/tsconfig.spec.json 1`] = `
|
|
2355
|
+
"{
|
|
2356
|
+
"extends": "../../../tsconfig.base.json",
|
|
2357
|
+
"compilerOptions": {
|
|
2358
|
+
"outDir": "./out-tsc/vitest",
|
|
2359
|
+
"types": [
|
|
2360
|
+
"vitest/globals",
|
|
2361
|
+
"vitest/importMeta",
|
|
2362
|
+
"vite/client",
|
|
2363
|
+
"node",
|
|
2364
|
+
"vitest"
|
|
2365
|
+
],
|
|
2366
|
+
"module": "nodenext",
|
|
2367
|
+
"moduleResolution": "nodenext"
|
|
2368
|
+
},
|
|
2369
|
+
"include": [
|
|
2370
|
+
"vite.config.ts",
|
|
2371
|
+
"vite.config.mts",
|
|
2372
|
+
"vitest.config.ts",
|
|
2373
|
+
"vitest.config.mts",
|
|
2374
|
+
"src/**/*.test.ts",
|
|
2375
|
+
"src/**/*.spec.ts",
|
|
2376
|
+
"src/**/*.test.tsx",
|
|
2377
|
+
"src/**/*.spec.tsx",
|
|
2378
|
+
"src/**/*.test.js",
|
|
2379
|
+
"src/**/*.spec.js",
|
|
2380
|
+
"src/**/*.test.jsx",
|
|
2381
|
+
"src/**/*.spec.jsx",
|
|
2382
|
+
"src/**/*.d.ts"
|
|
2383
|
+
],
|
|
2384
|
+
"references": [
|
|
2385
|
+
{
|
|
2386
|
+
"path": "./tsconfig.lib.json"
|
|
2387
|
+
}
|
|
2388
|
+
]
|
|
2389
|
+
}
|
|
2390
|
+
"
|
|
2391
|
+
`;
|
|
2392
|
+
|
|
2393
|
+
exports[`react-website generator > Tanstack router integration > should generate website with router correctly > packages/common/constructs/vite.config.ts 1`] = `
|
|
2394
|
+
"import { defineConfig } from 'vite';
|
|
2395
|
+
|
|
2396
|
+
export default defineConfig(() => ({
|
|
2397
|
+
root: __dirname,
|
|
2398
|
+
cacheDir: '../../../node_modules/.vite/packages/common/constructs',
|
|
2399
|
+
plugins: [],
|
|
2400
|
+
// Uncomment this if you are using workers.
|
|
2401
|
+
// worker: {
|
|
2402
|
+
// plugins: [ nxViteTsPaths() ],
|
|
2403
|
+
// },
|
|
2404
|
+
test: {
|
|
2405
|
+
watch: false,
|
|
2406
|
+
globals: true,
|
|
2407
|
+
environment: 'jsdom',
|
|
2408
|
+
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
|
2409
|
+
reporters: ['default'],
|
|
2410
|
+
coverage: {
|
|
2411
|
+
reportsDirectory: './test-output/vitest/coverage',
|
|
2412
|
+
provider: 'v8' as const,
|
|
2413
|
+
},
|
|
2414
|
+
passWithNoTests: true,
|
|
2415
|
+
},
|
|
2416
|
+
}));
|
|
2417
|
+
"
|
|
2418
|
+
`;
|
|
2419
|
+
|
|
2420
|
+
exports[`react-website generator > Tanstack router integration > should generate website with router correctly > packages/common/types/README.md 1`] = `
|
|
2421
|
+
"# @proj/common-types
|
|
2422
|
+
|
|
2423
|
+
This library was generated with [@aws/nx-plugin](https://github.com/awslabs/nx-plugin-for-aws/).
|
|
2424
|
+
|
|
2425
|
+
## Building
|
|
2426
|
+
|
|
2427
|
+
Run \`npx nx build @proj/common-types [--skip-nx-cache]\` to build the application.
|
|
2428
|
+
|
|
2429
|
+
## Running unit tests
|
|
2430
|
+
|
|
2431
|
+
Run \`npx nx test @proj/common-types\` to execute the unit tests via Vitest.
|
|
2432
|
+
|
|
2433
|
+
### Updating snapshots
|
|
2434
|
+
|
|
2435
|
+
To update snapshots, run the following command:
|
|
2436
|
+
|
|
2437
|
+
\`npx nx test @proj/common-types --configuration=update-snapshot\`
|
|
2438
|
+
|
|
2439
|
+
## Run lint
|
|
2440
|
+
|
|
2441
|
+
Run \`npx nx lint @proj/common-types\`
|
|
2442
|
+
|
|
2443
|
+
### Fixable issues
|
|
2444
|
+
|
|
2445
|
+
You can also automatiaclly fix some lint errors by running the following command:
|
|
2446
|
+
|
|
2447
|
+
\`npx nx lint @proj/common-types --configuration=fix\`
|
|
2448
|
+
|
|
2449
|
+
## Useful links
|
|
2450
|
+
|
|
2451
|
+
- [common-types reference docs](TODO)
|
|
2452
|
+
- [Learn more about NX](https://nx.dev/getting-started/intro)
|
|
2453
|
+
"
|
|
2454
|
+
`;
|
|
2455
|
+
|
|
2456
|
+
exports[`react-website generator > Tanstack router integration > should generate website with router correctly > packages/common/types/eslint.config.mjs 1`] = `
|
|
2457
|
+
"import baseConfig from '../../../eslint.config.mjs';
|
|
2458
|
+
|
|
2459
|
+
export default [
|
|
2460
|
+
...baseConfig,
|
|
2461
|
+
{
|
|
2462
|
+
files: ['**/*.json'],
|
|
2463
|
+
rules: {
|
|
2464
|
+
'@nx/dependency-checks': [
|
|
2465
|
+
'warn',
|
|
2466
|
+
{
|
|
2467
|
+
ignoredFiles: [
|
|
2468
|
+
'{projectRoot}/eslint.config.{js,cjs,mjs}',
|
|
2469
|
+
'{projectRoot}/vite.config.{js,ts,mjs,mts}',
|
|
2470
|
+
],
|
|
2471
|
+
},
|
|
2472
|
+
],
|
|
2473
|
+
},
|
|
2474
|
+
languageOptions: {
|
|
2475
|
+
parser: await import('jsonc-eslint-parser'),
|
|
2476
|
+
},
|
|
2477
|
+
},
|
|
2478
|
+
];
|
|
2479
|
+
"
|
|
2480
|
+
`;
|
|
2481
|
+
|
|
2482
|
+
exports[`react-website generator > Tanstack router integration > should generate website with router correctly > packages/common/types/project.json 1`] = `
|
|
2483
|
+
"{
|
|
2484
|
+
"name": "@proj/common-types",
|
|
2485
|
+
"$schema": "../../../node_modules/nx/schemas/project-schema.json",
|
|
2486
|
+
"sourceRoot": "packages/common/types/src",
|
|
2487
|
+
"projectType": "library",
|
|
2488
|
+
"tags": [],
|
|
2489
|
+
"targets": {
|
|
2490
|
+
"build": {
|
|
2491
|
+
"dependsOn": ["lint", "compile", "test"]
|
|
2492
|
+
},
|
|
2493
|
+
"compile": {
|
|
2494
|
+
"executor": "nx:run-commands",
|
|
2495
|
+
"outputs": ["{workspaceRoot}/dist/packages/common/types/tsc"],
|
|
2496
|
+
"options": {
|
|
2497
|
+
"command": "tsc --build tsconfig.lib.json",
|
|
2498
|
+
"cwd": "{projectRoot}"
|
|
2499
|
+
}
|
|
2500
|
+
},
|
|
2501
|
+
"test": {
|
|
2502
|
+
"executor": "@nx/vite:test",
|
|
2503
|
+
"outputs": ["{options.reportsDirectory}"],
|
|
2504
|
+
"options": {
|
|
2505
|
+
"reportsDirectory": "../../../coverage/packages/common/types"
|
|
2506
|
+
}
|
|
2507
|
+
}
|
|
2508
|
+
},
|
|
2509
|
+
"metadata": {
|
|
2510
|
+
"generator": "ts#project"
|
|
2511
|
+
}
|
|
2512
|
+
}
|
|
2513
|
+
"
|
|
2514
|
+
`;
|
|
2515
|
+
|
|
2516
|
+
exports[`react-website generator > Tanstack router integration > should generate website with router correctly > packages/common/types/src/index.ts 1`] = `
|
|
2517
|
+
"export * from './runtime-config.js';
|
|
2518
|
+
"
|
|
2519
|
+
`;
|
|
2520
|
+
|
|
2521
|
+
exports[`react-website generator > Tanstack router integration > should generate website with router correctly > packages/common/types/src/runtime-config.ts 1`] = `
|
|
2522
|
+
"// eslint-disable-next-line @typescript-eslint/no-empty-object-type, @typescript-eslint/no-empty-interface
|
|
2523
|
+
export interface IRuntimeConfig {}
|
|
2524
|
+
"
|
|
2525
|
+
`;
|
|
2526
|
+
|
|
2527
|
+
exports[`react-website generator > Tanstack router integration > should generate website with router correctly > packages/common/types/tsconfig.json 1`] = `
|
|
2528
|
+
"{
|
|
2529
|
+
"extends": "../../../tsconfig.base.json",
|
|
2530
|
+
"files": [],
|
|
2531
|
+
"include": [],
|
|
2532
|
+
"references": [
|
|
2533
|
+
{
|
|
2534
|
+
"path": "./tsconfig.lib.json"
|
|
2535
|
+
},
|
|
2536
|
+
{
|
|
2537
|
+
"path": "./tsconfig.spec.json"
|
|
2538
|
+
}
|
|
2539
|
+
],
|
|
2540
|
+
"compilerOptions": {}
|
|
2541
|
+
}
|
|
2542
|
+
"
|
|
2543
|
+
`;
|
|
2544
|
+
|
|
2545
|
+
exports[`react-website generator > Tanstack router integration > should generate website with router correctly > packages/common/types/tsconfig.lib.json 1`] = `
|
|
2546
|
+
"{
|
|
2547
|
+
"extends": "../../../tsconfig.base.json",
|
|
2548
|
+
"compilerOptions": {
|
|
2549
|
+
"rootDir": ".",
|
|
2550
|
+
"outDir": "../../../dist/packages/common/types/tsc",
|
|
2551
|
+
"tsBuildInfoFile": "../../../dist/packages/common/types/tsc/tsconfig.lib.tsbuildinfo",
|
|
2552
|
+
"emitDeclarationOnly": false,
|
|
2553
|
+
"module": "nodenext",
|
|
2554
|
+
"moduleResolution": "nodenext",
|
|
2555
|
+
"types": ["node"]
|
|
2556
|
+
},
|
|
2557
|
+
"include": ["src/**/*.ts"],
|
|
2558
|
+
"references": [],
|
|
2559
|
+
"exclude": [
|
|
2560
|
+
"vite.config.ts",
|
|
2561
|
+
"vite.config.mts",
|
|
2562
|
+
"vitest.config.ts",
|
|
2563
|
+
"vitest.config.mts",
|
|
2564
|
+
"src/**/*.test.ts",
|
|
2565
|
+
"src/**/*.spec.ts",
|
|
2566
|
+
"src/**/*.test.tsx",
|
|
2567
|
+
"src/**/*.spec.tsx",
|
|
2568
|
+
"src/**/*.test.js",
|
|
2569
|
+
"src/**/*.spec.js",
|
|
2570
|
+
"src/**/*.test.jsx",
|
|
2571
|
+
"src/**/*.spec.jsx"
|
|
2572
|
+
]
|
|
2573
|
+
}
|
|
2574
|
+
"
|
|
2575
|
+
`;
|
|
2576
|
+
|
|
2577
|
+
exports[`react-website generator > Tanstack router integration > should generate website with router correctly > packages/common/types/tsconfig.spec.json 1`] = `
|
|
2578
|
+
"{
|
|
2579
|
+
"extends": "../../../tsconfig.base.json",
|
|
2580
|
+
"compilerOptions": {
|
|
2581
|
+
"outDir": "./out-tsc/vitest",
|
|
2582
|
+
"types": [
|
|
2583
|
+
"vitest/globals",
|
|
2584
|
+
"vitest/importMeta",
|
|
2585
|
+
"vite/client",
|
|
2586
|
+
"node",
|
|
2587
|
+
"vitest"
|
|
2588
|
+
],
|
|
2589
|
+
"module": "nodenext",
|
|
2590
|
+
"moduleResolution": "nodenext"
|
|
2591
|
+
},
|
|
2592
|
+
"include": [
|
|
2593
|
+
"vite.config.ts",
|
|
2594
|
+
"vite.config.mts",
|
|
2595
|
+
"vitest.config.ts",
|
|
2596
|
+
"vitest.config.mts",
|
|
2597
|
+
"src/**/*.test.ts",
|
|
2598
|
+
"src/**/*.spec.ts",
|
|
2599
|
+
"src/**/*.test.tsx",
|
|
2600
|
+
"src/**/*.spec.tsx",
|
|
2601
|
+
"src/**/*.test.js",
|
|
2602
|
+
"src/**/*.spec.js",
|
|
2603
|
+
"src/**/*.test.jsx",
|
|
2604
|
+
"src/**/*.spec.jsx",
|
|
2605
|
+
"src/**/*.d.ts"
|
|
2606
|
+
],
|
|
2607
|
+
"references": [
|
|
2608
|
+
{
|
|
2609
|
+
"path": "./tsconfig.lib.json"
|
|
2610
|
+
}
|
|
2611
|
+
]
|
|
2612
|
+
}
|
|
2613
|
+
"
|
|
2614
|
+
`;
|
|
2615
|
+
|
|
2616
|
+
exports[`react-website generator > Tanstack router integration > should generate website with router correctly > packages/common/types/vite.config.ts 1`] = `
|
|
2617
|
+
"import { defineConfig } from 'vite';
|
|
2618
|
+
|
|
2619
|
+
export default defineConfig(() => ({
|
|
2620
|
+
root: __dirname,
|
|
2621
|
+
cacheDir: '../../../node_modules/.vite/packages/common/types',
|
|
2622
|
+
plugins: [],
|
|
2623
|
+
// Uncomment this if you are using workers.
|
|
2624
|
+
// worker: {
|
|
2625
|
+
// plugins: [ nxViteTsPaths() ],
|
|
2626
|
+
// },
|
|
2627
|
+
test: {
|
|
2628
|
+
watch: false,
|
|
2629
|
+
globals: true,
|
|
2630
|
+
environment: 'jsdom',
|
|
2631
|
+
include: ['src/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
|
2632
|
+
reporters: ['default'],
|
|
2633
|
+
coverage: {
|
|
2634
|
+
reportsDirectory: './test-output/vitest/coverage',
|
|
2635
|
+
provider: 'v8' as const,
|
|
2636
|
+
},
|
|
2637
|
+
passWithNoTests: true,
|
|
2638
|
+
},
|
|
2639
|
+
}));
|
|
2640
|
+
"
|
|
2641
|
+
`;
|
|
2642
|
+
|
|
2643
|
+
exports[`react-website generator > Tanstack router integration > should generate website with router correctly > pnpm-workspace.yaml 1`] = `
|
|
2644
|
+
"packages:
|
|
2645
|
+
- 'packages/*'
|
|
2646
|
+
- 'test-app'
|
|
2647
|
+
- 'packages/common/*'
|
|
2648
|
+
- 'packages/common/constructs'
|
|
2649
|
+
"
|
|
2650
|
+
`;
|
|
2651
|
+
|
|
2652
|
+
exports[`react-website generator > Tanstack router integration > should generate website with router correctly > test-app/README.md 1`] = `
|
|
2653
|
+
"# @proj/test-app
|
|
2654
|
+
|
|
2655
|
+
This library was generated with [@aws/nx-plugin](https://github.com/awslabs/nx-plugin-for-aws/).
|
|
2656
|
+
|
|
2657
|
+
## Building
|
|
2658
|
+
|
|
2659
|
+
Run \`npx nx build @proj/test-app [--skip-nx-cache]\` to build the application.
|
|
2660
|
+
|
|
2661
|
+
## Run dev server
|
|
2662
|
+
|
|
2663
|
+
Run \`npx nx serve @proj/test-app\`
|
|
2664
|
+
|
|
2665
|
+
## Running unit tests
|
|
2666
|
+
|
|
2667
|
+
Run \`npx nx test @proj/test-app\` to execute the unit tests via Vitest.
|
|
2668
|
+
|
|
2669
|
+
### Updating snapshots
|
|
2670
|
+
|
|
2671
|
+
To update snapshots, run the following command:
|
|
2672
|
+
|
|
2673
|
+
\`npx nx test @proj/test-app --configuration=update-snapshot\`
|
|
2674
|
+
|
|
2675
|
+
## Run lint
|
|
2676
|
+
|
|
2677
|
+
Run \`npx nx lint @proj/test-app\`
|
|
2678
|
+
|
|
2679
|
+
### Fixable issues
|
|
2680
|
+
|
|
2681
|
+
You can also automatically fix some lint errors by running the following command:
|
|
2682
|
+
|
|
2683
|
+
\`npx nx lint @proj/test-app --configuration=fix\`
|
|
2684
|
+
|
|
2685
|
+
### Runtime config
|
|
2686
|
+
|
|
2687
|
+
In order to integrate with cognito or trpc backends, you need to have a \`runtime-config.json\` file in your \`/public\` website directory. You can fetch this is follows:
|
|
2688
|
+
|
|
2689
|
+
\`npx nx run @proj/test-app:load:runtime-config\`
|
|
2690
|
+
|
|
2691
|
+
> [!IMPORTANT]
|
|
2692
|
+
> Ensure you have AWS CLI and curl installed
|
|
2693
|
+
> You have deployed your CDK infrastructure into the appropriate account
|
|
2694
|
+
> You have assumed a role in the AWS account with sufficient permissions to call describe-stacks from cloudformation
|
|
2695
|
+
|
|
2696
|
+
## Useful links
|
|
2697
|
+
|
|
2698
|
+
- [React website reference docs](TODO)
|
|
2699
|
+
- [Learn more about NX](https://nx.dev/getting-started/intro)
|
|
2700
|
+
"
|
|
2701
|
+
`;
|
|
2702
|
+
|
|
2703
|
+
exports[`react-website generator > Tanstack router integration > should generate website with router correctly > test-app/eslint.config.mjs 1`] = `
|
|
2704
|
+
"import nx from '@nx/eslint-plugin';
|
|
2705
|
+
import baseConfig from '../eslint.config.mjs';
|
|
2706
|
+
|
|
2707
|
+
export default [
|
|
2708
|
+
...baseConfig,
|
|
2709
|
+
...nx.configs['flat/react'],
|
|
2710
|
+
{
|
|
2711
|
+
files: ['**/*.ts', '**/*.tsx', '**/*.js', '**/*.jsx'],
|
|
2712
|
+
// Override or add rules here
|
|
2713
|
+
rules: {},
|
|
2714
|
+
},
|
|
2715
|
+
];
|
|
2716
|
+
"
|
|
2717
|
+
`;
|
|
2718
|
+
|
|
2719
|
+
exports[`react-website generator > Tanstack router integration > should generate website with router correctly > test-app/index.html 1`] = `
|
|
2720
|
+
"<!doctype html>
|
|
2721
|
+
<html lang="en">
|
|
2722
|
+
<head>
|
|
2723
|
+
<meta charset="utf-8" />
|
|
2724
|
+
<title>TestApp</title>
|
|
2725
|
+
<base href="/" />
|
|
2726
|
+
|
|
2727
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
2728
|
+
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
|
|
2729
|
+
<link rel="stylesheet" href="/src/styles.css" />
|
|
2730
|
+
</head>
|
|
2731
|
+
<body>
|
|
2732
|
+
<div id="root"></div>
|
|
2733
|
+
<script type="module" src="/src/main.tsx"></script>
|
|
2734
|
+
</body>
|
|
2735
|
+
</html>
|
|
2736
|
+
"
|
|
2737
|
+
`;
|
|
2738
|
+
|
|
2739
|
+
exports[`react-website generator > Tanstack router integration > should generate website with router correctly > test-app/project.json 1`] = `
|
|
2740
|
+
"{
|
|
2741
|
+
"name": "@proj/test-app",
|
|
2742
|
+
"$schema": "../node_modules/nx/schemas/project-schema.json",
|
|
2743
|
+
"sourceRoot": "test-app/src",
|
|
2744
|
+
"projectType": "application",
|
|
2745
|
+
"tags": [],
|
|
2746
|
+
"targets": {
|
|
2747
|
+
"build": {
|
|
2748
|
+
"dependsOn": ["lint", "compile", "bundle", "test"],
|
|
2749
|
+
"options": {
|
|
2750
|
+
"outputPath": "dist/test-app/bundle"
|
|
2751
|
+
}
|
|
2752
|
+
},
|
|
2753
|
+
"bundle": {
|
|
2754
|
+
"executor": "@nx/vite:build",
|
|
2755
|
+
"outputs": ["{options.outputPath}"],
|
|
2756
|
+
"defaultConfiguration": "production",
|
|
2757
|
+
"options": {
|
|
2758
|
+
"outputPath": "dist/test-app/bundle"
|
|
2759
|
+
},
|
|
2760
|
+
"configurations": {
|
|
2761
|
+
"development": {
|
|
2762
|
+
"mode": "development"
|
|
2763
|
+
},
|
|
2764
|
+
"production": {
|
|
2765
|
+
"mode": "production"
|
|
2766
|
+
}
|
|
2767
|
+
}
|
|
2768
|
+
},
|
|
2769
|
+
"compile": {
|
|
2770
|
+
"executor": "nx:run-commands",
|
|
2771
|
+
"outputs": ["{workspaceRoot}/dist/{projectRoot}/tsc"],
|
|
2772
|
+
"options": {
|
|
2773
|
+
"command": "tsc --build tsconfig.app.json",
|
|
2774
|
+
"cwd": "{projectRoot}"
|
|
2775
|
+
}
|
|
2776
|
+
},
|
|
2777
|
+
"lint": {
|
|
2778
|
+
"executor": "@nx/eslint:lint"
|
|
2779
|
+
},
|
|
2780
|
+
"load:runtime-config": {
|
|
2781
|
+
"executor": "nx:run-commands",
|
|
2782
|
+
"metadata": {
|
|
2783
|
+
"description": "Load runtime config from your deployed stack for dev purposes. You must set your AWS CLI credentials whilst calling 'pnpm exec nx run @proj/test-app:load:runtime-config'"
|
|
2784
|
+
},
|
|
2785
|
+
"options": {
|
|
2786
|
+
"command": "aws s3 cp s3://\`aws cloudformation describe-stacks --query \\"Stacks[?StackName=='proj-infra-sandbox'][].Outputs[?contains(OutputKey, 'WebsiteBucketName')].OutputValue\\" --output text\`/runtime-config.json './test-app/public/runtime-config.json'"
|
|
2787
|
+
}
|
|
2788
|
+
},
|
|
2789
|
+
"preview": {
|
|
2790
|
+
"dependsOn": ["build"],
|
|
2791
|
+
"executor": "@nx/vite:preview-server",
|
|
2792
|
+
"defaultConfiguration": "development",
|
|
2793
|
+
"options": {
|
|
2794
|
+
"buildTarget": "@proj/test-app:build"
|
|
2795
|
+
},
|
|
2796
|
+
"configurations": {
|
|
2797
|
+
"development": {
|
|
2798
|
+
"buildTarget": "@proj/test-app:build:development"
|
|
2799
|
+
},
|
|
2800
|
+
"production": {
|
|
2801
|
+
"buildTarget": "@proj/test-app:build:production"
|
|
2802
|
+
}
|
|
2803
|
+
}
|
|
2804
|
+
},
|
|
2805
|
+
"serve": {
|
|
2806
|
+
"executor": "@nx/vite:dev-server",
|
|
2807
|
+
"defaultConfiguration": "development",
|
|
2808
|
+
"options": {
|
|
2809
|
+
"buildTarget": "@proj/test-app:build"
|
|
2810
|
+
},
|
|
2811
|
+
"configurations": {
|
|
2812
|
+
"development": {
|
|
2813
|
+
"buildTarget": "@proj/test-app:build:development",
|
|
2814
|
+
"hmr": true
|
|
2815
|
+
},
|
|
2816
|
+
"production": {
|
|
2817
|
+
"buildTarget": "@proj/test-app:build:production",
|
|
2818
|
+
"hmr": false
|
|
2819
|
+
}
|
|
2820
|
+
}
|
|
2821
|
+
},
|
|
2822
|
+
"serve-local": {
|
|
2823
|
+
"executor": "@nx/vite:dev-server",
|
|
2824
|
+
"options": {
|
|
2825
|
+
"buildTarget": "@proj/test-app:build:development",
|
|
2826
|
+
"hmr": true,
|
|
2827
|
+
"mode": "serve-local"
|
|
2828
|
+
},
|
|
2829
|
+
"continuous": true
|
|
2830
|
+
},
|
|
2831
|
+
"serve-static": {
|
|
2832
|
+
"executor": "@nx/web:file-server",
|
|
2833
|
+
"dependsOn": ["build"],
|
|
2834
|
+
"options": {
|
|
2835
|
+
"buildTarget": "@proj/test-app:build",
|
|
2836
|
+
"spa": true
|
|
2837
|
+
}
|
|
2838
|
+
},
|
|
2839
|
+
"test": {
|
|
2840
|
+
"executor": "@nx/vite:test",
|
|
2841
|
+
"outputs": ["{options.reportsDirectory}"],
|
|
2842
|
+
"options": {
|
|
2843
|
+
"reportsDirectory": "../coverage/test-app"
|
|
2844
|
+
}
|
|
2845
|
+
}
|
|
2846
|
+
},
|
|
2847
|
+
"metadata": {
|
|
2848
|
+
"generator": "ts#react-website"
|
|
2849
|
+
}
|
|
2850
|
+
}
|
|
2851
|
+
"
|
|
2852
|
+
`;
|
|
2853
|
+
|
|
2854
|
+
exports[`react-website generator > Tanstack router integration > should generate website with router correctly > test-app/public/favicon.ico 1`] = `
|
|
2855
|
+
"00 �%6 ��% h�6(0\` $V/V/cV/�V/�V/�V/�V/�W0�Y1'B#pH[�f��i��i��i��i��i��ia�j�c�^R�\\��Y��U��R�|N�xKuI&V/
|
|
2856
|
+
V/�V/�V/�V/�V/�V/�X1�Y2Ld=9_;�X��l��k��k��k��k��k�kH�c8�a�]��Z��W��S�}P�zM�vIV/
|
|
2857
|
+
V/�V/�V/�V/�V/�W0�Y1�Z3LoDjA�\`;�_=��c��l��k��k��k��k��kÞk�j�f��c��\`��]��Y��V��R�}OCV/
|
|
2858
|
+
V/�V/�V/�V/�V/�W0�Z2�[3LoD[nD�iA�X7�oI��j��k��k��k��k��k��k��m�ks�i��f��b��_��[��W��T�yLV/
|
|
2859
|
+
V/�V/�V/�V/�V/�X1�Z3�\\4MnDoE�qF�oE�f@�X8��Z��l��k��k��k��k��k�ks�k��k��h��d��a��]��Y˅WV/
|
|
2860
|
+
V/�V/�V/�V/�V/�Y1�[3�\\4Ph=nD�pE�rG�sH�oF�a=�cA��f��k��k��k��k��k��k��k��k��j��f��b��_�\\SV/
|
|
2861
|
+
V/�V/�V/�V/�W0�Y2�[4�]5QmC6oD�qF�sH�uJ�uJ�nF�];�wO��k��k��k��k��k��k��k��k��k��h��d��\`��\\V/
|
|
2862
|
+
V/V/
|
|
2863
|
+
V/�V/�V/�V/�W0�Y2�\\4�]5QkA
|
|
2864
|
+
mC�oD�qF�tH�vJ�xL�vK�kD�^=��_��l��k��k��k��k��k��k��k��i��eؔb(V/ V/�V/eV/
|
|
2865
|
+
V/�V/�V/�V/�W0�Z2�\\4�^6QlAXmC�oE�rG�tI�wK�yM�zN�uK�eA�jF��h��k��k��k��k��k��k��k��j��geW0V/RV/�V/
|
|
2866
|
+
V/�V/�V/�V/�W0�Z2�\\4�^6Qj@kA�mC�pE�rG�uI�wK�yM�|O�{O�rJ�^=�|S��k��k��k��k��k��k��k��j��h�Z]5iY1�V/GV/
|
|
2867
|
+
V/�V/�V/�V/�X0�Z2�\\5�^6Qi?kA�mC�pE�rG�uI�wK�zM�|O�}P�xN�eB�W:��c��k��k��k��k��k��o���$W��H��H��KHɦ9�f>�X1�V/�V/
|
|
2868
|
+
V/�V/�V/�V/�X0�Z2�\\4�^6Qg>4i?�kA�mC�pE�rG�uI�wK�zM�|O�|P�vM�b@�bA��g��k��k��k��k��k��s �ӵ]������H-��H���J���G���*�\`8�Y1�V/�V/
|
|
2869
|
+
V/�V/�V/�V/�W0�Z2�\\4�^6Qd; f=�h?�kA�mC�pE�rG�tI�wK�yM�{O�yN�mF�^>��]��l��k��k��k��k��k��l�ͫH��ڔ��ٛ�ؖ�ؖ�ؖ.�ؘr�֏���O�߾D���/��h�i@�]5�Y1�V/�V/
|
|
2870
|
+
V/�V/�V/�V/�W0�Z2�\\4�^5Qd;Uf<�h>�j@�mC�oE�rG�tH�wK�yL�xM�qI�_=�vO��k��k��k��k��k��k��k��j������i��א��ؗ��ؘ��ؗ��֏���k���G��w�mC�e;�a8�]5�X1�V/]V/
|
|
2871
|
+
V/�V/�V/�V/�W0�Y2�\\4�]5Pb:c:�e<�h>�j@�lB�oD�qF�rGDwK}wK�sI�d@�cA��f��k��k��k��k��k��k��k��k��i���$���W���p���v���n���Y���I���*�rG�j@�f<�a8�\\4�X1�V/ V/
|
|
2872
|
+
V/�V/�V/�V/�W0�Y1�[3�\\5Qa8wb:�e<�g>�i@�lB�nD�pE�oCuI}sH�iB�Z:��Z��l��k��k��k��k��k��k��k��j��f��e����Ω4�ܹA�B�״=���(�}R�nC�j@�e<�\`8�[4�X1�V/
|
|
2873
|
+
V/�V/�V/�V/�V/�X1�[3�]5�\`7�b9�d;�f=�i?�kA�mC�oD*qG}kD�Z9�oI��j��k��k��k��k��k��k�k��k��i��e��a��]��_��g��g
|
|
2874
|
+
��[�xK�rF�nC�i?�d;�_7�[3�X1V/
|
|
2875
|
+
V/�V/�V/�V/�V/�X0�Z2�\\4�_6�a8�c:�f<�h>�j@�lBqjB}_<�\\;��c��l��k��k��k��k��k۞kC�k��j��g��c��\`��\\��X��S�}O�yL�uI�qE�lA�g>�c:�^6�[3JV/
|
|
2876
|
+
V/�V/�V/�V/�V/�W0�Y2�\\4�^6�\`8�b:�e;�g=�i?�kA\`;}U6�U��l��k��k��k��k��k��kl�k$�h��d��a��^��Z��V��S�}O�xK�tH�oD�j@�f<�a9�^6ZS,V/
|
|
2877
|
+
V/�V/�V/�V/�V/�V/�X1�[3�]5�_7�a9�d;�f<�g>MT4~kE��i��k��k��k��k��k��k��k�e�b��_�[��X��T�Q�zM�vJ�rF�mB�i?�e;�a8BW0V/
|
|
2878
|
+
V/�V/�V/�V/�V/�V/�W0�Z2�\\4�^6�\`8�b:�d;�g=iC~�a��k��k��k��k��k��k�k:�\`�]@�Y��VڀR�|O�xK�tH�pD�lA�h>he;V/
|
|
2879
|
+
V/�V/�V/�V/�V/�V/�W0�Y1�[3�]5�_7�a8�c:.xL~Q��R��S��T��T��U��W��o�W�TQ={MTwJYsGJoD+kAV/
|
|
2880
|
+
V/�V/�V/�V/�V/�V/�V/�X0�Z2�\\4�^6�\`7wkA}lB�nC�oD�pF�rG�sH�sH�V/
|
|
2881
|
+
V/�V/�V/�V/�V/�V/�V/�W/�X1�Z3�\\4�^6j@}kA�lB�nC�oD�pE�qF�rG�V/
|
|
2882
|
+
V/�V/�V/�V/�V/�V/�V/�V/�W0�Y2�[3Rh>}i?�j@�lB�mC�nC�oD�pE�V/
|
|
2883
|
+
V/�V/�V/�V/�V/�V/�V/�V/�V/�W0�Z2f=}g=�h?�j@�kA�lB�mB�mC�V/
|
|
2884
|
+
V/�V/�V/�V/�V/�V/�V/�V/�V/�V/2d;}e<�f=�g>�i?�j@�j@�kA�V/
|
|
2885
|
+
V/�V/�V/�V/�V/�V/�V/�V/�V/~b9}c:�d;�e<�f=�g>�h>�i?�V/
|
|
2886
|
+
V/�V/�V/�V/�V/�V/�V/�V/�V/\`7}a8�b9�c:�d;�e<�f<�f=�V/V/TV/pV/nV/nV/nV/nV/oV/:_66\`7oa8nb9nc:nd;nd;pe;C�������������������������������������������������������������������������>��������������������?����������������>����\`��\`����������?���?����?����?����?����?���?�?����?����?��������������������������������������������������( @ V/V/XV/\\V/\\V/]X1/L,~SI�i\`�i_�i_�i[�i�_�\\V�X\\�S\\{N^wJ,V/KV/�V/�V/�W0�Y1�d=BgA�b��k��k��k��k��k�s�c��_��Z��U�}P�xL6V/KV/�V/�V/�X1�Z3�pEmC�b=�pJ��j��k��k��k�kJ�kA�g�c��]��X��TyV/KV/�V/�V/�Y1�[3�oDfqF�nE�\`=��Y��l��k��k��kϞk˝j��f��\`��[��VV/KV/�V/�W/�Z2�\\4�mC#oD�rG�uI�lE�hD��e��k��k��k��k��k��h��c�^FV/V/V/KV/�V/�W0�Z3�]5�h>mC�pE�sH�wK�wL�hC�yP��k��k��k��k��k��i��e��[V/*V/zV/KV/�V/�W0�[3�]5�kA@mB�pE�tI�xL�{N�wL�fC��]��l��k��k��k��j͚g�w ]5\\W0oV/KV/�V/�W0�[3�]5�g>j@�mB�qF�tI�xL�|O�|P�hC�mI��k��k��k��l������F��J ��NIĢ6�d<�V/�V/KV/�V/�W0�[3�]5�g=ci?�mB�pE�tH�xL�{N�wM�eB��[��k��k��k��j���3��ڑU�ݩ�ڜ�ٜF��uk߾Dҽ�1��c�]5�W0�V/KV/�V/�W0�Z3�]5�d;e<�i?�lB�pE�sH�wK�wL�hC�vN��j��k��k��k��j��z�ܿ^��ֈ����Ԃ���Z���!�mC�a8�[4�W0�V/KV/�V/�W/�Z2�\\4�b9�d;�h>�kA�oD�qFBuJ�mE�fB��d��k��k��k��k��k��g��{�Ϊ=�ܽM�ٸD���'�uJ�h>�b9�[3�W06V/KV/�V/�V/�Y1�\\4�\`8�c:�g=�j@�mC�zKlD�_<��W��l��k��k��k��k؝j��f��_��_��e
|
|
2887
|
+
��] �wK�nC�g=�\`7�[3L'V/KV/�V/�V/�X1�[3�_6�b9�e<�h?�kA%\\9�mG��i��k��k��k��ke�k9�gՔb��]��W�Q�yL�sG�lA�e<�\`7�[3V/KV/�V/�V/�W0�Z2�]5�a8�d;�f=jeA��a��l��l��k��k��k�d.�_��Z�U�}O�vJ�pE�j?�d;v_7V/KV/�V/�V/�V/�X1�\\4�_7�b9�e;|P��Y��Z��[��\\�aA�\\�W7�RnzM�tH�nC\\i?!a9V/KV/�V/�V/�V/�W0�Z2�]5�_7Gj?lA�mC�oD�qF�sG�sH+V/KV/�V/�V/�V/�V/�X1�[3�\`7b8i?�j@�mB�nD�pE�pE+V/KV/�V/�V/�V/�V/�V/�X1)_6f=�g>�i@�kA�lB�mC+V/LV/�V/�V/�V/�V/�V/q]4c:�d;�f=�h>�i?�i?+V/@V/�V/�V/�V/�V/�V/[2\`8�b9�c:�e;�f<�f=$V/V/V/V/V/V/_6\`7a9c:d;d;����������������������������������0��0���������������������00�p8�p?�����������������������������������( V/'V/;W0*Z3^:�]2�k=�j%�]#�V<{N(j?V/�V/�X1�\\4h@LvM�i��kʞkA�cƉY�QaV/�V/�Z2�[4nCqF�lE��Z��l��k�h��\`��VV/ V/�W0�[3�[4mCrrG�wK�tL��e��k��j�d8��(
|
|
2888
|
+
\\5VV/�W0�[3�f=1kA�rG�zM�qI��^��k��z���z0��#��R^�}#�b:�V/�W0�Z3�d;�j@�qF�qH�zP��j��k��r�ƤB�ڽ]㫆*�lC�[3�V/�V/�Z2�a8�g>�jAGlFc��l��k��e�a��^�sH�c:�[47V/�V/�X1�^6�c:�^:�TŒa��d��n
|
|
2889
|
+
�\`@�V�xK�mB�d;-V/�V/�V/�Z2�_6 mB
|
|
2890
|
+
mC�pE�sG�yLtHlAV/�V/�V/�W/dc:e<�h?�j@�V/RV/|V/hV/_7a9^d;}f<A��������Oc������"
|
|
2891
|
+
`;
|
|
2892
|
+
|
|
2893
|
+
exports[`react-website generator > Tanstack router integration > should generate website with router correctly > test-app/src/components/AppLayout/index.tsx 1`] = `
|
|
2894
|
+
"import * as React from 'react';
|
|
2895
|
+
import { createContext, useCallback, useEffect, useState } from 'react';
|
|
2896
|
+
import Config from '../../config';
|
|
2897
|
+
|
|
2898
|
+
import {
|
|
2899
|
+
BreadcrumbGroup,
|
|
2900
|
+
BreadcrumbGroupProps,
|
|
2901
|
+
SideNavigation,
|
|
2902
|
+
TopNavigation,
|
|
2903
|
+
} from '@cloudscape-design/components';
|
|
2904
|
+
import CloudscapeAppLayout, {
|
|
2905
|
+
AppLayoutProps,
|
|
2906
|
+
} from '@cloudscape-design/components/app-layout';
|
|
2907
|
+
import { matchByPath, useLocation, useNavigate } from '@tanstack/react-router';
|
|
2908
|
+
|
|
2909
|
+
const getBreadcrumbs = (
|
|
2910
|
+
pathName: string,
|
|
2911
|
+
search: string,
|
|
2912
|
+
defaultBreadcrumb: string,
|
|
2913
|
+
availableRoutes?: string[],
|
|
2914
|
+
) => {
|
|
2915
|
+
const segments = [
|
|
2916
|
+
defaultBreadcrumb,
|
|
2917
|
+
...pathName.split('/').filter((segment) => segment !== ''),
|
|
2918
|
+
];
|
|
2919
|
+
|
|
2920
|
+
return segments.map((segment, i) => {
|
|
2921
|
+
const href =
|
|
2922
|
+
i === 0
|
|
2923
|
+
? '/'
|
|
2924
|
+
: \`/\${segments
|
|
2925
|
+
.slice(1, i + 1)
|
|
2926
|
+
.join('/')
|
|
2927
|
+
.replace('//', '/')}\`;
|
|
2928
|
+
|
|
2929
|
+
const matched =
|
|
2930
|
+
!availableRoutes || availableRoutes.find((r) => matchByPath(r, href, {}));
|
|
2931
|
+
|
|
2932
|
+
return {
|
|
2933
|
+
href: matched ? \`\${href}\${search}\` : '#',
|
|
2934
|
+
text: segment,
|
|
2935
|
+
};
|
|
2936
|
+
});
|
|
2937
|
+
};
|
|
2938
|
+
|
|
2939
|
+
export interface AppLayoutContext {
|
|
2940
|
+
appLayoutProps: AppLayoutProps;
|
|
2941
|
+
setAppLayoutProps: (props: AppLayoutProps) => void;
|
|
2942
|
+
displayHelpPanel: (helpContent: React.ReactNode) => void;
|
|
2943
|
+
}
|
|
2944
|
+
|
|
2945
|
+
/**
|
|
2946
|
+
* Context for updating/retrieving the AppLayout.
|
|
2947
|
+
*/
|
|
2948
|
+
export const AppLayoutContext = createContext({
|
|
2949
|
+
appLayoutProps: {},
|
|
2950
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
2951
|
+
setAppLayoutProps: (_: AppLayoutProps) => {},
|
|
2952
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
2953
|
+
displayHelpPanel: (_: React.ReactNode) => {},
|
|
2954
|
+
});
|
|
2955
|
+
|
|
2956
|
+
/**
|
|
2957
|
+
* Defines the App layout and contains logic for routing.
|
|
2958
|
+
*/
|
|
2959
|
+
const AppLayout: React.FC<React.PropsWithChildren> = ({ children }) => {
|
|
2960
|
+
const appLayout = React.useRef<AppLayoutProps.Ref>(null);
|
|
2961
|
+
const [appLayoutProps, setAppLayoutProps] = useState<AppLayoutProps>({});
|
|
2962
|
+
const setAppLayoutPropsSafe = useCallback(
|
|
2963
|
+
(props: AppLayoutProps) => {
|
|
2964
|
+
JSON.stringify(appLayoutProps) !== JSON.stringify(props) &&
|
|
2965
|
+
setAppLayoutProps(props);
|
|
2966
|
+
},
|
|
2967
|
+
[appLayoutProps],
|
|
2968
|
+
);
|
|
2969
|
+
|
|
2970
|
+
const navigate = useNavigate();
|
|
2971
|
+
const [activeBreadcrumbs, setActiveBreadcrumbs] = useState<
|
|
2972
|
+
BreadcrumbGroupProps.Item[]
|
|
2973
|
+
>([{ text: '/', href: '/' }]);
|
|
2974
|
+
const { pathname, search } = useLocation();
|
|
2975
|
+
|
|
2976
|
+
useEffect(() => {
|
|
2977
|
+
const breadcrumbs = getBreadcrumbs(
|
|
2978
|
+
pathname,
|
|
2979
|
+
Object.entries(search).reduce((p, [k, v]) => p + \`\${k}=\${v}\`, ''),
|
|
2980
|
+
'/',
|
|
2981
|
+
);
|
|
2982
|
+
setActiveBreadcrumbs(breadcrumbs);
|
|
2983
|
+
}, [pathname, search]);
|
|
2984
|
+
|
|
2985
|
+
const onNavigate = useCallback(
|
|
2986
|
+
(e: CustomEvent<{ href: string; external?: boolean }>) => {
|
|
2987
|
+
if (!e.detail.external) {
|
|
2988
|
+
e.preventDefault();
|
|
2989
|
+
setAppLayoutPropsSafe({
|
|
2990
|
+
contentType: undefined,
|
|
2991
|
+
});
|
|
2992
|
+
navigate({ to: e.detail.href });
|
|
2993
|
+
}
|
|
2994
|
+
},
|
|
2995
|
+
[navigate, setAppLayoutPropsSafe],
|
|
2996
|
+
);
|
|
2997
|
+
|
|
2998
|
+
return (
|
|
2999
|
+
<AppLayoutContext.Provider
|
|
3000
|
+
value={{
|
|
3001
|
+
appLayoutProps,
|
|
3002
|
+
setAppLayoutProps: setAppLayoutPropsSafe,
|
|
3003
|
+
displayHelpPanel: (helpContent: React.ReactNode) => {
|
|
3004
|
+
setAppLayoutPropsSafe({ tools: helpContent, toolsHide: false });
|
|
3005
|
+
appLayout.current?.openTools();
|
|
3006
|
+
},
|
|
3007
|
+
}}
|
|
3008
|
+
>
|
|
3009
|
+
<TopNavigation
|
|
3010
|
+
identity={{
|
|
3011
|
+
href: '/',
|
|
3012
|
+
title: Config.applicationName,
|
|
3013
|
+
logo: {
|
|
3014
|
+
src: Config.logo,
|
|
3015
|
+
},
|
|
3016
|
+
}}
|
|
3017
|
+
/>
|
|
3018
|
+
<CloudscapeAppLayout
|
|
3019
|
+
ref={appLayout}
|
|
3020
|
+
breadcrumbs={
|
|
3021
|
+
<BreadcrumbGroup onFollow={onNavigate} items={activeBreadcrumbs} />
|
|
3022
|
+
}
|
|
3023
|
+
navigation={
|
|
3024
|
+
<SideNavigation
|
|
3025
|
+
header={{ text: Config.applicationName, href: '/' }}
|
|
3026
|
+
activeHref={pathname}
|
|
3027
|
+
onFollow={onNavigate}
|
|
3028
|
+
items={[{ text: 'Home', type: 'link', href: '/' }]}
|
|
3029
|
+
/>
|
|
3030
|
+
}
|
|
3031
|
+
toolsHide
|
|
3032
|
+
content={children}
|
|
3033
|
+
{...appLayoutProps}
|
|
3034
|
+
/>
|
|
3035
|
+
</AppLayoutContext.Provider>
|
|
3036
|
+
);
|
|
3037
|
+
};
|
|
3038
|
+
|
|
3039
|
+
export default AppLayout;
|
|
3040
|
+
"
|
|
3041
|
+
`;
|
|
3042
|
+
|
|
3043
|
+
exports[`react-website generator > Tanstack router integration > should generate website with router correctly > test-app/src/config.ts 1`] = `
|
|
3044
|
+
"export default {
|
|
3045
|
+
applicationName: 'test-app',
|
|
3046
|
+
logo: 'data:image/svg+xml;base64,PCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj4KDTwhLS0gVXBsb2FkZWQgdG86IFNWRyBSZXBvLCB3d3cuc3ZncmVwby5jb20sIFRyYW5zZm9ybWVkIGJ5OiBTVkcgUmVwbyBNaXhlciBUb29scyAtLT4KPHN2ZyBmaWxsPSIjMjQ4YmFlIiB3aWR0aD0iODAwcHgiIGhlaWdodD0iODAwcHgiIHZpZXdCb3g9IjAgMCA1MTIgNTEyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0cm9rZT0iIzI0OGJhZSI+Cg08ZyBpZD0iU1ZHUmVwb19iZ0NhcnJpZXIiIHN0cm9rZS13aWR0aD0iMCIvPgoNPGcgaWQ9IlNWR1JlcG9fdHJhY2VyQ2FycmllciIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+Cg08ZyBpZD0iU1ZHUmVwb19pY29uQ2FycmllciI+Cg08dGl0bGU+aW9uaWNvbnMtdjVfbG9nb3M8L3RpdGxlPgoNPHBhdGggZD0iTTQxMC42NiwxODAuNzJoMHEtNy42Ny0yLjYyLTE1LjQ1LTQuODgsMS4yOS01LjI1LDIuMzgtMTAuNTZjMTEuNy01Ni45LDQuMDUtMTAyLjc0LTIyLjA2LTExNy44My0yNS0xNC40OC02NiwuNjEtMTA3LjM2LDM2LjY5cS02LjEsNS4zNC0xMS45NSwxMS0zLjktMy43Ni04LTcuMzZjLTQzLjM1LTM4LjU4LTg2LjgtNTQuODMtMTEyLjg4LTM5LjY5LTI1LDE0LjUxLTMyLjQzLDU3LjYtMjEuOSwxMTEuNTNxMS41OCw4LDMuNTUsMTUuOTNjLTYuMTUsMS43NS0xMi4wOSwzLjYyLTE3Ljc3LDUuNkM0OC40NiwxOTguOSwxNiwyMjYuNzMsMTYsMjU1LjU5YzAsMjkuODIsMzQuODQsNTkuNzIsODcuNzcsNzcuODVxNi40NCwyLjE5LDEzLDQuMDdRMTE0LjY0LDM0NiwxMTMsMzU0LjY4Yy0xMCw1My0yLjIsOTUuMDcsMjIuNzUsMTA5LjQ5LDI1Ljc3LDE0Ljg5LDY5LS40MSwxMTEuMTQtMzcuMzFxNS00LjM4LDEwLTkuMjUsNi4zMiw2LjExLDEzLDExLjg2YzQwLjgsMzUuMTgsODEuMDksNDkuMzksMTA2LDM0LjkzLDI1Ljc1LTE0Ljk0LDM0LjEyLTYwLjE0LDIzLjI1LTExNS4xM3EtMS4yNS02LjMtMi44OC0xMi44Niw0LjU2LTEuMzUsOC45My0yLjc5YzU1LTE4LjI3LDkwLjgzLTQ3LjgxLDkwLjgzLTc4QzQ5NiwyMjYuNjIsNDYyLjUsMTk4LjYxLDQxMC42NiwxODAuNzJabS0xMjktODEuMDhjMzUuNDMtMzAuOTEsNjguNTUtNDMuMTEsODMuNjUtMzQuMzloMGMxNi4wNyw5LjI5LDIyLjMyLDQ2Ljc1LDEyLjIyLDk1Ljg4cS0xLDQuOC0yLjE2LDkuNTdhNDg3LjgzLDQ4Ny44MywwLDAsMC02NC4xOC0xMC4xNiw0ODEuMjcsNDgxLjI3LDAsMCwwLTQwLjU3LTUwLjc1UTI3NiwxMDQuNTcsMjgxLjY0LDk5LjY0Wk0xNTcuNzMsMjgwLjI1cTYuNTEsMTIuNiwxMy42MSwyNC44OSw3LjIzLDEyLjU0LDE1LjA3LDI0LjcxYTQzNS4yOCw0MzUuMjgsMCwwLDEtNDQuMjQtNy4xM0MxNDYuNDEsMzA5LDE1MS42MywyOTQuNzUsMTU3LjczLDI4MC4yNVptMC00OC4zM2MtNi0xNC4xOS0xMS4wOC0yOC4xNS0xNS4yNS00MS42MywxMy43LTMuMDcsMjguMy01LjU4LDQzLjUyLTcuNDhxLTcuNjUsMTEuOTQtMTQuNzIsMjQuMjNUMTU3LjcsMjMxLjkyWm0xMC45LDI0LjE3cTkuNDgtMTkuNzcsMjAuNDItMzguNzhoMHExMC45My0xOSwyMy4yNy0zNy4xM2MxNC4yOC0xLjA4LDI4LjkyLTEuNjUsNDMuNzEtMS42NXMyOS41Mi41Nyw0My43OSwxLjY2cTEyLjIxLDE4LjA5LDIzLjEzLDM3dDIwLjY5LDM4LjZRMzM0LDI3NS42MywzMjMsMjk0LjczaDBxLTEwLjkxLDE5LTIzLDM3LjI0Yy0xNC4yNSwxLTI5LDEuNTUtNDQsMS41NXMtMjkuNDctLjQ3LTQzLjQ2LTEuMzhxLTEyLjQzLTE4LjE5LTIzLjQ2LTM3LjI5VDE2OC42LDI1Ni4wOVpNMzQwLjc1LDMwNXE3LjI1LTEyLjU4LDEzLjkyLTI1LjQ5aDBhNDQwLjQxLDQ0MC40MSwwLDAsMSwxNi4xMiw0Mi4zMkE0MzQuNDQsNDM0LjQ0LDAsMCwxLDMyNiwzMjkuNDhRMzMzLjYyLDMxNy4zOSwzNDAuNzUsMzA1Wm0xMy43Mi03My4wN3EtNi42NC0xMi42NS0xMy44MS0yNWgwcS03LTEyLjE4LTE0LjU5LTI0LjA2YzE1LjMxLDEuOTQsMzAsNC41Miw0My43Nyw3LjY3QTQzOS44OSw0MzkuODksMCwwLDEsMzU0LjQ3LDIzMS45M1pNMjU2LjIzLDEyNC40OGgwYTQzOS43NSw0MzkuNzUsMCwwLDEsMjguMjUsMzQuMThxLTI4LjM1LTEuMzUtNTYuNzQsMEMyMzcuMDcsMTQ2LjMyLDI0Ni42MiwxMzQuODcsMjU2LjIzLDEyNC40OFpNMTQ1LjY2LDY1Ljg2YzE2LjA2LTkuMzIsNTEuNTcsNCw4OSwzNy4yNywyLjM5LDIuMTMsNC44LDQuMzYsNy4yLDYuNjdBNDkxLjM3LDQ5MS4zNywwLDAsMCwyMDEsMTYwLjUxYTQ5OS4xMiw0OTkuMTIsMCwwLDAtNjQuMDYsMTBxLTEuODMtNy4zNi0zLjMtMTQuODJoMEMxMjQuNTksMTA5LjQ2LDEzMC41OCw3NC42MSwxNDUuNjYsNjUuODZaTTEyMi4yNSwzMTcuNzFxLTYtMS43MS0xMS44NS0zLjcxYy0yMy40LTgtNDIuNzMtMTguNDQtNTYtMjkuODFDNDIuNTIsMjc0LDM2LjUsMjYzLjgzLDM2LjUsMjU1LjU5YzAtMTcuNTEsMjYuMDYtMzkuODUsNjkuNTItNTVxOC4xOS0yLjg1LDE2LjUyLTUuMjFhNDkzLjU0LDQ5My41NCwwLDAsMCwyMy40LDYwLjc1QTUwMi40Niw1MDIuNDYsMCwwLDAsMTIyLjI1LDMxNy43MVptMTExLjEzLDkzLjY3Yy0xOC42MywxNi4zMi0zNy4yOSwyNy44OS01My43NCwzMy43MmgwYy0xNC43OCw1LjIzLTI2LjU1LDUuMzgtMzMuNjYsMS4yNy0xNS4xNC04Ljc1LTIxLjQ0LTQyLjU0LTEyLjg1LTg3Ljg2cTEuNTMtOCwzLjUtMTZhNDgwLjg1LDQ4MC44NSwwLDAsMCw2NC42OSw5LjM5LDUwMS4yLDUwMS4yLDAsMCwwLDQxLjIsNTFDMjM5LjU0LDQwNS44MywyMzYuNDksNDA4LjY1LDIzMy4zOCw0MTEuMzhabTIzLjQyLTIzLjIyYy05LjcyLTEwLjUxLTE5LjQyLTIyLjE0LTI4Ljg4LTM0LjY0cTEzLjc5LjU0LDI4LjA4LjU0YzkuNzgsMCwxOS40Ni0uMjEsMjktLjY0QTQzOS4zMyw0MzkuMzMsMCwwLDEsMjU2LjgsMzg4LjE2Wm0xMjQuNTIsMjguNTljLTIuODYsMTUuNDQtOC42MSwyNS43NC0xNS43MiwyOS44Ni0xNS4xMyw4Ljc4LTQ3LjQ4LTIuNjMtODIuMzYtMzIuNzItNC0zLjQ0LTgtNy4xMy0xMi4wNy0xMWE0ODQuNTQsNDg0LjU0LDAsMCwwLDQwLjIzLTUxLjIsNDc3Ljg0LDQ3Ny44NCwwLDAsMCw2NS0xMC4wNXExLjQ3LDUuOTQsMi42LDExLjY0aDBDMzgzLjgxLDM3Ny41OCwzODQuNSwzOTkuNTYsMzgxLjMyLDQxNi43NVptMTcuNC0xMDIuNjRoMGMtMi42Mi44Ny01LjMyLDEuNzEtOC4wNiwyLjUzYTQ4My4yNiw0ODMuMjYsMCwwLDAtMjQuMzEtNjAuOTQsNDgxLjUyLDQ4MS41MiwwLDAsMCwyMy4zNi02MC4wNmM0LjkxLDEuNDMsOS42OCwyLjkzLDE0LjI3LDQuNTIsNDQuNDIsMTUuMzIsNzEuNTIsMzgsNzEuNTIsNTUuNDNDNDc1LjUsMjc0LjE5LDQ0Ni4yMywyOTguMzMsMzk4LjcyLDMxNC4xMVoiLz4KDTxwYXRoIGQ9Ik0yNTYsMjk4LjU1YTQzLDQzLDAsMSwwLTQyLjg2LTQzQTQyLjkxLDQyLjkxLDAsMCwwLDI1NiwyOTguNTVaIi8+Cg08L2c+Cg08L3N2Zz4=',
|
|
3047
|
+
};
|
|
3048
|
+
"
|
|
3049
|
+
`;
|
|
3050
|
+
|
|
3051
|
+
exports[`react-website generator > Tanstack router integration > should generate website with router correctly > test-app/src/hooks/useAppLayout.tsx 1`] = `
|
|
3052
|
+
"import { useContext } from 'react';
|
|
3053
|
+
import { AppLayoutContext } from '../components/AppLayout';
|
|
3054
|
+
|
|
3055
|
+
export const useAppLayout = (): AppLayoutContext =>
|
|
3056
|
+
useContext(AppLayoutContext);
|
|
3057
|
+
"
|
|
3058
|
+
`;
|
|
3059
|
+
|
|
3060
|
+
exports[`react-website generator > Tanstack router integration > should generate website with router correctly > test-app/src/main.tsx 1`] = `
|
|
3061
|
+
"import React from 'react';
|
|
3062
|
+
import { createRoot } from 'react-dom/client';
|
|
3063
|
+
import { I18nProvider } from '@cloudscape-design/components/i18n';
|
|
3064
|
+
import messages from '@cloudscape-design/components/i18n/messages/all.en';
|
|
3065
|
+
import '@cloudscape-design/global-styles/index.css';
|
|
3066
|
+
import { RouterProvider, createRouter } from '@tanstack/react-router';
|
|
3067
|
+
import { routeTree } from './routeTree.gen';
|
|
3068
|
+
|
|
3069
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
3070
|
+
export type RouterProviderContext = {};
|
|
3071
|
+
|
|
3072
|
+
const router = createRouter({
|
|
3073
|
+
routeTree,
|
|
3074
|
+
context: {},
|
|
3075
|
+
});
|
|
3076
|
+
|
|
3077
|
+
// Register the router instance for type safety
|
|
3078
|
+
declare module '@tanstack/react-router' {
|
|
3079
|
+
interface Register {
|
|
3080
|
+
router: typeof router;
|
|
3081
|
+
}
|
|
3082
|
+
}
|
|
3083
|
+
|
|
3084
|
+
const App = () => {
|
|
3085
|
+
return <RouterProvider router={router} context={{}} />;
|
|
3086
|
+
};
|
|
3087
|
+
|
|
3088
|
+
const root = document.getElementById('root');
|
|
3089
|
+
root &&
|
|
3090
|
+
createRoot(root).render(
|
|
3091
|
+
<React.StrictMode>
|
|
3092
|
+
<I18nProvider locale="en" messages={[messages]}>
|
|
3093
|
+
<App />
|
|
3094
|
+
</I18nProvider>
|
|
3095
|
+
</React.StrictMode>,
|
|
3096
|
+
);
|
|
3097
|
+
"
|
|
3098
|
+
`;
|
|
3099
|
+
|
|
3100
|
+
exports[`react-website generator > Tanstack router integration > should generate website with router correctly > test-app/src/routeTree.gen.ts 1`] = `
|
|
3101
|
+
"/* eslint-disable */
|
|
3102
|
+
|
|
3103
|
+
// @ts-nocheck
|
|
3104
|
+
|
|
3105
|
+
// noinspection JSUnusedGlobalSymbols
|
|
3106
|
+
|
|
3107
|
+
// This file was automatically generated by TanStack Router.
|
|
3108
|
+
// You should NOT make any changes in this file as it will be overwritten.
|
|
3109
|
+
// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.
|
|
3110
|
+
|
|
3111
|
+
// Import Routes
|
|
3112
|
+
|
|
3113
|
+
import { Route as rootRoute } from './routes/__root';
|
|
3114
|
+
import { Route as IndexImport } from './routes/index';
|
|
3115
|
+
import { Route as WelcomeIndexImport } from './routes/welcome/index';
|
|
3116
|
+
|
|
3117
|
+
// Create/Update Routes
|
|
3118
|
+
|
|
3119
|
+
const IndexRoute = IndexImport.update({
|
|
3120
|
+
id: '/',
|
|
3121
|
+
path: '/',
|
|
3122
|
+
getParentRoute: () => rootRoute,
|
|
3123
|
+
} as any);
|
|
3124
|
+
|
|
3125
|
+
const WelcomeIndexRoute = WelcomeIndexImport.update({
|
|
3126
|
+
id: '/welcome/',
|
|
3127
|
+
path: '/welcome/',
|
|
3128
|
+
getParentRoute: () => rootRoute,
|
|
3129
|
+
} as any);
|
|
3130
|
+
|
|
3131
|
+
// Populate the FileRoutesByPath interface
|
|
3132
|
+
|
|
3133
|
+
declare module '@tanstack/react-router' {
|
|
3134
|
+
interface FileRoutesByPath {
|
|
3135
|
+
'/': {
|
|
3136
|
+
id: '/';
|
|
3137
|
+
path: '/';
|
|
3138
|
+
fullPath: '/';
|
|
3139
|
+
preLoaderRoute: typeof IndexImport;
|
|
3140
|
+
parentRoute: typeof rootRoute;
|
|
3141
|
+
};
|
|
3142
|
+
'/welcome/': {
|
|
3143
|
+
id: '/welcome/';
|
|
3144
|
+
path: '/welcome';
|
|
3145
|
+
fullPath: '/welcome';
|
|
3146
|
+
preLoaderRoute: typeof WelcomeIndexImport;
|
|
3147
|
+
parentRoute: typeof rootRoute;
|
|
3148
|
+
};
|
|
3149
|
+
}
|
|
3150
|
+
}
|
|
3151
|
+
|
|
3152
|
+
// Create and export the route tree
|
|
3153
|
+
|
|
3154
|
+
export interface FileRoutesByFullPath {
|
|
3155
|
+
'/': typeof IndexRoute;
|
|
3156
|
+
'/welcome': typeof WelcomeIndexRoute;
|
|
3157
|
+
}
|
|
3158
|
+
|
|
3159
|
+
export interface FileRoutesByTo {
|
|
3160
|
+
'/': typeof IndexRoute;
|
|
3161
|
+
'/welcome': typeof WelcomeIndexRoute;
|
|
3162
|
+
}
|
|
3163
|
+
|
|
3164
|
+
export interface FileRoutesById {
|
|
3165
|
+
__root__: typeof rootRoute;
|
|
3166
|
+
'/': typeof IndexRoute;
|
|
3167
|
+
'/welcome/': typeof WelcomeIndexRoute;
|
|
3168
|
+
}
|
|
3169
|
+
|
|
3170
|
+
export interface FileRouteTypes {
|
|
3171
|
+
fileRoutesByFullPath: FileRoutesByFullPath;
|
|
3172
|
+
fullPaths: '/' | '/welcome';
|
|
3173
|
+
fileRoutesByTo: FileRoutesByTo;
|
|
3174
|
+
to: '/' | '/welcome';
|
|
3175
|
+
id: '__root__' | '/' | '/welcome/';
|
|
3176
|
+
fileRoutesById: FileRoutesById;
|
|
3177
|
+
}
|
|
3178
|
+
|
|
3179
|
+
export interface RootRouteChildren {
|
|
3180
|
+
IndexRoute: typeof IndexRoute;
|
|
3181
|
+
WelcomeIndexRoute: typeof WelcomeIndexRoute;
|
|
3182
|
+
}
|
|
3183
|
+
|
|
3184
|
+
const rootRouteChildren: RootRouteChildren = {
|
|
3185
|
+
IndexRoute: IndexRoute,
|
|
3186
|
+
WelcomeIndexRoute: WelcomeIndexRoute,
|
|
3187
|
+
};
|
|
3188
|
+
|
|
3189
|
+
export const routeTree = rootRoute
|
|
3190
|
+
._addFileChildren(rootRouteChildren)
|
|
3191
|
+
._addFileTypes<FileRouteTypes>();
|
|
3192
|
+
|
|
3193
|
+
/* ROUTE_MANIFEST_START
|
|
3194
|
+
{
|
|
3195
|
+
"routes": {
|
|
3196
|
+
"__root__": {
|
|
3197
|
+
"filePath": "__root.tsx",
|
|
3198
|
+
"children": [
|
|
3199
|
+
"/",
|
|
3200
|
+
"/welcome/"
|
|
3201
|
+
]
|
|
3202
|
+
},
|
|
3203
|
+
"/": {
|
|
3204
|
+
"filePath": "index.tsx"
|
|
3205
|
+
},
|
|
3206
|
+
"/welcome/": {
|
|
3207
|
+
"filePath": "welcome/index.tsx"
|
|
3208
|
+
}
|
|
3209
|
+
}
|
|
3210
|
+
}
|
|
3211
|
+
ROUTE_MANIFEST_END */
|
|
3212
|
+
"
|
|
3213
|
+
`;
|
|
3214
|
+
|
|
3215
|
+
exports[`react-website generator > Tanstack router integration > should generate website with router correctly > test-app/src/routes/__root.tsx 1`] = `
|
|
3216
|
+
"import { createRootRouteWithContext } from '@tanstack/react-router';
|
|
3217
|
+
import AppLayout from '../components/AppLayout';
|
|
3218
|
+
import { RouterProviderContext } from '../main';
|
|
3219
|
+
import { Outlet } from '@tanstack/react-router';
|
|
3220
|
+
|
|
3221
|
+
export const Route = createRootRouteWithContext<RouterProviderContext>()({
|
|
3222
|
+
component: () => (
|
|
3223
|
+
<AppLayout>
|
|
3224
|
+
<Outlet />
|
|
3225
|
+
</AppLayout>
|
|
3226
|
+
),
|
|
3227
|
+
});
|
|
3228
|
+
"
|
|
3229
|
+
`;
|
|
3230
|
+
|
|
3231
|
+
exports[`react-website generator > Tanstack router integration > should generate website with router correctly > test-app/src/routes/index.tsx 1`] = `
|
|
3232
|
+
"import {
|
|
3233
|
+
ContentLayout,
|
|
3234
|
+
Header,
|
|
3235
|
+
SpaceBetween,
|
|
3236
|
+
Container,
|
|
3237
|
+
} from '@cloudscape-design/components';
|
|
3238
|
+
import { createFileRoute } from '@tanstack/react-router';
|
|
3239
|
+
|
|
3240
|
+
export const Route = createFileRoute('/')({
|
|
3241
|
+
component: RouteComponent,
|
|
3242
|
+
});
|
|
3243
|
+
|
|
3244
|
+
function RouteComponent() {
|
|
3245
|
+
return (
|
|
3246
|
+
<ContentLayout header={<Header>Welcome</Header>}>
|
|
3247
|
+
<SpaceBetween size="l">
|
|
3248
|
+
<Container>Welcome to your new React website!</Container>
|
|
3249
|
+
</SpaceBetween>
|
|
3250
|
+
</ContentLayout>
|
|
3251
|
+
);
|
|
3252
|
+
}
|
|
3253
|
+
"
|
|
3254
|
+
`;
|
|
3255
|
+
|
|
3256
|
+
exports[`react-website generator > Tanstack router integration > should generate website with router correctly > test-app/src/styles.css 1`] = `
|
|
3257
|
+
"@import 'tailwindcss';
|
|
3258
|
+
/* You can add global styles to this file, and also import other style files */
|
|
3259
|
+
"
|
|
3260
|
+
`;
|
|
3261
|
+
|
|
3262
|
+
exports[`react-website generator > Tanstack router integration > should generate website with router correctly > test-app/tsconfig.app.json 1`] = `
|
|
3263
|
+
"{
|
|
3264
|
+
"extends": "../tsconfig.base.json",
|
|
3265
|
+
"compilerOptions": {
|
|
3266
|
+
"outDir": "../dist/test-app/tsc",
|
|
3267
|
+
"tsBuildInfoFile": "../dist/test-app/tsc/tsconfig.lib.tsbuildinfo",
|
|
3268
|
+
"jsx": "react-jsx",
|
|
3269
|
+
"lib": ["DOM"],
|
|
3270
|
+
"types": [
|
|
3271
|
+
"node",
|
|
3272
|
+
"@nx/react/typings/cssmodule.d.ts",
|
|
3273
|
+
"@nx/react/typings/image.d.ts",
|
|
3274
|
+
"vite/client"
|
|
3275
|
+
]
|
|
3276
|
+
},
|
|
3277
|
+
"exclude": [
|
|
3278
|
+
"src/**/*.spec.ts",
|
|
3279
|
+
"src/**/*.test.ts",
|
|
3280
|
+
"src/**/*.spec.tsx",
|
|
3281
|
+
"src/**/*.test.tsx",
|
|
3282
|
+
"src/**/*.spec.js",
|
|
3283
|
+
"src/**/*.test.js",
|
|
3284
|
+
"src/**/*.spec.jsx",
|
|
3285
|
+
"src/**/*.test.jsx",
|
|
3286
|
+
"vite.config.ts",
|
|
3287
|
+
"vite.config.mts",
|
|
3288
|
+
"vitest.config.ts",
|
|
3289
|
+
"vitest.config.mts"
|
|
3290
|
+
],
|
|
3291
|
+
"include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"]
|
|
3292
|
+
}
|
|
3293
|
+
"
|
|
3294
|
+
`;
|
|
3295
|
+
|
|
3296
|
+
exports[`react-website generator > Tanstack router integration > should generate website with router correctly > test-app/tsconfig.json 1`] = `
|
|
3297
|
+
"{
|
|
3298
|
+
"files": [],
|
|
3299
|
+
"include": [],
|
|
3300
|
+
"references": [
|
|
3301
|
+
{
|
|
3302
|
+
"path": "./tsconfig.app.json"
|
|
3303
|
+
},
|
|
3304
|
+
{
|
|
3305
|
+
"path": "./tsconfig.spec.json"
|
|
3306
|
+
}
|
|
3307
|
+
],
|
|
3308
|
+
"extends": "../tsconfig.base.json",
|
|
3309
|
+
"compilerOptions": {
|
|
3310
|
+
"moduleResolution": "Bundler",
|
|
3311
|
+
"module": "Preserve"
|
|
3312
|
+
}
|
|
3313
|
+
}
|
|
3314
|
+
"
|
|
3315
|
+
`;
|
|
3316
|
+
|
|
3317
|
+
exports[`react-website generator > Tanstack router integration > should generate website with router correctly > test-app/tsconfig.spec.json 1`] = `
|
|
3318
|
+
"{
|
|
3319
|
+
"extends": "../tsconfig.base.json",
|
|
3320
|
+
"compilerOptions": {
|
|
3321
|
+
"outDir": "./out-tsc/vitest",
|
|
3322
|
+
"types": [
|
|
3323
|
+
"vitest/globals",
|
|
3324
|
+
"vitest/importMeta",
|
|
3325
|
+
"vite/client",
|
|
3326
|
+
"node",
|
|
3327
|
+
"vitest",
|
|
3328
|
+
"@nx/react/typings/cssmodule.d.ts",
|
|
3329
|
+
"@nx/react/typings/image.d.ts"
|
|
3330
|
+
]
|
|
3331
|
+
},
|
|
3332
|
+
"include": [
|
|
3333
|
+
"vite.config.ts",
|
|
3334
|
+
"vite.config.mts",
|
|
3335
|
+
"vitest.config.ts",
|
|
3336
|
+
"vitest.config.mts",
|
|
3337
|
+
"src/**/*.test.ts",
|
|
3338
|
+
"src/**/*.spec.ts",
|
|
3339
|
+
"src/**/*.test.tsx",
|
|
3340
|
+
"src/**/*.spec.tsx",
|
|
3341
|
+
"src/**/*.test.js",
|
|
3342
|
+
"src/**/*.spec.js",
|
|
3343
|
+
"src/**/*.test.jsx",
|
|
3344
|
+
"src/**/*.spec.jsx",
|
|
3345
|
+
"src/**/*.d.ts"
|
|
3346
|
+
],
|
|
3347
|
+
"references": [
|
|
3348
|
+
{
|
|
3349
|
+
"path": "./tsconfig.app.json"
|
|
3350
|
+
}
|
|
3351
|
+
]
|
|
3352
|
+
}
|
|
3353
|
+
"
|
|
3354
|
+
`;
|
|
3355
|
+
|
|
3356
|
+
exports[`react-website generator > Tanstack router integration > should generate website with router correctly > test-app/vite.config.ts 1`] = `
|
|
3357
|
+
"import tailwindcss from '@tailwindcss/vite';
|
|
3358
|
+
import tsconfigPaths from 'vite-tsconfig-paths';
|
|
3359
|
+
import { resolve } from 'path';
|
|
3360
|
+
import { tanstackRouter } from '@tanstack/router-plugin/vite';
|
|
3361
|
+
/// <reference types='vitest' />
|
|
3362
|
+
import { defineConfig } from 'vite';
|
|
3363
|
+
import react from '@vitejs/plugin-react';
|
|
3364
|
+
|
|
3365
|
+
export default defineConfig(() => ({
|
|
3366
|
+
define: {
|
|
3367
|
+
global: {},
|
|
3368
|
+
},
|
|
3369
|
+
root: __dirname,
|
|
3370
|
+
cacheDir: '../node_modules/.vite/test-app',
|
|
3371
|
+
server: {
|
|
3372
|
+
port: 4200,
|
|
3373
|
+
host: 'localhost',
|
|
3374
|
+
},
|
|
3375
|
+
preview: {
|
|
3376
|
+
port: 4300,
|
|
3377
|
+
host: 'localhost',
|
|
3378
|
+
},
|
|
3379
|
+
plugins: [
|
|
3380
|
+
tanstackRouter({
|
|
3381
|
+
routesDirectory: resolve(__dirname, 'src/routes'),
|
|
3382
|
+
generatedRouteTree: resolve(__dirname, 'src/routeTree.gen.ts'),
|
|
3383
|
+
}),
|
|
3384
|
+
react(),
|
|
3385
|
+
tailwindcss(),
|
|
3386
|
+
tsconfigPaths(),
|
|
3387
|
+
],
|
|
3388
|
+
build: {
|
|
3389
|
+
outDir: '../dist/test-app',
|
|
3390
|
+
emptyOutDir: true,
|
|
3391
|
+
reportCompressedSize: true,
|
|
3392
|
+
commonjsOptions: {
|
|
3393
|
+
transformMixedEsModules: true,
|
|
3394
|
+
},
|
|
3395
|
+
},
|
|
3396
|
+
test: {
|
|
3397
|
+
watch: false,
|
|
3398
|
+
globals: true,
|
|
3399
|
+
environment: 'jsdom',
|
|
3400
|
+
include: ['{src,tests}/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
|
3401
|
+
reporters: ['default'],
|
|
3402
|
+
coverage: {
|
|
3403
|
+
reportsDirectory: './test-output/vitest/coverage',
|
|
3404
|
+
provider: 'v8' as const,
|
|
3405
|
+
},
|
|
3406
|
+
passWithNoTests: true,
|
|
3407
|
+
},
|
|
3408
|
+
}));
|
|
3409
|
+
"
|
|
3410
|
+
`;
|
|
3411
|
+
|
|
3412
|
+
exports[`react-website generator > Tanstack router integration > should generate website with router correctly > tsconfig.base.json 1`] = `
|
|
3413
|
+
"{
|
|
3414
|
+
"compilerOptions": {
|
|
3415
|
+
"paths": {
|
|
3416
|
+
":proj/common-types": ["packages/common/types/src/index.ts"],
|
|
3417
|
+
":proj/test-app": ["test-app/src/index.ts"],
|
|
3418
|
+
":proj/common-constructs": ["packages/common/constructs/src/index.ts"]
|
|
3419
|
+
},
|
|
3420
|
+
"baseUrl": ".",
|
|
3421
|
+
"rootDir": "."
|
|
3422
|
+
}
|
|
3423
|
+
}
|
|
3424
|
+
"
|
|
3425
|
+
`;
|
|
3426
|
+
|
|
3427
|
+
exports[`react-website generator > Tanstack router integration > should generate website with router correctly > tsconfig.json 1`] = `
|
|
3428
|
+
"{
|
|
3429
|
+
"references": [
|
|
3430
|
+
{
|
|
3431
|
+
"path": "./test-app"
|
|
3432
|
+
},
|
|
3433
|
+
{
|
|
3434
|
+
"path": "./packages/common/types"
|
|
3435
|
+
},
|
|
3436
|
+
{
|
|
3437
|
+
"path": "./packages/common/constructs"
|
|
3438
|
+
}
|
|
3439
|
+
]
|
|
3440
|
+
}
|
|
3441
|
+
"
|
|
3442
|
+
`;
|
|
3443
|
+
|
|
3444
|
+
exports[`react-website generator > Tanstack router integration > should generate website with router correctly > vitest.workspace.ts 1`] = `
|
|
3445
|
+
"export default [
|
|
3446
|
+
'**/vite.config.{mjs,js,ts,mts}',
|
|
3447
|
+
'**/vitest.config.{mjs,js,ts,mts}',
|
|
3448
|
+
];
|
|
3449
|
+
"
|
|
3450
|
+
`;
|
|
3451
|
+
|
|
3452
|
+
exports[`react-website generator > should configure TypeScript correctly > tsconfig.json 1`] = `
|
|
3453
|
+
{
|
|
3454
|
+
"compilerOptions": {
|
|
3455
|
+
"module": "Preserve",
|
|
3456
|
+
"moduleResolution": "Bundler",
|
|
3457
|
+
},
|
|
3458
|
+
"extends": "../tsconfig.base.json",
|
|
3459
|
+
"files": [],
|
|
3460
|
+
"include": [],
|
|
3461
|
+
"references": [
|
|
3462
|
+
{
|
|
3463
|
+
"path": "./tsconfig.app.json",
|
|
3464
|
+
},
|
|
3465
|
+
{
|
|
3466
|
+
"path": "./tsconfig.spec.json",
|
|
3467
|
+
},
|
|
3468
|
+
],
|
|
3469
|
+
}
|
|
3470
|
+
`;
|
|
3471
|
+
|
|
3472
|
+
exports[`react-website generator > should configure vite correctly > vite.config.ts 1`] = `
|
|
3473
|
+
"import tailwindcss from '@tailwindcss/vite';
|
|
3474
|
+
import tsconfigPaths from 'vite-tsconfig-paths';
|
|
3475
|
+
import { resolve } from 'path';
|
|
3476
|
+
import { tanstackRouter } from '@tanstack/router-plugin/vite';
|
|
3477
|
+
/// <reference types='vitest' />
|
|
3478
|
+
import { defineConfig } from 'vite';
|
|
3479
|
+
import react from '@vitejs/plugin-react';
|
|
3480
|
+
|
|
3481
|
+
export default defineConfig(() => ({
|
|
3482
|
+
define: {
|
|
3483
|
+
global: {},
|
|
3484
|
+
},
|
|
3485
|
+
root: __dirname,
|
|
3486
|
+
cacheDir: '../node_modules/.vite/test-app',
|
|
3487
|
+
server: {
|
|
3488
|
+
port: 4200,
|
|
3489
|
+
host: 'localhost',
|
|
3490
|
+
},
|
|
3491
|
+
preview: {
|
|
3492
|
+
port: 4300,
|
|
3493
|
+
host: 'localhost',
|
|
3494
|
+
},
|
|
3495
|
+
plugins: [
|
|
3496
|
+
tanstackRouter({
|
|
3497
|
+
routesDirectory: resolve(__dirname, 'src/routes'),
|
|
3498
|
+
generatedRouteTree: resolve(__dirname, 'src/routeTree.gen.ts'),
|
|
3499
|
+
}),
|
|
3500
|
+
react(),
|
|
3501
|
+
tailwindcss(),
|
|
3502
|
+
tsconfigPaths(),
|
|
3503
|
+
],
|
|
3504
|
+
build: {
|
|
3505
|
+
outDir: '../dist/test-app',
|
|
3506
|
+
emptyOutDir: true,
|
|
3507
|
+
reportCompressedSize: true,
|
|
3508
|
+
commonjsOptions: {
|
|
3509
|
+
transformMixedEsModules: true,
|
|
3510
|
+
},
|
|
3511
|
+
},
|
|
3512
|
+
test: {
|
|
3513
|
+
watch: false,
|
|
3514
|
+
globals: true,
|
|
3515
|
+
environment: 'jsdom',
|
|
3516
|
+
include: ['{src,tests}/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
|
3517
|
+
reporters: ['default'],
|
|
3518
|
+
coverage: {
|
|
3519
|
+
reportsDirectory: './test-output/vitest/coverage',
|
|
3520
|
+
provider: 'v8' as const,
|
|
3521
|
+
},
|
|
3522
|
+
passWithNoTests: true,
|
|
3523
|
+
},
|
|
3524
|
+
}));
|
|
3525
|
+
"
|
|
3526
|
+
`;
|
|
3527
|
+
|
|
3528
|
+
exports[`react-website generator > should generate base files and structure > app-layout.tsx 1`] = `
|
|
3529
|
+
"import * as React from 'react';
|
|
3530
|
+
import { createContext, useCallback, useEffect, useState } from 'react';
|
|
3531
|
+
import Config from '../../config';
|
|
3532
|
+
|
|
3533
|
+
import {
|
|
3534
|
+
BreadcrumbGroup,
|
|
3535
|
+
BreadcrumbGroupProps,
|
|
3536
|
+
SideNavigation,
|
|
3537
|
+
TopNavigation,
|
|
3538
|
+
} from '@cloudscape-design/components';
|
|
3539
|
+
import CloudscapeAppLayout, {
|
|
3540
|
+
AppLayoutProps,
|
|
3541
|
+
} from '@cloudscape-design/components/app-layout';
|
|
3542
|
+
import { matchByPath, useLocation, useNavigate } from '@tanstack/react-router';
|
|
3543
|
+
|
|
3544
|
+
const getBreadcrumbs = (
|
|
3545
|
+
pathName: string,
|
|
3546
|
+
search: string,
|
|
3547
|
+
defaultBreadcrumb: string,
|
|
3548
|
+
availableRoutes?: string[],
|
|
3549
|
+
) => {
|
|
3550
|
+
const segments = [
|
|
3551
|
+
defaultBreadcrumb,
|
|
3552
|
+
...pathName.split('/').filter((segment) => segment !== ''),
|
|
3553
|
+
];
|
|
3554
|
+
|
|
3555
|
+
return segments.map((segment, i) => {
|
|
3556
|
+
const href =
|
|
3557
|
+
i === 0
|
|
3558
|
+
? '/'
|
|
3559
|
+
: \`/\${segments
|
|
3560
|
+
.slice(1, i + 1)
|
|
3561
|
+
.join('/')
|
|
3562
|
+
.replace('//', '/')}\`;
|
|
3563
|
+
|
|
3564
|
+
const matched =
|
|
3565
|
+
!availableRoutes || availableRoutes.find((r) => matchByPath(r, href, {}));
|
|
3566
|
+
|
|
3567
|
+
return {
|
|
3568
|
+
href: matched ? \`\${href}\${search}\` : '#',
|
|
3569
|
+
text: segment,
|
|
3570
|
+
};
|
|
3571
|
+
});
|
|
3572
|
+
};
|
|
3573
|
+
|
|
3574
|
+
export interface AppLayoutContext {
|
|
3575
|
+
appLayoutProps: AppLayoutProps;
|
|
3576
|
+
setAppLayoutProps: (props: AppLayoutProps) => void;
|
|
3577
|
+
displayHelpPanel: (helpContent: React.ReactNode) => void;
|
|
3578
|
+
}
|
|
3579
|
+
|
|
3580
|
+
/**
|
|
3581
|
+
* Context for updating/retrieving the AppLayout.
|
|
3582
|
+
*/
|
|
3583
|
+
export const AppLayoutContext = createContext({
|
|
3584
|
+
appLayoutProps: {},
|
|
3585
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
3586
|
+
setAppLayoutProps: (_: AppLayoutProps) => {},
|
|
3587
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
3588
|
+
displayHelpPanel: (_: React.ReactNode) => {},
|
|
3589
|
+
});
|
|
3590
|
+
|
|
3591
|
+
/**
|
|
3592
|
+
* Defines the App layout and contains logic for routing.
|
|
3593
|
+
*/
|
|
3594
|
+
const AppLayout: React.FC<React.PropsWithChildren> = ({ children }) => {
|
|
3595
|
+
const appLayout = React.useRef<AppLayoutProps.Ref>(null);
|
|
3596
|
+
const [appLayoutProps, setAppLayoutProps] = useState<AppLayoutProps>({});
|
|
3597
|
+
const setAppLayoutPropsSafe = useCallback(
|
|
3598
|
+
(props: AppLayoutProps) => {
|
|
3599
|
+
JSON.stringify(appLayoutProps) !== JSON.stringify(props) &&
|
|
3600
|
+
setAppLayoutProps(props);
|
|
3601
|
+
},
|
|
3602
|
+
[appLayoutProps],
|
|
3603
|
+
);
|
|
3604
|
+
|
|
3605
|
+
const navigate = useNavigate();
|
|
3606
|
+
const [activeBreadcrumbs, setActiveBreadcrumbs] = useState<
|
|
3607
|
+
BreadcrumbGroupProps.Item[]
|
|
3608
|
+
>([{ text: '/', href: '/' }]);
|
|
3609
|
+
const { pathname, search } = useLocation();
|
|
3610
|
+
|
|
3611
|
+
useEffect(() => {
|
|
3612
|
+
const breadcrumbs = getBreadcrumbs(
|
|
3613
|
+
pathname,
|
|
3614
|
+
Object.entries(search).reduce((p, [k, v]) => p + \`\${k}=\${v}\`, ''),
|
|
3615
|
+
'/',
|
|
3616
|
+
);
|
|
3617
|
+
setActiveBreadcrumbs(breadcrumbs);
|
|
3618
|
+
}, [pathname, search]);
|
|
3619
|
+
|
|
3620
|
+
const onNavigate = useCallback(
|
|
3621
|
+
(e: CustomEvent<{ href: string; external?: boolean }>) => {
|
|
3622
|
+
if (!e.detail.external) {
|
|
3623
|
+
e.preventDefault();
|
|
3624
|
+
setAppLayoutPropsSafe({
|
|
3625
|
+
contentType: undefined,
|
|
3626
|
+
});
|
|
3627
|
+
navigate({ to: e.detail.href });
|
|
3628
|
+
}
|
|
3629
|
+
},
|
|
3630
|
+
[navigate, setAppLayoutPropsSafe],
|
|
3631
|
+
);
|
|
3632
|
+
|
|
3633
|
+
return (
|
|
3634
|
+
<AppLayoutContext.Provider
|
|
3635
|
+
value={{
|
|
3636
|
+
appLayoutProps,
|
|
3637
|
+
setAppLayoutProps: setAppLayoutPropsSafe,
|
|
3638
|
+
displayHelpPanel: (helpContent: React.ReactNode) => {
|
|
3639
|
+
setAppLayoutPropsSafe({ tools: helpContent, toolsHide: false });
|
|
3640
|
+
appLayout.current?.openTools();
|
|
3641
|
+
},
|
|
3642
|
+
}}
|
|
3643
|
+
>
|
|
3644
|
+
<TopNavigation
|
|
3645
|
+
identity={{
|
|
3646
|
+
href: '/',
|
|
3647
|
+
title: Config.applicationName,
|
|
3648
|
+
logo: {
|
|
3649
|
+
src: Config.logo,
|
|
3650
|
+
},
|
|
3651
|
+
}}
|
|
3652
|
+
/>
|
|
3653
|
+
<CloudscapeAppLayout
|
|
3654
|
+
ref={appLayout}
|
|
3655
|
+
breadcrumbs={
|
|
3656
|
+
<BreadcrumbGroup onFollow={onNavigate} items={activeBreadcrumbs} />
|
|
3657
|
+
}
|
|
3658
|
+
navigation={
|
|
3659
|
+
<SideNavigation
|
|
3660
|
+
header={{ text: Config.applicationName, href: '/' }}
|
|
3661
|
+
activeHref={pathname}
|
|
3662
|
+
onFollow={onNavigate}
|
|
3663
|
+
items={[{ text: 'Home', type: 'link', href: '/' }]}
|
|
3664
|
+
/>
|
|
3665
|
+
}
|
|
3666
|
+
toolsHide
|
|
3667
|
+
content={children}
|
|
3668
|
+
{...appLayoutProps}
|
|
3669
|
+
/>
|
|
3670
|
+
</AppLayoutContext.Provider>
|
|
3671
|
+
);
|
|
3672
|
+
};
|
|
3673
|
+
|
|
3674
|
+
export default AppLayout;
|
|
3675
|
+
"
|
|
3676
|
+
`;
|
|
3677
|
+
|
|
3678
|
+
exports[`react-website generator > should generate base files and structure > config.ts 1`] = `
|
|
3679
|
+
"export default {
|
|
3680
|
+
applicationName: 'test-app',
|
|
3681
|
+
logo: 'data:image/svg+xml;base64,PCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj4KDTwhLS0gVXBsb2FkZWQgdG86IFNWRyBSZXBvLCB3d3cuc3ZncmVwby5jb20sIFRyYW5zZm9ybWVkIGJ5OiBTVkcgUmVwbyBNaXhlciBUb29scyAtLT4KPHN2ZyBmaWxsPSIjMjQ4YmFlIiB3aWR0aD0iODAwcHgiIGhlaWdodD0iODAwcHgiIHZpZXdCb3g9IjAgMCA1MTIgNTEyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHN0cm9rZT0iIzI0OGJhZSI+Cg08ZyBpZD0iU1ZHUmVwb19iZ0NhcnJpZXIiIHN0cm9rZS13aWR0aD0iMCIvPgoNPGcgaWQ9IlNWR1JlcG9fdHJhY2VyQ2FycmllciIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+Cg08ZyBpZD0iU1ZHUmVwb19pY29uQ2FycmllciI+Cg08dGl0bGU+aW9uaWNvbnMtdjVfbG9nb3M8L3RpdGxlPgoNPHBhdGggZD0iTTQxMC42NiwxODAuNzJoMHEtNy42Ny0yLjYyLTE1LjQ1LTQuODgsMS4yOS01LjI1LDIuMzgtMTAuNTZjMTEuNy01Ni45LDQuMDUtMTAyLjc0LTIyLjA2LTExNy44My0yNS0xNC40OC02NiwuNjEtMTA3LjM2LDM2LjY5cS02LjEsNS4zNC0xMS45NSwxMS0zLjktMy43Ni04LTcuMzZjLTQzLjM1LTM4LjU4LTg2LjgtNTQuODMtMTEyLjg4LTM5LjY5LTI1LDE0LjUxLTMyLjQzLDU3LjYtMjEuOSwxMTEuNTNxMS41OCw4LDMuNTUsMTUuOTNjLTYuMTUsMS43NS0xMi4wOSwzLjYyLTE3Ljc3LDUuNkM0OC40NiwxOTguOSwxNiwyMjYuNzMsMTYsMjU1LjU5YzAsMjkuODIsMzQuODQsNTkuNzIsODcuNzcsNzcuODVxNi40NCwyLjE5LDEzLDQuMDdRMTE0LjY0LDM0NiwxMTMsMzU0LjY4Yy0xMCw1My0yLjIsOTUuMDcsMjIuNzUsMTA5LjQ5LDI1Ljc3LDE0Ljg5LDY5LS40MSwxMTEuMTQtMzcuMzFxNS00LjM4LDEwLTkuMjUsNi4zMiw2LjExLDEzLDExLjg2YzQwLjgsMzUuMTgsODEuMDksNDkuMzksMTA2LDM0LjkzLDI1Ljc1LTE0Ljk0LDM0LjEyLTYwLjE0LDIzLjI1LTExNS4xM3EtMS4yNS02LjMtMi44OC0xMi44Niw0LjU2LTEuMzUsOC45My0yLjc5YzU1LTE4LjI3LDkwLjgzLTQ3LjgxLDkwLjgzLTc4QzQ5NiwyMjYuNjIsNDYyLjUsMTk4LjYxLDQxMC42NiwxODAuNzJabS0xMjktODEuMDhjMzUuNDMtMzAuOTEsNjguNTUtNDMuMTEsODMuNjUtMzQuMzloMGMxNi4wNyw5LjI5LDIyLjMyLDQ2Ljc1LDEyLjIyLDk1Ljg4cS0xLDQuOC0yLjE2LDkuNTdhNDg3LjgzLDQ4Ny44MywwLDAsMC02NC4xOC0xMC4xNiw0ODEuMjcsNDgxLjI3LDAsMCwwLTQwLjU3LTUwLjc1UTI3NiwxMDQuNTcsMjgxLjY0LDk5LjY0Wk0xNTcuNzMsMjgwLjI1cTYuNTEsMTIuNiwxMy42MSwyNC44OSw3LjIzLDEyLjU0LDE1LjA3LDI0LjcxYTQzNS4yOCw0MzUuMjgsMCwwLDEtNDQuMjQtNy4xM0MxNDYuNDEsMzA5LDE1MS42MywyOTQuNzUsMTU3LjczLDI4MC4yNVptMC00OC4zM2MtNi0xNC4xOS0xMS4wOC0yOC4xNS0xNS4yNS00MS42MywxMy43LTMuMDcsMjguMy01LjU4LDQzLjUyLTcuNDhxLTcuNjUsMTEuOTQtMTQuNzIsMjQuMjNUMTU3LjcsMjMxLjkyWm0xMC45LDI0LjE3cTkuNDgtMTkuNzcsMjAuNDItMzguNzhoMHExMC45My0xOSwyMy4yNy0zNy4xM2MxNC4yOC0xLjA4LDI4LjkyLTEuNjUsNDMuNzEtMS42NXMyOS41Mi41Nyw0My43OSwxLjY2cTEyLjIxLDE4LjA5LDIzLjEzLDM3dDIwLjY5LDM4LjZRMzM0LDI3NS42MywzMjMsMjk0LjczaDBxLTEwLjkxLDE5LTIzLDM3LjI0Yy0xNC4yNSwxLTI5LDEuNTUtNDQsMS41NXMtMjkuNDctLjQ3LTQzLjQ2LTEuMzhxLTEyLjQzLTE4LjE5LTIzLjQ2LTM3LjI5VDE2OC42LDI1Ni4wOVpNMzQwLjc1LDMwNXE3LjI1LTEyLjU4LDEzLjkyLTI1LjQ5aDBhNDQwLjQxLDQ0MC40MSwwLDAsMSwxNi4xMiw0Mi4zMkE0MzQuNDQsNDM0LjQ0LDAsMCwxLDMyNiwzMjkuNDhRMzMzLjYyLDMxNy4zOSwzNDAuNzUsMzA1Wm0xMy43Mi03My4wN3EtNi42NC0xMi42NS0xMy44MS0yNWgwcS03LTEyLjE4LTE0LjU5LTI0LjA2YzE1LjMxLDEuOTQsMzAsNC41Miw0My43Nyw3LjY3QTQzOS44OSw0MzkuODksMCwwLDEsMzU0LjQ3LDIzMS45M1pNMjU2LjIzLDEyNC40OGgwYTQzOS43NSw0MzkuNzUsMCwwLDEsMjguMjUsMzQuMThxLTI4LjM1LTEuMzUtNTYuNzQsMEMyMzcuMDcsMTQ2LjMyLDI0Ni42MiwxMzQuODcsMjU2LjIzLDEyNC40OFpNMTQ1LjY2LDY1Ljg2YzE2LjA2LTkuMzIsNTEuNTcsNCw4OSwzNy4yNywyLjM5LDIuMTMsNC44LDQuMzYsNy4yLDYuNjdBNDkxLjM3LDQ5MS4zNywwLDAsMCwyMDEsMTYwLjUxYTQ5OS4xMiw0OTkuMTIsMCwwLDAtNjQuMDYsMTBxLTEuODMtNy4zNi0zLjMtMTQuODJoMEMxMjQuNTksMTA5LjQ2LDEzMC41OCw3NC42MSwxNDUuNjYsNjUuODZaTTEyMi4yNSwzMTcuNzFxLTYtMS43MS0xMS44NS0zLjcxYy0yMy40LTgtNDIuNzMtMTguNDQtNTYtMjkuODFDNDIuNTIsMjc0LDM2LjUsMjYzLjgzLDM2LjUsMjU1LjU5YzAtMTcuNTEsMjYuMDYtMzkuODUsNjkuNTItNTVxOC4xOS0yLjg1LDE2LjUyLTUuMjFhNDkzLjU0LDQ5My41NCwwLDAsMCwyMy40LDYwLjc1QTUwMi40Niw1MDIuNDYsMCwwLDAsMTIyLjI1LDMxNy43MVptMTExLjEzLDkzLjY3Yy0xOC42MywxNi4zMi0zNy4yOSwyNy44OS01My43NCwzMy43MmgwYy0xNC43OCw1LjIzLTI2LjU1LDUuMzgtMzMuNjYsMS4yNy0xNS4xNC04Ljc1LTIxLjQ0LTQyLjU0LTEyLjg1LTg3Ljg2cTEuNTMtOCwzLjUtMTZhNDgwLjg1LDQ4MC44NSwwLDAsMCw2NC42OSw5LjM5LDUwMS4yLDUwMS4yLDAsMCwwLDQxLjIsNTFDMjM5LjU0LDQwNS44MywyMzYuNDksNDA4LjY1LDIzMy4zOCw0MTEuMzhabTIzLjQyLTIzLjIyYy05LjcyLTEwLjUxLTE5LjQyLTIyLjE0LTI4Ljg4LTM0LjY0cTEzLjc5LjU0LDI4LjA4LjU0YzkuNzgsMCwxOS40Ni0uMjEsMjktLjY0QTQzOS4zMyw0MzkuMzMsMCwwLDEsMjU2LjgsMzg4LjE2Wm0xMjQuNTIsMjguNTljLTIuODYsMTUuNDQtOC42MSwyNS43NC0xNS43MiwyOS44Ni0xNS4xMyw4Ljc4LTQ3LjQ4LTIuNjMtODIuMzYtMzIuNzItNC0zLjQ0LTgtNy4xMy0xMi4wNy0xMWE0ODQuNTQsNDg0LjU0LDAsMCwwLDQwLjIzLTUxLjIsNDc3Ljg0LDQ3Ny44NCwwLDAsMCw2NS0xMC4wNXExLjQ3LDUuOTQsMi42LDExLjY0aDBDMzgzLjgxLDM3Ny41OCwzODQuNSwzOTkuNTYsMzgxLjMyLDQxNi43NVptMTcuNC0xMDIuNjRoMGMtMi42Mi44Ny01LjMyLDEuNzEtOC4wNiwyLjUzYTQ4My4yNiw0ODMuMjYsMCwwLDAtMjQuMzEtNjAuOTQsNDgxLjUyLDQ4MS41MiwwLDAsMCwyMy4zNi02MC4wNmM0LjkxLDEuNDMsOS42OCwyLjkzLDE0LjI3LDQuNTIsNDQuNDIsMTUuMzIsNzEuNTIsMzgsNzEuNTIsNTUuNDNDNDc1LjUsMjc0LjE5LDQ0Ni4yMywyOTguMzMsMzk4LjcyLDMxNC4xMVoiLz4KDTxwYXRoIGQ9Ik0yNTYsMjk4LjU1YTQzLDQzLDAsMSwwLTQyLjg2LTQzQTQyLjkxLDQyLjkxLDAsMCwwLDI1NiwyOTguNTVaIi8+Cg08L2c+Cg08L3N2Zz4=',
|
|
3682
|
+
};
|
|
3683
|
+
"
|
|
3684
|
+
`;
|
|
3685
|
+
|
|
3686
|
+
exports[`react-website generator > should generate base files and structure > index.tsx 1`] = `
|
|
3687
|
+
"import {
|
|
3688
|
+
ContentLayout,
|
|
3689
|
+
Header,
|
|
3690
|
+
SpaceBetween,
|
|
3691
|
+
Container,
|
|
3692
|
+
} from '@cloudscape-design/components';
|
|
3693
|
+
import { createFileRoute } from '@tanstack/react-router';
|
|
3694
|
+
|
|
3695
|
+
export const Route = createFileRoute('/')({
|
|
3696
|
+
component: RouteComponent,
|
|
3697
|
+
});
|
|
3698
|
+
|
|
3699
|
+
function RouteComponent() {
|
|
3700
|
+
return (
|
|
3701
|
+
<ContentLayout header={<Header>Welcome</Header>}>
|
|
3702
|
+
<SpaceBetween size="l">
|
|
3703
|
+
<Container>Welcome to your new React website!</Container>
|
|
3704
|
+
</SpaceBetween>
|
|
3705
|
+
</ContentLayout>
|
|
3706
|
+
);
|
|
3707
|
+
}
|
|
3708
|
+
"
|
|
3709
|
+
`;
|
|
3710
|
+
|
|
3711
|
+
exports[`react-website generator > should generate base files and structure > main.tsx 1`] = `
|
|
3712
|
+
"import React from 'react';
|
|
3713
|
+
import { createRoot } from 'react-dom/client';
|
|
3714
|
+
import { I18nProvider } from '@cloudscape-design/components/i18n';
|
|
3715
|
+
import messages from '@cloudscape-design/components/i18n/messages/all.en';
|
|
3716
|
+
import '@cloudscape-design/global-styles/index.css';
|
|
3717
|
+
import { RouterProvider, createRouter } from '@tanstack/react-router';
|
|
3718
|
+
import { routeTree } from './routeTree.gen';
|
|
3719
|
+
|
|
3720
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
3721
|
+
export type RouterProviderContext = {};
|
|
3722
|
+
|
|
3723
|
+
const router = createRouter({
|
|
3724
|
+
routeTree,
|
|
3725
|
+
context: {},
|
|
3726
|
+
});
|
|
3727
|
+
|
|
3728
|
+
// Register the router instance for type safety
|
|
3729
|
+
declare module '@tanstack/react-router' {
|
|
3730
|
+
interface Register {
|
|
3731
|
+
router: typeof router;
|
|
3732
|
+
}
|
|
3733
|
+
}
|
|
3734
|
+
|
|
3735
|
+
const App = () => {
|
|
3736
|
+
return <RouterProvider router={router} context={{}} />;
|
|
3737
|
+
};
|
|
3738
|
+
|
|
3739
|
+
const root = document.getElementById('root');
|
|
3740
|
+
root &&
|
|
3741
|
+
createRoot(root).render(
|
|
3742
|
+
<React.StrictMode>
|
|
3743
|
+
<I18nProvider locale="en" messages={[messages]}>
|
|
3744
|
+
<App />
|
|
3745
|
+
</I18nProvider>
|
|
3746
|
+
</React.StrictMode>,
|
|
3747
|
+
);
|
|
3748
|
+
"
|
|
3749
|
+
`;
|
|
3750
|
+
|
|
3751
|
+
exports[`react-website generator > should generate shared constructs > common/constructs-app-index.ts 1`] = `
|
|
3752
|
+
"export * from './test-app.js';
|
|
3753
|
+
"
|
|
3754
|
+
`;
|
|
3755
|
+
|
|
3756
|
+
exports[`react-website generator > should generate shared constructs > common/constructs-core-index.ts 1`] = `
|
|
3757
|
+
"export * from './static-website.js';
|
|
3758
|
+
export * from './app.js';
|
|
3759
|
+
export * from './runtime-config.js';
|
|
3760
|
+
"
|
|
3761
|
+
`;
|
|
3762
|
+
|
|
3763
|
+
exports[`react-website generator > should generate shared constructs > common/constructs-core-static-website.ts 1`] = `
|
|
3764
|
+
"import { CfnJson, CfnOutput, RemovalPolicy, Stack, Token } from 'aws-cdk-lib';
|
|
3765
|
+
import { Distribution, ViewerProtocolPolicy } from 'aws-cdk-lib/aws-cloudfront';
|
|
3766
|
+
import { S3BucketOrigin } from 'aws-cdk-lib/aws-cloudfront-origins';
|
|
3767
|
+
import {
|
|
3768
|
+
BlockPublicAccess,
|
|
3769
|
+
Bucket,
|
|
3770
|
+
BucketEncryption,
|
|
3771
|
+
IBucket,
|
|
3772
|
+
ObjectOwnership,
|
|
3773
|
+
} from 'aws-cdk-lib/aws-s3';
|
|
3774
|
+
import { BucketDeployment, Source } from 'aws-cdk-lib/aws-s3-deployment';
|
|
3775
|
+
import { Construct } from 'constructs';
|
|
3776
|
+
import { RuntimeConfig } from './runtime-config.js';
|
|
3777
|
+
import { Key } from 'aws-cdk-lib/aws-kms';
|
|
3778
|
+
import { CfnWebACL } from 'aws-cdk-lib/aws-wafv2';
|
|
3779
|
+
const DEFAULT_RUNTIME_CONFIG_FILENAME = 'runtime-config.json';
|
|
3780
|
+
|
|
3781
|
+
export interface StaticWebsiteProps {
|
|
3782
|
+
readonly websiteFilePath: string;
|
|
3783
|
+
}
|
|
3784
|
+
|
|
3785
|
+
/**
|
|
3786
|
+
* Deploys a Static Website using by default a private S3 bucket as an origin and Cloudfront as the entrypoint.
|
|
3787
|
+
*
|
|
3788
|
+
* This construct configures a webAcl containing rules that are generally applicable to web applications. This
|
|
3789
|
+
* provides protection against exploitation of a wide range of vulnerabilities, including some of the high risk
|
|
3790
|
+
* and commonly occurring vulnerabilities described in OWASP publications such as OWASP Top 10.
|
|
3791
|
+
*
|
|
3792
|
+
*/
|
|
3793
|
+
export class StaticWebsite extends Construct {
|
|
3794
|
+
public readonly websiteBucket: IBucket;
|
|
3795
|
+
public readonly cloudFrontDistribution: Distribution;
|
|
3796
|
+
public readonly bucketDeployment: BucketDeployment;
|
|
3797
|
+
|
|
3798
|
+
constructor(
|
|
3799
|
+
scope: Construct,
|
|
3800
|
+
id: string,
|
|
3801
|
+
{ websiteFilePath }: StaticWebsiteProps,
|
|
3802
|
+
) {
|
|
3803
|
+
super(scope, id);
|
|
3804
|
+
this.node.setContext(
|
|
3805
|
+
'@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy',
|
|
3806
|
+
true,
|
|
3807
|
+
);
|
|
3808
|
+
|
|
3809
|
+
const websiteKey = new Key(this, 'WebsiteKey', {
|
|
3810
|
+
enableKeyRotation: true,
|
|
3811
|
+
});
|
|
3812
|
+
|
|
3813
|
+
const accessLogsBucket = new Bucket(this, 'AccessLogsBucket', {
|
|
3814
|
+
versioned: false,
|
|
3815
|
+
enforceSSL: true,
|
|
3816
|
+
autoDeleteObjects: true,
|
|
3817
|
+
removalPolicy: RemovalPolicy.DESTROY,
|
|
3818
|
+
encryption: BucketEncryption.KMS,
|
|
3819
|
+
encryptionKey: websiteKey,
|
|
3820
|
+
objectOwnership: ObjectOwnership.OBJECT_WRITER,
|
|
3821
|
+
publicReadAccess: false,
|
|
3822
|
+
blockPublicAccess: BlockPublicAccess.BLOCK_ALL,
|
|
3823
|
+
});
|
|
3824
|
+
// S3 Bucket to hold website files
|
|
3825
|
+
this.websiteBucket = new Bucket(this, 'WebsiteBucket', {
|
|
3826
|
+
versioned: true,
|
|
3827
|
+
enforceSSL: true,
|
|
3828
|
+
autoDeleteObjects: true,
|
|
3829
|
+
removalPolicy: RemovalPolicy.DESTROY,
|
|
3830
|
+
encryption: BucketEncryption.KMS,
|
|
3831
|
+
encryptionKey: websiteKey,
|
|
3832
|
+
objectOwnership: ObjectOwnership.BUCKET_OWNER_ENFORCED,
|
|
3833
|
+
publicReadAccess: false,
|
|
3834
|
+
blockPublicAccess: BlockPublicAccess.BLOCK_ALL,
|
|
3835
|
+
serverAccessLogsPrefix: 'website-access-logs',
|
|
3836
|
+
serverAccessLogsBucket: accessLogsBucket,
|
|
3837
|
+
});
|
|
3838
|
+
// Web ACL
|
|
3839
|
+
const wafStack = new CloudfrontWebAcl(this, 'waf');
|
|
3840
|
+
|
|
3841
|
+
// Cloudfront Distribution
|
|
3842
|
+
const logBucket = new Bucket(this, 'DistributionLogBucket', {
|
|
3843
|
+
enforceSSL: true,
|
|
3844
|
+
autoDeleteObjects: true,
|
|
3845
|
+
removalPolicy: RemovalPolicy.DESTROY,
|
|
3846
|
+
encryption: BucketEncryption.KMS,
|
|
3847
|
+
encryptionKey: websiteKey,
|
|
3848
|
+
objectOwnership: ObjectOwnership.BUCKET_OWNER_PREFERRED,
|
|
3849
|
+
publicReadAccess: false,
|
|
3850
|
+
blockPublicAccess: BlockPublicAccess.BLOCK_ALL,
|
|
3851
|
+
serverAccessLogsPrefix: 'distribution-access-logs',
|
|
3852
|
+
serverAccessLogsBucket: accessLogsBucket,
|
|
3853
|
+
});
|
|
3854
|
+
const defaultRootObject = 'index.html';
|
|
3855
|
+
this.cloudFrontDistribution = new Distribution(
|
|
3856
|
+
this,
|
|
3857
|
+
'CloudfrontDistribution',
|
|
3858
|
+
{
|
|
3859
|
+
webAclId: wafStack.wafArn,
|
|
3860
|
+
enableLogging: true,
|
|
3861
|
+
logBucket: logBucket,
|
|
3862
|
+
defaultBehavior: {
|
|
3863
|
+
origin: S3BucketOrigin.withOriginAccessControl(this.websiteBucket),
|
|
3864
|
+
viewerProtocolPolicy: ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
|
|
3865
|
+
},
|
|
3866
|
+
defaultRootObject,
|
|
3867
|
+
errorResponses: [
|
|
3868
|
+
{
|
|
3869
|
+
httpStatus: 404, // We need to redirect "key not found errors" to index.html for single page apps
|
|
3870
|
+
responseHttpStatus: 200,
|
|
3871
|
+
responsePagePath: \`/\${defaultRootObject}\`,
|
|
3872
|
+
},
|
|
3873
|
+
{
|
|
3874
|
+
httpStatus: 403, // We need to redirect reloads from paths (e.g. /foo/bar) to index.html for single page apps
|
|
3875
|
+
responseHttpStatus: 200,
|
|
3876
|
+
responsePagePath: \`/\${defaultRootObject}\`,
|
|
3877
|
+
},
|
|
3878
|
+
],
|
|
3879
|
+
},
|
|
3880
|
+
);
|
|
3881
|
+
// Deploy Website
|
|
3882
|
+
this.bucketDeployment = new BucketDeployment(this, 'WebsiteDeployment', {
|
|
3883
|
+
sources: [
|
|
3884
|
+
Source.asset(websiteFilePath),
|
|
3885
|
+
Source.jsonData(
|
|
3886
|
+
DEFAULT_RUNTIME_CONFIG_FILENAME,
|
|
3887
|
+
this.resolveTokens(RuntimeConfig.ensure(this).config),
|
|
3888
|
+
),
|
|
3889
|
+
],
|
|
3890
|
+
destinationBucket: this.websiteBucket,
|
|
3891
|
+
// Files in the distribution's edge caches will be invalidated after files are uploaded to the destination bucket.
|
|
3892
|
+
distribution: this.cloudFrontDistribution,
|
|
3893
|
+
memoryLimit: 1024,
|
|
3894
|
+
});
|
|
3895
|
+
new CfnOutput(this, 'DistributionDomainName', {
|
|
3896
|
+
value: this.cloudFrontDistribution.domainName,
|
|
3897
|
+
});
|
|
3898
|
+
new CfnOutput(this, 'WebsiteBucketName', {
|
|
3899
|
+
value: this.websiteBucket.bucketName,
|
|
3900
|
+
});
|
|
3901
|
+
}
|
|
3902
|
+
private resolveTokens = (payload: any) => {
|
|
3903
|
+
const _payload: Record<string, any> = {};
|
|
3904
|
+
Object.entries(payload).forEach(([key, value]) => {
|
|
3905
|
+
if (
|
|
3906
|
+
Token.isUnresolved(value) ||
|
|
3907
|
+
(typeof value === 'string' && value.endsWith('}}'))
|
|
3908
|
+
) {
|
|
3909
|
+
_payload[key] = new CfnJson(this, \`ResolveToken-\${key}\`, {
|
|
3910
|
+
value,
|
|
3911
|
+
}).value;
|
|
3912
|
+
} else if (typeof value === 'object') {
|
|
3913
|
+
_payload[key] = this.resolveTokens(value);
|
|
3914
|
+
} else if (Array.isArray(value)) {
|
|
3915
|
+
_payload[key] = value.map((v) => this.resolveTokens(v));
|
|
3916
|
+
} else {
|
|
3917
|
+
_payload[key] = value;
|
|
3918
|
+
}
|
|
3919
|
+
});
|
|
3920
|
+
return _payload;
|
|
3921
|
+
};
|
|
3922
|
+
}
|
|
3923
|
+
|
|
3924
|
+
export class CloudfrontWebAcl extends Stack {
|
|
3925
|
+
public readonly wafArn;
|
|
3926
|
+
constructor(scope: Construct, id: string) {
|
|
3927
|
+
super(scope, id, {
|
|
3928
|
+
env: {
|
|
3929
|
+
region: 'us-east-1',
|
|
3930
|
+
account: Stack.of(scope).account,
|
|
3931
|
+
},
|
|
3932
|
+
crossRegionReferences: true,
|
|
3933
|
+
});
|
|
3934
|
+
|
|
3935
|
+
this.wafArn = new CfnWebACL(this, 'WebAcl', {
|
|
3936
|
+
defaultAction: { allow: {} },
|
|
3937
|
+
scope: 'CLOUDFRONT',
|
|
3938
|
+
visibilityConfig: {
|
|
3939
|
+
cloudWatchMetricsEnabled: true,
|
|
3940
|
+
metricName: id,
|
|
3941
|
+
sampledRequestsEnabled: true,
|
|
3942
|
+
},
|
|
3943
|
+
rules: [
|
|
3944
|
+
{
|
|
3945
|
+
name: 'CRSRule',
|
|
3946
|
+
priority: 0,
|
|
3947
|
+
statement: {
|
|
3948
|
+
managedRuleGroupStatement: {
|
|
3949
|
+
name: 'AWSManagedRulesCommonRuleSet',
|
|
3950
|
+
vendorName: 'AWS',
|
|
3951
|
+
},
|
|
3952
|
+
},
|
|
3953
|
+
visibilityConfig: {
|
|
3954
|
+
cloudWatchMetricsEnabled: true,
|
|
3955
|
+
metricName: 'MetricForWebACLCDK-CRS',
|
|
3956
|
+
sampledRequestsEnabled: true,
|
|
3957
|
+
},
|
|
3958
|
+
overrideAction: {
|
|
3959
|
+
none: {},
|
|
3960
|
+
},
|
|
3961
|
+
},
|
|
3962
|
+
],
|
|
3963
|
+
}).attrArn;
|
|
3964
|
+
}
|
|
3965
|
+
}
|
|
3966
|
+
"
|
|
3967
|
+
`;
|
|
3968
|
+
|
|
3969
|
+
exports[`react-website generator > should generate shared constructs > test-app.ts 1`] = `
|
|
3970
|
+
"import * as url from 'url';
|
|
3971
|
+
import { Construct } from 'constructs';
|
|
3972
|
+
import { StaticWebsite } from '../../core/index.js';
|
|
3973
|
+
|
|
3974
|
+
export class TestApp extends StaticWebsite {
|
|
3975
|
+
constructor(scope: Construct, id: string) {
|
|
3976
|
+
super(scope, id, {
|
|
3977
|
+
websiteFilePath: url.fileURLToPath(
|
|
3978
|
+
new URL('../../../../../../dist/test-app/bundle', import.meta.url),
|
|
3979
|
+
),
|
|
3980
|
+
});
|
|
3981
|
+
}
|
|
3982
|
+
}
|
|
3983
|
+
"
|
|
3984
|
+
`;
|
|
3985
|
+
|
|
3986
|
+
exports[`react-website generator > should handle custom directory option > custom-dir-main.tsx 1`] = `
|
|
3987
|
+
"import React from 'react';
|
|
3988
|
+
import { createRoot } from 'react-dom/client';
|
|
3989
|
+
import { I18nProvider } from '@cloudscape-design/components/i18n';
|
|
3990
|
+
import messages from '@cloudscape-design/components/i18n/messages/all.en';
|
|
3991
|
+
import '@cloudscape-design/global-styles/index.css';
|
|
3992
|
+
import { RouterProvider, createRouter } from '@tanstack/react-router';
|
|
3993
|
+
import { routeTree } from './routeTree.gen';
|
|
3994
|
+
|
|
3995
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
|
3996
|
+
export type RouterProviderContext = {};
|
|
3997
|
+
|
|
3998
|
+
const router = createRouter({
|
|
3999
|
+
routeTree,
|
|
4000
|
+
context: {},
|
|
4001
|
+
});
|
|
4002
|
+
|
|
4003
|
+
// Register the router instance for type safety
|
|
4004
|
+
declare module '@tanstack/react-router' {
|
|
4005
|
+
interface Register {
|
|
4006
|
+
router: typeof router;
|
|
4007
|
+
}
|
|
4008
|
+
}
|
|
4009
|
+
|
|
4010
|
+
const App = () => {
|
|
4011
|
+
return <RouterProvider router={router} context={{}} />;
|
|
4012
|
+
};
|
|
4013
|
+
|
|
4014
|
+
const root = document.getElementById('root');
|
|
4015
|
+
root &&
|
|
4016
|
+
createRoot(root).render(
|
|
4017
|
+
<React.StrictMode>
|
|
4018
|
+
<I18nProvider locale="en" messages={[messages]}>
|
|
4019
|
+
<App />
|
|
4020
|
+
</I18nProvider>
|
|
4021
|
+
</React.StrictMode>,
|
|
4022
|
+
);
|
|
4023
|
+
"
|
|
4024
|
+
`;
|
|
4025
|
+
|
|
4026
|
+
exports[`react-website generator > should handle npm scope prefix correctly > scoped-dependencies 1`] = `
|
|
4027
|
+
{
|
|
4028
|
+
"@cloudscape-design/board-components": "^3.0.94",
|
|
4029
|
+
"@cloudscape-design/components": "^3.0.928",
|
|
4030
|
+
"@cloudscape-design/global-styles": "^1.0.38",
|
|
4031
|
+
"@tanstack/react-router": "^1.121.16",
|
|
4032
|
+
"aws-cdk-lib": "^2.200.0",
|
|
4033
|
+
"constructs": "^10.4.2",
|
|
4034
|
+
"react": "19.0.0",
|
|
4035
|
+
"react-dom": "19.0.0",
|
|
4036
|
+
"tailwindcss": "^4.1.11",
|
|
4037
|
+
}
|
|
4038
|
+
`;
|