Skip to content

Commit

Permalink
Split SSGs into separate files for overrides
Browse files Browse the repository at this point in the history
  • Loading branch information
rphillips-cc committed Jun 11, 2024
1 parent 3a802d5 commit fb77135
Show file tree
Hide file tree
Showing 17 changed files with 552 additions and 310 deletions.
4 changes: 2 additions & 2 deletions src/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import meow from 'meow';
import { exit } from 'process';
import { readFile } from 'fs/promises';
import { fdir } from 'fdir';
import { generate } from './index.js';

Expand Down Expand Up @@ -61,8 +62,7 @@ if (!folderPath) {
} else {
const crawler = new fdir().withRelativePaths().filter((filePath) => !isIgnoredPath(filePath));
const filePaths = await crawler.crawl(folderPath).withPromise();
const config = await generate(filePaths);
const config = await generate(filePaths, { readFile });

console.debug(filePaths);
console.log(JSON.stringify(config, undefined, 2));
}
36 changes: 21 additions & 15 deletions src/collections.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { basename, join, sep } from 'path';
import { findIcon } from './icons.js';
import { basename, join } from 'path';
import slugify from '@sindresorhus/slugify';
import titleize from 'titleize';
import { findIcon } from './icons.js';
import { stripTopPath } from './utility.js';

/**
* Produces an ordered set of paths that a file at this path could belong to.
Expand All @@ -12,7 +13,7 @@ import titleize from 'titleize';
export function getCollectionPaths(filePath) {
let builder = '';
const paths = [''];
const parts = filePath.split(sep);
const parts = filePath.split('/');

for (var i = 0; i < parts.length - 1; i++) {
builder = join(builder, parts[i]);
Expand All @@ -26,28 +27,30 @@ export function getCollectionPaths(filePath) {
* Generates collections config from a set of paths.
*
* @param collectionPaths {{ basePath: string, paths: string[] }}
* @returns {Record.<string, import('@cloudcannon/configuration-types').CollectionConfig>}
* @param source {string}
* @returns {import('./types').CollectionsConfig}
*/
export function generateCollectionsConfig(collectionPaths) {
/** @type Record<string, import('@cloudcannon/configuration-types').CollectionConfig> */
export function generateCollectionsConfig(collectionPaths, source) {
/** @type import('./types').CollectionsConfig */
const collectionsConfig = {};
const collectionPath = stripTopPath(collectionPaths.basePath, source);

for (let path of collectionPaths.paths) {
const key = slugify(path) || 'pages';
const sourcePath = stripTopPath(path, source);
const key = slugify(sourcePath) || 'pages';
const name = titleize(
basename(path || key)
basename(sourcePath || key)
.replace(/[_-]/g, ' ')
.trim(),
);

collectionsConfig[key] = {
path,
path: sourcePath,
name,
icon: findIcon(name.toLowerCase()),
};

console.log(path, collectionPaths.basePath);
if (path === collectionPaths.basePath) {
if (sourcePath === collectionPath) {
collectionsConfig[key].filter = {
base: 'strict',
};
Expand All @@ -68,11 +71,14 @@ export function processCollectionPaths(collectionPathCounts) {
let basePath = '';

if (paths.length) {
const checkParts = paths[0].split(sep);
const checkParts = paths[0].split('/');

for (var i = 0; i < checkParts.length; i++) {
const checkPath = join(...checkParts.slice(0, i));
const isSharedPath = paths.every((pathKey) => pathKey.startsWith(checkPath + sep));
const checkPath = join(...checkParts.slice(0, i + 1));

const isSharedPath =
checkPath &&
paths.every((pathKey) => pathKey === checkPath || pathKey.startsWith(checkPath + '/'));

if (isSharedPath) {
basePath = checkPath;
Expand All @@ -81,7 +87,7 @@ export function processCollectionPaths(collectionPathCounts) {
}

if (basePath) {
paths = paths.map((pathKey) => pathKey.substring(basePath.length + 1));
paths = paths.map((pathKey) => stripTopPath(pathKey, basePath));
}

return {
Expand Down
60 changes: 38 additions & 22 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { guessSsg } from './ssg.js';
import { last } from './utility.js';
import { guessSsg } from './ssgs/ssgs.js';
import { last, stripTopPath } from './utility.js';
import {
getCollectionPaths,
generateCollectionsConfig,
Expand All @@ -9,11 +9,11 @@ import {
/**
* Provides a summary of a file at this path.
*
* @param filePath {string}
* @param ssg {import('./ssg.js').Ssg}
* @returns {import('./types.d.ts').FileSummary}
* @param filePath {string} The input file path.
* @param ssg {import('./ssgs/ssg').default} The associated SSG.
* @returns {import('./types').ParsedFile} Summary of the file.
*/
function generateFile(filePath, ssg) {
function parseFile(filePath, ssg) {
const type = ssg.getFileType(filePath);

return {
Expand All @@ -23,20 +23,19 @@ function generateFile(filePath, ssg) {
}

/**
* Generates a baseline CLoudCannon configuration based on the file path provided.
* Provides a summary of files.
*
* @param filePaths {string[]} List of input file paths.
* @param _options {import('./types.d.ts').GenerateOptions=} Options to aid generation.
* @returns {Promise<import('@cloudcannon/configuration-types').Configuration>}
* @param filePaths {string[]} The input file path.
* @param ssg {import('./ssgs/ssg').default} The associated SSG.
* @param source {string} The site's source path.
* @returns {import('./types').ParsedFiles} The file summaries grouped by type.
*/
export async function generate(filePaths, _options) {
const ssg = guessSsg(filePaths);

function parseFiles(filePaths, ssg) {
/** @type {Record<string, number>} */
const collectionPathCounts = {};

/** @type {Record<import('./types.d.ts').FileType, import('./types.d.ts').FileSummary[]>} */
const files = {
/** @type {Record<import('./types').FileType, import('./types').ParsedFile[]>} */
const groups = {
config: [],
content: [],
partial: [],
Expand All @@ -46,7 +45,7 @@ export async function generate(filePaths, _options) {
};

for (let i = 0; i < filePaths.length; i++) {
const file = generateFile(filePaths[i], ssg);
const file = parseFile(filePaths[i], ssg);

if (file.type === 'content') {
const lastPath = last(getCollectionPaths(filePaths[i]));
Expand All @@ -57,18 +56,35 @@ export async function generate(filePaths, _options) {
}

if (file.type !== 'ignored') {
files[file.type].push(file);
groups[file.type].push(file);
}
}

const collectionPaths = processCollectionPaths(collectionPathCounts);
console.log('collectionPaths', collectionPaths);
return { collectionPathCounts, groups };
}

/**
* Generates a baseline CLoudCannon configuration based on the file path provided.
*
* @param filePaths {string[]} List of input file paths.
* @param options {import('./types').GenerateOptions=} Options to aid generation.
* @returns {Promise<import('@cloudcannon/configuration-types').Configuration & { ssg?: string; }>}
*/
export async function generate(filePaths, options) {
const ssg = guessSsg(filePaths);
const files = parseFiles(filePaths, ssg);
const collectionPaths = processCollectionPaths(files.collectionPathCounts);
const source =
options?.userConfig?.source ??
options?.buildConfig?.source ??
ssg.getSource(files, filePaths, collectionPaths);

return {
source: '',
collections_config: generateCollectionsConfig(collectionPaths),
ssg: ssg?.key,
source,
collections_config: generateCollectionsConfig(collectionPaths, source),
paths: {
collections: collectionPaths.basePath,
collections: stripTopPath(collectionPaths.basePath, source),
},
};
}
Loading

0 comments on commit fb77135

Please sign in to comment.