@ts-ioc-container/bundler 1.4.0 → 2.0.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.
@@ -1,3 +1,4 @@
1
+ import * as ts from 'typescript';
1
2
  interface Alias {
2
3
  pattern: string;
3
4
  /** Absolute, `/`-separated. */
@@ -11,15 +12,10 @@ export declare class ImportPaths {
11
12
  private readonly aliases;
12
13
  readonly extension: string;
13
14
  /**
14
- * Reads `paths` (following `extends`) and the extension imports need under the
15
- * tsconfig's `moduleResolution`; `importExtension` overrides the latter.
16
- *
17
- * @throws {TicConfigError} when a required tsconfig is missing or cannot be parsed.
15
+ * From a parsed tsconfig's options: its `paths` aliases, and the extension imports need
16
+ * under its `moduleResolution`; `importExtension` overrides the latter.
18
17
  */
19
- static load(tsconfig: {
20
- file: string;
21
- required: boolean;
22
- }, importExtension?: string): ImportPaths;
18
+ static fromOptions(options: ts.CompilerOptions, tsconfigFile: string, importExtension?: string): ImportPaths;
23
19
  constructor(aliases: Alias[], extension: string);
24
20
  /**
25
21
  * The folder a namespace names: a path relative to `baseDir`, or a `paths` alias.
@@ -29,18 +25,10 @@ export declare class ImportPaths {
29
25
  resolveNamespace(namespace: string, baseDir: string): string;
30
26
  /** The specifier `fromFile` imports `toFile` by: its most specific alias, else a relative path. */
31
27
  specifier(fromFile: string, toFile: string): string;
32
- /**
33
- * The tsconfig `paths` alias `file` is covered by, normalized to its name
34
- * (`@app/services/*` -> `app/services`), or `undefined` when no alias covers it.
35
- * Used to drop classes by alias (`select.excludeAliases`).
36
- */
37
- aliasName(file: string): string | undefined;
38
28
  private bestAlias;
39
29
  private aliasTargets;
40
30
  /** A longer matched target prefix is a more specific alias; an exact file alias beats every wildcard. */
41
31
  private matchAlias;
42
32
  }
43
- /** The name of a `paths` alias: `@app/services/*` and `@app/services` both become `app/services`. */
44
- export declare function normalizeAliasName(pattern: string): string;
45
33
  export {};
46
34
  //# sourceMappingURL=ImportPaths.d.ts.map
@@ -1,16 +1,15 @@
1
- import { type ExportPredicate } from './exportPredicate.js';
2
- import { type InclusionPredicate } from './inclusion.js';
1
+ /** The tsconfig a build without a config file extends. */
2
+ export declare const TSCONFIG_FILE = "tsconfig.json";
3
3
  export interface BuildOptions {
4
- /** Path of `tic.config.json`, relative to `cwd`. Default `tic.config.json`. */
4
+ /**
5
+ * Path of the `*.bundle.json` to build, relative to `cwd`. Omitted: build from the
6
+ * `tsconfig.json` of the package `cwd` is in (see `findPackageRoot`), every setting at its default.
7
+ */
5
8
  config?: string;
6
9
  /** Default `process.cwd()`. */
7
10
  cwd?: string;
8
11
  /** Compare instead of writing: outputs that would change are reported `stale`. */
9
12
  check?: boolean;
10
- /** Decides which scanned files take part; overrides every inclusion predicate file. */
11
- include?: InclusionPredicate;
12
- /** Decides which parsed classes become registrations; overrides every export predicate file. */
13
- filterExports?: ExportPredicate;
14
13
  }
15
14
  /** `written` / `unchanged` after a build; `stale` / `unchanged` after a check. */
16
15
  export type OutputStatus = 'written' | 'unchanged' | 'stale';
@@ -26,20 +25,18 @@ export interface OutputResult {
26
25
  export interface BuildResult {
27
26
  /** Absolute path of the config that was built. */
28
27
  config: string;
29
- outputs: OutputResult[];
28
+ output: OutputResult;
30
29
  /**
31
- * Non-fatal problems found while building, e.g. an `exclude` that drops a default
32
- * test glob or two selected classes passing the same decorator token. Each warning
33
- * names the bundle field it belongs to.
30
+ * Non-fatal problems found while building, e.g. a `files.exclude` that drops a default
31
+ * test glob or two selected classes passing the same decorator token.
34
32
  */
35
33
  warnings: string[];
36
34
  }
37
35
  /**
38
- * Generates one bundle per config entry. Every bundle is generated before any
39
- * file is written, so a failing namespace leaves the previous outputs intact.
36
+ * Generates the bundle a config describes. Nothing is written unless generation succeeds.
40
37
  *
41
- * @throws {TicConfigError} when the config, the tsconfig or a predicate file it names is missing or invalid.
42
- * @throws {NamespaceNotFoundError} when a namespace is neither a folder nor a tsconfig paths alias of one.
38
+ * @throws {TicConfigError} when the config or its tsconfig is missing or invalid, or the config has neither `files.paths` nor a tsconfig.
39
+ * @throws {NamespaceNotFoundError} when a path is neither a folder nor a tsconfig paths alias of one.
43
40
  */
44
- export declare function build({ config, cwd, check, include, filterExports, }?: BuildOptions): BuildResult;
41
+ export declare function build({ config, cwd, check }?: BuildOptions): BuildResult;
45
42
  //# sourceMappingURL=build.d.ts.map
@@ -1,120 +1,162 @@
1
+ /**
2
+ * Which files a bundle reads and parses: the first, cheap stage of selection,
3
+ * decided by path alone. The candidates are what the extended tsconfig compiles,
4
+ * or the folders in `paths` when given — they override the tsconfig's file set,
5
+ * as a child tsconfig's `include` overrides its parent's. A candidate is parsed
6
+ * when it matches one of `include` and none of `exclude`. Globs are relative to
7
+ * the config file and `/`-separated. With a file naming convention
8
+ * (`*.service.ts`), `include` keeps the bundler from reading anything else.
9
+ */
10
+ export interface FileSelector {
11
+ /**
12
+ * Folders to scan instead of the tsconfig's file set: relative to the config file,
13
+ * or tsconfig `paths` aliases. Required when there is no tsconfig to extend.
14
+ */
15
+ paths?: (string | PathConfig)[];
16
+ /** Globs a file must match one of, e.g. `**\/*.service.ts`. Default: every source file. */
17
+ include?: string[];
18
+ /** Globs of files never read. Replaces {@link DEFAULT_EXCLUDE} when given. */
19
+ exclude?: string[];
20
+ }
21
+ /** A {@link FileSelector} with its defaults filled in and its globs compiled. */
22
+ export interface ResolvedFileSelector {
23
+ /** `undefined`: the extended tsconfig's file set. */
24
+ paths?: Required<PathConfig>[];
25
+ include?: RegExp[];
26
+ exclude: RegExp[];
27
+ }
1
28
  /** Which exports of a file count: both kinds, only named exports, or only the default export. */
2
29
  export type ExportKind = 'any' | 'named' | 'default';
3
30
  /**
4
- * How the bundler picks target classes out of a file. A class is selected when
31
+ * Which classes of a parsed file are registered: the second stage of selection,
32
+ * run on the files {@link FileSelector} let through. A class is selected when
5
33
  * it is exported, not abstract, and meets every criterion set here; an empty
6
34
  * rule selects every exported class.
7
35
  */
8
36
  export interface ClassSelector {
9
37
  /** Default `any`. */
10
38
  export?: ExportKind;
11
- /** The class must carry one of these decorators, recognised by name (`register`, or a composed one). */
39
+ /**
40
+ * The class must carry one of these decorators, recognised by name (`register`, or a
41
+ * composed one). Default {@link DEFAULT_DECORATORS}; `[]` requires none.
42
+ */
12
43
  decorators?: string[];
13
44
  /** A glob the class name must match, e.g. `*Service`. An anonymous default export is named after its file. */
14
- nameGlob?: string;
45
+ name?: string;
15
46
  /**
16
47
  * Class names to drop after selection, e.g. one test double sitting next to the
17
- * real registration in the same file. Unlike `filterExports` this needs no file.
48
+ * real registration in the same file.
18
49
  */
19
50
  excludeClasses?: string[];
20
51
  /** A glob the class name must NOT match, e.g. `*Mock`. An anonymous default export is named after its file. */
21
- excludeNameGlob?: string;
22
- /**
23
- * tsconfig `paths` aliases to drop after selection: a class whose file resolves
24
- * through one of these aliases is dropped, e.g. `["services"]` for a `services/*`
25
- * (or `@services/*`) alias. Names may omit a leading `@` and a trailing `/*`.
26
- */
27
- excludeAliases?: string[];
52
+ excludeName?: string;
28
53
  }
29
54
  /** A {@link ClassSelector} with its defaults filled in and its globs compiled. */
30
- export interface ResolvedSelector {
55
+ export interface ResolvedClassSelector {
31
56
  export: ExportKind;
32
57
  decorators?: string[];
33
- nameGlob?: RegExp;
58
+ name?: RegExp;
34
59
  excludeClasses?: string[];
35
- excludeNameGlob?: RegExp;
36
- excludeAliases?: string[];
60
+ excludeName?: RegExp;
37
61
  }
38
- export interface NamespaceConfig {
62
+ export interface PathConfig {
39
63
  /** A folder relative to the config file (`./src/services`) or a tsconfig `paths` alias (`@app/services`). */
40
64
  path: string;
41
65
  /** Scan sub-folders too. Default `true`. */
42
66
  recursive?: boolean;
43
67
  }
68
+ /**
69
+ * The shape of `*.bundle.json`: one bundle, built on one tsconfig. A project that
70
+ * needs several bundles keeps one config file per bundle.
71
+ */
44
72
  export interface BundleConfig {
45
- /** The generated file, relative to the config file. */
46
- output: string;
47
- /** Name of the generated class, an `IContainerModule`. Default `Bundle`. */
48
- name?: string;
49
- namespaces: (string | NamespaceConfig)[];
50
- /** Which classes of a scanned file are registered. Default: every exported class. */
51
- select?: ClassSelector;
52
- /** Globs, relative to the config file, of files never scanned. Replaces {@link DEFAULT_EXCLUDE} when given. */
53
- exclude?: string[];
73
+ $schema?: string;
54
74
  /**
55
- * Globs, relative to the config file, of files never scanned, added on top of
56
- * `exclude` (or {@link DEFAULT_EXCLUDE} when `exclude` is omitted). Use this to
57
- * add one exclusion without restating the defaults.
75
+ * The generated file, relative to the config file. Default `<root>/<name>.bundle.ts`:
76
+ * `<root>` is the tsconfig's `rootDir`, else the common folder of the files it compiles.
77
+ * Required when there is no tsconfig to extend.
58
78
  */
59
- additionalExclude?: string[];
79
+ output?: string;
60
80
  /**
61
- * A file exporting an `InclusionPredicate`, relative to the config file. Overrides the
62
- * conventional `tic.include.*` next to the config.
81
+ * The bundle's name: letters, digits, `-` and `_`, starting with a letter. Default: the
82
+ * config file's stem (`production.bundle.json` -> `production`), else {@link DEFAULT_BUNDLE_NAME}.
83
+ * It names the default output (`production.bundle.ts`) and the generated class,
84
+ * an `IContainerModule` (`ProductionBundle`, see {@link toClassName}).
63
85
  */
64
- include?: string;
86
+ name?: string;
87
+ /** Tags associated with the bundle. */
88
+ tags?: string[];
65
89
  /**
66
- * A file exporting an `ExportPredicate`, relative to the config file. Overrides the
67
- * conventional `tic.exports.*` next to the config.
90
+ * The tsconfig the bundle builds on, like a tsconfig's own `extends`: the source of
91
+ * its file set, `paths` aliases and import extension. Relative to the config file.
92
+ * Default `./tsconfig.json`, which may be absent; a tsconfig named here must exist.
68
93
  */
69
- filterExports?: string;
70
- }
71
- /** The shape of `tic.config.json`. */
72
- export interface TicConfig {
73
- $schema?: string;
74
- /** Relative to the config file. Default `tsconfig.json`, which may be absent. */
75
- tsconfig?: string;
94
+ extends?: string;
76
95
  /** Extension of generated imports. Inferred from the tsconfig's `moduleResolution` when omitted. */
77
96
  importExtension?: string;
78
- bundles: BundleConfig[];
97
+ /** Which files are parsed. Default: what the tsconfig compiles, minus {@link DEFAULT_EXCLUDE}. */
98
+ files?: FileSelector;
99
+ /** Which classes of a parsed file are registered. Default: every exported class. */
100
+ classes?: ClassSelector;
79
101
  }
80
- export declare const DEFAULT_CONFIG_FILE = "tic.config.json";
81
- export declare const DEFAULT_BUNDLE_NAME = "Bundle";
102
+ /**
103
+ * A config file is named `<name>.bundle.json`, `<name>.bundle.yaml` or `<name>.bundle.yml`,
104
+ * e.g. `app.bundle.json`, `production.bundle.yaml`. Every format has the same shape.
105
+ */
106
+ export declare const CONFIG_FILE_SUFFIXES: string[];
107
+ export declare const DEFAULT_EXTENDS = "./tsconfig.json";
108
+ /** The bundle name when the config file gives none, e.g. building from `tsconfig.json` alone. */
109
+ export declare const DEFAULT_BUNDLE_NAME = "base";
110
+ /** What `classes.decorators` requires when omitted: the library's own `@register`. */
111
+ export declare const DEFAULT_DECORATORS: string[];
82
112
  export declare const DEFAULT_EXCLUDE: string[];
83
- /** A config whose defaults are filled in and whose paths are absolute. */
113
+ /** A {@link BundleConfig} whose defaults are filled in and whose paths are absolute. */
84
114
  export interface ResolvedConfig {
115
+ /** The config file itself. */
85
116
  file: string;
86
117
  dir: string;
118
+ /** `undefined`: derived from the tsconfig at build time (see {@link BundleConfig.output}). */
119
+ output?: string;
120
+ /** The bundle name: `production` for `production.bundle.json`. */
121
+ name: string;
122
+ /** The generated class: `ProductionBundle`. */
123
+ className: string;
124
+ tags: string[];
125
+ /** The extended tsconfig; `required` when the config names it, so it must exist. */
87
126
  tsconfig: {
88
127
  file: string;
89
128
  required: boolean;
90
129
  };
91
130
  importExtension?: string;
92
- bundles: ResolvedBundle[];
93
- /** Non-fatal problems found while resolving, e.g. an `exclude` that drops a default test glob. */
131
+ files: ResolvedFileSelector;
132
+ classes: ResolvedClassSelector;
133
+ /** Non-fatal problems found while resolving, e.g. a `files.exclude` that drops a default test glob. */
94
134
  warnings: string[];
95
135
  }
96
- export interface ResolvedBundle {
97
- output: string;
98
- name: string;
99
- namespaces: Required<NamespaceConfig>[];
100
- select: ResolvedSelector;
101
- /** The effective list: the configured `exclude` (or the defaults) followed by `additionalExclude`. */
102
- exclude: string[];
103
- /** Absolute path of the bundle's own predicate file, when it names one. */
104
- include?: string;
105
- /** Absolute path of the bundle's own export predicate file, when it names one. */
106
- filterExports?: string;
107
- }
108
136
  /**
109
- * Validates parsed `tic.config.json` content and resolves its paths against `file`'s directory.
137
+ * Validates parsed `*.bundle.json` content and resolves its paths against `file`'s directory.
110
138
  *
111
139
  * @throws {TicConfigError} when the content does not match the config shape; the message names the field.
112
140
  */
113
141
  export declare function resolveConfig(content: unknown, file: string): ResolvedConfig;
142
+ /** The generated class for a bundle name: `production` -> `ProductionBundle`, `my-app_v2` -> `MyAppV2Bundle`. */
143
+ export declare function toClassName(name: string): string;
144
+ /**
145
+ * The root of the package `dir` belongs to: the nearest folder, `dir` or above, with a
146
+ * `package.json` — the project root in a single-package project, the package in a
147
+ * monorepo. `dir` itself when no folder above has one.
148
+ */
149
+ export declare function findPackageRoot(dir: string): string;
150
+ /**
151
+ * The `*.bundle.{json,yaml,yml}` configs in `dir` (not its sub-folders), sorted by name.
152
+ *
153
+ * @throws {TicConfigError} when one bundle is described in two formats, e.g. `app.bundle.json` and `app.bundle.yaml`.
154
+ */
155
+ export declare function findConfigFiles(dir: string): string[];
114
156
  /**
115
- * Reads and validates a `tic.config.json`.
157
+ * Reads and validates a `*.bundle.json`, `*.bundle.yaml` or `*.bundle.yml`.
116
158
  *
117
- * @throws {TicConfigError} when the file is missing, is not valid JSON, or does not match the config shape.
159
+ * @throws {TicConfigError} when the file is missing, cannot be parsed, or does not match the config shape.
118
160
  */
119
161
  export declare function loadConfig(file: string): ResolvedConfig;
120
162
  //# sourceMappingURL=config.d.ts.map
package/typings/emit.d.ts CHANGED
@@ -4,15 +4,20 @@ export interface EmitInput {
4
4
  name: string;
5
5
  /** Shown in the header: where the output came from. */
6
6
  configPath: string;
7
- namespaces: string[];
7
+ /** The folders scanned; `undefined` when the files came from the extended tsconfig. */
8
+ paths?: string[];
9
+ /** Shown in the header when `paths` is `undefined`: the tsconfig the files came from. */
10
+ tsconfigPath: string;
8
11
  classes: (DiscoveredClass & {
9
12
  specifier: string;
10
13
  })[];
11
14
  }
15
+ /** The first line of every generated bundle; marks it as output, never input. */
16
+ export declare const GENERATED_HEADER = "// Generated by `tic build`";
12
17
  /**
13
18
  * Renders the generated bundle — static imports, `registrations`, and the bundle applying them —
14
19
  * from its protocol, `protocols/Bundle.ts.hbs`. This function only prepares the data: unique local
15
20
  * names, and one import per file in file order.
16
21
  */
17
- export declare function emitBundle({ name, configPath, namespaces, classes }: EmitInput): string;
22
+ export declare function emitBundle({ name, configPath, paths, tsconfigPath, classes }: EmitInput): string;
18
23
  //# sourceMappingURL=emit.d.ts.map
@@ -2,7 +2,7 @@
2
2
  export declare class TicError extends Error {
3
3
  name: string;
4
4
  }
5
- /** The config file is missing, is not JSON, or does not match the `tic.config.json` shape. */
5
+ /** The config file is missing, is not JSON, or does not match the `.bundles.json` shape. */
6
6
  export declare class TicConfigError extends TicError {
7
7
  name: string;
8
8
  }
@@ -1,12 +1,10 @@
1
- export { build, type BuildOptions, type BuildResult, type OutputResult, type OutputStatus } from './build.js';
1
+ export { build, TSCONFIG_FILE, type BuildOptions, type BuildResult, type OutputResult, type OutputStatus, } from './build.js';
2
2
  export { run, type CliIo } from './cli.js';
3
- export { loadConfig, resolveConfig, DEFAULT_CONFIG_FILE, DEFAULT_EXCLUDE, DEFAULT_BUNDLE_NAME, type TicConfig, type BundleConfig, type NamespaceConfig, type ClassSelector, type ExportKind, type ResolvedSelector, type ResolvedConfig, type ResolvedBundle, } from './config.js';
3
+ export { loadConfig, resolveConfig, CONFIG_FILE_SUFFIXES, findConfigFiles, findPackageRoot, DEFAULT_EXTENDS, DEFAULT_EXCLUDE, DEFAULT_BUNDLE_NAME, DEFAULT_DECORATORS, toClassName, type BundleConfig, type PathConfig, type ClassSelector, type ExportKind, type ResolvedClassSelector, type FileSelector, type ResolvedFileSelector, type ResolvedConfig, } from './config.js';
4
4
  export { ImportPaths } from './ImportPaths.js';
5
- export { type FilterPredicate } from './utils.js';
6
- export { type ExportPredicate, type ExportContext, EXPORTS_CONVENTION, findConventionalExportPredicate, loadExportPredicate, } from './exportPredicate.js';
7
- export { type InclusionPredicate, type InclusionContext, type TagInclusionPredicate, byTags, fileTags, INCLUSION_CONVENTION, findConventionalPredicate, loadInclusionPredicate, } from './inclusion.js';
8
- export { findClasses, listSourceFiles, type DiscoveredClass } from './scan.js';
9
- export { emitBundle, type EmitInput } from './emit.js';
5
+ export { loadTsconfig, type ExtendedTsconfig } from './tsconfig.js';
6
+ export { findClasses, isSourceFile, listSourceFiles, type DiscoveredClass } from './scan.js';
7
+ export { emitBundle, GENERATED_HEADER, type EmitInput } from './emit.js';
10
8
  export { globToRegExp } from './glob.js';
11
9
  export { TicError, TicConfigError, NamespaceNotFoundError } from './errors.js';
12
10
  //# sourceMappingURL=index.d.ts.map
package/typings/scan.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { ResolvedSelector } from './config.js';
1
+ import type { ResolvedClassSelector } from './config.js';
2
2
  /** An exported class the generated bundle registers. */
3
3
  export interface DiscoveredClass {
4
4
  file: string;
@@ -27,11 +27,13 @@ export interface DiscoveredClass {
27
27
  args: string[];
28
28
  }[];
29
29
  }
30
+ /** A TypeScript source file the bundler may parse: not a declaration file. */
31
+ export declare const isSourceFile: (file: string) => boolean;
30
32
  /** Source files of `dir`, sorted by path so the generated output is stable across machines. */
31
33
  export declare function listSourceFiles(dir: string, recursive: boolean, isExcluded: (file: string) => boolean): string[];
32
34
  /**
33
35
  * The exported, non-abstract classes of one file that `selector` selects, in
34
36
  * declaration order. Syntax only: decorators are recognised by name, not by type.
35
37
  */
36
- export declare function findClasses(file: string, selector: ResolvedSelector, text?: string): DiscoveredClass[];
38
+ export declare function findClasses(file: string, selector: ResolvedClassSelector, text?: string): DiscoveredClass[];
37
39
  //# sourceMappingURL=scan.d.ts.map
@@ -0,0 +1,25 @@
1
+ import { ImportPaths } from './ImportPaths.js';
2
+ /** What a bundle takes from the tsconfig it extends. */
3
+ export interface ExtendedTsconfig {
4
+ importPaths: ImportPaths;
5
+ /** Absolute paths of the files the tsconfig compiles; `undefined` when there is no tsconfig. */
6
+ fileNames?: string[];
7
+ /**
8
+ * Where the sources live, as tsc sees it: `rootDir`, else the longest common folder of
9
+ * the non-declaration files it compiles, else the tsconfig's folder. `undefined` when
10
+ * there is no tsconfig.
11
+ */
12
+ rootDir?: string;
13
+ }
14
+ /**
15
+ * Reads the tsconfig a bundle extends, following its own `extends`: its `paths` aliases,
16
+ * import extension and file set (`files` / `include` / `exclude`). An absent tsconfig that
17
+ * was not named explicitly yields no aliases and no file set.
18
+ *
19
+ * @throws {TicConfigError} when a required tsconfig is missing or cannot be parsed.
20
+ */
21
+ export declare function loadTsconfig(tsconfig: {
22
+ file: string;
23
+ required: boolean;
24
+ }, importExtension?: string): ExtendedTsconfig;
25
+ //# sourceMappingURL=tsconfig.d.ts.map
@@ -1,13 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.EXPORTS_CONVENTION = void 0;
4
- exports.findConventionalExportPredicate = findConventionalExportPredicate;
5
- exports.loadExportPredicate = loadExportPredicate;
6
- const predicateFile_1 = require("./predicateFile");
7
- exports.EXPORTS_CONVENTION = (0, predicateFile_1.conventionalNames)('tic.exports');
8
- function findConventionalExportPredicate(dir) {
9
- return (0, predicateFile_1.findConventionalFile)(dir, 'tic.exports');
10
- }
11
- function loadExportPredicate(file) {
12
- return (0, predicateFile_1.loadPredicateFile)(file, 'ExportPredicate');
13
- }
package/cjm/inclusion.js DELETED
@@ -1,24 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.INCLUSION_CONVENTION = void 0;
4
- exports.fileTags = fileTags;
5
- exports.byTags = byTags;
6
- exports.findConventionalPredicate = findConventionalPredicate;
7
- exports.loadInclusionPredicate = loadInclusionPredicate;
8
- const predicateFile_1 = require("./predicateFile");
9
- function fileTags(filename) {
10
- return filename
11
- .slice(filename.lastIndexOf('/') + 1)
12
- .split('.')
13
- .slice(1, -1);
14
- }
15
- function byTags(predicate) {
16
- return (context) => predicate(fileTags(context.filename), context);
17
- }
18
- exports.INCLUSION_CONVENTION = (0, predicateFile_1.conventionalNames)('tic.include');
19
- function findConventionalPredicate(dir) {
20
- return (0, predicateFile_1.findConventionalFile)(dir, 'tic.include');
21
- }
22
- function loadInclusionPredicate(file) {
23
- return (0, predicateFile_1.loadPredicateFile)(file, 'InclusionPredicate');
24
- }
@@ -1,30 +0,0 @@
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.conventionalNames = void 0;
7
- exports.findConventionalFile = findConventionalFile;
8
- exports.loadPredicateFile = loadPredicateFile;
9
- const node_fs_1 = require("node:fs");
10
- const node_module_1 = require("node:module");
11
- const node_path_1 = __importDefault(require("node:path"));
12
- const errors_1 = require("./errors");
13
- const EXTENSIONS = ['cjs', 'js', 'mjs', 'ts', 'cts', 'mts'];
14
- const conventionalNames = (base) => EXTENSIONS.map((ext) => `${base}.${ext}`);
15
- exports.conventionalNames = conventionalNames;
16
- function findConventionalFile(dir, base) {
17
- return (0, exports.conventionalNames)(base)
18
- .map((name) => node_path_1.default.join(dir, name))
19
- .find((file) => (0, node_fs_1.existsSync)(file));
20
- }
21
- function loadPredicateFile(file, typeName) {
22
- if (!(0, node_fs_1.existsSync)(file))
23
- throw new errors_1.TicConfigError(`predicate file not found: ${file}`);
24
- const loaded = (0, node_module_1.createRequire)(file)(file);
25
- const predicate = typeof loaded === 'function' ? loaded : loaded?.default;
26
- if (typeof predicate !== 'function') {
27
- throw new errors_1.TicConfigError(`${file} must export an ${typeName} function (default export or module.exports)`);
28
- }
29
- return predicate;
30
- }
package/cjm/utils.js DELETED
@@ -1,2 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,36 +0,0 @@
1
- import type { FilterPredicate } from './utils.js';
2
- /** What an {@link ExportPredicate} decides on: one exported class of a parsed file. */
3
- export interface ExportContext {
4
- /** The file's path relative to the config file, `/`-separated: `src/services/Logger.ts`. */
5
- filename: string;
6
- /** The name the class is exported under; `'default'` for a default export. */
7
- exportName: string;
8
- /** The declared class name; an anonymous default export is named after its file. */
9
- className: string;
10
- isDefault: boolean;
11
- /** Names of the class's decorators, renamed imports resolved (`register as reg` -> `'register'`). */
12
- decorators: string[];
13
- /** The file-name tags `byTags` reads: `Report.production.eu.ts` -> `['production', 'eu']`. */
14
- tags: string[];
15
- }
16
- /**
17
- * Decides, right after a file is parsed, whether one of its exported classes becomes a
18
- * registration. It runs on every exported, non-abstract class that passes `select`.
19
- *
20
- * @example
21
- * // tic.exports.ts, next to tic.config.json - picked up by convention
22
- * const filterExports: ExportPredicate = ({ exportName }) => !/(Stub|Mock|Fake)$/.test(exportName);
23
- * export default filterExports;
24
- */
25
- export type ExportPredicate = FilterPredicate<ExportContext>;
26
- /** Export predicate files looked up next to the config, in this order, when no bundle names one. */
27
- export declare const EXPORTS_CONVENTION: string[];
28
- /** The conventional export predicate file in `dir`, if there is one. */
29
- export declare function findConventionalExportPredicate(dir: string): string | undefined;
30
- /**
31
- * Loads an {@link ExportPredicate} file (see `loadPredicateFile` for formats and caching).
32
- *
33
- * @throws {TicConfigError} when the file is missing or does not export a function.
34
- */
35
- export declare function loadExportPredicate(file: string): ExportPredicate;
36
- //# sourceMappingURL=exportPredicate.d.ts.map
@@ -1,42 +0,0 @@
1
- import type { FilterPredicate } from './utils.js';
2
- /** What an {@link InclusionPredicate} decides on. */
3
- export interface InclusionContext {
4
- /** The file's path relative to the config file, `/`-separated: `src/services/Logger.ts`. */
5
- filename: string;
6
- }
7
- /**
8
- * Decides whether a scanned file takes part in code generation. A file takes
9
- * part only when it matches no `exclude` glob and the predicate returns `true`.
10
- *
11
- * @example
12
- * // tic.include.ts, next to tic.config.json - picked up by convention
13
- * const include: InclusionPredicate = ({ filename }) => !filename.includes('/legacy/');
14
- * export default include;
15
- */
16
- export type InclusionPredicate = FilterPredicate<InclusionContext>;
17
- /**
18
- * An {@link InclusionPredicate} over a file's tags, the dot-separated parts of its name between
19
- * the base name and the extension. Wrap it with {@link byTags} to use it anywhere an
20
- * `InclusionPredicate` goes.
21
- *
22
- * @example
23
- * // StripeGateway.production.ts joins production only; Shared.ts joins every environment
24
- * const ENVS = ['development', 'production', 'test'];
25
- * export default byTags((tags) => tags.filter((t) => ENVS.includes(t)).every((t) => t === process.env.TIC_ENV));
26
- */
27
- export type TagInclusionPredicate = (tags: string[], context: InclusionContext) => boolean;
28
- /** `src/Report.production.eu.ts` -> `['production', 'eu']`; `src/Shared.ts` -> `[]`. */
29
- export declare function fileTags(filename: string): string[];
30
- /** Wraps a {@link TagInclusionPredicate} into the {@link InclusionPredicate} the bundler calls. */
31
- export declare function byTags(predicate: TagInclusionPredicate): InclusionPredicate;
32
- /** Predicate files looked up next to the config, in this order, when no bundle names one. */
33
- export declare const INCLUSION_CONVENTION: string[];
34
- /** The conventional inclusion predicate file in `dir`, if there is one. */
35
- export declare function findConventionalPredicate(dir: string): string | undefined;
36
- /**
37
- * Loads an {@link InclusionPredicate} file (see `loadPredicateFile` for formats and caching).
38
- *
39
- * @throws {TicConfigError} when the file is missing or does not export a function.
40
- */
41
- export declare function loadInclusionPredicate(file: string): InclusionPredicate;
42
- //# sourceMappingURL=inclusion.d.ts.map
@@ -1,16 +0,0 @@
1
- import type { FilterPredicate } from './utils.js';
2
- /** `tic.include` -> `tic.include.cjs`, `tic.include.js`, ... in lookup order. */
3
- export declare const conventionalNames: (base: string) => string[];
4
- /** The first conventional file for `base` that exists in `dir`, if any. */
5
- export declare function findConventionalFile(dir: string, base: string): string | undefined;
6
- /**
7
- * Loads a predicate file synchronously with `require` - `.cjs` / `.js`, ES modules
8
- * (Node 22.12+) and `.ts` (Node with type stripping). Its default export, or
9
- * `module.exports` itself, is the predicate. Like any `require`d module it is loaded
10
- * once per process, so a predicate that depends on the environment should read it
11
- * when called, not when loaded.
12
- *
13
- * @throws {TicConfigError} when the file is missing or does not export a function.
14
- */
15
- export declare function loadPredicateFile<T extends FilterPredicate<never>>(file: string, typeName: string): T;
16
- //# sourceMappingURL=predicateFile.d.ts.map
@@ -1,3 +0,0 @@
1
- /** Decides whether a value is kept. The base of every predicate the bundler takes. */
2
- export type FilterPredicate<Target> = (value: Target) => boolean;
3
- //# sourceMappingURL=utils.d.ts.map