strapi/packages/utils/pack-up/src/node/createBuildContext.ts

189 lines
4.3 KiB
TypeScript
Raw Normal View History

feat: add pack-up package (#18233) * feat(pack-up): add build command (#18058) * chore: lint order of imports * feat(pack-up): add watch command (#18121) * feat: add watch command feat: add ts watch task * chore: pr amends * fix: promptUser linter * chore: remove \n with os.EOL * feat(pack-up): add init command (#18133) * feat(pack-up): add build command (#18058) * feat(pack-up): add watch command (#18121) * feat: add watch command feat: add ts watch task * chore: pr amends * fix: promptUser linter * chore: remove \n with os.EOL * feat: add init command fix: build feat: add default template and tests * chore: pr amends * Update packages/utils/pack-up/tests/console.ts Co-authored-by: Ben Irvin <ben@innerdvations.com> * chore: re-add mock * chore: fix tsconfig * chore: fix inquirer types due to rxjs inclusion * Update packages/utils/pack-up/src/node/templates/internal/files/typescript.ts * chore: fix inquirer types --------- Co-authored-by: Ben Irvin <ben@innerdvations.com> * feat(pack-up): add check command (#18183) * feat: add check command * chore: reintroduce CLI tests * fix: add build command to `prepublishOnly` * docs(pack-up): add readme and contributor docs (#18237) * chore: update README * docs(pack-up): add contributor documentation * chore: update overview doc to be clearer * fix(pack-up): init command (#18245) * fix: init command bugs * fix: node tests * fix: template exports ordering & file extensions * test(upload): double timeout on UploadAssetDialog test --------- Co-authored-by: Ben Irvin <ben@innerdvations.com>
2023-10-05 09:38:29 +01:00
import browserslistToEsbuild from 'browserslist-to-esbuild';
import path from 'path';
import { resolveConfigProperty } from './core/config';
feat: add pack-up package (#18233) * feat(pack-up): add build command (#18058) * chore: lint order of imports * feat(pack-up): add watch command (#18121) * feat: add watch command feat: add ts watch task * chore: pr amends * fix: promptUser linter * chore: remove \n with os.EOL * feat(pack-up): add init command (#18133) * feat(pack-up): add build command (#18058) * feat(pack-up): add watch command (#18121) * feat: add watch command feat: add ts watch task * chore: pr amends * fix: promptUser linter * chore: remove \n with os.EOL * feat: add init command fix: build feat: add default template and tests * chore: pr amends * Update packages/utils/pack-up/tests/console.ts Co-authored-by: Ben Irvin <ben@innerdvations.com> * chore: re-add mock * chore: fix tsconfig * chore: fix inquirer types due to rxjs inclusion * Update packages/utils/pack-up/src/node/templates/internal/files/typescript.ts * chore: fix inquirer types --------- Co-authored-by: Ben Irvin <ben@innerdvations.com> * feat(pack-up): add check command (#18183) * feat: add check command * chore: reintroduce CLI tests * fix: add build command to `prepublishOnly` * docs(pack-up): add readme and contributor docs (#18237) * chore: update README * docs(pack-up): add contributor documentation * chore: update overview doc to be clearer * fix(pack-up): init command (#18245) * fix: init command bugs * fix: node tests * fix: template exports ordering & file extensions * test(upload): double timeout on UploadAssetDialog test --------- Co-authored-by: Ben Irvin <ben@innerdvations.com>
2023-10-05 09:38:29 +01:00
import { parseExports, ExtMap, Export } from './core/exports';
import { loadTsConfig } from './core/tsconfig';
import type { Config } from './core/config';
import type { Logger } from './core/logger';
import type { PackageJson } from './core/pkg';
import type { ParsedCommandLine } from 'typescript';
interface BuildContextArgs {
config: Config;
cwd: string;
extMap: ExtMap;
logger: Logger;
pkg: PackageJson;
}
interface Targets {
node: string[];
web: string[];
'*': string[];
}
type Runtime = '*' | 'node' | 'web';
interface BuildContext {
config: Config;
cwd: string;
distPath: string;
exports: Record<string, Export>;
external: string[];
extMap: ExtMap;
logger: Logger;
pkg: PackageJson;
runtime?: Runtime;
targets: Targets;
ts?: {
config: ParsedCommandLine;
path: string;
};
}
const DEFAULT_BROWSERS_LIST_CONFIG = [
'last 3 major versions',
'Firefox ESR',
'last 2 Opera versions',
'not dead',
'node 16.0.0',
];
/**
* @description Create a build context for the pipeline we're creating,
* this is shared among tasks so they all use the same settings for core pieces
* such as a target, distPath, externals etc.
*/
const createBuildContext = async ({
config,
cwd,
extMap,
logger,
pkg,
}: BuildContextArgs): Promise<BuildContext> => {
const tsConfig = loadTsConfig({
cwd,
path: 'tsconfig.build.json',
logger,
});
const targets = {
'*': browserslistToEsbuild(pkg.browserslist ?? DEFAULT_BROWSERS_LIST_CONFIG),
node: browserslistToEsbuild(['node 16.0.0']),
web: ['esnext'],
};
const parsedExports = parseExports({ extMap, pkg }).reduce((acc, x) => {
feat: add pack-up package (#18233) * feat(pack-up): add build command (#18058) * chore: lint order of imports * feat(pack-up): add watch command (#18121) * feat: add watch command feat: add ts watch task * chore: pr amends * fix: promptUser linter * chore: remove \n with os.EOL * feat(pack-up): add init command (#18133) * feat(pack-up): add build command (#18058) * feat(pack-up): add watch command (#18121) * feat: add watch command feat: add ts watch task * chore: pr amends * fix: promptUser linter * chore: remove \n with os.EOL * feat: add init command fix: build feat: add default template and tests * chore: pr amends * Update packages/utils/pack-up/tests/console.ts Co-authored-by: Ben Irvin <ben@innerdvations.com> * chore: re-add mock * chore: fix tsconfig * chore: fix inquirer types due to rxjs inclusion * Update packages/utils/pack-up/src/node/templates/internal/files/typescript.ts * chore: fix inquirer types --------- Co-authored-by: Ben Irvin <ben@innerdvations.com> * feat(pack-up): add check command (#18183) * feat: add check command * chore: reintroduce CLI tests * fix: add build command to `prepublishOnly` * docs(pack-up): add readme and contributor docs (#18237) * chore: update README * docs(pack-up): add contributor documentation * chore: update overview doc to be clearer * fix(pack-up): init command (#18245) * fix: init command bugs * fix: node tests * fix: template exports ordering & file extensions * test(upload): double timeout on UploadAssetDialog test --------- Co-authored-by: Ben Irvin <ben@innerdvations.com>
2023-10-05 09:38:29 +01:00
const { _path: exportPath, ...exportEntry } = x;
return { ...acc, [exportPath]: exportEntry };
}, {} as Record<string, Export>);
const exports = resolveConfigProperty(config.exports, parsedExports);
feat: add pack-up package (#18233) * feat(pack-up): add build command (#18058) * chore: lint order of imports * feat(pack-up): add watch command (#18121) * feat: add watch command feat: add ts watch task * chore: pr amends * fix: promptUser linter * chore: remove \n with os.EOL * feat(pack-up): add init command (#18133) * feat(pack-up): add build command (#18058) * feat(pack-up): add watch command (#18121) * feat: add watch command feat: add ts watch task * chore: pr amends * fix: promptUser linter * chore: remove \n with os.EOL * feat: add init command fix: build feat: add default template and tests * chore: pr amends * Update packages/utils/pack-up/tests/console.ts Co-authored-by: Ben Irvin <ben@innerdvations.com> * chore: re-add mock * chore: fix tsconfig * chore: fix inquirer types due to rxjs inclusion * Update packages/utils/pack-up/src/node/templates/internal/files/typescript.ts * chore: fix inquirer types --------- Co-authored-by: Ben Irvin <ben@innerdvations.com> * feat(pack-up): add check command (#18183) * feat: add check command * chore: reintroduce CLI tests * fix: add build command to `prepublishOnly` * docs(pack-up): add readme and contributor docs (#18237) * chore: update README * docs(pack-up): add contributor documentation * chore: update overview doc to be clearer * fix(pack-up): init command (#18245) * fix: init command bugs * fix: node tests * fix: template exports ordering & file extensions * test(upload): double timeout on UploadAssetDialog test --------- Co-authored-by: Ben Irvin <ben@innerdvations.com>
2023-10-05 09:38:29 +01:00
const parsedExternals = [
...(pkg.dependencies ? Object.keys(pkg.dependencies) : []),
...(pkg.peerDependencies ? Object.keys(pkg.peerDependencies) : []),
];
const external =
config && Array.isArray(config.externals)
? [...parsedExternals, ...config.externals]
: parsedExternals;
const outputPaths = Object.values(exports)
.flatMap((exportEntry) => {
return [
exportEntry.import,
exportEntry.require,
exportEntry.browser?.import,
exportEntry.browser?.require,
exportEntry.node?.source && exportEntry.node.import,
exportEntry.node?.source && exportEntry.node.require,
].filter(Boolean) as string[];
})
.map((p) => path.resolve(cwd, p));
const commonDistPath = findCommonDirPath(outputPaths);
if (commonDistPath === cwd) {
throw new Error(
'all output files must share a common parent directory which is not the root package directory'
);
}
if (commonDistPath && !pathContains(cwd, commonDistPath)) {
throw new Error('all output files must be located within the package');
}
const configDistPath = config?.dist ? path.resolve(cwd, config.dist) : undefined;
const distPath = configDistPath || commonDistPath;
if (!distPath) {
throw new Error("could not detect 'dist' path");
}
return {
config,
cwd,
distPath,
exports,
external,
extMap,
logger,
pkg,
runtime: config?.runtime,
targets,
ts: tsConfig,
};
};
/**
* @internal
*/
const pathContains = (containerPath: string, itemPath: string): boolean => {
return !path.relative(containerPath, itemPath).startsWith('..');
};
/**
* @internal
*/
const findCommonDirPath = (filePaths: string[]): string | undefined => {
let commonPath: string | undefined;
for (const filePath of filePaths) {
let dirPath = path.dirname(filePath);
if (!commonPath) {
commonPath = dirPath;
// eslint-disable-next-line no-continue
continue;
}
while (dirPath !== commonPath) {
dirPath = path.dirname(dirPath);
if (dirPath === commonPath) {
break;
}
if (pathContains(dirPath, commonPath)) {
commonPath = dirPath;
break;
}
if (dirPath === '.') {
return undefined;
}
}
}
return commonPath;
};
export { createBuildContext };
export type { BuildContext, Targets, Runtime };