create-authhero 0.39.0 → 0.40.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.
@@ -1,18 +1,18 @@
1
1
  #!/usr/bin/env node
2
- import { Command as E } from "commander";
2
+ import { Command as P } from "commander";
3
3
  import m from "inquirer";
4
- import s from "fs";
4
+ import a from "fs";
5
5
  import i from "path";
6
- import { spawn as P } from "child_process";
7
- const D = new E(), p = {
6
+ import { spawn as E } from "child_process";
7
+ const D = new P(), 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: (a, e, n, r, o) => {
12
+ packageJson: (s, e, o, r, n) => {
13
13
  const t = r ? "workspace:*" : "latest";
14
14
  return {
15
- name: a,
15
+ name: s,
16
16
  version: "1.0.0",
17
17
  type: "module",
18
18
  scripts: {
@@ -23,7 +23,7 @@ const D = new E(), p = {
23
23
  },
24
24
  dependencies: {
25
25
  "@authhero/kysely-adapter": t,
26
- ...o && { "@authhero/react-admin": t },
26
+ ...n && { "@authhero/react-admin": t },
27
27
  "@authhero/widget": t,
28
28
  "@hono/swagger-ui": "^0.5.0",
29
29
  "@hono/zod-openapi": "^0.19.0",
@@ -33,7 +33,7 @@ const D = new E(), p = {
33
33
  hono: "^4.6.0",
34
34
  kysely: "latest",
35
35
  ...e && { "@authhero/multi-tenancy": t },
36
- ...n && { bcryptjs: "latest" }
36
+ ...o && { bcryptjs: "latest" }
37
37
  },
38
38
  devDependencies: {
39
39
  "@types/better-sqlite3": "^7.6.0",
@@ -49,10 +49,10 @@ const D = new E(), p = {
49
49
  name: "Cloudflare Workers (D1)",
50
50
  description: "Cloudflare Workers setup with D1 database",
51
51
  templateDir: "cloudflare",
52
- packageJson: (a, e, n, r, o) => {
52
+ packageJson: (s, e, o, r, n) => {
53
53
  const t = r ? "workspace:*" : "latest";
54
54
  return {
55
- name: a,
55
+ name: s,
56
56
  version: "1.0.0",
57
57
  type: "module",
58
58
  scripts: {
@@ -72,7 +72,7 @@ const D = new E(), p = {
72
72
  dependencies: {
73
73
  "@authhero/drizzle": t,
74
74
  "@authhero/kysely-adapter": t,
75
- ...o && { "@authhero/react-admin": t },
75
+ ...n && { "@authhero/react-admin": t },
76
76
  "@authhero/widget": t,
77
77
  "@hono/swagger-ui": "^0.5.0",
78
78
  "@hono/zod-openapi": "^0.19.0",
@@ -81,7 +81,7 @@ const D = new E(), p = {
81
81
  kysely: "latest",
82
82
  "kysely-d1": "latest",
83
83
  ...e && { "@authhero/multi-tenancy": t },
84
- ...n && { bcryptjs: "latest" }
84
+ ...o && { bcryptjs: "latest" }
85
85
  },
86
86
  devDependencies: {
87
87
  "@cloudflare/workers-types": "^4.0.0",
@@ -98,10 +98,10 @@ const D = new E(), p = {
98
98
  name: "AWS SST (Lambda + DynamoDB)",
99
99
  description: "Serverless AWS deployment with Lambda, DynamoDB, and SST",
100
100
  templateDir: "aws-sst",
101
- packageJson: (a, e, n, r, o) => {
101
+ packageJson: (s, e, o, r, n) => {
102
102
  const t = r ? "workspace:*" : "latest";
103
103
  return {
104
- name: a,
104
+ name: s,
105
105
  version: "1.0.0",
106
106
  type: "module",
107
107
  scripts: {
@@ -113,7 +113,7 @@ const D = new E(), p = {
113
113
  },
114
114
  dependencies: {
115
115
  "@authhero/aws": t,
116
- ...o && { "@authhero/react-admin": t },
116
+ ...n && { "@authhero/react-admin": t },
117
117
  "@authhero/widget": t,
118
118
  "@aws-sdk/client-dynamodb": "^3.0.0",
119
119
  "@aws-sdk/lib-dynamodb": "^3.0.0",
@@ -122,7 +122,7 @@ const D = new E(), p = {
122
122
  authhero: t,
123
123
  hono: "^4.6.0",
124
124
  ...e && { "@authhero/multi-tenancy": t },
125
- ...n && { bcryptjs: "latest" }
125
+ ...o && { bcryptjs: "latest" }
126
126
  },
127
127
  devDependencies: {
128
128
  "@types/aws-lambda": "^8.10.0",
@@ -136,34 +136,42 @@ const D = new E(), p = {
136
136
  seedFile: "seed.ts"
137
137
  }
138
138
  };
139
- function N(a, e) {
140
- s.readdirSync(a).forEach((r) => {
141
- const o = i.join(a, r), t = i.join(e, r);
142
- s.lstatSync(o).isDirectory() ? (s.mkdirSync(t, { recursive: !0 }), N(o, t)) : s.copyFileSync(o, t);
139
+ function N(s, e) {
140
+ a.readdirSync(s).forEach((r) => {
141
+ const n = i.join(s, r), t = i.join(e, r);
142
+ a.lstatSync(n).isDirectory() ? (a.mkdirSync(t, { recursive: !0 }), N(n, t)) : a.copyFileSync(n, t);
143
143
  });
144
144
  }
145
- function R(a, e = !1, n = "authhero-local", r) {
146
- const o = a ? "control_plane" : "main", t = a ? "Control Plane" : "Main", c = [
145
+ function R(s, e = !1, o = "authhero-local", r) {
146
+ const n = s ? "control_plane" : "main", t = s ? "Control Plane" : "Main", c = [
147
147
  "https://manage.authhero.net/auth-callback",
148
148
  "https://local.authhero.net/auth-callback",
149
149
  "http://localhost:5173/auth-callback",
150
150
  "http://localhost:3000/auth-callback",
151
151
  ...r ? ["http://localhost:3000/admin/auth-callback"] : []
152
152
  ], d = e ? [
153
- `https://localhost.emobix.co.uk:8443/test/a/${n}/callback`,
154
- `https://localhost:8443/test/a/${n}/callback`
153
+ `https://localhost.emobix.co.uk:8443/test/a/${o}/callback`,
154
+ `https://localhost:8443/test/a/${o}/callback`
155
155
  ] : [], f = [...c, ...d], h = [
156
156
  "https://manage.authhero.net",
157
157
  "https://local.authhero.net",
158
158
  "http://localhost:5173",
159
159
  "http://localhost:3000"
160
- ], C = e ? ["https://localhost:8443/", "https://localhost.emobix.co.uk:8443/"] : [], y = [...h, ...C], S = e ? `
160
+ ], C = e ? ["https://localhost:8443/", "https://localhost.emobix.co.uk:8443/"] : [], y = [...h, ...C], b = e ? `
161
161
  // Create OpenID Conformance Suite test clients and user
162
162
  console.log("Creating conformance test clients and user...");
163
-
163
+
164
+ // The OIDCC basic test plan calls /token without an audience param. AuthHero
165
+ // requires either an explicit audience or a tenant default_audience to mint
166
+ // an access token, so set one here for the conformance setup.
167
+ await adapters.tenants.update("${n}", {
168
+ default_audience: "urn:authhero:management",
169
+ });
170
+ console.log("✅ Set tenant default_audience for conformance");
171
+
164
172
  const conformanceCallbacks = [
165
- "https://localhost.emobix.co.uk:8443/test/a/${n}/callback",
166
- "https://localhost:8443/test/a/${n}/callback",
173
+ "https://localhost.emobix.co.uk:8443/test/a/${o}/callback",
174
+ "https://localhost:8443/test/a/${o}/callback",
167
175
  ];
168
176
  const conformanceLogoutUrls = [
169
177
  "https://localhost:8443/",
@@ -175,7 +183,7 @@ function R(a, e = !1, n = "authhero-local", r) {
175
183
  ];
176
184
 
177
185
  try {
178
- await adapters.clients.create("${o}", {
186
+ await adapters.clients.create("${n}", {
179
187
  client_id: "conformance-test",
180
188
  client_secret: "conformanceTestSecret123",
181
189
  name: "Conformance Test Client",
@@ -193,7 +201,7 @@ function R(a, e = !1, n = "authhero-local", r) {
193
201
  }
194
202
 
195
203
  try {
196
- await adapters.clients.create("${o}", {
204
+ await adapters.clients.create("${n}", {
197
205
  client_id: "conformance-test2",
198
206
  client_secret: "conformanceTestSecret456",
199
207
  name: "Conformance Test Client 2",
@@ -213,7 +221,7 @@ function R(a, e = !1, n = "authhero-local", r) {
213
221
  // Create a conformance test user with ALL OIDC profile claims populated
214
222
  // This is required for OIDCC-5.4 (VerifyScopesReturnedInUserInfoClaims) test
215
223
  try {
216
- await adapters.users.create("${o}", {
224
+ await adapters.users.create("${n}", {
217
225
  user_id: \`\${USERNAME_PASSWORD_PROVIDER}|conformance-user\`,
218
226
  email: "conformance@example.com",
219
227
  email_verified: true,
@@ -248,7 +256,7 @@ function R(a, e = !1, n = "authhero-local", r) {
248
256
  try {
249
257
  const bcrypt = await import("bcryptjs");
250
258
  const hashedPassword = await bcrypt.hash("ConformanceTest123!", 10);
251
- await adapters.passwords.create("${o}", {
259
+ await adapters.passwords.create("${n}", {
252
260
  user_id: \`\${USERNAME_PASSWORD_PROVIDER}|conformance-user\`,
253
261
  password: hashedPassword,
254
262
  });
@@ -266,9 +274,51 @@ import Database from "better-sqlite3";
266
274
  import createAdapters from "@authhero/kysely-adapter";
267
275
  import { seed } from "authhero";
268
276
 
277
+ interface ExtraClient {
278
+ client_id: string;
279
+ client_secret: string;
280
+ name?: string;
281
+ callbacks?: string[];
282
+ allowed_logout_urls?: string[];
283
+ web_origins?: string[];
284
+ }
285
+
286
+ function parseFlag(name: string): string | undefined {
287
+ const argv = process.argv.slice(2);
288
+ const eqPrefix = \`--\${name}=\`;
289
+ for (let i = 0; i < argv.length; i++) {
290
+ const arg = argv[i]!;
291
+ if (arg === \`--\${name}\`) return argv[i + 1];
292
+ if (arg.startsWith(eqPrefix)) return arg.slice(eqPrefix.length);
293
+ }
294
+ return undefined;
295
+ }
296
+
297
+ function positionalArgs(): string[] {
298
+ const out: string[] = [];
299
+ const argv = process.argv.slice(2);
300
+ for (let i = 0; i < argv.length; i++) {
301
+ const arg = argv[i]!;
302
+ if (arg.startsWith("--")) {
303
+ if (!arg.includes("=")) i++;
304
+ continue;
305
+ }
306
+ out.push(arg);
307
+ }
308
+ return out;
309
+ }
310
+
269
311
  async function main() {
270
- const adminUsername = process.argv[2] || process.env.ADMIN_USERNAME || "admin";
271
- const adminPassword = process.argv[3] || process.env.ADMIN_PASSWORD || "admin";
312
+ const positional = positionalArgs();
313
+ const adminUsername = positional[0] || process.env.ADMIN_USERNAME || "admin";
314
+ const adminPassword = positional[1] || process.env.ADMIN_PASSWORD || "admin";
315
+
316
+ const clientsJson = parseFlag("clients");
317
+ const userProfileJson = parseFlag("user-profile");
318
+ const extraClients: ExtraClient[] = clientsJson ? JSON.parse(clientsJson) : [];
319
+ const userProfile: Record<string, unknown> = userProfileJson
320
+ ? JSON.parse(userProfileJson)
321
+ : {};
272
322
 
273
323
  const dialect = new SqliteDialect({
274
324
  database: new Database("db.sqlite"),
@@ -277,32 +327,59 @@ async function main() {
277
327
  const db = new Kysely<any>({ dialect });
278
328
  const adapters = createAdapters(db);
279
329
 
280
- await seed(adapters, {
330
+ const seedResult = await seed(adapters, {
281
331
  adminUsername,
282
332
  adminPassword,
283
- tenantId: "${o}",
333
+ tenantId: "${n}",
284
334
  tenantName: "${t}",
285
- isControlPlane: ${!!a},
335
+ isControlPlane: ${!!s},
286
336
  clientId: "default",
287
337
  callbacks: ${JSON.stringify(f)},
288
338
  allowedLogoutUrls: ${JSON.stringify(y)},
289
339
  });
290
- ${S}
340
+
341
+ for (const c of extraClients) {
342
+ const existing = await adapters.clients.get(seedResult.tenantId, c.client_id);
343
+ if (existing) {
344
+ console.log(\`Client "\${c.client_id}" already exists, skipping...\`);
345
+ continue;
346
+ }
347
+ await adapters.clients.create(seedResult.tenantId, {
348
+ client_id: c.client_id,
349
+ client_secret: c.client_secret,
350
+ name: c.name ?? c.client_id,
351
+ callbacks: c.callbacks ?? [],
352
+ allowed_logout_urls: c.allowed_logout_urls ?? [],
353
+ web_origins: c.web_origins ?? [],
354
+ connections: ["Username-Password-Authentication"],
355
+ client_metadata: { universal_login_version: "2" },
356
+ });
357
+ console.log(\`✅ Created client "\${c.client_id}"\`);
358
+ }
359
+
360
+ if (Object.keys(userProfile).length > 0) {
361
+ await adapters.users.update(seedResult.tenantId, seedResult.userId, userProfile);
362
+ console.log(\`✅ Updated profile of user "\${seedResult.username}"\`);
363
+ }
364
+ ${b}
291
365
  await db.destroy();
292
366
  }
293
367
 
294
- main().catch(console.error);
368
+ main().catch((err) => {
369
+ console.error(err);
370
+ process.exit(1);
371
+ });
295
372
  `;
296
373
  }
297
- function U(a, e) {
298
- const n = e ? `import fs from "fs";
374
+ function O(s, e) {
375
+ const o = e ? `import fs from "fs";
299
376
  ` : "", r = e ? `
300
377
  const adminDistPath = path.resolve(
301
378
  __dirname,
302
379
  "../node_modules/@authhero/react-admin/dist",
303
380
  );
304
381
  const adminIndexPath = path.join(adminDistPath, "index.html");
305
- ` : "", o = e ? `
382
+ ` : "", n = e ? `
306
383
  // Add admin UI handler if the package is installed
307
384
  if (fs.existsSync(adminIndexPath)) {
308
385
  const issuer =
@@ -312,7 +389,7 @@ const adminIndexPath = path.join(adminDistPath, "index.html");
312
389
  .replace(/href="\\.\\//g, 'href="/admin/');
313
390
  const configJson = JSON.stringify({
314
391
  domain: issuer.replace(/\\/$/, ""),
315
- clientId: ${a ? "CONTROL_PLANE_CLIENT_ID," : '"default",'}
392
+ clientId: ${s ? "CONTROL_PLANE_CLIENT_ID," : '"default",'}
316
393
  basePath: "/admin",
317
394
  }).replace(/</g, "\\\\u003c");
318
395
  configWithHandlers.adminIndexHtml = rawHtml.replace(
@@ -325,13 +402,13 @@ const adminIndexPath = path.join(adminDistPath, "index.html");
325
402
  });
326
403
  }
327
404
  ` : "";
328
- return a ? `import { Context } from "hono";
405
+ return s ? `import { Context } from "hono";
329
406
  import { swaggerUI } from "@hono/swagger-ui";
330
407
  import { AuthHeroConfig, DataAdapters } from "authhero";
331
408
  import { serveStatic } from "@hono/node-server/serve-static";
332
409
  import { initMultiTenant } from "@authhero/multi-tenancy";
333
410
  import path from "path";
334
- ${n}import { fileURLToPath } from "url";
411
+ ${o}import { fileURLToPath } from "url";
335
412
 
336
413
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
337
414
 
@@ -352,7 +429,7 @@ export default function createApp(config: AuthHeroConfig & { dataAdapter: DataAd
352
429
  rewriteRequestPath: (p) => p.replace("/u/widget", ""),
353
430
  }),
354
431
  };
355
- ${o}
432
+ ${n}
356
433
  // Initialize multi-tenant AuthHero - syncs resource servers, roles, and connections by default
357
434
  const { app } = initMultiTenant({
358
435
  ...configWithHandlers,
@@ -389,7 +466,7 @@ import { AuthHeroConfig, init } from "authhero";
389
466
  import { swaggerUI } from "@hono/swagger-ui";
390
467
  import { serveStatic } from "@hono/node-server/serve-static";
391
468
  import path from "path";
392
- ${n}import { fileURLToPath } from "url";
469
+ ${o}import { fileURLToPath } from "url";
393
470
 
394
471
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
395
472
 
@@ -406,7 +483,7 @@ export default function createApp(config: AuthHeroConfig) {
406
483
  rewriteRequestPath: (p) => p.replace("/u/widget", ""),
407
484
  }),
408
485
  };
409
- ${o}
486
+ ${n}
410
487
  const { app } = init(configWithHandlers);
411
488
 
412
489
  app
@@ -430,7 +507,7 @@ ${o}
430
507
  }
431
508
  `;
432
509
  }
433
- function O(a) {
510
+ function U(s) {
434
511
  return `import { D1Dialect } from "kysely-d1";
435
512
  import { Kysely } from "kysely";
436
513
  import createAdapters from "@authhero/kysely-adapter";
@@ -457,9 +534,9 @@ export default {
457
534
  adminUsername,
458
535
  adminPassword,
459
536
  issuer,
460
- tenantId: "${a ? "control_plane" : "main"}",
461
- tenantName: "${a ? "Control Plane" : "Main"}",
462
- isControlPlane: ${!!a},
537
+ tenantId: "${s ? "control_plane" : "main"}",
538
+ tenantName: "${s ? "Control Plane" : "Main"}",
539
+ isControlPlane: ${!!s},
463
540
  clientId: "default",
464
541
  });
465
542
 
@@ -491,15 +568,15 @@ export default {
491
568
  };
492
569
  `;
493
570
  }
494
- function L(a, e) {
495
- const n = e ? `import adminIndexHtml from "./admin-index-html";
571
+ function $(s, e) {
572
+ const o = e ? `import adminIndexHtml from "./admin-index-html";
496
573
  ` : "", r = e ? ` adminIndexHtml,
497
574
  ` : "";
498
- return a ? `import { Context } from "hono";
575
+ return s ? `import { Context } from "hono";
499
576
  import { swaggerUI } from "@hono/swagger-ui";
500
577
  import { AuthHeroConfig, DataAdapters } from "authhero";
501
578
  import { initMultiTenant } from "@authhero/multi-tenancy";
502
- ${n}
579
+ ${o}
503
580
  // Control plane configuration
504
581
  const CONTROL_PLANE_TENANT_ID = "control_plane";
505
582
  const CONTROL_PLANE_CLIENT_ID = "default";
@@ -540,7 +617,7 @@ ${r} controlPlane: {
540
617
  import { cors } from "hono/cors";
541
618
  import { AuthHeroConfig, init } from "authhero";
542
619
  import { swaggerUI } from "@hono/swagger-ui";
543
- ${n}
620
+ ${o}
544
621
  export default function createApp(config: AuthHeroConfig) {
545
622
  const { app } = init({
546
623
  ...config,
@@ -576,8 +653,8 @@ ${r} });
576
653
  }
577
654
  `;
578
655
  }
579
- function j(a) {
580
- return a ? `import { Context } from "hono";
656
+ function L(s) {
657
+ return s ? `import { Context } from "hono";
581
658
  import { swaggerUI } from "@hono/swagger-ui";
582
659
  import { AuthHeroConfig, DataAdapters } from "authhero";
583
660
  import { initMultiTenant } from "@authhero/multi-tenancy";
@@ -682,7 +759,7 @@ export default function createApp(config: AppConfig) {
682
759
  }
683
760
  `;
684
761
  }
685
- function $(a) {
762
+ function j(s) {
686
763
  return `import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
687
764
  import { DynamoDBDocumentClient } from "@aws-sdk/lib-dynamodb";
688
765
  import createAdapters from "@authhero/aws";
@@ -711,9 +788,9 @@ async function main() {
711
788
  await seed(adapters, {
712
789
  adminUsername,
713
790
  adminPassword,
714
- tenantId: "${a ? "control_plane" : "main"}",
715
- tenantName: "${a ? "Control Plane" : "Main"}",
716
- isControlPlane: ${!!a},
791
+ tenantId: "${s ? "control_plane" : "main"}",
792
+ tenantName: "${s ? "Control Plane" : "Main"}",
793
+ isControlPlane: ${!!s},
717
794
  });
718
795
 
719
796
  console.log("✅ Database seeded successfully!");
@@ -722,23 +799,23 @@ async function main() {
722
799
  main().catch(console.error);
723
800
  `;
724
801
  }
725
- function H(a, e) {
726
- const n = i.join(a, "src");
727
- s.writeFileSync(
728
- i.join(n, "app.ts"),
802
+ function H(s, e) {
803
+ const o = i.join(s, "src");
804
+ a.writeFileSync(
805
+ i.join(o, "app.ts"),
806
+ L(e)
807
+ ), a.writeFileSync(
808
+ i.join(o, "seed.ts"),
729
809
  j(e)
730
- ), s.writeFileSync(
731
- i.join(n, "seed.ts"),
732
- $(e)
733
810
  );
734
811
  }
735
812
  function x() {
736
813
  console.log("\\n" + "─".repeat(50)), console.log("🔐 AuthHero deployed to AWS!"), console.log("📚 Check SST output for your API URL"), console.log("🚀 Open your server URL /setup to complete initial setup"), console.log("🌐 Portal available at https://local.authhero.net"), console.log("─".repeat(50) + "\\n");
737
814
  }
738
- function M(a) {
739
- const e = i.join(a, ".github", "workflows");
740
- s.mkdirSync(e, { recursive: !0 });
741
- const n = `name: Unit tests
815
+ function F(s) {
816
+ const e = i.join(s, ".github", "workflows");
817
+ a.mkdirSync(e, { recursive: !0 });
818
+ const o = `name: Unit tests
742
819
 
743
820
  on: push
744
821
 
@@ -795,7 +872,7 @@ jobs:
795
872
  with:
796
873
  apiToken: \${{ secrets.CLOUDFLARE_API_TOKEN }}
797
874
  command: deploy
798
- `, o = `name: Deploy to Production
875
+ `, n = `name: Deploy to Production
799
876
 
800
877
  on:
801
878
  release:
@@ -824,9 +901,9 @@ jobs:
824
901
  apiToken: \${{ secrets.PROD_CLOUDFLARE_API_TOKEN }}
825
902
  command: deploy --env production
826
903
  `;
827
- s.writeFileSync(i.join(e, "unit-tests.yml"), n), s.writeFileSync(i.join(e, "deploy-dev.yml"), r), s.writeFileSync(i.join(e, "release.yml"), o), console.log("\\n📦 GitHub CI workflows created!");
904
+ a.writeFileSync(i.join(e, "unit-tests.yml"), o), a.writeFileSync(i.join(e, "deploy-dev.yml"), r), a.writeFileSync(i.join(e, "release.yml"), n), console.log("\\n📦 GitHub CI workflows created!");
828
905
  }
829
- function F(a) {
906
+ function M(s) {
830
907
  const e = {
831
908
  branches: ["main"],
832
909
  plugins: [
@@ -835,11 +912,11 @@ function F(a) {
835
912
  "@semantic-release/github"
836
913
  ]
837
914
  };
838
- s.writeFileSync(
839
- i.join(a, ".releaserc.json"),
915
+ a.writeFileSync(
916
+ i.join(s, ".releaserc.json"),
840
917
  JSON.stringify(e, null, 2)
841
918
  );
842
- const n = i.join(a, "package.json"), r = JSON.parse(s.readFileSync(n, "utf-8"));
919
+ const o = i.join(s, "package.json"), r = JSON.parse(a.readFileSync(o, "utf-8"));
843
920
  r.devDependencies = {
844
921
  ...r.devDependencies,
845
922
  "semantic-release": "^24.0.0"
@@ -847,31 +924,31 @@ function F(a) {
847
924
  ...r.scripts,
848
925
  test: 'echo "No tests yet"',
849
926
  "type-check": "tsc --noEmit"
850
- }, s.writeFileSync(n, JSON.stringify(r, null, 2));
927
+ }, a.writeFileSync(o, JSON.stringify(r, null, 2));
851
928
  }
852
- function b(a, e) {
853
- return new Promise((n, r) => {
854
- const o = P(a, [], {
929
+ function _(s, e) {
930
+ return new Promise((o, r) => {
931
+ const n = E(s, [], {
855
932
  cwd: e,
856
933
  shell: !0,
857
934
  stdio: "inherit"
858
935
  });
859
- o.on("close", (t) => {
860
- t === 0 ? n() : r(new Error(`Command failed with exit code ${t}`));
861
- }), o.on("error", r);
936
+ n.on("close", (t) => {
937
+ t === 0 ? o() : r(new Error(`Command failed with exit code ${t}`));
938
+ }), n.on("error", r);
862
939
  });
863
940
  }
864
- function W(a, e, n) {
865
- const r = i.join(a, "src");
866
- s.writeFileSync(
941
+ function W(s, e, o) {
942
+ const r = i.join(s, "src");
943
+ a.writeFileSync(
867
944
  i.join(r, "app.ts"),
868
- L(e, n)
869
- ), s.writeFileSync(
945
+ $(e, o)
946
+ ), a.writeFileSync(
870
947
  i.join(r, "seed.ts"),
871
- O(e)
948
+ U(e)
872
949
  );
873
950
  }
874
- function _() {
951
+ function I() {
875
952
  console.log(`
876
953
  ` + "─".repeat(50)), console.log("🔐 AuthHero server running at https://localhost:3000"), console.log("🚀 Open https://localhost:3000/setup to complete initial setup"), console.log("─".repeat(50) + `
877
954
  `);
@@ -890,13 +967,13 @@ D.version("1.0.0").description("Create a new AuthHero project").argument("[proje
890
967
  ).option(
891
968
  "--workspace",
892
969
  "use workspace:* dependencies for local monorepo development"
893
- ).option("-y, --yes", "skip all prompts and use defaults/provided options").action(async (a, e) => {
894
- const n = e.yes === !0;
970
+ ).option("-y, --yes", "skip all prompts and use defaults/provided options").action(async (s, e) => {
971
+ const o = e.yes === !0;
895
972
  console.log(`
896
973
  🔐 Welcome to AuthHero!
897
974
  `);
898
- let r = a;
899
- r || (n ? (r = "auth-server", console.log(`Using default project name: ${r}`)) : r = (await m.prompt([
975
+ let r = s;
976
+ r || (o ? (r = "auth-server", console.log(`Using default project name: ${r}`)) : r = (await m.prompt([
900
977
  {
901
978
  type: "input",
902
979
  name: "projectName",
@@ -905,8 +982,8 @@ D.version("1.0.0").description("Create a new AuthHero project").argument("[proje
905
982
  validate: (u) => u !== "" || "Project name cannot be empty"
906
983
  }
907
984
  ])).projectName);
908
- const o = i.join(process.cwd(), r);
909
- s.existsSync(o) && (console.error(`❌ Project "${r}" already exists.`), process.exit(1));
985
+ const n = i.join(process.cwd(), r);
986
+ a.existsSync(n) && (console.error(`❌ Project "${r}" already exists.`), process.exit(1));
910
987
  let t;
911
988
  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)), t = e.template, console.log(`Using template: ${p[t].name}`)) : t = (await m.prompt([
912
989
  {
@@ -936,7 +1013,7 @@ D.version("1.0.0").description("Create a new AuthHero project").argument("[proje
936
1013
  }
937
1014
  ])).setupType;
938
1015
  let c;
939
- e.multiTenant !== void 0 ? c = e.multiTenant : n ? c = !1 : c = (await m.prompt([
1016
+ e.multiTenant !== void 0 ? c = e.multiTenant : o ? c = !1 : c = (await m.prompt([
940
1017
  {
941
1018
  type: "confirm",
942
1019
  name: "multiTenant",
@@ -945,7 +1022,7 @@ D.version("1.0.0").description("Create a new AuthHero project").argument("[proje
945
1022
  }
946
1023
  ])).multiTenant, c && console.log("Multi-tenant mode: enabled");
947
1024
  let d = !1;
948
- (t === "local" || t === "cloudflare") && (e.adminUi !== void 0 ? d = e.adminUi : n ? d = !0 : d = (await m.prompt([
1025
+ (t === "local" || t === "cloudflare") && (e.adminUi !== void 0 ? d = e.adminUi : o ? d = !0 : d = (await m.prompt([
949
1026
  {
950
1027
  type: "confirm",
951
1028
  name: "adminUi",
@@ -960,8 +1037,8 @@ D.version("1.0.0").description("Create a new AuthHero project").argument("[proje
960
1037
  const C = e.workspace || !1;
961
1038
  C && console.log("Workspace mode: enabled (using workspace:* dependencies)");
962
1039
  const y = p[t];
963
- s.mkdirSync(o, { recursive: !0 }), s.writeFileSync(
964
- i.join(o, "package.json"),
1040
+ a.mkdirSync(n, { recursive: !0 }), a.writeFileSync(
1041
+ i.join(n, "package.json"),
965
1042
  JSON.stringify(
966
1043
  y.packageJson(
967
1044
  r,
@@ -974,38 +1051,38 @@ D.version("1.0.0").description("Create a new AuthHero project").argument("[proje
974
1051
  2
975
1052
  )
976
1053
  );
977
- const S = y.templateDir, I = i.join(
1054
+ const b = y.templateDir, S = i.join(
978
1055
  import.meta.url.replace("file://", "").replace("/create-authhero.js", ""),
979
- S
1056
+ b
980
1057
  );
981
- if (s.existsSync(I) ? N(I, o) : (console.error(`❌ Template directory not found: ${I}`), process.exit(1)), t === "cloudflare" && W(o, c, d), t === "cloudflare") {
982
- const l = i.join(o, "wrangler.toml"), u = i.join(o, "wrangler.local.toml");
983
- s.existsSync(l) && s.copyFileSync(l, u);
984
- const g = i.join(o, ".dev.vars.example"), w = i.join(o, ".dev.vars");
985
- s.existsSync(g) && s.copyFileSync(g, w), console.log(
1058
+ if (a.existsSync(S) ? N(S, n) : (console.error(`❌ Template directory not found: ${S}`), process.exit(1)), t === "cloudflare" && W(n, c, d), t === "cloudflare") {
1059
+ const l = i.join(n, "wrangler.toml"), u = i.join(n, "wrangler.local.toml");
1060
+ a.existsSync(l) && a.copyFileSync(l, u);
1061
+ const g = i.join(n, ".dev.vars.example"), w = i.join(n, ".dev.vars");
1062
+ a.existsSync(g) && a.copyFileSync(g, w), console.log(
986
1063
  "📁 Created wrangler.local.toml and .dev.vars for local development"
987
1064
  );
988
1065
  }
989
1066
  let A = !1;
990
- if (t === "cloudflare" && (e.githubCi !== void 0 ? (A = e.githubCi, A && console.log("Including GitHub CI workflows with semantic versioning")) : n || (A = (await m.prompt([
1067
+ if (t === "cloudflare" && (e.githubCi !== void 0 ? (A = e.githubCi, A && console.log("Including GitHub CI workflows with semantic versioning")) : o || (A = (await m.prompt([
991
1068
  {
992
1069
  type: "confirm",
993
1070
  name: "includeGithubCi",
994
1071
  message: "Would you like to include GitHub CI with semantic versioning?",
995
1072
  default: !1
996
1073
  }
997
- ])).includeGithubCi), A && (M(o), F(o))), t === "local") {
1074
+ ])).includeGithubCi), A && (F(n), M(n))), t === "local") {
998
1075
  const l = R(
999
1076
  c,
1000
1077
  f,
1001
1078
  h,
1002
1079
  d
1003
1080
  );
1004
- s.writeFileSync(i.join(o, "src/seed.ts"), l);
1005
- const u = U(c, d);
1006
- s.writeFileSync(i.join(o, "src/app.ts"), u);
1081
+ a.writeFileSync(i.join(n, "src/seed.ts"), l);
1082
+ const u = O(c, d);
1083
+ a.writeFileSync(i.join(n, "src/app.ts"), u);
1007
1084
  }
1008
- if (t === "aws-sst" && H(o, c), f) {
1085
+ if (t === "aws-sst" && H(n, c), f) {
1009
1086
  const l = {
1010
1087
  alias: h,
1011
1088
  description: "AuthHero Conformance Test",
@@ -1024,8 +1101,8 @@ D.version("1.0.0").description("Create a new AuthHero project").argument("[proje
1024
1101
  resourceUrl: "http://host.docker.internal:3000/userinfo"
1025
1102
  }
1026
1103
  };
1027
- s.writeFileSync(
1028
- i.join(o, "conformance-config.json"),
1104
+ a.writeFileSync(
1105
+ i.join(n, "conformance-config.json"),
1029
1106
  JSON.stringify(l, null, 2)
1030
1107
  ), console.log(
1031
1108
  "📝 Created conformance-config.json for OpenID Conformance Suite"
@@ -1038,7 +1115,7 @@ D.version("1.0.0").description("Create a new AuthHero project").argument("[proje
1038
1115
  `
1039
1116
  );
1040
1117
  let v;
1041
- if (e.skipInstall ? v = !1 : n ? v = !0 : v = (await m.prompt([
1118
+ if (e.skipInstall ? v = !1 : o ? v = !0 : v = (await m.prompt([
1042
1119
  {
1043
1120
  type: "confirm",
1044
1121
  name: "shouldInstall",
@@ -1049,7 +1126,7 @@ D.version("1.0.0").description("Create a new AuthHero project").argument("[proje
1049
1126
  let l;
1050
1127
  e.packageManager ? (["npm", "yarn", "pnpm", "bun"].includes(e.packageManager) || (console.error(
1051
1128
  `❌ Invalid package manager: ${e.packageManager}`
1052
- ), console.error("Valid options: npm, yarn, pnpm, bun"), process.exit(1)), l = e.packageManager) : n ? l = "pnpm" : l = (await m.prompt([
1129
+ ), console.error("Valid options: npm, yarn, pnpm, bun"), process.exit(1)), l = e.packageManager) : o ? l = "pnpm" : l = (await m.prompt([
1053
1130
  {
1054
1131
  type: "list",
1055
1132
  name: "packageManager",
@@ -1067,13 +1144,13 @@ D.version("1.0.0").description("Create a new AuthHero project").argument("[proje
1067
1144
  `);
1068
1145
  try {
1069
1146
  const u = l === "pnpm" ? "pnpm install --ignore-workspace" : `${l} install`;
1070
- if (await b(u, o), t === "local" && (console.log(`
1147
+ if (await _(u, n), t === "local" && (console.log(`
1071
1148
  🔧 Building native modules...
1072
- `), await b("npm rebuild better-sqlite3", o)), console.log(`
1149
+ `), await _("npm rebuild better-sqlite3", n)), console.log(`
1073
1150
  ✅ Dependencies installed successfully!
1074
1151
  `), (t === "local" || t === "cloudflare") && !e.skipMigrate) {
1075
1152
  let w;
1076
- n ? w = !0 : w = (await m.prompt([
1153
+ o ? w = !0 : w = (await m.prompt([
1077
1154
  {
1078
1155
  type: "confirm",
1079
1156
  name: "shouldMigrate",
@@ -1082,20 +1159,20 @@ D.version("1.0.0").description("Create a new AuthHero project").argument("[proje
1082
1159
  }
1083
1160
  ])).shouldMigrate, w && (console.log(`
1084
1161
  🔄 Running migrations...
1085
- `), await b(`${l} run migrate`, o));
1162
+ `), await _(`${l} run migrate`, n));
1086
1163
  }
1087
1164
  let g;
1088
- e.skipStart || n ? g = !1 : g = (await m.prompt([
1165
+ e.skipStart || o ? g = !1 : g = (await m.prompt([
1089
1166
  {
1090
1167
  type: "confirm",
1091
1168
  name: "shouldStart",
1092
1169
  message: "Would you like to start the development server?",
1093
1170
  default: !0
1094
1171
  }
1095
- ])).shouldStart, g && (t === "cloudflare" ? _() : t === "aws-sst" ? x() : k(), console.log(`🚀 Starting development server...
1096
- `), await b(`${l} run dev`, o)), n && !g && (console.log(`
1172
+ ])).shouldStart, g && (t === "cloudflare" ? I() : t === "aws-sst" ? x() : k(), console.log(`🚀 Starting development server...
1173
+ `), await _(`${l} run dev`, n)), o && !g && (console.log(`
1097
1174
  ✅ Setup complete!`), console.log(`
1098
- To start the development server:`), console.log(` cd ${r}`), console.log(" npm run dev"), t === "cloudflare" ? _() : t === "aws-sst" ? x() : k());
1175
+ To start the development server:`), console.log(` cd ${r}`), console.log(" npm run dev"), t === "cloudflare" ? I() : t === "aws-sst" ? x() : k());
1099
1176
  } catch (u) {
1100
1177
  console.error(`
1101
1178
  ❌ An error occurred:`, u), process.exit(1);
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "type": "git",
6
6
  "url": "https://github.com/markusahlstrand/authhero"
7
7
  },
8
- "version": "0.39.0",
8
+ "version": "0.40.0",
9
9
  "type": "module",
10
10
  "main": "dist/create-authhero.js",
11
11
  "bin": {