seamless-cli 0.2.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/LICENSE +79 -0
- package/LICENSE.md +26 -0
- package/README.md +238 -0
- package/dist/commands/bootstrapAdmin.js +96 -0
- package/dist/commands/bootstrapAdmin.js.map +1 -0
- package/dist/commands/check.js +92 -0
- package/dist/commands/check.js.map +1 -0
- package/dist/commands/contribute.js +121 -0
- package/dist/commands/contribute.js.map +1 -0
- package/dist/commands/deploy.js +190 -0
- package/dist/commands/deploy.js.map +1 -0
- package/dist/commands/destroy.js +122 -0
- package/dist/commands/destroy.js.map +1 -0
- package/dist/commands/help.js +103 -0
- package/dist/commands/help.js.map +1 -0
- package/dist/commands/init.js +73 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/contributor/catalog.js +129 -0
- package/dist/contributor/catalog.js.map +1 -0
- package/dist/contributor/workspace.js +551 -0
- package/dist/contributor/workspace.js.map +1 -0
- package/dist/core/acm.js +24 -0
- package/dist/core/acm.js.map +1 -0
- package/dist/core/aws.js +374 -0
- package/dist/core/aws.js.map +1 -0
- package/dist/core/bootstrapSecret.js +31 -0
- package/dist/core/bootstrapSecret.js.map +1 -0
- package/dist/core/buildPush.js +91 -0
- package/dist/core/buildPush.js.map +1 -0
- package/dist/core/configure.js +25 -0
- package/dist/core/configure.js.map +1 -0
- package/dist/core/deployConfig.js +66 -0
- package/dist/core/deployConfig.js.map +1 -0
- package/dist/core/deployManifest.js +163 -0
- package/dist/core/deployManifest.js.map +1 -0
- package/dist/core/deploySecrets.js +31 -0
- package/dist/core/deploySecrets.js.map +1 -0
- package/dist/core/destroy.js +38 -0
- package/dist/core/destroy.js.map +1 -0
- package/dist/core/env.js +35 -0
- package/dist/core/env.js.map +1 -0
- package/dist/core/envDiscovery.js +153 -0
- package/dist/core/envDiscovery.js.map +1 -0
- package/dist/core/envRegistry.js +76 -0
- package/dist/core/envRegistry.js.map +1 -0
- package/dist/core/exec.js +17 -0
- package/dist/core/exec.js.map +1 -0
- package/dist/core/fetch.js +9 -0
- package/dist/core/fetch.js.map +1 -0
- package/dist/core/health.js +11 -0
- package/dist/core/health.js.map +1 -0
- package/dist/core/help.js +75 -0
- package/dist/core/help.js.map +1 -0
- package/dist/core/inspect.js +15 -0
- package/dist/core/inspect.js.map +1 -0
- package/dist/core/jwks.js +19 -0
- package/dist/core/jwks.js.map +1 -0
- package/dist/core/output.js +94 -0
- package/dist/core/output.js.map +1 -0
- package/dist/core/packageManager.js +10 -0
- package/dist/core/packageManager.js.map +1 -0
- package/dist/core/paths.js +7 -0
- package/dist/core/paths.js.map +1 -0
- package/dist/core/preReqs.js +14 -0
- package/dist/core/preReqs.js.map +1 -0
- package/dist/core/secrets.js +8 -0
- package/dist/core/secrets.js.map +1 -0
- package/dist/core/terraform.js +34 -0
- package/dist/core/terraform.js.map +1 -0
- package/dist/core/tfVars.js +69 -0
- package/dist/core/tfVars.js.map +1 -0
- package/dist/generators/admin/admin.js +2 -0
- package/dist/generators/admin/admin.js.map +1 -0
- package/dist/generators/auth/auth.js +47 -0
- package/dist/generators/auth/auth.js.map +1 -0
- package/dist/generators/backend/express.js +13 -0
- package/dist/generators/backend/express.js.map +1 -0
- package/dist/generators/config/config.js +43 -0
- package/dist/generators/config/config.js.map +1 -0
- package/dist/generators/deploy/aws/dev/files.js +36 -0
- package/dist/generators/deploy/aws/dev/files.js.map +1 -0
- package/dist/generators/deploy/aws/dev/template.js +1240 -0
- package/dist/generators/deploy/aws/dev/template.js.map +1 -0
- package/dist/generators/docker/docker.js +263 -0
- package/dist/generators/docker/docker.js.map +1 -0
- package/dist/generators/frontend/react.js +13 -0
- package/dist/generators/frontend/react.js.map +1 -0
- package/dist/index.js +43 -0
- package/dist/index.js.map +1 -0
- package/dist/prompts/contributeSetup.js +39 -0
- package/dist/prompts/contributeSetup.js.map +1 -0
- package/dist/prompts/deploySetup.js +244 -0
- package/dist/prompts/deploySetup.js.map +1 -0
- package/dist/prompts/projectSetup.js +73 -0
- package/dist/prompts/projectSetup.js.map +1 -0
- package/dist/utils/repoUtils.js +23 -0
- package/dist/utils/repoUtils.js.map +1 -0
- package/dist/utils/writeEnv.js +9 -0
- package/dist/utils/writeEnv.js.map +1 -0
- package/package.json +43 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
GNU AFFERO GENERAL PUBLIC LICENSE
|
|
2
|
+
Version 3, 19 November 2007
|
|
3
|
+
|
|
4
|
+
Copyright (C) 2007 Free Software Foundation, Inc.
|
|
5
|
+
<https://fsf.org/>
|
|
6
|
+
Everyone is permitted to copy and distribute verbatim copies
|
|
7
|
+
of this license document, but changing it is not allowed.
|
|
8
|
+
|
|
9
|
+
This license is identical to the GNU General Public License, except that it also
|
|
10
|
+
ensures that software running as a network service makes its source code
|
|
11
|
+
available to users.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
TERMS AND CONDITIONS
|
|
16
|
+
|
|
17
|
+
0. Definitions.
|
|
18
|
+
|
|
19
|
+
“This License” refers to version 3 of the GNU Affero General Public License.
|
|
20
|
+
|
|
21
|
+
“Copyright” also means copyright-like laws that apply to other kinds of works,
|
|
22
|
+
such as semiconductor masks.
|
|
23
|
+
|
|
24
|
+
The “Program” refers to any copyrightable work licensed under this License.
|
|
25
|
+
Each licensee is addressed as “you”.
|
|
26
|
+
|
|
27
|
+
To “modify” a work means to copy from or adapt all or part of the work in a
|
|
28
|
+
fashion requiring copyright permission, other than the making of an exact copy.
|
|
29
|
+
|
|
30
|
+
To “propagate” a work means to do anything with it that, without permission,
|
|
31
|
+
would make you directly or secondarily liable for infringement under applicable
|
|
32
|
+
copyright law, except executing it on a computer or modifying a private copy.
|
|
33
|
+
|
|
34
|
+
To “convey” a work means any kind of propagation that enables other parties to
|
|
35
|
+
make or receive copies.
|
|
36
|
+
|
|
37
|
+
An interactive user interface displays “Appropriate Legal Notices” to the extent
|
|
38
|
+
that it includes a convenient and prominently visible feature that displays an
|
|
39
|
+
appropriate copyright notice, and tells the user that there is no warranty for
|
|
40
|
+
the work (except to the extent that warranties are provided), that licensees may
|
|
41
|
+
convey the work under this License, and how to view a copy of this License.
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
13. Remote Network Interaction; Use with the GNU General Public License.
|
|
46
|
+
|
|
47
|
+
Notwithstanding any other provision of this License, if you modify the Program,
|
|
48
|
+
your modified version must prominently offer all users interacting with it
|
|
49
|
+
remotely through a computer network an opportunity to receive the Corresponding
|
|
50
|
+
Source of your version by providing access to the Corresponding Source from a
|
|
51
|
+
network server at no charge, through some standard or customary means of
|
|
52
|
+
facilitating copying of software.
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
15. Disclaimer of Warranty.
|
|
57
|
+
|
|
58
|
+
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
|
59
|
+
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER
|
|
60
|
+
PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER
|
|
61
|
+
EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
62
|
+
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
16. Limitation of Liability.
|
|
67
|
+
|
|
68
|
+
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY
|
|
69
|
+
COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS
|
|
70
|
+
PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL,
|
|
71
|
+
INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE
|
|
72
|
+
THE PROGRAM.
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
END OF TERMS AND CONDITIONS
|
|
77
|
+
|
|
78
|
+
You should have received a copy of the GNU Affero General Public License along
|
|
79
|
+
with this program. If not, see <https://www.gnu.org/licenses/>.
|
package/LICENSE.md
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# License
|
|
2
|
+
|
|
3
|
+
Seamless CLI ("seamless-cli") is licensed under the **GNU Affero General Public License v3.0 (AGPL-3.0-only)**.
|
|
4
|
+
|
|
5
|
+
- SPDX: `AGPL-3.0-only`
|
|
6
|
+
|
|
7
|
+
## What this means (high level)
|
|
8
|
+
|
|
9
|
+
- You are free to **use**, **modify**, and **self-host** this software.
|
|
10
|
+
- If you **modify** this software and **run it as a network service** (for example, hosting it for others to use), you must **make the complete corresponding source code of your modified version available** to users of that service, under the AGPL.
|
|
11
|
+
|
|
12
|
+
This summary is not legal advice and does not replace the license text.
|
|
13
|
+
|
|
14
|
+
## Full license text
|
|
15
|
+
|
|
16
|
+
The full license text is available here:
|
|
17
|
+
|
|
18
|
+
- https://www.gnu.org/licenses/agpl-3.0.html
|
|
19
|
+
|
|
20
|
+
You should include a copy of the AGPLv3 license in your distribution. If this repository does not contain the full license text yet, add it as `LICENSE` or `LICENSE.txt` (recommended), and keep this `LICENSE.md` as the human-friendly summary.
|
|
21
|
+
|
|
22
|
+
## Commercial licensing
|
|
23
|
+
|
|
24
|
+
If you would like to embed Seamless Auth API into a proprietary product, redistribute it under different terms, or offer it as a managed service without AGPL obligations, commercial licensing may be available.
|
|
25
|
+
|
|
26
|
+
Contact: support@seamlessauth.com
|
package/README.md
ADDED
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
# Seamless CLI
|
|
2
|
+
|
|
3
|
+
[](LICENSE)
|
|
4
|
+
[](https://www.npmjs.com/package/seamless-cli)
|
|
5
|
+
|
|
6
|
+
Seamless CLI is a command-line tool for bootstrapping applications with Seamless Auth, an open source, passwordless authentication system.
|
|
7
|
+
|
|
8
|
+
It guides you through creating a fully working authentication stack with a web app, API, and auth server that are already connected and ready to run.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Getting started
|
|
13
|
+
|
|
14
|
+
Run the CLI with `npx`:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npx seamless-cli init my-app
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Or run it in your current directory:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npx seamless-cli init
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
You’ll be guided through a short setup process where you can choose:
|
|
27
|
+
|
|
28
|
+
- Whether to create a web application
|
|
29
|
+
- Whether to create an API server
|
|
30
|
+
- How to run the auth server (local or Docker)
|
|
31
|
+
- Whether to run everything with Docker
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## What gets created
|
|
36
|
+
|
|
37
|
+
Depending on your selections, the CLI generates a project like this:
|
|
38
|
+
|
|
39
|
+
```text
|
|
40
|
+
my-app/
|
|
41
|
+
├─ auth/ # Seamless Auth server (optional)
|
|
42
|
+
├─ web/ # React web application (optional)
|
|
43
|
+
├─ api/ # Express API server (optional)
|
|
44
|
+
├─ docker-compose.yml (optional)
|
|
45
|
+
└─ README.md
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
All services are preconfigured to work together.
|
|
49
|
+
|
|
50
|
+
- Web calls the API
|
|
51
|
+
- API communicates with the auth server
|
|
52
|
+
- Auth manages sessions and tokens
|
|
53
|
+
|
|
54
|
+
No manual wiring is required.
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Running your project
|
|
59
|
+
|
|
60
|
+
### Option 1: Docker
|
|
61
|
+
|
|
62
|
+
If you choose Docker during setup:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
docker compose up
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
This starts:
|
|
69
|
+
|
|
70
|
+
- PostgreSQL
|
|
71
|
+
- Auth server
|
|
72
|
+
- API server
|
|
73
|
+
- Web app
|
|
74
|
+
|
|
75
|
+
All services are configured to communicate correctly inside the container network.
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
### Option 2: Local development
|
|
80
|
+
|
|
81
|
+
If you choose to run locally:
|
|
82
|
+
|
|
83
|
+
#### 1. Start PostgreSQL
|
|
84
|
+
|
|
85
|
+
Make sure you have a local PostgreSQL instance running on port `5432`.
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
#### 2. Start the auth server
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
cd auth
|
|
93
|
+
npm install
|
|
94
|
+
|
|
95
|
+
npm run db:create
|
|
96
|
+
npm run db:migrate
|
|
97
|
+
|
|
98
|
+
npm run dev
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
#### 3. Start the API
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
cd api
|
|
107
|
+
npm install
|
|
108
|
+
npm run dev
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
#### 4. Start the web app
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
cd web
|
|
117
|
+
npm install
|
|
118
|
+
npm run dev
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
## What is configured for you
|
|
124
|
+
|
|
125
|
+
Seamless CLI handles the parts that are usually difficult to get right:
|
|
126
|
+
|
|
127
|
+
- Shared API service tokens
|
|
128
|
+
- JWT signing configuration
|
|
129
|
+
- JWKS key generation for production mode
|
|
130
|
+
- Cross-service environment variables
|
|
131
|
+
- CORS and cookie-based session handling
|
|
132
|
+
|
|
133
|
+
Everything is aligned across services so the system works immediately after setup.
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
## Included projects
|
|
138
|
+
|
|
139
|
+
Seamless CLI pulls from the following repositories:
|
|
140
|
+
|
|
141
|
+
- Seamless Auth API
|
|
142
|
+
[https://github.com/fells-code/seamless-auth-api](https://github.com/fells-code/seamless-auth-api)
|
|
143
|
+
|
|
144
|
+
- Seamless Auth React Starter
|
|
145
|
+
[https://github.com/fells-code/seamless-auth-starter-react](https://github.com/fells-code/seamless-auth-starter-react)
|
|
146
|
+
|
|
147
|
+
- Seamless Auth API Starter
|
|
148
|
+
[https://github.com/fells-code/seamless-auth-starter-express](https://github.com/fells-code/seamless-auth-starter-express)
|
|
149
|
+
|
|
150
|
+
Each project can be used independently, but the CLI connects them into a working system.
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## Documentation
|
|
155
|
+
|
|
156
|
+
Full documentation is available at:
|
|
157
|
+
|
|
158
|
+
[https://docs.seamlessauth.com](https://docs.seamlessauth.com)
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Philosophy
|
|
163
|
+
|
|
164
|
+
Seamless Auth is built around a few principles:
|
|
165
|
+
|
|
166
|
+
- Passwordless authentication only
|
|
167
|
+
- No redirects or third-party auth providers
|
|
168
|
+
- Self-hosted by default
|
|
169
|
+
- Production-shaped local development
|
|
170
|
+
- Explicit configuration over hidden behavior
|
|
171
|
+
|
|
172
|
+
Seamless CLI exists to make this setup fast and repeatable.
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## Requirements
|
|
177
|
+
|
|
178
|
+
- Node.js 18 or newer
|
|
179
|
+
- npm or pnpm
|
|
180
|
+
- Docker (optional)
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
## Testing local CLI changes
|
|
185
|
+
|
|
186
|
+
From the repository root, build the CLI and link the local package:
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
npm install
|
|
190
|
+
npm run build
|
|
191
|
+
npm link
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Then run the linked command:
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
seamless --version
|
|
198
|
+
seamless --help
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
When you are done testing, remove the global link:
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
npm unlink -g seamless-cli
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
To smoke test the package artifact before publishing:
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
npm run build
|
|
211
|
+
TARBALL=$(npm pack --pack-destination /tmp)
|
|
212
|
+
TEST_DIR=$(mktemp -d)
|
|
213
|
+
|
|
214
|
+
cd "$TEST_DIR"
|
|
215
|
+
npm install "/tmp/$TARBALL"
|
|
216
|
+
npm exec -- seamless --version
|
|
217
|
+
npm exec -- seamless --help
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
If npm cache permissions block local testing, use a writable temporary cache:
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
npm --cache /tmp/npm-cache exec -- seamless --version
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
## License
|
|
229
|
+
|
|
230
|
+
AGPL-3.0-only © 2026 Fells Code LLC
|
|
231
|
+
|
|
232
|
+
This license ensures:
|
|
233
|
+
|
|
234
|
+
- transparency of security-critical code
|
|
235
|
+
- freedom to self-host and modify
|
|
236
|
+
- sustainability of the managed service offering
|
|
237
|
+
|
|
238
|
+
See `LICENSE` for details.
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { intro, outro, text, confirm, spinner } from "@clack/prompts";
|
|
4
|
+
import kleur from "kleur";
|
|
5
|
+
import { resolveBootstrapSecret } from "../core/bootstrapSecret.js";
|
|
6
|
+
function loadConfig() {
|
|
7
|
+
const configPath = path.join(process.cwd(), "seamless.config.json");
|
|
8
|
+
if (!fs.existsSync(configPath)) {
|
|
9
|
+
throw new Error("No seamless.config.json found. Run init first.");
|
|
10
|
+
}
|
|
11
|
+
return JSON.parse(fs.readFileSync(configPath, "utf-8"));
|
|
12
|
+
}
|
|
13
|
+
export async function runBootstrapAdmin(emailArg) {
|
|
14
|
+
intro("Seamless Auth Bootstrap");
|
|
15
|
+
const config = loadConfig();
|
|
16
|
+
let email = emailArg;
|
|
17
|
+
if (!email) {
|
|
18
|
+
email = (await text({
|
|
19
|
+
message: "Admin email address",
|
|
20
|
+
placeholder: "admin@example.com",
|
|
21
|
+
validate: (value) => {
|
|
22
|
+
if (!value || !value.includes("@")) {
|
|
23
|
+
return "Enter a valid email address";
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
}));
|
|
27
|
+
}
|
|
28
|
+
const proceed = await confirm({
|
|
29
|
+
message: "Create bootstrap admin invite?",
|
|
30
|
+
initialValue: true,
|
|
31
|
+
});
|
|
32
|
+
if (!proceed) {
|
|
33
|
+
outro("Cancelled.");
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
let apiUrl = process.env.SEAMLESS_API_URL;
|
|
37
|
+
if (!apiUrl) {
|
|
38
|
+
apiUrl = "http://localhost:3000";
|
|
39
|
+
}
|
|
40
|
+
let secret = resolveBootstrapSecret();
|
|
41
|
+
if (secret) {
|
|
42
|
+
console.log(kleur.gray("Using bootstrap secret from local environment"));
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
console.log("");
|
|
46
|
+
console.log(kleur.yellow("No bootstrap secret detected automatically."));
|
|
47
|
+
console.log("This may happen if the project is not initialized locally or running in production.");
|
|
48
|
+
secret = (await text({
|
|
49
|
+
message: "Bootstrap secret",
|
|
50
|
+
placeholder: "Enter your bootstrap secret",
|
|
51
|
+
validate: (value) => {
|
|
52
|
+
if (!value)
|
|
53
|
+
return "Bootstrap secret is required";
|
|
54
|
+
},
|
|
55
|
+
}));
|
|
56
|
+
}
|
|
57
|
+
const s = spinner();
|
|
58
|
+
s.start("Creating bootstrap invite...");
|
|
59
|
+
try {
|
|
60
|
+
const res = await fetch(`${apiUrl}/auth/internal/bootstrap/admin-invite`, {
|
|
61
|
+
method: "POST",
|
|
62
|
+
headers: {
|
|
63
|
+
"Content-Type": "application/json",
|
|
64
|
+
Authorization: `Bearer ${secret}`,
|
|
65
|
+
},
|
|
66
|
+
body: JSON.stringify({ email }),
|
|
67
|
+
});
|
|
68
|
+
const data = await res.json();
|
|
69
|
+
if (!res.ok) {
|
|
70
|
+
s.stop("Failed");
|
|
71
|
+
console.error(kleur.red("Error creating bootstrap invite"));
|
|
72
|
+
console.error(data);
|
|
73
|
+
process.exit(1);
|
|
74
|
+
}
|
|
75
|
+
s.stop("Done");
|
|
76
|
+
console.log("");
|
|
77
|
+
if (data?.data?.url) {
|
|
78
|
+
console.log(kleur.bold("Registration URL"));
|
|
79
|
+
console.log(kleur.cyan(data.data.url));
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
console.log(kleur.green(`Invite sent to ${email}`));
|
|
83
|
+
}
|
|
84
|
+
console.log("");
|
|
85
|
+
console.log("Next step:");
|
|
86
|
+
console.log("The invited user must complete registration to receive admin access.");
|
|
87
|
+
outro("Bootstrap complete.");
|
|
88
|
+
}
|
|
89
|
+
catch (err) {
|
|
90
|
+
s.stop("Failed");
|
|
91
|
+
console.error(kleur.red("Unexpected error"));
|
|
92
|
+
console.error(err.message);
|
|
93
|
+
process.exit(1);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=bootstrapAdmin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bootstrapAdmin.js","sourceRoot":"","sources":["../../src/commands/bootstrapAdmin.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { execSync } from "child_process";
|
|
4
|
+
export async function runCheck() {
|
|
5
|
+
console.log("\nSeamless Check\n");
|
|
6
|
+
const root = process.cwd();
|
|
7
|
+
const configPath = path.join(root, "seamless.config.json");
|
|
8
|
+
if (!fs.existsSync(configPath)) {
|
|
9
|
+
console.log("✖ seamless.config.json not found");
|
|
10
|
+
console.log("→ Run: seamless init\n");
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
console.log("✔ Config file found");
|
|
14
|
+
const config = JSON.parse(fs.readFileSync(configPath, "utf-8"));
|
|
15
|
+
checkStructure(root, config);
|
|
16
|
+
checkDocker();
|
|
17
|
+
checkCompose(root, config);
|
|
18
|
+
checkContainers();
|
|
19
|
+
await checkHealth();
|
|
20
|
+
console.log("\nCheck complete.\n");
|
|
21
|
+
}
|
|
22
|
+
function checkStructure(root, config) {
|
|
23
|
+
const services = config.services;
|
|
24
|
+
if (fs.existsSync(path.join(root, services.web.path))) {
|
|
25
|
+
console.log("✔ Web project detected");
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
console.log("✖ Web project missing");
|
|
29
|
+
}
|
|
30
|
+
if (fs.existsSync(path.join(root, services.api.path))) {
|
|
31
|
+
console.log("✔ API project detected");
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
console.log("✖ API project missing");
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function checkDocker() {
|
|
38
|
+
try {
|
|
39
|
+
execSync("docker --version", { stdio: "ignore" });
|
|
40
|
+
console.log("✔ Docker is installed");
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
console.log("✖ Docker not found");
|
|
44
|
+
console.log("→ Install Docker: https://docs.docker.com/get-docker/");
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function checkCompose(root, config) {
|
|
48
|
+
const composePath = path.join(root, config.docker.composeFile);
|
|
49
|
+
if (fs.existsSync(composePath)) {
|
|
50
|
+
console.log("✔ Docker Compose file found");
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
console.log("✖ docker-compose.yml missing");
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function checkContainers() {
|
|
57
|
+
try {
|
|
58
|
+
const output = execSync("docker ps --format '{{.Names}}'").toString();
|
|
59
|
+
if (!output.includes("api")) {
|
|
60
|
+
console.log("✖ API container not running");
|
|
61
|
+
console.log("→ Run: docker compose up\n");
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
console.log("✔ Containers running");
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
console.log("✖ Failed to check containers");
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
async function checkHealth() {
|
|
72
|
+
const checks = [
|
|
73
|
+
{ name: "API", url: "http://localhost:3000/" },
|
|
74
|
+
{ name: "Auth", url: "http://localhost:5312/health/status" },
|
|
75
|
+
{ name: "Admin", url: "http://localhost:5174" },
|
|
76
|
+
];
|
|
77
|
+
for (const check of checks) {
|
|
78
|
+
try {
|
|
79
|
+
const res = await fetch(check.url);
|
|
80
|
+
if (res.ok) {
|
|
81
|
+
console.log(`✔ ${check.name} is healthy`);
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
console.log(`✖ ${check.name} returned ${res.status}`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
console.log(`✖ ${check.name} not reachable`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check.js","sourceRoot":"","sources":["../../src/commands/check.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import kleur from "kleur";
|
|
4
|
+
import * as p from "@clack/prompts";
|
|
5
|
+
import { CONTRIBUTOR_COMPONENTS, formatPublicRef, resolveCloneSource, resolveWorkspaceDir, } from "../contributor/catalog.js";
|
|
6
|
+
import { configureContributorWorkspace } from "../contributor/workspace.js";
|
|
7
|
+
import { runContributorSetupPrompts } from "../prompts/contributeSetup.js";
|
|
8
|
+
import { cloneRepo } from "../utils/repoUtils.js";
|
|
9
|
+
import { runCommand } from "../core/exec.js";
|
|
10
|
+
const WORKSPACE_MANIFEST = "seamless.workspace.json";
|
|
11
|
+
export async function runContributeCommand(args) {
|
|
12
|
+
const subcommand = args[0] ?? "setup";
|
|
13
|
+
if (subcommand === "setup") {
|
|
14
|
+
await runContributorSetup(args[1]);
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
if (subcommand === "start") {
|
|
18
|
+
await runContributorStart();
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
throw new Error(`Unknown contribute subcommand: ${subcommand}`);
|
|
22
|
+
}
|
|
23
|
+
async function runContributorSetup(initialWorkspaceName) {
|
|
24
|
+
p.intro(kleur.cyan("Seamless Contributor Setup"));
|
|
25
|
+
const answers = await runContributorSetupPrompts(initialWorkspaceName);
|
|
26
|
+
const workspaceRoot = path.resolve(process.cwd(), answers.workspaceName);
|
|
27
|
+
ensureWorkspaceRoot(workspaceRoot);
|
|
28
|
+
const manifest = {
|
|
29
|
+
version: 1,
|
|
30
|
+
createdAt: new Date().toISOString(),
|
|
31
|
+
packageManager: "npm",
|
|
32
|
+
workspaceRoot,
|
|
33
|
+
components: [],
|
|
34
|
+
};
|
|
35
|
+
for (const component of CONTRIBUTOR_COMPONENTS) {
|
|
36
|
+
const mode = answers.localComponents.includes(component.id)
|
|
37
|
+
? "local"
|
|
38
|
+
: "public";
|
|
39
|
+
const workspaceDir = resolveWorkspaceDir(component, mode);
|
|
40
|
+
const localPath = mode === "local" || component.publicSurface === "github-repo"
|
|
41
|
+
? path.join(workspaceRoot, workspaceDir)
|
|
42
|
+
: undefined;
|
|
43
|
+
if (localPath) {
|
|
44
|
+
const cloneSource = resolveCloneSource(component);
|
|
45
|
+
await cloneRepo(cloneSource, localPath);
|
|
46
|
+
}
|
|
47
|
+
manifest.components.push({
|
|
48
|
+
id: component.id,
|
|
49
|
+
mode,
|
|
50
|
+
publicSurface: component.publicSurface,
|
|
51
|
+
publicRef: component.publicRef,
|
|
52
|
+
gitUrl: component.gitUrl,
|
|
53
|
+
localPath,
|
|
54
|
+
localPackages: component.localPackages,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
const configuredManifest = configureContributorWorkspace(workspaceRoot, manifest);
|
|
58
|
+
fs.mkdirSync(workspaceRoot, { recursive: true });
|
|
59
|
+
fs.writeFileSync(path.join(workspaceRoot, WORKSPACE_MANIFEST), JSON.stringify(configuredManifest, null, 2) + "\n");
|
|
60
|
+
printContributorSetupOutput(workspaceRoot, configuredManifest);
|
|
61
|
+
p.outro(kleur.green("Contributor workspace provisioned"));
|
|
62
|
+
}
|
|
63
|
+
async function runContributorStart() {
|
|
64
|
+
const workspaceRoot = process.cwd();
|
|
65
|
+
const manifestPath = path.join(workspaceRoot, WORKSPACE_MANIFEST);
|
|
66
|
+
if (!fs.existsSync(manifestPath)) {
|
|
67
|
+
throw new Error(`Contributor manifest not found in current directory: ${WORKSPACE_MANIFEST}`);
|
|
68
|
+
}
|
|
69
|
+
await runCommand("docker", ["compose", "up", "--build"], workspaceRoot);
|
|
70
|
+
}
|
|
71
|
+
function ensureWorkspaceRoot(workspaceRoot) {
|
|
72
|
+
if (!fs.existsSync(workspaceRoot)) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
const contents = fs.readdirSync(workspaceRoot);
|
|
76
|
+
if (contents.length > 0) {
|
|
77
|
+
throw new Error(`Workspace directory is not empty: ${workspaceRoot}`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
function printContributorSetupOutput(workspaceRoot, manifest) {
|
|
81
|
+
console.log("");
|
|
82
|
+
console.log(kleur.bold("Workspace"));
|
|
83
|
+
console.log(` ${kleur.white("Directory:")} ${workspaceRoot}`);
|
|
84
|
+
console.log(` ${kleur.white("Manifest:")} ${WORKSPACE_MANIFEST}`);
|
|
85
|
+
console.log(` ${kleur.white("Package manager:")} npm`);
|
|
86
|
+
console.log(` ${kleur.white("Docker Compose:")} ${manifest.docker?.composeFile ?? "docker-compose.yml"}`);
|
|
87
|
+
console.log("");
|
|
88
|
+
console.log(kleur.bold("Component plan"));
|
|
89
|
+
for (const component of manifest.components) {
|
|
90
|
+
const modeLabel = component.mode === "local"
|
|
91
|
+
? kleur.green("local source")
|
|
92
|
+
: kleur.cyan(`public ${component.publicSurface}`);
|
|
93
|
+
console.log(` • ${component.id} ${kleur.dim(`(${modeLabel})`)}`);
|
|
94
|
+
if (component.localPath) {
|
|
95
|
+
const relativePath = path.relative(workspaceRoot, component.localPath);
|
|
96
|
+
console.log(` path: ${relativePath || "."}`);
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
console.log(` source: ${formatPublicRef(component.publicRef)}`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
if (manifest.packageLinks && manifest.packageLinks.length > 0) {
|
|
103
|
+
console.log("");
|
|
104
|
+
console.log(kleur.bold("Local package links"));
|
|
105
|
+
for (const link of manifest.packageLinks) {
|
|
106
|
+
console.log(` • ${link.consumerComponentId} uses ${link.packageName} from ${link.targetPath}`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
if (manifest.warnings && manifest.warnings.length > 0) {
|
|
110
|
+
console.log("");
|
|
111
|
+
console.log(kleur.bold("Warnings"));
|
|
112
|
+
for (const warning of manifest.warnings) {
|
|
113
|
+
console.log(` • ${kleur.yellow(warning)}`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
console.log("");
|
|
117
|
+
console.log(kleur.bold("Next step"));
|
|
118
|
+
console.log(` cd ${workspaceRoot}`);
|
|
119
|
+
console.log(" docker compose up --build");
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=contribute.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contribute.js","sourceRoot":"","sources":["../../src/commands/contribute.ts"],"names":[],"mappings":"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"}
|