@funnelsgrove/cli 0.1.6 → 0.1.7
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/cli.js +5 -2
- package/dist/localSync.d.ts +1 -0
- package/dist/localSync.js +38 -4
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -7,7 +7,7 @@ import { fileURLToPath } from 'node:url';
|
|
|
7
7
|
import { Command } from 'commander';
|
|
8
8
|
import { callTrpcProcedure } from './apiClient.js';
|
|
9
9
|
import { clearActiveContext, getDefaultAuthConfigPath, loadActiveContext, loadAuthToken, saveActiveContext, saveAuthToken, } from './authStore.js';
|
|
10
|
-
import { buildSyncManifest, chunkChangedSourceFiles, collectChangedSourceFiles, collectSourceFiles, ensureGitignore, readSyncManifest, writeLocalEnvFile, writeSourceFiles, writeSyncManifest, } from './localSync.js';
|
|
10
|
+
import { buildSyncManifest, chunkChangedSourceFiles, collectChangedSourceFiles, collectSourceFiles, ensureGitignore, formatSyncUploadSummary, readSyncManifest, writeLocalEnvFile, writeSourceFiles, writeSyncManifest, } from './localSync.js';
|
|
11
11
|
import { pullEnvFile } from './envSync.js';
|
|
12
12
|
import { formatGitHubConnectRows, formatGitHubJobRows, formatGitHubStatusRows, } from './githubOutput.js';
|
|
13
13
|
import { syncGitHubDraftIfConnected } from './githubSyncFlow.js';
|
|
@@ -513,6 +513,7 @@ addExamples(syncCommand
|
|
|
513
513
|
let syncedFileCount = 0;
|
|
514
514
|
let deletedFileCount = 0;
|
|
515
515
|
if (changes) {
|
|
516
|
+
console.log(formatSyncUploadSummary(changes).join('\n'));
|
|
516
517
|
const batches = chunkChangedSourceFiles(changes);
|
|
517
518
|
for (const batch of batches) {
|
|
518
519
|
result = await callApi({
|
|
@@ -532,6 +533,8 @@ addExamples(syncCommand
|
|
|
532
533
|
}
|
|
533
534
|
}
|
|
534
535
|
else {
|
|
536
|
+
const files = await collectSourceFiles(target.sourceDir);
|
|
537
|
+
console.log(formatSyncUploadSummary({ deletedPaths: [], files }).join('\n'));
|
|
535
538
|
result = await callApi({
|
|
536
539
|
path: 'funnels.importSource',
|
|
537
540
|
type: 'mutation',
|
|
@@ -540,7 +543,7 @@ addExamples(syncCommand
|
|
|
540
543
|
workspaceId: target.workspaceId,
|
|
541
544
|
funnelId: target.funnelId,
|
|
542
545
|
message: options.message,
|
|
543
|
-
files
|
|
546
|
+
files,
|
|
544
547
|
},
|
|
545
548
|
});
|
|
546
549
|
syncedFileCount = result.syncedFiles.length;
|
package/dist/localSync.d.ts
CHANGED
|
@@ -36,4 +36,5 @@ export declare function readSyncManifest(rootDir: string): Promise<SyncManifest
|
|
|
36
36
|
export declare function collectSourceFiles(rootDir: string): Promise<SourceFile[]>;
|
|
37
37
|
export declare function collectChangedSourceFiles(rootDir: string, previousManifest: SyncManifest): Promise<ChangedSourceFiles>;
|
|
38
38
|
export declare function chunkChangedSourceFiles(changes: Pick<ChangedSourceFiles, 'deletedPaths' | 'files'>, maxContentChars?: number): SourceFilePatchBatch[];
|
|
39
|
+
export declare function formatSyncUploadSummary(changes: Pick<ChangedSourceFiles, 'deletedPaths' | 'files'>, largestFileLimit?: number): string[];
|
|
39
40
|
export declare function writeSourceFiles(rootDir: string, files: SourceFile[]): Promise<void>;
|
package/dist/localSync.js
CHANGED
|
@@ -3,16 +3,15 @@ import { mkdir, readdir, readFile, stat, writeFile } from 'node:fs/promises';
|
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
export const SYNC_MANIFEST_FILE = '.funnelsgrove-sync.json';
|
|
5
5
|
export const DEFAULT_PATCH_BATCH_CONTENT_CHARS = 12_000_000;
|
|
6
|
-
const
|
|
6
|
+
const EXCLUDED_LOCAL_DIRECTORY_NAMES = ['.git', '.playwright-cli', 'node_modules', '.next', 'out', 'output'];
|
|
7
|
+
const EXCLUDED_PATH_PARTS = new Set(EXCLUDED_LOCAL_DIRECTORY_NAMES);
|
|
7
8
|
const LOCAL_ONLY_GITIGNORE_LINES = [
|
|
8
9
|
'.env',
|
|
9
10
|
'.env.local',
|
|
10
11
|
'.env.*',
|
|
11
12
|
'!.env.example',
|
|
12
13
|
SYNC_MANIFEST_FILE,
|
|
13
|
-
'
|
|
14
|
-
'.next',
|
|
15
|
-
'out',
|
|
14
|
+
...EXCLUDED_LOCAL_DIRECTORY_NAMES.filter((directoryName) => directoryName !== '.git'),
|
|
16
15
|
];
|
|
17
16
|
export function normalizeSyncPath(filePath) {
|
|
18
17
|
const normalized = path.posix.normalize(filePath.replaceAll('\\', '/'));
|
|
@@ -157,6 +156,41 @@ export function chunkChangedSourceFiles(changes, maxContentChars = DEFAULT_PATCH
|
|
|
157
156
|
pushCurrentBatch();
|
|
158
157
|
return batches;
|
|
159
158
|
}
|
|
159
|
+
export function formatSyncUploadSummary(changes, largestFileLimit = 5) {
|
|
160
|
+
const fileSizes = changes.files
|
|
161
|
+
.map((file) => ({
|
|
162
|
+
path: file.path,
|
|
163
|
+
bytes: Buffer.byteLength(file.content, 'utf8'),
|
|
164
|
+
}))
|
|
165
|
+
.sort((left, right) => right.bytes - left.bytes || left.path.localeCompare(right.path));
|
|
166
|
+
const totalBytes = fileSizes.reduce((total, file) => total + file.bytes, 0);
|
|
167
|
+
const lines = [
|
|
168
|
+
`Preparing sync upload: ${formatCount(fileSizes.length, 'file')}, ${formatCount(changes.deletedPaths.length, 'deleted path')}, ${formatByteSize(totalBytes)} content.`,
|
|
169
|
+
];
|
|
170
|
+
if (fileSizes.length > 0 && largestFileLimit > 0) {
|
|
171
|
+
lines.push('Largest included files:');
|
|
172
|
+
for (const file of fileSizes.slice(0, largestFileLimit)) {
|
|
173
|
+
lines.push(` ${formatByteSize(file.bytes).padStart(6)} ${file.path}`);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return lines;
|
|
177
|
+
}
|
|
178
|
+
function formatCount(count, singular) {
|
|
179
|
+
return `${count} ${count === 1 ? singular : `${singular}s`}`;
|
|
180
|
+
}
|
|
181
|
+
function formatByteSize(byteCount) {
|
|
182
|
+
if (byteCount < 1024) {
|
|
183
|
+
return `${byteCount} B`;
|
|
184
|
+
}
|
|
185
|
+
const units = ['KB', 'MB', 'GB'];
|
|
186
|
+
let value = byteCount / 1024;
|
|
187
|
+
let unitIndex = 0;
|
|
188
|
+
while (value >= 1024 && unitIndex < units.length - 1) {
|
|
189
|
+
value /= 1024;
|
|
190
|
+
unitIndex += 1;
|
|
191
|
+
}
|
|
192
|
+
return `${value.toFixed(1)} ${units[unitIndex]}`;
|
|
193
|
+
}
|
|
160
194
|
async function readSourceFiles(rootDir, manifestFiles) {
|
|
161
195
|
const files = await Promise.all(manifestFiles.map(async (file) => {
|
|
162
196
|
const absolutePath = path.join(rootDir, assertSafeSyncPath(file.path));
|