Fix fetchContent
for nested files (#171)
* fix: fetchContent within nested folders * feat: add `sourceId` to fetchContent * test: update collection tests * fix: windows compat for importPath * chore: add changeset * fix: astroRoot => projectRoot * feat: add `slash` package * chore: remove sourceId prop * chore: update changeset * format
This commit is contained in:
parent
0054f78e42
commit
3ad0aac8cf
10 changed files with 60 additions and 10 deletions
5
.changeset/polite-sheep-raise.md
Normal file
5
.changeset/polite-sheep-raise.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
'astro': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Fix `fetchContent` API bug for nested `.md` files
|
23
examples/portfolio/src/pages/project/nested/lunar-eclipse.md
Normal file
23
examples/portfolio/src/pages/project/nested/lunar-eclipse.md
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
---
|
||||||
|
layout: ../../../layouts/project.astro
|
||||||
|
title: Lunar Eclipse
|
||||||
|
client: Self
|
||||||
|
published_at: 2020-03-04 00:00:00
|
||||||
|
img: https://images.unsplash.com/photo-1548391350-1a529f6ea42d?fit=crop&w=1400&h=700&q=75
|
||||||
|
description: |
|
||||||
|
We took some cool pictures of the moon and made a website about it.
|
||||||
|
tags:
|
||||||
|
- design
|
||||||
|
- dev
|
||||||
|
- branding
|
||||||
|
---
|
||||||
|
|
||||||
|
Rubber cheese mascarpone cut the cheese. Jarlsberg parmesan cheesy grin cream cheese port-salut stinking bishop ricotta brie. Roquefort when the cheese comes out everybody's happy goat cheese triangles stilton cheese and biscuits goat babybel. Bocconcini roquefort queso danish fontina pecorino.
|
||||||
|
|
||||||
|
Smelly cheese stinking bishop roquefort. Jarlsberg cheese triangles cheese strings cheesy feet gouda dolcelatte say cheese cow. Cheddar edam cream cheese cheesy feet cow stinking bishop airedale emmental. Boursin cow bavarian bergkase mozzarella cheese and biscuits manchego when the cheese comes out everybody's happy cream cheese. Cheese on toast st. agur blue cheese croque monsieur halloumi.
|
||||||
|
|
||||||
|
Fromage frais jarlsberg st. agur blue cheese. Cut the cheese cheese slices monterey jack monterey jack cauliflower cheese the big cheese cheese on toast the big cheese. Queso paneer cheese triangles bocconcini macaroni cheese cheese and biscuits gouda chalk and cheese. Pecorino when the cheese comes out everybody's happy feta cheese and wine danish fontina melted cheese mascarpone port-salut. When the cheese comes out everybody's happy pecorino cottage cheese.
|
||||||
|
|
||||||
|
Caerphilly parmesan manchego. Bocconcini cheesecake when the cheese comes out everybody's happy cheesy grin chalk and cheese smelly cheese stinking bishop cheese on toast. Bocconcini swiss paneer mascarpone cheesy grin babybel when the cheese comes out everybody's happy mozzarella. Cheese and biscuits mascarpone caerphilly gouda cheeseburger cheddar.
|
||||||
|
|
||||||
|
Cheese and biscuits cheesy grin roquefort. Ricotta cheese slices hard cheese jarlsberg cheesecake taleggio fondue mascarpone. Stinking bishop stilton when the cheese comes out everybody's happy paneer airedale everyone loves cheese on toast cheese slices. Ricotta cut the cheese cheese triangles babybel cream cheese ricotta.
|
|
@ -78,8 +78,8 @@
|
||||||
"rollup-plugin-terser": "^7.0.2",
|
"rollup-plugin-terser": "^7.0.2",
|
||||||
"sass": "^1.32.8",
|
"sass": "^1.32.8",
|
||||||
"snowpack": "^3.3.7",
|
"snowpack": "^3.3.7",
|
||||||
"string-width": "^5.0.0",
|
|
||||||
"source-map-support": "^0.5.19",
|
"source-map-support": "^0.5.19",
|
||||||
|
"string-width": "^5.0.0",
|
||||||
"svelte": "^3.35.0",
|
"svelte": "^3.35.0",
|
||||||
"unified": "^9.2.1",
|
"unified": "^9.2.1",
|
||||||
"vue": "^3.0.10",
|
"vue": "^3.0.10",
|
||||||
|
@ -98,7 +98,8 @@
|
||||||
"@types/react-dom": "^17.0.2",
|
"@types/react-dom": "^17.0.2",
|
||||||
"@types/sass": "^1.16.0",
|
"@types/sass": "^1.16.0",
|
||||||
"@types/yargs-parser": "^20.2.0",
|
"@types/yargs-parser": "^20.2.0",
|
||||||
"astro-scripts": "0.0.1"
|
"astro-scripts": "0.0.1",
|
||||||
|
"slash": "^4.0.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=14.0.0",
|
"node": ">=14.0.0",
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { fdir, PathsOutput } from 'fdir';
|
import { fdir, PathsOutput } from 'fdir';
|
||||||
|
import { fileURLToPath } from 'url';
|
||||||
|
import slash from 'slash';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handling for import.meta.glob and import.meta.globEager
|
* Handling for import.meta.glob and import.meta.globEager
|
||||||
|
@ -8,6 +10,7 @@ import { fdir, PathsOutput } from 'fdir';
|
||||||
interface GlobOptions {
|
interface GlobOptions {
|
||||||
namespace: string;
|
namespace: string;
|
||||||
filename: string;
|
filename: string;
|
||||||
|
projectRoot: URL;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface GlobResult {
|
interface GlobResult {
|
||||||
|
@ -39,13 +42,16 @@ function globSearch(spec: string, { filename }: { filename: string }): string[]
|
||||||
}
|
}
|
||||||
|
|
||||||
const cwd = path.join(path.dirname(filename), globDir.replace(/\//g, path.sep)); // this must match OS (could be '/' or '\')
|
const cwd = path.join(path.dirname(filename), globDir.replace(/\//g, path.sep)); // this must match OS (could be '/' or '\')
|
||||||
let found = crawler.glob(glob).crawl(cwd).sync() as PathsOutput;
|
let found = crawler
|
||||||
|
.glob(glob)
|
||||||
|
.crawlWithOptions(cwd, { includeBasePath: true })
|
||||||
|
.sync() as PathsOutput;
|
||||||
if (!found.length) {
|
if (!found.length) {
|
||||||
throw new Error(`No files matched "${spec}" from ${filename}`);
|
throw new Error(`No files matched "${spec}" from ${filename}`);
|
||||||
}
|
}
|
||||||
return found.map((importPath) => {
|
return found.map(importPath => {
|
||||||
if (importPath.startsWith('http') || importPath.startsWith('.')) return importPath;
|
if (importPath.startsWith('http') || importPath.startsWith('.')) return importPath;
|
||||||
return `./` + globDir + '/' + importPath;
|
return './' + path.posix.join(globDir, path.posix.relative(slash(cwd), importPath));
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
throw new Error(`No files matched "${spec}" from ${filename}`);
|
throw new Error(`No files matched "${spec}" from ${filename}`);
|
||||||
|
@ -65,6 +71,7 @@ export function fetchContent(spec: string, { namespace, filename }: GlobOptions)
|
||||||
|
|
||||||
// add URL if this appears within the /pages/ directory (probably can be improved)
|
// add URL if this appears within the /pages/ directory (probably can be improved)
|
||||||
const fullPath = path.resolve(path.dirname(filename), importPath);
|
const fullPath = path.resolve(path.dirname(filename), importPath);
|
||||||
|
|
||||||
if (fullPath.includes(`${path.sep}pages${path.sep}`)) {
|
if (fullPath.includes(`${path.sep}pages${path.sep}`)) {
|
||||||
const url = importPath.replace(/^\./, '').replace(/\.md$/, '');
|
const url = importPath.replace(/^\./, '').replace(/\.md$/, '');
|
||||||
imports.add(`${id}.url = '${url}';`);
|
imports.add(`${id}.url = '${url}';`);
|
||||||
|
|
|
@ -477,7 +477,7 @@ function compileModule(module: Script, state: CodegenState, compileOptions: Comp
|
||||||
const spec = (init as any).arguments[0].value;
|
const spec = (init as any).arguments[0].value;
|
||||||
if (typeof spec !== 'string') break;
|
if (typeof spec !== 'string') break;
|
||||||
|
|
||||||
const globResult = fetchContent(spec, { namespace, filename: state.filename });
|
const globResult = fetchContent(spec, { namespace, filename: state.filename, projectRoot: compileOptions.astroConfig.projectRoot });
|
||||||
|
|
||||||
let imports = '';
|
let imports = '';
|
||||||
for (const importStatement of globResult.imports) {
|
for (const importStatement of globResult.imports) {
|
||||||
|
@ -496,7 +496,7 @@ function compileModule(module: Script, state: CodegenState, compileOptions: Comp
|
||||||
|
|
||||||
// Astro.fetchContent()
|
// Astro.fetchContent()
|
||||||
for (const [namespace, { spec }] of contentImports.entries()) {
|
for (const [namespace, { spec }] of contentImports.entries()) {
|
||||||
const globResult = fetchContent(spec, { namespace, filename: state.filename });
|
const globResult = fetchContent(spec, { namespace, filename: state.filename, projectRoot: compileOptions.astroConfig.projectRoot });
|
||||||
for (const importStatement of globResult.imports) {
|
for (const importStatement of globResult.imports) {
|
||||||
state.importExportStatements.add(importStatement);
|
state.importExportStatements.add(importStatement);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ import type { TransformOptions, Transformer } from '../../@types/transformer';
|
||||||
import type { TemplateNode } from 'astro-parser';
|
import type { TemplateNode } from 'astro-parser';
|
||||||
import { debug } from '../../logger.js';
|
import { debug } from '../../logger.js';
|
||||||
import astroScopedStyles, { NEVER_SCOPED_TAGS } from './postcss-scoped-styles/index.js';
|
import astroScopedStyles, { NEVER_SCOPED_TAGS } from './postcss-scoped-styles/index.js';
|
||||||
|
import slash from 'slash';
|
||||||
|
|
||||||
type StyleType = 'css' | 'scss' | 'sass' | 'postcss';
|
type StyleType = 'css' | 'scss' | 'sass' | 'postcss';
|
||||||
|
|
||||||
|
@ -40,7 +41,7 @@ const getStyleType: Map<string, StyleType> = new Map([
|
||||||
function hashFromFilename(filename: string): string {
|
function hashFromFilename(filename: string): string {
|
||||||
const hash = crypto.createHash('sha256');
|
const hash = crypto.createHash('sha256');
|
||||||
return hash
|
return hash
|
||||||
.update(filename.replace(/\\/g, '/'))
|
.update(slash(filename))
|
||||||
.digest('base64')
|
.digest('base64')
|
||||||
.toString()
|
.toString()
|
||||||
.replace(/[^A-Za-z0-9-]/g, '')
|
.replace(/[^A-Za-z0-9-]/g, '')
|
||||||
|
|
|
@ -15,7 +15,7 @@ Collections('generates list & sorts successfully', async ({ runtime }) => {
|
||||||
return $(this).attr('href');
|
return $(this).attr('href');
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
assert.equal(urls, ['/post/three', '/post/two']);
|
assert.equal(urls, ['/post/nested/a', '/post/three', '/post/two']);
|
||||||
});
|
});
|
||||||
|
|
||||||
Collections('generates pagination successfully', async ({ runtime }) => {
|
Collections('generates pagination successfully', async ({ runtime }) => {
|
||||||
|
|
|
@ -8,7 +8,7 @@ export async function createCollection() {
|
||||||
data.sort((a, b) => new Date(b.date) - new Date(a.date));
|
data.sort((a, b) => new Date(b.date) - new Date(a.date));
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
pageSize: 2
|
pageSize: 3
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
---
|
---
|
||||||
|
|
8
packages/astro/test/fixtures/astro-collection/src/pages/post/nested/a.md
vendored
Normal file
8
packages/astro/test/fixtures/astro-collection/src/pages/post/nested/a.md
vendored
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
---
|
||||||
|
title: Post A
|
||||||
|
date: 2021-04-16 00:00:00
|
||||||
|
---
|
||||||
|
|
||||||
|
# Post A
|
||||||
|
|
||||||
|
I’m the "A" blog post
|
|
@ -10041,6 +10041,11 @@ slash@^3.0.0:
|
||||||
resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz"
|
resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz"
|
||||||
integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
|
integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
|
||||||
|
|
||||||
|
slash@^4.0.0:
|
||||||
|
version "4.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/slash/-/slash-4.0.0.tgz#2422372176c4c6c5addb5e2ada885af984b396a7"
|
||||||
|
integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==
|
||||||
|
|
||||||
slice-ansi@^2.1.0:
|
slice-ansi@^2.1.0:
|
||||||
version "2.1.0"
|
version "2.1.0"
|
||||||
resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz"
|
resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz"
|
||||||
|
|
Loading…
Reference in a new issue