@idfkit/core 0.1.0 → 0.2.0-rc.2
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 +16 -7
- package/dist/collection.d.ts +0 -13
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +1 -1
- package/dist/conformance.d.ts +20 -0
- package/dist/conformance.d.ts.map +1 -0
- package/dist/conformance.js +20 -0
- package/dist/conformance.js.map +1 -0
- package/dist/docs-url/index.d.ts +81 -0
- package/dist/docs-url/index.d.ts.map +1 -0
- package/dist/docs-url/index.js +201 -0
- package/dist/docs-url/index.js.map +1 -0
- package/dist/docs-url/locations.d.ts +2 -0
- package/dist/docs-url/locations.d.ts.map +1 -0
- package/dist/docs-url/locations.js +272 -0
- package/dist/docs-url/locations.js.map +1 -0
- package/dist/document.d.ts +40 -14
- package/dist/document.d.ts.map +1 -1
- package/dist/document.js +0 -0
- package/dist/document.js.map +1 -1
- package/dist/index.d.ts +19 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -3
- package/dist/index.js.map +1 -1
- package/dist/introspect/describe.d.ts +117 -0
- package/dist/introspect/describe.d.ts.map +1 -0
- package/dist/introspect/describe.js +206 -0
- package/dist/introspect/describe.js.map +1 -0
- package/dist/node.d.ts +5 -5
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +25 -5
- package/dist/node.js.map +1 -1
- package/dist/object.d.ts +1 -1
- package/dist/parse/epjson.d.ts +1 -1
- package/dist/parse/epjson.d.ts.map +1 -1
- package/dist/parse/epjson.js +3 -3
- package/dist/parse/epjson.js.map +1 -1
- package/dist/parse/idf.d.ts +24 -6
- package/dist/parse/idf.d.ts.map +1 -1
- package/dist/parse/idf.js +181 -8
- package/dist/parse/idf.js.map +1 -1
- package/dist/parse/lexer.d.ts +36 -0
- package/dist/parse/lexer.d.ts.map +1 -1
- package/dist/parse/lexer.js +49 -2
- package/dist/parse/lexer.js.map +1 -1
- package/dist/typemap.d.ts +7 -5
- package/dist/typemap.d.ts.map +1 -1
- package/dist/typemap.js +7 -5
- package/dist/typemap.js.map +1 -1
- package/dist/validate/index.d.ts +11 -0
- package/dist/validate/index.d.ts.map +1 -0
- package/dist/validate/index.js +10 -0
- package/dist/validate/index.js.map +1 -0
- package/dist/validate/types.d.ts +63 -0
- package/dist/validate/types.d.ts.map +1 -0
- package/dist/validate/types.js +25 -0
- package/dist/validate/types.js.map +1 -0
- package/dist/validate/validate.d.ts +82 -0
- package/dist/validate/validate.d.ts.map +1 -0
- package/dist/validate/validate.js +574 -0
- package/dist/validate/validate.js.map +1 -0
- package/dist/write/epjson.d.ts +3 -3
- package/dist/write/idf.d.ts +34 -2
- package/dist/write/idf.d.ts.map +1 -1
- package/dist/write/idf.js +24 -5
- package/dist/write/idf.js.map +1 -1
- package/package.json +11 -8
- package/dist/types/v26-1.d.ts +0 -65896
- package/dist/types/v26-1.d.ts.map +0 -1
- package/dist/types/v26-1.js +0 -5
- package/dist/types/v26-1.js.map +0 -1
- package/dist/types/v9-4.d.ts +0 -61414
- package/dist/types/v9-4.d.ts.map +0 -1
- package/dist/types/v9-4.js +0 -5
- package/dist/types/v9-4.js.map +0 -1
package/dist/parse/idf.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IdfDocument } from '../document.js';
|
|
2
2
|
import { lex } from './lexer.js';
|
|
3
3
|
/**
|
|
4
4
|
* Parse IDF text into a document.
|
|
@@ -18,35 +18,78 @@ export function parseIdf(text, schema, options = {}) {
|
|
|
18
18
|
diagnostics.push(diagnostic);
|
|
19
19
|
options.onDiagnostic?.(diagnostic);
|
|
20
20
|
};
|
|
21
|
+
/**
|
|
22
|
+
* Record a finding that does NOT stop the parse, whatever `strict` says.
|
|
23
|
+
*
|
|
24
|
+
* `report` throws under `strict`, which is right for a finding that leaves nothing to return: an
|
|
25
|
+
* object whose type is unknown cannot be built. A value of the wrong KIND is different. The
|
|
26
|
+
* object is built, the document is complete, and a caller reading strictly gets exactly what they
|
|
27
|
+
* got before this finding existed (FR-014). Routing it through `report` made a strict parse fail
|
|
28
|
+
* on files that used to load, which is the opposite of additive.
|
|
29
|
+
*/
|
|
30
|
+
const note = (diagnostic) => {
|
|
31
|
+
diagnostics.push(diagnostic);
|
|
32
|
+
options.onDiagnostic?.(diagnostic);
|
|
33
|
+
};
|
|
21
34
|
const raw = lex(text, { onDiagnostic: report });
|
|
22
|
-
const document = new
|
|
35
|
+
const document = new IdfDocument(schema);
|
|
23
36
|
for (const object of raw) {
|
|
24
37
|
const canonical = schema.resolve(object.typeName);
|
|
25
38
|
if (canonical === undefined) {
|
|
26
39
|
report({
|
|
27
40
|
message: `Unknown object type "${object.typeName}" in EnergyPlus ${schema.version}`,
|
|
28
41
|
line: object.line,
|
|
42
|
+
column: object.column,
|
|
29
43
|
typeName: object.typeName,
|
|
44
|
+
// Best effort, and the same rule Python's `_extract_object_name` uses: the first positional
|
|
45
|
+
// value is the name for every named type, and is a real field for the anonymous ones. An
|
|
46
|
+
// unknown type has no definition to tell the two apart, so the raw first value is what there
|
|
47
|
+
// is. Declaring `objectName` and never filling it would make the field a claim rather than a
|
|
48
|
+
// value.
|
|
49
|
+
objectName: object.values[0],
|
|
50
|
+
code: 'UnknownObjectType',
|
|
30
51
|
});
|
|
31
52
|
continue;
|
|
32
53
|
}
|
|
33
54
|
const definition = schema.require(canonical);
|
|
34
55
|
try {
|
|
35
|
-
const
|
|
56
|
+
const invalid = [];
|
|
57
|
+
const { name, values } = interpret(definition, object, invalid);
|
|
36
58
|
document.addRaw(canonical, definition.anon === 1 ? null : name, values);
|
|
59
|
+
// Reported after the object is built, never instead of building it: a value of the wrong
|
|
60
|
+
// kind does not stop the parse, so a caller reading strictly gets the document they always
|
|
61
|
+
// got. This adds a finding where there was silence, and nothing else.
|
|
62
|
+
//
|
|
63
|
+
// Positioned at the offending FIELD rather than at the object, because that is what makes it
|
|
64
|
+
// useful. The shape this catches is a missing semicolon swallowing the object below, and the
|
|
65
|
+
// object's own first line is nowhere near the damage.
|
|
66
|
+
for (const { field, index, value } of invalid) {
|
|
67
|
+
if (stringIsLegal(definition, field, value))
|
|
68
|
+
continue;
|
|
69
|
+
note({
|
|
70
|
+
message: `Field "${field}" expects a number, got "${value}"`,
|
|
71
|
+
line: fieldLine(text, object, index),
|
|
72
|
+
typeName: canonical,
|
|
73
|
+
objectName: definition.anon === 1 ? undefined : object.values[0],
|
|
74
|
+
code: 'InvalidField',
|
|
75
|
+
});
|
|
76
|
+
}
|
|
37
77
|
}
|
|
38
78
|
catch (error) {
|
|
39
79
|
report({
|
|
40
80
|
message: error instanceof Error ? error.message : String(error),
|
|
41
81
|
line: object.line,
|
|
82
|
+
column: object.column,
|
|
42
83
|
typeName: canonical,
|
|
84
|
+
objectName: definition.anon === 1 ? undefined : object.values[0],
|
|
85
|
+
code: 'ParseError',
|
|
43
86
|
});
|
|
44
87
|
}
|
|
45
88
|
}
|
|
46
89
|
return { document, diagnostics };
|
|
47
90
|
}
|
|
48
91
|
/** Map positional IDF values onto named schema fields. */
|
|
49
|
-
function interpret(definition, object) {
|
|
92
|
+
function interpret(definition, object, invalid) {
|
|
50
93
|
const order = definition.f;
|
|
51
94
|
const named = definition.anon !== 1 && order[0] === 'name';
|
|
52
95
|
const values = {};
|
|
@@ -61,6 +104,7 @@ function interpret(definition, object) {
|
|
|
61
104
|
}
|
|
62
105
|
const fixed = named ? order.slice(1) : order;
|
|
63
106
|
for (const field of fixed) {
|
|
107
|
+
const index = cursor;
|
|
64
108
|
const raw = object.values[cursor++];
|
|
65
109
|
if (raw === undefined)
|
|
66
110
|
break;
|
|
@@ -69,6 +113,11 @@ function interpret(definition, object) {
|
|
|
69
113
|
const coerced = coerce(definition, field, raw);
|
|
70
114
|
if (coerced !== undefined)
|
|
71
115
|
values[field] = coerced;
|
|
116
|
+
// A numeric field that kept its string is a coercion that fell through. Whether that is
|
|
117
|
+
// actually wrong needs the schema and is asked on the reporting path, which runs almost never.
|
|
118
|
+
if (invalid !== undefined && coerced === raw && isNumericField(definition, field)) {
|
|
119
|
+
invalid.push({ field, index, value: raw });
|
|
120
|
+
}
|
|
72
121
|
}
|
|
73
122
|
// Everything past the fixed fields belongs to the extensible section, read in
|
|
74
123
|
// repeats of the group width. A trailing partial group is kept rather than
|
|
@@ -107,6 +156,110 @@ function interpret(definition, object) {
|
|
|
107
156
|
}
|
|
108
157
|
return { name, values };
|
|
109
158
|
}
|
|
159
|
+
/**
|
|
160
|
+
* The two sizing sentinels, accepted in ANY numeric field.
|
|
161
|
+
*
|
|
162
|
+
* Not read from the field's own `se` branch, deliberately. The schema EnergyPlus ships is NARROWER
|
|
163
|
+
* than the engine it ships with, and its own example files prove it. Both of these declare a string
|
|
164
|
+
* branch naming exactly one sentinel, and the shipped files use the other one:
|
|
165
|
+
*
|
|
166
|
+
* `PlantLoop.plant_loop_volume` allows `Autocalculate`; 28 files write `Autosize`.
|
|
167
|
+
* `AirTerminal:SingleDuct:VAV:Reheat.maximum_flow_fraction_during_reheat` allows `Autosize`;
|
|
168
|
+
* 673 files write `Autocalculate`.
|
|
169
|
+
*
|
|
170
|
+
* The schema is well formed: across all 17 bundled versions no field declares a non-numeric string
|
|
171
|
+
* default on a numeric type with no string branch. It is simply stricter about WHICH sentinel
|
|
172
|
+
* belongs where than EnergyPlus is. Reading each field's branch literally produced 3,775 findings
|
|
173
|
+
* across the 760 example files of one release, every one against a model EnergyPlus reads happily.
|
|
174
|
+
*
|
|
175
|
+
* A parse finding says the value is not of the kind the field takes. Whether the exact sentinel is
|
|
176
|
+
* the one THIS field documents is a schema question, and `validateObject` already answers it.
|
|
177
|
+
*/
|
|
178
|
+
const SIZING_SENTINELS = new Set(['autosize', 'autocalculate']);
|
|
179
|
+
/** @internal */
|
|
180
|
+
function isNumericField(definition, field) {
|
|
181
|
+
const kind = definition.p[field]?.t;
|
|
182
|
+
return kind === 'n' || kind === 'i';
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Whether a string the numeric coercion rejected is legal for this field anyway.
|
|
186
|
+
*
|
|
187
|
+
* Consulted only when coercion has already failed, so the parse path pays nothing for it.
|
|
188
|
+
*
|
|
189
|
+
* @internal
|
|
190
|
+
*/
|
|
191
|
+
function stringIsLegal(definition, field, value) {
|
|
192
|
+
if (SIZING_SENTINELS.has(value.toLowerCase()))
|
|
193
|
+
return true;
|
|
194
|
+
const slim = definition.p[field];
|
|
195
|
+
if (slim === undefined)
|
|
196
|
+
return true;
|
|
197
|
+
// `auto` marks a collapsed `anyOf`. Without an `se` the string branch declared no enum, so any
|
|
198
|
+
// string satisfies it; with one, only its members do.
|
|
199
|
+
if (slim.se === undefined)
|
|
200
|
+
return slim.auto === 1;
|
|
201
|
+
const folded = value.toLowerCase();
|
|
202
|
+
return slim.se.some((allowed) => allowed.toLowerCase() === folded);
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* The 1-based line a field sits on, found by rescanning from the object's own offset.
|
|
206
|
+
*
|
|
207
|
+
* The lexer records one offset per object rather than a line per field, because a finding about a
|
|
208
|
+
* field is rare and an array per object is not. This walks forward counting separators, stepping
|
|
209
|
+
* over `!` comments so a comma inside one is not mistaken for one, which is the same rule the
|
|
210
|
+
* lexer itself follows.
|
|
211
|
+
*
|
|
212
|
+
* `index` counts into `RawObject.values`, which the lexer has already shifted the type name off.
|
|
213
|
+
* The scan starts at the type name, so it steps over one more separator than the index: the comma
|
|
214
|
+
* that ends `Building,` is what puts values[0] on the line after it.
|
|
215
|
+
*
|
|
216
|
+
* @internal
|
|
217
|
+
*/
|
|
218
|
+
function fieldLine(text, object, index) {
|
|
219
|
+
if (object.offset === undefined)
|
|
220
|
+
return object.line;
|
|
221
|
+
const separators = index + 1;
|
|
222
|
+
let seen = 0;
|
|
223
|
+
let position = object.offset;
|
|
224
|
+
while (position < text.length && seen < separators) {
|
|
225
|
+
const char = text[position];
|
|
226
|
+
if (char === '!') {
|
|
227
|
+
const newline = text.indexOf('\n', position);
|
|
228
|
+
if (newline < 0)
|
|
229
|
+
break;
|
|
230
|
+
position = newline + 1;
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
if (char === ';')
|
|
234
|
+
break;
|
|
235
|
+
if (char === ',')
|
|
236
|
+
seen += 1;
|
|
237
|
+
position += 1;
|
|
238
|
+
}
|
|
239
|
+
if (seen < separators)
|
|
240
|
+
return object.line;
|
|
241
|
+
// Step over whitespace AND any comment between the separator and the value. A field's comma is
|
|
242
|
+
// routinely followed by `!- Field Name` on the same line, and stopping at the `!` would report
|
|
243
|
+
// the line the PREVIOUS value sits on, one too early.
|
|
244
|
+
while (position < text.length) {
|
|
245
|
+
const char = text[position] ?? '';
|
|
246
|
+
if (char === '!') {
|
|
247
|
+
const newline = text.indexOf('\n', position);
|
|
248
|
+
if (newline < 0)
|
|
249
|
+
break;
|
|
250
|
+
position = newline + 1;
|
|
251
|
+
continue;
|
|
252
|
+
}
|
|
253
|
+
if (!/\s/.test(char))
|
|
254
|
+
break;
|
|
255
|
+
position += 1;
|
|
256
|
+
}
|
|
257
|
+
let line = object.line;
|
|
258
|
+
for (let i = object.offset; i < position; i += 1)
|
|
259
|
+
if (text[i] === '\n')
|
|
260
|
+
line += 1;
|
|
261
|
+
return line;
|
|
262
|
+
}
|
|
110
263
|
function coerce(definition, field, raw) {
|
|
111
264
|
return coerceValue(definition.p[field]?.t, raw);
|
|
112
265
|
}
|
|
@@ -137,11 +290,31 @@ function coerceValue(kind, raw) {
|
|
|
137
290
|
export class IdfParseError extends Error {
|
|
138
291
|
line;
|
|
139
292
|
typeName;
|
|
293
|
+
/**
|
|
294
|
+
* Every finding that stopped the parse.
|
|
295
|
+
*
|
|
296
|
+
* This error carried `line` and `typeName` from a single diagnostic, flattened into fields, and
|
|
297
|
+
* a caller who wanted the rest had nowhere to look. Python's `IDFParseError` has always carried
|
|
298
|
+
* the collection; this is the half of the difference that was real.
|
|
299
|
+
*
|
|
300
|
+
* `line` and `typeName` still resolve to the first finding's values, so no existing caller
|
|
301
|
+
* breaks (FR-013, FR-014). They are a convenience over `diagnostics[0]` rather than a second
|
|
302
|
+
* source of truth.
|
|
303
|
+
*/
|
|
304
|
+
diagnostics;
|
|
140
305
|
constructor(diagnostic) {
|
|
141
|
-
|
|
306
|
+
const diagnostics = Array.isArray(diagnostic)
|
|
307
|
+
? diagnostic
|
|
308
|
+
: [diagnostic];
|
|
309
|
+
const first = diagnostics[0];
|
|
310
|
+
if (first === undefined) {
|
|
311
|
+
throw new TypeError('IdfParseError needs at least one diagnostic');
|
|
312
|
+
}
|
|
313
|
+
super(`${first.message} (line ${first.line})`);
|
|
142
314
|
this.name = 'IdfParseError';
|
|
143
|
-
this.line =
|
|
144
|
-
this.typeName =
|
|
315
|
+
this.line = first.line;
|
|
316
|
+
this.typeName = first.typeName;
|
|
317
|
+
this.diagnostics = Object.freeze([...diagnostics]);
|
|
145
318
|
}
|
|
146
319
|
}
|
|
147
320
|
/**
|
|
@@ -151,7 +324,7 @@ export class IdfParseError extends Error {
|
|
|
151
324
|
* version lives inside the file. This does the minimum scan needed to break
|
|
152
325
|
* the cycle, and does not validate anything else.
|
|
153
326
|
*/
|
|
154
|
-
export function
|
|
327
|
+
export function getIdfVersion(text) {
|
|
155
328
|
// Strip comments first. Trying to tolerate them inside the pattern means
|
|
156
329
|
// guessing how many comment lines sit between the comma and the value, which
|
|
157
330
|
// is exactly the kind of thing that works on the file you tested and fails on
|
package/dist/parse/idf.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"idf.js","sourceRoot":"","sources":["../../src/parse/idf.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAG7C,OAAO,EAAE,GAAG,EAAsC,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"idf.js","sourceRoot":"","sources":["../../src/parse/idf.ts"],"names":[],"mappings":"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"}
|
package/dist/parse/lexer.d.ts
CHANGED
|
@@ -6,11 +6,47 @@ export interface RawObject {
|
|
|
6
6
|
values: string[];
|
|
7
7
|
/** 1-based line where the object starts, for diagnostics. */
|
|
8
8
|
line: number;
|
|
9
|
+
/** 1-based column where the object starts, for diagnostics. */
|
|
10
|
+
column?: number;
|
|
11
|
+
/**
|
|
12
|
+
* Absolute offset of the object's first character in the source text.
|
|
13
|
+
*
|
|
14
|
+
* One number per object, so that a finding about a FIELD can be positioned without the lexer
|
|
15
|
+
* recording a line for every field of every object. The rescan that uses it runs only when a
|
|
16
|
+
* finding is being built.
|
|
17
|
+
*/
|
|
18
|
+
offset?: number;
|
|
9
19
|
}
|
|
10
20
|
export interface LexDiagnostic {
|
|
11
21
|
message: string;
|
|
12
22
|
line: number;
|
|
23
|
+
/**
|
|
24
|
+
* Machine-readable kind, from the vocabulary both libraries share.
|
|
25
|
+
*
|
|
26
|
+
* Derived from Python's exception hierarchy by dropping the `Error` suffix, so neither language
|
|
27
|
+
* invented it and the mapping stays mechanical. The conformance corpus compares a finding on
|
|
28
|
+
* `(code, line, typeName)` and never on `message`: wording is a presentation choice each library
|
|
29
|
+
* should stay free to improve, and pinning it would turn every improvement into a failure.
|
|
30
|
+
*/
|
|
31
|
+
code?: ParseDiagnosticCode;
|
|
32
|
+
/** 1-based column, when the lexer knew one. */
|
|
33
|
+
column?: number;
|
|
34
|
+
/** Path the text came from, when it came from a file rather than a string. */
|
|
35
|
+
filepath?: string;
|
|
36
|
+
/**
|
|
37
|
+
* Object type the problem occurred in, when known.
|
|
38
|
+
*
|
|
39
|
+
* Declared here rather than only on `ParseDiagnostic` because the lexer knows it too: an
|
|
40
|
+
* unterminated object has read its type name before it runs out of input, and a finding that
|
|
41
|
+
* drops it says only that something went wrong somewhere.
|
|
42
|
+
*/
|
|
43
|
+
typeName?: string;
|
|
13
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* The shared diagnostic vocabulary. The table lives in
|
|
47
|
+
* `idfkit-conformance/runners/compare.md`; a code outside it is a difference, not a near match.
|
|
48
|
+
*/
|
|
49
|
+
export type ParseDiagnosticCode = 'UnknownObjectType' | 'InvalidField' | 'Range' | 'DuplicateObject' | 'ParseError' | 'VersionMismatch' | 'UnsupportedVersion' | 'SchemaNotFound';
|
|
14
50
|
export interface LexOptions {
|
|
15
51
|
/** Report a problem instead of throwing. */
|
|
16
52
|
onDiagnostic?: (diagnostic: LexDiagnostic) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lexer.d.ts","sourceRoot":"","sources":["../../src/parse/lexer.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,MAAM,WAAW,SAAS;IACxB,qEAAqE;IACrE,QAAQ,EAAE,MAAM,CAAC;IACjB,8EAA8E;IAC9E,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,6DAA6D;IAC7D,IAAI,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"lexer.d.ts","sourceRoot":"","sources":["../../src/parse/lexer.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,MAAM,WAAW,SAAS;IACxB,qEAAqE;IACrE,QAAQ,EAAE,MAAM,CAAC;IACjB,8EAA8E;IAC9E,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,6DAA6D;IAC7D,IAAI,EAAE,MAAM,CAAC;IACb,+DAA+D;IAC/D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,mBAAmB,CAAC;IAC3B,+CAA+C;IAC/C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAC3B,mBAAmB,GACnB,cAAc,GACd,OAAO,GACP,iBAAiB,GACjB,YAAY,GACZ,iBAAiB,GACjB,oBAAoB,GACpB,gBAAgB,CAAC;AAErB,MAAM,WAAW,UAAU;IACzB,4CAA4C;IAC5C,YAAY,CAAC,EAAE,CAAC,UAAU,EAAE,aAAa,KAAK,IAAI,CAAC;CACpD;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,UAAe,GAAG,SAAS,EAAE,CAmJvE"}
|
package/dist/parse/lexer.js
CHANGED
|
@@ -29,6 +29,20 @@ export function lex(text, options = {}) {
|
|
|
29
29
|
let fieldStart = 0;
|
|
30
30
|
let objectLine = 1;
|
|
31
31
|
let objectStarted = false;
|
|
32
|
+
/** Offset of the first character of the current line, for turning an offset into a column. */
|
|
33
|
+
let lineStart = 0;
|
|
34
|
+
/**
|
|
35
|
+
* Column the current object's type name begins at, or 0 while none has been seen.
|
|
36
|
+
*
|
|
37
|
+
* The first NON-BLANK character, not the start of the field text: Python's regex matches the
|
|
38
|
+
* type name itself, so an object indented three spaces reports column 4 there and has to report
|
|
39
|
+
* column 4 here too, or the corpus compares two different notions of position.
|
|
40
|
+
*/
|
|
41
|
+
let objectColumn = 0;
|
|
42
|
+
/** Absolute offset of the current object's first non-blank character. */
|
|
43
|
+
let objectOffset = -1;
|
|
44
|
+
/** 1-based column of an offset on the line it falls in. Matches Python's `_line_and_column`. */
|
|
45
|
+
const columnAt = (offset) => offset - lineStart + 1;
|
|
32
46
|
const endField = (end) => {
|
|
33
47
|
chunks.push(text.slice(fieldStart, end));
|
|
34
48
|
const value = chunks.join('').trim();
|
|
@@ -37,6 +51,14 @@ export function lex(text, options = {}) {
|
|
|
37
51
|
};
|
|
38
52
|
while (index < length) {
|
|
39
53
|
const char = text[index];
|
|
54
|
+
// The first non-blank character of an object fixes where the object starts. Recorded here
|
|
55
|
+
// rather than at the delimiter, because by then the leading whitespace has been consumed and
|
|
56
|
+
// the offset that remains points at the padding rather than at the name.
|
|
57
|
+
if (objectColumn === 0 && char !== undefined && !/\s/.test(char)) {
|
|
58
|
+
objectLine = line;
|
|
59
|
+
objectColumn = columnAt(index);
|
|
60
|
+
objectOffset = index;
|
|
61
|
+
}
|
|
40
62
|
if (char === '!') {
|
|
41
63
|
// Preserve any field text seen before the comment, then resume after the
|
|
42
64
|
// newline. This is what lets `Zone1, !- Name` work: the comment is not
|
|
@@ -51,9 +73,12 @@ export function lex(text, options = {}) {
|
|
|
51
73
|
index = newline + 1;
|
|
52
74
|
fieldStart = index;
|
|
53
75
|
line += 1;
|
|
76
|
+
lineStart = index;
|
|
54
77
|
if (!objectStarted && chunks.join('').trim() === '') {
|
|
55
78
|
chunks = [];
|
|
56
79
|
objectLine = line;
|
|
80
|
+
objectColumn = 0;
|
|
81
|
+
objectOffset = -1;
|
|
57
82
|
}
|
|
58
83
|
continue;
|
|
59
84
|
}
|
|
@@ -70,18 +95,32 @@ export function lex(text, options = {}) {
|
|
|
70
95
|
fieldStart = index;
|
|
71
96
|
const typeName = values.shift() ?? '';
|
|
72
97
|
if (typeName === '') {
|
|
73
|
-
report?.({
|
|
98
|
+
report?.({
|
|
99
|
+
message: 'Object with no type name',
|
|
100
|
+
line: objectLine,
|
|
101
|
+
column: objectColumn || undefined,
|
|
102
|
+
code: 'ParseError',
|
|
103
|
+
});
|
|
74
104
|
}
|
|
75
105
|
else {
|
|
76
|
-
objects.push({
|
|
106
|
+
objects.push({
|
|
107
|
+
typeName,
|
|
108
|
+
values,
|
|
109
|
+
line: objectLine,
|
|
110
|
+
column: objectColumn || undefined,
|
|
111
|
+
offset: objectOffset >= 0 ? objectOffset : undefined,
|
|
112
|
+
});
|
|
77
113
|
}
|
|
78
114
|
values = [];
|
|
79
115
|
objectStarted = false;
|
|
80
116
|
objectLine = line;
|
|
117
|
+
objectColumn = 0;
|
|
118
|
+
objectOffset = -1;
|
|
81
119
|
continue;
|
|
82
120
|
}
|
|
83
121
|
if (char === '\n') {
|
|
84
122
|
line += 1;
|
|
123
|
+
lineStart = index + 1;
|
|
85
124
|
if (!objectStarted &&
|
|
86
125
|
chunks.join('').trim() === '' &&
|
|
87
126
|
text.slice(fieldStart, index).trim() === '') {
|
|
@@ -89,6 +128,8 @@ export function lex(text, options = {}) {
|
|
|
89
128
|
chunks = [];
|
|
90
129
|
fieldStart = index + 1;
|
|
91
130
|
objectLine = line;
|
|
131
|
+
objectColumn = 0;
|
|
132
|
+
objectOffset = -1;
|
|
92
133
|
}
|
|
93
134
|
}
|
|
94
135
|
index += 1;
|
|
@@ -98,6 +139,12 @@ export function lex(text, options = {}) {
|
|
|
98
139
|
report?.({
|
|
99
140
|
message: `Unterminated object near "${trailing.slice(0, 40) || values[0]}" (missing ";")`,
|
|
100
141
|
line: objectLine,
|
|
142
|
+
code: 'ParseError',
|
|
143
|
+
column: objectColumn || undefined,
|
|
144
|
+
// `values` has not been shifted, because the shift happens on `;` and there was none, so the
|
|
145
|
+
// type name is still at the front. Reporting it is what lets the corpus compare this finding
|
|
146
|
+
// against Python's on `(code, line, typeName)`.
|
|
147
|
+
typeName: values[0],
|
|
101
148
|
});
|
|
102
149
|
}
|
|
103
150
|
return objects;
|
package/dist/parse/lexer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lexer.js","sourceRoot":"","sources":["../../src/parse/lexer.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"lexer.js","sourceRoot":"","sources":["../../src/parse/lexer.ts"],"names":[],"mappings":"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"}
|
package/dist/typemap.d.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Version-specific static typing, with no runtime cost at all.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* object type plus a `TypeMap` joining type name to
|
|
6
|
-
* parameterized by that map resolves `doc.all('Zone')` to
|
|
7
|
-
* objects with `Zone`'s fields, and the editor completes among
|
|
8
|
-
* names as you type the string.
|
|
4
|
+
* An opt-in package (`@idfkit/types-v26-1`, one per EnergyPlus version) exports
|
|
5
|
+
* one interface per object type plus a `TypeMap` joining type name to
|
|
6
|
+
* interface. A document parameterized by that map resolves `doc.all('Zone')` to
|
|
7
|
+
* a collection of objects with `Zone`'s fields, and the editor completes among
|
|
8
|
+
* all 858 type names as you type the string. Install none of them and every
|
|
9
|
+
* document is an `UntypedMap`: nothing stops working, the field names are
|
|
10
|
+
* simply not checked.
|
|
9
11
|
*
|
|
10
12
|
* This is where JavaScript beats the Python original rather than imitating it.
|
|
11
13
|
* `__getattr__` resolves names at runtime, so an editor cannot see them and a
|
package/dist/typemap.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typemap.d.ts","sourceRoot":"","sources":["../src/typemap.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"typemap.d.ts","sourceRoot":"","sources":["../src/typemap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,6EAA6E;AAC7E,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAEhD,iDAAiD;AACjD,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AAE9C;;;;;;GAMG;AACH,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,UAAU,IAAI,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAElF,6EAA6E;AAC7E,MAAM,MAAM,QAAQ,CAAC,CAAC,SAAS,UAAU,EAAE,CAAC,SAAS,MAAM,IAAI,CAAC,SAAS,MAAM,CAAC,GAC5E,CAAC,CAAC,CAAC,CAAC,GACJ,UAAU,CAAC;AAEf;;;;;;;;;GASG;AACH,MAAM,MAAM,QAAQ,CAAC,CAAC,SAAS,UAAU,EAAE,CAAC,SAAS,MAAM,IAAI,CAAC,SAAS,MAAM,CAAC,GAC5E,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GACb,WAAW,CAAC"}
|
package/dist/typemap.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Version-specific static typing, with no runtime cost at all.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* object type plus a `TypeMap` joining type name to
|
|
6
|
-
* parameterized by that map resolves `doc.all('Zone')` to
|
|
7
|
-
* objects with `Zone`'s fields, and the editor completes among
|
|
8
|
-
* names as you type the string.
|
|
4
|
+
* An opt-in package (`@idfkit/types-v26-1`, one per EnergyPlus version) exports
|
|
5
|
+
* one interface per object type plus a `TypeMap` joining type name to
|
|
6
|
+
* interface. A document parameterized by that map resolves `doc.all('Zone')` to
|
|
7
|
+
* a collection of objects with `Zone`'s fields, and the editor completes among
|
|
8
|
+
* all 858 type names as you type the string. Install none of them and every
|
|
9
|
+
* document is an `UntypedMap`: nothing stops working, the field names are
|
|
10
|
+
* simply not checked.
|
|
9
11
|
*
|
|
10
12
|
* This is where JavaScript beats the Python original rather than imitating it.
|
|
11
13
|
* `__getattr__` resolves names at runtime, so an editor cannot see them and a
|
package/dist/typemap.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typemap.js","sourceRoot":"","sources":["../src/typemap.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"typemap.js","sourceRoot":"","sources":["../src/typemap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schema validation.
|
|
3
|
+
*
|
|
4
|
+
* Five names, matching the Python library's `idfkit.validation` one for one
|
|
5
|
+
* under the field-casing rule. Everything else in this directory is an
|
|
6
|
+
* implementation detail.
|
|
7
|
+
*/
|
|
8
|
+
export { validateDocument, validateObject } from './validate.js';
|
|
9
|
+
export { Severity } from './types.js';
|
|
10
|
+
export type { ValidationError, ValidationResult } from './types.js';
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/validate/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACjE,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schema validation.
|
|
3
|
+
*
|
|
4
|
+
* Five names, matching the Python library's `idfkit.validation` one for one
|
|
5
|
+
* under the field-casing rule. Everything else in this directory is an
|
|
6
|
+
* implementation detail.
|
|
7
|
+
*/
|
|
8
|
+
export { validateDocument, validateObject } from './validate.js';
|
|
9
|
+
export { Severity } from './types.js';
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/validate/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACjE,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The vocabulary validation reports in.
|
|
3
|
+
*
|
|
4
|
+
* A finding is a record, not a throw. The Python original names the type
|
|
5
|
+
* `ValidationError` and this port keeps that spelling, but nothing here is ever
|
|
6
|
+
* raised: a finding carries a severity and a location, and callers collect them
|
|
7
|
+
* into a `ValidationResult` and decide what to do. Naming it after an exception
|
|
8
|
+
* and then returning it is the one thing the naming register asks both
|
|
9
|
+
* libraries to keep in step, so the name stays.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Severity of a validation finding.
|
|
13
|
+
*
|
|
14
|
+
* Both a value and a type. The value gives the Python original's
|
|
15
|
+
* `Severity.ERROR` spelling; the type is the string union that a `'error'`
|
|
16
|
+
* literal satisfies, which is how the same three strings reach the wire in both
|
|
17
|
+
* languages. The strings themselves are load-bearing: the conformance corpus
|
|
18
|
+
* compares them across the two implementations.
|
|
19
|
+
*/
|
|
20
|
+
export declare const Severity: Readonly<{
|
|
21
|
+
readonly ERROR: "error";
|
|
22
|
+
readonly WARNING: "warning";
|
|
23
|
+
readonly INFO: "info";
|
|
24
|
+
}>;
|
|
25
|
+
export type Severity = (typeof Severity)[keyof typeof Severity];
|
|
26
|
+
/**
|
|
27
|
+
* One validation finding.
|
|
28
|
+
*
|
|
29
|
+
* `code` is the machine-readable part and is shared with the Python library
|
|
30
|
+
* verbatim (`E001`…`E010`, `W002`, `W003`). `message` is for a human and is
|
|
31
|
+
* *not* guaranteed identical across the two languages: number formatting and
|
|
32
|
+
* type names differ between the runtimes. Match on `code`.
|
|
33
|
+
*/
|
|
34
|
+
export interface ValidationError {
|
|
35
|
+
/** How serious the finding is. */
|
|
36
|
+
readonly severity: Severity;
|
|
37
|
+
/** Object type the finding was found on. */
|
|
38
|
+
readonly objType: string;
|
|
39
|
+
/** Object name the finding was found on. Empty for anonymous objects. */
|
|
40
|
+
readonly objName: string;
|
|
41
|
+
/** Field the finding concerns, or `undefined` when it concerns the object. */
|
|
42
|
+
readonly field: string | undefined;
|
|
43
|
+
/** Human-readable description. */
|
|
44
|
+
readonly message: string;
|
|
45
|
+
/** Machine-readable code, stable across languages. */
|
|
46
|
+
readonly code: string;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Everything one validation run found, split by severity.
|
|
50
|
+
*
|
|
51
|
+
* `isValid` and `totalIssues` are computed once when the result is built rather
|
|
52
|
+
* than being live properties, because the arrays are read-only.
|
|
53
|
+
*/
|
|
54
|
+
export interface ValidationResult {
|
|
55
|
+
readonly errors: readonly ValidationError[];
|
|
56
|
+
readonly warnings: readonly ValidationError[];
|
|
57
|
+
readonly info: readonly ValidationError[];
|
|
58
|
+
/** True when `errors` is empty. Warnings and info do not make a model invalid. */
|
|
59
|
+
readonly isValid: boolean;
|
|
60
|
+
/** `errors + warnings + info`. */
|
|
61
|
+
readonly totalIssues: number;
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/validate/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;;;;;;;GAQG;AACH,eAAO,MAAM,QAAQ;;;;EAIV,CAAC;AAEZ,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,QAAQ,CAAC,CAAC,MAAM,OAAO,QAAQ,CAAC,CAAC;AAEhE;;;;;;;GAOG;AACH,MAAM,WAAW,eAAe;IAC9B,kCAAkC;IAClC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,4CAA4C;IAC5C,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,yEAAyE;IACzE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,8EAA8E;IAC9E,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,kCAAkC;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,sDAAsD;IACtD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,MAAM,EAAE,SAAS,eAAe,EAAE,CAAC;IAC5C,QAAQ,CAAC,QAAQ,EAAE,SAAS,eAAe,EAAE,CAAC;IAC9C,QAAQ,CAAC,IAAI,EAAE,SAAS,eAAe,EAAE,CAAC;IAC1C,kFAAkF;IAClF,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,kCAAkC;IAClC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B"}
|