@launchframe/cli 1.0.0-beta.8 → 1.0.0-beta.9
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/package.json +1 -1
- package/src/commands/cache.js +14 -14
- package/src/commands/help.js +2 -2
- package/src/commands/init.js +8 -8
- package/src/commands/service.js +6 -6
- package/src/generator.js +3 -3
- package/src/utils/github-access.js +4 -4
- package/src/utils/{module-cache.js → service-cache.js} +62 -62
package/package.json
CHANGED
package/src/commands/cache.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
const chalk = require('chalk');
|
|
2
|
-
const { clearCache, getCacheInfo } = require('../utils/
|
|
2
|
+
const { clearCache, getCacheInfo } = require('../utils/service-cache');
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* Clear
|
|
5
|
+
* Clear service cache
|
|
6
6
|
*/
|
|
7
7
|
async function cacheClear() {
|
|
8
|
-
console.log(chalk.yellow('\n⚠️ This will delete all cached
|
|
8
|
+
console.log(chalk.yellow('\n⚠️ This will delete all cached services'));
|
|
9
9
|
console.log(chalk.gray('You will need to re-download on next init or service:add\n'));
|
|
10
10
|
|
|
11
11
|
const inquirer = require('inquirer');
|
|
@@ -30,7 +30,7 @@ async function cacheClear() {
|
|
|
30
30
|
async function cacheInfo() {
|
|
31
31
|
const info = await getCacheInfo();
|
|
32
32
|
|
|
33
|
-
console.log(chalk.blue('\n📦
|
|
33
|
+
console.log(chalk.blue('\n📦 Service Cache Information\n'));
|
|
34
34
|
|
|
35
35
|
console.log(chalk.white('Location:'));
|
|
36
36
|
console.log(chalk.gray(` ${info.path}\n`));
|
|
@@ -54,14 +54,14 @@ async function cacheInfo() {
|
|
|
54
54
|
console.log(chalk.gray(` ${info.lastUpdate.toLocaleString()}\n`));
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
if (info.
|
|
58
|
-
console.log(chalk.white('Cached
|
|
59
|
-
info.
|
|
57
|
+
if (info.services && info.services.length > 0) {
|
|
58
|
+
console.log(chalk.white('Cached Services:'));
|
|
59
|
+
info.services.forEach(mod => {
|
|
60
60
|
console.log(chalk.gray(` • ${mod}`));
|
|
61
61
|
});
|
|
62
62
|
console.log('');
|
|
63
63
|
} else {
|
|
64
|
-
console.log(chalk.gray('No
|
|
64
|
+
console.log(chalk.gray('No services cached yet\n'));
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
console.log(chalk.gray('Commands:'));
|
|
@@ -73,21 +73,21 @@ async function cacheInfo() {
|
|
|
73
73
|
* Force update cache
|
|
74
74
|
*/
|
|
75
75
|
async function cacheUpdate() {
|
|
76
|
-
const { ensureCacheReady, getCacheInfo } = require('../utils/
|
|
76
|
+
const { ensureCacheReady, getCacheInfo } = require('../utils/service-cache');
|
|
77
77
|
|
|
78
78
|
console.log(chalk.blue('\n🔄 Forcing cache update...\n'));
|
|
79
79
|
|
|
80
80
|
try {
|
|
81
81
|
const info = await getCacheInfo();
|
|
82
|
-
const
|
|
82
|
+
const currentServices = info.services || [];
|
|
83
83
|
|
|
84
|
-
if (
|
|
85
|
-
console.log(chalk.yellow('No
|
|
84
|
+
if (currentServices.length === 0) {
|
|
85
|
+
console.log(chalk.yellow('No services in cache yet. Use init or service:add to populate.\n'));
|
|
86
86
|
return;
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
// Update cache with current
|
|
90
|
-
await ensureCacheReady(
|
|
89
|
+
// Update cache with current services
|
|
90
|
+
await ensureCacheReady(currentServices);
|
|
91
91
|
console.log(chalk.green('\n✓ Cache updated successfully\n'));
|
|
92
92
|
} catch (error) {
|
|
93
93
|
console.error(chalk.red(`\n❌ Failed to update cache: ${error.message}\n`));
|
package/src/commands/help.js
CHANGED
|
@@ -40,7 +40,7 @@ function help() {
|
|
|
40
40
|
console.log(chalk.white('Available Services:'));
|
|
41
41
|
console.log(chalk.gray(' waitlist Coming soon page with email collection\n'));
|
|
42
42
|
console.log(chalk.white('Cache Management:'));
|
|
43
|
-
console.log(chalk.gray(' cache:info Show cache location, size, and cached
|
|
43
|
+
console.log(chalk.gray(' cache:info Show cache location, size, and cached services'));
|
|
44
44
|
console.log(chalk.gray(' cache:update Force update cache to latest version'));
|
|
45
45
|
console.log(chalk.gray(' cache:clear Delete cache (re-download on next use)\n'));
|
|
46
46
|
console.log(chalk.white('Other commands:'));
|
|
@@ -75,7 +75,7 @@ function help() {
|
|
|
75
75
|
console.log(chalk.gray(' --user-model <b2b|b2b2c> User model (skips prompt)'));
|
|
76
76
|
console.log(chalk.gray(' help Show this help message\n'));
|
|
77
77
|
console.log(chalk.white('Cache Management:'));
|
|
78
|
-
console.log(chalk.gray(' cache:info Show cache location, size, and cached
|
|
78
|
+
console.log(chalk.gray(' cache:info Show cache location, size, and cached services'));
|
|
79
79
|
console.log(chalk.gray(' cache:update Force update cache to latest version'));
|
|
80
80
|
console.log(chalk.gray(' cache:clear Delete cache (re-download on next use)\n'));
|
|
81
81
|
console.log(chalk.white('Examples:'));
|
package/src/commands/init.js
CHANGED
|
@@ -4,7 +4,7 @@ const chalk = require('chalk');
|
|
|
4
4
|
const { runInitPrompts, runVariantPrompts } = require('../prompts');
|
|
5
5
|
const { generateProject } = require('../generator');
|
|
6
6
|
const { checkGitHubAccess, showAccessDeniedMessage } = require('../utils/github-access');
|
|
7
|
-
const { ensureCacheReady } = require('../utils/
|
|
7
|
+
const { ensureCacheReady } = require('../utils/service-cache');
|
|
8
8
|
const { isLaunchFrameProject } = require('../utils/project-helpers');
|
|
9
9
|
|
|
10
10
|
/**
|
|
@@ -116,8 +116,8 @@ async function init(options = {}) {
|
|
|
116
116
|
variantChoices = await runVariantPrompts();
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
-
// Determine which
|
|
120
|
-
const
|
|
119
|
+
// Determine which services are needed based on variant choices
|
|
120
|
+
const requiredServices = [
|
|
121
121
|
'backend',
|
|
122
122
|
'admin-portal',
|
|
123
123
|
'infrastructure',
|
|
@@ -126,20 +126,20 @@ async function init(options = {}) {
|
|
|
126
126
|
|
|
127
127
|
// Add customers-portal only if B2B2C mode
|
|
128
128
|
if (variantChoices.userModel === 'b2b2c') {
|
|
129
|
-
|
|
129
|
+
requiredServices.push('customers-portal');
|
|
130
130
|
}
|
|
131
131
|
|
|
132
132
|
// Determine template source (dev mode = local, production = cache)
|
|
133
133
|
let templateRoot;
|
|
134
134
|
|
|
135
135
|
if (devMode) {
|
|
136
|
-
// Dev mode: Use local
|
|
137
|
-
templateRoot = path.resolve(__dirname, '../../../
|
|
138
|
-
console.log(chalk.gray(`[DEV MODE] Using local
|
|
136
|
+
// Dev mode: Use local services directory
|
|
137
|
+
templateRoot = path.resolve(__dirname, '../../../services');
|
|
138
|
+
console.log(chalk.gray(`[DEV MODE] Using local services: ${templateRoot}\n`));
|
|
139
139
|
} else {
|
|
140
140
|
// Production mode: Use cache
|
|
141
141
|
try {
|
|
142
|
-
templateRoot = await ensureCacheReady(
|
|
142
|
+
templateRoot = await ensureCacheReady(requiredServices);
|
|
143
143
|
} catch (error) {
|
|
144
144
|
console.error(chalk.red(`\n❌ Error: ${error.message}\n`));
|
|
145
145
|
process.exit(1);
|
package/src/commands/service.js
CHANGED
|
@@ -8,7 +8,7 @@ const { isLaunchFrameProject, getProjectConfig, updateProjectConfig, getPrimaryD
|
|
|
8
8
|
const { replaceVariables } = require('../utils/variable-replacer');
|
|
9
9
|
const { updateEnvFile } = require('../utils/env-generator');
|
|
10
10
|
const { checkGitHubAccess, showAccessDeniedMessage } = require('../utils/github-access');
|
|
11
|
-
const { ensureCacheReady,
|
|
11
|
+
const { ensureCacheReady, getServicePath } = require('../utils/service-cache');
|
|
12
12
|
|
|
13
13
|
async function serviceAdd(serviceName) {
|
|
14
14
|
// STEP 1: Validation
|
|
@@ -75,13 +75,13 @@ async function serviceAdd(serviceName) {
|
|
|
75
75
|
let sourceDir;
|
|
76
76
|
|
|
77
77
|
if (isDevMode) {
|
|
78
|
-
// Local development: copy from launchframe-dev/
|
|
78
|
+
// Local development: copy from launchframe-dev/services directory
|
|
79
79
|
console.log(chalk.blue('\n[DEV MODE] Copying service from local directory...'));
|
|
80
|
-
sourceDir = path.resolve(__dirname, '../../../
|
|
80
|
+
sourceDir = path.resolve(__dirname, '../../../services', serviceName);
|
|
81
81
|
|
|
82
82
|
if (!fs.existsSync(sourceDir)) {
|
|
83
83
|
console.error(chalk.red(`Error: Local service directory not found: ${sourceDir}`));
|
|
84
|
-
console.log('Make sure the service exists in the
|
|
84
|
+
console.log('Make sure the service exists in the services directory');
|
|
85
85
|
process.exit(1);
|
|
86
86
|
}
|
|
87
87
|
} else {
|
|
@@ -98,9 +98,9 @@ async function serviceAdd(serviceName) {
|
|
|
98
98
|
console.log(chalk.green('✓ Repository access confirmed'));
|
|
99
99
|
|
|
100
100
|
try {
|
|
101
|
-
// Ensure cache has this service
|
|
101
|
+
// Ensure cache has this service
|
|
102
102
|
await ensureCacheReady([serviceName]);
|
|
103
|
-
sourceDir =
|
|
103
|
+
sourceDir = getServicePath(serviceName);
|
|
104
104
|
} catch (error) {
|
|
105
105
|
console.error(chalk.red(`\n❌ Error: ${error.message}\n`));
|
|
106
106
|
process.exit(1);
|
package/src/generator.js
CHANGED
|
@@ -142,7 +142,7 @@ async function generateProject(answers, variantChoices, templateRoot) {
|
|
|
142
142
|
await replaceVariables(path.join(destinationRoot, 'website'), variables);
|
|
143
143
|
initGitRepo(path.join(destinationRoot, 'website'), 'website');
|
|
144
144
|
|
|
145
|
-
// Step 5: Copy additional files (from project root, not
|
|
145
|
+
// Step 5: Copy additional files (from project root, not services/)
|
|
146
146
|
console.log('📋 Copying additional files...');
|
|
147
147
|
const additionalFiles = [
|
|
148
148
|
'.github',
|
|
@@ -174,13 +174,13 @@ async function generateProject(answers, variantChoices, templateRoot) {
|
|
|
174
174
|
// Step 7: Create .launchframe marker file with variant metadata
|
|
175
175
|
console.log('📝 Creating LaunchFrame marker file...');
|
|
176
176
|
const markerPath = path.join(destinationRoot, '.launchframe');
|
|
177
|
-
|
|
177
|
+
|
|
178
178
|
// Determine which services were installed
|
|
179
179
|
const installedServices = ['backend', 'admin-portal', 'infrastructure', 'website'];
|
|
180
180
|
if (variantChoices.userModel === 'b2b2c') {
|
|
181
181
|
installedServices.push('customers-portal');
|
|
182
182
|
}
|
|
183
|
-
|
|
183
|
+
|
|
184
184
|
const markerContent = {
|
|
185
185
|
version: '0.1.0',
|
|
186
186
|
createdAt: new Date().toISOString(),
|
|
@@ -14,14 +14,14 @@ function makeClickable(text, url) {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
|
-
* Check if user has SSH access to LaunchFrame
|
|
17
|
+
* Check if user has SSH access to LaunchFrame services repository
|
|
18
18
|
* @returns {Promise<{hasAccess: boolean, error?: string}>}
|
|
19
19
|
*/
|
|
20
20
|
async function checkGitHubAccess() {
|
|
21
21
|
try {
|
|
22
22
|
// Test SSH access by checking if we can list remote refs
|
|
23
23
|
execSync(
|
|
24
|
-
'git ls-remote git@github.com:launchframe-dev/
|
|
24
|
+
'git ls-remote git@github.com:launchframe-dev/services.git HEAD',
|
|
25
25
|
{
|
|
26
26
|
timeout: 15000,
|
|
27
27
|
stdio: 'pipe' // Don't show output
|
|
@@ -37,14 +37,14 @@ async function checkGitHubAccess() {
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
/**
|
|
40
|
-
* Display message when user doesn't have access to
|
|
40
|
+
* Display message when user doesn't have access to services repository
|
|
41
41
|
* Guides them to either purchase or setup SSH keys
|
|
42
42
|
*/
|
|
43
43
|
function showAccessDeniedMessage() {
|
|
44
44
|
const purchaseUrl = 'https://buy.polar.sh/polar_cl_Zy4YqEwhoIEdUrAH8vHaWuZtwZuv306sYMnq118MbKi';
|
|
45
45
|
const docsUrl = 'https://docs.launchframe.dev/guide/quick-start#add-ssh-key-to-repo';
|
|
46
46
|
|
|
47
|
-
console.log(chalk.red('\n❌ Cannot access LaunchFrame
|
|
47
|
+
console.log(chalk.red('\n❌ Cannot access LaunchFrame services repository\n'));
|
|
48
48
|
|
|
49
49
|
console.log(chalk.white('This could mean:\n'));
|
|
50
50
|
console.log(chalk.gray(' 1. You haven\'t purchased LaunchFrame yet'));
|
|
@@ -4,7 +4,7 @@ const os = require('os');
|
|
|
4
4
|
const { execSync } = require('child_process');
|
|
5
5
|
const chalk = require('chalk');
|
|
6
6
|
|
|
7
|
-
const
|
|
7
|
+
const SERVICES_REPO = 'git@github.com:launchframe-dev/services.git';
|
|
8
8
|
const BRANCH = 'main';
|
|
9
9
|
|
|
10
10
|
/**
|
|
@@ -15,9 +15,9 @@ const BRANCH = 'main';
|
|
|
15
15
|
function getCacheDir() {
|
|
16
16
|
const homeDir = os.homedir();
|
|
17
17
|
// Use same path structure on all platforms
|
|
18
|
-
// Windows: C:\Users\username\.launchframe\cache\
|
|
19
|
-
// Mac/Linux: /home/username/.launchframe/cache/
|
|
20
|
-
return path.join(homeDir, '.launchframe', 'cache', '
|
|
18
|
+
// Windows: C:\Users\username\.launchframe\cache\services
|
|
19
|
+
// Mac/Linux: /home/username/.launchframe/cache/services
|
|
20
|
+
return path.join(homeDir, '.launchframe', 'cache', 'services');
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
/**
|
|
@@ -32,33 +32,33 @@ async function cacheExists() {
|
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
34
|
* Initialize cache with sparse checkout
|
|
35
|
-
* Clones only the repository structure, no
|
|
35
|
+
* Clones only the repository structure, no services yet
|
|
36
36
|
* @returns {Promise<void>}
|
|
37
37
|
*/
|
|
38
38
|
async function initializeCache() {
|
|
39
39
|
const cacheDir = getCacheDir();
|
|
40
|
-
|
|
41
|
-
console.log(chalk.blue('🔄 Initializing
|
|
42
|
-
|
|
40
|
+
|
|
41
|
+
console.log(chalk.blue('🔄 Initializing services cache...'));
|
|
42
|
+
|
|
43
43
|
try {
|
|
44
44
|
// Ensure parent directory exists
|
|
45
45
|
await fs.ensureDir(path.dirname(cacheDir));
|
|
46
|
-
|
|
47
|
-
// Sparse clone (only root files, no
|
|
46
|
+
|
|
47
|
+
// Sparse clone (only root files, no services)
|
|
48
48
|
execSync(
|
|
49
|
-
`git clone --sparse --depth 1 --branch ${BRANCH} ${
|
|
50
|
-
{
|
|
49
|
+
`git clone --sparse --depth 1 --branch ${BRANCH} ${SERVICES_REPO} "${cacheDir}"`,
|
|
50
|
+
{
|
|
51
51
|
stdio: 'pipe', // Hide output
|
|
52
52
|
timeout: 60000 // 1 minute timeout
|
|
53
53
|
}
|
|
54
54
|
);
|
|
55
|
-
|
|
55
|
+
|
|
56
56
|
// Configure sparse checkout (starts with empty set)
|
|
57
57
|
execSync('git sparse-checkout init --cone', {
|
|
58
58
|
cwd: cacheDir,
|
|
59
59
|
stdio: 'pipe'
|
|
60
60
|
});
|
|
61
|
-
|
|
61
|
+
|
|
62
62
|
console.log(chalk.green('✓ Cache initialized'));
|
|
63
63
|
} catch (error) {
|
|
64
64
|
// Clean up partial clone on failure
|
|
@@ -74,16 +74,16 @@ async function initializeCache() {
|
|
|
74
74
|
*/
|
|
75
75
|
async function updateCache() {
|
|
76
76
|
const cacheDir = getCacheDir();
|
|
77
|
-
|
|
78
|
-
console.log(chalk.blue('🔄 Updating
|
|
79
|
-
|
|
77
|
+
|
|
78
|
+
console.log(chalk.blue('🔄 Updating service cache...'));
|
|
79
|
+
|
|
80
80
|
try {
|
|
81
81
|
execSync('git pull origin main', {
|
|
82
82
|
cwd: cacheDir,
|
|
83
83
|
stdio: 'pipe',
|
|
84
84
|
timeout: 30000 // 30 seconds
|
|
85
85
|
});
|
|
86
|
-
|
|
86
|
+
|
|
87
87
|
console.log(chalk.green('✓ Cache updated'));
|
|
88
88
|
} catch (error) {
|
|
89
89
|
throw new Error(`Failed to update cache: ${error.message}`);
|
|
@@ -91,53 +91,53 @@ async function updateCache() {
|
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
/**
|
|
94
|
-
* Expand sparse checkout to include specific
|
|
95
|
-
* @param {string[]}
|
|
94
|
+
* Expand sparse checkout to include specific services
|
|
95
|
+
* @param {string[]} serviceNames - Array of services names to expand
|
|
96
96
|
* @returns {Promise<void>}
|
|
97
97
|
*/
|
|
98
|
-
async function
|
|
98
|
+
async function expandServices(serviceNames) {
|
|
99
99
|
const cacheDir = getCacheDir();
|
|
100
|
-
|
|
101
|
-
console.log(chalk.blue(`📦 Loading
|
|
102
|
-
|
|
100
|
+
|
|
101
|
+
console.log(chalk.blue(`📦 Loading services: ${serviceNames.join(', ')}...`));
|
|
102
|
+
|
|
103
103
|
try {
|
|
104
104
|
// Get current sparse checkout list
|
|
105
|
-
let
|
|
105
|
+
let currentServices = [];
|
|
106
106
|
try {
|
|
107
107
|
const output = execSync('git sparse-checkout list', {
|
|
108
108
|
cwd: cacheDir,
|
|
109
109
|
stdio: 'pipe',
|
|
110
110
|
encoding: 'utf8'
|
|
111
111
|
});
|
|
112
|
-
|
|
112
|
+
currentServices = output.trim().split('\n').filter(Boolean);
|
|
113
113
|
} catch (error) {
|
|
114
|
-
// No
|
|
114
|
+
// No services yet, that's fine
|
|
115
115
|
}
|
|
116
|
-
|
|
117
|
-
// Add new
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
// Set sparse checkout to include all
|
|
121
|
-
execSync(`git sparse-checkout set ${
|
|
116
|
+
|
|
117
|
+
// Add new services to the list
|
|
118
|
+
const allServices = [...new Set([...currentServices, ...serviceNames])];
|
|
119
|
+
|
|
120
|
+
// Set sparse checkout to include all services
|
|
121
|
+
execSync(`git sparse-checkout set ${allServices.join(' ')}`, {
|
|
122
122
|
cwd: cacheDir,
|
|
123
123
|
stdio: 'pipe',
|
|
124
124
|
timeout: 60000 // 1 minute (may need to download files)
|
|
125
125
|
});
|
|
126
|
-
|
|
127
|
-
console.log(chalk.green('✓
|
|
126
|
+
|
|
127
|
+
console.log(chalk.green('✓ Services loaded'));
|
|
128
128
|
} catch (error) {
|
|
129
|
-
throw new Error(`Failed to expand
|
|
129
|
+
throw new Error(`Failed to expand services: ${error.message}`);
|
|
130
130
|
}
|
|
131
131
|
}
|
|
132
132
|
|
|
133
133
|
/**
|
|
134
|
-
* Get path to a specific
|
|
135
|
-
* @param {string}
|
|
136
|
-
* @returns {string} Absolute path to
|
|
134
|
+
* Get path to a specific service in the cache
|
|
135
|
+
* @param {string} serviceName - Service name (e.g., 'backend', 'admin-portal')
|
|
136
|
+
* @returns {string} Absolute path to service
|
|
137
137
|
*/
|
|
138
|
-
function
|
|
138
|
+
function getServicePath(serviceName) {
|
|
139
139
|
const cacheDir = getCacheDir();
|
|
140
|
-
return path.join(cacheDir,
|
|
140
|
+
return path.join(cacheDir, serviceName);
|
|
141
141
|
}
|
|
142
142
|
|
|
143
143
|
/**
|
|
@@ -149,13 +149,13 @@ function getCachePath() {
|
|
|
149
149
|
}
|
|
150
150
|
|
|
151
151
|
/**
|
|
152
|
-
* Clear the entire
|
|
152
|
+
* Clear the entire service cache
|
|
153
153
|
* Useful for troubleshooting or forcing fresh download
|
|
154
154
|
* @returns {Promise<void>}
|
|
155
155
|
*/
|
|
156
156
|
async function clearCache() {
|
|
157
157
|
const cacheDir = getCacheDir();
|
|
158
|
-
|
|
158
|
+
|
|
159
159
|
if (await fs.pathExists(cacheDir)) {
|
|
160
160
|
await fs.remove(cacheDir);
|
|
161
161
|
console.log(chalk.green('✓ Cache cleared'));
|
|
@@ -165,8 +165,8 @@ async function clearCache() {
|
|
|
165
165
|
}
|
|
166
166
|
|
|
167
167
|
/**
|
|
168
|
-
* Get cache information (size, last update,
|
|
169
|
-
* @returns {Promise<{exists: boolean, path: string, size?: number,
|
|
168
|
+
* Get cache information (size, last update, services)
|
|
169
|
+
* @returns {Promise<{exists: boolean, path: string, size?: number, services?: string[], lastUpdate?: Date}>}
|
|
170
170
|
*/
|
|
171
171
|
async function getCacheInfo() {
|
|
172
172
|
const cacheDir = getCacheDir();
|
|
@@ -174,13 +174,13 @@ async function getCacheInfo() {
|
|
|
174
174
|
exists: false,
|
|
175
175
|
path: cacheDir
|
|
176
176
|
};
|
|
177
|
-
|
|
177
|
+
|
|
178
178
|
if (!(await cacheExists())) {
|
|
179
179
|
return info;
|
|
180
180
|
}
|
|
181
|
-
|
|
181
|
+
|
|
182
182
|
info.exists = true;
|
|
183
|
-
|
|
183
|
+
|
|
184
184
|
try {
|
|
185
185
|
// Get cache size (du command works on Unix/Mac, different on Windows)
|
|
186
186
|
if (process.platform === 'win32') {
|
|
@@ -201,19 +201,19 @@ async function getCacheInfo() {
|
|
|
201
201
|
} catch (error) {
|
|
202
202
|
// Size calculation failed, not critical
|
|
203
203
|
}
|
|
204
|
-
|
|
204
|
+
|
|
205
205
|
try {
|
|
206
|
-
// Get list of expanded
|
|
206
|
+
// Get list of expanded services
|
|
207
207
|
const output = execSync('git sparse-checkout list', {
|
|
208
208
|
cwd: cacheDir,
|
|
209
209
|
encoding: 'utf8',
|
|
210
210
|
stdio: 'pipe'
|
|
211
211
|
});
|
|
212
|
-
info.
|
|
212
|
+
info.services = output.trim().split('\n').filter(Boolean);
|
|
213
213
|
} catch (error) {
|
|
214
|
-
info.
|
|
214
|
+
info.services = [];
|
|
215
215
|
}
|
|
216
|
-
|
|
216
|
+
|
|
217
217
|
try {
|
|
218
218
|
// Get last update time from git log
|
|
219
219
|
const output = execSync('git log -1 --format=%cd --date=iso', {
|
|
@@ -225,17 +225,17 @@ async function getCacheInfo() {
|
|
|
225
225
|
} catch (error) {
|
|
226
226
|
// Last update time failed, not critical
|
|
227
227
|
}
|
|
228
|
-
|
|
228
|
+
|
|
229
229
|
return info;
|
|
230
230
|
}
|
|
231
231
|
|
|
232
232
|
/**
|
|
233
233
|
* Ensure cache is ready (initialize if needed, update if exists)
|
|
234
234
|
* This is the main entry point for cache management
|
|
235
|
-
* @param {string[]}
|
|
235
|
+
* @param {string[]} requiredServices - Services needed for the operation
|
|
236
236
|
* @returns {Promise<string>} Path to cache root
|
|
237
237
|
*/
|
|
238
|
-
async function ensureCacheReady(
|
|
238
|
+
async function ensureCacheReady(requiredServices) {
|
|
239
239
|
try {
|
|
240
240
|
if (!(await cacheExists())) {
|
|
241
241
|
// Cache doesn't exist, initialize it
|
|
@@ -244,10 +244,10 @@ async function ensureCacheReady(requiredModules) {
|
|
|
244
244
|
// Cache exists, update it
|
|
245
245
|
await updateCache();
|
|
246
246
|
}
|
|
247
|
-
|
|
248
|
-
// Expand sparse checkout to include required
|
|
249
|
-
await
|
|
250
|
-
|
|
247
|
+
|
|
248
|
+
// Expand sparse checkout to include required services
|
|
249
|
+
await expandServices(requiredServices);
|
|
250
|
+
|
|
251
251
|
return getCachePath();
|
|
252
252
|
} catch (error) {
|
|
253
253
|
// If we fail and it's a network error, provide helpful message
|
|
@@ -265,8 +265,8 @@ module.exports = {
|
|
|
265
265
|
cacheExists,
|
|
266
266
|
initializeCache,
|
|
267
267
|
updateCache,
|
|
268
|
-
|
|
269
|
-
|
|
268
|
+
expandServices,
|
|
269
|
+
getServicePath,
|
|
270
270
|
getCachePath,
|
|
271
271
|
clearCache,
|
|
272
272
|
getCacheInfo,
|