@logto/connector-aws-ses 1.1.2 → 1.2.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/lib/index.js CHANGED
@@ -1,14 +1,227 @@
1
- export { az as default } from './index-s7VGoewj.js';
2
- import '@logto/connector-kit';
3
- import 'zod';
4
- import 'os';
5
- import 'path';
6
- import 'crypto';
7
- import 'fs';
8
- import 'buffer';
9
- import 'stream';
10
- import 'http';
11
- import 'https';
12
- import 'http2';
13
- import 'util';
14
- import 'process';
1
+ // src/index.ts
2
+ import { assert } from "@silverhand/essentials";
3
+ import { SESv2ServiceException } from "@aws-sdk/client-sesv2";
4
+ import {
5
+ ConnectorError,
6
+ ConnectorErrorCodes,
7
+ ConnectorType,
8
+ validateConfig
9
+ } from "@logto/connector-kit";
10
+
11
+ // src/constant.ts
12
+ import { ConnectorConfigFormItemType } from "@logto/connector-kit";
13
+ var defaultMetadata = {
14
+ id: "aws-ses-mail",
15
+ target: "aws-ses",
16
+ platform: null,
17
+ name: {
18
+ en: "AWS Direct Mail",
19
+ "zh-CN": "AWS\u90AE\u4EF6\u63A8\u9001",
20
+ "tr-TR": "AWS Direct Mail",
21
+ ko: "AWS \uB2E4\uC774\uB809\uD2B8 \uBA54\uC77C"
22
+ },
23
+ logo: "./logo.svg",
24
+ logoDark: "./logo-dark.svg",
25
+ description: {
26
+ en: "Amazon SES is a cloud email service provider that can integrate into any application for bulk email sending.",
27
+ "zh-CN": "Amazon SES \u662F\u4E91\u7535\u5B50\u90AE\u4EF6\u53D1\u9001\u670D\u52A1\u63D0\u4F9B\u5546\uFF0C\u5B83\u53EF\u4EE5\u96C6\u6210\u5230\u4EFB\u4F55\u5E94\u7528\u7A0B\u5E8F\u4E2D\uFF0C\u7528\u4E8E\u6279\u91CF\u53D1\u9001\u7535\u5B50\u90AE\u4EF6\u3002",
28
+ "tr-TR": "Amazon SES, toplu e-posta da\u011F\u0131t\u0131m\u0131 i\xE7in herhangi bir uygulamaya entegre edilebilen bir bulut e-posta da\u011F\u0131t\u0131m hizmeti sa\u011Flay\u0131c\u0131s\u0131d\u0131r.",
29
+ ko: "Amazon SES\uB294 \uBAA8\uB4E0 \uC560\uD50C\uB9AC\uCF00\uC774\uC158\uC5D0 \uD1B5\uD569\uD558\uC5EC \uB300\uB7C9\uC73C\uB85C \uC774\uBA54\uC77C\uC744 \uC804\uC1A1\uD560 \uC218 \uC788\uB294 \uD074\uB77C\uC6B0\uB4DC \uC774\uBA54\uC77C \uC11C\uBE44\uC2A4 \uACF5\uAE09\uC790\uC785\uB2C8\uB2E4."
30
+ },
31
+ readme: "./README.md",
32
+ formItems: [
33
+ {
34
+ key: "accessKeyId",
35
+ label: "Access Key ID",
36
+ type: ConnectorConfigFormItemType.Text,
37
+ required: true,
38
+ placeholder: "<access-key-id>"
39
+ },
40
+ {
41
+ key: "accessKeySecret",
42
+ label: "Access Key Secret",
43
+ type: ConnectorConfigFormItemType.Text,
44
+ required: true,
45
+ placeholder: "<access-key-secret>"
46
+ },
47
+ {
48
+ key: "region",
49
+ label: "Region",
50
+ type: ConnectorConfigFormItemType.Text,
51
+ required: true,
52
+ placeholder: "<region>"
53
+ },
54
+ {
55
+ key: "emailAddress",
56
+ label: "Email Address",
57
+ type: ConnectorConfigFormItemType.Text,
58
+ required: false,
59
+ placeholder: "<email-address>"
60
+ },
61
+ {
62
+ key: "emailAddressIdentityArn",
63
+ label: "Email Address Identity ARN",
64
+ type: ConnectorConfigFormItemType.Text,
65
+ required: false,
66
+ placeholder: "<email-address-identity-arn>"
67
+ },
68
+ {
69
+ key: "feedbackForwardingEmailAddress",
70
+ label: "Feedback Forwarding Email Address",
71
+ type: ConnectorConfigFormItemType.Text,
72
+ required: false,
73
+ placeholder: "<feedback-forwarding-email-address>"
74
+ },
75
+ {
76
+ key: "feedbackForwardingEmailAddressIdentityArn",
77
+ label: "Feedback Forwarding Email Address Identity ARN",
78
+ type: ConnectorConfigFormItemType.Text,
79
+ required: false,
80
+ placeholder: "<feedback-forwarding-email-address-identity-arn>"
81
+ },
82
+ {
83
+ key: "configurationSetName",
84
+ label: "Configuration Set Name",
85
+ type: ConnectorConfigFormItemType.Text,
86
+ required: false,
87
+ placeholder: "<configuration-set-name>"
88
+ },
89
+ {
90
+ key: "templates",
91
+ label: "Templates",
92
+ type: ConnectorConfigFormItemType.Json,
93
+ required: true,
94
+ defaultValue: [
95
+ {
96
+ usageType: "SignIn",
97
+ subject: "<sign-in-template-subject>",
98
+ content: "Your Logto sign-in verification code is {{code}}. The code will remain active for 10 minutes."
99
+ },
100
+ {
101
+ usageType: "Register",
102
+ subject: "<register-template-subject>",
103
+ content: "Your Logto sign-up verification code is {{code}}. The code will remain active for 10 minutes."
104
+ },
105
+ {
106
+ usageType: "ForgotPassword",
107
+ subject: "<forgot-password-template-subject>",
108
+ content: "Your Logto password change verification code is {{code}}. The code will remain active for 10 minutes."
109
+ },
110
+ {
111
+ usageType: "Generic",
112
+ subject: "<generic-template-subject>",
113
+ content: "Your Logto verification code is {{code}}. The code will remain active for 10 minutes."
114
+ }
115
+ ]
116
+ }
117
+ ]
118
+ };
119
+
120
+ // src/types.ts
121
+ import { z } from "zod";
122
+ var requiredTemplateUsageTypes = ["Register", "SignIn", "ForgotPassword", "Generic"];
123
+ var templateGuard = z.object({
124
+ usageType: z.string(),
125
+ subject: z.string(),
126
+ content: z.string()
127
+ // With variable {{code}}, support HTML
128
+ });
129
+ var awsSesConfigGuard = z.object({
130
+ accessKeyId: z.string(),
131
+ accessKeySecret: z.string(),
132
+ region: z.string(),
133
+ emailAddress: z.string().optional(),
134
+ emailAddressIdentityArn: z.string().optional(),
135
+ templates: z.array(templateGuard).refine(
136
+ (templates) => requiredTemplateUsageTypes.every(
137
+ (requiredType) => templates.map((template) => template.usageType).includes(requiredType)
138
+ ),
139
+ (templates) => ({
140
+ message: `Template with UsageType (${requiredTemplateUsageTypes.filter(
141
+ (requiredType) => !templates.map((template) => template.usageType).includes(requiredType)
142
+ ).join(", ")}) should be provided!`
143
+ })
144
+ ),
145
+ feedbackForwardingEmailAddress: z.string().optional(),
146
+ feedbackForwardingEmailAddressIdentityArn: z.string().optional(),
147
+ configurationSetName: z.string().optional()
148
+ });
149
+
150
+ // src/utils.ts
151
+ import { SendEmailCommand, SESv2Client } from "@aws-sdk/client-sesv2";
152
+ import { replaceSendMessageHandlebars } from "@logto/connector-kit";
153
+ var makeClient = (accessKeyId, secretAccessKey, region) => {
154
+ const credentials = {
155
+ accessKeyId,
156
+ secretAccessKey
157
+ };
158
+ return new SESv2Client({ credentials, region });
159
+ };
160
+ var makeEmailContent = (template, payload) => {
161
+ return {
162
+ Simple: {
163
+ Subject: { Data: replaceSendMessageHandlebars(template.subject, payload), Charset: "utf8" },
164
+ Body: {
165
+ Html: {
166
+ Data: replaceSendMessageHandlebars(template.content, payload)
167
+ }
168
+ }
169
+ }
170
+ };
171
+ };
172
+ var makeCommand = (config, emailContent, to) => {
173
+ return new SendEmailCommand({
174
+ Destination: { ToAddresses: [to] },
175
+ Content: emailContent,
176
+ FromEmailAddress: config.emailAddress,
177
+ FromEmailAddressIdentityArn: config.emailAddressIdentityArn,
178
+ FeedbackForwardingEmailAddress: config.feedbackForwardingEmailAddress,
179
+ FeedbackForwardingEmailAddressIdentityArn: config.feedbackForwardingEmailAddressIdentityArn,
180
+ ConfigurationSetName: config.configurationSetName
181
+ });
182
+ };
183
+
184
+ // src/index.ts
185
+ var sendMessage = (getConfig) => async (data, inputConfig) => {
186
+ const { to, type, payload } = data;
187
+ const config = inputConfig ?? await getConfig(defaultMetadata.id);
188
+ validateConfig(config, awsSesConfigGuard);
189
+ const { accessKeyId, accessKeySecret, region, templates } = config;
190
+ const template = templates.find((template2) => template2.usageType === type);
191
+ assert(
192
+ template,
193
+ new ConnectorError(
194
+ ConnectorErrorCodes.TemplateNotFound,
195
+ `Cannot find template for type: ${type}`
196
+ )
197
+ );
198
+ const client = makeClient(accessKeyId, accessKeySecret, region);
199
+ const emailContent = makeEmailContent(template, payload);
200
+ const command = makeCommand(config, emailContent, to);
201
+ try {
202
+ const response = await client.send(command);
203
+ assert(
204
+ response.$metadata.httpStatusCode === 200,
205
+ new ConnectorError(ConnectorErrorCodes.InvalidResponse, response)
206
+ );
207
+ return response.MessageId;
208
+ } catch (error) {
209
+ if (error instanceof SESv2ServiceException) {
210
+ throw new ConnectorError(ConnectorErrorCodes.InvalidResponse, error.message);
211
+ }
212
+ throw error;
213
+ }
214
+ };
215
+ var createAwsSesConnector = async ({ getConfig }) => {
216
+ return {
217
+ metadata: defaultMetadata,
218
+ type: ConnectorType.Email,
219
+ configGuard: awsSesConfigGuard,
220
+ sendMessage: sendMessage(getConfig)
221
+ };
222
+ };
223
+ var src_default = createAwsSesConnector;
224
+ export {
225
+ src_default as default
226
+ };
227
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/constant.ts","../src/types.ts","../src/utils.ts"],"sourcesContent":["import { assert } from '@silverhand/essentials';\n\nimport type { SESv2Client, SendEmailCommand, SendEmailCommandOutput } from '@aws-sdk/client-sesv2';\nimport { SESv2ServiceException } from '@aws-sdk/client-sesv2';\nimport type {\n CreateConnector,\n EmailConnector,\n GetConnectorConfig,\n SendMessageFunction,\n} from '@logto/connector-kit';\nimport {\n ConnectorError,\n ConnectorErrorCodes,\n ConnectorType,\n validateConfig,\n} from '@logto/connector-kit';\n\nimport { defaultMetadata } from './constant.js';\nimport { awsSesConfigGuard } from './types.js';\nimport { makeClient, makeCommand, makeEmailContent } from './utils.js';\n\nconst sendMessage =\n (getConfig: GetConnectorConfig): SendMessageFunction =>\n async (data, inputConfig) => {\n const { to, type, payload } = data;\n const config = inputConfig ?? (await getConfig(defaultMetadata.id));\n validateConfig(config, awsSesConfigGuard);\n const { accessKeyId, accessKeySecret, region, templates } = config;\n const template = templates.find((template) => template.usageType === type);\n\n assert(\n template,\n new ConnectorError(\n ConnectorErrorCodes.TemplateNotFound,\n `Cannot find template for type: ${type}`\n )\n );\n\n const client: SESv2Client = makeClient(accessKeyId, accessKeySecret, region);\n const emailContent = makeEmailContent(template, payload);\n const command: SendEmailCommand = makeCommand(config, emailContent, to);\n\n try {\n const response: SendEmailCommandOutput = await client.send(command);\n\n assert(\n response.$metadata.httpStatusCode === 200,\n new ConnectorError(ConnectorErrorCodes.InvalidResponse, response)\n );\n\n return response.MessageId;\n } catch (error: unknown) {\n if (error instanceof SESv2ServiceException) {\n throw new ConnectorError(ConnectorErrorCodes.InvalidResponse, error.message);\n }\n\n throw error;\n }\n };\n\nconst createAwsSesConnector: CreateConnector<EmailConnector> = async ({ getConfig }) => {\n return {\n metadata: defaultMetadata,\n type: ConnectorType.Email,\n configGuard: awsSesConfigGuard,\n sendMessage: sendMessage(getConfig),\n };\n};\n\nexport default createAwsSesConnector;\n","import type { ConnectorMetadata } from '@logto/connector-kit';\nimport { ConnectorConfigFormItemType } from '@logto/connector-kit';\n\nexport const defaultMetadata: ConnectorMetadata = {\n id: 'aws-ses-mail',\n target: 'aws-ses',\n platform: null,\n name: {\n en: 'AWS Direct Mail',\n 'zh-CN': 'AWS邮件推送',\n 'tr-TR': 'AWS Direct Mail',\n ko: 'AWS 다이렉트 메일',\n },\n logo: './logo.svg',\n logoDark: './logo-dark.svg',\n description: {\n en: 'Amazon SES is a cloud email service provider that can integrate into any application for bulk email sending.',\n 'zh-CN':\n 'Amazon SES 是云电子邮件发送服务提供商,它可以集成到任何应用程序中,用于批量发送电子邮件。',\n 'tr-TR':\n 'Amazon SES, toplu e-posta dağıtımı için herhangi bir uygulamaya entegre edilebilen bir bulut e-posta dağıtım hizmeti sağlayıcısıdır.',\n ko: 'Amazon SES는 모든 애플리케이션에 통합하여 대량으로 이메일을 전송할 수 있는 클라우드 이메일 서비스 공급자입니다.',\n },\n readme: './README.md',\n formItems: [\n {\n key: 'accessKeyId',\n label: 'Access Key ID',\n type: ConnectorConfigFormItemType.Text,\n required: true,\n placeholder: '<access-key-id>',\n },\n {\n key: 'accessKeySecret',\n label: 'Access Key Secret',\n type: ConnectorConfigFormItemType.Text,\n required: true,\n placeholder: '<access-key-secret>',\n },\n {\n key: 'region',\n label: 'Region',\n type: ConnectorConfigFormItemType.Text,\n required: true,\n placeholder: '<region>',\n },\n {\n key: 'emailAddress',\n label: 'Email Address',\n type: ConnectorConfigFormItemType.Text,\n required: false,\n placeholder: '<email-address>',\n },\n {\n key: 'emailAddressIdentityArn',\n label: 'Email Address Identity ARN',\n type: ConnectorConfigFormItemType.Text,\n required: false,\n placeholder: '<email-address-identity-arn>',\n },\n {\n key: 'feedbackForwardingEmailAddress',\n label: 'Feedback Forwarding Email Address',\n type: ConnectorConfigFormItemType.Text,\n required: false,\n placeholder: '<feedback-forwarding-email-address>',\n },\n {\n key: 'feedbackForwardingEmailAddressIdentityArn',\n label: 'Feedback Forwarding Email Address Identity ARN',\n type: ConnectorConfigFormItemType.Text,\n required: false,\n placeholder: '<feedback-forwarding-email-address-identity-arn>',\n },\n {\n key: 'configurationSetName',\n label: 'Configuration Set Name',\n type: ConnectorConfigFormItemType.Text,\n required: false,\n placeholder: '<configuration-set-name>',\n },\n {\n key: 'templates',\n label: 'Templates',\n type: ConnectorConfigFormItemType.Json,\n required: true,\n defaultValue: [\n {\n usageType: 'SignIn',\n subject: '<sign-in-template-subject>',\n content:\n 'Your Logto sign-in verification code is {{code}}. The code will remain active for 10 minutes.',\n },\n {\n usageType: 'Register',\n subject: '<register-template-subject>',\n content:\n 'Your Logto sign-up verification code is {{code}}. The code will remain active for 10 minutes.',\n },\n {\n usageType: 'ForgotPassword',\n subject: '<forgot-password-template-subject>',\n content:\n 'Your Logto password change verification code is {{code}}. The code will remain active for 10 minutes.',\n },\n {\n usageType: 'Generic',\n subject: '<generic-template-subject>',\n content:\n 'Your Logto verification code is {{code}}. The code will remain active for 10 minutes.',\n },\n ],\n },\n ],\n};\n","import { z } from 'zod';\n\n/**\n * UsageType here is used to specify the use case of the template, can be either\n * 'Register', 'SignIn', 'ForgotPassword', 'Generic'.\n */\nconst requiredTemplateUsageTypes = ['Register', 'SignIn', 'ForgotPassword', 'Generic'];\nconst templateGuard = z.object({\n usageType: z.string(),\n subject: z.string(),\n content: z.string(), // With variable {{code}}, support HTML\n});\n\nexport type Template = z.infer<typeof templateGuard>;\n\nexport const awsSesConfigGuard = z.object({\n accessKeyId: z.string(),\n accessKeySecret: z.string(),\n region: z.string(),\n emailAddress: z.string().optional(),\n emailAddressIdentityArn: z.string().optional(),\n templates: z.array(templateGuard).refine(\n (templates) =>\n requiredTemplateUsageTypes.every((requiredType) =>\n templates.map((template) => template.usageType).includes(requiredType)\n ),\n (templates) => ({\n message: `Template with UsageType (${requiredTemplateUsageTypes\n .filter(\n (requiredType) => !templates.map((template) => template.usageType).includes(requiredType)\n )\n .join(', ')}) should be provided!`,\n })\n ),\n feedbackForwardingEmailAddress: z.string().optional(),\n feedbackForwardingEmailAddressIdentityArn: z.string().optional(),\n configurationSetName: z.string().optional(),\n});\n\nexport type AwsSesConfig = z.infer<typeof awsSesConfigGuard>;\n","import type { EmailContent } from '@aws-sdk/client-sesv2';\nimport { SendEmailCommand, SESv2Client } from '@aws-sdk/client-sesv2';\nimport type { AwsCredentialIdentity } from '@aws-sdk/types';\nimport { replaceSendMessageHandlebars, type SendMessagePayload } from '@logto/connector-kit';\n\nimport type { AwsSesConfig, Template } from './types.js';\n\nexport const makeClient = (\n accessKeyId: string,\n secretAccessKey: string,\n region: string\n): SESv2Client => {\n const credentials: AwsCredentialIdentity = {\n accessKeyId,\n secretAccessKey,\n };\n\n return new SESv2Client({ credentials, region });\n};\n\nexport const makeEmailContent = (template: Template, payload: SendMessagePayload): EmailContent => {\n return {\n Simple: {\n Subject: { Data: replaceSendMessageHandlebars(template.subject, payload), Charset: 'utf8' },\n Body: {\n Html: {\n Data: replaceSendMessageHandlebars(template.content, payload),\n },\n },\n },\n };\n};\n\nexport const makeCommand = (\n config: AwsSesConfig,\n emailContent: EmailContent,\n to: string\n): SendEmailCommand => {\n return new SendEmailCommand({\n Destination: { ToAddresses: [to] },\n Content: emailContent,\n FromEmailAddress: config.emailAddress,\n FromEmailAddressIdentityArn: config.emailAddressIdentityArn,\n FeedbackForwardingEmailAddress: config.feedbackForwardingEmailAddress,\n FeedbackForwardingEmailAddressIdentityArn: config.feedbackForwardingEmailAddressIdentityArn,\n ConfigurationSetName: config.configurationSetName,\n });\n};\n"],"mappings":"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","names":["template"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@logto/connector-aws-ses",
3
- "version": "1.1.2",
3
+ "version": "1.2.0",
4
4
  "description": "Logto Connector for Amazon SES",
5
5
  "author": "Jeff <admin@breadth.app>",
6
6
  "dependencies": {
@@ -9,8 +9,8 @@
9
9
  "@logto/connector-kit": "^4.0.0",
10
10
  "@silverhand/essentials": "^2.9.1",
11
11
  "got": "^14.0.0",
12
- "snakecase-keys": "^8.0.0",
13
- "zod": "^3.22.4"
12
+ "snakecase-keys": "^8.0.1",
13
+ "zod": "^3.23.8"
14
14
  },
15
15
  "main": "./lib/index.js",
16
16
  "module": "./lib/index.js",
@@ -43,30 +43,25 @@
43
43
  "access": "public"
44
44
  },
45
45
  "devDependencies": {
46
- "@rollup/plugin-commonjs": "^26.0.0",
47
- "@rollup/plugin-json": "^6.1.0",
48
- "@rollup/plugin-node-resolve": "^15.2.3",
49
- "@rollup/plugin-typescript": "^11.1.6",
50
46
  "@silverhand/eslint-config": "6.0.1",
51
47
  "@silverhand/ts-config": "6.0.0",
52
48
  "@types/node": "^20.11.20",
53
49
  "@types/supertest": "^6.0.2",
54
- "@vitest/coverage-v8": "^1.4.0",
50
+ "@vitest/coverage-v8": "^2.0.0",
55
51
  "eslint": "^8.56.0",
56
52
  "lint-staged": "^15.0.2",
57
53
  "nock": "^13.3.1",
58
54
  "prettier": "^3.0.0",
59
- "rollup": "^4.12.0",
60
- "rollup-plugin-output-size": "^1.3.0",
61
55
  "supertest": "^7.0.0",
62
- "typescript": "^5.3.3",
63
- "vitest": "^1.4.0"
56
+ "tsup": "^8.1.0",
57
+ "typescript": "^5.5.3",
58
+ "vitest": "^2.0.0"
64
59
  },
65
60
  "scripts": {
66
61
  "precommit": "lint-staged",
67
- "build:test": "rm -rf lib/ && tsc -p tsconfig.test.json --sourcemap",
68
- "build": "rm -rf lib/ && tsc -p tsconfig.build.json --noEmit && rollup -c",
69
- "dev": "tsc -p tsconfig.build.json --watch --preserveWatchOutput --incremental",
62
+ "check": "tsc --noEmit",
63
+ "build": "tsup",
64
+ "dev": "tsup --watch",
70
65
  "lint": "eslint --ext .ts src",
71
66
  "lint:report": "pnpm lint --format json --output-file report.json",
72
67
  "test": "vitest src",
package/lib/constant.d.ts DELETED
@@ -1,2 +0,0 @@
1
- import type { ConnectorMetadata } from '@logto/connector-kit';
2
- export declare const defaultMetadata: ConnectorMetadata;
@@ -1,102 +0,0 @@
1
- import { s as strictParseShort, b as strictParseByte, e as strictParseFloat32 } from './index-s7VGoewj.js';
2
-
3
- const MONTHS = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
4
- const RFC3339 = new RegExp(/^(\d{4})-(\d{2})-(\d{2})[tT](\d{2}):(\d{2}):(\d{2})(?:\.(\d+))?[zZ]$/);
5
- const parseRfc3339DateTime = (value) => {
6
- if (value === null || value === undefined) {
7
- return undefined;
8
- }
9
- if (typeof value !== "string") {
10
- throw new TypeError("RFC-3339 date-times must be expressed as strings");
11
- }
12
- const match = RFC3339.exec(value);
13
- if (!match) {
14
- throw new TypeError("Invalid RFC-3339 date-time value");
15
- }
16
- const [_, yearStr, monthStr, dayStr, hours, minutes, seconds, fractionalMilliseconds] = match;
17
- const year = strictParseShort(stripLeadingZeroes(yearStr));
18
- const month = parseDateValue(monthStr, "month", 1, 12);
19
- const day = parseDateValue(dayStr, "day", 1, 31);
20
- return buildDate(year, month, day, { hours, minutes, seconds, fractionalMilliseconds });
21
- };
22
- const RFC3339_WITH_OFFSET = new RegExp(/^(\d{4})-(\d{2})-(\d{2})[tT](\d{2}):(\d{2}):(\d{2})(?:\.(\d+))?(([-+]\d{2}\:\d{2})|[zZ])$/);
23
- const parseRfc3339DateTimeWithOffset = (value) => {
24
- if (value === null || value === undefined) {
25
- return undefined;
26
- }
27
- if (typeof value !== "string") {
28
- throw new TypeError("RFC-3339 date-times must be expressed as strings");
29
- }
30
- const match = RFC3339_WITH_OFFSET.exec(value);
31
- if (!match) {
32
- throw new TypeError("Invalid RFC-3339 date-time value");
33
- }
34
- const [_, yearStr, monthStr, dayStr, hours, minutes, seconds, fractionalMilliseconds, offsetStr] = match;
35
- const year = strictParseShort(stripLeadingZeroes(yearStr));
36
- const month = parseDateValue(monthStr, "month", 1, 12);
37
- const day = parseDateValue(dayStr, "day", 1, 31);
38
- const date = buildDate(year, month, day, { hours, minutes, seconds, fractionalMilliseconds });
39
- if (offsetStr.toUpperCase() != "Z") {
40
- date.setTime(date.getTime() - parseOffsetToMilliseconds(offsetStr));
41
- }
42
- return date;
43
- };
44
- const buildDate = (year, month, day, time) => {
45
- const adjustedMonth = month - 1;
46
- validateDayOfMonth(year, adjustedMonth, day);
47
- return new Date(Date.UTC(year, adjustedMonth, day, parseDateValue(time.hours, "hour", 0, 23), parseDateValue(time.minutes, "minute", 0, 59), parseDateValue(time.seconds, "seconds", 0, 60), parseMilliseconds(time.fractionalMilliseconds)));
48
- };
49
- const DAYS_IN_MONTH = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
50
- const validateDayOfMonth = (year, month, day) => {
51
- let maxDays = DAYS_IN_MONTH[month];
52
- if (month === 1 && isLeapYear(year)) {
53
- maxDays = 29;
54
- }
55
- if (day > maxDays) {
56
- throw new TypeError(`Invalid day for ${MONTHS[month]} in ${year}: ${day}`);
57
- }
58
- };
59
- const isLeapYear = (year) => {
60
- return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
61
- };
62
- const parseDateValue = (value, type, lower, upper) => {
63
- const dateVal = strictParseByte(stripLeadingZeroes(value));
64
- if (dateVal < lower || dateVal > upper) {
65
- throw new TypeError(`${type} must be between ${lower} and ${upper}, inclusive`);
66
- }
67
- return dateVal;
68
- };
69
- const parseMilliseconds = (value) => {
70
- if (value === null || value === undefined) {
71
- return 0;
72
- }
73
- return strictParseFloat32("0." + value) * 1000;
74
- };
75
- const parseOffsetToMilliseconds = (value) => {
76
- const directionStr = value[0];
77
- let direction = 1;
78
- if (directionStr == "+") {
79
- direction = 1;
80
- }
81
- else if (directionStr == "-") {
82
- direction = -1;
83
- }
84
- else {
85
- throw new TypeError(`Offset direction, ${directionStr}, must be "+" or "-"`);
86
- }
87
- const hour = Number(value.substring(1, 3));
88
- const minute = Number(value.substring(4, 6));
89
- return direction * (hour * 60 + minute) * 60 * 1000;
90
- };
91
- const stripLeadingZeroes = (value) => {
92
- let idx = 0;
93
- while (idx < value.length - 1 && value.charAt(idx) === "0") {
94
- idx++;
95
- }
96
- if (idx === 0) {
97
- return value;
98
- }
99
- return value.slice(idx);
100
- };
101
-
102
- export { parseRfc3339DateTimeWithOffset as a, parseRfc3339DateTime as p };