Skip to content

Commit ef2f35d

Browse files
committed
.
0 parents  commit ef2f35d

File tree

10 files changed

+1407
-0
lines changed

10 files changed

+1407
-0
lines changed

.editorconfig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
root = true
2+
3+
[*]
4+
indent_style = space
5+
indent_size = 2
6+
end_of_line = lf
7+
charset = utf-8
8+
trim_trailing_whitespace = true
9+
insert_final_newline = true

.github/workflows/main.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: main
2+
on:
3+
- pull_request
4+
- push
5+
jobs:
6+
main:
7+
name: ${{matrix.node}}
8+
runs-on: ubuntu-latest
9+
steps:
10+
- uses: actions/checkout@v2
11+
- uses: dcodeIO/setup-node-nvm@master
12+
with:
13+
node-version: ${{matrix.node}}
14+
- run: npm install
15+
- run: npm test
16+
- uses: codecov/codecov-action@v1
17+
strategy:
18+
matrix:
19+
node:
20+
- lts/erbium
21+
- node

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.DS_Store
2+
*.log
3+
coverage/
4+
node_modules/
5+
yarn.lock

.npmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
package-lock=false

.prettierignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
coverage/
2+
*.json
3+
*.md

index.mjs

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
import bcp47 from 'bcp-47-normalize'
2+
import u from 'unist-builder'
3+
import x from 'xastscript'
4+
5+
var own = {}.hasOwnProperty
6+
7+
export function sitemap(data) {
8+
var nodes = []
9+
var urls = {}
10+
var groupings = {}
11+
var index = -1
12+
var i18n
13+
var grouping
14+
var entry
15+
var alt
16+
var key
17+
var node
18+
var modified
19+
20+
if (data) {
21+
while (++index < data.length) {
22+
entry = toEntry(data[index])
23+
24+
if (own.call(urls, entry.url)) {
25+
Object.assign(urls[entry.url], entry)
26+
} else {
27+
urls[entry.url] = entry
28+
}
29+
30+
if (entry.alternate) {
31+
i18n = true
32+
33+
if (!entry.lang) {
34+
throw new Error(
35+
'Expected `lang` in entry with `alternate` `' +
36+
entry +
37+
'` (`' +
38+
index +
39+
'`)'
40+
)
41+
}
42+
43+
// Find an already defined grouping.
44+
// Maybe the entry was references before?
45+
if (own.call(groupings, entry.url)) {
46+
grouping = groupings[entry.url]
47+
} else {
48+
grouping = []
49+
50+
// Maybe one of the `alternates` was references before, if so: use
51+
// that group.
52+
for (key in entry.alternate) {
53+
if (own.call(entry.alternate, key)) {
54+
alt = toEntry(entry.alternate[key])
55+
56+
if (own.call(groupings, alt.url)) {
57+
grouping = groupings[alt.url]
58+
break
59+
}
60+
}
61+
}
62+
}
63+
64+
if (!own.call(groupings, entry.url)) groupings[entry.url] = grouping
65+
if (!grouping.includes(entry.url)) grouping.push(entry.url)
66+
67+
for (key in entry.alternate) {
68+
if (own.call(entry.alternate, key)) {
69+
alt = toEntry(entry.alternate[key])
70+
if (!alt.lang) alt.lang = bcp47(key)
71+
72+
if (!own.call(urls, alt.url)) {
73+
urls[alt.url] = Object.assign({}, entry, alt)
74+
}
75+
76+
if (!own.call(groupings, alt.url)) groupings[alt.url] = grouping
77+
if (!grouping.includes(alt.url)) grouping.push(alt.url)
78+
}
79+
}
80+
}
81+
}
82+
}
83+
84+
for (key in urls) {
85+
if (own.call(urls, key)) {
86+
node = x('url', [x('loc', key)])
87+
entry = urls[key]
88+
modified = entry.modified
89+
90+
nodes.push(node)
91+
92+
if (modified != null) {
93+
if (typeof modified !== 'object') {
94+
modified = new Date(modified)
95+
}
96+
97+
if (isNaN(modified)) {
98+
throw new Error('Unexpected incorrect date `' + entry.modified + '`')
99+
}
100+
101+
node.children.push(x('lastmod', modified.toISOString()))
102+
}
103+
104+
if (own.call(groupings, key)) {
105+
grouping = groupings[key]
106+
index = -1
107+
108+
while (++index < grouping.length) {
109+
node.children.push(
110+
x('xhtml:link', {
111+
rel: 'alternate',
112+
hreflang: urls[grouping[index]].lang,
113+
href: grouping[index]
114+
})
115+
)
116+
}
117+
}
118+
}
119+
}
120+
121+
return u('root', [
122+
u('instruction', {name: 'xml'}, 'version="1.0" encoding="utf-8"'),
123+
x(
124+
'urlset',
125+
{
126+
xmlns: 'http://www.sitemaps.org/schemas/sitemap/0.9',
127+
'xmlns:xhtml': i18n ? 'http://www.w3.org/1999/xhtml' : undefined
128+
},
129+
nodes
130+
)
131+
])
132+
}
133+
134+
function toEntry(d) {
135+
var entry = {}
136+
var url
137+
138+
if (typeof d === 'string') {
139+
url = d
140+
} else {
141+
url = d.url
142+
if (d.lang != null) entry.lang = bcp47(d.lang)
143+
if (d.modified != null) entry.modified = d.modified
144+
if (d.alternate != null) entry.alternate = d.alternate
145+
}
146+
147+
entry.url = new URL(url).href
148+
return entry
149+
}

license

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
(The MIT License)
2+
3+
Copyright (c) 2021 Titus Wormer <[email protected]>
4+
5+
Permission is hereby granted, free of charge, to any person obtaining
6+
a copy of this software and associated documentation files (the
7+
'Software'), to deal in the Software without restriction, including
8+
without limitation the rights to use, copy, modify, merge, publish,
9+
distribute, sublicense, and/or sell copies of the Software, and to
10+
permit persons to whom the Software is furnished to do so, subject to
11+
the following conditions:
12+
13+
The above copyright notice and this permission notice shall be
14+
included in all copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
17+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

package.json

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
{
2+
"name": "xast-util-sitemap",
3+
"version": "0.0.0",
4+
"description": "xast utility to build a sitemap",
5+
"license": "MIT",
6+
"keywords": [
7+
"unist",
8+
"xast",
9+
"xast-util",
10+
"util",
11+
"utility",
12+
"xml",
13+
"sitemap"
14+
],
15+
"repository": "syntax-tree/xast-util-sitemap",
16+
"bugs": "https://github.com/syntax-tree/xast-util-sitemap/issues",
17+
"funding": {
18+
"type": "opencollective",
19+
"url": "https://opencollective.com/unified"
20+
},
21+
"author": "Titus Wormer <[email protected]> (https://wooorm.com)",
22+
"contributors": [
23+
"Titus Wormer <[email protected]> (https://wooorm.com)"
24+
],
25+
"type": "module",
26+
"main": "./index.mjs",
27+
"module": "./index.mjs",
28+
"files": [
29+
"index.mjs"
30+
],
31+
"dependencies": {
32+
"bcp-47-normalize": "^1.0.0",
33+
"unist-builder": "^2.0.0",
34+
"xastscript": "^2.0.0"
35+
},
36+
"devDependencies": {
37+
"c8": "^7.0.0",
38+
"concat-stream": "^2.0.0",
39+
"prettier": "^2.0.0",
40+
"regenerate": "^1.0.0",
41+
"remark-cli": "^9.0.0",
42+
"remark-preset-wooorm": "^8.0.0",
43+
"tape": "^5.0.0",
44+
"xast-util-to-xml": "^2.0.0",
45+
"xo": "^0.37.0"
46+
},
47+
"scripts": {
48+
"format": "remark . -qfo && prettier . -w --loglevel warn && xo --fix",
49+
"test-api": "node test.mjs",
50+
"test-coverage": "c8 --check-coverage --branches 100 --functions 100 --lines 100 --statements 100 --reporter lcov node --experimental-modules test.mjs",
51+
"test": "npm run format && npm run test-coverage"
52+
},
53+
"prettier": {
54+
"tabWidth": 2,
55+
"useTabs": false,
56+
"singleQuote": true,
57+
"bracketSpacing": false,
58+
"semi": false,
59+
"trailingComma": "none"
60+
},
61+
"xo": {
62+
"prettier": true,
63+
"esnext": false,
64+
"extensions": [
65+
"mjs"
66+
],
67+
"rules": {
68+
"complexity": "off",
69+
"eqeqeq": [
70+
"error",
71+
"always",
72+
{
73+
"null": "ignore"
74+
}
75+
],
76+
"max-depth": "off",
77+
"no-eq-null": "off",
78+
"no-self-compare": "off",
79+
"unicorn/prefer-number-properties": "off",
80+
"unicorn/prefer-type-error": "off"
81+
}
82+
},
83+
"remarkConfig": {
84+
"plugins": [
85+
"preset-wooorm"
86+
]
87+
}
88+
}

0 commit comments

Comments
 (0)