@bearplex-technologies/cli 0.1.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/config.d.ts +19 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +17 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +150 -0
- package/dist/index.js.map +1 -0
- package/dist/push.d.ts +11 -0
- package/dist/push.d.ts.map +1 -0
- package/dist/push.js +70 -0
- package/dist/push.js.map +1 -0
- package/dist/scan.d.ts +8 -0
- package/dist/scan.d.ts.map +1 -0
- package/dist/scan.js +207 -0
- package/dist/scan.js.map +1 -0
- package/package.json +43 -0
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface ContentField {
|
|
2
|
+
key: string;
|
|
3
|
+
label: string;
|
|
4
|
+
type: "text" | "markdown" | "image" | "link" | "email" | "phone";
|
|
5
|
+
value: string;
|
|
6
|
+
charLimit?: number;
|
|
7
|
+
imageHint?: string;
|
|
8
|
+
sortOrder: number;
|
|
9
|
+
}
|
|
10
|
+
export interface ContentManifest {
|
|
11
|
+
siteId: string;
|
|
12
|
+
apiUrl: string;
|
|
13
|
+
apiKey: string;
|
|
14
|
+
pages: Record<string, ContentField[]>;
|
|
15
|
+
}
|
|
16
|
+
export declare const CONFIG_FILE = "bearplex.content.json";
|
|
17
|
+
export declare function loadManifest(dir: string): Promise<ContentManifest | null>;
|
|
18
|
+
export declare function saveManifest(dir: string, manifest: ContentManifest): Promise<string>;
|
|
19
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;IACjE,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC;CACvC;AAED,eAAO,MAAM,WAAW,0BAA0B,CAAC;AAEnD,wBAAsB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAK/E;AAED,wBAAsB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAI1F"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { resolve } from "node:path";
|
|
4
|
+
export const CONFIG_FILE = "bearplex.content.json";
|
|
5
|
+
export async function loadManifest(dir) {
|
|
6
|
+
const path = resolve(dir, CONFIG_FILE);
|
|
7
|
+
if (!existsSync(path))
|
|
8
|
+
return null;
|
|
9
|
+
const raw = await readFile(path, "utf-8");
|
|
10
|
+
return JSON.parse(raw);
|
|
11
|
+
}
|
|
12
|
+
export async function saveManifest(dir, manifest) {
|
|
13
|
+
const path = resolve(dir, CONFIG_FILE);
|
|
14
|
+
await writeFile(path, JSON.stringify(manifest, null, 2) + "\n", "utf-8");
|
|
15
|
+
return path;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAmBpC,MAAM,CAAC,MAAM,WAAW,GAAG,uBAAuB,CAAC;AAEnD,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,GAAW;IAC5C,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;IACvC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACnC,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC1C,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAoB,CAAC;AAC5C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,GAAW,EAAE,QAAyB;IACvE,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;IACvC,MAAM,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;IACzE,OAAO,IAAI,CAAC;AACd,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from "commander";
|
|
3
|
+
import { resolve } from "node:path";
|
|
4
|
+
import { writeFile } from "node:fs/promises";
|
|
5
|
+
import { scanProject } from "./scan.js";
|
|
6
|
+
import { pushToAPI, pullFromAPI } from "./push.js";
|
|
7
|
+
import { loadManifest, saveManifest, CONFIG_FILE } from "./config.js";
|
|
8
|
+
const program = new Command();
|
|
9
|
+
program
|
|
10
|
+
.name("bearplex")
|
|
11
|
+
.description("BearPlex CMS CLI — scan websites, sync content fields")
|
|
12
|
+
.version("0.1.0");
|
|
13
|
+
// ── scan ──────────────────────────────────────────────
|
|
14
|
+
program
|
|
15
|
+
.command("scan")
|
|
16
|
+
.description("Scan a Next.js project and extract content into a manifest")
|
|
17
|
+
.argument("[dir]", "Source directory to scan (default: ./src)", "./src")
|
|
18
|
+
.option("-o, --output <path>", "Output manifest file", CONFIG_FILE)
|
|
19
|
+
.option("--site-id <id>", "Site ID for the manifest")
|
|
20
|
+
.option("--api-url <url>", "CMS API URL", "https://cms.oduscloud.com")
|
|
21
|
+
.option("--api-key <key>", "CMS API key")
|
|
22
|
+
.action(async (dir, opts) => {
|
|
23
|
+
const srcDir = resolve(process.cwd(), dir);
|
|
24
|
+
console.log(`\n Scanning ${srcDir}...\n`);
|
|
25
|
+
const result = await scanProject(srcDir);
|
|
26
|
+
console.log(` Found ${result.totalFields} content fields across ${result.filesScanned} files.\n`);
|
|
27
|
+
if (result.totalFields === 0) {
|
|
28
|
+
console.log(" No content fields detected. Try scanning a different directory.\n");
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
// Show summary
|
|
32
|
+
for (const [page, fields] of Object.entries(result.pages)) {
|
|
33
|
+
console.log(` Page: ${page} (${fields.length} fields)`);
|
|
34
|
+
for (const field of fields.slice(0, 5)) {
|
|
35
|
+
const preview = field.value.slice(0, 60).replace(/\n/g, " ");
|
|
36
|
+
console.log(` ${field.type.padEnd(8)} ${field.key.padEnd(30)} "${preview}${field.value.length > 60 ? "..." : ""}"`);
|
|
37
|
+
}
|
|
38
|
+
if (fields.length > 5) {
|
|
39
|
+
console.log(` ... and ${fields.length - 5} more`);
|
|
40
|
+
}
|
|
41
|
+
console.log();
|
|
42
|
+
}
|
|
43
|
+
const manifest = {
|
|
44
|
+
siteId: opts.siteId || "YOUR_SITE_ID",
|
|
45
|
+
apiUrl: opts.apiUrl,
|
|
46
|
+
apiKey: opts.apiKey || "YOUR_API_KEY",
|
|
47
|
+
pages: result.pages,
|
|
48
|
+
};
|
|
49
|
+
const outPath = await saveManifest(process.cwd(), manifest);
|
|
50
|
+
console.log(` Manifest saved to ${outPath}`);
|
|
51
|
+
console.log(` Review the file, then run: bearplex push\n`);
|
|
52
|
+
});
|
|
53
|
+
// ── init ──────────────────────────────────────────────
|
|
54
|
+
program
|
|
55
|
+
.command("init")
|
|
56
|
+
.description("Create a blank content manifest")
|
|
57
|
+
.option("--site-id <id>", "Site ID")
|
|
58
|
+
.option("--api-url <url>", "CMS API URL", "https://cms.oduscloud.com")
|
|
59
|
+
.option("--api-key <key>", "CMS API key")
|
|
60
|
+
.action(async (opts) => {
|
|
61
|
+
const manifest = {
|
|
62
|
+
siteId: opts.siteId || "YOUR_SITE_ID",
|
|
63
|
+
apiUrl: opts.apiUrl,
|
|
64
|
+
apiKey: opts.apiKey || "YOUR_API_KEY",
|
|
65
|
+
pages: {
|
|
66
|
+
home: [
|
|
67
|
+
{ key: "hero_title", label: "Hero Title", type: "text", value: "", sortOrder: 0 },
|
|
68
|
+
{ key: "hero_subtitle", label: "Hero Subtitle", type: "text", value: "", sortOrder: 1 },
|
|
69
|
+
],
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
const outPath = await saveManifest(process.cwd(), manifest);
|
|
73
|
+
console.log(`\n Created ${outPath}`);
|
|
74
|
+
console.log(` Edit the file with your content fields, then run: bearplex push\n`);
|
|
75
|
+
});
|
|
76
|
+
// ── push ──────────────────────────────────────────────
|
|
77
|
+
program
|
|
78
|
+
.command("push")
|
|
79
|
+
.description("Push content fields from the manifest to the CMS")
|
|
80
|
+
.option("-f, --file <path>", "Manifest file", CONFIG_FILE)
|
|
81
|
+
.option("--dry-run", "Show what would be created without making API calls")
|
|
82
|
+
.action(async (opts) => {
|
|
83
|
+
const manifest = await loadManifest(process.cwd());
|
|
84
|
+
if (!manifest) {
|
|
85
|
+
console.error(`\n No ${CONFIG_FILE} found. Run 'bearplex scan' or 'bearplex init' first.\n`);
|
|
86
|
+
process.exit(1);
|
|
87
|
+
}
|
|
88
|
+
if (manifest.siteId === "YOUR_SITE_ID" || manifest.apiKey === "YOUR_API_KEY") {
|
|
89
|
+
console.error("\n Update siteId and apiKey in the manifest before pushing.\n");
|
|
90
|
+
process.exit(1);
|
|
91
|
+
}
|
|
92
|
+
const totalFields = Object.values(manifest.pages).reduce((sum, fields) => sum + fields.length, 0);
|
|
93
|
+
console.log(`\n Pushing ${totalFields} fields to ${manifest.apiUrl}...\n`);
|
|
94
|
+
if (opts.dryRun) {
|
|
95
|
+
for (const [page, fields] of Object.entries(manifest.pages)) {
|
|
96
|
+
console.log(` Page: ${page}`);
|
|
97
|
+
for (const field of fields) {
|
|
98
|
+
console.log(` CREATE ${field.key} (${field.type})`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
console.log("\n Dry run complete. No changes made.\n");
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
const result = await pushToAPI(manifest);
|
|
105
|
+
console.log(` Created: ${result.created}`);
|
|
106
|
+
if (result.updated > 0)
|
|
107
|
+
console.log(` Updated: ${result.updated}`);
|
|
108
|
+
console.log(` Skipped (already exist): ${result.skipped}`);
|
|
109
|
+
if (result.errors.length > 0) {
|
|
110
|
+
console.log(` Errors: ${result.errors.length}`);
|
|
111
|
+
for (const err of result.errors) {
|
|
112
|
+
console.log(` - ${err}`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
console.log();
|
|
116
|
+
});
|
|
117
|
+
// ── pull ──────────────────────────────────────────────
|
|
118
|
+
program
|
|
119
|
+
.command("pull")
|
|
120
|
+
.description("Pull current CMS content into a local JSON file for fallback data")
|
|
121
|
+
.option("--api-url <url>", "CMS API URL")
|
|
122
|
+
.option("--api-key <key>", "CMS API key")
|
|
123
|
+
.option("--site-id <id>", "Site ID")
|
|
124
|
+
.option("-o, --output <path>", "Output file", "cms-content.json")
|
|
125
|
+
.action(async (opts) => {
|
|
126
|
+
// Try loading from manifest for defaults
|
|
127
|
+
const manifest = await loadManifest(process.cwd());
|
|
128
|
+
const apiUrl = opts.apiUrl || manifest?.apiUrl;
|
|
129
|
+
const apiKey = opts.apiKey || manifest?.apiKey;
|
|
130
|
+
const siteId = opts.siteId || manifest?.siteId;
|
|
131
|
+
if (!apiUrl || !apiKey || !siteId) {
|
|
132
|
+
console.error("\n Provide --api-url, --api-key, --site-id or create a manifest first.\n");
|
|
133
|
+
process.exit(1);
|
|
134
|
+
}
|
|
135
|
+
console.log(`\n Pulling content from ${apiUrl}...\n`);
|
|
136
|
+
try {
|
|
137
|
+
const content = await pullFromAPI(apiUrl, apiKey, siteId);
|
|
138
|
+
const outPath = resolve(process.cwd(), opts.output);
|
|
139
|
+
await writeFile(outPath, JSON.stringify(content, null, 2) + "\n", "utf-8");
|
|
140
|
+
const totalFields = Object.values(content).reduce((sum, page) => sum + Object.keys(page).length, 0);
|
|
141
|
+
console.log(` Pulled ${totalFields} fields across ${Object.keys(content).length} pages.`);
|
|
142
|
+
console.log(` Saved to ${outPath}\n`);
|
|
143
|
+
}
|
|
144
|
+
catch (e) {
|
|
145
|
+
console.error(` Error: ${e instanceof Error ? e.message : "Unknown error"}\n`);
|
|
146
|
+
process.exit(1);
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
program.parse();
|
|
150
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAGtE,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,UAAU,CAAC;KAChB,WAAW,CAAC,uDAAuD,CAAC;KACpE,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,yDAAyD;AACzD,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,4DAA4D,CAAC;KACzE,QAAQ,CAAC,OAAO,EAAE,2CAA2C,EAAE,OAAO,CAAC;KACvE,MAAM,CAAC,qBAAqB,EAAE,sBAAsB,EAAE,WAAW,CAAC;KAClE,MAAM,CAAC,gBAAgB,EAAE,0BAA0B,CAAC;KACpD,MAAM,CAAC,iBAAiB,EAAE,aAAa,EAAE,2BAA2B,CAAC;KACrE,MAAM,CAAC,iBAAiB,EAAE,aAAa,CAAC;KACxC,MAAM,CAAC,KAAK,EAAE,GAAW,EAAE,IAA0E,EAAE,EAAE;IACxG,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,GAAG,CAAC,CAAC;IAC3C,OAAO,CAAC,GAAG,CAAC,gBAAgB,MAAM,OAAO,CAAC,CAAC;IAE3C,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,MAAM,CAAC,CAAC;IAEzC,OAAO,CAAC,GAAG,CAAC,WAAW,MAAM,CAAC,WAAW,0BAA0B,MAAM,CAAC,YAAY,WAAW,CAAC,CAAC;IAEnG,IAAI,MAAM,CAAC,WAAW,KAAK,CAAC,EAAE,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,qEAAqE,CAAC,CAAC;QACnF,OAAO;IACT,CAAC;IAED,eAAe;IACf,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1D,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,KAAK,MAAM,CAAC,MAAM,UAAU,CAAC,CAAC;QACzD,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;YACvC,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;YAC7D,OAAO,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QACzH,CAAC;QACD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,OAAO,CAAC,GAAG,CAAC,eAAe,MAAM,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,CAAC;QACvD,CAAC;QACD,OAAO,CAAC,GAAG,EAAE,CAAC;IAChB,CAAC;IAED,MAAM,QAAQ,GAAoB;QAChC,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,cAAc;QACrC,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,cAAc;QACrC,KAAK,EAAE,MAAM,CAAC,KAAK;KACpB,CAAC;IAEF,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,CAAC,CAAC;IAC5D,OAAO,CAAC,GAAG,CAAC,uBAAuB,OAAO,EAAE,CAAC,CAAC;IAC9C,OAAO,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC;AAC9D,CAAC,CAAC,CAAC;AAEL,yDAAyD;AACzD,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,iCAAiC,CAAC;KAC9C,MAAM,CAAC,gBAAgB,EAAE,SAAS,CAAC;KACnC,MAAM,CAAC,iBAAiB,EAAE,aAAa,EAAE,2BAA2B,CAAC;KACrE,MAAM,CAAC,iBAAiB,EAAE,aAAa,CAAC;KACxC,MAAM,CAAC,KAAK,EAAE,IAA0D,EAAE,EAAE;IAC3E,MAAM,QAAQ,GAAoB;QAChC,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,cAAc;QACrC,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,cAAc;QACrC,KAAK,EAAE;YACL,IAAI,EAAE;gBACJ,EAAE,GAAG,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE;gBACjF,EAAE,GAAG,EAAE,eAAe,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE;aACxF;SACF;KACF,CAAC;IAEF,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,CAAC,CAAC;IAC5D,OAAO,CAAC,GAAG,CAAC,eAAe,OAAO,EAAE,CAAC,CAAC;IACtC,OAAO,CAAC,GAAG,CAAC,qEAAqE,CAAC,CAAC;AACrF,CAAC,CAAC,CAAC;AAEL,yDAAyD;AACzD,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,kDAAkD,CAAC;KAC/D,MAAM,CAAC,mBAAmB,EAAE,eAAe,EAAE,WAAW,CAAC;KACzD,MAAM,CAAC,WAAW,EAAE,qDAAqD,CAAC;KAC1E,MAAM,CAAC,KAAK,EAAE,IAAwC,EAAE,EAAE;IACzD,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IACnD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,CAAC,KAAK,CAAC,UAAU,WAAW,yDAAyD,CAAC,CAAC;QAC9F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,KAAK,cAAc,IAAI,QAAQ,CAAC,MAAM,KAAK,cAAc,EAAE,CAAC;QAC7E,OAAO,CAAC,KAAK,CAAC,gEAAgE,CAAC,CAAC;QAChF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,CAAC,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAClG,OAAO,CAAC,GAAG,CAAC,eAAe,WAAW,cAAc,QAAQ,CAAC,MAAM,OAAO,CAAC,CAAC;IAE5E,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5D,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC;YAC/B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,OAAO,CAAC,GAAG,CAAC,eAAe,KAAK,CAAC,GAAG,KAAK,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC;YAC1D,CAAC;QACH,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;QACxD,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,CAAC;IAEzC,OAAO,CAAC,GAAG,CAAC,cAAc,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;IAC5C,IAAI,MAAM,CAAC,OAAO,GAAG,CAAC;QAAE,OAAO,CAAC,GAAG,CAAC,cAAc,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;IACpE,OAAO,CAAC,GAAG,CAAC,8BAA8B,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;IAC5D,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,aAAa,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QACjD,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAChC,OAAO,CAAC,GAAG,CAAC,SAAS,GAAG,EAAE,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;IACD,OAAO,CAAC,GAAG,EAAE,CAAC;AAChB,CAAC,CAAC,CAAC;AAEL,yDAAyD;AACzD,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,mEAAmE,CAAC;KAChF,MAAM,CAAC,iBAAiB,EAAE,aAAa,CAAC;KACxC,MAAM,CAAC,iBAAiB,EAAE,aAAa,CAAC;KACxC,MAAM,CAAC,gBAAgB,EAAE,SAAS,CAAC;KACnC,MAAM,CAAC,qBAAqB,EAAE,aAAa,EAAE,kBAAkB,CAAC;KAChE,MAAM,CAAC,KAAK,EAAE,IAA2E,EAAE,EAAE;IAC5F,yCAAyC;IACzC,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IACnD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,QAAQ,EAAE,MAAM,CAAC;IAC/C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,QAAQ,EAAE,MAAM,CAAC;IAC/C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,QAAQ,EAAE,MAAM,CAAC;IAE/C,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;QAClC,OAAO,CAAC,KAAK,CAAC,2EAA2E,CAAC,CAAC;QAC3F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,4BAA4B,MAAM,OAAO,CAAC,CAAC;IAEvD,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QAC1D,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QACpD,MAAM,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;QAE3E,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QACpG,OAAO,CAAC,GAAG,CAAC,YAAY,WAAW,kBAAkB,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,SAAS,CAAC,CAAC;QAC3F,OAAO,CAAC,GAAG,CAAC,cAAc,OAAO,IAAI,CAAC,CAAC;IACzC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,IAAI,CAAC,CAAC;QAChF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
package/dist/push.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ContentManifest } from "./config.js";
|
|
2
|
+
interface PushResult {
|
|
3
|
+
created: number;
|
|
4
|
+
updated: number;
|
|
5
|
+
skipped: number;
|
|
6
|
+
errors: string[];
|
|
7
|
+
}
|
|
8
|
+
export declare function pushToAPI(manifest: ContentManifest): Promise<PushResult>;
|
|
9
|
+
export declare function pullFromAPI(apiUrl: string, apiKey: string, siteId: string): Promise<Record<string, Record<string, string>>>;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=push.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"push.d.ts","sourceRoot":"","sources":["../src/push.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,UAAU,UAAU;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,wBAAsB,SAAS,CAAC,QAAQ,EAAE,eAAe,GAAG,OAAO,CAAC,UAAU,CAAC,CAoD9E;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAkBjI"}
|
package/dist/push.js
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
export async function pushToAPI(manifest) {
|
|
2
|
+
const { siteId, apiUrl, apiKey } = manifest;
|
|
3
|
+
const result = { created: 0, updated: 0, skipped: 0, errors: [] };
|
|
4
|
+
// We use the admin API (POST /api/content) which requires session auth.
|
|
5
|
+
// For CLI usage, we'll use a direct API approach with the API key.
|
|
6
|
+
// The v1 API is read-only, so we need to use admin endpoints.
|
|
7
|
+
// For now, we'll use a dedicated CLI endpoint or the admin POST with a bearer token.
|
|
8
|
+
for (const [page, fields] of Object.entries(manifest.pages)) {
|
|
9
|
+
for (const field of fields) {
|
|
10
|
+
try {
|
|
11
|
+
const res = await fetch(`${apiUrl}/api/cli/content`, {
|
|
12
|
+
method: "POST",
|
|
13
|
+
headers: {
|
|
14
|
+
"Content-Type": "application/json",
|
|
15
|
+
Authorization: `Bearer ${apiKey}`,
|
|
16
|
+
},
|
|
17
|
+
body: JSON.stringify({
|
|
18
|
+
siteId,
|
|
19
|
+
page,
|
|
20
|
+
key: field.key,
|
|
21
|
+
label: field.label,
|
|
22
|
+
type: field.type,
|
|
23
|
+
charLimit: field.charLimit,
|
|
24
|
+
imageHint: field.imageHint,
|
|
25
|
+
sortOrder: field.sortOrder,
|
|
26
|
+
value: field.value,
|
|
27
|
+
}),
|
|
28
|
+
});
|
|
29
|
+
if (res.ok) {
|
|
30
|
+
const body = (await res.json());
|
|
31
|
+
if (body.updated) {
|
|
32
|
+
result.updated++;
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
result.created++;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
else if (res.status === 409) {
|
|
39
|
+
// Field already exists
|
|
40
|
+
result.skipped++;
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
const data = (await res.json().catch(() => ({ error: res.statusText })));
|
|
44
|
+
result.errors.push(`${page}.${field.key}: ${data.error || res.statusText}`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch (e) {
|
|
48
|
+
result.errors.push(`${page}.${field.key}: ${e instanceof Error ? e.message : "Network error"}`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return result;
|
|
53
|
+
}
|
|
54
|
+
export async function pullFromAPI(apiUrl, apiKey, siteId) {
|
|
55
|
+
const res = await fetch(`${apiUrl}/api/v1/content?siteId=${siteId}`, {
|
|
56
|
+
headers: { Authorization: `Bearer ${apiKey}` },
|
|
57
|
+
});
|
|
58
|
+
if (!res.ok) {
|
|
59
|
+
throw new Error(`Failed to pull content: ${res.statusText}`);
|
|
60
|
+
}
|
|
61
|
+
const items = (await res.json());
|
|
62
|
+
const pages = {};
|
|
63
|
+
for (const item of items) {
|
|
64
|
+
if (!pages[item.page])
|
|
65
|
+
pages[item.page] = {};
|
|
66
|
+
pages[item.page][`${item.page}.${item.key}`] = item.value ?? "";
|
|
67
|
+
}
|
|
68
|
+
return pages;
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=push.js.map
|
package/dist/push.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"push.js","sourceRoot":"","sources":["../src/push.ts"],"names":[],"mappings":"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"}
|
package/dist/scan.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ContentField } from "./config.js";
|
|
2
|
+
export interface ScanResult {
|
|
3
|
+
pages: Record<string, ContentField[]>;
|
|
4
|
+
totalFields: number;
|
|
5
|
+
filesScanned: number;
|
|
6
|
+
}
|
|
7
|
+
export declare function scanProject(srcDir: string): Promise<ScanResult>;
|
|
8
|
+
//# sourceMappingURL=scan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../src/scan.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAqKhD,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC;IACtC,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAiDrE"}
|
package/dist/scan.js
ADDED
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { basename, relative } from "node:path";
|
|
3
|
+
import { glob } from "glob";
|
|
4
|
+
/** Infer a CMS type from context clues. */
|
|
5
|
+
function inferType(text, context) {
|
|
6
|
+
const ctx = context.toLowerCase();
|
|
7
|
+
if (ctx.includes("image") || ctx.includes("img") || ctx.includes("photo") || ctx.includes("avatar"))
|
|
8
|
+
return "image";
|
|
9
|
+
if (ctx.includes("email") || text.includes("@"))
|
|
10
|
+
return "email";
|
|
11
|
+
if (ctx.includes("phone") || ctx.includes("tel"))
|
|
12
|
+
return "phone";
|
|
13
|
+
if (ctx.includes("href") || ctx.includes("link") || ctx.includes("url") || text.startsWith("http"))
|
|
14
|
+
return "link";
|
|
15
|
+
if (text.length > 200 || text.includes("\n"))
|
|
16
|
+
return "markdown";
|
|
17
|
+
return "text";
|
|
18
|
+
}
|
|
19
|
+
/** Convert a label like "Hero Title" to a key like "hero_title". */
|
|
20
|
+
function toKey(label) {
|
|
21
|
+
return label
|
|
22
|
+
.replace(/([a-z])([A-Z])/g, "$1_$2")
|
|
23
|
+
.replace(/[^a-zA-Z0-9]+/g, "_")
|
|
24
|
+
.replace(/^_|_$/g, "")
|
|
25
|
+
.toLowerCase()
|
|
26
|
+
.slice(0, 60);
|
|
27
|
+
}
|
|
28
|
+
/** Derive page name from a file path. Components that are imported on the homepage go to "home". */
|
|
29
|
+
function derivePage(filePath, srcDir) {
|
|
30
|
+
const rel = relative(srcDir, filePath);
|
|
31
|
+
// app/page.tsx → home
|
|
32
|
+
if (rel.includes("page.tsx") || rel.includes("page.jsx")) {
|
|
33
|
+
const parts = rel.split("/");
|
|
34
|
+
const idx = parts.indexOf("page.tsx") !== -1 ? parts.indexOf("page.tsx") : parts.indexOf("page.jsx");
|
|
35
|
+
if (idx <= 0 || (idx === 1 && parts[0] === "app"))
|
|
36
|
+
return "home";
|
|
37
|
+
// Dynamic routes like [slug] → skip
|
|
38
|
+
const folder = parts[idx - 1];
|
|
39
|
+
if (folder.startsWith("["))
|
|
40
|
+
return folder.replace(/[\[\]]/g, "");
|
|
41
|
+
return folder;
|
|
42
|
+
}
|
|
43
|
+
// components/Hero.tsx → use component name as section, page = "home"
|
|
44
|
+
return "home";
|
|
45
|
+
}
|
|
46
|
+
/** Derive a readable label from a variable/object key name. */
|
|
47
|
+
function keyToLabel(key) {
|
|
48
|
+
return key
|
|
49
|
+
.replace(/_/g, " ")
|
|
50
|
+
.replace(/([a-z])([A-Z])/g, "$1 $2")
|
|
51
|
+
.replace(/\b\w/g, (c) => c.toUpperCase());
|
|
52
|
+
}
|
|
53
|
+
/** Check if text looks like real user-facing content (not code/config). */
|
|
54
|
+
function isContent(text) {
|
|
55
|
+
// Must be at least 5 chars
|
|
56
|
+
if (text.length < 5)
|
|
57
|
+
return false;
|
|
58
|
+
// Skip template expressions
|
|
59
|
+
if (text.includes("${") || text.includes("` +"))
|
|
60
|
+
return false;
|
|
61
|
+
// Skip CSS-like values
|
|
62
|
+
if (text.startsWith("#") || text.startsWith("rgb") || text.startsWith("var(") || text.startsWith("hsl"))
|
|
63
|
+
return false;
|
|
64
|
+
// Skip code patterns
|
|
65
|
+
if (text.includes("className") || text.includes("onClick") || text.includes("import ")
|
|
66
|
+
|| text.includes("require(") || text.includes("console.") || text.includes("process.")
|
|
67
|
+
|| text.includes("__") || text.includes("=>"))
|
|
68
|
+
return false;
|
|
69
|
+
// Skip purely numeric/punctuation
|
|
70
|
+
if (/^[\s\d.,;:!?\-+*/=()]+$/.test(text))
|
|
71
|
+
return false;
|
|
72
|
+
// Skip URL-only strings (unless they're user-facing links)
|
|
73
|
+
if (/^https?:\/\/\S+$/.test(text) && !text.includes(" "))
|
|
74
|
+
return false;
|
|
75
|
+
// Skip very technical strings
|
|
76
|
+
if (/^[a-z][a-zA-Z]+\.[a-z]/.test(text))
|
|
77
|
+
return false; // looks like "module.exports"
|
|
78
|
+
// Skip short ALL_CAPS that look like enums
|
|
79
|
+
if (/^[A-Z_]{2,}$/.test(text) && text.length < 20)
|
|
80
|
+
return false;
|
|
81
|
+
// Skip metadata-like strings (page titles with template vars)
|
|
82
|
+
if (text.includes("${"))
|
|
83
|
+
return false;
|
|
84
|
+
// Must contain at least one letter
|
|
85
|
+
if (!/[a-zA-Z]/.test(text))
|
|
86
|
+
return false;
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
/** Extract content strings from a component file. */
|
|
90
|
+
function extractFromSource(source, fileName) {
|
|
91
|
+
const results = [];
|
|
92
|
+
const componentName = basename(fileName).replace(/\.(tsx?|jsx?)$/, "");
|
|
93
|
+
// Skip files that look like utilities/hooks/config
|
|
94
|
+
const lowerName = componentName.toLowerCase();
|
|
95
|
+
if (lowerName.startsWith("use") || lowerName === "utils" || lowerName === "helpers"
|
|
96
|
+
|| lowerName === "config" || lowerName === "constants" || lowerName === "types"
|
|
97
|
+
|| lowerName === "middleware" || lowerName === "cms") {
|
|
98
|
+
return [];
|
|
99
|
+
}
|
|
100
|
+
// Remove metadata exports before scanning (Next.js page metadata)
|
|
101
|
+
const cleanSource = source.replace(/export\s+const\s+metadata[\s\S]*?};/g, "");
|
|
102
|
+
// 1. JSX text content: >Some visible text<
|
|
103
|
+
const jsxTextRe = />([^<>{}`\n]{8,})</g;
|
|
104
|
+
let match;
|
|
105
|
+
while ((match = jsxTextRe.exec(cleanSource)) !== null) {
|
|
106
|
+
const text = match[1].trim();
|
|
107
|
+
if (!isContent(text))
|
|
108
|
+
continue;
|
|
109
|
+
const start = Math.max(0, match.index - 80);
|
|
110
|
+
const context = cleanSource.slice(start, match.index);
|
|
111
|
+
results.push({
|
|
112
|
+
label: text.slice(0, 50).trim(),
|
|
113
|
+
value: text,
|
|
114
|
+
type: inferType(text, context),
|
|
115
|
+
source: componentName,
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
// 2. Hardcoded object properties with content-like keys
|
|
119
|
+
const contentKeys = ["title", "desc", "description", "heading", "subtitle", "label", "text",
|
|
120
|
+
"content", "quote", "body", "caption", "role", "tag", "name"];
|
|
121
|
+
const objectPropRe = new RegExp(`(?:${contentKeys.join("|")})\\s*:\\s*["']([^"']{5,})["']`, "gi");
|
|
122
|
+
while ((match = objectPropRe.exec(cleanSource)) !== null) {
|
|
123
|
+
const propName = match[0].split(":")[0].trim();
|
|
124
|
+
const text = match[1].trim();
|
|
125
|
+
if (!isContent(text))
|
|
126
|
+
continue;
|
|
127
|
+
// Skip short tags like "AI" or identifiers
|
|
128
|
+
if (text.length < 5 && !/\s/.test(text))
|
|
129
|
+
continue;
|
|
130
|
+
results.push({
|
|
131
|
+
label: `${componentName} ${keyToLabel(propName)}`,
|
|
132
|
+
value: text,
|
|
133
|
+
type: inferType(text, propName),
|
|
134
|
+
source: componentName,
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
// 3. Named string constants that look like content
|
|
138
|
+
const constRe = /(?:const|let)\s+([a-zA-Z]\w{2,})\s*=\s*["']([^"']{10,})["']/g;
|
|
139
|
+
while ((match = constRe.exec(cleanSource)) !== null) {
|
|
140
|
+
const varName = match[1];
|
|
141
|
+
const text = match[2].trim();
|
|
142
|
+
if (!isContent(text))
|
|
143
|
+
continue;
|
|
144
|
+
// Skip common non-content variable names
|
|
145
|
+
if (["className", "style", "id", "key", "ref", "type", "name", "path", "route", "href"].includes(varName))
|
|
146
|
+
continue;
|
|
147
|
+
results.push({
|
|
148
|
+
label: `${componentName} ${keyToLabel(varName)}`,
|
|
149
|
+
value: text,
|
|
150
|
+
type: inferType(text, varName),
|
|
151
|
+
source: componentName,
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
// Deduplicate by value
|
|
155
|
+
const seen = new Set();
|
|
156
|
+
return results.filter((r) => {
|
|
157
|
+
if (seen.has(r.value))
|
|
158
|
+
return false;
|
|
159
|
+
seen.add(r.value);
|
|
160
|
+
return true;
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
export async function scanProject(srcDir) {
|
|
164
|
+
const files = await glob("**/*.{tsx,jsx}", {
|
|
165
|
+
cwd: srcDir,
|
|
166
|
+
absolute: true,
|
|
167
|
+
ignore: [
|
|
168
|
+
"**/node_modules/**", "**/.next/**", "**/dist/**",
|
|
169
|
+
"**/layout.tsx", "**/layout.jsx",
|
|
170
|
+
"**/loading.tsx", "**/error.tsx", "**/not-found.tsx",
|
|
171
|
+
],
|
|
172
|
+
});
|
|
173
|
+
const pages = {};
|
|
174
|
+
let totalFields = 0;
|
|
175
|
+
for (const file of files) {
|
|
176
|
+
const source = await readFile(file, "utf-8");
|
|
177
|
+
const extracted = extractFromSource(source, file);
|
|
178
|
+
if (extracted.length === 0)
|
|
179
|
+
continue;
|
|
180
|
+
const page = derivePage(file, srcDir);
|
|
181
|
+
if (!pages[page])
|
|
182
|
+
pages[page] = [];
|
|
183
|
+
// Track key counts to make them unique
|
|
184
|
+
const keyCounts = {};
|
|
185
|
+
for (const item of extracted) {
|
|
186
|
+
const prefix = item.source.toLowerCase().replace(/([a-z])([A-Z])/g, "$1_$2").toLowerCase();
|
|
187
|
+
const suffix = toKey(item.label.split(" ").slice(0, 4).join("_"));
|
|
188
|
+
let key = `${prefix}_${suffix}`.replace(/__+/g, "_").replace(/^_|_$/g, "");
|
|
189
|
+
key = key.slice(0, 55);
|
|
190
|
+
// Make duplicate keys unique by appending an index
|
|
191
|
+
keyCounts[key] = (keyCounts[key] || 0) + 1;
|
|
192
|
+
if (keyCounts[key] > 1) {
|
|
193
|
+
key = `${key}_${keyCounts[key]}`;
|
|
194
|
+
}
|
|
195
|
+
pages[page].push({
|
|
196
|
+
key: key.slice(0, 60),
|
|
197
|
+
label: `${item.source}: ${item.label}`,
|
|
198
|
+
type: item.type,
|
|
199
|
+
value: item.value,
|
|
200
|
+
sortOrder: pages[page].length,
|
|
201
|
+
});
|
|
202
|
+
totalFields++;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return { pages, totalFields, filesScanned: files.length };
|
|
206
|
+
}
|
|
207
|
+
//# sourceMappingURL=scan.js.map
|
package/dist/scan.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.js","sourceRoot":"","sources":["../src/scan.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@bearplex-technologies/cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "BearPlex CMS CLI — scan websites and sync content fields",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"bearplex": "./dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"main": "./dist/index.js",
|
|
10
|
+
"files": [
|
|
11
|
+
"dist"
|
|
12
|
+
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "tsc",
|
|
15
|
+
"dev": "tsc --watch",
|
|
16
|
+
"prepublishOnly": "npm run build"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"cms",
|
|
20
|
+
"bearplex",
|
|
21
|
+
"headless-cms",
|
|
22
|
+
"content-management",
|
|
23
|
+
"cli",
|
|
24
|
+
"scanner"
|
|
25
|
+
],
|
|
26
|
+
"author": "BearPlex <hello@bearplex.com>",
|
|
27
|
+
"license": "MIT",
|
|
28
|
+
"repository": {
|
|
29
|
+
"type": "git",
|
|
30
|
+
"url": "https://github.com/hamadpervaiz/bearplex-cms.git",
|
|
31
|
+
"directory": "packages/cli"
|
|
32
|
+
},
|
|
33
|
+
"homepage": "https://cms.oduscloud.com",
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"commander": "^13.1.0",
|
|
36
|
+
"glob": "^11.0.1"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@bearplex/tsconfig": "*",
|
|
40
|
+
"@types/node": "^22.0.0",
|
|
41
|
+
"typescript": "^5.7.3"
|
|
42
|
+
}
|
|
43
|
+
}
|