@apso/cli 0.8.6 → 0.10.1
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/README.md +221 -1653
- package/dist/commands/config.d.ts +13 -0
- package/dist/commands/config.js +114 -0
- package/dist/commands/deploy.d.ts +11 -0
- package/dist/commands/deploy.js +141 -0
- package/dist/commands/dev.d.ts +15 -0
- package/dist/commands/dev.js +95 -0
- package/dist/commands/generate.d.ts +12 -0
- package/dist/commands/generate.js +179 -0
- package/dist/commands/init.d.ts +16 -0
- package/dist/commands/init.js +313 -0
- package/dist/commands/link.d.ts +11 -0
- package/dist/commands/link.js +139 -0
- package/dist/commands/login.d.ts +22 -0
- package/dist/commands/login.js +345 -0
- package/dist/commands/logout.d.ts +9 -0
- package/dist/commands/logout.js +38 -0
- package/dist/commands/logs.d.ts +10 -0
- package/dist/commands/logs.js +64 -0
- package/dist/commands/mcp/serve.d.ts +11 -0
- package/dist/commands/mcp/serve.js +818 -0
- package/dist/commands/migrate.d.ts +11 -0
- package/dist/commands/migrate.js +137 -0
- package/dist/commands/open.d.ts +10 -0
- package/dist/commands/open.js +79 -0
- package/dist/commands/projects.d.ts +10 -0
- package/dist/commands/projects.js +106 -0
- package/dist/commands/schema/diff.d.ts +7 -0
- package/dist/commands/schema/diff.js +63 -0
- package/dist/commands/schema/pull.d.ts +9 -0
- package/dist/commands/schema/pull.js +81 -0
- package/dist/commands/schema/push.d.ts +9 -0
- package/dist/commands/schema/push.js +97 -0
- package/dist/commands/schema/validate.d.ts +9 -0
- package/dist/commands/schema/validate.js +90 -0
- package/dist/commands/server/new.d.ts +2 -19
- package/dist/commands/server/new.js +6 -192
- package/dist/commands/server/scaffold.d.ts +2 -25
- package/dist/commands/server/scaffold.js +6 -312
- package/dist/commands/status.d.ts +7 -0
- package/dist/commands/status.js +53 -0
- package/dist/commands/unlink.d.ts +9 -0
- package/dist/commands/unlink.js +47 -0
- package/dist/commands/whoami.d.ts +10 -0
- package/dist/commands/whoami.js +97 -0
- package/dist/lib/api/client.js +1 -1
- package/dist/lib/api/services.js +3 -3
- package/dist/lib/api/types.d.ts +9 -2
- package/dist/lib/apsorc-parser.d.ts +0 -19
- package/dist/lib/apsorc-parser.js +2 -73
- package/dist/lib/guards.d.ts +3 -20
- package/dist/lib/guards.js +1 -113
- package/dist/lib/index.d.ts +1 -9
- package/dist/lib/index.js +1 -18
- package/dist/lib/migrate/entity-generator.d.ts +14 -0
- package/dist/lib/migrate/entity-generator.js +7 -0
- package/dist/lib/migrate/sandbox.d.ts +42 -0
- package/dist/lib/migrate/sandbox.js +337 -0
- package/dist/lib/migrate/snapshot.d.ts +80 -0
- package/dist/lib/migrate/snapshot.js +100 -0
- package/dist/lib/templates/python/models/model-col-datetime.eta +1 -1
- package/dist/lib/templates/python/models/model-col-string.eta +1 -1
- package/dist/lib/templates/python/models/model-col-text.eta +1 -1
- package/dist/lib/templates/python/models/model-col-varchar.eta +1 -1
- package/dist/lib/utils/field.d.ts +12 -0
- package/dist/lib/utils/field.js +80 -1
- package/dist/lib/utils/schema-convert.d.ts +71 -0
- package/dist/lib/utils/schema-convert.js +169 -0
- package/dist/lib/utils/spinner.d.ts +19 -0
- package/dist/lib/utils/spinner.js +87 -0
- package/dist/lib/utils/template.d.ts +12 -0
- package/dist/lib/utils/template.js +49 -0
- package/npm-shrinkwrap.json +18118 -0
- package/oclif.manifest.json +547 -41
- package/package.json +26 -5
- package/dist/lib/controller.d.ts +0 -10
- package/dist/lib/controller.js +0 -99
- package/dist/lib/dto.d.ts +0 -16
- package/dist/lib/dto.js +0 -92
- package/dist/lib/entity.d.ts +0 -19
- package/dist/lib/entity.js +0 -56
- package/dist/lib/enums.d.ts +0 -6
- package/dist/lib/enums.js +0 -28
- package/dist/lib/gql-dto.d.ts +0 -3
- package/dist/lib/gql-dto.js +0 -39
- package/dist/lib/index-module.d.ts +0 -13
- package/dist/lib/index-module.js +0 -26
- package/dist/lib/module.d.ts +0 -13
- package/dist/lib/module.js +0 -42
- package/dist/lib/service.d.ts +0 -2
- package/dist/lib/service.js +0 -61
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const core_1 = require("@oclif/core");
|
|
5
|
+
const base_command_1 = tslib_1.__importDefault(require("../../lib/base-command"));
|
|
6
|
+
const config_1 = require("../../lib/config");
|
|
7
|
+
const services_1 = require("../../lib/api/services");
|
|
8
|
+
const apsorc_parser_1 = require("../../lib/apsorc-parser");
|
|
9
|
+
const schema_convert_1 = require("../../lib/utils/schema-convert");
|
|
10
|
+
class SchemaValidate extends base_command_1.default {
|
|
11
|
+
async run() {
|
|
12
|
+
var _a;
|
|
13
|
+
const { flags } = await this.parse(SchemaValidate);
|
|
14
|
+
// Parse .apsorc
|
|
15
|
+
let parsed;
|
|
16
|
+
try {
|
|
17
|
+
parsed = (0, apsorc_parser_1.parseApsorc)();
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
21
|
+
this.error(`Failed to parse .apsorc: ${msg}`);
|
|
22
|
+
}
|
|
23
|
+
// Convert to platform schema format
|
|
24
|
+
const schema = (0, schema_convert_1.apsorcToServiceSchema)(parsed);
|
|
25
|
+
// Count stats
|
|
26
|
+
const entityCount = schema.entities.length;
|
|
27
|
+
let fieldCount = 0;
|
|
28
|
+
let relationshipCount = 0;
|
|
29
|
+
for (const entity of schema.entities) {
|
|
30
|
+
fieldCount += entity.fields.length;
|
|
31
|
+
relationshipCount += ((_a = entity.relationships) === null || _a === void 0 ? void 0 : _a.length) || 0;
|
|
32
|
+
}
|
|
33
|
+
// Local validation
|
|
34
|
+
const errors = [];
|
|
35
|
+
for (const entity of schema.entities) {
|
|
36
|
+
if (!entity.name || entity.name.trim() === "") {
|
|
37
|
+
errors.push("Entity found with empty name");
|
|
38
|
+
}
|
|
39
|
+
if (entity.relationships) {
|
|
40
|
+
for (const rel of entity.relationships) {
|
|
41
|
+
const targetExists = schema.entities.some((e) => e.name === rel.target);
|
|
42
|
+
if (!targetExists) {
|
|
43
|
+
errors.push(`Entity "${entity.name}": relationship target "${rel.target}" does not reference an existing entity`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
// Server validation if linked and not --local
|
|
49
|
+
const isLinked = config_1.projectLink.exists();
|
|
50
|
+
const isAuthenticated = config_1.credentials.isValid();
|
|
51
|
+
if (!flags.local && isLinked && isAuthenticated) {
|
|
52
|
+
const link = config_1.projectLink.read();
|
|
53
|
+
try {
|
|
54
|
+
const result = await services_1.schemaApi.validate(link.workspaceSlug, link.serviceSlug, schema);
|
|
55
|
+
if (!result.valid) {
|
|
56
|
+
errors.push(...result.errors);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
61
|
+
this.warn(`Server validation failed: ${msg}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// Print results
|
|
65
|
+
this.log(`Schema: ${entityCount} entities, ${fieldCount} fields, ${relationshipCount} relationships`);
|
|
66
|
+
if (errors.length > 0) {
|
|
67
|
+
this.log("");
|
|
68
|
+
this.log("Errors:");
|
|
69
|
+
for (const err of errors) {
|
|
70
|
+
this.log(` - ${err}`);
|
|
71
|
+
}
|
|
72
|
+
this.error(`Validation failed with ${errors.length} error(s).`);
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
this.log("Validation passed.");
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
SchemaValidate.description = "Validate the local .apsorc schema";
|
|
80
|
+
SchemaValidate.examples = [
|
|
81
|
+
`$ apso schema validate`,
|
|
82
|
+
`$ apso schema validate --local`,
|
|
83
|
+
];
|
|
84
|
+
SchemaValidate.flags = {
|
|
85
|
+
local: core_1.Flags.boolean({
|
|
86
|
+
description: "Skip server validation even if linked",
|
|
87
|
+
default: false,
|
|
88
|
+
}),
|
|
89
|
+
};
|
|
90
|
+
exports.default = SchemaValidate;
|
|
@@ -1,25 +1,8 @@
|
|
|
1
1
|
import BaseCommand from "../../lib/base-command";
|
|
2
|
-
import { TargetLanguage } from "../../lib/types";
|
|
3
2
|
export default class New extends BaseCommand {
|
|
3
|
+
static hidden: boolean;
|
|
4
4
|
static description: string;
|
|
5
5
|
static examples: string[];
|
|
6
|
-
|
|
7
|
-
static flags: {
|
|
8
|
-
name: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
|
|
9
|
-
type: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
|
|
10
|
-
language: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
|
|
11
|
-
};
|
|
12
|
-
static args: {
|
|
13
|
-
name: import("@oclif/core/lib/interfaces/parser").Arg<string | undefined, Record<string, unknown>>;
|
|
14
|
-
};
|
|
15
|
-
installModules(projectPath: string): Promise<void>;
|
|
16
|
-
formatApp(projectPath: string): Promise<void>;
|
|
17
|
-
startApp(projectPath: string): Promise<void>;
|
|
18
|
-
cloneTemplate(projectPath: string, language: TargetLanguage): Promise<void>;
|
|
19
|
-
validateFlags(): Promise<{
|
|
20
|
-
projectName: string;
|
|
21
|
-
apiType: string;
|
|
22
|
-
language: TargetLanguage;
|
|
23
|
-
}>;
|
|
6
|
+
static strict: boolean;
|
|
24
7
|
run(): Promise<void>;
|
|
25
8
|
}
|
|
@@ -1,201 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
|
-
const core_1 = require("@oclif/core");
|
|
5
|
-
const child_process_1 = require("child_process");
|
|
6
|
-
const fs = tslib_1.__importStar(require("fs"));
|
|
7
|
-
const shelljs_1 = tslib_1.__importDefault(require("shelljs"));
|
|
8
|
-
const inquirer_1 = tslib_1.__importDefault(require("inquirer"));
|
|
9
4
|
const base_command_1 = tslib_1.__importDefault(require("../../lib/base-command"));
|
|
10
|
-
const path = tslib_1.__importStar(require("path"));
|
|
11
|
-
const TEMPLATE_REPOS = {
|
|
12
|
-
typescript: "https://github.com/apsoai/service-template.git",
|
|
13
|
-
python: "https://github.com/apsoai/service-template-python.git",
|
|
14
|
-
go: "https://github.com/apsoai/service-template-go.git",
|
|
15
|
-
};
|
|
16
|
-
const PROJECT_NAME_PATTERN = /^[A-Za-z][\w-]*$/;
|
|
17
5
|
class New extends base_command_1.default {
|
|
18
|
-
constructor() {
|
|
19
|
-
super(...arguments);
|
|
20
|
-
this.CURR_DIR = process.cwd();
|
|
21
|
-
}
|
|
22
|
-
async installModules(projectPath) {
|
|
23
|
-
this.log("Installing modules...");
|
|
24
|
-
await this.runNpmCommand(["install", "--force", "--prefix", projectPath]);
|
|
25
|
-
}
|
|
26
|
-
async formatApp(projectPath) {
|
|
27
|
-
this.log("Formatting code...");
|
|
28
|
-
shelljs_1.default.cd(projectPath);
|
|
29
|
-
await this.runNpmCommand(["run", "format", "--prefix", projectPath]);
|
|
30
|
-
}
|
|
31
|
-
async startApp(projectPath) {
|
|
32
|
-
return new Promise((resolve, reject) => {
|
|
33
|
-
const isWindows = process.platform === "win32";
|
|
34
|
-
const command = isWindows ? "npm.cmd" : "npm";
|
|
35
|
-
const args = ["start"];
|
|
36
|
-
const child = (0, child_process_1.spawn)(command, args, {
|
|
37
|
-
cwd: projectPath,
|
|
38
|
-
stdio: "inherit",
|
|
39
|
-
shell: isWindows,
|
|
40
|
-
});
|
|
41
|
-
child.on("close", (code) => {
|
|
42
|
-
if (code !== 0) {
|
|
43
|
-
reject({
|
|
44
|
-
command: `${command} ${args.join(" ")}`,
|
|
45
|
-
});
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
resolve();
|
|
49
|
-
});
|
|
50
|
-
child.on("error", (err) => {
|
|
51
|
-
this.log(`Error starting app: ${err.message}`);
|
|
52
|
-
reject(err);
|
|
53
|
-
});
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
async cloneTemplate(projectPath, language) {
|
|
57
|
-
const repoUrl = TEMPLATE_REPOS[language];
|
|
58
|
-
this.log(`Cloning ${language} service template...`);
|
|
59
|
-
// Create directory if it doesn't exist
|
|
60
|
-
if (fs.existsSync(projectPath)) {
|
|
61
|
-
this.error(`Directory already exists: ${projectPath}`);
|
|
62
|
-
}
|
|
63
|
-
else {
|
|
64
|
-
try {
|
|
65
|
-
fs.mkdirSync(projectPath, { recursive: true });
|
|
66
|
-
}
|
|
67
|
-
catch (error) {
|
|
68
|
-
this.error(`Failed to create directory: ${error.message}`);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
// Use quoted paths to prevent command injection
|
|
72
|
-
const cloneResult = shelljs_1.default.exec(`git clone --depth=1 --branch=main "${repoUrl}" "${projectPath}"`, { silent: true });
|
|
73
|
-
// Check if the command failed
|
|
74
|
-
if (cloneResult.code !== 0) {
|
|
75
|
-
// Clean up the failed directory
|
|
76
|
-
shelljs_1.default.rm("-rf", projectPath);
|
|
77
|
-
this.error(`Failed to clone the template repository from GitHub.\n` +
|
|
78
|
-
`Error Output:\n${cloneResult.stderr}\n\n` +
|
|
79
|
-
`Please check your network connection and ensure the repository exists at ${repoUrl}`);
|
|
80
|
-
}
|
|
81
|
-
// If clone was successful, proceed to remove the .git directory using safe shelljs method
|
|
82
|
-
shelljs_1.default.rm("-rf", path.join(projectPath, ".git"));
|
|
83
|
-
}
|
|
84
|
-
async validateFlags() {
|
|
85
|
-
var _a;
|
|
86
|
-
const { flags } = await this.parse(New);
|
|
87
|
-
let projectName = flags.name;
|
|
88
|
-
let apiType = (_a = flags.type) === null || _a === void 0 ? void 0 : _a.toLowerCase();
|
|
89
|
-
let language = flags.language;
|
|
90
|
-
// Prompt for project name if not provided
|
|
91
|
-
if (!projectName) {
|
|
92
|
-
const response = await inquirer_1.default.prompt([
|
|
93
|
-
{
|
|
94
|
-
type: "input",
|
|
95
|
-
name: "projectName",
|
|
96
|
-
message: "Enter your project name:",
|
|
97
|
-
validate: (input) => {
|
|
98
|
-
if (!input.trim()) {
|
|
99
|
-
return "Project name is required";
|
|
100
|
-
}
|
|
101
|
-
if (!PROJECT_NAME_PATTERN.test(input)) {
|
|
102
|
-
return "Project name must start with a letter and contain only letters, numbers, hyphens, and underscores";
|
|
103
|
-
}
|
|
104
|
-
return true;
|
|
105
|
-
},
|
|
106
|
-
},
|
|
107
|
-
]);
|
|
108
|
-
projectName = response.projectName;
|
|
109
|
-
}
|
|
110
|
-
// Validate project name format (security: prevent command injection and path traversal)
|
|
111
|
-
if (!projectName || !PROJECT_NAME_PATTERN.test(projectName)) {
|
|
112
|
-
this.error("Project name must start with a letter and contain only letters, numbers, hyphens, and underscores");
|
|
113
|
-
}
|
|
114
|
-
if (!apiType) {
|
|
115
|
-
apiType = "rest";
|
|
116
|
-
}
|
|
117
|
-
if (!["rest", "graphql"].includes(apiType)) {
|
|
118
|
-
this.error("`apiType` must be 'rest' or 'graphql'");
|
|
119
|
-
}
|
|
120
|
-
// Prompt for language if not provided
|
|
121
|
-
if (!language) {
|
|
122
|
-
const response = await inquirer_1.default.prompt([
|
|
123
|
-
{
|
|
124
|
-
type: "list",
|
|
125
|
-
name: "language",
|
|
126
|
-
message: "Select your target language:",
|
|
127
|
-
choices: [
|
|
128
|
-
{ name: "TypeScript", value: "typescript" },
|
|
129
|
-
{ name: "Python", value: "python" },
|
|
130
|
-
{ name: "Go", value: "go" },
|
|
131
|
-
],
|
|
132
|
-
default: "typescript",
|
|
133
|
-
},
|
|
134
|
-
]);
|
|
135
|
-
language = response.language;
|
|
136
|
-
}
|
|
137
|
-
return { projectName: projectName, apiType, language };
|
|
138
|
-
}
|
|
139
6
|
async run() {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
this.error("git is required but not found. Please install git and try again.");
|
|
143
|
-
}
|
|
144
|
-
this.log("Initializing New Apso Server...");
|
|
145
|
-
const { projectName, language } = await this.validateFlags();
|
|
146
|
-
const projectPath = path.join(this.CURR_DIR, projectName);
|
|
147
|
-
// Validate the resolved path is within current directory (prevent path traversal)
|
|
148
|
-
const resolvedPath = path.resolve(projectPath);
|
|
149
|
-
if (!resolvedPath.startsWith(path.resolve(this.CURR_DIR))) {
|
|
150
|
-
this.error("Invalid project name: path traversal detected");
|
|
151
|
-
}
|
|
152
|
-
await this.cloneTemplate(projectPath, language);
|
|
153
|
-
// Language-specific setup
|
|
154
|
-
switch (language) {
|
|
155
|
-
case "typescript": {
|
|
156
|
-
if (shelljs_1.default.which("npm")) {
|
|
157
|
-
await this.installModules(projectPath);
|
|
158
|
-
await this.formatApp(projectPath);
|
|
159
|
-
}
|
|
160
|
-
else {
|
|
161
|
-
this.log("Warning: npm not found. Skipping module installation.");
|
|
162
|
-
}
|
|
163
|
-
break;
|
|
164
|
-
}
|
|
165
|
-
case "python": {
|
|
166
|
-
this.log("Python project created. Run 'pip install -e .[dev]' to install dependencies.");
|
|
167
|
-
break;
|
|
168
|
-
}
|
|
169
|
-
case "go": {
|
|
170
|
-
this.log("Go project created. Run 'go mod tidy' to install dependencies.");
|
|
171
|
-
break;
|
|
172
|
-
}
|
|
173
|
-
// No default
|
|
174
|
-
}
|
|
175
|
-
this.log(`\nProject created at ${projectPath}`);
|
|
176
|
-
this.log(`Language: ${language}`);
|
|
7
|
+
this.warn('"apso server new" is deprecated. Use "apso init" instead.');
|
|
8
|
+
await this.config.runCommand("init", this.argv);
|
|
177
9
|
}
|
|
178
10
|
}
|
|
179
|
-
New.
|
|
180
|
-
New.
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
`$ apso server new --name TestProject --language go`,
|
|
184
|
-
];
|
|
185
|
-
New.flags = {
|
|
186
|
-
name: core_1.Flags.string({
|
|
187
|
-
char: "n",
|
|
188
|
-
description: "name of application",
|
|
189
|
-
}),
|
|
190
|
-
type: core_1.Flags.string({
|
|
191
|
-
char: "t",
|
|
192
|
-
description: "api type (rest or graphql)",
|
|
193
|
-
}),
|
|
194
|
-
language: core_1.Flags.string({
|
|
195
|
-
char: "l",
|
|
196
|
-
description: "target language (typescript, python, go)",
|
|
197
|
-
options: ["typescript", "python", "go"],
|
|
198
|
-
}),
|
|
199
|
-
};
|
|
200
|
-
New.args = { name: core_1.Args.string() };
|
|
11
|
+
New.hidden = true;
|
|
12
|
+
New.description = "[Deprecated] Use 'apso init' instead";
|
|
13
|
+
New.examples = [`$ apso init`];
|
|
14
|
+
New.strict = false;
|
|
201
15
|
exports.default = New;
|
|
@@ -1,31 +1,8 @@
|
|
|
1
|
-
import { Entity, RelationshipMap } from "../../lib";
|
|
2
1
|
import BaseCommand from "../../lib/base-command";
|
|
3
2
|
export default class Scaffold extends BaseCommand {
|
|
3
|
+
static hidden: boolean;
|
|
4
4
|
static description: string;
|
|
5
5
|
static examples: string[];
|
|
6
|
-
static
|
|
7
|
-
help: import("@oclif/core/lib/interfaces").BooleanFlag<void>;
|
|
8
|
-
"skip-format": import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
9
|
-
language: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
|
|
10
|
-
};
|
|
11
|
-
static args: {};
|
|
12
|
-
scaffoldServer(options: {
|
|
13
|
-
dir: string;
|
|
14
|
-
entity: Entity;
|
|
15
|
-
relationshipMap: RelationshipMap;
|
|
16
|
-
apiType: string;
|
|
17
|
-
allEntities: Entity[];
|
|
18
|
-
}): Promise<void>;
|
|
19
|
-
setupRestFiles(dir: string, entity: Entity, relationshipMap: RelationshipMap, apiType: string, allEntities: Entity[]): Promise<void>;
|
|
20
|
-
setupGraphqlFiles(dir: string, entity: Entity, relationshipMap: RelationshipMap): Promise<void>;
|
|
6
|
+
static strict: boolean;
|
|
21
7
|
run(): Promise<void>;
|
|
22
|
-
/**
|
|
23
|
-
* Scaffolds TypeScript code using the existing code path (for backward compatibility)
|
|
24
|
-
*/
|
|
25
|
-
private scaffoldTypeScript;
|
|
26
|
-
/**
|
|
27
|
-
* Scaffolds code using the new generator system (for Python, Go, and future languages)
|
|
28
|
-
* Note: Sequential file operations are intentional to provide progress feedback
|
|
29
|
-
*/
|
|
30
|
-
private scaffoldWithGenerator;
|
|
31
8
|
}
|