@octalmesh/seagull-core 0.0.2 → 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.
Files changed (38) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/README.md +173 -39
  3. package/dist/index.mjs +218 -152
  4. package/package.json +6 -6
  5. package/src/config/loader.test.ts +505 -0
  6. package/src/config/loader.ts +31 -12
  7. package/src/config/publishing.test.ts +92 -0
  8. package/src/config/publishing.ts +9 -5
  9. package/src/config/resolve-config-file.test.ts +60 -0
  10. package/src/config/schema.test.ts +466 -0
  11. package/src/config/schema.ts +16 -10
  12. package/src/config/spec-format.test.ts +54 -0
  13. package/src/config/spec-format.ts +48 -0
  14. package/src/config/template.test.ts +168 -0
  15. package/src/config/types.ts +3 -3
  16. package/src/generator/generator.test.ts +59 -0
  17. package/src/generator/registry.test.ts +84 -0
  18. package/src/generator/types.ts +9 -14
  19. package/src/generators/openapi-generator-cli/openapi-generator-cli.generator.test.ts +259 -0
  20. package/src/generators/openapi-generator-cli/patchers/go-module.patcher.test.ts +119 -0
  21. package/src/generators/openapi-generator-cli/patchers/maven.patcher.test.ts +141 -0
  22. package/src/generators/openapi-generator-cli/patchers/npm.patcher.test.ts +132 -0
  23. package/src/generators/openapi-typescript/openapi-typescript.generator.test.ts +190 -0
  24. package/src/git/git.test.ts +234 -0
  25. package/src/git/git.ts +50 -4
  26. package/src/index.ts +8 -0
  27. package/src/process/exec.test.ts +103 -0
  28. package/src/process/exec.ts +1 -2
  29. package/src/process/resolve-bin.test.ts +43 -0
  30. package/src/readme/default-templates.test.ts +179 -0
  31. package/src/readme/default-templates.ts +5 -10
  32. package/src/readme/readme-renderer.test.ts +121 -0
  33. package/src/readme/readme-renderer.ts +3 -7
  34. package/src/redocly/redocly-sync.test.ts +190 -0
  35. package/src/redocly/redocly-sync.ts +3 -1
  36. package/src/test-support/fixtures.ts +65 -0
  37. package/src/version/version.test.ts +93 -0
  38. package/src/version/version.ts +4 -2
@@ -0,0 +1,65 @@
1
+ import type {
2
+ ResolvedArtifact,
3
+ ResolvedContract,
4
+ ResolvedPublishing,
5
+ } from "../config/types";
6
+
7
+ /**
8
+ * Builds a {@link ResolvedPublishing} fixture with sensible defaults,
9
+ * overridable per-field - used across generator/readme/patcher tests so each
10
+ * test only has to spell out the fields it actually cares about.
11
+ */
12
+ export function makePublishing(
13
+ overrides: Partial<ResolvedPublishing> = {},
14
+ ): ResolvedPublishing {
15
+ return {
16
+ branch: "sdk/svc-auth/ts-client",
17
+ tagTemplate: "svc-{service}-{id}-v{version}",
18
+ repositoryUrl: "https://github.com/OctalMesh/ows-contracts",
19
+ npmRegistry: "https://npm.pkg.github.com",
20
+ npmAccess: "public",
21
+ mavenRepositoryId: "github",
22
+ mavenRepositoryUrl: "https://maven.pkg.github.com/OctalMesh/ows-contracts",
23
+ ...overrides,
24
+ };
25
+ }
26
+
27
+ /**
28
+ * Builds a {@link ResolvedArtifact} fixture, defaulting to a TypeScript
29
+ * client artifact - overridable per-field for other lang/kind/tool
30
+ * combinations.
31
+ */
32
+ export function makeArtifact(
33
+ overrides: Partial<ResolvedArtifact> = {},
34
+ ): ResolvedArtifact {
35
+ return {
36
+ id: "ts-client",
37
+ tool: "openapi-generator",
38
+ lang: "typescript",
39
+ kind: "client",
40
+ generator: "typescript-fetch",
41
+ outputDir: "/tmp/dist/sdk/auth/ts-client",
42
+ branch: "sdk/svc-auth/ts-client",
43
+ publishing: makePublishing(),
44
+ additionalProperties: {},
45
+ package: "@octalmesh/auth-client",
46
+ ...overrides,
47
+ };
48
+ }
49
+
50
+ /**
51
+ * Builds a {@link ResolvedContract} fixture containing a single artifact by
52
+ * default.
53
+ */
54
+ export function makeContract(
55
+ overrides: Partial<ResolvedContract> = {},
56
+ ): ResolvedContract {
57
+ return {
58
+ name: "auth",
59
+ title: "Auth Service API",
60
+ entrypoint: "/repo/specs/auth/openapi.yaml",
61
+ entrypointRelative: "specs/auth/openapi.yaml",
62
+ artifacts: [makeArtifact()],
63
+ ...overrides,
64
+ };
65
+ }
@@ -0,0 +1,93 @@
1
+ import { createHash } from "node:crypto";
2
+
3
+ import { afterEach, beforeEach, describe, expect, it } from "vitest";
4
+
5
+ import { hashSpec, resolveVersion } from "./version";
6
+
7
+ describe("resolveVersion", () => {
8
+ const originalOverride = process.env.SDK_VERSION_OVERRIDE;
9
+
10
+ beforeEach(() => {
11
+ delete process.env.SDK_VERSION_OVERRIDE;
12
+ });
13
+
14
+ afterEach(() => {
15
+ if (originalOverride === undefined) {
16
+ delete process.env.SDK_VERSION_OVERRIDE;
17
+ } else {
18
+ process.env.SDK_VERSION_OVERRIDE = originalOverride;
19
+ }
20
+ });
21
+
22
+ it("returns info.version from the spec, stripped of a leading 'v'", () => {
23
+ expect(resolveVersion({ info: { version: "1.2.3" } }, "auth")).toBe(
24
+ "1.2.3",
25
+ );
26
+ expect(resolveVersion({ info: { version: "v1.2.3" } }, "auth")).toBe(
27
+ "1.2.3",
28
+ );
29
+ });
30
+
31
+ it("trims whitespace around info.version", () => {
32
+ expect(resolveVersion({ info: { version: " 1.0.0 " } }, "auth")).toBe(
33
+ "1.0.0",
34
+ );
35
+ });
36
+
37
+ it("throws a descriptive error when info.version is missing", () => {
38
+ expect(() => resolveVersion({}, "auth")).toThrow(
39
+ /specs\/auth\/openapi\.yaml is missing "info\.version"/,
40
+ );
41
+ });
42
+
43
+ it("throws when info.version is present but empty/whitespace-only", () => {
44
+ expect(() =>
45
+ resolveVersion({ info: { version: " " } }, "catalog"),
46
+ ).toThrow(/specs\/catalog\/openapi\.yaml is missing "info\.version"/);
47
+ });
48
+
49
+ it("SDK_VERSION_OVERRIDE bypasses info.version entirely", () => {
50
+ process.env.SDK_VERSION_OVERRIDE = "9.9.9";
51
+
52
+ expect(resolveVersion({}, "auth")).toBe("9.9.9");
53
+ expect(resolveVersion({ info: { version: "1.0.0" } }, "auth")).toBe(
54
+ "9.9.9",
55
+ );
56
+ });
57
+
58
+ it("strips a leading 'v' from SDK_VERSION_OVERRIDE too", () => {
59
+ process.env.SDK_VERSION_OVERRIDE = "v2.0.0";
60
+
61
+ expect(resolveVersion({}, "auth")).toBe("2.0.0");
62
+ });
63
+
64
+ it("treats a blank SDK_VERSION_OVERRIDE as unset", () => {
65
+ process.env.SDK_VERSION_OVERRIDE = " ";
66
+
67
+ expect(() => resolveVersion({}, "auth")).toThrow(
68
+ /is missing "info\.version"/,
69
+ );
70
+ });
71
+ });
72
+
73
+ describe("hashSpec", () => {
74
+ it("computes a stable sha256 hex digest of the raw content", () => {
75
+ const raw = '{"info":{"version":"1.0.0"}}';
76
+
77
+ expect(hashSpec(raw)).toBe(createHash("sha256").update(raw).digest("hex"));
78
+ });
79
+
80
+ it("is deterministic for the same input", () => {
81
+ const raw = '{"a":1}';
82
+
83
+ expect(hashSpec(raw)).toBe(hashSpec(raw));
84
+ });
85
+
86
+ it("produces different hashes for different content", () => {
87
+ expect(hashSpec('{"a":1}')).not.toBe(hashSpec('{"a":2}'));
88
+ });
89
+
90
+ it("is sensitive to whitespace differences (raw text, not semantic JSON)", () => {
91
+ expect(hashSpec('{"a":1}')).not.toBe(hashSpec('{ "a": 1 }'));
92
+ });
93
+ });
@@ -54,12 +54,14 @@ export function resolveVersion(
54
54
  }
55
55
 
56
56
  /**
57
- * Computes a stable content hash of a bundled OpenAPI document's raw JSON text.
57
+ * Computes a stable content hash of a bundled OpenAPI document's raw file
58
+ * contents (JSON or YAML, whichever `paths.specFormat` produced).
59
+ *
58
60
  * Stamped alongside `VERSION` into every generated SDK package so
59
61
  * `publish-sdk.ts` can tell a genuine no-op republish (same spec, same version)
60
62
  * apart from a spec that changed without its `info.version` being bumped.
61
63
  *
62
- * @param raw - The raw bundled spec file contents (JSON text).
64
+ * @param raw - The raw bundled spec file contents.
63
65
  * @returns A `sha256` hex digest of the raw contents.
64
66
  */
65
67
  export function hashSpec(raw: string): string {