@reatomized/convex 0.0.0-stage → 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.
- package/LICENSE +202 -0
- package/README.md +110 -2
- package/dist/browser/logging.d.ts +39 -0
- package/dist/browser/logging.js +117 -0
- package/dist/browser/reatom/auth.d.ts +75 -0
- package/dist/browser/reatom/auth.js +329 -0
- package/dist/browser/reatom/client.d.ts +348 -0
- package/dist/browser/reatom/client.js +1138 -0
- package/dist/browser/reatom/connection_hooks.d.ts +11 -0
- package/dist/browser/reatom/connection_hooks.js +15 -0
- package/dist/browser/reatom/errors.d.ts +3 -0
- package/dist/browser/reatom/errors.js +8 -0
- package/dist/browser/reatom/index.d.ts +6 -0
- package/dist/browser/reatom/index.js +2 -0
- package/dist/browser/reatom/optimistic.d.ts +44 -0
- package/dist/browser/reatom/optimistic.js +70 -0
- package/dist/browser/reatom/paginated.d.ts +56 -0
- package/dist/browser/reatom/paginated.js +162 -0
- package/dist/browser/reatom/socket.d.ts +52 -0
- package/dist/browser/reatom/socket.js +523 -0
- package/dist/browser/sync/function_result.d.ts +21 -0
- package/dist/browser/sync/function_result.js +1 -0
- package/dist/browser/sync/metrics.d.ts +9 -0
- package/dist/browser/sync/metrics.js +43 -0
- package/dist/browser/sync/pagination.d.ts +22 -0
- package/dist/browser/sync/pagination.js +20 -0
- package/dist/browser/sync/protocol.d.ts +206 -0
- package/dist/browser/sync/protocol.js +75 -0
- package/dist/browser/sync/session.d.ts +1 -0
- package/dist/browser/sync/session.js +10 -0
- package/dist/browser/sync/udf_path_utils.d.ts +30 -0
- package/dist/browser/sync/udf_path_utils.js +38 -0
- package/dist/common/index.d.ts +11 -0
- package/dist/common/index.js +52 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/vendor/jwt-decode/LICENSE +21 -0
- package/dist/vendor/jwt-decode/index.d.ts +23 -0
- package/dist/vendor/jwt-decode/index.js +57 -0
- package/dist/vendor/long.d.ts +16 -0
- package/dist/vendor/long.js +297 -0
- package/package.json +59 -4
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import type { UserIdentityAttributes } from "convex/server";
|
|
2
|
+
export type { UserIdentityAttributes } from "convex/server";
|
|
3
|
+
import { JSONValue } from "convex/values";
|
|
4
|
+
import { Long } from "../../vendor/long.js";
|
|
5
|
+
/**
|
|
6
|
+
* Shared schema
|
|
7
|
+
*/
|
|
8
|
+
export declare function u64ToLong(encoded: EncodedU64): U64;
|
|
9
|
+
export declare function longToU64(raw: U64): EncodedU64;
|
|
10
|
+
export declare function parseServerMessage(encoded: EncodedServerMessage): WireServerMessage;
|
|
11
|
+
export declare function encodeClientMessage(message: ClientMessage): EncodedClientMessage;
|
|
12
|
+
type U64 = Long;
|
|
13
|
+
type EncodedU64 = string;
|
|
14
|
+
/**
|
|
15
|
+
* Unique nonnegative integer identifying a single query.
|
|
16
|
+
*/
|
|
17
|
+
export type QueryId = number;
|
|
18
|
+
export type QuerySetVersion = number;
|
|
19
|
+
export type RequestId = number;
|
|
20
|
+
export type IdentityVersion = number;
|
|
21
|
+
/**
|
|
22
|
+
* A serialized representation of decisions made during a query's execution.
|
|
23
|
+
*
|
|
24
|
+
* A journal is produced when a query function first executes and is re-used
|
|
25
|
+
* when a query is re-executed.
|
|
26
|
+
*
|
|
27
|
+
* Currently this is used to store pagination end cursors to ensure
|
|
28
|
+
* that pages of paginated queries will always end at the same cursor. This
|
|
29
|
+
* enables gapless, reactive pagination.
|
|
30
|
+
*
|
|
31
|
+
* `null` is used to represent empty journals.
|
|
32
|
+
* @public
|
|
33
|
+
*/
|
|
34
|
+
export type QueryJournal = string | null;
|
|
35
|
+
/**
|
|
36
|
+
* Client message schema
|
|
37
|
+
*/
|
|
38
|
+
type Connect = {
|
|
39
|
+
type: "Connect";
|
|
40
|
+
sessionId: string;
|
|
41
|
+
connectionCount: number;
|
|
42
|
+
lastCloseReason: string | null;
|
|
43
|
+
maxObservedTimestamp?: TS | undefined;
|
|
44
|
+
clientTs: number;
|
|
45
|
+
};
|
|
46
|
+
export type AddQuery = {
|
|
47
|
+
type: "Add";
|
|
48
|
+
queryId: QueryId;
|
|
49
|
+
udfPath: string;
|
|
50
|
+
args: JSONValue[];
|
|
51
|
+
journal?: QueryJournal | undefined;
|
|
52
|
+
};
|
|
53
|
+
export type RemoveQuery = {
|
|
54
|
+
type: "Remove";
|
|
55
|
+
queryId: QueryId;
|
|
56
|
+
};
|
|
57
|
+
export type QuerySetModification = {
|
|
58
|
+
type: "ModifyQuerySet";
|
|
59
|
+
baseVersion: QuerySetVersion;
|
|
60
|
+
newVersion: QuerySetVersion;
|
|
61
|
+
modifications: (AddQuery | RemoveQuery)[];
|
|
62
|
+
};
|
|
63
|
+
export type MutationRequest = {
|
|
64
|
+
type: "Mutation";
|
|
65
|
+
requestId: RequestId;
|
|
66
|
+
udfPath: string;
|
|
67
|
+
args: JSONValue[];
|
|
68
|
+
componentPath?: string | undefined;
|
|
69
|
+
};
|
|
70
|
+
export type ActionRequest = {
|
|
71
|
+
type: "Action";
|
|
72
|
+
requestId: RequestId;
|
|
73
|
+
udfPath: string;
|
|
74
|
+
args: JSONValue[];
|
|
75
|
+
componentPath?: string | undefined;
|
|
76
|
+
};
|
|
77
|
+
export type AdminAuthentication = {
|
|
78
|
+
type: "Authenticate";
|
|
79
|
+
tokenType: "Admin";
|
|
80
|
+
value: string;
|
|
81
|
+
baseVersion: IdentityVersion;
|
|
82
|
+
impersonating?: UserIdentityAttributes | undefined;
|
|
83
|
+
};
|
|
84
|
+
export type Authenticate = AdminAuthentication | {
|
|
85
|
+
type: "Authenticate";
|
|
86
|
+
tokenType: "User";
|
|
87
|
+
value: string;
|
|
88
|
+
baseVersion: IdentityVersion;
|
|
89
|
+
} | {
|
|
90
|
+
type: "Authenticate";
|
|
91
|
+
tokenType: "None";
|
|
92
|
+
baseVersion: IdentityVersion;
|
|
93
|
+
};
|
|
94
|
+
export type Event = {
|
|
95
|
+
type: "Event";
|
|
96
|
+
eventType: string;
|
|
97
|
+
event: any;
|
|
98
|
+
};
|
|
99
|
+
export type ClientMessage = Connect | Authenticate | QuerySetModification | MutationRequest | ActionRequest | Event;
|
|
100
|
+
type EncodedConnect = Omit<Connect, "maxObservedTimestamp"> & {
|
|
101
|
+
maxObservedTimestamp?: EncodedTS | undefined;
|
|
102
|
+
};
|
|
103
|
+
type EncodedClientMessage = EncodedConnect | Authenticate | QuerySetModification | MutationRequest | ActionRequest | Event;
|
|
104
|
+
/**
|
|
105
|
+
* Server message schema
|
|
106
|
+
*/
|
|
107
|
+
export type TS = U64;
|
|
108
|
+
type EncodedTS = EncodedU64;
|
|
109
|
+
type LogLines = string[];
|
|
110
|
+
export type StateVersion = {
|
|
111
|
+
querySet: QuerySetVersion;
|
|
112
|
+
ts: TS;
|
|
113
|
+
identity: IdentityVersion;
|
|
114
|
+
};
|
|
115
|
+
type EncodedStateVersion = Omit<StateVersion, "ts"> & {
|
|
116
|
+
ts: EncodedTS;
|
|
117
|
+
};
|
|
118
|
+
type StateModification = {
|
|
119
|
+
type: "QueryUpdated";
|
|
120
|
+
queryId: QueryId;
|
|
121
|
+
value: JSONValue;
|
|
122
|
+
logLines: LogLines;
|
|
123
|
+
journal: QueryJournal;
|
|
124
|
+
} | {
|
|
125
|
+
type: "QueryFailed";
|
|
126
|
+
queryId: QueryId;
|
|
127
|
+
errorMessage: string;
|
|
128
|
+
logLines: LogLines;
|
|
129
|
+
errorData: JSONValue;
|
|
130
|
+
journal: QueryJournal;
|
|
131
|
+
} | {
|
|
132
|
+
type: "QueryRemoved";
|
|
133
|
+
queryId: QueryId;
|
|
134
|
+
};
|
|
135
|
+
export type Transition = {
|
|
136
|
+
type: "Transition";
|
|
137
|
+
startVersion: StateVersion;
|
|
138
|
+
endVersion: StateVersion;
|
|
139
|
+
modifications: StateModification[];
|
|
140
|
+
clientClockSkew?: number;
|
|
141
|
+
serverTs?: number;
|
|
142
|
+
};
|
|
143
|
+
export type TransitionChunk = {
|
|
144
|
+
type: "TransitionChunk";
|
|
145
|
+
chunk: string;
|
|
146
|
+
partNumber: number;
|
|
147
|
+
totalParts: number;
|
|
148
|
+
transitionId: string;
|
|
149
|
+
};
|
|
150
|
+
type MutationSuccess = {
|
|
151
|
+
type: "MutationResponse";
|
|
152
|
+
requestId: RequestId;
|
|
153
|
+
success: true;
|
|
154
|
+
result: JSONValue;
|
|
155
|
+
ts: TS;
|
|
156
|
+
logLines: LogLines;
|
|
157
|
+
};
|
|
158
|
+
type MutationFailed = {
|
|
159
|
+
type: "MutationResponse";
|
|
160
|
+
requestId: RequestId;
|
|
161
|
+
success: false;
|
|
162
|
+
result: string;
|
|
163
|
+
logLines: LogLines;
|
|
164
|
+
errorData?: JSONValue;
|
|
165
|
+
};
|
|
166
|
+
export type MutationResponse = MutationSuccess | MutationFailed;
|
|
167
|
+
type ActionSuccess = {
|
|
168
|
+
type: "ActionResponse";
|
|
169
|
+
requestId: RequestId;
|
|
170
|
+
success: true;
|
|
171
|
+
result: JSONValue;
|
|
172
|
+
logLines: LogLines;
|
|
173
|
+
};
|
|
174
|
+
type ActionFailed = {
|
|
175
|
+
type: "ActionResponse";
|
|
176
|
+
requestId: RequestId;
|
|
177
|
+
success: false;
|
|
178
|
+
result: string;
|
|
179
|
+
logLines: LogLines;
|
|
180
|
+
errorData?: JSONValue;
|
|
181
|
+
};
|
|
182
|
+
export type ActionResponse = ActionSuccess | ActionFailed;
|
|
183
|
+
export type AuthError = {
|
|
184
|
+
type: "AuthError";
|
|
185
|
+
error: string;
|
|
186
|
+
baseVersion: IdentityVersion;
|
|
187
|
+
authUpdateAttempted: boolean;
|
|
188
|
+
};
|
|
189
|
+
type FatalError = {
|
|
190
|
+
type: "FatalError";
|
|
191
|
+
error: string;
|
|
192
|
+
};
|
|
193
|
+
type Ping = {
|
|
194
|
+
type: "Ping";
|
|
195
|
+
};
|
|
196
|
+
export type ServerMessage = Transition | MutationResponse | ActionResponse | FatalError | AuthError;
|
|
197
|
+
export type WireServerMessage = Transition | TransitionChunk | MutationResponse | ActionResponse | FatalError | AuthError | Ping;
|
|
198
|
+
type EncodedTransition = Omit<Transition, "startVersion" | "endVersion"> & {
|
|
199
|
+
startVersion: EncodedStateVersion;
|
|
200
|
+
endVersion: EncodedStateVersion;
|
|
201
|
+
};
|
|
202
|
+
type EncodedMutationSuccess = Omit<MutationSuccess, "ts"> & {
|
|
203
|
+
ts: EncodedTS;
|
|
204
|
+
};
|
|
205
|
+
type EncodedMutationResponse = MutationFailed | EncodedMutationSuccess;
|
|
206
|
+
type EncodedServerMessage = EncodedTransition | TransitionChunk | EncodedMutationResponse | ActionResponse | FatalError | AuthError | Ping;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { Base64 } from "convex/values";
|
|
2
|
+
import { Long } from "../../vendor/long.js";
|
|
3
|
+
/**
|
|
4
|
+
* Shared schema
|
|
5
|
+
*/
|
|
6
|
+
export function u64ToLong(encoded) {
|
|
7
|
+
const integerBytes = Base64.toByteArray(encoded);
|
|
8
|
+
return Long.fromBytesLE(Array.from(integerBytes));
|
|
9
|
+
}
|
|
10
|
+
export function longToU64(raw) {
|
|
11
|
+
const integerBytes = new Uint8Array(raw.toBytesLE());
|
|
12
|
+
return Base64.fromByteArray(integerBytes);
|
|
13
|
+
}
|
|
14
|
+
export function parseServerMessage(encoded) {
|
|
15
|
+
switch (encoded.type) {
|
|
16
|
+
case "FatalError":
|
|
17
|
+
case "AuthError":
|
|
18
|
+
case "ActionResponse":
|
|
19
|
+
case "TransitionChunk":
|
|
20
|
+
case "Ping": {
|
|
21
|
+
return { ...encoded };
|
|
22
|
+
}
|
|
23
|
+
case "MutationResponse": {
|
|
24
|
+
if (encoded.success) {
|
|
25
|
+
return { ...encoded, ts: u64ToLong(encoded.ts) };
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
return { ...encoded };
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
case "Transition": {
|
|
32
|
+
return {
|
|
33
|
+
...encoded,
|
|
34
|
+
startVersion: {
|
|
35
|
+
...encoded.startVersion,
|
|
36
|
+
ts: u64ToLong(encoded.startVersion.ts),
|
|
37
|
+
},
|
|
38
|
+
endVersion: {
|
|
39
|
+
...encoded.endVersion,
|
|
40
|
+
ts: u64ToLong(encoded.endVersion.ts),
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
default: {
|
|
45
|
+
encoded;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
export function encodeClientMessage(message) {
|
|
51
|
+
switch (message.type) {
|
|
52
|
+
case "Authenticate":
|
|
53
|
+
case "ModifyQuerySet":
|
|
54
|
+
case "Mutation":
|
|
55
|
+
case "Action":
|
|
56
|
+
case "Event": {
|
|
57
|
+
return { ...message };
|
|
58
|
+
}
|
|
59
|
+
case "Connect": {
|
|
60
|
+
if (message.maxObservedTimestamp !== undefined) {
|
|
61
|
+
return {
|
|
62
|
+
...message,
|
|
63
|
+
maxObservedTimestamp: longToU64(message.maxObservedTimestamp),
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
return { ...message, maxObservedTimestamp: undefined };
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
default: {
|
|
71
|
+
message;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return undefined;
|
|
75
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function newSessionId(): string;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export function newSessionId() {
|
|
2
|
+
return uuidv4();
|
|
3
|
+
}
|
|
4
|
+
// From https://stackoverflow.com/a/2117523
|
|
5
|
+
function uuidv4() {
|
|
6
|
+
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
|
|
7
|
+
const r = (Math.random() * 16) | 0, v = c === "x" ? r : (r & 0x3) | 0x8;
|
|
8
|
+
return v.toString(16);
|
|
9
|
+
});
|
|
10
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Value } from "convex/values";
|
|
2
|
+
export declare function canonicalizeUdfPath(udfPath: string): string;
|
|
3
|
+
/**
|
|
4
|
+
* The serialization here is not stable, these strings never make it outside the client.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* A string representing the name and arguments of a query.
|
|
8
|
+
*
|
|
9
|
+
* This is used by the {@link BaseConvexClient}.
|
|
10
|
+
*
|
|
11
|
+
* @public
|
|
12
|
+
*/
|
|
13
|
+
export type QueryToken = string & {
|
|
14
|
+
__queryToken: true;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* A string representing the name and arguments of a paginated query.
|
|
18
|
+
*
|
|
19
|
+
* This is a specialized form of QueryToken used for paginated queries.
|
|
20
|
+
*/
|
|
21
|
+
export type PaginatedQueryToken = QueryToken & {
|
|
22
|
+
__paginatedQueryToken: true;
|
|
23
|
+
};
|
|
24
|
+
export declare function serializePathAndArgs(udfPath: string, args: Record<string, Value>): QueryToken;
|
|
25
|
+
export declare function serializePaginatedPathAndArgs(udfPath: string, args: Record<string, Value>, // args WITHOUT paginationOpts
|
|
26
|
+
options: {
|
|
27
|
+
initialNumItems: number;
|
|
28
|
+
id: number;
|
|
29
|
+
}): PaginatedQueryToken;
|
|
30
|
+
export declare function serializedQueryTokenIsPaginated(token: QueryToken | PaginatedQueryToken): token is PaginatedQueryToken;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { convexToJson } from "convex/values";
|
|
2
|
+
export function canonicalizeUdfPath(udfPath) {
|
|
3
|
+
const pieces = udfPath.split(":");
|
|
4
|
+
let moduleName;
|
|
5
|
+
let functionName;
|
|
6
|
+
if (pieces.length === 1) {
|
|
7
|
+
moduleName = pieces[0];
|
|
8
|
+
functionName = "default";
|
|
9
|
+
}
|
|
10
|
+
else {
|
|
11
|
+
moduleName = pieces.slice(0, pieces.length - 1).join(":");
|
|
12
|
+
functionName = pieces[pieces.length - 1];
|
|
13
|
+
}
|
|
14
|
+
if (moduleName.endsWith(".js")) {
|
|
15
|
+
moduleName = moduleName.slice(0, -3);
|
|
16
|
+
}
|
|
17
|
+
return `${moduleName}:${functionName}`;
|
|
18
|
+
}
|
|
19
|
+
export function serializePathAndArgs(udfPath, args) {
|
|
20
|
+
return JSON.stringify({
|
|
21
|
+
udfPath: canonicalizeUdfPath(udfPath),
|
|
22
|
+
args: convexToJson(args),
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
export function serializePaginatedPathAndArgs(udfPath, args, // args WITHOUT paginationOpts
|
|
26
|
+
options) {
|
|
27
|
+
const { initialNumItems, id } = options;
|
|
28
|
+
const result = JSON.stringify({
|
|
29
|
+
type: "paginated",
|
|
30
|
+
udfPath: canonicalizeUdfPath(udfPath),
|
|
31
|
+
args: convexToJson(args),
|
|
32
|
+
options: convexToJson({ initialNumItems, id }),
|
|
33
|
+
});
|
|
34
|
+
return result;
|
|
35
|
+
}
|
|
36
|
+
export function serializedQueryTokenIsPaginated(token) {
|
|
37
|
+
return JSON.parse(token).type === "paginated";
|
|
38
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Value } from "convex/values";
|
|
2
|
+
/**
|
|
3
|
+
* Validate that the arguments to a Convex function are an object, defaulting
|
|
4
|
+
* `undefined` to `{}`.
|
|
5
|
+
*/
|
|
6
|
+
export declare function parseArgs(args: Record<string, Value> | undefined): Record<string, Value>;
|
|
7
|
+
export declare function validateDeploymentUrl(deploymentUrl: string): void;
|
|
8
|
+
/**
|
|
9
|
+
* Check whether a value is a plain old JavaScript object.
|
|
10
|
+
*/
|
|
11
|
+
export declare function isSimpleObject(value: unknown): boolean;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validate that the arguments to a Convex function are an object, defaulting
|
|
3
|
+
* `undefined` to `{}`.
|
|
4
|
+
*/
|
|
5
|
+
export function parseArgs(args) {
|
|
6
|
+
if (args === undefined) {
|
|
7
|
+
return {};
|
|
8
|
+
}
|
|
9
|
+
if (!isSimpleObject(args)) {
|
|
10
|
+
throw new Error(`The arguments to a Convex function must be an object. Received: ${args}`);
|
|
11
|
+
}
|
|
12
|
+
return args;
|
|
13
|
+
}
|
|
14
|
+
export function validateDeploymentUrl(deploymentUrl) {
|
|
15
|
+
// Don't use things like `new URL(deploymentUrl).hostname` since these aren't
|
|
16
|
+
// supported by React Native's JS environment
|
|
17
|
+
if (typeof deploymentUrl === "undefined") {
|
|
18
|
+
throw new Error(`Client created with undefined deployment address. If you used an environment variable, check that it's set.`);
|
|
19
|
+
}
|
|
20
|
+
if (typeof deploymentUrl !== "string") {
|
|
21
|
+
throw new Error(`Invalid deployment address: found ${deploymentUrl}".`);
|
|
22
|
+
}
|
|
23
|
+
if (!(deploymentUrl.startsWith("http:") || deploymentUrl.startsWith("https:"))) {
|
|
24
|
+
throw new Error(`Invalid deployment address: Must start with "https://" or "http://". Found "${deploymentUrl}".`);
|
|
25
|
+
}
|
|
26
|
+
// Most clients should connect to ".convex.cloud". But we also support localhost and
|
|
27
|
+
// custom custom. We validate the deployment url is a valid url, which is the most
|
|
28
|
+
// common failure pattern.
|
|
29
|
+
try {
|
|
30
|
+
new URL(deploymentUrl);
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
throw new Error(`Invalid deployment address: "${deploymentUrl}" is not a valid URL. If you believe this URL is correct, use the \`skipConvexDeploymentUrlCheck\` option to bypass this.`);
|
|
34
|
+
}
|
|
35
|
+
// If a user uses .convex.site, this is very likely incorrect.
|
|
36
|
+
if (deploymentUrl.endsWith(".convex.site")) {
|
|
37
|
+
throw new Error(`Invalid deployment address: "${deploymentUrl}" ends with .convex.site, which is used for HTTP Actions. Convex deployment URLs typically end with .convex.cloud? If you believe this URL is correct, use the \`skipConvexDeploymentUrlCheck\` option to bypass this.`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Check whether a value is a plain old JavaScript object.
|
|
42
|
+
*/
|
|
43
|
+
export function isSimpleObject(value) {
|
|
44
|
+
const isObject = typeof value === "object";
|
|
45
|
+
const prototype = Object.getPrototypeOf(value);
|
|
46
|
+
const isSimple = prototype === null ||
|
|
47
|
+
prototype === Object.prototype ||
|
|
48
|
+
// Objects generated from other contexts (e.g. across Node.js `vm` modules) will not satisfy the previous
|
|
49
|
+
// conditions but are still simple objects.
|
|
50
|
+
prototype?.constructor?.name === "Object";
|
|
51
|
+
return isObject && isSimple;
|
|
52
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const version = "1.48.0";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const version = "1.48.0";
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2015 Auth0, Inc. <support@auth0.com> (http://auth0.com)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export interface JwtDecodeOptions {
|
|
2
|
+
header?: boolean;
|
|
3
|
+
}
|
|
4
|
+
export interface JwtHeader {
|
|
5
|
+
typ?: string;
|
|
6
|
+
alg?: string;
|
|
7
|
+
kid?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface JwtPayload {
|
|
10
|
+
iss?: string;
|
|
11
|
+
sub?: string;
|
|
12
|
+
aud?: string[] | string;
|
|
13
|
+
exp?: number;
|
|
14
|
+
nbf?: number;
|
|
15
|
+
iat?: number;
|
|
16
|
+
jti?: string;
|
|
17
|
+
}
|
|
18
|
+
export declare class InvalidTokenError extends Error {
|
|
19
|
+
}
|
|
20
|
+
export declare function jwtDecode<T = JwtHeader>(token: string, options: JwtDecodeOptions & {
|
|
21
|
+
header: true;
|
|
22
|
+
}): T;
|
|
23
|
+
export declare function jwtDecode<T = JwtPayload>(token: string, options?: JwtDecodeOptions): T;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
export class InvalidTokenError extends Error {
|
|
2
|
+
}
|
|
3
|
+
InvalidTokenError.prototype.name = "InvalidTokenError";
|
|
4
|
+
function b64DecodeUnicode(str) {
|
|
5
|
+
return decodeURIComponent(atob(str).replace(/(.)/g, (_m, p) => {
|
|
6
|
+
let code = p.charCodeAt(0).toString(16).toUpperCase();
|
|
7
|
+
if (code.length < 2) {
|
|
8
|
+
code = "0" + code;
|
|
9
|
+
}
|
|
10
|
+
return "%" + code;
|
|
11
|
+
}));
|
|
12
|
+
}
|
|
13
|
+
function base64UrlDecode(str) {
|
|
14
|
+
let output = str.replace(/-/g, "+").replace(/_/g, "/");
|
|
15
|
+
switch (output.length % 4) {
|
|
16
|
+
case 0:
|
|
17
|
+
break;
|
|
18
|
+
case 2:
|
|
19
|
+
output += "==";
|
|
20
|
+
break;
|
|
21
|
+
case 3:
|
|
22
|
+
output += "=";
|
|
23
|
+
break;
|
|
24
|
+
default:
|
|
25
|
+
throw new Error("base64 string is not of the correct length");
|
|
26
|
+
}
|
|
27
|
+
try {
|
|
28
|
+
return b64DecodeUnicode(output);
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return atob(output);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export function jwtDecode(token, options) {
|
|
35
|
+
if (typeof token !== "string") {
|
|
36
|
+
throw new InvalidTokenError("Invalid token specified: must be a string");
|
|
37
|
+
}
|
|
38
|
+
options ||= {};
|
|
39
|
+
const pos = options.header === true ? 0 : 1;
|
|
40
|
+
const part = token.split(".")[pos];
|
|
41
|
+
if (typeof part !== "string") {
|
|
42
|
+
throw new InvalidTokenError(`Invalid token specified: missing part #${pos + 1}`);
|
|
43
|
+
}
|
|
44
|
+
let decoded;
|
|
45
|
+
try {
|
|
46
|
+
decoded = base64UrlDecode(part);
|
|
47
|
+
}
|
|
48
|
+
catch (e) {
|
|
49
|
+
throw new InvalidTokenError(`Invalid token specified: invalid base64 for part #${pos + 1} (${e.message})`);
|
|
50
|
+
}
|
|
51
|
+
try {
|
|
52
|
+
return JSON.parse(decoded);
|
|
53
|
+
}
|
|
54
|
+
catch (e) {
|
|
55
|
+
throw new InvalidTokenError(`Invalid token specified: invalid json for part #${pos + 1} (${e.message})`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare class Long {
|
|
2
|
+
low: number;
|
|
3
|
+
high: number;
|
|
4
|
+
__isUnsignedLong__: boolean;
|
|
5
|
+
static isLong(obj: Long): boolean;
|
|
6
|
+
constructor(low: number, high: number);
|
|
7
|
+
static fromBytesLE(bytes: number[]): Long;
|
|
8
|
+
toBytesLE(): number[];
|
|
9
|
+
static fromNumber(value: number): Long;
|
|
10
|
+
toString(): string;
|
|
11
|
+
equals(other: Long): boolean;
|
|
12
|
+
notEquals(other: Long): boolean;
|
|
13
|
+
comp(other: Long): 0 | 1 | -1;
|
|
14
|
+
lessThanOrEqual(other: Long): boolean;
|
|
15
|
+
static fromValue(val: any): Long;
|
|
16
|
+
}
|