@ainyc/canonry 1.26.0 → 1.26.2

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.
@@ -72,6 +72,10 @@ Do not write config.yaml by hand; use "canonry init", "canonry settings", or "ca
72
72
  } catch {
73
73
  }
74
74
  }
75
+ if ("CANONRY_BASE_PATH" in process.env) {
76
+ const val = process.env.CANONRY_BASE_PATH.trim();
77
+ parsed.basePath = val || void 0;
78
+ }
75
79
  if (parsed.basePath) {
76
80
  const normalizedBase = "/" + parsed.basePath.replace(/^\/|\/$/g, "");
77
81
  try {
@@ -11428,7 +11432,12 @@ async function createServer(opts) {
11428
11432
  return reply.status(404).send({ error: "Not found" });
11429
11433
  });
11430
11434
  }
11431
- const healthHandler = async () => ({ status: "ok", service: "canonry", version: PKG_VERSION });
11435
+ const healthHandler = async () => ({
11436
+ status: "ok",
11437
+ service: "canonry",
11438
+ version: PKG_VERSION,
11439
+ ...basePath ? { basePath: basePath.replace(/\/$/, "") } : {}
11440
+ });
11432
11441
  app.get("/health", healthHandler);
11433
11442
  if (basePath) {
11434
11443
  app.get(`${basePath}health`, healthHandler);
package/dist/cli.js CHANGED
@@ -19,7 +19,7 @@ import {
19
19
  setGoogleAuthConfig,
20
20
  showFirstRunNotice,
21
21
  trackEvent
22
- } from "./chunk-L6TL4UQI.js";
22
+ } from "./chunk-NVCAUQ33.js";
23
23
 
24
24
  // src/cli.ts
25
25
  import { pathToFileURL } from "url";
@@ -148,14 +148,56 @@ Usage: ${spec.usage}`, {
148
148
  }
149
149
 
150
150
  // src/client.ts
151
+ function createApiClient() {
152
+ const config = loadConfig();
153
+ const basePathResolved = !!config.basePath || "CANONRY_BASE_PATH" in process.env;
154
+ return new ApiClient(config.apiUrl, config.apiKey, { skipProbe: basePathResolved });
155
+ }
151
156
  var ApiClient = class {
152
157
  baseUrl;
158
+ originUrl;
153
159
  apiKey;
154
- constructor(baseUrl, apiKey) {
155
- this.baseUrl = baseUrl.replace(/\/$/, "") + "/api/v1";
160
+ probePromise = null;
161
+ probeSkipped;
162
+ constructor(baseUrl, apiKey, opts) {
163
+ this.originUrl = baseUrl.replace(/\/$/, "");
164
+ this.baseUrl = this.originUrl + "/api/v1";
156
165
  this.apiKey = apiKey;
166
+ this.probeSkipped = opts?.skipProbe ?? false;
167
+ }
168
+ /**
169
+ * On first API call, probe /health to auto-discover basePath when the user
170
+ * hasn't configured one locally. This lets `canonry run` in a separate shell
171
+ * discover that the server is running at e.g. /canonry/ without requiring
172
+ * config.yaml edits or CANONRY_BASE_PATH in every shell.
173
+ */
174
+ probeBasePath() {
175
+ if (this.probeSkipped) return Promise.resolve();
176
+ if (!this.probePromise) {
177
+ this.probePromise = (async () => {
178
+ try {
179
+ const origin = new URL(this.originUrl).origin;
180
+ const res = await fetch(`${origin}/health`, {
181
+ signal: AbortSignal.timeout(2e3)
182
+ });
183
+ if (res.ok) {
184
+ const body = await res.json();
185
+ if (body.basePath && typeof body.basePath === "string") {
186
+ const normalized = "/" + body.basePath.replace(/^\/|\/$/g, "");
187
+ if (normalized !== "/") {
188
+ this.originUrl = origin + normalized;
189
+ this.baseUrl = this.originUrl + "/api/v1";
190
+ }
191
+ }
192
+ }
193
+ } catch {
194
+ }
195
+ })();
196
+ }
197
+ return this.probePromise;
157
198
  }
158
199
  async request(method, path4, body) {
200
+ await this.probeBasePath();
159
201
  const url = `${this.baseUrl}${path4}`;
160
202
  const serializedBody = body != null ? JSON.stringify(body) : void 0;
161
203
  const headers = {
@@ -440,8 +482,7 @@ var ApiClient = class {
440
482
 
441
483
  // src/commands/bing.ts
442
484
  function getClient() {
443
- const config = loadConfig();
444
- return new ApiClient(config.apiUrl, config.apiKey);
485
+ return createApiClient();
445
486
  }
446
487
  async function bingConnect(project, opts) {
447
488
  let apiKey = opts?.apiKey;
@@ -963,8 +1004,7 @@ var BING_CLI_COMMANDS = [
963
1004
 
964
1005
  // src/commands/cdp.ts
965
1006
  function getClient2() {
966
- const config = loadConfig();
967
- return new ApiClient(config.apiUrl, config.apiKey);
1007
+ return createApiClient();
968
1008
  }
969
1009
  async function cdpConnect(opts) {
970
1010
  const config = loadConfig();
@@ -1155,8 +1195,7 @@ var CDP_CLI_COMMANDS = [
1155
1195
 
1156
1196
  // src/commands/ga.ts
1157
1197
  function getClient3() {
1158
- const config = loadConfig();
1159
- return new ApiClient(config.apiUrl, config.apiKey);
1198
+ return createApiClient();
1160
1199
  }
1161
1200
  async function gaConnect(project, opts) {
1162
1201
  if (!opts.propertyId) {
@@ -1398,8 +1437,7 @@ var GA_CLI_COMMANDS = [
1398
1437
 
1399
1438
  // src/commands/competitor.ts
1400
1439
  function getClient4() {
1401
- const config = loadConfig();
1402
- return new ApiClient(config.apiUrl, config.apiKey);
1440
+ return createApiClient();
1403
1441
  }
1404
1442
  async function addCompetitors(project, domains, format) {
1405
1443
  const client = getClient4();
@@ -1480,8 +1518,7 @@ var COMPETITOR_CLI_COMMANDS = [
1480
1518
 
1481
1519
  // src/commands/google.ts
1482
1520
  function getClient5() {
1483
- const config = loadConfig();
1484
- return new ApiClient(config.apiUrl, config.apiKey);
1521
+ return createApiClient();
1485
1522
  }
1486
1523
  async function waitForRunStatus(client, runId, config) {
1487
1524
  const start = Date.now();
@@ -2308,8 +2345,7 @@ var GOOGLE_CLI_COMMANDS = [
2308
2345
  // src/commands/keyword.ts
2309
2346
  import fs from "fs";
2310
2347
  function getClient6() {
2311
- const config = loadConfig();
2312
- return new ApiClient(config.apiUrl, config.apiKey);
2348
+ return createApiClient();
2313
2349
  }
2314
2350
  async function addKeywords(project, keywords, format) {
2315
2351
  const client = getClient6();
@@ -2553,8 +2589,7 @@ var KEYWORD_CLI_COMMANDS = [
2553
2589
 
2554
2590
  // src/commands/notify.ts
2555
2591
  function getClient7() {
2556
- const config = loadConfig();
2557
- return new ApiClient(config.apiUrl, config.apiKey);
2592
+ return createApiClient();
2558
2593
  }
2559
2594
  async function addNotification(project, opts) {
2560
2595
  const client = getClient7();
@@ -2726,8 +2761,7 @@ async function applyConfigFile(filePath) {
2726
2761
  }
2727
2762
  const content = fs2.readFileSync(filePath, "utf-8");
2728
2763
  const docs = parseAllDocuments(content);
2729
- const clientConfig = loadConfig();
2730
- const client = new ApiClient(clientConfig.apiUrl, clientConfig.apiKey);
2764
+ const client = createApiClient();
2731
2765
  const errors = [];
2732
2766
  const applied = [];
2733
2767
  for (let i = 0; i < docs.length; i++) {
@@ -2789,8 +2823,7 @@ async function applyConfigs(filePaths, format) {
2789
2823
 
2790
2824
  // src/commands/analytics.ts
2791
2825
  function getClient8() {
2792
- const config = loadConfig();
2793
- return new ApiClient(config.apiUrl, config.apiKey);
2826
+ return createApiClient();
2794
2827
  }
2795
2828
  async function showAnalytics(project, options) {
2796
2829
  const client = getClient8();
@@ -2897,8 +2930,7 @@ Source Origin Breakdown`);
2897
2930
 
2898
2931
  // src/commands/evidence.ts
2899
2932
  function getClient9() {
2900
- const config = loadConfig();
2901
- return new ApiClient(config.apiUrl, config.apiKey);
2933
+ return createApiClient();
2902
2934
  }
2903
2935
  async function showEvidence(project, format) {
2904
2936
  const client = getClient9();
@@ -2933,8 +2965,7 @@ async function showEvidence(project, format) {
2933
2965
  // src/commands/export-cmd.ts
2934
2966
  import { stringify } from "yaml";
2935
2967
  async function exportProject(project, opts) {
2936
- const config = loadConfig();
2937
- const client = new ApiClient(config.apiUrl, config.apiKey);
2968
+ const client = createApiClient();
2938
2969
  const data = await client.getExport(project);
2939
2970
  if (opts.includeResults) {
2940
2971
  try {
@@ -2955,8 +2986,7 @@ async function exportProject(project, opts) {
2955
2986
 
2956
2987
  // src/commands/history.ts
2957
2988
  function getClient10() {
2958
- const config = loadConfig();
2959
- return new ApiClient(config.apiUrl, config.apiKey);
2989
+ return createApiClient();
2960
2990
  }
2961
2991
  async function showHistory(project, format) {
2962
2992
  const client = getClient10();
@@ -2995,8 +3025,7 @@ async function showHistory(project, format) {
2995
3025
 
2996
3026
  // src/commands/status.ts
2997
3027
  function getClient11() {
2998
- const config = loadConfig();
2999
- return new ApiClient(config.apiUrl, config.apiKey);
3028
+ return createApiClient();
3000
3029
  }
3001
3030
  async function showStatus(project, format) {
3002
3031
  const client = getClient11();
@@ -3108,8 +3137,7 @@ var OPERATOR_CLI_COMMANDS = [
3108
3137
 
3109
3138
  // src/commands/project.ts
3110
3139
  function getClient12() {
3111
- const config = loadConfig();
3112
- return new ApiClient(config.apiUrl, config.apiKey);
3140
+ return createApiClient();
3113
3141
  }
3114
3142
  async function createProject(name, opts) {
3115
3143
  const client = getClient12();
@@ -3445,8 +3473,7 @@ var PROJECT_CLI_COMMANDS = [
3445
3473
 
3446
3474
  // src/commands/run.ts
3447
3475
  function getClient13() {
3448
- const config = loadConfig();
3449
- return new ApiClient(config.apiUrl, config.apiKey);
3476
+ return createApiClient();
3450
3477
  }
3451
3478
  var TERMINAL_STATUSES = /* @__PURE__ */ new Set(["completed", "partial", "failed", "cancelled"]);
3452
3479
  async function triggerRun(project, opts) {
@@ -3775,8 +3802,7 @@ var RUN_CLI_COMMANDS = [
3775
3802
 
3776
3803
  // src/commands/schedule.ts
3777
3804
  function getClient14() {
3778
- const config = loadConfig();
3779
- return new ApiClient(config.apiUrl, config.apiKey);
3805
+ return createApiClient();
3780
3806
  }
3781
3807
  async function setSchedule(project, opts) {
3782
3808
  const client = getClient14();
@@ -3939,8 +3965,7 @@ var SCHEDULE_CLI_COMMANDS = [
3939
3965
 
3940
3966
  // src/commands/settings.ts
3941
3967
  function getClient15() {
3942
- const config = loadConfig();
3943
- return new ApiClient(config.apiUrl, config.apiKey);
3968
+ return createApiClient();
3944
3969
  }
3945
3970
  async function setProvider(name, opts) {
3946
3971
  const client = getClient15();
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createServer,
3
3
  loadConfig
4
- } from "./chunk-L6TL4UQI.js";
4
+ } from "./chunk-NVCAUQ33.js";
5
5
  export {
6
6
  createServer,
7
7
  loadConfig
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ainyc/canonry",
3
- "version": "1.26.0",
3
+ "version": "1.26.2",
4
4
  "type": "module",
5
5
  "description": "The ultimate open-source AEO monitoring tool - track how answer engines cite your domain",
6
6
  "license": "FSL-1.1-ALv2",
@@ -52,17 +52,17 @@
52
52
  "@types/node-cron": "^3.0.11",
53
53
  "tsup": "^8.5.1",
54
54
  "tsx": "^4.19.0",
55
- "@ainyc/canonry-api-routes": "0.0.0",
56
55
  "@ainyc/canonry-contracts": "0.0.0",
57
- "@ainyc/canonry-config": "0.0.0",
56
+ "@ainyc/canonry-api-routes": "0.0.0",
58
57
  "@ainyc/canonry-db": "0.0.0",
58
+ "@ainyc/canonry-config": "0.0.0",
59
59
  "@ainyc/canonry-provider-claude": "0.0.0",
60
+ "@ainyc/canonry-provider-gemini": "0.0.0",
60
61
  "@ainyc/canonry-provider-cdp": "0.0.0",
61
62
  "@ainyc/canonry-provider-local": "0.0.0",
62
63
  "@ainyc/canonry-integration-bing": "0.0.0",
63
64
  "@ainyc/canonry-integration-google": "0.0.0",
64
65
  "@ainyc/canonry-provider-openai": "0.0.0",
65
- "@ainyc/canonry-provider-gemini": "0.0.0",
66
66
  "@ainyc/canonry-provider-perplexity": "0.0.0"
67
67
  },
68
68
  "scripts": {