@paragraph-com/cli 0.1.1 → 0.2.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.
Files changed (2) hide show
  1. package/dist/index.js +704 -35
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -980,7 +980,7 @@ var require_command = __commonJS({
980
980
  var EventEmitter = __require("events").EventEmitter;
981
981
  var childProcess = __require("child_process");
982
982
  var path2 = __require("path");
983
- var fs6 = __require("fs");
983
+ var fs8 = __require("fs");
984
984
  var process2 = __require("process");
985
985
  var { Argument: Argument2, humanReadableArgName } = require_argument();
986
986
  var { CommanderError: CommanderError2 } = require_error();
@@ -1913,10 +1913,10 @@ Expecting one of '${allowedValues.join("', '")}'`);
1913
1913
  const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
1914
1914
  function findFile(baseDir, baseName) {
1915
1915
  const localBin = path2.resolve(baseDir, baseName);
1916
- if (fs6.existsSync(localBin)) return localBin;
1916
+ if (fs8.existsSync(localBin)) return localBin;
1917
1917
  if (sourceExt.includes(path2.extname(baseName))) return void 0;
1918
1918
  const foundExt = sourceExt.find(
1919
- (ext) => fs6.existsSync(`${localBin}${ext}`)
1919
+ (ext) => fs8.existsSync(`${localBin}${ext}`)
1920
1920
  );
1921
1921
  if (foundExt) return `${localBin}${foundExt}`;
1922
1922
  return void 0;
@@ -1928,7 +1928,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1928
1928
  if (this._scriptPath) {
1929
1929
  let resolvedScriptPath;
1930
1930
  try {
1931
- resolvedScriptPath = fs6.realpathSync(this._scriptPath);
1931
+ resolvedScriptPath = fs8.realpathSync(this._scriptPath);
1932
1932
  } catch (err) {
1933
1933
  resolvedScriptPath = this._scriptPath;
1934
1934
  }
@@ -3266,7 +3266,7 @@ async function loadSellPeers() {
3266
3266
  throw err;
3267
3267
  }
3268
3268
  }
3269
- var BASE_URL, currentApiKey, setCurrentApiKey, ParagraphApiError, customAxios, getParagraphAPI, QueryResult, executeAbi, permit2Abi, AuthResource, MISSING_COIN_PEERS_MESSAGE, CoinsResource, FeedResource, MeResource, PostsResource, PublicationsResource, SearchResource, SubscribersResource, UsersResource, ParagraphAPI;
3269
+ var BASE_URL, currentApiKey, setCurrentApiKey, ParagraphApiError, customAxios, getParagraphAPI, QueryResult, executeAbi, permit2Abi, AnalyticsResource, AuthResource, MISSING_COIN_PEERS_MESSAGE, CoinsResource, FeedResource, MeResource, PostsResource, PublicationsResource, SearchResource, SubscribersResource, UsersResource, ParagraphAPI;
3270
3270
  var init_dist = __esm({
3271
3271
  "node_modules/@paragraph-com/sdk/dist/index.mjs"() {
3272
3272
  "use strict";
@@ -3330,6 +3330,16 @@ var init_dist = __esm({
3330
3330
  }
3331
3331
  );
3332
3332
  };
3333
+ const updatePublication2 = (publicationId, updatePublicationBody2) => {
3334
+ return customAxios(
3335
+ {
3336
+ url: `/v1/publications/${publicationId}`,
3337
+ method: "PATCH",
3338
+ headers: { "Content-Type": "application/json" },
3339
+ data: updatePublicationBody2
3340
+ }
3341
+ );
3342
+ };
3333
3343
  const getPublicationBySlug = (slug) => {
3334
3344
  return customAxios(
3335
3345
  {
@@ -3621,6 +3631,16 @@ var init_dist = __esm({
3621
3631
  }
3622
3632
  );
3623
3633
  };
3634
+ const removeSubscriber2 = (removeSubscriberBody2) => {
3635
+ return customAxios(
3636
+ {
3637
+ url: `/v1/subscribers`,
3638
+ method: "DELETE",
3639
+ headers: { "Content-Type": "application/json" },
3640
+ data: removeSubscriberBody2
3641
+ }
3642
+ );
3643
+ };
3624
3644
  const listSubscribers2 = (params) => {
3625
3645
  return customAxios(
3626
3646
  {
@@ -3657,6 +3677,24 @@ var init_dist = __esm({
3657
3677
  }
3658
3678
  );
3659
3679
  };
3680
+ const analyticsQuery = (analyticsQueryBody2) => {
3681
+ return customAxios(
3682
+ {
3683
+ url: `/v1/analytics/query`,
3684
+ method: "POST",
3685
+ headers: { "Content-Type": "application/json" },
3686
+ data: analyticsQueryBody2
3687
+ }
3688
+ );
3689
+ };
3690
+ const analyticsSchema = () => {
3691
+ return customAxios(
3692
+ {
3693
+ url: `/v1/analytics/schema`,
3694
+ method: "GET"
3695
+ }
3696
+ );
3697
+ };
3660
3698
  const createAuthSession = (createAuthSessionBody2) => {
3661
3699
  return customAxios(
3662
3700
  {
@@ -3683,7 +3721,7 @@ var init_dist = __esm({
3683
3721
  }
3684
3722
  );
3685
3723
  };
3686
- return { getPublicationById, getPublicationBySlug, getPublicationByDomain: getPublicationByDomain2, getSubscriberCount: getSubscriberCount2, getPostsFeed, getPostsByTag: getPostsByTag2, getPosts, getPostById, updatePost: updatePost2, deletePost: deletePost2, getPostByPublicationIdAndPostSlug, getPostByPublicationSlugAndPostSlug, createPost: createPost2, listOwnPosts, updatePostBySlug, deletePostBySlug, sendTestEmail: sendTestEmail2, getMe, getUser: getUser2, getUserByWallet, getCoin: getCoin2, getCoinByContract, getCoinHoldersById, getCoinHoldersByContract, getBuyArgsById, getBuyArgsByContract, getSellArgsById, getSellArgsByContract, getQuoteById, getQuoteByContract, getPopularCoins: getPopularCoins2, importSubscribers: importSubscribers2, addSubscriber: addSubscriber2, listSubscribers: listSubscribers2, searchPosts: searchPosts2, searchBlogs: searchBlogs2, searchCoins: searchCoins2, createAuthSession, getAuthSession, deleteAuthSession };
3724
+ return { getPublicationById, updatePublication: updatePublication2, getPublicationBySlug, getPublicationByDomain: getPublicationByDomain2, getSubscriberCount: getSubscriberCount2, getPostsFeed, getPostsByTag: getPostsByTag2, getPosts, getPostById, updatePost: updatePost2, deletePost: deletePost2, getPostByPublicationIdAndPostSlug, getPostByPublicationSlugAndPostSlug, createPost: createPost2, listOwnPosts, updatePostBySlug, deletePostBySlug, sendTestEmail: sendTestEmail2, getMe, getUser: getUser2, getUserByWallet, getCoin: getCoin2, getCoinByContract, getCoinHoldersById, getCoinHoldersByContract, getBuyArgsById, getBuyArgsByContract, getSellArgsById, getSellArgsByContract, getQuoteById, getQuoteByContract, getPopularCoins: getPopularCoins2, importSubscribers: importSubscribers2, addSubscriber: addSubscriber2, removeSubscriber: removeSubscriber2, listSubscribers: listSubscribers2, searchPosts: searchPosts2, searchBlogs: searchBlogs2, searchCoins: searchCoins2, analyticsQuery, analyticsSchema, createAuthSession, getAuthSession, deleteAuthSession };
3687
3725
  };
3688
3726
  QueryResult = class {
3689
3727
  constructor(promise) {
@@ -3739,6 +3777,99 @@ var init_dist = __esm({
3739
3777
  ]
3740
3778
  }
3741
3779
  ];
3780
+ AnalyticsResource = class {
3781
+ constructor(api) {
3782
+ this.api = api;
3783
+ }
3784
+ /**
3785
+ * Executes a read-only SQL query against the analytics schema for your
3786
+ * publication. The query runs in a transaction scoped to your publication —
3787
+ * you do not need to (and cannot) reference a blog id in the SQL. Requires
3788
+ * an API key.
3789
+ *
3790
+ * **SQL requirements:**
3791
+ * - `SELECT` or `WITH` (CTE) statements only
3792
+ * - Reference tables unprefixed (e.g. `FROM posts`) — the `analytics`
3793
+ * schema is the default `search_path`
3794
+ * - No semicolons, writes, DDL, or superuser functions
3795
+ * - Hard limit of 10,000 rows; excess rows are truncated and
3796
+ * `truncated: true` is returned
3797
+ * - 30-second statement timeout
3798
+ *
3799
+ * Call {@link AnalyticsResource.schema} first if you need to discover the
3800
+ * available tables and columns.
3801
+ *
3802
+ * @example
3803
+ * ```ts
3804
+ * const api = new ParagraphAPI({ apiKey: "your-api-key" });
3805
+ *
3806
+ * // Top 5 posts by views
3807
+ * const { rows } = await api.analytics.query({
3808
+ * sql: `
3809
+ * SELECT title, total_views, open_rate
3810
+ * FROM post_analytics_summary
3811
+ * ORDER BY total_views DESC
3812
+ * LIMIT 5
3813
+ * `,
3814
+ * });
3815
+ * rows.forEach(r => console.log(r.title, r.total_views));
3816
+ *
3817
+ * // Subscriber count
3818
+ * const { rows: [counts] } = await api.analytics.query({
3819
+ * sql: "SELECT active_count FROM blog_subscriber_counts",
3820
+ * });
3821
+ * console.log("Active subscribers:", counts.active_count);
3822
+ *
3823
+ * // Average open rate across the last 30 days
3824
+ * const { rows: [avg] } = await api.analytics.query({
3825
+ * sql: `
3826
+ * SELECT AVG(open_rate) AS avg_open_rate
3827
+ * FROM post_analytics_summary
3828
+ * WHERE published_at > NOW() - INTERVAL '30 days'
3829
+ * `,
3830
+ * });
3831
+ * ```
3832
+ *
3833
+ * @param body - An object containing the SQL string.
3834
+ * @param body.sql - A `SELECT` or `WITH` query against the analytics schema.
3835
+ * @returns A promise that resolves to an object with `rows`, `rowCount`,
3836
+ * `fields` (column names), and `truncated` (whether the 10,000-row cap was hit).
3837
+ */
3838
+ query(body) {
3839
+ return this.api.analyticsQuery(body);
3840
+ }
3841
+ /**
3842
+ * Returns column metadata for every table and view in the analytics schema.
3843
+ * Useful for discovering available tables and columns before writing a query.
3844
+ * Requires an API key.
3845
+ *
3846
+ * @example
3847
+ * ```ts
3848
+ * const api = new ParagraphAPI({ apiKey: "your-api-key" });
3849
+ *
3850
+ * const { tables } = await api.analytics.schema();
3851
+ *
3852
+ * // Group columns by table
3853
+ * const byTable = new Map<string, string[]>();
3854
+ * for (const col of tables) {
3855
+ * const cols = byTable.get(col.table_name) ?? [];
3856
+ * cols.push(`${col.column_name} (${col.data_type})`);
3857
+ * byTable.set(col.table_name, cols);
3858
+ * }
3859
+ * for (const [table, cols] of byTable) {
3860
+ * console.log(`\n${table}:`);
3861
+ * cols.forEach(c => console.log(` - ${c}`));
3862
+ * }
3863
+ * ```
3864
+ *
3865
+ * @returns A promise that resolves to an object with a `tables` array,
3866
+ * where each item describes one column (`table_name`, `column_name`,
3867
+ * `data_type`, `is_nullable`).
3868
+ */
3869
+ schema() {
3870
+ return this.api.analyticsSchema();
3871
+ }
3872
+ };
3742
3873
  AuthResource = class {
3743
3874
  constructor(api) {
3744
3875
  this.api = api;
@@ -4361,6 +4492,12 @@ var init_dist = __esm({
4361
4492
  * id: "postId",
4362
4493
  * scheduledAt: null,
4363
4494
  * });
4495
+ *
4496
+ * // Backdate a post — publishedAt sticks across re-publishes
4497
+ * await api.posts.update({
4498
+ * id: "postId",
4499
+ * publishedAt: new Date("2024-01-01T00:00:00Z").getTime(),
4500
+ * });
4364
4501
  * ```
4365
4502
  *
4366
4503
  * @param params - An object containing either `id` or `slug` to identify the post, plus the fields to update.
@@ -4469,6 +4606,45 @@ var init_dist = __esm({
4469
4606
  }
4470
4607
  throw new Error("Invalid identifier provided to get.");
4471
4608
  }
4609
+ /**
4610
+ * Updates settings for the publication associated with the API key.
4611
+ * Only provided fields are updated; omitted fields remain unchanged.
4612
+ * Requires an API key, and `publicationId` must match the publication that owns the key.
4613
+ *
4614
+ * @example
4615
+ * ```ts
4616
+ * const api = new ParagraphAPI({ apiKey: "your-api-key" });
4617
+ *
4618
+ * // Update name and theme
4619
+ * await api.publications.update("publicationId", {
4620
+ * name: "My Blog",
4621
+ * themeColor: "purple-600",
4622
+ * headerFont: "serif",
4623
+ * });
4624
+ *
4625
+ * // Pin posts to the top of the homepage (replaces the existing pinned list, max 50)
4626
+ * await api.publications.update("publicationId", {
4627
+ * pinnedPostIds: ["postId1", "postId2"],
4628
+ * });
4629
+ *
4630
+ * // Set a featured post — use a post ID, "latest", "popular", or "disabled"
4631
+ * await api.publications.update("publicationId", {
4632
+ * featuredPost: "latest",
4633
+ * });
4634
+ *
4635
+ * // Email notifications are merged onto existing settings; only the toggles you send change
4636
+ * await api.publications.update("publicationId", {
4637
+ * emailNotifications: { newSubscriber: true },
4638
+ * });
4639
+ * ```
4640
+ *
4641
+ * @param publicationId - The unique identifier of the publication to update.
4642
+ * @param body - The fields to update. See {@link UpdatePublicationBody}.
4643
+ * @returns A promise that resolves to the updated publication.
4644
+ */
4645
+ update(publicationId, body) {
4646
+ return this.api.updatePublication(publicationId, body);
4647
+ }
4472
4648
  };
4473
4649
  SearchResource = class {
4474
4650
  constructor(api) {
@@ -4616,6 +4792,35 @@ var init_dist = __esm({
4616
4792
  create(body) {
4617
4793
  return this.api.addSubscriber(body);
4618
4794
  }
4795
+ /**
4796
+ * Removes a subscriber from the publication associated with the API key.
4797
+ * The subscriber is identified by email, wallet, or both. If both are provided,
4798
+ * they must resolve to the same user. This is a hard delete; consider calling
4799
+ * `get()` first to confirm the subscriber exists. Requires an API key.
4800
+ *
4801
+ * @example
4802
+ * ```ts
4803
+ * const api = new ParagraphAPI({ apiKey: "your-api-key" });
4804
+ *
4805
+ * // Remove subscriber by email
4806
+ * await api.subscribers.remove({ email: "user@example.com" });
4807
+ *
4808
+ * // Remove subscriber by wallet
4809
+ * await api.subscribers.remove({ wallet: "0x1234..." });
4810
+ *
4811
+ * // Pass both — must resolve to the same user
4812
+ * await api.subscribers.remove({
4813
+ * email: "user@example.com",
4814
+ * wallet: "0x1234...",
4815
+ * });
4816
+ * ```
4817
+ *
4818
+ * @param body - The subscriber to remove. At least one of email or wallet must be provided.
4819
+ * @returns A promise that resolves to the result of the operation.
4820
+ */
4821
+ remove(body) {
4822
+ return this.api.removeSubscriber(body);
4823
+ }
4619
4824
  /**
4620
4825
  * Imports subscribers from a CSV file into the publication associated with the API key.
4621
4826
  * Requires an API key.
@@ -4686,6 +4891,7 @@ var init_dist = __esm({
4686
4891
  constructor(options) {
4687
4892
  this.apiKey = options?.apiKey;
4688
4893
  this.api = wrapAPIWithAuth(getParagraphAPI(), this.apiKey, setCurrentApiKey);
4894
+ this.analytics = new AnalyticsResource(this.api);
4689
4895
  this.auth = new AuthResource(this.api);
4690
4896
  this.publications = new PublicationsResource(this.api);
4691
4897
  this.subscribers = new SubscribersResource(this.api);
@@ -6906,7 +7112,7 @@ var init_auth2 = __esm({
6906
7112
 
6907
7113
  // node_modules/@paragraph-com/sdk/dist/zod.mjs
6908
7114
  import * as zod from "zod";
6909
- var getPublicationByIdParams, getPublicationByIdResponseSlugMax, getPublicationByIdResponseSummaryMax, getPublicationByIdResponse, getPublicationBySlugPathSlugMax, getPublicationBySlugParams, getPublicationBySlugResponseSlugMax, getPublicationBySlugResponseSummaryMax, getPublicationBySlugResponse, getPublicationByDomainParams, getPublicationByDomainResponseSlugMax, getPublicationByDomainResponseSummaryMax, getPublicationByDomainResponse, getSubscriberCountParams, getSubscriberCountResponse, getPostsFeedQueryLimitDefault, getPostsFeedQueryLimitMax, getPostsFeedQueryParams, getPostsFeedResponseItemsItemPostTitleMax, getPostsFeedResponseItemsItemPostSubtitleMax, getPostsFeedResponseItemsItemPostSlugMax, getPostsFeedResponseItemsItemPostAuthorsItemWalletAddressRegExp, getPostsFeedResponseItemsItemPostAuthorsItemBioMax, getPostsFeedResponseItemsItemPublicationSlugMax, getPostsFeedResponseItemsItemPublicationSummaryMax, getPostsFeedResponseItemsItemUserWalletAddressRegExp, getPostsFeedResponseItemsItemUserBioMax, getPostsFeedResponse, getPostsByTagParams, getPostsByTagQueryLimitDefault, getPostsByTagQueryLimitMax, getPostsByTagQueryParams, getPostsByTagResponseItemsItemTitleMax, getPostsByTagResponseItemsItemSubtitleMax, getPostsByTagResponseItemsItemSlugMax, getPostsByTagResponseItemsItemAuthorsItemWalletAddressRegExp, getPostsByTagResponseItemsItemAuthorsItemBioMax, getPostsByTagResponse, getPostsParams, getPostsQueryLimitDefault, getPostsQueryLimitMax, getPostsQueryParams, getPostsResponseItemsItemTitleMax, getPostsResponseItemsItemSubtitleMax, getPostsResponseItemsItemSlugMax, getPostsResponseItemsItemAuthorsItemWalletAddressRegExp, getPostsResponseItemsItemAuthorsItemBioMax, getPostsResponse, getPostByIdParams, getPostByIdQueryParams, getPostByIdResponseTitleMax, getPostByIdResponseSubtitleMax, getPostByIdResponseSlugMax, getPostByIdResponseAuthorsItemWalletAddressRegExp, getPostByIdResponseAuthorsItemBioMax, getPostByIdResponse, updatePostParams, updatePostBodyTitleMax, updatePostBodySubtitleMax, updatePostBodySlugMax, updatePostBodyPostPreviewMax, updatePostBodyScheduledAtMin, updatePostBody, updatePostResponse, deletePostParams, deletePostBody, deletePostResponse, getPostByPublicationIdAndPostSlugPathPostSlugMax, getPostByPublicationIdAndPostSlugParams, getPostByPublicationIdAndPostSlugQueryParams, getPostByPublicationIdAndPostSlugResponseTitleMax, getPostByPublicationIdAndPostSlugResponseSubtitleMax, getPostByPublicationIdAndPostSlugResponseSlugMax, getPostByPublicationIdAndPostSlugResponseAuthorsItemWalletAddressRegExp, getPostByPublicationIdAndPostSlugResponseAuthorsItemBioMax, getPostByPublicationIdAndPostSlugResponse, getPostByPublicationSlugAndPostSlugPathPublicationSlugMax, getPostByPublicationSlugAndPostSlugPathPostSlugMax, getPostByPublicationSlugAndPostSlugParams, getPostByPublicationSlugAndPostSlugQueryParams, getPostByPublicationSlugAndPostSlugResponseTitleMax, getPostByPublicationSlugAndPostSlugResponseSubtitleMax, getPostByPublicationSlugAndPostSlugResponseSlugMax, getPostByPublicationSlugAndPostSlugResponseAuthorsItemWalletAddressRegExp, getPostByPublicationSlugAndPostSlugResponseAuthorsItemBioMax, getPostByPublicationSlugAndPostSlugResponse, createPostBodyTitleMax, createPostBodySubtitleMax, createPostBodySlugMax, createPostBodyPostPreviewMax, createPostBodyScheduledAtMin, createPostBody, createPostResponse, listOwnPostsQueryLimitDefault, listOwnPostsQueryLimitMax, listOwnPostsQueryParams, listOwnPostsResponseItemsItemTitleMax, listOwnPostsResponseItemsItemSubtitleMax, listOwnPostsResponseItemsItemSlugMax, listOwnPostsResponseItemsItemAuthorsItemWalletAddressRegExp, listOwnPostsResponseItemsItemAuthorsItemBioMax, listOwnPostsResponse, updatePostBySlugPathSlugMax, updatePostBySlugParams, updatePostBySlugBodyTitleMax, updatePostBySlugBodySubtitleMax, updatePostBySlugBodySlugMax, updatePostBySlugBodyPostPreviewMax, updatePostBySlugBodyScheduledAtMin, updatePostBySlugBody, updatePostBySlugResponse, deletePostBySlugPathSlugMax, deletePostBySlugParams, deletePostBySlugBody, deletePostBySlugResponse, sendTestEmailParams, sendTestEmailBody, sendTestEmailResponse, getMeResponseSlugMax, getMeResponseSummaryMax, getMeResponse, getUserParams, getUserResponseWalletAddressRegExp, getUserResponseBioMax, getUserResponse, getUserByWalletPathWalletAddressRegExp, getUserByWalletParams, getUserByWalletResponseWalletAddressRegExp, getUserByWalletResponseBioMax, getUserByWalletResponse, getCoinParams, getCoinResponseContractAddressRegExp, getCoinResponse, getCoinByContractPathContractAddressRegExp, getCoinByContractParams, getCoinByContractResponseContractAddressRegExp, getCoinByContractResponse, getCoinHoldersByIdParams, getCoinHoldersByIdQueryLimitDefault, getCoinHoldersByIdQueryLimitMax, getCoinHoldersByIdQueryParams, getCoinHoldersByIdResponseItemsItemWalletAddressRegExp, getCoinHoldersByIdResponseItemsItemBalanceRegExp, getCoinHoldersByIdResponse, getCoinHoldersByContractPathContractAddressRegExp, getCoinHoldersByContractParams, getCoinHoldersByContractQueryLimitDefault, getCoinHoldersByContractQueryLimitMax, getCoinHoldersByContractQueryParams, getCoinHoldersByContractResponseItemsItemWalletAddressRegExp, getCoinHoldersByContractResponseItemsItemBalanceRegExp, getCoinHoldersByContractResponse, getBuyArgsByIdParams, getBuyArgsByIdQueryWalletAddressRegExp, getBuyArgsByIdQueryAmountRegExp, getBuyArgsByIdQueryParams, getBuyArgsByIdResponseCommandsRegExp, getBuyArgsByIdResponseInputsItemRegExp, getBuyArgsByIdResponse, getBuyArgsByContractPathContractAddressRegExp, getBuyArgsByContractParams, getBuyArgsByContractQueryWalletAddressRegExp, getBuyArgsByContractQueryAmountRegExp, getBuyArgsByContractQueryParams, getBuyArgsByContractResponseCommandsRegExp, getBuyArgsByContractResponseInputsItemRegExp, getBuyArgsByContractResponse, getSellArgsByIdParams, getSellArgsByIdQueryWalletAddressRegExp, getSellArgsByIdQueryAmountRegExp, getSellArgsByIdQueryParams, getSellArgsByIdResponseCommandsRegExp, getSellArgsByIdResponseInputsItemRegExp, getSellArgsByIdResponse, getSellArgsByContractPathContractAddressRegExp, getSellArgsByContractParams, getSellArgsByContractQueryWalletAddressRegExp, getSellArgsByContractQueryAmountRegExp, getSellArgsByContractQueryParams, getSellArgsByContractResponseCommandsRegExp, getSellArgsByContractResponseInputsItemRegExp, getSellArgsByContractResponse, getQuoteByIdParams, getQuoteByIdQueryAmountRegExp, getQuoteByIdQueryParams, getQuoteByIdResponse, getQuoteByContractParams, getQuoteByContractQueryAmountRegExp, getQuoteByContractQueryParams, getQuoteByContractResponse, getPopularCoinsResponseCoinsItemContractAddressRegExp, getPopularCoinsResponse, importSubscribersBody, importSubscribersResponse, addSubscriberBodyWalletRegExp, addSubscriberBody, addSubscriberResponse, listSubscribersQueryLimitDefault, listSubscribersQueryLimitMax, listSubscribersQueryParams, listSubscribersResponseItemsItemWalletAddressRegExp, listSubscribersResponse, searchPostsQueryParams, searchPostsResponseItem, searchPostsResponse, searchBlogsQueryParams, searchBlogsResponseItem, searchBlogsResponse, searchCoinsQueryParams, searchCoinsResponseItem, searchCoinsResponse, createAuthSessionBodyDeviceNameMax, createAuthSessionBodyCallbackUrlMax, createAuthSessionBody, getAuthSessionParams, getAuthSessionResponse, deleteAuthSessionParams, deleteAuthSessionResponse;
7115
+ var getPublicationByIdParams, getPublicationByIdResponseSlugMax, getPublicationByIdResponseSummaryMax, getPublicationByIdResponse, updatePublicationParams, updatePublicationBodyNameMax, updatePublicationBodySummaryMax, updatePublicationBodyPinnedPostIdsItemMax, updatePublicationBodyPinnedPostIdsMax, updatePublicationBody, updatePublicationResponseSlugMax, updatePublicationResponseSummaryMax, updatePublicationResponse, getPublicationBySlugPathSlugMax, getPublicationBySlugParams, getPublicationBySlugResponseSlugMax, getPublicationBySlugResponseSummaryMax, getPublicationBySlugResponse, getPublicationByDomainParams, getPublicationByDomainResponseSlugMax, getPublicationByDomainResponseSummaryMax, getPublicationByDomainResponse, getSubscriberCountParams, getSubscriberCountResponse, getPostsFeedQueryLimitDefault, getPostsFeedQueryLimitMax, getPostsFeedQueryParams, getPostsFeedResponseItemsItemPostTitleMax, getPostsFeedResponseItemsItemPostSubtitleMax, getPostsFeedResponseItemsItemPostSlugMax, getPostsFeedResponseItemsItemPostAuthorsItemWalletAddressRegExp, getPostsFeedResponseItemsItemPostAuthorsItemBioMax, getPostsFeedResponseItemsItemPublicationSlugMax, getPostsFeedResponseItemsItemPublicationSummaryMax, getPostsFeedResponseItemsItemUserWalletAddressRegExp, getPostsFeedResponseItemsItemUserBioMax, getPostsFeedResponse, getPostsByTagParams, getPostsByTagQueryLimitDefault, getPostsByTagQueryLimitMax, getPostsByTagQueryParams, getPostsByTagResponseItemsItemTitleMax, getPostsByTagResponseItemsItemSubtitleMax, getPostsByTagResponseItemsItemSlugMax, getPostsByTagResponseItemsItemAuthorsItemWalletAddressRegExp, getPostsByTagResponseItemsItemAuthorsItemBioMax, getPostsByTagResponse, getPostsParams, getPostsQueryLimitDefault, getPostsQueryLimitMax, getPostsQueryParams, getPostsResponseItemsItemTitleMax, getPostsResponseItemsItemSubtitleMax, getPostsResponseItemsItemSlugMax, getPostsResponseItemsItemAuthorsItemWalletAddressRegExp, getPostsResponseItemsItemAuthorsItemBioMax, getPostsResponse, getPostByIdParams, getPostByIdQueryParams, getPostByIdResponseTitleMax, getPostByIdResponseSubtitleMax, getPostByIdResponseSlugMax, getPostByIdResponseAuthorsItemWalletAddressRegExp, getPostByIdResponseAuthorsItemBioMax, getPostByIdResponse, updatePostParams, updatePostBodyTitleMax, updatePostBodySubtitleMax, updatePostBodySlugMax, updatePostBodyPostPreviewMax, updatePostBodyScheduledAtMin, updatePostBodyPublishedAtMin, updatePostBody, updatePostResponse, deletePostParams, deletePostBody, deletePostResponse, getPostByPublicationIdAndPostSlugPathPostSlugMax, getPostByPublicationIdAndPostSlugParams, getPostByPublicationIdAndPostSlugQueryParams, getPostByPublicationIdAndPostSlugResponseTitleMax, getPostByPublicationIdAndPostSlugResponseSubtitleMax, getPostByPublicationIdAndPostSlugResponseSlugMax, getPostByPublicationIdAndPostSlugResponseAuthorsItemWalletAddressRegExp, getPostByPublicationIdAndPostSlugResponseAuthorsItemBioMax, getPostByPublicationIdAndPostSlugResponse, getPostByPublicationSlugAndPostSlugPathPublicationSlugMax, getPostByPublicationSlugAndPostSlugPathPostSlugMax, getPostByPublicationSlugAndPostSlugParams, getPostByPublicationSlugAndPostSlugQueryParams, getPostByPublicationSlugAndPostSlugResponseTitleMax, getPostByPublicationSlugAndPostSlugResponseSubtitleMax, getPostByPublicationSlugAndPostSlugResponseSlugMax, getPostByPublicationSlugAndPostSlugResponseAuthorsItemWalletAddressRegExp, getPostByPublicationSlugAndPostSlugResponseAuthorsItemBioMax, getPostByPublicationSlugAndPostSlugResponse, createPostBodyTitleMax, createPostBodySubtitleMax, createPostBodySlugMax, createPostBodyPostPreviewMax, createPostBodyScheduledAtMin, createPostBody, createPostResponse, listOwnPostsQueryLimitDefault, listOwnPostsQueryLimitMax, listOwnPostsQueryParams, listOwnPostsResponseItemsItemTitleMax, listOwnPostsResponseItemsItemSubtitleMax, listOwnPostsResponseItemsItemSlugMax, listOwnPostsResponseItemsItemAuthorsItemWalletAddressRegExp, listOwnPostsResponseItemsItemAuthorsItemBioMax, listOwnPostsResponse, updatePostBySlugPathSlugMax, updatePostBySlugParams, updatePostBySlugBodyTitleMax, updatePostBySlugBodySubtitleMax, updatePostBySlugBodySlugMax, updatePostBySlugBodyPostPreviewMax, updatePostBySlugBodyScheduledAtMin, updatePostBySlugBodyPublishedAtMin, updatePostBySlugBody, updatePostBySlugResponse, deletePostBySlugPathSlugMax, deletePostBySlugParams, deletePostBySlugBody, deletePostBySlugResponse, sendTestEmailParams, sendTestEmailBody, sendTestEmailResponse, getMeResponseSlugMax, getMeResponseSummaryMax, getMeResponse, getUserParams, getUserResponseWalletAddressRegExp, getUserResponseBioMax, getUserResponse, getUserByWalletPathWalletAddressRegExp, getUserByWalletParams, getUserByWalletResponseWalletAddressRegExp, getUserByWalletResponseBioMax, getUserByWalletResponse, getCoinParams, getCoinResponseContractAddressRegExp, getCoinResponse, getCoinByContractPathContractAddressRegExp, getCoinByContractParams, getCoinByContractResponseContractAddressRegExp, getCoinByContractResponse, getCoinHoldersByIdParams, getCoinHoldersByIdQueryLimitDefault, getCoinHoldersByIdQueryLimitMax, getCoinHoldersByIdQueryParams, getCoinHoldersByIdResponseItemsItemWalletAddressRegExp, getCoinHoldersByIdResponseItemsItemBalanceRegExp, getCoinHoldersByIdResponse, getCoinHoldersByContractPathContractAddressRegExp, getCoinHoldersByContractParams, getCoinHoldersByContractQueryLimitDefault, getCoinHoldersByContractQueryLimitMax, getCoinHoldersByContractQueryParams, getCoinHoldersByContractResponseItemsItemWalletAddressRegExp, getCoinHoldersByContractResponseItemsItemBalanceRegExp, getCoinHoldersByContractResponse, getBuyArgsByIdParams, getBuyArgsByIdQueryWalletAddressRegExp, getBuyArgsByIdQueryAmountRegExp, getBuyArgsByIdQueryParams, getBuyArgsByIdResponseCommandsRegExp, getBuyArgsByIdResponseInputsItemRegExp, getBuyArgsByIdResponse, getBuyArgsByContractPathContractAddressRegExp, getBuyArgsByContractParams, getBuyArgsByContractQueryWalletAddressRegExp, getBuyArgsByContractQueryAmountRegExp, getBuyArgsByContractQueryParams, getBuyArgsByContractResponseCommandsRegExp, getBuyArgsByContractResponseInputsItemRegExp, getBuyArgsByContractResponse, getSellArgsByIdParams, getSellArgsByIdQueryWalletAddressRegExp, getSellArgsByIdQueryAmountRegExp, getSellArgsByIdQueryParams, getSellArgsByIdResponseCommandsRegExp, getSellArgsByIdResponseInputsItemRegExp, getSellArgsByIdResponse, getSellArgsByContractPathContractAddressRegExp, getSellArgsByContractParams, getSellArgsByContractQueryWalletAddressRegExp, getSellArgsByContractQueryAmountRegExp, getSellArgsByContractQueryParams, getSellArgsByContractResponseCommandsRegExp, getSellArgsByContractResponseInputsItemRegExp, getSellArgsByContractResponse, getQuoteByIdParams, getQuoteByIdQueryAmountRegExp, getQuoteByIdQueryParams, getQuoteByIdResponse, getQuoteByContractParams, getQuoteByContractQueryAmountRegExp, getQuoteByContractQueryParams, getQuoteByContractResponse, getPopularCoinsResponseCoinsItemContractAddressRegExp, getPopularCoinsResponse, importSubscribersBody, importSubscribersResponse, addSubscriberBodyWalletRegExp, addSubscriberBody, addSubscriberResponse, removeSubscriberBodyWalletRegExp, removeSubscriberBody, removeSubscriberResponse, listSubscribersQueryLimitDefault, listSubscribersQueryLimitMax, listSubscribersQueryParams, listSubscribersResponseItemsItemWalletAddressRegExp, listSubscribersResponse, searchPostsQueryParams, searchPostsResponseItem, searchPostsResponse, searchBlogsQueryParams, searchBlogsResponseItem, searchBlogsResponse, searchCoinsQueryParams, searchCoinsResponseItem, searchCoinsResponse, analyticsQueryBody, analyticsQueryResponse, analyticsSchemaResponse, createAuthSessionBodyDeviceNameMax, createAuthSessionBodyCallbackUrlMax, createAuthSessionBody, getAuthSessionParams, getAuthSessionResponse, deleteAuthSessionParams, deleteAuthSessionResponse;
6910
7116
  var init_zod = __esm({
6911
7117
  "node_modules/@paragraph-com/sdk/dist/zod.mjs"() {
6912
7118
  "use strict";
@@ -6922,7 +7128,86 @@ var init_zod = __esm({
6922
7128
  "slug": zod.string().min(1).max(getPublicationByIdResponseSlugMax).describe("URL-friendly identifier for the publication; accessible at paragraph.com/@[slug]"),
6923
7129
  "customDomain": zod.string().url().optional().describe("Custom domain configured for this publication"),
6924
7130
  "summary": zod.string().max(getPublicationByIdResponseSummaryMax).optional().describe("Brief description of the publication (max 500 characters)"),
6925
- "logoUrl": zod.string().url().optional().describe("URL to the publication's logo image")
7131
+ "logoUrl": zod.string().url().optional().describe("URL to the publication's logo image"),
7132
+ "postListType": zod.enum(["feed", "grid", "full-post"]).optional().describe("Homepage layout. 'feed' is a single-column list of cards, 'grid' is a 3-column grid, 'full-post' shows full posts in a single column."),
7133
+ "themeColor": zod.enum(["default", "orange-500", "rose-600", "pink-500", "fuchsia-600", "purple-600", "violet-600", "indigo-600", "blue-600", "sky-600", "cyan-600", "teal-600", "emerald-600", "green-600", "lime-600", "yellow-700", "amber-600", "orange-600", "stone-800", "rose-900", "indigo-950", "teal-950", "lime-950", "orange-950"]).optional().describe("Theme accent color for the publication"),
7134
+ "headerFont": zod.enum(["default", "serif", "mono"]).optional().describe("Font family used for headers"),
7135
+ "bodyFont": zod.enum(["default", "serif", "mono"]).optional().describe("Font family used for body text"),
7136
+ "showMostPopular": zod.boolean().optional().describe("Whether the 'most popular posts' widget is shown"),
7137
+ "hideStats": zod.boolean().optional().describe("Whether to hide stats like subscriber count, post count, and collects"),
7138
+ "featuredPost": zod.string().min(1).optional().describe("Featured post selector. Use 'latest' for the most recent post, 'popular' for the most-viewed post, 'disabled' to hide the featured slot, or the ID of a specific post in this publication."),
7139
+ "disableComments": zod.union([zod.boolean(), zod.enum(["on-platform"])]).optional().describe("Comment visibility. true disables all comments, false enables them, 'on-platform' hides on-Paragraph comments while keeping Farcaster comments."),
7140
+ "disableHighlights": zod.boolean().optional().describe("Whether to disable highlights on this publication's posts"),
7141
+ "enableTableOfContents": zod.boolean().optional().describe("Whether the table of contents is enabled on posts"),
7142
+ "enableSubscribePopup": zod.boolean().optional().describe("Whether to show the subscribe popup to first-time visitors arriving from external links"),
7143
+ "enableSubscribeScroll": zod.boolean().optional().describe("Whether to show the subscribe popup when first-time visitors scroll a post"),
7144
+ "pinnedPostIds": zod.array(zod.string()).optional().describe("Ordered list of post IDs pinned to the top of the publication's homepage. Pinned posts render in their own section above the regular feed."),
7145
+ "emailNotifications": zod.object({
7146
+ "newComment": zod.boolean().optional().describe("Email the writer when someone comments on a post"),
7147
+ "newSubscriber": zod.boolean().optional().describe("Email the writer when a new free subscriber signs up"),
7148
+ "newPaidSubscriber": zod.boolean().optional().describe("Email the writer when a new paid subscriber signs up"),
7149
+ "newContentCollected": zod.boolean().optional().describe("Email the writer when someone collects their content")
7150
+ }).optional().describe("Owner-side email notification toggles")
7151
+ });
7152
+ updatePublicationParams = zod.object({
7153
+ "publicationId": zod.string().describe("Unique identifier of the publication to update")
7154
+ });
7155
+ updatePublicationBodyNameMax = 100;
7156
+ updatePublicationBodySummaryMax = 500;
7157
+ updatePublicationBodyPinnedPostIdsItemMax = 64;
7158
+ updatePublicationBodyPinnedPostIdsMax = 50;
7159
+ updatePublicationBody = zod.object({
7160
+ "name": zod.string().min(1).max(updatePublicationBodyNameMax).optional().describe("Display name of the publication"),
7161
+ "summary": zod.string().max(updatePublicationBodySummaryMax).optional().describe("Brief description of the publication (max 500 characters)"),
7162
+ "postListType": zod.enum(["feed", "grid", "full-post"]).optional().describe("Homepage layout. 'feed' is a single-column list of cards, 'grid' is a 3-column grid, 'full-post' shows full posts in a single column."),
7163
+ "themeColor": zod.enum(["default", "orange-500", "rose-600", "pink-500", "fuchsia-600", "purple-600", "violet-600", "indigo-600", "blue-600", "sky-600", "cyan-600", "teal-600", "emerald-600", "green-600", "lime-600", "yellow-700", "amber-600", "orange-600", "stone-800", "rose-900", "indigo-950", "teal-950", "lime-950", "orange-950"]).optional().describe("Theme accent color for the publication"),
7164
+ "headerFont": zod.enum(["default", "serif", "mono"]).optional().describe("Font family used for headers"),
7165
+ "bodyFont": zod.enum(["default", "serif", "mono"]).optional().describe("Font family used for body text"),
7166
+ "showMostPopular": zod.boolean().optional().describe("Whether to show the 'most popular posts' widget"),
7167
+ "hideStats": zod.boolean().optional().describe("Whether to hide stats like subscriber count, post count, and collects"),
7168
+ "featuredPost": zod.string().min(1).optional().describe("Featured post selector. Use 'latest' for the most recent post, 'popular' for the most-viewed post, 'disabled' to hide the featured slot, or the ID of a specific post in this publication."),
7169
+ "disableComments": zod.union([zod.boolean(), zod.enum(["on-platform"])]).optional().describe("Comment visibility. true disables all comments, false enables them, 'on-platform' hides on-Paragraph comments while keeping Farcaster comments."),
7170
+ "disableHighlights": zod.boolean().optional().describe("Whether to disable highlights on posts"),
7171
+ "enableTableOfContents": zod.boolean().optional().describe("Whether the table of contents is enabled on posts"),
7172
+ "enableSubscribePopup": zod.boolean().optional().describe("Whether to show the subscribe popup to first-time visitors arriving from external links"),
7173
+ "enableSubscribeScroll": zod.boolean().optional().describe("Whether to show the subscribe popup when first-time visitors scroll a post"),
7174
+ "pinnedPostIds": zod.array(zod.string().min(1).max(updatePublicationBodyPinnedPostIdsItemMax)).max(updatePublicationBodyPinnedPostIdsMax).optional().describe("Ordered list of post IDs to pin to the top of the homepage. Each ID must belong to this publication. Replaces the existing pinned list. Maximum 50 IDs."),
7175
+ "emailNotifications": zod.object({
7176
+ "newComment": zod.boolean().optional().describe("Email the writer when someone comments on a post"),
7177
+ "newSubscriber": zod.boolean().optional().describe("Email the writer when a new free subscriber signs up"),
7178
+ "newPaidSubscriber": zod.boolean().optional().describe("Email the writer when a new paid subscriber signs up"),
7179
+ "newContentCollected": zod.boolean().optional().describe("Email the writer when someone collects their content")
7180
+ }).optional().describe("Owner-side email notification toggles")
7181
+ });
7182
+ updatePublicationResponseSlugMax = 256;
7183
+ updatePublicationResponseSummaryMax = 500;
7184
+ updatePublicationResponse = zod.object({
7185
+ "id": zod.string().describe("Unique identifier for the publication"),
7186
+ "name": zod.string().describe("Display name of the publication"),
7187
+ "ownerUserId": zod.string().describe("ID of the user who owns this publication"),
7188
+ "slug": zod.string().min(1).max(updatePublicationResponseSlugMax).describe("URL-friendly identifier for the publication; accessible at paragraph.com/@[slug]"),
7189
+ "customDomain": zod.string().url().optional().describe("Custom domain configured for this publication"),
7190
+ "summary": zod.string().max(updatePublicationResponseSummaryMax).optional().describe("Brief description of the publication (max 500 characters)"),
7191
+ "logoUrl": zod.string().url().optional().describe("URL to the publication's logo image"),
7192
+ "postListType": zod.enum(["feed", "grid", "full-post"]).optional().describe("Homepage layout. 'feed' is a single-column list of cards, 'grid' is a 3-column grid, 'full-post' shows full posts in a single column."),
7193
+ "themeColor": zod.enum(["default", "orange-500", "rose-600", "pink-500", "fuchsia-600", "purple-600", "violet-600", "indigo-600", "blue-600", "sky-600", "cyan-600", "teal-600", "emerald-600", "green-600", "lime-600", "yellow-700", "amber-600", "orange-600", "stone-800", "rose-900", "indigo-950", "teal-950", "lime-950", "orange-950"]).optional().describe("Theme accent color for the publication"),
7194
+ "headerFont": zod.enum(["default", "serif", "mono"]).optional().describe("Font family used for headers"),
7195
+ "bodyFont": zod.enum(["default", "serif", "mono"]).optional().describe("Font family used for body text"),
7196
+ "showMostPopular": zod.boolean().optional().describe("Whether the 'most popular posts' widget is shown"),
7197
+ "hideStats": zod.boolean().optional().describe("Whether to hide stats like subscriber count, post count, and collects"),
7198
+ "featuredPost": zod.string().min(1).optional().describe("Featured post selector. Use 'latest' for the most recent post, 'popular' for the most-viewed post, 'disabled' to hide the featured slot, or the ID of a specific post in this publication."),
7199
+ "disableComments": zod.union([zod.boolean(), zod.enum(["on-platform"])]).optional().describe("Comment visibility. true disables all comments, false enables them, 'on-platform' hides on-Paragraph comments while keeping Farcaster comments."),
7200
+ "disableHighlights": zod.boolean().optional().describe("Whether to disable highlights on this publication's posts"),
7201
+ "enableTableOfContents": zod.boolean().optional().describe("Whether the table of contents is enabled on posts"),
7202
+ "enableSubscribePopup": zod.boolean().optional().describe("Whether to show the subscribe popup to first-time visitors arriving from external links"),
7203
+ "enableSubscribeScroll": zod.boolean().optional().describe("Whether to show the subscribe popup when first-time visitors scroll a post"),
7204
+ "pinnedPostIds": zod.array(zod.string()).optional().describe("Ordered list of post IDs pinned to the top of the publication's homepage. Pinned posts render in their own section above the regular feed."),
7205
+ "emailNotifications": zod.object({
7206
+ "newComment": zod.boolean().optional().describe("Email the writer when someone comments on a post"),
7207
+ "newSubscriber": zod.boolean().optional().describe("Email the writer when a new free subscriber signs up"),
7208
+ "newPaidSubscriber": zod.boolean().optional().describe("Email the writer when a new paid subscriber signs up"),
7209
+ "newContentCollected": zod.boolean().optional().describe("Email the writer when someone collects their content")
7210
+ }).optional().describe("Owner-side email notification toggles")
6926
7211
  });
6927
7212
  getPublicationBySlugPathSlugMax = 256;
6928
7213
  getPublicationBySlugParams = zod.object({
@@ -6937,7 +7222,26 @@ var init_zod = __esm({
6937
7222
  "slug": zod.string().min(1).max(getPublicationBySlugResponseSlugMax).describe("URL-friendly identifier for the publication; accessible at paragraph.com/@[slug]"),
6938
7223
  "customDomain": zod.string().url().optional().describe("Custom domain configured for this publication"),
6939
7224
  "summary": zod.string().max(getPublicationBySlugResponseSummaryMax).optional().describe("Brief description of the publication (max 500 characters)"),
6940
- "logoUrl": zod.string().url().optional().describe("URL to the publication's logo image")
7225
+ "logoUrl": zod.string().url().optional().describe("URL to the publication's logo image"),
7226
+ "postListType": zod.enum(["feed", "grid", "full-post"]).optional().describe("Homepage layout. 'feed' is a single-column list of cards, 'grid' is a 3-column grid, 'full-post' shows full posts in a single column."),
7227
+ "themeColor": zod.enum(["default", "orange-500", "rose-600", "pink-500", "fuchsia-600", "purple-600", "violet-600", "indigo-600", "blue-600", "sky-600", "cyan-600", "teal-600", "emerald-600", "green-600", "lime-600", "yellow-700", "amber-600", "orange-600", "stone-800", "rose-900", "indigo-950", "teal-950", "lime-950", "orange-950"]).optional().describe("Theme accent color for the publication"),
7228
+ "headerFont": zod.enum(["default", "serif", "mono"]).optional().describe("Font family used for headers"),
7229
+ "bodyFont": zod.enum(["default", "serif", "mono"]).optional().describe("Font family used for body text"),
7230
+ "showMostPopular": zod.boolean().optional().describe("Whether the 'most popular posts' widget is shown"),
7231
+ "hideStats": zod.boolean().optional().describe("Whether to hide stats like subscriber count, post count, and collects"),
7232
+ "featuredPost": zod.string().min(1).optional().describe("Featured post selector. Use 'latest' for the most recent post, 'popular' for the most-viewed post, 'disabled' to hide the featured slot, or the ID of a specific post in this publication."),
7233
+ "disableComments": zod.union([zod.boolean(), zod.enum(["on-platform"])]).optional().describe("Comment visibility. true disables all comments, false enables them, 'on-platform' hides on-Paragraph comments while keeping Farcaster comments."),
7234
+ "disableHighlights": zod.boolean().optional().describe("Whether to disable highlights on this publication's posts"),
7235
+ "enableTableOfContents": zod.boolean().optional().describe("Whether the table of contents is enabled on posts"),
7236
+ "enableSubscribePopup": zod.boolean().optional().describe("Whether to show the subscribe popup to first-time visitors arriving from external links"),
7237
+ "enableSubscribeScroll": zod.boolean().optional().describe("Whether to show the subscribe popup when first-time visitors scroll a post"),
7238
+ "pinnedPostIds": zod.array(zod.string()).optional().describe("Ordered list of post IDs pinned to the top of the publication's homepage. Pinned posts render in their own section above the regular feed."),
7239
+ "emailNotifications": zod.object({
7240
+ "newComment": zod.boolean().optional().describe("Email the writer when someone comments on a post"),
7241
+ "newSubscriber": zod.boolean().optional().describe("Email the writer when a new free subscriber signs up"),
7242
+ "newPaidSubscriber": zod.boolean().optional().describe("Email the writer when a new paid subscriber signs up"),
7243
+ "newContentCollected": zod.boolean().optional().describe("Email the writer when someone collects their content")
7244
+ }).optional().describe("Owner-side email notification toggles")
6941
7245
  });
6942
7246
  getPublicationByDomainParams = zod.object({
6943
7247
  "domain": zod.string().describe("Custom domain of the publication")
@@ -6951,7 +7255,26 @@ var init_zod = __esm({
6951
7255
  "slug": zod.string().min(1).max(getPublicationByDomainResponseSlugMax).describe("URL-friendly identifier for the publication; accessible at paragraph.com/@[slug]"),
6952
7256
  "customDomain": zod.string().url().optional().describe("Custom domain configured for this publication"),
6953
7257
  "summary": zod.string().max(getPublicationByDomainResponseSummaryMax).optional().describe("Brief description of the publication (max 500 characters)"),
6954
- "logoUrl": zod.string().url().optional().describe("URL to the publication's logo image")
7258
+ "logoUrl": zod.string().url().optional().describe("URL to the publication's logo image"),
7259
+ "postListType": zod.enum(["feed", "grid", "full-post"]).optional().describe("Homepage layout. 'feed' is a single-column list of cards, 'grid' is a 3-column grid, 'full-post' shows full posts in a single column."),
7260
+ "themeColor": zod.enum(["default", "orange-500", "rose-600", "pink-500", "fuchsia-600", "purple-600", "violet-600", "indigo-600", "blue-600", "sky-600", "cyan-600", "teal-600", "emerald-600", "green-600", "lime-600", "yellow-700", "amber-600", "orange-600", "stone-800", "rose-900", "indigo-950", "teal-950", "lime-950", "orange-950"]).optional().describe("Theme accent color for the publication"),
7261
+ "headerFont": zod.enum(["default", "serif", "mono"]).optional().describe("Font family used for headers"),
7262
+ "bodyFont": zod.enum(["default", "serif", "mono"]).optional().describe("Font family used for body text"),
7263
+ "showMostPopular": zod.boolean().optional().describe("Whether the 'most popular posts' widget is shown"),
7264
+ "hideStats": zod.boolean().optional().describe("Whether to hide stats like subscriber count, post count, and collects"),
7265
+ "featuredPost": zod.string().min(1).optional().describe("Featured post selector. Use 'latest' for the most recent post, 'popular' for the most-viewed post, 'disabled' to hide the featured slot, or the ID of a specific post in this publication."),
7266
+ "disableComments": zod.union([zod.boolean(), zod.enum(["on-platform"])]).optional().describe("Comment visibility. true disables all comments, false enables them, 'on-platform' hides on-Paragraph comments while keeping Farcaster comments."),
7267
+ "disableHighlights": zod.boolean().optional().describe("Whether to disable highlights on this publication's posts"),
7268
+ "enableTableOfContents": zod.boolean().optional().describe("Whether the table of contents is enabled on posts"),
7269
+ "enableSubscribePopup": zod.boolean().optional().describe("Whether to show the subscribe popup to first-time visitors arriving from external links"),
7270
+ "enableSubscribeScroll": zod.boolean().optional().describe("Whether to show the subscribe popup when first-time visitors scroll a post"),
7271
+ "pinnedPostIds": zod.array(zod.string()).optional().describe("Ordered list of post IDs pinned to the top of the publication's homepage. Pinned posts render in their own section above the regular feed."),
7272
+ "emailNotifications": zod.object({
7273
+ "newComment": zod.boolean().optional().describe("Email the writer when someone comments on a post"),
7274
+ "newSubscriber": zod.boolean().optional().describe("Email the writer when a new free subscriber signs up"),
7275
+ "newPaidSubscriber": zod.boolean().optional().describe("Email the writer when a new paid subscriber signs up"),
7276
+ "newContentCollected": zod.boolean().optional().describe("Email the writer when someone collects their content")
7277
+ }).optional().describe("Owner-side email notification toggles")
6955
7278
  });
6956
7279
  getSubscriberCountParams = zod.object({
6957
7280
  "publicationId": zod.string().describe("Unique identifier of the publication")
@@ -7004,7 +7327,7 @@ var init_zod = __esm({
7004
7327
  }).optional().describe("Farcaster profile information, if linked")
7005
7328
  })).optional().describe("Authors of this post"),
7006
7329
  "authorIds": zod.array(zod.string()).optional().describe("IDs of the authors of this post"),
7007
- "views": zod.number().optional().describe("Total page views. Only included when fetching your own posts via GET /v1/posts"),
7330
+ "views": zod.number().optional().describe("Total views. Only included when fetching your own posts via GET /v1/posts"),
7008
7331
  "status": zod.enum(["published", "draft", "scheduled", "archived"]).optional().describe("Current publish status. Only set on authenticated endpoints (listOwn, getById for your own post). Use this instead of publishedAt to determine publish state \u2014 publishedAt is preserved across unpublishing.")
7009
7332
  }).describe("The post content"),
7010
7333
  "publication": zod.object({
@@ -7014,7 +7337,26 @@ var init_zod = __esm({
7014
7337
  "slug": zod.string().min(1).max(getPostsFeedResponseItemsItemPublicationSlugMax).describe("URL-friendly identifier for the publication; accessible at paragraph.com/@[slug]"),
7015
7338
  "customDomain": zod.string().url().optional().describe("Custom domain configured for this publication"),
7016
7339
  "summary": zod.string().max(getPostsFeedResponseItemsItemPublicationSummaryMax).optional().describe("Brief description of the publication (max 500 characters)"),
7017
- "logoUrl": zod.string().url().optional().describe("URL to the publication's logo image")
7340
+ "logoUrl": zod.string().url().optional().describe("URL to the publication's logo image"),
7341
+ "postListType": zod.enum(["feed", "grid", "full-post"]).optional().describe("Homepage layout. 'feed' is a single-column list of cards, 'grid' is a 3-column grid, 'full-post' shows full posts in a single column."),
7342
+ "themeColor": zod.enum(["default", "orange-500", "rose-600", "pink-500", "fuchsia-600", "purple-600", "violet-600", "indigo-600", "blue-600", "sky-600", "cyan-600", "teal-600", "emerald-600", "green-600", "lime-600", "yellow-700", "amber-600", "orange-600", "stone-800", "rose-900", "indigo-950", "teal-950", "lime-950", "orange-950"]).optional().describe("Theme accent color for the publication"),
7343
+ "headerFont": zod.enum(["default", "serif", "mono"]).optional().describe("Font family used for headers"),
7344
+ "bodyFont": zod.enum(["default", "serif", "mono"]).optional().describe("Font family used for body text"),
7345
+ "showMostPopular": zod.boolean().optional().describe("Whether the 'most popular posts' widget is shown"),
7346
+ "hideStats": zod.boolean().optional().describe("Whether to hide stats like subscriber count, post count, and collects"),
7347
+ "featuredPost": zod.string().min(1).optional().describe("Featured post selector. Use 'latest' for the most recent post, 'popular' for the most-viewed post, 'disabled' to hide the featured slot, or the ID of a specific post in this publication."),
7348
+ "disableComments": zod.union([zod.boolean(), zod.enum(["on-platform"])]).optional().describe("Comment visibility. true disables all comments, false enables them, 'on-platform' hides on-Paragraph comments while keeping Farcaster comments."),
7349
+ "disableHighlights": zod.boolean().optional().describe("Whether to disable highlights on this publication's posts"),
7350
+ "enableTableOfContents": zod.boolean().optional().describe("Whether the table of contents is enabled on posts"),
7351
+ "enableSubscribePopup": zod.boolean().optional().describe("Whether to show the subscribe popup to first-time visitors arriving from external links"),
7352
+ "enableSubscribeScroll": zod.boolean().optional().describe("Whether to show the subscribe popup when first-time visitors scroll a post"),
7353
+ "pinnedPostIds": zod.array(zod.string()).optional().describe("Ordered list of post IDs pinned to the top of the publication's homepage. Pinned posts render in their own section above the regular feed."),
7354
+ "emailNotifications": zod.object({
7355
+ "newComment": zod.boolean().optional().describe("Email the writer when someone comments on a post"),
7356
+ "newSubscriber": zod.boolean().optional().describe("Email the writer when a new free subscriber signs up"),
7357
+ "newPaidSubscriber": zod.boolean().optional().describe("Email the writer when a new paid subscriber signs up"),
7358
+ "newContentCollected": zod.boolean().optional().describe("Email the writer when someone collects their content")
7359
+ }).optional().describe("Owner-side email notification toggles")
7018
7360
  }).describe("The publication this post belongs to"),
7019
7361
  "user": zod.object({
7020
7362
  "id": zod.string().describe("Unique identifier for the user"),
@@ -7079,7 +7421,7 @@ var init_zod = __esm({
7079
7421
  }).optional().describe("Farcaster profile information, if linked")
7080
7422
  })).optional().describe("Authors of this post"),
7081
7423
  "authorIds": zod.array(zod.string()).optional().describe("IDs of the authors of this post"),
7082
- "views": zod.number().optional().describe("Total page views. Only included when fetching your own posts via GET /v1/posts"),
7424
+ "views": zod.number().optional().describe("Total views. Only included when fetching your own posts via GET /v1/posts"),
7083
7425
  "status": zod.enum(["published", "draft", "scheduled", "archived"]).optional().describe("Current publish status. Only set on authenticated endpoints (listOwn, getById for your own post). Use this instead of publishedAt to determine publish state \u2014 publishedAt is preserved across unpublishing.")
7084
7426
  })).describe("Array of items in this page"),
7085
7427
  "pagination": zod.object({
@@ -7131,7 +7473,7 @@ var init_zod = __esm({
7131
7473
  }).optional().describe("Farcaster profile information, if linked")
7132
7474
  })).optional().describe("Authors of this post"),
7133
7475
  "authorIds": zod.array(zod.string()).optional().describe("IDs of the authors of this post"),
7134
- "views": zod.number().optional().describe("Total page views. Only included when fetching your own posts via GET /v1/posts"),
7476
+ "views": zod.number().optional().describe("Total views. Only included when fetching your own posts via GET /v1/posts"),
7135
7477
  "status": zod.enum(["published", "draft", "scheduled", "archived"]).optional().describe("Current publish status. Only set on authenticated endpoints (listOwn, getById for your own post). Use this instead of publishedAt to determine publish state \u2014 publishedAt is preserved across unpublishing.")
7136
7478
  })).describe("Array of items in this page"),
7137
7479
  "pagination": zod.object({
@@ -7178,7 +7520,7 @@ var init_zod = __esm({
7178
7520
  }).optional().describe("Farcaster profile information, if linked")
7179
7521
  })).optional().describe("Authors of this post"),
7180
7522
  "authorIds": zod.array(zod.string()).optional().describe("IDs of the authors of this post"),
7181
- "views": zod.number().optional().describe("Total page views. Only included when fetching your own posts via GET /v1/posts"),
7523
+ "views": zod.number().optional().describe("Total views. Only included when fetching your own posts via GET /v1/posts"),
7182
7524
  "status": zod.enum(["published", "draft", "scheduled", "archived"]).optional().describe("Current publish status. Only set on authenticated endpoints (listOwn, getById for your own post). Use this instead of publishedAt to determine publish state \u2014 publishedAt is preserved across unpublishing.")
7183
7525
  });
7184
7526
  updatePostParams = zod.object({
@@ -7189,6 +7531,7 @@ var init_zod = __esm({
7189
7531
  updatePostBodySlugMax = 256;
7190
7532
  updatePostBodyPostPreviewMax = 500;
7191
7533
  updatePostBodyScheduledAtMin = 0;
7534
+ updatePostBodyPublishedAtMin = 0;
7192
7535
  updatePostBody = zod.object({
7193
7536
  "markdown": zod.string().optional().describe("Post content in Markdown format. Replaces full content \u2014 rich blocks created in the editor will be lost"),
7194
7537
  "title": zod.string().max(updatePostBodyTitleMax).optional().describe("Title of the post"),
@@ -7198,7 +7541,8 @@ var init_zod = __esm({
7198
7541
  "categories": zod.union([zod.array(zod.string()), zod.string()]).optional().describe("Category tags for the post. Can also be a comma-separated string."),
7199
7542
  "status": zod.enum(["draft", "published", "archived"]).optional().describe("Set to 'published' to publish, 'draft' to unpublish, or 'archived' to archive"),
7200
7543
  "scheduledAt": zod.number().min(updatePostBodyScheduledAtMin).nullish().describe("Unix timestamp (milliseconds) to schedule the post's first publish at a future time. Must be in the future and at most 30 days out. Only valid for draft posts that haven't been published or already scheduled. Cannot be combined with status: 'draft' or 'archived'. Pass null to cancel a previously scheduled publish."),
7201
- "sendNewsletter": zod.union([zod.boolean(), zod.enum(["true", "false", "1", "0"])]).optional().describe("Whether to send an email newsletter to subscribers when the post publishes. Only meaningful when publishing (status: 'published') or scheduling (scheduledAt set). Default: false")
7544
+ "sendNewsletter": zod.union([zod.boolean(), zod.enum(["true", "false", "1", "0"])]).optional().describe("Whether to send an email newsletter to subscribers when the post publishes. Only meaningful when publishing (status: 'published') or scheduling (scheduledAt set). Default: false"),
7545
+ "publishedAt": zod.number().min(updatePostBodyPublishedAtMin).optional().describe("Unix timestamp (milliseconds) to set as the post's publish date. Once set, the date is preserved across re-publishes.")
7202
7546
  });
7203
7547
  updatePostResponse = zod.object({
7204
7548
  "success": zod.literal(true).describe("Whether the update succeeded")
@@ -7250,7 +7594,7 @@ var init_zod = __esm({
7250
7594
  }).optional().describe("Farcaster profile information, if linked")
7251
7595
  })).optional().describe("Authors of this post"),
7252
7596
  "authorIds": zod.array(zod.string()).optional().describe("IDs of the authors of this post"),
7253
- "views": zod.number().optional().describe("Total page views. Only included when fetching your own posts via GET /v1/posts"),
7597
+ "views": zod.number().optional().describe("Total views. Only included when fetching your own posts via GET /v1/posts"),
7254
7598
  "status": zod.enum(["published", "draft", "scheduled", "archived"]).optional().describe("Current publish status. Only set on authenticated endpoints (listOwn, getById for your own post). Use this instead of publishedAt to determine publish state \u2014 publishedAt is preserved across unpublishing.")
7255
7599
  });
7256
7600
  getPostByPublicationSlugAndPostSlugPathPublicationSlugMax = 256;
@@ -7294,7 +7638,7 @@ var init_zod = __esm({
7294
7638
  }).optional().describe("Farcaster profile information, if linked")
7295
7639
  })).optional().describe("Authors of this post"),
7296
7640
  "authorIds": zod.array(zod.string()).optional().describe("IDs of the authors of this post"),
7297
- "views": zod.number().optional().describe("Total page views. Only included when fetching your own posts via GET /v1/posts"),
7641
+ "views": zod.number().optional().describe("Total views. Only included when fetching your own posts via GET /v1/posts"),
7298
7642
  "status": zod.enum(["published", "draft", "scheduled", "archived"]).optional().describe("Current publish status. Only set on authenticated endpoints (listOwn, getById for your own post). Use this instead of publishedAt to determine publish state \u2014 publishedAt is preserved across unpublishing.")
7299
7643
  });
7300
7644
  createPostBodyTitleMax = 200;
@@ -7359,7 +7703,7 @@ var init_zod = __esm({
7359
7703
  }).optional().describe("Farcaster profile information, if linked")
7360
7704
  })).optional().describe("Authors of this post"),
7361
7705
  "authorIds": zod.array(zod.string()).optional().describe("IDs of the authors of this post"),
7362
- "views": zod.number().optional().describe("Total page views. Only included when fetching your own posts via GET /v1/posts"),
7706
+ "views": zod.number().optional().describe("Total views. Only included when fetching your own posts via GET /v1/posts"),
7363
7707
  "status": zod.enum(["published", "draft", "scheduled", "archived"]).optional().describe("Current publish status. Only set on authenticated endpoints (listOwn, getById for your own post). Use this instead of publishedAt to determine publish state \u2014 publishedAt is preserved across unpublishing.")
7364
7708
  })).describe("Array of items in this page"),
7365
7709
  "pagination": zod.object({
@@ -7377,6 +7721,7 @@ var init_zod = __esm({
7377
7721
  updatePostBySlugBodySlugMax = 256;
7378
7722
  updatePostBySlugBodyPostPreviewMax = 500;
7379
7723
  updatePostBySlugBodyScheduledAtMin = 0;
7724
+ updatePostBySlugBodyPublishedAtMin = 0;
7380
7725
  updatePostBySlugBody = zod.object({
7381
7726
  "markdown": zod.string().optional().describe("Post content in Markdown format. Replaces full content \u2014 rich blocks created in the editor will be lost"),
7382
7727
  "title": zod.string().max(updatePostBySlugBodyTitleMax).optional().describe("Title of the post"),
@@ -7386,7 +7731,8 @@ var init_zod = __esm({
7386
7731
  "categories": zod.union([zod.array(zod.string()), zod.string()]).optional().describe("Category tags for the post. Can also be a comma-separated string."),
7387
7732
  "status": zod.enum(["draft", "published", "archived"]).optional().describe("Set to 'published' to publish, 'draft' to unpublish, or 'archived' to archive"),
7388
7733
  "scheduledAt": zod.number().min(updatePostBySlugBodyScheduledAtMin).nullish().describe("Unix timestamp (milliseconds) to schedule the post's first publish at a future time. Must be in the future and at most 30 days out. Only valid for draft posts that haven't been published or already scheduled. Cannot be combined with status: 'draft' or 'archived'. Pass null to cancel a previously scheduled publish."),
7389
- "sendNewsletter": zod.union([zod.boolean(), zod.enum(["true", "false", "1", "0"])]).optional().describe("Whether to send an email newsletter to subscribers when the post publishes. Only meaningful when publishing (status: 'published') or scheduling (scheduledAt set). Default: false")
7734
+ "sendNewsletter": zod.union([zod.boolean(), zod.enum(["true", "false", "1", "0"])]).optional().describe("Whether to send an email newsletter to subscribers when the post publishes. Only meaningful when publishing (status: 'published') or scheduling (scheduledAt set). Default: false"),
7735
+ "publishedAt": zod.number().min(updatePostBySlugBodyPublishedAtMin).optional().describe("Unix timestamp (milliseconds) to set as the post's publish date. Once set, the date is preserved across re-publishes.")
7390
7736
  });
7391
7737
  updatePostBySlugResponse = zod.object({
7392
7738
  "success": zod.literal(true).describe("Whether the update succeeded")
@@ -7415,7 +7761,26 @@ var init_zod = __esm({
7415
7761
  "slug": zod.string().min(1).max(getMeResponseSlugMax).describe("URL-friendly identifier for the publication; accessible at paragraph.com/@[slug]"),
7416
7762
  "customDomain": zod.string().url().optional().describe("Custom domain configured for this publication"),
7417
7763
  "summary": zod.string().max(getMeResponseSummaryMax).optional().describe("Brief description of the publication (max 500 characters)"),
7418
- "logoUrl": zod.string().url().optional().describe("URL to the publication's logo image")
7764
+ "logoUrl": zod.string().url().optional().describe("URL to the publication's logo image"),
7765
+ "postListType": zod.enum(["feed", "grid", "full-post"]).optional().describe("Homepage layout. 'feed' is a single-column list of cards, 'grid' is a 3-column grid, 'full-post' shows full posts in a single column."),
7766
+ "themeColor": zod.enum(["default", "orange-500", "rose-600", "pink-500", "fuchsia-600", "purple-600", "violet-600", "indigo-600", "blue-600", "sky-600", "cyan-600", "teal-600", "emerald-600", "green-600", "lime-600", "yellow-700", "amber-600", "orange-600", "stone-800", "rose-900", "indigo-950", "teal-950", "lime-950", "orange-950"]).optional().describe("Theme accent color for the publication"),
7767
+ "headerFont": zod.enum(["default", "serif", "mono"]).optional().describe("Font family used for headers"),
7768
+ "bodyFont": zod.enum(["default", "serif", "mono"]).optional().describe("Font family used for body text"),
7769
+ "showMostPopular": zod.boolean().optional().describe("Whether the 'most popular posts' widget is shown"),
7770
+ "hideStats": zod.boolean().optional().describe("Whether to hide stats like subscriber count, post count, and collects"),
7771
+ "featuredPost": zod.string().min(1).optional().describe("Featured post selector. Use 'latest' for the most recent post, 'popular' for the most-viewed post, 'disabled' to hide the featured slot, or the ID of a specific post in this publication."),
7772
+ "disableComments": zod.union([zod.boolean(), zod.enum(["on-platform"])]).optional().describe("Comment visibility. true disables all comments, false enables them, 'on-platform' hides on-Paragraph comments while keeping Farcaster comments."),
7773
+ "disableHighlights": zod.boolean().optional().describe("Whether to disable highlights on this publication's posts"),
7774
+ "enableTableOfContents": zod.boolean().optional().describe("Whether the table of contents is enabled on posts"),
7775
+ "enableSubscribePopup": zod.boolean().optional().describe("Whether to show the subscribe popup to first-time visitors arriving from external links"),
7776
+ "enableSubscribeScroll": zod.boolean().optional().describe("Whether to show the subscribe popup when first-time visitors scroll a post"),
7777
+ "pinnedPostIds": zod.array(zod.string()).optional().describe("Ordered list of post IDs pinned to the top of the publication's homepage. Pinned posts render in their own section above the regular feed."),
7778
+ "emailNotifications": zod.object({
7779
+ "newComment": zod.boolean().optional().describe("Email the writer when someone comments on a post"),
7780
+ "newSubscriber": zod.boolean().optional().describe("Email the writer when a new free subscriber signs up"),
7781
+ "newPaidSubscriber": zod.boolean().optional().describe("Email the writer when a new paid subscriber signs up"),
7782
+ "newContentCollected": zod.boolean().optional().describe("Email the writer when someone collects their content")
7783
+ }).optional().describe("Owner-side email notification toggles")
7419
7784
  });
7420
7785
  getUserParams = zod.object({
7421
7786
  "userId": zod.string().describe("Unique identifier of the user")
@@ -7711,6 +8076,14 @@ var init_zod = __esm({
7711
8076
  addSubscriberResponse = zod.object({
7712
8077
  "success": zod.literal(true).describe("Whether the subscriber was added")
7713
8078
  });
8079
+ removeSubscriberBodyWalletRegExp = new RegExp("^0x[a-fA-F0-9]{40}$");
8080
+ removeSubscriberBody = zod.object({
8081
+ "email": zod.string().email().optional().describe("Email address of the subscriber to remove"),
8082
+ "wallet": zod.string().regex(removeSubscriberBodyWalletRegExp).optional().describe("Wallet address of the subscriber to remove (0x format)")
8083
+ });
8084
+ removeSubscriberResponse = zod.object({
8085
+ "success": zod.literal(true).describe("Whether the subscriber was removed")
8086
+ });
7714
8087
  listSubscribersQueryLimitDefault = 10;
7715
8088
  listSubscribersQueryLimitMax = 100;
7716
8089
  listSubscribersQueryParams = zod.object({
@@ -7811,6 +8184,25 @@ var init_zod = __esm({
7811
8184
  "activeSubscriberCount": zod.number().describe("Number of active subscribers to this publication")
7812
8185
  });
7813
8186
  searchCoinsResponse = zod.array(searchCoinsResponseItem);
8187
+ analyticsQueryBody = zod.object({
8188
+ "sql": zod.string().min(1).describe("A SELECT or WITH query against the analytics schema. The analytics.* prefix is implicit.")
8189
+ });
8190
+ analyticsQueryResponse = zod.object({
8191
+ "rows": zod.array(zod.record(zod.string(), zod.unknown())).describe("Result rows. Each row is a column-name \u2192 value map."),
8192
+ "rowCount": zod.number().describe("Number of rows returned (after truncation if any)"),
8193
+ "fields": zod.array(zod.object({
8194
+ "name": zod.string()
8195
+ })).describe("Column names in row order"),
8196
+ "truncated": zod.boolean().describe("True if the result was truncated at the 10,000 row limit")
8197
+ });
8198
+ analyticsSchemaResponse = zod.object({
8199
+ "tables": zod.array(zod.object({
8200
+ "table_name": zod.string(),
8201
+ "column_name": zod.string(),
8202
+ "data_type": zod.string(),
8203
+ "is_nullable": zod.string()
8204
+ })).describe("One row per column, grouped by table in ordinal order")
8205
+ });
7814
8206
  createAuthSessionBodyDeviceNameMax = 100;
7815
8207
  createAuthSessionBodyCallbackUrlMax = 2048;
7816
8208
  createAuthSessionBody = zod.object({
@@ -7858,9 +8250,15 @@ async function resolvePublication(identifier, apiKey) {
7858
8250
  }
7859
8251
  return getPublication(identifier, apiKey);
7860
8252
  }
8253
+ async function updatePublication(publicationId, body, apiKey) {
8254
+ updatePublicationBody.parse(body);
8255
+ const client = createClient(apiKey);
8256
+ return client.publications.update(publicationId, body);
8257
+ }
7861
8258
  var init_publications = __esm({
7862
8259
  "src/services/publications.ts"() {
7863
8260
  "use strict";
8261
+ init_zod();
7864
8262
  init_client();
7865
8263
  }
7866
8264
  });
@@ -7964,7 +8362,8 @@ async function updatePost(idOrSlug, params) {
7964
8362
  title: params.title,
7965
8363
  subtitle: params.subtitle,
7966
8364
  markdown: params.markdown,
7967
- categories: params.tags
8365
+ categories: params.tags,
8366
+ publishedAt: params.publishedAt
7968
8367
  };
7969
8368
  updatePostBody.parse(body);
7970
8369
  const client = createClient(params.apiKey);
@@ -8257,29 +8656,44 @@ Examples:
8257
8656
  handleError(err);
8258
8657
  }
8259
8658
  });
8260
- const updateCmd = (parent) => parent.command("update [id-or-slug]").description("Update a post").option("--id <id-or-slug>", "Post ID or slug").option("--title <title>", "Post title").option("--text <markdown>", "Post content as markdown string").option("--file <path>", "Read post content from a file").option("--subtitle <subtitle>", "Post subtitle").option("--tags <tags>", "Comma-separated tags").addHelpText("after", `
8659
+ const updateCmd = (parent) => parent.command("update [id-or-slug]").description("Update a post").option("--id <id-or-slug>", "Post ID or slug").option("--title <title>", "Post title").option("--text <markdown>", "Post content as markdown string").option("--file <path>", "Read post content from a file").option("--subtitle <subtitle>", "Post subtitle").option("--tags <tags>", "Comma-separated tags").option("--published-at <time>", "Set the post's display publish date (ISO 8601 or Unix ms). Sticks across re-publishes \u2014 useful for backdating.").addHelpText("after", `
8261
8660
  Examples:
8262
8661
  $ paragraph post update my-post --title "New Title"
8263
8662
  $ paragraph post update --id my-post --title "New Title"
8264
8663
  $ paragraph post update my-post --file ./updated.md
8265
8664
  $ cat updated.md | paragraph post update my-post
8266
- $ paragraph post update my-post --tags "web3,defi" --json`).action(async function(idOrSlug, opts) {
8665
+ $ paragraph post update my-post --tags "web3,defi" --json
8666
+ $ paragraph post update my-post --published-at "2024-01-01T00:00:00Z"`).action(async function(idOrSlug, opts) {
8267
8667
  try {
8268
8668
  const id = requireArg(idOrSlug, opts.id, "post ID or slug");
8269
8669
  const apiKey = requireApiKey();
8270
8670
  const markdown = await resolveMarkdown(opts);
8271
- if (!opts.title && !opts.subtitle && !markdown && !opts.tags) {
8272
- throw new Error("Nothing to update. Provide --title, --subtitle, --text, --file, or --tags.");
8671
+ const publishedAt = opts.publishedAt ? parseScheduleTime(opts.publishedAt) : void 0;
8672
+ if (!opts.title && !opts.subtitle && !markdown && !opts.tags && publishedAt === void 0) {
8673
+ throw new Error(
8674
+ "Nothing to update. Provide --title, --subtitle, --text, --file, --tags, or --published-at."
8675
+ );
8273
8676
  }
8274
8677
  await updatePost(id, {
8275
8678
  apiKey,
8276
8679
  title: opts.title,
8277
8680
  markdown,
8278
8681
  subtitle: opts.subtitle,
8279
- tags: opts.tags?.split(",").map((t) => t.trim())
8682
+ tags: opts.tags?.split(",").map((t) => t.trim()),
8683
+ publishedAt
8280
8684
  });
8281
8685
  writeSuccess(`Post updated: ${id}`);
8282
- outputData(this, { ID: id }, { id, updated: true, title: opts.title, subtitle: opts.subtitle });
8686
+ outputData(
8687
+ this,
8688
+ { ID: id },
8689
+ {
8690
+ id,
8691
+ updated: true,
8692
+ title: opts.title,
8693
+ subtitle: opts.subtitle,
8694
+ publishedAt
8695
+ }
8696
+ );
8283
8697
  } catch (err) {
8284
8698
  handleError(err);
8285
8699
  }
@@ -8532,6 +8946,7 @@ var init_post = __esm({
8532
8946
  });
8533
8947
 
8534
8948
  // src/cli/commands/publication.ts
8949
+ import * as fs3 from "fs";
8535
8950
  function registerPublicationCommands(program2) {
8536
8951
  const publication = program2.command("publication").description("Manage publications");
8537
8952
  publication.command("get [identifier]").description("Get publication details by ID, slug, or domain").option("--id <identifier>", "Publication ID, slug, or domain").addHelpText("after", `
@@ -8556,6 +8971,106 @@ Examples:
8556
8971
  handleError(err);
8557
8972
  }
8558
8973
  });
8974
+ publication.command("update [publication-id]").description("Update publication settings (only provided fields are changed)").option("--id <id>", "Publication ID").option("--from-json <file>", "Read the full update body from a JSON file (merged with explicit flags; flags win)").option("--name <name>", "Display name").option("--summary <summary>", "Brief description (max 500 chars)").option("--theme-color <color>", "Theme accent color (e.g. 'purple-600', 'default')").option("--header-font <font>", "Header font: default | serif | mono").option("--body-font <font>", "Body font: default | serif | mono").option("--post-list-type <type>", "Homepage layout: feed | grid | full-post").option("--featured-post <selector>", "Post ID, or 'latest' | 'popular' | 'disabled'").option("--pinned-post-ids <ids>", "Comma-separated post IDs to pin (max 50, replaces existing list)").option("--disable-comments <value>", "Comment visibility: true | false | on-platform").option(
8975
+ "--email-notifications <pairs>",
8976
+ "Owner email toggles as key=value,... (keys: newComment, newSubscriber, newPaidSubscriber, newContentCollected)"
8977
+ ).addHelpText("after", `
8978
+ Examples:
8979
+ $ paragraph publication update abc123 --name "My Blog" --theme-color purple-600
8980
+ $ paragraph publication update abc123 --featured-post latest
8981
+ $ paragraph publication update abc123 --pinned-post-ids id1,id2,id3
8982
+ $ paragraph publication update abc123 --disable-comments on-platform
8983
+ $ paragraph publication update abc123 --email-notifications newSubscriber=true,newComment=false
8984
+ $ paragraph publication update abc123 --from-json ./settings.json
8985
+ $ paragraph publication update abc123 --from-json ./base.json --name "Override Name"`).action(async function(positionalId, opts) {
8986
+ try {
8987
+ const id = requireArg(positionalId, opts.id, "publication ID");
8988
+ const apiKey = requireApiKey();
8989
+ const body = {};
8990
+ if (opts.fromJson) {
8991
+ if (!fs3.existsSync(opts.fromJson)) {
8992
+ throw new Error(`File not found: "${opts.fromJson}".`);
8993
+ }
8994
+ const parsed = JSON.parse(fs3.readFileSync(opts.fromJson, "utf-8"));
8995
+ Object.assign(body, parsed);
8996
+ }
8997
+ if (opts.name !== void 0) body.name = opts.name;
8998
+ if (opts.summary !== void 0) body.summary = opts.summary;
8999
+ if (opts.themeColor !== void 0)
9000
+ body.themeColor = opts.themeColor;
9001
+ if (opts.headerFont !== void 0)
9002
+ body.headerFont = opts.headerFont;
9003
+ if (opts.bodyFont !== void 0) body.bodyFont = opts.bodyFont;
9004
+ if (opts.postListType !== void 0)
9005
+ body.postListType = opts.postListType;
9006
+ if (opts.featuredPost !== void 0)
9007
+ body.featuredPost = opts.featuredPost;
9008
+ if (opts.pinnedPostIds !== void 0) {
9009
+ const ids = opts.pinnedPostIds.split(",").map((s) => s.trim()).filter(Boolean);
9010
+ if (ids.length > 50) {
9011
+ throw new Error(
9012
+ `--pinned-post-ids accepts at most 50 IDs (got ${ids.length}).`
9013
+ );
9014
+ }
9015
+ body.pinnedPostIds = ids;
9016
+ }
9017
+ if (opts.disableComments !== void 0) {
9018
+ const v = opts.disableComments;
9019
+ if (v === "true") body.disableComments = true;
9020
+ else if (v === "false") body.disableComments = false;
9021
+ else if (v === "on-platform") body.disableComments = "on-platform";
9022
+ else
9023
+ throw new Error(
9024
+ `--disable-comments must be 'true', 'false', or 'on-platform' (got "${v}").`
9025
+ );
9026
+ }
9027
+ if (opts.emailNotifications !== void 0) {
9028
+ const pairs = opts.emailNotifications.split(",").map((s) => s.trim()).filter(Boolean);
9029
+ const allowed = /* @__PURE__ */ new Set([
9030
+ "newComment",
9031
+ "newSubscriber",
9032
+ "newPaidSubscriber",
9033
+ "newContentCollected"
9034
+ ]);
9035
+ const out = {};
9036
+ for (const pair of pairs) {
9037
+ const [key, value] = pair.split("=");
9038
+ if (!allowed.has(key)) {
9039
+ throw new Error(
9040
+ `--email-notifications: unknown key "${key}". Allowed: newComment, newSubscriber, newPaidSubscriber, newContentCollected.`
9041
+ );
9042
+ }
9043
+ if (value !== "true" && value !== "false") {
9044
+ throw new Error(
9045
+ `--email-notifications: value for "${key}" must be 'true' or 'false' (got "${value}").`
9046
+ );
9047
+ }
9048
+ out[key] = value === "true";
9049
+ }
9050
+ body.emailNotifications = out;
9051
+ }
9052
+ if (Object.keys(body).length === 0) {
9053
+ throw new Error(
9054
+ "Nothing to update. Provide at least one field flag, or pass --from-json <file>."
9055
+ );
9056
+ }
9057
+ const updated = await updatePublication(id, body, apiKey);
9058
+ writeSuccess(`Publication updated: ${updated.name}`);
9059
+ outputData(
9060
+ this,
9061
+ {
9062
+ ID: updated.id,
9063
+ Name: updated.name,
9064
+ Slug: updated.slug,
9065
+ Theme: updated.themeColor,
9066
+ "Pinned posts": updated.pinnedPostIds?.length ?? 0
9067
+ },
9068
+ updated
9069
+ );
9070
+ } catch (err) {
9071
+ handleError(err);
9072
+ }
9073
+ });
8559
9074
  }
8560
9075
  var init_publication = __esm({
8561
9076
  "src/cli/commands/publication.ts"() {
@@ -8638,7 +9153,7 @@ var init_search2 = __esm({
8638
9153
  });
8639
9154
 
8640
9155
  // src/services/subscribers.ts
8641
- import * as fs3 from "fs";
9156
+ import * as fs4 from "fs";
8642
9157
  async function listSubscribers(apiKey, pagination) {
8643
9158
  const client = createClient(apiKey);
8644
9159
  const result = await client.subscribers.get(
@@ -8667,9 +9182,14 @@ async function addSubscriber(params, apiKey) {
8667
9182
  const client = createClient(apiKey);
8668
9183
  await client.subscribers.create(params);
8669
9184
  }
9185
+ async function removeSubscriber(params, apiKey) {
9186
+ removeSubscriberBody.parse(params);
9187
+ const client = createClient(apiKey);
9188
+ await client.subscribers.remove(params);
9189
+ }
8670
9190
  async function importSubscribers(csvPath, apiKey) {
8671
9191
  const client = createClient(apiKey);
8672
- const csvContent = fs3.readFileSync(csvPath, "utf-8");
9192
+ const csvContent = fs4.readFileSync(csvPath, "utf-8");
8673
9193
  const file = new Blob([csvContent], { type: "text/csv" });
8674
9194
  await client.subscribers.importCsv({ file });
8675
9195
  }
@@ -8755,6 +9275,41 @@ Examples:
8755
9275
  handleError(err);
8756
9276
  }
8757
9277
  });
9278
+ subscriber.command("remove").description("Remove a subscriber by email or wallet address (hard delete, irreversible)").option("--email <email>", "Subscriber email address").option("--wallet <address>", "Subscriber wallet address (0x format)").option("--yes", "Skip confirmation prompt").addHelpText("after", `
9279
+ Examples:
9280
+ $ paragraph subscriber remove --email user@example.com
9281
+ $ paragraph subscriber remove --wallet 0x1234...abcd
9282
+ $ paragraph subscriber remove --email user@example.com --yes
9283
+ $ paragraph subscriber remove --email user@example.com --json --yes`).action(async function(opts) {
9284
+ try {
9285
+ if (!opts.email && !opts.wallet) {
9286
+ throw new Error("Provide --email or --wallet (or both).");
9287
+ }
9288
+ const apiKey = requireApiKey();
9289
+ const target = opts.email || opts.wallet;
9290
+ if (!opts.yes) {
9291
+ const ok = await confirm(
9292
+ `Permanently remove subscriber ${target}? This cannot be undone.`
9293
+ );
9294
+ if (!ok) {
9295
+ writeInfo("Cancelled.");
9296
+ return;
9297
+ }
9298
+ }
9299
+ await removeSubscriber(
9300
+ { email: opts.email, wallet: opts.wallet },
9301
+ apiKey
9302
+ );
9303
+ writeSuccess(`Subscriber removed: ${target}`);
9304
+ outputData(
9305
+ this,
9306
+ { Email: opts.email, Wallet: opts.wallet },
9307
+ { email: opts.email, wallet: opts.wallet, removed: true }
9308
+ );
9309
+ } catch (err) {
9310
+ handleError(err);
9311
+ }
9312
+ });
8758
9313
  subscriber.command("import").description("Import subscribers from a CSV file").requiredOption("--csv <file>", "Path to CSV file").addHelpText("after", `
8759
9314
  Examples:
8760
9315
  $ paragraph subscriber import --csv ./subscribers.csv
@@ -8776,6 +9331,7 @@ var init_subscriber = __esm({
8776
9331
  init_subscribers();
8777
9332
  init_output();
8778
9333
  init_error();
9334
+ init_prompt();
8779
9335
  init_args();
8780
9336
  }
8781
9337
  });
@@ -8995,10 +9551,121 @@ var init_user = __esm({
8995
9551
  }
8996
9552
  });
8997
9553
 
9554
+ // src/services/analytics.ts
9555
+ async function runQuery(sql, apiKey) {
9556
+ const client = createClient(apiKey);
9557
+ return client.analytics.query({ sql });
9558
+ }
9559
+ async function getSchema(apiKey) {
9560
+ const client = createClient(apiKey);
9561
+ return client.analytics.schema();
9562
+ }
9563
+ var init_analytics = __esm({
9564
+ "src/services/analytics.ts"() {
9565
+ "use strict";
9566
+ init_client();
9567
+ }
9568
+ });
9569
+
9570
+ // src/cli/commands/analytics.ts
9571
+ import * as fs5 from "fs";
9572
+ async function resolveSql(opts) {
9573
+ if (opts.sql) return opts.sql;
9574
+ if (opts.file) {
9575
+ if (!fs5.existsSync(opts.file)) {
9576
+ throw new Error(`File not found: "${opts.file}".`);
9577
+ }
9578
+ return fs5.readFileSync(opts.file, "utf-8");
9579
+ }
9580
+ const stdin = await readStdin();
9581
+ return stdin || void 0;
9582
+ }
9583
+ function registerAnalyticsCommands(program2) {
9584
+ const cmd = program2.command("analytics").description("Query your publication's analytics data");
9585
+ cmd.command("query").description("Run a read-only SQL query against the analytics schema").option("--sql <sql>", "SQL string (SELECT or WITH only)").option("--file <path>", "Read SQL from a file").addHelpText("after", `
9586
+ Examples:
9587
+ $ paragraph analytics query --sql "SELECT * FROM blog_subscriber_counts"
9588
+ $ paragraph analytics query --file ./query.sql
9589
+ $ paragraph analytics query --file ./query.sql --json
9590
+ $ echo "SELECT title, total_views FROM post_analytics_summary ORDER BY total_views DESC LIMIT 5" | paragraph analytics query`).action(async function(opts) {
9591
+ try {
9592
+ const sql = await resolveSql(opts);
9593
+ if (!sql) {
9594
+ throw new Error(
9595
+ "Provide SQL via --sql, --file, or pipe to stdin."
9596
+ );
9597
+ }
9598
+ const apiKey = requireApiKey();
9599
+ const result = await runQuery(sql, apiKey);
9600
+ if (isJsonMode(this)) {
9601
+ outputData(this, {}, result);
9602
+ return;
9603
+ }
9604
+ if (result.rows.length === 0) {
9605
+ writeInfo("No rows.");
9606
+ return;
9607
+ }
9608
+ const headers = result.fields.map((f) => f.name);
9609
+ const rows = result.rows.map(
9610
+ (r) => headers.map((h) => {
9611
+ const v = r[h];
9612
+ if (v === null || v === void 0) return "";
9613
+ if (typeof v === "object") return JSON.stringify(v);
9614
+ return String(v);
9615
+ })
9616
+ );
9617
+ outputTable(this, headers, rows, result.rows);
9618
+ const summary = `${result.rowCount} row${result.rowCount === 1 ? "" : "s"}${result.truncated ? " (truncated at 10,000)" : ""}`;
9619
+ writeInfo(summary);
9620
+ } catch (err) {
9621
+ handleError(err);
9622
+ }
9623
+ });
9624
+ cmd.command("schema").description("List all tables and columns in the analytics schema").option("--table <name>", "Filter to columns of a single table").addHelpText("after", `
9625
+ Examples:
9626
+ $ paragraph analytics schema
9627
+ $ paragraph analytics schema --table post_analytics_summary
9628
+ $ paragraph analytics schema --json`).action(async function(opts) {
9629
+ try {
9630
+ const apiKey = requireApiKey();
9631
+ const result = await getSchema(apiKey);
9632
+ const items8 = opts.table ? result.tables.filter((c) => c.table_name === opts.table) : result.tables;
9633
+ if (opts.table && items8.length === 0) {
9634
+ throw new Error(
9635
+ `No table named "${opts.table}". Run \`paragraph analytics schema\` to list available tables.`
9636
+ );
9637
+ }
9638
+ outputTable(
9639
+ this,
9640
+ ["Table", "Column", "Type", "Nullable"],
9641
+ items8.map((c) => [
9642
+ c.table_name,
9643
+ c.column_name,
9644
+ c.data_type,
9645
+ c.is_nullable
9646
+ ]),
9647
+ items8
9648
+ );
9649
+ } catch (err) {
9650
+ handleError(err);
9651
+ }
9652
+ });
9653
+ }
9654
+ var init_analytics2 = __esm({
9655
+ "src/cli/commands/analytics.ts"() {
9656
+ "use strict";
9657
+ init_auth();
9658
+ init_analytics();
9659
+ init_stdin();
9660
+ init_output();
9661
+ init_error();
9662
+ }
9663
+ });
9664
+
8998
9665
  // src/cli/program.ts
8999
9666
  function createProgram() {
9000
9667
  const program2 = new Command();
9001
- program2.name("paragraph").description("CLI for Paragraph").version("0.1.1", "-v, --version").option("--json", "Output as JSON").option("--verbose", "Show detailed output for debugging").exitOverride().configureOutput({
9668
+ program2.name("paragraph").description("CLI for Paragraph").version("0.2.0", "-v, --version").option("--json", "Output as JSON").option("--verbose", "Show detailed output for debugging").exitOverride().configureOutput({
9002
9669
  writeOut: (str) => process.stdout.write(str),
9003
9670
  writeErr: (str) => {
9004
9671
  if (process.argv.includes("--json")) {
@@ -9017,6 +9684,7 @@ function createProgram() {
9017
9684
  registerSubscriberCommands(program2);
9018
9685
  registerCoinCommands(program2);
9019
9686
  registerUserCommands(program2);
9687
+ registerAnalyticsCommands(program2);
9020
9688
  return program2;
9021
9689
  }
9022
9690
  var init_program = __esm({
@@ -9030,6 +9698,7 @@ var init_program = __esm({
9030
9698
  init_subscriber();
9031
9699
  init_coin();
9032
9700
  init_user();
9701
+ init_analytics2();
9033
9702
  }
9034
9703
  });
9035
9704
 
@@ -10283,7 +10952,7 @@ import { useState as useState9 } from "react";
10283
10952
  import { Box as Box21, Text as Text14, useInput as useInput17 } from "ink";
10284
10953
  import { TextInput as TextInput5, Spinner as Spinner9 } from "@inkjs/ui";
10285
10954
  import { StatusMessage as StatusMessage9 } from "@inkjs/ui";
10286
- import * as fs4 from "fs";
10955
+ import * as fs6 from "fs";
10287
10956
  import { jsx as jsx23, jsxs as jsxs21 } from "react/jsx-runtime";
10288
10957
  function PostCreate() {
10289
10958
  const { goBack } = useNavigation();
@@ -10305,7 +10974,7 @@ function PostCreate() {
10305
10974
  try {
10306
10975
  let markdown = "";
10307
10976
  if (filePath) {
10308
- markdown = fs4.readFileSync(filePath, "utf-8");
10977
+ markdown = fs6.readFileSync(filePath, "utf-8");
10309
10978
  } else {
10310
10979
  throw new Error("A file path is required for post content.");
10311
10980
  }
@@ -10431,7 +11100,7 @@ import { useState as useState10 } from "react";
10431
11100
  import { Box as Box22, Text as Text15, useInput as useInput18 } from "ink";
10432
11101
  import { TextInput as TextInput6, Spinner as Spinner10 } from "@inkjs/ui";
10433
11102
  import { StatusMessage as StatusMessage10 } from "@inkjs/ui";
10434
- import * as fs5 from "fs";
11103
+ import * as fs7 from "fs";
10435
11104
  import { jsx as jsx24, jsxs as jsxs22 } from "react/jsx-runtime";
10436
11105
  function PostUpdate() {
10437
11106
  const { goBack, screen } = useNavigation();
@@ -10452,7 +11121,7 @@ function PostUpdate() {
10452
11121
  setStep("updating");
10453
11122
  try {
10454
11123
  let markdown;
10455
- if (filePath) markdown = fs5.readFileSync(filePath, "utf-8");
11124
+ if (filePath) markdown = fs7.readFileSync(filePath, "utf-8");
10456
11125
  await updatePost(idOrSlug, {
10457
11126
  apiKey,
10458
11127
  title: title || void 0,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@paragraph-com/cli",
3
- "version": "0.1.1",
3
+ "version": "0.2.0",
4
4
  "type": "module",
5
5
  "description": "CLI for Paragraph",
6
6
  "repository": {
@@ -43,7 +43,7 @@
43
43
  },
44
44
  "dependencies": {
45
45
  "@inkjs/ui": "^2.0.0",
46
- "@paragraph-com/sdk": "^2.0.1",
46
+ "@paragraph-com/sdk": "^2.1.0",
47
47
  "cli-table3": "^0.6.5",
48
48
  "commander": "^12.0.0",
49
49
  "ink": "^5.1.0",