apiblaze 0.21.62 → 0.21.64

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/dist/index.js +61 -12
  2. package/package.json +8 -2
package/dist/index.js CHANGED
@@ -34,7 +34,7 @@ var __toESM = (mod, isNodeMode, target2) => (target2 = mod != null ? __create(__
34
34
  var version;
35
35
  var init_package = __esm({
36
36
  "package.json"() {
37
- version = "0.21.62";
37
+ version = "0.21.64";
38
38
  }
39
39
  });
40
40
 
@@ -5351,6 +5351,9 @@ function parseYesNo(flag, v) {
5351
5351
  }
5352
5352
  function directoryBodyFromFlags(f2) {
5353
5353
  const m = {};
5354
+ for (const [flag, v] of [["--privacy-url", f2.privacyUrl], ["--docs-url", f2.docsUrl], ["--icon-url", f2.iconUrl]]) {
5355
+ if (v && !/^https:\/\//i.test(v.trim())) throw new Error(`${flag} must be an https URL (got ${v.trim()}).`);
5356
+ }
5354
5357
  if (f2.privacyUrl) m.privacy_url = f2.privacyUrl;
5355
5358
  if (f2.support) m.support_contact = f2.support;
5356
5359
  if (f2.docsUrl) {
@@ -11794,13 +11797,17 @@ function shortenTo(text, limit) {
11794
11797
  const base2 = atWord >= Math.floor(limit * 0.4) ? cut.slice(0, atWord) : cut;
11795
11798
  return base2.replace(/[\s,;:(\-–—]+$/g, "").trim();
11796
11799
  }
11797
- async function promptForMissing(r, interactive2, defaults = { prompts: [] }, platforms = PLATFORMS) {
11800
+ async function promptForMissing(r, interactive2, defaults = { prompts: [] }, platforms = PLATFORMS, given = {}, save) {
11798
11801
  const out = {};
11799
11802
  const failing = r.report.results.filter((x) => !x.pass && !x.unverified);
11803
+ const answered = (k) => {
11804
+ const v = given[k];
11805
+ return Array.isArray(v) ? v.length > 0 : typeof v === "string" ? v.trim().length > 0 : v !== void 0 && v !== null && v !== false;
11806
+ };
11800
11807
  const asks = /* @__PURE__ */ new Map();
11801
11808
  for (const x of failing) {
11802
11809
  const p = PROMPT_FOR_RULE[x.id];
11803
- if (!p) continue;
11810
+ if (!p || answered(p.key)) continue;
11804
11811
  const cur = asks.get(p.key);
11805
11812
  if (!cur) {
11806
11813
  asks.set(p.key, { ...p });
@@ -11853,7 +11860,13 @@ async function promptForMissing(r, interactive2, defaults = { prompts: [] }, pla
11853
11860
  }
11854
11861
  lines.push(line.trim());
11855
11862
  }
11856
- if (lines.length) out.prompt = lines;
11863
+ if (lines.length) {
11864
+ out.prompt = lines;
11865
+ if (save) {
11866
+ const why = await save({ prompt: lines });
11867
+ if (why) say_(import_chalk30.default.yellow(` not saved: ${why}`));
11868
+ }
11869
+ }
11857
11870
  continue;
11858
11871
  }
11859
11872
  const dk = DEFAULT_FOR_KEY[a.key];
@@ -11866,9 +11879,19 @@ async function promptForMissing(r, interactive2, defaults = { prompts: [] }, pla
11866
11879
  ...def ? { default: def } : {},
11867
11880
  // The privacy page is a hard portal requirement (https + 200): check it here, before the
11868
11881
  // report has to come back red for a typo.
11869
- validate: a.key === "privacyUrl" ? validatePrivacyUrl : withinLimit(a)
11882
+ // Wrapped: inquirer calls validate(input, answers) and the answers object must not land in fetchFn.
11883
+ validate: a.key === "privacyUrl" ? (v) => validatePrivacyUrl(v) : a.key === "docsUrl" ? (v) => validateHttpsUrl(v, { label: "documentation URL", required: false }) : a.key === "iconUrl" ? (v) => validateHttpsUrl(v, { label: "icon URL", required: false }) : withinLimit(a)
11870
11884
  }]);
11871
- if (value?.trim()) out[a.key] = value.trim();
11885
+ if (value?.trim()) {
11886
+ out[a.key] = value.trim();
11887
+ if (save) {
11888
+ const why = await save({ [a.key]: value.trim() });
11889
+ if (why) {
11890
+ say_(import_chalk30.default.yellow(` not saved: ${why}`));
11891
+ delete out[a.key];
11892
+ }
11893
+ }
11894
+ }
11872
11895
  }
11873
11896
  const missingAttest = failing.filter((x) => x.id.startsWith("ATTEST_"));
11874
11897
  if (missingAttest.length) {
@@ -11899,7 +11922,7 @@ async function askOpenMode(caller, proj2, r, opts, interactive2, say) {
11899
11922
  say(import_chalk30.default.green(" \u2713 open mode: the connector takes no sign-in (public data); no reviewer account is needed."));
11900
11923
  return true;
11901
11924
  }
11902
- async function promptListingBasics(r, interactive2, defaults, given, platforms = PLATFORMS) {
11925
+ async function promptListingBasics(r, interactive2, defaults, given, platforms = PLATFORMS, save) {
11903
11926
  const meta = r.target?.metadata ?? {};
11904
11927
  const gpt = platforms.includes("chatgpt");
11905
11928
  const lim = { serverName: gpt ? 30 : 100, tagline: gpt ? 30 : 200, description: platforms.includes("claude") ? 2e3 : 4e3 };
@@ -11919,7 +11942,16 @@ async function promptListingBasics(r, interactive2, defaults, given, platforms =
11919
11942
  const { default: inquirer3 } = await import("inquirer");
11920
11943
  for (const w of want) {
11921
11944
  const { value } = await inquirer3.prompt([{ type: "input", name: "value", message: w.message, default: w.def }]);
11922
- if (value?.trim()) out[w.key] = value.trim();
11945
+ if (value?.trim()) {
11946
+ out[w.key] = value.trim();
11947
+ if (save) {
11948
+ const why = await save({ [w.key]: value.trim() });
11949
+ if (why) {
11950
+ say_(import_chalk30.default.yellow(` not saved: ${why}`));
11951
+ delete out[w.key];
11952
+ }
11953
+ }
11954
+ }
11923
11955
  }
11924
11956
  return out;
11925
11957
  }
@@ -12154,9 +12186,17 @@ async function runConnector(target2, opts) {
12154
12186
  if (changed) r = await fetchDirectoryReport(caller, proj2, { platforms });
12155
12187
  }
12156
12188
  if (await askOpenMode(caller, proj2, r, opts, interactive2, say)) r = await fetchDirectoryReport(caller, proj2, { platforms });
12157
- const basics = await promptListingBasics(r, interactive2, defaults, opts, platforms);
12189
+ const saveAnswer = async (f2) => {
12190
+ try {
12191
+ await patchProject(caller, proj2, { ...directoryBodyFromFlags(f2) }, "Save an answer");
12192
+ return null;
12193
+ } catch (e) {
12194
+ return e instanceof Error ? e.message : String(e);
12195
+ }
12196
+ };
12197
+ const basics = await promptListingBasics(r, interactive2, defaults, opts, platforms, interactive2 ? saveAnswer : void 0);
12158
12198
  if (!isReady(r, platforms) || Object.keys(basics).length) {
12159
- const asked = { ...basics, ...isReady(r, platforms) ? {} : await promptForMissing(r, interactive2, defaults, platforms) };
12199
+ const asked = { ...basics, ...isReady(r, platforms) ? {} : await promptForMissing(r, interactive2, defaults, platforms, basics, interactive2 ? saveAnswer : void 0) };
12160
12200
  const body = directoryBodyFromFlags(asked);
12161
12201
  if (body.directory_metadata || body.directory_attestations || body.openai_challenge_token) {
12162
12202
  await patchProject(caller, proj2, { ...body }, "Save listing details");
@@ -12308,10 +12348,19 @@ async function probeConventionalUrls(apexDomain, fetchFn = headStatus) {
12308
12348
  }
12309
12349
  return out;
12310
12350
  }
12351
+ var say_ = (line) => {
12352
+ if (process.env.APIBLAZE_SILENT !== "1") console.log(line);
12353
+ };
12311
12354
  async function validatePrivacyUrl(input, fetchFn = headStatus) {
12355
+ if (typeof fetchFn !== "function") fetchFn = headStatus;
12356
+ if (!(input ?? "").trim()) return "A public privacy policy URL is required by both directories.";
12357
+ return validateHttpsUrl(input, { label: "privacy URL", required: true, fetchFn });
12358
+ }
12359
+ async function validateHttpsUrl(input, o) {
12360
+ const fetchFn = typeof o.fetchFn === "function" ? o.fetchFn : headStatus;
12312
12361
  const u = (input ?? "").trim();
12313
- if (!u) return "A public privacy policy URL is required by both directories.";
12314
- if (!/^https:\/\//i.test(u)) return "The privacy URL must start with https://";
12362
+ if (!u) return o.required ? `A ${o.label} is required.` : true;
12363
+ if (!/^https:\/\//i.test(u)) return `The ${o.label} must start with https://`;
12315
12364
  const status2 = await fetchFn(u);
12316
12365
  if (status2 === 200) return true;
12317
12366
  return status2 === 0 ? `${u} did not answer (timeout or DNS). Publish the page, then enter its URL.` : `${u} answered ${status2}; it must answer 200.`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "apiblaze",
3
- "version": "0.21.62",
3
+ "version": "0.21.64",
4
4
  "description": "APIblaze CLI — Chat with your APIs, Manage your API keys, users and groups with the APIblaze serverless proxy",
5
5
  "keywords": [
6
6
  "apiblaze",
@@ -65,7 +65,9 @@
65
65
  "typecheck": "tsc --noEmit",
66
66
  "prepublishOnly": "npm run build && npm run typecheck",
67
67
  "release": "bash release.sh",
68
- "test": "node test/tail-inspector.test.js && node test/config-missing.test.js"
68
+ "test": "node test/tail-inspector.test.js && node test/config-missing.test.js",
69
+ "version": "npm run build && git add -A dist",
70
+ "postversion": "git push origin HEAD --follow-tags"
69
71
  },
70
72
  "dependencies": {
71
73
  "chalk": "^4.1.2",
@@ -97,5 +99,9 @@
97
99
  "allowScripts": {
98
100
  "esbuild": true,
99
101
  "fsevents": true
102
+ },
103
+ "repository": {
104
+ "type": "git",
105
+ "url": "git+https://github.com/APIblaze/npm-apiblaze.git"
100
106
  }
101
107
  }