@rezamirzapour/pod-sdk 1.0.7 → 1.0.8

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/README.md +115 -25
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @rezamirzapour/pod-sdk
2
2
 
3
- > Unified, type-safe, enterprise-grade SDK for **POD Platform** microservices (CMS Content, CMS Product, SSO, CustomPost, Podspace, Podform, Notification, Social, IUMS), engineered specifically for **Next.js App Router**, **Server Components**, and **Server Actions**.
3
+ > Unified, type-safe, enterprise-grade SDK for **POD Platform** microservices (CMS Content, CMS Product, SSO, Captcha, CustomPost, Podspace, Podform, Notification, Social, IUMS), engineered specifically for **Next.js App Router**, **Server Components**, and **Server Actions**.
4
4
 
5
5
  [![npm version](https://img.shields.io/npm/v/@rezamirzapour/pod-sdk.svg)](https://www.npmjs.com/package/@rezamirzapour/pod-sdk)
6
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
@@ -8,8 +8,9 @@
8
8
 
9
9
  ---
10
10
 
11
- ## Features
12
-
11
+ ## Features
12
+
13
+ - **Captcha Protection**: Generate configurable SVG/PNG challenges and validate user answers with a single, typed service.
13
14
  - 🌐 **Unified Multi-Service Architecture**: Single entry-point managing official POD microservices with official endpoints and configurations.
14
15
  - ⚡ **Powered by `@rezamirzapour/http`**: Automatic exponential backoff retries, Next.js incremental static regeneration (ISR) caching (`next.revalidate`, tags), and isomorphic execution.
15
16
  - 🧬 **First-Class TypeScript Generics (`<T, P>`)**: CMS Content, CMS Product, and CustomPost endpoints allow you to define and receive strongly typed metadata structures according to your business schemas.
@@ -20,18 +21,19 @@
20
21
  - 🚀 **Next.js App Router Ready**: Seamless support for Server Components, Server Actions, Route Handlers, and Client Components.
21
22
  - 🌳 **Treeshakeable & Dual ESM/CJS**: Ships clean ES modules (`.mjs`) and CommonJS (`.js`) with 100% complete TypeScript declarations (`.d.ts`).
22
23
 
23
- ---
24
-
25
- ## Microservices Included
24
+ ---
25
+
26
+ ## Microservices Included
26
27
 
27
28
  | Service | Accessor | Swagger Tag | Description |
28
29
  | :--- | :--- | :--- | :--- |
29
30
  | **CMS Content** | `sdk.cms` | `content` | Fetch, publish, edit, draft, archive, and categorize CMS articles with generic metadata `<T, P>`. |
30
31
  | **CMS Product** | `sdk.product` / `sdk.cms.products` | `product` | Product catalog, price & discount range filters, barcode lookup, batch publish, and AI search. |
31
32
  | **CMS Tags & Tree** | `sdk.tags` / `sdk.cms.tags` | `tags` | Manage tag categories and hierarchical tag trees (nodes, parent updates, ancestors, codes). |
32
- | **CustomPost** | `sdk.customPost` | - | Search timeline by metadata `<T>`, custom post CRUD, and high-level typed repository. |
33
- | **SSO** | `sdk.sso` | - | OAuth2 handshake, OTP dispatch with digital RSA signature, OTP verify, token generation, and user profile. |
34
- | **Podspace** | `sdk.podspace` | `public-apis` | Complete Cloud Storage: file/image uploads, resumable chunked uploads, folders, versions, share links, workspaces, trash, tags, & metadata. |
33
+ | **CustomPost** | `sdk.customPost` | - | Search timeline by metadata `<T>`, custom post CRUD, and high-level typed repository. |
34
+ | **SSO** | `sdk.sso` | - | OAuth2 handshake, OTP dispatch with digital RSA signature, OTP verify, token generation, and user profile. |
35
+ | **Captcha** | `sdk.captcha` | `captcha` | Generate SVG/PNG captcha images with configurable options and verify submitted values. |
36
+ | **Podspace** | `sdk.podspace` | `public-apis` | Complete Cloud Storage: file/image uploads, resumable chunked uploads, folders, versions, share links, workspaces, trash, tags, & metadata. |
35
37
  | **Podform** | `sdk.podform` | - | Survey & form response submission, question/form structure retrieval. |
36
38
  | **Notification** | `sdk.notification` | - | SMS delivery and bulk messaging with tracking. |
37
39
  | **Social** | `sdk.social` | - | User comments, reactions (likes/dislikes), rates, and social post interactions. |
@@ -58,9 +60,10 @@ NEXT_PUBLIC_API_POD_URL=https://api.pod.ir
58
60
  NEXT_PUBLIC_API_POD_SANDBOX_URL=https://api.sandpod.ir
59
61
  NEXT_PUBLIC_CMS_URL=https://api.pod.ir/srv/cms-server
60
62
  NEXT_PUBLIC_IUMS_URL=https://indra.khatam.ac.ir/srv
61
- NEXT_PUBLIC_NOTIFICATION_URL=https://api.pod.ir/srv/notification
62
- NEXT_PUBLIC_PODREPORT_URL=https://reporting.pod.ir
63
- NEXT_PUBLIC_PODSPACE_URL=https://podspace.pod.ir
63
+ NEXT_PUBLIC_NOTIFICATION_URL=https://api.pod.ir/srv/notification
64
+ NEXT_PUBLIC_PODREPORT_URL=https://reporting.pod.ir
65
+ NEXT_PUBLIC_PODSPACE_URL=https://podspace.pod.ir
66
+ NEXT_PUBLIC_PODFORM_URL=https://podform.pod.ir
64
67
 
65
68
  # Sandbox Endpoints (Development & Staging)
66
69
  NEXT_PUBLIC_SANDBOX_CMS_URL=http://api.sandpod.ir/srv/cms-sandbox
@@ -69,8 +72,10 @@ NEXT_PUBLIC_SANDBOX_PODSPACE_URL=http://podspace.sandpod.ir
69
72
  NEXT_PUBLIC_SANDBOX_STREAM_URL=https://sandbox-offline-stream.sandpod.ir
70
73
  ```
71
74
 
72
- > [!TIP]
73
- > If you have defined these `NEXT_PUBLIC_*` variables in your `.env` or `.env.local`, `@rezamirzapour/pod-sdk` will automatically detect and apply them without any manual URL mapping.
75
+ > [!TIP]
76
+ > If you have defined these `NEXT_PUBLIC_*` variables in your `.env` or `.env.local`, `@rezamirzapour/pod-sdk` will automatically detect and apply them without any manual URL mapping.
77
+
78
+ Captcha requests use the resolved `apiPod` URL (`NEXT_PUBLIC_API_POD_URL` in production or `NEXT_PUBLIC_API_POD_SANDBOX_URL` when `sandbox: true`); there is no separate captcha URL setting.
74
79
 
75
80
  ---
76
81
 
@@ -854,9 +859,9 @@ await podSdk.podspace.trash.deletePermanently(fileHash);
854
859
 
855
860
  ---
856
861
 
857
- ## Other POD Microservices
858
-
859
- ### 1. POD SSO (OTP Handshake with Web Crypto RSA Signature)
862
+ ## Other POD Microservices
863
+
864
+ ### 1. POD SSO (OTP Handshake with Web Crypto RSA Signature)
860
865
 
861
866
  ```typescript
862
867
  // app/actions/auth.ts
@@ -894,12 +899,97 @@ export async function verifyOtp(authorization: string, phoneNumber: string, code
894
899
  export async function getProfile(accessToken: string) {
895
900
  const profile = await podSdk.sso.getUserProfile(accessToken);
896
901
  return profile.result;
897
- }
898
- ```
899
-
900
- ---
901
-
902
- ### 2. Notification (SMS Delivery)
902
+ }
903
+ ```
904
+
905
+ ---
906
+
907
+ ### 2. Captcha (Generate and Verify)
908
+
909
+ The captcha service exposes the POD captcha API through `podSdk.captcha`. It creates a short-lived challenge image and checks the value entered by the user. Both calls return the SDK's standard `PodResponse<T>` shape (`hasError`, `result`, `message`, and `errorCode`).
910
+
911
+ `Client-Id` and `Access-Token` headers are added automatically from `createPodSdk({ clientId, apiToken })`. Keep these credentials on the server and call captcha methods from a Server Action or Route Handler; do not expose the SDK token in a Client Component.
912
+
913
+ #### Generate a captcha
914
+
915
+ ```typescript
916
+ // app/actions/captcha.ts
917
+ 'use server';
918
+
919
+ import { podSdk } from '@/lib/pod';
920
+
921
+ export async function createCaptcha() {
922
+ const response = await podSdk.captcha.get({
923
+ width: 280,
924
+ height: 96,
925
+ length: 6,
926
+ type: 'alphanumeric',
927
+ format: 'png',
928
+ noise: true,
929
+ bgColor: '#ffffff',
930
+ fontColor: '#1f2937',
931
+ fontSize: 36,
932
+ });
933
+
934
+ if (response.hasError || !response.result) {
935
+ throw new Error(response.message || 'Captcha generation failed');
936
+ }
937
+
938
+ // `image` is a data URI or SVG string, depending on `format`.
939
+ return {
940
+ captchaId: response.result.captchaId,
941
+ image: response.result.image,
942
+ mimeType: response.result.mimeType,
943
+ expiresAt: response.result.expiresAt,
944
+ };
945
+ }
946
+ ```
947
+
948
+ #### Verify the submitted value
949
+
950
+ ```typescript
951
+ import { podSdk } from '@/lib/pod';
952
+
953
+ export async function verifyCaptcha(captchaId: string, captchaValue: string) {
954
+ const response = await podSdk.captcha.check(captchaId, { captchaValue });
955
+
956
+ if (response.hasError) {
957
+ return { valid: false, message: response.message || 'Captcha verification failed' };
958
+ }
959
+
960
+ return {
961
+ valid: response.result?.valid === true,
962
+ message: response.result?.message,
963
+ };
964
+ }
965
+ ```
966
+
967
+ #### Captcha methods
968
+
969
+ | Method | HTTP | Path | Description |
970
+ | :--- | :--- | :--- | :--- |
971
+ | `get(options?)` | `POST` | `/api/core/captchas/generate` | Generate a captcha image. Options are sent as query parameters. |
972
+ | `check(captchaId, { captchaValue })` | `POST` | `/api/core/captchas/check/{captchaId}` | Verify the value entered for a generated captcha. |
973
+
974
+ `GenerateCaptchaOptions` supports the following fields:
975
+
976
+ | Option | Type | Default | Description |
977
+ | :--- | :--- | :--- | :--- |
978
+ | `width` | `number` | `200` | Image width in pixels. |
979
+ | `height` | `number` | `80` | Image height in pixels. |
980
+ | `length` | `number` | `5` | Number of characters in the challenge. |
981
+ | `type` | `string` | Server default | Challenge type, such as `numeric` or `alphanumeric`. |
982
+ | `format` | `'svg' \| 'png'` | `'svg'` | Image output format. |
983
+ | `noise` | `boolean` | `true` | Add visual noise to the image. |
984
+ | `bgColor` | `string` | Server default | Background color in hex format. |
985
+ | `fontColor` | `string` | Server default | Character color in hex format. |
986
+ | `fontSize` | `number` | Server default | Character font size. |
987
+
988
+ The generated response contains `captchaId`, `image`, `expiresAt`, and `mimeType`; `image` is returned as a data URI or SVG string. Always treat the challenge as temporary and request a new one after expiration or a failed attempt, according to your server-side policy.
989
+
990
+ ---
991
+
992
+ ### 3. Notification (SMS Delivery)
903
993
 
904
994
  ```typescript
905
995
  // app/actions/notify.ts
@@ -917,7 +1007,7 @@ export async function sendSms(phoneNumber: string, text: string) {
917
1007
 
918
1008
  ---
919
1009
 
920
- ### 3. Social (Comments & Likes)
1010
+ ### 4. Social (Comments & Likes)
921
1011
 
922
1012
  ```typescript
923
1013
  // app/actions/social.ts
@@ -939,7 +1029,7 @@ export async function likePost(postId: number) {
939
1029
 
940
1030
  ---
941
1031
 
942
- ### 4. IUMS (Identity & University Management Service)
1032
+ ### 5. IUMS (Identity & University Management Service)
943
1033
 
944
1034
  ```typescript
945
1035
  // app/actions/iums.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rezamirzapour/pod-sdk",
3
- "version": "1.0.7",
3
+ "version": "1.0.8",
4
4
  "description": "Unified, type-safe enterprise SDK for POD Platform microservices (SSO, CustomPost, Podspace, Podform, Notification, Social, CMS, IUMS) powered by @rezamirzapour/http.",
5
5
  "author": "Reza",
6
6
  "license": "MIT",