capacitor-ota 1.0.9 → 1.0.11
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/README.md +56 -92
- package/dist/cli/ota.mjs +1 -1
- package/dist/src/index.mjs +4 -3
- package/package.json +20 -9
package/README.md
CHANGED
|
@@ -8,27 +8,25 @@ Capacitor uygulamaları için Over-The-Air (OTA) güncelleme servisi.
|
|
|
8
8
|
┌──────────────────────────────────────────────────────────────┐
|
|
9
9
|
│ ADMIN (Nadir) │
|
|
10
10
|
├──────────────────────────────────────────────────────────────┤
|
|
11
|
-
│ CLI/Panel → POST /api/versions/upload
|
|
11
|
+
│ CLI/Panel → POST /api/versions/upload │
|
|
12
12
|
│ ↓ │
|
|
13
|
-
│ 1. Bundle → R2:
|
|
14
|
-
│ 2.
|
|
13
|
+
│ 1. Bundle → R2: /bundles/app/production/1.0.0.zip │
|
|
14
|
+
│ 2. Metadata → PostgreSQL │
|
|
15
15
|
└──────────────────────────────────────────────────────────────┘
|
|
16
16
|
|
|
17
17
|
┌──────────────────────────────────────────────────────────────┐
|
|
18
18
|
│ CİHAZ (Sık) │
|
|
19
19
|
├──────────────────────────────────────────────────────────────┤
|
|
20
|
-
│ App açılış → GET
|
|
21
|
-
│ ↓
|
|
20
|
+
│ App açılış → GET /updates/com.example.app.json │
|
|
21
|
+
│ ↓ │
|
|
22
22
|
│ Güncelleme var mı? │
|
|
23
23
|
│ ↓ evet │
|
|
24
|
-
│ GET
|
|
24
|
+
│ GET /bundles/app/production/1.0.0.zip │
|
|
25
25
|
│ ↓ │
|
|
26
26
|
│ CapacitorUpdater.download() → set() │
|
|
27
27
|
└──────────────────────────────────────────────────────────────┘
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
-
**Sonuç:** Cihazlar için 0 Workers request, sadece R2 + CDN.
|
|
31
|
-
|
|
32
30
|
---
|
|
33
31
|
|
|
34
32
|
## CLI Kullanımı
|
|
@@ -36,7 +34,7 @@ Capacitor uygulamaları için Over-The-Air (OTA) güncelleme servisi.
|
|
|
36
34
|
### Kurulum
|
|
37
35
|
|
|
38
36
|
```bash
|
|
39
|
-
cd ota
|
|
37
|
+
cd capacitor-ota
|
|
40
38
|
pnpm install
|
|
41
39
|
```
|
|
42
40
|
|
|
@@ -89,16 +87,13 @@ pnpm cli upload <app_id> <path> [options]
|
|
|
89
87
|
|------|------|----------|------------|
|
|
90
88
|
| `--version` | `-v` | Versiyon numarası | 1.0.0 |
|
|
91
89
|
| `--channel` | `-c` | Kanal | production |
|
|
92
|
-
| `--capacitor-app-id` | | Capacitor app ID (static JSON için) | - |
|
|
93
90
|
| `--min-native` | | Minimum native versiyon | - |
|
|
94
91
|
| `--notes` | | Release notes | - |
|
|
95
92
|
|
|
96
93
|
**Örnekler:**
|
|
97
94
|
```bash
|
|
98
95
|
# Dizin ile (otomatik ziplenir)
|
|
99
|
-
pnpm cli upload 9fa3a103d8d0 ./dist
|
|
100
|
-
-v 1.0.5 \
|
|
101
|
-
--capacitor-app-id com.example.app
|
|
96
|
+
pnpm cli upload 9fa3a103d8d0 ./dist -v 1.0.5
|
|
102
97
|
|
|
103
98
|
# Zip dosyası ile
|
|
104
99
|
pnpm cli upload 9fa3a103d8d0 ./bundle.zip -v 1.0.5
|
|
@@ -131,7 +126,7 @@ Belirtilen versiyonu aktif yapar.
|
|
|
131
126
|
pnpm cli config
|
|
132
127
|
|
|
133
128
|
# API URL değiştir
|
|
134
|
-
pnpm cli set-url https://
|
|
129
|
+
pnpm cli set-url https://ota-api.silgi.dev
|
|
135
130
|
```
|
|
136
131
|
|
|
137
132
|
---
|
|
@@ -142,21 +137,24 @@ pnpm cli set-url https://my-ota.workers.dev
|
|
|
142
137
|
|
|
143
138
|
| Method | Endpoint | Açıklama |
|
|
144
139
|
|--------|----------|----------|
|
|
145
|
-
| GET | `/
|
|
140
|
+
| GET | `/updates/:appId.json` | Static update check |
|
|
141
|
+
| GET | `/bundles/:path` | Bundle download |
|
|
146
142
|
|
|
147
143
|
### Protected (Auth Gerektirir)
|
|
148
144
|
|
|
149
145
|
| Method | Endpoint | Açıklama |
|
|
150
146
|
|--------|----------|----------|
|
|
151
147
|
| POST | `/api/auth/login` | Login |
|
|
148
|
+
| POST | `/api/auth/logout` | Logout |
|
|
152
149
|
| GET | `/api/apps` | App listesi |
|
|
153
150
|
| POST | `/api/apps` | App oluştur |
|
|
151
|
+
| PUT | `/api/apps/:id` | App güncelle |
|
|
154
152
|
| DELETE | `/api/apps/:id` | App sil |
|
|
155
153
|
| GET | `/api/versions` | Versiyon listesi |
|
|
156
154
|
| POST | `/api/versions/upload` | Versiyon yükle |
|
|
157
155
|
| DELETE | `/api/versions/:id` | Versiyon sil |
|
|
158
|
-
| POST | `/api/versions/:id/activate` | Versiyonu aktif yap |
|
|
159
156
|
| POST | `/api/versions/:id/rollback` | Rollback |
|
|
157
|
+
| GET | `/api/stats` | İstatistikler |
|
|
160
158
|
|
|
161
159
|
---
|
|
162
160
|
|
|
@@ -164,83 +162,38 @@ pnpm cli set-url https://my-ota.workers.dev
|
|
|
164
162
|
|
|
165
163
|
### 1. Plugin Kur
|
|
166
164
|
```bash
|
|
167
|
-
npm install
|
|
165
|
+
npm install capacitor-ota
|
|
168
166
|
npx cap sync
|
|
169
167
|
```
|
|
170
168
|
|
|
171
|
-
### 2.
|
|
172
|
-
```typescript
|
|
173
|
-
// capacitor.config.ts
|
|
174
|
-
const config: CapacitorConfig = {
|
|
175
|
-
plugins: {
|
|
176
|
-
CapacitorUpdater: {
|
|
177
|
-
autoUpdate: false, // Manuel kontrol
|
|
178
|
-
},
|
|
179
|
-
},
|
|
180
|
-
}
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
### 3. Vue Composable
|
|
169
|
+
### 2. App.vue
|
|
184
170
|
```typescript
|
|
185
|
-
|
|
186
|
-
import { CapacitorUpdater } from '@capgo/capacitor-updater'
|
|
171
|
+
import { initOtaUpdate } from 'capacitor-ota'
|
|
187
172
|
|
|
188
|
-
|
|
189
|
-
|
|
173
|
+
// App başlangıcında
|
|
174
|
+
await initOtaUpdate({
|
|
175
|
+
staticUrl: 'https://ota-api.silgi.dev',
|
|
190
176
|
appId: 'com.example.app',
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
async function checkForUpdate() {
|
|
195
|
-
const url = `${CONFIG.staticUrl}/updates/${CONFIG.appId}.json`
|
|
196
|
-
const response = await fetch(url)
|
|
197
|
-
const data = await response.json()
|
|
198
|
-
// ... version karşılaştırma ve indirme
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
async function downloadUpdate(url: string, version: string, checksum: string) {
|
|
202
|
-
const bundle = await CapacitorUpdater.download({ url, version, checksum })
|
|
203
|
-
return bundle
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
async function applyUpdate(bundleId: string) {
|
|
207
|
-
await CapacitorUpdater.set({ id: bundleId })
|
|
208
|
-
// Otomatik reload
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
return { checkForUpdate, downloadUpdate, applyUpdate }
|
|
212
|
-
}
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
### 4. App.vue
|
|
216
|
-
```vue
|
|
217
|
-
<script setup>
|
|
218
|
-
import { onMounted } from 'vue'
|
|
219
|
-
import { useOtaUpdate } from '@/composables/useOtaUpdate'
|
|
220
|
-
|
|
221
|
-
const ota = useOtaUpdate()
|
|
222
|
-
|
|
223
|
-
onMounted(async () => {
|
|
224
|
-
await ota.notifyAppReady() // Rollback'i önle
|
|
225
|
-
await ota.checkForUpdate()
|
|
177
|
+
appVersion: '1.0.0',
|
|
178
|
+
autoApply: true,
|
|
179
|
+
showUI: true,
|
|
226
180
|
})
|
|
227
|
-
</script>
|
|
228
181
|
```
|
|
229
182
|
|
|
230
183
|
---
|
|
231
184
|
|
|
232
185
|
## Static JSON Format
|
|
233
186
|
|
|
234
|
-
|
|
187
|
+
Güncelleme bilgisi:
|
|
235
188
|
|
|
236
189
|
```
|
|
237
|
-
GET https://ota.silgi.dev/updates/com.example.app.json
|
|
190
|
+
GET https://ota-api.silgi.dev/updates/com.example.app.json
|
|
238
191
|
```
|
|
239
192
|
|
|
240
193
|
```json
|
|
241
194
|
{
|
|
242
195
|
"version": "1.0.5",
|
|
243
|
-
"url": "https://ota.silgi.dev/9fa3a103d8d0/production/1.0.5.zip",
|
|
196
|
+
"url": "https://ota-api.silgi.dev/bundles/9fa3a103d8d0/production/1.0.5.zip",
|
|
244
197
|
"checksum": "a1b2c3d4e5f6...",
|
|
245
198
|
"min_native_version": "1.0.0",
|
|
246
199
|
"release_notes": "Bug fixes",
|
|
@@ -252,39 +205,50 @@ GET https://ota.silgi.dev/updates/com.example.app.json
|
|
|
252
205
|
|
|
253
206
|
## Deployment
|
|
254
207
|
|
|
208
|
+
### Development
|
|
255
209
|
```bash
|
|
256
|
-
# Local development
|
|
257
210
|
pnpm dev
|
|
211
|
+
```
|
|
258
212
|
|
|
259
|
-
|
|
213
|
+
### Production Build
|
|
214
|
+
```bash
|
|
260
215
|
pnpm build
|
|
261
|
-
|
|
216
|
+
node .output/server/index.mjs
|
|
262
217
|
```
|
|
263
218
|
|
|
264
219
|
---
|
|
265
220
|
|
|
266
221
|
## Environment Variables
|
|
267
222
|
|
|
268
|
-
### Workers (wrangler.toml)
|
|
269
|
-
```toml
|
|
270
|
-
[vars]
|
|
271
|
-
ADMIN_PASSWORD_HASH = "bcrypt_hash_here"
|
|
272
|
-
R2_PUBLIC_URL = "https://ota.silgi.dev"
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
### Client (.env)
|
|
276
223
|
```env
|
|
277
|
-
|
|
224
|
+
# PostgreSQL
|
|
225
|
+
DATABASE_URL=postgresql://user:pass@localhost:5432/capacitor_ota
|
|
226
|
+
|
|
227
|
+
# Cloudflare R2 (S3-compatible)
|
|
228
|
+
R2_ACCOUNT_ID=xxx
|
|
229
|
+
R2_ACCESS_KEY_ID=xxx
|
|
230
|
+
R2_SECRET_ACCESS_KEY=xxx
|
|
231
|
+
R2_BUCKET_NAME=ota-bundles
|
|
232
|
+
|
|
233
|
+
# Admin (generated on first setup)
|
|
234
|
+
ADMIN_PASSWORD_HASH=100000:salt:hash
|
|
278
235
|
```
|
|
279
236
|
|
|
280
237
|
---
|
|
281
238
|
|
|
282
|
-
##
|
|
239
|
+
## Database Schema
|
|
240
|
+
|
|
241
|
+
PostgreSQL 18 + Drizzle ORM + UUID v7
|
|
283
242
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
243
|
+
- `admins` - Admin kullanıcıları
|
|
244
|
+
- `sessions` - Auth sessions
|
|
245
|
+
- `apps` - Uygulamalar
|
|
246
|
+
- `versions` - Versiyon kayıtları
|
|
288
247
|
|
|
289
|
-
|
|
290
|
-
|
|
248
|
+
```bash
|
|
249
|
+
# Migration oluştur
|
|
250
|
+
pnpm db:generate
|
|
251
|
+
|
|
252
|
+
# Migration uygula
|
|
253
|
+
pnpm db:migrate
|
|
254
|
+
```
|
package/dist/cli/ota.mjs
CHANGED
|
@@ -20,7 +20,7 @@ import { execSync } from "child_process";
|
|
|
20
20
|
* rollback <version_id> Rollback to a version
|
|
21
21
|
*/
|
|
22
22
|
const CONFIG_PATH = resolve(homedir(), ".ota-cli.json");
|
|
23
|
-
const DEFAULT_URL = "https://ota-
|
|
23
|
+
const DEFAULT_URL = "https://ota-api.silgi.dev";
|
|
24
24
|
function loadConfig() {
|
|
25
25
|
if (existsSync(CONFIG_PATH)) return JSON.parse(readFileSync(CONFIG_PATH, "utf-8"));
|
|
26
26
|
return { url: DEFAULT_URL };
|
package/dist/src/index.mjs
CHANGED
|
@@ -70,7 +70,7 @@ var OtaUpdater = class {
|
|
|
70
70
|
});
|
|
71
71
|
try {
|
|
72
72
|
const url = `${this.config.staticUrl}/updates/${this.config.appId}.json`;
|
|
73
|
-
const response = await fetch(url
|
|
73
|
+
const response = await fetch(url);
|
|
74
74
|
if (!response.ok) {
|
|
75
75
|
if (response.status === 404) {
|
|
76
76
|
this.setState({ status: "idle" });
|
|
@@ -131,7 +131,7 @@ var OtaUpdater = class {
|
|
|
131
131
|
}
|
|
132
132
|
try {
|
|
133
133
|
const url = `${this.config.staticUrl}/updates/${this.config.appId}.json`;
|
|
134
|
-
const data = await (await fetch(url
|
|
134
|
+
const data = await (await fetch(url)).json();
|
|
135
135
|
const { CapacitorUpdater } = await import("@capgo/capacitor-updater");
|
|
136
136
|
const listener = await CapacitorUpdater.addListener("download", (event) => {
|
|
137
137
|
this.setState({ progress: event.percent });
|
|
@@ -140,8 +140,9 @@ var OtaUpdater = class {
|
|
|
140
140
|
version
|
|
141
141
|
});
|
|
142
142
|
});
|
|
143
|
+
const bundleUrl = data.url.startsWith("http") ? data.url : `${this.config.staticUrl}${data.url}`;
|
|
143
144
|
const bundle = await CapacitorUpdater.download({
|
|
144
|
-
url:
|
|
145
|
+
url: bundleUrl,
|
|
145
146
|
version: data.version,
|
|
146
147
|
checksum: data.checksum
|
|
147
148
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "capacitor-ota",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.11",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/src/index.mjs",
|
|
6
6
|
"types": "dist/src/index.d.mts",
|
|
@@ -18,25 +18,30 @@
|
|
|
18
18
|
"dist"
|
|
19
19
|
],
|
|
20
20
|
"scripts": {
|
|
21
|
-
"build": "tsdown",
|
|
22
21
|
"dev": "tsdown --watch",
|
|
23
22
|
"panel:dev": "vite dev --host",
|
|
24
|
-
"
|
|
23
|
+
"build": "tsdown && vite build",
|
|
25
24
|
"panel:preview": "vite preview",
|
|
26
|
-
"
|
|
27
|
-
"db:
|
|
28
|
-
"db:migrate
|
|
25
|
+
"start": "node .output/server/index.mjs",
|
|
26
|
+
"db:generate": "drizzle-kit generate",
|
|
27
|
+
"db:migrate": "drizzle-kit migrate",
|
|
28
|
+
"db:push": "drizzle-kit push",
|
|
29
|
+
"db:studio": "drizzle-kit studio",
|
|
29
30
|
"cli": "tsx cli/ota.ts"
|
|
30
31
|
},
|
|
31
32
|
"peerDependencies": {
|
|
32
|
-
"@
|
|
33
|
-
"@capacitor
|
|
33
|
+
"@capacitor/core": ">=8.0.0",
|
|
34
|
+
"@capgo/capacitor-updater": ">=6.0.0"
|
|
34
35
|
},
|
|
35
36
|
"devDependencies": {
|
|
36
|
-
"@cloudflare/workers-types": "^4.
|
|
37
|
+
"@cloudflare/workers-types": "^4.20260124.0",
|
|
37
38
|
"@tailwindcss/vite": "^4.1.18",
|
|
39
|
+
"@types/node": "^25.0.10",
|
|
40
|
+
"@types/pg": "^8.16.0",
|
|
38
41
|
"@vitejs/plugin-vue": "^6.0.3",
|
|
42
|
+
"drizzle-kit": "1.0.0-beta.12-a5629fb",
|
|
39
43
|
"nitro": "3.0.1-alpha.2",
|
|
44
|
+
"pg": "^8.17.2",
|
|
40
45
|
"pinia": "^3.0.4",
|
|
41
46
|
"tailwindcss": "^4.1.18",
|
|
42
47
|
"tsdown": "^0.20.1",
|
|
@@ -46,5 +51,11 @@
|
|
|
46
51
|
"vue": "^3.5.27",
|
|
47
52
|
"vue-router": "^4.6.4",
|
|
48
53
|
"wrangler": "^4.60.0"
|
|
54
|
+
},
|
|
55
|
+
"dependencies": {
|
|
56
|
+
"@aws-sdk/client-s3": "^3.975.0",
|
|
57
|
+
"@aws-sdk/s3-request-presigner": "^3.975.0",
|
|
58
|
+
"drizzle-orm": "1.0.0-beta.12-a5629fb",
|
|
59
|
+
"h3": "2.0.1-rc.11"
|
|
49
60
|
}
|
|
50
61
|
}
|