@tanstack/cli 0.0.6 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.cjs +15 -7
- package/dist/bin.mjs +11 -3
- package/dist/fetch-CbFFGJEw.cjs +3 -0
- package/dist/fetch-DG5dLrsb.cjs +522 -0
- package/dist/fetch-DhlVXS6S.mjs +390 -0
- package/dist/fetch-I_OVg8JX.mjs +3 -0
- package/dist/index.cjs +23 -22
- package/dist/index.mjs +2 -1
- package/dist/{template-CkAkdP8n.mjs → template-Szi7-AZJ.mjs} +53 -396
- package/dist/{template-Cup47s9h.cjs → template-lWrIZhCQ.cjs} +53 -522
- package/package.json +1 -1
- package/src/api/fetch.ts +31 -2
- package/src/commands/create.ts +9 -2
- package/src/commands/mcp.ts +9 -1
- package/src/engine/compile.ts +18 -0
- package/src/templates/base.ts +11 -19
package/src/api/fetch.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { existsSync, readFileSync, readdirSync, statSync } from 'node:fs'
|
|
2
|
-
import { join } from 'node:path'
|
|
2
|
+
import { extname, join } from 'node:path'
|
|
3
3
|
import {
|
|
4
4
|
IntegrationCompiledSchema,
|
|
5
5
|
IntegrationInfoSchema,
|
|
@@ -14,6 +14,24 @@ const GITHUB_RAW_BASE =
|
|
|
14
14
|
// 1 hour cache TTL for remote fetches
|
|
15
15
|
const CACHE_TTL_MS = 60 * 60 * 1000
|
|
16
16
|
|
|
17
|
+
// Binary file extensions that should be read as base64
|
|
18
|
+
const BINARY_EXTENSIONS = new Set([
|
|
19
|
+
'.png', '.jpg', '.jpeg', '.gif', '.webp', '.ico', '.svg',
|
|
20
|
+
'.woff', '.woff2', '.ttf', '.eot', '.otf',
|
|
21
|
+
'.pdf', '.zip', '.tar', '.gz',
|
|
22
|
+
'.mp3', '.mp4', '.wav', '.ogg', '.webm',
|
|
23
|
+
])
|
|
24
|
+
|
|
25
|
+
// Prefix for base64-encoded binary files
|
|
26
|
+
export const BINARY_PREFIX = 'base64:'
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Check if a file should be treated as binary based on extension
|
|
30
|
+
*/
|
|
31
|
+
function isBinaryFile(filePath: string): boolean {
|
|
32
|
+
return BINARY_EXTENSIONS.has(extname(filePath).toLowerCase())
|
|
33
|
+
}
|
|
34
|
+
|
|
17
35
|
/**
|
|
18
36
|
* Check if a path is a local directory
|
|
19
37
|
*/
|
|
@@ -92,6 +110,7 @@ export async function fetchIntegrationInfo(
|
|
|
92
110
|
|
|
93
111
|
/**
|
|
94
112
|
* Recursively read all files from a directory
|
|
113
|
+
* Binary files are read as base64 with a prefix marker
|
|
95
114
|
*/
|
|
96
115
|
function readDirRecursive(
|
|
97
116
|
dir: string,
|
|
@@ -108,6 +127,10 @@ function readDirRecursive(
|
|
|
108
127
|
|
|
109
128
|
if (stat.isDirectory()) {
|
|
110
129
|
Object.assign(files, readDirRecursive(fullPath, relativePath))
|
|
130
|
+
} else if (isBinaryFile(relativePath)) {
|
|
131
|
+
// Read binary files as base64 with prefix
|
|
132
|
+
const buffer = readFileSync(fullPath)
|
|
133
|
+
files[relativePath] = BINARY_PREFIX + buffer.toString('base64')
|
|
111
134
|
} else {
|
|
112
135
|
files[relativePath] = readFileSync(fullPath, 'utf-8')
|
|
113
136
|
}
|
|
@@ -152,7 +175,13 @@ export async function fetchIntegrationFiles(
|
|
|
152
175
|
const fileResponse = await fetch(fileUrl)
|
|
153
176
|
|
|
154
177
|
if (fileResponse.ok) {
|
|
155
|
-
|
|
178
|
+
if (isBinaryFile(filePath)) {
|
|
179
|
+
// Fetch binary files as arrayBuffer and convert to base64
|
|
180
|
+
const buffer = await fileResponse.arrayBuffer()
|
|
181
|
+
files[filePath] = BINARY_PREFIX + Buffer.from(buffer).toString('base64')
|
|
182
|
+
} else {
|
|
183
|
+
files[filePath] = await fileResponse.text()
|
|
184
|
+
}
|
|
156
185
|
}
|
|
157
186
|
}),
|
|
158
187
|
)
|
package/src/commands/create.ts
CHANGED
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
text,
|
|
15
15
|
} from '@clack/prompts'
|
|
16
16
|
import chalk from 'chalk'
|
|
17
|
-
import { fetchIntegrations, fetchManifest } from '../api/fetch.js'
|
|
17
|
+
import { BINARY_PREFIX, fetchIntegrations, fetchManifest } from '../api/fetch.js'
|
|
18
18
|
import { compile } from '../engine/compile.js'
|
|
19
19
|
import { writeConfigFile } from '../engine/config-file.js'
|
|
20
20
|
import { loadTemplate } from '../engine/custom-addons/template.js'
|
|
@@ -383,7 +383,14 @@ export async function runCreate(
|
|
|
383
383
|
const fullPath = resolve(targetDir, filePath)
|
|
384
384
|
const dir = resolve(fullPath, '..')
|
|
385
385
|
mkdirSync(dir, { recursive: true })
|
|
386
|
-
|
|
386
|
+
|
|
387
|
+
// Handle binary files (base64 encoded with prefix)
|
|
388
|
+
if (content.startsWith(BINARY_PREFIX)) {
|
|
389
|
+
const base64Data = content.slice(BINARY_PREFIX.length)
|
|
390
|
+
writeFileSync(fullPath, Buffer.from(base64Data, 'base64'))
|
|
391
|
+
} else {
|
|
392
|
+
writeFileSync(fullPath, content, 'utf-8')
|
|
393
|
+
}
|
|
387
394
|
}
|
|
388
395
|
|
|
389
396
|
// Write config file for integration/template creation
|
package/src/commands/mcp.ts
CHANGED
|
@@ -94,6 +94,7 @@ function createServer() {
|
|
|
94
94
|
try {
|
|
95
95
|
const { mkdirSync, writeFileSync } = await import('node:fs')
|
|
96
96
|
const { resolve } = await import('node:path')
|
|
97
|
+
const { BINARY_PREFIX } = await import('../api/fetch.js')
|
|
97
98
|
const { execSync } = await import('node:child_process')
|
|
98
99
|
|
|
99
100
|
// Fetch integration definitions if needed
|
|
@@ -121,7 +122,14 @@ function createServer() {
|
|
|
121
122
|
const fullPath = resolve(targetDir, filePath)
|
|
122
123
|
const dir = resolve(fullPath, '..')
|
|
123
124
|
mkdirSync(dir, { recursive: true })
|
|
124
|
-
|
|
125
|
+
|
|
126
|
+
// Handle binary files (base64 encoded with prefix)
|
|
127
|
+
if (content.startsWith(BINARY_PREFIX)) {
|
|
128
|
+
const base64Data = content.slice(BINARY_PREFIX.length)
|
|
129
|
+
writeFileSync(fullPath, Buffer.from(base64Data, 'base64'))
|
|
130
|
+
} else {
|
|
131
|
+
writeFileSync(fullPath, content, 'utf-8')
|
|
132
|
+
}
|
|
125
133
|
}
|
|
126
134
|
|
|
127
135
|
// Initialize git
|
package/src/engine/compile.ts
CHANGED
|
@@ -129,6 +129,7 @@ function buildPackageJson(
|
|
|
129
129
|
dependencies: {
|
|
130
130
|
'@tanstack/react-router': '^1.132.0',
|
|
131
131
|
'@tanstack/react-router-devtools': '^1.132.0',
|
|
132
|
+
'@tanstack/react-devtools': '^0.9.2',
|
|
132
133
|
'@tanstack/react-start': '^1.132.0',
|
|
133
134
|
react: '^19.2.0',
|
|
134
135
|
'react-dom': '^19.2.0',
|
|
@@ -246,6 +247,23 @@ export function compile(options: CompileOptions): CompileOutput {
|
|
|
246
247
|
return true
|
|
247
248
|
})
|
|
248
249
|
|
|
250
|
+
// Generate .env.example with integration env vars
|
|
251
|
+
if (uniqueEnvVars.length > 0) {
|
|
252
|
+
const envLines: Array<string> = [
|
|
253
|
+
'# Environment Variables',
|
|
254
|
+
'# Copy this file to .env.local and fill in your values',
|
|
255
|
+
'',
|
|
256
|
+
]
|
|
257
|
+
|
|
258
|
+
for (const v of uniqueEnvVars) {
|
|
259
|
+
envLines.push(`# ${v.description}${v.required ? ' (required)' : ''}`)
|
|
260
|
+
envLines.push(`${v.name}=${v.example || ''}`)
|
|
261
|
+
envLines.push('')
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
outputFiles['.env.example'] = envLines.join('\n')
|
|
265
|
+
}
|
|
266
|
+
|
|
249
267
|
return {
|
|
250
268
|
files: outputFiles,
|
|
251
269
|
packages,
|
package/src/templates/base.ts
CHANGED
|
@@ -163,11 +163,9 @@ export function generateRootRoute(
|
|
|
163
163
|
const lines: Array<{ text: string; integrationId: string }> = []
|
|
164
164
|
const hasHeader = options.chosenIntegrations.length > 0
|
|
165
165
|
|
|
166
|
-
if (devtoolsPlugins.length > 0) {
|
|
167
|
-
lines.push({ text: `import React from 'react'`, integrationId: 'base' })
|
|
168
|
-
}
|
|
169
166
|
lines.push({ text: `import { HeadContent, Scripts, createRootRoute } from '@tanstack/react-router'`, integrationId: 'base' })
|
|
170
|
-
lines.push({ text: `import {
|
|
167
|
+
lines.push({ text: `import { TanStackDevtools } from '@tanstack/react-devtools'`, integrationId: 'base' })
|
|
168
|
+
lines.push({ text: `import { TanStackRouterDevtoolsPanel } from '@tanstack/react-router-devtools'`, integrationId: 'base' })
|
|
171
169
|
|
|
172
170
|
lines.push({ text: `import appCss from '../styles.css?url'`, integrationId: 'base' })
|
|
173
171
|
if (hasHeader) {
|
|
@@ -194,16 +192,6 @@ export function generateRootRoute(
|
|
|
194
192
|
lines.push({ text: `import { ${devtools.jsName} } from '${importPath}'`, integrationId: devtools.integrationId })
|
|
195
193
|
}
|
|
196
194
|
|
|
197
|
-
// Devtools array
|
|
198
|
-
if (devtoolsPlugins.length > 0) {
|
|
199
|
-
lines.push({ text: '', integrationId: 'base' })
|
|
200
|
-
lines.push({ text: `const devtoolsPlugins = [`, integrationId: 'base' })
|
|
201
|
-
for (const devtools of devtoolsPlugins) {
|
|
202
|
-
lines.push({ text: ` ${devtools.jsName},`, integrationId: devtools.integrationId })
|
|
203
|
-
}
|
|
204
|
-
lines.push({ text: `]`, integrationId: 'base' })
|
|
205
|
-
}
|
|
206
|
-
|
|
207
195
|
lines.push({ text: '', integrationId: 'base' })
|
|
208
196
|
lines.push({ text: `export const Route = createRootRoute({`, integrationId: 'base' })
|
|
209
197
|
lines.push({ text: ` head: () => ({`, integrationId: 'base' })
|
|
@@ -237,13 +225,17 @@ export function generateRootRoute(
|
|
|
237
225
|
lines.push({ text: `${currentIndent}<Header />`, integrationId: 'base' })
|
|
238
226
|
}
|
|
239
227
|
lines.push({ text: `${currentIndent}{children}`, integrationId: 'base' })
|
|
240
|
-
lines.push({ text: `${currentIndent}<TanStackRouterDevtools />`, integrationId: 'base' })
|
|
241
228
|
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
229
|
+
// TanStack unified devtools with plugins
|
|
230
|
+
lines.push({ text: `${currentIndent}<TanStackDevtools`, integrationId: 'base' })
|
|
231
|
+
lines.push({ text: `${currentIndent} config={{ position: 'bottom-right' }}`, integrationId: 'base' })
|
|
232
|
+
lines.push({ text: `${currentIndent} plugins={[`, integrationId: 'base' })
|
|
233
|
+
lines.push({ text: `${currentIndent} { name: 'TanStack Router', render: <TanStackRouterDevtoolsPanel /> },`, integrationId: 'base' })
|
|
234
|
+
for (const devtools of devtoolsPlugins) {
|
|
235
|
+
lines.push({ text: `${currentIndent} ${devtools.jsName},`, integrationId: devtools.integrationId })
|
|
246
236
|
}
|
|
237
|
+
lines.push({ text: `${currentIndent} ]}`, integrationId: 'base' })
|
|
238
|
+
lines.push({ text: `${currentIndent}/>`, integrationId: 'base' })
|
|
247
239
|
|
|
248
240
|
for (const provider of [...rootProviders].reverse()) {
|
|
249
241
|
currentIndent = currentIndent.slice(0, -2)
|