autoblogger 0.2.1 → 0.2.3
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/README.md +39 -7
- package/dist/cli/index.js +72 -142
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/styles/autoblogger.css +41 -1
- package/dist/styles/standalone.css +1 -0
- package/package.json +5 -3
package/README.md
CHANGED
|
@@ -18,8 +18,9 @@ npx autoblogger init
|
|
|
18
18
|
The CLI automatically:
|
|
19
19
|
- Detects your Next.js and Prisma setup
|
|
20
20
|
- Adds required database models to your schema
|
|
21
|
-
- Creates config, API route, and dashboard page
|
|
22
|
-
-
|
|
21
|
+
- Creates config, API route, and dashboard page (in isolated route group)
|
|
22
|
+
- Adds the standalone CSS import to your globals.css
|
|
23
|
+
- Fixes hydration warnings for theme switching
|
|
23
24
|
- Runs the database migration
|
|
24
25
|
|
|
25
26
|
Visit `/writer` to start writing.
|
|
@@ -37,9 +38,10 @@ Visit `/writer` to start writing.
|
|
|
37
38
|
|
|
38
39
|
## Requirements
|
|
39
40
|
|
|
40
|
-
- Next.js 14 or
|
|
41
|
+
- Next.js 14, 15, or 16 (App Router)
|
|
41
42
|
- Prisma 5 or 6
|
|
42
43
|
- Node.js 20+
|
|
44
|
+
- Any CSS setup (Tailwind optional — standalone CSS included)
|
|
43
45
|
|
|
44
46
|
For AI features, you'll need API keys from [Anthropic](https://console.anthropic.com/) and/or [OpenAI](https://platform.openai.com/).
|
|
45
47
|
|
|
@@ -151,24 +153,54 @@ import { getSeoValues } from 'autoblogger/seo'
|
|
|
151
153
|
import { ARTICLE_CLASSES } from 'autoblogger/styles/article'
|
|
152
154
|
```
|
|
153
155
|
|
|
154
|
-
##
|
|
156
|
+
## Styling
|
|
157
|
+
|
|
158
|
+
Autoblogger ships with standalone CSS that works with any setup — no Tailwind required.
|
|
159
|
+
|
|
160
|
+
**Using the CLI?** It automatically adds the import for you.
|
|
161
|
+
|
|
162
|
+
**Manual setup?** Add to your `globals.css`:
|
|
163
|
+
```css
|
|
164
|
+
@import 'autoblogger/styles/standalone.css';
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
This single import includes all styles needed for the dashboard. Works with Tailwind v3, v4, CSS Modules, vanilla CSS, or no CSS framework at all.
|
|
168
|
+
|
|
169
|
+
### Advanced: Customizing Theme Colors
|
|
170
|
+
|
|
171
|
+
If you use Tailwind and want autoblogger to inherit your theme colors, you can use the preset instead:
|
|
155
172
|
|
|
156
|
-
**Tailwind classes not applying?** Add to your Tailwind content config:
|
|
157
173
|
```javascript
|
|
158
|
-
|
|
174
|
+
// tailwind.config.js (Tailwind v3 only)
|
|
175
|
+
module.exports = {
|
|
176
|
+
presets: [require('autoblogger/styles/preset')],
|
|
177
|
+
content: [
|
|
178
|
+
// your paths...
|
|
179
|
+
'./node_modules/autoblogger/dist/**/*.{js,mjs}',
|
|
180
|
+
],
|
|
181
|
+
}
|
|
159
182
|
```
|
|
160
183
|
|
|
161
|
-
|
|
184
|
+
Then import the base styles (without utilities):
|
|
162
185
|
```css
|
|
163
186
|
@import 'autoblogger/styles/autoblogger.css';
|
|
164
187
|
```
|
|
165
188
|
|
|
189
|
+
## Troubleshooting
|
|
190
|
+
|
|
166
191
|
**AI not working?** Check your environment variables:
|
|
167
192
|
```bash
|
|
168
193
|
ANTHROPIC_API_KEY="sk-ant-..."
|
|
169
194
|
OPENAI_API_KEY="sk-..."
|
|
170
195
|
```
|
|
171
196
|
|
|
197
|
+
**Hydration warnings with theme?** The CLI automatically adds `suppressHydrationWarning` to your root layout. If you set up manually, add it to your `<html>` tag:
|
|
198
|
+
```tsx
|
|
199
|
+
<html lang="en" suppressHydrationWarning>
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
**Layout conflicts?** The CLI creates the writer dashboard in an isolated route group `app/(writer)/writer/` to prevent inheriting your app's navbar/footer.
|
|
203
|
+
|
|
172
204
|
## License
|
|
173
205
|
|
|
174
206
|
MIT © [Hunter Rosenblume](https://github.com/hrosenblume)
|
package/dist/cli/index.js
CHANGED
|
@@ -24,7 +24,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
24
24
|
));
|
|
25
25
|
|
|
26
26
|
// src/cli/init.ts
|
|
27
|
-
var
|
|
27
|
+
var fs6 = __toESM(require("fs"));
|
|
28
28
|
var path6 = __toESM(require("path"));
|
|
29
29
|
var import_child_process2 = require("child_process");
|
|
30
30
|
var import_picocolors3 = __toESM(require("picocolors"));
|
|
@@ -388,90 +388,10 @@ function writeSchema(schemaPath, content) {
|
|
|
388
388
|
fs3.writeFileSync(schemaPath, content, "utf-8");
|
|
389
389
|
}
|
|
390
390
|
|
|
391
|
-
// src/cli/utils/tailwind-patch.ts
|
|
392
|
-
var fs4 = __toESM(require("fs"));
|
|
393
|
-
var AUTOBLOGGER_CONTENT_PATH = "'./node_modules/autoblogger/dist/**/*.{js,mjs}'";
|
|
394
|
-
var AUTOBLOGGER_SOURCE_PATH = '"./node_modules/autoblogger/dist/**/*.{js,mjs}"';
|
|
395
|
-
function patchTailwindConfig(configPath) {
|
|
396
|
-
if (!fs4.existsSync(configPath)) {
|
|
397
|
-
return { success: false, alreadyPatched: false };
|
|
398
|
-
}
|
|
399
|
-
let content = fs4.readFileSync(configPath, "utf-8");
|
|
400
|
-
if (content.includes("autoblogger")) {
|
|
401
|
-
return { success: true, alreadyPatched: true };
|
|
402
|
-
}
|
|
403
|
-
const contentArrayRegex = /(content\s*:\s*\[)([^\]]*?)(\])/s;
|
|
404
|
-
const match = content.match(contentArrayRegex);
|
|
405
|
-
if (match) {
|
|
406
|
-
const [full, start, items, end] = match;
|
|
407
|
-
const trimmedItems = items.trimEnd();
|
|
408
|
-
const needsComma = trimmedItems.length > 0 && !trimmedItems.endsWith(",");
|
|
409
|
-
const newItems = trimmedItems + (needsComma ? "," : "") + "\n // Autoblogger components\n " + AUTOBLOGGER_CONTENT_PATH + ",\n ";
|
|
410
|
-
content = content.replace(full, start + newItems + end);
|
|
411
|
-
return { success: true, alreadyPatched: false, content };
|
|
412
|
-
}
|
|
413
|
-
if (content.includes("export default")) {
|
|
414
|
-
const configObjRegex = /(export\s+default\s*\{)/;
|
|
415
|
-
if (configObjRegex.test(content)) {
|
|
416
|
-
content = content.replace(
|
|
417
|
-
configObjRegex,
|
|
418
|
-
`$1
|
|
419
|
-
content: [
|
|
420
|
-
// Autoblogger components
|
|
421
|
-
${AUTOBLOGGER_CONTENT_PATH},
|
|
422
|
-
],`
|
|
423
|
-
);
|
|
424
|
-
return { success: true, alreadyPatched: false, content };
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
if (content.includes("module.exports")) {
|
|
428
|
-
const moduleExportsRegex = /(module\.exports\s*=\s*\{)/;
|
|
429
|
-
if (moduleExportsRegex.test(content)) {
|
|
430
|
-
content = content.replace(
|
|
431
|
-
moduleExportsRegex,
|
|
432
|
-
`$1
|
|
433
|
-
content: [
|
|
434
|
-
// Autoblogger components
|
|
435
|
-
${AUTOBLOGGER_CONTENT_PATH},
|
|
436
|
-
],`
|
|
437
|
-
);
|
|
438
|
-
return { success: true, alreadyPatched: false, content };
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
return { success: false, alreadyPatched: false };
|
|
442
|
-
}
|
|
443
|
-
function patchTailwindCssConfig(cssPath) {
|
|
444
|
-
if (!fs4.existsSync(cssPath)) {
|
|
445
|
-
return { success: false, alreadyPatched: false, isCssConfig: true };
|
|
446
|
-
}
|
|
447
|
-
let content = fs4.readFileSync(cssPath, "utf-8");
|
|
448
|
-
if (!content.includes('@import "tailwindcss"') && !content.includes("@import 'tailwindcss'")) {
|
|
449
|
-
return { success: false, alreadyPatched: false, isCssConfig: false };
|
|
450
|
-
}
|
|
451
|
-
if (content.includes("autoblogger")) {
|
|
452
|
-
return { success: true, alreadyPatched: true, isCssConfig: true };
|
|
453
|
-
}
|
|
454
|
-
const importRegex = /(@import\s+["']tailwindcss["'];?\s*\n)/;
|
|
455
|
-
const match = content.match(importRegex);
|
|
456
|
-
if (match) {
|
|
457
|
-
content = content.replace(
|
|
458
|
-
importRegex,
|
|
459
|
-
`$1/* Autoblogger components */
|
|
460
|
-
@source ${AUTOBLOGGER_SOURCE_PATH};
|
|
461
|
-
`
|
|
462
|
-
);
|
|
463
|
-
return { success: true, alreadyPatched: false, content, isCssConfig: true };
|
|
464
|
-
}
|
|
465
|
-
return { success: false, alreadyPatched: false, isCssConfig: true };
|
|
466
|
-
}
|
|
467
|
-
function writeTailwindConfig(configPath, content) {
|
|
468
|
-
fs4.writeFileSync(configPath, content, "utf-8");
|
|
469
|
-
}
|
|
470
|
-
|
|
471
391
|
// src/cli/utils/css-patch.ts
|
|
472
|
-
var
|
|
392
|
+
var fs4 = __toESM(require("fs"));
|
|
473
393
|
var path4 = __toESM(require("path"));
|
|
474
|
-
var AUTOBLOGGER_CSS_IMPORT = "@import 'autoblogger/styles/
|
|
394
|
+
var AUTOBLOGGER_CSS_IMPORT = "@import 'autoblogger/styles/standalone.css';";
|
|
475
395
|
function findGlobalsCss(projectRoot) {
|
|
476
396
|
const candidates = [
|
|
477
397
|
"app/globals.css",
|
|
@@ -483,22 +403,22 @@ function findGlobalsCss(projectRoot) {
|
|
|
483
403
|
];
|
|
484
404
|
for (const candidate of candidates) {
|
|
485
405
|
const fullPath = path4.join(projectRoot, candidate);
|
|
486
|
-
if (
|
|
406
|
+
if (fs4.existsSync(fullPath)) {
|
|
487
407
|
return fullPath;
|
|
488
408
|
}
|
|
489
409
|
}
|
|
490
410
|
return null;
|
|
491
411
|
}
|
|
492
412
|
function patchGlobalsCss(cssPath) {
|
|
493
|
-
if (!
|
|
413
|
+
if (!fs4.existsSync(cssPath)) {
|
|
494
414
|
return { success: false, alreadyPatched: false };
|
|
495
415
|
}
|
|
496
|
-
let content =
|
|
416
|
+
let content = fs4.readFileSync(cssPath, "utf-8");
|
|
497
417
|
if (content.includes("autoblogger")) {
|
|
498
418
|
return { success: true, alreadyPatched: true, filePath: cssPath };
|
|
499
419
|
}
|
|
500
420
|
content = AUTOBLOGGER_CSS_IMPORT + "\n\n" + content;
|
|
501
|
-
|
|
421
|
+
fs4.writeFileSync(cssPath, content, "utf-8");
|
|
502
422
|
return { success: true, alreadyPatched: false, filePath: cssPath };
|
|
503
423
|
}
|
|
504
424
|
|
|
@@ -702,8 +622,18 @@ export default async function WriterPage({
|
|
|
702
622
|
}
|
|
703
623
|
`;
|
|
704
624
|
|
|
625
|
+
// src/cli/templates/writer-layout.ts
|
|
626
|
+
var WRITER_LAYOUT_TEMPLATE = `export default function WriterLayout({
|
|
627
|
+
children,
|
|
628
|
+
}: {
|
|
629
|
+
children: React.ReactNode
|
|
630
|
+
}) {
|
|
631
|
+
return children
|
|
632
|
+
}
|
|
633
|
+
`;
|
|
634
|
+
|
|
705
635
|
// src/cli/import.ts
|
|
706
|
-
var
|
|
636
|
+
var fs5 = __toESM(require("fs"));
|
|
707
637
|
var path5 = __toESM(require("path"));
|
|
708
638
|
var import_child_process = require("child_process");
|
|
709
639
|
var import_picocolors2 = __toESM(require("picocolors"));
|
|
@@ -768,7 +698,7 @@ function slugify(text) {
|
|
|
768
698
|
}
|
|
769
699
|
function parseMarkdownFile(filePath) {
|
|
770
700
|
try {
|
|
771
|
-
const content =
|
|
701
|
+
const content = fs5.readFileSync(filePath, "utf-8");
|
|
772
702
|
const { frontmatter, body } = parseFrontmatter(content);
|
|
773
703
|
let title = frontmatter.title;
|
|
774
704
|
if (!title) {
|
|
@@ -806,7 +736,7 @@ function parseMarkdownFile(filePath) {
|
|
|
806
736
|
function findMarkdownFiles(dir) {
|
|
807
737
|
const files = [];
|
|
808
738
|
function walk(currentDir) {
|
|
809
|
-
const entries =
|
|
739
|
+
const entries = fs5.readdirSync(currentDir, { withFileTypes: true });
|
|
810
740
|
for (const entry of entries) {
|
|
811
741
|
const fullPath = path5.join(currentDir, entry.name);
|
|
812
742
|
if (entry.isDirectory()) {
|
|
@@ -824,7 +754,7 @@ function findMarkdownFiles(dir) {
|
|
|
824
754
|
async function importContent(dirPath, options = {}) {
|
|
825
755
|
const cwd = process.cwd();
|
|
826
756
|
const absolutePath = path5.isAbsolute(dirPath) ? dirPath : path5.join(cwd, dirPath);
|
|
827
|
-
if (!
|
|
757
|
+
if (!fs5.existsSync(absolutePath)) {
|
|
828
758
|
throw new Error(`Directory not found: ${dirPath}`);
|
|
829
759
|
}
|
|
830
760
|
const files = findMarkdownFiles(absolutePath);
|
|
@@ -851,7 +781,7 @@ async function importContent(dirPath, options = {}) {
|
|
|
851
781
|
const status = options.status || "draft";
|
|
852
782
|
const importScript = generateImportScript(posts, status, options.tag);
|
|
853
783
|
const scriptPath = path5.join(cwd, ".autoblogger-import.mjs");
|
|
854
|
-
|
|
784
|
+
fs5.writeFileSync(scriptPath, importScript);
|
|
855
785
|
try {
|
|
856
786
|
(0, import_child_process.execSync)(`node ${scriptPath}`, {
|
|
857
787
|
cwd,
|
|
@@ -859,8 +789,8 @@ async function importContent(dirPath, options = {}) {
|
|
|
859
789
|
});
|
|
860
790
|
log("check", `Imported ${posts.length} posts as ${status}`);
|
|
861
791
|
} finally {
|
|
862
|
-
if (
|
|
863
|
-
|
|
792
|
+
if (fs5.existsSync(scriptPath)) {
|
|
793
|
+
fs5.unlinkSync(scriptPath);
|
|
864
794
|
}
|
|
865
795
|
}
|
|
866
796
|
}
|
|
@@ -956,9 +886,6 @@ async function init(options = {}) {
|
|
|
956
886
|
if (project.hasPrisma) {
|
|
957
887
|
log("check", `Found ${project.prismaSchemaPath}`);
|
|
958
888
|
}
|
|
959
|
-
if (project.hasTailwind) {
|
|
960
|
-
log("check", `Found ${path6.basename(project.tailwindConfigPath)}`);
|
|
961
|
-
}
|
|
962
889
|
if (!project.appRouterPath) {
|
|
963
890
|
console.log(import_picocolors3.default.red("Error: Could not find App Router (app/ or src/app/ directory)"));
|
|
964
891
|
console.log("Autoblogger requires Next.js App Router.");
|
|
@@ -1000,10 +927,10 @@ Error: Found conflicting model names in your Prisma schema:`));
|
|
|
1000
927
|
console.log(` - ${prismaPath} (add 11 models)`);
|
|
1001
928
|
console.log(` - lib/cms.ts`);
|
|
1002
929
|
console.log(` - ${project.appRouterPath}/api/cms/[...path]/route.ts`);
|
|
1003
|
-
console.log(` - ${project.appRouterPath}/writer/[[...path]]/page.tsx`);
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
}
|
|
930
|
+
console.log(` - ${project.appRouterPath}/(writer)/writer/[[...path]]/page.tsx`);
|
|
931
|
+
console.log(` - ${project.appRouterPath}/(writer)/layout.tsx`);
|
|
932
|
+
console.log(` - globals.css (add CSS import)`);
|
|
933
|
+
console.log(` - ${project.appRouterPath}/layout.tsx (add suppressHydrationWarning)`);
|
|
1007
934
|
if (answers.runMigration) {
|
|
1008
935
|
console.log("\nWould run:");
|
|
1009
936
|
console.log(" - npx prisma migrate dev --name add-autoblogger");
|
|
@@ -1019,8 +946,7 @@ Would import ${count} posts from ${answers.importPath}`);
|
|
|
1019
946
|
}
|
|
1020
947
|
const filesToBackup = [];
|
|
1021
948
|
if (project.hasPrisma) filesToBackup.push("prisma/schema.prisma");
|
|
1022
|
-
if (
|
|
1023
|
-
if (fs7.existsSync(path6.join(cwd, "lib", "cms.ts"))) filesToBackup.push("lib/cms.ts");
|
|
949
|
+
if (fs6.existsSync(path6.join(cwd, "lib", "cms.ts"))) filesToBackup.push("lib/cms.ts");
|
|
1024
950
|
if (filesToBackup.length > 0) {
|
|
1025
951
|
const backupPath = createBackup(filesToBackup, cwd);
|
|
1026
952
|
log("backup", `Created backup at ${path6.relative(cwd, backupPath)}`);
|
|
@@ -1034,59 +960,44 @@ Would import ${count} posts from ${answers.importPath}`);
|
|
|
1034
960
|
log("write", `Updated ${path6.relative(cwd, prismaPath)} (added 11 models)`);
|
|
1035
961
|
const libDir = path6.join(cwd, "lib");
|
|
1036
962
|
const cmsConfigPath = path6.join(libDir, "cms.ts");
|
|
1037
|
-
if (
|
|
963
|
+
if (fs6.existsSync(cmsConfigPath)) {
|
|
1038
964
|
log("skip", "lib/cms.ts already exists");
|
|
1039
965
|
} else {
|
|
1040
|
-
if (!
|
|
1041
|
-
|
|
966
|
+
if (!fs6.existsSync(libDir)) {
|
|
967
|
+
fs6.mkdirSync(libDir, { recursive: true });
|
|
1042
968
|
}
|
|
1043
|
-
|
|
969
|
+
fs6.writeFileSync(cmsConfigPath, CMS_CONFIG_TEMPLATE);
|
|
1044
970
|
log("write", "Created lib/cms.ts");
|
|
1045
971
|
}
|
|
1046
972
|
const apiRoutePath = path6.join(cwd, project.appRouterPath, "api", "cms", "[...path]", "route.ts");
|
|
1047
|
-
if (
|
|
973
|
+
if (fs6.existsSync(apiRoutePath)) {
|
|
1048
974
|
log("skip", `${project.appRouterPath}/api/cms/[...path]/route.ts already exists`);
|
|
1049
975
|
} else {
|
|
1050
976
|
const apiRouteDir = path6.dirname(apiRoutePath);
|
|
1051
|
-
if (!
|
|
1052
|
-
|
|
977
|
+
if (!fs6.existsSync(apiRouteDir)) {
|
|
978
|
+
fs6.mkdirSync(apiRouteDir, { recursive: true });
|
|
1053
979
|
}
|
|
1054
|
-
|
|
980
|
+
fs6.writeFileSync(apiRoutePath, API_ROUTE_TEMPLATE);
|
|
1055
981
|
log("write", `Created ${project.appRouterPath}/api/cms/[...path]/route.ts`);
|
|
1056
982
|
}
|
|
1057
|
-
const
|
|
1058
|
-
|
|
1059
|
-
|
|
983
|
+
const writerRouteGroup = path6.join(cwd, project.appRouterPath, "(writer)");
|
|
984
|
+
const dashboardPath = path6.join(writerRouteGroup, "writer", "[[...path]]", "page.tsx");
|
|
985
|
+
const writerLayoutPath = path6.join(writerRouteGroup, "layout.tsx");
|
|
986
|
+
if (fs6.existsSync(dashboardPath)) {
|
|
987
|
+
log("skip", `${project.appRouterPath}/(writer)/writer/[[...path]]/page.tsx already exists`);
|
|
1060
988
|
} else {
|
|
1061
989
|
const dashboardDir = path6.dirname(dashboardPath);
|
|
1062
|
-
if (!
|
|
1063
|
-
|
|
990
|
+
if (!fs6.existsSync(dashboardDir)) {
|
|
991
|
+
fs6.mkdirSync(dashboardDir, { recursive: true });
|
|
1064
992
|
}
|
|
1065
|
-
|
|
1066
|
-
log("write", `Created ${project.appRouterPath}/writer/[[...path]]/page.tsx`);
|
|
993
|
+
fs6.writeFileSync(dashboardPath, DASHBOARD_PAGE_TEMPLATE);
|
|
994
|
+
log("write", `Created ${project.appRouterPath}/(writer)/writer/[[...path]]/page.tsx`);
|
|
1067
995
|
}
|
|
1068
|
-
if (
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
writeTailwindConfig(project.tailwindConfigPath, patchResult.content);
|
|
1074
|
-
log("write", `Updated ${path6.basename(project.tailwindConfigPath)}`);
|
|
1075
|
-
} else {
|
|
1076
|
-
log("warn", "Could not auto-patch Tailwind config. Please add manually:");
|
|
1077
|
-
console.log(import_picocolors3.default.gray(" content: ['./node_modules/autoblogger/dist/**/*.{js,mjs}']"));
|
|
1078
|
-
}
|
|
1079
|
-
} else if (project.tailwindCssPath) {
|
|
1080
|
-
const patchResult = patchTailwindCssConfig(project.tailwindCssPath);
|
|
1081
|
-
if (patchResult.alreadyPatched) {
|
|
1082
|
-
log("skip", "Tailwind CSS config already includes autoblogger");
|
|
1083
|
-
} else if (patchResult.success && patchResult.content) {
|
|
1084
|
-
writeTailwindConfig(project.tailwindCssPath, patchResult.content);
|
|
1085
|
-
log("write", `Updated ${path6.basename(project.tailwindCssPath)} (Tailwind v4)`);
|
|
1086
|
-
} else {
|
|
1087
|
-
log("warn", "Could not auto-patch Tailwind v4 CSS config. Please add manually:");
|
|
1088
|
-
console.log(import_picocolors3.default.gray(' @source "./node_modules/autoblogger/dist/**/*.{js,mjs}";'));
|
|
1089
|
-
}
|
|
996
|
+
if (fs6.existsSync(writerLayoutPath)) {
|
|
997
|
+
log("skip", `${project.appRouterPath}/(writer)/layout.tsx already exists`);
|
|
998
|
+
} else {
|
|
999
|
+
fs6.writeFileSync(writerLayoutPath, WRITER_LAYOUT_TEMPLATE);
|
|
1000
|
+
log("write", `Created ${project.appRouterPath}/(writer)/layout.tsx`);
|
|
1090
1001
|
}
|
|
1091
1002
|
const globalsCssPath = findGlobalsCss(cwd);
|
|
1092
1003
|
if (globalsCssPath) {
|
|
@@ -1098,7 +1009,26 @@ Would import ${count} posts from ${answers.importPath}`);
|
|
|
1098
1009
|
}
|
|
1099
1010
|
} else {
|
|
1100
1011
|
log("warn", "Could not find globals.css. Please add manually:");
|
|
1101
|
-
console.log(import_picocolors3.default.gray(" @import 'autoblogger/styles/
|
|
1012
|
+
console.log(import_picocolors3.default.gray(" @import 'autoblogger/styles/standalone.css';"));
|
|
1013
|
+
}
|
|
1014
|
+
const rootLayoutPath = path6.join(cwd, project.appRouterPath, "layout.tsx");
|
|
1015
|
+
if (fs6.existsSync(rootLayoutPath)) {
|
|
1016
|
+
let layoutContent = fs6.readFileSync(rootLayoutPath, "utf-8");
|
|
1017
|
+
if (layoutContent.includes("suppressHydrationWarning")) {
|
|
1018
|
+
log("skip", "Root layout already has suppressHydrationWarning");
|
|
1019
|
+
} else {
|
|
1020
|
+
const htmlTagRegex = /<html([^>]*)>/;
|
|
1021
|
+
const match = layoutContent.match(htmlTagRegex);
|
|
1022
|
+
if (match) {
|
|
1023
|
+
const existingAttrs = match[1];
|
|
1024
|
+
const newHtmlTag = `<html${existingAttrs} suppressHydrationWarning>`;
|
|
1025
|
+
layoutContent = layoutContent.replace(htmlTagRegex, newHtmlTag);
|
|
1026
|
+
fs6.writeFileSync(rootLayoutPath, layoutContent);
|
|
1027
|
+
log("write", `Updated ${project.appRouterPath}/layout.tsx (added suppressHydrationWarning)`);
|
|
1028
|
+
} else {
|
|
1029
|
+
log("warn", "Could not find <html> tag in root layout. Please add suppressHydrationWarning manually.");
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1102
1032
|
}
|
|
1103
1033
|
if (answers.runMigration) {
|
|
1104
1034
|
console.log("");
|
|
@@ -1135,7 +1065,7 @@ Would import ${count} posts from ${answers.importPath}`);
|
|
|
1135
1065
|
console.log("");
|
|
1136
1066
|
console.log(import_picocolors3.default.gray("Next steps:"));
|
|
1137
1067
|
console.log(import_picocolors3.default.gray(" 1. Update lib/cms.ts with your auth configuration"));
|
|
1138
|
-
console.log(import_picocolors3.default.gray(" 2. Add your auth check to app/writer/[[...path]]/page.tsx"));
|
|
1068
|
+
console.log(import_picocolors3.default.gray(" 2. Add your auth check to app/(writer)/writer/[[...path]]/page.tsx"));
|
|
1139
1069
|
console.log(import_picocolors3.default.gray(" 3. Set ANTHROPIC_API_KEY and/or OPENAI_API_KEY for AI features"));
|
|
1140
1070
|
console.log("");
|
|
1141
1071
|
}
|
package/dist/index.js
CHANGED
|
@@ -1328,7 +1328,7 @@ function createPostsData(prisma, hooks) {
|
|
|
1328
1328
|
return result;
|
|
1329
1329
|
},
|
|
1330
1330
|
async update(id, data) {
|
|
1331
|
-
const { tagIds, ...postData } = data;
|
|
1331
|
+
const { tagIds, tags, revisions, topic, ...postData } = data;
|
|
1332
1332
|
if (postData.status === "published") {
|
|
1333
1333
|
const existing = await prisma.post.findUnique({ where: { id } });
|
|
1334
1334
|
if (existing?.status !== "published") {
|