forked from onwidget/astrowind
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Create local integration for load config.yaml and more
- Loading branch information
Showing
5 changed files
with
358 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
This folder will become an integration for **AstroWind**. | ||
|
||
We are working to allow updates to template instances. | ||
These are changes on the way to new **AstroWind v2** |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
import fs from 'node:fs'; | ||
import os from 'node:os'; | ||
|
||
import yaml from 'js-yaml'; | ||
|
||
import configBuilder from "./utils/configBuilder" | ||
|
||
const tasksIntegration = () => { | ||
let config; | ||
return { | ||
name: 'AstroWind:tasks', | ||
|
||
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 fileConfig = yaml.load(fs.readFileSync('src/config.yaml', 'utf8')); | ||
const { SITE, I18N, METADATA, APP_BLOG, UI, ANALYTICS } = configBuilder(fileConfig); | ||
|
||
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)}; | ||
`; | ||
} | ||
}, | ||
}, | ||
], | ||
}, | ||
}); | ||
|
||
addWatchFile(new URL('./src/config.yaml', config.root)); | ||
|
||
buildLogger.info("Astrowind `src/config.yaml` has been loaded.") | ||
}, | ||
'astro:config:done': async ({ config: cfg }) => { | ||
config = cfg; | ||
}, | ||
|
||
'astro:build:done': async ({ logger }) => { | ||
|
||
const buildLogger = logger.fork("astrowind"); | ||
buildLogger.info("Updating `robots.txt` with `sitemap-index.xml` ...") | ||
|
||
try { | ||
const outDir = config.outDir; | ||
const publicDir = config.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(config?.integrations) && | ||
config.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(config.base, config.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 */ | ||
} | ||
}, | ||
}, | ||
}; | ||
}; | ||
|
||
export default tasksIntegration; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,228 @@ | ||
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', | ||
classes: {}, | ||
tokens: { | ||
default: { | ||
fonts: {}, | ||
colors: { | ||
default: 'rgb(16 16 16)', | ||
heading: 'rgb(0 0 0)', | ||
muted: 'rgb(16 16 16 / 66%)', | ||
bgPage: 'rgb(255 255 255)', | ||
primary: 'rgb(1 97 239)', | ||
secondary: 'rgb(1 84 207)', | ||
accent: 'rgb(109 40 217)', | ||
}, | ||
}, | ||
dark: { | ||
fonts: {}, | ||
colors: { | ||
default: 'rgb(229 236 246)', | ||
heading: 'rgb(247, 248, 248)', | ||
muted: 'rgb(229 236 246 / 66%)', | ||
bgPage: 'rgb(3 6 32)', | ||
primary: 'rgb(1 97 239)', | ||
secondary: 'rgb(1 84 207)', | ||
accent: 'rgb(109 40 217)', | ||
}, | ||
}, | ||
}, | ||
}; | ||
|
||
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), | ||
}); |