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.
- package/dist/cli/commands/db-config.d.ts +2 -0
- package/dist/cli/commands/db-config.d.ts.map +1 -0
- package/dist/cli/commands/db-config.js +22 -0
- package/dist/cli/commands/fix-master-admin.d.ts +2 -0
- package/dist/cli/commands/fix-master-admin.d.ts.map +1 -0
- package/dist/cli/commands/fix-master-admin.js +22 -0
- package/dist/cli/commands/set-master-admin.d.ts +2 -0
- package/dist/cli/commands/set-master-admin.d.ts.map +1 -0
- package/dist/cli/commands/set-master-admin.js +25 -0
- package/dist/cli/commands/setup.d.ts +2 -0
- package/dist/cli/commands/setup.d.ts.map +1 -0
- package/dist/cli/commands/setup.js +34 -0
- package/dist/cli/commands/update-sections.d.ts +2 -0
- package/dist/cli/commands/update-sections.d.ts.map +1 -0
- package/dist/cli/commands/update-sections.js +27 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +15 -0
- package/dist/cli/lib/db-config.d.ts +4 -0
- package/dist/cli/lib/db-config.d.ts.map +1 -0
- package/dist/cli/lib/db-config.js +238 -0
- package/dist/cli/lib/db-migrate.d.ts +2 -0
- package/dist/cli/lib/db-migrate.d.ts.map +1 -0
- package/dist/cli/lib/db-migrate.js +83 -0
- package/dist/cli/lib/fix-master-admin.d.ts +2 -0
- package/dist/cli/lib/fix-master-admin.d.ts.map +1 -0
- package/dist/cli/lib/fix-master-admin.js +53 -0
- package/dist/cli/lib/set-master-admin.d.ts +2 -0
- package/dist/cli/lib/set-master-admin.d.ts.map +1 -0
- package/dist/cli/lib/set-master-admin.js +88 -0
- package/dist/cli/lib/update-sections.d.ts +2 -0
- package/dist/cli/lib/update-sections.d.ts.map +1 -0
- package/dist/cli/lib/update-sections.js +915 -0
- package/dist/cli/program/program.d.ts +4 -0
- package/dist/cli/program/program.d.ts.map +1 -0
- package/dist/cli/program/program.js +95 -0
- package/dist/cli/utils/add-table-keys.d.ts +32 -0
- package/dist/cli/utils/add-table-keys.d.ts.map +1 -0
- package/dist/cli/utils/add-table-keys.js +171 -0
- package/dist/cli/utils/check-version.d.ts +3 -0
- package/dist/cli/utils/check-version.d.ts.map +1 -0
- package/dist/cli/utils/check-version.js +125 -0
- package/dist/cli/utils/display-intro.d.ts +6 -0
- package/dist/cli/utils/display-intro.d.ts.map +1 -0
- package/dist/cli/utils/display-intro.js +9 -0
- package/dist/cli/utils/exec-utils.d.ts +19 -0
- package/dist/cli/utils/exec-utils.d.ts.map +1 -0
- package/dist/cli/utils/exec-utils.js +95 -0
- package/dist/cli/utils/get-package-manager.d.ts +4 -0
- package/dist/cli/utils/get-package-manager.d.ts.map +1 -0
- package/dist/cli/utils/get-package-manager.js +22 -0
- package/dist/cli/utils/reload-env.d.ts +16 -0
- package/dist/cli/utils/reload-env.d.ts.map +1 -0
- package/dist/cli/utils/reload-env.js +42 -0
- package/dist/cli/utils/render-title.d.ts +2 -0
- package/dist/cli/utils/render-title.d.ts.map +1 -0
- package/dist/cli/utils/render-title.js +12 -0
- package/dist/cli/utils/schema-generator.d.ts +10 -0
- package/dist/cli/utils/schema-generator.d.ts.map +1 -0
- package/dist/cli/utils/schema-generator.js +171 -0
- package/dist/core/config/config-loader.d.ts +4 -10
- package/dist/core/config/config-loader.d.ts.map +1 -1
- package/dist/core/config/config-loader.js +14 -14
- package/dist/core/factories/section-factory-with-esbuild.d.ts +1 -1
- package/dist/core/factories/section-factory-with-esbuild.js +1 -1
- package/dist/core/factories/section-factory-with-jiti.d.ts +1 -1
- package/dist/core/factories/section-factory-with-jiti.js +1 -1
- package/dist/core/sections/category.d.ts +32 -32
- package/dist/core/sections/hasItems.d.ts +32 -32
- package/dist/core/sections/section.d.ts +16 -16
- package/dist/core/sections/simple.d.ts +8 -8
- package/dist/db/config.js +1 -1
- package/dist/translations/base/en.d.ts +433 -0
- package/dist/translations/base/en.d.ts.map +1 -0
- package/dist/translations/base/en.js +444 -0
- package/dist/translations/client.d.ts +5178 -1
- package/dist/translations/client.d.ts.map +1 -1
- package/dist/translations/client.js +29 -4
- package/dist/translations/dict-store.d.ts +5 -1
- package/dist/translations/dict-store.d.ts.map +1 -1
- package/dist/translations/dict-store.js +31 -4
- package/dist/translations/index.d.ts +1 -1
- package/dist/translations/index.js +1 -1
- package/dist/translations/server.d.ts +5171 -1
- package/dist/translations/server.d.ts.map +1 -1
- package/dist/translations/server.js +26 -4
- package/package.json +18 -10
- package/dist/core/helpers/i18n.d.ts +0 -2
- package/dist/core/helpers/i18n.d.ts.map +0 -1
- package/dist/core/helpers/i18n.js +0 -3
- package/dist/core/localization.d.ts +0 -40
- package/dist/core/localization.d.ts.map +0 -1
- package/dist/core/localization.js +0 -48
- package/dist/logging/audit.d.ts +0 -20
- package/dist/logging/audit.d.ts.map +0 -1
- package/dist/logging/audit.js +0 -48
- package/dist/translations/localized-string.d.ts +0 -17
- package/dist/translations/localized-string.d.ts.map +0 -1
- package/dist/translations/localized-string.js +0 -32
- package/dist/translations/use-project-translation.d.ts +0 -19
- package/dist/translations/use-project-translation.d.ts.map +0 -1
- package/dist/translations/use-project-translation.js +0 -25
- package/dist/validators/types.d.ts +0 -7
- package/dist/validators/types.d.ts.map +0 -1
- package/dist/validators/types.js +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"program.d.ts","sourceRoot":"","sources":["../../../src/cli/program/program.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAA;AAmB3C,QAAA,MAAM,OAAO,SAAgB,CAAA;AA4F7B,eAAe,OAAO,CAAA"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { Command, Option } from 'commander';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import process from 'node:process';
|
|
4
|
+
import * as p from '@clack/prompts';
|
|
5
|
+
import { displayIntro } from '../utils/display-intro.js';
|
|
6
|
+
import { packageVersion, validateNextjsCmsApp } from '../utils/check-version.js';
|
|
7
|
+
const handleSigTerm = () => {
|
|
8
|
+
p.log.message('\n');
|
|
9
|
+
p.cancel(`Aborted\n`);
|
|
10
|
+
process.exit(1);
|
|
11
|
+
};
|
|
12
|
+
process.on('SIGINT', handleSigTerm);
|
|
13
|
+
process.on('SIGTERM', handleSigTerm);
|
|
14
|
+
// Validate nextjs-cms app and dependencies before proceeding
|
|
15
|
+
validateNextjsCmsApp();
|
|
16
|
+
const program = new Command();
|
|
17
|
+
program
|
|
18
|
+
.name('nextjs-cms')
|
|
19
|
+
.option('-d, --dev', 'use development environment file, use -d/--dev before any command to use the development environment file (e.g. nextjs-cms -d setup)', false)
|
|
20
|
+
.addOption(new Option('-f, --force', 'force the command to run even when version mismatch is detected').hideHelp())
|
|
21
|
+
.description(chalk.green('nextjs-cms CLI toolkit for managing your nextjs-cms application'))
|
|
22
|
+
.version(packageVersion)
|
|
23
|
+
// Include -v option to show the version number
|
|
24
|
+
.addOption(new Option('-v').hideHelp())
|
|
25
|
+
.enablePositionalOptions();
|
|
26
|
+
program
|
|
27
|
+
.command('setup')
|
|
28
|
+
.description('Complete nextjs-cms setup')
|
|
29
|
+
.option('--continue', 'continue the setup if you have already setup the database', false)
|
|
30
|
+
.passThroughOptions()
|
|
31
|
+
.action(async function () {
|
|
32
|
+
const c = Boolean(this.opts().continue);
|
|
33
|
+
const { runSetup } = await import('../commands/setup.js');
|
|
34
|
+
displayIntro({ command: 'setup', dev: Boolean(program.opts().dev), title: 'Setting up nextjs-cms 🚀' });
|
|
35
|
+
await runSetup(Boolean(program.opts().dev), c);
|
|
36
|
+
});
|
|
37
|
+
program
|
|
38
|
+
.command('db-config')
|
|
39
|
+
.description('Initialize nextjs-cms database configuration')
|
|
40
|
+
.passThroughOptions()
|
|
41
|
+
.action(async () => {
|
|
42
|
+
const { runDbConfig } = await import('../commands/db-config.js');
|
|
43
|
+
displayIntro({
|
|
44
|
+
command: 'db-config',
|
|
45
|
+
dev: Boolean(program.opts().dev),
|
|
46
|
+
title: 'Configuring database',
|
|
47
|
+
});
|
|
48
|
+
await runDbConfig(Boolean(program.opts().dev));
|
|
49
|
+
});
|
|
50
|
+
program
|
|
51
|
+
.command('set-master-admin')
|
|
52
|
+
.description('Set or update master admin password')
|
|
53
|
+
.passThroughOptions()
|
|
54
|
+
.action(async () => {
|
|
55
|
+
const { runSetMasterAdmin } = await import('../commands/set-master-admin.js');
|
|
56
|
+
displayIntro({
|
|
57
|
+
command: 'set-master-admin',
|
|
58
|
+
dev: Boolean(program.opts().dev),
|
|
59
|
+
title: 'Setting master admin',
|
|
60
|
+
});
|
|
61
|
+
await runSetMasterAdmin();
|
|
62
|
+
});
|
|
63
|
+
program
|
|
64
|
+
.command('fix-master-admin')
|
|
65
|
+
.description('Fix master admin privileges for all sections')
|
|
66
|
+
.passThroughOptions()
|
|
67
|
+
.action(async () => {
|
|
68
|
+
const { runFixMasterAdmin } = await import('../commands/fix-master-admin.js');
|
|
69
|
+
displayIntro({
|
|
70
|
+
command: 'fix-master-admin',
|
|
71
|
+
dev: Boolean(program.opts().dev),
|
|
72
|
+
title: 'Fixing master admin privileges',
|
|
73
|
+
});
|
|
74
|
+
await runFixMasterAdmin();
|
|
75
|
+
});
|
|
76
|
+
program
|
|
77
|
+
.command('update-sections')
|
|
78
|
+
.description('Update database tables based on current sections and update master admin privileges')
|
|
79
|
+
.passThroughOptions()
|
|
80
|
+
.action(async () => {
|
|
81
|
+
const { runUpdateSections } = await import('../commands/update-sections.js');
|
|
82
|
+
displayIntro({
|
|
83
|
+
command: 'update-sections',
|
|
84
|
+
dev: Boolean(program.opts().dev),
|
|
85
|
+
title: 'Updating sections',
|
|
86
|
+
});
|
|
87
|
+
await runUpdateSections(Boolean(program.opts().dev));
|
|
88
|
+
});
|
|
89
|
+
program.showHelpAfterError('(add --help for additional information)');
|
|
90
|
+
// Show the version number when the -v option is used
|
|
91
|
+
program.on('option:v', () => {
|
|
92
|
+
console.log(program.version());
|
|
93
|
+
process.exit();
|
|
94
|
+
});
|
|
95
|
+
export default program;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { FieldConfig } from '../../core/fields/index.js';
|
|
2
|
+
export declare function addTableKeys(table: {
|
|
3
|
+
name: string;
|
|
4
|
+
primaryKey: FieldConfig[];
|
|
5
|
+
index?: {
|
|
6
|
+
name?: string;
|
|
7
|
+
columns: FieldConfig[];
|
|
8
|
+
}[];
|
|
9
|
+
unique?: {
|
|
10
|
+
name?: string;
|
|
11
|
+
columns: FieldConfig[];
|
|
12
|
+
}[];
|
|
13
|
+
fulltext?: {
|
|
14
|
+
name?: string;
|
|
15
|
+
columns: FieldConfig[];
|
|
16
|
+
}[];
|
|
17
|
+
}, existingKeys?: {
|
|
18
|
+
primaryKeys: string[];
|
|
19
|
+
uniqueKeys: {
|
|
20
|
+
name: string;
|
|
21
|
+
columns: string[];
|
|
22
|
+
}[];
|
|
23
|
+
indexKeys: {
|
|
24
|
+
name: string;
|
|
25
|
+
columns: string[];
|
|
26
|
+
}[];
|
|
27
|
+
fullTextKeys: {
|
|
28
|
+
name: string;
|
|
29
|
+
columns: string[];
|
|
30
|
+
}[];
|
|
31
|
+
}): Promise<number>;
|
|
32
|
+
//# sourceMappingURL=add-table-keys.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add-table-keys.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/add-table-keys.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAA;AAG7D,wBAAsB,YAAY,CAC9B,KAAK,EAAE;IACH,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,WAAW,EAAE,CAAA;IACzB,KAAK,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,WAAW,EAAE,CAAA;KAAE,EAAE,CAAA;IACnD,MAAM,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,WAAW,EAAE,CAAA;KAAE,EAAE,CAAA;IACpD,QAAQ,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,WAAW,EAAE,CAAA;KAAE,EAAE,CAAA;CACzD,EACD,YAAY,CAAC,EAAE;IACX,WAAW,EAAE,MAAM,EAAE,CAAA;IACrB,UAAU,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,EAAE,CAAA;KAAE,EAAE,CAAA;IACjD,SAAS,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,EAAE,CAAA;KAAE,EAAE,CAAA;IAChD,YAAY,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,EAAE,CAAA;KAAE,EAAE,CAAA;CACtD,mBAoPJ"}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
export async function addTableKeys(table, existingKeys) {
|
|
3
|
+
// Lazy import heavy dependencies to avoid eager database connection initialization
|
|
4
|
+
const { db } = await import('../../db/client.js');
|
|
5
|
+
// console.log(chalk.gray(` - Checking table keys`))
|
|
6
|
+
/**
|
|
7
|
+
* Number of SQL errors
|
|
8
|
+
*/
|
|
9
|
+
let sqlErrors = 0;
|
|
10
|
+
/**
|
|
11
|
+
* Add the primary key, but first, check if the primary key exists or has changed
|
|
12
|
+
*/
|
|
13
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
14
|
+
if (table.primaryKey) {
|
|
15
|
+
if (existingKeys) {
|
|
16
|
+
const { primaryKeys } = existingKeys;
|
|
17
|
+
/**
|
|
18
|
+
* Check if the existing primary key matches the new primary key
|
|
19
|
+
*/
|
|
20
|
+
const primaryKeyChanged = primaryKeys.length !== table.primaryKey.length ||
|
|
21
|
+
!table.primaryKey.every((key) => primaryKeys.includes(key.name));
|
|
22
|
+
/**
|
|
23
|
+
* If primary key doesn't exist or has changed, update it
|
|
24
|
+
*/
|
|
25
|
+
if ((primaryKeys.length === 0 && table.primaryKey.length > 0) || primaryKeyChanged) {
|
|
26
|
+
/**
|
|
27
|
+
* Drop existing primary key if it exists
|
|
28
|
+
*/
|
|
29
|
+
if (primaryKeys.length > 0) {
|
|
30
|
+
console.log(chalk.gray(` - Dropping existing primary key from '${table.name}: [${primaryKeys.join(', ')}]`));
|
|
31
|
+
try {
|
|
32
|
+
await db.execute(`ALTER TABLE \`${table.name}\` DROP PRIMARY KEY`);
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
sqlErrors++;
|
|
36
|
+
console.error(chalk.red(` - Error dropping primary key for table '${table.name}':`, error));
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Add the new primary key
|
|
41
|
+
*/
|
|
42
|
+
console.log(chalk.gray(` - Adding primary key to '${table.name}': [${table.primaryKey.map((key) => key.name).join(', ')}]`));
|
|
43
|
+
try {
|
|
44
|
+
const primaryKeyColumns = table.primaryKey.map((column) => `\`${column.name}\``).join(', ');
|
|
45
|
+
await db.execute(`ALTER TABLE \`${table.name}\` ADD PRIMARY KEY (${primaryKeyColumns})`);
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
sqlErrors++;
|
|
49
|
+
console.error(chalk.red(` - Error updating primary key for table '${table.name}':`, error));
|
|
50
|
+
/**
|
|
51
|
+
* Reverting to the old primary key
|
|
52
|
+
*/
|
|
53
|
+
if (primaryKeys.length > 0) {
|
|
54
|
+
console.log(chalk.gray(` - Re-adding old primary key to '${table.name}': [${primaryKeys.map((key) => key).join(', ')}]`));
|
|
55
|
+
try {
|
|
56
|
+
const primaryKeyColumns = primaryKeys.map((column) => `\`${column}\``).join(', ');
|
|
57
|
+
await db.execute(`ALTER TABLE \`${table.name}\` ADD PRIMARY KEY (${primaryKeyColumns})`);
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
sqlErrors++;
|
|
61
|
+
console.error(chalk.red(` - Error re-adding primary key for table '${table.name}':`, error));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
// TODO: What is this?
|
|
69
|
+
sqlErrors++;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Modify unique keys
|
|
74
|
+
*/
|
|
75
|
+
if (table.unique) {
|
|
76
|
+
const existingUniqueKeys = existingKeys?.uniqueKeys ?? [];
|
|
77
|
+
for (const requestedUnique of table.unique) {
|
|
78
|
+
/**
|
|
79
|
+
* Check if the unique key already exists
|
|
80
|
+
*/
|
|
81
|
+
const matchingUnique = existingUniqueKeys.find((u) => {
|
|
82
|
+
return (requestedUnique.columns.length === u.columns.length &&
|
|
83
|
+
requestedUnique.columns.every((col) => u.columns.includes(col.name)));
|
|
84
|
+
});
|
|
85
|
+
const uniqueColumns = requestedUnique.columns.map((col) => `\`${col.name}\``).join(', ');
|
|
86
|
+
/**
|
|
87
|
+
* If key doesn't exist, add it
|
|
88
|
+
*/
|
|
89
|
+
if (!matchingUnique) {
|
|
90
|
+
console.log(chalk.gray(` - Adding unique key with columns [${requestedUnique.columns.map((col) => col.name).join(', ')}] to '${table.name}'`));
|
|
91
|
+
await db.execute(`ALTER TABLE \`${table.name}\` ADD UNIQUE ${requestedUnique.name ?? ''}(${uniqueColumns})`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Drop any existing unique keys that are not in the new set (based on columns)
|
|
96
|
+
*/
|
|
97
|
+
for (const existingUnique of existingUniqueKeys) {
|
|
98
|
+
if (!table.unique.find((unique) => {
|
|
99
|
+
return (unique.columns.length === existingUnique.columns.length &&
|
|
100
|
+
unique.columns.every((col) => existingUnique.columns.includes(col.name)));
|
|
101
|
+
})) {
|
|
102
|
+
console.log(chalk.gray(` - Dropping unique key with columns [${existingUnique.columns.join(', ')}] from '${table.name}'`));
|
|
103
|
+
await db.execute(`ALTER TABLE \`${table.name}\` DROP INDEX \`${existingUnique.name}\``);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Modify indexes
|
|
109
|
+
*/
|
|
110
|
+
if (table.index) {
|
|
111
|
+
const existingIndexes = existingKeys?.indexKeys ?? [];
|
|
112
|
+
for (const index of table.index) {
|
|
113
|
+
const matchingIndex = existingIndexes.find((i) => {
|
|
114
|
+
return (index.columns.length === i.columns.length &&
|
|
115
|
+
index.columns.every((col) => i.columns.includes(col.name)));
|
|
116
|
+
});
|
|
117
|
+
const indexColumns = index.columns.map((col) => `\`${col.name}\``).join(', ');
|
|
118
|
+
if (!matchingIndex) {
|
|
119
|
+
// Add index
|
|
120
|
+
console.log(chalk.gray(` - Adding index with columns [${index.columns.map((col) => col.name).join(', ')}] to '${table.name}'`));
|
|
121
|
+
await db.execute(`ALTER TABLE \`${table.name}\` ADD INDEX ${index.name ?? ''}(${indexColumns})`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Drop any existing indexes that are not in the new set (based on columns)
|
|
126
|
+
*/
|
|
127
|
+
for (const existingIndex of existingIndexes) {
|
|
128
|
+
if (!table.index.find((index) => {
|
|
129
|
+
return (index.columns.length === existingIndex.columns.length &&
|
|
130
|
+
index.columns.every((col) => existingIndex.columns.includes(col.name)));
|
|
131
|
+
})) {
|
|
132
|
+
console.log(chalk.gray(` - Dropping index with columns [${existingIndex.columns.join(', ')}] from '${table.name}'`));
|
|
133
|
+
await db.execute(`ALTER TABLE \`${table.name}\` DROP INDEX \`${existingIndex.name}\``);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Modify fulltext indexes
|
|
139
|
+
*/
|
|
140
|
+
if (table.fulltext) {
|
|
141
|
+
const existingIndexes = existingKeys?.fullTextKeys ?? [];
|
|
142
|
+
for (const requestedFullTextIndex of table.fulltext) {
|
|
143
|
+
const matchingFulltext = existingIndexes.find((i) => {
|
|
144
|
+
return (requestedFullTextIndex.columns.length === i.columns.length &&
|
|
145
|
+
requestedFullTextIndex.columns.every((col) => i.columns.includes(col.name)));
|
|
146
|
+
});
|
|
147
|
+
const fulltextColumns = requestedFullTextIndex.columns.map((col) => `\`${col.name}\``).join(', ');
|
|
148
|
+
/**
|
|
149
|
+
* If fulltext index doesn't exist, add it
|
|
150
|
+
*/
|
|
151
|
+
if (!matchingFulltext) {
|
|
152
|
+
// Add fulltext index
|
|
153
|
+
console.log(chalk.gray(` - Adding fulltext index with columns [${requestedFullTextIndex.columns.map((col) => col.name).join(', ')}] to '${table.name}'`));
|
|
154
|
+
await db.execute(`ALTER TABLE \`${table.name}\` ADD FULLTEXT ${requestedFullTextIndex.name ?? ''}(${fulltextColumns})`);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Drop any existing fulltext indexes that are not in the new set (based on columns)
|
|
159
|
+
*/
|
|
160
|
+
for (const existingFulltext of existingIndexes) {
|
|
161
|
+
if (!table.fulltext.find((fulltext) => {
|
|
162
|
+
return (fulltext.columns.length === existingFulltext.columns.length &&
|
|
163
|
+
fulltext.columns.every((col) => existingFulltext.columns.includes(col.name)));
|
|
164
|
+
})) {
|
|
165
|
+
console.log(chalk.gray(` - Dropping fulltext index with columns [${existingFulltext.columns.join(', ')}] from '${table.name}'`));
|
|
166
|
+
await db.execute(`ALTER TABLE \`${table.name}\` DROP INDEX \`${existingFulltext.name}\``);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return sqlErrors;
|
|
171
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check-version.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/check-version.ts"],"names":[],"mappings":"AAoIA,wBAAgB,oBAAoB,IAAI,IAAI,CAsC3C;AAED,eAAO,MAAM,cAAc,QAAsB,CAAA"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { readFileSync, existsSync, realpathSync } from 'node:fs';
|
|
2
|
+
import { join, dirname } from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
import { createRequire } from 'module';
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
function findPackageJson(startDir) {
|
|
7
|
+
let dir = startDir ?? process.cwd();
|
|
8
|
+
while (true) {
|
|
9
|
+
const candidate = join(dir, 'package.json');
|
|
10
|
+
if (existsSync(candidate))
|
|
11
|
+
return candidate;
|
|
12
|
+
const parent = dirname(dir);
|
|
13
|
+
if (parent === dir)
|
|
14
|
+
break;
|
|
15
|
+
dir = parent;
|
|
16
|
+
}
|
|
17
|
+
return undefined;
|
|
18
|
+
}
|
|
19
|
+
function findConfigFile(startDir) {
|
|
20
|
+
let dir = startDir ?? process.cwd();
|
|
21
|
+
while (true) {
|
|
22
|
+
const candidate = join(dir, 'cms.config.ts');
|
|
23
|
+
if (existsSync(candidate))
|
|
24
|
+
return candidate;
|
|
25
|
+
const parent = dirname(dir);
|
|
26
|
+
if (parent === dir)
|
|
27
|
+
break;
|
|
28
|
+
dir = parent;
|
|
29
|
+
}
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
// Get version dynamically from package.json
|
|
33
|
+
const currentFilePath = fileURLToPath(import.meta.url);
|
|
34
|
+
const currentDir = dirname(currentFilePath);
|
|
35
|
+
const packageJsonPath = join(currentDir, '../../../package.json');
|
|
36
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
|
|
37
|
+
function checkNextjsCmsInstallation() {
|
|
38
|
+
const requireFromCwd = createRequire(join(process.cwd(), 'index.js'));
|
|
39
|
+
// Check for cms.config.ts file
|
|
40
|
+
const configFile = findConfigFile();
|
|
41
|
+
if (configFile === undefined) {
|
|
42
|
+
return { error: 'not-nextjs-cms-app' };
|
|
43
|
+
}
|
|
44
|
+
// Check for nextjs-cms dependency in package.json
|
|
45
|
+
const pkgPath = findPackageJson();
|
|
46
|
+
if (pkgPath === undefined) {
|
|
47
|
+
return { error: 'not-nextjs-cms-app' };
|
|
48
|
+
}
|
|
49
|
+
const packageJson = JSON.parse(readFileSync(pkgPath, 'utf8'));
|
|
50
|
+
const deps = {
|
|
51
|
+
...(packageJson.dependencies ?? {}),
|
|
52
|
+
...(packageJson.devDependencies ?? {}),
|
|
53
|
+
};
|
|
54
|
+
const versionInProjectPackageJson = deps['nextjs-cms'];
|
|
55
|
+
if (versionInProjectPackageJson === undefined) {
|
|
56
|
+
return { error: 'local-not-found' };
|
|
57
|
+
}
|
|
58
|
+
// Hard check for installed version
|
|
59
|
+
// Resolve whatever the package exports at "." (this IS allowed)
|
|
60
|
+
const entryPath = requireFromCwd.resolve('nextjs-cms');
|
|
61
|
+
// Follow symlinks (helps with pnpm layouts)
|
|
62
|
+
const startPath = realpathSync(entryPath);
|
|
63
|
+
const installedPackageJson = findPackageJson(startPath);
|
|
64
|
+
if (installedPackageJson === undefined) {
|
|
65
|
+
return {
|
|
66
|
+
error: 'local-needs-update',
|
|
67
|
+
installedVersion: 'undefined',
|
|
68
|
+
packageVersion: versionInProjectPackageJson,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
const installedPackageJsonParsed = JSON.parse(readFileSync(installedPackageJson, 'utf8'));
|
|
72
|
+
const localInstalledVersion = installedPackageJsonParsed?.version ?? undefined;
|
|
73
|
+
if (localInstalledVersion !== versionInProjectPackageJson) {
|
|
74
|
+
return {
|
|
75
|
+
error: 'local-needs-update',
|
|
76
|
+
installedVersion: localInstalledVersion ?? 'undefined',
|
|
77
|
+
packageVersion: versionInProjectPackageJson,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
function shouldSkipValidation() {
|
|
83
|
+
const args = process.argv.slice(2); // Remove 'node' and script path
|
|
84
|
+
return (args.includes('-h') ||
|
|
85
|
+
args.includes('--help') ||
|
|
86
|
+
args.includes('-V') ||
|
|
87
|
+
args.includes('--version') ||
|
|
88
|
+
args.includes('-v') ||
|
|
89
|
+
args.includes('--force'));
|
|
90
|
+
}
|
|
91
|
+
export function validateNextjsCmsApp() {
|
|
92
|
+
// Skip validation for help and version commands
|
|
93
|
+
if (shouldSkipValidation()) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
const result = checkNextjsCmsInstallation();
|
|
97
|
+
if (typeof result === 'object' && 'error' in result) {
|
|
98
|
+
switch (result.error) {
|
|
99
|
+
case 'not-nextjs-cms-app':
|
|
100
|
+
console.error(chalk.red('❌ Error: This command must be run in a nextjs-cms application directory.'));
|
|
101
|
+
console.error(chalk.gray('Make sure you have:'));
|
|
102
|
+
console.error(chalk.gray(' - cms.config.ts file'));
|
|
103
|
+
console.error(chalk.gray(' - nextjs-cms as a dependency in package.json'));
|
|
104
|
+
console.error(chalk.gray(' - Did you forget to run `pnpm install`?'));
|
|
105
|
+
console.error('');
|
|
106
|
+
console.error(chalk.gray('To create a new nextjs-cms application, run:'));
|
|
107
|
+
console.error(chalk.gray(' - pnpm create nextjs-cms@latest'));
|
|
108
|
+
break;
|
|
109
|
+
case 'local-not-found':
|
|
110
|
+
console.error(chalk.red('❌ Error: nextjs-cms is not a dependency in package.json'));
|
|
111
|
+
console.error(chalk.gray('Make sure you have:'));
|
|
112
|
+
console.error(chalk.gray(' - nextjs-cms as a dependency in package.json'));
|
|
113
|
+
console.error(chalk.gray(' - Did you forget to run `pnpm install`?'));
|
|
114
|
+
break;
|
|
115
|
+
case 'local-needs-update':
|
|
116
|
+
console.error(chalk.red('❌ Error: the version of installed nextjs-cms in your cms is different from the version in package.json'));
|
|
117
|
+
console.error(chalk.gray(' - Installed version: ' + result.installedVersion));
|
|
118
|
+
console.error(chalk.gray(' - Package version: ' + result.packageVersion));
|
|
119
|
+
console.error(chalk.green(' - Please run `pnpm install and try again'));
|
|
120
|
+
break;
|
|
121
|
+
}
|
|
122
|
+
process.exit(1);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
export const packageVersion = packageJson.version;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"display-intro.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/display-intro.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,YAAY,GAAI,yBAAyB;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,SASrG,CAAA"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { getTitle } from './render-title.js';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import * as p from '@clack/prompts';
|
|
4
|
+
export const displayIntro = ({ command, dev, title }) => {
|
|
5
|
+
console.log();
|
|
6
|
+
console.log(chalk.white.bold(`${getTitle()} > ${chalk.cyan.italic(command)} ${dev ? chalk.gray('(development)') : chalk.gray('(production)')}`));
|
|
7
|
+
console.log();
|
|
8
|
+
p.intro(chalk.inverse(` ${title} `));
|
|
9
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Ora } from 'ora';
|
|
2
|
+
export interface ExecWithSpinnerOptions {
|
|
3
|
+
command: string;
|
|
4
|
+
args: string[];
|
|
5
|
+
cwd?: string;
|
|
6
|
+
stdout?: 'pipe' | 'ignore' | 'inherit';
|
|
7
|
+
stderr?: 'pipe' | 'ignore' | 'inherit';
|
|
8
|
+
spinnerText?: string;
|
|
9
|
+
onDataHandle?: (spinner: Ora) => (data: Buffer) => void;
|
|
10
|
+
onStderrHandle?: (data: Buffer) => void;
|
|
11
|
+
checkExitCode?: boolean;
|
|
12
|
+
checkStderrForErrors?: boolean;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Execute a command with a spinner, handling different stdio configurations
|
|
16
|
+
* and optional data handlers for progress updates.
|
|
17
|
+
*/
|
|
18
|
+
export declare const execWithSpinner: (options: ExecWithSpinnerOptions) => Promise<Ora | null>;
|
|
19
|
+
//# sourceMappingURL=exec-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exec-utils.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/exec-utils.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,KAAK,CAAA;AAE9B,MAAM,WAAW,sBAAsB;IACnC,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,MAAM,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAA;IACtC,MAAM,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAA;IACtC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IACvD,cAAc,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IACvC,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,oBAAoB,CAAC,EAAE,OAAO,CAAA;CACjC;AAED;;;GAGG;AACH,eAAO,MAAM,eAAe,GAAU,SAAS,sBAAsB,KAAG,OAAO,CAAC,GAAG,GAAG,IAAI,CAuGzF,CAAA"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { execa } from 'execa';
|
|
2
|
+
import ora from 'ora';
|
|
3
|
+
/**
|
|
4
|
+
* Execute a command with a spinner, handling different stdio configurations
|
|
5
|
+
* and optional data handlers for progress updates.
|
|
6
|
+
*/
|
|
7
|
+
export const execWithSpinner = async (options) => {
|
|
8
|
+
const { command, args, cwd, stdout = 'pipe', stderr = 'pipe', spinnerText = `Running ${command}...`, onDataHandle, onStderrHandle, checkExitCode = false, checkStderrForErrors = false, } = options;
|
|
9
|
+
const spinner = ora(spinnerText).start();
|
|
10
|
+
// If we need to check for errors in stderr but want to show it, we need to pipe it
|
|
11
|
+
const actualStderr = checkStderrForErrors && stderr === 'inherit' ? 'pipe' : stderr;
|
|
12
|
+
const actualStdout = checkStderrForErrors && stdout === 'inherit' ? 'pipe' : stdout;
|
|
13
|
+
const subprocess = execa(command, args, {
|
|
14
|
+
cwd,
|
|
15
|
+
stdout: actualStdout,
|
|
16
|
+
stderr: actualStderr,
|
|
17
|
+
reject: false, // Don't reject on non-zero exit codes - we handle it manually
|
|
18
|
+
});
|
|
19
|
+
let stderrOutput = '';
|
|
20
|
+
let stdoutOutput = '';
|
|
21
|
+
await new Promise((res, rej) => {
|
|
22
|
+
if (onDataHandle) {
|
|
23
|
+
subprocess.stdout?.on('data', onDataHandle(spinner));
|
|
24
|
+
}
|
|
25
|
+
else if (actualStdout === 'pipe') {
|
|
26
|
+
// Capture stdout to check for errors
|
|
27
|
+
subprocess.stdout?.on('data', (data) => {
|
|
28
|
+
const text = data.toString();
|
|
29
|
+
stdoutOutput += text;
|
|
30
|
+
// If we're supposed to inherit stdout, output it
|
|
31
|
+
if (stdout === 'inherit') {
|
|
32
|
+
process.stdout.write(data);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
if (onStderrHandle) {
|
|
37
|
+
subprocess.stderr?.on('data', (data) => {
|
|
38
|
+
onStderrHandle(data);
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
else if (actualStderr === 'pipe') {
|
|
42
|
+
// Capture stderr to check for specific errors
|
|
43
|
+
subprocess.stderr?.on('data', (data) => {
|
|
44
|
+
const text = data.toString();
|
|
45
|
+
stderrOutput += text;
|
|
46
|
+
// If we're supposed to inherit stderr, output it
|
|
47
|
+
if (stderr === 'inherit') {
|
|
48
|
+
process.stderr.write(data);
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
void subprocess.on('error', (e) => rej(e));
|
|
53
|
+
void subprocess.on('close', (code) => {
|
|
54
|
+
// Check for errors in stderr/stdout even if exit code is 0
|
|
55
|
+
if (checkStderrForErrors) {
|
|
56
|
+
const combinedOutput = (stderrOutput + stdoutOutput).toLowerCase();
|
|
57
|
+
const hasError = combinedOutput.includes('error:') ||
|
|
58
|
+
combinedOutput.includes('errno:') ||
|
|
59
|
+
combinedOutput.includes('sqlstate:') ||
|
|
60
|
+
combinedOutput.includes('multiple primary key') ||
|
|
61
|
+
combinedOutput.includes('er_multiple_pri_key') ||
|
|
62
|
+
/error\s+\d+/.test(combinedOutput);
|
|
63
|
+
if (hasError) {
|
|
64
|
+
const error = new Error(`${command} encountered an error during execution`);
|
|
65
|
+
if (stderrOutput) {
|
|
66
|
+
;
|
|
67
|
+
error.stderr = stderrOutput;
|
|
68
|
+
}
|
|
69
|
+
if (stdoutOutput) {
|
|
70
|
+
;
|
|
71
|
+
error.stdout = stdoutOutput;
|
|
72
|
+
}
|
|
73
|
+
rej(error);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (checkExitCode && code !== 0) {
|
|
78
|
+
const error = new Error(`${command} exited with code ${code}`);
|
|
79
|
+
if (stderrOutput) {
|
|
80
|
+
;
|
|
81
|
+
error.stderr = stderrOutput;
|
|
82
|
+
}
|
|
83
|
+
if (stdoutOutput) {
|
|
84
|
+
;
|
|
85
|
+
error.stdout = stdoutOutput;
|
|
86
|
+
}
|
|
87
|
+
rej(error);
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
res();
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
return spinner;
|
|
95
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-package-manager.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/get-package-manager.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAA;AAC5D,wBAAgB,oBAAoB,IAAI,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,CAkBtE"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export function detectPackageManager() {
|
|
2
|
+
// This environment variable is set by npm and yarn but pnpm seems less consistent
|
|
3
|
+
const userAgent = process.env.npm_config_user_agent;
|
|
4
|
+
if (userAgent) {
|
|
5
|
+
if (userAgent.startsWith('yarn')) {
|
|
6
|
+
return 'yarn';
|
|
7
|
+
}
|
|
8
|
+
else if (userAgent.startsWith('pnpm')) {
|
|
9
|
+
return 'pnpm';
|
|
10
|
+
}
|
|
11
|
+
else if (userAgent.startsWith('bun')) {
|
|
12
|
+
return 'bun';
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
return 'npm';
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
// If no user agent is set, assume npm
|
|
20
|
+
return 'npm';
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reloads environment variables from .env files
|
|
3
|
+
* This is useful after programmatically writing to .env files
|
|
4
|
+
*/
|
|
5
|
+
export declare function reloadEnvironmentVariables(envFile?: string): boolean;
|
|
6
|
+
/**
|
|
7
|
+
* Updates specific environment variables in process.env
|
|
8
|
+
* This provides immediate availability without requiring a full reload
|
|
9
|
+
*/
|
|
10
|
+
export declare function updateEnvironmentVariables(variables: Record<string, string>): void;
|
|
11
|
+
/**
|
|
12
|
+
* Reloads environment variables and updates specific ones in process.env
|
|
13
|
+
* This combines both approaches for maximum compatibility
|
|
14
|
+
*/
|
|
15
|
+
export declare function reloadAndUpdateEnvironmentVariables(variables?: Record<string, string>, envFile?: string): boolean;
|
|
16
|
+
//# sourceMappingURL=reload-env.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reload-env.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/reload-env.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAepE;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAIlF;AAED;;;GAGG;AACH,wBAAgB,mCAAmC,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAQjH"}
|