code: use,rest,nextjs (1 files)

This commit is contained in:
Richard Ward
2025-12-30 23:03:07 +00:00
parent 2f2ec12f61
commit 33b312b58d

View File

@@ -69,22 +69,30 @@ export function useRestApi<T = unknown>(options?: UseRestApiOptions) {
// Try to get tenant from context, fall back to options
const tenantContext = useTenantOptional()
const tenant = options?.tenant || tenantContext?.tenant
const packageId = options?.packageId || tenantContext?.packageId
const defaultPackageId = options?.packageId || tenantContext?.packageId
/**
* Build the base URL for API calls
* @param entity Entity name
* @param id Optional record ID
* @param action Optional action name
* @param pkgOverride Override the package (for dependency package access)
*/
const buildUrl = useCallback(
(entity: string, id?: string, action?: string) => {
if (!tenant || !packageId) {
throw new Error('Tenant and package are required')
(entity: string, id?: string, action?: string, pkgOverride?: string) => {
if (!tenant) {
throw new Error('Tenant is required')
}
let url = `/api/v1/${tenant}/${packageId}/${entity}`
const pkg = pkgOverride || defaultPackageId
if (!pkg) {
throw new Error('Package is required')
}
let url = `/api/v1/${tenant}/${pkg}/${entity}`
if (id) url += `/${id}`
if (action) url += `/${action}`
return url
},
[tenant, packageId]
[tenant, defaultPackageId]
)
/**
@@ -96,7 +104,8 @@ export function useRestApi<T = unknown>(options?: UseRestApiOptions) {
setError(null)
try {
const url = buildUrl(entity) + buildQueryString(options || {})
const { packageId: pkgOverride, ...queryOpts } = options || {}
const url = buildUrl(entity, undefined, undefined, pkgOverride) + buildQueryString(queryOpts)
const response = await fetch(url)
const json: ApiResponse<T[]> = await response.json()
@@ -307,3 +316,40 @@ export function useEntity<T = unknown>(entity: string, options?: UseRestApiOptio
api.action(entity, id, actionName, data),
}
}
/**
* Hook for accessing entities from a dependency package
*
* @example
* // On a forum_forge page, access user_manager entities
* const { list: listRoles } = useDependencyEntity<Role>('user_manager', 'roles')
* const roles = await listRoles()
*/
export function useDependencyEntity<T = unknown>(
packageId: string,
entity: string
) {
const tenantContext = useTenantOptional()
// Verify package is accessible (either primary or a dependency)
if (tenantContext && !tenantContext.hasPackage(packageId)) {
console.warn(
`Package '${packageId}' is not accessible from '${tenantContext.primaryPackage}'. ` +
`Add it to dependencies in metadata.json.`
)
}
const api = useRestApi<T>({ packageId })
return {
loading: api.loading,
error: api.error,
list: (opts?: Omit<RequestOptions, 'packageId'>) => api.list(entity, opts),
read: (id: string) => api.read(entity, id),
create: (data: Record<string, unknown>) => api.create(entity, data),
update: (id: string, data: Record<string, unknown>) => api.update(entity, id, data),
remove: (id: string) => api.remove(entity, id),
action: (id: string, actionName: string, data?: Record<string, unknown>) =>
api.action(entity, id, actionName, data),
}
}