Skip to content

Commit 342782f

Browse files
authored
Fix issue with using non-page files inside pages folders (#733)
(patch)
1 parent a45235e commit 342782f

File tree

7 files changed

+101
-36
lines changed

7 files changed

+101
-36
lines changed

packages/server/src/stages/pages/find-duplicates.test.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,29 @@ import {fullTransformer, findDuplicates, filterBy} from "."
22
import {normalize} from "path"
33

44
test("should filter by path", () => {
5-
expect(fullTransformer(normalize("app/foo/pages/api/bar"))).toBe(normalize("pages/api/bar"))
6-
expect(fullTransformer(normalize("app/foo/api/bar"))).toBe(normalize("pages/api/bar"))
5+
expect(fullTransformer(normalize("app/foo/pages/api/bar.ts"))).toBe(normalize("pages/api/bar.ts"))
6+
expect(fullTransformer(normalize("app/foo/api/bar.ts"))).toBe(normalize("pages/api/bar.ts"))
77

88
const dupes = findDuplicates(
99
[
10-
"app/foo/pages/api/bar",
11-
"app/pages/api/bar",
12-
"app/api/bar",
13-
"pages/bar",
14-
"app/ding/pages/bar",
10+
"app/foo/pages/api/bar.ts",
11+
"app/pages/api/bar.ts",
12+
"app/api/bar.ts",
13+
"pages/bar.ts",
14+
"app/ding/pages/bar.ts",
1515
].map(normalize),
1616
fullTransformer,
1717
)
1818

1919
expect(dupes).toEqual([
20-
["app/foo/pages/api/bar", "app/pages/api/bar", "app/api/bar"].map(normalize),
21-
["pages/bar", "app/ding/pages/bar"].map(normalize),
20+
["app/foo/pages/api/bar.ts", "app/pages/api/bar.ts", "app/api/bar.ts"].map(normalize),
21+
["pages/bar.ts", "app/ding/pages/bar.ts"].map(normalize),
2222
])
2323
expect(filterBy(dupes, "api")).toEqual([
24-
["app/foo/pages/api/bar", "app/pages/api/bar", "app/api/bar"].map(normalize),
24+
["app/foo/pages/api/bar.ts", "app/pages/api/bar.ts", "app/api/bar.ts"].map(normalize),
2525
])
2626
expect(filterBy(dupes, "pages", "api")).toEqual([
27-
["pages/bar", "app/ding/pages/bar"].map(normalize),
27+
["pages/bar.ts", "app/ding/pages/bar.ts"].map(normalize),
2828
])
2929
})
3030

packages/server/src/stages/pages/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {handleErrors, DuplicatePathError} from "./errors"
55
import flow from "lodash/flow"
66

77
export function pagesPathTransformer(path: string) {
8-
const regex = /(?:[\\/]?app[\\/].*?[\\/]?)(pages[\\/].+)$/
8+
const regex = /(?:[\\/]?app[\\/].*?[\\/]?)(pages[\\/].+\.m?[tj]sx?)$/
99
return (regex.exec(path) || [])[1] || path
1010
}
1111

packages/server/src/stages/pages/pages-path-transformer.test.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,36 @@ describe("createPagesPathTransformer", () => {
88
input: normalize("app/users/pages/one/two/three.tsx"),
99
expected: normalize("pages/one/two/three.tsx"),
1010
},
11+
{
12+
name: "Transforms js",
13+
input: normalize("app/users/pages/one/two/three.js"),
14+
expected: normalize("pages/one/two/three.js"),
15+
},
16+
{
17+
name: "Transforms ts",
18+
input: normalize("app/users/pages/one/two/three.ts"),
19+
expected: normalize("pages/one/two/three.ts"),
20+
},
21+
{
22+
name: "Transforms jsx",
23+
input: normalize("app/users/pages/one/two/three.jsx"),
24+
expected: normalize("pages/one/two/three.jsx"),
25+
},
26+
{
27+
name: "Transforms mjs",
28+
input: normalize("app/users/pages/one/two/three.mjs"),
29+
expected: normalize("pages/one/two/three.mjs"),
30+
},
31+
{
32+
name: "Ignores non tjsx paths: css",
33+
input: normalize("app/users/pages/one/two/three.css"),
34+
expected: normalize("app/users/pages/one/two/three.css"),
35+
},
36+
{
37+
name: "Ignores non tjsx paths: scss",
38+
input: normalize("app/users/pages/one/two/three.scss"),
39+
expected: normalize("app/users/pages/one/two/three.scss"),
40+
},
1141
{
1242
name: "handles leading /",
1343
input: normalize("/app/users/pages/one/two/three.tsx"),

packages/server/src/stages/pages/pages.test.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@ function getStreamWithInputCache(entries: string[]) {
1010

1111
describe("createStagePages", () => {
1212
it("should throw an error when there are duplicates", (done) => {
13-
const stream = getStreamWithInputCache([normalize("app/api/foo"), normalize("app/api/foo")])
13+
const stream = getStreamWithInputCache([
14+
normalize("app/api/foo.ts"),
15+
normalize("app/api/foo.ts"),
16+
])
1417
stream.on("error", (err) => {
1518
expect(err.message).toContain("conflicting api routes:")
1619
done()
@@ -22,12 +25,12 @@ describe("createStagePages", () => {
2225

2326
it("should throw an error when there are duplicate pages", (done) => {
2427
const stream = getStreamWithInputCache(
25-
["app/foo/pages/bar", "app/pages/bar", "pages/bar"].map(normalize),
28+
["app/foo/pages/bar.ts", "app/pages/bar.ts", "pages/bar.ts"].map(normalize),
2629
)
2730
stream.on("error", (err) => {
2831
expect(err.message).toContain("conflicting page routes:")
2932
expect(err.paths).toEqual([
30-
["app/foo/pages/bar", "app/pages/bar", "pages/bar"].map(normalize),
33+
["app/foo/pages/bar.ts", "app/pages/bar.ts", "pages/bar.ts"].map(normalize),
3134
])
3235
done()
3336
})
@@ -37,10 +40,12 @@ describe("createStagePages", () => {
3740
})
3841

3942
it("should throw an error when there are duplicate api routes from both in pages and out", (done) => {
40-
const stream = getStreamWithInputCache(["app/pages/api/bar", "app/api/bar"].map(normalize))
43+
const stream = getStreamWithInputCache(
44+
["app/pages/api/bar.ts", "app/api/bar.ts"].map(normalize),
45+
)
4146
stream.on("error", (err: DuplicatePathError) => {
4247
expect(err.message).toContain("conflicting api routes:")
43-
expect(err.paths).toEqual([["app/pages/api/bar", "app/api/bar"].map(normalize)])
48+
expect(err.paths).toEqual([["app/pages/api/bar.ts", "app/api/bar.ts"].map(normalize)])
4449
done()
4550
})
4651

@@ -49,7 +54,9 @@ describe("createStagePages", () => {
4954
})
5055

5156
it("should not throw an error when there are nested api routes", (done) => {
52-
const stream = getStreamWithInputCache(["app/pages/foo/api/bar", "app/api/bar"].map(normalize))
57+
const stream = getStreamWithInputCache(
58+
["app/pages/foo/api/bar.ts", "app/api/bar.ts"].map(normalize),
59+
)
5360
stream.on("error", () => {
5461
expect(true).toBe("This should not have been called")
5562
done()

packages/server/src/stages/relative/index.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,11 @@ const isJavaScriptFile = (filepath: string) => filepath.match(/\.(ts|tsx|js|jsx)
3030

3131
const isInAppFolder = (s: string, cwd: string) => s.replace(cwd + path.sep, "").indexOf("app") === 0
3232

33-
export const patternRelativeImport = /(from\s+(?:['"]))(\.[^'"]+)(['"])/g
33+
export const patternRelativeImportSingle = /(import\s(?:{[^}]*})?.*(?=(?:['"])(?:\.[^'"]+)(?:['"]))(?:['"]))(\.[^'"]+)(['"])/
34+
export const patternRelativeImportGlobal = new RegExp(patternRelativeImportSingle, "g")
3435

3536
export function replaceRelativeImports(content: string, replacer: (s: string) => string) {
36-
return content.replace(patternRelativeImport, (...args) => {
37+
return content.replace(patternRelativeImportGlobal, (...args) => {
3738
const [, start, importPath, end] = args
3839
return [start, replacer(importPath), end].join("")
3940
})
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import {patternRelativeImportSingle} from "."
2+
describe("patternRelativeImport", () => {
3+
it("matches an import statement", () => {
4+
const matches = `import from "./bar/baz"`.match(patternRelativeImportSingle)
5+
6+
expect(matches && matches[2]).toEqual("./bar/baz")
7+
})
8+
9+
it("matches a multiline import statement", () => {
10+
const input = `import {
11+
foo,
12+
bar
13+
} from "./ding"`
14+
const matches = input.match(patternRelativeImportSingle)
15+
16+
expect(matches && matches[2]).toEqual("./ding")
17+
})
18+
19+
it("matches an import statement with no specifier", () => {
20+
const input = `import from "./ding"`
21+
const matches = input.match(patternRelativeImportSingle)
22+
23+
expect(matches && matches[2]).toEqual("./ding")
24+
})
25+
})

packages/server/src/stages/relative/relative.test.ts

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,53 +9,55 @@ describe("relative", () => {
99
{
1010
path: normalize("/projects/blitz/blitz/app/users/pages.ts"),
1111
contents: `import {getFoo} from 'app/foo/bar';
12-
import from "app/thing/bar"
13-
import from 'app/thing/bar'`,
12+
import from "app/thing/bar"
13+
import from 'app/thing/bar'
14+
import 'app/thing/bar'`,
1415
},
1516
{
1617
path: normalize("/projects/blitz/blitz/app/users/foo.jpeg"),
1718
contents: `import {getFoo} from 'app/foo/bar';
18-
import from "../thing/bar"
19-
import from '../thing/bar'`,
19+
import from "../thing/bar"
20+
import from '../thing/bar'`,
2021
},
2122
{
2223
path: normalize("/projects/blitz/blitz/app/users/bar.tsx"),
2324
contents: `import {getFoo} from 'app/foo/bar';
24-
import from "app/thing/bar"
25-
import from 'app/thing/bar'`,
25+
import from "app/thing/bar"
26+
import from 'app/thing/bar'`,
2627
},
2728
{
2829
path: normalize("/projects/blitz/blitz/app/users/baz.js"),
2930
contents: `import {getFoo} from 'app/foo/bar';
30-
import from "app/thing/bar"
31-
import from 'app/thing/bar'`,
31+
import from "app/thing/bar"
32+
import from 'app/thing/bar'`,
3233
},
3334
]
3435

3536
const files = [
3637
{
3738
path: normalize("/projects/blitz/blitz/app/users/pages.ts"),
3839
contents: `import {getFoo} from 'app/foo/bar';
39-
import from "../thing/bar"
40-
import from '../thing/bar'`,
40+
import from "../thing/bar"
41+
import from '../thing/bar'
42+
import '../thing/bar'`,
4143
},
4244
{
4345
path: normalize("/projects/blitz/blitz/app/users/foo.jpeg"),
4446
contents: `import {getFoo} from 'app/foo/bar';
45-
import from "../thing/bar"
46-
import from '../thing/bar'`,
47+
import from "../thing/bar"
48+
import from '../thing/bar'`,
4749
},
4850
{
4951
path: normalize("/projects/blitz/blitz/app/users/bar.tsx"),
5052
contents: `import {getFoo} from 'app/foo/bar';
51-
import from "../thing/bar"
52-
import from '../thing/bar'`,
53+
import from "../thing/bar"
54+
import from '../thing/bar'`,
5355
},
5456
{
5557
path: normalize("/projects/blitz/blitz/app/users/baz.js"),
5658
contents: `import {getFoo} from 'app/foo/bar';
57-
import from "../thing/bar"
58-
import from '../thing/bar'`,
59+
import from "../thing/bar"
60+
import from '../thing/bar'`,
5961
},
6062
]
6163
const {stream} = createStageRelative(mockStageArgs({cwd: normalize("/projects/blitz/blitz")}))

0 commit comments

Comments
 (0)