@ambasada/village 0.8.5 → 0.8.6

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/dist/index.js CHANGED
@@ -53,6 +53,7 @@ __export(src_exports, {
53
53
  OFFERING_TIMEOUT_MS: () => OFFERING_TIMEOUT_MS,
54
54
  RECEIPT_HEADER: () => RECEIPT_HEADER,
55
55
  ReceiptError: () => ReceiptError,
56
+ SDK_SCRIPT_LIMIT: () => SDK_SCRIPT_LIMIT,
56
57
  SHELL_TOKEN_TTL_S: () => SHELL_TOKEN_TTL_S,
57
58
  SLOW_ENTRY_MS: () => SLOW_ENTRY_MS,
58
59
  SYSTEM_ACCOUNT: () => SYSTEM_ACCOUNT,
@@ -63,8 +64,10 @@ __export(src_exports, {
63
64
  appNotifyResult: () => appNotifyResult,
64
65
  appWebhookHeaders: () => appWebhookHeaders,
65
66
  base64url: () => base64url,
67
+ bundlesMiniappSdk: () => bundlesMiniappSdk,
66
68
  checkHtml: () => checkHtml,
67
69
  checkIcon: () => checkIcon,
70
+ checkPending: () => checkPending,
68
71
  checkRemote: () => checkRemote,
69
72
  createReceiptSigner: () => createReceiptSigner,
70
73
  decodeLeaf: () => decodeLeaf,
@@ -1274,7 +1277,7 @@ function checkHtml(html) {
1274
1277
  const darkStyle = [...html.matchAll(/<style\b[^>]*>([\s\S]*?)<\/style>/gi)].concat([...html.matchAll(/\bstyle\s*=\s*"([^"]*)"/gi)]).some(([, css]) => [...css.matchAll(/color-scheme\s*:\s*([^;}"]+)/gi)].some(([, v]) => /\bdark\b/i.test(v) && !/\blight\b/i.test(v)));
1275
1278
  if (darkMeta || darkStyle) f.problems.push({ code: "dark_only", message: "the entry page declares a dark-only color-scheme; the Ambasada app is light (use light, or light dark)" });
1276
1279
  if (!SDK_MARKERS.some((m) => html.includes(m))) {
1277
- f.warnings.push({ code: "no_miniapp_sdk", message: "no @ambasada/miniapp, miniapp.js or ambasadaShell in the entry HTML: a bundled import is fine too, the registry crawler confirms ready() is called at runtime" });
1280
+ f.warnings.push({ code: "no_miniapp_sdk", message: "no @ambasada/miniapp, miniapp.js or ambasadaShell in the entry HTML or its scripts: the Ambasada app waits for ready() to drop the splash" });
1278
1281
  }
1279
1282
  return f;
1280
1283
  }
@@ -1296,6 +1299,23 @@ async function probeManifest(origin, fetchImpl = fetch) {
1296
1299
  return { on: false, entry: null };
1297
1300
  }
1298
1301
  }
1302
+ var SDK_SCRIPT_LIMIT = 16;
1303
+ var BUNDLED_SDK = /ambasadaShell|@ambasada\/miniapp/;
1304
+ async function bundlesMiniappSdk(fetchImpl, pageUrl, html) {
1305
+ const origin = new URL(pageUrl).origin;
1306
+ const srcs = [...html.matchAll(/<script\b[^>]*\bsrc\s*=\s*["']([^"']+)["']/gi)].map(([, src]) => URL.canParse(src, pageUrl) ? new URL(src, pageUrl) : null).filter((u) => !!u && u.origin === origin).slice(0, SDK_SCRIPT_LIMIT);
1307
+ const found = await Promise.all(
1308
+ srcs.map(async (u) => {
1309
+ try {
1310
+ const res = await get(fetchImpl, u.toString());
1311
+ return res.status === 200 && BUNDLED_SDK.test(await res.text());
1312
+ } catch {
1313
+ return false;
1314
+ }
1315
+ })
1316
+ );
1317
+ return found.includes(true);
1318
+ }
1299
1319
  async function checkPage(fetchImpl, url, report, html) {
1300
1320
  try {
1301
1321
  const started = Date.now();
@@ -1304,7 +1324,11 @@ async function checkPage(fetchImpl, url, report, html) {
1304
1324
  if (!html) await res.body?.cancel();
1305
1325
  const ms = Date.now() - started;
1306
1326
  if (res.status !== 200) report.problems.push({ code: "entry_status", message: `${url} answered ${res.status}${res.headers.get("location") ? ` \u2192 ${res.headers.get("location")}` : ""}; ${html ? "the entry" : "the app"} must answer 200 without redirects` });
1307
- else if (html) merge(report, checkHtml(text));
1327
+ else if (html) {
1328
+ const found = checkHtml(text);
1329
+ if (found.warnings.some((w) => w.code === "no_miniapp_sdk") && await bundlesMiniappSdk(fetchImpl, url, text)) found.warnings = found.warnings.filter((w) => w.code !== "no_miniapp_sdk");
1330
+ merge(report, found);
1331
+ }
1308
1332
  if (ms > SLOW_ENTRY_MS) report.warnings.push({ code: "slow_entry", message: `${url} took ${ms} ms; aim for under ${SLOW_ENTRY_MS} ms${html ? " (the splash stays until ready())" : ""}` });
1309
1333
  } catch (error) {
1310
1334
  report.problems.push({ code: "entry_fetch", message: `could not fetch ${url}: ${error.message}` });
@@ -1424,6 +1448,7 @@ var LABELS = [
1424
1448
  function findingLabel(code) {
1425
1449
  return LABELS.find(([re]) => re.test(code))?.[1] ?? code.replace(/_/g, " ");
1426
1450
  }
1451
+ var checkPending = (check) => check?.status === "pending";
1427
1452
  function summarizeCheck(report, now = /* @__PURE__ */ new Date()) {
1428
1453
  const issues = [
1429
1454
  ...report.problems.map((p) => ({ ...p, level: "problem", label: findingLabel(p.code) })),
@@ -1433,10 +1458,12 @@ function summarizeCheck(report, now = /* @__PURE__ */ new Date()) {
1433
1458
  const miniapp = report.miniapp ? { miniapp: report.miniapp.on ? "on" : "off", entry: report.miniapp.entry } : {};
1434
1459
  return { ok: report.ok, issues, needs, checked_at: now.toISOString(), ...miniapp };
1435
1460
  }
1436
- function listingLine(tier, check) {
1461
+ function listingLine(tier, check, kind = "company") {
1437
1462
  if (check?.miniapp === "off") return "Mini app: off";
1463
+ const listed = kind === "project" ? "Listed" : "Listed for the event";
1464
+ if (checkPending(check)) return `${tier === "verified" ? "Verified" : tier === "listed" ? listed : tier === "unlisted" ? "Unlisted" : "Not registered yet"} \xB7 checking\u2026`;
1438
1465
  if (tier === "verified") return "Verified";
1439
- if (tier === "listed") return "Listed for the event";
1466
+ if (tier === "listed") return listed;
1440
1467
  if (tier === "unlisted") return check?.needs.length ? `Unlisted \xB7 needs: ${check.needs.join(", ")}` : "Unlisted";
1441
1468
  return check?.needs.length ? `Not registered yet \xB7 needs: ${check.needs.join(", ")}` : "Not registered yet";
1442
1469
  }
package/dist/types.d.ts CHANGED
@@ -166,8 +166,16 @@ export interface ChatRequest {
166
166
  messages: ChatMessage[];
167
167
  temperature?: number;
168
168
  max_tokens?: number;
169
+ /** `json_schema`: JSON in the schema's shape (live, and the mock's sample of it under `ambasada dev`); `json_object`: any JSON. */
169
170
  response_format?: {
170
171
  type: "text" | "json_object";
172
+ } | {
173
+ type: "json_schema";
174
+ json_schema: {
175
+ name: string;
176
+ schema: Record<string, unknown>;
177
+ strict?: boolean;
178
+ };
171
179
  } | Record<string, unknown>;
172
180
  [key: string]: unknown;
173
181
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ambasada/village",
3
- "version": "0.8.5",
3
+ "version": "0.8.6",
4
4
  "description": "The Hack A Ton add-on for Ambasada apps: TON checkout, receipts, offerings, LLM, the agent, the market; CLI commands and the local bank.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -27,7 +27,7 @@
27
27
  "node": ">=22"
28
28
  },
29
29
  "dependencies": {
30
- "@ambasada/sdk": "^0.8.5"
30
+ "@ambasada/sdk": "^0.8.6"
31
31
  },
32
32
  "devDependencies": {
33
33
  "@types/node": "^22.20.5",
@@ -35,7 +35,7 @@
35
35
  "typescript": "~5.9.3",
36
36
  "vitest": "^4.1.12",
37
37
  "@ambasada/protocol": "0.1.0",
38
- "@ambasada/cli": "0.8.5"
38
+ "@ambasada/cli": "0.8.6"
39
39
  },
40
40
  "author": "CENTYSO (https://centyso.com)",
41
41
  "homepage": "https://ambasada.id",