@hasna/shortlinks 0.1.12 → 0.1.14
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 +152 -191
- package/README.md +21 -18
- package/cloudflare/shortlinks.js +26 -10
- package/cloudflare/wrangler.example.toml +3 -1
- package/dist/cli/index.js +5895 -591
- package/dist/cloudflare.d.ts +1 -0
- package/dist/cloudflare.js +28 -10
- package/dist/index.d.ts +6 -0
- package/dist/index.js +5431 -92
- package/dist/pg-migrate.d.ts +7 -0
- package/dist/pg-store.d.ts +2 -1
- package/dist/remote-storage.d.ts +11 -0
- package/dist/server.d.ts +1 -0
- package/dist/server.js +4 -0
- package/dist/storage-config.d.ts +37 -0
- package/dist/storage-sync.d.ts +36 -0
- package/dist/storage.d.ts +6 -0
- package/dist/storage.js +5539 -0
- package/infra/aws-ec2-user-data.sh +59 -16
- package/package.json +11 -6
|
@@ -4,9 +4,14 @@ set -euo pipefail
|
|
|
4
4
|
export AWS_REGION="${AWS_REGION:-us-east-1}"
|
|
5
5
|
export SHORTLINKS_HOME="/var/lib/shortlinks"
|
|
6
6
|
export SHORTLINKS_PACKAGE="@hasna/shortlinks@latest"
|
|
7
|
-
export RDS_SECRET_ID="
|
|
8
|
-
export RDS_HOST="
|
|
9
|
-
export RDS_USERNAME="
|
|
7
|
+
export RDS_SECRET_ID="${RDS_SECRET_ID:-}"
|
|
8
|
+
export RDS_HOST="${RDS_HOST:-}"
|
|
9
|
+
export RDS_USERNAME="${RDS_USERNAME:-}"
|
|
10
|
+
export SHORTLINKS_DOMAIN="${SHORTLINKS_DOMAIN:-}"
|
|
11
|
+
export ATTACHMENTS_ORIGIN="${ATTACHMENTS_ORIGIN:-}"
|
|
12
|
+
|
|
13
|
+
: "${RDS_SECRET_ID:?Set RDS_SECRET_ID to the AWS Secrets Manager secret for the PostgreSQL database_url}"
|
|
14
|
+
: "${SHORTLINKS_DOMAIN:?Set SHORTLINKS_DOMAIN to the public host served by Caddy}"
|
|
10
15
|
|
|
11
16
|
dnf update -y
|
|
12
17
|
dnf install -y awscli jq tar gzip shadow-utils libcap
|
|
@@ -15,28 +20,29 @@ if ! id shortlinks >/dev/null 2>&1; then
|
|
|
15
20
|
useradd --system --create-home --home-dir "${SHORTLINKS_HOME}" --shell /sbin/nologin shortlinks
|
|
16
21
|
fi
|
|
17
22
|
|
|
18
|
-
install -d -o shortlinks -g shortlinks "${SHORTLINKS_HOME}/.hasna/
|
|
23
|
+
install -d -o shortlinks -g shortlinks "${SHORTLINKS_HOME}/.hasna/shortlinks/storage"
|
|
19
24
|
install -d -o shortlinks -g shortlinks "${SHORTLINKS_HOME}/.hasna/shortlinks"
|
|
20
25
|
|
|
21
|
-
|
|
26
|
+
if [ -n "${RDS_HOST}" ] && [ -n "${RDS_USERNAME}" ]; then
|
|
27
|
+
cat > "${SHORTLINKS_HOME}/.hasna/shortlinks/storage/config.json" <<CLOUD_CONFIG
|
|
22
28
|
{
|
|
23
29
|
"rds": {
|
|
24
30
|
"host": "${RDS_HOST}",
|
|
25
31
|
"port": 5432,
|
|
26
32
|
"username": "${RDS_USERNAME}",
|
|
27
|
-
"password_env": "
|
|
33
|
+
"password_env": "SHORTLINKS_CLOUD_DATABASE_PASSWORD",
|
|
28
34
|
"ssl": true
|
|
29
35
|
},
|
|
30
36
|
"mode": "hybrid",
|
|
31
|
-
"feedback_endpoint": "https://feedback.hasna.com/api/v1/feedback",
|
|
32
37
|
"auto_sync_interval_minutes": 0,
|
|
33
38
|
"sync": {
|
|
34
39
|
"schedule_minutes": 0
|
|
35
40
|
}
|
|
36
41
|
}
|
|
37
42
|
CLOUD_CONFIG
|
|
38
|
-
chown shortlinks:shortlinks "${SHORTLINKS_HOME}/.hasna/
|
|
39
|
-
chmod 600 "${SHORTLINKS_HOME}/.hasna/
|
|
43
|
+
chown shortlinks:shortlinks "${SHORTLINKS_HOME}/.hasna/shortlinks/storage/config.json"
|
|
44
|
+
chmod 600 "${SHORTLINKS_HOME}/.hasna/shortlinks/storage/config.json"
|
|
45
|
+
fi
|
|
40
46
|
|
|
41
47
|
su -s /bin/bash shortlinks -c 'curl -fsSL https://bun.sh/install | bash'
|
|
42
48
|
su -s /bin/bash shortlinks -c "${SHORTLINKS_HOME}/.bun/bin/bun install -g ${SHORTLINKS_PACKAGE} --no-cache"
|
|
@@ -50,14 +56,22 @@ export HOME="/var/lib/shortlinks"
|
|
|
50
56
|
export PATH="/var/lib/shortlinks/.bun/bin:/usr/local/bin:/usr/bin:/bin"
|
|
51
57
|
export NODE_TLS_REJECT_UNAUTHORIZED="0"
|
|
52
58
|
|
|
59
|
+
: "${RDS_SECRET_ID:?Set RDS_SECRET_ID to the AWS Secrets Manager secret for the PostgreSQL database_url}"
|
|
60
|
+
|
|
53
61
|
secret_json="$(aws secretsmanager get-secret-value \
|
|
54
62
|
--region "${AWS_REGION}" \
|
|
55
|
-
--secret-id "
|
|
63
|
+
--secret-id "${RDS_SECRET_ID}" \
|
|
56
64
|
--query SecretString \
|
|
57
65
|
--output text)"
|
|
58
66
|
|
|
59
|
-
export
|
|
60
|
-
|
|
67
|
+
export HASNA_SHORTLINKS_DATABASE_URL
|
|
68
|
+
HASNA_SHORTLINKS_DATABASE_URL="$(jq -r '.database_url // empty' <<<"${secret_json}")"
|
|
69
|
+
if [ -n "${HASNA_SHORTLINKS_DATABASE_URL}" ]; then
|
|
70
|
+
export SHORTLINKS_DATABASE_URL="${HASNA_SHORTLINKS_DATABASE_URL}"
|
|
71
|
+
else
|
|
72
|
+
export SHORTLINKS_CLOUD_DATABASE_PASSWORD
|
|
73
|
+
SHORTLINKS_CLOUD_DATABASE_PASSWORD="$(jq -r '.password // empty' <<<"${secret_json}")"
|
|
74
|
+
fi
|
|
61
75
|
|
|
62
76
|
exec "$@"
|
|
63
77
|
RUNNER
|
|
@@ -66,6 +80,15 @@ chown root:shortlinks /usr/local/bin/shortlinks-env-exec
|
|
|
66
80
|
|
|
67
81
|
su -s /bin/bash shortlinks -c 'PATH=/var/lib/shortlinks/.bun/bin:$PATH shortlinks --version'
|
|
68
82
|
|
|
83
|
+
cat > /etc/default/shortlinks <<SHORTLINKS_ENV
|
|
84
|
+
AWS_REGION=${AWS_REGION}
|
|
85
|
+
RDS_SECRET_ID=${RDS_SECRET_ID}
|
|
86
|
+
SHORTLINKS_DOMAIN=${SHORTLINKS_DOMAIN}
|
|
87
|
+
SHORTLINKS_STORE=remote
|
|
88
|
+
SHORTLINKS_ENV
|
|
89
|
+
chmod 640 /etc/default/shortlinks
|
|
90
|
+
chown root:shortlinks /etc/default/shortlinks
|
|
91
|
+
|
|
69
92
|
caddy_version="$(curl -fsSL https://api.github.com/repos/caddyserver/caddy/releases/latest | jq -r '.tag_name // "v2.10.2"' | sed 's/^v//')"
|
|
70
93
|
case "$(uname -m)" in
|
|
71
94
|
aarch64|arm64) caddy_arch="arm64" ;;
|
|
@@ -90,8 +113,8 @@ Group=shortlinks
|
|
|
90
113
|
WorkingDirectory=/var/lib/shortlinks
|
|
91
114
|
Environment=HOME=/var/lib/shortlinks
|
|
92
115
|
Environment=PATH=/var/lib/shortlinks/.bun/bin:/usr/local/bin:/usr/bin:/bin
|
|
93
|
-
|
|
94
|
-
ExecStart=/usr/local/bin/shortlinks-env-exec shortlinks serve --
|
|
116
|
+
EnvironmentFile=/etc/default/shortlinks
|
|
117
|
+
ExecStart=/usr/local/bin/shortlinks-env-exec shortlinks serve --remote --host 127.0.0.1 --port 8787 --default-host ${SHORTLINKS_DOMAIN}
|
|
95
118
|
Restart=always
|
|
96
119
|
RestartSec=5
|
|
97
120
|
|
|
@@ -123,12 +146,32 @@ WantedBy=multi-user.target
|
|
|
123
146
|
SERVICE
|
|
124
147
|
|
|
125
148
|
install -d /etc/caddy
|
|
126
|
-
|
|
127
|
-
|
|
149
|
+
if [ -n "${ATTACHMENTS_ORIGIN}" ]; then
|
|
150
|
+
cat > /etc/caddy/Caddyfile <<CADDY
|
|
151
|
+
${SHORTLINKS_DOMAIN} {
|
|
152
|
+
encode zstd gzip
|
|
153
|
+
|
|
154
|
+
handle /a/* {
|
|
155
|
+
reverse_proxy ${ATTACHMENTS_ORIGIN}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
handle /api/* {
|
|
159
|
+
reverse_proxy ${ATTACHMENTS_ORIGIN}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
handle {
|
|
163
|
+
reverse_proxy 127.0.0.1:8787
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
CADDY
|
|
167
|
+
else
|
|
168
|
+
cat > /etc/caddy/Caddyfile <<CADDY
|
|
169
|
+
${SHORTLINKS_DOMAIN} {
|
|
128
170
|
encode zstd gzip
|
|
129
171
|
reverse_proxy 127.0.0.1:8787
|
|
130
172
|
}
|
|
131
173
|
CADDY
|
|
174
|
+
fi
|
|
132
175
|
|
|
133
176
|
systemctl daemon-reload
|
|
134
177
|
systemctl enable shortlinks.service caddy.service
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hasna/shortlinks",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "CLI-only shortlink manager for custom domains, click tracking, Cloudflare setup, and
|
|
3
|
+
"version": "0.1.14",
|
|
4
|
+
"description": "CLI-only shortlink manager for custom domains, click tracking, Cloudflare setup, and repo-native storage sync",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -20,6 +20,10 @@
|
|
|
20
20
|
"./cloudflare": {
|
|
21
21
|
"types": "./dist/cloudflare.d.ts",
|
|
22
22
|
"import": "./dist/cloudflare.js"
|
|
23
|
+
},
|
|
24
|
+
"./storage": {
|
|
25
|
+
"types": "./dist/storage.d.ts",
|
|
26
|
+
"import": "./dist/storage.js"
|
|
23
27
|
}
|
|
24
28
|
},
|
|
25
29
|
"files": [
|
|
@@ -31,7 +35,7 @@
|
|
|
31
35
|
"SECURITY.md"
|
|
32
36
|
],
|
|
33
37
|
"scripts": {
|
|
34
|
-
"build": "rm -rf dist && bun build src/cli/index.ts --outdir dist/cli --target bun
|
|
38
|
+
"build": "rm -rf dist && bun build src/cli/index.ts --outdir dist/cli --target bun && bun build src/index.ts src/storage.ts --outdir dist --target bun && bun build src/server.ts --outdir dist --target bun && bun build src/cloudflare.ts --outdir dist --target bun && tsc -p tsconfig.build.json --emitDeclarationOnly --outDir dist",
|
|
35
39
|
"typecheck": "tsc --noEmit",
|
|
36
40
|
"test": "bun test",
|
|
37
41
|
"dev:cli": "bun run src/cli/index.ts",
|
|
@@ -66,13 +70,14 @@
|
|
|
66
70
|
"author": "Andrei Hasna <andrei@hasna.com>",
|
|
67
71
|
"license": "Apache-2.0",
|
|
68
72
|
"dependencies": {
|
|
69
|
-
"@hasna/cloud": "0.1.30",
|
|
70
|
-
"@hasna/events": "^0.1.6",
|
|
71
73
|
"chalk": "^5.4.1",
|
|
72
|
-
"commander": "^13.1.0"
|
|
74
|
+
"commander": "^13.1.0",
|
|
75
|
+
"pg": "^8.13.3",
|
|
76
|
+
"@hasna/events": "^0.1.6"
|
|
73
77
|
},
|
|
74
78
|
"devDependencies": {
|
|
75
79
|
"@types/bun": "^1.2.4",
|
|
80
|
+
"@types/pg": "^8.11.11",
|
|
76
81
|
"typescript": "^5.7.3"
|
|
77
82
|
}
|
|
78
83
|
}
|