Skip to content

Commit

Permalink
Preserve next-env.d.ts line ending (vercel#28100)
Browse files Browse the repository at this point in the history
* Preserve `next-env.d.ts` line ending

Prevent next from changing already existing line ending on
`next-env.d.ts` for no good reason

* Update comparison

Co-authored-by: Steven <[email protected]>

* Update checks and add tests

* update test

Co-authored-by: Steven <[email protected]>
Co-authored-by: [email protected] <[email protected]>
  • Loading branch information
3 people authored Sep 20, 2021
1 parent 05a732e commit 23ce41e
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 14 deletions.
41 changes: 27 additions & 14 deletions packages/next/lib/typescript/writeAppTypeDeclarations.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { promises as fs } from 'fs'
import os from 'os'
import path from 'path'
import { fileExists } from '../file-exists'
import { promises as fs } from 'fs'

export async function writeAppTypeDeclarations(
baseDir: string,
Expand All @@ -10,27 +9,41 @@ export async function writeAppTypeDeclarations(
// Reference `next` types
const appTypeDeclarations = path.join(baseDir, 'next-env.d.ts')

// Defaults EOL to system default
let eol = os.EOL
let currentContent: string | undefined

try {
currentContent = await fs.readFile(appTypeDeclarations, 'utf8')
// If file already exists then preserve its line ending
const lf = currentContent.indexOf('\n', /* skip first so we can lf - 1 */ 1)

if (lf !== -1) {
if (currentContent[lf - 1] === '\r') {
eol = '\r\n'
} else {
eol = '\n'
}
}
} catch (err) {}

const content =
'/// <reference types="next" />' +
os.EOL +
eol +
'/// <reference types="next/types/global" />' +
os.EOL +
eol +
(imageImportsEnabled
? '/// <reference types="next/image-types/global" />' + os.EOL
? '/// <reference types="next/image-types/global" />' + eol
: '') +
os.EOL +
eol +
'// NOTE: This file should not be edited' +
os.EOL +
eol +
'// see https://nextjs.org/docs/basic-features/typescript for more information.' +
os.EOL
eol

// Avoids a write for read-only filesystems
if (
(await fileExists(appTypeDeclarations)) &&
(await fs.readFile(appTypeDeclarations, 'utf8')) === content
) {
// Avoids an un-necessary write on read-only fs
if (currentContent === content) {
return
}

await fs.writeFile(appTypeDeclarations, content)
}
80 changes: 80 additions & 0 deletions test/unit/write-app-declarations.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/* eslint-env jest */
import os from 'os'
import fs from 'fs-extra'
import { join } from 'path'
import { writeAppTypeDeclarations } from 'next/dist/lib/typescript/writeAppTypeDeclarations'

const fixtureDir = join(__dirname, 'fixtures/app-declarations')
const declarationFile = join(fixtureDir, 'next-env.d.ts')
const imageImportsEnabled = false

describe('find config', () => {
afterEach(() => fs.remove(declarationFile))

it('should preserve CRLF EOL', async () => {
const eol = '\r\n'
const content =
'/// <reference types="next" />' +
eol +
'/// <reference types="next/types/global" />' +
eol +
(imageImportsEnabled
? '/// <reference types="next/image-types/global" />' + eol
: '') +
eol +
'// NOTE: This file should not be edited' +
eol +
'// see https://nextjs.org/docs/basic-features/typescript for more information.' +
eol

await fs.ensureDir(fixtureDir)
await fs.writeFile(declarationFile, content)

await writeAppTypeDeclarations(fixtureDir, imageImportsEnabled)
expect(await fs.readFile(declarationFile, 'utf8')).toBe(content)
})

it('should preserve LF EOL', async () => {
const eol = '\n'
const content =
'/// <reference types="next" />' +
eol +
'/// <reference types="next/types/global" />' +
eol +
(imageImportsEnabled
? '/// <reference types="next/image-types/global" />' + eol
: '') +
eol +
'// NOTE: This file should not be edited' +
eol +
'// see https://nextjs.org/docs/basic-features/typescript for more information.' +
eol

await fs.ensureDir(fixtureDir)
await fs.writeFile(declarationFile, content)

await writeAppTypeDeclarations(fixtureDir, imageImportsEnabled)
expect(await fs.readFile(declarationFile, 'utf8')).toBe(content)
})

it('should use OS EOL by default', async () => {
const eol = os.EOL
const content =
'/// <reference types="next" />' +
eol +
'/// <reference types="next/types/global" />' +
eol +
(imageImportsEnabled
? '/// <reference types="next/image-types/global" />' + eol
: '') +
eol +
'// NOTE: This file should not be edited' +
eol +
'// see https://nextjs.org/docs/basic-features/typescript for more information.' +
eol

await fs.ensureDir(fixtureDir)
await writeAppTypeDeclarations(fixtureDir, imageImportsEnabled)
expect(await fs.readFile(declarationFile, 'utf8')).toBe(content)
})
})

0 comments on commit 23ce41e

Please sign in to comment.