@funnelsgrove/emails 0.1.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 +84 -0
- package/dist/index.d.ts +193 -0
- package/dist/index.js +136 -0
- package/dist/index.js.map +1 -0
- package/package.json +39 -0
package/README.md
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# @funnelsgrove/emails
|
|
2
|
+
|
|
3
|
+
Private-token email client for the FunnelsGrove transactional email API.
|
|
4
|
+
|
|
5
|
+
```ts
|
|
6
|
+
import { createEmailsClient } from '@funnelsgrove/emails';
|
|
7
|
+
|
|
8
|
+
const emails = createEmailsClient({
|
|
9
|
+
privateToken: process.env.FUNNELSGROVE_PRIVATE_TOKEN!,
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
const receipt = await emails.send({
|
|
13
|
+
template: 'login-code',
|
|
14
|
+
to: 'person@example.com',
|
|
15
|
+
variables: { code: '481953', expiresInMinutes: 10 },
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
console.log(receipt.id);
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
The private token is sent as `Authorization: Bearer <token>` and is never intended for browser code. The template must be published in the project first. Project email content is managed through the existing `fgrove email` CLI.
|
|
22
|
+
|
|
23
|
+
Create and publish a template from Node.js or the CLI:
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
await emails.createTemplate({
|
|
27
|
+
slug: 'order-confirmation',
|
|
28
|
+
name: 'Order confirmation',
|
|
29
|
+
draft: {
|
|
30
|
+
subject: 'Order {{ORDER_ID}}',
|
|
31
|
+
previewText: null,
|
|
32
|
+
html: '<p>Order {{ORDER_ID}}</p>',
|
|
33
|
+
text: 'Order {{ORDER_ID}}',
|
|
34
|
+
variables: { ORDER_ID: 'string' },
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
fgrove email pull --workspace "$WORKSPACE" --project "$PROJECT"
|
|
41
|
+
fgrove email validate --dir .
|
|
42
|
+
fgrove email push --workspace "$WORKSPACE" --project "$PROJECT"
|
|
43
|
+
fgrove email template publish order-confirmation --workspace "$WORKSPACE" --project "$PROJECT"
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Sequence steps can use a published template or direct subject/body copy. Delays stay simple: hours or days. An empty `funnelIds` list applies to all funnels:
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
const sequence = await emails.createSequence({
|
|
50
|
+
slug: 'lead-follow-up',
|
|
51
|
+
name: 'Lead follow-up',
|
|
52
|
+
draft: {
|
|
53
|
+
triggerEventType: 'email_captured',
|
|
54
|
+
funnelIds: [],
|
|
55
|
+
steps: [{
|
|
56
|
+
key: 'welcome',
|
|
57
|
+
mode: 'template',
|
|
58
|
+
template: 'welcome',
|
|
59
|
+
variables: { firstName: 'first_name' },
|
|
60
|
+
delay: { value: 0, unit: 'hours' },
|
|
61
|
+
}],
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
await emails.addSequenceStep(sequence.id, {
|
|
66
|
+
key: 'reminder',
|
|
67
|
+
mode: 'direct',
|
|
68
|
+
subject: 'A quick reminder',
|
|
69
|
+
body: 'Come back when you are ready.',
|
|
70
|
+
delay: { value: 2, unit: 'days' },
|
|
71
|
+
});
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Sequence editing uses the same project CLI with `fgrove email sequence add-step` and local JSON files:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
fgrove email sequence add-step lead-follow-up \
|
|
78
|
+
--workspace "$WORKSPACE" \
|
|
79
|
+
--project "$PROJECT" \
|
|
80
|
+
--key reminder \
|
|
81
|
+
--subject "A quick reminder" \
|
|
82
|
+
--body "Come back when you are ready." \
|
|
83
|
+
--delay-days 2
|
|
84
|
+
```
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
export declare const DEFAULT_EMAILS_API_URL = "https://sdk-api.funnelsgrove.com";
|
|
2
|
+
export type EmailVariable = string | number | boolean;
|
|
3
|
+
export type SendEmailInput = {
|
|
4
|
+
template: string;
|
|
5
|
+
to: string;
|
|
6
|
+
variables?: Record<string, EmailVariable>;
|
|
7
|
+
idempotencyKey?: string;
|
|
8
|
+
};
|
|
9
|
+
export type EmailReceipt = {
|
|
10
|
+
id: string;
|
|
11
|
+
status: 'queued' | 'sent' | 'failed' | 'unknown';
|
|
12
|
+
};
|
|
13
|
+
export type EmailStatus = EmailReceipt & {
|
|
14
|
+
terminalReason: string | null;
|
|
15
|
+
createdAt: string;
|
|
16
|
+
updatedAt: string;
|
|
17
|
+
sentAt: string | null;
|
|
18
|
+
failedAt: string | null;
|
|
19
|
+
};
|
|
20
|
+
export type EmailTemplateVariableType = 'string' | 'number' | 'boolean';
|
|
21
|
+
export type EmailTemplateDraft = {
|
|
22
|
+
subject: string;
|
|
23
|
+
previewText: string | null;
|
|
24
|
+
html: string;
|
|
25
|
+
text: string;
|
|
26
|
+
variables: Record<string, EmailTemplateVariableType>;
|
|
27
|
+
};
|
|
28
|
+
export type EmailTemplate = {
|
|
29
|
+
id: string;
|
|
30
|
+
slug: string;
|
|
31
|
+
name: string;
|
|
32
|
+
currentPublishedVersionId: string | null;
|
|
33
|
+
draft: EmailTemplateDraft;
|
|
34
|
+
createdAt?: string;
|
|
35
|
+
updatedAt?: string;
|
|
36
|
+
};
|
|
37
|
+
export type EmailTemplateVersion = {
|
|
38
|
+
id: string;
|
|
39
|
+
templateId: string;
|
|
40
|
+
version: number;
|
|
41
|
+
subject: string;
|
|
42
|
+
previewText: string | null;
|
|
43
|
+
html: string;
|
|
44
|
+
text: string;
|
|
45
|
+
variables: Record<string, EmailTemplateVariableType>;
|
|
46
|
+
publishedAt: string;
|
|
47
|
+
};
|
|
48
|
+
export type EmailTemplateDetail = {
|
|
49
|
+
template: EmailTemplate;
|
|
50
|
+
versions: EmailTemplateVersion[];
|
|
51
|
+
};
|
|
52
|
+
export type SequenceDelay = {
|
|
53
|
+
value: number;
|
|
54
|
+
unit: 'hours' | 'days';
|
|
55
|
+
};
|
|
56
|
+
export type EmailSequenceTemplateStepInput = {
|
|
57
|
+
key: string;
|
|
58
|
+
mode?: 'template';
|
|
59
|
+
template: string;
|
|
60
|
+
variables?: Record<string, EmailVariable>;
|
|
61
|
+
delay: SequenceDelay;
|
|
62
|
+
};
|
|
63
|
+
export type EmailSequenceDirectStepInput = {
|
|
64
|
+
key: string;
|
|
65
|
+
mode: 'direct';
|
|
66
|
+
subject: string;
|
|
67
|
+
body: string;
|
|
68
|
+
delay: SequenceDelay;
|
|
69
|
+
};
|
|
70
|
+
export type EmailSequenceStepInput = EmailSequenceTemplateStepInput | EmailSequenceDirectStepInput;
|
|
71
|
+
export type EmailSequenceTemplateStep = {
|
|
72
|
+
key: string;
|
|
73
|
+
delaySeconds: number;
|
|
74
|
+
mode: 'template';
|
|
75
|
+
templateVersionId: string;
|
|
76
|
+
variables: Record<string, EmailVariable>;
|
|
77
|
+
};
|
|
78
|
+
export type EmailSequenceDirectStep = {
|
|
79
|
+
key: string;
|
|
80
|
+
delaySeconds: number;
|
|
81
|
+
mode: 'direct';
|
|
82
|
+
subject: string;
|
|
83
|
+
body: string;
|
|
84
|
+
};
|
|
85
|
+
export type EmailSequenceStep = EmailSequenceTemplateStep | EmailSequenceDirectStep;
|
|
86
|
+
export type EmailSequenceDraftInput = {
|
|
87
|
+
triggerEventType: 'email_captured' | 'purchase_completed' | 'registration_completed';
|
|
88
|
+
/** Empty means this sequence runs for every funnel in the project. */
|
|
89
|
+
funnelIds?: string[];
|
|
90
|
+
steps: EmailSequenceStepInput[];
|
|
91
|
+
exitEventTypes?: Array<'email_captured' | 'purchase_completed' | 'registration_completed'>;
|
|
92
|
+
};
|
|
93
|
+
export type EmailSequenceDraft = {
|
|
94
|
+
triggerEventType: EmailSequenceDraftInput['triggerEventType'];
|
|
95
|
+
funnelIds: string[];
|
|
96
|
+
steps: EmailSequenceStep[];
|
|
97
|
+
exitEventTypes: NonNullable<EmailSequenceDraftInput['exitEventTypes']>;
|
|
98
|
+
};
|
|
99
|
+
export type EmailSequence = {
|
|
100
|
+
id: string;
|
|
101
|
+
slug: string;
|
|
102
|
+
name: string;
|
|
103
|
+
currentPublishedVersionId: string | null;
|
|
104
|
+
isActive: boolean;
|
|
105
|
+
draft: EmailSequenceDraft;
|
|
106
|
+
};
|
|
107
|
+
export type EmailSequenceVersion = EmailSequenceDraft & {
|
|
108
|
+
id: string;
|
|
109
|
+
sequenceId: string;
|
|
110
|
+
version: number;
|
|
111
|
+
sender: {
|
|
112
|
+
domainId: string;
|
|
113
|
+
domain: string;
|
|
114
|
+
fromLocalPart: string;
|
|
115
|
+
displayName: string | null;
|
|
116
|
+
};
|
|
117
|
+
publishedAt: string;
|
|
118
|
+
};
|
|
119
|
+
export type EmailSequenceDetail = {
|
|
120
|
+
sequence: EmailSequence;
|
|
121
|
+
versions: EmailSequenceVersion[];
|
|
122
|
+
};
|
|
123
|
+
export type CreateSequenceInput = {
|
|
124
|
+
slug: string;
|
|
125
|
+
name: string;
|
|
126
|
+
draft: EmailSequenceDraftInput;
|
|
127
|
+
};
|
|
128
|
+
export declare class EmailsApiError extends Error {
|
|
129
|
+
readonly status: number;
|
|
130
|
+
constructor(status: number, message: string);
|
|
131
|
+
}
|
|
132
|
+
export type EmailsClientOptions = {
|
|
133
|
+
privateToken: string;
|
|
134
|
+
apiUrl?: string;
|
|
135
|
+
fetch?: typeof globalThis.fetch;
|
|
136
|
+
};
|
|
137
|
+
export type CreateTemplateInput = {
|
|
138
|
+
slug?: string;
|
|
139
|
+
name?: string;
|
|
140
|
+
starter?: 'login-code';
|
|
141
|
+
draft?: EmailTemplateDraft;
|
|
142
|
+
publish?: boolean;
|
|
143
|
+
};
|
|
144
|
+
export type UpdateTemplateInput = {
|
|
145
|
+
name?: string;
|
|
146
|
+
draft: Partial<EmailTemplateDraft>;
|
|
147
|
+
};
|
|
148
|
+
export declare class EmailsClient {
|
|
149
|
+
private readonly apiUrl;
|
|
150
|
+
private readonly privateToken;
|
|
151
|
+
private readonly fetchFn;
|
|
152
|
+
constructor(options: EmailsClientOptions);
|
|
153
|
+
send(input: SendEmailInput): Promise<EmailReceipt>;
|
|
154
|
+
get(deliveryId: string): Promise<EmailStatus>;
|
|
155
|
+
private request;
|
|
156
|
+
listTemplates(): Promise<EmailTemplate[]>;
|
|
157
|
+
getTemplate(templateId: string): Promise<EmailTemplateDetail>;
|
|
158
|
+
createTemplate(input: CreateTemplateInput): Promise<EmailTemplate | {
|
|
159
|
+
template: EmailTemplate;
|
|
160
|
+
version: EmailTemplateVersion;
|
|
161
|
+
}>;
|
|
162
|
+
updateTemplate(templateId: string, input: UpdateTemplateInput): Promise<EmailTemplate>;
|
|
163
|
+
validateTemplate(templateId: string): Promise<{
|
|
164
|
+
valid: true;
|
|
165
|
+
}>;
|
|
166
|
+
previewTemplate(templateId: string, values: Record<string, EmailVariable>): Promise<{
|
|
167
|
+
subject: string;
|
|
168
|
+
previewText: string | null;
|
|
169
|
+
html: string;
|
|
170
|
+
text: string;
|
|
171
|
+
}>;
|
|
172
|
+
sendTemplateTest(templateId: string, recipientEmail: string, values: Record<string, EmailVariable>): Promise<EmailReceipt>;
|
|
173
|
+
publishTemplate(templateId: string): Promise<{
|
|
174
|
+
template: EmailTemplate;
|
|
175
|
+
version: EmailTemplateVersion;
|
|
176
|
+
}>;
|
|
177
|
+
listSequences(): Promise<EmailSequence[]>;
|
|
178
|
+
getSequence(sequenceId: string): Promise<EmailSequenceDetail>;
|
|
179
|
+
createSequence(input: CreateSequenceInput): Promise<EmailSequence>;
|
|
180
|
+
updateSequence(sequenceId: string, input: {
|
|
181
|
+
name?: string;
|
|
182
|
+
draft: EmailSequenceDraftInput;
|
|
183
|
+
}): Promise<EmailSequence>;
|
|
184
|
+
addSequenceStep(sequenceId: string, step: EmailSequenceStepInput): Promise<EmailSequence>;
|
|
185
|
+
validateSequence(sequenceId: string): Promise<{
|
|
186
|
+
valid: true;
|
|
187
|
+
}>;
|
|
188
|
+
publishSequence(sequenceId: string): Promise<{
|
|
189
|
+
sequence: EmailSequence;
|
|
190
|
+
version: EmailSequenceVersion;
|
|
191
|
+
}>;
|
|
192
|
+
}
|
|
193
|
+
export declare const createEmailsClient: (options: EmailsClientOptions) => EmailsClient;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
export const DEFAULT_EMAILS_API_URL = 'https://sdk-api.funnelsgrove.com';
|
|
3
|
+
export class EmailsApiError extends Error {
|
|
4
|
+
status;
|
|
5
|
+
constructor(status, message) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.status = status;
|
|
8
|
+
this.name = 'EmailsApiError';
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
const trimUrl = (value) => value.trim().replace(/\/+$/, '');
|
|
12
|
+
const readJson = async (response) => {
|
|
13
|
+
const body = await response.text();
|
|
14
|
+
try {
|
|
15
|
+
return JSON.parse(body);
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return { error: body || response.statusText || 'Email API request failed' };
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
const errorMessage = (value) => (value && typeof value === 'object' && 'error' in value && typeof value.error === 'string'
|
|
22
|
+
? value.error
|
|
23
|
+
: 'Email API request failed');
|
|
24
|
+
export class EmailsClient {
|
|
25
|
+
apiUrl;
|
|
26
|
+
privateToken;
|
|
27
|
+
fetchFn;
|
|
28
|
+
constructor(options) {
|
|
29
|
+
if (!options.privateToken.trim())
|
|
30
|
+
throw new Error('privateToken is required');
|
|
31
|
+
this.privateToken = options.privateToken.trim();
|
|
32
|
+
this.apiUrl = trimUrl(options.apiUrl || DEFAULT_EMAILS_API_URL);
|
|
33
|
+
this.fetchFn = options.fetch || globalThis.fetch;
|
|
34
|
+
}
|
|
35
|
+
async send(input) {
|
|
36
|
+
const response = await this.fetchFn(`${this.apiUrl}/sdk/private/emails/send`, {
|
|
37
|
+
method: 'POST',
|
|
38
|
+
headers: {
|
|
39
|
+
authorization: `Bearer ${this.privateToken}`,
|
|
40
|
+
'content-type': 'application/json',
|
|
41
|
+
'idempotency-key': input.idempotencyKey || `email-${randomUUID()}`,
|
|
42
|
+
},
|
|
43
|
+
body: JSON.stringify({
|
|
44
|
+
template: input.template,
|
|
45
|
+
to: input.to,
|
|
46
|
+
variables: input.variables || {},
|
|
47
|
+
}),
|
|
48
|
+
});
|
|
49
|
+
const body = await readJson(response);
|
|
50
|
+
if (!response.ok)
|
|
51
|
+
throw new EmailsApiError(response.status, errorMessage(body));
|
|
52
|
+
return body;
|
|
53
|
+
}
|
|
54
|
+
async get(deliveryId) {
|
|
55
|
+
const response = await this.fetchFn(`${this.apiUrl}/sdk/private/emails/${encodeURIComponent(deliveryId)}`, {
|
|
56
|
+
headers: { authorization: `Bearer ${this.privateToken}` },
|
|
57
|
+
});
|
|
58
|
+
const body = await readJson(response);
|
|
59
|
+
if (!response.ok)
|
|
60
|
+
throw new EmailsApiError(response.status, errorMessage(body));
|
|
61
|
+
return body;
|
|
62
|
+
}
|
|
63
|
+
async request(path, init = {}) {
|
|
64
|
+
const response = await this.fetchFn(`${this.apiUrl}${path}`, {
|
|
65
|
+
...init,
|
|
66
|
+
headers: {
|
|
67
|
+
authorization: `Bearer ${this.privateToken}`,
|
|
68
|
+
...(init.body ? { 'content-type': 'application/json' } : {}),
|
|
69
|
+
...init.headers,
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
const body = await readJson(response);
|
|
73
|
+
if (!response.ok)
|
|
74
|
+
throw new EmailsApiError(response.status, errorMessage(body));
|
|
75
|
+
return body;
|
|
76
|
+
}
|
|
77
|
+
async listTemplates() {
|
|
78
|
+
return this.request('/sdk/private/templates');
|
|
79
|
+
}
|
|
80
|
+
async getTemplate(templateId) {
|
|
81
|
+
return this.request(`/sdk/private/templates/${encodeURIComponent(templateId)}`);
|
|
82
|
+
}
|
|
83
|
+
async createTemplate(input) {
|
|
84
|
+
return this.request('/sdk/private/templates', {
|
|
85
|
+
method: 'POST',
|
|
86
|
+
body: JSON.stringify(input),
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
async updateTemplate(templateId, input) {
|
|
90
|
+
return this.request(`/sdk/private/templates/${encodeURIComponent(templateId)}`, {
|
|
91
|
+
method: 'PATCH',
|
|
92
|
+
body: JSON.stringify(input),
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
async validateTemplate(templateId) {
|
|
96
|
+
return this.request(`/sdk/private/templates/${encodeURIComponent(templateId)}/validate`, { method: 'POST' });
|
|
97
|
+
}
|
|
98
|
+
async previewTemplate(templateId, values) {
|
|
99
|
+
return this.request(`/sdk/private/templates/${encodeURIComponent(templateId)}/preview`, {
|
|
100
|
+
method: 'POST',
|
|
101
|
+
body: JSON.stringify({ values }),
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
async sendTemplateTest(templateId, recipientEmail, values) {
|
|
105
|
+
return this.request(`/sdk/private/templates/${encodeURIComponent(templateId)}/test-send`, {
|
|
106
|
+
method: 'POST',
|
|
107
|
+
body: JSON.stringify({ recipientEmail, values }),
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
async publishTemplate(templateId) {
|
|
111
|
+
return this.request(`/sdk/private/templates/${encodeURIComponent(templateId)}/publish`, { method: 'POST' });
|
|
112
|
+
}
|
|
113
|
+
async listSequences() {
|
|
114
|
+
return this.request('/sdk/private/sequences');
|
|
115
|
+
}
|
|
116
|
+
async getSequence(sequenceId) {
|
|
117
|
+
return this.request(`/sdk/private/sequences/${encodeURIComponent(sequenceId)}`);
|
|
118
|
+
}
|
|
119
|
+
async createSequence(input) {
|
|
120
|
+
return this.request('/sdk/private/sequences', { method: 'POST', body: JSON.stringify(input) });
|
|
121
|
+
}
|
|
122
|
+
async updateSequence(sequenceId, input) {
|
|
123
|
+
return this.request(`/sdk/private/sequences/${encodeURIComponent(sequenceId)}`, { method: 'PATCH', body: JSON.stringify(input) });
|
|
124
|
+
}
|
|
125
|
+
async addSequenceStep(sequenceId, step) {
|
|
126
|
+
return this.request(`/sdk/private/sequences/${encodeURIComponent(sequenceId)}/steps`, { method: 'POST', body: JSON.stringify(step) });
|
|
127
|
+
}
|
|
128
|
+
async validateSequence(sequenceId) {
|
|
129
|
+
return this.request(`/sdk/private/sequences/${encodeURIComponent(sequenceId)}/validate`, { method: 'POST' });
|
|
130
|
+
}
|
|
131
|
+
async publishSequence(sequenceId) {
|
|
132
|
+
return this.request(`/sdk/private/sequences/${encodeURIComponent(sequenceId)}/publish`, { method: 'POST' });
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
export const createEmailsClient = (options) => new EmailsClient(options);
|
|
136
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@funnelsgrove/emails",
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "FunnelsGrove private email API client",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/The-Solid-Grove/funnelsgrove.git",
|
|
8
|
+
"directory": "apps/funnel-emails"
|
|
9
|
+
},
|
|
10
|
+
"type": "module",
|
|
11
|
+
"private": false,
|
|
12
|
+
"main": "./dist/index.js",
|
|
13
|
+
"module": "./dist/index.js",
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"exports": {
|
|
16
|
+
".": {
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"import": "./dist/index.js",
|
|
19
|
+
"default": "./dist/index.js"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"dist",
|
|
24
|
+
"README.md"
|
|
25
|
+
],
|
|
26
|
+
"publishConfig": {
|
|
27
|
+
"access": "public"
|
|
28
|
+
},
|
|
29
|
+
"scripts": {
|
|
30
|
+
"build": "rm -rf dist && tsc -p tsconfig.build.json && node ../../scripts/fix-esm-relative-imports.mjs dist",
|
|
31
|
+
"prepublishOnly": "npm run build",
|
|
32
|
+
"test:run": "vitest run --passWithNoTests"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@types/node": "^20",
|
|
36
|
+
"typescript": "^5",
|
|
37
|
+
"vitest": "^3.2.4"
|
|
38
|
+
}
|
|
39
|
+
}
|