@tenonhq/dovetail-dashboard 0.0.42 → 0.0.44

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 (2) hide show
  1. package/package.json +2 -2
  2. package/server.js +48 -24
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tenonhq/dovetail-dashboard",
3
- "version": "0.0.42",
3
+ "version": "0.0.44",
4
4
  "description": "Update Set Dashboard for Dovetail",
5
5
  "main": "server.js",
6
6
  "scripts": {
@@ -9,7 +9,7 @@
9
9
  "postpublish": "npm run version:bump"
10
10
  },
11
11
  "dependencies": {
12
- "@tenonhq/dovetail-claude-plans": "~0.0.23",
12
+ "@tenonhq/dovetail-claude-plans": "~0.0.26",
13
13
  "@tenonhq/dovetail-todo": "~0.0.1",
14
14
  "axios": "^1.5.1",
15
15
  "axios-cookiejar-support": "^4.0.7",
package/server.js CHANGED
@@ -99,38 +99,62 @@ var snClient = wrapper(axios.create({
99
99
  withCredentials: true,
100
100
  }));
101
101
 
102
- // Dovetail Scripted REST API rebrand: the API path moved from /api/cadso/claude/*
103
- // to /api/cadso/dovetail/*. snApi rewrites legacy /api/cadso/claude/* URLs to the
104
- // new path on first call; if that 404s (instance hasn't been re-imported yet) we
105
- // latch back to the legacy path for the rest of the session and warn once.
106
- var _dovetailApiUseLegacyClaudePath = false;
102
+ // Dovetail's core Scripted REST API now lives in the Dovetail scoped application
103
+ // at /api/cadso/dovetail_core/*. Older instances still expose the previous
104
+ // global-scope path /api/cadso/dovetail/*. Dashboard call sites still pass the
105
+ // original /api/cadso/claude/* paths; snApi maps them to dovetail_core first and,
106
+ // on a missing-endpoint error (404, or the 400 "Requested URI does not represent
107
+ // any resource" SN returns for an absent Scripted REST resource), latches to the
108
+ // legacy /api/cadso/dovetail/* path for the rest of the session and warns once.
109
+ // Mirrors packages/core/src/snClient.ts so the dashboard and the dove CLI agree.
110
+ var _dovetailApiUseLegacyPath = false;
111
+ var _SN_MISSING_ENDPOINT_BODY = "Requested URI does not represent any resource";
112
+
113
+ // True when an error means the Dovetail Scripted REST endpoint is absent on this
114
+ // instance: a 404, or the 400 body SN returns for an unknown scripted-REST URI.
115
+ function isMissingDovetailEndpoint(e) {
116
+ var status = e && e.response && e.response.status;
117
+ if (status === 404) return true;
118
+ if (status === 400) {
119
+ var data = e && e.response && e.response.data;
120
+ var body = "";
121
+ try {
122
+ body = typeof data === "string" ? data : JSON.stringify(data || "");
123
+ } catch (_e) {
124
+ body = "";
125
+ }
126
+ return body.indexOf(_SN_MISSING_ENDPOINT_BODY) !== -1;
127
+ }
128
+ return false;
129
+ }
130
+
131
+ // Map a dashboard call-site path (api/cadso/{claude,dovetail,dovetail_core}/<op>)
132
+ // to the active Dovetail scoped-API path. Returns null for non-scoped endpoints
133
+ // (e.g. api/now/table/*), which pass through unchanged.
134
+ function dovetailScopedPath(endpoint) {
135
+ var match = endpoint.match(
136
+ /^\/?api\/cadso\/(?:dovetail_core|dovetail|claude)\/(.*)$/
137
+ );
138
+ if (!match) return null;
139
+ var service = _dovetailApiUseLegacyPath ? "dovetail" : "dovetail_core";
140
+ return "api/cadso/" + service + "/" + match[1];
141
+ }
107
142
 
108
143
  async function snApi(method, endpoint, data) {
109
144
  await waitForRateLimit();
110
- // Rewrite legacy /api/cadso/claude/* call sites to the new dovetail path,
111
- // unless we've already discovered this instance only speaks the legacy path.
112
- var rewritten = endpoint;
113
- var isDovetailScopedApi = endpoint.indexOf("api/cadso/claude/") === 0
114
- || endpoint.indexOf("/api/cadso/claude/") === 0
115
- || endpoint.indexOf("api/cadso/dovetail/") === 0
116
- || endpoint.indexOf("/api/cadso/dovetail/") === 0;
117
- if (isDovetailScopedApi) {
118
- rewritten = _dovetailApiUseLegacyClaudePath
119
- ? endpoint.replace("api/cadso/dovetail/", "api/cadso/claude/")
120
- : endpoint.replace("api/cadso/claude/", "api/cadso/dovetail/");
121
- }
145
+ var scopedPath = dovetailScopedPath(endpoint);
146
+ var url = scopedPath || endpoint;
122
147
  try {
123
- return await snClient({ method: method, url: rewritten, data: data });
148
+ return await snClient({ method: method, url: url, data: data });
124
149
  } catch (e) {
125
- var status = e && e.response && e.response.status;
126
- if (isDovetailScopedApi && !_dovetailApiUseLegacyClaudePath && status === 404) {
150
+ if (scopedPath && !_dovetailApiUseLegacyPath && isMissingDovetailEndpoint(e)) {
127
151
  // eslint-disable-next-line no-console
128
152
  console.warn(
129
- "[deprecation] " + rewritten +
130
- " returned 404. Falling back to legacy /api/cadso/claude/* path. Re-import the Dovetail Scripted REST API XML on your ServiceNow instance to silence this warning.",
153
+ "[deprecation] " + url +
154
+ " not found. Falling back to legacy /api/cadso/dovetail/* path. Install the Dovetail application's Scripted REST APIs to silence this warning.",
131
155
  );
132
- _dovetailApiUseLegacyClaudePath = true;
133
- var legacyUrl = rewritten.replace("api/cadso/dovetail/", "api/cadso/claude/");
156
+ _dovetailApiUseLegacyPath = true;
157
+ var legacyUrl = dovetailScopedPath(endpoint);
134
158
  return await snClient({ method: method, url: legacyUrl, data: data });
135
159
  }
136
160
  throw e;