logic-auto-cli 0.1.0
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/LICENSE +21 -0
- package/README.md +3 -0
- package/bin/logic.js +8 -0
- package/package.json +21 -0
- package/src/cli.js +121 -0
- package/src/commands/add.js +28 -0
- package/src/commands/bundle.js +12 -0
- package/src/commands/check.js +11 -0
- package/src/commands/create.js +16 -0
- package/src/commands/del.js +21 -0
- package/src/commands/find.js +29 -0
- package/src/commands/info.js +28 -0
- package/src/commands/login.js +11 -0
- package/src/commands/logout.js +15 -0
- package/src/commands/publish.js +14 -0
- package/src/commands/set.js +18 -0
- package/src/config.js +57 -0
- package/src/logger.js +11 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 logic
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
package/bin/logic.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "logic-auto-cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Logic module bundling CLI",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"logic": "./bin/logic.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"bin",
|
|
11
|
+
"src"
|
|
12
|
+
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"start": "node ./bin/logic.js",
|
|
15
|
+
"dev": "node ./bin/logic.js"
|
|
16
|
+
},
|
|
17
|
+
"dependencies": {},
|
|
18
|
+
"engines": {
|
|
19
|
+
"node": ">=18"
|
|
20
|
+
}
|
|
21
|
+
}
|
package/src/cli.js
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { logError } from './logger.js';
|
|
2
|
+
import { handleBundle } from './commands/bundle.js';
|
|
3
|
+
import { handleCreate } from './commands/create.js';
|
|
4
|
+
import { handleSet } from './commands/set.js';
|
|
5
|
+
import { handleFind } from './commands/find.js';
|
|
6
|
+
import { handleAdd } from './commands/add.js';
|
|
7
|
+
import { handleDel } from './commands/del.js';
|
|
8
|
+
import { handleInfo } from './commands/info.js';
|
|
9
|
+
import { handleCheck } from './commands/check.js';
|
|
10
|
+
import { handleLogin } from './commands/login.js';
|
|
11
|
+
import { handleLogout } from './commands/logout.js';
|
|
12
|
+
import { handlePublish } from './commands/publish.js';
|
|
13
|
+
|
|
14
|
+
export async function runCli(argv) {
|
|
15
|
+
const args = argv.slice(2); // ['bundle', '...', ...]
|
|
16
|
+
const [command, ...rest] = args;
|
|
17
|
+
|
|
18
|
+
if (!command) {
|
|
19
|
+
printHelp();
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
switch (command) {
|
|
25
|
+
case 'bundle':
|
|
26
|
+
// logic bundle '...'
|
|
27
|
+
await handleBundle(rest);
|
|
28
|
+
break;
|
|
29
|
+
|
|
30
|
+
case 'create':
|
|
31
|
+
// logic create db-module
|
|
32
|
+
await handleCreate(rest);
|
|
33
|
+
break;
|
|
34
|
+
|
|
35
|
+
case 'set':
|
|
36
|
+
// logic set --domain '...'
|
|
37
|
+
await handleSet(rest);
|
|
38
|
+
break;
|
|
39
|
+
|
|
40
|
+
case 'find':
|
|
41
|
+
// logic find [ui | db] --keyword 값
|
|
42
|
+
await handleFind(rest);
|
|
43
|
+
break;
|
|
44
|
+
|
|
45
|
+
case 'add':
|
|
46
|
+
// logic add 'git경로'
|
|
47
|
+
await handleAdd(rest);
|
|
48
|
+
break;
|
|
49
|
+
|
|
50
|
+
case 'del':
|
|
51
|
+
// logic del 'git경로'
|
|
52
|
+
await handleDel(rest);
|
|
53
|
+
break;
|
|
54
|
+
|
|
55
|
+
case 'info':
|
|
56
|
+
// logic info 'git경로'
|
|
57
|
+
await handleInfo(rest);
|
|
58
|
+
break;
|
|
59
|
+
|
|
60
|
+
case 'check':
|
|
61
|
+
// logic check
|
|
62
|
+
await handleCheck(rest);
|
|
63
|
+
break;
|
|
64
|
+
|
|
65
|
+
case 'login':
|
|
66
|
+
// logic login
|
|
67
|
+
await handleLogin(rest);
|
|
68
|
+
break;
|
|
69
|
+
|
|
70
|
+
case 'logout':
|
|
71
|
+
// logic logout
|
|
72
|
+
await handleLogout(rest);
|
|
73
|
+
break;
|
|
74
|
+
|
|
75
|
+
case 'publish':
|
|
76
|
+
// logic publish
|
|
77
|
+
await handlePublish(rest);
|
|
78
|
+
break;
|
|
79
|
+
|
|
80
|
+
case 'help':
|
|
81
|
+
case '-h':
|
|
82
|
+
case '--help':
|
|
83
|
+
printHelp();
|
|
84
|
+
break;
|
|
85
|
+
|
|
86
|
+
default:
|
|
87
|
+
logError(`[logic] Unknown command: ${command}`);
|
|
88
|
+
printHelp();
|
|
89
|
+
process.exitCode = 1;
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
} catch (err) {
|
|
93
|
+
logError(`[logic] Command failed: ${err?.message || err}`);
|
|
94
|
+
process.exitCode = 1;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function printHelp() {
|
|
99
|
+
console.log(`
|
|
100
|
+
Usage:
|
|
101
|
+
logic bundle <bundle-name>
|
|
102
|
+
logic create db-module
|
|
103
|
+
logic set --domain <domain>
|
|
104
|
+
logic find [ui | db] --keyword <value>
|
|
105
|
+
logic add <git-url>
|
|
106
|
+
logic del <git-url>
|
|
107
|
+
logic info <git-url>
|
|
108
|
+
logic check
|
|
109
|
+
logic login
|
|
110
|
+
logic logout
|
|
111
|
+
logic publish
|
|
112
|
+
|
|
113
|
+
Examples:
|
|
114
|
+
logic bundle "@logic-ui/store-admin-web"
|
|
115
|
+
logic create db-module
|
|
116
|
+
logic set --domain "store"
|
|
117
|
+
logic find db --keyword "cms"
|
|
118
|
+
logic add "https://github.com/white-lab/logic-db-store-core.git"
|
|
119
|
+
logic info "https://github.com/white-lab/logic-db-store-core.git"
|
|
120
|
+
`);
|
|
121
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { loadConfig, saveConfig } from '../config.js';
|
|
2
|
+
import { logInfo } from '../logger.js';
|
|
3
|
+
|
|
4
|
+
export async function handleAdd(args) {
|
|
5
|
+
const [gitUrl] = args;
|
|
6
|
+
|
|
7
|
+
if (!gitUrl) {
|
|
8
|
+
throw new Error('Usage: logic add <git-url>');
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const config = loadConfig();
|
|
12
|
+
const exists = config.modules.find((m) => m.git === gitUrl);
|
|
13
|
+
|
|
14
|
+
if (exists) {
|
|
15
|
+
logInfo(`[logic] Module already added: ${gitUrl}`);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// TODO: git url 분석해서 type, domain, namespace 등 메타 생성
|
|
20
|
+
config.modules.push({
|
|
21
|
+
git: gitUrl,
|
|
22
|
+
type: 'unknown',
|
|
23
|
+
meta: {}
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
saveConfig(config);
|
|
27
|
+
logInfo(`[logic] Module added: ${gitUrl}`);
|
|
28
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { logInfo } from '../logger.js';
|
|
2
|
+
|
|
3
|
+
export async function handleBundle(args) {
|
|
4
|
+
const [bundleName] = args;
|
|
5
|
+
|
|
6
|
+
if (!bundleName) {
|
|
7
|
+
throw new Error('Bundle name is required. e.g. logic bundle "@logic-ui/store-admin-web"');
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// TODO: bundle 정의 및 조립 처리
|
|
11
|
+
logInfo(`[logic] Bundle command called with: ${bundleName}`);
|
|
12
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { loadConfig } from '../config.js';
|
|
2
|
+
import { logInfo } from '../logger.js';
|
|
3
|
+
|
|
4
|
+
export async function handleCheck() {
|
|
5
|
+
const config = loadConfig();
|
|
6
|
+
|
|
7
|
+
// TODO: 실제로는 npm install 상태, 버전 충돌, domain/namespace 충돌 검사
|
|
8
|
+
logInfo('[logic] Checking current configuration...');
|
|
9
|
+
logInfo(`- domain: ${config.domain || '(not set)'}`);
|
|
10
|
+
logInfo(`- modules: ${config.modules.length}`);
|
|
11
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { logInfo } from '../logger.js';
|
|
2
|
+
|
|
3
|
+
export async function handleCreate(args) {
|
|
4
|
+
const [type] = args; // e.g. "db-module"
|
|
5
|
+
|
|
6
|
+
if (!type) {
|
|
7
|
+
throw new Error('Create type is required. e.g. logic create db-module');
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
if (type !== 'db-module') {
|
|
11
|
+
throw new Error(`Unsupported create type: ${type}`);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// TODO: db-module 스캐폴딩 로직
|
|
15
|
+
logInfo('[logic] Creating db-module scaffold...');
|
|
16
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { loadConfig, saveConfig } from '../config.js';
|
|
2
|
+
import { logInfo } from '../logger.js';
|
|
3
|
+
|
|
4
|
+
export async function handleDel(args) {
|
|
5
|
+
const [gitUrl] = args;
|
|
6
|
+
|
|
7
|
+
if (!gitUrl) {
|
|
8
|
+
throw new Error('Usage: logic del <git-url>');
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const config = loadConfig();
|
|
12
|
+
const before = config.modules.length;
|
|
13
|
+
config.modules = config.modules.filter((m) => m.git !== gitUrl);
|
|
14
|
+
saveConfig(config);
|
|
15
|
+
|
|
16
|
+
if (config.modules.length === before) {
|
|
17
|
+
logInfo(`[logic] Module not found: ${gitUrl}`);
|
|
18
|
+
} else {
|
|
19
|
+
logInfo(`[logic] Module deleted: ${gitUrl}`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { logInfo } from '../logger.js';
|
|
2
|
+
|
|
3
|
+
export async function handleFind(args) {
|
|
4
|
+
// logic find [ui | db] --keyword 값
|
|
5
|
+
const [kind, ...rest] = args; // kind: "ui" | "db"
|
|
6
|
+
if (!kind || (kind !== 'ui' && kind !== 'db')) {
|
|
7
|
+
throw new Error('Usage: logic find [ui | db] --keyword <value>');
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const keywordIndex = rest.indexOf('--keyword');
|
|
11
|
+
if (keywordIndex === -1 || !rest[keywordIndex + 1]) {
|
|
12
|
+
throw new Error('Usage: logic find [ui | db] --keyword <value>');
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const keyword = rest[keywordIndex + 1];
|
|
16
|
+
|
|
17
|
+
// TODO: 레지스트리/로컬 캐시 등에서 모듈 검색
|
|
18
|
+
logInfo(`[logic] Find ${kind} modules with keyword: ${keyword}`);
|
|
19
|
+
|
|
20
|
+
// 샘플 출력
|
|
21
|
+
logInfo(`
|
|
22
|
+
Found 1 ${kind} module(s) for keyword "${keyword}"
|
|
23
|
+
|
|
24
|
+
1) @logic-${kind}/sample-core@1.0.0
|
|
25
|
+
- domain: sample
|
|
26
|
+
- namespace: logic.admin
|
|
27
|
+
- stars: 10
|
|
28
|
+
`);
|
|
29
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { loadConfig } from '../config.js';
|
|
2
|
+
import { logInfo } from '../logger.js';
|
|
3
|
+
|
|
4
|
+
export async function handleInfo(args) {
|
|
5
|
+
const [gitUrl] = args;
|
|
6
|
+
|
|
7
|
+
if (!gitUrl) {
|
|
8
|
+
throw new Error('Usage: logic info <git-url>');
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const config = loadConfig();
|
|
12
|
+
const moduleInfo = config.modules.find((m) => m.git === gitUrl);
|
|
13
|
+
|
|
14
|
+
if (!moduleInfo) {
|
|
15
|
+
throw new Error(`Module not found in local config: ${gitUrl}`);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// TODO: 실제 npm/remote registry 에서 의존성 조회
|
|
19
|
+
logInfo(`[logic] Info for: ${gitUrl}`);
|
|
20
|
+
logInfo(JSON.stringify({
|
|
21
|
+
git: moduleInfo.git,
|
|
22
|
+
type: moduleInfo.type,
|
|
23
|
+
deps: {
|
|
24
|
+
db: [],
|
|
25
|
+
ui: []
|
|
26
|
+
}
|
|
27
|
+
}, null, 2));
|
|
28
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { loadConfig, saveConfig } from '../config.js';
|
|
2
|
+
import { logInfo } from '../logger.js';
|
|
3
|
+
|
|
4
|
+
export async function handleLogin() {
|
|
5
|
+
// TODO: 실제 구현에서는 OAuth / 토큰 발급 절차 필요
|
|
6
|
+
const config = loadConfig();
|
|
7
|
+
config.loggedInUser = 'demo-user';
|
|
8
|
+
saveConfig(config);
|
|
9
|
+
|
|
10
|
+
logInfo('[logic] Logged in as demo-user');
|
|
11
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { loadConfig, saveConfig } from '../config.js';
|
|
2
|
+
import { logInfo } from '../logger.js';
|
|
3
|
+
|
|
4
|
+
export async function handleLogout() {
|
|
5
|
+
const config = loadConfig();
|
|
6
|
+
if (!config.loggedInUser) {
|
|
7
|
+
logInfo('[logic] Not logged in.');
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
config.loggedInUser = null;
|
|
12
|
+
saveConfig(config);
|
|
13
|
+
|
|
14
|
+
logInfo('[logic] Logged out.');
|
|
15
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { loadConfig } from '../config.js';
|
|
2
|
+
import { logInfo } from '../logger.js';
|
|
3
|
+
|
|
4
|
+
export async function handlePublish() {
|
|
5
|
+
const config = loadConfig();
|
|
6
|
+
|
|
7
|
+
if (!config.loggedInUser) {
|
|
8
|
+
throw new Error('You must be logged in to publish. Run: logic login');
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// TODO: 실제 구현에서는 현재 디렉토리의 package.json / logic.json 읽어서
|
|
12
|
+
// 레지스트리에 등록 또는 업데이트
|
|
13
|
+
logInfo(`[logic] Publishing current module as ${config.loggedInUser} ...`);
|
|
14
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { loadConfig, saveConfig } from '../config.js';
|
|
2
|
+
import { logInfo } from '../logger.js';
|
|
3
|
+
|
|
4
|
+
export async function handleSet(args) {
|
|
5
|
+
// e.g. ["--domain", "store"]
|
|
6
|
+
const domainIndex = args.indexOf('--domain');
|
|
7
|
+
if (domainIndex === -1 || !args[domainIndex + 1]) {
|
|
8
|
+
throw new Error('Usage: logic set --domain <domain>');
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const domain = args[domainIndex + 1];
|
|
12
|
+
|
|
13
|
+
const config = loadConfig();
|
|
14
|
+
config.domain = domain;
|
|
15
|
+
saveConfig(config);
|
|
16
|
+
|
|
17
|
+
logInfo(`[logic] Domain set to: ${domain}`);
|
|
18
|
+
}
|
package/src/config.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import os from 'os';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
|
|
5
|
+
export function getConfigDir() {
|
|
6
|
+
const home = os.homedir();
|
|
7
|
+
const platform = process.platform; // 'darwin' | 'win32' | 'linux' ...
|
|
8
|
+
|
|
9
|
+
let baseDir;
|
|
10
|
+
|
|
11
|
+
if (platform === 'win32') {
|
|
12
|
+
// 예: C:\Users\user\AppData\Roaming\logic
|
|
13
|
+
const appData = process.env.APPDATA || path.join(home, 'AppData', 'Roaming');
|
|
14
|
+
baseDir = path.join(appData, 'logic');
|
|
15
|
+
} else {
|
|
16
|
+
// 예: ~/.logic
|
|
17
|
+
baseDir = path.join(home, '.logic');
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (!fs.existsSync(baseDir)) {
|
|
21
|
+
fs.mkdirSync(baseDir, { recursive: true });
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return baseDir;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function getConfigFilePath() {
|
|
28
|
+
const dir = getConfigDir();
|
|
29
|
+
return path.join(dir, 'config.json');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function loadConfig() {
|
|
33
|
+
const file = getConfigFilePath();
|
|
34
|
+
if (!fs.existsSync(file)) {
|
|
35
|
+
return {
|
|
36
|
+
domain: null,
|
|
37
|
+
loggedInUser: null,
|
|
38
|
+
modules: [] // { git: '...', type: 'db' | 'ui', meta: {} }
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
try {
|
|
42
|
+
const json = fs.readFileSync(file, 'utf-8');
|
|
43
|
+
return JSON.parse(json);
|
|
44
|
+
} catch (e) {
|
|
45
|
+
console.warn('[logic] Failed to load config. Reinitializing.');
|
|
46
|
+
return {
|
|
47
|
+
domain: null,
|
|
48
|
+
loggedInUser: null,
|
|
49
|
+
modules: []
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function saveConfig(config) {
|
|
55
|
+
const file = getConfigFilePath();
|
|
56
|
+
fs.writeFileSync(file, JSON.stringify(config, null, 2), 'utf-8');
|
|
57
|
+
}
|