@ifc-lite/cli 0.33.1 → 0.36.1
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/README.md +9 -2
- package/dist/commands/anonymize.d.ts.map +1 -1
- package/dist/commands/anonymize.js +1 -0
- package/dist/commands/anonymize.js.map +1 -1
- package/dist/commands/check.d.ts +2 -0
- package/dist/commands/check.d.ts.map +1 -0
- package/dist/commands/check.js +119 -0
- package/dist/commands/check.js.map +1 -0
- package/dist/commands/convert.d.ts.map +1 -1
- package/dist/commands/convert.js +28 -8
- package/dist/commands/convert.js.map +1 -1
- package/dist/commands/create.d.ts.map +1 -1
- package/dist/commands/create.js +6 -0
- package/dist/commands/create.js.map +1 -1
- package/dist/commands/delivery-checks-rules.d.ts +37 -0
- package/dist/commands/delivery-checks-rules.d.ts.map +1 -0
- package/dist/commands/delivery-checks-rules.js +76 -0
- package/dist/commands/delivery-checks-rules.js.map +1 -0
- package/dist/commands/delivery-checks.d.ts +12 -0
- package/dist/commands/delivery-checks.d.ts.map +1 -1
- package/dist/commands/delivery-checks.js +16 -5
- package/dist/commands/delivery-checks.js.map +1 -1
- package/dist/commands/delivery-recipe.d.ts +13 -2
- package/dist/commands/delivery-recipe.d.ts.map +1 -1
- package/dist/commands/delivery-recipe.js +29 -17
- package/dist/commands/delivery-recipe.js.map +1 -1
- package/dist/commands/delivery-report.d.ts +2 -2
- package/dist/commands/delivery-report.d.ts.map +1 -1
- package/dist/commands/delivery-report.js +14 -4
- package/dist/commands/delivery-report.js.map +1 -1
- package/dist/commands/delivery.d.ts.map +1 -1
- package/dist/commands/delivery.js +17 -5
- package/dist/commands/delivery.js.map +1 -1
- package/dist/commands/diff-content-io.d.ts +50 -0
- package/dist/commands/diff-content-io.d.ts.map +1 -0
- package/dist/commands/diff-content-io.js +104 -0
- package/dist/commands/diff-content-io.js.map +1 -0
- package/dist/commands/diff-content-report.d.ts +23 -0
- package/dist/commands/diff-content-report.d.ts.map +1 -0
- package/dist/commands/diff-content-report.js +67 -0
- package/dist/commands/diff-content-report.js.map +1 -0
- package/dist/commands/diff-content.d.ts +19 -0
- package/dist/commands/diff-content.d.ts.map +1 -1
- package/dist/commands/diff-content.js +120 -129
- package/dist/commands/diff-content.js.map +1 -1
- package/dist/commands/diff-engine.d.ts +32 -1
- package/dist/commands/diff-engine.d.ts.map +1 -1
- package/dist/commands/diff-engine.js +76 -15
- package/dist/commands/diff-engine.js.map +1 -1
- package/dist/commands/diff-geometry.d.ts +107 -0
- package/dist/commands/diff-geometry.d.ts.map +1 -0
- package/dist/commands/diff-geometry.js +262 -0
- package/dist/commands/diff-geometry.js.map +1 -0
- package/dist/commands/diff-lineage-io.d.ts +23 -0
- package/dist/commands/diff-lineage-io.d.ts.map +1 -0
- package/dist/commands/diff-lineage-io.js +119 -0
- package/dist/commands/diff-lineage-io.js.map +1 -0
- package/dist/commands/diff-scope.d.ts.map +1 -1
- package/dist/commands/diff-scope.js +2 -0
- package/dist/commands/diff-scope.js.map +1 -1
- package/dist/commands/diff.d.ts.map +1 -1
- package/dist/commands/diff.js +36 -3
- package/dist/commands/diff.js.map +1 -1
- package/dist/commands/export.d.ts.map +1 -1
- package/dist/commands/export.js +13 -0
- package/dist/commands/export.js.map +1 -1
- package/dist/commands/ext.js +26 -10
- package/dist/commands/ext.js.map +1 -1
- package/dist/commands/extract-entities.d.ts.map +1 -1
- package/dist/commands/extract-entities.js +26 -8
- package/dist/commands/extract-entities.js.map +1 -1
- package/dist/commands/flow-tracking.d.ts +20 -0
- package/dist/commands/flow-tracking.d.ts.map +1 -0
- package/dist/commands/flow-tracking.js +86 -0
- package/dist/commands/flow-tracking.js.map +1 -0
- package/dist/commands/flow.d.ts +2 -0
- package/dist/commands/flow.d.ts.map +1 -0
- package/dist/commands/flow.js +229 -0
- package/dist/commands/flow.js.map +1 -0
- package/dist/commands/gym/channels.d.ts.map +1 -1
- package/dist/commands/gym/channels.js +10 -2
- package/dist/commands/gym/channels.js.map +1 -1
- package/dist/commands/gym.d.ts.map +1 -1
- package/dist/commands/gym.js +5 -1
- package/dist/commands/gym.js.map +1 -1
- package/dist/commands/ids.d.ts.map +1 -1
- package/dist/commands/ids.js +36 -3
- package/dist/commands/ids.js.map +1 -1
- package/dist/commands/info.d.ts.map +1 -1
- package/dist/commands/info.js +20 -5
- package/dist/commands/info.js.map +1 -1
- package/dist/commands/layer-publish.d.ts.map +1 -1
- package/dist/commands/layer-publish.js +6 -0
- package/dist/commands/layer-publish.js.map +1 -1
- package/dist/commands/lod.d.ts.map +1 -1
- package/dist/commands/lod.js +4 -1
- package/dist/commands/lod.js.map +1 -1
- package/dist/commands/mutate-step-record.d.ts +25 -1
- package/dist/commands/mutate-step-record.d.ts.map +1 -1
- package/dist/commands/mutate-step-record.js +17 -22
- package/dist/commands/mutate-step-record.js.map +1 -1
- package/dist/commands/mutate.d.ts +2 -1
- package/dist/commands/mutate.d.ts.map +1 -1
- package/dist/commands/mutate.js +27 -2
- package/dist/commands/mutate.js.map +1 -1
- package/dist/commands/rekey.d.ts +27 -0
- package/dist/commands/rekey.d.ts.map +1 -0
- package/dist/commands/rekey.js +213 -0
- package/dist/commands/rekey.js.map +1 -0
- package/dist/commands/simplify.d.ts.map +1 -1
- package/dist/commands/simplify.js +4 -1
- package/dist/commands/simplify.js.map +1 -1
- package/dist/commands/validate.d.ts +5 -14
- package/dist/commands/validate.d.ts.map +1 -1
- package/dist/commands/validate.js +13 -15
- package/dist/commands/validate.js.map +1 -1
- package/dist/headless-backend-store-authoring.d.ts +28 -0
- package/dist/headless-backend-store-authoring.d.ts.map +1 -0
- package/dist/headless-backend-store-authoring.js +34 -0
- package/dist/headless-backend-store-authoring.js.map +1 -0
- package/dist/headless-backend.d.ts +7 -0
- package/dist/headless-backend.d.ts.map +1 -1
- package/dist/headless-backend.js +78 -66
- package/dist/headless-backend.js.map +1 -1
- package/dist/help.d.ts +22 -0
- package/dist/help.d.ts.map +1 -0
- package/dist/help.js +260 -0
- package/dist/help.js.map +1 -0
- package/dist/index.js +45 -183
- package/dist/index.js.map +1 -1
- package/dist/loader.d.ts +2 -0
- package/dist/loader.d.ts.map +1 -1
- package/dist/loader.js +30 -1
- package/dist/loader.js.map +1 -1
- package/dist/out-flag-commands.d.ts +12 -0
- package/dist/out-flag-commands.d.ts.map +1 -0
- package/dist/out-flag-commands.js +19 -0
- package/dist/out-flag-commands.js.map +1 -0
- package/dist/query-overlay-relations.d.ts +8 -28
- package/dist/query-overlay-relations.d.ts.map +1 -1
- package/dist/query-overlay-relations.js +68 -78
- package/dist/query-overlay-relations.js.map +1 -1
- package/dist/query-overlay.d.ts +5 -3
- package/dist/query-overlay.d.ts.map +1 -1
- package/dist/query-overlay.js +57 -16
- package/dist/query-overlay.js.map +1 -1
- package/package.json +26 -22
- package/dist/version.d.ts +0 -14
- package/dist/version.d.ts.map +0 -1
- package/dist/version.js +0 -38
- package/dist/version.js.map +0 -1
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
|
+
export function printReport(report) {
|
|
5
|
+
const { diff } = report;
|
|
6
|
+
const out = (line) => {
|
|
7
|
+
process.stdout.write(`${line}\n`);
|
|
8
|
+
};
|
|
9
|
+
out('');
|
|
10
|
+
out(` Base: ${report.basePath}`);
|
|
11
|
+
out(` Head: ${report.headPath}`);
|
|
12
|
+
out(` Scope: ${diff.scope}` +
|
|
13
|
+
(diff.scope === 'data' ? ' (pass --geometry for world geometry hashes + boxes)' : ''));
|
|
14
|
+
if (report.keyProperty)
|
|
15
|
+
out(` Key: ${report.keyProperty} (GlobalId where absent)`);
|
|
16
|
+
out('');
|
|
17
|
+
out(` Unchanged: ${diff.counts.unchanged}`);
|
|
18
|
+
out(` Modified: ${diff.counts.modified}`);
|
|
19
|
+
out(` Added: ${diff.counts.added}`);
|
|
20
|
+
out(` Deleted: ${diff.counts.deleted}`);
|
|
21
|
+
const byKind = new Map();
|
|
22
|
+
for (const match of diff.contentMatches ?? []) {
|
|
23
|
+
byKind.set(match.kind, (byKind.get(match.kind) ?? 0) + 1);
|
|
24
|
+
}
|
|
25
|
+
out('');
|
|
26
|
+
if (byKind.size === 0) {
|
|
27
|
+
out(' Content matches: none');
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
out(' Content matches:');
|
|
31
|
+
for (const [kind, count] of [...byKind].sort()) {
|
|
32
|
+
out(` ${kind.padEnd(13)} ${count}`);
|
|
33
|
+
}
|
|
34
|
+
out(' (renamed / moved / reshaped / respecified are resolved; the rest need a human)');
|
|
35
|
+
}
|
|
36
|
+
if (diff.splitMerges) {
|
|
37
|
+
out('');
|
|
38
|
+
out(diff.splitMerges.length === 0
|
|
39
|
+
? ' Split/merge claims: none'
|
|
40
|
+
: ` Split/merge claims: ${diff.splitMerges.length}`);
|
|
41
|
+
}
|
|
42
|
+
if (diff.successors) {
|
|
43
|
+
out('');
|
|
44
|
+
out(diff.successors.length === 0
|
|
45
|
+
? ' Successor claims: none'
|
|
46
|
+
: ` Successor claims: ${diff.successors.length} (suggestions — review before accepting)`);
|
|
47
|
+
}
|
|
48
|
+
if (report.identityIn) {
|
|
49
|
+
out('');
|
|
50
|
+
out(` Identity map in: ${report.identityIn}`);
|
|
51
|
+
out(` applied: ${report.appliedCount}, ignored: ${report.ignoredCount}`);
|
|
52
|
+
}
|
|
53
|
+
if (report.written) {
|
|
54
|
+
out('');
|
|
55
|
+
out(` Identity map out: ${report.written.path} (${report.written.entries.length} claims)`);
|
|
56
|
+
}
|
|
57
|
+
if (report.lineageIn) {
|
|
58
|
+
out('');
|
|
59
|
+
out(` Lineage in: ${report.lineageIn}`);
|
|
60
|
+
}
|
|
61
|
+
if (report.lineageWritten) {
|
|
62
|
+
out('');
|
|
63
|
+
out(` Lineage out: ${report.lineageWritten.path} (${report.lineageWritten.entries.length} entries)`);
|
|
64
|
+
}
|
|
65
|
+
out('');
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=diff-content-report.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff-content-report.js","sourceRoot":"","sources":["../../src/commands/diff-content-report.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,6 +5,25 @@ export interface ContentDiffOptions {
|
|
|
5
5
|
identityIn?: string;
|
|
6
6
|
/** `--identity-out`: where to write the sidecar this run establishes. */
|
|
7
7
|
identityOut?: string;
|
|
8
|
+
/** `--lineage-in`: a lineage whose 1:1 entries are replayed as key aliases. */
|
|
9
|
+
lineageIn?: string;
|
|
10
|
+
/** `--lineage-out`: where to write the lineage this run establishes. */
|
|
11
|
+
lineageOut?: string;
|
|
12
|
+
/** `--accept`: a reviewed identity map folded into the lineage as `replaced`. */
|
|
13
|
+
accept?: string;
|
|
14
|
+
/** `--key-from`: `Tag` or `Pset.Prop`, the authored key to compare on. */
|
|
15
|
+
keyFrom?: string;
|
|
16
|
+
/** `--geometry`: run the wasm mesh pass and attach world geometry hashes,
|
|
17
|
+
* boxes and volumes, promoting the comparison from `data` to `both`
|
|
18
|
+
* scope (issue #4956). Skips with a stderr warning, not a fatal error,
|
|
19
|
+
* when the wasm runtime is not built on this host. */
|
|
20
|
+
geometry?: boolean;
|
|
21
|
+
/** `--split-merge`: opt in to the split/merge detector. Only produces
|
|
22
|
+
* claims together with `--geometry` (issue #4956). */
|
|
23
|
+
splitMerge?: boolean;
|
|
24
|
+
/** `--successors`: opt in to the successor-match detector. Only produces
|
|
25
|
+
* claims together with `--geometry` (issue #4956). */
|
|
26
|
+
successors?: boolean;
|
|
8
27
|
json: boolean;
|
|
9
28
|
}
|
|
10
29
|
export declare function contentDiffCommand(options: ContentDiffOptions): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diff-content.d.ts","sourceRoot":"","sources":["../../src/commands/diff-content.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"diff-content.d.ts","sourceRoot":"","sources":["../../src/commands/diff-content.ts"],"names":[],"mappings":"AA6DA,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,2DAA2D;IAC3D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yEAAyE;IACzE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+EAA+E;IAC/E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wEAAwE;IACxE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iFAAiF;IACjF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0EAA0E;IAC1E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;2DAGuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;2DACuD;IACvD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;2DACuD;IACvD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,IAAI,EAAE,OAAO,CAAC;CACf;AAED,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CA8LnF"}
|
|
@@ -8,37 +8,99 @@
|
|
|
8
8
|
* The loop this closes: run it once, review the `renamed` matches, keep the
|
|
9
9
|
* sidecar. On the next run the accepted claims come back in as key aliases, the
|
|
10
10
|
* re-GUIDed elements are matched by key, and they never show up as churn again.
|
|
11
|
-
*
|
|
11
|
+
* Data scope by default — see `diff-engine.ts`; `--geometry` below opts into
|
|
12
|
+
* the wasm mesh pass.
|
|
13
|
+
*
|
|
14
|
+
* Issue #4955 adds three things on the same loop: `--key-from` keys the
|
|
15
|
+
* comparison on an authored identifier instead of GlobalId; `--lineage-out` /
|
|
16
|
+
* `--lineage-in` write and replay the 1:k lineage an external table rekeys on;
|
|
17
|
+
* and `--accept` folds a reviewed identity map (a human's answer to the
|
|
18
|
+
* suggestions a geometry-capable run produced) into that lineage as
|
|
19
|
+
* `replaced` entries.
|
|
20
|
+
*
|
|
21
|
+
* Issue #4956 adds `--geometry`: a lazily-loaded `@ifc-lite/wasm` mesh pass
|
|
22
|
+
* (`diff-geometry.ts`) that attaches world geometry hashes, bounding boxes and
|
|
23
|
+
* volumes to both files' fingerprints, promoting the scope from `data` to
|
|
24
|
+
* `both`. `--split-merge` / `--successors` turn on the two geometry-only
|
|
25
|
+
* detection stages; both are no-ops without `--geometry` (the engine abstains
|
|
26
|
+
* exactly as it does for a viewer session whose geometry hashing failed).
|
|
12
27
|
*/
|
|
13
|
-
import { readFile,
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
28
|
+
import { readFile, writeFile } from 'node:fs/promises';
|
|
29
|
+
import { createIdentityMapSidecar, createLineageSidecar, diffModels, identityMapFromContentMatches, identityMapSidecarMismatches, keyAliasesFromLineage, keyAliasesFromSidecar, parseIdentityMapSidecar, serializeIdentityMapSidecar, serializeLineageSidecar, } from '@ifc-lite/diff';
|
|
30
|
+
import { parseAuthoredKeySpec } from '@ifc-lite/parser';
|
|
16
31
|
import { loadIfcBytes } from '../loader.js';
|
|
17
32
|
import { fatal, printJson } from '../output.js';
|
|
18
|
-
import { buildFileFingerprints, modelIdentityOf } from './diff-engine.js';
|
|
33
|
+
import { buildFileFingerprints, fallbackPairDuplicateAuthoredKeys, modelIdentityOf, } from './diff-engine.js';
|
|
34
|
+
import { readModel, refuseOverwritingAnInput, unwrapModel } from './diff-content-io.js';
|
|
35
|
+
import { resolveGeometryScope } from './diff-geometry.js';
|
|
36
|
+
import { mergeAliases, mergeLineage, readVerifiedLineage } from './diff-lineage-io.js';
|
|
37
|
+
import { printReport } from './diff-content-report.js';
|
|
19
38
|
export async function contentDiffCommand(options) {
|
|
20
39
|
const { basePath, headPath } = options;
|
|
40
|
+
const keySpec = options.keyFrom === undefined ? undefined : parseAuthoredKeySpec(options.keyFrom);
|
|
41
|
+
if (options.keyFrom !== undefined && !keySpec) {
|
|
42
|
+
fatal(`--key-from must be Tag or <PsetName>.<PropertyName>, got "${options.keyFrom}"`);
|
|
43
|
+
}
|
|
44
|
+
// `Tag` is case-insensitive at the CLI boundary, but the persisted sidecar
|
|
45
|
+
// contract is canonical and shared with the viewer's compare UI.
|
|
46
|
+
const keyProperty = keySpec?.kind === 'tag' ? 'Tag' : options.keyFrom?.trim();
|
|
21
47
|
// Before anything is read, and long before anything is written.
|
|
22
48
|
await refuseOverwritingAnInput(options);
|
|
23
49
|
const baseBytes = await readModel(basePath);
|
|
24
50
|
const headBytes = await readModel(headPath);
|
|
51
|
+
// The identity hash is over the file AS IT SITS ON DISK, before any
|
|
52
|
+
// `.ifcZIP` unwrapping (see `modelIdentityOf`) — so it is taken from the raw
|
|
53
|
+
// bytes, and the unwrap below is a separate step, not folded into this read.
|
|
25
54
|
const baseIdentity = modelIdentityOf(basePath, baseBytes);
|
|
26
55
|
const headIdentity = modelIdentityOf(headPath, headBytes);
|
|
56
|
+
const pinned = { base: baseIdentity, head: headIdentity, keyProperty };
|
|
27
57
|
const incoming = options.identityIn
|
|
28
|
-
? await readVerifiedSidecar(options.identityIn,
|
|
58
|
+
? await readVerifiedSidecar(options.identityIn, pinned)
|
|
29
59
|
: undefined;
|
|
60
|
+
const incomingLineage = options.lineageIn
|
|
61
|
+
? await readVerifiedLineage(options.lineageIn, pinned)
|
|
62
|
+
: undefined;
|
|
63
|
+
const accepted = options.accept ? await readVerifiedSidecar(options.accept, pinned) : undefined;
|
|
64
|
+
// Unwrapped ONCE and reused by both the parser and (if `--geometry` runs)
|
|
65
|
+
// the wasm mesh pass — `unwrapIfcZipView` is a cheap magic-byte no-op for an
|
|
66
|
+
// ordinary `.ifc` file, so a `--geometry` run over a `.ifcZIP` still sees the
|
|
67
|
+
// real STEP bytes rather than the zip container (issue #4956 review).
|
|
68
|
+
const baseUnwrapped = await unwrapModel(baseBytes, basePath);
|
|
69
|
+
const headUnwrapped = await unwrapModel(headBytes, headPath);
|
|
30
70
|
process.stderr.write('Loading files...\n');
|
|
31
|
-
const baseStore = await loadIfcBytes(
|
|
32
|
-
const headStore = await loadIfcBytes(
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
71
|
+
const baseStore = await loadIfcBytes(baseUnwrapped, basePath);
|
|
72
|
+
const headStore = await loadIfcBytes(headUnwrapped, headPath);
|
|
73
|
+
const duplicateAuthoredKeys = new Map();
|
|
74
|
+
const adapter = { keyProperty, duplicateAuthoredKeys };
|
|
75
|
+
const baseFingerprints = buildFileFingerprints(baseStore, adapter);
|
|
76
|
+
const headFingerprints = buildFileFingerprints(headStore, adapter);
|
|
77
|
+
fallbackPairDuplicateAuthoredKeys([
|
|
78
|
+
{ fingerprints: baseFingerprints, store: baseStore },
|
|
79
|
+
{ fingerprints: headFingerprints, store: headStore },
|
|
80
|
+
], duplicateAuthoredKeys);
|
|
81
|
+
for (const [value, ids] of duplicateAuthoredKeys) {
|
|
82
|
+
process.stderr.write(`Warning: ${keyProperty} = "${value}" names ${ids.length} entities; they fall back to GlobalId.\n`);
|
|
83
|
+
}
|
|
84
|
+
// Both sources of aliases are replayed together. A lineage's 1:1 entries and
|
|
85
|
+
// an identity map's claims are the same kind of thing under two file formats;
|
|
86
|
+
// where the two disagree about one head key, neither is applied — that is
|
|
87
|
+
// `resolveKeyAliases` rule 4, arriving from two files instead of one.
|
|
88
|
+
const aliases = mergeAliases(incoming ? keyAliasesFromSidecar(incoming) : undefined, incomingLineage ? keyAliasesFromLineage(incomingLineage.entries) : undefined);
|
|
89
|
+
// `--geometry` (issue #4956): see `diff-geometry.ts` for the wasm pass and
|
|
90
|
+
// the graceful fall-back to `scope: 'data'` when the runtime is absent.
|
|
91
|
+
const scope = await resolveGeometryScope(options.geometry ?? false, baseUnwrapped, headUnwrapped, baseFingerprints, headFingerprints, (message) => process.stderr.write(`Warning: ${message}\n`));
|
|
92
|
+
const diff = diffModels(baseFingerprints, headFingerprints, {
|
|
93
|
+
scope,
|
|
37
94
|
matchUnpairedByContent: true,
|
|
38
|
-
keyAliases:
|
|
95
|
+
keyAliases: aliases,
|
|
96
|
+
// Both are geometry-only stages (issue #4956): with no geometry pass run,
|
|
97
|
+
// the engine abstains and `diff.splitMerges` / `diff.successors` stay
|
|
98
|
+
// undefined, exactly as a viewer session with failed geometry hashing.
|
|
99
|
+
detectSplitMerge: options.splitMerge,
|
|
100
|
+
detectSuccessors: options.successors,
|
|
39
101
|
});
|
|
40
102
|
const applied = diff.appliedKeyAliases ?? new Map();
|
|
41
|
-
const ignored =
|
|
103
|
+
const ignored = aliases ? aliases.size - applied.size : 0;
|
|
42
104
|
let written;
|
|
43
105
|
if (options.identityOut) {
|
|
44
106
|
const entries = mergeIdentityClaims(incoming, applied, diff.contentMatches);
|
|
@@ -59,10 +121,25 @@ export async function contentDiffCommand(options) {
|
|
|
59
121
|
// optional, and `git log` dates a reviewed, committed artifact better
|
|
60
122
|
// than a self-reported timestamp does.
|
|
61
123
|
created: incoming?.created,
|
|
124
|
+
keyProperty,
|
|
62
125
|
});
|
|
63
126
|
await writeFile(options.identityOut, serializeIdentityMapSidecar(sidecar), 'utf-8');
|
|
64
127
|
written = { path: options.identityOut, entries: sidecar.entries };
|
|
65
128
|
}
|
|
129
|
+
let lineageWritten;
|
|
130
|
+
if (options.lineageOut) {
|
|
131
|
+
const { entries, deleted } = mergeLineage(incomingLineage, incoming, diff, accepted);
|
|
132
|
+
const sidecar = createLineageSidecar({
|
|
133
|
+
base: baseIdentity,
|
|
134
|
+
head: headIdentity,
|
|
135
|
+
entries,
|
|
136
|
+
deleted,
|
|
137
|
+
created: incomingLineage?.created,
|
|
138
|
+
keyProperty,
|
|
139
|
+
});
|
|
140
|
+
await writeFile(options.lineageOut, serializeLineageSidecar(sidecar), 'utf-8');
|
|
141
|
+
lineageWritten = { path: options.lineageOut, entries: sidecar.entries };
|
|
142
|
+
}
|
|
66
143
|
if (options.json) {
|
|
67
144
|
printJson({
|
|
68
145
|
base: { path: basePath, hash: baseIdentity.hash, schema: baseStore.schemaVersion },
|
|
@@ -74,12 +151,36 @@ export async function contentDiffCommand(options) {
|
|
|
74
151
|
base: match.base.map((entity) => entity.key),
|
|
75
152
|
head: match.head.map((entity) => entity.key),
|
|
76
153
|
})),
|
|
154
|
+
// Absent (not `[]`) exactly when the stage did not run or the geometry
|
|
155
|
+
// abstention fired — the engine's own "absent means not proved"
|
|
156
|
+
// contract, preserved rather than flattened to an empty array.
|
|
157
|
+
splitMerges: diff.splitMerges?.map((claim) => ({
|
|
158
|
+
kind: claim.kind,
|
|
159
|
+
confidence: claim.confidence,
|
|
160
|
+
whole: claim.whole.key,
|
|
161
|
+
pieces: claim.pieces.map((piece) => piece.key),
|
|
162
|
+
})),
|
|
163
|
+
successors: diff.successors?.map((claim) => ({
|
|
164
|
+
confidence: claim.confidence,
|
|
165
|
+
base: claim.base.key,
|
|
166
|
+
head: claim.head.key,
|
|
167
|
+
overlap: claim.overlap,
|
|
168
|
+
distance: claim.distance,
|
|
169
|
+
})),
|
|
77
170
|
identityMap: {
|
|
78
171
|
in: options.identityIn
|
|
79
172
|
? { path: options.identityIn, applied: applied.size, ignored }
|
|
80
173
|
: undefined,
|
|
81
174
|
out: written ? { path: written.path, entries: written.entries.length } : undefined,
|
|
82
175
|
},
|
|
176
|
+
lineage: {
|
|
177
|
+
in: options.lineageIn ? { path: options.lineageIn } : undefined,
|
|
178
|
+
out: lineageWritten
|
|
179
|
+
? { path: lineageWritten.path, entries: lineageWritten.entries.length }
|
|
180
|
+
: undefined,
|
|
181
|
+
},
|
|
182
|
+
keyProperty: keyProperty ?? null,
|
|
183
|
+
duplicateAuthoredKeys: [...duplicateAuthoredKeys.keys()],
|
|
83
184
|
});
|
|
84
185
|
return;
|
|
85
186
|
}
|
|
@@ -91,75 +192,11 @@ export async function contentDiffCommand(options) {
|
|
|
91
192
|
ignoredCount: ignored,
|
|
92
193
|
identityIn: options.identityIn,
|
|
93
194
|
written,
|
|
195
|
+
lineageIn: options.lineageIn,
|
|
196
|
+
lineageWritten,
|
|
197
|
+
keyProperty,
|
|
94
198
|
});
|
|
95
199
|
}
|
|
96
|
-
/**
|
|
97
|
-
* Refuse to run at all if `--identity-out` names one of the two input models.
|
|
98
|
-
*
|
|
99
|
-
* The sidecar is a JSON document. Writing it over an IFC file destroys the
|
|
100
|
-
* user's model, and a mistyped or shell-completed path is all it takes — the
|
|
101
|
-
* two arguments right before it are IFC paths. So this is checked first, and
|
|
102
|
-
* the command exits without reading, comparing, or writing anything.
|
|
103
|
-
*
|
|
104
|
-
* Two independent tests, because a path string is not a file:
|
|
105
|
-
*
|
|
106
|
-
* 1. Resolved paths are equal. Catches `./v1.ifc` vs `v1.ifc` vs `sub/../v1.ifc`
|
|
107
|
-
* with no filesystem access, and is the whole answer on a platform where
|
|
108
|
-
* `stat` reports no usable inode.
|
|
109
|
-
* 2. The output already exists AND is the same file as an input, by device +
|
|
110
|
-
* inode. This is the exhaustive test: it catches a symlink, a hard link, a
|
|
111
|
-
* bind mount, and `V1.IFC` on a case-insensitive filesystem — every way two
|
|
112
|
-
* different strings can name one file. It is also sufficient on its own for
|
|
113
|
-
* the destructive case, because a path that does not resolve to an existing
|
|
114
|
-
* file cannot be overwriting an input: the inputs must exist to be read.
|
|
115
|
-
*
|
|
116
|
-
* `--identity-in` and `--identity-out` naming the SAME sidecar is not checked
|
|
117
|
-
* here, because that is the carry-forward workflow this feature is built around
|
|
118
|
-
* (read the accepted claims, write back the ones that still held).
|
|
119
|
-
*/
|
|
120
|
-
async function refuseOverwritingAnInput(options) {
|
|
121
|
-
const { identityOut } = options;
|
|
122
|
-
if (identityOut === undefined)
|
|
123
|
-
return;
|
|
124
|
-
const out = resolve(identityOut);
|
|
125
|
-
const outStat = await statOrUndefined(identityOut);
|
|
126
|
-
for (const [label, input] of [
|
|
127
|
-
['base model', options.basePath],
|
|
128
|
-
['head model', options.headPath],
|
|
129
|
-
]) {
|
|
130
|
-
if (resolve(input) !== out && !isSameFile(outStat, await statOrUndefined(input)))
|
|
131
|
-
continue;
|
|
132
|
-
fatal(`--identity-out ${identityOut} is the ${label} (${input}). ` +
|
|
133
|
-
'Writing the identity map there would overwrite the input file.');
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
async function statOrUndefined(path) {
|
|
137
|
-
// A missing or unreadable path cannot be an input file being overwritten;
|
|
138
|
-
// reading the models is what reports it, with its own message.
|
|
139
|
-
try {
|
|
140
|
-
return await stat(path);
|
|
141
|
-
}
|
|
142
|
-
catch {
|
|
143
|
-
return undefined;
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
function isSameFile(a, b) {
|
|
147
|
-
return a !== undefined && b !== undefined && a.dev === b.dev && a.ino === b.ino;
|
|
148
|
-
}
|
|
149
|
-
/**
|
|
150
|
-
* Read one of the two input models, reporting a missing or unreadable path the
|
|
151
|
-
* way the rest of the command reports problems rather than throwing a raw
|
|
152
|
-
* `ENOENT` stack at the user — the same treatment `readVerifiedSidecar` already
|
|
153
|
-
* gives the sidecar.
|
|
154
|
-
*/
|
|
155
|
-
async function readModel(path) {
|
|
156
|
-
try {
|
|
157
|
-
return await readFile(path);
|
|
158
|
-
}
|
|
159
|
-
catch (error) {
|
|
160
|
-
return fatal(`Cannot read ${path}: ${error.message}`);
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
200
|
/**
|
|
164
201
|
* Read a sidecar and refuse it unless it was verified against exactly these two
|
|
165
202
|
* files.
|
|
@@ -171,7 +208,7 @@ async function readModel(path) {
|
|
|
171
208
|
* deliberately no override flag: the fix for a mismatch is to re-run the
|
|
172
209
|
* comparison that produced the claims, which is one command.
|
|
173
210
|
*/
|
|
174
|
-
async function readVerifiedSidecar(path,
|
|
211
|
+
async function readVerifiedSidecar(path, models) {
|
|
175
212
|
let text;
|
|
176
213
|
try {
|
|
177
214
|
text = await readFile(path, 'utf-8');
|
|
@@ -186,18 +223,12 @@ async function readVerifiedSidecar(path, base, head) {
|
|
|
186
223
|
catch (error) {
|
|
187
224
|
return fatal(error.message);
|
|
188
225
|
}
|
|
189
|
-
const problems = identityMapSidecarMismatches(sidecar,
|
|
226
|
+
const problems = identityMapSidecarMismatches(sidecar, models);
|
|
190
227
|
if (problems.length > 0) {
|
|
191
228
|
return fatal(`Identity map ${path} was not verified against these files:\n ${problems.join('\n ')}`);
|
|
192
229
|
}
|
|
193
230
|
return sidecar;
|
|
194
231
|
}
|
|
195
|
-
/** Distinct head keys a sidecar actually claims (self-claims and repeats are
|
|
196
|
-
* no-ops the consumer drops, so counting raw entries would overstate what
|
|
197
|
-
* could have applied). */
|
|
198
|
-
function countClaims(sidecar) {
|
|
199
|
-
return keyAliasesFromSidecar(sidecar).size;
|
|
200
|
-
}
|
|
201
232
|
/**
|
|
202
233
|
* The claims the output sidecar should carry: the incoming ones that still
|
|
203
234
|
* applied, plus the ones this run's content matching established.
|
|
@@ -227,44 +258,4 @@ function mergeIdentityClaims(incoming, applied, matches) {
|
|
|
227
258
|
entries.push(...identityMapFromContentMatches(matches));
|
|
228
259
|
return entries;
|
|
229
260
|
}
|
|
230
|
-
function printReport(report) {
|
|
231
|
-
const { diff } = report;
|
|
232
|
-
const out = (line) => {
|
|
233
|
-
process.stdout.write(`${line}\n`);
|
|
234
|
-
};
|
|
235
|
-
out('');
|
|
236
|
-
out(` Base: ${report.basePath}`);
|
|
237
|
-
out(` Head: ${report.headPath}`);
|
|
238
|
-
out(` Scope: data (the CLI has no geometry pipeline)`);
|
|
239
|
-
out('');
|
|
240
|
-
out(` Unchanged: ${diff.counts.unchanged}`);
|
|
241
|
-
out(` Modified: ${diff.counts.modified}`);
|
|
242
|
-
out(` Added: ${diff.counts.added}`);
|
|
243
|
-
out(` Deleted: ${diff.counts.deleted}`);
|
|
244
|
-
const byKind = new Map();
|
|
245
|
-
for (const match of diff.contentMatches ?? []) {
|
|
246
|
-
byKind.set(match.kind, (byKind.get(match.kind) ?? 0) + 1);
|
|
247
|
-
}
|
|
248
|
-
out('');
|
|
249
|
-
if (byKind.size === 0) {
|
|
250
|
-
out(' Content matches: none');
|
|
251
|
-
}
|
|
252
|
-
else {
|
|
253
|
-
out(' Content matches:');
|
|
254
|
-
for (const [kind, count] of [...byKind].sort()) {
|
|
255
|
-
out(` ${kind.padEnd(13)} ${count}`);
|
|
256
|
-
}
|
|
257
|
-
out(' (renamed / moved / reshaped are resolved; the rest need a human)');
|
|
258
|
-
}
|
|
259
|
-
if (report.identityIn) {
|
|
260
|
-
out('');
|
|
261
|
-
out(` Identity map in: ${report.identityIn}`);
|
|
262
|
-
out(` applied: ${report.appliedCount}, ignored: ${report.ignoredCount}`);
|
|
263
|
-
}
|
|
264
|
-
if (report.written) {
|
|
265
|
-
out('');
|
|
266
|
-
out(` Identity map out: ${report.written.path} (${report.written.entries.length} claims)`);
|
|
267
|
-
}
|
|
268
|
-
out('');
|
|
269
|
-
}
|
|
270
261
|
//# sourceMappingURL=diff-content.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diff-content.js","sourceRoot":"","sources":["../../src/commands/diff-content.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D
|
|
1
|
+
{"version":3,"file":"diff-content.js","sourceRoot":"","sources":["../../src/commands/diff-content.ts"],"names":[],"mappings":"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"}
|
|
@@ -19,5 +19,36 @@ export declare function modelIdentityOf(path: string, bytes: Uint8Array): ModelI
|
|
|
19
19
|
* check is inert unless both sides supply them (see the "Hash collisions"
|
|
20
20
|
* section of `docs/guide/model-diff.md`).
|
|
21
21
|
*/
|
|
22
|
-
|
|
22
|
+
/** Adapter options shared by the CLI and MCP fingerprint builders (issue #4955). */
|
|
23
|
+
export interface FingerprintAdapterOptions {
|
|
24
|
+
/**
|
|
25
|
+
* An authored key to use as the cross-revision identity instead of GlobalId:
|
|
26
|
+
* `Tag`, or `<PsetName>.<PropertyName>`. An entity carrying a non-empty value
|
|
27
|
+
* is keyed `prop:<value>`; one without falls back to its GlobalId. Two
|
|
28
|
+
* entities sharing one authored value collapse under the diff's first-wins
|
|
29
|
+
* key index, so they are reported on `duplicateAuthoredKeys` and fall back
|
|
30
|
+
* to GlobalId too — a key that names two things is not a key.
|
|
31
|
+
*/
|
|
32
|
+
keyProperty?: string;
|
|
33
|
+
/** Receives every authored value more than one entity carried. */
|
|
34
|
+
duplicateAuthoredKeys?: Map<string, number[]>;
|
|
35
|
+
}
|
|
36
|
+
/** Prefix on a fingerprint key taken from an authored property rather than a GlobalId. */
|
|
37
|
+
export declare const AUTHORED_KEY_PREFIX = "prop:";
|
|
38
|
+
/**
|
|
39
|
+
* Resolve every entity's key under an authored-key spec: `prop:<value>` where
|
|
40
|
+
* the value is present and unique, GlobalId otherwise. Duplicates are reported
|
|
41
|
+
* to the caller rather than silently collapsed by `indexByKey`.
|
|
42
|
+
*/
|
|
43
|
+
export declare function resolveAuthoredKeys(store: IfcDataStore, entities: readonly {
|
|
44
|
+
expressId: number;
|
|
45
|
+
globalId: string;
|
|
46
|
+
}[], options: FingerprintAdapterOptions): Map<number, string>;
|
|
47
|
+
export declare function buildFileFingerprints(store: IfcDataStore, options?: FingerprintAdapterOptions): EntityFingerprint<DiffRef>[];
|
|
48
|
+
/** A collision discovered in either file invalidates that authored value in
|
|
49
|
+
* both files, including fingerprints already built for the first side. */
|
|
50
|
+
export declare function fallbackPairDuplicateAuthoredKeys(sides: readonly {
|
|
51
|
+
fingerprints: EntityFingerprint<DiffRef>[];
|
|
52
|
+
store: IfcDataStore;
|
|
53
|
+
}[], duplicates: ReadonlyMap<string, number[]>): void;
|
|
23
54
|
//# sourceMappingURL=diff-engine.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diff-engine.d.ts","sourceRoot":"","sources":["../../src/commands/diff-engine.ts"],"names":[],"mappings":"AA8BA,OAAO,EAIL,KAAK,iBAAiB,EACtB,KAAK,aAAa,EACnB,MAAM,gBAAgB,CAAC;AAExB,OAAO,
|
|
1
|
+
{"version":3,"file":"diff-engine.d.ts","sourceRoot":"","sources":["../../src/commands/diff-engine.ts"],"names":[],"mappings":"AA8BA,OAAO,EAIL,KAAK,iBAAiB,EACtB,KAAK,aAAa,EACnB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAcL,KAAK,YAAY,EAElB,MAAM,kBAAkB,CAAC;AAI1B,yEAAyE;AACzE,MAAM,MAAM,OAAO,GAAG,MAAM,CAAC;AAE7B;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,aAAa,CAG9E;AAED;;;;;;;;GAQG;AACH,oFAAoF;AACpF,MAAM,WAAW,yBAAyB;IACxC;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kEAAkE;IAClE,qBAAqB,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CAC/C;AAED,0FAA0F;AAC1F,eAAO,MAAM,mBAAmB,UAAU,CAAC;AAE3C;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,YAAY,EACnB,QAAQ,EAAE,SAAS;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,EAAE,EAC5D,OAAO,EAAE,yBAAyB,GACjC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAyBrB;AAED,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,YAAY,EACnB,OAAO,GAAE,yBAA8B,GACtC,iBAAiB,CAAC,OAAO,CAAC,EAAE,CA8B9B;AAED;0EAC0E;AAC1E,wBAAgB,iCAAiC,CAC/C,KAAK,EAAE,SAAS;IACd,YAAY,EAAE,iBAAiB,CAAC,OAAO,CAAC,EAAE,CAAC;IAC3C,KAAK,EAAE,YAAY,CAAC;CACrB,EAAE,EACH,UAAU,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GACxC,IAAI,CAiBN"}
|