galileo-generated 0.2.8 → 0.2.9

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 (28) hide show
  1. package/.release-please-config.json +7 -0
  2. package/.release-please-manifest.json +1 -1
  3. package/dist/commonjs/hooks/registration.d.ts.map +1 -1
  4. package/dist/commonjs/hooks/registration.js +4 -0
  5. package/dist/commonjs/hooks/registration.js.map +1 -1
  6. package/dist/commonjs/hooks/sdk-identifier.d.ts +5 -0
  7. package/dist/commonjs/hooks/sdk-identifier.d.ts.map +1 -0
  8. package/dist/commonjs/hooks/sdk-identifier.js +37 -0
  9. package/dist/commonjs/hooks/sdk-identifier.js.map +1 -0
  10. package/dist/commonjs/tests/hooks/sdk-identifier.test.d.ts +2 -0
  11. package/dist/commonjs/tests/hooks/sdk-identifier.test.d.ts.map +1 -0
  12. package/dist/commonjs/tests/hooks/sdk-identifier.test.js +136 -0
  13. package/dist/commonjs/tests/hooks/sdk-identifier.test.js.map +1 -0
  14. package/dist/esm/hooks/registration.d.ts.map +1 -1
  15. package/dist/esm/hooks/registration.js +4 -0
  16. package/dist/esm/hooks/registration.js.map +1 -1
  17. package/dist/esm/hooks/sdk-identifier.d.ts +5 -0
  18. package/dist/esm/hooks/sdk-identifier.d.ts.map +1 -0
  19. package/dist/esm/hooks/sdk-identifier.js +33 -0
  20. package/dist/esm/hooks/sdk-identifier.js.map +1 -0
  21. package/dist/esm/tests/hooks/sdk-identifier.test.d.ts +2 -0
  22. package/dist/esm/tests/hooks/sdk-identifier.test.d.ts.map +1 -0
  23. package/dist/esm/tests/hooks/sdk-identifier.test.js +134 -0
  24. package/dist/esm/tests/hooks/sdk-identifier.test.js.map +1 -0
  25. package/package.json +1 -1
  26. package/src/hooks/registration.ts +5 -0
  27. package/src/hooks/sdk-identifier.ts +41 -0
  28. package/src/tests/hooks/sdk-identifier.test.ts +176 -0
@@ -10,6 +10,13 @@
10
10
  {"type": "perf", "section": "Performance"},
11
11
  {"type": "docs", "section": "Documentation"},
12
12
  {"type": "chore", "section": "Miscellaneous"}
13
+ ],
14
+ "extra-files": [
15
+ {
16
+ "type": "yaml",
17
+ "path": ".speakeasy/gen.yaml",
18
+ "jsonpath": "$.typescript.version"
19
+ }
13
20
  ]
14
21
  }
15
22
  }
@@ -1,3 +1,3 @@
1
1
  {
2
- ".": "0.2.8"
2
+ ".": "0.2.9"
3
3
  }
@@ -1 +1 @@
1
- {"version":3,"file":"registration.d.ts","sourceRoot":"","sources":["../../../src/hooks/registration.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAQxC,wBAAgB,SAAS,CAAC,KAAK,EAAE,KAAK,QAarC"}
1
+ {"version":3,"file":"registration.d.ts","sourceRoot":"","sources":["../../../src/hooks/registration.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAQxC,wBAAgB,SAAS,CAAC,KAAK,EAAE,KAAK,QAiBrC"}
@@ -4,6 +4,7 @@ exports.initHooks = initHooks;
4
4
  const cert_management_js_1 = require("./cert-management.js");
5
5
  const error_cleaner_js_1 = require("./error-cleaner.js");
6
6
  const token_management_js_1 = require("./token-management.js");
7
+ const sdk_identifier_js_1 = require("./sdk-identifier.js");
7
8
  /*
8
9
  * This file is only ever generated once on the first generation and then is free to be modified.
9
10
  * Any hooks you wish to add should be registered in the initHooks function. Feel free to define them
@@ -20,5 +21,8 @@ function initHooks(hooks) {
20
21
  // Register error cleaning hook
21
22
  const errorCleanerHook = new error_cleaner_js_1.ErrorCleanerHook();
22
23
  hooks.registerAfterErrorHook(errorCleanerHook);
24
+ // Register SDK identifier hook
25
+ const sdkIdentifierHook = new sdk_identifier_js_1.SDKIdentifierHook();
26
+ hooks.registerBeforeRequestHook(sdkIdentifierHook);
23
27
  }
24
28
  //# sourceMappingURL=registration.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"registration.js","sourceRoot":"","sources":["../../../src/hooks/registration.ts"],"names":[],"mappings":";;AAWA,8BAaC;AAxBD,6DAA0D;AAC1D,yDAAsD;AACtD,+DAA4D;AAG5D;;;;GAIG;AAEH,SAAgB,SAAS,CAAC,KAAY;IACrC,mDAAmD;IACnD,MAAM,QAAQ,GAAG,IAAI,uCAAkB,EAAE,CAAC;IAC1C,KAAK,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IAEpC,kCAAkC;IAClC,MAAM,SAAS,GAAG,IAAI,yCAAmB,EAAE,CAAC;IAC5C,KAAK,CAAC,yBAAyB,CAAC,SAAS,CAAC,CAAC;IAC3C,KAAK,CAAC,wBAAwB,CAAC,SAAS,CAAC,CAAC;IAE1C,+BAA+B;IAC/B,MAAM,gBAAgB,GAAG,IAAI,mCAAgB,EAAE,CAAC;IAChD,KAAK,CAAC,sBAAsB,CAAC,gBAAgB,CAAC,CAAC;AAChD,CAAC"}
1
+ {"version":3,"file":"registration.js","sourceRoot":"","sources":["../../../src/hooks/registration.ts"],"names":[],"mappings":";;AAYA,8BAiBC;AA7BD,6DAA0D;AAC1D,yDAAsD;AACtD,+DAA4D;AAC5D,2DAAwD;AAGxD;;;;GAIG;AAEH,SAAgB,SAAS,CAAC,KAAY;IACrC,mDAAmD;IACnD,MAAM,QAAQ,GAAG,IAAI,uCAAkB,EAAE,CAAC;IAC1C,KAAK,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IAEpC,kCAAkC;IAClC,MAAM,SAAS,GAAG,IAAI,yCAAmB,EAAE,CAAC;IAC5C,KAAK,CAAC,yBAAyB,CAAC,SAAS,CAAC,CAAC;IAC3C,KAAK,CAAC,wBAAwB,CAAC,SAAS,CAAC,CAAC;IAE1C,+BAA+B;IAC/B,MAAM,gBAAgB,GAAG,IAAI,mCAAgB,EAAE,CAAC;IAChD,KAAK,CAAC,sBAAsB,CAAC,gBAAgB,CAAC,CAAC;IAE/C,+BAA+B;IAC/B,MAAM,iBAAiB,GAAG,IAAI,qCAAiB,EAAE,CAAC;IAClD,KAAK,CAAC,yBAAyB,CAAC,iBAAiB,CAAC,CAAC;AACpD,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { BeforeRequestContext, BeforeRequestHook } from "./types.js";
2
+ export declare class SDKIdentifierHook implements BeforeRequestHook {
3
+ beforeRequest(_hookCtx: BeforeRequestContext, request: Request): Promise<Request>;
4
+ }
5
+ //# sourceMappingURL=sdk-identifier.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdk-identifier.d.ts","sourceRoot":"","sources":["../../../src/hooks/sdk-identifier.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AA4B1E,qBAAa,iBAAkB,YAAW,iBAAiB;IACnD,aAAa,CACjB,QAAQ,EAAE,oBAAoB,EAC9B,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,OAAO,CAAC;CAQpB"}
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SDKIdentifierHook = void 0;
4
+ let cachedVersion = null;
5
+ function loadVersion() {
6
+ if (cachedVersion) {
7
+ return cachedVersion;
8
+ }
9
+ try {
10
+ // NOTES: require is being used for now, using import demands appropriate
11
+ // compiler configuration, which won't be enabled yet due to Speakeasy's
12
+ // particular way of enabling persistent edits conflicting with workflow.
13
+ // Ticket sc-56960 created for this investigation.
14
+ const packageJsonPath = require.resolve("galileo-generated/package.json");
15
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
16
+ const packageJson = require(packageJsonPath);
17
+ cachedVersion = packageJson.version;
18
+ return cachedVersion ?? "unknown";
19
+ }
20
+ catch {
21
+ return "unknown";
22
+ }
23
+ }
24
+ function getSdkIdentifier(version) {
25
+ return `galileo-generated/${version}`;
26
+ }
27
+ class SDKIdentifierHook {
28
+ async beforeRequest(_hookCtx, request) {
29
+ const newRequest = request.clone();
30
+ const version = loadVersion();
31
+ const sdkIdentifier = getSdkIdentifier(version);
32
+ newRequest.headers.set("X-Galileo-SDK", sdkIdentifier);
33
+ return newRequest;
34
+ }
35
+ }
36
+ exports.SDKIdentifierHook = SDKIdentifierHook;
37
+ //# sourceMappingURL=sdk-identifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdk-identifier.js","sourceRoot":"","sources":["../../../src/hooks/sdk-identifier.ts"],"names":[],"mappings":";;;AAEA,IAAI,aAAa,GAAkB,IAAI,CAAC;AAExC,SAAS,WAAW;IAClB,IAAI,aAAa,EAAE,CAAC;QAClB,OAAO,aAAa,CAAC;IACvB,CAAC;IAED,IAAI,CAAC;QACH,yEAAyE;QACzE,wEAAwE;QACxE,yEAAyE;QACzE,kDAAkD;QAClD,MAAM,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC,gCAAgC,CAAC,CAAC;QAC1E,iEAAiE;QACjE,MAAM,WAAW,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;QAC7C,aAAa,GAAG,WAAW,CAAC,OAAO,CAAC;QACpC,OAAO,aAAa,IAAI,SAAS,CAAC;IACpC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CAAC,OAAe;IACvC,OAAO,qBAAqB,OAAO,EAAE,CAAC;AACxC,CAAC;AAED,MAAa,iBAAiB;IAC5B,KAAK,CAAC,aAAa,CACjB,QAA8B,EAC9B,OAAgB;QAEhB,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;QAEnC,MAAM,OAAO,GAAG,WAAW,EAAE,CAAC;QAC9B,MAAM,aAAa,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAChD,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,aAAa,CAAC,CAAC;QACvD,OAAO,UAAU,CAAC;IACpB,CAAC;CACF;AAZD,8CAYC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=sdk-identifier.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdk-identifier.test.d.ts","sourceRoot":"","sources":["../../../../src/tests/hooks/sdk-identifier.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,136 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const sdk_identifier_js_1 = require("../../hooks/sdk-identifier.js");
5
+ (0, vitest_1.describe)("SDKIdentifierHook", () => {
6
+ const mockContext = {
7
+ baseURL: new URL("http://localhost:8088"),
8
+ operationID: "testOperation",
9
+ oAuth2Scopes: null,
10
+ retryConfig: { strategy: "none" },
11
+ resolvedSecurity: null,
12
+ options: {},
13
+ };
14
+ (0, vitest_1.describe)("beforeRequest", () => {
15
+ (0, vitest_1.test)("adds X-Galileo-SDK header to request", async () => {
16
+ const hook = new sdk_identifier_js_1.SDKIdentifierHook();
17
+ const request = new Request("http://localhost:8088/api/test");
18
+ const modifiedRequest = await hook.beforeRequest(mockContext, request);
19
+ (0, vitest_1.expect)(modifiedRequest.headers.has("X-Galileo-SDK")).toBe(true);
20
+ });
21
+ (0, vitest_1.test)("header contains galileo-generated prefix", async () => {
22
+ const hook = new sdk_identifier_js_1.SDKIdentifierHook();
23
+ const request = new Request("http://localhost:8088/api/test");
24
+ const modifiedRequest = await hook.beforeRequest(mockContext, request);
25
+ const headerValue = modifiedRequest.headers.get("X-Galileo-SDK");
26
+ (0, vitest_1.expect)(headerValue).toMatch(/^galileo-generated\//);
27
+ });
28
+ (0, vitest_1.test)("header contains valid version format", async () => {
29
+ const hook = new sdk_identifier_js_1.SDKIdentifierHook();
30
+ const request = new Request("http://localhost:8088/api/test");
31
+ const modifiedRequest = await hook.beforeRequest(mockContext, request);
32
+ const headerValue = modifiedRequest.headers.get("X-Galileo-SDK");
33
+ (0, vitest_1.expect)(headerValue).toMatch(/^galileo-generated\/\d+\.\d+\.\d+/);
34
+ });
35
+ (0, vitest_1.test)("preserves existing headers", async () => {
36
+ const hook = new sdk_identifier_js_1.SDKIdentifierHook();
37
+ const request = new Request("http://localhost:8088/api/test", {
38
+ headers: {
39
+ "Content-Type": "application/json",
40
+ Authorization: "Bearer token",
41
+ },
42
+ });
43
+ const modifiedRequest = await hook.beforeRequest(mockContext, request);
44
+ (0, vitest_1.expect)(modifiedRequest.headers.get("Content-Type")).toBe("application/json");
45
+ (0, vitest_1.expect)(modifiedRequest.headers.get("Authorization")).toBe("Bearer token");
46
+ (0, vitest_1.expect)(modifiedRequest.headers.has("X-Galileo-SDK")).toBe(true);
47
+ });
48
+ (0, vitest_1.test)("returns a Request object", async () => {
49
+ const hook = new sdk_identifier_js_1.SDKIdentifierHook();
50
+ const request = new Request("http://localhost:8088/api/test");
51
+ const result = await hook.beforeRequest(mockContext, request);
52
+ (0, vitest_1.expect)(result instanceof Request).toBe(true);
53
+ });
54
+ (0, vitest_1.test)("does not modify request method or body", async () => {
55
+ const hook = new sdk_identifier_js_1.SDKIdentifierHook();
56
+ const body = JSON.stringify({ test: "data" });
57
+ const request = new Request("http://localhost:8088/api/test", {
58
+ method: "POST",
59
+ body,
60
+ });
61
+ const modifiedRequest = await hook.beforeRequest(mockContext, request);
62
+ (0, vitest_1.expect)(modifiedRequest.method).toBe("POST");
63
+ });
64
+ (0, vitest_1.test)("works with different HTTP methods", async () => {
65
+ const hook = new sdk_identifier_js_1.SDKIdentifierHook();
66
+ for (const method of ["GET", "POST", "PUT", "DELETE", "PATCH"]) {
67
+ const request = new Request("http://localhost:8088/api/test", {
68
+ method,
69
+ });
70
+ const modifiedRequest = await hook.beforeRequest(mockContext, request);
71
+ (0, vitest_1.expect)(modifiedRequest.headers.has("X-Galileo-SDK")).toBe(true);
72
+ (0, vitest_1.expect)(modifiedRequest.method).toBe(method);
73
+ }
74
+ });
75
+ (0, vitest_1.test)("header value is consistent across multiple calls", async () => {
76
+ const hook = new sdk_identifier_js_1.SDKIdentifierHook();
77
+ const request1 = new Request("http://localhost:8088/api/test");
78
+ const request2 = new Request("http://localhost:8088/api/test");
79
+ const modifiedRequest1 = await hook.beforeRequest(mockContext, request1);
80
+ const modifiedRequest2 = await hook.beforeRequest(mockContext, request2);
81
+ const header1 = modifiedRequest1.headers.get("X-Galileo-SDK");
82
+ const header2 = modifiedRequest2.headers.get("X-Galileo-SDK");
83
+ (0, vitest_1.expect)(header1).toBe(header2);
84
+ });
85
+ (0, vitest_1.test)("overwrites existing X-Galileo-SDK header", async () => {
86
+ const hook = new sdk_identifier_js_1.SDKIdentifierHook();
87
+ const request = new Request("http://localhost:8088/api/test", {
88
+ headers: {
89
+ "X-Galileo-SDK": "old-value",
90
+ },
91
+ });
92
+ const modifiedRequest = await hook.beforeRequest(mockContext, request);
93
+ const headerValue = modifiedRequest.headers.get("X-Galileo-SDK");
94
+ (0, vitest_1.expect)(headerValue).toMatch(/^galileo-generated\//);
95
+ (0, vitest_1.expect)(headerValue).not.toBe("old-value");
96
+ });
97
+ (0, vitest_1.test)("handles loadVersion() failure gracefully with fallback to unknown", async () => {
98
+ vitest_1.vi.resetModules();
99
+ vitest_1.vi.doMock("../../hooks/sdk-identifier.js", async () => {
100
+ return {
101
+ SDKIdentifierHook: class {
102
+ async beforeRequest(_hookCtx, request) {
103
+ const newRequest = request.clone();
104
+ const loadVersionWithFailure = () => {
105
+ try {
106
+ throw new Error("Failed to load package.json (ESM runtime issue)");
107
+ }
108
+ catch {
109
+ return "unknown";
110
+ }
111
+ };
112
+ const version = loadVersionWithFailure();
113
+ const sdkIdentifier = `galileo-generated/${version}`;
114
+ newRequest.headers.set("X-Galileo-SDK", sdkIdentifier);
115
+ return newRequest;
116
+ }
117
+ },
118
+ };
119
+ });
120
+ const { SDKIdentifierHook: MockedHook } = await import("../../hooks/sdk-identifier.js");
121
+ const hook = new MockedHook();
122
+ const request = new Request("http://localhost:8088/api/test");
123
+ const modifiedRequest = await hook.beforeRequest(mockContext, request);
124
+ const headerValue = modifiedRequest.headers.get("X-Galileo-SDK");
125
+ (0, vitest_1.expect)(headerValue).toBe("galileo-generated/unknown");
126
+ vitest_1.vi.doUnmock("../../hooks/sdk-identifier.js");
127
+ });
128
+ });
129
+ (0, vitest_1.describe)("hook integration", () => {
130
+ (0, vitest_1.test)("hook implements BeforeRequestHook interface", () => {
131
+ const hook = new sdk_identifier_js_1.SDKIdentifierHook();
132
+ (0, vitest_1.expect)(typeof hook.beforeRequest).toBe("function");
133
+ });
134
+ });
135
+ });
136
+ //# sourceMappingURL=sdk-identifier.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdk-identifier.test.js","sourceRoot":"","sources":["../../../../src/tests/hooks/sdk-identifier.test.ts"],"names":[],"mappings":";;AAAA,mCAAoD;AACpD,qEAAkE;AAGlE,IAAA,iBAAQ,EAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,MAAM,WAAW,GAAyB;QACxC,OAAO,EAAE,IAAI,GAAG,CAAC,uBAAuB,CAAC;QACzC,WAAW,EAAE,eAAe;QAC5B,YAAY,EAAE,IAAI;QAClB,WAAW,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE;QACjC,gBAAgB,EAAE,IAAI;QACtB,OAAO,EAAE,EAAE;KACZ,CAAC;IAEF,IAAA,iBAAQ,EAAC,eAAe,EAAE,GAAG,EAAE;QAC7B,IAAA,aAAI,EAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;YACtD,MAAM,IAAI,GAAG,IAAI,qCAAiB,EAAE,CAAC;YACrC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,gCAAgC,CAAC,CAAC;YAE9D,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;YAEvE,IAAA,eAAM,EAAC,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClE,CAAC,CAAC,CAAC;QAEH,IAAA,aAAI,EAAC,0CAA0C,EAAE,KAAK,IAAI,EAAE;YAC1D,MAAM,IAAI,GAAG,IAAI,qCAAiB,EAAE,CAAC;YACrC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,gCAAgC,CAAC,CAAC;YAE9D,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;YACvE,MAAM,WAAW,GAAG,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;YAEjE,IAAA,eAAM,EAAC,WAAW,CAAC,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;QACtD,CAAC,CAAC,CAAC;QAEH,IAAA,aAAI,EAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;YACtD,MAAM,IAAI,GAAG,IAAI,qCAAiB,EAAE,CAAC;YACrC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,gCAAgC,CAAC,CAAC;YAE9D,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;YACvE,MAAM,WAAW,GAAG,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;YAEjE,IAAA,eAAM,EAAC,WAAW,CAAC,CAAC,OAAO,CAAC,mCAAmC,CAAC,CAAC;QACnE,CAAC,CAAC,CAAC;QAEH,IAAA,aAAI,EAAC,4BAA4B,EAAE,KAAK,IAAI,EAAE;YAC5C,MAAM,IAAI,GAAG,IAAI,qCAAiB,EAAE,CAAC;YACrC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,gCAAgC,EAAE;gBAC5D,OAAO,EAAE;oBACP,cAAc,EAAE,kBAAkB;oBAClC,aAAa,EAAE,cAAc;iBAC9B;aACF,CAAC,CAAC;YAEH,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;YAEvE,IAAA,eAAM,EAAC,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;YAC7E,IAAA,eAAM,EAAC,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAC1E,IAAA,eAAM,EAAC,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClE,CAAC,CAAC,CAAC;QAEH,IAAA,aAAI,EAAC,0BAA0B,EAAE,KAAK,IAAI,EAAE;YAC1C,MAAM,IAAI,GAAG,IAAI,qCAAiB,EAAE,CAAC;YACrC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,gCAAgC,CAAC,CAAC;YAE9D,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;YAE9D,IAAA,eAAM,EAAC,MAAM,YAAY,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;QAEH,IAAA,aAAI,EAAC,wCAAwC,EAAE,KAAK,IAAI,EAAE;YACxD,MAAM,IAAI,GAAG,IAAI,qCAAiB,EAAE,CAAC;YACrC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;YAC9C,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,gCAAgC,EAAE;gBAC5D,MAAM,EAAE,MAAM;gBACd,IAAI;aACL,CAAC,CAAC;YAEH,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;YAEvE,IAAA,eAAM,EAAC,eAAe,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC9C,CAAC,CAAC,CAAC;QAEH,IAAA,aAAI,EAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE;YACnD,MAAM,IAAI,GAAG,IAAI,qCAAiB,EAAE,CAAC;YAErC,KAAK,MAAM,MAAM,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE,CAAC;gBAC/D,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,gCAAgC,EAAE;oBAC5D,MAAM;iBACP,CAAC,CAAC;gBAEH,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;gBAEvE,IAAA,eAAM,EAAC,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAChE,IAAA,eAAM,EAAC,eAAe,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC9C,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,IAAA,aAAI,EAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;YAClE,MAAM,IAAI,GAAG,IAAI,qCAAiB,EAAE,CAAC;YACrC,MAAM,QAAQ,GAAG,IAAI,OAAO,CAAC,gCAAgC,CAAC,CAAC;YAC/D,MAAM,QAAQ,GAAG,IAAI,OAAO,CAAC,gCAAgC,CAAC,CAAC;YAE/D,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;YACzE,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;YAEzE,MAAM,OAAO,GAAG,gBAAgB,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;YAC9D,MAAM,OAAO,GAAG,gBAAgB,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;YAE9D,IAAA,eAAM,EAAC,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;QAEH,IAAA,aAAI,EAAC,0CAA0C,EAAE,KAAK,IAAI,EAAE;YAC1D,MAAM,IAAI,GAAG,IAAI,qCAAiB,EAAE,CAAC;YACrC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,gCAAgC,EAAE;gBAC5D,OAAO,EAAE;oBACP,eAAe,EAAE,WAAW;iBAC7B;aACF,CAAC,CAAC;YAEH,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;YACvE,MAAM,WAAW,GAAG,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;YAEjE,IAAA,eAAM,EAAC,WAAW,CAAC,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;YACpD,IAAA,eAAM,EAAC,WAAW,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;QAEH,IAAA,aAAI,EAAC,mEAAmE,EAAE,KAAK,IAAI,EAAE;YACnF,WAAE,CAAC,YAAY,EAAE,CAAC;YAElB,WAAE,CAAC,MAAM,CAAC,+BAA+B,EAAE,KAAK,IAAI,EAAE;gBACpD,OAAO;oBACL,iBAAiB,EAAE;wBACjB,KAAK,CAAC,aAAa,CACjB,QAA8B,EAC9B,OAAgB;4BAEhB,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;4BAEnC,MAAM,sBAAsB,GAAG,GAAW,EAAE;gCAC1C,IAAI,CAAC;oCACH,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;gCACrE,CAAC;gCAAC,MAAM,CAAC;oCACP,OAAO,SAAS,CAAC;gCACnB,CAAC;4BACH,CAAC,CAAC;4BAEF,MAAM,OAAO,GAAG,sBAAsB,EAAE,CAAC;4BACzC,MAAM,aAAa,GAAG,qBAAqB,OAAO,EAAE,CAAC;4BACrD,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,aAAa,CAAC,CAAC;4BACvD,OAAO,UAAU,CAAC;wBACpB,CAAC;qBACF;iBACF,CAAC;YACJ,CAAC,CAAC,CAAC;YAEH,MAAM,EAAE,iBAAiB,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,+BAA+B,CAAC,CAAC;YACxF,MAAM,IAAI,GAAG,IAAI,UAAU,EAAE,CAAC;YAC9B,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,gCAAgC,CAAC,CAAC;YAE9D,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;YACvE,MAAM,WAAW,GAAG,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;YAEjE,IAAA,eAAM,EAAC,WAAW,CAAC,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;YAEtD,WAAE,CAAC,QAAQ,CAAC,+BAA+B,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,IAAA,iBAAQ,EAAC,kBAAkB,EAAE,GAAG,EAAE;QAChC,IAAA,aAAI,EAAC,6CAA6C,EAAE,GAAG,EAAE;YACvD,MAAM,IAAI,GAAG,IAAI,qCAAiB,EAAE,CAAC;YAErC,IAAA,eAAM,EAAC,OAAO,IAAI,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACrD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"registration.d.ts","sourceRoot":"","sources":["../../../src/hooks/registration.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAQxC,wBAAgB,SAAS,CAAC,KAAK,EAAE,KAAK,QAarC"}
1
+ {"version":3,"file":"registration.d.ts","sourceRoot":"","sources":["../../../src/hooks/registration.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAQxC,wBAAgB,SAAS,CAAC,KAAK,EAAE,KAAK,QAiBrC"}
@@ -1,6 +1,7 @@
1
1
  import { CertManagementHook } from "./cert-management.js";
2
2
  import { ErrorCleanerHook } from "./error-cleaner.js";
3
3
  import { TokenManagementHook } from "./token-management.js";
4
+ import { SDKIdentifierHook } from "./sdk-identifier.js";
4
5
  /*
5
6
  * This file is only ever generated once on the first generation and then is free to be modified.
6
7
  * Any hooks you wish to add should be registered in the initHooks function. Feel free to define them
@@ -17,5 +18,8 @@ export function initHooks(hooks) {
17
18
  // Register error cleaning hook
18
19
  const errorCleanerHook = new ErrorCleanerHook();
19
20
  hooks.registerAfterErrorHook(errorCleanerHook);
21
+ // Register SDK identifier hook
22
+ const sdkIdentifierHook = new SDKIdentifierHook();
23
+ hooks.registerBeforeRequestHook(sdkIdentifierHook);
20
24
  }
21
25
  //# sourceMappingURL=registration.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"registration.js","sourceRoot":"","sources":["../../../src/hooks/registration.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAG5D;;;;GAIG;AAEH,MAAM,UAAU,SAAS,CAAC,KAAY;IACrC,mDAAmD;IACnD,MAAM,QAAQ,GAAG,IAAI,kBAAkB,EAAE,CAAC;IAC1C,KAAK,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IAEpC,kCAAkC;IAClC,MAAM,SAAS,GAAG,IAAI,mBAAmB,EAAE,CAAC;IAC5C,KAAK,CAAC,yBAAyB,CAAC,SAAS,CAAC,CAAC;IAC3C,KAAK,CAAC,wBAAwB,CAAC,SAAS,CAAC,CAAC;IAE1C,+BAA+B;IAC/B,MAAM,gBAAgB,GAAG,IAAI,gBAAgB,EAAE,CAAC;IAChD,KAAK,CAAC,sBAAsB,CAAC,gBAAgB,CAAC,CAAC;AAChD,CAAC"}
1
+ {"version":3,"file":"registration.js","sourceRoot":"","sources":["../../../src/hooks/registration.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAGxD;;;;GAIG;AAEH,MAAM,UAAU,SAAS,CAAC,KAAY;IACrC,mDAAmD;IACnD,MAAM,QAAQ,GAAG,IAAI,kBAAkB,EAAE,CAAC;IAC1C,KAAK,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IAEpC,kCAAkC;IAClC,MAAM,SAAS,GAAG,IAAI,mBAAmB,EAAE,CAAC;IAC5C,KAAK,CAAC,yBAAyB,CAAC,SAAS,CAAC,CAAC;IAC3C,KAAK,CAAC,wBAAwB,CAAC,SAAS,CAAC,CAAC;IAE1C,+BAA+B;IAC/B,MAAM,gBAAgB,GAAG,IAAI,gBAAgB,EAAE,CAAC;IAChD,KAAK,CAAC,sBAAsB,CAAC,gBAAgB,CAAC,CAAC;IAE/C,+BAA+B;IAC/B,MAAM,iBAAiB,GAAG,IAAI,iBAAiB,EAAE,CAAC;IAClD,KAAK,CAAC,yBAAyB,CAAC,iBAAiB,CAAC,CAAC;AACpD,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { BeforeRequestContext, BeforeRequestHook } from "./types.js";
2
+ export declare class SDKIdentifierHook implements BeforeRequestHook {
3
+ beforeRequest(_hookCtx: BeforeRequestContext, request: Request): Promise<Request>;
4
+ }
5
+ //# sourceMappingURL=sdk-identifier.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdk-identifier.d.ts","sourceRoot":"","sources":["../../../src/hooks/sdk-identifier.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AA4B1E,qBAAa,iBAAkB,YAAW,iBAAiB;IACnD,aAAa,CACjB,QAAQ,EAAE,oBAAoB,EAC9B,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,OAAO,CAAC;CAQpB"}
@@ -0,0 +1,33 @@
1
+ let cachedVersion = null;
2
+ function loadVersion() {
3
+ if (cachedVersion) {
4
+ return cachedVersion;
5
+ }
6
+ try {
7
+ // NOTES: require is being used for now, using import demands appropriate
8
+ // compiler configuration, which won't be enabled yet due to Speakeasy's
9
+ // particular way of enabling persistent edits conflicting with workflow.
10
+ // Ticket sc-56960 created for this investigation.
11
+ const packageJsonPath = require.resolve("galileo-generated/package.json");
12
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
13
+ const packageJson = require(packageJsonPath);
14
+ cachedVersion = packageJson.version;
15
+ return cachedVersion ?? "unknown";
16
+ }
17
+ catch {
18
+ return "unknown";
19
+ }
20
+ }
21
+ function getSdkIdentifier(version) {
22
+ return `galileo-generated/${version}`;
23
+ }
24
+ export class SDKIdentifierHook {
25
+ async beforeRequest(_hookCtx, request) {
26
+ const newRequest = request.clone();
27
+ const version = loadVersion();
28
+ const sdkIdentifier = getSdkIdentifier(version);
29
+ newRequest.headers.set("X-Galileo-SDK", sdkIdentifier);
30
+ return newRequest;
31
+ }
32
+ }
33
+ //# sourceMappingURL=sdk-identifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdk-identifier.js","sourceRoot":"","sources":["../../../src/hooks/sdk-identifier.ts"],"names":[],"mappings":"AAEA,IAAI,aAAa,GAAkB,IAAI,CAAC;AAExC,SAAS,WAAW;IAClB,IAAI,aAAa,EAAE,CAAC;QAClB,OAAO,aAAa,CAAC;IACvB,CAAC;IAED,IAAI,CAAC;QACH,yEAAyE;QACzE,wEAAwE;QACxE,yEAAyE;QACzE,kDAAkD;QAClD,MAAM,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC,gCAAgC,CAAC,CAAC;QAC1E,iEAAiE;QACjE,MAAM,WAAW,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;QAC7C,aAAa,GAAG,WAAW,CAAC,OAAO,CAAC;QACpC,OAAO,aAAa,IAAI,SAAS,CAAC;IACpC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CAAC,OAAe;IACvC,OAAO,qBAAqB,OAAO,EAAE,CAAC;AACxC,CAAC;AAED,MAAM,OAAO,iBAAiB;IAC5B,KAAK,CAAC,aAAa,CACjB,QAA8B,EAC9B,OAAgB;QAEhB,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;QAEnC,MAAM,OAAO,GAAG,WAAW,EAAE,CAAC;QAC9B,MAAM,aAAa,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAChD,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,aAAa,CAAC,CAAC;QACvD,OAAO,UAAU,CAAC;IACpB,CAAC;CACF"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=sdk-identifier.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdk-identifier.test.d.ts","sourceRoot":"","sources":["../../../../src/tests/hooks/sdk-identifier.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,134 @@
1
+ import { describe, test, expect, vi } from "vitest";
2
+ import { SDKIdentifierHook } from "../../hooks/sdk-identifier.js";
3
+ describe("SDKIdentifierHook", () => {
4
+ const mockContext = {
5
+ baseURL: new URL("http://localhost:8088"),
6
+ operationID: "testOperation",
7
+ oAuth2Scopes: null,
8
+ retryConfig: { strategy: "none" },
9
+ resolvedSecurity: null,
10
+ options: {},
11
+ };
12
+ describe("beforeRequest", () => {
13
+ test("adds X-Galileo-SDK header to request", async () => {
14
+ const hook = new SDKIdentifierHook();
15
+ const request = new Request("http://localhost:8088/api/test");
16
+ const modifiedRequest = await hook.beforeRequest(mockContext, request);
17
+ expect(modifiedRequest.headers.has("X-Galileo-SDK")).toBe(true);
18
+ });
19
+ test("header contains galileo-generated prefix", async () => {
20
+ const hook = new SDKIdentifierHook();
21
+ const request = new Request("http://localhost:8088/api/test");
22
+ const modifiedRequest = await hook.beforeRequest(mockContext, request);
23
+ const headerValue = modifiedRequest.headers.get("X-Galileo-SDK");
24
+ expect(headerValue).toMatch(/^galileo-generated\//);
25
+ });
26
+ test("header contains valid version format", async () => {
27
+ const hook = new SDKIdentifierHook();
28
+ const request = new Request("http://localhost:8088/api/test");
29
+ const modifiedRequest = await hook.beforeRequest(mockContext, request);
30
+ const headerValue = modifiedRequest.headers.get("X-Galileo-SDK");
31
+ expect(headerValue).toMatch(/^galileo-generated\/\d+\.\d+\.\d+/);
32
+ });
33
+ test("preserves existing headers", async () => {
34
+ const hook = new SDKIdentifierHook();
35
+ const request = new Request("http://localhost:8088/api/test", {
36
+ headers: {
37
+ "Content-Type": "application/json",
38
+ Authorization: "Bearer token",
39
+ },
40
+ });
41
+ const modifiedRequest = await hook.beforeRequest(mockContext, request);
42
+ expect(modifiedRequest.headers.get("Content-Type")).toBe("application/json");
43
+ expect(modifiedRequest.headers.get("Authorization")).toBe("Bearer token");
44
+ expect(modifiedRequest.headers.has("X-Galileo-SDK")).toBe(true);
45
+ });
46
+ test("returns a Request object", async () => {
47
+ const hook = new SDKIdentifierHook();
48
+ const request = new Request("http://localhost:8088/api/test");
49
+ const result = await hook.beforeRequest(mockContext, request);
50
+ expect(result instanceof Request).toBe(true);
51
+ });
52
+ test("does not modify request method or body", async () => {
53
+ const hook = new SDKIdentifierHook();
54
+ const body = JSON.stringify({ test: "data" });
55
+ const request = new Request("http://localhost:8088/api/test", {
56
+ method: "POST",
57
+ body,
58
+ });
59
+ const modifiedRequest = await hook.beforeRequest(mockContext, request);
60
+ expect(modifiedRequest.method).toBe("POST");
61
+ });
62
+ test("works with different HTTP methods", async () => {
63
+ const hook = new SDKIdentifierHook();
64
+ for (const method of ["GET", "POST", "PUT", "DELETE", "PATCH"]) {
65
+ const request = new Request("http://localhost:8088/api/test", {
66
+ method,
67
+ });
68
+ const modifiedRequest = await hook.beforeRequest(mockContext, request);
69
+ expect(modifiedRequest.headers.has("X-Galileo-SDK")).toBe(true);
70
+ expect(modifiedRequest.method).toBe(method);
71
+ }
72
+ });
73
+ test("header value is consistent across multiple calls", async () => {
74
+ const hook = new SDKIdentifierHook();
75
+ const request1 = new Request("http://localhost:8088/api/test");
76
+ const request2 = new Request("http://localhost:8088/api/test");
77
+ const modifiedRequest1 = await hook.beforeRequest(mockContext, request1);
78
+ const modifiedRequest2 = await hook.beforeRequest(mockContext, request2);
79
+ const header1 = modifiedRequest1.headers.get("X-Galileo-SDK");
80
+ const header2 = modifiedRequest2.headers.get("X-Galileo-SDK");
81
+ expect(header1).toBe(header2);
82
+ });
83
+ test("overwrites existing X-Galileo-SDK header", async () => {
84
+ const hook = new SDKIdentifierHook();
85
+ const request = new Request("http://localhost:8088/api/test", {
86
+ headers: {
87
+ "X-Galileo-SDK": "old-value",
88
+ },
89
+ });
90
+ const modifiedRequest = await hook.beforeRequest(mockContext, request);
91
+ const headerValue = modifiedRequest.headers.get("X-Galileo-SDK");
92
+ expect(headerValue).toMatch(/^galileo-generated\//);
93
+ expect(headerValue).not.toBe("old-value");
94
+ });
95
+ test("handles loadVersion() failure gracefully with fallback to unknown", async () => {
96
+ vi.resetModules();
97
+ vi.doMock("../../hooks/sdk-identifier.js", async () => {
98
+ return {
99
+ SDKIdentifierHook: class {
100
+ async beforeRequest(_hookCtx, request) {
101
+ const newRequest = request.clone();
102
+ const loadVersionWithFailure = () => {
103
+ try {
104
+ throw new Error("Failed to load package.json (ESM runtime issue)");
105
+ }
106
+ catch {
107
+ return "unknown";
108
+ }
109
+ };
110
+ const version = loadVersionWithFailure();
111
+ const sdkIdentifier = `galileo-generated/${version}`;
112
+ newRequest.headers.set("X-Galileo-SDK", sdkIdentifier);
113
+ return newRequest;
114
+ }
115
+ },
116
+ };
117
+ });
118
+ const { SDKIdentifierHook: MockedHook } = await import("../../hooks/sdk-identifier.js");
119
+ const hook = new MockedHook();
120
+ const request = new Request("http://localhost:8088/api/test");
121
+ const modifiedRequest = await hook.beforeRequest(mockContext, request);
122
+ const headerValue = modifiedRequest.headers.get("X-Galileo-SDK");
123
+ expect(headerValue).toBe("galileo-generated/unknown");
124
+ vi.doUnmock("../../hooks/sdk-identifier.js");
125
+ });
126
+ });
127
+ describe("hook integration", () => {
128
+ test("hook implements BeforeRequestHook interface", () => {
129
+ const hook = new SDKIdentifierHook();
130
+ expect(typeof hook.beforeRequest).toBe("function");
131
+ });
132
+ });
133
+ });
134
+ //# sourceMappingURL=sdk-identifier.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdk-identifier.test.js","sourceRoot":"","sources":["../../../../src/tests/hooks/sdk-identifier.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "galileo-generated",
3
- "version": "0.2.8",
3
+ "version": "0.2.9",
4
4
  "author": "Galileo/Speakeasy",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1,6 +1,7 @@
1
1
  import { CertManagementHook } from "./cert-management.js";
2
2
  import { ErrorCleanerHook } from "./error-cleaner.js";
3
3
  import { TokenManagementHook } from "./token-management.js";
4
+ import { SDKIdentifierHook } from "./sdk-identifier.js";
4
5
  import type { Hooks } from "./types.js";
5
6
 
6
7
  /*
@@ -22,4 +23,8 @@ export function initHooks(hooks: Hooks) {
22
23
  // Register error cleaning hook
23
24
  const errorCleanerHook = new ErrorCleanerHook();
24
25
  hooks.registerAfterErrorHook(errorCleanerHook);
26
+
27
+ // Register SDK identifier hook
28
+ const sdkIdentifierHook = new SDKIdentifierHook();
29
+ hooks.registerBeforeRequestHook(sdkIdentifierHook);
25
30
  }
@@ -0,0 +1,41 @@
1
+ import type { BeforeRequestContext, BeforeRequestHook } from "./types.js";
2
+
3
+ let cachedVersion: string | null = null;
4
+
5
+ function loadVersion(): string {
6
+ if (cachedVersion) {
7
+ return cachedVersion;
8
+ }
9
+
10
+ try {
11
+ // NOTES: require is being used for now, using import demands appropriate
12
+ // compiler configuration, which won't be enabled yet due to Speakeasy's
13
+ // particular way of enabling persistent edits conflicting with workflow.
14
+ // Ticket sc-56960 created for this investigation.
15
+ const packageJsonPath = require.resolve("galileo-generated/package.json");
16
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
17
+ const packageJson = require(packageJsonPath);
18
+ cachedVersion = packageJson.version;
19
+ return cachedVersion ?? "unknown";
20
+ } catch {
21
+ return "unknown";
22
+ }
23
+ }
24
+
25
+ function getSdkIdentifier(version: string): string {
26
+ return `galileo-generated/${version}`;
27
+ }
28
+
29
+ export class SDKIdentifierHook implements BeforeRequestHook {
30
+ async beforeRequest(
31
+ _hookCtx: BeforeRequestContext,
32
+ request: Request,
33
+ ): Promise<Request> {
34
+ const newRequest = request.clone();
35
+
36
+ const version = loadVersion();
37
+ const sdkIdentifier = getSdkIdentifier(version);
38
+ newRequest.headers.set("X-Galileo-SDK", sdkIdentifier);
39
+ return newRequest;
40
+ }
41
+ }
@@ -0,0 +1,176 @@
1
+ import { describe, test, expect, vi } from "vitest";
2
+ import { SDKIdentifierHook } from "../../hooks/sdk-identifier.js";
3
+ import type { BeforeRequestContext } from "../../hooks/types.js";
4
+
5
+ describe("SDKIdentifierHook", () => {
6
+ const mockContext: BeforeRequestContext = {
7
+ baseURL: new URL("http://localhost:8088"),
8
+ operationID: "testOperation",
9
+ oAuth2Scopes: null,
10
+ retryConfig: { strategy: "none" },
11
+ resolvedSecurity: null,
12
+ options: {},
13
+ };
14
+
15
+ describe("beforeRequest", () => {
16
+ test("adds X-Galileo-SDK header to request", async () => {
17
+ const hook = new SDKIdentifierHook();
18
+ const request = new Request("http://localhost:8088/api/test");
19
+
20
+ const modifiedRequest = await hook.beforeRequest(mockContext, request);
21
+
22
+ expect(modifiedRequest.headers.has("X-Galileo-SDK")).toBe(true);
23
+ });
24
+
25
+ test("header contains galileo-generated prefix", async () => {
26
+ const hook = new SDKIdentifierHook();
27
+ const request = new Request("http://localhost:8088/api/test");
28
+
29
+ const modifiedRequest = await hook.beforeRequest(mockContext, request);
30
+ const headerValue = modifiedRequest.headers.get("X-Galileo-SDK");
31
+
32
+ expect(headerValue).toMatch(/^galileo-generated\//);
33
+ });
34
+
35
+ test("header contains valid version format", async () => {
36
+ const hook = new SDKIdentifierHook();
37
+ const request = new Request("http://localhost:8088/api/test");
38
+
39
+ const modifiedRequest = await hook.beforeRequest(mockContext, request);
40
+ const headerValue = modifiedRequest.headers.get("X-Galileo-SDK");
41
+
42
+ expect(headerValue).toMatch(/^galileo-generated\/\d+\.\d+\.\d+/);
43
+ });
44
+
45
+ test("preserves existing headers", async () => {
46
+ const hook = new SDKIdentifierHook();
47
+ const request = new Request("http://localhost:8088/api/test", {
48
+ headers: {
49
+ "Content-Type": "application/json",
50
+ Authorization: "Bearer token",
51
+ },
52
+ });
53
+
54
+ const modifiedRequest = await hook.beforeRequest(mockContext, request);
55
+
56
+ expect(modifiedRequest.headers.get("Content-Type")).toBe("application/json");
57
+ expect(modifiedRequest.headers.get("Authorization")).toBe("Bearer token");
58
+ expect(modifiedRequest.headers.has("X-Galileo-SDK")).toBe(true);
59
+ });
60
+
61
+ test("returns a Request object", async () => {
62
+ const hook = new SDKIdentifierHook();
63
+ const request = new Request("http://localhost:8088/api/test");
64
+
65
+ const result = await hook.beforeRequest(mockContext, request);
66
+
67
+ expect(result instanceof Request).toBe(true);
68
+ });
69
+
70
+ test("does not modify request method or body", async () => {
71
+ const hook = new SDKIdentifierHook();
72
+ const body = JSON.stringify({ test: "data" });
73
+ const request = new Request("http://localhost:8088/api/test", {
74
+ method: "POST",
75
+ body,
76
+ });
77
+
78
+ const modifiedRequest = await hook.beforeRequest(mockContext, request);
79
+
80
+ expect(modifiedRequest.method).toBe("POST");
81
+ });
82
+
83
+ test("works with different HTTP methods", async () => {
84
+ const hook = new SDKIdentifierHook();
85
+
86
+ for (const method of ["GET", "POST", "PUT", "DELETE", "PATCH"]) {
87
+ const request = new Request("http://localhost:8088/api/test", {
88
+ method,
89
+ });
90
+
91
+ const modifiedRequest = await hook.beforeRequest(mockContext, request);
92
+
93
+ expect(modifiedRequest.headers.has("X-Galileo-SDK")).toBe(true);
94
+ expect(modifiedRequest.method).toBe(method);
95
+ }
96
+ });
97
+
98
+ test("header value is consistent across multiple calls", async () => {
99
+ const hook = new SDKIdentifierHook();
100
+ const request1 = new Request("http://localhost:8088/api/test");
101
+ const request2 = new Request("http://localhost:8088/api/test");
102
+
103
+ const modifiedRequest1 = await hook.beforeRequest(mockContext, request1);
104
+ const modifiedRequest2 = await hook.beforeRequest(mockContext, request2);
105
+
106
+ const header1 = modifiedRequest1.headers.get("X-Galileo-SDK");
107
+ const header2 = modifiedRequest2.headers.get("X-Galileo-SDK");
108
+
109
+ expect(header1).toBe(header2);
110
+ });
111
+
112
+ test("overwrites existing X-Galileo-SDK header", async () => {
113
+ const hook = new SDKIdentifierHook();
114
+ const request = new Request("http://localhost:8088/api/test", {
115
+ headers: {
116
+ "X-Galileo-SDK": "old-value",
117
+ },
118
+ });
119
+
120
+ const modifiedRequest = await hook.beforeRequest(mockContext, request);
121
+ const headerValue = modifiedRequest.headers.get("X-Galileo-SDK");
122
+
123
+ expect(headerValue).toMatch(/^galileo-generated\//);
124
+ expect(headerValue).not.toBe("old-value");
125
+ });
126
+
127
+ test("handles loadVersion() failure gracefully with fallback to unknown", async () => {
128
+ vi.resetModules();
129
+
130
+ vi.doMock("../../hooks/sdk-identifier.js", async () => {
131
+ return {
132
+ SDKIdentifierHook: class {
133
+ async beforeRequest(
134
+ _hookCtx: BeforeRequestContext,
135
+ request: Request,
136
+ ): Promise<Request> {
137
+ const newRequest = request.clone();
138
+
139
+ const loadVersionWithFailure = (): string => {
140
+ try {
141
+ throw new Error("Failed to load package.json (ESM runtime issue)");
142
+ } catch {
143
+ return "unknown";
144
+ }
145
+ };
146
+
147
+ const version = loadVersionWithFailure();
148
+ const sdkIdentifier = `galileo-generated/${version}`;
149
+ newRequest.headers.set("X-Galileo-SDK", sdkIdentifier);
150
+ return newRequest;
151
+ }
152
+ },
153
+ };
154
+ });
155
+
156
+ const { SDKIdentifierHook: MockedHook } = await import("../../hooks/sdk-identifier.js");
157
+ const hook = new MockedHook();
158
+ const request = new Request("http://localhost:8088/api/test");
159
+
160
+ const modifiedRequest = await hook.beforeRequest(mockContext, request);
161
+ const headerValue = modifiedRequest.headers.get("X-Galileo-SDK");
162
+
163
+ expect(headerValue).toBe("galileo-generated/unknown");
164
+
165
+ vi.doUnmock("../../hooks/sdk-identifier.js");
166
+ });
167
+ });
168
+
169
+ describe("hook integration", () => {
170
+ test("hook implements BeforeRequestHook interface", () => {
171
+ const hook = new SDKIdentifierHook();
172
+
173
+ expect(typeof hook.beforeRequest).toBe("function");
174
+ });
175
+ });
176
+ });