nextjs-cms 0.6.8 → 0.7.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.
Files changed (105) hide show
  1. package/dist/cli/commands/db-config.d.ts +2 -0
  2. package/dist/cli/commands/db-config.d.ts.map +1 -0
  3. package/dist/cli/commands/db-config.js +22 -0
  4. package/dist/cli/commands/fix-master-admin.d.ts +2 -0
  5. package/dist/cli/commands/fix-master-admin.d.ts.map +1 -0
  6. package/dist/cli/commands/fix-master-admin.js +22 -0
  7. package/dist/cli/commands/set-master-admin.d.ts +2 -0
  8. package/dist/cli/commands/set-master-admin.d.ts.map +1 -0
  9. package/dist/cli/commands/set-master-admin.js +25 -0
  10. package/dist/cli/commands/setup.d.ts +2 -0
  11. package/dist/cli/commands/setup.d.ts.map +1 -0
  12. package/dist/cli/commands/setup.js +34 -0
  13. package/dist/cli/commands/update-sections.d.ts +2 -0
  14. package/dist/cli/commands/update-sections.d.ts.map +1 -0
  15. package/dist/cli/commands/update-sections.js +27 -0
  16. package/dist/cli/index.d.ts +3 -0
  17. package/dist/cli/index.d.ts.map +1 -0
  18. package/dist/cli/index.js +15 -0
  19. package/dist/cli/lib/db-config.d.ts +4 -0
  20. package/dist/cli/lib/db-config.d.ts.map +1 -0
  21. package/dist/cli/lib/db-config.js +238 -0
  22. package/dist/cli/lib/db-migrate.d.ts +2 -0
  23. package/dist/cli/lib/db-migrate.d.ts.map +1 -0
  24. package/dist/cli/lib/db-migrate.js +83 -0
  25. package/dist/cli/lib/fix-master-admin.d.ts +2 -0
  26. package/dist/cli/lib/fix-master-admin.d.ts.map +1 -0
  27. package/dist/cli/lib/fix-master-admin.js +53 -0
  28. package/dist/cli/lib/set-master-admin.d.ts +2 -0
  29. package/dist/cli/lib/set-master-admin.d.ts.map +1 -0
  30. package/dist/cli/lib/set-master-admin.js +88 -0
  31. package/dist/cli/lib/update-sections.d.ts +2 -0
  32. package/dist/cli/lib/update-sections.d.ts.map +1 -0
  33. package/dist/cli/lib/update-sections.js +915 -0
  34. package/dist/cli/program/program.d.ts +4 -0
  35. package/dist/cli/program/program.d.ts.map +1 -0
  36. package/dist/cli/program/program.js +95 -0
  37. package/dist/cli/utils/add-table-keys.d.ts +32 -0
  38. package/dist/cli/utils/add-table-keys.d.ts.map +1 -0
  39. package/dist/cli/utils/add-table-keys.js +171 -0
  40. package/dist/cli/utils/check-version.d.ts +3 -0
  41. package/dist/cli/utils/check-version.d.ts.map +1 -0
  42. package/dist/cli/utils/check-version.js +125 -0
  43. package/dist/cli/utils/display-intro.d.ts +6 -0
  44. package/dist/cli/utils/display-intro.d.ts.map +1 -0
  45. package/dist/cli/utils/display-intro.js +9 -0
  46. package/dist/cli/utils/exec-utils.d.ts +19 -0
  47. package/dist/cli/utils/exec-utils.d.ts.map +1 -0
  48. package/dist/cli/utils/exec-utils.js +95 -0
  49. package/dist/cli/utils/get-package-manager.d.ts +4 -0
  50. package/dist/cli/utils/get-package-manager.d.ts.map +1 -0
  51. package/dist/cli/utils/get-package-manager.js +22 -0
  52. package/dist/cli/utils/reload-env.d.ts +16 -0
  53. package/dist/cli/utils/reload-env.d.ts.map +1 -0
  54. package/dist/cli/utils/reload-env.js +42 -0
  55. package/dist/cli/utils/render-title.d.ts +2 -0
  56. package/dist/cli/utils/render-title.d.ts.map +1 -0
  57. package/dist/cli/utils/render-title.js +12 -0
  58. package/dist/cli/utils/schema-generator.d.ts +10 -0
  59. package/dist/cli/utils/schema-generator.d.ts.map +1 -0
  60. package/dist/cli/utils/schema-generator.js +171 -0
  61. package/dist/core/config/config-loader.d.ts +4 -10
  62. package/dist/core/config/config-loader.d.ts.map +1 -1
  63. package/dist/core/config/config-loader.js +14 -14
  64. package/dist/core/factories/section-factory-with-esbuild.d.ts +1 -1
  65. package/dist/core/factories/section-factory-with-esbuild.js +1 -1
  66. package/dist/core/factories/section-factory-with-jiti.d.ts +1 -1
  67. package/dist/core/factories/section-factory-with-jiti.js +1 -1
  68. package/dist/core/sections/category.d.ts +32 -32
  69. package/dist/core/sections/hasItems.d.ts +32 -32
  70. package/dist/core/sections/section.d.ts +16 -16
  71. package/dist/core/sections/simple.d.ts +8 -8
  72. package/dist/db/config.js +1 -1
  73. package/dist/translations/base/en.d.ts +433 -0
  74. package/dist/translations/base/en.d.ts.map +1 -0
  75. package/dist/translations/base/en.js +444 -0
  76. package/dist/translations/client.d.ts +5178 -1
  77. package/dist/translations/client.d.ts.map +1 -1
  78. package/dist/translations/client.js +29 -4
  79. package/dist/translations/dict-store.d.ts +5 -1
  80. package/dist/translations/dict-store.d.ts.map +1 -1
  81. package/dist/translations/dict-store.js +31 -4
  82. package/dist/translations/index.d.ts +1 -1
  83. package/dist/translations/index.js +1 -1
  84. package/dist/translations/server.d.ts +5171 -1
  85. package/dist/translations/server.d.ts.map +1 -1
  86. package/dist/translations/server.js +26 -4
  87. package/package.json +18 -10
  88. package/dist/core/helpers/i18n.d.ts +0 -2
  89. package/dist/core/helpers/i18n.d.ts.map +0 -1
  90. package/dist/core/helpers/i18n.js +0 -3
  91. package/dist/core/localization.d.ts +0 -40
  92. package/dist/core/localization.d.ts.map +0 -1
  93. package/dist/core/localization.js +0 -48
  94. package/dist/logging/audit.d.ts +0 -20
  95. package/dist/logging/audit.d.ts.map +0 -1
  96. package/dist/logging/audit.js +0 -48
  97. package/dist/translations/localized-string.d.ts +0 -17
  98. package/dist/translations/localized-string.d.ts.map +0 -1
  99. package/dist/translations/localized-string.js +0 -32
  100. package/dist/translations/use-project-translation.d.ts +0 -19
  101. package/dist/translations/use-project-translation.d.ts.map +0 -1
  102. package/dist/translations/use-project-translation.js +0 -25
  103. package/dist/validators/types.d.ts +0 -7
  104. package/dist/validators/types.d.ts.map +0 -1
  105. package/dist/validators/types.js +0 -0
@@ -0,0 +1,2 @@
1
+ export declare function runDbConfig(dev: boolean): Promise<void>;
2
+ //# sourceMappingURL=db-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-config.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/db-config.ts"],"names":[],"mappings":"AAGA,wBAAsB,WAAW,CAAC,GAAG,EAAE,OAAO,iBAiB7C"}
@@ -0,0 +1,22 @@
1
+ import chalk from 'chalk';
2
+ import * as p from '@clack/prompts';
3
+ export async function runDbConfig(dev) {
4
+ let exitCode = 0;
5
+ try {
6
+ p.log.info(chalk.cyan('Configuring database'));
7
+ // Lazy import to avoid eager database connection
8
+ const { dbConfigSetup } = await import('../lib/db-config.js');
9
+ await dbConfigSetup({ dev });
10
+ p.outro(chalk.inverse(' ✓ Database configuration completed '));
11
+ }
12
+ catch (error) {
13
+ console.error(chalk.red('✗ Error during database configuration:'), error);
14
+ exitCode = 1;
15
+ }
16
+ finally {
17
+ // Lazy import for cleanup
18
+ const { dbConnectionClose } = await import('../../db/client.js');
19
+ await dbConnectionClose();
20
+ }
21
+ process.exit(exitCode);
22
+ }
@@ -0,0 +1,2 @@
1
+ export declare function runFixMasterAdmin(): Promise<void>;
2
+ //# sourceMappingURL=fix-master-admin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fix-master-admin.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/fix-master-admin.ts"],"names":[],"mappings":"AAGA,wBAAsB,iBAAiB,kBAiBtC"}
@@ -0,0 +1,22 @@
1
+ import chalk from 'chalk';
2
+ import * as p from '@clack/prompts';
3
+ export async function runFixMasterAdmin() {
4
+ let exitCode = 0;
5
+ try {
6
+ p.log.info(chalk.cyan('Looking up sections'));
7
+ // Lazy import to avoid eager database connection
8
+ const { fixMasterAdminPrivileges } = await import('../lib/fix-master-admin.js');
9
+ await fixMasterAdminPrivileges();
10
+ p.outro(chalk.inverse(' ✓ Master admin privileges fixed '));
11
+ }
12
+ catch (error) {
13
+ console.error(chalk.red('Error fixing master admin privileges:'), error);
14
+ exitCode = 1;
15
+ }
16
+ finally {
17
+ // Lazy import for cleanup
18
+ const { dbConnectionClose } = await import('../../db/client.js');
19
+ await dbConnectionClose();
20
+ }
21
+ process.exit(exitCode);
22
+ }
@@ -0,0 +1,2 @@
1
+ export declare function runSetMasterAdmin(): Promise<void>;
2
+ //# sourceMappingURL=set-master-admin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"set-master-admin.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/set-master-admin.ts"],"names":[],"mappings":"AAGA,wBAAsB,iBAAiB,kBAoBtC"}
@@ -0,0 +1,25 @@
1
+ import chalk from 'chalk';
2
+ import * as p from '@clack/prompts';
3
+ export async function runSetMasterAdmin() {
4
+ p.log.info(chalk.cyan('Setting up master admin'));
5
+ let exitCode = 0;
6
+ try {
7
+ const { setMasterAdmin } = await import('../lib/set-master-admin.js');
8
+ await setMasterAdmin();
9
+ p.outro(chalk.inverse(' ✓ Master admin setup completed successfully '));
10
+ }
11
+ catch (error) {
12
+ p.log.error(chalk.red('✗ Error resetting master admin:'));
13
+ console.error(error);
14
+ // Lazy import for cleanup
15
+ const { dbConnectionClose } = await import('../../db/client.js');
16
+ await dbConnectionClose();
17
+ exitCode = 1;
18
+ }
19
+ finally {
20
+ // Lazy import for cleanup
21
+ const { dbConnectionClose } = await import('../../db/client.js');
22
+ await dbConnectionClose();
23
+ }
24
+ process.exit(exitCode);
25
+ }
@@ -0,0 +1,2 @@
1
+ export declare function runSetup(dev: boolean, skipDbConfig: boolean): Promise<void>;
2
+ //# sourceMappingURL=setup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/setup.ts"],"names":[],"mappings":"AAGA,wBAAsB,QAAQ,CAAC,GAAG,EAAE,OAAO,EAAE,YAAY,EAAE,OAAO,iBAiCjE"}
@@ -0,0 +1,34 @@
1
+ import * as p from '@clack/prompts';
2
+ import chalk from 'chalk';
3
+ export async function runSetup(dev, skipDbConfig) {
4
+ let exitCode = 0;
5
+ try {
6
+ if (!skipDbConfig) {
7
+ p.log.info(chalk.cyan('Configuring database'));
8
+ const { dbConfigSetup } = await import('../lib/db-config.js');
9
+ await dbConfigSetup({ dev });
10
+ }
11
+ p.log.info(chalk.cyan('Generating database tables'));
12
+ const { generateDatabaseTables } = await import('../lib/db-migrate.js');
13
+ await generateDatabaseTables();
14
+ p.log.info(chalk.cyan('Setting up master admin'));
15
+ const { setMasterAdmin } = await import('../lib/set-master-admin.js');
16
+ await setMasterAdmin();
17
+ p.outro(chalk.inverse(' ✓ nextjs-cms setup completed successfully '));
18
+ }
19
+ catch (error) {
20
+ console.log('');
21
+ console.error(chalk.red('✗ Error during setup:'), error);
22
+ p.outro(chalk.red('✗ Setup failed'));
23
+ // Lazy import for cleanup
24
+ const { dbConnectionClose } = await import('../../db/client.js');
25
+ await dbConnectionClose();
26
+ exitCode = 1;
27
+ }
28
+ finally {
29
+ // Lazy import for cleanup
30
+ const { dbConnectionClose } = await import('../../db/client.js');
31
+ await dbConnectionClose();
32
+ }
33
+ process.exit(exitCode);
34
+ }
@@ -0,0 +1,2 @@
1
+ export declare function runUpdateSections(dev: boolean): Promise<void>;
2
+ //# sourceMappingURL=update-sections.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-sections.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/update-sections.ts"],"names":[],"mappings":"AAGA,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,OAAO,iBAsBnD"}
@@ -0,0 +1,27 @@
1
+ import chalk from 'chalk';
2
+ import * as p from '@clack/prompts';
3
+ export async function runUpdateSections(dev) {
4
+ let exitCode = 0;
5
+ try {
6
+ p.log.info(chalk.cyan('Updating sections'));
7
+ const { updateSections } = await import('../lib/update-sections.js');
8
+ await updateSections(dev);
9
+ p.log.info(chalk.cyan('Modifying master admin privileges'));
10
+ // Lazy import to avoid eager database connection
11
+ const { fixMasterAdminPrivileges } = await import('../lib/fix-master-admin.js');
12
+ await fixMasterAdminPrivileges();
13
+ p.log.message(chalk.green(' - ✓ Master admin privileges fixed.'));
14
+ p.outro(chalk.inverse(' ✓ Sections updated '));
15
+ }
16
+ catch (error) {
17
+ p.log.error(chalk.red('✗ Error updating sections:'));
18
+ console.error(error);
19
+ exitCode = 1;
20
+ }
21
+ finally {
22
+ // Lazy import for cleanup
23
+ const { dbConnectionClose } = await import('../../db/client.js');
24
+ await dbConnectionClose();
25
+ }
26
+ process.exit(exitCode);
27
+ }
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":""}
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env node
2
+ import dotenv from 'dotenv';
3
+ import program from './program/program.js';
4
+ program.parse(process.argv);
5
+ // Load environment file based on parsed dev flag
6
+ if (Boolean(program.opts().dev) === true) {
7
+ dotenv.config({ path: '.env.development', quiet: true });
8
+ // @ts-expect-error -- CLI intentionally sets NODE_ENV before app code runs
9
+ process.env.NODE_ENV = 'development';
10
+ }
11
+ else {
12
+ dotenv.config();
13
+ // @ts-expect-error -- CLI intentionally sets NODE_ENV before app code runs
14
+ process.env.NODE_ENV = 'production';
15
+ }
@@ -0,0 +1,4 @@
1
+ export declare function dbConfigSetup(options: {
2
+ dev: boolean;
3
+ }): Promise<void>;
4
+ //# sourceMappingURL=db-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-config.d.ts","sourceRoot":"","sources":["../../../src/cli/lib/db-config.ts"],"names":[],"mappings":"AAmCA,wBAAsB,aAAa,CAAC,OAAO,EAAE;IAAE,GAAG,EAAE,OAAO,CAAA;CAAE,iBAyO5D"}
@@ -0,0 +1,238 @@
1
+ import { createConnection } from 'mysql2/promise';
2
+ import * as p from '@clack/prompts';
3
+ import fs from 'fs';
4
+ import path from 'path';
5
+ import { cwd } from 'process';
6
+ import chalk from 'chalk';
7
+ import ora from 'ora';
8
+ /**
9
+ * Removes specific environment variables from the .env file content
10
+ * Removes both the generated comment block and the individual variable lines
11
+ */
12
+ function removeEnvVariables(content, variables) {
13
+ let result = content;
14
+ // Remove the generated block comment if it exists (including the markers)
15
+ const blockRegex = /\n*####\s*\n#\s*generated by the init script\s*\n####\s*\n?/g;
16
+ result = result.replace(blockRegex, '\n');
17
+ // Remove individual variable lines (entire lines including newline)
18
+ variables.forEach((variable) => {
19
+ result = result.replace(new RegExp(`^${variable}=.*$\\n?`, 'gm'), '');
20
+ });
21
+ return result;
22
+ }
23
+ /**
24
+ * Validates if a string is a valid port number
25
+ */
26
+ function isValidPort(value) {
27
+ const port = parseInt(value, 10);
28
+ return !isNaN(port) && port > 0 && port <= 65535;
29
+ }
30
+ export async function dbConfigSetup(options) {
31
+ const { dev = false } = options;
32
+ const envFileName = dev ? '.env.development' : '.env.production';
33
+ /**
34
+ * Step 1: Ask for connection credentials
35
+ */
36
+ p.log.info('Database Connection');
37
+ p.log.message('Please provide your MySQL/MariaDB server credentials');
38
+ const { dbHost, dbPort, dbUser, dbPassword } = await p.group({
39
+ dbHost: () => p.text({
40
+ message: 'Database host:',
41
+ placeholder: 'localhost',
42
+ defaultValue: 'localhost',
43
+ validate(value) {
44
+ if (value && value.length < 2)
45
+ return `Database host must be at least 2 characters`;
46
+ },
47
+ }),
48
+ dbPort: () => p.text({
49
+ message: 'Database port:',
50
+ placeholder: '3306',
51
+ defaultValue: '3306',
52
+ validate(value) {
53
+ if (value && !isValidPort(value)) {
54
+ return `Database port must be a valid number between 1 and 65535`;
55
+ }
56
+ },
57
+ }),
58
+ dbUser: () => p.text({
59
+ message: 'Database username:',
60
+ validate(value) {
61
+ if (value.length < 1)
62
+ return `Database username is required`;
63
+ },
64
+ }),
65
+ dbPassword: () => p.text({
66
+ message: 'Database password:',
67
+ validate(value) {
68
+ if (value.length < 1)
69
+ return `Database password is required`;
70
+ },
71
+ }),
72
+ }, {
73
+ onCancel: () => {
74
+ p.cancel(`Aborted\n`);
75
+ process.exit(1);
76
+ },
77
+ });
78
+ /**
79
+ * Step 2: Test the database connection
80
+ */
81
+ const s = ora('Testing database connection...').start();
82
+ let migrationClient;
83
+ try {
84
+ /**
85
+ * It's recommended to not use a pool connection for migrations, that's why we're creating a new connection here.
86
+ */
87
+ migrationClient = await createConnection({
88
+ host: String(dbHost),
89
+ user: String(dbUser),
90
+ password: String(dbPassword),
91
+ database: '',
92
+ port: parseInt(String(dbPort), 10),
93
+ });
94
+ s.stop();
95
+ p.log.success(chalk.green('✓ Connected successfully!'));
96
+ /**
97
+ * Step 3: Now that connection is successful, ask for database name
98
+ */
99
+ const dbName = await p.text({
100
+ message: 'Database name:',
101
+ placeholder: 'If the database does not exist, it will be created',
102
+ validate(value) {
103
+ if (value.length < 2)
104
+ return `Database name must be at least 2 characters`;
105
+ // Validate database name format (alphanumeric, underscore, hyphen)
106
+ if (!/^[a-zA-Z0-9_-]+$/.test(value)) {
107
+ return `Database name can only contain letters, numbers, underscores, and hyphens`;
108
+ }
109
+ },
110
+ });
111
+ if (p.isCancel(dbName)) {
112
+ p.cancel(`Aborted\n`);
113
+ process.exit(1);
114
+ }
115
+ /**
116
+ * Step 4: Create the database
117
+ */
118
+ s.start('Creating database...');
119
+ /**
120
+ * Let's create the database using parameterized query to prevent SQL injection
121
+ */
122
+ await migrationClient.query('CREATE DATABASE IF NOT EXISTS ??', [dbName]);
123
+ s.stop();
124
+ p.log.success(chalk.green('✓ Database created successfully!'));
125
+ /**
126
+ * Let's save the database credentials in the .env file
127
+ */
128
+ const envPath = path.resolve(cwd(), envFileName);
129
+ /**
130
+ * If the .env file does not exist, we'll create it
131
+ */
132
+ if (!fs.existsSync(envPath)) {
133
+ fs.writeFileSync(envPath, '');
134
+ }
135
+ /**
136
+ * Read current .env content and remove existing database credentials
137
+ */
138
+ let currentEnv = fs.readFileSync(envPath, 'utf8');
139
+ currentEnv = removeEnvVariables(currentEnv, ['DB_HOST', 'DB_PORT', 'DB_NAME', 'DB_USER', 'DB_PASSWORD']);
140
+ /**
141
+ * Prepare new environment variables block
142
+ */
143
+ const newEnvBlock = `
144
+
145
+ ####
146
+ # generated by the init script
147
+ ####
148
+ DB_HOST=${dbHost}
149
+ DB_PORT=${dbPort}
150
+ DB_NAME=${dbName}
151
+ DB_USER=${dbUser}
152
+ DB_PASSWORD='${dbPassword}'
153
+ `;
154
+ /**
155
+ * Append the new credentials to the .env file
156
+ */
157
+ let finalEnv = currentEnv + newEnvBlock;
158
+ // Trim multiple consecutive empty lines to a maximum of two empty lines
159
+ finalEnv = finalEnv.replace(/(\n\s*\n){3,}/g, '\n\n');
160
+ // Trim leading whitespace
161
+ finalEnv = finalEnv.trim() + '\n';
162
+ fs.writeFileSync(envPath, finalEnv);
163
+ // Reload environment variables after writing to .env file
164
+ const dbVariables = {
165
+ DB_HOST: String(dbHost),
166
+ DB_PORT: String(dbPort),
167
+ DB_NAME: String(dbName),
168
+ DB_USER: String(dbUser),
169
+ DB_PASSWORD: String(dbPassword),
170
+ };
171
+ const { reloadAndUpdateEnvironmentVariables } = await import('../utils/reload-env.js');
172
+ reloadAndUpdateEnvironmentVariables(dbVariables, envFileName);
173
+ /**
174
+ * Get environment variables from env and check if they are correct
175
+ */
176
+ const envDbHost = process.env.DB_HOST;
177
+ const envDbPort = process.env.DB_PORT;
178
+ const envDbName = process.env.DB_NAME;
179
+ const envDbUser = process.env.DB_USER;
180
+ const envDbPassword = process.env.DB_PASSWORD;
181
+ // Validate that the values match what we just set
182
+ const mismatches = [];
183
+ if (envDbHost !== String(dbHost))
184
+ mismatches.push('DB_HOST');
185
+ if (envDbPort !== String(dbPort))
186
+ mismatches.push('DB_PORT');
187
+ if (envDbName !== String(dbName))
188
+ mismatches.push('DB_NAME');
189
+ if (envDbUser !== String(dbUser))
190
+ mismatches.push('DB_USER');
191
+ if (envDbPassword !== String(dbPassword))
192
+ mismatches.push('DB_PASSWORD');
193
+ if (mismatches.length > 0) {
194
+ p.log.error(`✗ Couldn't save database credentials to ${envFileName} file}`);
195
+ console.error(`Please save these values manually to the ${envFileName} file:`);
196
+ console.error(`DB_HOST: ${dbHost}`);
197
+ console.error(`DB_PORT: ${dbPort}`);
198
+ console.error(`DB_NAME: ${dbName}`);
199
+ console.error(`DB_USER: ${dbUser}`);
200
+ console.error(`DB_PASSWORD: ${dbPassword}`);
201
+ console.error();
202
+ console.error(chalk.cyan(`and then run: ${chalk.green(`pnpm nextjs-cms ${dev ? '-d' : ''} setup --continue`)} to continue your setup`));
203
+ process.exit(1);
204
+ }
205
+ p.log.message(chalk.cyan(` - Saved database credentials to ${envFileName} file`));
206
+ }
207
+ catch (error) {
208
+ s.stop();
209
+ p.log.error(chalk.red('✗ Database setup failed!'));
210
+ const errorMessage = error instanceof Error ? error.message : String(error);
211
+ const errorCode = error && typeof error === 'object' && 'code' in error ? error.code : null;
212
+ // Provide specific error messages based on error type
213
+ if (errorCode === 'ER_ACCESS_DENIED_ERROR' || errorCode === 'ECONNREFUSED') {
214
+ console.error('\n❌ Connection Error:', errorMessage);
215
+ console.error('\nPlease verify:');
216
+ console.error(' • Database host and port are correct');
217
+ console.error(' • Username and password are correct');
218
+ console.error(' • Database server is running');
219
+ console.error(' • User has sufficient privileges');
220
+ }
221
+ else if (errorCode === 'ER_BAD_DB_ERROR') {
222
+ console.error('\n❌ Database Error:', errorMessage);
223
+ }
224
+ else {
225
+ console.error('\n❌ Error:', errorMessage);
226
+ }
227
+ p.outro(`\nSetup failed. Please check the errors above and try again.`);
228
+ process.exit(1);
229
+ }
230
+ finally {
231
+ /**
232
+ * Always close the connection, even if an error occurred
233
+ */
234
+ if (migrationClient) {
235
+ await migrationClient.end();
236
+ }
237
+ }
238
+ }
@@ -0,0 +1,2 @@
1
+ export declare function generateDatabaseTables(): Promise<void>;
2
+ //# sourceMappingURL=db-migrate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-migrate.d.ts","sourceRoot":"","sources":["../../../src/cli/lib/db-migrate.ts"],"names":[],"mappings":"AAOA,wBAAsB,sBAAsB,kBAoF3C"}
@@ -0,0 +1,83 @@
1
+ import * as p from '@clack/prompts';
2
+ import { execWithSpinner } from '../utils/exec-utils.js';
3
+ import chalk from 'chalk';
4
+ import { MysqlTableChecker } from '../../core/db/index.js';
5
+ import { db } from '../../db/client.js';
6
+ import { sql } from '../../db/index.js';
7
+ export async function generateDatabaseTables() {
8
+ /**
9
+ * We should first drop all primary keys from the tables
10
+ */
11
+ const _existingTables = [];
12
+ const tablesToCheck = [
13
+ '__nextjs_cms_tables',
14
+ 'admins',
15
+ 'admin_privileges',
16
+ 'access_tokens',
17
+ 'editor_photos',
18
+ ];
19
+ try {
20
+ const result = await MysqlTableChecker.getExistingTables();
21
+ result.forEach((table) => {
22
+ if (tablesToCheck.includes(table)) {
23
+ _existingTables.push(table);
24
+ }
25
+ });
26
+ if (_existingTables.length > 0) {
27
+ const allOrSome = _existingTables.length === tablesToCheck.length ? 'all' : 'some';
28
+ p.log.warn(chalk.yellow(`You already have ${allOrSome === 'some' ? 'a few required tables from' : ''} a previous database schema:`));
29
+ for (const table of _existingTables) {
30
+ p.log.message(chalk.yellow(` - ${table}`));
31
+ }
32
+ p.log.message(chalk.cyan('These tables will be dropped and new ones will be created.'));
33
+ const answer = await p.select({
34
+ message: 'Do you want to continue? (y/n)',
35
+ options: [
36
+ { value: 'y', label: 'Yes' },
37
+ { value: 'n', label: 'No' },
38
+ ],
39
+ initialValue: 'n',
40
+ });
41
+ if (p.isCancel(answer) || answer !== 'y') {
42
+ p.log.error(chalk.red('Aborted\n'));
43
+ process.exit(1);
44
+ }
45
+ try {
46
+ // Disable foreign key checks to allow dropping tables with foreign key constraints
47
+ await db.execute(sql `SET FOREIGN_KEY_CHECKS = 0`);
48
+ // Drop all tables at once
49
+ for (const table of _existingTables) {
50
+ await db.execute(sql `DROP TABLE IF EXISTS \`${sql.raw(table)}\``);
51
+ }
52
+ // Re-enable foreign key checks
53
+ await db.execute(sql `SET FOREIGN_KEY_CHECKS = 1`);
54
+ }
55
+ catch (error) {
56
+ // Re-enable foreign key checks even if there's an error
57
+ await db.execute(sql `SET FOREIGN_KEY_CHECKS = 1`).catch(() => {
58
+ // Ignore errors when re-enabling
59
+ });
60
+ console.error(chalk.red('✗ Error dropping existing tables:'), error);
61
+ p.log.error(chalk.red('✗ Failed to drop existing tables'));
62
+ throw error;
63
+ }
64
+ }
65
+ const spinner = await execWithSpinner({
66
+ command: 'pnpm',
67
+ args: ['drizzle-kit', 'push', '--force', '--config=drizzle.config.ts'],
68
+ cwd: process.cwd(),
69
+ stdout: 'pipe', // Show output
70
+ stderr: 'inherit', // Show errors
71
+ spinnerText: 'Generating database tables...',
72
+ checkExitCode: true, // Throw on non-zero exit codes
73
+ checkStderrForErrors: true, // Also check for errors in output even if exit code is 0
74
+ });
75
+ spinner?.stop();
76
+ p.log.success(chalk.green(' ✓ Database tables generated'));
77
+ }
78
+ catch (error) {
79
+ console.error(chalk.red(' ✗ Error generating database tables:'), error);
80
+ p.log.error(chalk.red('✗ Failed to generate database tables'));
81
+ process.exit(1);
82
+ }
83
+ }
@@ -0,0 +1,2 @@
1
+ export declare function fixMasterAdminPrivileges(): Promise<void>;
2
+ //# sourceMappingURL=fix-master-admin.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,53 @@
1
+ import { getPluginRoutes } from '../../plugins/server.js';
2
+ export async function fixMasterAdminPrivileges() {
3
+ // Lazy import heavy dependencies to avoid eager database connection initialization
4
+ const { SectionFactory } = await import('../../core/factories/index.js');
5
+ const { db } = await import('../../db/client.js');
6
+ 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
+ const sections = await SectionFactory.getSectionsSilently();
10
+ const rows = sections.map((section) => ({
11
+ adminId: '1',
12
+ sectionName: section.name,
13
+ operations: 'CUD',
14
+ publisher: '1',
15
+ }));
16
+ const pluginRoutes = await getPluginRoutes();
17
+ const pluginNames = new Set(pluginRoutes.map((route) => {
18
+ return route.pluginName;
19
+ }));
20
+ pluginNames.forEach((pluginName) => {
21
+ rows.push({
22
+ adminId: '1',
23
+ sectionName: pluginName,
24
+ operations: 'CUD',
25
+ publisher: '1',
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
+ });
43
+ await db
44
+ .insert(AdminPrivilegesTable)
45
+ .values(rows)
46
+ .onDuplicateKeyUpdate({
47
+ set: {
48
+ operations: 'CUD',
49
+ publisher: true,
50
+ },
51
+ });
52
+ return;
53
+ }
@@ -0,0 +1,2 @@
1
+ export declare function setMasterAdmin(): Promise<void>;
2
+ //# sourceMappingURL=set-master-admin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"set-master-admin.d.ts","sourceRoot":"","sources":["../../../src/cli/lib/set-master-admin.ts"],"names":[],"mappings":"AAGA,wBAAsB,cAAc,kBA+FnC"}