@neopress/cli 4.2.0 → 4.3.0
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 +113 -45
- package/dist/index.js +80 -24
- package/package.json +1 -1
package/dist/bin.cjs
CHANGED
|
@@ -24998,7 +24998,8 @@ var PagesEndpoint = class {
|
|
|
24998
24998
|
}
|
|
24999
24999
|
async list(params) {
|
|
25000
25000
|
const { page, limit, offset } = this.client.resolvePagination(params);
|
|
25001
|
-
let query = this.client.db.from("pages").select("*", { count: "exact" }).eq("site_id", this.client.siteIdNumber).is("draft_deleted_at", null)
|
|
25001
|
+
let query = this.client.db.from("pages").select("*", { count: "exact" }).eq("site_id", this.client.siteIdNumber).is("draft_deleted_at", null);
|
|
25002
|
+
query = params?.order ? query.order("created_at", { ascending: params.order === "asc" }) : query.order("path");
|
|
25002
25003
|
if (params?.status)
|
|
25003
25004
|
query = query.eq("status", params.status);
|
|
25004
25005
|
const { data, error: error48, count } = await query.range(offset, offset + limit - 1);
|
|
@@ -40052,8 +40053,10 @@ var CollectionsEndpoint = class {
|
|
|
40052
40053
|
get basePath() {
|
|
40053
40054
|
return `${this.client.siteBasePath}/collections`;
|
|
40054
40055
|
}
|
|
40055
|
-
async list() {
|
|
40056
|
-
|
|
40056
|
+
async list(params) {
|
|
40057
|
+
let query = this.client.db.from("collections").select("*").eq("site_id", this.client.siteIdNumber).is("draft_deleted_at", null);
|
|
40058
|
+
query = params?.order ? query.order("created_at", { ascending: params.order === "asc" }) : query.order("name");
|
|
40059
|
+
const { data, error: error48 } = await query;
|
|
40057
40060
|
if (error48)
|
|
40058
40061
|
throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
|
|
40059
40062
|
return (data ?? []).map((r) => serializeCollection(r));
|
|
@@ -40126,7 +40129,7 @@ var EntriesEndpoint = class {
|
|
|
40126
40129
|
}
|
|
40127
40130
|
async list(collectionId, params) {
|
|
40128
40131
|
const { page, limit, offset } = this.client.resolvePagination(params);
|
|
40129
|
-
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:
|
|
40132
|
+
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" });
|
|
40130
40133
|
if (params?.status)
|
|
40131
40134
|
query = query.eq("status", params.status);
|
|
40132
40135
|
if (params?.locale)
|
|
@@ -40217,8 +40220,10 @@ var FormsEndpoint = class {
|
|
|
40217
40220
|
get basePath() {
|
|
40218
40221
|
return `${this.client.siteBasePath}/forms`;
|
|
40219
40222
|
}
|
|
40220
|
-
async list() {
|
|
40221
|
-
|
|
40223
|
+
async list(params) {
|
|
40224
|
+
let query = this.client.db.from("forms").select("*").eq("site_id", this.client.siteIdNumber).is("draft_deleted_at", null);
|
|
40225
|
+
query = params?.order ? query.order("created_at", { ascending: params.order === "asc" }) : query.order("name");
|
|
40226
|
+
const { data, error: error48 } = await query;
|
|
40222
40227
|
if (error48)
|
|
40223
40228
|
throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
|
|
40224
40229
|
const rows = data ?? [];
|
|
@@ -40297,7 +40302,7 @@ var AssetsEndpoint = class {
|
|
|
40297
40302
|
}
|
|
40298
40303
|
async list(params) {
|
|
40299
40304
|
const { page, limit, offset } = this.client.resolvePagination(params);
|
|
40300
|
-
const { data, error: error48, count } = await this.client.db.from("assets").select("*", { count: "exact" }).eq("site_id", this.client.siteIdNumber).order("created_at", { ascending:
|
|
40305
|
+
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);
|
|
40301
40306
|
if (error48)
|
|
40302
40307
|
throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
|
|
40303
40308
|
const rows = data ?? [];
|
|
@@ -40363,7 +40368,7 @@ var SiteEndpoint = class {
|
|
|
40363
40368
|
constructor(client) {
|
|
40364
40369
|
this.client = client;
|
|
40365
40370
|
}
|
|
40366
|
-
async list() {
|
|
40371
|
+
async list(params) {
|
|
40367
40372
|
const profileId = this.client.authUserId;
|
|
40368
40373
|
if (!profileId) {
|
|
40369
40374
|
throw new NeopressApiError("NO_AUTH", "site.list requires an authenticated access token", 0);
|
|
@@ -40371,10 +40376,15 @@ var SiteEndpoint = class {
|
|
|
40371
40376
|
const { data, error: error48 } = await this.client.db.from("sites_profiles").select("role, sites!inner(*)").eq("profile_id", profileId).eq("status", "active");
|
|
40372
40377
|
if (error48)
|
|
40373
40378
|
throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
|
|
40374
|
-
|
|
40379
|
+
const sites = (data ?? []).map((m) => ({
|
|
40375
40380
|
...serializeSite(m.sites),
|
|
40376
40381
|
role: m.role
|
|
40377
40382
|
}));
|
|
40383
|
+
if (params?.order) {
|
|
40384
|
+
const dir = params.order === "asc" ? 1 : -1;
|
|
40385
|
+
sites.sort((a, b) => (a.createdAt ?? "") < (b.createdAt ?? "") ? -dir : (a.createdAt ?? "") > (b.createdAt ?? "") ? dir : 0);
|
|
40386
|
+
}
|
|
40387
|
+
return sites;
|
|
40378
40388
|
}
|
|
40379
40389
|
async get() {
|
|
40380
40390
|
const { data, error: error48 } = await this.client.db.from("sites").select("*").eq("id", this.client.siteIdNumber).single();
|
|
@@ -40412,8 +40422,10 @@ var RedirectsEndpoint = class {
|
|
|
40412
40422
|
constructor(client) {
|
|
40413
40423
|
this.client = client;
|
|
40414
40424
|
}
|
|
40415
|
-
async list() {
|
|
40416
|
-
|
|
40425
|
+
async list(params) {
|
|
40426
|
+
let query = this.client.db.from("redirect_rules").select("*").eq("site_id", this.client.siteIdNumber);
|
|
40427
|
+
query = params?.order ? query.order("created_at", { ascending: params.order === "asc" }) : query.order("priority", { ascending: true });
|
|
40428
|
+
const { data, error: error48 } = await query;
|
|
40417
40429
|
if (error48)
|
|
40418
40430
|
throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
|
|
40419
40431
|
return (data ?? []).map((r) => serializeRedirect(r));
|
|
@@ -40490,7 +40502,7 @@ var EntryReferencesEndpoint = class {
|
|
|
40490
40502
|
query = query.eq("from_entry_id", params.fromEntryId);
|
|
40491
40503
|
if (params?.toEntryId)
|
|
40492
40504
|
query = query.eq("to_entry_id", params.toEntryId);
|
|
40493
|
-
const { data, error: error48 } = await query.order("created_at", { ascending:
|
|
40505
|
+
const { data, error: error48 } = await query.order("created_at", { ascending: params?.order === "asc" });
|
|
40494
40506
|
if (error48)
|
|
40495
40507
|
throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
|
|
40496
40508
|
return (data ?? []).map((r) => serializeEntryReference(r));
|
|
@@ -40612,18 +40624,57 @@ var TemplatesEndpoint = class {
|
|
|
40612
40624
|
const res = await this.client.delete(this.basePath);
|
|
40613
40625
|
return res.data;
|
|
40614
40626
|
}
|
|
40627
|
+
/**
|
|
40628
|
+
* List templates across the sites the caller can access.
|
|
40629
|
+
*
|
|
40630
|
+
* Direct-DB: `templates` is public-read and `sites` RLS scopes the visible set
|
|
40631
|
+
* (own active memberships, or all sites for the super admin), so no server
|
|
40632
|
+
* route is needed — the two RLS-scoped queries reproduce the old handler.
|
|
40633
|
+
*/
|
|
40615
40634
|
async list(params) {
|
|
40616
|
-
const
|
|
40617
|
-
if (
|
|
40618
|
-
|
|
40619
|
-
|
|
40620
|
-
|
|
40621
|
-
|
|
40622
|
-
|
|
40623
|
-
|
|
40624
|
-
|
|
40625
|
-
|
|
40626
|
-
|
|
40635
|
+
const { data: sitesData, error: sitesError } = await this.client.db.from("sites").select("id, handle, name");
|
|
40636
|
+
if (sitesError)
|
|
40637
|
+
throw new NeopressApiError("DB_ERROR", sitesError.message, 0, sitesError);
|
|
40638
|
+
const siteMeta = /* @__PURE__ */ new Map();
|
|
40639
|
+
for (const site of sitesData ?? []) {
|
|
40640
|
+
if (typeof site.id !== "number")
|
|
40641
|
+
continue;
|
|
40642
|
+
siteMeta.set(site.id, {
|
|
40643
|
+
handle: site.handle ?? null,
|
|
40644
|
+
name: site.name ?? null
|
|
40645
|
+
});
|
|
40646
|
+
}
|
|
40647
|
+
const siteIds = [...siteMeta.keys()];
|
|
40648
|
+
if (siteIds.length === 0)
|
|
40649
|
+
return [];
|
|
40650
|
+
const namePrefix = params?.namePrefix?.trim();
|
|
40651
|
+
const industry = params?.industry?.trim();
|
|
40652
|
+
const limit = Math.min(Math.max(params?.limit ?? 100, 1), 500);
|
|
40653
|
+
let query = this.client.db.from("templates").select("id, name, industry, reference_url, preview_img_urls, description, created_at").in("id", siteIds);
|
|
40654
|
+
if (namePrefix)
|
|
40655
|
+
query = query.ilike("name", `${namePrefix}%`);
|
|
40656
|
+
if (industry)
|
|
40657
|
+
query = query.eq("industry", industry);
|
|
40658
|
+
if (params?.order)
|
|
40659
|
+
query = query.order("created_at", { ascending: params.order === "asc" });
|
|
40660
|
+
query = query.limit(limit);
|
|
40661
|
+
const { data, error: error48 } = await query;
|
|
40662
|
+
if (error48)
|
|
40663
|
+
throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
|
|
40664
|
+
return (data ?? []).map((t) => {
|
|
40665
|
+
const siteId = t.id;
|
|
40666
|
+
return {
|
|
40667
|
+
siteId,
|
|
40668
|
+
handle: siteMeta.get(siteId)?.handle ?? null,
|
|
40669
|
+
siteName: siteMeta.get(siteId)?.name ?? null,
|
|
40670
|
+
name: t.name,
|
|
40671
|
+
industry: t.industry,
|
|
40672
|
+
referenceUrl: t.reference_url,
|
|
40673
|
+
previewImgUrls: t.preview_img_urls ?? null,
|
|
40674
|
+
description: t.description ?? null,
|
|
40675
|
+
createdAt: t.created_at
|
|
40676
|
+
};
|
|
40677
|
+
});
|
|
40627
40678
|
}
|
|
40628
40679
|
};
|
|
40629
40680
|
|
|
@@ -40646,7 +40697,12 @@ var HeadshotsEndpoint = class {
|
|
|
40646
40697
|
query = query.eq("attire", params.attire);
|
|
40647
40698
|
if (params?.isActive !== void 0)
|
|
40648
40699
|
query = query.eq("is_active", params.isActive);
|
|
40649
|
-
|
|
40700
|
+
if (params?.order) {
|
|
40701
|
+
query = query.order("created_at", { ascending: params.order === "asc" });
|
|
40702
|
+
} else {
|
|
40703
|
+
query = query.order("age_band", { ascending: true }).order("gender", { ascending: true }).order("ethnicity", { ascending: true }).order("variation_index", { ascending: true });
|
|
40704
|
+
}
|
|
40705
|
+
const { data, error: error48, count } = await query.range(offset, offset + limit - 1);
|
|
40650
40706
|
if (error48)
|
|
40651
40707
|
throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
|
|
40652
40708
|
return {
|
|
@@ -40912,6 +40968,16 @@ async function getGlobalClientAsync() {
|
|
|
40912
40968
|
return new NeopressClient({ accessToken: token, siteId: 0, baseUrl: getBaseUrl(), supabaseUrl: sb.url, supabaseAnonKey: sb.anonKey });
|
|
40913
40969
|
}
|
|
40914
40970
|
|
|
40971
|
+
// src/utils/order.ts
|
|
40972
|
+
function parseOrder(value) {
|
|
40973
|
+
if (value === void 0) return void 0;
|
|
40974
|
+
if (value !== "asc" && value !== "desc") {
|
|
40975
|
+
fail(`Invalid --order value "${value}". Use "asc" or "desc".`);
|
|
40976
|
+
}
|
|
40977
|
+
return value;
|
|
40978
|
+
}
|
|
40979
|
+
var ORDER_OPTION_DESC = "Sort by created_at (asc or desc)";
|
|
40980
|
+
|
|
40915
40981
|
// src/commands/sites.ts
|
|
40916
40982
|
function registerSiteCommands(program3) {
|
|
40917
40983
|
const sites = program3.command("sites").description("Manage sites").addHelpText("after", `
|
|
@@ -40922,9 +40988,9 @@ Examples:
|
|
|
40922
40988
|
$ neopress sites use my-site
|
|
40923
40989
|
$ neopress sites current
|
|
40924
40990
|
Run \`sites use <id|handle>\` to set the global active site, or \`sites create --pin\` to scope a site to the current directory. \`sites current\` shows which site commands will target and why.`);
|
|
40925
|
-
sites.command("list").description("List accessible sites").action(async () => {
|
|
40991
|
+
sites.command("list").description("List accessible sites").option("--order <asc|desc>", ORDER_OPTION_DESC).action(async (options) => {
|
|
40926
40992
|
const client = await getGlobalClientAsync();
|
|
40927
|
-
const sitesList = await client.site.list();
|
|
40993
|
+
const sitesList = await client.site.list({ order: parseOrder(options.order) });
|
|
40928
40994
|
output(sitesList);
|
|
40929
40995
|
});
|
|
40930
40996
|
sites.command("use <siteIdOrHandle>").description("Set active site (ID or handle)").addHelpText("after", `
|
|
@@ -41078,10 +41144,11 @@ Examples:
|
|
|
41078
41144
|
$ neopress pages compile <pageId>
|
|
41079
41145
|
|
|
41080
41146
|
Draft content fields (--tsx/--i18n/--draft-meta) need \`neopress publish\` to go live. \`pages delete\` is a soft delete.`);
|
|
41081
|
-
pages.command("list").description("List pages").option("--status <status>", "Filter by status (draft/published)").option("--page <n>", "Page number", "1").option("--limit <n>", "Results per page", "20").action(async (options) => {
|
|
41147
|
+
pages.command("list").description("List pages").option("--status <status>", "Filter by status (draft/published)").option("--order <asc|desc>", ORDER_OPTION_DESC).option("--page <n>", "Page number", "1").option("--limit <n>", "Results per page", "20").action(async (options) => {
|
|
41082
41148
|
const client = await getClientAsync();
|
|
41083
41149
|
const res = await client.pages.list({
|
|
41084
41150
|
status: options.status,
|
|
41151
|
+
order: parseOrder(options.order),
|
|
41085
41152
|
page: parseInt(options.page, 10),
|
|
41086
41153
|
limit: parseInt(options.limit, 10)
|
|
41087
41154
|
});
|
|
@@ -41178,9 +41245,9 @@ Examples:
|
|
|
41178
41245
|
$ neopress collections update 12 --schema @schema.json
|
|
41179
41246
|
|
|
41180
41247
|
Collections are identified by numeric id, never name. delete is a soft delete \u2014 the collection is hidden from list/get but its row is retained.`);
|
|
41181
|
-
collections.command("list").description("List collections").action(async () => {
|
|
41248
|
+
collections.command("list").description("List collections").option("--order <asc|desc>", ORDER_OPTION_DESC).action(async (options) => {
|
|
41182
41249
|
const client = await getClientAsync();
|
|
41183
|
-
const data = await client.collections.list();
|
|
41250
|
+
const data = await client.collections.list({ order: parseOrder(options.order) });
|
|
41184
41251
|
output(data);
|
|
41185
41252
|
});
|
|
41186
41253
|
collections.command("get <collectionId>").description("Get collection details").action(async (collectionId) => {
|
|
@@ -41238,11 +41305,12 @@ Examples:
|
|
|
41238
41305
|
$ neopress entries publish <entryId>
|
|
41239
41306
|
|
|
41240
41307
|
Entries are created as drafts \u2014 run \`neopress entries publish <entryId>\` to make them live. create/update/delete revalidate the reader cache; delete is a soft delete.`);
|
|
41241
|
-
entries.command("list").description("List entries in a collection").requiredOption("--collection <id>", "Collection ID").option("--status <status>", "Filter by status").option("--locale <locale>", "Filter by locale").option("--page <n>", "Page number", "1").option("--limit <n>", "Results per page", "20").action(async (options) => {
|
|
41308
|
+
entries.command("list").description("List entries in a collection").requiredOption("--collection <id>", "Collection ID").option("--status <status>", "Filter by status").option("--locale <locale>", "Filter by locale").option("--order <asc|desc>", ORDER_OPTION_DESC).option("--page <n>", "Page number", "1").option("--limit <n>", "Results per page", "20").action(async (options) => {
|
|
41242
41309
|
const client = await getClientAsync();
|
|
41243
41310
|
const res = await client.entries.list(parseInt(options.collection, 10), {
|
|
41244
41311
|
status: options.status,
|
|
41245
41312
|
locale: options.locale,
|
|
41313
|
+
order: parseOrder(options.order),
|
|
41246
41314
|
page: parseInt(options.page, 10),
|
|
41247
41315
|
limit: parseInt(options.limit, 10)
|
|
41248
41316
|
});
|
|
@@ -41332,9 +41400,9 @@ Examples:
|
|
|
41332
41400
|
$ neopress forms publish <formId>
|
|
41333
41401
|
$ neopress forms responses <formId> --limit 50
|
|
41334
41402
|
Forms are created as drafts \u2014 run \`neopress forms publish <formId>\` to make them live. JSON options take inline JSON or @file.`);
|
|
41335
|
-
forms.command("list").description("List forms").action(async () => {
|
|
41403
|
+
forms.command("list").description("List forms").option("--order <asc|desc>", ORDER_OPTION_DESC).action(async (options) => {
|
|
41336
41404
|
const client = await getClientAsync();
|
|
41337
|
-
const data = await client.forms.list();
|
|
41405
|
+
const data = await client.forms.list({ order: parseOrder(options.order) });
|
|
41338
41406
|
output(data);
|
|
41339
41407
|
});
|
|
41340
41408
|
forms.command("get <formId>").description("Get form details").action(async (formId) => {
|
|
@@ -41414,9 +41482,10 @@ Examples:
|
|
|
41414
41482
|
$ neopress assets upload ./hero.png --folder images
|
|
41415
41483
|
$ neopress assets list --limit 50
|
|
41416
41484
|
Upload runs presign \u2192 PUT to storage \u2192 register in one step; content type is inferred from the file extension.`);
|
|
41417
|
-
assets.command("list").description("List assets").option("--page <n>", "Page number", "1").option("--limit <n>", "Results per page", "20").action(async (options) => {
|
|
41485
|
+
assets.command("list").description("List assets").option("--order <asc|desc>", ORDER_OPTION_DESC).option("--page <n>", "Page number", "1").option("--limit <n>", "Results per page", "20").action(async (options) => {
|
|
41418
41486
|
const client = await getClientAsync();
|
|
41419
41487
|
const res = await client.assets.list({
|
|
41488
|
+
order: parseOrder(options.order),
|
|
41420
41489
|
page: parseInt(options.page, 10),
|
|
41421
41490
|
limit: parseInt(options.limit, 10)
|
|
41422
41491
|
});
|
|
@@ -41499,9 +41568,9 @@ Examples:
|
|
|
41499
41568
|
$ neopress redirects create --source /docs --dest /guide --type 308
|
|
41500
41569
|
$ neopress redirects list
|
|
41501
41570
|
Rules are created enabled. delete <ruleId> removes a rule permanently.`);
|
|
41502
|
-
redirects.command("list").description("List redirect rules").action(async () => {
|
|
41571
|
+
redirects.command("list").description("List redirect rules").option("--order <asc|desc>", `${ORDER_OPTION_DESC} (default sort: priority)`).action(async (options) => {
|
|
41503
41572
|
const client = await getClientAsync();
|
|
41504
|
-
const data = await client.redirects.list();
|
|
41573
|
+
const data = await client.redirects.list({ order: parseOrder(options.order) });
|
|
41505
41574
|
output(data);
|
|
41506
41575
|
});
|
|
41507
41576
|
redirects.command("create").description("Create a redirect rule").addHelpText("after", `
|
|
@@ -41564,11 +41633,12 @@ Examples:
|
|
|
41564
41633
|
$ neopress entry-references list --from-entry 12
|
|
41565
41634
|
$ neopress entry-references delete <referenceId>
|
|
41566
41635
|
--field is a reference field key from the source entry's collection schema. delete is a hard delete and removes the relation immediately.`);
|
|
41567
|
-
refs.command("list").description("List entry references").option("--from-entry <id>", "Filter by source entry ID").option("--to-entry <id>", "Filter by target entry ID").action(async (options) => {
|
|
41636
|
+
refs.command("list").description("List entry references").option("--from-entry <id>", "Filter by source entry ID").option("--to-entry <id>", "Filter by target entry ID").option("--order <asc|desc>", ORDER_OPTION_DESC).action(async (options) => {
|
|
41568
41637
|
const client = await getClientAsync();
|
|
41569
41638
|
const data = await client.entryReferences.list({
|
|
41570
41639
|
fromEntryId: options.fromEntry ? parseInt(options.fromEntry, 10) : void 0,
|
|
41571
|
-
toEntryId: options.toEntry ? parseInt(options.toEntry, 10) : void 0
|
|
41640
|
+
toEntryId: options.toEntry ? parseInt(options.toEntry, 10) : void 0,
|
|
41641
|
+
order: parseOrder(options.order)
|
|
41572
41642
|
});
|
|
41573
41643
|
output(data);
|
|
41574
41644
|
});
|
|
@@ -41730,15 +41800,12 @@ Examples:
|
|
|
41730
41800
|
$ neopress templates list --industry saas --limit 50
|
|
41731
41801
|
$ neopress templates delete
|
|
41732
41802
|
\`templates mark\` operates on the active site. \`templates delete\` permanently removes the template metadata AND the connected site \u2014 it is destructive and not recoverable.`);
|
|
41733
|
-
templates.command("list").description("List templates across sites you can access").option("--name-prefix <prefix>", "Filter by template name prefix").option("--industry <industry>", "Filter by industry key").option("--limit <n>", "Max results (default 100, max 500)").action(async (options) => {
|
|
41734
|
-
const
|
|
41735
|
-
if (!token) {
|
|
41736
|
-
fail("Not authenticated. Run `neopress login`.");
|
|
41737
|
-
}
|
|
41738
|
-
const client = new NeopressClient({ accessToken: token, siteId: 0, baseUrl: getBaseUrl() });
|
|
41803
|
+
templates.command("list").description("List templates across sites you can access").option("--name-prefix <prefix>", "Filter by template name prefix").option("--industry <industry>", "Filter by industry key").option("--order <asc|desc>", ORDER_OPTION_DESC).option("--limit <n>", "Max results (default 100, max 500)").action(async (options) => {
|
|
41804
|
+
const client = await getGlobalClientAsync();
|
|
41739
41805
|
const templates2 = await client.templates.list({
|
|
41740
41806
|
namePrefix: options.namePrefix,
|
|
41741
41807
|
industry: options.industry,
|
|
41808
|
+
order: parseOrder(options.order),
|
|
41742
41809
|
limit: options.limit ? parseInt(options.limit, 10) : void 0
|
|
41743
41810
|
});
|
|
41744
41811
|
output(templates2);
|
|
@@ -41803,7 +41870,7 @@ Examples:
|
|
|
41803
41870
|
$ neopress headshots create --image-url https://cdn/x.webp --age-band young --gender male --ethnicity white --variation-index 0
|
|
41804
41871
|
$ neopress headshots update 12 --inactive
|
|
41805
41872
|
The pool is global and RLS-gated: only the super-admin account can read or write it. No active site is needed.`);
|
|
41806
|
-
headshots.command("list").description("List headshot pool entries").option("--age-band <band>", `Filter by age band (${AGE_BANDS.join("/")})`).option("--gender <gender>", `Filter by gender (${GENDERS.join("/")})`).option("--ethnicity <ethnicity>", `Filter by ethnicity (${ETHNICITIES.join("/")})`).option("--attire <attire>", `Filter by attire (${ATTIRES.join("/")})`).option("--active", "Only active entries").option("--inactive", "Only inactive entries").option("--page <n>", "Page number", "1").option("--limit <n>", "Results per page", "20").addHelpText("after", `
|
|
41873
|
+
headshots.command("list").description("List headshot pool entries").option("--age-band <band>", `Filter by age band (${AGE_BANDS.join("/")})`).option("--gender <gender>", `Filter by gender (${GENDERS.join("/")})`).option("--ethnicity <ethnicity>", `Filter by ethnicity (${ETHNICITIES.join("/")})`).option("--attire <attire>", `Filter by attire (${ATTIRES.join("/")})`).option("--active", "Only active entries").option("--inactive", "Only inactive entries").option("--order <asc|desc>", ORDER_OPTION_DESC).option("--page <n>", "Page number", "1").option("--limit <n>", "Results per page", "20").addHelpText("after", `
|
|
41807
41874
|
Examples:
|
|
41808
41875
|
$ neopress headshots list
|
|
41809
41876
|
$ neopress headshots list --gender female --age-band middle --active
|
|
@@ -41818,6 +41885,7 @@ Filters are equality matches on the pool's demographic columns; results are pagi
|
|
|
41818
41885
|
const params = {
|
|
41819
41886
|
page: parseInt(options.page, 10),
|
|
41820
41887
|
limit: parseInt(options.limit, 10),
|
|
41888
|
+
order: parseOrder(options.order),
|
|
41821
41889
|
ageBand: options.ageBand,
|
|
41822
41890
|
gender: options.gender,
|
|
41823
41891
|
ethnicity: options.ethnicity,
|
|
@@ -41997,7 +42065,7 @@ function registerGuideCommands(program3) {
|
|
|
41997
42065
|
|
|
41998
42066
|
// src/bin.ts
|
|
41999
42067
|
var program2 = new Command();
|
|
42000
|
-
program2.name("neopress").description("Neopress CLI \u2014 manage your site from the terminal").version("4.
|
|
42068
|
+
program2.name("neopress").description("Neopress CLI \u2014 manage your site from the terminal").version("4.3.0").option("--json", "Output in JSON format (for AI tools and pipes)").option("--site <idOrHandle>", "Target a specific site (overrides active site; not persisted)").option("--no-input", "Non-interactive mode").hook("preAction", (thisCommand) => {
|
|
42001
42069
|
const opts = thisCommand.optsWithGlobals();
|
|
42002
42070
|
if (opts.site) setSiteOverride(String(opts.site));
|
|
42003
42071
|
if (opts.json || !process.stdout.isTTY) setJsonMode(true);
|
package/dist/index.js
CHANGED
|
@@ -21220,7 +21220,8 @@ var PagesEndpoint = class {
|
|
|
21220
21220
|
}
|
|
21221
21221
|
async list(params) {
|
|
21222
21222
|
const { page, limit, offset } = this.client.resolvePagination(params);
|
|
21223
|
-
let query = this.client.db.from("pages").select("*", { count: "exact" }).eq("site_id", this.client.siteIdNumber).is("draft_deleted_at", null)
|
|
21223
|
+
let query = this.client.db.from("pages").select("*", { count: "exact" }).eq("site_id", this.client.siteIdNumber).is("draft_deleted_at", null);
|
|
21224
|
+
query = params?.order ? query.order("created_at", { ascending: params.order === "asc" }) : query.order("path");
|
|
21224
21225
|
if (params?.status)
|
|
21225
21226
|
query = query.eq("status", params.status);
|
|
21226
21227
|
const { data, error: error48, count } = await query.range(offset, offset + limit - 1);
|
|
@@ -36274,8 +36275,10 @@ var CollectionsEndpoint = class {
|
|
|
36274
36275
|
get basePath() {
|
|
36275
36276
|
return `${this.client.siteBasePath}/collections`;
|
|
36276
36277
|
}
|
|
36277
|
-
async list() {
|
|
36278
|
-
|
|
36278
|
+
async list(params) {
|
|
36279
|
+
let query = this.client.db.from("collections").select("*").eq("site_id", this.client.siteIdNumber).is("draft_deleted_at", null);
|
|
36280
|
+
query = params?.order ? query.order("created_at", { ascending: params.order === "asc" }) : query.order("name");
|
|
36281
|
+
const { data, error: error48 } = await query;
|
|
36279
36282
|
if (error48)
|
|
36280
36283
|
throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
|
|
36281
36284
|
return (data ?? []).map((r) => serializeCollection(r));
|
|
@@ -36348,7 +36351,7 @@ var EntriesEndpoint = class {
|
|
|
36348
36351
|
}
|
|
36349
36352
|
async list(collectionId, params) {
|
|
36350
36353
|
const { page, limit, offset } = this.client.resolvePagination(params);
|
|
36351
|
-
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:
|
|
36354
|
+
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" });
|
|
36352
36355
|
if (params?.status)
|
|
36353
36356
|
query = query.eq("status", params.status);
|
|
36354
36357
|
if (params?.locale)
|
|
@@ -36439,8 +36442,10 @@ var FormsEndpoint = class {
|
|
|
36439
36442
|
get basePath() {
|
|
36440
36443
|
return `${this.client.siteBasePath}/forms`;
|
|
36441
36444
|
}
|
|
36442
|
-
async list() {
|
|
36443
|
-
|
|
36445
|
+
async list(params) {
|
|
36446
|
+
let query = this.client.db.from("forms").select("*").eq("site_id", this.client.siteIdNumber).is("draft_deleted_at", null);
|
|
36447
|
+
query = params?.order ? query.order("created_at", { ascending: params.order === "asc" }) : query.order("name");
|
|
36448
|
+
const { data, error: error48 } = await query;
|
|
36444
36449
|
if (error48)
|
|
36445
36450
|
throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
|
|
36446
36451
|
const rows = data ?? [];
|
|
@@ -36519,7 +36524,7 @@ var AssetsEndpoint = class {
|
|
|
36519
36524
|
}
|
|
36520
36525
|
async list(params) {
|
|
36521
36526
|
const { page, limit, offset } = this.client.resolvePagination(params);
|
|
36522
|
-
const { data, error: error48, count } = await this.client.db.from("assets").select("*", { count: "exact" }).eq("site_id", this.client.siteIdNumber).order("created_at", { ascending:
|
|
36527
|
+
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);
|
|
36523
36528
|
if (error48)
|
|
36524
36529
|
throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
|
|
36525
36530
|
const rows = data ?? [];
|
|
@@ -36585,7 +36590,7 @@ var SiteEndpoint = class {
|
|
|
36585
36590
|
constructor(client) {
|
|
36586
36591
|
this.client = client;
|
|
36587
36592
|
}
|
|
36588
|
-
async list() {
|
|
36593
|
+
async list(params) {
|
|
36589
36594
|
const profileId = this.client.authUserId;
|
|
36590
36595
|
if (!profileId) {
|
|
36591
36596
|
throw new NeopressApiError("NO_AUTH", "site.list requires an authenticated access token", 0);
|
|
@@ -36593,10 +36598,15 @@ var SiteEndpoint = class {
|
|
|
36593
36598
|
const { data, error: error48 } = await this.client.db.from("sites_profiles").select("role, sites!inner(*)").eq("profile_id", profileId).eq("status", "active");
|
|
36594
36599
|
if (error48)
|
|
36595
36600
|
throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
|
|
36596
|
-
|
|
36601
|
+
const sites = (data ?? []).map((m) => ({
|
|
36597
36602
|
...serializeSite(m.sites),
|
|
36598
36603
|
role: m.role
|
|
36599
36604
|
}));
|
|
36605
|
+
if (params?.order) {
|
|
36606
|
+
const dir = params.order === "asc" ? 1 : -1;
|
|
36607
|
+
sites.sort((a, b) => (a.createdAt ?? "") < (b.createdAt ?? "") ? -dir : (a.createdAt ?? "") > (b.createdAt ?? "") ? dir : 0);
|
|
36608
|
+
}
|
|
36609
|
+
return sites;
|
|
36600
36610
|
}
|
|
36601
36611
|
async get() {
|
|
36602
36612
|
const { data, error: error48 } = await this.client.db.from("sites").select("*").eq("id", this.client.siteIdNumber).single();
|
|
@@ -36634,8 +36644,10 @@ var RedirectsEndpoint = class {
|
|
|
36634
36644
|
constructor(client) {
|
|
36635
36645
|
this.client = client;
|
|
36636
36646
|
}
|
|
36637
|
-
async list() {
|
|
36638
|
-
|
|
36647
|
+
async list(params) {
|
|
36648
|
+
let query = this.client.db.from("redirect_rules").select("*").eq("site_id", this.client.siteIdNumber);
|
|
36649
|
+
query = params?.order ? query.order("created_at", { ascending: params.order === "asc" }) : query.order("priority", { ascending: true });
|
|
36650
|
+
const { data, error: error48 } = await query;
|
|
36639
36651
|
if (error48)
|
|
36640
36652
|
throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
|
|
36641
36653
|
return (data ?? []).map((r) => serializeRedirect(r));
|
|
@@ -36712,7 +36724,7 @@ var EntryReferencesEndpoint = class {
|
|
|
36712
36724
|
query = query.eq("from_entry_id", params.fromEntryId);
|
|
36713
36725
|
if (params?.toEntryId)
|
|
36714
36726
|
query = query.eq("to_entry_id", params.toEntryId);
|
|
36715
|
-
const { data, error: error48 } = await query.order("created_at", { ascending:
|
|
36727
|
+
const { data, error: error48 } = await query.order("created_at", { ascending: params?.order === "asc" });
|
|
36716
36728
|
if (error48)
|
|
36717
36729
|
throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
|
|
36718
36730
|
return (data ?? []).map((r) => serializeEntryReference(r));
|
|
@@ -36834,18 +36846,57 @@ var TemplatesEndpoint = class {
|
|
|
36834
36846
|
const res = await this.client.delete(this.basePath);
|
|
36835
36847
|
return res.data;
|
|
36836
36848
|
}
|
|
36849
|
+
/**
|
|
36850
|
+
* List templates across the sites the caller can access.
|
|
36851
|
+
*
|
|
36852
|
+
* Direct-DB: `templates` is public-read and `sites` RLS scopes the visible set
|
|
36853
|
+
* (own active memberships, or all sites for the super admin), so no server
|
|
36854
|
+
* route is needed — the two RLS-scoped queries reproduce the old handler.
|
|
36855
|
+
*/
|
|
36837
36856
|
async list(params) {
|
|
36838
|
-
const
|
|
36839
|
-
if (
|
|
36840
|
-
|
|
36841
|
-
|
|
36842
|
-
|
|
36843
|
-
|
|
36844
|
-
|
|
36845
|
-
|
|
36846
|
-
|
|
36847
|
-
|
|
36848
|
-
|
|
36857
|
+
const { data: sitesData, error: sitesError } = await this.client.db.from("sites").select("id, handle, name");
|
|
36858
|
+
if (sitesError)
|
|
36859
|
+
throw new NeopressApiError("DB_ERROR", sitesError.message, 0, sitesError);
|
|
36860
|
+
const siteMeta = /* @__PURE__ */ new Map();
|
|
36861
|
+
for (const site of sitesData ?? []) {
|
|
36862
|
+
if (typeof site.id !== "number")
|
|
36863
|
+
continue;
|
|
36864
|
+
siteMeta.set(site.id, {
|
|
36865
|
+
handle: site.handle ?? null,
|
|
36866
|
+
name: site.name ?? null
|
|
36867
|
+
});
|
|
36868
|
+
}
|
|
36869
|
+
const siteIds = [...siteMeta.keys()];
|
|
36870
|
+
if (siteIds.length === 0)
|
|
36871
|
+
return [];
|
|
36872
|
+
const namePrefix = params?.namePrefix?.trim();
|
|
36873
|
+
const industry = params?.industry?.trim();
|
|
36874
|
+
const limit = Math.min(Math.max(params?.limit ?? 100, 1), 500);
|
|
36875
|
+
let query = this.client.db.from("templates").select("id, name, industry, reference_url, preview_img_urls, description, created_at").in("id", siteIds);
|
|
36876
|
+
if (namePrefix)
|
|
36877
|
+
query = query.ilike("name", `${namePrefix}%`);
|
|
36878
|
+
if (industry)
|
|
36879
|
+
query = query.eq("industry", industry);
|
|
36880
|
+
if (params?.order)
|
|
36881
|
+
query = query.order("created_at", { ascending: params.order === "asc" });
|
|
36882
|
+
query = query.limit(limit);
|
|
36883
|
+
const { data, error: error48 } = await query;
|
|
36884
|
+
if (error48)
|
|
36885
|
+
throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
|
|
36886
|
+
return (data ?? []).map((t) => {
|
|
36887
|
+
const siteId = t.id;
|
|
36888
|
+
return {
|
|
36889
|
+
siteId,
|
|
36890
|
+
handle: siteMeta.get(siteId)?.handle ?? null,
|
|
36891
|
+
siteName: siteMeta.get(siteId)?.name ?? null,
|
|
36892
|
+
name: t.name,
|
|
36893
|
+
industry: t.industry,
|
|
36894
|
+
referenceUrl: t.reference_url,
|
|
36895
|
+
previewImgUrls: t.preview_img_urls ?? null,
|
|
36896
|
+
description: t.description ?? null,
|
|
36897
|
+
createdAt: t.created_at
|
|
36898
|
+
};
|
|
36899
|
+
});
|
|
36849
36900
|
}
|
|
36850
36901
|
};
|
|
36851
36902
|
|
|
@@ -36868,7 +36919,12 @@ var HeadshotsEndpoint = class {
|
|
|
36868
36919
|
query = query.eq("attire", params.attire);
|
|
36869
36920
|
if (params?.isActive !== void 0)
|
|
36870
36921
|
query = query.eq("is_active", params.isActive);
|
|
36871
|
-
|
|
36922
|
+
if (params?.order) {
|
|
36923
|
+
query = query.order("created_at", { ascending: params.order === "asc" });
|
|
36924
|
+
} else {
|
|
36925
|
+
query = query.order("age_band", { ascending: true }).order("gender", { ascending: true }).order("ethnicity", { ascending: true }).order("variation_index", { ascending: true });
|
|
36926
|
+
}
|
|
36927
|
+
const { data, error: error48, count } = await query.range(offset, offset + limit - 1);
|
|
36872
36928
|
if (error48)
|
|
36873
36929
|
throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
|
|
36874
36930
|
return {
|