resend 6.1.1 → 6.1.2-preview-templates.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/index.d.mts CHANGED
@@ -48,9 +48,9 @@ interface EmailApiAttachment {
48
48
  content_id?: string;
49
49
  }
50
50
  interface EmailApiOptions {
51
- from: string;
51
+ from?: string;
52
52
  to: string | string[];
53
- subject: string;
53
+ subject?: string;
54
54
  region?: string;
55
55
  headers?: Record<string, string>;
56
56
  html?: string;
@@ -61,6 +61,10 @@ interface EmailApiOptions {
61
61
  scheduled_at?: string;
62
62
  tags?: Tag$1[];
63
63
  attachments?: EmailApiAttachment[];
64
+ template?: {
65
+ id: string;
66
+ variables?: Record<string, string | number | boolean>;
67
+ };
64
68
  }
65
69
 
66
70
  interface GetOptions {
@@ -77,11 +81,6 @@ interface IdempotentRequest {
77
81
  idempotencyKey?: string;
78
82
  }
79
83
 
80
- interface List<T> {
81
- readonly object: 'list';
82
- data: T[];
83
- }
84
-
85
84
  type PaginationOptions = {
86
85
  /**
87
86
  * Maximum number of items to return (1-100, default: 20)
@@ -247,6 +246,16 @@ interface EmailRenderOptions$1 {
247
246
  */
248
247
  text: string;
249
248
  }
249
+ interface EmailTemplateOptions {
250
+ template: {
251
+ id: string;
252
+ variables?: Record<string, string | number | boolean>;
253
+ };
254
+ }
255
+ interface CreateEmailBaseOptionsWithTemplate extends Omit<CreateEmailBaseOptions, 'from' | 'subject'> {
256
+ from?: string;
257
+ subject?: string;
258
+ }
250
259
  interface CreateEmailBaseOptions {
251
260
  /**
252
261
  * Filename and content of attachments (max 40mb per email)
@@ -310,7 +319,13 @@ interface CreateEmailBaseOptions {
310
319
  */
311
320
  scheduledAt?: string;
312
321
  }
313
- type CreateEmailOptions = RequireAtLeastOne<EmailRenderOptions$1> & CreateEmailBaseOptions;
322
+ type CreateEmailOptions = ((RequireAtLeastOne<EmailRenderOptions$1> & CreateEmailBaseOptions) & {
323
+ template?: never;
324
+ }) | ((EmailTemplateOptions & CreateEmailBaseOptionsWithTemplate) & {
325
+ react?: never;
326
+ html?: never;
327
+ text?: never;
328
+ });
314
329
  interface CreateEmailRequestOptions extends PostOptions, IdempotentRequest {
315
330
  }
316
331
  interface CreateEmailResponseSuccess {
@@ -930,6 +945,180 @@ declare class Emails {
930
945
  cancel(id: string): Promise<CancelEmailResponse>;
931
946
  }
932
947
 
948
+ interface Template {
949
+ id: string;
950
+ name: string;
951
+ subject: string | null;
952
+ html: string;
953
+ text: string | null;
954
+ status: 'draft' | 'published';
955
+ variables: TemplateVariable[] | null;
956
+ alias: string | null;
957
+ from: string | null;
958
+ reply_to: string[] | null;
959
+ published_at: string | null;
960
+ created_at: string;
961
+ updated_at: string;
962
+ }
963
+ type TemplateVariableListFallbackType = string[] | number[] | boolean[] | Record<string, unknown>[];
964
+ interface TemplateVariable {
965
+ key: string;
966
+ fallback_value: string | number | boolean | Record<string, unknown> | TemplateVariableListFallbackType | null;
967
+ type: 'string' | 'number' | 'boolean' | 'object' | 'list';
968
+ created_at: string;
969
+ updated_at: string;
970
+ }
971
+
972
+ type TemplateContentCreationOptions = RequireAtLeastOne<{
973
+ html: string;
974
+ react: React.ReactNode;
975
+ }>;
976
+ type TemplateVariableCreationOptions = Pick<TemplateVariable, 'key' | 'type'> & ({
977
+ type: 'string';
978
+ fallbackValue?: string | null;
979
+ } | {
980
+ type: 'number';
981
+ fallbackValue?: number | null;
982
+ } | {
983
+ type: 'boolean';
984
+ fallbackValue?: boolean | null;
985
+ } | {
986
+ type: 'object';
987
+ fallbackValue: Record<string, unknown>;
988
+ } | {
989
+ type: 'list';
990
+ fallbackValue: TemplateVariableListFallbackType;
991
+ });
992
+ type TemplateOptionalFieldsForCreation = Partial<Pick<Template, 'subject' | 'text' | 'alias' | 'from'>> & {
993
+ replyTo?: string[] | string;
994
+ variables?: TemplateVariableCreationOptions[];
995
+ };
996
+ type CreateTemplateOptions = Pick<Template, 'name'> & TemplateOptionalFieldsForCreation & TemplateContentCreationOptions;
997
+ interface CreateTemplateResponseSuccess extends Pick<Template, 'id'> {
998
+ object: 'template';
999
+ }
1000
+ type CreateTemplateResponse = {
1001
+ data: CreateTemplateResponseSuccess;
1002
+ error: null;
1003
+ } | {
1004
+ data: null;
1005
+ error: ErrorResponse;
1006
+ };
1007
+
1008
+ interface DuplicateTemplateResponseSuccess extends Pick<Template, 'id'> {
1009
+ object: 'template';
1010
+ }
1011
+ type DuplicateTemplateResponse = {
1012
+ data: DuplicateTemplateResponseSuccess;
1013
+ error: null;
1014
+ } | {
1015
+ data: null;
1016
+ error: ErrorResponse;
1017
+ };
1018
+
1019
+ interface PublishTemplateResponseSuccess extends Pick<Template, 'id'> {
1020
+ object: 'template';
1021
+ }
1022
+ type PublishTemplateResponse = {
1023
+ data: PublishTemplateResponseSuccess;
1024
+ error: null;
1025
+ } | {
1026
+ data: null;
1027
+ error: ErrorResponse;
1028
+ };
1029
+
1030
+ declare class ChainableTemplateResult<T extends CreateTemplateResponse | DuplicateTemplateResponse> implements PromiseLike<T> {
1031
+ private readonly promise;
1032
+ private readonly publishFn;
1033
+ constructor(promise: Promise<T>, publishFn: (id: string) => Promise<PublishTemplateResponse>);
1034
+ then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null): PromiseLike<TResult1 | TResult2>;
1035
+ publish(): Promise<PublishTemplateResponse>;
1036
+ }
1037
+
1038
+ interface GetTemplateResponseSuccess extends Template {
1039
+ object: 'template';
1040
+ }
1041
+ type GetTemplateResponse = {
1042
+ data: GetTemplateResponseSuccess;
1043
+ error: null;
1044
+ } | {
1045
+ data: null;
1046
+ error: ErrorResponse;
1047
+ };
1048
+
1049
+ interface TemplateListItem extends Pick<Template, 'id' | 'name' | 'created_at' | 'updated_at' | 'status' | 'published_at' | 'alias'> {
1050
+ }
1051
+ interface ListTemplatesResponseSuccess {
1052
+ object: 'list';
1053
+ data: TemplateListItem[];
1054
+ has_more: boolean;
1055
+ }
1056
+ type ListTemplatesResponse = {
1057
+ data: ListTemplatesResponseSuccess;
1058
+ error: null;
1059
+ } | {
1060
+ data: null;
1061
+ error: ErrorResponse;
1062
+ };
1063
+
1064
+ interface RemoveTemplateResponseSuccess {
1065
+ object: 'template';
1066
+ id: string;
1067
+ deleted: boolean;
1068
+ }
1069
+ type RemoveTemplateResponse = {
1070
+ data: RemoveTemplateResponseSuccess;
1071
+ error: null;
1072
+ } | {
1073
+ data: null;
1074
+ error: ErrorResponse;
1075
+ };
1076
+
1077
+ type TemplateVariableUpdateOptions = Pick<TemplateVariable, 'key' | 'type'> & ({
1078
+ type: 'string';
1079
+ fallbackValue?: string | null;
1080
+ } | {
1081
+ type: 'number';
1082
+ fallbackValue?: number | null;
1083
+ } | {
1084
+ type: 'boolean';
1085
+ fallbackValue?: boolean | null;
1086
+ } | {
1087
+ type: 'object';
1088
+ fallbackValue: Record<string, unknown>;
1089
+ } | {
1090
+ type: 'list';
1091
+ fallbackValue: TemplateVariableListFallbackType;
1092
+ });
1093
+ interface UpdateTemplateOptions extends Partial<Pick<Template, 'name' | 'subject' | 'html' | 'text' | 'from' | 'alias'>> {
1094
+ variables?: TemplateVariableUpdateOptions[];
1095
+ replyTo?: string[] | string;
1096
+ }
1097
+ interface UpdateTemplateResponseSuccess extends Pick<Template, 'id'> {
1098
+ object: 'template';
1099
+ }
1100
+ type UpdateTemplateResponse = {
1101
+ data: UpdateTemplateResponseSuccess;
1102
+ error: null;
1103
+ } | {
1104
+ data: null;
1105
+ error: ErrorResponse;
1106
+ };
1107
+
1108
+ declare class Templates {
1109
+ private readonly resend;
1110
+ private renderAsync?;
1111
+ constructor(resend: Resend);
1112
+ create(payload: CreateTemplateOptions): ChainableTemplateResult<CreateTemplateResponse>;
1113
+ private performCreate;
1114
+ remove(identifier: string): Promise<RemoveTemplateResponse>;
1115
+ get(identifier: string): Promise<GetTemplateResponse>;
1116
+ list(options?: PaginationOptions): Promise<ListTemplatesResponse>;
1117
+ duplicate(identifier: string): ChainableTemplateResult<DuplicateTemplateResponse>;
1118
+ publish(identifier: string): Promise<PublishTemplateResponse>;
1119
+ update(identifier: string, payload: UpdateTemplateOptions): Promise<UpdateTemplateResponse>;
1120
+ }
1121
+
933
1122
  declare class Resend {
934
1123
  readonly key?: string | undefined;
935
1124
  private readonly headers;
@@ -940,6 +1129,7 @@ declare class Resend {
940
1129
  readonly contacts: Contacts;
941
1130
  readonly domains: Domains;
942
1131
  readonly emails: Emails;
1132
+ readonly templates: Templates;
943
1133
  constructor(key?: string | undefined);
944
1134
  fetchRequest<T>(path: string, options?: {}): Promise<{
945
1135
  data: T;
@@ -985,4 +1175,4 @@ declare class Resend {
985
1175
  }>;
986
1176
  }
987
1177
 
988
- export { type ApiKey, type Attachment, type Audience, type Broadcast, type CancelEmailResponse, type CancelEmailResponseSuccess, type Contact, type CreateApiKeyOptions, type CreateApiKeyRequestOptions, type CreateApiKeyResponse, type CreateApiKeyResponseSuccess, type CreateAudienceOptions, type CreateAudienceRequestOptions, type CreateAudienceResponse, type CreateAudienceResponseSuccess, type CreateBatchOptions, type CreateBatchRequestOptions, type CreateBatchResponse, type CreateBatchSuccessResponse, type CreateBroadcastOptions, type CreateBroadcastRequestOptions, type CreateBroadcastResponse, type CreateBroadcastResponseSuccess, type CreateContactOptions, type CreateContactRequestOptions, type CreateContactResponse, type CreateContactResponseSuccess, type CreateDomainOptions, type CreateDomainRequestOptions, type CreateDomainResponse, type CreateDomainResponseSuccess, type CreateEmailOptions, type CreateEmailRequestOptions, type CreateEmailResponse, type CreateEmailResponseSuccess, type Domain, type DomainApiOptions, type DomainDkimRecord, type DomainNameservers, type DomainRecords, type DomainRegion, type DomainSpfRecord, type DomainStatus, type EmailApiAttachment, type EmailApiOptions, type ErrorResponse, type GetAudienceResponse, type GetAudienceResponseSuccess, type GetBroadcastResponse, type GetBroadcastResponseSuccess, type GetContactOptions, type GetContactResponse, type GetContactResponseSuccess, type GetDomainResponse, type GetDomainResponseSuccess, type GetEmailResponse, type GetEmailResponseSuccess, type GetOptions, type IdempotentRequest, type List, type ListApiKeysOptions, type ListApiKeysResponse, type ListApiKeysResponseSuccess, type ListAudiencesOptions, type ListAudiencesResponse, type ListAudiencesResponseSuccess, type ListBroadcastsOptions, type ListBroadcastsResponse, type ListBroadcastsResponseSuccess, type ListContactsOptions, type ListContactsResponse, type ListContactsResponseSuccess, type ListDomainsOptions, type ListDomainsResponse, type ListDomainsResponseSuccess, type PaginationOptions, type PatchOptions, type PostOptions, type PutOptions, type RemoveApiKeyResponse, type RemoveApiKeyResponseSuccess, type RemoveAudiencesResponse, type RemoveAudiencesResponseSuccess, type RemoveBroadcastResponse, type RemoveBroadcastResponseSuccess, type RemoveContactOptions, type RemoveContactsResponse, type RemoveContactsResponseSuccess, type RemoveDomainsResponse, type RemoveDomainsResponseSuccess, type RequireAtLeastOne, Resend, type SelectingField, type SendBroadcastOptions, type SendBroadcastRequestOptions, type SendBroadcastResponse, type SendBroadcastResponseSuccess, type Tag, type UpdateBroadcastOptions, type UpdateBroadcastResponse, type UpdateBroadcastResponseSuccess, type UpdateContactOptions, type UpdateContactResponse, type UpdateContactResponseSuccess, type UpdateDomainsOptions, type UpdateDomainsResponse, type UpdateDomainsResponseSuccess, type UpdateEmailOptions, type UpdateEmailResponse, type UpdateEmailResponseSuccess, type VerifyDomainsResponse, type VerifyDomainsResponseSuccess };
1178
+ export { type ApiKey, type Attachment, type Audience, type Broadcast, type CancelEmailResponse, type CancelEmailResponseSuccess, type Contact, type CreateApiKeyOptions, type CreateApiKeyRequestOptions, type CreateApiKeyResponse, type CreateApiKeyResponseSuccess, type CreateAudienceOptions, type CreateAudienceRequestOptions, type CreateAudienceResponse, type CreateAudienceResponseSuccess, type CreateBatchOptions, type CreateBatchRequestOptions, type CreateBatchResponse, type CreateBatchSuccessResponse, type CreateBroadcastOptions, type CreateBroadcastRequestOptions, type CreateBroadcastResponse, type CreateBroadcastResponseSuccess, type CreateContactOptions, type CreateContactRequestOptions, type CreateContactResponse, type CreateContactResponseSuccess, type CreateDomainOptions, type CreateDomainRequestOptions, type CreateDomainResponse, type CreateDomainResponseSuccess, type CreateEmailOptions, type CreateEmailRequestOptions, type CreateEmailResponse, type CreateEmailResponseSuccess, type Domain, type DomainApiOptions, type DomainDkimRecord, type DomainNameservers, type DomainRecords, type DomainRegion, type DomainSpfRecord, type DomainStatus, type EmailApiAttachment, type EmailApiOptions, type ErrorResponse, type GetAudienceResponse, type GetAudienceResponseSuccess, type GetBroadcastResponse, type GetBroadcastResponseSuccess, type GetContactOptions, type GetContactResponse, type GetContactResponseSuccess, type GetDomainResponse, type GetDomainResponseSuccess, type GetEmailResponse, type GetEmailResponseSuccess, type GetOptions, type IdempotentRequest, type ListApiKeysOptions, type ListApiKeysResponse, type ListApiKeysResponseSuccess, type ListAudiencesOptions, type ListAudiencesResponse, type ListAudiencesResponseSuccess, type ListBroadcastsOptions, type ListBroadcastsResponse, type ListBroadcastsResponseSuccess, type ListContactsOptions, type ListContactsResponse, type ListContactsResponseSuccess, type ListDomainsOptions, type ListDomainsResponse, type ListDomainsResponseSuccess, type PaginationOptions, type PatchOptions, type PostOptions, type PutOptions, type RemoveApiKeyResponse, type RemoveApiKeyResponseSuccess, type RemoveAudiencesResponse, type RemoveAudiencesResponseSuccess, type RemoveBroadcastResponse, type RemoveBroadcastResponseSuccess, type RemoveContactOptions, type RemoveContactsResponse, type RemoveContactsResponseSuccess, type RemoveDomainsResponse, type RemoveDomainsResponseSuccess, type RequireAtLeastOne, Resend, type SelectingField, type SendBroadcastOptions, type SendBroadcastRequestOptions, type SendBroadcastResponse, type SendBroadcastResponseSuccess, type Tag, type UpdateBroadcastOptions, type UpdateBroadcastResponse, type UpdateBroadcastResponseSuccess, type UpdateContactOptions, type UpdateContactResponse, type UpdateContactResponseSuccess, type UpdateDomainsOptions, type UpdateDomainsResponse, type UpdateDomainsResponseSuccess, type UpdateEmailOptions, type UpdateEmailResponse, type UpdateEmailResponseSuccess, type VerifyDomainsResponse, type VerifyDomainsResponseSuccess };
package/dist/index.d.ts CHANGED
@@ -48,9 +48,9 @@ interface EmailApiAttachment {
48
48
  content_id?: string;
49
49
  }
50
50
  interface EmailApiOptions {
51
- from: string;
51
+ from?: string;
52
52
  to: string | string[];
53
- subject: string;
53
+ subject?: string;
54
54
  region?: string;
55
55
  headers?: Record<string, string>;
56
56
  html?: string;
@@ -61,6 +61,10 @@ interface EmailApiOptions {
61
61
  scheduled_at?: string;
62
62
  tags?: Tag$1[];
63
63
  attachments?: EmailApiAttachment[];
64
+ template?: {
65
+ id: string;
66
+ variables?: Record<string, string | number | boolean>;
67
+ };
64
68
  }
65
69
 
66
70
  interface GetOptions {
@@ -77,11 +81,6 @@ interface IdempotentRequest {
77
81
  idempotencyKey?: string;
78
82
  }
79
83
 
80
- interface List<T> {
81
- readonly object: 'list';
82
- data: T[];
83
- }
84
-
85
84
  type PaginationOptions = {
86
85
  /**
87
86
  * Maximum number of items to return (1-100, default: 20)
@@ -247,6 +246,16 @@ interface EmailRenderOptions$1 {
247
246
  */
248
247
  text: string;
249
248
  }
249
+ interface EmailTemplateOptions {
250
+ template: {
251
+ id: string;
252
+ variables?: Record<string, string | number | boolean>;
253
+ };
254
+ }
255
+ interface CreateEmailBaseOptionsWithTemplate extends Omit<CreateEmailBaseOptions, 'from' | 'subject'> {
256
+ from?: string;
257
+ subject?: string;
258
+ }
250
259
  interface CreateEmailBaseOptions {
251
260
  /**
252
261
  * Filename and content of attachments (max 40mb per email)
@@ -310,7 +319,13 @@ interface CreateEmailBaseOptions {
310
319
  */
311
320
  scheduledAt?: string;
312
321
  }
313
- type CreateEmailOptions = RequireAtLeastOne<EmailRenderOptions$1> & CreateEmailBaseOptions;
322
+ type CreateEmailOptions = ((RequireAtLeastOne<EmailRenderOptions$1> & CreateEmailBaseOptions) & {
323
+ template?: never;
324
+ }) | ((EmailTemplateOptions & CreateEmailBaseOptionsWithTemplate) & {
325
+ react?: never;
326
+ html?: never;
327
+ text?: never;
328
+ });
314
329
  interface CreateEmailRequestOptions extends PostOptions, IdempotentRequest {
315
330
  }
316
331
  interface CreateEmailResponseSuccess {
@@ -930,6 +945,180 @@ declare class Emails {
930
945
  cancel(id: string): Promise<CancelEmailResponse>;
931
946
  }
932
947
 
948
+ interface Template {
949
+ id: string;
950
+ name: string;
951
+ subject: string | null;
952
+ html: string;
953
+ text: string | null;
954
+ status: 'draft' | 'published';
955
+ variables: TemplateVariable[] | null;
956
+ alias: string | null;
957
+ from: string | null;
958
+ reply_to: string[] | null;
959
+ published_at: string | null;
960
+ created_at: string;
961
+ updated_at: string;
962
+ }
963
+ type TemplateVariableListFallbackType = string[] | number[] | boolean[] | Record<string, unknown>[];
964
+ interface TemplateVariable {
965
+ key: string;
966
+ fallback_value: string | number | boolean | Record<string, unknown> | TemplateVariableListFallbackType | null;
967
+ type: 'string' | 'number' | 'boolean' | 'object' | 'list';
968
+ created_at: string;
969
+ updated_at: string;
970
+ }
971
+
972
+ type TemplateContentCreationOptions = RequireAtLeastOne<{
973
+ html: string;
974
+ react: React.ReactNode;
975
+ }>;
976
+ type TemplateVariableCreationOptions = Pick<TemplateVariable, 'key' | 'type'> & ({
977
+ type: 'string';
978
+ fallbackValue?: string | null;
979
+ } | {
980
+ type: 'number';
981
+ fallbackValue?: number | null;
982
+ } | {
983
+ type: 'boolean';
984
+ fallbackValue?: boolean | null;
985
+ } | {
986
+ type: 'object';
987
+ fallbackValue: Record<string, unknown>;
988
+ } | {
989
+ type: 'list';
990
+ fallbackValue: TemplateVariableListFallbackType;
991
+ });
992
+ type TemplateOptionalFieldsForCreation = Partial<Pick<Template, 'subject' | 'text' | 'alias' | 'from'>> & {
993
+ replyTo?: string[] | string;
994
+ variables?: TemplateVariableCreationOptions[];
995
+ };
996
+ type CreateTemplateOptions = Pick<Template, 'name'> & TemplateOptionalFieldsForCreation & TemplateContentCreationOptions;
997
+ interface CreateTemplateResponseSuccess extends Pick<Template, 'id'> {
998
+ object: 'template';
999
+ }
1000
+ type CreateTemplateResponse = {
1001
+ data: CreateTemplateResponseSuccess;
1002
+ error: null;
1003
+ } | {
1004
+ data: null;
1005
+ error: ErrorResponse;
1006
+ };
1007
+
1008
+ interface DuplicateTemplateResponseSuccess extends Pick<Template, 'id'> {
1009
+ object: 'template';
1010
+ }
1011
+ type DuplicateTemplateResponse = {
1012
+ data: DuplicateTemplateResponseSuccess;
1013
+ error: null;
1014
+ } | {
1015
+ data: null;
1016
+ error: ErrorResponse;
1017
+ };
1018
+
1019
+ interface PublishTemplateResponseSuccess extends Pick<Template, 'id'> {
1020
+ object: 'template';
1021
+ }
1022
+ type PublishTemplateResponse = {
1023
+ data: PublishTemplateResponseSuccess;
1024
+ error: null;
1025
+ } | {
1026
+ data: null;
1027
+ error: ErrorResponse;
1028
+ };
1029
+
1030
+ declare class ChainableTemplateResult<T extends CreateTemplateResponse | DuplicateTemplateResponse> implements PromiseLike<T> {
1031
+ private readonly promise;
1032
+ private readonly publishFn;
1033
+ constructor(promise: Promise<T>, publishFn: (id: string) => Promise<PublishTemplateResponse>);
1034
+ then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null): PromiseLike<TResult1 | TResult2>;
1035
+ publish(): Promise<PublishTemplateResponse>;
1036
+ }
1037
+
1038
+ interface GetTemplateResponseSuccess extends Template {
1039
+ object: 'template';
1040
+ }
1041
+ type GetTemplateResponse = {
1042
+ data: GetTemplateResponseSuccess;
1043
+ error: null;
1044
+ } | {
1045
+ data: null;
1046
+ error: ErrorResponse;
1047
+ };
1048
+
1049
+ interface TemplateListItem extends Pick<Template, 'id' | 'name' | 'created_at' | 'updated_at' | 'status' | 'published_at' | 'alias'> {
1050
+ }
1051
+ interface ListTemplatesResponseSuccess {
1052
+ object: 'list';
1053
+ data: TemplateListItem[];
1054
+ has_more: boolean;
1055
+ }
1056
+ type ListTemplatesResponse = {
1057
+ data: ListTemplatesResponseSuccess;
1058
+ error: null;
1059
+ } | {
1060
+ data: null;
1061
+ error: ErrorResponse;
1062
+ };
1063
+
1064
+ interface RemoveTemplateResponseSuccess {
1065
+ object: 'template';
1066
+ id: string;
1067
+ deleted: boolean;
1068
+ }
1069
+ type RemoveTemplateResponse = {
1070
+ data: RemoveTemplateResponseSuccess;
1071
+ error: null;
1072
+ } | {
1073
+ data: null;
1074
+ error: ErrorResponse;
1075
+ };
1076
+
1077
+ type TemplateVariableUpdateOptions = Pick<TemplateVariable, 'key' | 'type'> & ({
1078
+ type: 'string';
1079
+ fallbackValue?: string | null;
1080
+ } | {
1081
+ type: 'number';
1082
+ fallbackValue?: number | null;
1083
+ } | {
1084
+ type: 'boolean';
1085
+ fallbackValue?: boolean | null;
1086
+ } | {
1087
+ type: 'object';
1088
+ fallbackValue: Record<string, unknown>;
1089
+ } | {
1090
+ type: 'list';
1091
+ fallbackValue: TemplateVariableListFallbackType;
1092
+ });
1093
+ interface UpdateTemplateOptions extends Partial<Pick<Template, 'name' | 'subject' | 'html' | 'text' | 'from' | 'alias'>> {
1094
+ variables?: TemplateVariableUpdateOptions[];
1095
+ replyTo?: string[] | string;
1096
+ }
1097
+ interface UpdateTemplateResponseSuccess extends Pick<Template, 'id'> {
1098
+ object: 'template';
1099
+ }
1100
+ type UpdateTemplateResponse = {
1101
+ data: UpdateTemplateResponseSuccess;
1102
+ error: null;
1103
+ } | {
1104
+ data: null;
1105
+ error: ErrorResponse;
1106
+ };
1107
+
1108
+ declare class Templates {
1109
+ private readonly resend;
1110
+ private renderAsync?;
1111
+ constructor(resend: Resend);
1112
+ create(payload: CreateTemplateOptions): ChainableTemplateResult<CreateTemplateResponse>;
1113
+ private performCreate;
1114
+ remove(identifier: string): Promise<RemoveTemplateResponse>;
1115
+ get(identifier: string): Promise<GetTemplateResponse>;
1116
+ list(options?: PaginationOptions): Promise<ListTemplatesResponse>;
1117
+ duplicate(identifier: string): ChainableTemplateResult<DuplicateTemplateResponse>;
1118
+ publish(identifier: string): Promise<PublishTemplateResponse>;
1119
+ update(identifier: string, payload: UpdateTemplateOptions): Promise<UpdateTemplateResponse>;
1120
+ }
1121
+
933
1122
  declare class Resend {
934
1123
  readonly key?: string | undefined;
935
1124
  private readonly headers;
@@ -940,6 +1129,7 @@ declare class Resend {
940
1129
  readonly contacts: Contacts;
941
1130
  readonly domains: Domains;
942
1131
  readonly emails: Emails;
1132
+ readonly templates: Templates;
943
1133
  constructor(key?: string | undefined);
944
1134
  fetchRequest<T>(path: string, options?: {}): Promise<{
945
1135
  data: T;
@@ -985,4 +1175,4 @@ declare class Resend {
985
1175
  }>;
986
1176
  }
987
1177
 
988
- export { type ApiKey, type Attachment, type Audience, type Broadcast, type CancelEmailResponse, type CancelEmailResponseSuccess, type Contact, type CreateApiKeyOptions, type CreateApiKeyRequestOptions, type CreateApiKeyResponse, type CreateApiKeyResponseSuccess, type CreateAudienceOptions, type CreateAudienceRequestOptions, type CreateAudienceResponse, type CreateAudienceResponseSuccess, type CreateBatchOptions, type CreateBatchRequestOptions, type CreateBatchResponse, type CreateBatchSuccessResponse, type CreateBroadcastOptions, type CreateBroadcastRequestOptions, type CreateBroadcastResponse, type CreateBroadcastResponseSuccess, type CreateContactOptions, type CreateContactRequestOptions, type CreateContactResponse, type CreateContactResponseSuccess, type CreateDomainOptions, type CreateDomainRequestOptions, type CreateDomainResponse, type CreateDomainResponseSuccess, type CreateEmailOptions, type CreateEmailRequestOptions, type CreateEmailResponse, type CreateEmailResponseSuccess, type Domain, type DomainApiOptions, type DomainDkimRecord, type DomainNameservers, type DomainRecords, type DomainRegion, type DomainSpfRecord, type DomainStatus, type EmailApiAttachment, type EmailApiOptions, type ErrorResponse, type GetAudienceResponse, type GetAudienceResponseSuccess, type GetBroadcastResponse, type GetBroadcastResponseSuccess, type GetContactOptions, type GetContactResponse, type GetContactResponseSuccess, type GetDomainResponse, type GetDomainResponseSuccess, type GetEmailResponse, type GetEmailResponseSuccess, type GetOptions, type IdempotentRequest, type List, type ListApiKeysOptions, type ListApiKeysResponse, type ListApiKeysResponseSuccess, type ListAudiencesOptions, type ListAudiencesResponse, type ListAudiencesResponseSuccess, type ListBroadcastsOptions, type ListBroadcastsResponse, type ListBroadcastsResponseSuccess, type ListContactsOptions, type ListContactsResponse, type ListContactsResponseSuccess, type ListDomainsOptions, type ListDomainsResponse, type ListDomainsResponseSuccess, type PaginationOptions, type PatchOptions, type PostOptions, type PutOptions, type RemoveApiKeyResponse, type RemoveApiKeyResponseSuccess, type RemoveAudiencesResponse, type RemoveAudiencesResponseSuccess, type RemoveBroadcastResponse, type RemoveBroadcastResponseSuccess, type RemoveContactOptions, type RemoveContactsResponse, type RemoveContactsResponseSuccess, type RemoveDomainsResponse, type RemoveDomainsResponseSuccess, type RequireAtLeastOne, Resend, type SelectingField, type SendBroadcastOptions, type SendBroadcastRequestOptions, type SendBroadcastResponse, type SendBroadcastResponseSuccess, type Tag, type UpdateBroadcastOptions, type UpdateBroadcastResponse, type UpdateBroadcastResponseSuccess, type UpdateContactOptions, type UpdateContactResponse, type UpdateContactResponseSuccess, type UpdateDomainsOptions, type UpdateDomainsResponse, type UpdateDomainsResponseSuccess, type UpdateEmailOptions, type UpdateEmailResponse, type UpdateEmailResponseSuccess, type VerifyDomainsResponse, type VerifyDomainsResponseSuccess };
1178
+ export { type ApiKey, type Attachment, type Audience, type Broadcast, type CancelEmailResponse, type CancelEmailResponseSuccess, type Contact, type CreateApiKeyOptions, type CreateApiKeyRequestOptions, type CreateApiKeyResponse, type CreateApiKeyResponseSuccess, type CreateAudienceOptions, type CreateAudienceRequestOptions, type CreateAudienceResponse, type CreateAudienceResponseSuccess, type CreateBatchOptions, type CreateBatchRequestOptions, type CreateBatchResponse, type CreateBatchSuccessResponse, type CreateBroadcastOptions, type CreateBroadcastRequestOptions, type CreateBroadcastResponse, type CreateBroadcastResponseSuccess, type CreateContactOptions, type CreateContactRequestOptions, type CreateContactResponse, type CreateContactResponseSuccess, type CreateDomainOptions, type CreateDomainRequestOptions, type CreateDomainResponse, type CreateDomainResponseSuccess, type CreateEmailOptions, type CreateEmailRequestOptions, type CreateEmailResponse, type CreateEmailResponseSuccess, type Domain, type DomainApiOptions, type DomainDkimRecord, type DomainNameservers, type DomainRecords, type DomainRegion, type DomainSpfRecord, type DomainStatus, type EmailApiAttachment, type EmailApiOptions, type ErrorResponse, type GetAudienceResponse, type GetAudienceResponseSuccess, type GetBroadcastResponse, type GetBroadcastResponseSuccess, type GetContactOptions, type GetContactResponse, type GetContactResponseSuccess, type GetDomainResponse, type GetDomainResponseSuccess, type GetEmailResponse, type GetEmailResponseSuccess, type GetOptions, type IdempotentRequest, type ListApiKeysOptions, type ListApiKeysResponse, type ListApiKeysResponseSuccess, type ListAudiencesOptions, type ListAudiencesResponse, type ListAudiencesResponseSuccess, type ListBroadcastsOptions, type ListBroadcastsResponse, type ListBroadcastsResponseSuccess, type ListContactsOptions, type ListContactsResponse, type ListContactsResponseSuccess, type ListDomainsOptions, type ListDomainsResponse, type ListDomainsResponseSuccess, type PaginationOptions, type PatchOptions, type PostOptions, type PutOptions, type RemoveApiKeyResponse, type RemoveApiKeyResponseSuccess, type RemoveAudiencesResponse, type RemoveAudiencesResponseSuccess, type RemoveBroadcastResponse, type RemoveBroadcastResponseSuccess, type RemoveContactOptions, type RemoveContactsResponse, type RemoveContactsResponseSuccess, type RemoveDomainsResponse, type RemoveDomainsResponseSuccess, type RequireAtLeastOne, Resend, type SelectingField, type SendBroadcastOptions, type SendBroadcastRequestOptions, type SendBroadcastResponse, type SendBroadcastResponseSuccess, type Tag, type UpdateBroadcastOptions, type UpdateBroadcastResponse, type UpdateBroadcastResponseSuccess, type UpdateContactOptions, type UpdateContactResponse, type UpdateContactResponseSuccess, type UpdateDomainsOptions, type UpdateDomainsResponse, type UpdateDomainsResponseSuccess, type UpdateEmailOptions, type UpdateEmailResponse, type UpdateEmailResponseSuccess, type VerifyDomainsResponse, type VerifyDomainsResponseSuccess };
package/dist/index.js CHANGED
@@ -84,7 +84,7 @@ __export(index_exports, {
84
84
  module.exports = __toCommonJS(index_exports);
85
85
 
86
86
  // package.json
87
- var version = "6.1.1";
87
+ var version = "6.1.2-preview-templates.0";
88
88
 
89
89
  // src/common/utils/build-pagination-query.ts
90
90
  function buildPaginationQuery(options) {
@@ -198,7 +198,11 @@ function parseEmailToApiOptions(email) {
198
198
  subject: email.subject,
199
199
  tags: email.tags,
200
200
  text: email.text,
201
- to: email.to
201
+ to: email.to,
202
+ template: email.template ? {
203
+ id: email.template.id,
204
+ variables: email.template.variables
205
+ } : void 0
202
206
  };
203
207
  }
204
208
 
@@ -210,7 +214,7 @@ function render(node) {
210
214
  }).catch(() => {
211
215
  reject(
212
216
  Error(
213
- "Failed to render React component. Make sure to install `@react-email/render`"
217
+ "Failed to render React component. Make sure to install `@react-email/render` or `@react-email/components`."
214
218
  )
215
219
  );
216
220
  });
@@ -553,6 +557,150 @@ var Emails = class {
553
557
  }
554
558
  };
555
559
 
560
+ // src/common/utils/get-pagination-query-properties.ts
561
+ function getPaginationQueryProperties(options = {}) {
562
+ const query = new URLSearchParams();
563
+ if (options.before) query.set("before", options.before);
564
+ if (options.after) query.set("after", options.after);
565
+ if (options.limit) query.set("limit", options.limit.toString());
566
+ return query.size > 0 ? `?${query.toString()}` : "";
567
+ }
568
+
569
+ // src/common/utils/parse-template-to-api-options.ts
570
+ function parseVariables(variables) {
571
+ return variables == null ? void 0 : variables.map((variable) => ({
572
+ key: variable.key,
573
+ type: variable.type,
574
+ fallback_value: variable.fallbackValue
575
+ }));
576
+ }
577
+ function parseTemplateToApiOptions(template) {
578
+ return {
579
+ name: "name" in template ? template.name : void 0,
580
+ subject: template.subject,
581
+ html: template.html,
582
+ text: template.text,
583
+ alias: template.alias,
584
+ from: template.from,
585
+ reply_to: template.replyTo,
586
+ variables: parseVariables(template.variables)
587
+ };
588
+ }
589
+
590
+ // src/templates/chainable-template-result.ts
591
+ var ChainableTemplateResult = class {
592
+ constructor(promise, publishFn) {
593
+ this.promise = promise;
594
+ this.publishFn = publishFn;
595
+ }
596
+ // If user calls `then` or only awaits for the result of create() or duplicate(), the behavior should be
597
+ // exactly as if they called create() or duplicate() directly. This will act as a normal promise
598
+ // biome-ignore lint/suspicious/noThenProperty: This class intentionally implements PromiseLike
599
+ then(onfulfilled, onrejected) {
600
+ return this.promise.then(onfulfilled, onrejected);
601
+ }
602
+ publish() {
603
+ return __async(this, null, function* () {
604
+ const { data, error } = yield this.promise;
605
+ if (error) {
606
+ return {
607
+ data: null,
608
+ error
609
+ };
610
+ }
611
+ const publishResult = yield this.publishFn(data.id);
612
+ return publishResult;
613
+ });
614
+ }
615
+ };
616
+
617
+ // src/templates/templates.ts
618
+ var Templates = class {
619
+ constructor(resend) {
620
+ this.resend = resend;
621
+ }
622
+ create(payload) {
623
+ const createPromise = this.performCreate(payload);
624
+ return new ChainableTemplateResult(createPromise, this.publish.bind(this));
625
+ }
626
+ // This creation process is being done separately from the public create so that
627
+ // the user can chain the publish operation after the create operation. Otherwise, due
628
+ // to the async nature of the renderAsync, the return type would be
629
+ // Promise<ChainableTemplateResult<CreateTemplateResponse>> which wouldn't be chainable.
630
+ performCreate(payload) {
631
+ return __async(this, null, function* () {
632
+ if (payload.react) {
633
+ if (!this.renderAsync) {
634
+ try {
635
+ const { renderAsync } = yield import("@react-email/render");
636
+ this.renderAsync = renderAsync;
637
+ } catch (e) {
638
+ throw new Error(
639
+ "Failed to render React component. Make sure to install `@react-email/render`"
640
+ );
641
+ }
642
+ }
643
+ payload.html = yield this.renderAsync(
644
+ payload.react
645
+ );
646
+ }
647
+ return this.resend.post(
648
+ "/templates",
649
+ parseTemplateToApiOptions(payload)
650
+ );
651
+ });
652
+ }
653
+ remove(identifier) {
654
+ return __async(this, null, function* () {
655
+ const data = yield this.resend.delete(
656
+ `/templates/${identifier}`
657
+ );
658
+ return data;
659
+ });
660
+ }
661
+ get(identifier) {
662
+ return __async(this, null, function* () {
663
+ const data = yield this.resend.get(
664
+ `/templates/${identifier}`
665
+ );
666
+ return data;
667
+ });
668
+ }
669
+ list() {
670
+ return __async(this, arguments, function* (options = {}) {
671
+ return this.resend.get(
672
+ `/templates${getPaginationQueryProperties(options)}`
673
+ );
674
+ });
675
+ }
676
+ duplicate(identifier) {
677
+ const promiseDuplicate = this.resend.post(
678
+ `/templates/${identifier}/duplicate`
679
+ );
680
+ return new ChainableTemplateResult(
681
+ promiseDuplicate,
682
+ this.publish.bind(this)
683
+ );
684
+ }
685
+ publish(identifier) {
686
+ return __async(this, null, function* () {
687
+ const data = yield this.resend.post(
688
+ `/templates/${identifier}/publish`
689
+ );
690
+ return data;
691
+ });
692
+ }
693
+ update(identifier, payload) {
694
+ return __async(this, null, function* () {
695
+ const data = yield this.resend.patch(
696
+ `/templates/${identifier}`,
697
+ parseTemplateToApiOptions(payload)
698
+ );
699
+ return data;
700
+ });
701
+ }
702
+ };
703
+
556
704
  // src/resend.ts
557
705
  var defaultBaseUrl = "https://api.resend.com";
558
706
  var defaultUserAgent = `resend-node:${version}`;
@@ -568,6 +716,7 @@ var Resend = class {
568
716
  this.contacts = new Contacts(this);
569
717
  this.domains = new Domains(this);
570
718
  this.emails = new Emails(this);
719
+ this.templates = new Templates(this);
571
720
  if (!key) {
572
721
  if (typeof process !== "undefined" && process.env) {
573
722
  this.key = process.env.RESEND_API_KEY;
package/dist/index.mjs CHANGED
@@ -51,7 +51,7 @@ var __async = (__this, __arguments, generator) => {
51
51
  };
52
52
 
53
53
  // package.json
54
- var version = "6.1.1";
54
+ var version = "6.1.2-preview-templates.0";
55
55
 
56
56
  // src/common/utils/build-pagination-query.ts
57
57
  function buildPaginationQuery(options) {
@@ -165,7 +165,11 @@ function parseEmailToApiOptions(email) {
165
165
  subject: email.subject,
166
166
  tags: email.tags,
167
167
  text: email.text,
168
- to: email.to
168
+ to: email.to,
169
+ template: email.template ? {
170
+ id: email.template.id,
171
+ variables: email.template.variables
172
+ } : void 0
169
173
  };
170
174
  }
171
175
 
@@ -177,7 +181,7 @@ function render(node) {
177
181
  }).catch(() => {
178
182
  reject(
179
183
  Error(
180
- "Failed to render React component. Make sure to install `@react-email/render`"
184
+ "Failed to render React component. Make sure to install `@react-email/render` or `@react-email/components`."
181
185
  )
182
186
  );
183
187
  });
@@ -520,6 +524,150 @@ var Emails = class {
520
524
  }
521
525
  };
522
526
 
527
+ // src/common/utils/get-pagination-query-properties.ts
528
+ function getPaginationQueryProperties(options = {}) {
529
+ const query = new URLSearchParams();
530
+ if (options.before) query.set("before", options.before);
531
+ if (options.after) query.set("after", options.after);
532
+ if (options.limit) query.set("limit", options.limit.toString());
533
+ return query.size > 0 ? `?${query.toString()}` : "";
534
+ }
535
+
536
+ // src/common/utils/parse-template-to-api-options.ts
537
+ function parseVariables(variables) {
538
+ return variables == null ? void 0 : variables.map((variable) => ({
539
+ key: variable.key,
540
+ type: variable.type,
541
+ fallback_value: variable.fallbackValue
542
+ }));
543
+ }
544
+ function parseTemplateToApiOptions(template) {
545
+ return {
546
+ name: "name" in template ? template.name : void 0,
547
+ subject: template.subject,
548
+ html: template.html,
549
+ text: template.text,
550
+ alias: template.alias,
551
+ from: template.from,
552
+ reply_to: template.replyTo,
553
+ variables: parseVariables(template.variables)
554
+ };
555
+ }
556
+
557
+ // src/templates/chainable-template-result.ts
558
+ var ChainableTemplateResult = class {
559
+ constructor(promise, publishFn) {
560
+ this.promise = promise;
561
+ this.publishFn = publishFn;
562
+ }
563
+ // If user calls `then` or only awaits for the result of create() or duplicate(), the behavior should be
564
+ // exactly as if they called create() or duplicate() directly. This will act as a normal promise
565
+ // biome-ignore lint/suspicious/noThenProperty: This class intentionally implements PromiseLike
566
+ then(onfulfilled, onrejected) {
567
+ return this.promise.then(onfulfilled, onrejected);
568
+ }
569
+ publish() {
570
+ return __async(this, null, function* () {
571
+ const { data, error } = yield this.promise;
572
+ if (error) {
573
+ return {
574
+ data: null,
575
+ error
576
+ };
577
+ }
578
+ const publishResult = yield this.publishFn(data.id);
579
+ return publishResult;
580
+ });
581
+ }
582
+ };
583
+
584
+ // src/templates/templates.ts
585
+ var Templates = class {
586
+ constructor(resend) {
587
+ this.resend = resend;
588
+ }
589
+ create(payload) {
590
+ const createPromise = this.performCreate(payload);
591
+ return new ChainableTemplateResult(createPromise, this.publish.bind(this));
592
+ }
593
+ // This creation process is being done separately from the public create so that
594
+ // the user can chain the publish operation after the create operation. Otherwise, due
595
+ // to the async nature of the renderAsync, the return type would be
596
+ // Promise<ChainableTemplateResult<CreateTemplateResponse>> which wouldn't be chainable.
597
+ performCreate(payload) {
598
+ return __async(this, null, function* () {
599
+ if (payload.react) {
600
+ if (!this.renderAsync) {
601
+ try {
602
+ const { renderAsync } = yield import("@react-email/render");
603
+ this.renderAsync = renderAsync;
604
+ } catch (e) {
605
+ throw new Error(
606
+ "Failed to render React component. Make sure to install `@react-email/render`"
607
+ );
608
+ }
609
+ }
610
+ payload.html = yield this.renderAsync(
611
+ payload.react
612
+ );
613
+ }
614
+ return this.resend.post(
615
+ "/templates",
616
+ parseTemplateToApiOptions(payload)
617
+ );
618
+ });
619
+ }
620
+ remove(identifier) {
621
+ return __async(this, null, function* () {
622
+ const data = yield this.resend.delete(
623
+ `/templates/${identifier}`
624
+ );
625
+ return data;
626
+ });
627
+ }
628
+ get(identifier) {
629
+ return __async(this, null, function* () {
630
+ const data = yield this.resend.get(
631
+ `/templates/${identifier}`
632
+ );
633
+ return data;
634
+ });
635
+ }
636
+ list() {
637
+ return __async(this, arguments, function* (options = {}) {
638
+ return this.resend.get(
639
+ `/templates${getPaginationQueryProperties(options)}`
640
+ );
641
+ });
642
+ }
643
+ duplicate(identifier) {
644
+ const promiseDuplicate = this.resend.post(
645
+ `/templates/${identifier}/duplicate`
646
+ );
647
+ return new ChainableTemplateResult(
648
+ promiseDuplicate,
649
+ this.publish.bind(this)
650
+ );
651
+ }
652
+ publish(identifier) {
653
+ return __async(this, null, function* () {
654
+ const data = yield this.resend.post(
655
+ `/templates/${identifier}/publish`
656
+ );
657
+ return data;
658
+ });
659
+ }
660
+ update(identifier, payload) {
661
+ return __async(this, null, function* () {
662
+ const data = yield this.resend.patch(
663
+ `/templates/${identifier}`,
664
+ parseTemplateToApiOptions(payload)
665
+ );
666
+ return data;
667
+ });
668
+ }
669
+ };
670
+
523
671
  // src/resend.ts
524
672
  var defaultBaseUrl = "https://api.resend.com";
525
673
  var defaultUserAgent = `resend-node:${version}`;
@@ -535,6 +683,7 @@ var Resend = class {
535
683
  this.contacts = new Contacts(this);
536
684
  this.domains = new Domains(this);
537
685
  this.emails = new Emails(this);
686
+ this.templates = new Templates(this);
538
687
  if (!key) {
539
688
  if (typeof process !== "undefined" && process.env) {
540
689
  this.key = process.env.RESEND_API_KEY;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "resend",
3
- "version": "6.1.1",
3
+ "version": "6.1.2-preview-templates.0",
4
4
  "description": "Node.js library for the Resend API",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -23,6 +23,16 @@
23
23
  }
24
24
  }
25
25
  },
26
+ "scripts": {
27
+ "build": "tsup src/index.ts --format esm,cjs --dts",
28
+ "format": "biome format --write .",
29
+ "format:apply": "biome check --write .",
30
+ "format:check": "biome format .",
31
+ "lint": "biome check .",
32
+ "prepublishOnly": "pnpm run build",
33
+ "test": "vitest run",
34
+ "test:watch": "vitest"
35
+ },
26
36
  "repository": {
27
37
  "type": "git",
28
38
  "url": "git+https://github.com/resendlabs/resend-node.git"
@@ -34,7 +44,7 @@
34
44
  },
35
45
  "homepage": "https://github.com/resendlabs/resend-node#readme",
36
46
  "peerDependencies": {
37
- "@react-email/render": "^1.1.0"
47
+ "@react-email/render": "*"
38
48
  },
39
49
  "peerDependenciesMeta": {
40
50
  "@react-email/render": {
@@ -51,13 +61,5 @@
51
61
  "vitest": "3.2.4",
52
62
  "vitest-fetch-mock": "0.4.5"
53
63
  },
54
- "scripts": {
55
- "build": "tsup src/index.ts --format esm,cjs --dts",
56
- "format": "biome format --write .",
57
- "format:apply": "biome check --write .",
58
- "format:check": "biome format .",
59
- "lint": "biome check .",
60
- "test": "vitest run",
61
- "test:watch": "vitest"
62
- }
63
- }
64
+ "packageManager": "pnpm@10.17.1"
65
+ }