@neopress/mcp 1.0.0 → 1.1.1

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/bin.cjs CHANGED
@@ -3838,7 +3838,7 @@ var require_fast_uri = __commonJS({
3838
3838
  if (!options.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport)) {
3839
3839
  if (parsed.host && (options.domainHost || schemeHandler && schemeHandler.domainHost) && isIP === false && nonSimpleDomain(parsed.host)) {
3840
3840
  try {
3841
- parsed.host = URL.domainToASCII(parsed.host.toLowerCase());
3841
+ parsed.host = new URL("http://" + parsed.host).hostname;
3842
3842
  } catch (e) {
3843
3843
  parsed.error = parsed.error || "Host's domain name can not be converted to ASCII: " + e;
3844
3844
  }
@@ -51345,13 +51345,33 @@ function serializeTemplate(t) {
51345
51345
  id: t.id,
51346
51346
  name: t.name,
51347
51347
  description: t.description ?? null,
51348
- industry: t.industry,
51349
51348
  referenceUrl: t.reference_url,
51350
51349
  previewImgUrls: t.preview_img_urls,
51351
51350
  previewVideoUrl: t.preview_video_url ?? null,
51352
51351
  createdAt: t.created_at
51353
51352
  };
51354
51353
  }
51354
+ function serializeHeadshot(h) {
51355
+ return {
51356
+ id: h.id,
51357
+ imageUrl: h.image_url,
51358
+ width: h.width,
51359
+ height: h.height,
51360
+ aspectRatio: h.aspect_ratio,
51361
+ mimeType: h.mime_type,
51362
+ byteSize: h.byte_size,
51363
+ ageBand: h.age_band,
51364
+ gender: h.gender,
51365
+ ethnicity: h.ethnicity,
51366
+ attire: h.attire,
51367
+ variationIndex: h.variation_index,
51368
+ gptPrompt: h.gpt_prompt,
51369
+ tags: h.tags ?? [],
51370
+ isActive: h.is_active,
51371
+ createdAt: h.created_at,
51372
+ updatedAt: h.updated_at
51373
+ };
51374
+ }
51355
51375
  function serializeSite(site) {
51356
51376
  return {
51357
51377
  id: site.id,
@@ -51405,7 +51425,8 @@ var PagesEndpoint = class {
51405
51425
  }
51406
51426
  async list(params) {
51407
51427
  const { page, limit, offset } = this.client.resolvePagination(params);
51408
- let query = this.client.db.from("pages").select("*", { count: "exact" }).eq("site_id", this.client.siteIdNumber).is("draft_deleted_at", null).order("path");
51428
+ let query = this.client.db.from("pages").select("*", { count: "exact" }).eq("site_id", this.client.siteIdNumber).is("draft_deleted_at", null);
51429
+ query = params?.order ? query.order("created_at", { ascending: params.order === "asc" }) : query.order("path");
51409
51430
  if (params?.status)
51410
51431
  query = query.eq("status", params.status);
51411
51432
  const { data, error: error48, count } = await query.range(offset, offset + limit - 1);
@@ -52691,8 +52712,10 @@ var CollectionsEndpoint = class {
52691
52712
  get basePath() {
52692
52713
  return `${this.client.siteBasePath}/collections`;
52693
52714
  }
52694
- async list() {
52695
- const { data, error: error48 } = await this.client.db.from("collections").select("*").eq("site_id", this.client.siteIdNumber).is("draft_deleted_at", null).order("name");
52715
+ async list(params) {
52716
+ let query = this.client.db.from("collections").select("*").eq("site_id", this.client.siteIdNumber).is("draft_deleted_at", null);
52717
+ query = params?.order ? query.order("created_at", { ascending: params.order === "asc" }) : query.order("name");
52718
+ const { data, error: error48 } = await query;
52696
52719
  if (error48)
52697
52720
  throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
52698
52721
  return (data ?? []).map((r) => serializeCollection(r));
@@ -52765,7 +52788,7 @@ var EntriesEndpoint = class {
52765
52788
  }
52766
52789
  async list(collectionId, params) {
52767
52790
  const { page, limit, offset } = this.client.resolvePagination(params);
52768
- let query = this.client.db.from("entries").select("*", { count: "exact" }).eq("site_id", this.client.siteIdNumber).eq("collection_id", collectionId).is("deleted_at", null).order("created_at", { ascending: false });
52791
+ let query = this.client.db.from("entries").select("*", { count: "exact" }).eq("site_id", this.client.siteIdNumber).eq("collection_id", collectionId).is("deleted_at", null).order("created_at", { ascending: params?.order === "asc" });
52769
52792
  if (params?.status)
52770
52793
  query = query.eq("status", params.status);
52771
52794
  if (params?.locale)
@@ -52856,8 +52879,10 @@ var FormsEndpoint = class {
52856
52879
  get basePath() {
52857
52880
  return `${this.client.siteBasePath}/forms`;
52858
52881
  }
52859
- async list() {
52860
- const { data, error: error48 } = await this.client.db.from("forms").select("*").eq("site_id", this.client.siteIdNumber).is("draft_deleted_at", null).order("name");
52882
+ async list(params) {
52883
+ let query = this.client.db.from("forms").select("*").eq("site_id", this.client.siteIdNumber).is("draft_deleted_at", null);
52884
+ query = params?.order ? query.order("created_at", { ascending: params.order === "asc" }) : query.order("name");
52885
+ const { data, error: error48 } = await query;
52861
52886
  if (error48)
52862
52887
  throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
52863
52888
  const rows = data ?? [];
@@ -52936,7 +52961,7 @@ var AssetsEndpoint = class {
52936
52961
  }
52937
52962
  async list(params) {
52938
52963
  const { page, limit, offset } = this.client.resolvePagination(params);
52939
- const { data, error: error48, count } = await this.client.db.from("assets").select("*", { count: "exact" }).eq("site_id", this.client.siteIdNumber).order("created_at", { ascending: false }).range(offset, offset + limit - 1);
52964
+ const { data, error: error48, count } = await this.client.db.from("assets").select("*", { count: "exact" }).eq("site_id", this.client.siteIdNumber).order("created_at", { ascending: params?.order === "asc" }).range(offset, offset + limit - 1);
52940
52965
  if (error48)
52941
52966
  throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
52942
52967
  const rows = data ?? [];
@@ -53002,7 +53027,7 @@ var SiteEndpoint = class {
53002
53027
  constructor(client) {
53003
53028
  this.client = client;
53004
53029
  }
53005
- async list() {
53030
+ async list(params) {
53006
53031
  const profileId = this.client.authUserId;
53007
53032
  if (!profileId) {
53008
53033
  throw new NeopressApiError("NO_AUTH", "site.list requires an authenticated access token", 0);
@@ -53010,10 +53035,15 @@ var SiteEndpoint = class {
53010
53035
  const { data, error: error48 } = await this.client.db.from("sites_profiles").select("role, sites!inner(*)").eq("profile_id", profileId).eq("status", "active");
53011
53036
  if (error48)
53012
53037
  throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
53013
- return (data ?? []).map((m) => ({
53038
+ const sites = (data ?? []).map((m) => ({
53014
53039
  ...serializeSite(m.sites),
53015
53040
  role: m.role
53016
53041
  }));
53042
+ if (params?.order) {
53043
+ const dir = params.order === "asc" ? 1 : -1;
53044
+ sites.sort((a, b) => (a.createdAt ?? "") < (b.createdAt ?? "") ? -dir : (a.createdAt ?? "") > (b.createdAt ?? "") ? dir : 0);
53045
+ }
53046
+ return sites;
53017
53047
  }
53018
53048
  async get() {
53019
53049
  const { data, error: error48 } = await this.client.db.from("sites").select("*").eq("id", this.client.siteIdNumber).single();
@@ -53051,8 +53081,10 @@ var RedirectsEndpoint = class {
53051
53081
  constructor(client) {
53052
53082
  this.client = client;
53053
53083
  }
53054
- async list() {
53055
- const { data, error: error48 } = await this.client.db.from("redirect_rules").select("*").eq("site_id", this.client.siteIdNumber).order("priority", { ascending: true });
53084
+ async list(params) {
53085
+ let query = this.client.db.from("redirect_rules").select("*").eq("site_id", this.client.siteIdNumber);
53086
+ query = params?.order ? query.order("created_at", { ascending: params.order === "asc" }) : query.order("priority", { ascending: true });
53087
+ const { data, error: error48 } = await query;
53056
53088
  if (error48)
53057
53089
  throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
53058
53090
  return (data ?? []).map((r) => serializeRedirect(r));
@@ -53062,7 +53094,7 @@ var RedirectsEndpoint = class {
53062
53094
  site_id: this.client.siteIdNumber,
53063
53095
  source: data.source,
53064
53096
  destination: data.destination,
53065
- redirect_type: data.redirectType ?? 307,
53097
+ redirect_type: data.redirectType ?? 308,
53066
53098
  include_children: data.includeChildren ?? false,
53067
53099
  preserve_path: data.preservePath ?? false,
53068
53100
  enabled: data.enabled !== false,
@@ -53129,7 +53161,7 @@ var EntryReferencesEndpoint = class {
53129
53161
  query = query.eq("from_entry_id", params.fromEntryId);
53130
53162
  if (params?.toEntryId)
53131
53163
  query = query.eq("to_entry_id", params.toEntryId);
53132
- const { data, error: error48 } = await query.order("created_at", { ascending: false });
53164
+ const { data, error: error48 } = await query.order("created_at", { ascending: params?.order === "asc" });
53133
53165
  if (error48)
53134
53166
  throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
53135
53167
  return (data ?? []).map((r) => serializeEntryReference(r));
@@ -53251,18 +53283,165 @@ var TemplatesEndpoint = class {
53251
53283
  const res = await this.client.delete(this.basePath);
53252
53284
  return res.data;
53253
53285
  }
53286
+ /**
53287
+ * List templates across the sites the caller can access.
53288
+ *
53289
+ * Direct-DB: `templates` is public-read and `sites` RLS scopes the visible set
53290
+ * (own active memberships, or all sites for the super admin), so no server
53291
+ * route is needed — the two RLS-scoped queries reproduce the old handler.
53292
+ */
53254
53293
  async list(params) {
53255
- const qs = new URLSearchParams();
53256
- if (params?.namePrefix)
53257
- qs.set("namePrefix", params.namePrefix);
53258
- if (params?.industry)
53259
- qs.set("industry", params.industry);
53260
- if (params?.limit != null)
53261
- qs.set("limit", String(params.limit));
53262
- const query = qs.toString();
53263
- const path = query ? `/api/v1/templates?${query}` : "/api/v1/templates";
53264
- const res = await this.client.get(path);
53265
- return res.data;
53294
+ const { data: sitesData, error: sitesError } = await this.client.db.from("sites").select("id, handle, name");
53295
+ if (sitesError)
53296
+ throw new NeopressApiError("DB_ERROR", sitesError.message, 0, sitesError);
53297
+ const siteMeta = /* @__PURE__ */ new Map();
53298
+ for (const site of sitesData ?? []) {
53299
+ if (typeof site.id !== "number")
53300
+ continue;
53301
+ siteMeta.set(site.id, {
53302
+ handle: site.handle ?? null,
53303
+ name: site.name ?? null
53304
+ });
53305
+ }
53306
+ const siteIds = [...siteMeta.keys()];
53307
+ if (siteIds.length === 0)
53308
+ return [];
53309
+ const namePrefix = params?.namePrefix?.trim();
53310
+ const limit = Math.min(Math.max(params?.limit ?? 100, 1), 500);
53311
+ let query = this.client.db.from("templates").select("id, name, reference_url, preview_img_urls, description, created_at").in("id", siteIds);
53312
+ if (namePrefix)
53313
+ query = query.ilike("name", `${namePrefix}%`);
53314
+ if (params?.order)
53315
+ query = query.order("created_at", { ascending: params.order === "asc" });
53316
+ query = query.limit(limit);
53317
+ const { data, error: error48 } = await query;
53318
+ if (error48)
53319
+ throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
53320
+ return (data ?? []).map((t) => {
53321
+ const siteId2 = t.id;
53322
+ return {
53323
+ siteId: siteId2,
53324
+ handle: siteMeta.get(siteId2)?.handle ?? null,
53325
+ siteName: siteMeta.get(siteId2)?.name ?? null,
53326
+ name: t.name,
53327
+ referenceUrl: t.reference_url,
53328
+ previewImgUrls: t.preview_img_urls ?? null,
53329
+ description: t.description ?? null,
53330
+ createdAt: t.created_at
53331
+ };
53332
+ });
53333
+ }
53334
+ };
53335
+
53336
+ // ../sdk/dist/endpoints/headshots.js
53337
+ var HeadshotsEndpoint = class {
53338
+ client;
53339
+ constructor(client) {
53340
+ this.client = client;
53341
+ }
53342
+ async list(params) {
53343
+ const { page, limit, offset } = this.client.resolvePagination(params);
53344
+ let query = this.client.db.from("headshot_pool").select("*", { count: "exact" });
53345
+ if (params?.ageBand)
53346
+ query = query.eq("age_band", params.ageBand);
53347
+ if (params?.gender)
53348
+ query = query.eq("gender", params.gender);
53349
+ if (params?.ethnicity)
53350
+ query = query.eq("ethnicity", params.ethnicity);
53351
+ if (params?.attire)
53352
+ query = query.eq("attire", params.attire);
53353
+ if (params?.isActive !== void 0)
53354
+ query = query.eq("is_active", params.isActive);
53355
+ if (params?.order) {
53356
+ query = query.order("created_at", { ascending: params.order === "asc" });
53357
+ } else {
53358
+ query = query.order("age_band", { ascending: true }).order("gender", { ascending: true }).order("ethnicity", { ascending: true }).order("variation_index", { ascending: true });
53359
+ }
53360
+ const { data, error: error48, count } = await query.range(offset, offset + limit - 1);
53361
+ if (error48)
53362
+ throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
53363
+ return {
53364
+ data: (data ?? []).map((r) => serializeHeadshot(r)),
53365
+ pagination: this.client.paginationMeta(page, limit, offset, count ?? 0)
53366
+ };
53367
+ }
53368
+ async get(id) {
53369
+ const { data, error: error48 } = await this.client.db.from("headshot_pool").select("*").eq("id", id).single();
53370
+ if (error48)
53371
+ throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
53372
+ return serializeHeadshot(data);
53373
+ }
53374
+ async create(params) {
53375
+ const values = {
53376
+ image_url: params.imageUrl,
53377
+ age_band: params.ageBand,
53378
+ gender: params.gender,
53379
+ ethnicity: params.ethnicity,
53380
+ variation_index: params.variationIndex
53381
+ };
53382
+ if (params.attire !== void 0)
53383
+ values.attire = params.attire;
53384
+ if (params.width !== void 0)
53385
+ values.width = params.width;
53386
+ if (params.height !== void 0)
53387
+ values.height = params.height;
53388
+ if (params.aspectRatio !== void 0)
53389
+ values.aspect_ratio = params.aspectRatio;
53390
+ if (params.mimeType !== void 0)
53391
+ values.mime_type = params.mimeType;
53392
+ if (params.byteSize !== void 0)
53393
+ values.byte_size = params.byteSize;
53394
+ if (params.gptPrompt !== void 0)
53395
+ values.gpt_prompt = params.gptPrompt;
53396
+ if (params.tags !== void 0)
53397
+ values.tags = params.tags;
53398
+ if (params.isActive !== void 0)
53399
+ values.is_active = params.isActive;
53400
+ const { data, error: error48 } = await this.client.db.from("headshot_pool").insert(values).select().single();
53401
+ if (error48)
53402
+ throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
53403
+ return serializeHeadshot(data);
53404
+ }
53405
+ async update(id, params) {
53406
+ const values = {};
53407
+ if (params.imageUrl !== void 0)
53408
+ values.image_url = params.imageUrl;
53409
+ if (params.ageBand !== void 0)
53410
+ values.age_band = params.ageBand;
53411
+ if (params.gender !== void 0)
53412
+ values.gender = params.gender;
53413
+ if (params.ethnicity !== void 0)
53414
+ values.ethnicity = params.ethnicity;
53415
+ if (params.attire !== void 0)
53416
+ values.attire = params.attire;
53417
+ if (params.variationIndex !== void 0)
53418
+ values.variation_index = params.variationIndex;
53419
+ if (params.width !== void 0)
53420
+ values.width = params.width;
53421
+ if (params.height !== void 0)
53422
+ values.height = params.height;
53423
+ if (params.aspectRatio !== void 0)
53424
+ values.aspect_ratio = params.aspectRatio;
53425
+ if (params.mimeType !== void 0)
53426
+ values.mime_type = params.mimeType;
53427
+ if (params.byteSize !== void 0)
53428
+ values.byte_size = params.byteSize;
53429
+ if (params.gptPrompt !== void 0)
53430
+ values.gpt_prompt = params.gptPrompt;
53431
+ if (params.tags !== void 0)
53432
+ values.tags = params.tags;
53433
+ if (params.isActive !== void 0)
53434
+ values.is_active = params.isActive;
53435
+ const { data, error: error48 } = await this.client.db.from("headshot_pool").update(values).eq("id", id).select().single();
53436
+ if (error48)
53437
+ throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
53438
+ return serializeHeadshot(data);
53439
+ }
53440
+ async delete(id) {
53441
+ const { error: error48 } = await this.client.db.from("headshot_pool").delete().eq("id", id);
53442
+ if (error48)
53443
+ throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
53444
+ return { id, deleted: true };
53266
53445
  }
53267
53446
  };
53268
53447
 
@@ -53286,6 +53465,7 @@ var NeopressClient = class {
53286
53465
  entryReferences;
53287
53466
  analytics;
53288
53467
  templates;
53468
+ headshots;
53289
53469
  constructor(options) {
53290
53470
  this.baseUrl = (options.baseUrl || "https://app.neopress.ai").replace(/\/$/, "");
53291
53471
  this.accessToken = options.accessToken || "";
@@ -53304,6 +53484,7 @@ var NeopressClient = class {
53304
53484
  this.entryReferences = new EntryReferencesEndpoint(this);
53305
53485
  this.analytics = new AnalyticsEndpoint(this);
53306
53486
  this.templates = new TemplatesEndpoint(this);
53487
+ this.headshots = new HeadshotsEndpoint(this);
53307
53488
  }
53308
53489
  get siteBasePath() {
53309
53490
  return `/api/v1/sites/${this.siteId}`;
@@ -53584,14 +53765,15 @@ Use these rules before generating pages, collection schemas, entries, forms, or
53584
53765
 
53585
53766
  - Layout owns header, footer, global CSS, and 404. Page TSX starts at page content.
53586
53767
  - Generated page TSX is sandboxed. Do not import Supabase, create API clients, read env vars, use filesystem/process APIs, or assume arbitrary npm packages.
53587
- - Use allowed runtime packages only: React/Next basics, shadcn UI imports, lucide-react, date-fns, framer-motion, gsap (incl. \`gsap/ScrollTrigger\`, driven via \`@gsap/react\`'s \`useGSAP\`), @neopress/content, @neopress/routing, @neopress/i18n, and @neopress/forms.
53768
+ - Use allowed runtime packages only: React/Next basics, shadcn UI imports, lucide-react, @radix-ui/react-slot, @radix-ui/react-select, @neopress/youtube, @neopress/map, clsx, class-variance-authority, tailwind-merge, date-fns, framer-motion, gsap (including \`gsap/ScrollTrigger\`, driven via \`@gsap/react\`'s \`useGSAP\`), react-hook-form, zod, @hookform/resolvers, @hookform/resolvers/zod, @neopress/content, @neopress/routing, @neopress/i18n, and @neopress/forms.
53769
+ - @radix-ui/react-select is a single-value listbox/dropdown (replaces a native \`<select>\`, whose popup is unstyled OS chrome). Compose its parts directly in page TSX; every \`<Select.Item value>\` must be a non-empty string (an empty-string value throws at runtime and blanks the page \u2014 use a sentinel like \`"all"\`); use \`position="popper"\` with an explicit z-index and a non-transparent background on \`<Select.Content>\` (it portals to \`document.body\`).
53588
53770
 
53589
53771
  ## Templates
53590
53772
 
53591
53773
  - Reusable templates are normal Neopress sites marked by a \`templates\` metadata row.
53592
53774
  - \`templates.id\` equals \`sites.id\`.
53593
53775
  - Build layout, pages, collections, entries, forms, assets, compile, publish, and verify before marking a finished template.
53594
- - Use \`neopress_template_mark\` to create or update the metadata row with \`name\`, \`industry\`, required \`referenceUrl\`, required \`previewImgUrls\` (at least one), and optional \`description\`.
53776
+ - Use \`neopress_template_mark\` to create or update the metadata row with \`name\`, required \`referenceUrl\`, required \`previewImgUrls\` (at least one), and optional \`description\`.
53595
53777
  - \`referenceUrl\` is a single http(s) provenance URL. \`description\` is an optional summary of the template (max 150 characters).
53596
53778
  - Template metadata does not replace page TSX, CMS content, forms, or publish state.
53597
53779
  - Use \`neopress_template_delete\` only for explicit template-site hard deletion. It removes the metadata row and connected site.
@@ -53601,6 +53783,7 @@ Use these rules before generating pages, collection schemas, entries, forms, or
53601
53783
  - Dynamic pages require a collection, a page path like \`/blog/[slug]\`, a numeric \`collectionId\`, matching entries, entry publish, page compile, and site publish.
53602
53784
  - \`queryConfig\` is stored in page \`draftMeta.queryConfig\`.
53603
53785
  - Query labels become React props. Entry query results are flattened, so use \`post.body\` instead of \`post.data.body\`.
53786
+ - Initial CMS data arrives through those injected query props. \`entryClient\`, when injected in reader/preview for a site handle, is only a client-side auxiliary for load-more/filter/get/create interactions after the initial render; do not use it for initial render or server data loading.
53604
53787
  - Use numeric \`collection_id\` filters. Runtime controls site, status, locale, deleted state, and published snapshots.
53605
53788
 
53606
53789
  ## Collections and entries
@@ -53614,11 +53797,13 @@ Use these rules before generating pages, collection schemas, entries, forms, or
53614
53797
 
53615
53798
  - Reference fields require a schema field with \`type: "references"\` and target \`collection_id\`.
53616
53799
  - Links live in \`entry_references\`, not only in raw entry \`data\`.
53800
+ - \`includeReferences\` fetches arrays keyed by the includeReferences alias or field key, and parent entry \`id\` must be selected. With an alias, the alias prop remains an array of referenced entries. Without an alias, if the field key matches a raw numeric reference field in \`entry.data\`, flattening unwraps that array to one flattened object or null.
53617
53801
  - After changing references, publish the source entry again.
53618
53802
 
53619
53803
  ## Forms
53620
53804
 
53621
53805
  - Render forms with \`NeopressForm\` from \`@neopress/forms\` and the injected \`formClient\` prop.
53806
+ - In page TSX, \`formId\` may be a numeric literal or numeric string so schemas can be injected before compile.
53622
53807
  - Do not manually submit form data with \`fetch\` or \`FormData\`.
53623
53808
  - Create/update the form, publish the form, compile the page, then publish the site.
53624
53809
 
@@ -53936,7 +54121,6 @@ var toolDefinitions = [
53936
54121
  ...siteIdShape,
53937
54122
  name: external_exports.string(),
53938
54123
  description: external_exports.string().max(150).optional(),
53939
- industry: external_exports.string(),
53940
54124
  referenceUrl: httpUrlSchema,
53941
54125
  previewImgUrls: external_exports.array(external_exports.string()).min(1)
53942
54126
  },
@@ -53945,7 +54129,6 @@ var toolDefinitions = [
53945
54129
  return client.templates.mark({
53946
54130
  name: asString(input, "name"),
53947
54131
  description: asOptionalString(input, "description"),
53948
- industry: asString(input, "industry"),
53949
54132
  referenceUrl: asString(input, "referenceUrl"),
53950
54133
  previewImgUrls: input.previewImgUrls
53951
54134
  });
package/dist/http-bin.cjs CHANGED
@@ -3838,7 +3838,7 @@ var require_fast_uri = __commonJS({
3838
3838
  if (!options.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport)) {
3839
3839
  if (parsed.host && (options.domainHost || schemeHandler && schemeHandler.domainHost) && isIP === false && nonSimpleDomain(parsed.host)) {
3840
3840
  try {
3841
- parsed.host = URL.domainToASCII(parsed.host.toLowerCase());
3841
+ parsed.host = new URL("http://" + parsed.host).hostname;
3842
3842
  } catch (e) {
3843
3843
  parsed.error = parsed.error || "Host's domain name can not be converted to ASCII: " + e;
3844
3844
  }
@@ -52583,13 +52583,33 @@ function serializeTemplate(t) {
52583
52583
  id: t.id,
52584
52584
  name: t.name,
52585
52585
  description: t.description ?? null,
52586
- industry: t.industry,
52587
52586
  referenceUrl: t.reference_url,
52588
52587
  previewImgUrls: t.preview_img_urls,
52589
52588
  previewVideoUrl: t.preview_video_url ?? null,
52590
52589
  createdAt: t.created_at
52591
52590
  };
52592
52591
  }
52592
+ function serializeHeadshot(h) {
52593
+ return {
52594
+ id: h.id,
52595
+ imageUrl: h.image_url,
52596
+ width: h.width,
52597
+ height: h.height,
52598
+ aspectRatio: h.aspect_ratio,
52599
+ mimeType: h.mime_type,
52600
+ byteSize: h.byte_size,
52601
+ ageBand: h.age_band,
52602
+ gender: h.gender,
52603
+ ethnicity: h.ethnicity,
52604
+ attire: h.attire,
52605
+ variationIndex: h.variation_index,
52606
+ gptPrompt: h.gpt_prompt,
52607
+ tags: h.tags ?? [],
52608
+ isActive: h.is_active,
52609
+ createdAt: h.created_at,
52610
+ updatedAt: h.updated_at
52611
+ };
52612
+ }
52593
52613
  function serializeSite(site) {
52594
52614
  return {
52595
52615
  id: site.id,
@@ -52643,7 +52663,8 @@ var PagesEndpoint = class {
52643
52663
  }
52644
52664
  async list(params) {
52645
52665
  const { page, limit, offset } = this.client.resolvePagination(params);
52646
- let query = this.client.db.from("pages").select("*", { count: "exact" }).eq("site_id", this.client.siteIdNumber).is("draft_deleted_at", null).order("path");
52666
+ let query = this.client.db.from("pages").select("*", { count: "exact" }).eq("site_id", this.client.siteIdNumber).is("draft_deleted_at", null);
52667
+ query = params?.order ? query.order("created_at", { ascending: params.order === "asc" }) : query.order("path");
52647
52668
  if (params?.status)
52648
52669
  query = query.eq("status", params.status);
52649
52670
  const { data, error: error48, count } = await query.range(offset, offset + limit - 1);
@@ -53929,8 +53950,10 @@ var CollectionsEndpoint = class {
53929
53950
  get basePath() {
53930
53951
  return `${this.client.siteBasePath}/collections`;
53931
53952
  }
53932
- async list() {
53933
- const { data, error: error48 } = await this.client.db.from("collections").select("*").eq("site_id", this.client.siteIdNumber).is("draft_deleted_at", null).order("name");
53953
+ async list(params) {
53954
+ let query = this.client.db.from("collections").select("*").eq("site_id", this.client.siteIdNumber).is("draft_deleted_at", null);
53955
+ query = params?.order ? query.order("created_at", { ascending: params.order === "asc" }) : query.order("name");
53956
+ const { data, error: error48 } = await query;
53934
53957
  if (error48)
53935
53958
  throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
53936
53959
  return (data ?? []).map((r) => serializeCollection(r));
@@ -54003,7 +54026,7 @@ var EntriesEndpoint = class {
54003
54026
  }
54004
54027
  async list(collectionId, params) {
54005
54028
  const { page, limit, offset } = this.client.resolvePagination(params);
54006
- let query = this.client.db.from("entries").select("*", { count: "exact" }).eq("site_id", this.client.siteIdNumber).eq("collection_id", collectionId).is("deleted_at", null).order("created_at", { ascending: false });
54029
+ let query = this.client.db.from("entries").select("*", { count: "exact" }).eq("site_id", this.client.siteIdNumber).eq("collection_id", collectionId).is("deleted_at", null).order("created_at", { ascending: params?.order === "asc" });
54007
54030
  if (params?.status)
54008
54031
  query = query.eq("status", params.status);
54009
54032
  if (params?.locale)
@@ -54094,8 +54117,10 @@ var FormsEndpoint = class {
54094
54117
  get basePath() {
54095
54118
  return `${this.client.siteBasePath}/forms`;
54096
54119
  }
54097
- async list() {
54098
- const { data, error: error48 } = await this.client.db.from("forms").select("*").eq("site_id", this.client.siteIdNumber).is("draft_deleted_at", null).order("name");
54120
+ async list(params) {
54121
+ let query = this.client.db.from("forms").select("*").eq("site_id", this.client.siteIdNumber).is("draft_deleted_at", null);
54122
+ query = params?.order ? query.order("created_at", { ascending: params.order === "asc" }) : query.order("name");
54123
+ const { data, error: error48 } = await query;
54099
54124
  if (error48)
54100
54125
  throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
54101
54126
  const rows = data ?? [];
@@ -54174,7 +54199,7 @@ var AssetsEndpoint = class {
54174
54199
  }
54175
54200
  async list(params) {
54176
54201
  const { page, limit, offset } = this.client.resolvePagination(params);
54177
- const { data, error: error48, count } = await this.client.db.from("assets").select("*", { count: "exact" }).eq("site_id", this.client.siteIdNumber).order("created_at", { ascending: false }).range(offset, offset + limit - 1);
54202
+ const { data, error: error48, count } = await this.client.db.from("assets").select("*", { count: "exact" }).eq("site_id", this.client.siteIdNumber).order("created_at", { ascending: params?.order === "asc" }).range(offset, offset + limit - 1);
54178
54203
  if (error48)
54179
54204
  throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
54180
54205
  const rows = data ?? [];
@@ -54240,7 +54265,7 @@ var SiteEndpoint = class {
54240
54265
  constructor(client) {
54241
54266
  this.client = client;
54242
54267
  }
54243
- async list() {
54268
+ async list(params) {
54244
54269
  const profileId = this.client.authUserId;
54245
54270
  if (!profileId) {
54246
54271
  throw new NeopressApiError("NO_AUTH", "site.list requires an authenticated access token", 0);
@@ -54248,10 +54273,15 @@ var SiteEndpoint = class {
54248
54273
  const { data, error: error48 } = await this.client.db.from("sites_profiles").select("role, sites!inner(*)").eq("profile_id", profileId).eq("status", "active");
54249
54274
  if (error48)
54250
54275
  throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
54251
- return (data ?? []).map((m) => ({
54276
+ const sites = (data ?? []).map((m) => ({
54252
54277
  ...serializeSite(m.sites),
54253
54278
  role: m.role
54254
54279
  }));
54280
+ if (params?.order) {
54281
+ const dir = params.order === "asc" ? 1 : -1;
54282
+ sites.sort((a, b) => (a.createdAt ?? "") < (b.createdAt ?? "") ? -dir : (a.createdAt ?? "") > (b.createdAt ?? "") ? dir : 0);
54283
+ }
54284
+ return sites;
54255
54285
  }
54256
54286
  async get() {
54257
54287
  const { data, error: error48 } = await this.client.db.from("sites").select("*").eq("id", this.client.siteIdNumber).single();
@@ -54289,8 +54319,10 @@ var RedirectsEndpoint = class {
54289
54319
  constructor(client) {
54290
54320
  this.client = client;
54291
54321
  }
54292
- async list() {
54293
- const { data, error: error48 } = await this.client.db.from("redirect_rules").select("*").eq("site_id", this.client.siteIdNumber).order("priority", { ascending: true });
54322
+ async list(params) {
54323
+ let query = this.client.db.from("redirect_rules").select("*").eq("site_id", this.client.siteIdNumber);
54324
+ query = params?.order ? query.order("created_at", { ascending: params.order === "asc" }) : query.order("priority", { ascending: true });
54325
+ const { data, error: error48 } = await query;
54294
54326
  if (error48)
54295
54327
  throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
54296
54328
  return (data ?? []).map((r) => serializeRedirect(r));
@@ -54300,7 +54332,7 @@ var RedirectsEndpoint = class {
54300
54332
  site_id: this.client.siteIdNumber,
54301
54333
  source: data.source,
54302
54334
  destination: data.destination,
54303
- redirect_type: data.redirectType ?? 307,
54335
+ redirect_type: data.redirectType ?? 308,
54304
54336
  include_children: data.includeChildren ?? false,
54305
54337
  preserve_path: data.preservePath ?? false,
54306
54338
  enabled: data.enabled !== false,
@@ -54367,7 +54399,7 @@ var EntryReferencesEndpoint = class {
54367
54399
  query = query.eq("from_entry_id", params.fromEntryId);
54368
54400
  if (params?.toEntryId)
54369
54401
  query = query.eq("to_entry_id", params.toEntryId);
54370
- const { data, error: error48 } = await query.order("created_at", { ascending: false });
54402
+ const { data, error: error48 } = await query.order("created_at", { ascending: params?.order === "asc" });
54371
54403
  if (error48)
54372
54404
  throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
54373
54405
  return (data ?? []).map((r) => serializeEntryReference(r));
@@ -54489,18 +54521,165 @@ var TemplatesEndpoint = class {
54489
54521
  const res = await this.client.delete(this.basePath);
54490
54522
  return res.data;
54491
54523
  }
54524
+ /**
54525
+ * List templates across the sites the caller can access.
54526
+ *
54527
+ * Direct-DB: `templates` is public-read and `sites` RLS scopes the visible set
54528
+ * (own active memberships, or all sites for the super admin), so no server
54529
+ * route is needed — the two RLS-scoped queries reproduce the old handler.
54530
+ */
54492
54531
  async list(params) {
54493
- const qs = new URLSearchParams();
54494
- if (params?.namePrefix)
54495
- qs.set("namePrefix", params.namePrefix);
54496
- if (params?.industry)
54497
- qs.set("industry", params.industry);
54498
- if (params?.limit != null)
54499
- qs.set("limit", String(params.limit));
54500
- const query = qs.toString();
54501
- const path = query ? `/api/v1/templates?${query}` : "/api/v1/templates";
54502
- const res = await this.client.get(path);
54503
- return res.data;
54532
+ const { data: sitesData, error: sitesError } = await this.client.db.from("sites").select("id, handle, name");
54533
+ if (sitesError)
54534
+ throw new NeopressApiError("DB_ERROR", sitesError.message, 0, sitesError);
54535
+ const siteMeta = /* @__PURE__ */ new Map();
54536
+ for (const site of sitesData ?? []) {
54537
+ if (typeof site.id !== "number")
54538
+ continue;
54539
+ siteMeta.set(site.id, {
54540
+ handle: site.handle ?? null,
54541
+ name: site.name ?? null
54542
+ });
54543
+ }
54544
+ const siteIds = [...siteMeta.keys()];
54545
+ if (siteIds.length === 0)
54546
+ return [];
54547
+ const namePrefix = params?.namePrefix?.trim();
54548
+ const limit = Math.min(Math.max(params?.limit ?? 100, 1), 500);
54549
+ let query = this.client.db.from("templates").select("id, name, reference_url, preview_img_urls, description, created_at").in("id", siteIds);
54550
+ if (namePrefix)
54551
+ query = query.ilike("name", `${namePrefix}%`);
54552
+ if (params?.order)
54553
+ query = query.order("created_at", { ascending: params.order === "asc" });
54554
+ query = query.limit(limit);
54555
+ const { data, error: error48 } = await query;
54556
+ if (error48)
54557
+ throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
54558
+ return (data ?? []).map((t) => {
54559
+ const siteId2 = t.id;
54560
+ return {
54561
+ siteId: siteId2,
54562
+ handle: siteMeta.get(siteId2)?.handle ?? null,
54563
+ siteName: siteMeta.get(siteId2)?.name ?? null,
54564
+ name: t.name,
54565
+ referenceUrl: t.reference_url,
54566
+ previewImgUrls: t.preview_img_urls ?? null,
54567
+ description: t.description ?? null,
54568
+ createdAt: t.created_at
54569
+ };
54570
+ });
54571
+ }
54572
+ };
54573
+
54574
+ // ../sdk/dist/endpoints/headshots.js
54575
+ var HeadshotsEndpoint = class {
54576
+ client;
54577
+ constructor(client) {
54578
+ this.client = client;
54579
+ }
54580
+ async list(params) {
54581
+ const { page, limit, offset } = this.client.resolvePagination(params);
54582
+ let query = this.client.db.from("headshot_pool").select("*", { count: "exact" });
54583
+ if (params?.ageBand)
54584
+ query = query.eq("age_band", params.ageBand);
54585
+ if (params?.gender)
54586
+ query = query.eq("gender", params.gender);
54587
+ if (params?.ethnicity)
54588
+ query = query.eq("ethnicity", params.ethnicity);
54589
+ if (params?.attire)
54590
+ query = query.eq("attire", params.attire);
54591
+ if (params?.isActive !== void 0)
54592
+ query = query.eq("is_active", params.isActive);
54593
+ if (params?.order) {
54594
+ query = query.order("created_at", { ascending: params.order === "asc" });
54595
+ } else {
54596
+ query = query.order("age_band", { ascending: true }).order("gender", { ascending: true }).order("ethnicity", { ascending: true }).order("variation_index", { ascending: true });
54597
+ }
54598
+ const { data, error: error48, count } = await query.range(offset, offset + limit - 1);
54599
+ if (error48)
54600
+ throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
54601
+ return {
54602
+ data: (data ?? []).map((r) => serializeHeadshot(r)),
54603
+ pagination: this.client.paginationMeta(page, limit, offset, count ?? 0)
54604
+ };
54605
+ }
54606
+ async get(id) {
54607
+ const { data, error: error48 } = await this.client.db.from("headshot_pool").select("*").eq("id", id).single();
54608
+ if (error48)
54609
+ throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
54610
+ return serializeHeadshot(data);
54611
+ }
54612
+ async create(params) {
54613
+ const values = {
54614
+ image_url: params.imageUrl,
54615
+ age_band: params.ageBand,
54616
+ gender: params.gender,
54617
+ ethnicity: params.ethnicity,
54618
+ variation_index: params.variationIndex
54619
+ };
54620
+ if (params.attire !== void 0)
54621
+ values.attire = params.attire;
54622
+ if (params.width !== void 0)
54623
+ values.width = params.width;
54624
+ if (params.height !== void 0)
54625
+ values.height = params.height;
54626
+ if (params.aspectRatio !== void 0)
54627
+ values.aspect_ratio = params.aspectRatio;
54628
+ if (params.mimeType !== void 0)
54629
+ values.mime_type = params.mimeType;
54630
+ if (params.byteSize !== void 0)
54631
+ values.byte_size = params.byteSize;
54632
+ if (params.gptPrompt !== void 0)
54633
+ values.gpt_prompt = params.gptPrompt;
54634
+ if (params.tags !== void 0)
54635
+ values.tags = params.tags;
54636
+ if (params.isActive !== void 0)
54637
+ values.is_active = params.isActive;
54638
+ const { data, error: error48 } = await this.client.db.from("headshot_pool").insert(values).select().single();
54639
+ if (error48)
54640
+ throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
54641
+ return serializeHeadshot(data);
54642
+ }
54643
+ async update(id, params) {
54644
+ const values = {};
54645
+ if (params.imageUrl !== void 0)
54646
+ values.image_url = params.imageUrl;
54647
+ if (params.ageBand !== void 0)
54648
+ values.age_band = params.ageBand;
54649
+ if (params.gender !== void 0)
54650
+ values.gender = params.gender;
54651
+ if (params.ethnicity !== void 0)
54652
+ values.ethnicity = params.ethnicity;
54653
+ if (params.attire !== void 0)
54654
+ values.attire = params.attire;
54655
+ if (params.variationIndex !== void 0)
54656
+ values.variation_index = params.variationIndex;
54657
+ if (params.width !== void 0)
54658
+ values.width = params.width;
54659
+ if (params.height !== void 0)
54660
+ values.height = params.height;
54661
+ if (params.aspectRatio !== void 0)
54662
+ values.aspect_ratio = params.aspectRatio;
54663
+ if (params.mimeType !== void 0)
54664
+ values.mime_type = params.mimeType;
54665
+ if (params.byteSize !== void 0)
54666
+ values.byte_size = params.byteSize;
54667
+ if (params.gptPrompt !== void 0)
54668
+ values.gpt_prompt = params.gptPrompt;
54669
+ if (params.tags !== void 0)
54670
+ values.tags = params.tags;
54671
+ if (params.isActive !== void 0)
54672
+ values.is_active = params.isActive;
54673
+ const { data, error: error48 } = await this.client.db.from("headshot_pool").update(values).eq("id", id).select().single();
54674
+ if (error48)
54675
+ throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
54676
+ return serializeHeadshot(data);
54677
+ }
54678
+ async delete(id) {
54679
+ const { error: error48 } = await this.client.db.from("headshot_pool").delete().eq("id", id);
54680
+ if (error48)
54681
+ throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
54682
+ return { id, deleted: true };
54504
54683
  }
54505
54684
  };
54506
54685
 
@@ -54524,6 +54703,7 @@ var NeopressClient = class {
54524
54703
  entryReferences;
54525
54704
  analytics;
54526
54705
  templates;
54706
+ headshots;
54527
54707
  constructor(options) {
54528
54708
  this.baseUrl = (options.baseUrl || "https://app.neopress.ai").replace(/\/$/, "");
54529
54709
  this.accessToken = options.accessToken || "";
@@ -54542,6 +54722,7 @@ var NeopressClient = class {
54542
54722
  this.entryReferences = new EntryReferencesEndpoint(this);
54543
54723
  this.analytics = new AnalyticsEndpoint(this);
54544
54724
  this.templates = new TemplatesEndpoint(this);
54725
+ this.headshots = new HeadshotsEndpoint(this);
54545
54726
  }
54546
54727
  get siteBasePath() {
54547
54728
  return `/api/v1/sites/${this.siteId}`;
@@ -54822,14 +55003,15 @@ Use these rules before generating pages, collection schemas, entries, forms, or
54822
55003
 
54823
55004
  - Layout owns header, footer, global CSS, and 404. Page TSX starts at page content.
54824
55005
  - Generated page TSX is sandboxed. Do not import Supabase, create API clients, read env vars, use filesystem/process APIs, or assume arbitrary npm packages.
54825
- - Use allowed runtime packages only: React/Next basics, shadcn UI imports, lucide-react, date-fns, framer-motion, gsap (incl. \`gsap/ScrollTrigger\`, driven via \`@gsap/react\`'s \`useGSAP\`), @neopress/content, @neopress/routing, @neopress/i18n, and @neopress/forms.
55006
+ - Use allowed runtime packages only: React/Next basics, shadcn UI imports, lucide-react, @radix-ui/react-slot, @radix-ui/react-select, @neopress/youtube, @neopress/map, clsx, class-variance-authority, tailwind-merge, date-fns, framer-motion, gsap (including \`gsap/ScrollTrigger\`, driven via \`@gsap/react\`'s \`useGSAP\`), react-hook-form, zod, @hookform/resolvers, @hookform/resolvers/zod, @neopress/content, @neopress/routing, @neopress/i18n, and @neopress/forms.
55007
+ - @radix-ui/react-select is a single-value listbox/dropdown (replaces a native \`<select>\`, whose popup is unstyled OS chrome). Compose its parts directly in page TSX; every \`<Select.Item value>\` must be a non-empty string (an empty-string value throws at runtime and blanks the page \u2014 use a sentinel like \`"all"\`); use \`position="popper"\` with an explicit z-index and a non-transparent background on \`<Select.Content>\` (it portals to \`document.body\`).
54826
55008
 
54827
55009
  ## Templates
54828
55010
 
54829
55011
  - Reusable templates are normal Neopress sites marked by a \`templates\` metadata row.
54830
55012
  - \`templates.id\` equals \`sites.id\`.
54831
55013
  - Build layout, pages, collections, entries, forms, assets, compile, publish, and verify before marking a finished template.
54832
- - Use \`neopress_template_mark\` to create or update the metadata row with \`name\`, \`industry\`, required \`referenceUrl\`, required \`previewImgUrls\` (at least one), and optional \`description\`.
55014
+ - Use \`neopress_template_mark\` to create or update the metadata row with \`name\`, required \`referenceUrl\`, required \`previewImgUrls\` (at least one), and optional \`description\`.
54833
55015
  - \`referenceUrl\` is a single http(s) provenance URL. \`description\` is an optional summary of the template (max 150 characters).
54834
55016
  - Template metadata does not replace page TSX, CMS content, forms, or publish state.
54835
55017
  - Use \`neopress_template_delete\` only for explicit template-site hard deletion. It removes the metadata row and connected site.
@@ -54839,6 +55021,7 @@ Use these rules before generating pages, collection schemas, entries, forms, or
54839
55021
  - Dynamic pages require a collection, a page path like \`/blog/[slug]\`, a numeric \`collectionId\`, matching entries, entry publish, page compile, and site publish.
54840
55022
  - \`queryConfig\` is stored in page \`draftMeta.queryConfig\`.
54841
55023
  - Query labels become React props. Entry query results are flattened, so use \`post.body\` instead of \`post.data.body\`.
55024
+ - Initial CMS data arrives through those injected query props. \`entryClient\`, when injected in reader/preview for a site handle, is only a client-side auxiliary for load-more/filter/get/create interactions after the initial render; do not use it for initial render or server data loading.
54842
55025
  - Use numeric \`collection_id\` filters. Runtime controls site, status, locale, deleted state, and published snapshots.
54843
55026
 
54844
55027
  ## Collections and entries
@@ -54852,11 +55035,13 @@ Use these rules before generating pages, collection schemas, entries, forms, or
54852
55035
 
54853
55036
  - Reference fields require a schema field with \`type: "references"\` and target \`collection_id\`.
54854
55037
  - Links live in \`entry_references\`, not only in raw entry \`data\`.
55038
+ - \`includeReferences\` fetches arrays keyed by the includeReferences alias or field key, and parent entry \`id\` must be selected. With an alias, the alias prop remains an array of referenced entries. Without an alias, if the field key matches a raw numeric reference field in \`entry.data\`, flattening unwraps that array to one flattened object or null.
54855
55039
  - After changing references, publish the source entry again.
54856
55040
 
54857
55041
  ## Forms
54858
55042
 
54859
55043
  - Render forms with \`NeopressForm\` from \`@neopress/forms\` and the injected \`formClient\` prop.
55044
+ - In page TSX, \`formId\` may be a numeric literal or numeric string so schemas can be injected before compile.
54860
55045
  - Do not manually submit form data with \`fetch\` or \`FormData\`.
54861
55046
  - Create/update the form, publish the form, compile the page, then publish the site.
54862
55047
 
@@ -55174,7 +55359,6 @@ var toolDefinitions = [
55174
55359
  ...siteIdShape,
55175
55360
  name: external_exports.string(),
55176
55361
  description: external_exports.string().max(150).optional(),
55177
- industry: external_exports.string(),
55178
55362
  referenceUrl: httpUrlSchema,
55179
55363
  previewImgUrls: external_exports.array(external_exports.string()).min(1)
55180
55364
  },
@@ -55183,7 +55367,6 @@ var toolDefinitions = [
55183
55367
  return client.templates.mark({
55184
55368
  name: asString(input, "name"),
55185
55369
  description: asOptionalString(input, "description"),
55186
- industry: asString(input, "industry"),
55187
55370
  referenceUrl: asString(input, "referenceUrl"),
55188
55371
  previewImgUrls: input.previewImgUrls
55189
55372
  });
package/dist/index.js CHANGED
@@ -3836,7 +3836,7 @@ var require_fast_uri = __commonJS({
3836
3836
  if (!options.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport)) {
3837
3837
  if (parsed.host && (options.domainHost || schemeHandler && schemeHandler.domainHost) && isIP === false && nonSimpleDomain(parsed.host)) {
3838
3838
  try {
3839
- parsed.host = URL.domainToASCII(parsed.host.toLowerCase());
3839
+ parsed.host = new URL("http://" + parsed.host).hostname;
3840
3840
  } catch (e) {
3841
3841
  parsed.error = parsed.error || "Host's domain name can not be converted to ASCII: " + e;
3842
3842
  }
@@ -51253,13 +51253,33 @@ function serializeTemplate(t) {
51253
51253
  id: t.id,
51254
51254
  name: t.name,
51255
51255
  description: t.description ?? null,
51256
- industry: t.industry,
51257
51256
  referenceUrl: t.reference_url,
51258
51257
  previewImgUrls: t.preview_img_urls,
51259
51258
  previewVideoUrl: t.preview_video_url ?? null,
51260
51259
  createdAt: t.created_at
51261
51260
  };
51262
51261
  }
51262
+ function serializeHeadshot(h) {
51263
+ return {
51264
+ id: h.id,
51265
+ imageUrl: h.image_url,
51266
+ width: h.width,
51267
+ height: h.height,
51268
+ aspectRatio: h.aspect_ratio,
51269
+ mimeType: h.mime_type,
51270
+ byteSize: h.byte_size,
51271
+ ageBand: h.age_band,
51272
+ gender: h.gender,
51273
+ ethnicity: h.ethnicity,
51274
+ attire: h.attire,
51275
+ variationIndex: h.variation_index,
51276
+ gptPrompt: h.gpt_prompt,
51277
+ tags: h.tags ?? [],
51278
+ isActive: h.is_active,
51279
+ createdAt: h.created_at,
51280
+ updatedAt: h.updated_at
51281
+ };
51282
+ }
51263
51283
  function serializeSite(site) {
51264
51284
  return {
51265
51285
  id: site.id,
@@ -51313,7 +51333,8 @@ var PagesEndpoint = class {
51313
51333
  }
51314
51334
  async list(params) {
51315
51335
  const { page, limit, offset } = this.client.resolvePagination(params);
51316
- let query = this.client.db.from("pages").select("*", { count: "exact" }).eq("site_id", this.client.siteIdNumber).is("draft_deleted_at", null).order("path");
51336
+ let query = this.client.db.from("pages").select("*", { count: "exact" }).eq("site_id", this.client.siteIdNumber).is("draft_deleted_at", null);
51337
+ query = params?.order ? query.order("created_at", { ascending: params.order === "asc" }) : query.order("path");
51317
51338
  if (params?.status)
51318
51339
  query = query.eq("status", params.status);
51319
51340
  const { data, error: error48, count } = await query.range(offset, offset + limit - 1);
@@ -52599,8 +52620,10 @@ var CollectionsEndpoint = class {
52599
52620
  get basePath() {
52600
52621
  return `${this.client.siteBasePath}/collections`;
52601
52622
  }
52602
- async list() {
52603
- const { data, error: error48 } = await this.client.db.from("collections").select("*").eq("site_id", this.client.siteIdNumber).is("draft_deleted_at", null).order("name");
52623
+ async list(params) {
52624
+ let query = this.client.db.from("collections").select("*").eq("site_id", this.client.siteIdNumber).is("draft_deleted_at", null);
52625
+ query = params?.order ? query.order("created_at", { ascending: params.order === "asc" }) : query.order("name");
52626
+ const { data, error: error48 } = await query;
52604
52627
  if (error48)
52605
52628
  throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
52606
52629
  return (data ?? []).map((r) => serializeCollection(r));
@@ -52673,7 +52696,7 @@ var EntriesEndpoint = class {
52673
52696
  }
52674
52697
  async list(collectionId, params) {
52675
52698
  const { page, limit, offset } = this.client.resolvePagination(params);
52676
- let query = this.client.db.from("entries").select("*", { count: "exact" }).eq("site_id", this.client.siteIdNumber).eq("collection_id", collectionId).is("deleted_at", null).order("created_at", { ascending: false });
52699
+ let query = this.client.db.from("entries").select("*", { count: "exact" }).eq("site_id", this.client.siteIdNumber).eq("collection_id", collectionId).is("deleted_at", null).order("created_at", { ascending: params?.order === "asc" });
52677
52700
  if (params?.status)
52678
52701
  query = query.eq("status", params.status);
52679
52702
  if (params?.locale)
@@ -52764,8 +52787,10 @@ var FormsEndpoint = class {
52764
52787
  get basePath() {
52765
52788
  return `${this.client.siteBasePath}/forms`;
52766
52789
  }
52767
- async list() {
52768
- const { data, error: error48 } = await this.client.db.from("forms").select("*").eq("site_id", this.client.siteIdNumber).is("draft_deleted_at", null).order("name");
52790
+ async list(params) {
52791
+ let query = this.client.db.from("forms").select("*").eq("site_id", this.client.siteIdNumber).is("draft_deleted_at", null);
52792
+ query = params?.order ? query.order("created_at", { ascending: params.order === "asc" }) : query.order("name");
52793
+ const { data, error: error48 } = await query;
52769
52794
  if (error48)
52770
52795
  throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
52771
52796
  const rows = data ?? [];
@@ -52844,7 +52869,7 @@ var AssetsEndpoint = class {
52844
52869
  }
52845
52870
  async list(params) {
52846
52871
  const { page, limit, offset } = this.client.resolvePagination(params);
52847
- const { data, error: error48, count } = await this.client.db.from("assets").select("*", { count: "exact" }).eq("site_id", this.client.siteIdNumber).order("created_at", { ascending: false }).range(offset, offset + limit - 1);
52872
+ const { data, error: error48, count } = await this.client.db.from("assets").select("*", { count: "exact" }).eq("site_id", this.client.siteIdNumber).order("created_at", { ascending: params?.order === "asc" }).range(offset, offset + limit - 1);
52848
52873
  if (error48)
52849
52874
  throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
52850
52875
  const rows = data ?? [];
@@ -52910,7 +52935,7 @@ var SiteEndpoint = class {
52910
52935
  constructor(client) {
52911
52936
  this.client = client;
52912
52937
  }
52913
- async list() {
52938
+ async list(params) {
52914
52939
  const profileId = this.client.authUserId;
52915
52940
  if (!profileId) {
52916
52941
  throw new NeopressApiError("NO_AUTH", "site.list requires an authenticated access token", 0);
@@ -52918,10 +52943,15 @@ var SiteEndpoint = class {
52918
52943
  const { data, error: error48 } = await this.client.db.from("sites_profiles").select("role, sites!inner(*)").eq("profile_id", profileId).eq("status", "active");
52919
52944
  if (error48)
52920
52945
  throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
52921
- return (data ?? []).map((m) => ({
52946
+ const sites = (data ?? []).map((m) => ({
52922
52947
  ...serializeSite(m.sites),
52923
52948
  role: m.role
52924
52949
  }));
52950
+ if (params?.order) {
52951
+ const dir = params.order === "asc" ? 1 : -1;
52952
+ sites.sort((a, b) => (a.createdAt ?? "") < (b.createdAt ?? "") ? -dir : (a.createdAt ?? "") > (b.createdAt ?? "") ? dir : 0);
52953
+ }
52954
+ return sites;
52925
52955
  }
52926
52956
  async get() {
52927
52957
  const { data, error: error48 } = await this.client.db.from("sites").select("*").eq("id", this.client.siteIdNumber).single();
@@ -52959,8 +52989,10 @@ var RedirectsEndpoint = class {
52959
52989
  constructor(client) {
52960
52990
  this.client = client;
52961
52991
  }
52962
- async list() {
52963
- const { data, error: error48 } = await this.client.db.from("redirect_rules").select("*").eq("site_id", this.client.siteIdNumber).order("priority", { ascending: true });
52992
+ async list(params) {
52993
+ let query = this.client.db.from("redirect_rules").select("*").eq("site_id", this.client.siteIdNumber);
52994
+ query = params?.order ? query.order("created_at", { ascending: params.order === "asc" }) : query.order("priority", { ascending: true });
52995
+ const { data, error: error48 } = await query;
52964
52996
  if (error48)
52965
52997
  throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
52966
52998
  return (data ?? []).map((r) => serializeRedirect(r));
@@ -52970,7 +53002,7 @@ var RedirectsEndpoint = class {
52970
53002
  site_id: this.client.siteIdNumber,
52971
53003
  source: data.source,
52972
53004
  destination: data.destination,
52973
- redirect_type: data.redirectType ?? 307,
53005
+ redirect_type: data.redirectType ?? 308,
52974
53006
  include_children: data.includeChildren ?? false,
52975
53007
  preserve_path: data.preservePath ?? false,
52976
53008
  enabled: data.enabled !== false,
@@ -53037,7 +53069,7 @@ var EntryReferencesEndpoint = class {
53037
53069
  query = query.eq("from_entry_id", params.fromEntryId);
53038
53070
  if (params?.toEntryId)
53039
53071
  query = query.eq("to_entry_id", params.toEntryId);
53040
- const { data, error: error48 } = await query.order("created_at", { ascending: false });
53072
+ const { data, error: error48 } = await query.order("created_at", { ascending: params?.order === "asc" });
53041
53073
  if (error48)
53042
53074
  throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
53043
53075
  return (data ?? []).map((r) => serializeEntryReference(r));
@@ -53159,18 +53191,165 @@ var TemplatesEndpoint = class {
53159
53191
  const res = await this.client.delete(this.basePath);
53160
53192
  return res.data;
53161
53193
  }
53194
+ /**
53195
+ * List templates across the sites the caller can access.
53196
+ *
53197
+ * Direct-DB: `templates` is public-read and `sites` RLS scopes the visible set
53198
+ * (own active memberships, or all sites for the super admin), so no server
53199
+ * route is needed — the two RLS-scoped queries reproduce the old handler.
53200
+ */
53162
53201
  async list(params) {
53163
- const qs = new URLSearchParams();
53164
- if (params?.namePrefix)
53165
- qs.set("namePrefix", params.namePrefix);
53166
- if (params?.industry)
53167
- qs.set("industry", params.industry);
53168
- if (params?.limit != null)
53169
- qs.set("limit", String(params.limit));
53170
- const query = qs.toString();
53171
- const path = query ? `/api/v1/templates?${query}` : "/api/v1/templates";
53172
- const res = await this.client.get(path);
53173
- return res.data;
53202
+ const { data: sitesData, error: sitesError } = await this.client.db.from("sites").select("id, handle, name");
53203
+ if (sitesError)
53204
+ throw new NeopressApiError("DB_ERROR", sitesError.message, 0, sitesError);
53205
+ const siteMeta = /* @__PURE__ */ new Map();
53206
+ for (const site of sitesData ?? []) {
53207
+ if (typeof site.id !== "number")
53208
+ continue;
53209
+ siteMeta.set(site.id, {
53210
+ handle: site.handle ?? null,
53211
+ name: site.name ?? null
53212
+ });
53213
+ }
53214
+ const siteIds = [...siteMeta.keys()];
53215
+ if (siteIds.length === 0)
53216
+ return [];
53217
+ const namePrefix = params?.namePrefix?.trim();
53218
+ const limit = Math.min(Math.max(params?.limit ?? 100, 1), 500);
53219
+ let query = this.client.db.from("templates").select("id, name, reference_url, preview_img_urls, description, created_at").in("id", siteIds);
53220
+ if (namePrefix)
53221
+ query = query.ilike("name", `${namePrefix}%`);
53222
+ if (params?.order)
53223
+ query = query.order("created_at", { ascending: params.order === "asc" });
53224
+ query = query.limit(limit);
53225
+ const { data, error: error48 } = await query;
53226
+ if (error48)
53227
+ throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
53228
+ return (data ?? []).map((t) => {
53229
+ const siteId2 = t.id;
53230
+ return {
53231
+ siteId: siteId2,
53232
+ handle: siteMeta.get(siteId2)?.handle ?? null,
53233
+ siteName: siteMeta.get(siteId2)?.name ?? null,
53234
+ name: t.name,
53235
+ referenceUrl: t.reference_url,
53236
+ previewImgUrls: t.preview_img_urls ?? null,
53237
+ description: t.description ?? null,
53238
+ createdAt: t.created_at
53239
+ };
53240
+ });
53241
+ }
53242
+ };
53243
+
53244
+ // ../sdk/dist/endpoints/headshots.js
53245
+ var HeadshotsEndpoint = class {
53246
+ client;
53247
+ constructor(client) {
53248
+ this.client = client;
53249
+ }
53250
+ async list(params) {
53251
+ const { page, limit, offset } = this.client.resolvePagination(params);
53252
+ let query = this.client.db.from("headshot_pool").select("*", { count: "exact" });
53253
+ if (params?.ageBand)
53254
+ query = query.eq("age_band", params.ageBand);
53255
+ if (params?.gender)
53256
+ query = query.eq("gender", params.gender);
53257
+ if (params?.ethnicity)
53258
+ query = query.eq("ethnicity", params.ethnicity);
53259
+ if (params?.attire)
53260
+ query = query.eq("attire", params.attire);
53261
+ if (params?.isActive !== void 0)
53262
+ query = query.eq("is_active", params.isActive);
53263
+ if (params?.order) {
53264
+ query = query.order("created_at", { ascending: params.order === "asc" });
53265
+ } else {
53266
+ query = query.order("age_band", { ascending: true }).order("gender", { ascending: true }).order("ethnicity", { ascending: true }).order("variation_index", { ascending: true });
53267
+ }
53268
+ const { data, error: error48, count } = await query.range(offset, offset + limit - 1);
53269
+ if (error48)
53270
+ throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
53271
+ return {
53272
+ data: (data ?? []).map((r) => serializeHeadshot(r)),
53273
+ pagination: this.client.paginationMeta(page, limit, offset, count ?? 0)
53274
+ };
53275
+ }
53276
+ async get(id) {
53277
+ const { data, error: error48 } = await this.client.db.from("headshot_pool").select("*").eq("id", id).single();
53278
+ if (error48)
53279
+ throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
53280
+ return serializeHeadshot(data);
53281
+ }
53282
+ async create(params) {
53283
+ const values = {
53284
+ image_url: params.imageUrl,
53285
+ age_band: params.ageBand,
53286
+ gender: params.gender,
53287
+ ethnicity: params.ethnicity,
53288
+ variation_index: params.variationIndex
53289
+ };
53290
+ if (params.attire !== void 0)
53291
+ values.attire = params.attire;
53292
+ if (params.width !== void 0)
53293
+ values.width = params.width;
53294
+ if (params.height !== void 0)
53295
+ values.height = params.height;
53296
+ if (params.aspectRatio !== void 0)
53297
+ values.aspect_ratio = params.aspectRatio;
53298
+ if (params.mimeType !== void 0)
53299
+ values.mime_type = params.mimeType;
53300
+ if (params.byteSize !== void 0)
53301
+ values.byte_size = params.byteSize;
53302
+ if (params.gptPrompt !== void 0)
53303
+ values.gpt_prompt = params.gptPrompt;
53304
+ if (params.tags !== void 0)
53305
+ values.tags = params.tags;
53306
+ if (params.isActive !== void 0)
53307
+ values.is_active = params.isActive;
53308
+ const { data, error: error48 } = await this.client.db.from("headshot_pool").insert(values).select().single();
53309
+ if (error48)
53310
+ throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
53311
+ return serializeHeadshot(data);
53312
+ }
53313
+ async update(id, params) {
53314
+ const values = {};
53315
+ if (params.imageUrl !== void 0)
53316
+ values.image_url = params.imageUrl;
53317
+ if (params.ageBand !== void 0)
53318
+ values.age_band = params.ageBand;
53319
+ if (params.gender !== void 0)
53320
+ values.gender = params.gender;
53321
+ if (params.ethnicity !== void 0)
53322
+ values.ethnicity = params.ethnicity;
53323
+ if (params.attire !== void 0)
53324
+ values.attire = params.attire;
53325
+ if (params.variationIndex !== void 0)
53326
+ values.variation_index = params.variationIndex;
53327
+ if (params.width !== void 0)
53328
+ values.width = params.width;
53329
+ if (params.height !== void 0)
53330
+ values.height = params.height;
53331
+ if (params.aspectRatio !== void 0)
53332
+ values.aspect_ratio = params.aspectRatio;
53333
+ if (params.mimeType !== void 0)
53334
+ values.mime_type = params.mimeType;
53335
+ if (params.byteSize !== void 0)
53336
+ values.byte_size = params.byteSize;
53337
+ if (params.gptPrompt !== void 0)
53338
+ values.gpt_prompt = params.gptPrompt;
53339
+ if (params.tags !== void 0)
53340
+ values.tags = params.tags;
53341
+ if (params.isActive !== void 0)
53342
+ values.is_active = params.isActive;
53343
+ const { data, error: error48 } = await this.client.db.from("headshot_pool").update(values).eq("id", id).select().single();
53344
+ if (error48)
53345
+ throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
53346
+ return serializeHeadshot(data);
53347
+ }
53348
+ async delete(id) {
53349
+ const { error: error48 } = await this.client.db.from("headshot_pool").delete().eq("id", id);
53350
+ if (error48)
53351
+ throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
53352
+ return { id, deleted: true };
53174
53353
  }
53175
53354
  };
53176
53355
 
@@ -53194,6 +53373,7 @@ var NeopressClient = class {
53194
53373
  entryReferences;
53195
53374
  analytics;
53196
53375
  templates;
53376
+ headshots;
53197
53377
  constructor(options) {
53198
53378
  this.baseUrl = (options.baseUrl || "https://app.neopress.ai").replace(/\/$/, "");
53199
53379
  this.accessToken = options.accessToken || "";
@@ -53212,6 +53392,7 @@ var NeopressClient = class {
53212
53392
  this.entryReferences = new EntryReferencesEndpoint(this);
53213
53393
  this.analytics = new AnalyticsEndpoint(this);
53214
53394
  this.templates = new TemplatesEndpoint(this);
53395
+ this.headshots = new HeadshotsEndpoint(this);
53215
53396
  }
53216
53397
  get siteBasePath() {
53217
53398
  return `/api/v1/sites/${this.siteId}`;
@@ -53492,14 +53673,15 @@ Use these rules before generating pages, collection schemas, entries, forms, or
53492
53673
 
53493
53674
  - Layout owns header, footer, global CSS, and 404. Page TSX starts at page content.
53494
53675
  - Generated page TSX is sandboxed. Do not import Supabase, create API clients, read env vars, use filesystem/process APIs, or assume arbitrary npm packages.
53495
- - Use allowed runtime packages only: React/Next basics, shadcn UI imports, lucide-react, date-fns, framer-motion, gsap (incl. \`gsap/ScrollTrigger\`, driven via \`@gsap/react\`'s \`useGSAP\`), @neopress/content, @neopress/routing, @neopress/i18n, and @neopress/forms.
53676
+ - Use allowed runtime packages only: React/Next basics, shadcn UI imports, lucide-react, @radix-ui/react-slot, @radix-ui/react-select, @neopress/youtube, @neopress/map, clsx, class-variance-authority, tailwind-merge, date-fns, framer-motion, gsap (including \`gsap/ScrollTrigger\`, driven via \`@gsap/react\`'s \`useGSAP\`), react-hook-form, zod, @hookform/resolvers, @hookform/resolvers/zod, @neopress/content, @neopress/routing, @neopress/i18n, and @neopress/forms.
53677
+ - @radix-ui/react-select is a single-value listbox/dropdown (replaces a native \`<select>\`, whose popup is unstyled OS chrome). Compose its parts directly in page TSX; every \`<Select.Item value>\` must be a non-empty string (an empty-string value throws at runtime and blanks the page \u2014 use a sentinel like \`"all"\`); use \`position="popper"\` with an explicit z-index and a non-transparent background on \`<Select.Content>\` (it portals to \`document.body\`).
53496
53678
 
53497
53679
  ## Templates
53498
53680
 
53499
53681
  - Reusable templates are normal Neopress sites marked by a \`templates\` metadata row.
53500
53682
  - \`templates.id\` equals \`sites.id\`.
53501
53683
  - Build layout, pages, collections, entries, forms, assets, compile, publish, and verify before marking a finished template.
53502
- - Use \`neopress_template_mark\` to create or update the metadata row with \`name\`, \`industry\`, required \`referenceUrl\`, required \`previewImgUrls\` (at least one), and optional \`description\`.
53684
+ - Use \`neopress_template_mark\` to create or update the metadata row with \`name\`, required \`referenceUrl\`, required \`previewImgUrls\` (at least one), and optional \`description\`.
53503
53685
  - \`referenceUrl\` is a single http(s) provenance URL. \`description\` is an optional summary of the template (max 150 characters).
53504
53686
  - Template metadata does not replace page TSX, CMS content, forms, or publish state.
53505
53687
  - Use \`neopress_template_delete\` only for explicit template-site hard deletion. It removes the metadata row and connected site.
@@ -53509,6 +53691,7 @@ Use these rules before generating pages, collection schemas, entries, forms, or
53509
53691
  - Dynamic pages require a collection, a page path like \`/blog/[slug]\`, a numeric \`collectionId\`, matching entries, entry publish, page compile, and site publish.
53510
53692
  - \`queryConfig\` is stored in page \`draftMeta.queryConfig\`.
53511
53693
  - Query labels become React props. Entry query results are flattened, so use \`post.body\` instead of \`post.data.body\`.
53694
+ - Initial CMS data arrives through those injected query props. \`entryClient\`, when injected in reader/preview for a site handle, is only a client-side auxiliary for load-more/filter/get/create interactions after the initial render; do not use it for initial render or server data loading.
53512
53695
  - Use numeric \`collection_id\` filters. Runtime controls site, status, locale, deleted state, and published snapshots.
53513
53696
 
53514
53697
  ## Collections and entries
@@ -53522,11 +53705,13 @@ Use these rules before generating pages, collection schemas, entries, forms, or
53522
53705
 
53523
53706
  - Reference fields require a schema field with \`type: "references"\` and target \`collection_id\`.
53524
53707
  - Links live in \`entry_references\`, not only in raw entry \`data\`.
53708
+ - \`includeReferences\` fetches arrays keyed by the includeReferences alias or field key, and parent entry \`id\` must be selected. With an alias, the alias prop remains an array of referenced entries. Without an alias, if the field key matches a raw numeric reference field in \`entry.data\`, flattening unwraps that array to one flattened object or null.
53525
53709
  - After changing references, publish the source entry again.
53526
53710
 
53527
53711
  ## Forms
53528
53712
 
53529
53713
  - Render forms with \`NeopressForm\` from \`@neopress/forms\` and the injected \`formClient\` prop.
53714
+ - In page TSX, \`formId\` may be a numeric literal or numeric string so schemas can be injected before compile.
53530
53715
  - Do not manually submit form data with \`fetch\` or \`FormData\`.
53531
53716
  - Create/update the form, publish the form, compile the page, then publish the site.
53532
53717
 
@@ -53844,7 +54029,6 @@ var toolDefinitions = [
53844
54029
  ...siteIdShape,
53845
54030
  name: external_exports3.string(),
53846
54031
  description: external_exports3.string().max(150).optional(),
53847
- industry: external_exports3.string(),
53848
54032
  referenceUrl: httpUrlSchema,
53849
54033
  previewImgUrls: external_exports3.array(external_exports3.string()).min(1)
53850
54034
  },
@@ -53853,7 +54037,6 @@ var toolDefinitions = [
53853
54037
  return client.templates.mark({
53854
54038
  name: asString(input, "name"),
53855
54039
  description: asOptionalString(input, "description"),
53856
- industry: asString(input, "industry"),
53857
54040
  referenceUrl: asString(input, "referenceUrl"),
53858
54041
  previewImgUrls: input.previewImgUrls
53859
54042
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neopress/mcp",
3
- "version": "1.0.0",
3
+ "version": "1.1.1",
4
4
  "description": "Neopress MCP server for first-party AI agents",
5
5
  "type": "module",
6
6
  "bin": {