marc-ts 0.1.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.
@@ -0,0 +1,150 @@
1
+ import { MarcRecord } from './types';
2
+ /**
3
+ * Extract the title from a MARC record (245 $a$b).
4
+ *
5
+ * @param record - The MARC record
6
+ * @returns The title, or undefined if not found
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * const titleText = title(record);
11
+ * // "The Catcher in the Rye"
12
+ * ```
13
+ */
14
+ export declare function title(record: MarcRecord): string | undefined;
15
+ /**
16
+ * Extract the title proper from a MARC record (245 $a only).
17
+ * This is just the main title without subtitle.
18
+ *
19
+ * @param record - The MARC record
20
+ * @returns The title proper, or undefined if not found
21
+ *
22
+ * @example
23
+ * ```typescript
24
+ * const mainTitle = titleProper(record);
25
+ * // "The Catcher in the Rye"
26
+ * ```
27
+ */
28
+ export declare function titleProper(record: MarcRecord): string | undefined;
29
+ /**
30
+ * Extract the author from a MARC record (100 $a or 110 $a).
31
+ *
32
+ * @param record - The MARC record
33
+ * @returns The author name, or undefined if not found
34
+ *
35
+ * @example
36
+ * ```typescript
37
+ * const authorName = author(record);
38
+ * // "Salinger, J. D."
39
+ * ```
40
+ */
41
+ export declare function author(record: MarcRecord): string | undefined;
42
+ /**
43
+ * Extract the edition statement from a MARC record (250 $a).
44
+ *
45
+ * @param record - The MARC record
46
+ * @returns The edition statement, or undefined if not found
47
+ *
48
+ * @example
49
+ * ```typescript
50
+ * const ed = edition(record);
51
+ * // "2nd ed."
52
+ * ```
53
+ */
54
+ export declare function edition(record: MarcRecord): string | undefined;
55
+ /**
56
+ * Extract the publisher from a MARC record (264 $b or 260 $b).
57
+ * Tries RDA field (264) first, then falls back to AACR2 field (260).
58
+ *
59
+ * @param record - The MARC record
60
+ * @returns The publisher name, or undefined if not found
61
+ *
62
+ * @example
63
+ * ```typescript
64
+ * const pub = publisher(record);
65
+ * // "Little, Brown and Company"
66
+ * ```
67
+ */
68
+ export declare function publisher(record: MarcRecord): string | undefined;
69
+ /**
70
+ * Extract the publication date from a MARC record (264 $c or 260 $c).
71
+ * Tries RDA field (264) first, then falls back to AACR2 field (260).
72
+ *
73
+ * @param record - The MARC record
74
+ * @returns The publication date, or undefined if not found
75
+ *
76
+ * @example
77
+ * ```typescript
78
+ * const date = publicationDate(record);
79
+ * // "1951"
80
+ * ```
81
+ */
82
+ export declare function publicationDate(record: MarcRecord): string | undefined;
83
+ /**
84
+ * Extract all ISBNs from a MARC record (020 $a).
85
+ * Returns an array because ISBN is a repeatable field.
86
+ *
87
+ * @param record - The MARC record
88
+ * @returns Array of ISBNs (empty if none found)
89
+ *
90
+ * @example
91
+ * ```typescript
92
+ * const isbns = isbn(record);
93
+ * // ["978-0-316-76948-0", "0-316-76948-7"]
94
+ * ```
95
+ */
96
+ export declare function isbn(record: MarcRecord): string[];
97
+ /**
98
+ * Extract the ISSN from a MARC record (022 $a).
99
+ *
100
+ * @param record - The MARC record
101
+ * @returns The ISSN, or undefined if not found
102
+ *
103
+ * @example
104
+ * ```typescript
105
+ * const issnValue = issn(record);
106
+ * // "0028-0836"
107
+ * ```
108
+ */
109
+ export declare function issn(record: MarcRecord): string | undefined;
110
+ /**
111
+ * Extract the LCCN from a MARC record (010 $a).
112
+ *
113
+ * @param record - The MARC record
114
+ * @returns The LCCN, or undefined if not found
115
+ *
116
+ * @example
117
+ * ```typescript
118
+ * const lccnValue = lccn(record);
119
+ * // " 50011915 "
120
+ * ```
121
+ */
122
+ export declare function lccn(record: MarcRecord): string | undefined;
123
+ /**
124
+ * Extract all subject headings from a MARC record (6XX $a).
125
+ * Includes all 6XX fields (600-699).
126
+ *
127
+ * @param record - The MARC record
128
+ * @returns Array of subject headings (empty if none found)
129
+ *
130
+ * @example
131
+ * ```typescript
132
+ * const subjectList = subjects(record);
133
+ * // ["History", "Biography", "Fiction"]
134
+ * ```
135
+ */
136
+ export declare function subjects(record: MarcRecord): string[];
137
+ /**
138
+ * Extract the series statement from a MARC record (490 $a).
139
+ *
140
+ * @param record - The MARC record
141
+ * @returns The series statement, or undefined if not found
142
+ *
143
+ * @example
144
+ * ```typescript
145
+ * const series = seriesStatement(record);
146
+ * // "Penguin classics"
147
+ * ```
148
+ */
149
+ export declare function seriesStatement(record: MarcRecord): string | undefined;
150
+ //# sourceMappingURL=convenience.d.ts.map
@@ -0,0 +1,166 @@
1
+ import { MarcRecord, ControlField, DataField } from './types';
2
+ /**
3
+ * Append a field to the end of a record.
4
+ * Returns a new record, does not mutate the original.
5
+ *
6
+ * @param record - The MARC record
7
+ * @param field - The field to append
8
+ * @returns A new record with the field appended
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * const newField: DataField = {
13
+ * tag: '650',
14
+ * indicator1: ' ',
15
+ * indicator2: '0',
16
+ * subfields: [{ code: 'a', value: 'New subject' }],
17
+ * };
18
+ * const updated = appendField(record, newField);
19
+ * // record is unchanged, updated contains the new field
20
+ * ```
21
+ */
22
+ export declare function appendField(record: MarcRecord, field: ControlField | DataField): MarcRecord;
23
+ /**
24
+ * Insert a field before the first occurrence of a tag.
25
+ * Returns a new record, does not mutate the original.
26
+ *
27
+ * @param record - The MARC record
28
+ * @param tag - The tag to insert before
29
+ * @param field - The field to insert
30
+ * @returns A new record with the field inserted
31
+ *
32
+ * @example
33
+ * ```typescript
34
+ * const newField: DataField = {
35
+ * tag: '650',
36
+ * indicator1: ' ',
37
+ * indicator2: '0',
38
+ * subfields: [{ code: 'a', value: 'New subject' }],
39
+ * };
40
+ * const updated = insertFieldBefore(record, '700', newField);
41
+ * // Inserts the 650 field before the first 700 field
42
+ * ```
43
+ */
44
+ export declare function insertFieldBefore(record: MarcRecord, tag: string, field: ControlField | DataField): MarcRecord;
45
+ /**
46
+ * Insert a field after the first occurrence of a tag.
47
+ * Returns a new record, does not mutate the original.
48
+ *
49
+ * @param record - The MARC record
50
+ * @param tag - The tag to insert after
51
+ * @param field - The field to insert
52
+ * @returns A new record with the field inserted
53
+ *
54
+ * @example
55
+ * ```typescript
56
+ * const updated = insertFieldAfter(record, '245', newField);
57
+ * // Inserts the field after the first 245 field
58
+ * ```
59
+ */
60
+ export declare function insertFieldAfter(record: MarcRecord, tag: string, field: ControlField | DataField): MarcRecord;
61
+ /**
62
+ * Insert a field in MARC block order.
63
+ * Maintains proper MARC21 field ordering: LDR → 00X → 0XX → 1XX → ... → 9XX
64
+ *
65
+ * @param record - The MARC record
66
+ * @param field - The field to insert
67
+ * @returns A new record with the field inserted in proper order
68
+ *
69
+ * @example
70
+ * ```typescript
71
+ * const field650: DataField = {
72
+ * tag: '650',
73
+ * indicator1: ' ',
74
+ * indicator2: '0',
75
+ * subfields: [{ code: 'a', value: 'Subject' }],
76
+ * };
77
+ * const updated = insertGroupedField(record, field650);
78
+ * // Field is inserted after other 6XX fields but before 7XX fields
79
+ * ```
80
+ */
81
+ export declare function insertGroupedField(record: MarcRecord, field: ControlField | DataField): MarcRecord;
82
+ /**
83
+ * Remove all fields with a specific tag.
84
+ * Returns a new record, does not mutate the original.
85
+ *
86
+ * @param record - The MARC record
87
+ * @param tag - The tag of fields to remove
88
+ * @returns A new record with the fields removed
89
+ *
90
+ * @example
91
+ * ```typescript
92
+ * const updated = removeFields(record, '650');
93
+ * // All 650 fields are removed from the returned record
94
+ * ```
95
+ */
96
+ export declare function removeFields(record: MarcRecord, tag: string): MarcRecord;
97
+ /**
98
+ * Remove a specific field instance from a record.
99
+ * Uses reference equality to identify the field.
100
+ *
101
+ * @param record - The MARC record
102
+ * @param field - The specific field instance to remove
103
+ * @returns A new record with the field removed
104
+ *
105
+ * @example
106
+ * ```typescript
107
+ * const field = getField(record, '650');
108
+ * if (field) {
109
+ * const updated = removeField(record, field);
110
+ * // That specific field is removed
111
+ * }
112
+ * ```
113
+ */
114
+ export declare function removeField(record: MarcRecord, field: ControlField | DataField): MarcRecord;
115
+ /**
116
+ * Add a subfield to a data field.
117
+ * Returns a new field, does not mutate the original.
118
+ *
119
+ * @param field - The data field
120
+ * @param code - The subfield code
121
+ * @param value - The subfield value
122
+ * @returns A new field with the subfield added
123
+ *
124
+ * @example
125
+ * ```typescript
126
+ * const field = getField(record, '245');
127
+ * if (field && isDataField(field)) {
128
+ * const updated = addSubfield(field, 'c', 'Author name');
129
+ * // field is unchanged, updated has the new subfield
130
+ * }
131
+ * ```
132
+ */
133
+ export declare function addSubfield(field: DataField, code: string, value: string): DataField;
134
+ /**
135
+ * Remove all subfields with a specific code from a data field.
136
+ * Returns a new field, does not mutate the original.
137
+ *
138
+ * @param field - The data field
139
+ * @param code - The subfield code to remove
140
+ * @returns A new field with the subfields removed
141
+ *
142
+ * @example
143
+ * ```typescript
144
+ * const updated = removeSubfield(field, 'x');
145
+ * // All $x subfields are removed
146
+ * ```
147
+ */
148
+ export declare function removeSubfield(field: DataField, code: string): DataField;
149
+ /**
150
+ * Replace the first subfield with a specific code in a data field.
151
+ * If the subfield doesn't exist, adds it.
152
+ * Returns a new field, does not mutate the original.
153
+ *
154
+ * @param field - The data field
155
+ * @param code - The subfield code to replace
156
+ * @param newValue - The new value for the subfield
157
+ * @returns A new field with the subfield replaced
158
+ *
159
+ * @example
160
+ * ```typescript
161
+ * const updated = replaceSubfield(field, 'a', 'New title');
162
+ * // First $a subfield is replaced with new value
163
+ * ```
164
+ */
165
+ export declare function replaceSubfield(field: DataField, code: string, newValue: string): DataField;
166
+ //# sourceMappingURL=field-ops.d.ts.map
@@ -0,0 +1,88 @@
1
+ import { MarcRecord, ControlField, DataField } from './types';
2
+ /**
3
+ * Get the first field with the specified tag.
4
+ *
5
+ * @param record - The MARC record to search
6
+ * @param tag - The field tag to find (e.g., '245', '100')
7
+ * @returns The first matching field, or undefined if not found
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * const titleField = getField(record, '245');
12
+ * if (titleField && isDataField(titleField)) {
13
+ * console.log('Title field found');
14
+ * }
15
+ * ```
16
+ */
17
+ export declare function getField(record: MarcRecord, tag: string): ControlField | DataField | undefined;
18
+ /**
19
+ * Get all fields with the specified tag.
20
+ *
21
+ * @param record - The MARC record to search
22
+ * @param tag - The field tag to find (e.g., '650', '700')
23
+ * @returns Array of matching fields (empty if none found)
24
+ *
25
+ * @example
26
+ * ```typescript
27
+ * const subjectFields = getFields(record, '650');
28
+ * console.log(`Found ${subjectFields.length} subject fields`);
29
+ * ```
30
+ */
31
+ export declare function getFields(record: MarcRecord, tag: string): (ControlField | DataField)[];
32
+ /**
33
+ * Get the first subfield with the specified code from a data field.
34
+ *
35
+ * @param field - The data field to search
36
+ * @param code - The subfield code to find (e.g., 'a', 'b')
37
+ * @returns The subfield value, or undefined if not found
38
+ *
39
+ * @example
40
+ * ```typescript
41
+ * const field = getField(record, '245');
42
+ * if (field && isDataField(field)) {
43
+ * const title = getSubfield(field, 'a');
44
+ * console.log('Title:', title);
45
+ * }
46
+ * ```
47
+ */
48
+ export declare function getSubfield(field: DataField, code: string): string | undefined;
49
+ /**
50
+ * Get all subfields with the specified code from a data field.
51
+ * Useful for repeatable subfields.
52
+ *
53
+ * @param field - The data field to search
54
+ * @param code - The subfield code to find (e.g., 'a', 'x')
55
+ * @returns Array of subfield values (empty if none found)
56
+ *
57
+ * @example
58
+ * ```typescript
59
+ * const field = getField(record, '650');
60
+ * if (field && isDataField(field)) {
61
+ * const subdivisions = getSubfields(field, 'x');
62
+ * console.log('Subdivisions:', subdivisions);
63
+ * }
64
+ * ```
65
+ */
66
+ export declare function getSubfields(field: DataField, code: string): string[];
67
+ /**
68
+ * Get all subfields from a data field as an array of {code, value} pairs.
69
+ *
70
+ * @param field - The data field
71
+ * @returns Array of subfield objects
72
+ *
73
+ * @example
74
+ * ```typescript
75
+ * const field = getField(record, '245');
76
+ * if (field && isDataField(field)) {
77
+ * const allSubfields = getAllSubfields(field);
78
+ * for (const sf of allSubfields) {
79
+ * console.log(`$${sf.code}: ${sf.value}`);
80
+ * }
81
+ * }
82
+ * ```
83
+ */
84
+ export declare function getAllSubfields(field: DataField): Array<{
85
+ code: string;
86
+ value: string;
87
+ }>;
88
+ //# sourceMappingURL=field-utils.d.ts.map
package/dist/index.cjs ADDED
@@ -0,0 +1,3 @@
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const u=require("./types-CJcxHJff.cjs");var te=27,v="�",G=new Map([[33,"Ł"],[34,"Ø"],[35,"Đ"],[36,"Þ"],[37,"Æ"],[38,"Œ"],[39,"ʹ"],[40,"·"],[41,"♭"],[42,"®"],[43,"±"],[44,"Ơ"],[45,"Ư"],[46,"ʼ"],[48,"ʻ"],[49,"ł"],[50,"ø"],[51,"đ"],[52,"þ"],[53,"æ"],[54,"œ"],[55,"ʺ"],[56,"ı"],[57,"£"],[58,"ð"],[59,"ơ"],[60,"ư"],[63,"°"]]),W=new Map([[96,"̉"],[97,"̀"],[98,"́"],[99,"̂"],[100,"̃"],[101,"̄"],[102,"̆"],[103,"̇"],[104,"̈"],[105,"̌"],[106,"̊"],[107,"︠"],[108,"︡"],[109,"̕"],[110,"̋"],[111,"̐"],[112,"̧"],[113,"̨"],[114,"̣"],[115,"̤"],[116,"̥"],[117,"̳"],[118,"̲"],[119,"̦"],[120,"̜"],[121,"̮"],[122,"︢"],[123,"︣"],[126,"̓"]]),ne=new Map(Array.from(W.entries()).map(([e,t])=>[t,e+128])),re=new Map(Array.from(G.entries()).map(([e,t])=>[t,e+128])),ie=T(65,"ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ",97,"αβγδεζηθικλμνξοπρστυφχψω"),se=T(96,"אבגדהוזחטיךכלםמןנסעףפץצקרשת"),oe=T(65,"АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ",97,"абвгдежзийклмнопрстуфхцчшщъыьэюя"),ae=new Map([[33,"ء"],[34,"آ"],[35,"أ"],[36,"ؤ"],[37,"إ"],[38,"ئ"],[39,"ا"],[40,"ب"],[41,"ة"],[42,"ت"],[43,"ث"],[44,"ج"],[45,"ح"],[46,"خ"],[47,"د"],[48,"ذ"],[49,"ر"],[50,"ز"],[51,"س"],[52,"ش"],[53,"ص"],[54,"ض"],[55,"ط"],[56,"ظ"],[57,"ع"],[58,"غ"],[65,"ف"],[66,"ق"],[67,"ك"],[68,"ل"],[69,"م"],[70,"ن"],[71,"ه"],[72,"و"],[73,"ى"],[74,"ي"]]),ce=new Map([[40,"₍"],[41,"₎"],[43,"₊"],[45,"₋"],[48,"₀"],[49,"₁"],[50,"₂"],[51,"₃"],[52,"₄"],[53,"₅"],[54,"₆"],[55,"₇"],[56,"₈"],[57,"₉"]]),le=new Map([[40,"⁽"],[41,"⁾"],[43,"⁺"],[45,"⁻"],[48,"⁰"],[49,"¹"],[50,"²"],[51,"³"],[52,"⁴"],[53,"⁵"],[54,"⁶"],[55,"⁷"],[56,"⁸"],[57,"⁹"],[110,"ⁿ"]]),de=new Map([[2171169,"一"],[2171170,"丁"],[2171171,"七"],[2171172,"万"],[2171173,"丈"],[2171174,"三"],[2171175,"上"],[2171176,"下"],[2171177,"不"],[2171178,"与"],[2171179,"丐"],[2171180,"丑"],[2171181,"且"],[2171182,"世"],[2171183,"丘"],[2171184,"丙"],[2171185,"业"],[2171186,"丛"],[2171187,"东"],[2171188,"丝"],[2171189,"丞"],[2171190,"丟"],[2171191,"丠"],[2171192,"両"],[2171193,"丢"],[2171194,"两"],[2171195,"严"],[2171196,"並"],[2171197,"丧"],[2171198,"丨"],[2171199,"个"],[2171200,"丫"],[2171201,"中"],[2171202,"丰"]]),fe={ascii:new Map,ansel:ue(G,W),greek:ie,hebrew:se,cyrillic:oe,arabic:ae,subscript:ce,superscript:le};function T(...e){const t=new Map;for(let n=0;n<e.length;n+=2){const r=e[n],i=e[n+1];Array.from(i).forEach((s,o)=>t.set(r+o,s))}return t}function ue(...e){const t=new Map;for(const n of e)for(const[r,i]of n)t.set(r,i);return t}function M(e){const t=e.codePointAt(0);return t>=768&&t<=879||t>=65056&&t<=65071}function I(e,t){return t?e-128:e}function ge(e,t,n){const r=I(e,n);return t==="ascii"?r>=32&&r<=126?String.fromCharCode(r):v:fe[t].get(r)??v}function he(e,t,n){if(t+2>=e.length)return{char:v,next:e.length};const r=I(e[t],n),i=I(e[t+1],n),s=I(e[t+2],n),o=r<<16|i<<8|s;return{char:de.get(o)??v,next:t+3}}function pe(e,t,n){if(t+1>=e.length)return{char:v,next:e.length};const r=e[t+1];let i,s;if(r===40||r===44)i="g0",s=t+2;else if(r===41||r===45)i="g1",s=t+2;else if(r===36){const l=e[t+2];if(l===void 0)return{char:v,next:e.length};l===40||l===44?(i="g0",s=t+3):l===41||l===45?(i="g1",s=t+3):(i="g0",s=t+2)}else return{char:v,next:t+2};if(s>=e.length)return{char:v,next:e.length};let o=e[s];if(o===33){if(s++,s>=e.length)return{char:v,next:e.length};o=e[s]}const c=Ee(o);return c?{char:"",next:we(n,i,c,s+1)}:{char:v,next:s+1}}function we(e,t,n,r){return e[t]=n,r}function Ee(e){switch(e){case 49:return"eacc";case 50:return"hebrew";case 51:return"arabic";case 52:return"cyrillic";case 66:return"ascii";case 69:return"ansel";case 78:return"cyrillic";case 81:return"greek";case 83:return"greek";case 98:return"subscript";case 112:return"superscript";default:return}}function k(e){const t={g0:"ascii",g1:"ansel"},n=[];let r="",i=0;const s=o=>{if(o){if(M(o)){r+=o;return}n.push(o+r),r=""}};for(;i<e.length;){const o=e[i];if(o===te){const d=pe(e,i,t);s(d.char),i=d.next;continue}if(o<32){s(String.fromCharCode(o)),i++;continue}const c=o>=160,l=c?t.g1:t.g0;if(l==="eacc"){const d=he(e,i,c);s(d.char),i=d.next;continue}s(ge(o,l,c)),i++}return r&&n.push(r),n.join("")}function me(e){return x(e).bytes}function x(e){const t=e.normalize("NFD"),n=[];let r=0,i=0;for(;i<t.length;){const s=t.codePointAt(i),o=t[i];if(M(o)){n.push(63),r++,i++;continue}let c=i+(s>65535?2:1);const l=[];for(;c<t.length&&M(t[c]);){const d=ne.get(t[c]);d!==void 0?l.push(d):(l.push(63),r++),c++}if(n.push(...l),s<128)n.push(s);else{const d=re.get(o);d!==void 0?n.push(d):(n.push(63),r++)}i=c}return{bytes:new Uint8Array(n),lossyCount:r}}var U=31,j=30,C=24,y=12,A=3,P=4,R=new TextDecoder("utf-8",{fatal:!1});function H(e){return R.decode(e)}function q(e,t=16){const n=e.slice(0,t),r=Array.from(n,i=>i.toString(16).padStart(2,"0")).join(" ");return e.length>t?`${r} … (${e.length} bytes)`:r}function z(e,t={}){const n=t.strict??!1,r=t.maxWarnings??100,i=[];if(e.length<C+1){const a=h("truncated_record",`Record too short: ${e.length} bytes`);if(n)throw new Error(a.message);return i.push(a),{record:null,warnings:i}}const s=Se(e);if(!be(s,i,n)&&(n||i.length>=r))return{record:null,warnings:i};const o=parseInt(s.substring(0,5),10);if(isNaN(o)||o>e.length){const a=h("invalid_leader",`Invalid record length in leader: ${s.substring(0,5)}`);if(n)throw new Error(a.message);i.push(a)}else if(o<e.length){const a=h("truncated_record",`Buffer is longer than the record length declared in the leader: leader says ${o}, buffer is ${e.length} bytes. Trailing bytes ignored (likely a concatenated stream — split on 0x1D first).`);if(n)throw new Error(a.message);i.push(a),e=e.slice(0,o)}const c=parseInt(s.substring(12,17),10);if(isNaN(c)){const a=h("invalid_leader",`Invalid base address in leader: ${s.substring(12,17)}`);if(n)throw new Error(a.message);return i.push(a),{record:null,warnings:i}}const l=C,d=e.indexOf(j,l);if(d===-1){const a=h("invalid_directory","Directory terminator not found");if(n)throw new Error(a.message);return i.push(a),{record:null,warnings:i}}const g=Fe(e.slice(l,d),i,n,r);if(g.length===0){const a=h("invalid_directory","No directory entries found");if(n)throw new Error(a.message);return i.push(a),{record:null,warnings:i}}const f=s[9]===" ";if(s[9]!==" "&&s[9]!=="a"){const a=h("invalid_leader",`Leader position 9 (encoding flag) is '${s[9]}'; expected 'a' (UTF-8) or ' ' (MARC-8). Defaulting to UTF-8.`);if(n)throw new Error(a.message);i.push(a)}return{record:{leader:s,fields:Ce(e,g,c,f?k:a=>R.decode(a),i,n,r)},warnings:i}}function ve(e){const t=z(e,{strict:!0});if(!t.record)throw new Error("Failed to parse MARC record in strict mode");return t.record}function Se(e){const t=e.slice(0,C);return R.decode(t)}function be(e,t,n){if(e.length!==C){const r=h("invalid_leader",`Leader length is ${e.length}, expected ${C}`);if(n)throw new Error(r.message);return t.push(r),!1}if(e[10]!=="2"){const r=h("invalid_leader",`Leader position 10 (indicator count) is '${e[10]}', expected '2'`);t.push(r)}if(e[11]!=="2"){const r=h("invalid_leader",`Leader position 11 (subfield code length) is '${e[11]}', expected '2'`);t.push(r)}return!0}function Fe(e,t,n,r){const i=[];for(let s=0;s<e.length;s+=y){if(t.length>=r){t.push(h("truncated_record",`Directory parsing halted after reaching maxWarnings limit (${r}); remaining ${e.length-s} bytes of directory not parsed.`));break}if(s+y>e.length)break;const o=e.slice(s,s+y),c=R.decode(o),l=c.substring(0,A),d=c.substring(A,A+P),g=c.substring(A+P,y),f=parseInt(d,10),a=parseInt(g,10);if(isNaN(f)||isNaN(a)){const w=h("invalid_directory",`Invalid directory entry for tag ${l}: length=${d}, position=${g}`);if(n)throw new Error(w.message);t.push(w);continue}i.push({tag:l,fieldLength:f,startingPosition:a})}return i}function Ce(e,t,n,r,i,s,o){const c=[];for(const l of t){if(i.length>=o){i.push(h("truncated_record",`Field parsing halted after reaching maxWarnings limit (${o}); not all directory entries were processed.`,void 0,l.tag));break}const d=n+l.startingPosition,g=d+l.fieldLength-1;if(d>=e.length||g>e.length){const a=h("invalid_field",`Field ${l.tag} out of bounds: start=${d}, end=${g}, buffer length=${e.length}`,d,l.tag);if(s)throw new Error(a.message);i.push(a);continue}let f;if(e[g]!==j){const a=h("invalid_field",`Field ${l.tag} does not end with a field terminator at byte ${g} (found 0x${(e[g]??0).toString(16).padStart(2,"0")}); using the full declared length without stripping a terminator byte.`,d,l.tag);if(s)throw new Error(a.message);i.push(a),f=e.slice(d,d+l.fieldLength)}else f=e.slice(d,g);if(l.tag.startsWith("00")){try{const a=r(f);c.push({tag:l.tag,data:a})}catch(a){const w=h("encoding_error",`Failed to decode control field ${l.tag}: ${a instanceof Error?a.message:String(a)}. Raw bytes (hex): ${q(f)}.`,d,l.tag);if(s)throw new Error(w.message);i.push(w),c.push({tag:l.tag,data:H(f)})}continue}if(f.length<2){const a=h("invalid_field",`Data field ${l.tag} too short for indicators: ${f.length} bytes`,d,l.tag);if(s)throw new Error(a.message);i.push(a);continue}try{const a=String.fromCharCode(f[0]??0),w=String.fromCharCode(f[1]??0),$=$e(f.slice(2),r,l.tag,i,s,o);c.push({tag:l.tag,indicator1:a,indicator2:w,subfields:$})}catch(a){const w=h("invalid_field",`Failed to parse data field ${l.tag}: ${a instanceof Error?a.message:String(a)}`,d,l.tag);if(s)throw new Error(w.message);i.push(w)}}return c}function $e(e,t,n,r,i,s){const o=[];let c=0;for(;c<e.length;){if(r.length>=s){r.push(h("truncated_record",`Subfield parsing halted after reaching maxWarnings limit (${s}) in field ${n}; not all subfields were processed.`,void 0,n));break}if(e[c]!==U){const f=h("invalid_field",`Expected subfield delimiter in field ${n} at position ${c}`,void 0,n);if(i)throw new Error(f.message);r.push(f);break}if(c++,c>=e.length)break;const l=String.fromCharCode(e[c]??0);c++;const d=c;for(;c<e.length&&e[c]!==U;)c++;const g=e.slice(d,c);try{const f=t(g);o.push({code:l,value:f})}catch(f){const a=h("encoding_error",`Failed to decode subfield ${n}$${l}: ${f instanceof Error?f.message:String(f)}. Raw bytes (hex): ${q(g)}.`,void 0,n);if(i)throw new Error(a.message);r.push(a),o.push({code:l,value:H(g)})}}return o}function h(e,t,n,r){return{type:e,message:t,position:n,tag:r}}function J(e,t,n,r){return{type:e,message:t,position:n,tag:r}}var ye=31,B=30,Ae=29,_=24,Ie=3,_e=4,Re=5;function Ne(e,t={}){return Y(e,t).bytes}function Y(e,t={}){De(e);const n=[],r=t.encoding==="marc8",i=new TextEncoder,s=r?(m,S)=>{const b=x(m);return b.lossyCount>0&&n.push(J("encoding_error",`MARC-8 encoding substituted ${b.lossyCount} character(s) with '?' because they have no MARC-8 equivalent.`,void 0,S)),b.bytes}:m=>i.encode(m),o=[],c=[];let l=0;for(const m of e.fields){const S=Me(m,ee=>s(ee,m.tag)),b=S.length+1,Q=m.tag.padEnd(Ie," ")+b.toString().padStart(_e,"0")+l.toString().padStart(Re,"0");o.push(Q),c.push(S),c.push(new Uint8Array([B])),l+=b}const d=i.encode(o.join("")),g=new Uint8Array(d.length+1);g.set(d),g[d.length]=B;const f=_+g.length,a=c.reduce((m,S)=>m+S.length,0),w=new Uint8Array(a);let $=0;for(const m of c)w.set(m,$),$+=m.length;const N=f+a+1,X=Te(e.leader,N,f,r),F=new Uint8Array(N);return F.set(i.encode(X),0),F.set(g,_),F.set(w,f),F[N-1]=Ae,{bytes:F,warnings:n}}function D(e){const t=e.charCodeAt(0);return t>=32&&t<=126}function De(e){for(const t of e.fields){if(typeof t.tag!="string"||t.tag.length!==3)throw new Error(`MARC field tag must be exactly 3 characters; got ${JSON.stringify(t.tag)}`);if(!u.isControlField(t)){if(t.indicator1.length!==1)throw new Error(`Field ${t.tag} indicator1 must be exactly 1 character; got ${JSON.stringify(t.indicator1)}`);if(!D(t.indicator1))throw new Error(`Field ${t.tag} indicator1 must be an ASCII printable character (U+0020–U+007E); got ${JSON.stringify(t.indicator1)}`);if(t.indicator2.length!==1)throw new Error(`Field ${t.tag} indicator2 must be exactly 1 character; got ${JSON.stringify(t.indicator2)}`);if(!D(t.indicator2))throw new Error(`Field ${t.tag} indicator2 must be an ASCII printable character (U+0020–U+007E); got ${JSON.stringify(t.indicator2)}`);for(const n of t.subfields){if(n.code.length!==1)throw new Error(`Field ${t.tag} subfield code must be exactly 1 character; got ${JSON.stringify(n.code)}`);if(!D(n.code))throw new Error(`Field ${t.tag} subfield code must be an ASCII printable character (U+0020–U+007E); got ${JSON.stringify(n.code)}`)}}}}function Me(e,t){if(u.isControlField(e))return t(e.data);const n=[new Uint8Array([e.indicator1.charCodeAt(0),e.indicator2.charCodeAt(0)])];for(const o of e.subfields){const c=new Uint8Array([ye,o.code.charCodeAt(0)]);n.push(c,t(o.value))}const r=n.reduce((o,c)=>o+c.length,0),i=new Uint8Array(r);let s=0;for(const o of n)i.set(o,s),s+=o.length;return i}function Te(e,t,n,r){let i=e.padEnd(_," ").substring(0,_);const s=t.toString().padStart(5,"0");if(s.length>5)throw new Error(`Record length ${t} exceeds maximum (99999)`);i=s+i.substring(5);const o=n.toString().padStart(5,"0");if(o.length>5)throw new Error(`Base address ${n} exceeds maximum (99999)`);return i=i.substring(0,12)+o+i.substring(17),i=i.substring(0,9)+(r?" ":"a")+i.substring(10),i}function E(e,t){return e.fields.find(n=>n.tag===t)}function xe(e,t){return e.fields.filter(n=>n.tag===t)}function p(e,t){return e.subfields.find(n=>n.code===t)?.value}function Le(e,t){return e.subfields.filter(n=>n.code===t).map(n=>n.value)}function Ue(e){return e.subfields.map(t=>({code:t.code,value:t.value}))}function Pe(e){const t=E(e,"245");if(!t||!u.isDataField(t))return;const n=p(t,"a")??"",r=p(t,"b")??"";return(n+" "+r).trim()||void 0}function Be(e){const t=E(e,"245");if(!(!t||!u.isDataField(t)))return p(t,"a")}function Oe(e){const t=E(e,"100");if(t&&u.isDataField(t))return p(t,"a");const n=E(e,"110");if(n&&u.isDataField(n))return p(n,"a")}function Ge(e){const t=E(e,"250");if(!(!t||!u.isDataField(t)))return p(t,"a")}function We(e){const t=E(e,"264");if(t&&u.isDataField(t)){const r=p(t,"b");if(r)return r}const n=E(e,"260");if(n&&u.isDataField(n))return p(n,"b")}function ke(e){const t=E(e,"264");if(t&&u.isDataField(t)){const r=p(t,"c");if(r)return r}const n=E(e,"260");if(n&&u.isDataField(n))return p(n,"c")}function je(e){const t=[];for(const n of e.fields)if(n.tag==="020"&&u.isDataField(n)){const r=p(n,"a");r&&t.push(r)}return t}function He(e){const t=E(e,"022");if(!(!t||!u.isDataField(t)))return p(t,"a")}function qe(e){const t=E(e,"010");if(!(!t||!u.isDataField(t)))return p(t,"a")}function ze(e){const t=[];for(const n of e.fields)if(n.tag.startsWith("6")&&u.isDataField(n)){const r=p(n,"a");r&&t.push(r)}return t}function Je(e){const t=E(e,"490");if(!(!t||!u.isDataField(t)))return p(t,"a")}function Z(e,t){if(e.length!==3||t.length!==3)return!1;for(let n=0;n<3;n++){const r=t[n],i=e[n];if(r==="."||r?.toUpperCase()==="X"){if(i&&!/\d/.test(i))return!1;continue}if(r!==i)return!1}return!0}function Ye(e,t){return e.fields.filter(n=>Z(n.tag,t))}function Ze(e,t){return e.fields.find(n=>Z(n.tag,t))}function L(e,t){return{...e,fields:[...e.fields,t]}}function Ke(e,t,n){const r=e.fields.findIndex(s=>s.tag===t);if(r===-1)return L(e,n);const i=Array.from(e.fields);return i.splice(r,0,n),{...e,fields:i}}function Ve(e,t,n){const r=e.fields.findIndex(s=>s.tag===t);if(r===-1)return L(e,n);const i=Array.from(e.fields);return i.splice(r+1,0,n),{...e,fields:i}}function Xe(e,t){const n=parseInt(t.tag,10);let r=e.fields.length;for(let s=0;s<e.fields.length;s++){const o=e.fields[s];if(o&&parseInt(o.tag,10)>n){r=s;break}}const i=Array.from(e.fields);return i.splice(r,0,t),{...e,fields:i}}function Qe(e,t){return{...e,fields:e.fields.filter(n=>n.tag!==t)}}function et(e,t){return{...e,fields:e.fields.filter(n=>n!==t)}}function K(e,t,n){return{...e,subfields:[...e.subfields,{code:t,value:n}]}}function tt(e,t){return{...e,subfields:e.subfields.filter(n=>n.code!==t)}}function nt(e,t,n){const r=e.subfields.findIndex(s=>s.code===t);if(r===-1)return K(e,t,n);const i=[...e.subfields];return i[r]={code:t,value:n},{...e,subfields:i}}function rt(e){const t=new Array(e.fields.length);for(let n=0;n<e.fields.length;n++){const r=e.fields[n];if(u.isControlField(r))t[n]={tag:r.tag,data:r.data};else{const i=new Array(r.subfields.length);for(let s=0;s<r.subfields.length;s++){const o=r.subfields[s];i[s]={code:o.code,value:o.value}}t[n]={tag:r.tag,indicator1:r.indicator1,indicator2:r.indicator2,subfields:i}}}return{leader:e.leader,fields:t}}function it(e,t,n=!1){if(e.leader!==t.leader||e.fields.length!==t.fields.length)return!1;const r=n?[...e.fields].sort(O):e.fields,i=n?[...t.fields].sort(O):t.fields;for(let s=0;s<r.length;s++){const o=r[s],c=i[s];if(!o||!c||!V(o,c))return!1}return!0}function V(e,t){if(e.tag!==t.tag)return!1;if(u.isControlField(e)&&u.isControlField(t))return e.data===t.data;if(!u.isControlField(e)&&!u.isControlField(t)){if(e.indicator1!==t.indicator1||e.indicator2!==t.indicator2||e.subfields.length!==t.subfields.length)return!1;for(let n=0;n<e.subfields.length;n++){const r=e.subfields[n],i=t.subfields[n];if(!r||!i||r.code!==i.code||r.value!==i.value)return!1}return!0}return!1}function O(e,t){return e.tag.localeCompare(t.tag)}exports.addSubfield=K;exports.appendField=L;exports.author=Oe;exports.cloneRecord=rt;exports.createWarning=J;exports.edition=Ge;exports.fieldsEqual=V;exports.getAllSubfields=Ue;exports.getField=E;exports.getFields=xe;exports.getFieldsByPattern=Ye;exports.getFirstFieldByPattern=Ze;exports.getSubfield=p;exports.getSubfields=Le;exports.insertFieldAfter=Ve;exports.insertFieldBefore=Ke;exports.insertGroupedField=Xe;exports.isControlField=u.isControlField;exports.isDataField=u.isDataField;exports.isbn=je;exports.issn=He;exports.lccn=qe;exports.marc8ToUnicode=k;exports.parseMarcRecord=z;exports.parseMarcRecordStrict=ve;exports.publicationDate=ke;exports.publisher=We;exports.recordsEqual=it;exports.removeField=et;exports.removeFields=Qe;exports.removeSubfield=tt;exports.replaceSubfield=nt;exports.serializeMarcRecord=Ne;exports.serializeMarcRecordWithWarnings=Y;exports.seriesStatement=Je;exports.subjects=ze;exports.title=Pe;exports.titleProper=Be;exports.unicodeToMarc8=me;exports.unicodeToMarc8WithStats=x;
2
+
3
+ //# sourceMappingURL=index.cjs.map