This commit is contained in:
Sandip Ghimire 2026-01-20 17:58:43 +05:45
commit d94bfc5a68
10 changed files with 784 additions and 0 deletions

8
.editorconfig Normal file
View File

@ -0,0 +1,8 @@
[*.{js,jsx,mjs,cjs,ts,tsx,mts,cts,vue,css,scss,sass,less,styl}]
charset = utf-8
indent_size = 2
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
end_of_line = lf
max_line_length = 100

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
node_modules

4
.vscode/extensions.json vendored Normal file
View File

@ -0,0 +1,4 @@
{
"recommendations": ["prettier.prettier-vscode", "dbaeumer.vscode-eslint"],
"unwantedRecommendations": ["octref.vetur"]
}

31
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,31 @@
{
"editor.formatOnSave": true,
"editor.defaultFormatter": "prettier.prettier-vscode",
"editor.formatOnSaveMode": "file",
"[vue]": {
"editor.defaultFormatter": "prettier.prettier-vscode"
},
"[typescript]": {
"editor.defaultFormatter": "prettier.prettier-vscode"
},
"[javascript]": {
"editor.defaultFormatter": "prettier.prettier-vscode"
},
"[css]": {
"editor.defaultFormatter": "prettier.prettier-vscode"
},
"[json]": {
"editor.defaultFormatter": "prettier.prettier-vscode"
},
"[jsonc]": {
"editor.defaultFormatter": "prettier.prettier-vscode"
},
"explorer.fileNesting.enabled": true,
"explorer.fileNesting.expand": true,
"explorer.fileNesting.patterns": {
"package.json": "package-lock.json, tsconfig.json, tsconfig.app.json, tsconfig.node.json, .prettierrc.json, .prettierignore, eslint.config.js",
".gitignore": ".gitattributes"
}
}

24
package.json Normal file
View File

@ -0,0 +1,24 @@
{
"name": "date-insert",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"runner": "tsx src/index.ts --noEmit"
},
"keywords": [],
"author": "",
"license": "ISC",
"packageManager": "pnpm@10.28.1",
"dependencies": {
"chalk": "^5.6.2",
"mysql2": "^3.16.1",
"nepali-date-library": "^1.1.12"
},
"devDependencies": {
"@types/node": "^25.0.9",
"prettier": "^3.8.0",
"tsx": "^4.21.0",
"typescript": "^5.9.3"
}
}

457
pnpm-lock.yaml Normal file
View File

@ -0,0 +1,457 @@
lockfileVersion: '9.0'
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
importers:
.:
dependencies:
chalk:
specifier: ^5.6.2
version: 5.6.2
mysql2:
specifier: ^3.16.1
version: 3.16.1
nepali-date-library:
specifier: ^1.1.12
version: 1.1.12
devDependencies:
'@types/node':
specifier: ^25.0.9
version: 25.0.9
prettier:
specifier: ^3.8.0
version: 3.8.0
tsx:
specifier: ^4.21.0
version: 4.21.0
typescript:
specifier: ^5.9.3
version: 5.9.3
packages:
'@esbuild/aix-ppc64@0.27.2':
resolution: {integrity: sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==}
engines: {node: '>=18'}
cpu: [ppc64]
os: [aix]
'@esbuild/android-arm64@0.27.2':
resolution: {integrity: sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==}
engines: {node: '>=18'}
cpu: [arm64]
os: [android]
'@esbuild/android-arm@0.27.2':
resolution: {integrity: sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==}
engines: {node: '>=18'}
cpu: [arm]
os: [android]
'@esbuild/android-x64@0.27.2':
resolution: {integrity: sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==}
engines: {node: '>=18'}
cpu: [x64]
os: [android]
'@esbuild/darwin-arm64@0.27.2':
resolution: {integrity: sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==}
engines: {node: '>=18'}
cpu: [arm64]
os: [darwin]
'@esbuild/darwin-x64@0.27.2':
resolution: {integrity: sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==}
engines: {node: '>=18'}
cpu: [x64]
os: [darwin]
'@esbuild/freebsd-arm64@0.27.2':
resolution: {integrity: sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==}
engines: {node: '>=18'}
cpu: [arm64]
os: [freebsd]
'@esbuild/freebsd-x64@0.27.2':
resolution: {integrity: sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==}
engines: {node: '>=18'}
cpu: [x64]
os: [freebsd]
'@esbuild/linux-arm64@0.27.2':
resolution: {integrity: sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==}
engines: {node: '>=18'}
cpu: [arm64]
os: [linux]
'@esbuild/linux-arm@0.27.2':
resolution: {integrity: sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==}
engines: {node: '>=18'}
cpu: [arm]
os: [linux]
'@esbuild/linux-ia32@0.27.2':
resolution: {integrity: sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==}
engines: {node: '>=18'}
cpu: [ia32]
os: [linux]
'@esbuild/linux-loong64@0.27.2':
resolution: {integrity: sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==}
engines: {node: '>=18'}
cpu: [loong64]
os: [linux]
'@esbuild/linux-mips64el@0.27.2':
resolution: {integrity: sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==}
engines: {node: '>=18'}
cpu: [mips64el]
os: [linux]
'@esbuild/linux-ppc64@0.27.2':
resolution: {integrity: sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==}
engines: {node: '>=18'}
cpu: [ppc64]
os: [linux]
'@esbuild/linux-riscv64@0.27.2':
resolution: {integrity: sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==}
engines: {node: '>=18'}
cpu: [riscv64]
os: [linux]
'@esbuild/linux-s390x@0.27.2':
resolution: {integrity: sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==}
engines: {node: '>=18'}
cpu: [s390x]
os: [linux]
'@esbuild/linux-x64@0.27.2':
resolution: {integrity: sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==}
engines: {node: '>=18'}
cpu: [x64]
os: [linux]
'@esbuild/netbsd-arm64@0.27.2':
resolution: {integrity: sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==}
engines: {node: '>=18'}
cpu: [arm64]
os: [netbsd]
'@esbuild/netbsd-x64@0.27.2':
resolution: {integrity: sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==}
engines: {node: '>=18'}
cpu: [x64]
os: [netbsd]
'@esbuild/openbsd-arm64@0.27.2':
resolution: {integrity: sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==}
engines: {node: '>=18'}
cpu: [arm64]
os: [openbsd]
'@esbuild/openbsd-x64@0.27.2':
resolution: {integrity: sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==}
engines: {node: '>=18'}
cpu: [x64]
os: [openbsd]
'@esbuild/openharmony-arm64@0.27.2':
resolution: {integrity: sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==}
engines: {node: '>=18'}
cpu: [arm64]
os: [openharmony]
'@esbuild/sunos-x64@0.27.2':
resolution: {integrity: sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==}
engines: {node: '>=18'}
cpu: [x64]
os: [sunos]
'@esbuild/win32-arm64@0.27.2':
resolution: {integrity: sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==}
engines: {node: '>=18'}
cpu: [arm64]
os: [win32]
'@esbuild/win32-ia32@0.27.2':
resolution: {integrity: sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==}
engines: {node: '>=18'}
cpu: [ia32]
os: [win32]
'@esbuild/win32-x64@0.27.2':
resolution: {integrity: sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==}
engines: {node: '>=18'}
cpu: [x64]
os: [win32]
'@types/node@25.0.9':
resolution: {integrity: sha512-/rpCXHlCWeqClNBwUhDcusJxXYDjZTyE8v5oTO7WbL8eij2nKhUeU89/6xgjU7N4/Vh3He0BtyhJdQbDyhiXAw==}
aws-ssl-profiles@1.1.2:
resolution: {integrity: sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g==}
engines: {node: '>= 6.0.0'}
chalk@5.6.2:
resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==}
engines: {node: ^12.17.0 || ^14.13 || >=16.0.0}
denque@2.1.0:
resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==}
engines: {node: '>=0.10'}
esbuild@0.27.2:
resolution: {integrity: sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==}
engines: {node: '>=18'}
hasBin: true
fsevents@2.3.3:
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
os: [darwin]
generate-function@2.3.1:
resolution: {integrity: sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==}
get-tsconfig@4.13.0:
resolution: {integrity: sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==}
iconv-lite@0.7.2:
resolution: {integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==}
engines: {node: '>=0.10.0'}
is-property@1.0.2:
resolution: {integrity: sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==}
long@5.3.2:
resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==}
lru.min@1.1.3:
resolution: {integrity: sha512-Lkk/vx6ak3rYkRR0Nhu4lFUT2VDnQSxBe8Hbl7f36358p6ow8Bnvr8lrLt98H8J1aGxfhbX4Fs5tYg2+FTwr5Q==}
engines: {bun: '>=1.0.0', deno: '>=1.30.0', node: '>=8.0.0'}
mysql2@3.16.1:
resolution: {integrity: sha512-b75qsDB3ieYEzMsT1uRGsztM/sy6vWPY40uPZlVVl8eefAotFCoS7jaDB5DxDNtlW5kdVGd9jptSpkvujNxI2A==}
engines: {node: '>= 8.0'}
named-placeholders@1.1.6:
resolution: {integrity: sha512-Tz09sEL2EEuv5fFowm419c1+a/jSMiBjI9gHxVLrVdbUkkNUUfjsVYs9pVZu5oCon/kmRh9TfLEObFtkVxmY0w==}
engines: {node: '>=8.0.0'}
nepali-date-library@1.1.12:
resolution: {integrity: sha512-hMgTBaJWxU9mBbV2aiH2xtuwImokXt9qhv4u7IZ1I2JJhVVa5LtuNtJXZYU6DVrGaWkMppv2dT9VfeOZwM1Kqw==}
engines: {node: '>=24.0.0 <25.0.0'}
prettier@3.8.0:
resolution: {integrity: sha512-yEPsovQfpxYfgWNhCfECjG5AQaO+K3dp6XERmOepyPDVqcJm+bjyCVO3pmU+nAPe0N5dDvekfGezt/EIiRe1TA==}
engines: {node: '>=14'}
hasBin: true
resolve-pkg-maps@1.0.0:
resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
safer-buffer@2.1.2:
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
seq-queue@0.0.5:
resolution: {integrity: sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q==}
sqlstring@2.3.3:
resolution: {integrity: sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==}
engines: {node: '>= 0.6'}
tsx@4.21.0:
resolution: {integrity: sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==}
engines: {node: '>=18.0.0'}
hasBin: true
typescript@5.9.3:
resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==}
engines: {node: '>=14.17'}
hasBin: true
undici-types@7.16.0:
resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==}
snapshots:
'@esbuild/aix-ppc64@0.27.2':
optional: true
'@esbuild/android-arm64@0.27.2':
optional: true
'@esbuild/android-arm@0.27.2':
optional: true
'@esbuild/android-x64@0.27.2':
optional: true
'@esbuild/darwin-arm64@0.27.2':
optional: true
'@esbuild/darwin-x64@0.27.2':
optional: true
'@esbuild/freebsd-arm64@0.27.2':
optional: true
'@esbuild/freebsd-x64@0.27.2':
optional: true
'@esbuild/linux-arm64@0.27.2':
optional: true
'@esbuild/linux-arm@0.27.2':
optional: true
'@esbuild/linux-ia32@0.27.2':
optional: true
'@esbuild/linux-loong64@0.27.2':
optional: true
'@esbuild/linux-mips64el@0.27.2':
optional: true
'@esbuild/linux-ppc64@0.27.2':
optional: true
'@esbuild/linux-riscv64@0.27.2':
optional: true
'@esbuild/linux-s390x@0.27.2':
optional: true
'@esbuild/linux-x64@0.27.2':
optional: true
'@esbuild/netbsd-arm64@0.27.2':
optional: true
'@esbuild/netbsd-x64@0.27.2':
optional: true
'@esbuild/openbsd-arm64@0.27.2':
optional: true
'@esbuild/openbsd-x64@0.27.2':
optional: true
'@esbuild/openharmony-arm64@0.27.2':
optional: true
'@esbuild/sunos-x64@0.27.2':
optional: true
'@esbuild/win32-arm64@0.27.2':
optional: true
'@esbuild/win32-ia32@0.27.2':
optional: true
'@esbuild/win32-x64@0.27.2':
optional: true
'@types/node@25.0.9':
dependencies:
undici-types: 7.16.0
aws-ssl-profiles@1.1.2: {}
chalk@5.6.2: {}
denque@2.1.0: {}
esbuild@0.27.2:
optionalDependencies:
'@esbuild/aix-ppc64': 0.27.2
'@esbuild/android-arm': 0.27.2
'@esbuild/android-arm64': 0.27.2
'@esbuild/android-x64': 0.27.2
'@esbuild/darwin-arm64': 0.27.2
'@esbuild/darwin-x64': 0.27.2
'@esbuild/freebsd-arm64': 0.27.2
'@esbuild/freebsd-x64': 0.27.2
'@esbuild/linux-arm': 0.27.2
'@esbuild/linux-arm64': 0.27.2
'@esbuild/linux-ia32': 0.27.2
'@esbuild/linux-loong64': 0.27.2
'@esbuild/linux-mips64el': 0.27.2
'@esbuild/linux-ppc64': 0.27.2
'@esbuild/linux-riscv64': 0.27.2
'@esbuild/linux-s390x': 0.27.2
'@esbuild/linux-x64': 0.27.2
'@esbuild/netbsd-arm64': 0.27.2
'@esbuild/netbsd-x64': 0.27.2
'@esbuild/openbsd-arm64': 0.27.2
'@esbuild/openbsd-x64': 0.27.2
'@esbuild/openharmony-arm64': 0.27.2
'@esbuild/sunos-x64': 0.27.2
'@esbuild/win32-arm64': 0.27.2
'@esbuild/win32-ia32': 0.27.2
'@esbuild/win32-x64': 0.27.2
fsevents@2.3.3:
optional: true
generate-function@2.3.1:
dependencies:
is-property: 1.0.2
get-tsconfig@4.13.0:
dependencies:
resolve-pkg-maps: 1.0.0
iconv-lite@0.7.2:
dependencies:
safer-buffer: 2.1.2
is-property@1.0.2: {}
long@5.3.2: {}
lru.min@1.1.3: {}
mysql2@3.16.1:
dependencies:
aws-ssl-profiles: 1.1.2
denque: 2.1.0
generate-function: 2.3.1
iconv-lite: 0.7.2
long: 5.3.2
lru.min: 1.1.3
named-placeholders: 1.1.6
seq-queue: 0.0.5
sqlstring: 2.3.3
named-placeholders@1.1.6:
dependencies:
lru.min: 1.1.3
nepali-date-library@1.1.12: {}
prettier@3.8.0: {}
resolve-pkg-maps@1.0.0: {}
safer-buffer@2.1.2: {}
seq-queue@0.0.5: {}
sqlstring@2.3.3: {}
tsx@4.21.0:
dependencies:
esbuild: 0.27.2
get-tsconfig: 4.13.0
optionalDependencies:
fsevents: 2.3.3
typescript@5.9.3: {}
undici-types@7.16.0: {}

72
src/helper/dbConnector.ts Normal file
View File

@ -0,0 +1,72 @@
import mysql, { Pool, ResultSetHeader } from "mysql2/promise";
import { logger } from "./logger";
type DbConfig = {
host: string;
user: string;
password: string;
database: string;
connectionLimit?: number;
port?: number;
};
export class Database {
private pool?: Pool;
constructor(private readonly config: DbConfig) {}
start() {
if (this.pool) return;
this.pool = mysql.createPool({
...this.config,
waitForConnections: true,
connectionLimit: this.config.connectionLimit ?? 10,
queueLimit: 0,
});
logger.success("MySQL pool started");
}
async execute<T = any>(
sql: string,
params?: any[],
): Promise<T | ResultSetHeader> {
if (!this.pool) {
throw new Error("Database not started");
}
try {
const [result] = await this.pool.execute(sql, params);
return result as T | ResultSetHeader;
} catch (err: any) {
if (
err.code === "PROTOCOL_CONNECTION_LOST" ||
err.code === "ECONNRESET" ||
err.code === "ER_SERVER_SHUTDOWN"
) {
logger.error("Database connection lost, retry may succeed");
}
throw err;
}
}
async healthCheck(): Promise<boolean> {
try {
await this.execute("SELECT 1");
return true;
} catch {
return false;
}
}
async stop() {
if (!this.pool) return;
await this.pool.end();
this.pool = undefined;
logger.success("MySQL pool stopped");
}
}

38
src/helper/logger.ts Normal file
View File

@ -0,0 +1,38 @@
import chalk from "chalk";
const timestamp = () => chalk.gray(new Date().toISOString());
export const logger = {
info: (...args: any[]) =>
console.log(`${chalk.blue(chalk.bold("[INFO]"))} ${timestamp()}`, chalk.cyan(...args)),
success: (...args: any[]) =>
console.log(`${chalk.green(chalk.bold("[SUCCESS]"))} ${timestamp()}`, chalk.white(...args)),
warn: (...args: any[]) =>
console.warn(`${chalk.yellow(chalk.bold("[WARN]"))} ${timestamp()}`, chalk.green(...args)),
error: (...args: any[]) =>
console.error(`${chalk.red(chalk.bold("[ERROR]"))} ${timestamp()}`, chalk.redBright(...args)),
debug: (...args: any[]) =>
console.log(`${chalk.magenta(chalk.bold("[DEBUG]"))} ${timestamp()}`, chalk.gray(...args)),
bold: (...args: any[]) => console.log(chalk.bold(...args)),
underline: (...args: any[]) => console.log(chalk.underline(...args)),
color: (color: keyof typeof chalk, ...args: any[]) => {
const fn = (chalk as any)[color];
if (fn) console.log(fn(...args));
else console.log(...args);
},
bg: (bgColor: keyof typeof chalk, ...args: any[]) => {
const fn = (chalk as any)[bgColor];
if (fn) console.log(fn(...args));
else console.log(...args);
},
table: (obj: any) => console.table(obj),
};

137
src/index.ts Normal file
View File

@ -0,0 +1,137 @@
import { Database } from "./helper/dbConnector";
import { logger } from "./helper/logger";
import NepaliDate, { BStoAD, NEPALI_DATE_MAP } from "nepali-date-library";
interface WarningType {
Level: string;
Code: number;
Message: string;
}
const db = new Database({
host: "localhost",
user: "root",
password: "rootooro",
database: "date",
port: 3306,
});
export { db };
async function main() {
//Start Connection
db.start();
//Create Update Table
try {
const result = await db.execute(`
CREATE TABLE IF NOT EXISTS date_map (
id INT PRIMARY KEY AUTO_INCREMENT,
nepali_date VARCHAR(20),
english_date VARCHAR(20) UNIQUE
);
`);
logger.info("Table creation checked / executed.");
if ((result as any).warningStatus > 0) {
const warnings: WarningType[] = (await db.execute<WarningType[]>(
"SHOW WARNINGS",
)) as WarningType[];
if (warnings) {
for (const warn of warnings) {
logger.warn(`[${warn.Level}] ${warn.Message}`);
}
}
}
} catch (err: any) {
logger.error("Failed to create table:", err.code, err.message);
}
//Insert Table
const data = getRangeSet(1976, 2100);
const totalStart = Date.now();
for (const item of data) {
const rows: { nepaliDate: string; englishDate: string }[] = [];
const yearStart = Date.now();
for (let month = 0; month <= 11; month++) {
for (let day = 1; day <= item.days[month]; day++) {
const nepaliDate = new NepaliDate(item.year, month, day).format("YYYY-MM-DD");
const englishDate = BStoAD(nepaliDate);
rows.push({ nepaliDate: nepaliDate, englishDate: englishDate });
}
}
if (rows.length === 0) continue;
const values = rows.map((r) => `('${r.nepaliDate}', '${r.englishDate}')`);
const sql = `
INSERT INTO date_map (nepali_date, english_date)
VALUES ${values}
ON DUPLICATE KEY UPDATE nepali_date = VALUES(nepali_date)
`;
try {
await db.execute(sql);
logger.info(`Year ${item.year} inserted in ${Date.now() - yearStart}ms`);
} catch (e: any) {
logger.error(`Year ${item.year} failed:`, e.message || e);
}
}
logger.info(`Total time taken: ${Date.now() - totalStart}ms`);
//Stop Connection
await db.stop();
}
main().catch(console.error);
async function shutdown(code = 0) {
console.log("Shutting down.");
await db.stop();
process.exit(code);
}
process.on("SIGINT", shutdown);
process.on("SIGTERM", shutdown);
process.on("uncaughtException", async (err) => {
console.error(err);
await shutdown(1);
});
process.on("unhandledRejection", async (reason) => {
console.error(reason);
await shutdown(1);
});
const getRangeSet = (fromYear: number, toYear: number) => {
if (fromYear > toYear) {
throw new Error(`fromYear (${fromYear}) cannot be greater than toYear (${toYear})`);
}
const fromExists = NEPALI_DATE_MAP.find(
(item: (typeof NEPALI_DATE_MAP)[0]) => item.year === fromYear,
);
const toExists = NEPALI_DATE_MAP.find(
(item: (typeof NEPALI_DATE_MAP)[0]) => item.year === toYear,
);
if (!fromExists || !toExists) {
throw new Error(
`Invalid range: ${!fromExists ? fromYear : ""} ${!toExists ? toYear : ""} year(s) not found in NEPALI_DATE_MAP`,
);
}
const range = NEPALI_DATE_MAP.filter(
(item: (typeof NEPALI_DATE_MAP)[0]) => item.year >= fromYear && item.year <= toYear,
);
return range;
};

12
tsconfig.json Normal file
View File

@ -0,0 +1,12 @@
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"strict": true,
"esModuleInterop": true,
"moduleResolution": "NodeNext",
"skipLibCheck": true,
"types": ["node"]
},
"include": ["src/**/*.ts"]
}