}} */
+ let manifest = undefined;
+
+ before(async () => {
+ fixture = await loadFixture({ root: './fixtures/content-intellisense/' });
+ await fixture.build();
+
+ collectionsDir = await fixture.readdir('../.astro/collections');
+ manifest = JSON.parse(await fixture.readFile('../.astro/collections/collections.json'));
+ });
+
+ it('generate JSON schemas for content collections', async () => {
+ assert.deepEqual(collectionsDir.includes('blog-cc.schema.json'), true);
+ });
+
+ it('generate JSON schemas for content layer', async () => {
+ assert.deepEqual(collectionsDir.includes('blog-cl.schema.json'), true);
+ });
+
+ it('manifest exists', async () => {
+ assert.notEqual(manifest, undefined);
+ });
+
+ it('manifest has content collections', async () => {
+ const manifestCollections = manifest.collections.map((collection) => collection.name);
+ assert.equal(
+ manifestCollections.includes('blog-cc'),
+ true,
+ "Expected 'blog-cc' collection in manifest",
+ );
+ });
+
+ it('manifest has content layer', async () => {
+ const manifestCollections = manifest.collections.map((collection) => collection.name);
+ assert.equal(
+ manifestCollections.includes('blog-cl'),
+ true,
+ "Expected 'blog-cl' collection in manifest",
+ );
+ });
+
+ it('has entries for content collections', async () => {
+ const collectionEntries = Object.entries(manifest.entries).filter((entry) =>
+ entry[0].includes(
+ '/astro/packages/astro/test/fixtures/content-intellisense/src/content/blog-cc/',
+ ),
+ );
+ assert.equal(collectionEntries.length, 3, "Expected 3 entries for 'blog-cc' collection");
+ assert.equal(
+ collectionEntries.every((entry) => entry[1] === 'blog-cc'),
+ true,
+ "Expected 3 entries for 'blog-cc' collection to have 'blog-cc' as collection",
+ );
+ });
+
+ it('has entries for content layer', async () => {
+ const collectionEntries = Object.entries(manifest.entries).filter((entry) =>
+ entry[0].includes('/astro/packages/astro/test/fixtures/content-intellisense/src/blog-cl/'),
+ );
+
+ assert.equal(collectionEntries.length, 3, "Expected 3 entries for 'blog-cl' collection");
+ assert.equal(
+ collectionEntries.every((entry) => entry[1] === 'blog-cl'),
+ true,
+ "Expected 3 entries for 'blog-cl' collection to have 'blog-cl' as collection name",
+ );
+ });
+});
diff --git a/packages/astro/test/content-layer-markdoc.test.js b/packages/astro/test/content-layer-markdoc.test.js
new file mode 100644
index 000000000000..c5279b9e7522
--- /dev/null
+++ b/packages/astro/test/content-layer-markdoc.test.js
@@ -0,0 +1,88 @@
+import assert from 'node:assert/strict';
+import { after, before, describe, it } from 'node:test';
+import * as cheerio from 'cheerio';
+import { loadFixture } from './test-utils.js';
+
+describe('Content layer markdoc', () => {
+ let fixture;
+
+ before(async () => {
+ fixture = await loadFixture({
+ root: './fixtures/content-layer-markdoc/',
+ });
+ });
+
+ describe('dev', () => {
+ let devServer;
+
+ before(async () => {
+ devServer = await fixture.startDevServer();
+ });
+
+ after(async () => {
+ await devServer.stop();
+ });
+
+ it('renders content - with components', async () => {
+ const res = await fixture.fetch('/');
+ const html = await res.text();
+
+ renderComponentsChecks(html);
+ });
+
+ it('renders content - with components inside partials', async () => {
+ const res = await fixture.fetch('/');
+ const html = await res.text();
+
+ renderComponentsInsidePartialsChecks(html);
+ });
+ });
+
+ describe('build', () => {
+ before(async () => {
+ await fixture.build();
+ });
+
+ it('renders content - with components', async () => {
+ const html = await fixture.readFile('/index.html');
+
+ renderComponentsChecks(html);
+ });
+
+ it('renders content - with components inside partials', async () => {
+ const html = await fixture.readFile('/index.html');
+
+ renderComponentsInsidePartialsChecks(html);
+ });
+ });
+});
+
+/** @param {string} html */
+function renderComponentsChecks(html) {
+ const $ = cheerio.load(html);
+ const h2 = $('h2');
+ assert.equal(h2.text(), 'Post with components');
+
+ // Renders custom shortcode component
+ const marquee = $('marquee');
+ assert.notEqual(marquee, null);
+ assert.equal(marquee.attr('data-custom-marquee'), '');
+
+ // Renders Astro Code component
+ const pre = $('pre');
+ assert.notEqual(pre, null);
+ assert.ok(pre.hasClass('github-dark'));
+ assert.ok(pre.hasClass('astro-code'));
+}
+
+/** @param {string} html */
+function renderComponentsInsidePartialsChecks(html) {
+ const $ = cheerio.load(html);
+ // renders Counter.tsx
+ const button = $('#counter');
+ assert.equal(button.text(), '1');
+
+ // renders DeeplyNested.astro
+ const deeplyNested = $('#deeply-nested');
+ assert.equal(deeplyNested.text(), 'Deeply nested partial');
+}
diff --git a/packages/astro/test/content-layer-render.test.js b/packages/astro/test/content-layer-render.test.js
new file mode 100644
index 000000000000..fa743e719ca4
--- /dev/null
+++ b/packages/astro/test/content-layer-render.test.js
@@ -0,0 +1,45 @@
+import assert from 'node:assert/strict';
+import { after, before, describe, it } from 'node:test';
+import { loadFixture } from './test-utils.js';
+
+describe('Content Layer MDX rendering dev', () => {
+ /** @type {import("./test-utils.js").Fixture} */
+ let fixture;
+
+ let devServer;
+ before(async () => {
+ fixture = await loadFixture({
+ root: './fixtures/content-layer-rendering/',
+ });
+ devServer = await fixture.startDevServer();
+ });
+
+ after(async () => {
+ devServer?.stop();
+ });
+
+ it('Render an MDX file', async () => {
+ const html = await fixture.fetch('/reptiles/iguana').then((r) => r.text());
+
+ assert.match(html, /Iguana/);
+ assert.match(html, /This is a rendered entry/);
+ });
+});
+
+describe('Content Layer MDX rendering build', () => {
+ /** @type {import("./test-utils.js").Fixture} */
+ let fixture;
+ before(async () => {
+ fixture = await loadFixture({
+ root: './fixtures/content-layer-rendering/',
+ });
+ await fixture.build();
+ });
+
+ it('Render an MDX file', async () => {
+ const html = await fixture.readFile('/reptiles/iguana/index.html');
+
+ assert.match(html, /Iguana/);
+ assert.match(html, /This is a rendered entry/);
+ });
+});
diff --git a/packages/astro/test/content-layer.test.js b/packages/astro/test/content-layer.test.js
new file mode 100644
index 000000000000..41c05206bad2
--- /dev/null
+++ b/packages/astro/test/content-layer.test.js
@@ -0,0 +1,279 @@
+import assert from 'node:assert/strict';
+import { promises as fs } from 'node:fs';
+import { sep } from 'node:path';
+import { sep as posixSep } from 'node:path/posix';
+import { after, before, describe, it } from 'node:test';
+import * as devalue from 'devalue';
+
+import { loadFixture } from './test-utils.js';
+describe('Content Layer', () => {
+ /** @type {import("./test-utils.js").Fixture} */
+ let fixture;
+
+ before(async () => {
+ fixture = await loadFixture({ root: './fixtures/content-layer/' });
+ });
+
+ describe('Build', () => {
+ let json;
+ before(async () => {
+ fixture = await loadFixture({ root: './fixtures/content-layer/' });
+ await fs
+ .unlink(new URL('./node_modules/.astro/data-store.json', fixture.config.root))
+ .catch(() => {});
+ await fixture.build();
+ const rawJson = await fixture.readFile('/collections.json');
+ json = devalue.parse(rawJson);
+ });
+
+ it('Returns custom loader collection', async () => {
+ assert.ok(json.hasOwnProperty('customLoader'));
+ assert.ok(Array.isArray(json.customLoader));
+
+ const item = json.customLoader[0];
+ assert.deepEqual(item, {
+ id: '1',
+ collection: 'blog',
+ data: {
+ userId: 1,
+ id: 1,
+ title: 'sunt aut facere repellat provident occaecati excepturi optio reprehenderit',
+ body: 'quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto',
+ },
+ });
+ });
+
+ it('filters collection items', async () => {
+ assert.ok(json.hasOwnProperty('customLoader'));
+ assert.ok(Array.isArray(json.customLoader));
+ assert.equal(json.customLoader.length, 5);
+ });
+
+ it('Returns `file()` loader collection', async () => {
+ assert.ok(json.hasOwnProperty('fileLoader'));
+ assert.ok(Array.isArray(json.fileLoader));
+
+ const ids = json.fileLoader.map((item) => item.data.id);
+ assert.deepEqual(ids, [
+ 'labrador-retriever',
+ 'german-shepherd',
+ 'golden-retriever',
+ 'french-bulldog',
+ 'bulldog',
+ 'beagle',
+ 'poodle',
+ 'rottweiler',
+ 'german-shorthaired-pointer',
+ 'yorkshire-terrier',
+ 'boxer',
+ 'dachshund',
+ 'siberian-husky',
+ 'great-dane',
+ 'doberman-pinscher',
+ 'australian-shepherd',
+ 'miniature-schnauzer',
+ 'cavalier-king-charles-spaniel',
+ 'shih-tzu',
+ 'boston-terrier',
+ 'bernese-mountain-dog',
+ 'pomeranian',
+ 'havanese',
+ 'english-springer-spaniel',
+ 'shetland-sheepdog',
+ ]);
+ });
+
+ it('Returns data entry by id', async () => {
+ assert.ok(json.hasOwnProperty('dataEntry'));
+ assert.equal(json.dataEntry.filePath?.split(sep).join(posixSep), 'src/data/dogs.json');
+ delete json.dataEntry.filePath;
+ assert.deepEqual(json.dataEntry, {
+ id: 'beagle',
+ collection: 'dogs',
+ data: {
+ breed: 'Beagle',
+ id: 'beagle',
+ size: 'Small to Medium',
+ origin: 'England',
+ lifespan: '12-15 years',
+ temperament: ['Friendly', 'Curious', 'Merry'],
+ },
+ });
+ });
+
+ it('returns collection from a simple loader', async () => {
+ assert.ok(json.hasOwnProperty('simpleLoader'));
+ assert.ok(Array.isArray(json.simpleLoader));
+
+ const item = json.simpleLoader[0];
+ assert.deepEqual(item, {
+ id: 'siamese',
+ collection: 'cats',
+ data: {
+ breed: 'Siamese',
+ id: 'siamese',
+ size: 'Medium',
+ origin: 'Thailand',
+ lifespan: '15 years',
+ temperament: ['Active', 'Affectionate', 'Social', 'Playful'],
+ },
+ });
+ });
+
+ it('transforms a reference id to a reference object', async () => {
+ assert.ok(json.hasOwnProperty('entryWithReference'));
+ assert.deepEqual(json.entryWithReference.data.cat, { collection: 'cats', id: 'tabby' });
+ });
+
+ it('can store Date objects', async () => {
+ assert.ok(json.entryWithReference.data.publishedDate instanceof Date);
+ });
+
+ it('returns a referenced entry', async () => {
+ assert.ok(json.hasOwnProperty('referencedEntry'));
+ assert.deepEqual(json.referencedEntry, {
+ collection: 'cats',
+ data: {
+ breed: 'Tabby',
+ id: 'tabby',
+ size: 'Medium',
+ origin: 'Egypt',
+ lifespan: '15 years',
+ temperament: ['Curious', 'Playful', 'Independent'],
+ },
+ id: 'tabby',
+ });
+ });
+
+ it('updates the store on new builds', async () => {
+ assert.equal(json.increment.data.lastValue, 1);
+ await fixture.build();
+ const newJson = devalue.parse(await fixture.readFile('/collections.json'));
+ assert.equal(newJson.increment.data.lastValue, 2);
+ });
+
+ it('clears the store on new build with force flag', async () => {
+ let newJson = devalue.parse(await fixture.readFile('/collections.json'));
+ assert.equal(newJson.increment.data.lastValue, 2);
+ await fixture.build({ force: true }, {});
+ newJson = devalue.parse(await fixture.readFile('/collections.json'));
+ assert.equal(newJson.increment.data.lastValue, 1);
+ });
+
+ it('clears the store on new build if the config has changed', async () => {
+ let newJson = devalue.parse(await fixture.readFile('/collections.json'));
+ assert.equal(newJson.increment.data.lastValue, 1);
+ await fixture.editFile('src/content/config.ts', (prev) => {
+ return `${prev}\nexport const foo = 'bar';`;
+ });
+ await fixture.build();
+ newJson = devalue.parse(await fixture.readFile('/collections.json'));
+ assert.equal(newJson.increment.data.lastValue, 1);
+ await fixture.resetAllFiles();
+ });
+ });
+
+ describe('Dev', () => {
+ let devServer;
+ let json;
+ before(async () => {
+ devServer = await fixture.startDevServer();
+ const rawJsonResponse = await fixture.fetch('/collections.json');
+ const rawJson = await rawJsonResponse.text();
+ json = devalue.parse(rawJson);
+ });
+
+ after(async () => {
+ devServer?.stop();
+ });
+
+ it('Returns custom loader collection', async () => {
+ assert.ok(json.hasOwnProperty('customLoader'));
+ assert.ok(Array.isArray(json.customLoader));
+
+ const item = json.customLoader[0];
+ assert.deepEqual(item, {
+ id: '1',
+ collection: 'blog',
+ data: {
+ userId: 1,
+ id: 1,
+ title: 'sunt aut facere repellat provident occaecati excepturi optio reprehenderit',
+ body: 'quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto',
+ },
+ });
+ });
+
+ it('Returns `file()` loader collection', async () => {
+ assert.ok(json.hasOwnProperty('fileLoader'));
+ assert.ok(Array.isArray(json.fileLoader));
+
+ const ids = json.fileLoader.map((item) => item.data.id);
+ assert.deepEqual(ids, [
+ 'labrador-retriever',
+ 'german-shepherd',
+ 'golden-retriever',
+ 'french-bulldog',
+ 'bulldog',
+ 'beagle',
+ 'poodle',
+ 'rottweiler',
+ 'german-shorthaired-pointer',
+ 'yorkshire-terrier',
+ 'boxer',
+ 'dachshund',
+ 'siberian-husky',
+ 'great-dane',
+ 'doberman-pinscher',
+ 'australian-shepherd',
+ 'miniature-schnauzer',
+ 'cavalier-king-charles-spaniel',
+ 'shih-tzu',
+ 'boston-terrier',
+ 'bernese-mountain-dog',
+ 'pomeranian',
+ 'havanese',
+ 'english-springer-spaniel',
+ 'shetland-sheepdog',
+ ]);
+ });
+
+ it('Returns data entry by id', async () => {
+ assert.ok(json.hasOwnProperty('dataEntry'));
+ assert.equal(json.dataEntry.filePath?.split(sep).join(posixSep), 'src/data/dogs.json');
+ delete json.dataEntry.filePath;
+ assert.deepEqual(json.dataEntry, {
+ id: 'beagle',
+ collection: 'dogs',
+ data: {
+ breed: 'Beagle',
+ id: 'beagle',
+ size: 'Small to Medium',
+ origin: 'England',
+ lifespan: '12-15 years',
+ temperament: ['Friendly', 'Curious', 'Merry'],
+ },
+ });
+ });
+
+ it('updates collection when data file is changed', async () => {
+ const rawJsonResponse = await fixture.fetch('/collections.json');
+ const initialJson = devalue.parse(await rawJsonResponse.text());
+ assert.equal(initialJson.fileLoader[0].data.temperament.includes('Bouncy'), false);
+
+ await fixture.editFile('/src/data/dogs.json', (prev) => {
+ const data = JSON.parse(prev);
+ data[0].temperament.push('Bouncy');
+ return JSON.stringify(data, null, 2);
+ });
+
+ // Writes are debounced to 500ms
+ await new Promise((r) => setTimeout(r, 700));
+
+ const updatedJsonResponse = await fixture.fetch('/collections.json');
+ const updated = devalue.parse(await updatedJsonResponse.text());
+ assert.ok(updated.fileLoader[0].data.temperament.includes('Bouncy'));
+ await fixture.resetAllFiles();
+ });
+ });
+});
diff --git a/packages/astro/test/fixtures/content-collections/astro.config.mjs b/packages/astro/test/fixtures/content-collections/astro.config.mjs
index aa89463ab72b..911cb3a99881 100644
--- a/packages/astro/test/fixtures/content-collections/astro.config.mjs
+++ b/packages/astro/test/fixtures/content-collections/astro.config.mjs
@@ -4,4 +4,7 @@ import { defineConfig } from 'astro/config';
// https://astro.build/config
export default defineConfig({
integrations: [mdx()],
+ experimental: {
+ contentIntellisense: true
+ }
});
diff --git a/packages/astro/test/fixtures/content-intellisense/astro.config.mjs b/packages/astro/test/fixtures/content-intellisense/astro.config.mjs
new file mode 100644
index 000000000000..f6358a896fab
--- /dev/null
+++ b/packages/astro/test/fixtures/content-intellisense/astro.config.mjs
@@ -0,0 +1,12 @@
+import markdoc from "@astrojs/markdoc";
+import mdx from '@astrojs/mdx';
+import { defineConfig } from 'astro/config';
+
+// https://astro.build/config
+export default defineConfig({
+ integrations: [mdx(), markdoc()],
+ experimental: {
+ contentLayer: true,
+ contentIntellisense: true
+ }
+});
diff --git a/packages/astro/test/fixtures/content-intellisense/package.json b/packages/astro/test/fixtures/content-intellisense/package.json
new file mode 100644
index 000000000000..1e22bf9946f6
--- /dev/null
+++ b/packages/astro/test/fixtures/content-intellisense/package.json
@@ -0,0 +1,10 @@
+{
+ "name": "@test/content-intellisense",
+ "version": "0.0.0",
+ "private": true,
+ "dependencies": {
+ "astro": "workspace:*",
+ "@astrojs/mdx": "workspace:*",
+ "@astrojs/markdoc": "workspace:*"
+ }
+}
diff --git a/packages/astro/test/fixtures/content-intellisense/src/blog-cl/entry.md b/packages/astro/test/fixtures/content-intellisense/src/blog-cl/entry.md
new file mode 100644
index 000000000000..caaa4ebeff82
--- /dev/null
+++ b/packages/astro/test/fixtures/content-intellisense/src/blog-cl/entry.md
@@ -0,0 +1,3 @@
+---
+title: "Markdown"
+---
diff --git a/packages/astro/test/fixtures/content-intellisense/src/blog-cl/entry2.mdx b/packages/astro/test/fixtures/content-intellisense/src/blog-cl/entry2.mdx
new file mode 100644
index 000000000000..0872819c8cf1
--- /dev/null
+++ b/packages/astro/test/fixtures/content-intellisense/src/blog-cl/entry2.mdx
@@ -0,0 +1,3 @@
+---
+title: "MDX"
+---
diff --git a/packages/astro/test/fixtures/content-intellisense/src/blog-cl/entry3.mdoc b/packages/astro/test/fixtures/content-intellisense/src/blog-cl/entry3.mdoc
new file mode 100644
index 000000000000..e13eaa2f6ac8
--- /dev/null
+++ b/packages/astro/test/fixtures/content-intellisense/src/blog-cl/entry3.mdoc
@@ -0,0 +1,3 @@
+---
+title: "Markdoc"
+---
diff --git a/packages/astro/test/fixtures/content-intellisense/src/content/blog-cc/entry.md b/packages/astro/test/fixtures/content-intellisense/src/content/blog-cc/entry.md
new file mode 100644
index 000000000000..caaa4ebeff82
--- /dev/null
+++ b/packages/astro/test/fixtures/content-intellisense/src/content/blog-cc/entry.md
@@ -0,0 +1,3 @@
+---
+title: "Markdown"
+---
diff --git a/packages/astro/test/fixtures/content-intellisense/src/content/blog-cc/entry2.mdx b/packages/astro/test/fixtures/content-intellisense/src/content/blog-cc/entry2.mdx
new file mode 100644
index 000000000000..0872819c8cf1
--- /dev/null
+++ b/packages/astro/test/fixtures/content-intellisense/src/content/blog-cc/entry2.mdx
@@ -0,0 +1,3 @@
+---
+title: "MDX"
+---
diff --git a/packages/astro/test/fixtures/content-intellisense/src/content/blog-cc/entry3.mdoc b/packages/astro/test/fixtures/content-intellisense/src/content/blog-cc/entry3.mdoc
new file mode 100644
index 000000000000..e13eaa2f6ac8
--- /dev/null
+++ b/packages/astro/test/fixtures/content-intellisense/src/content/blog-cc/entry3.mdoc
@@ -0,0 +1,3 @@
+---
+title: "Markdoc"
+---
diff --git a/packages/astro/test/fixtures/content-intellisense/src/content/config.ts b/packages/astro/test/fixtures/content-intellisense/src/content/config.ts
new file mode 100644
index 000000000000..64120adabe20
--- /dev/null
+++ b/packages/astro/test/fixtures/content-intellisense/src/content/config.ts
@@ -0,0 +1,24 @@
+import { glob } from 'astro/loaders';
+import { defineCollection, z } from 'astro:content';
+
+const blogCC = defineCollection({
+ type: 'content',
+ schema: z.object({
+ title: z.string(),
+ description: z.string().optional(),
+ }),
+});
+
+const blogCL = defineCollection({
+ // By default the ID is a slug, generated from the path of the file relative to `base`
+ loader: glob({ pattern: "**/*", base: "./src/blog-cl" }),
+ schema: z.object({
+ title: z.string(),
+ description: z.string().optional(),
+ }),
+});
+
+export const collections = {
+ "blog-cc": blogCC,
+ "blog-cl": blogCL,
+};
diff --git a/packages/astro/test/fixtures/content-intellisense/src/utils.js b/packages/astro/test/fixtures/content-intellisense/src/utils.js
new file mode 100644
index 000000000000..3a6244327862
--- /dev/null
+++ b/packages/astro/test/fixtures/content-intellisense/src/utils.js
@@ -0,0 +1,8 @@
+export function stripRenderFn(entryWithRender) {
+ const { render, ...entry } = entryWithRender;
+ return entry;
+}
+
+export function stripAllRenderFn(collection = []) {
+ return collection.map(stripRenderFn);
+}
diff --git a/packages/astro/test/fixtures/content-layer-markdoc/astro.config.mjs b/packages/astro/test/fixtures/content-layer-markdoc/astro.config.mjs
new file mode 100644
index 000000000000..bbb19ad302db
--- /dev/null
+++ b/packages/astro/test/fixtures/content-layer-markdoc/astro.config.mjs
@@ -0,0 +1,9 @@
+import markdoc from '@astrojs/markdoc';
+import preact from '@astrojs/preact';
+import { defineConfig } from 'astro/config';
+
+// https://astro.build/config
+export default defineConfig({
+ integrations: [markdoc(), preact()],
+ experimental: { contentLayer: true }
+});
diff --git a/packages/astro/test/fixtures/content-layer-markdoc/content/_nested.mdoc b/packages/astro/test/fixtures/content-layer-markdoc/content/_nested.mdoc
new file mode 100644
index 000000000000..68f529280124
--- /dev/null
+++ b/packages/astro/test/fixtures/content-layer-markdoc/content/_nested.mdoc
@@ -0,0 +1,3 @@
+Render components from a deeply nested partial:
+
+{% deeply-nested /%}
diff --git a/packages/astro/test/fixtures/content-layer-markdoc/content/blog/_counter.mdoc b/packages/astro/test/fixtures/content-layer-markdoc/content/blog/_counter.mdoc
new file mode 100644
index 000000000000..4a015695c68e
--- /dev/null
+++ b/packages/astro/test/fixtures/content-layer-markdoc/content/blog/_counter.mdoc
@@ -0,0 +1,7 @@
+# Hello from a partial!
+
+Render a component from a partial:
+
+{% counter /%}
+
+{% partial file="../_nested.mdoc" /%}
diff --git a/packages/astro/test/fixtures/content-layer-markdoc/content/blog/with-components.mdoc b/packages/astro/test/fixtures/content-layer-markdoc/content/blog/with-components.mdoc
new file mode 100644
index 000000000000..eb7d20426e59
--- /dev/null
+++ b/packages/astro/test/fixtures/content-layer-markdoc/content/blog/with-components.mdoc
@@ -0,0 +1,19 @@
+---
+title: Post with components
+---
+
+## Post with components
+
+This uses a custom marquee component with a shortcode:
+
+{% marquee-element direction="right" %}
+I'm a marquee too!
+{% /marquee-element %}
+
+{% partial file="_counter.mdoc" /%}
+
+And a code component for code blocks:
+
+```js
+const isRenderedWithShiki = true;
+```
diff --git a/packages/astro/test/fixtures/content-layer-markdoc/markdoc.config.ts b/packages/astro/test/fixtures/content-layer-markdoc/markdoc.config.ts
new file mode 100644
index 000000000000..6093ec5938a5
--- /dev/null
+++ b/packages/astro/test/fixtures/content-layer-markdoc/markdoc.config.ts
@@ -0,0 +1,32 @@
+import { Markdoc, component, defineMarkdocConfig } from '@astrojs/markdoc/config';
+
+export default defineMarkdocConfig({
+ nodes: {
+ fence: {
+ render: component('./src/components/Code.astro'),
+ attributes: {
+ language: { type: String },
+ content: { type: String },
+ },
+ },
+ },
+ tags: {
+ 'marquee-element': {
+ render: component('./src/components/CustomMarquee.astro'),
+ attributes: {
+ direction: {
+ type: String,
+ default: 'left',
+ matches: ['left', 'right', 'up', 'down'],
+ errorLevel: 'critical',
+ },
+ },
+ },
+ counter: {
+ render: component('./src/components/CounterWrapper.astro'),
+ },
+ 'deeply-nested': {
+ render: component('./src/components/DeeplyNested.astro'),
+ },
+ },
+});
diff --git a/packages/astro/test/fixtures/content-layer-markdoc/package.json b/packages/astro/test/fixtures/content-layer-markdoc/package.json
new file mode 100644
index 000000000000..91ca2f8c9c00
--- /dev/null
+++ b/packages/astro/test/fixtures/content-layer-markdoc/package.json
@@ -0,0 +1,11 @@
+{
+ "name": "@test/content-layer-markdoc",
+ "version": "0.0.0",
+ "private": true,
+ "dependencies": {
+ "@astrojs/markdoc": "workspace:*",
+ "@astrojs/preact": "workspace:*",
+ "astro": "workspace:*",
+ "preact": "^10.23.1"
+ }
+}
\ No newline at end of file
diff --git a/packages/astro/test/fixtures/content-layer-markdoc/src/components/Code.astro b/packages/astro/test/fixtures/content-layer-markdoc/src/components/Code.astro
new file mode 100644
index 000000000000..18bf1399f22e
--- /dev/null
+++ b/packages/astro/test/fixtures/content-layer-markdoc/src/components/Code.astro
@@ -0,0 +1,12 @@
+---
+import { Code } from 'astro/components';
+
+type Props = {
+ content: string;
+ language: string;
+}
+
+const { content, language } = Astro.props as Props;
+---
+
+
diff --git a/packages/astro/test/fixtures/content-layer-markdoc/src/components/Counter.tsx b/packages/astro/test/fixtures/content-layer-markdoc/src/components/Counter.tsx
new file mode 100644
index 000000000000..f1e239718cf8
--- /dev/null
+++ b/packages/astro/test/fixtures/content-layer-markdoc/src/components/Counter.tsx
@@ -0,0 +1,10 @@
+import { useState } from 'preact/hooks';
+
+export default function Counter() {
+ const [count, setCount] = useState(1);
+ return (
+ setCount(count + 1)}>
+ {count}
+
+ );
+}
diff --git a/packages/astro/test/fixtures/content-layer-markdoc/src/components/CounterWrapper.astro b/packages/astro/test/fixtures/content-layer-markdoc/src/components/CounterWrapper.astro
new file mode 100644
index 000000000000..e45ac6438152
--- /dev/null
+++ b/packages/astro/test/fixtures/content-layer-markdoc/src/components/CounterWrapper.astro
@@ -0,0 +1,5 @@
+---
+import Counter from './Counter';
+---
+
+
diff --git a/packages/astro/test/fixtures/content-layer-markdoc/src/components/CustomMarquee.astro b/packages/astro/test/fixtures/content-layer-markdoc/src/components/CustomMarquee.astro
new file mode 100644
index 000000000000..3108b997354c
--- /dev/null
+++ b/packages/astro/test/fixtures/content-layer-markdoc/src/components/CustomMarquee.astro
@@ -0,0 +1 @@
+
diff --git a/packages/astro/test/fixtures/content-layer-markdoc/src/components/DeeplyNested.astro b/packages/astro/test/fixtures/content-layer-markdoc/src/components/DeeplyNested.astro
new file mode 100644
index 000000000000..eb23f675a0f6
--- /dev/null
+++ b/packages/astro/test/fixtures/content-layer-markdoc/src/components/DeeplyNested.astro
@@ -0,0 +1,5 @@
+---
+
+---
+
+Deeply nested partial
diff --git a/packages/astro/test/fixtures/content-layer-markdoc/src/content/config.ts b/packages/astro/test/fixtures/content-layer-markdoc/src/content/config.ts
new file mode 100644
index 000000000000..18ead9aa161f
--- /dev/null
+++ b/packages/astro/test/fixtures/content-layer-markdoc/src/content/config.ts
@@ -0,0 +1,11 @@
+import { defineCollection } from 'astro:content';
+import { glob } from 'astro/loaders';
+
+const blog = defineCollection({
+ loader: glob({
+ pattern: '*.mdoc',
+ base: 'content/blog',
+ }),
+});
+
+export const collections = { blog };
diff --git a/packages/astro/test/fixtures/content-layer-markdoc/src/pages/index.astro b/packages/astro/test/fixtures/content-layer-markdoc/src/pages/index.astro
new file mode 100644
index 000000000000..5c7747eef923
--- /dev/null
+++ b/packages/astro/test/fixtures/content-layer-markdoc/src/pages/index.astro
@@ -0,0 +1,19 @@
+---
+import { getEntry, render } from "astro:content";
+
+const post = await getEntry('blog', 'with-components');
+const { Content } = await render(post);
+---
+
+
+
+
+
+
+
+ Content
+
+
+
+
+
diff --git a/packages/astro/test/fixtures/content-layer-rendering/.gitignore b/packages/astro/test/fixtures/content-layer-rendering/.gitignore
new file mode 100644
index 000000000000..16d3c4dbbfec
--- /dev/null
+++ b/packages/astro/test/fixtures/content-layer-rendering/.gitignore
@@ -0,0 +1 @@
+.cache
diff --git a/packages/astro/test/fixtures/content-layer-rendering/astro.config.mjs b/packages/astro/test/fixtures/content-layer-rendering/astro.config.mjs
new file mode 100644
index 000000000000..c3fd1366a07a
--- /dev/null
+++ b/packages/astro/test/fixtures/content-layer-rendering/astro.config.mjs
@@ -0,0 +1,17 @@
+import mdx from '@astrojs/mdx';
+import { defineConfig } from 'astro/config';
+import { fileURLToPath } from 'node:url';
+
+export default defineConfig({
+ integrations: [mdx()],
+ vite: {
+ resolve: {
+ alias: {
+ '@images': fileURLToPath(new URL('./images', import.meta.url))
+ }
+ },
+ },
+ experimental: {
+ contentLayer: true,
+ },
+});
diff --git a/packages/astro/test/fixtures/content-layer-rendering/content-outside-src-mdx/iguana.mdx b/packages/astro/test/fixtures/content-layer-rendering/content-outside-src-mdx/iguana.mdx
new file mode 100644
index 000000000000..1266a73753b9
--- /dev/null
+++ b/packages/astro/test/fixtures/content-layer-rendering/content-outside-src-mdx/iguana.mdx
@@ -0,0 +1,16 @@
+---
+title: Iguana
+description: 'Introduction to Iguana.'
+publishedDate: 'Sat May 21 2022 00:00:00 GMT-0400 (Eastern Daylight Time)'
+tags: [cats, felines]
+---
+
+import H2 from "../src/components/H2.astro";
+
+Iguana
+
+### Iguana
+
+This is a rendered entry
+
+![file](./shuttle.jpg)
diff --git a/packages/astro/test/fixtures/content-layer-rendering/content-outside-src-mdx/shuttle.jpg b/packages/astro/test/fixtures/content-layer-rendering/content-outside-src-mdx/shuttle.jpg
new file mode 100644
index 000000000000..80b8ea67b8e4
Binary files /dev/null and b/packages/astro/test/fixtures/content-layer-rendering/content-outside-src-mdx/shuttle.jpg differ
diff --git a/packages/astro/test/fixtures/content-layer-rendering/images/atlantis.avif b/packages/astro/test/fixtures/content-layer-rendering/images/atlantis.avif
new file mode 100644
index 000000000000..6b9f6d5a5913
Binary files /dev/null and b/packages/astro/test/fixtures/content-layer-rendering/images/atlantis.avif differ
diff --git a/packages/astro/test/fixtures/content-layer-rendering/images/launch.webp b/packages/astro/test/fixtures/content-layer-rendering/images/launch.webp
new file mode 100644
index 000000000000..144ded978ad2
Binary files /dev/null and b/packages/astro/test/fixtures/content-layer-rendering/images/launch.webp differ
diff --git a/packages/astro/test/fixtures/content-layer-rendering/images/shuttle.jpg b/packages/astro/test/fixtures/content-layer-rendering/images/shuttle.jpg
new file mode 100644
index 000000000000..80b8ea67b8e4
Binary files /dev/null and b/packages/astro/test/fixtures/content-layer-rendering/images/shuttle.jpg differ
diff --git a/packages/astro/test/fixtures/content-layer-rendering/package.json b/packages/astro/test/fixtures/content-layer-rendering/package.json
new file mode 100644
index 000000000000..6679b8d6ecfb
--- /dev/null
+++ b/packages/astro/test/fixtures/content-layer-rendering/package.json
@@ -0,0 +1,9 @@
+{
+ "name": "@test/content-layer-rendering",
+ "version": "0.0.0",
+ "private": true,
+ "dependencies": {
+ "astro": "workspace:*",
+ "@astrojs/mdx": "workspace:*"
+ }
+}
diff --git a/packages/astro/test/fixtures/content-layer-rendering/src/components/H2.astro b/packages/astro/test/fixtures/content-layer-rendering/src/components/H2.astro
new file mode 100644
index 000000000000..d1ad359c2ee1
--- /dev/null
+++ b/packages/astro/test/fixtures/content-layer-rendering/src/components/H2.astro
@@ -0,0 +1,4 @@
+---
+---
+
+
diff --git a/packages/astro/test/fixtures/content-layer-rendering/src/components/H3.astro b/packages/astro/test/fixtures/content-layer-rendering/src/components/H3.astro
new file mode 100644
index 000000000000..fa476e929eae
--- /dev/null
+++ b/packages/astro/test/fixtures/content-layer-rendering/src/components/H3.astro
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/packages/astro/test/fixtures/content-layer-rendering/src/components/LayoutProp.astro b/packages/astro/test/fixtures/content-layer-rendering/src/components/LayoutProp.astro
new file mode 100644
index 000000000000..a2954162a396
--- /dev/null
+++ b/packages/astro/test/fixtures/content-layer-rendering/src/components/LayoutProp.astro
@@ -0,0 +1,39 @@
+---
+import { CollectionEntry, getCollection } from 'astro:content';
+import H3 from './H3.astro'
+// Test for recursive `getCollection()` calls
+const blog = await getCollection('blog');
+
+type Props = {
+ content: CollectionEntry<'blog'>['data'];
+};
+
+const {
+ content: { title },
+} = Astro.props;
+---
+
+
+
+
+
+
+
+ With Layout Prop
+
+
+ {title}
+ H3 inserted in the layout
+
+
+
+
+
+
+
diff --git a/packages/astro/test/fixtures/content-layer-rendering/src/components/WithScripts.astro b/packages/astro/test/fixtures/content-layer-rendering/src/components/WithScripts.astro
new file mode 100644
index 000000000000..e37694eaf1f0
--- /dev/null
+++ b/packages/astro/test/fixtures/content-layer-rendering/src/components/WithScripts.astro
@@ -0,0 +1,11 @@
+Hoisted script didn't update me :(
+
+Inline script didn't update me :(
+
+
+
+
diff --git a/packages/astro/test/fixtures/content-layer-rendering/src/content/config.ts b/packages/astro/test/fixtures/content-layer-rendering/src/content/config.ts
new file mode 100644
index 000000000000..eb175fa99bd8
--- /dev/null
+++ b/packages/astro/test/fixtures/content-layer-rendering/src/content/config.ts
@@ -0,0 +1,18 @@
+import { defineCollection, z, reference } from 'astro:content';
+import { glob } from 'astro/loaders';
+
+const reptiles = defineCollection({
+ loader: glob({
+ pattern: '*.mdx',
+ base: new URL('../../content-outside-src-mdx', import.meta.url),
+ }),
+ schema: () =>
+ z.object({
+ title: z.string(),
+ description: z.string(),
+ publishedDate: z.coerce.date(),
+ tags: z.array(z.string()),
+ }),
+});
+
+export const collections = { reptiles };
diff --git a/packages/astro/test/fixtures/content-layer-rendering/src/pages/reptiles/[slug].astro b/packages/astro/test/fixtures/content-layer-rendering/src/pages/reptiles/[slug].astro
new file mode 100644
index 000000000000..526805e09947
--- /dev/null
+++ b/packages/astro/test/fixtures/content-layer-rendering/src/pages/reptiles/[slug].astro
@@ -0,0 +1,25 @@
+---
+import type { GetStaticPaths } from "astro";
+import { getCollection, render } from "astro:content"
+import { Image } from "astro:assets"
+
+export const getStaticPaths = (async () => {
+ const collection = await getCollection("reptiles");
+ if(!collection) return []
+ return collection.map((reptile) => ({
+ params: {
+ slug: `${reptile.id}`
+ },
+ props: {
+ reptile
+ }
+ }));
+}) satisfies GetStaticPaths;
+
+const { reptile } = Astro.props as any
+const { Content } = await render(reptile)
+
+---
+
+{reptile.data.title}
+
diff --git a/packages/astro/test/fixtures/content-layer/astro.config.mjs b/packages/astro/test/fixtures/content-layer/astro.config.mjs
new file mode 100644
index 000000000000..3266e5e8c0ad
--- /dev/null
+++ b/packages/astro/test/fixtures/content-layer/astro.config.mjs
@@ -0,0 +1,18 @@
+import mdx from '@astrojs/mdx';
+import { defineConfig } from 'astro/config';
+import { fileURLToPath } from 'node:url';
+
+export default defineConfig({
+ integrations: [mdx()],
+ vite: {
+ resolve: {
+ alias: {
+ '@images': fileURLToPath(new URL('./images', import.meta.url))
+ }
+ },
+ },
+ experimental: {
+ contentLayer: true,
+ contentIntellisense: true,
+ },
+});
diff --git a/packages/astro/test/fixtures/content-layer/content-outside-src/columbia-copy.md b/packages/astro/test/fixtures/content-layer/content-outside-src/columbia-copy.md
new file mode 100644
index 000000000000..6e770b2afd95
--- /dev/null
+++ b/packages/astro/test/fixtures/content-layer/content-outside-src/columbia-copy.md
@@ -0,0 +1,16 @@
+---
+title: More Columbia
+description: 'Learn about the Columbia NASA space shuttle.'
+publishedDate: 'Sat May 21 2022 00:00:00 GMT-0400 (Eastern Daylight Time)'
+tags: [space, 90s]
+cat: tabby
+---
+
+**Source:** [Wikipedia](https://en.wikipedia.org/wiki/Space_Shuttle_Endeavour)
+
+Space Shuttle Endeavour (Orbiter Vehicle Designation: OV-105) is a retired orbiter from NASA's Space Shuttle program and the fifth and final operational Shuttle built. It embarked on its first mission, STS-49, in May 1992 and its 25th and final mission, STS-134, in May 2011. STS-134 was expected to be the final mission of the Space Shuttle program, but with the authorization of STS-135, Atlantis became the last shuttle to fly.
+
+The United States Congress approved the construction of Endeavour in 1987 to replace the Space Shuttle Challenger, which was destroyed in 1986.
+
+NASA chose, on cost grounds, to build much of Endeavour from spare parts rather than refitting the Space Shuttle Enterprise, and used structural spares built during the construction of Discovery and Atlantis in its assembly.
+Space Shuttle Endeavour (Orbiter Vehicle Designation: OV-105) is a retired orbiter from NASA's Space Shuttle program and the fifth and final operational Shuttle built. It embarked on its first mission, STS-49, in May 1992 and its 25th and final mission, STS-134, in May 2011. STS-134 was expected to be the final mission of the Space Shuttle program, but with the authorization of STS-135, Atlantis became the last shuttle to fly.
diff --git a/packages/astro/test/fixtures/content-layer/content-outside-src/columbia.md b/packages/astro/test/fixtures/content-layer/content-outside-src/columbia.md
new file mode 100644
index 000000000000..e8a7bf248647
--- /dev/null
+++ b/packages/astro/test/fixtures/content-layer/content-outside-src/columbia.md
@@ -0,0 +1,22 @@
+---
+title: Columbia
+description: 'Learn about the Columbia NASA space shuttle.'
+publishedDate: 'Sat May 21 2022 00:00:00 GMT-0400 (Eastern Daylight Time)'
+tags: [space, 90s]
+heroImage: "@images/launch.webp"
+---
+
+**Source:** [Wikipedia](https://en.wikipedia.org/wiki/Space_Shuttle_Endeavour)
+
+![columbia bare](shuttle.jpg)
+![columbia relative](./shuttle.jpg)
+![atlantis alias](@images/atlantis.avif)
+![columbia relative 2](./shuttle.jpg)
+
+## Columbia
+
+Space Shuttle Columbia (Orbiter Vehicle Designation: OV-102) was the first space-rated orbiter in NASA's Space Shuttle fleet. It launched for the first time on mission STS-1 on April 12, 1981, the first flight of the Space Shuttle program. Over 22 years of service, it completed 27 missions before disintegrating during re-entry near the end of its 28th mission, STS-107 on February 1, 2003, resulting in the deaths of all seven crew members.
+
+Columbia was named after the American sloop Columbia Rediviva which, from 1787 to 1793, under the command of Captain Robert Gray, explored the US Pacific Northwest and became the first American vessel to circumnavigate the globe. It is also named after the Command Module of Apollo 11, the first crewed landing on another celestial body. Columbia
+
+Columbia was the first space shuttle to reach space, on mission STS-1. It was also the first space shuttle to be launched more than once, with a total of 28 missions flown over 22 years. In 2003, Columbia was destroyed as it re-entered Earth's atmosphere, killing all seven crew members. The disaster led to the grounding of the space shuttle fleet for over two years, and the eventual retirement of the remaining orbiters.
diff --git a/packages/astro/test/fixtures/content-layer/content-outside-src/endeavour.md b/packages/astro/test/fixtures/content-layer/content-outside-src/endeavour.md
new file mode 100644
index 000000000000..51d6e8c42178
--- /dev/null
+++ b/packages/astro/test/fixtures/content-layer/content-outside-src/endeavour.md
@@ -0,0 +1,14 @@
+---
+title: Endeavour
+description: 'Learn about the Endeavour NASA space shuttle.'
+publishedDate: 'Sun Jul 11 2021 00:00:00 GMT-0400 (Eastern Daylight Time)'
+tags: [space, 90s]
+---
+
+**Source:** [Wikipedia](https://en.wikipedia.org/wiki/Space_Shuttle_Endeavour)
+
+Space Shuttle Endeavour (Orbiter Vehicle Designation: OV-105) is a retired orbiter from NASA's Space Shuttle program and the fifth and final operational Shuttle built. It embarked on its first mission, STS-49, in May 1992 and its 25th and final mission, STS-134, in May 2011. STS-134 was expected to be the final mission of the Space Shuttle program, but with the authorization of STS-135, Atlantis became the last shuttle to fly.
+
+The United States Congress approved the construction of Endeavour in 1987 to replace the Space Shuttle Challenger, which was destroyed in 1986.
+
+NASA chose, on cost grounds, to build much of Endeavour from spare parts rather than refitting the Space Shuttle Enterprise, and used structural spares built during the construction of Discovery and Atlantis in its assembly.
diff --git a/packages/astro/test/fixtures/content-layer/content-outside-src/enterprise.md b/packages/astro/test/fixtures/content-layer/content-outside-src/enterprise.md
new file mode 100644
index 000000000000..3131e6d5df3a
--- /dev/null
+++ b/packages/astro/test/fixtures/content-layer/content-outside-src/enterprise.md
@@ -0,0 +1,14 @@
+---
+title: 'Enterprise'
+description: 'Learn about the Enterprise NASA space shuttle.'
+publishedDate: 'Tue Jun 08 2021 00:00:00 GMT-0400 (Eastern Daylight Time)'
+tags: [space, 70s]
+---
+
+**Source:** [Wikipedia](https://en.wikipedia.org/wiki/Space_Shuttle_Enterprise)
+
+Space Shuttle Enterprise (Orbiter Vehicle Designation: OV-101) was the first orbiter of the Space Shuttle system. Rolled out on September 17, 1976, it was built for NASA as part of the Space Shuttle program to perform atmospheric test flights after being launched from a modified Boeing 747. It was constructed without engines or a functional heat shield. As a result, it was not capable of spaceflight.
+
+Originally, Enterprise had been intended to be refitted for orbital flight to become the second space-rated orbiter in service. However, during the construction of Space Shuttle Columbia, details of the final design changed, making it simpler and less costly to build Challenger around a body frame that had been built as a test article. Similarly, Enterprise was considered for refit to replace Challenger after the latter was destroyed, but Endeavour was built from structural spares instead.
+
+Enterprise was restored and placed on display in 2003 at the Smithsonian's new Steven F. Udvar-Hazy Center in Virginia. Following the retirement of the Space Shuttle fleet, Discovery replaced Enterprise at the Udvar-Hazy Center, and Enterprise was transferred to the Intrepid Sea, Air & Space Museum in New York City, where it has been on display since July 2012.
diff --git a/packages/astro/test/fixtures/content-layer/content-outside-src/index.md b/packages/astro/test/fixtures/content-layer/content-outside-src/index.md
new file mode 100644
index 000000000000..4971108e36ed
--- /dev/null
+++ b/packages/astro/test/fixtures/content-layer/content-outside-src/index.md
@@ -0,0 +1,15 @@
+---
+title: Columbia
+description: 'Learn about the Columbia NASA space shuttle.'
+publishedDate: 'Sat May 21 2022 00:00:00 GMT-0400 (Eastern Daylight Time)'
+tags: [space, 90s]
+---
+
+**Source:** [Wikipedia](https://en.wikipedia.org/wiki/Space_Shuttle_Endeavour)
+
+Space Shuttle Endeavour (Orbiter Vehicle Designation: OV-105) is a retired orbiter from NASA's Space Shuttle program and the fifth and final operational Shuttle built. It embarked on its first mission, STS-49, in May 1992 and its 25th and final mission, STS-134, in May 2011. STS-134 was expected to be the final mission of the Space Shuttle program, but with the authorization of STS-135, Atlantis became the last shuttle to fly.
+
+The United States Congress approved the construction of Endeavour in 1987 to replace the Space Shuttle Challenger, which was destroyed in 1986.
+
+NASA chose, on cost grounds, to build much of Endeavour from spare parts rather than refitting the Space Shuttle Enterprise, and used structural spares built during the construction of Discovery and Atlantis in its assembly.
+Space Shuttle Endeavour (Orbiter Vehicle Designation: OV-105) is a retired orbiter from NASA's Space Shuttle program and the fifth and final operational Shuttle built. It embarked on its first mission, STS-49, in May 1992 and its 25th and final mission, STS-134, in May 2011. STS-134 was expected to be the final mission of the Space Shuttle program, but with the authorization of STS-135, Atlantis became the last shuttle to fly.
diff --git a/packages/astro/test/fixtures/content-layer/content-outside-src/shuttle.jpg b/packages/astro/test/fixtures/content-layer/content-outside-src/shuttle.jpg
new file mode 100644
index 000000000000..80b8ea67b8e4
Binary files /dev/null and b/packages/astro/test/fixtures/content-layer/content-outside-src/shuttle.jpg differ
diff --git a/packages/astro/test/fixtures/content-layer/images/atlantis.avif b/packages/astro/test/fixtures/content-layer/images/atlantis.avif
new file mode 100644
index 000000000000..6b9f6d5a5913
Binary files /dev/null and b/packages/astro/test/fixtures/content-layer/images/atlantis.avif differ
diff --git a/packages/astro/test/fixtures/content-layer/images/launch.webp b/packages/astro/test/fixtures/content-layer/images/launch.webp
new file mode 100644
index 000000000000..144ded978ad2
Binary files /dev/null and b/packages/astro/test/fixtures/content-layer/images/launch.webp differ
diff --git a/packages/astro/test/fixtures/content-layer/images/shuttle.jpg b/packages/astro/test/fixtures/content-layer/images/shuttle.jpg
new file mode 100644
index 000000000000..80b8ea67b8e4
Binary files /dev/null and b/packages/astro/test/fixtures/content-layer/images/shuttle.jpg differ
diff --git a/packages/astro/test/fixtures/content-layer/package.json b/packages/astro/test/fixtures/content-layer/package.json
new file mode 100644
index 000000000000..fc73ce6f7ac7
--- /dev/null
+++ b/packages/astro/test/fixtures/content-layer/package.json
@@ -0,0 +1,9 @@
+{
+ "name": "@test/content-layer",
+ "version": "0.0.0",
+ "private": true,
+ "dependencies": {
+ "astro": "workspace:*",
+ "@astrojs/mdx": "workspace:*"
+ }
+}
diff --git a/packages/astro/test/fixtures/content-layer/src/components/H2.astro b/packages/astro/test/fixtures/content-layer/src/components/H2.astro
new file mode 100644
index 000000000000..d1ad359c2ee1
--- /dev/null
+++ b/packages/astro/test/fixtures/content-layer/src/components/H2.astro
@@ -0,0 +1,4 @@
+---
+---
+
+
diff --git a/packages/astro/test/fixtures/content-layer/src/components/H3.astro b/packages/astro/test/fixtures/content-layer/src/components/H3.astro
new file mode 100644
index 000000000000..fa476e929eae
--- /dev/null
+++ b/packages/astro/test/fixtures/content-layer/src/components/H3.astro
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/packages/astro/test/fixtures/content-layer/src/components/LayoutProp.astro b/packages/astro/test/fixtures/content-layer/src/components/LayoutProp.astro
new file mode 100644
index 000000000000..a2954162a396
--- /dev/null
+++ b/packages/astro/test/fixtures/content-layer/src/components/LayoutProp.astro
@@ -0,0 +1,39 @@
+---
+import { CollectionEntry, getCollection } from 'astro:content';
+import H3 from './H3.astro'
+// Test for recursive `getCollection()` calls
+const blog = await getCollection('blog');
+
+type Props = {
+ content: CollectionEntry<'blog'>['data'];
+};
+
+const {
+ content: { title },
+} = Astro.props;
+---
+
+
+
+
+
+
+
+ With Layout Prop
+
+
+ {title}
+ H3 inserted in the layout
+
+
+
+
+
+
+
diff --git a/packages/astro/test/fixtures/content-layer/src/components/WithScripts.astro b/packages/astro/test/fixtures/content-layer/src/components/WithScripts.astro
new file mode 100644
index 000000000000..e37694eaf1f0
--- /dev/null
+++ b/packages/astro/test/fixtures/content-layer/src/components/WithScripts.astro
@@ -0,0 +1,11 @@
+Hoisted script didn't update me :(
+
+Inline script didn't update me :(
+
+
+
+
diff --git a/packages/astro/test/fixtures/content-layer/src/content/config.ts b/packages/astro/test/fixtures/content-layer/src/content/config.ts
new file mode 100644
index 000000000000..1689a56b1c28
--- /dev/null
+++ b/packages/astro/test/fixtures/content-layer/src/content/config.ts
@@ -0,0 +1,111 @@
+import { defineCollection, z, reference } from 'astro:content';
+import { file, glob } from 'astro/loaders';
+import { loader } from '../loaders/post-loader.js';
+
+const blog = defineCollection({
+ loader: loader({ url: 'https://jsonplaceholder.typicode.com/posts' }),
+});
+
+const dogs = defineCollection({
+ loader: file('src/data/dogs.json'),
+ schema: z.object({
+ breed: z.string(),
+ id: z.string(),
+ size: z.string(),
+ origin: z.string(),
+ lifespan: z.string(),
+ temperament: z.array(z.string()),
+ }),
+});
+
+const cats = defineCollection({
+ loader: async function () {
+ return [
+ {
+ breed: 'Siamese',
+ id: 'siamese',
+ size: 'Medium',
+ origin: 'Thailand',
+ lifespan: '15 years',
+ temperament: ['Active', 'Affectionate', 'Social', 'Playful'],
+ },
+ {
+ breed: 'Persian',
+ id: 'persian',
+ size: 'Medium',
+ origin: 'Iran',
+ lifespan: '15 years',
+ temperament: ['Calm', 'Affectionate', 'Social'],
+ },
+ {
+ breed: 'Tabby',
+ id: 'tabby',
+ size: 'Medium',
+ origin: 'Egypt',
+ lifespan: '15 years',
+ temperament: ['Curious', 'Playful', 'Independent'],
+ },
+ {
+ breed: 'Ragdoll',
+ id: 'ragdoll',
+ size: 'Medium',
+ origin: 'United States',
+ lifespan: '15 years',
+ temperament: ['Calm', 'Affectionate', 'Social'],
+ },
+ ];
+ },
+ schema: z.object({
+ breed: z.string(),
+ id: z.string(),
+ size: z.string(),
+ origin: z.string(),
+ lifespan: z.string(),
+ temperament: z.array(z.string()),
+ }),
+});
+
+// Absolute paths should also work
+const absoluteRoot = new URL('../../content-outside-src', import.meta.url);
+
+const spacecraft = defineCollection({
+ loader: glob({ pattern: '*.md', base: absoluteRoot }),
+ schema: ({ image }) =>
+ z.object({
+ title: z.string(),
+ description: z.string(),
+ publishedDate: z.coerce.date(),
+ tags: z.array(z.string()),
+ heroImage: image().optional(),
+ cat: reference('cats').optional(),
+ }),
+});
+
+const numbers = defineCollection({
+ loader: glob({ pattern: 'src/data/glob-data/*', base: '.' }),
+});
+
+const increment = defineCollection({
+ loader: {
+ name: 'increment-loader',
+ load: async ({ store }) => {
+ const entry = store.get<{lastValue: number}>('value');
+ const lastValue = entry?.data.lastValue ?? 0;
+ store.set({
+ id: 'value',
+ data: {
+ lastValue: lastValue + 1,
+ lastUpdated: new Date(),
+ },
+ });
+ },
+ // Example of a loader that returns an async schema function
+ schema: async () => z.object({
+ lastValue: z.number(),
+ lastUpdated: z.date(),
+ }),
+ },
+
+});
+
+export const collections = { blog, dogs, cats, numbers, spacecraft, increment };
diff --git a/packages/astro/test/fixtures/content-layer/src/data/dogs.json b/packages/astro/test/fixtures/content-layer/src/data/dogs.json
new file mode 100644
index 000000000000..66e6320c65e1
--- /dev/null
+++ b/packages/astro/test/fixtures/content-layer/src/data/dogs.json
@@ -0,0 +1,302 @@
+[
+ {
+ "breed": "Labrador Retriever",
+ "id": "labrador-retriever",
+ "size": "Large",
+ "origin": "Canada",
+ "lifespan": "10-12 years",
+ "temperament": [
+ "Friendly",
+ "Active",
+ "Outgoing"
+ ]
+ },
+ {
+ "breed": "German Shepherd",
+ "id": "german-shepherd",
+ "size": "Large",
+ "origin": "Germany",
+ "lifespan": "9-13 years",
+ "temperament": [
+ "Loyal",
+ "Intelligent",
+ "Confident"
+ ]
+ },
+ {
+ "breed": "Golden Retriever",
+ "id": "golden-retriever",
+ "size": "Large",
+ "origin": "Scotland",
+ "lifespan": "10-12 years",
+ "temperament": [
+ "Intelligent",
+ "Friendly",
+ "Devoted"
+ ]
+ },
+ {
+ "breed": "French Bulldog",
+ "id": "french-bulldog",
+ "size": "Small",
+ "origin": "France",
+ "lifespan": "10-12 years",
+ "temperament": [
+ "Playful",
+ "Adaptable",
+ "Sociable"
+ ]
+ },
+ {
+ "breed": "Bulldog",
+ "id": "bulldog",
+ "size": "Medium",
+ "origin": "England",
+ "lifespan": "8-10 years",
+ "temperament": [
+ "Docile",
+ "Willful",
+ "Friendly"
+ ]
+ },
+ {
+ "breed": "Beagle",
+ "id": "beagle",
+ "size": "Small to Medium",
+ "origin": "England",
+ "lifespan": "12-15 years",
+ "temperament": [
+ "Friendly",
+ "Curious",
+ "Merry"
+ ]
+ },
+ {
+ "breed": "Poodle",
+ "id": "poodle",
+ "size": "Toy, Miniature, or Standard",
+ "origin": "Germany",
+ "lifespan": "12-15 years",
+ "temperament": [
+ "Intelligent",
+ "Active",
+ "Alert"
+ ]
+ },
+ {
+ "breed": "Rottweiler",
+ "id": "rottweiler",
+ "size": "Large",
+ "origin": "Germany",
+ "lifespan": "8-10 years",
+ "temperament": [
+ "Loyal",
+ "Confident",
+ "Courageous"
+ ]
+ },
+ {
+ "breed": "German Shorthaired Pointer",
+ "id": "german-shorthaired-pointer",
+ "size": "Medium to Large",
+ "origin": "Germany",
+ "lifespan": "10-12 years",
+ "temperament": [
+ "Friendly",
+ "Intelligent",
+ "Willing to Please"
+ ]
+ },
+ {
+ "breed": "Yorkshire Terrier",
+ "id": "yorkshire-terrier",
+ "size": "Toy",
+ "origin": "England",
+ "lifespan": "13-16 years",
+ "temperament": [
+ "Affectionate",
+ "Sprightly",
+ "Tomboyish"
+ ]
+ },
+ {
+ "breed": "Boxer",
+ "id": "boxer",
+ "size": "Medium to Large",
+ "origin": "Germany",
+ "lifespan": "10-12 years",
+ "temperament": [
+ "Playful",
+ "Energetic",
+ "Loyal"
+ ]
+ },
+ {
+ "breed": "Dachshund",
+ "id": "dachshund",
+ "size": "Small",
+ "origin": "Germany",
+ "lifespan": "12-16 years",
+ "temperament": [
+ "Clever",
+ "Stubborn",
+ "Devoted"
+ ]
+ },
+ {
+ "breed": "Siberian Husky",
+ "id": "siberian-husky",
+ "size": "Medium",
+ "origin": "Siberia",
+ "lifespan": "12-14 years",
+ "temperament": [
+ "Outgoing",
+ "Mischievous",
+ "Loyal"
+ ]
+ },
+ {
+ "breed": "Great Dane",
+ "id": "great-dane",
+ "size": "Large",
+ "origin": "Germany",
+ "lifespan": "7-10 years",
+ "temperament": [
+ "Friendly",
+ "Patient",
+ "Dependable"
+ ]
+ },
+ {
+ "breed": "Doberman Pinscher",
+ "id": "doberman-pinscher",
+ "size": "Large",
+ "origin": "Germany",
+ "lifespan": "10-12 years",
+ "temperament": [
+ "Loyal",
+ "Fearless",
+ "Alert"
+ ]
+ },
+ {
+ "breed": "Australian Shepherd",
+ "id": "australian-shepherd",
+ "size": "Medium",
+ "origin": "United States",
+ "lifespan": "12-15 years",
+ "temperament": [
+ "Intelligent",
+ "Work-oriented",
+ "Exuberant"
+ ]
+ },
+ {
+ "breed": "Miniature Schnauzer",
+ "id": "miniature-schnauzer",
+ "size": "Small",
+ "origin": "Germany",
+ "lifespan": "12-15 years",
+ "temperament": [
+ "Friendly",
+ "Smart",
+ "Obedient"
+ ]
+ },
+ {
+ "breed": "Cavalier King Charles Spaniel",
+ "id": "cavalier-king-charles-spaniel",
+ "size": "Small",
+ "origin": "United Kingdom",
+ "lifespan": "9-14 years",
+ "temperament": [
+ "Affectionate",
+ "Gentle",
+ "Graceful"
+ ]
+ },
+ {
+ "breed": "Shih Tzu",
+ "id": "shih-tzu",
+ "size": "Small",
+ "origin": "China",
+ "lifespan": "10-18 years",
+ "temperament": [
+ "Affectionate",
+ "Playful",
+ "Outgoing"
+ ]
+ },
+ {
+ "breed": "Boston Terrier",
+ "id": "boston-terrier",
+ "size": "Small",
+ "origin": "United States",
+ "lifespan": "11-13 years",
+ "temperament": [
+ "Friendly",
+ "Lively",
+ "Intelligent"
+ ]
+ },
+ {
+ "breed": "Bernese Mountain Dog",
+ "id": "bernese-mountain-dog",
+ "size": "Large",
+ "origin": "Switzerland",
+ "lifespan": "7-10 years",
+ "temperament": [
+ "Good-natured",
+ "Calm",
+ "Strong"
+ ]
+ },
+ {
+ "breed": "Pomeranian",
+ "id": "pomeranian",
+ "size": "Toy",
+ "origin": "Germany",
+ "lifespan": "12-16 years",
+ "temperament": [
+ "Lively",
+ "Bold",
+ "Inquisitive"
+ ]
+ },
+ {
+ "breed": "Havanese",
+ "id": "havanese",
+ "size": "Small",
+ "origin": "Cuba",
+ "lifespan": "14-16 years",
+ "temperament": [
+ "Playful",
+ "Intelligent",
+ "Outgoing"
+ ]
+ },
+ {
+ "breed": "English Springer Spaniel",
+ "id": "english-springer-spaniel",
+ "size": "Medium",
+ "origin": "England",
+ "lifespan": "12-14 years",
+ "temperament": [
+ "Friendly",
+ "Playful",
+ "Obedient"
+ ]
+ },
+ {
+ "breed": "Shetland Sheepdog",
+ "id": "shetland-sheepdog",
+ "size": "Small",
+ "origin": "Scotland",
+ "lifespan": "12-14 years",
+ "temperament": [
+ "Playful",
+ "Energetic",
+ "Intelligent"
+ ]
+ }
+]
diff --git a/packages/astro/test/fixtures/content-layer/src/data/glob-data/index.json b/packages/astro/test/fixtures/content-layer/src/data/glob-data/index.json
new file mode 100644
index 000000000000..efc60137d68e
--- /dev/null
+++ b/packages/astro/test/fixtures/content-layer/src/data/glob-data/index.json
@@ -0,0 +1,3 @@
+{
+ "title": "One"
+}
diff --git a/packages/astro/test/fixtures/content-layer/src/data/glob-data/one.json b/packages/astro/test/fixtures/content-layer/src/data/glob-data/one.json
new file mode 100644
index 000000000000..efc60137d68e
--- /dev/null
+++ b/packages/astro/test/fixtures/content-layer/src/data/glob-data/one.json
@@ -0,0 +1,3 @@
+{
+ "title": "One"
+}
diff --git a/packages/astro/test/fixtures/content-layer/src/data/glob-data/three.json b/packages/astro/test/fixtures/content-layer/src/data/glob-data/three.json
new file mode 100644
index 000000000000..7d028e937a71
--- /dev/null
+++ b/packages/astro/test/fixtures/content-layer/src/data/glob-data/three.json
@@ -0,0 +1,3 @@
+{
+ "title": "Three"
+}
diff --git a/packages/astro/test/fixtures/content-layer/src/data/glob-data/two.json b/packages/astro/test/fixtures/content-layer/src/data/glob-data/two.json
new file mode 100644
index 000000000000..1a8215509b0a
--- /dev/null
+++ b/packages/astro/test/fixtures/content-layer/src/data/glob-data/two.json
@@ -0,0 +1,3 @@
+{
+ "title": "Two"
+}
diff --git a/packages/astro/test/fixtures/content-layer/src/loaders/post-loader.ts b/packages/astro/test/fixtures/content-layer/src/loaders/post-loader.ts
new file mode 100644
index 000000000000..b03c1442227e
--- /dev/null
+++ b/packages/astro/test/fixtures/content-layer/src/loaders/post-loader.ts
@@ -0,0 +1,45 @@
+import { z } from 'astro:content';
+import type { Loader } from "astro/loaders"
+
+export interface PostLoaderConfig {
+ url: string;
+}
+
+export function loader(config:PostLoaderConfig): Loader {
+ return {
+ name: "post-loader",
+ load: async ({
+ store, meta, logger
+ }) => {
+ logger.info('Loading posts');
+
+ const lastSynced = meta.get('lastSynced');
+
+ // Don't sync more than once a minute
+ if (lastSynced && (Date.now() - Number(lastSynced) < 1000 * 60)) {
+ logger.info('Skipping sync');
+ return;
+ }
+
+ const posts = await fetch(config.url)
+ .then((res) => res.json());
+
+ store.clear();
+
+ for (const data of posts) {
+ store.set({id: data.id, data});
+ }
+ meta.set('lastSynced', String(Date.now()));
+ },
+ schema: async () => {
+ // Simulate a delay
+ await new Promise((resolve) => setTimeout(resolve, 1000));
+ return z.object({
+ title: z.string(),
+ body: z.string(),
+ userId: z.number(),
+ id: z.number(),
+ });
+ }
+ };
+}
diff --git a/packages/astro/test/fixtures/content-layer/src/pages/blog/[id].astro b/packages/astro/test/fixtures/content-layer/src/pages/blog/[id].astro
new file mode 100644
index 000000000000..850833907ba7
--- /dev/null
+++ b/packages/astro/test/fixtures/content-layer/src/pages/blog/[id].astro
@@ -0,0 +1,29 @@
+---
+import type { GetStaticPaths } from "astro";
+import { getCollection } from "astro:content"
+export const getStaticPaths = (async () => {
+ const collection = await getCollection("blog");
+ if(!collection) return []
+ return collection.map((post) => ({
+ params: {
+ id: post.id
+ },
+ props: {
+ post: post.data
+ }
+ }));
+}) satisfies GetStaticPaths;
+
+interface Props {
+ post: {
+ title: string;
+ body: string;
+ }
+}
+
+const { post } = Astro.props
+
+---
+
+{post.title}
+{post.body}
diff --git a/packages/astro/test/fixtures/content-layer/src/pages/collections.json.js b/packages/astro/test/fixtures/content-layer/src/pages/collections.json.js
new file mode 100644
index 000000000000..f637bf80d02f
--- /dev/null
+++ b/packages/astro/test/fixtures/content-layer/src/pages/collections.json.js
@@ -0,0 +1,30 @@
+import { getCollection, getEntry } from 'astro:content';
+import * as devalue from 'devalue';
+
+export async function GET() {
+ const customLoader = await getCollection('blog', (entry) => {
+ return entry.data.id < 6;
+ });
+ const fileLoader = await getCollection('dogs');
+
+ const dataEntry = await getEntry('dogs', 'beagle');
+
+ const simpleLoader = await getCollection('cats');
+
+ const entryWithReference = await getEntry('spacecraft', 'columbia-copy');
+ const referencedEntry = await getEntry(entryWithReference.data.cat);
+
+ const increment = await getEntry('increment', 'value');
+
+ return new Response(
+ devalue.stringify({
+ customLoader,
+ fileLoader,
+ dataEntry,
+ simpleLoader,
+ entryWithReference,
+ referencedEntry,
+ increment,
+ })
+ );
+}
diff --git a/packages/astro/test/fixtures/content-layer/src/pages/dogs/[slug].astro b/packages/astro/test/fixtures/content-layer/src/pages/dogs/[slug].astro
new file mode 100644
index 000000000000..977ae6efa167
--- /dev/null
+++ b/packages/astro/test/fixtures/content-layer/src/pages/dogs/[slug].astro
@@ -0,0 +1,40 @@
+---
+import type { GetStaticPaths } from "astro";
+import { getCollection } from "astro:content"
+export const getStaticPaths = (async () => {
+ const collection = await getCollection("dogs");
+ if(!collection) return []
+ return collection.map((dog) => ({
+ params: {
+ slug: dog.id
+ },
+ props: {
+ dog: dog.data
+ }
+ }));
+}) satisfies GetStaticPaths;
+
+
+interface Props {
+ dog: {
+ breed: string;
+ id: string;
+ size: string;
+ origin: string;
+ lifespan: string;
+ temperament: string[];
+ }
+}
+
+const { dog } = Astro.props
+
+
+---
+
+{dog.breed}
+
+Size: {dog.size}
+Origin: {dog.origin}
+Lifespan: {dog.lifespan}
+Temperament: {dog.temperament.join(", ")}
+
diff --git a/packages/astro/test/fixtures/content-layer/src/pages/index.astro b/packages/astro/test/fixtures/content-layer/src/pages/index.astro
new file mode 100644
index 000000000000..dbd18118a045
--- /dev/null
+++ b/packages/astro/test/fixtures/content-layer/src/pages/index.astro
@@ -0,0 +1,33 @@
+---
+import { getCollection, getEntry } from 'astro:content';
+
+const blog = await getCollection('blog');
+const first = await getEntry('blog', 1);
+const dogs = await getCollection('dogs');
+const increment = await getEntry('increment', 'value');
+---
+
+
+ Index
+
+
+ Last updated: {increment.data.lastUpdated.toLocaleTimeString()}
+
+ Dogs
+
+ Blog Posts
+
+ {first.data.title}
+
+
+
+
+
diff --git a/packages/astro/test/fixtures/content-layer/src/pages/spacecraft/[slug].astro b/packages/astro/test/fixtures/content-layer/src/pages/spacecraft/[slug].astro
new file mode 100644
index 000000000000..80314606f96f
--- /dev/null
+++ b/packages/astro/test/fixtures/content-layer/src/pages/spacecraft/[slug].astro
@@ -0,0 +1,35 @@
+---
+import type { GetStaticPaths } from "astro";
+import { getCollection, getEntry, render } from "astro:content"
+import { Image } from "astro:assets"
+
+export const getStaticPaths = (async () => {
+ const collection = await getCollection("spacecraft");
+ if(!collection) return []
+ return collection.map((craft) => ({
+ params: {
+ slug: `/${craft.id}`
+ },
+ props: {
+ craft
+ }
+ }));
+}) satisfies GetStaticPaths;
+
+
+
+
+const { craft } = Astro.props as any
+
+let cat = craft.data.cat ? await getEntry(craft.data.cat) : undefined
+const { Content, headings } = await render(craft)
+
+---
+
+{craft.data.title}
+
+{cat? 🐈: {cat.data.breed}
: undefined}
+{craft.data.heroImage ? : undefined}
+
diff --git a/packages/astro/test/test-utils.js b/packages/astro/test/test-utils.js
index 4ed888f970f4..95edeebd2673 100644
--- a/packages/astro/test/test-utils.js
+++ b/packages/astro/test/test-utils.js
@@ -7,6 +7,8 @@ import fastGlob from 'fast-glob';
import stripAnsi from 'strip-ansi';
import { Agent } from 'undici';
import { check } from '../dist/cli/check/index.js';
+import { globalContentLayer } from '../dist/content/content-layer.js';
+import { globalContentConfigObserver } from '../dist/content/utils.js';
import build from '../dist/core/build/index.js';
import { RESOLVED_SPLIT_MODULE_ID } from '../dist/core/build/plugins/plugin-ssr.js';
import { getVirtualModulePageName } from '../dist/core/build/plugins/util.js';
@@ -22,6 +24,7 @@ process.env.ASTRO_TELEMETRY_DISABLED = true;
/**
* @typedef {import('../src/core/dev/dev').DevServer} DevServer
* @typedef {import('../src/@types/astro').AstroInlineConfig & { root?: string | URL }} AstroInlineConfig
+ * @typedef {import('../src/@types/astro').AstroConfig} AstroConfig
* @typedef {import('../src/core/preview/index').PreviewServer} PreviewServer
* @typedef {import('../src/core/app/index').App} App
* @typedef {import('../src/cli/check/index').AstroChecker} AstroChecker
@@ -36,7 +39,7 @@ process.env.ASTRO_TELEMETRY_DISABLED = true;
* @property {(path: string) => Promise} pathExists
* @property {(url: string, opts: Parameters[1]) => Promise} fetch
* @property {(path: string) => Promise} readFile
- * @property {(path: string, updater: (content: string) => string) => Promise} writeFile
+ * @property {(path: string, updater: (content: string) => string) => Promise} editFile
* @property {(path: string) => Promise} readdir
* @property {(pattern: string) => Promise} glob
* @property {typeof dev} startDevServer
@@ -47,6 +50,7 @@ process.env.ASTRO_TELEMETRY_DISABLED = true;
* @property {() => Promise} onNextChange
* @property {typeof check} check
* @property {typeof sync} sync
+ * @property {AstroConfig} config
*
* This function returns an instance of the Check
*
@@ -157,15 +161,22 @@ export async function loadFixture(inlineConfig) {
let devServer;
return {
- build: async (extraInlineConfig = {}) => {
+ build: async (extraInlineConfig = {}, options = {}) => {
+ globalContentLayer.dispose();
+ globalContentConfigObserver.set({ status: 'init' });
process.env.NODE_ENV = 'production';
- return build(mergeConfig(inlineConfig, extraInlineConfig), { teardownCompiler: false });
+ return build(mergeConfig(inlineConfig, extraInlineConfig), {
+ teardownCompiler: false,
+ ...options,
+ });
},
sync,
check: async (opts) => {
return await check(opts);
},
startDevServer: async (extraInlineConfig = {}) => {
+ globalContentLayer.dispose();
+ globalContentConfigObserver.set({ status: 'init' });
process.env.NODE_ENV = 'development';
devServer = await dev(mergeConfig(inlineConfig, extraInlineConfig));
config.server.host = parseAddressToHost(devServer.address.address); // update host
@@ -275,7 +286,7 @@ export async function loadFixture(inlineConfig) {
typeof newContentsOrCallback === 'function'
? newContentsOrCallback(contents)
: newContentsOrCallback;
- const nextChange = onNextChange();
+ const nextChange = devServer ? onNextChange() : Promise.resolve();
await fs.promises.writeFile(fileUrl, newContents);
await nextChange;
return reset;
diff --git a/packages/astro/test/units/dev/collections-mixed-content-errors.test.js b/packages/astro/test/units/dev/collections-mixed-content-errors.test.js
index 73ce15377f34..3417650fc963 100644
--- a/packages/astro/test/units/dev/collections-mixed-content-errors.test.js
+++ b/packages/astro/test/units/dev/collections-mixed-content-errors.test.js
@@ -8,13 +8,15 @@ const root = new URL('../../fixtures/content-mixed-errors/', import.meta.url);
async function sync({ fs }) {
try {
- await _sync({
- inlineConfig: {
+ await _sync(
+ {
root: fileURLToPath(root),
logLevel: 'silent',
},
- fs,
- });
+ {
+ fs,
+ },
+ );
return 0;
} catch (_) {
return 1;
@@ -121,11 +123,7 @@ title: Post
root,
);
- try {
- const res = await sync({ fs });
- assert.equal(res, 0);
- } catch (e) {
- assert.fail(`Did not expect sync to throw: ${e.message}`);
- }
+ const res = await sync({ fs });
+ assert.equal(res, 0);
});
});
diff --git a/packages/astro/test/units/dev/restart.test.js b/packages/astro/test/units/dev/restart.test.js
index a09bfce98c6f..339b95fc1acb 100644
--- a/packages/astro/test/units/dev/restart.test.js
+++ b/packages/astro/test/units/dev/restart.test.js
@@ -194,4 +194,31 @@ describe('dev container restarts', () => {
await restart.container.close();
}
});
+
+ it('Is able to restart project on .astro/settings.json changes', async () => {
+ const fs = createFs(
+ {
+ '/src/pages/index.astro': ``,
+ '/.astro/settings.json': `{}`,
+ },
+ root,
+ );
+
+ const restart = await createContainerWithAutomaticRestart({
+ fs,
+ inlineConfig: { root: fileURLToPath(root), logLevel: 'silent' },
+ });
+ await startContainer(restart.container);
+ assert.equal(isStarted(restart.container), true);
+
+ try {
+ let restartComplete = restart.restarted();
+ fs.mkdirSync('/.astro/', { recursive: true });
+ fs.writeFileSync('/.astro/settings.json', `{ }`);
+ triggerFSEvent(restart.container, fs, '/.astro/settings.json', 'change');
+ await restartComplete;
+ } finally {
+ await restart.container.close();
+ }
+ });
});
diff --git a/packages/astro/test/units/integrations/api.test.js b/packages/astro/test/units/integrations/api.test.js
index 960e003fc3f1..6122ba6408f6 100644
--- a/packages/astro/test/units/integrations/api.test.js
+++ b/packages/astro/test/units/integrations/api.test.js
@@ -1,7 +1,11 @@
import * as assert from 'node:assert/strict';
import { describe, it } from 'node:test';
import { validateSupportedFeatures } from '../../../dist/integrations/features-validation.js';
-import { runHookBuildSetup, runHookConfigSetup } from '../../../dist/integrations/hooks.js';
+import {
+ normalizeInjectedTypeFilename,
+ runHookBuildSetup,
+ runHookConfigSetup,
+} from '../../../dist/integrations/hooks.js';
import { defaultLogger } from '../test-utils.js';
describe('Integration API', () => {
@@ -311,3 +315,20 @@ describe('Astro feature map', function () {
});
});
});
+
+describe('normalizeInjectedTypeFilename', () => {
+ // invalid filename
+ assert.throws(() => normalizeInjectedTypeFilename('types', 'integration'));
+ // valid filename
+ assert.doesNotThrow(() => normalizeInjectedTypeFilename('types.d.ts', 'integration'));
+ // filename normalization
+ assert.equal(
+ normalizeInjectedTypeFilename('aA1-*/_"~.d.ts', 'integration'),
+ './integrations/integration/aA1-_____.d.ts',
+ );
+ // integration name normalization
+ assert.equal(
+ normalizeInjectedTypeFilename('types.d.ts', 'aA1-*/_"~.'),
+ './integrations/aA1-_____./types.d.ts',
+ );
+});
diff --git a/packages/astro/types/content.d.ts b/packages/astro/types/content.d.ts
index 18ddf2c8ca5e..1715a30a42e3 100644
--- a/packages/astro/types/content.d.ts
+++ b/packages/astro/types/content.d.ts
@@ -20,6 +20,31 @@ declare module 'astro:content' {
>;
}>;
+ export interface DataEntry {
+ id: string;
+ data: Record;
+ filePath?: string;
+ body?: string;
+ }
+
+ export interface DataStore {
+ get: (key: string) => DataEntry;
+ entries: () => Array<[id: string, DataEntry]>;
+ set: (key: string, data: Record, body?: string, filePath?: string) => void;
+ values: () => Array;
+ keys: () => Array;
+ delete: (key: string) => void;
+ clear: () => void;
+ has: (key: string) => boolean;
+ }
+
+ export interface MetaStore {
+ get: (key: string) => string | undefined;
+ set: (key: string, value: string) => void;
+ delete: (key: string) => void;
+ has: (key: string) => boolean;
+ }
+
type BaseSchemaWithoutEffects =
| import('astro/zod').AnyZodObject
| import('astro/zod').ZodUnion<[BaseSchemaWithoutEffects, ...BaseSchemaWithoutEffects[]]>
@@ -32,6 +57,12 @@ declare module 'astro:content' {
export type SchemaContext = { image: ImageFunction };
+ type ContentLayerConfig = {
+ type?: 'content_layer';
+ schema?: S | ((context: SchemaContext) => S);
+ loader: import('astro/loaders').Loader | (() => Array | Promise>);
+ };
+
type DataCollectionConfig = {
type: 'data';
schema?: S | ((context: SchemaContext) => S);
@@ -40,11 +71,13 @@ declare module 'astro:content' {
type ContentCollectionConfig = {
type?: 'content';
schema?: S | ((context: SchemaContext) => S);
+ loader?: never;
};
export type CollectionConfig =
| ContentCollectionConfig
- | DataCollectionConfig;
+ | DataCollectionConfig
+ | ContentLayerConfig;
export function defineCollection(
input: CollectionConfig,
diff --git a/packages/db/src/core/integration/index.ts b/packages/db/src/core/integration/index.ts
index 6573c838af13..68439cfb9541 100644
--- a/packages/db/src/core/integration/index.ts
+++ b/packages/db/src/core/integration/index.ts
@@ -22,7 +22,7 @@ import { resolveDbConfig } from '../load-file.js';
import { SEED_DEV_FILE_NAME } from '../queries.js';
import { type VitePlugin, getDbDirectoryUrl } from '../utils.js';
import { fileURLIntegration } from './file-url.js';
-import { typegenInternal } from './typegen.js';
+import { getDtsContent } from './typegen.js';
import {
type LateSeedFiles,
type LateTables,
@@ -30,7 +30,6 @@ import {
resolved,
vitePluginDb,
} from './vite-plugin-db.js';
-import { vitePluginInjectEnvTs } from './vite-plugin-inject-env-ts.js';
function astroDBIntegration(): AstroIntegration {
let connectToStudio = false;
@@ -102,11 +101,11 @@ function astroDBIntegration(): AstroIntegration {
updateConfig({
vite: {
assetsInclude: [DB_PATH],
- plugins: [dbPlugin, vitePluginInjectEnvTs(config, logger)],
+ plugins: [dbPlugin],
},
});
},
- 'astro:config:done': async ({ config }) => {
+ 'astro:config:done': async ({ config, injectTypes }) => {
if (command === 'preview') return;
// TODO: refine where we load tables
@@ -122,7 +121,10 @@ function astroDBIntegration(): AstroIntegration {
await writeFile(localDbUrl, '');
}
- await typegenInternal({ tables: tables.get() ?? {}, root: config.root });
+ injectTypes({
+ filename: 'db.d.ts',
+ content: getDtsContent(tables.get() ?? {}),
+ });
},
'astro:server:setup': async ({ server, logger }) => {
seedHandler.execute = async (fileUrl) => {
diff --git a/packages/db/src/core/integration/typegen.ts b/packages/db/src/core/integration/typegen.ts
index 725738fc5a51..91364b3c3dc1 100644
--- a/packages/db/src/core/integration/typegen.ts
+++ b/packages/db/src/core/integration/typegen.ts
@@ -1,18 +1,7 @@
-import { existsSync } from 'node:fs';
-import { mkdir, writeFile } from 'node:fs/promises';
-import type { AstroConfig } from 'astro';
-import { DB_TYPES_FILE, RUNTIME_IMPORT } from '../consts.js';
-import { resolveDbConfig } from '../load-file.js';
+import { RUNTIME_IMPORT } from '../consts.js';
import type { DBTable, DBTables } from '../types.js';
-// Exported for use in Astro core CLI
-export async function typegen(astroConfig: Pick) {
- const { dbConfig } = await resolveDbConfig(astroConfig);
-
- await typegenInternal({ tables: dbConfig.tables, root: astroConfig.root });
-}
-
-export async function typegenInternal({ tables, root }: { tables: DBTables; root: URL }) {
+export function getDtsContent(tables: DBTables) {
const content = `// This file is generated by Astro DB
declare module 'astro:db' {
${Object.entries(tables)
@@ -20,14 +9,7 @@ ${Object.entries(tables)
.join('\n')}
}
`;
-
- const dotAstroDir = new URL('.astro/', root);
-
- if (!existsSync(dotAstroDir)) {
- await mkdir(dotAstroDir);
- }
-
- await writeFile(new URL(DB_TYPES_FILE, dotAstroDir), content);
+ return content;
}
function generateTableType(name: string, table: DBTable): string {
diff --git a/packages/db/src/core/integration/vite-plugin-inject-env-ts.ts b/packages/db/src/core/integration/vite-plugin-inject-env-ts.ts
deleted file mode 100644
index 14257d480fef..000000000000
--- a/packages/db/src/core/integration/vite-plugin-inject-env-ts.ts
+++ /dev/null
@@ -1,65 +0,0 @@
-import { existsSync } from 'node:fs';
-import { readFile, writeFile } from 'node:fs/promises';
-import path from 'node:path';
-import { fileURLToPath } from 'node:url';
-import type { AstroIntegrationLogger } from 'astro';
-import { bold } from 'kleur/colors';
-import { normalizePath } from 'vite';
-import { DB_TYPES_FILE } from '../consts.js';
-import type { VitePlugin } from '../utils.js';
-
-export function vitePluginInjectEnvTs(
- { srcDir, root }: { srcDir: URL; root: URL },
- logger: AstroIntegrationLogger,
-): VitePlugin {
- return {
- name: 'db-inject-env-ts',
- enforce: 'post',
- async config() {
- await setUpEnvTs({ srcDir, root, logger });
- },
- };
-}
-
-export async function setUpEnvTs({
- srcDir,
- root,
- logger,
-}: {
- srcDir: URL;
- root: URL;
- logger: AstroIntegrationLogger;
-}) {
- const envTsPath = getEnvTsPath({ srcDir });
- const envTsPathRelativetoRoot = normalizePath(
- path.relative(fileURLToPath(root), fileURLToPath(envTsPath)),
- );
-
- if (existsSync(envTsPath)) {
- let typesEnvContents = await readFile(envTsPath, 'utf-8');
- const dotAstroDir = new URL('.astro/', root);
-
- if (!existsSync(dotAstroDir)) return;
-
- const dbTypeReference = getDBTypeReference({ srcDir, dotAstroDir });
-
- if (!typesEnvContents.includes(dbTypeReference)) {
- typesEnvContents = `${dbTypeReference}\n${typesEnvContents}`;
- await writeFile(envTsPath, typesEnvContents, 'utf-8');
- logger.info(`Added ${bold(envTsPathRelativetoRoot)} types`);
- }
- }
-}
-
-function getDBTypeReference({ srcDir, dotAstroDir }: { srcDir: URL; dotAstroDir: URL }) {
- const dbTypesFile = new URL(DB_TYPES_FILE, dotAstroDir);
- const contentTypesRelativeToSrcDir = normalizePath(
- path.relative(fileURLToPath(srcDir), fileURLToPath(dbTypesFile)),
- );
-
- return `/// `;
-}
-
-function getEnvTsPath({ srcDir }: { srcDir: URL }) {
- return new URL('env.d.ts', srcDir);
-}
diff --git a/packages/db/src/index.ts b/packages/db/src/index.ts
index b26507130471..f7022a24a236 100644
--- a/packages/db/src/index.ts
+++ b/packages/db/src/index.ts
@@ -1,4 +1,3 @@
export type { TableConfig } from './core/types.js';
export { cli } from './core/cli/index.js';
export { integration as default } from './core/integration/index.js';
-export { typegen } from './core/integration/typegen.js';
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 58191b539a1d..01db0912ed26 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -93,6 +93,9 @@ importers:
pretty-bytes:
specifier: ^6.1.1
version: 6.1.1
+ sharp:
+ specifier: ^0.33.3
+ version: 0.33.3
benchmark/packages/timer:
dependencies:
@@ -585,6 +588,9 @@ importers:
'@oslojs/encoding':
specifier: ^0.4.1
version: 0.4.1
+ '@rollup/pluginutils':
+ specifier: ^5.1.0
+ version: 5.1.0(rollup@4.20.0)
'@types/babel__core':
specifier: ^7.20.5
version: 7.20.5
@@ -675,9 +681,15 @@ importers:
magic-string:
specifier: ^0.30.11
version: 0.30.11
+ micromatch:
+ specifier: ^4.0.7
+ version: 4.0.7
mrmime:
specifier: ^2.0.0
version: 2.0.0
+ neotraverse:
+ specifier: ^0.6.9
+ version: 0.6.9
ora:
specifier: ^8.0.1
version: 8.0.1
@@ -729,12 +741,18 @@ importers:
which-pm:
specifier: ^3.0.0
version: 3.0.0
+ xxhash-wasm:
+ specifier: ^1.0.2
+ version: 1.0.2
zod:
specifier: ^3.23.8
version: 3.23.8
zod-to-json-schema:
specifier: ^3.23.2
version: 3.23.2(zod@3.23.8)
+ zod-to-ts:
+ specifier: ^1.2.0
+ version: 1.2.0(typescript@5.5.4)(zod@3.23.8)
optionalDependencies:
sharp:
specifier: ^0.33.3
@@ -785,6 +803,9 @@ importers:
'@types/js-yaml':
specifier: ^4.0.9
version: 4.0.9
+ '@types/micromatch':
+ specifier: ^4.0.9
+ version: 4.0.9
'@types/prompts':
specifier: ^2.4.9
version: 2.4.9
@@ -2683,6 +2704,51 @@ importers:
specifier: workspace:*
version: link:../../..
+ packages/astro/test/fixtures/content-intellisense:
+ dependencies:
+ '@astrojs/markdoc':
+ specifier: workspace:*
+ version: link:../../../../integrations/markdoc
+ '@astrojs/mdx':
+ specifier: workspace:*
+ version: link:../../../../integrations/mdx
+ astro:
+ specifier: workspace:*
+ version: link:../../..
+
+ packages/astro/test/fixtures/content-layer:
+ dependencies:
+ '@astrojs/mdx':
+ specifier: workspace:*
+ version: link:../../../../integrations/mdx
+ astro:
+ specifier: workspace:*
+ version: link:../../..
+
+ packages/astro/test/fixtures/content-layer-markdoc:
+ dependencies:
+ '@astrojs/markdoc':
+ specifier: workspace:*
+ version: link:../../../../integrations/markdoc
+ '@astrojs/preact':
+ specifier: workspace:*
+ version: link:../../../../integrations/preact
+ astro:
+ specifier: workspace:*
+ version: link:../../..
+ preact:
+ specifier: ^10.23.1
+ version: 10.23.1
+
+ packages/astro/test/fixtures/content-layer-rendering:
+ dependencies:
+ '@astrojs/mdx':
+ specifier: workspace:*
+ version: link:../../../../integrations/mdx
+ astro:
+ specifier: workspace:*
+ version: link:../../..
+
packages/astro/test/fixtures/content-mixed-errors:
dependencies:
astro:
@@ -6077,6 +6143,10 @@ packages:
resolution: {integrity: sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A==}
engines: {node: '>=6.9.0'}
+ '@babel/helper-plugin-utils@7.24.7':
+ resolution: {integrity: sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==}
+ engines: {node: '>=6.9.0'}
+
'@babel/helper-plugin-utils@7.24.8':
resolution: {integrity: sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==}
engines: {node: '>=6.9.0'}
@@ -6193,6 +6263,10 @@ packages:
resolution: {integrity: sha512-dkxf7+hn8mFBwKjs9bvBlArzLVxVbS8usaPUDd5p2a9JCL9tB8OaOVN1isD4+Xyk4ns89/xeOmbQvgdK7IIVdA==}
engines: {node: '>=6.9.0'}
+ '@babel/template@7.24.7':
+ resolution: {integrity: sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==}
+ engines: {node: '>=6.9.0'}
+
'@babel/template@7.25.0':
resolution: {integrity: sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==}
engines: {node: '>=6.9.0'}
@@ -6744,6 +6818,10 @@ packages:
peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || >=8.0.0
+ '@eslint-community/regexpp@4.10.0':
+ resolution: {integrity: sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==}
+ engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
+
'@eslint-community/regexpp@4.11.0':
resolution: {integrity: sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==}
engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0}
@@ -6915,6 +6993,9 @@ packages:
resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==}
engines: {node: '>=6.0.0'}
+ '@jridgewell/sourcemap-codec@1.4.15':
+ resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==}
+
'@jridgewell/sourcemap-codec@1.5.0':
resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==}
@@ -7340,6 +7421,9 @@ packages:
'@types/body-parser@1.19.5':
resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==}
+ '@types/braces@3.0.4':
+ resolution: {integrity: sha512-0WR3b8eaISjEW7RpZnclONaLFDf7buaowRHdqLp4vLj54AsSAYWfh3DRbfiYJY9XDxMgx1B4sE1Afw2PGpuHOA==}
+
'@types/canvas-confetti@1.6.4':
resolution: {integrity: sha512-fNyZ/Fdw/Y92X0vv7B+BD6ysHL4xVU5dJcgzgxLdGbn8O3PezZNIJpml44lKM0nsGur+o/6+NZbZeNTt00U1uA==}
@@ -7427,6 +7511,9 @@ packages:
'@types/mdx@2.0.13':
resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==}
+ '@types/micromatch@4.0.9':
+ resolution: {integrity: sha512-7V+8ncr22h4UoYRLnLXSpTxjQrNUXtWHGeMPRJt1nULXI57G9bIcpyrHlmrQ7QK24EyyuXvYcSSWAM8GA9nqCg==}
+
'@types/mime@1.3.5':
resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==}
@@ -7748,6 +7835,11 @@ packages:
peerDependencies:
acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
+ acorn@8.12.0:
+ resolution: {integrity: sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==}
+ engines: {node: '>=0.4.0'}
+ hasBin: true
+
acorn@8.12.1:
resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==}
engines: {node: '>=0.4.0'}
@@ -7883,6 +7975,9 @@ packages:
peerDependencies:
postcss: ^8.1.0
+ axobject-query@4.0.0:
+ resolution: {integrity: sha512-+60uv1hiVFhHZeO+Lz0RYzsVHy5Wr1ayX0mwda9KPDVLNJgZ1T9Ny7VmFbLDzxsH0D87I86vgj3gFrjTJUYznw==}
+
axobject-query@4.1.0:
resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==}
engines: {node: '>= 0.4'}
@@ -7958,6 +8053,15 @@ packages:
resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==}
engines: {node: '>=8'}
+ braces@3.0.3:
+ resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
+ engines: {node: '>=8'}
+
+ browserslist@4.23.1:
+ resolution: {integrity: sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==}
+ engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
+ hasBin: true
+
browserslist@4.23.3:
resolution: {integrity: sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==}
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
@@ -8001,8 +8105,11 @@ packages:
resolution: {integrity: sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==}
engines: {node: '>=14.16'}
- caniuse-lite@1.0.30001647:
- resolution: {integrity: sha512-n83xdNiyeNcHpzWY+1aFbqCK7LuLfBricc4+alSQL2Xb6OR3XpnQAmlDG+pQcdTfiHRuLcQ96VOfrPSGiNJYSg==}
+ caniuse-lite@1.0.30001639:
+ resolution: {integrity: sha512-eFHflNTBIlFwP2AIKaYuBQN/apnUoKNhBdza8ZnW/h2di4LCZ4xFqYlxUxo+LQ76KFI1PGcC1QDxMbxTZpSCAg==}
+
+ caniuse-lite@1.0.30001649:
+ resolution: {integrity: sha512-fJegqZZ0ZX8HOWr6rcafGr72+xcgJKI9oWfDW5DrD7ExUtgZC7a7R7ZYmZqplh7XDocFdGeIFn7roAxhOeYrPQ==}
canvas-confetti@1.9.3:
resolution: {integrity: sha512-rFfTURMvmVEX1gyXFgn5QMn81bYk70qa0HLzcIOSVEyl57n6o9ItHeBtUSWdvKAPY0xlvBHno4/v3QPrT83q9g==}
@@ -8529,6 +8636,9 @@ packages:
ee-first@1.1.1:
resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
+ electron-to-chromium@1.4.816:
+ resolution: {integrity: sha512-EKH5X5oqC6hLmiS7/vYtZHZFTNdhsYG5NVPRN6Yn0kQHNBlT59+xSM8HBy66P5fxWpKgZbPqb+diC64ng295Jw==}
+
electron-to-chromium@1.5.4:
resolution: {integrity: sha512-orzA81VqLyIGUEA77YkVA1D+N+nNfl2isJVjjmOyrlxuooZ19ynb+dOlaDTqd/idKRS9lDCSBmtzM+kyCsMnkA==}
@@ -8767,6 +8877,10 @@ packages:
resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==}
engines: {node: '>=8'}
+ fill-range@7.1.1:
+ resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
+ engines: {node: '>=8'}
+
finalhandler@1.2.0:
resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==}
engines: {node: '>= 0.8'}
@@ -9468,6 +9582,9 @@ packages:
resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==}
hasBin: true
+ magic-string@0.30.10:
+ resolution: {integrity: sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==}
+
magic-string@0.30.11:
resolution: {integrity: sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==}
@@ -9710,8 +9827,8 @@ packages:
micromark@4.0.0:
resolution: {integrity: sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==}
- micromatch@4.0.5:
- resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==}
+ micromatch@4.0.7:
+ resolution: {integrity: sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==}
engines: {node: '>=8.6'}
mime-db@1.52.0:
@@ -9829,6 +9946,10 @@ packages:
resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==}
engines: {node: '>= 0.6'}
+ neotraverse@0.6.9:
+ resolution: {integrity: sha512-IJ00Agk9rMj4ChQwT/nWhLG/vC7PgNAk+BEKOE0DU5ToOHrmv3wefk8+2TcPDb4TRTQNpq0TIaDlaqvmrTAbrw==}
+ engines: {node: '>= 18'}
+
nlcst-to-string@4.0.0:
resolution: {integrity: sha512-YKLBCcUYKAg0FNlOBT6aI91qFmSiFKiluk655WzPF+DDMA02qIyy8uiRqI8QXtcFpEvll12LpL5MXqEmAZ+dcA==}
@@ -9869,6 +9990,9 @@ packages:
resolution: {integrity: sha512-X/GpUpNNiPDYUeUD183W8V4OW6OHYWI29w/QDyb+c/GzOfVEAlo6HjbW9++eXT2aV2lGg+uS+XqTD2q0pNREQA==}
engines: {node: '>=14'}
+ node-releases@2.0.14:
+ resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==}
+
node-releases@2.0.18:
resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==}
@@ -10098,6 +10222,9 @@ packages:
periscopic@3.1.0:
resolution: {integrity: sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==}
+ picocolors@1.0.0:
+ resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
+
picocolors@1.0.1:
resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==}
@@ -10336,8 +10463,8 @@ packages:
preact@10.23.1:
resolution: {integrity: sha512-O5UdRsNh4vdZaTieWe3XOgSpdMAmkIYBCT3VhQDlKrzyCm8lUYsk0fmVEvoQQifoOjFRTaHZO69ylrzTW2BH+A==}
- preferred-pm@3.1.4:
- resolution: {integrity: sha512-lEHd+yEm22jXdCphDrkvIJQU66EuLojPPtvZkpKIkiD+l0DMThF/niqZKJSoU8Vl7iuvtmzyMhir9LdVy5WMnA==}
+ preferred-pm@3.1.3:
+ resolution: {integrity: sha512-MkXsENfftWSRpzCzImcp4FRsCc3y1opwB73CfCNWyzMqArju2CrlMHlqB7VexKiPEOjGMbttv1r9fSCn5S610w==}
engines: {node: '>=10'}
preferred-pm@4.0.0:
@@ -10664,6 +10791,11 @@ packages:
resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
hasBin: true
+ semver@7.6.2:
+ resolution: {integrity: sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==}
+ engines: {node: '>=10'}
+ hasBin: true
+
semver@7.6.3:
resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==}
engines: {node: '>=10'}
@@ -11193,6 +11325,9 @@ packages:
resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==}
engines: {node: '>=18'}
+ unified@11.0.4:
+ resolution: {integrity: sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==}
+
unified@11.0.5:
resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==}
@@ -11266,6 +11401,12 @@ packages:
resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==}
engines: {node: '>= 0.8'}
+ update-browserslist-db@1.0.16:
+ resolution: {integrity: sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==}
+ hasBin: true
+ peerDependencies:
+ browserslist: '>= 4.21.0'
+
update-browserslist-db@1.1.0:
resolution: {integrity: sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==}
hasBin: true
@@ -11561,8 +11702,8 @@ packages:
resolution: {integrity: sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==}
engines: {node: '>=4'}
- which-pm@2.2.0:
- resolution: {integrity: sha512-MOiaDbA5ZZgUjkeMWM5EkJp4loW5ZRoa5bc3/aeMox/PJelMhE6t7S/mLuiY43DBupyxH+S0U1bTui9kWUlmsw==}
+ which-pm@2.0.0:
+ resolution: {integrity: sha512-Lhs9Pmyph0p5n5Z3mVnN0yWcbQYUAD7rbQUiMsQxOJ3T57k7RFe35SUwWMf7dsbDZks1uOmw4AecB/JMDj3v/w==}
engines: {node: '>=8.15'}
which-pm@3.0.0:
@@ -11635,6 +11776,9 @@ packages:
resolution: {integrity: sha512-f9s+fUkX04BxQf+7mMWAp5zk61pciie+fFLC9hX9UVvCeJQfNHRHXpeo5MPcR0EUf57PYLdt+ZO4f3Ipk2oZUw==}
engines: {node: '>=0.1'}
+ xxhash-wasm@1.0.2:
+ resolution: {integrity: sha512-ibF0Or+FivM9lNrg+HGJfVX8WJqgo+kCLDc4vx6xMeTce7Aj+DLttKbxxRR/gNLSAelRc1omAPlJ77N/Jem07A==}
+
y18n@5.0.8:
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
engines: {node: '>=10'}
@@ -11678,6 +11822,12 @@ packages:
peerDependencies:
zod: ^3.23.3
+ zod-to-ts@1.2.0:
+ resolution: {integrity: sha512-x30XE43V+InwGpvTySRNz9kB7qFU8DlyEy7BsSTCHPH1R0QasMmHWZDCzYm6bVXtj/9NNJAZF3jW8rzFvH5OFA==}
+ peerDependencies:
+ typescript: ^4.9.4 || ^5.0.2
+ zod: ^3
+
zod@3.23.8:
resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==}
@@ -11826,7 +11976,7 @@ snapshots:
dependencies:
'@babel/compat-data': 7.25.2
'@babel/helper-validator-option': 7.24.8
- browserslist: 4.23.3
+ browserslist: 4.23.1
lru-cache: 5.1.1
semver: 6.3.1
@@ -11851,7 +12001,7 @@ snapshots:
'@babel/helper-function-name@7.24.7':
dependencies:
- '@babel/template': 7.25.0
+ '@babel/template': 7.24.7
'@babel/types': 7.25.2
'@babel/helper-member-expression-to-functions@7.24.7':
@@ -11890,6 +12040,8 @@ snapshots:
dependencies:
'@babel/types': 7.25.2
+ '@babel/helper-plugin-utils@7.24.7': {}
+
'@babel/helper-plugin-utils@7.24.8': {}
'@babel/helper-replace-supers@7.24.7(@babel/core@7.25.2)':
@@ -11945,7 +12097,7 @@ snapshots:
dependencies:
'@babel/core': 7.25.2
'@babel/helper-create-class-features-plugin': 7.24.7(@babel/core@7.25.2)
- '@babel/helper-plugin-utils': 7.24.8
+ '@babel/helper-plugin-utils': 7.24.7
'@babel/plugin-syntax-decorators': 7.24.1(@babel/core@7.25.2)
transitivePeerDependencies:
- supports-color
@@ -11953,17 +12105,17 @@ snapshots:
'@babel/plugin-syntax-decorators@7.24.1(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.24.8
+ '@babel/helper-plugin-utils': 7.24.7
'@babel/plugin-syntax-import-attributes@7.24.1(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.24.8
+ '@babel/helper-plugin-utils': 7.24.7
'@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.24.8
+ '@babel/helper-plugin-utils': 7.24.7
'@babel/plugin-syntax-jsx@7.24.7(@babel/core@7.25.2)':
dependencies:
@@ -11973,7 +12125,7 @@ snapshots:
'@babel/plugin-syntax-typescript@7.24.7(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.24.8
+ '@babel/helper-plugin-utils': 7.24.7
'@babel/plugin-transform-react-jsx-development@7.24.7(@babel/core@7.25.2)':
dependencies:
@@ -11985,12 +12137,12 @@ snapshots:
'@babel/plugin-transform-react-jsx-self@7.24.7(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.24.8
+ '@babel/helper-plugin-utils': 7.24.7
'@babel/plugin-transform-react-jsx-source@7.24.1(@babel/core@7.25.2)':
dependencies:
'@babel/core': 7.25.2
- '@babel/helper-plugin-utils': 7.24.8
+ '@babel/helper-plugin-utils': 7.24.7
'@babel/plugin-transform-react-jsx@7.25.2(@babel/core@7.25.2)':
dependencies:
@@ -12008,7 +12160,7 @@ snapshots:
'@babel/core': 7.25.2
'@babel/helper-annotate-as-pure': 7.24.7
'@babel/helper-create-class-features-plugin': 7.24.7(@babel/core@7.25.2)
- '@babel/helper-plugin-utils': 7.24.8
+ '@babel/helper-plugin-utils': 7.24.7
'@babel/plugin-syntax-typescript': 7.24.7(@babel/core@7.25.2)
transitivePeerDependencies:
- supports-color
@@ -12017,6 +12169,12 @@ snapshots:
dependencies:
regenerator-runtime: 0.14.1
+ '@babel/template@7.24.7':
+ dependencies:
+ '@babel/code-frame': 7.24.7
+ '@babel/parser': 7.25.3
+ '@babel/types': 7.25.2
+
'@babel/template@7.25.0':
dependencies:
'@babel/code-frame': 7.24.7
@@ -12146,7 +12304,7 @@ snapshots:
mri: 1.2.0
outdent: 0.5.0
p-limit: 2.3.0
- preferred-pm: 3.1.4
+ preferred-pm: 3.1.3
resolve-from: 5.0.0
semver: 7.6.3
spawndamnit: 2.0.0
@@ -12160,7 +12318,7 @@ snapshots:
'@changesets/types': 6.0.0
'@manypkg/get-packages': 1.1.3
fs-extra: 7.0.1
- micromatch: 4.0.5
+ micromatch: 4.0.7
'@changesets/errors@0.2.0':
dependencies:
@@ -12200,7 +12358,7 @@ snapshots:
'@changesets/types': 6.0.0
'@manypkg/get-packages': 1.1.3
is-subdir: 1.2.0
- micromatch: 4.0.5
+ micromatch: 4.0.7
spawndamnit: 2.0.0
'@changesets/logger@0.1.0':
@@ -12251,13 +12409,13 @@ snapshots:
'@clack/core@0.3.4':
dependencies:
- picocolors: 1.0.1
+ picocolors: 1.0.0
sisteransi: 1.0.5
'@clack/prompts@0.7.0':
dependencies:
'@clack/core': 0.3.4
- picocolors: 1.0.1
+ picocolors: 1.0.0
sisteransi: 1.0.5
'@colors/colors@1.5.0':
@@ -12603,6 +12761,8 @@ snapshots:
eslint: 9.9.0(jiti@1.21.0)
eslint-visitor-keys: 3.4.3
+ '@eslint-community/regexpp@4.10.0': {}
+
'@eslint-community/regexpp@4.11.0': {}
'@eslint/config-array@0.17.1':
@@ -12732,19 +12892,21 @@ snapshots:
'@jridgewell/gen-mapping@0.3.5':
dependencies:
'@jridgewell/set-array': 1.2.1
- '@jridgewell/sourcemap-codec': 1.5.0
+ '@jridgewell/sourcemap-codec': 1.4.15
'@jridgewell/trace-mapping': 0.3.25
'@jridgewell/resolve-uri@3.1.2': {}
'@jridgewell/set-array@1.2.1': {}
+ '@jridgewell/sourcemap-codec@1.4.15': {}
+
'@jridgewell/sourcemap-codec@1.5.0': {}
'@jridgewell/trace-mapping@0.3.25':
dependencies:
'@jridgewell/resolve-uri': 3.1.2
- '@jridgewell/sourcemap-codec': 1.5.0
+ '@jridgewell/sourcemap-codec': 1.4.15
'@jsdevtools/rehype-toc@3.0.2': {}
@@ -13212,6 +13374,8 @@ snapshots:
'@types/connect': 3.4.38
'@types/node': 18.19.31
+ '@types/braces@3.0.4': {}
+
'@types/canvas-confetti@1.6.4': {}
'@types/clean-css@4.2.11':
@@ -13304,6 +13468,10 @@ snapshots:
'@types/mdx@2.0.13': {}
+ '@types/micromatch@4.0.9':
+ dependencies:
+ '@types/braces': 3.0.4
+
'@types/mime@1.3.5': {}
'@types/ms@0.7.34': {}
@@ -13511,7 +13679,7 @@ snapshots:
estree-walker: 2.0.2
glob: 7.2.3
graceful-fs: 4.2.11
- micromatch: 4.0.5
+ micromatch: 4.0.7
node-gyp-build: 4.8.0
resolve-from: 5.0.0
transitivePeerDependencies:
@@ -13638,9 +13806,9 @@ snapshots:
'@vue/babel-plugin-jsx@1.2.2(@babel/core@7.25.2)':
dependencies:
'@babel/helper-module-imports': 7.22.15
- '@babel/helper-plugin-utils': 7.24.8
+ '@babel/helper-plugin-utils': 7.24.7
'@babel/plugin-syntax-jsx': 7.24.7(@babel/core@7.25.2)
- '@babel/template': 7.25.0
+ '@babel/template': 7.24.7
'@babel/traverse': 7.25.3
'@babel/types': 7.25.2
'@vue/babel-helper-vue-transform-on': 1.2.2
@@ -13658,7 +13826,7 @@ snapshots:
'@babel/code-frame': 7.24.7
'@babel/core': 7.25.2
'@babel/helper-module-imports': 7.22.15
- '@babel/helper-plugin-utils': 7.24.8
+ '@babel/helper-plugin-utils': 7.24.7
'@babel/parser': 7.25.3
'@vue/compiler-sfc': 3.4.37
@@ -13765,6 +13933,8 @@ snapshots:
dependencies:
acorn: 8.12.1
+ acorn@8.12.0: {}
+
acorn@8.12.1: {}
agent-base@6.0.2:
@@ -13906,20 +14076,24 @@ snapshots:
progress: 2.0.3
reinterval: 1.1.0
retimer: 3.0.0
- semver: 7.6.3
+ semver: 7.6.2
subarg: 1.0.0
timestring: 6.0.0
autoprefixer@10.4.20(postcss@8.4.41):
dependencies:
browserslist: 4.23.3
- caniuse-lite: 1.0.30001647
+ caniuse-lite: 1.0.30001649
fraction.js: 4.3.7
normalize-range: 0.1.2
picocolors: 1.0.1
postcss: 8.4.41
postcss-value-parser: 4.2.0
+ axobject-query@4.0.0:
+ dependencies:
+ dequal: 2.0.3
+
axobject-query@4.1.0: {}
babel-plugin-jsx-dom-expressions@0.37.19(@babel/core@7.25.2):
@@ -14011,9 +14185,20 @@ snapshots:
dependencies:
fill-range: 7.0.1
+ braces@3.0.3:
+ dependencies:
+ fill-range: 7.1.1
+
+ browserslist@4.23.1:
+ dependencies:
+ caniuse-lite: 1.0.30001639
+ electron-to-chromium: 1.4.816
+ node-releases: 2.0.14
+ update-browserslist-db: 1.0.16(browserslist@4.23.1)
+
browserslist@4.23.3:
dependencies:
- caniuse-lite: 1.0.30001647
+ caniuse-lite: 1.0.30001649
electron-to-chromium: 1.5.4
node-releases: 2.0.18
update-browserslist-db: 1.1.0(browserslist@4.23.3)
@@ -14052,7 +14237,9 @@ snapshots:
camelcase@7.0.1: {}
- caniuse-lite@1.0.30001647: {}
+ caniuse-lite@1.0.30001639: {}
+
+ caniuse-lite@1.0.30001649: {}
canvas-confetti@1.9.3: {}
@@ -14172,7 +14359,7 @@ snapshots:
code-red@1.0.4:
dependencies:
- '@jridgewell/sourcemap-codec': 1.5.0
+ '@jridgewell/sourcemap-codec': 1.4.15
'@types/estree': 1.0.5
acorn: 8.12.1
estree-walker: 3.0.3
@@ -14449,6 +14636,8 @@ snapshots:
ee-first@1.1.1: {}
+ electron-to-chromium@1.4.816: {}
+
electron-to-chromium@1.5.4: {}
emmet@2.4.7:
@@ -14730,7 +14919,7 @@ snapshots:
'@nodelib/fs.walk': 1.2.8
glob-parent: 5.1.2
merge2: 1.4.1
- micromatch: 4.0.5
+ micromatch: 4.0.7
fast-json-stable-stringify@2.1.0: {}
@@ -14761,6 +14950,10 @@ snapshots:
dependencies:
to-regex-range: 5.0.1
+ fill-range@7.1.1:
+ dependencies:
+ to-regex-range: 5.0.1
+
finalhandler@1.2.0:
dependencies:
debug: 2.6.9
@@ -14787,7 +14980,7 @@ snapshots:
find-yarn-workspace-root2@1.2.16:
dependencies:
- micromatch: 4.0.5
+ micromatch: 4.0.7
pkg-dir: 4.2.0
flat-cache@4.0.1:
@@ -15603,13 +15796,17 @@ snapshots:
lz-string@1.5.0: {}
+ magic-string@0.30.10:
+ dependencies:
+ '@jridgewell/sourcemap-codec': 1.4.15
+
magic-string@0.30.11:
dependencies:
'@jridgewell/sourcemap-codec': 1.5.0
magic-string@0.30.5:
dependencies:
- '@jridgewell/sourcemap-codec': 1.5.0
+ '@jridgewell/sourcemap-codec': 1.4.15
make-dir@3.1.0:
dependencies:
@@ -16133,9 +16330,9 @@ snapshots:
transitivePeerDependencies:
- supports-color
- micromatch@4.0.5:
+ micromatch@4.0.7:
dependencies:
- braces: 3.0.2
+ braces: 3.0.3
picomatch: 2.3.1
mime-db@1.52.0: {}
@@ -16216,6 +16413,8 @@ snapshots:
negotiator@0.6.3: {}
+ neotraverse@0.6.9: {}
+
nlcst-to-string@4.0.0:
dependencies:
'@types/nlcst': 2.0.3
@@ -16265,6 +16464,8 @@ snapshots:
range-parser: 1.2.1
type-is: 1.6.18
+ node-releases@2.0.14: {}
+
node-releases@2.0.18: {}
nopt@5.0.0:
@@ -16494,6 +16695,8 @@ snapshots:
estree-walker: 3.0.3
is-reference: 3.0.2
+ picocolors@1.0.0: {}
+
picocolors@1.0.1: {}
picomatch@2.3.1: {}
@@ -16771,12 +16974,12 @@ snapshots:
preact@10.23.1: {}
- preferred-pm@3.1.4:
+ preferred-pm@3.1.3:
dependencies:
find-up: 5.0.0
find-yarn-workspace-root2: 1.2.16
path-exists: 4.0.0
- which-pm: 2.2.0
+ which-pm: 2.0.0
preferred-pm@4.0.0:
dependencies:
@@ -16885,7 +17088,7 @@ snapshots:
refa@0.12.1:
dependencies:
- '@eslint-community/regexpp': 4.11.0
+ '@eslint-community/regexpp': 4.10.0
regenerator-runtime@0.13.11: {}
@@ -16893,7 +17096,7 @@ snapshots:
regexp-ast-analysis@0.7.1:
dependencies:
- '@eslint-community/regexpp': 4.11.0
+ '@eslint-community/regexpp': 4.10.0
refa: 0.12.1
rehype-autolink-headings@7.1.0:
@@ -16902,7 +17105,7 @@ snapshots:
'@ungap/structured-clone': 1.2.0
hast-util-heading-rank: 3.0.0
hast-util-is-element: 3.0.0
- unified: 11.0.5
+ unified: 11.0.4
unist-util-visit: 5.0.0
rehype-mathjax@6.0.0:
@@ -17175,7 +17378,7 @@ snapshots:
scslre@0.3.0:
dependencies:
- '@eslint-community/regexpp': 4.11.0
+ '@eslint-community/regexpp': 4.10.0
refa: 0.12.1
regexp-ast-analysis: 0.7.1
@@ -17186,6 +17389,8 @@ snapshots:
semver@6.3.1: {}
+ semver@7.6.2: {}
+
semver@7.6.3: {}
send@0.18.0:
@@ -17242,7 +17447,7 @@ snapshots:
dependencies:
color: 4.2.3
detect-libc: 2.0.3
- semver: 7.6.3
+ semver: 7.6.2
optionalDependencies:
'@img/sharp-darwin-arm64': 0.33.3
'@img/sharp-darwin-x64': 0.33.3
@@ -17507,18 +17712,18 @@ snapshots:
svelte@4.2.18:
dependencies:
'@ampproject/remapping': 2.3.0
- '@jridgewell/sourcemap-codec': 1.5.0
+ '@jridgewell/sourcemap-codec': 1.4.15
'@jridgewell/trace-mapping': 0.3.25
'@types/estree': 1.0.5
- acorn: 8.12.1
+ acorn: 8.12.0
aria-query: 5.3.0
- axobject-query: 4.1.0
+ axobject-query: 4.0.0
code-red: 1.0.4
css-tree: 2.3.1
estree-walker: 3.0.3
is-reference: 3.0.2
locate-character: 3.0.0
- magic-string: 0.30.11
+ magic-string: 0.30.10
periscopic: 3.1.0
svg-tags@1.0.0: {}
@@ -17531,7 +17736,7 @@ snapshots:
css-tree: 2.3.1
css-what: 6.1.0
csso: 5.0.5
- picocolors: 1.0.1
+ picocolors: 1.0.0
symbol-tree@3.2.4: {}
@@ -17547,7 +17752,7 @@ snapshots:
is-glob: 4.0.3
jiti: 1.21.0
lilconfig: 2.1.0
- micromatch: 4.0.5
+ micromatch: 4.0.7
normalize-path: 3.0.0
object-hash: 3.0.0
picocolors: 1.0.1
@@ -17748,6 +17953,16 @@ snapshots:
unicorn-magic@0.1.0: {}
+ unified@11.0.4:
+ dependencies:
+ '@types/unist': 3.0.2
+ bail: 2.0.2
+ devlop: 1.1.0
+ extend: 3.0.2
+ is-plain-obj: 4.1.0
+ trough: 2.2.0
+ vfile: 6.0.2
+
unified@11.0.5:
dependencies:
'@types/unist': 3.0.2
@@ -17844,6 +18059,12 @@ snapshots:
unpipe@1.0.0: {}
+ update-browserslist-db@1.0.16(browserslist@4.23.1):
+ dependencies:
+ browserslist: 4.23.1
+ escalade: 3.1.2
+ picocolors: 1.0.1
+
update-browserslist-db@1.1.0(browserslist@4.23.3):
dependencies:
browserslist: 4.23.3
@@ -18156,7 +18377,7 @@ snapshots:
which-pm-runs@1.1.0: {}
- which-pm@2.2.0:
+ which-pm@2.0.0:
dependencies:
load-yaml-file: 0.2.0
path-exists: 4.0.0
@@ -18217,6 +18438,8 @@ snapshots:
xmldom-sre@0.1.31: {}
+ xxhash-wasm@1.0.2: {}
+
y18n@5.0.8: {}
yallist@2.1.2: {}
@@ -18249,6 +18472,11 @@ snapshots:
dependencies:
zod: 3.23.8
+ zod-to-ts@1.2.0(typescript@5.5.4)(zod@3.23.8):
+ dependencies:
+ typescript: 5.5.4
+ zod: 3.23.8
+
zod@3.23.8: {}
zwitch@2.0.4: {}