framer-code-link 0.10.1 → 0.12.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/index.mjs +51 -28
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1262,7 +1262,8 @@ var Installer = class {
|
|
|
1262
1262
|
this.ensurePrettierConfig(),
|
|
1263
1263
|
this.ensureFramerDeclarations(),
|
|
1264
1264
|
this.ensurePackageJson(),
|
|
1265
|
-
this.ensureSkills()
|
|
1265
|
+
this.ensureSkills(),
|
|
1266
|
+
this.ensureGitignore()
|
|
1266
1267
|
]);
|
|
1267
1268
|
Promise.resolve().then(async () => {
|
|
1268
1269
|
await this.ensureReact18Types();
|
|
@@ -1416,6 +1417,27 @@ declare module "*.json"
|
|
|
1416
1417
|
async ensureSkills() {
|
|
1417
1418
|
await installSkills(this.projectDir);
|
|
1418
1419
|
}
|
|
1420
|
+
async ensureGitignore() {
|
|
1421
|
+
const gitignorePath = path.join(this.projectDir, ".gitignore");
|
|
1422
|
+
try {
|
|
1423
|
+
await fs.access(gitignorePath);
|
|
1424
|
+
debug(".gitignore already exists");
|
|
1425
|
+
return;
|
|
1426
|
+
} catch {}
|
|
1427
|
+
const content = [
|
|
1428
|
+
"node_modules/",
|
|
1429
|
+
"",
|
|
1430
|
+
"# Framer Code Link",
|
|
1431
|
+
".framer-sync-state.json",
|
|
1432
|
+
".skills/",
|
|
1433
|
+
".agents/skills/",
|
|
1434
|
+
".claude/skills/",
|
|
1435
|
+
".cursor/skills/",
|
|
1436
|
+
""
|
|
1437
|
+
].join("\n");
|
|
1438
|
+
await fs.writeFile(gitignorePath, content);
|
|
1439
|
+
debug("Created .gitignore");
|
|
1440
|
+
}
|
|
1419
1441
|
async ensureReact18Types() {
|
|
1420
1442
|
const reactTypesDir = path.join(this.projectDir, "node_modules/@types/react");
|
|
1421
1443
|
const reactFiles = [
|
|
@@ -1877,8 +1899,8 @@ function hashContent(content) {
|
|
|
1877
1899
|
function toPackageName(name) {
|
|
1878
1900
|
return name.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/^-+|-+$/g, "").replace(/-+/g, "-");
|
|
1879
1901
|
}
|
|
1880
|
-
function
|
|
1881
|
-
return name.replace(/[^a-zA-Z0-9-
|
|
1902
|
+
function toDirectoryName(name) {
|
|
1903
|
+
return name.replace(/[^a-zA-Z0-9-]/g, "-").replace(/^-+|-+$/g, "").replace(/-+/g, "-");
|
|
1882
1904
|
}
|
|
1883
1905
|
async function getProjectHashFromCwd() {
|
|
1884
1906
|
try {
|
|
@@ -1889,27 +1911,27 @@ async function getProjectHashFromCwd() {
|
|
|
1889
1911
|
return null;
|
|
1890
1912
|
}
|
|
1891
1913
|
}
|
|
1892
|
-
async function
|
|
1893
|
-
if (
|
|
1894
|
-
const resolved = path.resolve(
|
|
1914
|
+
async function findOrCreateProjectDirectory(projectHash, projectName, explicitDirectory) {
|
|
1915
|
+
if (explicitDirectory) {
|
|
1916
|
+
const resolved = path.resolve(explicitDirectory);
|
|
1895
1917
|
await fs.mkdir(path.join(resolved, "files"), { recursive: true });
|
|
1896
1918
|
return {
|
|
1897
|
-
|
|
1919
|
+
directory: resolved,
|
|
1898
1920
|
created: false
|
|
1899
1921
|
};
|
|
1900
1922
|
}
|
|
1901
1923
|
const cwd = process.cwd();
|
|
1902
|
-
const existing = await
|
|
1924
|
+
const existing = await findExistingProjectDirectory(cwd, projectHash);
|
|
1903
1925
|
if (existing) return {
|
|
1904
|
-
|
|
1926
|
+
directory: existing,
|
|
1905
1927
|
created: false
|
|
1906
1928
|
};
|
|
1907
1929
|
if (!projectName) throw new Error("Failed to get Project name. Pass --name <project name>.");
|
|
1908
|
-
const
|
|
1930
|
+
const directoryName = toDirectoryName(projectName);
|
|
1909
1931
|
const pkgName = toPackageName(projectName);
|
|
1910
1932
|
const shortId = shortProjectHash(projectHash);
|
|
1911
|
-
const
|
|
1912
|
-
await fs.mkdir(path.join(
|
|
1933
|
+
const projectDirectory = path.join(cwd, directoryName || shortId);
|
|
1934
|
+
await fs.mkdir(path.join(projectDirectory, "files"), { recursive: true });
|
|
1913
1935
|
const pkg = {
|
|
1914
1936
|
name: pkgName || shortId,
|
|
1915
1937
|
version: "1.0.0",
|
|
@@ -1917,19 +1939,19 @@ async function findOrCreateProjectDir(projectHash, projectName, explicitDir) {
|
|
|
1917
1939
|
shortProjectHash: shortId,
|
|
1918
1940
|
framerProjectName: projectName
|
|
1919
1941
|
};
|
|
1920
|
-
await fs.writeFile(path.join(
|
|
1942
|
+
await fs.writeFile(path.join(projectDirectory, "package.json"), JSON.stringify(pkg, null, 2));
|
|
1921
1943
|
return {
|
|
1922
|
-
|
|
1944
|
+
directory: projectDirectory,
|
|
1923
1945
|
created: true
|
|
1924
1946
|
};
|
|
1925
1947
|
}
|
|
1926
|
-
async function
|
|
1927
|
-
if (await matchesProject(path.join(
|
|
1928
|
-
const entries = await fs.readdir(
|
|
1948
|
+
async function findExistingProjectDirectory(baseDirectory, projectHash) {
|
|
1949
|
+
if (await matchesProject(path.join(baseDirectory, "package.json"), projectHash)) return baseDirectory;
|
|
1950
|
+
const entries = await fs.readdir(baseDirectory, { withFileTypes: true });
|
|
1929
1951
|
for (const entry of entries) {
|
|
1930
1952
|
if (!entry.isDirectory()) continue;
|
|
1931
|
-
const
|
|
1932
|
-
if (await matchesProject(path.join(
|
|
1953
|
+
const directory = path.join(baseDirectory, entry.name);
|
|
1954
|
+
if (await matchesProject(path.join(directory, "package.json"), projectHash)) return directory;
|
|
1933
1955
|
}
|
|
1934
1956
|
return null;
|
|
1935
1957
|
}
|
|
@@ -2351,9 +2373,9 @@ async function executeEffect(effect, context) {
|
|
|
2351
2373
|
case "INIT_WORKSPACE":
|
|
2352
2374
|
if (!config.projectDir) {
|
|
2353
2375
|
const projectName = config.explicitName ?? effect.projectInfo.projectName;
|
|
2354
|
-
const
|
|
2355
|
-
config.projectDir =
|
|
2356
|
-
config.projectDirCreated =
|
|
2376
|
+
const directoryInfo = await findOrCreateProjectDirectory(config.projectHash, projectName, config.explicitDirectory);
|
|
2377
|
+
config.projectDir = directoryInfo.directory;
|
|
2378
|
+
config.projectDirCreated = directoryInfo.created;
|
|
2357
2379
|
config.filesDir = `${config.projectDir}/files`;
|
|
2358
2380
|
debug(`Files directory: ${config.filesDir}`);
|
|
2359
2381
|
await fs.mkdir(config.filesDir, { recursive: true });
|
|
@@ -2505,11 +2527,12 @@ async function executeEffect(effect, context) {
|
|
|
2505
2527
|
resetDisconnectState();
|
|
2506
2528
|
return [];
|
|
2507
2529
|
}
|
|
2508
|
-
const
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
else
|
|
2512
|
-
else if (
|
|
2530
|
+
const relative = config.projectDir ? path.relative(process.cwd(), config.projectDir) : null;
|
|
2531
|
+
const relativeDirectory = relative != null ? relative ? "./" + relative : "." : null;
|
|
2532
|
+
if (effect.totalCount === 0 && relativeDirectory) if (config.projectDirCreated) success(`Created ${relativeDirectory} folder`);
|
|
2533
|
+
else success(`Syncing to ${relativeDirectory} folder`);
|
|
2534
|
+
else if (relativeDirectory && config.projectDirCreated) success(`Synced into ${relativeDirectory} (${effect.updatedCount} files added)`);
|
|
2535
|
+
else if (relativeDirectory) success(`Synced into ${relativeDirectory} (${effect.updatedCount} files updated, ${effect.unchangedCount} unchanged)`);
|
|
2513
2536
|
else success(`Synced ${effect.totalCount} files (${effect.updatedCount} updated, ${effect.unchangedCount} unchanged)`);
|
|
2514
2537
|
status("Watching for changes...");
|
|
2515
2538
|
return [];
|
|
@@ -2757,7 +2780,7 @@ program.name("framer-code-link").description("Sync Framer code components to you
|
|
|
2757
2780
|
filesDir: null,
|
|
2758
2781
|
dangerouslyAutoDelete: options.dangerouslyAutoDelete ?? false,
|
|
2759
2782
|
allowUnsupportedNpm: options.unsupportedNpm ?? false,
|
|
2760
|
-
|
|
2783
|
+
explicitDirectory: options.dir,
|
|
2761
2784
|
explicitName: options.name
|
|
2762
2785
|
};
|
|
2763
2786
|
if (config.dangerouslyAutoDelete) warn("Auto-delete mode enabled - files will be deleted without confirmation");
|