-
Notifications
You must be signed in to change notification settings - Fork 42
Expand file tree
/
Copy pathvite.config.ts
More file actions
144 lines (127 loc) · 4.47 KB
/
vite.config.ts
File metadata and controls
144 lines (127 loc) · 4.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
import * as fs from 'node:fs/promises'
import * as path from 'node:path'
import react from '@vitejs/plugin-react'
import { Instance } from 'prool'
import { defineConfig, loadEnv, type Plugin } from 'vite'
import mkcert from 'vite-plugin-mkcert'
import { vocs } from 'vocs/vite'
// https://vite.dev/config/
export default defineConfig(({ mode }) => {
const env = loadEnv(mode, process.cwd(), '')
for (const key of Object.keys(env)) {
if (!(key in process.env)) process.env[key] = env[key]
}
const useHttp = process.env.CI === 'true' || process.env.VITE_USE_HTTP === 'true'
return {
plugins: [syncTips(), vocs(), react(), ...(useHttp ? [] : [mkcert()]), tempoNode()],
server: useHttp
? {
host: 'localhost',
}
: undefined,
}
})
function tempoNode(): Plugin {
return {
name: 'tempo-node',
async configureServer(_server) {
if (!('VITE_TEMPO_ENV' in process.env) || process.env.VITE_TEMPO_ENV !== 'localnet') return
const instance = Instance.tempo({
dev: { blockTime: '500ms' },
port: 8545,
})
console.log('→ starting tempo node...')
await instance.start()
console.log('√ tempo node started on port 8545')
},
}
}
/**
* Escape angle brackets in prose so MDX does not interpret them as JSX.
* Preserves content inside fenced code blocks and inline code spans.
*/
function escapeAngleBrackets(source: string): string {
const lines = source.split('\n')
const result: string[] = []
let inCodeBlock = false
for (const line of lines) {
if (/^```/.test(line)) {
inCodeBlock = !inCodeBlock
result.push(line)
continue
}
if (inCodeBlock) {
result.push(line)
continue
}
// Split by inline code spans to avoid escaping inside them
const parts = line.split(/(`[^`]*`)/)
for (let i = 0; i < parts.length; i++) {
if (i % 2 === 0) {
// Escape < > that would be misread as JSX. Use backslash escapes
// which MDX/micromark supports.
parts[i] = parts[i].replace(/</g, '<').replace(/>/g, '>')
}
}
result.push(parts.join(''))
}
return result.join('\n')
}
function syncTips(): Plugin {
const repo = 'tempoxyz/tempo'
const outputDir = 'src/pages/protocol/tips'
let synced = false
async function sync() {
if (synced) return
synced = true
console.log('→ syncing TIPs from GitHub...')
const res = await fetch(`https://api.github.com/repos/${repo}/contents/tips`)
if (!res.ok) {
console.error('✗ failed to fetch TIPs directory:', res.statusText)
return
}
const files = (await res.json()) as Array<{ name: string; download_url: string; type: string }>
const tipFiles = files.filter((f) => f.type === 'file' && /^tip-\d+\.md$/.test(f.name))
await fs.mkdir(outputDir, { recursive: true })
await Promise.all(
tipFiles.map(async (file) => {
let content = await fetch(file.download_url).then((r) => r.text())
// Strip stale Solidity interface links from upstream TIPs. The linked
// files are no longer published, so keeping the link would surface dead
// references in the docs UI and fail Vocs' dead-link checker.
content = content.replace(
/^- \[[^\]]+\.sol\]\(tips\/(?:ref-impls|verify)\/src\/interfaces\/[^)]+\)\n/gm,
'',
)
content = content.replace(
/\[([^\]]+\.sol)\]\(tips\/(?:ref-impls|verify)\/src\/interfaces\/[^)]+\)/g,
'$1',
)
// tip-0000 links to `./tip_template.md`, which lives in the tempo
// repo but not in the docs site.
content = content.replace(
/\(\.\/tip_template\.md\)/g,
'(https://github.com/tempoxyz/tempo/blob/main/tips/tip_template.md)',
)
// Rewrite inter-TIP links from ./tip-NNNN.md to ./tip-NNNN (synced as .mdx,
// Vocs resolves extensionless paths).
content = content.replace(/\(\.\/tip-(\d+)\.md\)/g, '(./tip-$1)')
// Escape angle brackets outside of code blocks/inline code so MDX doesn't
// treat them as JSX (e.g. `Mapping<B256, bool>` in prose).
content = escapeAngleBrackets(content)
const outputPath = path.join(outputDir, file.name.replace('.md', '.mdx'))
await fs.writeFile(outputPath, content)
}),
)
console.log(`√ synced ${tipFiles.length} TIPs`)
}
return {
name: 'sync-tips',
async buildStart() {
await sync()
},
async configureServer() {
await sync()
},
}
}