Skip to content

Commit

Permalink
fix(router,server,cli): add support for array syntax with server expo…
Browse files Browse the repository at this point in the history
…rts (#27462)

# Why

- fix #27456

<!--
Please describe the motivation for this PR, and link to relevant GitHub
issues, forums posts, or feature requests.
-->

# How

- add support for API routes to match array syntax variations.
- add support for exporting each unique nested variation of HTML routes
for server hosting.


<!--
How did you build this feature or fix this bug and why?
-->

# Test Plan

- Added extensive tests for the new logic in the server manifest
creation, html collection, and e2e server requesting.
- I've also updated the CLI collection tests to use the same manifest
mock creation as the integration navigation tests.

<!--
Please describe how you tested this change and how a reviewer could
reproduce your test, especially if this PR does not include automated
tests! If possible, please also provide terminal output and/or
screenshots demonstrating your test/reproduction.
-->

# Checklist

<!--
Please check the appropriate items below if they apply to your diff.
This is required for changes to Expo modules.
-->

- [ ] Documentation is up to date to reflect these changes (eg:
https://docs.expo.dev and README.md).
- [ ] Conforms with the [Documentation Writing Style
Guide](https://github.com/expo/expo/blob/main/guides/Expo%20Documentation%20Writing%20Style%20Guide.md)
- [ ] This diff will work correctly for `npx expo prebuild` & EAS Build
(eg: updated a module plugin).

---------

Co-authored-by: Expo Bot <34669131+expo-bot@users.noreply.github.com>
  • Loading branch information
EvanBacon and expo-bot committed Mar 7, 2024
1 parent ec39bf6 commit 3d2157c
Show file tree
Hide file tree
Showing 30 changed files with 770 additions and 297 deletions.
@@ -0,0 +1,8 @@
/** @type {import('expo-router/server').RequestHandler} */
export function GET() {
return new Response(
JSON.stringify({
value: 'multi-group-api-get',
})
);
}
3 changes: 3 additions & 0 deletions apps/router-e2e/__e2e__/server/app/(a,b)/multi-group.tsx
@@ -0,0 +1,3 @@
export default function Page() {
return <div data-testid="multi-group">Beta</div>;
}
1 change: 1 addition & 0 deletions packages/@expo/cli/CHANGELOG.md
Expand Up @@ -16,6 +16,7 @@

### 🐛 Bug fixes

- Fix using array syntax `(a,b)` with server output. ([#27462](https://github.com/expo/expo/pull/27462) by [@EvanBacon](https://github.com/EvanBacon))
- Prevent `console.log` statements from colliding with Metro logs. ([#27217](https://github.com/expo/expo/pull/27217) by [@EvanBacon](https://github.com/EvanBacon))
- Fix using dev server URL in development. ([#27213](https://github.com/expo/expo/pull/27213) by [@EvanBacon](https://github.com/EvanBacon))
- Always reset production bundler cache in run command. ([#27114](https://github.com/expo/expo/pull/27114) by [@EvanBacon](https://github.com/EvanBacon))
Expand Down
77 changes: 69 additions & 8 deletions packages/@expo/cli/e2e/__tests__/export/server.test.ts
Expand Up @@ -29,6 +29,20 @@ describe('server-output', () => {
560 * 1000
);

function getFiles() {
// List output files with sizes for snapshotting.
// This is to make sure that any changes to the output are intentional.
// Posix path formatting is used to make paths the same across OSes.
return klawSync(outputDir)
.map((entry) => {
if (entry.path.includes('node_modules') || !entry.stats.isFile()) {
return null;
}
return path.posix.relative(outputDir, entry.path);
})
.filter(Boolean);
}

describe('requests', () => {
beforeAll(async () => {
await ensurePortFreeAsync(3000);
Expand Down Expand Up @@ -126,6 +140,60 @@ describe('server-output', () => {
).toMatch(/<div id="root">/);
});

it(`can serve up static html in array group`, async () => {
expect(getFiles()).not.toContain('server/multi-group.html');
expect(getFiles()).not.toContain('server/(a,b)/multi-group.html');
expect(getFiles()).toContain('server/(a)/multi-group.html');
expect(getFiles()).toContain('server/(b)/multi-group.html');
expect(await fetch('http://localhost:3000/multi-group').then((res) => res.text())).toMatch(
/<div data-testid="multi-group">/
);
});

it(`can serve up static html in specific array group`, async () => {
expect(
await fetch('http://localhost:3000/(a)/multi-group').then((res) => res.text())
).toMatch(/<div data-testid="multi-group">/);

expect(
await fetch('http://localhost:3000/(b)/multi-group').then((res) => res.text())
).toMatch(/<div data-testid="multi-group">/);
});

it(`can not serve up static html in retained array group syntax`, async () => {
// Should not be able to match the array syntax
expect(
await fetch('http://localhost:3000/(a,b)/multi-group').then((res) => res.status)
).toEqual(404);
});

it(`can serve up API route in array group`, async () => {
expect(getFiles()).toContain('server/_expo/functions/(a,b)/multi-group-api+api.js');
expect(getFiles()).not.toContain('server/_expo/functions/(a)/multi-group-api+api.js');
expect(getFiles()).not.toContain('server/_expo/functions/(b)/multi-group-api+api.js');

expect(
await fetch('http://localhost:3000/multi-group-api').then((res) => res.json())
).toEqual({ value: 'multi-group-api-get' });
});

it(`can serve up API route in specific array group`, async () => {
// Should be able to match all the group variations
expect(
await fetch('http://localhost:3000/(a)/multi-group-api').then((res) => res.json())
).toEqual({ value: 'multi-group-api-get' });
expect(
await fetch('http://localhost:3000/(b)/multi-group-api').then((res) => res.json())
).toEqual({ value: 'multi-group-api-get' });
});

it(`can not serve up API route in retained array group syntax`, async () => {
// Should not be able to match the array syntax
expect(
await fetch('http://localhost:3000/(a,b)/multi-group-api').then((res) => res.status)
).toEqual(404);
});

it(
'can use environment variables',
async () => {
Expand Down Expand Up @@ -269,14 +337,7 @@ describe('server-output', () => {
// List output files with sizes for snapshotting.
// This is to make sure that any changes to the output are intentional.
// Posix path formatting is used to make paths the same across OSes.
const files = klawSync(outputDir)
.map((entry) => {
if (entry.path.includes('node_modules') || !entry.stats.isFile()) {
return null;
}
return path.posix.relative(outputDir, entry.path);
})
.filter(Boolean);
const files = getFiles();

// The wrapper should not be included as a route.
expect(files).not.toContain('server/+html.html');
Expand Down

0 comments on commit 3d2157c

Please sign in to comment.