@tahminator/pipeline 1.0.75 → 1.0.76-beta.023dc7b4

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/README.md CHANGED
@@ -38,6 +38,7 @@ import {
38
38
  EnvClient,
39
39
  GitHubClient,
40
40
  NPMClient,
41
+ ProtobufCompilerClient,
41
42
  PulumiClient,
42
43
  SonarScannerClient,
43
44
  Utils,
@@ -53,6 +54,7 @@ Jump to client documentation
53
54
 
54
55
  - [`GitHubClient`](#githubclient)
55
56
  - [`DockerClient`](#dockerclient)
57
+ - [`ProtobufCompilerClient`](#protobufcompilerclient)
56
58
  - [`NPMClient`](#npmclient)
57
59
  - [`SonarScannerClient`](#sonarscannerclient)
58
60
  - [`Utils`](#utils)
@@ -178,6 +180,32 @@ await client.promoteDockerImage({
178
180
  });
179
181
  ```
180
182
 
183
+ ### `ProtobufCompilerClient`
184
+
185
+ Generate protobuf clients with the [Buf CLI](https://buf.build/docs/installation/) and its remote plugins, then optionally upload them to a GitHub repository path. The client installs Buf globally with npm when necessary.
186
+
187
+ ```ts
188
+ const gh = await GitHubClient.createWithGithubAppToken({
189
+ appId: process.env.GH_APP_ID!,
190
+ privateKey: await Utils.decodeBase64EncodedString(
191
+ process.env.GH_PRIVATE_KEY_B64!,
192
+ ),
193
+ installationId: process.env.GH_INSTALLATION_ID!,
194
+ });
195
+ const protobuf = new ProtobufCompilerClient(gh);
196
+
197
+ await protobuf.compile({
198
+ sourceLanguage: ProtobufSourceLanguage.RUST,
199
+ bufToken: process.env.BUF_TOKEN,
200
+ targetLanguages: {
201
+ [ProtobufTargetLanguage.JAVA]: {
202
+ uploadLocation: "Patina-Network/proto-clients/java",
203
+ },
204
+ },
205
+ protoFilesLocation: "./proto",
206
+ });
207
+ ```
208
+
181
209
  ### `NPMClient`
182
210
 
183
211
  Interface with NPM registry in order to publish packages to `npmjs.com`
@@ -88,10 +88,10 @@ export declare class GitHubClient {
88
88
  */
89
89
  mergePr(...args: Parameters<GitHubPRManager["mergePr"]>): Promise<void>;
90
90
  /**
91
- * Create or update a check run (the "status checks" shown on a PR/commit), dispatched by
92
- * `action`.
91
+ * Create, update, or get a check run (the "status checks" shown on a PR/commit), dispatched
92
+ * by `args.action`.
93
93
  */
94
- writeStatusCheck(...args: Parameters<GitHubPRManager["writeStatusCheck"]>): Promise<{
94
+ statusCheck(...args: Parameters<GitHubPRManager["statusCheck"]>): Promise<{
95
95
  id: number;
96
96
  head_sha: string;
97
97
  node_id: string;
@@ -117,7 +117,14 @@ export declare class GitHubClient {
117
117
  app: import("@octokit/openapi-types").components["schemas"]["nullable-integration"];
118
118
  pull_requests: import("@octokit/openapi-types").components["schemas"]["pull-request-minimal"][];
119
119
  deployment?: import("@octokit/openapi-types").components["schemas"]["deployment-simple"];
120
- }>;
120
+ } | null>;
121
+ /**
122
+ * Uploads a local directory into a repository path using the authenticated GitHub API.
123
+ * Existing files under `directory` that are not present locally are deleted.
124
+ *
125
+ * **PLEASE DO NOT USE THIS FUNCTION UNLESS YOU KNOW WHAT YOU ARE DOING.**
126
+ */
127
+ DANGEROUS__uploadDirectoryContents(...args: Parameters<GitHubPRManager["uploadDirectoryContents"]>): Promise<void>;
121
128
  /**
122
129
  * Confirms whether the given user is an active member of a team within an org.
123
130
  *
package/dist/gh/client.js CHANGED
@@ -120,11 +120,20 @@ export class GitHubClient {
120
120
  return this.prManager.mergePr(...args);
121
121
  }
122
122
  /**
123
- * Create or update a check run (the "status checks" shown on a PR/commit), dispatched by
124
- * `action`.
123
+ * Create, update, or get a check run (the "status checks" shown on a PR/commit), dispatched
124
+ * by `args.action`.
125
125
  */
126
- writeStatusCheck(...args) {
127
- return this.prManager.writeStatusCheck(...args);
126
+ statusCheck(...args) {
127
+ return this.prManager.statusCheck(...args);
128
+ }
129
+ /**
130
+ * Uploads a local directory into a repository path using the authenticated GitHub API.
131
+ * Existing files under `directory` that are not present locally are deleted.
132
+ *
133
+ * **PLEASE DO NOT USE THIS FUNCTION UNLESS YOU KNOW WHAT YOU ARE DOING.**
134
+ */
135
+ DANGEROUS__uploadDirectoryContents(...args) {
136
+ return this.prManager.uploadDirectoryContents(...args);
128
137
  }
129
138
  /**
130
139
  * Confirms whether the given user is an active member of a team within an org.
@@ -7,7 +7,15 @@ type CheckRunOutput = {
7
7
  summary: string;
8
8
  text?: string;
9
9
  };
10
- type WriteStatusCheckArgs = {
10
+ type UploadDirectoryContentsArgs = {
11
+ owner: string;
12
+ repository: string;
13
+ sourceDirectory: string;
14
+ directory?: string;
15
+ message?: string;
16
+ branch?: string;
17
+ };
18
+ type StatusCheckArgs = {
11
19
  action: "create";
12
20
  owner: string;
13
21
  repository: string;
@@ -29,10 +37,20 @@ type WriteStatusCheckArgs = {
29
37
  conclusion?: CheckRunConclusion;
30
38
  output?: CheckRunOutput;
31
39
  detailsUrl?: string;
40
+ } | {
41
+ action: "get";
42
+ owner: string;
43
+ repository: string;
44
+ /**
45
+ * commit sha, branch name, or tag name
46
+ */
47
+ ref: string;
48
+ name: string;
32
49
  };
33
50
  export declare class GitHubPRManager {
34
51
  private readonly client;
35
52
  constructor(client: Octokit);
53
+ uploadDirectoryContents({ owner, repository, sourceDirectory, directory, message, branch, }: UploadDirectoryContentsArgs): Promise<void>;
36
54
  updateK8sTagWithPR({ newTag, imageName, kustomizationFilePath, environment, originRepo, manifestRepo, }: {
37
55
  newTag: string;
38
56
  imageName: string;
@@ -47,7 +65,7 @@ export declare class GitHubPRManager {
47
65
  repository: string;
48
66
  mergeMethod?: "merge" | "squash" | "rebase";
49
67
  }): Promise<void>;
50
- writeStatusCheck(args: WriteStatusCheckArgs): Promise<{
68
+ statusCheck(args: StatusCheckArgs): Promise<{
51
69
  id: number;
52
70
  head_sha: string;
53
71
  node_id: string;
@@ -73,12 +91,16 @@ export declare class GitHubPRManager {
73
91
  app: import("@octokit/openapi-types").components["schemas"]["nullable-integration"];
74
92
  pull_requests: import("@octokit/openapi-types").components["schemas"]["pull-request-minimal"][];
75
93
  deployment?: import("@octokit/openapi-types").components["schemas"]["deployment-simple"];
76
- }>;
94
+ } | null>;
77
95
  sendPrMessage({ prId, owner, repository, message, }: {
78
96
  prId: number;
79
97
  owner: string;
80
98
  repository: string;
81
99
  message: string;
82
100
  }): Promise<void>;
101
+ private createDirectoryTree;
102
+ private createDirectoryBlobEntries;
103
+ private getDirectoryPathPrefix;
104
+ private collectDirectoryFiles;
83
105
  }
84
106
  export {};
@@ -1,3 +1,5 @@
1
+ import { readdir, readFile } from "node:fs/promises";
2
+ import path from "node:path";
1
3
  import yaml from "yaml";
2
4
  import { Utils } from "../../utils";
3
5
  import { kustomizeSchema } from "./schema";
@@ -6,6 +8,47 @@ export class GitHubPRManager {
6
8
  constructor(client) {
7
9
  this.client = client;
8
10
  }
11
+ async uploadDirectoryContents({ owner, repository, sourceDirectory, directory = "", message = "chore: update generated files", branch, }) {
12
+ const { data: repo } = await this.client.rest.repos.get({
13
+ owner,
14
+ repo: repository,
15
+ });
16
+ const targetBranch = branch ?? repo.default_branch;
17
+ const { data: ref } = await this.client.rest.git.getRef({
18
+ owner,
19
+ repo: repository,
20
+ ref: `heads/${targetBranch}`,
21
+ });
22
+ const { data: baseCommit } = await this.client.rest.git.getCommit({
23
+ owner,
24
+ repo: repository,
25
+ commit_sha: ref.object.sha,
26
+ });
27
+ const treeSha = await this.createDirectoryTree({
28
+ directory,
29
+ owner,
30
+ repository,
31
+ sourceDirectory,
32
+ baseTreeSha: baseCommit.tree.sha,
33
+ });
34
+ if (treeSha === baseCommit.tree.sha) {
35
+ console.log("No directory changes to upload.");
36
+ return;
37
+ }
38
+ const { data: commit } = await this.client.rest.git.createCommit({
39
+ owner,
40
+ repo: repository,
41
+ message,
42
+ tree: treeSha,
43
+ parents: [ref.object.sha],
44
+ });
45
+ await this.client.rest.git.updateRef({
46
+ owner,
47
+ repo: repository,
48
+ ref: `heads/${targetBranch}`,
49
+ sha: commit.sha,
50
+ });
51
+ }
9
52
  async updateK8sTagWithPR({ newTag, imageName, kustomizationFilePath, environment, originRepo, manifestRepo, }) {
10
53
  const [manifestOwner, manifestRepository] = manifestRepo;
11
54
  const [originOwner, originRepository] = originRepo;
@@ -82,7 +125,7 @@ export class GitHubPRManager {
82
125
  merge_method: mergeMethod,
83
126
  });
84
127
  }
85
- async writeStatusCheck(args) {
128
+ async statusCheck(args) {
86
129
  switch (args.action) {
87
130
  case "create": {
88
131
  const { owner, repository, sha, name, status, conclusion, output, detailsUrl, } = args;
@@ -111,6 +154,16 @@ export class GitHubPRManager {
111
154
  });
112
155
  return data;
113
156
  }
157
+ case "get": {
158
+ const { owner, repository, ref, name } = args;
159
+ const { data } = await this.client.rest.checks.listForRef({
160
+ owner,
161
+ repo: repository,
162
+ ref,
163
+ check_name: name,
164
+ });
165
+ return data.check_runs[0] ?? null;
166
+ }
114
167
  }
115
168
  }
116
169
  async sendPrMessage({ prId, owner, repository, message, }) {
@@ -121,4 +174,84 @@ export class GitHubPRManager {
121
174
  body: message,
122
175
  });
123
176
  }
177
+ async createDirectoryTree({ owner, repository, sourceDirectory, directory, baseTreeSha, }) {
178
+ const pathPrefix = this.getDirectoryPathPrefix(directory);
179
+ const files = await this.collectDirectoryFiles(sourceDirectory);
180
+ const localPaths = new Set(files.map(({ relativePath }) => `${pathPrefix}${relativePath}`));
181
+ const { data: existingTree } = await this.client.rest.git.getTree({
182
+ owner,
183
+ repo: repository,
184
+ tree_sha: baseTreeSha,
185
+ recursive: "true",
186
+ });
187
+ const deletionEntries = existingTree.tree.flatMap((entry) => {
188
+ if (entry.type !== "blob" ||
189
+ !entry.path?.startsWith(pathPrefix) ||
190
+ localPaths.has(entry.path)) {
191
+ return [];
192
+ }
193
+ return [
194
+ {
195
+ path: entry.path,
196
+ mode: "100644",
197
+ type: "blob",
198
+ sha: null,
199
+ },
200
+ ];
201
+ });
202
+ const blobEntries = await this.createDirectoryBlobEntries({
203
+ files,
204
+ owner,
205
+ repository,
206
+ pathPrefix,
207
+ });
208
+ const { data: tree } = await this.client.rest.git.createTree({
209
+ owner,
210
+ repo: repository,
211
+ base_tree: baseTreeSha,
212
+ tree: [...deletionEntries, ...blobEntries],
213
+ });
214
+ return tree.sha;
215
+ }
216
+ async createDirectoryBlobEntries({ owner, repository, files, pathPrefix, }) {
217
+ return Promise.all(files.map(async ({ absolutePath, relativePath }) => {
218
+ const content = await readFile(absolutePath);
219
+ const { data: blob } = await this.client.rest.git.createBlob({
220
+ owner,
221
+ repo: repository,
222
+ content: content.toString("base64"),
223
+ encoding: "base64",
224
+ });
225
+ return {
226
+ path: `${pathPrefix}${relativePath}`,
227
+ mode: "100644",
228
+ type: "blob",
229
+ sha: blob.sha,
230
+ };
231
+ }));
232
+ }
233
+ getDirectoryPathPrefix(directory) {
234
+ const normalizedDirectory = directory.replace(/^\/+|\/+$/g, "");
235
+ return normalizedDirectory ? `${normalizedDirectory}/` : "";
236
+ }
237
+ async collectDirectoryFiles(directory, baseDirectory = directory) {
238
+ const files = [];
239
+ for (const entry of await readdir(directory, { withFileTypes: true })) {
240
+ const absolutePath = path.join(directory, entry.name);
241
+ if (entry.isDirectory()) {
242
+ files.push(...(await this.collectDirectoryFiles(absolutePath, baseDirectory)));
243
+ continue;
244
+ }
245
+ if (entry.isFile()) {
246
+ files.push({
247
+ absolutePath,
248
+ relativePath: path
249
+ .relative(baseDirectory, absolutePath)
250
+ .split(path.sep)
251
+ .join("/"),
252
+ });
253
+ }
254
+ }
255
+ return files;
256
+ }
124
257
  }
package/dist/index.d.ts CHANGED
@@ -3,6 +3,7 @@ export * from "./docker";
3
3
  export * from "./npm";
4
4
  export * from "./sonar";
5
5
  export * from "./pulumi";
6
+ export * from "./protobuf";
6
7
  export * from "./types";
7
8
  export * from "./env";
8
9
  export * from "./postgres";
package/dist/index.js CHANGED
@@ -3,6 +3,7 @@ export * from "./docker";
3
3
  export * from "./npm";
4
4
  export * from "./sonar";
5
5
  export * from "./pulumi";
6
+ export * from "./protobuf";
6
7
  export * from "./types";
7
8
  export * from "./env";
8
9
  export * from "./postgres";
@@ -0,0 +1,16 @@
1
+ import type { GitHubClient } from "../gh";
2
+ import { type ProtobufCompilerCompileArgs, type ProtobufCompilerCompileResult } from "./types";
3
+ export declare class ProtobufCompilerClient {
4
+ private readonly githubClient;
5
+ constructor(githubClient: GitHubClient);
6
+ compile({ bufToken, targetLanguages, protoFilesLocation, outputDirectory, }: ProtobufCompilerCompileArgs): Promise<ProtobufCompilerCompileResult>;
7
+ installToolchains(): Promise<void>;
8
+ private generateWithBuf;
9
+ private getCompilationTargets;
10
+ private getConfiguredTargetLanguages;
11
+ private getTargetLanguageStrategy;
12
+ private getBufGenerateInput;
13
+ private findBufModuleDirectory;
14
+ private uploadGeneratedDirectory;
15
+ private parseGitHubRepository;
16
+ }
@@ -0,0 +1,154 @@
1
+ import { $ } from "bun";
2
+ import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
3
+ import { tmpdir } from "node:os";
4
+ import path from "node:path";
5
+ import yaml from "yaml";
6
+ import { isCmdAvailable } from "../utils/cmd";
7
+ import { GoProtobufTargetLanguageStrategy, JavaProtobufTargetLanguageStrategy, RustProtobufTargetLanguageStrategy, } from "./strategy";
8
+ import { ProtobufTargetLanguage, } from "./types";
9
+ export class ProtobufCompilerClient {
10
+ githubClient;
11
+ constructor(githubClient) {
12
+ this.githubClient = githubClient;
13
+ }
14
+ async compile({ bufToken, targetLanguages, protoFilesLocation, outputDirectory, }) {
15
+ await this.installToolchains();
16
+ const outputDirectoryPath = path.resolve(outputDirectory ??
17
+ (await mkdtemp(path.join(tmpdir(), "protobuf-compiler-"))));
18
+ const targets = this.getCompilationTargets(targetLanguages);
19
+ await mkdir(outputDirectoryPath, { recursive: true });
20
+ await this.generateWithBuf({
21
+ bufToken,
22
+ outputDirectory: outputDirectoryPath,
23
+ protoFilesLocation,
24
+ targetStrategies: targets.map(({ strategy }) => strategy),
25
+ });
26
+ const generatedDirectories = {};
27
+ for (const { language, strategy } of targets) {
28
+ generatedDirectories[language] = path.join(outputDirectoryPath, strategy.outputDirectoryName);
29
+ }
30
+ for (const { language, options } of targets) {
31
+ if (!options.uploadLocation)
32
+ continue;
33
+ const generatedDirectory = generatedDirectories[language];
34
+ if (!generatedDirectory) {
35
+ throw new Error("Generated code directory was not created.");
36
+ }
37
+ await this.uploadGeneratedDirectory({
38
+ generatedDirectory,
39
+ options,
40
+ });
41
+ }
42
+ return { generatedDirectories, outputDirectory: outputDirectoryPath };
43
+ }
44
+ async installToolchains() {
45
+ if (!(await isCmdAvailable("buf"))) {
46
+ console.log("Buf is missing, installing globally via NPM...");
47
+ await $ `npm i -g @bufbuild/buf`;
48
+ }
49
+ }
50
+ async generateWithBuf({ bufToken, protoFilesLocation, outputDirectory, targetStrategies, }) {
51
+ const templateDirectory = await mkdtemp(path.join(tmpdir(), "protobuf-buf-template-"));
52
+ const templatePath = path.join(templateDirectory, "buf.gen.yaml");
53
+ const { input, pathFilter } = await this.getBufGenerateInput(protoFilesLocation);
54
+ const pathFlag = pathFilter ? ["--path", pathFilter] : [];
55
+ await writeFile(templatePath, yaml.stringify({
56
+ version: "v2",
57
+ plugins: targetStrategies.map((strategy) => ({
58
+ out: strategy.outputDirectoryName,
59
+ remote: strategy.remotePlugin,
60
+ })),
61
+ }));
62
+ try {
63
+ const command = bufToken ?
64
+ $.env({
65
+ ...process.env,
66
+ BUF_TOKEN: bufToken,
67
+ }) `buf generate ${input} --template ${templatePath} ${pathFlag}`.cwd(outputDirectory)
68
+ : $ `buf generate ${input} --template ${templatePath} ${pathFlag}`.cwd(outputDirectory);
69
+ await command;
70
+ }
71
+ finally {
72
+ await rm(templateDirectory, { force: true, recursive: true });
73
+ }
74
+ }
75
+ getCompilationTargets(targetLanguages) {
76
+ return this.getConfiguredTargetLanguages(targetLanguages).map(([language, options]) => ({
77
+ language,
78
+ options,
79
+ strategy: this.getTargetLanguageStrategy(language),
80
+ }));
81
+ }
82
+ getConfiguredTargetLanguages(targetLanguages) {
83
+ const targets = [];
84
+ for (const [language, options] of Object.entries(targetLanguages)) {
85
+ if (!options)
86
+ continue;
87
+ targets.push([Number(language), options]);
88
+ }
89
+ return targets;
90
+ }
91
+ getTargetLanguageStrategy(targetLanguage) {
92
+ switch (targetLanguage) {
93
+ case ProtobufTargetLanguage.JAVA:
94
+ return new JavaProtobufTargetLanguageStrategy();
95
+ case ProtobufTargetLanguage.GO:
96
+ return new GoProtobufTargetLanguageStrategy();
97
+ case ProtobufTargetLanguage.RUST:
98
+ return new RustProtobufTargetLanguageStrategy();
99
+ }
100
+ }
101
+ async getBufGenerateInput(protoFilesLocation) {
102
+ const resolvedLocation = path.resolve(protoFilesLocation);
103
+ const stats = await Bun.file(resolvedLocation).stat();
104
+ if (stats.isFile() && !resolvedLocation.endsWith(".proto")) {
105
+ throw new Error(`${protoFilesLocation} is not a .proto file.`);
106
+ }
107
+ const sourceDirectory = stats.isFile() ? path.dirname(resolvedLocation) : resolvedLocation;
108
+ const moduleDirectory = (await this.findBufModuleDirectory(sourceDirectory)) ?? sourceDirectory;
109
+ return {
110
+ input: moduleDirectory,
111
+ pathFilter: moduleDirectory === resolvedLocation ? undefined : resolvedLocation,
112
+ };
113
+ }
114
+ async findBufModuleDirectory(directory) {
115
+ let currentDirectory = path.resolve(directory);
116
+ while (true) {
117
+ if (await Bun.file(path.join(currentDirectory, "buf.yaml")).exists()) {
118
+ return currentDirectory;
119
+ }
120
+ const parentDirectory = path.dirname(currentDirectory);
121
+ if (parentDirectory === currentDirectory) {
122
+ return null;
123
+ }
124
+ currentDirectory = parentDirectory;
125
+ }
126
+ }
127
+ async uploadGeneratedDirectory({ generatedDirectory, options, }) {
128
+ if (!options.uploadLocation) {
129
+ throw new Error("An upload location is required to upload generated code.");
130
+ }
131
+ const repository = this.parseGitHubRepository(options.uploadLocation, options.directory);
132
+ await this.githubClient.DANGEROUS__uploadDirectoryContents({
133
+ owner: repository.owner,
134
+ repository: repository.repository,
135
+ directory: repository.directory,
136
+ sourceDirectory: generatedDirectory,
137
+ message: options.commitMessage ?? "chore: update generated protobuf clients",
138
+ branch: options.branch,
139
+ });
140
+ }
141
+ parseGitHubRepository(uploadLocation, directory) {
142
+ const [owner, repository, ...pathParts] = uploadLocation
143
+ .split("/")
144
+ .filter(Boolean);
145
+ if (!owner || !repository) {
146
+ throw new Error("GitHub upload location must be in the form `owner/repo` or `owner/repo/path`.");
147
+ }
148
+ return {
149
+ directory: directory ?? pathParts.join("/"),
150
+ owner,
151
+ repository,
152
+ };
153
+ }
154
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./client";
2
+ export * from "./types";
@@ -0,0 +1,2 @@
1
+ export * from "./client";
2
+ export * from "./types";
@@ -0,0 +1,5 @@
1
+ import type { IProtobufTargetLanguageStrategy } from "./types";
2
+ export declare class GoProtobufTargetLanguageStrategy implements IProtobufTargetLanguageStrategy {
3
+ readonly outputDirectoryName = "go";
4
+ readonly remotePlugin = "buf.build/protocolbuffers/go";
5
+ }
@@ -0,0 +1,4 @@
1
+ export class GoProtobufTargetLanguageStrategy {
2
+ outputDirectoryName = "go";
3
+ remotePlugin = "buf.build/protocolbuffers/go";
4
+ }
@@ -0,0 +1,4 @@
1
+ export * from "./go";
2
+ export * from "./java";
3
+ export * from "./rust";
4
+ export * from "./types";
@@ -0,0 +1,4 @@
1
+ export * from "./go";
2
+ export * from "./java";
3
+ export * from "./rust";
4
+ export * from "./types";
@@ -0,0 +1,5 @@
1
+ import type { IProtobufTargetLanguageStrategy } from "./types";
2
+ export declare class JavaProtobufTargetLanguageStrategy implements IProtobufTargetLanguageStrategy {
3
+ readonly outputDirectoryName = "java";
4
+ readonly remotePlugin = "buf.build/protocolbuffers/java";
5
+ }
@@ -0,0 +1,4 @@
1
+ export class JavaProtobufTargetLanguageStrategy {
2
+ outputDirectoryName = "java";
3
+ remotePlugin = "buf.build/protocolbuffers/java";
4
+ }
@@ -0,0 +1,5 @@
1
+ import type { IProtobufTargetLanguageStrategy } from "./types";
2
+ export declare class RustProtobufTargetLanguageStrategy implements IProtobufTargetLanguageStrategy {
3
+ readonly outputDirectoryName = "rust";
4
+ readonly remotePlugin = "buf.build/community/neoeinstein-prost";
5
+ }
@@ -0,0 +1,4 @@
1
+ export class RustProtobufTargetLanguageStrategy {
2
+ outputDirectoryName = "rust";
3
+ remotePlugin = "buf.build/community/neoeinstein-prost";
4
+ }
@@ -0,0 +1,4 @@
1
+ export interface IProtobufTargetLanguageStrategy {
2
+ readonly outputDirectoryName: string;
3
+ readonly remotePlugin: string;
4
+ }
File without changes
@@ -0,0 +1,47 @@
1
+ export declare enum ProtobufSourceLanguage {
2
+ RUST = 0
3
+ }
4
+ export declare enum ProtobufTargetLanguage {
5
+ JAVA = 0,
6
+ RUST = 1,
7
+ GO = 2
8
+ }
9
+ export interface ProtobufTargetLanguageOptions {
10
+ /**
11
+ * Either `owner/repo` or `owner/repo/path/inside/repo`.
12
+ *
13
+ * @example "Patina-Network/proto-clients/java"
14
+ */
15
+ uploadLocation?: string;
16
+ /** Overrides the path parsed from `uploadLocation`. */
17
+ directory?: string;
18
+ branch?: string;
19
+ commitMessage?: string;
20
+ }
21
+ export type ProtobufTargetLanguages = Partial<Record<ProtobufTargetLanguage, ProtobufTargetLanguageOptions>>;
22
+ export interface ProtobufCompilerCompileArgs {
23
+ sourceLanguage: ProtobufSourceLanguage;
24
+ /** Optional BSR API token used for Buf remote plugins. */
25
+ bufToken?: string;
26
+ /**
27
+ * A map of target language to target-specific options.
28
+ *
29
+ * @example
30
+ * ```ts
31
+ * {
32
+ * [ProtobufTargetLanguage.JAVA]: {
33
+ * uploadLocation: "Patina-Network/proto-clients/java",
34
+ * },
35
+ * }
36
+ * ```
37
+ */
38
+ targetLanguages: ProtobufTargetLanguages;
39
+ /** Directory containing proto files, or one specific `.proto` file. */
40
+ protoFilesLocation: string;
41
+ /** Defaults to a temporary directory. */
42
+ outputDirectory?: string;
43
+ }
44
+ export interface ProtobufCompilerCompileResult {
45
+ outputDirectory: string;
46
+ generatedDirectories: Partial<Record<ProtobufTargetLanguage, string>>;
47
+ }
@@ -0,0 +1,10 @@
1
+ export var ProtobufSourceLanguage;
2
+ (function (ProtobufSourceLanguage) {
3
+ ProtobufSourceLanguage[ProtobufSourceLanguage["RUST"] = 0] = "RUST";
4
+ })(ProtobufSourceLanguage || (ProtobufSourceLanguage = {}));
5
+ export var ProtobufTargetLanguage;
6
+ (function (ProtobufTargetLanguage) {
7
+ ProtobufTargetLanguage[ProtobufTargetLanguage["JAVA"] = 0] = "JAVA";
8
+ ProtobufTargetLanguage[ProtobufTargetLanguage["RUST"] = 1] = "RUST";
9
+ ProtobufTargetLanguage[ProtobufTargetLanguage["GO"] = 2] = "GO";
10
+ })(ProtobufTargetLanguage || (ProtobufTargetLanguage = {}));
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "type": "module",
4
4
  "author": "Tahmid Ahmed",
5
5
  "description": "A collection of Bun shell scripts that can be re-used in various CICD pipelines.",
6
- "version": "1.0.75",
6
+ "version": "1.0.76-beta.023dc7b4",
7
7
  "repository": {
8
8
  "url": "git+https://github.com/tahminator/pipeline.git"
9
9
  },
@@ -21,14 +21,13 @@
21
21
  },
22
22
  "scripts": {
23
23
  "typecheck": "tsc --noEmit",
24
- "test": "bun run typecheck && bun run fmt && bun run lint",
24
+ "test": "bun run typecheck && bun run fmt && bun run lint && bun test",
25
25
  "fmt": "bun run prettier",
26
26
  "lint": "bun run eslint",
27
27
  "eslint": "eslint .",
28
28
  "eslint:fix": "eslint . --fix",
29
29
  "prettier": "prettier --check .",
30
30
  "prettier:fix": "prettier --write .",
31
- "vt": "vitest run",
32
31
  "build": "tsc -p tsconfig.build.json"
33
32
  },
34
33
  "devDependencies": {