1- import assert from "node:assert" ;
21import { logRaw } from "@cloudflare/cli" ;
3- import { brandColor , dim } from "@cloudflare/cli/colors" ;
42import { runFrameworkGenerator } from "frameworks/index" ;
5- import { transformFile } from "helpers/codemod" ;
63import { detectPackageManager } from "helpers/packageManagers" ;
7- import { installPackages } from "helpers/packages" ;
8- import * as recast from "recast" ;
94import type { TemplateConfig } from "../../src/templates" ;
10- import type { types } from "recast" ;
115import type { C3Context } from "types" ;
126
13- const b = recast . types . builders ;
14- const t = recast . types . namedTypes ;
157const { npm } = detectPackageManager ( ) ;
168
179const generate = async ( ctx : C3Context ) => {
1810 await runFrameworkGenerator ( ctx , [
1911 ctx . project . name ,
12+ "--host" ,
13+ "cloudflare" ,
2014 "--framework" ,
2115 "react" ,
2216 // to prevent asking about git twice, just let c3 do it
@@ -26,91 +20,13 @@ const generate = async (ctx: C3Context) => {
2620 logRaw ( "" ) ; // newline
2721} ;
2822
29- const configure = async ( ) => {
30- await installPackages ( [ "@cloudflare/vite-plugin" ] , {
31- dev : true ,
32- startText : "Installing the Cloudflare Vite plugin" ,
33- doneText : `${ brandColor ( `installed` ) } ${ dim ( "@cloudflare/vite-plugin" ) } ` ,
34- } ) ;
35-
36- updateViteConfig ( ) ;
37- } ;
38-
39- const updateViteConfig = ( ) => {
40- const filePath = "vite.config.ts" ;
41-
42- transformFile ( filePath , {
43- visitProgram ( n ) {
44- // Add an import of the @cloudflare /vite-plugin
45- // ```
46- // import {cloudflare} from "@cloudflare/vite-plugin";
47- // ```
48- const lastImportIndex = n . node . body . findLastIndex (
49- ( statement ) => statement . type === "ImportDeclaration" ,
50- ) ;
51- const lastImport = n . get ( "body" , lastImportIndex ) ;
52- const importAst = b . importDeclaration (
53- [ b . importSpecifier ( b . identifier ( "cloudflare" ) ) ] ,
54- b . stringLiteral ( "@cloudflare/vite-plugin" ) ,
55- ) ;
56- lastImport . insertAfter ( importAst ) ;
57-
58- return this . traverse ( n ) ;
59- } ,
60- visitCallExpression : function ( n ) {
61- // Add the imported plugin to the config
62- // ```
63- // defineConfig({
64- // plugins: [react(), cloudflare()],
65- // });
66- const callee = n . node . callee as types . namedTypes . Identifier ;
67- if ( callee . name !== "defineConfig" ) {
68- return this . traverse ( n ) ;
69- }
70-
71- const config = n . node . arguments [ 0 ] ;
72- assert ( t . ObjectExpression . check ( config ) ) ;
73- const pluginsProp = config . properties . find ( ( prop ) => isPluginsProp ( prop ) ) ;
74- assert ( pluginsProp && t . ArrayExpression . check ( pluginsProp . value ) ) ;
75- pluginsProp . value . elements . push (
76- b . callExpression ( b . identifier ( "cloudflare" ) , [
77- b . objectExpression ( [
78- b . objectProperty (
79- b . identifier ( "viteEnvironment" ) ,
80- b . objectExpression ( [
81- b . objectProperty ( b . identifier ( "name" ) , b . literal ( "ssr" ) ) ,
82- ] ) ,
83- ) ,
84- ] ) ,
85- ] ) ,
86- ) ;
87-
88- return false ;
89- } ,
90- } ) ;
91- } ;
92-
93- function isPluginsProp (
94- prop : unknown ,
95- ) : prop is types . namedTypes . ObjectProperty | types . namedTypes . Property {
96- return (
97- ( t . Property . check ( prop ) || t . ObjectProperty . check ( prop ) ) &&
98- t . Identifier . check ( prop . key ) &&
99- prop . key . name === "plugins"
100- ) ;
101- }
102-
10323const config : TemplateConfig = {
10424 configVersion : 1 ,
10525 id : "tanstack" ,
10626 platform : "workers" ,
10727 frameworkCli : "@tanstack/create-start" ,
10828 displayName : "TanStack Start" ,
10929 generate,
110- configure,
111- copyFiles : {
112- path : "./templates" ,
113- } ,
11430 transformPackageJson : async ( ) => ( {
11531 scripts : {
11632 deploy : `${ npm } run build && wrangler deploy` ,
0 commit comments