supabase 2.98.2 → 2.99.0-beta.2

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 CHANGED
@@ -1,177 +1,179 @@
1
- # Supabase CLI
1
+ # supabase
2
2
 
3
- [![Coverage Status](https://coveralls.io/repos/github/supabase/cli/badge.svg?branch=develop)](https://coveralls.io/github/supabase/cli?branch=develop) [![Bitbucket Pipelines](https://img.shields.io/bitbucket/pipelines/supabase-cli/setup-cli/master?style=flat-square&label=Bitbucket%20Canary)](https://bitbucket.org/supabase-cli/setup-cli/pipelines) [![Gitlab Pipeline Status](https://img.shields.io/gitlab/pipeline-status/sweatybridge%2Fsetup-cli?label=Gitlab%20Canary)
4
- ](https://gitlab.com/sweatybridge/setup-cli/-/pipelines)
3
+ The TypeScript/Bun Supabase CLI in this repo.
5
4
 
6
- [Supabase](https://supabase.io) is an open source Firebase alternative. We're building the features of Firebase using enterprise-grade open source tools.
5
+ This workspace contains:
7
6
 
8
- This repository contains all the functionality for Supabase CLI.
7
+ - the published `supabase` package
8
+ - the `supabase` binary entrypoint
9
+ - local-development commands backed by `@supabase/stack`
10
+ - login and machine-readable output support
9
11
 
10
- - [x] Running Supabase locally
11
- - [x] Managing database migrations
12
- - [x] Creating and deploying Supabase Functions
13
- - [x] Generating types directly from your database schema
14
- - [x] Making authenticated HTTP requests to [Management API](https://supabase.com/docs/reference/api/introduction)
12
+ ## Status
15
13
 
16
- ## Getting started
14
+ This workspace currently contains the next/V3 CLI shell and the scaffolding for a legacy shell.
17
15
 
18
- ### Install the CLI
16
+ For current migration/parity status, see:
19
17
 
20
- Available via [NPM](https://www.npmjs.com) as dev dependency. To install:
18
+ - [`docs/go-cli-porting-status.md`](/Users/jgoux/Code/supabase/dx-labs/apps/cli/docs/go-cli-porting-status.md)
21
19
 
22
- ```bash
23
- npm i supabase --save-dev
24
- ```
20
+ For the generated command/reference docs, see:
25
21
 
26
- When installing with yarn 4, you need to disable experimental fetch with the following nodejs config.
22
+ - [`docs/go-cli-reference.md`](/Users/jgoux/Code/supabase/dx-labs/apps/cli/docs/go-cli-reference.md)
23
+ - [`docs/supabase-home.md`](/Users/jgoux/Code/supabase/dx-labs/apps/cli/docs/supabase-home.md)
24
+ - [`../../packages/stack/docs/service-versioning.md`](/Users/jgoux/Code/supabase/dx-labs/packages/stack/docs/service-versioning.md)
27
25
 
28
- ```
29
- NODE_OPTIONS=--no-experimental-fetch yarn add supabase
30
- ```
26
+ The README is intentionally brief. Command details should live in the generated docs and the parity tracker above.
31
27
 
32
- > **Note**
33
- For Bun versions below v1.0.17, you must add `supabase` as a [trusted dependency](https://bun.sh/guides/install/trusted) before running `bun add -D supabase`.
28
+ ## Run From Source
34
29
 
35
- <details>
36
- <summary><b>macOS</b></summary>
30
+ From the workspace:
37
31
 
38
- Available via [Homebrew](https://brew.sh). To install:
32
+ ```sh
33
+ cd apps/cli
34
+ pnpm dev:next -- --help
35
+ ```
39
36
 
40
- ```sh
41
- brew install supabase/tap/supabase
42
- ```
37
+ Examples:
43
38
 
44
- To install the beta release channel:
45
-
46
- ```sh
47
- brew install supabase/tap/supabase-beta
48
- brew link --overwrite supabase-beta
49
- ```
50
-
51
- To upgrade:
39
+ ```sh
40
+ pnpm dev:next -- start
41
+ pnpm dev:next -- start --mode docker
42
+ pnpm dev:next -- start --detach
43
+ pnpm dev:next -- status
44
+ pnpm dev:next -- logs
45
+ pnpm dev:next -- login --no-browser
46
+ pnpm dev:legacy -- hello
47
+ ```
52
48
 
53
- ```sh
54
- brew upgrade supabase
55
- ```
56
- </details>
49
+ ### Legacy shell and the Go binary
57
50
 
58
- <details>
59
- <summary><b>Windows</b></summary>
51
+ Phase 0 commands in the legacy shell proxy to the Go CLI binary. To run these commands from source you need `supabase` (the Go CLI) available on your PATH.
60
52
 
61
- Available via [Scoop](https://scoop.sh). To install:
53
+ For convenience, create a shell alias instead of using `pnpm dev:legacy` directly. For example in `.zshrc`:
62
54
 
63
- ```powershell
64
- scoop bucket add supabase https://github.com/supabase/scoop-bucket.git
65
- scoop install supabase
66
- ```
55
+ ```sh
56
+ alias supabase-dev="bun /absolute/path/to/dx-lab/apps/cli/src/legacy/main.ts"
57
+ ```
67
58
 
68
- To upgrade:
59
+ Then Phase 0 commands resolve the Go binary via PATH automatically:
69
60
 
70
- ```powershell
71
- scoop update supabase
72
- ```
73
- </details>
61
+ ```sh
62
+ supabase-dev orgs list # proxied to supabase on PATH
63
+ supabase-dev login # native TypeScript
64
+ ```
74
65
 
75
- <details>
76
- <summary><b>Linux</b></summary>
66
+ You can also point `SUPABASE_GO_BINARY` at a specific binary to skip the PATH lookup:
77
67
 
78
- Available via [Homebrew](https://brew.sh) and Linux packages.
68
+ ```sh
69
+ export SUPABASE_GO_BINARY=/path/to/supabase
70
+ ```
79
71
 
80
- #### via Homebrew
72
+ ## Build
81
73
 
82
- To install:
74
+ There are two separate build paths depending on what you need.
83
75
 
84
- ```sh
85
- brew install supabase/tap/supabase
86
- ```
76
+ ### Source bundles (development)
87
77
 
88
- To upgrade:
78
+ From `apps/cli`:
89
79
 
90
- ```sh
91
- brew upgrade supabase
92
- ```
80
+ ```sh
81
+ pnpm build
82
+ pnpm build:next
83
+ pnpm build:legacy
84
+ pnpm build:shim
85
+ ```
93
86
 
94
- #### via Linux packages
87
+ Output in `dist/`:
95
88
 
96
- Linux packages are provided in [Releases](https://github.com/supabase/cli/releases). To install, download the `.apk`/`.deb`/`.rpm`/`.pkg.tar.zst` file depending on your package manager and run the respective commands.
89
+ - `dist/supabase.js` base shim that routes to the correct platform binary
90
+ - `dist/main-next.js` — next shell bundle
91
+ - `dist/main-legacy.js` — legacy shell bundle
97
92
 
98
- ```sh
99
- sudo apk add --allow-untrusted <...>.apk
100
- ```
93
+ ### Platform releases (Bun single-file executables)
101
94
 
102
- ```sh
103
- sudo dpkg -i <...>.deb
104
- ```
95
+ Used at release time to produce the compiled binaries that go into the platform-specific npm packages:
105
96
 
106
- ```sh
107
- sudo rpm -i <...>.rpm
108
- ```
97
+ ```sh
98
+ # next shell (TS only)
99
+ bun scripts/build.ts --shell next --version X.Y.Z
109
100
 
110
- ```sh
111
- sudo pacman -U <...>.pkg.tar.zst
112
- ```
113
- </details>
101
+ # legacy shell (TS SFE + Go binary for each platform)
102
+ bun scripts/build.ts --shell legacy --version X.Y.Z
103
+ ```
114
104
 
115
- <details>
116
- <summary><b>Other Platforms</b></summary>
105
+ For the legacy shell, this also cross-compiles the Go CLI binary from `apps/cli-go/` and places both binaries in `packages/cli-{platform}/bin/`.
117
106
 
118
- You can also install the CLI via [go modules](https://go.dev/ref/mod#go-install) without the help of package managers.
107
+ See [`docs/binary-distribution.md`](./docs/binary-distribution.md) for a full explanation of the packaging model.
119
108
 
120
- ```sh
121
- go install github.com/supabase/cli@latest
122
- ```
109
+ ## Architecture
123
110
 
124
- Add a symlink to the binary in `$PATH` for easier access:
111
+ The CLI is built on `effect/unstable/cli`.
125
112
 
126
- ```sh
127
- ln -s "$(go env GOPATH)/bin/cli" /usr/bin/supabase
128
- ```
113
+ Important areas:
129
114
 
130
- This works on other non-standard Linux distros.
131
- </details>
115
+ - `src/shared/cli/` for shared runner logic, roots, and global flags
116
+ - `src/next/commands/` for the next/V3 command tree
117
+ - `src/legacy/commands/` for the legacy command tree
118
+ - `src/shared/output/` for text / JSON / NDJSON output policies
119
+ - `src/shared/runtime/` for TTY, stdin, browser, Ink, and process-control services
120
+ - `src/next/auth/` for login-related services
132
121
 
133
- <details>
134
- <summary><b>Community Maintained Packages</b></summary>
122
+ The local stack commands use `@supabase/stack` for lifecycle, daemon transport, status, and logs.
123
+ That stack layer now has an explicit preparation phase, so foreground and detached `start` flows
124
+ can surface `Downloading` before normal runtime states.
135
125
 
136
- Available via [pkgx](https://pkgx.sh/). Package script [here](https://github.com/pkgxdev/pantry/blob/main/projects/supabase.com/cli/package.yml).
137
- To install in your working directory:
126
+ Useful companion docs:
138
127
 
139
- ```bash
140
- pkgx install supabase
141
- ```
128
+ - [`../../packages/stack/docs/architecture.md`](/Users/jgoux/Code/supabase/dx-labs/packages/stack/docs/architecture.md)
129
+ - [`../../packages/stack/docs/detach-mode.md`](/Users/jgoux/Code/supabase/dx-labs/packages/stack/docs/detach-mode.md)
130
+ - [`docs/ui.md`](/Users/jgoux/Code/supabase/dx-labs/apps/cli/docs/ui.md)
142
131
 
143
- Available via [Nixpkgs](https://nixos.org/). Package script [here](https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/tools/supabase-cli/default.nix).
144
- </details>
132
+ ## Development
145
133
 
146
- ### Run the CLI
134
+ From `apps/cli`:
147
135
 
148
- ```bash
149
- supabase bootstrap
136
+ ```sh
137
+ pnpm check:all
138
+ pnpm fix:all
139
+ pnpm test
150
140
  ```
151
141
 
152
- Or using npx:
142
+ Useful subsets:
153
143
 
154
- ```bash
155
- npx supabase bootstrap
144
+ ```sh
145
+ pnpm test:core # unit + integration (no binary required)
146
+ pnpm test:legacy-integration # legacy behavioral tests (requires SUPABASE_GO_BINARY — see CLAUDE.md)
147
+ pnpm test:e2e # end-to-end subprocess tests
156
148
  ```
157
149
 
158
- The bootstrap command will guide you through the process of setting up a Supabase project using one of the [starter](https://github.com/supabase-community/supabase-samples/blob/main/samples.json) templates.
150
+ ## Publishing
159
151
 
160
- ## Docs
152
+ This workspace publishes the main `supabase` package.
161
153
 
162
- Command & config reference can be found [here](https://supabase.com/docs/reference/cli/about).
154
+ Release channels are split by npm dist-tag:
163
155
 
164
- ## Breaking changes
156
+ - stable publishes the legacy shell to `latest`
157
+ - alpha publishes the next/V3 shell to `alpha`
165
158
 
166
- We follow semantic versioning for changes that directly impact CLI commands, flags, and configurations.
159
+ The release automation is split across:
167
160
 
168
- However, due to dependencies on other service images, we cannot guarantee that schema migrations, seed.sql, and generated types will always work for the same CLI major version. If you need such guarantees, we encourage you to pin a specific version of CLI in package.json.
161
+ - [`.github/workflows/release-stable.yml`](../../.github/workflows/release-stable.yml)
162
+ - [`.github/workflows/release-alpha.yml`](../../.github/workflows/release-alpha.yml)
169
163
 
170
- ## Developing
164
+ ### Platform packages
171
165
 
172
- To run from source:
166
+ Platform-specific packages live under:
173
167
 
174
- ```sh
175
- # Go >= 1.22
176
- go run . help
177
- ```
168
+ - `packages/cli-darwin-*`
169
+ - `packages/cli-linux-*`
170
+ - `packages/cli-windows-*`
171
+
172
+ Each platform package ships two binaries for the legacy stable channel:
173
+
174
+ - `bin/supabase` — the compiled TypeScript SFE (Bun single-file executable)
175
+ - `bin/supabase-go` — the compiled Go CLI binary, used by Phase 0 proxy commands
176
+
177
+ The Go binary is compiled from `apps/cli-go/` at release time. Run `pnpm repos:install` after a fresh clone to make that source available.
178
+
179
+ See [`docs/binary-distribution.md`](./docs/binary-distribution.md) for the full packaging model.
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/shared/cli/bin.ts
4
+ import { execFileSync } from "node:child_process";
5
+ import { createRequire } from "node:module";
6
+ import os from "node:os";
7
+ import path from "node:path";
8
+ import process from "node:process";
9
+ var PLATFORMS = {
10
+ darwin: { arm64: ["darwin-arm64"], x64: ["darwin-x64"] },
11
+ linux: {
12
+ arm64: ["linux-arm64", "linux-arm64-musl"],
13
+ x64: ["linux-x64", "linux-x64-musl"]
14
+ },
15
+ win32: { arm64: ["windows-arm64"], x64: ["windows-x64"] }
16
+ };
17
+ var platformMap = PLATFORMS[process.platform];
18
+ if (!platformMap)
19
+ throw new Error(`Unsupported platform: ${process.platform}`);
20
+ var candidates = platformMap[os.arch()];
21
+ if (!candidates)
22
+ throw new Error(`Unsupported architecture: ${os.arch()} on ${process.platform}`);
23
+ var ext = process.platform === "win32" ? ".exe" : "";
24
+ var require2 = createRequire(import.meta.url);
25
+ var binPath;
26
+ for (const suffix of candidates) {
27
+ try {
28
+ const pkgPath = path.dirname(require2.resolve(`@supabase/cli-${suffix}/package.json`));
29
+ binPath = path.join(pkgPath, "bin", `supabase${ext}`);
30
+ break;
31
+ } catch {}
32
+ }
33
+ if (!binPath) {
34
+ throw new Error(`No matching Supabase CLI binary package found for ${process.platform}-${os.arch()}`);
35
+ }
36
+ try {
37
+ execFileSync(binPath, process.argv.slice(2), { stdio: "inherit" });
38
+ } catch (e) {
39
+ if (e && typeof e === "object" && "status" in e && typeof e.status === "number")
40
+ process.exit(e.status);
41
+ throw e;
42
+ }
package/package.json CHANGED
@@ -1,45 +1,133 @@
1
1
  {
2
2
  "name": "supabase",
3
- "version": "2.98.2",
3
+ "version": "2.99.0-beta.2",
4
+ "private": false,
4
5
  "description": "Supabase CLI",
5
- "repository": "supabase/cli",
6
- "homepage": "https://supabase.com/docs/reference/cli",
7
- "bugs": "https://github.com/supabase/cli/issues",
6
+ "homepage": "https://github.com/supabase/cli#readme",
7
+ "bugs": {
8
+ "url": "https://github.com/supabase/cli/issues"
9
+ },
8
10
  "license": "MIT",
9
- "author": "Supabase",
10
- "type": "module",
11
- "engines": {
12
- "npm": ">=8"
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "https://github.com/supabase/cli.git",
14
+ "directory": "apps/cli"
15
+ },
16
+ "bin": {
17
+ "supabase": "dist/supabase.js"
13
18
  },
14
19
  "files": [
15
- "scripts"
20
+ "dist/supabase.js"
16
21
  ],
17
- "scripts": {
18
- "postinstall": "node scripts/postinstall.js"
19
- },
20
- "bin": {
21
- "supabase": "bin/supabase"
22
+ "type": "module",
23
+ "publishConfig": {
24
+ "access": "public"
22
25
  },
23
26
  "dependencies": {
24
- "bin-links": "^6.0.0",
25
- "https-proxy-agent": "^9.0.0",
26
- "node-fetch": "^3.3.2",
27
- "tar": "7.5.13"
27
+ "@clack/prompts": "^1.2.0",
28
+ "@effect/atom-react": "4.0.0-beta.54",
29
+ "@effect/platform-bun": "^4.0.0-beta.43",
30
+ "@napi-rs/keyring": "^1.1.2",
31
+ "@vercel/detect-agent": "^1.2.3",
32
+ "effect": "^4.0.0-beta.43",
33
+ "ink": "^7.0.1",
34
+ "ink-spinner": "^5.0.0",
35
+ "posthog-node": "^5.29.4",
36
+ "react": "^19.2.5"
37
+ },
38
+ "devDependencies": {
39
+ "@effect/vitest": "^4.0.0-beta.43",
40
+ "@tsconfig/bun": "^1.0.10",
41
+ "@types/bun": "^1.3.12",
42
+ "@types/react": "^19.2.14",
43
+ "@typescript/native-preview": "7.0.0-dev.20260422.1",
44
+ "@vitest/coverage-istanbul": "^4.1.5",
45
+ "knip": "^6.6.1",
46
+ "oxfmt": "^0.46.0",
47
+ "oxlint": "^1.61.0",
48
+ "oxlint-tsgolint": "^0.21.1",
49
+ "react-devtools-core": "^7.0.1",
50
+ "vitest": "^4.1.5",
51
+ "@supabase/api": "0.1.0",
52
+ "@supabase/config": "0.1.0",
53
+ "@supabase/stack": "0.1.0"
54
+ },
55
+ "optionalDependencies": {
56
+ "@supabase/cli-darwin-x64": "2.99.0-beta.2",
57
+ "@supabase/cli-darwin-arm64": "2.99.0-beta.2",
58
+ "@supabase/cli-linux-arm64": "2.99.0-beta.2",
59
+ "@supabase/cli-linux-arm64-musl": "2.99.0-beta.2",
60
+ "@supabase/cli-windows-arm64": "2.99.0-beta.2",
61
+ "@supabase/cli-linux-x64": "2.99.0-beta.2",
62
+ "@supabase/cli-linux-x64-musl": "2.99.0-beta.2",
63
+ "@supabase/cli-windows-x64": "2.99.0-beta.2"
28
64
  },
29
65
  "release": {
30
66
  "branches": [
31
- {
32
- "name": "+([0-9])?(.{+([0-9]),x}).x",
33
- "channel": "hotfix"
34
- },
67
+ "main",
35
68
  {
36
69
  "name": "develop",
37
- "channel": "latest"
70
+ "prerelease": "beta"
38
71
  }
39
72
  ],
40
73
  "plugins": [
41
- "@semantic-release/commit-analyzer",
42
- "@semantic-release/git"
74
+ "@semantic-release/commit-analyzer"
43
75
  ]
76
+ },
77
+ "knip": {
78
+ "entry": [
79
+ "src/shared/cli/bin.ts",
80
+ "src/**/*.test.ts",
81
+ "src/**/*.e2e.test.ts"
82
+ ],
83
+ "ignore": [
84
+ "scripts/*.ts",
85
+ "tests/**/*.ts"
86
+ ],
87
+ "ignoreBinaries": [
88
+ "nx"
89
+ ],
90
+ "ignoreDependencies": [
91
+ "@typescript/native-preview",
92
+ "oxfmt",
93
+ "oxlint",
94
+ "oxlint-tsgolint"
95
+ ]
96
+ },
97
+ "nx": {
98
+ "targets": {
99
+ "build": {
100
+ "outputs": [
101
+ "{projectRoot}/dist"
102
+ ],
103
+ "dependsOn": [
104
+ {
105
+ "projects": [
106
+ "cli-go"
107
+ ],
108
+ "target": "build"
109
+ }
110
+ ]
111
+ },
112
+ "test:smoke": {
113
+ "cache": false
114
+ }
115
+ },
116
+ "implicitDependencies": [
117
+ "cli-go"
118
+ ]
119
+ },
120
+ "scripts": {
121
+ "build": "pnpm build:next && pnpm build:legacy && pnpm build:shim",
122
+ "build:next": "bun build src/next/main.ts --outfile dist/main-next.js --target bun --packages external",
123
+ "build:legacy": "bun build src/legacy/main.ts --outfile dist/main-legacy.js --target bun --packages external",
124
+ "build:shim": "bun build src/shared/cli/bin.ts --outfile dist/supabase.js --target node",
125
+ "dev:next": "pnpm exec bun src/next/main.ts",
126
+ "dev:legacy": "pnpm exec bun src/legacy/main.ts",
127
+ "test": "nx run-many -t test:core test:e2e --projects=$npm_package_name",
128
+ "test:core": "nx run-many -t test:unit test:integration --projects=$npm_package_name --coverage.enabled",
129
+ "test:smoke": "bun run tests/smoke-test.ts",
130
+ "check:all": "nx run-many -t types:check lint:check fmt:check knip:check --projects=$npm_package_name",
131
+ "fix:all": "nx run-many -t lint:fix fmt:fix knip:fix --projects=$npm_package_name"
44
132
  }
45
- }
133
+ }
package/LICENSE DELETED
@@ -1,21 +0,0 @@
1
- MIT License
2
-
3
- Copyright (c) 2021 Supabase, Inc. and contributors
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
@@ -1,180 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- // Ref 1: https://github.com/sanathkr/go-npm
4
- // Ref 2: https://medium.com/xendit-engineering/how-we-repurposed-npm-to-publish-and-distribute-our-go-binaries-for-internal-cli-23981b80911b
5
- "use strict";
6
-
7
- import binLinks from "bin-links";
8
- import { createHash } from "crypto";
9
- import fs from "fs";
10
- import fetch from "node-fetch";
11
- import { Agent } from "https";
12
- import { HttpsProxyAgent } from "https-proxy-agent";
13
- import path from "path";
14
- import { extract } from "tar";
15
- import zlib from "zlib";
16
-
17
- // Mapping from Node's `process.arch` to Golang's `$GOARCH`
18
- const ARCH_MAPPING = {
19
- x64: "amd64",
20
- arm64: "arm64",
21
- };
22
-
23
- // Mapping between Node's `process.platform` to Golang's
24
- const PLATFORM_MAPPING = {
25
- darwin: "darwin",
26
- linux: "linux",
27
- win32: "windows",
28
- };
29
-
30
- const arch = ARCH_MAPPING[process.arch];
31
- const platform = PLATFORM_MAPPING[process.platform];
32
-
33
- // TODO: import pkg from "../package.json" assert { type: "json" };
34
- const readPackageJson = async () => {
35
- const contents = await fs.promises.readFile("package.json");
36
- return JSON.parse(contents);
37
- };
38
-
39
- // Build the download url from package.json
40
- const getDownloadUrl = (packageJson) => {
41
- const pkgName = packageJson.name;
42
- const version = packageJson.version;
43
- const repo = packageJson.repository;
44
- const url = `https://github.com/${repo}/releases/download/v${version}/${pkgName}_${platform}_${arch}.tar.gz`;
45
- return url;
46
- };
47
-
48
- const fetchAndParseCheckSumFile = async (packageJson, agent) => {
49
- const version = packageJson.version;
50
- const pkgName = packageJson.name;
51
- const repo = packageJson.repository;
52
- const checksumFileUrl = `https://github.com/${repo}/releases/download/v${version}/${pkgName}_${version}_checksums.txt`;
53
-
54
- // Fetch the checksum file
55
- console.info("Downloading", checksumFileUrl);
56
- const response = await fetch(checksumFileUrl, { agent });
57
- if (response.ok) {
58
- const checkSumContent = await response.text();
59
- const lines = checkSumContent.split("\n");
60
-
61
- const checksums = {};
62
- for (const line of lines) {
63
- const [checksum, packageName] = line.split(/\s+/);
64
- checksums[packageName] = checksum;
65
- }
66
-
67
- return checksums;
68
- } else {
69
- console.error(
70
- "Could not fetch checksum file",
71
- response.status,
72
- response.statusText
73
- );
74
- }
75
- };
76
-
77
- const errGlobal = `Installing Supabase CLI as a global module is not supported.
78
- Please use one of the supported package managers: https://github.com/supabase/cli#install-the-cli
79
- `;
80
- const errChecksum = "Checksum mismatch. Downloaded data might be corrupted.";
81
- const errUnsupported = `Installation is not supported for ${process.platform} ${process.arch}`;
82
-
83
- /**
84
- * Reads the configuration from application's package.json,
85
- * downloads the binary from package url and stores at
86
- * ./bin in the package's root.
87
- *
88
- * See: https://docs.npmjs.com/files/package.json#bin
89
- */
90
- async function main() {
91
- const yarnGlobal = JSON.parse(
92
- process.env.npm_config_argv || "{}"
93
- ).original?.includes("global");
94
- if (process.env.npm_config_global || yarnGlobal) {
95
- throw errGlobal;
96
- }
97
- if (!arch || !platform) {
98
- throw errUnsupported;
99
- }
100
-
101
- // Read from package.json and prepare for the installation.
102
- const pkg = await readPackageJson();
103
- if (platform === "windows") {
104
- // Update bin path in package.json
105
- pkg.bin[pkg.name] += ".exe";
106
- }
107
-
108
- // Prepare the installation path by creating the directory if it doesn't exist.
109
- const binPath = pkg.bin[pkg.name];
110
- const binDir = path.dirname(binPath);
111
- await fs.promises.mkdir(binDir, { recursive: true });
112
-
113
- // Create the agent that will be used for all the fetch requests later.
114
- const proxyUrl =
115
- process.env.npm_config_https_proxy ||
116
- process.env.npm_config_http_proxy ||
117
- process.env.npm_config_proxy;
118
- // Keeps the TCP connection alive when sending multiple requests
119
- // Ref: https://github.com/node-fetch/node-fetch/issues/1735
120
- const agent = proxyUrl
121
- ? new HttpsProxyAgent(proxyUrl, { keepAlive: true })
122
- : new Agent({ keepAlive: true });
123
-
124
- // First, fetch the checksum map.
125
- const checksumMap = await fetchAndParseCheckSumFile(pkg, agent);
126
-
127
- // Then, download the binary.
128
- const url = getDownloadUrl(pkg);
129
- console.info("Downloading", url);
130
- const resp = await fetch(url, { agent });
131
- const hash = createHash("sha256");
132
- const pkgNameWithPlatform = `${pkg.name}_${platform}_${arch}.tar.gz`;
133
-
134
- // Then, decompress the binary -- we will first Un-GZip, then we will untar.
135
- const ungz = zlib.createGunzip();
136
- const binName = path.basename(binPath);
137
- const untar = extract({ cwd: binDir }, [binName]);
138
-
139
- // Update the hash with the binary data as it's being downloaded.
140
- resp.body
141
- .on("data", (chunk) => {
142
- hash.update(chunk);
143
- })
144
- // Pipe the data to the ungz stream.
145
- .pipe(ungz);
146
-
147
- // After the ungz stream has ended, verify the checksum.
148
- ungz
149
- .on("end", () => {
150
- const expectedChecksum = checksumMap?.[pkgNameWithPlatform];
151
- // Skip verification if we can't find the file checksum
152
- if (!expectedChecksum) {
153
- console.warn("Skipping checksum verification");
154
- return;
155
- }
156
- const calculatedChecksum = hash.digest("hex");
157
- if (calculatedChecksum !== expectedChecksum) {
158
- throw errChecksum;
159
- }
160
- console.info("Checksum verified.");
161
- })
162
- // Pipe the data to the untar stream.
163
- .pipe(untar);
164
-
165
- // Wait for the untar stream to finish.
166
- await new Promise((resolve, reject) => {
167
- untar.on("error", reject);
168
- untar.on("end", () => resolve());
169
- });
170
-
171
- // Link the binaries in postinstall to support yarn
172
- await binLinks({
173
- path: path.resolve("."),
174
- pkg: { ...pkg, bin: { [pkg.name]: binPath } },
175
- });
176
-
177
- console.info("Installed Supabase CLI successfully");
178
- }
179
-
180
- await main();