diff --git a/package.json b/package.json index e9e6d0de4..f87038948 100644 --- a/package.json +++ b/package.json @@ -62,5 +62,6 @@ "eslint --fix", "git add" ] - } + }, + "packageManager": "pnpm@9.10.0+sha1.216899f511c8dfde183c7cb50b69009c779534a8" } diff --git a/scripts/utils.js b/scripts/utils.ts similarity index 73% rename from scripts/utils.js rename to scripts/utils.ts index 489d021fe..f611bb650 100644 --- a/scripts/utils.js +++ b/scripts/utils.ts @@ -1,10 +1,10 @@ -const exec = require('@actions/exec'); -const core = require('@actions/core'); -const github = require('@actions/github'); -const Joi = require('joi'); -const http = require('http'); -const https = require('https'); -const flags = require('./flags.js'); +import exec from '@actions/exec'; +import core from '@actions/core'; +import github from '@actions/github'; +import Joi from 'joi'; +import http from 'http'; +import https from 'https'; +import flags from './flags.js'; async function getCurrentBranchName() { let myOutput = ''; @@ -13,8 +13,8 @@ async function getCurrentBranchName() { const options = { silent: true, listeners: { - stdout: (data) => (myOutput += data.toString()), - stderr: (data) => (myError += data.toString()), + stdout: (data: Buffer) => (myOutput += data.toString()), + stderr: (data: Buffer) => (myError += data.toString()), }, }; @@ -23,7 +23,7 @@ async function getCurrentBranchName() { } /** on master branch will return an empty array */ -module.exports.getMasterData = async function () { +export const getMasterData = async function () { const options = { silent: true }; const curentBranchName = await getCurrentBranchName(); // when on a branch/PR different from master @@ -40,7 +40,7 @@ module.exports.getMasterData = async function () { } // eslint-disable-next-line global-require - const masterData = require('./masterData.js'); + const masterData = (await import('./masterData.js')).default as Person[]; // restore `scripts/masterData.js` after was loaded if (curentBranchName !== 'master') { @@ -50,7 +50,7 @@ module.exports.getMasterData = async function () { return masterData; }; -module.exports.Schema = Joi.object({ +export const Schema = Joi.object({ name: Joi.string().required(), description: Joi.string().required(), url: Joi.string() @@ -60,16 +60,33 @@ module.exports.Schema = Joi.object({ country: Joi.string() .valid(...flags) .required(), - twitter: Joi.string().pattern(new RegExp(/^@?(\w){1,15}$/)), - mastodon: Joi.string().pattern(new RegExp(/^@(\w){1,30}@(\w)+\.(.?\w)+$/)), - bluesky: Joi.string().pattern(new RegExp(/^[\w-]+\.(?:[\w-]+\.)?[\w-]+$/)), + twitter: Joi.string().pattern(/^@?(\w){1,15}$/), + mastodon: Joi.string().pattern(/^@(\w){1,30}@(\w)+\.(.?\w)+$/), + bluesky: Joi.string().pattern(/^[\w-]+\.(?:[\w-]+\.)?[\w-]+$/), emoji: Joi.string().allow(''), computer: Joi.string().valid('apple', 'windows', 'linux', 'bsd'), phone: Joi.string().valid('iphone', 'android', 'windowsphone', 'flipphone'), tags: Joi.array().items(Joi.string()), }); -module.exports.getStatusCode = function (url) { +/* + TODO: This should be inferred but then I want to move to Valibot. If you give a moose a muffin. +*/ +export type Person = { + name: string; + description: string; + url: string; + country: string; + twitter?: `@${string}`; + mastodon?: string; + bluesky?: string; + emoji?: string; + computer?: 'apple' | 'windows' | 'linux' | 'bsd'; + phone?: 'iphone' | 'android' | 'windowsphone' | 'flipphone'; + tags?: string[]; +}; + +export const getStatusCode = function (url: string) { const client = url.startsWith('https') ? https : http; return new Promise((resolve, reject) => { const REQUEST_TIMEOUT = 10000; @@ -90,10 +107,10 @@ module.exports.getStatusCode = function (url) { // If there are errors, will fail the action & add a comment detailing the issues // If there are no errors, will leave an "all-clear" comment with relevant URLs (to ease a potential manual check) -module.exports.communicateValidationOutcome = async function ( - errors, - failedUrls, - changedData +export const communicateValidationOutcome = function ( + errors: { message: string }[], + failedUrls: string[], + changedData: { name: string; url: string }[] ) { let comment = ''; if (errors.length || failedUrls.length) { diff --git a/src/components/Person.js b/src/components/Person.tsx similarity index 68% rename from src/components/Person.js rename to src/components/Person.tsx index cd4ae9953..5ef5d9a56 100644 --- a/src/components/Person.js +++ b/src/components/Person.tsx @@ -3,12 +3,13 @@ import PropTypes from 'prop-types'; import { name } from 'country-emoji'; import { useParams } from '@remix-run/react'; import * as icons from '../util/icons'; +import { Person } from '../../scripts/utils'; -export default function Person({ person }) { +export default function PersonComponent({ person }: { person: Person }) { const url = new URL(person.url); const twitter = person.twitter ? `https://unavatar.io/x/${person.twitter.replace('@', '')}` - : null; + : ''; const website = `https://unavatar.io/${url.host}`; const unavatar = person.twitter ? `${twitter}?fallback=${website}&ttl=28d` @@ -18,7 +19,7 @@ export default function Person({ person }) { return (
@@ -29,14 +30,14 @@ export default function Person({ person }) { alt={person.name} onError={({ currentTarget }) => { currentTarget.onerror = null; // prevents looping - currentTarget.src = "/default.png"; + currentTarget.src = '/default.png'; }} loading="lazy" />

{person.name} - {" "} + {' '} {person.emoji}

{url.host} - {url.pathname.replace(/\/$/, "")} + {url.pathname.replace(/\/$/, '')}

{person.description}