@spencerls/react-native-nfc 1.0.8 → 1.0.9

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