create-seamless 0.0.10 → 0.1.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/README.md +1 -1
- package/package.json +17 -11
- package/index.js +0 -519
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# create-seamless
|
|
2
2
|
|
|
3
|
-
[](LICENSE)
|
|
3
|
+
[](LICENSE)
|
|
4
4
|
[](https://www.npmjs.com/package/create-seamless)
|
|
5
5
|
|
|
6
6
|
`create-seamless` is a project scaffolding tool for building applications with **Seamless Auth**, an open source, passwordless authentication system.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-seamless",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "The starter script for Seamless Auth",
|
|
5
5
|
"homepage": "https://github.com/fells-code/create-seamless#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -12,25 +12,31 @@
|
|
|
12
12
|
},
|
|
13
13
|
"license": "AGPL-3.0-only",
|
|
14
14
|
"author": "Fells Code, LLC",
|
|
15
|
+
"bin": {
|
|
16
|
+
"create-seamless": "dist/index.js"
|
|
17
|
+
},
|
|
15
18
|
"type": "module",
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsc",
|
|
21
|
+
"dev": "tsx src/index.ts",
|
|
22
|
+
"clean": "rm -rf dist"
|
|
23
|
+
},
|
|
16
24
|
"main": "index.js",
|
|
17
25
|
"files": [
|
|
18
|
-
"index.js",
|
|
19
26
|
"dist",
|
|
27
|
+
"templates",
|
|
20
28
|
"README.md",
|
|
21
29
|
"LICENSE"
|
|
22
30
|
],
|
|
23
|
-
"scripts": {
|
|
24
|
-
"test": "echo \"Error: no test specified\" && exit 1"
|
|
25
|
-
},
|
|
26
|
-
"bin": {
|
|
27
|
-
"create-seamlessauth": "index.js"
|
|
28
|
-
},
|
|
29
31
|
"dependencies": {
|
|
30
|
-
"
|
|
32
|
+
"@clack/prompts": "^1.0.1",
|
|
33
|
+
"adm-zip": "^0.5.16",
|
|
34
|
+
"kleur": "^4.1.5"
|
|
31
35
|
},
|
|
32
36
|
"devDependencies": {
|
|
33
37
|
"@types/adm-zip": "^0.5.7",
|
|
34
|
-
"@types/node": "^24.10.
|
|
38
|
+
"@types/node": "^24.10.13",
|
|
39
|
+
"tsx": "^4.21.0",
|
|
40
|
+
"typescript": "^5.9.3"
|
|
35
41
|
}
|
|
36
|
-
}
|
|
42
|
+
}
|
package/index.js
DELETED
|
@@ -1,519 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import fs from "fs";
|
|
3
|
-
import path from "path";
|
|
4
|
-
import { execSync } from "child_process";
|
|
5
|
-
import { pipeline } from "stream";
|
|
6
|
-
import { promisify } from "util";
|
|
7
|
-
import { createWriteStream } from "fs";
|
|
8
|
-
import AdmZip from "adm-zip";
|
|
9
|
-
import { randomBytes } from "crypto";
|
|
10
|
-
import net from "net";
|
|
11
|
-
|
|
12
|
-
const streamPipeline = promisify(pipeline);
|
|
13
|
-
|
|
14
|
-
const MIN_NODE_MAJOR = 18;
|
|
15
|
-
const nodeMajor = Number(process.versions.node.split(".")[0]);
|
|
16
|
-
|
|
17
|
-
function ensureExecutable(filePath) {
|
|
18
|
-
if (fs.existsSync(filePath)) {
|
|
19
|
-
fs.chmodSync(filePath, 0o755);
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function isPortAvailable(port) {
|
|
24
|
-
return new Promise((resolve) => {
|
|
25
|
-
const server = net
|
|
26
|
-
.createServer()
|
|
27
|
-
.once("error", () => resolve(false))
|
|
28
|
-
.once("listening", () => {
|
|
29
|
-
server.close();
|
|
30
|
-
resolve(true);
|
|
31
|
-
})
|
|
32
|
-
.listen(port);
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function printHelp() {
|
|
37
|
-
console.log(`
|
|
38
|
-
create-seamless
|
|
39
|
-
|
|
40
|
-
Scaffold a local Seamless Auth development environment.
|
|
41
|
-
|
|
42
|
-
Usage:
|
|
43
|
-
npx create-seamless [project-name] [options]
|
|
44
|
-
|
|
45
|
-
Options:
|
|
46
|
-
--auth Include the Seamless Auth server
|
|
47
|
-
--api Include the Express API example
|
|
48
|
-
--web Include the React web application
|
|
49
|
-
--no-git Skip git initialization
|
|
50
|
-
|
|
51
|
-
--auth-port <n> Auth server port (default: 5312)
|
|
52
|
-
--api-port <n> API server port (default: 3000)
|
|
53
|
-
--web-port <n> Web server port (default: 5001)
|
|
54
|
-
|
|
55
|
-
-h, --help Show this help message
|
|
56
|
-
|
|
57
|
-
If no component flags are provided, all components are included.
|
|
58
|
-
|
|
59
|
-
Docs:
|
|
60
|
-
https://docs.seamlessauth.com
|
|
61
|
-
`);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
if (nodeMajor < MIN_NODE_MAJOR) {
|
|
65
|
-
console.error(`
|
|
66
|
-
❌ Seamless requires Node ${MIN_NODE_MAJOR}+.
|
|
67
|
-
You are running Node ${process.versions.node}
|
|
68
|
-
|
|
69
|
-
Upgrade at https://nodejs.org
|
|
70
|
-
`);
|
|
71
|
-
process.exit(1);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
const args = process.argv.slice(2);
|
|
75
|
-
|
|
76
|
-
if (args.includes("-h") || args.includes("--help")) {
|
|
77
|
-
printHelp();
|
|
78
|
-
process.exit(0);
|
|
79
|
-
}
|
|
80
|
-
const projectName = args.find((a) => !a.startsWith("--")) ?? "seamless-app";
|
|
81
|
-
|
|
82
|
-
const hasFlag = (flag) => args.includes(`--${flag}`);
|
|
83
|
-
const getFlag = (flag, fallback) => {
|
|
84
|
-
const i = args.indexOf(`--${flag}`);
|
|
85
|
-
return i !== -1 ? args[i + 1] : fallback;
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
const includeAuth = hasFlag("auth");
|
|
89
|
-
const includeWeb = hasFlag("web");
|
|
90
|
-
const includeApi = hasFlag("api");
|
|
91
|
-
const skipGit = hasFlag("no-git");
|
|
92
|
-
|
|
93
|
-
const authPort = getFlag("auth-port", "5312");
|
|
94
|
-
const apiPort = getFlag("api-port", "3000");
|
|
95
|
-
const webPort = getFlag("web-port", "5001");
|
|
96
|
-
|
|
97
|
-
const wantsSomething = includeAuth || includeWeb || includeApi;
|
|
98
|
-
const AUTH = wantsSomething ? includeAuth : true;
|
|
99
|
-
const WEB = wantsSomething ? includeWeb : true;
|
|
100
|
-
const API = wantsSomething ? includeApi : true;
|
|
101
|
-
|
|
102
|
-
const REPOS = {
|
|
103
|
-
auth: "fells-code/seamless-auth-api",
|
|
104
|
-
web: "fells-code/seamless-auth-starter-react",
|
|
105
|
-
api: "fells-code/seamless-auth-starter-express",
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
const GENERATED_README = (projectName) => `# ${projectName}
|
|
109
|
-
|
|
110
|
-
This project was generated with \`create-seamless\` and provides a fully local,
|
|
111
|
-
open source authentication stack built on **Seamless Auth**.
|
|
112
|
-
|
|
113
|
-
It is designed for development environments where you want:
|
|
114
|
-
|
|
115
|
-
- Passwordless authentication
|
|
116
|
-
- No hosted dependencies
|
|
117
|
-
- No redirects or third-party auth services
|
|
118
|
-
- A production-shaped local setup
|
|
119
|
-
|
|
120
|
-
---
|
|
121
|
-
|
|
122
|
-
## Project layout
|
|
123
|
-
|
|
124
|
-
\`\`\`text
|
|
125
|
-
.
|
|
126
|
-
├─ auth/ # Seamless Auth open source server
|
|
127
|
-
├─ api/ # Backend API server (optional)
|
|
128
|
-
├─ web/ # Frontend web application (optional)
|
|
129
|
-
├─ Docker-compose.yml # Docker compose for one command spin up of dev environment
|
|
130
|
-
└─ README.md
|
|
131
|
-
\`\`\`
|
|
132
|
-
|
|
133
|
-
---
|
|
134
|
-
|
|
135
|
-
## Running the stack
|
|
136
|
-
|
|
137
|
-
### Running with Docker (optional)
|
|
138
|
-
|
|
139
|
-
This project includes a Docker Compose configuration that allows you to run the
|
|
140
|
-
entire Seamless Auth stack locally with a single command.
|
|
141
|
-
|
|
142
|
-
### Requirements
|
|
143
|
-
|
|
144
|
-
* Docker
|
|
145
|
-
* Docker Compose
|
|
146
|
-
|
|
147
|
-
### Start the stack
|
|
148
|
-
|
|
149
|
-
From the project root, run:
|
|
150
|
-
|
|
151
|
-
\`\`\`bash
|
|
152
|
-
docker compose up
|
|
153
|
-
\`\`\`
|
|
154
|
-
|
|
155
|
-
This will start the following services in development mode:
|
|
156
|
-
|
|
157
|
-
* Postgres database
|
|
158
|
-
* Seamless Auth server
|
|
159
|
-
* API server
|
|
160
|
-
* Web UI
|
|
161
|
-
|
|
162
|
-
All services are configured with hot reload. Changes to the source code will be
|
|
163
|
-
picked up automatically.
|
|
164
|
-
|
|
165
|
-
### Access the application
|
|
166
|
-
|
|
167
|
-
Once all services are running, open:
|
|
168
|
-
|
|
169
|
-
\`\`\`
|
|
170
|
-
http://localhost:5001
|
|
171
|
-
\`\`\`
|
|
172
|
-
|
|
173
|
-
This is the main entry point for the web application.
|
|
174
|
-
|
|
175
|
-
### Stopping the stack
|
|
176
|
-
|
|
177
|
-
To stop all services:
|
|
178
|
-
|
|
179
|
-
\`\`\`bash
|
|
180
|
-
docker compose down
|
|
181
|
-
\`\`\`
|
|
182
|
-
|
|
183
|
-
This will shut down all containers while preserving the local database volume.
|
|
184
|
-
|
|
185
|
-
Open separate terminals and run each service independently.
|
|
186
|
-
|
|
187
|
-
### Auth server
|
|
188
|
-
|
|
189
|
-
\`\`\`bash
|
|
190
|
-
cd auth
|
|
191
|
-
npm run dev
|
|
192
|
-
\`\`\`
|
|
193
|
-
|
|
194
|
-
Default port: \`5312\`
|
|
195
|
-
|
|
196
|
-
---
|
|
197
|
-
|
|
198
|
-
### API server
|
|
199
|
-
|
|
200
|
-
\`\`\`bash
|
|
201
|
-
cd api
|
|
202
|
-
npm run dev
|
|
203
|
-
\`\`\`
|
|
204
|
-
|
|
205
|
-
Default port: \`3000\`
|
|
206
|
-
|
|
207
|
-
---
|
|
208
|
-
|
|
209
|
-
### Web application
|
|
210
|
-
|
|
211
|
-
\`\`\`bash
|
|
212
|
-
cd web
|
|
213
|
-
npm run dev
|
|
214
|
-
\`\`\`
|
|
215
|
-
|
|
216
|
-
Default port: \`5001\`
|
|
217
|
-
|
|
218
|
-
---
|
|
219
|
-
|
|
220
|
-
## Documentation
|
|
221
|
-
|
|
222
|
-
Full Seamless Auth documentation:
|
|
223
|
-
|
|
224
|
-
https://seamlessauth.com/docs
|
|
225
|
-
|
|
226
|
-
---
|
|
227
|
-
|
|
228
|
-
## Included open source projects
|
|
229
|
-
|
|
230
|
-
- Seamless Auth Server
|
|
231
|
-
https://github.com/fells-code/seamless-auth-server
|
|
232
|
-
|
|
233
|
-
- Seamless Auth React Starter
|
|
234
|
-
https://github.com/fells-code/seamless-auth-starter-react
|
|
235
|
-
|
|
236
|
-
- Seamless Auth API Starter
|
|
237
|
-
https://github.com/fells-code/seamless-auth-starter-express
|
|
238
|
-
|
|
239
|
-
---
|
|
240
|
-
|
|
241
|
-
## License
|
|
242
|
-
|
|
243
|
-
This generated project inherits the licenses of the open source components it
|
|
244
|
-
includes.
|
|
245
|
-
|
|
246
|
-
Review each subproject for its specific license before deploying to production.
|
|
247
|
-
`;
|
|
248
|
-
|
|
249
|
-
const GENERATED_DOCKER_COMPOSE = `
|
|
250
|
-
services:
|
|
251
|
-
db:
|
|
252
|
-
image: postgres:16
|
|
253
|
-
container_name: seamless-db
|
|
254
|
-
ports:
|
|
255
|
-
- "5432:5432"
|
|
256
|
-
environment:
|
|
257
|
-
POSTGRES_USER: myuser
|
|
258
|
-
POSTGRES_PASSWORD: mypassword
|
|
259
|
-
POSTGRES_DB: postgres
|
|
260
|
-
volumes:
|
|
261
|
-
- pgdata:/var/lib/postgresql/data
|
|
262
|
-
- ./postgres_init:/docker-entrypoint-initdb.d
|
|
263
|
-
healthcheck:
|
|
264
|
-
test: ["CMD-SHELL", "pg_isready -U myuser -d postgres"]
|
|
265
|
-
interval: 5s
|
|
266
|
-
timeout: 5s
|
|
267
|
-
retries: 5
|
|
268
|
-
|
|
269
|
-
auth:
|
|
270
|
-
container_name: seamless-auth
|
|
271
|
-
build:
|
|
272
|
-
context: ./auth
|
|
273
|
-
dockerfile: Dockerfile.dev
|
|
274
|
-
ports:
|
|
275
|
-
- "${authPort}:${authPort}"
|
|
276
|
-
env_file:
|
|
277
|
-
- ./auth/.env
|
|
278
|
-
environment:
|
|
279
|
-
DB_HOST: db
|
|
280
|
-
ISSUER: http://auth:${authPort}
|
|
281
|
-
volumes:
|
|
282
|
-
- ./auth:/app
|
|
283
|
-
- /app/node_modules
|
|
284
|
-
depends_on:
|
|
285
|
-
db:
|
|
286
|
-
condition: service_healthy
|
|
287
|
-
|
|
288
|
-
api:
|
|
289
|
-
container_name: seamless-api
|
|
290
|
-
build: ./api
|
|
291
|
-
ports:
|
|
292
|
-
- "${apiPort}:${apiPort}"
|
|
293
|
-
env_file:
|
|
294
|
-
- ./api/.env
|
|
295
|
-
environment:
|
|
296
|
-
AUTH_SERVER_URL: http://auth:${authPort}
|
|
297
|
-
DB_HOST: db
|
|
298
|
-
volumes:
|
|
299
|
-
- ./api:/app
|
|
300
|
-
- /app/node_modules
|
|
301
|
-
depends_on:
|
|
302
|
-
db:
|
|
303
|
-
condition: service_healthy
|
|
304
|
-
|
|
305
|
-
web:
|
|
306
|
-
container_name: seamless-web
|
|
307
|
-
build: ./web
|
|
308
|
-
ports:
|
|
309
|
-
- "${webPort}:${webPort}"
|
|
310
|
-
env_file:
|
|
311
|
-
- ./web/.env
|
|
312
|
-
volumes:
|
|
313
|
-
- ./web:/app
|
|
314
|
-
- /app/node_modules
|
|
315
|
-
depends_on:
|
|
316
|
-
- auth
|
|
317
|
-
- api
|
|
318
|
-
|
|
319
|
-
volumes:
|
|
320
|
-
pgdata:
|
|
321
|
-
`;
|
|
322
|
-
|
|
323
|
-
function writeEnv(dir, values) {
|
|
324
|
-
const env = Object.entries(values)
|
|
325
|
-
.map(([k, v]) => `${k}=${v}`)
|
|
326
|
-
.join("\n");
|
|
327
|
-
fs.writeFileSync(path.join(dir, ".env"), env + "\n");
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
async function downloadRepo(repo, dest) {
|
|
331
|
-
const url = `https://codeload.github.com/${repo}/zip/refs/heads/main`;
|
|
332
|
-
const res = await fetch(url);
|
|
333
|
-
if (!res.ok || !res.body) {
|
|
334
|
-
throw new Error(`Failed to download ${repo}`);
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
const zipPath = path.join(dest, "_repo.zip");
|
|
338
|
-
await streamPipeline(res.body, createWriteStream(zipPath));
|
|
339
|
-
|
|
340
|
-
const zip = new AdmZip(zipPath);
|
|
341
|
-
zip.extractAllTo(dest, true);
|
|
342
|
-
fs.unlinkSync(zipPath);
|
|
343
|
-
|
|
344
|
-
const inner = fs.readdirSync(dest).find((f) => f.endsWith("-main"));
|
|
345
|
-
if (!inner) throw new Error("Unexpected repo structure");
|
|
346
|
-
|
|
347
|
-
const innerPath = path.join(dest, inner);
|
|
348
|
-
for (const file of fs.readdirSync(innerPath)) {
|
|
349
|
-
fs.renameSync(path.join(innerPath, file), path.join(dest, file));
|
|
350
|
-
}
|
|
351
|
-
fs.rmdirSync(innerPath);
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
(async () => {
|
|
355
|
-
const root = path.join(process.cwd(), projectName);
|
|
356
|
-
|
|
357
|
-
if (fs.existsSync(root)) {
|
|
358
|
-
console.error("❌ Directory already exists.");
|
|
359
|
-
process.exit(1);
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
fs.mkdirSync(root);
|
|
363
|
-
|
|
364
|
-
console.log(`\nCreating Seamless project: ${projectName}\n`);
|
|
365
|
-
const API_SERVICE_TOKEN = randomBytes(32).toString("hex");
|
|
366
|
-
|
|
367
|
-
let dbHostPort = "5432";
|
|
368
|
-
|
|
369
|
-
if (!(await isPortAvailable(5432))) {
|
|
370
|
-
dbHostPort = "5433";
|
|
371
|
-
console.log(`
|
|
372
|
-
⚠️ Port 5432 is already in use on your machine.
|
|
373
|
-
Using 5433 for Docker Postgres instead.
|
|
374
|
-
`);
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
if (AUTH) {
|
|
378
|
-
const dir = path.join(root, "auth");
|
|
379
|
-
fs.mkdirSync(dir);
|
|
380
|
-
console.log("Fetching Seamless Auth OSS...");
|
|
381
|
-
await downloadRepo(REPOS.auth, dir);
|
|
382
|
-
|
|
383
|
-
writeEnv(dir, {
|
|
384
|
-
PORT: authPort,
|
|
385
|
-
NODE_ENV: "development",
|
|
386
|
-
|
|
387
|
-
VERSION: "1.0.0",
|
|
388
|
-
APP_NAME: "Seamless Auth Example",
|
|
389
|
-
APP_ID: "local-dev",
|
|
390
|
-
APP_ORIGIN: `http://localhost:${apiPort}`,
|
|
391
|
-
ISSUER: `http://localhost:${authPort}`,
|
|
392
|
-
|
|
393
|
-
AUTH_MODE: "server",
|
|
394
|
-
DEMO: "true",
|
|
395
|
-
|
|
396
|
-
DEFAULT_ROLES: "user,betaUser",
|
|
397
|
-
AVAILABLE_ROLES: "user,admin,betaUser,team",
|
|
398
|
-
|
|
399
|
-
DB_LOGGING: "false",
|
|
400
|
-
DB_HOST: "localhost",
|
|
401
|
-
DB_PORT: dbHostPort,
|
|
402
|
-
DB_NAME: "seamless_auth",
|
|
403
|
-
DB_USER: "myuser",
|
|
404
|
-
DB_PASSWORD: "mypassword",
|
|
405
|
-
|
|
406
|
-
ACCESS_TOKEN_TTL: "30m",
|
|
407
|
-
REFRESH_TOKEN_TTL: "1h",
|
|
408
|
-
RATE_LIMIT: "100",
|
|
409
|
-
DELAY_AFTER: "50",
|
|
410
|
-
|
|
411
|
-
API_SERVICE_TOKEN: API_SERVICE_TOKEN,
|
|
412
|
-
|
|
413
|
-
JWKS_ACTIVE_KID: "dev-main",
|
|
414
|
-
|
|
415
|
-
RPID: "localhost",
|
|
416
|
-
ORIGINS: `http://localhost:${webPort}`,
|
|
417
|
-
});
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
if (API) {
|
|
421
|
-
const dir = path.join(root, "api");
|
|
422
|
-
fs.mkdirSync(dir);
|
|
423
|
-
console.log("Fetching API starter...");
|
|
424
|
-
await downloadRepo(REPOS.api, dir);
|
|
425
|
-
|
|
426
|
-
writeEnv(dir, {
|
|
427
|
-
AUTH_SERVER_URL: `http://localhost:${authPort}`,
|
|
428
|
-
APP_ORIGIN: `http://localhost:${apiPort}`,
|
|
429
|
-
UI_ORIGIN: `http://localhost:${webPort}`,
|
|
430
|
-
COOKIE_SIGNING_KEY: randomBytes(32).toString("hex"),
|
|
431
|
-
API_SERVICE_TOKEN: API_SERVICE_TOKEN,
|
|
432
|
-
|
|
433
|
-
DB_HOST: "localhost",
|
|
434
|
-
DB_PORT: dbHostPort,
|
|
435
|
-
DB_NAME: "seamless_api",
|
|
436
|
-
DB_USER: "myuser",
|
|
437
|
-
DB_PASSWORD: "mypassword",
|
|
438
|
-
|
|
439
|
-
SQL_LOGGING: "false",
|
|
440
|
-
});
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
if (WEB) {
|
|
444
|
-
const dir = path.join(root, "web");
|
|
445
|
-
fs.mkdirSync(dir);
|
|
446
|
-
console.log("Fetching Web starter...");
|
|
447
|
-
await downloadRepo(REPOS.web, dir);
|
|
448
|
-
|
|
449
|
-
writeEnv(dir, {
|
|
450
|
-
VITE_AUTH_SERVER_URL: `http://localhost:${apiPort}/`,
|
|
451
|
-
VITE_API_URL: `http://localhost:${apiPort}/`,
|
|
452
|
-
PORT: webPort,
|
|
453
|
-
});
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
fs.writeFileSync(path.join(root, "README.md"), GENERATED_README(projectName));
|
|
457
|
-
|
|
458
|
-
if (!skipGit) {
|
|
459
|
-
execSync("git init", { cwd: root });
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
if (AUTH && API && WEB) {
|
|
463
|
-
const compose = GENERATED_DOCKER_COMPOSE.replace(
|
|
464
|
-
'"5432:5432"',
|
|
465
|
-
`"${dbHostPort}:5432"`,
|
|
466
|
-
);
|
|
467
|
-
|
|
468
|
-
fs.writeFileSync(path.join(root, "docker-compose.yml"), compose);
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
if (AUTH) {
|
|
472
|
-
const authScriptPath = path.join(root, "auth", "validateEnvs.sh");
|
|
473
|
-
ensureExecutable(authScriptPath);
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
const pgDir = path.join(root, "postgres_init");
|
|
477
|
-
fs.mkdirSync(pgDir);
|
|
478
|
-
fs.writeFileSync(
|
|
479
|
-
path.join(pgDir, "init.sql"),
|
|
480
|
-
`
|
|
481
|
-
CREATE DATABASE seamless_auth;
|
|
482
|
-
CREATE DATABASE seamless_api;
|
|
483
|
-
`,
|
|
484
|
-
);
|
|
485
|
-
|
|
486
|
-
console.log(`
|
|
487
|
-
╔════════════════════════════════════════╗
|
|
488
|
-
║ S E A M L E S S ║
|
|
489
|
-
╚════════════════════════════════════════╝
|
|
490
|
-
|
|
491
|
-
Your local auth stack is ready.
|
|
492
|
-
|
|
493
|
-
Start development:
|
|
494
|
-
|
|
495
|
-
cd ${projectName}
|
|
496
|
-
|
|
497
|
-
# terminal 1
|
|
498
|
-
cd auth && npm i && npm run dev
|
|
499
|
-
|
|
500
|
-
# terminal 2
|
|
501
|
-
cd api && npm i && npm run dev
|
|
502
|
-
|
|
503
|
-
# terminal 3
|
|
504
|
-
cd web && npm i && npm run dev
|
|
505
|
-
|
|
506
|
-
or if using Docker
|
|
507
|
-
|
|
508
|
-
docker compose up
|
|
509
|
-
|
|
510
|
-
If you already have Postgres running locally,
|
|
511
|
-
the generator may map Docker to port 5433 instead.
|
|
512
|
-
|
|
513
|
-
Docs: https://docs.seamlessauth.com/docs
|
|
514
|
-
Happy hacking. 🚀
|
|
515
|
-
`);
|
|
516
|
-
})().catch((err) => {
|
|
517
|
-
console.error("\n❌ Error:", err.message);
|
|
518
|
-
process.exit(1);
|
|
519
|
-
});
|