everything-dev 1.6.0 → 1.7.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.
Files changed (108) hide show
  1. package/dist/api-contract.cjs +55 -8
  2. package/dist/api-contract.cjs.map +1 -1
  3. package/dist/api-contract.mjs +55 -8
  4. package/dist/api-contract.mjs.map +1 -1
  5. package/dist/app.cjs +26 -2
  6. package/dist/app.cjs.map +1 -1
  7. package/dist/app.mjs +27 -3
  8. package/dist/app.mjs.map +1 -1
  9. package/dist/cli/init.cjs +4 -4
  10. package/dist/cli/init.cjs.map +1 -1
  11. package/dist/cli/init.mjs +4 -4
  12. package/dist/cli/init.mjs.map +1 -1
  13. package/dist/cli/sync.cjs +2 -2
  14. package/dist/cli/sync.cjs.map +1 -1
  15. package/dist/cli/sync.mjs +2 -2
  16. package/dist/cli/sync.mjs.map +1 -1
  17. package/dist/cli.cjs +0 -1
  18. package/dist/cli.cjs.map +1 -1
  19. package/dist/cli.mjs +0 -1
  20. package/dist/cli.mjs.map +1 -1
  21. package/dist/components/streaming-view.cjs +0 -18
  22. package/dist/components/streaming-view.cjs.map +1 -1
  23. package/dist/components/streaming-view.mjs +0 -18
  24. package/dist/components/streaming-view.mjs.map +1 -1
  25. package/dist/config.cjs +21 -5
  26. package/dist/config.cjs.map +1 -1
  27. package/dist/config.d.cts +2 -1
  28. package/dist/config.d.cts.map +1 -1
  29. package/dist/config.d.mts +2 -1
  30. package/dist/config.d.mts.map +1 -1
  31. package/dist/config.mjs +21 -6
  32. package/dist/config.mjs.map +1 -1
  33. package/dist/contract.cjs +8 -1
  34. package/dist/contract.cjs.map +1 -1
  35. package/dist/contract.d.cts +44 -8
  36. package/dist/contract.d.cts.map +1 -1
  37. package/dist/contract.d.mts +44 -8
  38. package/dist/contract.d.mts.map +1 -1
  39. package/dist/contract.meta.cjs +1 -1
  40. package/dist/contract.meta.cjs.map +1 -1
  41. package/dist/contract.meta.d.cts +1 -1
  42. package/dist/contract.meta.d.mts +1 -1
  43. package/dist/contract.meta.mjs +1 -1
  44. package/dist/contract.meta.mjs.map +1 -1
  45. package/dist/contract.mjs +8 -1
  46. package/dist/contract.mjs.map +1 -1
  47. package/dist/dev-session.cjs +51 -66
  48. package/dist/dev-session.cjs.map +1 -1
  49. package/dist/dev-session.mjs +52 -67
  50. package/dist/dev-session.mjs.map +1 -1
  51. package/dist/fastkv.cjs +56 -0
  52. package/dist/fastkv.cjs.map +1 -1
  53. package/dist/fastkv.d.cts +45 -1
  54. package/dist/fastkv.d.cts.map +1 -1
  55. package/dist/fastkv.d.mts +45 -1
  56. package/dist/fastkv.d.mts.map +1 -1
  57. package/dist/fastkv.mjs +54 -1
  58. package/dist/fastkv.mjs.map +1 -1
  59. package/dist/host.cjs +1 -1
  60. package/dist/host.cjs.map +1 -1
  61. package/dist/host.mjs +1 -1
  62. package/dist/host.mjs.map +1 -1
  63. package/dist/index.cjs +4 -0
  64. package/dist/index.d.cts +4 -4
  65. package/dist/index.d.mts +4 -4
  66. package/dist/index.mjs +3 -3
  67. package/dist/near-cli.cjs +1 -1
  68. package/dist/near-cli.mjs +1 -1
  69. package/dist/orchestrator.cjs +55 -20
  70. package/dist/orchestrator.cjs.map +1 -1
  71. package/dist/orchestrator.d.cts +5 -4
  72. package/dist/orchestrator.d.cts.map +1 -1
  73. package/dist/orchestrator.d.mts +5 -4
  74. package/dist/orchestrator.d.mts.map +1 -1
  75. package/dist/orchestrator.mjs +55 -20
  76. package/dist/orchestrator.mjs.map +1 -1
  77. package/dist/plugin.cjs +135 -9
  78. package/dist/plugin.cjs.map +1 -1
  79. package/dist/plugin.d.cts +49 -8
  80. package/dist/plugin.d.cts.map +1 -1
  81. package/dist/plugin.d.mts +49 -8
  82. package/dist/plugin.d.mts.map +1 -1
  83. package/dist/plugin.mjs +137 -11
  84. package/dist/plugin.mjs.map +1 -1
  85. package/dist/types.cjs +15 -5
  86. package/dist/types.cjs.map +1 -1
  87. package/dist/types.d.cts +60 -9
  88. package/dist/types.d.cts.map +1 -1
  89. package/dist/types.d.mts +60 -9
  90. package/dist/types.d.mts.map +1 -1
  91. package/dist/types.mjs +15 -5
  92. package/dist/types.mjs.map +1 -1
  93. package/package.json +2 -2
  94. package/src/api-contract.ts +88 -9
  95. package/src/app.ts +55 -7
  96. package/src/cli/init.ts +6 -6
  97. package/src/cli/sync.ts +5 -3
  98. package/src/cli.ts +0 -1
  99. package/src/components/streaming-view.ts +0 -20
  100. package/src/config.ts +39 -23
  101. package/src/contract.meta.ts +4 -1
  102. package/src/contract.ts +7 -0
  103. package/src/dev-session.ts +85 -83
  104. package/src/fastkv.ts +95 -0
  105. package/src/host.ts +1 -1
  106. package/src/orchestrator.ts +61 -31
  107. package/src/plugin.ts +202 -5
  108. package/src/types.ts +38 -4
package/src/plugin.ts CHANGED
@@ -1,4 +1,5 @@
1
- import { readFileSync, writeFileSync } from "node:fs";
1
+ import { randomBytes } from "node:crypto";
2
+ import { existsSync, readFileSync, writeFileSync } from "node:fs";
2
3
  import { basename, dirname, join, resolve } from "node:path";
3
4
  import { Effect } from "effect";
4
5
  import { syncApiContractBridge } from "./api-contract";
@@ -46,9 +47,14 @@ import { type AppConfig, type AppOrchestrator, startApp } from "./dev-session";
46
47
  import {
47
48
  buildRegistryConfigUrlForNetwork,
48
49
  fetchBosConfigFromFastKv,
50
+ fetchPluginFromRegistry,
51
+ fetchRemotePluginManifest,
49
52
  getRegistryNamespaceForAccount,
50
53
  getRegistryNamespaceForNetwork,
54
+ type PluginManifest,
55
+ parsePluginBosUrl,
51
56
  } from "./fastkv";
57
+ import { computeSriHashForUrl } from "./integrity";
52
58
  import { addFunctionCallAccessKey, ensureNearCli, executeTransaction } from "./near-cli";
53
59
  import { getNetworkIdForAccount } from "./network";
54
60
  import { createPlugin, z } from "./sdk";
@@ -56,6 +62,35 @@ import { syncAndGenerateSharedUi } from "./shared";
56
62
  import type { BosConfig, RuntimeConfig, SourceMode } from "./types";
57
63
  import { run } from "./utils/run";
58
64
 
65
+ function ensureEnvFile(configDir: string): void {
66
+ const envPath = join(configDir, ".env");
67
+ const examplePath = join(configDir, ".env.example");
68
+
69
+ if (existsSync(envPath)) return;
70
+
71
+ if (!existsSync(examplePath)) return;
72
+
73
+ const content = readFileSync(examplePath, "utf-8");
74
+ const lines = content.split("\n");
75
+
76
+ const secret = randomBytes(32).toString("base64url");
77
+
78
+ const updated = lines
79
+ .map((line) => {
80
+ if (/^BETTER_AUTH_SECRET=/.test(line)) {
81
+ return `BETTER_AUTH_SECRET=${secret}`;
82
+ }
83
+ if (/^BETTER_AUTH_URL=/.test(line)) {
84
+ return `BETTER_AUTH_URL=http://localhost:3000`;
85
+ }
86
+ return line;
87
+ })
88
+ .join("\n");
89
+
90
+ writeFileSync(envPath, updated);
91
+ console.log(`[CLI] Created .env from .env.example with generated BETTER_AUTH_SECRET`);
92
+ }
93
+
59
94
  const DEFAULT_DEV_CONFIG: AppConfig = {
60
95
  host: "local",
61
96
  ui: "local",
@@ -167,6 +202,9 @@ function determineProcesses(
167
202
  const processes: string[] = [];
168
203
  if (config.ssr && config.ui === "local") processes.push("ui-ssr");
169
204
  if (config.ui === "local") processes.push("ui");
205
+ if (localPackages.includes("auth") && runtimeConfig?.auth?.source === "local") {
206
+ processes.push("auth");
207
+ }
170
208
  if (config.api === "local" && !config.proxy) processes.push("api");
171
209
  for (const pkg of localPackages) {
172
210
  if (pkg.startsWith("plugin:")) {
@@ -256,6 +294,9 @@ function listPluginAttachments(config: BosConfig | null) {
256
294
  source: attachment.development?.startsWith("local:")
257
295
  ? ("local" as const)
258
296
  : ("remote" as const),
297
+ integrity: attachment.integrity,
298
+ version: attachment.version,
299
+ name: attachment.name,
259
300
  }))
260
301
  .sort((a, b) => a.key.localeCompare(b.key));
261
302
  }
@@ -522,7 +563,74 @@ export default createPlugin({
522
563
  };
523
564
  }
524
565
 
525
- const key = sanitizePluginKey(input.as ?? defaultPluginKey(input.source));
566
+ const pluginRef = parsePluginBosUrl(input.source);
567
+ let production = input.production ?? input.source;
568
+ let integrity: string | undefined;
569
+ let version: string | undefined;
570
+ let name: string | undefined;
571
+
572
+ if (pluginRef) {
573
+ try {
574
+ const entry = await fetchPluginFromRegistry(pluginRef.accountId, pluginRef.pluginName);
575
+ if (!entry) {
576
+ return {
577
+ status: "error" as const,
578
+ key: "",
579
+ error: `Plugin not found in registry: bos://${pluginRef.accountId}/plugins/${pluginRef.pluginName}`,
580
+ };
581
+ }
582
+
583
+ const manifest = entry.manifest;
584
+ if (
585
+ manifest.schemaVersion !== 1 ||
586
+ manifest.kind !== "every-plugin/manifest" ||
587
+ !manifest.plugin?.name ||
588
+ !manifest.plugin?.version ||
589
+ !manifest.runtime?.remoteEntry
590
+ ) {
591
+ return {
592
+ status: "error" as const,
593
+ key: "",
594
+ error: `Invalid plugin manifest for bos://${pluginRef.accountId}/plugins/${pluginRef.pluginName}`,
595
+ };
596
+ }
597
+
598
+ production = entry.metadata.cdnUrl || input.production || input.source;
599
+ name = manifest.plugin.name;
600
+ version = manifest.plugin.version;
601
+ } catch (error) {
602
+ return {
603
+ status: "error" as const,
604
+ key: "",
605
+ error: `Failed to resolve plugin from registry: ${error instanceof Error ? error.message : error}`,
606
+ };
607
+ }
608
+ }
609
+
610
+ if (!input.source.startsWith("local:") && !pluginRef && production.startsWith("https://")) {
611
+ try {
612
+ const manifest = await fetchRemotePluginManifest(production);
613
+ if (manifest) {
614
+ name = manifest.plugin.name;
615
+ version = manifest.plugin.version;
616
+ }
617
+ } catch {
618
+ console.warn(`[plugin add] Could not fetch manifest from ${production}`);
619
+ }
620
+ }
621
+
622
+ if (!input.source.startsWith("local:") && production.startsWith("https://")) {
623
+ try {
624
+ const computed = await computeSriHashForUrl(production);
625
+ if (computed) integrity = computed;
626
+ } catch {
627
+ console.warn(`[plugin add] Could not compute integrity for ${production}`);
628
+ }
629
+ }
630
+
631
+ const key = sanitizePluginKey(
632
+ input.as ?? (pluginRef ? pluginRef.pluginName : defaultPluginKey(input.source)),
633
+ );
526
634
  const existing = deps.bosConfig.plugins?.[key];
527
635
  const nextPlugins = { ...(deps.bosConfig.plugins ?? {}) };
528
636
 
@@ -534,7 +642,10 @@ export default createPlugin({
534
642
  }
535
643
  : {
536
644
  ...(existing ?? {}),
537
- production: input.production ?? input.source,
645
+ production,
646
+ ...(integrity ? { integrity } : {}),
647
+ ...(name ? { name } : {}),
648
+ ...(version ? { version } : {}),
538
649
  };
539
650
 
540
651
  deps.bosConfig = {
@@ -550,6 +661,8 @@ export default createPlugin({
550
661
  key,
551
662
  development: deps.bosConfig.plugins?.[key]?.development,
552
663
  production: deps.bosConfig.plugins?.[key]?.production,
664
+ integrity,
665
+ version,
553
666
  };
554
667
  }),
555
668
 
@@ -633,7 +746,11 @@ export default createPlugin({
633
746
  };
634
747
  }
635
748
 
636
- const pkgJson = (await Bun.file(pkgPath).json()) as { scripts?: Record<string, string> };
749
+ const pkgJson = (await Bun.file(pkgPath).json()) as {
750
+ scripts?: Record<string, string>;
751
+ name?: string;
752
+ version?: string;
753
+ };
637
754
  const script = pkgJson.scripts?.deploy ? "deploy" : "build";
638
755
 
639
756
  const { stdout, stderr, exitCode } = (await run("bun", ["run", script], {
@@ -654,7 +771,21 @@ export default createPlugin({
654
771
  if (stdout.trim()) process.stdout.write(stdout);
655
772
  if (stderr.trim()) process.stderr.write(stderr);
656
773
 
657
- const publishedUrl = extractPublishedUrl(`${stdout}\n${stderr}`);
774
+ let publishedUrl = extractPublishedUrl(`${stdout}\n${stderr}`);
775
+
776
+ let manifest: PluginManifest | null = null;
777
+ if (publishedUrl) {
778
+ manifest = await fetchRemotePluginManifest(publishedUrl);
779
+ } else if (attachment.production) {
780
+ manifest = await fetchRemotePluginManifest(attachment.production);
781
+ if (manifest) {
782
+ publishedUrl = attachment.production;
783
+ }
784
+ }
785
+
786
+ const integrity = publishedUrl ? await computeSriHashForUrl(publishedUrl) : null;
787
+ const version = manifest?.plugin.version ?? pkgJson.version;
788
+
658
789
  if (publishedUrl) {
659
790
  deps.bosConfig = {
660
791
  ...deps.bosConfig,
@@ -663,10 +794,65 @@ export default createPlugin({
663
794
  [input.key]: {
664
795
  ...(deps.bosConfig.plugins?.[input.key] ?? {}),
665
796
  production: publishedUrl,
797
+ ...(integrity ? { integrity } : {}),
798
+ ...(manifest?.plugin.name ? { name: manifest.plugin.name } : {}),
799
+ ...(version ? { version } : {}),
666
800
  },
667
801
  },
668
802
  };
669
803
  await saveBosConfig(deps.configDir, deps.bosConfig);
804
+
805
+ const account = deps.bosConfig.account;
806
+ const network = getNetworkIdForAccount(account);
807
+ if (manifest && version) {
808
+ try {
809
+ const registryEntries: Record<string, string> = {
810
+ [`plugins/${account}/${input.key}/manifest.json`]: JSON.stringify(manifest),
811
+ [`plugins/${account}/${input.key}/metadata`]: JSON.stringify({
812
+ title: null,
813
+ description: null,
814
+ repoUrl: deps.bosConfig.repository ?? null,
815
+ version,
816
+ publishedAt: new Date().toISOString(),
817
+ cdnUrl: publishedUrl,
818
+ integrity,
819
+ }),
820
+ [`plugins/${account}/${input.key}/versions/${version}/manifest.json`]:
821
+ JSON.stringify(manifest),
822
+ };
823
+ const payload = JSON.stringify(registryEntries);
824
+ const argsBase64 = Buffer.from(payload).toString("base64");
825
+ const privateKey = process.env.NEAR_PRIVATE_KEY || process.env.BOS_NEAR_PRIVATE_KEY;
826
+
827
+ await Effect.runPromise(ensureNearCli);
828
+ try {
829
+ await Effect.runPromise(
830
+ executeTransaction({
831
+ account,
832
+ contract: getRegistryNamespaceForNetwork(network),
833
+ method: "__fastdata_kv",
834
+ argsBase64,
835
+ network,
836
+ privateKey,
837
+ gas: "50Tgas",
838
+ deposit: "0NEAR",
839
+ }),
840
+ );
841
+ } catch (registryError) {
842
+ const txHash = extractTransactionHash(registryError);
843
+ if (!txHash) {
844
+ console.warn(
845
+ `[publish] Plugin registry write failed: ${registryError instanceof Error ? registryError.message : registryError}`,
846
+ );
847
+ }
848
+ }
849
+ } catch (registryError) {
850
+ console.warn(
851
+ `[publish] Plugin registry write skipped: ${registryError instanceof Error ? registryError.message : registryError}`,
852
+ );
853
+ }
854
+ }
855
+
670
856
  await refreshApiContractBridge(deps.configDir);
671
857
  }
672
858
 
@@ -676,11 +862,15 @@ export default createPlugin({
676
862
  path: localPath,
677
863
  script,
678
864
  production: publishedUrl ?? attachment.production,
865
+ integrity: integrity ?? undefined,
866
+ version: version ?? undefined,
679
867
  };
680
868
  },
681
869
  ),
682
870
 
683
871
  dev: builder.dev.handler(async ({ input }: { input: DevOptions }) => {
872
+ ensureEnvFile(deps.configDir);
873
+
684
874
  const localPackages = detectLocalPackages(
685
875
  deps.bosConfig ?? undefined,
686
876
  deps.runtimeConfig ?? undefined,
@@ -741,6 +931,7 @@ export default createPlugin({
741
931
  const developmentRuntime = buildRuntimeConfig(deps.bosConfig, {
742
932
  uiSource: appConfig.ui,
743
933
  apiSource: appConfig.api,
934
+ authSource: refreshedLocalPackages.includes("auth") ? "local" : "remote",
744
935
  hostUrl: `http://localhost:${hostPort}`,
745
936
  proxy: env.API_PROXY,
746
937
  env: "development",
@@ -778,6 +969,8 @@ export default createPlugin({
778
969
  }),
779
970
 
780
971
  start: builder.start.handler(async ({ input }: { input: StartOptions }) => {
972
+ ensureEnvFile(deps.configDir);
973
+
781
974
  let remoteConfig: BosConfig | null = null;
782
975
 
783
976
  if (input.account && input.domain) {
@@ -808,6 +1001,7 @@ export default createPlugin({
808
1001
  const runtimeConfig = buildRuntimeConfig(config, {
809
1002
  uiSource: "remote",
810
1003
  apiSource: "remote",
1004
+ authSource: "remote",
811
1005
  hostUrl: `http://localhost:${port}`,
812
1006
  env: "production",
813
1007
  plugins: runtimePlugins,
@@ -867,6 +1061,7 @@ export default createPlugin({
867
1061
  const runtimeConfig = buildRuntimeConfig(deps.bosConfig, {
868
1062
  uiSource: deps.bosConfig.app.ui?.development ? "local" : "remote",
869
1063
  apiSource: deps.bosConfig.app.api?.development ? "local" : "remote",
1064
+ authSource: deps.bosConfig.app.auth?.development ? "local" : "remote",
870
1065
  hostUrl: resolveDevelopmentHostUrl(deps.bosConfig.app.host.development),
871
1066
  env: "development",
872
1067
  plugins: deps.runtimeConfig?.plugins,
@@ -1203,6 +1398,8 @@ export default createPlugin({
1203
1398
  await runBunInstall(directory);
1204
1399
  }
1205
1400
 
1401
+ ensureEnvFile(directory);
1402
+
1206
1403
  return {
1207
1404
  status: "initialized" as const,
1208
1405
  directory,
package/src/types.ts CHANGED
@@ -1,5 +1,29 @@
1
1
  import { z } from "./sdk";
2
2
 
3
+ export interface BosConfigInput extends Record<string, unknown> {
4
+ extends?: string;
5
+ account?: string;
6
+ domain?: string;
7
+ testnet?: string;
8
+ template?: string;
9
+ gateway?: {
10
+ development?: string;
11
+ production?: string;
12
+ account?: string;
13
+ };
14
+ development?: string;
15
+ production?: string;
16
+ integrity?: string;
17
+ name?: string;
18
+ version?: string;
19
+ proxy?: string;
20
+ variables?: Record<string, string>;
21
+ secrets?: string[];
22
+ app?: Record<string, Record<string, unknown>>;
23
+ shared?: Record<string, Record<string, Record<string, unknown>>>;
24
+ plugins?: Record<string, BosConfigInput>;
25
+ }
26
+
3
27
  export const SourceModeSchema = z.enum(["local", "remote"]);
4
28
  export type SourceMode = z.infer<typeof SourceModeSchema>;
5
29
 
@@ -28,7 +52,7 @@ export const ApiPluginConfigSchema = z.object({
28
52
  name: z.string(),
29
53
  development: z.string().optional(),
30
54
  production: z.string().optional(),
31
- productionIntegrity: z.string().optional(),
55
+ integrity: z.string().optional(),
32
56
  proxy: z.string().optional(),
33
57
  variables: z.record(z.string(), z.string()).optional(),
34
58
  secrets: z.array(z.string()).optional(),
@@ -39,7 +63,9 @@ export const BosPluginRefSchema = z.object({
39
63
  extends: z.string().optional(),
40
64
  development: z.string().optional(),
41
65
  production: z.string().optional(),
42
- productionIntegrity: z.string().optional(),
66
+ integrity: z.string().optional(),
67
+ name: z.string().optional(),
68
+ version: z.string().optional(),
43
69
  proxy: z.string().optional(),
44
70
  variables: z.record(z.string(), z.string()).optional(),
45
71
  secrets: z.array(z.string()).optional(),
@@ -65,7 +91,7 @@ export const UiConfigSchema = z.object({
65
91
  name: z.string(),
66
92
  development: z.string().optional(),
67
93
  production: z.string().optional(),
68
- productionIntegrity: z.string().optional(),
94
+ integrity: z.string().optional(),
69
95
  ssr: z.string().optional(),
70
96
  ssrIntegrity: z.string().optional(),
71
97
  });
@@ -74,7 +100,7 @@ export type UiConfig = z.infer<typeof UiConfigSchema>;
74
100
  export const HostConfigSchema = z.object({
75
101
  development: z.string(),
76
102
  production: z.string(),
77
- productionIntegrity: z.string().optional(),
103
+ integrity: z.string().optional(),
78
104
  secrets: z.array(z.string()).optional(),
79
105
  });
80
106
  export type HostConfig = z.infer<typeof HostConfigSchema>;
@@ -106,6 +132,7 @@ export const BosConfigSchema = z.object({
106
132
  host: HostConfigSchema,
107
133
  ui: UiConfigSchema,
108
134
  api: ApiPluginConfigSchema,
135
+ auth: ApiPluginConfigSchema.optional(),
109
136
  }),
110
137
  });
111
138
  export type BosConfig = z.infer<typeof BosConfigSchema>;
@@ -136,6 +163,13 @@ export const RuntimeConfigSchema = z.object({
136
163
  variables: z.record(z.string(), z.string()).optional(),
137
164
  secrets: z.array(z.string()).optional(),
138
165
  }),
166
+ auth: FederationEntrySchema.extend({
167
+ localPath: z.string().optional(),
168
+ port: z.number().optional(),
169
+ proxy: z.string().optional(),
170
+ variables: z.record(z.string(), z.string()).optional(),
171
+ secrets: z.array(z.string()).optional(),
172
+ }).optional(),
139
173
  plugins: z.record(z.string(), RuntimePluginConfigSchema).optional(),
140
174
  });
141
175
  export type RuntimeConfig = z.infer<typeof RuntimeConfigSchema>;