apiblaze 0.21.63 → 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 +59 -12
  2. package/package.json +1 -1
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.63";
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];
@@ -11867,9 +11880,18 @@ async function promptForMissing(r, interactive2, defaults = { prompts: [] }, pla
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
11882
  // Wrapped: inquirer calls validate(input, answers) and the answers object must not land in fetchFn.
11870
- validate: a.key === "privacyUrl" ? (v) => validatePrivacyUrl(v) : withinLimit(a)
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)
11871
11884
  }]);
11872
- 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
+ }
11873
11895
  }
11874
11896
  const missingAttest = failing.filter((x) => x.id.startsWith("ATTEST_"));
11875
11897
  if (missingAttest.length) {
@@ -11900,7 +11922,7 @@ async function askOpenMode(caller, proj2, r, opts, interactive2, say) {
11900
11922
  say(import_chalk30.default.green(" \u2713 open mode: the connector takes no sign-in (public data); no reviewer account is needed."));
11901
11923
  return true;
11902
11924
  }
11903
- async function promptListingBasics(r, interactive2, defaults, given, platforms = PLATFORMS) {
11925
+ async function promptListingBasics(r, interactive2, defaults, given, platforms = PLATFORMS, save) {
11904
11926
  const meta = r.target?.metadata ?? {};
11905
11927
  const gpt = platforms.includes("chatgpt");
11906
11928
  const lim = { serverName: gpt ? 30 : 100, tagline: gpt ? 30 : 200, description: platforms.includes("claude") ? 2e3 : 4e3 };
@@ -11920,7 +11942,16 @@ async function promptListingBasics(r, interactive2, defaults, given, platforms =
11920
11942
  const { default: inquirer3 } = await import("inquirer");
11921
11943
  for (const w of want) {
11922
11944
  const { value } = await inquirer3.prompt([{ type: "input", name: "value", message: w.message, default: w.def }]);
11923
- 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
+ }
11924
11955
  }
11925
11956
  return out;
11926
11957
  }
@@ -12155,9 +12186,17 @@ async function runConnector(target2, opts) {
12155
12186
  if (changed) r = await fetchDirectoryReport(caller, proj2, { platforms });
12156
12187
  }
12157
12188
  if (await askOpenMode(caller, proj2, r, opts, interactive2, say)) r = await fetchDirectoryReport(caller, proj2, { platforms });
12158
- 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);
12159
12198
  if (!isReady(r, platforms) || Object.keys(basics).length) {
12160
- 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) };
12161
12200
  const body = directoryBodyFromFlags(asked);
12162
12201
  if (body.directory_metadata || body.directory_attestations || body.openai_challenge_token) {
12163
12202
  await patchProject(caller, proj2, { ...body }, "Save listing details");
@@ -12309,11 +12348,19 @@ async function probeConventionalUrls(apexDomain, fetchFn = headStatus) {
12309
12348
  }
12310
12349
  return out;
12311
12350
  }
12351
+ var say_ = (line) => {
12352
+ if (process.env.APIBLAZE_SILENT !== "1") console.log(line);
12353
+ };
12312
12354
  async function validatePrivacyUrl(input, fetchFn = headStatus) {
12313
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;
12314
12361
  const u = (input ?? "").trim();
12315
- if (!u) return "A public privacy policy URL is required by both directories.";
12316
- 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://`;
12317
12364
  const status2 = await fetchFn(u);
12318
12365
  if (status2 === 200) return true;
12319
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.63",
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",