create-seamless 0.1.0 → 0.1.1
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 +109 -51
- package/dist/commands/init.js +65 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/core/configure.js +25 -0
- package/dist/core/configure.js.map +1 -0
- package/dist/core/env.js +35 -0
- package/dist/core/env.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/help.js +56 -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 +83 -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/secrets.js +8 -0
- package/dist/core/secrets.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/docker/docker.js +231 -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 +17 -0
- package/dist/index.js.map +1 -0
- package/dist/prompts/projectSetup.js +64 -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 +4 -3
package/README.md
CHANGED
|
@@ -3,85 +3,142 @@
|
|
|
3
3
|
[](LICENSE)
|
|
4
4
|
[](https://www.npmjs.com/package/create-seamless)
|
|
5
5
|
|
|
6
|
-
`create-seamless` is a
|
|
6
|
+
`create-seamless` is a CLI for bootstrapping applications with Seamless Auth, an open source, passwordless authentication system.
|
|
7
7
|
|
|
8
|
-
It
|
|
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
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Getting started
|
|
13
|
+
|
|
14
|
+
Run the CLI with `npx`:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npx create-seamless my-app
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Or run it in your current directory:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npx create-seamless
|
|
24
|
+
```
|
|
13
25
|
|
|
14
|
-
|
|
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
|
|
15
32
|
|
|
16
33
|
---
|
|
17
34
|
|
|
18
|
-
## What
|
|
35
|
+
## What gets created
|
|
19
36
|
|
|
20
|
-
Depending on
|
|
37
|
+
Depending on your selections, the CLI generates a project like this:
|
|
21
38
|
|
|
22
39
|
```text
|
|
23
40
|
my-app/
|
|
24
|
-
├─ auth/ # Seamless Auth
|
|
25
|
-
├─ web/ #
|
|
26
|
-
├─ api/ #
|
|
41
|
+
├─ auth/ # Seamless Auth server (optional)
|
|
42
|
+
├─ web/ # React web application (optional)
|
|
43
|
+
├─ api/ # Express API server (optional)
|
|
44
|
+
├─ docker-compose.yml (optional)
|
|
27
45
|
└─ README.md
|
|
28
46
|
```
|
|
29
47
|
|
|
30
|
-
|
|
48
|
+
All services are preconfigured to work together.
|
|
31
49
|
|
|
32
|
-
|
|
50
|
+
- Web calls the API
|
|
51
|
+
- API communicates with the auth server
|
|
52
|
+
- Auth manages sessions and tokens
|
|
33
53
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
54
|
+
No manual wiring is required.
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Running your project
|
|
37
59
|
|
|
38
|
-
|
|
39
|
-
cd api && npm run dev
|
|
60
|
+
### Option 1: Docker
|
|
40
61
|
|
|
41
|
-
|
|
42
|
-
|
|
62
|
+
If you choose Docker during setup:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
docker compose up
|
|
43
66
|
```
|
|
44
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
|
+
|
|
45
77
|
---
|
|
46
78
|
|
|
47
|
-
|
|
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
|
+
---
|
|
48
88
|
|
|
49
|
-
|
|
89
|
+
#### 2. Start the auth server
|
|
50
90
|
|
|
51
91
|
```bash
|
|
52
|
-
|
|
92
|
+
cd auth
|
|
93
|
+
npm install
|
|
94
|
+
|
|
95
|
+
npm run db:create
|
|
96
|
+
npm run db:migrate
|
|
97
|
+
|
|
98
|
+
npm run dev
|
|
53
99
|
```
|
|
54
100
|
|
|
55
|
-
|
|
101
|
+
---
|
|
56
102
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
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
|
+
```
|
|
60
120
|
|
|
61
121
|
---
|
|
62
122
|
|
|
63
|
-
##
|
|
123
|
+
## What is configured for you
|
|
124
|
+
|
|
125
|
+
create-seamless handles the parts that are usually difficult to get right:
|
|
64
126
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
| `--install` | Automatically install dependencies |
|
|
71
|
-
| `--no-git` | Skip git initialization |
|
|
72
|
-
| `--auth-port` | Auth server port (default: 3000) |
|
|
73
|
-
| `--api-port` | API server port (default: 4000) |
|
|
74
|
-
| `--web-port` | Web dev server port (default: 5173) |
|
|
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
|
|
75
132
|
|
|
76
|
-
|
|
133
|
+
Everything is aligned across services so the system works immediately after setup.
|
|
77
134
|
|
|
78
135
|
---
|
|
79
136
|
|
|
80
137
|
## Included projects
|
|
81
138
|
|
|
82
|
-
|
|
139
|
+
create-seamless pulls from the following repositories:
|
|
83
140
|
|
|
84
|
-
- Seamless Auth
|
|
141
|
+
- Seamless Auth API
|
|
85
142
|
[https://github.com/fells-code/seamless-auth-api](https://github.com/fells-code/seamless-auth-api)
|
|
86
143
|
|
|
87
144
|
- Seamless Auth React Starter
|
|
@@ -90,29 +147,29 @@ If no component flags are provided, all components are included.
|
|
|
90
147
|
- Seamless Auth API Starter
|
|
91
148
|
[https://github.com/fells-code/seamless-auth-starter-express](https://github.com/fells-code/seamless-auth-starter-express)
|
|
92
149
|
|
|
93
|
-
Each
|
|
150
|
+
Each project can be used independently, but the CLI connects them into a working system.
|
|
94
151
|
|
|
95
152
|
---
|
|
96
153
|
|
|
97
154
|
## Documentation
|
|
98
155
|
|
|
99
|
-
Full documentation
|
|
156
|
+
Full documentation is available at:
|
|
100
157
|
|
|
101
|
-
[https://seamlessauth.com
|
|
158
|
+
[https://docs.seamlessauth.com](https://docs.seamlessauth.com)
|
|
102
159
|
|
|
103
160
|
---
|
|
104
161
|
|
|
105
162
|
## Philosophy
|
|
106
163
|
|
|
107
|
-
Seamless Auth is
|
|
164
|
+
Seamless Auth is built around a few principles:
|
|
108
165
|
|
|
109
166
|
- Passwordless authentication only
|
|
110
|
-
-
|
|
111
|
-
- Self-hosted
|
|
167
|
+
- No redirects or third-party auth providers
|
|
168
|
+
- Self-hosted by default
|
|
112
169
|
- Production-shaped local development
|
|
113
|
-
-
|
|
170
|
+
- Explicit configuration over hidden behavior
|
|
114
171
|
|
|
115
|
-
|
|
172
|
+
create-seamless exists to make this setup fast and repeatable.
|
|
116
173
|
|
|
117
174
|
---
|
|
118
175
|
|
|
@@ -120,12 +177,13 @@ Seamless Auth is designed around:
|
|
|
120
177
|
|
|
121
178
|
- Node.js 18 or newer
|
|
122
179
|
- npm or pnpm
|
|
180
|
+
- Docker (optional)
|
|
123
181
|
|
|
124
182
|
---
|
|
125
183
|
|
|
126
184
|
## License
|
|
127
185
|
|
|
128
|
-
|
|
186
|
+
AGPL-3.0-only © 2026 Fells Code LLC
|
|
129
187
|
|
|
130
188
|
This license ensures:
|
|
131
189
|
|
|
@@ -133,4 +191,4 @@ This license ensures:
|
|
|
133
191
|
- freedom to self-host and modify
|
|
134
192
|
- sustainability of the managed service offering
|
|
135
193
|
|
|
136
|
-
See
|
|
194
|
+
See `LICENSE` for details.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import { runProjectSetupPrompts } from "../prompts/projectSetup.js";
|
|
4
|
+
import { generateReactStarter } from "../generators/frontend/react.js";
|
|
5
|
+
import { generateExpressStarter } from "../generators/backend/express.js";
|
|
6
|
+
import { generateAuthServer } from "../generators/auth/auth.js";
|
|
7
|
+
import { configureApiEnv, configureWebEnv } from "../core/configure.js";
|
|
8
|
+
import { configureAuthLocalEnv, generateDockerCompose, } from "../generators/docker/docker.js";
|
|
9
|
+
import { printSuccessOutput } from "../core/output.js";
|
|
10
|
+
export async function runCLI(projectName) {
|
|
11
|
+
const cwd = process.cwd();
|
|
12
|
+
let root = cwd;
|
|
13
|
+
if (projectName) {
|
|
14
|
+
root = path.join(cwd, projectName);
|
|
15
|
+
if (fs.existsSync(root)) {
|
|
16
|
+
throw new Error(`Directory already exists: ${projectName}`);
|
|
17
|
+
}
|
|
18
|
+
fs.mkdirSync(root);
|
|
19
|
+
console.log(`Creating project in ${root}`);
|
|
20
|
+
}
|
|
21
|
+
const files = fs.readdirSync(root);
|
|
22
|
+
const isEmpty = files.length === 0;
|
|
23
|
+
if (!isEmpty) {
|
|
24
|
+
console.log("Existing project detected.");
|
|
25
|
+
console.log("Integration flow coming next.");
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const answers = await runProjectSetupPrompts();
|
|
29
|
+
if (answers.web && answers.webFramework === "react") {
|
|
30
|
+
await generateReactStarter({ root });
|
|
31
|
+
}
|
|
32
|
+
if (answers.api && answers.apiFramework === "express") {
|
|
33
|
+
await generateExpressStarter({ root });
|
|
34
|
+
}
|
|
35
|
+
let sharedConfig = {};
|
|
36
|
+
if (answers.authMode === "local") {
|
|
37
|
+
await generateAuthServer({ root }, "local");
|
|
38
|
+
sharedConfig = await configureAuthLocalEnv(root);
|
|
39
|
+
}
|
|
40
|
+
if (answers.useDocker) {
|
|
41
|
+
const dockerShared = await generateDockerCompose(root, {
|
|
42
|
+
authMode: answers.authMode,
|
|
43
|
+
includeApi: answers.api,
|
|
44
|
+
includeWeb: answers.web,
|
|
45
|
+
});
|
|
46
|
+
if (answers.authMode === "docker") {
|
|
47
|
+
sharedConfig = dockerShared;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
if (answers.api) {
|
|
51
|
+
configureApiEnv(root, sharedConfig);
|
|
52
|
+
}
|
|
53
|
+
if (answers.web) {
|
|
54
|
+
configureWebEnv(root);
|
|
55
|
+
}
|
|
56
|
+
printSuccessOutput({
|
|
57
|
+
projectName,
|
|
58
|
+
root,
|
|
59
|
+
webFramework: answers.webFramework,
|
|
60
|
+
apiFramework: answers.apiFramework,
|
|
61
|
+
authMode: answers.authMode,
|
|
62
|
+
useDocker: answers.useDocker,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import { parseEnv, writeEnv } from "./env.js";
|
|
4
|
+
import { generateSecret } from "./secrets.js";
|
|
5
|
+
export function configureApiEnv(root, shared) {
|
|
6
|
+
const apiEnvPath = path.join(root, "api", ".env");
|
|
7
|
+
if (!fs.existsSync(apiEnvPath))
|
|
8
|
+
return;
|
|
9
|
+
const env = parseEnv(apiEnvPath);
|
|
10
|
+
env.AUTH_SERVER_URL = "http://localhost:5312";
|
|
11
|
+
env.API_SERVICE_TOKEN = shared.apiToken;
|
|
12
|
+
env.JWKS_KID = shared.kid;
|
|
13
|
+
env.COOKIE_SIGNING_KEY = generateSecret(32);
|
|
14
|
+
writeEnv(apiEnvPath, env);
|
|
15
|
+
}
|
|
16
|
+
export function configureWebEnv(root) {
|
|
17
|
+
const webEnvPath = path.join(root, "web", ".env");
|
|
18
|
+
if (!fs.existsSync(webEnvPath))
|
|
19
|
+
return;
|
|
20
|
+
const env = parseEnv(webEnvPath);
|
|
21
|
+
env.VITE_AUTH_SERVER_URL = "http://localhost:5312";
|
|
22
|
+
env.VITE_API_URL = "http://localhost:3000";
|
|
23
|
+
writeEnv(webEnvPath, env);
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=configure.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configure.js","sourceRoot":"","sources":["../../src/core/configure.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,UAAU,eAAe,CAAC,IAAY,EAAE,MAAW;IACvD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAElD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO;IAEvC,MAAM,GAAG,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;IAEjC,GAAG,CAAC,eAAe,GAAG,uBAAuB,CAAC;IAC9C,GAAG,CAAC,iBAAiB,GAAG,MAAM,CAAC,QAAQ,CAAC;IACxC,GAAG,CAAC,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC;IAC1B,GAAG,CAAC,kBAAkB,GAAG,cAAc,CAAC,EAAE,CAAC,CAAC;IAE5C,QAAQ,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAElD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO;IAEvC,MAAM,GAAG,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;IAEjC,GAAG,CAAC,oBAAoB,GAAG,uBAAuB,CAAC;IACnD,GAAG,CAAC,YAAY,GAAG,uBAAuB,CAAC;IAE3C,QAAQ,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;AAC5B,CAAC"}
|
package/dist/core/env.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
export function parseEnv(filePath) {
|
|
3
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
4
|
+
const lines = content.split("\n");
|
|
5
|
+
const env = {};
|
|
6
|
+
for (const line of lines) {
|
|
7
|
+
if (!line || line.startsWith("#"))
|
|
8
|
+
continue;
|
|
9
|
+
const [key, ...rest] = line.split("=");
|
|
10
|
+
if (!key)
|
|
11
|
+
continue;
|
|
12
|
+
env[key.trim()] = rest.join("=").trim();
|
|
13
|
+
}
|
|
14
|
+
return env;
|
|
15
|
+
}
|
|
16
|
+
export function parseEnvString(content) {
|
|
17
|
+
const lines = content.split("\n");
|
|
18
|
+
const env = {};
|
|
19
|
+
for (const line of lines) {
|
|
20
|
+
if (!line || line.startsWith("#"))
|
|
21
|
+
continue;
|
|
22
|
+
const [key, ...rest] = line.split("=");
|
|
23
|
+
if (!key)
|
|
24
|
+
continue;
|
|
25
|
+
env[key.trim()] = rest.join("=").trim();
|
|
26
|
+
}
|
|
27
|
+
return env;
|
|
28
|
+
}
|
|
29
|
+
export function writeEnv(filePath, env) {
|
|
30
|
+
const content = Object.entries(env)
|
|
31
|
+
.map(([k, v]) => `${k}=${v}`)
|
|
32
|
+
.join("\n");
|
|
33
|
+
fs.writeFileSync(filePath, content + "\n");
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=env.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/core/env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB,MAAM,UAAU,QAAQ,CAAC,QAAgB;IACvC,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAEnD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAElC,MAAM,GAAG,GAA2B,EAAE,CAAC;IAEvC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QAE5C,MAAM,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACvC,IAAI,CAAC,GAAG;YAAE,SAAS;QAEnB,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAC1C,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,OAAe;IAC5C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAElC,MAAM,GAAG,GAA2B,EAAE,CAAC;IAEvC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QAE5C,MAAM,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAEvC,IAAI,CAAC,GAAG;YAAE,SAAS;QAEnB,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAC1C,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,QAAgB,EAAE,GAA2B;IACpE,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC;SAChC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;SAC5B,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAC,CAAC;AAC7C,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { spawn } from "child_process";
|
|
2
|
+
export function runCommand(command, args, cwd) {
|
|
3
|
+
return new Promise((resolve, reject) => {
|
|
4
|
+
const child = spawn(command, args, {
|
|
5
|
+
stdio: "inherit",
|
|
6
|
+
cwd,
|
|
7
|
+
shell: true,
|
|
8
|
+
});
|
|
9
|
+
child.on("close", (code) => {
|
|
10
|
+
if (code === 0)
|
|
11
|
+
resolve();
|
|
12
|
+
else
|
|
13
|
+
reject(new Error(`${command} failed`));
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=exec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exec.js","sourceRoot":"","sources":["../../src/core/exec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAEtC,MAAM,UAAU,UAAU,CACxB,OAAe,EACf,IAAc,EACd,GAAW;IAEX,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE;YACjC,KAAK,EAAE,SAAS;YAChB,GAAG;YACH,KAAK,EAAE,IAAI;SACZ,CAAC,CAAC;QAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YACzB,IAAI,IAAI,KAAK,CAAC;gBAAE,OAAO,EAAE,CAAC;;gBACrB,MAAM,CAAC,IAAI,KAAK,CAAC,GAAG,OAAO,SAAS,CAAC,CAAC,CAAC;QAC9C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export async function fetchEnvExample() {
|
|
2
|
+
const url = "https://raw.githubusercontent.com/fells-code/seamless-auth-api/main/.env.example";
|
|
3
|
+
const res = await fetch(url);
|
|
4
|
+
if (!res.ok) {
|
|
5
|
+
throw new Error("Failed to fetch auth env.example");
|
|
6
|
+
}
|
|
7
|
+
return await res.text();
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=fetch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../src/core/fetch.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,MAAM,GAAG,GACP,kFAAkF,CAAC;IAErF,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;IAE7B,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IACtD,CAAC;IAED,OAAO,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
export function printHelp() {
|
|
2
|
+
console.log(`
|
|
3
|
+
create-seamless
|
|
4
|
+
|
|
5
|
+
Seamless Auth CLI — scaffold and integrate passwordless authentication.
|
|
6
|
+
|
|
7
|
+
────────────────────────────────────────────
|
|
8
|
+
|
|
9
|
+
USAGE
|
|
10
|
+
|
|
11
|
+
npx create-seamless
|
|
12
|
+
npx create-seamless <project-name>
|
|
13
|
+
npx create-seamless -h
|
|
14
|
+
npx create-seamless --help
|
|
15
|
+
|
|
16
|
+
────────────────────────────────────────────
|
|
17
|
+
|
|
18
|
+
BEHAVIOR
|
|
19
|
+
|
|
20
|
+
npx create-seamless
|
|
21
|
+
|
|
22
|
+
Without a name:
|
|
23
|
+
• If directory is empty → create a new project
|
|
24
|
+
|
|
25
|
+
npx create-seamless <project-name>
|
|
26
|
+
|
|
27
|
+
With a name:
|
|
28
|
+
• Creates a new directory
|
|
29
|
+
|
|
30
|
+
────────────────────────────────────────────
|
|
31
|
+
|
|
32
|
+
WHAT YOU CAN BUILD
|
|
33
|
+
|
|
34
|
+
• A web application starter with Seamless Auth
|
|
35
|
+
• An API server starter with Seamless Auth
|
|
36
|
+
• SeamlessAuth server (local or Docker)
|
|
37
|
+
|
|
38
|
+
────────────────────────────────────────────
|
|
39
|
+
|
|
40
|
+
EXAMPLES
|
|
41
|
+
|
|
42
|
+
npx create-seamless
|
|
43
|
+
→ Interactive setup in current directory
|
|
44
|
+
|
|
45
|
+
npx create-seamless my-app
|
|
46
|
+
→ Create new project in ./my-app
|
|
47
|
+
|
|
48
|
+
────────────────────────────────────────────
|
|
49
|
+
|
|
50
|
+
DOCS
|
|
51
|
+
|
|
52
|
+
https://docs.seamlessauth.com
|
|
53
|
+
|
|
54
|
+
`);
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=help.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"help.js","sourceRoot":"","sources":["../../src/core/help.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,SAAS;IACvB,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoDb,CAAC,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { detectPackageManager } from "./packageManager.js";
|
|
4
|
+
export async function inspectProject(root) {
|
|
5
|
+
const hasPackageJson = fs.existsSync(path.join(root, "package.json"));
|
|
6
|
+
return {
|
|
7
|
+
root,
|
|
8
|
+
packageManager: detectPackageManager(root),
|
|
9
|
+
detected: {
|
|
10
|
+
packageJson: hasPackageJson,
|
|
11
|
+
anything: hasPackageJson,
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=inspect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inspect.js","sourceRoot":"","sources":["../../src/core/inspect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAE3D,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAY;IAC/C,MAAM,cAAc,GAAG,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC;IAEtE,OAAO;QACL,IAAI;QACJ,cAAc,EAAE,oBAAoB,CAAC,IAAI,CAAC;QAC1C,QAAQ,EAAE;YACR,WAAW,EAAE,cAAc;YAC3B,QAAQ,EAAE,cAAc;SACzB;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { generateKeyPairSync } from "crypto";
|
|
2
|
+
export function generateJWKS() {
|
|
3
|
+
const { publicKey, privateKey } = generateKeyPairSync("rsa", {
|
|
4
|
+
modulusLength: 2048,
|
|
5
|
+
publicKeyEncoding: {
|
|
6
|
+
type: "spki",
|
|
7
|
+
format: "pem",
|
|
8
|
+
},
|
|
9
|
+
privateKeyEncoding: {
|
|
10
|
+
type: "pkcs8",
|
|
11
|
+
format: "pem",
|
|
12
|
+
},
|
|
13
|
+
});
|
|
14
|
+
return {
|
|
15
|
+
publicKey,
|
|
16
|
+
privateKey,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=jwks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jwks.js","sourceRoot":"","sources":["../../src/core/jwks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AAE7C,MAAM,UAAU,YAAY;IAC1B,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,mBAAmB,CAAC,KAAK,EAAE;QAC3D,aAAa,EAAE,IAAI;QACnB,iBAAiB,EAAE;YACjB,IAAI,EAAE,MAAM;YACZ,MAAM,EAAE,KAAK;SACd;QACD,kBAAkB,EAAE;YAClB,IAAI,EAAE,OAAO;YACb,MAAM,EAAE,KAAK;SACd;KACF,CAAC,CAAC;IAEH,OAAO;QACL,SAAS;QACT,UAAU;KACX,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import kleur from "kleur";
|
|
2
|
+
export function printSuccessOutput(config) {
|
|
3
|
+
const { projectName, webFramework, apiFramework, authMode, useDocker } = config;
|
|
4
|
+
const title = kleur.bold().cyan("SEAMLESS");
|
|
5
|
+
console.log(`
|
|
6
|
+
╔════════════════════════════════════════╗
|
|
7
|
+
║ ${title} ║
|
|
8
|
+
╚════════════════════════════════════════╝
|
|
9
|
+
`);
|
|
10
|
+
console.log(kleur.green("✔ Your SeamlessAuth project is ready.\n"));
|
|
11
|
+
if (projectName) {
|
|
12
|
+
console.log(kleur.dim("Project created in: ") + kleur.bold(projectName));
|
|
13
|
+
console.log(kleur.cyan(`cd ${projectName}\n`));
|
|
14
|
+
}
|
|
15
|
+
console.log(kleur.bold("Project includes:\n"));
|
|
16
|
+
if (webFramework) {
|
|
17
|
+
console.log(" • " +
|
|
18
|
+
kleur.white("Web app") +
|
|
19
|
+
kleur.dim(` (${formatFramework(webFramework)})`));
|
|
20
|
+
}
|
|
21
|
+
if (apiFramework) {
|
|
22
|
+
console.log(" • " +
|
|
23
|
+
kleur.white("API server") +
|
|
24
|
+
kleur.dim(` (${formatFramework(apiFramework)})`));
|
|
25
|
+
}
|
|
26
|
+
console.log(" • " +
|
|
27
|
+
kleur.white("Auth server") +
|
|
28
|
+
kleur.dim(authMode === "local" ? " (local source)" : " (Docker image)"));
|
|
29
|
+
console.log("");
|
|
30
|
+
console.log(kleur.bold("Getting started:\n"));
|
|
31
|
+
if (useDocker) {
|
|
32
|
+
console.log(kleur.cyan(" docker compose up\n"));
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
if (authMode === "local") {
|
|
36
|
+
console.log(kleur.dim("# Auth server"));
|
|
37
|
+
console.log(kleur.yellow(" ⚠ Requires a local PostgreSQL instance running on localhost, port 5432\n"));
|
|
38
|
+
console.log(" cd auth");
|
|
39
|
+
console.log(" npm install\n");
|
|
40
|
+
console.log(kleur.dim(" # Initialize database"));
|
|
41
|
+
console.log(" npm run db:create");
|
|
42
|
+
console.log(" npm run db:migrate\n");
|
|
43
|
+
console.log(kleur.dim(" # Start auth server"));
|
|
44
|
+
console.log(" npm run dev\n");
|
|
45
|
+
}
|
|
46
|
+
if (apiFramework) {
|
|
47
|
+
console.log(kleur.dim("# API server"));
|
|
48
|
+
console.log(" cd api && npm install && npm run dev\n");
|
|
49
|
+
}
|
|
50
|
+
if (webFramework) {
|
|
51
|
+
console.log(kleur.dim("# Web app"));
|
|
52
|
+
console.log(" cd web && npm install && npm run dev\n");
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
console.log(kleur.bold("Available services:\n"));
|
|
56
|
+
console.log(" Auth: " + kleur.cyan("http://localhost:5312"));
|
|
57
|
+
if (apiFramework) {
|
|
58
|
+
console.log(" API: " + kleur.cyan("http://localhost:3000"));
|
|
59
|
+
}
|
|
60
|
+
if (webFramework) {
|
|
61
|
+
console.log(" Web: " + kleur.cyan("http://localhost:5173"));
|
|
62
|
+
}
|
|
63
|
+
console.log("");
|
|
64
|
+
console.log(kleur.bold("Notes:\n"));
|
|
65
|
+
console.log(kleur.dim(" • Web connects to API automatically"));
|
|
66
|
+
console.log(kleur.dim(" • API connects to Auth automatically"));
|
|
67
|
+
console.log(kleur.dim(" • All secrets and keys are pre-configured\n"));
|
|
68
|
+
console.log(kleur.dim("Docs: ") + kleur.cyan("https://docs.seamlessauth.com\n"));
|
|
69
|
+
console.log(kleur.bold().green("Happy hacking. 🚀\n"));
|
|
70
|
+
}
|
|
71
|
+
function formatFramework(name) {
|
|
72
|
+
const map = {
|
|
73
|
+
react: "React",
|
|
74
|
+
express: "Express",
|
|
75
|
+
angular: "Angular",
|
|
76
|
+
next: "Next.js",
|
|
77
|
+
fastapi: "FastAPI",
|
|
78
|
+
fastify: "Fastify",
|
|
79
|
+
vue: "Vue",
|
|
80
|
+
};
|
|
81
|
+
return map[name] || name;
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=output.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/core/output.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
export function detectPackageManager(root) {
|
|
4
|
+
if (fs.existsSync(path.join(root, "pnpm-lock.yaml")))
|
|
5
|
+
return "pnpm";
|
|
6
|
+
if (fs.existsSync(path.join(root, "yarn.lock")))
|
|
7
|
+
return "yarn";
|
|
8
|
+
return "npm";
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=packageManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"packageManager.js","sourceRoot":"","sources":["../../src/core/packageManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAIxB,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;QAAE,OAAO,MAAM,CAAC;IACpE,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAAE,OAAO,MAAM,CAAC;IAC/D,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import { fileURLToPath } from "url";
|
|
3
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
4
|
+
const __dirname = path.dirname(__filename);
|
|
5
|
+
export const PROJECT_ROOT = path.resolve(__dirname, "../../");
|
|
6
|
+
export const TEMPLATE_ROOT = path.join(PROJECT_ROOT, "templates");
|
|
7
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/core/paths.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;AAE3C,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;AAE9D,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secrets.js","sourceRoot":"","sources":["../../src/core/secrets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAErC,MAAM,UAAU,cAAc,CAAC,MAAM,GAAG,EAAE;IACxC,OAAO,WAAW,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,WAAW;IACzB,OAAO,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AACjD,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { runCommand } from "../../core/exec.js";
|
|
4
|
+
import { writeEnv } from "../../utils/writeEnv.js";
|
|
5
|
+
const AUTH_REPO = "https://github.com/fells-code/seamless-auth-api";
|
|
6
|
+
const AUTH_PORT = 5312;
|
|
7
|
+
export async function generateAuthServer(context, mode) {
|
|
8
|
+
const { root } = context;
|
|
9
|
+
if (mode === "local") {
|
|
10
|
+
await setupLocalAuth(root);
|
|
11
|
+
}
|
|
12
|
+
else {
|
|
13
|
+
await setupDockerAuth(root);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
async function setupLocalAuth(root) {
|
|
17
|
+
const authDir = path.join(root, "auth");
|
|
18
|
+
console.log("Cloning SeamlessAuth server...");
|
|
19
|
+
await runCommand("git", ["clone", AUTH_REPO, "auth"], root);
|
|
20
|
+
console.log("Writing auth environment...");
|
|
21
|
+
writeEnv(authDir, {
|
|
22
|
+
PORT: AUTH_PORT,
|
|
23
|
+
NODE_ENV: "development",
|
|
24
|
+
AUTH_MODE: "server",
|
|
25
|
+
ISSUER: `http://localhost:${AUTH_PORT}`,
|
|
26
|
+
});
|
|
27
|
+
console.log("Auth server ready in /auth");
|
|
28
|
+
}
|
|
29
|
+
async function setupDockerAuth(root) {
|
|
30
|
+
console.log("Creating docker-compose for SeamlessAuth...");
|
|
31
|
+
const dockerCompose = `
|
|
32
|
+
services:
|
|
33
|
+
auth:
|
|
34
|
+
image: ghcr.io/fells-code/seamless-auth-api:v0.1.2
|
|
35
|
+
container_name: seamless-auth
|
|
36
|
+
ports:
|
|
37
|
+
- "5312:5312"
|
|
38
|
+
environment:
|
|
39
|
+
PORT: 5312
|
|
40
|
+
NODE_ENV: development
|
|
41
|
+
AUTH_MODE: server
|
|
42
|
+
ISSUER: http://localhost:5312
|
|
43
|
+
`;
|
|
44
|
+
fs.writeFileSync(path.join(root, "docker-compose.yml"), dockerCompose.trim() + "\n");
|
|
45
|
+
console.log("Docker setup ready.");
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../src/generators/auth/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAEnD,MAAM,SAAS,GAAG,iDAAiD,CAAC;AACpE,MAAM,SAAS,GAAG,IAAI,CAAC;AAEvB,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,OAAY,EACZ,IAAiC;IAEjC,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;IAEzB,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;QACrB,MAAM,cAAc,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;SAAM,CAAC;QACN,MAAM,eAAe,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;AACH,CAAC;AAED,KAAK,UAAU,cAAc,CAAC,IAAY;IACxC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAExC,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;IAE9C,MAAM,UAAU,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC;IAE5D,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;IAE3C,QAAQ,CAAC,OAAO,EAAE;QAChB,IAAI,EAAE,SAAS;QACf,QAAQ,EAAE,aAAa;QACvB,SAAS,EAAE,QAAQ;QACnB,MAAM,EAAE,oBAAoB,SAAS,EAAE;KACxC,CAAC,CAAC;IAEH,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;AAC5C,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,IAAY;IACzC,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC;IAE3D,MAAM,aAAa,GAAG;;;;;;;;;;;;CAYvB,CAAC;IAEA,EAAE,CAAC,aAAa,CACd,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,oBAAoB,CAAC,EACrC,aAAa,CAAC,IAAI,EAAE,GAAG,IAAI,CAC5B,CAAC;IAEF,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;AACrC,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import { cloneRepo, removeGitDir, copyEnvExample, } from "../../utils/repoUtils.js";
|
|
3
|
+
const API_STARTER_REPO = "https://github.com/fells-code/seamless-auth-starter-express.git";
|
|
4
|
+
export async function generateExpressStarter(context) {
|
|
5
|
+
const { root } = context;
|
|
6
|
+
const apiDir = path.join(root, "api");
|
|
7
|
+
console.log("Cloning Seamless Auth Express starter...");
|
|
8
|
+
await cloneRepo(API_STARTER_REPO, apiDir);
|
|
9
|
+
removeGitDir(apiDir);
|
|
10
|
+
copyEnvExample(apiDir);
|
|
11
|
+
console.log("API starter ready.");
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=express.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"express.js","sourceRoot":"","sources":["../../../src/generators/backend/express.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EACL,SAAS,EACT,YAAY,EACZ,cAAc,GACf,MAAM,0BAA0B,CAAC;AAElC,MAAM,gBAAgB,GACpB,iEAAiE,CAAC;AAEpE,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,OAAyB;IACpE,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;IAEzB,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAEtC,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;IAExD,MAAM,SAAS,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC;IAE1C,YAAY,CAAC,MAAM,CAAC,CAAC;IACrB,cAAc,CAAC,MAAM,CAAC,CAAC;IAEvB,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;AACpC,CAAC"}
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { fetchEnvExample } from "../../core/fetch.js";
|
|
4
|
+
import { parseEnv, parseEnvString } from "../../core/env.js";
|
|
5
|
+
import { generateSecret } from "../../core/secrets.js";
|
|
6
|
+
import { generateJWKS } from "../../core/jwks.js";
|
|
7
|
+
export async function generateDockerCompose(root, options) {
|
|
8
|
+
const { compose, shared } = await buildCompose(options, root);
|
|
9
|
+
fs.writeFileSync(path.join(root, "docker-compose.yml"), compose.trim() + "\n");
|
|
10
|
+
console.log("Docker compose created.");
|
|
11
|
+
return shared;
|
|
12
|
+
}
|
|
13
|
+
async function buildCompose(options, root) {
|
|
14
|
+
const { authMode, includeApi, includeWeb } = options;
|
|
15
|
+
const { service: authBlock, shared } = await authService(authMode, root);
|
|
16
|
+
return {
|
|
17
|
+
compose: `
|
|
18
|
+
services:
|
|
19
|
+
db:
|
|
20
|
+
image: postgres:16
|
|
21
|
+
container_name: seamless-db
|
|
22
|
+
ports:
|
|
23
|
+
- "5432:5432"
|
|
24
|
+
environment:
|
|
25
|
+
POSTGRES_USER: myuser
|
|
26
|
+
POSTGRES_PASSWORD: mypassword
|
|
27
|
+
POSTGRES_DB: postgres
|
|
28
|
+
volumes:
|
|
29
|
+
- pgdata:/var/lib/postgresql/data
|
|
30
|
+
|
|
31
|
+
${authBlock}
|
|
32
|
+
|
|
33
|
+
${includeApi ? apiService(shared) : ""}
|
|
34
|
+
|
|
35
|
+
${includeWeb ? webService() : ""}
|
|
36
|
+
|
|
37
|
+
volumes:
|
|
38
|
+
pgdata:
|
|
39
|
+
`,
|
|
40
|
+
shared,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
async function authService(mode, root) {
|
|
44
|
+
if (mode === "local") {
|
|
45
|
+
const shared = await configureAuthLocalEnv(root);
|
|
46
|
+
return {
|
|
47
|
+
service: `
|
|
48
|
+
auth:
|
|
49
|
+
container_name: seamless-auth
|
|
50
|
+
build:
|
|
51
|
+
context: ./auth
|
|
52
|
+
dockerfile: Dockerfile.dev
|
|
53
|
+
ports:
|
|
54
|
+
- "5312:5312"
|
|
55
|
+
env_file:
|
|
56
|
+
- ./auth/.env
|
|
57
|
+
environment:
|
|
58
|
+
DB_HOST: db
|
|
59
|
+
ISSUER: http://auth:5312
|
|
60
|
+
volumes:
|
|
61
|
+
- ./auth:/app
|
|
62
|
+
- /app/node_modules
|
|
63
|
+
depends_on:
|
|
64
|
+
- db
|
|
65
|
+
`,
|
|
66
|
+
shared,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
return await authServiceDocker();
|
|
70
|
+
}
|
|
71
|
+
function apiService(shared) {
|
|
72
|
+
return `
|
|
73
|
+
api:
|
|
74
|
+
container_name: api
|
|
75
|
+
build: ./api
|
|
76
|
+
ports:
|
|
77
|
+
- "3000:3000"
|
|
78
|
+
env_file:
|
|
79
|
+
- ./api/.env
|
|
80
|
+
environment:
|
|
81
|
+
AUTH_SERVER_URL: http://auth:5312
|
|
82
|
+
UI_ORIGIN: http://localhost:5173
|
|
83
|
+
DB_HOST: db
|
|
84
|
+
API_SERVICE_TOKEN: ${shared.apiToken}
|
|
85
|
+
JWKS_KID: ${shared.kid}
|
|
86
|
+
volumes:
|
|
87
|
+
- ./api:/app
|
|
88
|
+
- /app/node_modules
|
|
89
|
+
depends_on:
|
|
90
|
+
- db
|
|
91
|
+
- auth
|
|
92
|
+
`;
|
|
93
|
+
}
|
|
94
|
+
function webService() {
|
|
95
|
+
return `
|
|
96
|
+
web:
|
|
97
|
+
container_name: web
|
|
98
|
+
build: ./web
|
|
99
|
+
ports:
|
|
100
|
+
- "5173:5173"
|
|
101
|
+
env_file:
|
|
102
|
+
- ./web/.env
|
|
103
|
+
environment:
|
|
104
|
+
VITE_API_URL: http://localhost:3000
|
|
105
|
+
VITE_AUTH_SERVER_URL: http://localhost:3000/
|
|
106
|
+
volumes:
|
|
107
|
+
- ./web:/app
|
|
108
|
+
- /app/node_modules
|
|
109
|
+
depends_on:
|
|
110
|
+
- auth
|
|
111
|
+
- api
|
|
112
|
+
`;
|
|
113
|
+
}
|
|
114
|
+
async function authServiceDocker() {
|
|
115
|
+
const raw = await fetchEnvExample();
|
|
116
|
+
const parsed = parseEnvString(raw);
|
|
117
|
+
const { env, shared } = buildAuthEnv(parsed, "docker");
|
|
118
|
+
const envBlock = envToDockerBlock(env);
|
|
119
|
+
return {
|
|
120
|
+
service: `
|
|
121
|
+
auth:
|
|
122
|
+
image: ghcr.io/fells-code/seamless-auth-api:v0.1.5
|
|
123
|
+
container_name: seamless-auth
|
|
124
|
+
ports:
|
|
125
|
+
- "5312:5312"
|
|
126
|
+
environment:
|
|
127
|
+
${envBlock}
|
|
128
|
+
depends_on:
|
|
129
|
+
- db
|
|
130
|
+
`,
|
|
131
|
+
shared,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
function buildAuthEnv(env, mode) {
|
|
135
|
+
const apiToken = generateSecret(32);
|
|
136
|
+
env.PORT = "5312";
|
|
137
|
+
env.NODE_ENV = mode === "docker" ? "production" : "development";
|
|
138
|
+
env.AUTH_MODE = "server";
|
|
139
|
+
env.ISSUER = "http://auth:5312";
|
|
140
|
+
env.DB_HOST = mode === "docker" ? "db" : "localhost";
|
|
141
|
+
env.DB_PORT = "5432";
|
|
142
|
+
env.API_SERVICE_TOKEN = apiToken;
|
|
143
|
+
let kid = "main";
|
|
144
|
+
env.JWKS_ACTIVE_KID = kid;
|
|
145
|
+
if (mode === "docker") {
|
|
146
|
+
const jwks = buildJWKSConfig();
|
|
147
|
+
kid = jwks.kid;
|
|
148
|
+
env.SEAMLESS_JWKS_ACTIVE_KID = jwks.kid;
|
|
149
|
+
env.JWKS_ACTIVE_KID = jwks.kid;
|
|
150
|
+
env[`SEAMLESS_JWKS_KEY_${jwks.kid}_PRIVATE`] = jwks.privateKey;
|
|
151
|
+
env.JWKS_PUBLIC_KEYS = jwks.publicJwksJson;
|
|
152
|
+
}
|
|
153
|
+
env.APP_ORIGIN = "http://localhost:3000";
|
|
154
|
+
env.ORIGINS = "http://localhost:5173";
|
|
155
|
+
return {
|
|
156
|
+
env,
|
|
157
|
+
shared: {
|
|
158
|
+
apiToken,
|
|
159
|
+
kid,
|
|
160
|
+
},
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
export function envToDockerBlock(env) {
|
|
164
|
+
return Object.entries(env)
|
|
165
|
+
.map(([k, v]) => {
|
|
166
|
+
if (v.includes("\n")) {
|
|
167
|
+
return ` ${k}: |\n${indentMultiline(v, 8)}`;
|
|
168
|
+
}
|
|
169
|
+
return ` ${k}: ${v}`;
|
|
170
|
+
})
|
|
171
|
+
.join("\n");
|
|
172
|
+
}
|
|
173
|
+
function indentMultiline(value, spaces) {
|
|
174
|
+
const indent = " ".repeat(spaces);
|
|
175
|
+
return value
|
|
176
|
+
.split("\n")
|
|
177
|
+
.map((line) => `${indent}${line}`)
|
|
178
|
+
.join("\n");
|
|
179
|
+
}
|
|
180
|
+
export function buildJWKSConfig() {
|
|
181
|
+
const kid = "main";
|
|
182
|
+
const { publicKey, privateKey } = generateJWKS();
|
|
183
|
+
return {
|
|
184
|
+
kid,
|
|
185
|
+
privateKey,
|
|
186
|
+
publicKey,
|
|
187
|
+
publicJwksJson: JSON.stringify({
|
|
188
|
+
keys: [
|
|
189
|
+
{
|
|
190
|
+
kid,
|
|
191
|
+
pem: publicKey,
|
|
192
|
+
},
|
|
193
|
+
],
|
|
194
|
+
}, null, 2),
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
export async function configureAuthLocalEnv(root) {
|
|
198
|
+
const authDir = path.join(root, "auth");
|
|
199
|
+
const envExamplePath = path.join(authDir, ".env.example");
|
|
200
|
+
const envPath = path.join(authDir, ".env");
|
|
201
|
+
if (!fs.existsSync(envExamplePath)) {
|
|
202
|
+
throw new Error(".env.example not found in auth directory");
|
|
203
|
+
}
|
|
204
|
+
const raw = fs.readFileSync(envExamplePath, "utf-8");
|
|
205
|
+
const parsed = parseEnvString(raw);
|
|
206
|
+
const { env, shared } = buildAuthEnv(parsed, "local");
|
|
207
|
+
writeEnvFile(envPath, env);
|
|
208
|
+
return shared;
|
|
209
|
+
}
|
|
210
|
+
function writeEnvFile(filePath, env) {
|
|
211
|
+
const content = Object.entries(env)
|
|
212
|
+
.map(([k, v]) => {
|
|
213
|
+
if (v.includes("\n")) {
|
|
214
|
+
return `${k}="${escapeMultiline(v)}"`;
|
|
215
|
+
}
|
|
216
|
+
return `${k}=${v}`;
|
|
217
|
+
})
|
|
218
|
+
.join("\n");
|
|
219
|
+
fs.writeFileSync(filePath, content + "\n");
|
|
220
|
+
}
|
|
221
|
+
function escapeMultiline(value) {
|
|
222
|
+
return value.replace(/\n/g, "\\n");
|
|
223
|
+
}
|
|
224
|
+
export function extractSharedFromExistingEnv(root) {
|
|
225
|
+
const env = parseEnv(path.join(root, "auth", ".env"));
|
|
226
|
+
return {
|
|
227
|
+
apiToken: env.API_SERVICE_TOKEN,
|
|
228
|
+
kid: env.JWKS_ACTIVE_KID || "main",
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
//# sourceMappingURL=docker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docker.js","sourceRoot":"","sources":["../../../src/generators/docker/docker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import { cloneRepo, removeGitDir, copyEnvExample, } from "../../utils/repoUtils.js";
|
|
3
|
+
const WEB_STARTER_REPO = "https://github.com/fells-code/seamless-auth-starter-react.git";
|
|
4
|
+
export async function generateReactStarter(context) {
|
|
5
|
+
const { root } = context;
|
|
6
|
+
const webDir = path.join(root, "web");
|
|
7
|
+
console.log("Cloning Seamless Auth React starter...");
|
|
8
|
+
await cloneRepo(WEB_STARTER_REPO, webDir);
|
|
9
|
+
removeGitDir(webDir);
|
|
10
|
+
copyEnvExample(webDir);
|
|
11
|
+
console.log("Web starter ready.");
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=react.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"react.js","sourceRoot":"","sources":["../../../src/generators/frontend/react.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EACL,SAAS,EACT,YAAY,EACZ,cAAc,GACf,MAAM,0BAA0B,CAAC;AAElC,MAAM,gBAAgB,GACpB,+DAA+D,CAAC;AAElE,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,OAAyB;IAClE,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;IACzB,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAEtC,OAAO,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC;IAEtD,MAAM,SAAS,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC;IAE1C,YAAY,CAAC,MAAM,CAAC,CAAC;IACrB,cAAc,CAAC,MAAM,CAAC,CAAC;IAEvB,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;AACpC,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { runCLI } from "./commands/init.js";
|
|
3
|
+
import { printHelp } from "./core/help.js";
|
|
4
|
+
const args = process.argv.slice(2);
|
|
5
|
+
const firstArg = args[0];
|
|
6
|
+
async function main() {
|
|
7
|
+
if (firstArg === "-h" || firstArg === "--help") {
|
|
8
|
+
printHelp();
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
await runCLI(firstArg);
|
|
12
|
+
}
|
|
13
|
+
main().catch((err) => {
|
|
14
|
+
console.error("Error:", err.message);
|
|
15
|
+
process.exit(1);
|
|
16
|
+
});
|
|
17
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAEnC,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;AAEzB,KAAK,UAAU,IAAI;IACjB,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC/C,SAAS,EAAE,CAAC;QACZ,OAAO;IACT,CAAC;IAED,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;AACzB,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { confirm, select } from "@clack/prompts";
|
|
2
|
+
export async function runProjectSetupPrompts() {
|
|
3
|
+
const web = await confirm({
|
|
4
|
+
message: "Do you want to create a web application?",
|
|
5
|
+
});
|
|
6
|
+
let webFramework = null;
|
|
7
|
+
if (web) {
|
|
8
|
+
const result = await select({
|
|
9
|
+
message: "Which framework?",
|
|
10
|
+
options: [
|
|
11
|
+
{ value: "react", label: "React (Vite)" },
|
|
12
|
+
{ value: "next", label: "Next.js (coming soon)", disabled: true },
|
|
13
|
+
{ value: "vue", label: "Vue (coming soon)", disabled: true },
|
|
14
|
+
{ value: "angular", label: "Angular (coming soon)", disabled: true },
|
|
15
|
+
],
|
|
16
|
+
});
|
|
17
|
+
webFramework = result;
|
|
18
|
+
}
|
|
19
|
+
const api = await confirm({
|
|
20
|
+
message: "Do you want to create an API server?",
|
|
21
|
+
});
|
|
22
|
+
let apiFramework = null;
|
|
23
|
+
if (api) {
|
|
24
|
+
const result = await select({
|
|
25
|
+
message: "Which backend?",
|
|
26
|
+
options: [
|
|
27
|
+
{ value: "express", label: "Express" },
|
|
28
|
+
{ value: "next", label: "Next.js (coming soon)", disabled: true },
|
|
29
|
+
{ value: "fastify", label: "Fastify (coming soon)", disabled: true },
|
|
30
|
+
{ value: "fast-api", label: "FastAPI (coming soon)", disabled: true },
|
|
31
|
+
],
|
|
32
|
+
});
|
|
33
|
+
apiFramework = result;
|
|
34
|
+
}
|
|
35
|
+
const authMode = (await select({
|
|
36
|
+
message: "How would you like to run SeamlessAuth?",
|
|
37
|
+
options: [
|
|
38
|
+
{
|
|
39
|
+
value: "local",
|
|
40
|
+
label: "Local development server (npm run dev yourself)",
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
value: "docker",
|
|
44
|
+
label: "Docker container (recommended - just run docker compose up)",
|
|
45
|
+
},
|
|
46
|
+
],
|
|
47
|
+
}));
|
|
48
|
+
let useDocker = await confirm({
|
|
49
|
+
message: "Do you want to run your stack with Docker?",
|
|
50
|
+
});
|
|
51
|
+
if (authMode === "docker" && !useDocker) {
|
|
52
|
+
console.log("\nAuth server requires Docker — enabling Docker mode automatically.\n");
|
|
53
|
+
useDocker = true;
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
web,
|
|
57
|
+
webFramework,
|
|
58
|
+
api,
|
|
59
|
+
apiFramework,
|
|
60
|
+
authMode,
|
|
61
|
+
useDocker,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=projectSetup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projectSetup.js","sourceRoot":"","sources":["../../src/prompts/projectSetup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAQ,MAAM,gBAAgB,CAAC;AAMvD,MAAM,CAAC,KAAK,UAAU,sBAAsB;IAC1C,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC;QACxB,OAAO,EAAE,0CAA0C;KACpD,CAAC,CAAC;IAEH,IAAI,YAAY,GAAiB,IAAI,CAAC;IAEtC,IAAI,GAAG,EAAE,CAAC;QACR,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC;YAC1B,OAAO,EAAE,kBAAkB;YAC3B,OAAO,EAAE;gBACP,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE;gBACzC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,uBAAuB,EAAE,QAAQ,EAAE,IAAI,EAAE;gBACjE,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,mBAAmB,EAAE,QAAQ,EAAE,IAAI,EAAE;gBAC5D,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,uBAAuB,EAAE,QAAQ,EAAE,IAAI,EAAE;aACrE;SACF,CAAC,CAAC;QAEH,YAAY,GAAG,MAAsB,CAAC;IACxC,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC;QACxB,OAAO,EAAE,sCAAsC;KAChD,CAAC,CAAC;IAEH,IAAI,YAAY,GAAiB,IAAI,CAAC;IAEtC,IAAI,GAAG,EAAE,CAAC;QACR,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC;YAC1B,OAAO,EAAE,gBAAgB;YACzB,OAAO,EAAE;gBACP,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE;gBACtC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,uBAAuB,EAAE,QAAQ,EAAE,IAAI,EAAE;gBACjE,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,uBAAuB,EAAE,QAAQ,EAAE,IAAI,EAAE;gBACpE,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,uBAAuB,EAAE,QAAQ,EAAE,IAAI,EAAE;aACtE;SACF,CAAC,CAAC;QAEH,YAAY,GAAG,MAAsB,CAAC;IACxC,CAAC;IAED,MAAM,QAAQ,GAAG,CAAC,MAAM,MAAM,CAAC;QAC7B,OAAO,EAAE,yCAAyC;QAClD,OAAO,EAAE;YACP;gBACE,KAAK,EAAE,OAAO;gBACd,KAAK,EAAE,iDAAiD;aACzD;YACD;gBACE,KAAK,EAAE,QAAQ;gBACf,KAAK,EAAE,6DAA6D;aACrE;SACF;KACF,CAAC,CAAa,CAAC;IAEhB,IAAI,SAAS,GAAG,MAAM,OAAO,CAAC;QAC5B,OAAO,EAAE,4CAA4C;KACtD,CAAC,CAAC;IAEH,IAAI,QAAQ,KAAK,QAAQ,IAAI,CAAC,SAAS,EAAE,CAAC;QACxC,OAAO,CAAC,GAAG,CACT,uEAAuE,CACxE,CAAC;QACF,SAAS,GAAG,IAAI,CAAC;IACnB,CAAC;IAED,OAAO;QACL,GAAG;QACH,YAAY;QACZ,GAAG;QACH,YAAY;QACZ,QAAQ;QACR,SAAS;KACV,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { runCommand } from "../core/exec.js";
|
|
4
|
+
export async function cloneRepo(repoUrl, dest) {
|
|
5
|
+
const parentDir = path.dirname(dest);
|
|
6
|
+
const folderName = path.basename(dest);
|
|
7
|
+
fs.mkdirSync(parentDir, { recursive: true });
|
|
8
|
+
await runCommand("git", ["clone", "--depth", "1", repoUrl, folderName], parentDir);
|
|
9
|
+
}
|
|
10
|
+
export function removeGitDir(projectRoot) {
|
|
11
|
+
const gitDir = path.join(projectRoot, ".git");
|
|
12
|
+
if (fs.existsSync(gitDir)) {
|
|
13
|
+
fs.rmSync(gitDir, { recursive: true, force: true });
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export function copyEnvExample(projectRoot) {
|
|
17
|
+
const envExample = path.join(projectRoot, ".env.example");
|
|
18
|
+
const env = path.join(projectRoot, ".env");
|
|
19
|
+
if (fs.existsSync(envExample) && !fs.existsSync(env)) {
|
|
20
|
+
fs.copyFileSync(envExample, env);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=repoUtils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repoUtils.js","sourceRoot":"","sources":["../../src/utils/repoUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,OAAe,EAAE,IAAY;IAC3D,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAEvC,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE7C,MAAM,UAAU,CACd,KAAK,EACL,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,OAAO,EAAE,UAAU,CAAC,EAC9C,SAAS,CACV,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,WAAmB;IAC9C,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IAC9C,IAAI,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1B,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACtD,CAAC;AACH,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,WAAmB;IAChD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;IAC1D,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IAE3C,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACrD,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;IACnC,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
export function writeEnv(dir, values) {
|
|
4
|
+
const env = Object.entries(values)
|
|
5
|
+
.map(([k, v]) => `${k}=${v}`)
|
|
6
|
+
.join("\n");
|
|
7
|
+
fs.writeFileSync(path.join(dir, ".env"), env + "\n");
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=writeEnv.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"writeEnv.js","sourceRoot":"","sources":["../../src/utils/writeEnv.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB,MAAM,UAAU,QAAQ,CAAC,GAAW,EAAE,MAA2B;IAC/D,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;SAC/B,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;SAC5B,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC,CAAC;AACvD,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-seamless",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "The starter script for Seamless Auth",
|
|
5
5
|
"homepage": "https://github.com/fells-code/create-seamless#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -19,9 +19,10 @@
|
|
|
19
19
|
"scripts": {
|
|
20
20
|
"build": "tsc",
|
|
21
21
|
"dev": "tsx src/index.ts",
|
|
22
|
-
"clean": "rm -rf dist"
|
|
22
|
+
"clean": "rm -rf dist",
|
|
23
|
+
"prepublishOnly": "npm run build"
|
|
23
24
|
},
|
|
24
|
-
"main": "index.js",
|
|
25
|
+
"main": "dist/index.js",
|
|
25
26
|
"files": [
|
|
26
27
|
"dist",
|
|
27
28
|
"templates",
|