@aborruso/ckan-mcp-server 0.4.76 → 0.4.78
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/LOG.md +10 -0
- package/dist/index.js +99 -21
- package/dist/worker.js +3 -3
- package/package.json +2 -1
package/LOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# LOG
|
|
2
2
|
|
|
3
|
+
## 2026-03-08
|
|
4
|
+
|
|
5
|
+
- fix(`package.ts`): auto-convert `NOW` date math to ISO dates for `issued` and `modified` fields in `q` and `fq` — these are CKAN extra fields not native Solr fields, so `NOW` syntax returned 0 results on all portals tested (dati.gov.it, catalog.data.gov); ISO dates work universally
|
|
6
|
+
- fix(`package.ts`): fix `content_recent` clause to use ISO date for `issued` field (same root cause)
|
|
7
|
+
- docs(`tools.md`): clarify date math limitation — `NOW` only works on `metadata_modified`/`metadata_created`; `issued`/`modified` require explicit ISO dates (now auto-converted by server)
|
|
8
|
+
|
|
9
|
+
## 2026-03-07 (v0.4.77)
|
|
10
|
+
|
|
11
|
+
- fix(`http.ts`): remove `Referer`, `Sec-Fetch-*`, `Upgrade-Insecure-Requests` from axios headers — these triggered WAF block on BA Data (data.buenosaires.gob.ar) and other portals with strict WAF rules; dati.gov.it unaffected
|
|
12
|
+
|
|
3
13
|
## 2026-03-06 (v0.4.75)
|
|
4
14
|
|
|
5
15
|
- fix(`ckan_find_portals`): deduplicate portals by hostname, preferring https over http
|
package/dist/index.js
CHANGED
|
@@ -199,6 +199,10 @@ function getPortalApiPath(serverUrl) {
|
|
|
199
199
|
const portal = getPortalConfig(serverUrl);
|
|
200
200
|
return portal?.api_path || "/api/3/action";
|
|
201
201
|
}
|
|
202
|
+
function requiresMultilingualNormalization(serverUrl) {
|
|
203
|
+
const portal = getPortalConfig(serverUrl);
|
|
204
|
+
return portal?.normalize === "multilingual";
|
|
205
|
+
}
|
|
202
206
|
|
|
203
207
|
// src/utils/http.ts
|
|
204
208
|
var loadZlib = /* @__PURE__ */ (() => {
|
|
@@ -359,11 +363,6 @@ async function makeCkanRequest(serverUrl, action, params = {}) {
|
|
|
359
363
|
"Accept-Language": "en-US,en;q=0.9,it;q=0.8",
|
|
360
364
|
"Accept-Encoding": "gzip, deflate, br",
|
|
361
365
|
Connection: "keep-alive",
|
|
362
|
-
Referer: `${baseUrl}/`,
|
|
363
|
-
"Sec-Fetch-Site": "same-origin",
|
|
364
|
-
"Sec-Fetch-Mode": "navigate",
|
|
365
|
-
"Sec-Fetch-Dest": "document",
|
|
366
|
-
"Upgrade-Insecure-Requests": "1",
|
|
367
366
|
"Sec-CH-UA": '"Chromium";v="120", "Not?A_Brand";v="24", "Google Chrome";v="120"',
|
|
368
367
|
"Sec-CH-UA-Mobile": "?0",
|
|
369
368
|
"Sec-CH-UA-Platform": '"Linux"',
|
|
@@ -876,20 +875,94 @@ function resolvePageParams(page, pageSize, start, rows) {
|
|
|
876
875
|
}
|
|
877
876
|
return { effectiveStart: start, effectiveRows: rows };
|
|
878
877
|
}
|
|
878
|
+
function resolveNowExpr(nowExpr) {
|
|
879
|
+
const upper = nowExpr.toUpperCase();
|
|
880
|
+
const now = /* @__PURE__ */ new Date();
|
|
881
|
+
if (upper === "NOW") return now.toISOString();
|
|
882
|
+
const floorMatch = upper.match(/^NOW\/(DAY|MONTH)$/);
|
|
883
|
+
if (floorMatch) {
|
|
884
|
+
if (floorMatch[1] === "DAY") now.setUTCHours(0, 0, 0, 0);
|
|
885
|
+
else {
|
|
886
|
+
now.setUTCDate(1);
|
|
887
|
+
now.setUTCHours(0, 0, 0, 0);
|
|
888
|
+
}
|
|
889
|
+
return now.toISOString();
|
|
890
|
+
}
|
|
891
|
+
const arithMatch = upper.match(/^NOW([+-])(\d+)(YEARS?|MONTHS?|DAYS?|HOURS?|MINUTES?|SECONDS?)$/);
|
|
892
|
+
if (arithMatch) {
|
|
893
|
+
const sign = arithMatch[1] === "+" ? 1 : -1;
|
|
894
|
+
const n = parseInt(arithMatch[2]);
|
|
895
|
+
const unit = arithMatch[3].replace(/S$/, "");
|
|
896
|
+
switch (unit) {
|
|
897
|
+
case "YEAR":
|
|
898
|
+
now.setUTCFullYear(now.getUTCFullYear() + sign * n);
|
|
899
|
+
break;
|
|
900
|
+
case "MONTH":
|
|
901
|
+
now.setUTCMonth(now.getUTCMonth() + sign * n);
|
|
902
|
+
break;
|
|
903
|
+
case "DAY":
|
|
904
|
+
now.setUTCDate(now.getUTCDate() + sign * n);
|
|
905
|
+
break;
|
|
906
|
+
case "HOUR":
|
|
907
|
+
now.setUTCHours(now.getUTCHours() + sign * n);
|
|
908
|
+
break;
|
|
909
|
+
case "MINUTE":
|
|
910
|
+
now.setUTCMinutes(now.getUTCMinutes() + sign * n);
|
|
911
|
+
break;
|
|
912
|
+
case "SECOND":
|
|
913
|
+
now.setUTCSeconds(now.getUTCSeconds() + sign * n);
|
|
914
|
+
break;
|
|
915
|
+
}
|
|
916
|
+
return now.toISOString();
|
|
917
|
+
}
|
|
918
|
+
return nowExpr;
|
|
919
|
+
}
|
|
920
|
+
function convertNowForExtraFields(str) {
|
|
921
|
+
return str.replace(
|
|
922
|
+
/\b(issued|modified):\[([^\]]*)\]/gi,
|
|
923
|
+
(_match, field, range) => {
|
|
924
|
+
const converted = range.replace(
|
|
925
|
+
/\bNOW(?:[+-]\d+(?:YEARS?|MONTHS?|DAYS?|HOURS?|MINUTES?|SECONDS?)|\/(?:DAY|MONTH))?\b/gi,
|
|
926
|
+
(now) => resolveNowExpr(now)
|
|
927
|
+
);
|
|
928
|
+
return `${field}:[${converted}]`;
|
|
929
|
+
}
|
|
930
|
+
);
|
|
931
|
+
}
|
|
932
|
+
function normalizePackage(pkg) {
|
|
933
|
+
const translation = pkg.translation;
|
|
934
|
+
if (!pkg.title && translation) {
|
|
935
|
+
pkg = { ...pkg, title: translation.en?.title || Object.values(translation)[0]?.title };
|
|
936
|
+
}
|
|
937
|
+
if (!pkg.name) {
|
|
938
|
+
pkg = { ...pkg, name: pkg.id };
|
|
939
|
+
}
|
|
940
|
+
if (pkg.organization?.title && typeof pkg.organization.title === "object") {
|
|
941
|
+
const titleObj = pkg.organization.title;
|
|
942
|
+
pkg = { ...pkg, organization: { ...pkg.organization, title: titleObj.en || Object.values(titleObj)[0] } };
|
|
943
|
+
}
|
|
944
|
+
if (pkg.tags) {
|
|
945
|
+
pkg = { ...pkg, tags: pkg.tags.map((t) => t.name ? t : { ...t, name: t.id || t["display-name"] || "" }) };
|
|
946
|
+
}
|
|
947
|
+
return pkg;
|
|
948
|
+
}
|
|
879
949
|
function compactSearchResult(result, serverUrl) {
|
|
880
950
|
return {
|
|
881
951
|
count: result.count,
|
|
882
|
-
results: (result.results || []).map((
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
952
|
+
results: (result.results || []).map((rawPkg) => {
|
|
953
|
+
const pkg = serverUrl && requiresMultilingualNormalization(serverUrl) ? normalizePackage(rawPkg) : rawPkg;
|
|
954
|
+
return {
|
|
955
|
+
id: pkg.id,
|
|
956
|
+
name: pkg.name,
|
|
957
|
+
title: pkg.title || pkg.name,
|
|
958
|
+
notes: pkg.notes ? pkg.notes.substring(0, 200) + (pkg.notes.length > 200 ? "..." : "") : null,
|
|
959
|
+
organization: pkg.organization?.title || pkg.organization?.name || null,
|
|
960
|
+
tags: (pkg.tags || []).map((t) => t.name),
|
|
961
|
+
num_resources: pkg.num_resources ?? 0,
|
|
962
|
+
metadata_modified: pkg.metadata_modified,
|
|
963
|
+
...serverUrl ? { view_url: getDatasetViewUrl(serverUrl, pkg) } : {}
|
|
964
|
+
};
|
|
965
|
+
}),
|
|
893
966
|
...result.facets && Object.keys(result.facets).length > 0 ? { facets: result.facets } : {},
|
|
894
967
|
...result.search_facets && Object.keys(result.search_facets).length > 0 ? { search_facets: result.search_facets } : {}
|
|
895
968
|
};
|
|
@@ -1089,7 +1162,11 @@ Typical workflow: ckan_package_search \u2192 ckan_package_show (get full metadat
|
|
|
1089
1162
|
let effectiveSort = params.sort;
|
|
1090
1163
|
if (params.content_recent) {
|
|
1091
1164
|
const days = params.content_recent_days ?? 30;
|
|
1092
|
-
const
|
|
1165
|
+
const daysAgo = /* @__PURE__ */ new Date();
|
|
1166
|
+
daysAgo.setUTCDate(daysAgo.getUTCDate() - days);
|
|
1167
|
+
const daysAgoIso = daysAgo.toISOString();
|
|
1168
|
+
const nowIso = (/* @__PURE__ */ new Date()).toISOString();
|
|
1169
|
+
const recentClause = `(issued:[${daysAgoIso} TO ${nowIso}]) OR (-issued:* AND metadata_created:[NOW-${days}DAYS TO NOW])`;
|
|
1093
1170
|
query = userQuery && userQuery !== "*:*" ? `(${userQuery}) AND (${recentClause})` : recentClause;
|
|
1094
1171
|
if (!effectiveSort) effectiveSort = "issued desc, metadata_created desc";
|
|
1095
1172
|
}
|
|
@@ -1100,12 +1177,12 @@ Typical workflow: ckan_package_search \u2192 ckan_package_show (get full metadat
|
|
|
1100
1177
|
);
|
|
1101
1178
|
const { effectiveRows, effectiveStart } = resolvePageParams(params.page, params.page_size, params.start, params.rows);
|
|
1102
1179
|
const apiParams = {
|
|
1103
|
-
q: effectiveQuery,
|
|
1180
|
+
q: convertNowForExtraFields(effectiveQuery),
|
|
1104
1181
|
rows: effectiveRows,
|
|
1105
1182
|
start: effectiveStart,
|
|
1106
1183
|
include_private: params.include_drafts
|
|
1107
1184
|
};
|
|
1108
|
-
if (params.fq) apiParams.fq = params.fq;
|
|
1185
|
+
if (params.fq) apiParams.fq = convertNowForExtraFields(params.fq);
|
|
1109
1186
|
if (effectiveSort) apiParams.sort = effectiveSort;
|
|
1110
1187
|
if (params.facet_field && params.facet_field.length > 0) {
|
|
1111
1188
|
apiParams["facet.field"] = JSON.stringify(params.facet_field);
|
|
@@ -1208,7 +1285,8 @@ Note: showing top ${sorted.length} only. Use \`response_format: json\` for full
|
|
|
1208
1285
|
markdown += `## Datasets
|
|
1209
1286
|
|
|
1210
1287
|
`;
|
|
1211
|
-
for (const
|
|
1288
|
+
for (const rawPkg of result.results) {
|
|
1289
|
+
const pkg = requiresMultilingualNormalization(params.server_url) ? normalizePackage(rawPkg) : rawPkg;
|
|
1212
1290
|
markdown += `### ${pkg.title || pkg.name}
|
|
1213
1291
|
|
|
1214
1292
|
`;
|
|
@@ -4955,7 +5033,7 @@ var registerAllPrompts = (server2) => {
|
|
|
4955
5033
|
function createServer() {
|
|
4956
5034
|
return new McpServer({
|
|
4957
5035
|
name: "ckan-mcp-server",
|
|
4958
|
-
version: "0.4.
|
|
5036
|
+
version: "0.4.78"
|
|
4959
5037
|
});
|
|
4960
5038
|
}
|
|
4961
5039
|
function registerAll(server2) {
|
package/dist/worker.js
CHANGED
|
@@ -41,7 +41,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
41
41
|
`)}getSetCookie(){return this.get("set-cookie")||[]}get[Symbol.toStringTag](){return"AxiosHeaders"}static from(e){return e instanceof this?e:new this(e)}static concat(e,...r){let n=new this(e);return r.forEach(o=>n.set(o)),n}static accessor(e){let n=(this[cv]=this[cv]={accessors:{}}).accessors,o=this.prototype;function s(i){let a=hs(i);n[a]||(kA(o,i),n[a]=!0)}return y.isArray(e)?e.forEach(s):s(e),this}};ro.accessor(["Content-Type","Content-Length","Accept","Accept-Encoding","User-Agent","Authorization"]);y.reduceDescriptors(ro.prototype,({value:t},e)=>{let r=e[0].toUpperCase()+e.slice(1);return{get:()=>t,set(n){this[r]=n}}});y.freezeMethods(ro);var Te=ro;function gs(t,e){let r=this||to,n=e||r,o=Te.from(n.headers),s=n.data;return y.forEach(t,function(a){s=a.call(r,s,o.normalize(),e?e.status:void 0)}),o.normalize(),s}function ys(t){return!!(t&&t.__CANCEL__)}function uv(t,e,r){Z.call(this,t??"canceled",Z.ERR_CANCELED,e,r),this.name="CanceledError"}y.inherits(uv,Z,{__CANCEL__:!0});var Lt=uv;function _s(t,e,r){let n=r.config.validateStatus;!r.status||!n||n(r.status)?t(r):e(new Z("Request failed with status code "+r.status,[Z.ERR_BAD_REQUEST,Z.ERR_BAD_RESPONSE][Math.floor(r.status/100)-4],r.config,r.request,r))}function Ef(t){let e=/^([-+\w]{1,25})(:?\/\/|:)/.exec(t);return e&&e[1]||""}function $A(t,e){t=t||10;let r=new Array(t),n=new Array(t),o=0,s=0,i;return e=e!==void 0?e:1e3,function(c){let u=Date.now(),l=n[s];i||(i=u),r[o]=c,n[o]=u;let d=s,h=0;for(;d!==o;)h+=r[d++],d=d%t;if(o=(o+1)%t,o===s&&(s=(s+1)%t),u-i<e)return;let p=l&&u-l;return p?Math.round(h*1e3/p):void 0}}var lv=$A;function SA(t,e){let r=0,n=1e3/e,o,s,i=(u,l=Date.now())=>{r=l,o=null,s&&(clearTimeout(s),s=null),t(...u)};return[(...u)=>{let l=Date.now(),d=l-r;d>=n?i(u,l):(o=u,s||(s=setTimeout(()=>{s=null,i(o)},n-d)))},()=>o&&i(o)]}var dv=SA;var no=(t,e,r=3)=>{let n=0,o=lv(50,250);return dv(s=>{let i=s.loaded,a=s.lengthComputable?s.total:void 0,c=i-n,u=o(c),l=i<=a;n=i;let d={loaded:i,total:a,progress:a?i/a:void 0,bytes:c,rate:u||void 0,estimated:u&&a&&l?(a-i)/u:void 0,event:s,lengthComputable:a!=null,[e?"download":"upload"]:!0};t(d)},r)},Pf=(t,e)=>{let r=t!=null;return[n=>e[0]({lengthComputable:r,total:t,loaded:n}),e[1]]},Af=t=>(...e)=>y.asap(()=>t(...e));var fv=ke.hasStandardBrowserEnv?((t,e)=>r=>(r=new URL(r,ke.origin),t.protocol===r.protocol&&t.host===r.host&&(e||t.port===r.port)))(new URL(ke.origin),ke.navigator&&/(msie|trident)/i.test(ke.navigator.userAgent)):()=>!0;var pv=ke.hasStandardBrowserEnv?{write(t,e,r,n,o,s,i){if(typeof document>"u")return;let a=[`${t}=${encodeURIComponent(e)}`];y.isNumber(r)&&a.push(`expires=${new Date(r).toUTCString()}`),y.isString(n)&&a.push(`path=${n}`),y.isString(o)&&a.push(`domain=${o}`),s===!0&&a.push("secure"),y.isString(i)&&a.push(`SameSite=${i}`),document.cookie=a.join("; ")},read(t){if(typeof document>"u")return null;let e=document.cookie.match(new RegExp("(?:^|; )"+t+"=([^;]*)"));return e?decodeURIComponent(e[1]):null},remove(t){this.write(t,"",Date.now()-864e5,"/")}}:{write(){},read(){return null},remove(){}};function Of(t){return/^([a-z][a-z\d+\-.]*:)?\/\//i.test(t)}function Nf(t,e){return e?t.replace(/\/?\/$/,"")+"/"+e.replace(/^\/+/,""):t}function vs(t,e,r){let n=!Of(e);return t&&(n||r==!1)?Nf(t,e):e}var mv=t=>t instanceof Te?{...t}:t;function zt(t,e){e=e||{};let r={};function n(u,l,d,h){return y.isPlainObject(u)&&y.isPlainObject(l)?y.merge.call({caseless:h},u,l):y.isPlainObject(l)?y.merge({},l):y.isArray(l)?l.slice():l}function o(u,l,d,h){if(y.isUndefined(l)){if(!y.isUndefined(u))return n(void 0,u,d,h)}else return n(u,l,d,h)}function s(u,l){if(!y.isUndefined(l))return n(void 0,l)}function i(u,l){if(y.isUndefined(l)){if(!y.isUndefined(u))return n(void 0,u)}else return n(void 0,l)}function a(u,l,d){if(d in e)return n(u,l);if(d in t)return n(void 0,u)}let c={url:s,method:s,data:s,baseURL:i,transformRequest:i,transformResponse:i,paramsSerializer:i,timeout:i,timeoutMessage:i,withCredentials:i,withXSRFToken:i,adapter:i,responseType:i,xsrfCookieName:i,xsrfHeaderName:i,onUploadProgress:i,onDownloadProgress:i,decompress:i,maxContentLength:i,maxBodyLength:i,beforeRedirect:i,transport:i,httpAgent:i,httpsAgent:i,cancelToken:i,socketPath:i,responseEncoding:i,validateStatus:a,headers:(u,l,d)=>o(mv(u),mv(l),d,!0)};return y.forEach(Object.keys({...t,...e}),function(l){let d=c[l]||o,h=d(t[l],e[l],l);y.isUndefined(h)&&d!==a||(r[l]=h)}),r}var $a=t=>{let e=zt({},t),{data:r,withXSRFToken:n,xsrfHeaderName:o,xsrfCookieName:s,headers:i,auth:a}=e;if(e.headers=i=Te.from(i),e.url=ms(vs(e.baseURL,e.url,e.allowAbsoluteUrls),t.params,t.paramsSerializer),a&&i.set("Authorization","Basic "+btoa((a.username||"")+":"+(a.password?unescape(encodeURIComponent(a.password)):""))),y.isFormData(r)){if(ke.hasStandardBrowserEnv||ke.hasStandardBrowserWebWorkerEnv)i.setContentType(void 0);else if(y.isFunction(r.getHeaders)){let c=r.getHeaders(),u=["content-type","content-length"];Object.entries(c).forEach(([l,d])=>{u.includes(l.toLowerCase())&&i.set(l,d)})}}if(ke.hasStandardBrowserEnv&&(n&&y.isFunction(n)&&(n=n(e)),n||n!==!1&&fv(e.url))){let c=o&&s&&pv.read(s);c&&i.set(o,c)}return e};var zA=typeof XMLHttpRequest<"u",hv=zA&&function(t){return new Promise(function(r,n){let o=$a(t),s=o.data,i=Te.from(o.headers).normalize(),{responseType:a,onUploadProgress:c,onDownloadProgress:u}=o,l,d,h,p,f;function m(){p&&p(),f&&f(),o.cancelToken&&o.cancelToken.unsubscribe(l),o.signal&&o.signal.removeEventListener("abort",l)}let g=new XMLHttpRequest;g.open(o.method.toUpperCase(),o.url,!0),g.timeout=o.timeout;function _(){if(!g)return;let k=Te.from("getAllResponseHeaders"in g&&g.getAllResponseHeaders()),A={data:!a||a==="text"||a==="json"?g.responseText:g.response,status:g.status,statusText:g.statusText,headers:k,config:t,request:g};_s(function(pe){r(pe),m()},function(pe){n(pe),m()},A),g=null}"onloadend"in g?g.onloadend=_:g.onreadystatechange=function(){!g||g.readyState!==4||g.status===0&&!(g.responseURL&&g.responseURL.indexOf("file:")===0)||setTimeout(_)},g.onabort=function(){g&&(n(new Z("Request aborted",Z.ECONNABORTED,t,g)),g=null)},g.onerror=function(z){let A=z&&z.message?z.message:"Network Error",be=new Z(A,Z.ERR_NETWORK,t,g);be.event=z||null,n(be),g=null},g.ontimeout=function(){let z=o.timeout?"timeout of "+o.timeout+"ms exceeded":"timeout exceeded",A=o.transitional||wa;o.timeoutErrorMessage&&(z=o.timeoutErrorMessage),n(new Z(z,A.clarifyTimeoutError?Z.ETIMEDOUT:Z.ECONNABORTED,t,g)),g=null},s===void 0&&i.setContentType(null),"setRequestHeader"in g&&y.forEach(i.toJSON(),function(z,A){g.setRequestHeader(A,z)}),y.isUndefined(o.withCredentials)||(g.withCredentials=!!o.withCredentials),a&&a!=="json"&&(g.responseType=o.responseType),u&&([h,f]=no(u,!0),g.addEventListener("progress",h)),c&&g.upload&&([d,p]=no(c),g.upload.addEventListener("progress",d),g.upload.addEventListener("loadend",p)),(o.cancelToken||o.signal)&&(l=k=>{g&&(n(!k||k.type?new Lt(null,t,g):k),g.abort(),g=null)},o.cancelToken&&o.cancelToken.subscribe(l),o.signal&&(o.signal.aborted?l():o.signal.addEventListener("abort",l)));let x=Ef(o.url);if(x&&ke.protocols.indexOf(x)===-1){n(new Z("Unsupported protocol "+x+":",Z.ERR_BAD_REQUEST,t));return}g.send(s||null)})};var TA=(t,e)=>{let{length:r}=t=t?t.filter(Boolean):[];if(e||r){let n=new AbortController,o,s=function(u){if(!o){o=!0,a();let l=u instanceof Error?u:this.reason;n.abort(l instanceof Z?l:new Lt(l instanceof Error?l.message:l))}},i=e&&setTimeout(()=>{i=null,s(new Z(`timeout ${e} of ms exceeded`,Z.ETIMEDOUT))},e),a=()=>{t&&(i&&clearTimeout(i),i=null,t.forEach(u=>{u.unsubscribe?u.unsubscribe(s):u.removeEventListener("abort",s)}),t=null)};t.forEach(u=>u.addEventListener("abort",s));let{signal:c}=n;return c.unsubscribe=()=>y.asap(a),c}},gv=TA;var RA=function*(t,e){let r=t.byteLength;if(!e||r<e){yield t;return}let n=0,o;for(;n<r;)o=n+e,yield t.slice(n,o),n=o},EA=async function*(t,e){for await(let r of PA(t))yield*RA(r,e)},PA=async function*(t){if(t[Symbol.asyncIterator]){yield*t;return}let e=t.getReader();try{for(;;){let{done:r,value:n}=await e.read();if(r)break;yield n}}finally{await e.cancel()}},Cf=(t,e,r,n)=>{let o=EA(t,e),s=0,i,a=c=>{i||(i=!0,n&&n(c))};return new ReadableStream({async pull(c){try{let{done:u,value:l}=await o.next();if(u){a(),c.close();return}let d=l.byteLength;if(r){let h=s+=d;r(h)}c.enqueue(new Uint8Array(l))}catch(u){throw a(u),u}},cancel(c){return a(c),o.return()}},{highWaterMark:2})};var yv=64*1024,{isFunction:Sa}=y,AA=(({Request:t,Response:e})=>({Request:t,Response:e}))(y.global),{ReadableStream:_v,TextEncoder:vv}=y.global,bv=(t,...e)=>{try{return!!t(...e)}catch{return!1}},OA=t=>{t=y.merge.call({skipUndefined:!0},AA,t);let{fetch:e,Request:r,Response:n}=t,o=e?Sa(e):typeof fetch=="function",s=Sa(r),i=Sa(n);if(!o)return!1;let a=o&&Sa(_v),c=o&&(typeof vv=="function"?(f=>m=>f.encode(m))(new vv):async f=>new Uint8Array(await new r(f).arrayBuffer())),u=s&&a&&bv(()=>{let f=!1,m=new r(ke.origin,{body:new _v,method:"POST",get duplex(){return f=!0,"half"}}).headers.has("Content-Type");return f&&!m}),l=i&&a&&bv(()=>y.isReadableStream(new n("").body)),d={stream:l&&(f=>f.body)};o&&["text","arrayBuffer","blob","formData","stream"].forEach(f=>{!d[f]&&(d[f]=(m,g)=>{let _=m&&m[f];if(_)return _.call(m);throw new Z(`Response type '${f}' is not supported`,Z.ERR_NOT_SUPPORT,g)})});let h=async f=>{if(f==null)return 0;if(y.isBlob(f))return f.size;if(y.isSpecCompliantForm(f))return(await new r(ke.origin,{method:"POST",body:f}).arrayBuffer()).byteLength;if(y.isArrayBufferView(f)||y.isArrayBuffer(f))return f.byteLength;if(y.isURLSearchParams(f)&&(f=f+""),y.isString(f))return(await c(f)).byteLength},p=async(f,m)=>{let g=y.toFiniteNumber(f.getContentLength());return g??h(m)};return async f=>{let{url:m,method:g,data:_,signal:x,cancelToken:k,timeout:z,onDownloadProgress:A,onUploadProgress:be,responseType:pe,headers:Tt,withCredentials:rr="same-origin",fetchOptions:nr}=$a(f),yn=e||fetch;pe=pe?(pe+"").toLowerCase():"text";let Ar=gv([x,k&&k.toAbortSignal()],z),or=null,Ht=Ar&&Ar.unsubscribe&&(()=>{Ar.unsubscribe()}),Wf;try{if(be&&u&&g!=="get"&&g!=="head"&&(Wf=await p(Tt,_))!==0){let ir=new r(m,{method:"POST",body:_,duplex:"half"}),_n;if(y.isFormData(_)&&(_n=ir.headers.get("content-type"))&&Tt.setContentType(_n),ir.body){let[qa,ks]=Pf(Wf,no(Af(be)));_=Cf(ir.body,yv,qa,ks)}}y.isString(rr)||(rr=rr?"include":"omit");let Rt=s&&"credentials"in r.prototype,Qf={...nr,signal:Ar,method:g.toUpperCase(),headers:Tt.normalize().toJSON(),body:_,duplex:"half",credentials:Rt?rr:void 0};or=s&&new r(m,Qf);let sr=await(s?yn(or,nr):yn(m,Qf)),Xf=l&&(pe==="stream"||pe==="response");if(l&&(A||Xf&&Ht)){let ir={};["status","statusText","headers"].forEach(Yf=>{ir[Yf]=sr[Yf]});let _n=y.toFiniteNumber(sr.headers.get("content-length")),[qa,ks]=A&&Pf(_n,no(Af(A),!0))||[];sr=new n(Cf(sr.body,yv,qa,()=>{ks&&ks(),Ht&&Ht()}),ir)}pe=pe||"text";let $b=await d[y.findKey(d,pe)||"text"](sr,f);return!Xf&&Ht&&Ht(),await new Promise((ir,_n)=>{_s(ir,_n,{data:$b,headers:Te.from(sr.headers),status:sr.status,statusText:sr.statusText,config:f,request:or})})}catch(Rt){throw Ht&&Ht(),Rt&&Rt.name==="TypeError"&&/Load failed|fetch/i.test(Rt.message)?Object.assign(new Z("Network Error",Z.ERR_NETWORK,f,or),{cause:Rt.cause||Rt}):Z.from(Rt,Rt&&Rt.code,f,or)}}},NA=new Map,If=t=>{let e=t&&t.env||{},{fetch:r,Request:n,Response:o}=e,s=[n,o,r],i=s.length,a=i,c,u,l=NA;for(;a--;)c=s[a],u=l.get(c),u===void 0&&l.set(c,u=a?new Map:OA(e)),l=u;return u},QZ=If();var Mf={http:va,xhr:hv,fetch:{get:If}};y.forEach(Mf,(t,e)=>{if(t){try{Object.defineProperty(t,"name",{value:e})}catch{}Object.defineProperty(t,"adapterName",{value:e})}});var wv=t=>`- ${t}`,IA=t=>y.isFunction(t)||t===null||t===!1;function MA(t,e){t=y.isArray(t)?t:[t];let{length:r}=t,n,o,s={};for(let i=0;i<r;i++){n=t[i];let a;if(o=n,!IA(n)&&(o=Mf[(a=String(n)).toLowerCase()],o===void 0))throw new Z(`Unknown adapter '${a}'`);if(o&&(y.isFunction(o)||(o=o.get(e))))break;s[a||"#"+i]=o}if(!o){let i=Object.entries(s).map(([c,u])=>`adapter ${c} `+(u===!1?"is not supported by the environment":"is not available in the build")),a=r?i.length>1?`since :
|
|
42
42
|
`+i.map(wv).join(`
|
|
43
43
|
`):" "+wv(i[0]):"as no adapter specified";throw new Z("There is no suitable adapter to dispatch the request "+a,"ERR_NOT_SUPPORT")}return o}var za={getAdapter:MA,adapters:Mf};function jf(t){if(t.cancelToken&&t.cancelToken.throwIfRequested(),t.signal&&t.signal.aborted)throw new Lt(null,t)}function Ta(t){return jf(t),t.headers=Te.from(t.headers),t.data=gs.call(t,t.transformRequest),["post","put","patch"].indexOf(t.method)!==-1&&t.headers.setContentType("application/x-www-form-urlencoded",!1),za.getAdapter(t.adapter||to.adapter,t)(t).then(function(n){return jf(t),n.data=gs.call(t,t.transformResponse,n),n.headers=Te.from(n.headers),n},function(n){return ys(n)||(jf(t),n&&n.response&&(n.response.data=gs.call(t,t.transformResponse,n.response),n.response.headers=Te.from(n.response.headers))),Promise.reject(n)})}var Ra="1.13.2";var Ea={};["object","boolean","number","function","string","symbol"].forEach((t,e)=>{Ea[t]=function(n){return typeof n===t||"a"+(e<1?"n ":" ")+t}});var xv={};Ea.transitional=function(e,r,n){function o(s,i){return"[Axios v"+Ra+"] Transitional option '"+s+"'"+i+(n?". "+n:"")}return(s,i,a)=>{if(e===!1)throw new Z(o(i," has been removed"+(r?" in "+r:"")),Z.ERR_DEPRECATED);return r&&!xv[i]&&(xv[i]=!0,console.warn(o(i," has been deprecated since v"+r+" and will be removed in the near future"))),e?e(s,i,a):!0}};Ea.spelling=function(e){return(r,n)=>(console.warn(`${n} is likely a misspelling of ${e}`),!0)};function jA(t,e,r){if(typeof t!="object")throw new Z("options must be an object",Z.ERR_BAD_OPTION_VALUE);let n=Object.keys(t),o=n.length;for(;o-- >0;){let s=n[o],i=e[s];if(i){let a=t[s],c=a===void 0||i(a,s,t);if(c!==!0)throw new Z("option "+s+" must be "+c,Z.ERR_BAD_OPTION_VALUE);continue}if(r!==!0)throw new Z("Unknown option "+s,Z.ERR_BAD_OPTION)}}var bs={assertOptions:jA,validators:Ea};var Ut=bs.validators,oo=class{constructor(e){this.defaults=e||{},this.interceptors={request:new xf,response:new xf}}async request(e,r){try{return await this._request(e,r)}catch(n){if(n instanceof Error){let o={};Error.captureStackTrace?Error.captureStackTrace(o):o=new Error;let s=o.stack?o.stack.replace(/^.+\n/,""):"";try{n.stack?s&&!String(n.stack).endsWith(s.replace(/^.+\n.+\n/,""))&&(n.stack+=`
|
|
44
|
-
`+s):n.stack=s}catch{}}throw n}}_request(e,r){typeof e=="string"?(r=r||{},r.url=e):r=e||{},r=zt(this.defaults,r);let{transitional:n,paramsSerializer:o,headers:s}=r;n!==void 0&&bs.assertOptions(n,{silentJSONParsing:Ut.transitional(Ut.boolean),forcedJSONParsing:Ut.transitional(Ut.boolean),clarifyTimeoutError:Ut.transitional(Ut.boolean)},!1),o!=null&&(y.isFunction(o)?r.paramsSerializer={serialize:o}:bs.assertOptions(o,{encode:Ut.function,serialize:Ut.function},!0)),r.allowAbsoluteUrls!==void 0||(this.defaults.allowAbsoluteUrls!==void 0?r.allowAbsoluteUrls=this.defaults.allowAbsoluteUrls:r.allowAbsoluteUrls=!0),bs.assertOptions(r,{baseUrl:Ut.spelling("baseURL"),withXsrfToken:Ut.spelling("withXSRFToken")},!0),r.method=(r.method||this.defaults.method||"get").toLowerCase();let i=s&&y.merge(s.common,s[r.method]);s&&y.forEach(["delete","get","head","post","put","patch","common"],f=>{delete s[f]}),r.headers=Te.concat(i,s);let a=[],c=!0;this.interceptors.request.forEach(function(m){typeof m.runWhen=="function"&&m.runWhen(r)===!1||(c=c&&m.synchronous,a.unshift(m.fulfilled,m.rejected))});let u=[];this.interceptors.response.forEach(function(m){u.push(m.fulfilled,m.rejected)});let l,d=0,h;if(!c){let f=[Ta.bind(this),void 0];for(f.unshift(...a),f.push(...u),h=f.length,l=Promise.resolve(r);d<h;)l=l.then(f[d++],f[d++]);return l}h=a.length;let p=r;for(;d<h;){let f=a[d++],m=a[d++];try{p=f(p)}catch(g){m.call(this,g);break}}try{l=Ta.call(this,p)}catch(f){return Promise.reject(f)}for(d=0,h=u.length;d<h;)l=l.then(u[d++],u[d++]);return l}getUri(e){e=zt(this.defaults,e);let r=vs(e.baseURL,e.url,e.allowAbsoluteUrls);return ms(r,e.params,e.paramsSerializer)}};y.forEach(["delete","get","head","options"],function(e){oo.prototype[e]=function(r,n){return this.request(zt(n||{},{method:e,url:r,data:(n||{}).data}))}});y.forEach(["post","put","patch"],function(e){function r(n){return function(s,i,a){return this.request(zt(a||{},{method:e,headers:n?{"Content-Type":"multipart/form-data"}:{},url:s,data:i}))}}oo.prototype[e]=r(),oo.prototype[e+"Form"]=r(!0)});var ws=oo;var qf=class t{constructor(e){if(typeof e!="function")throw new TypeError("executor must be a function.");let r;this.promise=new Promise(function(s){r=s});let n=this;this.promise.then(o=>{if(!n._listeners)return;let s=n._listeners.length;for(;s-- >0;)n._listeners[s](o);n._listeners=null}),this.promise.then=o=>{let s,i=new Promise(a=>{n.subscribe(a),s=a}).then(o);return i.cancel=function(){n.unsubscribe(s)},i},e(function(s,i,a){n.reason||(n.reason=new Lt(s,i,a),r(n.reason))})}throwIfRequested(){if(this.reason)throw this.reason}subscribe(e){if(this.reason){e(this.reason);return}this._listeners?this._listeners.push(e):this._listeners=[e]}unsubscribe(e){if(!this._listeners)return;let r=this._listeners.indexOf(e);r!==-1&&this._listeners.splice(r,1)}toAbortSignal(){let e=new AbortController,r=n=>{e.abort(n)};return this.subscribe(r),e.signal.unsubscribe=()=>this.unsubscribe(r),e.signal}static source(){let e;return{token:new t(function(o){e=o}),cancel:e}}},kv=qf;function Df(t){return function(r){return t.apply(null,r)}}function Zf(t){return y.isObject(t)&&t.isAxiosError===!0}var Lf={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511,WebServerIsDown:521,ConnectionTimedOut:522,OriginIsUnreachable:523,TimeoutOccurred:524,SslHandshakeFailed:525,InvalidSslCertificate:526};Object.entries(Lf).forEach(([t,e])=>{Lf[e]=t});var $v=Lf;function Sv(t){let e=new ws(t),r=ls(ws.prototype.request,e);return y.extend(r,ws.prototype,e,{allOwnKeys:!0}),y.extend(r,e,null,{allOwnKeys:!0}),r.create=function(o){return Sv(zt(t,o))},r}var Se=Sv(to);Se.Axios=ws;Se.CanceledError=Lt;Se.CancelToken=kv;Se.isCancel=ys;Se.VERSION=Ra;Se.toFormData=Rr;Se.AxiosError=Z;Se.Cancel=Se.CanceledError;Se.all=function(e){return Promise.all(e)};Se.spread=Df;Se.isAxiosError=Zf;Se.mergeConfig=zt;Se.AxiosHeaders=Te;Se.formToJSON=t=>xa(y.isHTMLForm(t)?new FormData(t):t);Se.getAdapter=za.getAdapter;Se.HttpStatusCode=$v;Se.default=Se;var Ft=Se;var{Axios:JL,AxiosError:GL,CanceledError:WL,isCancel:QL,CancelToken:XL,VERSION:YL,all:e2,Cancel:t2,isAxiosError:r2,spread:n2,toFormData:o2,AxiosHeaders:s2,HttpStatusCode:i2,formToJSON:a2,getAdapter:c2,mergeConfig:u2}=Ft;var Er={portals:[{id:"dati-gov-it",name:"dati.gov.it",api_url:"https://www.dati.gov.it/opendata",api_url_aliases:["https://dati.gov.it/opendata","http://www.dati.gov.it/opendata","http://dati.gov.it/opendata"],search:{force_text_field:!0},hvd:{category_field:"hvd_category"},sparql:{endpoint_url:"https://lod.dati.gov.it/sparql",method:"GET"},dataset_view_url:"https://www.dati.gov.it/view-dataset/dataset?id={id}",organization_view_url:"https://www.dati.gov.it/view-dataset?organization={name}"},{id:"anac-opendata",name:"dati.anticorruzione.it/opendata",api_url:"https://dati.anticorruzione.it/opendata",api_url_aliases:["http://dati.anticorruzione.it/opendata","https://dati.anticorruzione.it","http://dati.anticorruzione.it"]},{id:"data-gov-uk",name:"data.gov.uk",api_url:"https://data.gov.uk",api_url_aliases:["https://www.data.gov.uk","http://data.gov.uk","http://www.data.gov.uk"],api_path:"/api/action",dataset_view_url:"https://www.data.gov.uk/dataset/{id}/{name}",organization_view_url:"https://www.data.gov.uk/organization/{name}"},{id:"catalog-data-gov",name:"catalog.data.gov",api_url:"https://catalog.data.gov",api_url_aliases:["http://catalog.data.gov"]},{id:"open-canada",name:"open.canada.ca",api_url:"https://open.canada.ca/data",api_url_aliases:["http://open.canada.ca/data","https://open.canada.ca","http://open.canada.ca"]},{id:"data-gov-au",name:"data.gov.au",api_url:"https://data.gov.au",api_url_aliases:["http://data.gov.au","https://www.data.gov.au","http://www.data.gov.au"],dataset_view_url:"https://data.gov.au/data/dataset/{name}",organization_view_url:"https://data.gov.au/data/organization/{name}"},{id:"opendata-swiss",name:"opendata.swiss",api_url:"https://ckan.opendata.swiss",api_url_aliases:["https://opendata.swiss","http://opendata.swiss","https://www.opendata.swiss","http://www.opendata.swiss"]},{id:"data-stadt-zuerich-ch",name:"data.stadt-zuerich.ch",api_url:"https://data.stadt-zuerich.ch",api_url_aliases:["http://data.stadt-zuerich.ch","https://www.data.stadt-zuerich.ch","https://ckan-prod.zurich.datopian.com"],organization_view_url:"https://ckan-prod.zurich.datopian.com/organization/{name}"},{id:"govdata-de",name:"govdata.de",api_url:"https://ckan.govdata.de",api_url_aliases:["https://www.govdata.de","https://govdata.de","https://www.govdata.de/daten","https://data.gov.de","https://www.data.gov.de"],dataset_view_url:"https://ckan.govdata.de/dataset/{name}",organization_view_url:"https://ckan.govdata.de/organization/{name}"}],defaults:{dataset_view_url:"{server_url}/dataset/{name}",organization_view_url:"{server_url}/organization/{name}",search:{force_text_field:!1}}};function pn(t){return t.replace(/\/$/,"")}function DA(t){try{return new URL(t).hostname}catch{return null}}function mn(t){let e=pn(t);return Er.portals.find(n=>{let o=pn(n.api_url),s=(n.api_url_aliases||[]).map(pn);return o===e||s.includes(e)})||null}function zv(t){let e=mn(t),r=Er.defaults?.search||{};return{force_text_field:e?.search?.force_text_field??r.force_text_field??!1}}function Uf(t){return pn(t)}function Pa(t){let e=Er.portals.find(r=>[r.api_url,...r.api_url_aliases||[]].some(o=>DA(o)===t));return e?pn(e.api_url):null}function so(t){return mn(t)?.hvd??null}function Tv(t){let e=pn(t);return Er.portals.find(n=>n.sparql&&pn(n.sparql.endpoint_url)===e)?.sparql??null}function Rv(t){return mn(t)?.sparql??null}function hn(t){return mn(t)?.api_path||"/api/3/action"}var ZA=(()=>{let t=null;return async()=>(t||(t=(async()=>{try{return await import("node:zlib")}catch{return null}})()),t)})();function Ev(t,e){if(!t)return;let r=e.toLowerCase();for(let[n,o]of Object.entries(t))if(n.toLowerCase()===r)return Array.isArray(o)?o.join(","):String(o)}function LA(t){if(t&&!(typeof Buffer>"u")){if(Buffer.isBuffer(t))return t;if(t instanceof ArrayBuffer)return Buffer.from(t);if(ArrayBuffer.isView(t))return Buffer.from(t.buffer,t.byteOffset,t.byteLength)}}function UA(t){if(t){if(t instanceof ArrayBuffer)return t;if(ArrayBuffer.isView(t))return t.buffer.slice(t.byteOffset,t.byteOffset+t.byteLength)}}async function FA(t,e){if(e&&typeof DecompressionStream<"u")try{let r=new DecompressionStream(e.includes("br")?"br":e.includes("deflate")?"deflate":"gzip"),n=await new Response(new Blob([t]).stream().pipeThrough(r)).arrayBuffer();return new TextDecoder("utf-8").decode(n).trim()}catch{}return new TextDecoder("utf-8").decode(t).trim()}async function Pv(t,e){if(t==null)return t;let r=UA(t);if(r&&typeof Buffer>"u"){let c=Ev(e,"content-encoding"),u=await FA(r,c);if(!u)return u;try{return JSON.parse(u)}catch{return u}}if(typeof t=="string")try{return JSON.parse(t)}catch{return t}let n=LA(t);if(!n)return t;let o=Ev(e,"content-encoding"),s=n,i=await ZA();try{i&&(o?.includes("gzip")?s=i.gunzipSync(n):o?.includes("br")?s=i.brotliDecompressSync(n):o?.includes("deflate")?s=i.inflateSync(n):n.length>=2&&n[0]===31&&n[1]===139&&(s=i.gunzipSync(n)))}catch{s=n}let a=s.toString("utf-8").trim();if(!a)return a;try{return JSON.parse(a)}catch{return a}}async function B(t,e,r={}){let n=typeof process<"u"&&!!process.versions?.node,o=t;try{let c=new URL(t).hostname,u=Pa(c);u&&(o=u)}catch{}let s=o.replace(/\/$/,""),i=hn(o),a=`${s}${i}/${e}`;try{let c;if(n){let u=await Ft.get(a,{params:r,timeout:3e4,responseType:"arraybuffer",headers:{Accept:"application/json, text/plain, */*","Accept-Language":"en-US,en;q=0.9,it;q=0.8","Accept-Encoding":"gzip, deflate, br",Connection:"keep-alive",Referer:`${s}/`,"Sec-Fetch-Site":"same-origin","Sec-Fetch-Mode":"navigate","Sec-Fetch-Dest":"document","Upgrade-Insecure-Requests":"1","Sec-CH-UA":'"Chromium";v="120", "Not?A_Brand";v="24", "Google Chrome";v="120"',"Sec-CH-UA-Mobile":"?0","Sec-CH-UA-Platform":'"Linux"',"User-Agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"}});c=await Pv(u.data,u.headers)}else{let u=new URLSearchParams;for(let[g,_]of Object.entries(r))_!=null&&u.set(g,String(_));let l=u.toString()?`${a}?${u.toString()}`:a,d=new AbortController,h=setTimeout(()=>d.abort(),3e4),p;try{p=await fetch(l,{method:"GET",signal:d.signal,headers:{Accept:"application/json, text/plain, */*","Accept-Encoding":"identity","User-Agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"}})}finally{clearTimeout(h)}if(!p.ok)throw new Error(`CKAN API error (${p.status}): ${p.statusText}`);let f=await p.arrayBuffer(),m={};p.headers.forEach((g,_)=>{m[_]=g}),c=await Pv(f,m)}if(c&&c.success===!0)return c.result;throw new Error(`CKAN API returned success=false: ${JSON.stringify(c)}`)}catch(c){if(Ft.isAxiosError(c)){let u=c;if(u.response){let l=u.response.status,d=u.response.data,h=d?.error?.message||d?.error||"Unknown error";throw new Error(`CKAN API error (${l}): ${h}`)}else throw u.code==="ECONNABORTED"?new Error(`Request timeout connecting to ${t}`):u.code==="ENOTFOUND"?new Error(`Server not found: ${t}`):new Error(`Network error: ${u.message}`)}throw c}}function G(t,e=Tr){return t.length<=e?t:t.substring(0,e)+`
|
|
44
|
+
`+s):n.stack=s}catch{}}throw n}}_request(e,r){typeof e=="string"?(r=r||{},r.url=e):r=e||{},r=zt(this.defaults,r);let{transitional:n,paramsSerializer:o,headers:s}=r;n!==void 0&&bs.assertOptions(n,{silentJSONParsing:Ut.transitional(Ut.boolean),forcedJSONParsing:Ut.transitional(Ut.boolean),clarifyTimeoutError:Ut.transitional(Ut.boolean)},!1),o!=null&&(y.isFunction(o)?r.paramsSerializer={serialize:o}:bs.assertOptions(o,{encode:Ut.function,serialize:Ut.function},!0)),r.allowAbsoluteUrls!==void 0||(this.defaults.allowAbsoluteUrls!==void 0?r.allowAbsoluteUrls=this.defaults.allowAbsoluteUrls:r.allowAbsoluteUrls=!0),bs.assertOptions(r,{baseUrl:Ut.spelling("baseURL"),withXsrfToken:Ut.spelling("withXSRFToken")},!0),r.method=(r.method||this.defaults.method||"get").toLowerCase();let i=s&&y.merge(s.common,s[r.method]);s&&y.forEach(["delete","get","head","post","put","patch","common"],f=>{delete s[f]}),r.headers=Te.concat(i,s);let a=[],c=!0;this.interceptors.request.forEach(function(m){typeof m.runWhen=="function"&&m.runWhen(r)===!1||(c=c&&m.synchronous,a.unshift(m.fulfilled,m.rejected))});let u=[];this.interceptors.response.forEach(function(m){u.push(m.fulfilled,m.rejected)});let l,d=0,h;if(!c){let f=[Ta.bind(this),void 0];for(f.unshift(...a),f.push(...u),h=f.length,l=Promise.resolve(r);d<h;)l=l.then(f[d++],f[d++]);return l}h=a.length;let p=r;for(;d<h;){let f=a[d++],m=a[d++];try{p=f(p)}catch(g){m.call(this,g);break}}try{l=Ta.call(this,p)}catch(f){return Promise.reject(f)}for(d=0,h=u.length;d<h;)l=l.then(u[d++],u[d++]);return l}getUri(e){e=zt(this.defaults,e);let r=vs(e.baseURL,e.url,e.allowAbsoluteUrls);return ms(r,e.params,e.paramsSerializer)}};y.forEach(["delete","get","head","options"],function(e){oo.prototype[e]=function(r,n){return this.request(zt(n||{},{method:e,url:r,data:(n||{}).data}))}});y.forEach(["post","put","patch"],function(e){function r(n){return function(s,i,a){return this.request(zt(a||{},{method:e,headers:n?{"Content-Type":"multipart/form-data"}:{},url:s,data:i}))}}oo.prototype[e]=r(),oo.prototype[e+"Form"]=r(!0)});var ws=oo;var qf=class t{constructor(e){if(typeof e!="function")throw new TypeError("executor must be a function.");let r;this.promise=new Promise(function(s){r=s});let n=this;this.promise.then(o=>{if(!n._listeners)return;let s=n._listeners.length;for(;s-- >0;)n._listeners[s](o);n._listeners=null}),this.promise.then=o=>{let s,i=new Promise(a=>{n.subscribe(a),s=a}).then(o);return i.cancel=function(){n.unsubscribe(s)},i},e(function(s,i,a){n.reason||(n.reason=new Lt(s,i,a),r(n.reason))})}throwIfRequested(){if(this.reason)throw this.reason}subscribe(e){if(this.reason){e(this.reason);return}this._listeners?this._listeners.push(e):this._listeners=[e]}unsubscribe(e){if(!this._listeners)return;let r=this._listeners.indexOf(e);r!==-1&&this._listeners.splice(r,1)}toAbortSignal(){let e=new AbortController,r=n=>{e.abort(n)};return this.subscribe(r),e.signal.unsubscribe=()=>this.unsubscribe(r),e.signal}static source(){let e;return{token:new t(function(o){e=o}),cancel:e}}},kv=qf;function Df(t){return function(r){return t.apply(null,r)}}function Zf(t){return y.isObject(t)&&t.isAxiosError===!0}var Lf={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511,WebServerIsDown:521,ConnectionTimedOut:522,OriginIsUnreachable:523,TimeoutOccurred:524,SslHandshakeFailed:525,InvalidSslCertificate:526};Object.entries(Lf).forEach(([t,e])=>{Lf[e]=t});var $v=Lf;function Sv(t){let e=new ws(t),r=ls(ws.prototype.request,e);return y.extend(r,ws.prototype,e,{allOwnKeys:!0}),y.extend(r,e,null,{allOwnKeys:!0}),r.create=function(o){return Sv(zt(t,o))},r}var Se=Sv(to);Se.Axios=ws;Se.CanceledError=Lt;Se.CancelToken=kv;Se.isCancel=ys;Se.VERSION=Ra;Se.toFormData=Rr;Se.AxiosError=Z;Se.Cancel=Se.CanceledError;Se.all=function(e){return Promise.all(e)};Se.spread=Df;Se.isAxiosError=Zf;Se.mergeConfig=zt;Se.AxiosHeaders=Te;Se.formToJSON=t=>xa(y.isHTMLForm(t)?new FormData(t):t);Se.getAdapter=za.getAdapter;Se.HttpStatusCode=$v;Se.default=Se;var Ft=Se;var{Axios:JL,AxiosError:GL,CanceledError:WL,isCancel:QL,CancelToken:XL,VERSION:YL,all:e2,Cancel:t2,isAxiosError:r2,spread:n2,toFormData:o2,AxiosHeaders:s2,HttpStatusCode:i2,formToJSON:a2,getAdapter:c2,mergeConfig:u2}=Ft;var Er={portals:[{id:"dati-gov-it",name:"dati.gov.it",api_url:"https://www.dati.gov.it/opendata",api_url_aliases:["https://dati.gov.it/opendata","http://www.dati.gov.it/opendata","http://dati.gov.it/opendata"],search:{force_text_field:!0},hvd:{category_field:"hvd_category"},sparql:{endpoint_url:"https://lod.dati.gov.it/sparql",method:"GET"},dataset_view_url:"https://www.dati.gov.it/view-dataset/dataset?id={id}",organization_view_url:"https://www.dati.gov.it/view-dataset?organization={name}"},{id:"anac-opendata",name:"dati.anticorruzione.it/opendata",api_url:"https://dati.anticorruzione.it/opendata",api_url_aliases:["http://dati.anticorruzione.it/opendata","https://dati.anticorruzione.it","http://dati.anticorruzione.it"]},{id:"data-gov-uk",name:"data.gov.uk",api_url:"https://data.gov.uk",api_url_aliases:["https://www.data.gov.uk","http://data.gov.uk","http://www.data.gov.uk"],api_path:"/api/action",dataset_view_url:"https://www.data.gov.uk/dataset/{id}/{name}",organization_view_url:"https://www.data.gov.uk/organization/{name}"},{id:"catalog-data-gov",name:"catalog.data.gov",api_url:"https://catalog.data.gov",api_url_aliases:["http://catalog.data.gov"]},{id:"open-canada",name:"open.canada.ca",api_url:"https://open.canada.ca/data",api_url_aliases:["http://open.canada.ca/data","https://open.canada.ca","http://open.canada.ca"]},{id:"data-gov-au",name:"data.gov.au",api_url:"https://data.gov.au",api_url_aliases:["http://data.gov.au","https://www.data.gov.au","http://www.data.gov.au"],dataset_view_url:"https://data.gov.au/data/dataset/{name}",organization_view_url:"https://data.gov.au/data/organization/{name}"},{id:"opendata-swiss",name:"opendata.swiss",api_url:"https://ckan.opendata.swiss",api_url_aliases:["https://opendata.swiss","http://opendata.swiss","https://www.opendata.swiss","http://www.opendata.swiss"]},{id:"data-stadt-zuerich-ch",name:"data.stadt-zuerich.ch",api_url:"https://data.stadt-zuerich.ch",api_url_aliases:["http://data.stadt-zuerich.ch","https://www.data.stadt-zuerich.ch","https://ckan-prod.zurich.datopian.com"],organization_view_url:"https://ckan-prod.zurich.datopian.com/organization/{name}"},{id:"govdata-de",name:"govdata.de",api_url:"https://ckan.govdata.de",api_url_aliases:["https://www.govdata.de","https://govdata.de","https://www.govdata.de/daten","https://data.gov.de","https://www.data.gov.de"],dataset_view_url:"https://ckan.govdata.de/dataset/{name}",organization_view_url:"https://ckan.govdata.de/organization/{name}"}],defaults:{dataset_view_url:"{server_url}/dataset/{name}",organization_view_url:"{server_url}/organization/{name}",search:{force_text_field:!1}}};function pn(t){return t.replace(/\/$/,"")}function DA(t){try{return new URL(t).hostname}catch{return null}}function mn(t){let e=pn(t);return Er.portals.find(n=>{let o=pn(n.api_url),s=(n.api_url_aliases||[]).map(pn);return o===e||s.includes(e)})||null}function zv(t){let e=mn(t),r=Er.defaults?.search||{};return{force_text_field:e?.search?.force_text_field??r.force_text_field??!1}}function Uf(t){return pn(t)}function Pa(t){let e=Er.portals.find(r=>[r.api_url,...r.api_url_aliases||[]].some(o=>DA(o)===t));return e?pn(e.api_url):null}function so(t){return mn(t)?.hvd??null}function Tv(t){let e=pn(t);return Er.portals.find(n=>n.sparql&&pn(n.sparql.endpoint_url)===e)?.sparql??null}function Rv(t){return mn(t)?.sparql??null}function hn(t){return mn(t)?.api_path||"/api/3/action"}var ZA=(()=>{let t=null;return async()=>(t||(t=(async()=>{try{return await import("node:zlib")}catch{return null}})()),t)})();function Ev(t,e){if(!t)return;let r=e.toLowerCase();for(let[n,o]of Object.entries(t))if(n.toLowerCase()===r)return Array.isArray(o)?o.join(","):String(o)}function LA(t){if(t&&!(typeof Buffer>"u")){if(Buffer.isBuffer(t))return t;if(t instanceof ArrayBuffer)return Buffer.from(t);if(ArrayBuffer.isView(t))return Buffer.from(t.buffer,t.byteOffset,t.byteLength)}}function UA(t){if(t){if(t instanceof ArrayBuffer)return t;if(ArrayBuffer.isView(t))return t.buffer.slice(t.byteOffset,t.byteOffset+t.byteLength)}}async function FA(t,e){if(e&&typeof DecompressionStream<"u")try{let r=new DecompressionStream(e.includes("br")?"br":e.includes("deflate")?"deflate":"gzip"),n=await new Response(new Blob([t]).stream().pipeThrough(r)).arrayBuffer();return new TextDecoder("utf-8").decode(n).trim()}catch{}return new TextDecoder("utf-8").decode(t).trim()}async function Pv(t,e){if(t==null)return t;let r=UA(t);if(r&&typeof Buffer>"u"){let c=Ev(e,"content-encoding"),u=await FA(r,c);if(!u)return u;try{return JSON.parse(u)}catch{return u}}if(typeof t=="string")try{return JSON.parse(t)}catch{return t}let n=LA(t);if(!n)return t;let o=Ev(e,"content-encoding"),s=n,i=await ZA();try{i&&(o?.includes("gzip")?s=i.gunzipSync(n):o?.includes("br")?s=i.brotliDecompressSync(n):o?.includes("deflate")?s=i.inflateSync(n):n.length>=2&&n[0]===31&&n[1]===139&&(s=i.gunzipSync(n)))}catch{s=n}let a=s.toString("utf-8").trim();if(!a)return a;try{return JSON.parse(a)}catch{return a}}async function B(t,e,r={}){let n=typeof process<"u"&&!!process.versions?.node,o=t;try{let c=new URL(t).hostname,u=Pa(c);u&&(o=u)}catch{}let s=o.replace(/\/$/,""),i=hn(o),a=`${s}${i}/${e}`;try{let c;if(n){let u=await Ft.get(a,{params:r,timeout:3e4,responseType:"arraybuffer",headers:{Accept:"application/json, text/plain, */*","Accept-Language":"en-US,en;q=0.9,it;q=0.8","Accept-Encoding":"gzip, deflate, br",Connection:"keep-alive","Sec-CH-UA":'"Chromium";v="120", "Not?A_Brand";v="24", "Google Chrome";v="120"',"Sec-CH-UA-Mobile":"?0","Sec-CH-UA-Platform":'"Linux"',"User-Agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"}});c=await Pv(u.data,u.headers)}else{let u=new URLSearchParams;for(let[g,_]of Object.entries(r))_!=null&&u.set(g,String(_));let l=u.toString()?`${a}?${u.toString()}`:a,d=new AbortController,h=setTimeout(()=>d.abort(),3e4),p;try{p=await fetch(l,{method:"GET",signal:d.signal,headers:{Accept:"application/json, text/plain, */*","Accept-Encoding":"identity","User-Agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"}})}finally{clearTimeout(h)}if(!p.ok)throw new Error(`CKAN API error (${p.status}): ${p.statusText}`);let f=await p.arrayBuffer(),m={};p.headers.forEach((g,_)=>{m[_]=g}),c=await Pv(f,m)}if(c&&c.success===!0)return c.result;throw new Error(`CKAN API returned success=false: ${JSON.stringify(c)}`)}catch(c){if(Ft.isAxiosError(c)){let u=c;if(u.response){let l=u.response.status,d=u.response.data,h=d?.error?.message||d?.error||"Unknown error";throw new Error(`CKAN API error (${l}): ${h}`)}else throw u.code==="ECONNABORTED"?new Error(`Request timeout connecting to ${t}`):u.code==="ENOTFOUND"?new Error(`Server not found: ${t}`):new Error(`Network error: ${u.message}`)}throw c}}function G(t,e=Tr){return t.length<=e?t:t.substring(0,e)+`
|
|
45
45
|
|
|
46
46
|
... [Response truncated at ${e} characters]`}function nt(t,e=Tr){let r=JSON.stringify(t,null,2);if(r.length<=e||(r=JSON.stringify(t),r.length<=e))return r;let n=structuredClone(t),o=["results","records","resources","packages","organizations","groups","tags"];for(let s of o)if(Array.isArray(n[s])&&n[s].length>0){let i=n[s].length;for(;n[s].length>1;)if(n[s].pop(),n._truncated=!0,n._original_count=i,r=JSON.stringify(n),r.length<=e)return r}return G(JSON.stringify(n),e)}function Ye(t){try{if(!t)return"Invalid Date";let e=new Date(t);return Number.isNaN(e.getTime())?"Invalid Date":e.toISOString().slice(0,10)}catch{return"Invalid Date"}}function Av(t){if(!t||t===0)return"0 B";let e=1024,r=["B","KB","MB","GB"],n=Math.floor(Math.log(t)/Math.log(e));return parseFloat((t/Math.pow(e,n)).toFixed(2))+" "+r[n]}function HA(){try{return typeof WorkerGlobalScope<"u"}catch{return!1}}function se(t){return HA()?t+`
|
|
47
47
|
|
|
@@ -1084,7 +1084,7 @@ ckan_package_search({
|
|
|
1084
1084
|
})
|
|
1085
1085
|
\`\`\`
|
|
1086
1086
|
|
|
1087
|
-
If the portal supports HVD classification, look for datasets with fields like \`hvd_category\` or \`applicable_legislation\`.`,_b=t=>{t.registerPrompt(YO,{title:"Search High-Value Datasets (HVD)",description:"Guided prompt to find High-Value Datasets (HVD) on a CKAN portal. Automatically uses the correct filter field from portal configuration.",argsSchema:{server_url:v.string().url().describe("Base URL of the CKAN server"),rows:v.coerce.number().int().positive().default(10).describe("Max results to return")}},async({server_url:e,rows:r})=>{let n=so(e);return ht(eN(e,r,n?.category_field??null))})};var vb=t=>{pb(t),mb(t),hb(t),gb(t),yb(t),_b(t)};function bb(){return new ma({name:"ckan-mcp-server",version:"0.4.
|
|
1087
|
+
If the portal supports HVD classification, look for datasets with fields like \`hvd_category\` or \`applicable_legislation\`.`,_b=t=>{t.registerPrompt(YO,{title:"Search High-Value Datasets (HVD)",description:"Guided prompt to find High-Value Datasets (HVD) on a CKAN portal. Automatically uses the correct filter field from portal configuration.",argsSchema:{server_url:v.string().url().describe("Base URL of the CKAN server"),rows:v.coerce.number().int().positive().default(10).describe("Max results to return")}},async({server_url:e,rows:r})=>{let n=so(e);return ht(eN(e,r,n?.category_field??null))})};var vb=t=>{pb(t),mb(t),hb(t),gb(t),yb(t),_b(t)};function bb(){return new ma({name:"ckan-mcp-server",version:"0.4.77"})}function wb(t){Lv(t),Uv(t),Hv(t),Vv(t),Bv(t),Jv(t),eb(t),tb(t),rb(t),nb(t),ob(t),fb(t),vb(t)}var ja=class{constructor(e={}){this._started=!1,this._streamMapping=new Map,this._requestToStreamMapping=new Map,this._requestResponseMap=new Map,this._initialized=!1,this._enableJsonResponse=!1,this._standaloneSseStreamId="_GET_stream",this.sessionIdGenerator=e.sessionIdGenerator,this._enableJsonResponse=e.enableJsonResponse??!1,this._eventStore=e.eventStore,this._onsessioninitialized=e.onsessioninitialized,this._onsessionclosed=e.onsessionclosed,this._allowedHosts=e.allowedHosts,this._allowedOrigins=e.allowedOrigins,this._enableDnsRebindingProtection=e.enableDnsRebindingProtection??!1,this._retryInterval=e.retryInterval}async start(){if(this._started)throw new Error("Transport already started");this._started=!0}createJsonErrorResponse(e,r,n,o){let s={code:r,message:n};return o?.data!==void 0&&(s.data=o.data),new Response(JSON.stringify({jsonrpc:"2.0",error:s,id:null}),{status:e,headers:{"Content-Type":"application/json",...o?.headers}})}validateRequestHeaders(e){if(this._enableDnsRebindingProtection){if(this._allowedHosts&&this._allowedHosts.length>0){let r=e.headers.get("host");if(!r||!this._allowedHosts.includes(r)){let n=`Invalid Host header: ${r}`;return this.onerror?.(new Error(n)),this.createJsonErrorResponse(403,-32e3,n)}}if(this._allowedOrigins&&this._allowedOrigins.length>0){let r=e.headers.get("origin");if(r&&!this._allowedOrigins.includes(r)){let n=`Invalid Origin header: ${r}`;return this.onerror?.(new Error(n)),this.createJsonErrorResponse(403,-32e3,n)}}}}async handleRequest(e,r){let n=this.validateRequestHeaders(e);if(n)return n;switch(e.method){case"POST":return this.handlePostRequest(e,r);case"GET":return this.handleGetRequest(e);case"DELETE":return this.handleDeleteRequest(e);default:return this.handleUnsupportedRequest()}}async writePrimingEvent(e,r,n,o){if(!this._eventStore||o<"2025-11-25")return;let s=await this._eventStore.storeEvent(n,{}),i=`id: ${s}
|
|
1088
1088
|
data:
|
|
1089
1089
|
|
|
1090
1090
|
`;this._retryInterval!==void 0&&(i=`id: ${s}
|
|
@@ -1278,4 +1278,4 @@ data:
|
|
|
1278
1278
|
</div>
|
|
1279
1279
|
</div>
|
|
1280
1280
|
</body>
|
|
1281
|
-
</html>`,{headers:{"Content-Type":"text/html; charset=utf-8","Access-Control-Allow-Origin":"*"}});if(t.method==="GET"&&e.pathname==="/health")return new Response(JSON.stringify({status:"ok",version:"0.4.
|
|
1281
|
+
</html>`,{headers:{"Content-Type":"text/html; charset=utf-8","Access-Control-Allow-Origin":"*"}});if(t.method==="GET"&&e.pathname==="/health")return new Response(JSON.stringify({status:"ok",version:"0.4.77",tools:20,resources:7,prompts:6,runtime:"cloudflare-workers"}),{headers:{"Content-Type":"application/json","Access-Control-Allow-Origin":"*"}});if(e.pathname==="/mcp")try{let r=t.clone();try{let s=await r.json();if(s?.method==="tools/call"&&s?.params?.name){let i=s.params.name,a=s.params.arguments??{},c={tool:i,server:a.server_url??""};a.q!==void 0&&(c.q=a.q),a.fq!==void 0&&(c.fq=a.fq),a.query!==void 0&&(c.query=a.query),a.id!==void 0&&(c.id=a.id),a.name!==void 0&&(c.name=a.name),a.pattern!==void 0&&(c.pattern=a.pattern),a.resource_id!==void 0&&(c.resource_id=a.resource_id),a.format_filter!==void 0&&(c.format_filter=a.format_filter),a.sort!==void 0&&(c.sort=a.sort),a.rows!==void 0&&(c.rows=a.rows),a.limit!==void 0&&(c.limit=a.limit),a.sql!==void 0&&(c.sql=String(a.sql).slice(0,200)),console.log(JSON.stringify(c))}}catch{}let n=await kb.handleRequest(t),o=new Headers(n.headers);return o.set("Access-Control-Allow-Origin","*"),o.set("X-Service-Notice","Demo instance - 100k requests/day shared quota"),o.set("X-Recommendation","https://github.com/ondata/ckan-mcp-server#installation"),new Response(n.body,{status:n.status,statusText:n.statusText,headers:o})}catch(r){return console.error("Worker error:",r),new Response(JSON.stringify({jsonrpc:"2.0",error:{code:-32603,message:"Internal error",data:r instanceof Error?r.message:String(r)},id:null}),{status:500,headers:{"Content-Type":"application/json","Access-Control-Allow-Origin":"*"}})}return new Response("Not Found",{status:404,headers:{"Access-Control-Allow-Origin":"*"}})}};export{G4 as default};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aborruso/ckan-mcp-server",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.78",
|
|
4
4
|
"description": "MCP server for interacting with CKAN open data portals",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
"test:coverage": "vitest --coverage",
|
|
22
22
|
"build:dxt": "esbuild src/index.ts --bundle --platform=node --format=cjs --outfile=dxt-staging/server/index.js",
|
|
23
23
|
"pack:dxt": "rm -rf dxt-staging && mkdir -p dxt-staging/server && npm run build:dxt && echo '{\"type\":\"commonjs\"}' > dxt-staging/server/package.json && cp manifest.json icon.png dxt-staging/ && dxt pack dxt-staging ckan-mcp-server.dxt && rm -rf dxt-staging",
|
|
24
|
+
"pack:skill": "mkdir -p tmp && cd skills && zip -r ../tmp/ckan-mcp.skill ckan-mcp/ && cd ..",
|
|
24
25
|
"prepack": "cp README.md .readme-full.md && cp .readme-npm.md README.md",
|
|
25
26
|
"postpack": "mv .readme-full.md README.md"
|
|
26
27
|
},
|