Remove tsc-multi, re-install gts, apply autoformatting and linting

This commit is contained in:
Jon Staab
2024-12-17 10:59:27 -08:00
parent 0b86613161
commit f33e03740e
122 changed files with 2243 additions and 2178 deletions
+6 -8
View File
@@ -11,25 +11,23 @@
"files": [
"build"
],
"engines": {
"node": ">=12.0.0"
},
"types": "./build/src/index.d.ts",
"exports": {
".": {
"types": "./build/src/index.d.ts",
"import": "./build/src/index.mjs",
"require": "./build/src/index.cjs"
"import": "./build/src/index.js",
"require": "./build/src/index.js"
}
},
"scripts": {
"pub": "npm run lint && npm run build && npm publish",
"build": "gts clean && tsc-multi",
"build": "gts clean && tsc",
"lint": "gts lint",
"fix": "gts fix"
},
"devDependencies": {
"gts": "^5.0.1",
"tsc-multi": "^1.1.0",
"typescript": "~5.1.6"
},
"dependencies": {
"@braintree/sanitize-url": "^7.0.2",
"@welshman/lib": "~0.0.33",
+95 -70
View File
@@ -1,5 +1,5 @@
import {nip19} from "nostr-tools"
import {sanitizeUrl} from '@braintree/sanitize-url'
import {decode, neventEncode, nprofileEncode, naddrEncode} from "nostr-tools/nip19"
import {sanitizeUrl} from "@braintree/sanitize-url"
const last = <T>(xs: T[], ...args: unknown[]) => xs[xs.length - 1]
@@ -33,7 +33,7 @@ type ProfilePointer = {
export type ParseContext = {
results: Parsed[]
content: string,
content: string
tags: string[][]
}
@@ -124,31 +124,36 @@ export type ParsedAddress = {
}
export type Parsed =
ParsedAddress |
ParsedCashu |
ParsedCode |
ParsedEllipsis |
ParsedEvent |
ParsedInvoice |
ParsedLink |
ParsedNewline |
ParsedProfile |
ParsedText |
ParsedTopic
| ParsedAddress
| ParsedCashu
| ParsedCode
| ParsedEllipsis
| ParsedEvent
| ParsedInvoice
| ParsedLink
| ParsedNewline
| ParsedProfile
| ParsedText
| ParsedTopic
// Matchers
export const isAddress = (parsed: Parsed): parsed is ParsedAddress => parsed.type === ParsedType.Address
export const isCashu = (parsed: Parsed): parsed is ParsedCashu => parsed.type === ParsedType.Cashu
export const isCode = (parsed: Parsed): parsed is ParsedCode => parsed.type === ParsedType.Code
export const isEllipsis = (parsed: Parsed): parsed is ParsedEllipsis => parsed.type === ParsedType.Ellipsis
export const isEvent = (parsed: Parsed): parsed is ParsedEvent => parsed.type === ParsedType.Event
export const isInvoice = (parsed: Parsed): parsed is ParsedInvoice => parsed.type === ParsedType.Invoice
export const isLink = (parsed: Parsed): parsed is ParsedLink => parsed.type === ParsedType.Link
export const isNewline = (parsed: Parsed): parsed is ParsedNewline => parsed.type === ParsedType.Newline
export const isProfile = (parsed: Parsed): parsed is ParsedProfile => parsed.type === ParsedType.Profile
export const isText = (parsed: Parsed): parsed is ParsedText => parsed.type === ParsedType.Text
export const isTopic = (parsed: Parsed): parsed is ParsedTopic => parsed.type === ParsedType.Topic
export const isAddress = (parsed: Parsed): parsed is ParsedAddress =>
parsed.type === ParsedType.Address
export const isCashu = (parsed: Parsed): parsed is ParsedCashu => parsed.type === ParsedType.Cashu
export const isCode = (parsed: Parsed): parsed is ParsedCode => parsed.type === ParsedType.Code
export const isEllipsis = (parsed: Parsed): parsed is ParsedEllipsis =>
parsed.type === ParsedType.Ellipsis
export const isEvent = (parsed: Parsed): parsed is ParsedEvent => parsed.type === ParsedType.Event
export const isInvoice = (parsed: Parsed): parsed is ParsedInvoice =>
parsed.type === ParsedType.Invoice
export const isLink = (parsed: Parsed): parsed is ParsedLink => parsed.type === ParsedType.Link
export const isNewline = (parsed: Parsed): parsed is ParsedNewline =>
parsed.type === ParsedType.Newline
export const isProfile = (parsed: Parsed): parsed is ParsedProfile =>
parsed.type === ParsedType.Profile
export const isText = (parsed: Parsed): parsed is ParsedText => parsed.type === ParsedType.Text
export const isTopic = (parsed: Parsed): parsed is ParsedTopic => parsed.type === ParsedType.Topic
// Parsers for known formats
@@ -157,7 +162,7 @@ export const parseAddress = (text: string, context: ParseContext): ParsedAddress
if (naddr) {
try {
const {data} = nip19.decode(fromNostrURI(naddr))
const {data} = decode(fromNostrURI(naddr))
return {type: ParsedType.Address, value: data as AddressPointer, raw: naddr}
} catch (e) {
@@ -195,10 +200,8 @@ export const parseEvent = (text: string, context: ParseContext): ParsedEvent | v
if (entity) {
try {
const {type, data} = nip19.decode(fromNostrURI(entity))
const value = type === "note"
? {id: data as string, relays: []}
: data as EventPointer
const {type, data} = decode(fromNostrURI(entity))
const value = type === "note" ? {id: data as string, relays: []} : (data as EventPointer)
return {type: ParsedType.Event, value, raw: entity}
} catch (e) {
@@ -217,15 +220,16 @@ export const parseInvoice = (text: string, context: ParseContext): ParsedInvoice
export const parseLink = (text: string, context: ParseContext): ParsedLink | void => {
const prev = last(context.results)
const [link] = text.match(/^([a-z\+:]{2,30}:\/\/)?[-\.~\w]+\.[\w]{2,6}([^\s]*[^<>"'\.!,:\s\)\(]+)?/gi) || []
const [link] =
text.match(/^([a-z\+:]{2,30}:\/\/)?[-\.~\w]+\.[\w]{2,6}([^\s]*[^<>"'\.!,:\s\)\(]+)?/gi) || []
// Skip url if it's just the end of a filepath or an ellipse
if (!link || prev?.type === ParsedType.Text && prev.value.endsWith("/") || link.match(/\.\./)) {
if (!link || (prev?.type === ParsedType.Text && prev.value.endsWith("/")) || link.match(/\.\./)) {
return
}
// Skip it if it looks like an IP address but doesn't have a protocol
if (link.match(/\d+\.\d+/) && !link.includes('://')) {
if (link.match(/\d+\.\d+/) && !link.includes("://")) {
return
}
@@ -240,7 +244,7 @@ export const parseLink = (text: string, context: ParseContext): ParsedLink | voi
const meta = Object.fromEntries(new URLSearchParams(url.hash.slice(1)).entries())
for (const tag of context.tags) {
if (tag[0] === 'imeta' && tag.find(t => t.includes(`url ${link}`))) {
if (tag[0] === "imeta" && tag.find(t => t.includes(`url ${link}`))) {
Object.assign(meta, Object.fromEntries(tag.slice(1).map((m: string) => m.split(" "))))
}
}
@@ -261,10 +265,9 @@ export const parseProfile = (text: string, context: ParseContext): ParsedProfile
if (entity) {
try {
const {type, data} = nip19.decode(fromNostrURI(entity.replace('@', '')))
const value = type === "npub"
? {pubkey: data as string, relays: []}
: data as ProfilePointer
const {type, data} = decode(fromNostrURI(entity.replace("@", "")))
const value =
type === "npub" ? {pubkey: data as string, relays: []} : (data as ProfilePointer)
return {type: ParsedType.Profile, value, raw: entity}
} catch (e) {
@@ -282,10 +285,12 @@ export const parseTopic = (text: string, context: ParseContext): ParsedTopic | v
}
}
// Parse other formats to known types
export const parseLegacyMention = (text: string, context: ParseContext): ParsedProfile | ParsedEvent | void => {
export const parseLegacyMention = (
text: string,
context: ParseContext,
): ParsedProfile | ParsedEvent | void => {
const mentionMatch = text.match(/^#\[(\d+)\]/i) || []
if (mentionMatch) {
@@ -313,7 +318,7 @@ export const parsers = [
parseEvent,
parseCashu,
parseInvoice,
parseLink
parseLink,
]
export const parseNext = (raw: string, context: ParseContext): Parsed | void => {
@@ -371,12 +376,7 @@ type TruncateOpts = {
export const truncate = (
content: Parsed[],
{
minLength = 500,
maxLength = 700,
mediaLength = 200,
entityLength = 30,
}: TruncateOpts = {},
{minLength = 500, maxLength = 700, mediaLength = 200, entityLength = 30}: TruncateOpts = {},
) => {
// Get a list of content sizes so we know where to truncate
// Non-plaintext things might take up more or less room if rendered
@@ -429,7 +429,7 @@ export class Renderer {
toString = () => this.value
addText = (value: string) => {
const element = document.createElement('div')
const element = document.createElement("div")
element.innerText = value
@@ -459,17 +459,17 @@ export type RenderOptions = {
}
export const textRenderOptions = {
newline: '\n',
entityBase: '',
newline: "\n",
entityBase: "",
renderLink: (href: string, display: string) => href,
renderEntity: (entity: string) => entity.slice(0, 16) + '…',
renderEntity: (entity: string) => entity.slice(0, 16) + "…",
}
export const htmlRenderOptions = {
newline: '\n',
entityBase: 'https://njump.me/',
newline: "\n",
entityBase: "https://njump.me/",
renderLink: (href: string, display: string) => {
const element = document.createElement('a')
const element = document.createElement("a")
element.href = sanitizeUrl(href)
element.target = "_blank"
@@ -477,7 +477,7 @@ export const htmlRenderOptions = {
return element.outerHTML
},
renderEntity: (entity: string) => entity.slice(0, 16) + '…',
renderEntity: (entity: string) => entity.slice(0, 16) + "…",
}
export const makeTextRenderer = (options: Partial<RenderOptions> = {}) =>
@@ -499,31 +499,56 @@ export const renderInvoice = (p: ParsedInvoice, r: Renderer) => r.addText(p.valu
export const renderLink = (p: ParsedLink, r: Renderer) =>
r.addLink(p.value.url.toString(), p.value.url.host + p.value.url.pathname)
export const renderNewline = (p: ParsedNewline, r: Renderer) => r.addNewlines(Array.from(p.value).length)
export const renderNewline = (p: ParsedNewline, r: Renderer) =>
r.addNewlines(Array.from(p.value).length)
export const renderText = (p: ParsedText, r: Renderer) => r.addText(p.value)
export const renderTopic = (p: ParsedTopic, r: Renderer) => r.addText(p.value)
export const renderEvent = (p: ParsedEvent, r: Renderer) => r.addEntityLink(nip19.neventEncode(p.value))
export const renderEvent = (p: ParsedEvent, r: Renderer) => r.addEntityLink(neventEncode(p.value))
export const renderProfile = (p: ParsedProfile, r: Renderer) => r.addEntityLink(nip19.nprofileEncode(p.value))
export const renderProfile = (p: ParsedProfile, r: Renderer) =>
r.addEntityLink(nprofileEncode(p.value))
export const renderAddress = (p: ParsedAddress, r: Renderer) => r.addEntityLink(nip19.naddrEncode(p.value))
export const renderAddress = (p: ParsedAddress, r: Renderer) =>
r.addEntityLink(naddrEncode(p.value))
export const renderOne = (parsed: Parsed, renderer: Renderer) => {
switch (parsed.type) {
case ParsedType.Address: renderAddress(parsed as ParsedAddress, renderer); break
case ParsedType.Cashu: renderCashu(parsed as ParsedCashu, renderer); break
case ParsedType.Code: renderCode(parsed as ParsedCode, renderer); break
case ParsedType.Ellipsis: renderEllipsis(parsed as ParsedEllipsis, renderer); break
case ParsedType.Event: renderEvent(parsed as ParsedEvent, renderer); break
case ParsedType.Invoice: renderInvoice(parsed as ParsedInvoice, renderer); break
case ParsedType.Link: renderLink(parsed as ParsedLink, renderer); break
case ParsedType.Newline: renderNewline(parsed as ParsedNewline, renderer); break
case ParsedType.Profile: renderProfile(parsed as ParsedProfile, renderer); break
case ParsedType.Text: renderText(parsed as ParsedText, renderer); break
case ParsedType.Topic: renderTopic(parsed as ParsedTopic, renderer); break
case ParsedType.Address:
renderAddress(parsed as ParsedAddress, renderer)
break
case ParsedType.Cashu:
renderCashu(parsed as ParsedCashu, renderer)
break
case ParsedType.Code:
renderCode(parsed as ParsedCode, renderer)
break
case ParsedType.Ellipsis:
renderEllipsis(parsed as ParsedEllipsis, renderer)
break
case ParsedType.Event:
renderEvent(parsed as ParsedEvent, renderer)
break
case ParsedType.Invoice:
renderInvoice(parsed as ParsedInvoice, renderer)
break
case ParsedType.Link:
renderLink(parsed as ParsedLink, renderer)
break
case ParsedType.Newline:
renderNewline(parsed as ParsedNewline, renderer)
break
case ParsedType.Profile:
renderProfile(parsed as ParsedProfile, renderer)
break
case ParsedType.Text:
renderText(parsed as ParsedText, renderer)
break
case ParsedType.Topic:
renderTopic(parsed as ParsedTopic, renderer)
break
}
return renderer
-7
View File
@@ -1,7 +0,0 @@
{
"targets": [
{"extname": ".cjs", "module": "commonjs"},
{"extname": ".mjs", "module": "esnext", "moduleResolution": "node"}
],
"projects": ["tsconfig.json"]
}
+7 -4
View File
@@ -3,9 +3,12 @@
"compilerOptions": {
"rootDir": ".",
"outDir": "build",
"esModuleInterop": true,
"skipLibCheck": true,
"lib": ["esnext", "dom", "dom.iterable"]
"module": "nodenext",
"moduleResolution": "nodenext",
"lib": ["esnext", "dom"]
},
"include": ["src/**/*.ts"]
"include": [
"src/**/*.ts",
"test/**/*.ts"
]
}