@exxili/capacitor-nfc 0.0.11 → 0.0.12
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/README.md +190 -102
- package/android/src/main/kotlin/com/exxili/capacitornfc/NFCPlugin.kt +124 -38
- package/dist/esm/definitions.d.ts +43 -7
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/index.js +205 -42
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/web.d.ts +2 -6
- package/dist/esm/web.js +10 -22
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +215 -64
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +215 -64
- package/dist/plugin.js.map +1 -1
- package/ios/Sources/NFCPlugin/NFCPlugin.swift +40 -13
- package/ios/Sources/NFCPlugin/NFCReader.swift +183 -42
- package/ios/Sources/NFCPlugin/NFCWriter.swift +7 -14
- package/package.json +4 -3
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { PluginListenerHandle } from '@capacitor/core';
|
|
2
|
-
export
|
|
2
|
+
export type PayloadType = string | number[] | Uint8Array;
|
|
3
3
|
export interface NFCPluginBasic {
|
|
4
4
|
/**
|
|
5
5
|
* Checks if NFC is supported on the device. Returns true on all iOS devices, and checks for support on Android.
|
|
@@ -8,6 +8,10 @@ export interface NFCPluginBasic {
|
|
|
8
8
|
supported: boolean;
|
|
9
9
|
}>;
|
|
10
10
|
startScan(): Promise<void>;
|
|
11
|
+
/**
|
|
12
|
+
* Cancels an ongoing scan session (iOS only currently; no-op / rejection on Android).
|
|
13
|
+
*/
|
|
14
|
+
cancelScan(): Promise<void>;
|
|
11
15
|
/**
|
|
12
16
|
* Writes an NDEF message to an NFC tag.
|
|
13
17
|
* @param options The NDEF message to write.
|
|
@@ -43,10 +47,33 @@ export interface NFCPluginBasic {
|
|
|
43
47
|
}
|
|
44
48
|
export interface NDEFMessages<T extends PayloadType = string> {
|
|
45
49
|
messages: NDEFMessage<T>[];
|
|
50
|
+
tagInfo?: TagInfo;
|
|
46
51
|
}
|
|
47
52
|
export interface NDEFMessage<T extends PayloadType = string> {
|
|
48
53
|
records: NDEFRecord<T>[];
|
|
49
54
|
}
|
|
55
|
+
export interface TagInfo {
|
|
56
|
+
/**
|
|
57
|
+
* The unique identifier of the tag (UID) as a hex string
|
|
58
|
+
*/
|
|
59
|
+
uid: string;
|
|
60
|
+
/**
|
|
61
|
+
* The NFC tag technology types supported
|
|
62
|
+
*/
|
|
63
|
+
techTypes: string[];
|
|
64
|
+
/**
|
|
65
|
+
* The maximum size of NDEF message that can be written to this tag (if applicable)
|
|
66
|
+
*/
|
|
67
|
+
maxSize?: number;
|
|
68
|
+
/**
|
|
69
|
+
* Whether the tag is writable
|
|
70
|
+
*/
|
|
71
|
+
isWritable?: boolean;
|
|
72
|
+
/**
|
|
73
|
+
* The tag type (e.g., "ISO14443-4", "MifareClassic", etc.)
|
|
74
|
+
*/
|
|
75
|
+
type?: string;
|
|
76
|
+
}
|
|
50
77
|
export interface NDEFRecord<T extends PayloadType = string> {
|
|
51
78
|
/**
|
|
52
79
|
* The type of the record.
|
|
@@ -66,17 +93,26 @@ export interface NFCError {
|
|
|
66
93
|
export interface NDEFWriteOptions<T extends PayloadType = Uint8Array> {
|
|
67
94
|
records: NDEFRecord<T>[];
|
|
68
95
|
}
|
|
69
|
-
export
|
|
96
|
+
export type NDEFMessagesTransformable = {
|
|
70
97
|
base64: () => NDEFMessages;
|
|
71
98
|
uint8Array: () => NDEFMessages<Uint8Array>;
|
|
72
99
|
string: () => NDEFMessages;
|
|
73
100
|
numberArray: () => NDEFMessages<number[]>;
|
|
74
101
|
};
|
|
75
|
-
export
|
|
76
|
-
export interface NFCPlugin extends Omit<NFCPluginBasic,
|
|
102
|
+
export type TagResultListenerFunc = (data: NDEFMessagesTransformable) => void;
|
|
103
|
+
export interface NFCPlugin extends Omit<NFCPluginBasic, 'writeNDEF' | 'addListener'> {
|
|
77
104
|
writeNDEF: <T extends PayloadType = Uint8Array>(record?: NDEFWriteOptions<T>) => Promise<void>;
|
|
78
105
|
wrapperListeners: TagResultListenerFunc[];
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
106
|
+
/**
|
|
107
|
+
* Register a read listener. Returns an unsubscribe function to remove just this listener.
|
|
108
|
+
*/
|
|
109
|
+
onRead: (listenerFunc: TagResultListenerFunc) => () => void;
|
|
110
|
+
/**
|
|
111
|
+
* Register a write success listener. Returns an unsubscribe function.
|
|
112
|
+
*/
|
|
113
|
+
onWrite: (listenerFunc: () => void) => () => void;
|
|
114
|
+
/**
|
|
115
|
+
* Register an error listener. Returns an unsubscribe function.
|
|
116
|
+
*/
|
|
117
|
+
onError: (listenerFunc: (error: NFCError) => void) => () => void;
|
|
82
118
|
}
|
|
@@ -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
|
|
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 * 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\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\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"]}
|
package/dist/esm/index.js
CHANGED
|
@@ -1,16 +1,48 @@
|
|
|
1
|
+
var _a, _b;
|
|
1
2
|
import { registerPlugin } from '@capacitor/core';
|
|
2
3
|
const NFCPlug = registerPlugin('NFC', {
|
|
3
|
-
web: () => import('./web').then(m => new m.NFCWeb()),
|
|
4
|
+
web: () => import('./web').then((m) => new m.NFCWeb()),
|
|
4
5
|
});
|
|
5
6
|
export * from './definitions';
|
|
6
7
|
export const NFC = {
|
|
7
8
|
isSupported: NFCPlug.isSupported.bind(NFCPlug),
|
|
8
9
|
startScan: NFCPlug.startScan.bind(NFCPlug),
|
|
10
|
+
cancelScan: (_b = (_a = NFCPlug.cancelScan) === null || _a === void 0 ? void 0 : _a.bind(NFCPlug)) !== null && _b !== void 0 ? _b : (async () => {
|
|
11
|
+
/* Android no-op */
|
|
12
|
+
}),
|
|
9
13
|
cancelWriteAndroid: NFCPlug.cancelWriteAndroid.bind(NFCPlug),
|
|
10
|
-
onRead: (func) =>
|
|
11
|
-
|
|
14
|
+
onRead: (func) => {
|
|
15
|
+
NFC.wrapperListeners.push(func);
|
|
16
|
+
// Return unsubscribe function
|
|
17
|
+
return () => {
|
|
18
|
+
NFC.wrapperListeners = NFC.wrapperListeners.filter((l) => l !== func);
|
|
19
|
+
};
|
|
20
|
+
},
|
|
21
|
+
onWrite: (func) => {
|
|
22
|
+
let handle;
|
|
23
|
+
NFCPlug.addListener(`nfcWriteSuccess`, func).then((h) => (handle = h));
|
|
24
|
+
return () => {
|
|
25
|
+
var _a;
|
|
26
|
+
try {
|
|
27
|
+
(_a = handle === null || handle === void 0 ? void 0 : handle.remove) === null || _a === void 0 ? void 0 : _a.call(handle);
|
|
28
|
+
}
|
|
29
|
+
catch (_b) {
|
|
30
|
+
/* empty */
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
},
|
|
12
34
|
onError: (errorFn) => {
|
|
13
|
-
|
|
35
|
+
let handle;
|
|
36
|
+
NFCPlug.addListener(`nfcError`, errorFn).then((h) => (handle = h));
|
|
37
|
+
return () => {
|
|
38
|
+
var _a;
|
|
39
|
+
try {
|
|
40
|
+
(_a = handle === null || handle === void 0 ? void 0 : handle.remove) === null || _a === void 0 ? void 0 : _a.call(handle);
|
|
41
|
+
}
|
|
42
|
+
catch (_b) {
|
|
43
|
+
/* empty */
|
|
44
|
+
}
|
|
45
|
+
};
|
|
14
46
|
},
|
|
15
47
|
removeAllListeners: (eventName) => {
|
|
16
48
|
NFC.wrapperListeners = [];
|
|
@@ -19,63 +51,194 @@ export const NFC = {
|
|
|
19
51
|
wrapperListeners: [],
|
|
20
52
|
async writeNDEF(options) {
|
|
21
53
|
var _a;
|
|
54
|
+
// Helper encoders for well-known record types (only applied to string payloads)
|
|
55
|
+
const buildTextPayload = (text, lang = 'en') => {
|
|
56
|
+
const langBytes = Array.from(new TextEncoder().encode(lang));
|
|
57
|
+
const textBytes = Array.from(new TextEncoder().encode(text));
|
|
58
|
+
const status = langBytes.length & 0x3f; // UTF-8 encoding, language length (<= 63)
|
|
59
|
+
return [status, ...langBytes, ...textBytes];
|
|
60
|
+
};
|
|
61
|
+
const buildUriPayload = (uri, prefixCode = 0x00) => {
|
|
62
|
+
const uriBytes = Array.from(new TextEncoder().encode(uri));
|
|
63
|
+
return [prefixCode, ...uriBytes];
|
|
64
|
+
};
|
|
65
|
+
const recordsArray = (_a = options === null || options === void 0 ? void 0 : options.records) !== null && _a !== void 0 ? _a : [];
|
|
66
|
+
if (recordsArray.length === 0)
|
|
67
|
+
throw new Error('At least one NDEF record is required');
|
|
22
68
|
const ndefMessage = {
|
|
23
|
-
records:
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
69
|
+
records: recordsArray.map((record) => {
|
|
70
|
+
let payload = null;
|
|
71
|
+
if (typeof record.payload === 'string') {
|
|
72
|
+
// Apply spec-compliant formatting only for Well Known Text (T) & URI (U) types.
|
|
73
|
+
if (record.type === 'T') {
|
|
74
|
+
payload = buildTextPayload(record.payload);
|
|
75
|
+
}
|
|
76
|
+
else if (record.type === 'U') {
|
|
77
|
+
payload = buildUriPayload(record.payload);
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
// Generic string: raw UTF-8 bytes (no extra framing)
|
|
81
|
+
payload = Array.from(new TextEncoder().encode(record.payload));
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
else if (Array.isArray(record.payload)) {
|
|
85
|
+
// Assume already raw bytes; do NOT modify
|
|
86
|
+
payload = record.payload;
|
|
87
|
+
}
|
|
88
|
+
else if (record.payload instanceof Uint8Array) {
|
|
89
|
+
payload = Array.from(record.payload);
|
|
90
|
+
}
|
|
31
91
|
if (!payload)
|
|
32
|
-
throw 'Unsupported payload type';
|
|
33
|
-
return {
|
|
34
|
-
|
|
35
|
-
payload,
|
|
36
|
-
};
|
|
37
|
-
})) !== null && _a !== void 0 ? _a : [],
|
|
92
|
+
throw new Error('Unsupported payload type');
|
|
93
|
+
return { type: record.type, payload };
|
|
94
|
+
}),
|
|
38
95
|
};
|
|
39
96
|
await NFCPlug.writeNDEF(ndefMessage);
|
|
40
97
|
},
|
|
41
98
|
};
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
99
|
+
// Decode a base64 string into a Uint8Array (browser-safe). Existing code used atob already.
|
|
100
|
+
const decodeBase64ToBytes = (base64Payload) => {
|
|
101
|
+
const bin = atob(base64Payload);
|
|
102
|
+
const out = new Uint8Array(bin.length);
|
|
103
|
+
for (let i = 0; i < bin.length; i++)
|
|
104
|
+
out[i] = bin.charCodeAt(i);
|
|
105
|
+
return out;
|
|
106
|
+
};
|
|
107
|
+
// Parse NFC Forum "Text" (Well Known 'T') records according to spec.
|
|
108
|
+
const decodeTextRecord = (bytes) => {
|
|
109
|
+
if (bytes.length === 0)
|
|
110
|
+
return '';
|
|
111
|
+
const status = bytes[0];
|
|
112
|
+
const isUTF16 = (status & 0x80) !== 0; // Bit 7 indicates encoding
|
|
113
|
+
const langLength = status & 0x3f; // Bits 0-5 language code length
|
|
114
|
+
if (1 + langLength > bytes.length)
|
|
115
|
+
return ''; // Corrupt
|
|
116
|
+
const textBytes = bytes.slice(1 + langLength);
|
|
117
|
+
try {
|
|
118
|
+
const decoder = new TextDecoder(isUTF16 ? 'utf-16' : 'utf-8');
|
|
119
|
+
return decoder.decode(textBytes);
|
|
120
|
+
}
|
|
121
|
+
catch (_a) {
|
|
122
|
+
// Fallback: naive ASCII
|
|
123
|
+
return Array.from(textBytes)
|
|
124
|
+
.map((b) => String.fromCharCode(b))
|
|
125
|
+
.join('');
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
// Basic URI prefix table for Well Known 'U' records (optional convenience)
|
|
129
|
+
const URI_PREFIX = [
|
|
130
|
+
'',
|
|
131
|
+
'http://www.',
|
|
132
|
+
'https://www.',
|
|
133
|
+
'http://',
|
|
134
|
+
'https://',
|
|
135
|
+
'tel:',
|
|
136
|
+
'mailto:',
|
|
137
|
+
'ftp://anonymous:anonymous@',
|
|
138
|
+
'ftp://ftp.',
|
|
139
|
+
'ftps://',
|
|
140
|
+
'sftp://',
|
|
141
|
+
'smb://',
|
|
142
|
+
'nfs://',
|
|
143
|
+
'ftp://',
|
|
144
|
+
'dav://',
|
|
145
|
+
'news:',
|
|
146
|
+
'telnet://',
|
|
147
|
+
'imap:',
|
|
148
|
+
'rtsp://',
|
|
149
|
+
'urn:',
|
|
150
|
+
'pop:',
|
|
151
|
+
'sip:',
|
|
152
|
+
'sips:',
|
|
153
|
+
'tftp:',
|
|
154
|
+
'btspp://',
|
|
155
|
+
'btl2cap://',
|
|
156
|
+
'btgoep://',
|
|
157
|
+
'tcpobex://',
|
|
158
|
+
'irdaobex://',
|
|
159
|
+
'file://',
|
|
160
|
+
'urn:epc:id:',
|
|
161
|
+
'urn:epc:tag:',
|
|
162
|
+
'urn:epc:pat:',
|
|
163
|
+
'urn:epc:raw:',
|
|
164
|
+
'urn:epc:',
|
|
165
|
+
'urn:nfc:',
|
|
166
|
+
];
|
|
167
|
+
const decodeUriRecord = (bytes) => {
|
|
168
|
+
if (bytes.length === 0)
|
|
169
|
+
return '';
|
|
170
|
+
const prefixIndex = bytes[0];
|
|
171
|
+
const prefix = URI_PREFIX[prefixIndex] || '';
|
|
172
|
+
const remainder = bytes.slice(1);
|
|
173
|
+
try {
|
|
174
|
+
return prefix + new TextDecoder('utf-8').decode(remainder);
|
|
175
|
+
}
|
|
176
|
+
catch (_a) {
|
|
177
|
+
return (prefix +
|
|
178
|
+
Array.from(remainder)
|
|
179
|
+
.map((b) => String.fromCharCode(b))
|
|
180
|
+
.join(''));
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
const toStringPayload = (recordType, bytes) => {
|
|
184
|
+
// Well Known Text
|
|
185
|
+
if (recordType === 'T')
|
|
186
|
+
return decodeTextRecord(bytes);
|
|
187
|
+
// Well Known URI
|
|
188
|
+
if (recordType === 'U')
|
|
189
|
+
return decodeUriRecord(bytes);
|
|
190
|
+
// Default: attempt UTF-8 decode
|
|
191
|
+
try {
|
|
192
|
+
return new TextDecoder('utf-8').decode(bytes);
|
|
193
|
+
}
|
|
194
|
+
catch (_a) {
|
|
195
|
+
return Array.from(bytes)
|
|
196
|
+
.map((c) => String.fromCharCode(c))
|
|
197
|
+
.join('');
|
|
198
|
+
}
|
|
46
199
|
};
|
|
47
200
|
const mapPayloadTo = (type, data) => {
|
|
48
201
|
return {
|
|
49
|
-
messages: data.messages.map(message => ({
|
|
50
|
-
records: message.records.map(record =>
|
|
51
|
-
|
|
52
|
-
payload
|
|
53
|
-
|
|
54
|
-
:
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
202
|
+
messages: data.messages.map((message) => ({
|
|
203
|
+
records: message.records.map((record) => {
|
|
204
|
+
const bytes = decodeBase64ToBytes(record.payload);
|
|
205
|
+
let payload;
|
|
206
|
+
switch (type) {
|
|
207
|
+
case 'b64':
|
|
208
|
+
payload = record.payload; // original base64 string
|
|
209
|
+
break;
|
|
210
|
+
case 'uint8Array':
|
|
211
|
+
payload = bytes;
|
|
212
|
+
break;
|
|
213
|
+
case 'numberArray':
|
|
214
|
+
payload = Array.from(bytes);
|
|
215
|
+
break;
|
|
216
|
+
case 'string':
|
|
217
|
+
payload = toStringPayload(record.type, bytes);
|
|
218
|
+
break;
|
|
219
|
+
default:
|
|
220
|
+
payload = record.payload;
|
|
221
|
+
}
|
|
222
|
+
return { type: record.type, payload };
|
|
223
|
+
}),
|
|
224
|
+
})),
|
|
225
|
+
tagInfo: data.tagInfo, // Include tag information
|
|
63
226
|
};
|
|
64
227
|
};
|
|
65
|
-
NFCPlug.addListener(`nfcTag`, data => {
|
|
228
|
+
NFCPlug.addListener(`nfcTag`, (data) => {
|
|
66
229
|
const wrappedData = {
|
|
67
230
|
base64() {
|
|
68
|
-
return mapPayloadTo(
|
|
231
|
+
return mapPayloadTo('b64', data);
|
|
69
232
|
},
|
|
70
233
|
string() {
|
|
71
|
-
return mapPayloadTo(
|
|
234
|
+
return mapPayloadTo('string', data);
|
|
72
235
|
},
|
|
73
236
|
uint8Array() {
|
|
74
|
-
return mapPayloadTo(
|
|
237
|
+
return mapPayloadTo('uint8Array', data);
|
|
75
238
|
},
|
|
76
239
|
numberArray() {
|
|
77
|
-
return mapPayloadTo(
|
|
78
|
-
}
|
|
240
|
+
return mapPayloadTo('numberArray', data);
|
|
241
|
+
},
|
|
79
242
|
};
|
|
80
243
|
for (const listener of NFC.wrapperListeners) {
|
|
81
244
|
listener(wrappedData);
|
package/dist/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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})"]}
|
|
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 cancelScan:\n NFCPlug.cancelScan?.bind(NFCPlug) ??\n (async () => {\n /* Android no-op */\n }),\n cancelWriteAndroid: NFCPlug.cancelWriteAndroid.bind(NFCPlug),\n onRead: (func: TagResultListenerFunc) => {\n NFC.wrapperListeners.push(func);\n // Return unsubscribe function\n return () => {\n NFC.wrapperListeners = NFC.wrapperListeners.filter((l) => l !== func);\n };\n },\n onWrite: (func: () => void) => {\n let handle: any;\n NFCPlug.addListener(`nfcWriteSuccess`, func).then((h) => (handle = h));\n return () => {\n try {\n handle?.remove?.();\n } catch {\n /* empty */\n }\n };\n },\n onError: (errorFn: (error: NFCError) => void) => {\n let handle: any;\n NFCPlug.addListener(`nfcError`, errorFn).then((h) => (handle = h));\n return () => {\n try {\n handle?.remove?.();\n } catch {\n /* empty */\n }\n };\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 // Helper encoders for well-known record types (only applied to string payloads)\n const buildTextPayload = (text: string, lang = 'en'): number[] => {\n const langBytes = Array.from(new TextEncoder().encode(lang));\n const textBytes = Array.from(new TextEncoder().encode(text));\n const status = langBytes.length & 0x3f; // UTF-8 encoding, language length (<= 63)\n return [status, ...langBytes, ...textBytes];\n };\n const buildUriPayload = (uri: string, prefixCode = 0x00): number[] => {\n const uriBytes = Array.from(new TextEncoder().encode(uri));\n return [prefixCode, ...uriBytes];\n };\n\n const recordsArray = options?.records ?? [];\n if (recordsArray.length === 0) throw new Error('At least one NDEF record is required');\n\n const ndefMessage: NDEFWriteOptions<number[]> = {\n records: recordsArray.map((record) => {\n let payload: number[] | null = null;\n\n if (typeof record.payload === 'string') {\n // Apply spec-compliant formatting only for Well Known Text (T) & URI (U) types.\n if (record.type === 'T') {\n payload = buildTextPayload(record.payload);\n } else if (record.type === 'U') {\n payload = buildUriPayload(record.payload);\n } else {\n // Generic string: raw UTF-8 bytes (no extra framing)\n payload = Array.from(new TextEncoder().encode(record.payload));\n }\n } else if (Array.isArray(record.payload)) {\n // Assume already raw bytes; do NOT modify\n payload = record.payload as number[];\n } else if (record.payload instanceof Uint8Array) {\n payload = Array.from(record.payload);\n }\n\n if (!payload) throw new Error('Unsupported payload type');\n\n return { type: record.type, payload };\n }),\n };\n\n await NFCPlug.writeNDEF(ndefMessage);\n },\n};\n\n// ----- Payload transformation helpers -----\ntype DecodeSpecifier = 'b64' | 'string' | 'uint8Array' | 'numberArray';\ntype decodedType<T extends DecodeSpecifier> = NDEFMessages<\n T extends 'b64' ? string : T extends 'string' ? string : T extends 'uint8Array' ? Uint8Array : number[]\n>;\n\n// Decode a base64 string into a Uint8Array (browser-safe). Existing code used atob already.\nconst decodeBase64ToBytes = (base64Payload: string): Uint8Array => {\n const bin = atob(base64Payload);\n const out = new Uint8Array(bin.length);\n for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);\n return out;\n};\n\n// Parse NFC Forum \"Text\" (Well Known 'T') records according to spec.\nconst decodeTextRecord = (bytes: Uint8Array): string => {\n if (bytes.length === 0) return '';\n const status = bytes[0];\n const isUTF16 = (status & 0x80) !== 0; // Bit 7 indicates encoding\n const langLength = status & 0x3f; // Bits 0-5 language code length\n if (1 + langLength > bytes.length) return ''; // Corrupt\n const textBytes = bytes.slice(1 + langLength);\n try {\n const decoder = new TextDecoder(isUTF16 ? 'utf-16' : 'utf-8');\n return decoder.decode(textBytes);\n } catch {\n // Fallback: naive ASCII\n return Array.from(textBytes)\n .map((b) => String.fromCharCode(b))\n .join('');\n }\n};\n\n// Basic URI prefix table for Well Known 'U' records (optional convenience)\nconst URI_PREFIX: string[] = [\n '',\n 'http://www.',\n 'https://www.',\n 'http://',\n 'https://',\n 'tel:',\n 'mailto:',\n 'ftp://anonymous:anonymous@',\n 'ftp://ftp.',\n 'ftps://',\n 'sftp://',\n 'smb://',\n 'nfs://',\n 'ftp://',\n 'dav://',\n 'news:',\n 'telnet://',\n 'imap:',\n 'rtsp://',\n 'urn:',\n 'pop:',\n 'sip:',\n 'sips:',\n 'tftp:',\n 'btspp://',\n 'btl2cap://',\n 'btgoep://',\n 'tcpobex://',\n 'irdaobex://',\n 'file://',\n 'urn:epc:id:',\n 'urn:epc:tag:',\n 'urn:epc:pat:',\n 'urn:epc:raw:',\n 'urn:epc:',\n 'urn:nfc:',\n];\n\nconst decodeUriRecord = (bytes: Uint8Array): string => {\n if (bytes.length === 0) return '';\n const prefixIndex = bytes[0];\n const prefix = URI_PREFIX[prefixIndex] || '';\n const remainder = bytes.slice(1);\n try {\n return prefix + new TextDecoder('utf-8').decode(remainder);\n } catch {\n return (\n prefix +\n Array.from(remainder)\n .map((b) => String.fromCharCode(b))\n .join('')\n );\n }\n};\n\nconst toStringPayload = (recordType: string, bytes: Uint8Array): string => {\n // Well Known Text\n if (recordType === 'T') return decodeTextRecord(bytes);\n // Well Known URI\n if (recordType === 'U') return decodeUriRecord(bytes);\n // Default: attempt UTF-8 decode\n try {\n return new TextDecoder('utf-8').decode(bytes);\n } catch {\n return Array.from(bytes)\n .map((c) => String.fromCharCode(c))\n .join('');\n }\n};\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 const bytes = decodeBase64ToBytes(record.payload as unknown as string);\n let payload: any;\n switch (type) {\n case 'b64':\n payload = record.payload; // original base64 string\n break;\n case 'uint8Array':\n payload = bytes;\n break;\n case 'numberArray':\n payload = Array.from(bytes);\n break;\n case 'string':\n payload = toStringPayload(record.type, bytes);\n break;\n default:\n payload = record.payload;\n }\n return { type: record.type, payload };\n }),\n })),\n tagInfo: data.tagInfo, // Include tag information\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});\n"]}
|
package/dist/esm/web.d.ts
CHANGED
|
@@ -1,14 +1,10 @@
|
|
|
1
1
|
import { WebPlugin } from '@capacitor/core';
|
|
2
|
-
|
|
3
|
-
export declare class NFCWeb extends WebPlugin implements NFCPlugin {
|
|
4
|
-
wrapperListeners: never[];
|
|
2
|
+
export declare class NFCWeb extends WebPlugin {
|
|
5
3
|
isSupported(): Promise<{
|
|
6
4
|
supported: boolean;
|
|
7
5
|
}>;
|
|
8
6
|
startScan(): Promise<void>;
|
|
7
|
+
cancelScan(): Promise<void>;
|
|
9
8
|
cancelWriteAndroid(): Promise<void>;
|
|
10
9
|
writeNDEF(): Promise<void>;
|
|
11
|
-
onRead(_func: TagResultListenerFunc): Promise<void>;
|
|
12
|
-
onWrite(): Promise<void>;
|
|
13
|
-
onError(_errorFn: (error: any) => void): Promise<void>;
|
|
14
10
|
}
|
package/dist/esm/web.js
CHANGED
|
@@ -1,31 +1,19 @@
|
|
|
1
1
|
import { WebPlugin } from '@capacitor/core';
|
|
2
2
|
export class NFCWeb extends WebPlugin {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
this.wrapperListeners = [];
|
|
3
|
+
async isSupported() {
|
|
4
|
+
return { supported: false };
|
|
6
5
|
}
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
async startScan() {
|
|
7
|
+
throw new Error('NFC is not supported on web');
|
|
9
8
|
}
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
async cancelScan() {
|
|
10
|
+
throw new Error('NFC is not supported on web');
|
|
12
11
|
}
|
|
13
|
-
cancelWriteAndroid() {
|
|
14
|
-
|
|
12
|
+
async cancelWriteAndroid() {
|
|
13
|
+
throw new Error('NFC is not supported on web');
|
|
15
14
|
}
|
|
16
|
-
writeNDEF() {
|
|
17
|
-
|
|
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'));
|
|
15
|
+
async writeNDEF() {
|
|
16
|
+
throw new Error('NFC is not supported on web');
|
|
29
17
|
}
|
|
30
18
|
}
|
|
31
19
|
//# sourceMappingURL=web.js.map
|
package/dist/esm/web.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,MAAM,OAAO,MAAO,SAAQ,SAAS;IACnC,KAAK,CAAC,WAAW;QACf,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IAC9B,CAAC;IAED,KAAK,CAAC,SAAS;QACb,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IACjD,CAAC;IAED,KAAK,CAAC,UAAU;QACd,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IACjD,CAAC;IAED,KAAK,CAAC,kBAAkB;QACtB,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IACjD,CAAC;IAED,KAAK,CAAC,SAAS;QACb,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IACjD,CAAC;CACF","sourcesContent":["import { WebPlugin } from '@capacitor/core';\n\nexport class NFCWeb extends WebPlugin {\n async isSupported(): Promise<{ supported: boolean }> {\n return { supported: false };\n }\n\n async startScan(): Promise<void> {\n throw new Error('NFC is not supported on web');\n }\n\n async cancelScan(): Promise<void> {\n throw new Error('NFC is not supported on web');\n }\n\n async cancelWriteAndroid(): Promise<void> {\n throw new Error('NFC is not supported on web');\n }\n\n async writeNDEF(): Promise<void> {\n throw new Error('NFC is not supported on web');\n }\n}\n"]}
|