records.ts (4610B)
1 import type { 2 NdefMessage, 3 NdefMessageInit, 4 NdefRecord, 5 NdefRecordInit, 6 NdefReadingEvent, 7 NfcMessage, 8 NfcMessageInput, 9 NfcRecord, 10 NfcRecordData, 11 NfcRecordInput, 12 NfcReadPayload, 13 NfcTextEncoding 14 } from "./types.js"; 15 16 export type NfcJsonPrimitive = string | number | boolean | null; 17 export type NfcJsonValue = NfcJsonPrimitive | NfcJsonValue[] | { [key: string]: NfcJsonValue }; 18 19 export type NfcRecordTextOptions = { 20 id?: string; 21 lang?: string; 22 encoding?: NfcTextEncoding; 23 }; 24 25 export type NfcRecordUrlOptions = { 26 id?: string; 27 }; 28 29 export type NfcRecordMimeOptions = { 30 id?: string; 31 }; 32 33 export type NfcRecordJsonOptions = { 34 id?: string; 35 media_type?: string; 36 }; 37 38 export const nfc_record_text = (text: string, opts?: NfcRecordTextOptions): NfcRecordInput => { 39 return { 40 record_type: "text", 41 data: text, 42 id: opts?.id, 43 lang: opts?.lang, 44 encoding: opts?.encoding 45 }; 46 }; 47 48 export const nfc_record_url = (url: string, opts?: NfcRecordUrlOptions): NfcRecordInput => { 49 return { 50 record_type: "url", 51 data: url, 52 id: opts?.id 53 }; 54 }; 55 56 export const nfc_record_mime = (media_type: string, data: NfcRecordData, opts?: NfcRecordMimeOptions): NfcRecordInput => { 57 return { 58 record_type: "mime", 59 media_type, 60 data, 61 id: opts?.id 62 }; 63 }; 64 65 export const nfc_record_json = (value: NfcJsonValue, opts?: NfcRecordJsonOptions): NfcRecordInput => { 66 return { 67 record_type: "mime", 68 media_type: opts?.media_type ?? "application/json", 69 data: JSON.stringify(value), 70 id: opts?.id 71 }; 72 }; 73 74 export const nfc_message_from_records = (records: NfcRecordInput[]): NfcMessageInput => { 75 return { records }; 76 }; 77 78 export const nfc_message_text = (text: string, opts?: NfcRecordTextOptions): NfcMessageInput => { 79 return nfc_message_from_records([nfc_record_text(text, opts)]); 80 }; 81 82 export const nfc_message_url = (url: string, opts?: NfcRecordUrlOptions): NfcMessageInput => { 83 return nfc_message_from_records([nfc_record_url(url, opts)]); 84 }; 85 86 export const nfc_message_mime = (media_type: string, data: NfcRecordData, opts?: NfcRecordMimeOptions): NfcMessageInput => { 87 return nfc_message_from_records([nfc_record_mime(media_type, data, opts)]); 88 }; 89 90 export const nfc_message_json = (value: NfcJsonValue, opts?: NfcRecordJsonOptions): NfcMessageInput => { 91 return nfc_message_from_records([nfc_record_json(value, opts)]); 92 }; 93 94 export const nfc_record_data_bytes = (record: NfcRecord): Uint8Array | undefined => { 95 const data = record.data; 96 if (!data) return; 97 if (typeof data === "string") { 98 if (typeof TextEncoder === "undefined") return; 99 return new TextEncoder().encode(data); 100 } 101 if (data instanceof ArrayBuffer) return new Uint8Array(data); 102 if (ArrayBuffer.isView(data)) return new Uint8Array(data.buffer, data.byteOffset, data.byteLength); 103 return; 104 }; 105 106 export const nfc_record_data_text = (record: NfcRecord): string | undefined => { 107 const data = record.data; 108 if (typeof data === "string") return data; 109 const bytes = nfc_record_data_bytes(record); 110 if (!bytes) return; 111 if (typeof TextDecoder === "undefined") return; 112 const encoding = record.encoding === "utf-16" ? "utf-16" : "utf-8"; 113 try { 114 return new TextDecoder(encoding).decode(bytes); 115 } catch { 116 return; 117 } 118 }; 119 120 export const nfc_record_to_web = (record: NfcRecordInput): NdefRecordInit => { 121 return { 122 recordType: record.record_type, 123 mediaType: record.media_type, 124 id: record.id, 125 encoding: record.encoding, 126 lang: record.lang, 127 data: record.data 128 }; 129 }; 130 131 export const nfc_message_to_web = (message: NfcMessageInput): NdefMessageInit => { 132 return { 133 records: message.records.map(nfc_record_to_web) 134 }; 135 }; 136 137 export const nfc_record_from_web = (record: NdefRecord): NfcRecord => { 138 return { 139 record_type: record.recordType, 140 media_type: record.mediaType, 141 id: record.id, 142 encoding: record.encoding, 143 lang: record.lang, 144 data: record.data ?? undefined 145 }; 146 }; 147 148 export const nfc_message_from_web = (message: NdefMessage): NfcMessage => { 149 return { 150 records: message.records.map(nfc_record_from_web) 151 }; 152 }; 153 154 export const nfc_read_payload_from_event = (event: NdefReadingEvent): NfcReadPayload => { 155 return { 156 message: nfc_message_from_web(event.message), 157 serial_number: event.serialNumber ?? undefined, 158 timestamp_ms: Date.now() 159 }; 160 };