summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Alexander Niebuhr <alexander@nbhr.io> 2023-07-17 15:12:41 +0200
committerGravatar GitHub <noreply@github.com> 2023-07-17 09:12:41 -0400
commit27cd4316c448202f9c697259567b6f084e557fa2 (patch)
tree628107fd5e9423a6c2fc0e95978faf991ee0f603
parent1c8a225a5bdde57a9f1abf8a517ae2c583e4652b (diff)
downloadastro-27cd4316c448202f9c697259567b6f084e557fa2.tar.gz
astro-27cd4316c448202f9c697259567b6f084e557fa2.tar.zst
astro-27cd4316c448202f9c697259567b6f084e557fa2.zip
fix(@astrojs/cloudflare): SSR split file renaming misses ts endpoints (#7568)
* fix bug, where ts files where not renamed correctly * try to make rename logic more robust * remove log * update tests * update changeset * cleanup * fix lint * debug windows tests * fix windows support * fix cloudflare directory code * use EventContext type * improve for loop * change changeset Co-authored-by: Emanuele Stoppa <my.burning@gmail.com> * change changeset Co-authored-by: Emanuele Stoppa <my.burning@gmail.com> --------- Co-authored-by: Emanuele Stoppa <my.burning@gmail.com>
-rw-r--r--packages/integrations/cloudflare/src/index.ts81
-rw-r--r--packages/integrations/cloudflare/src/server.directory.ts4
-rw-r--r--packages/integrations/cloudflare/test/directory-split.test.js3
-rw-r--r--packages/integrations/cloudflare/test/fixtures/split/src/pages/javascript.js0
-rw-r--r--packages/integrations/cloudflare/test/fixtures/split/src/pages/test.json.ts0
-rw-r--r--packages/integrations/cloudflare/test/fixtures/split/src/pages/trpc/[trpc].ts0
6 files changed, 54 insertions, 34 deletions
diff --git a/packages/integrations/cloudflare/src/index.ts b/packages/integrations/cloudflare/src/index.ts
index 40ee006f3..3385acd0d 100644
--- a/packages/integrations/cloudflare/src/index.ts
+++ b/packages/integrations/cloudflare/src/index.ts
@@ -3,7 +3,7 @@ import type { AstroAdapter, AstroConfig, AstroIntegration, RouteData } from 'ast
import esbuild from 'esbuild';
import * as fs from 'fs';
import * as os from 'os';
-import { dirname } from 'path';
+import { sep } from 'path';
import glob from 'tiny-glob';
import { fileURLToPath, pathToFileURL } from 'url';
@@ -21,15 +21,15 @@ interface BuildConfig {
export function getAdapter(isModeDirectory: boolean): AstroAdapter {
return isModeDirectory
? {
- name: '@astrojs/cloudflare',
- serverEntrypoint: '@astrojs/cloudflare/server.directory.js',
- exports: ['onRequest', 'manifest'],
- }
+ name: '@astrojs/cloudflare',
+ serverEntrypoint: '@astrojs/cloudflare/server.directory.js',
+ exports: ['onRequest', 'manifest'],
+ }
: {
- name: '@astrojs/cloudflare',
- serverEntrypoint: '@astrojs/cloudflare/server.advanced.js',
- exports: ['default'],
- };
+ name: '@astrojs/cloudflare',
+ serverEntrypoint: '@astrojs/cloudflare/server.advanced.js',
+ exports: ['default'],
+ };
}
const SHIM = `globalThis.process = {
@@ -112,13 +112,12 @@ export default function createIntegration(args?: Options): AstroIntegration {
}
if (isModeDirectory && _buildConfig.split) {
- const entryPointsRouteData = [..._entryPoints.keys()];
const entryPointsURL = [..._entryPoints.values()];
const entryPaths = entryPointsURL.map((entry) => fileURLToPath(entry));
- const outputDir = fileURLToPath(new URL('.astro', _buildConfig.server));
+ const outputUrl = new URL('$astro', _buildConfig.server)
+ const outputDir = fileURLToPath(outputUrl);
- // NOTE: AFAIK, esbuild keeps the order of the entryPoints array
- const { outputFiles } = await esbuild.build({
+ await esbuild.build({
target: 'es2020',
platform: 'browser',
conditions: ['workerd', 'worker', 'browser'],
@@ -134,28 +133,44 @@ export default function createIntegration(args?: Options): AstroIntegration {
logOverride: {
'ignored-bare-import': 'silent',
},
- write: false,
});
- // loop through all bundled files and write them to the functions folder
- for (const [index, outputFile] of outputFiles.entries()) {
- // we need to make sure the filename in the functions folder
- // matches to cloudflares routing capabilities (see their docs)
- // IN: src/pages/[language]/files/[...path].astro
- // OUT: [language]/files/[[path]].js
- const fileName = entryPointsRouteData[index].component
- .replace('src/pages/', '')
- .replace('.astro', '.js')
- .replace(/(\[\.\.\.)(\w+)(\])/g, (_match, _p1, p2) => {
- return `[[${p2}]]`;
- });
-
- const fileUrl = new URL(fileName, functionsUrl);
- const newFileDir = dirname(fileURLToPath(fileUrl));
- if (!fs.existsSync(newFileDir)) {
- fs.mkdirSync(newFileDir, { recursive: true });
- }
- await fs.promises.writeFile(fileUrl, outputFile.contents);
+ const outputFiles: Array<string> = (
+ await glob(`**/*`, {
+ cwd: outputDir,
+ filesOnly: true,
+ })
+ )
+
+ // move the files into the functions folder
+ // & make sure the file names match Cloudflare syntax for routing
+ for (const outputFile of outputFiles) {
+ const path = outputFile.split(sep);
+
+ const finalSegments = path.map((segment) => segment
+ .replace(/(\_)(\w+)(\_)/g, (_, __, prop) => {
+ return `[${prop}]`;
+ })
+ .replace(/(\_\-\-\-)(\w+)(\_)/g, (_, __, prop) => {
+ return `[[${prop}]]`;
+ })
+ );
+
+ finalSegments[finalSegments.length - 1] = finalSegments[finalSegments.length - 1]
+ .replace('entry.', '')
+ .replace(/(.*)\.(\w+)\.(\w+)$/g, (_, fileName, __, newExt) => {
+ return `${fileName}.${newExt}`;
+ })
+
+ const finalDirPath = finalSegments.slice(0, -1).join(sep);
+ const finalPath = finalSegments.join(sep);
+
+ const newDirUrl = new URL(finalDirPath, functionsUrl);
+ await fs.promises.mkdir(newDirUrl, { recursive: true })
+
+ const oldFileUrl = new URL(`$astro/${outputFile}`, outputUrl);
+ const newFileUrl = new URL(finalPath, functionsUrl);
+ await fs.promises.rename(oldFileUrl, newFileUrl);
}
} else {
const entryPath = fileURLToPath(new URL(_buildConfig.serverEntry, _buildConfig.server));
diff --git a/packages/integrations/cloudflare/src/server.directory.ts b/packages/integrations/cloudflare/src/server.directory.ts
index f9f71a33b..e6cc104f9 100644
--- a/packages/integrations/cloudflare/src/server.directory.ts
+++ b/packages/integrations/cloudflare/src/server.directory.ts
@@ -24,7 +24,9 @@ export function createExports(manifest: SSRManifest) {
const { pathname } = new URL(request.url);
// static assets fallback, in case default _routes.json is not used
if (manifest.assets.has(pathname)) {
- return next(request);
+ // we need this so the page does not error
+ // https://developers.cloudflare.com/pages/platform/functions/advanced-mode/#set-up-a-function
+ return (runtimeEnv.env as EventContext<unknown, string, unknown>['env']).ASSETS.fetch(request);
}
let routeData = app.match(request, { matchNotFound: true });
diff --git a/packages/integrations/cloudflare/test/directory-split.test.js b/packages/integrations/cloudflare/test/directory-split.test.js
index 384543a4b..6e6b0bfe2 100644
--- a/packages/integrations/cloudflare/test/directory-split.test.js
+++ b/packages/integrations/cloudflare/test/directory-split.test.js
@@ -36,6 +36,9 @@ describe('Cloudflare SSR split', () => {
expect(await fixture.pathExists('../functions/[person]/[car].js')).to.be.true;
expect(await fixture.pathExists('../functions/files/[[path]].js')).to.be.true;
expect(await fixture.pathExists('../functions/[language]/files/[[path]].js')).to.be.true;
+ expect(await fixture.pathExists('../functions/trpc/[trpc].js')).to.be.true;
+ expect(await fixture.pathExists('../functions/javascript.js')).to.be.true;
+ expect(await fixture.pathExists('../functions/test.json.js')).to.be.true;
});
it('generates pre-rendered files', async () => {
diff --git a/packages/integrations/cloudflare/test/fixtures/split/src/pages/javascript.js b/packages/integrations/cloudflare/test/fixtures/split/src/pages/javascript.js
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/packages/integrations/cloudflare/test/fixtures/split/src/pages/javascript.js
diff --git a/packages/integrations/cloudflare/test/fixtures/split/src/pages/test.json.ts b/packages/integrations/cloudflare/test/fixtures/split/src/pages/test.json.ts
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/packages/integrations/cloudflare/test/fixtures/split/src/pages/test.json.ts
diff --git a/packages/integrations/cloudflare/test/fixtures/split/src/pages/trpc/[trpc].ts b/packages/integrations/cloudflare/test/fixtures/split/src/pages/trpc/[trpc].ts
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/packages/integrations/cloudflare/test/fixtures/split/src/pages/trpc/[trpc].ts