@spencerls/react-native-nfc 1.0.8 → 1.0.10

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.mjs CHANGED
@@ -4,21 +4,149 @@ var __export = (target, all) => {
4
4
  __defProp(target, name, { get: all[name], enumerable: true });
5
5
  };
6
6
 
7
- // src/nfc/a/index.ts
8
- var a_exports = {};
9
- __export(a_exports, {
10
- operations: () => operations,
11
- utils: () => utils
7
+ // src/nfc/ndef/builder.ts
8
+ import {
9
+ Ndef
10
+ } from "react-native-nfc-manager";
11
+ var mimeTypes = {
12
+ TEXT: "text/plain",
13
+ JSON: "application/json"
14
+ };
15
+ var Builder = class _Builder {
16
+ static records(b) {
17
+ return b(_Builder);
18
+ }
19
+ static message(b) {
20
+ return Ndef.encodeMessage(b(_Builder));
21
+ }
22
+ static record(init) {
23
+ const { tnf, type, id = [], payload = [] } = init;
24
+ const toBytes = (v) => typeof v === "string" ? Array.from(Buffer.from(v, "utf8")) : v;
25
+ return {
26
+ tnf,
27
+ type: toBytes(type),
28
+ id: toBytes(id),
29
+ payload: toBytes(payload)
30
+ };
31
+ }
32
+ static textRecord(text, lang = "en", encoding = "utf8", id) {
33
+ const record = Ndef.textRecord(text, lang, encoding);
34
+ if (id) record.id = Array.from(Buffer.from(id, "utf8"));
35
+ return record;
36
+ }
37
+ static uriRecord(uri, id) {
38
+ return Ndef.uriRecord(uri, id);
39
+ }
40
+ static jsonRecord(payload, id) {
41
+ return _Builder.mimeRecord(mimeTypes.JSON, payload, id);
42
+ }
43
+ static mimeRecord(mimeType, payload, id) {
44
+ const payloadBytes = typeof payload === "string" ? Array.from(Buffer.from(payload, "utf8")) : payload instanceof Uint8Array ? Array.from(payload) : payload;
45
+ const idBytes = id ? Array.from(Buffer.from(id, "utf8")) : [];
46
+ return _Builder.record({
47
+ tnf: Ndef.TNF_MIME_MEDIA,
48
+ type: mimeType,
49
+ id: idBytes,
50
+ payload: payloadBytes
51
+ });
52
+ }
53
+ static externalRecord(domain, type, payload, id) {
54
+ const recordType = `${domain}:${type}`;
55
+ const payloadBytes = typeof payload === "string" ? Array.from(Buffer.from(payload, "utf8")) : payload instanceof Uint8Array ? Array.from(payload) : payload;
56
+ const idBytes = id ? Array.from(Buffer.from(id, "utf8")) : [];
57
+ return _Builder.record({
58
+ tnf: Ndef.TNF_EXTERNAL_TYPE,
59
+ type: recordType,
60
+ id: idBytes,
61
+ payload: payloadBytes
62
+ });
63
+ }
64
+ static createEmpty() {
65
+ return _Builder.record({
66
+ tnf: Ndef.TNF_EMPTY,
67
+ type: [],
68
+ id: [],
69
+ payload: []
70
+ });
71
+ }
72
+ };
73
+
74
+ // src/nfc/ndef/internal/operations.ts
75
+ var operations_exports = {};
76
+ __export(operations_exports, {
77
+ readMessage: () => readMessage,
78
+ write: () => write
12
79
  });
80
+ import nfcManager, { Ndef as Ndef2 } from "react-native-nfc-manager";
13
81
 
14
- // src/nfc/a/operations.ts
15
- import NfcManager2, { NfcTech } from "react-native-nfc-manager";
82
+ // src/nfc/ndef/error.ts
83
+ var NdefError = class extends Error {
84
+ constructor(message) {
85
+ super(`[NDEF] ${message}`);
86
+ }
87
+ };
16
88
 
17
- // src/nfc/service.ts
89
+ // src/nfc/ndef/internal/operations.ts
90
+ function assertMessage(msg) {
91
+ if (!msg.ndefMessage || msg.ndefMessage.length === 0) {
92
+ throw new NdefError("NDEF message contains no NDEF records");
93
+ }
94
+ }
95
+ async function readMessage() {
96
+ const msg = await nfcManager.ndefHandler.getNdefMessage();
97
+ if (!msg) throw new NdefError("No NDEF message detected");
98
+ assertMessage(msg);
99
+ return msg;
100
+ }
101
+ async function write(records) {
102
+ if (records.length === 0) {
103
+ throw new NdefError("Cannot write an empty records array");
104
+ }
105
+ const bytes = Ndef2.encodeMessage(records);
106
+ await nfcManager.ndefHandler.writeNdefMessage(bytes);
107
+ }
108
+
109
+ // src/nfc/ndef/internal/tech.ts
18
110
  import { Platform } from "react-native";
19
- import NfcManager, {
111
+ import { NfcTech } from "react-native-nfc-manager";
112
+ var tech = Platform.OS === "android" ? [NfcTech.Ndef, NfcTech.NfcA] : [NfcTech.Ndef];
113
+
114
+ // src/nfc/ndef/internal/index.ts
115
+ var nfcNdefTag = {
116
+ ...operations_exports,
117
+ tech
118
+ };
119
+
120
+ // src/nfc/ndef/operations.ts
121
+ var operations_exports4 = {};
122
+ __export(operations_exports4, {
123
+ getStatus: () => getStatus,
124
+ makeReadOnly: () => makeReadOnly,
125
+ readFull: () => readFull,
126
+ readMessage: () => readMessage2,
127
+ write: () => write2,
128
+ writeExternal: () => writeExternal,
129
+ writeJson: () => writeJson,
130
+ writeMime: () => writeMime,
131
+ writeText: () => writeText,
132
+ writeUri: () => writeUri
133
+ });
134
+ import nfcManager4 from "react-native-nfc-manager";
135
+
136
+ // src/nfc/service.ts
137
+ import { Platform as Platform2 } from "react-native";
138
+ import nfcManager2, {
20
139
  NfcEvents
21
140
  } from "react-native-nfc-manager";
141
+
142
+ // src/nfc/error.ts
143
+ var NfcError = class extends Error {
144
+ constructor(message) {
145
+ super(`[NFC] ${message}`);
146
+ }
147
+ };
148
+
149
+ // src/nfc/service.ts
22
150
  var NfcService = class {
23
151
  constructor() {
24
152
  this.state = { mode: "idle", tag: null };
@@ -26,10 +154,10 @@ var NfcService = class {
26
154
  this.isProcessingTag = false;
27
155
  this.currentCooldownMs = 1500;
28
156
  this.readerModeFlags_ANDROID = null;
29
- NfcManager.start();
157
+ nfcManager2.start();
30
158
  }
31
159
  enableReaderMode_ANDROID(flags) {
32
- if (Platform.OS !== "android") return;
160
+ if (Platform2.OS !== "android") return;
33
161
  this.readerModeFlags_ANDROID = flags;
34
162
  }
35
163
  // -----------------------------
@@ -62,7 +190,7 @@ var NfcService = class {
62
190
  this.currentCooldownMs = (_a = options == null ? void 0 : options.cooldownMs) != null ? _a : 1500;
63
191
  this.isProcessingTag = false;
64
192
  this.setState({ mode: "starting", tag: null });
65
- NfcManager.setEventListener(
193
+ nfcManager2.setEventListener(
66
194
  NfcEvents.DiscoverTag,
67
195
  async (tag) => {
68
196
  var _a2;
@@ -89,12 +217,12 @@ var NfcService = class {
89
217
  );
90
218
  try {
91
219
  if (this.readerModeFlags_ANDROID) {
92
- await NfcManager.registerTagEvent({
220
+ await nfcManager2.registerTagEvent({
93
221
  isReaderModeEnabled: true,
94
222
  readerModeFlags: this.readerModeFlags_ANDROID
95
223
  });
96
224
  } else {
97
- await NfcManager.registerTagEvent();
225
+ await nfcManager2.registerTagEvent();
98
226
  }
99
227
  if (this.state.mode === "starting") {
100
228
  this.setState({ mode: "active" });
@@ -110,14 +238,14 @@ var NfcService = class {
110
238
  async stopReader() {
111
239
  if (["idle", "stopping"].includes(this.state.mode)) return;
112
240
  this.setState({ mode: "stopping" });
113
- NfcManager.setEventListener(NfcEvents.DiscoverTag, () => {
241
+ nfcManager2.setEventListener(NfcEvents.DiscoverTag, () => {
114
242
  });
115
243
  if (this.cooldownTimer) {
116
244
  clearTimeout(this.cooldownTimer);
117
245
  this.cooldownTimer = void 0;
118
246
  }
119
247
  try {
120
- await NfcManager.unregisterTagEvent();
248
+ await nfcManager2.unregisterTagEvent();
121
249
  } catch (err) {
122
250
  console.warn("[NFC] unregisterTagEvent error:", err);
123
251
  }
@@ -135,13 +263,13 @@ var NfcService = class {
135
263
  // -----------------------------
136
264
  // Technology sessions (NDEF, NfcV, etc.)
137
265
  // -----------------------------
138
- async withTechnology(tech, handler) {
266
+ async withTechnology(tech3, handler) {
139
267
  if (this.state.mode === "technology") {
140
- throw new Error("[NFC] Technology is already in use!");
268
+ throw new NfcError("Technology is already in use!");
141
269
  }
142
270
  if (this.readerModeFlags_ANDROID) {
143
271
  return this.withTechnologyReaderMode_ANDROID(
144
- tech,
272
+ tech3,
145
273
  handler,
146
274
  this.readerModeFlags_ANDROID
147
275
  );
@@ -155,26 +283,26 @@ var NfcService = class {
155
283
  await this.stopReader();
156
284
  }
157
285
  if (this.state.mode !== "idle") {
158
- throw new Error(
159
- `[NFC] Cannot start technology session in mode ${this.state.mode}`
286
+ throw new NfcError(
287
+ `Cannot start technology session in mode ${this.state.mode}`
160
288
  );
161
289
  }
162
290
  this.setState({ mode: "technology" });
163
291
  try {
164
- await NfcManager.requestTechnology(tech, {
292
+ await nfcManager2.requestTechnology(tech3, {
165
293
  alertMessage: "Hold near NFC tag"
166
294
  });
167
295
  const result = await handler();
168
- if (Platform.OS === "ios") {
169
- await NfcManager.setAlertMessageIOS("Success!");
296
+ if (Platform2.OS === "ios") {
297
+ await nfcManager2.setAlertMessageIOS("Success!");
170
298
  }
171
299
  return result;
172
300
  } catch (err) {
173
301
  const message = typeof err === "string" ? err : (err == null ? void 0 : err.message) || "Unknown NFC error";
174
- throw new Error(`[NFC] withTechnology error: ${message}`);
302
+ throw new NfcError(`withTechnology error: ${message}`);
175
303
  } finally {
176
304
  try {
177
- await NfcManager.cancelTechnologyRequest();
305
+ await nfcManager2.cancelTechnologyRequest();
178
306
  } catch {
179
307
  }
180
308
  this.setState({ mode: "idle", tag: null });
@@ -190,26 +318,24 @@ var NfcService = class {
190
318
  }
191
319
  }
192
320
  }
193
- async withTechnologyReaderMode_ANDROID(tech, handler, flags) {
321
+ async withTechnologyReaderMode_ANDROID(tech3, handler, flags) {
194
322
  const readerWasActive = ["starting", "active", "stopping"].includes(
195
323
  this.state.mode
196
324
  );
197
325
  this.isProcessingTag = true;
198
326
  this.setState({ mode: "technology" });
199
327
  try {
200
- await NfcManager.requestTechnology(tech, {
328
+ await nfcManager2.requestTechnology(tech3, {
201
329
  isReaderModeEnabled: true,
202
330
  readerModeFlags: flags
203
331
  });
204
332
  return await handler();
205
333
  } catch (err) {
206
334
  const message = typeof err === "string" ? err : (err == null ? void 0 : err.message) || "Unknown NFC error";
207
- throw new Error(
208
- `[NFC] withTechnologyReaderMode_ANDROID error: ${message}`
209
- );
335
+ throw new NfcError(`withTechnologyReaderMode_ANDROID error: ${message}`);
210
336
  } finally {
211
337
  try {
212
- await NfcManager.cancelTechnologyRequest();
338
+ await nfcManager2.cancelTechnologyRequest();
213
339
  } catch {
214
340
  }
215
341
  this.isProcessingTag = false;
@@ -219,311 +345,355 @@ var NfcService = class {
219
345
  };
220
346
  var nfcService = new NfcService();
221
347
 
222
- // src/nfc/a/operations.ts
223
- var operations = {
224
- async transceive(data) {
225
- return nfcService.withTechnology(NfcTech.NfcA, async () => {
226
- return await NfcManager2.transceive(data);
227
- });
228
- }
229
- };
348
+ // src/nfc/tag/internal/operations.ts
349
+ var operations_exports2 = {};
350
+ __export(operations_exports2, {
351
+ getTag: () => getTag
352
+ });
353
+ import nfcManager3 from "react-native-nfc-manager";
354
+ async function getTag() {
355
+ const tagEvent = await nfcManager3.getTag();
356
+ if (!tagEvent) throw new Error("No tag detected");
357
+ return tagEvent;
358
+ }
230
359
 
231
- // src/nfc/a/utils.ts
232
- var utils = {};
360
+ // src/nfc/tag/internal/index.ts
361
+ var nfcTag = {
362
+ ...operations_exports2
363
+ };
233
364
 
234
- // src/nfc/v/index.ts
235
- var v_exports = {};
236
- __export(v_exports, {
237
- operations: () => operations2,
238
- utils: () => utils2
365
+ // src/nfc/tag/operations.ts
366
+ var operations_exports3 = {};
367
+ __export(operations_exports3, {
368
+ getTag: () => getTag2
239
369
  });
370
+ async function getTag2(tech3) {
371
+ return nfcService.withTechnology(tech3, nfcTag.getTag);
372
+ }
240
373
 
241
- // src/nfc/v/operations.ts
242
- import NfcManager4 from "react-native-nfc-manager";
374
+ // src/nfc/ndef/operations.ts
375
+ async function getStatus() {
376
+ return await nfcManager4.ndefHandler.getNdefStatus();
377
+ }
378
+ async function readMessage2() {
379
+ return await nfcService.withTechnology(
380
+ nfcNdefTag.tech,
381
+ nfcNdefTag.readMessage
382
+ );
383
+ }
384
+ async function readFull() {
385
+ return await nfcService.withTechnology(nfcNdefTag.tech, async () => {
386
+ const tag = await nfcTag.getTag();
387
+ const message = await nfcNdefTag.readMessage();
388
+ return { message, tag };
389
+ });
390
+ }
391
+ async function write2(records) {
392
+ if (!records || records.length === 0) {
393
+ throw new NdefError("write: no NDEF records provided");
394
+ }
395
+ await nfcService.withTechnology(
396
+ nfcNdefTag.tech,
397
+ async () => await nfcNdefTag.write(records)
398
+ );
399
+ }
400
+ async function writeText(text, lang, encoding, id) {
401
+ const rec = Builder.textRecord(text, lang, encoding, id);
402
+ await write2([rec]);
403
+ }
404
+ async function writeUri(uri, id) {
405
+ const rec = Builder.uriRecord(uri, id);
406
+ await write2([rec]);
407
+ }
408
+ async function writeJson(data, id) {
409
+ let json;
410
+ try {
411
+ json = JSON.stringify(data);
412
+ } catch (e) {
413
+ throw new NdefError(`writeJson: value is not JSON serializable: ${e}`);
414
+ }
415
+ const rec = Builder.jsonRecord(json, id);
416
+ await write2([rec]);
417
+ }
418
+ async function writeMime(mimeType, payload, id) {
419
+ if (!mimeType || typeof mimeType !== "string") {
420
+ throw new NdefError("writeMime: mimeType must be a non-empty string");
421
+ }
422
+ const rec = Builder.mimeRecord(mimeType, payload, id);
423
+ await write2([rec]);
424
+ }
425
+ async function writeExternal(domain, type, payload, id) {
426
+ if (!domain || typeof domain !== "string") {
427
+ throw new NdefError("writeExternal: domain must be a non-empty string");
428
+ }
429
+ if (!type || typeof type !== "string") {
430
+ throw new NdefError("writeExternal: type must be a non-empty string");
431
+ }
432
+ const rec = Builder.externalRecord(domain, type, payload, id);
433
+ await write2([rec]);
434
+ }
435
+ async function makeReadOnly() {
436
+ await nfcService.withTechnology(
437
+ nfcNdefTag.tech,
438
+ nfcManager4.ndefHandler.makeReadOnly
439
+ );
440
+ }
243
441
 
244
- // src/nfc/v/internal.ts
245
- import NfcManager3 from "react-native-nfc-manager";
442
+ // src/nfc/v/internal/operations.ts
443
+ var operations_exports5 = {};
444
+ __export(operations_exports5, {
445
+ getSystemInfo: () => getSystemInfo,
446
+ readBlock: () => readBlock,
447
+ readBlocks: () => readBlocks,
448
+ transceive: () => transceive,
449
+ writeBlock: () => writeBlock,
450
+ writeBlocks: () => writeBlocks
451
+ });
452
+ import nfcManager5 from "react-native-nfc-manager";
246
453
 
247
- // src/nfc/v/utils.ts
248
- import { Platform as Platform2 } from "react-native";
249
- import { NfcTech as NfcTech2 } from "react-native-nfc-manager";
250
- var utils2 = {
251
- tech: Platform2.OS === "ios" ? [NfcTech2.Iso15693IOS] : NfcTech2.NfcV,
252
- Flags: {
253
- HIGH_DATA_RATE: 2,
254
- ADDRESSED: 32
255
- // If needed later: OPTION: 0x40 (not commonly used)
256
- },
257
- Commands: {
258
- READ_SINGLE_BLOCK: 32,
259
- WRITE_SINGLE_BLOCK: 33,
260
- GET_SYSTEM_INFO: 43
261
- },
262
- /**
263
- * Combine multiple flag bits into one byte.
264
- * Example: Flags.ADDRESSED | Flags.HIGH_DATA_RATE
265
- */
266
- flags(...bits) {
267
- return bits.reduce((acc, bit) => acc | bit, 0);
268
- },
269
- /**
270
- * Convert tag.id hex string (MSB->LSB) into reversed byte array (LSB->MSB)
271
- * ISO15693 requires reversed UID for addressed commands.
272
- */
273
- reverseUid(tagIdHex) {
274
- const bytes = [];
275
- for (let i = 0; i < tagIdHex.length; i += 2) {
276
- bytes.unshift(Number.parseInt(tagIdHex.substring(i, i + 2), 16));
277
- }
278
- return bytes;
279
- },
280
- /**
281
- * Build READ_SINGLE_BLOCK command.
282
- * FLAGS: addressed + high data rate by default.
283
- */
284
- buildReadBlock(uidReversed, blockNumber) {
285
- const flags = this.flags(this.Flags.ADDRESSED, this.Flags.HIGH_DATA_RATE);
286
- return [
287
- flags,
288
- this.Commands.READ_SINGLE_BLOCK,
289
- ...uidReversed,
290
- blockNumber
291
- ];
292
- },
293
- /**
294
- * Build WRITE_SINGLE_BLOCK command.
295
- * Note: data must match the block size (usually 4 or 8 bytes).
296
- */
297
- buildWriteBlock(uidReversed, blockNumber, data) {
298
- const flags = this.flags(this.Flags.ADDRESSED, this.Flags.HIGH_DATA_RATE);
299
- return [
300
- flags,
301
- this.Commands.WRITE_SINGLE_BLOCK,
302
- ...uidReversed,
303
- blockNumber,
304
- ...data
305
- ];
306
- },
307
- /**
308
- * Build GET_SYSTEM_INFO command.
309
- */
310
- buildGetSystemInfo(uidReversed) {
311
- return [this.Flags.HIGH_DATA_RATE, this.Commands.GET_SYSTEM_INFO];
312
- },
313
- /**
314
- * Parse a READ_SINGLE_BLOCK response.
315
- * Response format:
316
- * - byte[0] = status (0x00 = success)
317
- * - byte[1..] = block payload bytes
318
- */
319
- parseReadResponse(resp) {
320
- if (!resp || resp.length === 0) {
321
- throw new Error("Empty NFC-V response");
322
- }
323
- const status = resp[0];
324
- if (status === void 0) {
325
- throw new Error("Invalid NFC-V response: missing status byte");
326
- }
327
- if (status !== 0) {
328
- throw new Error(`Read failed. Status: 0x${status.toString(16)}`);
329
- }
330
- return new Uint8Array(resp.slice(1));
331
- },
332
- /**
333
- * Parse WRITE_SINGLE_BLOCK response.
334
- * Successful write has resp[0] === 0x00.
335
- */
336
- parseWriteResponse(resp) {
337
- if (!resp || resp.length === 0) {
338
- throw new Error("Empty NFC-V response");
339
- }
340
- const status = resp[0];
341
- if (status === void 0) {
342
- throw new Error("Invalid NFC-V response: missing status byte");
343
- }
344
- if (status !== 0) {
345
- throw new Error(`Write failed. Status: 0x${status.toString(16)}`);
346
- }
347
- },
348
- /**
349
- * Parse GET_SYSTEM_INFO response.
350
- * Returns: UID, DSFID, AFI, numberOfBlocks, blockSize, manufacturer
351
- */
352
- parseSystemInfo(resp) {
353
- var _a;
354
- if (!resp || resp.length < 2) {
355
- throw new Error("Invalid System Info response");
356
- }
357
- const status = resp[0];
358
- if (status === void 0 || status !== 0) {
359
- throw new Error("Invalid System Info response");
360
- }
361
- const flagsByte = resp[1];
362
- if (flagsByte === void 0) {
363
- throw new Error("Invalid System Info response: missing flags byte");
364
- }
365
- const infoFlags = flagsByte & 15;
366
- let offset = 2;
367
- const result = {};
368
- if (resp.length >= offset + 8) {
369
- const uidBytes = resp.slice(offset, offset + 8);
370
- result.uid = uidBytes.slice().reverse().map((b) => b.toString(16).padStart(2, "0")).join("").toUpperCase();
371
- offset += 8;
372
- }
373
- if (infoFlags & 1 && resp.length > offset) {
374
- result.dsfid = resp[offset++];
375
- }
376
- if (infoFlags & 2 && resp.length > offset) {
377
- result.afi = resp[offset++];
378
- }
379
- if (infoFlags & 4 && resp.length >= offset + 2) {
380
- const numBlocks = resp[offset++];
381
- const blkSize = resp[offset++];
382
- if (numBlocks !== void 0) {
383
- result.numberOfBlocks = numBlocks + 1;
384
- }
385
- if (blkSize !== void 0) {
386
- result.blockSize = blkSize + 1;
387
- }
388
- }
389
- if (infoFlags & 8 && resp.length > offset) {
390
- result.icReference = resp[offset++];
391
- }
392
- if (!result.blockSize) result.blockSize = 4;
393
- result.manufacturer = this.detectManufacturer((_a = result.uid) != null ? _a : "");
394
- return result;
395
- },
396
- /** Identify common manufacturers based on UID prefix */
397
- detectManufacturer(uid) {
398
- if (uid.startsWith("E004") || uid.startsWith("E006") || uid.startsWith("E016"))
399
- return "EM Microelectronic";
400
- if (uid.startsWith("E002")) return "STMicroelectronics";
401
- if (uid.startsWith("E007")) return "Texas Instruments";
402
- if (uid.startsWith("E010")) return "NXP";
403
- return "Unknown";
454
+ // src/nfc/v/error.ts
455
+ var VError = class extends Error {
456
+ constructor(message) {
457
+ super(`[V] ${message}`);
404
458
  }
405
459
  };
406
460
 
407
- // src/nfc/v/internal.ts
408
- async function readBlockRaw(tag, blockNumber) {
409
- const uid = utils2.reverseUid(tag.id);
410
- const cmd = utils2.buildReadBlock(uid, blockNumber);
411
- const resp = await NfcManager3.transceive(cmd);
412
- return utils2.parseReadResponse(resp);
413
- }
414
- async function writeBlockRaw(tag, blockNumber, data) {
415
- const uid = utils2.reverseUid(tag.id);
416
- const cmd = utils2.buildWriteBlock(uid, blockNumber, data);
417
- const resp = await NfcManager3.transceive(cmd);
418
- return utils2.parseWriteResponse(resp);
419
- }
420
- async function getSystemInfoRaw(tag) {
421
- const uid = utils2.reverseUid(tag.id);
422
- const cmd = utils2.buildGetSystemInfo(uid);
423
- const resp = await NfcManager3.transceive(cmd);
424
- return utils2.parseSystemInfo(resp);
461
+ // src/nfc/v/internal/utils.ts
462
+ var utils_exports = {};
463
+ __export(utils_exports, {
464
+ COMMANDS: () => COMMANDS,
465
+ FLAGS: () => FLAGS,
466
+ buildFlags: () => buildFlags,
467
+ buildGetSystemInfo: () => buildGetSystemInfo,
468
+ buildReadBlock: () => buildReadBlock,
469
+ buildWriteBlock: () => buildWriteBlock,
470
+ detectManufacturer: () => detectManufacturer,
471
+ parseReadResponse: () => parseReadResponse,
472
+ parseSystemInfo: () => parseSystemInfo,
473
+ parseWriteResponse: () => parseWriteResponse,
474
+ reverseUid: () => reverseUid
475
+ });
476
+ var FLAGS = {
477
+ HIGH_DATA_RATE: 2,
478
+ ADDRESSED: 32
479
+ // If needed later: OPTION: 0x40 (not commonly used)
480
+ };
481
+ var COMMANDS = {
482
+ READ_SINGLE_BLOCK: 32,
483
+ WRITE_SINGLE_BLOCK: 33,
484
+ GET_SYSTEM_INFO: 43
485
+ };
486
+ function buildFlags(...bits) {
487
+ return bits.reduce((acc, bit) => acc | bit, 0);
488
+ }
489
+ function reverseUid(tagIdHex) {
490
+ const bytes = [];
491
+ for (let i = 0; i < tagIdHex.length; i += 2) {
492
+ bytes.unshift(Number.parseInt(tagIdHex.substring(i, i + 2), 16));
493
+ }
494
+ return bytes;
495
+ }
496
+ function buildReadBlock(uidReversed, blockNumber) {
497
+ const flags = buildFlags(FLAGS.ADDRESSED, FLAGS.HIGH_DATA_RATE);
498
+ return [flags, COMMANDS.READ_SINGLE_BLOCK, ...uidReversed, blockNumber];
499
+ }
500
+ function buildWriteBlock(uidReversed, blockNumber, data) {
501
+ const flags = buildFlags(FLAGS.ADDRESSED, FLAGS.HIGH_DATA_RATE);
502
+ return [
503
+ flags,
504
+ COMMANDS.WRITE_SINGLE_BLOCK,
505
+ ...uidReversed,
506
+ blockNumber,
507
+ ...data
508
+ ];
509
+ }
510
+ function buildGetSystemInfo() {
511
+ return [FLAGS.HIGH_DATA_RATE, COMMANDS.GET_SYSTEM_INFO];
512
+ }
513
+ function parseReadResponse(resp) {
514
+ if (!resp || resp.length === 0) {
515
+ throw new Error("Empty NFC-V response");
516
+ }
517
+ const status = resp[0];
518
+ if (status === void 0) {
519
+ throw new Error("Invalid NFC-V response: missing status byte");
520
+ }
521
+ if (status !== 0) {
522
+ throw new Error(`Read failed. Status: 0x${status.toString(16)}`);
523
+ }
524
+ return new Uint8Array(resp.slice(1));
525
+ }
526
+ function parseWriteResponse(resp) {
527
+ if (!resp || resp.length === 0) {
528
+ throw new Error("Empty NFC-V response");
529
+ }
530
+ const status = resp[0];
531
+ if (status === void 0) {
532
+ throw new Error("Invalid NFC-V response: missing status byte");
533
+ }
534
+ if (status !== 0) {
535
+ throw new Error(`Write failed. Status: 0x${status.toString(16)}`);
536
+ }
537
+ }
538
+ function parseSystemInfo(resp) {
539
+ var _a;
540
+ if (!resp || resp.length < 2) {
541
+ throw new Error("Invalid System Info response");
542
+ }
543
+ const status = resp[0];
544
+ if (status === void 0 || status !== 0) {
545
+ throw new Error("Invalid System Info response");
546
+ }
547
+ const flagsByte = resp[1];
548
+ if (flagsByte === void 0) {
549
+ throw new Error("Invalid System Info response: missing flags byte");
550
+ }
551
+ const infoFlags = flagsByte & 15;
552
+ let offset = 2;
553
+ const result = {};
554
+ if (resp.length >= offset + 8) {
555
+ const uidBytes = resp.slice(offset, offset + 8);
556
+ result.uid = uidBytes.slice().reverse().map((b) => b.toString(16).padStart(2, "0")).join("").toUpperCase();
557
+ offset += 8;
558
+ }
559
+ if (infoFlags & 1 && resp.length > offset) {
560
+ result.dsfid = resp[offset++];
561
+ }
562
+ if (infoFlags & 2 && resp.length > offset) {
563
+ result.afi = resp[offset++];
564
+ }
565
+ if (infoFlags & 4 && resp.length >= offset + 2) {
566
+ const numBlocks = resp[offset++];
567
+ const blkSize = resp[offset++];
568
+ if (numBlocks !== void 0) {
569
+ result.numberOfBlocks = numBlocks + 1;
570
+ }
571
+ if (blkSize !== void 0) {
572
+ result.blockSize = blkSize + 1;
573
+ }
574
+ }
575
+ if (infoFlags & 8 && resp.length > offset) {
576
+ result.icReference = resp[offset++];
577
+ }
578
+ if (!result.blockSize) result.blockSize = 4;
579
+ result.manufacturer = detectManufacturer((_a = result.uid) != null ? _a : "");
580
+ return result;
581
+ }
582
+ function detectManufacturer(uid) {
583
+ if (uid.startsWith("E004") || uid.startsWith("E006") || uid.startsWith("E016"))
584
+ return "EM Microelectronic";
585
+ if (uid.startsWith("E002")) return "STMicroelectronics";
586
+ if (uid.startsWith("E007")) return "Texas Instruments";
587
+ if (uid.startsWith("E010")) return "NXP";
588
+ return "Unknown";
425
589
  }
426
590
 
427
- // src/nfc/v/operations.ts
428
- var operations2 = {
429
- async withVTag(handler) {
430
- return nfcService.withTechnology(utils2.tech, async () => {
431
- const tag = await NfcManager4.getTag();
432
- if (!(tag == null ? void 0 : tag.id)) throw new Error("No NFC-V tag detected");
433
- return handler(tag);
434
- });
435
- },
436
- async writeBlockNfcV(blockNumber, data) {
437
- return this.withVTag((tag) => writeBlockRaw(tag, blockNumber, data));
438
- },
439
- async readBlockNfcV(blockNumber) {
440
- return this.withVTag((tag) => readBlockRaw(tag, blockNumber));
441
- },
442
- async getSystemInfoNfcV() {
443
- return this.withVTag((tag) => getSystemInfoRaw(tag));
591
+ // src/nfc/v/internal/operations.ts
592
+ async function transceive(bytes) {
593
+ return await nfcManager5.nfcVHandler.transceive(bytes);
594
+ }
595
+ async function readBlock(tagId, blockNumber) {
596
+ const uid = reverseUid(tagId);
597
+ const cmd = buildReadBlock(uid, blockNumber);
598
+ const resp = await transceive(cmd);
599
+ return parseReadResponse(resp);
600
+ }
601
+ async function readBlocks(tagId, startBlock, endBlock) {
602
+ const data = new Uint8Array();
603
+ let offset = 0;
604
+ for (let i = startBlock; i < endBlock; i++) {
605
+ const block = await readBlock(tagId, i);
606
+ data.set(block, offset);
607
+ offset += block.length;
444
608
  }
445
- };
609
+ return data;
610
+ }
611
+ async function writeBlock(tagId, blockNumber, data) {
612
+ const uid = reverseUid(tagId);
613
+ const cmd = buildWriteBlock(uid, blockNumber, data);
614
+ const resp = await transceive(cmd);
615
+ parseWriteResponse(resp);
616
+ }
617
+ async function writeBlocks(tagId, blockNumber, data) {
618
+ for (let i = 0; i < data.length; i++) {
619
+ const blockData = data[i];
620
+ if (blockData === void 0) {
621
+ throw new VError(`No data provided for block at index ${i}`);
622
+ }
623
+ await writeBlock(tagId, blockNumber + i, blockData);
624
+ }
625
+ }
626
+ async function getSystemInfo() {
627
+ const cmd = buildGetSystemInfo();
628
+ const resp = await transceive(cmd);
629
+ return parseSystemInfo(resp);
630
+ }
446
631
 
447
- // src/nfc/ndef/index.ts
448
- var ndef_exports = {};
449
- __export(ndef_exports, {
450
- operations: () => operations3,
451
- utils: () => utils3
452
- });
632
+ // src/nfc/v/internal/tech.ts
633
+ import { Platform as Platform3 } from "react-native";
634
+ import { NfcTech as NfcTech2 } from "react-native-nfc-manager";
635
+ var tech2 = Platform3.OS === "ios" ? [NfcTech2.Iso15693IOS] : NfcTech2.NfcV;
453
636
 
454
- // src/nfc/ndef/operations.ts
455
- import NfcManager5, {
456
- Ndef,
457
- NfcTech as NfcTech3
458
- } from "react-native-nfc-manager";
459
- var operations3 = {
460
- async writeNdef(records) {
461
- await nfcService.withTechnology([NfcTech3.Ndef, NfcTech3.NfcA], async () => {
462
- const bytes = Ndef.encodeMessage(records);
463
- await NfcManager5.ndefHandler.writeNdefMessage(bytes);
464
- });
465
- },
466
- writeTextNdef(text) {
467
- const record = Ndef.textRecord(text);
468
- return this.writeNdef([record]);
469
- },
470
- writeUriNdef(uri) {
471
- const record = Ndef.uriRecord(uri);
472
- return this.writeNdef([record]);
473
- }
637
+ // src/nfc/v/internal/index.ts
638
+ var nfcVTag = {
639
+ ...operations_exports5,
640
+ tech: tech2,
641
+ utils: utils_exports
474
642
  };
475
643
 
476
- // src/nfc/ndef/utils.ts
477
- var utils3 = {};
644
+ // src/nfc/v/operations.ts
645
+ var operations_exports6 = {};
646
+ __export(operations_exports6, {
647
+ getSystemInfo: () => getSystemInfo2,
648
+ readBlock: () => readBlock2,
649
+ readBlocks: () => readBlocks2,
650
+ writeBlock: () => writeBlock2,
651
+ writeBlocks: () => writeBlocks2
652
+ });
653
+ async function writeBlock2(blockNumber, data) {
654
+ await nfcService.withTechnology(nfcVTag.tech, async () => {
655
+ const tag = await nfcTag.getTag();
656
+ if (!(tag == null ? void 0 : tag.id)) throw new VError("No NFC-V tag id detected");
657
+ await nfcVTag.writeBlock(tag.id, blockNumber, data);
658
+ });
659
+ }
660
+ async function writeBlocks2(blockNumber, data) {
661
+ await nfcService.withTechnology(nfcVTag.tech, async () => {
662
+ const tag = await nfcTag.getTag();
663
+ if (!(tag == null ? void 0 : tag.id)) throw new VError("No NFC-V tag id detected");
664
+ nfcVTag.writeBlocks(tag.id, blockNumber, data);
665
+ });
666
+ }
667
+ async function readBlock2(blockNumber) {
668
+ return await nfcService.withTechnology(nfcVTag.tech, async () => {
669
+ const tag = await nfcTag.getTag();
670
+ if (!(tag == null ? void 0 : tag.id)) throw new VError("No NFC-V tag id detected");
671
+ return await nfcVTag.readBlock(tag.id, blockNumber);
672
+ });
673
+ }
674
+ async function readBlocks2(startBlock, endBlock) {
675
+ return await nfcService.withTechnology(nfcVTag.tech, async () => {
676
+ const tag = await nfcTag.getTag();
677
+ if (!(tag == null ? void 0 : tag.id)) throw new Error("No NFC-V tag id detected");
678
+ return await nfcVTag.readBlocks(tag.id, startBlock, endBlock);
679
+ });
680
+ }
681
+ async function getSystemInfo2() {
682
+ return await nfcService.withTechnology(nfcVTag.tech, nfcVTag.getSystemInfo);
683
+ }
478
684
 
479
685
  // src/nfc/namespace.ts
480
686
  var nfc = {
481
687
  service: nfcService,
482
- /** ISO15693 protocol helpers and high-level operations */
483
- v: {
484
- ...operations2,
485
- // NfcVOperations, nfcV
486
- utils: utils2
487
- },
488
- /** NFC-A / Type 2 helpers and operations */
489
- a: {
490
- ...operations,
491
- utils
492
- },
493
- /** NDEF read/write utilities and operations */
494
- ndef: {
495
- ...operations3,
496
- utils: utils3
497
- }
688
+ v: { ...operations_exports6 },
689
+ ndef: { ...operations_exports4, Builder },
690
+ tag: { ...operations_exports3 }
498
691
  };
499
692
 
500
- // src/react/nfc-provider.tsx
501
- import {
502
- createContext,
503
- useContext,
504
- useEffect,
505
- useState
506
- } from "react";
507
- import { jsx } from "react/jsx-runtime";
508
- var NfcContext = createContext(null);
509
- function NfcProvider({ children }) {
510
- const [state, setState] = useState(nfcService.getState());
511
- useEffect(() => {
512
- const unsubscribe = nfcService.subscribe(setState);
513
- return unsubscribe;
514
- }, []);
515
- return /* @__PURE__ */ jsx(NfcContext.Provider, { value: { state, service: nfcService }, children });
516
- }
517
- function useNfcContext() {
518
- const ctx = useContext(NfcContext);
519
- if (!ctx) throw new Error("useNfcContext must be inside <NfcProvider>");
520
- return ctx;
521
- }
522
-
523
693
  // src/react/use-nfc.ts
524
- import { useEffect as useEffect2 } from "react";
694
+ import { useEffect } from "react";
525
695
  function useNfc(onTag, options) {
526
- useEffect2(() => {
696
+ useEffect(() => {
527
697
  nfcService.startReader(
528
698
  async (tag) => {
529
699
  if (!tag.id) return;
@@ -553,27 +723,27 @@ function useNfcReader() {
553
723
  }
554
724
 
555
725
  // src/react/use-nfc-state.ts
556
- import { useEffect as useEffect3, useState as useState2 } from "react";
726
+ import { useEffect as useEffect2, useState } from "react";
557
727
  function useNfcState() {
558
- const [nfcState, setNfcState] = useState2(nfcService.getState());
559
- useEffect3(() => nfcService.subscribe(setNfcState), []);
728
+ const [nfcState, setNfcState] = useState(nfcService.getState());
729
+ useEffect2(() => nfcService.subscribe(setNfcState), []);
560
730
  return nfcState;
561
731
  }
562
732
 
563
733
  // src/react/use-nfc-technology.ts
564
- import NfcManager6, {
565
- Ndef as Ndef2,
566
- NfcTech as NfcTech4
734
+ import NfcManager, {
735
+ Ndef as Ndef3,
736
+ NfcTech as NfcTech3
567
737
  } from "react-native-nfc-manager";
568
738
  function useNfcTechnology() {
569
739
  async function writeNdef(records) {
570
- return nfcService.withTechnology(NfcTech4.Ndef, async () => {
571
- const bytes = Ndef2.encodeMessage(records);
572
- await NfcManager6.ndefHandler.writeNdefMessage(bytes);
740
+ return nfcService.withTechnology(NfcTech3.Ndef, async () => {
741
+ const bytes = Ndef3.encodeMessage(records);
742
+ await NfcManager.ndefHandler.writeNdefMessage(bytes);
573
743
  });
574
744
  }
575
- async function runWithTech(tech, fn) {
576
- return nfcService.withTechnology(tech, fn);
745
+ async function runWithTech(tech3, fn) {
746
+ return nfcService.withTechnology(tech3, fn);
577
747
  }
578
748
  return {
579
749
  writeNdef,
@@ -581,14 +751,12 @@ function useNfcTechnology() {
581
751
  };
582
752
  }
583
753
  export {
584
- NfcProvider,
585
754
  nfc,
586
- a_exports as nfcA,
587
- ndef_exports as nfcNdef,
755
+ nfcNdefTag,
588
756
  nfcService,
589
- v_exports as nfcV,
757
+ nfcTag,
758
+ nfcVTag,
590
759
  useNfc,
591
- useNfcContext,
592
760
  useNfcReader,
593
761
  useNfcState,
594
762
  useNfcTechnology