@knapsack/app
Version:
Build Design Systems on top of knapsack, by Basalt
135 lines (118 loc) • 3.98 kB
text/typescript
/**
* Copyright (C) 2018 Basalt
This file is part of Knapsack.
Knapsack is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your option)
any later version.
Knapsack is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
You should have received a copy of the GNU General Public License along
with Knapsack; if not, see <https://www.gnu.org/licenses>.
*/
import { resolve } from 'path';
import {
validateUniqueIdsInArray,
validateDataAgainstSchema,
} from '@knapsack/schema-utils';
import { knapsackDesignTokensSchema } from '@knapsack/core/types';
import { KnapsackRendererBase } from '../server/renderer-base';
import * as log from '../cli/log';
import { knapsackEvents, EVENTS } from '../server/events';
import { dirExistsOrExit } from '../server/server-utils';
import { KnapsackConfig } from '../schemas/knapsack-config';
/**
* Handle backwards compatibility of config
*/
function convertOldConfig(config: KnapsackConfig): KnapsackConfig {
// handle backward compatibility here, may need to make new Interface
return config;
}
/**
* @todo validate with schema and assign defaults
*/
function validateConfig(config: KnapsackConfig): boolean {
const templateRendererResults = validateUniqueIdsInArray(
config.templateRenderers,
);
if (!templateRendererResults.ok) {
log.error(
`Each templateRenderer must have a unique id, these do not: ${templateRendererResults.duplicateIdList}`,
);
process.exit(1);
}
config.templateRenderers.forEach((templateRenderer, i) => {
if (templateRenderer instanceof KnapsackRendererBase === false) {
log.error(
`Each templateRenderer must be an instance of "KnapsackRenderer" and ${templateRenderer.id ||
`number ${i + 1}`} is not`,
);
process.exit(1);
}
});
// @todo check if `config.patterns` exists; but can't now as it can contain globs
dirExistsOrExit(config.public);
if (config.designTokens?.data) {
{
const { message, ok } = validateDataAgainstSchema(
knapsackDesignTokensSchema,
config.designTokens.data,
);
if (!ok) {
log.error(message);
process.exit(1);
}
}
{
const { ok, message } = validateUniqueIdsInArray(
config.designTokens.data.tokens,
'name',
);
if (!ok) {
log.error(`Error in Design Tokens. ${message}`);
process.exit(1);
}
}
}
if (config.designTokens?.createCodeSnippet) {
config.designTokens.data.tokens = config.designTokens.data.tokens.map(
token => {
if (token.code) return token;
return {
...token,
code: config.designTokens.createCodeSnippet(token),
};
},
);
}
{
const { ok, message } = validateUniqueIdsInArray(config.plugins);
if (!ok) {
log.error(`Plugins must have a unique "id". ${message}`);
process.exit(1);
}
}
return true;
}
/**
* Prepare user config: validate, convert all paths to absolute, assign defaults
*/
export function processConfig(
userConfig: KnapsackConfig,
from: string,
): KnapsackConfig {
const { public: publicDir, dist, ...rest } = convertOldConfig(userConfig);
const config: KnapsackConfig = {
public: resolve(from, publicDir),
dist: resolve(from, dist),
// data: resolve(from, rest.data), // @todo turn `data` directory from relative to absolute path & then resolve issues elsewhere that arise (i.e. when `join()` is used)
plugins: rest.plugins ?? [],
...rest,
};
const ok = validateConfig(config);
if (!ok) process.exit(1);
knapsackEvents.emit(EVENTS.CONFIG_READY, config);
return config;
}