@paragraph-com/cli 0.2.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +256 -23
  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 fs8 = __require("fs");
983
+ var fs9 = __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 (fs8.existsSync(localBin)) return localBin;
1916
+ if (fs9.existsSync(localBin)) return localBin;
1917
1917
  if (sourceExt.includes(path2.extname(baseName))) return void 0;
1918
1918
  const foundExt = sourceExt.find(
1919
- (ext) => fs8.existsSync(`${localBin}${ext}`)
1919
+ (ext) => fs9.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 = fs8.realpathSync(this._scriptPath);
1931
+ resolvedScriptPath = fs9.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, AnalyticsResource, 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, EmailsResource, 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";
@@ -3695,6 +3695,16 @@ var init_dist = __esm({
3695
3695
  }
3696
3696
  );
3697
3697
  };
3698
+ const sendCustomEmail2 = (sendCustomEmailBody2) => {
3699
+ return customAxios(
3700
+ {
3701
+ url: `/v1/emails/send`,
3702
+ method: "POST",
3703
+ headers: { "Content-Type": "application/json" },
3704
+ data: sendCustomEmailBody2
3705
+ }
3706
+ );
3707
+ };
3698
3708
  const createAuthSession = (createAuthSessionBody2) => {
3699
3709
  return customAxios(
3700
3710
  {
@@ -3721,7 +3731,7 @@ var init_dist = __esm({
3721
3731
  }
3722
3732
  );
3723
3733
  };
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 };
3734
+ 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, sendCustomEmail: sendCustomEmail2, createAuthSession, getAuthSession, deleteAuthSession };
3725
3735
  };
3726
3736
  QueryResult = class {
3727
3737
  constructor(promise) {
@@ -4230,6 +4240,68 @@ var init_dist = __esm({
4230
4240
  throw new Error("Invalid identifier provided to getQuote.");
4231
4241
  }
4232
4242
  };
4243
+ EmailsResource = class {
4244
+ constructor(api) {
4245
+ this.api = api;
4246
+ }
4247
+ /**
4248
+ * Sends a custom email from your publication to a list of recipient
4249
+ * addresses. Markdown body, rendered to HTML server-side. Each recipient
4250
+ * receives the email individually with a mandatory unsubscribe footer.
4251
+ * Requires an API key.
4252
+ *
4253
+ * **Eligibility:** Publications must be approved by Paragraph before they
4254
+ * can send custom emails. Ineligible publications receive a 403.
4255
+ *
4256
+ * **Per-recipient filtering:**
4257
+ * - Malformed addresses and known disposable domains are skipped (`invalid`).
4258
+ * - Addresses that previously unsubscribed from this publication are skipped
4259
+ * (`suppressed`).
4260
+ * - Skipped recipients are returned in the response; nothing is delivered to
4261
+ * them.
4262
+ *
4263
+ * **Caps:** Maximum of 10,000 addresses per call.
4264
+ *
4265
+ * **Async delivery:** A 200 response means recipients were accepted, not
4266
+ * delivered. Sends are queued asynchronously.
4267
+ *
4268
+ * @example
4269
+ * ```ts
4270
+ * const api = new ParagraphAPI({ apiKey: "your-api-key" });
4271
+ *
4272
+ * // Send a markdown email to a list of recipients
4273
+ * const { accepted, skipped } = await api.emails.send({
4274
+ * subject: "Hello from Paragraph",
4275
+ * body: "# Welcome\n\nThanks for reading.",
4276
+ * emails: ["reader@example.com", "another@example.com"],
4277
+ * });
4278
+ * console.log(`${accepted} queued, ${skipped.length} skipped`);
4279
+ * skipped.forEach(s => console.log(`${s.email}: ${s.reason}`));
4280
+ *
4281
+ * // Dry run — check filtering without sending
4282
+ * const preview = await api.emails.send({
4283
+ * subject: "Preview",
4284
+ * body: "Body here",
4285
+ * emails: ["reader@example.com"],
4286
+ * dryRun: true,
4287
+ * });
4288
+ * ```
4289
+ *
4290
+ * @param body - The email send request.
4291
+ * @param body.subject - Subject line (1–998 characters).
4292
+ * @param body.body - Markdown body, rendered to HTML server-side (max 100KB).
4293
+ * @param body.emails - Recipient email addresses (max 10,000).
4294
+ * @param body.dryRun - If true, run filtering and return the accepted/skipped
4295
+ * split without scheduling delivery.
4296
+ * @returns A promise resolving to `{ accepted, skipped }`. `accepted` is the
4297
+ * number of recipients queued for delivery; `skipped` lists rejected
4298
+ * recipients with their reason (`suppressed`, `invalid`, or
4299
+ * `scheduling_failed`).
4300
+ */
4301
+ send(body) {
4302
+ return this.api.sendCustomEmail(body);
4303
+ }
4304
+ };
4233
4305
  FeedResource = class {
4234
4306
  constructor(api) {
4235
4307
  this.api = api;
@@ -4899,6 +4971,7 @@ var init_dist = __esm({
4899
4971
  this.feed = new FeedResource(this.api);
4900
4972
  this.users = new UsersResource(this.api);
4901
4973
  this.coins = new CoinsResource(this.api);
4974
+ this.emails = new EmailsResource(this.api);
4902
4975
  this.search = new SearchResource(this.api);
4903
4976
  this.me = new MeResource(this.api);
4904
4977
  }
@@ -7112,7 +7185,7 @@ var init_auth2 = __esm({
7112
7185
 
7113
7186
  // node_modules/@paragraph-com/sdk/dist/zod.mjs
7114
7187
  import * as zod from "zod";
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;
7188
+ 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, sendCustomEmailBodySubjectMax, sendCustomEmailBodyBodyMax, sendCustomEmailBodyEmailsItemMin, sendCustomEmailBodyEmailsItemMax, sendCustomEmailBodyEmailsMax, sendCustomEmailBody, sendCustomEmailResponse, createAuthSessionBodyDeviceNameMax, createAuthSessionBodyCallbackUrlMax, createAuthSessionBody, getAuthSessionParams, getAuthSessionResponse, deleteAuthSessionParams, deleteAuthSessionResponse;
7116
7189
  var init_zod = __esm({
7117
7190
  "node_modules/@paragraph-com/sdk/dist/zod.mjs"() {
7118
7191
  "use strict";
@@ -7540,9 +7613,11 @@ var init_zod = __esm({
7540
7613
  "postPreview": zod.string().max(updatePostBodyPostPreviewMax).optional().describe("Preview text for the post"),
7541
7614
  "categories": zod.union([zod.array(zod.string()), zod.string()]).optional().describe("Category tags for the post. Can also be a comma-separated string."),
7542
7615
  "status": zod.enum(["draft", "published", "archived"]).optional().describe("Set to 'published' to publish, 'draft' to unpublish, or 'archived' to archive"),
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."),
7616
+ "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. The value 0 is treated the same as omitting the field (no scheduling request); note that on an already-scheduled post, omitting `scheduledAt` while changing `status` cancels the schedule."),
7544
7617
  "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.")
7618
+ "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."),
7619
+ "imageUrl": zod.string().url().optional().describe("URL of an image to set as the post's cover/hero image. The image is fetched, re-hosted on Paragraph's CDN, and a placeholder is generated. Pass clearImage: true instead to remove the existing cover."),
7620
+ "clearImage": zod.boolean().optional().describe("When true, removes the post's existing cover/hero image. Ignored if imageUrl is also provided.")
7546
7621
  });
7547
7622
  updatePostResponse = zod.object({
7548
7623
  "success": zod.literal(true).describe("Whether the update succeeded")
@@ -7656,7 +7731,7 @@ var init_zod = __esm({
7656
7731
  "slug": zod.string().min(1).max(createPostBodySlugMax).optional().describe("Optional URL-friendly identifier for the post. If not provided, will be generated from title"),
7657
7732
  "postPreview": zod.string().max(createPostBodyPostPreviewMax).optional().describe("Optional preview text for the post. If not provided, will be generated from content"),
7658
7733
  "categories": zod.union([zod.array(zod.string()), zod.string()]).optional().describe("Optional array of category tags for the post. Can also be a comma-separated string."),
7659
- "scheduledAt": zod.number().min(createPostBodyScheduledAtMin).optional().describe("Optional Unix timestamp (milliseconds) to schedule first-publish of the post at a future time. Must be in the future. Cannot be combined with status: 'draft'. When set, the post is created and queued to publish (and send newsletter, if requested) at the specified time.")
7734
+ "scheduledAt": zod.number().min(createPostBodyScheduledAtMin).optional().describe("Optional Unix timestamp (milliseconds) to schedule first-publish of the post at a future time. Must be in the future. Cannot be combined with status: 'draft'. When set, the post is created and queued to publish (and send newsletter, if requested) at the specified time. Pass 0 or omit the field for an unscheduled post.")
7660
7735
  });
7661
7736
  createPostResponse = zod.object({
7662
7737
  "id": zod.string().describe("The ID of the created post"),
@@ -7730,9 +7805,11 @@ var init_zod = __esm({
7730
7805
  "postPreview": zod.string().max(updatePostBySlugBodyPostPreviewMax).optional().describe("Preview text for the post"),
7731
7806
  "categories": zod.union([zod.array(zod.string()), zod.string()]).optional().describe("Category tags for the post. Can also be a comma-separated string."),
7732
7807
  "status": zod.enum(["draft", "published", "archived"]).optional().describe("Set to 'published' to publish, 'draft' to unpublish, or 'archived' to archive"),
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."),
7808
+ "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. The value 0 is treated the same as omitting the field (no scheduling request); note that on an already-scheduled post, omitting `scheduledAt` while changing `status` cancels the schedule."),
7734
7809
  "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.")
7810
+ "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."),
7811
+ "imageUrl": zod.string().url().optional().describe("URL of an image to set as the post's cover/hero image. The image is fetched, re-hosted on Paragraph's CDN, and a placeholder is generated. Pass clearImage: true instead to remove the existing cover."),
7812
+ "clearImage": zod.boolean().optional().describe("When true, removes the post's existing cover/hero image. Ignored if imageUrl is also provided.")
7736
7813
  });
7737
7814
  updatePostBySlugResponse = zod.object({
7738
7815
  "success": zod.literal(true).describe("Whether the update succeeded")
@@ -8203,6 +8280,24 @@ var init_zod = __esm({
8203
8280
  "is_nullable": zod.string()
8204
8281
  })).describe("One row per column, grouped by table in ordinal order")
8205
8282
  });
8283
+ sendCustomEmailBodySubjectMax = 998;
8284
+ sendCustomEmailBodyBodyMax = 1e5;
8285
+ sendCustomEmailBodyEmailsItemMin = 3;
8286
+ sendCustomEmailBodyEmailsItemMax = 254;
8287
+ sendCustomEmailBodyEmailsMax = 1e4;
8288
+ sendCustomEmailBody = zod.object({
8289
+ "subject": zod.string().min(1).max(sendCustomEmailBodySubjectMax).describe("Subject line of the email"),
8290
+ "body": zod.string().min(1).max(sendCustomEmailBodyBodyMax).describe("Email body. Markdown; rendered to HTML server-side. Max 100KB."),
8291
+ "emails": zod.array(zod.string().min(sendCustomEmailBodyEmailsItemMin).max(sendCustomEmailBodyEmailsItemMax)).min(1).max(sendCustomEmailBodyEmailsMax).describe('Recipient email addresses (max 10,000). Malformed addresses are returned in `skipped` with `reason: "invalid"` rather than rejecting the whole request.'),
8292
+ "dryRun": zod.boolean().optional().describe("If true, run filtering and return the accepted/skipped split without scheduling delivery")
8293
+ });
8294
+ sendCustomEmailResponse = zod.object({
8295
+ "accepted": zod.number().describe("Number of recipients queued for delivery (or that would be queued when dryRun is true)"),
8296
+ "skipped": zod.array(zod.object({
8297
+ "email": zod.string(),
8298
+ "reason": zod.enum(["suppressed", "invalid", "scheduling_failed"])
8299
+ })).describe("Recipients that were rejected, with the reason each one was skipped. `scheduling_failed` means filtering passed but the delivery task could not be queued \u2014 retry these addresses.")
8300
+ });
8206
8301
  createAuthSessionBodyDeviceNameMax = 100;
8207
8302
  createAuthSessionBodyCallbackUrlMax = 2048;
8208
8303
  createAuthSessionBody = zod.object({
@@ -8363,7 +8458,9 @@ async function updatePost(idOrSlug, params) {
8363
8458
  subtitle: params.subtitle,
8364
8459
  markdown: params.markdown,
8365
8460
  categories: params.tags,
8366
- publishedAt: params.publishedAt
8461
+ publishedAt: params.publishedAt,
8462
+ imageUrl: params.imageUrl,
8463
+ clearImage: params.clearImage
8367
8464
  };
8368
8465
  updatePostBody.parse(body);
8369
8466
  const client = createClient(params.apiKey);
@@ -8656,22 +8753,24 @@ Examples:
8656
8753
  handleError(err);
8657
8754
  }
8658
8755
  });
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", `
8756
+ 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.").option("--image-url <url>", "URL of an image to set as the post's cover. Fetched server-side, re-hosted on Paragraph's CDN.").option("--clear-image", "Remove the post's existing cover image. Ignored if --image-url is also provided.").addHelpText("after", `
8660
8757
  Examples:
8661
8758
  $ paragraph post update my-post --title "New Title"
8662
8759
  $ paragraph post update --id my-post --title "New Title"
8663
8760
  $ paragraph post update my-post --file ./updated.md
8664
8761
  $ cat updated.md | paragraph post update my-post
8665
8762
  $ 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) {
8763
+ $ paragraph post update my-post --published-at "2024-01-01T00:00:00Z"
8764
+ $ paragraph post update my-post --image-url https://example.com/cover.jpg
8765
+ $ paragraph post update my-post --clear-image`).action(async function(idOrSlug, opts) {
8667
8766
  try {
8668
8767
  const id = requireArg(idOrSlug, opts.id, "post ID or slug");
8669
8768
  const apiKey = requireApiKey();
8670
8769
  const markdown = await resolveMarkdown(opts);
8671
8770
  const publishedAt = opts.publishedAt ? parseScheduleTime(opts.publishedAt) : void 0;
8672
- if (!opts.title && !opts.subtitle && !markdown && !opts.tags && publishedAt === void 0) {
8771
+ if (!opts.title && !opts.subtitle && !markdown && !opts.tags && publishedAt === void 0 && !opts.imageUrl && !opts.clearImage) {
8673
8772
  throw new Error(
8674
- "Nothing to update. Provide --title, --subtitle, --text, --file, --tags, or --published-at."
8773
+ "Nothing to update. Provide --title, --subtitle, --text, --file, --tags, --published-at, --image-url, or --clear-image."
8675
8774
  );
8676
8775
  }
8677
8776
  await updatePost(id, {
@@ -8680,7 +8779,9 @@ Examples:
8680
8779
  markdown,
8681
8780
  subtitle: opts.subtitle,
8682
8781
  tags: opts.tags?.split(",").map((t) => t.trim()),
8683
- publishedAt
8782
+ publishedAt,
8783
+ imageUrl: opts.imageUrl,
8784
+ clearImage: opts.clearImage
8684
8785
  });
8685
8786
  writeSuccess(`Post updated: ${id}`);
8686
8787
  outputData(
@@ -9662,10 +9763,140 @@ var init_analytics2 = __esm({
9662
9763
  }
9663
9764
  });
9664
9765
 
9766
+ // src/services/emails.ts
9767
+ async function sendCustomEmail(params) {
9768
+ const client = createClient(params.apiKey);
9769
+ return client.emails.send({
9770
+ subject: params.subject,
9771
+ body: params.body,
9772
+ emails: params.emails,
9773
+ ...params.dryRun ? { dryRun: true } : {}
9774
+ });
9775
+ }
9776
+ var init_emails = __esm({
9777
+ "src/services/emails.ts"() {
9778
+ "use strict";
9779
+ init_client();
9780
+ }
9781
+ });
9782
+
9783
+ // src/cli/commands/email.ts
9784
+ import * as fs6 from "fs";
9785
+ async function resolveBody(opts) {
9786
+ if (opts.body) return opts.body;
9787
+ if (opts.bodyFile) {
9788
+ if (!fs6.existsSync(opts.bodyFile)) {
9789
+ throw new Error(
9790
+ `File not found: "${opts.bodyFile}". Check the path, or use --body <markdown> to pass content inline.`
9791
+ );
9792
+ }
9793
+ return fs6.readFileSync(opts.bodyFile, "utf-8");
9794
+ }
9795
+ const stdin = await readStdin();
9796
+ return stdin || void 0;
9797
+ }
9798
+ function collectRecipients(value, previous) {
9799
+ const parts = value.split(",").map((s) => s.trim()).filter(Boolean);
9800
+ return previous.concat(parts);
9801
+ }
9802
+ function registerEmailCommands(program2) {
9803
+ const email = program2.command("email").description("Send custom emails from your publication");
9804
+ email.command("send").description("Send a custom markdown email to a list of recipients").requiredOption("--subject <subject>", "Email subject").option("--body <markdown>", "Email body as markdown string").option("--body-file <path>", "Read email body from a file").option(
9805
+ "--to <emails>",
9806
+ "Recipient email (repeatable, or comma-separated)",
9807
+ collectRecipients,
9808
+ []
9809
+ ).option(
9810
+ "--dry-run",
9811
+ "Run filtering and show the accepted/skipped split without sending"
9812
+ ).option("--yes", "Skip the confirmation prompt before sending").addHelpText(
9813
+ "after",
9814
+ `
9815
+ Examples:
9816
+ $ paragraph email send --subject "Hello" --body "# Hi" --to reader@example.com
9817
+ $ paragraph email send --subject "Update" --body-file ./body.md --to a@x.com --to b@x.com
9818
+ $ paragraph email send --subject "Update" --body-file ./body.md --to "a@x.com,b@x.com"
9819
+ $ cat body.md | paragraph email send --subject "Update" --to reader@example.com
9820
+ $ paragraph email send --subject "Update" --body "# Hi" --to a@x.com --dry-run`
9821
+ ).action(async function(opts) {
9822
+ try {
9823
+ const apiKey = requireApiKey();
9824
+ const body = await resolveBody(opts);
9825
+ if (!body) {
9826
+ throw new Error(
9827
+ "Provide email body via --body, --body-file, or pipe to stdin."
9828
+ );
9829
+ }
9830
+ const recipients = opts.to;
9831
+ if (recipients.length === 0) {
9832
+ throw new Error(
9833
+ "Provide at least one recipient via --to <email>. Repeat the flag or pass a comma-separated list."
9834
+ );
9835
+ }
9836
+ if (!opts.dryRun && !opts.yes) {
9837
+ if (!process.stdin.isTTY) {
9838
+ throw new Error(
9839
+ "Cannot confirm send in non-interactive mode. Use --yes to confirm, or --dry-run to preview."
9840
+ );
9841
+ }
9842
+ const ok = await confirm(
9843
+ `Send "${opts.subject}" to ${recipients.length} recipient${recipients.length === 1 ? "" : "s"}?`
9844
+ );
9845
+ if (!ok) {
9846
+ process.stderr.write("Aborted.\n");
9847
+ process.exit(1);
9848
+ }
9849
+ }
9850
+ const result = await sendCustomEmail({
9851
+ apiKey,
9852
+ subject: opts.subject,
9853
+ body,
9854
+ emails: recipients,
9855
+ dryRun: opts.dryRun
9856
+ });
9857
+ const action = opts.dryRun ? "Dry run" : "Email queued";
9858
+ writeSuccess(
9859
+ `${action}: ${result.accepted} accepted, ${result.skipped.length} skipped`
9860
+ );
9861
+ if (result.skipped.length > 0) {
9862
+ writeInfo("Skipped recipients:");
9863
+ for (const s of result.skipped) {
9864
+ process.stderr.write(` ${s.email} \u2014 ${s.reason}
9865
+ `);
9866
+ }
9867
+ }
9868
+ outputData(
9869
+ this,
9870
+ {
9871
+ Subject: opts.subject,
9872
+ Recipients: recipients.length,
9873
+ Accepted: result.accepted,
9874
+ Skipped: result.skipped.length,
9875
+ DryRun: opts.dryRun ? "yes" : "no"
9876
+ },
9877
+ { ...result, dryRun: !!opts.dryRun }
9878
+ );
9879
+ } catch (err) {
9880
+ handleError(err);
9881
+ }
9882
+ });
9883
+ }
9884
+ var init_email = __esm({
9885
+ "src/cli/commands/email.ts"() {
9886
+ "use strict";
9887
+ init_auth();
9888
+ init_emails();
9889
+ init_output();
9890
+ init_error();
9891
+ init_stdin();
9892
+ init_prompt();
9893
+ }
9894
+ });
9895
+
9665
9896
  // src/cli/program.ts
9666
9897
  function createProgram() {
9667
9898
  const program2 = new Command();
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({
9899
+ program2.name("paragraph").description("CLI for Paragraph").version("0.3.1", "-v, --version").option("--json", "Output as JSON").option("--verbose", "Show detailed output for debugging").exitOverride().configureOutput({
9669
9900
  writeOut: (str) => process.stdout.write(str),
9670
9901
  writeErr: (str) => {
9671
9902
  if (process.argv.includes("--json")) {
@@ -9685,6 +9916,7 @@ function createProgram() {
9685
9916
  registerCoinCommands(program2);
9686
9917
  registerUserCommands(program2);
9687
9918
  registerAnalyticsCommands(program2);
9919
+ registerEmailCommands(program2);
9688
9920
  return program2;
9689
9921
  }
9690
9922
  var init_program = __esm({
@@ -9699,6 +9931,7 @@ var init_program = __esm({
9699
9931
  init_coin();
9700
9932
  init_user();
9701
9933
  init_analytics2();
9934
+ init_email();
9702
9935
  }
9703
9936
  });
9704
9937
 
@@ -10952,7 +11185,7 @@ import { useState as useState9 } from "react";
10952
11185
  import { Box as Box21, Text as Text14, useInput as useInput17 } from "ink";
10953
11186
  import { TextInput as TextInput5, Spinner as Spinner9 } from "@inkjs/ui";
10954
11187
  import { StatusMessage as StatusMessage9 } from "@inkjs/ui";
10955
- import * as fs6 from "fs";
11188
+ import * as fs7 from "fs";
10956
11189
  import { jsx as jsx23, jsxs as jsxs21 } from "react/jsx-runtime";
10957
11190
  function PostCreate() {
10958
11191
  const { goBack } = useNavigation();
@@ -10974,7 +11207,7 @@ function PostCreate() {
10974
11207
  try {
10975
11208
  let markdown = "";
10976
11209
  if (filePath) {
10977
- markdown = fs6.readFileSync(filePath, "utf-8");
11210
+ markdown = fs7.readFileSync(filePath, "utf-8");
10978
11211
  } else {
10979
11212
  throw new Error("A file path is required for post content.");
10980
11213
  }
@@ -11100,7 +11333,7 @@ import { useState as useState10 } from "react";
11100
11333
  import { Box as Box22, Text as Text15, useInput as useInput18 } from "ink";
11101
11334
  import { TextInput as TextInput6, Spinner as Spinner10 } from "@inkjs/ui";
11102
11335
  import { StatusMessage as StatusMessage10 } from "@inkjs/ui";
11103
- import * as fs7 from "fs";
11336
+ import * as fs8 from "fs";
11104
11337
  import { jsx as jsx24, jsxs as jsxs22 } from "react/jsx-runtime";
11105
11338
  function PostUpdate() {
11106
11339
  const { goBack, screen } = useNavigation();
@@ -11121,7 +11354,7 @@ function PostUpdate() {
11121
11354
  setStep("updating");
11122
11355
  try {
11123
11356
  let markdown;
11124
- if (filePath) markdown = fs7.readFileSync(filePath, "utf-8");
11357
+ if (filePath) markdown = fs8.readFileSync(filePath, "utf-8");
11125
11358
  await updatePost(idOrSlug, {
11126
11359
  apiKey,
11127
11360
  title: title || void 0,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@paragraph-com/cli",
3
- "version": "0.2.0",
3
+ "version": "0.3.1",
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.1.0",
46
+ "@paragraph-com/sdk": "^2.2.1",
47
47
  "cli-table3": "^0.6.5",
48
48
  "commander": "^12.0.0",
49
49
  "ink": "^5.1.0",