1tube 0.1.47 → 0.1.49

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 (3) hide show
  1. package/deno.lock +24 -14
  2. package/package.json +4 -4
  3. package/src/server.ts +113 -8
package/deno.lock CHANGED
@@ -15,13 +15,14 @@
15
15
  "npm:@ai-sdk/google@2": "2.0.74_zod@3.25.76",
16
16
  "npm:@ai-sdk/openai@2": "2.0.106_zod@3.25.76",
17
17
  "npm:ai@6": "6.0.193_zod@3.25.76",
18
- "npm:drizzle-kit@1.0.0-rc.3": "1.0.0-rc.3",
18
+ "npm:drizzle-kit@1.0.0-rc.4": "1.0.0-rc.4",
19
19
  "npm:drizzle-orm@1.0.0-rc.3": "1.0.0-rc.3_zod@3.25.76",
20
+ "npm:drizzle-orm@1.0.0-rc.4": "1.0.0-rc.4_zod@3.25.76",
20
21
  "npm:es-module-lexer@2": "2.1.0",
21
22
  "npm:esbuild@~0.25.5": "0.25.12",
22
23
  "npm:esbuild@~0.28.1": "0.28.1",
23
- "npm:hono@4": "4.12.27",
24
- "npm:hono@^4.12.27": "4.12.27",
24
+ "npm:hono@4": "4.12.30",
25
+ "npm:hono@^4.12.30": "4.12.30",
25
26
  "npm:typescript@latest": "6.0.3",
26
27
  "npm:zod@^3.23.0": "3.25.76"
27
28
  },
@@ -129,8 +130,8 @@
129
130
  "json-schema"
130
131
  ]
131
132
  },
132
- "@drizzle-team/brocli@0.11.0": {
133
- "integrity": "sha512-hD3pekGiPg0WPCCGAZmusBBJsDqGUR66Y452YgQsZOnkdQ7ViEPKuyP4huUGEZQefp8g34RRodXYmJ2TbCH+tg=="
133
+ "@drizzle-team/brocli@0.12.0": {
134
+ "integrity": "sha512-mlUE+rZ8CatQekLhnaiN91Iemdd+e2gFKooGlnRB3oPTL3VghLfX24dx7HrzMNeC1JrIB/0kpsfyty3f5HNfxQ=="
134
135
  },
135
136
  "@esbuild/aix-ppc64@0.25.12": {
136
137
  "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==",
@@ -417,8 +418,8 @@
417
418
  "zod"
418
419
  ]
419
420
  },
420
- "drizzle-kit@1.0.0-rc.3": {
421
- "integrity": "sha512-lwGIi6GTlEYzrtac1Szecns+zrAxjaOoNysfBCKRQOXQE7nMJ8IU2I2S6ek3FHEm1N30dQb5YrTdqV7zNH6n7A==",
421
+ "drizzle-kit@1.0.0-rc.4": {
422
+ "integrity": "sha512-KZCpjRyu+oYHLj/UJogfFlOkWhHVkaEI2EOT1U3NDVXUzLoTyPjqwFxwOrlQxsY6jzRyxcz4EacqboGfhEeYrA==",
422
423
  "dependencies": [
423
424
  "@drizzle-team/brocli",
424
425
  "@js-temporal/polyfill",
@@ -437,6 +438,15 @@
437
438
  "zod"
438
439
  ]
439
440
  },
441
+ "drizzle-orm@1.0.0-rc.4_zod@3.25.76": {
442
+ "integrity": "sha512-BT+pf+qoiYHqltoA88Jmf6ilGMXPlpfE0hEJKc2adRtMCAl25Swk/t5gXcWxZNAwdtf3F5gCd2FpeOyP/pT0Hw==",
443
+ "dependencies": [
444
+ "zod"
445
+ ],
446
+ "optionalPeers": [
447
+ "zod"
448
+ ]
449
+ },
440
450
  "es-module-lexer@2.1.0": {
441
451
  "integrity": "sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ=="
442
452
  },
@@ -515,11 +525,11 @@
515
525
  "resolve-pkg-maps"
516
526
  ]
517
527
  },
518
- "hono@4.12.27": {
519
- "integrity": "sha512-1yrb/+w6HWQJrUCLkJ2IF5jNIPvvFkblV5RNOYl6bV+OA6p9GLcMpHFFGTosSvHvcAUibuUukRqhlYI4z32C7Q=="
528
+ "hono@4.12.30": {
529
+ "integrity": "sha512-emn+JoJjrN9YTpRDS5it/UI2SO9BAE37T6I3d963RxcZ81G9A4pr2SZTEiiaiKbzx+NKRg5BZ89fCL7gCJCUog=="
520
530
  },
521
- "jiti@2.6.1": {
522
- "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==",
531
+ "jiti@2.7.0": {
532
+ "integrity": "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==",
523
533
  "bin": true
524
534
  },
525
535
  "jsbi@4.3.2": {
@@ -553,9 +563,9 @@
553
563
  ],
554
564
  "packageJson": {
555
565
  "dependencies": [
556
- "npm:drizzle-kit@1.0.0-rc.3",
557
- "npm:drizzle-orm@1.0.0-rc.3",
558
- "npm:hono@^4.12.27"
566
+ "npm:drizzle-kit@1.0.0-rc.4",
567
+ "npm:drizzle-orm@1.0.0-rc.4",
568
+ "npm:hono@^4.12.30"
559
569
  ]
560
570
  }
561
571
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "1tube",
3
- "version": "0.1.47",
3
+ "version": "0.1.49",
4
4
  "private": false,
5
5
  "description": "Self-hosted Supabase Edge Functions gateway for Deno, plus an ESLint plugin for consumers",
6
6
  "license": "MIT",
@@ -61,10 +61,10 @@
61
61
  "prepublishOnly": "bun run build:edge && bun run typecheck && bun run check && bun run smoke:bin"
62
62
  },
63
63
  "dependencies": {
64
- "drizzle-orm": "1.0.0-rc.3",
65
- "hono": "^4.12.27"
64
+ "drizzle-orm": "1.0.0-rc.4",
65
+ "hono": "^4.12.30"
66
66
  },
67
67
  "devDependencies": {
68
- "drizzle-kit": "1.0.0-rc.3"
68
+ "drizzle-kit": "1.0.0-rc.4"
69
69
  }
70
70
  }
package/src/server.ts CHANGED
@@ -819,9 +819,18 @@ async function readDenoImportMap(
819
819
  // confusing failures.
820
820
  const SECRETS_REQUIRED_IN_PROD = ["JWT_SECRET"];
821
821
 
822
- async function applyDevDefaults() {
822
+ /** Keys edge handlers typically need once `--dev` has finished bootstrapping. */
823
+ const DEV_SUPABASE_KEYS_REQUIRED = [
824
+ "SUPABASE_ANON_KEY",
825
+ "SUPABASE_SERVICE_ROLE_KEY",
826
+ ] as const;
827
+
828
+ function missingDevSupabaseKeys(): string[] {
829
+ return DEV_SUPABASE_KEYS_REQUIRED.filter((key) => !Deno.env.get(key));
830
+ }
831
+
832
+ function applyStatusEnv(statusEnv: Record<string, string>): number {
823
833
  let applied = 0;
824
- const statusEnv = await readLocalSupabaseStatusEnv();
825
834
  for (const [target, sources] of Object.entries(LOCAL_SUPABASE_STATUS_KEYS)) {
826
835
  if (Deno.env.get(target)) continue;
827
836
  const value = sources
@@ -833,11 +842,87 @@ async function applyDevDefaults() {
833
842
  Deno.env.set(target, value);
834
843
  applied++;
835
844
  }
845
+ return applied;
846
+ }
836
847
 
837
- if (!Deno.env.get("SUPABASE_URL") && Deno.env.get("VITE_SUPABASE_URL")) {
838
- Deno.env.set("SUPABASE_URL", Deno.env.get("VITE_SUPABASE_URL")!);
848
+ /**
849
+ * Map host-project aliases (Vite publishable key, modern secret names) onto
850
+ * the legacy SUPABASE_* names edge functions still read.
851
+ */
852
+ function applyDevEnvAliases(): number {
853
+ let applied = 0;
854
+ const aliasPairs: Array<[from: string, to: string]> = [
855
+ ["VITE_SUPABASE_URL", "SUPABASE_URL"],
856
+ ["VITE_SUPABASE_PUBLISHABLE_KEY", "SUPABASE_PUBLISHABLE_KEY"],
857
+ ["VITE_SUPABASE_PUBLISHABLE_KEY", "SUPABASE_ANON_KEY"],
858
+ ["SUPABASE_PUBLISHABLE_KEY", "SUPABASE_ANON_KEY"],
859
+ ["SUPABASE_SECRET_KEY", "SUPABASE_SERVICE_ROLE_KEY"],
860
+ ];
861
+ for (const [from, to] of aliasPairs) {
862
+ if (Deno.env.get(to)) continue;
863
+ const value = Deno.env.get(from);
864
+ if (!value) continue;
865
+ Deno.env.set(to, value);
839
866
  applied++;
840
867
  }
868
+ return applied;
869
+ }
870
+
871
+ function devStatusRetryConfig(): { attempts: number; delayMs: number } {
872
+ const attemptsRaw = parseInt(
873
+ Deno.env.get("1TUBE_DEV_STATUS_ATTEMPTS") || "",
874
+ 10,
875
+ );
876
+ const delayRaw = parseInt(
877
+ Deno.env.get("1TUBE_DEV_STATUS_RETRY_MS") || "",
878
+ 10,
879
+ );
880
+ return {
881
+ attempts: Number.isFinite(attemptsRaw) && attemptsRaw > 0
882
+ ? attemptsRaw
883
+ : 5,
884
+ delayMs: Number.isFinite(delayRaw) && delayRaw >= 0 ? delayRaw : 1000,
885
+ };
886
+ }
887
+
888
+ async function applyDevDefaults() {
889
+ let applied = applyDevEnvAliases();
890
+
891
+ const skipStatus = (Deno.env.get("1TUBE_DEV_SKIP_SUPABASE_STATUS") || "") ===
892
+ "1";
893
+ const { attempts, delayMs } = devStatusRetryConfig();
894
+
895
+ if (!skipStatus) {
896
+ for (let attempt = 1; attempt <= attempts; attempt++) {
897
+ const missing = missingDevSupabaseKeys();
898
+ if (missing.length === 0) break;
899
+
900
+ if (attempt > 1) {
901
+ console.warn(
902
+ `[1tube] Local Supabase keys still missing (${
903
+ missing.join(", ")
904
+ }); retrying \`supabase status\` (${attempt}/${attempts})…`,
905
+ );
906
+ if (delayMs > 0) {
907
+ await new Promise((resolve) => setTimeout(resolve, delayMs));
908
+ }
909
+ }
910
+
911
+ const statusEnv = await readLocalSupabaseStatusEnv();
912
+ if (Object.keys(statusEnv).length === 0) {
913
+ if (attempt === 1) {
914
+ console.warn(
915
+ "[1tube] Could not read local Supabase keys via `supabase status` " +
916
+ "(CLI missing or stack not ready); will retry…",
917
+ );
918
+ }
919
+ continue;
920
+ }
921
+ applied += applyStatusEnv(statusEnv);
922
+ // Status may only populate PUBLISHABLE/SECRET; re-alias onto ANON/SERVICE.
923
+ applied += applyDevEnvAliases();
924
+ }
925
+ }
841
926
 
842
927
  for (const [key, value] of Object.entries(LOCAL_SUPABASE_DEFAULTS)) {
843
928
  if (!Deno.env.get(key)) {
@@ -848,12 +933,27 @@ async function applyDevDefaults() {
848
933
  if (applied > 0) {
849
934
  console.log(`[1tube] Applied ${applied} dev default(s) (1TUBE_DEV=1)`);
850
935
  }
936
+
937
+ const missing = missingDevSupabaseKeys();
938
+ if (missing.length > 0) {
939
+ console.error(
940
+ `[1tube] FATAL: --dev could not resolve ${missing.join(", ")} after ` +
941
+ `${skipStatus ? "skipping" : `${attempts} attempt(s) at`} ` +
942
+ `\`supabase status\`. ` +
943
+ `Start local Supabase (\`supabase start\`) so status works, or set ` +
944
+ `the missing vars in .env (SUPABASE_ANON_KEY / SUPABASE_SERVICE_ROLE_KEY, ` +
945
+ `or VITE_SUPABASE_PUBLISHABLE_KEY + SUPABASE_SERVICE_ROLE_KEY).`,
946
+ );
947
+ Deno.exit(EXIT_CODES.CONFIG);
948
+ }
851
949
  }
852
950
 
853
951
  async function readLocalSupabaseStatusEnv(): Promise<Record<string, string>> {
854
952
  const runners: Array<{ command: string; args: string[] }> = [
855
953
  { command: "supabase", args: ["status", "-o", "env"] },
856
954
  { command: "bunx", args: ["supabase", "status", "-o", "env"] },
955
+ { command: "bun", args: ["x", "supabase", "status", "-o", "env"] },
956
+ { command: "npx", args: ["--yes", "supabase", "status", "-o", "env"] },
857
957
  ];
858
958
 
859
959
  for (const runner of runners) {
@@ -861,12 +961,17 @@ async function readLocalSupabaseStatusEnv(): Promise<Record<string, string>> {
861
961
  const output = await new Deno.Command(runner.command, {
862
962
  args: runner.args,
863
963
  stdout: "piped",
864
- stderr: "null",
964
+ stderr: "piped",
865
965
  }).output();
866
- if (!output.success) continue;
867
- return parseSupabaseStatusEnv(new TextDecoder().decode(output.stdout));
966
+ const stdout = new TextDecoder().decode(output.stdout);
967
+ const parsed = parseSupabaseStatusEnv(stdout);
968
+ // Accept stdout even on non-zero exit — `supabase status` often warns
969
+ // about stopped optional services while still printing usable keys.
970
+ if (parsed.ANON_KEY || parsed.PUBLISHABLE_KEY || parsed.SERVICE_ROLE_KEY) {
971
+ return parsed;
972
+ }
868
973
  } catch {
869
- // CLI not installed on PATH (or bunx unavailable). Try the next runner.
974
+ // CLI not installed on PATH (or bunx/npx unavailable). Try the next runner.
870
975
  }
871
976
  }
872
977
  return {};