@octalmesh/seagull 0.0.1 → 0.1.1

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/dist/cli.mjs CHANGED
@@ -1,58 +1,15 @@
1
1
  #!/usr/bin/env node
2
-
3
- import { _ as resolveConfigPath, a as generateSdkCommand, d as cleanCommand, f as bundleCommand, i as lintCommand, n as publishSdkCommand, r as publishRegistriesCommand, t as serveDocsCommand, u as generateDocsCommand, v as loadConfig } from "./serve-docs-BZaITOD0.mjs";
4
2
  import { readFileSync } from "node:fs";
5
3
  import path from "node:path";
6
4
  import { fileURLToPath } from "node:url";
7
- import { Command } from "commander";
5
+ import { createProgram } from "@octalmesh/seagull-cli";
8
6
  //#region src/cli.ts
9
7
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
10
8
  const pkg = JSON.parse(readFileSync(path.join(__dirname, "..", "package.json"), "utf8"));
11
- const program = new Command();
12
- program.name("seagull").description(pkg.description).version(pkg.version).option("-c, --config <path>", "path to the CLI config file (default: auto-detected in the current directory)");
13
- program.command("lint").description("Lint every contract's OpenAPI spec with Redocly.").action(withErrorHandling(async () => lintCommand(resolveConfig())));
14
- program.command("bundle").description("Bundle every contract's OpenAPI spec into dist/specs.").action(withErrorHandling(async () => bundleCommand(resolveConfig())));
15
- program.command("generate").description("Generate every configured SDK artifact into dist/sdk.").action(withErrorHandling(async () => generateSdkCommand(resolveConfig())));
16
- program.command("clean").description("Remove the dist output directory.").action(withErrorHandling(async () => cleanCommand(resolveConfig())));
17
- const docs = program.command("docs").description("Documentation site commands.");
18
- docs.command("generate").description("Generate the Scalar documentation site into dist/docs.").action(withErrorHandling(async () => generateDocsCommand(resolveConfig())));
19
- docs.command("serve").description("Serve the generated documentation site locally.").action(withErrorHandling(async () => serveDocsCommand(resolveConfig())));
20
- const publish = program.command("publish").description("Publishing commands.");
21
- publish.command("sdk").description("Publish generated SDKs to their per-artifact git branches/tags.").option("--dry-run", "print what would be pushed without pushing").action(withErrorHandling(async (opts) => {
22
- await publishSdkCommand(resolveConfig(), { dryRun: opts.dryRun });
23
- }));
24
- publish.command("registries").description("Publish registry-backed packages (npm publish / mvn deploy).").option("--dry-run", "print what would be published without publishing").action(withErrorHandling(async (opts) => {
25
- await publishRegistriesCommand(resolveConfig(), { dryRun: opts.dryRun });
26
- }));
27
- await program.parseAsync();
28
- /**
29
- * Resolves and loads the config, using `--config` if given, else
30
- * auto-discovering it in the current directory.
31
- *
32
- * @returns The resolved config.
33
- */
34
- function resolveConfig() {
35
- const { config: configOption } = program.opts();
36
- const configPath = configOption ? path.resolve(process.cwd(), configOption) : resolveConfigPath(process.cwd());
37
- return loadConfig(configPath);
38
- }
39
- /**
40
- * Wraps a commander action so a thrown Error prints as `seagull: <message>`
41
- * and exits non-zero, instead of an unhandled-rejection stack trace.
42
- *
43
- * @param fn The action function to wrap.
44
- * @returns A wrapped action function that handles errors.
45
- */
46
- function withErrorHandling(fn) {
47
- return async (...args) => {
48
- try {
49
- await fn(...args);
50
- } catch (error) {
51
- console.error(`seagull: ${error instanceof Error ? error.message : error}`);
52
- process.exitCode = 1;
53
- }
54
- };
55
- }
9
+ await createProgram({
10
+ ...pkg,
11
+ name: "seagull"
12
+ }).parseAsync();
56
13
  //#endregion
57
14
  export {};
58
15
 
package/dist/cli.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.mjs","names":[],"sources":["../src/cli.ts"],"sourcesContent":["import { readFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nimport { Command } from \"commander\";\n\nimport { loadConfig } from \"@config/loader\";\nimport { resolveConfigPath } from \"@config/resolve-config-file\";\nimport type { ResolvedConfig } from \"@config/types\";\n\nimport { bundleCommand } from \"@commands/bundle\";\nimport { cleanCommand } from \"@commands/clean\";\nimport { generateDocsCommand } from \"@commands/generate-docs\";\nimport { generateSdkCommand } from \"@commands/generate-sdk\";\nimport { lintCommand } from \"@commands/lint\";\nimport { publishRegistriesCommand } from \"@commands/publish-registries\";\nimport { publishSdkCommand } from \"@commands/publish-sdk\";\nimport { serveDocsCommand } from \"@commands/serve-docs\";\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\nconst pkg = JSON.parse(\n readFileSync(path.join(__dirname, \"..\", \"package.json\"), \"utf8\"),\n) as { version: string; description: string };\nconst program = new Command();\n\n//<editor-fold desc=\"Commands\" defaultstate=\"collapsed\">\n\nprogram\n .name(\"seagull\")\n .description(pkg.description)\n .version(pkg.version)\n .option(\n \"-c, --config <path>\",\n \"path to the CLI config file (default: auto-detected in the current directory)\",\n );\n\nprogram\n .command(\"lint\")\n .description(\"Lint every contract's OpenAPI spec with Redocly.\")\n .action(withErrorHandling(async () => lintCommand(resolveConfig())));\n\nprogram\n .command(\"bundle\")\n .description(\"Bundle every contract's OpenAPI spec into dist/specs.\")\n .action(withErrorHandling(async () => bundleCommand(resolveConfig())));\n\nprogram\n .command(\"generate\")\n .description(\"Generate every configured SDK artifact into dist/sdk.\")\n .action(withErrorHandling(async () => generateSdkCommand(resolveConfig())));\n\nprogram\n .command(\"clean\")\n .description(\"Remove the dist output directory.\")\n .action(withErrorHandling(async () => cleanCommand(resolveConfig())));\n\nconst docs = program\n .command(\"docs\")\n .description(\"Documentation site commands.\");\n\ndocs\n .command(\"generate\")\n .description(\"Generate the Scalar documentation site into dist/docs.\")\n .action(withErrorHandling(async () => generateDocsCommand(resolveConfig())));\n\ndocs\n .command(\"serve\")\n .description(\"Serve the generated documentation site locally.\")\n .action(withErrorHandling(async () => serveDocsCommand(resolveConfig())));\n\nconst publish = program.command(\"publish\").description(\"Publishing commands.\");\n\npublish\n .command(\"sdk\")\n .description(\n \"Publish generated SDKs to their per-artifact git branches/tags.\",\n )\n .option(\"--dry-run\", \"print what would be pushed without pushing\")\n .action(\n withErrorHandling(async (opts: DryRunOptions) => {\n await publishSdkCommand(resolveConfig(), { dryRun: opts.dryRun });\n }),\n );\n\npublish\n .command(\"registries\")\n .description(\"Publish registry-backed packages (npm publish / mvn deploy).\")\n .option(\"--dry-run\", \"print what would be published without publishing\")\n .action(\n withErrorHandling(async (opts: DryRunOptions) => {\n await publishRegistriesCommand(resolveConfig(), { dryRun: opts.dryRun });\n }),\n );\n\n//</editor-fold>\n\nawait program.parseAsync();\n\ninterface DryRunOptions {\n dryRun?: boolean;\n}\n\n/**\n * Resolves and loads the config, using `--config` if given, else\n * auto-discovering it in the current directory.\n *\n * @returns The resolved config.\n */\nfunction resolveConfig(): ResolvedConfig {\n const { config: configOption } = program.opts<{ config?: string }>();\n const configPath = configOption\n ? path.resolve(process.cwd(), configOption)\n : resolveConfigPath(process.cwd());\n\n return loadConfig(configPath);\n}\n\n/**\n * Wraps a commander action so a thrown Error prints as `seagull: <message>`\n * and exits non-zero, instead of an unhandled-rejection stack trace.\n *\n * @param fn The action function to wrap.\n * @returns A wrapped action function that handles errors.\n */\nfunction withErrorHandling<Args extends unknown[]>(\n fn: (...args: Args) => Promise<void>,\n): (...args: Args) => Promise<void> {\n return async (...args: Args) => {\n try {\n await fn(...args);\n } catch (error) {\n console.error(\n `seagull: ${error instanceof Error ? error.message : error}`,\n );\n process.exitCode = 1;\n }\n };\n}\n"],"mappings":";;;;;;;;AAmBA,MAAM,YAAY,KAAK,QAAQ,cAAc,YAAY,GAAG,CAAC;AAC7D,MAAM,MAAM,KAAK,MACf,aAAa,KAAK,KAAK,WAAW,MAAM,cAAc,GAAG,MAAM,CACjE;AACA,MAAM,UAAU,IAAI,QAAQ;AAI5B,QACG,KAAK,SAAS,CAAC,CACf,YAAY,IAAI,WAAW,CAAC,CAC5B,QAAQ,IAAI,OAAO,CAAC,CACpB,OACC,uBACA,+EACF;AAEF,QACG,QAAQ,MAAM,CAAC,CACf,YAAY,kDAAkD,CAAC,CAC/D,OAAO,kBAAkB,YAAY,YAAY,cAAc,CAAC,CAAC,CAAC;AAErE,QACG,QAAQ,QAAQ,CAAC,CACjB,YAAY,uDAAuD,CAAC,CACpE,OAAO,kBAAkB,YAAY,cAAc,cAAc,CAAC,CAAC,CAAC;AAEvE,QACG,QAAQ,UAAU,CAAC,CACnB,YAAY,uDAAuD,CAAC,CACpE,OAAO,kBAAkB,YAAY,mBAAmB,cAAc,CAAC,CAAC,CAAC;AAE5E,QACG,QAAQ,OAAO,CAAC,CAChB,YAAY,mCAAmC,CAAC,CAChD,OAAO,kBAAkB,YAAY,aAAa,cAAc,CAAC,CAAC,CAAC;AAEtE,MAAM,OAAO,QACV,QAAQ,MAAM,CAAC,CACf,YAAY,8BAA8B;AAE7C,KACG,QAAQ,UAAU,CAAC,CACnB,YAAY,wDAAwD,CAAC,CACrE,OAAO,kBAAkB,YAAY,oBAAoB,cAAc,CAAC,CAAC,CAAC;AAE7E,KACG,QAAQ,OAAO,CAAC,CAChB,YAAY,iDAAiD,CAAC,CAC9D,OAAO,kBAAkB,YAAY,iBAAiB,cAAc,CAAC,CAAC,CAAC;AAE1E,MAAM,UAAU,QAAQ,QAAQ,SAAS,CAAC,CAAC,YAAY,sBAAsB;AAE7E,QACG,QAAQ,KAAK,CAAC,CACd,YACC,iEACF,CAAC,CACA,OAAO,aAAa,4CAA4C,CAAC,CACjE,OACC,kBAAkB,OAAO,SAAwB;CAC/C,MAAM,kBAAkB,cAAc,GAAG,EAAE,QAAQ,KAAK,OAAO,CAAC;AAClE,CAAC,CACH;AAEF,QACG,QAAQ,YAAY,CAAC,CACrB,YAAY,8DAA8D,CAAC,CAC3E,OAAO,aAAa,kDAAkD,CAAC,CACvE,OACC,kBAAkB,OAAO,SAAwB;CAC/C,MAAM,yBAAyB,cAAc,GAAG,EAAE,QAAQ,KAAK,OAAO,CAAC;AACzE,CAAC,CACH;AAIF,MAAM,QAAQ,WAAW;;;;;;;AAYzB,SAAS,gBAAgC;CACvC,MAAM,EAAE,QAAQ,iBAAiB,QAAQ,KAA0B;CACnE,MAAM,aAAa,eACf,KAAK,QAAQ,QAAQ,IAAI,GAAG,YAAY,IACxC,kBAAkB,QAAQ,IAAI,CAAC;CAEnC,OAAO,WAAW,UAAU;AAC9B;;;;;;;;AASA,SAAS,kBACP,IACkC;CAClC,OAAO,OAAO,GAAG,SAAe;EAC9B,IAAI;GACF,MAAM,GAAG,GAAG,IAAI;EAClB,SAAS,OAAO;GACd,QAAQ,MACN,YAAY,iBAAiB,QAAQ,MAAM,UAAU,OACvD;GACA,QAAQ,WAAW;EACrB;CACF;AACF"}
1
+ {"version":3,"file":"cli.mjs","names":[],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { readFileSync } from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nimport { createProgram } from \"@octalmesh/seagull-cli\";\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\nconst pkg = JSON.parse(\n readFileSync(path.join(__dirname, \"..\", \"package.json\"), \"utf8\"),\n) as { version: string; description: string };\n\nawait createProgram({ ...pkg, name: \"seagull\" }).parseAsync();\n"],"mappings":";;;;;;AAOA,MAAM,YAAY,KAAK,QAAQ,cAAc,YAAY,GAAG,CAAC;AAC7D,MAAM,MAAM,KAAK,MACf,aAAa,KAAK,KAAK,WAAW,MAAM,cAAc,GAAG,MAAM,CACjE;AAEA,MAAM,cAAc;CAAE,GAAG;CAAK,MAAM;AAAU,CAAC,CAAC,CAAC,WAAW"}
package/dist/index.d.mts CHANGED
@@ -1,391 +1,3 @@
1
-
2
- import { z } from "zod";
3
- //#region src/config/schema.d.ts
4
- /**
5
- * A free-form tree of leaf values, used for the `vars:` block in the CLI config.
6
- * Nest however deep is useful - every leaf becomes addressable as
7
- * `{vars.<dot.path>}` in templated fields.
8
- */
9
- type VarsTree = {
10
- [key: string]: string | number | boolean | VarsTree;
11
- };
12
- //#endregion
13
- //#region src/config/types.d.ts
14
- type SdkTool = "openapi-generator" | "openapi-typescript";
15
- type SdkLang = "typescript" | "go" | "java";
16
- type SdkKind = "client" | "server";
17
- /**
18
- * A single artifact a contract generates: a generator recipe from the CLI
19
- * config, fully resolved (templates interpolated, overrides merged, paths made
20
- * absolute) for one specific contract.
21
- */
22
- interface ResolvedArtifact {
23
- /**
24
- * The id this artifact is known by for this contract - the key under
25
- * `generators:` it was resolved from, or its `as` override. Used as the
26
- * output folder segment, and to derive the publish branch/tag.
27
- */
28
- id: string;
29
- tool: SdkTool;
30
- lang: SdkLang;
31
- kind: SdkKind;
32
- /** `openapi-generator -g` value. Set only when `tool` is `openapi-generator`. */
33
- generator?: string;
34
- /** Absolute output directory: `<sdkDir>/<contract>/<id>`. */
35
- outputDir: string;
36
- /** `sdk/svc-<contract>/<id>` */
37
- branch: string;
38
- /** `svc-<contract>-<id>` */
39
- tagPrefix: string;
40
- additionalProperties: Record<string, string | number | boolean>;
41
- package?: string;
42
- goModule?: string;
43
- goPackageName?: string;
44
- maven?: {
45
- groupId: string;
46
- artifactId: string;
47
- };
48
- /**
49
- * Absolute path to a custom README template, if `readme:` was set for this
50
- * generator/artifact. Falls back to a built-in default template when unset -
51
- * see `core/readme/readme-renderer.ts`.
52
- */
53
- readmeTemplate?: string;
54
- }
55
- interface ResolvedContract {
56
- name: string;
57
- title: string;
58
- /** Absolute path to the source `openapi.yaml`. */
59
- entrypoint: string;
60
- /**
61
- * Path to the source `openapi.yaml`, relative to `rootDir` - what
62
- * `redocly.yaml`'s `apis:` section wants.
63
- */
64
- entrypointRelative: string;
65
- artifacts: ResolvedArtifact[];
66
- }
67
- /**
68
- * One (contract, artifact) pair - the flattened unit of work most commands
69
- * actually iterate over.
70
- */
71
- interface ResolvedArtifactEntry {
72
- contract: ResolvedContract;
73
- artifact: ResolvedArtifact;
74
- }
75
- interface ResolvedConfig {
76
- /**
77
- * Directory containing the config file - every relative path in the config
78
- * (entrypoints, `paths.*`, `readme` templates, ...) resolves against this.
79
- */
80
- rootDir: string;
81
- paths: {
82
- dist: string;
83
- specs: string;
84
- docs: string;
85
- sdk: string;
86
- };
87
- github: {
88
- owner: string;
89
- repo: string;
90
- };
91
- vars: VarsTree;
92
- docs: {
93
- server: {
94
- host: string;
95
- port: number;
96
- };
97
- metadata: {
98
- title: string;
99
- description: string;
100
- favicon: string;
101
- baseServerUrl: string;
102
- };
103
- };
104
- contracts: ResolvedContract[];
105
- /**
106
- * Every (contract, artifact) pair across every contract, in config order -
107
- * the flat list most commands iterate over.
108
- */
109
- allArtifacts: ResolvedArtifactEntry[];
110
- }
111
- //#endregion
112
- //#region src/config/loader.d.ts
113
- /**
114
- * Loads, validates, and fully resolves a CLI config file - the single entry
115
- * point every command uses to get its configuration.
116
- *
117
- * Unlike a build tool bundled into the consumer's own repo, seagull is
118
- * installed as a dependency, so it has no way to guess where the
119
- * consumer's config lives on its own - `configPath` must be supplied by the
120
- * caller (the CLI resolves it via `resolveConfigPath()` in
121
- * `config/resolve-config-file.ts`, or `--config`).
122
- *
123
- * @param configPath - Absolute path to the CLI config file.
124
- * @returns The fully resolved config.
125
- */
126
- declare function loadConfig(configPath: string): ResolvedConfig;
127
- //#endregion
128
- //#region src/config/resolve-config-file.d.ts
129
- /**
130
- * Config filenames CLI recognizes, checked in this order.
131
- */
132
- declare const CONFIG_FILENAMES: readonly [".seagull", ".seagull.yaml", ".seagull.yml", "seagull.yaml", "seagull.yml"];
133
- /**
134
- * Finds the CLI config file in a directory, trying each of
135
- * {@link CONFIG_FILENAMES} in order.
136
- *
137
- * @param cwd - The directory to look in (typically `process.cwd()`).
138
- * @returns The absolute path to the first matching config file.
139
- * @throws Error if none of the candidate filenames exist in `cwd`.
140
- *
141
- * @see {@link CONFIG_FILENAMES} - the list of filenames checked, in order.
142
- */
143
- declare function resolveConfigPath(cwd: string): string;
144
- //#endregion
145
- //#region src/core/generator/types.d.ts
146
- /** Passed once per tool to {@link Generator.prepare}, before any of that
147
- * tool's {@link Generator.generate} calls run. */
148
- interface PrepareContext {
149
- rootDir: string;
150
- /**
151
- * Every (contract, artifact) pair that uses this generator's `tool`, across
152
- * all contracts.
153
- */
154
- entries: ResolvedArtifactEntry[];
155
- }
156
- /** Passed once per artifact to {@link Generator.generate}. */
157
- interface GenerateContext {
158
- rootDir: string;
159
- contract: ResolvedContract;
160
- artifact: ResolvedArtifact;
161
- version: string;
162
- github: {
163
- owner: string;
164
- repo: string;
165
- };
166
- /**
167
- * Absolute path to the contract's bundled JSON spec
168
- * (`<specsDir>/<contract>.json`).
169
- */
170
- specInputPath: string;
171
- }
172
- //#endregion
173
- //#region src/core/generator/generator.d.ts
174
- /**
175
- * The root primitive every concrete SDK generator implements.
176
- *
177
- * One instance per underlying tool (`openapi-generator-cli`,
178
- * `openapi-typescript`, ...) - not one per language, since a single tool
179
- * invocation (e.g. `openapi-generator-cli -g java`/`-g go`) already covers
180
- * every language it supports. Language-specific behaviour (patching `go.mod`,
181
- * `package.json`, `pom.xml`, ...) is composed in via patchers rather than
182
- * living in per-language subclasses.
183
- */
184
- declare abstract class Generator {
185
- abstract readonly tool: SdkTool;
186
- /**
187
- * Optional one-time setup step, run once per tool before any of that tool's
188
- * {@link generate} calls - for tools like `openapi-typescript` that generate
189
- * every contract's output in a single global invocation instead of one call
190
- * per artifact.
191
- *
192
- * @param ctx - Every (contract, artifact) pair using this generator's tool.
193
- */
194
- prepare?(ctx: PrepareContext): Promise<void>;
195
- /**
196
- * Generates a single artifact.
197
- *
198
- * @param ctx - The contract, artifact, and resolved version to generate for.
199
- */
200
- abstract generate(ctx: GenerateContext): Promise<void>;
201
- }
202
- //#endregion
203
- //#region src/core/generator/registry.d.ts
204
- /**
205
- * Looks up the concrete {@link Generator} implementation for a given tool name.
206
- */
207
- declare class GeneratorRegistry {
208
- private readonly generators;
209
- /**
210
- * Registers a generator implementation under its own {@link Generator.tool}.
211
- *
212
- * @param generator - The generator instance to register.
213
- * @returns `this`, for chaining.
214
- */
215
- register(generator: Generator): this;
216
- /**
217
- * Resolves the generator implementation for a given tool name.
218
- *
219
- * @param tool - The tool name, e.g. `"openapi-generator"`.
220
- * @returns The registered generator.
221
- * @throws Error if no generator is registered for that tool.
222
- */
223
- resolve(tool: SdkTool): Generator;
224
- /**
225
- * All distinct tools currently registered.
226
- *
227
- * @returns The registered tool names.
228
- */
229
- tools(): SdkTool[];
230
- }
231
- //#endregion
232
- //#region src/core/process/resolve-bin.d.ts
233
- /**
234
- * Resolves the absolute path to an installed npm package's own CLI entrypoint
235
- * script, using Node's standard module resolution algorithm - so it works the
236
- * same way regardless of which package manager (npm/pnpm/yarn) installed CLI
237
- * and its dependencies, or how deeply they get hoisted. Shelling out to
238
- * `pnpm exec`/`npx` instead would assume a specific package manager and a
239
- * particular install layout, which doesn't hold once CLI is just another
240
- * dependency in someone else's project.
241
- *
242
- * @param pkgName - The npm package name, e.g. `"@org/cli"`.
243
- * @param binName - Which entry to resolve from that package's `bin` field.
244
- * Defaults to the package's own unscoped name.
245
- * @returns The absolute path to the resolved bin script.
246
- * @throws Error if the package or the requested bin entry can't be found.
247
- */
248
- declare function resolveBinPath(pkgName: string, binName?: string): string;
249
- //#endregion
250
- //#region src/core/process/exec.d.ts
251
- /**
252
- * Runs a command to completion, streaming its stdio straight through
253
- * (`inherit`), and rejects if it exits non-zero.
254
- *
255
- * This is the async counterpart used for the "one long-running tool" commands
256
- * (`redocly`, `openapi-generator-cli`, `openapi-typescript`); for short
257
- * synchronous calls (git plumbing, `npm publish`/`mvn deploy`), see
258
- * {@link runSync}.
259
- *
260
- * @param command - The executable to run.
261
- * @param args - Arguments to pass to it.
262
- * @param cwd - The working directory to run it in.
263
- * @returns A promise that resolves on exit code 0, and rejects otherwise.
264
- */
265
- declare function run(command: string, args: string[], cwd: string): Promise<void>;
266
- /**
267
- * Runs a command to completion synchronously, streaming its stdio straight
268
- * through (`inherit`).
269
- *
270
- * @param command - The executable to run.
271
- * @param args - Arguments to pass to it.
272
- * @param cwd - The working directory to run it in.
273
- * @returns The exit status (0 on success).
274
- */
275
- declare function runSync(command: string, args: string[], cwd: string): number;
276
- //#endregion
277
- //#region src/generators/openapi-generator-cli/openapi-generator-cli.generator.d.ts
278
- /**
279
- * Wraps `openapi-generator-cli` - the single tool implementation behind every
280
- * `-g` template (`typescript-fetch`, `go`, `go-server`, `java`, `spring`, ...),
281
- * regardless of language. Language-specific output patching is delegated to a
282
- * {@link Patcher}, selected by `artifact.lang`.
283
- */
284
- declare class OpenApiGeneratorCli extends Generator {
285
- readonly tool: SdkTool;
286
- private readonly patchers;
287
- generate(ctx: GenerateContext): Promise<void>;
288
- }
289
- //#endregion
290
- //#region src/generators/openapi-typescript/openapi-typescript.generator.d.ts
291
- /**
292
- * Wraps `openapi-typescript`. Unlike `openapi-generator-cli`, it isn't invoked
293
- * once per artifact - it reads `redocly.yaml`'s `apis:` map (kept in sync with
294
- * the CLI config by `core/redocly/redocly-sync.ts`) and writes every contract's
295
- * `index.d.ts` to its configured `x-openapi-ts.output` path in a single run,
296
- * so that single global invocation happens once in {@link prepare}.
297
- * {@link generate} then only has to write each artifact's package.json` -
298
- * `openapi-typescript` emits `index.d.ts` alone, with no package manifest of
299
- * its own to patch.
300
- */
301
- declare class OpenApiTypescriptGenerator extends Generator {
302
- readonly tool: SdkTool;
303
- prepare({ rootDir, entries }: PrepareContext): Promise<void>;
304
- generate({ contract, artifact, version, github }: GenerateContext): Promise<void>;
305
- }
306
- //#endregion
307
- //#region src/commands/bundle.d.ts
308
- /**
309
- * Bundles every contract's OpenAPI spec into `dist/specs/<contract>.json`.
310
- *
311
- * @param config - The resolved CLI config.
312
- */
313
- declare function bundleCommand(config: ResolvedConfig): Promise<void>;
314
- //#endregion
315
- //#region src/commands/clean.d.ts
316
- /**
317
- * Removes the entire `dist` output directory.
318
- *
319
- * @param config - The resolved CLI config.
320
- */
321
- declare function cleanCommand(config: ResolvedConfig): Promise<void>;
322
- //#endregion
323
- //#region src/commands/generate-docs.d.ts
324
- /**
325
- * Generates the documentation website for every contract into `dist/docs`.
326
- *
327
- * @param config - The resolved CLI config.
328
- */
329
- declare function generateDocsCommand(config: ResolvedConfig): Promise<void>;
330
- //#endregion
331
- //#region src/commands/generate-sdk.d.ts
332
- /**
333
- * Generates SDK packages for every artifact of every contract in the config.
334
- *
335
- * @param config - The resolved config.
336
- */
337
- declare function generateSdkCommand(config: ResolvedConfig): Promise<void>;
338
- //#endregion
339
- //#region src/commands/lint.d.ts
340
- /**
341
- * Lints every contract's OpenAPI spec.
342
- * Sets `process.exitCode = 1` if any contract fails.
343
- *
344
- * @param config - The resolved CLI config.
345
- */
346
- declare function lintCommand(config: ResolvedConfig): Promise<void>;
347
- //#endregion
348
- //#region src/commands/publish-registries.d.ts
349
- interface PublishRegistriesOptions {
350
- dryRun?: boolean;
351
- }
352
- /**
353
- * Publishes registry-backed packages:
354
- * - TypeScript (client and server-types) -> npm (needs a configured registry
355
- * or auth token on the machine running this).
356
- * - Java (client and server) -> Maven (needs `~/.m2/settings.xml` credentials
357
- * for whichever repository `mvn deploy` resolves to).
358
- *
359
- * Go packages are intentionally skipped - they're consumed straight from
360
- * their git branch/tag (see `publish-sdk.ts`), Go has no registry step.
361
- *
362
- * @param config - The resolved CLI config.
363
- * @param options - `{ dryRun }` - print what would run without running it.
364
- */
365
- declare function publishRegistriesCommand(config: ResolvedConfig, options?: PublishRegistriesOptions): Promise<void>;
366
- //#endregion
367
- //#region src/commands/publish-sdk.d.ts
368
- interface PublishSdkOptions {
369
- dryRun?: boolean;
370
- }
371
- /**
372
- * Redistributes each generated artifact's `dist/sdk/<contract>/<artifact-id>`
373
- * into its own orphan branch (`sdk/svc-<contract>/<artifact-id>`) and tags the
374
- * publish.
375
- *
376
- * @param config - The resolved CLI config.
377
- * @param options - `{ dryRun }` - skip pushing, just report what would happen.
378
- */
379
- declare function publishSdkCommand(config: ResolvedConfig, options?: PublishSdkOptions): Promise<void>;
380
- //#endregion
381
- //#region src/commands/serve-docs.d.ts
382
- /**
383
- * Serves the generated documentation site (`dist/docs`) over plain HTTP for
384
- * local previewing.
385
- *
386
- * @param config - The resolved CLI config.
387
- */
388
- declare function serveDocsCommand(config: ResolvedConfig): Promise<void>;
389
- //#endregion
390
- export { CONFIG_FILENAMES, type GenerateContext, Generator, GeneratorRegistry, OpenApiGeneratorCli, OpenApiTypescriptGenerator, type PrepareContext, type PublishRegistriesOptions, type PublishSdkOptions, type ResolvedArtifact, type ResolvedArtifactEntry, type ResolvedConfig, type ResolvedContract, type SdkKind, type SdkLang, type SdkTool, type VarsTree, bundleCommand, cleanCommand, generateDocsCommand, generateSdkCommand, lintCommand, loadConfig, publishRegistriesCommand, publishSdkCommand, resolveBinPath, resolveConfigPath, run, runSync, serveDocsCommand };
391
- //# sourceMappingURL=index.d.mts.map
1
+ export * from "@octalmesh/seagull-cli";
2
+ export * from "@octalmesh/seagull-core";
3
+ export * from "@octalmesh/seagull-docs";
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env node
2
-
3
- import { _ as resolveConfigPath, a as generateSdkCommand, c as Generator, d as cleanCommand, f as bundleCommand, g as CONFIG_FILENAMES, h as runSync, i as lintCommand, l as GeneratorRegistry, m as run, n as publishSdkCommand, o as OpenApiTypescriptGenerator, p as resolveBinPath, r as publishRegistriesCommand, s as OpenApiGeneratorCli, t as serveDocsCommand, u as generateDocsCommand, v as loadConfig } from "./serve-docs-BZaITOD0.mjs";
4
- export { CONFIG_FILENAMES, Generator, GeneratorRegistry, OpenApiGeneratorCli, OpenApiTypescriptGenerator, bundleCommand, cleanCommand, generateDocsCommand, generateSdkCommand, lintCommand, loadConfig, publishRegistriesCommand, publishSdkCommand, resolveBinPath, resolveConfigPath, run, runSync, serveDocsCommand };
1
+ export * from "@octalmesh/seagull-cli";
2
+ export * from "@octalmesh/seagull-core";
3
+ export * from "@octalmesh/seagull-docs";
4
+ export {};
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@octalmesh/seagull",
3
- "version": "0.0.1",
3
+ "version": "0.1.1",
4
4
  "description": "Contract-first OpenAPI SDK, docs, and publishing pipeline - driven by a single seagull config.",
5
5
  "author": "OctalMesh <contact@octalmesh.com> (https://octalmesh.com)",
6
6
  "license": "MIT",
7
- "homepage": "https://github.com/OctalMesh/Seagull",
7
+ "homepage": "https://developers.octalmesh.com/seagull",
8
8
  "type": "module",
9
9
  "keywords": [
10
10
  "octalmesh",
@@ -49,22 +49,20 @@
49
49
  "devEngines": {
50
50
  "runtime": {
51
51
  "name": "node",
52
- "version": "^22.22.0",
52
+ "version": "^22.22.0 || ^24.0.0",
53
53
  "onFail": "warn"
54
54
  }
55
55
  },
56
56
  "dependencies": {
57
- "@openapitools/openapi-generator-cli": "^2.41.0",
58
- "@redocly/cli": "^2.50.0",
59
- "@scalar/api-reference": "^1.67.0",
60
- "commander": "^15.0.0",
61
- "openapi-typescript": "^7.13.0",
62
- "yaml": "^2.9.0",
63
- "zod": "^4.5.4"
57
+ "@octalmesh/seagull-cli": "0.1.1",
58
+ "@octalmesh/seagull-core": "0.1.1",
59
+ "@octalmesh/seagull-docs": "0.1.1"
64
60
  },
65
61
  "devDependencies": {
62
+ "@changesets/cli": "^3.0.2",
66
63
  "@trivago/prettier-plugin-sort-imports": "^6.0.2",
67
- "@types/node": "^26.4.0",
64
+ "@types/node": "^26.5.1",
65
+ "@vitest/coverage-v8": "^5.0.0",
68
66
  "@vitest/ui": "^5.0.0",
69
67
  "eslint": "^10.10.0",
70
68
  "eslint-config-prettier": "^10.1.8",
@@ -72,24 +70,41 @@
72
70
  "prettier": "^3.9.6",
73
71
  "prettier-plugin-yaml": "^1.3.0",
74
72
  "tree-node-cli": "^3.0.0",
75
- "tsdown": "0.22.14",
73
+ "tsdown": "0.23.0",
76
74
  "typescript": "^6.0.2",
77
75
  "typescript-eslint": "^8.69.0",
76
+ "vite": "^8.3.0",
78
77
  "vitest": "^5.0.0"
79
78
  },
80
79
  "scripts": {
81
- "build": "tsdown",
82
- "dev": "tsdown --watch",
83
- "typecheck": "tsc --noEmit",
84
- "test": "vitest",
85
- "test:run": "vitest run --passWithNoTests",
86
- "test:watch": "vitest watch",
87
- "test:ui": "vitest --ui",
80
+ "build": "pnpm --filter \"./packages/**\" run build && tsdown",
81
+ "dev": "pnpm --filter \"./packages/**\" --parallel run dev",
82
+ "typecheck": "pnpm --filter \"./packages/**\" run typecheck && tsc --noEmit",
88
83
  "lint": "eslint .",
89
84
  "lint:fix": "eslint . --fix",
85
+ "test": "pnpm run build && vitest run",
86
+ "test:watch": "pnpm run test:unit:watch",
87
+ "test:ui": "pnpm build && vitest --ui",
88
+ "test:coverage": "vitest run --project=\"unit:*\" --coverage",
89
+ "test:report": "vitest run --reporter=html",
90
+ "test:preview": "vite preview --outDir .vitest",
91
+ "test:unit": "vitest run --project=\"unit:*\"",
92
+ "test:unit:watch": "vitest --project=\"unit:*\"",
93
+ "test:unit:ui": "vitest --project=\"unit:*\" --ui",
94
+ "test:e2e": "pnpm build && vitest run --project=e2e",
95
+ "test:e2e:ui": "pnpm build && vitest --ui --project=e2e",
90
96
  "format": "prettier . --write",
91
97
  "format:check": "prettier . --check",
98
+ "deps": "pnpm update --latest --recursive --interactive",
99
+ "deps:check": "pnpm outdated --recursive",
92
100
  "tree": "treee -I \"node_modules|.git|.idea|target|build|dist|dev-dist|bin|.project-structure.txt\" -a --dirs-first",
93
- "tree:export": "pnpm run tree --silent > .project-structure.txt"
101
+ "tree:export": "pnpm run tree --silent > .project-structure.txt",
102
+ "changeset": "changeset add",
103
+ "changeset:status": "changeset status --verbose --since=dev",
104
+ "changeset:empty": "changeset add --empty",
105
+ "version": "changeset version && pnpm install --no-frozen-lockfile --lockfile-only",
106
+ "release": "pnpm run build && pnpm run test:run && pnpm run release:publish",
107
+ "release:dry": "pnpm -r publish --no-git-checks --provenance --dry-run",
108
+ "release:publish": "pnpm -r publish --no-git-checks --provenance"
94
109
  }
95
110
  }