@ifc-lite/rules 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 +45 -0
- package/dist/engine/rule-engine-chunk.d.ts +25 -0
- package/dist/engine/rule-engine-chunk.d.ts.map +1 -0
- package/dist/engine/rule-engine-chunk.js +43 -0
- package/dist/engine/rule-engine-chunk.js.map +1 -0
- package/dist/engine/rule-engine-compare.d.ts +17 -0
- package/dist/engine/rule-engine-compare.d.ts.map +1 -0
- package/dist/engine/rule-engine-compare.js +69 -0
- package/dist/engine/rule-engine-compare.js.map +1 -0
- package/dist/engine/rule-engine-requirements.d.ts +37 -0
- package/dist/engine/rule-engine-requirements.d.ts.map +1 -0
- package/dist/engine/rule-engine-requirements.js +293 -0
- package/dist/engine/rule-engine-requirements.js.map +1 -0
- package/dist/engine/rule-engine-sets.d.ts +46 -0
- package/dist/engine/rule-engine-sets.d.ts.map +1 -0
- package/dist/engine/rule-engine-sets.js +298 -0
- package/dist/engine/rule-engine-sets.js.map +1 -0
- package/dist/engine/rule-engine-unit.d.ts +23 -0
- package/dist/engine/rule-engine-unit.d.ts.map +1 -0
- package/dist/engine/rule-engine-unit.js +64 -0
- package/dist/engine/rule-engine-unit.js.map +1 -0
- package/dist/engine/rule-engine.d.ts +29 -0
- package/dist/engine/rule-engine.d.ts.map +1 -0
- package/dist/engine/rule-engine.js +244 -0
- package/dist/engine/rule-engine.js.map +1 -0
- package/dist/filter/effective-filter-fields.d.ts +13 -0
- package/dist/filter/effective-filter-fields.d.ts.map +1 -0
- package/dist/filter/effective-filter-fields.js +44 -0
- package/dist/filter/effective-filter-fields.js.map +1 -0
- package/dist/filter/entity-predefined-type.d.ts +24 -0
- package/dist/filter/entity-predefined-type.d.ts.map +1 -0
- package/dist/filter/entity-predefined-type.js +34 -0
- package/dist/filter/entity-predefined-type.js.map +1 -0
- package/dist/filter/filter-evaluate-groups.d.ts +36 -0
- package/dist/filter/filter-evaluate-groups.d.ts.map +1 -0
- package/dist/filter/filter-evaluate-groups.js +111 -0
- package/dist/filter/filter-evaluate-groups.js.map +1 -0
- package/dist/filter/filter-evaluate-model-tag.d.ts +22 -0
- package/dist/filter/filter-evaluate-model-tag.d.ts.map +1 -0
- package/dist/filter/filter-evaluate-model-tag.js +35 -0
- package/dist/filter/filter-evaluate-model-tag.js.map +1 -0
- package/dist/filter/filter-evaluate-mutations.d.ts +51 -0
- package/dist/filter/filter-evaluate-mutations.d.ts.map +1 -0
- package/dist/filter/filter-evaluate-mutations.js +111 -0
- package/dist/filter/filter-evaluate-mutations.js.map +1 -0
- package/dist/filter/filter-evaluate-yield.d.ts +9 -0
- package/dist/filter/filter-evaluate-yield.d.ts.map +1 -0
- package/dist/filter/filter-evaluate-yield.js +32 -0
- package/dist/filter/filter-evaluate-yield.js.map +1 -0
- package/dist/filter/filter-evaluate.d.ts +120 -0
- package/dist/filter/filter-evaluate.d.ts.map +1 -0
- package/dist/filter/filter-evaluate.js +408 -0
- package/dist/filter/filter-evaluate.js.map +1 -0
- package/dist/filter/filter-group-rule.d.ts +23 -0
- package/dist/filter/filter-group-rule.d.ts.map +1 -0
- package/dist/filter/filter-group-rule.js +69 -0
- package/dist/filter/filter-group-rule.js.map +1 -0
- package/dist/filter/filter-groups.d.ts +65 -0
- package/dist/filter/filter-groups.d.ts.map +1 -0
- package/dist/filter/filter-groups.js +136 -0
- package/dist/filter/filter-groups.js.map +1 -0
- package/dist/filter/filter-iteration-source.d.ts +26 -0
- package/dist/filter/filter-iteration-source.d.ts.map +1 -0
- package/dist/filter/filter-iteration-source.js +154 -0
- package/dist/filter/filter-iteration-source.js.map +1 -0
- package/dist/filter/filter-iteration.d.ts +5 -0
- package/dist/filter/filter-iteration.d.ts.map +1 -0
- package/dist/filter/filter-iteration.js +25 -0
- package/dist/filter/filter-iteration.js.map +1 -0
- package/dist/filter/filter-match.d.ts +114 -0
- package/dist/filter/filter-match.d.ts.map +1 -0
- package/dist/filter/filter-match.js +302 -0
- package/dist/filter/filter-match.js.map +1 -0
- package/dist/filter/filter-ops.d.ts +90 -0
- package/dist/filter/filter-ops.d.ts.map +1 -0
- package/dist/filter/filter-ops.js +202 -0
- package/dist/filter/filter-ops.js.map +1 -0
- package/dist/filter/filter-rule-guards.d.ts +4 -0
- package/dist/filter/filter-rule-guards.d.ts.map +1 -0
- package/dist/filter/filter-rule-guards.js +74 -0
- package/dist/filter/filter-rule-guards.js.map +1 -0
- package/dist/filter/filter-rules.d.ts +275 -0
- package/dist/filter/filter-rules.d.ts.map +1 -0
- package/dist/filter/filter-rules.js +68 -0
- package/dist/filter/filter-rules.js.map +1 -0
- package/dist/filter/lens-material-names.d.ts +13 -0
- package/dist/filter/lens-material-names.d.ts.map +1 -0
- package/dist/filter/lens-material-names.js +36 -0
- package/dist/filter/lens-material-names.js.map +1 -0
- package/dist/filter/measure-units.d.ts +29 -0
- package/dist/filter/measure-units.d.ts.map +1 -0
- package/dist/filter/measure-units.js +72 -0
- package/dist/filter/measure-units.js.map +1 -0
- package/dist/filter/model-tag.d.ts +65 -0
- package/dist/filter/model-tag.d.ts.map +1 -0
- package/dist/filter/model-tag.js +57 -0
- package/dist/filter/model-tag.js.map +1 -0
- package/dist/filter/read-measure-subject.d.ts +28 -0
- package/dist/filter/read-measure-subject.d.ts.map +1 -0
- package/dist/filter/read-measure-subject.js +116 -0
- package/dist/filter/read-measure-subject.js.map +1 -0
- package/dist/filter/read-subject.d.ts +72 -0
- package/dist/filter/read-subject.d.ts.map +1 -0
- package/dist/filter/read-subject.js +128 -0
- package/dist/filter/read-subject.js.map +1 -0
- package/dist/filter/subject-match.d.ts +27 -0
- package/dist/filter/subject-match.d.ts.map +1 -0
- package/dist/filter/subject-match.js +52 -0
- package/dist/filter/subject-match.js.map +1 -0
- package/dist/filter/subject-read-options.d.ts +33 -0
- package/dist/filter/subject-read-options.d.ts.map +1 -0
- package/dist/filter/subject-read-options.js +8 -0
- package/dist/filter/subject-read-options.js.map +1 -0
- package/dist/ids/ids-facet-to-rules.d.ts +20 -0
- package/dist/ids/ids-facet-to-rules.d.ts.map +1 -0
- package/dist/ids/ids-facet-to-rules.js +230 -0
- package/dist/ids/ids-facet-to-rules.js.map +1 -0
- package/dist/ids/ids-regex.d.ts +44 -0
- package/dist/ids/ids-regex.d.ts.map +1 -0
- package/dist/ids/ids-regex.js +334 -0
- package/dist/ids/ids-regex.js.map +1 -0
- package/dist/ids/ids-to-rule-set.d.ts +39 -0
- package/dist/ids/ids-to-rule-set.d.ts.map +1 -0
- package/dist/ids/ids-to-rule-set.js +103 -0
- package/dist/ids/ids-to-rule-set.js.map +1 -0
- package/dist/ids/ids-xml-writer.d.ts +11 -0
- package/dist/ids/ids-xml-writer.d.ts.map +1 -0
- package/dist/ids/ids-xml-writer.js +172 -0
- package/dist/ids/ids-xml-writer.js.map +1 -0
- package/dist/ids/rule-set-to-ids.d.ts +45 -0
- package/dist/ids/rule-set-to-ids.d.ts.map +1 -0
- package/dist/ids/rule-set-to-ids.js +140 -0
- package/dist/ids/rule-set-to-ids.js.map +1 -0
- package/dist/ids/rule-to-ids-facets.d.ts +52 -0
- package/dist/ids/rule-to-ids-facets.d.ts.map +1 -0
- package/dist/ids/rule-to-ids-facets.js +291 -0
- package/dist/ids/rule-to-ids-facets.js.map +1 -0
- package/dist/ids/stored-unit-scale.d.ts +15 -0
- package/dist/ids/stored-unit-scale.d.ts.map +1 -0
- package/dist/ids/stored-unit-scale.js +64 -0
- package/dist/ids/stored-unit-scale.js.map +1 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +46 -0
- package/dist/index.js.map +1 -0
- package/dist/rule-set/between-chip.d.ts +54 -0
- package/dist/rule-set/between-chip.d.ts.map +1 -0
- package/dist/rule-set/between-chip.js +95 -0
- package/dist/rule-set/between-chip.js.map +1 -0
- package/dist/rule-set/requirement-invariants.d.ts +25 -0
- package/dist/rule-set/requirement-invariants.d.ts.map +1 -0
- package/dist/rule-set/requirement-invariants.js +29 -0
- package/dist/rule-set/requirement-invariants.js.map +1 -0
- package/dist/rule-set/requirement-text.d.ts +20 -0
- package/dist/rule-set/requirement-text.d.ts.map +1 -0
- package/dist/rule-set/requirement-text.js +179 -0
- package/dist/rule-set/requirement-text.js.map +1 -0
- package/dist/rule-set/rule-set-io-requirement.d.ts +22 -0
- package/dist/rule-set/rule-set-io-requirement.d.ts.map +1 -0
- package/dist/rule-set/rule-set-io-requirement.js +140 -0
- package/dist/rule-set/rule-set-io-requirement.js.map +1 -0
- package/dist/rule-set/rule-set-io-shared.d.ts +24 -0
- package/dist/rule-set/rule-set-io-shared.d.ts.map +1 -0
- package/dist/rule-set/rule-set-io-shared.js +48 -0
- package/dist/rule-set/rule-set-io-shared.js.map +1 -0
- package/dist/rule-set/rule-set-io-subject.d.ts +10 -0
- package/dist/rule-set/rule-set-io-subject.d.ts.map +1 -0
- package/dist/rule-set/rule-set-io-subject.js +67 -0
- package/dist/rule-set/rule-set-io-subject.js.map +1 -0
- package/dist/rule-set/rule-set-io.d.ts +37 -0
- package/dist/rule-set/rule-set-io.d.ts.map +1 -0
- package/dist/rule-set/rule-set-io.js +142 -0
- package/dist/rule-set/rule-set-io.js.map +1 -0
- package/dist/rule-set/rule-set.d.ts +109 -0
- package/dist/rule-set/rule-set.d.ts.map +1 -0
- package/dist/rule-set/rule-set.js +5 -0
- package/dist/rule-set/rule-set.js.map +1 -0
- package/package.json +59 -0
|
@@ -0,0 +1,48 @@
|
|
|
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
|
+
* Shared plumbing for the `rule-set-io-*.ts` split (#5138): the exception
|
|
6
|
+
* type `parseRuleSetFile` catches to turn any failure into `{ ok: false,
|
|
7
|
+
* error }`, small JSON-shape guards, and the one-warning-per-parse budget
|
|
8
|
+
* for unknown optional fields (plan §3 forward-compat posture). Split out
|
|
9
|
+
* of `rule-set-io.ts` purely to stay under the ~400-line module cap — the
|
|
10
|
+
* parse logic is one recursive-descent pass over one file format, not
|
|
11
|
+
* several independent modules.
|
|
12
|
+
*/
|
|
13
|
+
/** Thrown by every `parseX` helper on a validation failure; caught once at
|
|
14
|
+
* the top of `parseRuleSetFile` and turned into `{ ok: false, error }`.
|
|
15
|
+
* Never escapes this package. */
|
|
16
|
+
export class RuleSetError extends Error {
|
|
17
|
+
}
|
|
18
|
+
export function fail(message) {
|
|
19
|
+
throw new RuleSetError(message);
|
|
20
|
+
}
|
|
21
|
+
export function isPlainObject(v) {
|
|
22
|
+
return typeof v === 'object' && v !== null && !Array.isArray(v);
|
|
23
|
+
}
|
|
24
|
+
export function isStringArray(v) {
|
|
25
|
+
return Array.isArray(v) && v.every((x) => typeof x === 'string');
|
|
26
|
+
}
|
|
27
|
+
export function unknownKeysOf(obj, known) {
|
|
28
|
+
return Object.keys(obj).filter((k) => !known.includes(k));
|
|
29
|
+
}
|
|
30
|
+
/** Whether the one-warning-per-parse budget has been spent. Reset by
|
|
31
|
+
* `resetWarnBudget()` at the top of every `parseRuleSetFile` call — this
|
|
32
|
+
* module has exactly one entry point that resets it, and node:test/the
|
|
33
|
+
* browser both run it single-threaded, so a concurrent parse never
|
|
34
|
+
* interleaves with another's budget. */
|
|
35
|
+
let warnedThisParse = false;
|
|
36
|
+
export function resetWarnBudget() {
|
|
37
|
+
warnedThisParse = false;
|
|
38
|
+
}
|
|
39
|
+
/** Warn once, for the whole parse, that unknown OPTIONAL fields were
|
|
40
|
+
* dropped — never for an unknown top-level key, which is a hard reject
|
|
41
|
+
* (`fail`), not a warning. */
|
|
42
|
+
export function warnUnknownFields(context, unknown) {
|
|
43
|
+
if (unknown.length === 0 || warnedThisParse)
|
|
44
|
+
return;
|
|
45
|
+
warnedThisParse = true;
|
|
46
|
+
console.warn(`[rule-set] ${context}: ignoring unknown field(s) ${unknown.join(', ')}`);
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=rule-set-io-shared.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rule-set-io-shared.js","sourceRoot":"","sources":["../../src/rule-set/rule-set-io-shared.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D;;;;;;;;GAQG;AAEH;;kCAEkC;AAClC,MAAM,OAAO,YAAa,SAAQ,KAAK;CAAG;AAE1C,MAAM,UAAU,IAAI,CAAC,OAAe;IAClC,MAAM,IAAI,YAAY,CAAC,OAAO,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,CAAU;IACtC,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AAClE,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,CAAU;IACtC,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,GAA4B,EAAE,KAAwB;IAClF,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;AAC5D,CAAC;AAED;;;;yCAIyC;AACzC,IAAI,eAAe,GAAG,KAAK,CAAC;AAE5B,MAAM,UAAU,eAAe;IAC7B,eAAe,GAAG,KAAK,CAAC;AAC1B,CAAC;AAED;;+BAE+B;AAC/B,MAAM,UAAU,iBAAiB,CAAC,OAAe,EAAE,OAAiB;IAClE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,eAAe;QAAE,OAAO;IACpD,eAAe,GAAG,IAAI,CAAC;IACvB,OAAO,CAAC,IAAI,CAAC,cAAc,OAAO,+BAA+B,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACzF,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `Subject` parsing for `.rules.json` files (#5138). Split out of
|
|
3
|
+
* `rule-set-io.ts` to stay under the module-size cap — subjects are the
|
|
4
|
+
* one shape every requirement kind (`unique`/`aggregate`/`compare`) shares,
|
|
5
|
+
* so it earns its own file rather than living inside any one of them.
|
|
6
|
+
*/
|
|
7
|
+
import type { Subject } from './rule-set.js';
|
|
8
|
+
export declare function isSingleValuedSubject(subject: Subject): boolean;
|
|
9
|
+
export declare function parseSubject(raw: unknown, where: string): Subject;
|
|
10
|
+
//# sourceMappingURL=rule-set-io-subject.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rule-set-io-subject.d.ts","sourceRoot":"","sources":["../../src/rule-set/rule-set-io-subject.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAiB7C,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAE/D;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAuCjE"}
|
|
@@ -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
|
+
import { fail, isPlainObject } from './rule-set-io-shared.js';
|
|
5
|
+
const TEXT_KINDS = new Set(['literal', 'regex']);
|
|
6
|
+
const SUBJECT_KINDS = new Set([
|
|
7
|
+
'attribute', 'property', 'quantity', 'classification', 'group',
|
|
8
|
+
'name', 'material', 'storey', 'parent', 'type', 'ifcType', 'predefinedType', 'globalId',
|
|
9
|
+
]);
|
|
10
|
+
/** Subject kinds that carry more than one value per element (an element can
|
|
11
|
+
* have several materials, classification refs, spatial ancestors, or groups).
|
|
12
|
+
* `sum|min|max|avg`/`compare` need a single number or string to read —
|
|
13
|
+
* plan §3; multi-valued subjects are only meaningful as a bucketing key
|
|
14
|
+
* (`unique`, `count`, `groupBy`). */
|
|
15
|
+
const MULTI_VALUED_SUBJECT_KINDS = new Set(['material', 'classification', 'parent', 'group']);
|
|
16
|
+
export function isSingleValuedSubject(subject) {
|
|
17
|
+
return !MULTI_VALUED_SUBJECT_KINDS.has(subject.kind);
|
|
18
|
+
}
|
|
19
|
+
export function parseSubject(raw, where) {
|
|
20
|
+
if (!isPlainObject(raw))
|
|
21
|
+
fail(`${where}: subject must be an object`);
|
|
22
|
+
const s = raw;
|
|
23
|
+
const kind = s.kind;
|
|
24
|
+
if (typeof kind !== 'string' || !SUBJECT_KINDS.has(kind))
|
|
25
|
+
fail(`${where}: unrecognised subject kind ${JSON.stringify(kind)}`);
|
|
26
|
+
if (kind === 'attribute') {
|
|
27
|
+
if (typeof s.name !== 'string' || s.name.length === 0)
|
|
28
|
+
fail(`${where}: attribute subject needs "name"`);
|
|
29
|
+
return { kind: 'attribute', name: s.name };
|
|
30
|
+
}
|
|
31
|
+
if (kind === 'property' || kind === 'quantity') {
|
|
32
|
+
const nameField = kind === 'property' ? 'propertyName' : 'quantityName';
|
|
33
|
+
const nameKindField = kind === 'property' ? 'propertyNameKind' : 'quantityNameKind';
|
|
34
|
+
if (typeof s.setName !== 'string' || s.setName.length === 0)
|
|
35
|
+
fail(`${where}: ${kind} subject needs "setName"`);
|
|
36
|
+
if (typeof s[nameField] !== 'string' || s[nameField].length === 0) {
|
|
37
|
+
fail(`${where}: ${kind} subject needs "${nameField}"`);
|
|
38
|
+
}
|
|
39
|
+
if (s.setNameKind !== undefined && !TEXT_KINDS.has(s.setNameKind))
|
|
40
|
+
fail(`${where}: bad "setNameKind"`);
|
|
41
|
+
if (s[nameKindField] !== undefined && !TEXT_KINDS.has(s[nameKindField]))
|
|
42
|
+
fail(`${where}: bad "${nameKindField}"`);
|
|
43
|
+
if (s.inherit !== undefined && s.inherit !== 'type' && s.inherit !== 'aggregation')
|
|
44
|
+
fail(`${where}: bad "inherit"`);
|
|
45
|
+
return {
|
|
46
|
+
...(s.inherit !== undefined ? { inherit: s.inherit } : {}),
|
|
47
|
+
kind,
|
|
48
|
+
setName: s.setName,
|
|
49
|
+
...(s.setNameKind !== undefined ? { setNameKind: s.setNameKind } : {}),
|
|
50
|
+
[nameField]: s[nameField],
|
|
51
|
+
...(s[nameKindField] !== undefined ? { [nameKindField]: s[nameKindField] } : {}),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
if (kind === 'classification') {
|
|
55
|
+
if (s.system !== undefined && typeof s.system !== 'string')
|
|
56
|
+
fail(`${where}: "system" must be a string`);
|
|
57
|
+
return { kind: 'classification', ...(s.system !== undefined ? { system: s.system } : {}) };
|
|
58
|
+
}
|
|
59
|
+
if (kind === 'group') {
|
|
60
|
+
if (s.groupClass !== undefined && typeof s.groupClass !== 'string')
|
|
61
|
+
fail(`${where}: "groupClass" must be a string`);
|
|
62
|
+
return { kind: 'group', ...(s.groupClass ? { groupClass: s.groupClass } : {}) };
|
|
63
|
+
}
|
|
64
|
+
// Bare-kind subjects: name/material/storey/parent/type/ifcType/predefinedType/globalId.
|
|
65
|
+
return { kind };
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=rule-set-io-subject.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rule-set-io-subject.js","sourceRoot":"","sources":["../../src/rule-set/rule-set-io-subject.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse/validate/serialize a `<name>.rules.json` file (#5138 plan §3).
|
|
3
|
+
*
|
|
4
|
+
* `parseRuleSetFile` never throws on bad input — every failure comes back
|
|
5
|
+
* as `{ ok: false, error }`, the same posture `delivery-recipe.ts` and the
|
|
6
|
+
* clash-preset loader use for a saved-definition file a human can hand-edit.
|
|
7
|
+
* Forward compat is deliberately asymmetric: an unknown TOP-LEVEL key or a
|
|
8
|
+
* `version` newer than this build rejects the whole file (we cannot know
|
|
9
|
+
* what a newer version's semantics are), while an unknown OPTIONAL field
|
|
10
|
+
* nested inside an `InformationRule`/`RuleBlock` is additive by design and
|
|
11
|
+
* is dropped with exactly one `console.warn` for the whole parse, not one
|
|
12
|
+
* per occurrence — a rule set can carry dozens of rules and warning once
|
|
13
|
+
* per field would drown the one thing worth telling the author.
|
|
14
|
+
*
|
|
15
|
+
* `Subject` parsing lives in `rule-set-io-subject.ts` and
|
|
16
|
+
* `RuleBlock`/`Requirement` parsing in `rule-set-io-requirement.ts` — split
|
|
17
|
+
* out to stay under the module-size cap; this file owns the top-level
|
|
18
|
+
* `RuleSetFile` shape plus parse/serialize. `exportRuleSet`/`importRuleSetFile`
|
|
19
|
+
* (DOM: `downloadFile`, `FileReader`) are NOT here — #5138 PR 7a moved the
|
|
20
|
+
* rest of this module into `@ifc-lite/rules`, but those two stayed in the
|
|
21
|
+
* viewer as `apps/viewer/src/lib/validation/rule-set-io-browser.ts`, which
|
|
22
|
+
* calls back into `parseRuleSetFile`/`serializeRuleSet` below.
|
|
23
|
+
*/
|
|
24
|
+
import type { RuleSetFile } from './rule-set.js';
|
|
25
|
+
export type RuleSetParseResult = {
|
|
26
|
+
ok: true;
|
|
27
|
+
file: RuleSetFile;
|
|
28
|
+
} | {
|
|
29
|
+
ok: false;
|
|
30
|
+
error: string;
|
|
31
|
+
};
|
|
32
|
+
/** Parse/validate an unknown JSON value into a `RuleSetFile`. Never throws —
|
|
33
|
+
* every rejection reason (unknown top-level key, a version this build does
|
|
34
|
+
* not understand, a malformed rule) comes back as `error`. */
|
|
35
|
+
export declare function parseRuleSetFile(raw: unknown): RuleSetParseResult;
|
|
36
|
+
export declare function serializeRuleSet(file: RuleSetFile): string;
|
|
37
|
+
//# sourceMappingURL=rule-set-io.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rule-set-io.d.ts","sourceRoot":"","sources":["../../src/rule-set/rule-set-io.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAmC,MAAM,eAAe,CAAC;AAKlF,MAAM,MAAM,kBAAkB,GAC1B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,WAAW,CAAA;CAAE,GAC/B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AA6FjC;;+DAE+D;AAC/D,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,GAAG,kBAAkB,CAmCjE;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,CAE1D"}
|
|
@@ -0,0 +1,142 @@
|
|
|
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 { RULE_SET_VERSION } from './rule-set.js';
|
|
5
|
+
import { fail, isPlainObject, isStringArray, unknownKeysOf, warnUnknownFields, resetWarnBudget, RuleSetError } from './rule-set-io-shared.js';
|
|
6
|
+
import { parseRuleBlock, parseRequirement } from './rule-set-io-requirement.js';
|
|
7
|
+
const SEVERITIES = new Set(['error', 'warning']);
|
|
8
|
+
// ── targets ──────────────────────────────────────────────────────────────────
|
|
9
|
+
function parseTargets(raw) {
|
|
10
|
+
if (raw === undefined)
|
|
11
|
+
return undefined;
|
|
12
|
+
if (!isPlainObject(raw))
|
|
13
|
+
fail('"targets" must be an object');
|
|
14
|
+
const t = raw;
|
|
15
|
+
const out = {};
|
|
16
|
+
// Opaque strings only — never resolved to a runtime model id here. A
|
|
17
|
+
// fingerprint/tag id that no longer matches anything is the run-time
|
|
18
|
+
// engine's problem (it matches nothing), not a load-time error.
|
|
19
|
+
if ('modelFingerprints' in t) {
|
|
20
|
+
if (!isStringArray(t.modelFingerprints))
|
|
21
|
+
fail('"targets.modelFingerprints" must be an array of strings');
|
|
22
|
+
out.modelFingerprints = t.modelFingerprints;
|
|
23
|
+
}
|
|
24
|
+
if ('modelTagIds' in t) {
|
|
25
|
+
if (!isStringArray(t.modelTagIds))
|
|
26
|
+
fail('"targets.modelTagIds" must be an array of strings');
|
|
27
|
+
out.modelTagIds = t.modelTagIds;
|
|
28
|
+
}
|
|
29
|
+
return out;
|
|
30
|
+
}
|
|
31
|
+
// ── information rule ─────────────────────────────────────────────────────────
|
|
32
|
+
const INFORMATION_RULE_FIELDS = [
|
|
33
|
+
'id', 'name', 'description', 'severity', 'applicability', 'requirement',
|
|
34
|
+
'cardinality', 'caseSensitive', 'tolerance',
|
|
35
|
+
];
|
|
36
|
+
function parseInformationRule(raw, index) {
|
|
37
|
+
const where = `rules[${index}]`;
|
|
38
|
+
if (!isPlainObject(raw))
|
|
39
|
+
fail(`${where}: must be an object`);
|
|
40
|
+
const r = raw;
|
|
41
|
+
// Legacy shape (pre-#5138 draft carried a `requirements: RuleBlock`
|
|
42
|
+
// singular field, later renamed/generalised to `requirement: Requirement`).
|
|
43
|
+
// No silent migration — the semantics changed (a bare block vs. the
|
|
44
|
+
// kind-tagged union), so a caller must re-author, not get a guessed
|
|
45
|
+
// conversion.
|
|
46
|
+
if ('requirements' in r && !('requirement' in r)) {
|
|
47
|
+
fail(`${where}: found legacy "requirements" field — renamed to "requirement" (#5138), no automatic migration`);
|
|
48
|
+
}
|
|
49
|
+
if (typeof r.id !== 'string' || r.id.length === 0)
|
|
50
|
+
fail(`${where}: "id" is required`);
|
|
51
|
+
if (typeof r.name !== 'string' || r.name.length === 0)
|
|
52
|
+
fail(`${where}: "name" is required`);
|
|
53
|
+
if (r.description !== undefined && typeof r.description !== 'string')
|
|
54
|
+
fail(`${where}: "description" must be a string`);
|
|
55
|
+
if (r.severity !== undefined && !SEVERITIES.has(r.severity))
|
|
56
|
+
fail(`${where}: bad "severity"`);
|
|
57
|
+
if (r.caseSensitive !== undefined && typeof r.caseSensitive !== 'boolean')
|
|
58
|
+
fail(`${where}: "caseSensitive" must be a boolean`);
|
|
59
|
+
let tolerance;
|
|
60
|
+
if (r.tolerance !== undefined) {
|
|
61
|
+
if (typeof r.tolerance !== 'number' || !Number.isFinite(r.tolerance))
|
|
62
|
+
fail(`${where}: "tolerance" must be a finite number`);
|
|
63
|
+
tolerance = Math.max(0, r.tolerance);
|
|
64
|
+
}
|
|
65
|
+
let cardinality;
|
|
66
|
+
if (r.cardinality !== undefined) {
|
|
67
|
+
if (!isPlainObject(r.cardinality))
|
|
68
|
+
fail(`${where}.cardinality: must be an object`);
|
|
69
|
+
const c = r.cardinality;
|
|
70
|
+
cardinality = {};
|
|
71
|
+
if (c.minApplicable !== undefined) {
|
|
72
|
+
if (typeof c.minApplicable !== 'number' || !Number.isFinite(c.minApplicable))
|
|
73
|
+
fail(`${where}.cardinality: "minApplicable" must be a finite number`);
|
|
74
|
+
cardinality.minApplicable = Math.max(0, c.minApplicable);
|
|
75
|
+
}
|
|
76
|
+
if (c.maxApplicable !== undefined) {
|
|
77
|
+
if (typeof c.maxApplicable !== 'number' || !Number.isFinite(c.maxApplicable))
|
|
78
|
+
fail(`${where}.cardinality: "maxApplicable" must be a finite number`);
|
|
79
|
+
cardinality.maxApplicable = Math.max(0, c.maxApplicable);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
const applicability = parseRuleBlock(r.applicability, `${where}.applicability`, null);
|
|
83
|
+
const requirement = parseRequirement(r.requirement, `${where}.requirement`);
|
|
84
|
+
warnUnknownFields(where, unknownKeysOf(r, INFORMATION_RULE_FIELDS));
|
|
85
|
+
return {
|
|
86
|
+
id: r.id, name: r.name,
|
|
87
|
+
...(r.description !== undefined ? { description: r.description } : {}),
|
|
88
|
+
...(r.severity !== undefined ? { severity: r.severity } : {}),
|
|
89
|
+
applicability, requirement,
|
|
90
|
+
...(cardinality ? { cardinality } : {}),
|
|
91
|
+
...(r.caseSensitive !== undefined ? { caseSensitive: r.caseSensitive } : {}),
|
|
92
|
+
...(tolerance !== undefined ? { tolerance } : {}),
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
// ── top level ────────────────────────────────────────────────────────────────
|
|
96
|
+
const RULE_SET_FIELDS = ['version', 'name', 'description', 'targets', 'rules'];
|
|
97
|
+
/** Parse/validate an unknown JSON value into a `RuleSetFile`. Never throws —
|
|
98
|
+
* every rejection reason (unknown top-level key, a version this build does
|
|
99
|
+
* not understand, a malformed rule) comes back as `error`. */
|
|
100
|
+
export function parseRuleSetFile(raw) {
|
|
101
|
+
resetWarnBudget();
|
|
102
|
+
try {
|
|
103
|
+
if (!isPlainObject(raw))
|
|
104
|
+
fail('a rule set file must be a JSON object');
|
|
105
|
+
const obj = raw;
|
|
106
|
+
const unknownTop = unknownKeysOf(obj, RULE_SET_FIELDS);
|
|
107
|
+
if (unknownTop.length > 0)
|
|
108
|
+
fail(`unrecognised top-level field(s): ${unknownTop.join(', ')}`);
|
|
109
|
+
if (typeof obj.version !== 'number')
|
|
110
|
+
fail('"version" must be a number');
|
|
111
|
+
if (obj.version > RULE_SET_VERSION) {
|
|
112
|
+
fail(`this file was created by a newer rule-set format (version ${obj.version}); this build only understands version ${RULE_SET_VERSION}`);
|
|
113
|
+
}
|
|
114
|
+
if (obj.version !== RULE_SET_VERSION)
|
|
115
|
+
fail(`unsupported "version" ${obj.version}, expected ${RULE_SET_VERSION}`);
|
|
116
|
+
if (typeof obj.name !== 'string' || obj.name.length === 0)
|
|
117
|
+
fail('"name" is required');
|
|
118
|
+
if (obj.description !== undefined && typeof obj.description !== 'string')
|
|
119
|
+
fail('"description" must be a string');
|
|
120
|
+
const targets = parseTargets(obj.targets);
|
|
121
|
+
if (!Array.isArray(obj.rules))
|
|
122
|
+
fail('"rules" must be an array');
|
|
123
|
+
const rules = obj.rules.map((r, i) => parseInformationRule(r, i));
|
|
124
|
+
const file = {
|
|
125
|
+
version: RULE_SET_VERSION,
|
|
126
|
+
name: obj.name,
|
|
127
|
+
...(obj.description !== undefined ? { description: obj.description } : {}),
|
|
128
|
+
...(targets ? { targets } : {}),
|
|
129
|
+
rules,
|
|
130
|
+
};
|
|
131
|
+
return { ok: true, file };
|
|
132
|
+
}
|
|
133
|
+
catch (err) {
|
|
134
|
+
if (err instanceof RuleSetError)
|
|
135
|
+
return { ok: false, error: err.message };
|
|
136
|
+
return { ok: false, error: `Failed to parse rule set: ${err.message}` };
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
export function serializeRuleSet(file) {
|
|
140
|
+
return JSON.stringify(file, null, 2);
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=rule-set-io.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rule-set-io.js","sourceRoot":"","sources":["../../src/rule-set/rule-set-io.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `<name>.rules.json` file format for information validation (#5138).
|
|
3
|
+
*
|
|
4
|
+
* Rules are authored in the `FilterRule` vocabulary applicability already
|
|
5
|
+
* uses (`lib/search`), not a second grammar — this module only adds the
|
|
6
|
+
* shapes the search chips/selector do not need: a requirement (what has to
|
|
7
|
+
* be true of the applicable set), and the `unique`/`aggregate`/`compare`
|
|
8
|
+
* kinds that buildingSMART's own IDS 1.0 cannot express (plan §2). Subjects
|
|
9
|
+
* are never redefined here; `Subject` is a `FilterRule` minus its operator,
|
|
10
|
+
* so `readSubject` (PR 3) and the rule editor (PR 5) share one taxonomy with
|
|
11
|
+
* search.
|
|
12
|
+
*
|
|
13
|
+
* `rule-set-io.ts` (parse/validate/serialize/export) and
|
|
14
|
+
* `requirement-text.ts` (the `unique`/`aggregate`/`compare` text grammar)
|
|
15
|
+
* are the other two modules in this package; this one is pure types plus
|
|
16
|
+
* the version constant, so every consumer can import it without pulling in
|
|
17
|
+
* `JSON.parse` or DOM download machinery.
|
|
18
|
+
*/
|
|
19
|
+
import type { AttributeRule, PropertyRule, QuantityRule, ClassificationRule, GroupRule, NumericOp } from '../filter/filter-rules.js';
|
|
20
|
+
import type { FilterGroup } from '../filter/filter-groups.js';
|
|
21
|
+
export declare const RULE_SET_VERSION: 1;
|
|
22
|
+
export interface RuleSetFile {
|
|
23
|
+
version: typeof RULE_SET_VERSION;
|
|
24
|
+
name: string;
|
|
25
|
+
description?: string;
|
|
26
|
+
/** Persisted default target; the run-time picker can override. */
|
|
27
|
+
targets?: RuleSetTargets;
|
|
28
|
+
rules: InformationRule[];
|
|
29
|
+
}
|
|
30
|
+
/** Never a local model id. Both lists are OR-ed; empty/absent = every loaded model. */
|
|
31
|
+
export interface RuleSetTargets {
|
|
32
|
+
/** `model.sourceFingerprint` values (= `EvaluatorModel.filterIdentity`, what `ModelRule.values` already match on). */
|
|
33
|
+
modelFingerprints?: string[];
|
|
34
|
+
/** `ModelTagRule.tagIds` (#4215). Unresolved ids match nothing, never "all". */
|
|
35
|
+
modelTagIds?: string[];
|
|
36
|
+
}
|
|
37
|
+
export interface InformationRule {
|
|
38
|
+
id: string;
|
|
39
|
+
name: string;
|
|
40
|
+
description?: string;
|
|
41
|
+
severity?: 'error' | 'warning';
|
|
42
|
+
/** Which elements the rule applies to. Groups OR-ed, rules inside AND/OR per group.
|
|
43
|
+
* `ifcType` rules may carry `exactClass`. */
|
|
44
|
+
applicability: RuleBlock;
|
|
45
|
+
requirement: Requirement;
|
|
46
|
+
cardinality?: {
|
|
47
|
+
minApplicable?: number;
|
|
48
|
+
maxApplicable?: number;
|
|
49
|
+
};
|
|
50
|
+
/** IDS is case-sensitive (bSI #346); default true. Applies to eq/ne/contains/notContains/in/notIn
|
|
51
|
+
* and to unique/groupBy keys. Regex flags remain the author's; globalId is always exact. */
|
|
52
|
+
caseSensitive?: boolean;
|
|
53
|
+
/** Relative tolerance for numeric eq/ne/gte/lte; default 1e-6 (bSI #418). */
|
|
54
|
+
tolerance?: number;
|
|
55
|
+
}
|
|
56
|
+
export interface RuleBlock {
|
|
57
|
+
groups: FilterGroup[];
|
|
58
|
+
/** How the block was last edited; editor reopens in that mode. */
|
|
59
|
+
authoredAs: 'chips' | 'selector';
|
|
60
|
+
}
|
|
61
|
+
export type Requirement = {
|
|
62
|
+
kind: 'element';
|
|
63
|
+
block: RuleBlock;
|
|
64
|
+
} | UniqueRequirement | AggregateRequirement | CompareRequirement | UnitRequirement;
|
|
65
|
+
/** A FilterRule minus its operator/operand — the exact input `readSubject` takes. */
|
|
66
|
+
type SubjectOf<R> = Omit<R, 'op' | 'value' | 'values' | 'valueKind'>;
|
|
67
|
+
export type Subject = SubjectOf<AttributeRule> | SubjectOf<PropertyRule> | SubjectOf<QuantityRule> | SubjectOf<ClassificationRule> | SubjectOf<GroupRule> | {
|
|
68
|
+
kind: 'name' | 'material' | 'storey' | 'parent' | 'type' | 'ifcType' | 'predefinedType' | 'globalId';
|
|
69
|
+
};
|
|
70
|
+
export interface UniqueRequirement {
|
|
71
|
+
kind: 'unique';
|
|
72
|
+
subject: Subject;
|
|
73
|
+
/** federation (default): the same value in two models is a duplicate. */
|
|
74
|
+
scope?: 'perModel' | 'federation';
|
|
75
|
+
}
|
|
76
|
+
export interface AggregateRequirement {
|
|
77
|
+
kind: 'aggregate';
|
|
78
|
+
fn: 'count' | 'sum' | 'min' | 'max' | 'avg';
|
|
79
|
+
subject?: Subject;
|
|
80
|
+
groupBy?: {
|
|
81
|
+
subject: Subject;
|
|
82
|
+
/** Elements whose own subject value (or identity, for `parent`) defines the full
|
|
83
|
+
* key set, so EMPTY groups exist and can fail (`count gte 1`). */
|
|
84
|
+
universe?: RuleBlock;
|
|
85
|
+
};
|
|
86
|
+
op: NumericOp;
|
|
87
|
+
value: number;
|
|
88
|
+
}
|
|
89
|
+
export interface CompareRequirement {
|
|
90
|
+
kind: 'compare';
|
|
91
|
+
left: Subject;
|
|
92
|
+
right: Subject;
|
|
93
|
+
op: NumericOp;
|
|
94
|
+
valueType?: 'number' | 'date';
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* "Width is recorded in mm" (#5300): every value of `subject` on an
|
|
98
|
+
* applicable element must be recorded in `unit`, a display symbol as the
|
|
99
|
+
* property panel shows it (`mm`, `m`, `m²`, `m³`, `kg`, …). Per element,
|
|
100
|
+
* like `element`. IDS 1.0 cannot express this (bSI discussion #437).
|
|
101
|
+
*/
|
|
102
|
+
export interface UnitRequirement {
|
|
103
|
+
kind: 'unit';
|
|
104
|
+
/** A property or quantity subject; no other subject carries a unit. */
|
|
105
|
+
subject: SubjectOf<PropertyRule> | SubjectOf<QuantityRule>;
|
|
106
|
+
unit: string;
|
|
107
|
+
}
|
|
108
|
+
export {};
|
|
109
|
+
//# sourceMappingURL=rule-set.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rule-set.d.ts","sourceRoot":"","sources":["../../src/rule-set/rule-set.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
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 const RULE_SET_VERSION = 1;
|
|
5
|
+
//# sourceMappingURL=rule-set.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rule-set.js","sourceRoot":"","sources":["../../src/rule-set/rule-set.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AA+B/D,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAU,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ifc-lite/rules",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Filter-rule vocabulary, evaluator and .rules.json information-validation engine for IFC-Lite",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"default": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"@ifc-lite/data": "5.0.0",
|
|
17
|
+
"@ifc-lite/encoding": "2.2.0",
|
|
18
|
+
"@ifc-lite/mutations": "2.6.0",
|
|
19
|
+
"@ifc-lite/ids": "2.0.0",
|
|
20
|
+
"@ifc-lite/parser": "8.0.0",
|
|
21
|
+
"@ifc-lite/lists": "2.2.5"
|
|
22
|
+
},
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"@types/node": "^26.6.1",
|
|
25
|
+
"typescript": "^6.0.3",
|
|
26
|
+
"vitest": "^5.0.1"
|
|
27
|
+
},
|
|
28
|
+
"license": "MPL-2.0",
|
|
29
|
+
"author": "Louis True",
|
|
30
|
+
"repository": {
|
|
31
|
+
"type": "git",
|
|
32
|
+
"url": "https://github.com/LTplus-AG/ifc-lite.git",
|
|
33
|
+
"directory": "packages/rules"
|
|
34
|
+
},
|
|
35
|
+
"homepage": "https://ifclite.dev/docs/",
|
|
36
|
+
"bugs": "https://github.com/LTplus-AG/ifc-lite/issues",
|
|
37
|
+
"keywords": [
|
|
38
|
+
"ifc",
|
|
39
|
+
"bim",
|
|
40
|
+
"validation",
|
|
41
|
+
"ids",
|
|
42
|
+
"rules",
|
|
43
|
+
"filter",
|
|
44
|
+
"aec"
|
|
45
|
+
],
|
|
46
|
+
"publishConfig": {
|
|
47
|
+
"access": "public"
|
|
48
|
+
},
|
|
49
|
+
"files": [
|
|
50
|
+
"dist",
|
|
51
|
+
"README.md"
|
|
52
|
+
],
|
|
53
|
+
"scripts": {
|
|
54
|
+
"build": "pnpm exec tsc",
|
|
55
|
+
"typecheck": "node ../../scripts/typecheck-tests.mjs",
|
|
56
|
+
"dev": "pnpm exec tsc --watch",
|
|
57
|
+
"test": "vitest run"
|
|
58
|
+
}
|
|
59
|
+
}
|