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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md 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,CAuzLR"}
package/dist/routes.js CHANGED
@@ -5296,13 +5296,16 @@ 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.replace(/\\/g, '\\\\').replace(/`/g, '\\`').replace(/\${/g, '\\${');
5308
+ const escapedHtml = html.replace(/\\/g, '\\\\').replace(/`/g, '\\`').replace(/\${/g, '\\${');
5306
5309
  if (!fileContent.includes("from 'resend'")) {
5307
5310
  fileContent = `import { Resend } from 'resend';\n` + fileContent;
5308
5311
  }
@@ -5322,12 +5325,13 @@ export const authClient = createAuthClient({
5322
5325
  const handlers = {
5323
5326
  'password-reset': {
5324
5327
  regex: /sendResetPassword\s*:\s*async\s*\([^)]*\)\s*=>\s*\{[\s\S]*?\},?/,
5328
+ sectionRegex: /emailAndPassword\s*:\s*\{\s*/,
5325
5329
  fn: `sendResetPassword: async ({ user, url, token }, request) => {
5326
- const subject = \\\`${escapedSubject}\\\`
5330
+ const subject = \`${escapedSubject}\`
5327
5331
  .replace(/{{user.name}}/g, user?.name || '')
5328
5332
  .replace(/{{user.email}}/g, user?.email || '');
5329
5333
 
5330
- const html = \\\`${escapedHtml}\\\`
5334
+ const html = \`${escapedHtml}\`
5331
5335
  .replace(/{{user.name}}/g, user?.name || '')
5332
5336
  .replace(/{{user.email}}/g, user?.email || '')
5333
5337
  .replace(/{{url}}/g, url || '')
@@ -5342,12 +5346,13 @@ export const authClient = createAuthClient({
5342
5346
  },
5343
5347
  'email-verification': {
5344
5348
  regex: /sendVerificationEmail\s*:\s*async\s*\([^)]*\)\s*=>\s*\{[\s\S]*?\},?/,
5349
+ sectionRegex: /emailVerification\s*:\s*\{\s*/,
5345
5350
  fn: `sendVerificationEmail: async ({ user, url, token }, request) => {
5346
- const subject = \\\`${escapedSubject}\\\`
5351
+ const subject = \`${escapedSubject}\`
5347
5352
  .replace(/{{user.name}}/g, user?.name || '')
5348
5353
  .replace(/{{user.email}}/g, user?.email || '');
5349
5354
 
5350
- const html = \\\`${escapedHtml}\\\`
5355
+ const html = \`${escapedHtml}\`
5351
5356
  .replace(/{{user.name}}/g, user?.name || '')
5352
5357
  .replace(/{{user.email}}/g, user?.email || '')
5353
5358
  .replace(/{{url}}/g, url || '')
@@ -5362,11 +5367,12 @@ export const authClient = createAuthClient({
5362
5367
  },
5363
5368
  'magic-link': {
5364
5369
  regex: /sendMagicLink\s*:\s*async\s*\([^)]*\)\s*=>\s*\{[\s\S]*?\},?/,
5370
+ sectionRegex: /magicLink\s*:\s*\{\s*/,
5365
5371
  fn: `sendMagicLink: async ({ email, token, url }, ctx) => {
5366
- const subject = \\\`${escapedSubject}\\\`
5372
+ const subject = \`${escapedSubject}\`
5367
5373
  .replace(/{{user.email}}/g, email || '');
5368
5374
 
5369
- const html = \\\`${escapedHtml}\\\`
5375
+ const html = \`${escapedHtml}\`
5370
5376
  .replace(/{{user.email}}/g, email || '')
5371
5377
  .replace(/{{url}}/g, url || '')
5372
5378
  .replace(/{{token}}/g, token || '');
@@ -5400,16 +5406,16 @@ export const authClient = createAuthClient({
5400
5406
  }) => {
5401
5407
  const { invitation, organization, inviter } = data;
5402
5408
  const baseUrl = process.env.BETTER_AUTH_URL || 'http://localhost:3000';
5403
- const url = \\\`\\\${baseUrl}/accept-invitation?id=\\\${invitation.id}\\\`;
5409
+ const url = \`\${baseUrl}/accept-invitation?id=\${invitation.id}\`;
5404
5410
 
5405
- const subject = \\\`${escapedSubject}\\\`
5411
+ const subject = \`${escapedSubject}\`
5406
5412
  .replace(/{{organization.name}}/g, organization?.name || '')
5407
5413
  .replace(/{{invitation.role}}/g, invitation.role || '')
5408
5414
  .replace(/{{inviter.user.name}}/g, inviter?.user?.name || '')
5409
5415
  .replace(/{{inviter.user.email}}/g, inviter?.user?.email || '')
5410
5416
  .replace(/{{invitation.email}}/g, invitation.email || '');
5411
5417
 
5412
- const html = \\\`${escapedHtml}\\\`
5418
+ const html = \`${escapedHtml}\`
5413
5419
  .replace(/{{invitation.url}}/g, url)
5414
5420
  .replace(/{{invitation.role}}/g, invitation.role || '')
5415
5421
  .replace(/{{organization.name}}/g, organization?.name || '')
@@ -5418,7 +5424,7 @@ export const authClient = createAuthClient({
5418
5424
  .replace(/{{inviter.user.email}}/g, inviter?.user?.email || '')
5419
5425
  .replace(/{{invitation.email}}/g, invitation.email || '')
5420
5426
  .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\\\` : '');
5427
+ .replace(/{{expiresIn}}/g, invitation.expiresAt ? \`\${Math.ceil((invitation.expiresAt.getTime() - Date.now()) / (1000 * 60 * 60 * 24))} days\` : '');
5422
5428
 
5423
5429
  void sendEmail({
5424
5430
  to: invitation.email,
@@ -5444,27 +5450,25 @@ export const authClient = createAuthClient({
5444
5450
  if (handler.regex.test(fileContent)) {
5445
5451
  fileContent = fileContent.replace(handler.regex, `${handler.fn},`);
5446
5452
  }
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 `);
5453
+ else if (templateId === 'org-invitation') {
5454
+ const orgPluginRegex = /organization\(\s*\{\s*/;
5455
+ if (!orgPluginRegex.test(fileContent)) {
5456
+ return res.status(400).json({
5457
+ success: false,
5458
+ message: 'organization plugin config not found in auth.ts',
5459
+ });
5457
5460
  }
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 `);
5461
+ fileContent = fileContent.replace(orgPluginRegex, (m) => `${m}${handler.fn},\n `);
5462
+ }
5463
+ else {
5464
+ const sectionRegex = handler.sectionRegex || /emailAndPassword\s*:\s*\{\s*/;
5465
+ if (!sectionRegex.test(fileContent)) {
5466
+ return res.status(400).json({
5467
+ success: false,
5468
+ message: 'target email config section not found in auth.ts',
5469
+ });
5467
5470
  }
5471
+ fileContent = fileContent.replace(sectionRegex, (m) => `${m}${handler.fn},\n `);
5468
5472
  }
5469
5473
  writeFileSync(authPath, fileContent, 'utf-8');
5470
5474
  res.json({ success: true, path: authPath });