everything-dev 0.0.19 → 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/package.json +1 -1
- package/src/cli.ts +14 -8
- package/src/config.ts +45 -0
- package/src/contract.ts +1 -0
- package/src/lib/sync.ts +12 -15
- package/src/plugin.ts +76 -12
package/package.json
CHANGED
package/src/cli.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
|
+
import { spinner } from "@clack/prompts";
|
|
2
3
|
import { program } from "commander";
|
|
3
4
|
import { createPluginRuntime } from "every-plugin";
|
|
4
5
|
import { getConfigDir, getConfigPath, getPackages, getTitle, loadConfig, type BosConfig } from "./config";
|
|
@@ -742,18 +743,20 @@ Zephyr Configuration:
|
|
|
742
743
|
|
|
743
744
|
program
|
|
744
745
|
.command("sync")
|
|
745
|
-
.description("Sync dependencies and config from
|
|
746
|
-
.option("--account <account>", "NEAR account to sync from (default:
|
|
747
|
-
.option("--gateway <gateway>", "Gateway domain to sync from (default:
|
|
746
|
+
.description("Sync dependencies and config from published bos.config.json")
|
|
747
|
+
.option("--account <account>", "NEAR account to sync from (default: from config)")
|
|
748
|
+
.option("--gateway <gateway>", "Gateway domain to sync from (default: from config)")
|
|
748
749
|
.option("--network <network>", "Network: mainnet | testnet", "mainnet")
|
|
749
750
|
.option("--force", "Force sync even if versions match")
|
|
750
751
|
.option("--files", "Also sync template files (tsconfig, etc.)")
|
|
751
752
|
.action(async (options: { account?: string; gateway?: string; network?: string; force?: boolean; files?: boolean }) => {
|
|
752
753
|
console.log();
|
|
753
|
-
const
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
754
|
+
const gateway = config?.gateway as { production?: string } | undefined;
|
|
755
|
+
const gatewayDomain = gateway?.production?.replace(/^https?:\/\//, "") || "everything.dev";
|
|
756
|
+
const source = `${options.account || config?.account || "every.near"}/${options.gateway || gatewayDomain}`;
|
|
757
|
+
|
|
758
|
+
const s = spinner();
|
|
759
|
+
s.start(`Syncing from ${source}...`);
|
|
757
760
|
|
|
758
761
|
const result = await client.sync({
|
|
759
762
|
account: options.account,
|
|
@@ -764,16 +767,19 @@ Zephyr Configuration:
|
|
|
764
767
|
});
|
|
765
768
|
|
|
766
769
|
if (result.status === "error") {
|
|
767
|
-
|
|
770
|
+
s.stop(colors.error(`${icons.err} Sync failed: ${result.error || "Unknown error"}`));
|
|
768
771
|
process.exit(1);
|
|
769
772
|
}
|
|
770
773
|
|
|
774
|
+
s.stop(colors.green(`${icons.ok} Synced from ${source}`));
|
|
775
|
+
|
|
771
776
|
console.log();
|
|
772
777
|
console.log(colors.cyan(frames.top(52)));
|
|
773
778
|
console.log(` ${icons.ok} ${gradients.cyber("SYNCED")}`);
|
|
774
779
|
console.log(colors.cyan(frames.bottom(52)));
|
|
775
780
|
console.log();
|
|
776
781
|
console.log(` ${colors.dim("Source:")} ${colors.cyan(`${result.account}/${result.gateway}`)}`);
|
|
782
|
+
console.log(` ${colors.dim("URL:")} ${colors.cyan(result.socialUrl)}`);
|
|
777
783
|
console.log(` ${colors.dim("Host URL:")} ${colors.cyan(result.hostUrl)}`);
|
|
778
784
|
console.log();
|
|
779
785
|
|
package/src/config.ts
CHANGED
|
@@ -202,3 +202,48 @@ export function getGatewayUrl(env: "development" | "production" = "development")
|
|
|
202
202
|
}
|
|
203
203
|
return config.gateway[env];
|
|
204
204
|
}
|
|
205
|
+
|
|
206
|
+
export async function packageExists(pkg: string): Promise<boolean> {
|
|
207
|
+
const dir = getConfigDir();
|
|
208
|
+
return Bun.file(`${dir}/${pkg}/package.json`).exists();
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
export async function resolvePackageModes(
|
|
212
|
+
packages: string[],
|
|
213
|
+
input: Record<string, SourceMode | undefined>
|
|
214
|
+
): Promise<{ modes: Record<string, SourceMode>; autoRemote: string[] }> {
|
|
215
|
+
const dir = getConfigDir();
|
|
216
|
+
const modes: Record<string, SourceMode> = {};
|
|
217
|
+
const autoRemote: string[] = [];
|
|
218
|
+
|
|
219
|
+
for (const pkg of packages) {
|
|
220
|
+
const exists = await Bun.file(`${dir}/${pkg}/package.json`).exists();
|
|
221
|
+
const requestedMode = input[pkg] ?? "local";
|
|
222
|
+
|
|
223
|
+
if (!exists && requestedMode === "local") {
|
|
224
|
+
modes[pkg] = "remote";
|
|
225
|
+
autoRemote.push(pkg);
|
|
226
|
+
} else {
|
|
227
|
+
modes[pkg] = requestedMode;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
return { modes, autoRemote };
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
export async function getExistingPackages(packages: string[]): Promise<{ existing: string[]; missing: string[] }> {
|
|
235
|
+
const dir = getConfigDir();
|
|
236
|
+
const existing: string[] = [];
|
|
237
|
+
const missing: string[] = [];
|
|
238
|
+
|
|
239
|
+
for (const pkg of packages) {
|
|
240
|
+
const exists = await Bun.file(`${dir}/${pkg}/package.json`).exists();
|
|
241
|
+
if (exists) {
|
|
242
|
+
existing.push(pkg);
|
|
243
|
+
} else {
|
|
244
|
+
missing.push(pkg);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
return { existing, missing };
|
|
249
|
+
}
|
package/src/contract.ts
CHANGED
|
@@ -223,6 +223,7 @@ const SyncResultSchema = z.object({
|
|
|
223
223
|
status: z.enum(["synced", "error"]),
|
|
224
224
|
account: z.string(),
|
|
225
225
|
gateway: z.string(),
|
|
226
|
+
socialUrl: z.string().optional(),
|
|
226
227
|
hostUrl: z.string(),
|
|
227
228
|
catalogUpdated: z.boolean(),
|
|
228
229
|
packagesUpdated: z.array(z.string()),
|
package/src/lib/sync.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { mkdtemp, rm, cp, mkdir } from "fs/promises";
|
|
2
|
-
import { tmpdir } from "os";
|
|
3
|
-
import { join, dirname } from "path";
|
|
4
1
|
import { execa } from "execa";
|
|
2
|
+
import { cp, mkdir, mkdtemp, rm } from "fs/promises";
|
|
3
|
+
import { tmpdir } from "os";
|
|
4
|
+
import { dirname, join } from "path";
|
|
5
5
|
import type { BosConfig } from "../config";
|
|
6
6
|
|
|
7
7
|
export interface FileSyncResult {
|
|
@@ -24,10 +24,14 @@ export async function syncFiles(options: FileSyncOptions): Promise<FileSyncResul
|
|
|
24
24
|
const results: FileSyncResult[] = [];
|
|
25
25
|
|
|
26
26
|
for (const pkg of packages) {
|
|
27
|
+
const pkgDir = `${configDir}/${pkg}`;
|
|
28
|
+
const pkgDirExists = await Bun.file(`${pkgDir}/package.json`).exists();
|
|
29
|
+
if (!pkgDirExists) continue;
|
|
30
|
+
|
|
27
31
|
const appConfig = bosConfig.app[pkg] as {
|
|
28
32
|
template?: string;
|
|
29
33
|
files?: string[];
|
|
30
|
-
sync?: { dependencies?: boolean; devDependencies?: boolean
|
|
34
|
+
sync?: { dependencies?: boolean; devDependencies?: boolean };
|
|
31
35
|
};
|
|
32
36
|
|
|
33
37
|
if (!appConfig?.template || !appConfig?.files) {
|
|
@@ -44,7 +48,6 @@ export async function syncFiles(options: FileSyncOptions): Promise<FileSyncResul
|
|
|
44
48
|
const filesSynced: string[] = [];
|
|
45
49
|
const depsAdded: string[] = [];
|
|
46
50
|
const depsUpdated: string[] = [];
|
|
47
|
-
const pkgDir = `${configDir}/${pkg}`;
|
|
48
51
|
|
|
49
52
|
for (const file of appConfig.files) {
|
|
50
53
|
const srcPath = join(tempDir, file);
|
|
@@ -53,7 +56,7 @@ export async function syncFiles(options: FileSyncOptions): Promise<FileSyncResul
|
|
|
53
56
|
try {
|
|
54
57
|
const destDir = dirname(destPath);
|
|
55
58
|
await mkdir(destDir, { recursive: true });
|
|
56
|
-
await cp(srcPath, destPath, { force, recursive: true });
|
|
59
|
+
await cp(srcPath, destPath, { force: true, recursive: true });
|
|
57
60
|
filesSynced.push(file);
|
|
58
61
|
} catch {
|
|
59
62
|
}
|
|
@@ -103,16 +106,10 @@ export async function syncFiles(options: FileSyncOptions): Promise<FileSyncResul
|
|
|
103
106
|
}
|
|
104
107
|
}
|
|
105
108
|
|
|
106
|
-
if (
|
|
109
|
+
if (templatePkg.scripts) {
|
|
107
110
|
if (!localPkg.scripts) localPkg.scripts = {};
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
: syncConfig.scripts;
|
|
111
|
-
|
|
112
|
-
for (const scriptName of scriptsToSync) {
|
|
113
|
-
if (templatePkg.scripts[scriptName]) {
|
|
114
|
-
localPkg.scripts[scriptName] = templatePkg.scripts[scriptName];
|
|
115
|
-
}
|
|
111
|
+
for (const [name, script] of Object.entries(templatePkg.scripts)) {
|
|
112
|
+
localPkg.scripts[name] = script;
|
|
116
113
|
}
|
|
117
114
|
}
|
|
118
115
|
|
package/src/plugin.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createPlugin } from "every-plugin";
|
|
2
2
|
import { Effect } from "every-plugin/effect";
|
|
3
3
|
import { z } from "every-plugin/zod";
|
|
4
|
-
import { Graph } from "near-social-js";
|
|
4
|
+
import { Graph, calculateRequiredDeposit } from "near-social-js";
|
|
5
5
|
|
|
6
6
|
import { createProcessRegistry } from "./lib/process-registry";
|
|
7
7
|
import {
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
type BosConfig as BosConfigType,
|
|
10
10
|
DEFAULT_DEV_CONFIG,
|
|
11
11
|
getConfigDir,
|
|
12
|
+
getExistingPackages,
|
|
12
13
|
getHost,
|
|
13
14
|
getHostRemoteUrl,
|
|
14
15
|
getPackages,
|
|
@@ -16,6 +17,7 @@ import {
|
|
|
16
17
|
getRemotes,
|
|
17
18
|
loadConfig,
|
|
18
19
|
type RemoteConfig,
|
|
20
|
+
resolvePackageModes,
|
|
19
21
|
type SourceMode,
|
|
20
22
|
setConfig
|
|
21
23
|
} from "./config";
|
|
@@ -197,10 +199,24 @@ export default createPlugin({
|
|
|
197
199
|
|
|
198
200
|
createRouter: (deps: BosDeps, builder) => ({
|
|
199
201
|
dev: builder.dev.handler(async ({ input }) => {
|
|
202
|
+
const { modes, autoRemote } = await resolvePackageModes(
|
|
203
|
+
["host", "ui", "api"],
|
|
204
|
+
{ host: input.host, ui: input.ui, api: input.api }
|
|
205
|
+
);
|
|
206
|
+
|
|
207
|
+
if (autoRemote.length > 0) {
|
|
208
|
+
console.log();
|
|
209
|
+
console.log(colors.cyan(` ${icons.config} Auto-detecting packages...`));
|
|
210
|
+
for (const pkg of autoRemote) {
|
|
211
|
+
console.log(colors.dim(` ${pkg} not found locally → using remote`));
|
|
212
|
+
}
|
|
213
|
+
console.log();
|
|
214
|
+
}
|
|
215
|
+
|
|
200
216
|
const appConfig = buildAppConfig({
|
|
201
|
-
host:
|
|
202
|
-
ui:
|
|
203
|
-
api:
|
|
217
|
+
host: modes.host,
|
|
218
|
+
ui: modes.ui,
|
|
219
|
+
api: modes.api,
|
|
204
220
|
proxy: input.proxy,
|
|
205
221
|
});
|
|
206
222
|
|
|
@@ -211,6 +227,7 @@ export default createPlugin({
|
|
|
211
227
|
status: "error" as const,
|
|
212
228
|
description: "No remote URL configured for host",
|
|
213
229
|
processes: [],
|
|
230
|
+
autoRemote,
|
|
214
231
|
};
|
|
215
232
|
}
|
|
216
233
|
}
|
|
@@ -363,6 +380,27 @@ export default createPlugin({
|
|
|
363
380
|
return {
|
|
364
381
|
status: "error" as const,
|
|
365
382
|
built: [],
|
|
383
|
+
skipped: [],
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
const { existing, missing } = await getExistingPackages(targets);
|
|
388
|
+
|
|
389
|
+
if (missing.length > 0) {
|
|
390
|
+
console.log();
|
|
391
|
+
console.log(colors.cyan(` ${icons.config} Auto-detecting packages...`));
|
|
392
|
+
for (const pkg of missing) {
|
|
393
|
+
console.log(colors.dim(` ${pkg} not found locally → skipping`));
|
|
394
|
+
}
|
|
395
|
+
console.log();
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
if (existing.length === 0) {
|
|
399
|
+
console.log(colors.dim(` No packages found locally to build`));
|
|
400
|
+
return {
|
|
401
|
+
status: "error" as const,
|
|
402
|
+
built: [],
|
|
403
|
+
skipped: missing,
|
|
366
404
|
};
|
|
367
405
|
}
|
|
368
406
|
|
|
@@ -384,7 +422,7 @@ export default createPlugin({
|
|
|
384
422
|
}
|
|
385
423
|
}
|
|
386
424
|
|
|
387
|
-
for (const target of
|
|
425
|
+
for (const target of existing) {
|
|
388
426
|
const buildConfig = buildCommands[target];
|
|
389
427
|
if (!buildConfig) continue;
|
|
390
428
|
|
|
@@ -404,6 +442,7 @@ export default createPlugin({
|
|
|
404
442
|
return {
|
|
405
443
|
status: "success" as const,
|
|
406
444
|
built,
|
|
445
|
+
skipped: missing,
|
|
407
446
|
deployed: buildInput.deploy,
|
|
408
447
|
};
|
|
409
448
|
}),
|
|
@@ -434,9 +473,29 @@ export default createPlugin({
|
|
|
434
473
|
const bosEnv = yield* loadBosEnv;
|
|
435
474
|
const privateKey = nearPrivateKey || bosEnv.NEAR_PRIVATE_KEY;
|
|
436
475
|
|
|
437
|
-
const socialArgs = buildSocialSetArgs(account, gatewayDomain, bosConfig)
|
|
476
|
+
const socialArgs = buildSocialSetArgs(account, gatewayDomain, bosConfig) as {
|
|
477
|
+
data: Record<string, Record<string, unknown>>;
|
|
478
|
+
};
|
|
438
479
|
const argsBase64 = Buffer.from(JSON.stringify(socialArgs)).toString("base64");
|
|
439
480
|
|
|
481
|
+
const graph = new Graph({
|
|
482
|
+
network,
|
|
483
|
+
contractId: socialContract,
|
|
484
|
+
});
|
|
485
|
+
const storageBalance = yield* Effect.tryPromise({
|
|
486
|
+
try: () => graph.storageBalanceOf(account),
|
|
487
|
+
catch: () => new Error("Failed to fetch storage balance"),
|
|
488
|
+
});
|
|
489
|
+
|
|
490
|
+
const requiredDeposit = calculateRequiredDeposit({
|
|
491
|
+
data: socialArgs.data,
|
|
492
|
+
storageBalance: storageBalance ? {
|
|
493
|
+
available: BigInt(storageBalance.available),
|
|
494
|
+
total: BigInt(storageBalance.total),
|
|
495
|
+
} : null,
|
|
496
|
+
});
|
|
497
|
+
const depositAmount = requiredDeposit.toFixed();
|
|
498
|
+
|
|
440
499
|
if (publishInput.dryRun) {
|
|
441
500
|
return {
|
|
442
501
|
status: "dry-run" as const,
|
|
@@ -453,7 +512,7 @@ export default createPlugin({
|
|
|
453
512
|
network,
|
|
454
513
|
privateKey,
|
|
455
514
|
gas: "300Tgas",
|
|
456
|
-
deposit: "0
|
|
515
|
+
deposit: depositAmount === "0" ? "1" : depositAmount,
|
|
457
516
|
});
|
|
458
517
|
|
|
459
518
|
return {
|
|
@@ -1228,14 +1287,16 @@ export default createPlugin({
|
|
|
1228
1287
|
const DEFAULT_SYNC_ACCOUNT = "every.near";
|
|
1229
1288
|
const DEFAULT_SYNC_GATEWAY = "everything.dev";
|
|
1230
1289
|
|
|
1231
|
-
const account = input.account || DEFAULT_SYNC_ACCOUNT;
|
|
1232
|
-
const gateway = input.gateway || DEFAULT_SYNC_GATEWAY;
|
|
1290
|
+
const account = input.account || bosConfig?.account || DEFAULT_SYNC_ACCOUNT;
|
|
1291
|
+
const gateway = input.gateway || (bosConfig ? getGatewayDomain(bosConfig) : null) || DEFAULT_SYNC_GATEWAY;
|
|
1292
|
+
const socialUrl = `https://near.social/mob.near/widget/State.Inspector?key=${account}/bos/gateways/${gateway}`;
|
|
1233
1293
|
|
|
1234
1294
|
if (!bosConfig) {
|
|
1235
1295
|
return {
|
|
1236
1296
|
status: "error" as const,
|
|
1237
1297
|
account,
|
|
1238
1298
|
gateway,
|
|
1299
|
+
socialUrl,
|
|
1239
1300
|
hostUrl: "",
|
|
1240
1301
|
catalogUpdated: false,
|
|
1241
1302
|
packagesUpdated: [],
|
|
@@ -1362,10 +1423,12 @@ export default createPlugin({
|
|
|
1362
1423
|
const packagesUpdated: string[] = [];
|
|
1363
1424
|
|
|
1364
1425
|
for (const pkg of packages) {
|
|
1365
|
-
const
|
|
1366
|
-
const
|
|
1426
|
+
const pkgDir = `${configDir}/${pkg}`;
|
|
1427
|
+
const pkgDirExists = await Bun.file(`${pkgDir}/package.json`).exists();
|
|
1428
|
+
if (!pkgDirExists) continue;
|
|
1367
1429
|
|
|
1368
|
-
|
|
1430
|
+
const pkgPath = `${pkgDir}/package.json`;
|
|
1431
|
+
const pkgFile = Bun.file(pkgPath);
|
|
1369
1432
|
|
|
1370
1433
|
const pkgJson = await pkgFile.json() as {
|
|
1371
1434
|
dependencies?: Record<string, string>;
|
|
@@ -1413,6 +1476,7 @@ export default createPlugin({
|
|
|
1413
1476
|
status: "synced" as const,
|
|
1414
1477
|
account,
|
|
1415
1478
|
gateway,
|
|
1479
|
+
socialUrl,
|
|
1416
1480
|
hostUrl,
|
|
1417
1481
|
catalogUpdated: true,
|
|
1418
1482
|
packagesUpdated,
|