@notionhive/core 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/lib/add-component.js +72 -0
- package/lib/category-cli.js +166 -0
- package/lib/copy-shared.js +147 -0
- package/lib/copy.js +58 -0
- package/lib/index.js +18 -0
- package/lib/parse-imports.js +34 -0
- package/lib/paths.js +44 -0
- package/lib/rewrite-imports.js +20 -0
- package/package.json +13 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
const fs = require("fs");
|
|
2
|
+
const path = require("path");
|
|
3
|
+
const { copyDirectory, pathExists } = require("./copy");
|
|
4
|
+
const { rewriteImports } = require("./rewrite-imports");
|
|
5
|
+
const { parseSharedImports } = require("./parse-imports");
|
|
6
|
+
const { resolvePaths } = require("./paths");
|
|
7
|
+
const { copySharedTree } = require("./copy-shared");
|
|
8
|
+
|
|
9
|
+
async function addComponent({
|
|
10
|
+
registryEntry,
|
|
11
|
+
sourceRoot,
|
|
12
|
+
targetDir,
|
|
13
|
+
force = false,
|
|
14
|
+
}) {
|
|
15
|
+
const paths = resolvePaths(targetDir);
|
|
16
|
+
const componentSource = path.join(
|
|
17
|
+
sourceRoot,
|
|
18
|
+
"components",
|
|
19
|
+
"organisms",
|
|
20
|
+
registryEntry.folderName
|
|
21
|
+
);
|
|
22
|
+
const componentTarget = path.join(paths.componentsDir, registryEntry.folderName);
|
|
23
|
+
|
|
24
|
+
if (!(await pathExists(componentSource))) {
|
|
25
|
+
throw new Error(`Component source not found: ${componentSource}`);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
await fs.promises.mkdir(paths.componentsDir, { recursive: true });
|
|
29
|
+
|
|
30
|
+
await copyDirectory(componentSource, componentTarget, {
|
|
31
|
+
force,
|
|
32
|
+
transformFile: (content) => rewriteImports(content),
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
const sharedImports = parseSharedImports(
|
|
36
|
+
await fs.promises.readFile(
|
|
37
|
+
path.join(componentSource, `${registryEntry.folderName}.jsx`),
|
|
38
|
+
"utf8"
|
|
39
|
+
)
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
const copiedShared = await copySharedTree({
|
|
43
|
+
sharedPaths: sharedImports,
|
|
44
|
+
sourceRoot,
|
|
45
|
+
sharedDir: paths.sharedDir,
|
|
46
|
+
targetDir: paths.targetDir,
|
|
47
|
+
force,
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
const copiedAssets = [];
|
|
51
|
+
|
|
52
|
+
if (registryEntry.assets) {
|
|
53
|
+
const assetSource = path.join(sourceRoot, registryEntry.assets);
|
|
54
|
+
const assetTarget = path.join(paths.targetDir, registryEntry.assets);
|
|
55
|
+
|
|
56
|
+
if (await pathExists(assetSource)) {
|
|
57
|
+
await copyDirectory(assetSource, assetTarget, { force });
|
|
58
|
+
copiedAssets.push(path.relative(paths.targetDir, assetTarget));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return {
|
|
63
|
+
componentPath: path.relative(paths.targetDir, componentTarget),
|
|
64
|
+
sharedPaths: copiedShared,
|
|
65
|
+
assetPaths: copiedAssets,
|
|
66
|
+
importLine: `import { ${registryEntry.exportName} } from "${paths.importPrefix}/${registryEntry.folderName}";`,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
module.exports = {
|
|
71
|
+
addComponent,
|
|
72
|
+
};
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
const fs = require("fs");
|
|
2
|
+
const path = require("path");
|
|
3
|
+
const { addComponent } = require("./add-component");
|
|
4
|
+
const { findLibraryRoot } = require("./paths");
|
|
5
|
+
|
|
6
|
+
function createCategoryCli(categoryConfig) {
|
|
7
|
+
return async function runCategoryCli(packageRoot, argv = process.argv.slice(2)) {
|
|
8
|
+
const REGISTRY_DIR = path.join(packageRoot, "registry");
|
|
9
|
+
const {
|
|
10
|
+
packageName,
|
|
11
|
+
binName,
|
|
12
|
+
label,
|
|
13
|
+
labelPlural,
|
|
14
|
+
exampleId,
|
|
15
|
+
} = categoryConfig;
|
|
16
|
+
|
|
17
|
+
function printHelp() {
|
|
18
|
+
console.log(`${packageName}
|
|
19
|
+
|
|
20
|
+
Add editable ${label} source into your Next.js project.
|
|
21
|
+
|
|
22
|
+
Usage:
|
|
23
|
+
npx ${packageName} add <${label}-id> [--dir <path>] [--force]
|
|
24
|
+
npx ${packageName} list
|
|
25
|
+
|
|
26
|
+
Examples:
|
|
27
|
+
npx ${packageName} add ${exampleId}
|
|
28
|
+
npx ${packageName} add ${exampleId} --dir ../client-site
|
|
29
|
+
npx ${packageName} list
|
|
30
|
+
`);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function loadRegistry() {
|
|
34
|
+
const indexPath = path.join(REGISTRY_DIR, "index.json");
|
|
35
|
+
return JSON.parse(fs.readFileSync(indexPath, "utf8"));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function resolveSourceRoot() {
|
|
39
|
+
const fromCwd = findLibraryRoot(process.cwd());
|
|
40
|
+
if (fromCwd) {
|
|
41
|
+
return fromCwd;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const bundledTemplates = path.join(packageRoot, "templates");
|
|
45
|
+
if (fs.existsSync(path.join(bundledTemplates, "components", "organisms"))) {
|
|
46
|
+
return bundledTemplates;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
throw new Error(
|
|
50
|
+
`Could not locate component source. Run from the component library repo, or install a published ${packageName} package with bundled templates.`
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function parseArgs(args) {
|
|
55
|
+
const tokens = [...args];
|
|
56
|
+
const command = tokens.shift();
|
|
57
|
+
|
|
58
|
+
if (!command || command === "--help" || command === "-h") {
|
|
59
|
+
return { command: "help" };
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (command === "list") {
|
|
63
|
+
return { command: "list" };
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (command !== "add") {
|
|
67
|
+
return { command: "unknown", raw: command };
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const id = tokens.shift();
|
|
71
|
+
let targetDir = process.cwd();
|
|
72
|
+
let force = false;
|
|
73
|
+
|
|
74
|
+
while (tokens.length > 0) {
|
|
75
|
+
const flag = tokens.shift();
|
|
76
|
+
if (flag === "--dir") {
|
|
77
|
+
targetDir = tokens.shift();
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
if (flag === "--force") {
|
|
81
|
+
force = true;
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
throw new Error(`Unknown flag: ${flag}`);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (!id) {
|
|
88
|
+
throw new Error(`Missing ${label} id. Example: ${exampleId}`);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return { command: "add", id, targetDir, force };
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
async function runList() {
|
|
95
|
+
const registry = loadRegistry();
|
|
96
|
+
console.log(`Available ${labelPlural}:\n`);
|
|
97
|
+
for (const entry of registry.items) {
|
|
98
|
+
console.log(` ${entry.id.padEnd(16)} ${entry.exportName}${entry.assets ? " (assets)" : ""}`);
|
|
99
|
+
}
|
|
100
|
+
console.log(`\nInstall: npx ${packageName} add ${exampleId}`);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
async function runAdd({ id, targetDir, force }) {
|
|
104
|
+
const registry = loadRegistry();
|
|
105
|
+
const entry = registry.items.find((item) => item.id === id);
|
|
106
|
+
|
|
107
|
+
if (!entry) {
|
|
108
|
+
throw new Error(`Unknown ${label} id "${id}". Run "${binName} list" to see options.`);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const sourceRoot = resolveSourceRoot();
|
|
112
|
+
const result = await addComponent({
|
|
113
|
+
registryEntry: entry,
|
|
114
|
+
sourceRoot,
|
|
115
|
+
targetDir,
|
|
116
|
+
force,
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
console.log(`Added ${entry.exportName} to ${path.resolve(targetDir)}\n`);
|
|
120
|
+
console.log("Files:");
|
|
121
|
+
console.log(` ${result.componentPath}/`);
|
|
122
|
+
for (const sharedPath of result.sharedPaths) {
|
|
123
|
+
console.log(` ${sharedPath}`);
|
|
124
|
+
}
|
|
125
|
+
for (const assetPath of result.assetPaths) {
|
|
126
|
+
console.log(` ${assetPath}/`);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
console.log("\nImport:");
|
|
130
|
+
console.log(` ${result.importLine}\n`);
|
|
131
|
+
console.log("Requirements: Next.js 16+, Tailwind CSS v4, prop-types");
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
try {
|
|
135
|
+
const parsed = parseArgs(argv);
|
|
136
|
+
|
|
137
|
+
if (parsed.command === "help") {
|
|
138
|
+
printHelp();
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (parsed.command === "unknown") {
|
|
143
|
+
throw new Error(`Unknown command "${parsed.raw}"`);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (parsed.command === "list") {
|
|
147
|
+
await runList();
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (parsed.command === "add") {
|
|
152
|
+
await runAdd(parsed);
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
printHelp();
|
|
157
|
+
} catch (error) {
|
|
158
|
+
console.error(`Error: ${error.message}`);
|
|
159
|
+
process.exit(1);
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
module.exports = {
|
|
165
|
+
createCategoryCli,
|
|
166
|
+
};
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
const fs = require("fs");
|
|
2
|
+
const path = require("path");
|
|
3
|
+
const { copyDirectory, pathExists } = require("./copy");
|
|
4
|
+
const { rewriteImports } = require("./rewrite-imports");
|
|
5
|
+
const { parseSharedImports } = require("./parse-imports");
|
|
6
|
+
|
|
7
|
+
function sharedTargetPath(sharedDir, sharedPath) {
|
|
8
|
+
const [category, ...rest] = sharedPath.split("/");
|
|
9
|
+
|
|
10
|
+
if (category === "atoms") {
|
|
11
|
+
return path.join(sharedDir, rest.join("/"));
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
if (category === "hooks") {
|
|
15
|
+
return path.join(sharedDir, "hooks", rest.join("/"));
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (category === "molecules") {
|
|
19
|
+
return path.join(sharedDir, "molecules", rest.join("/"));
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return path.join(sharedDir, sharedPath.replace(/\//g, "-"));
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function sharedSourcePath(sourceRoot, sharedPath) {
|
|
26
|
+
const [category, ...rest] = sharedPath.split("/");
|
|
27
|
+
|
|
28
|
+
if (category === "hooks") {
|
|
29
|
+
return path.join(sourceRoot, "components", "hooks", `${rest.join("/")}.js`);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return path.join(sourceRoot, "components", category, ...rest);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async function copySharedFile(sourceFile, targetFile, force) {
|
|
36
|
+
if (await pathExists(targetFile)) {
|
|
37
|
+
return path.relative(path.dirname(targetFile), targetFile);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
await fs.promises.mkdir(path.dirname(targetFile), { recursive: true });
|
|
41
|
+
|
|
42
|
+
if (await pathExists(sourceFile)) {
|
|
43
|
+
const content = await fs.promises.readFile(sourceFile, "utf8");
|
|
44
|
+
await fs.promises.writeFile(targetFile, rewriteImports(content), "utf8");
|
|
45
|
+
return targetFile;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
throw new Error(`Shared file not found: ${sourceFile}`);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async function copySharedDependency({
|
|
52
|
+
sharedPath,
|
|
53
|
+
sourceRoot,
|
|
54
|
+
sharedDir,
|
|
55
|
+
targetDir,
|
|
56
|
+
force,
|
|
57
|
+
copied,
|
|
58
|
+
copiedPaths,
|
|
59
|
+
}) {
|
|
60
|
+
if (copied.has(sharedPath)) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
copied.add(sharedPath);
|
|
65
|
+
|
|
66
|
+
const source = sharedSourcePath(sourceRoot, sharedPath);
|
|
67
|
+
const target = sharedTargetPath(sharedDir, sharedPath);
|
|
68
|
+
const [category] = sharedPath.split("/");
|
|
69
|
+
|
|
70
|
+
if (category === "hooks") {
|
|
71
|
+
await copySharedFile(source, `${target}.js`, force);
|
|
72
|
+
copiedPaths.push(path.relative(targetDir, `${target}.js`));
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (!(await pathExists(source))) {
|
|
77
|
+
throw new Error(`Shared dependency not found: ${source}`);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (await pathExists(target)) {
|
|
81
|
+
copiedPaths.push(path.relative(targetDir, target));
|
|
82
|
+
} else {
|
|
83
|
+
await copyDirectory(source, target, {
|
|
84
|
+
force,
|
|
85
|
+
transformFile: (content) => rewriteImports(content),
|
|
86
|
+
});
|
|
87
|
+
copiedPaths.push(path.relative(targetDir, target));
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const mainFile = path.join(target, `${path.basename(target)}.jsx`);
|
|
91
|
+
let parseSource = "";
|
|
92
|
+
|
|
93
|
+
if (await pathExists(mainFile)) {
|
|
94
|
+
parseSource = await fs.promises.readFile(mainFile, "utf8");
|
|
95
|
+
} else if (await pathExists(`${target}.js`)) {
|
|
96
|
+
parseSource = await fs.promises.readFile(`${target}.js`, "utf8");
|
|
97
|
+
} else {
|
|
98
|
+
const entries = await fs.promises.readdir(target);
|
|
99
|
+
const jsxFile = entries.find((name) => name.endsWith(".jsx"));
|
|
100
|
+
if (jsxFile) {
|
|
101
|
+
parseSource = await fs.promises.readFile(path.join(target, jsxFile), "utf8");
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
for (const nestedSharedPath of parseSharedImports(parseSource)) {
|
|
106
|
+
await copySharedDependency({
|
|
107
|
+
sharedPath: nestedSharedPath,
|
|
108
|
+
sourceRoot,
|
|
109
|
+
sharedDir,
|
|
110
|
+
targetDir,
|
|
111
|
+
force,
|
|
112
|
+
copied,
|
|
113
|
+
copiedPaths,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
async function copySharedTree({
|
|
119
|
+
sharedPaths,
|
|
120
|
+
sourceRoot,
|
|
121
|
+
sharedDir,
|
|
122
|
+
targetDir,
|
|
123
|
+
force,
|
|
124
|
+
}) {
|
|
125
|
+
const copied = new Set();
|
|
126
|
+
const copiedPaths = [];
|
|
127
|
+
|
|
128
|
+
for (const sharedPath of sharedPaths) {
|
|
129
|
+
await copySharedDependency({
|
|
130
|
+
sharedPath,
|
|
131
|
+
sourceRoot,
|
|
132
|
+
sharedDir,
|
|
133
|
+
targetDir,
|
|
134
|
+
force,
|
|
135
|
+
copied,
|
|
136
|
+
copiedPaths,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return [...new Set(copiedPaths)];
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
module.exports = {
|
|
144
|
+
copySharedTree,
|
|
145
|
+
sharedSourcePath,
|
|
146
|
+
sharedTargetPath,
|
|
147
|
+
};
|
package/lib/copy.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
const fs = require("fs");
|
|
2
|
+
const path = require("path");
|
|
3
|
+
|
|
4
|
+
async function pathExists(filePath) {
|
|
5
|
+
try {
|
|
6
|
+
await fs.promises.access(filePath);
|
|
7
|
+
return true;
|
|
8
|
+
} catch {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async function copyDirectory(source, destination, options = {}) {
|
|
14
|
+
const { force = false, transformFile } = options;
|
|
15
|
+
|
|
16
|
+
if (!(await pathExists(source))) {
|
|
17
|
+
throw new Error(`Source not found: ${source}`);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (await pathExists(destination)) {
|
|
21
|
+
if (!force) {
|
|
22
|
+
throw new Error(`Destination already exists: ${destination} (use --force to overwrite)`);
|
|
23
|
+
}
|
|
24
|
+
await fs.promises.rm(destination, { recursive: true, force: true });
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
await fs.promises.mkdir(destination, { recursive: true });
|
|
28
|
+
|
|
29
|
+
const entries = await fs.promises.readdir(source, { withFileTypes: true });
|
|
30
|
+
|
|
31
|
+
for (const entry of entries) {
|
|
32
|
+
if (entry.name === "node_modules" || entry.name.endsWith(".stories.jsx")) {
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const srcPath = path.join(source, entry.name);
|
|
37
|
+
const destPath = path.join(destination, entry.name);
|
|
38
|
+
|
|
39
|
+
if (entry.isDirectory()) {
|
|
40
|
+
await copyDirectory(srcPath, destPath, options);
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (typeof transformFile === "function") {
|
|
45
|
+
const input = await fs.promises.readFile(srcPath, "utf8");
|
|
46
|
+
const output = transformFile(input, srcPath);
|
|
47
|
+
await fs.promises.writeFile(destPath, output, "utf8");
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
await fs.promises.copyFile(srcPath, destPath);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
module.exports = {
|
|
56
|
+
pathExists,
|
|
57
|
+
copyDirectory,
|
|
58
|
+
};
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const { addComponent } = require("./add-component");
|
|
2
|
+
const { copyDirectory } = require("./copy");
|
|
3
|
+
const { copySharedTree } = require("./copy-shared");
|
|
4
|
+
const { createCategoryCli } = require("./category-cli");
|
|
5
|
+
const { findLibraryRoot, resolvePaths } = require("./paths");
|
|
6
|
+
const { rewriteImports } = require("./rewrite-imports");
|
|
7
|
+
const { parseSharedImports } = require("./parse-imports");
|
|
8
|
+
|
|
9
|
+
module.exports = {
|
|
10
|
+
addComponent,
|
|
11
|
+
copyDirectory,
|
|
12
|
+
copySharedTree,
|
|
13
|
+
createCategoryCli,
|
|
14
|
+
findLibraryRoot,
|
|
15
|
+
resolvePaths,
|
|
16
|
+
rewriteImports,
|
|
17
|
+
parseSharedImports,
|
|
18
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
const SHARED_DEPENDENCY_ROOTS = {
|
|
2
|
+
SafeImage: "atoms/SafeImage",
|
|
3
|
+
useCarousel: "hooks/useCarousel",
|
|
4
|
+
};
|
|
5
|
+
|
|
6
|
+
function parseSharedImports(source) {
|
|
7
|
+
const deps = new Set();
|
|
8
|
+
|
|
9
|
+
const relativePattern =
|
|
10
|
+
/from\s+["'](?:\.\.\/)+(atoms|hooks|molecules)\/([^"']+)["']/g;
|
|
11
|
+
let match = relativePattern.exec(source);
|
|
12
|
+
|
|
13
|
+
while (match) {
|
|
14
|
+
deps.add(`${match[1]}/${match[2]}`);
|
|
15
|
+
match = relativePattern.exec(source);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return [...deps];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function sharedFolderName(relativePath) {
|
|
22
|
+
if (relativePath === "atoms/SafeImage") return "SafeImage";
|
|
23
|
+
if (relativePath === "hooks/useCarousel") return "hooks/useCarousel";
|
|
24
|
+
if (relativePath.startsWith("molecules/")) {
|
|
25
|
+
return `molecules/${relativePath.split("/")[1]}`;
|
|
26
|
+
}
|
|
27
|
+
return relativePath.replace(/\//g, "-");
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
module.exports = {
|
|
31
|
+
SHARED_DEPENDENCY_ROOTS,
|
|
32
|
+
parseSharedImports,
|
|
33
|
+
sharedFolderName,
|
|
34
|
+
};
|
package/lib/paths.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
const fs = require("fs");
|
|
2
|
+
const path = require("path");
|
|
3
|
+
|
|
4
|
+
const SHARED_MAP = {
|
|
5
|
+
"atoms/SafeImage": "_shared/SafeImage",
|
|
6
|
+
"hooks/useCarousel": "_shared/hooks/useCarousel",
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
function findLibraryRoot(startDir) {
|
|
10
|
+
let current = startDir;
|
|
11
|
+
while (current !== path.dirname(current)) {
|
|
12
|
+
const componentsDir = path.join(current, "components", "organisms");
|
|
13
|
+
if (fs.existsSync(componentsDir)) {
|
|
14
|
+
return current;
|
|
15
|
+
}
|
|
16
|
+
current = path.dirname(current);
|
|
17
|
+
}
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function resolvePaths(targetDir, options = {}) {
|
|
22
|
+
const componentsDir = path.join(targetDir, "components");
|
|
23
|
+
const publicDir = path.join(targetDir, "public");
|
|
24
|
+
|
|
25
|
+
return {
|
|
26
|
+
targetDir: path.resolve(targetDir),
|
|
27
|
+
componentsDir,
|
|
28
|
+
sharedDir: path.join(componentsDir, "_shared"),
|
|
29
|
+
publicDir,
|
|
30
|
+
importPrefix: options.importPrefix ?? "@/components",
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function mapSharedPath(relativeImportPath) {
|
|
35
|
+
const normalized = relativeImportPath.replace(/\\/g, "/");
|
|
36
|
+
return SHARED_MAP[normalized] ?? null;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
module.exports = {
|
|
40
|
+
SHARED_MAP,
|
|
41
|
+
findLibraryRoot,
|
|
42
|
+
resolvePaths,
|
|
43
|
+
mapSharedPath,
|
|
44
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
function rewriteImports(source) {
|
|
2
|
+
return source.replace(
|
|
3
|
+
/from\s+["'](?:\.\.\/)+(atoms|hooks|molecules)\/([^"']+)["']/g,
|
|
4
|
+
(_match, category, rest) => {
|
|
5
|
+
if (category === "atoms") {
|
|
6
|
+
return `from "@/components/_shared/${rest}"`;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
if (category === "hooks") {
|
|
10
|
+
return `from "@/components/_shared/hooks/${rest}"`;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
return `from "@/components/_shared/molecules/${rest}"`;
|
|
14
|
+
}
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
module.exports = {
|
|
19
|
+
rewriteImports,
|
|
20
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@notionhive/core",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Shared utilities for @notionhive category CLIs (copy editable source into projects).",
|
|
5
|
+
"license": "UNLICENSED",
|
|
6
|
+
"main": "./lib/index.js",
|
|
7
|
+
"files": [
|
|
8
|
+
"lib"
|
|
9
|
+
],
|
|
10
|
+
"engines": {
|
|
11
|
+
"node": ">=18"
|
|
12
|
+
}
|
|
13
|
+
}
|