import { DateTime } from 'luxon'; import { Config } from '../conf'; import { build_env_scope } from '../env'; import { load_themes } from '../themes'; import { load_extras } from '../template'; import { Metadata } from '../metadata'; import { hash_obj } from '../hash'; import { BuildState } from './state'; import { read_json, with_default_if_missing, write_json } from '../fs'; import { copy_raw_files } from './raw'; import { render_text_file_templates } from './mustache'; import { render_markdown_files } from './markdown'; import { render_json_schema_files } from './jsonschema'; import { write_sitemap_if_needed } from './sitemap'; import { write_rss_if_needed } from './rss'; import { write_events_and_calendars_if_needed } from './icalendar'; import { as_context_time, as_html_time } from '../time'; export { BuildState, ThemeGroups } from './state'; export async function build_docs_project(conf: Config) { const now = DateTime.now(); const conf_hash = hash_obj(conf); const themes = await load_themes(conf); const get_metadata = read_json(conf.metadata, false).then(({ parsed }) => parsed); const metadata = await with_default_if_missing(get_metadata, { last_build: null, files: { }, }); const state: BuildState = { conf, seen_files: new Set(), env: build_env_scope(conf), layouts: Object.create(null), themes: themes, theme_groups: { all: Object.values(themes), light: [ ], dark: [ ], high_contrast: [ ], low_contrast: [ ], monochrome: [ ], greyscale: [ ], protanopia_safe: [ ], deuteranopia_safe: [ ], tritanopia_safe: [ ], }, old_metadata: metadata, new_metadata: { last_build: { time: now.toISO(), config_hash: conf_hash, }, files: { } }, extras: await load_extras(), made_directories: new Set(), rss: [ ], sitemap: [ ], events: [ ], event_series: [ ], calendars: [ ], build_time: as_context_time(now), }; for (const theme of Object.values(themes)) { for (const label of theme.labels) { state.theme_groups[label].push(theme); } } if (conf.input.raw) { await copy_raw_files(state); } if (conf.input.text) { await render_text_file_templates(state); } if (conf.input.markdown) { await render_markdown_files(state); } if (conf.input['schema+json'] || conf.input['schema+yaml']) { await render_json_schema_files(state); } // todo: other file types... await write_sitemap_if_needed(state); await write_rss_if_needed(state); await write_events_and_calendars_if_needed(state); // Write the updated metadata file await write_json(conf.metadata, state.new_metadata, true); }