mirror of https://github.com/ghostfolio/ghostfolio
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
267 lines
11 KiB
267 lines
11 KiB
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.createNodesV2 = exports.createNodes = exports.createDependencies = void 0;
|
|
const devkit_1 = require("@nx/devkit");
|
|
const path_1 = require("path");
|
|
const get_named_inputs_1 = require("@nx/devkit/src/utils/get-named-inputs");
|
|
const fs_1 = require("fs");
|
|
const calculate_hash_for_create_nodes_1 = require("@nx/devkit/src/utils/calculate-hash-for-create-nodes");
|
|
const cache_directory_1 = require("nx/src/utils/cache-directory");
|
|
const js_1 = require("@nx/js");
|
|
const config_utils_1 = require("@nx/devkit/src/utils/config-utils");
|
|
const file_hasher_1 = require("nx/src/hasher/file-hasher");
|
|
const tsquery_1 = require("@phenomnomnominal/tsquery");
|
|
const util_1 = require("@nx/js/src/plugins/typescript/util");
|
|
const pmc = (0, devkit_1.getPackageManagerCommand)();
|
|
function readTargetsCache(cachePath) {
|
|
return (0, fs_1.existsSync)(cachePath) ? (0, devkit_1.readJsonFile)(cachePath) : {};
|
|
}
|
|
function writeTargetsToCache(cachePath, results) {
|
|
(0, devkit_1.writeJsonFile)(cachePath, results);
|
|
}
|
|
/**
|
|
* @deprecated The 'createDependencies' function is now a no-op. This functionality is included in 'createNodesV2'.
|
|
*/
|
|
const createDependencies = () => {
|
|
return [];
|
|
};
|
|
exports.createDependencies = createDependencies;
|
|
const storybookConfigGlob = '**/.storybook/main.{js,ts,mjs,mts,cjs,cts}';
|
|
exports.createNodes = [
|
|
storybookConfigGlob,
|
|
async (configFilePaths, options, context) => {
|
|
const normalizedOptions = normalizeOptions(options);
|
|
const optionsHash = (0, file_hasher_1.hashObject)(normalizedOptions);
|
|
const cachePath = (0, path_1.join)(cache_directory_1.workspaceDataDirectory, `storybook-${optionsHash}.hash`);
|
|
const targetsCache = readTargetsCache(cachePath);
|
|
try {
|
|
return await (0, devkit_1.createNodesFromFiles)((configFile, _, context) => createNodesInternal(configFile, normalizedOptions, context, targetsCache), configFilePaths, normalizedOptions, context);
|
|
}
|
|
finally {
|
|
writeTargetsToCache(cachePath, targetsCache);
|
|
}
|
|
},
|
|
];
|
|
exports.createNodesV2 = exports.createNodes;
|
|
async function createNodesInternal(configFilePath, options, context, targetsCache) {
|
|
let projectRoot = '';
|
|
if (configFilePath.includes('/.storybook')) {
|
|
projectRoot = (0, path_1.dirname)(configFilePath).replace('/.storybook', '');
|
|
}
|
|
else {
|
|
projectRoot = (0, path_1.dirname)(configFilePath).replace('.storybook', '');
|
|
}
|
|
if (projectRoot === '') {
|
|
projectRoot = '.';
|
|
}
|
|
// Do not create a project if package.json and project.json isn't there.
|
|
const siblingFiles = (0, fs_1.readdirSync)((0, path_1.join)(context.workspaceRoot, projectRoot));
|
|
if (!siblingFiles.includes('package.json') &&
|
|
!siblingFiles.includes('project.json')) {
|
|
return {};
|
|
}
|
|
const hash = await (0, calculate_hash_for_create_nodes_1.calculateHashForCreateNodes)(projectRoot, options, context, [(0, js_1.getLockFileName)((0, devkit_1.detectPackageManager)(context.workspaceRoot))]);
|
|
const projectName = buildProjectName(projectRoot, context.workspaceRoot);
|
|
targetsCache[hash] ??= await buildStorybookTargets(configFilePath, projectRoot, options, context, projectName);
|
|
const result = {
|
|
projects: {
|
|
[projectRoot]: {
|
|
root: projectRoot,
|
|
targets: targetsCache[hash],
|
|
},
|
|
},
|
|
};
|
|
return result;
|
|
}
|
|
async function buildStorybookTargets(configFilePath, projectRoot, options, context, projectName) {
|
|
const buildOutputs = getOutputs();
|
|
const namedInputs = (0, get_named_inputs_1.getNamedInputs)(projectRoot, context);
|
|
// First attempt to do a very fast lookup for the framework
|
|
// If that fails, the framework might be inherited, so do a very heavyweight lookup
|
|
const storybookFramework = (await getStorybookFramework(configFilePath, context)) ||
|
|
(await getStorybookFullyResolvedFramework(configFilePath, context));
|
|
const frameworkIsAngular = storybookFramework === '@storybook/angular';
|
|
if (frameworkIsAngular && !projectName) {
|
|
throw new Error(`Could not find a name for the project at '${projectRoot}'. Please make sure that the project has a package.json or project.json file with name specified.`);
|
|
}
|
|
const targets = {};
|
|
targets[options.buildStorybookTargetName] = buildTarget(namedInputs, buildOutputs, projectRoot, frameworkIsAngular, projectName, configFilePath);
|
|
targets[options.serveStorybookTargetName] = serveTarget(projectRoot, frameworkIsAngular, projectName, configFilePath);
|
|
if (isStorybookTestRunnerInstalled()) {
|
|
targets[options.testStorybookTargetName] = testTarget(projectRoot);
|
|
}
|
|
targets[options.staticStorybookTargetName] = serveStaticTarget(options, projectRoot);
|
|
(0, util_1.addBuildAndWatchDepsTargets)(context.workspaceRoot, projectRoot, targets, options, pmc);
|
|
return targets;
|
|
}
|
|
function buildTarget(namedInputs, outputs, projectRoot, frameworkIsAngular, projectName, configFilePath) {
|
|
let targetConfig;
|
|
if (frameworkIsAngular) {
|
|
targetConfig = {
|
|
executor: '@storybook/angular:build-storybook',
|
|
options: {
|
|
configDir: `${(0, path_1.dirname)(configFilePath)}`,
|
|
browserTarget: `${projectName}:build-storybook`,
|
|
compodoc: false,
|
|
outputDir: (0, devkit_1.joinPathFragments)(projectRoot, 'storybook-static'),
|
|
},
|
|
cache: true,
|
|
outputs,
|
|
inputs: [
|
|
...('production' in namedInputs
|
|
? ['production', '^production']
|
|
: ['default', '^default']),
|
|
{
|
|
externalDependencies: [
|
|
'storybook',
|
|
'@storybook/angular',
|
|
isStorybookTestRunnerInstalled()
|
|
? '@storybook/test-runner'
|
|
: undefined,
|
|
].filter(Boolean),
|
|
},
|
|
],
|
|
};
|
|
}
|
|
else {
|
|
targetConfig = {
|
|
command: `storybook build`,
|
|
options: { cwd: projectRoot },
|
|
cache: true,
|
|
outputs,
|
|
inputs: [
|
|
...('production' in namedInputs
|
|
? ['production', '^production']
|
|
: ['default', '^default']),
|
|
{
|
|
externalDependencies: [
|
|
'storybook',
|
|
isStorybookTestRunnerInstalled()
|
|
? '@storybook/test-runner'
|
|
: undefined,
|
|
].filter(Boolean),
|
|
},
|
|
],
|
|
};
|
|
}
|
|
return targetConfig;
|
|
}
|
|
function serveTarget(projectRoot, frameworkIsAngular, projectName, configFilePath) {
|
|
if (frameworkIsAngular) {
|
|
return {
|
|
continuous: true,
|
|
executor: '@storybook/angular:start-storybook',
|
|
options: {
|
|
configDir: `${(0, path_1.dirname)(configFilePath)}`,
|
|
browserTarget: `${projectName}:build-storybook`,
|
|
compodoc: false,
|
|
},
|
|
};
|
|
}
|
|
else {
|
|
return {
|
|
continuous: true,
|
|
command: `storybook dev`,
|
|
options: { cwd: projectRoot },
|
|
};
|
|
}
|
|
}
|
|
function testTarget(projectRoot) {
|
|
const targetConfig = {
|
|
command: `test-storybook`,
|
|
options: { cwd: projectRoot },
|
|
inputs: [
|
|
{
|
|
externalDependencies: ['storybook', '@storybook/test-runner'],
|
|
},
|
|
],
|
|
};
|
|
return targetConfig;
|
|
}
|
|
function serveStaticTarget(options, projectRoot) {
|
|
const targetConfig = {
|
|
dependsOn: [`${options.buildStorybookTargetName}`],
|
|
continuous: true,
|
|
executor: '@nx/web:file-server',
|
|
options: {
|
|
buildTarget: `${options.buildStorybookTargetName}`,
|
|
staticFilePath: (0, devkit_1.joinPathFragments)(projectRoot, 'storybook-static'),
|
|
},
|
|
};
|
|
return targetConfig;
|
|
}
|
|
async function getStorybookFramework(configFilePath, context) {
|
|
const resolvedPath = (0, path_1.join)(context.workspaceRoot, configFilePath);
|
|
const mainTsJs = (0, fs_1.readFileSync)(resolvedPath, 'utf-8');
|
|
const importDeclarations = (0, tsquery_1.query)(mainTsJs, 'ImportDeclaration:has(ImportSpecifier:has([text="StorybookConfig"]))')?.[0];
|
|
if (!importDeclarations) {
|
|
return parseFrameworkName(mainTsJs);
|
|
}
|
|
const storybookConfigImportPackage = (0, tsquery_1.query)(importDeclarations, 'StringLiteral')?.[0];
|
|
if (storybookConfigImportPackage?.getText() === `'@storybook/core-common'`) {
|
|
return parseFrameworkName(mainTsJs);
|
|
}
|
|
return storybookConfigImportPackage?.getText();
|
|
}
|
|
function parseFrameworkName(mainTsJs) {
|
|
const frameworkPropertyAssignment = (0, tsquery_1.query)(mainTsJs, `PropertyAssignment:has(Identifier:has([text="framework"]))`)?.[0];
|
|
if (!frameworkPropertyAssignment) {
|
|
return undefined;
|
|
}
|
|
const propertyAssignments = (0, tsquery_1.query)(frameworkPropertyAssignment, `PropertyAssignment:has(Identifier:has([text="name"]))`);
|
|
const namePropertyAssignment = propertyAssignments?.find((expression) => {
|
|
return expression.getText().startsWith('name');
|
|
});
|
|
if (!namePropertyAssignment) {
|
|
const storybookConfigImportPackage = (0, tsquery_1.query)(frameworkPropertyAssignment, 'StringLiteral')?.[0];
|
|
return storybookConfigImportPackage?.getText();
|
|
}
|
|
return (0, tsquery_1.query)(namePropertyAssignment, `StringLiteral`)?.[0]?.getText();
|
|
}
|
|
async function getStorybookFullyResolvedFramework(configFilePath, context) {
|
|
const resolvedPath = (0, path_1.join)(context.workspaceRoot, configFilePath);
|
|
const { framework } = await (0, config_utils_1.loadConfigFile)(resolvedPath);
|
|
return typeof framework === 'string' ? framework : framework.name;
|
|
}
|
|
function getOutputs() {
|
|
const outputs = [
|
|
`{projectRoot}/storybook-static`,
|
|
`{options.output-dir}`,
|
|
`{options.outputDir}`,
|
|
`{options.o}`,
|
|
];
|
|
return outputs;
|
|
}
|
|
function normalizeOptions(options) {
|
|
return {
|
|
buildStorybookTargetName: options.buildStorybookTargetName ?? 'build-storybook',
|
|
serveStorybookTargetName: options.serveStorybookTargetName ?? 'storybook',
|
|
testStorybookTargetName: options.testStorybookTargetName ?? 'test-storybook',
|
|
staticStorybookTargetName: options.staticStorybookTargetName ?? 'static-storybook',
|
|
buildDepsTargetName: options.buildDepsTargetName ?? 'build-deps',
|
|
watchDepsTargetName: options.watchDepsTargetName ?? 'watch-deps',
|
|
};
|
|
}
|
|
function buildProjectName(projectRoot, workspaceRoot) {
|
|
const packageJsonPath = (0, path_1.join)(workspaceRoot, projectRoot, 'package.json');
|
|
const projectJsonPath = (0, path_1.join)(workspaceRoot, projectRoot, 'project.json');
|
|
let name;
|
|
if ((0, fs_1.existsSync)(projectJsonPath)) {
|
|
const projectJson = (0, devkit_1.parseJson)((0, fs_1.readFileSync)(projectJsonPath, 'utf-8'));
|
|
name = projectJson.name;
|
|
}
|
|
else if ((0, fs_1.existsSync)(packageJsonPath)) {
|
|
const packageJson = (0, devkit_1.parseJson)((0, fs_1.readFileSync)(packageJsonPath, 'utf-8'));
|
|
name = packageJson.name;
|
|
}
|
|
return name;
|
|
}
|
|
function isStorybookTestRunnerInstalled() {
|
|
try {
|
|
require.resolve('@storybook/test-runner');
|
|
return true;
|
|
}
|
|
catch (e) {
|
|
return false;
|
|
}
|
|
}
|
|
|