diff --git a/apps/api/package.json b/apps/api/package.json index bb6cf03..7bce628 100644 --- a/apps/api/package.json +++ b/apps/api/package.json @@ -26,9 +26,9 @@ "pino-pretty": "10.0.0", "@gokceno/crux-graphql-schema": "1.0.6", "@gokceno/crux-locales": "0.0.2", - "@gokceno/crux-bucket": "1.1.6", + "@gokceno/crux-bucket": "1.2.0", "@gokceno/crux-bucket-cache-libsql": "0.3.10", - "@gokceno/crux-bucket-source-filesystem": "0.0.9", - "@gokceno/crux-bucket-source-github": "0.0.9" + "@gokceno/crux-bucket-source-filesystem": "0.1.0", + "@gokceno/crux-bucket-source-github": "0.1.0" } } diff --git a/packages/bucket-source-filesystem/CHANGELOG.md b/packages/bucket-source-filesystem/CHANGELOG.md index 6846e7b..29023a2 100644 --- a/packages/bucket-source-filesystem/CHANGELOG.md +++ b/packages/bucket-source-filesystem/CHANGELOG.md @@ -1,5 +1,11 @@ # @gokceno/crux-bucket-source-filesystem +## 0.1.0 + +### Minor Changes + +- Implemented locale based folder/file scanning. + ## 0.0.9 ### Patch Changes diff --git a/packages/bucket-source-filesystem/package.json b/packages/bucket-source-filesystem/package.json index e3fc7fe..185d068 100644 --- a/packages/bucket-source-filesystem/package.json +++ b/packages/bucket-source-filesystem/package.json @@ -1,7 +1,7 @@ { "name": "@gokceno/crux-bucket-source-filesystem", "repository": "git+https://github.com/gokceno/crux.md.git", - "version": "0.0.9", + "version": "0.1.0", "main": "./src/Filesystem.js", "type": "module", "publishConfig": { diff --git a/packages/bucket-source-filesystem/src/Filesystem.js b/packages/bucket-source-filesystem/src/Filesystem.js index 1bce157..6cd384b 100644 --- a/packages/bucket-source-filesystem/src/Filesystem.js +++ b/packages/bucket-source-filesystem/src/Filesystem.js @@ -5,7 +5,7 @@ import slugify from '@sindresorhus/slugify' export const FileSystem = ({ bucketPath }) => { const _defaultFileExtension = 'md'; - const _root = [(bucketPath || './')]; + const _root = bucketPath || './'; const _slugifyReplacements = [ ['ü', 'u'], ['Ü', 'u'], @@ -19,9 +19,9 @@ export const FileSystem = ({ bucketPath }) => { ['Ç', 'c'], ['&', ''], ]; - const open = async({ filename }) => { + const open = async(filename) => { try { - return await fs.readFile(path.join(..._root, filename), 'utf8'); + return await fs.readFile(path.join(_root, filename), 'utf8'); } catch(e) { console.error(e); @@ -30,14 +30,18 @@ export const FileSystem = ({ bucketPath }) => { } const list = async ({ collection, locale, omitBody = true }) => { try { - const filenames = await fs.readdir(path.join(..._root, (locale ?? ''), 'collections', collection)); + const filenames = await fs.readdir( + _constructPath({ root: _root, collection, locale }) + ); const filteredFiles = filenames.filter(filename => filename.split('.')[1] === _defaultFileExtension); const filePromises = filteredFiles.map(async (filename) => { - const file = await open({ filename: path.join((locale ?? ''), 'collections', collection, filename) }); - const frontMatter = _extractFrontMatter(file); + const file = await open( + _constructPath({ locale, collection, filename }) + ); if(file === undefined) { throw new Error('Failed to get file contents or types got mixed up.'); } + const frontMatter = _extractFrontMatter(file); return { _id: slugify(filename.replace('.' + _defaultFileExtension, ''), { customReplacements: _slugifyReplacements, decamelize: false }), _slug: slugify(frontMatter.title || '', { customReplacements: _slugifyReplacements, decamelize: false }), @@ -52,16 +56,39 @@ export const FileSystem = ({ bucketPath }) => { throw new Error('One or more paths not found.'); } } - const get = async({ filename, locale }) => { - let file = await open({ filename: path.join((locale ?? ''), 'singles', [filename, _defaultFileExtension].join('.')) }); + const get = async({ single, locale }) => { + let file = await open( + _constructPath({ locale, single }) + ); const frontMatter = _extractFrontMatter(file); return { - _id: slugify(filename.replace('.' + _defaultFileExtension, ''), { customReplacements: _slugifyReplacements, decamelize: false }), + _id: slugify(single, { customReplacements: _slugifyReplacements, decamelize: false }), _slug: slugify(frontMatter.title || '', { customReplacements: _slugifyReplacements, decamelize: false }), ...frontMatter, ..._extractBody(file), } } + const _constructPath = ({ root, collection, single, filename, locale }) => { + let language, country; + let fragments = []; + if(root !== undefined) fragments.push(root); + if(locale !== undefined) { + // eslint-disable-next-line no-unused-vars + [language, country] = locale.split('-'); + fragments.push(language); + } + if(collection !== undefined) { + fragments.push('collections', collection); + if (filename !== undefined) fragments.push(filename); + } + else if(single !== undefined) { + fragments.push('singles', [single, _defaultFileExtension].join('.')); + } + else { + throw new Error('Misformed file path.') + } + return path.join(...fragments); + } const _extractBody = (file) => { const body = file.split('---')[2]; if(body === undefined) throw new Error('Can not extract body, file may be formatted incorrectly.'); diff --git a/packages/bucket-source-github/CHANGELOG.md b/packages/bucket-source-github/CHANGELOG.md index 38d13f8..d508afb 100644 --- a/packages/bucket-source-github/CHANGELOG.md +++ b/packages/bucket-source-github/CHANGELOG.md @@ -1,5 +1,11 @@ # @gokceno/crux-bucket-source-filesystem +## 0.1.0 + +### Minor Changes + +- Implemented locale based folder/file scanning. + ## 0.0.9 ### Patch Changes diff --git a/packages/bucket-source-github/package.json b/packages/bucket-source-github/package.json index 80180f8..9dd7c1e 100644 --- a/packages/bucket-source-github/package.json +++ b/packages/bucket-source-github/package.json @@ -1,7 +1,7 @@ { "name": "@gokceno/crux-bucket-source-github", "repository": "git+https://github.com/gokceno/crux.md.git", - "version": "0.0.9", + "version": "0.1.0", "main": "./src/GitHub.js", "type": "module", "publishConfig": { diff --git a/packages/bucket-source-github/src/GitHub.js b/packages/bucket-source-github/src/GitHub.js index 9aedba2..bfb3521 100644 --- a/packages/bucket-source-github/src/GitHub.js +++ b/packages/bucket-source-github/src/GitHub.js @@ -19,7 +19,7 @@ export const GitHub = ({ owner, repo, basePath = '', auth, headers = { 'X-GitHub ['Ç', 'c'], ['&', ''], ]; - const open = async({ filename }) => { + const open = async(filename) => { try { const response = await _octokit.request(`GET /repos/${owner}/${repo}/contents/${path.join(basePath, filename)}`, { owner, @@ -47,7 +47,7 @@ export const GitHub = ({ owner, repo, basePath = '', auth, headers = { 'X-GitHub headers }); const promises = response?.data?.filter(d => d.name.split('.')[1] === _defaultFileExtension).map(async (file) => { - const fileContents = await open({ filename: path.join((locale ?? ''), 'collections', collection, file.name) }); + const fileContents = await open(path.join((locale ?? ''), 'collections', collection, file.name)); const frontMatter = _extractFrontMatter(fileContents); return { _id: slugify(file.name.replace('.' + _defaultFileExtension, ''), { customReplacements: _slugifyReplacements, decamelize: false }), @@ -64,13 +64,13 @@ export const GitHub = ({ owner, repo, basePath = '', auth, headers = { 'X-GitHub throw new Error('Generic error.'); } } - const get = async({ filename, locale }) => { - let finalPath = ['singles', [filename, _defaultFileExtension].join('.')]; + const get = async({ single, locale }) => { + let finalPath = ['singles', [single, _defaultFileExtension].join('.')]; if(locale !== undefined) finalPath.unshift(locale); - const fileContents = await open({ filename: path.join(...finalPath) }); + const fileContents = await open(path.join(...finalPath)); const frontMatter = _extractFrontMatter(fileContents); return { - _id: slugify(filename.replace('.' + _defaultFileExtension, ''), { customReplacements: _slugifyReplacements, decamelize: false }), + _id: slugify(single, { customReplacements: _slugifyReplacements, decamelize: false }), _slug: slugify(frontMatter.title || '', { customReplacements: _slugifyReplacements, decamelize: false }), ...frontMatter, ..._extractBody(fileContents), diff --git a/packages/bucket/CHANGELOG.md b/packages/bucket/CHANGELOG.md index 6a6b06c..748f22e 100644 --- a/packages/bucket/CHANGELOG.md +++ b/packages/bucket/CHANGELOG.md @@ -1,5 +1,11 @@ # @gokceno/crux-bucket +## 1.2.0 + +### Minor Changes + +- Implemented locale based folder/file scanning. + ## 1.1.6 ### Patch Changes diff --git a/packages/bucket/package.json b/packages/bucket/package.json index 0e36dc1..5921490 100644 --- a/packages/bucket/package.json +++ b/packages/bucket/package.json @@ -1,7 +1,7 @@ { "name": "@gokceno/crux-bucket", "repository": "git+https://github.com/gokceno/crux.md.git", - "version": "1.1.6", + "version": "1.2.0", "main": "./src/Bucket.js", "type": "module", "publishConfig": { diff --git a/packages/bucket/src/Bucket.js b/packages/bucket/src/Bucket.js index aba7906..e7cb6ed 100644 --- a/packages/bucket/src/Bucket.js +++ b/packages/bucket/src/Bucket.js @@ -58,14 +58,14 @@ export const Bucket = () => { const fetch = async (params) => { _cache.setManifest(params.manifest); if(_collection !== undefined) return _fetchCollection({ cache: _cache, source: _source, collection: _collection, order: _order, locale: _locale, filters: _filters, expansions: _expansions, manifest: params.manifest, ...params.limit }); - if(_single !== undefined) return _fetchSingle({ cache: _cache, source: _source, single: _single, expansions: _expansions, ...params }); + if(_single !== undefined) return _fetchSingle({ cache: _cache, source: _source, single: _single, expansions: _expansions, locale: _locale, ...params }); throw new Error('Select failed.'); } const manifest = async() => { // TODO: handle parse errors - if(_cache === undefined) return YAML.parse(await _source.open({ filename: 'manifest.yml' })); + if(_cache === undefined) return YAML.parse(await _source.open('manifest.yml')); if(!_cache.isCached({ isManifest: true })) { - return _cache.populate({ isManifest: true, data: YAML.parse(await _source.open({ filename: 'manifest.yml' }))}); + return _cache.populate({ isManifest: true, data: YAML.parse(await _source.open('manifest.yml'))}); } return _cache.get({ isManifest: true }); } @@ -115,7 +115,7 @@ export const Bucket = () => { const _fetchSingle = async (params) => { const { manifest, cache, source, single, locale, expansions } = params; if (!cache.isCached({ single, locale })) { - let sourceData = await source.get({ locale, filename: single }); + let sourceData = await source.get({ locale, single }); const [ data ] = await Promise.all(expansions.map(async (expansion) => { // FIXME: What if more than one expansion?? if(typeof Object.values(expansion)[0] === 'string') { return await _handleStringExpansion(expansion, sourceData, manifest, cache);