diff --git a/core/dev-test/index.html b/core/dev-test/index.html index f539dd1a..a5c8ee28 100644 --- a/core/dev-test/index.html +++ b/core/dev-test/index.html @@ -15,6 +15,10 @@ content: '{\n"title": "This is a JSON front matter post",\n"image": "/nf-logo.png",\n"date": "2015-02-15T00:00:00.000Z"\n}\n\n# I Am a Title in Markdown\n\nHello, world\n\n* One Thing\n* Another Thing\n* A Third Thing\n', }, + '2015-02-16-this-is-a-toml-frontmatter-post.md': { + content: + '+++\ntitle = "This is a TOML front matter post"\nimage = "/nf-logo.png"\n"date" = "2015-02-16T00:00:00.000Z"\n+++\n\n# I Am a Title in Markdown\n\nHello, world\n\n* One Thing\n* Another Thing\n* A Third Thing\n', + }, '2015-02-14-this-is-a-post-with-a-different-extension.other': { content: '---\ntitle: This post should not appear because the extension is different\nimage: /nf-logo.png\ndate: 2015-02-14T00:00:00.000Z\n---\n\n# I Am a Title in Markdown\n\nHello, world\n\n* One Thing\n* Another Thing\n* A Third Thing\n', diff --git a/core/package.json b/core/package.json index a9c76346..3d30a41e 100644 --- a/core/package.json +++ b/core/package.json @@ -1,6 +1,6 @@ { "name": "@staticcms/core", - "version": "1.0.0-beta1", + "version": "1.0.0-beta2", "license": "MIT", "description": "Static CMS core application.", "repository": "https://github.com/StaticJsCMS/static-cms", @@ -45,6 +45,7 @@ "@emotion/css": "11.10.0", "@emotion/react": "11.10.4", "@emotion/styled": "11.10.4", + "@ltd/j-toml": "1.35.2", "@mui/icons-material": "5.10.6", "@mui/material": "5.10.10", "@mui/system": "5.4.1", diff --git a/core/src/backends/test/implementation.ts b/core/src/backends/test/implementation.ts index df8648d3..2ec094e8 100644 --- a/core/src/backends/test/implementation.ts +++ b/core/src/backends/test/implementation.ts @@ -283,7 +283,14 @@ export default class TestBackend implements BackendClass { extension: string, depth: number, ): Promise { - return this.entriesByFolder(folder, extension, depth); + const files = folder ? getFolderFiles(window.repoFiles, folder, extension, depth) : []; + + const entries = files.map(f => ({ + data: f.content as string, + file: { path: f.path, id: f.path }, + })); + + return Promise.resolve(entries); } getMediaDisplayURL(_displayURL: DisplayURL): Promise { diff --git a/core/src/formats/TomlFormatter.ts b/core/src/formats/TomlFormatter.ts new file mode 100644 index 00000000..7373573b --- /dev/null +++ b/core/src/formats/TomlFormatter.ts @@ -0,0 +1,18 @@ +import toml from '@ltd/j-toml'; + +import { FileFormatter } from './FileFormatter'; + +class TomlFormatter extends FileFormatter { + fromFile(content: string) { + return toml.parse(content) as object; + } + + toFile(data: object): string { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + return toml.stringify(data as any, { + newline: '\n', + }); + } +} + +export default new TomlFormatter(); diff --git a/core/src/formats/formats.ts b/core/src/formats/formats.ts index 44ce6153..d64acc05 100644 --- a/core/src/formats/formats.ts +++ b/core/src/formats/formats.ts @@ -1,25 +1,29 @@ import YamlFormatter from './YamlFormatter'; +import TomlFormatter from './TomlFormatter'; import JsonFormatter from './JsonFormatter'; -import { FrontmatterInfer, frontmatterJSON, frontmatterYAML } from './frontmatter'; +import { FrontmatterInfer, frontmatterJSON, frontmatterTOML, frontmatterYAML } from './frontmatter'; import type { Delimiter } from './frontmatter'; import type { Collection, Entry, Format } from '../interface'; import type { FileFormatter } from './FileFormatter'; -export const frontmatterFormats = ['yaml-frontmatter', 'json-frontmatter']; +export const frontmatterFormats = ['yaml-frontmatter', 'toml-frontmatter', 'json-frontmatter']; export const formatExtensions = { yml: 'yml', yaml: 'yml', + toml: 'toml', json: 'json', frontmatter: 'md', 'json-frontmatter': 'md', + 'toml-frontmatter': 'md', 'yaml-frontmatter': 'md', }; export const extensionFormatters: Record = { yml: YamlFormatter, yaml: YamlFormatter, + toml: TomlFormatter, json: JsonFormatter, md: FrontmatterInfer, markdown: FrontmatterInfer, @@ -30,9 +34,11 @@ function formatByName(name: Format, customDelimiter?: Delimiter): FileFormatter const fileFormatter: Record = { yml: YamlFormatter, yaml: YamlFormatter, + toml: TomlFormatter, json: JsonFormatter, frontmatter: FrontmatterInfer, 'json-frontmatter': frontmatterJSON(customDelimiter), + 'toml-frontmatter': frontmatterTOML(customDelimiter), 'yaml-frontmatter': frontmatterYAML(customDelimiter), }; diff --git a/core/src/formats/frontmatter.ts b/core/src/formats/frontmatter.ts index 525510fa..805a85ba 100644 --- a/core/src/formats/frontmatter.ts +++ b/core/src/formats/frontmatter.ts @@ -1,11 +1,13 @@ import matter from 'gray-matter'; import YamlFormatter from './YamlFormatter'; +import TomlFormatter from './TomlFormatter'; import JsonFormatter from './JsonFormatter'; import { FileFormatter } from './FileFormatter'; const Languages = { YAML: 'yaml', + TOML: 'toml', JSON: 'json', } as const; @@ -15,6 +17,12 @@ export type Delimiter = string | [string, string]; type Format = { language: Language; delimiters: Delimiter }; const parsers = { + toml: { + parse: (input: string) => TomlFormatter.fromFile(input), + stringify: (metadata: object) => { + return TomlFormatter.toFile(metadata); + }, + }, json: { parse: (input: string) => { let JSONinput = input.trim(); @@ -54,6 +62,8 @@ function inferFrontmatterFormat(str: string) { switch (firstLine) { case '---': return getFormatOpts(Languages.YAML); + case '+++': + return getFormatOpts(Languages.TOML); case '{': return getFormatOpts(Languages.JSON); default: @@ -68,6 +78,7 @@ export function getFormatOpts(format?: Language, customDelimiter?: Delimiter) { const formats: { [key in Language]: Format } = { yaml: { language: Languages.YAML, delimiters: '---' }, + toml: { language: Languages.TOML, delimiters: '+++' }, json: { language: Languages.JSON, delimiters: ['{', '}'] }, }; @@ -126,6 +137,10 @@ export class FrontmatterFormatter extends FileFormatter { export const FrontmatterInfer = new FrontmatterFormatter(); +export function frontmatterTOML(customDelimiter?: Delimiter) { + return new FrontmatterFormatter(Languages.TOML, customDelimiter); +} + export function frontmatterYAML(customDelimiter?: Delimiter) { return new FrontmatterFormatter(Languages.YAML, customDelimiter); } diff --git a/core/yarn.lock b/core/yarn.lock index 5f2e1ce6..3073a398 100644 --- a/core/yarn.lock +++ b/core/yarn.lock @@ -1614,6 +1614,11 @@ resolved "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz" integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A== +"@ltd/j-toml@1.35.2": + version "1.35.2" + resolved "https://registry.yarnpkg.com/@ltd/j-toml/-/j-toml-1.35.2.tgz#bd3532c9db4cb7d585d492b3eaf5f33c57981a9e" + integrity sha512-vhRlbbbp61PE/209BO14wRvgldF34lplcmVaNZnKU2QRwOfc+0NhD3S0hdMBRw1d3cvU9EC67tuV7MNRiVDNyg== + "@mapbox/jsonlint-lines-primitives@~2.0.2": version "2.0.2" resolved "https://registry.npmjs.org/@mapbox/jsonlint-lines-primitives/-/jsonlint-lines-primitives-2.0.2.tgz"