Skip to content

Commit

Permalink
Prefer a named constructor to casting
Browse files Browse the repository at this point in the history
Refs #1834
  • Loading branch information
thewilkybarkid committed Jan 6, 2025
1 parent 8f8fec8 commit 91a8894
Show file tree
Hide file tree
Showing 19 changed files with 72 additions and 70 deletions.
10 changes: 5 additions & 5 deletions integration/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ import * as Nodemailer from '../src/nodemailer.js'
import { Program } from '../src/Program.js'
import { PublicUrl } from '../src/public-url.js'
import * as TemplatePage from '../src/TemplatePage.js'
import type { EmailAddress } from '../src/types/email-address.js'
import { EmailAddress } from '../src/types/email-address.js'
import type { NonEmptyString } from '../src/types/string.js'
import type { WasPrereviewRemovedEnv } from '../src/zenodo.js'
import Logger = L.Logger
Expand Down Expand Up @@ -1998,7 +1998,7 @@ export const hasAnUnverifiedEmailAddress: Fixtures<
'0000-0002-1825-0097',
ContactEmailAddressC.encode(
new UnverifiedContactEmailAddress({
value: '[email protected]' as EmailAddress,
value: EmailAddress('[email protected]'),
verificationToken: 'ff0d6f8e-7dca-4a26-b68b-93f2d2bc3c2a' as Uuid,
}),
),
Expand All @@ -2016,7 +2016,7 @@ export const hasAVerifiedEmailAddress: Fixtures<
contactEmailAddressStore: async ({ contactEmailAddressStore }, use) => {
await contactEmailAddressStore.set(
'0000-0002-1825-0097',
ContactEmailAddressC.encode(new VerifiedContactEmailAddress({ value: '[email protected]' as EmailAddress })),
ContactEmailAddressC.encode(new VerifiedContactEmailAddress({ value: EmailAddress('[email protected]') })),
)

await use(contactEmailAddressStore)
Expand Down Expand Up @@ -2094,15 +2094,15 @@ export const invitedToBeAnAuthor: Fixtures<
'bec5727e-9992-4f3b-85be-6712df617b9d',
AuthorInviteC.encode({
status: 'open',
emailAddress: '[email protected]' as EmailAddress,
emailAddress: EmailAddress('[email protected]'),
review: 1055806,
}),
)

const email = createAuthorInviteEmail(
{
name: 'Josiah Carberry' as NonEmptyString,
emailAddress: '[email protected]' as EmailAddress,
emailAddress: EmailAddress('[email protected]'),
},
'bec5727e-9992-4f3b-85be-6712df617b9d' as Uuid,
{
Expand Down
20 changes: 10 additions & 10 deletions src/club-details.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Eq as stringEq } from 'fp-ts/lib/string.js'
import { Orcid, Eq as eqOrcid } from 'orcid-id-ts'
import { type Html, html } from './html.js'
import type { ClubId } from './types/club-id.js'
import type { EmailAddress } from './types/email-address.js'
import { EmailAddress } from './types/email-address.js'

export interface Club {
readonly name: string
Expand Down Expand Up @@ -197,7 +197,7 @@ const clubs: RR.ReadonlyRecord<ClubId, Club> = {
orcid: Orcid('0000-0002-5815-8703'),
},
],
contact: '[email protected]' as EmailAddress,
contact: EmailAddress('[email protected]'),
},
bios2: {
name: 'Computational Biodiversity Science and Services',
Expand Down Expand Up @@ -330,7 +330,7 @@ const clubs: RR.ReadonlyRecord<ClubId, Club> = {
{ name: 'Surya Nedunchezhiyan', orcid: Orcid('0009-0008-3322-2327') },
{ name: 'Tiffany I. Leung', orcid: Orcid('0000-0002-6007-4023') },
],
contact: '[email protected]' as EmailAddress,
contact: EmailAddress('[email protected]'),
},
'language-club': {
name: 'Language Club',
Expand Down Expand Up @@ -372,7 +372,7 @@ const clubs: RR.ReadonlyRecord<ClubId, Club> = {
{ name: 'Luis Alberto Bezares Calderón', orcid: Orcid('0000-0001-6678-6876') },
{ name: 'Alexandra Kerbl', orcid: Orcid('0000-0002-9454-6359') },
],
contact: '[email protected]' as EmailAddress,
contact: EmailAddress('[email protected]'),
},
neuroden: {
name: 'Neuroden',
Expand All @@ -394,7 +394,7 @@ const clubs: RR.ReadonlyRecord<ClubId, Club> = {
{ name: 'Abbas Saifuddin', orcid: Orcid('0009-0003-9667-6207') },
{ name: 'Hamza Mustafa', orcid: Orcid('0009-0006-0344-5365') },
],
contact: '[email protected]' as EmailAddress,
contact: EmailAddress('[email protected]'),
},
'nsa-utd': {
name: 'Neuroscience Student Association at UTD',
Expand All @@ -414,7 +414,7 @@ const clubs: RR.ReadonlyRecord<ClubId, Club> = {
{ name: 'Emma Unger', orcid: Orcid('0009-0000-6854-2621') },
{ name: 'Mohammad Khan', orcid: Orcid('0009-0007-7940-1964') },
],
contact: '[email protected]' as EmailAddress,
contact: EmailAddress('[email protected]'),
},
'open-box-science': {
name: 'Open Box Science',
Expand Down Expand Up @@ -453,7 +453,7 @@ const clubs: RR.ReadonlyRecord<ClubId, Club> = {
</p>
`,
leads: [{ name: 'Assist. Prof. Dr. Salwan M. Abdulateef', orcid: Orcid('0000-0002-7389-0003') }],
contact: '[email protected]' as EmailAddress,
contact: EmailAddress('[email protected]'),
},
'open-science-community-uruguay': {
name: 'Open Science Community Uruguay (OSCU)',
Expand All @@ -469,7 +469,7 @@ const clubs: RR.ReadonlyRecord<ClubId, Club> = {
{ name: 'Daniel Prieto', orcid: Orcid('0000-0001-8356-1708') },
{ name: 'Mateo Vidal Panario', orcid: Orcid('0009-0009-3980-7163') },
],
contact: '[email protected]' as EmailAddress,
contact: EmailAddress('[email protected]'),
},
oxplants: {
name: 'OxPlants Preprint Club',
Expand Down Expand Up @@ -517,7 +517,7 @@ const clubs: RR.ReadonlyRecord<ClubId, Club> = {
</p>
`,
leads: [{ name: 'Alain Manuel Chaple Gil', orcid: Orcid('0000-0002-8571-4429') }],
contact: '[email protected]' as EmailAddress,
contact: EmailAddress('[email protected]'),
},
'rr-id-student-reviewer-club': {
name: 'RR\\ID Student Reviewer Club',
Expand All @@ -537,7 +537,7 @@ const clubs: RR.ReadonlyRecord<ClubId, Club> = {
</p>
`,
leads: [{ name: 'Hildy Fong Baker', orcid: Orcid('0000-0002-3836-1966') }],
contact: '[email protected]' as EmailAddress,
contact: EmailAddress('[email protected]'),
},
'sg-biofilms-microbiome': {
name: 'SG Biofilms and Microbiome Club',
Expand Down
12 changes: 6 additions & 6 deletions src/email.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
verifyContactEmailAddressMatch,
writeReviewVerifyEmailAddressMatch,
} from './routes.js'
import type { EmailAddress } from './types/email-address.js'
import { EmailAddress } from './types/email-address.js'
import type { IndeterminatePreprintId } from './types/preprint-id.js'
import type { NonEmptyString } from './types/string.js'
import type { User } from './user.js'
Expand Down Expand Up @@ -47,7 +47,7 @@ export const sendContactEmailAddressVerificationEmail = (
R.asks(
({ locale }: { locale: SupportedLocale }) =>
({
from: { address: '[email protected]' as EmailAddress, name: 'PREreview' },
from: { address: EmailAddress('[email protected]'), name: 'PREreview' },
to: { address: emailAddress.value, name: user.name },
subject: translate(locale, 'email', 'verifyEmailAddressTitle')(),
text: `${translate(locale, 'email', 'hiName')({ name: user.name })}\n\n${translate(locale, 'email', 'verifyEmailAddressGoingTo')({ link: verificationUrl.href })}`,
Expand Down Expand Up @@ -86,7 +86,7 @@ export const sendContactEmailAddressVerificationEmailForReview = (
R.asks(
({ locale }: { locale: SupportedLocale }) =>
({
from: { address: '[email protected]' as EmailAddress, name: 'PREreview' },
from: { address: EmailAddress('[email protected]'), name: 'PREreview' },
to: { address: emailAddress.value, name: user.name },
subject: translate(locale, 'email', 'verifyEmailAddressTitle')(),
text: `${translate(locale, 'email', 'hiName')({ name: user.name })}\n\n${translate(locale, 'email', 'verifyEmailAddressGoingTo')({ link: verificationUrl.href })}`,
Expand Down Expand Up @@ -127,7 +127,7 @@ export const createContactEmailAddressVerificationEmailForInvitedAuthor = ({
R.asks(
({ locale }: { locale: SupportedLocale }) =>
({
from: { address: '[email protected]' as EmailAddress, name: 'PREreview' },
from: { address: EmailAddress('[email protected]'), name: 'PREreview' },
to: { address: emailAddress.value, name: user.name },
subject: translate(locale, 'email', 'verifyEmailAddressTitle')(),
text: `${translate(locale, 'email', 'hiName')({ name: user.name })}\n\n${translate(locale, 'email', 'verifyEmailAddressGoingTo')({ link: verificationUrl.href })}`,
Expand Down Expand Up @@ -168,7 +168,7 @@ export const createContactEmailAddressVerificationEmailForComment = ({
R.map(
verificationUrl =>
({
from: { address: '[email protected]' as EmailAddress, name: 'PREreview' },
from: { address: EmailAddress('[email protected]'), name: 'PREreview' },
to: { address: emailAddress.value, name: user.name },
subject: translate(locale, 'email', 'verifyEmailAddressTitle')(),
text: `${translate(locale, 'email', 'hiName')({ name: user.name })}\n\n${translate(locale, 'email', 'verifyEmailAddressGoingTo')({ link: verificationUrl.href })}`,
Expand Down Expand Up @@ -204,7 +204,7 @@ export const createAuthorInviteEmail = (
R.map(
({ inviteUrl, declineUrl }) =>
({
from: { address: '[email protected]' as EmailAddress, name: 'PREreview' },
from: { address: EmailAddress('[email protected]'), name: 'PREreview' },
to: { address: person.emailAddress, name: person.name },
subject: 'Be listed as a PREreview author',
text: `
Expand Down
2 changes: 2 additions & 0 deletions src/types/email-address.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,5 @@ export const EmailAddressSchema = pipe(
Schema.filter(s => isEmailValid(s), { message: () => 'not an email address' }),
Schema.brand(EmailAddressBrand),
)

export const EmailAddress = (email: string) => EmailAddressSchema.make(email)
4 changes: 2 additions & 2 deletions test/fc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ import {
isNonCacheable,
} from '../src/status-code.js'
import { type ClubId, clubIds } from '../src/types/club-id.js'
import type { EmailAddress } from '../src/types/email-address.js'
import { EmailAddress } from '../src/types/email-address.js'
import { type FieldId, fieldIds } from '../src/types/field.js'
import { ProfileId } from '../src/types/index.js'
import {
Expand Down Expand Up @@ -379,7 +379,7 @@ const asset = (): fc.Arbitrary<keyof typeof assets> =>
const js = (): fc.Arbitrary<EndsWith<keyof typeof assets, '.js'>> =>
asset().filter((asset): asset is EndsWith<typeof asset, '.js'> => asset.endsWith('.js'))

export const emailAddress = (): fc.Arbitrary<EmailAddress> => fc.emailAddress() as fc.Arbitrary<EmailAddress>
export const emailAddress = (): fc.Arbitrary<EmailAddress> => fc.emailAddress().map(EmailAddress)

export const contactEmailAddress = (): fc.Arbitrary<ContactEmailAddress> =>
fc.oneof(unverifiedContactEmailAddress(), verifiedContactEmailAddress())
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Either } from 'effect'
import { DefaultLocale } from '../../../src/locales/index.js'
import type { EmailAddress, Uuid } from '../../../src/types/index.js'
import { EmailAddress, type Uuid } from '../../../src/types/index.js'
import * as EnterEmailAddressForm from '../../../src/WriteCommentFlow/EnterEmailAddressPage/EnterEmailAddressForm.js'
import * as _ from '../../../src/WriteCommentFlow/EnterEmailAddressPage/EnterEmailAddressPage.js'
import { expect, test } from '../../base.js'
Expand All @@ -21,7 +21,7 @@ test('content looks right when there is an email address', async ({ showPage })
const response = _.EnterEmailAddressPage({
commentId: '7ad2f67d-dc01-48c5-b6ac-3490d494f67d' as Uuid.Uuid,
form: new EnterEmailAddressForm.CompletedForm({
emailAddress: '[email protected]' as EmailAddress.EmailAddress,
emailAddress: EmailAddress.EmailAddress('[email protected]'),
}),
locale: DefaultLocale,
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { DefaultLocale } from '../../../src/locales/index.js'
import type { EmailAddress, Uuid } from '../../../src/types/index.js'
import { EmailAddress, type Uuid } from '../../../src/types/index.js'
import * as _ from '../../../src/WriteCommentFlow/NeedToVerifyEmailAddressPage/NeedToVerifyEmailAddressPage.js'
import { expect, test } from '../../base.js'

test('content looks right', async ({ showPage }) => {
const response = _.NeedToVerifyEmailAddressPage({
commentId: '7ad2f67d-dc01-48c5-b6ac-3490d494f67d' as Uuid.Uuid,
emailAddress: '[email protected]' as EmailAddress.EmailAddress,
emailAddress: EmailAddress.EmailAddress('[email protected]'),
locale: DefaultLocale,
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ import * as E from 'fp-ts/lib/Either.js'
import type { Uuid } from 'uuid-ts'
import { enterEmailAddressForm } from '../../src/author-invite-flow/enter-email-address-page/enter-email-address-form.js'
import { invalidE, missingE } from '../../src/form.js'
import type { EmailAddress } from '../../src/types/email-address.js'
import { EmailAddress } from '../../src/types/email-address.js'
import { expect, test } from '../base.js'

test('content looks right', async ({ showPage }) => {
const response = enterEmailAddressForm({
inviteId: 'ee9dd955-7b3b-4ad2-8a61-25dd42cb70f0' as Uuid,
invitedEmailAddress: '[email protected]' as EmailAddress,
invitedEmailAddress: EmailAddress('[email protected]'),
form: { useInvitedAddress: E.right(undefined), otherEmailAddress: E.right(undefined) },
})

Expand All @@ -21,7 +21,7 @@ test('content looks right when fields are missing', async ({ showPage }) => {
await test.step('choice field', async () => {
const response = enterEmailAddressForm({
inviteId: 'ee9dd955-7b3b-4ad2-8a61-25dd42cb70f0' as Uuid,
invitedEmailAddress: '[email protected]' as EmailAddress,
invitedEmailAddress: EmailAddress('[email protected]'),
form: { useInvitedAddress: E.left(missingE()), otherEmailAddress: E.right(undefined) },
})

Expand All @@ -33,7 +33,7 @@ test('content looks right when fields are missing', async ({ showPage }) => {
await test.step('other email address field', async () => {
const response = enterEmailAddressForm({
inviteId: 'ee9dd955-7b3b-4ad2-8a61-25dd42cb70f0' as Uuid,
invitedEmailAddress: '[email protected]' as EmailAddress,
invitedEmailAddress: EmailAddress('[email protected]'),
form: { useInvitedAddress: E.right('no'), otherEmailAddress: E.left(missingE()) },
})

Expand All @@ -46,7 +46,7 @@ test('content looks right when fields are missing', async ({ showPage }) => {
test('content looks right when fields are invalid', async ({ showPage }) => {
const response = enterEmailAddressForm({
inviteId: 'ee9dd955-7b3b-4ad2-8a61-25dd42cb70f0' as Uuid,
invitedEmailAddress: '[email protected]' as EmailAddress,
invitedEmailAddress: EmailAddress('[email protected]'),
form: { useInvitedAddress: E.right('no'), otherEmailAddress: E.left(invalidE('not an email address')) },
})

Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import type { Uuid } from 'uuid-ts'
import { needToVerifyEmailAddressPage } from '../../src/author-invite-flow/need-to-verify-email-address-page/need-to-verify-email-address-page.js'
import { UnverifiedContactEmailAddress } from '../../src/contact-email-address.js'
import type { EmailAddress } from '../../src/types/email-address.js'
import { EmailAddress } from '../../src/types/email-address.js'
import { expect, test } from '../base.js'

test('content looks right', async ({ showPage }) => {
const response = needToVerifyEmailAddressPage({
inviteId: 'ee9dd955-7b3b-4ad2-8a61-25dd42cb70f0' as Uuid,
contactEmailAddress: new UnverifiedContactEmailAddress({
value: '[email protected]' as EmailAddress,
value: EmailAddress('[email protected]'),
verificationToken: '2a29e36c-da26-438d-9a67-577101fa8968' as Uuid,
}),
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Orcid } from 'orcid-id-ts'
import type { Uuid } from 'uuid-ts'
import { authorInviteStart } from '../../src/author-invite-flow/index.js'
import { html } from '../../src/html.js'
import type { EmailAddress } from '../../src/types/email-address.js'
import { EmailAddress } from '../../src/types/email-address.js'
import type { Pseudonym } from '../../src/types/pseudonym.js'
import { expect, test } from '../base.js'

Expand All @@ -19,7 +19,7 @@ test('content looks right when already started', async ({ showPage }) => {
getAuthorInvite: () =>
TE.right({
status: 'assigned',
emailAddress: '[email protected]' as EmailAddress,
emailAddress: EmailAddress('[email protected]'),
orcid: Orcid('0000-0002-1825-0097'),
review: 1234,
}),
Expand Down
6 changes: 3 additions & 3 deletions visual-regression/author-invite-flow/author-invite.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Orcid } from 'orcid-id-ts'
import type { Uuid } from 'uuid-ts'
import { authorInvite } from '../../src/author-invite-flow/index.js'
import { html } from '../../src/html.js'
import type { EmailAddress } from '../../src/types/email-address.js'
import { EmailAddress } from '../../src/types/email-address.js'
import type { Pseudonym } from '../../src/types/pseudonym.js'
import { expect, test } from '../base.js'

Expand All @@ -14,7 +14,7 @@ import PlainDate = Temporal.PlainDate
test('content looks right', async ({ showPage }) => {
const response = await authorInvite({ id: 'ee9dd955-7b3b-4ad2-8a61-25dd42cb70f0' as Uuid })({
getAuthorInvite: () =>
TE.right({ status: 'open', emailAddress: '[email protected]' as EmailAddress, review: 1234 }),
TE.right({ status: 'open', emailAddress: EmailAddress('[email protected]'), review: 1234 }),
getPrereview: () =>
TE.right({
authors: {
Expand Down Expand Up @@ -73,7 +73,7 @@ test('content looks right when logged in', async ({ showPage }) => {
},
})({
getAuthorInvite: () =>
TE.right({ status: 'open', emailAddress: '[email protected]' as EmailAddress, review: 1234 }),
TE.right({ status: 'open', emailAddress: EmailAddress('[email protected]'), review: 1234 }),
getPrereview: () =>
TE.right({
authors: {
Expand Down
4 changes: 2 additions & 2 deletions visual-regression/club-profile-page/club-profile-page.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import type { Prereviews } from '../../src/club-profile-page/prereviews.js'
import { html, rawHtml } from '../../src/html.js'
import { DefaultLocale } from '../../src/locales/index.js'
import type { ClubId } from '../../src/types/club-id.js'
import type { EmailAddress } from '../../src/types/email-address.js'
import { EmailAddress } from '../../src/types/email-address.js'
import { expect, test } from '../base.js'

import PlainDate = Temporal.PlainDate
Expand Down Expand Up @@ -45,7 +45,7 @@ const club1 = {
{ name: 'Arpita Ghosh', orcid: Orcid('0009-0003-2106-3270') },
{ name: 'Garima Jain', orcid: Orcid('0000-0002-8079-9611') },
],
contact: '[email protected]' as EmailAddress,
contact: EmailAddress('[email protected]'),
joinLink: new URL(
'https://docs.google.com/forms/d/e/1FAIpQLScOR3oM_9OOhRKxjQvupN8YLtaGImOfKskkllrveTWIqrJUVg/viewform',
),
Expand Down
Loading

0 comments on commit 91a8894

Please sign in to comment.