@afroze9/terrastudio-cli 0.42.4 → 0.47.2
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/bundle/cli.cjs +28860 -0
- package/package.json +6 -13
- package/dist/cli.d.ts +0 -3
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js +0 -20
- package/dist/cli.js.map +0 -1
- package/dist/commands/hcl.d.ts +0 -3
- package/dist/commands/hcl.d.ts.map +0 -1
- package/dist/commands/hcl.js +0 -158
- package/dist/commands/hcl.js.map +0 -1
- package/dist/commands/module.d.ts +0 -3
- package/dist/commands/module.d.ts.map +0 -1
- package/dist/commands/module.js +0 -277
- package/dist/commands/module.js.map +0 -1
- package/dist/commands/project.d.ts +0 -3
- package/dist/commands/project.d.ts.map +0 -1
- package/dist/commands/project.js +0 -137
- package/dist/commands/project.js.map +0 -1
- package/dist/commands/resource.d.ts +0 -3
- package/dist/commands/resource.d.ts.map +0 -1
- package/dist/commands/resource.js +0 -366
- package/dist/commands/resource.js.map +0 -1
- package/dist/commands/terraform.d.ts +0 -3
- package/dist/commands/terraform.d.ts.map +0 -1
- package/dist/commands/terraform.js +0 -199
- package/dist/commands/terraform.js.map +0 -1
- package/dist/index.d.ts +0 -3
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -4
- package/dist/index.js.map +0 -1
- package/dist/platform/node-io.d.ts +0 -29
- package/dist/platform/node-io.d.ts.map +0 -1
- package/dist/platform/node-io.js +0 -61
- package/dist/platform/node-io.js.map +0 -1
- package/dist/platform/resolve-project.d.ts +0 -9
- package/dist/platform/resolve-project.d.ts.map +0 -1
- package/dist/platform/resolve-project.js +0 -41
- package/dist/platform/resolve-project.js.map +0 -1
|
@@ -1,199 +0,0 @@
|
|
|
1
|
-
import { Command } from 'commander';
|
|
2
|
-
import { storage, toLoadedProject } from '../platform/node-io.js';
|
|
3
|
-
import { Project } from '@terrastudio/project';
|
|
4
|
-
import { spawn } from 'node:child_process';
|
|
5
|
-
import { existsSync } from 'node:fs';
|
|
6
|
-
import path from 'node:path';
|
|
7
|
-
import { resolveProjectPath } from '../platform/resolve-project.js';
|
|
8
|
-
/** Resolve the terraform/ directory for a project path. */
|
|
9
|
-
function tfDir(projectPath) {
|
|
10
|
-
return path.join(projectPath, 'terraform');
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* Spawn terraform with the given args in the terraform/ directory.
|
|
14
|
-
* Streams stdout/stderr directly to the terminal.
|
|
15
|
-
* Rejects with the exit code if non-zero.
|
|
16
|
-
*/
|
|
17
|
-
function runTerraform(cwd, args, allowedCodes = [0]) {
|
|
18
|
-
return new Promise((resolve, reject) => {
|
|
19
|
-
const proc = spawn('terraform', args, {
|
|
20
|
-
cwd,
|
|
21
|
-
stdio: 'inherit',
|
|
22
|
-
shell: process.platform === 'win32',
|
|
23
|
-
});
|
|
24
|
-
proc.on('close', (code) => {
|
|
25
|
-
if (code !== null && allowedCodes.includes(code))
|
|
26
|
-
resolve();
|
|
27
|
-
else
|
|
28
|
-
reject(new Error(`terraform exited with code ${code}`));
|
|
29
|
-
});
|
|
30
|
-
proc.on('error', (err) => {
|
|
31
|
-
if (err.code === 'ENOENT') {
|
|
32
|
-
reject(new Error('terraform binary not found. Install Terraform: https://developer.hashicorp.com/terraform/install'));
|
|
33
|
-
}
|
|
34
|
-
else {
|
|
35
|
-
reject(err);
|
|
36
|
-
}
|
|
37
|
-
});
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
/** Check that terraform files exist in the project. Exits with an error if not. */
|
|
41
|
-
async function requireTerraformFiles(projectPath) {
|
|
42
|
-
const files = await storage.readTerraformFiles(projectPath);
|
|
43
|
-
if (Object.keys(files).length === 0) {
|
|
44
|
-
console.error('No Terraform files found in terraform/ directory.');
|
|
45
|
-
console.error(`Run first: tstudio hcl generate "${projectPath}"`);
|
|
46
|
-
process.exit(1);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
export function makeTerraformCommand() {
|
|
50
|
-
const cmd = new Command('terraform').alias('tf').description('Run Terraform commands against a project');
|
|
51
|
-
// ─── init ──────────────────────────────────────────────────────────────────
|
|
52
|
-
cmd
|
|
53
|
-
.command('init [path]')
|
|
54
|
-
.description('Run terraform init in the project\'s terraform/ directory')
|
|
55
|
-
.action(async (projectPath) => {
|
|
56
|
-
const resolved = resolveProjectPath(projectPath);
|
|
57
|
-
const dir = tfDir(resolved);
|
|
58
|
-
if (!existsSync(dir)) {
|
|
59
|
-
console.error(`terraform/ directory not found at: ${dir}`);
|
|
60
|
-
console.error('Run `tstudio hcl generate <path>` first.');
|
|
61
|
-
process.exit(1);
|
|
62
|
-
}
|
|
63
|
-
await runTerraform(dir, ['init']).catch((err) => {
|
|
64
|
-
console.error(err.message);
|
|
65
|
-
process.exit(1);
|
|
66
|
-
});
|
|
67
|
-
});
|
|
68
|
-
// ─── validate ──────────────────────────────────────────────────────────────
|
|
69
|
-
cmd
|
|
70
|
-
.command('validate [path]')
|
|
71
|
-
.description('Run terraform validate in the project\'s terraform/ directory')
|
|
72
|
-
.action(async (projectPath) => {
|
|
73
|
-
const resolved = resolveProjectPath(projectPath);
|
|
74
|
-
const dir = tfDir(resolved);
|
|
75
|
-
await runTerraform(dir, ['validate']).catch((err) => {
|
|
76
|
-
console.error(err.message);
|
|
77
|
-
process.exit(1);
|
|
78
|
-
});
|
|
79
|
-
});
|
|
80
|
-
// ─── plan ──────────────────────────────────────────────────────────────────
|
|
81
|
-
cmd
|
|
82
|
-
.command('plan [path]')
|
|
83
|
-
.description('Run terraform plan')
|
|
84
|
-
.option('--out <planFile>', 'Save plan to file (relative to terraform/ dir)')
|
|
85
|
-
.action(async (projectPath, options) => {
|
|
86
|
-
const resolved = resolveProjectPath(projectPath);
|
|
87
|
-
await requireTerraformFiles(resolved);
|
|
88
|
-
const dir = tfDir(resolved);
|
|
89
|
-
const args = ['plan'];
|
|
90
|
-
if (options.out)
|
|
91
|
-
args.push('-out', options.out);
|
|
92
|
-
// Exit code 2 = changes present (not an error)
|
|
93
|
-
await runTerraform(dir, args, [0, 2]).catch((err) => {
|
|
94
|
-
console.error(err.message);
|
|
95
|
-
process.exit(1);
|
|
96
|
-
});
|
|
97
|
-
});
|
|
98
|
-
// ─── apply ─────────────────────────────────────────────────────────────────
|
|
99
|
-
cmd
|
|
100
|
-
.command('apply [path]')
|
|
101
|
-
.description('Run terraform apply (auto-approves)')
|
|
102
|
-
.option('--plan <planFile>', 'Apply a saved plan file instead of planning inline')
|
|
103
|
-
.action(async (projectPath, options) => {
|
|
104
|
-
const resolved = resolveProjectPath(projectPath);
|
|
105
|
-
await requireTerraformFiles(resolved);
|
|
106
|
-
const dir = tfDir(resolved);
|
|
107
|
-
const args = options.plan
|
|
108
|
-
? ['apply', '-auto-approve', options.plan]
|
|
109
|
-
: ['apply', '-auto-approve'];
|
|
110
|
-
await runTerraform(dir, args).catch((err) => {
|
|
111
|
-
console.error(err.message);
|
|
112
|
-
process.exit(1);
|
|
113
|
-
});
|
|
114
|
-
});
|
|
115
|
-
// ─── destroy ───────────────────────────────────────────────────────────────
|
|
116
|
-
cmd
|
|
117
|
-
.command('destroy [path]')
|
|
118
|
-
.description('Run terraform destroy (auto-approves)')
|
|
119
|
-
.action(async (projectPath) => {
|
|
120
|
-
const resolved = resolveProjectPath(projectPath);
|
|
121
|
-
const dir = tfDir(resolved);
|
|
122
|
-
await runTerraform(dir, ['destroy', '-auto-approve']).catch((err) => {
|
|
123
|
-
console.error(err.message);
|
|
124
|
-
process.exit(1);
|
|
125
|
-
});
|
|
126
|
-
});
|
|
127
|
-
// ─── status ────────────────────────────────────────────────────────────────
|
|
128
|
-
cmd
|
|
129
|
-
.command('status [path]')
|
|
130
|
-
.description('Show deployment status by reading terraform state (terraform show -json)')
|
|
131
|
-
.action(async (projectPath) => {
|
|
132
|
-
const resolved = resolveProjectPath(projectPath);
|
|
133
|
-
const stored = await storage.loadProject(resolved);
|
|
134
|
-
const project = Project.fromLoaded(toLoadedProject(stored));
|
|
135
|
-
const dir = tfDir(resolved);
|
|
136
|
-
// Capture JSON output from terraform show
|
|
137
|
-
const output = await new Promise((resolve, reject) => {
|
|
138
|
-
const chunks = [];
|
|
139
|
-
const proc = spawn('terraform', ['show', '-json'], {
|
|
140
|
-
cwd: dir,
|
|
141
|
-
shell: process.platform === 'win32',
|
|
142
|
-
});
|
|
143
|
-
proc.stdout.on('data', (d) => chunks.push(d));
|
|
144
|
-
proc.stderr.on('data', (d) => process.stderr.write(d));
|
|
145
|
-
proc.on('close', (code) => {
|
|
146
|
-
if (code === 0)
|
|
147
|
-
resolve(Buffer.concat(chunks).toString('utf8'));
|
|
148
|
-
else
|
|
149
|
-
reject(new Error(`terraform show exited with code ${code}`));
|
|
150
|
-
});
|
|
151
|
-
proc.on('error', (err) => {
|
|
152
|
-
if (err.code === 'ENOENT') {
|
|
153
|
-
reject(new Error('terraform binary not found.'));
|
|
154
|
-
}
|
|
155
|
-
else {
|
|
156
|
-
reject(err);
|
|
157
|
-
}
|
|
158
|
-
});
|
|
159
|
-
}).catch((err) => {
|
|
160
|
-
console.error(err.message);
|
|
161
|
-
process.exit(1);
|
|
162
|
-
});
|
|
163
|
-
let state;
|
|
164
|
-
try {
|
|
165
|
-
state = JSON.parse(output);
|
|
166
|
-
}
|
|
167
|
-
catch {
|
|
168
|
-
console.log('No state found (project not yet deployed).');
|
|
169
|
-
return;
|
|
170
|
-
}
|
|
171
|
-
const values = state['values']?.['root_module'];
|
|
172
|
-
const tfResources = values?.['resources'] ?? [];
|
|
173
|
-
if (tfResources.length === 0) {
|
|
174
|
-
console.log('No deployed resources found in state.');
|
|
175
|
-
return;
|
|
176
|
-
}
|
|
177
|
-
// Build a map of terraform address → node label for display
|
|
178
|
-
const addressToLabel = new Map();
|
|
179
|
-
for (const node of project.nodes) {
|
|
180
|
-
if (node.data.terraformName && node.type && !node.type.startsWith('_')) {
|
|
181
|
-
const tfType = node.type.split('/').pop() ?? node.type;
|
|
182
|
-
const addr = `${tfType}.${node.data.terraformName}`;
|
|
183
|
-
addressToLabel.set(addr, node.data.label ?? node.data.terraformName ?? addr);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
const colAddr = 'Address'.padEnd(55);
|
|
187
|
-
const colStatus = 'Status';
|
|
188
|
-
console.log(`${colAddr} ${colStatus}`);
|
|
189
|
-
console.log(`${'-'.repeat(55)} ${'-'.repeat(10)}`);
|
|
190
|
-
for (const res of tfResources) {
|
|
191
|
-
const addr = String(res['address'] ?? '');
|
|
192
|
-
const label = addressToLabel.get(addr);
|
|
193
|
-
const display = label ? `${addr} (${label})` : addr;
|
|
194
|
-
console.log(`${display.padEnd(55)} deployed`);
|
|
195
|
-
}
|
|
196
|
-
});
|
|
197
|
-
return cmd;
|
|
198
|
-
}
|
|
199
|
-
//# sourceMappingURL=terraform.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"terraform.js","sourceRoot":"","sources":["../../src/commands/terraform.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
DELETED
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAChF,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC"}
|
package/dist/index.js
DELETED
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,yDAAyD;AACzD,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAChF,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC"}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* CLI-specific platform utilities.
|
|
3
|
-
*
|
|
4
|
-
* Project file I/O is handled by NodeProjectStorage from @terrastudio/platform-node.
|
|
5
|
-
* This module provides the shared storage instance and CLI-only utilities such as
|
|
6
|
-
* loadRegistry / loadValidator (plugin loading — desktop uses a reactive registry instead).
|
|
7
|
-
*/
|
|
8
|
-
import { NodeProjectStorage } from '@terrastudio/platform-node';
|
|
9
|
-
import { PluginRegistry } from '@terrastudio/core';
|
|
10
|
-
import type { ProviderId, StoredProjectData } from '@terrastudio/types';
|
|
11
|
-
import type { ProjectValidatorContext, LoadedProject } from '@terrastudio/project';
|
|
12
|
-
/** Shared storage instance for all CLI commands. */
|
|
13
|
-
export declare const storage: NodeProjectStorage;
|
|
14
|
-
/**
|
|
15
|
-
* Convert a StoredProjectData (from IProjectStorage) to LoadedProject (for Project.fromLoaded).
|
|
16
|
-
* The projectConfig field is cast — the CLI trusts that on-disk data matches the expected shape.
|
|
17
|
-
*/
|
|
18
|
-
export declare function toLoadedProject(stored: StoredProjectData): LoadedProject;
|
|
19
|
-
/**
|
|
20
|
-
* Load plugins for the given providers and return the fully loaded PluginRegistry.
|
|
21
|
-
* Use this when you need the registry for HCL generation (connectionRules, schemas, pipeline).
|
|
22
|
-
*/
|
|
23
|
-
export declare function loadRegistry(providerIds: ProviderId[]): Promise<PluginRegistry>;
|
|
24
|
-
/**
|
|
25
|
-
* Load plugins for the given providers and return a ProjectValidatorContext.
|
|
26
|
-
* Use this for mutation validation (addNode, addEdge, moveNode).
|
|
27
|
-
*/
|
|
28
|
-
export declare function loadValidator(providerIds: ProviderId[]): Promise<ProjectValidatorContext>;
|
|
29
|
-
//# sourceMappingURL=node-io.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"node-io.d.ts","sourceRoot":"","sources":["../../src/platform/node-io.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,cAAc,EAAqB,MAAM,mBAAmB,CAAC;AACtE,OAAO,KAAK,EAAE,UAAU,EAAkB,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACxF,OAAO,KAAK,EAAE,uBAAuB,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAEnF,oDAAoD;AACpD,eAAO,MAAM,OAAO,oBAA2B,CAAC;AAEhD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,iBAAiB,GAAG,aAAa,CAExE;AAqBD;;;GAGG;AACH,wBAAsB,YAAY,CAAC,WAAW,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,cAAc,CAAC,CAKrF;AAED;;;GAGG;AACH,wBAAsB,aAAa,CAAC,WAAW,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAQ/F"}
|
package/dist/platform/node-io.js
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* CLI-specific platform utilities.
|
|
3
|
-
*
|
|
4
|
-
* Project file I/O is handled by NodeProjectStorage from @terrastudio/platform-node.
|
|
5
|
-
* This module provides the shared storage instance and CLI-only utilities such as
|
|
6
|
-
* loadRegistry / loadValidator (plugin loading — desktop uses a reactive registry instead).
|
|
7
|
-
*/
|
|
8
|
-
import { NodeProjectStorage } from '@terrastudio/platform-node';
|
|
9
|
-
import { PluginRegistry, EdgeRuleValidator } from '@terrastudio/core';
|
|
10
|
-
/** Shared storage instance for all CLI commands. */
|
|
11
|
-
export const storage = new NodeProjectStorage();
|
|
12
|
-
/**
|
|
13
|
-
* Convert a StoredProjectData (from IProjectStorage) to LoadedProject (for Project.fromLoaded).
|
|
14
|
-
* The projectConfig field is cast — the CLI trusts that on-disk data matches the expected shape.
|
|
15
|
-
*/
|
|
16
|
-
export function toLoadedProject(stored) {
|
|
17
|
-
return stored;
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* Register lazy plugin loaders for the given provider IDs onto a PluginRegistry.
|
|
21
|
-
*/
|
|
22
|
-
function registerPlugins(registry, providerIds) {
|
|
23
|
-
for (const providerId of providerIds) {
|
|
24
|
-
if (providerId === 'azurerm') {
|
|
25
|
-
registry.registerLazyPlugin('azurerm', () => import('@terrastudio/plugin-azure-networking'));
|
|
26
|
-
registry.registerLazyPlugin('azurerm', () => import('@terrastudio/plugin-azure-compute'));
|
|
27
|
-
registry.registerLazyPlugin('azurerm', () => import('@terrastudio/plugin-azure-storage'));
|
|
28
|
-
registry.registerLazyPlugin('azurerm', () => import('@terrastudio/plugin-azure-database'));
|
|
29
|
-
registry.registerLazyPlugin('azurerm', () => import('@terrastudio/plugin-azure-monitoring'));
|
|
30
|
-
registry.registerLazyPlugin('azurerm', () => import('@terrastudio/plugin-azure-security'));
|
|
31
|
-
}
|
|
32
|
-
else if (providerId === 'aws') {
|
|
33
|
-
registry.registerLazyPlugin('aws', () => import('@terrastudio/plugin-aws-networking'));
|
|
34
|
-
registry.registerLazyPlugin('aws', () => import('@terrastudio/plugin-aws-compute'));
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Load plugins for the given providers and return the fully loaded PluginRegistry.
|
|
40
|
-
* Use this when you need the registry for HCL generation (connectionRules, schemas, pipeline).
|
|
41
|
-
*/
|
|
42
|
-
export async function loadRegistry(providerIds) {
|
|
43
|
-
const registry = new PluginRegistry();
|
|
44
|
-
registerPlugins(registry, providerIds);
|
|
45
|
-
await registry.loadPluginsForProviders(providerIds);
|
|
46
|
-
return registry;
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Load plugins for the given providers and return a ProjectValidatorContext.
|
|
50
|
-
* Use this for mutation validation (addNode, addEdge, moveNode).
|
|
51
|
-
*/
|
|
52
|
-
export async function loadValidator(providerIds) {
|
|
53
|
-
const registry = await loadRegistry(providerIds);
|
|
54
|
-
const rules = registry.getConnectionRules();
|
|
55
|
-
const edgeValidator = new EdgeRuleValidator(rules);
|
|
56
|
-
return {
|
|
57
|
-
getSchema: (typeId) => registry.getResourceSchema(typeId),
|
|
58
|
-
edgeValidator,
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
//# sourceMappingURL=node-io.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"node-io.js","sourceRoot":"","sources":["../../src/platform/node-io.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAItE,oDAAoD;AACpD,MAAM,CAAC,MAAM,OAAO,GAAG,IAAI,kBAAkB,EAAE,CAAC;AAEhD;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,MAAyB;IACvD,OAAO,MAAkC,CAAC;AAC5C,CAAC;AAED;;GAEG;AACH,SAAS,eAAe,CAAC,QAAwB,EAAE,WAAyB;IAC1E,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;QACrC,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;YAC7B,QAAQ,CAAC,kBAAkB,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,sCAAsC,CAAC,CAAC,CAAC;YAC7F,QAAQ,CAAC,kBAAkB,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,mCAAmC,CAAC,CAAC,CAAC;YAC1F,QAAQ,CAAC,kBAAkB,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,mCAAmC,CAAC,CAAC,CAAC;YAC1F,QAAQ,CAAC,kBAAkB,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,oCAAoC,CAAC,CAAC,CAAC;YAC3F,QAAQ,CAAC,kBAAkB,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,sCAAsC,CAAC,CAAC,CAAC;YAC7F,QAAQ,CAAC,kBAAkB,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,oCAAoC,CAAC,CAAC,CAAC;QAC7F,CAAC;aAAM,IAAI,UAAU,KAAK,KAAK,EAAE,CAAC;YAChC,QAAQ,CAAC,kBAAkB,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,oCAAoC,CAAC,CAAC,CAAC;YACvF,QAAQ,CAAC,kBAAkB,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,iCAAiC,CAAC,CAAC,CAAC;QACtF,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,WAAyB;IAC1D,MAAM,QAAQ,GAAG,IAAI,cAAc,EAAE,CAAC;IACtC,eAAe,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;IACvC,MAAM,QAAQ,CAAC,uBAAuB,CAAC,WAAW,CAAC,CAAC;IACpD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,WAAyB;IAC3D,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,WAAW,CAAC,CAAC;IACjD,MAAM,KAAK,GAAG,QAAQ,CAAC,kBAAkB,EAAE,CAAC;IAC5C,MAAM,aAAa,GAAG,IAAI,iBAAiB,CAAC,KAAK,CAAC,CAAC;IACnD,OAAO;QACL,SAAS,EAAE,CAAC,MAAsB,EAAE,EAAE,CAAC,QAAQ,CAAC,iBAAiB,CAAC,MAAM,CAAC;QACzE,aAAa;KACd,CAAC;AACJ,CAAC"}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Resolve the project path from an optional argument.
|
|
3
|
-
*
|
|
4
|
-
* If a path is provided, returns it as-is (resolved to absolute).
|
|
5
|
-
* If omitted, walks up from cwd looking for a directory containing a .tstudio file.
|
|
6
|
-
* Exits with an error if no project is found.
|
|
7
|
-
*/
|
|
8
|
-
export declare function resolveProjectPath(pathArg?: string): string;
|
|
9
|
-
//# sourceMappingURL=resolve-project.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-project.d.ts","sourceRoot":"","sources":["../../src/platform/resolve-project.ts"],"names":[],"mappings":"AAGA;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAuB3D"}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { existsSync, readdirSync } from 'node:fs';
|
|
2
|
-
import { resolve, dirname } from 'node:path';
|
|
3
|
-
/**
|
|
4
|
-
* Resolve the project path from an optional argument.
|
|
5
|
-
*
|
|
6
|
-
* If a path is provided, returns it as-is (resolved to absolute).
|
|
7
|
-
* If omitted, walks up from cwd looking for a directory containing a .tstudio file.
|
|
8
|
-
* Exits with an error if no project is found.
|
|
9
|
-
*/
|
|
10
|
-
export function resolveProjectPath(pathArg) {
|
|
11
|
-
if (pathArg) {
|
|
12
|
-
return resolve(pathArg);
|
|
13
|
-
}
|
|
14
|
-
// Walk up from cwd looking for a .tstudio file
|
|
15
|
-
let dir = resolve(process.cwd());
|
|
16
|
-
const root = dirname(dir) === dir ? dir : undefined; // filesystem root guard
|
|
17
|
-
while (true) {
|
|
18
|
-
if (hasTstudioFile(dir)) {
|
|
19
|
-
return dir;
|
|
20
|
-
}
|
|
21
|
-
const parent = dirname(dir);
|
|
22
|
-
if (parent === dir || parent === root) {
|
|
23
|
-
break;
|
|
24
|
-
}
|
|
25
|
-
dir = parent;
|
|
26
|
-
}
|
|
27
|
-
console.error('No .tstudio project found in current directory or any parent.');
|
|
28
|
-
console.error('Either run this command from a project directory, or pass the path explicitly.');
|
|
29
|
-
process.exit(1);
|
|
30
|
-
}
|
|
31
|
-
function hasTstudioFile(dir) {
|
|
32
|
-
if (!existsSync(dir))
|
|
33
|
-
return false;
|
|
34
|
-
try {
|
|
35
|
-
return readdirSync(dir).some((f) => f.endsWith('.tstudio'));
|
|
36
|
-
}
|
|
37
|
-
catch {
|
|
38
|
-
return false;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
//# sourceMappingURL=resolve-project.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-project.js","sourceRoot":"","sources":["../../src/platform/resolve-project.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAE7C;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAgB;IACjD,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1B,CAAC;IAED,+CAA+C;IAC/C,IAAI,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IACjC,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,wBAAwB;IAE7E,OAAO,IAAI,EAAE,CAAC;QACZ,IAAI,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC;YACxB,OAAO,GAAG,CAAC;QACb,CAAC;QACD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YACtC,MAAM;QACR,CAAC;QACD,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;IAED,OAAO,CAAC,KAAK,CAAC,+DAA+D,CAAC,CAAC;IAC/E,OAAO,CAAC,KAAK,CAAC,gFAAgF,CAAC,CAAC;IAChG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,SAAS,cAAc,CAAC,GAAW;IACjC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IACnC,IAAI,CAAC;QACH,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC;IAC9D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
|