Add board compilation
This commit is contained in:
parent
e2d1b006fe
commit
4a6482100a
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,3 +1,4 @@
|
||||
node_modules
|
||||
src/server/public/dist
|
||||
src/server/public/assets/compiled
|
||||
.env
|
331
package-lock.json
generated
331
package-lock.json
generated
@ -16,9 +16,12 @@
|
||||
"@firebox/tsutil": "^0.1.2",
|
||||
"@sinclair/typebox": "^0.31.5",
|
||||
"@types/katex": "^0.16.7",
|
||||
"@types/object-hash": "^3.0.6",
|
||||
"dotenv": "^16.3.1",
|
||||
"execa": "^8.0.1",
|
||||
"fastify": "^4.22.0",
|
||||
"katex": "^0.16.10",
|
||||
"object-hash": "^3.0.0",
|
||||
"tsx": "^4.7.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
@ -1180,6 +1183,11 @@
|
||||
"dev": true,
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@types/object-hash": {
|
||||
"version": "3.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/object-hash/-/object-hash-3.0.6.tgz",
|
||||
"integrity": "sha512-fOBV8C1FIu2ELinoILQ+ApxcUKz4ngq+IWUYrxSGjXzzjUALijilampwkMgEtJ+h2njAW3pi853QpzNVCHB73w=="
|
||||
},
|
||||
"node_modules/@types/parse-json": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
|
||||
@ -1720,6 +1728,19 @@
|
||||
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/cross-spawn": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
||||
"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
|
||||
"dependencies": {
|
||||
"path-key": "^3.1.0",
|
||||
"shebang-command": "^2.0.0",
|
||||
"which": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/csstype": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
|
||||
@ -1932,6 +1953,64 @@
|
||||
"node": ">=0.8.x"
|
||||
}
|
||||
},
|
||||
"node_modules/execa": {
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz",
|
||||
"integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==",
|
||||
"dependencies": {
|
||||
"cross-spawn": "^7.0.3",
|
||||
"get-stream": "^8.0.1",
|
||||
"human-signals": "^5.0.0",
|
||||
"is-stream": "^3.0.0",
|
||||
"merge-stream": "^2.0.0",
|
||||
"npm-run-path": "^5.1.0",
|
||||
"onetime": "^6.0.0",
|
||||
"signal-exit": "^4.1.0",
|
||||
"strip-final-newline": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.17"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sindresorhus/execa?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/execa/node_modules/mimic-fn": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz",
|
||||
"integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/execa/node_modules/onetime": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz",
|
||||
"integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==",
|
||||
"dependencies": {
|
||||
"mimic-fn": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/execa/node_modules/signal-exit": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
|
||||
"integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/external-editor": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz",
|
||||
@ -2158,6 +2237,17 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/get-stream": {
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz",
|
||||
"integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==",
|
||||
"engines": {
|
||||
"node": ">=16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/get-tsconfig": {
|
||||
"version": "4.7.3",
|
||||
"resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.3.tgz",
|
||||
@ -2316,6 +2406,14 @@
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/human-signals": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz",
|
||||
"integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==",
|
||||
"engines": {
|
||||
"node": ">=16.17.0"
|
||||
}
|
||||
},
|
||||
"node_modules/iconv-lite": {
|
||||
"version": "0.4.24",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
||||
@ -2678,6 +2776,17 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-stream": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz",
|
||||
"integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==",
|
||||
"engines": {
|
||||
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/is-string": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz",
|
||||
@ -2763,6 +2872,11 @@
|
||||
"integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/isexe": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
|
||||
},
|
||||
"node_modules/js-tokens": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||
@ -2959,6 +3073,11 @@
|
||||
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/merge-stream": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
|
||||
"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="
|
||||
},
|
||||
"node_modules/mime": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz",
|
||||
@ -3077,6 +3196,31 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/npm-run-path": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz",
|
||||
"integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==",
|
||||
"dependencies": {
|
||||
"path-key": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/npm-run-path/node_modules/path-key": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz",
|
||||
"integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/object-assign": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
@ -3086,6 +3230,14 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/object-hash": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
|
||||
"integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/object-inspect": {
|
||||
"version": "1.12.3",
|
||||
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz",
|
||||
@ -3342,6 +3494,14 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/path-key": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
|
||||
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/path-parse": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
|
||||
@ -3884,6 +4044,25 @@
|
||||
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
|
||||
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
|
||||
},
|
||||
"node_modules/shebang-command": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
|
||||
"dependencies": {
|
||||
"shebang-regex": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/shebang-regex": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
|
||||
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/side-channel": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
|
||||
@ -3986,6 +4165,17 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/strip-final-newline": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz",
|
||||
"integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/sucrase": {
|
||||
"version": "3.34.0",
|
||||
"resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.34.0.tgz",
|
||||
@ -4252,6 +4442,20 @@
|
||||
"defaults": "^1.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/which": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
|
||||
"dependencies": {
|
||||
"isexe": "^2.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"node-which": "bin/node-which"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/which-boxed-primitive": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz",
|
||||
@ -5206,6 +5410,11 @@
|
||||
"dev": true,
|
||||
"peer": true
|
||||
},
|
||||
"@types/object-hash": {
|
||||
"version": "3.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/object-hash/-/object-hash-3.0.6.tgz",
|
||||
"integrity": "sha512-fOBV8C1FIu2ELinoILQ+ApxcUKz4ngq+IWUYrxSGjXzzjUALijilampwkMgEtJ+h2njAW3pi853QpzNVCHB73w=="
|
||||
},
|
||||
"@types/parse-json": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
|
||||
@ -5603,6 +5812,16 @@
|
||||
"integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
|
||||
"dev": true
|
||||
},
|
||||
"cross-spawn": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
||||
"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
|
||||
"requires": {
|
||||
"path-key": "^3.1.0",
|
||||
"shebang-command": "^2.0.0",
|
||||
"which": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"csstype": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
|
||||
@ -5763,6 +5982,42 @@
|
||||
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
|
||||
"integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q=="
|
||||
},
|
||||
"execa": {
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz",
|
||||
"integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==",
|
||||
"requires": {
|
||||
"cross-spawn": "^7.0.3",
|
||||
"get-stream": "^8.0.1",
|
||||
"human-signals": "^5.0.0",
|
||||
"is-stream": "^3.0.0",
|
||||
"merge-stream": "^2.0.0",
|
||||
"npm-run-path": "^5.1.0",
|
||||
"onetime": "^6.0.0",
|
||||
"signal-exit": "^4.1.0",
|
||||
"strip-final-newline": "^3.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"mimic-fn": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz",
|
||||
"integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw=="
|
||||
},
|
||||
"onetime": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz",
|
||||
"integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==",
|
||||
"requires": {
|
||||
"mimic-fn": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"signal-exit": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
|
||||
"integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"external-editor": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz",
|
||||
@ -5951,6 +6206,11 @@
|
||||
"has-symbols": "^1.0.3"
|
||||
}
|
||||
},
|
||||
"get-stream": {
|
||||
"version": "8.0.1",
|
||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz",
|
||||
"integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA=="
|
||||
},
|
||||
"get-tsconfig": {
|
||||
"version": "4.7.3",
|
||||
"resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.3.tgz",
|
||||
@ -6061,6 +6321,11 @@
|
||||
"toidentifier": "1.0.1"
|
||||
}
|
||||
},
|
||||
"human-signals": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz",
|
||||
"integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ=="
|
||||
},
|
||||
"iconv-lite": {
|
||||
"version": "0.4.24",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
||||
@ -6315,6 +6580,11 @@
|
||||
"call-bind": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"is-stream": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz",
|
||||
"integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA=="
|
||||
},
|
||||
"is-string": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz",
|
||||
@ -6370,6 +6640,11 @@
|
||||
"integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
|
||||
"dev": true
|
||||
},
|
||||
"isexe": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
|
||||
},
|
||||
"js-tokens": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||
@ -6518,6 +6793,11 @@
|
||||
"integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
|
||||
"dev": true
|
||||
},
|
||||
"merge-stream": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
|
||||
"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="
|
||||
},
|
||||
"mime": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz",
|
||||
@ -6604,12 +6884,32 @@
|
||||
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
|
||||
"dev": true
|
||||
},
|
||||
"npm-run-path": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz",
|
||||
"integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==",
|
||||
"requires": {
|
||||
"path-key": "^4.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"path-key": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz",
|
||||
"integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
|
||||
"dev": true
|
||||
},
|
||||
"object-hash": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
|
||||
"integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw=="
|
||||
},
|
||||
"object-inspect": {
|
||||
"version": "1.12.3",
|
||||
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz",
|
||||
@ -6790,6 +7090,11 @@
|
||||
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
|
||||
"dev": true
|
||||
},
|
||||
"path-key": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
|
||||
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="
|
||||
},
|
||||
"path-parse": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
|
||||
@ -7184,6 +7489,19 @@
|
||||
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
|
||||
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
|
||||
},
|
||||
"shebang-command": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
|
||||
"requires": {
|
||||
"shebang-regex": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"shebang-regex": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
|
||||
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="
|
||||
},
|
||||
"side-channel": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
|
||||
@ -7265,6 +7583,11 @@
|
||||
"ansi-regex": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"strip-final-newline": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz",
|
||||
"integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw=="
|
||||
},
|
||||
"sucrase": {
|
||||
"version": "3.34.0",
|
||||
"resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.34.0.tgz",
|
||||
@ -7451,6 +7774,14 @@
|
||||
"defaults": "^1.0.3"
|
||||
}
|
||||
},
|
||||
"which": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
|
||||
"requires": {
|
||||
"isexe": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"which-boxed-primitive": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz",
|
||||
|
14
package.json
14
package.json
@ -6,14 +6,17 @@
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"dev-docker": "docker compose --profile dev up -d",
|
||||
"dev-server": "echo \"starting server\" && npm run withenv ./src/server/index.ts",
|
||||
"dev-server": "npm run withenv ./src/server/index.ts",
|
||||
"dev-build-client": "npm run withenv ./scripts/build.ts",
|
||||
"dev-watch-client": "npm run withenv ./scripts/watch.ts",
|
||||
"dev-migrate": "source ./.env && pg-migrations apply --directory ./src/database/migrations",
|
||||
"prod-migrate": "pg-migrations apply --directory ./src/database/migrations",
|
||||
"dev-start": "echo \"building frontend\" && npm run dev-build-client && echo \"starting server\" && npm run dev-server",
|
||||
"prod-build-client": "npm run withenv ./scripts/build.ts",
|
||||
"prod-docker": "docker compose --profile prod up -d",
|
||||
"prod-start": "echo \"building frontend\" && npm run prod-build-client && echo \"${DATABASE_URL}\" && echo \"running migrations\" && npm run prod-migrate && echo \"starting server\" && npm run withenv ./src/server/index.ts",
|
||||
"prod-server": "npm run withenv ./src/server/index.ts",
|
||||
"prod-start": "echo \"building frontend\" && npm run prod-build-client && echo \"starting server\" && npm run prod-server",
|
||||
"withenv": "tsx ./scripts/run-with-env.ts",
|
||||
"make-svgs": "npm run withenv ./scripts/make-svgs.ts",
|
||||
"compile-content": "npm run withenv ./scripts/compile-content.ts",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"repository": {
|
||||
@ -30,9 +33,12 @@
|
||||
"@firebox/tsutil": "^0.1.2",
|
||||
"@sinclair/typebox": "^0.31.5",
|
||||
"@types/katex": "^0.16.7",
|
||||
"@types/object-hash": "^3.0.6",
|
||||
"dotenv": "^16.3.1",
|
||||
"execa": "^8.0.1",
|
||||
"fastify": "^4.22.0",
|
||||
"katex": "^0.16.10",
|
||||
"object-hash": "^3.0.0",
|
||||
"tsx": "^4.7.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
80
scripts/compile-content.ts
Normal file
80
scripts/compile-content.ts
Normal file
@ -0,0 +1,80 @@
|
||||
import fs from "fs";
|
||||
import { getDirname } from '../util/dirname';
|
||||
import path from "path";
|
||||
import { Mathuscript, parseMathuscript } from "../src/client/player/parse";
|
||||
import { writeFileSync, mkdirSync, rmSync } from 'fs';
|
||||
import {execa} from 'execa';
|
||||
import hash from "object-hash";
|
||||
|
||||
const __dirname = getDirname(import.meta);
|
||||
|
||||
// Function to convert LaTeX to SVG
|
||||
async function latexToSvg(latex: string, dir: string, tempDir: string | null): Promise<string> {
|
||||
try {
|
||||
// const dir = path.join(__dirname, "..", "src", "server", "public", "svgs");
|
||||
tempDir = tempDir ?? path.join(dir, "temp");
|
||||
|
||||
mkdirSync(tempDir, {recursive: true});
|
||||
|
||||
const fname = hash(latex);
|
||||
const tempFileName = path.join(tempDir, fname);
|
||||
const outFileName = path.join(dir, fname);
|
||||
writeFileSync(`${tempFileName}.tex`, latex);
|
||||
|
||||
// Run LaTeX to generate a DVI file
|
||||
console.log("generating dvi file");
|
||||
await execa('latex', ['-halt-on-error', `-output-directory=${tempDir}`, `${tempFileName}.tex`]);
|
||||
|
||||
// Convert DVI to SVG
|
||||
console.log("converting to svg");
|
||||
await execa('dvisvgm', [`${tempFileName}.dvi`, '-n', '-o', `${outFileName}.svg`]);
|
||||
|
||||
console.log("cleaning up temp files");
|
||||
rmSync(tempDir, {force: true, recursive: true});
|
||||
|
||||
return `${fname}.svg`;
|
||||
} catch (error) {
|
||||
console.error('Error converting LaTeX to SVG:', error);
|
||||
throw Error('Error converting LaTeX to SVG');
|
||||
}
|
||||
}
|
||||
|
||||
const contentDir = path.join(__dirname, "..", "src", "content");
|
||||
const publicDir = path.join(__dirname, "..", "src", "server", "public");
|
||||
const assetsDir = path.join(publicDir, "assets");
|
||||
const compiledAssetsDir = path.join(assetsDir, "compiled");
|
||||
const compileToDir = path.join(__dirname, "..", "src", "client", "content");
|
||||
|
||||
const preamblePath = path.join(contentDir, "preamble.tex");
|
||||
const sectionsDir = path.join(contentDir, "sections");
|
||||
|
||||
const compileContents = async () => {
|
||||
fs.rmSync(compileToDir, {force: true, recursive: true});
|
||||
fs.mkdirSync(compileToDir, {recursive: true});
|
||||
const sectionFiles = fs.readdirSync(sectionsDir);
|
||||
const sections: {name: string; text: string, parsed: Mathuscript}[] = [];
|
||||
sectionFiles.forEach(sectionFile => {
|
||||
const fullName = path.join(sectionsDir, sectionFile);
|
||||
console.log("Reading", sectionFile);
|
||||
const fileText = fs.readFileSync(fullName, "utf8");
|
||||
sections.push({
|
||||
name: sectionFile,
|
||||
text: fileText,
|
||||
parsed: parseMathuscript(fileText),
|
||||
});
|
||||
})
|
||||
const preamble = fs.readFileSync(preamblePath, "utf8");
|
||||
for (const section of sections) {
|
||||
console.log("Processing", section.name);
|
||||
for (const step of section.parsed.filter(step => step.name === "board")) {
|
||||
console.log('Step');
|
||||
if (step.text.trim()) {
|
||||
const svgPath = await latexToSvg(`${preamble}\n\n\\begin{document}\n${step.text}\n\\end{document}\n`, compiledAssetsDir, null);
|
||||
step.text = svgPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
fs.writeFileSync(path.join(compileToDir, "content.ts"), `export const content = {sections: ${JSON.stringify(sections)}}`);
|
||||
}
|
||||
|
||||
await compileContents();
|
@ -42,7 +42,7 @@ const App = (props: { name: string }) => {
|
||||
margin: auto;
|
||||
`}>
|
||||
<h1>MathU</h1>
|
||||
<MathuscriptPlayer script={script} />
|
||||
<MathuscriptPlayer scriptName="cantor-schroeder-bernstein" />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
1
src/client/content/content.ts
Normal file
1
src/client/content/content.ts
Normal file
@ -0,0 +1 @@
|
||||
export const content = {sections: [{"name":"cantor-schroeder-bernstein.mus","text":"# !use [board, bridget, calvin, kit, theo, axelle]\n\nboard \"Given $\\chalk{yellow}f\\chalk{white}: \\mathbb{Q} \\to \\mathbb{R}$ and $x \\in \\mathbb{Q}$, there is a unique $y \\in \\mathbb{N}$ such that $\\chalk{blue}f\\chalk{white}(x)=y$\"\n\nbridget (happy) \"Hi, friends!\"\n\ncalvin (mathstruck) \"Wow, did you know that $a^2+b^2=c^2$?\"\n\ncalvin (thinking) \"Something else\"\n\nbridget (surprised) \"Me again000000\"\n\nkit (smiling) \"I'm Kit 1!\"\n\nkit (smiling) \"I'm Kit 2!\"\n\nboard \"\"\n\ncalvin (happy) \"I'm back!\"\n\nbridget (aha) \"I'm on the right now!\"\n\ntheo (heh) \"Oh, hey guys. Didn't see you there.\"\n\naxelle \"Oh, hi.\"\n\nboard \"If $ax^2+bx+c=0$, then $x = \\frac{-b\\pm\\sqrt{b^2-4ac}}{2a}$.\"\n\ntheo \"Did you know...\"","parsed":[{"name":"board","text":"a4dc03d7dade1daf859767ba8dd51678d73a3bf7.svg"},{"name":"bridget","emotion":"happy","text":"Hi, friends!"},{"name":"calvin","emotion":"mathstruck","text":"Wow, did you know that $a^2+b^2=c^2$?"},{"name":"calvin","emotion":"thinking","text":"Something else"},{"name":"bridget","emotion":"surprised","text":"Me again000000"},{"name":"kit","emotion":"smiling","text":"I'm Kit 1!"},{"name":"kit","emotion":"smiling","text":"I'm Kit 2!"},{"name":"board","text":""},{"name":"calvin","emotion":"happy","text":"I'm back!"},{"name":"bridget","emotion":"aha","text":"I'm on the right now!"},{"name":"theo","emotion":"heh","text":"Oh, hey guys. Didn't see you there."},{"name":"axelle","text":"Oh, hi."},{"name":"board","text":"fa97c503f244f13f97a181facac0c22c16408700.svg"},{"name":"theo","text":"Did you know..."}]}]}
|
@ -4,6 +4,7 @@ import { useCallback, useMemo, useRef, useState } from "react";
|
||||
import { MathText } from "./MathText";
|
||||
import { characterData } from "./data";
|
||||
import { DialogText, DialogTextImperatives } from "./DialogText";
|
||||
import { content } from "../content/content";
|
||||
|
||||
type VisualState = {
|
||||
turn: number,
|
||||
@ -57,9 +58,9 @@ const getCharData = (name: string | null) => {
|
||||
|
||||
const allChars = Object.keys(characterData) as (keyof typeof characterData)[];
|
||||
|
||||
export const MathuscriptPlayer = (props: { script: string }) => {
|
||||
const {script} = props;
|
||||
const parsedScript = useMemo(() => parseMathuscript(script), [script]);
|
||||
export const MathuscriptPlayer = (props: { scriptName: string }) => {
|
||||
const {scriptName} = props;
|
||||
const parsedScript = content.sections.find(s => s.name.split(".")[0] === scriptName)!.parsed; // useMemo(() => parseMathuscript(script), [script]);
|
||||
const goAgain = useRef(false);
|
||||
const [index, setIndex] = useState(0);
|
||||
const [visualState, setVisualState] = useState<VisualState>({turn: 0, characters: [], board: {text: ""}, dialog: {name: null, emotion: "", text: ""}});
|
||||
@ -77,7 +78,7 @@ export const MathuscriptPlayer = (props: { script: string }) => {
|
||||
const step = parsedScript[index];
|
||||
if (step) {
|
||||
setIndex(i => i+1);
|
||||
setVisualState(state => afterStep(state, step));
|
||||
setVisualState(state => afterStep(state, {emotion: "", ...step}));
|
||||
if (step.name === "board") {
|
||||
goAgain.current = true;
|
||||
} else {
|
||||
@ -126,7 +127,12 @@ export const MathuscriptPlayer = (props: { script: string }) => {
|
||||
padding: 1em;
|
||||
`}>
|
||||
<div>
|
||||
<MathText>{visualState.board.text}</MathText>
|
||||
{
|
||||
visualState.board.text && <img className={css`
|
||||
transform: scale(1.25);
|
||||
`} src={`/assets/compiled/${visualState.board.text}`}/>
|
||||
}
|
||||
{/* <MathText>{visualState.board.text}</MathText> */}
|
||||
</div>
|
||||
</div>
|
||||
<div className={css`
|
||||
|
@ -2,7 +2,7 @@
|
||||
const lineRegex = /^\s*(?<name>[a-z-]+)\s+(?:\((?<emotion>[a-z-]+)\))?\s*"(?<text>(?:[^"\\]|\\.)*)"\s*$/;
|
||||
|
||||
export const parseMathuscript = (script: string) => {
|
||||
return script.split("\n").filter(Boolean).map(line => {
|
||||
return script.split("\n").filter(x => x && !x.startsWith("#")).map(line => {
|
||||
const match = line.match(lineRegex);
|
||||
if (!match) {
|
||||
throw Error(`Bad Line: ${JSON.stringify(line)}`);
|
||||
|
17
src/content/preamble.tex
Normal file
17
src/content/preamble.tex
Normal file
@ -0,0 +1,17 @@
|
||||
\documentclass[varwidth=256px]{standalone}
|
||||
\usepackage{amsmath}
|
||||
\usepackage{amssymb}
|
||||
\usepackage{xcolor}
|
||||
|
||||
\definecolor{chalkwhite}{RGB}{240, 250, 245}
|
||||
\definecolor{chalkred}{RGB}{255, 119, 122}
|
||||
\definecolor{chalkorange}{RGB}{255, 195, 128}
|
||||
\definecolor{chalkyellow}{RGB}{244, 244, 120}
|
||||
\definecolor{chalkgreen}{RGB}{135, 230, 121}
|
||||
\definecolor{chalkblue}{RGB}{128, 195, 255}
|
||||
\definecolor{chalkpurple}{RGB}{206, 168, 238}
|
||||
\definecolor{chalkpink}{RGB}{240, 157, 215}
|
||||
|
||||
\newcommand{\chalk}[1]{\color{chalk#1}}
|
||||
|
||||
\chalk{white}
|
29
src/content/sections/cantor-schroeder-bernstein.mus
Normal file
29
src/content/sections/cantor-schroeder-bernstein.mus
Normal file
@ -0,0 +1,29 @@
|
||||
# !use [board, bridget, calvin, kit, theo, axelle]
|
||||
|
||||
board "Given $\chalk{yellow}f\chalk{white}: \mathbb{Q} \to \mathbb{R}$ and $x \in \mathbb{Q}$, there is a unique $y \in \mathbb{N}$ such that $\chalk{blue}f\chalk{white}(x)=y$"
|
||||
|
||||
bridget (happy) "Hi, friends!"
|
||||
|
||||
calvin (mathstruck) "Wow, did you know that $a^2+b^2=c^2$?"
|
||||
|
||||
calvin (thinking) "Something else"
|
||||
|
||||
bridget (surprised) "Me again000000"
|
||||
|
||||
kit (smiling) "I'm Kit 1!"
|
||||
|
||||
kit (smiling) "I'm Kit 2!"
|
||||
|
||||
board ""
|
||||
|
||||
calvin (happy) "I'm back!"
|
||||
|
||||
bridget (aha) "I'm on the right now!"
|
||||
|
||||
theo (heh) "Oh, hey guys. Didn't see you there."
|
||||
|
||||
axelle "Oh, hi."
|
||||
|
||||
board "If $ax^2+bx+c=0$, then $x = \frac{-b\pm\sqrt{b^2-4ac}}{2a}$."
|
||||
|
||||
theo "Did you know..."
|
@ -1,28 +0,0 @@
|
||||
import createConnectionPool, {ConnectionPool, ConnectionPoolConfig, sql} from '@databases/pg';
|
||||
|
||||
export {sql};
|
||||
|
||||
const portString = process.env["DB_PORT"];
|
||||
const portNumber = portString ? parseInt(portString) : undefined;
|
||||
|
||||
const clientConfig: ConnectionPoolConfig = {
|
||||
host: process.env["DB_HOST"],
|
||||
user: process.env["DB_USER"],
|
||||
database: process.env["DB_NAME"],
|
||||
password: process.env["DB_PASSWORD"],
|
||||
port: portNumber,
|
||||
};
|
||||
|
||||
// @ts-ignore
|
||||
const db: ConnectionPool = createConnectionPool({
|
||||
connectionString: false,
|
||||
...clientConfig
|
||||
});
|
||||
|
||||
process.once('SIGTERM', () => {
|
||||
db.dispose().catch((ex) => {
|
||||
console.error(ex);
|
||||
});
|
||||
});
|
||||
|
||||
export {db};
|
@ -1,4 +0,0 @@
|
||||
CREATE TABLE testtable (
|
||||
id text,
|
||||
somecolumn text
|
||||
)
|
6
util/dirname.ts
Normal file
6
util/dirname.ts
Normal file
@ -0,0 +1,6 @@
|
||||
import { fileURLToPath } from "url";
|
||||
|
||||
/**
|
||||
* Pass in `import.meta` to get the __dirname.
|
||||
*/
|
||||
export const getDirname = (importMeta: ImportMeta) => fileURLToPath(new URL('.', importMeta.url));
|
Loading…
x
Reference in New Issue
Block a user