@ts-ioc-container/bundler 1.5.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +47 -31
- package/README.md +157 -280
- package/cjm/app.js +39 -0
- package/cjm/bin.js +2 -2
- package/cjm/cli/Application.js +58 -0
- package/cjm/cli/IErrorHandler.js +5 -0
- package/cjm/cli/decorators.js +9 -0
- package/cjm/cli/index.js +17 -0
- package/cjm/cli/options.js +25 -0
- package/cjm/cli/usage.js +19 -0
- package/cjm/domain/CliIo.js +7 -0
- package/cjm/domain/GlobalConfig.js +7 -0
- package/cjm/exceptions/DomainException.js +54 -0
- package/cjm/exceptions/ExceptionHandler.js +38 -0
- package/cjm/features/build/BuildConfig.js +183 -0
- package/cjm/features/build/BuildController.js +91 -0
- package/cjm/features/build/BuildModule.js +16 -0
- package/cjm/{ImportPaths.js → features/build/domain/ImportPaths.js} +7 -29
- package/cjm/features/build/domain/configFiles.js +35 -0
- package/cjm/{emit.js → features/build/domain/emit.js} +10 -9
- package/cjm/{scan.js → features/build/domain/scan.js} +6 -3
- package/cjm/features/build/domain/tokenCollisions.js +29 -0
- package/cjm/features/build/domain/tsconfig.js +78 -0
- package/cjm/features/build/services/BundleBuilder.js +116 -0
- package/cjm/features/build/services/TicConfigService.js +68 -0
- package/cjm/features/help/HelpController.js +39 -0
- package/cjm/features/help/HelpModule.js +12 -0
- package/cjm/features/help/VersionController.js +45 -0
- package/cjm/index.js +87 -28
- package/cjm/modules/CommonModule.js +28 -0
- package/cjm/schema/ticConfigSchema.js +24 -0
- package/cjm/services/ConsoleLogger.js +36 -0
- package/cjm/services/HandlebarsRenderService.js +33 -0
- package/cjm/services/NodeFileSystemService.js +32 -0
- package/cjm/services/OutputService.js +33 -0
- package/package.json +10 -7
- package/tic.schema.json +118 -147
- package/tpl/index.cjs +36 -16
- package/typings/app.d.ts +24 -0
- package/typings/cli/Application.d.ts +16 -0
- package/typings/cli/Application.d.ts.map +1 -0
- package/typings/cli/IErrorHandler.d.ts +7 -0
- package/typings/cli/IErrorHandler.d.ts.map +1 -0
- package/typings/cli/decorators.d.ts +10 -0
- package/typings/cli/decorators.d.ts.map +1 -0
- package/typings/cli/index.d.ts +6 -0
- package/typings/cli/index.d.ts.map +1 -0
- package/typings/cli/options.d.ts +23 -0
- package/typings/cli/options.d.ts.map +1 -0
- package/typings/cli/usage.d.ts +2 -0
- package/typings/cli/usage.d.ts.map +1 -0
- package/typings/domain/CliIo.d.ts +10 -0
- package/typings/domain/CliIo.d.ts.map +1 -0
- package/typings/domain/GlobalConfig.d.ts +10 -0
- package/typings/domain/GlobalConfig.d.ts.map +1 -0
- package/typings/exceptions/DomainException.d.ts +37 -0
- package/typings/exceptions/DomainException.d.ts.map +1 -0
- package/typings/exceptions/ExceptionHandler.d.ts +12 -0
- package/typings/exceptions/ExceptionHandler.d.ts.map +1 -0
- package/typings/features/build/BuildConfig.d.ts +179 -0
- package/typings/features/build/BuildConfig.d.ts.map +1 -0
- package/typings/features/build/BuildController.d.ts +32 -0
- package/typings/features/build/BuildController.d.ts.map +1 -0
- package/typings/features/build/BuildModule.d.ts +5 -0
- package/typings/features/build/BuildModule.d.ts.map +1 -0
- package/typings/{ImportPaths.d.ts → features/build/domain/ImportPaths.d.ts} +4 -16
- package/typings/features/build/domain/ImportPaths.d.ts.map +1 -0
- package/typings/features/build/domain/configFiles.d.ts +13 -0
- package/typings/features/build/domain/configFiles.d.ts.map +1 -0
- package/typings/features/build/domain/emit.d.ts +42 -0
- package/typings/features/build/domain/emit.d.ts.map +1 -0
- package/typings/features/build/domain/glob.d.ts.map +1 -0
- package/typings/{scan.d.ts → features/build/domain/scan.d.ts} +4 -2
- package/typings/features/build/domain/scan.d.ts.map +1 -0
- package/typings/features/build/domain/tokenCollisions.d.ts +14 -0
- package/typings/features/build/domain/tokenCollisions.d.ts.map +1 -0
- package/typings/features/build/domain/tsconfig.d.ts +25 -0
- package/typings/features/build/domain/tsconfig.d.ts.map +1 -0
- package/typings/features/build/services/BundleBuilder.d.ts +68 -0
- package/typings/features/build/services/BundleBuilder.d.ts.map +1 -0
- package/typings/features/build/services/TicConfigService.d.ts +37 -0
- package/typings/features/build/services/TicConfigService.d.ts.map +1 -0
- package/typings/features/help/HelpController.d.ts +8 -0
- package/typings/features/help/HelpController.d.ts.map +1 -0
- package/typings/features/help/HelpModule.d.ts +5 -0
- package/typings/features/help/HelpModule.d.ts.map +1 -0
- package/typings/features/help/VersionController.d.ts +8 -0
- package/typings/features/help/VersionController.d.ts.map +1 -0
- package/typings/index.d.ts +25 -11
- package/typings/modules/CommonModule.d.ts +9 -0
- package/typings/modules/CommonModule.d.ts.map +1 -0
- package/typings/schema/ticConfigSchema.d.ts +7 -0
- package/typings/schema/ticConfigSchema.d.ts.map +1 -0
- package/typings/services/ConsoleLogger.d.ts +20 -0
- package/typings/services/ConsoleLogger.d.ts.map +1 -0
- package/typings/services/HandlebarsRenderService.d.ts +23 -0
- package/typings/services/HandlebarsRenderService.d.ts.map +1 -0
- package/typings/services/NodeFileSystemService.d.ts +21 -0
- package/typings/services/NodeFileSystemService.d.ts.map +1 -0
- package/typings/services/OutputService.d.ts +13 -0
- package/typings/services/OutputService.d.ts.map +1 -0
- package/cjm/build.js +0 -132
- package/cjm/cli.js +0 -84
- package/cjm/config.js +0 -162
- package/cjm/errors.js +0 -15
- package/cjm/exportPredicate.js +0 -13
- package/cjm/inclusion.js +0 -24
- package/cjm/predicateFile.js +0 -30
- package/cjm/render.js +0 -15
- package/cjm/utils.js +0 -2
- package/typings/build.d.ts +0 -45
- package/typings/cli.d.ts +0 -8
- package/typings/config.d.ts +0 -123
- package/typings/emit.d.ts +0 -18
- package/typings/errors.d.ts +0 -13
- package/typings/exportPredicate.d.ts +0 -36
- package/typings/inclusion.d.ts +0 -42
- package/typings/predicateFile.d.ts +0 -16
- package/typings/render.d.ts +0 -8
- package/typings/utils.d.ts +0 -3
- /package/cjm/{glob.js → features/build/domain/glob.js} +0 -0
- /package/typings/{glob.d.ts → features/build/domain/glob.d.ts} +0 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Application = void 0;
|
|
4
|
+
const ts_ioc_container_1 = require("ts-ioc-container");
|
|
5
|
+
const DomainException_1 = require("../exceptions/DomainException");
|
|
6
|
+
const decorators_1 = require("./decorators");
|
|
7
|
+
const IErrorHandler_1 = require("./IErrorHandler");
|
|
8
|
+
const usage_1 = require("./usage");
|
|
9
|
+
const COMMAND_ALIASES = {
|
|
10
|
+
'--help': 'help',
|
|
11
|
+
'-h': 'help',
|
|
12
|
+
'--version': 'version',
|
|
13
|
+
'-v': 'version',
|
|
14
|
+
};
|
|
15
|
+
function parseCommandAndAction(argv) {
|
|
16
|
+
const [first, maybeAction] = argv;
|
|
17
|
+
if (!first)
|
|
18
|
+
throw new DomainException_1.MissingCommandError(usage_1.USAGE);
|
|
19
|
+
const command = COMMAND_ALIASES[first] ?? first;
|
|
20
|
+
const action = maybeAction && !maybeAction.startsWith('-') ? maybeAction : decorators_1.DEFAULT_ACTION;
|
|
21
|
+
return { command, action };
|
|
22
|
+
}
|
|
23
|
+
class Application {
|
|
24
|
+
scope;
|
|
25
|
+
errorHandler;
|
|
26
|
+
static bootstrap(container) {
|
|
27
|
+
return new Application(container, IErrorHandler_1.IErrorHandlerKey.resolve(container));
|
|
28
|
+
}
|
|
29
|
+
constructor(scope, errorHandler) {
|
|
30
|
+
this.scope = scope;
|
|
31
|
+
this.errorHandler = errorHandler;
|
|
32
|
+
}
|
|
33
|
+
run(...argv) {
|
|
34
|
+
try {
|
|
35
|
+
const { command, action } = parseCommandAndAction(argv);
|
|
36
|
+
if (!this.scope.hasRegistration(command))
|
|
37
|
+
throw new DomainException_1.UnknownCommandError(command);
|
|
38
|
+
const controller = this.scope.resolve(command);
|
|
39
|
+
const collector = new ts_ioc_container_1.HookCollector({
|
|
40
|
+
key: action,
|
|
41
|
+
createExecutionContext: (0, ts_ioc_container_1.createHookContextFactory)({ args: argv }),
|
|
42
|
+
});
|
|
43
|
+
const actions = collector.getActions(controller, { scope: this.scope });
|
|
44
|
+
if (actions.length === 0)
|
|
45
|
+
throw new DomainException_1.UnknownActionError(command, action);
|
|
46
|
+
for (const item of actions)
|
|
47
|
+
(0, ts_ioc_container_1.toTask)(item)();
|
|
48
|
+
return 0;
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
return this.errorHandler.handleError(error);
|
|
52
|
+
}
|
|
53
|
+
finally {
|
|
54
|
+
this.scope.dispose();
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
exports.Application = Application;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.onDefault = exports.action = exports.DEFAULT_ACTION = void 0;
|
|
4
|
+
const ts_ioc_container_1 = require("ts-ioc-container");
|
|
5
|
+
exports.DEFAULT_ACTION = 'default';
|
|
6
|
+
const action = (name, ...hooks) => (0, ts_ioc_container_1.hook)(name, (0, ts_ioc_container_1.sequential)(...hooks));
|
|
7
|
+
exports.action = action;
|
|
8
|
+
const onDefault = (...hooks) => (0, exports.action)(exports.DEFAULT_ACTION, ...hooks);
|
|
9
|
+
exports.onDefault = onDefault;
|
package/cjm/cli/index.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.USAGE = exports.IErrorHandlerKey = exports.Application = exports.validate = exports.parseOptions = exports.commandArgs = exports.onDefault = exports.DEFAULT_ACTION = exports.action = void 0;
|
|
4
|
+
var decorators_1 = require("./decorators");
|
|
5
|
+
Object.defineProperty(exports, "action", { enumerable: true, get: function () { return decorators_1.action; } });
|
|
6
|
+
Object.defineProperty(exports, "DEFAULT_ACTION", { enumerable: true, get: function () { return decorators_1.DEFAULT_ACTION; } });
|
|
7
|
+
Object.defineProperty(exports, "onDefault", { enumerable: true, get: function () { return decorators_1.onDefault; } });
|
|
8
|
+
var options_1 = require("./options");
|
|
9
|
+
Object.defineProperty(exports, "commandArgs", { enumerable: true, get: function () { return options_1.commandArgs; } });
|
|
10
|
+
Object.defineProperty(exports, "parseOptions", { enumerable: true, get: function () { return options_1.parseOptions; } });
|
|
11
|
+
Object.defineProperty(exports, "validate", { enumerable: true, get: function () { return options_1.validate; } });
|
|
12
|
+
var Application_1 = require("./Application");
|
|
13
|
+
Object.defineProperty(exports, "Application", { enumerable: true, get: function () { return Application_1.Application; } });
|
|
14
|
+
var IErrorHandler_1 = require("./IErrorHandler");
|
|
15
|
+
Object.defineProperty(exports, "IErrorHandlerKey", { enumerable: true, get: function () { return IErrorHandler_1.IErrorHandlerKey; } });
|
|
16
|
+
var usage_1 = require("./usage");
|
|
17
|
+
Object.defineProperty(exports, "USAGE", { enumerable: true, get: function () { return usage_1.USAGE; } });
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validate = exports.parseOptions = exports.commandArgs = void 0;
|
|
4
|
+
const node_util_1 = require("node:util");
|
|
5
|
+
const zod_1 = require("zod");
|
|
6
|
+
const DomainException_1 = require("../exceptions/DomainException");
|
|
7
|
+
const commandArgs = ({ args = [] }) => args.map(String);
|
|
8
|
+
exports.commandArgs = commandArgs;
|
|
9
|
+
const parseOptions = (options) => (argv) => {
|
|
10
|
+
const firstFlag = argv.findIndex((arg) => arg.startsWith('-'));
|
|
11
|
+
try {
|
|
12
|
+
return { ...(0, node_util_1.parseArgs)({ args: firstFlag >= 0 ? argv.slice(firstFlag) : [], options, strict: true }).values };
|
|
13
|
+
}
|
|
14
|
+
catch (e) {
|
|
15
|
+
throw new DomainException_1.UsageError(e.message);
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
exports.parseOptions = parseOptions;
|
|
19
|
+
const validate = (schema) => (value) => {
|
|
20
|
+
const result = schema.safeParse(value);
|
|
21
|
+
if (!result.success)
|
|
22
|
+
throw new DomainException_1.UsageError(zod_1.z.prettifyError(result.error));
|
|
23
|
+
return result.data;
|
|
24
|
+
};
|
|
25
|
+
exports.validate = validate;
|
package/cjm/cli/usage.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.USAGE = void 0;
|
|
4
|
+
exports.USAGE = [
|
|
5
|
+
'Usage: ts-ioc-container <command> [options]',
|
|
6
|
+
' tic is a shortcut for ts-ioc-container',
|
|
7
|
+
'',
|
|
8
|
+
'Commands:',
|
|
9
|
+
' ts-ioc-container build [--config <path>]... [--check] generate one bundle per *.bundle.{json,yaml,yml} config',
|
|
10
|
+
' (none: one bundle from tsconfig.json, all defaults)',
|
|
11
|
+
' ts-ioc-container help show this help',
|
|
12
|
+
' ts-ioc-container version show the version',
|
|
13
|
+
'',
|
|
14
|
+
'Options:',
|
|
15
|
+
' -c, --config <path> build only this config; repeatable (default: every *.bundle.{json,yaml,yml} of the package, else tsconfig.json)',
|
|
16
|
+
' --check write nothing; exit 1 when a generated bundle is out of date',
|
|
17
|
+
' -h, --help show this help',
|
|
18
|
+
' -v, --version show the version',
|
|
19
|
+
].join('\n');
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.processIo = exports.CliIoKey = void 0;
|
|
4
|
+
const ts_ioc_container_1 = require("ts-ioc-container");
|
|
5
|
+
exports.CliIoKey = new ts_ioc_container_1.SingleToken('CliIo');
|
|
6
|
+
const processIo = () => ({ cwd: process.cwd(), stdout: console.log, stderr: console.error });
|
|
7
|
+
exports.processIo = processIo;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.globalConfig = exports.GlobalConfigKey = void 0;
|
|
4
|
+
const ts_ioc_container_1 = require("ts-ioc-container");
|
|
5
|
+
exports.GlobalConfigKey = new ts_ioc_container_1.SingleToken('GlobalConfig');
|
|
6
|
+
const globalConfig = (key) => ({ scope }) => exports.GlobalConfigKey.resolve(scope)[key];
|
|
7
|
+
exports.globalConfig = globalConfig;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.StaleBundlesError = exports.UsageError = exports.UnknownActionError = exports.UnknownCommandError = exports.MissingCommandError = exports.NamespaceNotFoundError = exports.TicConfigError = exports.TicError = void 0;
|
|
4
|
+
class TicError extends Error {
|
|
5
|
+
code;
|
|
6
|
+
constructor(code, message) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.code = code;
|
|
9
|
+
this.name = new.target.name;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
exports.TicError = TicError;
|
|
13
|
+
class TicConfigError extends TicError {
|
|
14
|
+
constructor(message) {
|
|
15
|
+
super('INVALID_CONFIG', message);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.TicConfigError = TicConfigError;
|
|
19
|
+
class NamespaceNotFoundError extends TicError {
|
|
20
|
+
constructor(message) {
|
|
21
|
+
super('NAMESPACE_NOT_FOUND', message);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
exports.NamespaceNotFoundError = NamespaceNotFoundError;
|
|
25
|
+
class MissingCommandError extends TicError {
|
|
26
|
+
constructor(usage) {
|
|
27
|
+
super('MISSING_COMMAND', `missing command\n${usage}`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
exports.MissingCommandError = MissingCommandError;
|
|
31
|
+
class UnknownCommandError extends TicError {
|
|
32
|
+
constructor(command) {
|
|
33
|
+
super('UNKNOWN_COMMAND', `unknown command "${command}"`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
exports.UnknownCommandError = UnknownCommandError;
|
|
37
|
+
class UnknownActionError extends TicError {
|
|
38
|
+
constructor(command, action) {
|
|
39
|
+
super('UNKNOWN_ACTION', `unknown action "${action}" for command "${command}"`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
exports.UnknownActionError = UnknownActionError;
|
|
43
|
+
class UsageError extends TicError {
|
|
44
|
+
constructor(message) {
|
|
45
|
+
super('USAGE', message);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
exports.UsageError = UsageError;
|
|
49
|
+
class StaleBundlesError extends TicError {
|
|
50
|
+
constructor(count) {
|
|
51
|
+
super('STALE_BUNDLES', `${count} generated bundle${count === 1 ? ' is' : 's are'} out of date — run \`tic build\``);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
exports.StaleBundlesError = StaleBundlesError;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.ExceptionHandler = void 0;
|
|
16
|
+
const ts_ioc_container_1 = require("ts-ioc-container");
|
|
17
|
+
const IErrorHandler_1 = require("../cli/IErrorHandler");
|
|
18
|
+
const ConsoleLogger_1 = require("../services/ConsoleLogger");
|
|
19
|
+
const DomainException_1 = require("./DomainException");
|
|
20
|
+
let ExceptionHandler = class ExceptionHandler {
|
|
21
|
+
logger;
|
|
22
|
+
constructor(logger) {
|
|
23
|
+
this.logger = logger;
|
|
24
|
+
}
|
|
25
|
+
handleError(error) {
|
|
26
|
+
if (error instanceof DomainException_1.TicError)
|
|
27
|
+
this.logger.error(error.message);
|
|
28
|
+
else
|
|
29
|
+
this.logger.error(error instanceof Error ? (error.stack ?? error.message) : String(error));
|
|
30
|
+
return 1;
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
exports.ExceptionHandler = ExceptionHandler;
|
|
34
|
+
exports.ExceptionHandler = ExceptionHandler = __decorate([
|
|
35
|
+
(0, ts_ioc_container_1.register)(IErrorHandler_1.IErrorHandlerKey, (0, ts_ioc_container_1.singleton)()),
|
|
36
|
+
__param(0, (0, ts_ioc_container_1.inject)((0, ts_ioc_container_1.by)(ConsoleLogger_1.ILoggerKey))),
|
|
37
|
+
__metadata("design:paramtypes", [Object])
|
|
38
|
+
], ExceptionHandler);
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.configSuffix = exports.CONFIG_FILE_SUFFIXES = exports.BUNDLE_CONFIG_SCHEMA = exports.DEFAULT_EXCLUDE = exports.DEFAULT_DECORATORS = exports.DEFAULT_BUNDLE_NAME = exports.DEFAULT_EXTENDS = void 0;
|
|
7
|
+
exports.toClassName = toClassName;
|
|
8
|
+
exports.resolveConfig = resolveConfig;
|
|
9
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
10
|
+
const zod_1 = require("zod");
|
|
11
|
+
const DomainException_1 = require("../../exceptions/DomainException");
|
|
12
|
+
const glob_1 = require("./domain/glob");
|
|
13
|
+
exports.DEFAULT_EXTENDS = './tsconfig.json';
|
|
14
|
+
exports.DEFAULT_BUNDLE_NAME = 'base';
|
|
15
|
+
exports.DEFAULT_DECORATORS = ['register'];
|
|
16
|
+
exports.DEFAULT_EXCLUDE = [
|
|
17
|
+
'**/*.spec.ts',
|
|
18
|
+
'**/*.test.ts',
|
|
19
|
+
'**/*.spec.tsx',
|
|
20
|
+
'**/*.test.tsx',
|
|
21
|
+
'**/__tests__/**',
|
|
22
|
+
'**/node_modules/**',
|
|
23
|
+
];
|
|
24
|
+
const BUNDLE_NAME = /^[A-Za-z][\w-]*$/;
|
|
25
|
+
const expected = (what) => ({ error: `expected ${what}` });
|
|
26
|
+
const nonEmptyString = () => zod_1.z.string(expected('a non-empty string')).min(1, expected('a non-empty string'));
|
|
27
|
+
const isNonEmptyString = (value) => typeof value === 'string' && value.length > 0;
|
|
28
|
+
const strings = (what, minItems) => zod_1.z
|
|
29
|
+
.custom((value) => Array.isArray(value) && value.length >= minItems && value.every(isNonEmptyString), expected(what))
|
|
30
|
+
.meta({ type: 'array', items: { type: 'string', minLength: 1 }, ...(minItems > 0 && { minItems }) });
|
|
31
|
+
const stringList = () => strings('an array of strings', 0);
|
|
32
|
+
const nonEmptyStringList = () => strings('a non-empty array of strings', 1);
|
|
33
|
+
const PATH_SCHEMA = zod_1.z.union([
|
|
34
|
+
nonEmptyString(),
|
|
35
|
+
zod_1.z.object({
|
|
36
|
+
path: nonEmptyString(),
|
|
37
|
+
recursive: zod_1.z.boolean(expected('a boolean')).default(true),
|
|
38
|
+
}, expected('a string or an object with "path"')),
|
|
39
|
+
], expected('a string or an object with "path"'));
|
|
40
|
+
const FILES_SCHEMA = zod_1.z
|
|
41
|
+
.strictObject({
|
|
42
|
+
paths: zod_1.z
|
|
43
|
+
.array(PATH_SCHEMA, expected('a non-empty array'))
|
|
44
|
+
.min(1, expected('a non-empty array'))
|
|
45
|
+
.optional()
|
|
46
|
+
.describe("Folders to scan instead of the extended tsconfig's file set: paths relative to this file (./src/services) or tsconfig paths aliases (@app/services). Required when there is no tsconfig to extend."),
|
|
47
|
+
include: nonEmptyStringList()
|
|
48
|
+
.optional()
|
|
49
|
+
.describe('Globs a file must match one of, e.g. ["**/*.service.ts", "**/*.repository.ts"]. Default: every source file.'),
|
|
50
|
+
exclude: stringList()
|
|
51
|
+
.default(exports.DEFAULT_EXCLUDE)
|
|
52
|
+
.describe('Globs of files never read. Replaces the default when given. A non-empty list that omits a default glob makes `tic build` warn.'),
|
|
53
|
+
}, expected('an object'))
|
|
54
|
+
.describe('Which files this bundle reads and parses — decided by path alone, before parsing. The candidates are what the extended tsconfig compiles, or the folders in `paths` when given. A candidate is parsed when it matches one of `include` and none of `exclude`. Globs are relative to this file. With a file naming convention, `include` keeps every other file unread.');
|
|
55
|
+
const CLASSES_SCHEMA = zod_1.z
|
|
56
|
+
.strictObject({
|
|
57
|
+
export: zod_1.z
|
|
58
|
+
.enum(['any', 'named', 'default'], expected('"any", "named" or "default"'))
|
|
59
|
+
.default('any')
|
|
60
|
+
.describe('Which exports count.'),
|
|
61
|
+
decorators: stringList()
|
|
62
|
+
.default(exports.DEFAULT_DECORATORS)
|
|
63
|
+
.describe('The class must carry one of these decorators, recognised by name (e.g. "register", or a composed decorator). Default ["register"]; [] requires none.'),
|
|
64
|
+
name: nonEmptyString()
|
|
65
|
+
.optional()
|
|
66
|
+
.describe('Glob the class name must match, e.g. "*Service". An anonymous default export is named after its file.'),
|
|
67
|
+
excludeClasses: nonEmptyStringList()
|
|
68
|
+
.optional()
|
|
69
|
+
.describe('Class names to drop after selection, e.g. one test double sitting next to the real registration in the same file.'),
|
|
70
|
+
excludeName: nonEmptyString()
|
|
71
|
+
.optional()
|
|
72
|
+
.describe('Glob the class name must NOT match, e.g. "*Mock". An anonymous default export is named after its file.'),
|
|
73
|
+
}, expected('an object'))
|
|
74
|
+
.describe('Which classes of a parsed file are registered. A class is selected when it is exported, not abstract, and meets every criterion set here; by default that is every exported class decorated with @register.');
|
|
75
|
+
exports.BUNDLE_CONFIG_SCHEMA = zod_1.z.strictObject({
|
|
76
|
+
$schema: zod_1.z.string().optional(),
|
|
77
|
+
output: nonEmptyString()
|
|
78
|
+
.optional()
|
|
79
|
+
.describe("The bundle file (convention: *.bundle.ts). Default `<root>/<name>.bundle.ts`: <root> is the tsconfig's rootDir, else the common folder of the files it compiles. Required when there is no tsconfig to extend."),
|
|
80
|
+
name: zod_1.z
|
|
81
|
+
.string(expected('letters, digits, "-" or "_", starting with a letter'))
|
|
82
|
+
.regex(BUNDLE_NAME, expected('letters, digits, "-" or "_", starting with a letter'))
|
|
83
|
+
.optional()
|
|
84
|
+
.describe('The bundle\'s name: letters, digits, "-" and "_", starting with a letter. Default: this file\'s stem (production.bundle.json → production), else "base". It names the default output (production.bundle.ts) and the generated IContainerModule class (ProductionBundle).'),
|
|
85
|
+
tags: stringList().default([]).describe('Tags associated with the bundle.'),
|
|
86
|
+
extends: nonEmptyString()
|
|
87
|
+
.optional()
|
|
88
|
+
.meta({ default: exports.DEFAULT_EXTENDS })
|
|
89
|
+
.describe("The tsconfig this bundle builds on, like a tsconfig's own `extends`: what it compiles (`files` / `include` / `exclude`) is the bundle's file set unless `files.paths` overrides it, and its `paths` aliases and module resolution shape the generated imports. Relative to this file. The default may be absent; a tsconfig named here must exist."),
|
|
90
|
+
importExtension: zod_1.z
|
|
91
|
+
.string(expected('a string'))
|
|
92
|
+
.optional()
|
|
93
|
+
.describe('Extension of generated imports, e.g. ".js". Inferred from the tsconfig: ".js" under node16/nodenext resolution, none otherwise.'),
|
|
94
|
+
files: FILES_SCHEMA.optional(),
|
|
95
|
+
classes: CLASSES_SCHEMA.optional(),
|
|
96
|
+
}, expected('an object'));
|
|
97
|
+
function formatPath(segments) {
|
|
98
|
+
const formatted = segments
|
|
99
|
+
.map((segment) => (typeof segment === 'number' ? `[${segment}]` : `.${String(segment)}`))
|
|
100
|
+
.join('')
|
|
101
|
+
.replace(/^\./, '');
|
|
102
|
+
return formatted || 'config';
|
|
103
|
+
}
|
|
104
|
+
function matchedBranch(issue) {
|
|
105
|
+
const typeMatched = issue.errors.filter((branch) => branch.every((inner) => inner.code !== 'invalid_type' || inner.path.length > 0));
|
|
106
|
+
return typeMatched.length === 1 ? typeMatched[0] : undefined;
|
|
107
|
+
}
|
|
108
|
+
function formatIssue(issue, prefix = []) {
|
|
109
|
+
const at = [...prefix, ...issue.path];
|
|
110
|
+
if (issue.code === 'unrecognized_keys')
|
|
111
|
+
return issue.keys.map((key) => `${formatPath([...at, key])}: unknown field`);
|
|
112
|
+
const branch = issue.code === 'invalid_union' ? matchedBranch(issue) : undefined;
|
|
113
|
+
if (branch)
|
|
114
|
+
return branch.flatMap((inner) => formatIssue(inner, at));
|
|
115
|
+
return [`${formatPath(at)}: ${issue.message}`];
|
|
116
|
+
}
|
|
117
|
+
const formatIssues = (error) => error.issues.flatMap((issue) => formatIssue(issue)).join('; ');
|
|
118
|
+
function toFileSelector(files) {
|
|
119
|
+
if (files === undefined)
|
|
120
|
+
return { exclude: exports.DEFAULT_EXCLUDE.map(glob_1.globToRegExp) };
|
|
121
|
+
return {
|
|
122
|
+
paths: files.paths?.map((entry) => (typeof entry === 'string' ? { path: entry, recursive: true } : entry)),
|
|
123
|
+
include: files.include?.map(glob_1.globToRegExp),
|
|
124
|
+
exclude: files.exclude.map(glob_1.globToRegExp),
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
function toClassSelector(classes) {
|
|
128
|
+
if (classes === undefined)
|
|
129
|
+
return { export: 'any', decorators: exports.DEFAULT_DECORATORS };
|
|
130
|
+
const { decorators, name, excludeName, ...rest } = classes;
|
|
131
|
+
return {
|
|
132
|
+
...rest,
|
|
133
|
+
decorators: decorators.length > 0 ? decorators : undefined,
|
|
134
|
+
name: name === undefined ? undefined : (0, glob_1.globToRegExp)(name),
|
|
135
|
+
excludeName: excludeName === undefined ? undefined : (0, glob_1.globToRegExp)(excludeName),
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
function excludeWarnings(files) {
|
|
139
|
+
const exclude = files?.exclude ?? [];
|
|
140
|
+
if (exclude.length === 0)
|
|
141
|
+
return [];
|
|
142
|
+
const missing = exports.DEFAULT_EXCLUDE.filter((glob) => !exclude.includes(glob));
|
|
143
|
+
if (missing.length === 0)
|
|
144
|
+
return [];
|
|
145
|
+
return [
|
|
146
|
+
`files.exclude replaces the default excludes and omits ${missing.map((glob) => `"${glob}"`).join(', ')}; ` +
|
|
147
|
+
`add them back`,
|
|
148
|
+
];
|
|
149
|
+
}
|
|
150
|
+
exports.CONFIG_FILE_SUFFIXES = ['.bundle.json', '.bundle.yaml', '.bundle.yml'];
|
|
151
|
+
const configSuffix = (file) => exports.CONFIG_FILE_SUFFIXES.find((suffix) => file.endsWith(suffix));
|
|
152
|
+
exports.configSuffix = configSuffix;
|
|
153
|
+
function configStem(file) {
|
|
154
|
+
const base = node_path_1.default.basename(file);
|
|
155
|
+
const suffix = (0, exports.configSuffix)(base);
|
|
156
|
+
const stem = suffix ? base.slice(0, -suffix.length) : '';
|
|
157
|
+
return BUNDLE_NAME.test(stem) ? stem : undefined;
|
|
158
|
+
}
|
|
159
|
+
function toClassName(name) {
|
|
160
|
+
const words = name.split(/[-_]+/).filter(Boolean);
|
|
161
|
+
return `${words.map((word) => word[0].toUpperCase() + word.slice(1)).join('')}Bundle`;
|
|
162
|
+
}
|
|
163
|
+
function resolveConfig(content, file) {
|
|
164
|
+
const result = exports.BUNDLE_CONFIG_SCHEMA.safeParse(content);
|
|
165
|
+
if (!result.success)
|
|
166
|
+
throw new DomainException_1.TicConfigError(formatIssues(result.error));
|
|
167
|
+
const { output, name, tags, extends: tsconfig, importExtension, files, classes } = result.data;
|
|
168
|
+
const dir = node_path_1.default.dirname(file);
|
|
169
|
+
const bundleName = name ?? configStem(file) ?? exports.DEFAULT_BUNDLE_NAME;
|
|
170
|
+
return {
|
|
171
|
+
file,
|
|
172
|
+
dir,
|
|
173
|
+
output: output === undefined ? undefined : node_path_1.default.resolve(dir, output),
|
|
174
|
+
name: bundleName,
|
|
175
|
+
className: toClassName(bundleName),
|
|
176
|
+
tags,
|
|
177
|
+
tsconfig: { file: node_path_1.default.resolve(dir, tsconfig ?? exports.DEFAULT_EXTENDS), required: tsconfig !== undefined },
|
|
178
|
+
importExtension,
|
|
179
|
+
files: toFileSelector(files),
|
|
180
|
+
classes: toClassSelector(classes),
|
|
181
|
+
warnings: excludeWarnings(files),
|
|
182
|
+
};
|
|
183
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
15
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
16
|
+
};
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.BuildController = exports.BUILD_OPTIONS = void 0;
|
|
19
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
20
|
+
const ts_ioc_container_1 = require("ts-ioc-container");
|
|
21
|
+
const zod_1 = require("zod");
|
|
22
|
+
const cli_1 = require("../../cli");
|
|
23
|
+
const GlobalConfig_1 = require("../../domain/GlobalConfig");
|
|
24
|
+
const DomainException_1 = require("../../exceptions/DomainException");
|
|
25
|
+
const ConsoleLogger_1 = require("../../services/ConsoleLogger");
|
|
26
|
+
const OutputService_1 = require("../../services/OutputService");
|
|
27
|
+
const BundleBuilder_1 = require("./services/BundleBuilder");
|
|
28
|
+
const TicConfigService_1 = require("./services/TicConfigService");
|
|
29
|
+
exports.BUILD_OPTIONS = zod_1.z.object({
|
|
30
|
+
config: zod_1.z.array(zod_1.z.string().min(1)).default([]),
|
|
31
|
+
check: zod_1.z.boolean().default(false),
|
|
32
|
+
});
|
|
33
|
+
const buildArgs = (0, cli_1.parseOptions)({
|
|
34
|
+
config: { type: 'string', short: 'c', multiple: true },
|
|
35
|
+
check: { type: 'boolean' },
|
|
36
|
+
});
|
|
37
|
+
const VERB = { written: 'wrote', unchanged: 'unchanged', stale: 'stale' };
|
|
38
|
+
const plural = (n) => `${n} registration${n === 1 ? '' : 's'}`;
|
|
39
|
+
let BuildController = class BuildController {
|
|
40
|
+
cwd;
|
|
41
|
+
configs;
|
|
42
|
+
builder;
|
|
43
|
+
output;
|
|
44
|
+
logger;
|
|
45
|
+
constructor(cwd, configs, builder, output, logger) {
|
|
46
|
+
this.cwd = cwd;
|
|
47
|
+
this.configs = configs;
|
|
48
|
+
this.builder = builder;
|
|
49
|
+
this.output = output;
|
|
50
|
+
this.logger = logger;
|
|
51
|
+
}
|
|
52
|
+
build(options) {
|
|
53
|
+
let stale = 0;
|
|
54
|
+
for (const config of this.configs.discover(options.config)) {
|
|
55
|
+
const name = config === undefined ? TicConfigService_1.TSCONFIG_FILE : node_path_1.default.relative(this.cwd, config);
|
|
56
|
+
try {
|
|
57
|
+
const { output, warnings } = this.builder.build({ config, check: options.check });
|
|
58
|
+
for (const warning of warnings)
|
|
59
|
+
this.logger.warn(`${name}: ${warning}`);
|
|
60
|
+
const { status, file, registrations } = output;
|
|
61
|
+
this.output.write(`${VERB[status].padEnd(10)}${node_path_1.default.relative(this.cwd, file)} (${plural(registrations)})`);
|
|
62
|
+
if (status === 'stale')
|
|
63
|
+
stale++;
|
|
64
|
+
}
|
|
65
|
+
catch (e) {
|
|
66
|
+
if (e instanceof DomainException_1.TicError)
|
|
67
|
+
e.message = `${name}: ${e.message}`;
|
|
68
|
+
throw e;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
if (stale > 0)
|
|
72
|
+
throw new DomainException_1.StaleBundlesError(stale);
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
exports.BuildController = BuildController;
|
|
76
|
+
__decorate([
|
|
77
|
+
(0, cli_1.onDefault)(ts_ioc_container_1.invoke),
|
|
78
|
+
__param(0, (0, ts_ioc_container_1.inject)((0, ts_ioc_container_1.pipe)(cli_1.commandArgs, buildArgs, (0, cli_1.validate)(exports.BUILD_OPTIONS)))),
|
|
79
|
+
__metadata("design:type", Function),
|
|
80
|
+
__metadata("design:paramtypes", [Object]),
|
|
81
|
+
__metadata("design:returntype", void 0)
|
|
82
|
+
], BuildController.prototype, "build", null);
|
|
83
|
+
exports.BuildController = BuildController = __decorate([
|
|
84
|
+
(0, ts_ioc_container_1.register)('build'),
|
|
85
|
+
__param(0, (0, ts_ioc_container_1.inject)((0, GlobalConfig_1.globalConfig)('cwd'))),
|
|
86
|
+
__param(1, (0, ts_ioc_container_1.inject)((0, ts_ioc_container_1.by)(TicConfigService_1.ITicConfigServiceKey))),
|
|
87
|
+
__param(2, (0, ts_ioc_container_1.inject)((0, ts_ioc_container_1.by)(BundleBuilder_1.IBundleBuilderKey))),
|
|
88
|
+
__param(3, (0, ts_ioc_container_1.inject)((0, ts_ioc_container_1.by)(OutputService_1.IOutputServiceKey))),
|
|
89
|
+
__param(4, (0, ts_ioc_container_1.inject)((0, ts_ioc_container_1.by)(ConsoleLogger_1.ILoggerKey))),
|
|
90
|
+
__metadata("design:paramtypes", [String, Object, Object, Object, Object])
|
|
91
|
+
], BuildController);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BuildModule = void 0;
|
|
4
|
+
const ts_ioc_container_1 = require("ts-ioc-container");
|
|
5
|
+
const BuildController_1 = require("./BuildController");
|
|
6
|
+
const BundleBuilder_1 = require("./services/BundleBuilder");
|
|
7
|
+
const TicConfigService_1 = require("./services/TicConfigService");
|
|
8
|
+
class BuildModule {
|
|
9
|
+
applyTo(container) {
|
|
10
|
+
container
|
|
11
|
+
.addRegistration(ts_ioc_container_1.Registration.fromClass(BuildController_1.BuildController))
|
|
12
|
+
.addRegistration(ts_ioc_container_1.Registration.fromClass(BundleBuilder_1.BundleBuilder))
|
|
13
|
+
.addRegistration(ts_ioc_container_1.Registration.fromClass(TicConfigService_1.TicConfigService));
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
exports.BuildModule = BuildModule;
|
|
@@ -37,14 +37,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
37
37
|
};
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
39
|
exports.ImportPaths = void 0;
|
|
40
|
-
exports.normalizeAliasName = normalizeAliasName;
|
|
41
40
|
const node_fs_1 = require("node:fs");
|
|
42
41
|
const node_path_1 = __importDefault(require("node:path"));
|
|
43
42
|
const ts = __importStar(require("typescript"));
|
|
44
|
-
const
|
|
43
|
+
const DomainException_1 = require("../../../exceptions/DomainException");
|
|
45
44
|
const glob_1 = require("./glob");
|
|
46
45
|
const SOURCE_EXTENSION = /\.(tsx?|mts|cts)$/;
|
|
47
|
-
const NO_INPUTS = 18003;
|
|
48
46
|
const isDirectory = (dir) => (0, node_fs_1.existsSync)(dir) && (0, node_fs_1.statSync)(dir).isDirectory();
|
|
49
47
|
const isRelative = (spec) => spec.startsWith('.') || node_path_1.default.isAbsolute(spec);
|
|
50
48
|
function splitWildcard(pattern) {
|
|
@@ -54,20 +52,9 @@ function splitWildcard(pattern) {
|
|
|
54
52
|
class ImportPaths {
|
|
55
53
|
aliases;
|
|
56
54
|
extension;
|
|
57
|
-
static
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
throw new errors_1.TicConfigError(`tsconfig not found: ${tsconfig.file}`);
|
|
61
|
-
return new ImportPaths([], importExtension ?? '');
|
|
62
|
-
}
|
|
63
|
-
const { config, error } = ts.readConfigFile(tsconfig.file, ts.sys.readFile);
|
|
64
|
-
const parsed = ts.parseJsonConfigFileContent(config, ts.sys, node_path_1.default.dirname(tsconfig.file), undefined, tsconfig.file);
|
|
65
|
-
const [fatal] = [error, ...parsed.errors].filter((d) => !!d && d.code !== NO_INPUTS);
|
|
66
|
-
if (fatal) {
|
|
67
|
-
throw new errors_1.TicConfigError(`${tsconfig.file}: ${ts.flattenDiagnosticMessageText(fatal.messageText, '\n')}`);
|
|
68
|
-
}
|
|
69
|
-
const { paths = {}, baseUrl, pathsBasePath, moduleResolution } = parsed.options;
|
|
70
|
-
const base = baseUrl ?? (typeof pathsBasePath === 'string' ? pathsBasePath : node_path_1.default.dirname(tsconfig.file));
|
|
55
|
+
static fromOptions(options, tsconfigFile, importExtension) {
|
|
56
|
+
const { paths = {}, baseUrl, pathsBasePath, moduleResolution } = options;
|
|
57
|
+
const base = baseUrl ?? (typeof pathsBasePath === 'string' ? pathsBasePath : node_path_1.default.dirname(tsconfigFile));
|
|
71
58
|
const aliases = Object.entries(paths).map(([pattern, targets]) => ({
|
|
72
59
|
pattern,
|
|
73
60
|
targets: targets.map((target) => (0, glob_1.toPosix)(node_path_1.default.resolve(base, target))),
|
|
@@ -88,7 +75,7 @@ class ImportPaths {
|
|
|
88
75
|
if (found)
|
|
89
76
|
return node_path_1.default.normalize(found);
|
|
90
77
|
}
|
|
91
|
-
throw new
|
|
78
|
+
throw new DomainException_1.NamespaceNotFoundError(`namespace "${namespace}" is neither a folder relative to ${baseDir} nor a tsconfig paths alias of one`);
|
|
92
79
|
}
|
|
93
80
|
specifier(fromFile, toFile) {
|
|
94
81
|
const target = (0, glob_1.toPosix)(toFile);
|
|
@@ -99,12 +86,6 @@ class ImportPaths {
|
|
|
99
86
|
const relative = (0, glob_1.toPosix)(node_path_1.default.relative(node_path_1.default.dirname(fromFile), bare));
|
|
100
87
|
return `${relative.startsWith('.') ? relative : `./${relative}`}${this.extension}`;
|
|
101
88
|
}
|
|
102
|
-
aliasName(file) {
|
|
103
|
-
const target = (0, glob_1.toPosix)(file);
|
|
104
|
-
const bare = target.replace(SOURCE_EXTENSION, '');
|
|
105
|
-
const best = this.bestAlias(target, bare);
|
|
106
|
-
return best && normalizeAliasName(best.pattern);
|
|
107
|
-
}
|
|
108
89
|
bestAlias(target, bare) {
|
|
109
90
|
let best;
|
|
110
91
|
for (const { pattern, targets } of this.aliases) {
|
|
@@ -132,17 +113,14 @@ class ImportPaths {
|
|
|
132
113
|
const wildcard = splitWildcard(aliasTarget);
|
|
133
114
|
if (!wildcard) {
|
|
134
115
|
const exact = aliasTarget === file || aliasTarget.replace(SOURCE_EXTENSION, '') === bare;
|
|
135
|
-
return exact && !splitWildcard(pattern) ? { spec: pattern, score: Infinity
|
|
116
|
+
return exact && !splitWildcard(pattern) ? { spec: pattern, score: Infinity } : undefined;
|
|
136
117
|
}
|
|
137
118
|
const [prefix, suffix] = wildcard;
|
|
138
119
|
if (!bare.startsWith(prefix) || !bare.endsWith(suffix) || bare.length < prefix.length + suffix.length) {
|
|
139
120
|
return undefined;
|
|
140
121
|
}
|
|
141
122
|
const captured = bare.slice(prefix.length, bare.length - suffix.length);
|
|
142
|
-
return { spec: `${pattern.replace('*', captured)}${this.extension}`, score: prefix.length
|
|
123
|
+
return { spec: `${pattern.replace('*', captured)}${this.extension}`, score: prefix.length };
|
|
143
124
|
}
|
|
144
125
|
}
|
|
145
126
|
exports.ImportPaths = ImportPaths;
|
|
146
|
-
function normalizeAliasName(pattern) {
|
|
147
|
-
return pattern.replace(/^@/, '').replace(/\/?\*$/, '');
|
|
148
|
-
}
|