alchemy 0.16.5 → 0.16.7

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.
Files changed (48) hide show
  1. package/lib/cloudflare/account-api-token.d.ts +1 -1
  2. package/lib/cloudflare/account-api-token.d.ts.map +1 -1
  3. package/lib/cloudflare/account-api-token.js.map +1 -1
  4. package/lib/cloudflare/account-id.d.ts +41 -0
  5. package/lib/cloudflare/account-id.d.ts.map +1 -0
  6. package/lib/cloudflare/account-id.js +40 -0
  7. package/lib/cloudflare/account-id.js.map +1 -0
  8. package/lib/cloudflare/index.d.ts +1 -0
  9. package/lib/cloudflare/index.d.ts.map +1 -1
  10. package/lib/cloudflare/index.js +1 -0
  11. package/lib/cloudflare/index.js.map +1 -1
  12. package/lib/cloudflare/permission-groups.d.ts +1 -1
  13. package/lib/cloudflare/permission-groups.d.ts.map +1 -1
  14. package/lib/cloudflare/wrangler.json.d.ts +1 -1
  15. package/lib/cloudflare/wrangler.json.d.ts.map +1 -1
  16. package/lib/cloudflare/wrangler.json.js +1 -1
  17. package/lib/cloudflare/wrangler.json.js.map +1 -1
  18. package/lib/sentry/api.d.ts +50 -0
  19. package/lib/sentry/api.d.ts.map +1 -0
  20. package/lib/sentry/api.js +76 -0
  21. package/lib/sentry/api.js.map +1 -0
  22. package/lib/sentry/client-key.d.ts +156 -0
  23. package/lib/sentry/client-key.d.ts.map +1 -0
  24. package/lib/sentry/client-key.js +126 -0
  25. package/lib/sentry/client-key.js.map +1 -0
  26. package/lib/sentry/index.d.ts +5 -0
  27. package/lib/sentry/index.d.ts.map +1 -0
  28. package/lib/sentry/index.js +5 -0
  29. package/lib/sentry/index.js.map +1 -0
  30. package/lib/sentry/project.d.ts +235 -0
  31. package/lib/sentry/project.d.ts.map +1 -0
  32. package/lib/sentry/project.js +146 -0
  33. package/lib/sentry/project.js.map +1 -0
  34. package/lib/sentry/team.d.ts +109 -0
  35. package/lib/sentry/team.d.ts.map +1 -0
  36. package/lib/sentry/team.js +109 -0
  37. package/lib/sentry/team.js.map +1 -0
  38. package/package.json +2 -1
  39. package/src/cloudflare/account-api-token.ts +4 -1
  40. package/src/cloudflare/account-id.ts +48 -0
  41. package/src/cloudflare/index.ts +1 -0
  42. package/src/cloudflare/permission-groups.ts +1 -1
  43. package/src/cloudflare/wrangler.json.ts +2 -2
  44. package/src/sentry/api.ts +106 -0
  45. package/src/sentry/client-key.ts +295 -0
  46. package/src/sentry/index.ts +4 -0
  47. package/src/sentry/project.ts +420 -0
  48. package/src/sentry/team.ts +235 -0
@@ -0,0 +1,126 @@
1
+ import { Resource } from "../resource.js";
2
+ import { SentryApi } from "./api.js";
3
+ /**
4
+ * Create and manage Sentry client keys
5
+ *
6
+ * @example
7
+ * // Create a basic Sentry client key:
8
+ * const key = await ClientKey("my-key", {
9
+ * name: "My Key",
10
+ * project: "my-project",
11
+ * organization: "my-org"
12
+ * });
13
+ *
14
+ * @example
15
+ * // Create a client key with rate limiting:
16
+ * const key = await ClientKey("rate-limited-key", {
17
+ * name: "Rate Limited Key",
18
+ * project: "my-project",
19
+ * organization: "my-org",
20
+ * rateLimit: {
21
+ * window: 3600, // 1 hour
22
+ * count: 1000 // 1000 events per hour
23
+ * }
24
+ * });
25
+ *
26
+ * @example
27
+ * // Create a client key for a specific use case:
28
+ * const key = await ClientKey("profiling-key", {
29
+ * name: "Profiling Key",
30
+ * project: "my-project",
31
+ * organization: "my-org",
32
+ * useCase: "profiling"
33
+ * });
34
+ *
35
+ * @example
36
+ * // Create or adopt an existing key with the same name:
37
+ * const key = await ClientKey("existing-key", {
38
+ * name: "Existing Key",
39
+ * project: "my-project",
40
+ * organization: "my-org",
41
+ * adopt: true
42
+ * });
43
+ */
44
+ export const ClientKey = Resource("sentry::ClientKey", async function (id, props) {
45
+ const api = new SentryApi({ authToken: props.authToken });
46
+ if (this.phase === "delete") {
47
+ try {
48
+ if (this.output?.id) {
49
+ const response = await api.delete(`/projects/${props.organization}/${props.project}/keys/${this.output.id}/`);
50
+ if (!response.ok && response.status !== 404) {
51
+ console.error("Error deleting client key:", response.statusText);
52
+ }
53
+ }
54
+ }
55
+ catch (error) {
56
+ console.error("Error deleting client key:", error);
57
+ }
58
+ return this.destroy();
59
+ }
60
+ else {
61
+ try {
62
+ let response;
63
+ if (this.phase === "update" && this.output?.id) {
64
+ response = await api.put(`/projects/${props.organization}/${props.project}/keys/${this.output.id}/`, props);
65
+ }
66
+ else {
67
+ try {
68
+ response = await api.post(`/projects/${props.organization}/${props.project}/keys/`, props);
69
+ }
70
+ catch (error) {
71
+ // Check if this is a "key already exists" error and adopt is enabled
72
+ if (props.adopt &&
73
+ error instanceof Error &&
74
+ error.message.includes("already exists") &&
75
+ props.name) {
76
+ console.log(`Client key '${props.name}' already exists, adopting it`);
77
+ // Find the existing key by name
78
+ const existingKey = await findClientKeyByName(api, props.organization, props.project, props.name);
79
+ if (!existingKey) {
80
+ throw new Error(`Failed to find existing client key '${props.name}' for adoption`);
81
+ }
82
+ response = await api.get(`/projects/${props.organization}/${props.project}/keys/${existingKey.id}/`);
83
+ }
84
+ else {
85
+ throw error;
86
+ }
87
+ }
88
+ }
89
+ if (!response.ok) {
90
+ throw new Error(`API error: ${response.statusText}`);
91
+ }
92
+ const data = (await response.json());
93
+ return this({
94
+ ...props,
95
+ id: data.id,
96
+ label: data.label,
97
+ public: data.public,
98
+ secret: data.secret,
99
+ projectId: data.projectId,
100
+ isActive: data.isActive,
101
+ dsn: data.dsn,
102
+ browserSdkVersion: data.browserSdkVersion,
103
+ browserSdk: data.browserSdk,
104
+ dateCreated: data.dateCreated,
105
+ dynamicSdkLoaderOptions: data.dynamicSdkLoaderOptions,
106
+ });
107
+ }
108
+ catch (error) {
109
+ console.error("Error creating/updating client key:", error);
110
+ throw error;
111
+ }
112
+ }
113
+ });
114
+ /**
115
+ * Find a client key by name
116
+ */
117
+ async function findClientKeyByName(api, organization, project, name) {
118
+ const response = await api.get(`/projects/${organization}/${project}/keys/`);
119
+ if (!response.ok) {
120
+ throw new Error(`API error: ${response.statusText}`);
121
+ }
122
+ const keys = (await response.json());
123
+ const key = keys.find((k) => k.name === name);
124
+ return key ? { id: key.id } : null;
125
+ }
126
+ //# sourceMappingURL=client-key.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client-key.js","sourceRoot":"","sources":["../../src/sentry/client-key.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export * from "./api.js";
2
+ export * from "./client-key.js";
3
+ export * from "./project.js";
4
+ export * from "./team.js";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sentry/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC"}
@@ -0,0 +1,5 @@
1
+ export * from "./api.js";
2
+ export * from "./client-key.js";
3
+ export * from "./project.js";
4
+ export * from "./team.js";
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sentry/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,iBAAiB,CAAC;AAChC,cAAc,cAAc,CAAC;AAC7B,cAAc,WAAW,CAAC"}
@@ -0,0 +1,235 @@
1
+ import type { Context } from "../context.js";
2
+ import { Resource } from "../resource.js";
3
+ import type { Secret } from "../secret.js";
4
+ /**
5
+ * Properties for creating or updating a Project
6
+ */
7
+ export interface ProjectProps {
8
+ /**
9
+ * The name for the project
10
+ */
11
+ name: string;
12
+ /**
13
+ * Uniquely identifies a project and is used for the interface
14
+ */
15
+ slug?: string;
16
+ /**
17
+ * The platform for the project
18
+ */
19
+ platform?: string;
20
+ /**
21
+ * Whether to alert on every new issue
22
+ */
23
+ defaultRules?: boolean;
24
+ /**
25
+ * The team slug that owns the project
26
+ */
27
+ team: string;
28
+ /**
29
+ * The organization ID or slug that owns the project
30
+ */
31
+ organization: string;
32
+ /**
33
+ * Auth token to use (overrides environment variable)
34
+ */
35
+ authToken?: Secret;
36
+ /**
37
+ * Whether to adopt an existing project with the same slug if it exists
38
+ * If true and a project with the same slug exists, it will be adopted rather than creating a new one
39
+ *
40
+ * @default false
41
+ */
42
+ adopt?: boolean;
43
+ }
44
+ /**
45
+ * Output returned after Project creation/update
46
+ */
47
+ export interface Project extends Omit<Resource<"sentry::Project">, "team">, Omit<ProjectProps, "team"> {
48
+ /**
49
+ * The ID of the project
50
+ */
51
+ id: string;
52
+ /**
53
+ * The team that owns the project
54
+ */
55
+ team: {
56
+ id: string;
57
+ name: string;
58
+ slug: string;
59
+ };
60
+ /**
61
+ * All teams that have access to the project
62
+ */
63
+ teams: Array<{
64
+ id: string;
65
+ name: string;
66
+ slug: string;
67
+ }>;
68
+ /**
69
+ * Whether the project is bookmarked
70
+ */
71
+ isBookmarked: boolean;
72
+ /**
73
+ * Whether the current user is a member of the project
74
+ */
75
+ isMember: boolean;
76
+ /**
77
+ * Access permissions for the project
78
+ */
79
+ access: string[];
80
+ /**
81
+ * Whether the current user has access to the project
82
+ */
83
+ hasAccess: boolean;
84
+ /**
85
+ * Time at which the project was created
86
+ */
87
+ dateCreated: string;
88
+ /**
89
+ * List of environments in the project
90
+ */
91
+ environments: string[];
92
+ /**
93
+ * Event processing status
94
+ */
95
+ eventProcessing: {
96
+ symbolicationDegraded: boolean;
97
+ };
98
+ /**
99
+ * List of features enabled for the project
100
+ */
101
+ features: string[];
102
+ /**
103
+ * Whether the project has received its first event
104
+ */
105
+ firstEvent: string | null;
106
+ /**
107
+ * Whether the project has received its first transaction event
108
+ */
109
+ firstTransactionEvent: boolean;
110
+ /**
111
+ * Whether the project has sessions
112
+ */
113
+ hasSessions: boolean;
114
+ /**
115
+ * Whether the project has profiles
116
+ */
117
+ hasProfiles: boolean;
118
+ /**
119
+ * Whether the project has replays
120
+ */
121
+ hasReplays: boolean;
122
+ /**
123
+ * Whether the project has flags
124
+ */
125
+ hasFlags: boolean;
126
+ /**
127
+ * Whether the project has monitors
128
+ */
129
+ hasMonitors: boolean;
130
+ /**
131
+ * Whether the project has feedback
132
+ */
133
+ hasFeedbacks: boolean;
134
+ /**
135
+ * Whether the project has new feedback
136
+ */
137
+ hasNewFeedbacks: boolean;
138
+ /**
139
+ * Whether the project has minified stack traces
140
+ */
141
+ hasMinifiedStackTrace: boolean;
142
+ /**
143
+ * Whether the project has HTTP insights
144
+ */
145
+ hasInsightsHttp: boolean;
146
+ /**
147
+ * Whether the project has database insights
148
+ */
149
+ hasInsightsDb: boolean;
150
+ /**
151
+ * Whether the project has asset insights
152
+ */
153
+ hasInsightsAssets: boolean;
154
+ /**
155
+ * Whether the project has app start insights
156
+ */
157
+ hasInsightsAppStart: boolean;
158
+ /**
159
+ * Whether the project has screen load insights
160
+ */
161
+ hasInsightsScreenLoad: boolean;
162
+ /**
163
+ * Whether the project has vitals insights
164
+ */
165
+ hasInsightsVitals: boolean;
166
+ /**
167
+ * Whether the project has cache insights
168
+ */
169
+ hasInsightsCaches: boolean;
170
+ /**
171
+ * Whether the project has queue insights
172
+ */
173
+ hasInsightsQueues: boolean;
174
+ /**
175
+ * Whether the project has LLM monitoring
176
+ */
177
+ hasInsightsLlmMonitoring: boolean;
178
+ /**
179
+ * List of platforms in the project
180
+ */
181
+ platforms: string[];
182
+ /**
183
+ * Latest release information
184
+ */
185
+ latestRelease: string | null;
186
+ /**
187
+ * Whether the project has user reports
188
+ */
189
+ hasUserReports: boolean;
190
+ /**
191
+ * Latest deployment information
192
+ */
193
+ latestDeploys: string | null;
194
+ }
195
+ /**
196
+ * Create and manage Sentry projects
197
+ *
198
+ * @example
199
+ * // Create a basic Sentry project:
200
+ * const project = await Project("my-project", {
201
+ * name: "My Project",
202
+ * team: "my-team",
203
+ * organization: "my-org"
204
+ * });
205
+ *
206
+ * @example
207
+ * // Create a project for a specific platform:
208
+ * const project = await Project("js-project", {
209
+ * name: "JavaScript Project",
210
+ * team: "my-team",
211
+ * organization: "my-org",
212
+ * platform: "javascript"
213
+ * });
214
+ *
215
+ * @example
216
+ * // Create a project with a custom slug and disabled default rules:
217
+ * const project = await Project("custom-project", {
218
+ * name: "Custom Project",
219
+ * team: "my-team",
220
+ * organization: "my-org",
221
+ * slug: "custom-project-slug",
222
+ * defaultRules: false
223
+ * });
224
+ *
225
+ * @example
226
+ * // Create or adopt an existing project with the same slug:
227
+ * const project = await Project("existing-project", {
228
+ * name: "Existing Project",
229
+ * team: "my-team",
230
+ * organization: "my-org",
231
+ * adopt: true
232
+ * });
233
+ */
234
+ export declare const Project: (((this: any, id: string, props?: {}) => never) & (new (_: never) => never)) | ((this: Context<Project>, id: string, props: ProjectProps) => Promise<Project>);
235
+ //# sourceMappingURL=project.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../../src/sentry/project.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,146 @@
1
+ import { Resource } from "../resource.js";
2
+ import { SentryApi } from "./api.js";
3
+ /**
4
+ * Create and manage Sentry projects
5
+ *
6
+ * @example
7
+ * // Create a basic Sentry project:
8
+ * const project = await Project("my-project", {
9
+ * name: "My Project",
10
+ * team: "my-team",
11
+ * organization: "my-org"
12
+ * });
13
+ *
14
+ * @example
15
+ * // Create a project for a specific platform:
16
+ * const project = await Project("js-project", {
17
+ * name: "JavaScript Project",
18
+ * team: "my-team",
19
+ * organization: "my-org",
20
+ * platform: "javascript"
21
+ * });
22
+ *
23
+ * @example
24
+ * // Create a project with a custom slug and disabled default rules:
25
+ * const project = await Project("custom-project", {
26
+ * name: "Custom Project",
27
+ * team: "my-team",
28
+ * organization: "my-org",
29
+ * slug: "custom-project-slug",
30
+ * defaultRules: false
31
+ * });
32
+ *
33
+ * @example
34
+ * // Create or adopt an existing project with the same slug:
35
+ * const project = await Project("existing-project", {
36
+ * name: "Existing Project",
37
+ * team: "my-team",
38
+ * organization: "my-org",
39
+ * adopt: true
40
+ * });
41
+ */
42
+ export const Project = Resource("sentry::Project", async function (id, props) {
43
+ const api = new SentryApi({ authToken: props.authToken });
44
+ if (this.phase === "delete") {
45
+ try {
46
+ if (this.output?.id) {
47
+ const response = await api.delete(`/projects/${props.organization}/${this.output.slug || this.output.id}/`);
48
+ if (!response.ok && response.status !== 404) {
49
+ console.error("Error deleting project:", response.statusText);
50
+ }
51
+ }
52
+ }
53
+ catch (error) {
54
+ console.error("Error deleting project:", error);
55
+ }
56
+ return this.destroy();
57
+ }
58
+ else {
59
+ try {
60
+ let response;
61
+ if (this.phase === "update" && this.output?.id) {
62
+ response = await api.put(`/projects/${props.organization}/${this.output.slug || this.output.id}/`, props);
63
+ }
64
+ else {
65
+ try {
66
+ response = await api.post(`/teams/${props.organization}/${props.team}/projects/`, props);
67
+ }
68
+ catch (error) {
69
+ // Check if this is a "project already exists" error and adopt is enabled
70
+ if (props.adopt &&
71
+ error instanceof Error &&
72
+ error.message.includes("already exists")) {
73
+ console.log(`Project '${props.slug || props.name}' already exists, adopting it`);
74
+ // Find the existing project by slug
75
+ const existingProject = await findProjectBySlug(api, props.organization, props.slug || props.name);
76
+ if (!existingProject) {
77
+ throw new Error(`Failed to find existing project '${props.slug || props.name}' for adoption`);
78
+ }
79
+ response = await api.get(`/projects/${props.organization}/${existingProject.slug}/`);
80
+ }
81
+ else {
82
+ throw error;
83
+ }
84
+ }
85
+ }
86
+ if (!response.ok) {
87
+ throw new Error(`API error: ${response.statusText}`);
88
+ }
89
+ const data = (await response.json());
90
+ return this({
91
+ ...props,
92
+ id: data.id,
93
+ team: data.team,
94
+ teams: data.teams,
95
+ isBookmarked: data.isBookmarked,
96
+ isMember: data.isMember,
97
+ access: data.access,
98
+ hasAccess: data.hasAccess,
99
+ dateCreated: data.dateCreated,
100
+ environments: data.environments,
101
+ eventProcessing: data.eventProcessing,
102
+ features: data.features,
103
+ firstEvent: data.firstEvent,
104
+ firstTransactionEvent: data.firstTransactionEvent,
105
+ hasSessions: data.hasSessions,
106
+ hasProfiles: data.hasProfiles,
107
+ hasReplays: data.hasReplays,
108
+ hasFlags: data.hasFlags,
109
+ hasMonitors: data.hasMonitors,
110
+ hasFeedbacks: data.hasFeedbacks,
111
+ hasNewFeedbacks: data.hasNewFeedbacks,
112
+ hasMinifiedStackTrace: data.hasMinifiedStackTrace,
113
+ hasInsightsHttp: data.hasInsightsHttp,
114
+ hasInsightsDb: data.hasInsightsDb,
115
+ hasInsightsAssets: data.hasInsightsAssets,
116
+ hasInsightsAppStart: data.hasInsightsAppStart,
117
+ hasInsightsScreenLoad: data.hasInsightsScreenLoad,
118
+ hasInsightsVitals: data.hasInsightsVitals,
119
+ hasInsightsCaches: data.hasInsightsCaches,
120
+ hasInsightsQueues: data.hasInsightsQueues,
121
+ hasInsightsLlmMonitoring: data.hasInsightsLlmMonitoring,
122
+ platforms: data.platforms,
123
+ latestRelease: data.latestRelease,
124
+ hasUserReports: data.hasUserReports,
125
+ latestDeploys: data.latestDeploys,
126
+ });
127
+ }
128
+ catch (error) {
129
+ console.error("Error creating/updating project:", error);
130
+ throw error;
131
+ }
132
+ }
133
+ });
134
+ /**
135
+ * Find a project by slug
136
+ */
137
+ async function findProjectBySlug(api, organization, slug) {
138
+ const response = await api.get(`/projects/${organization}`);
139
+ if (!response.ok) {
140
+ throw new Error(`API error: ${response.statusText}`);
141
+ }
142
+ const projects = (await response.json());
143
+ const project = projects.find((p) => p.slug === slug);
144
+ return project ? { id: project.id, slug: project.slug } : null;
145
+ }
146
+ //# sourceMappingURL=project.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project.js","sourceRoot":"","sources":["../../src/sentry/project.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,109 @@
1
+ import type { Context } from "../context.js";
2
+ import { Resource } from "../resource.js";
3
+ import type { Secret } from "../secret.js";
4
+ /**
5
+ * Properties for creating or updating a Team
6
+ */
7
+ export interface TeamProps {
8
+ /**
9
+ * The name for the team
10
+ */
11
+ name: string;
12
+ /**
13
+ * Uniquely identifies a team and is used for the interface
14
+ */
15
+ slug?: string;
16
+ /**
17
+ * The organization ID or slug that owns the team
18
+ */
19
+ organization: string;
20
+ /**
21
+ * Auth token to use (overrides environment variable)
22
+ */
23
+ authToken?: Secret;
24
+ /**
25
+ * Whether to adopt an existing team with the same slug if it exists
26
+ * If true and a team with the same slug exists, it will be adopted rather than creating a new one
27
+ *
28
+ * @default false
29
+ */
30
+ adopt?: boolean;
31
+ }
32
+ /**
33
+ * Output returned after Team creation/update
34
+ */
35
+ export interface Team extends Resource<"sentry::Team">, TeamProps {
36
+ /**
37
+ * The ID of the team
38
+ */
39
+ id: string;
40
+ /**
41
+ * Time at which the team was created
42
+ */
43
+ dateCreated: string;
44
+ /**
45
+ * Whether the current user is a member of the team
46
+ */
47
+ isMember: boolean;
48
+ /**
49
+ * The role of the current user in the team
50
+ */
51
+ teamRole: string;
52
+ /**
53
+ * Team flags
54
+ */
55
+ flags: {
56
+ "idp:provisioned": boolean;
57
+ };
58
+ /**
59
+ * Access permissions for the team
60
+ */
61
+ access: string[];
62
+ /**
63
+ * Whether the current user has access to the team
64
+ */
65
+ hasAccess: boolean;
66
+ /**
67
+ * Whether the team membership is pending
68
+ */
69
+ isPending: boolean;
70
+ /**
71
+ * Number of members in the team
72
+ */
73
+ memberCount: number;
74
+ /**
75
+ * Team avatar information
76
+ */
77
+ avatar: {
78
+ avatarType: string;
79
+ avatarUuid: string | null;
80
+ };
81
+ }
82
+ /**
83
+ * Create and manage Sentry teams
84
+ *
85
+ * @example
86
+ * // Create a basic Sentry team:
87
+ * const team = await Team("my-team", {
88
+ * name: "My Team",
89
+ * organization: "my-org"
90
+ * });
91
+ *
92
+ * @example
93
+ * // Create a team with a custom slug:
94
+ * const team = await Team("custom-team", {
95
+ * name: "Custom Team",
96
+ * organization: "my-org",
97
+ * slug: "custom-team-slug"
98
+ * });
99
+ *
100
+ * @example
101
+ * // Create or adopt an existing team with the same slug:
102
+ * const team = await Team("existing-team", {
103
+ * name: "Existing Team",
104
+ * organization: "my-org",
105
+ * adopt: true
106
+ * });
107
+ */
108
+ export declare const Team: (((this: any, id: string, props?: {}) => never) & (new (_: never) => never)) | ((this: Context<Team>, id: string, props: TeamProps) => Promise<Team>);
109
+ //# sourceMappingURL=team.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"team.d.ts","sourceRoot":"","sources":["../../src/sentry/team.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAG3C;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,YAAY,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,IAAK,SAAQ,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS;IAC/D;;OAEG;IACH,EAAE,EAAE,MAAM,CAAC;IAEX;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,QAAQ,EAAE,OAAO,CAAC;IAElB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,KAAK,EAAE;QACL,iBAAiB,EAAE,OAAO,CAAC;KAC5B,CAAC;IAEF;;OAEG;IACH,MAAM,EAAE,MAAM,EAAE,CAAC;IAEjB;;OAEG;IACH,SAAS,EAAE,OAAO,CAAC;IAEnB;;OAEG;IACH,SAAS,EAAE,OAAO,CAAC;IAEnB;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,MAAM,EAAE;QACN,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;KAC3B,CAAC;CACH;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,IAAI,yFAGP,OAAO,CAAC,IAAI,CAAC,MACf,MAAM,SACH,SAAS,KACf,OAAO,CAAC,IAAI,CAAC,CAsFjB,CAAC"}