@akanjs/cli 0.0.88 → 0.0.90
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/index.js +1248 -486
- package/package.json +1 -1
- package/pkgs/@akanjs/cli/src/application/application.command.d.ts +6 -6
- package/pkgs/@akanjs/cli/src/application/application.runner.d.ts +15 -7
- package/pkgs/@akanjs/cli/src/application/application.script.d.ts +46 -16
- package/pkgs/@akanjs/cli/src/cloud/cloud.command.d.ts +3 -0
- package/pkgs/@akanjs/cli/src/cloud/cloud.runner.d.ts +2 -0
- package/pkgs/@akanjs/cli/src/cloud/cloud.script.d.ts +3 -0
- package/pkgs/@akanjs/cli/src/library/library.command.d.ts +1 -1
- package/pkgs/@akanjs/cli/src/library/library.runner.d.ts +2 -0
- package/pkgs/@akanjs/cli/src/library/library.script.d.ts +2 -0
- package/pkgs/@akanjs/cli/src/module/module.prompt.d.ts +17 -8
- package/pkgs/@akanjs/cli/src/module/module.runner.d.ts +1 -3
- package/pkgs/@akanjs/cli/src/module/module.script.d.ts +1 -1
- package/pkgs/@akanjs/cli/src/package/package.command.d.ts +1 -1
- package/pkgs/@akanjs/cli/src/package/package.runner.d.ts +3 -2
- package/pkgs/@akanjs/cli/src/package/package.script.d.ts +3 -2
- package/pkgs/@akanjs/devkit/src/aiEditor.d.ts +14 -0
- package/pkgs/@akanjs/devkit/src/constants.d.ts +8 -1
- package/pkgs/@akanjs/devkit/src/executors.d.ts +24 -31
- package/pkgs/@akanjs/devkit/src/getRelatedCnsts.d.ts +52 -8
- package/pkgs/@akanjs/devkit/src/index.d.ts +0 -1
- package/src/templates/workspaceRoot/package.json.template +5 -0
- package/pkgs/@akanjs/devkit/src/installExternalLib.d.ts +0 -2
- /package/pkgs/@akanjs/cli/src/{package/page → page}/page.command.d.ts +0 -0
- /package/pkgs/@akanjs/cli/src/{package/page → page}/page.runner.d.ts +0 -0
- /package/pkgs/@akanjs/cli/src/{package/page → page}/page.script.d.ts +0 -0
package/index.js
CHANGED
|
@@ -58,8 +58,8 @@ var createTunnel = async ({ app, environment, port = 27017 }) => {
|
|
|
58
58
|
};
|
|
59
59
|
|
|
60
60
|
// pkgs/@akanjs/devkit/src/getCredentials.ts
|
|
61
|
-
var import_fs = __toESM(require("fs")
|
|
62
|
-
var import_js_yaml = __toESM(require("js-yaml")
|
|
61
|
+
var import_fs = __toESM(require("fs"));
|
|
62
|
+
var import_js_yaml = __toESM(require("js-yaml"));
|
|
63
63
|
var getCredentials = (app, environment) => {
|
|
64
64
|
const secret = import_js_yaml.default.load(
|
|
65
65
|
import_fs.default.readFileSync(`${app.workspace.workspaceRoot}/infra/app/values/${app.name}-secret.yaml`, "utf-8")
|
|
@@ -68,9 +68,9 @@ var getCredentials = (app, environment) => {
|
|
|
68
68
|
};
|
|
69
69
|
|
|
70
70
|
// pkgs/@akanjs/devkit/src/uploadRelease.ts
|
|
71
|
-
var import_axios = __toESM(require("axios")
|
|
72
|
-
var import_form_data = __toESM(require("form-data")
|
|
73
|
-
var import_fs2 = __toESM(require("fs")
|
|
71
|
+
var import_axios = __toESM(require("axios"));
|
|
72
|
+
var import_form_data = __toESM(require("form-data"));
|
|
73
|
+
var import_fs2 = __toESM(require("fs"));
|
|
74
74
|
var uploadRelease = async (projectName, {
|
|
75
75
|
workspaceRoot,
|
|
76
76
|
environment,
|
|
@@ -119,58 +119,96 @@ var uploadRelease = async (projectName, {
|
|
|
119
119
|
};
|
|
120
120
|
|
|
121
121
|
// pkgs/@akanjs/devkit/src/getModelFileData.ts
|
|
122
|
-
var import_fs3 = __toESM(require("fs")
|
|
123
|
-
var getModelFileData = (modulePath, modelName) => {
|
|
124
|
-
const moduleType = modulePath.startsWith("apps") ? "app" : "lib";
|
|
125
|
-
const moduleName = modulePath.split("/")[1];
|
|
126
|
-
const constantFilePath = `${modulePath}/lib/${modelName}/${modelName}.constant.ts`;
|
|
127
|
-
const unitFilePath = `${modulePath}/lib/${modelName}/${modelName}.Unit.tsx`;
|
|
128
|
-
const viewFilePath = `${modulePath}/lib/${modelName}/${modelName}.View.tsx`;
|
|
129
|
-
const constantFileStr = import_fs3.default.readFileSync(constantFilePath, "utf8");
|
|
130
|
-
const unitFileStr = import_fs3.default.readFileSync(unitFilePath, "utf8");
|
|
131
|
-
const viewFileStr = import_fs3.default.readFileSync(viewFilePath, "utf8");
|
|
132
|
-
const constantFileLines = constantFileStr.split("\n");
|
|
133
|
-
const importLibNames = constantFileLines.filter((line) => line.startsWith("import { cnst as ")).map((line) => line.split("cnst as ")[1].split(" ")[0]);
|
|
134
|
-
const importLocalPaths = constantFileLines.filter((line) => line.startsWith("import { ") && line.includes('from "../')).map((line) => line.split("from ")[1].split('"')[1]);
|
|
135
|
-
const importModelNames = importLocalPaths.map((path7) => path7.split("/")[1]).filter((name) => !name.startsWith("_"));
|
|
136
|
-
const hasImportScalar = !!importLocalPaths.map((path7) => path7.split("/")[1]).filter((name) => name.startsWith("_")).length;
|
|
137
|
-
return {
|
|
138
|
-
moduleType,
|
|
139
|
-
moduleName,
|
|
140
|
-
modelName,
|
|
141
|
-
constantFilePath,
|
|
142
|
-
unitFilePath,
|
|
143
|
-
viewFilePath,
|
|
144
|
-
importModelNames,
|
|
145
|
-
hasImportScalar,
|
|
146
|
-
importLibNames,
|
|
147
|
-
constantFileStr,
|
|
148
|
-
unitFileStr,
|
|
149
|
-
viewFileStr
|
|
150
|
-
};
|
|
151
|
-
};
|
|
122
|
+
var import_fs3 = __toESM(require("fs"));
|
|
152
123
|
|
|
153
124
|
// pkgs/@akanjs/devkit/src/getRelatedCnsts.ts
|
|
154
|
-
var
|
|
155
|
-
var import_ora = __toESM(require("ora")
|
|
156
|
-
var ts = __toESM(require("typescript")
|
|
157
|
-
var
|
|
158
|
-
const tsConfigPath = `./tsconfig.json`;
|
|
125
|
+
var fs4 = __toESM(require("fs"));
|
|
126
|
+
var import_ora = __toESM(require("ora"));
|
|
127
|
+
var ts = __toESM(require("typescript"));
|
|
128
|
+
var parseTsConfig = (tsConfigPath = "./tsconfig.json") => {
|
|
159
129
|
const configFile = ts.readConfigFile(tsConfigPath, (path7) => {
|
|
160
130
|
return ts.sys.readFile(path7);
|
|
161
131
|
});
|
|
162
|
-
|
|
132
|
+
return ts.parseJsonConfigFileContent(
|
|
163
133
|
configFile.config,
|
|
164
134
|
ts.sys,
|
|
165
|
-
|
|
135
|
+
fs4.realpathSync(tsConfigPath).replace(/[^/\\]+$/, "")
|
|
166
136
|
);
|
|
137
|
+
};
|
|
138
|
+
var collectImportedFiles = (constantFilePath, parsedConfig) => {
|
|
139
|
+
const allFilesToAnalyze = /* @__PURE__ */ new Set([constantFilePath]);
|
|
140
|
+
const analyzedFiles = /* @__PURE__ */ new Set();
|
|
141
|
+
const spinner = (0, import_ora.default)("Collecting related files...");
|
|
142
|
+
spinner.start();
|
|
143
|
+
function collectImported(filePath) {
|
|
144
|
+
if (analyzedFiles.has(filePath))
|
|
145
|
+
return;
|
|
146
|
+
analyzedFiles.add(filePath);
|
|
147
|
+
const tempProgram = ts.createProgram([filePath], parsedConfig.options);
|
|
148
|
+
const source = tempProgram.getSourceFile(filePath);
|
|
149
|
+
if (!source)
|
|
150
|
+
return;
|
|
151
|
+
function collectImports(node) {
|
|
152
|
+
if (ts.isImportDeclaration(node) && ts.isStringLiteral(node.moduleSpecifier)) {
|
|
153
|
+
const importPath = node.moduleSpecifier.text;
|
|
154
|
+
if (importPath.startsWith(".")) {
|
|
155
|
+
const resolved = ts.resolveModuleName(importPath, filePath, parsedConfig.options, ts.sys).resolvedModule?.resolvedFileName;
|
|
156
|
+
if (resolved && !allFilesToAnalyze.has(resolved)) {
|
|
157
|
+
allFilesToAnalyze.add(resolved);
|
|
158
|
+
collectImported(resolved);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
ts.forEachChild(node, collectImports);
|
|
163
|
+
}
|
|
164
|
+
collectImports(source);
|
|
165
|
+
}
|
|
166
|
+
collectImported(constantFilePath);
|
|
167
|
+
spinner.succeed(`Found ${allFilesToAnalyze.size} related files.`);
|
|
168
|
+
return {
|
|
169
|
+
allFilesToAnalyze,
|
|
170
|
+
analyzedFiles
|
|
171
|
+
};
|
|
172
|
+
};
|
|
173
|
+
var createTsProgram = (filePaths, options) => {
|
|
174
|
+
const spinner = (0, import_ora.default)("Creating TypeScript program for all files...");
|
|
175
|
+
spinner.start();
|
|
176
|
+
const program2 = ts.createProgram(Array.from(filePaths), options);
|
|
177
|
+
const checker = program2.getTypeChecker();
|
|
178
|
+
spinner.succeed("TypeScript program created.");
|
|
179
|
+
return {
|
|
180
|
+
program: program2,
|
|
181
|
+
checker
|
|
182
|
+
};
|
|
183
|
+
};
|
|
184
|
+
var createSymbolCache = (checker) => {
|
|
185
|
+
const symbolCache = /* @__PURE__ */ new Map();
|
|
186
|
+
return (node) => {
|
|
187
|
+
const cacheKey = `${node.getSourceFile().fileName}:${node.pos}:${node.end}`;
|
|
188
|
+
if (!symbolCache.has(cacheKey)) {
|
|
189
|
+
symbolCache.set(cacheKey, checker.getSymbolAtLocation(node));
|
|
190
|
+
}
|
|
191
|
+
return symbolCache.get(cacheKey);
|
|
192
|
+
};
|
|
193
|
+
};
|
|
194
|
+
var analyzeProperties = (filesToAnalyze, program2, checker) => {
|
|
167
195
|
const propertyMap = /* @__PURE__ */ new Map();
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
196
|
+
const analyzedFiles = /* @__PURE__ */ new Set();
|
|
197
|
+
const sourceLineCache = /* @__PURE__ */ new Map();
|
|
198
|
+
const getCachedSymbol = createSymbolCache(checker);
|
|
199
|
+
const spinner = (0, import_ora.default)("Analyzing property relationships...");
|
|
200
|
+
spinner.start();
|
|
201
|
+
function analyzeFileProperties(filePath) {
|
|
202
|
+
if (analyzedFiles.has(filePath))
|
|
203
|
+
return;
|
|
204
|
+
analyzedFiles.add(filePath);
|
|
171
205
|
const source = program2.getSourceFile(filePath);
|
|
172
206
|
if (!source)
|
|
173
|
-
return
|
|
207
|
+
return;
|
|
208
|
+
if (!sourceLineCache.has(filePath)) {
|
|
209
|
+
sourceLineCache.set(filePath, source.getFullText().split("\n"));
|
|
210
|
+
}
|
|
211
|
+
const sourceLines = sourceLineCache.get(filePath);
|
|
174
212
|
function visit(node) {
|
|
175
213
|
if (!source)
|
|
176
214
|
return;
|
|
@@ -178,37 +216,38 @@ var getRelatedCnsts = (constantFilePath) => {
|
|
|
178
216
|
const left = node.expression;
|
|
179
217
|
const right = node.name;
|
|
180
218
|
const { line } = ts.getLineAndCharacterOfPosition(source, node.getStart());
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
const symbol = checker.getSymbolAtLocation(right);
|
|
219
|
+
if (ts.isIdentifier(left) && sourceLines && sourceLines.length > line && (sourceLines[line].includes(`@Field.Prop(() => ${left.text}.${right.text}`) || sourceLines[line].includes(`base.Filter(${left.text}.${right.text},`))) {
|
|
220
|
+
const symbol = getCachedSymbol(right);
|
|
184
221
|
if (symbol?.declarations && symbol.declarations.length > 0) {
|
|
185
222
|
const key = symbol.declarations[0].getSourceFile().fileName.split("/").pop()?.split(".")[0] ?? "";
|
|
186
223
|
const property = propertyMap.get(key);
|
|
187
224
|
const isScalar = symbol.declarations[0].getSourceFile().fileName.includes("_");
|
|
188
|
-
const
|
|
225
|
+
const symbolFilePath = symbol.declarations[0].getSourceFile().fileName.replace(`${ts.sys.getCurrentDirectory()}/`, "");
|
|
189
226
|
if (property) {
|
|
190
227
|
propertyMap.set(`${left.text}.${right.text}`, {
|
|
191
|
-
filePath:
|
|
228
|
+
filePath: symbolFilePath,
|
|
192
229
|
isLibModule: true,
|
|
193
230
|
isImport: false,
|
|
194
231
|
libName: left.text,
|
|
232
|
+
source: fs4.readFileSync(symbolFilePath, "utf-8"),
|
|
195
233
|
isScalar
|
|
196
234
|
});
|
|
197
|
-
} else
|
|
235
|
+
} else {
|
|
198
236
|
propertyMap.set(key, {
|
|
199
|
-
filePath:
|
|
237
|
+
filePath: symbolFilePath,
|
|
200
238
|
isLibModule: true,
|
|
201
239
|
isImport: false,
|
|
202
240
|
libName: left.text,
|
|
203
|
-
isScalar
|
|
241
|
+
isScalar,
|
|
242
|
+
source: fs4.readFileSync(symbolFilePath, "utf-8")
|
|
204
243
|
});
|
|
205
|
-
|
|
244
|
+
}
|
|
206
245
|
}
|
|
207
246
|
}
|
|
208
|
-
} else if (ts.isImportDeclaration(node)) {
|
|
209
|
-
const importPath = node.moduleSpecifier.
|
|
247
|
+
} else if (ts.isImportDeclaration(node) && ts.isStringLiteral(node.moduleSpecifier)) {
|
|
248
|
+
const importPath = node.moduleSpecifier.text;
|
|
210
249
|
if (importPath.startsWith(".")) {
|
|
211
|
-
const resolved = ts.resolveModuleName(importPath, filePath,
|
|
250
|
+
const resolved = ts.resolveModuleName(importPath, filePath, program2.getCompilerOptions(), ts.sys).resolvedModule?.resolvedFileName;
|
|
212
251
|
const moduleName = importPath.split("/").pop()?.split(".")[0] ?? "";
|
|
213
252
|
const property = propertyMap.get(moduleName);
|
|
214
253
|
const isScalar = importPath.includes("_");
|
|
@@ -217,87 +256,38 @@ var getRelatedCnsts = (constantFilePath) => {
|
|
|
217
256
|
filePath: resolved,
|
|
218
257
|
isLibModule: false,
|
|
219
258
|
isImport: true,
|
|
220
|
-
isScalar
|
|
259
|
+
isScalar,
|
|
260
|
+
source: fs4.readFileSync(resolved, "utf-8")
|
|
221
261
|
});
|
|
222
|
-
findPropertyOriginAll(resolved);
|
|
223
262
|
}
|
|
224
263
|
}
|
|
225
264
|
}
|
|
226
265
|
ts.forEachChild(node, visit);
|
|
227
266
|
}
|
|
228
267
|
visit(source);
|
|
229
|
-
return propertyMap;
|
|
230
268
|
}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
const checker = program2.getTypeChecker();
|
|
234
|
-
const source = program2.getSourceFile(filePath);
|
|
235
|
-
const propertyMap2 = /* @__PURE__ */ new Map();
|
|
236
|
-
if (!source)
|
|
237
|
-
return null;
|
|
238
|
-
function visit(node) {
|
|
239
|
-
if (ts.isPropertyAccessExpression(node)) {
|
|
240
|
-
const left = node.expression;
|
|
241
|
-
const right = node.name;
|
|
242
|
-
if (ts.isIdentifier(left) && left.text === aliasName && right.text === libName) {
|
|
243
|
-
const symbol = checker.getSymbolAtLocation(right);
|
|
244
|
-
if (symbol?.declarations && symbol.declarations.length > 0) {
|
|
245
|
-
return symbol.declarations[0].getSourceFile().fileName;
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
return ts.forEachChild(node, visit) || null;
|
|
250
|
-
}
|
|
251
|
-
return visit(source);
|
|
269
|
+
for (const filePath of filesToAnalyze) {
|
|
270
|
+
analyzeFileProperties(filePath);
|
|
252
271
|
}
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
272
|
+
spinner.succeed(`Analysis complete. Found ${propertyMap.size} properties.`);
|
|
273
|
+
return propertyMap;
|
|
274
|
+
};
|
|
275
|
+
var getRelatedCnsts = (constantFilePath) => {
|
|
276
|
+
const parsedConfig = parseTsConfig();
|
|
277
|
+
const { allFilesToAnalyze } = collectImportedFiles(constantFilePath, parsedConfig);
|
|
278
|
+
const { program: program2, checker } = createTsProgram(allFilesToAnalyze, parsedConfig.options);
|
|
279
|
+
const propertyMap = analyzeProperties(allFilesToAnalyze, program2, checker);
|
|
280
|
+
return Array.from(propertyMap.entries()).map(([key, value]) => ({ key, ...value }));
|
|
258
281
|
};
|
|
259
282
|
|
|
260
283
|
// pkgs/@akanjs/devkit/src/selectModel.ts
|
|
261
284
|
var import_prompts = require("@inquirer/prompts");
|
|
262
|
-
var
|
|
285
|
+
var import_fs4 = __toESM(require("fs"));
|
|
263
286
|
|
|
264
287
|
// pkgs/@akanjs/devkit/src/streamAi.ts
|
|
265
288
|
var import_prompts2 = require("@langchain/core/prompts");
|
|
266
289
|
var import_runnables = require("@langchain/core/runnables");
|
|
267
290
|
var import_openai = require("@langchain/openai");
|
|
268
|
-
var streamAi = async (question, callback = (chunk) => {
|
|
269
|
-
process.stdout.write(chunk);
|
|
270
|
-
}) => {
|
|
271
|
-
const createStreamingModel = (apiKey = process.env.DEEPSEEK_API_KEY) => {
|
|
272
|
-
if (!apiKey)
|
|
273
|
-
throw new Error(`process.env.DEEPSEEK_API_KEY is not set`);
|
|
274
|
-
return new import_openai.ChatOpenAI({
|
|
275
|
-
modelName: "deepseek-reasoner",
|
|
276
|
-
temperature: 0.7,
|
|
277
|
-
streaming: true,
|
|
278
|
-
// Enable streaming
|
|
279
|
-
configuration: { baseURL: "https://api.deepseek.com/v1", apiKey }
|
|
280
|
-
});
|
|
281
|
-
};
|
|
282
|
-
const createProcessingChain = () => {
|
|
283
|
-
return import_runnables.RunnableSequence.from([import_prompts2.PromptTemplate.fromTemplate(`Answer concisely: {question}`), createStreamingModel()]);
|
|
284
|
-
};
|
|
285
|
-
try {
|
|
286
|
-
const chain = createProcessingChain();
|
|
287
|
-
const stream = await chain.stream({ question });
|
|
288
|
-
let fullResponse = "";
|
|
289
|
-
for await (const chunk of stream) {
|
|
290
|
-
const content = chunk.content;
|
|
291
|
-
if (typeof content === "string") {
|
|
292
|
-
fullResponse += content;
|
|
293
|
-
callback(content);
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
return { content: fullResponse };
|
|
297
|
-
} catch (error) {
|
|
298
|
-
throw new Error("Failed to stream response");
|
|
299
|
-
}
|
|
300
|
-
};
|
|
301
291
|
|
|
302
292
|
// pkgs/@akanjs/common/isDayjs.ts
|
|
303
293
|
var import_dayjs = require("dayjs");
|
|
@@ -483,7 +473,7 @@ var sleep = async (ms) => {
|
|
|
483
473
|
};
|
|
484
474
|
|
|
485
475
|
// pkgs/@akanjs/config/src/akanConfig.ts
|
|
486
|
-
var
|
|
476
|
+
var import_fs5 = __toESM(require("fs"));
|
|
487
477
|
var import_path2 = __toESM(require("path"));
|
|
488
478
|
|
|
489
479
|
// pkgs/@akanjs/config/src/nextConfig.ts
|
|
@@ -698,7 +688,7 @@ CMD ["npm", "start"]`,
|
|
|
698
688
|
};
|
|
699
689
|
var getAppConfig = async (appRoot, props) => {
|
|
700
690
|
const akanConfigPath = import_path2.default.join(appRoot, "akan.config.ts");
|
|
701
|
-
if (!
|
|
691
|
+
if (!import_fs5.default.existsSync(akanConfigPath))
|
|
702
692
|
throw new Error(`application akan.config.ts is not found ${appRoot}`);
|
|
703
693
|
const configImp = (await import(`${appRoot}/akan.config.ts`)).default;
|
|
704
694
|
const config = typeof configImp === "function" ? configImp(props) : configImp;
|
|
@@ -718,7 +708,7 @@ var makeLibConfig = (config, props) => {
|
|
|
718
708
|
};
|
|
719
709
|
var getLibConfig = async (libRoot, props) => {
|
|
720
710
|
const akanConfigPath = import_path2.default.join(libRoot, "akan.config.ts");
|
|
721
|
-
if (!
|
|
711
|
+
if (!import_fs5.default.existsSync(akanConfigPath))
|
|
722
712
|
throw new Error(`library akan.config.ts is not found ${libRoot}`);
|
|
723
713
|
const configImp = (await import(`${libRoot}/akan.config.ts`)).default;
|
|
724
714
|
const config = typeof configImp === "function" ? configImp(props) : configImp;
|
|
@@ -764,15 +754,15 @@ var getDefaultFileScan = () => ({
|
|
|
764
754
|
|
|
765
755
|
// pkgs/@akanjs/devkit/src/executors.ts
|
|
766
756
|
var import_child_process = require("child_process");
|
|
767
|
-
var
|
|
768
|
-
var
|
|
769
|
-
var
|
|
770
|
-
var
|
|
757
|
+
var import_dotenv = __toESM(require("dotenv"));
|
|
758
|
+
var import_fs6 = __toESM(require("fs"));
|
|
759
|
+
var import_promises = __toESM(require("fs/promises"));
|
|
760
|
+
var import_path3 = __toESM(require("path"));
|
|
771
761
|
|
|
772
762
|
// pkgs/@akanjs/devkit/src/dependencyScanner.ts
|
|
773
|
-
var fs7 = __toESM(require("fs")
|
|
774
|
-
var path3 = __toESM(require("path")
|
|
775
|
-
var ts2 = __toESM(require("typescript")
|
|
763
|
+
var fs7 = __toESM(require("fs"));
|
|
764
|
+
var path3 = __toESM(require("path"));
|
|
765
|
+
var ts2 = __toESM(require("typescript"));
|
|
776
766
|
var TypeScriptDependencyScanner = class {
|
|
777
767
|
constructor(directory) {
|
|
778
768
|
this.directory = directory;
|
|
@@ -923,8 +913,8 @@ var Executor = class {
|
|
|
923
913
|
constructor(name, cwdPath) {
|
|
924
914
|
this.logger = new Logger(name);
|
|
925
915
|
this.cwdPath = cwdPath;
|
|
926
|
-
if (!
|
|
927
|
-
|
|
916
|
+
if (!import_fs6.default.existsSync(cwdPath))
|
|
917
|
+
import_fs6.default.mkdirSync(cwdPath, { recursive: true });
|
|
928
918
|
}
|
|
929
919
|
exec(command, options = {}) {
|
|
930
920
|
const proc = (0, import_child_process.exec)(command, { cwd: this.cwdPath, ...options });
|
|
@@ -983,31 +973,31 @@ var Executor = class {
|
|
|
983
973
|
}
|
|
984
974
|
mkdir(dirPath) {
|
|
985
975
|
const writePath = this.#getPath(dirPath);
|
|
986
|
-
if (!
|
|
987
|
-
|
|
976
|
+
if (!import_fs6.default.existsSync(writePath))
|
|
977
|
+
import_fs6.default.mkdirSync(writePath, { recursive: true });
|
|
988
978
|
this.logger.verbose(`Make directory ${writePath}`);
|
|
989
979
|
return this;
|
|
990
980
|
}
|
|
991
981
|
exists(filePath) {
|
|
992
982
|
const readPath = this.#getPath(filePath);
|
|
993
|
-
return
|
|
983
|
+
return import_fs6.default.existsSync(readPath);
|
|
994
984
|
}
|
|
995
985
|
writeFile(filePath, content, { overwrite = true } = {}) {
|
|
996
986
|
const writePath = this.#getPath(filePath);
|
|
997
987
|
const dir = import_path3.default.dirname(writePath);
|
|
998
|
-
if (!
|
|
999
|
-
|
|
988
|
+
if (!import_fs6.default.existsSync(dir))
|
|
989
|
+
import_fs6.default.mkdirSync(dir, { recursive: true });
|
|
1000
990
|
const contentStr = typeof content === "string" ? content : JSON.stringify(content, null, 2);
|
|
1001
|
-
if (
|
|
1002
|
-
const currentContent =
|
|
991
|
+
if (import_fs6.default.existsSync(writePath)) {
|
|
992
|
+
const currentContent = import_fs6.default.readFileSync(writePath, "utf8");
|
|
1003
993
|
if (currentContent === contentStr || !overwrite)
|
|
1004
994
|
this.logger.verbose(`File ${writePath} is unchanged`);
|
|
1005
995
|
else {
|
|
1006
|
-
|
|
996
|
+
import_fs6.default.writeFileSync(writePath, contentStr, "utf8");
|
|
1007
997
|
this.logger.verbose(`File ${writePath} is changed`);
|
|
1008
998
|
}
|
|
1009
999
|
} else {
|
|
1010
|
-
|
|
1000
|
+
import_fs6.default.writeFileSync(writePath, contentStr, "utf8");
|
|
1011
1001
|
this.logger.verbose(`File ${writePath} is created`);
|
|
1012
1002
|
}
|
|
1013
1003
|
return this;
|
|
@@ -1023,11 +1013,11 @@ var Executor = class {
|
|
|
1023
1013
|
}
|
|
1024
1014
|
readFile(filePath) {
|
|
1025
1015
|
const readPath = this.#getPath(filePath);
|
|
1026
|
-
return
|
|
1016
|
+
return import_fs6.default.readFileSync(readPath, "utf8");
|
|
1027
1017
|
}
|
|
1028
1018
|
readJson(filePath) {
|
|
1029
1019
|
const readPath = this.#getPath(filePath);
|
|
1030
|
-
return JSON.parse(
|
|
1020
|
+
return JSON.parse(import_fs6.default.readFileSync(readPath, "utf8"));
|
|
1031
1021
|
}
|
|
1032
1022
|
async cp(srcPath, destPath) {
|
|
1033
1023
|
const src = this.#getPath(srcPath);
|
|
@@ -1096,7 +1086,7 @@ var Executor = class {
|
|
|
1096
1086
|
overwrite = true
|
|
1097
1087
|
}) {
|
|
1098
1088
|
const templatePath = `${__dirname}/src/templates${template ? `/${template}` : ""}`.replace(".ts", ".js");
|
|
1099
|
-
if (
|
|
1089
|
+
if (import_fs6.default.statSync(templatePath).isFile()) {
|
|
1100
1090
|
const filename = import_path3.default.basename(templatePath);
|
|
1101
1091
|
await this.#applyTemplateFile(
|
|
1102
1092
|
{ templatePath, targetPath: import_path3.default.join(basePath2, filename), scanResult, overwrite },
|
|
@@ -1107,7 +1097,7 @@ var Executor = class {
|
|
|
1107
1097
|
await Promise.all(
|
|
1108
1098
|
subdirs.map(async (subdir) => {
|
|
1109
1099
|
const subpath = import_path3.default.join(templatePath, subdir);
|
|
1110
|
-
if (
|
|
1100
|
+
if (import_fs6.default.statSync(subpath).isFile())
|
|
1111
1101
|
await this.#applyTemplateFile(
|
|
1112
1102
|
{ templatePath: subpath, targetPath: import_path3.default.join(basePath2, subdir), scanResult, overwrite },
|
|
1113
1103
|
dict
|
|
@@ -1204,12 +1194,32 @@ var WorkspaceExecutor = class _WorkspaceExecutor extends Executor {
|
|
|
1204
1194
|
this.writeJson("tsconfig.json", rootTsConfig);
|
|
1205
1195
|
return this;
|
|
1206
1196
|
}
|
|
1197
|
+
async getDirInModule(basePath2, name) {
|
|
1198
|
+
const AVOID_DIRS = ["__lib", "__scalar", `_${name}`];
|
|
1199
|
+
const getDirs = async (dirname, maxDepth = 3, results = [], prefix = "") => {
|
|
1200
|
+
const dirs = await import_promises.default.readdir(dirname);
|
|
1201
|
+
await Promise.all(
|
|
1202
|
+
dirs.map(async (dir) => {
|
|
1203
|
+
if (AVOID_DIRS.includes(dir))
|
|
1204
|
+
return;
|
|
1205
|
+
const dirPath = import_path3.default.join(dirname, dir);
|
|
1206
|
+
if (import_fs6.default.lstatSync(dirPath).isDirectory()) {
|
|
1207
|
+
results.push(`${name}/${prefix}${dir}`);
|
|
1208
|
+
if (maxDepth > 0)
|
|
1209
|
+
await getDirs(dirPath, maxDepth - 1, results, `${prefix}${dir}/`);
|
|
1210
|
+
}
|
|
1211
|
+
})
|
|
1212
|
+
);
|
|
1213
|
+
return results;
|
|
1214
|
+
};
|
|
1215
|
+
return await getDirs(basePath2);
|
|
1216
|
+
}
|
|
1207
1217
|
async commit(message, { init = false, add = true } = {}) {
|
|
1208
1218
|
if (init)
|
|
1209
|
-
await this.exec(`git init`);
|
|
1219
|
+
await this.exec(`git init --quiet`);
|
|
1210
1220
|
if (add)
|
|
1211
1221
|
await this.exec(`git add .`);
|
|
1212
|
-
await this.exec(`git commit -m "${message}"`);
|
|
1222
|
+
await this.exec(`git commit --quiet -m "${message}"`);
|
|
1213
1223
|
}
|
|
1214
1224
|
async #getDirHasFile(basePath2, targetFilename) {
|
|
1215
1225
|
const AVOID_DIRS = ["node_modules", "dist", "public", "./next"];
|
|
@@ -1220,8 +1230,8 @@ var WorkspaceExecutor = class _WorkspaceExecutor extends Executor {
|
|
|
1220
1230
|
if (AVOID_DIRS.includes(dir))
|
|
1221
1231
|
return;
|
|
1222
1232
|
const dirPath = import_path3.default.join(dirname, dir);
|
|
1223
|
-
if (
|
|
1224
|
-
const hasTargetFile =
|
|
1233
|
+
if (import_fs6.default.lstatSync(dirPath).isDirectory()) {
|
|
1234
|
+
const hasTargetFile = import_fs6.default.existsSync(import_path3.default.join(dirPath, targetFilename));
|
|
1225
1235
|
if (hasTargetFile)
|
|
1226
1236
|
results.push(`${prefix}${dir}`);
|
|
1227
1237
|
if (maxDepth > 0)
|
|
@@ -1241,6 +1251,14 @@ var WorkspaceExecutor = class _WorkspaceExecutor extends Executor {
|
|
|
1241
1251
|
];
|
|
1242
1252
|
return scalarConstantExampleFiles;
|
|
1243
1253
|
}
|
|
1254
|
+
async getViewFiles() {
|
|
1255
|
+
const [appNames, libNames] = await this.getSyss();
|
|
1256
|
+
const viewExampleFiles = [
|
|
1257
|
+
...(await Promise.all(appNames.map((appName) => AppExecutor.from(this, appName).getViewsSourceCode()))).flat(),
|
|
1258
|
+
...(await Promise.all(libNames.map((libName) => LibExecutor.from(this, libName).getViewsSourceCode()))).flat()
|
|
1259
|
+
];
|
|
1260
|
+
return viewExampleFiles;
|
|
1261
|
+
}
|
|
1244
1262
|
};
|
|
1245
1263
|
var SysExecutor = class extends Executor {
|
|
1246
1264
|
workspace;
|
|
@@ -1255,6 +1273,10 @@ var SysExecutor = class extends Executor {
|
|
|
1255
1273
|
async getConfig(command) {
|
|
1256
1274
|
return this.type === "app" ? await getAppConfig(this.cwdPath, { ...this.workspace.getBaseDevEnv(), type: "app", name: this.name, command }) : await getLibConfig(this.cwdPath, { ...this.workspace.getBaseDevEnv(), type: "lib", name: this.name, command });
|
|
1257
1275
|
}
|
|
1276
|
+
async getModules() {
|
|
1277
|
+
const path7 = this.type === "app" ? `apps/${this.name}/lib` : `libs/${this.name}/lib`;
|
|
1278
|
+
return await this.workspace.getDirInModule(path7, this.name);
|
|
1279
|
+
}
|
|
1258
1280
|
async scan({
|
|
1259
1281
|
tsconfig = this.getTsConfig(`${this.cwdPath}/tsconfig.json`),
|
|
1260
1282
|
akanConfig
|
|
@@ -1279,11 +1301,11 @@ var SysExecutor = class extends Executor {
|
|
|
1279
1301
|
const pathSplitLength = path7.split("/").length;
|
|
1280
1302
|
return tsconfig.compilerOptions.paths[path7][0].split("/").slice(1, 1 + pathSplitLength).join("/");
|
|
1281
1303
|
}).filter((libName) => libName !== this.name);
|
|
1282
|
-
if (!
|
|
1283
|
-
|
|
1304
|
+
if (!import_fs6.default.existsSync(`${this.cwdPath}/lib/__scalar`))
|
|
1305
|
+
import_fs6.default.mkdirSync(`${this.cwdPath}/lib/__scalar`, { recursive: true });
|
|
1284
1306
|
const files = getDefaultFileScan();
|
|
1285
1307
|
const dirnames = (await import_promises.default.readdir(`${this.cwdPath}/lib`)).filter(
|
|
1286
|
-
(name) =>
|
|
1308
|
+
(name) => import_fs6.default.lstatSync(`${this.cwdPath}/lib/${name}`).isDirectory()
|
|
1287
1309
|
);
|
|
1288
1310
|
const databaseDirs = dirnames.filter((name) => !name.startsWith("_"));
|
|
1289
1311
|
const serviceDirs = dirnames.filter((name) => name.startsWith("_") && !name.startsWith("__"));
|
|
@@ -1411,20 +1433,42 @@ var SysExecutor = class extends Executor {
|
|
|
1411
1433
|
return { filepath, content };
|
|
1412
1434
|
}
|
|
1413
1435
|
async getDatabaseModules() {
|
|
1414
|
-
const databaseModules = (await import_promises.default.readdir(`${this.cwdPath}/lib`)).filter((name) => !name.startsWith("_") && !name.startsWith("__") && !name.endsWith(".ts")).filter((name) =>
|
|
1436
|
+
const databaseModules = (await import_promises.default.readdir(`${this.cwdPath}/lib`)).filter((name) => !name.startsWith("_") && !name.startsWith("__") && !name.endsWith(".ts")).filter((name) => import_fs6.default.existsSync(`${this.cwdPath}/lib/${name}/${name}.constant.ts`));
|
|
1415
1437
|
return databaseModules;
|
|
1416
1438
|
}
|
|
1417
1439
|
async getServiceModules() {
|
|
1418
|
-
const serviceModules = (await import_promises.default.readdir(`${this.cwdPath}/lib`)).filter((name) => name.startsWith("_") && !name.startsWith("__")).filter((name) =>
|
|
1440
|
+
const serviceModules = (await import_promises.default.readdir(`${this.cwdPath}/lib`)).filter((name) => name.startsWith("_") && !name.startsWith("__")).filter((name) => import_fs6.default.existsSync(`${this.cwdPath}/lib/${name}/${name}.service.ts`));
|
|
1419
1441
|
return serviceModules;
|
|
1420
1442
|
}
|
|
1421
1443
|
async getScalarModules() {
|
|
1422
|
-
const scalarModules = (await import_promises.default.readdir(`${this.cwdPath}/lib/__scalar`)).filter((name) => !name.startsWith("_")).filter((name) =>
|
|
1444
|
+
const scalarModules = (await import_promises.default.readdir(`${this.cwdPath}/lib/__scalar`)).filter((name) => !name.startsWith("_")).filter((name) => import_fs6.default.existsSync(`${this.cwdPath}/lib/__scalar/${name}/${name}.constant.ts`));
|
|
1423
1445
|
return scalarModules;
|
|
1424
1446
|
}
|
|
1425
|
-
async
|
|
1426
|
-
const
|
|
1427
|
-
return
|
|
1447
|
+
async getViewComponents() {
|
|
1448
|
+
const viewComponents = (await import_promises.default.readdir(`${this.cwdPath}/lib`)).filter((name) => !name.startsWith("_") && !name.startsWith("__") && !name.endsWith(".ts")).filter((name) => import_fs6.default.existsSync(`${this.cwdPath}/lib/${name}/${name}.View.tsx`));
|
|
1449
|
+
return viewComponents;
|
|
1450
|
+
}
|
|
1451
|
+
async getUnitComponents() {
|
|
1452
|
+
const unitComponents = (await import_promises.default.readdir(`${this.cwdPath}/lib`)).filter((name) => name.startsWith("_") && !name.startsWith("__")).filter((name) => import_fs6.default.existsSync(`${this.cwdPath}/lib/${name}/${name}.Unit.tsx`));
|
|
1453
|
+
return unitComponents;
|
|
1454
|
+
}
|
|
1455
|
+
async getTemplateComponents() {
|
|
1456
|
+
const templateComponents = (await import_promises.default.readdir(`${this.cwdPath}/lib`)).filter((name) => name.startsWith("_") && !name.startsWith("__")).filter((name) => import_fs6.default.existsSync(`${this.cwdPath}/lib/${name}/${name}.Template.tsx`));
|
|
1457
|
+
return templateComponents;
|
|
1458
|
+
}
|
|
1459
|
+
async getViewsSourceCode() {
|
|
1460
|
+
const viewComponents = await this.getViewComponents();
|
|
1461
|
+
return viewComponents.map((viewComponent) => this.getLocalFile(`lib/${viewComponent}/${viewComponent}.View.tsx`));
|
|
1462
|
+
}
|
|
1463
|
+
async getUnitsSourceCode() {
|
|
1464
|
+
const unitComponents = await this.getUnitComponents();
|
|
1465
|
+
return unitComponents.map((unitComponent) => this.getLocalFile(`lib/${unitComponent}/${unitComponent}.Unit.tsx`));
|
|
1466
|
+
}
|
|
1467
|
+
async getTemplatesSourceCode() {
|
|
1468
|
+
const templateComponents = await this.getTemplateComponents();
|
|
1469
|
+
return templateComponents.map(
|
|
1470
|
+
(templateComponent) => this.getLocalFile(`lib/${templateComponent}/${templateComponent}.Template.tsx`)
|
|
1471
|
+
);
|
|
1428
1472
|
}
|
|
1429
1473
|
async getScalarConstantFiles() {
|
|
1430
1474
|
const scalarModules = await this.getScalarModules();
|
|
@@ -1444,8 +1488,10 @@ var SysExecutor = class extends Executor {
|
|
|
1444
1488
|
}
|
|
1445
1489
|
};
|
|
1446
1490
|
var AppExecutor = class _AppExecutor extends SysExecutor {
|
|
1491
|
+
dist;
|
|
1447
1492
|
constructor({ workspace, name }) {
|
|
1448
1493
|
super({ workspace, name, type: "app" });
|
|
1494
|
+
this.dist = new Executor(`${name} Dist App Executor`, `${this.workspace.workspaceRoot}/dist/apps/${name}`);
|
|
1449
1495
|
}
|
|
1450
1496
|
static from(executor, name) {
|
|
1451
1497
|
if (executor instanceof WorkspaceExecutor)
|
|
@@ -1462,9 +1508,9 @@ var AppExecutor = class _AppExecutor extends SysExecutor {
|
|
|
1462
1508
|
}
|
|
1463
1509
|
async syncAssets(libDeps) {
|
|
1464
1510
|
const projectPublicLibPath = `${this.cwdPath}/public/libs`;
|
|
1465
|
-
if (
|
|
1511
|
+
if (import_fs6.default.existsSync(projectPublicLibPath))
|
|
1466
1512
|
await import_promises.default.rm(projectPublicLibPath, { recursive: true });
|
|
1467
|
-
const targetDeps = libDeps.filter((dep) =>
|
|
1513
|
+
const targetDeps = libDeps.filter((dep) => import_fs6.default.existsSync(`${this.workspace.workspaceRoot}/libs/${dep}/public`));
|
|
1468
1514
|
await Promise.all(targetDeps.map((dep) => import_promises.default.mkdir(`${projectPublicLibPath}/${dep}`, { recursive: true })));
|
|
1469
1515
|
await Promise.all(
|
|
1470
1516
|
targetDeps.map(
|
|
@@ -1475,23 +1521,13 @@ var AppExecutor = class _AppExecutor extends SysExecutor {
|
|
|
1475
1521
|
);
|
|
1476
1522
|
}
|
|
1477
1523
|
};
|
|
1478
|
-
var DistAppExecutor = class _DistAppExecutor extends Executor {
|
|
1479
|
-
name;
|
|
1480
|
-
constructor({ workspace, name }) {
|
|
1481
|
-
super(`${name} Dist App Executor`, `${workspace.workspaceRoot}/dist/apps/${name}`);
|
|
1482
|
-
this.name = name;
|
|
1483
|
-
}
|
|
1484
|
-
static from(executor, name) {
|
|
1485
|
-
if (executor instanceof WorkspaceExecutor)
|
|
1486
|
-
return new _DistAppExecutor({ workspace: executor, name });
|
|
1487
|
-
return new _DistAppExecutor({ workspace: executor.workspace, name });
|
|
1488
|
-
}
|
|
1489
|
-
};
|
|
1490
1524
|
var LibExecutor = class _LibExecutor extends SysExecutor {
|
|
1491
1525
|
workspaceRoot;
|
|
1492
1526
|
repoName;
|
|
1527
|
+
dist;
|
|
1493
1528
|
constructor({ workspace, name }) {
|
|
1494
1529
|
super({ workspace, name, type: "lib" });
|
|
1530
|
+
this.dist = new Executor(`${name} Dist Lib Executor`, `${this.workspace.workspaceRoot}/dist/libs/${name}`);
|
|
1495
1531
|
}
|
|
1496
1532
|
static from(executor, name) {
|
|
1497
1533
|
if (executor instanceof WorkspaceExecutor)
|
|
@@ -1510,10 +1546,12 @@ var LibExecutor = class _LibExecutor extends SysExecutor {
|
|
|
1510
1546
|
var PkgExecutor = class _PkgExecutor extends Executor {
|
|
1511
1547
|
workspace;
|
|
1512
1548
|
name;
|
|
1549
|
+
dist;
|
|
1513
1550
|
constructor({ workspace = WorkspaceExecutor.fromRoot(), name }) {
|
|
1514
1551
|
super(`${name} Pkg Executor`, `${workspace.workspaceRoot}/pkgs/${name}`);
|
|
1515
1552
|
this.workspace = workspace;
|
|
1516
1553
|
this.name = name;
|
|
1554
|
+
this.dist = new Executor(`${name} Dist Pkg Executor`, `${this.workspace.workspaceRoot}/dist/pkgs/${name}`);
|
|
1517
1555
|
}
|
|
1518
1556
|
static from(executor, name) {
|
|
1519
1557
|
if (executor instanceof WorkspaceExecutor)
|
|
@@ -1543,24 +1581,6 @@ var PkgExecutor = class _PkgExecutor extends Executor {
|
|
|
1543
1581
|
return pkgScanResult;
|
|
1544
1582
|
}
|
|
1545
1583
|
};
|
|
1546
|
-
var DistPkgExecutor = class _DistPkgExecutor extends Executor {
|
|
1547
|
-
workspaceRoot;
|
|
1548
|
-
repoName;
|
|
1549
|
-
name;
|
|
1550
|
-
constructor({ workspaceRoot, repoName, name }) {
|
|
1551
|
-
super(`${name} Dist Pkg Executor`, `${workspaceRoot}/dist/pkgs/${name}`);
|
|
1552
|
-
this.workspaceRoot = workspaceRoot;
|
|
1553
|
-
this.repoName = repoName;
|
|
1554
|
-
this.name = name;
|
|
1555
|
-
}
|
|
1556
|
-
static from(workspaceExecutor, name) {
|
|
1557
|
-
return new _DistPkgExecutor({
|
|
1558
|
-
workspaceRoot: workspaceExecutor.workspaceRoot,
|
|
1559
|
-
repoName: workspaceExecutor.repoName,
|
|
1560
|
-
name
|
|
1561
|
-
});
|
|
1562
|
-
}
|
|
1563
|
-
};
|
|
1564
1584
|
|
|
1565
1585
|
// pkgs/@akanjs/devkit/src/constants.ts
|
|
1566
1586
|
var import_os = require("os");
|
|
@@ -1570,21 +1590,21 @@ var akanCloudHost = process.env.NEXT_PUBLIC_OPERATION_MODE === "local" ? "http:/
|
|
|
1570
1590
|
var akanCloudBackendUrl = `${akanCloudHost}${process.env.NEXT_PUBLIC_OPERATION_MODE === "local" ? ":8080" : ""}/backend`;
|
|
1571
1591
|
var akanCloudClientUrl = `${akanCloudHost}${process.env.NEXT_PUBLIC_OPERATION_MODE === "local" ? ":4200" : ""}`;
|
|
1572
1592
|
var defaultHostConfig = {};
|
|
1573
|
-
var defaultAkanGlobalConfig = {};
|
|
1593
|
+
var defaultAkanGlobalConfig = { cloudHost: {}, llm: null };
|
|
1574
1594
|
|
|
1575
1595
|
// pkgs/@akanjs/devkit/src/auth.ts
|
|
1576
|
-
var
|
|
1596
|
+
var import_fs7 = __toESM(require("fs"));
|
|
1577
1597
|
var getAkanGlobalConfig = () => {
|
|
1578
|
-
const akanConfig =
|
|
1598
|
+
const akanConfig = import_fs7.default.existsSync(configPath) ? JSON.parse(import_fs7.default.readFileSync(configPath, "utf8")) : defaultAkanGlobalConfig;
|
|
1579
1599
|
return akanConfig;
|
|
1580
1600
|
};
|
|
1581
1601
|
var setAkanGlobalConfig = (akanConfig) => {
|
|
1582
|
-
|
|
1583
|
-
|
|
1602
|
+
import_fs7.default.mkdirSync(basePath, { recursive: true });
|
|
1603
|
+
import_fs7.default.writeFileSync(configPath, JSON.stringify(akanConfig, null, 2));
|
|
1584
1604
|
};
|
|
1585
1605
|
var getHostConfig = (host = akanCloudHost) => {
|
|
1586
1606
|
const akanConfig = getAkanGlobalConfig();
|
|
1587
|
-
return akanConfig[host] ?? defaultHostConfig;
|
|
1607
|
+
return akanConfig.cloudHost[host] ?? defaultHostConfig;
|
|
1588
1608
|
};
|
|
1589
1609
|
var setHostConfig = (host = akanCloudHost, config = {}) => {
|
|
1590
1610
|
const akanConfig = getAkanGlobalConfig();
|
|
@@ -1603,7 +1623,7 @@ var getSelf = async (token) => {
|
|
|
1603
1623
|
|
|
1604
1624
|
// pkgs/@akanjs/devkit/src/capacitorApp.ts
|
|
1605
1625
|
var import_project = require("@trapezedev/project");
|
|
1606
|
-
var
|
|
1626
|
+
var import_fs8 = __toESM(require("fs"));
|
|
1607
1627
|
var CapacitorApp = class {
|
|
1608
1628
|
constructor(app) {
|
|
1609
1629
|
this.app = app;
|
|
@@ -1629,7 +1649,7 @@ var CapacitorApp = class {
|
|
|
1629
1649
|
await this.project.commit();
|
|
1630
1650
|
}
|
|
1631
1651
|
async releaseIos() {
|
|
1632
|
-
const isAdded =
|
|
1652
|
+
const isAdded = import_fs8.default.existsSync(`${this.app.cwdPath}/ios/App/Podfile`);
|
|
1633
1653
|
if (!isAdded) {
|
|
1634
1654
|
await this.app.spawn("npx cap add ios");
|
|
1635
1655
|
await this.app.spawn("npx @capacitor/assets generate");
|
|
@@ -1638,7 +1658,7 @@ var CapacitorApp = class {
|
|
|
1638
1658
|
await this.app.spawn("cross-env", ["APP_OPERATION_MODE=release", "npx", "cap", "sync", "ios"]);
|
|
1639
1659
|
}
|
|
1640
1660
|
async releaseAndroid() {
|
|
1641
|
-
const isAdded =
|
|
1661
|
+
const isAdded = import_fs8.default.existsSync(`${this.app.cwdPath}/android/app/build.gradle`);
|
|
1642
1662
|
if (!isAdded) {
|
|
1643
1663
|
await this.app.spawn("npx cap add android");
|
|
1644
1664
|
await this.app.spawn("npx @capacitor/assets generate");
|
|
@@ -1879,7 +1899,7 @@ var Target = {
|
|
|
1879
1899
|
// pkgs/@akanjs/devkit/src/commandDecorators/command.ts
|
|
1880
1900
|
var import_prompts3 = require("@inquirer/prompts");
|
|
1881
1901
|
var import_commander = require("commander");
|
|
1882
|
-
var
|
|
1902
|
+
var import_fs9 = __toESM(require("fs"));
|
|
1883
1903
|
var camelToKebabCase = (str) => str.replace(/([A-Z])/g, "-$1").toLowerCase();
|
|
1884
1904
|
var handleOption = (programCommand, argMeta) => {
|
|
1885
1905
|
const {
|
|
@@ -1926,7 +1946,7 @@ var getOptionValue = async (argMeta, opt) => {
|
|
|
1926
1946
|
const message = ask ?? `Do you want to set ${name}? ${desc ? ` (${desc})` : ""}: `;
|
|
1927
1947
|
return await (0, import_prompts3.confirm)({ message });
|
|
1928
1948
|
} else {
|
|
1929
|
-
const message = ask
|
|
1949
|
+
const message = ask ? `${ask}: ` : `Enter the ${name} value${example ? ` (example: ${example})` : ""}: `;
|
|
1930
1950
|
if (argMeta.argsOption.nullable)
|
|
1931
1951
|
return await (0, import_prompts3.input)({ message });
|
|
1932
1952
|
else
|
|
@@ -1975,8 +1995,8 @@ var getArgumentValue = async (argMeta, value, workspace) => {
|
|
|
1975
1995
|
throw new Error(`Invalid system type: ${argMeta.type}`);
|
|
1976
1996
|
};
|
|
1977
1997
|
var runCommands = async (...commands) => {
|
|
1978
|
-
const hasPackageJson =
|
|
1979
|
-
const version = hasPackageJson ? JSON.parse(
|
|
1998
|
+
const hasPackageJson = import_fs9.default.existsSync(`${__dirname}/package.json`);
|
|
1999
|
+
const version = hasPackageJson ? JSON.parse(import_fs9.default.readFileSync(`${__dirname}/package.json`, "utf8")).version : "0.0.1";
|
|
1980
2000
|
import_commander.program.version(version).description("Akan CLI");
|
|
1981
2001
|
for (const command of commands) {
|
|
1982
2002
|
const targetMetas = getTargetMetas(command);
|
|
@@ -2026,15 +2046,64 @@ var runCommands = async (...commands) => {
|
|
|
2026
2046
|
var import_prompts4 = require("@inquirer/prompts");
|
|
2027
2047
|
var import_messages = require("@langchain/core/messages");
|
|
2028
2048
|
var import_openai2 = require("@langchain/openai");
|
|
2049
|
+
var import_chalk = __toESM(require("chalk"));
|
|
2029
2050
|
var MAX_ASK_TRY = 300;
|
|
2051
|
+
var supportedLlmModels = ["deepseek-chat", "deepseek-reasoner"];
|
|
2030
2052
|
var AiSession = class _AiSession {
|
|
2031
|
-
static #chat =
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2053
|
+
static #chat = null;
|
|
2054
|
+
static async init({ temperature = 0.7, useExisting = true } = {}) {
|
|
2055
|
+
if (useExisting) {
|
|
2056
|
+
const llmConfig2 = this.getLlmConfig();
|
|
2057
|
+
if (llmConfig2)
|
|
2058
|
+
return this.#setChatModel(llmConfig2.model, llmConfig2.apiKey);
|
|
2059
|
+
}
|
|
2060
|
+
const llmConfig = await this.#requestLlmConfig();
|
|
2061
|
+
const { model, apiKey } = llmConfig;
|
|
2062
|
+
await this.#validateApiKey(model, apiKey);
|
|
2063
|
+
return this.#setChatModel(model, apiKey, { temperature }).setLlmConfig({ model, apiKey });
|
|
2064
|
+
}
|
|
2065
|
+
static #setChatModel(model, apiKey, { temperature = 0.7 } = {}) {
|
|
2066
|
+
this.#chat = new import_openai2.ChatOpenAI({
|
|
2067
|
+
modelName: model,
|
|
2068
|
+
temperature,
|
|
2069
|
+
streaming: true,
|
|
2070
|
+
configuration: { baseURL: "https://api.deepseek.com/v1", apiKey }
|
|
2071
|
+
});
|
|
2072
|
+
return this;
|
|
2073
|
+
}
|
|
2074
|
+
static getLlmConfig() {
|
|
2075
|
+
const akanConfig = getAkanGlobalConfig();
|
|
2076
|
+
return akanConfig.llm ?? null;
|
|
2077
|
+
}
|
|
2078
|
+
static setLlmConfig(llmConfig) {
|
|
2079
|
+
const akanConfig = getAkanGlobalConfig();
|
|
2080
|
+
akanConfig.llm = llmConfig;
|
|
2081
|
+
setAkanGlobalConfig(akanConfig);
|
|
2082
|
+
return this;
|
|
2083
|
+
}
|
|
2084
|
+
static async #requestLlmConfig() {
|
|
2085
|
+
const model = await (0, import_prompts4.select)({ message: "Select a LLM model", choices: supportedLlmModels });
|
|
2086
|
+
const apiKey = await (0, import_prompts4.input)({ message: "Enter your API key" });
|
|
2087
|
+
return { model, apiKey };
|
|
2088
|
+
}
|
|
2089
|
+
static async #validateApiKey(modelName, apiKey) {
|
|
2090
|
+
const chat = new import_openai2.ChatOpenAI({
|
|
2091
|
+
modelName,
|
|
2092
|
+
temperature: 0,
|
|
2093
|
+
configuration: { baseURL: "https://api.deepseek.com/v1", apiKey }
|
|
2094
|
+
});
|
|
2095
|
+
try {
|
|
2096
|
+
await chat.invoke("Hi, and just say 'ok'");
|
|
2097
|
+
return true;
|
|
2098
|
+
} catch (error) {
|
|
2099
|
+
Logger.rawLog(
|
|
2100
|
+
import_chalk.default.red(
|
|
2101
|
+
`LLM API key is invalid. Please check your API key and try again. You can set it again by running "akan set-llm" or reset by running "akan reset-llm"`
|
|
2102
|
+
)
|
|
2103
|
+
);
|
|
2104
|
+
throw error;
|
|
2105
|
+
}
|
|
2106
|
+
}
|
|
2038
2107
|
messageHistory = [];
|
|
2039
2108
|
constructor(messageHistory = []) {
|
|
2040
2109
|
this.messageHistory = messageHistory;
|
|
@@ -2044,6 +2113,8 @@ var AiSession = class _AiSession {
|
|
|
2044
2113
|
Logger.raw(chunk);
|
|
2045
2114
|
}
|
|
2046
2115
|
} = {}) {
|
|
2116
|
+
if (!_AiSession.#chat)
|
|
2117
|
+
throw new Error("Please initialize the AI session first");
|
|
2047
2118
|
try {
|
|
2048
2119
|
const humanMessage = new import_messages.HumanMessage(question);
|
|
2049
2120
|
this.messageHistory.push(humanMessage);
|
|
@@ -2056,6 +2127,8 @@ var AiSession = class _AiSession {
|
|
|
2056
2127
|
onChunk(content);
|
|
2057
2128
|
}
|
|
2058
2129
|
}
|
|
2130
|
+
fullResponse += "\n";
|
|
2131
|
+
onChunk("\n");
|
|
2059
2132
|
this.messageHistory.push(new import_messages.AIMessage(fullResponse));
|
|
2060
2133
|
return { content: fullResponse, messageHistory: this.messageHistory };
|
|
2061
2134
|
} catch (error) {
|
|
@@ -2084,8 +2157,8 @@ var AiSession = class _AiSession {
|
|
|
2084
2157
|
return this.#getTypescriptCode(content);
|
|
2085
2158
|
}
|
|
2086
2159
|
#getTypescriptCode(content) {
|
|
2087
|
-
const code = /```typescript([\s\S]*?)```/.exec(content);
|
|
2088
|
-
return code ? code[
|
|
2160
|
+
const code = /```(typescript|tsx)([\s\S]*?)```/.exec(content);
|
|
2161
|
+
return code ? code[2] : content;
|
|
2089
2162
|
}
|
|
2090
2163
|
};
|
|
2091
2164
|
|
|
@@ -2098,9 +2171,17 @@ var LibraryRunner = class {
|
|
|
2098
2171
|
const scanResult = await lib.scan({ akanConfig });
|
|
2099
2172
|
return scanResult;
|
|
2100
2173
|
}
|
|
2174
|
+
async createLibrary(libName, workspace) {
|
|
2175
|
+
}
|
|
2176
|
+
async removeLibrary(lib) {
|
|
2177
|
+
await lib.workspace.exec(`rm -rf libs/${lib.name}`);
|
|
2178
|
+
lib.log(`Library ${lib.name} removed`);
|
|
2179
|
+
}
|
|
2101
2180
|
async installLibrary(workspace, libName) {
|
|
2102
2181
|
workspace.log(`Installing ${libName} library as git subtree...`);
|
|
2103
|
-
await workspace.exec(
|
|
2182
|
+
await workspace.exec(
|
|
2183
|
+
`git subtree add --quiet --prefix=libs/${libName} git@github.com:akan-team/${libName}.git main`
|
|
2184
|
+
);
|
|
2104
2185
|
await workspace.cp(`libs/${libName}/env/env.server.example.ts`, `libs/${libName}/env/env.server.testing.ts`);
|
|
2105
2186
|
workspace.setTsPaths("lib", libName);
|
|
2106
2187
|
await workspace.commit(`Add ${libName} library`);
|
|
@@ -2129,18 +2210,18 @@ var LibraryRunner = class {
|
|
|
2129
2210
|
});
|
|
2130
2211
|
const newRootPackageJson = { ...rootPackageJson, dependencies, devDependencies };
|
|
2131
2212
|
lib.workspace.writeJson("package.json", newRootPackageJson);
|
|
2132
|
-
await lib.workspace.spawn("pnpm", ["install"]);
|
|
2213
|
+
await lib.workspace.spawn("pnpm", ["install", "--reporter=silent"]);
|
|
2133
2214
|
await lib.workspace.commit(`Merge ${lib.name} library dependencies`);
|
|
2134
2215
|
}
|
|
2135
2216
|
async pushLibrary(lib, branch) {
|
|
2136
2217
|
await lib.workspace.exec(
|
|
2137
|
-
`git subtree push --prefix=libs/${lib.name} git@github.com:akan-team/${lib.name}.git ${branch}`
|
|
2218
|
+
`git subtree push --quiet --prefix=libs/${lib.name} git@github.com:akan-team/${lib.name}.git ${branch}`
|
|
2138
2219
|
);
|
|
2139
2220
|
lib.logger.log(`${lib.name} library pushed to ${branch} branch`);
|
|
2140
2221
|
}
|
|
2141
2222
|
async pullLibrary(lib, branch) {
|
|
2142
2223
|
await lib.workspace.exec(
|
|
2143
|
-
`git subtree pull --prefix=libs/${lib.name} git@github.com:akan-team/${lib.name}.git ${branch}`
|
|
2224
|
+
`git subtree pull --quiet --prefix=libs/${lib.name} git@github.com:akan-team/${lib.name}.git ${branch}`
|
|
2144
2225
|
);
|
|
2145
2226
|
lib.logger.log(`${lib.name} library pulled from ${branch} branch`);
|
|
2146
2227
|
}
|
|
@@ -2187,6 +2268,12 @@ var LibraryScript = class {
|
|
|
2187
2268
|
for (const libName of scanResult.akanConfig.libs)
|
|
2188
2269
|
await this.syncLibrary(LibExecutor.from(lib.workspace, libName), { recursive: false });
|
|
2189
2270
|
}
|
|
2271
|
+
async createLibrary(libName, workspace) {
|
|
2272
|
+
await this.#runner.createLibrary(libName, workspace);
|
|
2273
|
+
}
|
|
2274
|
+
async removeLibrary(lib) {
|
|
2275
|
+
await this.#runner.removeLibrary(lib);
|
|
2276
|
+
}
|
|
2190
2277
|
async installLibrary(workspace, libName) {
|
|
2191
2278
|
const lib = await this.#runner.installLibrary(workspace, libName);
|
|
2192
2279
|
workspace.log(`${libName} library installed`);
|
|
@@ -2213,9 +2300,10 @@ var import_openai3 = require("@langchain/openai");
|
|
|
2213
2300
|
var import_plugin_react = __toESM(require("@vitejs/plugin-react"));
|
|
2214
2301
|
var import_dotenv3 = __toESM(require("dotenv"));
|
|
2215
2302
|
var esbuild = __toESM(require("esbuild"));
|
|
2216
|
-
var
|
|
2303
|
+
var import_fs10 = __toESM(require("fs"));
|
|
2217
2304
|
var import_promises2 = __toESM(require("fs/promises"));
|
|
2218
2305
|
var import_js_yaml2 = __toESM(require("js-yaml"));
|
|
2306
|
+
var import_open = __toESM(require("open"));
|
|
2219
2307
|
var import_ora2 = __toESM(require("ora"));
|
|
2220
2308
|
var import_path4 = __toESM(require("path"));
|
|
2221
2309
|
var vite = __toESM(require("vite"));
|
|
@@ -2223,8 +2311,9 @@ var import_vite_plugin_node_polyfills = require("vite-plugin-node-polyfills");
|
|
|
2223
2311
|
var import_vite_tsconfig_paths = __toESM(require("vite-tsconfig-paths"));
|
|
2224
2312
|
|
|
2225
2313
|
// pkgs/@akanjs/cli/src/module/module.prompt.ts
|
|
2226
|
-
var
|
|
2227
|
-
|
|
2314
|
+
var frameworkDescription = `
|
|
2315
|
+
\uB098\uB294 \uC880 \uB354 \uD6A8\uC728\uC801\uC73C\uB85C \uCF54\uB529\uC744 \uD558\uAE30 \uC704\uD574\uC11C \uC790\uCCB4 \uD504\uB808\uC784\uC6CC\uD06C\uB97C \uC81C\uC791\uD588\uC5B4.
|
|
2316
|
+
\uADF8\uB798\uC11C \uC6B0\uB9AC \uD504\uB808\uC784\uC6CC\uD06C\uC5D0 \uB300\uD55C \uC124\uBA85\uC744 \uD574\uC904\uD14C\uB2C8\uAE4C \uC798 \uC774\uD574\uD558\uB3C4\uB85D \uD574. \uC6B0\uB9AC \uD504\uB808\uC784\uC6CC\uD06C\uB294 next.js 13\uACFC nest.js, capacitor.js, nx, mongoDB \uAE30\uBC18\uC758 \uD504\uB860\uD2B8\uC5D4\uB4DC, \uC571, \uBC31\uC5D4\uB4DC \uD1B5\uD569 \uD504\uB808\uC784\uC6CC\uD06C\uC57C. \uADF8\uB798\uC11C \uBC31\uC5D4\uB4DC, \uD504\uB860\uD2B8\uC5D4\uB4DC, DB Schema\uC5D0 \uB300\uD55C \uCF54\uB4DC\uAC00 \uBAA8\uB450 \uD55C \uD3F4\uB354 \uC548\uC5D0 \uC788\uC5B4. \uADF8\uB798\uC11C \uC790\uBC14\uC2A4\uD06C\uB9BD\uD2B8, \uD0C0\uC785\uC2A4\uD06C\uB9BD\uD2B8, \uADF8\uB9AC\uACE0 \uD504\uB808\uC784\uC6CC\uD06C\uC5D0 \uB300\uD55C \uC774\uD574\uB9CC \uC788\uB2E4\uBA74 \uAD6C\uBD84\uC9D3\uC9C0 \uC54A\uACE0 \uC0AC\uC6A9\uD560 \uC218 \uC788\uB2E4\uB294 \uC7A5\uC810\uC774 \uC788\uC5B4.
|
|
2228
2317
|
|
|
2229
2318
|
\uAC00\uC7A5 \uC678\uBD80\uC758 \uAD6C\uC870\uB294
|
|
2230
2319
|
- app
|
|
@@ -2742,6 +2831,433 @@ export const General = ({ className, \${dict.model}, self }: \${dict.Model}ViewP
|
|
|
2742
2831
|
|
|
2743
2832
|
\uC77C\uB2E8 \uD504\uB808\uC784\uC6CC\uD06C\uC5D0 \uB300\uD55C \uC124\uBA85\uC740 \uC774 \uC815\uB3C4\uB85C \uD558\uACE0 \uC774 \uC815\uBCF4\uB4E4\uC744 \uAE30\uBC18\uC73C\uB85C \uB0B4\uAC00 \uC6D0\uD558\uB294 \uC694\uAD6C\uB97C \uB4E4\uC5B4\uC918.
|
|
2744
2833
|
`;
|
|
2834
|
+
var moduleDesription = `
|
|
2835
|
+
|
|
2836
|
+
The project follows a modular architecture with clear separation of concerns. Each module in lib/<model>/ represents a domain
|
|
2837
|
+
entity with a standardized file structure that promotes consistency and maintainability.
|
|
2838
|
+
|
|
2839
|
+
## Core Components
|
|
2840
|
+
|
|
2841
|
+
### <Model>.View.tsx
|
|
2842
|
+
Presentation-only components that render data without managing state.
|
|
2843
|
+
It works as a server component, They accept model data as props and display it according to specific layouts.
|
|
2844
|
+
These components focus purely on how data looks to the user.
|
|
2845
|
+
only use the full model.
|
|
2846
|
+
This component is only viewing the component. So don't use click event or other interaction events.
|
|
2847
|
+
If you need interaction, possible to wrapping the component with the <Model>.Zone.tsx component.
|
|
2848
|
+
But useable the Link component for navigation.
|
|
2849
|
+
Components created in Model.View.tsx should primarily be made to show the entire detailed data of the model rather than showing only partial data of the model.
|
|
2850
|
+
|
|
2851
|
+
|
|
2852
|
+
### <Model>.Template.tsx
|
|
2853
|
+
Reusable layout patterns with integrated state management. It works as a client component, These components provide consistent UI patterns and handle data
|
|
2854
|
+
binding, often using store hooks to access application state.
|
|
2855
|
+
|
|
2856
|
+
### <Model>.Unit.tsx
|
|
2857
|
+
Small, self-contained UI components representing individual model instances. It works as a server component, They're designed for rendering single items in
|
|
2858
|
+
lists or grids, displaying model data in compact formats. only use the light model.
|
|
2859
|
+
|
|
2860
|
+
### <Model>.Zone.tsx
|
|
2861
|
+
Top-level container components that orchestrate other components. It works as a client component, They compose views, templates, and units into complete UI
|
|
2862
|
+
sections while managing data flow to child components.
|
|
2863
|
+
|
|
2864
|
+
### <Model>.Util.tsx
|
|
2865
|
+
Specialized components and utility functions specific to a model, It works as a client component, providing both UI components and helper functions for
|
|
2866
|
+
model-specific functionality.
|
|
2867
|
+
|
|
2868
|
+
## Data Management
|
|
2869
|
+
|
|
2870
|
+
### <model>.signal.ts
|
|
2871
|
+
Defines API endpoints with type safety using decorators for GraphQL queries and mutations, creating a type-safe bridge between
|
|
2872
|
+
frontend and backend.
|
|
2873
|
+
|
|
2874
|
+
### <model>.store.ts
|
|
2875
|
+
Manages client-side state with typed actions and state, handling UI state, form state, and cached data.
|
|
2876
|
+
|
|
2877
|
+
### <model>.service.ts
|
|
2878
|
+
Implements server-side business logic with dependency injection, handling data processing and complex operations.
|
|
2879
|
+
|
|
2880
|
+
### <model>.constant.ts
|
|
2881
|
+
Defines type definitions and model schemas using decorators to structure model fields, validation, and relationships.
|
|
2882
|
+
|
|
2883
|
+
### <model>.dictionary.ts
|
|
2884
|
+
Provides internationalization and label definitions for model properties and operations.
|
|
2885
|
+
|
|
2886
|
+
### <model>.document.ts
|
|
2887
|
+
Defines database schema and model operations with decorators for database interaction.
|
|
2888
|
+
|
|
2889
|
+
## Data Flow
|
|
2890
|
+
The architecture follows a clear data flow pattern:
|
|
2891
|
+
- Server-side: Document \u2192 Service \u2192 Signal \u2192 API
|
|
2892
|
+
- Client-side: API \u2192 Store \u2192 Components (Zone \u2192 Template/View/Unit)
|
|
2893
|
+
|
|
2894
|
+
This modular structure enables rapid development while maintaining consistency, type safety, and testability throughout the
|
|
2895
|
+
application.
|
|
2896
|
+
`;
|
|
2897
|
+
var utilUiDescription = `
|
|
2898
|
+
This UI kit is an internally developed UI kit within the Akan.js framework.
|
|
2899
|
+
The libs/util/ui directory contains a comprehensive React component library designed for modern web applications.
|
|
2900
|
+
This framework provides a complete set of production-ready, reusable UI components with consistent styling, type safety, and advanced functionality.
|
|
2901
|
+
|
|
2902
|
+
- Every component must be used exactly as described in the documentation.
|
|
2903
|
+
- Do not add any additional props to the components.
|
|
2904
|
+
- Must use the written props exactly.
|
|
2905
|
+
- Only the components explicitly listed in the documentation are available\u2014no additional components exist beyond those specified.
|
|
2906
|
+
|
|
2907
|
+
|
|
2908
|
+
|
|
2909
|
+
Architecture & Foundation
|
|
2910
|
+
|
|
2911
|
+
Core Technologies:
|
|
2912
|
+
- Built on React 18+ with TypeScript for strict type safety
|
|
2913
|
+
- Styled with Tailwind CSS and DaisyUI for consistent design system
|
|
2914
|
+
- Implements modern React patterns including hooks, context providers, and portals
|
|
2915
|
+
- Full internationalization (i18n) support for multilingual applications
|
|
2916
|
+
- Responsive-first design with mobile optimization
|
|
2917
|
+
|
|
2918
|
+
Design Principles:
|
|
2919
|
+
- Composable component architecture with predictable APIs
|
|
2920
|
+
- Accessibility (a11y) compliance throughout
|
|
2921
|
+
- Performance optimization with lazy loading and code splitting
|
|
2922
|
+
- Consistent error handling and validation patterns
|
|
2923
|
+
- Session storage integration for form state persistence
|
|
2924
|
+
|
|
2925
|
+
Component Categories
|
|
2926
|
+
|
|
2927
|
+
Core Input Components
|
|
2928
|
+
|
|
2929
|
+
Essential form controls with advanced validation and user experience features:
|
|
2930
|
+
- Button - Async-aware button with automatic loading/success/error states
|
|
2931
|
+
- Input - Comprehensive input system with real-time validation, multiple variants (Text, Password, Email, Number, Checkbox), and
|
|
2932
|
+
session caching
|
|
2933
|
+
- Select - Advanced dropdown with search, multi-select, and custom rendering
|
|
2934
|
+
- DatePicker - Date/time selection with range support and custom formatting
|
|
2935
|
+
- CodeInput - PIN/verification code input with auto-focus management
|
|
2936
|
+
- Upload - File upload system with drag-drop, progress tracking, image cropping, and multiple file support
|
|
2937
|
+
|
|
2938
|
+
Data Display Components
|
|
2939
|
+
|
|
2940
|
+
Components for presenting and organizing information:
|
|
2941
|
+
- Chart - Visualization suite (Bar, Line, Pie, Doughnut) built on Chart.js
|
|
2942
|
+
- Avatar - User profile images with intelligent fallbacks
|
|
2943
|
+
- ChatBubble - Chat interface with message grouping and timestamps
|
|
2944
|
+
- Empty - Customizable empty state displays
|
|
2945
|
+
- QRCode - QR code generation with click-to-open functionality
|
|
2946
|
+
|
|
2947
|
+
Layout & Navigation System
|
|
2948
|
+
|
|
2949
|
+
Comprehensive layout framework for application structure:
|
|
2950
|
+
- Layout - Complete layout system with Header (auto-hide), Sider (collapsible), Navbar (portal-based), BottomTab (with badges),
|
|
2951
|
+
and container components
|
|
2952
|
+
- Modal/Dialog - Composable dialog system with backdrop, animations, and gesture support
|
|
2953
|
+
- BottomSheet - Mobile-optimized bottom sheet with drag gestures
|
|
2954
|
+
- Menu - Navigation menus with horizontal/vertical modes and submenu support
|
|
2955
|
+
- Tab - Tabbed interfaces with lazy loading and scroll management
|
|
2956
|
+
- ScreenNavigator - Gesture-based screen navigation with spring animations
|
|
2957
|
+
|
|
2958
|
+
Interactive Components
|
|
2959
|
+
|
|
2960
|
+
Advanced user interaction components:
|
|
2961
|
+
- Pagination - Smart page navigation with ellipsis and responsive design
|
|
2962
|
+
- InfiniteScroll - Automatic content loading with intersection observer
|
|
2963
|
+
- DndKit - Drag and drop functionality with provider pattern
|
|
2964
|
+
- Radio - Radio button groups with custom styling
|
|
2965
|
+
- ToggleSelect - Button-based selection with single/multi-select modes
|
|
2966
|
+
- Share - Native share API with copy fallback
|
|
2967
|
+
|
|
2968
|
+
Utility & Feedback Components
|
|
2969
|
+
|
|
2970
|
+
Supporting components for enhanced user experience:
|
|
2971
|
+
- Loading - Comprehensive loading states (Area, Button, Input, Skeleton, Spin, ProgressBar) with animations
|
|
2972
|
+
- Link - Adaptive navigation links with SSR/CSR compatibility
|
|
2973
|
+
- MapView - Map integration supporting both Google Maps and Pigeon Maps with markers and overlays
|
|
2974
|
+
- Image - Optimized image component with blur placeholders and SSR support
|
|
2975
|
+
- Portal - Teleportation component for rendering outside component tree
|
|
2976
|
+
|
|
2977
|
+
Advanced Features
|
|
2978
|
+
|
|
2979
|
+
State Management Integration
|
|
2980
|
+
|
|
2981
|
+
- Context-driven architecture for complex components
|
|
2982
|
+
- Signal-based real-time communication components
|
|
2983
|
+
- Session storage integration for form persistence
|
|
2984
|
+
- Theme-aware styling with automatic adaptation
|
|
2985
|
+
|
|
2986
|
+
Performance Optimizations
|
|
2987
|
+
|
|
2988
|
+
- Lazy loading support for heavy components
|
|
2989
|
+
- Code splitting at component level
|
|
2990
|
+
- Optimized re-rendering with React.memo patterns
|
|
2991
|
+
- Intersection Observer for scroll-based interactions
|
|
2992
|
+
|
|
2993
|
+
Developer Experience
|
|
2994
|
+
|
|
2995
|
+
- Comprehensive TypeScript interfaces for all props
|
|
2996
|
+
- Consistent naming conventions and API patterns
|
|
2997
|
+
- Built-in error boundaries and fallback handling
|
|
2998
|
+
- Extensive JSDoc documentation
|
|
2999
|
+
- Hot reload support for development
|
|
3000
|
+
|
|
3001
|
+
Accessibility & Internationalization
|
|
3002
|
+
|
|
3003
|
+
- ARIA attributes and keyboard navigation support
|
|
3004
|
+
- Screen reader compatibility
|
|
3005
|
+
- RTL (right-to-left) language support
|
|
3006
|
+
- Localized date/time formatting
|
|
3007
|
+
- Color contrast compliance
|
|
3008
|
+
|
|
3009
|
+
Usage Patterns
|
|
3010
|
+
|
|
3011
|
+
The library follows a consistent component composition pattern where complex components are built from smaller, focused
|
|
3012
|
+
subcomponents. For example:
|
|
3013
|
+
|
|
3014
|
+
- Chart.Bar, Chart.Line for different visualization types
|
|
3015
|
+
- Dialog.Modal, Dialog.Title, Dialog.Content for composable modals
|
|
3016
|
+
- Layout.Header, Layout.Sider, Layout.Navbar for layout construction
|
|
3017
|
+
- Upload.File, Upload.Image, Upload.Images for different upload scenarios
|
|
3018
|
+
|
|
3019
|
+
This design enables maximum flexibility while maintaining consistency across the application. Components are designed to work
|
|
3020
|
+
seamlessly together, sharing common styling patterns, validation systems, and state management approaches.
|
|
3021
|
+
|
|
3022
|
+
The library serves as a comprehensive foundation for building modern, accessible, and performant web applications with a focus
|
|
3023
|
+
on developer productivity and end-user experience.
|
|
3024
|
+
|
|
3025
|
+
Avatar
|
|
3026
|
+
- Displays user profile images with automatic fallback to user icon
|
|
3027
|
+
- Props: className?: string, icon?: ReactNode, src?: string
|
|
3028
|
+
|
|
3029
|
+
Button
|
|
3030
|
+
- Enhanced button with automatic loading states and error handling
|
|
3031
|
+
- Props: onClick: (e, {onError}) => Promise<Result>, onSuccess?: (result) => void, className?, children, standard button props
|
|
3032
|
+
|
|
3033
|
+
Input
|
|
3034
|
+
- Comprehensive input system with real-time validation and caching
|
|
3035
|
+
- Props: value: string, validate: (value) => boolean | string, onChange?, nullable?, inputStyleType?: "bordered" | "borderless"
|
|
3036
|
+
| "underline", icon?, cacheKey?
|
|
3037
|
+
- Variants: Input.TextArea, Input.Password, Input.Email, Input.Number, Input.Checkbox
|
|
3038
|
+
|
|
3039
|
+
Select
|
|
3040
|
+
- Advanced dropdown with search and multi-select capabilities
|
|
3041
|
+
- Props: value: T | T[], options: {label, value}[], multiple?, searchable?, onChange, onSearch?, renderOption?, renderSelected?
|
|
3042
|
+
|
|
3043
|
+
DatePicker
|
|
3044
|
+
- Date/time picker with range selection support
|
|
3045
|
+
- Props: value?: Dayjs, onChange, showTime?, format?, disabledDate?
|
|
3046
|
+
- Variants: DatePicker.RangePicker, DatePicker.TimePicker
|
|
3047
|
+
|
|
3048
|
+
CodeInput
|
|
3049
|
+
- PIN/code input with individual character boxes
|
|
3050
|
+
- Props: maxNum: number, value: string, onChange, unitStyle?: "box" | "underline", autoComplete?
|
|
3051
|
+
|
|
3052
|
+
Display Components
|
|
3053
|
+
|
|
3054
|
+
Table
|
|
3055
|
+
- Feature-rich data table with pagination and responsive design
|
|
3056
|
+
- Props: columns: Column[], dataSource: any[], loading?, pagination?, onRow?, rowClassName?
|
|
3057
|
+
|
|
3058
|
+
Modal
|
|
3059
|
+
- Dialog modal with backdrop and action buttons
|
|
3060
|
+
- Props: open: boolean, onCancel, title?, action?, confirmClose?
|
|
3061
|
+
- Variants: Modal.Window
|
|
3062
|
+
|
|
3063
|
+
Image
|
|
3064
|
+
- Optimized image component with blur placeholder and SSR support
|
|
3065
|
+
- Props: src?, file?: ProtoFile, abstractData?, alt?, standard Next.js Image props
|
|
3066
|
+
|
|
3067
|
+
ChatBubble
|
|
3068
|
+
- Chat message bubble with avatar and timestamp
|
|
3069
|
+
- Props: avatar?, hasPrev?, hasNext?, isMe?, name?, at?: Dayjs, children
|
|
3070
|
+
|
|
3071
|
+
Empty
|
|
3072
|
+
- Empty state placeholder with customizable message
|
|
3073
|
+
- Props: description?, minHeight?, children?
|
|
3074
|
+
|
|
3075
|
+
QRCode
|
|
3076
|
+
- QR code generator with click-to-open functionality
|
|
3077
|
+
- Props: href: string, className?
|
|
3078
|
+
|
|
3079
|
+
Layout Components
|
|
3080
|
+
|
|
3081
|
+
BottomSheet
|
|
3082
|
+
- Only mobile bottom sheet with drag gestures
|
|
3083
|
+
- Props: open: boolean, onCancel, type: "full" | "half", children
|
|
3084
|
+
|
|
3085
|
+
Layout
|
|
3086
|
+
Layout - Complete layout framework with responsive design
|
|
3087
|
+
- Layout.Header - Top header with auto-hide functionality
|
|
3088
|
+
- Props: className?: string, type?: "static" | "hide", children?: any, height?: number
|
|
3089
|
+
- Features: Auto-hide on scroll, fixed positioning
|
|
3090
|
+
- Layout.Sider - Collapsible sidebar
|
|
3091
|
+
- Props: className?: string, bgClassName?: string, children?: any
|
|
3092
|
+
- Features: Drawer-based with toggle functionality
|
|
3093
|
+
- Layout.Navbar - Navigation bar with portal content
|
|
3094
|
+
- Props: className?: string, children?: ReactNode, height?:
|
|
3095
|
+
|
|
3096
|
+
Menu
|
|
3097
|
+
- Navigation menu with horizontal/vertical modes and submenu support
|
|
3098
|
+
- Props: items: MenuItem[], mode?: "horizontal" | "inline", selectedKeys?, onClick?, inlineCollapsed?
|
|
3099
|
+
|
|
3100
|
+
|
|
3101
|
+
Tab
|
|
3102
|
+
- Tabbed interface system
|
|
3103
|
+
- Tab.Provider - Tab context provider
|
|
3104
|
+
- Props: className?: string, defaultMenu?: string | null, children?: any
|
|
3105
|
+
- Tab.Menu - Tab menu item
|
|
3106
|
+
- Props: className?: string, activeClassName?: string, disabledClassName?: string, disabled?: boolean, menu: string, children:
|
|
3107
|
+
any, scrollToTop?: boolean, tooltip?: string
|
|
3108
|
+
- Tab.Panel - Tab content panel
|
|
3109
|
+
- Props: className?: string, menu: string, children?: any, loading?: "eager" | "lazy" | "every"
|
|
3110
|
+
- Features: Lazy loading support
|
|
3111
|
+
|
|
3112
|
+
ScreenNavigator
|
|
3113
|
+
- Gesture-based screen navigation
|
|
3114
|
+
- ScreenNavigator.Provider - Navigation context provider
|
|
3115
|
+
- Props: setMenu?: (menu: string) => void, children: ReactNode, menus: string[]
|
|
3116
|
+
- Features: Gesture-based navigation, spring animations
|
|
3117
|
+
- ScreenNavigator.Screen - Individual screen container
|
|
3118
|
+
- Props: children: ReactNode, className?: string
|
|
3119
|
+
- ScreenNavigator.NavbarItem - Navigation bar item
|
|
3120
|
+
- Props: menu: string, children: ReactNode, className?: string
|
|
3121
|
+
|
|
3122
|
+
Upload
|
|
3123
|
+
- File upload system with multiple modes
|
|
3124
|
+
- Upload
|
|
3125
|
+
- Basic file upload with drag & drop
|
|
3126
|
+
- Props: onChange?: (fileList: FileList) => void; multiple?: boolean; accept?: string; className?: string; uploadClassName?: string; children: React.ReactNode; disabled?: boolean;
|
|
3127
|
+
- Upload.File
|
|
3128
|
+
- Single file upload with preview
|
|
3129
|
+
- Props: multiple?: boolean; file: ProtoFile | null; render?: (file: ProtoFile) => React.ReactNode; onChange?: (e: File | FileList) => void | Promise<void>; onRemove?: (e: any) => void; children?: React.ReactNode; disabled?: boolean; maxCount?: number; className?: string; uploadClassName?: string; accept?: string;
|
|
3130
|
+
- Upload.FileList
|
|
3131
|
+
- Multiple files with table view and progress tracking
|
|
3132
|
+
- Props: multiple?: boolean; fileList: ProtoFile[]; render?: (file: ProtoFile) => React.ReactNode; onChange?: (e: File | FileList) => void | Promise<void>; onRemove?: (e: any) => void; children?: React.ReactNode; disabled?: boolean; maxCount?: number; className?: string; uploadClassName?: string; accept?: string;
|
|
3133
|
+
- Upload.Image
|
|
3134
|
+
- Image upload with integrated cropping functionality
|
|
3135
|
+
- Props: multiple?: boolean; file: ProtoFile | null; render?: (file: ProtoFile) => React.ReactNode; onChange?: (e: File | FileList) => void | Promise<void>; onRemove?: (e: any) => void; children?: React.ReactNode; disabled?: boolean; maxCount?: number; className?: string; uploadClassName?: string; accept?: string;
|
|
3136
|
+
- Upload.Images
|
|
3137
|
+
- Multiple image upload with gallery preview
|
|
3138
|
+
- Props: multiple?: boolean; fileList: ProtoFile[]; render?: (file: ProtoFile) => React.ReactNode; onChange?: (e: File | FileList) => void | Promise<void>; onRemove?: (e: any) => void; children?: React.ReactNode; disabled?: boolean; maxCount?: number; className?: string; uploadClassName?: string; accept?: string;
|
|
3139
|
+
|
|
3140
|
+
DndKit
|
|
3141
|
+
- Drag and drop functionality built on @dnd-kit
|
|
3142
|
+
- DndKit.Provider
|
|
3143
|
+
- DnD context provider
|
|
3144
|
+
- Props: className?: string + all DndContextProps
|
|
3145
|
+
- DndKit.DraggableUnit
|
|
3146
|
+
- Draggable item wrapper
|
|
3147
|
+
- Props: id: string, children: ReactNode, className?: string, onClick?: () => void | Promise<void>
|
|
3148
|
+
- DndKit.DroppableColumn
|
|
3149
|
+
- Drop target column
|
|
3150
|
+
- Props: id: string, items: T[], className?: string, children: ReactNode, onOver?: (id, items, event) => void, onEnd?: (id,
|
|
3151
|
+
item, event) => void
|
|
3152
|
+
|
|
3153
|
+
MapView
|
|
3154
|
+
- Map integration with multiple providers
|
|
3155
|
+
- MapView.Map
|
|
3156
|
+
- Main map container with theme awareness
|
|
3157
|
+
- Props: className?: string, onLoad?: () => void, onClick?: (coordinate) => void, onRightClick?: (coordinate) => void,
|
|
3158
|
+
onMouseMove?: (coordinate) => void, children: any
|
|
3159
|
+
- MapView.Marker
|
|
3160
|
+
- Map marker component
|
|
3161
|
+
- Props: coordinate: cnst.Coordinate, zIndex?: number, children?: any
|
|
3162
|
+
- MapView.Google
|
|
3163
|
+
- Google Maps implementation
|
|
3164
|
+
- Props: id?: string, className?: string, mapKey: string, onClick/onRightClick?: (coordinate) => void, center?:
|
|
3165
|
+
cnst.Coordinate, onChangeCenter?: (coordinate) => void, zoom?: number, onChangeZoom?: (zoom) => void, bounds?: {minLat, maxLat,
|
|
3166
|
+
minLng, maxLng}, onLoad?: () => void, onMouseMove?: (coordinate, event) => void, options?: google.maps.MapOptions, children: any
|
|
3167
|
+
- MapView.Pigeon
|
|
3168
|
+
- Pigeon Maps implementation (lightweight alternative)
|
|
3169
|
+
- Props: id?: string, className?: string, onLoad?: () => void, onClick/onRightClick?: (coordinate) => void, center?:
|
|
3170
|
+
cnst.Coordinate, onChangeCenter?: (coordinate) => void, zoom?: number, onChangeZoom?: (zoom) => void, bounds?: {minLat, maxLat,
|
|
3171
|
+
minLng, maxLng}, onChangeBounds?: (bounds) => void, mouseEvents?: boolean, onMouseMove?: (coordinate) => void, mapTiler?: (x, y,
|
|
3172
|
+
z, dpr) => string, children?: any, zoomControlStyle?: CSSProperties
|
|
3173
|
+
|
|
3174
|
+
|
|
3175
|
+
Pagination
|
|
3176
|
+
- Page navigation with smart ellipsis and responsive design
|
|
3177
|
+
- Props: currentPage: number, total: number, onPageSelect, itemsPerPage: number
|
|
3178
|
+
|
|
3179
|
+
Radio
|
|
3180
|
+
- Radio button group with custom styling support
|
|
3181
|
+
- Props: value, children: ReactElement[], onChange, disabled?
|
|
3182
|
+
|
|
3183
|
+
ToggleSelect
|
|
3184
|
+
- Button-based selection with single/multi-select modes
|
|
3185
|
+
- Props: items, value, validate, onChange, nullable
|
|
3186
|
+
- Variants: ToggleSelect.Multi
|
|
3187
|
+
|
|
3188
|
+
Share
|
|
3189
|
+
- Native share API with copy fallback
|
|
3190
|
+
- Props: title: string, url: string, children
|
|
3191
|
+
|
|
3192
|
+
Specialized Component Groups
|
|
3193
|
+
|
|
3194
|
+
Chart
|
|
3195
|
+
- Visualization components built on Chart.js and react-chartjs-2
|
|
3196
|
+
- Chart.Bar - Bar chart component
|
|
3197
|
+
- Props: data: ChartData<"bar">, options?: ChartOptions<"bar">
|
|
3198
|
+
- Features: Responsive layout, legend display, title configuration
|
|
3199
|
+
- Chart.Line - Line chart component
|
|
3200
|
+
- Props: data: ChartData<"line">, options?: ChartOptions<"line">
|
|
3201
|
+
- Features: Line-specific Chart.js configuration with curve interpolation
|
|
3202
|
+
- Chart.Pie - Pie chart component
|
|
3203
|
+
- Props: data: ChartData<"pie">, options?: ChartOptions<"pie">
|
|
3204
|
+
- Features: ArcElement rendering, responsive design
|
|
3205
|
+
- Chart.Doughnut - Doughnut chart component
|
|
3206
|
+
- Props: data: ChartData<"doughnut">, options?: ChartOptions<"doughnut">
|
|
3207
|
+
- Features: Similar to pie but with center cutout
|
|
3208
|
+
|
|
3209
|
+
Dialog
|
|
3210
|
+
- Composable modal dialog system built on Radix UI
|
|
3211
|
+
- Dialog.Provider - Dialog context provider
|
|
3212
|
+
- Props: className?: string, open?: boolean, defaultOpen?: boolean, children?: any
|
|
3213
|
+
- Dialog.Modal - Main modal container
|
|
3214
|
+
- Props: className?: string, bodyClassName?: string, confirmClose?: boolean, children?: any, onCancel?: () => void
|
|
3215
|
+
- Features: Drag gestures, spring animations, responsive design, close confirmation
|
|
3216
|
+
- Dialog.Title - Modal title component
|
|
3217
|
+
- Props: children?: ReactNode
|
|
3218
|
+
- Dialog.Content - Modal content area
|
|
3219
|
+
- Props: className?: string, children?: ReactNode
|
|
3220
|
+
- Dialog.Action - Modal action buttons container
|
|
3221
|
+
- Props: children?: ReactNode
|
|
3222
|
+
- Dialog.Trigger - Modal trigger element
|
|
3223
|
+
- Props: className?: string, children?: any
|
|
3224
|
+
|
|
3225
|
+
Link
|
|
3226
|
+
- Adaptive navigation system
|
|
3227
|
+
- Link
|
|
3228
|
+
- Main adaptive link (auto-switches between CSR/Next.js based on render mode)
|
|
3229
|
+
- Link.Back - Back navigation link
|
|
3230
|
+
- Props: className?: string, children?: any
|
|
3231
|
+
- Features: Browser history integration
|
|
3232
|
+
- Link.Close - Window close link
|
|
3233
|
+
- Props: Similar to Back but closes window
|
|
3234
|
+
- Link.CsrLink & Link.NextLink - Environment-specific implementations with active state support
|
|
3235
|
+
|
|
3236
|
+
|
|
3237
|
+
Loading
|
|
3238
|
+
- Loading states for different UI elements
|
|
3239
|
+
- Loading.Area - Full-screen loading overlay with animated dots
|
|
3240
|
+
- Loading.Button - Button loading skeleton
|
|
3241
|
+
- Props: className?: string, active?: boolean, style?: CSSProperties
|
|
3242
|
+
- Loading.Input - Input loading skeleton
|
|
3243
|
+
- Loading.Skeleton - Multi-line content skeleton with pulse animation
|
|
3244
|
+
- Loading.Spin - Custom loading spinner
|
|
3245
|
+
- Props: indicator?: ReactNode, isCenter?: boolean
|
|
3246
|
+
- Loading.ProgressBar - Animated progress bar
|
|
3247
|
+
- Props: className?: string, value: number, max: number
|
|
3248
|
+
- Features: React Spring animations
|
|
3249
|
+
|
|
3250
|
+
Key Framework Features
|
|
3251
|
+
|
|
3252
|
+
- TypeScript support with strict typing
|
|
3253
|
+
- Responsive design with mobile-first approach
|
|
3254
|
+
- Internationalization (i18n) integration
|
|
3255
|
+
- Session storage caching for form inputs
|
|
3256
|
+
- Accessibility compliance
|
|
3257
|
+
- Consistent DaisyUI/Tailwind CSS styling
|
|
3258
|
+
- Modern React patterns (hooks, context, providers)
|
|
3259
|
+
- Error handling and validation systems
|
|
3260
|
+
`;
|
|
2745
3261
|
var frameworkAbstract = `
|
|
2746
3262
|
Intro
|
|
2747
3263
|
- Build an all-stack application at once.
|
|
@@ -2761,7 +3277,66 @@ Procedure
|
|
|
2761
3277
|
- No Spaghetti Components anymore, build your page with domain-driven components
|
|
2762
3278
|
- write one page, use SSR on Next.js and build Android&iOS CSR app with beautiful page transitions!
|
|
2763
3279
|
- built-in ai code generation, tell about business, the logic is generated.
|
|
3280
|
+
|
|
3281
|
+
|
|
2764
3282
|
`;
|
|
3283
|
+
var eslintDescription = `
|
|
3284
|
+
Core ESLint Extensions
|
|
3285
|
+
|
|
3286
|
+
Base Configurations:
|
|
3287
|
+
- eslint:recommended - Standard ESLint recommended rules
|
|
3288
|
+
- next & next/core-web-vitals - Next.js specific linting rules
|
|
3289
|
+
- @typescript-eslint/recommended-type-checked - TypeScript recommended rules with type checking
|
|
3290
|
+
- @typescript-eslint/strict-type-checked - Strict TypeScript type checking rules
|
|
3291
|
+
- @typescript-eslint/stylistic-type-checked - TypeScript stylistic rules with type checking
|
|
3292
|
+
|
|
3293
|
+
Third-Party Plugins
|
|
3294
|
+
|
|
3295
|
+
1. eslint-plugin-unused-imports
|
|
3296
|
+
- Automatically detects and warns about unused imports
|
|
3297
|
+
- Helps keep code clean by removing unnecessary import statements
|
|
3298
|
+
|
|
3299
|
+
2. eslint-plugin-simple-import-sort
|
|
3300
|
+
- Automatically sorts import statements in a consistent order
|
|
3301
|
+
- Enforces clean import organization throughout the codebase
|
|
3302
|
+
|
|
3303
|
+
Custom Plugin: @akanjs/lint
|
|
3304
|
+
|
|
3305
|
+
1. useClientByFile
|
|
3306
|
+
- Enforces proper "use client" directive usage in Next.js App Router
|
|
3307
|
+
- Server files must NOT have "use client" directive
|
|
3308
|
+
- Client files MUST have "use client" directive at the top
|
|
3309
|
+
|
|
3310
|
+
2. noImportClientFunctions
|
|
3311
|
+
- Prevents server files from importing client-side functions
|
|
3312
|
+
- Ensures proper separation between server and client code
|
|
3313
|
+
|
|
3314
|
+
3. nonScalarPropsRestricted
|
|
3315
|
+
- Prevents non-scalar props (functions) in server components
|
|
3316
|
+
- Specifically targets page.tsx and layout.tsx files
|
|
3317
|
+
- Allows exceptions for specific props like "loader", "render", and "of"
|
|
3318
|
+
|
|
3319
|
+
4. noImportExternalLibrary
|
|
3320
|
+
- Restricts external library imports in pure import/re-export files
|
|
3321
|
+
- Only allows imports from the same app scope (@appName/...)
|
|
3322
|
+
- Promotes clean architecture and prevents dependency leakage
|
|
3323
|
+
|
|
3324
|
+
Key Rule Configurations
|
|
3325
|
+
|
|
3326
|
+
Disabled Rules:
|
|
3327
|
+
- no-console: "error" - Prevents console statements in production code
|
|
3328
|
+
- Various TypeScript strict rules are disabled for flexibility
|
|
3329
|
+
- React and Next.js specific rules are relaxed for development ease
|
|
3330
|
+
|
|
3331
|
+
Import Management:
|
|
3332
|
+
- unused-imports/no-unused-imports: "warn" - Warns about unused imports
|
|
3333
|
+
- simple-import-sort/imports: "warn" - Enforces import sorting
|
|
3334
|
+
- import/first: "warn" - Ensures imports come first
|
|
3335
|
+
- import/newline-after-import: "warn" - Enforces newline after imports
|
|
3336
|
+
|
|
3337
|
+
This configuration creates a robust linting setup that enforces Next.js App Router best practices, maintains clean code
|
|
3338
|
+
organization, and ensures proper server/client code separation.
|
|
3339
|
+
`;
|
|
2765
3340
|
var scalarConstantDescription = `
|
|
2766
3341
|
Purpose and Structure
|
|
2767
3342
|
|
|
@@ -3116,10 +3691,10 @@ ${frameworkAbstract}
|
|
|
3116
3691
|
2. <model>.constant.ts \uD30C\uC77C\uC5D0 \uB300\uD55C \uAC1C\uC694
|
|
3117
3692
|
${scalarConstantDescription}
|
|
3118
3693
|
|
|
3119
|
-
3. <model
|
|
3694
|
+
3. <model>.constant.ts \uD30C\uC77C\uC758 Enum \uC791\uC131\uBC95
|
|
3120
3695
|
${howToSetEnumInModelConstant}
|
|
3121
3696
|
|
|
3122
|
-
4. <model
|
|
3697
|
+
4. <model>.constant.ts \uD30C\uC77C\uC758 Field \uC791\uC131\uBC95
|
|
3123
3698
|
${howToSetFieldInModelConstant}
|
|
3124
3699
|
|
|
3125
3700
|
5. \uD604\uC7AC \uD504\uB85C\uC81D\uD2B8 \uB0B4 \uB2E4\uB978 constant.ts \uD30C\uC77C\uB4E4\uC5D0 \uB300\uD55C \uC608\uC2DC
|
|
@@ -3144,6 +3719,87 @@ Target filename: ${modelName}.constant.ts
|
|
|
3144
3719
|
\`\`\`
|
|
3145
3720
|
${boilerplate}
|
|
3146
3721
|
\`\`\`
|
|
3722
|
+
`;
|
|
3723
|
+
var requestView = ({
|
|
3724
|
+
sysName,
|
|
3725
|
+
modelName,
|
|
3726
|
+
ModelName,
|
|
3727
|
+
boilerplate,
|
|
3728
|
+
constant,
|
|
3729
|
+
properties,
|
|
3730
|
+
exampleFiles
|
|
3731
|
+
}) => `
|
|
3732
|
+
|
|
3733
|
+
|
|
3734
|
+
1. Akan.js \uD504\uB808\uC784\uC6CC\uD06C\uC5D0 \uB300\uD55C \uAC1C\uC694
|
|
3735
|
+
${frameworkAbstract}
|
|
3736
|
+
|
|
3737
|
+
2. Akan.js\uD504\uB808\uC784\uC6CC\uD06C \uB370\uC774\uD130 \uAE30\uBC18 \uBAA8\uB4C8\uC5D0 \uB300\uD55C \uAC1C\uC694
|
|
3738
|
+
${moduleDesription}
|
|
3739
|
+
|
|
3740
|
+
3. Akan.js eslint \uC124\uC815\uC5D0 \uB300\uD55C \uAC1C\uC694
|
|
3741
|
+
${eslintDescription}
|
|
3742
|
+
|
|
3743
|
+
4. util/ui \uB0B4 ui\uD0B7\uC5D0 \uB300\uD55C \uAC1C\uC694
|
|
3744
|
+
${utilUiDescription}
|
|
3745
|
+
|
|
3746
|
+
|
|
3747
|
+
|
|
3748
|
+
5. ${ModelName}.constant.ts \uD30C\uC77C\uC5D0 \uB300\uD55C \uC815\uBCF4
|
|
3749
|
+
${constant}
|
|
3750
|
+
|
|
3751
|
+
6. ${modelName}\uC5D0\uC11C \uC885\uC18D\uB418\uB294 \uB2E4\uB978 \uBAA8\uB378\uB4E4\uC758 \uD0C0\uC785 \uC815\uC758
|
|
3752
|
+
${properties.map(
|
|
3753
|
+
(property) => `
|
|
3754
|
+
\`\`\`
|
|
3755
|
+
${property.key}.constant.ts
|
|
3756
|
+
|
|
3757
|
+
|
|
3758
|
+
${property.source}
|
|
3759
|
+
\`\`\`
|
|
3760
|
+
`
|
|
3761
|
+
).join("\n\n")}
|
|
3762
|
+
|
|
3763
|
+
|
|
3764
|
+
7. \uC608\uC2DC \uD30C\uC77C\uB4E4
|
|
3765
|
+
${exampleFiles.map(
|
|
3766
|
+
(example) => `
|
|
3767
|
+
Example filename: ${example.filepath}
|
|
3768
|
+
\`\`\`
|
|
3769
|
+
${example.content}
|
|
3770
|
+
\`\`\`
|
|
3771
|
+
`
|
|
3772
|
+
).join("\n\n")}
|
|
3773
|
+
|
|
3774
|
+
|
|
3775
|
+
|
|
3776
|
+
Application name: ${sysName}
|
|
3777
|
+
Model name: ${modelName}
|
|
3778
|
+
Target filename: ${ModelName}.View.tsx
|
|
3779
|
+
|
|
3780
|
+
|
|
3781
|
+
\uB108\uB294 Akan.js\uB77C\uB294 \uC0AC\uB0B4 \uD504\uB808\uC784\uC6CC\uD06C\uB85C Typescript \uAE30\uBC18 \uD504\uB85C\uADF8\uB7A8\uC744 \uC791\uC131\uD558\uB294 \uC2DC\uB2C8\uC5B4 \uAC1C\uBC1C\uC790\uC57C.
|
|
3782
|
+
\uADF8 \uC911\uC5D0\uC11C\uB3C4 \uD504\uB860\uD2B8\uC5D4\uB4DC \uAC1C\uBC1C\uC790.
|
|
3783
|
+
\uB9CC\uC57D\uC5D0 \uC544\uC774\uCF58 \uC0AC\uC6A9\uC774 \uD544\uC694\uD558\uBA74 react-icons \uB77C\uC774\uBE0C\uB7EC\uB9AC\uC5D0\uC11C \uC801\uD569\uD55C \uC544\uC774\uCF58\uC744 \uCC3E\uC544\uC11C \uC0AC\uC6A9\uD574\uC918.
|
|
3784
|
+
\uB610, \uC0C9\uC0C1\uC744 \uC0AC\uC6A9\uD558\uB824\uACE0 \uD558\uBA74 \uD558\uB4DC\uCF54\uB529\uB41C \uC0C9\uC0C1(bg-red)\uC774 \uC544\uB2CC \uD14C\uB9C8 \uC0C9\uC0C1(bg-primary)\uC744 \uC0AC\uC6A9\uD574\uC11C \uC791\uC131\uD574\uC918.
|
|
3785
|
+
\uADF8\uB9AC\uACE0 optional\uD55C \uD544\uB4DC\uB294 field && <div>... \uAC00 \uC544\uB2CC, field ? <div>... : null \uD615\uD0DC\uB85C \uC791\uC131\uD574\uC918.
|
|
3786
|
+
css\uB77C\uC774\uBE0C\uB7EC\uB9AC\uB294 DaisyUI\uB97C \uAE30\uBC18\uC73C\uB85C \uC791\uC131\uD574\uC8FC\uB294\uB370, btn, input, badge\uC640 \uAC19\uC740 \uB2E8\uC21C\uD55C \uAE30\uBCF8 css\uB294 \uC0AC\uC6A9\uD574\uB3C4 \uAD1C\uCC2E\uC544. \uADF8\uB7F0\uB370 card, hero\uAC19\uC774 \uBCF5\uC7A1\uD55C \uCEF4\uD3EC\uB10C\uD2B8\uB294 \uC0AC\uC6A9\uD558\uBA74 \uC548\uB3FC.
|
|
3787
|
+
\uBAA8\uB378\uC5D0 \uB300\uD574\uC11C object destructuring\uC740 \uD558\uC9C0\uB9D0\uACE0 ${modelName}.field \uD615\uD0DC\uB85C \uC811\uADFC\uD558\uACE0, \uD0C0\uC785\uC5D0 \uC5D0\uB7EC\uB294 \uC808\uB300\uB85C \uBC1C\uC0DD\uD558\uC9C0 \uC54A\uB3C4\uB85D ${modelName}.constant.ts\uC5D0 \uC791\uC131\uB418\uC788\uB294 \uC2A4\uD0A4\uB9C8\uB97C \uBCF4\uACE0 \uC791\uC131\uD574.
|
|
3788
|
+
\uC870\uAC74\uBD80 className\uC774 \uD544\uC694\uD55C \uACBD\uC6B0\uC5D0\uB294 clsx \uB77C\uC774\uBE0C\uB7EC\uB9AC\uB97C \uC0AC\uC6A9\uD574\uC57C\uB3FC.
|
|
3789
|
+
\uBAA8\uB4E0 \uBAA8\uB378 \uD544\uB4DC\uC5D0 \uC811\uADFC\uD558\uAE30 \uC804\uC5D0, \uAC01 \uC2A4\uD0A4\uB9C8\uC758 \uC2E4\uC81C \uD544\uB4DC \uB9AC\uC2A4\uD2B8\uB97C \uC791\uC131\uD558\uACE0 \uAC80\uD1A0\uD574. \uD2B9\uD788 \uC911\uCCA9\uB41C \uAC1D\uCCB4( ex) XXX.XXX.XXX )\uC5D0 \uC811\uADFC\uD560 \uB54C\uB294 \uB354\uC6B1 \uC8FC\uC758\uD574.
|
|
3790
|
+
\uB610\uD55C ${modelName}\uACFC \uC885\uC18D\uC131\uC774 \uC788\uB294 \uB2E4\uB978 \uBAA8\uB378\uB4E4\uC758 \uD0C0\uC785\uB4E4\uB3C4 \uBAA8\uB450 \uC704\uBC30\uD558\uC9C0\uB9D0\uACE0 \uC798 \uD30C\uC545\uD558\uACE0 \uC791\uC131\uD574.
|
|
3791
|
+
\uC704\uC5D0\uC11C \uC124\uBA85\uD55C \uBAA8\uB4E0 \uB8F0\uACFC \uC124\uBA85, \uD0C0\uC785\uC744 \uC808\uB300\uB85C \uC704\uBC30\uD558\uC9C0\uB9D0\uACE0 \uC798 \uD30C\uC545\uD558\uACE0 \uC791\uC131\uD574.(\uAC01 \uB370\uC774\uD130\uC758 \uD0C0\uC785, \uCEF4\uD3EC\uB10C\uD2B8\uC758 props\uB4F1...)
|
|
3792
|
+
\uC124\uBA85\uD55C \uB0B4\uC6A9 \uC774\uC678\uC5D0 \uB0B4\uC6A9\uC73C\uB85C \uB2C8\uAC00 \uCD94\uC0C1\uD574\uC11C \uC4F0\uC9C0\uB9D0\uACE0 \uC704\uC5D0 \uBA85\uC2DC\uB418\uC788\uB294 \uB8F0 \uC548\uC5D0\uC11C\uB9CC \uC791\uC131\uD574. \uC788\uC9C0\uB3C4 \uC54A\uC740 \uAC83\uB4E4 \uB9CC\uB4E4\uC5B4\uC11C \uCD94\uC0C1\uD654 \uC2DC\uCF1C\uC11C \uC790\uAFB8 \uC4F0\uB294 \uC77C\uC740 \uC808\uB300\uB85C \uD558\uC9C0\uB9C8.
|
|
3793
|
+
\uD2B9\uD788\uB098 \uBC29\uAE08 \uB9D0\uD55C \uC774 \uC704 \uB450 \uBB38\uC7A5\uC740 \uC808\uB300\uC801\uC73C\uB85C \uC9C0\uCF1C\uC57C \uD560 \uB8F0\uC774\uC57C \uC791\uC131\uD560 \uB54C \uD56D\uC0C1 \uC9C0\uD0A4\uACE0 \uB530\uB77C.
|
|
3794
|
+
${ModelName}.View.tsx \uCF54\uB4DC\uB97C \uC791\uC131\uD574\uC918. \uC77C\uBC18\uC801\uC73C\uB85C \uC0AC\uC6A9\uD560 \uC218 \uC788\uB294 \uB514\uC790\uC778\uC758 \uCEF4\uD3EC\uB10C\uD2B8\uB97C 4\uAC1C \uC815\uB3C4 \uB9CC\uB4E4\uC5B4\uC918. (ex card, table...)
|
|
3795
|
+
\uC608\uC2DC \uB4E4\uC5B4\uC92C\uB2E4\uACE0 \uC608\uC2DC\uB9CC \uB9CC\uB4E4\uC9C0 \uB9D0\uACE0 \uB2C8 \uC0DD\uAC01\uC5D0 \uC77C\uBC18\uC801\uC73C\uB85C \uC0AC\uC6A9\uD55C\uB2E4 \uD558\uB294 \uCEF4\uD3EC\uB10C\uD2B8\uB85C \uC0DD\uAC01\uD574\uC11C \uB9CC\uB4E4\uC5B4.
|
|
3796
|
+
|
|
3797
|
+
Target filename: ${ModelName}.View.tsx
|
|
3798
|
+
\`\`\`
|
|
3799
|
+
|
|
3800
|
+
\`\`\`
|
|
3801
|
+
|
|
3802
|
+
|
|
3147
3803
|
`;
|
|
3148
3804
|
|
|
3149
3805
|
// pkgs/@akanjs/cli/src/application/application.prompt.ts
|
|
@@ -3195,6 +3851,10 @@ var ApplicationRunner = class {
|
|
|
3195
3851
|
workspace.setTsPaths("app", appName);
|
|
3196
3852
|
return AppExecutor.from(workspace, appName);
|
|
3197
3853
|
}
|
|
3854
|
+
async removeApplication(app) {
|
|
3855
|
+
await app.workspace.exec(`rm -rf apps/${app.name}`);
|
|
3856
|
+
app.log(`Application ${app.name} removed`);
|
|
3857
|
+
}
|
|
3198
3858
|
async scanSync(app) {
|
|
3199
3859
|
const akanConfig = await getAppConfig(app.cwdPath, {
|
|
3200
3860
|
...app.workspace.getBaseDevEnv(),
|
|
@@ -3216,16 +3876,16 @@ var ApplicationRunner = class {
|
|
|
3216
3876
|
...env
|
|
3217
3877
|
};
|
|
3218
3878
|
}
|
|
3219
|
-
async #prepareCommand(app,
|
|
3220
|
-
await
|
|
3879
|
+
async #prepareCommand(app, type, target) {
|
|
3880
|
+
await app.dist.exec(`rm -rf ${target}`);
|
|
3221
3881
|
if (target === "frontend") {
|
|
3222
3882
|
await app.exec("rm -rf .next");
|
|
3223
3883
|
app.writeFile("next.config.ts", defaultNextConfigFile);
|
|
3224
3884
|
}
|
|
3225
3885
|
return { env: this.#getEnv(app, { AKAN_COMMAND_TYPE: type }) };
|
|
3226
3886
|
}
|
|
3227
|
-
async buildBackend(app
|
|
3228
|
-
await this.#prepareCommand(app,
|
|
3887
|
+
async buildBackend(app) {
|
|
3888
|
+
await this.#prepareCommand(app, "serve", "backend");
|
|
3229
3889
|
const akanConfig = await app.getConfig("build");
|
|
3230
3890
|
const buildResult = await esbuild.build({
|
|
3231
3891
|
write: false,
|
|
@@ -3233,12 +3893,12 @@ var ApplicationRunner = class {
|
|
|
3233
3893
|
bundle: true,
|
|
3234
3894
|
packages: "external",
|
|
3235
3895
|
platform: "node",
|
|
3236
|
-
outdir: `${
|
|
3896
|
+
outdir: `${app.dist.cwdPath}/backend`,
|
|
3237
3897
|
logLevel: "warning"
|
|
3238
3898
|
});
|
|
3239
3899
|
const rootPackageJson = app.workspace.readJson("package.json");
|
|
3240
3900
|
const dependencies = extractDependencies(buildResult.outputFiles, rootPackageJson);
|
|
3241
|
-
buildResult.outputFiles.map((file) =>
|
|
3901
|
+
buildResult.outputFiles.map((file) => app.dist.writeFile(file.path, file.text));
|
|
3242
3902
|
const appPackageJson = {
|
|
3243
3903
|
name: `${app.name}/backend`,
|
|
3244
3904
|
description: `${app.name} backend`,
|
|
@@ -3247,31 +3907,33 @@ var ApplicationRunner = class {
|
|
|
3247
3907
|
engines: { node: ">=22" },
|
|
3248
3908
|
dependencies
|
|
3249
3909
|
};
|
|
3250
|
-
|
|
3251
|
-
|
|
3910
|
+
app.dist.writeJson("backend/package.json", appPackageJson);
|
|
3911
|
+
app.dist.writeFile(import_path4.default.join(app.dist.cwdPath, "backend", "Dockerfile"), akanConfig.backend.dockerfile);
|
|
3252
3912
|
}
|
|
3253
|
-
async serveBackend(app,
|
|
3254
|
-
const { env } = await this.#prepareCommand(app,
|
|
3913
|
+
async serveBackend(app, { open: open2 = false } = {}) {
|
|
3914
|
+
const { env } = await this.#prepareCommand(app, "serve", "backend");
|
|
3255
3915
|
const ctx = await esbuild.context({
|
|
3256
3916
|
write: true,
|
|
3257
3917
|
entryPoints: [`${app.cwdPath}/main.ts`],
|
|
3258
3918
|
bundle: true,
|
|
3259
3919
|
packages: "external",
|
|
3260
3920
|
platform: "node",
|
|
3261
|
-
outdir: import_path4.default.join(
|
|
3921
|
+
outdir: import_path4.default.join(app.dist.cwdPath, "backend"),
|
|
3262
3922
|
logLevel: "warning"
|
|
3263
3923
|
});
|
|
3264
3924
|
await ctx.watch();
|
|
3265
3925
|
await sleep(100);
|
|
3266
|
-
|
|
3926
|
+
if (open2)
|
|
3927
|
+
setTimeout(() => (0, import_open.default)("http://localhost:8080/backend/graphql"), 3e3);
|
|
3928
|
+
await app.dist.spawn("node", ["--watch", "backend/main.js"], { env });
|
|
3267
3929
|
}
|
|
3268
|
-
async buildFrontend(app
|
|
3269
|
-
const { env } = await this.#prepareCommand(app,
|
|
3930
|
+
async buildFrontend(app) {
|
|
3931
|
+
const { env } = await this.#prepareCommand(app, "build", "frontend");
|
|
3270
3932
|
const akanConfig = await app.getConfig("build");
|
|
3271
3933
|
await app.spawn("npx", ["next", "build", "--no-lint"], { env });
|
|
3272
3934
|
const buildResult = await esbuild.build({
|
|
3273
3935
|
entryPoints: [`${app.cwdPath}/next.config.ts`],
|
|
3274
|
-
outdir: `${
|
|
3936
|
+
outdir: `${app.dist.cwdPath}/frontend`,
|
|
3275
3937
|
bundle: true,
|
|
3276
3938
|
packages: "external",
|
|
3277
3939
|
platform: "node",
|
|
@@ -3282,7 +3944,7 @@ var ApplicationRunner = class {
|
|
|
3282
3944
|
});
|
|
3283
3945
|
const rootPackageJson = app.workspace.readJson("package.json");
|
|
3284
3946
|
const dependencies = extractDependencies(buildResult.outputFiles, rootPackageJson, ["next", "react", "react-dom"]);
|
|
3285
|
-
buildResult.outputFiles.map((file) =>
|
|
3947
|
+
buildResult.outputFiles.map((file) => app.dist.writeFile(file.path, file.text));
|
|
3286
3948
|
const appPackageJson = {
|
|
3287
3949
|
name: `${app.name}/frontend`,
|
|
3288
3950
|
description: `${app.name} frontend`,
|
|
@@ -3293,26 +3955,28 @@ var ApplicationRunner = class {
|
|
|
3293
3955
|
start: "next start"
|
|
3294
3956
|
}
|
|
3295
3957
|
};
|
|
3296
|
-
|
|
3958
|
+
app.dist.writeJson("frontend/package.json", appPackageJson);
|
|
3297
3959
|
await Promise.all([
|
|
3298
|
-
app.cp(".next", import_path4.default.join(
|
|
3299
|
-
app.cp("public", import_path4.default.join(
|
|
3960
|
+
app.cp(".next", import_path4.default.join(app.dist.cwdPath, "frontend", ".next")),
|
|
3961
|
+
app.cp("public", import_path4.default.join(app.dist.cwdPath, "frontend", "public"))
|
|
3300
3962
|
]);
|
|
3301
|
-
|
|
3963
|
+
app.dist.writeFile("frontend/Dockerfile", akanConfig.frontend.dockerfile);
|
|
3302
3964
|
}
|
|
3303
|
-
async serveFrontend(app,
|
|
3304
|
-
const { env } = await this.#prepareCommand(app,
|
|
3305
|
-
|
|
3965
|
+
async serveFrontend(app, { open: open2 = false, turbo = true } = {}) {
|
|
3966
|
+
const { env } = await this.#prepareCommand(app, "serve", "frontend");
|
|
3967
|
+
if (open2)
|
|
3968
|
+
setTimeout(() => (0, import_open.default)("http://localhost:4200"), 3e3);
|
|
3969
|
+
await app.spawn("npx", ["next", "dev", "-p", "4200", ...turbo ? ["--turbo"] : []], { env });
|
|
3306
3970
|
}
|
|
3307
|
-
async #getViteConfig(app
|
|
3308
|
-
const { env } = await this.#prepareCommand(app,
|
|
3971
|
+
async #getViteConfig(app) {
|
|
3972
|
+
const { env } = await this.#prepareCommand(app, "build", "csr");
|
|
3309
3973
|
const processEnv = env;
|
|
3310
3974
|
const akanjsPrefix = process.env.USE_AKANJS_PKGS === "true" ? "../../../../pkgs/" : "";
|
|
3311
3975
|
const config = vite.defineConfig({
|
|
3312
3976
|
root: `${app.cwdPath}/app`,
|
|
3313
3977
|
base: "/",
|
|
3314
3978
|
build: {
|
|
3315
|
-
outDir: `${
|
|
3979
|
+
outDir: `${app.dist.cwdPath}/csr`,
|
|
3316
3980
|
sourcemap: false,
|
|
3317
3981
|
emptyOutDir: true,
|
|
3318
3982
|
rollupOptions: { external: ["next/server"], input: `${app.cwdPath}/app/index.html` }
|
|
@@ -3370,18 +4034,20 @@ var ApplicationRunner = class {
|
|
|
3370
4034
|
});
|
|
3371
4035
|
return config;
|
|
3372
4036
|
}
|
|
3373
|
-
async buildCsr(app
|
|
3374
|
-
const config = await this.#getViteConfig(app
|
|
4037
|
+
async buildCsr(app) {
|
|
4038
|
+
const config = await this.#getViteConfig(app);
|
|
3375
4039
|
await vite.build(config);
|
|
3376
4040
|
}
|
|
3377
|
-
async serveCsr(app,
|
|
3378
|
-
const config = await this.#getViteConfig(app
|
|
4041
|
+
async serveCsr(app, { open: open2 = false } = {}) {
|
|
4042
|
+
const config = await this.#getViteConfig(app);
|
|
3379
4043
|
const server = await vite.createServer(config);
|
|
3380
4044
|
await server.listen(4201);
|
|
3381
4045
|
app.log(`CSR server is running on http://localhost:4201`);
|
|
4046
|
+
if (open2)
|
|
4047
|
+
setTimeout(() => (0, import_open.default)("http://localhost:4201"), 3e3);
|
|
3382
4048
|
}
|
|
3383
4049
|
async #prepareIos(app) {
|
|
3384
|
-
const isAdded =
|
|
4050
|
+
const isAdded = import_fs10.default.existsSync(`${app.cwdPath}/ios/App/Podfile`);
|
|
3385
4051
|
if (!isAdded) {
|
|
3386
4052
|
await app.spawn("npx", ["cap", "add", "ios"]);
|
|
3387
4053
|
await app.spawn("npx", ["@capacitor/assets", "generate"]);
|
|
@@ -3416,7 +4082,7 @@ var ApplicationRunner = class {
|
|
|
3416
4082
|
await capacitorApp.releaseIos();
|
|
3417
4083
|
}
|
|
3418
4084
|
async #prepareAndroid(app) {
|
|
3419
|
-
const isAdded =
|
|
4085
|
+
const isAdded = import_fs10.default.existsSync(`${app.cwdPath}/android/app/build.gradle`);
|
|
3420
4086
|
if (!isAdded) {
|
|
3421
4087
|
await app.spawn("npx", ["cap", "add", "android"]);
|
|
3422
4088
|
await app.spawn("npx", ["@capacitor/assets", "generate"]);
|
|
@@ -3495,24 +4161,23 @@ var ApplicationRunner = class {
|
|
|
3495
4161
|
await capacitorApp.save();
|
|
3496
4162
|
}
|
|
3497
4163
|
async releaseSource(app, { rebuild, buildNum = 0, environment = "debug", local = true } = {}) {
|
|
3498
|
-
const distApp = DistAppExecutor.from(app, app.name);
|
|
3499
4164
|
const buildRoot = `${app.workspace.workspaceRoot}/releases/builds/${app.name}`;
|
|
3500
4165
|
const appVersionInfo = import_js_yaml2.default.load(app.readFile("config.yaml"));
|
|
3501
4166
|
const platformVersion = appVersionInfo.platforms.android.versionName;
|
|
3502
|
-
if (
|
|
4167
|
+
if (import_fs10.default.existsSync(buildRoot))
|
|
3503
4168
|
await import_promises2.default.rm(buildRoot, { recursive: true, force: true });
|
|
3504
4169
|
await import_promises2.default.mkdir(buildRoot, { recursive: true });
|
|
3505
|
-
if (rebuild || !
|
|
3506
|
-
await this.buildBackend(app
|
|
3507
|
-
if (rebuild || !
|
|
3508
|
-
await this.buildFrontend(app
|
|
3509
|
-
if (rebuild || !
|
|
3510
|
-
await this.buildCsr(app
|
|
4170
|
+
if (rebuild || !import_fs10.default.existsSync(`${app.dist.cwdPath}/backend`))
|
|
4171
|
+
await this.buildBackend(app);
|
|
4172
|
+
if (rebuild || !import_fs10.default.existsSync(`${app.dist.cwdPath}/frontend`))
|
|
4173
|
+
await this.buildFrontend(app);
|
|
4174
|
+
if (rebuild || !import_fs10.default.existsSync(`${app.dist.cwdPath}/csr`))
|
|
4175
|
+
await this.buildCsr(app);
|
|
3511
4176
|
const buildVersion = `${platformVersion}-${buildNum}`;
|
|
3512
4177
|
const buildPath = `${buildRoot}/${buildVersion}`;
|
|
3513
4178
|
await import_promises2.default.mkdir(buildPath, { recursive: true });
|
|
3514
|
-
await import_promises2.default.cp(`${
|
|
3515
|
-
await import_promises2.default.cp(
|
|
4179
|
+
await import_promises2.default.cp(`${app.dist.cwdPath}/backend`, `${buildPath}/backend`, { recursive: true });
|
|
4180
|
+
await import_promises2.default.cp(app.dist.cwdPath, buildRoot, { recursive: true });
|
|
3516
4181
|
await import_promises2.default.rm(`${buildRoot}/frontend/.next`, { recursive: true, force: true });
|
|
3517
4182
|
await app.workspace.spawn("tar", [
|
|
3518
4183
|
"-zcf",
|
|
@@ -3521,8 +4186,8 @@ var ApplicationRunner = class {
|
|
|
3521
4186
|
buildRoot,
|
|
3522
4187
|
"./"
|
|
3523
4188
|
]);
|
|
3524
|
-
if (
|
|
3525
|
-
await import_promises2.default.cp(`${
|
|
4189
|
+
if (import_fs10.default.existsSync(`${app.dist.cwdPath}/csr`)) {
|
|
4190
|
+
await import_promises2.default.cp(`${app.dist.cwdPath}/csr`, "./csr", { recursive: true });
|
|
3526
4191
|
await app.workspace.spawn("zip", [
|
|
3527
4192
|
"-r",
|
|
3528
4193
|
`${app.workspace.workspaceRoot}/releases/builds/${app.name}-appBuild.zip`,
|
|
@@ -3531,7 +4196,7 @@ var ApplicationRunner = class {
|
|
|
3531
4196
|
await import_promises2.default.rm("./csr", { recursive: true, force: true });
|
|
3532
4197
|
}
|
|
3533
4198
|
const sourceRoot = `${app.workspace.workspaceRoot}/releases/sources/${app.name}`;
|
|
3534
|
-
if (
|
|
4199
|
+
if (import_fs10.default.existsSync(sourceRoot)) {
|
|
3535
4200
|
const MAX_RETRY = 3;
|
|
3536
4201
|
for (let i = 0; i < MAX_RETRY; i++) {
|
|
3537
4202
|
try {
|
|
@@ -3541,7 +4206,7 @@ var ApplicationRunner = class {
|
|
|
3541
4206
|
}
|
|
3542
4207
|
}
|
|
3543
4208
|
await import_promises2.default.mkdir(sourceRoot, { recursive: true });
|
|
3544
|
-
await import_promises2.default.cp(
|
|
4209
|
+
await import_promises2.default.cp(app.dist.cwdPath, `${sourceRoot}/apps/${app.name}`, { recursive: true });
|
|
3545
4210
|
const libDeps = ["social", "shared", "platform", "util"];
|
|
3546
4211
|
await Promise.all(
|
|
3547
4212
|
libDeps.map(
|
|
@@ -3551,7 +4216,7 @@ var ApplicationRunner = class {
|
|
|
3551
4216
|
await Promise.all(
|
|
3552
4217
|
[".next", "ios", "android", "public/libs"].map(async (path7) => {
|
|
3553
4218
|
const targetPath = `${sourceRoot}/apps/${app.name}/${path7}`;
|
|
3554
|
-
if (
|
|
4219
|
+
if (import_fs10.default.existsSync(targetPath))
|
|
3555
4220
|
await import_promises2.default.rm(targetPath, { recursive: true, force: true });
|
|
3556
4221
|
})
|
|
3557
4222
|
);
|
|
@@ -3579,8 +4244,8 @@ var ApplicationRunner = class {
|
|
|
3579
4244
|
[]
|
|
3580
4245
|
)
|
|
3581
4246
|
]);
|
|
3582
|
-
|
|
3583
|
-
|
|
4247
|
+
import_fs10.default.writeFileSync(`${sourceRoot}/tsconfig.json`, JSON.stringify(tsconfig, null, 2));
|
|
4248
|
+
import_fs10.default.writeFileSync(
|
|
3584
4249
|
`${sourceRoot}/README.md`,
|
|
3585
4250
|
`# ${app.name}
|
|
3586
4251
|
\uBCF8 \uD504\uB85C\uC81D\uD2B8\uC758 \uC18C\uC2A4\uCF54\uB4DC \uBC0F \uAD00\uB828\uC790\uB8CC\uB294 \uBAA8\uB450 \uBE44\uBC00\uC815\uBCF4\uB85C \uAD00\uB9AC\uB429\uB2C8\uB2E4.
|
|
@@ -3680,9 +4345,14 @@ var ApplicationRunner = class {
|
|
|
3680
4345
|
var ApplicationScript = class {
|
|
3681
4346
|
#runner = new ApplicationRunner();
|
|
3682
4347
|
libraryScript = new LibraryScript();
|
|
3683
|
-
async createApplication(appName, workspace) {
|
|
4348
|
+
async createApplication(appName, workspace, { serve = false } = {}) {
|
|
3684
4349
|
const app = await this.#runner.createApplication(appName, workspace);
|
|
3685
4350
|
await this.syncApplication(app);
|
|
4351
|
+
if (serve)
|
|
4352
|
+
await this.serve(app, { open: true });
|
|
4353
|
+
}
|
|
4354
|
+
async removeApplication(app) {
|
|
4355
|
+
await this.#runner.removeApplication(app);
|
|
3686
4356
|
}
|
|
3687
4357
|
async scanApplication(app, verbose = false) {
|
|
3688
4358
|
const scanResult = await this.#runner.scanSync(app);
|
|
@@ -3697,64 +4367,78 @@ var ApplicationScript = class {
|
|
|
3697
4367
|
for (const libName of scanResult.akanConfig.libs)
|
|
3698
4368
|
await this.libraryScript.syncLibrary(LibExecutor.from(app, libName), { recursive: false });
|
|
3699
4369
|
}
|
|
3700
|
-
async build(app
|
|
3701
|
-
await this.syncApplication(app);
|
|
3702
|
-
await Promise.all([this.buildBackend(app, distApp), this.buildFrontend(app, distApp)]);
|
|
3703
|
-
}
|
|
3704
|
-
async serve(app, distApp = DistAppExecutor.from(app, app.name)) {
|
|
3705
|
-
await this.syncApplication(app);
|
|
3706
|
-
await Promise.all([this.#runner.serveBackend(app, distApp), this.#runner.serveFrontend(app, distApp)]);
|
|
3707
|
-
}
|
|
3708
|
-
async buildBackend(app, distApp = DistAppExecutor.from(app, app.name)) {
|
|
3709
|
-
await this.syncApplication(app);
|
|
3710
|
-
await this.#runner.buildBackend(app, distApp);
|
|
3711
|
-
}
|
|
3712
|
-
async serveBackend(app, distApp = DistAppExecutor.from(app, app.name)) {
|
|
3713
|
-
await this.syncApplication(app);
|
|
3714
|
-
await this.#runner.serveBackend(app, distApp);
|
|
3715
|
-
}
|
|
3716
|
-
async buildFrontend(app, distApp = DistAppExecutor.from(app, app.name)) {
|
|
3717
|
-
await this.syncApplication(app);
|
|
3718
|
-
await this.#runner.buildFrontend(app, distApp);
|
|
3719
|
-
}
|
|
3720
|
-
async serveFrontend(app, distApp = DistAppExecutor.from(app, app.name)) {
|
|
3721
|
-
await this.syncApplication(app);
|
|
3722
|
-
await this.#runner.serveFrontend(app, distApp);
|
|
3723
|
-
}
|
|
3724
|
-
async buildCsr(app, distApp = DistAppExecutor.from(app, app.name)) {
|
|
3725
|
-
await this.syncApplication(app);
|
|
3726
|
-
await this.#runner.buildCsr(app, distApp);
|
|
3727
|
-
}
|
|
3728
|
-
async serveCsr(app, distApp = DistAppExecutor.from(app, app.name)) {
|
|
4370
|
+
async build(app) {
|
|
3729
4371
|
await this.syncApplication(app);
|
|
3730
|
-
await this
|
|
4372
|
+
await Promise.all([this.buildBackend(app, { sync: false }), this.buildFrontend(app, { sync: false })]);
|
|
3731
4373
|
}
|
|
3732
|
-
async
|
|
4374
|
+
async serve(app, { open: open2 = false } = {}) {
|
|
3733
4375
|
await this.syncApplication(app);
|
|
3734
|
-
await this
|
|
4376
|
+
await Promise.all([this.serveBackend(app, { open: open2, sync: false }), this.serveFrontend(app, { open: open2, sync: false })]);
|
|
4377
|
+
}
|
|
4378
|
+
async buildBackend(app, { sync = true } = {}) {
|
|
4379
|
+
if (sync)
|
|
4380
|
+
await this.syncApplication(app);
|
|
4381
|
+
await this.#runner.buildBackend(app);
|
|
4382
|
+
}
|
|
4383
|
+
async serveBackend(app, { open: open2 = false, sync = true } = {}) {
|
|
4384
|
+
if (sync)
|
|
4385
|
+
await this.syncApplication(app);
|
|
4386
|
+
await this.#runner.serveBackend(app, { open: open2 });
|
|
4387
|
+
}
|
|
4388
|
+
async buildFrontend(app, { sync = true } = {}) {
|
|
4389
|
+
if (sync)
|
|
4390
|
+
await this.syncApplication(app);
|
|
4391
|
+
await this.#runner.buildFrontend(app);
|
|
4392
|
+
}
|
|
4393
|
+
async serveFrontend(app, { open: open2 = false, turbo = false, sync = true } = {}) {
|
|
4394
|
+
if (sync)
|
|
4395
|
+
await this.syncApplication(app);
|
|
4396
|
+
await this.#runner.serveFrontend(app, { open: open2, turbo });
|
|
4397
|
+
}
|
|
4398
|
+
async buildCsr(app, { sync = true } = {}) {
|
|
4399
|
+
if (sync)
|
|
4400
|
+
await this.syncApplication(app);
|
|
4401
|
+
await this.#runner.buildCsr(app);
|
|
4402
|
+
}
|
|
4403
|
+
async serveCsr(app, { open: open2 = false, sync = true } = {}) {
|
|
4404
|
+
if (sync)
|
|
4405
|
+
await this.syncApplication(app);
|
|
4406
|
+
await this.#runner.serveCsr(app, { open: open2 });
|
|
4407
|
+
}
|
|
4408
|
+
async buildIos(app, { sync = true } = {}) {
|
|
4409
|
+
if (sync)
|
|
4410
|
+
await this.syncApplication(app);
|
|
3735
4411
|
await this.#runner.buildIos(app);
|
|
3736
4412
|
}
|
|
3737
|
-
async serveIos(app, {
|
|
3738
|
-
|
|
3739
|
-
|
|
4413
|
+
async serveIos(app, {
|
|
4414
|
+
open: open2 = false,
|
|
4415
|
+
operation = "local",
|
|
4416
|
+
sync = true
|
|
4417
|
+
} = {}) {
|
|
4418
|
+
if (sync)
|
|
4419
|
+
await this.syncApplication(app);
|
|
3740
4420
|
await this.#runner.serveIos(app, { open: open2, operation });
|
|
3741
4421
|
}
|
|
3742
|
-
async releaseIos(app) {
|
|
3743
|
-
await this.buildCsr(app);
|
|
4422
|
+
async releaseIos(app, { sync = true } = {}) {
|
|
4423
|
+
await this.buildCsr(app, { sync });
|
|
3744
4424
|
await this.#runner.releaseIos(app);
|
|
3745
4425
|
}
|
|
3746
|
-
async buildAndroid(app) {
|
|
3747
|
-
|
|
3748
|
-
|
|
4426
|
+
async buildAndroid(app, { sync = true } = {}) {
|
|
4427
|
+
if (sync)
|
|
4428
|
+
await this.syncApplication(app);
|
|
3749
4429
|
await this.#runner.buildAndroid(app);
|
|
3750
4430
|
}
|
|
3751
|
-
async serveAndroid(app, {
|
|
3752
|
-
|
|
3753
|
-
|
|
4431
|
+
async serveAndroid(app, {
|
|
4432
|
+
open: open2 = false,
|
|
4433
|
+
operation = "local",
|
|
4434
|
+
sync = true
|
|
4435
|
+
} = {}) {
|
|
4436
|
+
if (sync)
|
|
4437
|
+
await this.syncApplication(app);
|
|
3754
4438
|
await this.#runner.serveAndroid(app, { open: open2, operation });
|
|
3755
4439
|
}
|
|
3756
|
-
async releaseAndroid(app) {
|
|
3757
|
-
await this.buildCsr(app);
|
|
4440
|
+
async releaseAndroid(app, { sync = true } = {}) {
|
|
4441
|
+
await this.buildCsr(app, { sync });
|
|
3758
4442
|
await this.#runner.releaseAndroid(app);
|
|
3759
4443
|
}
|
|
3760
4444
|
async dumpDatabase(app, environment) {
|
|
@@ -3797,10 +4481,11 @@ var ApplicationScript = class {
|
|
|
3797
4481
|
// pkgs/@akanjs/cli/src/application/application.command.ts
|
|
3798
4482
|
var ApplicationCommand = class {
|
|
3799
4483
|
applicationScript = new ApplicationScript();
|
|
3800
|
-
async createApplication(name, workspace) {
|
|
3801
|
-
await this.applicationScript.createApplication(name, workspace);
|
|
4484
|
+
async createApplication(name, serve, workspace) {
|
|
4485
|
+
await this.applicationScript.createApplication(name, workspace, { serve });
|
|
3802
4486
|
}
|
|
3803
|
-
async removeApplication(app
|
|
4487
|
+
async removeApplication(app) {
|
|
4488
|
+
await this.applicationScript.removeApplication(app);
|
|
3804
4489
|
}
|
|
3805
4490
|
async scanApplication(app) {
|
|
3806
4491
|
await this.applicationScript.scanApplication(app, true);
|
|
@@ -3823,17 +4508,17 @@ var ApplicationCommand = class {
|
|
|
3823
4508
|
async buildAndroid(app) {
|
|
3824
4509
|
await this.applicationScript.buildAndroid(app);
|
|
3825
4510
|
}
|
|
3826
|
-
async serve(app) {
|
|
3827
|
-
await this.applicationScript.serve(app);
|
|
4511
|
+
async serve(app, open2) {
|
|
4512
|
+
await this.applicationScript.serve(app, { open: open2 });
|
|
3828
4513
|
}
|
|
3829
|
-
async serveBackend(app) {
|
|
3830
|
-
await this.applicationScript.serveBackend(app);
|
|
4514
|
+
async serveBackend(app, open2) {
|
|
4515
|
+
await this.applicationScript.serveBackend(app, { open: open2 });
|
|
3831
4516
|
}
|
|
3832
|
-
async serveFrontend(app) {
|
|
3833
|
-
await this.applicationScript.serveFrontend(app);
|
|
4517
|
+
async serveFrontend(app, open2, turbo) {
|
|
4518
|
+
await this.applicationScript.serveFrontend(app, { open: open2, turbo });
|
|
3834
4519
|
}
|
|
3835
|
-
async serveCsr(app) {
|
|
3836
|
-
await this.applicationScript.serveCsr(app);
|
|
4520
|
+
async serveCsr(app, open2) {
|
|
4521
|
+
await this.applicationScript.serveCsr(app, { open: open2 });
|
|
3837
4522
|
}
|
|
3838
4523
|
async serveIos(app, open2, release) {
|
|
3839
4524
|
await this.applicationScript.serveIos(app, { open: open2, operation: release ? "release" : "local" });
|
|
@@ -3875,12 +4560,12 @@ var ApplicationCommand = class {
|
|
|
3875
4560
|
__decorateClass([
|
|
3876
4561
|
Target.Public(),
|
|
3877
4562
|
__decorateParam(0, Option("name", { desc: "name of application" })),
|
|
3878
|
-
__decorateParam(1,
|
|
4563
|
+
__decorateParam(1, Option("serve", { type: "boolean", desc: "serve application", default: false })),
|
|
4564
|
+
__decorateParam(2, Workspace())
|
|
3879
4565
|
], ApplicationCommand.prototype, "createApplication", 1);
|
|
3880
4566
|
__decorateClass([
|
|
3881
4567
|
Target.Public(),
|
|
3882
|
-
__decorateParam(0, App())
|
|
3883
|
-
__decorateParam(1, Workspace())
|
|
4568
|
+
__decorateParam(0, App())
|
|
3884
4569
|
], ApplicationCommand.prototype, "removeApplication", 1);
|
|
3885
4570
|
__decorateClass([
|
|
3886
4571
|
Target.Public(),
|
|
@@ -3912,31 +4597,36 @@ __decorateClass([
|
|
|
3912
4597
|
], ApplicationCommand.prototype, "buildAndroid", 1);
|
|
3913
4598
|
__decorateClass([
|
|
3914
4599
|
Target.Public({ short: true }),
|
|
3915
|
-
__decorateParam(0, App())
|
|
4600
|
+
__decorateParam(0, App()),
|
|
4601
|
+
__decorateParam(1, Option("open", { type: "boolean", desc: "open web browser", default: false }))
|
|
3916
4602
|
], ApplicationCommand.prototype, "serve", 1);
|
|
3917
4603
|
__decorateClass([
|
|
3918
4604
|
Target.Public({ short: true }),
|
|
3919
|
-
__decorateParam(0, App())
|
|
4605
|
+
__decorateParam(0, App()),
|
|
4606
|
+
__decorateParam(1, Option("open", { type: "boolean", desc: "open graphql playground", default: false }))
|
|
3920
4607
|
], ApplicationCommand.prototype, "serveBackend", 1);
|
|
3921
4608
|
__decorateClass([
|
|
3922
4609
|
Target.Public({ short: true }),
|
|
3923
|
-
__decorateParam(0, App())
|
|
4610
|
+
__decorateParam(0, App()),
|
|
4611
|
+
__decorateParam(1, Option("open", { type: "boolean", desc: "open web browser", default: false })),
|
|
4612
|
+
__decorateParam(2, Option("turbo", { type: "boolean", desc: "turbo", default: false }))
|
|
3924
4613
|
], ApplicationCommand.prototype, "serveFrontend", 1);
|
|
3925
4614
|
__decorateClass([
|
|
3926
4615
|
Target.Public({ short: true }),
|
|
3927
|
-
__decorateParam(0, App())
|
|
4616
|
+
__decorateParam(0, App()),
|
|
4617
|
+
__decorateParam(1, Option("open", { type: "boolean", desc: "open web browser", default: false }))
|
|
3928
4618
|
], ApplicationCommand.prototype, "serveCsr", 1);
|
|
3929
4619
|
__decorateClass([
|
|
3930
4620
|
Target.Public({ short: true }),
|
|
3931
4621
|
__decorateParam(0, App()),
|
|
3932
|
-
__decorateParam(1, Option("open", { desc: "open ios simulator", default: false })),
|
|
3933
|
-
__decorateParam(2, Option("release", { desc: "release mode", default: false }))
|
|
4622
|
+
__decorateParam(1, Option("open", { type: "boolean", desc: "open ios simulator", default: false })),
|
|
4623
|
+
__decorateParam(2, Option("release", { type: "boolean", desc: "release mode", default: false }))
|
|
3934
4624
|
], ApplicationCommand.prototype, "serveIos", 1);
|
|
3935
4625
|
__decorateClass([
|
|
3936
4626
|
Target.Public({ short: true }),
|
|
3937
4627
|
__decorateParam(0, App()),
|
|
3938
|
-
__decorateParam(1, Option("open", { desc: "open android simulator", default: false })),
|
|
3939
|
-
__decorateParam(2, Option("release", { desc: "release mode", default: false }))
|
|
4628
|
+
__decorateParam(1, Option("open", { type: "boolean", desc: "open android simulator", default: false })),
|
|
4629
|
+
__decorateParam(2, Option("release", { type: "boolean", desc: "release mode", default: false }))
|
|
3940
4630
|
], ApplicationCommand.prototype, "serveAndroid", 1);
|
|
3941
4631
|
__decorateClass([
|
|
3942
4632
|
Target.Public(),
|
|
@@ -3949,10 +4639,10 @@ __decorateClass([
|
|
|
3949
4639
|
__decorateClass([
|
|
3950
4640
|
Target.Public(),
|
|
3951
4641
|
__decorateParam(0, App()),
|
|
3952
|
-
__decorateParam(1, Option("rebuild", { desc: "rebuild", default: false })),
|
|
4642
|
+
__decorateParam(1, Option("rebuild", { type: "boolean", desc: "rebuild", default: false })),
|
|
3953
4643
|
__decorateParam(2, Option("buildNum", { desc: "build number", default: 0 })),
|
|
3954
4644
|
__decorateParam(3, Option("environment", { desc: "environment", default: "debug" })),
|
|
3955
|
-
__decorateParam(4, Option("local", { desc: "local", default: true }))
|
|
4645
|
+
__decorateParam(4, Option("local", { type: "boolean", desc: "local", default: true }))
|
|
3956
4646
|
], ApplicationCommand.prototype, "releaseSource", 1);
|
|
3957
4647
|
__decorateClass([
|
|
3958
4648
|
Target.Public(),
|
|
@@ -4007,7 +4697,7 @@ ApplicationCommand = __decorateClass([
|
|
|
4007
4697
|
// pkgs/@akanjs/cli/src/package/package.runner.ts
|
|
4008
4698
|
var esbuild2 = __toESM(require("esbuild"));
|
|
4009
4699
|
var import_esbuild_plugin_d = require("esbuild-plugin-d.ts");
|
|
4010
|
-
var
|
|
4700
|
+
var import_fs11 = __toESM(require("fs"));
|
|
4011
4701
|
var import_promises3 = __toESM(require("fs/promises"));
|
|
4012
4702
|
var PackageRunner = class {
|
|
4013
4703
|
async version(workspace) {
|
|
@@ -4022,15 +4712,19 @@ var PackageRunner = class {
|
|
|
4022
4712
|
dict: { pkgName, PkgName: capitalize(pkgName) }
|
|
4023
4713
|
});
|
|
4024
4714
|
}
|
|
4715
|
+
async removePackage(pkg) {
|
|
4716
|
+
await pkg.workspace.exec(`rm -rf pkgs/${pkg.name}`);
|
|
4717
|
+
pkg.log(`Package ${pkg.name} removed`);
|
|
4718
|
+
}
|
|
4025
4719
|
async scanSync(pkg) {
|
|
4026
4720
|
const scanResult = await pkg.scan();
|
|
4027
4721
|
return scanResult;
|
|
4028
4722
|
}
|
|
4029
|
-
async buildPackage(pkg
|
|
4723
|
+
async buildPackage(pkg) {
|
|
4030
4724
|
const rootPackageJson = pkg.workspace.readJson("package.json");
|
|
4031
4725
|
const pkgJson = pkg.readJson("package.json");
|
|
4032
|
-
if (
|
|
4033
|
-
await pkg.workspace.exec(`rm -rf ${
|
|
4726
|
+
if (import_fs11.default.existsSync(pkg.dist.cwdPath))
|
|
4727
|
+
await pkg.workspace.exec(`rm -rf ${pkg.dist.cwdPath}`);
|
|
4034
4728
|
let buildResult;
|
|
4035
4729
|
if (pkg.name === "@akanjs/config") {
|
|
4036
4730
|
buildResult = await esbuild2.build({
|
|
@@ -4039,7 +4733,7 @@ var PackageRunner = class {
|
|
|
4039
4733
|
bundle: false,
|
|
4040
4734
|
packages: "external",
|
|
4041
4735
|
format: "cjs",
|
|
4042
|
-
outdir:
|
|
4736
|
+
outdir: pkg.dist.cwdPath,
|
|
4043
4737
|
logLevel: "error",
|
|
4044
4738
|
outExtension: { ".js": pkgJson.type === "module" ? ".cjs" : ".js" },
|
|
4045
4739
|
plugins: [(0, import_esbuild_plugin_d.dtsPlugin)({ tsconfig: `${pkg.cwdPath}/tsconfig.json` })]
|
|
@@ -4050,10 +4744,9 @@ var PackageRunner = class {
|
|
|
4050
4744
|
bundle: false,
|
|
4051
4745
|
packages: "external",
|
|
4052
4746
|
format: "esm",
|
|
4053
|
-
outdir:
|
|
4747
|
+
outdir: pkg.dist.cwdPath,
|
|
4054
4748
|
logLevel: "error",
|
|
4055
4749
|
outExtension: { ".js": pkgJson.type === "module" ? ".js" : ".mjs" },
|
|
4056
|
-
// copy css files
|
|
4057
4750
|
loader: { ".css": "copy", ".js": "copy" }
|
|
4058
4751
|
});
|
|
4059
4752
|
} else if (pkg.name === "@akanjs/cli") {
|
|
@@ -4063,7 +4756,7 @@ var PackageRunner = class {
|
|
|
4063
4756
|
bundle: true,
|
|
4064
4757
|
format: "cjs",
|
|
4065
4758
|
packages: "external",
|
|
4066
|
-
outdir:
|
|
4759
|
+
outdir: pkg.dist.cwdPath,
|
|
4067
4760
|
logLevel: "error",
|
|
4068
4761
|
plugins: [(0, import_esbuild_plugin_d.dtsPlugin)({ tsconfig: `${pkg.cwdPath}/tsconfig.json` })]
|
|
4069
4762
|
});
|
|
@@ -4071,14 +4764,14 @@ var PackageRunner = class {
|
|
|
4071
4764
|
write: true,
|
|
4072
4765
|
entryPoints: [`${pkg.cwdPath}/src/templates/**/*.ts`, `${pkg.cwdPath}/src/templates/**/*.tsx`],
|
|
4073
4766
|
packages: "external",
|
|
4074
|
-
outdir: `${
|
|
4767
|
+
outdir: `${pkg.dist.cwdPath}/src/templates`,
|
|
4075
4768
|
outbase: `${pkg.cwdPath}/src/templates`,
|
|
4076
4769
|
format: "cjs",
|
|
4077
4770
|
platform: "node",
|
|
4078
4771
|
footer: { js: "module.exports = module.exports.default;" }
|
|
4079
4772
|
});
|
|
4080
4773
|
await pkg.workspace.exec(
|
|
4081
|
-
`rsync -aq --exclude="*.ts" --exclude="*.tsx" ${pkg.cwdPath}/src/templates/ ${
|
|
4774
|
+
`rsync -aq --exclude="*.ts" --exclude="*.tsx" ${pkg.cwdPath}/src/templates/ ${pkg.dist.cwdPath}/src/templates/`
|
|
4082
4775
|
);
|
|
4083
4776
|
} else {
|
|
4084
4777
|
const platform = [
|
|
@@ -4097,7 +4790,7 @@ var PackageRunner = class {
|
|
|
4097
4790
|
splitting: false,
|
|
4098
4791
|
platform,
|
|
4099
4792
|
format: "cjs",
|
|
4100
|
-
outdir:
|
|
4793
|
+
outdir: pkg.dist.cwdPath,
|
|
4101
4794
|
outExtension: { ".js": pkgJson.type === "module" ? ".cjs" : ".js" },
|
|
4102
4795
|
logLevel: "error",
|
|
4103
4796
|
plugins: [(0, import_esbuild_plugin_d.dtsPlugin)({ tsconfig: `${pkg.cwdPath}/tsconfig.json` })]
|
|
@@ -4110,7 +4803,7 @@ var PackageRunner = class {
|
|
|
4110
4803
|
splitting: false,
|
|
4111
4804
|
platform,
|
|
4112
4805
|
format: "esm",
|
|
4113
|
-
outdir:
|
|
4806
|
+
outdir: pkg.dist.cwdPath,
|
|
4114
4807
|
outExtension: { ".js": pkgJson.type === "module" ? ".js" : ".mjs" },
|
|
4115
4808
|
logLevel: "error",
|
|
4116
4809
|
plugins: []
|
|
@@ -4133,8 +4826,8 @@ var PackageRunner = class {
|
|
|
4133
4826
|
}
|
|
4134
4827
|
};
|
|
4135
4828
|
if (buildResult.outputFiles)
|
|
4136
|
-
buildResult.outputFiles.map((file) =>
|
|
4137
|
-
|
|
4829
|
+
buildResult.outputFiles.map((file) => pkg.dist.writeFile(file.path, file.text));
|
|
4830
|
+
pkg.dist.writeJson("package.json", pkgPackageJson);
|
|
4138
4831
|
pkg.writeJson("package.json", pkgPackageJson);
|
|
4139
4832
|
}
|
|
4140
4833
|
};
|
|
@@ -4148,20 +4841,23 @@ var PackageScript = class {
|
|
|
4148
4841
|
async createPackage(workspace, pkgName) {
|
|
4149
4842
|
await this.#runner.createPackage(workspace, pkgName);
|
|
4150
4843
|
}
|
|
4844
|
+
async removePackage(pkg) {
|
|
4845
|
+
await this.#runner.removePackage(pkg);
|
|
4846
|
+
}
|
|
4151
4847
|
async scanPackage(pkg) {
|
|
4152
4848
|
const scanResult = await this.#runner.scanSync(pkg);
|
|
4153
4849
|
pkg.logger.rawLog(JSON.stringify(scanResult, null, 2));
|
|
4154
4850
|
}
|
|
4155
|
-
async buildPackage(pkg
|
|
4156
|
-
await this.#runner.buildPackage(pkg
|
|
4851
|
+
async buildPackage(pkg) {
|
|
4852
|
+
await this.#runner.buildPackage(pkg);
|
|
4157
4853
|
}
|
|
4158
4854
|
};
|
|
4159
4855
|
|
|
4160
4856
|
// pkgs/@akanjs/cli/src/cloud/cloud.runner.ts
|
|
4161
4857
|
var import_prompts7 = require("@inquirer/prompts");
|
|
4162
|
-
var
|
|
4858
|
+
var import_chalk2 = __toESM(require("chalk"));
|
|
4163
4859
|
var import_latest_version = __toESM(require("latest-version"));
|
|
4164
|
-
var
|
|
4860
|
+
var import_open2 = __toESM(require("open"));
|
|
4165
4861
|
var QRcode = __toESM(require("qrcode"));
|
|
4166
4862
|
var import_uuid = require("uuid");
|
|
4167
4863
|
var CloudRunner = class {
|
|
@@ -4169,17 +4865,17 @@ var CloudRunner = class {
|
|
|
4169
4865
|
const config = getHostConfig();
|
|
4170
4866
|
const self = config.auth ? await getSelf(config.auth.token) : null;
|
|
4171
4867
|
if (self) {
|
|
4172
|
-
Logger.rawLog(
|
|
4868
|
+
Logger.rawLog(import_chalk2.default.green(`
|
|
4173
4869
|
\u2713 Already logged in akan cloud as ${self.nickname}
|
|
4174
4870
|
`));
|
|
4175
4871
|
return true;
|
|
4176
4872
|
}
|
|
4177
4873
|
const remoteId = (0, import_uuid.v4)();
|
|
4178
4874
|
const signinUrl = `${akanCloudClientUrl}/signin?remoteId=${remoteId}`;
|
|
4179
|
-
Logger.rawLog(
|
|
4180
|
-
${
|
|
4181
|
-
Logger.rawLog(
|
|
4182
|
-
Logger.rawLog(
|
|
4875
|
+
Logger.rawLog(import_chalk2.default.bold(`
|
|
4876
|
+
${import_chalk2.default.green("\u27A4")} Authentication Required`));
|
|
4877
|
+
Logger.rawLog(import_chalk2.default.dim("Please visit or click the following URL:"));
|
|
4878
|
+
Logger.rawLog(import_chalk2.default.cyan.underline(signinUrl) + "\n");
|
|
4183
4879
|
try {
|
|
4184
4880
|
const qrcode = await new Promise((resolve, reject) => {
|
|
4185
4881
|
QRcode.toString(signinUrl, { type: "terminal", small: true }, (err, data) => {
|
|
@@ -4189,12 +4885,12 @@ ${import_chalk.default.green("\u27A4")} Authentication Required`));
|
|
|
4189
4885
|
});
|
|
4190
4886
|
});
|
|
4191
4887
|
Logger.rawLog(qrcode);
|
|
4192
|
-
await (0,
|
|
4193
|
-
Logger.rawLog(
|
|
4888
|
+
await (0, import_open2.default)(signinUrl);
|
|
4889
|
+
Logger.rawLog(import_chalk2.default.dim("Opening browser..."));
|
|
4194
4890
|
} catch {
|
|
4195
|
-
Logger.rawLog(
|
|
4891
|
+
Logger.rawLog(import_chalk2.default.yellow("Could not open browser. Please visit the URL manually."));
|
|
4196
4892
|
}
|
|
4197
|
-
Logger.rawLog(
|
|
4893
|
+
Logger.rawLog(import_chalk2.default.dim("Waiting for authentication..."));
|
|
4198
4894
|
const MAX_RETRY = 300;
|
|
4199
4895
|
for (let i = 0; i < MAX_RETRY; i++) {
|
|
4200
4896
|
const res = await fetch(`${akanCloudBackendUrl}/user/getRemoteAuthToken/${remoteId}`);
|
|
@@ -4202,30 +4898,38 @@ ${import_chalk.default.green("\u27A4")} Authentication Required`));
|
|
|
4202
4898
|
const self2 = jwt ? await getSelf(jwt) : null;
|
|
4203
4899
|
if (jwt && self2) {
|
|
4204
4900
|
setHostConfig(akanCloudHost, { auth: { token: jwt, self: self2 } });
|
|
4205
|
-
Logger.rawLog(
|
|
4206
|
-
Logger.rawLog(
|
|
4901
|
+
Logger.rawLog(import_chalk2.default.green(`\r\u2713 Authentication successful!`));
|
|
4902
|
+
Logger.rawLog(import_chalk2.default.green.bold(`
|
|
4207
4903
|
\u2728 Welcome aboard, ${self2.nickname}!`));
|
|
4208
|
-
Logger.rawLog(
|
|
4904
|
+
Logger.rawLog(import_chalk2.default.dim("You're now ready to use Akan CLI!\n"));
|
|
4209
4905
|
return true;
|
|
4210
4906
|
}
|
|
4211
4907
|
await sleep(2e3);
|
|
4212
4908
|
}
|
|
4213
|
-
throw new Error(
|
|
4909
|
+
throw new Error(import_chalk2.default.red("\u2716 Authentication timed out after 10 minutes. Please try again."));
|
|
4214
4910
|
}
|
|
4215
4911
|
logout() {
|
|
4216
4912
|
const config = getHostConfig();
|
|
4217
4913
|
if (config.auth) {
|
|
4218
4914
|
setHostConfig(akanCloudHost, {});
|
|
4219
|
-
Logger.rawLog(
|
|
4915
|
+
Logger.rawLog(import_chalk2.default.magenta.bold(`
|
|
4220
4916
|
\u{1F44B} Goodbye, ${config.auth.self.nickname}!`));
|
|
4221
|
-
Logger.rawLog(
|
|
4222
|
-
Logger.rawLog(
|
|
4223
|
-
Logger.rawLog(
|
|
4917
|
+
Logger.rawLog(import_chalk2.default.dim("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n"));
|
|
4918
|
+
Logger.rawLog(import_chalk2.default.cyan("You have been successfully logged out."));
|
|
4919
|
+
Logger.rawLog(import_chalk2.default.dim("Thank you for using Akan CLI. Come back soon! \u{1F31F}\n"));
|
|
4224
4920
|
} else {
|
|
4225
|
-
Logger.rawLog(
|
|
4226
|
-
Logger.rawLog(
|
|
4921
|
+
Logger.rawLog(import_chalk2.default.yellow.bold("\n\u26A0\uFE0F No active session found"));
|
|
4922
|
+
Logger.rawLog(import_chalk2.default.dim("You were not logged in to begin with\n"));
|
|
4227
4923
|
}
|
|
4228
4924
|
}
|
|
4925
|
+
async setLlm() {
|
|
4926
|
+
await AiSession.init({ useExisting: true });
|
|
4927
|
+
Logger.rawLog(import_chalk2.default.green("LLM model set successfully"));
|
|
4928
|
+
}
|
|
4929
|
+
resetLlm() {
|
|
4930
|
+
AiSession.setLlmConfig(null);
|
|
4931
|
+
Logger.rawLog(import_chalk2.default.green("LLM model reset successfully"));
|
|
4932
|
+
}
|
|
4229
4933
|
async getAkanPkgs(workspace) {
|
|
4230
4934
|
const pkgs = await workspace.getPkgs();
|
|
4231
4935
|
const akanPkgs = pkgs.filter((pkg) => pkg.startsWith("@akanjs/"));
|
|
@@ -4247,20 +4951,7 @@ ${import_chalk.default.green("\u27A4")} Authentication Required`));
|
|
|
4247
4951
|
const newPackageJsonStr = JSON.stringify({ ...packageJson, version: nextVersion }, null, 2);
|
|
4248
4952
|
workspace.writeFile(`pkgs/${library}/package.json`, newPackageJsonStr);
|
|
4249
4953
|
const distPackageJson = workspace.readJson(`dist/pkgs/${library}/package.json`);
|
|
4250
|
-
const newDistPackageJson = {
|
|
4251
|
-
...distPackageJson,
|
|
4252
|
-
// ...(distPackageJson.dependencies
|
|
4253
|
-
// ? {
|
|
4254
|
-
// dependencies: Object.fromEntries(
|
|
4255
|
-
// Object.entries(distPackageJson.dependencies).map(([key, value]) => [
|
|
4256
|
-
// key,
|
|
4257
|
-
// value.startsWith("^") ? value : `^${value}`,
|
|
4258
|
-
// ])
|
|
4259
|
-
// ),
|
|
4260
|
-
// }
|
|
4261
|
-
// : {}),
|
|
4262
|
-
version: nextVersion
|
|
4263
|
-
};
|
|
4954
|
+
const newDistPackageJson = { ...distPackageJson, version: nextVersion };
|
|
4264
4955
|
workspace.writeJson(`dist/pkgs/${library}/package.json`, newDistPackageJson);
|
|
4265
4956
|
}
|
|
4266
4957
|
const isDeployConfirmed = await (0, import_prompts7.confirm)({
|
|
@@ -4291,6 +4982,17 @@ var CloudScript = class {
|
|
|
4291
4982
|
logout() {
|
|
4292
4983
|
this.#runner.logout();
|
|
4293
4984
|
}
|
|
4985
|
+
async setLlm() {
|
|
4986
|
+
await this.#runner.setLlm();
|
|
4987
|
+
}
|
|
4988
|
+
resetLlm() {
|
|
4989
|
+
this.#runner.resetLlm();
|
|
4990
|
+
}
|
|
4991
|
+
async ask(question) {
|
|
4992
|
+
await AiSession.init();
|
|
4993
|
+
const session = new AiSession();
|
|
4994
|
+
await session.ask(question);
|
|
4995
|
+
}
|
|
4294
4996
|
async deployAkan(workspace) {
|
|
4295
4997
|
const akanPkgs = await this.#runner.getAkanPkgs(workspace);
|
|
4296
4998
|
await Promise.all(
|
|
@@ -4309,6 +5011,15 @@ var CloudCommand = class {
|
|
|
4309
5011
|
logout() {
|
|
4310
5012
|
this.cloudScript.logout();
|
|
4311
5013
|
}
|
|
5014
|
+
async setLlm() {
|
|
5015
|
+
await this.cloudScript.setLlm();
|
|
5016
|
+
}
|
|
5017
|
+
resetLlm() {
|
|
5018
|
+
this.cloudScript.resetLlm();
|
|
5019
|
+
}
|
|
5020
|
+
async ask(question) {
|
|
5021
|
+
await this.cloudScript.ask(question);
|
|
5022
|
+
}
|
|
4312
5023
|
async deployAkan(workspace) {
|
|
4313
5024
|
await this.cloudScript.deployAkan(workspace);
|
|
4314
5025
|
}
|
|
@@ -4319,6 +5030,16 @@ __decorateClass([
|
|
|
4319
5030
|
__decorateClass([
|
|
4320
5031
|
Target.Public()
|
|
4321
5032
|
], CloudCommand.prototype, "logout", 1);
|
|
5033
|
+
__decorateClass([
|
|
5034
|
+
Target.Public()
|
|
5035
|
+
], CloudCommand.prototype, "setLlm", 1);
|
|
5036
|
+
__decorateClass([
|
|
5037
|
+
Target.Public()
|
|
5038
|
+
], CloudCommand.prototype, "resetLlm", 1);
|
|
5039
|
+
__decorateClass([
|
|
5040
|
+
Target.Public(),
|
|
5041
|
+
__decorateParam(0, Option("question", { ask: "question to ask" }))
|
|
5042
|
+
], CloudCommand.prototype, "ask", 1);
|
|
4322
5043
|
__decorateClass([
|
|
4323
5044
|
Target.Public({ devOnly: true }),
|
|
4324
5045
|
__decorateParam(0, Workspace())
|
|
@@ -4331,8 +5052,10 @@ CloudCommand = __decorateClass([
|
|
|
4331
5052
|
var LibraryCommand = class {
|
|
4332
5053
|
libraryScript = new LibraryScript();
|
|
4333
5054
|
async createLibrary(name, workspace) {
|
|
5055
|
+
await this.libraryScript.createLibrary(name, workspace);
|
|
4334
5056
|
}
|
|
4335
|
-
async removeLibrary(lib
|
|
5057
|
+
async removeLibrary(lib) {
|
|
5058
|
+
await this.libraryScript.removeLibrary(lib);
|
|
4336
5059
|
}
|
|
4337
5060
|
async scanLibrary(lib) {
|
|
4338
5061
|
await this.libraryScript.scanLibrary(lib, true);
|
|
@@ -4356,8 +5079,7 @@ __decorateClass([
|
|
|
4356
5079
|
], LibraryCommand.prototype, "createLibrary", 1);
|
|
4357
5080
|
__decorateClass([
|
|
4358
5081
|
Target.Public(),
|
|
4359
|
-
__decorateParam(0, Lib())
|
|
4360
|
-
__decorateParam(1, Workspace())
|
|
5082
|
+
__decorateParam(0, Lib())
|
|
4361
5083
|
], LibraryCommand.prototype, "removeLibrary", 1);
|
|
4362
5084
|
__decorateClass([
|
|
4363
5085
|
Target.Public(),
|
|
@@ -4386,8 +5108,11 @@ LibraryCommand = __decorateClass([
|
|
|
4386
5108
|
Commands()
|
|
4387
5109
|
], LibraryCommand);
|
|
4388
5110
|
|
|
5111
|
+
// pkgs/@akanjs/cli/src/module/module.script.ts
|
|
5112
|
+
var import_prompts8 = require("@inquirer/prompts");
|
|
5113
|
+
var import_fs12 = __toESM(require("fs"));
|
|
5114
|
+
|
|
4389
5115
|
// pkgs/@akanjs/cli/src/module/module.runner.ts
|
|
4390
|
-
var import_fs14 = __toESM(require("fs"));
|
|
4391
5116
|
var ModuleRunner = class {
|
|
4392
5117
|
async createModule(workspace, sysType, sysName, moduleName, description) {
|
|
4393
5118
|
}
|
|
@@ -4465,56 +5190,64 @@ var ModuleRunner = class {
|
|
|
4465
5190
|
}
|
|
4466
5191
|
};
|
|
4467
5192
|
}
|
|
4468
|
-
async createUnit(
|
|
4469
|
-
|
|
4470
|
-
|
|
4471
|
-
|
|
4472
|
-
|
|
4473
|
-
|
|
4474
|
-
|
|
4475
|
-
|
|
4476
|
-
|
|
4477
|
-
\`\`\`
|
|
4478
|
-
${
|
|
4479
|
-
\`\`\`
|
|
4480
|
-
|
|
4481
|
-
|
|
4482
|
-
|
|
4483
|
-
${
|
|
4484
|
-
|
|
4485
|
-
|
|
4486
|
-
|
|
4487
|
-
|
|
4488
|
-
|
|
4489
|
-
|
|
4490
|
-
|
|
4491
|
-
|
|
4492
|
-
|
|
4493
|
-
|
|
4494
|
-
|
|
4495
|
-
|
|
4496
|
-
|
|
4497
|
-
|
|
4498
|
-
|
|
4499
|
-
|
|
4500
|
-
|
|
4501
|
-
|
|
4502
|
-
|
|
4503
|
-
|
|
4504
|
-
|
|
4505
|
-
|
|
4506
|
-
|
|
4507
|
-
|
|
4508
|
-
|
|
4509
|
-
|
|
4510
|
-
|
|
4511
|
-
|
|
4512
|
-
|
|
4513
|
-
|
|
4514
|
-
|
|
4515
|
-
}
|
|
4516
|
-
|
|
4517
|
-
|
|
5193
|
+
// async createUnit(sys: App | Lib, modelName: string) {
|
|
5194
|
+
// const modelFileData = getModelFileData(sys.cwdPath, modelName);
|
|
5195
|
+
// const { paths } = getRelatedCnsts(modelFileData.constantFilePath);
|
|
5196
|
+
// const names = { model: modelName, Model: capitalize(modelName), LightModel: `Light${capitalize(modelName)}` };
|
|
5197
|
+
// const prompt = `
|
|
5198
|
+
// 너는 React, Typescript, TailwindCSS를 기반으로 코딩하는 프론트엔드 개발자야.
|
|
5199
|
+
// ${names.Model}이라는 도메인에 대해서 ${names.LightModel} 스키마를 대상으로 react component를 디자인하려고 해. 아래는 현재 보일러플레이트 형태의 컴포넌트야.
|
|
5200
|
+
// \`\`\`
|
|
5201
|
+
// ${modelFileData.unitFileStr}
|
|
5202
|
+
// \`\`\`
|
|
5203
|
+
// ${names.LightModel}은 다음과 같이 ${names.Model} 스키마에서 일부 필드를 추출해서 lightweight fetch된 형태로 설계되어있어.
|
|
5204
|
+
// \`\`\`
|
|
5205
|
+
// ${modelFileData.constantFileStr}
|
|
5206
|
+
// \`\`\`
|
|
5207
|
+
// 아래는 현재 스키마와 연관된 스키마 파일들이야. 스키마 파일들의 코드들을 보고 서로 어떻게 연계 되어있는지 이해하도록 해.
|
|
5208
|
+
// ${
|
|
5209
|
+
// paths
|
|
5210
|
+
// ? new Array(paths.size).fill(0).map((_, index) => {
|
|
5211
|
+
// //순서대로 paths key 추출
|
|
5212
|
+
// const key = Array.from(paths.keys())[index];
|
|
5213
|
+
// const filePath = paths.get(key)?.filePath;
|
|
5214
|
+
// if (!filePath) throw new Error("filePath is undefined");
|
|
5215
|
+
// return `${key}\n\`\`\`${fs.readFileSync(filePath, "utf8")}\`\`\`\`\n\n`;
|
|
5216
|
+
// })
|
|
5217
|
+
// : ""
|
|
5218
|
+
// }
|
|
5219
|
+
// 추가로, 만약에 아이콘 사용이 필요하면 react-icons/bi 라이브러리에서 사용해줘.
|
|
5220
|
+
// 또, 색상을 사용하려고 하면 하드코딩된 색상(bg-red)이 아닌 테마 색상(bg-primary)을 사용해서 작성해줘.
|
|
5221
|
+
// 그리고 optional한 필드는 field && <div>... 가 아닌, field ? <div>... : null 형태로 작성해줘.
|
|
5222
|
+
// css라이브러리는 DaisyUI를 기반으로 작성해주는데, btn, input, badge와 같은 단순한 기본 css는 사용해도 괜찮아. 그런데 card, hero같이 복잡한 컴포넌트는 사용하면 안돼.
|
|
5223
|
+
// 조건부 className이 필요한 경우에는 clsx 라이브러리를 사용해서 작성해야해.
|
|
5224
|
+
// 모델에 대해서 object destructuring은 하지말고 ${modelName}.field 형태로 접근하게 코드를 작성해야해.
|
|
5225
|
+
// ${names.Model}.Unit.Card의 리액트 컴포넌트를 디자인해서 작성해줘.
|
|
5226
|
+
// `;
|
|
5227
|
+
// try {
|
|
5228
|
+
// fs.writeFileSync("./local/prompt.txt", prompt);
|
|
5229
|
+
// const { content } = await streamAi(prompt, (chunk) => {
|
|
5230
|
+
// process.stdout.write(chunk);
|
|
5231
|
+
// });
|
|
5232
|
+
// fs.writeFileSync("./local/result.txt", content);
|
|
5233
|
+
// } catch (error) {
|
|
5234
|
+
// // console.error("Application error:", error);
|
|
5235
|
+
// }
|
|
5236
|
+
// }
|
|
5237
|
+
// async createView(sys: App | Lib, modelName: string) {
|
|
5238
|
+
// const modelFileData = getModelFileData(sys.cwdPath, modelName);
|
|
5239
|
+
// // const modelFileData = getModelFileData(sys.cwdPath, modelName);
|
|
5240
|
+
// // const { paths } = getRelatedCnsts(modelFileData.constantFilePath);
|
|
5241
|
+
// // const names = { model: modelName, Model: capitalize(modelName), LightModel: `Light${capitalize(modelName)}` };
|
|
5242
|
+
// // const prompt = prompt.requestView({
|
|
5243
|
+
// // sysName: sys.name,
|
|
5244
|
+
// // modelName,
|
|
5245
|
+
// // modelDesc: modelFileData.modelDesc,
|
|
5246
|
+
// // modelSchemaDesign: modelFileData.modelSchemaDesign,
|
|
5247
|
+
// // boilerplate: modelFileData.viewFileStr,
|
|
5248
|
+
// // paths,
|
|
5249
|
+
// // });
|
|
5250
|
+
// }
|
|
4518
5251
|
};
|
|
4519
5252
|
|
|
4520
5253
|
// pkgs/@akanjs/cli/src/module/module.script.ts
|
|
@@ -4559,38 +5292,67 @@ var ModuleScript = class {
|
|
|
4559
5292
|
}
|
|
4560
5293
|
async createTest(workspace, name) {
|
|
4561
5294
|
}
|
|
4562
|
-
async createUnit(
|
|
4563
|
-
const
|
|
4564
|
-
await
|
|
5295
|
+
async createUnit(sys2) {
|
|
5296
|
+
const libs = await sys2.getModules();
|
|
5297
|
+
const unitExampleFiles = await sys2.getUnitsSourceCode();
|
|
5298
|
+
const lib = await (0, import_prompts8.select)({
|
|
5299
|
+
message: "Select the lib",
|
|
5300
|
+
choices: libs
|
|
5301
|
+
}).catch((e) => {
|
|
5302
|
+
Logger.error("canceled");
|
|
5303
|
+
return null;
|
|
5304
|
+
});
|
|
5305
|
+
if (!lib)
|
|
5306
|
+
return;
|
|
5307
|
+
const name = lib.split("/").pop();
|
|
5308
|
+
if (!name)
|
|
5309
|
+
return;
|
|
5310
|
+
const Name = capitalize(name);
|
|
5311
|
+
const relatedCnsts = getRelatedCnsts(`${sys2.cwdPath}/lib/${name}/${name}.constant.ts`);
|
|
5312
|
+
const constant = import_fs12.default.readFileSync(`${sys2.cwdPath}/lib/${name}/${name}.constant.ts`, "utf-8");
|
|
5313
|
+
const session = new AiSession();
|
|
5314
|
+
const promptRst = requestView({
|
|
5315
|
+
sysName: sys2.name,
|
|
5316
|
+
modelName: name,
|
|
5317
|
+
ModelName: Name,
|
|
5318
|
+
constant,
|
|
5319
|
+
properties: relatedCnsts.map((r) => ({ key: r.key, source: r.source })),
|
|
5320
|
+
exampleFiles: randomPicks(unitExampleFiles, Math.min(10, unitExampleFiles.length))
|
|
5321
|
+
});
|
|
5322
|
+
const content = await session.editTypescript(promptRst);
|
|
5323
|
+
import_fs12.default.writeFileSync(`${sys2.cwdPath}/prompt.txt`, promptRst);
|
|
5324
|
+
import_fs12.default.writeFileSync(`${sys2.cwdPath}/result.txt`, content);
|
|
4565
5325
|
}
|
|
4566
5326
|
async createView(sys2) {
|
|
4567
|
-
const
|
|
4568
|
-
const
|
|
4569
|
-
|
|
4570
|
-
|
|
4571
|
-
|
|
4572
|
-
|
|
4573
|
-
|
|
4574
|
-
|
|
4575
|
-
|
|
4576
|
-
|
|
4577
|
-
|
|
4578
|
-
|
|
4579
|
-
|
|
4580
|
-
|
|
4581
|
-
|
|
4582
|
-
|
|
4583
|
-
|
|
4584
|
-
|
|
4585
|
-
|
|
4586
|
-
|
|
4587
|
-
|
|
4588
|
-
|
|
4589
|
-
|
|
4590
|
-
|
|
4591
|
-
|
|
4592
|
-
|
|
4593
|
-
|
|
5327
|
+
const libs = await sys2.getModules();
|
|
5328
|
+
const lib = await (0, import_prompts8.select)({
|
|
5329
|
+
message: "Select the lib",
|
|
5330
|
+
choices: libs
|
|
5331
|
+
}).catch((e) => {
|
|
5332
|
+
Logger.error("canceled");
|
|
5333
|
+
return null;
|
|
5334
|
+
});
|
|
5335
|
+
if (!lib)
|
|
5336
|
+
return;
|
|
5337
|
+
const name = lib.split("/").pop();
|
|
5338
|
+
if (!name)
|
|
5339
|
+
return;
|
|
5340
|
+
const viewExampleFiles = (await sys2.getViewsSourceCode()).filter((f) => f.filepath.includes(`${name}.View.tsx`));
|
|
5341
|
+
const Name = capitalize(name);
|
|
5342
|
+
const relatedCnsts = getRelatedCnsts(`${sys2.cwdPath}/lib/${name}/${name}.constant.ts`);
|
|
5343
|
+
const constant = import_fs12.default.readFileSync(`${sys2.cwdPath}/lib/${name}/${name}.constant.ts`, "utf-8");
|
|
5344
|
+
const session = new AiSession();
|
|
5345
|
+
const promptRst = requestView({
|
|
5346
|
+
sysName: sys2.name,
|
|
5347
|
+
modelName: name,
|
|
5348
|
+
ModelName: Name,
|
|
5349
|
+
constant,
|
|
5350
|
+
properties: relatedCnsts.map((r) => ({ key: r.key, source: r.source })),
|
|
5351
|
+
exampleFiles: randomPicks(viewExampleFiles, Math.min(20, viewExampleFiles.length))
|
|
5352
|
+
});
|
|
5353
|
+
const content = await session.editTypescript(promptRst);
|
|
5354
|
+
import_fs12.default.writeFileSync(`${sys2.cwdPath}/prompt.txt`, promptRst);
|
|
5355
|
+
import_fs12.default.writeFileSync(`${sys2.cwdPath}/result.txt`, content);
|
|
4594
5356
|
}
|
|
4595
5357
|
};
|
|
4596
5358
|
|
|
@@ -4673,7 +5435,8 @@ var PackageCommand = class {
|
|
|
4673
5435
|
async createPackage(name, workspace) {
|
|
4674
5436
|
await this.packageScript.createPackage(workspace, name);
|
|
4675
5437
|
}
|
|
4676
|
-
async removePackage(
|
|
5438
|
+
async removePackage(pkg) {
|
|
5439
|
+
await this.packageScript.removePackage(pkg);
|
|
4677
5440
|
}
|
|
4678
5441
|
async scanPackage(pkg) {
|
|
4679
5442
|
await this.packageScript.scanPackage(pkg);
|
|
@@ -4693,8 +5456,7 @@ __decorateClass([
|
|
|
4693
5456
|
], PackageCommand.prototype, "createPackage", 1);
|
|
4694
5457
|
__decorateClass([
|
|
4695
5458
|
Target.Public(),
|
|
4696
|
-
__decorateParam(0,
|
|
4697
|
-
__decorateParam(1, Workspace())
|
|
5459
|
+
__decorateParam(0, Pkg())
|
|
4698
5460
|
], PackageCommand.prototype, "removePackage", 1);
|
|
4699
5461
|
__decorateClass([
|
|
4700
5462
|
Target.Public(),
|
|
@@ -4708,13 +5470,13 @@ PackageCommand = __decorateClass([
|
|
|
4708
5470
|
Commands()
|
|
4709
5471
|
], PackageCommand);
|
|
4710
5472
|
|
|
4711
|
-
// pkgs/@akanjs/cli/src/
|
|
5473
|
+
// pkgs/@akanjs/cli/src/page/page.runner.ts
|
|
4712
5474
|
var PageRunner = class {
|
|
4713
5475
|
async createPage(app, name) {
|
|
4714
5476
|
}
|
|
4715
5477
|
};
|
|
4716
5478
|
|
|
4717
|
-
// pkgs/@akanjs/cli/src/
|
|
5479
|
+
// pkgs/@akanjs/cli/src/page/page.script.ts
|
|
4718
5480
|
var PageScript = class {
|
|
4719
5481
|
#runner = new PageRunner();
|
|
4720
5482
|
async createPage(app, name) {
|
|
@@ -4722,7 +5484,7 @@ var PageScript = class {
|
|
|
4722
5484
|
}
|
|
4723
5485
|
};
|
|
4724
5486
|
|
|
4725
|
-
// pkgs/@akanjs/cli/src/
|
|
5487
|
+
// pkgs/@akanjs/cli/src/page/page.command.ts
|
|
4726
5488
|
var PageCommand = class {
|
|
4727
5489
|
pageScript = new PageScript();
|
|
4728
5490
|
async createPage(app, name) {
|
|
@@ -4839,7 +5601,7 @@ var WorkspaceScript = class {
|
|
|
4839
5601
|
};
|
|
4840
5602
|
workspace.writeFile("package.json", packageJson);
|
|
4841
5603
|
workspace.log("Installing dependencies...");
|
|
4842
|
-
await workspace.spawn("pnpm", ["
|
|
5604
|
+
await workspace.spawn("pnpm", ["install", "--reporter=silent"]);
|
|
4843
5605
|
workspace.log("Initializing git repository and commit...");
|
|
4844
5606
|
await workspace.commit("Initial commit", { init: true });
|
|
4845
5607
|
await this.libraryScript.installLibrary(workspace, "util");
|
|
@@ -4864,8 +5626,8 @@ var WorkspaceCommand = class {
|
|
|
4864
5626
|
};
|
|
4865
5627
|
__decorateClass([
|
|
4866
5628
|
Target.Public(),
|
|
4867
|
-
__decorateParam(0, Option("name", { desc: "name of
|
|
4868
|
-
__decorateParam(1, Option("app", { desc: "application
|
|
5629
|
+
__decorateParam(0, Option("name", { desc: "what is the name of your organization?" })),
|
|
5630
|
+
__decorateParam(1, Option("app", { desc: "describe your first application to create." })),
|
|
4869
5631
|
__decorateParam(2, Option("dir", { desc: "directory of workspace", default: process.env.USE_AKANJS_PKGS === "true" ? "local" : "." }))
|
|
4870
5632
|
], WorkspaceCommand.prototype, "createWorkspace", 1);
|
|
4871
5633
|
__decorateClass([
|
|
@@ -4887,7 +5649,6 @@ void runCommands(
|
|
|
4887
5649
|
PageCommand,
|
|
4888
5650
|
CloudCommand
|
|
4889
5651
|
);
|
|
4890
|
-
//!Field.Prop 거르기가 빡세네.
|
|
4891
5652
|
//! Temp
|
|
4892
5653
|
//! zip 명령어는 압축시 폴더 경로를 무시하는 게 안됨
|
|
4893
5654
|
//! 두 가지 방법이 있음
|
|
@@ -4896,3 +5657,4 @@ void runCommands(
|
|
|
4896
5657
|
//! execSync를 가져오기 싫으니 일단 2번 방법으로 해보자
|
|
4897
5658
|
//! add path in tsconfig.json
|
|
4898
5659
|
//! Temporary fix for barrel library
|
|
5660
|
+
//! 파일을 {name}.View.tsx에 저장.
|