1- import { endSection } from "@cloudflare/cli" ;
1+ import { crash , endSection } from "@cloudflare/cli" ;
22import { brandColor } from "@cloudflare/cli/colors" ;
33import { spinner } from "@cloudflare/cli/interactive" ;
4- import { parseTs , transformFile } from "helpers/codemod" ;
4+ import { loadTemplateSnippets , transformFile } from "helpers/codemod" ;
55import { runCommand , runFrameworkGenerator } from "helpers/command" ;
66import { usesTypescript } from "helpers/files" ;
77import { detectPackageManager } from "helpers/packages" ;
8+ import * as recast from "recast" ;
89import { quoteShellArgs } from "../../src/common" ;
910import type { TemplateConfig } from "../../src/templates" ;
10- import type * as recast from "recast" ;
1111import type { C3Context } from "types" ;
1212
1313const { npm, npx } = detectPackageManager ( ) ;
@@ -23,6 +23,7 @@ const configure = async (ctx: C3Context) => {
2323 await runCommand ( cmd ) ;
2424
2525 addBindingsProxy ( ctx ) ;
26+ populateCloudflareEnv ( ) ;
2627} ;
2728
2829const addBindingsProxy = ( ctx : C3Context ) => {
@@ -35,43 +36,90 @@ const addBindingsProxy = (ctx: C3Context) => {
3536 const s = spinner ( ) ;
3637 s . start ( "Updating `vite.config.ts`" ) ;
3738
38- // Insert the env declaration after the last import (but before the rest of the body)
39- const envDeclaration = `
40- let env = {};
41-
42- if(process.env.NODE_ENV === 'development') {
43- const { getPlatformProxy } = await import('wrangler');
44- const platformProxy = await getPlatformProxy();
45- env = platformProxy.env;
46- }
47- ` ;
39+ const snippets = loadTemplateSnippets ( ctx ) ;
40+ const b = recast . types . builders ;
4841
4942 transformFile ( "vite.config.ts" , {
43+ // Insert the env declaration after the last import (but before the rest of the body)
5044 visitProgram : function ( n ) {
5145 const lastImportIndex = n . node . body . findLastIndex (
5246 ( t ) => t . type === "ImportDeclaration"
5347 ) ;
54- n . get ( "body" ) . insertAt ( lastImportIndex + 1 , envDeclaration ) ;
48+ const lastImport = n . get ( "body" , lastImportIndex ) ;
49+ lastImport . insertAfter ( ...snippets . getPlatformProxyTs ) ;
50+
51+ return this . traverse ( n ) ;
52+ } ,
53+ // Pass the `platform` object from the declaration to the `qwikCity` plugin
54+ visitCallExpression : function ( n ) {
55+ const callee = n . node . callee as recast . types . namedTypes . Identifier ;
56+ if ( callee . name !== "qwikCity" ) {
57+ return this . traverse ( n ) ;
58+ }
59+
60+ // The config object passed to `qwikCity`
61+ const configArgument = n . node . arguments [ 0 ] as
62+ | recast . types . namedTypes . ObjectExpression
63+ | undefined ;
64+
65+ const platformPropery = b . objectProperty . from ( {
66+ key : b . identifier ( "platform" ) ,
67+ value : b . identifier ( "platform" ) ,
68+ shorthand : true ,
69+ } ) ;
70+
71+ if ( ! configArgument ) {
72+ n . node . arguments = [ b . objectExpression ( [ platformPropery ] ) ] ;
73+
74+ return false ;
75+ }
76+
77+ if ( configArgument . type !== "ObjectExpression" ) {
78+ crash ( "Failed to update `vite.config.ts`" ) ;
79+ }
80+
81+ // Add the `platform` object to the object
82+ configArgument . properties . push ( platformPropery ) ;
5583
5684 return false ;
5785 } ,
5886 } ) ;
5987
60- // Populate the `qwikCity` plugin with the platform object containing the `env` defined above.
61- const platformObject = parseTs ( `{ platform: { env } }` ) ;
88+ s . stop ( ` ${ brandColor ( "updated" ) } \`vite.config.ts\`` ) ;
89+ } ;
6290
63- transformFile ( "vite.config.ts" , {
64- visitCallExpression : function ( n ) {
65- const callee = n . node . callee as recast . types . namedTypes . Identifier ;
66- if ( callee . name === "qwikCity" ) {
67- n . node . arguments = [ platformObject ] ;
91+ const populateCloudflareEnv = ( ) => {
92+ const entrypointPath = "src/entry.cloudflare-pages.tsx" ;
93+
94+ const s = spinner ( ) ;
95+ s . start ( `Updating \`${ entrypointPath } \`` ) ;
96+
97+ transformFile ( entrypointPath , {
98+ visitTSInterfaceDeclaration : function ( n ) {
99+ const b = recast . types . builders ;
100+ const id = n . node . id as recast . types . namedTypes . Identifier ;
101+ if ( id . name !== "QwikCityPlatform" ) {
102+ this . traverse ( n ) ;
68103 }
69104
70- this . traverse ( n ) ;
105+ const newBody = [
106+ [ "env" , "Env" ] ,
107+ // Qwik doesn't supply `cf` to the platform object. Should they do so, uncomment this
108+ // ["cf", "CfProperties"],
109+ ] . map ( ( [ varName , type ] ) =>
110+ b . tsPropertySignature (
111+ b . identifier ( varName ) ,
112+ b . tsTypeAnnotation ( b . tsTypeReference ( b . identifier ( type ) ) )
113+ )
114+ ) ;
115+
116+ n . node . body . body = newBody ;
117+
118+ return false ;
71119 } ,
72120 } ) ;
73121
74- s . stop ( `${ brandColor ( "updated" ) } \`vite.config.ts \`` ) ;
122+ s . stop ( `${ brandColor ( "updated" ) } \`${ entrypointPath } \`` ) ;
75123} ;
76124
77125const config : TemplateConfig = {
@@ -89,6 +137,8 @@ const config: TemplateConfig = {
89137 transformPackageJson : async ( ) => ( {
90138 scripts : {
91139 deploy : `${ npm } run build && wrangler pages deploy ./dist` ,
140+ preview : `${ npm } run build && wrangler pages dev ./dist` ,
141+ "build-cf-types" : `wrangler types` ,
92142 } ,
93143 } ) ,
94144} ;
0 commit comments