autoblogger 0.1.16 → 0.1.17
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 +50 -44
- package/dist/cli/index.js +94 -48
- package/dist/styles/article.d.mts +4 -4
- package/dist/styles/article.d.ts +4 -4
- package/dist/styles/article.js +4 -4
- package/dist/styles/article.js.map +1 -1
- package/dist/styles/article.mjs +4 -4
- package/dist/styles/article.mjs.map +1 -1
- package/dist/styles/autoblogger.css +165 -0
- package/dist/styles/preset.js +48 -8
- package/dist/ui.js +4 -4
- package/dist/ui.js.map +1 -1
- package/dist/ui.mjs +4 -4
- package/dist/ui.mjs.map +1 -1
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -313,68 +313,74 @@ The `[[...path]]` syntax is a catch-all route that captures the dashboard's inte
|
|
|
313
313
|
|
|
314
314
|
## Configuring Tailwind
|
|
315
315
|
|
|
316
|
-
Autoblogger's UI uses Tailwind CSS
|
|
316
|
+
Autoblogger's UI uses Tailwind CSS. Add the package's files to your Tailwind content configuration so the classes aren't purged:
|
|
317
317
|
|
|
318
318
|
```javascript
|
|
319
|
-
// tailwind.config.js
|
|
319
|
+
// tailwind.config.js
|
|
320
320
|
module.exports = {
|
|
321
|
+
presets: [require('autoblogger/styles/preset')],
|
|
321
322
|
content: [
|
|
322
323
|
'./app/**/*.{js,ts,jsx,tsx}',
|
|
323
324
|
'./components/**/*.{js,ts,jsx,tsx}',
|
|
324
325
|
// Add this line to include Autoblogger's components
|
|
325
326
|
'./node_modules/autoblogger/dist/**/*.{js,mjs}',
|
|
326
327
|
],
|
|
328
|
+
darkMode: 'class',
|
|
327
329
|
// ... rest of your config
|
|
328
330
|
}
|
|
329
331
|
```
|
|
330
332
|
|
|
331
|
-
The
|
|
333
|
+
The `autoblogger/styles/preset` includes:
|
|
334
|
+
- Typography scale (`text-title`, `text-h1`, `text-h2`, `text-h3`, `text-body`, `text-table`)
|
|
335
|
+
- Color tokens (`bg-background`, `text-muted-foreground`, `border-border`, etc.)
|
|
336
|
+
- Border radius utilities
|
|
337
|
+
|
|
338
|
+
---
|
|
339
|
+
|
|
340
|
+
## Styling
|
|
341
|
+
|
|
342
|
+
Autoblogger includes a complete theme with CSS variables, prose styles, and editor styling. Import it in your global CSS:
|
|
343
|
+
|
|
344
|
+
```css
|
|
345
|
+
/* app/globals.css */
|
|
346
|
+
@import 'autoblogger/styles/autoblogger.css';
|
|
347
|
+
|
|
348
|
+
@tailwind base;
|
|
349
|
+
@tailwind components;
|
|
350
|
+
@tailwind utilities;
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
This provides:
|
|
354
|
+
- **Light and dark mode colors** — shadcn/ui Zinc theme tokens
|
|
355
|
+
- **Typography scale** — Consistent heading and body sizes
|
|
356
|
+
- **Prose styles** — Article content formatting (headings, paragraphs, lists, code, blockquotes)
|
|
357
|
+
- **Editor styles** — Tiptap focus states and placeholder styling
|
|
358
|
+
- **Animations** — Fade-in effects with reduced motion support
|
|
359
|
+
|
|
360
|
+
### Customizing
|
|
361
|
+
|
|
362
|
+
Override any CSS variable after the import:
|
|
332
363
|
|
|
333
364
|
```css
|
|
334
|
-
|
|
365
|
+
@import 'autoblogger/styles/autoblogger.css';
|
|
366
|
+
|
|
335
367
|
:root {
|
|
336
|
-
--
|
|
337
|
-
--foreground: 0 0% 3.9%;
|
|
338
|
-
--card: 0 0% 100%;
|
|
339
|
-
--card-foreground: 0 0% 3.9%;
|
|
340
|
-
--popover: 0 0% 100%;
|
|
341
|
-
--popover-foreground: 0 0% 3.9%;
|
|
342
|
-
--primary: 0 0% 9%;
|
|
343
|
-
--primary-foreground: 0 0% 98%;
|
|
344
|
-
--secondary: 0 0% 96.1%;
|
|
345
|
-
--secondary-foreground: 0 0% 9%;
|
|
346
|
-
--muted: 0 0% 96.1%;
|
|
347
|
-
--muted-foreground: 0 0% 45.1%;
|
|
348
|
-
--accent: 0 0% 96.1%;
|
|
349
|
-
--accent-foreground: 0 0% 9%;
|
|
350
|
-
--destructive: 0 84.2% 60.2%;
|
|
351
|
-
--destructive-foreground: 0 0% 98%;
|
|
352
|
-
--border: 0 0% 89.8%;
|
|
353
|
-
--input: 0 0% 89.8%;
|
|
354
|
-
--ring: 0 0% 3.9%;
|
|
368
|
+
--primary: 221 83% 53%; /* Custom blue primary */
|
|
355
369
|
}
|
|
370
|
+
```
|
|
356
371
|
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
--muted-foreground: 0 0% 63.9%;
|
|
370
|
-
--accent: 0 0% 14.9%;
|
|
371
|
-
--accent-foreground: 0 0% 98%;
|
|
372
|
-
--destructive: 0 62.8% 30.6%;
|
|
373
|
-
--destructive-foreground: 0 0% 98%;
|
|
374
|
-
--border: 0 0% 14.9%;
|
|
375
|
-
--input: 0 0% 14.9%;
|
|
376
|
-
--ring: 0 0% 83.1%;
|
|
377
|
-
}
|
|
372
|
+
Or pass custom styles when creating the CMS:
|
|
373
|
+
|
|
374
|
+
```typescript
|
|
375
|
+
// lib/cms.ts
|
|
376
|
+
export const cms = createAutoblogger({
|
|
377
|
+
// ... other config
|
|
378
|
+
styles: {
|
|
379
|
+
container: 'max-w-3xl mx-auto px-8',
|
|
380
|
+
title: 'text-4xl font-serif',
|
|
381
|
+
prose: 'prose prose-lg dark:prose-invert',
|
|
382
|
+
},
|
|
383
|
+
})
|
|
378
384
|
```
|
|
379
385
|
|
|
380
386
|
---
|
package/dist/cli/index.js
CHANGED
|
@@ -24,8 +24,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
24
24
|
));
|
|
25
25
|
|
|
26
26
|
// src/cli/init.ts
|
|
27
|
-
var
|
|
28
|
-
var
|
|
27
|
+
var fs7 = __toESM(require("fs"));
|
|
28
|
+
var path6 = __toESM(require("path"));
|
|
29
29
|
var import_child_process2 = require("child_process");
|
|
30
30
|
var import_picocolors3 = __toESM(require("picocolors"));
|
|
31
31
|
|
|
@@ -468,6 +468,40 @@ function writeTailwindConfig(configPath, content) {
|
|
|
468
468
|
fs4.writeFileSync(configPath, content, "utf-8");
|
|
469
469
|
}
|
|
470
470
|
|
|
471
|
+
// src/cli/utils/css-patch.ts
|
|
472
|
+
var fs5 = __toESM(require("fs"));
|
|
473
|
+
var path4 = __toESM(require("path"));
|
|
474
|
+
var AUTOBLOGGER_CSS_IMPORT = "@import 'autoblogger/styles/autoblogger.css';";
|
|
475
|
+
function findGlobalsCss(projectRoot) {
|
|
476
|
+
const candidates = [
|
|
477
|
+
"app/globals.css",
|
|
478
|
+
"src/app/globals.css",
|
|
479
|
+
"styles/globals.css",
|
|
480
|
+
"src/styles/globals.css",
|
|
481
|
+
"app/global.css",
|
|
482
|
+
"src/app/global.css"
|
|
483
|
+
];
|
|
484
|
+
for (const candidate of candidates) {
|
|
485
|
+
const fullPath = path4.join(projectRoot, candidate);
|
|
486
|
+
if (fs5.existsSync(fullPath)) {
|
|
487
|
+
return fullPath;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
return null;
|
|
491
|
+
}
|
|
492
|
+
function patchGlobalsCss(cssPath) {
|
|
493
|
+
if (!fs5.existsSync(cssPath)) {
|
|
494
|
+
return { success: false, alreadyPatched: false };
|
|
495
|
+
}
|
|
496
|
+
let content = fs5.readFileSync(cssPath, "utf-8");
|
|
497
|
+
if (content.includes("autoblogger")) {
|
|
498
|
+
return { success: true, alreadyPatched: true, filePath: cssPath };
|
|
499
|
+
}
|
|
500
|
+
content = AUTOBLOGGER_CSS_IMPORT + "\n\n" + content;
|
|
501
|
+
fs5.writeFileSync(cssPath, content, "utf-8");
|
|
502
|
+
return { success: true, alreadyPatched: false, filePath: cssPath };
|
|
503
|
+
}
|
|
504
|
+
|
|
471
505
|
// src/cli/utils/prompts.ts
|
|
472
506
|
var import_prompts = __toESM(require("prompts"));
|
|
473
507
|
var import_picocolors = __toESM(require("picocolors"));
|
|
@@ -669,8 +703,8 @@ export default async function WriterPage({
|
|
|
669
703
|
`;
|
|
670
704
|
|
|
671
705
|
// src/cli/import.ts
|
|
672
|
-
var
|
|
673
|
-
var
|
|
706
|
+
var fs6 = __toESM(require("fs"));
|
|
707
|
+
var path5 = __toESM(require("path"));
|
|
674
708
|
var import_child_process = require("child_process");
|
|
675
709
|
var import_picocolors2 = __toESM(require("picocolors"));
|
|
676
710
|
function parseFrontmatter(content) {
|
|
@@ -734,14 +768,14 @@ function slugify(text) {
|
|
|
734
768
|
}
|
|
735
769
|
function parseMarkdownFile(filePath) {
|
|
736
770
|
try {
|
|
737
|
-
const content =
|
|
771
|
+
const content = fs6.readFileSync(filePath, "utf-8");
|
|
738
772
|
const { frontmatter, body } = parseFrontmatter(content);
|
|
739
773
|
let title = frontmatter.title;
|
|
740
774
|
if (!title) {
|
|
741
775
|
const headingMatch = body.match(/^#\s+(.+)$/m);
|
|
742
|
-
title = headingMatch ? headingMatch[1] :
|
|
776
|
+
title = headingMatch ? headingMatch[1] : path5.basename(filePath, path5.extname(filePath));
|
|
743
777
|
}
|
|
744
|
-
const slug = frontmatter.slug || slugify(
|
|
778
|
+
const slug = frontmatter.slug || slugify(path5.basename(filePath, path5.extname(filePath))) || slugify(title);
|
|
745
779
|
let publishedAt;
|
|
746
780
|
if (frontmatter.date) {
|
|
747
781
|
const parsed = new Date(frontmatter.date);
|
|
@@ -772,9 +806,9 @@ function parseMarkdownFile(filePath) {
|
|
|
772
806
|
function findMarkdownFiles(dir) {
|
|
773
807
|
const files = [];
|
|
774
808
|
function walk(currentDir) {
|
|
775
|
-
const entries =
|
|
809
|
+
const entries = fs6.readdirSync(currentDir, { withFileTypes: true });
|
|
776
810
|
for (const entry of entries) {
|
|
777
|
-
const fullPath =
|
|
811
|
+
const fullPath = path5.join(currentDir, entry.name);
|
|
778
812
|
if (entry.isDirectory()) {
|
|
779
813
|
if (!entry.name.startsWith(".") && entry.name !== "node_modules") {
|
|
780
814
|
walk(fullPath);
|
|
@@ -789,8 +823,8 @@ function findMarkdownFiles(dir) {
|
|
|
789
823
|
}
|
|
790
824
|
async function importContent(dirPath, options = {}) {
|
|
791
825
|
const cwd = process.cwd();
|
|
792
|
-
const absolutePath =
|
|
793
|
-
if (!
|
|
826
|
+
const absolutePath = path5.isAbsolute(dirPath) ? dirPath : path5.join(cwd, dirPath);
|
|
827
|
+
if (!fs6.existsSync(absolutePath)) {
|
|
794
828
|
throw new Error(`Directory not found: ${dirPath}`);
|
|
795
829
|
}
|
|
796
830
|
const files = findMarkdownFiles(absolutePath);
|
|
@@ -816,8 +850,8 @@ async function importContent(dirPath, options = {}) {
|
|
|
816
850
|
}
|
|
817
851
|
const status = options.status || "draft";
|
|
818
852
|
const importScript = generateImportScript(posts, status, options.tag);
|
|
819
|
-
const scriptPath =
|
|
820
|
-
|
|
853
|
+
const scriptPath = path5.join(cwd, ".autoblogger-import.mjs");
|
|
854
|
+
fs6.writeFileSync(scriptPath, importScript);
|
|
821
855
|
try {
|
|
822
856
|
(0, import_child_process.execSync)(`node ${scriptPath}`, {
|
|
823
857
|
cwd,
|
|
@@ -825,8 +859,8 @@ async function importContent(dirPath, options = {}) {
|
|
|
825
859
|
});
|
|
826
860
|
log("check", `Imported ${posts.length} posts as ${status}`);
|
|
827
861
|
} finally {
|
|
828
|
-
if (
|
|
829
|
-
|
|
862
|
+
if (fs6.existsSync(scriptPath)) {
|
|
863
|
+
fs6.unlinkSync(scriptPath);
|
|
830
864
|
}
|
|
831
865
|
}
|
|
832
866
|
}
|
|
@@ -923,7 +957,7 @@ async function init(options = {}) {
|
|
|
923
957
|
log("check", `Found ${project.prismaSchemaPath}`);
|
|
924
958
|
}
|
|
925
959
|
if (project.hasTailwind) {
|
|
926
|
-
log("check", `Found ${
|
|
960
|
+
log("check", `Found ${path6.basename(project.tailwindConfigPath)}`);
|
|
927
961
|
}
|
|
928
962
|
if (!project.appRouterPath) {
|
|
929
963
|
console.log(import_picocolors3.default.red("Error: Could not find App Router (app/ or src/app/ directory)"));
|
|
@@ -932,7 +966,7 @@ async function init(options = {}) {
|
|
|
932
966
|
}
|
|
933
967
|
const contentCounts = {};
|
|
934
968
|
for (const contentPath of project.contentPaths) {
|
|
935
|
-
contentCounts[contentPath] = countMarkdownFiles(
|
|
969
|
+
contentCounts[contentPath] = countMarkdownFiles(path6.join(cwd, contentPath));
|
|
936
970
|
}
|
|
937
971
|
let answers = {
|
|
938
972
|
dbProvider: "postgresql",
|
|
@@ -950,7 +984,7 @@ async function init(options = {}) {
|
|
|
950
984
|
answers.importContent = true;
|
|
951
985
|
answers.importPath = project.contentPaths[0];
|
|
952
986
|
}
|
|
953
|
-
const prismaPath = project.prismaSchemaPath ||
|
|
987
|
+
const prismaPath = project.prismaSchemaPath || path6.join(cwd, "prisma", "schema.prisma");
|
|
954
988
|
const conflicts = checkConflicts(prismaPath);
|
|
955
989
|
if (conflicts.length > 0) {
|
|
956
990
|
console.log(import_picocolors3.default.red(`
|
|
@@ -976,7 +1010,7 @@ Error: Found conflicting model names in your Prisma schema:`));
|
|
|
976
1010
|
console.log(" - npx prisma generate");
|
|
977
1011
|
}
|
|
978
1012
|
if (answers.importContent && answers.importPath) {
|
|
979
|
-
const count = contentCounts[answers.importPath] || countMarkdownFiles(
|
|
1013
|
+
const count = contentCounts[answers.importPath] || countMarkdownFiles(path6.join(cwd, answers.importPath));
|
|
980
1014
|
console.log(`
|
|
981
1015
|
Would import ${count} posts from ${answers.importPath}`);
|
|
982
1016
|
}
|
|
@@ -985,11 +1019,11 @@ Would import ${count} posts from ${answers.importPath}`);
|
|
|
985
1019
|
}
|
|
986
1020
|
const filesToBackup = [];
|
|
987
1021
|
if (project.hasPrisma) filesToBackup.push("prisma/schema.prisma");
|
|
988
|
-
if (project.tailwindConfigPath) filesToBackup.push(
|
|
989
|
-
if (
|
|
1022
|
+
if (project.tailwindConfigPath) filesToBackup.push(path6.relative(cwd, project.tailwindConfigPath));
|
|
1023
|
+
if (fs7.existsSync(path6.join(cwd, "lib", "cms.ts"))) filesToBackup.push("lib/cms.ts");
|
|
990
1024
|
if (filesToBackup.length > 0) {
|
|
991
1025
|
const backupPath = createBackup(filesToBackup, cwd);
|
|
992
|
-
log("backup", `Created backup at ${
|
|
1026
|
+
log("backup", `Created backup at ${path6.relative(cwd, backupPath)}`);
|
|
993
1027
|
}
|
|
994
1028
|
const mergeResult = mergeSchema(prismaPath, answers.dbProvider);
|
|
995
1029
|
if (!mergeResult.success) {
|
|
@@ -997,38 +1031,38 @@ Would import ${count} posts from ${answers.importPath}`);
|
|
|
997
1031
|
return;
|
|
998
1032
|
}
|
|
999
1033
|
writeSchema(prismaPath, mergeResult.content);
|
|
1000
|
-
log("write", `Updated ${
|
|
1001
|
-
const libDir =
|
|
1002
|
-
const cmsConfigPath =
|
|
1003
|
-
if (
|
|
1034
|
+
log("write", `Updated ${path6.relative(cwd, prismaPath)} (added 11 models)`);
|
|
1035
|
+
const libDir = path6.join(cwd, "lib");
|
|
1036
|
+
const cmsConfigPath = path6.join(libDir, "cms.ts");
|
|
1037
|
+
if (fs7.existsSync(cmsConfigPath)) {
|
|
1004
1038
|
log("skip", "lib/cms.ts already exists");
|
|
1005
1039
|
} else {
|
|
1006
|
-
if (!
|
|
1007
|
-
|
|
1040
|
+
if (!fs7.existsSync(libDir)) {
|
|
1041
|
+
fs7.mkdirSync(libDir, { recursive: true });
|
|
1008
1042
|
}
|
|
1009
|
-
|
|
1043
|
+
fs7.writeFileSync(cmsConfigPath, CMS_CONFIG_TEMPLATE);
|
|
1010
1044
|
log("write", "Created lib/cms.ts");
|
|
1011
1045
|
}
|
|
1012
|
-
const apiRoutePath =
|
|
1013
|
-
if (
|
|
1046
|
+
const apiRoutePath = path6.join(cwd, project.appRouterPath, "api", "cms", "[...path]", "route.ts");
|
|
1047
|
+
if (fs7.existsSync(apiRoutePath)) {
|
|
1014
1048
|
log("skip", `${project.appRouterPath}/api/cms/[...path]/route.ts already exists`);
|
|
1015
1049
|
} else {
|
|
1016
|
-
const apiRouteDir =
|
|
1017
|
-
if (!
|
|
1018
|
-
|
|
1050
|
+
const apiRouteDir = path6.dirname(apiRoutePath);
|
|
1051
|
+
if (!fs7.existsSync(apiRouteDir)) {
|
|
1052
|
+
fs7.mkdirSync(apiRouteDir, { recursive: true });
|
|
1019
1053
|
}
|
|
1020
|
-
|
|
1054
|
+
fs7.writeFileSync(apiRoutePath, API_ROUTE_TEMPLATE);
|
|
1021
1055
|
log("write", `Created ${project.appRouterPath}/api/cms/[...path]/route.ts`);
|
|
1022
1056
|
}
|
|
1023
|
-
const dashboardPath =
|
|
1024
|
-
if (
|
|
1057
|
+
const dashboardPath = path6.join(cwd, project.appRouterPath, "writer", "[[...path]]", "page.tsx");
|
|
1058
|
+
if (fs7.existsSync(dashboardPath)) {
|
|
1025
1059
|
log("skip", `${project.appRouterPath}/writer/[[...path]]/page.tsx already exists`);
|
|
1026
1060
|
} else {
|
|
1027
|
-
const dashboardDir =
|
|
1028
|
-
if (!
|
|
1029
|
-
|
|
1061
|
+
const dashboardDir = path6.dirname(dashboardPath);
|
|
1062
|
+
if (!fs7.existsSync(dashboardDir)) {
|
|
1063
|
+
fs7.mkdirSync(dashboardDir, { recursive: true });
|
|
1030
1064
|
}
|
|
1031
|
-
|
|
1065
|
+
fs7.writeFileSync(dashboardPath, DASHBOARD_PAGE_TEMPLATE);
|
|
1032
1066
|
log("write", `Created ${project.appRouterPath}/writer/[[...path]]/page.tsx`);
|
|
1033
1067
|
}
|
|
1034
1068
|
if (project.tailwindConfigPath) {
|
|
@@ -1037,7 +1071,7 @@ Would import ${count} posts from ${answers.importPath}`);
|
|
|
1037
1071
|
log("skip", "Tailwind config already includes autoblogger");
|
|
1038
1072
|
} else if (patchResult.success && patchResult.content) {
|
|
1039
1073
|
writeTailwindConfig(project.tailwindConfigPath, patchResult.content);
|
|
1040
|
-
log("write", `Updated ${
|
|
1074
|
+
log("write", `Updated ${path6.basename(project.tailwindConfigPath)}`);
|
|
1041
1075
|
} else {
|
|
1042
1076
|
log("warn", "Could not auto-patch Tailwind config. Please add manually:");
|
|
1043
1077
|
console.log(import_picocolors3.default.gray(" content: ['./node_modules/autoblogger/dist/**/*.{js,mjs}']"));
|
|
@@ -1048,12 +1082,24 @@ Would import ${count} posts from ${answers.importPath}`);
|
|
|
1048
1082
|
log("skip", "Tailwind CSS config already includes autoblogger");
|
|
1049
1083
|
} else if (patchResult.success && patchResult.content) {
|
|
1050
1084
|
writeTailwindConfig(project.tailwindCssPath, patchResult.content);
|
|
1051
|
-
log("write", `Updated ${
|
|
1085
|
+
log("write", `Updated ${path6.basename(project.tailwindCssPath)} (Tailwind v4)`);
|
|
1052
1086
|
} else {
|
|
1053
1087
|
log("warn", "Could not auto-patch Tailwind v4 CSS config. Please add manually:");
|
|
1054
1088
|
console.log(import_picocolors3.default.gray(' @source "./node_modules/autoblogger/dist/**/*.{js,mjs}";'));
|
|
1055
1089
|
}
|
|
1056
1090
|
}
|
|
1091
|
+
const globalsCssPath = findGlobalsCss(cwd);
|
|
1092
|
+
if (globalsCssPath) {
|
|
1093
|
+
const cssResult = patchGlobalsCss(globalsCssPath);
|
|
1094
|
+
if (cssResult.alreadyPatched) {
|
|
1095
|
+
log("skip", "globals.css already imports autoblogger styles");
|
|
1096
|
+
} else if (cssResult.success) {
|
|
1097
|
+
log("write", `Updated ${path6.relative(cwd, globalsCssPath)} (added autoblogger CSS import)`);
|
|
1098
|
+
}
|
|
1099
|
+
} else {
|
|
1100
|
+
log("warn", "Could not find globals.css. Please add manually:");
|
|
1101
|
+
console.log(import_picocolors3.default.gray(" @import 'autoblogger/styles/autoblogger.css';"));
|
|
1102
|
+
}
|
|
1057
1103
|
if (answers.runMigration) {
|
|
1058
1104
|
console.log("");
|
|
1059
1105
|
log("run", "prisma migrate dev --name add-autoblogger");
|
|
@@ -1075,10 +1121,10 @@ Would import ${count} posts from ${answers.importPath}`);
|
|
|
1075
1121
|
}
|
|
1076
1122
|
if (answers.importContent && answers.importPath) {
|
|
1077
1123
|
console.log("");
|
|
1078
|
-
const count = contentCounts[answers.importPath] || countMarkdownFiles(
|
|
1124
|
+
const count = contentCounts[answers.importPath] || countMarkdownFiles(path6.join(cwd, answers.importPath));
|
|
1079
1125
|
log("info", `Found ${count} markdown files in ${answers.importPath}`);
|
|
1080
1126
|
try {
|
|
1081
|
-
await importContent(
|
|
1127
|
+
await importContent(path6.join(cwd, answers.importPath), { status: "draft" });
|
|
1082
1128
|
} catch (error) {
|
|
1083
1129
|
log("warn", `Content import failed: ${error instanceof Error ? error.message : error}`);
|
|
1084
1130
|
console.log(import_picocolors3.default.gray(" You can import later with: npx autoblogger import <path>"));
|
|
@@ -1154,13 +1200,13 @@ async function main() {
|
|
|
1154
1200
|
dryRun: flags.dryRun
|
|
1155
1201
|
});
|
|
1156
1202
|
} else if (command === "import") {
|
|
1157
|
-
const
|
|
1158
|
-
if (!
|
|
1203
|
+
const path7 = args[1];
|
|
1204
|
+
if (!path7) {
|
|
1159
1205
|
console.error(import_picocolors4.default.red("Error: Please specify a path to import from"));
|
|
1160
1206
|
console.log("\nUsage: npx autoblogger import <path>");
|
|
1161
1207
|
process.exit(1);
|
|
1162
1208
|
}
|
|
1163
|
-
await importContent(
|
|
1209
|
+
await importContent(path7, {
|
|
1164
1210
|
status: flags.status || "draft",
|
|
1165
1211
|
tag: flags.tag,
|
|
1166
1212
|
dryRun: flags.dryRun
|
|
@@ -3,11 +3,11 @@ declare const ARTICLE_LAYOUT: {
|
|
|
3
3
|
readonly padding: 24;
|
|
4
4
|
};
|
|
5
5
|
declare const ARTICLE_CLASSES: {
|
|
6
|
-
readonly container: "max-w-
|
|
7
|
-
readonly title: "text-
|
|
8
|
-
readonly subtitle: "text-
|
|
6
|
+
readonly container: "max-w-[680px] mx-auto px-6";
|
|
7
|
+
readonly title: "text-title font-bold";
|
|
8
|
+
readonly subtitle: "text-h2 text-muted-foreground";
|
|
9
9
|
readonly byline: "text-sm text-muted-foreground";
|
|
10
|
-
readonly body: "text-
|
|
10
|
+
readonly body: "text-body prose dark:prose-invert";
|
|
11
11
|
readonly prose: "prose dark:prose-invert max-w-none";
|
|
12
12
|
};
|
|
13
13
|
type ArticleClasses = typeof ARTICLE_CLASSES;
|
package/dist/styles/article.d.ts
CHANGED
|
@@ -3,11 +3,11 @@ declare const ARTICLE_LAYOUT: {
|
|
|
3
3
|
readonly padding: 24;
|
|
4
4
|
};
|
|
5
5
|
declare const ARTICLE_CLASSES: {
|
|
6
|
-
readonly container: "max-w-
|
|
7
|
-
readonly title: "text-
|
|
8
|
-
readonly subtitle: "text-
|
|
6
|
+
readonly container: "max-w-[680px] mx-auto px-6";
|
|
7
|
+
readonly title: "text-title font-bold";
|
|
8
|
+
readonly subtitle: "text-h2 text-muted-foreground";
|
|
9
9
|
readonly byline: "text-sm text-muted-foreground";
|
|
10
|
-
readonly body: "text-
|
|
10
|
+
readonly body: "text-body prose dark:prose-invert";
|
|
11
11
|
readonly prose: "prose dark:prose-invert max-w-none";
|
|
12
12
|
};
|
|
13
13
|
type ArticleClasses = typeof ARTICLE_CLASSES;
|
package/dist/styles/article.js
CHANGED
|
@@ -29,11 +29,11 @@ var ARTICLE_LAYOUT = {
|
|
|
29
29
|
padding: 24
|
|
30
30
|
};
|
|
31
31
|
var ARTICLE_CLASSES = {
|
|
32
|
-
container: "max-w-
|
|
33
|
-
title: "text-
|
|
34
|
-
subtitle: "text-
|
|
32
|
+
container: "max-w-[680px] mx-auto px-6",
|
|
33
|
+
title: "text-title font-bold",
|
|
34
|
+
subtitle: "text-h2 text-muted-foreground",
|
|
35
35
|
byline: "text-sm text-muted-foreground",
|
|
36
|
-
body: "text-
|
|
36
|
+
body: "text-body prose dark:prose-invert",
|
|
37
37
|
prose: "prose dark:prose-invert max-w-none"
|
|
38
38
|
};
|
|
39
39
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/styles/article.ts"],"sourcesContent":["export const ARTICLE_LAYOUT = {\n maxWidth: 680,\n padding: 24,\n} as const\n\nexport const ARTICLE_CLASSES = {\n container: 'max-w-
|
|
1
|
+
{"version":3,"sources":["../../src/styles/article.ts"],"sourcesContent":["export const ARTICLE_LAYOUT = {\n maxWidth: 680,\n padding: 24,\n} as const\n\nexport const ARTICLE_CLASSES = {\n container: 'max-w-[680px] mx-auto px-6',\n title: 'text-title font-bold',\n subtitle: 'text-h2 text-muted-foreground',\n byline: 'text-sm text-muted-foreground',\n body: 'text-body prose dark:prose-invert',\n prose: 'prose dark:prose-invert max-w-none',\n} as const\n\nexport type ArticleClasses = typeof ARTICLE_CLASSES\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAO,IAAM,iBAAiB;AAAA,EAC5B,UAAU;AAAA,EACV,SAAS;AACX;AAEO,IAAM,kBAAkB;AAAA,EAC7B,WAAW;AAAA,EACX,OAAO;AAAA,EACP,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,OAAO;AACT;","names":[]}
|
package/dist/styles/article.mjs
CHANGED
|
@@ -4,11 +4,11 @@ var ARTICLE_LAYOUT = {
|
|
|
4
4
|
padding: 24
|
|
5
5
|
};
|
|
6
6
|
var ARTICLE_CLASSES = {
|
|
7
|
-
container: "max-w-
|
|
8
|
-
title: "text-
|
|
9
|
-
subtitle: "text-
|
|
7
|
+
container: "max-w-[680px] mx-auto px-6",
|
|
8
|
+
title: "text-title font-bold",
|
|
9
|
+
subtitle: "text-h2 text-muted-foreground",
|
|
10
10
|
byline: "text-sm text-muted-foreground",
|
|
11
|
-
body: "text-
|
|
11
|
+
body: "text-body prose dark:prose-invert",
|
|
12
12
|
prose: "prose dark:prose-invert max-w-none"
|
|
13
13
|
};
|
|
14
14
|
export {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/styles/article.ts"],"sourcesContent":["export const ARTICLE_LAYOUT = {\n maxWidth: 680,\n padding: 24,\n} as const\n\nexport const ARTICLE_CLASSES = {\n container: 'max-w-
|
|
1
|
+
{"version":3,"sources":["../../src/styles/article.ts"],"sourcesContent":["export const ARTICLE_LAYOUT = {\n maxWidth: 680,\n padding: 24,\n} as const\n\nexport const ARTICLE_CLASSES = {\n container: 'max-w-[680px] mx-auto px-6',\n title: 'text-title font-bold',\n subtitle: 'text-h2 text-muted-foreground',\n byline: 'text-sm text-muted-foreground',\n body: 'text-body prose dark:prose-invert',\n prose: 'prose dark:prose-invert max-w-none',\n} as const\n\nexport type ArticleClasses = typeof ARTICLE_CLASSES\n"],"mappings":";AAAO,IAAM,iBAAiB;AAAA,EAC5B,UAAU;AAAA,EACV,SAAS;AACX;AAEO,IAAM,kBAAkB;AAAA,EAC7B,WAAW;AAAA,EACX,OAAO;AAAA,EACP,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,OAAO;AACT;","names":[]}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Autoblogger Theme CSS (Isolated)
|
|
3
|
+
*
|
|
4
|
+
* All styles are scoped under .autoblogger container
|
|
5
|
+
* Variables are prefixed with --ab- to avoid conflicts
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/* ============================================
|
|
9
|
+
CSS VARIABLES (namespaced with --ab-)
|
|
10
|
+
============================================ */
|
|
11
|
+
|
|
12
|
+
:root {
|
|
13
|
+
--ab-background: 0 0% 100%;
|
|
14
|
+
--ab-foreground: 240 10% 3.9%;
|
|
15
|
+
--ab-card: 0 0% 100%;
|
|
16
|
+
--ab-card-foreground: 240 10% 3.9%;
|
|
17
|
+
--ab-popover: 0 0% 100%;
|
|
18
|
+
--ab-popover-foreground: 240 10% 3.9%;
|
|
19
|
+
--ab-primary: 240 5.9% 10%;
|
|
20
|
+
--ab-primary-foreground: 0 0% 98%;
|
|
21
|
+
--ab-secondary: 240 4.8% 95.9%;
|
|
22
|
+
--ab-secondary-foreground: 240 5.9% 10%;
|
|
23
|
+
--ab-muted: 240 4.8% 95.9%;
|
|
24
|
+
--ab-muted-foreground: 240 3.8% 46.1%;
|
|
25
|
+
--ab-accent: 240 4.8% 95.9%;
|
|
26
|
+
--ab-accent-foreground: 240 5.9% 10%;
|
|
27
|
+
--ab-destructive: 0 84.2% 60.2%;
|
|
28
|
+
--ab-destructive-foreground: 0 0% 98%;
|
|
29
|
+
--ab-border: 240 5.9% 90%;
|
|
30
|
+
--ab-input: 240 5.9% 90%;
|
|
31
|
+
--ab-ring: 240 10% 3.9%;
|
|
32
|
+
--ab-radius: 0.5rem;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.dark {
|
|
36
|
+
--ab-background: 240 10% 3.9%;
|
|
37
|
+
--ab-foreground: 0 0% 98%;
|
|
38
|
+
--ab-card: 240 10% 3.9%;
|
|
39
|
+
--ab-card-foreground: 0 0% 98%;
|
|
40
|
+
--ab-popover: 240 10% 3.9%;
|
|
41
|
+
--ab-popover-foreground: 0 0% 98%;
|
|
42
|
+
--ab-primary: 0 0% 98%;
|
|
43
|
+
--ab-primary-foreground: 240 5.9% 10%;
|
|
44
|
+
--ab-secondary: 240 3.7% 15.9%;
|
|
45
|
+
--ab-secondary-foreground: 0 0% 98%;
|
|
46
|
+
--ab-muted: 240 3.7% 15.9%;
|
|
47
|
+
--ab-muted-foreground: 240 5% 64.9%;
|
|
48
|
+
--ab-accent: 240 3.7% 15.9%;
|
|
49
|
+
--ab-accent-foreground: 0 0% 98%;
|
|
50
|
+
--ab-destructive: 0 62.8% 30.6%;
|
|
51
|
+
--ab-destructive-foreground: 0 0% 98%;
|
|
52
|
+
--ab-border: 240 3.7% 15.9%;
|
|
53
|
+
--ab-input: 240 3.7% 15.9%;
|
|
54
|
+
--ab-ring: 240 4.9% 83.9%;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/* Alias --ab-* to standard names for Tailwind compatibility */
|
|
58
|
+
.autoblogger {
|
|
59
|
+
--background: var(--ab-background);
|
|
60
|
+
--foreground: var(--ab-foreground);
|
|
61
|
+
--card: var(--ab-card);
|
|
62
|
+
--card-foreground: var(--ab-card-foreground);
|
|
63
|
+
--popover: var(--ab-popover);
|
|
64
|
+
--popover-foreground: var(--ab-popover-foreground);
|
|
65
|
+
--primary: var(--ab-primary);
|
|
66
|
+
--primary-foreground: var(--ab-primary-foreground);
|
|
67
|
+
--secondary: var(--ab-secondary);
|
|
68
|
+
--secondary-foreground: var(--ab-secondary-foreground);
|
|
69
|
+
--muted: var(--ab-muted);
|
|
70
|
+
--muted-foreground: var(--ab-muted-foreground);
|
|
71
|
+
--accent: var(--ab-accent);
|
|
72
|
+
--accent-foreground: var(--ab-accent-foreground);
|
|
73
|
+
--destructive: var(--ab-destructive);
|
|
74
|
+
--destructive-foreground: var(--ab-destructive-foreground);
|
|
75
|
+
--border: var(--ab-border);
|
|
76
|
+
--input: var(--ab-input);
|
|
77
|
+
--ring: var(--ab-ring);
|
|
78
|
+
--radius: var(--ab-radius);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/* ============================================
|
|
82
|
+
SCOPED BASE STYLES (only inside .autoblogger)
|
|
83
|
+
============================================ */
|
|
84
|
+
|
|
85
|
+
.autoblogger {
|
|
86
|
+
background-color: hsl(var(--background));
|
|
87
|
+
color: hsl(var(--foreground));
|
|
88
|
+
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
89
|
+
-webkit-font-smoothing: antialiased;
|
|
90
|
+
-moz-osx-font-smoothing: grayscale;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.autoblogger *, .autoblogger *::before, .autoblogger *::after {
|
|
94
|
+
border-color: hsl(var(--border));
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.autoblogger * {
|
|
98
|
+
transition-property: background-color, border-color;
|
|
99
|
+
transition-duration: 150ms;
|
|
100
|
+
transition-timing-function: ease-out;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.autoblogger a, .autoblogger button {
|
|
104
|
+
touch-action: manipulation;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/* ============================================
|
|
108
|
+
ANIMATIONS
|
|
109
|
+
============================================ */
|
|
110
|
+
|
|
111
|
+
@keyframes ab-fadeInUp {
|
|
112
|
+
from { opacity: 0; transform: translateY(12px); }
|
|
113
|
+
to { opacity: 1; transform: translateY(0); }
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.autoblogger .animate-fade-in-up {
|
|
117
|
+
opacity: 0;
|
|
118
|
+
animation: ab-fadeInUp 0.5s ease-out forwards;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
@media (prefers-reduced-motion: reduce) {
|
|
122
|
+
.autoblogger .animate-fade-in-up {
|
|
123
|
+
animation: none;
|
|
124
|
+
opacity: 1;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/* ============================================
|
|
129
|
+
PROSE STYLES (scoped)
|
|
130
|
+
============================================ */
|
|
131
|
+
|
|
132
|
+
.autoblogger .prose { max-width: none; }
|
|
133
|
+
.autoblogger .prose h1 { font-size: 22px; line-height: 1.3; font-weight: 700; margin-bottom: 1.5rem; }
|
|
134
|
+
.autoblogger .prose h2 { font-size: 18px; line-height: 1.4; font-weight: 700; margin-top: 2rem; margin-bottom: 1rem; }
|
|
135
|
+
.autoblogger .prose h3 { font-size: 16px; line-height: 1.4; font-weight: 700; margin-top: 1.5rem; margin-bottom: 0.75rem; }
|
|
136
|
+
.autoblogger .prose p { margin-bottom: 1rem; line-height: 1.625; }
|
|
137
|
+
.autoblogger .prose ul, .autoblogger .prose ol { margin-bottom: 1rem; padding-left: 1.5rem; }
|
|
138
|
+
.autoblogger .prose li { margin-bottom: 0.5rem; }
|
|
139
|
+
.autoblogger .prose ul li { list-style-type: disc; }
|
|
140
|
+
.autoblogger .prose ol li { list-style-type: decimal; }
|
|
141
|
+
.autoblogger .prose a { color: #2563eb; text-decoration: underline; }
|
|
142
|
+
.dark .autoblogger .prose a { color: #60a5fa; }
|
|
143
|
+
.autoblogger .prose code { background-color: hsl(var(--muted)); padding: 0.125rem 0.375rem; border-radius: 0.25rem; font-size: 0.875rem; }
|
|
144
|
+
.autoblogger .prose pre { background-color: hsl(var(--muted)); padding: 1rem; border-radius: 0.5rem; overflow-x: auto; margin-bottom: 1rem; }
|
|
145
|
+
.autoblogger .prose pre code { background-color: transparent; padding: 0; }
|
|
146
|
+
.autoblogger .prose blockquote { border-left: 4px solid hsl(var(--border)); padding-left: 1rem; font-style: italic; margin: 1rem 0; }
|
|
147
|
+
.autoblogger .prose img { border-radius: 0.5rem; margin: 1rem 0; }
|
|
148
|
+
.autoblogger .prose hr { margin: 2rem 0; border-color: hsl(var(--border)); }
|
|
149
|
+
|
|
150
|
+
/* ============================================
|
|
151
|
+
TIPTAP EDITOR STYLES (scoped)
|
|
152
|
+
============================================ */
|
|
153
|
+
|
|
154
|
+
.autoblogger .ProseMirror:focus { outline: none; }
|
|
155
|
+
.autoblogger .ProseMirror p.is-editor-empty:first-child::before {
|
|
156
|
+
content: attr(data-placeholder);
|
|
157
|
+
color: #d1d5db;
|
|
158
|
+
pointer-events: none;
|
|
159
|
+
float: left;
|
|
160
|
+
height: 0;
|
|
161
|
+
}
|
|
162
|
+
.dark .autoblogger .ProseMirror p.is-editor-empty:first-child::before { color: #374151; }
|
|
163
|
+
.autoblogger .ProseMirror h1 { font-size: 22px; line-height: 1.3; }
|
|
164
|
+
.autoblogger .ProseMirror h2 { font-size: 18px; line-height: 1.4; }
|
|
165
|
+
.autoblogger .ProseMirror h3 { font-size: 16px; line-height: 1.4; }
|