create-authhero 0.26.0 → 0.28.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/dist/cloudflare/wrangler.toml +1 -0
- package/dist/create-authhero.js +251 -240
- package/package.json +1 -1
package/dist/create-authhero.js
CHANGED
|
@@ -1,156 +1,165 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { Command as
|
|
2
|
+
import { Command as R } from "commander";
|
|
3
3
|
import u from "inquirer";
|
|
4
|
-
import
|
|
4
|
+
import a from "fs";
|
|
5
5
|
import l from "path";
|
|
6
|
-
import { spawn as
|
|
7
|
-
const
|
|
6
|
+
import { spawn as T } from "child_process";
|
|
7
|
+
const E = new R(), p = {
|
|
8
8
|
local: {
|
|
9
9
|
name: "Local (SQLite)",
|
|
10
10
|
description: "Local development setup with SQLite database - great for getting started",
|
|
11
11
|
templateDir: "local",
|
|
12
|
-
packageJson: (
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
12
|
+
packageJson: (o, e, r, n) => {
|
|
13
|
+
const t = n ? "workspace:*" : "latest";
|
|
14
|
+
return {
|
|
15
|
+
name: o,
|
|
16
|
+
version: "1.0.0",
|
|
17
|
+
type: "module",
|
|
18
|
+
scripts: {
|
|
19
|
+
dev: "npx tsx watch src/index.ts",
|
|
20
|
+
start: "npx tsx src/index.ts",
|
|
21
|
+
migrate: "npx tsx src/migrate.ts",
|
|
22
|
+
seed: "npx tsx src/seed.ts"
|
|
23
|
+
},
|
|
24
|
+
dependencies: {
|
|
25
|
+
"@authhero/kysely-adapter": t,
|
|
26
|
+
"@authhero/widget": t,
|
|
27
|
+
"@hono/swagger-ui": "^0.5.0",
|
|
28
|
+
"@hono/zod-openapi": "^0.19.0",
|
|
29
|
+
"@hono/node-server": "latest",
|
|
30
|
+
authhero: t,
|
|
31
|
+
"better-sqlite3": "latest",
|
|
32
|
+
hono: "^4.6.0",
|
|
33
|
+
kysely: "latest",
|
|
34
|
+
...e && { "@authhero/multi-tenancy": t },
|
|
35
|
+
...r && { bcryptjs: "latest" }
|
|
36
|
+
},
|
|
37
|
+
devDependencies: {
|
|
38
|
+
"@types/better-sqlite3": "^7.6.0",
|
|
39
|
+
"@types/node": "^20.0.0",
|
|
40
|
+
tsx: "^4.0.0",
|
|
41
|
+
typescript: "^5.5.0"
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
},
|
|
42
45
|
seedFile: "seed.ts"
|
|
43
46
|
},
|
|
44
47
|
cloudflare: {
|
|
45
48
|
name: "Cloudflare Workers (D1)",
|
|
46
49
|
description: "Cloudflare Workers setup with D1 database",
|
|
47
50
|
templateDir: "cloudflare",
|
|
48
|
-
packageJson: (
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
51
|
+
packageJson: (o, e, r, n) => {
|
|
52
|
+
const t = n ? "workspace:*" : "latest";
|
|
53
|
+
return {
|
|
54
|
+
name: o,
|
|
55
|
+
version: "1.0.0",
|
|
56
|
+
type: "module",
|
|
57
|
+
scripts: {
|
|
58
|
+
postinstall: "node copy-assets.js",
|
|
59
|
+
"copy-assets": "node copy-assets.js",
|
|
60
|
+
dev: "wrangler dev --port 3000 --local-protocol https",
|
|
61
|
+
"dev:remote": "wrangler dev --port 3000 --local-protocol https --remote --config wrangler.local.toml",
|
|
62
|
+
deploy: "wrangler deploy --config wrangler.local.toml",
|
|
63
|
+
"db:migrate:local": "wrangler d1 migrations apply AUTH_DB --local",
|
|
64
|
+
"db:migrate:remote": "wrangler d1 migrations apply AUTH_DB --remote --config wrangler.local.toml",
|
|
65
|
+
migrate: "wrangler d1 migrations apply AUTH_DB --local",
|
|
66
|
+
"seed:local": "node seed-helper.js",
|
|
67
|
+
"seed:remote": "node seed-helper.js '' '' remote",
|
|
68
|
+
seed: "node seed-helper.js",
|
|
69
|
+
setup: "cp wrangler.toml wrangler.local.toml && cp .dev.vars.example .dev.vars && echo '✅ Created wrangler.local.toml and .dev.vars - update with your IDs'"
|
|
70
|
+
},
|
|
71
|
+
dependencies: {
|
|
72
|
+
"@authhero/drizzle": t,
|
|
73
|
+
"@authhero/kysely-adapter": t,
|
|
74
|
+
"@authhero/widget": t,
|
|
75
|
+
"@hono/swagger-ui": "^0.5.0",
|
|
76
|
+
"@hono/zod-openapi": "^0.19.0",
|
|
77
|
+
authhero: t,
|
|
78
|
+
hono: "^4.6.0",
|
|
79
|
+
kysely: "latest",
|
|
80
|
+
"kysely-d1": "latest",
|
|
81
|
+
...e && { "@authhero/multi-tenancy": t },
|
|
82
|
+
...r && { bcryptjs: "latest" }
|
|
83
|
+
},
|
|
84
|
+
devDependencies: {
|
|
85
|
+
"@cloudflare/workers-types": "^4.0.0",
|
|
86
|
+
"drizzle-kit": "^0.31.0",
|
|
87
|
+
"drizzle-orm": "^0.44.0",
|
|
88
|
+
typescript: "^5.5.0",
|
|
89
|
+
wrangler: "^3.0.0"
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
},
|
|
87
93
|
seedFile: "seed.ts"
|
|
88
94
|
},
|
|
89
95
|
"aws-sst": {
|
|
90
96
|
name: "AWS SST (Lambda + DynamoDB)",
|
|
91
97
|
description: "Serverless AWS deployment with Lambda, DynamoDB, and SST",
|
|
92
98
|
templateDir: "aws-sst",
|
|
93
|
-
packageJson: (
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
99
|
+
packageJson: (o, e, r, n) => {
|
|
100
|
+
const t = n ? "workspace:*" : "latest";
|
|
101
|
+
return {
|
|
102
|
+
name: o,
|
|
103
|
+
version: "1.0.0",
|
|
104
|
+
type: "module",
|
|
105
|
+
scripts: {
|
|
106
|
+
dev: "sst dev",
|
|
107
|
+
deploy: "sst deploy --stage production",
|
|
108
|
+
remove: "sst remove",
|
|
109
|
+
seed: "npx tsx src/seed.ts",
|
|
110
|
+
"copy-assets": "node copy-assets.js"
|
|
111
|
+
},
|
|
112
|
+
dependencies: {
|
|
113
|
+
"@authhero/aws": t,
|
|
114
|
+
"@authhero/widget": t,
|
|
115
|
+
"@aws-sdk/client-dynamodb": "^3.0.0",
|
|
116
|
+
"@aws-sdk/lib-dynamodb": "^3.0.0",
|
|
117
|
+
"@hono/swagger-ui": "^0.5.0",
|
|
118
|
+
"@hono/zod-openapi": "^0.19.0",
|
|
119
|
+
authhero: t,
|
|
120
|
+
hono: "^4.6.0",
|
|
121
|
+
...e && { "@authhero/multi-tenancy": t },
|
|
122
|
+
...r && { bcryptjs: "latest" }
|
|
123
|
+
},
|
|
124
|
+
devDependencies: {
|
|
125
|
+
"@types/aws-lambda": "^8.10.0",
|
|
126
|
+
"@types/node": "^20.0.0",
|
|
127
|
+
sst: "^3.0.0",
|
|
128
|
+
tsx: "^4.0.0",
|
|
129
|
+
typescript: "^5.5.0"
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
},
|
|
124
133
|
seedFile: "seed.ts"
|
|
125
134
|
}
|
|
126
135
|
};
|
|
127
|
-
function
|
|
128
|
-
|
|
129
|
-
const
|
|
130
|
-
|
|
136
|
+
function P(o, e) {
|
|
137
|
+
a.readdirSync(o).forEach((n) => {
|
|
138
|
+
const t = l.join(o, n), s = l.join(e, n);
|
|
139
|
+
a.lstatSync(t).isDirectory() ? (a.mkdirSync(s, { recursive: !0 }), P(t, s)) : a.copyFileSync(t, s);
|
|
131
140
|
});
|
|
132
141
|
}
|
|
133
|
-
function
|
|
134
|
-
const
|
|
142
|
+
function O(o, e = !1, r = "authhero-local") {
|
|
143
|
+
const n = o ? "control_plane" : "main", t = o ? "Control Plane" : "Main", s = [
|
|
135
144
|
"https://manage.authhero.net/auth-callback",
|
|
136
145
|
"https://local.authhero.net/auth-callback",
|
|
137
146
|
"http://localhost:5173/auth-callback",
|
|
138
147
|
"https://localhost:3000/auth-callback"
|
|
139
148
|
], c = e ? [
|
|
140
|
-
`https://localhost.emobix.co.uk:8443/test/a/${
|
|
141
|
-
`https://localhost:8443/test/a/${
|
|
142
|
-
] : [], g = [...
|
|
149
|
+
`https://localhost.emobix.co.uk:8443/test/a/${r}/callback`,
|
|
150
|
+
`https://localhost:8443/test/a/${r}/callback`
|
|
151
|
+
] : [], g = [...s, ...c], w = [
|
|
143
152
|
"https://manage.authhero.net",
|
|
144
153
|
"https://local.authhero.net",
|
|
145
154
|
"http://localhost:5173",
|
|
146
155
|
"https://localhost:3000"
|
|
147
|
-
],
|
|
156
|
+
], A = e ? ["https://localhost:8443/", "https://localhost.emobix.co.uk:8443/"] : [], y = [...w, ...A], k = e ? `
|
|
148
157
|
// Create OpenID Conformance Suite test clients and user
|
|
149
158
|
console.log("Creating conformance test clients and user...");
|
|
150
159
|
|
|
151
160
|
const conformanceCallbacks = [
|
|
152
|
-
"https://localhost.emobix.co.uk:8443/test/a/${
|
|
153
|
-
"https://localhost:8443/test/a/${
|
|
161
|
+
"https://localhost.emobix.co.uk:8443/test/a/${r}/callback",
|
|
162
|
+
"https://localhost:8443/test/a/${r}/callback",
|
|
154
163
|
];
|
|
155
164
|
const conformanceLogoutUrls = [
|
|
156
165
|
"https://localhost:8443/",
|
|
@@ -162,7 +171,7 @@ function R(t, e = !1, o = "authhero-local") {
|
|
|
162
171
|
];
|
|
163
172
|
|
|
164
173
|
try {
|
|
165
|
-
await adapters.clients.create("${
|
|
174
|
+
await adapters.clients.create("${n}", {
|
|
166
175
|
client_id: "conformance-test",
|
|
167
176
|
client_secret: "conformanceTestSecret123",
|
|
168
177
|
name: "Conformance Test Client",
|
|
@@ -180,7 +189,7 @@ function R(t, e = !1, o = "authhero-local") {
|
|
|
180
189
|
}
|
|
181
190
|
|
|
182
191
|
try {
|
|
183
|
-
await adapters.clients.create("${
|
|
192
|
+
await adapters.clients.create("${n}", {
|
|
184
193
|
client_id: "conformance-test2",
|
|
185
194
|
client_secret: "conformanceTestSecret456",
|
|
186
195
|
name: "Conformance Test Client 2",
|
|
@@ -200,7 +209,7 @@ function R(t, e = !1, o = "authhero-local") {
|
|
|
200
209
|
// Create a conformance test user with ALL OIDC profile claims populated
|
|
201
210
|
// This is required for OIDCC-5.4 (VerifyScopesReturnedInUserInfoClaims) test
|
|
202
211
|
try {
|
|
203
|
-
await adapters.users.create("${
|
|
212
|
+
await adapters.users.create("${n}", {
|
|
204
213
|
user_id: "auth2|conformance-user",
|
|
205
214
|
email: "conformance@example.com",
|
|
206
215
|
email_verified: true,
|
|
@@ -235,7 +244,7 @@ function R(t, e = !1, o = "authhero-local") {
|
|
|
235
244
|
try {
|
|
236
245
|
const bcrypt = await import("bcryptjs");
|
|
237
246
|
const hashedPassword = await bcrypt.hash("ConformanceTest123!", 10);
|
|
238
|
-
await adapters.passwords.create("${
|
|
247
|
+
await adapters.passwords.create("${n}", {
|
|
239
248
|
user_id: "auth2|conformance-user",
|
|
240
249
|
password: hashedPassword,
|
|
241
250
|
});
|
|
@@ -273,21 +282,21 @@ async function main() {
|
|
|
273
282
|
await seed(adapters, {
|
|
274
283
|
adminEmail,
|
|
275
284
|
adminPassword,
|
|
276
|
-
tenantId: "${
|
|
277
|
-
tenantName: "${
|
|
278
|
-
isControlPlane: ${
|
|
285
|
+
tenantId: "${n}",
|
|
286
|
+
tenantName: "${t}",
|
|
287
|
+
isControlPlane: ${o},
|
|
279
288
|
callbacks: ${JSON.stringify(g)},
|
|
280
|
-
allowedLogoutUrls: ${JSON.stringify(
|
|
289
|
+
allowedLogoutUrls: ${JSON.stringify(y)},
|
|
281
290
|
});
|
|
282
|
-
${
|
|
291
|
+
${k}
|
|
283
292
|
await db.destroy();
|
|
284
293
|
}
|
|
285
294
|
|
|
286
295
|
main().catch(console.error);
|
|
287
296
|
`;
|
|
288
297
|
}
|
|
289
|
-
function
|
|
290
|
-
return
|
|
298
|
+
function j(o) {
|
|
299
|
+
return o ? `import { Context } from "hono";
|
|
291
300
|
import { swaggerUI } from "@hono/swagger-ui";
|
|
292
301
|
import { AuthHeroConfig, DataAdapters } from "authhero";
|
|
293
302
|
import { serveStatic } from "@hono/node-server/serve-static";
|
|
@@ -390,7 +399,7 @@ export default function createApp(config: AuthHeroConfig) {
|
|
|
390
399
|
}
|
|
391
400
|
`;
|
|
392
401
|
}
|
|
393
|
-
function
|
|
402
|
+
function U(o) {
|
|
394
403
|
return `import { D1Dialect } from "kysely-d1";
|
|
395
404
|
import { Kysely } from "kysely";
|
|
396
405
|
import createAdapters from "@authhero/kysely-adapter";
|
|
@@ -430,9 +439,9 @@ export default {
|
|
|
430
439
|
adminEmail,
|
|
431
440
|
adminPassword,
|
|
432
441
|
issuer,
|
|
433
|
-
tenantId: "${
|
|
434
|
-
tenantName: "${
|
|
435
|
-
isControlPlane: ${
|
|
442
|
+
tenantId: "${o ? "control_plane" : "main"}",
|
|
443
|
+
tenantName: "${o ? "Control Plane" : "Main"}",
|
|
444
|
+
isControlPlane: ${o},
|
|
436
445
|
});
|
|
437
446
|
|
|
438
447
|
return new Response(
|
|
@@ -463,8 +472,8 @@ export default {
|
|
|
463
472
|
};
|
|
464
473
|
`;
|
|
465
474
|
}
|
|
466
|
-
function
|
|
467
|
-
return
|
|
475
|
+
function M(o) {
|
|
476
|
+
return o ? `import { Context } from "hono";
|
|
468
477
|
import { swaggerUI } from "@hono/swagger-ui";
|
|
469
478
|
import { AuthHeroConfig, DataAdapters } from "authhero";
|
|
470
479
|
import { initMultiTenant } from "@authhero/multi-tenancy";
|
|
@@ -543,8 +552,8 @@ export default function createApp(config: AuthHeroConfig) {
|
|
|
543
552
|
}
|
|
544
553
|
`;
|
|
545
554
|
}
|
|
546
|
-
function
|
|
547
|
-
return
|
|
555
|
+
function $(o) {
|
|
556
|
+
return o ? `import { Context } from "hono";
|
|
548
557
|
import { swaggerUI } from "@hono/swagger-ui";
|
|
549
558
|
import { AuthHeroConfig, DataAdapters } from "authhero";
|
|
550
559
|
import { initMultiTenant } from "@authhero/multi-tenancy";
|
|
@@ -649,7 +658,7 @@ export default function createApp(config: AppConfig) {
|
|
|
649
658
|
}
|
|
650
659
|
`;
|
|
651
660
|
}
|
|
652
|
-
function
|
|
661
|
+
function H(o) {
|
|
653
662
|
return `import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
|
|
654
663
|
import { DynamoDBDocumentClient } from "@aws-sdk/lib-dynamodb";
|
|
655
664
|
import createAdapters from "@authhero/aws";
|
|
@@ -684,9 +693,9 @@ async function main() {
|
|
|
684
693
|
await seed(adapters, {
|
|
685
694
|
adminEmail,
|
|
686
695
|
adminPassword,
|
|
687
|
-
tenantId: "${
|
|
688
|
-
tenantName: "${
|
|
689
|
-
isControlPlane: ${
|
|
696
|
+
tenantId: "${o ? "control_plane" : "main"}",
|
|
697
|
+
tenantName: "${o ? "Control Plane" : "Main"}",
|
|
698
|
+
isControlPlane: ${o},
|
|
690
699
|
});
|
|
691
700
|
|
|
692
701
|
console.log("✅ Database seeded successfully!");
|
|
@@ -695,23 +704,23 @@ async function main() {
|
|
|
695
704
|
main().catch(console.error);
|
|
696
705
|
`;
|
|
697
706
|
}
|
|
698
|
-
function
|
|
699
|
-
const
|
|
700
|
-
|
|
701
|
-
l.join(
|
|
702
|
-
M(e)
|
|
703
|
-
), s.writeFileSync(
|
|
704
|
-
l.join(o, "seed.ts"),
|
|
707
|
+
function F(o, e) {
|
|
708
|
+
const r = l.join(o, "src");
|
|
709
|
+
a.writeFileSync(
|
|
710
|
+
l.join(r, "app.ts"),
|
|
705
711
|
$(e)
|
|
712
|
+
), a.writeFileSync(
|
|
713
|
+
l.join(r, "seed.ts"),
|
|
714
|
+
H(e)
|
|
706
715
|
);
|
|
707
716
|
}
|
|
708
|
-
function I(
|
|
709
|
-
console.log("\\n" + "─".repeat(50)), console.log("🔐 AuthHero deployed to AWS!"), console.log("📚 Check SST output for your API URL"), console.log("🌐 Portal available at https://local.authhero.net"), console.log(
|
|
717
|
+
function I(o) {
|
|
718
|
+
console.log("\\n" + "─".repeat(50)), console.log("🔐 AuthHero deployed to AWS!"), console.log("📚 Check SST output for your API URL"), console.log("🌐 Portal available at https://local.authhero.net"), console.log(o ? "🏢 Multi-tenant mode enabled with control_plane tenant" : "🏠 Single-tenant mode with 'main' tenant"), console.log("─".repeat(50) + "\\n");
|
|
710
719
|
}
|
|
711
|
-
function
|
|
712
|
-
const e = l.join(
|
|
713
|
-
|
|
714
|
-
const
|
|
720
|
+
function W(o) {
|
|
721
|
+
const e = l.join(o, ".github", "workflows");
|
|
722
|
+
a.mkdirSync(e, { recursive: !0 });
|
|
723
|
+
const r = `name: Unit tests
|
|
715
724
|
|
|
716
725
|
on: push
|
|
717
726
|
|
|
@@ -732,7 +741,7 @@ jobs:
|
|
|
732
741
|
|
|
733
742
|
- run: npm run type-check
|
|
734
743
|
- run: npm test
|
|
735
|
-
`,
|
|
744
|
+
`, n = `name: Deploy to Dev
|
|
736
745
|
|
|
737
746
|
on:
|
|
738
747
|
push:
|
|
@@ -768,7 +777,7 @@ jobs:
|
|
|
768
777
|
with:
|
|
769
778
|
apiToken: \${{ secrets.CLOUDFLARE_API_TOKEN }}
|
|
770
779
|
command: deploy
|
|
771
|
-
`,
|
|
780
|
+
`, t = `name: Deploy to Production
|
|
772
781
|
|
|
773
782
|
on:
|
|
774
783
|
release:
|
|
@@ -797,9 +806,9 @@ jobs:
|
|
|
797
806
|
apiToken: \${{ secrets.PROD_CLOUDFLARE_API_TOKEN }}
|
|
798
807
|
command: deploy --env production
|
|
799
808
|
`;
|
|
800
|
-
|
|
809
|
+
a.writeFileSync(l.join(e, "unit-tests.yml"), r), a.writeFileSync(l.join(e, "deploy-dev.yml"), n), a.writeFileSync(l.join(e, "release.yml"), t), console.log("\\n📦 GitHub CI workflows created!");
|
|
801
810
|
}
|
|
802
|
-
function
|
|
811
|
+
function q(o) {
|
|
803
812
|
const e = {
|
|
804
813
|
branches: ["main"],
|
|
805
814
|
plugins: [
|
|
@@ -808,78 +817,78 @@ function W(t) {
|
|
|
808
817
|
"@semantic-release/github"
|
|
809
818
|
]
|
|
810
819
|
};
|
|
811
|
-
|
|
812
|
-
l.join(
|
|
820
|
+
a.writeFileSync(
|
|
821
|
+
l.join(o, ".releaserc.json"),
|
|
813
822
|
JSON.stringify(e, null, 2)
|
|
814
823
|
);
|
|
815
|
-
const
|
|
816
|
-
|
|
817
|
-
...
|
|
824
|
+
const r = l.join(o, "package.json"), n = JSON.parse(a.readFileSync(r, "utf-8"));
|
|
825
|
+
n.devDependencies = {
|
|
826
|
+
...n.devDependencies,
|
|
818
827
|
"semantic-release": "^24.0.0"
|
|
819
|
-
},
|
|
820
|
-
...
|
|
828
|
+
}, n.scripts = {
|
|
829
|
+
...n.scripts,
|
|
821
830
|
test: 'echo "No tests yet"',
|
|
822
831
|
"type-check": "tsc --noEmit"
|
|
823
|
-
},
|
|
832
|
+
}, a.writeFileSync(r, JSON.stringify(n, null, 2));
|
|
824
833
|
}
|
|
825
|
-
function b(
|
|
826
|
-
return new Promise((
|
|
827
|
-
const
|
|
834
|
+
function b(o, e) {
|
|
835
|
+
return new Promise((r, n) => {
|
|
836
|
+
const t = T(o, [], {
|
|
828
837
|
cwd: e,
|
|
829
838
|
shell: !0,
|
|
830
839
|
stdio: "inherit"
|
|
831
840
|
});
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
}),
|
|
841
|
+
t.on("close", (s) => {
|
|
842
|
+
s === 0 ? r() : n(new Error(`Command failed with exit code ${s}`));
|
|
843
|
+
}), t.on("error", n);
|
|
835
844
|
});
|
|
836
845
|
}
|
|
837
|
-
function D(
|
|
838
|
-
return new Promise((
|
|
839
|
-
const
|
|
846
|
+
function D(o, e, r) {
|
|
847
|
+
return new Promise((n, t) => {
|
|
848
|
+
const s = T(o, [], {
|
|
840
849
|
cwd: e,
|
|
841
850
|
shell: !0,
|
|
842
851
|
stdio: "inherit",
|
|
843
|
-
env: { ...process.env, ...
|
|
852
|
+
env: { ...process.env, ...r }
|
|
844
853
|
});
|
|
845
|
-
|
|
846
|
-
c === 0 ?
|
|
847
|
-
}),
|
|
854
|
+
s.on("close", (c) => {
|
|
855
|
+
c === 0 ? n() : t(new Error(`Command failed with exit code ${c}`));
|
|
856
|
+
}), s.on("error", t);
|
|
848
857
|
});
|
|
849
858
|
}
|
|
850
|
-
function
|
|
851
|
-
const
|
|
852
|
-
|
|
853
|
-
l.join(
|
|
859
|
+
function B(o, e) {
|
|
860
|
+
const r = l.join(o, "src");
|
|
861
|
+
a.writeFileSync(
|
|
862
|
+
l.join(r, "app.ts"),
|
|
863
|
+
M(e)
|
|
864
|
+
), a.writeFileSync(
|
|
865
|
+
l.join(r, "seed.ts"),
|
|
854
866
|
U(e)
|
|
855
|
-
), s.writeFileSync(
|
|
856
|
-
l.join(o, "seed.ts"),
|
|
857
|
-
j(e)
|
|
858
867
|
);
|
|
859
868
|
}
|
|
860
|
-
function
|
|
869
|
+
function _(o) {
|
|
861
870
|
console.log(`
|
|
862
|
-
` + "─".repeat(50)), console.log("🔐 AuthHero server running at https://localhost:3000"), console.log("📚 API documentation available at https://localhost:3000/docs"), console.log("🌐 Portal available at https://local.authhero.net"), console.log(
|
|
871
|
+
` + "─".repeat(50)), console.log("🔐 AuthHero server running at https://localhost:3000"), console.log("📚 API documentation available at https://localhost:3000/docs"), console.log("🌐 Portal available at https://local.authhero.net"), console.log(o ? "🏢 Multi-tenant mode enabled with control_plane tenant" : "🏠 Single-tenant mode with 'main' tenant"), console.log("─".repeat(50) + `
|
|
863
872
|
`);
|
|
864
873
|
}
|
|
865
|
-
function
|
|
874
|
+
function N(o) {
|
|
866
875
|
console.log(`
|
|
867
|
-
` + "─".repeat(50)), console.log("✅ Self-signed certificates generated with openssl"), console.log("⚠️ You may need to trust the certificate in your browser"), console.log("🔐 AuthHero server running at https://localhost:3000"), console.log("📚 API documentation available at https://localhost:3000/docs"), console.log("🌐 Portal available at https://local.authhero.net"), console.log(
|
|
876
|
+
` + "─".repeat(50)), console.log("✅ Self-signed certificates generated with openssl"), console.log("⚠️ You may need to trust the certificate in your browser"), console.log("🔐 AuthHero server running at https://localhost:3000"), console.log("📚 API documentation available at https://localhost:3000/docs"), console.log("🌐 Portal available at https://local.authhero.net"), console.log(o ? "🏢 Multi-tenant mode enabled with control_plane tenant" : "🏠 Single-tenant mode with 'main' tenant"), console.log("─".repeat(50) + `
|
|
868
877
|
`);
|
|
869
878
|
}
|
|
870
|
-
|
|
879
|
+
E.version("1.0.0").description("Create a new AuthHero project").argument("[project-name]", "name of the project").option("-t, --template <type>", "template type: local or cloudflare").option("-e, --email <email>", "admin email address").option("-p, --password <password>", "admin password (min 8 characters)").option(
|
|
871
880
|
"--package-manager <pm>",
|
|
872
881
|
"package manager to use: npm, yarn, pnpm, or bun"
|
|
873
882
|
).option("--multi-tenant", "enable multi-tenant mode").option("--skip-install", "skip installing dependencies").option("--skip-migrate", "skip running database migrations").option("--skip-seed", "skip seeding the database").option("--skip-start", "skip starting the development server").option("--github-ci", "include GitHub CI workflows with semantic versioning").option("--conformance", "add OpenID conformance suite test clients").option(
|
|
874
883
|
"--conformance-alias <alias>",
|
|
875
884
|
"alias for conformance suite (default: authhero-local)"
|
|
876
|
-
).option("-y, --yes", "skip all prompts and use defaults/provided options").action(async (
|
|
877
|
-
const
|
|
885
|
+
).option("--workspace", "use workspace:* dependencies for local monorepo development").option("-y, --yes", "skip all prompts and use defaults/provided options").action(async (o, e) => {
|
|
886
|
+
const r = e.yes === !0;
|
|
878
887
|
console.log(`
|
|
879
888
|
🔐 Welcome to AuthHero!
|
|
880
889
|
`);
|
|
881
|
-
let
|
|
882
|
-
|
|
890
|
+
let n = o;
|
|
891
|
+
n || (r ? (n = "auth-server", console.log(`Using default project name: ${n}`)) : n = (await u.prompt([
|
|
883
892
|
{
|
|
884
893
|
type: "input",
|
|
885
894
|
name: "projectName",
|
|
@@ -888,10 +897,10 @@ T.version("1.0.0").description("Create a new AuthHero project").argument("[proje
|
|
|
888
897
|
validate: (d) => d !== "" || "Project name cannot be empty"
|
|
889
898
|
}
|
|
890
899
|
])).projectName);
|
|
891
|
-
const
|
|
892
|
-
|
|
893
|
-
let
|
|
894
|
-
e.template ? (["local", "cloudflare", "aws-sst"].includes(e.template) || (console.error(`❌ Invalid template: ${e.template}`), console.error("Valid options: local, cloudflare, aws-sst"), process.exit(1)),
|
|
900
|
+
const t = l.join(process.cwd(), n);
|
|
901
|
+
a.existsSync(t) && (console.error(`❌ Project "${n}" already exists.`), process.exit(1));
|
|
902
|
+
let s;
|
|
903
|
+
e.template ? (["local", "cloudflare", "aws-sst"].includes(e.template) || (console.error(`❌ Invalid template: ${e.template}`), console.error("Valid options: local, cloudflare, aws-sst"), process.exit(1)), s = e.template, console.log(`Using template: ${p[s].name}`)) : s = (await u.prompt([
|
|
895
904
|
{
|
|
896
905
|
type: "list",
|
|
897
906
|
name: "setupType",
|
|
@@ -919,7 +928,7 @@ T.version("1.0.0").description("Create a new AuthHero project").argument("[proje
|
|
|
919
928
|
}
|
|
920
929
|
])).setupType;
|
|
921
930
|
let c;
|
|
922
|
-
e.multiTenant !== void 0 ? (c = e.multiTenant, console.log(`Multi-tenant mode: ${c ? "enabled" : "disabled"}`)) :
|
|
931
|
+
e.multiTenant !== void 0 ? (c = e.multiTenant, console.log(`Multi-tenant mode: ${c ? "enabled" : "disabled"}`)) : r ? c = !1 : c = (await u.prompt([
|
|
923
932
|
{
|
|
924
933
|
type: "confirm",
|
|
925
934
|
name: "multiTenant",
|
|
@@ -932,42 +941,44 @@ T.version("1.0.0").description("Create a new AuthHero project").argument("[proje
|
|
|
932
941
|
g && console.log(
|
|
933
942
|
`OpenID Conformance Suite: enabled (alias: ${w})`
|
|
934
943
|
);
|
|
935
|
-
const
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
944
|
+
const A = e.workspace || !1;
|
|
945
|
+
A && console.log("Workspace mode: enabled (using workspace:* dependencies)");
|
|
946
|
+
const y = p[s];
|
|
947
|
+
a.mkdirSync(t, { recursive: !0 }), a.writeFileSync(
|
|
948
|
+
l.join(t, "package.json"),
|
|
949
|
+
JSON.stringify(y.packageJson(n, c, g, A), null, 2)
|
|
939
950
|
);
|
|
940
|
-
const
|
|
951
|
+
const k = y.templateDir, x = l.join(
|
|
941
952
|
import.meta.url.replace("file://", "").replace("/create-authhero.js", ""),
|
|
942
|
-
|
|
953
|
+
k
|
|
943
954
|
);
|
|
944
|
-
if (
|
|
945
|
-
const i = l.join(
|
|
946
|
-
|
|
947
|
-
const m = l.join(
|
|
948
|
-
|
|
955
|
+
if (a.existsSync(x) ? P(x, t) : (console.error(`❌ Template directory not found: ${x}`), process.exit(1)), s === "cloudflare" && B(t, c), s === "cloudflare") {
|
|
956
|
+
const i = l.join(t, "wrangler.toml"), d = l.join(t, "wrangler.local.toml");
|
|
957
|
+
a.existsSync(i) && a.copyFileSync(i, d);
|
|
958
|
+
const m = l.join(t, ".dev.vars.example"), f = l.join(t, ".dev.vars");
|
|
959
|
+
a.existsSync(m) && a.copyFileSync(m, f), console.log(
|
|
949
960
|
"📁 Created wrangler.local.toml and .dev.vars for local development"
|
|
950
961
|
);
|
|
951
962
|
}
|
|
952
963
|
let C = !1;
|
|
953
|
-
if (
|
|
964
|
+
if (s === "cloudflare" && (e.githubCi !== void 0 ? (C = e.githubCi, C && console.log("Including GitHub CI workflows with semantic versioning")) : r || (C = (await u.prompt([
|
|
954
965
|
{
|
|
955
966
|
type: "confirm",
|
|
956
967
|
name: "includeGithubCi",
|
|
957
968
|
message: "Would you like to include GitHub CI with semantic versioning?",
|
|
958
969
|
default: !1
|
|
959
970
|
}
|
|
960
|
-
])).includeGithubCi), C && (
|
|
961
|
-
const i =
|
|
971
|
+
])).includeGithubCi), C && (W(t), q(t))), s === "local") {
|
|
972
|
+
const i = O(
|
|
962
973
|
c,
|
|
963
974
|
g,
|
|
964
975
|
w
|
|
965
976
|
);
|
|
966
|
-
|
|
967
|
-
const d =
|
|
968
|
-
|
|
977
|
+
a.writeFileSync(l.join(t, "src/seed.ts"), i);
|
|
978
|
+
const d = j(c);
|
|
979
|
+
a.writeFileSync(l.join(t, "src/app.ts"), d);
|
|
969
980
|
}
|
|
970
|
-
if (
|
|
981
|
+
if (s === "aws-sst" && F(t, c), g) {
|
|
971
982
|
const i = {
|
|
972
983
|
alias: w,
|
|
973
984
|
description: "AuthHero Conformance Test",
|
|
@@ -986,32 +997,32 @@ T.version("1.0.0").description("Create a new AuthHero project").argument("[proje
|
|
|
986
997
|
resourceUrl: "http://host.docker.internal:3000/userinfo"
|
|
987
998
|
}
|
|
988
999
|
};
|
|
989
|
-
|
|
990
|
-
l.join(
|
|
1000
|
+
a.writeFileSync(
|
|
1001
|
+
l.join(t, "conformance-config.json"),
|
|
991
1002
|
JSON.stringify(i, null, 2)
|
|
992
1003
|
), console.log(
|
|
993
1004
|
"📝 Created conformance-config.json for OpenID Conformance Suite"
|
|
994
1005
|
);
|
|
995
1006
|
}
|
|
996
|
-
const
|
|
1007
|
+
const L = c ? "multi-tenant" : "single-tenant";
|
|
997
1008
|
console.log(
|
|
998
1009
|
`
|
|
999
|
-
✅ Project "${
|
|
1010
|
+
✅ Project "${n}" has been created with ${y.name} (${L}) setup!
|
|
1000
1011
|
`
|
|
1001
1012
|
);
|
|
1002
|
-
let
|
|
1003
|
-
if (e.skipInstall ?
|
|
1013
|
+
let v;
|
|
1014
|
+
if (e.skipInstall ? v = !1 : r ? v = !0 : v = (await u.prompt([
|
|
1004
1015
|
{
|
|
1005
1016
|
type: "confirm",
|
|
1006
1017
|
name: "shouldInstall",
|
|
1007
1018
|
message: "Would you like to install dependencies now?",
|
|
1008
1019
|
default: !0
|
|
1009
1020
|
}
|
|
1010
|
-
])).shouldInstall,
|
|
1021
|
+
])).shouldInstall, v) {
|
|
1011
1022
|
let i;
|
|
1012
1023
|
e.packageManager ? (["npm", "yarn", "pnpm", "bun"].includes(e.packageManager) || (console.error(
|
|
1013
1024
|
`❌ Invalid package manager: ${e.packageManager}`
|
|
1014
|
-
), console.error("Valid options: npm, yarn, pnpm, bun"), process.exit(1)), i = e.packageManager) :
|
|
1025
|
+
), console.error("Valid options: npm, yarn, pnpm, bun"), process.exit(1)), i = e.packageManager) : r ? i = "pnpm" : i = (await u.prompt([
|
|
1015
1026
|
{
|
|
1016
1027
|
type: "list",
|
|
1017
1028
|
name: "packageManager",
|
|
@@ -1029,13 +1040,13 @@ T.version("1.0.0").description("Create a new AuthHero project").argument("[proje
|
|
|
1029
1040
|
`);
|
|
1030
1041
|
try {
|
|
1031
1042
|
const d = i === "pnpm" ? "pnpm install --ignore-workspace" : `${i} install`;
|
|
1032
|
-
if (await b(d,
|
|
1043
|
+
if (await b(d, t), s === "local" && (console.log(`
|
|
1033
1044
|
🔧 Building native modules...
|
|
1034
|
-
`), await b("npm rebuild better-sqlite3",
|
|
1045
|
+
`), await b("npm rebuild better-sqlite3", t)), console.log(`
|
|
1035
1046
|
✅ Dependencies installed successfully!
|
|
1036
|
-
`),
|
|
1047
|
+
`), s === "local" || s === "cloudflare") {
|
|
1037
1048
|
let f;
|
|
1038
|
-
if (e.skipMigrate && e.skipSeed ? f = !1 :
|
|
1049
|
+
if (e.skipMigrate && e.skipSeed ? f = !1 : r ? f = !e.skipMigrate || !e.skipSeed : f = (await u.prompt([
|
|
1039
1050
|
{
|
|
1040
1051
|
type: "confirm",
|
|
1041
1052
|
name: "shouldSetup",
|
|
@@ -1064,18 +1075,18 @@ T.version("1.0.0").description("Create a new AuthHero project").argument("[proje
|
|
|
1064
1075
|
}
|
|
1065
1076
|
]), e.skipMigrate || (console.log(`
|
|
1066
1077
|
🔄 Running migrations...
|
|
1067
|
-
`), await b(`${i} run migrate`,
|
|
1078
|
+
`), await b(`${i} run migrate`, t)), e.skipSeed || (console.log(`
|
|
1068
1079
|
🌱 Seeding database...
|
|
1069
|
-
`),
|
|
1080
|
+
`), s === "local" ? await D(
|
|
1070
1081
|
`${i} run seed`,
|
|
1071
|
-
|
|
1082
|
+
t,
|
|
1072
1083
|
{
|
|
1073
1084
|
ADMIN_EMAIL: h.username,
|
|
1074
1085
|
ADMIN_PASSWORD: h.password
|
|
1075
1086
|
}
|
|
1076
1087
|
) : await D(
|
|
1077
1088
|
`${i} run seed:local`,
|
|
1078
|
-
|
|
1089
|
+
t,
|
|
1079
1090
|
{
|
|
1080
1091
|
ADMIN_EMAIL: h.username,
|
|
1081
1092
|
ADMIN_PASSWORD: h.password
|
|
@@ -1084,29 +1095,29 @@ T.version("1.0.0").description("Create a new AuthHero project").argument("[proje
|
|
|
1084
1095
|
}
|
|
1085
1096
|
}
|
|
1086
1097
|
let m;
|
|
1087
|
-
e.skipStart ||
|
|
1098
|
+
e.skipStart || r ? m = !1 : m = (await u.prompt([
|
|
1088
1099
|
{
|
|
1089
1100
|
type: "confirm",
|
|
1090
1101
|
name: "shouldStart",
|
|
1091
1102
|
message: "Would you like to start the development server?",
|
|
1092
1103
|
default: !0
|
|
1093
1104
|
}
|
|
1094
|
-
])).shouldStart, m && (
|
|
1095
|
-
`), await b(`${i} run dev`,
|
|
1105
|
+
])).shouldStart, m && (s === "cloudflare" ? _(c) : s === "aws-sst" ? I(c) : N(c), console.log(`🚀 Starting development server...
|
|
1106
|
+
`), await b(`${i} run dev`, t)), r && !m && (console.log(`
|
|
1096
1107
|
✅ Setup complete!`), console.log(`
|
|
1097
|
-
To start the development server:`), console.log(` cd ${
|
|
1108
|
+
To start the development server:`), console.log(` cd ${n}`), console.log(" npm run dev"), s === "cloudflare" ? _(c) : s === "aws-sst" ? I(c) : N(c));
|
|
1098
1109
|
} catch (d) {
|
|
1099
1110
|
console.error(`
|
|
1100
1111
|
❌ An error occurred:`, d), process.exit(1);
|
|
1101
1112
|
}
|
|
1102
1113
|
}
|
|
1103
|
-
|
|
1114
|
+
v || (console.log("Next steps:"), console.log(` cd ${n}`), s === "local" ? (console.log(" npm install"), console.log(" npm run migrate"), console.log(
|
|
1104
1115
|
" ADMIN_EMAIL=admin@example.com ADMIN_PASSWORD=yourpassword npm run seed"
|
|
1105
|
-
), console.log(" npm run dev")) :
|
|
1116
|
+
), console.log(" npm run dev")) : s === "cloudflare" ? (console.log(" npm install"), console.log(
|
|
1106
1117
|
" npm run migrate # or npm run db:migrate:remote for production"
|
|
1107
1118
|
), console.log(
|
|
1108
1119
|
" ADMIN_EMAIL=admin@example.com ADMIN_PASSWORD=yourpassword npm run seed"
|
|
1109
|
-
), console.log(" npm run dev # or npm run dev:remote for production")) :
|
|
1120
|
+
), console.log(" npm run dev # or npm run dev:remote for production")) : s === "aws-sst" && (console.log(" npm install"), console.log(" npm run dev # Deploys to AWS in development mode"), console.log(" # After deploy, get TABLE_NAME from output, then:"), console.log(
|
|
1110
1121
|
" TABLE_NAME=<your-table> ADMIN_EMAIL=admin@example.com ADMIN_PASSWORD=yourpassword npm run seed"
|
|
1111
1122
|
)), console.log(`
|
|
1112
1123
|
Server will be available at: https://localhost:3000`), console.log("Portal available at: https://local.authhero.net"), g && (console.log(`
|
|
@@ -1120,4 +1131,4 @@ Server will be available at: https://localhost:3000`), console.log("Portal avail
|
|
|
1120
1131
|
For more information, visit: https://authhero.net/docs
|
|
1121
1132
|
`));
|
|
1122
1133
|
});
|
|
1123
|
-
|
|
1134
|
+
E.parse(process.argv);
|