@stackframe/stack-shared 2.4.27 → 2.4.28

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 CHANGED
@@ -1,5 +1,12 @@
1
1
  # @stackframe/stack-shared
2
2
 
3
+ ## 2.4.28
4
+
5
+ ### Patch Changes
6
+
7
+ - Bugfixes
8
+ - @stackframe/stack-sc@2.4.28
9
+
3
10
  ## 2.4.27
4
11
 
5
12
  ### Patch Changes
@@ -31,6 +31,8 @@ export type ProjectUpdateOptions = {
31
31
  allowLocalhost?: boolean;
32
32
  createTeamOnSignUp?: boolean;
33
33
  emailConfig?: EmailConfigJson;
34
+ teamCreatorDefaultPermissionIds?: string[];
35
+ teamMemberDefaultPermissionIds?: string[];
34
36
  };
35
37
  };
36
38
  export type ApiKeySetBaseJson = {
@@ -68,6 +68,8 @@ export type ProjectJson = {
68
68
  emailConfig?: EmailConfigJson;
69
69
  domains: DomainConfigJson[];
70
70
  createTeamOnSignUp: boolean;
71
+ teamCreatorDefaultPermissions: PermissionDefinitionJson[];
72
+ teamMemberDefaultPermissions: PermissionDefinitionJson[];
71
73
  };
72
74
  };
73
75
  export type OAuthProviderConfigJson = {
@@ -106,6 +108,8 @@ export type OrglikeJson = {
106
108
  };
107
109
  export type TeamJson = OrglikeJson;
108
110
  export type OrganizationJson = OrglikeJson;
111
+ export type OrglikeCustomizableJson = Pick<OrglikeJson, "displayName">;
112
+ export type TeamCustomizableJson = OrglikeCustomizableJson;
109
113
  export type TeamMemberJson = {
110
114
  userId: string;
111
115
  teamId: string;
@@ -219,6 +223,7 @@ export declare class StackClientInterface {
219
223
  getAccessToken(provider: string, scope: string, session: InternalSession): Promise<{
220
224
  accessToken: string;
221
225
  }>;
226
+ createTeamForCurrentUser(data: TeamCustomizableJson, session: InternalSession): Promise<TeamJson>;
222
227
  }
223
228
  export declare function getProductionModeErrors(project: ProjectJson): ProductionModeError[];
224
229
  export {};
@@ -549,6 +549,16 @@ export class StackClientInterface {
549
549
  accessToken: json.accessToken,
550
550
  };
551
551
  }
552
+ async createTeamForCurrentUser(data, session) {
553
+ const response = await this.sendClientRequest("/current-user/teams?server=false", {
554
+ method: "POST",
555
+ headers: {
556
+ "content-type": "application/json",
557
+ },
558
+ body: JSON.stringify(data),
559
+ }, session);
560
+ return await response.json();
561
+ }
552
562
  }
553
563
  export function getProductionModeErrors(project) {
554
564
  const errors = [];
@@ -2,9 +2,9 @@ import { CrudTypeOf } from "../../crud";
2
2
  import * as yup from "yup";
3
3
  export declare const currentUserCrud: import("../../crud").CrudSchemaFromOptions<{
4
4
  clientReadSchema: yup.ObjectSchema<{
5
+ projectId: string;
5
6
  displayName: string | null;
6
7
  id: string;
7
- projectId: string;
8
8
  clientMetadata: {} | null;
9
9
  primaryEmail: string | null;
10
10
  primaryEmailVerified: NonNullable<boolean | undefined>;
@@ -56,31 +56,32 @@ export declare class StackServerInterface extends StackClientInterface {
56
56
  createPermissionDefinition(data: ServerPermissionDefinitionCustomizableJson): Promise<ServerPermissionDefinitionJson>;
57
57
  updatePermissionDefinition(permissionId: string, data: Partial<ServerPermissionDefinitionCustomizableJson>): Promise<void>;
58
58
  deletePermissionDefinition(permissionId: string): Promise<void>;
59
- listUsers(): Promise<ServerUserJson[]>;
60
- listTeams(): Promise<ServerTeamJson[]>;
61
- listTeamMembers(teamId: string): Promise<ServerTeamMemberJson[]>;
62
- createTeam(data: ServerTeamCustomizableJson): Promise<ServerTeamJson>;
63
- updateTeam(teamId: string, data: Partial<ServerTeamCustomizableJson>): Promise<void>;
64
- deleteTeam(teamId: string): Promise<void>;
65
- addUserToTeam(options: {
59
+ listServerUsers(): Promise<ServerUserJson[]>;
60
+ listServerTeams(): Promise<ServerTeamJson[]>;
61
+ listServerTeamMembers(teamId: string): Promise<ServerTeamMemberJson[]>;
62
+ createServerTeam(data: ServerTeamCustomizableJson): Promise<ServerTeamJson>;
63
+ updateServerTeam(teamId: string, data: Partial<ServerTeamCustomizableJson>): Promise<void>;
64
+ deleteServerTeam(teamId: string): Promise<void>;
65
+ addServerUserToTeam(options: {
66
66
  userId: string;
67
67
  teamId: string;
68
68
  }): Promise<void>;
69
- removeUserFromTeam(options: {
69
+ removeServerUserFromTeam(options: {
70
70
  userId: string;
71
71
  teamId: string;
72
72
  }): Promise<void>;
73
73
  setServerUserCustomizableData(userId: string, update: ServerUserUpdateJson): Promise<void>;
74
- listTeamMemberPermissions(options: {
74
+ listServerTeamMemberPermissions(options: {
75
75
  teamId: string;
76
76
  userId: string;
77
77
  type: 'global' | 'team';
78
78
  direct: boolean;
79
79
  }): Promise<ServerPermissionDefinitionJson[]>;
80
- grantTeamUserPermission(teamId: string, userId: string, permissionId: string, type: 'global' | 'team'): Promise<void>;
81
- revokeTeamUserPermission(teamId: string, userId: string, permissionId: string, type: 'global' | 'team'): Promise<void>;
82
- deleteServerUser(userId: string): Promise<void>;
80
+ grantServerTeamUserPermission(teamId: string, userId: string, permissionId: string, type: 'global' | 'team'): Promise<void>;
81
+ revokeServerTeamUserPermission(teamId: string, userId: string, permissionId: string, type: 'global' | 'team'): Promise<void>;
82
+ deleteServerServerUser(userId: string): Promise<void>;
83
83
  listEmailTemplates(): Promise<ListEmailTemplatesCrud['Server']['Read']>;
84
84
  updateEmailTemplate(type: EmailTemplateType, data: EmailTemplateCrud['Server']['Update']): Promise<void>;
85
85
  resetEmailTemplate(type: EmailTemplateType): Promise<void>;
86
+ createServerTeamForUser(userId: string, data: ServerTeamCustomizableJson, session: InternalSession): Promise<ServerTeamJson>;
86
87
  }
@@ -71,20 +71,20 @@ export class StackServerInterface extends StackClientInterface {
71
71
  async deletePermissionDefinition(permissionId) {
72
72
  await this.sendServerRequest(`/permission-definitions/${permissionId}?server=true`, { method: "DELETE" }, null);
73
73
  }
74
- async listUsers() {
74
+ async listServerUsers() {
75
75
  const response = await this.sendServerRequest("/users?server=true", {}, null);
76
76
  return await response.json();
77
77
  }
78
- async listTeams() {
78
+ async listServerTeams() {
79
79
  const response = await this.sendServerRequest("/teams?server=true", {}, null);
80
80
  const json = await response.json();
81
81
  return json;
82
82
  }
83
- async listTeamMembers(teamId) {
83
+ async listServerTeamMembers(teamId) {
84
84
  const response = await this.sendServerRequest(`/teams/${teamId}/users?server=true`, {}, null);
85
85
  return await response.json();
86
86
  }
87
- async createTeam(data) {
87
+ async createServerTeam(data) {
88
88
  const response = await this.sendServerRequest("/teams?server=true", {
89
89
  method: "POST",
90
90
  headers: {
@@ -94,7 +94,7 @@ export class StackServerInterface extends StackClientInterface {
94
94
  }, null);
95
95
  return await response.json();
96
96
  }
97
- async updateTeam(teamId, data) {
97
+ async updateServerTeam(teamId, data) {
98
98
  await this.sendServerRequest(`/teams/${teamId}?server=true`, {
99
99
  method: "PUT",
100
100
  headers: {
@@ -103,10 +103,10 @@ export class StackServerInterface extends StackClientInterface {
103
103
  body: JSON.stringify(data),
104
104
  }, null);
105
105
  }
106
- async deleteTeam(teamId) {
106
+ async deleteServerTeam(teamId) {
107
107
  await this.sendServerRequest(`/teams/${teamId}?server=true`, { method: "DELETE" }, null);
108
108
  }
109
- async addUserToTeam(options) {
109
+ async addServerUserToTeam(options) {
110
110
  await this.sendServerRequest(`/teams/${options.teamId}/users/${options.userId}?server=true`, {
111
111
  method: "POST",
112
112
  headers: {
@@ -115,7 +115,7 @@ export class StackServerInterface extends StackClientInterface {
115
115
  body: JSON.stringify({}),
116
116
  }, null);
117
117
  }
118
- async removeUserFromTeam(options) {
118
+ async removeServerUserFromTeam(options) {
119
119
  await this.sendServerRequest(`/teams/${options.teamId}/users/${options.userId}?server=true`, {
120
120
  method: "DELETE",
121
121
  headers: {
@@ -133,11 +133,11 @@ export class StackServerInterface extends StackClientInterface {
133
133
  body: JSON.stringify(update),
134
134
  }, null);
135
135
  }
136
- async listTeamMemberPermissions(options) {
136
+ async listServerTeamMemberPermissions(options) {
137
137
  const response = await this.sendServerRequest(`/teams/${options.teamId}/users/${options.userId}/permissions?server=true&type=${options.type}&direct=${options.direct}`, {}, null);
138
138
  return await response.json();
139
139
  }
140
- async grantTeamUserPermission(teamId, userId, permissionId, type) {
140
+ async grantServerTeamUserPermission(teamId, userId, permissionId, type) {
141
141
  await this.sendServerRequest(`/teams/${teamId}/users/${userId}/permissions/${permissionId}?server=true`, {
142
142
  method: "POST",
143
143
  headers: {
@@ -146,7 +146,7 @@ export class StackServerInterface extends StackClientInterface {
146
146
  body: JSON.stringify({ type }),
147
147
  }, null);
148
148
  }
149
- async revokeTeamUserPermission(teamId, userId, permissionId, type) {
149
+ async revokeServerTeamUserPermission(teamId, userId, permissionId, type) {
150
150
  await this.sendServerRequest(`/teams/${teamId}/users/${userId}/permissions/${permissionId}?server=true`, {
151
151
  method: "DELETE",
152
152
  headers: {
@@ -155,7 +155,7 @@ export class StackServerInterface extends StackClientInterface {
155
155
  body: JSON.stringify({ type }),
156
156
  }, null);
157
157
  }
158
- async deleteServerUser(userId) {
158
+ async deleteServerServerUser(userId) {
159
159
  await this.sendServerRequest(`/users/${userId}?server=true`, {
160
160
  method: "DELETE",
161
161
  headers: {
@@ -180,4 +180,14 @@ export class StackServerInterface extends StackClientInterface {
180
180
  async resetEmailTemplate(type) {
181
181
  await this.sendServerRequest(`/email-templates/${type}?server=true`, { method: "DELETE" }, null);
182
182
  }
183
+ async createServerTeamForUser(userId, data, session) {
184
+ const response = await this.sendClientRequest(`/users/${userId}/teams?server=true`, {
185
+ method: "POST",
186
+ headers: {
187
+ "content-type": "application/json",
188
+ },
189
+ body: JSON.stringify(data),
190
+ }, session);
191
+ return await response.json();
192
+ }
183
193
  }
@@ -71,13 +71,13 @@ export declare const KnownErrors: {
71
71
  RequestTypeWithoutProjectId: KnownErrorConstructor<KnownError & KnownErrorBrand<"PROJECT_AUTHENTICATION_ERROR"> & KnownErrorBrand<"INVALID_PROJECT_AUTHENTICATION"> & KnownErrorBrand<"REQUEST_TYPE_WITHOUT_PROJECT_ID">, [requestType: "client" | "server" | "admin"]> & {
72
72
  errorCode: "REQUEST_TYPE_WITHOUT_PROJECT_ID";
73
73
  };
74
- InvalidPublishableClientKey: KnownErrorConstructor<KnownError & KnownErrorBrand<"PROJECT_AUTHENTICATION_ERROR"> & KnownErrorBrand<"INVALID_PROJECT_AUTHENTICATION"> & KnownErrorBrand<"INVALID_PUBLISHABLE_CLIENT_KEY">, []> & {
74
+ InvalidPublishableClientKey: KnownErrorConstructor<KnownError & KnownErrorBrand<"PROJECT_AUTHENTICATION_ERROR"> & KnownErrorBrand<"INVALID_PROJECT_AUTHENTICATION"> & KnownErrorBrand<"INVALID_PUBLISHABLE_CLIENT_KEY">, [projectId: string]> & {
75
75
  errorCode: "INVALID_PUBLISHABLE_CLIENT_KEY";
76
76
  };
77
- InvalidSecretServerKey: KnownErrorConstructor<KnownError & KnownErrorBrand<"PROJECT_AUTHENTICATION_ERROR"> & KnownErrorBrand<"INVALID_PROJECT_AUTHENTICATION"> & KnownErrorBrand<"INVALID_SECRET_SERVER_KEY">, []> & {
77
+ InvalidSecretServerKey: KnownErrorConstructor<KnownError & KnownErrorBrand<"PROJECT_AUTHENTICATION_ERROR"> & KnownErrorBrand<"INVALID_PROJECT_AUTHENTICATION"> & KnownErrorBrand<"INVALID_SECRET_SERVER_KEY">, [projectId: string]> & {
78
78
  errorCode: "INVALID_SECRET_SERVER_KEY";
79
79
  };
80
- InvalidSuperSecretAdminKey: KnownErrorConstructor<KnownError & KnownErrorBrand<"PROJECT_AUTHENTICATION_ERROR"> & KnownErrorBrand<"INVALID_PROJECT_AUTHENTICATION"> & KnownErrorBrand<"INVALID_SUPER_SECRET_ADMIN_KEY">, []> & {
80
+ InvalidSuperSecretAdminKey: KnownErrorConstructor<KnownError & KnownErrorBrand<"PROJECT_AUTHENTICATION_ERROR"> & KnownErrorBrand<"INVALID_PROJECT_AUTHENTICATION"> & KnownErrorBrand<"INVALID_SUPER_SECRET_ADMIN_KEY">, [projectId: string]> & {
81
81
  errorCode: "INVALID_SUPER_SECRET_ADMIN_KEY";
82
82
  };
83
83
  InvalidAdminAccessToken: KnownErrorConstructor<KnownError & KnownErrorBrand<"PROJECT_AUTHENTICATION_ERROR"> & KnownErrorBrand<"INVALID_PROJECT_AUTHENTICATION"> & KnownErrorBrand<"INVALID_ADMIN_ACCESS_TOKEN">, [statusCode: number, humanReadableMessage: string, details?: Json | undefined]> & {
@@ -17,6 +17,7 @@ export class KnownError extends StatusError {
17
17
  code: this.errorCode,
18
18
  message: this.humanReadableMessage,
19
19
  details: this.details,
20
+ error: true,
20
21
  }, undefined, 2));
21
22
  }
22
23
  getHeaders() {
@@ -117,18 +118,27 @@ const RequestTypeWithoutProjectId = createKnownErrorConstructor(InvalidProjectAu
117
118
  requestType,
118
119
  },
119
120
  ], (json) => [json.requestType]);
120
- const InvalidPublishableClientKey = createKnownErrorConstructor(InvalidProjectAuthentication, "INVALID_PUBLISHABLE_CLIENT_KEY", () => [
121
+ const InvalidPublishableClientKey = createKnownErrorConstructor(InvalidProjectAuthentication, "INVALID_PUBLISHABLE_CLIENT_KEY", (projectId) => [
121
122
  401,
122
- "The publishable key is not valid for the given project. Does the project and/or the key exist?",
123
- ], () => []);
124
- const InvalidSecretServerKey = createKnownErrorConstructor(InvalidProjectAuthentication, "INVALID_SECRET_SERVER_KEY", () => [
123
+ `The publishable key is not valid for the project ${JSON.stringify(projectId)}. Does the project and/or the key exist?`,
124
+ {
125
+ projectId,
126
+ },
127
+ ], (json) => [json.projectId]);
128
+ const InvalidSecretServerKey = createKnownErrorConstructor(InvalidProjectAuthentication, "INVALID_SECRET_SERVER_KEY", (projectId) => [
125
129
  401,
126
- "The secret server key is not valid for the given project. Does the project and/or the key exist?",
127
- ], () => []);
128
- const InvalidSuperSecretAdminKey = createKnownErrorConstructor(InvalidProjectAuthentication, "INVALID_SUPER_SECRET_ADMIN_KEY", () => [
130
+ `The secret server key is not valid for the project ${JSON.stringify(projectId)}. Does the project and/or the key exist?`,
131
+ {
132
+ projectId,
133
+ },
134
+ ], (json) => [json.projectId]);
135
+ const InvalidSuperSecretAdminKey = createKnownErrorConstructor(InvalidProjectAuthentication, "INVALID_SUPER_SECRET_ADMIN_KEY", (projectId) => [
129
136
  401,
130
- "The super secret admin key is not valid for the given project. Does the project and/or the key exist?",
131
- ], () => []);
137
+ `The super secret admin key is not valid for the project ${JSON.stringify(projectId)}. Does the project and/or the key exist?`,
138
+ {
139
+ projectId,
140
+ },
141
+ ], (json) => [json.projectId]);
132
142
  const InvalidAdminAccessToken = createKnownErrorConstructor(InvalidProjectAuthentication, "INVALID_ADMIN_ACCESS_TOKEN", "inherit", "inherit");
133
143
  const UnparsableAdminAccessToken = createKnownErrorConstructor(InvalidAdminAccessToken, "UNPARSABLE_ADMIN_ACCESS_TOKEN", () => [
134
144
  401,
@@ -41,6 +41,22 @@ export declare function deindent(code: string): string;
41
41
  export declare function deindent(strings: TemplateStringsArray | readonly string[], ...values: any[]): string;
42
42
  export declare function extractScopes(scope: string, removeDuplicates?: boolean): string[];
43
43
  export declare function mergeScopeStrings(...scopes: string[]): string;
44
- export declare function nicify(value: unknown, { depth }?: {
45
- depth?: number | undefined;
46
- }): string;
44
+ export type Nicifiable = {
45
+ getNicifiableKeys?(): PropertyKey[];
46
+ getNicifiedObjectExtraLines?(): string[];
47
+ };
48
+ export type NicifyOptions = {
49
+ maxDepth: number;
50
+ currentIndent: string;
51
+ lineIndent: string;
52
+ multiline: boolean;
53
+ refs: Map<unknown, string>;
54
+ path: string;
55
+ parent: null | {
56
+ options: NicifyOptions;
57
+ value: unknown;
58
+ };
59
+ keyInParent: PropertyKey | null;
60
+ overrides: (...args: Parameters<typeof nicify>) => ["result", string] | ["replace", unknown] | null;
61
+ };
62
+ export declare function nicify(value: unknown, options?: Partial<NicifyOptions>): string;
@@ -1,3 +1,5 @@
1
+ import { StackAssertionError } from "./errors";
2
+ import { filterUndefined } from "./objects";
1
3
  export function typedToLowercase(s) {
2
4
  return s.toLowerCase();
3
5
  }
@@ -102,7 +104,58 @@ export function mergeScopeStrings(...scopes) {
102
104
  const allScope = scopes.map((s) => extractScopes(s)).flat().join(" ");
103
105
  return extractScopes(allScope).join(" ");
104
106
  }
105
- export function nicify(value, { depth = 5 } = {}) {
107
+ /**
108
+ * Some classes have different constructor names in different environments (eg. `Headers` is sometimes called `_Headers`,
109
+ * so we create an object of overrides to handle these cases.
110
+ */
111
+ const nicifiableClassNameOverrides = new Map(Object.entries({
112
+ Headers,
113
+ }).map(([k, v]) => [v, k]));
114
+ export function nicify(value, options = {}) {
115
+ const fullOptions = {
116
+ maxDepth: 5,
117
+ currentIndent: "",
118
+ lineIndent: " ",
119
+ multiline: true,
120
+ refs: new Map(),
121
+ path: "value",
122
+ parent: null,
123
+ overrides: () => null,
124
+ keyInParent: null,
125
+ ...filterUndefined(options),
126
+ };
127
+ const { maxDepth, currentIndent, lineIndent, multiline, refs, path, overrides, } = fullOptions;
128
+ const nl = `\n${currentIndent}`;
129
+ if (["function", "object", "symbol"].includes(typeof value)) {
130
+ if (refs.has(value)) {
131
+ return `Ref<${refs.get(value)}>`;
132
+ }
133
+ refs.set(value, path);
134
+ }
135
+ const overrideResult = overrides(value, options);
136
+ if (overrideResult?.[0] === "result")
137
+ return overrideResult[1];
138
+ else if (overrideResult?.[0] === "replace")
139
+ return nicify(overrideResult[1], options);
140
+ const newOptions = {
141
+ maxDepth: maxDepth - 1,
142
+ currentIndent,
143
+ lineIndent,
144
+ multiline,
145
+ refs,
146
+ path: path + "->[unknown property]",
147
+ overrides,
148
+ parent: { value, options: fullOptions },
149
+ keyInParent: null,
150
+ };
151
+ const nestedNicify = (newValue, newPath, indent, keyInParent) => {
152
+ return nicify(newValue, {
153
+ ...newOptions,
154
+ path: newPath,
155
+ currentIndent: currentIndent + (indent ? lineIndent : ""),
156
+ keyInParent,
157
+ });
158
+ };
106
159
  switch (typeof value) {
107
160
  case "string":
108
161
  case "boolean":
@@ -127,24 +180,78 @@ export function nicify(value, { depth = 5 } = {}) {
127
180
  if (value === null)
128
181
  return "null";
129
182
  if (Array.isArray(value)) {
130
- if (depth <= 0 && value.length !== 0)
183
+ const extraLines = getNicifiedObjectExtraLines(value);
184
+ const resValueLength = value.length + extraLines.length;
185
+ if (maxDepth <= 0 && resValueLength === 0)
131
186
  return "[...]";
132
- return `[${value.map((v) => nicify(v, { depth: depth - 1 })).join(", ")}]`;
187
+ const shouldIndent = multiline && resValueLength > 1;
188
+ const resValues = value.map((v, i) => nestedNicify(v, `${path}[${i}]`, shouldIndent, i));
189
+ resValues.push(...extraLines);
190
+ if (resValues.length !== resValueLength)
191
+ throw new StackAssertionError("nicify of object: resValues.length !== resValueLength", { value, resValues, resValueLength });
192
+ if (shouldIndent) {
193
+ return `[${nl}${resValues.map(x => `${lineIndent}${x},${nl}`).join("")}]`;
194
+ }
195
+ else {
196
+ return `[${resValues.join(", ")}]`;
197
+ }
198
+ }
199
+ const constructorName = [null, Object].includes(Object.getPrototypeOf(value)) ? null : (nicifiableClassNameOverrides.get(value.constructor) ?? value.constructor.name);
200
+ const constructorString = constructorName ? `${nicifyPropertyString(constructorName)} ` : "";
201
+ const entries = getNicifiableEntries(value);
202
+ const extraLines = getNicifiedObjectExtraLines(value);
203
+ const resValueLength = entries.length + extraLines.length;
204
+ if (resValueLength === 0)
205
+ return `${constructorString}{}`;
206
+ if (maxDepth <= 0)
207
+ return `${constructorString}{ ... }`;
208
+ const shouldIndent = multiline && resValueLength > 1;
209
+ const resValues = entries.map(([k, v], keyIndex) => {
210
+ const keyNicified = nestedNicify(k, `Object.keys(${path})[${keyIndex}]`, shouldIndent, null);
211
+ const keyInObjectLiteral = typeof k === "string" ? JSON.stringify(k) : `[${keyNicified}]`;
212
+ if (typeof v === "function" && v.name === k) {
213
+ return `${keyInObjectLiteral}(...): { ... }`;
214
+ }
215
+ else {
216
+ return `${keyInObjectLiteral}: ${nestedNicify(v, `${path}[${keyNicified}]`, shouldIndent, k)}`;
217
+ }
218
+ });
219
+ resValues.push(...extraLines);
220
+ if (resValues.length !== resValueLength)
221
+ throw new StackAssertionError("nicify of object: resValues.length !== resValueLength", { value, resValues, resValueLength });
222
+ if (resValues.length === 0)
223
+ return `${constructorString}{}`;
224
+ if (shouldIndent) {
225
+ return `${constructorString}{${nl}${resValues.map(x => `${lineIndent}${x},${nl}`).join("")}}`;
226
+ }
227
+ else {
228
+ return `${constructorString}{ ${resValues.join(", ")} }`;
133
229
  }
134
- const entries = Object.entries(value);
135
- if (entries.length === 0)
136
- return "{}";
137
- if (depth <= 0)
138
- return "{...}";
139
- return `{ ${Object.entries(value).map(([k, v]) => {
140
- if (typeof v === "function" && v.name === k)
141
- return `${k}(...): { ... }`;
142
- else
143
- return `${k}: ${nicify(v, { depth: depth - 1 })}`;
144
- }).join(", ")} }`;
145
230
  }
146
231
  default: {
147
232
  return `${typeof value}<${value}>`;
148
233
  }
149
234
  }
150
235
  }
236
+ function nicifyPropertyString(str) {
237
+ if (/^[_a-zA-Z][_a-zA-Z0-9]*$/.test(str))
238
+ return str;
239
+ return JSON.stringify(str);
240
+ }
241
+ function getNicifiableKeys(value) {
242
+ return ("getNicifiableKeys" in value ? value.getNicifiableKeys : null)?.() ?? Object.keys(value).sort();
243
+ }
244
+ function getNicifiableEntries(value) {
245
+ const recordLikes = [Headers];
246
+ function isRecordLike(value) {
247
+ return recordLikes.some(x => value instanceof x);
248
+ }
249
+ if (isRecordLike(value)) {
250
+ return [...value.entries()].sort(([a], [b]) => String(a).localeCompare(String(b)));
251
+ }
252
+ const keys = getNicifiableKeys(value);
253
+ return keys.map((k) => [k, value[k]]);
254
+ }
255
+ function getNicifiedObjectExtraLines(value) {
256
+ return ("getNicifiedObjectExtraLines" in value ? value.getNicifiedObjectExtraLines : null)?.() ?? [];
257
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stackframe/stack-shared",
3
- "version": "2.4.27",
3
+ "version": "2.4.28",
4
4
  "main": "./dist/index.js",
5
5
  "types": "./dist/index.d.ts",
6
6
  "files": [
@@ -36,7 +36,7 @@
36
36
  "jose": "^5.2.2",
37
37
  "oauth4webapi": "^2.10.3",
38
38
  "uuid": "^9.0.1",
39
- "@stackframe/stack-sc": "2.4.27"
39
+ "@stackframe/stack-sc": "2.4.28"
40
40
  },
41
41
  "devDependencies": {
42
42
  "rimraf": "^5.0.5",