@utilsy/cms-nextjs 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/react.js CHANGED
@@ -134,7 +134,84 @@ function useBlogComments(postId) {
134
134
  );
135
135
  return { comments, loading, submitting, error, refetch, submitComment };
136
136
  }
137
+ function useContentEntries(contentTypeApiId, query, options) {
138
+ const client = useCmsClient();
139
+ const [entries, setEntries] = useState([]);
140
+ const [totalDocs, setTotalDocs] = useState(0);
141
+ const [loading, setLoading] = useState(true);
142
+ const [error, setError] = useState(null);
143
+ const enabled = options?.enabled !== false && !!contentTypeApiId;
144
+ const queryKey = JSON.stringify(query ?? {});
145
+ const refetch = useCallback(async () => {
146
+ if (!enabled) return;
147
+ setLoading(true);
148
+ setError(null);
149
+ try {
150
+ const result = await client.content.listMappedEntries(contentTypeApiId, query);
151
+ setEntries(result?.entries ?? []);
152
+ setTotalDocs(result?.totalDocs ?? 0);
153
+ } catch (e) {
154
+ setError(e instanceof Error ? e : new Error(String(e)));
155
+ setEntries([]);
156
+ setTotalDocs(0);
157
+ } finally {
158
+ setLoading(false);
159
+ }
160
+ }, [client, contentTypeApiId, enabled, queryKey, query]);
161
+ useEffect(() => {
162
+ refetch();
163
+ }, [refetch]);
164
+ return { entries, totalDocs, loading, error, refetch };
165
+ }
166
+ function useContentEntry(contentTypeApiId, idOrSlug, options) {
167
+ const client = useCmsClient();
168
+ const [entry, setEntry] = useState(null);
169
+ const [loading, setLoading] = useState(true);
170
+ const [error, setError] = useState(null);
171
+ const enabled = options?.enabled !== false && !!contentTypeApiId && !!idOrSlug;
172
+ const refetch = useCallback(async () => {
173
+ if (!enabled) return;
174
+ setLoading(true);
175
+ setError(null);
176
+ try {
177
+ const data = await client.content.getMappedEntry(contentTypeApiId, idOrSlug);
178
+ setEntry(data);
179
+ } catch (e) {
180
+ setError(e instanceof Error ? e : new Error(String(e)));
181
+ setEntry(null);
182
+ } finally {
183
+ setLoading(false);
184
+ }
185
+ }, [client, contentTypeApiId, idOrSlug, enabled]);
186
+ useEffect(() => {
187
+ refetch();
188
+ }, [refetch]);
189
+ return { entry, loading, error, refetch };
190
+ }
191
+ function useSubmitLead(contentTypeApiId) {
192
+ const client = useCmsClient();
193
+ const [submitting, setSubmitting] = useState(false);
194
+ const [error, setError] = useState(null);
195
+ const submit = useCallback(
196
+ async (data, options) => {
197
+ if (!contentTypeApiId) return null;
198
+ setSubmitting(true);
199
+ setError(null);
200
+ try {
201
+ return await client.leads.submit(contentTypeApiId, data, options);
202
+ } catch (e) {
203
+ const err = e instanceof Error ? e : new Error(String(e));
204
+ setError(err);
205
+ return null;
206
+ } finally {
207
+ setSubmitting(false);
208
+ }
209
+ },
210
+ [client, contentTypeApiId]
211
+ );
212
+ return { submit, submitting, error };
213
+ }
137
214
 
138
- export { CmsProvider, getVisitorId, useBlogComments, useBlogEngagement, useBlogLike, useCmsClient, useVisitorId };
215
+ export { CmsProvider, getVisitorId, useBlogComments, useBlogEngagement, useBlogLike, useCmsClient, useContentEntries, useContentEntry, useSubmitLead, useVisitorId };
139
216
  //# sourceMappingURL=react.js.map
140
217
  //# sourceMappingURL=react.js.map
package/dist/react.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/react/context.ts","../src/react/provider.tsx","../src/react/use-cms-client.ts","../src/react/use-visitor-id.ts","../src/react/use-blog-engagement.ts","../src/react/use-blog-like.ts","../src/react/use-blog-comments.ts"],"names":["useState","useEffect","useCallback"],"mappings":"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","file":"react.js","sourcesContent":["import { createContext } from \"react\";\nimport type { CmsClient } from \"../client.js\";\n\nexport const CmsClientContext = createContext<CmsClient | null>(null);\n","\"use client\";\n\nimport type { ReactNode } from \"react\";\nimport type { CmsClient } from \"../client.js\";\nimport { CmsClientContext } from \"./context.js\";\n\nexport type CmsProviderProps = {\n client: CmsClient;\n children: ReactNode;\n};\n\nexport function CmsProvider({ client, children }: CmsProviderProps) {\n return <CmsClientContext.Provider value={client}>{children}</CmsClientContext.Provider>;\n}\n","\"use client\";\n\nimport { useContext } from \"react\";\nimport type { CmsClient } from \"../client.js\";\nimport { CmsClientContext } from \"./context.js\";\n\nexport function useCmsClient(): CmsClient {\n const client = useContext(CmsClientContext);\n if (!client) {\n throw new Error(\"useCmsClient must be used within a <CmsProvider client={...}>\");\n }\n return client;\n}\n","\"use client\";\n\nimport { useEffect, useState } from \"react\";\n\nconst DEFAULT_STORAGE_KEY = \"utilsy_cms_visitor_id\";\n\nexport type UseVisitorIdOptions = {\n storageKey?: string;\n};\n\nexport function useVisitorId(options?: UseVisitorIdOptions): string {\n const storageKey = options?.storageKey ?? DEFAULT_STORAGE_KEY;\n const [visitorId, setVisitorId] = useState(\"\");\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n let id = localStorage.getItem(storageKey);\n if (!id) {\n id =\n typeof crypto !== \"undefined\" && \"randomUUID\" in crypto\n ? crypto.randomUUID()\n : `v-${Date.now()}-${Math.random().toString(36).slice(2)}`;\n localStorage.setItem(storageKey, id);\n }\n setVisitorId(id);\n }, [storageKey]);\n\n return visitorId;\n}\n\n/** Non-hook helper for event handlers */\nexport function getVisitorId(storageKey = DEFAULT_STORAGE_KEY): string {\n if (typeof window === \"undefined\") return \"\";\n let id = localStorage.getItem(storageKey);\n if (!id) {\n id =\n typeof crypto !== \"undefined\" && \"randomUUID\" in crypto\n ? crypto.randomUUID()\n : `v-${Date.now()}-${Math.random().toString(36).slice(2)}`;\n localStorage.setItem(storageKey, id);\n }\n return id;\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useState } from \"react\";\nimport type { BlogEngagement } from \"../blog/types.js\";\nimport { useCmsClient } from \"./use-cms-client.js\";\nimport { getVisitorId } from \"./use-visitor-id.js\";\n\nexport type UseBlogEngagementOptions = {\n visitorId?: string;\n storageKey?: string;\n};\n\nexport function useBlogEngagement(postId: string, options?: UseBlogEngagementOptions) {\n const client = useCmsClient();\n const [engagement, setEngagement] = useState<BlogEngagement | null>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const refetch = useCallback(async () => {\n if (!postId) return;\n setLoading(true);\n setError(null);\n try {\n const visitorId =\n options?.visitorId ??\n (typeof window !== \"undefined\" ? getVisitorId(options?.storageKey) : undefined);\n const data = await client.blog.getEngagement(postId, { visitorId });\n setEngagement(data);\n } catch (e) {\n setError(e instanceof Error ? e : new Error(String(e)));\n } finally {\n setLoading(false);\n }\n }, [client, postId, options?.visitorId, options?.storageKey]);\n\n useEffect(() => {\n refetch();\n }, [refetch]);\n\n return { engagement, loading, error, refetch };\n}\n","\"use client\";\n\nimport { useCallback, useState } from \"react\";\nimport { useBlogEngagement } from \"./use-blog-engagement.js\";\nimport { useCmsClient } from \"./use-cms-client.js\";\nimport { getVisitorId } from \"./use-visitor-id.js\";\n\nexport type UseBlogLikeOptions = {\n visitorId?: string;\n storageKey?: string;\n};\n\nexport function useBlogLike(postId: string, options?: UseBlogLikeOptions) {\n const client = useCmsClient();\n const { engagement, loading: engagementLoading, refetch } = useBlogEngagement(postId, options);\n const [toggling, setToggling] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const toggle = useCallback(async () => {\n if (!postId) return;\n setToggling(true);\n setError(null);\n try {\n const visitorId =\n options?.visitorId ??\n (typeof window !== \"undefined\" ? getVisitorId(options?.storageKey) : undefined);\n await client.blog.toggleLike(postId, { visitorId });\n await refetch();\n } catch (e) {\n setError(e instanceof Error ? e : new Error(String(e)));\n } finally {\n setToggling(false);\n }\n }, [client, postId, options?.visitorId, options?.storageKey, refetch]);\n\n return {\n liked: engagement?.likedByMe ?? false,\n likeCount: engagement?.likeCount ?? 0,\n viewCount: engagement?.viewCount ?? 0,\n commentCount: engagement?.commentCount ?? 0,\n loading: engagementLoading,\n toggling,\n error,\n toggle,\n refetch,\n };\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useState } from \"react\";\nimport type { BlogComment, CreateBlogCommentInput } from \"../blog/types.js\";\nimport { useCmsClient } from \"./use-cms-client.js\";\n\nexport function useBlogComments(postId: string) {\n const client = useCmsClient();\n const [comments, setComments] = useState<BlogComment[]>([]);\n const [loading, setLoading] = useState(true);\n const [submitting, setSubmitting] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const refetch = useCallback(async () => {\n if (!postId) return;\n setLoading(true);\n setError(null);\n try {\n const data = await client.blog.listMappedComments(postId);\n setComments(data ?? []);\n } catch (e) {\n setError(e instanceof Error ? e : new Error(String(e)));\n } finally {\n setLoading(false);\n }\n }, [client, postId]);\n\n useEffect(() => {\n refetch();\n }, [refetch]);\n\n const submitComment = useCallback(\n async (input: CreateBlogCommentInput) => {\n if (!postId) return;\n setSubmitting(true);\n setError(null);\n try {\n await client.blog.createComment(postId, input);\n await refetch();\n } catch (e) {\n const err = e instanceof Error ? e : new Error(String(e));\n setError(err);\n throw err;\n } finally {\n setSubmitting(false);\n }\n },\n [client, postId, refetch],\n );\n\n return { comments, loading, submitting, error, refetch, submitComment };\n}\n"]}
1
+ {"version":3,"sources":["../src/react/context.ts","../src/react/provider.tsx","../src/react/use-cms-client.ts","../src/react/use-visitor-id.ts","../src/react/use-blog-engagement.ts","../src/react/use-blog-like.ts","../src/react/use-blog-comments.ts","../src/react/use-content-entries.ts","../src/react/use-content-entry.ts","../src/react/use-submit-lead.ts"],"names":["useState","useEffect","useCallback"],"mappings":"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","file":"react.js","sourcesContent":["import { createContext } from \"react\";\nimport type { CmsClient } from \"../client.js\";\n\nexport const CmsClientContext = createContext<CmsClient | null>(null);\n","\"use client\";\n\nimport type { ReactNode } from \"react\";\nimport type { CmsClient } from \"../client.js\";\nimport { CmsClientContext } from \"./context.js\";\n\nexport type CmsProviderProps = {\n client: CmsClient;\n children: ReactNode;\n};\n\nexport function CmsProvider({ client, children }: CmsProviderProps) {\n return <CmsClientContext.Provider value={client}>{children}</CmsClientContext.Provider>;\n}\n","\"use client\";\n\nimport { useContext } from \"react\";\nimport type { CmsClient } from \"../client.js\";\nimport { CmsClientContext } from \"./context.js\";\n\nexport function useCmsClient(): CmsClient {\n const client = useContext(CmsClientContext);\n if (!client) {\n throw new Error(\"useCmsClient must be used within a <CmsProvider client={...}>\");\n }\n return client;\n}\n","\"use client\";\n\nimport { useEffect, useState } from \"react\";\n\nconst DEFAULT_STORAGE_KEY = \"utilsy_cms_visitor_id\";\n\nexport type UseVisitorIdOptions = {\n storageKey?: string;\n};\n\nexport function useVisitorId(options?: UseVisitorIdOptions): string {\n const storageKey = options?.storageKey ?? DEFAULT_STORAGE_KEY;\n const [visitorId, setVisitorId] = useState(\"\");\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n let id = localStorage.getItem(storageKey);\n if (!id) {\n id =\n typeof crypto !== \"undefined\" && \"randomUUID\" in crypto\n ? crypto.randomUUID()\n : `v-${Date.now()}-${Math.random().toString(36).slice(2)}`;\n localStorage.setItem(storageKey, id);\n }\n setVisitorId(id);\n }, [storageKey]);\n\n return visitorId;\n}\n\n/** Non-hook helper for event handlers */\nexport function getVisitorId(storageKey = DEFAULT_STORAGE_KEY): string {\n if (typeof window === \"undefined\") return \"\";\n let id = localStorage.getItem(storageKey);\n if (!id) {\n id =\n typeof crypto !== \"undefined\" && \"randomUUID\" in crypto\n ? crypto.randomUUID()\n : `v-${Date.now()}-${Math.random().toString(36).slice(2)}`;\n localStorage.setItem(storageKey, id);\n }\n return id;\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useState } from \"react\";\nimport type { BlogEngagement } from \"../blog/types.js\";\nimport { useCmsClient } from \"./use-cms-client.js\";\nimport { getVisitorId } from \"./use-visitor-id.js\";\n\nexport type UseBlogEngagementOptions = {\n visitorId?: string;\n storageKey?: string;\n};\n\nexport function useBlogEngagement(postId: string, options?: UseBlogEngagementOptions) {\n const client = useCmsClient();\n const [engagement, setEngagement] = useState<BlogEngagement | null>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const refetch = useCallback(async () => {\n if (!postId) return;\n setLoading(true);\n setError(null);\n try {\n const visitorId =\n options?.visitorId ??\n (typeof window !== \"undefined\" ? getVisitorId(options?.storageKey) : undefined);\n const data = await client.blog.getEngagement(postId, { visitorId });\n setEngagement(data);\n } catch (e) {\n setError(e instanceof Error ? e : new Error(String(e)));\n } finally {\n setLoading(false);\n }\n }, [client, postId, options?.visitorId, options?.storageKey]);\n\n useEffect(() => {\n refetch();\n }, [refetch]);\n\n return { engagement, loading, error, refetch };\n}\n","\"use client\";\n\nimport { useCallback, useState } from \"react\";\nimport { useBlogEngagement } from \"./use-blog-engagement.js\";\nimport { useCmsClient } from \"./use-cms-client.js\";\nimport { getVisitorId } from \"./use-visitor-id.js\";\n\nexport type UseBlogLikeOptions = {\n visitorId?: string;\n storageKey?: string;\n};\n\nexport function useBlogLike(postId: string, options?: UseBlogLikeOptions) {\n const client = useCmsClient();\n const { engagement, loading: engagementLoading, refetch } = useBlogEngagement(postId, options);\n const [toggling, setToggling] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const toggle = useCallback(async () => {\n if (!postId) return;\n setToggling(true);\n setError(null);\n try {\n const visitorId =\n options?.visitorId ??\n (typeof window !== \"undefined\" ? getVisitorId(options?.storageKey) : undefined);\n await client.blog.toggleLike(postId, { visitorId });\n await refetch();\n } catch (e) {\n setError(e instanceof Error ? e : new Error(String(e)));\n } finally {\n setToggling(false);\n }\n }, [client, postId, options?.visitorId, options?.storageKey, refetch]);\n\n return {\n liked: engagement?.likedByMe ?? false,\n likeCount: engagement?.likeCount ?? 0,\n viewCount: engagement?.viewCount ?? 0,\n commentCount: engagement?.commentCount ?? 0,\n loading: engagementLoading,\n toggling,\n error,\n toggle,\n refetch,\n };\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useState } from \"react\";\nimport type { BlogComment, CreateBlogCommentInput } from \"../blog/types.js\";\nimport { useCmsClient } from \"./use-cms-client.js\";\n\nexport function useBlogComments(postId: string) {\n const client = useCmsClient();\n const [comments, setComments] = useState<BlogComment[]>([]);\n const [loading, setLoading] = useState(true);\n const [submitting, setSubmitting] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const refetch = useCallback(async () => {\n if (!postId) return;\n setLoading(true);\n setError(null);\n try {\n const data = await client.blog.listMappedComments(postId);\n setComments(data ?? []);\n } catch (e) {\n setError(e instanceof Error ? e : new Error(String(e)));\n } finally {\n setLoading(false);\n }\n }, [client, postId]);\n\n useEffect(() => {\n refetch();\n }, [refetch]);\n\n const submitComment = useCallback(\n async (input: CreateBlogCommentInput) => {\n if (!postId) return;\n setSubmitting(true);\n setError(null);\n try {\n await client.blog.createComment(postId, input);\n await refetch();\n } catch (e) {\n const err = e instanceof Error ? e : new Error(String(e));\n setError(err);\n throw err;\n } finally {\n setSubmitting(false);\n }\n },\n [client, postId, refetch],\n );\n\n return { comments, loading, submitting, error, refetch, submitComment };\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useState } from \"react\";\nimport type { ContentEntry, ListContentEntriesQuery } from \"../content/types.js\";\nimport { useCmsClient } from \"./use-cms-client.js\";\n\nexport type UseContentEntriesOptions = {\n enabled?: boolean;\n};\n\nexport function useContentEntries(\n contentTypeApiId: string,\n query?: ListContentEntriesQuery,\n options?: UseContentEntriesOptions,\n) {\n const client = useCmsClient();\n const [entries, setEntries] = useState<ContentEntry[]>([]);\n const [totalDocs, setTotalDocs] = useState(0);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const enabled = options?.enabled !== false && !!contentTypeApiId;\n const queryKey = JSON.stringify(query ?? {});\n\n const refetch = useCallback(async () => {\n if (!enabled) return;\n setLoading(true);\n setError(null);\n try {\n const result = await client.content.listMappedEntries(contentTypeApiId, query);\n setEntries(result?.entries ?? []);\n setTotalDocs(result?.totalDocs ?? 0);\n } catch (e) {\n setError(e instanceof Error ? e : new Error(String(e)));\n setEntries([]);\n setTotalDocs(0);\n } finally {\n setLoading(false);\n }\n }, [client, contentTypeApiId, enabled, queryKey, query]);\n\n useEffect(() => {\n refetch();\n }, [refetch]);\n\n return { entries, totalDocs, loading, error, refetch };\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useState } from \"react\";\nimport type { ContentEntry } from \"../content/types.js\";\nimport { useCmsClient } from \"./use-cms-client.js\";\n\nexport type UseContentEntryOptions = {\n enabled?: boolean;\n};\n\nexport function useContentEntry(\n contentTypeApiId: string,\n idOrSlug: string,\n options?: UseContentEntryOptions,\n) {\n const client = useCmsClient();\n const [entry, setEntry] = useState<ContentEntry | null>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const enabled = options?.enabled !== false && !!contentTypeApiId && !!idOrSlug;\n\n const refetch = useCallback(async () => {\n if (!enabled) return;\n setLoading(true);\n setError(null);\n try {\n const data = await client.content.getMappedEntry(contentTypeApiId, idOrSlug);\n setEntry(data);\n } catch (e) {\n setError(e instanceof Error ? e : new Error(String(e)));\n setEntry(null);\n } finally {\n setLoading(false);\n }\n }, [client, contentTypeApiId, idOrSlug, enabled]);\n\n useEffect(() => {\n refetch();\n }, [refetch]);\n\n return { entry, loading, error, refetch };\n}\n","\"use client\";\n\nimport { useCallback, useState } from \"react\";\nimport type { LeadSubmissionData, SubmitLeadOptions, SubmitLeadResult } from \"../leads/types.js\";\nimport { useCmsClient } from \"./use-cms-client.js\";\n\nexport function useSubmitLead(contentTypeApiId: string) {\n const client = useCmsClient();\n const [submitting, setSubmitting] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const submit = useCallback(\n async (\n data: LeadSubmissionData,\n options?: SubmitLeadOptions,\n ): Promise<SubmitLeadResult | null> => {\n if (!contentTypeApiId) return null;\n setSubmitting(true);\n setError(null);\n try {\n return await client.leads.submit(contentTypeApiId, data, options);\n } catch (e) {\n const err = e instanceof Error ? e : new Error(String(e));\n setError(err);\n return null;\n } finally {\n setSubmitting(false);\n }\n },\n [client, contentTypeApiId],\n );\n\n return { submit, submitting, error };\n}\n"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@utilsy/cms-nextjs",
3
- "version": "0.1.0",
4
- "description": "Headless Next.js SDK for Utilsy gateway-cms public blog APIs",
3
+ "version": "0.3.0",
4
+ "description": "Headless Next.js SDK for Utilsy gateway-cms public blog, content-type, and lead capture APIs",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "sideEffects": false,
@@ -66,6 +66,8 @@
66
66
  "cms",
67
67
  "nextjs",
68
68
  "blog",
69
+ "content-types",
70
+ "leads",
69
71
  "headless"
70
72
  ],
71
73
  "repository": {