@exxili/capacitor-nfc 0.0.2 → 0.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.
@@ -0,0 +1,315 @@
1
+ package com.exxili.capacitornfc
2
+
3
+ import android.app.PendingIntent
4
+ import android.content.Intent
5
+ import android.content.IntentFilter
6
+ import android.nfc.NdefMessage
7
+ import android.nfc.NdefRecord
8
+ import android.nfc.NfcAdapter
9
+ import android.nfc.NfcAdapter.ACTION_NDEF_DISCOVERED
10
+ import android.nfc.NfcAdapter.ACTION_TAG_DISCOVERED
11
+ import android.nfc.NfcAdapter.ACTION_TECH_DISCOVERED
12
+ import android.nfc.NfcAdapter.EXTRA_NDEF_MESSAGES
13
+ import android.nfc.NfcAdapter.getDefaultAdapter
14
+ import android.nfc.Tag
15
+ import android.nfc.tech.IsoDep
16
+ import android.nfc.tech.MifareClassic
17
+ import android.nfc.tech.MifareUltralight
18
+ import android.nfc.tech.Ndef
19
+ import android.nfc.tech.NdefFormatable
20
+ import android.nfc.tech.NfcA
21
+ import android.nfc.tech.NfcB
22
+ import android.nfc.tech.NfcBarcode
23
+ import android.nfc.tech.NfcF
24
+ import android.nfc.tech.NfcV
25
+ import android.util.Log
26
+ import com.getcapacitor.JSArray
27
+ import com.getcapacitor.JSObject
28
+ import com.getcapacitor.Plugin
29
+ import com.getcapacitor.PluginCall
30
+ import com.getcapacitor.PluginMethod
31
+ import com.getcapacitor.annotation.CapacitorPlugin
32
+ import org.json.JSONObject
33
+ import java.io.IOException
34
+ import java.io.UnsupportedEncodingException
35
+ import java.nio.charset.Charset
36
+ import java.util.Base64
37
+
38
+ @CapacitorPlugin(name = "NFC")
39
+ class NFCPlugin : Plugin() {
40
+ private var writeMode = false
41
+ private var recordsBuffer: JSArray? = null
42
+
43
+ private val techListsArray = arrayOf(arrayOf<String>(
44
+ IsoDep::class.java.name,
45
+ MifareClassic::class.java.name,
46
+ MifareUltralight::class.java.name,
47
+ Ndef::class.java.name,
48
+ NdefFormatable::class.java.name,
49
+ NfcBarcode::class.java.name,
50
+ NfcA::class.java.name,
51
+ NfcB::class.java.name,
52
+ NfcF::class.java.name,
53
+ NfcV::class.java.name
54
+ ))
55
+
56
+ public override fun handleOnNewIntent(intent: Intent?) {
57
+ super.handleOnNewIntent(intent)
58
+
59
+ if (intent == null || intent.action.isNullOrBlank()) {
60
+ return
61
+ }
62
+
63
+ if (writeMode) {
64
+ Log.d("NFC", "WRITE MODE START")
65
+ handleWriteTag(intent)
66
+ writeMode = false
67
+ recordsBuffer = null
68
+ }
69
+ else if (ACTION_NDEF_DISCOVERED == intent.action) {
70
+ Log.d("NFC", "READ MODE START")
71
+ handleReadTag(intent)
72
+ }
73
+ }
74
+
75
+ @PluginMethod
76
+ fun isSupported(call: PluginCall) {
77
+ val adapter = NfcAdapter.getDefaultAdapter(this.activity)
78
+ val ret = JSObject()
79
+ ret.put("supported", adapter != null)
80
+ call.resolve(ret)
81
+ }
82
+
83
+ @PluginMethod
84
+ fun cancelWriteAndroid(call: PluginCall) {
85
+ this.writeMode = false
86
+ call.resolve()
87
+ }
88
+
89
+ @PluginMethod
90
+ fun startScan(call: PluginCall) {
91
+ print("startScan called")
92
+ call.reject("Android NFC scanning does not require 'startScan' method.")
93
+ }
94
+
95
+ @PluginMethod
96
+ fun writeNDEF(call: PluginCall) {
97
+ print("writeNDEF called")
98
+
99
+ writeMode = true
100
+ recordsBuffer = call.getArray("records")
101
+
102
+ call.resolve()
103
+ }
104
+
105
+ override fun handleOnPause() {
106
+ super.handleOnPause()
107
+ getDefaultAdapter(this.activity)?.disableForegroundDispatch(this.activity)
108
+ }
109
+
110
+ override fun handleOnResume() {
111
+ super.handleOnResume()
112
+ if(getDefaultAdapter(this.activity) == null) return;
113
+
114
+ val intent = Intent(context, this.activity.javaClass).apply {
115
+ addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
116
+ }
117
+
118
+ val pendingIntent =
119
+ PendingIntent.getActivity(this.activity, 0, intent, PendingIntent.FLAG_MUTABLE)
120
+
121
+ val intentFilter: Array<IntentFilter> =
122
+ arrayOf(
123
+ IntentFilter(ACTION_NDEF_DISCOVERED).apply {
124
+ try {
125
+ addDataType("text/plain")
126
+ } catch (e: IntentFilter.MalformedMimeTypeException) {
127
+ throw RuntimeException("failed", e)
128
+ }
129
+ },
130
+ IntentFilter(ACTION_TECH_DISCOVERED),
131
+ IntentFilter(ACTION_TAG_DISCOVERED)
132
+ )
133
+
134
+ getDefaultAdapter(this.activity).enableForegroundDispatch(
135
+ this.activity,
136
+ pendingIntent,
137
+ intentFilter,
138
+ techListsArray
139
+ )
140
+ }
141
+
142
+ private fun handleWriteTag(intent: Intent) {
143
+ val records = recordsBuffer?.toList<JSONObject>()
144
+ if(records != null) {
145
+ val ndefRecords = mutableListOf<NdefRecord>()
146
+
147
+ try {
148
+ for (record in records) {
149
+ val payload = record.getJSONArray("payload")
150
+ val type: String? = record.getString("type")
151
+
152
+ if (payload.length() == 0 || type == null) {
153
+ notifyListeners(
154
+ "nfcError",
155
+ JSObject().put(
156
+ "error",
157
+ "Invalid record: payload or type is missing."
158
+ )
159
+ )
160
+ return
161
+ }
162
+
163
+ val typeBytes = type.toByteArray(Charsets.UTF_8)
164
+ val payloadBytes = ByteArray(payload.length())
165
+ for(i in 0 until payload.length()) {
166
+ payloadBytes[i] = payload.getInt(i).toByte()
167
+ }
168
+
169
+ ndefRecords.add(
170
+ NdefRecord(
171
+ NdefRecord.TNF_WELL_KNOWN,
172
+ typeBytes,
173
+ ByteArray(0),
174
+ payloadBytes
175
+ )
176
+ )
177
+ }
178
+
179
+ val ndefMessage = NdefMessage(ndefRecords.toTypedArray())
180
+ val tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG, Tag::class.java)
181
+ var ndef = Ndef.get(tag)
182
+
183
+ if (ndef == null) {
184
+ val formatable = NdefFormatable.get(tag)
185
+ if (formatable != null) {
186
+ try {
187
+ formatable.connect()
188
+ val mimeRecord = NdefRecord.createMime("text/plain", "INIT".toByteArray(
189
+ Charset.forName("US-ASCII")))
190
+ val msg = NdefMessage(mimeRecord)
191
+ formatable.format(msg)
192
+ // Success!
193
+ // Emit event to Capacitor plugin for success
194
+ println("Successfully formatted and wrote NDEF message to tag!")
195
+ } catch (e: IOException) {
196
+ // Error connecting or formatting
197
+ // Emit event to Capacitor plugin for error
198
+ println("Error formatting or writing to NDEF-formatable tag: ${e.message}")
199
+ } catch (e: Exception) { // Catch other potential exceptions during format, like TagLostException
200
+ println("Error during NDEF formatting: ${e.message}")
201
+ } finally {
202
+ try {
203
+ formatable.close()
204
+ } catch (e: IOException) {
205
+ println("Error closing NdefFormatable connection: ${e.message}")
206
+ }
207
+ }
208
+
209
+ ndef = Ndef.get(formatable.tag)
210
+ } else {
211
+ notifyListeners(
212
+ "nfcError",
213
+ JSObject().put(
214
+ "error",
215
+ "Tag does not support NDEF writing."
216
+ )
217
+ )
218
+ return
219
+ }
220
+ }
221
+
222
+ ndef.use { // Use block ensures ndef.close() is called
223
+ ndef.connect()
224
+ if (!ndef.isWritable) {
225
+ notifyListeners(
226
+ "nfcError",
227
+ JSObject().put(
228
+ "error",
229
+ "NFC tag is not writable"
230
+ )
231
+ )
232
+ return
233
+ }
234
+ if (ndef.maxSize < ndefMessage.toByteArray().size) {
235
+ notifyListeners(
236
+ "nfcError",
237
+ JSObject().put(
238
+ "error",
239
+ "Message too large for this NFC Tag (max ${ndef.maxSize} bytes)."
240
+ )
241
+ )
242
+ return
243
+ }
244
+
245
+ ndef.writeNdefMessage(ndefMessage)
246
+ Log.d("NFC", "NDEF message successfully written to tag.")
247
+ }
248
+
249
+ notifyListeners("nfcWriteSuccess", JSObject().put("success", true))
250
+ }
251
+ catch (e: UnsupportedEncodingException) {
252
+ Log.e("NFC", "Encoding error during NDEF record creation: ${e.message}")
253
+ notifyListeners(
254
+ "nfcError",
255
+ JSObject().put(
256
+ "error",
257
+ "Encoding error: ${e.message}"
258
+ )
259
+ )
260
+ }
261
+ catch (e: IOException) {
262
+ Log.e("NFC", "I/O error during NFC write: ${e.message}")
263
+ notifyListeners(
264
+ "nfcError",
265
+ JSObject().put(
266
+ "error",
267
+ "NFC I/O error: ${e.message}"
268
+ )
269
+ )
270
+ }
271
+ catch (e: Exception) {
272
+ Log.e("NFC", "Error writing NDEF message: ${e.message}", e)
273
+ notifyListeners(
274
+ "nfcError",
275
+ JSObject().put(
276
+ "error",
277
+ "Failed to write NDEF message: ${e.message}"
278
+ )
279
+ )
280
+ }
281
+ }
282
+ else {
283
+ notifyListeners("nfcError", JSObject().put("error", "Failed to write NFC tag"))
284
+ }
285
+ }
286
+
287
+ private fun handleReadTag(intent: Intent) {
288
+ val jsResponse = JSObject()
289
+
290
+ val ndefMessages = JSArray()
291
+ val receivedMessages = intent.getParcelableArrayExtra(
292
+ EXTRA_NDEF_MESSAGES,
293
+ NdefMessage::class.java
294
+ )
295
+
296
+ receivedMessages?.also { rawMessages ->
297
+ for (message in rawMessages) {
298
+ val ndefRecords = JSArray()
299
+ for (record in message.records) {
300
+ val rec = JSObject()
301
+ rec.put("type", String(record.type, Charsets.UTF_8))
302
+ rec.put("payload", Base64.getEncoder().encodeToString(record.payload))
303
+ ndefRecords.put(rec)
304
+ }
305
+
306
+ val msg = JSObject()
307
+ msg.put("records", ndefRecords)
308
+ ndefMessages.put(msg)
309
+ }
310
+ }
311
+
312
+ jsResponse.put("messages", ndefMessages)
313
+ this.notifyListeners("nfcTag", jsResponse)
314
+ }
315
+ }
@@ -1,20 +1,34 @@
1
- import { PluginListenerHandle } from '@capacitor/core';
2
- export interface NFCPlugin {
1
+ import type { PluginListenerHandle } from '@capacitor/core';
2
+ export declare type PayloadType = string | number[] | Uint8Array;
3
+ export interface NFCPluginBasic {
3
4
  /**
4
- * Starts the NFC scanning session.
5
+ * Checks if NFC is supported on the device. Returns true on all iOS devices, and checks for support on Android.
5
6
  */
7
+ isSupported(): Promise<{
8
+ supported: boolean;
9
+ }>;
6
10
  startScan(): Promise<void>;
7
11
  /**
8
12
  * Writes an NDEF message to an NFC tag.
9
13
  * @param options The NDEF message to write.
10
14
  */
11
- writeNDEF(options: NDEFWriteOptions): Promise<void>;
15
+ writeNDEF<T extends PayloadType = number[]>(options: NDEFWriteOptions<T>): Promise<void>;
16
+ /**
17
+ * Cancels writeNDEF on Android (exits "write mode").
18
+ */
19
+ cancelWriteAndroid(): Promise<void>;
12
20
  /**
13
21
  * Adds a listener for NFC tag detection events.
14
22
  * @param eventName The name of the event ('nfcTag').
15
23
  * @param listenerFunc The function to call when an NFC tag is detected.
16
24
  */
17
25
  addListener(eventName: 'nfcTag', listenerFunc: (data: NDEFMessages) => void): Promise<PluginListenerHandle> & PluginListenerHandle;
26
+ /**
27
+ * Adds a listener for NFC tag write events.
28
+ * @param eventName The name of the event ('nfcWriteSuccess').
29
+ * @param listenerFunc The function to call when an NFC tag is written.
30
+ */
31
+ addListener(eventName: 'nfcWriteSuccess', listenerFunc: () => void): Promise<PluginListenerHandle> & PluginListenerHandle;
18
32
  /**
19
33
  * Adds a listener for NFC error events.
20
34
  * @param eventName The name of the event ('nfcError').
@@ -27,13 +41,13 @@ export interface NFCPlugin {
27
41
  */
28
42
  removeAllListeners(eventName: 'nfcTag' | 'nfcError'): Promise<void>;
29
43
  }
30
- export interface NDEFMessages {
31
- messages: NDEFMessage[];
44
+ export interface NDEFMessages<T extends PayloadType = string> {
45
+ messages: NDEFMessage<T>[];
32
46
  }
33
- export interface NDEFMessage {
34
- records: NDEFRecord[];
47
+ export interface NDEFMessage<T extends PayloadType = string> {
48
+ records: NDEFRecord<T>[];
35
49
  }
36
- export interface NDEFRecord {
50
+ export interface NDEFRecord<T extends PayloadType = string> {
37
51
  /**
38
52
  * The type of the record.
39
53
  */
@@ -41,7 +55,7 @@ export interface NDEFRecord {
41
55
  /**
42
56
  * The payload of the record.
43
57
  */
44
- payload: string;
58
+ payload: T;
45
59
  }
46
60
  export interface NFCError {
47
61
  /**
@@ -49,6 +63,20 @@ export interface NFCError {
49
63
  */
50
64
  error: string;
51
65
  }
52
- export interface NDEFWriteOptions {
53
- records: NDEFRecord[];
66
+ export interface NDEFWriteOptions<T extends PayloadType = Uint8Array> {
67
+ records: NDEFRecord<T>[];
68
+ }
69
+ export declare type NDEFMessagesTransformable = {
70
+ base64: () => NDEFMessages;
71
+ uint8Array: () => NDEFMessages<Uint8Array>;
72
+ string: () => NDEFMessages;
73
+ numberArray: () => NDEFMessages<number[]>;
74
+ };
75
+ export declare type TagResultListenerFunc = (data: NDEFMessagesTransformable) => void;
76
+ export interface NFCPlugin extends Omit<NFCPluginBasic, "writeNDEF" | "addListener"> {
77
+ writeNDEF: <T extends PayloadType = Uint8Array>(record?: NDEFWriteOptions<T>) => Promise<void>;
78
+ wrapperListeners: TagResultListenerFunc[];
79
+ onRead: (listenerFunc: TagResultListenerFunc) => void;
80
+ onWrite: (listenerFunc: () => void) => void;
81
+ onError: (listenerFunc: (error: NFCError) => void) => void;
54
82
  }
@@ -1 +1 @@
1
- {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["import { PluginListenerHandle } from '@capacitor/core';\n\nexport interface NFCPlugin {\n /**\n * Starts the NFC scanning session.\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(options: NDEFWriteOptions): 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 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 {\n messages: NDEFMessage[];\n}\n\nexport interface NDEFMessage {\n records: NDEFRecord[];\n}\n\nexport interface NDEFRecord {\n /**\n * The type of the record.\n */\n type: string;\n\n /**\n * The payload of the record.\n */\n payload: string;\n}\n\nexport interface NFCError {\n /**\n * The error message.\n */\n error: string;\n}\n\nexport interface NDEFWriteOptions {\n records: NDEFRecord[];\n}\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 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,4 +1,3 @@
1
1
  import type { NFCPlugin } from './definitions';
2
- declare const NFC: NFCPlugin;
3
2
  export * from './definitions';
4
- export { NFC };
3
+ export declare const NFC: NFCPlugin;
package/dist/esm/index.js CHANGED
@@ -1,5 +1,84 @@
1
1
  import { registerPlugin } from '@capacitor/core';
2
- const NFC = registerPlugin('NFC');
2
+ const NFCPlug = registerPlugin('NFC', {
3
+ web: () => import('./web').then(m => new m.NFCWeb()),
4
+ });
3
5
  export * from './definitions';
4
- export { NFC };
6
+ export const NFC = {
7
+ isSupported: NFCPlug.isSupported.bind(NFCPlug),
8
+ startScan: NFCPlug.startScan.bind(NFCPlug),
9
+ cancelWriteAndroid: NFCPlug.cancelWriteAndroid.bind(NFCPlug),
10
+ onRead: (func) => NFC.wrapperListeners.push(func),
11
+ onWrite: (func) => NFCPlug.addListener(`nfcWriteSuccess`, func),
12
+ onError: (errorFn) => {
13
+ NFCPlug.addListener(`nfcError`, errorFn);
14
+ },
15
+ removeAllListeners: (eventName) => {
16
+ NFC.wrapperListeners = [];
17
+ return NFCPlug.removeAllListeners(eventName);
18
+ },
19
+ wrapperListeners: [],
20
+ async writeNDEF(options) {
21
+ var _a;
22
+ const ndefMessage = {
23
+ records: (_a = options === null || options === void 0 ? void 0 : options.records.map((record) => {
24
+ const payload = typeof record.payload === 'string'
25
+ ? Array.from(new TextEncoder().encode(record.payload))
26
+ : Array.isArray(record.payload)
27
+ ? record.payload
28
+ : record.payload instanceof Uint8Array
29
+ ? Array.from(record.payload)
30
+ : null;
31
+ if (!payload)
32
+ throw 'Unsupported payload type';
33
+ return {
34
+ type: record.type,
35
+ payload,
36
+ };
37
+ })) !== null && _a !== void 0 ? _a : [],
38
+ };
39
+ await NFCPlug.writeNDEF(ndefMessage);
40
+ },
41
+ };
42
+ const decodeBase64 = (base64Payload) => {
43
+ return atob(base64Payload)
44
+ .split('')
45
+ .map((char) => char.charCodeAt(0));
46
+ };
47
+ const mapPayloadTo = (type, data) => {
48
+ return {
49
+ messages: data.messages.map(message => ({
50
+ records: message.records.map(record => ({
51
+ type: record.type,
52
+ payload: type === "b64"
53
+ ? record.payload
54
+ : type === "string"
55
+ ? decodeBase64(record.payload)
56
+ : type === "uint8Array"
57
+ ? new Uint8Array(decodeBase64(record.payload))
58
+ : type === "numberArray"
59
+ ? Array.from(decodeBase64(record.payload))
60
+ : record.payload
61
+ }))
62
+ }))
63
+ };
64
+ };
65
+ NFCPlug.addListener(`nfcTag`, data => {
66
+ const wrappedData = {
67
+ base64() {
68
+ return mapPayloadTo("b64", data);
69
+ },
70
+ string() {
71
+ return mapPayloadTo("string", data);
72
+ },
73
+ uint8Array() {
74
+ return mapPayloadTo("uint8Array", data);
75
+ },
76
+ numberArray() {
77
+ return mapPayloadTo("numberArray", data);
78
+ }
79
+ };
80
+ for (const listener of NFC.wrapperListeners) {
81
+ listener(wrappedData);
82
+ }
83
+ });
5
84
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAGjD,MAAM,GAAG,GAAG,cAAc,CAAY,KAAK,CAAC,CAAC;AAE7C,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,GAAG,EAAE,CAAC","sourcesContent":["import { registerPlugin } from '@capacitor/core';\nimport type { NFCPlugin } from './definitions';\n\nconst NFC = registerPlugin<NFCPlugin>('NFC');\n\nexport * from './definitions';\nexport { NFC };\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { registerPlugin } from '@capacitor/core';\n\nimport type {\n NDEFMessagesTransformable,\n NDEFWriteOptions,\n NFCPlugin,\n NFCPluginBasic,\n PayloadType,\n TagResultListenerFunc,\n NFCError,\n NDEFMessages\n} from './definitions';\n\nconst NFCPlug = registerPlugin<NFCPluginBasic>('NFC', {\n web: () => import('./web').then(m => new m.NFCWeb()),\n});\nexport * from './definitions';\nexport const NFC: NFCPlugin = {\n isSupported: NFCPlug.isSupported.bind(NFCPlug),\n startScan: NFCPlug.startScan.bind(NFCPlug),\n cancelWriteAndroid: NFCPlug.cancelWriteAndroid.bind(NFCPlug),\n onRead: (func: TagResultListenerFunc) => NFC.wrapperListeners.push(func),\n onWrite: (func: ()=> void) => NFCPlug.addListener(`nfcWriteSuccess`, func),\n onError: (errorFn: (error: NFCError) => void) => {\n NFCPlug.addListener(`nfcError`, errorFn);\n },\n removeAllListeners: (eventName: 'nfcTag' | 'nfcError') => {\n NFC.wrapperListeners = [];\n return NFCPlug.removeAllListeners(eventName);\n },\n wrapperListeners: [],\n\n async writeNDEF<T extends PayloadType = Uint8Array>(options?: NDEFWriteOptions<T>): Promise<void> {\n const ndefMessage: NDEFWriteOptions<number[]> = {\n records:\n options?.records.map((record) => {\n const payload: number[] | null =\n typeof record.payload === 'string'\n ? Array.from(new TextEncoder().encode(record.payload))\n : Array.isArray(record.payload)\n ? record.payload\n : record.payload instanceof Uint8Array\n ? Array.from(record.payload)\n : null;\n\n if (!payload) throw 'Unsupported payload type';\n\n return {\n type: record.type,\n payload,\n };\n }) ?? [],\n };\n\n await NFCPlug.writeNDEF(ndefMessage);\n },\n};\n\ntype DecodeSpecifier = \"b64\" | \"string\" | \"uint8Array\" | \"numberArray\";\ntype decodedType<T extends DecodeSpecifier> = NDEFMessages<T extends \"b64\" ? string : T extends \"string\" ? string : T extends \"uint8Array\" ? Uint8Array : number[]>\nconst decodeBase64 = (base64Payload: string)=> {\n return atob(base64Payload)\n .split('')\n .map((char) => char.charCodeAt(0));\n}\nconst mapPayloadTo = <T extends DecodeSpecifier>(type: T, data: NDEFMessages): decodedType<T> => {\n return {\n messages: data.messages.map(message => ({\n records: message.records.map(record => ({\n type: record.type,\n payload:\n type === \"b64\"\n ? record.payload\n :type === \"string\"\n ? decodeBase64(record.payload)\n : type === \"uint8Array\"\n ? new Uint8Array(decodeBase64(record.payload))\n : type === \"numberArray\"\n ? Array.from(decodeBase64(record.payload))\n : record.payload\n }))\n }))\n } as decodedType<T>\n}\n\nNFCPlug.addListener(`nfcTag`, data=> {\n const wrappedData: NDEFMessagesTransformable = {\n base64() {\n return mapPayloadTo(\"b64\", data)\n },\n string() {\n return mapPayloadTo(\"string\", data)\n },\n uint8Array() {\n return mapPayloadTo(\"uint8Array\", data)\n },\n numberArray() {\n return mapPayloadTo(\"numberArray\", data)\n }\n }\n\n for(const listener of NFC.wrapperListeners) {\n listener(wrappedData);\n }\n})"]}
@@ -0,0 +1,14 @@
1
+ import { WebPlugin } from '@capacitor/core';
2
+ import type { NFCPlugin, TagResultListenerFunc } from './definitions';
3
+ export declare class NFCWeb extends WebPlugin implements NFCPlugin {
4
+ wrapperListeners: never[];
5
+ isSupported(): Promise<{
6
+ supported: boolean;
7
+ }>;
8
+ startScan(): Promise<void>;
9
+ cancelWriteAndroid(): Promise<void>;
10
+ writeNDEF(): Promise<void>;
11
+ onRead(_func: TagResultListenerFunc): Promise<void>;
12
+ onWrite(): Promise<void>;
13
+ onError(_errorFn: (error: any) => void): Promise<void>;
14
+ }
@@ -0,0 +1,31 @@
1
+ import { WebPlugin } from '@capacitor/core';
2
+ export class NFCWeb extends WebPlugin {
3
+ constructor() {
4
+ super(...arguments);
5
+ this.wrapperListeners = [];
6
+ }
7
+ isSupported() {
8
+ return Promise.resolve({ supported: false });
9
+ }
10
+ startScan() {
11
+ return Promise.reject(new Error('NFC is not supported on web'));
12
+ }
13
+ cancelWriteAndroid() {
14
+ return Promise.reject(new Error('NFC is not supported on web'));
15
+ }
16
+ writeNDEF() {
17
+ return Promise.reject(new Error('NFC is not supported on web'));
18
+ }
19
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
20
+ onRead(_func) {
21
+ return Promise.reject(new Error('NFC is not supported on web'));
22
+ }
23
+ onWrite() {
24
+ return Promise.reject(new Error('NFC is not supported on web'));
25
+ }
26
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
27
+ onError(_errorFn) {
28
+ return Promise.reject(new Error('NFC is not supported on web'));
29
+ }
30
+ }
31
+ //# sourceMappingURL=web.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAI5C,MAAM,OAAO,MAAO,SAAQ,SAAS;IAArC;;QACE,qBAAgB,GAAG,EAAE,CAAC;IA+BxB,CAAC;IA7BC,WAAW;QACT,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;IAC/C,CAAC;IAED,SAAS;QACP,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC,CAAC;IAClE,CAAC;IAED,kBAAkB;QAChB,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC,CAAC;IAClE,CAAC;IAED,SAAS;QACP,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC,CAAC;IAClE,CAAC;IAED,6DAA6D;IAC7D,MAAM,CAAC,KAA4B;QACjC,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC,CAAC;IAClE,CAAC;IAED,OAAO;QACL,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC,CAAC;IAClE,CAAC;IAED,6DAA6D;IAC7D,OAAO,CAAC,QAA8B;QACpC,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC,CAAC;IAClE,CAAC;CACF","sourcesContent":["import { WebPlugin } from '@capacitor/core';\n\nimport type { NFCPlugin, TagResultListenerFunc } from './definitions';\n\nexport class NFCWeb extends WebPlugin implements NFCPlugin {\n wrapperListeners = [];\n \n isSupported(): Promise<{ supported: boolean }> {\n return Promise.resolve({ supported: false });\n }\n\n startScan(): Promise<void> {\n return Promise.reject(new Error('NFC is not supported on web'));\n }\n\n cancelWriteAndroid(): Promise<void> {\n return Promise.reject(new Error('NFC is not supported on web'));\n }\n\n writeNDEF(): Promise<void> {\n return Promise.reject(new Error('NFC is not supported on web'));\n }\n \n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n onRead(_func: TagResultListenerFunc): Promise<void> {\n return Promise.reject(new Error('NFC is not supported on web'));\n }\n\n onWrite(): Promise<void> {\n return Promise.reject(new Error('NFC is not supported on web'));\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n onError(_errorFn: (error: any) => void): Promise<void> {\n return Promise.reject(new Error('NFC is not supported on web'));\n }\n}"]}