@neopress/cli 4.2.0 → 4.4.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 +116 -55
- package/dist/index.js +77 -26
- package/package.json +1 -1
package/dist/bin.cjs
CHANGED
|
@@ -24917,7 +24917,6 @@ function serializeTemplate(t) {
|
|
|
24917
24917
|
id: t.id,
|
|
24918
24918
|
name: t.name,
|
|
24919
24919
|
description: t.description ?? null,
|
|
24920
|
-
industry: t.industry,
|
|
24921
24920
|
referenceUrl: t.reference_url,
|
|
24922
24921
|
previewImgUrls: t.preview_img_urls,
|
|
24923
24922
|
previewVideoUrl: t.preview_video_url ?? null,
|
|
@@ -24998,7 +24997,8 @@ var PagesEndpoint = class {
|
|
|
24998
24997
|
}
|
|
24999
24998
|
async list(params) {
|
|
25000
24999
|
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)
|
|
25000
|
+
let query = this.client.db.from("pages").select("*", { count: "exact" }).eq("site_id", this.client.siteIdNumber).is("draft_deleted_at", null);
|
|
25001
|
+
query = params?.order ? query.order("created_at", { ascending: params.order === "asc" }) : query.order("path");
|
|
25002
25002
|
if (params?.status)
|
|
25003
25003
|
query = query.eq("status", params.status);
|
|
25004
25004
|
const { data, error: error48, count } = await query.range(offset, offset + limit - 1);
|
|
@@ -40052,8 +40052,10 @@ var CollectionsEndpoint = class {
|
|
|
40052
40052
|
get basePath() {
|
|
40053
40053
|
return `${this.client.siteBasePath}/collections`;
|
|
40054
40054
|
}
|
|
40055
|
-
async list() {
|
|
40056
|
-
|
|
40055
|
+
async list(params) {
|
|
40056
|
+
let query = this.client.db.from("collections").select("*").eq("site_id", this.client.siteIdNumber).is("draft_deleted_at", null);
|
|
40057
|
+
query = params?.order ? query.order("created_at", { ascending: params.order === "asc" }) : query.order("name");
|
|
40058
|
+
const { data, error: error48 } = await query;
|
|
40057
40059
|
if (error48)
|
|
40058
40060
|
throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
|
|
40059
40061
|
return (data ?? []).map((r) => serializeCollection(r));
|
|
@@ -40126,7 +40128,7 @@ var EntriesEndpoint = class {
|
|
|
40126
40128
|
}
|
|
40127
40129
|
async list(collectionId, params) {
|
|
40128
40130
|
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:
|
|
40131
|
+
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
40132
|
if (params?.status)
|
|
40131
40133
|
query = query.eq("status", params.status);
|
|
40132
40134
|
if (params?.locale)
|
|
@@ -40217,8 +40219,10 @@ var FormsEndpoint = class {
|
|
|
40217
40219
|
get basePath() {
|
|
40218
40220
|
return `${this.client.siteBasePath}/forms`;
|
|
40219
40221
|
}
|
|
40220
|
-
async list() {
|
|
40221
|
-
|
|
40222
|
+
async list(params) {
|
|
40223
|
+
let query = this.client.db.from("forms").select("*").eq("site_id", this.client.siteIdNumber).is("draft_deleted_at", null);
|
|
40224
|
+
query = params?.order ? query.order("created_at", { ascending: params.order === "asc" }) : query.order("name");
|
|
40225
|
+
const { data, error: error48 } = await query;
|
|
40222
40226
|
if (error48)
|
|
40223
40227
|
throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
|
|
40224
40228
|
const rows = data ?? [];
|
|
@@ -40297,7 +40301,7 @@ var AssetsEndpoint = class {
|
|
|
40297
40301
|
}
|
|
40298
40302
|
async list(params) {
|
|
40299
40303
|
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:
|
|
40304
|
+
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
40305
|
if (error48)
|
|
40302
40306
|
throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
|
|
40303
40307
|
const rows = data ?? [];
|
|
@@ -40363,7 +40367,7 @@ var SiteEndpoint = class {
|
|
|
40363
40367
|
constructor(client) {
|
|
40364
40368
|
this.client = client;
|
|
40365
40369
|
}
|
|
40366
|
-
async list() {
|
|
40370
|
+
async list(params) {
|
|
40367
40371
|
const profileId = this.client.authUserId;
|
|
40368
40372
|
if (!profileId) {
|
|
40369
40373
|
throw new NeopressApiError("NO_AUTH", "site.list requires an authenticated access token", 0);
|
|
@@ -40371,10 +40375,15 @@ var SiteEndpoint = class {
|
|
|
40371
40375
|
const { data, error: error48 } = await this.client.db.from("sites_profiles").select("role, sites!inner(*)").eq("profile_id", profileId).eq("status", "active");
|
|
40372
40376
|
if (error48)
|
|
40373
40377
|
throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
|
|
40374
|
-
|
|
40378
|
+
const sites = (data ?? []).map((m) => ({
|
|
40375
40379
|
...serializeSite(m.sites),
|
|
40376
40380
|
role: m.role
|
|
40377
40381
|
}));
|
|
40382
|
+
if (params?.order) {
|
|
40383
|
+
const dir = params.order === "asc" ? 1 : -1;
|
|
40384
|
+
sites.sort((a, b) => (a.createdAt ?? "") < (b.createdAt ?? "") ? -dir : (a.createdAt ?? "") > (b.createdAt ?? "") ? dir : 0);
|
|
40385
|
+
}
|
|
40386
|
+
return sites;
|
|
40378
40387
|
}
|
|
40379
40388
|
async get() {
|
|
40380
40389
|
const { data, error: error48 } = await this.client.db.from("sites").select("*").eq("id", this.client.siteIdNumber).single();
|
|
@@ -40412,8 +40421,10 @@ var RedirectsEndpoint = class {
|
|
|
40412
40421
|
constructor(client) {
|
|
40413
40422
|
this.client = client;
|
|
40414
40423
|
}
|
|
40415
|
-
async list() {
|
|
40416
|
-
|
|
40424
|
+
async list(params) {
|
|
40425
|
+
let query = this.client.db.from("redirect_rules").select("*").eq("site_id", this.client.siteIdNumber);
|
|
40426
|
+
query = params?.order ? query.order("created_at", { ascending: params.order === "asc" }) : query.order("priority", { ascending: true });
|
|
40427
|
+
const { data, error: error48 } = await query;
|
|
40417
40428
|
if (error48)
|
|
40418
40429
|
throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
|
|
40419
40430
|
return (data ?? []).map((r) => serializeRedirect(r));
|
|
@@ -40423,7 +40434,7 @@ var RedirectsEndpoint = class {
|
|
|
40423
40434
|
site_id: this.client.siteIdNumber,
|
|
40424
40435
|
source: data.source,
|
|
40425
40436
|
destination: data.destination,
|
|
40426
|
-
redirect_type: data.redirectType ??
|
|
40437
|
+
redirect_type: data.redirectType ?? 308,
|
|
40427
40438
|
include_children: data.includeChildren ?? false,
|
|
40428
40439
|
preserve_path: data.preservePath ?? false,
|
|
40429
40440
|
enabled: data.enabled !== false,
|
|
@@ -40490,7 +40501,7 @@ var EntryReferencesEndpoint = class {
|
|
|
40490
40501
|
query = query.eq("from_entry_id", params.fromEntryId);
|
|
40491
40502
|
if (params?.toEntryId)
|
|
40492
40503
|
query = query.eq("to_entry_id", params.toEntryId);
|
|
40493
|
-
const { data, error: error48 } = await query.order("created_at", { ascending:
|
|
40504
|
+
const { data, error: error48 } = await query.order("created_at", { ascending: params?.order === "asc" });
|
|
40494
40505
|
if (error48)
|
|
40495
40506
|
throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
|
|
40496
40507
|
return (data ?? []).map((r) => serializeEntryReference(r));
|
|
@@ -40612,18 +40623,53 @@ var TemplatesEndpoint = class {
|
|
|
40612
40623
|
const res = await this.client.delete(this.basePath);
|
|
40613
40624
|
return res.data;
|
|
40614
40625
|
}
|
|
40626
|
+
/**
|
|
40627
|
+
* List templates across the sites the caller can access.
|
|
40628
|
+
*
|
|
40629
|
+
* Direct-DB: `templates` is public-read and `sites` RLS scopes the visible set
|
|
40630
|
+
* (own active memberships, or all sites for the super admin), so no server
|
|
40631
|
+
* route is needed — the two RLS-scoped queries reproduce the old handler.
|
|
40632
|
+
*/
|
|
40615
40633
|
async list(params) {
|
|
40616
|
-
const
|
|
40617
|
-
if (
|
|
40618
|
-
|
|
40619
|
-
|
|
40620
|
-
|
|
40621
|
-
|
|
40622
|
-
|
|
40623
|
-
|
|
40624
|
-
|
|
40625
|
-
|
|
40626
|
-
|
|
40634
|
+
const { data: sitesData, error: sitesError } = await this.client.db.from("sites").select("id, handle, name");
|
|
40635
|
+
if (sitesError)
|
|
40636
|
+
throw new NeopressApiError("DB_ERROR", sitesError.message, 0, sitesError);
|
|
40637
|
+
const siteMeta = /* @__PURE__ */ new Map();
|
|
40638
|
+
for (const site of sitesData ?? []) {
|
|
40639
|
+
if (typeof site.id !== "number")
|
|
40640
|
+
continue;
|
|
40641
|
+
siteMeta.set(site.id, {
|
|
40642
|
+
handle: site.handle ?? null,
|
|
40643
|
+
name: site.name ?? null
|
|
40644
|
+
});
|
|
40645
|
+
}
|
|
40646
|
+
const siteIds = [...siteMeta.keys()];
|
|
40647
|
+
if (siteIds.length === 0)
|
|
40648
|
+
return [];
|
|
40649
|
+
const namePrefix = params?.namePrefix?.trim();
|
|
40650
|
+
const limit = Math.min(Math.max(params?.limit ?? 100, 1), 500);
|
|
40651
|
+
let query = this.client.db.from("templates").select("id, name, reference_url, preview_img_urls, description, created_at").in("id", siteIds);
|
|
40652
|
+
if (namePrefix)
|
|
40653
|
+
query = query.ilike("name", `${namePrefix}%`);
|
|
40654
|
+
if (params?.order)
|
|
40655
|
+
query = query.order("created_at", { ascending: params.order === "asc" });
|
|
40656
|
+
query = query.limit(limit);
|
|
40657
|
+
const { data, error: error48 } = await query;
|
|
40658
|
+
if (error48)
|
|
40659
|
+
throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
|
|
40660
|
+
return (data ?? []).map((t) => {
|
|
40661
|
+
const siteId = t.id;
|
|
40662
|
+
return {
|
|
40663
|
+
siteId,
|
|
40664
|
+
handle: siteMeta.get(siteId)?.handle ?? null,
|
|
40665
|
+
siteName: siteMeta.get(siteId)?.name ?? null,
|
|
40666
|
+
name: t.name,
|
|
40667
|
+
referenceUrl: t.reference_url,
|
|
40668
|
+
previewImgUrls: t.preview_img_urls ?? null,
|
|
40669
|
+
description: t.description ?? null,
|
|
40670
|
+
createdAt: t.created_at
|
|
40671
|
+
};
|
|
40672
|
+
});
|
|
40627
40673
|
}
|
|
40628
40674
|
};
|
|
40629
40675
|
|
|
@@ -40646,7 +40692,12 @@ var HeadshotsEndpoint = class {
|
|
|
40646
40692
|
query = query.eq("attire", params.attire);
|
|
40647
40693
|
if (params?.isActive !== void 0)
|
|
40648
40694
|
query = query.eq("is_active", params.isActive);
|
|
40649
|
-
|
|
40695
|
+
if (params?.order) {
|
|
40696
|
+
query = query.order("created_at", { ascending: params.order === "asc" });
|
|
40697
|
+
} else {
|
|
40698
|
+
query = query.order("age_band", { ascending: true }).order("gender", { ascending: true }).order("ethnicity", { ascending: true }).order("variation_index", { ascending: true });
|
|
40699
|
+
}
|
|
40700
|
+
const { data, error: error48, count } = await query.range(offset, offset + limit - 1);
|
|
40650
40701
|
if (error48)
|
|
40651
40702
|
throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
|
|
40652
40703
|
return {
|
|
@@ -40912,6 +40963,16 @@ async function getGlobalClientAsync() {
|
|
|
40912
40963
|
return new NeopressClient({ accessToken: token, siteId: 0, baseUrl: getBaseUrl(), supabaseUrl: sb.url, supabaseAnonKey: sb.anonKey });
|
|
40913
40964
|
}
|
|
40914
40965
|
|
|
40966
|
+
// src/utils/order.ts
|
|
40967
|
+
function parseOrder(value) {
|
|
40968
|
+
if (value === void 0) return void 0;
|
|
40969
|
+
if (value !== "asc" && value !== "desc") {
|
|
40970
|
+
fail(`Invalid --order value "${value}". Use "asc" or "desc".`);
|
|
40971
|
+
}
|
|
40972
|
+
return value;
|
|
40973
|
+
}
|
|
40974
|
+
var ORDER_OPTION_DESC = "Sort by created_at (asc or desc)";
|
|
40975
|
+
|
|
40915
40976
|
// src/commands/sites.ts
|
|
40916
40977
|
function registerSiteCommands(program3) {
|
|
40917
40978
|
const sites = program3.command("sites").description("Manage sites").addHelpText("after", `
|
|
@@ -40922,9 +40983,9 @@ Examples:
|
|
|
40922
40983
|
$ neopress sites use my-site
|
|
40923
40984
|
$ neopress sites current
|
|
40924
40985
|
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 () => {
|
|
40986
|
+
sites.command("list").description("List accessible sites").option("--order <asc|desc>", ORDER_OPTION_DESC).action(async (options) => {
|
|
40926
40987
|
const client = await getGlobalClientAsync();
|
|
40927
|
-
const sitesList = await client.site.list();
|
|
40988
|
+
const sitesList = await client.site.list({ order: parseOrder(options.order) });
|
|
40928
40989
|
output(sitesList);
|
|
40929
40990
|
});
|
|
40930
40991
|
sites.command("use <siteIdOrHandle>").description("Set active site (ID or handle)").addHelpText("after", `
|
|
@@ -41078,10 +41139,11 @@ Examples:
|
|
|
41078
41139
|
$ neopress pages compile <pageId>
|
|
41079
41140
|
|
|
41080
41141
|
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) => {
|
|
41142
|
+
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
41143
|
const client = await getClientAsync();
|
|
41083
41144
|
const res = await client.pages.list({
|
|
41084
41145
|
status: options.status,
|
|
41146
|
+
order: parseOrder(options.order),
|
|
41085
41147
|
page: parseInt(options.page, 10),
|
|
41086
41148
|
limit: parseInt(options.limit, 10)
|
|
41087
41149
|
});
|
|
@@ -41178,9 +41240,9 @@ Examples:
|
|
|
41178
41240
|
$ neopress collections update 12 --schema @schema.json
|
|
41179
41241
|
|
|
41180
41242
|
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 () => {
|
|
41243
|
+
collections.command("list").description("List collections").option("--order <asc|desc>", ORDER_OPTION_DESC).action(async (options) => {
|
|
41182
41244
|
const client = await getClientAsync();
|
|
41183
|
-
const data = await client.collections.list();
|
|
41245
|
+
const data = await client.collections.list({ order: parseOrder(options.order) });
|
|
41184
41246
|
output(data);
|
|
41185
41247
|
});
|
|
41186
41248
|
collections.command("get <collectionId>").description("Get collection details").action(async (collectionId) => {
|
|
@@ -41238,11 +41300,12 @@ Examples:
|
|
|
41238
41300
|
$ neopress entries publish <entryId>
|
|
41239
41301
|
|
|
41240
41302
|
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) => {
|
|
41303
|
+
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
41304
|
const client = await getClientAsync();
|
|
41243
41305
|
const res = await client.entries.list(parseInt(options.collection, 10), {
|
|
41244
41306
|
status: options.status,
|
|
41245
41307
|
locale: options.locale,
|
|
41308
|
+
order: parseOrder(options.order),
|
|
41246
41309
|
page: parseInt(options.page, 10),
|
|
41247
41310
|
limit: parseInt(options.limit, 10)
|
|
41248
41311
|
});
|
|
@@ -41332,9 +41395,9 @@ Examples:
|
|
|
41332
41395
|
$ neopress forms publish <formId>
|
|
41333
41396
|
$ neopress forms responses <formId> --limit 50
|
|
41334
41397
|
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 () => {
|
|
41398
|
+
forms.command("list").description("List forms").option("--order <asc|desc>", ORDER_OPTION_DESC).action(async (options) => {
|
|
41336
41399
|
const client = await getClientAsync();
|
|
41337
|
-
const data = await client.forms.list();
|
|
41400
|
+
const data = await client.forms.list({ order: parseOrder(options.order) });
|
|
41338
41401
|
output(data);
|
|
41339
41402
|
});
|
|
41340
41403
|
forms.command("get <formId>").description("Get form details").action(async (formId) => {
|
|
@@ -41414,9 +41477,10 @@ Examples:
|
|
|
41414
41477
|
$ neopress assets upload ./hero.png --folder images
|
|
41415
41478
|
$ neopress assets list --limit 50
|
|
41416
41479
|
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) => {
|
|
41480
|
+
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
41481
|
const client = await getClientAsync();
|
|
41419
41482
|
const res = await client.assets.list({
|
|
41483
|
+
order: parseOrder(options.order),
|
|
41420
41484
|
page: parseInt(options.page, 10),
|
|
41421
41485
|
limit: parseInt(options.limit, 10)
|
|
41422
41486
|
});
|
|
@@ -41499,16 +41563,16 @@ Examples:
|
|
|
41499
41563
|
$ neopress redirects create --source /docs --dest /guide --type 308
|
|
41500
41564
|
$ neopress redirects list
|
|
41501
41565
|
Rules are created enabled. delete <ruleId> removes a rule permanently.`);
|
|
41502
|
-
redirects.command("list").description("List redirect rules").action(async () => {
|
|
41566
|
+
redirects.command("list").description("List redirect rules").option("--order <asc|desc>", `${ORDER_OPTION_DESC} (default sort: priority)`).action(async (options) => {
|
|
41503
41567
|
const client = await getClientAsync();
|
|
41504
|
-
const data = await client.redirects.list();
|
|
41568
|
+
const data = await client.redirects.list({ order: parseOrder(options.order) });
|
|
41505
41569
|
output(data);
|
|
41506
41570
|
});
|
|
41507
41571
|
redirects.command("create").description("Create a redirect rule").addHelpText("after", `
|
|
41508
41572
|
Examples:
|
|
41509
41573
|
$ neopress redirects create --source /old --dest /about
|
|
41510
41574
|
$ neopress redirects create --source /docs --dest /guide --type 308
|
|
41511
|
-
--source and --dest are both required. --type is 307 (temporary
|
|
41575
|
+
--source and --dest are both required. --type is 307 (temporary) or 308 (permanent, default). The rule is created enabled.`).requiredOption("--source <path>", "Source path").requiredOption("--dest <path>", "Destination path").option("--type <type>", "Redirect type (307/308)", "308").action(async (options) => {
|
|
41512
41576
|
const client = await getClientAsync();
|
|
41513
41577
|
const rule = await client.redirects.create({
|
|
41514
41578
|
source: options.source,
|
|
@@ -41564,11 +41628,12 @@ Examples:
|
|
|
41564
41628
|
$ neopress entry-references list --from-entry 12
|
|
41565
41629
|
$ neopress entry-references delete <referenceId>
|
|
41566
41630
|
--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) => {
|
|
41631
|
+
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
41632
|
const client = await getClientAsync();
|
|
41569
41633
|
const data = await client.entryReferences.list({
|
|
41570
41634
|
fromEntryId: options.fromEntry ? parseInt(options.fromEntry, 10) : void 0,
|
|
41571
|
-
toEntryId: options.toEntry ? parseInt(options.toEntry, 10) : void 0
|
|
41635
|
+
toEntryId: options.toEntry ? parseInt(options.toEntry, 10) : void 0,
|
|
41636
|
+
order: parseOrder(options.order)
|
|
41572
41637
|
});
|
|
41573
41638
|
output(data);
|
|
41574
41639
|
});
|
|
@@ -41726,19 +41791,15 @@ function collectPreviewImgUrl(value, previous = []) {
|
|
|
41726
41791
|
function registerTemplateCommands(program3) {
|
|
41727
41792
|
const templates = program3.command("templates").description("Manage template metadata for the active site").addHelpText("after", `
|
|
41728
41793
|
Examples:
|
|
41729
|
-
$ neopress templates mark --name "SaaS Landing" --
|
|
41730
|
-
$ neopress templates list --
|
|
41794
|
+
$ neopress templates mark --name "SaaS Landing" --reference-url https://example.com --preview-img-url https://cdn.example.com/1.png
|
|
41795
|
+
$ neopress templates list --limit 50
|
|
41731
41796
|
$ neopress templates delete
|
|
41732
41797
|
\`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("--
|
|
41734
|
-
const
|
|
41735
|
-
if (!token) {
|
|
41736
|
-
fail("Not authenticated. Run `neopress login`.");
|
|
41737
|
-
}
|
|
41738
|
-
const client = new NeopressClient({ accessToken: token, siteId: 0, baseUrl: getBaseUrl() });
|
|
41798
|
+
templates.command("list").description("List templates across sites you can access").option("--name-prefix <prefix>", "Filter by template name prefix").option("--order <asc|desc>", ORDER_OPTION_DESC).option("--limit <n>", "Max results (default 100, max 500)").action(async (options) => {
|
|
41799
|
+
const client = await getGlobalClientAsync();
|
|
41739
41800
|
const templates2 = await client.templates.list({
|
|
41740
41801
|
namePrefix: options.namePrefix,
|
|
41741
|
-
|
|
41802
|
+
order: parseOrder(options.order),
|
|
41742
41803
|
limit: options.limit ? parseInt(options.limit, 10) : void 0
|
|
41743
41804
|
});
|
|
41744
41805
|
output(templates2);
|
|
@@ -41750,9 +41811,9 @@ Examples:
|
|
|
41750
41811
|
});
|
|
41751
41812
|
templates.command("mark").description("Mark or update the active site as a template").addHelpText("after", `
|
|
41752
41813
|
Examples:
|
|
41753
|
-
$ neopress templates mark --name "SaaS Landing" --
|
|
41754
|
-
$ neopress templates mark --name Portfolio --
|
|
41755
|
-
--name
|
|
41814
|
+
$ neopress templates mark --name "SaaS Landing" --reference-url https://example.com --preview-img-url https://cdn.example.com/1.png
|
|
41815
|
+
$ neopress templates mark --name Portfolio --reference-url https://example.com --preview-img-url https://cdn.example.com/a.png --preview-img-url https://cdn.example.com/b.png --description "Minimal portfolio"
|
|
41816
|
+
--name and --reference-url are required, and at least one --preview-img-url must be given (repeat the flag for multiple images). Upserts the template metadata for the active site and sets the site status to active; running it again updates the existing template.`).requiredOption("--name <name>", "Template display name").option("--description <description>", "Template description, up to 150 characters").requiredOption(
|
|
41756
41817
|
"--reference-url <url>",
|
|
41757
41818
|
"Reference URL for template provenance"
|
|
41758
41819
|
).option(
|
|
@@ -41765,7 +41826,6 @@ Examples:
|
|
|
41765
41826
|
const template = await client.templates.mark({
|
|
41766
41827
|
name: options.name,
|
|
41767
41828
|
description: options.description,
|
|
41768
|
-
industry: options.industry,
|
|
41769
41829
|
referenceUrl: options.referenceUrl,
|
|
41770
41830
|
previewImgUrls: options.previewImgUrl.length > 0 ? options.previewImgUrl : void 0
|
|
41771
41831
|
});
|
|
@@ -41803,7 +41863,7 @@ Examples:
|
|
|
41803
41863
|
$ neopress headshots create --image-url https://cdn/x.webp --age-band young --gender male --ethnicity white --variation-index 0
|
|
41804
41864
|
$ neopress headshots update 12 --inactive
|
|
41805
41865
|
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", `
|
|
41866
|
+
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
41867
|
Examples:
|
|
41808
41868
|
$ neopress headshots list
|
|
41809
41869
|
$ neopress headshots list --gender female --age-band middle --active
|
|
@@ -41818,6 +41878,7 @@ Filters are equality matches on the pool's demographic columns; results are pagi
|
|
|
41818
41878
|
const params = {
|
|
41819
41879
|
page: parseInt(options.page, 10),
|
|
41820
41880
|
limit: parseInt(options.limit, 10),
|
|
41881
|
+
order: parseOrder(options.order),
|
|
41821
41882
|
ageBand: options.ageBand,
|
|
41822
41883
|
gender: options.gender,
|
|
41823
41884
|
ethnicity: options.ethnicity,
|
|
@@ -41997,7 +42058,7 @@ function registerGuideCommands(program3) {
|
|
|
41997
42058
|
|
|
41998
42059
|
// src/bin.ts
|
|
41999
42060
|
var program2 = new Command();
|
|
42000
|
-
program2.name("neopress").description("Neopress CLI \u2014 manage your site from the terminal").version("4.
|
|
42061
|
+
program2.name("neopress").description("Neopress CLI \u2014 manage your site from the terminal").version("4.4.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
42062
|
const opts = thisCommand.optsWithGlobals();
|
|
42002
42063
|
if (opts.site) setSiteOverride(String(opts.site));
|
|
42003
42064
|
if (opts.json || !process.stdout.isTTY) setJsonMode(true);
|
package/dist/index.js
CHANGED
|
@@ -21139,7 +21139,6 @@ function serializeTemplate(t) {
|
|
|
21139
21139
|
id: t.id,
|
|
21140
21140
|
name: t.name,
|
|
21141
21141
|
description: t.description ?? null,
|
|
21142
|
-
industry: t.industry,
|
|
21143
21142
|
referenceUrl: t.reference_url,
|
|
21144
21143
|
previewImgUrls: t.preview_img_urls,
|
|
21145
21144
|
previewVideoUrl: t.preview_video_url ?? null,
|
|
@@ -21220,7 +21219,8 @@ var PagesEndpoint = class {
|
|
|
21220
21219
|
}
|
|
21221
21220
|
async list(params) {
|
|
21222
21221
|
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)
|
|
21222
|
+
let query = this.client.db.from("pages").select("*", { count: "exact" }).eq("site_id", this.client.siteIdNumber).is("draft_deleted_at", null);
|
|
21223
|
+
query = params?.order ? query.order("created_at", { ascending: params.order === "asc" }) : query.order("path");
|
|
21224
21224
|
if (params?.status)
|
|
21225
21225
|
query = query.eq("status", params.status);
|
|
21226
21226
|
const { data, error: error48, count } = await query.range(offset, offset + limit - 1);
|
|
@@ -36274,8 +36274,10 @@ var CollectionsEndpoint = class {
|
|
|
36274
36274
|
get basePath() {
|
|
36275
36275
|
return `${this.client.siteBasePath}/collections`;
|
|
36276
36276
|
}
|
|
36277
|
-
async list() {
|
|
36278
|
-
|
|
36277
|
+
async list(params) {
|
|
36278
|
+
let query = this.client.db.from("collections").select("*").eq("site_id", this.client.siteIdNumber).is("draft_deleted_at", null);
|
|
36279
|
+
query = params?.order ? query.order("created_at", { ascending: params.order === "asc" }) : query.order("name");
|
|
36280
|
+
const { data, error: error48 } = await query;
|
|
36279
36281
|
if (error48)
|
|
36280
36282
|
throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
|
|
36281
36283
|
return (data ?? []).map((r) => serializeCollection(r));
|
|
@@ -36348,7 +36350,7 @@ var EntriesEndpoint = class {
|
|
|
36348
36350
|
}
|
|
36349
36351
|
async list(collectionId, params) {
|
|
36350
36352
|
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:
|
|
36353
|
+
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
36354
|
if (params?.status)
|
|
36353
36355
|
query = query.eq("status", params.status);
|
|
36354
36356
|
if (params?.locale)
|
|
@@ -36439,8 +36441,10 @@ var FormsEndpoint = class {
|
|
|
36439
36441
|
get basePath() {
|
|
36440
36442
|
return `${this.client.siteBasePath}/forms`;
|
|
36441
36443
|
}
|
|
36442
|
-
async list() {
|
|
36443
|
-
|
|
36444
|
+
async list(params) {
|
|
36445
|
+
let query = this.client.db.from("forms").select("*").eq("site_id", this.client.siteIdNumber).is("draft_deleted_at", null);
|
|
36446
|
+
query = params?.order ? query.order("created_at", { ascending: params.order === "asc" }) : query.order("name");
|
|
36447
|
+
const { data, error: error48 } = await query;
|
|
36444
36448
|
if (error48)
|
|
36445
36449
|
throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
|
|
36446
36450
|
const rows = data ?? [];
|
|
@@ -36519,7 +36523,7 @@ var AssetsEndpoint = class {
|
|
|
36519
36523
|
}
|
|
36520
36524
|
async list(params) {
|
|
36521
36525
|
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:
|
|
36526
|
+
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
36527
|
if (error48)
|
|
36524
36528
|
throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
|
|
36525
36529
|
const rows = data ?? [];
|
|
@@ -36585,7 +36589,7 @@ var SiteEndpoint = class {
|
|
|
36585
36589
|
constructor(client) {
|
|
36586
36590
|
this.client = client;
|
|
36587
36591
|
}
|
|
36588
|
-
async list() {
|
|
36592
|
+
async list(params) {
|
|
36589
36593
|
const profileId = this.client.authUserId;
|
|
36590
36594
|
if (!profileId) {
|
|
36591
36595
|
throw new NeopressApiError("NO_AUTH", "site.list requires an authenticated access token", 0);
|
|
@@ -36593,10 +36597,15 @@ var SiteEndpoint = class {
|
|
|
36593
36597
|
const { data, error: error48 } = await this.client.db.from("sites_profiles").select("role, sites!inner(*)").eq("profile_id", profileId).eq("status", "active");
|
|
36594
36598
|
if (error48)
|
|
36595
36599
|
throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
|
|
36596
|
-
|
|
36600
|
+
const sites = (data ?? []).map((m) => ({
|
|
36597
36601
|
...serializeSite(m.sites),
|
|
36598
36602
|
role: m.role
|
|
36599
36603
|
}));
|
|
36604
|
+
if (params?.order) {
|
|
36605
|
+
const dir = params.order === "asc" ? 1 : -1;
|
|
36606
|
+
sites.sort((a, b) => (a.createdAt ?? "") < (b.createdAt ?? "") ? -dir : (a.createdAt ?? "") > (b.createdAt ?? "") ? dir : 0);
|
|
36607
|
+
}
|
|
36608
|
+
return sites;
|
|
36600
36609
|
}
|
|
36601
36610
|
async get() {
|
|
36602
36611
|
const { data, error: error48 } = await this.client.db.from("sites").select("*").eq("id", this.client.siteIdNumber).single();
|
|
@@ -36634,8 +36643,10 @@ var RedirectsEndpoint = class {
|
|
|
36634
36643
|
constructor(client) {
|
|
36635
36644
|
this.client = client;
|
|
36636
36645
|
}
|
|
36637
|
-
async list() {
|
|
36638
|
-
|
|
36646
|
+
async list(params) {
|
|
36647
|
+
let query = this.client.db.from("redirect_rules").select("*").eq("site_id", this.client.siteIdNumber);
|
|
36648
|
+
query = params?.order ? query.order("created_at", { ascending: params.order === "asc" }) : query.order("priority", { ascending: true });
|
|
36649
|
+
const { data, error: error48 } = await query;
|
|
36639
36650
|
if (error48)
|
|
36640
36651
|
throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
|
|
36641
36652
|
return (data ?? []).map((r) => serializeRedirect(r));
|
|
@@ -36645,7 +36656,7 @@ var RedirectsEndpoint = class {
|
|
|
36645
36656
|
site_id: this.client.siteIdNumber,
|
|
36646
36657
|
source: data.source,
|
|
36647
36658
|
destination: data.destination,
|
|
36648
|
-
redirect_type: data.redirectType ??
|
|
36659
|
+
redirect_type: data.redirectType ?? 308,
|
|
36649
36660
|
include_children: data.includeChildren ?? false,
|
|
36650
36661
|
preserve_path: data.preservePath ?? false,
|
|
36651
36662
|
enabled: data.enabled !== false,
|
|
@@ -36712,7 +36723,7 @@ var EntryReferencesEndpoint = class {
|
|
|
36712
36723
|
query = query.eq("from_entry_id", params.fromEntryId);
|
|
36713
36724
|
if (params?.toEntryId)
|
|
36714
36725
|
query = query.eq("to_entry_id", params.toEntryId);
|
|
36715
|
-
const { data, error: error48 } = await query.order("created_at", { ascending:
|
|
36726
|
+
const { data, error: error48 } = await query.order("created_at", { ascending: params?.order === "asc" });
|
|
36716
36727
|
if (error48)
|
|
36717
36728
|
throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
|
|
36718
36729
|
return (data ?? []).map((r) => serializeEntryReference(r));
|
|
@@ -36834,18 +36845,53 @@ var TemplatesEndpoint = class {
|
|
|
36834
36845
|
const res = await this.client.delete(this.basePath);
|
|
36835
36846
|
return res.data;
|
|
36836
36847
|
}
|
|
36848
|
+
/**
|
|
36849
|
+
* List templates across the sites the caller can access.
|
|
36850
|
+
*
|
|
36851
|
+
* Direct-DB: `templates` is public-read and `sites` RLS scopes the visible set
|
|
36852
|
+
* (own active memberships, or all sites for the super admin), so no server
|
|
36853
|
+
* route is needed — the two RLS-scoped queries reproduce the old handler.
|
|
36854
|
+
*/
|
|
36837
36855
|
async list(params) {
|
|
36838
|
-
const
|
|
36839
|
-
if (
|
|
36840
|
-
|
|
36841
|
-
|
|
36842
|
-
|
|
36843
|
-
|
|
36844
|
-
|
|
36845
|
-
|
|
36846
|
-
|
|
36847
|
-
|
|
36848
|
-
|
|
36856
|
+
const { data: sitesData, error: sitesError } = await this.client.db.from("sites").select("id, handle, name");
|
|
36857
|
+
if (sitesError)
|
|
36858
|
+
throw new NeopressApiError("DB_ERROR", sitesError.message, 0, sitesError);
|
|
36859
|
+
const siteMeta = /* @__PURE__ */ new Map();
|
|
36860
|
+
for (const site of sitesData ?? []) {
|
|
36861
|
+
if (typeof site.id !== "number")
|
|
36862
|
+
continue;
|
|
36863
|
+
siteMeta.set(site.id, {
|
|
36864
|
+
handle: site.handle ?? null,
|
|
36865
|
+
name: site.name ?? null
|
|
36866
|
+
});
|
|
36867
|
+
}
|
|
36868
|
+
const siteIds = [...siteMeta.keys()];
|
|
36869
|
+
if (siteIds.length === 0)
|
|
36870
|
+
return [];
|
|
36871
|
+
const namePrefix = params?.namePrefix?.trim();
|
|
36872
|
+
const limit = Math.min(Math.max(params?.limit ?? 100, 1), 500);
|
|
36873
|
+
let query = this.client.db.from("templates").select("id, name, reference_url, preview_img_urls, description, created_at").in("id", siteIds);
|
|
36874
|
+
if (namePrefix)
|
|
36875
|
+
query = query.ilike("name", `${namePrefix}%`);
|
|
36876
|
+
if (params?.order)
|
|
36877
|
+
query = query.order("created_at", { ascending: params.order === "asc" });
|
|
36878
|
+
query = query.limit(limit);
|
|
36879
|
+
const { data, error: error48 } = await query;
|
|
36880
|
+
if (error48)
|
|
36881
|
+
throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
|
|
36882
|
+
return (data ?? []).map((t) => {
|
|
36883
|
+
const siteId = t.id;
|
|
36884
|
+
return {
|
|
36885
|
+
siteId,
|
|
36886
|
+
handle: siteMeta.get(siteId)?.handle ?? null,
|
|
36887
|
+
siteName: siteMeta.get(siteId)?.name ?? null,
|
|
36888
|
+
name: t.name,
|
|
36889
|
+
referenceUrl: t.reference_url,
|
|
36890
|
+
previewImgUrls: t.preview_img_urls ?? null,
|
|
36891
|
+
description: t.description ?? null,
|
|
36892
|
+
createdAt: t.created_at
|
|
36893
|
+
};
|
|
36894
|
+
});
|
|
36849
36895
|
}
|
|
36850
36896
|
};
|
|
36851
36897
|
|
|
@@ -36868,7 +36914,12 @@ var HeadshotsEndpoint = class {
|
|
|
36868
36914
|
query = query.eq("attire", params.attire);
|
|
36869
36915
|
if (params?.isActive !== void 0)
|
|
36870
36916
|
query = query.eq("is_active", params.isActive);
|
|
36871
|
-
|
|
36917
|
+
if (params?.order) {
|
|
36918
|
+
query = query.order("created_at", { ascending: params.order === "asc" });
|
|
36919
|
+
} else {
|
|
36920
|
+
query = query.order("age_band", { ascending: true }).order("gender", { ascending: true }).order("ethnicity", { ascending: true }).order("variation_index", { ascending: true });
|
|
36921
|
+
}
|
|
36922
|
+
const { data, error: error48, count } = await query.range(offset, offset + limit - 1);
|
|
36872
36923
|
if (error48)
|
|
36873
36924
|
throw new NeopressApiError("DB_ERROR", error48.message, 0, error48);
|
|
36874
36925
|
return {
|