History

Make custom tools lint clean

Rhys Sullivan committed 4 months ago

Commit f754da51 parent 2a35fef33 files · +681 −549Browse files

Showing the changes to packages/plugins/apps/src/source/github-source.ts (1 of 33 files). Show all

Unified · Split

packages/plugins/apps/src/source/github-source.ts+81−74
@@ -1,4 +1,4 @@
1−import { Data, Effect, Result } from "effect";
1+import { Data, Effect, Predicate, Result, Schema } from "effect";
22
33 import { PublishError, type FileDiagnostic } from "../pipeline/discover";
44 import { PUBLISH_LIMITS, enforcePublishLimits } from "../pipeline/publish";
@@ -106,37 +106,42 @@ const requestJson = <A>( · 101 unmodified lines
106106 input: GitHubSourceInput,
107107 path: string,
108108 ): Effect.Effect<A, GitHubSourceError> =>
109− Effect.tryPromise({
110− try: async () => {
111− const fetchImpl = input.fetch ?? globalThis.fetch;
112− const headers: Record<string, string> = {
113− accept: "application/vnd.github+json",
114− "user-agent": "executor-apps-github-source",
115− };
116− if (input.token) headers.authorization = `Bearer ${input.token}`;
117− const response = await fetchImpl(
118− `${trimBaseUrl(input.baseUrl ?? "https://api.github.com")}${path}`,
119− {
109+ Effect.gen(function* () {
110+ const response = yield* Effect.tryPromise({
111+ try: async () => {
112+ const fetchImpl = input.fetch ?? globalThis.fetch;
113+ const headers: Record<string, string> = {
114+ accept: "application/vnd.github+json",
115+ "user-agent": "executor-apps-github-source",
116+ };
117+ if (input.token) headers.authorization = `Bearer ${input.token}`;
118+ return fetchImpl(`${trimBaseUrl(input.baseUrl ?? "https://api.github.com")}${path}`, {
120119 headers,
121− },
122− );
123− if (!response.ok) {
124− throw new GitHubSourceError({
125− message: `GitHub request failed: GET ${path} -> ${response.status}`,
126− status: response.status,
127− path,
128120 });
129− }
130− return (await response.json()) as A;
131− },
132− catch: (cause) =>
133− cause instanceof GitHubSourceError
134− ? cause
135− : new GitHubSourceError({
136− message: `GitHub request failed: GET ${path}`,
137− path,
138− cause,
139− }),
121+ },
122+ catch: (cause) =>
123+ new GitHubSourceError({
124+ message: `GitHub request failed: GET ${path}`,
125+ path,
126+ cause,
127+ }),
128+ });
129+ if (!response.ok) {
130+ return yield* new GitHubSourceError({
131+ message: `GitHub request failed: GET ${path} -> ${response.status}`,
132+ status: response.status,
133+ path,
134+ });
135+ }
136+ return yield* Effect.tryPromise({
137+ try: () => response.json() as Promise<A>,
138+ catch: (cause) =>
139+ new GitHubSourceError({
140+ message: `GitHub response was not valid JSON: GET ${path}`,
141+ path,
142+ cause,
143+ }),
144+ });
140145 });
141146
142147 interface RepoResponse {
@@ -254,42 +259,39 @@ const classifyTreeEntry = ( · 111 unmodified lines
254259 };
255260
256261 const decodeBlob = (path: string, blob: BlobResponse): Effect.Effect<string, GitHubSourceError> =>
257− Effect.try({
258− try: () => {
259− const encoding = asString(blob.encoding);
260− const content = asString(blob.content);
261− if (!content || encoding !== "base64") {
262− throw new GitHubSourceError({
263− message: `GitHub blob ${path} did not return base64 content`,
264− path,
265− });
266− }
267− return Buffer.from(content.replace(/\s/g, ""), "base64").toString("utf8");
268− },
269− catch: (cause) =>
270− cause instanceof GitHubSourceError
271− ? cause
272− : new GitHubSourceError({ message: `Failed to decode GitHub blob ${path}`, path, cause }),
262+ Effect.gen(function* () {
263+ const encoding = asString(blob.encoding);
264+ const content = asString(blob.content);
265+ if (!content || encoding !== "base64") {
266+ return yield* new GitHubSourceError({
267+ message: `GitHub blob ${path} did not return base64 content`,
268+ path,
269+ });
270+ }
271+ return Buffer.from(content.replace(/\s/g, ""), "base64").toString("utf8");
273272 });
274273
274+const decodeExecutorJson = Schema.decodeUnknownEffect(Schema.UnknownFromJsonString);
275+
275276 const executorDescription = (
276277 files: FileSet,
277278 ): Effect.Effect<string | undefined, GitHubSourceError> =>
278− Effect.try({
279− try: () => {
280− const raw = files.get("executor.json");
281− if (!raw) return undefined;
282− const parsed = JSON.parse(raw) as unknown;
283− if (!isRecord(parsed)) return undefined;
284− const description = parsed.description;
285− return typeof description === "string" ? description : undefined;
286− },
287− catch: (cause) =>
288− new GitHubSourceError({
289− message: "executor.json is not valid JSON",
290− path: "executor.json",
291− cause,
292− }),
279+ Effect.gen(function* () {
280+ const raw = files.get("executor.json");
281+ if (!raw) return undefined;
282+ const parsed = yield* decodeExecutorJson(raw).pipe(
283+ Effect.mapError(
284+ (cause) =>
285+ new GitHubSourceError({
286+ message: "executor.json is not valid JSON",
287+ path: "executor.json",
288+ cause,
289+ }),
290+ ),
291+ );
292+ if (!isRecord(parsed)) return undefined;
293+ const description = parsed.description;
294+ return typeof description === "string" ? description : undefined;
293295 });
294296
295297 export const fetchGitHubSource = (
@@ -336,7 +338,7 @@ export const fetchGitHubSource = ( · 40 unmodified lines
336338 else skipped.push(classified.skipped);
337339 }
338340 const treeLimitError = checkTreeLimits(entries);
339− if (treeLimitError) return yield* Effect.fail(treeLimitError);
341+ if (treeLimitError) return yield* treeLimitError;
340342
341343 const files = new Map<string, string>();
342344 for (const entry of entries) {
@@ -348,7 +350,7 @@ export const fetchGitHubSource = ( · 5 unmodified lines
348350 files.set(path, yield* decodeBlob(path, blob));
349351 }
350352 const payloadLimitError = enforcePublishLimits(files);
351− if (payloadLimitError) return yield* Effect.fail(payloadLimitError);
353+ if (payloadLimitError) return yield* payloadLimitError;
352354
353355 return {
354356 files,
@@ -360,17 +362,22 @@ export const fetchGitHubSource = ( · 5 unmodified lines
360362 };
361363 });
362364
363−const publishErrorToSyncError = (error: PublishError): SyncErrorData => ({
364− stage: error.stage,
365− message: error.message,
366− diagnostics: error.diagnostics,
367−});
365+const publishErrorToSyncError = (publishFailure: PublishError): SyncErrorData => {
366+ const stage = publishFailure.stage;
367+ const message = publishFailure.message;
368+ const diagnostics = publishFailure.diagnostics;
369+ return { stage, message, diagnostics };
370+};
368371
369−const sourceErrorToSyncError = (error: GitHubSourceError): SyncErrorData => ({
370− stage: "source",
371− message: error.message,
372− diagnostics: error.path ? [{ path: error.path, message: error.message }] : [],
373−});
372+const sourceErrorToSyncError = (sourceFailure: GitHubSourceError): SyncErrorData => {
373+ const message = sourceFailure.message;
374+ const path = sourceFailure.path;
375+ return {
376+ stage: "source",
377+ message,
378+ diagnostics: path ? [{ path, message }] : [],
379+ };
380+};
374381
375382 const sourceRef = (snapshot: GitHubSourceSnapshot, connection?: string): AppSourceRef => ({
376383 kind: "github",
@@ -391,7 +398,7 @@ export const syncGitHubSource = (input: SyncGitHubSourceInput): Effect.Effect<Gi · 14 unmodified lines
391398 tools: [],
392399 skipped: [],
393400 errors: [
394− error instanceof PublishError
401+ Predicate.isTagged("PublishError")(error)
395402 ? publishErrorToSyncError(error)
396403 : sourceErrorToSyncError(error),
397404 ],