Merge branch 'main' into re-export-component-client
This commit is contained in:
commit
243f7ae11c
75 changed files with 809 additions and 187 deletions
7
.changeset/fluffy-hounds-smash.md
Normal file
7
.changeset/fluffy-hounds-smash.md
Normal file
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
'astro': patch
|
||||
'@astrojs/netlify': patch
|
||||
'@astrojs/markdown-remark': patch
|
||||
---
|
||||
|
||||
Fix: "vpath" import error when building for netlify edge
|
7
.changeset/four-numbers-flash.md
Normal file
7
.changeset/four-numbers-flash.md
Normal file
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
'@astrojs/telemetry': patch
|
||||
---
|
||||
|
||||
Fix telemetry crashing astro build/dev when using optional integrations
|
||||
|
||||
Telemetry will now ignore falsy integration values but will gather a count of how many integrations out of the total are now optional integrations
|
5
.changeset/funny-terms-matter.md
Normal file
5
.changeset/funny-terms-matter.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'@astrojs/telemetry': patch
|
||||
---
|
||||
|
||||
Add's optional integrations field to `@astrojs/telemetry`'s payload
|
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
'@astrojs/netlify': patch
|
||||
---
|
||||
|
||||
Adds support for base64 encoded responses in Netlify Functions
|
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
Fix: find a hosting network differently based on Node version
|
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
Inlines hydration scripts
|
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
'@astrojs/cloudflare': minor
|
||||
---
|
||||
|
||||
add SSR adaptor for Cloudflare Pages functions
|
18
.changeset/popular-cherries-float.md
Normal file
18
.changeset/popular-cherries-float.md
Normal file
|
@ -0,0 +1,18 @@
|
|||
---
|
||||
'@astrojs/sitemap': minor
|
||||
---
|
||||
|
||||
# Key features
|
||||
|
||||
- Split up your large sitemap into multiple sitemaps by custom limit.
|
||||
- Ability to add sitemap specific attributes such as `lastmod` etc.
|
||||
- Final output customization via JS function.
|
||||
- Localization support.
|
||||
- Reliability: all config options are validated.
|
||||
|
||||
## Important changes
|
||||
|
||||
The integration always generates at least two files instead of one:
|
||||
|
||||
- `sitemap-index.xml` - index file;
|
||||
- `sitemap-{i}.xml` - actual sitemap.
|
6
.changeset/wild-phones-work.md
Normal file
6
.changeset/wild-phones-work.md
Normal file
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
'astro': patch
|
||||
'@astrojs/markdown-remark': patch
|
||||
---
|
||||
|
||||
Remove extra newlines around Markdown components
|
|
@ -9,6 +9,6 @@
|
|||
"preview": "astro preview"
|
||||
},
|
||||
"devDependencies": {
|
||||
"astro": "^1.0.0-beta.46"
|
||||
"astro": "^1.0.0-beta.47"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@astrojs/preact": "^0.1.3",
|
||||
"astro": "^1.0.0-beta.46",
|
||||
"astro": "^1.0.0-beta.47",
|
||||
"sass": "^1.52.2"
|
||||
},
|
||||
"dependencies": {
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@astrojs/preact": "^0.1.3",
|
||||
"astro": "^1.0.0-beta.46"
|
||||
"astro": "^1.0.0-beta.47"
|
||||
},
|
||||
"dependencies": {
|
||||
"preact": "^10.7.3"
|
||||
|
|
|
@ -10,6 +10,6 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@example/my-component": "workspace:*",
|
||||
"astro": "^1.0.0-beta.46"
|
||||
"astro": "^1.0.0-beta.47"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,6 @@
|
|||
"serve": "astro --root demo preview"
|
||||
},
|
||||
"devDependencies": {
|
||||
"astro": "^1.0.0-beta.46"
|
||||
"astro": "^1.0.0-beta.47"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,6 @@
|
|||
"devDependencies": {
|
||||
"@astrojs/preact": "^0.1.3",
|
||||
"@astrojs/react": "^0.1.3",
|
||||
"astro": "^1.0.0-beta.46"
|
||||
"astro": "^1.0.0-beta.47"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,6 @@
|
|||
"preview": "astro preview"
|
||||
},
|
||||
"devDependencies": {
|
||||
"astro": "^1.0.0-beta.46"
|
||||
"astro": "^1.0.0-beta.47"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
"preview": "astro preview"
|
||||
},
|
||||
"devDependencies": {
|
||||
"astro": "^1.0.0-beta.46"
|
||||
"astro": "^1.0.0-beta.47"
|
||||
},
|
||||
"dependencies": {
|
||||
"alpinejs": "^3.10.2"
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@astrojs/lit": "^0.1.5",
|
||||
"astro": "^1.0.0-beta.46"
|
||||
"astro": "^1.0.0-beta.47"
|
||||
},
|
||||
"dependencies": {
|
||||
"@webcomponents/template-shadowroot": "^0.1.0",
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
"@astrojs/solid-js": "^0.1.4",
|
||||
"@astrojs/svelte": "^0.1.4",
|
||||
"@astrojs/vue": "^0.1.5",
|
||||
"astro": "^1.0.0-beta.46"
|
||||
"astro": "^1.0.0-beta.47"
|
||||
},
|
||||
"dependencies": {
|
||||
"@webcomponents/template-shadowroot": "^0.1.0",
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@astrojs/preact": "^0.1.3",
|
||||
"astro": "^1.0.0-beta.46"
|
||||
"astro": "^1.0.0-beta.47"
|
||||
},
|
||||
"dependencies": {
|
||||
"preact": "^10.7.3"
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@astrojs/react": "^0.1.3",
|
||||
"astro": "^1.0.0-beta.46"
|
||||
"astro": "^1.0.0-beta.47"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/react": "^18.0.10",
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@astrojs/solid-js": "^0.1.4",
|
||||
"astro": "^1.0.0-beta.46"
|
||||
"astro": "^1.0.0-beta.47"
|
||||
},
|
||||
"dependencies": {
|
||||
"solid-js": "^1.4.3"
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@astrojs/svelte": "^0.1.4",
|
||||
"astro": "^1.0.0-beta.46"
|
||||
"astro": "^1.0.0-beta.47"
|
||||
},
|
||||
"dependencies": {
|
||||
"svelte": "^3.48.0"
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@astrojs/vue": "^0.1.5",
|
||||
"astro": "^1.0.0-beta.46"
|
||||
"astro": "^1.0.0-beta.47"
|
||||
},
|
||||
"dependencies": {
|
||||
"vue": "^3.2.36"
|
||||
|
|
|
@ -9,5 +9,6 @@ import solid from '@astrojs/solid-js';
|
|||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
site: 'https://example.com',
|
||||
integrations: [lit(), react(), tailwind(), turbolinks(), partytown(), sitemap(), solid()],
|
||||
});
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
"@astrojs/solid-js": "0.1.4",
|
||||
"@astrojs/tailwind": "^0.2.1",
|
||||
"@astrojs/turbolinks": "^0.1.3",
|
||||
"astro": "^1.0.0-beta.46",
|
||||
"astro": "^1.0.0-beta.47",
|
||||
"solid-js": "^1.4.3"
|
||||
},
|
||||
"dependencies": {
|
||||
|
|
|
@ -9,6 +9,6 @@
|
|||
"preview": "astro preview"
|
||||
},
|
||||
"devDependencies": {
|
||||
"astro": "^1.0.0-beta.46"
|
||||
"astro": "^1.0.0-beta.47"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,6 @@
|
|||
"preview": "astro preview"
|
||||
},
|
||||
"devDependencies": {
|
||||
"astro": "^1.0.0-beta.46"
|
||||
"astro": "^1.0.0-beta.47"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@astrojs/preact": "^0.1.3",
|
||||
"astro": "^1.0.0-beta.46",
|
||||
"astro": "^1.0.0-beta.47",
|
||||
"sass": "^1.52.2"
|
||||
},
|
||||
"dependencies": {
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
"devDependencies": {
|
||||
"@astrojs/node": "^0.1.2",
|
||||
"@astrojs/svelte": "^0.1.4",
|
||||
"astro": "^1.0.0-beta.46",
|
||||
"astro": "^1.0.0-beta.47",
|
||||
"concurrently": "^7.2.1",
|
||||
"lightcookie": "^1.0.25",
|
||||
"unocss": "^0.15.6",
|
||||
|
|
|
@ -9,6 +9,6 @@
|
|||
"preview": "astro preview"
|
||||
},
|
||||
"devDependencies": {
|
||||
"astro": "^1.0.0-beta.46"
|
||||
"astro": "^1.0.0-beta.47"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@astrojs/react": "^0.1.3",
|
||||
"astro": "^1.0.0-beta.46",
|
||||
"astro": "^1.0.0-beta.47",
|
||||
"sass": "^1.52.2"
|
||||
},
|
||||
"dependencies": {
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@astrojs/markdown-remark": "^0.11.2",
|
||||
"astro": "^1.0.0-beta.46",
|
||||
"astro": "^1.0.0-beta.47",
|
||||
"hast-util-select": "5.0.1",
|
||||
"rehype-autolink-headings": "^6.1.1",
|
||||
"rehype-slug": "^5.0.1",
|
||||
|
|
|
@ -10,6 +10,6 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@astrojs/markdown-remark": "^0.11.2",
|
||||
"astro": "^1.0.0-beta.46"
|
||||
"astro": "^1.0.0-beta.47"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
"@astrojs/react": "^0.1.3",
|
||||
"@astrojs/svelte": "^0.1.4",
|
||||
"@astrojs/vue": "^0.1.5",
|
||||
"astro": "^1.0.0-beta.46"
|
||||
"astro": "^1.0.0-beta.47"
|
||||
},
|
||||
"dependencies": {
|
||||
"preact": "^10.7.3",
|
||||
|
|
|
@ -25,6 +25,6 @@
|
|||
"@astrojs/solid-js": "^0.1.4",
|
||||
"@astrojs/svelte": "^0.1.4",
|
||||
"@astrojs/vue": "^0.1.5",
|
||||
"astro": "^1.0.0-beta.46"
|
||||
"astro": "^1.0.0-beta.47"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@astrojs/tailwind": "^0.2.1",
|
||||
"astro": "^1.0.0-beta.46",
|
||||
"astro": "^1.0.0-beta.47",
|
||||
"autoprefixer": "^10.4.7",
|
||||
"canvas-confetti": "^1.5.1",
|
||||
"postcss": "^8.4.14",
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
"preview": "astro preview"
|
||||
},
|
||||
"devDependencies": {
|
||||
"astro": "^1.0.0-beta.46",
|
||||
"astro": "^1.0.0-beta.47",
|
||||
"vite-plugin-pwa": "0.11.11",
|
||||
"workbox-window": "^6.5.3"
|
||||
}
|
||||
|
|
|
@ -1,5 +1,13 @@
|
|||
# astro
|
||||
|
||||
## 1.0.0-beta.47
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#3599](https://github.com/withastro/astro/pull/3599) [`0ffc350c`](https://github.com/withastro/astro/commit/0ffc350c8d6bcf7fe4f6bde7ce1c10c014d7b4a1) Thanks [@arimgibson](https://github.com/arimgibson)! - Fix: find a hosting network differently based on Node version
|
||||
|
||||
* [#3605](https://github.com/withastro/astro/pull/3605) [`4916b733`](https://github.com/withastro/astro/commit/4916b733c2b8265ab46762bbbc85aa4171296515) Thanks [@matthewp](https://github.com/matthewp)! - Inlines hydration scripts
|
||||
|
||||
## 1.0.0-beta.46
|
||||
|
||||
### Patch Changes
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "astro",
|
||||
"version": "1.0.0-beta.46",
|
||||
"version": "1.0.0-beta.47",
|
||||
"description": "Astro is a modern site builder with web best practices, performance, and DX front-of-mind.",
|
||||
"type": "module",
|
||||
"author": "withastro",
|
||||
|
|
|
@ -156,7 +156,7 @@ export default function markdown({ config }: AstroPluginOptions): Plugin {
|
|||
const { layout = '', components = '', setup = '', ...content } = frontmatter;
|
||||
content.astro = metadata;
|
||||
const prelude = `---
|
||||
import { slug as $$slug } from '@astrojs/markdown-remark';
|
||||
import { slug as $$slug } from '@astrojs/markdown-remark/ssr-utils';
|
||||
${layout ? `import Layout from '${layout}';` : ''}
|
||||
${components ? `import * from '${components}';` : ''}
|
||||
${hasInjectedScript ? `import '${PAGE_SSR_SCRIPT_ID}';` : ''}
|
||||
|
|
|
@ -291,12 +291,16 @@ describe('Astro Markdown', () => {
|
|||
expect(slots.find('> .fragmentSlot > div').text()).to.contain('1:');
|
||||
expect(slots.find('> .fragmentSlot > div + p').text()).to.contain('2:');
|
||||
expect(slots.find('> .pSlot > p[title="hello"]').text()).to.contain('3:');
|
||||
expect(slots.find('> .defaultSlot').text().replace(/\s+/g, ' ')).to.equal(
|
||||
`
|
||||
4: Div in default slot
|
||||
5: Paragraph in fragment in default slot
|
||||
6: Regular text in default slot
|
||||
`.replace(/\s+/g, ' ')
|
||||
expect(slots.find('> .defaultSlot').html()).to.match(
|
||||
new RegExp(
|
||||
`<div>4: Div in default slot</div>` +
|
||||
// Optional extra paragraph due to the line breaks between components
|
||||
`(<p></p>)?` +
|
||||
`<p>5: Paragraph in fragment in default slot</p>` +
|
||||
// Optional whitespace due to the line breaks between components
|
||||
`[\s\n]*` +
|
||||
`6: Regular text in default slot`
|
||||
)
|
||||
);
|
||||
|
||||
const nestedSlots = $('article').eq(1);
|
||||
|
|
|
@ -5,10 +5,6 @@ import * as cheerio from 'cheerio';
|
|||
describe('Error display', () => {
|
||||
if (isWindows) return;
|
||||
|
||||
// TODO: Ubuntu CI runs hit a reliability problem with more than one test in this suite.
|
||||
// Re-enable this suite once that issue is tracked down.
|
||||
if (isLinux) return;
|
||||
|
||||
/** @type {import('./test-utils').Fixture} */
|
||||
let fixture;
|
||||
|
||||
|
@ -18,14 +14,24 @@ describe('Error display', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('Astro', async () => {
|
||||
/**
|
||||
* TODO: Track down reliability issue
|
||||
*
|
||||
* After fixing a syntax error on one page, the dev server hangs on the hmr.js request.
|
||||
* This is specific to a project that has other framework component errors,
|
||||
* in this case the fixture has multiple broken pages and components.
|
||||
*
|
||||
* The issue could be internal to vite, the hmr.js request triggers connect:dispatcher
|
||||
* events but vite:load is never actually called.
|
||||
*/
|
||||
describe.skip('Astro template syntax', async () => {
|
||||
let devServer;
|
||||
|
||||
before(async () => {
|
||||
beforeEach(async () => {
|
||||
devServer = await fixture.startDevServer();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
afterEach(async () => {
|
||||
await devServer.stop();
|
||||
});
|
||||
|
||||
|
|
7
packages/integrations/cloudflare/CHANGELOG.md
Normal file
7
packages/integrations/cloudflare/CHANGELOG.md
Normal file
|
@ -0,0 +1,7 @@
|
|||
# @astrojs/cloudflare
|
||||
|
||||
## 0.2.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#3600](https://github.com/withastro/astro/pull/3600) [`7f423581`](https://github.com/withastro/astro/commit/7f423581411648c9a69b68918ff930581f12cf16) Thanks [@nrgnrg](https://github.com/nrgnrg)! - add SSR adaptor for Cloudflare Pages functions
|
|
@ -22,3 +22,11 @@ $ pnpm install wrangler --save-dev
|
|||
```
|
||||
|
||||
It's then possible to update the preview script in your `package.json` to `"preview": "wrangler pages dev ./dist"`
|
||||
|
||||
## Streams
|
||||
|
||||
Some integrations such as (react)[https://github.com/withastro/astro/tree/main/packages/integrations/react] rely on web streams. Currently Cloudflare Pages functions are in beta and don't support the `streams_enable_constructors` feature flag.
|
||||
|
||||
In order to work around this:
|
||||
- install the `"web-streams-polyfill"` package
|
||||
- add `import "web-streams-polyfill/es2018";` to the top of the front matter of every page which requires streams, such as server rendering a React component.
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "@astrojs/cloudflare",
|
||||
"description": "Deploy your site to cloudflare pages functions",
|
||||
"version": "0.1.0",
|
||||
"version": "0.2.0",
|
||||
"type": "module",
|
||||
"types": "./dist/index.d.ts",
|
||||
"author": "withastro",
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
# @astrojs/netlify
|
||||
|
||||
## 0.4.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#3592](https://github.com/withastro/astro/pull/3592) [`0ddcef20`](https://github.com/withastro/astro/commit/0ddcef2043e3c2f65aaeec7a969c374c053e22f3) Thanks [@tony-sull](https://github.com/tony-sull)! - Adds support for base64 encoded responses in Netlify Functions
|
||||
|
||||
## 0.4.3
|
||||
|
||||
### Patch Changes
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "@astrojs/netlify",
|
||||
"description": "Deploy your site to Netlify",
|
||||
"version": "0.4.3",
|
||||
"version": "0.4.4",
|
||||
"type": "module",
|
||||
"types": "./dist/index.d.ts",
|
||||
"author": "withastro",
|
||||
|
@ -27,7 +27,7 @@
|
|||
"dev": "astro-scripts dev \"src/**/*.ts\"",
|
||||
"test-fn": "mocha --exit --timeout 20000 test/functions/",
|
||||
"test-edge": "deno test --allow-run --allow-read --allow-net ./test/edge-functions/",
|
||||
"test": "npm run test-fn"
|
||||
"test": "npm run test-fn && npm run test-edge"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/webapi": "^0.12.0",
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { SSRManifest } from 'astro';
|
||||
import type { SSRManifest } from 'astro';
|
||||
import { App } from 'astro/app';
|
||||
import './edge-shim.js';
|
||||
|
||||
|
|
|
@ -5,11 +5,15 @@ import { assertEquals, assert, DOMParser } from './deps.ts';
|
|||
|
||||
// @ts-ignore
|
||||
Deno.test({
|
||||
// TODO: debug why build cannot be found in "await import"
|
||||
ignore: true,
|
||||
name: 'Edge Basics',
|
||||
skip: true,
|
||||
async fn() {
|
||||
let close = await runBuild('./fixtures/edge-basic/');
|
||||
const { default: handler } = await import('./fixtures/edge-basic/.netlify/edge-functions/entry.js');
|
||||
const { default: handler } = await import(
|
||||
'./fixtures/edge-basic/.netlify/edge-functions/entry.js'
|
||||
);
|
||||
const response = await handler(new Request('http://example.com/'));
|
||||
assertEquals(response.status, 200);
|
||||
const html = await response.text();
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
---
|
||||
title: Hey there!
|
||||
---
|
||||
|
||||
# {frontmatter.title}!
|
||||
|
||||
It's a markdown file!
|
|
@ -5,6 +5,8 @@ import { assertEquals, assert, DOMParser } from './deps.ts';
|
|||
|
||||
// @ts-ignore
|
||||
Deno.test({
|
||||
// TODO: debug why build cannot be found in "await import"
|
||||
ignore: true,
|
||||
name: 'Assets are preferred over HTML routes',
|
||||
async fn() {
|
||||
let close = await runBuild('./fixtures/root-dynamic/');
|
||||
|
|
|
@ -64,7 +64,35 @@ export default {
|
|||
}
|
||||
```
|
||||
|
||||
Now, [build your site for production](https://docs.astro.build/en/reference/cli-reference/#astro-build) via the `astro build` command. You should find your sitemap under `dist/sitemap.xml`!
|
||||
Now, [build your site for production](https://docs.astro.build/en/reference/cli-reference/#astro-build) via the `astro build` command. You should find your _sitemap_ under `dist/sitemap-index.xml` and `dist/sitemap-0.xml`!
|
||||
|
||||
Generated sitemap content for two pages website:
|
||||
|
||||
**sitemap-index.xml**
|
||||
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||
<sitemap>
|
||||
<loc>https://stargazers.club/sitemap-0.xml</loc>
|
||||
</sitemap>
|
||||
</sitemapindex>
|
||||
```
|
||||
|
||||
**sitemap-0.xml**
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1">
|
||||
<url>
|
||||
<loc>https://stargazers.club/</loc>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://stargazers.club/second-page/</loc>
|
||||
</url>
|
||||
</urlset>
|
||||
```
|
||||
|
||||
You can also check our [Astro Integration Documentation][astro-integration] for more on integrations.
|
||||
|
||||
|
@ -111,5 +139,158 @@ export default {
|
|||
}
|
||||
```
|
||||
|
||||
### entryLimit
|
||||
|
||||
Non-negative `Number` of entries per sitemap file. Default value is 45000. A sitemap index and multiple sitemaps are created if you have more entries. See explanation on [Google](https://developers.google.com/search/docs/advanced/sitemaps/large-sitemaps).
|
||||
|
||||
__astro.config.mjs__
|
||||
|
||||
```js
|
||||
import sitemap from '@astrojs/sitemap';
|
||||
|
||||
export default {
|
||||
site: 'https://stargazers.club',
|
||||
integrations: [
|
||||
sitemap({
|
||||
entryLimit: 10000,
|
||||
}),
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
### changefreq, lastmod, priority
|
||||
|
||||
`changefreq` - How frequently the page is likely to change. Available values: `always` \| `hourly` \| `daily` \| `weekly` \| `monthly` \| `yearly` \| `never`.
|
||||
|
||||
`priority` - The priority of this URL relative to other URLs on your site. Valid values range from 0.0 to 1.0.
|
||||
|
||||
`lastmod` - The date of page last modification.
|
||||
|
||||
`changefreq` and `priority` are ignored by Google.
|
||||
|
||||
See detailed explanation of sitemap specific options on [sitemap.org](https://www.sitemaps.org/protocol.html).
|
||||
|
||||
|
||||
:exclamation: This integration uses 'astro:build:done' hook. The hook exposes generated page paths only. So with present version of Astro the integration has no abilities to analyze a page source, frontmatter etc. The integration can add `changefreq`, `lastmod` and `priority` attributes only in a batch or nothing.
|
||||
|
||||
__astro.config.mjs__
|
||||
|
||||
```js
|
||||
import sitemap from '@astrojs/sitemap';
|
||||
|
||||
export default {
|
||||
site: 'https://stargazers.club',
|
||||
integrations: [
|
||||
sitemap({
|
||||
changefreq: 'weekly',
|
||||
priority: 0.7,
|
||||
lastmod: new Date('2022-02-24'),
|
||||
}),
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
### serialize
|
||||
|
||||
Async or sync function called for each sitemap entry just before writing to a disk.
|
||||
|
||||
It receives as parameter `SitemapItem` object which consists of `url` (required, absolute page URL) and optional `changefreq`, `lastmod`, `priority` and `links` properties.
|
||||
|
||||
Optional `links` property contains a `LinkItem` list of alternate pages including a parent page.
|
||||
`LinkItem` type has two required fields: `url` (the fully-qualified URL for the version of this page for the specified language) and `hreflang` (a supported language code targeted by this version of the page).
|
||||
|
||||
`serialize` function should return `SitemapItem`, touched or not.
|
||||
|
||||
The example below shows the ability to add the sitemap specific properties individually.
|
||||
|
||||
__astro.config.mjs__
|
||||
|
||||
```js
|
||||
import sitemap from '@astrojs/sitemap';
|
||||
|
||||
export default {
|
||||
site: 'https://stargazers.club',
|
||||
integrations: [
|
||||
sitemap({
|
||||
serialize(item) {
|
||||
if (/your-special-page/.test(item.url)) {
|
||||
item.changefreq = 'daily';
|
||||
item.lastmod = new Date();
|
||||
item.priority = 0.9;
|
||||
}
|
||||
return item;
|
||||
},
|
||||
}),
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
### i18n
|
||||
|
||||
To localize a sitemap you should supply the integration config with the `i18n` option. The integration will check generated page paths on presence of locale keys in paths.
|
||||
|
||||
`i18n` object has two required properties:
|
||||
|
||||
- `defaultLocale`: `String`. Its value must exist as one of `locales` keys.
|
||||
- `locales`: `Record<String, String>`, key/value - pairs. The key is used to look for a locale part in a page path. The value is a language attribute, only English alphabet and hyphen allowed. See more about language attribute on [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/lang).
|
||||
|
||||
|
||||
Read more about localization on Google in [Advanced SEO](https://developers.google.com/search/docs/advanced/crawling/localized-versions#all-method-guidelines).
|
||||
|
||||
__astro.config.mjs__
|
||||
|
||||
```js
|
||||
import sitemap from '@astrojs/sitemap';
|
||||
|
||||
export default {
|
||||
site: 'https://stargazers.club',
|
||||
integrations: [
|
||||
sitemap({
|
||||
i18n: {
|
||||
defaultLocale: 'en', // All urls that don't contain `es` or `fr` after `https://stargazers.club/` will be treated as default locale, i.e. `en`
|
||||
locales: {
|
||||
en: 'en-US', // The `defaultLocale` value must present in `locales` keys
|
||||
es: 'es-ES',
|
||||
fr: 'fr-CA',
|
||||
},
|
||||
},
|
||||
}),
|
||||
],
|
||||
};
|
||||
...
|
||||
|
||||
```
|
||||
|
||||
The sitemap content will be:
|
||||
|
||||
```xml
|
||||
...
|
||||
<url>
|
||||
<loc>https://stargazers.club/</loc>
|
||||
<xhtml:link rel="alternate" hreflang="en-US" href="https://stargazers.club/"/>
|
||||
<xhtml:link rel="alternate" hreflang="es-ES" href="https://stargazers.club/es/"/>
|
||||
<xhtml:link rel="alternate" hreflang="fr-CA" href="https://stargazers.club/fr/"/>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://stargazers.club/es/</loc>
|
||||
<xhtml:link rel="alternate" hreflang="en-US" href="https://stargazers.club/"/>
|
||||
<xhtml:link rel="alternate" hreflang="es-ES" href="https://stargazers.club/es/"/>
|
||||
<xhtml:link rel="alternate" hreflang="fr-CA" href="https://stargazers.club/fr/"/>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://stargazers.club/fr/</loc>
|
||||
<xhtml:link rel="alternate" hreflang="en-US" href="https://stargazers.club/"/>
|
||||
<xhtml:link rel="alternate" hreflang="es-ES" href="https://stargazers.club/es/"/>
|
||||
<xhtml:link rel="alternate" hreflang="fr-CA" href="https://stargazers.club/fr/"/>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://stargazers.club/es/second-page/</loc>
|
||||
<xhtml:link rel="alternate" hreflang="es-ES" href="https://stargazers.club/es/second-page/"/>
|
||||
<xhtml:link rel="alternate" hreflang="fr-CA" href="https://stargazers.club/fr/second-page/"/>
|
||||
<xhtml:link rel="alternate" hreflang="en-US" href="https://stargazers.club/second-page/"/>
|
||||
</url>
|
||||
...
|
||||
```
|
||||
|
||||
[astro-integration]: https://docs.astro.build/en/guides/integrations-guide/
|
||||
[astro-ui-frameworks]: https://docs.astro.build/en/core-concepts/framework-components/#using-framework-components
|
||||
|
|
|
@ -13,7 +13,8 @@
|
|||
},
|
||||
"keywords": [
|
||||
"astro-component",
|
||||
"seo"
|
||||
"seo",
|
||||
"sitemap"
|
||||
],
|
||||
"bugs": "https://github.com/withastro/astro/issues",
|
||||
"homepage": "https://astro.build",
|
||||
|
@ -21,12 +22,18 @@
|
|||
".": "./dist/index.js",
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "astro-scripts build \"src/**/*.ts\" && tsc",
|
||||
"build:ci": "astro-scripts build \"src/**/*.ts\"",
|
||||
"dev": "astro-scripts dev \"src/**/*.ts\""
|
||||
},
|
||||
"dependencies": {},
|
||||
"dependencies": {
|
||||
"sitemap": "^7.1.1",
|
||||
"zod": "^3.17.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"astro": "workspace:*",
|
||||
"astro-scripts": "workspace:*"
|
||||
|
|
5
packages/integrations/sitemap/src/config-defaults.ts
Normal file
5
packages/integrations/sitemap/src/config-defaults.ts
Normal file
|
@ -0,0 +1,5 @@
|
|||
import type { SitemapOptions } from './index';
|
||||
|
||||
export const SITEMAP_CONFIG_DEFAULTS: SitemapOptions & any = {
|
||||
entryLimit: 45000,
|
||||
};
|
9
packages/integrations/sitemap/src/constants.ts
Normal file
9
packages/integrations/sitemap/src/constants.ts
Normal file
|
@ -0,0 +1,9 @@
|
|||
export const changefreqValues = [
|
||||
'always',
|
||||
'hourly',
|
||||
'daily',
|
||||
'weekly',
|
||||
'monthly',
|
||||
'yearly',
|
||||
'never',
|
||||
] as const;
|
55
packages/integrations/sitemap/src/generate-sitemap.ts
Normal file
55
packages/integrations/sitemap/src/generate-sitemap.ts
Normal file
|
@ -0,0 +1,55 @@
|
|||
import { SitemapItemLoose } from 'sitemap';
|
||||
|
||||
import type { SitemapOptions } from './index';
|
||||
import { parseUrl } from './utils/parse-url';
|
||||
|
||||
const STATUS_CODE_PAGE_REGEXP = /\/[0-9]{3}\/?$/;
|
||||
|
||||
/** Construct sitemap.xml given a set of URLs */
|
||||
export function generateSitemap(pages: string[], finalSiteUrl: string, opts: SitemapOptions) {
|
||||
const { changefreq, priority: prioritySrc, lastmod: lastmodSrc, i18n } = opts || {};
|
||||
// TODO: find way to respect <link rel="canonical"> URLs here
|
||||
const urls = [...pages].filter((url) => !STATUS_CODE_PAGE_REGEXP.test(url));
|
||||
urls.sort((a, b) => a.localeCompare(b, 'en', { numeric: true })); // sort alphabetically so sitemap is same each time
|
||||
|
||||
const lastmod = lastmodSrc?.toISOString();
|
||||
const priority = typeof prioritySrc === 'number' ? prioritySrc : undefined;
|
||||
|
||||
const { locales, defaultLocale } = i18n || {};
|
||||
const localeCodes = Object.keys(locales || {});
|
||||
|
||||
const getPath = (url: string) => {
|
||||
const result = parseUrl(url, i18n?.defaultLocale || '', localeCodes, finalSiteUrl);
|
||||
return result?.path;
|
||||
};
|
||||
const getLocale = (url: string) => {
|
||||
const result = parseUrl(url, i18n?.defaultLocale || '', localeCodes, finalSiteUrl);
|
||||
return result?.locale;
|
||||
};
|
||||
|
||||
const urlData = urls.map((url) => {
|
||||
let links;
|
||||
if (defaultLocale && locales) {
|
||||
const currentPath = getPath(url);
|
||||
if (currentPath) {
|
||||
const filtered = urls.filter((subUrl) => getPath(subUrl) === currentPath);
|
||||
if (filtered.length > 1) {
|
||||
links = filtered.map((subUrl) => ({
|
||||
url: subUrl,
|
||||
lang: locales[getLocale(subUrl)!],
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
url,
|
||||
links,
|
||||
lastmod,
|
||||
priority,
|
||||
changefreq, // : changefreq as EnumChangefreq,
|
||||
} as SitemapItemLoose;
|
||||
});
|
||||
|
||||
return urlData;
|
||||
}
|
|
@ -1,91 +1,138 @@
|
|||
import type { AstroConfig, AstroIntegration } from 'astro';
|
||||
import fs from 'node:fs';
|
||||
const STATUS_CODE_PAGE_REGEXP = /\/[0-9]{3}\/?$/;
|
||||
import { LinkItem as LinkItemBase, simpleSitemapAndIndex, SitemapItemLoose } from 'sitemap';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { ZodError } from 'zod';
|
||||
|
||||
type SitemapOptions =
|
||||
import { changefreqValues } from './constants';
|
||||
import { generateSitemap } from './generate-sitemap';
|
||||
import { Logger } from './utils/logger';
|
||||
import { validateOptions } from './validate-options';
|
||||
|
||||
export type ChangeFreq = typeof changefreqValues[number];
|
||||
export type SitemapItem = Pick<
|
||||
SitemapItemLoose,
|
||||
'url' | 'lastmod' | 'changefreq' | 'priority' | 'links'
|
||||
>;
|
||||
export type LinkItem = LinkItemBase;
|
||||
|
||||
export type SitemapOptions =
|
||||
| {
|
||||
/**
|
||||
* All pages are included in your sitemap by default.
|
||||
* With this config option, you can filter included pages by URL.
|
||||
*
|
||||
* The `page` function parameter is the full URL of your rendered page, including your `site` domain.
|
||||
* Return `true` to include a page in your sitemap, and `false` to remove it.
|
||||
*
|
||||
* ```js
|
||||
* filter: (page) => page !== 'http://example.com/secret-page'
|
||||
* ```
|
||||
*/
|
||||
filter?(page: string): boolean;
|
||||
|
||||
/**
|
||||
* If you have any URL, not rendered by Astro, that you want to include in your sitemap,
|
||||
* this config option will help you to include your array of custom pages in your sitemap.
|
||||
*
|
||||
* ```js
|
||||
* customPages: ['http://example.com/custom-page', 'http://example.com/custom-page2']
|
||||
* ```
|
||||
*/
|
||||
customPages?: Array<string>;
|
||||
|
||||
/**
|
||||
* If present, we use the `site` config option as the base for all sitemap URLs
|
||||
* Use `canonicalURL` to override this
|
||||
*/
|
||||
customPages?: string[];
|
||||
canonicalURL?: string;
|
||||
|
||||
i18n?: {
|
||||
defaultLocale: string;
|
||||
locales: Record<string, string>;
|
||||
};
|
||||
// number of entries per sitemap file
|
||||
entryLimit?: number;
|
||||
|
||||
// sitemap specific
|
||||
changefreq?: ChangeFreq;
|
||||
lastmod?: Date;
|
||||
priority?: number;
|
||||
|
||||
// called for each sitemap item just before to save them on disk, sync or async
|
||||
serialize?(item: SitemapItemLoose): SitemapItemLoose;
|
||||
}
|
||||
| undefined;
|
||||
|
||||
/** Construct sitemap.xml given a set of URLs */
|
||||
function generateSitemap(pages: string[]) {
|
||||
// TODO: find way to respect <link rel="canonical"> URLs here
|
||||
const urls = [...pages].filter((url) => !STATUS_CODE_PAGE_REGEXP.test(url));
|
||||
urls.sort((a, b) => a.localeCompare(b, 'en', { numeric: true })); // sort alphabetically so sitemap is same each time
|
||||
let sitemap = `<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">`;
|
||||
for (const url of urls) {
|
||||
sitemap += `<url><loc>${url}</loc></url>`;
|
||||
}
|
||||
sitemap += `</urlset>\n`;
|
||||
return sitemap;
|
||||
function formatConfigErrorMessage(err: ZodError) {
|
||||
const errorList = err.issues.map((issue) => ` ${issue.path.join('.')} ${issue.message + '.'}`);
|
||||
return errorList.join('\n');
|
||||
}
|
||||
|
||||
export default function createPlugin({
|
||||
filter,
|
||||
customPages,
|
||||
canonicalURL,
|
||||
}: SitemapOptions = {}): AstroIntegration {
|
||||
const PKG_NAME = '@astrojs/sitemap';
|
||||
const OUTFILE = 'sitemap-index.xml';
|
||||
|
||||
const createPlugin = (options?: SitemapOptions): AstroIntegration => {
|
||||
let config: AstroConfig;
|
||||
return {
|
||||
name: '@astrojs/sitemap',
|
||||
name: PKG_NAME,
|
||||
|
||||
hooks: {
|
||||
'astro:config:done': async ({ config: _config }) => {
|
||||
config = _config;
|
||||
'astro:config:done': async ({ config: cfg }) => {
|
||||
config = cfg;
|
||||
},
|
||||
'astro:build:done': async ({ pages, dir }) => {
|
||||
let finalSiteUrl: URL;
|
||||
if (canonicalURL) {
|
||||
finalSiteUrl = new URL(canonicalURL);
|
||||
finalSiteUrl.pathname += finalSiteUrl.pathname.endsWith('/') ? '' : '/'; // normalizes the final url since it's provided by user
|
||||
} else if (config.site) {
|
||||
finalSiteUrl = new URL(config.base, config.site);
|
||||
} else {
|
||||
console.warn(
|
||||
'The Sitemap integration requires either the `site` astro.config option or `canonicalURL` integration option. Skipping.'
|
||||
);
|
||||
return;
|
||||
|
||||
'astro:build:done': async ({ dir, pages }) => {
|
||||
const logger = new Logger(PKG_NAME);
|
||||
|
||||
try {
|
||||
const opts = validateOptions(config.site, options);
|
||||
|
||||
const { filter, customPages, canonicalURL, serialize, entryLimit } = opts;
|
||||
|
||||
let finalSiteUrl: URL;
|
||||
if (canonicalURL) {
|
||||
finalSiteUrl = new URL(canonicalURL);
|
||||
if (!finalSiteUrl.pathname.endsWith('/')) {
|
||||
finalSiteUrl.pathname += '/'; // normalizes the final url since it's provided by user
|
||||
}
|
||||
} else {
|
||||
// `validateOptions` forces to provide `canonicalURL` or `config.site` at least.
|
||||
// So step to check on empty values of `canonicalURL` and `config.site` is dropped.
|
||||
finalSiteUrl = new URL(config.base, config.site);
|
||||
}
|
||||
|
||||
let pageUrls = pages.map((p) => {
|
||||
const path = finalSiteUrl.pathname + p.pathname;
|
||||
return new URL(path, finalSiteUrl).href;
|
||||
});
|
||||
|
||||
try {
|
||||
if (filter) {
|
||||
pageUrls = pageUrls.filter(filter);
|
||||
}
|
||||
} catch (err) {
|
||||
logger.error(`Error filtering pages\n${(err as any).toString()}`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (customPages) {
|
||||
pageUrls = [...pageUrls, ...customPages];
|
||||
}
|
||||
|
||||
if (pageUrls.length === 0) {
|
||||
logger.warn(`No data for sitemap.\n\`${OUTFILE}\` is not created.`);
|
||||
return;
|
||||
}
|
||||
|
||||
let urlData = generateSitemap(pageUrls, finalSiteUrl.href, opts);
|
||||
|
||||
if (serialize) {
|
||||
try {
|
||||
const serializedUrls: SitemapItemLoose[] = [];
|
||||
for (const item of urlData) {
|
||||
const serialized = await Promise.resolve(serialize(item));
|
||||
serializedUrls.push(serialized);
|
||||
}
|
||||
urlData = serializedUrls;
|
||||
} catch (err) {
|
||||
logger.error(`Error serializing pages\n${(err as any).toString()}`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
await simpleSitemapAndIndex({
|
||||
hostname: finalSiteUrl.href,
|
||||
destinationDir: fileURLToPath(dir),
|
||||
sourceData: urlData,
|
||||
limit: entryLimit,
|
||||
gzip: false,
|
||||
});
|
||||
logger.success(`\`${OUTFILE}\` is created.`);
|
||||
} catch (err) {
|
||||
if (err instanceof ZodError) {
|
||||
logger.warn(formatConfigErrorMessage(err));
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
let pageUrls = pages.map((p) => {
|
||||
const path = finalSiteUrl.pathname + p.pathname;
|
||||
return new URL(path, finalSiteUrl).href;
|
||||
});
|
||||
if (filter) {
|
||||
pageUrls = pageUrls.filter((page: string) => filter(page));
|
||||
}
|
||||
if (customPages) {
|
||||
pageUrls = [...pageUrls, ...customPages];
|
||||
}
|
||||
const sitemapContent = generateSitemap(pageUrls);
|
||||
fs.writeFileSync(new URL('sitemap.xml', dir), sitemapContent);
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
export default createPlugin;
|
||||
|
|
47
packages/integrations/sitemap/src/schema.ts
Normal file
47
packages/integrations/sitemap/src/schema.ts
Normal file
|
@ -0,0 +1,47 @@
|
|||
import { z } from 'zod';
|
||||
import { SITEMAP_CONFIG_DEFAULTS } from './config-defaults';
|
||||
import { changefreqValues } from './constants';
|
||||
|
||||
const localeKeySchema = () => z.string().min(1);
|
||||
|
||||
const isFunction = (fn: any) => fn instanceof Function;
|
||||
|
||||
const fnSchema = () =>
|
||||
z
|
||||
.any()
|
||||
.refine((val) => !val || isFunction(val), { message: 'Not a function' })
|
||||
.optional();
|
||||
|
||||
export const SitemapOptionsSchema = z
|
||||
.object({
|
||||
filter: fnSchema(),
|
||||
customPages: z.string().url().array().optional(),
|
||||
canonicalURL: z.string().url().optional(),
|
||||
|
||||
i18n: z
|
||||
.object({
|
||||
defaultLocale: localeKeySchema(),
|
||||
locales: z.record(
|
||||
localeKeySchema(),
|
||||
z
|
||||
.string()
|
||||
.min(2)
|
||||
.regex(/^[a-zA-Z\-]+$/gm, {
|
||||
message: 'Only English alphabet symbols and hyphen allowed',
|
||||
})
|
||||
),
|
||||
})
|
||||
.refine((val) => !val || val.locales[val.defaultLocale], {
|
||||
message: '`defaultLocale` must exists in `locales` keys',
|
||||
})
|
||||
.optional(),
|
||||
|
||||
entryLimit: z.number().nonnegative().default(SITEMAP_CONFIG_DEFAULTS.entryLimit),
|
||||
serialize: fnSchema(),
|
||||
|
||||
changefreq: z.enum(changefreqValues).optional(),
|
||||
lastmod: z.date().optional(),
|
||||
priority: z.number().min(0).max(1).optional(),
|
||||
})
|
||||
.strict()
|
||||
.default(SITEMAP_CONFIG_DEFAULTS);
|
10
packages/integrations/sitemap/src/utils/is-object-empty.ts
Normal file
10
packages/integrations/sitemap/src/utils/is-object-empty.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
// @internal
|
||||
export const isObjectEmpty = (o: any) => {
|
||||
if (!o) {
|
||||
return true;
|
||||
}
|
||||
if (Array.isArray(o)) {
|
||||
return o.length === 0;
|
||||
}
|
||||
return Object.keys(o).length === 0 && Object.getPrototypeOf(o) === Object.prototype;
|
||||
};
|
13
packages/integrations/sitemap/src/utils/is-valid-url.ts
Normal file
13
packages/integrations/sitemap/src/utils/is-valid-url.ts
Normal file
|
@ -0,0 +1,13 @@
|
|||
// @internal
|
||||
export const isValidUrl = (s: any) => {
|
||||
if (typeof s !== 'string' || !s) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const dummy = new URL(s);
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
};
|
46
packages/integrations/sitemap/src/utils/logger.ts
Normal file
46
packages/integrations/sitemap/src/utils/logger.ts
Normal file
|
@ -0,0 +1,46 @@
|
|||
// @internal
|
||||
export interface ILogger {
|
||||
info(msg: string): void;
|
||||
success(msg: string): void;
|
||||
warn(msg: string): void;
|
||||
error(msg: string): void;
|
||||
}
|
||||
|
||||
// @internal
|
||||
export class Logger implements ILogger {
|
||||
private colors = {
|
||||
reset: '\x1b[0m',
|
||||
fg: {
|
||||
red: '\x1b[31m',
|
||||
green: '\x1b[32m',
|
||||
yellow: '\x1b[33m',
|
||||
},
|
||||
} as const;
|
||||
|
||||
private packageName: string;
|
||||
|
||||
constructor(packageName: string) {
|
||||
this.packageName = packageName;
|
||||
}
|
||||
|
||||
private log(msg: string, prefix: string = '') {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`%s${this.packageName}:%s ${msg}\n`, prefix, prefix ? this.colors.reset : '');
|
||||
}
|
||||
|
||||
info(msg: string) {
|
||||
this.log(msg);
|
||||
}
|
||||
|
||||
success(msg: string) {
|
||||
this.log(msg, this.colors.fg.green);
|
||||
}
|
||||
|
||||
warn(msg: string) {
|
||||
this.log(`Skipped!\n${msg}`, this.colors.fg.yellow);
|
||||
}
|
||||
|
||||
error(msg: string) {
|
||||
this.log(`Failed!\n${msg}`, this.colors.fg.red);
|
||||
}
|
||||
}
|
39
packages/integrations/sitemap/src/utils/parse-url.ts
Normal file
39
packages/integrations/sitemap/src/utils/parse-url.ts
Normal file
|
@ -0,0 +1,39 @@
|
|||
export const parseUrl = (
|
||||
url: string,
|
||||
defaultLocale: string,
|
||||
localeCodes: string[],
|
||||
base: string
|
||||
) => {
|
||||
if (
|
||||
!url ||
|
||||
!defaultLocale ||
|
||||
localeCodes.length === 0 ||
|
||||
localeCodes.some((key) => !key) ||
|
||||
!base
|
||||
) {
|
||||
throw new Error('parseUrl: some parameters are empty');
|
||||
}
|
||||
if (url.indexOf(base) !== 0) {
|
||||
return undefined;
|
||||
}
|
||||
let s = url.replace(base, '');
|
||||
if (!s || s === '/') {
|
||||
return { locale: defaultLocale, path: '/' };
|
||||
}
|
||||
if (!s.startsWith('/')) {
|
||||
s = '/' + s;
|
||||
}
|
||||
const a = s.split('/');
|
||||
const locale = a[1];
|
||||
if (localeCodes.some((key) => key === locale)) {
|
||||
let path = a.slice(2).join('/');
|
||||
if (path === '//') {
|
||||
path = '/';
|
||||
}
|
||||
if (path !== '/' && !path.startsWith('/')) {
|
||||
path = '/' + path;
|
||||
}
|
||||
return { locale, path };
|
||||
}
|
||||
return { locale: defaultLocale, path: s };
|
||||
};
|
22
packages/integrations/sitemap/src/validate-options.ts
Normal file
22
packages/integrations/sitemap/src/validate-options.ts
Normal file
|
@ -0,0 +1,22 @@
|
|||
import { z } from 'zod';
|
||||
import type { SitemapOptions } from './index';
|
||||
import { SitemapOptionsSchema } from './schema';
|
||||
|
||||
// @internal
|
||||
export const validateOptions = (site: string | undefined, opts: SitemapOptions) => {
|
||||
const result = SitemapOptionsSchema.parse(opts);
|
||||
|
||||
z.object({
|
||||
site: z.string().optional(), // Astro takes care of `site`: how to validate, transform and refine
|
||||
canonicalURL: z.string().optional(), // `canonicalURL` is already validated in prev step
|
||||
})
|
||||
.refine(({ site, canonicalURL }) => site || canonicalURL, {
|
||||
message: 'Required `site` astro.config option or `canonicalURL` integration option',
|
||||
})
|
||||
.parse({
|
||||
site,
|
||||
canonicalURL: result.canonicalURL,
|
||||
});
|
||||
|
||||
return result;
|
||||
};
|
|
@ -13,7 +13,8 @@
|
|||
"homepage": "https://astro.build",
|
||||
"main": "./dist/index.js",
|
||||
"exports": {
|
||||
".": "./dist/index.js"
|
||||
".": "./dist/index.js",
|
||||
"./ssr-utils": "./dist/ssr-utils.js"
|
||||
},
|
||||
"scripts": {
|
||||
"prepublish": "pnpm build",
|
||||
|
|
|
@ -13,7 +13,6 @@ import scopedStyles from './remark-scoped-styles.js';
|
|||
import remarkShiki from './remark-shiki.js';
|
||||
import remarkUnwrap from './remark-unwrap.js';
|
||||
|
||||
import Slugger from 'github-slugger';
|
||||
import rehypeRaw from 'rehype-raw';
|
||||
import rehypeStringify from 'rehype-stringify';
|
||||
import markdown from 'remark-parse';
|
||||
|
@ -26,11 +25,6 @@ export * from './types.js';
|
|||
export const DEFAULT_REMARK_PLUGINS = ['remark-gfm', 'remark-smartypants'];
|
||||
export const DEFAULT_REHYPE_PLUGINS = [];
|
||||
|
||||
const slugger = new Slugger();
|
||||
export function slug(value: string): string {
|
||||
return slugger.slug(value);
|
||||
}
|
||||
|
||||
/** Shared utility for rendering markdown */
|
||||
export async function renderMarkdown(
|
||||
content: string,
|
||||
|
|
|
@ -25,7 +25,7 @@ export default function createCollectHeaders() {
|
|||
return;
|
||||
}
|
||||
if (child.type === 'raw') {
|
||||
if (child.value.startsWith('\n<') || child.value.endsWith('>\n')) {
|
||||
if (child.value.match(/^\n?<.*>\n?$/)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,11 +53,11 @@ export default function rehypeJsx(): ReturnType<RehypePlugin> {
|
|||
// wrapped by raw opening and closing tags
|
||||
const openingTag = {
|
||||
type: 'raw',
|
||||
value: `\n<${node.name}${attrs}>`,
|
||||
value: `<${node.name}${attrs}>`,
|
||||
};
|
||||
const closingTag = {
|
||||
type: 'raw',
|
||||
value: `</${node.name}>\n`,
|
||||
value: `</${node.name}>`,
|
||||
};
|
||||
parent.children.splice(index, 1, openingTag, ...node.children, closingTag);
|
||||
});
|
||||
|
|
8
packages/markdown/remark/src/ssr-utils.ts
Normal file
8
packages/markdown/remark/src/ssr-utils.ts
Normal file
|
@ -0,0 +1,8 @@
|
|||
/** Utilities used in deployment-ready SSR bundles */
|
||||
import Slugger from 'github-slugger';
|
||||
|
||||
const slugger = new Slugger();
|
||||
/** @see {@link "/packages/astro/vite-plugin-markdown"} */
|
||||
export function slug(value: string): string {
|
||||
return slugger.slug(value);
|
||||
}
|
|
@ -49,7 +49,7 @@ describe('components', () => {
|
|||
it('should normalize children', async () => {
|
||||
const { code } = await renderMarkdown(`<Component bool={true}>Hello world!</Component>`, {});
|
||||
|
||||
chai.expect(code).to.equal(`\n<Component bool={true}>Hello world!</Component>\n`);
|
||||
chai.expect(code).to.equal(`<Component bool={true}>Hello world!</Component>`);
|
||||
});
|
||||
|
||||
it('should be able to nest components', async () => {
|
||||
|
@ -60,7 +60,7 @@ describe('components', () => {
|
|||
|
||||
chai
|
||||
.expect(code)
|
||||
.to.equal(`\n<Component bool={true}>\n<Component>Hello world!</Component>\n</Component>\n`);
|
||||
.to.equal(`<Component bool={true}><Component>Hello world!</Component></Component>`);
|
||||
});
|
||||
|
||||
it('should allow markdown without many spaces', async () => {
|
||||
|
@ -71,6 +71,6 @@ describe('components', () => {
|
|||
{}
|
||||
);
|
||||
|
||||
chai.expect(code).to.equal(`\n<Component><h1 id="hello-world">Hello world!</h1></Component>\n`);
|
||||
chai.expect(code).to.equal(`<Component><h1 id="hello-world">Hello world!</h1></Component>`);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -11,7 +11,7 @@ describe('expressions', () => {
|
|||
it('should be able to serialize expression inside component', async () => {
|
||||
const { code } = await renderMarkdown(`<Component>{a}</Component>`, {});
|
||||
|
||||
chai.expect(code).to.equal(`\n<Component>{a}</Component>\n`);
|
||||
chai.expect(code).to.equal(`<Component>{a}</Component>`);
|
||||
});
|
||||
|
||||
it('should be able to serialize expression inside markdown', async () => {
|
||||
|
|
|
@ -36,6 +36,7 @@ interface EventCliSessionInternal extends EventCliSession {
|
|||
config?: ConfigInfo;
|
||||
configKeys?: string[];
|
||||
flags?: string[];
|
||||
optionalIntegrations?: number;
|
||||
}
|
||||
|
||||
function getViteVersion() {
|
||||
|
@ -89,6 +90,8 @@ export function eventCliSession(
|
|||
userConfig?: AstroUserConfig,
|
||||
flags?: Record<string, any>
|
||||
): { eventName: string; payload: EventCliSessionInternal }[] {
|
||||
// Filter out falsy integrations
|
||||
const integrations = userConfig?.integrations?.filter?.(Boolean) ?? [];
|
||||
const configValues = userConfig
|
||||
? {
|
||||
markdownPlugins: [
|
||||
|
@ -96,7 +99,7 @@ export function eventCliSession(
|
|||
userConfig?.markdown?.rehypePlugins ?? [],
|
||||
].flat(1),
|
||||
adapter: userConfig?.adapter?.name ?? null,
|
||||
integrations: userConfig?.integrations?.map((i: any) => i.name) ?? [],
|
||||
integrations: integrations?.map?.((i: any) => i?.name) ?? [],
|
||||
trailingSlash: userConfig?.trailingSlash,
|
||||
build: userConfig?.build
|
||||
? {
|
||||
|
@ -125,6 +128,8 @@ export function eventCliSession(
|
|||
// Config Values
|
||||
config: configValues,
|
||||
flags: cliFlags,
|
||||
// Optional integrations
|
||||
optionalIntegrations: userConfig?.integrations?.length - integrations?.length,
|
||||
};
|
||||
return [{ eventName: EVENT_SESSION, payload }];
|
||||
}
|
||||
|
|
|
@ -411,6 +411,40 @@ describe('Session event', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('config.integrations + optionalIntegrations', () => {
|
||||
it('optional/conditional integrations', () => {
|
||||
const config = {
|
||||
srcDir: 1,
|
||||
integrations: [null, undefined, { name: 'example-integration' }],
|
||||
};
|
||||
const [{ payload }] = events.eventCliSession(
|
||||
{
|
||||
cliCommand: 'dev',
|
||||
astroVersion: '0.0.0',
|
||||
},
|
||||
config
|
||||
);
|
||||
expect(payload.config.integrations).deep.equal(['example-integration']);
|
||||
expect(payload.optionalIntegrations).to.equal(2);
|
||||
});
|
||||
|
||||
it('falsy integrations', () => {
|
||||
const config = {
|
||||
srcDir: 1,
|
||||
integrations: [null, undefined, false],
|
||||
};
|
||||
const [{ payload }] = events.eventCliSession(
|
||||
{
|
||||
cliCommand: 'dev',
|
||||
astroVersion: '0.0.0',
|
||||
},
|
||||
config
|
||||
);
|
||||
expect(payload.config.integrations.length).to.equal(0);
|
||||
expect(payload.optionalIntegrations).to.equal(3);
|
||||
});
|
||||
});
|
||||
|
||||
describe('flags', () => {
|
||||
it('includes cli flags in payload', () => {
|
||||
const config = {};
|
||||
|
|
|
@ -47,14 +47,14 @@ importers:
|
|||
|
||||
examples/basics:
|
||||
specifiers:
|
||||
astro: ^1.0.0-beta.46
|
||||
astro: ^1.0.0-beta.47
|
||||
devDependencies:
|
||||
astro: link:../../packages/astro
|
||||
|
||||
examples/blog:
|
||||
specifiers:
|
||||
'@astrojs/preact': ^0.1.3
|
||||
astro: ^1.0.0-beta.46
|
||||
astro: ^1.0.0-beta.47
|
||||
preact: ^10.7.3
|
||||
dependencies:
|
||||
preact: 10.7.3
|
||||
|
@ -65,7 +65,7 @@ importers:
|
|||
examples/blog-multiple-authors:
|
||||
specifiers:
|
||||
'@astrojs/preact': ^0.1.3
|
||||
astro: ^1.0.0-beta.46
|
||||
astro: ^1.0.0-beta.47
|
||||
preact: ^10.7.3
|
||||
sass: ^1.52.2
|
||||
dependencies:
|
||||
|
@ -77,14 +77,14 @@ importers:
|
|||
|
||||
examples/component:
|
||||
specifiers:
|
||||
astro: ^1.0.0-beta.46
|
||||
astro: ^1.0.0-beta.47
|
||||
devDependencies:
|
||||
astro: link:../../packages/astro
|
||||
|
||||
examples/component/demo:
|
||||
specifiers:
|
||||
'@example/my-component': workspace:*
|
||||
astro: ^1.0.0-beta.46
|
||||
astro: ^1.0.0-beta.47
|
||||
devDependencies:
|
||||
'@example/my-component': link:../packages/my-component
|
||||
astro: link:../../../packages/astro
|
||||
|
@ -100,7 +100,7 @@ importers:
|
|||
'@docsearch/css': ^3.1.0
|
||||
'@docsearch/react': ^3.1.0
|
||||
'@types/react': ^17.0.45
|
||||
astro: ^1.0.0-beta.46
|
||||
astro: ^1.0.0-beta.47
|
||||
preact: ^10.7.3
|
||||
react: ^17.0.2
|
||||
react-dom: ^17.0.2
|
||||
|
@ -119,14 +119,14 @@ importers:
|
|||
|
||||
examples/env-vars:
|
||||
specifiers:
|
||||
astro: ^1.0.0-beta.46
|
||||
astro: ^1.0.0-beta.47
|
||||
devDependencies:
|
||||
astro: link:../../packages/astro
|
||||
|
||||
examples/framework-alpine:
|
||||
specifiers:
|
||||
alpinejs: ^3.10.2
|
||||
astro: ^1.0.0-beta.46
|
||||
astro: ^1.0.0-beta.47
|
||||
dependencies:
|
||||
alpinejs: 3.10.2
|
||||
devDependencies:
|
||||
|
@ -136,7 +136,7 @@ importers:
|
|||
specifiers:
|
||||
'@astrojs/lit': ^0.1.5
|
||||
'@webcomponents/template-shadowroot': ^0.1.0
|
||||
astro: ^1.0.0-beta.46
|
||||
astro: ^1.0.0-beta.47
|
||||
lit: ^2.2.5
|
||||
dependencies:
|
||||
'@webcomponents/template-shadowroot': 0.1.0
|
||||
|
@ -154,7 +154,7 @@ importers:
|
|||
'@astrojs/svelte': ^0.1.4
|
||||
'@astrojs/vue': ^0.1.5
|
||||
'@webcomponents/template-shadowroot': ^0.1.0
|
||||
astro: ^1.0.0-beta.46
|
||||
astro: ^1.0.0-beta.47
|
||||
lit: ^2.2.5
|
||||
preact: ^10.7.3
|
||||
react: ^18.1.0
|
||||
|
@ -183,7 +183,7 @@ importers:
|
|||
examples/framework-preact:
|
||||
specifiers:
|
||||
'@astrojs/preact': ^0.1.3
|
||||
astro: ^1.0.0-beta.46
|
||||
astro: ^1.0.0-beta.47
|
||||
preact: ^10.7.3
|
||||
dependencies:
|
||||
preact: 10.7.3
|
||||
|
@ -196,7 +196,7 @@ importers:
|
|||
'@astrojs/react': ^0.1.3
|
||||
'@types/react': ^18.0.10
|
||||
'@types/react-dom': ^18.0.5
|
||||
astro: ^1.0.0-beta.46
|
||||
astro: ^1.0.0-beta.47
|
||||
react: ^18.1.0
|
||||
react-dom: ^18.1.0
|
||||
dependencies:
|
||||
|
@ -211,7 +211,7 @@ importers:
|
|||
examples/framework-solid:
|
||||
specifiers:
|
||||
'@astrojs/solid-js': ^0.1.4
|
||||
astro: ^1.0.0-beta.46
|
||||
astro: ^1.0.0-beta.47
|
||||
solid-js: ^1.4.3
|
||||
dependencies:
|
||||
solid-js: 1.4.3
|
||||
|
@ -222,7 +222,7 @@ importers:
|
|||
examples/framework-svelte:
|
||||
specifiers:
|
||||
'@astrojs/svelte': ^0.1.4
|
||||
astro: ^1.0.0-beta.46
|
||||
astro: ^1.0.0-beta.47
|
||||
svelte: ^3.48.0
|
||||
dependencies:
|
||||
svelte: 3.48.0
|
||||
|
@ -233,7 +233,7 @@ importers:
|
|||
examples/framework-vue:
|
||||
specifiers:
|
||||
'@astrojs/vue': ^0.1.5
|
||||
astro: ^1.0.0-beta.46
|
||||
astro: ^1.0.0-beta.47
|
||||
vue: ^3.2.36
|
||||
dependencies:
|
||||
vue: 3.2.37
|
||||
|
@ -251,7 +251,7 @@ importers:
|
|||
'@astrojs/tailwind': ^0.2.1
|
||||
'@astrojs/turbolinks': ^0.1.3
|
||||
'@webcomponents/template-shadowroot': ^0.1.0
|
||||
astro: ^1.0.0-beta.46
|
||||
astro: ^1.0.0-beta.47
|
||||
lit: ^2.2.5
|
||||
preact: ^10.7.3
|
||||
react: ^18.1.0
|
||||
|
@ -280,20 +280,20 @@ importers:
|
|||
|
||||
examples/minimal:
|
||||
specifiers:
|
||||
astro: ^1.0.0-beta.46
|
||||
astro: ^1.0.0-beta.47
|
||||
devDependencies:
|
||||
astro: link:../../packages/astro
|
||||
|
||||
examples/non-html-pages:
|
||||
specifiers:
|
||||
astro: ^1.0.0-beta.46
|
||||
astro: ^1.0.0-beta.47
|
||||
devDependencies:
|
||||
astro: link:../../packages/astro
|
||||
|
||||
examples/portfolio:
|
||||
specifiers:
|
||||
'@astrojs/preact': ^0.1.3
|
||||
astro: ^1.0.0-beta.46
|
||||
astro: ^1.0.0-beta.47
|
||||
preact: ^10.7.3
|
||||
sass: ^1.52.2
|
||||
dependencies:
|
||||
|
@ -307,7 +307,7 @@ importers:
|
|||
specifiers:
|
||||
'@astrojs/node': ^0.1.2
|
||||
'@astrojs/svelte': ^0.1.4
|
||||
astro: ^1.0.0-beta.46
|
||||
astro: ^1.0.0-beta.47
|
||||
concurrently: ^7.2.1
|
||||
lightcookie: ^1.0.25
|
||||
svelte: ^3.48.0
|
||||
|
@ -326,14 +326,14 @@ importers:
|
|||
|
||||
examples/starter:
|
||||
specifiers:
|
||||
astro: ^1.0.0-beta.46
|
||||
astro: ^1.0.0-beta.47
|
||||
devDependencies:
|
||||
astro: link:../../packages/astro
|
||||
|
||||
examples/subpath:
|
||||
specifiers:
|
||||
'@astrojs/react': ^0.1.3
|
||||
astro: ^1.0.0-beta.46
|
||||
astro: ^1.0.0-beta.47
|
||||
react: ^18.1.0
|
||||
react-dom: ^18.1.0
|
||||
sass: ^1.52.2
|
||||
|
@ -352,7 +352,7 @@ importers:
|
|||
'@astrojs/react': ^0.1.3
|
||||
'@astrojs/svelte': ^0.1.4
|
||||
'@astrojs/vue': ^0.1.5
|
||||
astro: ^1.0.0-beta.46
|
||||
astro: ^1.0.0-beta.47
|
||||
preact: ^10.7.3
|
||||
react: ^18.1.0
|
||||
react-dom: ^18.1.0
|
||||
|
@ -375,7 +375,7 @@ importers:
|
|||
examples/with-markdown-plugins:
|
||||
specifiers:
|
||||
'@astrojs/markdown-remark': ^0.11.2
|
||||
astro: ^1.0.0-beta.46
|
||||
astro: ^1.0.0-beta.47
|
||||
hast-util-select: 5.0.1
|
||||
rehype-autolink-headings: ^6.1.1
|
||||
rehype-slug: ^5.0.1
|
||||
|
@ -393,7 +393,7 @@ importers:
|
|||
examples/with-markdown-shiki:
|
||||
specifiers:
|
||||
'@astrojs/markdown-remark': ^0.11.2
|
||||
astro: ^1.0.0-beta.46
|
||||
astro: ^1.0.0-beta.47
|
||||
devDependencies:
|
||||
'@astrojs/markdown-remark': link:../../packages/markdown/remark
|
||||
astro: link:../../packages/astro
|
||||
|
@ -408,7 +408,7 @@ importers:
|
|||
'@nanostores/preact': ^0.1.3
|
||||
'@nanostores/react': ^0.1.5
|
||||
'@nanostores/vue': ^0.4.1
|
||||
astro: ^1.0.0-beta.46
|
||||
astro: ^1.0.0-beta.47
|
||||
nanostores: ^0.5.12
|
||||
preact: ^10.7.3
|
||||
react: ^18.1.0
|
||||
|
@ -436,7 +436,7 @@ importers:
|
|||
examples/with-tailwindcss:
|
||||
specifiers:
|
||||
'@astrojs/tailwind': ^0.2.1
|
||||
astro: ^1.0.0-beta.46
|
||||
astro: ^1.0.0-beta.47
|
||||
autoprefixer: ^10.4.7
|
||||
canvas-confetti: ^1.5.1
|
||||
postcss: ^8.4.14
|
||||
|
@ -451,7 +451,7 @@ importers:
|
|||
|
||||
examples/with-vite-plugin-pwa:
|
||||
specifiers:
|
||||
astro: ^1.0.0-beta.46
|
||||
astro: ^1.0.0-beta.47
|
||||
vite-plugin-pwa: 0.11.11
|
||||
workbox-window: ^6.5.3
|
||||
devDependencies:
|
||||
|
@ -1832,6 +1832,11 @@ importers:
|
|||
specifiers:
|
||||
astro: workspace:*
|
||||
astro-scripts: workspace:*
|
||||
sitemap: ^7.1.1
|
||||
zod: ^3.17.3
|
||||
dependencies:
|
||||
sitemap: 7.1.1
|
||||
zod: 3.17.3
|
||||
devDependencies:
|
||||
astro: link:../../astro
|
||||
astro-scripts: link:../../../scripts
|
||||
|
@ -6857,6 +6862,12 @@ packages:
|
|||
'@types/node': 17.0.41
|
||||
dev: false
|
||||
|
||||
/@types/sax/1.2.4:
|
||||
resolution: {integrity: sha512-pSAff4IAxJjfAXUG6tFkO7dsSbTmf8CtUpfhhZ5VhkRpC4628tJhh3+V6H1E+/Gs9piSzYKT5yzHO5M4GG9jkw==}
|
||||
dependencies:
|
||||
'@types/node': 17.0.41
|
||||
dev: false
|
||||
|
||||
/@types/scheduler/0.16.2:
|
||||
resolution: {integrity: sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==}
|
||||
|
||||
|
@ -12549,6 +12560,17 @@ packages:
|
|||
resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==}
|
||||
dev: false
|
||||
|
||||
/sitemap/7.1.1:
|
||||
resolution: {integrity: sha512-mK3aFtjz4VdJN0igpIJrinf3EO8U8mxOPsTBzSsy06UtjZQJ3YY3o3Xa7zSc5nMqcMrRwlChHZ18Kxg0caiPBg==}
|
||||
engines: {node: '>=12.0.0', npm: '>=5.6.0'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
'@types/node': 17.0.41
|
||||
'@types/sax': 1.2.4
|
||||
arg: 5.0.2
|
||||
sax: 1.2.4
|
||||
dev: false
|
||||
|
||||
/slash/2.0.0:
|
||||
resolution: {integrity: sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==}
|
||||
engines: {node: '>=6'}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
Date,Commits (24hr),Issues (24hr),Issues:BUG (24hr),Issues:RFC (24hr),Issues:DOC (24hr),PRs (24hr),Open PRs,Open Issues,Bugs: Needs Triage,Bugs: Accepted,RFC: In Progress,RFC: Accepted,Date (ISO)
|
||||
"Friday, June 17, 2022",17,7,6,0,0,9,16,68,39,20,0,0,"2022-06-17T12:02:08.929Z"
|
||||
"Thursday, June 16, 2022",6,1,1,0,0,3,15,62,34,20,0,0,"2022-06-16T12:02:16.472Z"
|
||||
"Wednesday, June 15, 2022",15,3,3,0,0,8,16,64,35,21,0,0,"2022-06-15T12:02:03.380Z"
|
||||
"Tuesday, June 14, 2022",2,3,3,0,0,5,17,64,35,21,0,0,"2022-06-14T12:02:10.537Z"
|
||||
|
|
|
Loading…
Reference in a new issue