Skip to content

Commit

Permalink
fix(std/json): Add newline at the end of json files (denoland#6885)
Browse files Browse the repository at this point in the history
  • Loading branch information
tranzystorekk committed Jul 26, 2020
1 parent 3b7fdd6 commit 7326e1a
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 37 deletions.
8 changes: 7 additions & 1 deletion std/fs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,18 +133,24 @@ const foo = readJsonSync("./foo.json");

Writes an object to a JSON file.

**WriteJsonOptions**
#### WriteJsonOptions

- replacer : An array of strings and numbers that acts as a approved list for
selecting the object properties that will be stringified.
- space : Adds indentation, white space, and line break characters to the
return-value JSON text to make it easier to read.

You can also specify options from `Deno.WriteFileOptions` to configure how the
file is written.

```ts
import { writeJson, writeJsonSync } from "https://deno.land/std/fs/mod.ts";

writeJson("./target.dat", { foo: "bar" }, { spaces: 2 }); // returns a promise
writeJsonSync("./target.dat", { foo: "bar" }, { replacer: ["foo"] }); // void

// appends to the file instead of rewriting
writeJsonSync("./target.dat", { foo: "bar" }, { append: true });
```

### walk
Expand Down
51 changes: 27 additions & 24 deletions std/fs/write_json.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,43 @@
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type Replacer = (key: string, value: any) => any;

export interface WriteJsonOptions {
spaces?: number | string;
export interface WriteJsonOptions extends Deno.WriteFileOptions {
replacer?: Array<number | string> | Replacer;
spaces?: number | string;
}

/* Writes an object to a JSON file. */
export async function writeJson(
function serialize(
filePath: string,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
object: any,
options: WriteJsonOptions = {},
): Promise<void> {
let contentRaw = "";

options: WriteJsonOptions,
): string {
try {
contentRaw = JSON.stringify(
const jsonString = JSON.stringify(
object,
options.replacer as string[],
options.spaces,
);
return `${jsonString}\n`;
} catch (err) {
err.message = `${filePath}: ${err.message}`;
throw err;
}
}

await Deno.writeFile(filePath, new TextEncoder().encode(contentRaw));
/* Writes an object to a JSON file. */
export async function writeJson(
filePath: string,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
object: any,
options: WriteJsonOptions = {},
): Promise<void> {
const jsonString = serialize(filePath, object, options);
await Deno.writeTextFile(filePath, jsonString, {
append: options.append,
create: options.create,
mode: options.mode,
});
}

/* Writes an object to a JSON file. */
Expand All @@ -37,18 +48,10 @@ export function writeJsonSync(
object: any,
options: WriteJsonOptions = {},
): void {
let contentRaw = "";

try {
contentRaw = JSON.stringify(
object,
options.replacer as string[],
options.spaces,
);
} catch (err) {
err.message = `${filePath}: ${err.message}`;
throw err;
}

Deno.writeFileSync(filePath, new TextEncoder().encode(contentRaw));
const jsonString = serialize(filePath, object, options);
Deno.writeTextFileSync(filePath, jsonString, {
append: options.append,
create: options.create,
mode: options.mode,
});
}
24 changes: 12 additions & 12 deletions std/fs/write_json_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Deno.test("writeJsonIfNotExists", async function (): Promise<void> {

await Deno.remove(notExistsJsonFile);

assertEquals(new TextDecoder().decode(content), `{"a":"1"}`);
assertEquals(new TextDecoder().decode(content), `{"a":"1"}\n`);
});

Deno.test("writeJsonIfExists", async function (): Promise<void> {
Expand All @@ -46,7 +46,7 @@ Deno.test("writeJsonIfExists", async function (): Promise<void> {

await Deno.remove(existsJsonFile);

assertEquals(new TextDecoder().decode(content), `{"a":"1"}`);
assertEquals(new TextDecoder().decode(content), `{"a":"1"}\n`);
});

Deno.test("writeJsonIfExistsAnInvalidJson", async function (): Promise<void> {
Expand All @@ -71,7 +71,7 @@ Deno.test("writeJsonIfExistsAnInvalidJson", async function (): Promise<void> {

await Deno.remove(existsInvalidJsonFile);

assertEquals(new TextDecoder().decode(content), `{"a":"1"}`);
assertEquals(new TextDecoder().decode(content), `{"a":"1"}\n`);
});

Deno.test("writeJsonWithSpaces", async function (): Promise<void> {
Expand All @@ -93,7 +93,7 @@ Deno.test("writeJsonWithSpaces", async function (): Promise<void> {

await Deno.remove(existsJsonFile);

assertEquals(new TextDecoder().decode(content), `{\n "a": "1"\n}`);
assertEquals(new TextDecoder().decode(content), `{\n "a": "1"\n}\n`);
});

Deno.test("writeJsonWithReplacer", async function (): Promise<void> {
Expand Down Expand Up @@ -121,7 +121,7 @@ Deno.test("writeJsonWithReplacer", async function (): Promise<void> {

await Deno.remove(existsJsonFile);

assertEquals(new TextDecoder().decode(content), `{"a":"1"}`);
assertEquals(new TextDecoder().decode(content), `{"a":"1"}\n`);
});

Deno.test("writeJsonSyncIfNotExists", function (): void {
Expand All @@ -140,7 +140,7 @@ Deno.test("writeJsonSyncIfNotExists", function (): void {

Deno.removeSync(notExistsJsonFile);

assertEquals(new TextDecoder().decode(content), `{"a":"1"}`);
assertEquals(new TextDecoder().decode(content), `{"a":"1"}\n`);
});

Deno.test("writeJsonSyncIfExists", function (): void {
Expand All @@ -161,7 +161,7 @@ Deno.test("writeJsonSyncIfExists", function (): void {

Deno.removeSync(existsJsonFile);

assertEquals(new TextDecoder().decode(content), `{"a":"1"}`);
assertEquals(new TextDecoder().decode(content), `{"a":"1"}\n`);
});

Deno.test("writeJsonSyncIfExistsAnInvalidJson", function (): void {
Expand All @@ -186,10 +186,10 @@ Deno.test("writeJsonSyncIfExistsAnInvalidJson", function (): void {

Deno.removeSync(existsInvalidJsonFile);

assertEquals(new TextDecoder().decode(content), `{"a":"1"}`);
assertEquals(new TextDecoder().decode(content), `{"a":"1"}\n`);
});

Deno.test("writeJsonWithSpaces", function (): void {
Deno.test("writeJsonSyncWithSpaces", function (): void {
const existsJsonFile = path.join(testdataDir, "file_write_spaces_sync.json");

const invalidJsonContent = new TextEncoder().encode();
Expand All @@ -208,10 +208,10 @@ Deno.test("writeJsonWithSpaces", function (): void {

Deno.removeSync(existsJsonFile);

assertEquals(new TextDecoder().decode(content), `{\n "a": "1"\n}`);
assertEquals(new TextDecoder().decode(content), `{\n "a": "1"\n}\n`);
});

Deno.test("writeJsonWithReplacer", function (): void {
Deno.test("writeJsonSyncWithReplacer", function (): void {
const existsJsonFile = path.join(
testdataDir,
"file_write_replacer_sync.json",
Expand Down Expand Up @@ -239,5 +239,5 @@ Deno.test("writeJsonWithReplacer", function (): void {

Deno.removeSync(existsJsonFile);

assertEquals(new TextDecoder().decode(content), `{"a":"1"}`);
assertEquals(new TextDecoder().decode(content), `{"a":"1"}\n`);
});

0 comments on commit 7326e1a

Please sign in to comment.