Files
Web_FreeCAD_Bitbybit/scripts/generate-freecad-property-area-inventory.mjs
wangdequan d11566403d
Some checks failed
real-verification / chrome (push) Has been cancelled
real-verification / freecad-oracle (push) Has been cancelled
real-verification / wasm (push) Has been cancelled
feat: close ordered pairs and property codec batches
2026-08-17 04:58:46 -04:00

63 lines
3.7 KiB
JavaScript

import { createHash } from 'node:crypto'
import { readFile, writeFile } from 'node:fs/promises'
import { resolve } from 'node:path'
const root = resolve(new URL('..', import.meta.url).pathname)
const runtimePath = resolve(root, '.cache/freecad/reference-desktop.json')
const sourcePaths = [
'.cache/freecad/FreeCAD/src/Mod/Measure/App/MeasureArea.cpp',
'.cache/freecad/FreeCAD/src/Mod/Measure/App/MeasureArea.h',
]
const outputPath = resolve(root, 'config/freecad-property-area-inventory.json')
const runtimeContent = await readFile(runtimePath)
const runtime = JSON.parse(runtimeContent)
const sourceContents = await Promise.all(sourcePaths.map((path) => readFile(resolve(root, path))))
const fail = (message) => { throw new Error(`FreeCAD PropertyArea inventory generation failed: ${message}`) }
if (runtime.schemaVersion !== 1 || runtime.freecadVersion !== '1.1.1' || runtime.gitCommit !== '0108fd4b4850cc46e625b60e53cea7a7bbe69f8d') fail('desktop oracle is not the locked FreeCAD baseline')
const records = []
for (const objectType of runtime.runtimeObjects?.types ?? []) {
for (const property of objectType.properties ?? []) {
if (property.typeId !== 'App::PropertyArea') continue
const input = objectType.properties.find((candidate) => candidate.name === 'Elements')
records.push({
objectTypeId: objectType.typeId,
objectAvailable: objectType.available === true,
probeStatus: objectType.probeStatus,
propertyName: property.name,
group: property.group,
status: property.status,
normalizedStatus: property.status.map((entry) => entry === 24 ? 'PropReadOnly' : entry === 27 ? 'PropOutput' : String(entry)),
defaultRaw: property.default,
valueModel: { kind: 'quantity', dimension: 'length^2', defaultValue: 0, defaultUnit: 'mm^2', derived: true, writable: false },
inputs: [{ propertyName: input?.name, typeId: input?.typeId, group: input?.group, defaultValue: input?.default, scope: 'Global', allowExternal: true, cardinality: 'one-or-more' }],
dependencies: [{ sourceProperty: 'Elements', targetProperty: 'Area', relation: 'link-sub-list', effect: 'immediate-recompute-on-change' }],
applicability: {
selectionMustBeNonEmpty: true,
everyElementMustBeValid: true,
supportedMeasureElementTypes: ['PLANE', 'CYLINDER', 'SURFACE', 'VOLUME'],
unsupportedMeasureElementTypes: ['INVALID', 'POINT', 'LINE', 'CURVE'],
externalDocumentElementsAllowed: true,
},
execution: { aggregation: 'sum-area', resultProperty: 'Area', invalidGeometryDiagnostic: 'Cannot calculate area', shape: 'not-applicable-derived-measurement' },
})
}
}
if (records.length !== 1) fail(`expected one native App::PropertyArea record, found ${records.length}`)
const report = {
schemaVersion: 1,
status: 'pass',
baseline: { freecadVersion: runtime.freecadVersion, commit: runtime.gitCommit },
propertyType: 'App::PropertyArea',
recordCount: records.length,
records,
provenance: {
runtime: { path: '.cache/freecad/reference-desktop.json', bytes: runtimeContent.length, sha256: createHash('sha256').update(runtimeContent).digest('hex') },
sources: sourcePaths.map((path, index) => ({ path, bytes: sourceContents[index].length, sha256: createHash('sha256').update(sourceContents[index]).digest('hex') })),
},
classification: 'opaque-fcstd-proxy',
nextPhases: ['B', 'C', 'D', 'E', 'F', 'G', 'H', 'I'],
}
await writeFile(outputPath, `${JSON.stringify(report, null, 2)}\n`)
console.log(JSON.stringify({ status: 'freecad-property-area-inventory-generated', output: 'config/freecad-property-area-inventory.json', propertyType: report.propertyType, recordCount: report.recordCount, objectTypeId: records[0].objectTypeId }, null, 2))