@webority-technologies/mobile-core 0.0.1 → 0.0.3
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 +22 -1
- package/lib/commonjs/api/baseUrl.js +34 -0
- package/lib/commonjs/api/curl.js +109 -0
- package/lib/commonjs/api/publicClient.js +11 -20
- package/lib/commonjs/api/retry.js +75 -0
- package/lib/commonjs/api/userClient.js +46 -22
- package/lib/commonjs/auth/authStore.js +101 -33
- package/lib/commonjs/auth/jwt.js +32 -8
- package/lib/commonjs/config/index.js +2 -1
- package/lib/commonjs/deepLink/index.js +286 -0
- package/lib/commonjs/download/adapters/expoFs.js +100 -0
- package/lib/commonjs/download/adapters/shared.js +13 -0
- package/lib/commonjs/download/index.js +272 -0
- package/lib/commonjs/formatters/date.js +1 -1
- package/lib/commonjs/formatters/index.js +24 -0
- package/lib/commonjs/formatters/phone.js +132 -15
- package/lib/commonjs/geolocation/adapters/expoLocation.js +126 -0
- package/lib/commonjs/geolocation/index.js +339 -0
- package/lib/commonjs/index.js +151 -48
- package/lib/commonjs/initSDK.js +23 -2
- package/lib/commonjs/initUserAuth.js +2 -1
- package/lib/commonjs/logger/index.js +159 -5
- package/lib/commonjs/network/index.js +6 -0
- package/lib/commonjs/network/networkStatus.js +50 -15
- package/lib/commonjs/permissions/index.js +24 -1
- package/lib/commonjs/sqlite/adapters/expo.js +53 -0
- package/lib/commonjs/sqlite/adapters/op.js +43 -0
- package/lib/commonjs/sqlite/adapters/rows.js +33 -0
- package/lib/commonjs/sqlite/adapters/storage.js +50 -0
- package/lib/commonjs/sqlite/adapters/sync.js +45 -0
- package/lib/commonjs/sqlite/index.js +610 -0
- package/lib/commonjs/sqlite/nitro.js +17 -0
- package/lib/commonjs/sqlite/op.js +18 -0
- package/lib/commonjs/sqlite/quick.js +14 -0
- package/lib/commonjs/sqlite/storage.js +14 -0
- package/lib/commonjs/storage/index.js +41 -20
- package/lib/commonjs/types/globals.d.js +6 -0
- package/lib/commonjs/utils/imageCompression.js +51 -14
- package/lib/commonjs/utils/index.js +6 -0
- package/lib/commonjs/versionCheck/index.js +28 -4
- package/lib/module/api/baseUrl.js +30 -0
- package/lib/module/api/curl.js +104 -0
- package/lib/module/api/publicClient.js +11 -20
- package/lib/module/api/retry.js +69 -0
- package/lib/module/api/userClient.js +45 -21
- package/lib/module/auth/authStore.js +99 -32
- package/lib/module/auth/jwt.js +32 -8
- package/lib/module/config/index.js +2 -1
- package/lib/module/deepLink/index.js +280 -0
- package/lib/module/download/adapters/expoFs.js +95 -0
- package/lib/module/download/adapters/shared.js +8 -0
- package/lib/module/download/index.js +264 -0
- package/lib/module/formatters/date.js +1 -1
- package/lib/module/formatters/index.js +1 -1
- package/lib/module/formatters/phone.js +110 -13
- package/lib/module/geolocation/adapters/expoLocation.js +121 -0
- package/lib/module/geolocation/index.js +332 -0
- package/lib/module/index.js +28 -11
- package/lib/module/initSDK.js +23 -2
- package/lib/module/initUserAuth.js +2 -1
- package/lib/module/logger/index.js +156 -4
- package/lib/module/network/index.js +1 -1
- package/lib/module/network/networkStatus.js +47 -14
- package/lib/module/permissions/index.js +22 -0
- package/lib/module/sqlite/adapters/expo.js +48 -0
- package/lib/module/sqlite/adapters/op.js +38 -0
- package/lib/module/sqlite/adapters/rows.js +28 -0
- package/lib/module/sqlite/adapters/storage.js +46 -0
- package/lib/module/sqlite/adapters/sync.js +41 -0
- package/lib/module/sqlite/index.js +600 -0
- package/lib/module/sqlite/nitro.js +12 -0
- package/lib/module/sqlite/op.js +13 -0
- package/lib/module/sqlite/quick.js +9 -0
- package/lib/module/sqlite/storage.js +9 -0
- package/lib/module/storage/index.js +38 -19
- package/lib/module/types/globals.d.js +10 -0
- package/lib/module/utils/imageCompression.js +49 -13
- package/lib/module/utils/index.js +1 -1
- package/lib/module/versionCheck/index.js +27 -4
- package/lib/typescript/commonjs/api/baseUrl.d.ts +20 -0
- package/lib/typescript/commonjs/api/curl.d.ts +18 -0
- package/lib/typescript/commonjs/api/retry.d.ts +27 -0
- package/lib/typescript/commonjs/api/userClient.d.ts +11 -0
- package/lib/typescript/commonjs/auth/authStore.d.ts +29 -6
- package/lib/typescript/commonjs/config/index.d.ts +6 -0
- package/lib/typescript/commonjs/deepLink/index.d.ts +54 -0
- package/lib/typescript/commonjs/download/adapters/expoFs.d.ts +45 -0
- package/lib/typescript/commonjs/download/adapters/shared.d.ts +3 -0
- package/lib/typescript/commonjs/download/index.d.ts +76 -0
- package/lib/typescript/commonjs/formatters/index.d.ts +2 -1
- package/lib/typescript/commonjs/formatters/phone.d.ts +27 -1
- package/lib/typescript/commonjs/geolocation/adapters/expoLocation.d.ts +42 -0
- package/lib/typescript/commonjs/geolocation/index.d.ts +89 -0
- package/lib/typescript/commonjs/index.d.ts +30 -13
- package/lib/typescript/commonjs/initSDK.d.ts +32 -0
- package/lib/typescript/commonjs/logger/index.d.ts +39 -0
- package/lib/typescript/commonjs/network/index.d.ts +2 -2
- package/lib/typescript/commonjs/network/networkStatus.d.ts +16 -0
- package/lib/typescript/commonjs/permissions/index.d.ts +35 -0
- package/lib/typescript/commonjs/sqlite/adapters/expo.d.ts +30 -0
- package/lib/typescript/commonjs/sqlite/adapters/op.d.ts +27 -0
- package/lib/typescript/commonjs/sqlite/adapters/rows.d.ts +7 -0
- package/lib/typescript/commonjs/sqlite/adapters/storage.d.ts +30 -0
- package/lib/typescript/commonjs/sqlite/adapters/sync.d.ts +31 -0
- package/lib/typescript/commonjs/sqlite/index.d.ts +121 -0
- package/lib/typescript/commonjs/sqlite/nitro.d.ts +7 -0
- package/lib/typescript/commonjs/sqlite/op.d.ts +8 -0
- package/lib/typescript/commonjs/sqlite/quick.d.ts +4 -0
- package/lib/typescript/commonjs/sqlite/storage.d.ts +4 -0
- package/lib/typescript/commonjs/storage/index.d.ts +25 -3
- package/lib/typescript/commonjs/utils/imageCompression.d.ts +17 -0
- package/lib/typescript/commonjs/utils/index.d.ts +2 -2
- package/lib/typescript/module/api/baseUrl.d.ts +20 -0
- package/lib/typescript/module/api/curl.d.ts +18 -0
- package/lib/typescript/module/api/retry.d.ts +27 -0
- package/lib/typescript/module/api/userClient.d.ts +11 -0
- package/lib/typescript/module/auth/authStore.d.ts +29 -6
- package/lib/typescript/module/config/index.d.ts +6 -0
- package/lib/typescript/module/deepLink/index.d.ts +54 -0
- package/lib/typescript/module/download/adapters/expoFs.d.ts +45 -0
- package/lib/typescript/module/download/adapters/shared.d.ts +3 -0
- package/lib/typescript/module/download/index.d.ts +76 -0
- package/lib/typescript/module/formatters/index.d.ts +2 -1
- package/lib/typescript/module/formatters/phone.d.ts +27 -1
- package/lib/typescript/module/geolocation/adapters/expoLocation.d.ts +42 -0
- package/lib/typescript/module/geolocation/index.d.ts +89 -0
- package/lib/typescript/module/index.d.ts +30 -13
- package/lib/typescript/module/initSDK.d.ts +32 -0
- package/lib/typescript/module/logger/index.d.ts +39 -0
- package/lib/typescript/module/network/index.d.ts +2 -2
- package/lib/typescript/module/network/networkStatus.d.ts +16 -0
- package/lib/typescript/module/permissions/index.d.ts +35 -0
- package/lib/typescript/module/sqlite/adapters/expo.d.ts +30 -0
- package/lib/typescript/module/sqlite/adapters/op.d.ts +27 -0
- package/lib/typescript/module/sqlite/adapters/rows.d.ts +7 -0
- package/lib/typescript/module/sqlite/adapters/storage.d.ts +30 -0
- package/lib/typescript/module/sqlite/adapters/sync.d.ts +31 -0
- package/lib/typescript/module/sqlite/index.d.ts +121 -0
- package/lib/typescript/module/sqlite/nitro.d.ts +7 -0
- package/lib/typescript/module/sqlite/op.d.ts +8 -0
- package/lib/typescript/module/sqlite/quick.d.ts +4 -0
- package/lib/typescript/module/sqlite/storage.d.ts +4 -0
- package/lib/typescript/module/storage/index.d.ts +25 -3
- package/lib/typescript/module/utils/imageCompression.d.ts +17 -0
- package/lib/typescript/module/utils/index.d.ts +2 -2
- package/package.json +102 -13
|
@@ -6,6 +6,22 @@ interface AsyncStorageLike {
|
|
|
6
6
|
getItem: (key: string) => Promise<string | null>;
|
|
7
7
|
setItem: (key: string, value: string) => Promise<void>;
|
|
8
8
|
removeItem: (key: string) => Promise<void>;
|
|
9
|
+
/**
|
|
10
|
+
* The batch API exists under TWO names, and both are live in this fleet.
|
|
11
|
+
*
|
|
12
|
+
* `@react-native-async-storage/async-storage` 3 renamed the v1 trio and
|
|
13
|
+
* changed their shapes: `getMany` returns a Record where `multiGet` returned
|
|
14
|
+
* pairs, and `setMany` takes a Record where `multiSet` took pairs. The v1
|
|
15
|
+
* names are still what `expo-sqlite/kv-store` and AsyncStorage 2 expose.
|
|
16
|
+
*
|
|
17
|
+
* Declaring only one set is not a compile error and not a runtime error — it
|
|
18
|
+
* silently falls through to the per-key loop below. The fleet pins
|
|
19
|
+
* AsyncStorage 3, so recognising only the v1 names put every consumer on N
|
|
20
|
+
* round-trips per batch with nothing to notice.
|
|
21
|
+
*/
|
|
22
|
+
getMany?: (keys: string[]) => Promise<Record<string, string | null>>;
|
|
23
|
+
setMany?: (entries: Record<string, string>) => Promise<void>;
|
|
24
|
+
removeMany?: (keys: string[]) => Promise<void>;
|
|
9
25
|
multiGet?: (keys: readonly string[]) => Promise<readonly [string, string | null][]>;
|
|
10
26
|
multiSet?: (kvs: readonly [string, string][]) => Promise<void>;
|
|
11
27
|
multiRemove?: (keys: readonly string[]) => Promise<void>;
|
|
@@ -13,8 +29,14 @@ interface AsyncStorageLike {
|
|
|
13
29
|
getAllKeys?: () => Promise<readonly string[]>;
|
|
14
30
|
}
|
|
15
31
|
/**
|
|
16
|
-
*
|
|
17
|
-
*
|
|
32
|
+
* Always true now that the backend ships with the library. Kept because callers
|
|
33
|
+
* whose use of storage is an OPTIMISATION branch on it, and removing it would
|
|
34
|
+
* be a breaking change for no gain.
|
|
35
|
+
*/
|
|
36
|
+
export declare const isStorageAvailable: () => boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Replace the storage backend. Intended for TESTS and for the showcase; an app
|
|
39
|
+
* gets expo-sqlite/kv-store without wiring anything. Pass `null` to restore it.
|
|
18
40
|
*/
|
|
19
41
|
export declare const setStorageImplementation: (impl: AsyncStorageLike | null) => void;
|
|
20
42
|
export interface StorageApi {
|
|
@@ -34,7 +56,7 @@ export interface StorageApi {
|
|
|
34
56
|
* All operations swallow errors (logging them) and return a falsy result
|
|
35
57
|
* so that storage problems never crash the app.
|
|
36
58
|
*
|
|
37
|
-
* Backed by
|
|
59
|
+
* Backed by `expo-sqlite/kv-store` by default;
|
|
38
60
|
* override with `setStorageImplementation()` for MMKV or custom adapters.
|
|
39
61
|
*/
|
|
40
62
|
export declare const Storage: StorageApi;
|
|
@@ -16,6 +16,22 @@ export interface CompressImageOptions {
|
|
|
16
16
|
*/
|
|
17
17
|
fileSize?: number;
|
|
18
18
|
}
|
|
19
|
+
export interface CompressorModule {
|
|
20
|
+
Image: {
|
|
21
|
+
compress: (uri: string, options: {
|
|
22
|
+
maxWidth?: number;
|
|
23
|
+
maxHeight?: number;
|
|
24
|
+
quality?: number;
|
|
25
|
+
compressionMethod?: 'auto' | 'manual';
|
|
26
|
+
output?: 'jpg' | 'png' | 'webp';
|
|
27
|
+
}) => Promise<string>;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Replace the compressor. Intended for TESTS and for the showcase; an app gets
|
|
32
|
+
* expo-image-manipulator without wiring anything. Pass `null` to restore it.
|
|
33
|
+
*/
|
|
34
|
+
export declare const setImageCompressorImplementation: (impl: CompressorModule | null) => void;
|
|
19
35
|
/**
|
|
20
36
|
* Bigger source files get compressed harder — a fixed quality either over-compresses
|
|
21
37
|
* small photos or leaves large ones too heavy to upload quickly. Unknown size falls
|
|
@@ -28,4 +44,5 @@ export declare const qualityForFileSize: (fileSize?: number) => number;
|
|
|
28
44
|
* dependency is missing — so callers can rely on always getting a usable URI.
|
|
29
45
|
*/
|
|
30
46
|
export declare const compressImage: (uri: string, options?: CompressImageOptions) => Promise<string>;
|
|
47
|
+
export type { CompressorModule as ImageCompressorLike };
|
|
31
48
|
//# sourceMappingURL=imageCompression.d.ts.map
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export type { CompressImageOptions } from './imageCompression';
|
|
2
|
-
export { compressImage } from './imageCompression';
|
|
1
|
+
export type { CompressImageOptions, ImageCompressorLike } from './imageCompression';
|
|
2
|
+
export { compressImage, setImageCompressorImplementation } from './imageCompression';
|
|
3
3
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { AxiosInstance } from 'axios';
|
|
2
|
+
/**
|
|
3
|
+
* Resolves `baseURL` PER REQUEST rather than at module evaluation.
|
|
4
|
+
*
|
|
5
|
+
* `axios.create({ baseURL: getConfigValue('baseUrl') })` reads the value once,
|
|
6
|
+
* when the module is first imported — which happens the moment anything touches
|
|
7
|
+
* the package barrel, long before an app's startup code can call `setConfig`.
|
|
8
|
+
* The result was a client permanently pinned to `undefined` and a `setConfig`
|
|
9
|
+
* that appeared to do nothing, with no error anywhere: requests just went to a
|
|
10
|
+
* relative URL.
|
|
11
|
+
*
|
|
12
|
+
* A consumer cannot fix that by ordering its own imports, because the import
|
|
13
|
+
* that loses the race is usually one it never wrote. So the clients stop
|
|
14
|
+
* capturing the value and ask for it per request instead.
|
|
15
|
+
*
|
|
16
|
+
* An explicit per-request `baseURL` still wins, which is what keeps a one-off
|
|
17
|
+
* call to a different host possible.
|
|
18
|
+
*/
|
|
19
|
+
export declare const applyConfiguredBaseUrl: (client: AxiosInstance) => void;
|
|
20
|
+
//# sourceMappingURL=baseUrl.d.ts.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { AxiosRequestConfig } from 'axios';
|
|
2
|
+
/**
|
|
3
|
+
* Builds a copy-pasteable curl command for a request, with every credential
|
|
4
|
+
* replaced by a placeholder.
|
|
5
|
+
*
|
|
6
|
+
* The redaction is the point, not a nicety. An unredacted version of this in a
|
|
7
|
+
* consumer app put `Authorization: Bearer <token>` and the login request's
|
|
8
|
+
* plaintext password into the device console of a *release* staging build.
|
|
9
|
+
* A curl line is worth having; a curl line that has to be trusted not to be
|
|
10
|
+
* enabled in the wrong build is not.
|
|
11
|
+
*/
|
|
12
|
+
export declare const buildCurl: (config: AxiosRequestConfig) => string;
|
|
13
|
+
/**
|
|
14
|
+
* Logs the curl equivalent of a request. Never throws: a failure to describe a
|
|
15
|
+
* request must not be able to fail the request itself.
|
|
16
|
+
*/
|
|
17
|
+
export declare const logCurl: (config: AxiosRequestConfig) => void;
|
|
18
|
+
//# sourceMappingURL=curl.d.ts.map
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { AxiosError, AxiosInstance } from 'axios';
|
|
2
|
+
export interface RetryPolicy {
|
|
3
|
+
retries?: number;
|
|
4
|
+
/** `attempt` is 1-based: 1 is the first retry, not the original request. */
|
|
5
|
+
retryDelayMs?: (attempt: number) => number;
|
|
6
|
+
shouldRetry?: (error: AxiosError) => boolean;
|
|
7
|
+
onRetry?: (attempt: number, error: AxiosError) => void;
|
|
8
|
+
}
|
|
9
|
+
declare module 'axios' {
|
|
10
|
+
interface AxiosRequestConfig {
|
|
11
|
+
/** `false` opts a single request out of retrying; an object overrides the client policy. */
|
|
12
|
+
retry?: boolean | RetryPolicy;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Status-based ONLY, deliberately: a bare network error (no `error.response`)
|
|
17
|
+
* is never retryable. Both clients carry non-idempotent requests, login and OTP
|
|
18
|
+
* on the public one and every write on the user one, and a broken connection
|
|
19
|
+
* says nothing about whether the request reached the server. Retrying can
|
|
20
|
+
* therefore create a second session, or a duplicate record, that the user never
|
|
21
|
+
* sees. A generic network-error retry rule is not a substitute: it decides on
|
|
22
|
+
* the transport alone and never looks at the HTTP method, so it retries POSTs
|
|
23
|
+
* as readily as GETs.
|
|
24
|
+
*/
|
|
25
|
+
export declare const isRetryableStatus: (status: number | undefined) => boolean;
|
|
26
|
+
export declare const attachRetry: (client: AxiosInstance, policy?: RetryPolicy) => void;
|
|
27
|
+
//# sourceMappingURL=retry.d.ts.map
|
|
@@ -45,5 +45,16 @@ export interface RefreshableStore {
|
|
|
45
45
|
declare const userClient: AxiosInstance;
|
|
46
46
|
export declare const injectStore: <S>(_store: S) => void;
|
|
47
47
|
export declare const injectAuthActions: (actions: AuthActions) => void;
|
|
48
|
+
/**
|
|
49
|
+
* Clear any in-flight token refresh and reject everything queued behind it.
|
|
50
|
+
* Call this on logout.
|
|
51
|
+
*
|
|
52
|
+
* Without it, a refresh that was already in flight when the user logged out
|
|
53
|
+
* resolves afterwards and replays every queued request with a token for a
|
|
54
|
+
* session that has ended. The queue is module state, so it survives the logout
|
|
55
|
+
* entirely: nothing else clears it. A consumer app hit this and hand-wrote the
|
|
56
|
+
* same function locally, which is how it was found.
|
|
57
|
+
*/
|
|
58
|
+
export declare const resetRefreshState: () => void;
|
|
48
59
|
export default userClient;
|
|
49
60
|
//# sourceMappingURL=userClient.d.ts.map
|
|
@@ -2,6 +2,15 @@ import type * as KeychainModule from 'react-native-keychain';
|
|
|
2
2
|
/**
|
|
3
3
|
* Token data persisted in the keychain.
|
|
4
4
|
*/
|
|
5
|
+
/**
|
|
6
|
+
* The two keys the library itself reads. Everything in the library that needs
|
|
7
|
+
* the bearer token, the HTTP client, the download module and the authenticated
|
|
8
|
+
* image cache, resolves it through these rather than repeating the literal, so
|
|
9
|
+
* one of them cannot silently drift and start reading a key nothing writes.
|
|
10
|
+
* Apps are free to store their own tokens under any other key.
|
|
11
|
+
*/
|
|
12
|
+
export declare const ACCESS_TOKEN_KEY = "accessToken";
|
|
13
|
+
export declare const REFRESH_TOKEN_KEY = "refreshToken";
|
|
5
14
|
export interface StoredToken {
|
|
6
15
|
token: string;
|
|
7
16
|
expiry: string;
|
|
@@ -11,20 +20,34 @@ export interface StoredToken {
|
|
|
11
20
|
* Lets us avoid a hard import on `react-native-keychain`, so an app that never
|
|
12
21
|
* stores a token does not have to install it.
|
|
13
22
|
*/
|
|
23
|
+
/**
|
|
24
|
+
* The GENERIC password API, not the internet-credentials one.
|
|
25
|
+
*
|
|
26
|
+
* `kSecClassInternetPassword` exists for credentials bound to a server, protocol
|
|
27
|
+
* and port, and it integrates with Safari and AutoFill. A bearer token keyed by
|
|
28
|
+
* a name like "accessToken" is none of those things, and the library was only
|
|
29
|
+
* satisfying that API's required `server` argument by passing the key twice,
|
|
30
|
+
* once as the server and once as the service. That is misuse of the class.
|
|
31
|
+
*
|
|
32
|
+
* `kSecClassGenericPassword` is the class for app-local secrets, which is what a
|
|
33
|
+
* token is. It is what expo-secure-store uses underneath, and what the consumer
|
|
34
|
+
* app being migrated had already chosen for itself.
|
|
35
|
+
*/
|
|
14
36
|
interface KeychainLike {
|
|
15
|
-
|
|
37
|
+
setGenericPassword: (username: string, password: string, options?: {
|
|
16
38
|
service?: string;
|
|
17
39
|
}) => Promise<unknown>;
|
|
18
|
-
|
|
40
|
+
getGenericPassword: (options?: {
|
|
19
41
|
service?: string;
|
|
20
42
|
}) => Promise<KeychainModule.UserCredentials | false>;
|
|
21
|
-
|
|
22
|
-
service
|
|
43
|
+
resetGenericPassword: (options?: {
|
|
44
|
+
service?: string;
|
|
23
45
|
}) => Promise<unknown>;
|
|
24
46
|
}
|
|
25
47
|
/**
|
|
26
|
-
*
|
|
27
|
-
*
|
|
48
|
+
* Replace the secure-store backend. Intended for TESTS and for the showcase,
|
|
49
|
+
* which injects a failing store to demo the write-failure path; it is not how
|
|
50
|
+
* an app configures the library. Pass `null` to restore expo-secure-store.
|
|
28
51
|
*/
|
|
29
52
|
export declare const setKeychainImplementation: (impl: KeychainLike | null) => void;
|
|
30
53
|
/**
|
|
@@ -27,6 +27,12 @@ export interface Config {
|
|
|
27
27
|
appId: string | null;
|
|
28
28
|
/** The app's user-visible version string, e.g. `'1.4.2'`. Same rationale as `appId`. */
|
|
29
29
|
appVersion: string | null;
|
|
30
|
+
/**
|
|
31
|
+
* Log a copy-pasteable curl command for every API request. Credentials are
|
|
32
|
+
* redacted either way, but this is still request-level noise, so it stays off
|
|
33
|
+
* unless an app asks for it while debugging.
|
|
34
|
+
*/
|
|
35
|
+
logCurl: boolean;
|
|
30
36
|
}
|
|
31
37
|
/**
|
|
32
38
|
* Set global configuration for all Webority packages
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
export interface ParsedLink {
|
|
2
|
+
/** The original URL, trimmed. */
|
|
3
|
+
url: string;
|
|
4
|
+
/** Lower-cased scheme without `://`, or '' when the URL carried none. */
|
|
5
|
+
scheme: string;
|
|
6
|
+
/**
|
|
7
|
+
* The authority for http(s) URLs. Custom schemes put the first route segment
|
|
8
|
+
* there (`myapp://order/12`), so for those `host` is `segments[0]` and stays
|
|
9
|
+
* part of `path` so one route pattern matches both link shapes.
|
|
10
|
+
*/
|
|
11
|
+
host: string;
|
|
12
|
+
/** Route path with no leading or trailing slash. */
|
|
13
|
+
path: string;
|
|
14
|
+
segments: string[];
|
|
15
|
+
/** Query values, decoded. A repeated key keeps its last occurrence. */
|
|
16
|
+
query: Record<string, string>;
|
|
17
|
+
}
|
|
18
|
+
export interface DeepLinkRoute {
|
|
19
|
+
/** A path pattern with `:param` segments (`order/:id`), or a RegExp on `path`. */
|
|
20
|
+
match: string | RegExp;
|
|
21
|
+
requiresAuth?: boolean;
|
|
22
|
+
handler: (link: ParsedLink, params: Record<string, string>) => void;
|
|
23
|
+
}
|
|
24
|
+
export interface DeepLinkConfig {
|
|
25
|
+
routes: DeepLinkRoute[];
|
|
26
|
+
/** Navigator readiness. Links arriving before this is true are queued. */
|
|
27
|
+
isReady?: () => boolean;
|
|
28
|
+
isAuthenticated?: () => boolean;
|
|
29
|
+
/** Called when an auth-gated link is stashed; the app sends the user to login. */
|
|
30
|
+
onUnauthenticated?: (link: ParsedLink) => void;
|
|
31
|
+
onUnmatched?: (link: ParsedLink) => void;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Parse a deep-link URL. Returns null for anything that is not a usable URL so
|
|
35
|
+
* a hostile or truncated link can never throw on the native event path.
|
|
36
|
+
*/
|
|
37
|
+
export declare const parseDeepLink: (url: string) => ParsedLink | null;
|
|
38
|
+
export declare const DeepLink: {
|
|
39
|
+
configure: (next: DeepLinkConfig) => void;
|
|
40
|
+
start: () => Promise<void>;
|
|
41
|
+
stop: () => void;
|
|
42
|
+
handleUrl: (url: string) => void;
|
|
43
|
+
setReady: (ready: boolean) => void;
|
|
44
|
+
/** Replay the stashed link, once. Call after a successful login. */
|
|
45
|
+
replayPending: () => void;
|
|
46
|
+
getPending: () => ParsedLink | null;
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Configure and start the deep-link service for the lifetime of a component.
|
|
50
|
+
* The stored config delegates to the latest render, so new route closures do
|
|
51
|
+
* not tear down and re-subscribe the native listener.
|
|
52
|
+
*/
|
|
53
|
+
export declare const useDeepLink: (deepLinkConfig: DeepLinkConfig) => void;
|
|
54
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { FileSystemLike } from '../index.js';
|
|
2
|
+
/**
|
|
3
|
+
* expo-file-system. Shape verified against 57.0.6, where the legacy function
|
|
4
|
+
* API (`downloadAsync`, `getInfoAsync`) still exists on the main entry point
|
|
5
|
+
* but every one of those functions THROWS at runtime; they now live behind
|
|
6
|
+
* `expo-file-system/legacy`. This adapter therefore uses the class API only.
|
|
7
|
+
*
|
|
8
|
+
* The REQUIRE lives in the entry point beside this file, never here.
|
|
9
|
+
*/
|
|
10
|
+
interface ExpoFileLike {
|
|
11
|
+
readonly uri: string;
|
|
12
|
+
readonly exists: boolean;
|
|
13
|
+
readonly size: number;
|
|
14
|
+
delete: () => void;
|
|
15
|
+
}
|
|
16
|
+
interface ExpoDirectoryLike {
|
|
17
|
+
readonly uri: string;
|
|
18
|
+
create: (options?: {
|
|
19
|
+
intermediates?: boolean;
|
|
20
|
+
idempotent?: boolean;
|
|
21
|
+
}) => void;
|
|
22
|
+
}
|
|
23
|
+
interface ExpoDownloadTaskLike {
|
|
24
|
+
downloadAsync: () => Promise<ExpoFileLike | null>;
|
|
25
|
+
cancel: () => void;
|
|
26
|
+
}
|
|
27
|
+
export interface ExpoFileSystemModuleLike {
|
|
28
|
+
File: (new (uri: string) => ExpoFileLike) & {
|
|
29
|
+
createDownloadTask: (url: string, destination: ExpoFileLike, options?: {
|
|
30
|
+
headers?: Record<string, string>;
|
|
31
|
+
onProgress?: (progress: {
|
|
32
|
+
bytesWritten: number;
|
|
33
|
+
totalBytes: number;
|
|
34
|
+
}) => void;
|
|
35
|
+
}) => ExpoDownloadTaskLike;
|
|
36
|
+
};
|
|
37
|
+
Directory: new (uri: string) => ExpoDirectoryLike;
|
|
38
|
+
Paths: {
|
|
39
|
+
document: ExpoDirectoryLike;
|
|
40
|
+
cache: ExpoDirectoryLike;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
export declare const adaptExpoFileSystem: (mod: unknown) => FileSystemLike | null;
|
|
44
|
+
export {};
|
|
45
|
+
//# sourceMappingURL=expoFs.d.ts.map
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
export interface FileSystemDirs {
|
|
2
|
+
documents: string;
|
|
3
|
+
cache: string;
|
|
4
|
+
downloads: string;
|
|
5
|
+
}
|
|
6
|
+
export interface FileSystemDownloadRequest {
|
|
7
|
+
url: string;
|
|
8
|
+
path: string;
|
|
9
|
+
headers: Record<string, string>;
|
|
10
|
+
onProgress?: (received: number, total: number) => void;
|
|
11
|
+
}
|
|
12
|
+
export interface FileSystemDownloadHandle {
|
|
13
|
+
promise: Promise<{
|
|
14
|
+
status?: number;
|
|
15
|
+
bytes?: number;
|
|
16
|
+
}>;
|
|
17
|
+
cancel?: () => void;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* The slice of a native filesystem module this module actually uses. Both
|
|
21
|
+
* `react-native-blob-util` and `react-native-fs` are adapted onto it, and an app
|
|
22
|
+
* can inject its own with `setFileSystemImplementation`.
|
|
23
|
+
*/
|
|
24
|
+
export interface FileSystemLike {
|
|
25
|
+
dirs: FileSystemDirs;
|
|
26
|
+
download: (request: FileSystemDownloadRequest) => FileSystemDownloadHandle;
|
|
27
|
+
exists: (path: string) => Promise<boolean>;
|
|
28
|
+
stat: (path: string) => Promise<{
|
|
29
|
+
size: number;
|
|
30
|
+
}>;
|
|
31
|
+
unlink: (path: string) => Promise<void>;
|
|
32
|
+
mkdir: (path: string) => Promise<void>;
|
|
33
|
+
}
|
|
34
|
+
export type DownloadDestination = 'documents' | 'cache' | 'downloads';
|
|
35
|
+
export interface DownloadOptions {
|
|
36
|
+
url: string;
|
|
37
|
+
fileName?: string;
|
|
38
|
+
destination?: DownloadDestination;
|
|
39
|
+
headers?: Record<string, string>;
|
|
40
|
+
authenticated?: boolean;
|
|
41
|
+
mimeType?: string;
|
|
42
|
+
onProgress?: (received: number, total: number, fraction: number) => void;
|
|
43
|
+
overwrite?: boolean;
|
|
44
|
+
signal?: AbortSignal;
|
|
45
|
+
}
|
|
46
|
+
export interface DownloadResult {
|
|
47
|
+
path: string;
|
|
48
|
+
bytes: number;
|
|
49
|
+
mimeType?: string;
|
|
50
|
+
fromCache: boolean;
|
|
51
|
+
}
|
|
52
|
+
export type DownloadErrorCode = 'unsupported' | 'permission-denied' | 'network' | 'http-error' | 'write-failed' | 'aborted' | 'empty-file';
|
|
53
|
+
export declare class DownloadError extends Error {
|
|
54
|
+
readonly code: DownloadErrorCode;
|
|
55
|
+
readonly status?: number;
|
|
56
|
+
constructor(code: DownloadErrorCode, message: string, status?: number);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Replace the filesystem backend. Intended for TESTS and for the showcase,
|
|
60
|
+
* which injects a denying backend to demo the permission error; an app gets
|
|
61
|
+
* expo-file-system without wiring anything. Pass `null` to restore it.
|
|
62
|
+
*/
|
|
63
|
+
export declare const setFileSystemImplementation: (impl: FileSystemLike | null) => void;
|
|
64
|
+
/**
|
|
65
|
+
* Download a file to the device, attaching the stored bearer token by default.
|
|
66
|
+
*
|
|
67
|
+
* A finished download is always verified to be non-empty: a 0-byte file looks
|
|
68
|
+
* like a success to every caller and then wedges whatever consumes it, so it is
|
|
69
|
+
* deleted and reported as `empty-file`.
|
|
70
|
+
*/
|
|
71
|
+
export declare const downloadFile: (options: DownloadOptions) => Promise<DownloadResult>;
|
|
72
|
+
/**
|
|
73
|
+
* Hand a downloaded file to the OS, to open in whichever app claims it.
|
|
74
|
+
*/
|
|
75
|
+
export declare const openFile: (path: string, mimeType?: string) => Promise<void>;
|
|
76
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -4,5 +4,6 @@ export type { DateInput, DateStyle, TimeStyle } from './date.js';
|
|
|
4
4
|
export { formatDate, formatDateTime, formatRelativeTime, formatTime } from './date.js';
|
|
5
5
|
export { getInitials } from './initials.js';
|
|
6
6
|
export { formatCompactNumber, formatNumber, formatPercent } from './number.js';
|
|
7
|
-
export {
|
|
7
|
+
export type { FormatPhoneOptions, PhoneCountry, PhoneNumber } from './phone.js';
|
|
8
|
+
export { detectPhoneCountry, formatPhone, isValidPhoneNumber, normalizePhone, parsePhoneNumber, parsePhoneNumberFromString } from './phone.js';
|
|
8
9
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1,13 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Real cross-country validation, re-exported rather than reimplemented.
|
|
3
|
+
* formatPhone/normalizePhone/detectPhoneCountry below are a fast, dependency-
|
|
4
|
+
* light DISPLAY formatter for a fixed set of countries; they are not a
|
|
5
|
+
* validator. Real phone number plans have country-specific area-code and
|
|
6
|
+
* mobile-prefix rules that only a maintained metadata table gets right -
|
|
7
|
+
* hand-rolling that risks silently-wrong validation for a country nobody
|
|
8
|
+
* tests against. Both live here so consumers get one phone module, not two.
|
|
9
|
+
*/
|
|
10
|
+
export type { PhoneNumber } from 'libphonenumber-js';
|
|
11
|
+
export { isValidPhoneNumber, parsePhoneNumber, parsePhoneNumberFromString } from 'libphonenumber-js';
|
|
12
|
+
export type PhoneCountry = 'IN' | 'US' | 'GB' | 'AE' | 'AU' | 'SG' | 'CA';
|
|
13
|
+
export interface FormatPhoneOptions {
|
|
14
|
+
defaultCountryCode?: string;
|
|
15
|
+
country?: PhoneCountry;
|
|
16
|
+
includeCountryCode?: boolean;
|
|
17
|
+
}
|
|
1
18
|
/**
|
|
2
19
|
* Strip everything except digits and a leading `+` (preserved if present).
|
|
3
20
|
*/
|
|
4
21
|
export declare const normalizePhone: (input: string) => string;
|
|
22
|
+
/**
|
|
23
|
+
* Detect the country of a phone number: from its own `+` country code when
|
|
24
|
+
* present, otherwise from `defaultCountryCode`. Returns null when neither
|
|
25
|
+
* carries a recognised calling code.
|
|
26
|
+
*/
|
|
27
|
+
export declare const detectPhoneCountry: (input: string, defaultCountryCode?: string) => PhoneCountry | null;
|
|
5
28
|
/**
|
|
6
29
|
* Format a phone number for human display.
|
|
7
30
|
*
|
|
8
31
|
* - Indian mobile (10 digits) → `XXXXX XXXXX`
|
|
9
32
|
* - With `+91` country code → `+91 XXXXX XXXXX`
|
|
33
|
+
* - A number that already carries a recognised country code is grouped for
|
|
34
|
+
* that country regardless of `defaultCountryCode`.
|
|
10
35
|
* - Other inputs are returned as `+CC NNNN NNNN…` best-effort grouping.
|
|
11
36
|
*/
|
|
12
|
-
export declare
|
|
37
|
+
export declare function formatPhone(input: string, defaultCountryCode?: string): string;
|
|
38
|
+
export declare function formatPhone(input: string, options?: FormatPhoneOptions): string;
|
|
13
39
|
//# sourceMappingURL=phone.d.ts.map
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { GeolocationLike } from '../index.js';
|
|
2
|
+
/**
|
|
3
|
+
* The slice of expo-location this adapter uses. Verified against 57.0.14.
|
|
4
|
+
*
|
|
5
|
+
* The REQUIRE lives in the entry point beside this file, never here.
|
|
6
|
+
*/
|
|
7
|
+
export interface ExpoLocationObject {
|
|
8
|
+
coords?: {
|
|
9
|
+
latitude?: number;
|
|
10
|
+
longitude?: number;
|
|
11
|
+
altitude?: number | null;
|
|
12
|
+
accuracy?: number | null;
|
|
13
|
+
heading?: number | null;
|
|
14
|
+
speed?: number | null;
|
|
15
|
+
} | null;
|
|
16
|
+
timestamp?: number;
|
|
17
|
+
}
|
|
18
|
+
export interface ExpoLocationSubscription {
|
|
19
|
+
remove: () => void;
|
|
20
|
+
}
|
|
21
|
+
export interface ExpoLocationLike {
|
|
22
|
+
getCurrentPositionAsync: (options?: Record<string, unknown>) => Promise<ExpoLocationObject>;
|
|
23
|
+
watchPositionAsync: (options: Record<string, unknown>, callback: (location: ExpoLocationObject) => void) => Promise<ExpoLocationSubscription>;
|
|
24
|
+
getForegroundPermissionsAsync?: () => Promise<{
|
|
25
|
+
granted: boolean;
|
|
26
|
+
}>;
|
|
27
|
+
hasServicesEnabledAsync?: () => Promise<boolean>;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Adapts expo-location to the library's geolocation seam.
|
|
31
|
+
*
|
|
32
|
+
* The interesting half is `watchPosition`. The seam must hand back a numeric
|
|
33
|
+
* watch id SYNCHRONOUSLY, while `watchPositionAsync` only resolves its
|
|
34
|
+
* subscription later. So the adapter mints its own id immediately and stores
|
|
35
|
+
* the subscription against it on arrival. `clearWatch` called during that
|
|
36
|
+
* window records the id as cancelled, and the subscription is removed the
|
|
37
|
+
* moment it lands — without that, a screen that unmounts before the watch
|
|
38
|
+
* starts leaks a live GPS listener for the rest of the session, which is a
|
|
39
|
+
* battery drain nobody would attribute to this code.
|
|
40
|
+
*/
|
|
41
|
+
export declare const adaptExpoLocation: (mod: ExpoLocationLike) => GeolocationLike;
|
|
42
|
+
//# sourceMappingURL=expoLocation.d.ts.map
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
export interface GeoCoordinates {
|
|
2
|
+
latitude: number;
|
|
3
|
+
longitude: number;
|
|
4
|
+
accuracy: number;
|
|
5
|
+
altitude: number | null;
|
|
6
|
+
heading: number | null;
|
|
7
|
+
speed: number | null;
|
|
8
|
+
}
|
|
9
|
+
export interface GeoPosition {
|
|
10
|
+
coords: GeoCoordinates;
|
|
11
|
+
timestamp: number;
|
|
12
|
+
}
|
|
13
|
+
export type GeoErrorCode = 'permission-denied' | 'position-unavailable' | 'timeout' | 'services-disabled' | 'unsupported';
|
|
14
|
+
export declare class GeolocationError extends Error {
|
|
15
|
+
readonly code: GeoErrorCode;
|
|
16
|
+
constructor(code: GeoErrorCode, message: string);
|
|
17
|
+
}
|
|
18
|
+
export interface GeoOptions {
|
|
19
|
+
/** `fine` maps to the platform's high-accuracy (GPS) provider. Default `fine`. */
|
|
20
|
+
accuracy?: 'fine' | 'coarse';
|
|
21
|
+
timeoutMs?: number;
|
|
22
|
+
maximumAgeMs?: number;
|
|
23
|
+
/** Extra attempts after the first, used only for `timeout` / `position-unavailable`. */
|
|
24
|
+
retries?: number;
|
|
25
|
+
/** A fix with a worse (larger) accuracy radius counts as `position-unavailable`. */
|
|
26
|
+
minimumAccuracyM?: number;
|
|
27
|
+
/**
|
|
28
|
+
* Pause between retries. Android's fused provider is frequently not ready on
|
|
29
|
+
* the first request after the permission grant or after location is switched
|
|
30
|
+
* on, and retrying immediately just re-collects the same failure.
|
|
31
|
+
*/
|
|
32
|
+
retryDelayMs?: number;
|
|
33
|
+
}
|
|
34
|
+
export interface GeoWatchOptions extends GeoOptions {
|
|
35
|
+
/** Metres the device must move before the listener fires again. */
|
|
36
|
+
distanceFilterM?: number;
|
|
37
|
+
onError?: (error: GeolocationError) => void;
|
|
38
|
+
}
|
|
39
|
+
interface NativeGeoCoords {
|
|
40
|
+
latitude?: number | null;
|
|
41
|
+
longitude?: number | null;
|
|
42
|
+
accuracy?: number | null;
|
|
43
|
+
altitude?: number | null;
|
|
44
|
+
heading?: number | null;
|
|
45
|
+
speed?: number | null;
|
|
46
|
+
}
|
|
47
|
+
interface NativeGeoPosition {
|
|
48
|
+
coords?: NativeGeoCoords | null;
|
|
49
|
+
timestamp?: number | null;
|
|
50
|
+
}
|
|
51
|
+
interface NativeGeoError {
|
|
52
|
+
code?: number;
|
|
53
|
+
message?: string;
|
|
54
|
+
}
|
|
55
|
+
interface NativeGeoOptions {
|
|
56
|
+
enableHighAccuracy?: boolean;
|
|
57
|
+
timeout?: number;
|
|
58
|
+
maximumAge?: number;
|
|
59
|
+
distanceFilter?: number;
|
|
60
|
+
}
|
|
61
|
+
/** Minimal shape of the native geolocation module we depend on. */
|
|
62
|
+
export interface GeolocationLike {
|
|
63
|
+
getCurrentPosition: (onSuccess: (position: NativeGeoPosition) => void, onError?: (error: NativeGeoError) => void, options?: NativeGeoOptions) => void;
|
|
64
|
+
watchPosition: (onSuccess: (position: NativeGeoPosition) => void, onError?: (error: NativeGeoError) => void, options?: NativeGeoOptions) => number;
|
|
65
|
+
clearWatch: (watchId: number) => void;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Replace the geolocation provider. Intended for TESTS and for the showcase,
|
|
69
|
+
* which injects a denying provider to demo the permission and services-off
|
|
70
|
+
* errors; an app gets expo-location without wiring anything. Pass `null` to
|
|
71
|
+
* restore it.
|
|
72
|
+
*/
|
|
73
|
+
export declare const setGeolocationImplementation: (impl: GeolocationLike | null) => void;
|
|
74
|
+
export declare const Geolocation: {
|
|
75
|
+
getCurrentPosition: (options?: GeoOptions) => Promise<GeoPosition>;
|
|
76
|
+
watchPosition: (listener: (position: GeoPosition) => void, options?: GeoWatchOptions) => (() => void);
|
|
77
|
+
isAvailable: () => boolean;
|
|
78
|
+
};
|
|
79
|
+
export interface UseCurrentPositionResult {
|
|
80
|
+
position: GeoPosition | null;
|
|
81
|
+
error: GeolocationError | null;
|
|
82
|
+
loading: boolean;
|
|
83
|
+
refresh: () => void;
|
|
84
|
+
}
|
|
85
|
+
export declare const useCurrentPosition: (options?: GeoOptions & {
|
|
86
|
+
enabled?: boolean;
|
|
87
|
+
}) => UseCurrentPositionResult;
|
|
88
|
+
export {};
|
|
89
|
+
//# sourceMappingURL=index.d.ts.map
|