@nxextensions/firebase-cypress
Version:
An NX Plugin for Firebase Applications that would like to use emulators for E2E testing with Cypress
165 lines • 8.17 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.configGenerator = configGenerator;
const devkit_1 = require("@nx/devkit");
const js_1 = require("@nx/js");
const path_1 = require("path");
const cypress_version_1 = require("../../utils/cypress-version");
const config_1 = require("../../utils/config");
async function configGenerator(tree, options) {
if (!(options === null || options === void 0 ? void 0 : options.projects)) {
throw new Error(`Projects must be provided`);
}
const targetProjects = Array.isArray(options.projects)
? options.projects
: options.projects.split(/[ ,]/);
const projects = (0, devkit_1.readProjectsConfigurationFromProjectGraph)(await (0, devkit_1.createProjectGraphAsync)()).projects;
const filteredConfigs = targetProjects.map((proj) => {
const projectConfig = projects[proj];
if (!projectConfig) {
throw new Error(`Unable to find project configuration for project: ${proj}`);
}
return projectConfig;
});
await Promise.all(filteredConfigs.map((config) => generateFilesForSelectedProjects(config, tree, options)));
await (0, devkit_1.formatFiles)(tree);
return () => {
(0, devkit_1.installPackagesTask)(tree);
};
}
function normalizeOptions(options, tree, project) {
var _a, _b, _c, _d, _e;
const opts = {};
opts.directory = (_a = options.directory) !== null && _a !== void 0 ? _a : 'src';
opts.js = (_b = options.useJavascript) !== null && _b !== void 0 ? _b : false;
opts.jsx = (_c = opts.js) !== null && _c !== void 0 ? _c : false;
const segmentCount = (opts.directory.match(/[\\/]/g) || []).length + 1;
const offsetFromProjectRoot = Array.from({ length: segmentCount }, () => '..').join('/');
opts.hasTsConfig = tree.exists((0, devkit_1.joinPathFragments)(project.root, 'tsconfig.json'));
opts.bundler = (_d = options.bundler) !== null && _d !== void 0 ? _d : 'webpack';
opts.baseUrl = (_e = options.baseUrl) !== null && _e !== void 0 ? _e : 'http://localhost:4200';
opts.offsetFromProjectRoot = `${offsetFromProjectRoot}/`;
return opts;
}
// to refactor
async function generateFilesForSelectedProjects(project, tree, options) {
var _a;
if (!hasFirebaseJson(project.root, tree)) {
process.stdout.write(`No firebase configuration was found for project: ${(_a = project.name) !== null && _a !== void 0 ? _a : project.root}. Skipping the project.\n`);
return;
}
const appsDir = (0, devkit_1.getWorkspaceLayout)(tree).appsDir;
const newProjectName = `${project.name ? project.name : ''}-e2e`;
if (newProjectName === '-e2e') {
const message = `Warning! The project located at: ${project.root} has no defined name. Aborting generation for this project`;
process.stdout.write(message);
return;
}
const newProjectDir = (0, devkit_1.joinPathFragments)(appsDir, newProjectName);
if (tree.exists(newProjectDir)) {
throw new Error(`An error occurred while creating the project: ${newProjectDir} already exists.`);
}
const newProject = {
root: newProjectDir,
name: newProjectName,
projectType: 'application',
sourceRoot: (0, devkit_1.joinPathFragments)(newProjectDir, 'src'),
implicitDependencies: [project.name],
};
(0, devkit_1.addProjectConfiguration)(tree, newProjectName, newProject);
const opts = normalizeOptions(options, tree, newProject);
createInitialCypressConfig(tree, newProject, opts);
await injectConfiguration(tree, project, newProject, opts);
}
function hasFirebaseJson(projectRoot, tree) {
return tree.exists((0, devkit_1.joinPathFragments)(projectRoot, 'firebase.json'));
}
function createInitialCypressConfig(tree, project, options) {
const templateVars = {
...options,
offsetFromRoot: (0, devkit_1.offsetFromRoot)(project.root),
offsetFromProjectRoot: options.hasTsConfig
? options.offsetFromProjectRoot
: '',
tsConfigPath: options.hasTsConfig
? `${options.offsetFromProjectRoot}tsconfig.json`
: (0, js_1.getRelativePathToRootTsConfig)(tree, project.root),
ext: '',
};
(0, devkit_1.generateFiles)(tree, (0, path_1.join)(__dirname, 'files/common'), project.root, templateVars);
if (options.js) {
if (isEsmProject(tree, project.root)) {
(0, devkit_1.generateFiles)(tree, (0, path_1.join)(__dirname, 'files/config-js-esm'), project.root, templateVars);
}
else {
(0, devkit_1.generateFiles)(tree, (0, path_1.join)(__dirname, 'files/config-js-cjs'), project.root, templateVars);
}
}
else {
(0, devkit_1.generateFiles)(tree, (0, path_1.join)(__dirname, 'files/config-ts'), project.root, templateVars);
}
}
function isEsmProject(tree, projectRoot) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let packageJson;
if (tree.exists((0, devkit_1.joinPathFragments)(projectRoot, 'package.json'))) {
packageJson = (0, devkit_1.readJson)(tree, (0, devkit_1.joinPathFragments)(projectRoot, 'package.json'));
}
else {
packageJson = (0, devkit_1.readJson)(tree, 'package.json');
}
return packageJson.type === 'module';
}
async function injectConfiguration(tree, projectConfig, e2eProjectConfig, options) {
var _a, _b, _c, _d;
const serveTarget = (_a = projectConfig.targets) === null || _a === void 0 ? void 0 : _a['serve'];
if (!serveTarget) {
process.stdout.write(`The current project: ${projectConfig.name} does not have a serve target. Skipping configuration for this project.`);
return;
}
const cypressVersion = (0, cypress_version_1.installedCypressVersion)();
const filesToUse = cypressVersion && cypressVersion < 10 ? 'v9' : 'v10';
const hasTsConfig = tree.exists((0, devkit_1.joinPathFragments)(e2eProjectConfig.root, 'tsconfig.json'));
const segmentCount = (options.directory.match(/[\\/]/g) || []).length + 1;
const offsetFromProjectRoot = Array.from({ length: segmentCount }, () => '..').join('/');
const fileOpts = {
...options,
project: projectConfig.name,
dir: (_b = options.directory) !== null && _b !== void 0 ? _b : 'src',
ext: options.js ? 'js' : 'ts',
offsetFromRoot: (0, devkit_1.offsetFromRoot)(e2eProjectConfig.root),
offsetFromProjectRoot,
projectRoot: projectConfig.root,
tsConfigPath: hasTsConfig
? `${offsetFromProjectRoot}/tsconfig.json`
: (0, js_1.getRelativePathToRootTsConfig)(tree, e2eProjectConfig.root),
tmpl: '',
};
(0, devkit_1.generateFiles)(tree, (0, path_1.join)(__dirname, 'files', filesToUse), e2eProjectConfig.root, fileOpts);
if (filesToUse === 'v10') {
const cyFile = (0, devkit_1.joinPathFragments)(e2eProjectConfig.root, options.js ? 'cypress.config.js' : 'cypress.config.ts');
const webServerCommands = {};
let ciWebServerCommand;
const targetString = (0, devkit_1.targetToTargetString)({
project: projectConfig.name,
target: 'serve',
});
webServerCommands.default = `nx run ${targetString}`;
if ((_c = serveTarget.configurations) === null || _c === void 0 ? void 0 : _c['production']) {
webServerCommands.production = `nx run ${targetString}:production`;
}
if ((_d = projectConfig.targets) === null || _d === void 0 ? void 0 : _d['serve-static']) {
ciWebServerCommand = `nx run ${projectConfig.name}:serve-static`;
}
const updatedCyConfig = await (0, config_1.addDefaultE2eConfig)(tree.read(cyFile, 'utf-8'), {
cypressDir: options.directory,
bundler: options.bundler === 'vite' ? 'vite' : undefined,
webServerCommands,
ciWebServerCommand: ciWebServerCommand,
}, options.baseUrl);
tree.write(cyFile, updatedCyConfig);
}
}
// noinspection JSUnusedGlobalSymbols
exports.default = configGenerator;
//# sourceMappingURL=generator.js.map