-
-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(postbuild): create schema on postbuild #1
- Loading branch information
1 parent
1b18c3a
commit f8c793e
Showing
17 changed files
with
269 additions
and
209 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
import { createSitemap } from './src/index'; | ||
|
||
createSitemap('https://example.com', { debug: true, resetTime: true }); | ||
createSitemap('https://example.com/', { debug: true, resetTime: true }); |
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 @@ | ||
Nothing here... |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
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,27 @@ | ||
<?xml version="1.0"?> | ||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> | ||
<url> | ||
<loc>https://example.com/</loc> | ||
<lastmod>2021-06-20</lastmod> | ||
</url> | ||
<url> | ||
<loc>https://example.com/page2/</loc> | ||
<lastmod>2021-06-20</lastmod> | ||
</url> | ||
<url> | ||
<loc>https://example.com/page1/</loc> | ||
<lastmod>2021-06-20</lastmod> | ||
</url> | ||
<url> | ||
<loc>https://example.com/page2/subpage2/</loc> | ||
<lastmod>2021-06-20</lastmod> | ||
</url> | ||
<url> | ||
<loc>https://example.com/page1/subpage1/</loc> | ||
<lastmod>2021-06-20</lastmod> | ||
</url> | ||
<url> | ||
<loc>https://example.com/page2/subpage2/subsubpage2/</loc> | ||
<lastmod>2021-06-20</lastmod> | ||
</url> | ||
</urlset> |
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 |
---|---|---|
@@ -1,161 +1,45 @@ | ||
import fs, { writeFile } from 'fs'; | ||
import { Options } from 'interfaces/global.interface'; | ||
import path from 'path'; | ||
import xml from 'xml'; | ||
import fg from 'fast-glob'; | ||
import fs from 'fs'; | ||
import { create } from 'xmlbuilder2'; | ||
import { Options, PagesJson } from '../interfaces/global.interface'; | ||
|
||
interface Page { | ||
title: string; | ||
slug: string; | ||
lastModified: string; | ||
created: string; | ||
} | ||
|
||
interface File { | ||
file: string; | ||
created: number; | ||
modified: number; | ||
} | ||
const PATH_BUILD = './src/build/'; | ||
|
||
const ROUTES = 'src/routes'; | ||
|
||
/** | ||
* Main wrapper | ||
* @param {string} domain Your domain | ||
*/ | ||
export const buildSitemap = (domain: string, options: Options): void => { | ||
const files = getFiles(options); | ||
assembleXML(files, domain, options); | ||
const getUrl = (url: string, domain: string) => { | ||
const slash = domain.split('/').pop() ? '/' : ''; | ||
const trimmed = url.slice(12).replace('index.html', ''); | ||
return `${domain}${slash}${trimmed}`; | ||
}; | ||
|
||
const walkSync = (dir: string, filelist: any[] = []) => { | ||
fs.readdirSync(dir).forEach((file) => { | ||
const filePath = path.join(dir, file); | ||
const created = fs.statSync(filePath).ctime; | ||
const modified = fs.statSync(filePath).mtime; | ||
export async function buildSitemap(domain: string, options?: Options): Promise<PagesJson[]> { | ||
const pages = await fg([`${PATH_BUILD}**/*.html`]); | ||
|
||
filelist = fs.statSync(path.join(dir, file)).isDirectory() | ||
? walkSync(path.join(dir, file), filelist) | ||
: filelist.concat({ file: filePath, created, modified }); | ||
const results: PagesJson[] = pages.map((page) => { | ||
return { | ||
page: getUrl(page, domain), | ||
changeFreq: options?.changeFreq ?? '', | ||
lastMod: options?.resetTime ? new Date().toISOString().split('T')[0] : '' | ||
}; | ||
}); | ||
return filelist; | ||
}; | ||
|
||
/** | ||
* Gathering files from subolders | ||
* @param {string} options some options | ||
*/ | ||
export const getFiles = (options: Options): Page[] => { | ||
const pages: Page[] = []; | ||
|
||
const paths = walkSync(ROUTES); | ||
|
||
if (!paths?.length) { | ||
console.error( | ||
'No routes found in you project... Make sure you have this folder created:', | ||
ROUTES | ||
); | ||
return []; | ||
} | ||
|
||
paths.forEach((route: File) => { | ||
const fileRaw = route.file.split('/'); | ||
return results; | ||
} | ||
|
||
const file = fileRaw.splice(2, 10).join('/'); | ||
// Excluding svelte files | ||
const slug = file.replace('/index.svelte', '').replace('.svelte', ''); | ||
if (slug !== 'index' && slug.includes('__') === false) { | ||
pages.push({ | ||
lastModified: (options.resetTime ? new Date() : new Date(route.modified)) | ||
.toISOString() | ||
.slice(0, 10), | ||
title: slug, | ||
created: (options.resetTime ? new Date() : new Date(route.created)) | ||
.toISOString() | ||
.slice(0, 10), | ||
slug | ||
}); | ||
} | ||
export const writeSitemap = (items: PagesJson[]): void => { | ||
const sitemap = create({ version: '1.0' }).ele('urlset', { | ||
xmlns: 'http://www.sitemaps.org/schemas/sitemap/0.9' | ||
}); | ||
|
||
if (options?.debug) { | ||
console.log('pages', pages); | ||
for (const item of items) { | ||
const page = sitemap.ele('url'); | ||
page.ele('loc').txt(item.page); | ||
if (item.changeFreq) { | ||
page.ele('changefreq').txt(item.changeFreq); | ||
} | ||
if (item.lastMod) { | ||
page.ele('lastmod').txt(item.lastMod); | ||
} | ||
} | ||
return pages; | ||
}; | ||
|
||
/** | ||
* Assemble xml and create file | ||
* @param {string[]} pages List of pages | ||
* @param {string} domain Your domain | ||
* @param {string} options Some useful options | ||
*/ | ||
export const assembleXML = (pages: Page[], domain: string, options: Options) => { | ||
const indexItem = { | ||
// build index item | ||
url: [ | ||
{ | ||
loc: domain | ||
}, | ||
{ | ||
lastmod: new Date( | ||
Math.max.apply( | ||
null, | ||
pages.map((page) => { | ||
return new Date(page.lastModified ?? page.created) as unknown as number; | ||
}) | ||
) | ||
) | ||
.toISOString() | ||
.split('T')[0] | ||
}, | ||
{ changefreq: 'daily' }, | ||
{ priority: '1.0' } | ||
] | ||
}; | ||
const xml = sitemap.end({ prettyPrint: true }); | ||
|
||
const sitemapItems = pages.reduce( | ||
( | ||
items: { url: [{ loc: string }, { lastmod: string }] }[], | ||
item: { | ||
title: string; | ||
slug: string; | ||
lastModified?: string; | ||
created: string; | ||
} | ||
) => { | ||
// build page items | ||
items.push({ | ||
url: [ | ||
{ | ||
loc: `${domain}/${item.slug}` | ||
}, | ||
{ | ||
lastmod: new Date(item.lastModified ?? item.created).toISOString().split('T')[0] | ||
} | ||
] | ||
}); | ||
return items; | ||
}, | ||
[] | ||
); | ||
|
||
const sitemapObject = { | ||
urlset: [ | ||
{ | ||
_attr: { | ||
xmlns: 'http://www.sitemaps.org/schemas/sitemap/0.9' | ||
} | ||
}, | ||
indexItem, | ||
...sitemapItems | ||
] | ||
}; | ||
|
||
const sitemap = `<?xml version="1.0" encoding="UTF-8"?>${xml(sitemapObject)}`; | ||
|
||
writeFile('./static/sitemap.xml', sitemap, (err) => { | ||
if (!err) { | ||
console.log('\x1b[32m', `File './static/sitemap.xml' has been created.`, '\x1b[0m'); | ||
} | ||
}); | ||
fs.writeFileSync(`${PATH_BUILD}/sitemap.xml`, xml); | ||
}; |
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 |
---|---|---|
@@ -1,7 +1,17 @@ | ||
import { Options } from 'interfaces/global.interface'; | ||
import { buildSitemap } from './helpers/global.helper'; | ||
import { buildSitemap, writeSitemap } from './helpers/global.helper'; | ||
import { Options } from './interfaces/global.interface'; | ||
import { DOMAIN } from './vars'; | ||
|
||
export const createSitemap = (domain: string = DOMAIN, options: Options) => { | ||
buildSitemap(domain, options); | ||
export const createSitemap = async (domain: string = DOMAIN, options?: Options) => { | ||
if (options?.debug) { | ||
console.log('OPTIONS', options); | ||
} | ||
|
||
const json = await buildSitemap(domain, options); | ||
|
||
if (options?.debug) { | ||
console.log('RESULT', json); | ||
} | ||
|
||
writeSitemap(json); | ||
}; |
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 was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
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 |
---|---|---|
@@ -1 +1,5 @@ | ||
import { Options } from './interfaces/global.interface'; | ||
|
||
export const DOMAIN = 'https://example.com'; | ||
|
||
export const OPTIONS: Options = { resetTime: false, debug: false, changeFreq: 'weekly' }; |
Oops, something went wrong.