add template in hard
Some checks failed
Build Docker Image Front / run (pull_request) Failing after 52s
Build Docker Image Back / run (pull_request) Successful in 25s
JsDocs / coverage (pull_request) Successful in 22s
Test and coverage / coverage (pull_request) Successful in 1m26s

This commit is contained in:
2024-05-20 12:23:41 +02:00
parent 738381ee16
commit 99196c6dba
128 changed files with 15138 additions and 4873 deletions

114
front/vendor/integration/index.mjs vendored Normal file
View File

@ -0,0 +1,114 @@
import fs from 'node:fs';
import os from 'node:os';
import configBuilder from './utils/configBuilder';
import loadConfig from './utils/loadConfig';
export default ({ config: _themeConfig = 'src/config.yaml' } = {}) => {
let cfg;
return {
name: 'astrowind-integration',
hooks: {
'astro:config:setup': async ({
// command,
config,
// injectRoute,
// isRestart,
logger,
updateConfig,
addWatchFile,
}) => {
const buildLogger = logger.fork('astrowind');
const virtualModuleId = 'astrowind:config';
const resolvedVirtualModuleId = '\0' + virtualModuleId;
const rawJsonConfig = await loadConfig(_themeConfig);
const { SITE, I18N, METADATA, APP_BLOG, UI, ANALYTICS } = configBuilder(rawJsonConfig);
updateConfig({
site: SITE.site,
base: SITE.base,
trailingSlash: SITE.trailingSlash ? 'always' : 'never',
vite: {
plugins: [
{
name: 'vite-plugin-astrowind-config',
resolveId(id) {
if (id === virtualModuleId) {
return resolvedVirtualModuleId;
}
},
load(id) {
if (id === resolvedVirtualModuleId) {
return `
export const SITE = ${JSON.stringify(SITE)};
export const I18N = ${JSON.stringify(I18N)};
export const METADATA = ${JSON.stringify(METADATA)};
export const APP_BLOG = ${JSON.stringify(APP_BLOG)};
export const UI = ${JSON.stringify(UI)};
export const ANALYTICS = ${JSON.stringify(ANALYTICS)};
`;
}
},
},
],
},
});
if (typeof _themeConfig === 'string') {
addWatchFile(new URL(_themeConfig, config.root));
buildLogger.info(`Astrowind \`${_themeConfig}\` has been loaded.`);
} else {
buildLogger.info(`Astrowind config has been loaded.`);
}
},
'astro:config:done': async ({ config }) => {
cfg = config;
},
'astro:build:done': async ({ logger }) => {
const buildLogger = logger.fork('astrowind');
buildLogger.info('Updating `robots.txt` with `sitemap-index.xml` ...');
try {
const outDir = cfg.outDir;
const publicDir = cfg.publicDir;
const sitemapName = 'sitemap-index.xml';
const sitemapFile = new URL(sitemapName, outDir);
const robotsTxtFile = new URL('robots.txt', publicDir);
const robotsTxtFileInOut = new URL('robots.txt', outDir);
const hasIntegration =
Array.isArray(cfg?.integrations) &&
cfg.integrations?.find((e) => e?.name === '@astrojs/sitemap') !== undefined;
const sitemapExists = fs.existsSync(sitemapFile);
if (hasIntegration && sitemapExists) {
const robotsTxt = fs.readFileSync(robotsTxtFile, { encoding: 'utf8', flags: 'a+' });
const sitemapUrl = new URL(sitemapName, String(new URL(cfg.base, cfg.site)));
const pattern = /^Sitemap:(.*)$/m;
if (!pattern.test(robotsTxt)) {
fs.appendFileSync(robotsTxtFileInOut, `${os.EOL}${os.EOL}Sitemap: ${sitemapUrl}`, {
encoding: 'utf8',
flags: 'w',
});
} else {
fs.writeFileSync(robotsTxtFileInOut, robotsTxt.replace(pattern, `Sitemap: ${sitemapUrl}`), {
encoding: 'utf8',
flags: 'w',
});
}
}
} catch (err) {
/* empty */
}
},
},
};
};

10
front/vendor/integration/types.d.ts vendored Normal file
View File

@ -0,0 +1,10 @@
declare module 'astrowind:config' {
import type { SiteConfig, I18NConfig, MetaDataConfig, AppBlogConfig, UIConfig, AnalyticsConfig } from './config';
export const SITE: SiteConfig;
export const I18N: I18NConfig;
export const METADATA: MetaDataConfig;
export const APP_BLOG: AppBlogConfig;
export const UI: UIConfig;
export const ANALYTICS: AnalyticsConfig;
}

View File

@ -0,0 +1,201 @@
import merge from 'lodash.merge';
import type { MetaData } from '~/types';
type Config = {
site?: SiteConfig;
metadata?: MetaDataConfig;
i18n?: I18NConfig;
apps?: {
blog?: AppBlogConfig;
};
ui?: unknown;
analytics?: unknown;
};
export interface SiteConfig {
name: string;
site?: string;
base?: string;
trailingSlash?: boolean;
googleSiteVerificationId?: string;
}
export interface MetaDataConfig extends Omit<MetaData, 'title'> {
title?: {
default: string;
template: string;
};
}
export interface I18NConfig {
language: string;
textDirection: string;
dateFormatter?: Intl.DateTimeFormat;
}
export interface AppBlogConfig {
isEnabled: boolean;
postsPerPage: number;
isRelatedPostsEnabled: boolean;
relatedPostsCount: number;
post: {
isEnabled: boolean;
permalink: string;
robots: {
index: boolean;
follow: boolean;
};
};
list: {
isEnabled: boolean;
pathname: string;
robots: {
index: boolean;
follow: boolean;
};
};
category: {
isEnabled: boolean;
pathname: string;
robots: {
index: boolean;
follow: boolean;
};
};
tag: {
isEnabled: boolean;
pathname: string;
robots: {
index: boolean;
follow: boolean;
};
};
}
export interface AnalyticsConfig {
vendors: {
googleAnalytics: {
id?: string;
partytown?: boolean;
};
};
}
export interface UIConfig {}
const DEFAULT_SITE_NAME = 'Website';
const getSite = (config: Config) => {
const _default = {
name: DEFAULT_SITE_NAME,
site: undefined,
base: '/',
trailingSlash: false,
googleSiteVerificationId: '',
};
return merge({}, _default, config?.site ?? {}) as SiteConfig;
};
const getMetadata = (config: Config) => {
const siteConfig = getSite(config);
const _default = {
title: {
default: siteConfig?.name || DEFAULT_SITE_NAME,
template: '%s',
},
description: '',
robots: {
index: false,
follow: false,
},
openGraph: {
type: 'website',
},
};
return merge({}, _default, config?.metadata ?? {}) as MetaDataConfig;
};
const getI18N = (config: Config) => {
const _default = {
language: 'en',
textDirection: 'ltr',
};
const value = merge({}, _default, config?.i18n ?? {});
return value as I18NConfig;
};
const getAppBlog = (config: Config) => {
const _default = {
isEnabled: false,
postsPerPage: 6,
isRelatedPostsEnabled: false,
relatedPostsCount: 4,
post: {
isEnabled: true,
permalink: '/blog/%slug%',
robots: {
index: true,
follow: true,
},
},
list: {
isEnabled: true,
pathname: 'blog',
robots: {
index: true,
follow: true,
},
},
category: {
isEnabled: true,
pathname: 'category',
robots: {
index: true,
follow: true,
},
},
tag: {
isEnabled: true,
pathname: 'tag',
robots: {
index: false,
follow: true,
},
},
};
return merge({}, _default, config?.apps?.blog ?? {}) as AppBlogConfig;
};
const getUI = (config: Config) => {
const _default = {
theme: 'system',
};
return merge({}, _default, config?.ui ?? {});
};
const getAnalytics = (config: Config) => {
const _default = {
vendors: {
googleAnalytics: {
id: undefined,
partytown: true,
},
},
};
return merge({}, _default, config?.analytics ?? {}) as AnalyticsConfig;
};
export default (config: Config) => ({
SITE: getSite(config),
I18N: getI18N(config),
METADATA: getMetadata(config),
APP_BLOG: getAppBlog(config),
UI: getUI(config),
ANALYTICS: getAnalytics(config),
});

View File

@ -0,0 +1,16 @@
import fs from 'node:fs';
import yaml from 'js-yaml';
const loadConfig = async (configPathOrData: string | object) => {
if (typeof configPathOrData === 'string') {
const content = fs.readFileSync(configPathOrData, 'utf8');
if (configPathOrData.endsWith('.yaml') || configPathOrData.endsWith('.yml')) {
return yaml.load(content);
}
return content;
}
return configPathOrData;
};
export default loadConfig;