Skip to content

Commit 182545c

Browse files
committed
fix: some assets fail
1 parent 13975fe commit 182545c

7 files changed

Lines changed: 207 additions & 46 deletions

File tree

app/components/SpeakerPageSection.vue

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import SpeakerPageHeading from '~/components/speakers/SpeakerPageHeading.vue'
44
import SectionTitle from '~/components/SectionTitle.vue'
55
import { speakers } from '~/utils/speakers.constants'
66
import { urlBasePath } from '~/utils/constants'
7+
import { sponsors as fallbackSponsors } from '~/utils/newt.constants'
78
// import { ISpeaker } from '~/types/interface'
89
910
const shuffleArray = ([...array]) => {
@@ -24,7 +25,11 @@ const LTSpeakers = speakers.filter(speaker => speaker.session.type === 'LT')
2425
const { fetchContent } = useSponsorsCMS()
2526
const { data: sponsors } = useLazyAsyncData('sponsors', () => fetchContent())
2627
27-
const sessionSponsors = (computed(() => [...sponsors.value.platinum, ...sponsors.value.gold]))
28+
const sessionSponsors = computed(() => {
29+
const resolvedSponsors = sponsors.value ?? fallbackSponsors
30+
31+
return [...resolvedSponsors.platinum, ...resolvedSponsors.gold]
32+
})
2833
</script>
2934

3035
<template>

app/composables/useCMS.ts

Lines changed: 93 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,102 @@
11
import { createClient } from 'newt-client-js'
22
import { Query } from 'newt-client-js/dist/types/types'
3-
import { ISponsor } from '~/types/sponsors'
3+
import { sponsors as fallbackSponsors } from '~/utils/newt.constants'
4+
import { ISponsor, Rank } from '~/types/sponsors'
5+
6+
type SponsorGroups = Record<Rank, ISponsor[]>
7+
8+
const sponsorRanks: Rank[] = [
9+
'platinum',
10+
'gold',
11+
'silver',
12+
'bronze',
13+
'specialMedia',
14+
'media',
15+
'streaming',
16+
'dinner',
17+
]
18+
19+
function createEmptySponsorGroups(): SponsorGroups {
20+
return sponsorRanks.reduce((groups, rank) => {
21+
groups[rank] = []
22+
return groups
23+
}, {} as SponsorGroups)
24+
}
25+
26+
function normalizeSponsorGroups(groups?: Partial<Record<Rank, ISponsor[]>>): SponsorGroups {
27+
const normalized = createEmptySponsorGroups()
28+
29+
for (const rank of sponsorRanks) {
30+
normalized[rank] = groups?.[rank] ?? []
31+
}
32+
33+
return normalized
34+
}
35+
36+
function fallbackSponsorGroups(): SponsorGroups {
37+
return normalizeSponsorGroups(fallbackSponsors)
38+
}
439

540
export function useCMS<T>(options: { modelUid: string }) {
641
const runtimeConfig = useRuntimeConfig()
7-
const client = createClient({
8-
spaceUid: runtimeConfig.newtSpaceUid,
9-
token: runtimeConfig.newtCdnToken,
10-
apiType: 'cdn',
11-
})
42+
const hasCredentials = Boolean(runtimeConfig.newtSpaceUid && runtimeConfig.newtCdnToken)
43+
const client = hasCredentials
44+
? createClient({
45+
spaceUid: runtimeConfig.newtSpaceUid,
46+
token: runtimeConfig.newtCdnToken,
47+
apiType: 'cdn',
48+
})
49+
: null
1250
const appUid = 'vuefes-2022'
1351

14-
const fetchContent = (query?: Query) =>
15-
client.getContents<T>({ appUid, ...options, query }).then((contents) => {
16-
return contents.items
17-
})
52+
const fetchContent = async (query?: Query) => {
53+
if (!client) {
54+
return []
55+
}
56+
57+
const contents = await client.getContents<T>({ appUid, ...options, query })
58+
59+
return contents.items
60+
}
1861

1962
return {
2063
fetchContent,
2164
}
2265
}
2366

2467
export function useSponsorsCMS() {
25-
const runtimeConfig = useRuntimeConfig()
26-
const client = createClient({
27-
spaceUid: runtimeConfig.newtSpaceUid,
28-
token: runtimeConfig.newtCdnToken,
29-
apiType: 'cdn',
30-
})
31-
const appUid = 'vuefes-2022'
32-
3368
const options = { modelUid: 'sponsor' }
3469
const { fetchContent: getContents } = useCMS<ISponsor>(options)
35-
const fetchContent = () =>
36-
getContents({ appUid, ...options }).then((sponsors) => {
37-
return sponsors
38-
.sort((first, second) => {
39-
return first.order > second.order ? 1 : -1
40-
})
41-
.reduce(groupBy('rank'), {})
42-
})
43-
44-
const fetchContentByName = (name: string) =>
45-
getContents({ name_en: name }).then((sponsor) => {
46-
return sponsor[0]
47-
})
70+
71+
const fetchContent = async () => {
72+
try {
73+
const sponsors = await getContents()
74+
75+
if (sponsors.length === 0) {
76+
return fallbackSponsorGroups()
77+
}
78+
79+
return normalizeSponsorGroups(
80+
sponsors
81+
.sort((first, second) => {
82+
return first.order > second.order ? 1 : -1
83+
})
84+
.reduce(groupBy('rank'), {} as Partial<Record<Rank, ISponsor[]>>),
85+
)
86+
} catch {
87+
return fallbackSponsorGroups()
88+
}
89+
}
90+
91+
const fetchContentByName = async (name: string) => {
92+
try {
93+
const sponsor = await getContents({ name_en: name })
94+
95+
return sponsor[0] ?? findSponsorByName(name)
96+
} catch {
97+
return findSponsorByName(name)
98+
}
99+
}
48100

49101
return {
50102
fetchContent,
@@ -63,3 +115,13 @@ function groupBy<T extends Record<string, any>, P extends keyof T & string>(grou
63115
return acc
64116
}
65117
}
118+
119+
function findSponsorByName(name: string): ISponsor | undefined {
120+
for (const rank of sponsorRanks) {
121+
const sponsor = fallbackSponsors[rank]?.find((entry) => entry.name_en === name)
122+
123+
if (sponsor) {
124+
return sponsor
125+
}
126+
}
127+
}

app/pages/sponsor-sessions/_sponsor/index.vue

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,27 @@ import FooterPageSection from '~/components/FooterPageSection.vue'
77
import IchimatsuDividedBar from '~/components/IchimatsuDividedBar.vue'
88
import { generalOg, twitterOg } from '~/utils/og.constants'
99
import { conferenceTitle, linkUrl } from '~/utils/constants'
10+
import { sponsors as fallbackSponsors } from '~/utils/newt.constants'
1011
import { sponsorSessions } from '~/utils/sponsorSessions.constant'
12+
13+
function findFallbackSponsor(name: string) {
14+
for (const sponsors of Object.values(fallbackSponsors)) {
15+
const sponsor = sponsors.find((entry) => entry.name_en === name)
16+
17+
if (sponsor) {
18+
return sponsor
19+
}
20+
}
21+
}
1122
1223
const route = useRoute()
1324
1425
const sessionInfo = computed(() => sponsorSessions.find(session => session.id === route.params.sponsor))
1526
1627
const { fetchContentByName } = useSponsorsCMS()
17-
const { pending, data: sponsor } = useLazyAsyncData('sponsor-session', () => fetchContentByName(route.params.sponsor))
28+
const sponsorSlug = String(route.params.sponsor)
29+
const { data: sponsor } = useLazyAsyncData(`sponsor-session:${sponsorSlug}`, () => fetchContentByName(sponsorSlug))
30+
const resolvedSponsor = computed(() => sponsor.value ?? findFallbackSponsor(sponsorSlug))
1831
1932
const url = `https://vuefes.jp/2022/sponsor-sessions/${sessionInfo.value.id}`
2033
const title = `${sessionInfo.value.session.title}(${sessionInfo.value.sponsor}) | ${conferenceTitle}`
@@ -31,7 +44,7 @@ useNuxt2Meta({
3144
</script>
3245

3346
<template>
34-
<div v-if="!pending">
47+
<div v-if="resolvedSponsor && sessionInfo">
3548
<nav-page-section class="mb-12" />
3649
<PageTitle
3750
class="mb-10 md:mb-24"
@@ -40,11 +53,11 @@ useNuxt2Meta({
4053
/>
4154
<div class="aspect-[250/140] mx-auto mb-3 w-40 md:mb-6 md:w-62.5">
4255
<img
43-
:src="sponsor.image.src"
44-
:alt="sponsor.name_jp"
56+
:src="resolvedSponsor.image.src"
57+
:alt="resolvedSponsor.name_jp"
4558
>
4659
</div>
47-
<p class="mb-8 text-base font-bold text-center text-vue-blue md:mb-15 md:text-22">{{ sponsor.name_jp }}</p>
60+
<p class="mb-8 text-base font-bold text-center text-vue-blue md:mb-15 md:text-22">{{ resolvedSponsor.name_jp }}</p>
4861
<SessionPageSection :session-info="sessionInfo">
4962
<SpeakerProfiles :speaker-profiles="sessionInfo.speakers" />
5063
</SessionPageSection>

app/utils/speakers.constants.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -458,8 +458,8 @@ export const speakers: ISpeaker[] = [
458458
<p>なお、本発表は以下の3記事の内容を合わせて再構成したものになる予定です。</p>
459459
<ul>
460460
<li><a class="inner-link" target="_blank" rel="noopener" href="https://devblog.thebase.in/entry/2021/12/08/203039">「Storybook と Chromatic でビジュアルリグレッションテストを実施する」</a></li>
461-
<li><a class="inner-link" target="_blank" rel="noopener" href-"https://devblog.thebase.in/entry/process-of-introduction-of-chromatic">「ビジュアルリグレッションテストのツールを導入するまでの意思決定プロセス」</a></li>
462-
<li><a class="inner-link" target="_blank" rel="noopener" href-"https://devblog.thebase.in/entry/typescript-compiler-api-storybook">「TypeScript Compiler API で40の Storybook コンポーネントを storiesOf から CSF(Component Story Format)に置換した」</a></li>
461+
<li><a class="inner-link" target="_blank" rel="noopener" href="https://devblog.thebase.in/entry/process-of-introduction-of-chromatic">「ビジュアルリグレッションテストのツールを導入するまでの意思決定プロセス」</a></li>
462+
<li><a class="inner-link" target="_blank" rel="noopener" href="https://devblog.thebase.in/entry/typescript-compiler-api-storybook">「TypeScript Compiler API で40の Storybook コンポーネントを storiesOf から CSF(Component Story Format)に置換した」</a></li>
463463
</ul>
464464
`,
465465
time: 20,

netlify.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
[build]
2+
command = "npm run generate"
3+
publish = "dist"
4+
15
[[redirects]]
26
from = "/2022/*"
37
to = "/2022/index.html"

nuxt.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export default defineNuxtConfig({
2626
],
2727
link: [
2828
{ rel: 'icon', type: 'image/x-icon', href: '/2022/favicon.ico' },
29-
{ rel: 'icon', sizes: '180x180', href: '/icon/apple-touch-icon.png' },
29+
{ rel: 'icon', sizes: '180x180', href: isProd ? '/2022/icon/apple-touch-icon.png' : '/icon/apple-touch-icon.png' },
3030
...preloadImages(),
3131
],
3232
htmlAttrs: {

scripts/renameDir.js

Lines changed: 83 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,89 @@
11
const fs = require('fs-extra')
2+
const vm = require('vm')
3+
const devalue = require('devalue')
24
const { resolve } = require('path')
35

4-
fs.moveSync(resolve(__dirname, '../dist/'), resolve(__dirname, '../tmp/'))
6+
const generatedDir = resolve(__dirname, '../.output/public')
7+
const publishDir = resolve(__dirname, '../dist')
8+
const yearDir = resolve(publishDir, '2022')
9+
const nestedYearDir = resolve(generatedDir, '2022')
510

6-
fs.moveSync(resolve(__dirname, '../tmp/'), resolve(__dirname, '../dist/2022/'))
11+
if (!fs.existsSync(generatedDir)) {
12+
throw new Error(`Missing generated output at ${generatedDir}`)
13+
}
714

8-
fs.remove('tmp', (err) => {
9-
if (err) {
10-
throw err
15+
fs.removeSync(publishDir)
16+
fs.ensureDirSync(publishDir)
17+
18+
for (const entry of fs.readdirSync(generatedDir)) {
19+
if (entry === '2022') {
20+
continue
21+
}
22+
23+
fs.copySync(resolve(generatedDir, entry), resolve(yearDir, entry))
24+
}
25+
26+
if (fs.existsSync(nestedYearDir)) {
27+
fs.copySync(nestedYearDir, yearDir)
28+
}
29+
30+
const htmlFiles = []
31+
32+
const walkHtmlFiles = dir => {
33+
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
34+
const entryPath = resolve(dir, entry.name)
35+
36+
if (entry.isDirectory()) {
37+
walkHtmlFiles(entryPath)
38+
continue
39+
}
40+
41+
if (entry.isFile() && entry.name.endsWith('.html')) {
42+
htmlFiles.push(entryPath)
43+
}
44+
}
45+
}
46+
47+
const extractNuxtPayload = filePath => {
48+
const html = fs.readFileSync(filePath, 'utf8')
49+
const match = html.match(/<script>window\.__NUXT__=(.*?)<\/script>/s)
50+
51+
if (!match) {
52+
return null
53+
}
54+
55+
const sandbox = { window: {} }
56+
57+
vm.runInNewContext(`window.__NUXT__=${match[1]}`, sandbox, { filename: filePath })
58+
59+
return sandbox.window.__NUXT__
60+
}
61+
62+
const toRelativePath = value => value.replace(/^\/+/, '')
63+
64+
const writePayloadFile = ({ routePath, staticAssetsBase, data, fetch, mutations }) => {
65+
if (!routePath || !staticAssetsBase) {
66+
return
67+
}
68+
69+
const routeDir = routePath === '/' ? '' : toRelativePath(routePath)
70+
const staticAssetsDir = resolve(publishDir, toRelativePath(staticAssetsBase))
71+
const payloadDir = routeDir ? resolve(staticAssetsDir, routeDir) : staticAssetsDir
72+
const payload = devalue({ data, fetch, mutations })
73+
const payloadScript = `__NUXT_JSONP__(${JSON.stringify(routePath)}, ${payload});\n`
74+
75+
fs.ensureDirSync(payloadDir)
76+
fs.writeFileSync(resolve(payloadDir, 'payload.js'), payloadScript)
77+
}
78+
79+
walkHtmlFiles(yearDir)
80+
81+
for (const htmlFile of htmlFiles) {
82+
const nuxtPayload = extractNuxtPayload(htmlFile)
83+
84+
if (!nuxtPayload) {
85+
continue
1186
}
12-
})
87+
88+
writePayloadFile(nuxtPayload)
89+
}

0 commit comments

Comments
 (0)