@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 +213 -30
- package/dist/http-bin.cjs +213 -30
- package/dist/index.js +213 -30
- package/package.json +1 -1
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
|
|
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)
|
|
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
|
-
|
|
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:
|
|
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
|
-
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
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 ??
|
|
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:
|
|
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
|
|
53256
|
-
if (
|
|
53257
|
-
|
|
53258
|
-
|
|
53259
|
-
|
|
53260
|
-
|
|
53261
|
-
|
|
53262
|
-
|
|
53263
|
-
|
|
53264
|
-
|
|
53265
|
-
|
|
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 (
|
|
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\`,
|
|
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
|
|
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)
|
|
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
|
-
|
|
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:
|
|
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
|
-
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
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 ??
|
|
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:
|
|
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
|
|
54494
|
-
if (
|
|
54495
|
-
|
|
54496
|
-
|
|
54497
|
-
|
|
54498
|
-
|
|
54499
|
-
|
|
54500
|
-
|
|
54501
|
-
|
|
54502
|
-
|
|
54503
|
-
|
|
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 (
|
|
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\`,
|
|
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
|
|
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)
|
|
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
|
-
|
|
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:
|
|
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
|
-
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
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 ??
|
|
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:
|
|
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
|
|
53164
|
-
if (
|
|
53165
|
-
|
|
53166
|
-
|
|
53167
|
-
|
|
53168
|
-
|
|
53169
|
-
|
|
53170
|
-
|
|
53171
|
-
|
|
53172
|
-
|
|
53173
|
-
|
|
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 (
|
|
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\`,
|
|
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
|
});
|