|
1 | | -import { existsSync } from "node:fs"; |
2 | | -import { platform } from "node:os"; |
3 | | -import { logRaw, updateStatus } from "@cloudflare/cli"; |
4 | | -import { blue, brandColor, dim } from "@cloudflare/cli/colors"; |
5 | | -import { runFrameworkGenerator } from "frameworks/index"; |
6 | | -import { transformFile } from "helpers/codemod"; |
7 | | -import { usesTypescript } from "helpers/files"; |
8 | | -import { detectPackageManager } from "helpers/packageManagers"; |
9 | | -import { installPackages } from "helpers/packages"; |
10 | | -import * as recast from "recast"; |
11 | | -import type { TemplateConfig } from "../../src/templates"; |
12 | | -import type { C3Context, PackageJson } from "types"; |
| 1 | +import pages from "./pages/c3"; |
| 2 | +import workers from "./workers/c3"; |
| 3 | +import type { MultiPlatformTemplateConfig } from "../../src/templates"; |
13 | 4 |
|
14 | | -const { npm } = detectPackageManager(); |
15 | | - |
16 | | -const generate = async (ctx: C3Context) => { |
17 | | - await runFrameworkGenerator(ctx, ["create", ctx.project.name]); |
18 | | - |
19 | | - logRaw(""); |
20 | | -}; |
21 | | - |
22 | | -const configure = async (ctx: C3Context) => { |
23 | | - // Install the adapter |
24 | | - const pkg = `@sveltejs/adapter-cloudflare`; |
25 | | - await installPackages([pkg], { |
26 | | - dev: true, |
27 | | - startText: "Adding the Cloudflare Pages adapter", |
28 | | - doneText: `${brandColor(`installed`)} ${dim(pkg)}`, |
29 | | - }); |
30 | | - |
31 | | - updateSvelteConfig(); |
32 | | - updatePlaywrightConfig(usesTypescript(ctx)); |
33 | | - updateTypeDefinitions(ctx); |
34 | | -}; |
35 | | - |
36 | | -const updateSvelteConfig = () => { |
37 | | - // All we need to do is change the import statement in svelte.config.js |
38 | | - updateStatus(`Changing adapter in ${blue("svelte.config.js")}`); |
39 | | - |
40 | | - transformFile("svelte.config.js", { |
41 | | - visitImportDeclaration: function (n) { |
42 | | - // importSource is the `x` in `import y from "x"` |
43 | | - const importSource = n.value.source; |
44 | | - if (importSource.value === "@sveltejs/adapter-auto") { |
45 | | - importSource.value = "@sveltejs/adapter-cloudflare"; |
46 | | - } |
47 | | - |
48 | | - // stop traversing this node |
49 | | - return false; |
50 | | - }, |
51 | | - }); |
52 | | -}; |
53 | | - |
54 | | -const updatePlaywrightConfig = (shouldUseTypescript: boolean) => { |
55 | | - const filePath = `playwright.config.${shouldUseTypescript ? "ts" : "js"}`; |
56 | | - if (!existsSync(filePath)) { |
57 | | - return; |
58 | | - } |
59 | | - |
60 | | - updateStatus(`Changing webServer port in ${blue(filePath)}`); |
61 | | - |
62 | | - transformFile(filePath, { |
63 | | - visitObjectExpression: function (n) { |
64 | | - const portProp = n.node.properties.find((prop) => { |
65 | | - if (!("key" in prop) || !("name" in prop.key)) { |
66 | | - return false; |
67 | | - } |
68 | | - |
69 | | - return prop.key.name === "port"; |
70 | | - }); |
71 | | - |
72 | | - if (!portProp || !("value" in portProp) || !("value" in portProp.value)) { |
73 | | - return this.traverse(n); |
74 | | - } |
75 | | - |
76 | | - portProp.value.value = 8788; |
77 | | - return false; |
78 | | - }, |
79 | | - }); |
80 | | -}; |
81 | | - |
82 | | -const updateTypeDefinitions = (ctx: C3Context) => { |
83 | | - if (!usesTypescript(ctx)) { |
84 | | - return; |
85 | | - } |
86 | | - |
87 | | - updateStatus(`Updating global type definitions in ${blue("app.d.ts")}`); |
88 | | - |
89 | | - const b = recast.types.builders; |
90 | | - |
91 | | - transformFile("src/app.d.ts", { |
92 | | - visitTSModuleDeclaration(n) { |
93 | | - if (n.value.id.name === "App" && n.node.body) { |
94 | | - const moduleBlock = n.node |
95 | | - .body as recast.types.namedTypes.TSModuleBlock; |
96 | | - |
97 | | - const platformInterface = b.tsInterfaceDeclaration( |
98 | | - b.identifier("Platform"), |
99 | | - b.tsInterfaceBody([ |
100 | | - b.tsPropertySignature( |
101 | | - b.identifier("env"), |
102 | | - b.tsTypeAnnotation(b.tsTypeReference(b.identifier("Env"))), |
103 | | - ), |
104 | | - b.tsPropertySignature( |
105 | | - b.identifier("cf"), |
106 | | - b.tsTypeAnnotation( |
107 | | - b.tsTypeReference(b.identifier("CfProperties")), |
108 | | - ), |
109 | | - ), |
110 | | - b.tsPropertySignature( |
111 | | - b.identifier("ctx"), |
112 | | - b.tsTypeAnnotation( |
113 | | - b.tsTypeReference(b.identifier("ExecutionContext")), |
114 | | - ), |
115 | | - ), |
116 | | - ]), |
117 | | - ); |
118 | | - |
119 | | - moduleBlock.body.unshift(platformInterface); |
120 | | - } |
121 | | - |
122 | | - this.traverse(n); |
123 | | - }, |
124 | | - }); |
125 | | -}; |
126 | | - |
127 | | -const config: TemplateConfig = { |
128 | | - configVersion: 1, |
129 | | - id: "svelte", |
130 | | - frameworkCli: "sv", |
| 5 | +const config: MultiPlatformTemplateConfig = { |
131 | 6 | displayName: "SvelteKit", |
132 | | - platform: "pages", |
133 | | - copyFiles: { |
134 | | - path: "./templates", |
135 | | - }, |
136 | | - generate, |
137 | | - configure, |
138 | | - transformPackageJson: async (original: PackageJson, ctx: C3Context) => { |
139 | | - let scripts: Record<string, string> = { |
140 | | - preview: `${npm} run build && wrangler pages dev`, |
141 | | - deploy: `${npm} run build && wrangler pages deploy`, |
142 | | - }; |
143 | | - |
144 | | - if (usesTypescript(ctx)) { |
145 | | - const mv = platform() === "win32" ? "move" : "mv"; |
146 | | - scripts = { |
147 | | - ...scripts, |
148 | | - "cf-typegen": `wrangler types && ${mv} worker-configuration.d.ts src/`, |
149 | | - }; |
150 | | - } |
151 | | - |
152 | | - return { scripts }; |
153 | | - }, |
154 | | - devScript: "dev", |
155 | | - deployScript: "deploy", |
156 | | - previewScript: "preview", |
| 7 | + platformVariants: { pages, workers }, |
157 | 8 | }; |
158 | 9 | export default config; |
0 commit comments