Skip to content

Commit

Permalink
Merge branch 'main' into docs/surround-docs
Browse files Browse the repository at this point in the history
  • Loading branch information
farnabaz committed Oct 18, 2022
2 parents dbf56b0 + 98271a7 commit b1187ce
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 28 deletions.
4 changes: 3 additions & 1 deletion src/runtime/composables/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ import { addPrerenderPath, shouldUseClientDB, withContentBase } from './utils'
*/
export const createQueryFetch = <T = ParsedContent>(path?: string) => async (query: QueryBuilder<T>) => {
if (path) {
if (query.params().first) {
if (query.params().first && (query.params().where || []).length === 0) {
// If query contains `path` and does not contain any `where` condition
// Then can use `path` as `where` condition to find exact match
query.where({ _path: withoutTrailingSlash(path) })
} else {
query.where({ _path: new RegExp(`^${path.replace(/[-[\]{}()*+.,^$\s/]/g, '\\$&')}`) })
Expand Down
9 changes: 5 additions & 4 deletions src/runtime/transformers/path-meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,13 @@ export default defineTransformer({
// Check first part for locale name
const _locale = locales.includes(parts[0]) ? parts.shift() : defaultLocale

const filePath = parts.join('/')
const filePath = generatePath(parts.join('/'))

return <ParsedContent> {
_path: generatePath(filePath),
_draft: isDraft(filePath),
_partial: isPartial(filePath),
_path: filePath,
_dir: filePath.split('/').slice(-2)[0],
_draft: isDraft(_path),
_partial: isPartial(_path),
_locale,
...content,
// TODO: move title to Markdown parser
Expand Down
43 changes: 39 additions & 4 deletions test/features/content-query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,33 +11,68 @@ export const testContentQuery = () => {
})

test('exact match foo not found', async () => {
const content = await $fetch('/features/query-content?path=/foo&findOne=1')
const content = await $fetch('/features/query-content?path=/prefix/foo&findOne=1')

// empty
expect(content).includes('$$$$')
})

// test `queryContent( PREFIX ).findOne()`
test('exact match foo/bar found', async () => {
const content = await $fetch('/features/query-content?path=/foo/bar&findOne=1')
const content = await $fetch('/features/query-content?path=/prefix/foo/bar&findOne=1')

// empty
expect(content).includes('prefix:foo:bar.md$$')
})

// test `queryContent( PREFIX ).find()`
test('prefix queries', async () => {
const content = await $fetch('/features/query-content?path=/foo')
const content = await $fetch('/features/query-content?path=/prefix/foo')

expect(content).includes('prefix:foo:bar.md')
expect(content).includes('prefix:foo:baz.md')
expect(content).includes('prefix:foobarbaz.md')
})

// test `queryContent( PREFIX ).find()` with trailing slash
test('directory listing', async () => {
const content = await $fetch('/features/query-content?path=/foo/')
const content = await $fetch('/features/query-content?path=/prefix/foo/')

expect(content).includes('prefix:foo:bar.md')
expect(content).includes('prefix:foo:baz.md')
expect(content).not.includes('prefix:foobarbaz.md')
})

// test `queryContent( PREFIX ).where( CONDITION ).find()`
test('list contents with tag', async () => {
const content = await $fetch('/features/query-content?where={"tags": { "$contains": "mdc" } }')

expect(content).includes(':mdc-props-inline.md')
expect(content).includes(':mdc-props.md')
})

// test `queryContent( PREFIX ).where( CONDITION ).findOne()`
test('find contents with tag', async () => {
const content = await $fetch('/features/query-content?where={"tags": { "$contains": "mdc" } }&findOne=1')

expect(content).includes(':mdc-props-inline.md')
expect(content).not.includes(':mdc-props.md')
})

// test `queryContent().where( CONDITION ).find()`
test('find contents with tag', async () => {
const content = await $fetch('/features/query-content?prefix=&where={"tags": { "$contains": "mdc" } }')

expect(content).includes(':mdc-props-inline.md')
expect(content).includes(':mdc-props.md')
})

// test `queryContent().where( CONDITION ).findOne()`
test('find contents with tag', async () => {
const content = await $fetch('/features/query-content?prefix=&where={"tags": { "$contains": "mdc" } }&findOne=1')

expect(content).includes(':mdc-props-inline.md')
expect(content).not.includes(':mdc-props.md')
})
})
}
33 changes: 24 additions & 9 deletions test/features/transformer-path-meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,36 +7,41 @@ const testCases = {
title: '',
_draft: false,
_partial: false,
_path: '/'
_path: '/',
_dir: ''
},
'content:3.index.draft.md': {
__description: 'Index file with position [Draft]',
title: '',
_draft: true,
_partial: false,
_path: '/'
_path: '/',
_dir: ''
},
'content:1.blog:3.index.draft.md': {
__description: 'Blog Index file with position [Draft]',
title: '',
_draft: true,
_partial: false,
_path: '/blog'
_path: '/blog',
_dir: ''
},
'content:1.blog:_4.the-post.md': {
__description: 'Blog post file with position [Partial]',
title: '4The Post',
_draft: false,
_partial: true,
_path: '/blog/_4.the-post'
_path: '/blog/_4.the-post',
_dir: 'blog'
},
...['1.0.0', '1.1', '1', '1.x', '1.0.x', '1.0.0.x'].reduce((map, semver) => {
map[`content:${semver}:doc.md`] = {
title: 'Doc',
_draft: false,
_partial: false,
_path: `/${semver}/doc`,
_source: 'content'
_source: 'content',
_dir: semver
}
return map
}, {}),
Expand All @@ -45,28 +50,32 @@ const testCases = {
title: 'Doc',
_draft: false,
_partial: false,
_path: '/one/two/three/four/five/doc'
_path: '/one/two/three/four/five/doc',
_dir: 'five'
},
'content:1.one:file?param=value#hash.md': {
__description: 'Handle special chars in file name',
title: 'File?param=value#hash',
_draft: false,
_partial: false,
_path: '/one/fileparamvaluehash'
_path: '/one/fileparamvaluehash',
_dir: 'one'
},
'content:indexer.md': {
__description: 'non-index file with index substring',
title: 'Indexer',
_draft: false,
_partial: false,
_path: '/indexer'
_path: '/indexer',
_dir: ''
},
'content:indexer.draft.md': {
__description: 'non-index file with index substring',
title: 'Indexer',
_draft: true,
_partial: false,
_path: '/indexer'
_path: '/indexer',
_dir: ''
}
}

Expand Down Expand Up @@ -110,6 +119,12 @@ export const testPathMetaTransformer = () => {
`source is not equal, recieved: ${transformed._source}`
)

expect(transformed).toHaveProperty('_dir')
assert(
transformed._dir === expected._dir,
`directory is not equal, recieved: ${transformed._dir}`
)

expect(transformed).toHaveProperty('_path')
assert(
fullPath.startsWith(`${transformed._source}/${transformed._file}`),
Expand Down
2 changes: 2 additions & 0 deletions test/fixtures/basic/content/_partial/mdc-props-inline.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
---
tags:
- mdc
categories:
- Art
- History
Expand Down
2 changes: 2 additions & 0 deletions test/fixtures/basic/content/_partial/mdc-props.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
---
tags:
- mdc
categories:
- Art
- History
Expand Down
20 changes: 13 additions & 7 deletions test/fixtures/basic/pages/features/query-content.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,21 @@

<script setup>
const route = useRoute()
const path = route.query.path
const findOne = route.query.findOne
const prefix = route.query.prefix === undefined ? '/_partial' : ''
const path = route.query.path || ''
const findOne = route.query.findOne || false
const where = route.query.where ? JSON.parse(route.query.where) : false
const { data } = await useAsyncData('foo', () => {
const q = queryContent('/_partial/prefix' + path)
return findOne ? q.findOne() : q.find()
}, {
transform: (data) => {
return findOne ? data._id : data.map(d => d._id)
let q = queryContent(prefix + path || undefined)
if (where) {
q = q.where(where)
}
return findOne ? q.findOne() : q.find()
},
{
transform: data => findOne ? data._id : data.map(d => d._id)
})
</script>
6 changes: 3 additions & 3 deletions test/fixtures/basic/server/api/parse.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { defineEventHandler, useBody } from 'h3'
import { eventHandler, readBody } from 'h3'
import { parseContent } from '#content/server'

export default defineEventHandler(async (event) => {
const { id, content, options } = await useBody(event)
export default eventHandler(async (event) => {
const { id, content, options } = await readBody(event)

// @ts-ignore
const parsedContent = await parseContent(id, content, options)
Expand Down

0 comments on commit b1187ce

Please sign in to comment.