@primmel/primmel 1.6.0 → 1.7.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/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/src/ser-des/config/data.d.ts.map +1 -1
- package/dist/src/ser-des/config/data.js +4 -2
- package/dist/src/ser-des/config/data.js.map +1 -1
- package/dist/src/ser-des/config/term.d.ts.map +1 -1
- package/dist/src/ser-des/config/term.js +3 -0
- package/dist/src/ser-des/config/term.js.map +1 -1
- package/dist/src/ser-des/index.d.ts +1 -1
- package/dist/src/ser-des/index.d.ts.map +1 -1
- package/dist/src/ser-des/index.js +3 -1
- package/dist/src/ser-des/index.js.map +1 -1
- package/dist/src/ser-des/package.d.ts +68 -0
- package/dist/src/ser-des/package.d.ts.map +1 -1
- package/dist/src/ser-des/package.js +169 -24
- package/dist/src/ser-des/package.js.map +1 -1
- package/dist/src/ser-des/parse-block.d.ts.map +1 -1
- package/dist/src/ser-des/parse-block.js +6 -4
- package/dist/src/ser-des/parse-block.js.map +1 -1
- package/dist/src/ser-des/parse.d.ts +8 -0
- package/dist/src/ser-des/parse.d.ts.map +1 -1
- package/dist/src/ser-des/parse.js +25 -0
- package/dist/src/ser-des/parse.js.map +1 -1
- package/dist/src/ser-des/types.d.ts +15 -0
- package/dist/src/ser-des/types.d.ts.map +1 -1
- package/dist/src/types/Term.d.ts +8 -0
- package/dist/src/types/Term.d.ts.map +1 -1
- package/dist-browser/index.mjs +809 -694
- package/dist-cli/primmel.mjs +139 -29
- package/package.json +1 -1
package/dist-cli/primmel.mjs
CHANGED
|
@@ -187,6 +187,7 @@ function createDuplicateIdChecker() {
|
|
|
187
187
|
function parse(mmelString, parsers, options = {}) {
|
|
188
188
|
const tokens = tokenizeWithPositions(mmelString);
|
|
189
189
|
const dupChecker = createDuplicateIdChecker();
|
|
190
|
+
const constructs = [];
|
|
190
191
|
let ctx = {
|
|
191
192
|
root: "",
|
|
192
193
|
metadata: null,
|
|
@@ -298,6 +299,15 @@ function parse(mmelString, parsers, options = {}) {
|
|
|
298
299
|
ctx.issues.push(issue);
|
|
299
300
|
}
|
|
300
301
|
}
|
|
302
|
+
if (options.withProvenance) {
|
|
303
|
+
constructs.push({
|
|
304
|
+
field: cfg.field ?? keyword,
|
|
305
|
+
id: idTok.value,
|
|
306
|
+
keyword,
|
|
307
|
+
start: tok.start,
|
|
308
|
+
end: payloadTok.end
|
|
309
|
+
});
|
|
310
|
+
}
|
|
301
311
|
updateCtx = cfg.parse(idTok.value, payloadTok.value);
|
|
302
312
|
} else {
|
|
303
313
|
if (i >= tokens.length) {
|
|
@@ -306,6 +316,15 @@ function parse(mmelString, parsers, options = {}) {
|
|
|
306
316
|
);
|
|
307
317
|
}
|
|
308
318
|
const payloadTok = tokens[i++];
|
|
319
|
+
if (options.withProvenance) {
|
|
320
|
+
constructs.push({
|
|
321
|
+
field: cfg.field ?? keyword,
|
|
322
|
+
id: "",
|
|
323
|
+
keyword,
|
|
324
|
+
start: tok.start,
|
|
325
|
+
end: payloadTok.end
|
|
326
|
+
});
|
|
327
|
+
}
|
|
309
328
|
updateCtx = cfg.parse(payloadTok.value);
|
|
310
329
|
}
|
|
311
330
|
const next = updateCtx(ctx);
|
|
@@ -314,6 +333,9 @@ function parse(mmelString, parsers, options = {}) {
|
|
|
314
333
|
}
|
|
315
334
|
ctx = next;
|
|
316
335
|
}
|
|
336
|
+
if (options.withProvenance) {
|
|
337
|
+
ctx.constructs = constructs;
|
|
338
|
+
}
|
|
317
339
|
return ctx;
|
|
318
340
|
}
|
|
319
341
|
|
|
@@ -432,8 +454,12 @@ function forEachAttribute(data, visitor, errCtx) {
|
|
|
432
454
|
while (i < t.length) {
|
|
433
455
|
if (t[i] === "ref") {
|
|
434
456
|
const nameParts2 = [t[i++]];
|
|
435
|
-
if (i < t.length)
|
|
436
|
-
|
|
457
|
+
if (i < t.length) {
|
|
458
|
+
nameParts2.push(t[i++]);
|
|
459
|
+
}
|
|
460
|
+
if (i < t.length) {
|
|
461
|
+
nameParts2.push(t[i++]);
|
|
462
|
+
}
|
|
437
463
|
let blockContent = "";
|
|
438
464
|
if (i < t.length && t[i].charAt(0) === "{") {
|
|
439
465
|
blockContent = unwrapBlock(t[i++]);
|
|
@@ -642,7 +668,9 @@ var parseDataClass = function(id, data) {
|
|
|
642
668
|
const ref = { predicate: m[1], target: m[2] };
|
|
643
669
|
if (details) {
|
|
644
670
|
const noteMatch = /note\s+"([^"]*)"/.exec(details) ?? /note\s+(\S+)/.exec(details);
|
|
645
|
-
if (noteMatch)
|
|
671
|
+
if (noteMatch) {
|
|
672
|
+
ref.note = noteMatch[1];
|
|
673
|
+
}
|
|
646
674
|
}
|
|
647
675
|
result.ref ??= [];
|
|
648
676
|
result.ref.push(ref);
|
|
@@ -792,7 +820,9 @@ var dumpDataClass = function(dataclass) {
|
|
|
792
820
|
if (dataclass.ref && dataclass.ref.length > 0) {
|
|
793
821
|
for (const r of dataclass.ref) {
|
|
794
822
|
out += " ref " + r.predicate + ' "' + escapeString(r.target) + '"';
|
|
795
|
-
if (r.note)
|
|
823
|
+
if (r.note) {
|
|
824
|
+
out += ' { note "' + escapeString(r.note) + '" }';
|
|
825
|
+
}
|
|
796
826
|
out += "\n";
|
|
797
827
|
}
|
|
798
828
|
}
|
|
@@ -7525,6 +7555,8 @@ var parseTerm = function(id, data) {
|
|
|
7525
7555
|
result.note = unwrapped(value);
|
|
7526
7556
|
} else if (command === "source") {
|
|
7527
7557
|
result.source = unwrapped(value);
|
|
7558
|
+
} else if (command === "overlay") {
|
|
7559
|
+
result.overlay = value() === "true";
|
|
7528
7560
|
} else if (command === "scope_note") {
|
|
7529
7561
|
result.scopeNote = unwrapped(value);
|
|
7530
7562
|
} else if (command === "language") {
|
|
@@ -13228,6 +13260,55 @@ function packageFiles(dir) {
|
|
|
13228
13260
|
}
|
|
13229
13261
|
return files;
|
|
13230
13262
|
}
|
|
13263
|
+
function countNewlines(text) {
|
|
13264
|
+
let n = 0;
|
|
13265
|
+
for (let i = 0; i < text.length; i++) {
|
|
13266
|
+
if (text.charAt(i) === "\n") {
|
|
13267
|
+
n++;
|
|
13268
|
+
}
|
|
13269
|
+
}
|
|
13270
|
+
return n;
|
|
13271
|
+
}
|
|
13272
|
+
function chunkify(files) {
|
|
13273
|
+
const chunks = [];
|
|
13274
|
+
let offset = 0;
|
|
13275
|
+
let line = 1;
|
|
13276
|
+
for (const f of files) {
|
|
13277
|
+
if (f.role !== "content") {
|
|
13278
|
+
continue;
|
|
13279
|
+
}
|
|
13280
|
+
const text = preprocessIncludes(f.path);
|
|
13281
|
+
chunks.push({ path: f.path, text, start: offset, lineStart: line });
|
|
13282
|
+
offset += text.length + 2;
|
|
13283
|
+
line += countNewlines(text) + 2;
|
|
13284
|
+
}
|
|
13285
|
+
return chunks;
|
|
13286
|
+
}
|
|
13287
|
+
function joinChunks(chunks) {
|
|
13288
|
+
return chunks.map((c) => c.text).join("\n\n");
|
|
13289
|
+
}
|
|
13290
|
+
function mapConstructs(parsed, chunks, packageId) {
|
|
13291
|
+
const out = {};
|
|
13292
|
+
let ci = 0;
|
|
13293
|
+
for (const c of parsed) {
|
|
13294
|
+
while (ci + 1 < chunks.length && c.start.offset >= chunks[ci + 1].start) {
|
|
13295
|
+
ci++;
|
|
13296
|
+
}
|
|
13297
|
+
const chunk = chunks[ci];
|
|
13298
|
+
const local = (p) => ({
|
|
13299
|
+
line: p.line - chunk.lineStart + 1,
|
|
13300
|
+
col: p.col,
|
|
13301
|
+
offset: p.offset - chunk.start
|
|
13302
|
+
});
|
|
13303
|
+
const source = {
|
|
13304
|
+
file: chunk.path,
|
|
13305
|
+
...packageId !== void 0 ? { package: packageId } : {},
|
|
13306
|
+
span: { start: local(c.start), end: local(c.end) }
|
|
13307
|
+
};
|
|
13308
|
+
(out[c.field] ??= {})[c.id] = source;
|
|
13309
|
+
}
|
|
13310
|
+
return out;
|
|
13311
|
+
}
|
|
13231
13312
|
function readPackageManifest(path) {
|
|
13232
13313
|
const manifestPath = join(resolve3(path), "package.primmel");
|
|
13233
13314
|
if (!existsSync2(manifestPath)) {
|
|
@@ -13246,24 +13327,21 @@ function readPackageManifest(path) {
|
|
|
13246
13327
|
}
|
|
13247
13328
|
return manifest;
|
|
13248
13329
|
}
|
|
13249
|
-
function loadPackageInternal(dir, options = {}) {
|
|
13330
|
+
function loadPackageInternal(dir, options = {}, withProvenance = false) {
|
|
13250
13331
|
const files = packageFiles(dir);
|
|
13251
13332
|
if (files.length === 0) {
|
|
13252
13333
|
throw new Error(`loadPackage: no package files found in ${resolve3(dir)}`);
|
|
13253
13334
|
}
|
|
13254
13335
|
let manifest = null;
|
|
13255
|
-
|
|
13256
|
-
|
|
13257
|
-
if (f.role === "manifest") {
|
|
13258
|
-
manifest = readPackageManifest(dir);
|
|
13259
|
-
} else {
|
|
13260
|
-
chunks.push(preprocessIncludes(f.path));
|
|
13261
|
-
}
|
|
13336
|
+
if (files.some((f) => f.role === "manifest")) {
|
|
13337
|
+
manifest = readPackageManifest(dir);
|
|
13262
13338
|
}
|
|
13339
|
+
const chunks = chunkify(files);
|
|
13263
13340
|
if (manifest && options.resolvePackage && effectiveUses(manifest).length > 0) {
|
|
13264
|
-
return composePackage(dir, options, manifest);
|
|
13341
|
+
return composePackage(dir, options, manifest, withProvenance);
|
|
13265
13342
|
}
|
|
13266
|
-
const
|
|
13343
|
+
const parseOptions = withProvenance ? { ...options, withProvenance: true } : options;
|
|
13344
|
+
const ctx = parse(joinChunks(chunks), PARSER_CONFIG, parseOptions);
|
|
13267
13345
|
if (manifest) {
|
|
13268
13346
|
ctx.packageManifest = manifest;
|
|
13269
13347
|
const deprecated = extendsDeprecationIssue(manifest);
|
|
@@ -13272,7 +13350,15 @@ function loadPackageInternal(dir, options = {}) {
|
|
|
13272
13350
|
}
|
|
13273
13351
|
}
|
|
13274
13352
|
const standard = resolve(ctx, RESOLVER_CONFIG);
|
|
13275
|
-
|
|
13353
|
+
const result = { standard, issues: ctx.issues };
|
|
13354
|
+
if (withProvenance) {
|
|
13355
|
+
const manifestFile = files.find((f) => f.role === "manifest")?.path;
|
|
13356
|
+
result.provenance = {
|
|
13357
|
+
...manifestFile !== void 0 ? { manifest: manifestFile } : {},
|
|
13358
|
+
constructs: mapConstructs(ctx.constructs ?? [], chunks, manifest?.id)
|
|
13359
|
+
};
|
|
13360
|
+
}
|
|
13361
|
+
return result;
|
|
13276
13362
|
}
|
|
13277
13363
|
function loadPackageWithIssues(dir, options = {}) {
|
|
13278
13364
|
return loadPackageInternal(dir, options);
|
|
@@ -13371,15 +13457,11 @@ var MERGE_FIELDS = [
|
|
|
13371
13457
|
"texts"
|
|
13372
13458
|
];
|
|
13373
13459
|
function parsePackageContent(dir, options) {
|
|
13374
|
-
const chunks =
|
|
13375
|
-
|
|
13376
|
-
|
|
13377
|
-
chunks.push(preprocessIncludes(f.path));
|
|
13378
|
-
}
|
|
13379
|
-
}
|
|
13380
|
-
return parse(chunks.join("\n\n"), PARSER_CONFIG, options);
|
|
13460
|
+
const chunks = chunkify(packageFiles(dir));
|
|
13461
|
+
const ctx = parse(joinChunks(chunks), PARSER_CONFIG, options);
|
|
13462
|
+
return { ctx, chunks };
|
|
13381
13463
|
}
|
|
13382
|
-
function composePackage(rootDir, options, rootManifest) {
|
|
13464
|
+
function composePackage(rootDir, options, rootManifest, withProvenance = false) {
|
|
13383
13465
|
const locate = options.resolvePackage;
|
|
13384
13466
|
const rootId = rootManifest.id;
|
|
13385
13467
|
const dirs = /* @__PURE__ */ new Map([[rootId, resolve3(rootDir)]]);
|
|
@@ -13430,9 +13512,13 @@ function composePackage(rootDir, options, rootManifest) {
|
|
|
13430
13512
|
order.push(id);
|
|
13431
13513
|
};
|
|
13432
13514
|
visit(rootId);
|
|
13515
|
+
const parseOptions = withProvenance ? { ...options, withProvenance: true } : options;
|
|
13433
13516
|
const ctxs = /* @__PURE__ */ new Map();
|
|
13517
|
+
const pkgChunks = /* @__PURE__ */ new Map();
|
|
13434
13518
|
for (const id of order) {
|
|
13435
|
-
|
|
13519
|
+
const parsed = parsePackageContent(dirs.get(id), parseOptions);
|
|
13520
|
+
ctxs.set(id, parsed.ctx);
|
|
13521
|
+
pkgChunks.set(id, parsed.chunks);
|
|
13436
13522
|
}
|
|
13437
13523
|
const provenance = /* @__PURE__ */ new Map();
|
|
13438
13524
|
for (const field of MERGE_FIELDS) {
|
|
@@ -13454,10 +13540,13 @@ function composePackage(rootDir, options, rootManifest) {
|
|
|
13454
13540
|
)) {
|
|
13455
13541
|
const prior = pm.get(key);
|
|
13456
13542
|
if (prior !== void 0) {
|
|
13457
|
-
|
|
13458
|
-
|
|
13459
|
-
|
|
13460
|
-
|
|
13543
|
+
const isOverlay = field === "terms" && typeof value === "object" && value !== null && value.overlay === true;
|
|
13544
|
+
if (!isOverlay) {
|
|
13545
|
+
throw new CompositionError(
|
|
13546
|
+
"uses-no-redefine",
|
|
13547
|
+
`package "${id}" redefines ${String(field)} id "${key}" already declared by package "${prior}" \u2014 an overlay may reference upstream ids, never redefine them (uses-no-redefine)`
|
|
13548
|
+
);
|
|
13549
|
+
}
|
|
13461
13550
|
}
|
|
13462
13551
|
target[key] = value;
|
|
13463
13552
|
pm.set(key, id);
|
|
@@ -13514,11 +13603,32 @@ function composePackage(rootDir, options, rootManifest) {
|
|
|
13514
13603
|
}
|
|
13515
13604
|
acc.packageManifest = rootManifest;
|
|
13516
13605
|
const standard = resolve(acc, RESOLVER_CONFIG);
|
|
13517
|
-
|
|
13606
|
+
const result = {
|
|
13518
13607
|
standard,
|
|
13519
13608
|
issues: [...acc.issues, ...compositionIssues],
|
|
13520
13609
|
composition: { root: rootId, order }
|
|
13521
13610
|
};
|
|
13611
|
+
if (withProvenance) {
|
|
13612
|
+
const constructs = {};
|
|
13613
|
+
for (const id of order) {
|
|
13614
|
+
const perPackage = mapConstructs(
|
|
13615
|
+
ctxs.get(id).constructs ?? [],
|
|
13616
|
+
pkgChunks.get(id),
|
|
13617
|
+
id
|
|
13618
|
+
);
|
|
13619
|
+
for (const [field, byId2] of Object.entries(perPackage)) {
|
|
13620
|
+
const target = constructs[field] ??= {};
|
|
13621
|
+
for (const [constructId, source] of Object.entries(byId2)) {
|
|
13622
|
+
target[constructId] = source;
|
|
13623
|
+
}
|
|
13624
|
+
}
|
|
13625
|
+
}
|
|
13626
|
+
result.provenance = {
|
|
13627
|
+
manifest: join(resolve3(rootDir), "package.primmel"),
|
|
13628
|
+
constructs
|
|
13629
|
+
};
|
|
13630
|
+
}
|
|
13631
|
+
return result;
|
|
13522
13632
|
}
|
|
13523
13633
|
|
|
13524
13634
|
// src/ser-des/prm.ts
|
package/package.json
CHANGED