@globio/cli 0.1.5 → 0.1.7
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/dist/index.js +68 -25
- package/jsr.json +1 -1
- package/package.json +1 -1
- package/src/commands/init.ts +1 -0
- package/src/commands/migrate.ts +29 -17
- package/src/lib/api.ts +52 -0
package/dist/index.js
CHANGED
|
@@ -446,6 +446,36 @@ import * as p3 from "@clack/prompts";
|
|
|
446
446
|
import chalk7 from "chalk";
|
|
447
447
|
import { basename } from "path";
|
|
448
448
|
|
|
449
|
+
// src/lib/api.ts
|
|
450
|
+
var BASE_URL = "https://api.globio.stanlink.online";
|
|
451
|
+
async function apiCall(path2, options = {}) {
|
|
452
|
+
const profileName = options.profile ?? config.getActiveProfile();
|
|
453
|
+
const profile = config.getProfile(profileName);
|
|
454
|
+
if (!profile?.project_api_key) {
|
|
455
|
+
throw new Error("No active project. Run: globio projects use <id>");
|
|
456
|
+
}
|
|
457
|
+
const res = await fetch(`${BASE_URL}${path2}`, {
|
|
458
|
+
method: options.method ?? "GET",
|
|
459
|
+
headers: {
|
|
460
|
+
"Content-Type": "application/json",
|
|
461
|
+
"X-Globio-Key": profile.project_api_key
|
|
462
|
+
},
|
|
463
|
+
body: options.body ? JSON.stringify(options.body) : void 0
|
|
464
|
+
});
|
|
465
|
+
const data = await res.json();
|
|
466
|
+
if (!data.success) {
|
|
467
|
+
throw new Error(data.error ?? `API error ${res.status}`);
|
|
468
|
+
}
|
|
469
|
+
return data;
|
|
470
|
+
}
|
|
471
|
+
async function docSet(collection, docId, data, profile) {
|
|
472
|
+
await apiCall(`/doc/${collection}/${docId}`, {
|
|
473
|
+
method: "PUT",
|
|
474
|
+
body: data,
|
|
475
|
+
profile
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
|
|
449
479
|
// src/lib/firebase.ts
|
|
450
480
|
async function initFirebase(serviceAccountPath) {
|
|
451
481
|
const admin = await import("firebase-admin");
|
|
@@ -480,17 +510,6 @@ function createProgressBar(label) {
|
|
|
480
510
|
return bar;
|
|
481
511
|
}
|
|
482
512
|
|
|
483
|
-
// src/lib/sdk.ts
|
|
484
|
-
import { Globio } from "@globio/sdk";
|
|
485
|
-
function getClient(profileName) {
|
|
486
|
-
const { pat } = config.requireAuth(profileName);
|
|
487
|
-
const { projectId } = config.requireProject(profileName);
|
|
488
|
-
const profile = config.getProfile(profileName);
|
|
489
|
-
const apiKey = profile?.project_api_key ?? pat;
|
|
490
|
-
void projectId;
|
|
491
|
-
return new Globio({ apiKey });
|
|
492
|
-
}
|
|
493
|
-
|
|
494
513
|
// src/commands/migrate.ts
|
|
495
514
|
var version2 = getCliVersion();
|
|
496
515
|
function resolveProfileName(profile) {
|
|
@@ -500,7 +519,7 @@ async function migrateFirestore(options) {
|
|
|
500
519
|
printBanner(version2);
|
|
501
520
|
p3.intro(gold("\u21D2\u21D2") + " Firebase \u2192 Globio Migration");
|
|
502
521
|
const { firestore } = await initFirebase(options.from);
|
|
503
|
-
const
|
|
522
|
+
const profileName = resolveProfileName(options.profile);
|
|
504
523
|
let collections = [];
|
|
505
524
|
if (options.all) {
|
|
506
525
|
const snapshot = await firestore.listCollections();
|
|
@@ -542,10 +561,7 @@ async function migrateFirestore(options) {
|
|
|
542
561
|
}
|
|
543
562
|
for (const doc of snapshot.docs) {
|
|
544
563
|
try {
|
|
545
|
-
|
|
546
|
-
if (!result.success) {
|
|
547
|
-
throw new Error(result.error.message);
|
|
548
|
-
}
|
|
564
|
+
await docSet(collectionId, doc.id, doc.data(), profileName);
|
|
549
565
|
results[collectionId].success++;
|
|
550
566
|
} catch {
|
|
551
567
|
results[collectionId].failed++;
|
|
@@ -578,7 +594,11 @@ async function migrateFirebaseStorage(options) {
|
|
|
578
594
|
printBanner(version2);
|
|
579
595
|
p3.intro(gold("\u21D2\u21D2") + " Firebase \u2192 Globio Migration");
|
|
580
596
|
const { storage } = await initFirebase(options.from);
|
|
581
|
-
const
|
|
597
|
+
const profileName = resolveProfileName(options.profile);
|
|
598
|
+
const profile = config.getProfile(profileName);
|
|
599
|
+
if (!profile?.project_api_key) {
|
|
600
|
+
throw new Error("No active project. Run: globio projects use <id>");
|
|
601
|
+
}
|
|
582
602
|
const bucketName = options.bucket.replace(/^gs:\/\//, "");
|
|
583
603
|
const bucket = storage.bucket(bucketName);
|
|
584
604
|
const prefix = options.folder ? options.folder.replace(/^\//, "") : "";
|
|
@@ -591,17 +611,26 @@ async function migrateFirebaseStorage(options) {
|
|
|
591
611
|
for (const file of files) {
|
|
592
612
|
try {
|
|
593
613
|
const [buffer] = await file.download();
|
|
594
|
-
const
|
|
595
|
-
|
|
614
|
+
const bytes = Uint8Array.from(buffer);
|
|
615
|
+
const formData = new FormData();
|
|
616
|
+
formData.append(
|
|
617
|
+
"file",
|
|
618
|
+
new Blob([bytes]),
|
|
596
619
|
basename(file.name) || file.name
|
|
597
620
|
);
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
621
|
+
formData.append("path", file.name);
|
|
622
|
+
const res = await fetch(
|
|
623
|
+
"https://api.globio.stanlink.online/vault/files",
|
|
624
|
+
{
|
|
625
|
+
method: "POST",
|
|
626
|
+
headers: {
|
|
627
|
+
"X-Globio-Key": profile.project_api_key
|
|
628
|
+
},
|
|
629
|
+
body: formData
|
|
601
630
|
}
|
|
602
|
-
|
|
603
|
-
if (!
|
|
604
|
-
throw new Error(
|
|
631
|
+
);
|
|
632
|
+
if (!res.ok) {
|
|
633
|
+
throw new Error(`Upload failed: ${res.status}`);
|
|
605
634
|
}
|
|
606
635
|
success++;
|
|
607
636
|
} catch {
|
|
@@ -793,6 +822,7 @@ async function init(options = {}) {
|
|
|
793
822
|
|
|
794
823
|
export const globio = new Globio({
|
|
795
824
|
apiKey: process.env.GLOBIO_API_KEY!,
|
|
825
|
+
projectId: '${activeProjectId}',
|
|
796
826
|
});
|
|
797
827
|
`
|
|
798
828
|
);
|
|
@@ -886,6 +916,19 @@ async function servicesList(options = {}) {
|
|
|
886
916
|
import chalk11 from "chalk";
|
|
887
917
|
import ora from "ora";
|
|
888
918
|
import { existsSync as existsSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "fs";
|
|
919
|
+
|
|
920
|
+
// src/lib/sdk.ts
|
|
921
|
+
import { Globio } from "@globio/sdk";
|
|
922
|
+
function getClient(profileName) {
|
|
923
|
+
const { pat } = config.requireAuth(profileName);
|
|
924
|
+
const { projectId } = config.requireProject(profileName);
|
|
925
|
+
const profile = config.getProfile(profileName);
|
|
926
|
+
const apiKey = profile?.project_api_key ?? pat;
|
|
927
|
+
void projectId;
|
|
928
|
+
return new Globio({ apiKey });
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
// src/commands/functions.ts
|
|
889
932
|
function resolveProfileName3(profile) {
|
|
890
933
|
return profile ?? config.getActiveProfile() ?? "default";
|
|
891
934
|
}
|
package/jsr.json
CHANGED
package/package.json
CHANGED
package/src/commands/init.ts
CHANGED
package/src/commands/migrate.ts
CHANGED
|
@@ -8,9 +8,9 @@ import {
|
|
|
8
8
|
orange,
|
|
9
9
|
printBanner,
|
|
10
10
|
} from '../lib/banner.js';
|
|
11
|
+
import { docSet } from '../lib/api.js';
|
|
11
12
|
import { initFirebase } from '../lib/firebase.js';
|
|
12
13
|
import { createProgressBar } from '../lib/progress.js';
|
|
13
|
-
import { getClient } from '../lib/sdk.js';
|
|
14
14
|
import { config } from '../lib/config.js';
|
|
15
15
|
|
|
16
16
|
const version = getCliVersion();
|
|
@@ -39,7 +39,7 @@ export async function migrateFirestore(options: MigrateFirestoreOptions) {
|
|
|
39
39
|
p.intro(gold('⇒⇒') + ' Firebase → Globio Migration');
|
|
40
40
|
|
|
41
41
|
const { firestore } = await initFirebase(options.from);
|
|
42
|
-
const
|
|
42
|
+
const profileName = resolveProfileName(options.profile);
|
|
43
43
|
|
|
44
44
|
let collections: string[] = [];
|
|
45
45
|
|
|
@@ -96,10 +96,7 @@ export async function migrateFirestore(options: MigrateFirestoreOptions) {
|
|
|
96
96
|
|
|
97
97
|
for (const doc of snapshot.docs) {
|
|
98
98
|
try {
|
|
99
|
-
|
|
100
|
-
if (!result.success) {
|
|
101
|
-
throw new Error(result.error.message);
|
|
102
|
-
}
|
|
99
|
+
await docSet(collectionId, doc.id, doc.data(), profileName);
|
|
103
100
|
results[collectionId].success++;
|
|
104
101
|
} catch {
|
|
105
102
|
results[collectionId].failed++;
|
|
@@ -146,7 +143,12 @@ export async function migrateFirebaseStorage(options: MigrateStorageOptions) {
|
|
|
146
143
|
p.intro(gold('⇒⇒') + ' Firebase → Globio Migration');
|
|
147
144
|
|
|
148
145
|
const { storage } = await initFirebase(options.from);
|
|
149
|
-
const
|
|
146
|
+
const profileName = resolveProfileName(options.profile);
|
|
147
|
+
const profile = config.getProfile(profileName);
|
|
148
|
+
|
|
149
|
+
if (!profile?.project_api_key) {
|
|
150
|
+
throw new Error('No active project. Run: globio projects use <id>');
|
|
151
|
+
}
|
|
150
152
|
|
|
151
153
|
const bucketName = options.bucket.replace(/^gs:\/\//, '');
|
|
152
154
|
const bucket = storage.bucket(bucketName);
|
|
@@ -165,18 +167,28 @@ export async function migrateFirebaseStorage(options: MigrateStorageOptions) {
|
|
|
165
167
|
for (const file of files) {
|
|
166
168
|
try {
|
|
167
169
|
const [buffer] = await file.download();
|
|
168
|
-
const
|
|
169
|
-
|
|
170
|
+
const bytes = Uint8Array.from(buffer);
|
|
171
|
+
const formData = new FormData();
|
|
172
|
+
formData.append(
|
|
173
|
+
'file',
|
|
174
|
+
new Blob([bytes]),
|
|
170
175
|
basename(file.name) || file.name
|
|
171
176
|
);
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
177
|
+
formData.append('path', file.name);
|
|
178
|
+
|
|
179
|
+
const res = await fetch(
|
|
180
|
+
'https://api.globio.stanlink.online/vault/files',
|
|
181
|
+
{
|
|
182
|
+
method: 'POST',
|
|
183
|
+
headers: {
|
|
184
|
+
'X-Globio-Key': profile.project_api_key,
|
|
185
|
+
},
|
|
186
|
+
body: formData,
|
|
187
|
+
}
|
|
188
|
+
);
|
|
189
|
+
|
|
190
|
+
if (!res.ok) {
|
|
191
|
+
throw new Error(`Upload failed: ${res.status}`);
|
|
180
192
|
}
|
|
181
193
|
|
|
182
194
|
success++;
|
package/src/lib/api.ts
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { config } from './config.js';
|
|
2
|
+
|
|
3
|
+
const BASE_URL = 'https://api.globio.stanlink.online';
|
|
4
|
+
|
|
5
|
+
export async function apiCall(
|
|
6
|
+
path: string,
|
|
7
|
+
options: {
|
|
8
|
+
method?: string;
|
|
9
|
+
body?: unknown;
|
|
10
|
+
profile?: string;
|
|
11
|
+
} = {}
|
|
12
|
+
): Promise<unknown> {
|
|
13
|
+
const profileName = options.profile ?? config.getActiveProfile();
|
|
14
|
+
const profile = config.getProfile(profileName);
|
|
15
|
+
|
|
16
|
+
if (!profile?.project_api_key) {
|
|
17
|
+
throw new Error('No active project. Run: globio projects use <id>');
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const res = await fetch(`${BASE_URL}${path}`, {
|
|
21
|
+
method: options.method ?? 'GET',
|
|
22
|
+
headers: {
|
|
23
|
+
'Content-Type': 'application/json',
|
|
24
|
+
'X-Globio-Key': profile.project_api_key,
|
|
25
|
+
},
|
|
26
|
+
body: options.body ? JSON.stringify(options.body) : undefined,
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const data = (await res.json()) as {
|
|
30
|
+
success: boolean;
|
|
31
|
+
error?: string;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
if (!data.success) {
|
|
35
|
+
throw new Error(data.error ?? `API error ${res.status}`);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return data;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export async function docSet(
|
|
42
|
+
collection: string,
|
|
43
|
+
docId: string,
|
|
44
|
+
data: Record<string, unknown>,
|
|
45
|
+
profile?: string
|
|
46
|
+
): Promise<void> {
|
|
47
|
+
await apiCall(`/doc/${collection}/${docId}`, {
|
|
48
|
+
method: 'PUT',
|
|
49
|
+
body: data,
|
|
50
|
+
profile,
|
|
51
|
+
});
|
|
52
|
+
}
|