@icib.dev/api-client 1.0.3 → 1.0.5

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
@@ -41,6 +41,10 @@ npx api-client-generate --url https://api.example.com/docs/openapi --out api
41
41
 
42
42
  # Using BASE_URL env (default: $BASE_URL/docs/openapi)
43
43
  BASE_URL=https://api.example.com npx api-client-generate --out api
44
+
45
+ # Custom base path (default empty; when set, included in axios baseURL)
46
+ npx api-client-generate --base-path /v1/api
47
+ BASE_PATH=/v2 npx api-client-generate
44
48
  ```
45
49
 
46
50
  The client is generated in your project directory (e.g. `./api/`).
@@ -5,7 +5,7 @@ export function setAuthToken(token) {
5
5
  _token = token;
6
6
  }
7
7
  export const client = axios.create({
8
- baseURL: "https://api.example.com",
8
+ baseURL: "https://api.example.com/api",
9
9
  headers: {
10
10
  "Content-Type": "application/json",
11
11
  },
@@ -3,6 +3,6 @@ import { client } from "../client.js";
3
3
  /** API client for items endpoints */
4
4
  export const items = {
5
5
  async list() {
6
- return client.get("/api/items/");
6
+ return client.get("/items/");
7
7
  }
8
8
  };
@@ -3,14 +3,14 @@ import { readFileSync, mkdirSync, writeFileSync } from "fs";
3
3
  import { dirname, join } from "path";
4
4
  import { fileURLToPath } from "url";
5
5
  import SwaggerParser from "@apidevtools/swagger-parser";
6
- import { normalizedJsonHash, computeClientHash, } from "./hash.js";
6
+ import { normalizedJsonHash, computeClientHash } from "./hash.js";
7
7
  const __dirname = dirname(fileURLToPath(import.meta.url));
8
8
  const DEFAULT_OUT = "api";
9
9
  function getDefaultUrl() {
10
10
  const base = process.env.BASE_URL;
11
11
  if (base) {
12
12
  const normalized = base.replace(/\/$/, "");
13
- return `${normalized}/docs/openapi`;
13
+ return `${normalized}/docs/json`;
14
14
  }
15
15
  return "https://api.icib.dev/docs/?format=openapi";
16
16
  }
@@ -18,6 +18,7 @@ function parseArgs() {
18
18
  const args = process.argv.slice(2);
19
19
  let url = getDefaultUrl();
20
20
  let out = DEFAULT_OUT;
21
+ let basePath = process.env.BASE_PATH;
21
22
  for (let i = 0; i < args.length; i++) {
22
23
  if (args[i] === "--url" && args[i + 1]) {
23
24
  url = args[++i];
@@ -25,8 +26,12 @@ function parseArgs() {
25
26
  else if (args[i] === "--out" && args[i + 1]) {
26
27
  out = args[++i];
27
28
  }
29
+ else if ((args[i] === "--base-path" || args[i] === "--basePath") &&
30
+ args[i + 1]) {
31
+ basePath = args[++i];
32
+ }
28
33
  }
29
- return { url, out };
34
+ return { url, out, basePath };
30
35
  }
31
36
  async function fetchSpec(url) {
32
37
  const res = await fetch(url);
@@ -66,10 +71,6 @@ function getOrigin(doc) {
66
71
  }
67
72
  return "https://api.icib.dev";
68
73
  }
69
- function getBasePath(doc) {
70
- const oas2 = doc;
71
- return oas2.basePath ?? "/api";
72
- }
73
74
  function getDefinitions(doc) {
74
75
  return doc.definitions ?? doc.components?.schemas ?? {};
75
76
  }
@@ -168,11 +169,11 @@ function generateTypes(definitions) {
168
169
  lines.push("}\n");
169
170
  return lines.join("\n");
170
171
  }
171
- function extractOperations(paths, basePath, definitions) {
172
+ function extractOperations(paths, definitions) {
172
173
  const ops = [];
173
174
  const methods = ["get", "post", "put", "patch", "delete"];
174
175
  for (const [path, pathItem] of Object.entries(paths)) {
175
- const fullPath = basePath + (path.startsWith("/") ? path : `/${path}`);
176
+ const fullPath = path.startsWith("/") ? path : `/${path}`;
176
177
  for (const method of methods) {
177
178
  const op = pathItem[method];
178
179
  if (!op?.operationId)
@@ -615,18 +616,24 @@ function generateIndex(contextTags) {
615
616
  return exports.join("\n");
616
617
  }
617
618
  async function main() {
618
- const { url, out } = parseArgs();
619
+ const { url, out, basePath: basePathOverride } = parseArgs();
619
620
  console.log(`Fetching spec from ${url}...`);
620
621
  const rawSpec = await loadRawSpec(url);
621
622
  const doc = await parseSpec(rawSpec);
622
623
  const baseUrl = getOrigin(doc);
623
- const basePath = getBasePath(doc);
624
+ const basePath = (() => {
625
+ const raw = basePathOverride ?? "";
626
+ if (raw === "")
627
+ return "";
628
+ return raw.startsWith("/") ? raw : `/${raw}`;
629
+ })();
624
630
  const definitions = getDefinitions(doc);
625
631
  const paths = getPaths(doc);
626
632
  console.log(`Base URL: ${baseUrl}`);
633
+ console.log(`Base path: ${basePath}`);
627
634
  console.log(`Paths: ${Object.keys(paths).length}`);
628
635
  console.log(`Definitions: ${Object.keys(definitions).length}`);
629
- const ops = extractOperations(paths, basePath, definitions);
636
+ const ops = extractOperations(paths, definitions);
630
637
  const byTag = groupByTag(ops, paths);
631
638
  const cwd = process.cwd();
632
639
  const outDir = join(cwd, out);
@@ -634,8 +641,11 @@ async function main() {
634
641
  const contextsDir = join(outDir, "contexts");
635
642
  mkdirSync(typesDir, { recursive: true });
636
643
  mkdirSync(contextsDir, { recursive: true });
644
+ const clientBaseUrl = basePath
645
+ ? `${baseUrl.replace(/\/$/, "")}${basePath}`
646
+ : baseUrl;
637
647
  writeFileSync(join(typesDir, "index.ts"), generateTypes(definitions));
638
- writeFileSync(join(outDir, "client.ts"), generateClient(baseUrl));
648
+ writeFileSync(join(outDir, "client.ts"), generateClient(clientBaseUrl));
639
649
  const sortedTags = [...byTag.keys()].sort();
640
650
  for (const tag of sortedTags) {
641
651
  const ctxName = sanitizeContextName(tag);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@icib.dev/api-client",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "Strictly-typed TypeScript API client for ICIB API",
5
5
  "type": "module",
6
6
  "main": "./dist/api/index.js",