P7/P8: add topology proxies and recovery reports
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { unzipSync } from 'fflate'
|
||||
import { XMLParser } from 'fast-xml-parser'
|
||||
import type { DocumentSnapshot, DocumentObjectSnapshot, ModelTreeItem, ObjectPropertySnapshot } from './types'
|
||||
|
||||
export type FcstdArchiveLimits = {
|
||||
maxArchiveBytes: number
|
||||
@@ -47,6 +48,7 @@ export type FcstdInspection = {
|
||||
entries: FcstdEntryMetadata[]
|
||||
objects: FcstdObjectSummary[]
|
||||
compatibility: FcstdCompatibilityReport
|
||||
proxyDocument: DocumentSnapshot
|
||||
}
|
||||
|
||||
export const DEFAULT_FCSTD_LIMITS: FcstdArchiveLimits = {
|
||||
@@ -72,6 +74,12 @@ const recognizedTypeIds = new Set([
|
||||
'Sketcher::SketchObject',
|
||||
])
|
||||
|
||||
const hashString = (value: string) => {
|
||||
let hash = 2166136261
|
||||
for (let index = 0; index < value.length; index += 1) hash = Math.imul(hash ^ value.charCodeAt(index), 16777619)
|
||||
return (hash >>> 0).toString(16).padStart(8, '0')
|
||||
}
|
||||
|
||||
const blockedTypeId = (typeId: string) => /(?:FeaturePython|PythonFeature|::Python)/i.test(typeId)
|
||||
|
||||
const entryRole = (path: string): FcstdEntryRole => {
|
||||
@@ -203,6 +211,15 @@ const parseDocumentXml = (bytes: Uint8Array) => {
|
||||
}
|
||||
}
|
||||
|
||||
const createProxyProperty = (name: string, label: string, value: string): ObjectPropertySnapshot => ({ name, label, group: 'FCStd import', scope: 'data', type: 'App::PropertyString', value, readOnly: true })
|
||||
|
||||
const createProxyDocument = (inspection: Omit<FcstdInspection, 'proxyDocument'>): DocumentSnapshot => {
|
||||
const documentId = `fcstd-${hashString(`${inspection.label}|${inspection.schemaVersion}|${inspection.objects.map((object) => object.name).join('|')}`)}`
|
||||
const tree: ModelTreeItem[] = inspection.objects.map((object) => ({ id: object.name, label: object.label, type: object.typeId.includes('Body') ? 'body' : object.typeId.includes('Sketch') ? 'sketch' : 'feature', state: 'readonly', detail: `${object.typeId} · ${object.support}` }))
|
||||
const objects: DocumentObjectSnapshot[] = inspection.objects.map((object) => ({ id: object.name, typeId: object.typeId, properties: [createProxyProperty('Label', 'Label', object.label), createProxyProperty('TypeId', 'Type', object.typeId), createProxyProperty('ImportSupport', 'Import support', object.support), createProxyProperty('PropertyCount', 'Property count', String(object.propertyCount))] }))
|
||||
return { id: documentId, label: inspection.label, version: 1, dirty: false, readOnly: true, units: 'mm', tree, objects, dependencies: [], recompute: { generation: 0, status: 'idle', objectStates: Object.fromEntries(objects.map((object) => [object.id, 'up-to-date'])), dirtyObjects: [], order: [], errors: [] } }
|
||||
}
|
||||
|
||||
export const inspectFcstdArchive = (bytes: Uint8Array, limitOverrides: Partial<FcstdArchiveLimits> = {}): FcstdInspection => {
|
||||
const limits = { ...DEFAULT_FCSTD_LIMITS, ...limitOverrides }
|
||||
for (const [name, value] of Object.entries(limits)) if (!Number.isSafeInteger(value) || value <= 0) throw new RangeError(`FCStd limit ${name} must be a positive safe integer.`)
|
||||
@@ -223,7 +240,7 @@ export const inspectFcstdArchive = (bytes: Uint8Array, limitOverrides: Partial<F
|
||||
const proxyObjects = document.objects.filter((object) => object.support === 'proxy')
|
||||
if (proxyObjects.length > 0) warnings.push(`${proxyObjects.length} unrecognized object type(s) require a read-only proxy.`)
|
||||
const level: FcstdCompatibilityReport['level'] = blockedObjects.length > 0 ? 'blocked' : proxyObjects.length > 0 || scriptEntries.length > 0 ? 'partial' : 'metadata-compatible'
|
||||
return {
|
||||
const inspection: Omit<FcstdInspection, 'proxyDocument'> = {
|
||||
format: 'FCStd',
|
||||
schemaVersion: document.schemaVersion,
|
||||
label: document.label,
|
||||
@@ -240,4 +257,5 @@ export const inspectFcstdArchive = (bytes: Uint8Array, limitOverrides: Partial<F
|
||||
warnings,
|
||||
},
|
||||
}
|
||||
return { ...inspection, proxyDocument: createProxyDocument(inspection) }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user