@neopress/cli 4.10.1 → 4.11.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/README.md CHANGED
@@ -73,10 +73,26 @@ neopress analytics funnels create --data @funnel.json
73
73
  # Preview, then publish the whole site
74
74
  neopress publish preview
75
75
  neopress publish
76
+
77
+ # Operate the site control plane
78
+ neopress domains status
79
+ neopress search-console authorize
80
+ neopress team list
81
+ neopress history list
82
+ neopress analytics funnels results <funnelId>
83
+
84
+ # Use exact-target destructive commands
85
+ neopress publish unpublish-pages 12 18
86
+ neopress domains remove example.com
76
87
  ```
77
88
 
78
89
  Run `neopress <command> --help` for the flags and examples of any command.
79
90
 
91
+ The API enforces the same site role, work-access, and plan entitlements for CLI,
92
+ SDK, and MCP calls. External API access starts at Launch; saved funnel results
93
+ require Growth analytics, custom-domain connection requires the custom-domain
94
+ feature, team management is Owner/Admin, and billing is Owner-only.
95
+
80
96
  ## JSON / AI mode
81
97
 
82
98
  Output is human-readable in a terminal and **automatically switches to JSON when
package/dist/bin.cjs CHANGED
@@ -3686,6 +3686,12 @@ var FormsEndpoint = class {
3686
3686
  async deleteResponse(formId, responseId) {
3687
3687
  await this.client.delete(`${this.basePath}/${formId}/responses/${responseId}`);
3688
3688
  }
3689
+ async getResponse(formId, responseId) {
3690
+ return (await this.client.get(`${this.basePath}/${formId}/responses/${responseId}`)).data;
3691
+ }
3692
+ async markResponseRead(formId, responseId) {
3693
+ return (await this.client.patch(`${this.basePath}/${formId}/responses/${responseId}`, { read: true })).data;
3694
+ }
3689
3695
  };
3690
3696
  //#endregion
3691
3697
  //#region ../sdk/src/endpoints/assets.ts
@@ -3833,8 +3839,14 @@ var PublishEndpoint = class {
3833
3839
  async preview() {
3834
3840
  return (await this.client.get(`${this.client.siteBasePath}/publish`)).data;
3835
3841
  }
3836
- async site() {
3837
- return (await this.client.post(`${this.client.siteBasePath}/publish`)).data;
3842
+ async site(selection) {
3843
+ return (await this.client.post(`${this.client.siteBasePath}/publish`, selection ? { selection } : void 0)).data;
3844
+ }
3845
+ async unpublishPages(pageIds) {
3846
+ return (await this.client.patch(`${this.client.siteBasePath}/publish`, { pageIds })).data;
3847
+ }
3848
+ async undeploy() {
3849
+ return (await this.client.delete(`${this.client.siteBasePath}/publish`)).data;
3838
3850
  }
3839
3851
  };
3840
3852
  //#endregion
@@ -4002,6 +4014,14 @@ var AnalyticsFunnelsEndpoint = class {
4002
4014
  async delete(funnelId) {
4003
4015
  await this.client.delete(`${this.basePath}/${funnelId}`);
4004
4016
  }
4017
+ async results(funnelId, params) {
4018
+ const query = new URLSearchParams();
4019
+ if (params?.dateFrom) query.set("dateFrom", params.dateFrom);
4020
+ if (params?.dateTo) query.set("dateTo", params.dateTo);
4021
+ if (params?.timezone) query.set("timezone", params.timezone);
4022
+ const suffix = query.size > 0 ? `?${query.toString()}` : "";
4023
+ return (await this.client.get(`${this.basePath}/${funnelId}/results${suffix}`)).data;
4024
+ }
4005
4025
  };
4006
4026
  //#endregion
4007
4027
  //#region ../sdk/src/endpoints/templates.ts
@@ -4130,6 +4150,122 @@ var LogosEndpoint = class {
4130
4150
  }
4131
4151
  };
4132
4152
  //#endregion
4153
+ //#region ../sdk/src/endpoints/domains.ts
4154
+ var DomainsEndpoint = class {
4155
+ client;
4156
+ constructor(client) {
4157
+ this.client = client;
4158
+ }
4159
+ get basePath() {
4160
+ return `${this.client.siteBasePath}/domains`;
4161
+ }
4162
+ async status() {
4163
+ return (await this.client.get(this.basePath)).data;
4164
+ }
4165
+ async connect(domain) {
4166
+ return (await this.client.post(this.basePath, { domain })).data;
4167
+ }
4168
+ async refresh() {
4169
+ return (await this.client.patch(this.basePath, {})).data;
4170
+ }
4171
+ async remove(domain) {
4172
+ return (await this.client.delete(this.basePath, { domain })).data;
4173
+ }
4174
+ };
4175
+ //#endregion
4176
+ //#region ../sdk/src/endpoints/search-console.ts
4177
+ var SearchConsoleConnectionEndpoint = class {
4178
+ client;
4179
+ constructor(client) {
4180
+ this.client = client;
4181
+ }
4182
+ get basePath() {
4183
+ return `${this.client.siteBasePath}/search-console`;
4184
+ }
4185
+ async status() {
4186
+ return (await this.client.get(this.basePath)).data;
4187
+ }
4188
+ async authorize(locale) {
4189
+ return (await this.client.post(this.basePath, locale ? { locale } : {})).data;
4190
+ }
4191
+ async disconnect() {
4192
+ return (await this.client.delete(this.basePath)).data;
4193
+ }
4194
+ };
4195
+ //#endregion
4196
+ //#region ../sdk/src/endpoints/billing.ts
4197
+ var BillingEndpoint = class {
4198
+ client;
4199
+ constructor(client) {
4200
+ this.client = client;
4201
+ }
4202
+ get basePath() {
4203
+ return `${this.client.siteBasePath}/billing`;
4204
+ }
4205
+ async status() {
4206
+ return (await this.client.get(this.basePath)).data;
4207
+ }
4208
+ async checkout(plan) {
4209
+ return (await this.client.post(`${this.basePath}/checkout`, { plan })).data;
4210
+ }
4211
+ async portal() {
4212
+ return (await this.client.post(`${this.basePath}/portal`)).data;
4213
+ }
4214
+ async cancel() {
4215
+ return (await this.client.post(`${this.basePath}/subscription/cancel`)).data;
4216
+ }
4217
+ async resume() {
4218
+ return (await this.client.post(`${this.basePath}/subscription/resume`)).data;
4219
+ }
4220
+ };
4221
+ //#endregion
4222
+ //#region ../sdk/src/endpoints/team.ts
4223
+ var TeamEndpoint = class {
4224
+ client;
4225
+ constructor(client) {
4226
+ this.client = client;
4227
+ }
4228
+ get basePath() {
4229
+ return `${this.client.siteBasePath}/team`;
4230
+ }
4231
+ async list() {
4232
+ return (await this.client.get(this.basePath)).data;
4233
+ }
4234
+ async invite(input) {
4235
+ return (await this.client.post(this.basePath, input)).data;
4236
+ }
4237
+ async updateRole(profileId, role) {
4238
+ return (await this.client.patch(`${this.basePath}/${profileId}`, { role })).data;
4239
+ }
4240
+ async remove(profileId) {
4241
+ return (await this.client.delete(`${this.basePath}/${profileId}`)).data;
4242
+ }
4243
+ async transferOwnership(profileId) {
4244
+ return (await this.client.post(`${this.basePath}/ownership`, { profileId })).data;
4245
+ }
4246
+ };
4247
+ //#endregion
4248
+ //#region ../sdk/src/endpoints/history.ts
4249
+ var HistoryEndpoint = class {
4250
+ client;
4251
+ constructor(client) {
4252
+ this.client = client;
4253
+ }
4254
+ get basePath() {
4255
+ return `${this.client.siteBasePath}/history/snapshots`;
4256
+ }
4257
+ async list(limit) {
4258
+ const query = limit === void 0 ? "" : `?limit=${encodeURIComponent(String(limit))}`;
4259
+ return (await this.client.get(`${this.basePath}${query}`)).data;
4260
+ }
4261
+ async get(snapshotId) {
4262
+ return (await this.client.get(`${this.basePath}/${snapshotId}`)).data;
4263
+ }
4264
+ async restore(snapshotId) {
4265
+ return (await this.client.post(`${this.basePath}/${snapshotId}/restore`)).data;
4266
+ }
4267
+ };
4268
+ //#endregion
4133
4269
  //#region ../sdk/src/client.ts
4134
4270
  /**
4135
4271
  * @neopress/sdk — API Client
@@ -4154,6 +4290,11 @@ var NeopressClient = class {
4154
4290
  templates;
4155
4291
  headshots;
4156
4292
  logos;
4293
+ domains;
4294
+ searchConsole;
4295
+ billing;
4296
+ team;
4297
+ history;
4157
4298
  constructor(options) {
4158
4299
  this.baseUrl = (options.baseUrl || "https://app.neopress.ai").replace(/\/$/, "");
4159
4300
  this.accessToken = options.accessToken || "";
@@ -4172,6 +4313,11 @@ var NeopressClient = class {
4172
4313
  this.templates = new TemplatesEndpoint(this);
4173
4314
  this.headshots = new HeadshotsEndpoint(this);
4174
4315
  this.logos = new LogosEndpoint(this);
4316
+ this.domains = new DomainsEndpoint(this);
4317
+ this.searchConsole = new SearchConsoleConnectionEndpoint(this);
4318
+ this.billing = new BillingEndpoint(this);
4319
+ this.team = new TeamEndpoint(this);
4320
+ this.history = new HistoryEndpoint(this);
4175
4321
  }
4176
4322
  get siteBasePath() {
4177
4323
  return `/api/v1/sites/${this.siteId}`;
@@ -4221,8 +4367,8 @@ var NeopressClient = class {
4221
4367
  async patch(path, body) {
4222
4368
  return this.request("PATCH", path, body);
4223
4369
  }
4224
- async delete(path) {
4225
- return this.request("DELETE", path);
4370
+ async delete(path, body) {
4371
+ return this.request("DELETE", path, body);
4226
4372
  }
4227
4373
  };
4228
4374
  //#endregion
@@ -4685,6 +4831,16 @@ Returns submitted responses newest-first, paginated (--page/--limit, default pag
4685
4831
  limit: parseInt(options.limit, 10)
4686
4832
  }));
4687
4833
  });
4834
+ forms.command("response-get <formId> <responseId>").description("Get one form response").action(async (formId, responseId) => {
4835
+ output(await (await getClientAsync()).forms.getResponse(parseInt(formId, 10), parseInt(responseId, 10)));
4836
+ });
4837
+ forms.command("response-mark-read <formId> <responseId>").description("Mark one form response as read").action(async (formId, responseId) => {
4838
+ output(await (await getClientAsync()).forms.markResponseRead(parseInt(formId, 10), parseInt(responseId, 10)));
4839
+ });
4840
+ forms.command("response-delete <formId> <responseId>").description("Delete one form response").action(async (formId, responseId) => {
4841
+ await (await getClientAsync()).forms.deleteResponse(parseInt(formId, 10), parseInt(responseId, 10));
4842
+ ok(`Form response ${responseId} deleted`);
4843
+ });
4688
4844
  forms.command("delete <formId>").description("Delete a form").action(async (formId) => {
4689
4845
  await (await getClientAsync()).forms.delete(parseInt(formId, 10));
4690
4846
  ok(`Form ${formId} deleted`);
@@ -4750,15 +4906,24 @@ Examples:
4750
4906
  //#endregion
4751
4907
  //#region src/commands/publish.ts
4752
4908
  function registerPublishCommands(program) {
4753
- program.command("publish").description("Publish site or preview changes").addHelpText("after", `
4909
+ const publish = program.command("publish").description("Publish site or preview changes").option("--selection <json>", "Selective publish JSON or @file path").addHelpText("after", `
4754
4910
  Examples:
4755
4911
  $ neopress publish preview Show what would change
4756
- $ neopress publish Publish all pending changes live`).action(async () => {
4757
- output(await (await getClientAsync()).publish.site());
4912
+ $ neopress publish Publish all pending changes live`).action(async (options) => {
4913
+ const client = await getClientAsync();
4914
+ const selection = options.selection ? JSON.parse(String(options.selection).startsWith("@") ? (0, node_fs.readFileSync)(String(options.selection).slice(1), "utf8") : String(options.selection)) : void 0;
4915
+ output(await client.publish.site(selection));
4758
4916
  if (!isJsonMode()) ok("Site published");
4759
- }).command("preview").description("Preview pending publish changes").action(async () => {
4917
+ });
4918
+ publish.command("preview").description("Preview pending publish changes").action(async () => {
4760
4919
  output(await (await getClientAsync()).publish.preview());
4761
4920
  });
4921
+ publish.command("unpublish-pages <pageIds...>").description("Remove exact page IDs from production").action(async (pageIds) => {
4922
+ output(await (await getClientAsync()).publish.unpublishPages(pageIds.map(Number)));
4923
+ });
4924
+ publish.command("undeploy").description("Take the whole site offline").action(async () => {
4925
+ output(await (await getClientAsync()).publish.undeploy());
4926
+ });
4762
4927
  }
4763
4928
  //#endregion
4764
4929
  //#region src/commands/redirects.ts
@@ -4983,6 +5148,13 @@ Funnel input has name, ordered steps using eventId, and windowMode/windowHours.
4983
5148
  funnels.command("get <funnelId>").description("Get a saved analytics funnel").action(async (funnelId) => {
4984
5149
  output(await (await getClientAsync()).analytics.funnels.get(funnelId));
4985
5150
  });
5151
+ funnels.command("results <funnelId>").description("Get aggregate results for a saved funnel").option("--date-from <date>", "Start date in YYYY-MM-DD").option("--date-to <date>", "End date in YYYY-MM-DD").option("--timezone <timezone>", "IANA reporting timezone").action(async (funnelId, options) => {
5152
+ output(await (await getClientAsync()).analytics.funnels.results(funnelId, {
5153
+ dateFrom: options.dateFrom,
5154
+ dateTo: options.dateTo,
5155
+ timezone: options.timezone
5156
+ }));
5157
+ });
4986
5158
  funnels.command("create").description("Create a saved analytics funnel").requiredOption("--data <json>", "Funnel definition JSON or @file path").action(async (options) => {
4987
5159
  output(await (await getClientAsync()).analytics.funnels.create(parseDefinitionInput(options.data, "--data")));
4988
5160
  });
@@ -5386,6 +5558,102 @@ function registerGuideCommands(program) {
5386
5558
  });
5387
5559
  }
5388
5560
  //#endregion
5561
+ //#region src/commands/domains.ts
5562
+ function registerDomainCommands(program) {
5563
+ const domains = program.command("domains").description("Manage the site's custom domain");
5564
+ domains.command("status").description("Get custom-domain status").action(async () => {
5565
+ output(await (await getClientAsync()).domains.status());
5566
+ });
5567
+ domains.command("connect <domain>").description("Connect a custom domain").action(async (domain) => output(await (await getClientAsync()).domains.connect(domain)));
5568
+ domains.command("refresh").description("Refresh DNS verification status").action(async () => {
5569
+ output(await (await getClientAsync()).domains.refresh());
5570
+ });
5571
+ domains.command("remove <domain>").description("Remove the exact currently connected domain").addHelpText("after", `
5572
+ Examples:
5573
+ $ neopress domains status
5574
+ $ neopress domains remove example.com
5575
+ Pass the exact domain returned by status so a concurrent replacement cannot be removed.`).action(async (domain) => output(await (await getClientAsync()).domains.remove(domain)));
5576
+ }
5577
+ //#endregion
5578
+ //#region src/commands/search-console.ts
5579
+ function registerSearchConsoleCommands(program) {
5580
+ const searchConsole = program.command("search-console").description("Manage the site's Google Search Console connection");
5581
+ searchConsole.command("status").description("Get connection status").action(async () => {
5582
+ output(await (await getClientAsync()).searchConsole.status());
5583
+ });
5584
+ searchConsole.command("authorize").description("Create an OAuth authorization URL").option("--locale <locale>", "Dashboard locale for the OAuth return flow").action(async (options) => {
5585
+ output(await (await getClientAsync()).searchConsole.authorize(options.locale));
5586
+ });
5587
+ searchConsole.command("disconnect").description("Disconnect Search Console").action(async () => {
5588
+ output(await (await getClientAsync()).searchConsole.disconnect());
5589
+ });
5590
+ }
5591
+ //#endregion
5592
+ //#region src/commands/billing.ts
5593
+ function registerBillingCommands(program) {
5594
+ const billing = program.command("billing").description("Manage owner-only billing handoffs");
5595
+ billing.command("status").description("Get plan and subscription status").action(async () => {
5596
+ output(await (await getClientAsync()).billing.status());
5597
+ });
5598
+ billing.command("checkout <plan>").description("Create a checkout URL for launch or growth").action(async (plan) => {
5599
+ if (plan !== "launch" && plan !== "growth") fail("Plan must be launch or growth.");
5600
+ output(await (await getClientAsync()).billing.checkout(plan));
5601
+ });
5602
+ billing.command("portal").description("Create a customer-portal URL").action(async () => {
5603
+ output(await (await getClientAsync()).billing.portal());
5604
+ });
5605
+ billing.command("cancel").description("Cancel at the end of the billing period").action(async () => {
5606
+ output(await (await getClientAsync()).billing.cancel());
5607
+ });
5608
+ billing.command("resume").description("Remove scheduled cancellation").action(async () => {
5609
+ output(await (await getClientAsync()).billing.resume());
5610
+ });
5611
+ }
5612
+ //#endregion
5613
+ //#region src/commands/team.ts
5614
+ function role(value) {
5615
+ if (value !== "admin" && value !== "editor" && value !== "viewer") fail("Role must be admin, editor, or viewer.");
5616
+ return value;
5617
+ }
5618
+ function registerTeamCommands(program) {
5619
+ const team = program.command("team").description("Manage project members and invitations");
5620
+ team.command("list").description("List active members and pending invitations").action(async () => {
5621
+ output(await (await getClientAsync()).team.list());
5622
+ });
5623
+ team.command("invite <email>").description("Invite a member").requiredOption("--role <role>", "admin, editor, or viewer").option("--locale <locale>", "Invitation email locale").action(async (email, options) => {
5624
+ output(await (await getClientAsync()).team.invite({
5625
+ email,
5626
+ role: role(options.role),
5627
+ locale: options.locale
5628
+ }));
5629
+ });
5630
+ team.command("update-role <profileId>").description("Change a member's role preset").requiredOption("--role <role>", "admin, editor, or viewer").action(async (profileId, options) => {
5631
+ output(await (await getClientAsync()).team.updateRole(profileId, role(options.role)));
5632
+ });
5633
+ team.command("remove <profileId>").description("Remove a member").action(async (profileId) => output(await (await getClientAsync()).team.remove(profileId)));
5634
+ team.command("transfer-ownership <profileId>").description("Transfer ownership to an active member").action(async (profileId) => {
5635
+ output(await (await getClientAsync()).team.transferOwnership(profileId));
5636
+ });
5637
+ }
5638
+ //#endregion
5639
+ //#region src/commands/history.ts
5640
+ function registerHistoryCommands(program) {
5641
+ const history = program.command("history").description("Inspect and restore entity snapshots");
5642
+ history.command("list").description("List restorable snapshots").option("--limit <n>", "Maximum snapshots", "20").action(async (options) => {
5643
+ output(await (await getClientAsync()).history.list(Number(options.limit)));
5644
+ });
5645
+ history.command("get <snapshotId>").description("Get one snapshot").action(async (snapshotId) => {
5646
+ output(await (await getClientAsync()).history.get(Number(snapshotId)));
5647
+ });
5648
+ history.command("restore <snapshotId>").description("Restore an exact page, layout, collection, or form snapshot").addHelpText("after", `
5649
+ Examples:
5650
+ $ neopress history list
5651
+ $ neopress history restore 123
5652
+ Restore changes draft state; page visibility and form settings may affect live behavior immediately.`).action(async (snapshotId) => {
5653
+ output(await (await getClientAsync()).history.restore(Number(snapshotId)));
5654
+ });
5655
+ }
5656
+ //#endregion
5389
5657
  //#region src/bin.ts
5390
5658
  /**
5391
5659
  * @neopress/cli — Neopress CLI
@@ -5394,7 +5662,7 @@ function registerGuideCommands(program) {
5394
5662
  * Designed for use with Claude Code and other AI tools via --json mode.
5395
5663
  */
5396
5664
  const program = new Command();
5397
- program.name("neopress").description("Neopress CLI — manage your site from the terminal").version("4.10.1").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) => {
5665
+ program.name("neopress").description("Neopress CLI — manage your site from the terminal").version("4.11.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) => {
5398
5666
  const opts = thisCommand.optsWithGlobals();
5399
5667
  if (opts.site) setSiteOverride(String(opts.site));
5400
5668
  if (opts.json || !process.stdout.isTTY) setJsonMode(true);
@@ -5414,6 +5682,11 @@ registerAnalyticsCommands(program);
5414
5682
  registerTemplateCommands(program);
5415
5683
  registerHeadshotCommands(program);
5416
5684
  registerLogoCommands(program);
5685
+ registerDomainCommands(program);
5686
+ registerSearchConsoleCommands(program);
5687
+ registerBillingCommands(program);
5688
+ registerTeamCommands(program);
5689
+ registerHistoryCommands(program);
5417
5690
  registerGuideCommands(program);
5418
5691
  program.addHelpText("after", `
5419
5692
  Quickstart:
package/dist/index.d.ts CHANGED
@@ -560,6 +560,11 @@ declare class FormsEndpoint {
560
560
  limit?: number;
561
561
  }): Promise<PaginatedResponse<FormResponse>>;
562
562
  deleteResponse(formId: number, responseId: number): Promise<void>;
563
+ getResponse(formId: number, responseId: number): Promise<FormResponse>;
564
+ markResponseRead(formId: number, responseId: number): Promise<{
565
+ id: number;
566
+ readAt: string;
567
+ }>;
563
568
  }
564
569
  //#endregion
565
570
  //#region ../sdk/src/endpoints/assets.d.ts
@@ -683,11 +688,19 @@ declare class RedirectsEndpoint {
683
688
  }
684
689
  //#endregion
685
690
  //#region ../sdk/src/endpoints/publish.d.ts
691
+ interface PublishSelection {
692
+ pageIds?: number[];
693
+ collectionIds?: number[];
694
+ formIds?: number[];
695
+ includeLayout?: boolean;
696
+ }
686
697
  declare class PublishEndpoint {
687
698
  private readonly client;
688
699
  constructor(client: NeopressClient);
689
700
  preview(): Promise<unknown>;
690
- site(): Promise<unknown>;
701
+ site(selection?: PublishSelection): Promise<unknown>;
702
+ unpublishPages(pageIds: number[]): Promise<unknown>;
703
+ undeploy(): Promise<unknown>;
691
704
  }
692
705
  //#endregion
693
706
  //#region ../sdk/src/endpoints/entry-references.d.ts
@@ -750,6 +763,7 @@ declare class AnalyticsFunnelsEndpoint {
750
763
  create(data: AnalyticsFunnelDefinitionInput): Promise<AnalyticsFunnelDefinition>;
751
764
  update(funnelId: string, data: AnalyticsFunnelDefinitionInput): Promise<AnalyticsFunnelDefinition>;
752
765
  delete(funnelId: string): Promise<void>;
766
+ results(funnelId: string, params?: Pick<AnalyticsDateRangeParams, "dateFrom" | "dateTo" | "timezone">): Promise<AnalyticsQueryResult>;
753
767
  }
754
768
  //#endregion
755
769
  //#region ../sdk/src/endpoints/templates.d.ts
@@ -934,6 +948,139 @@ declare class LogosEndpoint {
934
948
  delete(id: number): Promise<LogoDeleteResult>;
935
949
  }
936
950
  //#endregion
951
+ //#region ../sdk/src/endpoints/domains.d.ts
952
+ interface DomainStatus {
953
+ domain: string | null;
954
+ domainType: string | null;
955
+ verified: boolean | null;
956
+ }
957
+ declare class DomainsEndpoint {
958
+ private readonly client;
959
+ constructor(client: NeopressClient);
960
+ private get basePath();
961
+ status(): Promise<DomainStatus>;
962
+ connect(domain: string): Promise<DomainStatus>;
963
+ refresh(): Promise<DomainStatus & Record<string, unknown>>;
964
+ remove(domain: string): Promise<{
965
+ removedDomain: string;
966
+ removedFromProvider: boolean;
967
+ providerError: string | null;
968
+ }>;
969
+ }
970
+ //#endregion
971
+ //#region ../sdk/src/endpoints/search-console.d.ts
972
+ interface SearchConsoleConnectionStatus {
973
+ authorized: boolean;
974
+ connected: boolean;
975
+ propertyUrl: string | null;
976
+ status: string | null;
977
+ disconnectReason: string | null;
978
+ provisioning: unknown;
979
+ }
980
+ declare class SearchConsoleConnectionEndpoint {
981
+ private readonly client;
982
+ constructor(client: NeopressClient);
983
+ private get basePath();
984
+ status(): Promise<SearchConsoleConnectionStatus>;
985
+ authorize(locale?: string): Promise<{
986
+ authorizationUrl: string;
987
+ requiresUserAction: true;
988
+ }>;
989
+ disconnect(): Promise<{
990
+ disconnected: true;
991
+ }>;
992
+ }
993
+ //#endregion
994
+ //#region ../sdk/src/endpoints/billing.d.ts
995
+ interface BillingStatus {
996
+ planKey: string | null;
997
+ customTrialEndsAt: string | null;
998
+ prepaidGrowthEndsAt: string | null;
999
+ subscription: {
1000
+ status: string | null;
1001
+ cancelAtPeriodEnd: boolean | null;
1002
+ currentPeriodStart: string | null;
1003
+ currentPeriodEnd: string | null;
1004
+ } | null;
1005
+ }
1006
+ declare class BillingEndpoint {
1007
+ private readonly client;
1008
+ constructor(client: NeopressClient);
1009
+ private get basePath();
1010
+ status(): Promise<BillingStatus>;
1011
+ checkout(plan: "launch" | "growth"): Promise<{
1012
+ checkoutUrl: string;
1013
+ requiresUserAction: true;
1014
+ }>;
1015
+ portal(): Promise<{
1016
+ portalUrl: string;
1017
+ requiresUserAction: true;
1018
+ }>;
1019
+ cancel(): Promise<{
1020
+ cancelAtPeriodEnd: boolean;
1021
+ effectiveAt: string | null;
1022
+ }>;
1023
+ resume(): Promise<{
1024
+ cancelAtPeriodEnd: boolean;
1025
+ effectiveAt: string | null;
1026
+ }>;
1027
+ }
1028
+ //#endregion
1029
+ //#region ../sdk/src/endpoints/team.d.ts
1030
+ type TeamRole = "admin" | "editor" | "viewer";
1031
+ interface TeamListResult {
1032
+ members: unknown[];
1033
+ invitations: unknown[];
1034
+ }
1035
+ declare class TeamEndpoint {
1036
+ private readonly client;
1037
+ constructor(client: NeopressClient);
1038
+ private get basePath();
1039
+ list(): Promise<TeamListResult>;
1040
+ invite(input: {
1041
+ email: string;
1042
+ role: TeamRole;
1043
+ locale?: string;
1044
+ }): Promise<unknown>;
1045
+ updateRole(profileId: string, role: TeamRole): Promise<{
1046
+ updated: true;
1047
+ }>;
1048
+ remove(profileId: string): Promise<{
1049
+ removed: true;
1050
+ }>;
1051
+ transferOwnership(profileId: string): Promise<{
1052
+ transferred: true;
1053
+ alreadyTransferred?: true;
1054
+ }>;
1055
+ }
1056
+ //#endregion
1057
+ //#region ../sdk/src/endpoints/history.d.ts
1058
+ interface EntitySnapshotSummary {
1059
+ id: number;
1060
+ entityType: "page" | "site_layout" | "collection" | "form";
1061
+ entityId: number;
1062
+ createdAt: string;
1063
+ }
1064
+ interface EntitySnapshot extends EntitySnapshotSummary {
1065
+ data: unknown;
1066
+ }
1067
+ declare class HistoryEndpoint {
1068
+ private readonly client;
1069
+ constructor(client: NeopressClient);
1070
+ private get basePath();
1071
+ list(limit?: number): Promise<{
1072
+ snapshots: EntitySnapshotSummary[];
1073
+ hasMore: boolean;
1074
+ }>;
1075
+ get(snapshotId: number): Promise<EntitySnapshot>;
1076
+ restore(snapshotId: number): Promise<{
1077
+ restored: true;
1078
+ snapshotId: number;
1079
+ entityType: string;
1080
+ entityId: number;
1081
+ }>;
1082
+ }
1083
+ //#endregion
937
1084
  //#region ../sdk/src/client.d.ts
938
1085
  /**
939
1086
  * ⚠️ No `supabaseUrl` / `supabaseAnonKey`. This client speaks HTTP to
@@ -971,6 +1118,11 @@ declare class NeopressClient {
971
1118
  readonly templates: TemplatesEndpoint;
972
1119
  readonly headshots: HeadshotsEndpoint;
973
1120
  readonly logos: LogosEndpoint;
1121
+ readonly domains: DomainsEndpoint;
1122
+ readonly searchConsole: SearchConsoleConnectionEndpoint;
1123
+ readonly billing: BillingEndpoint;
1124
+ readonly team: TeamEndpoint;
1125
+ readonly history: HistoryEndpoint;
974
1126
  constructor(options: NeopressClientOptions);
975
1127
  get siteBasePath(): string;
976
1128
  request<T>(method: string, path: string, body?: unknown): Promise<T>;
@@ -978,7 +1130,7 @@ declare class NeopressClient {
978
1130
  getList<T>(path: string): Promise<PaginatedResponse<T>>;
979
1131
  post<T>(path: string, body?: unknown): Promise<ApiResponse<T>>;
980
1132
  patch<T>(path: string, body: unknown): Promise<ApiResponse<T>>;
981
- delete<T>(path: string): Promise<ApiResponse<T>>;
1133
+ delete<T>(path: string, body?: unknown): Promise<ApiResponse<T>>;
982
1134
  }
983
1135
  //#endregion
984
1136
  //#region src/utils/client.d.ts
package/dist/index.js CHANGED
@@ -245,6 +245,12 @@ var FormsEndpoint = class {
245
245
  async deleteResponse(formId, responseId) {
246
246
  await this.client.delete(`${this.basePath}/${formId}/responses/${responseId}`);
247
247
  }
248
+ async getResponse(formId, responseId) {
249
+ return (await this.client.get(`${this.basePath}/${formId}/responses/${responseId}`)).data;
250
+ }
251
+ async markResponseRead(formId, responseId) {
252
+ return (await this.client.patch(`${this.basePath}/${formId}/responses/${responseId}`, { read: true })).data;
253
+ }
248
254
  };
249
255
  //#endregion
250
256
  //#region ../sdk/src/endpoints/assets.ts
@@ -392,8 +398,14 @@ var PublishEndpoint = class {
392
398
  async preview() {
393
399
  return (await this.client.get(`${this.client.siteBasePath}/publish`)).data;
394
400
  }
395
- async site() {
396
- return (await this.client.post(`${this.client.siteBasePath}/publish`)).data;
401
+ async site(selection) {
402
+ return (await this.client.post(`${this.client.siteBasePath}/publish`, selection ? { selection } : void 0)).data;
403
+ }
404
+ async unpublishPages(pageIds) {
405
+ return (await this.client.patch(`${this.client.siteBasePath}/publish`, { pageIds })).data;
406
+ }
407
+ async undeploy() {
408
+ return (await this.client.delete(`${this.client.siteBasePath}/publish`)).data;
397
409
  }
398
410
  };
399
411
  //#endregion
@@ -561,6 +573,14 @@ var AnalyticsFunnelsEndpoint = class {
561
573
  async delete(funnelId) {
562
574
  await this.client.delete(`${this.basePath}/${funnelId}`);
563
575
  }
576
+ async results(funnelId, params) {
577
+ const query = new URLSearchParams();
578
+ if (params?.dateFrom) query.set("dateFrom", params.dateFrom);
579
+ if (params?.dateTo) query.set("dateTo", params.dateTo);
580
+ if (params?.timezone) query.set("timezone", params.timezone);
581
+ const suffix = query.size > 0 ? `?${query.toString()}` : "";
582
+ return (await this.client.get(`${this.basePath}/${funnelId}/results${suffix}`)).data;
583
+ }
564
584
  };
565
585
  //#endregion
566
586
  //#region ../sdk/src/endpoints/templates.ts
@@ -689,6 +709,122 @@ var LogosEndpoint = class {
689
709
  }
690
710
  };
691
711
  //#endregion
712
+ //#region ../sdk/src/endpoints/domains.ts
713
+ var DomainsEndpoint = class {
714
+ client;
715
+ constructor(client) {
716
+ this.client = client;
717
+ }
718
+ get basePath() {
719
+ return `${this.client.siteBasePath}/domains`;
720
+ }
721
+ async status() {
722
+ return (await this.client.get(this.basePath)).data;
723
+ }
724
+ async connect(domain) {
725
+ return (await this.client.post(this.basePath, { domain })).data;
726
+ }
727
+ async refresh() {
728
+ return (await this.client.patch(this.basePath, {})).data;
729
+ }
730
+ async remove(domain) {
731
+ return (await this.client.delete(this.basePath, { domain })).data;
732
+ }
733
+ };
734
+ //#endregion
735
+ //#region ../sdk/src/endpoints/search-console.ts
736
+ var SearchConsoleConnectionEndpoint = class {
737
+ client;
738
+ constructor(client) {
739
+ this.client = client;
740
+ }
741
+ get basePath() {
742
+ return `${this.client.siteBasePath}/search-console`;
743
+ }
744
+ async status() {
745
+ return (await this.client.get(this.basePath)).data;
746
+ }
747
+ async authorize(locale) {
748
+ return (await this.client.post(this.basePath, locale ? { locale } : {})).data;
749
+ }
750
+ async disconnect() {
751
+ return (await this.client.delete(this.basePath)).data;
752
+ }
753
+ };
754
+ //#endregion
755
+ //#region ../sdk/src/endpoints/billing.ts
756
+ var BillingEndpoint = class {
757
+ client;
758
+ constructor(client) {
759
+ this.client = client;
760
+ }
761
+ get basePath() {
762
+ return `${this.client.siteBasePath}/billing`;
763
+ }
764
+ async status() {
765
+ return (await this.client.get(this.basePath)).data;
766
+ }
767
+ async checkout(plan) {
768
+ return (await this.client.post(`${this.basePath}/checkout`, { plan })).data;
769
+ }
770
+ async portal() {
771
+ return (await this.client.post(`${this.basePath}/portal`)).data;
772
+ }
773
+ async cancel() {
774
+ return (await this.client.post(`${this.basePath}/subscription/cancel`)).data;
775
+ }
776
+ async resume() {
777
+ return (await this.client.post(`${this.basePath}/subscription/resume`)).data;
778
+ }
779
+ };
780
+ //#endregion
781
+ //#region ../sdk/src/endpoints/team.ts
782
+ var TeamEndpoint = class {
783
+ client;
784
+ constructor(client) {
785
+ this.client = client;
786
+ }
787
+ get basePath() {
788
+ return `${this.client.siteBasePath}/team`;
789
+ }
790
+ async list() {
791
+ return (await this.client.get(this.basePath)).data;
792
+ }
793
+ async invite(input) {
794
+ return (await this.client.post(this.basePath, input)).data;
795
+ }
796
+ async updateRole(profileId, role) {
797
+ return (await this.client.patch(`${this.basePath}/${profileId}`, { role })).data;
798
+ }
799
+ async remove(profileId) {
800
+ return (await this.client.delete(`${this.basePath}/${profileId}`)).data;
801
+ }
802
+ async transferOwnership(profileId) {
803
+ return (await this.client.post(`${this.basePath}/ownership`, { profileId })).data;
804
+ }
805
+ };
806
+ //#endregion
807
+ //#region ../sdk/src/endpoints/history.ts
808
+ var HistoryEndpoint = class {
809
+ client;
810
+ constructor(client) {
811
+ this.client = client;
812
+ }
813
+ get basePath() {
814
+ return `${this.client.siteBasePath}/history/snapshots`;
815
+ }
816
+ async list(limit) {
817
+ const query = limit === void 0 ? "" : `?limit=${encodeURIComponent(String(limit))}`;
818
+ return (await this.client.get(`${this.basePath}${query}`)).data;
819
+ }
820
+ async get(snapshotId) {
821
+ return (await this.client.get(`${this.basePath}/${snapshotId}`)).data;
822
+ }
823
+ async restore(snapshotId) {
824
+ return (await this.client.post(`${this.basePath}/${snapshotId}/restore`)).data;
825
+ }
826
+ };
827
+ //#endregion
692
828
  //#region ../sdk/src/client.ts
693
829
  /**
694
830
  * @neopress/sdk — API Client
@@ -713,6 +849,11 @@ var NeopressClient = class {
713
849
  templates;
714
850
  headshots;
715
851
  logos;
852
+ domains;
853
+ searchConsole;
854
+ billing;
855
+ team;
856
+ history;
716
857
  constructor(options) {
717
858
  this.baseUrl = (options.baseUrl || "https://app.neopress.ai").replace(/\/$/, "");
718
859
  this.accessToken = options.accessToken || "";
@@ -731,6 +872,11 @@ var NeopressClient = class {
731
872
  this.templates = new TemplatesEndpoint(this);
732
873
  this.headshots = new HeadshotsEndpoint(this);
733
874
  this.logos = new LogosEndpoint(this);
875
+ this.domains = new DomainsEndpoint(this);
876
+ this.searchConsole = new SearchConsoleConnectionEndpoint(this);
877
+ this.billing = new BillingEndpoint(this);
878
+ this.team = new TeamEndpoint(this);
879
+ this.history = new HistoryEndpoint(this);
734
880
  }
735
881
  get siteBasePath() {
736
882
  return `/api/v1/sites/${this.siteId}`;
@@ -780,8 +926,8 @@ var NeopressClient = class {
780
926
  async patch(path, body) {
781
927
  return this.request("PATCH", path, body);
782
928
  }
783
- async delete(path) {
784
- return this.request("DELETE", path);
929
+ async delete(path, body) {
930
+ return this.request("DELETE", path, body);
785
931
  }
786
932
  };
787
933
  //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neopress/cli",
3
- "version": "4.10.1",
3
+ "version": "4.11.0",
4
4
  "description": "Neopress CLI — manage your Neopress site from the terminal",
5
5
  "type": "module",
6
6
  "keywords": [