nextjs-cms 0.9.21 → 0.9.23

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 (190) hide show
  1. package/README.md +65 -13
  2. package/dist/api/actions/files.d.ts +30 -0
  3. package/dist/api/actions/files.d.ts.map +1 -0
  4. package/dist/api/actions/files.js +234 -0
  5. package/dist/api/actions/index.d.ts +4 -0
  6. package/dist/api/actions/index.d.ts.map +1 -0
  7. package/dist/api/actions/index.js +3 -0
  8. package/dist/api/actions/pages.d.ts +297 -0
  9. package/dist/api/actions/pages.d.ts.map +1 -0
  10. package/dist/api/actions/pages.js +1215 -0
  11. package/dist/api/actions/privileges.d.ts +25 -0
  12. package/dist/api/actions/privileges.d.ts.map +1 -0
  13. package/dist/api/actions/privileges.js +98 -0
  14. package/dist/api/client/index.d.ts +4 -0
  15. package/dist/api/client/index.d.ts.map +1 -0
  16. package/dist/api/client/index.js +3 -0
  17. package/dist/api/client.d.ts +30 -0
  18. package/dist/api/client.d.ts.map +1 -0
  19. package/dist/api/client.js +82 -0
  20. package/dist/api/index.d.ts +1 -938
  21. package/dist/api/index.d.ts.map +1 -1
  22. package/dist/api/index.js +0 -13
  23. package/dist/api/lib/serverActions.d.ts +3 -3
  24. package/dist/api/plugin/index.d.ts +7 -0
  25. package/dist/api/plugin/index.d.ts.map +1 -0
  26. package/dist/api/plugin/index.js +5 -0
  27. package/dist/api/root.d.ts +18 -1844
  28. package/dist/api/root.d.ts.map +1 -1
  29. package/dist/api/root.js +18 -83
  30. package/dist/api/routers/navigation.d.ts +3 -3
  31. package/dist/api/server/index.d.ts +8 -0
  32. package/dist/api/server/index.d.ts.map +1 -0
  33. package/dist/api/server/index.js +3 -0
  34. package/dist/api/server.d.ts +2748 -0
  35. package/dist/api/server.d.ts.map +1 -0
  36. package/dist/api/server.js +100 -0
  37. package/dist/api/trpc/client.d.ts +19 -3
  38. package/dist/api/trpc/client.d.ts.map +1 -1
  39. package/dist/api/trpc/client.js +55 -1
  40. package/dist/api/trpc/query-client.d.ts +3 -1
  41. package/dist/api/trpc/query-client.d.ts.map +1 -1
  42. package/dist/api/trpc/query-client.js +25 -20
  43. package/dist/api/trpc/root.d.ts +906 -0
  44. package/dist/api/trpc/root.d.ts.map +1 -0
  45. package/dist/api/trpc/root.js +47 -0
  46. package/dist/api/trpc/routers/accountSettings.d.ts +66 -0
  47. package/dist/api/trpc/routers/accountSettings.d.ts.map +1 -0
  48. package/dist/api/trpc/routers/accountSettings.js +200 -0
  49. package/dist/api/trpc/routers/admins.d.ts +112 -0
  50. package/dist/api/trpc/routers/admins.d.ts.map +1 -0
  51. package/dist/api/trpc/routers/admins.js +331 -0
  52. package/dist/api/trpc/routers/auth.d.ts +54 -0
  53. package/dist/api/trpc/routers/auth.d.ts.map +1 -0
  54. package/dist/api/trpc/routers/auth.js +50 -0
  55. package/dist/api/trpc/routers/categorySection.d.ts +105 -0
  56. package/dist/api/trpc/routers/categorySection.d.ts.map +1 -0
  57. package/dist/api/trpc/routers/categorySection.js +49 -0
  58. package/dist/api/trpc/routers/config.d.ts +48 -0
  59. package/dist/api/trpc/routers/config.d.ts.map +1 -0
  60. package/dist/api/trpc/routers/config.js +18 -0
  61. package/dist/api/trpc/routers/cpanel.d.ts +82 -0
  62. package/dist/api/trpc/routers/cpanel.d.ts.map +1 -0
  63. package/dist/api/trpc/routers/cpanel.js +216 -0
  64. package/dist/api/trpc/routers/fields.d.ts +35 -0
  65. package/dist/api/trpc/routers/fields.d.ts.map +1 -0
  66. package/dist/api/trpc/routers/fields.js +81 -0
  67. package/dist/api/trpc/routers/files.d.ts +34 -0
  68. package/dist/api/trpc/routers/files.d.ts.map +1 -0
  69. package/dist/api/trpc/routers/files.js +14 -0
  70. package/dist/api/trpc/routers/gallery.d.ts +35 -0
  71. package/dist/api/trpc/routers/gallery.d.ts.map +1 -0
  72. package/dist/api/trpc/routers/gallery.js +92 -0
  73. package/dist/api/trpc/routers/hasItemsSection.d.ts +194 -0
  74. package/dist/api/trpc/routers/hasItemsSection.d.ts.map +1 -0
  75. package/dist/api/trpc/routers/hasItemsSection.js +86 -0
  76. package/dist/api/trpc/routers/logs.d.ts +59 -0
  77. package/dist/api/trpc/routers/logs.d.ts.map +1 -0
  78. package/dist/api/trpc/routers/logs.js +79 -0
  79. package/dist/api/trpc/routers/navigation.d.ts +65 -0
  80. package/dist/api/trpc/routers/navigation.d.ts.map +1 -0
  81. package/dist/api/trpc/routers/navigation.js +11 -0
  82. package/dist/api/trpc/routers/simpleSection.d.ts +93 -0
  83. package/dist/api/trpc/routers/simpleSection.d.ts.map +1 -0
  84. package/dist/api/trpc/routers/simpleSection.js +54 -0
  85. package/dist/api/trpc/server.d.ts +2789 -5
  86. package/dist/api/trpc/server.d.ts.map +1 -1
  87. package/dist/api/trpc/server.js +91 -52
  88. package/dist/api/trpc/trpc.d.ts +111 -0
  89. package/dist/api/trpc/trpc.d.ts.map +1 -0
  90. package/dist/api/trpc/trpc.js +99 -0
  91. package/dist/api/trpc/utils/async-caller-proxy.d.ts +2 -0
  92. package/dist/api/trpc/utils/async-caller-proxy.d.ts.map +1 -0
  93. package/dist/api/trpc/utils/async-caller-proxy.js +38 -0
  94. package/dist/api/trpc/utils/refresh-token-link.d.ts +6 -0
  95. package/dist/api/trpc/utils/refresh-token-link.d.ts.map +1 -0
  96. package/dist/api/trpc/utils/refresh-token-link.js +81 -0
  97. package/dist/api/trpc/utils/router-types.d.ts +7 -0
  98. package/dist/api/trpc/utils/router-types.d.ts.map +1 -0
  99. package/dist/api/trpc/utils/router-types.js +0 -0
  100. package/dist/api/use-axios-private.d.ts +6 -0
  101. package/dist/api/use-axios-private.d.ts.map +1 -0
  102. package/dist/api/use-axios-private.js +57 -0
  103. package/dist/api/utils/async-caller-proxy.d.ts +2 -0
  104. package/dist/api/utils/async-caller-proxy.d.ts.map +1 -0
  105. package/dist/api/utils/async-caller-proxy.js +36 -0
  106. package/dist/api/utils/lazy-caller-proxy.d.ts +2 -0
  107. package/dist/api/utils/lazy-caller-proxy.d.ts.map +1 -0
  108. package/dist/api/utils/lazy-caller-proxy.js +36 -0
  109. package/dist/api/utils/router-types.d.ts +7 -0
  110. package/dist/api/utils/router-types.d.ts.map +1 -0
  111. package/dist/api/utils/router-types.js +0 -0
  112. package/dist/auth/hooks/index.d.ts +1 -2
  113. package/dist/auth/hooks/index.d.ts.map +1 -1
  114. package/dist/auth/hooks/index.js +1 -2
  115. package/dist/auth/react.d.ts +1 -2
  116. package/dist/auth/react.d.ts.map +1 -1
  117. package/dist/auth/react.js +1 -2
  118. package/dist/auth/trpc.d.ts +1 -1
  119. package/dist/auth/trpc.d.ts.map +1 -1
  120. package/dist/auth/trpc.js +0 -1
  121. package/dist/cli/lib/fix-master-admin.d.ts.map +1 -1
  122. package/dist/cli/lib/fix-master-admin.js +12 -25
  123. package/dist/cli/lib/update-sections.d.ts.map +1 -1
  124. package/dist/cli/lib/update-sections.js +90 -46
  125. package/dist/core/config/config-loader.d.ts +23 -7
  126. package/dist/core/config/config-loader.d.ts.map +1 -1
  127. package/dist/core/config/config-loader.js +26 -9
  128. package/dist/core/db/table-checker/MysqlTable.d.ts.map +1 -1
  129. package/dist/core/db/table-checker/MysqlTable.js +3 -1
  130. package/dist/core/fields/date-range.d.ts +4 -4
  131. package/dist/core/fields/select.d.ts +1 -1
  132. package/dist/core/sections/category.d.ts +8 -8
  133. package/dist/core/sections/hasItems.d.ts +8 -8
  134. package/dist/core/sections/section.d.ts +5 -5
  135. package/dist/core/sections/simple.d.ts +4 -4
  136. package/dist/core/types/index.d.ts +17 -0
  137. package/dist/core/types/index.d.ts.map +1 -1
  138. package/dist/index.d.ts +0 -1
  139. package/dist/index.d.ts.map +1 -1
  140. package/dist/index.js +0 -1
  141. package/dist/plugins/client.d.ts +19 -0
  142. package/dist/plugins/client.d.ts.map +1 -0
  143. package/dist/plugins/client.js +24 -0
  144. package/dist/plugins/define.d.ts +4 -0
  145. package/dist/plugins/define.d.ts.map +1 -0
  146. package/dist/plugins/define.js +3 -0
  147. package/dist/plugins/derive.d.ts +32 -0
  148. package/dist/plugins/derive.d.ts.map +1 -0
  149. package/dist/plugins/derive.js +77 -0
  150. package/dist/plugins/loader.d.ts +51 -7
  151. package/dist/plugins/loader.d.ts.map +1 -1
  152. package/dist/plugins/loader.js +111 -51
  153. package/dist/plugins/manifest.d.ts +28 -0
  154. package/dist/plugins/manifest.d.ts.map +1 -0
  155. package/dist/plugins/manifest.js +83 -0
  156. package/dist/plugins/prefetch.d.ts +16 -0
  157. package/dist/plugins/prefetch.d.ts.map +1 -0
  158. package/dist/plugins/prefetch.js +40 -0
  159. package/dist/plugins/registry.d.ts +22 -0
  160. package/dist/plugins/registry.d.ts.map +1 -0
  161. package/dist/plugins/registry.js +25 -0
  162. package/dist/plugins/server.d.ts +2 -0
  163. package/dist/plugins/server.d.ts.map +1 -1
  164. package/dist/plugins/server.js +2 -0
  165. package/dist/plugins/types.d.ts +9 -0
  166. package/dist/plugins/types.d.ts.map +1 -0
  167. package/dist/plugins/types.js +0 -0
  168. package/dist/translations/base/en.d.ts +5 -0
  169. package/dist/translations/base/en.d.ts.map +1 -1
  170. package/dist/translations/base/en.js +5 -0
  171. package/dist/translations/client.d.ts +64 -4
  172. package/dist/translations/client.d.ts.map +1 -1
  173. package/dist/translations/server.d.ts +64 -4
  174. package/dist/translations/server.d.ts.map +1 -1
  175. package/dist/utils/console-log.d.ts +18 -0
  176. package/dist/utils/console-log.d.ts.map +1 -0
  177. package/dist/utils/console-log.js +28 -0
  178. package/dist/utils/index.d.ts +1 -0
  179. package/dist/utils/index.d.ts.map +1 -1
  180. package/dist/utils/index.js +1 -0
  181. package/dist/utils/log.d.ts +18 -0
  182. package/dist/utils/log.d.ts.map +1 -0
  183. package/dist/utils/log.js +28 -0
  184. package/dist/validators/index.d.ts +1 -0
  185. package/dist/validators/index.d.ts.map +1 -1
  186. package/dist/validators/index.js +1 -0
  187. package/dist/validators/tags.d.ts +4 -0
  188. package/dist/validators/tags.d.ts.map +1 -0
  189. package/dist/validators/tags.js +8 -0
  190. package/package.json +36 -18
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lazy-caller-proxy.d.ts","sourceRoot":"","sources":["../../../src/api/utils/lazy-caller-proxy.ts"],"names":[],"mappings":"AAWA,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAyBzF"}
@@ -0,0 +1,36 @@
1
+ const resolveCallerPath = (root, path) => {
2
+ let current = root;
3
+ for (const key of path) {
4
+ if (!current || (typeof current !== 'object' && typeof current !== 'function')) {
5
+ return undefined;
6
+ }
7
+ current = current[key];
8
+ }
9
+ return current;
10
+ };
11
+ export function createLazyCallerProxy(getCaller) {
12
+ const callProcedure = async (path, args) => {
13
+ const caller = await getCaller();
14
+ const proc = resolveCallerPath(caller, path);
15
+ if (typeof proc !== 'function') {
16
+ throw new Error(`tRPC procedure not found: ${path.join('.')}`);
17
+ }
18
+ return proc(...args);
19
+ };
20
+ const createCallerProxy = (path = []) => {
21
+ const proxyTarget = (...args) => callProcedure(path, args);
22
+ return new Proxy(proxyTarget, {
23
+ get(_target, prop) {
24
+ if (prop === 'then')
25
+ return undefined;
26
+ if (typeof prop !== 'string')
27
+ return undefined;
28
+ return createCallerProxy([...path, prop]);
29
+ },
30
+ apply(_target, _thisArg, args) {
31
+ return callProcedure(path, args);
32
+ },
33
+ });
34
+ };
35
+ return createCallerProxy();
36
+ }
@@ -0,0 +1,7 @@
1
+ import type { AnyRouter } from '@trpc/server';
2
+ import type { CoreRouters } from '../root.js';
3
+ export type RouterRecord = Record<string, AnyRouter>;
4
+ export type NonConflictingRouterRecord<TUser extends RouterRecord> = Extract<keyof TUser, keyof CoreRouters> extends never ? TUser : {
5
+ [K in keyof TUser]: K extends keyof CoreRouters ? never : TUser[K];
6
+ };
7
+ //# sourceMappingURL=router-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"router-types.d.ts","sourceRoot":"","sources":["../../../src/api/utils/router-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAE7C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAE7C,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;AAEpD,MAAM,MAAM,0BAA0B,CAAC,KAAK,SAAS,YAAY,IAC7D,OAAO,CAAC,MAAM,KAAK,EAAE,MAAM,WAAW,CAAC,SAAS,KAAK,GAC/C,KAAK,GACL;KACK,CAAC,IAAI,MAAM,KAAK,GAAG,CAAC,SAAS,MAAM,WAAW,GAAG,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC;CACrE,CAAA"}
File without changes
@@ -1,4 +1,3 @@
1
- import useAxiosPrivate from './useAxiosPrivate.js';
2
1
  import useRefreshToken from './useRefreshToken.js';
3
- export { useAxiosPrivate, useRefreshToken };
2
+ export { useRefreshToken };
4
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/auth/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,MAAM,sBAAsB,CAAA;AAClD,OAAO,eAAe,MAAM,sBAAsB,CAAA;AAElD,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/auth/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,MAAM,sBAAsB,CAAA;AAElD,OAAO,EAAE,eAAe,EAAE,CAAA"}
@@ -1,3 +1,2 @@
1
- import useAxiosPrivate from './useAxiosPrivate.js';
2
1
  import useRefreshToken from './useRefreshToken.js';
3
- export { useAxiosPrivate, useRefreshToken };
2
+ export { useRefreshToken };
@@ -3,7 +3,7 @@
3
3
  */
4
4
  import * as React from 'react';
5
5
  import type { Session } from './index.js';
6
- import useAxiosPrivate from './hooks/useAxiosPrivate.js';
6
+ import useAxiosPrivate from '../api/use-axios-private.js';
7
7
  import useRefreshToken from './hooks/useRefreshToken.js';
8
8
  export type UpdateSession = (data?: any) => Promise<Session | null>;
9
9
  export interface SessionProviderProps {
@@ -109,5 +109,4 @@ export declare function useSession<R extends boolean>(options?: UseSessionOption
109
109
  */
110
110
  export declare function SessionProvider(props: SessionProviderProps): React.JSX.Element;
111
111
  export { useAxiosPrivate, useRefreshToken };
112
- export { refreshTokenLink } from './trpc';
113
112
  //# sourceMappingURL=react.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../../src/auth/react.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../../src/auth/react.tsx"],"names":[],"mappings":"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"}
@@ -5,7 +5,7 @@
5
5
  import * as React from 'react';
6
6
  import { fetchData, now, useOnline } from './lib/client.js';
7
7
  import { useRouter } from 'next/navigation';
8
- import useAxiosPrivate from './hooks/useAxiosPrivate.js';
8
+ import useAxiosPrivate from '../api/use-axios-private.js';
9
9
  import useRefreshToken from './hooks/useRefreshToken.js';
10
10
  import { setLoginPageLanguageCookie, clearLanguageChangedOnLogin } from '../translations/language-cookie.js';
11
11
  export const __AUTH = {
@@ -378,4 +378,3 @@ export function SessionProvider(props) {
378
378
  return React.createElement(SessionContext.Provider, { value: value }, children);
379
379
  }
380
380
  export { useAxiosPrivate, useRefreshToken };
381
- export { refreshTokenLink } from './trpc';
@@ -2,5 +2,5 @@ import type { TRPCLink } from '@trpc/client';
2
2
  /**
3
3
  * tRPC link that refreshes the token if it's expired
4
4
  */
5
- export declare const refreshTokenLink: () => TRPCLink</*AppRouter*/ any>;
5
+ export declare const refreshTokenLink: () => TRPCLink<any>;
6
6
  //# sourceMappingURL=trpc.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"trpc.d.ts","sourceRoot":"","sources":["../../src/auth/trpc.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAM5C;;GAEG;AACH,eAAO,MAAM,gBAAgB,QAAO,QAAQ,CAAC,aAAa,CAAC,GAAG,CA6E7D,CAAA"}
1
+ {"version":3,"file":"trpc.d.ts","sourceRoot":"","sources":["../../src/auth/trpc.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAK5C;;GAEG;AACH,eAAO,MAAM,gBAAgB,QAAO,QAAQ,CAAC,GAAG,CA6E/C,CAAA"}
package/dist/auth/trpc.js CHANGED
@@ -1,5 +1,4 @@
1
1
  import { observable } from '@trpc/server/observable';
2
- // import type { AppRouter } from '../api'
3
2
  import { logout, refreshSession } from './react.js';
4
3
  /**
5
4
  * tRPC link that refreshes the token if it's expired
@@ -1 +1 @@
1
- {"version":3,"file":"fix-master-admin.d.ts","sourceRoot":"","sources":["../../../src/cli/lib/fix-master-admin.ts"],"names":[],"mappings":"AAEA,wBAAsB,wBAAwB,kBA2D7C"}
1
+ {"version":3,"file":"fix-master-admin.d.ts","sourceRoot":"","sources":["../../../src/cli/lib/fix-master-admin.ts"],"names":[],"mappings":"AAGA,wBAAsB,wBAAwB,kBAyC7C"}
@@ -1,11 +1,10 @@
1
- import { getPluginRoutes } from '../../plugins/server.js';
1
+ import { derivePluginName } from '../../plugins/derive.js';
2
+ import { getCMSConfig } from '../../core/config/index.js';
2
3
  export async function fixMasterAdminPrivileges() {
3
4
  // Lazy import heavy dependencies to avoid eager database connection initialization
4
5
  const { SectionFactory } = await import('../../core/factories/index.js');
5
6
  const { db } = await import('../../db/client.js');
6
7
  const { AdminPrivilegesTable } = await import('../../db/schema.js');
7
- // Let's also add privileges for all the sections to the master admin
8
- // Loop through the sections to get the section ids for the insertion into the admin_privileges table
9
8
  const sections = await SectionFactory.getSectionsSilently();
10
9
  const rows = sections.map((section) => ({
11
10
  adminId: '1',
@@ -13,33 +12,21 @@ export async function fixMasterAdminPrivileges() {
13
12
  operations: 'CUD',
14
13
  publisher: '1',
15
14
  }));
16
- const pluginRoutes = await getPluginRoutes();
17
- const pluginNames = new Set(pluginRoutes.map((route) => {
18
- return route.pluginName;
19
- }));
20
- pluginNames.forEach((pluginName) => {
15
+ // Plugin names are derived from their npm package name — no plugin code is
16
+ // evaluated, so the CLI never enters server-only-marked import chains.
17
+ const config = await getCMSConfig();
18
+ for (const registration of config.plugins ?? []) {
19
+ if (!registration.package)
20
+ continue;
21
21
  rows.push({
22
22
  adminId: '1',
23
- sectionName: pluginName,
23
+ sectionName: derivePluginName(registration.package),
24
24
  operations: 'CUD',
25
25
  publisher: '1',
26
26
  });
27
- });
28
- /**
29
- * Add the admins and logs sections to the privileges
30
- */
31
- rows.push({
32
- adminId: '1',
33
- sectionName: 'admins',
34
- operations: 'CUD',
35
- publisher: '1',
36
- });
37
- rows.push({
38
- adminId: '1',
39
- sectionName: 'log',
40
- operations: 'CUD',
41
- publisher: '1',
42
- });
27
+ }
28
+ rows.push({ adminId: '1', sectionName: 'admins', operations: 'CUD', publisher: '1' });
29
+ rows.push({ adminId: '1', sectionName: 'log', operations: 'CUD', publisher: '1' });
43
30
  await db
44
31
  .insert(AdminPrivilegesTable)
45
32
  .values(rows)
@@ -1 +1 @@
1
- {"version":3,"file":"update-sections.d.ts","sourceRoot":"","sources":["../../../src/cli/lib/update-sections.ts"],"names":[],"mappings":"AAmzEA,wBAAsB,cAAc,CAAC,SAAS,UAAQ,iBAoBrD"}
1
+ {"version":3,"file":"update-sections.d.ts","sourceRoot":"","sources":["../../../src/cli/lib/update-sections.ts"],"names":[],"mappings":"AAw3EA,wBAAsB,cAAc,CAAC,SAAS,UAAQ,iBAoBrD"}
@@ -192,7 +192,12 @@ function generateFieldSQL(input) {
192
192
  else if (!input.defaultValue) {
193
193
  fieldSQL += ' DEFAULT NULL';
194
194
  }
195
- if (input.defaultValue !== null && input.defaultValue !== undefined) {
195
+ if (input.defaultValue !== null && input.defaultValue !== undefined && input.required) {
196
+ // Only add sql default when the field is required,
197
+ // to allow null values in non-required fields
198
+ // with defaultValue prop set.
199
+ // Example: Admin cleared the defaultValue of
200
+ // non-required field and submits.
196
201
  fieldSQL += ` DEFAULT '${input.defaultValue}'`;
197
202
  }
198
203
  return fieldSQL;
@@ -383,6 +388,40 @@ function buildLocaleFieldConfig() {
383
388
  order: 0,
384
389
  });
385
390
  }
391
+ async function createEditorPhotosTable(localized) {
392
+ await db.execute(sql `
393
+ CREATE TABLE IF NOT EXISTS \`editor_photos\` (
394
+ \`photo\` VARCHAR(100) NOT NULL PRIMARY KEY,
395
+ \`section\` VARCHAR(100) NOT NULL,
396
+ \`item_id\` VARCHAR(50) NOT NULL,
397
+ \`field\` VARCHAR(100) NOT NULL,
398
+ \`meta\` LONGTEXT,
399
+ ${localized ? sql `\`locale\` VARCHAR(10) NOT NULL,` : sql ``}
400
+ \`linked\` BOOLEAN DEFAULT false,
401
+ \`created_at\` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
402
+ )
403
+ `);
404
+ }
405
+ async function ensureEditorPhotosLocaleColumn(defaultLocaleCode, knownColumns) {
406
+ let columns = knownColumns ?? (await MysqlTableChecker.getColumns('editor_photos').catch(() => []));
407
+ if (columns.includes('locale')) {
408
+ return false;
409
+ }
410
+ if (columns.length === 0) {
411
+ await createEditorPhotosTable(true);
412
+ columns = await MysqlTableChecker.getColumns('editor_photos').catch(() => []);
413
+ if (columns.includes('locale')) {
414
+ log.info(chalk.gray(` - Created 'editor_photos' table with 'locale' column.`));
415
+ return true;
416
+ }
417
+ throw new Error(`Failed to create 'editor_photos' table with a 'locale' column.`);
418
+ }
419
+ await db.execute(sql `ALTER TABLE \`editor_photos\` ADD COLUMN \`locale\` VARCHAR(10) DEFAULT NULL`);
420
+ await db.execute(sql `UPDATE \`editor_photos\` SET \`locale\` = ${defaultLocaleCode} WHERE \`locale\` IS NULL`);
421
+ await db.execute(sql `ALTER TABLE \`editor_photos\` MODIFY COLUMN \`locale\` VARCHAR(10) NOT NULL`);
422
+ log.info(chalk.gray(` - Added 'locale' column to 'editor_photos' and backfilled existing rows with '${defaultLocaleCode}'.`));
423
+ return true;
424
+ }
386
425
  async function ensureTableRegistryEntry(tableName, sectionName) {
387
426
  await db
388
427
  .insert(NextJsCmsTablesTable)
@@ -954,22 +993,22 @@ const main = async (s) => {
954
993
  * Let's see if the table `__nextjs_cms_tables` exists in the database.
955
994
  * If it doesn't, we'll create it using the same schema as `NextJsCmsTablesTable`.
956
995
  */
957
- await db.execute(sql `
958
- CREATE TABLE IF NOT EXISTS __nextjs_cms_tables (
959
- name VARCHAR(100) NOT NULL PRIMARY KEY,
960
- section VARCHAR(200),
961
- created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
962
- )
996
+ await db.execute(sql `
997
+ CREATE TABLE IF NOT EXISTS __nextjs_cms_tables (
998
+ name VARCHAR(100) NOT NULL PRIMARY KEY,
999
+ section VARCHAR(200),
1000
+ created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
1001
+ )
963
1002
  `);
964
1003
  /**
965
1004
  * Persistent key/value store for CMS-level state that must survive config removal.
966
1005
  */
967
- await db.execute(sql `
968
- CREATE TABLE IF NOT EXISTS __nextjs_cms_config (
969
- \`key\` VARCHAR(100) NOT NULL PRIMARY KEY,
970
- \`value\` LONGTEXT,
971
- updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
972
- )
1006
+ await db.execute(sql `
1007
+ CREATE TABLE IF NOT EXISTS __nextjs_cms_config (
1008
+ \`key\` VARCHAR(100) NOT NULL PRIMARY KEY,
1009
+ \`value\` LONGTEXT,
1010
+ updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
1011
+ )
973
1012
  `);
974
1013
  await db.execute(sql `ALTER TABLE \`__nextjs_cms_config\` MODIFY COLUMN \`value\` LONGTEXT`);
975
1014
  /**
@@ -987,46 +1026,54 @@ const main = async (s) => {
987
1026
  */
988
1027
  const RESERVED_TABLE_SUFFIX = '_locales';
989
1028
  const RESERVED_COLUMN_NAME = 'locale';
990
- const reservedNameErrors = [];
1029
+ const configurationErrors = [];
1030
+ const builtSections = sections.map((_s) => {
1031
+ const section = _s.build();
1032
+ section.buildFields();
1033
+ return section;
1034
+ });
1035
+ const managedSectionTables = new Map(builtSections.map((section) => [section.db.table, section.name]));
991
1036
  /**
992
1037
  * Insert the sections into the database
993
1038
  */
994
- for (const _s of sections) {
995
- const s = _s.build();
996
- s.buildFields();
1039
+ for (const s of builtSections) {
997
1040
  localesTableAssetMetadata.set(s.localesTableName, {
998
1041
  sectionName: s.name,
999
1042
  fields: getLocalizedAssetFields(s.fieldConfigs),
1000
1043
  });
1001
1044
  if (s.db.table.endsWith(RESERVED_TABLE_SUFFIX)) {
1002
- reservedNameErrors.push(`Section '${s.name}': table name '${s.db.table}' ends with reserved suffix '${RESERVED_TABLE_SUFFIX}'.`);
1045
+ configurationErrors.push(`Section '${s.name}': table name '${s.db.table}' ends with reserved suffix '${RESERVED_TABLE_SUFFIX}'.`);
1003
1046
  }
1004
1047
  for (const field of s.fields) {
1005
1048
  if (field.name === RESERVED_COLUMN_NAME) {
1006
- reservedNameErrors.push(`Section '${s.name}', field '${field.name}': field name '${RESERVED_COLUMN_NAME}' is reserved.`);
1049
+ configurationErrors.push(`Section '${s.name}', field '${field.name}': field name '${RESERVED_COLUMN_NAME}' is reserved.`);
1007
1050
  }
1008
1051
  if (field.destinationDb) {
1009
1052
  if (field.destinationDb.table.endsWith(RESERVED_TABLE_SUFFIX)) {
1010
- reservedNameErrors.push(`Section '${s.name}', field '${field.name}': destinationDb.table '${field.destinationDb.table}' ends with reserved suffix '${RESERVED_TABLE_SUFFIX}'.`);
1053
+ configurationErrors.push(`Section '${s.name}', field '${field.name}': destinationDb.table '${field.destinationDb.table}' ends with reserved suffix '${RESERVED_TABLE_SUFFIX}'.`);
1011
1054
  }
1012
1055
  if (field.destinationDb.itemIdentifier === RESERVED_COLUMN_NAME ||
1013
1056
  field.destinationDb.selectIdentifier === RESERVED_COLUMN_NAME) {
1014
- reservedNameErrors.push(`Section '${s.name}', field '${field.name}': destinationDb identifier column name '${RESERVED_COLUMN_NAME}' is reserved.`);
1057
+ configurationErrors.push(`Section '${s.name}', field '${field.name}': destinationDb identifier column name '${RESERVED_COLUMN_NAME}' is reserved.`);
1015
1058
  }
1016
1059
  }
1017
1060
  if (isExternalSelectDbField(field)) {
1061
+ const ownerSectionName = managedSectionTables.get(field.db.table);
1062
+ if (ownerSectionName) {
1063
+ configurationErrors.push(`Section '${s.name}', field '${field.name}': db.table '${field.db.table}' belongs to managed section '${ownerSectionName}'. Use the 'section' prop instead of 'db' so update-sections does not treat the section table as an external lookup table.`);
1064
+ }
1018
1065
  if (field.db.table.endsWith(RESERVED_TABLE_SUFFIX)) {
1019
- reservedNameErrors.push(`Section '${s.name}', field '${field.name}': db.table '${field.db.table}' ends with reserved suffix '${RESERVED_TABLE_SUFFIX}'.`);
1066
+ configurationErrors.push(`Section '${s.name}', field '${field.name}': db.table '${field.db.table}' ends with reserved suffix '${RESERVED_TABLE_SUFFIX}'.`);
1020
1067
  }
1021
1068
  const reservedColumns = [field.db.identifier, field.db.label, field.db.orderBy].filter((column) => column === RESERVED_COLUMN_NAME);
1022
1069
  if (reservedColumns.length > 0) {
1023
- reservedNameErrors.push(`Section '${s.name}', field '${field.name}': db column name '${RESERVED_COLUMN_NAME}' is reserved.`);
1070
+ configurationErrors.push(`Section '${s.name}', field '${field.name}': db column name '${RESERVED_COLUMN_NAME}' is reserved.`);
1024
1071
  }
1025
1072
  }
1026
1073
  }
1027
1074
  const galleryForValidation = await s.getGallery();
1028
1075
  if (galleryForValidation?.db.tableName && galleryForValidation.db.tableName.endsWith(RESERVED_TABLE_SUFFIX)) {
1029
- reservedNameErrors.push(`Section '${s.name}': gallery table '${galleryForValidation.db.tableName}' ends with reserved suffix '${RESERVED_TABLE_SUFFIX}'.`);
1076
+ configurationErrors.push(`Section '${s.name}': gallery table '${galleryForValidation.db.tableName}' ends with reserved suffix '${RESERVED_TABLE_SUFFIX}'.`);
1030
1077
  }
1031
1078
  /**
1032
1079
  * Generate the Drizzle schema for the table
@@ -1335,13 +1382,13 @@ const main = async (s) => {
1335
1382
  }
1336
1383
  }
1337
1384
  /**
1338
- * Reject the run before any DB write if any section used a reserved name.
1385
+ * Reject the run before schema writes if any section configuration is unsafe.
1339
1386
  */
1340
- if (reservedNameErrors.length > 0) {
1341
- s.stop(`update-sections aborted: ${reservedNameErrors.length} reserved-name conflict(s) detected.\n` +
1342
- reservedNameErrors.map((e) => ` - ${e}`).join('\n') +
1343
- `\n\nThe suffix '${RESERVED_TABLE_SUFFIX}' and the column name '${RESERVED_COLUMN_NAME}' are reserved for the localization system. Please rename and re-run.`);
1344
- throw new Error('update-sections: reserved name conflicts detected');
1387
+ if (configurationErrors.length > 0) {
1388
+ s.stop(`update-sections aborted: ${configurationErrors.length} configuration conflict(s) detected.\n` +
1389
+ configurationErrors.map((e) => ` - ${e}`).join('\n') +
1390
+ `\n\nThe suffix '${RESERVED_TABLE_SUFFIX}' and the column name '${RESERVED_COLUMN_NAME}' are reserved for the localization system. Section-managed tables must be referenced with the 'section' prop. Please update cms.config.ts and re-run.`);
1391
+ throw new Error('update-sections: configuration conflicts detected');
1345
1392
  }
1346
1393
  /**
1347
1394
  * Write schema file if schema generation is enabled
@@ -1423,6 +1470,7 @@ const main = async (s) => {
1423
1470
  if (localizationCurrentlyEnabled && cmsConfig.localization) {
1424
1471
  const configLocalizationState = buildStoredEnabledLocalizationState(cmsConfig.localization);
1425
1472
  enableTargetState = configLocalizationState;
1473
+ const storedPendingDisableLocalizationState = storedEnabledLocalizationState?.transition?.type === 'disable' ? storedEnabledLocalizationState : null;
1426
1474
  if (storedEnabledLocalizationState &&
1427
1475
  storedEnabledLocalizationState.defaultLocale !== configLocalizationState.defaultLocale) {
1428
1476
  s.stop(`Aborting. Changing localization defaultLocale is not supported (stored='${storedEnabledLocalizationState.defaultLocale}', config='${configLocalizationState.defaultLocale}'). Revert cms.config.ts and re-run update-sections.`);
@@ -1451,18 +1499,23 @@ const main = async (s) => {
1451
1499
  }
1452
1500
  }
1453
1501
  const needsEditorPhotosMigration = editorPhotosExists && !editorPhotosHasLocale;
1454
- const shouldRunEnableTransition = storedPendingEnableLocalizationState || !storedEnabledLocalizationState;
1502
+ const shouldRunEnableTransition = storedPendingEnableLocalizationState ||
1503
+ !storedEnabledLocalizationState ||
1504
+ storedPendingDisableLocalizationState;
1455
1505
  if (shouldRunEnableTransition) {
1456
1506
  const affectedList = [...(needsEditorPhotosMigration ? ['editor_photos'] : []), ...affectedLocalizedTables];
1457
1507
  const affectedListText = affectedList.length > 0
1458
1508
  ? affectedList.map((n) => ` - ${n}`).join('\n')
1459
1509
  : ` - No existing tables need a locale backfill; update-sections will verify localized tables after sync.`;
1460
1510
  const isEnableRetry = storedPendingEnableLocalizationState?.transition.status === 'pending';
1511
+ const isDisableRecovery = storedPendingDisableLocalizationState?.transition?.status === 'pending';
1461
1512
  s.stop();
1462
1513
  const confirm = await select({
1463
- message: (isEnableRetry
1464
- ? `A previous localization enable attempt did not complete. update-sections will retry setup now.\n\n`
1465
- : `It looks like you enabled localization. Your existing data in these tables will be marked as defaultLocale '${configLocalizationState.defaultLocale}':\n`) +
1514
+ message: (isDisableRecovery
1515
+ ? `A previous localization disable attempt did not complete, but cms.config.ts has localization enabled again. update-sections will repair localization artifacts and clear the pending disable state after verification.\n\n`
1516
+ : isEnableRetry
1517
+ ? `A previous localization enable attempt did not complete. update-sections will retry setup now.\n\n`
1518
+ : `It looks like you enabled localization. Your existing data in these tables will be marked as defaultLocale '${configLocalizationState.defaultLocale}':\n`) +
1466
1519
  affectedListText +
1467
1520
  `\n\n${chalk.redBright('WARNING:')} Existing data in these tables MUST already be in '${configLocalizationState.defaultLocale}'. ` +
1468
1521
  `Changing defaultLocale after this point is not supported. If your data is not in '${configLocalizationState.defaultLocale}', ` +
@@ -1483,22 +1536,12 @@ const main = async (s) => {
1483
1536
  type: 'enable',
1484
1537
  status: 'pending',
1485
1538
  startedAt: storedPendingEnableLocalizationState?.transition.startedAt ?? now,
1486
- ...(isEnableRetry ? { lastAttemptAt: now } : {}),
1539
+ ...(isEnableRetry || isDisableRecovery ? { lastAttemptAt: now } : {}),
1487
1540
  });
1488
1541
  await writeStoredLocalizationState(enablePendingState);
1489
- if (needsEditorPhotosMigration) {
1490
- try {
1491
- await db.execute(sql `ALTER TABLE \`editor_photos\` ADD COLUMN \`locale\` VARCHAR(10) DEFAULT NULL`);
1492
- await db.execute(sql `UPDATE \`editor_photos\` SET \`locale\` = ${configLocalizationState.defaultLocale} WHERE \`locale\` IS NULL`);
1493
- await db.execute(sql `ALTER TABLE \`editor_photos\` MODIFY COLUMN \`locale\` VARCHAR(10) NOT NULL`);
1494
- log.info(chalk.gray(` - Added 'locale' column to 'editor_photos' and backfilled existing rows with '${configLocalizationState.defaultLocale}'.`));
1495
- }
1496
- catch (error) {
1497
- console.error(chalk.red(` - Error migrating 'editor_photos' for localization enable:`, error));
1498
- }
1499
- }
1500
1542
  s.start();
1501
1543
  }
1544
+ await ensureEditorPhotosLocaleColumn(configLocalizationState.defaultLocale, editorPhotosColumns);
1502
1545
  }
1503
1546
  else if (!localizationCurrentlyEnabled && storedEnabledLocalizationState) {
1504
1547
  /**
@@ -1534,6 +1577,7 @@ const main = async (s) => {
1534
1577
  ` 3. Drop '_locales' tables entirely\n\n` +
1535
1578
  `Affected tables:\n` +
1536
1579
  affected.map((t) => ` - ${t.name} (${t.type})`).join('\n') +
1580
+ `\n\n${chalk.redBright('WARNING: This action is irreversible and will permanently delete data and affected tables. It is recommended to make a backup of your data before proceeding.')}` +
1537
1581
  `\n\nProceed?`,
1538
1582
  options: [
1539
1583
  { value: 'yes', label: `Yes, that's correct` },