@exxili/capacitor-nfc 0.0.11 → 0.0.13

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.
@@ -1,5 +1,6 @@
1
1
  package com.exxili.capacitornfc
2
2
 
3
+ import android.app.ActivityOptions
3
4
  import android.app.PendingIntent
4
5
  import android.content.Intent
5
6
  import android.content.IntentFilter
@@ -22,7 +23,10 @@ import android.nfc.tech.NfcB
22
23
  import android.nfc.tech.NfcBarcode
23
24
  import android.nfc.tech.NfcF
24
25
  import android.nfc.tech.NfcV
26
+ import android.os.Build
27
+ import android.os.Bundle
25
28
  import android.util.Log
29
+ import androidx.annotation.RequiresApi
26
30
  import com.getcapacitor.JSArray
27
31
  import com.getcapacitor.JSObject
28
32
  import com.getcapacitor.Plugin
@@ -53,6 +57,7 @@ class NFCPlugin : Plugin() {
53
57
  NfcV::class.java.name
54
58
  ))
55
59
 
60
+ @RequiresApi(Build.VERSION_CODES.TIRAMISU)
56
61
  public override fun handleOnNewIntent(intent: Intent?) {
57
62
  super.handleOnNewIntent(intent)
58
63
 
@@ -66,9 +71,9 @@ class NFCPlugin : Plugin() {
66
71
  writeMode = false
67
72
  recordsBuffer = null
68
73
  }
69
- else if (ACTION_NDEF_DISCOVERED == intent.action || ACTION_TAG_DISCOVERED == intent.action) {
74
+ else if (ACTION_NDEF_DISCOVERED == intent.action || ACTION_TAG_DISCOVERED == intent.action || ACTION_TECH_DISCOVERED == intent.action) {
70
75
  Log.d("NFC", "READ MODE START")
71
- handleReadTag(intent)
76
+ handleReadTag(intent)
72
77
  }
73
78
  }
74
79
 
@@ -115,8 +120,28 @@ class NFCPlugin : Plugin() {
115
120
  addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
116
121
  }
117
122
 
123
+ val pendingIntentFlags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
124
+ PendingIntent.FLAG_MUTABLE
125
+ } else {
126
+ PendingIntent.FLAG_UPDATE_CURRENT
127
+ }
128
+
129
+ var activityOptionsBundle: Bundle? = null
130
+
131
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { // API 35 (Android 15)
132
+ activityOptionsBundle = ActivityOptions.makeBasic().apply {
133
+ setPendingIntentCreatorBackgroundActivityStartMode(ActivityOptions.MODE_BACKGROUND_ACTIVITY_START_ALLOWED)
134
+ }.toBundle()
135
+ }
136
+
118
137
  val pendingIntent =
119
- PendingIntent.getActivity(this.activity, 0, intent, PendingIntent.FLAG_MUTABLE)
138
+ PendingIntent.getActivity(
139
+ this.activity,
140
+ 0,
141
+ intent,
142
+ pendingIntentFlags,
143
+ activityOptionsBundle
144
+ )
120
145
 
121
146
  val intentFilter: Array<IntentFilter> =
122
147
  arrayOf(
@@ -139,6 +164,7 @@ class NFCPlugin : Plugin() {
139
164
  )
140
165
  }
141
166
 
167
+ @RequiresApi(Build.VERSION_CODES.TIRAMISU)
142
168
  private fun handleWriteTag(intent: Intent) {
143
169
  val records = recordsBuffer?.toList<JSONObject>()
144
170
  if(records != null) {
@@ -160,20 +186,49 @@ class NFCPlugin : Plugin() {
160
186
  return
161
187
  }
162
188
 
163
- val typeBytes = type.toByteArray(Charsets.UTF_8)
164
189
  val payloadBytes = ByteArray(payload.length())
165
190
  for(i in 0 until payload.length()) {
166
191
  payloadBytes[i] = payload.getInt(i).toByte()
167
192
  }
168
193
 
169
- ndefRecords.add(
170
- NdefRecord(
194
+ val (tnf, typeBytes) = when {
195
+ type == "T" || type == "U" -> Pair(
171
196
  NdefRecord.TNF_WELL_KNOWN,
197
+ type.toByteArray(Charsets.UTF_8)
198
+ )
199
+ type.contains("/") -> Pair(
200
+ NdefRecord.TNF_MIME_MEDIA,
201
+ type.toByteArray(Charsets.US_ASCII)
202
+ )
203
+ else -> Pair(
204
+ NdefRecord.TNF_EXTERNAL_TYPE,
205
+ type.toByteArray(Charsets.UTF_8)
206
+ )
207
+ }
208
+
209
+ val record = if (tnf == NdefRecord.TNF_MIME_MEDIA) {
210
+ try {
211
+ NdefRecord.createMime(type, payloadBytes)
212
+ } catch (e: IllegalArgumentException) {
213
+ notifyListeners(
214
+ "nfcError",
215
+ JSObject().put(
216
+ "error",
217
+ "Invalid MIME type for record"
218
+ )
219
+ )
220
+ return
221
+ }
222
+ } else {
223
+ NdefRecord(
224
+ tnf,
172
225
  typeBytes,
173
226
  ByteArray(0),
174
227
  payloadBytes
175
228
  )
176
- )
229
+ }
230
+
231
+ ndefRecords.add(record)
177
232
  }
178
233
 
179
234
  val ndefMessage = NdefMessage(ndefRecords.toTypedArray())
@@ -284,61 +339,121 @@ class NFCPlugin : Plugin() {
284
339
  }
285
340
  }
286
341
 
342
+ @RequiresApi(Build.VERSION_CODES.TIRAMISU)
287
343
  private fun handleReadTag(intent: Intent) {
288
344
  val jsResponse = JSObject()
289
-
290
345
  val ndefMessages = JSArray()
291
346
 
292
- when (intent.action) {
293
- NfcAdapter.ACTION_NDEF_DISCOVERED -> {
294
- val receivedMessages = intent.getParcelableArrayExtra(
295
- EXTRA_NDEF_MESSAGES,
296
- NdefMessage::class.java
297
- )
347
+ // Get tag information regardless of NDEF content
348
+ val tag: Tag? = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG, Tag::class.java)
349
+ val tagInfo = tag?.let { extractTagInfo(it) }
298
350
 
299
- receivedMessages?.also { rawMessages ->
300
- for (message in rawMessages) {
301
- val ndefRecords = JSArray()
302
- for (record in message.records) {
303
- val rec = JSObject()
304
- rec.put("type", String(record.type, Charsets.UTF_8))
305
- rec.put("payload", Base64.getEncoder().encodeToString(record.payload))
306
- ndefRecords.put(rec)
307
- }
351
+ // Try to obtain raw NDEF messages first (ACTION_NDEF_DISCOVERED path)
352
+ val receivedMessages = intent.getParcelableArrayExtra(
353
+ EXTRA_NDEF_MESSAGES,
354
+ NdefMessage::class.java
355
+ )
308
356
 
309
- val msg = JSObject()
310
- msg.put("records", ndefRecords)
311
- ndefMessages.put(msg)
357
+ if (receivedMessages != null && receivedMessages.isNotEmpty()) {
358
+ // Standard NDEF-discovered path
359
+ for (message in receivedMessages) {
360
+ ndefMessages.put(ndefMessageToJS(message))
361
+ }
362
+ } else {
363
+ // For ACTION_TAG_DISCOVERED or ACTION_TECH_DISCOVERED we may still have an NDEF tag.
364
+ var added = false
365
+ if (tag != null) {
366
+ val ndef = Ndef.get(tag)
367
+ if (ndef != null) {
368
+ try {
369
+ ndef.connect()
370
+ // Prefer cached message to avoid additional IO if available
371
+ val message: NdefMessage? = ndef.cachedNdefMessage ?: try {
372
+ ndef.ndefMessage
373
+ } catch (e: Exception) { null }
374
+ if (message != null) {
375
+ ndefMessages.put(ndefMessageToJS(message))
376
+ added = true
377
+ }
378
+ } catch (e: Exception) {
379
+ Log.w("NFC", "Failed to read NDEF message from TECH/TAG intent: ${e.message}")
380
+ } finally {
381
+ try { ndef.close() } catch (_: Exception) {}
312
382
  }
313
383
  }
314
- }
315
-
316
- NfcAdapter.ACTION_TAG_DISCOVERED -> {
317
- val tagId = intent.getByteArrayExtra(NfcAdapter.EXTRA_ID)
318
- val result = if (tagId != null) byteArrayToHexString(tagId) else ""
319
-
320
- val rec = JSObject()
321
- rec.put("type", "ID")
322
- rec.put("payload", Base64.getEncoder().encodeToString(result.toByteArray()))
323
384
 
324
- val ndefRecords = JSArray()
325
- ndefRecords.put(rec)
326
-
327
- val msg = JSObject()
328
- msg.put("records", ndefRecords)
329
- ndefMessages.put(msg)
385
+ // If no NDEF message found, fallback to tag ID (legacy behavior)
386
+ if (!added) {
387
+ val tagId = intent.getByteArrayExtra(NfcAdapter.EXTRA_ID) ?: tag.id
388
+ val result = if (tagId != null) byteArrayToHexString(tagId) else ""
389
+ val rec = JSObject()
390
+ rec.put("type", "ID")
391
+ rec.put("payload", Base64.getEncoder().encodeToString(result.toByteArray()))
392
+ val ndefRecords = JSArray().apply { put(rec) }
393
+ val msg = JSObject().apply { put("records", ndefRecords) }
394
+ ndefMessages.put(msg)
395
+ }
330
396
  }
331
397
  }
332
398
 
333
399
  jsResponse.put("messages", ndefMessages)
400
+ // Always include tag information if available
401
+ if (tagInfo != null) {
402
+ jsResponse.put("tagInfo", tagInfo)
403
+ }
334
404
  this.notifyListeners("nfcTag", jsResponse)
335
405
  }
336
406
 
407
+ private fun extractTagInfo(tag: Tag): JSObject {
408
+ val tagInfo = JSObject()
409
+
410
+ // Always include UID
411
+ val uid = byteArrayToHexString(tag.id)
412
+ tagInfo.put("uid", uid)
413
+
414
+ // Include technology types
415
+ val techTypes = JSArray()
416
+ for (tech in tag.techList) {
417
+ techTypes.put(tech)
418
+ }
419
+ tagInfo.put("techTypes", techTypes)
420
+
421
+ // Try to get NDEF-specific information
422
+ val ndef = Ndef.get(tag)
423
+ if (ndef != null) {
424
+ try {
425
+ ndef.connect()
426
+ tagInfo.put("maxSize", ndef.maxSize)
427
+ tagInfo.put("isWritable", ndef.isWritable)
428
+ tagInfo.put("type", ndef.type)
429
+ } catch (e: Exception) {
430
+ Log.w("NFC", "Failed to read NDEF tag info: ${e.message}")
431
+ } finally {
432
+ try { ndef.close() } catch (_: Exception) {}
433
+ }
434
+ }
435
+
436
+ return tagInfo
437
+ }
438
+
439
+ private fun ndefMessageToJS(message: NdefMessage): JSObject {
440
+ val ndefRecords = JSArray()
441
+ for (record in message.records) {
442
+ val rec = JSObject()
443
+ rec.put("type", String(record.type, Charsets.UTF_8))
444
+ rec.put("payload", Base64.getEncoder().encodeToString(record.payload))
445
+ ndefRecords.put(rec)
446
+ }
447
+ val msg = JSObject()
448
+ msg.put("records", ndefRecords)
449
+ return msg
450
+ }
451
+
337
452
  private fun byteArrayToHexString(inarray: ByteArray): String {
338
453
  val hex = arrayOf("0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F")
339
454
  var out = ""
340
455
 
341
- for (j in inarray.size - 1 downTo 0) {
456
+ for (j in inarray.indices) {
342
457
  val `in` = inarray[j].toInt() and 0xff
343
458
  val i1 = (`in` shr 4) and 0x0f
344
459
  out += hex[i1]
@@ -1,5 +1,21 @@
1
1
  import type { PluginListenerHandle } from '@capacitor/core';
2
- export declare type PayloadType = string | number[] | Uint8Array;
2
+ export type PayloadType = string | number[] | Uint8Array;
3
+ export interface StartScanOptions {
4
+ /**
5
+ * Select the native reader strategy.
6
+ * - `auto` (default): attempt advanced tag session first, downgrade automatically on entitlement failures.
7
+ * - `full`: force the advanced tag session (resets any cached fallback state).
8
+ * - `compat`: force the compatibility tag session (ISO14443-only, avoids advanced entitlements).
9
+ * - `ndef`: skip tag session entirely and use the legacy NDEF reader.
10
+ */
11
+ mode?: 'auto' | 'full' | 'compat' | 'ndef';
12
+ /**
13
+ * Backwards-compatible hints for older app code. When true, they map to `mode` selections above.
14
+ */
15
+ forceFull?: boolean;
16
+ forceCompat?: boolean;
17
+ forceNDEF?: boolean;
18
+ }
3
19
  export interface NFCPluginBasic {
4
20
  /**
5
21
  * Checks if NFC is supported on the device. Returns true on all iOS devices, and checks for support on Android.
@@ -7,7 +23,15 @@ export interface NFCPluginBasic {
7
23
  isSupported(): Promise<{
8
24
  supported: boolean;
9
25
  }>;
10
- startScan(): Promise<void>;
26
+ /**
27
+ * Begins listening for NFC tags.
28
+ * @param options Optional tuning parameters for native reader behavior.
29
+ */
30
+ startScan(options?: StartScanOptions): Promise<void>;
31
+ /**
32
+ * Cancels an ongoing scan session (iOS only currently; no-op / rejection on Android).
33
+ */
34
+ cancelScan(): Promise<void>;
11
35
  /**
12
36
  * Writes an NDEF message to an NFC tag.
13
37
  * @param options The NDEF message to write.
@@ -43,10 +67,45 @@ export interface NFCPluginBasic {
43
67
  }
44
68
  export interface NDEFMessages<T extends PayloadType = string> {
45
69
  messages: NDEFMessage<T>[];
70
+ tagInfo?: TagInfo;
46
71
  }
47
72
  export interface NDEFMessage<T extends PayloadType = string> {
48
73
  records: NDEFRecord<T>[];
49
74
  }
75
+ export interface TagInfo {
76
+ /**
77
+ * The unique identifier of the tag (UID) as a hex string
78
+ */
79
+ uid?: string;
80
+ /**
81
+ * The NFC tag technology types supported
82
+ */
83
+ techTypes?: string[];
84
+ /**
85
+ * The maximum size of NDEF message that can be written to this tag (if applicable)
86
+ */
87
+ maxSize?: number;
88
+ /**
89
+ * Whether the tag is writable
90
+ */
91
+ isWritable?: boolean;
92
+ /**
93
+ * The tag type (e.g., "ISO14443-4", "MifareClassic", etc.)
94
+ */
95
+ type?: string;
96
+ /**
97
+ * Truthy when the plugin downgraded reader capabilities for compatibility.
98
+ */
99
+ fallback?: boolean;
100
+ /**
101
+ * Indicates the active fallback mode (`compat` or `ndef`).
102
+ */
103
+ fallbackMode?: 'compat' | 'ndef';
104
+ /**
105
+ * Optional reason string when fallback was applied (e.g., `missing-entitlement`).
106
+ */
107
+ reason?: string;
108
+ }
50
109
  export interface NDEFRecord<T extends PayloadType = string> {
51
110
  /**
52
111
  * The type of the record.
@@ -65,18 +124,32 @@ export interface NFCError {
65
124
  }
66
125
  export interface NDEFWriteOptions<T extends PayloadType = Uint8Array> {
67
126
  records: NDEFRecord<T>[];
127
+ /**
128
+ * When true, bypasses automatic Well Known Type formatting (Text 'T' and URI 'U' prefixes).
129
+ * All payloads are written as raw bytes without additional framing.
130
+ */
131
+ rawMode?: boolean;
68
132
  }
69
- export declare type NDEFMessagesTransformable = {
133
+ export type NDEFMessagesTransformable = {
70
134
  base64: () => NDEFMessages;
71
135
  uint8Array: () => NDEFMessages<Uint8Array>;
72
136
  string: () => NDEFMessages;
73
137
  numberArray: () => NDEFMessages<number[]>;
74
138
  };
75
- export declare type TagResultListenerFunc = (data: NDEFMessagesTransformable) => void;
76
- export interface NFCPlugin extends Omit<NFCPluginBasic, "writeNDEF" | "addListener"> {
139
+ export type TagResultListenerFunc = (data: NDEFMessagesTransformable) => void;
140
+ export interface NFCPlugin extends Omit<NFCPluginBasic, 'writeNDEF' | 'addListener'> {
77
141
  writeNDEF: <T extends PayloadType = Uint8Array>(record?: NDEFWriteOptions<T>) => Promise<void>;
78
142
  wrapperListeners: TagResultListenerFunc[];
79
- onRead: (listenerFunc: TagResultListenerFunc) => void;
80
- onWrite: (listenerFunc: () => void) => void;
81
- onError: (listenerFunc: (error: NFCError) => void) => void;
143
+ /**
144
+ * Register a read listener. Returns an unsubscribe function to remove just this listener.
145
+ */
146
+ onRead: (listenerFunc: TagResultListenerFunc) => () => void;
147
+ /**
148
+ * Register a write success listener. Returns an unsubscribe function.
149
+ */
150
+ onWrite: (listenerFunc: () => void) => () => void;
151
+ /**
152
+ * Register an error listener. Returns an unsubscribe function.
153
+ */
154
+ onError: (listenerFunc: (error: NFCError) => void) => () => void;
82
155
  }
@@ -1 +1 @@
1
- {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["import type { PluginListenerHandle } from '@capacitor/core';\n\n// Payload from a new NFC scan is a base64 encoded string\nexport type PayloadType = string | number[] | Uint8Array\n\nexport interface NFCPluginBasic {\n /**\n * Checks if NFC is supported on the device. Returns true on all iOS devices, and checks for support on Android.\n */\n isSupported(): Promise<{ supported: boolean }>;\n\n startScan(): Promise<void>;\n\n /**\n * Writes an NDEF message to an NFC tag.\n * @param options The NDEF message to write.\n */\n writeNDEF<T extends PayloadType = number[]>(options: NDEFWriteOptions<T>): Promise<void>;\n\n /**\n * Cancels writeNDEF on Android (exits \"write mode\").\n */\n cancelWriteAndroid(): Promise<void>;\n\n /**\n * Adds a listener for NFC tag detection events.\n * @param eventName The name of the event ('nfcTag').\n * @param listenerFunc The function to call when an NFC tag is detected.\n */\n addListener(\n eventName: 'nfcTag',\n listenerFunc: (data: NDEFMessages) => void,\n ): Promise<PluginListenerHandle> & PluginListenerHandle;\n\n /**\n * Adds a listener for NFC tag write events.\n * @param eventName The name of the event ('nfcWriteSuccess').\n * @param listenerFunc The function to call when an NFC tag is written.\n */\n addListener(\n eventName: 'nfcWriteSuccess',\n listenerFunc: ()=> void,\n ): Promise<PluginListenerHandle> & PluginListenerHandle;\n\n /**\n * Adds a listener for NFC error events.\n * @param eventName The name of the event ('nfcError').\n * @param listenerFunc The function to call when an NFC error occurs.\n */\n addListener(\n eventName: 'nfcError',\n listenerFunc: (error: NFCError) => void,\n ): Promise<PluginListenerHandle> & PluginListenerHandle;\n\n /**\n * Removes all listeners for the specified event.\n * @param eventName The name of the event.\n */\n removeAllListeners(eventName: 'nfcTag' | 'nfcError'): Promise<void>;\n}\n\nexport interface NDEFMessages<T extends PayloadType = string> {\n messages: NDEFMessage<T>[];\n}\n\nexport interface NDEFMessage<T extends PayloadType = string> {\n records: NDEFRecord<T>[];\n}\n\nexport interface NDEFRecord<T extends PayloadType = string> {\n /**\n * The type of the record.\n */\n type: string;\n\n /**\n * The payload of the record.\n */\n payload: T;\n}\n\n\nexport interface NFCError {\n /**\n * The error message.\n */\n error: string;\n}\n\nexport interface NDEFWriteOptions<T extends PayloadType = Uint8Array> {\n records: NDEFRecord<T>[];\n}\n\nexport type NDEFMessagesTransformable = {\n base64: ()=> NDEFMessages;\n uint8Array: ()=> NDEFMessages<Uint8Array>;\n string: ()=> NDEFMessages;\n numberArray: ()=> NDEFMessages<number[]>;\n}\n\nexport type TagResultListenerFunc = (data: NDEFMessagesTransformable) => void\n\nexport interface NFCPlugin extends Omit<NFCPluginBasic, \"writeNDEF\" | \"addListener\"> {\n writeNDEF: <T extends PayloadType = Uint8Array>(record?: NDEFWriteOptions<T>) => Promise<void>;\n wrapperListeners: TagResultListenerFunc[],\n onRead: (listenerFunc: TagResultListenerFunc)=> void,\n onWrite: (listenerFunc: ()=> void) => void,\n onError: (listenerFunc: (error: NFCError)=> void)=> void,\n}"]}
1
+ {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["import type { PluginListenerHandle } from '@capacitor/core';\n\n// Payload from a new NFC scan is a base64 encoded string\nexport type PayloadType = string | number[] | Uint8Array;\n\nexport interface StartScanOptions {\n /**\n * Select the native reader strategy.\n * - `auto` (default): attempt advanced tag session first, downgrade automatically on entitlement failures.\n * - `full`: force the advanced tag session (resets any cached fallback state).\n * - `compat`: force the compatibility tag session (ISO14443-only, avoids advanced entitlements).\n * - `ndef`: skip tag session entirely and use the legacy NDEF reader.\n */\n mode?: 'auto' | 'full' | 'compat' | 'ndef';\n /**\n * Backwards-compatible hints for older app code. When true, they map to `mode` selections above.\n */\n forceFull?: boolean;\n forceCompat?: boolean;\n forceNDEF?: boolean;\n}\n\nexport interface NFCPluginBasic {\n /**\n * Checks if NFC is supported on the device. Returns true on all iOS devices, and checks for support on Android.\n */\n isSupported(): Promise<{ supported: boolean }>;\n\n /**\n * Begins listening for NFC tags.\n * @param options Optional tuning parameters for native reader behavior.\n */\n startScan(options?: StartScanOptions): Promise<void>;\n\n /**\n * Cancels an ongoing scan session (iOS only currently; no-op / rejection on Android).\n */\n cancelScan(): Promise<void>;\n\n /**\n * Writes an NDEF message to an NFC tag.\n * @param options The NDEF message to write.\n */\n writeNDEF<T extends PayloadType = number[]>(options: NDEFWriteOptions<T>): Promise<void>;\n\n /**\n * Cancels writeNDEF on Android (exits \"write mode\").\n */\n cancelWriteAndroid(): Promise<void>;\n\n /**\n * Adds a listener for NFC tag detection events.\n * @param eventName The name of the event ('nfcTag').\n * @param listenerFunc The function to call when an NFC tag is detected.\n */\n addListener(\n eventName: 'nfcTag',\n listenerFunc: (data: NDEFMessages) => void,\n ): Promise<PluginListenerHandle> & PluginListenerHandle;\n\n /**\n * Adds a listener for NFC tag write events.\n * @param eventName The name of the event ('nfcWriteSuccess').\n * @param listenerFunc The function to call when an NFC tag is written.\n */\n addListener(\n eventName: 'nfcWriteSuccess',\n listenerFunc: () => void,\n ): Promise<PluginListenerHandle> & PluginListenerHandle;\n\n /**\n * Adds a listener for NFC error events.\n * @param eventName The name of the event ('nfcError').\n * @param listenerFunc The function to call when an NFC error occurs.\n */\n addListener(\n eventName: 'nfcError',\n listenerFunc: (error: NFCError) => void,\n ): Promise<PluginListenerHandle> & PluginListenerHandle;\n\n /**\n * Removes all listeners for the specified event.\n * @param eventName The name of the event.\n */\n removeAllListeners(eventName: 'nfcTag' | 'nfcError'): Promise<void>;\n}\n\nexport interface NDEFMessages<T extends PayloadType = string> {\n messages: NDEFMessage<T>[];\n tagInfo?: TagInfo;\n}\n\nexport interface NDEFMessage<T extends PayloadType = string> {\n records: NDEFRecord<T>[];\n}\n\nexport interface TagInfo {\n /**\n * The unique identifier of the tag (UID) as a hex string\n */\n uid?: string;\n\n /**\n * The NFC tag technology types supported\n */\n techTypes?: string[];\n\n /**\n * The maximum size of NDEF message that can be written to this tag (if applicable)\n */\n maxSize?: number;\n\n /**\n * Whether the tag is writable\n */\n isWritable?: boolean;\n\n /**\n * The tag type (e.g., \"ISO14443-4\", \"MifareClassic\", etc.)\n */\n type?: string;\n\n /**\n * Truthy when the plugin downgraded reader capabilities for compatibility.\n */\n fallback?: boolean;\n\n /**\n * Indicates the active fallback mode (`compat` or `ndef`).\n */\n fallbackMode?: 'compat' | 'ndef';\n\n /**\n * Optional reason string when fallback was applied (e.g., `missing-entitlement`).\n */\n reason?: string;\n}\n\nexport interface NDEFRecord<T extends PayloadType = string> {\n /**\n * The type of the record.\n */\n type: string;\n\n /**\n * The payload of the record.\n */\n payload: T;\n}\n\nexport interface NFCError {\n /**\n * The error message.\n */\n error: string;\n}\n\nexport interface NDEFWriteOptions<T extends PayloadType = Uint8Array> {\n records: NDEFRecord<T>[];\n /**\n * When true, bypasses automatic Well Known Type formatting (Text 'T' and URI 'U' prefixes).\n * All payloads are written as raw bytes without additional framing.\n */\n rawMode?: boolean;\n}\n\nexport type NDEFMessagesTransformable = {\n base64: () => NDEFMessages;\n uint8Array: () => NDEFMessages<Uint8Array>;\n string: () => NDEFMessages;\n numberArray: () => NDEFMessages<number[]>;\n};\n\nexport type TagResultListenerFunc = (data: NDEFMessagesTransformable) => void;\n\nexport interface NFCPlugin extends Omit<NFCPluginBasic, 'writeNDEF' | 'addListener'> {\n writeNDEF: <T extends PayloadType = Uint8Array>(record?: NDEFWriteOptions<T>) => Promise<void>;\n wrapperListeners: TagResultListenerFunc[];\n /**\n * Register a read listener. Returns an unsubscribe function to remove just this listener.\n */\n onRead: (listenerFunc: TagResultListenerFunc) => () => void;\n /**\n * Register a write success listener. Returns an unsubscribe function.\n */\n onWrite: (listenerFunc: () => void) => () => void;\n /**\n * Register an error listener. Returns an unsubscribe function.\n */\n onError: (listenerFunc: (error: NFCError) => void) => () => void;\n}\n"]}
@@ -1,3 +1,3 @@
1
- import type { NFCPlugin } from './definitions';
2
- export * from './definitions';
1
+ import type { NFCPlugin } from './definitions.js';
2
+ export * from './definitions.js';
3
3
  export declare const NFC: NFCPlugin;