@stackframe/stack-shared 2.7.13 → 2.7.14
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/CHANGELOG.md +7 -0
- package/dist/interface/crud/projects.js +3 -1
- package/dist/interface/crud/users.js +1 -1
- package/dist/interface/serverInterface.js +25 -24
- package/dist/schema-fields.d.ts +0 -1
- package/dist/schema-fields.js +1 -2
- package/dist/utils/caches.d.ts +10 -10
- package/dist/utils/promises.js +7 -1
- package/dist/utils/stores.d.ts +6 -6
- package/dist/utils/strings.js +1 -5
- package/dist/utils/urls.d.ts +12 -0
- package/dist/utils/urls.js +17 -0
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -45,7 +45,9 @@ export const emailConfigSchema = yupObject({
|
|
|
45
45
|
}),
|
|
46
46
|
});
|
|
47
47
|
const domainSchema = yupObject({
|
|
48
|
-
domain: schemaFields.
|
|
48
|
+
domain: schemaFields.urlSchema.defined()
|
|
49
|
+
.matches(/^https?:\/\//, 'URL must start with http:// or https://')
|
|
50
|
+
.meta({ openapiField: { description: 'URL. Must start with http:// or https://', exampleValue: 'https://example.com' } }),
|
|
49
51
|
handler_path: schemaFields.handlerPathSchema.defined(),
|
|
50
52
|
});
|
|
51
53
|
export const projectsCrudAdminReadSchema = yupObject({
|
|
@@ -7,7 +7,7 @@ export const usersCrudServerUpdateSchema = fieldSchema.yupObject({
|
|
|
7
7
|
client_metadata: fieldSchema.userClientMetadataSchema.optional(),
|
|
8
8
|
client_read_only_metadata: fieldSchema.userClientReadOnlyMetadataSchema.optional(),
|
|
9
9
|
server_metadata: fieldSchema.userServerMetadataSchema.optional(),
|
|
10
|
-
primary_email: fieldSchema.primaryEmailSchema.nullable().optional(),
|
|
10
|
+
primary_email: fieldSchema.primaryEmailSchema.nullable().optional().nonEmpty(),
|
|
11
11
|
primary_email_verified: fieldSchema.primaryEmailVerifiedSchema.optional(),
|
|
12
12
|
primary_email_auth_enabled: fieldSchema.primaryEmailAuthEnabledSchema.optional(),
|
|
13
13
|
passkey_auth_enabled: fieldSchema.userOtpAuthEnabledSchema.optional(),
|
|
@@ -2,6 +2,7 @@ import { KnownErrors } from "../known-errors";
|
|
|
2
2
|
import { StackAssertionError } from "../utils/errors";
|
|
3
3
|
import { filterUndefined } from "../utils/objects";
|
|
4
4
|
import { Result } from "../utils/results";
|
|
5
|
+
import { urlString } from "../utils/urls";
|
|
5
6
|
import { StackClientInterface } from "./clientInterface";
|
|
6
7
|
export class StackServerInterface extends StackClientInterface {
|
|
7
8
|
constructor(options) {
|
|
@@ -57,35 +58,35 @@ export class StackServerInterface extends StackClientInterface {
|
|
|
57
58
|
return user;
|
|
58
59
|
}
|
|
59
60
|
async getServerUserById(userId) {
|
|
60
|
-
const response = await this.sendServerRequest(`/users/${userId}`, {}, null);
|
|
61
|
+
const response = await this.sendServerRequest(urlString `/users/${userId}`, {}, null);
|
|
61
62
|
const user = await response.json();
|
|
62
63
|
if (!user)
|
|
63
64
|
return Result.error(new Error("Failed to get user"));
|
|
64
65
|
return Result.ok(user);
|
|
65
66
|
}
|
|
66
67
|
async listServerTeamInvitations(options) {
|
|
67
|
-
const response = await this.sendServerRequest(
|
|
68
|
+
const response = await this.sendServerRequest(urlString `/team-invitations?team_id=${options.teamId}`, {}, null);
|
|
68
69
|
const result = await response.json();
|
|
69
70
|
return result.items;
|
|
70
71
|
}
|
|
71
72
|
async revokeServerTeamInvitation(invitationId, teamId) {
|
|
72
|
-
await this.sendServerRequest(`/team-invitations/${invitationId}?team_id=${teamId}`, { method: "DELETE" }, null);
|
|
73
|
+
await this.sendServerRequest(urlString `/team-invitations/${invitationId}?team_id=${teamId}`, { method: "DELETE" }, null);
|
|
73
74
|
}
|
|
74
75
|
async listServerTeamMemberProfiles(options) {
|
|
75
|
-
const response = await this.sendServerRequest(
|
|
76
|
+
const response = await this.sendServerRequest(urlString `/team-member-profiles?team_id=${options.teamId}`, {}, null);
|
|
76
77
|
const result = await response.json();
|
|
77
78
|
return result.items;
|
|
78
79
|
}
|
|
79
80
|
async getServerTeamMemberProfile(options) {
|
|
80
|
-
const response = await this.sendServerRequest(`/team-member-profiles/${options.teamId}/${options.userId}`, {}, null);
|
|
81
|
+
const response = await this.sendServerRequest(urlString `/team-member-profiles/${options.teamId}/${options.userId}`, {}, null);
|
|
81
82
|
return await response.json();
|
|
82
83
|
}
|
|
83
84
|
async listServerTeamPermissions(options, session) {
|
|
84
|
-
const response = await this.sendServerRequest(
|
|
85
|
+
const response = await this.sendServerRequest(`/team-permissions?${new URLSearchParams(filterUndefined({
|
|
85
86
|
user_id: options.userId,
|
|
86
87
|
team_id: options.teamId,
|
|
87
88
|
recursive: options.recursive.toString(),
|
|
88
|
-
}))
|
|
89
|
+
}))}`, {}, session);
|
|
89
90
|
const result = await response.json();
|
|
90
91
|
return result.items;
|
|
91
92
|
}
|
|
@@ -107,9 +108,9 @@ export class StackServerInterface extends StackClientInterface {
|
|
|
107
108
|
return await response.json();
|
|
108
109
|
}
|
|
109
110
|
async listServerTeams(options) {
|
|
110
|
-
const response = await this.sendServerRequest(
|
|
111
|
+
const response = await this.sendServerRequest(`/teams?${new URLSearchParams(filterUndefined({
|
|
111
112
|
user_id: options?.userId,
|
|
112
|
-
}))
|
|
113
|
+
}))}`, {}, null);
|
|
113
114
|
const result = await response.json();
|
|
114
115
|
return result.items;
|
|
115
116
|
}
|
|
@@ -130,7 +131,7 @@ export class StackServerInterface extends StackClientInterface {
|
|
|
130
131
|
return await response.json();
|
|
131
132
|
}
|
|
132
133
|
async updateServerTeam(teamId, data) {
|
|
133
|
-
const response = await this.sendServerRequest(`/teams/${teamId}`, {
|
|
134
|
+
const response = await this.sendServerRequest(urlString `/teams/${teamId}`, {
|
|
134
135
|
method: "PATCH",
|
|
135
136
|
headers: {
|
|
136
137
|
"content-type": "application/json",
|
|
@@ -140,10 +141,10 @@ export class StackServerInterface extends StackClientInterface {
|
|
|
140
141
|
return await response.json();
|
|
141
142
|
}
|
|
142
143
|
async deleteServerTeam(teamId) {
|
|
143
|
-
await this.sendServerRequest(`/teams/${teamId}`, { method: "DELETE" }, null);
|
|
144
|
+
await this.sendServerRequest(urlString `/teams/${teamId}`, { method: "DELETE" }, null);
|
|
144
145
|
}
|
|
145
146
|
async addServerUserToTeam(options) {
|
|
146
|
-
const response = await this.sendServerRequest(`/team-memberships/${options.teamId}/${options.userId}`, {
|
|
147
|
+
const response = await this.sendServerRequest(urlString `/team-memberships/${options.teamId}/${options.userId}`, {
|
|
147
148
|
method: "POST",
|
|
148
149
|
headers: {
|
|
149
150
|
"content-type": "application/json",
|
|
@@ -153,7 +154,7 @@ export class StackServerInterface extends StackClientInterface {
|
|
|
153
154
|
return await response.json();
|
|
154
155
|
}
|
|
155
156
|
async removeServerUserFromTeam(options) {
|
|
156
|
-
await this.sendServerRequest(`/team-memberships/${options.teamId}/${options.userId}`, {
|
|
157
|
+
await this.sendServerRequest(urlString `/team-memberships/${options.teamId}/${options.userId}`, {
|
|
157
158
|
method: "DELETE",
|
|
158
159
|
headers: {
|
|
159
160
|
"content-type": "application/json",
|
|
@@ -162,7 +163,7 @@ export class StackServerInterface extends StackClientInterface {
|
|
|
162
163
|
}, null);
|
|
163
164
|
}
|
|
164
165
|
async updateServerUser(userId, update) {
|
|
165
|
-
const response = await this.sendServerRequest(`/users/${userId}`, {
|
|
166
|
+
const response = await this.sendServerRequest(urlString `/users/${userId}`, {
|
|
166
167
|
method: "PATCH",
|
|
167
168
|
headers: {
|
|
168
169
|
"content-type": "application/json",
|
|
@@ -172,7 +173,7 @@ export class StackServerInterface extends StackClientInterface {
|
|
|
172
173
|
return await response.json();
|
|
173
174
|
}
|
|
174
175
|
async createServerProviderAccessToken(userId, provider, scope) {
|
|
175
|
-
const response = await this.sendServerRequest(`/connected-accounts/${userId}/${provider}/access-token`, {
|
|
176
|
+
const response = await this.sendServerRequest(urlString `/connected-accounts/${userId}/${provider}/access-token`, {
|
|
176
177
|
method: "POST",
|
|
177
178
|
headers: {
|
|
178
179
|
"content-type": "application/json",
|
|
@@ -199,7 +200,7 @@ export class StackServerInterface extends StackClientInterface {
|
|
|
199
200
|
};
|
|
200
201
|
}
|
|
201
202
|
async leaveServerTeam(options) {
|
|
202
|
-
await this.sendClientRequest(`/team-memberships/${options.teamId}/${options.userId}`, {
|
|
203
|
+
await this.sendClientRequest(urlString `/team-memberships/${options.teamId}/${options.userId}`, {
|
|
203
204
|
method: "DELETE",
|
|
204
205
|
headers: {
|
|
205
206
|
"content-type": "application/json",
|
|
@@ -208,7 +209,7 @@ export class StackServerInterface extends StackClientInterface {
|
|
|
208
209
|
}, null);
|
|
209
210
|
}
|
|
210
211
|
async updateServerTeamMemberProfile(options) {
|
|
211
|
-
await this.sendServerRequest(`/team-member-profiles/${options.teamId}/${options.userId}`, {
|
|
212
|
+
await this.sendServerRequest(urlString `/team-member-profiles/${options.teamId}/${options.userId}`, {
|
|
212
213
|
method: "PATCH",
|
|
213
214
|
headers: {
|
|
214
215
|
"content-type": "application/json",
|
|
@@ -217,7 +218,7 @@ export class StackServerInterface extends StackClientInterface {
|
|
|
217
218
|
}, null);
|
|
218
219
|
}
|
|
219
220
|
async grantServerTeamUserPermission(teamId, userId, permissionId) {
|
|
220
|
-
await this.sendServerRequest(`/team-permissions/${teamId}/${userId}/${permissionId}`, {
|
|
221
|
+
await this.sendServerRequest(urlString `/team-permissions/${teamId}/${userId}/${permissionId}`, {
|
|
221
222
|
method: "POST",
|
|
222
223
|
headers: {
|
|
223
224
|
"content-type": "application/json",
|
|
@@ -226,7 +227,7 @@ export class StackServerInterface extends StackClientInterface {
|
|
|
226
227
|
}, null);
|
|
227
228
|
}
|
|
228
229
|
async revokeServerTeamUserPermission(teamId, userId, permissionId) {
|
|
229
|
-
await this.sendServerRequest(`/team-permissions/${teamId}/${userId}/${permissionId}`, {
|
|
230
|
+
await this.sendServerRequest(urlString `/team-permissions/${teamId}/${userId}/${permissionId}`, {
|
|
230
231
|
method: "DELETE",
|
|
231
232
|
headers: {
|
|
232
233
|
"content-type": "application/json",
|
|
@@ -235,7 +236,7 @@ export class StackServerInterface extends StackClientInterface {
|
|
|
235
236
|
}, null);
|
|
236
237
|
}
|
|
237
238
|
async deleteServerServerUser(userId) {
|
|
238
|
-
await this.sendServerRequest(`/users/${userId}`, {
|
|
239
|
+
await this.sendServerRequest(urlString `/users/${userId}`, {
|
|
239
240
|
method: "DELETE",
|
|
240
241
|
headers: {
|
|
241
242
|
"content-type": "application/json",
|
|
@@ -254,7 +255,7 @@ export class StackServerInterface extends StackClientInterface {
|
|
|
254
255
|
return await response.json();
|
|
255
256
|
}
|
|
256
257
|
async updateServerContactChannel(userId, contactChannelId, data) {
|
|
257
|
-
const response = await this.sendServerRequest(`/contact-channels/${userId}/${contactChannelId}`, {
|
|
258
|
+
const response = await this.sendServerRequest(urlString `/contact-channels/${userId}/${contactChannelId}`, {
|
|
258
259
|
method: "PATCH",
|
|
259
260
|
headers: {
|
|
260
261
|
"content-type": "application/json",
|
|
@@ -264,19 +265,19 @@ export class StackServerInterface extends StackClientInterface {
|
|
|
264
265
|
return await response.json();
|
|
265
266
|
}
|
|
266
267
|
async deleteServerContactChannel(userId, contactChannelId) {
|
|
267
|
-
await this.sendServerRequest(`/contact-channels/${userId}/${contactChannelId}`, {
|
|
268
|
+
await this.sendServerRequest(urlString `/contact-channels/${userId}/${contactChannelId}`, {
|
|
268
269
|
method: "DELETE",
|
|
269
270
|
}, null);
|
|
270
271
|
}
|
|
271
272
|
async listServerContactChannels(userId) {
|
|
272
|
-
const response = await this.sendServerRequest(`/contact-channels?user_id=${userId}`, {
|
|
273
|
+
const response = await this.sendServerRequest(urlString `/contact-channels?user_id=${userId}`, {
|
|
273
274
|
method: "GET",
|
|
274
275
|
}, null);
|
|
275
276
|
const json = await response.json();
|
|
276
277
|
return json.items;
|
|
277
278
|
}
|
|
278
279
|
async sendServerContactChannelVerificationEmail(userId, contactChannelId, callbackUrl) {
|
|
279
|
-
await this.sendServerRequest(`/contact-channels/${userId}/${contactChannelId}/send-verification-code`, {
|
|
280
|
+
await this.sendServerRequest(urlString `/contact-channels/${userId}/${contactChannelId}/send-verification-code`, {
|
|
280
281
|
method: "POST",
|
|
281
282
|
headers: {
|
|
282
283
|
"content-type": "application/json",
|
package/dist/schema-fields.d.ts
CHANGED
|
@@ -79,7 +79,6 @@ export declare const emailPortSchema: yup.NumberSchema<number | undefined, yup.A
|
|
|
79
79
|
export declare const emailUsernameSchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
|
|
80
80
|
export declare const emailSenderEmailSchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
|
|
81
81
|
export declare const emailPasswordSchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
|
|
82
|
-
export declare const projectTrustedDomainSchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
|
|
83
82
|
export declare const handlerPathSchema: yup.StringSchema<string | undefined, yup.AnyObject, undefined, "">;
|
|
84
83
|
export declare class ReplaceFieldWithOwnUserId extends Error {
|
|
85
84
|
readonly path: string;
|
package/dist/schema-fields.js
CHANGED
|
@@ -248,12 +248,11 @@ export const oauthMicrosoftTenantIdSchema = yupString().meta({ openapiField: { d
|
|
|
248
248
|
export const emailTypeSchema = yupString().oneOf(['shared', 'standard']).meta({ openapiField: { description: 'Email provider type, one of shared, standard. "shared" uses Stack shared email provider and it is only meant for development. "standard" uses your own email server and will have your email address as the sender.', exampleValue: 'standard' } });
|
|
249
249
|
export const emailSenderNameSchema = yupString().meta({ openapiField: { description: 'Email sender name. Needs to be specified when using type="standard"', exampleValue: 'Stack' } });
|
|
250
250
|
export const emailHostSchema = yupString().meta({ openapiField: { description: 'Email host. Needs to be specified when using type="standard"', exampleValue: 'smtp.your-domain.com' } });
|
|
251
|
-
export const emailPortSchema = yupNumber().meta({ openapiField: { description: 'Email port. Needs to be specified when using type="standard"', exampleValue: 587 } });
|
|
251
|
+
export const emailPortSchema = yupNumber().min(0).max(65535).meta({ openapiField: { description: 'Email port. Needs to be specified when using type="standard"', exampleValue: 587 } });
|
|
252
252
|
export const emailUsernameSchema = yupString().meta({ openapiField: { description: 'Email username. Needs to be specified when using type="standard"', exampleValue: 'smtp-email' } });
|
|
253
253
|
export const emailSenderEmailSchema = emailSchema.meta({ openapiField: { description: 'Email sender email. Needs to be specified when using type="standard"', exampleValue: 'example@your-domain.com' } });
|
|
254
254
|
export const emailPasswordSchema = passwordSchema.meta({ openapiField: { description: 'Email password. Needs to be specified when using type="standard"', exampleValue: 'your-email-password' } });
|
|
255
255
|
// Project domain config
|
|
256
|
-
export const projectTrustedDomainSchema = urlSchema.test('is-https', 'Trusted domain must start with https://', (value) => value?.startsWith('https://')).meta({ openapiField: { description: 'Your domain URL. Make sure you own and trust this domain. Needs to start with https://', exampleValue: 'https://example.com' } });
|
|
257
256
|
export const handlerPathSchema = yupString().test('is-handler-path', 'Handler path must start with /', (value) => value?.startsWith('/')).meta({ openapiField: { description: 'Handler path. If you did not setup a custom handler path, it should be "/handler" by default. It needs to start with /', exampleValue: '/handler' } });
|
|
258
257
|
// Users
|
|
259
258
|
export class ReplaceFieldWithOwnUserId extends Error {
|
package/dist/utils/caches.d.ts
CHANGED
|
@@ -17,16 +17,16 @@ export declare class AsyncCache<D extends any[], T> {
|
|
|
17
17
|
refreshWhere(predicate: (dependencies: D) => boolean): Promise<void>;
|
|
18
18
|
readonly isCacheAvailable: (key: D) => boolean;
|
|
19
19
|
readonly getIfCached: (key: D) => ({
|
|
20
|
+
status: "error";
|
|
21
|
+
error: unknown;
|
|
22
|
+
} & {
|
|
23
|
+
status: "error";
|
|
24
|
+
}) | ({
|
|
20
25
|
status: "pending";
|
|
21
26
|
} & {
|
|
22
27
|
progress: void;
|
|
23
28
|
} & {
|
|
24
29
|
status: "pending";
|
|
25
|
-
}) | ({
|
|
26
|
-
status: "error";
|
|
27
|
-
error: unknown;
|
|
28
|
-
} & {
|
|
29
|
-
status: "error";
|
|
30
30
|
}) | ({
|
|
31
31
|
status: "ok";
|
|
32
32
|
data: T;
|
|
@@ -57,16 +57,16 @@ declare class AsyncValueCache<T> {
|
|
|
57
57
|
});
|
|
58
58
|
isCacheAvailable(): boolean;
|
|
59
59
|
getIfCached(): ({
|
|
60
|
+
status: "error";
|
|
61
|
+
error: unknown;
|
|
62
|
+
} & {
|
|
63
|
+
status: "error";
|
|
64
|
+
}) | ({
|
|
60
65
|
status: "pending";
|
|
61
66
|
} & {
|
|
62
67
|
progress: void;
|
|
63
68
|
} & {
|
|
64
69
|
status: "pending";
|
|
65
|
-
}) | ({
|
|
66
|
-
status: "error";
|
|
67
|
-
error: unknown;
|
|
68
|
-
} & {
|
|
69
|
-
status: "error";
|
|
70
70
|
}) | ({
|
|
71
71
|
status: "ok";
|
|
72
72
|
data: T;
|
package/dist/utils/promises.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { KnownError } from "..";
|
|
1
2
|
import { StackAssertionError, captureError, concatStacktraces } from "./errors";
|
|
2
3
|
import { DependenciesMap } from "./maps";
|
|
3
4
|
import { Result } from "./results";
|
|
@@ -105,7 +106,12 @@ export function runAsynchronouslyWithAlert(...args) {
|
|
|
105
106
|
return runAsynchronously(args[0], {
|
|
106
107
|
...args[1],
|
|
107
108
|
onError: error => {
|
|
108
|
-
|
|
109
|
+
if (error instanceof KnownError && process.env.NODE_ENV.includes("production")) {
|
|
110
|
+
alert(error.message);
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
alert(`An unhandled error occurred. Please ${process.env.NODE_ENV === "development" ? `check the browser console for the full error.` : "report this to the developer."}\n\n${error}`);
|
|
114
|
+
}
|
|
109
115
|
args[1]?.onError?.(error);
|
|
110
116
|
},
|
|
111
117
|
}, ...args.slice(2));
|
package/dist/utils/stores.d.ts
CHANGED
|
@@ -60,12 +60,6 @@ export declare class AsyncStore<T> implements ReadonlyAsyncStore<T> {
|
|
|
60
60
|
isAvailable(): boolean;
|
|
61
61
|
isRejected(): boolean;
|
|
62
62
|
get(): ({
|
|
63
|
-
status: "pending";
|
|
64
|
-
} & {
|
|
65
|
-
progress: void;
|
|
66
|
-
} & {
|
|
67
|
-
status: "pending";
|
|
68
|
-
}) | ({
|
|
69
63
|
status: "error";
|
|
70
64
|
error: unknown;
|
|
71
65
|
} & {
|
|
@@ -75,6 +69,12 @@ export declare class AsyncStore<T> implements ReadonlyAsyncStore<T> {
|
|
|
75
69
|
data: T;
|
|
76
70
|
} & {
|
|
77
71
|
status: "ok";
|
|
72
|
+
}) | ({
|
|
73
|
+
status: "pending";
|
|
74
|
+
} & {
|
|
75
|
+
progress: void;
|
|
76
|
+
} & {
|
|
77
|
+
status: "pending";
|
|
78
78
|
});
|
|
79
79
|
getOrWait(): ReactPromise<T>;
|
|
80
80
|
_setIfLatest(result: Result<T>, curCounter: number): boolean;
|
package/dist/utils/strings.js
CHANGED
|
@@ -67,11 +67,7 @@ export function trimLines(s) {
|
|
|
67
67
|
* Useful for implementing your own template literal tags.
|
|
68
68
|
*/
|
|
69
69
|
export function templateIdentity(strings, ...values) {
|
|
70
|
-
|
|
71
|
-
return "";
|
|
72
|
-
if (values.length !== strings.length - 1)
|
|
73
|
-
throw new Error("Invalid number of values; must be one less than strings");
|
|
74
|
-
return strings.slice(1).reduce((result, string, i) => `${result}${values[i] ?? "n/a"}${string}`, strings[0]);
|
|
70
|
+
return strings.reduce((result, str, i) => result + str + (values[i] ?? ''), '');
|
|
75
71
|
}
|
|
76
72
|
export function deindent(strings, ...values) {
|
|
77
73
|
if (typeof strings === "string")
|
package/dist/utils/urls.d.ts
CHANGED
|
@@ -3,3 +3,15 @@ export declare function isValidUrl(url: string): boolean;
|
|
|
3
3
|
export declare function isLocalhost(urlOrString: string | URL): boolean;
|
|
4
4
|
export declare function isRelative(url: string): boolean;
|
|
5
5
|
export declare function getRelativePart(url: URL): string;
|
|
6
|
+
/**
|
|
7
|
+
* A template literal tag that returns a URL.
|
|
8
|
+
*
|
|
9
|
+
* Any values passed are encoded.
|
|
10
|
+
*/
|
|
11
|
+
export declare function url(strings: TemplateStringsArray | readonly string[], ...values: (string | number | boolean)[]): URL;
|
|
12
|
+
/**
|
|
13
|
+
* A template literal tag that returns a URL string.
|
|
14
|
+
*
|
|
15
|
+
* Any values passed are encoded.
|
|
16
|
+
*/
|
|
17
|
+
export declare function urlString(strings: TemplateStringsArray | readonly string[], ...values: (string | number | boolean)[]): string;
|
package/dist/utils/urls.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { generateSecureRandomString } from "./crypto";
|
|
2
|
+
import { templateIdentity } from "./strings";
|
|
2
3
|
export function createUrlIfValid(...args) {
|
|
3
4
|
try {
|
|
4
5
|
return new URL(...args);
|
|
@@ -34,3 +35,19 @@ export function isRelative(url) {
|
|
|
34
35
|
export function getRelativePart(url) {
|
|
35
36
|
return url.pathname + url.search + url.hash;
|
|
36
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* A template literal tag that returns a URL.
|
|
40
|
+
*
|
|
41
|
+
* Any values passed are encoded.
|
|
42
|
+
*/
|
|
43
|
+
export function url(strings, ...values) {
|
|
44
|
+
return new URL(urlString(strings, ...values));
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* A template literal tag that returns a URL string.
|
|
48
|
+
*
|
|
49
|
+
* Any values passed are encoded.
|
|
50
|
+
*/
|
|
51
|
+
export function urlString(strings, ...values) {
|
|
52
|
+
return templateIdentity(strings, values.map(encodeURIComponent));
|
|
53
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stackframe/stack-shared",
|
|
3
|
-
"version": "2.7.
|
|
3
|
+
"version": "2.7.14",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
6
|
"type": "module",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"oauth4webapi": "^2.10.3",
|
|
53
53
|
"semver": "^7.6.3",
|
|
54
54
|
"uuid": "^9.0.1",
|
|
55
|
-
"@stackframe/stack-sc": "2.7.
|
|
55
|
+
"@stackframe/stack-sc": "2.7.14"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"@sentry/nextjs": "^8.40.0",
|