@underundre/undev 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +148 -0
- package/README.ru.md +148 -0
- package/configs/.editorconfig +28 -0
- package/configs/commitlint.config.js +36 -0
- package/configs/eslint.config.js +58 -0
- package/configs/prettier.config.js +23 -0
- package/configs/tsconfig.base.json +23 -0
- package/package.json +53 -0
- package/scripts/common.sh +74 -0
- package/scripts/db/backup.sh +53 -0
- package/scripts/db/restore.sh +46 -0
- package/scripts/deploy/deploy.sh +102 -0
- package/scripts/deploy/logs.sh +40 -0
- package/scripts/deploy/rollback.sh +46 -0
- package/scripts/dev/setup.sh +69 -0
- package/scripts/docker/cleanup.sh +49 -0
- package/scripts/monitoring/security-audit.sh +76 -0
- package/scripts/server/health-check.sh +83 -0
- package/scripts/server/setup-ssl.sh +30 -0
- package/scripts/server/setup-vps.sh +92 -0
- package/templates/.env.example +32 -0
- package/templates/.github/workflows/ci.yml +48 -0
- package/templates/docker-compose.dev.yml +41 -0
- package/templates/package-scripts.jsonc +52 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Undre
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# @underundre/undev
|
|
2
|
+
|
|
3
|
+
Reusable dev scripts, configs, and templates for Node.js/TypeScript projects.
|
|
4
|
+
|
|
5
|
+
[Русская версия](README.ru.md)
|
|
6
|
+
|
|
7
|
+
## What's Inside
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
configs/ # Shareable tool configs
|
|
11
|
+
eslint.config.js # ESLint flat config (TS strict)
|
|
12
|
+
prettier.config.js # Prettier rules
|
|
13
|
+
tsconfig.base.json # TypeScript strict base
|
|
14
|
+
commitlint.config.js # Conventional Commits
|
|
15
|
+
.editorconfig # IDE settings
|
|
16
|
+
|
|
17
|
+
scripts/ # Bash scripts (parameterized via env vars)
|
|
18
|
+
common.sh # Shared utils (colors, logging, confirm, telegram)
|
|
19
|
+
deploy/
|
|
20
|
+
deploy.sh # Zero-downtime SSH deploy
|
|
21
|
+
rollback.sh # Rollback to previous deploy
|
|
22
|
+
logs.sh # Tail prod logs (pm2/docker/nginx)
|
|
23
|
+
db/
|
|
24
|
+
backup.sh # PostgreSQL backup with retention
|
|
25
|
+
restore.sh # PostgreSQL restore from dump
|
|
26
|
+
server/
|
|
27
|
+
setup-vps.sh # Fresh VPS bootstrap (user, ssh, ufw, node, pm2)
|
|
28
|
+
setup-ssl.sh # Let's Encrypt + auto-renewal
|
|
29
|
+
health-check.sh # Disk/memory/CPU/services check
|
|
30
|
+
docker/
|
|
31
|
+
cleanup.sh # Prune images, containers, volumes
|
|
32
|
+
dev/
|
|
33
|
+
setup.sh # Clone → install → .env → migrate → build
|
|
34
|
+
monitoring/
|
|
35
|
+
security-audit.sh # npm audit + secret scan + outdated deps
|
|
36
|
+
|
|
37
|
+
templates/ # Copy into your project
|
|
38
|
+
.github/workflows/ci.yml # GitHub Actions CI pipeline
|
|
39
|
+
.env.example # Environment variables template
|
|
40
|
+
docker-compose.dev.yml # Dev DB (Postgres + Redis)
|
|
41
|
+
package-scripts.jsonc # Recommended npm scripts reference
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Usage: Configs
|
|
45
|
+
|
|
46
|
+
Install as dev dependency:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npm i -D @underundre/undev
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### ESLint
|
|
53
|
+
|
|
54
|
+
```js
|
|
55
|
+
// eslint.config.js
|
|
56
|
+
import baseConfig from "@underundre/undev/eslint";
|
|
57
|
+
export default [...baseConfig];
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### TypeScript
|
|
61
|
+
|
|
62
|
+
```json
|
|
63
|
+
// tsconfig.json
|
|
64
|
+
{
|
|
65
|
+
"extends": "@underundre/undev/tsconfig",
|
|
66
|
+
"compilerOptions": {
|
|
67
|
+
"outDir": "./dist",
|
|
68
|
+
"rootDir": "./src"
|
|
69
|
+
},
|
|
70
|
+
"include": ["src"]
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Prettier
|
|
75
|
+
|
|
76
|
+
```json
|
|
77
|
+
// package.json
|
|
78
|
+
{ "prettier": "@underundre/undev/prettier" }
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Commitlint
|
|
82
|
+
|
|
83
|
+
```js
|
|
84
|
+
// commitlint.config.js
|
|
85
|
+
export default { extends: ["@underundre/undev/commitlint"] };
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Usage: Scripts
|
|
89
|
+
|
|
90
|
+
Copy the scripts you need into your project:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
# Copy deploy scripts
|
|
94
|
+
cp -r node_modules/@underundre/undev/scripts/deploy ./scripts/deploy
|
|
95
|
+
cp node_modules/@underundre/undev/scripts/common.sh ./scripts/
|
|
96
|
+
|
|
97
|
+
# Or cherry-pick
|
|
98
|
+
cp node_modules/@underundre/undev/scripts/db/backup.sh ./scripts/
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
All scripts read config from environment variables. Set them in `.env.production` or pass inline:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
PROD_SSH_HOST=deploy@myserver.com REMOTE_APP_DIR=/home/deploy/app ./scripts/deploy/deploy.sh
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Script Config Reference
|
|
108
|
+
|
|
109
|
+
| Variable | Used by | Default |
|
|
110
|
+
|----------|---------|---------|
|
|
111
|
+
| `PROD_SSH_HOST` | deploy, rollback, logs | required |
|
|
112
|
+
| `REMOTE_APP_DIR` | deploy, rollback | required |
|
|
113
|
+
| `POSTGRES_HOST` | db/backup, db/restore | `localhost` |
|
|
114
|
+
| `POSTGRES_PORT` | db/backup, db/restore | `5432` |
|
|
115
|
+
| `POSTGRES_USER` | db/backup, db/restore | `postgres` |
|
|
116
|
+
| `POSTGRES_DB` | db/backup, db/restore | required |
|
|
117
|
+
| `BACKUP_DIR` | db/backup | `./backups` |
|
|
118
|
+
| `RETENTION_DAYS` | db/backup | `14` |
|
|
119
|
+
| `TELEGRAM_BOT_TOKEN` | all (optional notifications) | — |
|
|
120
|
+
| `TELEGRAM_CHAT_ID` | all (optional notifications) | — |
|
|
121
|
+
|
|
122
|
+
## Usage: Templates
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
# CI workflow
|
|
126
|
+
cp node_modules/@underundre/undev/templates/.github/workflows/ci.yml .github/workflows/
|
|
127
|
+
|
|
128
|
+
# Environment template
|
|
129
|
+
cp node_modules/@underundre/undev/templates/.env.example .
|
|
130
|
+
|
|
131
|
+
# Dev Docker Compose
|
|
132
|
+
cp node_modules/@underundre/undev/templates/docker-compose.dev.yml .
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## npm Scripts Reference
|
|
136
|
+
|
|
137
|
+
See `templates/package-scripts.jsonc` for a complete set of recommended scripts. Key ones:
|
|
138
|
+
|
|
139
|
+
```json
|
|
140
|
+
{
|
|
141
|
+
"validate": "npm run lint && npm run typecheck && npm run format:check",
|
|
142
|
+
"validate:fix": "npm run lint:fix && npm run typecheck && npm run format"
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## License
|
|
147
|
+
|
|
148
|
+
MIT
|
package/README.ru.md
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# @underundre/undev
|
|
2
|
+
|
|
3
|
+
Переиспользуемые dev-скрипты, конфиги и шаблоны для Node.js/TypeScript проектов.
|
|
4
|
+
|
|
5
|
+
[English version](README.md)
|
|
6
|
+
|
|
7
|
+
## Что внутри
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
configs/ # Шарируемые конфиги инструментов
|
|
11
|
+
eslint.config.js # ESLint flat config (строгий TS)
|
|
12
|
+
prettier.config.js # Prettier правила
|
|
13
|
+
tsconfig.base.json # TypeScript strict база
|
|
14
|
+
commitlint.config.js # Conventional Commits
|
|
15
|
+
.editorconfig # Настройки IDE
|
|
16
|
+
|
|
17
|
+
scripts/ # Bash-скрипты (параметризованы через env vars)
|
|
18
|
+
common.sh # Общие утилиты (цвета, логирование, confirm, telegram)
|
|
19
|
+
deploy/
|
|
20
|
+
deploy.sh # Zero-downtime SSH деплой
|
|
21
|
+
rollback.sh # Откат на предыдущий деплой
|
|
22
|
+
logs.sh # Tail логов на проде (pm2/docker/nginx)
|
|
23
|
+
db/
|
|
24
|
+
backup.sh # Бэкап PostgreSQL с ротацией
|
|
25
|
+
restore.sh # Восстановление PostgreSQL из дампа
|
|
26
|
+
server/
|
|
27
|
+
setup-vps.sh # Настройка свежего VPS (юзер, ssh, ufw, node, pm2)
|
|
28
|
+
setup-ssl.sh # Let's Encrypt + автообновление
|
|
29
|
+
health-check.sh # Проверка диска/памяти/CPU/сервисов
|
|
30
|
+
docker/
|
|
31
|
+
cleanup.sh # Очистка images, containers, volumes
|
|
32
|
+
dev/
|
|
33
|
+
setup.sh # Клон → установка → .env → миграции → билд
|
|
34
|
+
monitoring/
|
|
35
|
+
security-audit.sh # npm audit + сканирование секретов + устаревшие зависимости
|
|
36
|
+
|
|
37
|
+
templates/ # Скопировать в свой проект
|
|
38
|
+
.github/workflows/ci.yml # GitHub Actions CI пайплайн
|
|
39
|
+
.env.example # Шаблон переменных окружения
|
|
40
|
+
docker-compose.dev.yml # Dev БД (Postgres + Redis)
|
|
41
|
+
package-scripts.jsonc # Рекомендуемые npm scripts
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Использование: Конфиги
|
|
45
|
+
|
|
46
|
+
Установить как dev-зависимость:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npm i -D @underundre/undev
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### ESLint
|
|
53
|
+
|
|
54
|
+
```js
|
|
55
|
+
// eslint.config.js
|
|
56
|
+
import baseConfig from "@underundre/undev/eslint";
|
|
57
|
+
export default [...baseConfig];
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### TypeScript
|
|
61
|
+
|
|
62
|
+
```json
|
|
63
|
+
// tsconfig.json
|
|
64
|
+
{
|
|
65
|
+
"extends": "@underundre/undev/tsconfig",
|
|
66
|
+
"compilerOptions": {
|
|
67
|
+
"outDir": "./dist",
|
|
68
|
+
"rootDir": "./src"
|
|
69
|
+
},
|
|
70
|
+
"include": ["src"]
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Prettier
|
|
75
|
+
|
|
76
|
+
```json
|
|
77
|
+
// package.json
|
|
78
|
+
{ "prettier": "@underundre/undev/prettier" }
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Commitlint
|
|
82
|
+
|
|
83
|
+
```js
|
|
84
|
+
// commitlint.config.js
|
|
85
|
+
export default { extends: ["@underundre/undev/commitlint"] };
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Использование: Скрипты
|
|
89
|
+
|
|
90
|
+
Скопировать нужные скрипты в проект:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
# Скопировать скрипты деплоя
|
|
94
|
+
cp -r node_modules/@underundre/undev/scripts/deploy ./scripts/deploy
|
|
95
|
+
cp node_modules/@underundre/undev/scripts/common.sh ./scripts/
|
|
96
|
+
|
|
97
|
+
# Или по одному
|
|
98
|
+
cp node_modules/@underundre/undev/scripts/db/backup.sh ./scripts/
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Все скрипты читают конфиг из переменных окружения. Задать в `.env.production` или передать инлайн:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
PROD_SSH_HOST=deploy@myserver.com REMOTE_APP_DIR=/home/deploy/app ./scripts/deploy/deploy.sh
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Переменные окружения
|
|
108
|
+
|
|
109
|
+
| Переменная | Используется | По умолчанию |
|
|
110
|
+
|-----------|-------------|-------------|
|
|
111
|
+
| `PROD_SSH_HOST` | deploy, rollback, logs | обязательно |
|
|
112
|
+
| `REMOTE_APP_DIR` | deploy, rollback | обязательно |
|
|
113
|
+
| `POSTGRES_HOST` | db/backup, db/restore | `localhost` |
|
|
114
|
+
| `POSTGRES_PORT` | db/backup, db/restore | `5432` |
|
|
115
|
+
| `POSTGRES_USER` | db/backup, db/restore | `postgres` |
|
|
116
|
+
| `POSTGRES_DB` | db/backup, db/restore | обязательно |
|
|
117
|
+
| `BACKUP_DIR` | db/backup | `./backups` |
|
|
118
|
+
| `RETENTION_DAYS` | db/backup | `14` |
|
|
119
|
+
| `TELEGRAM_BOT_TOKEN` | все (опц. уведомления) | — |
|
|
120
|
+
| `TELEGRAM_CHAT_ID` | все (опц. уведомления) | — |
|
|
121
|
+
|
|
122
|
+
## Использование: Шаблоны
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
# CI workflow
|
|
126
|
+
cp node_modules/@underundre/undev/templates/.github/workflows/ci.yml .github/workflows/
|
|
127
|
+
|
|
128
|
+
# Шаблон окружения
|
|
129
|
+
cp node_modules/@underundre/undev/templates/.env.example .
|
|
130
|
+
|
|
131
|
+
# Dev Docker Compose
|
|
132
|
+
cp node_modules/@underundre/undev/templates/docker-compose.dev.yml .
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## npm Scripts
|
|
136
|
+
|
|
137
|
+
См. `templates/package-scripts.jsonc`. Ключевые:
|
|
138
|
+
|
|
139
|
+
```json
|
|
140
|
+
{
|
|
141
|
+
"validate": "npm run lint && npm run typecheck && npm run format:check",
|
|
142
|
+
"validate:fix": "npm run lint:fix && npm run typecheck && npm run format"
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Лицензия
|
|
147
|
+
|
|
148
|
+
MIT
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
root = true
|
|
2
|
+
|
|
3
|
+
[*]
|
|
4
|
+
charset = utf-8
|
|
5
|
+
indent_style = space
|
|
6
|
+
indent_size = 2
|
|
7
|
+
end_of_line = lf
|
|
8
|
+
insert_final_newline = true
|
|
9
|
+
trim_trailing_whitespace = true
|
|
10
|
+
|
|
11
|
+
[*.md]
|
|
12
|
+
trim_trailing_whitespace = false
|
|
13
|
+
|
|
14
|
+
[Makefile]
|
|
15
|
+
indent_style = tab
|
|
16
|
+
|
|
17
|
+
[*.{sh,bash}]
|
|
18
|
+
indent_size = 2
|
|
19
|
+
end_of_line = lf
|
|
20
|
+
|
|
21
|
+
[*.{yml,yaml}]
|
|
22
|
+
indent_size = 2
|
|
23
|
+
|
|
24
|
+
[*.{json,jsonc}]
|
|
25
|
+
indent_size = 2
|
|
26
|
+
|
|
27
|
+
[*.{sql}]
|
|
28
|
+
indent_size = 4
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shareable commitlint config — Conventional Commits.
|
|
3
|
+
*
|
|
4
|
+
* Usage in your project:
|
|
5
|
+
* export default { extends: ["@underundre/undev/commitlint"] };
|
|
6
|
+
*
|
|
7
|
+
* Or import directly:
|
|
8
|
+
* import config from "@underundre/undev/commitlint";
|
|
9
|
+
* export default config;
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
export default {
|
|
13
|
+
extends: ["@commitlint/config-conventional"],
|
|
14
|
+
rules: {
|
|
15
|
+
"type-enum": [
|
|
16
|
+
2,
|
|
17
|
+
"always",
|
|
18
|
+
[
|
|
19
|
+
"feat",
|
|
20
|
+
"fix",
|
|
21
|
+
"docs",
|
|
22
|
+
"style",
|
|
23
|
+
"refactor",
|
|
24
|
+
"perf",
|
|
25
|
+
"test",
|
|
26
|
+
"build",
|
|
27
|
+
"ci",
|
|
28
|
+
"chore",
|
|
29
|
+
"revert",
|
|
30
|
+
],
|
|
31
|
+
],
|
|
32
|
+
"subject-case": [2, "never", ["start-case", "pascal-case", "upper-case"]],
|
|
33
|
+
"subject-max-length": [2, "always", 100],
|
|
34
|
+
"body-max-line-length": [1, "always", 100],
|
|
35
|
+
},
|
|
36
|
+
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shareable ESLint flat config for TypeScript projects.
|
|
3
|
+
*
|
|
4
|
+
* Usage in your project:
|
|
5
|
+
* import baseConfig from "@underundre/undev/eslint";
|
|
6
|
+
* export default [...baseConfig, { /* your overrides * / }];
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import js from "@eslint/js";
|
|
10
|
+
import tsPlugin from "@typescript-eslint/eslint-plugin";
|
|
11
|
+
import tsParser from "@typescript-eslint/parser";
|
|
12
|
+
|
|
13
|
+
/** @type {import("eslint").Linter.Config[]} */
|
|
14
|
+
export default [
|
|
15
|
+
js.configs.recommended,
|
|
16
|
+
{
|
|
17
|
+
files: ["**/*.ts", "**/*.tsx", "**/*.mts"],
|
|
18
|
+
languageOptions: {
|
|
19
|
+
parser: tsParser,
|
|
20
|
+
parserOptions: {
|
|
21
|
+
projectService: true,
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
plugins: {
|
|
25
|
+
"@typescript-eslint": tsPlugin,
|
|
26
|
+
},
|
|
27
|
+
rules: {
|
|
28
|
+
// TypeScript strict
|
|
29
|
+
"@typescript-eslint/no-explicit-any": "error",
|
|
30
|
+
"@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_" }],
|
|
31
|
+
"@typescript-eslint/consistent-type-imports": ["error", { prefer: "type-imports" }],
|
|
32
|
+
"@typescript-eslint/no-import-type-side-effects": "error",
|
|
33
|
+
|
|
34
|
+
// Safety
|
|
35
|
+
"no-console": ["warn", { allow: ["warn", "error"] }],
|
|
36
|
+
"no-debugger": "error",
|
|
37
|
+
"no-eval": "error",
|
|
38
|
+
"no-implied-eval": "error",
|
|
39
|
+
"prefer-const": "error",
|
|
40
|
+
"no-var": "error",
|
|
41
|
+
eqeqeq: ["error", "always"],
|
|
42
|
+
|
|
43
|
+
// Style (let prettier handle formatting)
|
|
44
|
+
"no-multiple-empty-lines": ["error", { max: 1 }],
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
ignores: [
|
|
49
|
+
"node_modules/",
|
|
50
|
+
"dist/",
|
|
51
|
+
"build/",
|
|
52
|
+
"coverage/",
|
|
53
|
+
"*.min.js",
|
|
54
|
+
".next/",
|
|
55
|
+
".nuxt/",
|
|
56
|
+
],
|
|
57
|
+
},
|
|
58
|
+
];
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shareable Prettier config.
|
|
3
|
+
*
|
|
4
|
+
* Usage in your project's package.json:
|
|
5
|
+
* "prettier": "@underundre/undev/prettier"
|
|
6
|
+
*
|
|
7
|
+
* Or in prettier.config.js:
|
|
8
|
+
* import config from "@underundre/undev/prettier";
|
|
9
|
+
* export default { ...config, /* overrides */ };
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/** @type {import("prettier").Config} */
|
|
13
|
+
export default {
|
|
14
|
+
semi: true,
|
|
15
|
+
singleQuote: false,
|
|
16
|
+
tabWidth: 2,
|
|
17
|
+
trailingComma: "all",
|
|
18
|
+
printWidth: 100,
|
|
19
|
+
bracketSpacing: true,
|
|
20
|
+
arrowParens: "always",
|
|
21
|
+
endOfLine: "lf",
|
|
22
|
+
plugins: [],
|
|
23
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json.schemastore.org/tsconfig",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"target": "ES2022",
|
|
5
|
+
"module": "NodeNext",
|
|
6
|
+
"moduleResolution": "NodeNext",
|
|
7
|
+
"lib": ["ES2022"],
|
|
8
|
+
"strict": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"skipLibCheck": true,
|
|
11
|
+
"forceConsistentCasingInFileNames": true,
|
|
12
|
+
"resolveJsonModule": true,
|
|
13
|
+
"isolatedModules": true,
|
|
14
|
+
"declaration": true,
|
|
15
|
+
"declarationMap": true,
|
|
16
|
+
"sourceMap": true,
|
|
17
|
+
"noUncheckedIndexedAccess": true,
|
|
18
|
+
"noUnusedLocals": true,
|
|
19
|
+
"noUnusedParameters": true,
|
|
20
|
+
"noFallthroughCasesInSwitch": true,
|
|
21
|
+
"verbatimModuleSyntax": true
|
|
22
|
+
}
|
|
23
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@underundre/undev",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Reusable dev scripts, configs, and templates for Node.js/TypeScript projects",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"exports": {
|
|
7
|
+
"./eslint": "./configs/eslint.config.js",
|
|
8
|
+
"./prettier": "./configs/prettier.config.js",
|
|
9
|
+
"./tsconfig": "./configs/tsconfig.base.json",
|
|
10
|
+
"./commitlint": "./configs/commitlint.config.js"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"configs",
|
|
14
|
+
"scripts",
|
|
15
|
+
"templates"
|
|
16
|
+
],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"lint": "echo 'No source to lint'",
|
|
19
|
+
"test": "echo 'No tests yet'"
|
|
20
|
+
},
|
|
21
|
+
"keywords": [
|
|
22
|
+
"dev-scripts",
|
|
23
|
+
"configs",
|
|
24
|
+
"eslint",
|
|
25
|
+
"prettier",
|
|
26
|
+
"typescript",
|
|
27
|
+
"deploy",
|
|
28
|
+
"devops"
|
|
29
|
+
],
|
|
30
|
+
"author": "UnderUndre",
|
|
31
|
+
"license": "MIT",
|
|
32
|
+
"repository": {
|
|
33
|
+
"type": "git",
|
|
34
|
+
"url": "git+https://github.com/UnderUndre/undev.git"
|
|
35
|
+
},
|
|
36
|
+
"bugs": {
|
|
37
|
+
"url": "https://github.com/UnderUndre/undev/issues"
|
|
38
|
+
},
|
|
39
|
+
"homepage": "https://github.com/UnderUndre/undev#readme",
|
|
40
|
+
"engines": {
|
|
41
|
+
"node": ">=20.0.0"
|
|
42
|
+
},
|
|
43
|
+
"peerDependencies": {
|
|
44
|
+
"eslint": ">=9.0.0",
|
|
45
|
+
"prettier": ">=3.0.0",
|
|
46
|
+
"typescript": ">=5.0.0"
|
|
47
|
+
},
|
|
48
|
+
"peerDependenciesMeta": {
|
|
49
|
+
"eslint": { "optional": true },
|
|
50
|
+
"prettier": { "optional": true },
|
|
51
|
+
"typescript": { "optional": true }
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# ─────────────────────────────────────────────────
|
|
3
|
+
# Common utilities for all undev scripts.
|
|
4
|
+
# Source this at the top of every script:
|
|
5
|
+
# source "$(dirname "$0")/common.sh"
|
|
6
|
+
# ─────────────────────────────────────────────────
|
|
7
|
+
|
|
8
|
+
set -euo pipefail
|
|
9
|
+
|
|
10
|
+
# Colors
|
|
11
|
+
RED='\033[0;31m'
|
|
12
|
+
GREEN='\033[0;32m'
|
|
13
|
+
YELLOW='\033[1;33m'
|
|
14
|
+
BLUE='\033[0;34m'
|
|
15
|
+
CYAN='\033[0;36m'
|
|
16
|
+
NC='\033[0m'
|
|
17
|
+
|
|
18
|
+
# Detect repo root
|
|
19
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
20
|
+
REPO_ROOT="$(git -C "$SCRIPT_DIR" rev-parse --show-toplevel 2>/dev/null || dirname "$SCRIPT_DIR")"
|
|
21
|
+
|
|
22
|
+
# Logging
|
|
23
|
+
log() { echo -e "${GREEN}[$(date '+%H:%M:%S')]${NC} $1"; }
|
|
24
|
+
warn() { echo -e "${YELLOW}[$(date '+%H:%M:%S')] WARN:${NC} $1"; }
|
|
25
|
+
error() { echo -e "${RED}[$(date '+%H:%M:%S')] ERROR:${NC} $1" >&2; }
|
|
26
|
+
info() { echo -e "${CYAN}[$(date '+%H:%M:%S')]${NC} $1"; }
|
|
27
|
+
step() { echo -e "${BLUE}▸${NC} $1"; }
|
|
28
|
+
|
|
29
|
+
# Confirm prompt (skip if --yes or CI)
|
|
30
|
+
confirm() {
|
|
31
|
+
local msg="${1:-Continue?}"
|
|
32
|
+
if [[ "${YES:-false}" == "true" ]] || [[ "${CI:-false}" == "true" ]]; then
|
|
33
|
+
return 0
|
|
34
|
+
fi
|
|
35
|
+
read -rp "$(echo -e "${YELLOW}${msg} [y/N]${NC} ")" answer
|
|
36
|
+
[[ "$answer" =~ ^[Yy]$ ]]
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
# Load .env file if it exists
|
|
40
|
+
load_env() {
|
|
41
|
+
local env_file="${1:-.env}"
|
|
42
|
+
if [[ -f "$REPO_ROOT/$env_file" ]]; then
|
|
43
|
+
set -a
|
|
44
|
+
source "$REPO_ROOT/$env_file"
|
|
45
|
+
set +a
|
|
46
|
+
fi
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
# Telegram notification (optional — needs TELEGRAM_BOT_TOKEN + TELEGRAM_CHAT_ID)
|
|
50
|
+
notify_telegram() {
|
|
51
|
+
local message="$1"
|
|
52
|
+
if [[ -n "${TELEGRAM_BOT_TOKEN:-}" ]] && [[ -n "${TELEGRAM_CHAT_ID:-}" ]]; then
|
|
53
|
+
curl -sf -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \
|
|
54
|
+
--data-urlencode "chat_id=${TELEGRAM_CHAT_ID}" \
|
|
55
|
+
--data-urlencode "text=${message}" \
|
|
56
|
+
--data-urlencode "parse_mode=Markdown" > /dev/null 2>&1 &
|
|
57
|
+
fi
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
# Git helpers
|
|
61
|
+
git_branch() { git -C "$REPO_ROOT" rev-parse --abbrev-ref HEAD; }
|
|
62
|
+
git_commit() { git -C "$REPO_ROOT" rev-parse --short HEAD; }
|
|
63
|
+
git_version() { node -p "require('$REPO_ROOT/package.json').version" 2>/dev/null || echo "0.0.0"; }
|
|
64
|
+
git_dirty() { [[ -n "$(git -C "$REPO_ROOT" status --porcelain)" ]]; }
|
|
65
|
+
|
|
66
|
+
# Require commands
|
|
67
|
+
require_cmd() {
|
|
68
|
+
for cmd in "$@"; do
|
|
69
|
+
if ! command -v "$cmd" &>/dev/null; then
|
|
70
|
+
error "Required command not found: $cmd"
|
|
71
|
+
exit 1
|
|
72
|
+
fi
|
|
73
|
+
done
|
|
74
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# ─────────────────────────────────────────────────
|
|
3
|
+
# PostgreSQL database backup.
|
|
4
|
+
#
|
|
5
|
+
# Config (env vars or .env):
|
|
6
|
+
# POSTGRES_HOST (default: localhost)
|
|
7
|
+
# POSTGRES_PORT (default: 5432)
|
|
8
|
+
# POSTGRES_USER (default: postgres)
|
|
9
|
+
# POSTGRES_DB (required)
|
|
10
|
+
# BACKUP_DIR (default: ./backups)
|
|
11
|
+
# RETENTION_DAYS (default: 14)
|
|
12
|
+
#
|
|
13
|
+
# Usage:
|
|
14
|
+
# ./scripts/db/backup.sh # Backup to local dir
|
|
15
|
+
# BACKUP_DIR=/mnt/s3 ./scripts/db/backup.sh # Custom dir
|
|
16
|
+
# ─────────────────────────────────────────────────
|
|
17
|
+
|
|
18
|
+
source "$(dirname "$0")/../common.sh"
|
|
19
|
+
load_env
|
|
20
|
+
|
|
21
|
+
require_cmd pg_dump
|
|
22
|
+
|
|
23
|
+
: "${POSTGRES_DB:?Set POSTGRES_DB}"
|
|
24
|
+
|
|
25
|
+
DB_HOST="${POSTGRES_HOST:-localhost}"
|
|
26
|
+
DB_PORT="${POSTGRES_PORT:-5432}"
|
|
27
|
+
DB_USER="${POSTGRES_USER:-postgres}"
|
|
28
|
+
BACKUP_DIR="${BACKUP_DIR:-$REPO_ROOT/backups}"
|
|
29
|
+
RETENTION_DAYS="${RETENTION_DAYS:-14}"
|
|
30
|
+
|
|
31
|
+
DATE=$(date +%Y%m%d_%H%M%S)
|
|
32
|
+
BACKUP_FILE="${BACKUP_DIR}/${POSTGRES_DB}_${DATE}.dump"
|
|
33
|
+
|
|
34
|
+
mkdir -p "$BACKUP_DIR"
|
|
35
|
+
|
|
36
|
+
step "Backing up ${POSTGRES_DB}@${DB_HOST}:${DB_PORT}..."
|
|
37
|
+
pg_dump -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -Fc "$POSTGRES_DB" > "$BACKUP_FILE"
|
|
38
|
+
|
|
39
|
+
SIZE=$(du -h "$BACKUP_FILE" | cut -f1)
|
|
40
|
+
log "Backup complete: $BACKUP_FILE ($SIZE)"
|
|
41
|
+
|
|
42
|
+
# Retention cleanup
|
|
43
|
+
if [[ "$RETENTION_DAYS" -gt 0 ]]; then
|
|
44
|
+
DELETED=$(find "$BACKUP_DIR" -name "*.dump" -mtime "+$RETENTION_DAYS" -delete -print | wc -l)
|
|
45
|
+
if [[ "$DELETED" -gt 0 ]]; then
|
|
46
|
+
info "Cleaned $DELETED old backups (>$RETENTION_DAYS days)"
|
|
47
|
+
fi
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
notify_telegram "💾 *DB Backup*
|
|
51
|
+
📦 $POSTGRES_DB
|
|
52
|
+
📏 $SIZE
|
|
53
|
+
🗑 Retention: ${RETENTION_DAYS}d"
|