@carlonicora/nextjs-jsonapi 1.141.0 → 1.141.2
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/{BlockNoteEditor-UNYOBY7K.mjs → BlockNoteEditor-3V7LHCFY.mjs} +2 -2
- package/dist/{BlockNoteEditor-HTTA7FIH.js → BlockNoteEditor-S6LWQDMF.js} +9 -9
- package/dist/{BlockNoteEditor-HTTA7FIH.js.map → BlockNoteEditor-S6LWQDMF.js.map} +1 -1
- package/dist/billing/index.js +310 -310
- package/dist/billing/index.mjs +1 -1
- package/dist/{chunk-7TKD4SMQ.mjs → chunk-7ZEETAQV.mjs} +23 -12
- package/dist/chunk-7ZEETAQV.mjs.map +1 -0
- package/dist/{chunk-QCLR35VY.js → chunk-S4G7IXZZ.js} +22 -11
- package/dist/chunk-S4G7IXZZ.js.map +1 -0
- package/dist/client/index.js +2 -2
- package/dist/client/index.mjs +1 -1
- package/dist/components/index.d.mts +2 -2
- package/dist/components/index.d.ts +2 -2
- package/dist/components/index.js +2 -2
- package/dist/components/index.mjs +1 -1
- package/dist/contexts/index.js +2 -2
- package/dist/contexts/index.mjs +1 -1
- package/dist/features/help/index.js +31 -31
- package/dist/features/help/index.mjs +1 -1
- package/dist/server/index.js +3 -3
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +2 -2
- package/dist/server/index.mjs.map +1 -1
- package/package.json +51 -52
- package/src/components/forms/EditorSheet.tsx +41 -7
- package/src/components/forms/FileUploader.tsx +18 -3
- package/src/components/forms/FormInput.tsx +1 -2
- package/src/features/auth/utils/AuthCookies.ts +2 -2
- package/src/server/ServerSession.ts +2 -2
- package/src/shadcnui/ui/calendar.tsx +1 -1
- package/dist/chunk-7TKD4SMQ.mjs.map +0 -1
- package/dist/chunk-QCLR35VY.js.map +0 -1
- /package/dist/{BlockNoteEditor-UNYOBY7K.mjs.map → BlockNoteEditor-3V7LHCFY.mjs.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/server/cache.ts","../../src/server/ServerSession.ts","../../src/server/JsonApiServer.ts"],"sourcesContent":["// Server-only utilities (NOT server actions - these cannot be called from client components)\n\nimport { revalidateTag } from \"next/cache\";\n\nexport type CacheProfile = \"seconds\" | \"minutes\" | \"hours\" | \"days\" | \"weeks\" | \"max\" | \"default\";\n\n/**\n * Revalidate a cache tag to invalidate cached data.\n * Next.js 16+ requires a profile parameter.\n *\n * @param tag - The cache tag to invalidate\n * @param profile - The cache profile (defaults to \"max\" for immediate invalidation)\n */\nexport async function invalidateCacheTag(tag: string, profile: CacheProfile = \"max\"): Promise<void> {\n revalidateTag(tag, profile);\n}\n\n/**\n * Revalidate multiple cache tags.\n *\n * @param tags - Array of cache tags to invalidate\n * @param profile - The cache profile (defaults to \"max\" for immediate invalidation)\n */\nexport async function invalidateCacheTags(tags: string[], profile: CacheProfile = \"max\"): Promise<void> {\n for (const tag of tags) {\n revalidateTag(tag, profile);\n }\n}\n","import { cookies } from \"next/headers\";\nimport { redirect } from \"next/navigation\";\nimport pako from \"pako\";\nimport { Action, checkPermissionsFromServer, ModuleWithPermissions } from \"../permissions\";\n\nexport class ServerSession {\n static async isLogged() {\n const cookieStore = await cookies();\n const token = cookieStore.get(\"token\");\n\n if (!token || !token.value) return false;\n return true;\n }\n\n static async companyId() {\n const cookieStore = await cookies();\n return cookieStore.get(\"companyId\")?.value ?? \"\";\n }\n\n static async userId() {\n const cookieStore = await cookies();\n return cookieStore.get(\"userId\")?.value ?? \"\";\n }\n\n static async checkPermission<M extends ModuleWithPermissions>(params: { module: M; action: Action; data?: any }) {\n if (!(await this.hasPermissionToModule(params))) redirect(`/401`);\n }\n\n static async hasRole(roleId: string): Promise<boolean> {\n const cookieStore = await cookies();\n const roles = cookieStore.get(\"roles\")?.value;\n\n if (!roles || !roles.includes(roleId)) return false;\n\n return true;\n }\n\n static async hasFeature(featureId: string): Promise<boolean> {\n const cookieStore = await cookies();\n const features = cookieStore.get(\"features\")?.value;\n\n if (!features || !features.includes(featureId)) return false;\n\n return true;\n }\n\n static async hasPermissionToModule<M extends ModuleWithPermissions>(params: {\n module: M;\n action: Action;\n data?: any;\n }): Promise<boolean> {\n const cookieStore = await cookies();\n\n if (params.module.feature) {\n const features = cookieStore.get(\"features\")?.value;\n\n if (features && !features.includes(params.module.feature)) return false;\n }\n\n const rawModules = cookieStore.get(\"modules\")?.value;\n if (!rawModules) return false;\n\n const modules: {\n id: string;\n permissions: {\n create: boolean | string;\n read: boolean | string;\n update: boolean | string;\n delete: boolean | string;\n };\n }[] = JSON.parse(pako.ungzip(Buffer.from(rawModules, \"base64\"), { to: \"string\" }));\n\n const selectedModule = modules.find((module) => module.id === params.module.moduleId);\n\n return checkPermissionsFromServer({\n module: params.module,\n action: params.action,\n data: params.data,\n userId: await this.userId(),\n selectedModule: selectedModule,\n });\n\n // if (!selectedModule) return false;\n\n // if (!selectedModule.permissions[params.action]) return false;\n // if (typeof selectedModule.permissions[params.action] === \"boolean\")\n // return selectedModule.permissions[params.action] as boolean;\n\n // if (!params.data) return false;\n\n // return params.data[selectedModule.permissions[params.action] as string] === this.userId;\n }\n}\n","// Server-only utilities (NOT server actions - these cannot be called from client components)\n\nimport { JsonApiDataFactory } from \"../core/factories/JsonApiDataFactory\";\nimport { ApiRequestDataTypeInterface } from \"../core/interfaces/ApiRequestDataTypeInterface\";\nimport { ApiResponseInterface } from \"../core/interfaces/ApiResponseInterface\";\nimport { translateResponse } from \"../core/utils/translateResponse\";\nimport { ModuleWithPermissions } from \"../permissions/types\";\nimport { serverRequest } from \"./request\";\nimport { getServerToken } from \"./token\";\n\n// Config storage for server contexts\nlet _serverConfig: {\n apiUrl: string;\n appUrl?: string;\n trackablePages?: ModuleWithPermissions[];\n bootstrapper?: () => void;\n additionalHeaders?: Record<string, string>;\n} | null = null;\n\n/**\n * Configure the JSON:API server client.\n * Call this in your Bootstrapper or server initialization.\n */\nexport function configureServerJsonApi(config: {\n apiUrl: string;\n appUrl?: string;\n trackablePages?: ModuleWithPermissions[];\n bootstrapper?: () => void;\n additionalHeaders?: Record<string, string>;\n}): void {\n _serverConfig = config;\n if (config.bootstrapper) {\n config.bootstrapper();\n }\n}\n\nexport function getServerApiUrl(): string {\n if (_serverConfig?.apiUrl) {\n return _serverConfig.apiUrl;\n }\n const envUrl = process.env.NEXT_PUBLIC_API_URL;\n if (!envUrl) {\n throw new Error(\n \"API URL not configured. Use configureServerJsonApi() or set NEXT_PUBLIC_API_URL environment variable.\",\n );\n }\n return envUrl;\n}\n\nexport function getServerAppUrl(): string {\n if (_serverConfig?.appUrl) {\n return _serverConfig.appUrl;\n }\n const envUrl = process.env.NEXT_PUBLIC_ADDRESS;\n if (!envUrl) {\n throw new Error(\n \"App URL not configured. Use configureServerJsonApi({ appUrl }) or set NEXT_PUBLIC_ADDRESS environment variable.\",\n );\n }\n return envUrl.trim().replace(/\\/+$/, \"\");\n}\n\nexport function getServerTrackablePages(): ModuleWithPermissions[] {\n return _serverConfig?.trackablePages ?? [];\n}\n\nfunction runServerBootstrapper(): void {\n if (_serverConfig?.bootstrapper) {\n _serverConfig.bootstrapper();\n }\n}\n\nfunction buildServerUrl(endpoint: string): string {\n const apiUrl = getServerApiUrl();\n return endpoint.startsWith(\"http\") ? endpoint : `${apiUrl}${endpoint}`;\n}\n\nexport async function ServerJsonApiGet(params: {\n classKey: ApiRequestDataTypeInterface;\n endpoint: string;\n companyId?: string;\n language: string;\n}): Promise<ApiResponseInterface> {\n runServerBootstrapper();\n const token = await getServerToken();\n\n const apiResponse = await serverRequest({\n method: \"GET\",\n url: buildServerUrl(params.endpoint),\n token,\n cache: params.classKey.cache,\n companyId: params.companyId,\n language: params.language,\n additionalHeaders: _serverConfig?.additionalHeaders,\n });\n\n return translateResponse({\n classKey: params.classKey,\n apiResponse,\n companyId: params.companyId,\n language: params.language,\n paginationHandler: async (endpoint: string) =>\n ServerJsonApiGet({\n classKey: params.classKey,\n endpoint,\n companyId: params.companyId,\n language: params.language,\n }),\n });\n}\n\nexport async function ServerJsonApiPost(params: {\n classKey: ApiRequestDataTypeInterface;\n endpoint: string;\n companyId?: string;\n body?: any;\n overridesJsonApiCreation?: boolean;\n files?: { [key: string]: File | Blob } | File | Blob;\n language: string;\n responseType?: ApiRequestDataTypeInterface;\n}): Promise<ApiResponseInterface> {\n runServerBootstrapper();\n const token = await getServerToken();\n\n let body = params.body;\n if (!body) {\n body = {};\n } else if (params.overridesJsonApiCreation !== true) {\n body = JsonApiDataFactory.create(params.classKey, body);\n }\n\n const apiResponse = await serverRequest({\n method: \"POST\",\n url: buildServerUrl(params.endpoint),\n token,\n body,\n files: params.files,\n companyId: params.companyId,\n language: params.language,\n additionalHeaders: _serverConfig?.additionalHeaders,\n });\n\n return translateResponse({\n classKey: params.responseType ?? params.classKey,\n apiResponse,\n companyId: params.companyId,\n language: params.language,\n });\n}\n\nexport async function ServerJsonApiPut(params: {\n classKey: ApiRequestDataTypeInterface;\n endpoint: string;\n companyId?: string;\n body?: any;\n files?: { [key: string]: File | Blob } | File | Blob;\n language: string;\n responseType?: ApiRequestDataTypeInterface;\n}): Promise<ApiResponseInterface> {\n runServerBootstrapper();\n const token = await getServerToken();\n\n let body = params.body;\n if (!body) {\n body = {};\n } else {\n body = JsonApiDataFactory.create(params.classKey, body);\n }\n\n const apiResponse = await serverRequest({\n method: \"PUT\",\n url: buildServerUrl(params.endpoint),\n token,\n body,\n files: params.files,\n companyId: params.companyId,\n language: params.language,\n additionalHeaders: _serverConfig?.additionalHeaders,\n });\n\n return translateResponse({\n classKey: params.responseType ?? params.classKey,\n apiResponse,\n companyId: params.companyId,\n language: params.language,\n });\n}\n\nexport async function ServerJsonApiPatch(params: {\n classKey: ApiRequestDataTypeInterface;\n endpoint: string;\n companyId?: string;\n body?: any;\n files?: { [key: string]: File | Blob } | File | Blob;\n overridesJsonApiCreation?: boolean;\n responseType?: ApiRequestDataTypeInterface;\n language: string;\n}): Promise<ApiResponseInterface> {\n runServerBootstrapper();\n const token = await getServerToken();\n\n let body = params.body;\n if (!body) {\n body = {};\n } else if (params.overridesJsonApiCreation !== true) {\n body = JsonApiDataFactory.create(params.classKey, body);\n }\n\n const apiResponse = await serverRequest({\n method: \"PATCH\",\n url: buildServerUrl(params.endpoint),\n token,\n body,\n files: params.files,\n companyId: params.companyId,\n language: params.language,\n additionalHeaders: _serverConfig?.additionalHeaders,\n });\n\n return translateResponse({\n classKey: params.responseType ?? params.classKey,\n apiResponse,\n companyId: params.companyId,\n language: params.language,\n });\n}\n\nexport async function ServerJsonApiDelete(params: {\n classKey: ApiRequestDataTypeInterface;\n endpoint: string;\n companyId?: string;\n language: string;\n responseType?: ApiRequestDataTypeInterface;\n}): Promise<ApiResponseInterface> {\n runServerBootstrapper();\n const token = await getServerToken();\n\n const apiResponse = await serverRequest({\n method: \"DELETE\",\n url: buildServerUrl(params.endpoint),\n token,\n companyId: params.companyId,\n language: params.language,\n additionalHeaders: _serverConfig?.additionalHeaders,\n });\n\n return translateResponse({\n classKey: params.responseType ?? params.classKey,\n apiResponse,\n companyId: params.companyId,\n language: params.language,\n });\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/server/cache.ts","../../src/server/ServerSession.ts","../../src/server/JsonApiServer.ts"],"sourcesContent":["// Server-only utilities (NOT server actions - these cannot be called from client components)\n\nimport { revalidateTag } from \"next/cache\";\n\nexport type CacheProfile = \"seconds\" | \"minutes\" | \"hours\" | \"days\" | \"weeks\" | \"max\" | \"default\";\n\n/**\n * Revalidate a cache tag to invalidate cached data.\n * Next.js 16+ requires a profile parameter.\n *\n * @param tag - The cache tag to invalidate\n * @param profile - The cache profile (defaults to \"max\" for immediate invalidation)\n */\nexport async function invalidateCacheTag(tag: string, profile: CacheProfile = \"max\"): Promise<void> {\n revalidateTag(tag, profile);\n}\n\n/**\n * Revalidate multiple cache tags.\n *\n * @param tags - Array of cache tags to invalidate\n * @param profile - The cache profile (defaults to \"max\" for immediate invalidation)\n */\nexport async function invalidateCacheTags(tags: string[], profile: CacheProfile = \"max\"): Promise<void> {\n for (const tag of tags) {\n revalidateTag(tag, profile);\n }\n}\n","import { cookies } from \"next/headers\";\nimport { redirect } from \"next/navigation\";\nimport { ungzip } from \"pako\";\nimport { Action, checkPermissionsFromServer, ModuleWithPermissions } from \"../permissions\";\n\nexport class ServerSession {\n static async isLogged() {\n const cookieStore = await cookies();\n const token = cookieStore.get(\"token\");\n\n if (!token || !token.value) return false;\n return true;\n }\n\n static async companyId() {\n const cookieStore = await cookies();\n return cookieStore.get(\"companyId\")?.value ?? \"\";\n }\n\n static async userId() {\n const cookieStore = await cookies();\n return cookieStore.get(\"userId\")?.value ?? \"\";\n }\n\n static async checkPermission<M extends ModuleWithPermissions>(params: { module: M; action: Action; data?: any }) {\n if (!(await this.hasPermissionToModule(params))) redirect(`/401`);\n }\n\n static async hasRole(roleId: string): Promise<boolean> {\n const cookieStore = await cookies();\n const roles = cookieStore.get(\"roles\")?.value;\n\n if (!roles || !roles.includes(roleId)) return false;\n\n return true;\n }\n\n static async hasFeature(featureId: string): Promise<boolean> {\n const cookieStore = await cookies();\n const features = cookieStore.get(\"features\")?.value;\n\n if (!features || !features.includes(featureId)) return false;\n\n return true;\n }\n\n static async hasPermissionToModule<M extends ModuleWithPermissions>(params: {\n module: M;\n action: Action;\n data?: any;\n }): Promise<boolean> {\n const cookieStore = await cookies();\n\n if (params.module.feature) {\n const features = cookieStore.get(\"features\")?.value;\n\n if (features && !features.includes(params.module.feature)) return false;\n }\n\n const rawModules = cookieStore.get(\"modules\")?.value;\n if (!rawModules) return false;\n\n const modules: {\n id: string;\n permissions: {\n create: boolean | string;\n read: boolean | string;\n update: boolean | string;\n delete: boolean | string;\n };\n }[] = JSON.parse(ungzip(Buffer.from(rawModules, \"base64\"), { toText: true }));\n\n const selectedModule = modules.find((module) => module.id === params.module.moduleId);\n\n return checkPermissionsFromServer({\n module: params.module,\n action: params.action,\n data: params.data,\n userId: await this.userId(),\n selectedModule: selectedModule,\n });\n\n // if (!selectedModule) return false;\n\n // if (!selectedModule.permissions[params.action]) return false;\n // if (typeof selectedModule.permissions[params.action] === \"boolean\")\n // return selectedModule.permissions[params.action] as boolean;\n\n // if (!params.data) return false;\n\n // return params.data[selectedModule.permissions[params.action] as string] === this.userId;\n }\n}\n","// Server-only utilities (NOT server actions - these cannot be called from client components)\n\nimport { JsonApiDataFactory } from \"../core/factories/JsonApiDataFactory\";\nimport { ApiRequestDataTypeInterface } from \"../core/interfaces/ApiRequestDataTypeInterface\";\nimport { ApiResponseInterface } from \"../core/interfaces/ApiResponseInterface\";\nimport { translateResponse } from \"../core/utils/translateResponse\";\nimport { ModuleWithPermissions } from \"../permissions/types\";\nimport { serverRequest } from \"./request\";\nimport { getServerToken } from \"./token\";\n\n// Config storage for server contexts\nlet _serverConfig: {\n apiUrl: string;\n appUrl?: string;\n trackablePages?: ModuleWithPermissions[];\n bootstrapper?: () => void;\n additionalHeaders?: Record<string, string>;\n} | null = null;\n\n/**\n * Configure the JSON:API server client.\n * Call this in your Bootstrapper or server initialization.\n */\nexport function configureServerJsonApi(config: {\n apiUrl: string;\n appUrl?: string;\n trackablePages?: ModuleWithPermissions[];\n bootstrapper?: () => void;\n additionalHeaders?: Record<string, string>;\n}): void {\n _serverConfig = config;\n if (config.bootstrapper) {\n config.bootstrapper();\n }\n}\n\nexport function getServerApiUrl(): string {\n if (_serverConfig?.apiUrl) {\n return _serverConfig.apiUrl;\n }\n const envUrl = process.env.NEXT_PUBLIC_API_URL;\n if (!envUrl) {\n throw new Error(\n \"API URL not configured. Use configureServerJsonApi() or set NEXT_PUBLIC_API_URL environment variable.\",\n );\n }\n return envUrl;\n}\n\nexport function getServerAppUrl(): string {\n if (_serverConfig?.appUrl) {\n return _serverConfig.appUrl;\n }\n const envUrl = process.env.NEXT_PUBLIC_ADDRESS;\n if (!envUrl) {\n throw new Error(\n \"App URL not configured. Use configureServerJsonApi({ appUrl }) or set NEXT_PUBLIC_ADDRESS environment variable.\",\n );\n }\n return envUrl.trim().replace(/\\/+$/, \"\");\n}\n\nexport function getServerTrackablePages(): ModuleWithPermissions[] {\n return _serverConfig?.trackablePages ?? [];\n}\n\nfunction runServerBootstrapper(): void {\n if (_serverConfig?.bootstrapper) {\n _serverConfig.bootstrapper();\n }\n}\n\nfunction buildServerUrl(endpoint: string): string {\n const apiUrl = getServerApiUrl();\n return endpoint.startsWith(\"http\") ? endpoint : `${apiUrl}${endpoint}`;\n}\n\nexport async function ServerJsonApiGet(params: {\n classKey: ApiRequestDataTypeInterface;\n endpoint: string;\n companyId?: string;\n language: string;\n}): Promise<ApiResponseInterface> {\n runServerBootstrapper();\n const token = await getServerToken();\n\n const apiResponse = await serverRequest({\n method: \"GET\",\n url: buildServerUrl(params.endpoint),\n token,\n cache: params.classKey.cache,\n companyId: params.companyId,\n language: params.language,\n additionalHeaders: _serverConfig?.additionalHeaders,\n });\n\n return translateResponse({\n classKey: params.classKey,\n apiResponse,\n companyId: params.companyId,\n language: params.language,\n paginationHandler: async (endpoint: string) =>\n ServerJsonApiGet({\n classKey: params.classKey,\n endpoint,\n companyId: params.companyId,\n language: params.language,\n }),\n });\n}\n\nexport async function ServerJsonApiPost(params: {\n classKey: ApiRequestDataTypeInterface;\n endpoint: string;\n companyId?: string;\n body?: any;\n overridesJsonApiCreation?: boolean;\n files?: { [key: string]: File | Blob } | File | Blob;\n language: string;\n responseType?: ApiRequestDataTypeInterface;\n}): Promise<ApiResponseInterface> {\n runServerBootstrapper();\n const token = await getServerToken();\n\n let body = params.body;\n if (!body) {\n body = {};\n } else if (params.overridesJsonApiCreation !== true) {\n body = JsonApiDataFactory.create(params.classKey, body);\n }\n\n const apiResponse = await serverRequest({\n method: \"POST\",\n url: buildServerUrl(params.endpoint),\n token,\n body,\n files: params.files,\n companyId: params.companyId,\n language: params.language,\n additionalHeaders: _serverConfig?.additionalHeaders,\n });\n\n return translateResponse({\n classKey: params.responseType ?? params.classKey,\n apiResponse,\n companyId: params.companyId,\n language: params.language,\n });\n}\n\nexport async function ServerJsonApiPut(params: {\n classKey: ApiRequestDataTypeInterface;\n endpoint: string;\n companyId?: string;\n body?: any;\n files?: { [key: string]: File | Blob } | File | Blob;\n language: string;\n responseType?: ApiRequestDataTypeInterface;\n}): Promise<ApiResponseInterface> {\n runServerBootstrapper();\n const token = await getServerToken();\n\n let body = params.body;\n if (!body) {\n body = {};\n } else {\n body = JsonApiDataFactory.create(params.classKey, body);\n }\n\n const apiResponse = await serverRequest({\n method: \"PUT\",\n url: buildServerUrl(params.endpoint),\n token,\n body,\n files: params.files,\n companyId: params.companyId,\n language: params.language,\n additionalHeaders: _serverConfig?.additionalHeaders,\n });\n\n return translateResponse({\n classKey: params.responseType ?? params.classKey,\n apiResponse,\n companyId: params.companyId,\n language: params.language,\n });\n}\n\nexport async function ServerJsonApiPatch(params: {\n classKey: ApiRequestDataTypeInterface;\n endpoint: string;\n companyId?: string;\n body?: any;\n files?: { [key: string]: File | Blob } | File | Blob;\n overridesJsonApiCreation?: boolean;\n responseType?: ApiRequestDataTypeInterface;\n language: string;\n}): Promise<ApiResponseInterface> {\n runServerBootstrapper();\n const token = await getServerToken();\n\n let body = params.body;\n if (!body) {\n body = {};\n } else if (params.overridesJsonApiCreation !== true) {\n body = JsonApiDataFactory.create(params.classKey, body);\n }\n\n const apiResponse = await serverRequest({\n method: \"PATCH\",\n url: buildServerUrl(params.endpoint),\n token,\n body,\n files: params.files,\n companyId: params.companyId,\n language: params.language,\n additionalHeaders: _serverConfig?.additionalHeaders,\n });\n\n return translateResponse({\n classKey: params.responseType ?? params.classKey,\n apiResponse,\n companyId: params.companyId,\n language: params.language,\n });\n}\n\nexport async function ServerJsonApiDelete(params: {\n classKey: ApiRequestDataTypeInterface;\n endpoint: string;\n companyId?: string;\n language: string;\n responseType?: ApiRequestDataTypeInterface;\n}): Promise<ApiResponseInterface> {\n runServerBootstrapper();\n const token = await getServerToken();\n\n const apiResponse = await serverRequest({\n method: \"DELETE\",\n url: buildServerUrl(params.endpoint),\n token,\n companyId: params.companyId,\n language: params.language,\n additionalHeaders: _serverConfig?.additionalHeaders,\n });\n\n return translateResponse({\n classKey: params.responseType ?? params.classKey,\n apiResponse,\n companyId: params.companyId,\n language: params.language,\n });\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@carlonicora/nextjs-jsonapi",
|
|
3
|
-
"version": "1.141.
|
|
3
|
+
"version": "1.141.2",
|
|
4
4
|
"description": "Next.js JSON:API client with server/client support and caching",
|
|
5
5
|
"author": "Carlo Nicora",
|
|
6
6
|
"license": "GPL-3.0-or-later",
|
|
@@ -112,96 +112,95 @@
|
|
|
112
112
|
}
|
|
113
113
|
},
|
|
114
114
|
"dependencies": {
|
|
115
|
-
"@base-ui/react": "1.
|
|
116
|
-
"@blocknote/core": "^0.
|
|
117
|
-
"@blocknote/react": "^0.
|
|
118
|
-
"@blocknote/shadcn": "^0.
|
|
119
|
-
"@blocknote/xl-ai": "^0.
|
|
120
|
-
"ai": "^6.0.5",
|
|
115
|
+
"@base-ui/react": "1.6.0",
|
|
116
|
+
"@blocknote/core": "^0.52.1",
|
|
117
|
+
"@blocknote/react": "^0.52.1",
|
|
118
|
+
"@blocknote/shadcn": "^0.52.1",
|
|
119
|
+
"@blocknote/xl-ai": "^0.52.1",
|
|
121
120
|
"@dnd-kit/core": "^6.3.1",
|
|
122
121
|
"@dnd-kit/sortable": "^10.0.0",
|
|
123
122
|
"@dnd-kit/utilities": "^3.2.2",
|
|
124
|
-
"@floating-ui/react": "^0.27.
|
|
123
|
+
"@floating-ui/react": "^0.27.20",
|
|
125
124
|
"@handlewithcare/prosemirror-inputrules": "^0.1.4",
|
|
126
|
-
"@hookform/resolvers": "^5.
|
|
127
|
-
"@radix-ui/react-label": "^2.1.
|
|
128
|
-
"@radix-ui/react-slot": "^1.
|
|
125
|
+
"@hookform/resolvers": "^5.5.7",
|
|
126
|
+
"@radix-ui/react-label": "^2.1.15",
|
|
127
|
+
"@radix-ui/react-slot": "^1.3.3",
|
|
129
128
|
"@simplewebauthn/browser": "^13.3.0",
|
|
129
|
+
"ai": "^6.0.238",
|
|
130
130
|
"class-variance-authority": "^0.7.1",
|
|
131
131
|
"clsx": "^2.1.1",
|
|
132
132
|
"cmdk": "^1.1.1",
|
|
133
133
|
"codice-fiscale-js": "^2.3.23",
|
|
134
|
-
"commander": "^
|
|
134
|
+
"commander": "^15.0.0",
|
|
135
135
|
"cookies-next": "^6.1.1",
|
|
136
136
|
"d3": "^7.9.0",
|
|
137
137
|
"dagre": "^0.8.5",
|
|
138
|
-
"date-fns": "^4.
|
|
138
|
+
"date-fns": "^4.4.0",
|
|
139
139
|
"embla-carousel-react": "^8.6.0",
|
|
140
|
+
"fuse.js": "^7.5.0",
|
|
140
141
|
"input-otp": "^1.4.2",
|
|
141
|
-
"jotai": "^2.20.
|
|
142
|
-
"jotai-family": "^1.0
|
|
143
|
-
"lucide-react": "^1.
|
|
142
|
+
"jotai": "^2.20.2",
|
|
143
|
+
"jotai-family": "^1.1.0",
|
|
144
|
+
"lucide-react": "^1.28.0",
|
|
145
|
+
"next-mdx-remote": "^6.0.0",
|
|
144
146
|
"next-themes": "^0.4.6",
|
|
145
|
-
"pako": "^
|
|
147
|
+
"pako": "^3.0.1",
|
|
146
148
|
"qrcode.react": "^4.2.0",
|
|
147
|
-
"react-day-picker": "^
|
|
148
|
-
"react-dropzone": "^
|
|
149
|
-
"react-hook-form": "
|
|
149
|
+
"react-day-picker": "^10.0.1",
|
|
150
|
+
"react-dropzone": "^19.1.1",
|
|
151
|
+
"react-hook-form": "7.83.0",
|
|
150
152
|
"react-markdown": "^10.1.0",
|
|
151
|
-
"react-resizable-panels": "^4.
|
|
152
|
-
"recharts": "^3.
|
|
153
|
-
"fuse.js": "^7.0.0",
|
|
154
|
-
"next-mdx-remote": "^5.0.0",
|
|
153
|
+
"react-resizable-panels": "^4.12.2",
|
|
154
|
+
"recharts": "^3.10.1",
|
|
155
155
|
"rehype-autolink-headings": "^7.1.0",
|
|
156
156
|
"rehype-slug": "^6.0.0",
|
|
157
157
|
"remark-gfm": "^4.0.1",
|
|
158
|
-
"shadcn": "^4.
|
|
158
|
+
"shadcn": "^4.16.1",
|
|
159
159
|
"shepherd.js": "^15.2.2",
|
|
160
160
|
"socket.io-client": "^4.8.3",
|
|
161
161
|
"sonner": "^2.0.7",
|
|
162
162
|
"tailwind-merge": "^3.6.0",
|
|
163
163
|
"tw-animate-css": "^1.4.0",
|
|
164
|
-
"uuid": "^14.0.
|
|
164
|
+
"uuid": "^14.0.1",
|
|
165
165
|
"vaul": "^1.1.2",
|
|
166
166
|
"zod": "^4.4.3"
|
|
167
167
|
},
|
|
168
168
|
"devDependencies": {
|
|
169
|
-
"@eslint/eslintrc": "^3.3.
|
|
170
|
-
"@eslint/js": "^9.39.
|
|
171
|
-
"@semantic-release/changelog": "^
|
|
172
|
-
"@semantic-release/git": "^
|
|
169
|
+
"@eslint/eslintrc": "^3.3.6",
|
|
170
|
+
"@eslint/js": "^9.39.5",
|
|
171
|
+
"@semantic-release/changelog": "^7.0.0",
|
|
172
|
+
"@semantic-release/git": "^11.0.1",
|
|
173
173
|
"@tanstack/react-table": "^8.21.3",
|
|
174
174
|
"@testing-library/dom": "^10.4.1",
|
|
175
|
-
"@testing-library/jest-dom": "^
|
|
175
|
+
"@testing-library/jest-dom": "^7.0.0",
|
|
176
176
|
"@testing-library/react": "^16.3.2",
|
|
177
177
|
"@testing-library/user-event": "^14.6.1",
|
|
178
178
|
"@types/d3": "^7.4.3",
|
|
179
179
|
"@types/dagre": "^0.7.54",
|
|
180
|
-
"@types/node": "^
|
|
181
|
-
"@types/pako": "^2.0.4",
|
|
180
|
+
"@types/node": "^26.1.2",
|
|
182
181
|
"@types/qrcode.react": "^3.0.0",
|
|
183
|
-
"@types/react": "
|
|
184
|
-
"@types/react-dom": "
|
|
185
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
186
|
-
"@typescript-eslint/parser": "^8.
|
|
187
|
-
"@vitejs/plugin-react": "^6.0.
|
|
188
|
-
"@vitest/coverage-v8": "^4.1.
|
|
189
|
-
"@vitest/ui": "^4.1.
|
|
190
|
-
"conventional-changelog-conventionalcommits": "^
|
|
191
|
-
"eslint": "^9.39.
|
|
182
|
+
"@types/react": "19.2.18",
|
|
183
|
+
"@types/react-dom": "19.2.4",
|
|
184
|
+
"@typescript-eslint/eslint-plugin": "^8.65.0",
|
|
185
|
+
"@typescript-eslint/parser": "^8.65.0",
|
|
186
|
+
"@vitejs/plugin-react": "^6.0.5",
|
|
187
|
+
"@vitest/coverage-v8": "^4.1.10",
|
|
188
|
+
"@vitest/ui": "^4.1.10",
|
|
189
|
+
"conventional-changelog-conventionalcommits": "^10.2.1",
|
|
190
|
+
"eslint": "^9.39.5",
|
|
192
191
|
"eslint-config-prettier": "^10.1.8",
|
|
193
|
-
"eslint-plugin-prettier": "^5.5.
|
|
194
|
-
"globals": "^17.
|
|
195
|
-
"jsdom": "^
|
|
196
|
-
"next": "^16.2.
|
|
197
|
-
"next-intl": "^4.
|
|
198
|
-
"prettier": "^3.
|
|
199
|
-
"react": "
|
|
200
|
-
"react-dom": "
|
|
201
|
-
"semantic-release": "^25.0.
|
|
192
|
+
"eslint-plugin-prettier": "^5.5.6",
|
|
193
|
+
"globals": "^17.8.0",
|
|
194
|
+
"jsdom": "^30.0.1",
|
|
195
|
+
"next": "^16.2.12",
|
|
196
|
+
"next-intl": "^4.13.4",
|
|
197
|
+
"prettier": "^3.9.6",
|
|
198
|
+
"react": "19.2.8",
|
|
199
|
+
"react-dom": "19.2.8",
|
|
200
|
+
"semantic-release": "^25.0.8",
|
|
202
201
|
"tsup": "^8.5.1",
|
|
203
202
|
"typescript": "^5.9.3",
|
|
204
|
-
"vitest": "^4.1.
|
|
203
|
+
"vitest": "^4.1.10"
|
|
205
204
|
},
|
|
206
205
|
"keywords": [
|
|
207
206
|
"nextjs",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import { useTranslations } from "next-intl";
|
|
4
|
-
import { ReactElement, ReactNode, useCallback, useEffect, useRef } from "react";
|
|
4
|
+
import { isValidElement, ReactElement, ReactNode, useCallback, useEffect, useRef } from "react";
|
|
5
5
|
import { FieldValues, UseFormReturn } from "react-hook-form";
|
|
6
6
|
import { PencilIcon } from "lucide-react";
|
|
7
7
|
import { ModuleWithPermissions } from "../../permissions/types";
|
|
@@ -24,6 +24,39 @@ import { errorToast } from "../errors/errorToast";
|
|
|
24
24
|
|
|
25
25
|
type EditorSheetSize = "sm" | "md" | "lg" | "xl" | "2xl";
|
|
26
26
|
|
|
27
|
+
/**
|
|
28
|
+
* Resolve the `nativeButton` contract for a caller-supplied `trigger`.
|
|
29
|
+
*
|
|
30
|
+
* Base UI checks `nativeButton` against the element the trigger ACTUALLY puts in
|
|
31
|
+
* the DOM and logs an error when the two disagree — in BOTH directions (see
|
|
32
|
+
* `@base-ui/react/internals/use-button/useButton`: "expected a native <button>"
|
|
33
|
+
* / "expected a non-<button>"). Since `trigger` is supplied by the call site and
|
|
34
|
+
* this package has two live conventions, no constant is correct for all of them:
|
|
35
|
+
*
|
|
36
|
+
* - `<Button render={<div />} nativeButton={false}>` — the pointer-cursor
|
|
37
|
+
* convention documented in this package's CLAUDE.md — renders a `<div>`.
|
|
38
|
+
* - a plain `<Button>` / `<button>` / `<Button render={<Link />}>` renders a
|
|
39
|
+
* native `<button>` / a native `<button>` / an `<a>` respectively.
|
|
40
|
+
*
|
|
41
|
+
* So derive it from the element instead of hardcoding it.
|
|
42
|
+
*/
|
|
43
|
+
function resolveTriggerIsNativeButton(trigger: ReactNode): boolean {
|
|
44
|
+
if (!isValidElement(trigger)) return true;
|
|
45
|
+
|
|
46
|
+
const props = (trigger.props ?? {}) as { nativeButton?: boolean; render?: unknown };
|
|
47
|
+
|
|
48
|
+
// The call site already declared the contract for its own element — honour it.
|
|
49
|
+
if (typeof props.nativeButton === "boolean") return props.nativeButton;
|
|
50
|
+
|
|
51
|
+
// `render={<X />}` means X is what reaches the DOM (e.g. <Link> → <a>, <div>).
|
|
52
|
+
if (isValidElement(props.render)) return props.render.type === "button";
|
|
53
|
+
|
|
54
|
+
// Intrinsic tags: only <button> is native. Components (this package's <Button>
|
|
55
|
+
// and the Base UI primitives) default to rendering a native <button>.
|
|
56
|
+
if (typeof trigger.type === "string") return trigger.type === "button";
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
|
|
27
60
|
const sizeClasses: Record<EditorSheetSize, string> = {
|
|
28
61
|
sm: "data-[side=right]:sm:max-w-2xl",
|
|
29
62
|
md: "data-[side=right]:sm:max-w-3xl",
|
|
@@ -212,12 +245,13 @@ export function EditorSheet<T extends FieldValues>({
|
|
|
212
245
|
// <button> inside SheetTrigger's <button> (invalid HTML / hydration
|
|
213
246
|
// error). `render` also preserves the element's native `disabled`.
|
|
214
247
|
//
|
|
215
|
-
// `nativeButton
|
|
216
|
-
//
|
|
217
|
-
//
|
|
218
|
-
//
|
|
219
|
-
//
|
|
220
|
-
|
|
248
|
+
// `nativeButton` must match the element the trigger actually renders,
|
|
249
|
+
// or Base UI logs a semantics/accessibility error at runtime. Call
|
|
250
|
+
// sites pass BOTH kinds — a native `<Button>` and the div-rendering
|
|
251
|
+
// `<Button render={<div />} nativeButton={false}>` convention — so it
|
|
252
|
+
// is resolved per trigger rather than hardcoded (a constant `false`
|
|
253
|
+
// warned on every native-button trigger).
|
|
254
|
+
<SheetTrigger nativeButton={resolveTriggerIsNativeButton(trigger)} render={trigger as ReactElement} />
|
|
221
255
|
) : (
|
|
222
256
|
<SheetTrigger>
|
|
223
257
|
{isEdit ? (
|
|
@@ -31,6 +31,12 @@ export type { DropzoneOptions } from "react-dropzone";
|
|
|
31
31
|
|
|
32
32
|
type DirectionOptions = "rtl" | "ltr" | undefined;
|
|
33
33
|
|
|
34
|
+
/**
|
|
35
|
+
* One entry of react-dropzone 19.3's grouped `accept` form. Declared locally rather than
|
|
36
|
+
* imported because 19.1 has no `AcceptGroup` export, and this file must compile against both.
|
|
37
|
+
*/
|
|
38
|
+
type AcceptGroupLike = { description?: string; accept: Accept };
|
|
39
|
+
|
|
34
40
|
type FileUploaderContextType = {
|
|
35
41
|
dropzoneState: DropzoneState;
|
|
36
42
|
isLOF: boolean;
|
|
@@ -40,7 +46,9 @@ type FileUploaderContextType = {
|
|
|
40
46
|
setActiveIndex: Dispatch<SetStateAction<number>>;
|
|
41
47
|
orientation: "horizontal" | "vertical";
|
|
42
48
|
direction: DirectionOptions;
|
|
43
|
-
|
|
49
|
+
// Mirrors whatever react-dropzone declares: 19.1 had `Accept`, 19.3 widened it to
|
|
50
|
+
// `Accept | AcceptGroup[]`. Indexing the option type keeps this correct on both.
|
|
51
|
+
accept?: DropzoneOptions["accept"];
|
|
44
52
|
};
|
|
45
53
|
|
|
46
54
|
const FileUploaderContext = createContext<FileUploaderContextType | null>(null);
|
|
@@ -332,11 +340,18 @@ export const FileInput = forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDiv
|
|
|
332
340
|
|
|
333
341
|
const acceptedLabels = useMemo(() => {
|
|
334
342
|
if (!accept) return null;
|
|
343
|
+
// react-dropzone 19.3 made two changes to `accept`: it allows a grouped form
|
|
344
|
+
// (`{ description?, accept }[]`) beside the flat MIME -> extensions record, and it widened
|
|
345
|
+
// each value from `readonly string[]` to `string | readonly string[]`. Normalise both so a
|
|
346
|
+
// single-extension string is not iterated character by character.
|
|
347
|
+
const entries: [string, string | readonly string[]][] = Array.isArray(accept)
|
|
348
|
+
? accept.flatMap((group: AcceptGroupLike) => Object.entries(group.accept))
|
|
349
|
+
: Object.entries(accept);
|
|
335
350
|
const extensions = new Set<string>();
|
|
336
351
|
let hasWildcardImages = false;
|
|
337
|
-
for (const [mime, exts] of
|
|
352
|
+
for (const [mime, exts] of entries) {
|
|
338
353
|
if (mime === "image/*") hasWildcardImages = true;
|
|
339
|
-
for (const ext of exts) extensions.add(ext);
|
|
354
|
+
for (const ext of typeof exts === "string" ? [exts] : exts) extensions.add(ext);
|
|
340
355
|
}
|
|
341
356
|
const labels = Array.from(extensions).sort();
|
|
342
357
|
if (hasWildcardImages) labels.push(t("ui.labels.images"));
|
|
@@ -92,8 +92,7 @@ export function FormInput({
|
|
|
92
92
|
autoFocus: autoFocus === true,
|
|
93
93
|
type: type === "password" ? "password" : "text",
|
|
94
94
|
inputMode: (type === "number" || type === "currency" || type === "decimal" ? "decimal" : undefined) as
|
|
95
|
-
|
|
96
|
-
| undefined,
|
|
95
|
+
"decimal" | undefined,
|
|
97
96
|
className: `w-full ${type === "number" || type === "currency" || type === "decimal" ? "text-end" : ""}`,
|
|
98
97
|
disabled: disabled === true || form.formState.isSubmitting,
|
|
99
98
|
placeholder: placeholder || "",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Server-only cookie utilities (consumers should provide their own server actions via configureAuth)
|
|
2
2
|
|
|
3
3
|
import { cookies } from "next/headers";
|
|
4
|
-
import
|
|
4
|
+
import { gzip } from "pako";
|
|
5
5
|
|
|
6
6
|
export async function updateToken(params: {
|
|
7
7
|
token?: string;
|
|
@@ -82,7 +82,7 @@ export async function updateToken(params: {
|
|
|
82
82
|
});
|
|
83
83
|
|
|
84
84
|
if (params.modules) {
|
|
85
|
-
const compressedValue = Buffer.from(
|
|
85
|
+
const compressedValue = Buffer.from(gzip(JSON.stringify(params.modules))).toString("base64");
|
|
86
86
|
|
|
87
87
|
(await cookies()).set({
|
|
88
88
|
name: "modules",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { cookies } from "next/headers";
|
|
2
2
|
import { redirect } from "next/navigation";
|
|
3
|
-
import
|
|
3
|
+
import { ungzip } from "pako";
|
|
4
4
|
import { Action, checkPermissionsFromServer, ModuleWithPermissions } from "../permissions";
|
|
5
5
|
|
|
6
6
|
export class ServerSession {
|
|
@@ -68,7 +68,7 @@ export class ServerSession {
|
|
|
68
68
|
update: boolean | string;
|
|
69
69
|
delete: boolean | string;
|
|
70
70
|
};
|
|
71
|
-
}[] = JSON.parse(
|
|
71
|
+
}[] = JSON.parse(ungzip(Buffer.from(rawModules, "base64"), { toText: true }));
|
|
72
72
|
|
|
73
73
|
const selectedModule = modules.find((module) => module.id === params.module.moduleId);
|
|
74
74
|
|
|
@@ -70,7 +70,7 @@ function Calendar({
|
|
|
70
70
|
: "cn-calendar-caption-label rounded-(--cell-radius) flex items-center gap-1 text-sm [&>svg]:text-muted-foreground [&>svg]:size-3.5",
|
|
71
71
|
defaultClassNames.caption_label,
|
|
72
72
|
),
|
|
73
|
-
|
|
73
|
+
month_grid: cn("w-full border-collapse", defaultClassNames.month_grid),
|
|
74
74
|
weekdays: cn("flex", defaultClassNames.weekdays),
|
|
75
75
|
weekday: cn(
|
|
76
76
|
"text-muted-foreground rounded-(--cell-radius) flex-1 font-normal text-xs select-none",
|