@pubid/pubid 0.1.27 → 0.1.28
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/flavors/ecma/index.js +3 -0
- package/dist/flavors/ieee/index.js +84 -8
- package/dist/flavors/ieee/model.js +6 -1
- package/dist/flavors/iso/model.d.ts +15 -1
- package/dist/flavors/iso/model.js +16 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/model/subset-match.js +2 -1
- package/package.json +1 -1
- package/vendor/parg/ieee.json +2225 -1750
|
@@ -37,6 +37,9 @@ function ecmaClass(kind) {
|
|
|
37
37
|
const prefix = KIND_PREFIXES[kind];
|
|
38
38
|
class EcmaKindIdentifier extends BaseIdentifier {
|
|
39
39
|
static polymorphicName = `pubid:ecma:${kind}`;
|
|
40
|
+
// Ruby Pubid::Ecma declares subset_strict :part: a part-less ECMA
|
|
41
|
+
// reference means "this document has none", not "any part".
|
|
42
|
+
static subsetStrict = ["part"];
|
|
40
43
|
static attributes = extendAttributes(BaseIdentifier, {
|
|
41
44
|
number: { type: "string" },
|
|
42
45
|
part: { type: "string" },
|
|
@@ -320,9 +320,14 @@ class IeeeBuilder {
|
|
|
320
320
|
const copubs = Array.isArray(pubData["copublishers"])
|
|
321
321
|
? pubData["copublishers"]
|
|
322
322
|
: [pubData["copublishers"]];
|
|
323
|
+
// A capture may carry its own separators ("/IEC/ISO" — a joint
|
|
324
|
+
// token glued to the leading slash); the collection renders
|
|
325
|
+
// join("/"), so entries hold bare orgs.
|
|
323
326
|
attributes["copublisher"] = copubs
|
|
324
327
|
.map((cp) => extractValue(asHash(cp)["copublisher"]))
|
|
325
|
-
.filter((cp) => cp !== undefined)
|
|
328
|
+
.filter((cp) => cp !== undefined)
|
|
329
|
+
.flatMap((c) => c.replace(/^\//, "").split("/"))
|
|
330
|
+
.filter((c) => c !== "");
|
|
326
331
|
}
|
|
327
332
|
}
|
|
328
333
|
else if (parsed["publisher"] !== undefined) {
|
|
@@ -637,7 +642,15 @@ class IeeeBuilder {
|
|
|
637
642
|
}
|
|
638
643
|
}
|
|
639
644
|
else {
|
|
640
|
-
|
|
645
|
+
// A degraded wire leaf carries the whole draft clause verbatim
|
|
646
|
+
// ("/D2.1.1" — the three-segment designator the engine cannot
|
|
647
|
+
// structure): IeeeDraft.parse is the inverse of render, so it
|
|
648
|
+
// strips the prefix instead of double-appending it.
|
|
649
|
+
const reparsed = IeeeDraft.parse(extractValue(draftData) ?? "");
|
|
650
|
+
if (reparsed !== undefined) {
|
|
651
|
+
attributes["draft"] = reparsed.render();
|
|
652
|
+
return;
|
|
653
|
+
}
|
|
641
654
|
}
|
|
642
655
|
// A REV-carrying draft embeds its print date into the designator
|
|
643
656
|
// with the month canonicalized numeric (pubid ruling 2026-10-14):
|
|
@@ -1098,7 +1111,10 @@ class IeeeBuilder {
|
|
|
1098
1111
|
// strip it (the #471 separator-in-capture rule). The stored
|
|
1099
1112
|
// form keeps the comma so it re-parses through the same tail.
|
|
1100
1113
|
const draftYear = (extractValue(parsed["draft_year"]) ?? "").replace(/^[, ]+/, "");
|
|
1101
|
-
|
|
1114
|
+
// Compose through the render so a designator-word version
|
|
1115
|
+
// ("ED1") keeps its word instead of concatenating D ("DED1").
|
|
1116
|
+
attributes["draft"] =
|
|
1117
|
+
new IeeeDraft({ version: draftVer, year: draftYear }).render();
|
|
1102
1118
|
if (parsed["year"] === undefined)
|
|
1103
1119
|
delete attributes["year"];
|
|
1104
1120
|
}
|
|
@@ -1178,7 +1194,14 @@ class IeeeBuilder {
|
|
|
1178
1194
|
// the P and keep the joint spelling.
|
|
1179
1195
|
const numericDraft = parsed["draft_version"] !== undefined &&
|
|
1180
1196
|
/^\d/.test(extractValue(parsed["draft_version"]) ?? "");
|
|
1181
|
-
|
|
1197
|
+
// P + a /D designator (any draft capture) is a DRAFT, never a
|
|
1198
|
+
// printed Std (the owner's 2026-10-24 ruling) -- the joint/
|
|
1199
|
+
// project-draft family owns the row; the non-P rows keep the
|
|
1200
|
+
// printed-strip doctrine (the normalization ledger).
|
|
1201
|
+
const pWithDraft = parsed["project_marker"] !== undefined &&
|
|
1202
|
+
(parsed["draft_version"] !== undefined || parsed["draft_iso_stage"] !== undefined ||
|
|
1203
|
+
parsed["draft_month"] !== undefined || parsed["draft_year"] !== undefined);
|
|
1204
|
+
if (parsed["iso_published"] !== undefined && !pWithDraft &&
|
|
1182
1205
|
(parsed["printed_dash_year"] !== undefined || parsed["printed_month_year"] !== undefined ||
|
|
1183
1206
|
(numericDraft && parsed["draft_month"] !== undefined) ||
|
|
1184
1207
|
(parsed["year"] === undefined && parsed["parameters"] !== undefined &&
|
|
@@ -1193,6 +1216,11 @@ class IeeeBuilder {
|
|
|
1193
1216
|
if (partVal !== undefined) {
|
|
1194
1217
|
printedCode += /^[._-]/.test(partVal) ? partVal : `${sep}${partVal}`;
|
|
1195
1218
|
}
|
|
1219
|
+
// the subpart carries its separator too (C1 separator-in-capture);
|
|
1220
|
+
// the two-party rows split "-57-1202"-class parts into both
|
|
1221
|
+
const subVal = parsed["subpart"] !== undefined ? extractValue(parsed["subpart"]) : undefined;
|
|
1222
|
+
if (subVal !== undefined && subVal !== "")
|
|
1223
|
+
printedCode += subVal;
|
|
1196
1224
|
// P = project: the marker is identity, preserved as spelled.
|
|
1197
1225
|
if (parsed["project_marker"] !== undefined)
|
|
1198
1226
|
printedCode = `P${printedCode}`;
|
|
@@ -1217,9 +1245,11 @@ class IeeeBuilder {
|
|
|
1217
1245
|
printedAttrs["month"] = attributes["month"];
|
|
1218
1246
|
}
|
|
1219
1247
|
else if (parsed["draft_month"] !== undefined) {
|
|
1220
|
-
// The date trails the draft itself
|
|
1221
|
-
// the
|
|
1222
|
-
|
|
1248
|
+
// The date trails the draft itself ("D31, Aug 2010"): the
|
|
1249
|
+
// normalization ledger strips the ordinal draft on the printed
|
|
1250
|
+
// joint face and surfaces the date as the printed date.
|
|
1251
|
+
printedAttrs["year"] = extractValue(parsed["draft_year"]);
|
|
1252
|
+
printedAttrs["month"] = extractValue(parsed["draft_month"]);
|
|
1223
1253
|
}
|
|
1224
1254
|
const codeObj = IeeeCode.parse(finalCode);
|
|
1225
1255
|
if (codeObj !== undefined) {
|
|
@@ -1254,6 +1284,20 @@ class IeeeBuilder {
|
|
|
1254
1284
|
// date-less form ("/D=CD1") elects the same face only when the input
|
|
1255
1285
|
// spells the designator (the reference's original_input gate) — the
|
|
1256
1286
|
// stage-first rows keep their ISO rendering.
|
|
1287
|
+
// The designation route ("IEEE P24748-4/D=FDIS") has no
|
|
1288
|
+
// publishers group; IEEE is the sole publisher of the D=
|
|
1289
|
+
// designator face, and the elections below read the builder-local
|
|
1290
|
+
// slots.
|
|
1291
|
+
if (attributes["publisher"] === undefined)
|
|
1292
|
+
attributes["publisher"] = "IEEE";
|
|
1293
|
+
if (attributes["copublisher"] === undefined)
|
|
1294
|
+
attributes["copublisher"] = [];
|
|
1295
|
+
// The model rebuilds publishers from publisher+copublisher when
|
|
1296
|
+
// the publishers group is absent (the reference initialize).
|
|
1297
|
+
if (attributes["publishers"] === undefined) {
|
|
1298
|
+
attributes["publishers"] = [attributes["publisher"],
|
|
1299
|
+
...(attributes["copublisher"] ?? [])];
|
|
1300
|
+
}
|
|
1257
1301
|
const dEqInput = this.originalInput.includes("/D=");
|
|
1258
1302
|
const stageWordForGate = extractValue(parsed["iso_stage"]) ?? "";
|
|
1259
1303
|
if (parsed["iso_stage"] !== undefined &&
|
|
@@ -1284,6 +1328,29 @@ class IeeeBuilder {
|
|
|
1284
1328
|
if (!bareIeeeProject)
|
|
1285
1329
|
attributes["lead_party"] = "ISO";
|
|
1286
1330
|
let stageAbbr = extractValue(parsed["iso_stage"]);
|
|
1331
|
+
// The bare-IEEE project row carries the stage on the D=
|
|
1332
|
+
// designator with the IEEE date convention ("D=FDIS-201008",
|
|
1333
|
+
// pubid#203); the ISO stage-word face is not elected.
|
|
1334
|
+
if (bareIeeeProject && parsed["draft_stage_year"] === undefined) {
|
|
1335
|
+
let date = "";
|
|
1336
|
+
const y = attributes["year"];
|
|
1337
|
+
const m = String(attributes["month"] ?? "");
|
|
1338
|
+
if (y !== undefined) {
|
|
1339
|
+
date = `-${y}`;
|
|
1340
|
+
if (m !== "") {
|
|
1341
|
+
const monthNum = /^\d+$/.test(m) ? Number(m) : DRAFT_MONTH_NAMES[String(m).replace(/\.$/, "")];
|
|
1342
|
+
if (monthNum !== undefined)
|
|
1343
|
+
date += String(monthNum).padStart(2, "0");
|
|
1344
|
+
}
|
|
1345
|
+
}
|
|
1346
|
+
attributes["ieee_draft"] = `D=${stageAbbr}${date}`;
|
|
1347
|
+
const record = stageAbbr !== undefined ? locateStage(stageAbbr) : undefined;
|
|
1348
|
+
if (record !== undefined)
|
|
1349
|
+
attributes["typed_stage"] = new IeeeTypedStage(record);
|
|
1350
|
+
attributes["lead_party"] = "IEEE";
|
|
1351
|
+
delete attributes["year"];
|
|
1352
|
+
delete attributes["month"];
|
|
1353
|
+
}
|
|
1287
1354
|
// The IEC "/V<version>" iteration rides glued onto the stage word
|
|
1288
1355
|
// ("_CDV/V3" -> "CDV3") — the family's lossless spelling (the
|
|
1289
1356
|
// reference's builder, pubid#477).
|
|
@@ -1364,8 +1431,17 @@ class IeeeBuilder {
|
|
|
1364
1431
|
// builds the base [ISO, IEC, IEEE], lead ISO); the CD-stage rows and
|
|
1365
1432
|
// the IEEE-led project rows preserve the printed order (P90003 stays
|
|
1366
1433
|
// IEEE/ISO/IEC).
|
|
1434
|
+
// The reorder is the PUBLISHED stage-less doctrine (pubid#317)
|
|
1435
|
+
// only: the project rows (the P marker) and every draft-bearing
|
|
1436
|
+
// row keep the printed publisher order (the 2026-10-24 corpus
|
|
1437
|
+
// faces, pubid#595).
|
|
1438
|
+
const draftBearing = parsed["project_marker"] !== undefined ||
|
|
1439
|
+
parsed["draft_version"] !== undefined ||
|
|
1440
|
+
parsed["draft"] !== undefined ||
|
|
1441
|
+
parsed["draft_iso_stage"] !== undefined ||
|
|
1442
|
+
parsed["draft_stage_year"] !== undefined;
|
|
1367
1443
|
if (parsed["iso_published"] !== undefined && parsed["iso_stage"] === undefined &&
|
|
1368
|
-
Array.isArray(attributes["publishers"])) {
|
|
1444
|
+
!draftBearing && Array.isArray(attributes["publishers"])) {
|
|
1369
1445
|
const pubs = attributes["publishers"];
|
|
1370
1446
|
attributes["publishers"] = [...pubs.filter((p) => p !== "IEEE"), ...pubs.filter((p) => p === "IEEE")];
|
|
1371
1447
|
attributes["publisher"] = attributes["publishers"][0];
|
|
@@ -222,7 +222,12 @@ export class IeeeDraft {
|
|
|
222
222
|
});
|
|
223
223
|
}
|
|
224
224
|
render() {
|
|
225
|
-
|
|
225
|
+
// A version that already opens with a designator word ("ED4", the
|
|
226
|
+
// IEC edition-draft ordinal; an ISO/IEC stage token such as
|
|
227
|
+
// "FDIS_March") renders verbatim — prepending D concatenates a
|
|
228
|
+
// hallucinated token ("DED4", "DFDIS") that no face spells.
|
|
229
|
+
const designatorVerbatim = /^(ED\d|(FDIS|FCD|CDV|DIS|CD|WD|PWI|NP))/.test(this.version);
|
|
230
|
+
let result = designatorVerbatim ? `/${this.version}` : `/D${this.version}`;
|
|
226
231
|
if (this.isoStage !== undefined)
|
|
227
232
|
result += `=${this.isoStage}`;
|
|
228
233
|
if (this.isoStage !== undefined && this.isoIteration !== undefined) {
|
|
@@ -40,6 +40,10 @@ export declare class IsoEdition extends Component {
|
|
|
40
40
|
toWire(): Record<string, unknown>;
|
|
41
41
|
}
|
|
42
42
|
export declare abstract class IsoIdentifier extends BaseIdentifier {
|
|
43
|
+
/** The typed-stage state joins the match (the published default is
|
|
44
|
+
* stated: ISO 9004 does not match ISO/DIS 9004) but never the wire
|
|
45
|
+
* hash — the attribute table drives toHash, so it is named here. */
|
|
46
|
+
static subsetAttributes: string[];
|
|
43
47
|
static attributes: import("../../model/attribute.js").AttributeTable;
|
|
44
48
|
readonly number: string | undefined;
|
|
45
49
|
readonly part: string | undefined;
|
|
@@ -75,7 +79,16 @@ export declare abstract class IsoIdentifier extends BaseIdentifier {
|
|
|
75
79
|
/** identifier.rb's base key_value block (the single-document whitelist). */
|
|
76
80
|
export declare const ISO_MAPPINGS: FieldMapping[];
|
|
77
81
|
/** The ISO Publisher component: "ISO/IEC/IEEE". */
|
|
78
|
-
export declare class IsoPublisher {
|
|
82
|
+
export declare class IsoPublisher extends Component {
|
|
83
|
+
static attributes: {
|
|
84
|
+
publisher: {
|
|
85
|
+
type: string;
|
|
86
|
+
};
|
|
87
|
+
copublisher: {
|
|
88
|
+
type: string;
|
|
89
|
+
collection: boolean;
|
|
90
|
+
};
|
|
91
|
+
};
|
|
79
92
|
readonly publisher: string;
|
|
80
93
|
readonly copublisher: string[] | undefined;
|
|
81
94
|
constructor(attrs: {
|
|
@@ -83,6 +96,7 @@ export declare class IsoPublisher {
|
|
|
83
96
|
copublisher?: unknown;
|
|
84
97
|
});
|
|
85
98
|
render(): string;
|
|
99
|
+
toWire(): Record<string, unknown>;
|
|
86
100
|
}
|
|
87
101
|
/** Single documents (everything except supplements, TcDocument, Bundled). */
|
|
88
102
|
export declare abstract class IsoSingleIdentifier extends IsoIdentifier {
|
|
@@ -60,6 +60,10 @@ export class IsoEdition extends Component {
|
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
62
|
export class IsoIdentifier extends BaseIdentifier {
|
|
63
|
+
/** The typed-stage state joins the match (the published default is
|
|
64
|
+
* stated: ISO 9004 does not match ISO/DIS 9004) but never the wire
|
|
65
|
+
* hash — the attribute table drives toHash, so it is named here. */
|
|
66
|
+
static subsetAttributes = ["typedStageState"];
|
|
63
67
|
static attributes = extendAttributes(BaseIdentifier, {
|
|
64
68
|
number: { type: "string" },
|
|
65
69
|
part: { type: "string" },
|
|
@@ -275,10 +279,15 @@ const stageMapping = () => ({
|
|
|
275
279
|
},
|
|
276
280
|
});
|
|
277
281
|
/** The ISO Publisher component: "ISO/IEC/IEEE". */
|
|
278
|
-
export class IsoPublisher {
|
|
282
|
+
export class IsoPublisher extends Component {
|
|
283
|
+
static attributes = {
|
|
284
|
+
publisher: { type: "string" },
|
|
285
|
+
copublisher: { type: "string", collection: true },
|
|
286
|
+
};
|
|
279
287
|
publisher;
|
|
280
288
|
copublisher;
|
|
281
289
|
constructor(attrs) {
|
|
290
|
+
super();
|
|
282
291
|
this.publisher = attrs.publisher === undefined || attrs.publisher === null ? "ISO" : String(attrs.publisher);
|
|
283
292
|
this.copublisher = Array.isArray(attrs.copublisher) ? attrs.copublisher.map(String) : [];
|
|
284
293
|
}
|
|
@@ -287,6 +296,12 @@ export class IsoPublisher {
|
|
|
287
296
|
return this.publisher;
|
|
288
297
|
return this.publisher + this.copublisher.map((cp) => `/${cp}`).join("");
|
|
289
298
|
}
|
|
299
|
+
toWire() {
|
|
300
|
+
return {
|
|
301
|
+
publisher: this.publisher,
|
|
302
|
+
...(this.copublisher && this.copublisher.length > 0 ? { copublisher: this.copublisher } : {}),
|
|
303
|
+
};
|
|
304
|
+
}
|
|
290
305
|
}
|
|
291
306
|
/** Single documents (everything except supplements, TcDocument, Bundled). */
|
|
292
307
|
export class IsoSingleIdentifier extends IsoIdentifier {
|
package/dist/index.d.ts
CHANGED
|
@@ -7,3 +7,4 @@ export { PendingRegistry } from "./conformance/pending.js";
|
|
|
7
7
|
export { checkCase, runFlavor, runCorpus } from "./conformance/runner.js";
|
|
8
8
|
export { corpusModeImplementation, CorpusBackedIdentifier } from "./implementations/corpus-mode.js";
|
|
9
9
|
export { grammarImplementation } from "./flavors/index.js";
|
|
10
|
+
export { subsetMatch, valueMatch, exactMatch } from "./model/subset-match.js";
|
package/dist/index.js
CHANGED
|
@@ -7,3 +7,4 @@ export { corpusModeImplementation, CorpusBackedIdentifier } from "./implementati
|
|
|
7
7
|
// Root re-export so consumers needn't deep-import flavor modules
|
|
8
8
|
// (pubid/pubid-ts#63 - the estate serving codec).
|
|
9
9
|
export { grammarImplementation } from "./flavors/index.js";
|
|
10
|
+
export { subsetMatch, valueMatch, exactMatch } from "./model/subset-match.js";
|
|
@@ -121,7 +121,8 @@ export function subsetMatch(reference, candidate) {
|
|
|
121
121
|
? ALL_PARTS_ATTRIBUTES
|
|
122
122
|
: []),
|
|
123
123
|
]);
|
|
124
|
-
|
|
124
|
+
const names = [...Object.keys(ctor.attributes), ...(ctor.subsetAttributes ?? [])];
|
|
125
|
+
return names.every((name) => {
|
|
125
126
|
if (ignored.has(name))
|
|
126
127
|
return true;
|
|
127
128
|
const mine = reference[name];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pubid/pubid",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.28",
|
|
4
4
|
"description": "TypeScript PubID identifiers: resolution, normalization and canonical hashes for every identifier in the pubid-testsuite corpus (41 standards bodies), with a conformance runner mirroring the Ruby reference",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|