Skip to content

Commit a6e5a31

Browse files
authored
Merge branch 'main' into patch-2
2 parents dc7c5d7 + 0020999 commit a6e5a31

11 files changed

Lines changed: 124 additions & 14 deletions

File tree

Lines changed: 6 additions & 0 deletions
Loading

app/assets/logos/oss-partners/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import LogoLunaria from './lunaria.svg'
3030
import LogoJsr from './jsr.svg'
3131
import LogoIconify from './iconify.svg'
3232
import LogoFloatingUi from './floating-ui-vue.svg'
33+
import LogoBlento from './blento.svg'
3334

3435
// The list is used on the about page. To add, simply upload the logos nearby and add an entry here. Prefer SVGs.
3536
// For logo src, specify a string or object with the light and dark theme variants.
@@ -195,4 +196,9 @@ export const OSS_PARTNERS = [
195196
logo: LogoFloatingUi,
196197
url: 'https://floating-ui.com/',
197198
},
199+
{
200+
name: 'blento',
201+
logo: LogoBlento,
202+
url: 'https://blento.app/npmx.dev',
203+
},
198204
]
Lines changed: 17 additions & 0 deletions
Loading
Lines changed: 17 additions & 0 deletions
Loading

app/assets/logos/sponsors/index.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import LogoVlt from './vlt.svg'
66
import LogoVltLight from './vlt-light.svg'
77
import LogoNetlify from './netlify.svg'
88
import LogoNetlifyLight from './netlify-light.svg'
9+
import LogoBluesky from './bluesky.svg'
10+
import LogoBlueskyLight from './bluesky-light.svg'
911

1012
// The list is used on the about page. To add, simply upload the logos nearby and add an entry here. Prefer SVGs.
1113
// For logo src, specify a string or object with the light and dark theme variants.
@@ -51,4 +53,13 @@ export const SPONSORS = [
5153
normalisingIndent: '0.125rem',
5254
url: 'https://netlify.com/',
5355
},
56+
{
57+
name: 'Bluesky',
58+
logo: {
59+
dark: LogoBluesky,
60+
light: LogoBlueskyLight,
61+
},
62+
normalisingIndent: '0.625rem',
63+
url: 'https://bsky.app/',
64+
},
5465
]

app/components/BlogPostListCard.vue

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@ defineProps<{
3333
<!-- Text Content -->
3434
<div class="flex-1 min-w-0 text-start gap-2">
3535
<div class="flex items-center gap-2">
36-
<span class="text-xs text-fg-muted font-mono">{{ published }}</span>
36+
<span class="text-xs text-fg-muted font-mono">
37+
<DateTime :datetime="published" year="numeric" month="short" day="numeric" />
38+
</span>
3739
<span
3840
v-if="draft"
3941
class="text-xs px-1.5 py-0.5 rounded badge-orange font-sans font-medium"

config/env.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,15 @@ export const gitBranch = process.env.BRANCH || process.env.VERCEL_GIT_COMMIT_REF
4444
* Whether this is the canary environment (main.npmx.dev).
4545
*
4646
* Detected as any non-PR Vercel deploy from the `main` branch
47-
* (which may receive `VERCEL_ENV === 'production'` or `'preview'`
48-
* depending on the project's production branch configuration).
47+
* (which may receive `VERCEL_ENV === 'production'`, `'preview'`, or a
48+
* custom `'canary'` environment depending on the project configuration).
4949
*
5050
* @see {@link https://vercel.com/docs/environment-variables/system-environment-variables#VERCEL_ENV}
5151
*/
5252
export const isCanary =
53-
(process.env.VERCEL_ENV === 'production' || process.env.VERCEL_ENV === 'preview') &&
53+
(process.env.VERCEL_ENV === 'production' ||
54+
process.env.VERCEL_ENV === 'preview' ||
55+
process.env.VERCEL_ENV === 'canary') &&
5456
gitBranch === 'main' &&
5557
!isPR
5658

nuxt.config.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export default defineNuxtConfig({
5555
},
5656
},
5757

58-
devtools: { enabled: !true },
58+
devtools: { enabled: true },
5959

6060
devServer: {
6161
// Used with atproto oauth
@@ -136,6 +136,14 @@ export default defineNuxtConfig({
136136
// never cache
137137
'/api/auth/**': { isr: false, cache: false },
138138
'/api/social/**': { isr: false, cache: false },
139+
'/api/atproto/bluesky-comments': {
140+
isr: {
141+
expiration: 60 * 60 /* one hour */,
142+
passQuery: true,
143+
allowQuery: ['uri'],
144+
},
145+
cache: { maxAge: 3600 },
146+
},
139147
'/api/atproto/bluesky-author-profiles': {
140148
isr: {
141149
expiration: 60 * 60 /* one hour */,

server/api/registry/badge/[type]/[...pkg].get.ts

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,14 @@ function measureDefaultTextWidth(text: string): number {
8787
return Math.max(MIN_BADGE_TEXT_WIDTH, Math.round(text.length * CHAR_WIDTH) + BADGE_PADDING_X * 2)
8888
}
8989

90+
function escapeXML(str: string): string {
91+
return str
92+
.replace(/&/g, '&amp;')
93+
.replace(/</g, '&lt;')
94+
.replace(/>/g, '&gt;')
95+
.replace(/"/g, '&quot;')
96+
}
97+
9098
function measureShieldsTextLength(text: string): number {
9199
const measuredWidth = measureTextWidth(text, SHIELDS_FONT_SHORTHAND)
92100

@@ -108,9 +116,11 @@ function renderDefaultBadgeSvg(params: {
108116
const rightWidth = measureDefaultTextWidth(finalValue)
109117
const totalWidth = leftWidth + rightWidth
110118
const height = 20
119+
const escapedLabel = escapeXML(finalLabel)
120+
const escapedValue = escapeXML(finalValue)
111121

112122
return `
113-
<svg xmlns="http://www.w3.org/2000/svg" width="${totalWidth}" height="${height}" role="img" aria-label="${finalLabel}: ${finalValue}">
123+
<svg xmlns="http://www.w3.org/2000/svg" width="${totalWidth}" height="${height}" role="img" aria-label="${escapedLabel}: ${escapedValue}">
114124
<clipPath id="r">
115125
<rect width="${totalWidth}" height="${height}" rx="3" fill="#fff"/>
116126
</clipPath>
@@ -119,8 +129,8 @@ function renderDefaultBadgeSvg(params: {
119129
<rect x="${leftWidth}" width="${rightWidth}" height="${height}" fill="${finalColor}"/>
120130
</g>
121131
<g text-anchor="middle" font-family="Geist, system-ui, -apple-system, sans-serif" font-size="11">
122-
<text x="${leftWidth / 2}" y="14" fill="#ffffff">${finalLabel}</text>
123-
<text x="${leftWidth + rightWidth / 2}" y="14" fill="#ffffff">${finalValue}</text>
132+
<text x="${leftWidth / 2}" y="14" fill="#ffffff">${escapedLabel}</text>
133+
<text x="${leftWidth + rightWidth / 2}" y="14" fill="#ffffff">${escapedValue}</text>
124134
</g>
125135
</svg>
126136
`.trim()
@@ -141,7 +151,9 @@ function renderShieldsBadgeSvg(params: {
141151
const rightWidth = rightTextLength + SHIELDS_LABEL_PADDING_X * 2
142152
const totalWidth = leftWidth + rightWidth
143153
const height = 20
144-
const title = `${finalLabel}: ${finalValue}`
154+
const escapedLabel = escapeXML(finalLabel)
155+
const escapedValue = escapeXML(finalValue)
156+
const title = `${escapedLabel}: ${escapedValue}`
145157

146158
const leftCenter = Math.round((leftWidth / 2) * 10)
147159
const rightCenter = Math.round((leftWidth + rightWidth / 2) * 10)
@@ -163,10 +175,10 @@ function renderShieldsBadgeSvg(params: {
163175
<rect width="${totalWidth}" height="${height}" fill="url(#s)"/>
164176
</g>
165177
<g fill="#fff" text-anchor="middle" font-family="Verdana, Geneva, DejaVu Sans, sans-serif" text-rendering="geometricPrecision" font-size="110">
166-
<text aria-hidden="true" x="${leftCenter}" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="${leftTextLengthAttr}">${finalLabel}</text>
167-
<text x="${leftCenter}" y="140" transform="scale(.1)" fill="#fff" textLength="${leftTextLengthAttr}">${finalLabel}</text>
168-
<text aria-hidden="true" x="${rightCenter}" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="${rightTextLengthAttr}">${finalValue}</text>
169-
<text x="${rightCenter}" y="140" transform="scale(.1)" fill="#fff" textLength="${rightTextLengthAttr}">${finalValue}</text>
178+
<text aria-hidden="true" x="${leftCenter}" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="${leftTextLengthAttr}">${escapedLabel}</text>
179+
<text x="${leftCenter}" y="140" transform="scale(.1)" fill="#fff" textLength="${leftTextLengthAttr}">${escapedLabel}</text>
180+
<text aria-hidden="true" x="${rightCenter}" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="${rightTextLengthAttr}">${escapedValue}</text>
181+
<text x="${rightCenter}" y="140" transform="scale(.1)" fill="#fff" textLength="${rightTextLengthAttr}">${escapedValue}</text>
170182
</g>
171183
</svg>
172184
`.trim()

shared/schemas/social.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,19 @@ export type PackageLikeBody = v.InferOutput<typeof PackageLikeBodySchema>
1313
// TODO: add 'avatar'
1414
export const ProfileEditBodySchema = v.object({
1515
displayName: v.pipe(v.string(), v.maxLength(640)),
16-
website: v.optional(v.union([v.literal(''), v.pipe(v.string(), v.url())])),
16+
website: v.optional(
17+
v.union([
18+
v.literal(''),
19+
v.pipe(
20+
v.string(),
21+
v.url(),
22+
v.check(
23+
url => url.startsWith('https://') || url.startsWith('http://'),
24+
'Website must use http or https',
25+
),
26+
),
27+
]),
28+
),
1729
description: v.optional(v.pipe(v.string(), v.maxLength(2560))),
1830
})
1931

0 commit comments

Comments
 (0)