create-jwn-js 1.0.30 → 1.0.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/index.js +9 -3
  2. package/package.json +3 -2
  3. package/{template-lambda-api-ts → template-lambda-http-api-ts}/package.json +3 -1
  4. package/template-lambda-http-api-ts/src/backend/index.mts +8 -0
  5. package/{template-lambda-api-ts → template-lambda-http-api-ts}/src/scripts/test.setup.mts +1 -1
  6. package/{template-lambda-api-ts → template-lambda-http-api-ts}/src/scripts/vitest.global.setup.mts +1 -1
  7. package/{template-lambda-api-ts → template-lambda-http-api-ts}/tsconfig.json +1 -0
  8. package/{template-lambda-api-ts → template-lambda-http-api-ts}/vite.config.mts +40 -44
  9. package/{template-lambda-api-ts → template-lambda-http-api-ts}/yarn.lock +27 -0
  10. package/template-lambda-rest-api-ts/.gitignore +5 -0
  11. package/template-lambda-rest-api-ts/index.mts +0 -0
  12. package/template-lambda-rest-api-ts/package.json +30 -0
  13. package/template-lambda-rest-api-ts/src/backend/__its__/handler.spec.mts +9 -0
  14. package/template-lambda-rest-api-ts/src/scripts/test.setup.mts +21 -0
  15. package/template-lambda-rest-api-ts/src/scripts/vitest.global.setup.mts +26 -0
  16. package/template-lambda-rest-api-ts/tsconfig.json +47 -0
  17. package/template-lambda-rest-api-ts/vite.config.mts +188 -0
  18. package/template-lambda-rest-api-ts/vitest.config.mts +40 -0
  19. package/template-lambda-rest-api-ts/vitest.config.production.mts +38 -0
  20. package/template-lambda-rest-api-ts/yarn-error.log +1889 -0
  21. package/{template-lambda-api-ts/dist → template-lambda-rest-api-ts}/yarn.lock +1011 -0
  22. package/{template-vite-vue3-ts → template-vite-node-ts}/connect.json +1 -10
  23. package/template-vite-node-ts/src/backend/server/helpers/createConfigServer.ts +1 -1
  24. package/template-vite-node-ts/yarn.lock +4 -4
  25. package/template-vite-vue3-ts/src/backend/server/helpers/createConfigServer.ts +1 -1
  26. package/template-lambda-api-ts/dist/index.mjs +0 -9
  27. package/template-lambda-api-ts/dist/package.json +0 -11
  28. package/template-vite-node-ts/connect.json5 +0 -20
  29. /package/{template-lambda-api-ts → template-lambda-http-api-ts}/.gitignore +0 -0
  30. /package/{template-lambda-api-ts → template-lambda-http-api-ts}/index.mts +0 -0
  31. /package/{template-lambda-api-ts → template-lambda-http-api-ts}/src/backend/__its__/handler.spec.mts +0 -0
  32. /package/{template-lambda-api-ts → template-lambda-http-api-ts}/vitest.config.mts +0 -0
  33. /package/{template-lambda-api-ts → template-lambda-http-api-ts}/vitest.config.production.mts +0 -0
  34. /package/{template-lambda-api-ts → template-lambda-http-api-ts}/yarn-error.log +0 -0
  35. /package/{template-lambda-api-ts → template-lambda-rest-api-ts}/src/backend/index.mts +0 -0
package/index.js CHANGED
@@ -5,6 +5,7 @@ const path = require('path')
5
5
  const margv = require('margv')
6
6
  const argv = margv();
7
7
  const prompts = require('prompts');
8
+ const json5 = require('json5');
8
9
 
9
10
  const {
10
11
  yellow,
@@ -40,7 +41,12 @@ const FRAMEWORKS = [
40
41
  color: yellow,
41
42
  variants: [
42
43
  {
43
- name: 'lambda-api-ts',
44
+ name: 'lambda-rest-api-ts',
45
+ display: 'TypeScript',
46
+ color: blue
47
+ },
48
+ {
49
+ name: 'lambda-http-api-ts',
44
50
  display: 'TypeScript',
45
51
  color: blue
46
52
  }
@@ -186,8 +192,8 @@ async function init() {
186
192
 
187
193
  // connect.json5
188
194
  if(fs.existsSync(path.join(templateDir, `connect-template.json5`))) {
189
- const connect = require(path.join(templateDir, `connect-template.json5`));
190
- write('connect.json5', JSON.stringify(connect, null, 2));
195
+ const connect = json5.parse(fs.readFileSync(path.join(templateDir, `connect-template.json5`)).toString());
196
+ write('connect.json5', json5.stringify(connect, null, 2));
191
197
  }
192
198
 
193
199
  // package.json
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-jwn-js",
3
- "version": "1.0.30",
3
+ "version": "1.0.32",
4
4
  "license": "PRIVATE",
5
5
  "author": "Webigorkiev",
6
6
  "bin": {
@@ -18,6 +18,7 @@
18
18
  },
19
19
  "homepage": "https://github.com/webigorkiev",
20
20
  "dependencies": {
21
+ "json5": "^2.2.3",
21
22
  "kolorist": "^1.5.0",
22
23
  "margv": "^1.1.2",
23
24
  "prompts": "^2.4.2"
@@ -33,7 +34,7 @@
33
34
  "jsdom": "^24.0.0",
34
35
  "memjs": "^1.3.2",
35
36
  "typescript": "^5.3.3",
36
- "vite": "4",
37
+ "vite": "5",
37
38
  "vitepress": "0.22.4",
38
39
  "vitest": "^1.2.2"
39
40
  }
@@ -10,10 +10,12 @@
10
10
  "serve": "vite",
11
11
  "build": "vite build && cd ./dist && yarn",
12
12
  "test": "vitest run",
13
- "test:production": "vitest run -c vitest.config.production.mts"
13
+ "test:production": "vitest run -c vitest.config.production.mts",
14
+ "deploy": "yarn build && cd dist && zip -r ../dist.zip ."
14
15
  },
15
16
  "devDependencies": {
16
17
  "@types/aws-lambda": "8",
18
+ "@types/fs-extra": "^11.0.4",
17
19
  "@types/node": "20",
18
20
  "chalk": "^5.3.0",
19
21
  "fs-extra": "^11.2.0",
@@ -0,0 +1,8 @@
1
+ import type { APIGatewayProxyEventV2, APIGatewayProxyResultV2 } from "aws-lambda";
2
+
3
+ export const handler = async (event: APIGatewayProxyEventV2): Promise<APIGatewayProxyResultV2> => {
4
+ return {
5
+ statusCode: 200,
6
+ body: JSON.stringify(event),
7
+ };
8
+ };
@@ -16,6 +16,6 @@ const defaultHeaders = {
16
16
  const fetchWrapper = async(
17
17
  input: RequestInfo,
18
18
  init: RequestInit = {}
19
- ) => crossFetch(input, Object.assign({}, defaultHeaders, init));
19
+ ) => fetch(input, Object.assign({}, defaultHeaders, init));
20
20
 
21
21
  export {fetchWrapper as fetch, testConfig};
@@ -1,5 +1,5 @@
1
1
  import {createServer, ViteDevServer} from "vite";
2
- import {testConfig} from "./test.setup";
2
+ import {testConfig} from "./test.setup.mts";
3
3
 
4
4
  declare global {
5
5
  var server: ViteDevServer;
@@ -17,6 +17,7 @@
17
17
  "strictPropertyInitialization": false,
18
18
  "experimentalDecorators": true,
19
19
  "emitDecoratorMetadata": true,
20
+ "allowImportingTsExtensions": true,
20
21
  "lib": [
21
22
  "esnext",
22
23
  "dom"
@@ -1,11 +1,10 @@
1
- import type { APIGatewayProxyEvent, APIGatewayProxyResult } from "aws-lambda";
1
+ import type { APIGatewayProxyEventV2, APIGatewayProxyStructuredResultV2 } from "aws-lambda";
2
2
  import * as path from "node:path";
3
3
  import {performance} from "node:perf_hooks";
4
4
  import chalk from "chalk";
5
5
  import {build, defineConfig, mergeConfig, Plugin, ResolvedConfig} from "vite";
6
6
  import fs from "fs-extra";
7
- import type {IncomingMessage} from "vite";
8
- import querystring from "node:querystring";
7
+ import type {Connect} from "vite";
9
8
 
10
9
  interface Options {
11
10
  entry: string
@@ -16,15 +15,11 @@ const cnf = {
16
15
  host: "localhost",
17
16
  port: 3000,
18
17
  };
19
- const defaultHedares = {
20
- "content-type": "application/json"
21
- }
22
-
23
- const readBody = (req: IncomingMessage) => {
18
+ const readBody = (req: Connect.IncomingMessage): Promise<string> => {
24
19
  return new Promise(resolve => {
25
- const body = [];
20
+ const body: Buffer[] = [];
26
21
  req
27
- .on('data', chunk => {
22
+ .on('data', (chunk: Buffer) => {
28
23
  body.push(chunk);
29
24
  })
30
25
  .on('end', () => {
@@ -34,42 +29,42 @@ const readBody = (req: IncomingMessage) => {
34
29
  };
35
30
 
36
31
  // Адаптер для согласованности с AWS Lambda
37
- const incomingMessageAdapter = async(req: IncomingMessage): Promise<APIGatewayProxyEvent> => {
38
- const urlPath = req.originalUrl.split("#")[0];
32
+ const incomingMessageAdapter = async(req: Connect.IncomingMessage): Promise<APIGatewayProxyEventV2> => {
33
+ const urlPath = (req.originalUrl || "").split("#")[0];
39
34
  const path = urlPath.split('?')[0];
40
- const multiValueQueryStringParameters = querystring.parse(urlPath.split('?')[1]);
41
- const queryStringParameters = Object.keys(multiValueQueryStringParameters).reduce((ac, key) => {
42
- ac[key] = ac[key] || multiValueQueryStringParameters[key];
43
- if(Array.isArray(ac[key])) {
44
- ac[key] = ac[key][ac[key].length - 1];
45
- }
46
- return ac;
47
- }, {})
35
+ const rawQueryString = urlPath.split('?')[1];
48
36
  const headers = (req.rawHeaders || []).reduce((ac, v, index, all) => {
49
- index % 2 === 0 ? (ac[v] = ac[v] || "") : (ac[all[index - 1]] = v);
37
+ index % 2 === 0 ? (ac[v] = (ac[v] || "").toLowerCase()) : (ac[all[index - 1]] = v);
50
38
  return ac;
51
- }, {});
52
- const multiValueHeaders = (req.rawHeaders || []).reduce((ac, v, index, all) => {
53
- index % 2 === 0 ? (ac[v] = ac[v] || []) : (ac[all[index - 1]].push(v));
54
- return ac;
55
- }, {});
39
+ }, {} as Record<string, string>);
40
+ const method = (req.method || "").toUpperCase();
41
+ const resourcePath = path.split("/").slice(1).join("/");
56
42
  return {
57
- body: await readBody(req),
58
- headers: headers,
59
- multiValueHeaders,
60
- httpMethod: req.method.toUpperCase(),
61
- isBase64Encoded: false,
62
- // @ts-ignore
63
- path,
64
- pathParameters: null,
65
- queryStringParameters,
66
- multiValueQueryStringParameters,
67
- stageVariables: null,
43
+ version: "2.0",
44
+ routeKey: `${method} ${resourcePath}`,
45
+ rawPath: path,
46
+ rawQueryString,
47
+ headers,
68
48
  requestContext: {
69
- resourcePath: path,
70
- httpMethod: req.method.toUpperCase(),
71
- }, // Only for production
72
- resource: path,
49
+ accountId: "",
50
+ apiId: "",
51
+ domainName: "",
52
+ domainPrefix: "",
53
+ http: {
54
+ method,
55
+ path,
56
+ protocol: "HTTP/1.1",
57
+ sourceIp: headers["x-forwarded-for"],
58
+ userAgent: headers["user-agent"],
59
+ },
60
+ requestId: "",
61
+ routeKey: `${method} ${resourcePath}`,
62
+ stage: "",
63
+ time: "",
64
+ timeEpoch: Math.round(new Date().getTime()/1000)
65
+ },
66
+ body: await readBody(req),
67
+ isBase64Encoded: false
73
68
  }
74
69
  }
75
70
  const node = (opt: Options): Plugin => {
@@ -80,9 +75,10 @@ const node = (opt: Options): Plugin => {
80
75
  async (req, res, next) => {
81
76
  const ssrModule = await server.ssrLoadModule(path.join(server.config.root, opt.entry));
82
77
  const render = ssrModule.handler || ssrModule.default || ssrModule;
83
- const {statusCode, body, headers, multiValueHeaders} = await render(await incomingMessageAdapter(req), {}) as APIGatewayProxyResult;
84
- const allHeaders = Object.assign({}, defaultHedares, headers || {}, multiValueHeaders || {});
85
- Object.entries(allHeaders).map(([key, value]) => res.setHeader(key, value));
78
+ const {headers, statusCode, body, cookies} = (await render(await incomingMessageAdapter(req), {})) as APIGatewayProxyStructuredResultV2;
79
+ const allHeaders = Object.assign({}, headers || {}) as Record<string, string|string[]>;
80
+ Object.entries(allHeaders).map(([key, value] : [string, string]) => res.setHeader(key, value));
81
+ (cookies || []).forEach((cookie) => res.setHeader("Set-Cookie", cookie));
86
82
  res.statusCode = statusCode || 200;
87
83
  res.end(body);
88
84
  });
@@ -1329,6 +1329,28 @@
1329
1329
  resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4"
1330
1330
  integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==
1331
1331
 
1332
+ "@types/fs-extra@^11.0.4":
1333
+ version "11.0.4"
1334
+ resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-11.0.4.tgz#e16a863bb8843fba8c5004362b5a73e17becca45"
1335
+ integrity sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==
1336
+ dependencies:
1337
+ "@types/jsonfile" "*"
1338
+ "@types/node" "*"
1339
+
1340
+ "@types/jsonfile@*":
1341
+ version "6.1.4"
1342
+ resolved "https://registry.yarnpkg.com/@types/jsonfile/-/jsonfile-6.1.4.tgz#614afec1a1164e7d670b4a7ad64df3e7beb7b702"
1343
+ integrity sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==
1344
+ dependencies:
1345
+ "@types/node" "*"
1346
+
1347
+ "@types/node@*":
1348
+ version "22.7.4"
1349
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-22.7.4.tgz#e35d6f48dca3255ce44256ddc05dee1c23353fcc"
1350
+ integrity sha512-y+NPi1rFzDs1NdQHHToqeiX2TIS79SWEAw9GYhkkx8bD0ChpfqC+n2j5OXOCpzfojBEBt6DnEnnG9MY0zk1XLg==
1351
+ dependencies:
1352
+ undici-types "~6.19.2"
1353
+
1332
1354
  "@types/node@20":
1333
1355
  version "20.14.12"
1334
1356
  resolved "https://registry.yarnpkg.com/@types/node/-/node-20.14.12.tgz#129d7c3a822cb49fc7ff661235f19cfefd422b49"
@@ -1952,6 +1974,11 @@ undici-types@~5.26.4:
1952
1974
  resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617"
1953
1975
  integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==
1954
1976
 
1977
+ undici-types@~6.19.2:
1978
+ version "6.19.8"
1979
+ resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02"
1980
+ integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==
1981
+
1955
1982
  universalify@^0.2.0:
1956
1983
  version "0.2.0"
1957
1984
  resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.2.0.tgz#6451760566fa857534745ab1dde952d1b1761be0"
@@ -0,0 +1,5 @@
1
+ node_modules
2
+ .DS_Store
3
+ *.local
4
+ .idea
5
+ dist
File without changes
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "template-lambda-api",
3
+ "private": true,
4
+ "author": "webigorkiev",
5
+ "license": "PRIVATE",
6
+ "version": "1.0.1",
7
+ "main": "./index.mts",
8
+ "scripts": {
9
+ "dev": "vite",
10
+ "serve": "vite",
11
+ "build": "vite build && cd ./dist && yarn",
12
+ "test": "vitest run",
13
+ "test:production": "vitest run -c vitest.config.production.mts",
14
+ "deploy": "yarn build && cd dist && zip -r ../dist.zip ."
15
+ },
16
+ "devDependencies": {
17
+ "@types/aws-lambda": "8",
18
+ "@types/fs-extra": "^11.0.4",
19
+ "@types/node": "20",
20
+ "chalk": "^5.3.0",
21
+ "fs-extra": "^11.2.0",
22
+ "jsdom": "^24.1.1",
23
+ "typescript": "5",
24
+ "vite": "5",
25
+ "vitest": "^2.0.4"
26
+ },
27
+ "dependencies": {
28
+ "@aws-sdk/client-s3": "3"
29
+ }
30
+ }
@@ -0,0 +1,9 @@
1
+ import {fetch, testConfig} from "../../scripts/test.setup";
2
+
3
+ describe("/", () => {
4
+ const url = new URL(testConfig.apiUrl + "/test-hello-world");
5
+ test(`request GET ${testConfig.apiUrl}/test-hello-world`, async() => {
6
+ const response = await fetch(url.toString());
7
+ expect(response.ok).toEqual(true);
8
+ })
9
+ });
@@ -0,0 +1,21 @@
1
+ const env = process.env.TEST_MODE_APP as "test";
2
+ const entryDevelopment = "http://localhost:3000";
3
+ const entryProduction = "https://dpjhcqy0yj.execute-api.eu-central-1.amazonaws.com/default";
4
+ const apiUrl = env === "test" ? entryDevelopment : entryProduction;
5
+ const testConfig = {
6
+ apiUrl,
7
+ apiKey: "vOAwIEMvw01UHaJsVuYrD4Kjg6WzXyc6364dMBcX"
8
+ }
9
+ const defaultHeaders = {
10
+ headers: {
11
+ "user-agent": "fetch-tests",
12
+ "content-type": "application/json",
13
+ "x-api-key": testConfig.apiKey,
14
+ }
15
+ }
16
+ const fetchWrapper = async(
17
+ input: RequestInfo,
18
+ init: RequestInit = {}
19
+ ) => fetch(input, Object.assign({}, defaultHeaders, init));
20
+
21
+ export {fetchWrapper as fetch, testConfig};
@@ -0,0 +1,26 @@
1
+ import {createServer, ViteDevServer} from "vite";
2
+ import {testConfig} from "./test.setup.mts";
3
+
4
+ declare global {
5
+ var server: ViteDevServer;
6
+ }
7
+
8
+ const start = async(resolve: CallableFunction) => {
9
+ try {
10
+ await fetch(`${testConfig.apiUrl}/dev-start'`);
11
+ resolve();
12
+ } catch(e: any) {
13
+ await new Promise(resolve => setTimeout(resolve, 100));
14
+ await start(resolve);
15
+ }
16
+ };
17
+
18
+ export async function setup() {
19
+ global.server = await createServer();
20
+ await global.server.listen();
21
+ await new Promise(resolve => start(resolve));
22
+ }
23
+
24
+ export async function teardown() {
25
+ await global.server.close();
26
+ }
@@ -0,0 +1,47 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "esnext",
4
+ "module": "esnext",
5
+ "moduleResolution": "node",
6
+ "strict": true,
7
+ "noImplicitThis": true,
8
+ "jsx": "preserve",
9
+ "sourceMap": true,
10
+ "resolveJsonModule": true,
11
+ "esModuleInterop": true,
12
+ "allowSyntheticDefaultImports": true,
13
+ "allowJs": true,
14
+ "noImplicitAny": true,
15
+ "strictFunctionTypes": false,
16
+ "skipLibCheck": true,
17
+ "strictPropertyInitialization": false,
18
+ "experimentalDecorators": true,
19
+ "emitDecoratorMetadata": true,
20
+ "allowImportingTsExtensions": true,
21
+ "lib": [
22
+ "esnext",
23
+ "dom"
24
+ ],
25
+ "types": [
26
+ "vite/client",
27
+ "node"
28
+ ],
29
+ "baseUrl": ".",
30
+ "paths": {
31
+ "@/*": [
32
+ "./src/*"
33
+ ]
34
+ }
35
+ },
36
+ "include": [
37
+ "src/**/*.ts",
38
+ "src/**/*.mts",
39
+ "src/**/*.d.ts",
40
+ "src/**/*.tsx",
41
+ "src/**/*.vue",
42
+ "node_modules/vitest/globals.d.ts"
43
+ ],
44
+ "exclude": [
45
+ "dist"
46
+ ]
47
+ }
@@ -0,0 +1,188 @@
1
+ import type { APIGatewayProxyEvent, APIGatewayProxyResult } from "aws-lambda";
2
+ import * as path from "node:path";
3
+ import {performance} from "node:perf_hooks";
4
+ import chalk from "chalk";
5
+ import {build, defineConfig, mergeConfig, Plugin, ResolvedConfig} from "vite";
6
+ import fs from "fs-extra";
7
+ import type {Connect} from "vite";
8
+ import querystring from "node:querystring";
9
+
10
+ interface Options {
11
+ entry: string
12
+ }
13
+
14
+ const cnf = {
15
+ protocol: "http",
16
+ host: "localhost",
17
+ port: 3000,
18
+ };
19
+ const readBody = (req: Connect.IncomingMessage): Promise<string> => {
20
+ return new Promise(resolve => {
21
+ const body: Buffer[] = [];
22
+ req
23
+ .on('data', (chunk: Buffer) => {
24
+ body.push(chunk);
25
+ })
26
+ .on('end', () => {
27
+ resolve(Buffer.concat(body).toString());
28
+ });
29
+ });
30
+ };
31
+
32
+ // Адаптер для согласованности с AWS Lambda
33
+ const incomingMessageAdapter = async(req: Connect.IncomingMessage): Promise<APIGatewayProxyEvent> => {
34
+ const urlPath = (req.originalUrl || "").split("#")[0];
35
+ const path = urlPath.split('?')[0];
36
+ const queryStringParameters = querystring.parse(urlPath.split('?')[1]);
37
+ const queryStringParametersString = Object.keys(queryStringParameters).reduce((ac, key) => {
38
+ const value = queryStringParameters[key] as string|string[];
39
+ const valueString: string = !Array.isArray(value)
40
+ ? value
41
+ : value[value.length - 1]
42
+ ac[key] = ac[key] || valueString;
43
+ return ac;
44
+ }, {} as Record<string, string>);
45
+ const multiValueQueryStringParameters = Object.keys(queryStringParameters).reduce((ac, key) => {
46
+ const value = Array.isArray(queryStringParameters[key]) ? queryStringParameters[key] : [queryStringParameters[key]]
47
+ ac[key] = ac[key] || value;
48
+ return ac;
49
+ }, {} as Record<string, string[]>);
50
+ const headers = (req.rawHeaders || []).reduce((ac, v, index, all) => {
51
+ index % 2 === 0 ? (ac[v] = ac[v] || "") : (ac[all[index - 1]] = v);
52
+ return ac;
53
+ }, {} as Record<string, any>);
54
+ const multiValueHeaders = (req.rawHeaders || []).reduce((ac, v, index, all) => {
55
+ index % 2 === 0 ? (ac[v] = ac[v] || []) : (ac[all[index - 1]].push(v));
56
+ return ac;
57
+ }, {} as Record<string, any>);
58
+ const headersLowerCase = Object.keys(headers).reduce((ac, key) => {
59
+ const value = headers[key];
60
+ ac[key.toLowerCase()] = value;
61
+ return ac;
62
+ }, {} as Record<string, string>);
63
+ return {
64
+ body: await readBody(req),
65
+ headers,
66
+ multiValueHeaders,
67
+ httpMethod: (req.method || "").toUpperCase(),
68
+ isBase64Encoded: false,
69
+ // @ts-ignore
70
+ path,
71
+ pathParameters: null,
72
+ queryStringParameters: queryStringParametersString,
73
+ multiValueQueryStringParameters,
74
+ stageVariables: null,
75
+ requestContext: {
76
+ resourcePath: path.split("/").slice(1).join("/"),
77
+ httpMethod: (req.method || "").toUpperCase(),
78
+ accountId: "",
79
+ apiId: "",
80
+ authorizer: {},
81
+ protocol: "http",
82
+ identity: {
83
+ cognitoIdentityPoolId: null,
84
+ cognitoIdentityId: null,
85
+ apiKey: "",
86
+ principalOrgId: null,
87
+ cognitoAuthenticationType: null,
88
+ userArn: null,
89
+ apiKeyId: "",
90
+ userAgent: headersLowerCase["user-agent"],
91
+ accountId: null,
92
+ caller: null,
93
+ sourceIp: headersLowerCase["x-forwarded-for"],
94
+ accessKey: null,
95
+ cognitoAuthenticationProvider: null,
96
+ user: null,
97
+ clientCert: null
98
+ },
99
+ path,
100
+ stage: "",
101
+ requestId: "",
102
+ requestTimeEpoch: 0,
103
+ resourceId: ""
104
+ }, // Only for production
105
+ resource: path,
106
+ }
107
+ }
108
+ const node = (opt: Options): Plugin => {
109
+ return {
110
+ name: "vite-node-js",
111
+ async configureServer(server) {
112
+ return () => server.middlewares.use(
113
+ async (req, res, next) => {
114
+ const ssrModule = await server.ssrLoadModule(path.join(server.config.root, opt.entry));
115
+ const render = ssrModule.handler || ssrModule.default || ssrModule;
116
+ const {statusCode, body, headers, multiValueHeaders} = (await render(await incomingMessageAdapter(req), {})) as APIGatewayProxyResult;
117
+ const allHeaders = Object.assign({}, headers || {}, multiValueHeaders || {}) as Record<string, string|string[]>;
118
+ Object.entries(allHeaders).map(([key, value] : [string, string]) => res.setHeader(key, value));
119
+ res.statusCode = statusCode || 200;
120
+ res.end(body);
121
+ });
122
+ },
123
+ async configResolved(configVite:ResolvedConfig) {
124
+ const time = performance.now();
125
+ const start = async(resolve: CallableFunction) => {
126
+ try {
127
+ await fetch(`${cnf.protocol}://${cnf.host}:${cnf.port}/start-server`);
128
+ const interval = Math.round((performance.now() - time)/10)/100;
129
+ console.log(chalk.green('dev server running for ') + chalk.red(`${interval}s`) + chalk.green(' at:'));
130
+ console.log(`${cnf.protocol}://${cnf.host}:${cnf.port}`);
131
+ resolve();
132
+ } catch(e: any) {
133
+ await start(resolve);
134
+ }
135
+ };
136
+ if(configVite.command === "build") {
137
+
138
+ // @ts-ignore
139
+ if(!configVite.build.isBuild) {
140
+ await build(mergeConfig({
141
+ build: {
142
+ isBuild: true,
143
+ outDir: path.resolve(configVite.root, `dist`),
144
+ ssr: path.join(configVite.root, opt.entry),
145
+ }
146
+ }, {}));
147
+ const packagePath = path.resolve(configVite.root, "./dist", "./package.json");
148
+ await fs.copy("./package.json", packagePath);
149
+ const pkg = await fs.readJson(packagePath);
150
+ delete(pkg.devDependencies);
151
+ delete(pkg.scripts);
152
+ await fs.writeJson(packagePath, pkg, {
153
+ spaces: 2
154
+ });
155
+ process.exit(0);
156
+ }
157
+ } else {
158
+ console.log();
159
+ console.log(chalk.green('dev server starting...'));
160
+ new Promise(resolve => start(resolve));
161
+ }
162
+ },
163
+ async closeBundle() {}
164
+ }
165
+ }
166
+
167
+ export default defineConfig({
168
+ resolve: {
169
+ alias: [
170
+ {
171
+ find: /@\/(.*)/,
172
+ replacement: path.resolve("./src") + "/$1"
173
+ }
174
+ ],
175
+ },
176
+ server: {
177
+ host: cnf.host,
178
+ port: cnf.port
179
+ },
180
+ optimizeDeps: {
181
+ include:[]
182
+ },
183
+ plugins: [
184
+ node({
185
+ entry: "/src/backend/index.mts"
186
+ })
187
+ ]
188
+ });
@@ -0,0 +1,40 @@
1
+ /// <reference types="vitest" />
2
+ import path from 'node:path';
3
+ import { defineConfig } from 'vitest/config';
4
+
5
+ process.env.TEST_MODE_APP = "test";
6
+
7
+ export default defineConfig({
8
+ resolve: {
9
+ alias: [
10
+ {
11
+ find: /^~(.+)/,
12
+ replacement: path.resolve('./node_modules') + '/$1',
13
+ },
14
+ {
15
+ find: /@\/(.*)/,
16
+ replacement: path.resolve('./src') + '/$1',
17
+ },
18
+ ],
19
+ },
20
+ plugins: [
21
+ ],
22
+ test: {
23
+ root: "./",
24
+ include: ["**/__its__/**/*.(m)?[jt]s?(x)", "**/__tests__/**/*.(m)?[jt]s?(x)", "**/?(*.)+(spec|test).(m)?[jt]s?(x)"],
25
+ exclude: ["**/node_modules/**", "./src/certs/**", "./src/scripts/**", "./src/sql/**", "./src/estimation-client/**"],
26
+ environment: "jsdom",
27
+ globals: true,
28
+ globalSetup: ["./src/scripts/vitest.global.setup.mts"],
29
+ testTimeout: 15000,
30
+ hookTimeout: 15000,
31
+ // threads: false
32
+ // @ts-ignore
33
+ singleThread: true,
34
+ poolOptions: {
35
+ threads: {
36
+ singleThread: true
37
+ }
38
+ }
39
+ },
40
+ });