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