better-auth-studio 1.0.59 → 1.0.60-beta.2

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 CHANGED
@@ -253,10 +253,10 @@ cd better-auth-studio
253
253
  pnpm install
254
254
 
255
255
  # Build the project
256
- pnpm run build
256
+ pnpm build
257
257
 
258
258
  # Start development server
259
- pnpm run dev
259
+ pnpm dev
260
260
  ```
261
261
 
262
262
  ### Contributing
@@ -1 +1 @@
1
- {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"AAeA,OAAO,EAA+B,MAAM,EAAE,MAAM,SAAS,CAAC;AAS9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AA+D9C,wBAAsB,oBAAoB,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,UAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,CAqLhG;AAeD,wBAAgB,YAAY,CAC1B,UAAU,EAAE,UAAU,EACtB,UAAU,CAAC,EAAE,MAAM,EACnB,SAAS,CAAC,EAAE,MAAM,GACjB,MAAM,CAkzLR"}
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../src/routes.ts"],"names":[],"mappings":"AAeA,OAAO,EAA+B,MAAM,EAAE,MAAM,SAAS,CAAC;AAS9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AA+D9C,wBAAsB,oBAAoB,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,UAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,CAqLhG;AAeD,wBAAgB,YAAY,CAC1B,UAAU,EAAE,UAAU,EACtB,UAAU,CAAC,EAAE,MAAM,EACnB,SAAS,CAAC,EAAE,MAAM,GACjB,MAAM,CA0zLR"}
package/dist/routes.js CHANGED
@@ -5296,13 +5296,19 @@ export const authClient = createAuthClient({
5296
5296
  .status(400)
5297
5297
  .json({ success: false, message: 'templateId, subject and html are required' });
5298
5298
  }
5299
- const authPath = join(process.cwd(), 'examples/nextjs/prisma/lib/auth.ts');
5300
- if (!existsSync(authPath)) {
5299
+ const authPathFromConfig = configPath ? join(process.cwd(), configPath) : null;
5300
+ const authPath = authPathFromConfig || (await findAuthConfigPath());
5301
+ if (!authPath || !existsSync(authPath)) {
5301
5302
  return res.status(404).json({ success: false, message: 'auth.ts not found' });
5302
5303
  }
5303
5304
  let fileContent = readFileSync(authPath, 'utf-8');
5304
- const escapedSubject = subject.replace(/`/g, '\\`').replace(/\${/g, '\\${');
5305
- const escapedHtml = html.replace(/`/g, '\\`').replace(/\${/g, '\\${');
5305
+ // Escape backticks and ${ for template literals
5306
+ // First escape backslashes, then escape backticks and ${ to avoid double-escaping
5307
+ const escapedSubject = subject
5308
+ .replace(/\\/g, '\\\\')
5309
+ .replace(/`/g, '\\`')
5310
+ .replace(/\${/g, '\\${');
5311
+ const escapedHtml = html.replace(/\\/g, '\\\\').replace(/`/g, '\\`').replace(/\${/g, '\\${');
5306
5312
  if (!fileContent.includes("from 'resend'")) {
5307
5313
  fileContent = `import { Resend } from 'resend';\n` + fileContent;
5308
5314
  }
@@ -5322,12 +5328,13 @@ export const authClient = createAuthClient({
5322
5328
  const handlers = {
5323
5329
  'password-reset': {
5324
5330
  regex: /sendResetPassword\s*:\s*async\s*\([^)]*\)\s*=>\s*\{[\s\S]*?\},?/,
5331
+ sectionRegex: /emailAndPassword\s*:\s*\{\s*/,
5325
5332
  fn: `sendResetPassword: async ({ user, url, token }, request) => {
5326
- const subject = \\\`${escapedSubject}\\\`
5333
+ const subject = \`${escapedSubject}\`
5327
5334
  .replace(/{{user.name}}/g, user?.name || '')
5328
5335
  .replace(/{{user.email}}/g, user?.email || '');
5329
5336
 
5330
- const html = \\\`${escapedHtml}\\\`
5337
+ const html = \`${escapedHtml}\`
5331
5338
  .replace(/{{user.name}}/g, user?.name || '')
5332
5339
  .replace(/{{user.email}}/g, user?.email || '')
5333
5340
  .replace(/{{url}}/g, url || '')
@@ -5342,12 +5349,13 @@ export const authClient = createAuthClient({
5342
5349
  },
5343
5350
  'email-verification': {
5344
5351
  regex: /sendVerificationEmail\s*:\s*async\s*\([^)]*\)\s*=>\s*\{[\s\S]*?\},?/,
5352
+ sectionRegex: /emailVerification\s*:\s*\{\s*/,
5345
5353
  fn: `sendVerificationEmail: async ({ user, url, token }, request) => {
5346
- const subject = \\\`${escapedSubject}\\\`
5354
+ const subject = \`${escapedSubject}\`
5347
5355
  .replace(/{{user.name}}/g, user?.name || '')
5348
5356
  .replace(/{{user.email}}/g, user?.email || '');
5349
5357
 
5350
- const html = \\\`${escapedHtml}\\\`
5358
+ const html = \`${escapedHtml}\`
5351
5359
  .replace(/{{user.name}}/g, user?.name || '')
5352
5360
  .replace(/{{user.email}}/g, user?.email || '')
5353
5361
  .replace(/{{url}}/g, url || '')
@@ -5362,11 +5370,12 @@ export const authClient = createAuthClient({
5362
5370
  },
5363
5371
  'magic-link': {
5364
5372
  regex: /sendMagicLink\s*:\s*async\s*\([^)]*\)\s*=>\s*\{[\s\S]*?\},?/,
5373
+ sectionRegex: /magicLink\s*:\s*\{\s*/,
5365
5374
  fn: `sendMagicLink: async ({ email, token, url }, ctx) => {
5366
- const subject = \\\`${escapedSubject}\\\`
5375
+ const subject = \`${escapedSubject}\`
5367
5376
  .replace(/{{user.email}}/g, email || '');
5368
5377
 
5369
- const html = \\\`${escapedHtml}\\\`
5378
+ const html = \`${escapedHtml}\`
5370
5379
  .replace(/{{user.email}}/g, email || '')
5371
5380
  .replace(/{{url}}/g, url || '')
5372
5381
  .replace(/{{token}}/g, token || '');
@@ -5400,16 +5409,16 @@ export const authClient = createAuthClient({
5400
5409
  }) => {
5401
5410
  const { invitation, organization, inviter } = data;
5402
5411
  const baseUrl = process.env.BETTER_AUTH_URL || 'http://localhost:3000';
5403
- const url = \\\`\\\${baseUrl}/accept-invitation?id=\\\${invitation.id}\\\`;
5412
+ const url = \`\${baseUrl}/accept-invitation?id=\${invitation.id}\`;
5404
5413
 
5405
- const subject = \\\`${escapedSubject}\\\`
5414
+ const subject = \`${escapedSubject}\`
5406
5415
  .replace(/{{organization.name}}/g, organization?.name || '')
5407
5416
  .replace(/{{invitation.role}}/g, invitation.role || '')
5408
5417
  .replace(/{{inviter.user.name}}/g, inviter?.user?.name || '')
5409
5418
  .replace(/{{inviter.user.email}}/g, inviter?.user?.email || '')
5410
5419
  .replace(/{{invitation.email}}/g, invitation.email || '');
5411
5420
 
5412
- const html = \\\`${escapedHtml}\\\`
5421
+ const html = \`${escapedHtml}\`
5413
5422
  .replace(/{{invitation.url}}/g, url)
5414
5423
  .replace(/{{invitation.role}}/g, invitation.role || '')
5415
5424
  .replace(/{{organization.name}}/g, organization?.name || '')
@@ -5418,7 +5427,7 @@ export const authClient = createAuthClient({
5418
5427
  .replace(/{{inviter.user.email}}/g, inviter?.user?.email || '')
5419
5428
  .replace(/{{invitation.email}}/g, invitation.email || '')
5420
5429
  .replace(/{{invitation.expiresAt}}/g, invitation.expiresAt?.toLocaleString() || '')
5421
- .replace(/{{expiresIn}}/g, invitation.expiresAt ? \\\`\\\${Math.ceil((invitation.expiresAt.getTime() - Date.now()) / (1000 * 60 * 60 * 24))} days\\\` : '');
5430
+ .replace(/{{expiresIn}}/g, invitation.expiresAt ? \`\${Math.ceil((invitation.expiresAt.getTime() - Date.now()) / (1000 * 60 * 60 * 24))} days\` : '');
5422
5431
 
5423
5432
  void sendEmail({
5424
5433
  to: invitation.email,
@@ -5444,27 +5453,25 @@ export const authClient = createAuthClient({
5444
5453
  if (handler.regex.test(fileContent)) {
5445
5454
  fileContent = fileContent.replace(handler.regex, `${handler.fn},`);
5446
5455
  }
5447
- else {
5448
- if (templateId === 'org-invitation') {
5449
- const orgPluginRegex = /organization\(\s*\{\s*/;
5450
- if (!orgPluginRegex.test(fileContent)) {
5451
- return res.status(400).json({
5452
- success: false,
5453
- message: 'organization plugin config not found in auth.ts',
5454
- });
5455
- }
5456
- fileContent = fileContent.replace(orgPluginRegex, (m) => `${m}${handler.fn},\n `);
5456
+ else if (templateId === 'org-invitation') {
5457
+ const orgPluginRegex = /organization\(\s*\{\s*/;
5458
+ if (!orgPluginRegex.test(fileContent)) {
5459
+ return res.status(400).json({
5460
+ success: false,
5461
+ message: 'organization plugin config not found in auth.ts',
5462
+ });
5457
5463
  }
5458
- else {
5459
- const emailAndPasswordRegex = /emailAndPassword\s*:\s*\{\s*/;
5460
- if (!emailAndPasswordRegex.test(fileContent)) {
5461
- return res.status(400).json({
5462
- success: false,
5463
- message: 'emailAndPassword config not found in auth.ts',
5464
- });
5465
- }
5466
- fileContent = fileContent.replace(emailAndPasswordRegex, (m) => `${m}${handler.fn},\n `);
5464
+ fileContent = fileContent.replace(orgPluginRegex, (m) => `${m}${handler.fn},\n `);
5465
+ }
5466
+ else {
5467
+ const sectionRegex = handler.sectionRegex || /emailAndPassword\s*:\s*\{\s*/;
5468
+ if (!sectionRegex.test(fileContent)) {
5469
+ return res.status(400).json({
5470
+ success: false,
5471
+ message: 'target email config section not found in auth.ts',
5472
+ });
5467
5473
  }
5474
+ fileContent = fileContent.replace(sectionRegex, (m) => `${m}${handler.fn},\n `);
5468
5475
  }
5469
5476
  writeFileSync(authPath, fileContent, 'utf-8');
5470
5477
  res.json({ success: true, path: authPath });