@appattest/react-native 0.1.0

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,245 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = exports.ErrorCode = exports.AppAttestError = exports.AppAttest = void 0;
7
+ exports.useAllSecrets = useAllSecrets;
8
+ exports.useAppAttestState = useAppAttestState;
9
+ exports.useSecret = useSecret;
10
+ var _react = require("react");
11
+ var _reactNative = require("react-native");
12
+ var _NativeAppAttest = _interopRequireDefault(require("./NativeAppAttest"));
13
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
14
+ /**
15
+ * @appattest/react-native — public API.
16
+ *
17
+ * Surface mirrors the Swift SDK's bridge translation:
18
+ * - AppAttest.start() — fire-and-forget setup (zero-arg)
19
+ * - AppAttest.getSecret(name) — Promise<string | null>
20
+ * - AppAttest.getAllSecrets() — Promise<Record<string, string>>
21
+ * - AppAttest.getState() — Promise<AppAttestState>
22
+ * - AppAttest.waitForReady() — Promise<void>
23
+ * - AppAttest.retry() — Promise<void>
24
+ * - AppAttest.addStateListener(fn) — (state) => void; returns unsubscribe
25
+ * - AppAttest.setDebugMode
26
+ *
27
+ * React hooks (idiomatic for RN consumers):
28
+ * - useSecret(name) — string | null, re-renders on rotation
29
+ * - useAllSecrets() — Record<string, string>, re-renders on rotation
30
+ * - useAppAttestState() — AppAttestState, re-renders on transition
31
+ *
32
+ * There is no sandbox-mode modal logic. Developers handle their
33
+ * own UX for `.subscriptionRequired` / `.creditsRequired` / `.unavailable`.
34
+ */
35
+
36
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
37
+ const eventEmitter = new _reactNative.NativeEventEmitter(_reactNative.NativeModules.RNAppAttest);
38
+
39
+ /**
40
+ * Lifecycle state. Mirrors `AppAttestClient.State` on the native side.
41
+ */
42
+
43
+ /**
44
+ * Typed error thrown by every method. `code` matches the Swift SDK's
45
+ * `AppAttestError.code` one-for-one.
46
+ */
47
+ class AppAttestError extends Error {
48
+ /** For `subscription_required`: URL to (re)start the project subscription. */
49
+
50
+ /** For `credits_required`: URL to top up the project balance. */
51
+
52
+ constructor(code, message, extras) {
53
+ super(message);
54
+ this.name = 'AppAttestError';
55
+ this.code = code;
56
+ this.subscribeUrl = extras?.subscribeUrl;
57
+ this.topupUrl = extras?.topupUrl;
58
+ this.nativeError = extras?.nativeError;
59
+ }
60
+
61
+ /**
62
+ * Single accessor for the dashboard URL regardless of code. Returns
63
+ * `subscribeUrl` for `subscription_required`, `topupUrl` for
64
+ * `credits_required`, else `undefined`.
65
+ */
66
+ get actionUrl() {
67
+ return this.subscribeUrl ?? this.topupUrl;
68
+ }
69
+ }
70
+
71
+ /** Stable string codes. Match Swift `AppAttestError.code` one-for-one. */
72
+ exports.AppAttestError = AppAttestError;
73
+ const ErrorCode = exports.ErrorCode = {
74
+ SubscriptionRequired: 'subscription_required',
75
+ CreditsRequired: 'credits_required',
76
+ AttestationRejected: 'attestation_rejected',
77
+ ServiceUnavailable: 'service_unavailable',
78
+ Network: 'network',
79
+ DebugModeReleaseBlocked: 'debug_mode_release_blocked',
80
+ InvalidArgument: 'invalid_argument'
81
+ };
82
+ function buildError(e, native) {
83
+ return new AppAttestError(e.code ?? 'internal_error', e.message ?? String(native), {
84
+ subscribeUrl: e.userInfo?.subscribeUrl ?? e.subscribeUrl,
85
+ topupUrl: e.userInfo?.topupUrl ?? e.topupUrl,
86
+ nativeError: native
87
+ });
88
+ }
89
+ async function wrap(p) {
90
+ try {
91
+ return await p;
92
+ } catch (err) {
93
+ throw buildError(err, err);
94
+ }
95
+ }
96
+ function decodeState(raw) {
97
+ const error = raw.error ? buildError(raw.error, raw.error) : undefined;
98
+ return {
99
+ name: raw.name,
100
+ error
101
+ };
102
+ }
103
+ const AppAttest = exports.AppAttest = {
104
+ /**
105
+ * Synchronous, idempotent setup. Zero-argument. Apple's AAGUID
106
+ * determines the bucket (sandbox vs production) server-side; the SDK
107
+ * is bucket-blind.
108
+ */
109
+ start() {
110
+ return wrap(_NativeAppAttest.default.start());
111
+ },
112
+ /** Awaits a terminal state. Resolves on `ready`; rejects with
113
+ * AppAttestError on subscriptionRequired / creditsRequired / unavailable. */
114
+ waitForReady() {
115
+ return wrap(_NativeAppAttest.default.waitForReady());
116
+ },
117
+ /** Re-runs the background sync. */
118
+ retry() {
119
+ return wrap(_NativeAppAttest.default.retry());
120
+ },
121
+ /** Wipes stored credentials and secrets. */
122
+ reset() {
123
+ return wrap(_NativeAppAttest.default.reset());
124
+ },
125
+ /**
126
+ * Invalidate the cached secrets bundle and immediately sync. Keeps
127
+ * attestation credentials. Forces a 200 on the next sync, which
128
+ * consumes one credit on the production bucket.
129
+ *
130
+ * Use this for host-app "force refresh" / "sync now" UX. For wiping
131
+ * everything (including attestation), see ``reset()``.
132
+ */
133
+ invalidateBundle() {
134
+ return wrap(_NativeAppAttest.default.invalidateBundle());
135
+ },
136
+ /** Returns the secret for `name`, or `null`. */
137
+ getSecret(name) {
138
+ return wrap(_NativeAppAttest.default.getSecret(name));
139
+ },
140
+ /** Snapshot of every synced secret. */
141
+ getAllSecrets() {
142
+ return wrap(_NativeAppAttest.default.getAllSecrets());
143
+ },
144
+ /** Current state snapshot. */
145
+ async getState() {
146
+ const raw = await wrap(_NativeAppAttest.default.getState());
147
+ return decodeState(raw);
148
+ },
149
+ /** Subscribe to state transitions. Returns an unsubscribe fn. */
150
+ addStateListener(listener) {
151
+ const subscription = eventEmitter.addListener('stateChanged', raw => {
152
+ listener(decodeState(raw));
153
+ });
154
+ return () => subscription.remove();
155
+ },
156
+ /** Set runtime mode. `'production'` (or `null`) is default. */
157
+ setDebugMode(mode, stubs) {
158
+ return wrap(_NativeAppAttest.default.setDebugMode(mode, stubs ?? null));
159
+ }
160
+
161
+ // setApiBaseUrl is not exposed — the base URL is hardcoded in the Swift
162
+ // SDK. There is no runtime override path from JavaScript.
163
+ };
164
+
165
+ // MARK: - React hooks
166
+
167
+ /**
168
+ * React hook returning the current value of `secrets[name]`. Re-renders
169
+ * the host component whenever the underlying value changes (e.g. after
170
+ * a foreground rotation pulled new data).
171
+ */
172
+ function useSecret(name) {
173
+ const [value, setValue] = (0, _react.useState)(null);
174
+ (0, _react.useEffect)(() => {
175
+ let active = true;
176
+ AppAttest.getSecret(name).then(v => {
177
+ if (active) setValue(v);
178
+ }).catch(() => {});
179
+ const unsubscribe = AppAttest.addStateListener(async s => {
180
+ if (s.name === 'ready') {
181
+ try {
182
+ const v = await AppAttest.getSecret(name);
183
+ if (active) setValue(v);
184
+ } catch {/* ignore */}
185
+ }
186
+ });
187
+ return () => {
188
+ active = false;
189
+ unsubscribe();
190
+ };
191
+ }, [name]);
192
+ return value;
193
+ }
194
+
195
+ /**
196
+ * React hook returning every synced secret. Re-renders on rotation.
197
+ */
198
+ function useAllSecrets() {
199
+ const [all, setAll] = (0, _react.useState)({});
200
+ (0, _react.useEffect)(() => {
201
+ let active = true;
202
+ AppAttest.getAllSecrets().then(v => {
203
+ if (active) setAll(v);
204
+ }).catch(() => {});
205
+ const unsubscribe = AppAttest.addStateListener(async s => {
206
+ if (s.name === 'ready') {
207
+ try {
208
+ const v = await AppAttest.getAllSecrets();
209
+ if (active) setAll(v);
210
+ } catch {/* ignore */}
211
+ }
212
+ });
213
+ return () => {
214
+ active = false;
215
+ unsubscribe();
216
+ };
217
+ }, []);
218
+ return all;
219
+ }
220
+
221
+ /**
222
+ * React hook returning the current `AppAttestState`. Re-renders on
223
+ * every transition.
224
+ */
225
+ function useAppAttestState() {
226
+ const [state, setState] = (0, _react.useState)({
227
+ name: 'initializing'
228
+ });
229
+ (0, _react.useEffect)(() => {
230
+ let active = true;
231
+ AppAttest.getState().then(s => {
232
+ if (active) setState(s);
233
+ }).catch(() => {});
234
+ const unsubscribe = AppAttest.addStateListener(s => {
235
+ if (active) setState(s);
236
+ });
237
+ return () => {
238
+ active = false;
239
+ unsubscribe();
240
+ };
241
+ }, []);
242
+ return state;
243
+ }
244
+ var _default = exports.default = AppAttest;
245
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_react","require","_reactNative","_NativeAppAttest","_interopRequireDefault","e","__esModule","default","eventEmitter","NativeEventEmitter","NativeModules","RNAppAttest","AppAttestError","Error","constructor","code","message","extras","name","subscribeUrl","topupUrl","nativeError","actionUrl","exports","ErrorCode","SubscriptionRequired","CreditsRequired","AttestationRejected","ServiceUnavailable","Network","DebugModeReleaseBlocked","InvalidArgument","buildError","native","String","userInfo","wrap","p","err","decodeState","raw","error","undefined","AppAttest","start","NativeAppAttest","waitForReady","retry","reset","invalidateBundle","getSecret","getAllSecrets","getState","addStateListener","listener","subscription","addListener","remove","setDebugMode","mode","stubs","useSecret","value","setValue","useState","useEffect","active","then","v","catch","unsubscribe","s","useAllSecrets","all","setAll","useAppAttestState","state","setState","_default"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1 @@
1
+ {"type":"commonjs"}
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * TurboModule spec for the AppAttest iOS native module.
5
+ *
6
+ * Codegen reads this file. The shape is restricted to what TurboModule
7
+ * codegen can serialize (primitives, Object, arrays of primitives,
8
+ * Promises, null).
9
+ *
10
+ * Errors: rejection objects carry `{ code, message,
11
+ * subscribeUrl?, topupUrl? }`. The TS wrapper in `index.ts` translates
12
+ * these into `AppAttestError`.
13
+ */
14
+
15
+ import { TurboModuleRegistry } from 'react-native';
16
+ export default TurboModuleRegistry.getEnforcing('RNAppAttest');
17
+ //# sourceMappingURL=NativeAppAttest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["TurboModuleRegistry","getEnforcing"],"sourceRoot":"../../src","sources":["NativeAppAttest.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAASA,mBAAmB,QAAQ,cAAc;AAyDlD,eAAeA,mBAAmB,CAACC,YAAY,CAAO,aAAa,CAAC","ignoreList":[]}
@@ -0,0 +1,237 @@
1
+ "use strict";
2
+
3
+ /**
4
+ * @appattest/react-native — public API.
5
+ *
6
+ * Surface mirrors the Swift SDK's bridge translation:
7
+ * - AppAttest.start() — fire-and-forget setup (zero-arg)
8
+ * - AppAttest.getSecret(name) — Promise<string | null>
9
+ * - AppAttest.getAllSecrets() — Promise<Record<string, string>>
10
+ * - AppAttest.getState() — Promise<AppAttestState>
11
+ * - AppAttest.waitForReady() — Promise<void>
12
+ * - AppAttest.retry() — Promise<void>
13
+ * - AppAttest.addStateListener(fn) — (state) => void; returns unsubscribe
14
+ * - AppAttest.setDebugMode
15
+ *
16
+ * React hooks (idiomatic for RN consumers):
17
+ * - useSecret(name) — string | null, re-renders on rotation
18
+ * - useAllSecrets() — Record<string, string>, re-renders on rotation
19
+ * - useAppAttestState() — AppAttestState, re-renders on transition
20
+ *
21
+ * There is no sandbox-mode modal logic. Developers handle their
22
+ * own UX for `.subscriptionRequired` / `.creditsRequired` / `.unavailable`.
23
+ */
24
+
25
+ import { useEffect, useState } from 'react';
26
+ import { NativeEventEmitter, NativeModules } from 'react-native';
27
+ import NativeAppAttest from './NativeAppAttest';
28
+
29
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
30
+ const eventEmitter = new NativeEventEmitter(NativeModules.RNAppAttest);
31
+
32
+ /**
33
+ * Lifecycle state. Mirrors `AppAttestClient.State` on the native side.
34
+ */
35
+
36
+ /**
37
+ * Typed error thrown by every method. `code` matches the Swift SDK's
38
+ * `AppAttestError.code` one-for-one.
39
+ */
40
+ export class AppAttestError extends Error {
41
+ /** For `subscription_required`: URL to (re)start the project subscription. */
42
+
43
+ /** For `credits_required`: URL to top up the project balance. */
44
+
45
+ constructor(code, message, extras) {
46
+ super(message);
47
+ this.name = 'AppAttestError';
48
+ this.code = code;
49
+ this.subscribeUrl = extras?.subscribeUrl;
50
+ this.topupUrl = extras?.topupUrl;
51
+ this.nativeError = extras?.nativeError;
52
+ }
53
+
54
+ /**
55
+ * Single accessor for the dashboard URL regardless of code. Returns
56
+ * `subscribeUrl` for `subscription_required`, `topupUrl` for
57
+ * `credits_required`, else `undefined`.
58
+ */
59
+ get actionUrl() {
60
+ return this.subscribeUrl ?? this.topupUrl;
61
+ }
62
+ }
63
+
64
+ /** Stable string codes. Match Swift `AppAttestError.code` one-for-one. */
65
+ export const ErrorCode = {
66
+ SubscriptionRequired: 'subscription_required',
67
+ CreditsRequired: 'credits_required',
68
+ AttestationRejected: 'attestation_rejected',
69
+ ServiceUnavailable: 'service_unavailable',
70
+ Network: 'network',
71
+ DebugModeReleaseBlocked: 'debug_mode_release_blocked',
72
+ InvalidArgument: 'invalid_argument'
73
+ };
74
+ function buildError(e, native) {
75
+ return new AppAttestError(e.code ?? 'internal_error', e.message ?? String(native), {
76
+ subscribeUrl: e.userInfo?.subscribeUrl ?? e.subscribeUrl,
77
+ topupUrl: e.userInfo?.topupUrl ?? e.topupUrl,
78
+ nativeError: native
79
+ });
80
+ }
81
+ async function wrap(p) {
82
+ try {
83
+ return await p;
84
+ } catch (err) {
85
+ throw buildError(err, err);
86
+ }
87
+ }
88
+ function decodeState(raw) {
89
+ const error = raw.error ? buildError(raw.error, raw.error) : undefined;
90
+ return {
91
+ name: raw.name,
92
+ error
93
+ };
94
+ }
95
+ export const AppAttest = {
96
+ /**
97
+ * Synchronous, idempotent setup. Zero-argument. Apple's AAGUID
98
+ * determines the bucket (sandbox vs production) server-side; the SDK
99
+ * is bucket-blind.
100
+ */
101
+ start() {
102
+ return wrap(NativeAppAttest.start());
103
+ },
104
+ /** Awaits a terminal state. Resolves on `ready`; rejects with
105
+ * AppAttestError on subscriptionRequired / creditsRequired / unavailable. */
106
+ waitForReady() {
107
+ return wrap(NativeAppAttest.waitForReady());
108
+ },
109
+ /** Re-runs the background sync. */
110
+ retry() {
111
+ return wrap(NativeAppAttest.retry());
112
+ },
113
+ /** Wipes stored credentials and secrets. */
114
+ reset() {
115
+ return wrap(NativeAppAttest.reset());
116
+ },
117
+ /**
118
+ * Invalidate the cached secrets bundle and immediately sync. Keeps
119
+ * attestation credentials. Forces a 200 on the next sync, which
120
+ * consumes one credit on the production bucket.
121
+ *
122
+ * Use this for host-app "force refresh" / "sync now" UX. For wiping
123
+ * everything (including attestation), see ``reset()``.
124
+ */
125
+ invalidateBundle() {
126
+ return wrap(NativeAppAttest.invalidateBundle());
127
+ },
128
+ /** Returns the secret for `name`, or `null`. */
129
+ getSecret(name) {
130
+ return wrap(NativeAppAttest.getSecret(name));
131
+ },
132
+ /** Snapshot of every synced secret. */
133
+ getAllSecrets() {
134
+ return wrap(NativeAppAttest.getAllSecrets());
135
+ },
136
+ /** Current state snapshot. */
137
+ async getState() {
138
+ const raw = await wrap(NativeAppAttest.getState());
139
+ return decodeState(raw);
140
+ },
141
+ /** Subscribe to state transitions. Returns an unsubscribe fn. */
142
+ addStateListener(listener) {
143
+ const subscription = eventEmitter.addListener('stateChanged', raw => {
144
+ listener(decodeState(raw));
145
+ });
146
+ return () => subscription.remove();
147
+ },
148
+ /** Set runtime mode. `'production'` (or `null`) is default. */
149
+ setDebugMode(mode, stubs) {
150
+ return wrap(NativeAppAttest.setDebugMode(mode, stubs ?? null));
151
+ }
152
+
153
+ // setApiBaseUrl is not exposed — the base URL is hardcoded in the Swift
154
+ // SDK. There is no runtime override path from JavaScript.
155
+ };
156
+
157
+ // MARK: - React hooks
158
+
159
+ /**
160
+ * React hook returning the current value of `secrets[name]`. Re-renders
161
+ * the host component whenever the underlying value changes (e.g. after
162
+ * a foreground rotation pulled new data).
163
+ */
164
+ export function useSecret(name) {
165
+ const [value, setValue] = useState(null);
166
+ useEffect(() => {
167
+ let active = true;
168
+ AppAttest.getSecret(name).then(v => {
169
+ if (active) setValue(v);
170
+ }).catch(() => {});
171
+ const unsubscribe = AppAttest.addStateListener(async s => {
172
+ if (s.name === 'ready') {
173
+ try {
174
+ const v = await AppAttest.getSecret(name);
175
+ if (active) setValue(v);
176
+ } catch {/* ignore */}
177
+ }
178
+ });
179
+ return () => {
180
+ active = false;
181
+ unsubscribe();
182
+ };
183
+ }, [name]);
184
+ return value;
185
+ }
186
+
187
+ /**
188
+ * React hook returning every synced secret. Re-renders on rotation.
189
+ */
190
+ export function useAllSecrets() {
191
+ const [all, setAll] = useState({});
192
+ useEffect(() => {
193
+ let active = true;
194
+ AppAttest.getAllSecrets().then(v => {
195
+ if (active) setAll(v);
196
+ }).catch(() => {});
197
+ const unsubscribe = AppAttest.addStateListener(async s => {
198
+ if (s.name === 'ready') {
199
+ try {
200
+ const v = await AppAttest.getAllSecrets();
201
+ if (active) setAll(v);
202
+ } catch {/* ignore */}
203
+ }
204
+ });
205
+ return () => {
206
+ active = false;
207
+ unsubscribe();
208
+ };
209
+ }, []);
210
+ return all;
211
+ }
212
+
213
+ /**
214
+ * React hook returning the current `AppAttestState`. Re-renders on
215
+ * every transition.
216
+ */
217
+ export function useAppAttestState() {
218
+ const [state, setState] = useState({
219
+ name: 'initializing'
220
+ });
221
+ useEffect(() => {
222
+ let active = true;
223
+ AppAttest.getState().then(s => {
224
+ if (active) setState(s);
225
+ }).catch(() => {});
226
+ const unsubscribe = AppAttest.addStateListener(s => {
227
+ if (active) setState(s);
228
+ });
229
+ return () => {
230
+ active = false;
231
+ unsubscribe();
232
+ };
233
+ }, []);
234
+ return state;
235
+ }
236
+ export default AppAttest;
237
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["useEffect","useState","NativeEventEmitter","NativeModules","NativeAppAttest","eventEmitter","RNAppAttest","AppAttestError","Error","constructor","code","message","extras","name","subscribeUrl","topupUrl","nativeError","actionUrl","ErrorCode","SubscriptionRequired","CreditsRequired","AttestationRejected","ServiceUnavailable","Network","DebugModeReleaseBlocked","InvalidArgument","buildError","e","native","String","userInfo","wrap","p","err","decodeState","raw","error","undefined","AppAttest","start","waitForReady","retry","reset","invalidateBundle","getSecret","getAllSecrets","getState","addStateListener","listener","subscription","addListener","remove","setDebugMode","mode","stubs","useSecret","value","setValue","active","then","v","catch","unsubscribe","s","useAllSecrets","all","setAll","useAppAttestState","state","setState"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * TurboModule spec for the AppAttest iOS native module.
3
+ *
4
+ * Codegen reads this file. The shape is restricted to what TurboModule
5
+ * codegen can serialize (primitives, Object, arrays of primitives,
6
+ * Promises, null).
7
+ *
8
+ * Errors: rejection objects carry `{ code, message,
9
+ * subscribeUrl?, topupUrl? }`. The TS wrapper in `index.ts` translates
10
+ * these into `AppAttestError`.
11
+ */
12
+ import type { TurboModule } from 'react-native';
13
+ export interface Spec extends TurboModule {
14
+ /** Synchronous, idempotent setup. Zero-argument (bucket is
15
+ * AAGUID-derived server-side). */
16
+ start(): Promise<void>;
17
+ /** Awaits the next terminal state. Resolves on `ready`; rejects on
18
+ * subscriptionRequired / creditsRequired / unavailable. */
19
+ waitForReady(): Promise<void>;
20
+ /** Re-runs the background sync. */
21
+ retry(): Promise<void>;
22
+ /** Wipes stored credentials and secrets. */
23
+ reset(): Promise<void>;
24
+ /** Invalidate the cached secrets bundle and immediately sync. Keeps
25
+ * attestation; forces a 200 (1 credit on production). */
26
+ invalidateBundle(): Promise<void>;
27
+ /** Synchronous-feeling secret lookup. Returns `null` if not yet
28
+ * synced or absent. */
29
+ getSecret(name: string): Promise<string | null>;
30
+ /** Snapshot of every synced secret as `{ [name]: value }`. */
31
+ getAllSecrets(): Promise<{
32
+ [key: string]: string;
33
+ }>;
34
+ /** Current state as `{ name, error? }`. */
35
+ getState(): Promise<{
36
+ name: string;
37
+ error?: {
38
+ code: string;
39
+ message: string;
40
+ subscribeUrl?: string;
41
+ topupUrl?: string;
42
+ };
43
+ }>;
44
+ /** `null` / `'production'` for production; `'local'` for the DEBUG-only
45
+ * stub mode. `'local'` requires `stubs`. */
46
+ setDebugMode(name: string | null, stubs: {
47
+ [key: string]: string;
48
+ } | null): Promise<void>;
49
+ addListener(eventName: string): void;
50
+ removeListeners(count: number): void;
51
+ }
52
+ declare const _default: Spec;
53
+ export default _default;
54
+ //# sourceMappingURL=NativeAppAttest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NativeAppAttest.d.ts","sourceRoot":"","sources":["../../src/NativeAppAttest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD,MAAM,WAAW,IAAK,SAAQ,WAAW;IAGvC;uCACmC;IACnC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB;gEAC4D;IAC5D,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE9B,mCAAmC;IACnC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB,4CAA4C;IAC5C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB;8DAC0D;IAC1D,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAIlC;4BACwB;IACxB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAEhD,8DAA8D;IAC9D,aAAa,IAAI,OAAO,CAAC;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC,CAAC;IAEpD,2CAA2C;IAC3C,QAAQ,IAAI,OAAO,CAAC;QAClB,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,CAAC,EAAE;YACN,IAAI,EAAE,MAAM,CAAC;YACb,OAAO,EAAE,MAAM,CAAC;YAChB,YAAY,CAAC,EAAE,MAAM,CAAC;YACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;SACnB,CAAC;KACH,CAAC,CAAC;IAIH;iDAC6C;IAC7C,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAM1F,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtC;;AAED,wBAAqE"}