@ifc-lite/flow-nodes 0.2.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/LICENSE +373 -0
- package/README.md +34 -0
- package/dist/apply-table-node.d.ts +3 -0
- package/dist/apply-table-node.d.ts.map +1 -0
- package/dist/apply-table-node.js +119 -0
- package/dist/apply-table-node.js.map +1 -0
- package/dist/connector-nodes.d.ts +3 -0
- package/dist/connector-nodes.d.ts.map +1 -0
- package/dist/connector-nodes.js +192 -0
- package/dist/connector-nodes.js.map +1 -0
- package/dist/core-nodes.d.ts +3 -0
- package/dist/core-nodes.d.ts.map +1 -0
- package/dist/core-nodes.js +277 -0
- package/dist/core-nodes.js.map +1 -0
- package/dist/csv-nodes.d.ts +3 -0
- package/dist/csv-nodes.d.ts.map +1 -0
- package/dist/csv-nodes.js +111 -0
- package/dist/csv-nodes.js.map +1 -0
- package/dist/csv-parse.d.ts +26 -0
- package/dist/csv-parse.d.ts.map +1 -0
- package/dist/csv-parse.js +83 -0
- package/dist/csv-parse.js.map +1 -0
- package/dist/element-nodes.d.ts +36 -0
- package/dist/element-nodes.d.ts.map +1 -0
- package/dist/element-nodes.js +224 -0
- package/dist/element-nodes.js.map +1 -0
- package/dist/host.d.ts +107 -0
- package/dist/host.d.ts.map +1 -0
- package/dist/host.js +94 -0
- package/dist/host.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +50 -0
- package/dist/index.js.map +1 -0
- package/dist/model-nodes.d.ts +3 -0
- package/dist/model-nodes.d.ts.map +1 -0
- package/dist/model-nodes.js +200 -0
- package/dist/model-nodes.js.map +1 -0
- package/dist/script-node.d.ts +4 -0
- package/dist/script-node.d.ts.map +1 -0
- package/dist/script-node.js +140 -0
- package/dist/script-node.js.map +1 -0
- package/dist/strict-cell.d.ts +20 -0
- package/dist/strict-cell.d.ts.map +1 -0
- package/dist/strict-cell.js +33 -0
- package/dist/strict-cell.js.map +1 -0
- package/dist/table-nodes.d.ts +17 -0
- package/dist/table-nodes.d.ts.map +1 -0
- package/dist/table-nodes.js +200 -0
- package/dist/table-nodes.js.map +1 -0
- package/dist/viewer-nodes.d.ts +3 -0
- package/dist/viewer-nodes.d.ts.map +1 -0
- package/dist/viewer-nodes.js +93 -0
- package/dist/viewer-nodes.js.map +1 -0
- package/dist/write-nodes.d.ts +3 -0
- package/dist/write-nodes.d.ts.map +1 -0
- package/dist/write-nodes.js +63 -0
- package/dist/write-nodes.js.map +1 -0
- package/dist/xlsx-io.d.ts +24 -0
- package/dist/xlsx-io.d.ts.map +1 -0
- package/dist/xlsx-io.js +160 -0
- package/dist/xlsx-io.js.map +1 -0
- package/dist/xlsx-nodes.d.ts +3 -0
- package/dist/xlsx-nodes.d.ts.map +1 -0
- package/dist/xlsx-nodes.js +99 -0
- package/dist/xlsx-nodes.js.map +1 -0
- package/package.json +60 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
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
|
+
import { NodeRegistry } from '@ifc-lite/flow';
|
|
5
|
+
import { applyTableNode } from './apply-table-node.js';
|
|
6
|
+
import { connectorNodes } from './connector-nodes.js';
|
|
7
|
+
import { coreNodes } from './core-nodes.js';
|
|
8
|
+
import { csvNodes } from './csv-nodes.js';
|
|
9
|
+
import { elementNodes } from './element-nodes.js';
|
|
10
|
+
import { modelNodes } from './model-nodes.js';
|
|
11
|
+
import { scriptListNode, scriptNode } from './script-node.js';
|
|
12
|
+
import { tableNodes } from './table-nodes.js';
|
|
13
|
+
import { viewerNodes } from './viewer-nodes.js';
|
|
14
|
+
import { writeNodes } from './write-nodes.js';
|
|
15
|
+
import { xlsxNodes } from './xlsx-nodes.js';
|
|
16
|
+
export { requireCapability, toRef, toSdkRef, resolveByGlobalId, rememberGlobalId, forgetGlobalId, invalidateGlobalIdIndex } from './host.js';
|
|
17
|
+
export { columnTypeOf, VALUE_TYPE_BY_COLUMN_TYPE } from './table-nodes.js';
|
|
18
|
+
export { readXlsxTable, writeXlsxTable } from './xlsx-io.js';
|
|
19
|
+
/** Every standard node, in one registry. */
|
|
20
|
+
export function createStandardRegistry() {
|
|
21
|
+
return new NodeRegistry().registerAll([
|
|
22
|
+
...coreNodes,
|
|
23
|
+
...modelNodes,
|
|
24
|
+
...tableNodes,
|
|
25
|
+
...viewerNodes,
|
|
26
|
+
...writeNodes,
|
|
27
|
+
...elementNodes,
|
|
28
|
+
...csvNodes,
|
|
29
|
+
...xlsxNodes,
|
|
30
|
+
...connectorNodes,
|
|
31
|
+
applyTableNode,
|
|
32
|
+
scriptNode,
|
|
33
|
+
scriptListNode,
|
|
34
|
+
]);
|
|
35
|
+
}
|
|
36
|
+
/** What a viewer-embedded host offers. Secrets are never available in the browser. */
|
|
37
|
+
export const BROWSER_FEATURES = {
|
|
38
|
+
backend: new Set(['viewer', 'visibility', 'selection', 'mutate', 'store', 'files', 'sandbox']),
|
|
39
|
+
network: false,
|
|
40
|
+
secrets: new Set(),
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* What the CLI's `HeadlessBackend` offers. It implements the viewer
|
|
44
|
+
* methods as inert no-ops, so `viewer`/`visibility`/`selection` are
|
|
45
|
+
* deliberately absent here: a viewer node must report `noop`, not pretend.
|
|
46
|
+
*/
|
|
47
|
+
export function headlessFeatures(secrets = []) {
|
|
48
|
+
return { backend: new Set(['mutate', 'store', 'files', 'sandbox']), network: false, secrets: new Set(secrets) };
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D,OAAO,EAAE,YAAY,EAAqB,MAAM,gBAAgB,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAG5C,OAAO,EAAE,iBAAiB,EAAE,KAAK,EAAE,QAAQ,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,cAAc,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAC;AAC7I,OAAO,EAAE,YAAY,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAE3E,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAG7D,4CAA4C;AAC5C,MAAM,UAAU,sBAAsB;IACpC,OAAO,IAAI,YAAY,EAAY,CAAC,WAAW,CAAC;QAC9C,GAAG,SAAS;QACZ,GAAG,UAAU;QACb,GAAG,UAAU;QACb,GAAG,WAAW;QACd,GAAG,UAAU;QACb,GAAG,YAAY;QACf,GAAG,QAAQ;QACX,GAAG,SAAS;QACZ,GAAG,cAAc;QACjB,cAAc;QACd,UAAU;QACV,cAAc;KACf,CAAC,CAAC;AACL,CAAC;AAED,sFAAsF;AACtF,MAAM,CAAC,MAAM,gBAAgB,GAAiB;IAC5C,OAAO,EAAE,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;IAC9F,OAAO,EAAE,KAAK;IACd,OAAO,EAAE,IAAI,GAAG,EAAE;CACnB,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,UAA4B,EAAE;IAC7D,OAAO,EAAE,OAAO,EAAE,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;AAClH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-nodes.d.ts","sourceRoot":"","sources":["../src/model-nodes.ts"],"names":[],"mappings":"AAaA,OAAO,EAUL,KAAK,WAAW,EACjB,MAAM,WAAW,CAAC;AAanB,eAAO,MAAM,UAAU,EAAE,WAAW,EAwLnC,CAAC"}
|
|
@@ -0,0 +1,200 @@
|
|
|
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
|
+
import { ENTITY_GROUP, ENTITY_ITEM, ENTITY_LIST, SCALAR_ITEM, entityOf, requireCapability, toRef, toSdkRef, } from './host.js';
|
|
5
|
+
const str = (v, name) => {
|
|
6
|
+
if (typeof v !== 'string' || v.length === 0)
|
|
7
|
+
throw new Error(`"${name}" must be a non-empty string`);
|
|
8
|
+
return v;
|
|
9
|
+
};
|
|
10
|
+
function query(ctx, modelId) {
|
|
11
|
+
const q = ctx.host.bim.query();
|
|
12
|
+
const id = typeof modelId === 'string' && modelId.length > 0 ? modelId : ctx.host.defaultModelId;
|
|
13
|
+
return id ? q.model(id) : q;
|
|
14
|
+
}
|
|
15
|
+
export const modelNodes = [
|
|
16
|
+
{
|
|
17
|
+
type: 'model.select',
|
|
18
|
+
title: 'Select',
|
|
19
|
+
category: 'model',
|
|
20
|
+
doc: 'Entities matching an IfcOpenShell-style selector, e.g. `IfcWall, Pset_WallCommon.IsExternal=TRUE`.',
|
|
21
|
+
inputs: [],
|
|
22
|
+
outputs: [{ name: 'entities', type: ENTITY_LIST }],
|
|
23
|
+
params: [
|
|
24
|
+
{ name: 'selector', kind: 'string', default: 'IfcWall' },
|
|
25
|
+
{ name: 'model', kind: 'string', doc: 'Model id; the default model when empty.' },
|
|
26
|
+
],
|
|
27
|
+
capabilities: ['model.read'],
|
|
28
|
+
reads: 'model',
|
|
29
|
+
run: (ctx, _i, p) => {
|
|
30
|
+
requireCapability(ctx, 'model.read');
|
|
31
|
+
return { entities: query(ctx, p.model).select(str(p.selector, 'selector')).toArray().map(toRef) };
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
type: 'model.byType',
|
|
36
|
+
title: 'By type',
|
|
37
|
+
category: 'model',
|
|
38
|
+
inputs: [],
|
|
39
|
+
outputs: [{ name: 'entities', type: ENTITY_LIST }],
|
|
40
|
+
params: [
|
|
41
|
+
{ name: 'type', kind: 'string', default: 'IfcWall' },
|
|
42
|
+
{ name: 'model', kind: 'string' },
|
|
43
|
+
],
|
|
44
|
+
capabilities: ['model.read'],
|
|
45
|
+
reads: 'model',
|
|
46
|
+
run: (ctx, _i, p) => {
|
|
47
|
+
requireCapability(ctx, 'model.read');
|
|
48
|
+
return { entities: query(ctx, p.model).byType(str(p.type, 'type')).toArray().map(toRef) };
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
type: 'model.attribute',
|
|
53
|
+
title: 'Attribute',
|
|
54
|
+
category: 'model',
|
|
55
|
+
doc: 'Name, Type, Description, ObjectType or GlobalId of an entity.',
|
|
56
|
+
inputs: [{ name: 'entity', type: ENTITY_ITEM }],
|
|
57
|
+
outputs: [{ name: 'value', type: SCALAR_ITEM }],
|
|
58
|
+
params: [{ name: 'attribute', kind: 'enum', default: 'Name', options: ['Name', 'Type', 'Description', 'ObjectType', 'GlobalId'] }],
|
|
59
|
+
capabilities: ['model.read'],
|
|
60
|
+
reads: 'model',
|
|
61
|
+
run: (ctx, i, p) => {
|
|
62
|
+
requireCapability(ctx, 'model.read');
|
|
63
|
+
const e = entityOf(ctx, i.entity);
|
|
64
|
+
switch (p.attribute) {
|
|
65
|
+
case 'Name': return { value: e.name };
|
|
66
|
+
case 'Type': return { value: e.type };
|
|
67
|
+
case 'Description': return { value: e.description };
|
|
68
|
+
case 'ObjectType': return { value: e.objectType };
|
|
69
|
+
case 'GlobalId': return { value: e.globalId };
|
|
70
|
+
default: throw new Error(`unknown attribute "${String(p.attribute)}"`);
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
type: 'model.property',
|
|
76
|
+
title: 'Property',
|
|
77
|
+
category: 'model',
|
|
78
|
+
inputs: [{ name: 'entity', type: ENTITY_ITEM }],
|
|
79
|
+
outputs: [{ name: 'value', type: SCALAR_ITEM }],
|
|
80
|
+
params: [
|
|
81
|
+
{ name: 'pset', kind: 'string', default: 'Pset_WallCommon' },
|
|
82
|
+
{ name: 'property', kind: 'string', default: 'IsExternal' },
|
|
83
|
+
],
|
|
84
|
+
capabilities: ['model.read'],
|
|
85
|
+
reads: 'model',
|
|
86
|
+
run: (ctx, i, p) => {
|
|
87
|
+
requireCapability(ctx, 'model.read');
|
|
88
|
+
return { value: ctx.host.bim.property(toSdkRef(ctx, i.entity), str(p.pset, 'pset'), str(p.property, 'property')) };
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
type: 'model.quantity',
|
|
93
|
+
title: 'Quantity',
|
|
94
|
+
category: 'model',
|
|
95
|
+
inputs: [{ name: 'entity', type: ENTITY_ITEM }],
|
|
96
|
+
outputs: [{ name: 'value', type: SCALAR_ITEM }],
|
|
97
|
+
params: [
|
|
98
|
+
{ name: 'qset', kind: 'string', doc: 'Optional quantity set name.' },
|
|
99
|
+
{ name: 'quantity', kind: 'string', default: 'NetVolume' },
|
|
100
|
+
],
|
|
101
|
+
capabilities: ['model.read'],
|
|
102
|
+
reads: 'model',
|
|
103
|
+
run: (ctx, i, p) => {
|
|
104
|
+
requireCapability(ctx, 'model.read');
|
|
105
|
+
const ref = toSdkRef(ctx, i.entity);
|
|
106
|
+
const q = str(p.quantity, 'quantity');
|
|
107
|
+
const value = typeof p.qset === 'string' && p.qset.length > 0 ? ctx.host.bim.quantity(ref, p.qset, q) : ctx.host.bim.quantity(ref, q);
|
|
108
|
+
return { value };
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
type: 'model.related',
|
|
113
|
+
title: 'Related',
|
|
114
|
+
category: 'model',
|
|
115
|
+
doc: 'Entities linked by an IFC relationship, e.g. IfcRelVoidsElement forward = openings of a wall.',
|
|
116
|
+
inputs: [{ name: 'entity', type: ENTITY_ITEM }],
|
|
117
|
+
outputs: [{ name: 'related', type: ENTITY_LIST }],
|
|
118
|
+
params: [
|
|
119
|
+
{ name: 'relationship', kind: 'string', default: 'IfcRelVoidsElement' },
|
|
120
|
+
{ name: 'direction', kind: 'enum', default: 'forward', options: ['forward', 'inverse'] },
|
|
121
|
+
],
|
|
122
|
+
capabilities: ['model.read'],
|
|
123
|
+
reads: 'model',
|
|
124
|
+
run: (ctx, i, p) => {
|
|
125
|
+
requireCapability(ctx, 'model.read');
|
|
126
|
+
const dir = p.direction === 'inverse' ? 'inverse' : 'forward';
|
|
127
|
+
return { related: ctx.host.bim.related(toSdkRef(ctx, i.entity), str(p.relationship, 'relationship'), dir).map(toRef) };
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
type: 'model.storey',
|
|
132
|
+
title: 'Storey',
|
|
133
|
+
category: 'model',
|
|
134
|
+
inputs: [{ name: 'entity', type: ENTITY_ITEM }],
|
|
135
|
+
outputs: [{ name: 'storey', type: ENTITY_ITEM }],
|
|
136
|
+
params: [],
|
|
137
|
+
capabilities: ['model.read'],
|
|
138
|
+
reads: 'model',
|
|
139
|
+
run: (ctx, i) => {
|
|
140
|
+
requireCapability(ctx, 'model.read');
|
|
141
|
+
const s = ctx.host.bim.storey(toSdkRef(ctx, i.entity));
|
|
142
|
+
return { storey: s ? toRef(s) : null };
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
type: 'model.contains',
|
|
147
|
+
title: 'Contained elements',
|
|
148
|
+
category: 'model',
|
|
149
|
+
inputs: [{ name: 'container', type: ENTITY_ITEM }],
|
|
150
|
+
outputs: [{ name: 'entities', type: ENTITY_LIST }],
|
|
151
|
+
params: [],
|
|
152
|
+
capabilities: ['model.read'],
|
|
153
|
+
reads: 'model',
|
|
154
|
+
run: (ctx, i) => {
|
|
155
|
+
requireCapability(ctx, 'model.read');
|
|
156
|
+
return { entities: ctx.host.bim.contains(toSdkRef(ctx, i.container)).map(toRef) };
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
type: 'model.groupByStorey',
|
|
161
|
+
title: 'Group by storey',
|
|
162
|
+
category: 'model',
|
|
163
|
+
doc: 'Entities under their storey GlobalId; entities with no storey go under "".',
|
|
164
|
+
inputs: [{ name: 'entities', type: ENTITY_LIST }],
|
|
165
|
+
outputs: [{ name: 'group', type: ENTITY_GROUP }],
|
|
166
|
+
params: [],
|
|
167
|
+
capabilities: ['model.read'],
|
|
168
|
+
reads: 'model',
|
|
169
|
+
run: (ctx, i) => {
|
|
170
|
+
requireCapability(ctx, 'model.read');
|
|
171
|
+
const group = new Map();
|
|
172
|
+
for (const ref of i.entities) {
|
|
173
|
+
const s = ctx.host.bim.storey(toSdkRef(ctx, ref));
|
|
174
|
+
const key = s?.globalId ?? '';
|
|
175
|
+
(group.get(key) ?? group.set(key, []).get(key)).push(ref);
|
|
176
|
+
}
|
|
177
|
+
return { group };
|
|
178
|
+
},
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
type: 'model.groupByType',
|
|
182
|
+
title: 'Group by type',
|
|
183
|
+
category: 'model',
|
|
184
|
+
inputs: [{ name: 'entities', type: ENTITY_LIST }],
|
|
185
|
+
outputs: [{ name: 'group', type: ENTITY_GROUP }],
|
|
186
|
+
params: [],
|
|
187
|
+
capabilities: ['model.read'],
|
|
188
|
+
reads: 'model',
|
|
189
|
+
run: (ctx, i) => {
|
|
190
|
+
requireCapability(ctx, 'model.read');
|
|
191
|
+
const group = new Map();
|
|
192
|
+
for (const ref of i.entities) {
|
|
193
|
+
const key = entityOf(ctx, ref).type;
|
|
194
|
+
(group.get(key) ?? group.set(key, []).get(key)).push(ref);
|
|
195
|
+
}
|
|
196
|
+
return { group };
|
|
197
|
+
},
|
|
198
|
+
},
|
|
199
|
+
];
|
|
200
|
+
//# sourceMappingURL=model-nodes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-nodes.js","sourceRoot":"","sources":["../src/model-nodes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"script-node.d.ts","sourceRoot":"","sources":["../src/script-node.ts"],"names":[],"mappings":"AAwBA,OAAO,EAAmD,KAAK,WAAW,EAAE,MAAM,WAAW,CAAC;AAiF9F,eAAO,MAAM,UAAU,EAAE,WAgBxB,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,WAsB5B,CAAC"}
|
|
@@ -0,0 +1,140 @@
|
|
|
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
|
+
/**
|
|
5
|
+
* `script.run` and `script.list` — the two nodes that execute user code, in
|
|
6
|
+
* the QuickJS sandbox (`bim.sandbox`), with the sandbox's own `bim` API.
|
|
7
|
+
* This is the Dynamo "Python Script" analog: the code sees `inputs.a/b/c`
|
|
8
|
+
* and the value of its last expression is the output.
|
|
9
|
+
*
|
|
10
|
+
* The two differ only in the access their ports declare, which is what
|
|
11
|
+
* decides whether the scheduler lifts them: `script.run` takes items, so a
|
|
12
|
+
* list arriving on `a` runs the code once per element; `script.list` takes
|
|
13
|
+
* whole lists and returns one, which is what ranking, sorting, and any
|
|
14
|
+
* whole-set computation needs (and what a per-item node cannot express).
|
|
15
|
+
*
|
|
16
|
+
* The sandbox `bim` is *not* the SDK `bim` the built-in nodes use (it has
|
|
17
|
+
* no `bcf`, `ids`, `spatial`); that difference is documented, not papered
|
|
18
|
+
* over. Sandbox permissions are derived from the graph's grants: mutation
|
|
19
|
+
* is only enabled when a `model.mutate` grant exists.
|
|
20
|
+
*/
|
|
21
|
+
import { createSandbox } from '@ifc-lite/sandbox';
|
|
22
|
+
import { ANY_ITEM, ANY_LIST, requireCapability } from './host.js';
|
|
23
|
+
/**
|
|
24
|
+
* One sandbox per (BimContext, permission set), kept for the lifetime of
|
|
25
|
+
* the context: QuickJS module init is the expensive part, and a graph with
|
|
26
|
+
* several Script nodes (or a re-run) must not pay it per lane. Created here
|
|
27
|
+
* rather than through `bim.sandbox` because that path dynamically imports
|
|
28
|
+
* `@ifc-lite/sandbox` relative to the SDK package, which a pnpm-isolated
|
|
29
|
+
* install cannot resolve headlessly.
|
|
30
|
+
*/
|
|
31
|
+
const sandboxes = new WeakMap();
|
|
32
|
+
function sandboxFor(bim, permissions, timeoutMs) {
|
|
33
|
+
const key = JSON.stringify({ permissions, timeoutMs });
|
|
34
|
+
let perContext = sandboxes.get(bim);
|
|
35
|
+
if (!perContext) {
|
|
36
|
+
perContext = new Map();
|
|
37
|
+
sandboxes.set(bim, perContext);
|
|
38
|
+
}
|
|
39
|
+
let pending = perContext.get(key);
|
|
40
|
+
if (!pending) {
|
|
41
|
+
// A rejected creation (a wasm load failure, a transient resource limit)
|
|
42
|
+
// must not be cached: every later lane would await the same rejection for
|
|
43
|
+
// the lifetime of the context, turning one hiccup into a dead node.
|
|
44
|
+
pending = createSandbox(bim, { permissions, limits: { timeoutMs } }).catch((err) => {
|
|
45
|
+
if (perContext.get(key) === pending)
|
|
46
|
+
perContext.delete(key);
|
|
47
|
+
throw err;
|
|
48
|
+
});
|
|
49
|
+
perContext.set(key, pending);
|
|
50
|
+
}
|
|
51
|
+
return pending;
|
|
52
|
+
}
|
|
53
|
+
/** Evaluate `params.code` with `inputs` in scope and return its last expression. */
|
|
54
|
+
async function evaluate(ctx, inputs, params) {
|
|
55
|
+
// The node declares `model.read`; without this check a graph granted
|
|
56
|
+
// nothing still got a sandbox with query+model on, so user code could
|
|
57
|
+
// read the model through a capability the graph never had.
|
|
58
|
+
requireCapability(ctx, 'model.read');
|
|
59
|
+
const grants = ctx.host.grants;
|
|
60
|
+
const has = (scope, action) => !grants || grants.some((g) => g.scope === scope && g.action === action);
|
|
61
|
+
const permissions = {
|
|
62
|
+
query: true,
|
|
63
|
+
model: true,
|
|
64
|
+
viewer: has('viewer', 'colorize') || has('viewer', 'isolate') || has('viewer', 'fly') || has('viewer', 'section'),
|
|
65
|
+
mutate: has('model', 'mutate'),
|
|
66
|
+
store: has('model', 'create'),
|
|
67
|
+
export: has('export', 'create'),
|
|
68
|
+
lens: true,
|
|
69
|
+
files: true,
|
|
70
|
+
};
|
|
71
|
+
const injected = JSON.stringify({ a: inputs.a ?? null, b: inputs.b ?? null, c: inputs.c ?? null });
|
|
72
|
+
// Every lane shares one sandbox, and QuickJS evaluates a program in the
|
|
73
|
+
// GLOBAL lexical scope — so a second lane re-running `const inputs = …`,
|
|
74
|
+
// or any `const` the user wrote, died with "redeclaration of 'x'". Every
|
|
75
|
+
// lane but the first then logged an error and yielded null, which a
|
|
76
|
+
// downstream filter reads as a legitimate answer. Running the source
|
|
77
|
+
// through a direct `eval` inside a function gives each lane its own
|
|
78
|
+
// variable environment while keeping the two things the node promises:
|
|
79
|
+
// `inputs` in scope, and the last expression as the value (`eval` returns
|
|
80
|
+
// its program's completion value, which a function body would not).
|
|
81
|
+
const code = `(function (inputs) { return eval(${JSON.stringify(String(params.code ?? ''))}); })(${injected})`;
|
|
82
|
+
const sandbox = await sandboxFor(ctx.host.bim, permissions, Number(params.timeoutMs) || 30_000);
|
|
83
|
+
// Plain JavaScript by contract: skipping the TypeScript strip avoids
|
|
84
|
+
// initialising esbuild-wasm, which only works in the browser. It is also
|
|
85
|
+
// what keeps the wrapper above honest — the source reaches `eval`
|
|
86
|
+
// verbatim, not as something a transpiler rewrote.
|
|
87
|
+
const result = await sandbox.eval(code, { typescript: false });
|
|
88
|
+
for (const entry of result.logs) {
|
|
89
|
+
const level = entry.level === 'error' ? 'error' : entry.level === 'warn' ? 'warn' : 'info';
|
|
90
|
+
ctx.log(level, entry.args.map((a) => (typeof a === 'string' ? a : JSON.stringify(a))).join(' '));
|
|
91
|
+
}
|
|
92
|
+
return result.value ?? null;
|
|
93
|
+
}
|
|
94
|
+
/** The shared editable surface, so the two nodes cannot drift apart. */
|
|
95
|
+
const SCRIPT_PARAMS = [
|
|
96
|
+
{ name: 'code', kind: 'code', language: 'javascript', default: 'inputs.a', doc: 'JavaScript (not TypeScript). The value of the last expression is the output.' },
|
|
97
|
+
{ name: 'timeoutMs', kind: 'number', default: 30_000, doc: 'Hard limit per evaluation; the sandbox is interrupted when it is exceeded.' },
|
|
98
|
+
];
|
|
99
|
+
export const scriptNode = {
|
|
100
|
+
type: 'script.run',
|
|
101
|
+
title: 'Script',
|
|
102
|
+
category: 'script',
|
|
103
|
+
doc: 'Runs JavaScript (not TypeScript) in the sandbox with `inputs.a`, `inputs.b`, `inputs.c` and the sandbox `bim` API; the last expression is `result`. A list on an input runs the code once per element. An entity arrives as `{ globalId, modelId, expressId }`, which is also a `bim.*` ref.',
|
|
104
|
+
inputs: [
|
|
105
|
+
{ name: 'a', type: ANY_ITEM, optional: true, nullable: true },
|
|
106
|
+
{ name: 'b', type: ANY_ITEM, optional: true, nullable: true },
|
|
107
|
+
{ name: 'c', type: ANY_ITEM, optional: true, nullable: true },
|
|
108
|
+
],
|
|
109
|
+
outputs: [{ name: 'result', type: ANY_ITEM }],
|
|
110
|
+
params: [...SCRIPT_PARAMS],
|
|
111
|
+
capabilities: ['model.read'],
|
|
112
|
+
reads: 'model',
|
|
113
|
+
requires: { backend: ['sandbox'] },
|
|
114
|
+
run: async (ctx, inputs, params) => ({ result: await evaluate(ctx, inputs, params) }),
|
|
115
|
+
};
|
|
116
|
+
export const scriptListNode = {
|
|
117
|
+
type: 'script.list',
|
|
118
|
+
title: 'Script (list)',
|
|
119
|
+
category: 'script',
|
|
120
|
+
doc: 'Like Script, but `inputs.a/b/c` are whole lists and the last expression must be an array — for sorting, ranking, and anything that needs the whole set at once.',
|
|
121
|
+
inputs: [
|
|
122
|
+
{ name: 'a', type: ANY_LIST, optional: true },
|
|
123
|
+
{ name: 'b', type: ANY_LIST, optional: true },
|
|
124
|
+
{ name: 'c', type: ANY_LIST, optional: true },
|
|
125
|
+
],
|
|
126
|
+
outputs: [{ name: 'items', type: ANY_LIST }],
|
|
127
|
+
params: [...SCRIPT_PARAMS],
|
|
128
|
+
capabilities: ['model.read'],
|
|
129
|
+
reads: 'model',
|
|
130
|
+
requires: { backend: ['sandbox'] },
|
|
131
|
+
run: async (ctx, inputs, params) => {
|
|
132
|
+
const value = await evaluate(ctx, inputs, params);
|
|
133
|
+
// An `items` port hands its value straight to downstream list ports; a
|
|
134
|
+
// non-array here would reach them as a list-shaped value that is not one.
|
|
135
|
+
if (!Array.isArray(value))
|
|
136
|
+
throw new Error(`script.list must end in an array, got ${value === null ? 'null' : typeof value}`);
|
|
137
|
+
return { items: value };
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
//# sourceMappingURL=script-node.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"script-node.js","sourceRoot":"","sources":["../src/script-node.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,aAAa,EAAgB,MAAM,mBAAmB,CAAC;AAEhE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,iBAAiB,EAA8B,MAAM,WAAW,CAAC;AAE9F;;;;;;;GAOG;AACH,MAAM,SAAS,GAAG,IAAI,OAAO,EAA6C,CAAC;AAE3E,SAAS,UAAU,CAAC,GAAe,EAAE,WAAoC,EAAE,SAAiB;IAC1F,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC,CAAC;IACvD,IAAI,UAAU,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACpC,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,UAAU,GAAG,IAAI,GAAG,EAAE,CAAC;QACvB,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;IACjC,CAAC;IACD,IAAI,OAAO,GAAG,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAClC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,wEAAwE;QACxE,0EAA0E;QAC1E,oEAAoE;QACpE,OAAO,GAAG,aAAa,CAAC,GAAG,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;YACjF,IAAI,UAAW,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,OAAO;gBAAE,UAAW,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC9D,MAAM,GAAG,CAAC;QACZ,CAAC,CAAC,CAAC;QACH,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAC/B,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,oFAAoF;AACpF,KAAK,UAAU,QAAQ,CAAC,GAAQ,EAAE,MAAyC,EAAE,MAAyC;IACpH,qEAAqE;IACrE,sEAAsE;IACtE,2DAA2D;IAC3D,iBAAiB,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;IACrC,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;IAC/B,MAAM,GAAG,GAAG,CAAC,KAAa,EAAE,MAAc,EAAE,EAAE,CAAC,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,KAAK,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;IACvH,MAAM,WAAW,GAAG;QAClB,KAAK,EAAE,IAAI;QACX,KAAK,EAAE,IAAI;QACX,MAAM,EAAE,GAAG,CAAC,QAAQ,EAAE,UAAU,CAAC,IAAI,GAAG,CAAC,QAAQ,EAAE,SAAS,CAAC,IAAI,GAAG,CAAC,QAAQ,EAAE,KAAK,CAAC,IAAI,GAAG,CAAC,QAAQ,EAAE,SAAS,CAAC;QACjH,MAAM,EAAE,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC;QAC9B,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC;QAC7B,MAAM,EAAE,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC;QAC/B,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,IAAI;KACZ,CAAC;IACF,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IACnG,wEAAwE;IACxE,yEAAyE;IACzE,yEAAyE;IACzE,oEAAoE;IACpE,qEAAqE;IACrE,oEAAoE;IACpE,uEAAuE;IACvE,0EAA0E;IAC1E,oEAAoE;IACpE,MAAM,IAAI,GAAG,oCAAoC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,SAAS,QAAQ,GAAG,CAAC;IAC/G,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,MAAM,CAAC,CAAC;IAChG,qEAAqE;IACrE,yEAAyE;IACzE,kEAAkE;IAClE,mDAAmD;IACnD,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC;IAC/D,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;QAChC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;QAC3F,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACnG,CAAC;IACD,OAAO,MAAM,CAAC,KAAK,IAAI,IAAI,CAAC;AAC9B,CAAC;AAED,wEAAwE;AACxE,MAAM,aAAa,GAAG;IACpB,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,8EAA8E,EAAE;IAChK,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,4EAA4E,EAAE;CACjI,CAAC;AAEX,MAAM,CAAC,MAAM,UAAU,GAAgB;IACrC,IAAI,EAAE,YAAY;IAClB,KAAK,EAAE,QAAQ;IACf,QAAQ,EAAE,QAAQ;IAClB,GAAG,EAAE,8RAA8R;IACnS,MAAM,EAAE;QACN,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE;QAC7D,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE;QAC7D,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE;KAC9D;IACD,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;IAC7C,MAAM,EAAE,CAAC,GAAG,aAAa,CAAC;IAC1B,YAAY,EAAE,CAAC,YAAY,CAAC;IAC5B,KAAK,EAAE,OAAO;IACd,QAAQ,EAAE,EAAE,OAAO,EAAE,CAAC,SAAS,CAAC,EAAE;IAClC,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;CACtF,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAgB;IACzC,IAAI,EAAE,aAAa;IACnB,KAAK,EAAE,eAAe;IACtB,QAAQ,EAAE,QAAQ;IAClB,GAAG,EAAE,iKAAiK;IACtK,MAAM,EAAE;QACN,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;QAC7C,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;QAC7C,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE;KAC9C;IACD,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;IAC5C,MAAM,EAAE,CAAC,GAAG,aAAa,CAAC;IAC1B,YAAY,EAAE,CAAC,YAAY,CAAC;IAC5B,KAAK,EAAE,OAAO;IACd,QAAQ,EAAE,EAAE,OAAO,EAAE,CAAC,SAAS,CAAC,EAAE;IAClC,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;QACjC,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QAClD,uEAAuE;QACvE,0EAA0E;QAC1E,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,yCAAyC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,KAAK,EAAE,CAAC,CAAC;QAC9H,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IAC1B,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Is a spreadsheet cell's text a COMPLETE value of its column's type?
|
|
3
|
+
*
|
|
4
|
+
* `@ifc-lite/mutations`' `parseValue` is lenient by construction: `parseFloat`
|
|
5
|
+
* reads the longest numeric prefix, so `"12,5"` becomes 12 and `"60abc"`
|
|
6
|
+
* becomes 60, and every string other than true/yes/1 becomes `false`. A
|
|
7
|
+
* European CSV (`12,5` in a Real column) therefore wrote 12 into the model
|
|
8
|
+
* with nothing reported. This check runs first at every table→value boundary
|
|
9
|
+
* (the CSV and XLSX readers, and `model.applyTable`), so a value is either
|
|
10
|
+
* exactly what the cell says or reported and left unwritten (#5377 review).
|
|
11
|
+
*/
|
|
12
|
+
import type { ColumnType } from '@ifc-lite/flow';
|
|
13
|
+
import { PARSE_INVALID, type PropertyValue } from '@ifc-lite/mutations';
|
|
14
|
+
/**
|
|
15
|
+
* Parse a cell as its column's type, or {@link PARSE_INVALID}. The text is
|
|
16
|
+
* trimmed ONCE and the same text is both checked and parsed: checking the
|
|
17
|
+
* trimmed text but parsing the raw one accepted `" true "` and wrote `false`.
|
|
18
|
+
*/
|
|
19
|
+
export declare function parseStrictCell(raw: string, type: ColumnType): PropertyValue | typeof PARSE_INVALID;
|
|
20
|
+
//# sourceMappingURL=strict-cell.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"strict-cell.d.ts","sourceRoot":"","sources":["../src/strict-cell.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAc,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAuBpF;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,aAAa,GAAG,OAAO,aAAa,CAGnG"}
|
|
@@ -0,0 +1,33 @@
|
|
|
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
|
+
import { PARSE_INVALID, parseValue } from '@ifc-lite/mutations';
|
|
5
|
+
import { VALUE_TYPE_BY_COLUMN_TYPE } from './table-nodes.js';
|
|
6
|
+
const REAL = /^[+-]?(\d+\.?\d*|\.\d+)([eE][+-]?\d+)?$/;
|
|
7
|
+
const INTEGER = /^[+-]?\d+$/;
|
|
8
|
+
/**
|
|
9
|
+
* IFC LOGICAL's UNKNOWN is deliberately absent: the property model carries a
|
|
10
|
+
* boolean, and writing UNKNOWN as `false` would state a fact the sheet did not.
|
|
11
|
+
*/
|
|
12
|
+
const BOOLEAN = /^(true|false|yes|no|1|0)$/i;
|
|
13
|
+
function isStrictlyTyped(text, type) {
|
|
14
|
+
switch (type) {
|
|
15
|
+
// The syntax alone admits `1e309` (Infinity) and integers past 2^53
|
|
16
|
+
// (silently rounded), so the value itself is checked too.
|
|
17
|
+
case 'real': return REAL.test(text) && Number.isFinite(Number(text));
|
|
18
|
+
case 'integer': return INTEGER.test(text) && Number.isSafeInteger(Number(text));
|
|
19
|
+
case 'boolean':
|
|
20
|
+
case 'logical': return BOOLEAN.test(text);
|
|
21
|
+
default: return true;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Parse a cell as its column's type, or {@link PARSE_INVALID}. The text is
|
|
26
|
+
* trimmed ONCE and the same text is both checked and parsed: checking the
|
|
27
|
+
* trimmed text but parsing the raw one accepted `" true "` and wrote `false`.
|
|
28
|
+
*/
|
|
29
|
+
export function parseStrictCell(raw, type) {
|
|
30
|
+
const text = raw.trim();
|
|
31
|
+
return isStrictlyTyped(text, type) ? parseValue(text, VALUE_TYPE_BY_COLUMN_TYPE[type]) : PARSE_INVALID;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=strict-cell.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"strict-cell.js","sourceRoot":"","sources":["../src/strict-cell.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAe/D,OAAO,EAAE,aAAa,EAAE,UAAU,EAAsB,MAAM,qBAAqB,CAAC;AACpF,OAAO,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAE7D,MAAM,IAAI,GAAG,yCAAyC,CAAC;AACvD,MAAM,OAAO,GAAG,YAAY,CAAC;AAC7B;;;GAGG;AACH,MAAM,OAAO,GAAG,4BAA4B,CAAC;AAE7C,SAAS,eAAe,CAAC,IAAY,EAAE,IAAgB;IACrD,QAAQ,IAAI,EAAE,CAAC;QACb,oEAAoE;QACpE,0DAA0D;QAC1D,KAAK,MAAM,CAAC,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;QACrE,KAAK,SAAS,CAAC,CAAC,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;QAChF,KAAK,SAAS,CAAC;QACf,KAAK,SAAS,CAAC,CAAC,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1C,OAAO,CAAC,CAAC,OAAO,IAAI,CAAC;IACvB,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,GAAW,EAAE,IAAgB;IAC3D,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IACxB,OAAO,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,yBAAyB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC;AACzG,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `table.*` — typed tables to and from entities.
|
|
3
|
+
*
|
|
4
|
+
* `table.fromEntities` is the Excel export loop's first half: one row per
|
|
5
|
+
* entity, keyed by GlobalId, every column stamped with the IFC value type
|
|
6
|
+
* and (for properties) its pset/prop binding so `ApplyTable` can write it
|
|
7
|
+
* back without guessing. `table.longFormat` is the canonical
|
|
8
|
+
* (GlobalId, Pset, Prop, Value, Type) shape that `pivot` widens.
|
|
9
|
+
*/
|
|
10
|
+
import { PropertyValueType } from '@ifc-lite/data';
|
|
11
|
+
import { type ColumnType, type Table } from '@ifc-lite/flow';
|
|
12
|
+
import { type FlowNodeDef } from './host.js';
|
|
13
|
+
export declare function columnTypeOf(valueType: number): ColumnType;
|
|
14
|
+
export declare const VALUE_TYPE_BY_COLUMN_TYPE: Readonly<Record<ColumnType, PropertyValueType>>;
|
|
15
|
+
export declare function tableOf(v: unknown): Table;
|
|
16
|
+
export declare const tableNodes: FlowNodeDef[];
|
|
17
|
+
//# sourceMappingURL=table-nodes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"table-nodes.d.ts","sourceRoot":"","sources":["../src/table-nodes.ts"],"names":[],"mappings":"AAIA;;;;;;;;GAQG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAA2D,KAAK,UAAU,EAA2C,KAAK,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAE/J,OAAO,EAAuG,KAAK,WAAW,EAAE,MAAM,WAAW,CAAC;AAgBlJ,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU,CAE1D;AAED,eAAO,MAAM,yBAAyB,EAAE,QAAQ,CAAC,MAAM,CAAC,UAAU,EAAE,iBAAiB,CAAC,CAYrF,CAAC;AAIF,wBAAgB,OAAO,CAAC,CAAC,EAAE,OAAO,GAAG,KAAK,CAIzC;AASD,eAAO,MAAM,UAAU,EAAE,WAAW,EAwInC,CAAC"}
|