alchemy 0.16.5 → 0.16.6

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.
@@ -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"}
@@ -0,0 +1,109 @@
1
+ import { Resource } from "../resource.js";
2
+ import { SentryApi } from "./api.js";
3
+ /**
4
+ * Create and manage Sentry teams
5
+ *
6
+ * @example
7
+ * // Create a basic Sentry team:
8
+ * const team = await Team("my-team", {
9
+ * name: "My Team",
10
+ * organization: "my-org"
11
+ * });
12
+ *
13
+ * @example
14
+ * // Create a team with a custom slug:
15
+ * const team = await Team("custom-team", {
16
+ * name: "Custom Team",
17
+ * organization: "my-org",
18
+ * slug: "custom-team-slug"
19
+ * });
20
+ *
21
+ * @example
22
+ * // Create or adopt an existing team with the same slug:
23
+ * const team = await Team("existing-team", {
24
+ * name: "Existing Team",
25
+ * organization: "my-org",
26
+ * adopt: true
27
+ * });
28
+ */
29
+ export const Team = Resource("sentry::Team", async function (id, props) {
30
+ const api = new SentryApi({ authToken: props.authToken });
31
+ if (this.phase === "delete") {
32
+ try {
33
+ if (this.output?.id) {
34
+ const response = await api.delete(`/teams/${props.organization}/${this.output.slug || this.output.id}/`);
35
+ if (!response.ok && response.status !== 404) {
36
+ console.error("Error deleting team:", response.statusText);
37
+ }
38
+ }
39
+ }
40
+ catch (error) {
41
+ console.error("Error deleting team:", error);
42
+ }
43
+ return this.destroy();
44
+ }
45
+ else {
46
+ try {
47
+ let response;
48
+ if (this.phase === "update" && this.output?.id) {
49
+ response = await api.put(`/teams/${props.organization}/${this.output.slug || this.output.id}/`, props);
50
+ }
51
+ else {
52
+ try {
53
+ response = await api.post(`/organizations/${props.organization}/teams/`, props);
54
+ }
55
+ catch (error) {
56
+ // Check if this is a "team already exists" error and adopt is enabled
57
+ if (props.adopt &&
58
+ error instanceof Error &&
59
+ error.message.includes("already exists")) {
60
+ console.log(`Team '${props.slug || props.name}' already exists, adopting it`);
61
+ // Find the existing team by slug
62
+ const existingTeam = await findTeamBySlug(api, props.organization, props.slug || props.name);
63
+ if (!existingTeam) {
64
+ throw new Error(`Failed to find existing team '${props.slug || props.name}' for adoption`);
65
+ }
66
+ response = await api.get(`/organizations/${props.organization}/teams/${existingTeam.slug}/`);
67
+ }
68
+ else {
69
+ throw error;
70
+ }
71
+ }
72
+ }
73
+ if (!response.ok) {
74
+ throw new Error(`API error: ${response.statusText}`);
75
+ }
76
+ const data = (await response.json());
77
+ return this({
78
+ ...props,
79
+ id: data.id,
80
+ dateCreated: data.dateCreated,
81
+ isMember: data.isMember,
82
+ teamRole: data.teamRole,
83
+ flags: data.flags,
84
+ access: data.access,
85
+ hasAccess: data.hasAccess,
86
+ isPending: data.isPending,
87
+ memberCount: data.memberCount,
88
+ avatar: data.avatar,
89
+ });
90
+ }
91
+ catch (error) {
92
+ console.error("Error creating/updating team:", error);
93
+ throw error;
94
+ }
95
+ }
96
+ });
97
+ /**
98
+ * Find a team by slug
99
+ */
100
+ async function findTeamBySlug(api, organization, slug) {
101
+ const response = await api.get(`/teams/${organization}/${slug}/`);
102
+ if (!response.ok) {
103
+ throw new Error(`API error: ${response.statusText}`);
104
+ }
105
+ const teams = (await response.json());
106
+ const team = teams.find((t) => t.slug === slug);
107
+ return team ? { id: team.id, slug: team.slug } : null;
108
+ }
109
+ //# sourceMappingURL=team.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"team.js","sourceRoot":"","sources":["../../src/sentry/team.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "alchemy",
3
- "version": "0.16.5",
3
+ "version": "0.16.6",
4
4
  "type": "module",
5
5
  "module": "./lib/index.js",
6
6
  "scripts": {
@@ -23,6 +23,7 @@
23
23
  "./github": "./lib/github/index.js",
24
24
  "./neon": "./lib/neon/index.js",
25
25
  "./os": "./lib/os/index.js",
26
+ "./sentry": "./lib/sentry/index.js",
26
27
  "./shadcn": "./lib/shadcn/index.js",
27
28
  "./stripe": "./lib/stripe/index.js",
28
29
  "./test/bun": "./lib/test/bun.js",
@@ -0,0 +1,106 @@
1
+ import { alchemy } from "../alchemy.js";
2
+ import type { Secret } from "../secret.js";
3
+
4
+ /**
5
+ * Options for Sentry API requests
6
+ */
7
+ export interface SentryApiOptions {
8
+ /**
9
+ * Auth token to use (overrides environment variable)
10
+ */
11
+ authToken?: Secret;
12
+ }
13
+
14
+ /**
15
+ * Minimal API client using raw fetch
16
+ */
17
+ export class SentryApi {
18
+ /** Base URL for API */
19
+ readonly baseUrl: string;
20
+
21
+ /** Auth token */
22
+ readonly authToken: Secret;
23
+
24
+ /**
25
+ * Create a new API client
26
+ *
27
+ * @param options API options
28
+ */
29
+ constructor(options: SentryApiOptions = {}) {
30
+ this.baseUrl = "https://sentry.io/api/0";
31
+ this.authToken =
32
+ options.authToken ?? alchemy.secret(process.env.SENTRY_AUTH_TOKEN || "");
33
+
34
+ if (!this.authToken.unencrypted) {
35
+ throw new Error("SENTRY_AUTH_TOKEN environment variable is required");
36
+ }
37
+ }
38
+
39
+ /**
40
+ * Make a request to the API
41
+ *
42
+ * @param path API path (without base URL)
43
+ * @param init Fetch init options
44
+ * @returns Raw Response object from fetch
45
+ */
46
+ async fetch(path: string, init: RequestInit = {}): Promise<Response> {
47
+ const headers: Record<string, string> = {
48
+ "Content-Type": "application/json",
49
+ Authorization: `Bearer ${this.authToken.unencrypted}`,
50
+ };
51
+
52
+ if (init.headers) {
53
+ const initHeaders = init.headers as Record<string, string>;
54
+ Object.keys(initHeaders).forEach((key) => {
55
+ headers[key] = initHeaders[key];
56
+ });
57
+ }
58
+
59
+ if (init.body instanceof FormData) {
60
+ delete headers["Content-Type"];
61
+ }
62
+
63
+ return fetch(`${this.baseUrl}${path}`, {
64
+ ...init,
65
+ headers,
66
+ });
67
+ }
68
+
69
+ /**
70
+ * Helper for GET requests
71
+ */
72
+ async get(path: string, init: RequestInit = {}): Promise<Response> {
73
+ return this.fetch(path, { ...init, method: "GET" });
74
+ }
75
+
76
+ /**
77
+ * Helper for POST requests
78
+ */
79
+ async post(
80
+ path: string,
81
+ body: any,
82
+ init: RequestInit = {},
83
+ ): Promise<Response> {
84
+ const requestBody = body instanceof FormData ? body : JSON.stringify(body);
85
+ return this.fetch(path, { ...init, method: "POST", body: requestBody });
86
+ }
87
+
88
+ /**
89
+ * Helper for PUT requests
90
+ */
91
+ async put(
92
+ path: string,
93
+ body: any,
94
+ init: RequestInit = {},
95
+ ): Promise<Response> {
96
+ const requestBody = body instanceof FormData ? body : JSON.stringify(body);
97
+ return this.fetch(path, { ...init, method: "PUT", body: requestBody });
98
+ }
99
+
100
+ /**
101
+ * Helper for DELETE requests
102
+ */
103
+ async delete(path: string, init: RequestInit = {}): Promise<Response> {
104
+ return this.fetch(path, { ...init, method: "DELETE" });
105
+ }
106
+ }