@proteinjs/reflection-build 1.4.12 → 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.
- package/CHANGELOG.md +45 -0
- package/dist/src/BuildContract.d.ts +69 -0
- package/dist/src/BuildContract.js +393 -0
- package/dist/src/BuildContract.js.map +1 -0
- package/dist/src/ReflectionDoctor.d.ts +95 -0
- package/dist/src/ReflectionDoctor.js +588 -0
- package/dist/src/ReflectionDoctor.js.map +1 -0
- package/dist/src/build.d.ts +5 -1
- package/dist/src/build.js +13 -77
- package/dist/src/build.js.map +1 -1
- package/dist/src/codegen/writeGeneratedIndex.d.ts +25 -0
- package/dist/src/codegen/writeGeneratedIndex.js +89 -13
- package/dist/src/codegen/writeGeneratedIndex.js.map +1 -1
- package/dist/src/parser/createGraphBuilder.js +30 -5
- package/dist/src/parser/createGraphBuilder.js.map +1 -1
- package/dist/src/runBuild.js +12 -2
- package/dist/src/runBuild.js.map +1 -1
- package/dist/src/runDoctor.d.ts +2 -0
- package/dist/src/runDoctor.js +83 -0
- package/dist/src/runDoctor.js.map +1 -0
- package/dist/test/DependencySourceGraphGate.test.d.ts +1 -0
- package/dist/test/DependencySourceGraphGate.test.js +78 -0
- package/dist/test/DependencySourceGraphGate.test.js.map +1 -0
- package/dist/test/GraphEmitRelativePaths.test.d.ts +1 -0
- package/dist/test/GraphEmitRelativePaths.test.js +162 -0
- package/dist/test/GraphEmitRelativePaths.test.js.map +1 -0
- package/dist/test/ReflectionDoctor.test.d.ts +1 -0
- package/dist/test/ReflectionDoctor.test.js +316 -0
- package/dist/test/ReflectionDoctor.test.js.map +1 -0
- package/dist/test/TestSubpathContract.test.d.ts +1 -0
- package/dist/test/TestSubpathContract.test.js +260 -0
- package/dist/test/TestSubpathContract.test.js.map +1 -0
- package/dist/test/ValidateDontMutate.test.d.ts +1 -0
- package/dist/test/ValidateDontMutate.test.js +238 -0
- package/dist/test/ValidateDontMutate.test.js.map +1 -0
- package/dist/test/examples/source-repository/a/generated/index.d.ts +0 -8
- package/dist/test/examples/source-repository/a/generated/index.js +1 -9
- package/dist/test/examples/source-repository/a/generated/index.js.map +1 -1
- package/dist/test/examples/source-repository/b/generated/index.d.ts +0 -8
- package/dist/test/examples/source-repository/b/generated/index.js +1 -9
- package/dist/test/examples/source-repository/b/generated/index.js.map +1 -1
- package/package.json +5 -4
- package/src/BuildContract.ts +384 -0
- package/src/ReflectionDoctor.ts +589 -0
- package/src/build.ts +19 -56
- package/src/codegen/writeGeneratedIndex.ts +80 -9
- package/src/parser/createGraphBuilder.ts +9 -4
- package/src/runBuild.ts +7 -1
- package/src/runDoctor.ts +34 -0
- package/test/DependencySourceGraphGate.test.ts +61 -0
- package/test/GraphEmitRelativePaths.test.ts +95 -0
- package/test/ReflectionDoctor.test.ts +193 -0
- package/test/TestSubpathContract.test.ts +148 -0
- package/test/ValidateDontMutate.test.ts +126 -0
- package/test/examples/source-repository/a/dist/BuildContract.d.ts +69 -0
- package/test/examples/source-repository/a/dist/BuildContract.js +393 -0
- package/test/examples/source-repository/a/dist/BuildContract.js.map +1 -0
- package/test/examples/source-repository/a/dist/build.d.ts +5 -1
- package/test/examples/source-repository/a/dist/build.js +13 -77
- package/test/examples/source-repository/a/dist/build.js.map +1 -1
- package/test/examples/source-repository/a/dist/codegen/writeGeneratedIndex.d.ts +25 -0
- package/test/examples/source-repository/a/dist/codegen/writeGeneratedIndex.js +89 -13
- package/test/examples/source-repository/a/dist/codegen/writeGeneratedIndex.js.map +1 -1
- package/test/examples/source-repository/a/dist/generated/index.d.ts +0 -8
- package/test/examples/source-repository/a/dist/generated/index.js +1 -9
- package/test/examples/source-repository/a/dist/generated/index.js.map +1 -1
- package/test/examples/source-repository/a/dist/parser/createGraphBuilder.js +30 -5
- package/test/examples/source-repository/a/dist/parser/createGraphBuilder.js.map +1 -1
- package/test/examples/source-repository/a/dist/runBuild.js +12 -2
- package/test/examples/source-repository/a/dist/runBuild.js.map +1 -1
- package/test/examples/source-repository/a/generated/index.ts +1 -9
- package/test/examples/source-repository/b/dist/BuildContract.d.ts +69 -0
- package/test/examples/source-repository/b/dist/BuildContract.js +393 -0
- package/test/examples/source-repository/b/dist/BuildContract.js.map +1 -0
- package/test/examples/source-repository/b/dist/build.d.ts +5 -1
- package/test/examples/source-repository/b/dist/build.js +13 -77
- package/test/examples/source-repository/b/dist/build.js.map +1 -1
- package/test/examples/source-repository/b/dist/codegen/writeGeneratedIndex.d.ts +25 -0
- package/test/examples/source-repository/b/dist/codegen/writeGeneratedIndex.js +89 -13
- package/test/examples/source-repository/b/dist/codegen/writeGeneratedIndex.js.map +1 -1
- package/test/examples/source-repository/b/dist/generated/index.d.ts +0 -8
- package/test/examples/source-repository/b/dist/generated/index.js +1 -9
- package/test/examples/source-repository/b/dist/generated/index.js.map +1 -1
- package/test/examples/source-repository/b/dist/parser/createGraphBuilder.js +30 -5
- package/test/examples/source-repository/b/dist/parser/createGraphBuilder.js.map +1 -1
- package/test/examples/source-repository/b/dist/runBuild.js +12 -2
- package/test/examples/source-repository/b/dist/runBuild.js.map +1 -1
- package/test/examples/source-repository/b/generated/index.ts +1 -10
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,51 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# [2.0.0](https://github.com/proteinjs/reflection/compare/@proteinjs/reflection-build@1.5.0...@proteinjs/reflection-build@2.0.0) (2026-08-18)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* **reflection-build:** emit package-relative filePaths in the source graph — kills the build-machine path disclosure ([df453e5](https://github.com/proteinjs/reflection/commit/df453e5433a6d085686c0818ec66d4826a7de6f2))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
### Features
|
|
15
|
+
|
|
16
|
+
* **reflection-build:** reflection-doctor CLI — inventory, orphan detection, --explain parent-edge traces ([ab53c39](https://github.com/proteinjs/reflection/commit/ab53c39df976feeb46ce9d6130bcf397b0d48a5e))
|
|
17
|
+
* **reflection-build:** validate-don't-mutate package-config contract + generalized ./test subpath contract (BuildContract, --fix) ([88b0a2b](https://github.com/proteinjs/reflection/commit/88b0a2b011fcf817fad6fbdff7fa5078422f4ba1))
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### BREAKING CHANGES
|
|
21
|
+
|
|
22
|
+
* **reflection-build:** reflection-build no longer rewrites package.json/tsconfig.json on
|
|
23
|
+
every build. It validates them as a contract: absent config is completed (including
|
|
24
|
+
the ./test subpath's root stubs, exports/typesVersions, tsconfig excludes), but
|
|
25
|
+
CONFLICTING config now FAILS the build with a friendly error (nothing changed on
|
|
26
|
+
disk) instead of being silently overwritten. Run `reflection-build --fix` once to
|
|
27
|
+
adopt the contract on out-of-sync packages.
|
|
28
|
+
|
|
29
|
+
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
# [1.5.0](https://github.com/proteinjs/reflection/compare/@proteinjs/reflection-build@1.4.12...@proteinjs/reflection-build@1.5.0) (2026-08-14)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
### Bug Fixes
|
|
39
|
+
|
|
40
|
+
* no-constant-condition in dependencyHasSourceGraph — rule-exempt for(;;) for the upward fs walk ([9ce4332](https://github.com/proteinjs/reflection/commit/9ce43325d0a75a7913b1c90baf86ebc2b23ca10a))
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
### Features
|
|
44
|
+
|
|
45
|
+
* generated indexes import only reflection-built dependencies ([229277f](https://github.com/proteinjs/reflection/commit/229277f0c9c26716cee8a1a80f2aaa7587cdb839))
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
6
51
|
## [1.4.12](https://github.com/proteinjs/reflection/compare/@proteinjs/reflection-build@1.4.11...@proteinjs/reflection-build@1.4.12) (2026-08-13)
|
|
7
52
|
|
|
8
53
|
**Note:** Version bump only for package @proteinjs/reflection-build
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
export interface BuildContractOptions {
|
|
2
|
+
/** Root of the package being built (contains package.json) */
|
|
3
|
+
packageDir: string;
|
|
4
|
+
/** First REFLECTION_SOURCE_DIRS entry; 'src' for prod builds */
|
|
5
|
+
primaryRoot: string;
|
|
6
|
+
/** REFLECTION_DIST_DIR or 'dist' */
|
|
7
|
+
distDirRel: string;
|
|
8
|
+
/** Absolute path to the generated index .ts this invocation emits */
|
|
9
|
+
generatedIndexPath: string;
|
|
10
|
+
/** Write conflicting values to the contract instead of failing the build */
|
|
11
|
+
fix: boolean;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* The package-config contract of a reflection build (task #104 §3.3, validate-don't-mutate).
|
|
15
|
+
*
|
|
16
|
+
* A build's artifact is only usable if the package's config points at it, so reflection-build
|
|
17
|
+
* owns that config as a contract instead of silently rewriting files on every build:
|
|
18
|
+
*
|
|
19
|
+
* - ABSENT config is completed in place (a fresh or copied package gets main/types, subpath
|
|
20
|
+
* mappings, stubs — the zero-ceremony workflow survives).
|
|
21
|
+
* - EXISTING config that conflicts with the contract fails the build with a friendly error
|
|
22
|
+
* (plain words, why it matters, the exact lines to paste, `--fix` offered first) and leaves
|
|
23
|
+
* every file untouched.
|
|
24
|
+
* - `reflection-build --fix` writes the contract over conflicting values; it is idempotent.
|
|
25
|
+
*
|
|
26
|
+
* Prod builds (primary root 'src') own main/types + the tsconfig include. Subpath builds
|
|
27
|
+
* (primary root e.g. 'test') own the complete subpath contract — root <root>.js/<root>.d.ts
|
|
28
|
+
* stubs, exports/typesVersions mappings, files[] entries, tsconfig excludes (the d51556f0
|
|
29
|
+
* class, generalized): consumers must resolve the subpath to built dist in every install
|
|
30
|
+
* shape and resolution mode, never to sources.
|
|
31
|
+
*/
|
|
32
|
+
export declare class BuildContract {
|
|
33
|
+
private readonly options;
|
|
34
|
+
constructor(options: BuildContractOptions);
|
|
35
|
+
apply(): Promise<void>;
|
|
36
|
+
private applyPackageJson;
|
|
37
|
+
/** Prod builds: main/types point at the built reflection artifact. */
|
|
38
|
+
private settleEntryPoints;
|
|
39
|
+
/** Subpath builds: exports map "." and "./<root>" to the built artifacts. */
|
|
40
|
+
private settleSubpathExports;
|
|
41
|
+
/** Subpath builds: typesVersions carries the subpath's types for node10 resolution. */
|
|
42
|
+
private settleTypesVersions;
|
|
43
|
+
/** Subpath builds: an existing files allowlist must keep shipping the root stubs. */
|
|
44
|
+
private settleFilesAllowlist;
|
|
45
|
+
/**
|
|
46
|
+
* Subpath builds: root stubs that win the node10/paths-mapped file lookup, so every install
|
|
47
|
+
* shape resolves the subpath to built dist — never to sources (the TS6059/ts-jest class).
|
|
48
|
+
*/
|
|
49
|
+
private applyStubs;
|
|
50
|
+
/**
|
|
51
|
+
* tsconfig: include the generated index; on subpath builds, exclude the root stubs from
|
|
52
|
+
* compilation. List membership only — nothing here can conflict.
|
|
53
|
+
*/
|
|
54
|
+
private applyTsconfig;
|
|
55
|
+
/**
|
|
56
|
+
* Settle one string field: absent → set; equal → ok; a dangling value (points at a file
|
|
57
|
+
* that does not exist — npm init's boilerplate `"main": "index.js"`, a stale copy) → set;
|
|
58
|
+
* a value that points at a real, different file is a deliberate setting → conflict.
|
|
59
|
+
*/
|
|
60
|
+
private settleString;
|
|
61
|
+
private formatConflicts;
|
|
62
|
+
private isProd;
|
|
63
|
+
private prodIndexJs;
|
|
64
|
+
private prodIndexDts;
|
|
65
|
+
private subpathIndexJs;
|
|
66
|
+
private subpathIndexDts;
|
|
67
|
+
private stubJsName;
|
|
68
|
+
private stubDtsName;
|
|
69
|
+
}
|
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
35
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
36
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
37
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
38
|
+
function step(op) {
|
|
39
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
40
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
41
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
42
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
43
|
+
switch (op[0]) {
|
|
44
|
+
case 0: case 1: t = op; break;
|
|
45
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
46
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
47
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
48
|
+
default:
|
|
49
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
50
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
51
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
52
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
53
|
+
if (t[2]) _.ops.pop();
|
|
54
|
+
_.trys.pop(); continue;
|
|
55
|
+
}
|
|
56
|
+
op = body.call(thisArg, _);
|
|
57
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
58
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
62
|
+
exports.BuildContract = void 0;
|
|
63
|
+
var fs = __importStar(require("fs"));
|
|
64
|
+
var path = __importStar(require("path"));
|
|
65
|
+
var tsconfigTemplate = require('./tsconfigTemplate.json');
|
|
66
|
+
/**
|
|
67
|
+
* The package-config contract of a reflection build (task #104 §3.3, validate-don't-mutate).
|
|
68
|
+
*
|
|
69
|
+
* A build's artifact is only usable if the package's config points at it, so reflection-build
|
|
70
|
+
* owns that config as a contract instead of silently rewriting files on every build:
|
|
71
|
+
*
|
|
72
|
+
* - ABSENT config is completed in place (a fresh or copied package gets main/types, subpath
|
|
73
|
+
* mappings, stubs — the zero-ceremony workflow survives).
|
|
74
|
+
* - EXISTING config that conflicts with the contract fails the build with a friendly error
|
|
75
|
+
* (plain words, why it matters, the exact lines to paste, `--fix` offered first) and leaves
|
|
76
|
+
* every file untouched.
|
|
77
|
+
* - `reflection-build --fix` writes the contract over conflicting values; it is idempotent.
|
|
78
|
+
*
|
|
79
|
+
* Prod builds (primary root 'src') own main/types + the tsconfig include. Subpath builds
|
|
80
|
+
* (primary root e.g. 'test') own the complete subpath contract — root <root>.js/<root>.d.ts
|
|
81
|
+
* stubs, exports/typesVersions mappings, files[] entries, tsconfig excludes (the d51556f0
|
|
82
|
+
* class, generalized): consumers must resolve the subpath to built dist in every install
|
|
83
|
+
* shape and resolution mode, never to sources.
|
|
84
|
+
*/
|
|
85
|
+
var BuildContract = /** @class */ (function () {
|
|
86
|
+
function BuildContract(options) {
|
|
87
|
+
this.options = options;
|
|
88
|
+
}
|
|
89
|
+
BuildContract.prototype.apply = function () {
|
|
90
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
91
|
+
var conflicts, writes, _i, writes_1, write;
|
|
92
|
+
return __generator(this, function (_a) {
|
|
93
|
+
conflicts = [];
|
|
94
|
+
writes = [];
|
|
95
|
+
this.applyPackageJson(conflicts, writes);
|
|
96
|
+
this.applyStubs(conflicts, writes);
|
|
97
|
+
this.applyTsconfig(writes);
|
|
98
|
+
if (conflicts.length > 0) {
|
|
99
|
+
throw new Error(this.formatConflicts(conflicts));
|
|
100
|
+
}
|
|
101
|
+
for (_i = 0, writes_1 = writes; _i < writes_1.length; _i++) {
|
|
102
|
+
write = writes_1[_i];
|
|
103
|
+
fs.writeFileSync(write.filePath, write.content);
|
|
104
|
+
}
|
|
105
|
+
return [2 /*return*/];
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
};
|
|
109
|
+
BuildContract.prototype.applyPackageJson = function (conflicts, writes) {
|
|
110
|
+
var packageJsonPath = path.join(this.options.packageDir, 'package.json');
|
|
111
|
+
if (!fs.existsSync(packageJsonPath)) {
|
|
112
|
+
throw new Error("package.json does not exist, run `npm init -y` to create one");
|
|
113
|
+
}
|
|
114
|
+
var original = fs.readFileSync(packageJsonPath, 'utf-8');
|
|
115
|
+
var packageJson = JSON.parse(original);
|
|
116
|
+
if (this.isProd()) {
|
|
117
|
+
this.settleEntryPoints(packageJson, conflicts);
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
this.settleSubpathExports(packageJson, conflicts);
|
|
121
|
+
this.settleTypesVersions(packageJson, conflicts);
|
|
122
|
+
this.settleFilesAllowlist(packageJson);
|
|
123
|
+
}
|
|
124
|
+
var updated = JSON.stringify(packageJson, null, 2);
|
|
125
|
+
if (updated !== JSON.stringify(JSON.parse(original), null, 2)) {
|
|
126
|
+
writes.push({ filePath: packageJsonPath, content: updated });
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
/** Prod builds: main/types point at the built reflection artifact. */
|
|
130
|
+
BuildContract.prototype.settleEntryPoints = function (packageJson, conflicts) {
|
|
131
|
+
var pasteBlock = [" \"main\": \"".concat(this.prodIndexJs(), "\","), " \"types\": \"".concat(this.prodIndexDts(), "\"")].join('\n');
|
|
132
|
+
var whyItMatters = 'Every consumer loads this package through main/types; pointing them anywhere but the ' +
|
|
133
|
+
'built reflection artifact ships a package that loads the wrong code.';
|
|
134
|
+
this.settleString(packageJson, 'main', this.prodIndexJs(), conflicts, whyItMatters, pasteBlock);
|
|
135
|
+
this.settleString(packageJson, 'types', this.prodIndexDts(), conflicts, whyItMatters, pasteBlock);
|
|
136
|
+
};
|
|
137
|
+
/** Subpath builds: exports map "." and "./<root>" to the built artifacts. */
|
|
138
|
+
BuildContract.prototype.settleSubpathExports = function (packageJson, conflicts) {
|
|
139
|
+
var _a;
|
|
140
|
+
var root = this.options.primaryRoot;
|
|
141
|
+
var expectedExports = (_a = {
|
|
142
|
+
'.': { types: this.prodIndexDts(), default: this.prodIndexJs() }
|
|
143
|
+
},
|
|
144
|
+
_a["./".concat(root)] = { types: this.subpathIndexDts(), default: this.subpathIndexJs() },
|
|
145
|
+
_a);
|
|
146
|
+
var whyItMatters = "Consumers import '<package>/".concat(root, "' through these mappings; a wrong mapping resolves ") +
|
|
147
|
+
'to the wrong files (or to sources), breaking consumer builds.';
|
|
148
|
+
if (packageJson.exports == null) {
|
|
149
|
+
packageJson.exports = expectedExports;
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
for (var _i = 0, _b = Object.keys(expectedExports); _i < _b.length; _i++) {
|
|
153
|
+
var subpath = _b[_i];
|
|
154
|
+
var expected = expectedExports[subpath];
|
|
155
|
+
var current = packageJson.exports[subpath];
|
|
156
|
+
if (current == null) {
|
|
157
|
+
packageJson.exports[subpath] = expected;
|
|
158
|
+
}
|
|
159
|
+
else if (JSON.stringify(current) !== JSON.stringify(expected)) {
|
|
160
|
+
if (this.options.fix) {
|
|
161
|
+
packageJson.exports[subpath] = expected;
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
conflicts.push({
|
|
165
|
+
file: 'package.json',
|
|
166
|
+
found: "\"exports\" maps \"".concat(subpath, "\" to ").concat(JSON.stringify(current)),
|
|
167
|
+
expected: JSON.stringify(expected),
|
|
168
|
+
whyItMatters: whyItMatters,
|
|
169
|
+
pasteBlock: " \"exports\": ".concat(JSON.stringify(expectedExports, null, 2).replace(/\n/g, '\n ')),
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
/** Subpath builds: typesVersions carries the subpath's types for node10 resolution. */
|
|
176
|
+
BuildContract.prototype.settleTypesVersions = function (packageJson, conflicts) {
|
|
177
|
+
var _a;
|
|
178
|
+
var root = this.options.primaryRoot;
|
|
179
|
+
// No leading './' by typesVersions convention.
|
|
180
|
+
var expected = [this.subpathIndexDts().replace(/^\.\//, '')];
|
|
181
|
+
var expectedBlock = { '*': (_a = {}, _a[root] = expected, _a) };
|
|
182
|
+
if (packageJson.typesVersions == null) {
|
|
183
|
+
packageJson.typesVersions = expectedBlock;
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
if (packageJson.typesVersions['*'] == null) {
|
|
187
|
+
packageJson.typesVersions['*'] = expectedBlock['*'];
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
var current = packageJson.typesVersions['*'][root];
|
|
191
|
+
if (current == null) {
|
|
192
|
+
packageJson.typesVersions['*'][root] = expected;
|
|
193
|
+
}
|
|
194
|
+
else if (JSON.stringify(current) !== JSON.stringify(expected)) {
|
|
195
|
+
if (this.options.fix) {
|
|
196
|
+
packageJson.typesVersions['*'][root] = expected;
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
conflicts.push({
|
|
200
|
+
file: 'package.json',
|
|
201
|
+
found: "\"typesVersions\" maps \"".concat(root, "\" to ").concat(JSON.stringify(current)),
|
|
202
|
+
expected: JSON.stringify(expected),
|
|
203
|
+
whyItMatters: "Editors and node10-resolution consumers find '<package>/".concat(root, "' types through this ") +
|
|
204
|
+
'mapping; a wrong mapping breaks type resolution for every consumer.',
|
|
205
|
+
pasteBlock: " \"typesVersions\": ".concat(JSON.stringify(expectedBlock, null, 2).replace(/\n/g, '\n ')),
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
/** Subpath builds: an existing files allowlist must keep shipping the root stubs. */
|
|
211
|
+
BuildContract.prototype.settleFilesAllowlist = function (packageJson) {
|
|
212
|
+
if (!Array.isArray(packageJson.files)) {
|
|
213
|
+
// No allowlist means npm publishes the stubs already; adding one would change what
|
|
214
|
+
// gets published, which is not this contract's call.
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
for (var _i = 0, _a = [this.stubJsName(), this.stubDtsName()]; _i < _a.length; _i++) {
|
|
218
|
+
var stub = _a[_i];
|
|
219
|
+
if (!packageJson.files.includes(stub)) {
|
|
220
|
+
packageJson.files.push(stub);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
/**
|
|
225
|
+
* Subpath builds: root stubs that win the node10/paths-mapped file lookup, so every install
|
|
226
|
+
* shape resolves the subpath to built dist — never to sources (the TS6059/ts-jest class).
|
|
227
|
+
*/
|
|
228
|
+
BuildContract.prototype.applyStubs = function (conflicts, writes) {
|
|
229
|
+
if (this.isProd()) {
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
var root = this.options.primaryRoot;
|
|
233
|
+
var targetNoExt = "./".concat(this.options.distDirRel, "/generated/").concat(root, "/index");
|
|
234
|
+
var whyItMatters = "Consumers compiled with node10/classic resolution (or a tsconfig paths mapping) resolve " +
|
|
235
|
+
"'<package>/".concat(root, "' as a file path, bypassing the exports map; without a root stub that ") +
|
|
236
|
+
'lands on sources in workspace-symlinked installs (TS6059 breaks the consumer build).';
|
|
237
|
+
var stubJs = {
|
|
238
|
+
file: this.stubJsName(),
|
|
239
|
+
content: "// Node10/classic-resolution stub for the `./".concat(root, "` subpath, owned by reflection-build.\n") +
|
|
240
|
+
"// Consumers that bypass the exports map (node10 resolution, tsconfig paths mappings) resolve\n" +
|
|
241
|
+
"// this file path first, so every install shape loads the built dist \u2014 never sources.\n" +
|
|
242
|
+
"module.exports = require('".concat(targetNoExt, ".js');\n"),
|
|
243
|
+
};
|
|
244
|
+
var stubDts = {
|
|
245
|
+
file: this.stubDtsName(),
|
|
246
|
+
content: "// Types counterpart of ".concat(this.stubJsName(), " \u2014 see that file for why this stub exists.\n") +
|
|
247
|
+
"export * from '".concat(targetNoExt, "';\n"),
|
|
248
|
+
};
|
|
249
|
+
for (var _i = 0, _a = [stubJs, stubDts]; _i < _a.length; _i++) {
|
|
250
|
+
var stub = _a[_i];
|
|
251
|
+
var stubPath = path.join(this.options.packageDir, stub.file);
|
|
252
|
+
if (!fs.existsSync(stubPath)) {
|
|
253
|
+
writes.push({ filePath: stubPath, content: stub.content });
|
|
254
|
+
continue;
|
|
255
|
+
}
|
|
256
|
+
var current = fs.readFileSync(stubPath, 'utf-8');
|
|
257
|
+
if (current.includes(targetNoExt)) {
|
|
258
|
+
continue;
|
|
259
|
+
}
|
|
260
|
+
if (this.options.fix) {
|
|
261
|
+
writes.push({ filePath: stubPath, content: stub.content });
|
|
262
|
+
}
|
|
263
|
+
else {
|
|
264
|
+
conflicts.push({
|
|
265
|
+
file: stub.file,
|
|
266
|
+
found: "".concat(stub.file, " exists but does not point at ").concat(targetNoExt),
|
|
267
|
+
expected: targetNoExt,
|
|
268
|
+
whyItMatters: whyItMatters,
|
|
269
|
+
pasteBlock: stub.content.replace(/^/gm, ' ').trimRight(),
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
};
|
|
274
|
+
/**
|
|
275
|
+
* tsconfig: include the generated index; on subpath builds, exclude the root stubs from
|
|
276
|
+
* compilation. List membership only — nothing here can conflict.
|
|
277
|
+
*/
|
|
278
|
+
BuildContract.prototype.applyTsconfig = function (writes) {
|
|
279
|
+
var tsconfigPath = path.join(this.options.packageDir, 'tsconfig.json');
|
|
280
|
+
var includePath = "./".concat(path.relative(this.options.packageDir, this.options.generatedIndexPath));
|
|
281
|
+
if (!fs.existsSync(tsconfigPath)) {
|
|
282
|
+
var tsconfig_1 = Object.assign({}, tsconfigTemplate);
|
|
283
|
+
tsconfig_1.include = [includePath];
|
|
284
|
+
if (!this.isProd()) {
|
|
285
|
+
// Fresh exclude must carry node_modules: an explicit exclude replaces the default one.
|
|
286
|
+
tsconfig_1.exclude = ['node_modules', this.stubJsName(), this.stubDtsName()];
|
|
287
|
+
}
|
|
288
|
+
writes.push({ filePath: tsconfigPath, content: JSON.stringify(tsconfig_1, null, 4) });
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
var original = fs.readFileSync(tsconfigPath, 'utf-8');
|
|
292
|
+
var tsconfig = JSON.parse(original);
|
|
293
|
+
if (tsconfig.include && !tsconfig.include.includes(includePath)) {
|
|
294
|
+
tsconfig.include.push(includePath);
|
|
295
|
+
}
|
|
296
|
+
if (!this.isProd()) {
|
|
297
|
+
if (!Array.isArray(tsconfig.exclude)) {
|
|
298
|
+
tsconfig.exclude = ['node_modules'];
|
|
299
|
+
}
|
|
300
|
+
for (var _i = 0, _a = [this.stubJsName(), this.stubDtsName()]; _i < _a.length; _i++) {
|
|
301
|
+
var stub = _a[_i];
|
|
302
|
+
if (!tsconfig.exclude.includes(stub)) {
|
|
303
|
+
tsconfig.exclude.push(stub);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
var updated = JSON.stringify(tsconfig, null, 4);
|
|
308
|
+
if (updated !== JSON.stringify(JSON.parse(original), null, 4)) {
|
|
309
|
+
writes.push({ filePath: tsconfigPath, content: updated });
|
|
310
|
+
}
|
|
311
|
+
};
|
|
312
|
+
/**
|
|
313
|
+
* Settle one string field: absent → set; equal → ok; a dangling value (points at a file
|
|
314
|
+
* that does not exist — npm init's boilerplate `"main": "index.js"`, a stale copy) → set;
|
|
315
|
+
* a value that points at a real, different file is a deliberate setting → conflict.
|
|
316
|
+
*/
|
|
317
|
+
BuildContract.prototype.settleString = function (packageJson, field, expected, conflicts, whyItMatters, pasteBlock) {
|
|
318
|
+
var current = packageJson[field];
|
|
319
|
+
if (current === expected) {
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
if (typeof current === 'string' && fs.existsSync(path.join(this.options.packageDir, current))) {
|
|
323
|
+
if (this.options.fix) {
|
|
324
|
+
packageJson[field] = expected;
|
|
325
|
+
}
|
|
326
|
+
else {
|
|
327
|
+
conflicts.push({
|
|
328
|
+
file: 'package.json',
|
|
329
|
+
found: "\"".concat(field, "\" is \"").concat(current, "\""),
|
|
330
|
+
expected: expected,
|
|
331
|
+
whyItMatters: whyItMatters,
|
|
332
|
+
pasteBlock: pasteBlock,
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
packageJson[field] = expected;
|
|
338
|
+
};
|
|
339
|
+
BuildContract.prototype.formatConflicts = function (conflicts) {
|
|
340
|
+
var lines = [];
|
|
341
|
+
lines.push("reflection-build: this package's config conflicts with what the build produces.");
|
|
342
|
+
lines.push("Nothing was changed on disk.");
|
|
343
|
+
lines.push('');
|
|
344
|
+
for (var _i = 0, conflicts_1 = conflicts; _i < conflicts_1.length; _i++) {
|
|
345
|
+
var conflict = conflicts_1[_i];
|
|
346
|
+
lines.push("- ".concat(conflict.file, ": ").concat(conflict.found));
|
|
347
|
+
lines.push(" the build's artifact is ".concat(conflict.expected));
|
|
348
|
+
lines.push(" Why it matters: ".concat(conflict.whyItMatters));
|
|
349
|
+
}
|
|
350
|
+
lines.push('');
|
|
351
|
+
lines.push("The quickest fix \u2014 rewrite just these fields to match the build:");
|
|
352
|
+
lines.push('');
|
|
353
|
+
lines.push(" npx reflection-build --fix");
|
|
354
|
+
lines.push('');
|
|
355
|
+
lines.push("Or paste the expected values in yourself:");
|
|
356
|
+
lines.push('');
|
|
357
|
+
var seen = {};
|
|
358
|
+
for (var _a = 0, conflicts_2 = conflicts; _a < conflicts_2.length; _a++) {
|
|
359
|
+
var conflict = conflicts_2[_a];
|
|
360
|
+
if (seen[conflict.pasteBlock]) {
|
|
361
|
+
continue;
|
|
362
|
+
}
|
|
363
|
+
seen[conflict.pasteBlock] = true;
|
|
364
|
+
lines.push(conflict.pasteBlock);
|
|
365
|
+
lines.push('');
|
|
366
|
+
}
|
|
367
|
+
return lines.join('\n');
|
|
368
|
+
};
|
|
369
|
+
BuildContract.prototype.isProd = function () {
|
|
370
|
+
return this.options.primaryRoot === 'src';
|
|
371
|
+
};
|
|
372
|
+
BuildContract.prototype.prodIndexJs = function () {
|
|
373
|
+
return "./".concat(path.join(this.options.distDirRel, 'generated', 'index.js'));
|
|
374
|
+
};
|
|
375
|
+
BuildContract.prototype.prodIndexDts = function () {
|
|
376
|
+
return "./".concat(path.join(this.options.distDirRel, 'generated', 'index.d.ts'));
|
|
377
|
+
};
|
|
378
|
+
BuildContract.prototype.subpathIndexJs = function () {
|
|
379
|
+
return "./".concat(path.join(this.options.distDirRel, 'generated', this.options.primaryRoot, 'index.js'));
|
|
380
|
+
};
|
|
381
|
+
BuildContract.prototype.subpathIndexDts = function () {
|
|
382
|
+
return "./".concat(path.join(this.options.distDirRel, 'generated', this.options.primaryRoot, 'index.d.ts'));
|
|
383
|
+
};
|
|
384
|
+
BuildContract.prototype.stubJsName = function () {
|
|
385
|
+
return "".concat(this.options.primaryRoot, ".js");
|
|
386
|
+
};
|
|
387
|
+
BuildContract.prototype.stubDtsName = function () {
|
|
388
|
+
return "".concat(this.options.primaryRoot, ".d.ts");
|
|
389
|
+
};
|
|
390
|
+
return BuildContract;
|
|
391
|
+
}());
|
|
392
|
+
exports.BuildContract = BuildContract;
|
|
393
|
+
//# sourceMappingURL=BuildContract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BuildContract.js","sourceRoot":"","sources":["../../src/BuildContract.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
export interface DoctorReport {
|
|
2
|
+
text: string;
|
|
3
|
+
healthy: boolean;
|
|
4
|
+
dependencies: {
|
|
5
|
+
/** reflection-built deps whose graphs load at runtime */
|
|
6
|
+
loaded: string[];
|
|
7
|
+
/** declared deps that ship no graph (normal for non-reflection deps) */
|
|
8
|
+
withoutGraph: string[];
|
|
9
|
+
/** deps opted out via SKIP_REFLECTION_LOAD */
|
|
10
|
+
skipped: string[];
|
|
11
|
+
};
|
|
12
|
+
nodeCount: number;
|
|
13
|
+
edgeCount: number;
|
|
14
|
+
sourceLinkCount: number;
|
|
15
|
+
drift: {
|
|
16
|
+
/** declarations in current sources missing from the built artifact (stale dist) */
|
|
17
|
+
missingFromDist: string[];
|
|
18
|
+
/** declarations in the built artifact no longer in sources (stale dist) */
|
|
19
|
+
onlyInDist: string[];
|
|
20
|
+
};
|
|
21
|
+
orphans: Orphan[];
|
|
22
|
+
}
|
|
23
|
+
export interface Orphan {
|
|
24
|
+
qualifiedName: string;
|
|
25
|
+
unresolvedParent: string;
|
|
26
|
+
cause: string;
|
|
27
|
+
}
|
|
28
|
+
export interface Explanation {
|
|
29
|
+
text: string;
|
|
30
|
+
verdict: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* reflection-doctor (task #104 §3.1): purely analytical diagnostics for a reflection-built
|
|
34
|
+
* package, run from the package dir. Executes NO dependency code — its own graph and every
|
|
35
|
+
* dependency graph are harvested statically from `dist/generated/index.js` artifacts (the
|
|
36
|
+
* same upward node_modules walk the build's import gate uses, transitively, mirroring what
|
|
37
|
+
* the runtime would merge).
|
|
38
|
+
*
|
|
39
|
+
* - `diagnose()` prints the registered inventory (deps with graphs / without / skip-listed),
|
|
40
|
+
* this package's node+edge+sourceLink counts, emitted-vs-source drift (stale dist), and
|
|
41
|
+
* ORPHANS: nodes the build kept because a parent is foreign, whose parent's package
|
|
42
|
+
* resolves to no loadable graph — the undeclared-dep / typo footgun that the runtime
|
|
43
|
+
* silently prunes today.
|
|
44
|
+
* - `explain(name)` prints the parent-edge resolution trace for one declaration — how (or
|
|
45
|
+
* why not) it becomes Loadable — naming the broken hop and its cause.
|
|
46
|
+
*/
|
|
47
|
+
export declare class ReflectionDoctor {
|
|
48
|
+
private readonly packageDir;
|
|
49
|
+
private readonly skipList;
|
|
50
|
+
constructor(packageDir: string, options?: {
|
|
51
|
+
skipList?: string[];
|
|
52
|
+
});
|
|
53
|
+
diagnose(): Promise<DoctorReport>;
|
|
54
|
+
explain(nameOrQualifiedName: string): Promise<Explanation>;
|
|
55
|
+
/**
|
|
56
|
+
* Recursive parent-edge trace. Returns the first Loadable-reaching direct parent (for the
|
|
57
|
+
* objects() verdict) and the first broken hop encountered, if any.
|
|
58
|
+
*/
|
|
59
|
+
private trace;
|
|
60
|
+
private classifyUnresolvedParent;
|
|
61
|
+
/** Why a package contributes no graph, from the consuming package's point of view. */
|
|
62
|
+
private classifyPackage;
|
|
63
|
+
/**
|
|
64
|
+
* Orphans: nodes this package's build kept (foreign parent ⇒ benefit of the doubt), whose
|
|
65
|
+
* parent's package contributes NO graph at runtime — the runtime will silently prune them.
|
|
66
|
+
* Parents living in loaded graphs that simply aren't Loadable are not orphans (that pruning
|
|
67
|
+
* is by design); `explain` covers those.
|
|
68
|
+
*/
|
|
69
|
+
private findOrphans;
|
|
70
|
+
/** Emitted-vs-source drift: rebuild-needed detection for the prod graph. */
|
|
71
|
+
private computeDrift;
|
|
72
|
+
/**
|
|
73
|
+
* Statically harvest this package's graph and, transitively, every reflection-built
|
|
74
|
+
* dependency's graph — the same set the runtime merges.
|
|
75
|
+
*/
|
|
76
|
+
private harvestUniverse;
|
|
77
|
+
private addToUniverse;
|
|
78
|
+
/** Extract the serialized graph from a generated index without executing it. */
|
|
79
|
+
private parseArtifactGraph;
|
|
80
|
+
private parseSourceLinkKeys;
|
|
81
|
+
private dependencyInventory;
|
|
82
|
+
private resolveTarget;
|
|
83
|
+
/** The declaration is in no harvested graph — diagnose why from this package's sources. */
|
|
84
|
+
private explainNotFound;
|
|
85
|
+
/** Raw parser pass over src — sees non-exported declarations the graph never contains. */
|
|
86
|
+
private findDeclarationInSources;
|
|
87
|
+
private checkSourceLink;
|
|
88
|
+
private findValuedNode;
|
|
89
|
+
private describeKind;
|
|
90
|
+
private formatReport;
|
|
91
|
+
/** True for shapes a qualified name can take; inline type expressions (unions, literals, comments) fail this. */
|
|
92
|
+
private isResolvableQualifiedName;
|
|
93
|
+
private dependencyNames;
|
|
94
|
+
private readPackageJson;
|
|
95
|
+
}
|