@crmforall/connect 0.1.6 → 0.1.8

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.
@@ -49,18 +49,26 @@ async function collectDbSettings(json) {
49
49
  if (json || !(0, prompts_1.isInteractive)()) {
50
50
  return (0, contracts_1.jsonError)("init", contracts_1.ERROR_CODE.AUTH_FAILED, "비대화형 실행에서는 CRMFORALL_DB_URL(+CRMFORALL_DB_PASSWORD) 환경변수가 필요합니다. 비밀번호를 명령 인자로 넘기지 마세요.");
51
51
  }
52
- console.log("\nDB 접속 정보를 입력하세요. (읽기 전용 계정 + crmforall 스키마 CREATE 권한 권장)");
53
- console.log("비밀번호는 화면에 표시되지 않고, 명령 인자·로그에 남지 않습니다.\n");
54
- const host = await (0, prompts_1.prompt)("호스트 (예: db.internal.shop.com / localhost)");
52
+ (0, prompts_1.section)("DB 접속 정보 입력");
53
+ console.log("읽기 전용 계정 + crmforall 스키마 CREATE 권한 권장. 비밀번호는 표시되지 않고 인자·로그에 남지 않아요.\n");
54
+ const host = await (0, prompts_1.prompt)("호스트 (예: petco.xxxx.ap-northeast-2.rds.amazonaws.com / localhost)");
55
55
  const port = Number(await (0, prompts_1.prompt)("포트", "5432"));
56
56
  const database = await (0, prompts_1.prompt)("데이터베이스 이름 (예: shop)");
57
57
  const user = await (0, prompts_1.prompt)("사용자 (예: cfa_reader)");
58
58
  const password = await (0, prompts_1.promptHidden)("비밀번호 (입력 비표시)");
59
- const ssl = (await (0, prompts_1.prompt)("SSL 사용? (y/N)", "N")).toLowerCase() === "y";
59
+ const ssl = (await (0, prompts_1.select)("SSL(보안 연결) 사용?", [
60
+ { label: "아니오 (로컬·사내망 기본)", value: "n" },
61
+ { label: "예", value: "y", hint: "AWS RDS 등 원격 DB 권장" },
62
+ ], 0)) === "y";
60
63
  return { sourceType: "postgresql", host, port, database, user, password, ssl };
61
64
  }
62
65
  async function runInit(opts) {
63
66
  const existing = (0, connector_1.loadConfig)();
67
+ if ((0, prompts_1.isInteractive)() && !opts.json) {
68
+ console.log("\n크렘포올 커넥터 설치 마법사");
69
+ console.log("DB를 읽기 전용으로 연결하고, 발송 대상 계산은 이 서버 안에서 수행합니다.");
70
+ console.log("진행 중 안내를 따라 입력하면 돼요. (Ctrl+C로 언제든 취소)\n");
71
+ }
64
72
  // --- 1. 자격증명 확보: 토큰 교환 또는 기존 설정 재사용 ---
65
73
  let identity;
66
74
  if (opts.token) {
@@ -109,6 +117,18 @@ async function runInit(opts) {
109
117
  db: dbSettings,
110
118
  mapping: existing?.mapping ?? null,
111
119
  });
120
+ // 확인 요약 (비밀번호 제외) — 대화형에서만
121
+ if ((0, prompts_1.isInteractive)() && !opts.json) {
122
+ (0, prompts_1.section)("입력 정보 확인 (비밀번호 제외)");
123
+ console.log(` 호스트 : ${config.db.host}:${config.db.port}`);
124
+ console.log(` DB : ${config.db.database} 계정: ${config.db.user} SSL: ${config.db.ssl ? "예" : "아니오"}`);
125
+ console.log(` 플랫폼 : ${config.platformUrl}`);
126
+ console.log(` 스키마 : ${config.crmSchema} (이 DB에 새로 생성될 전용 공간)`);
127
+ const go = await (0, prompts_1.confirm)("\n이대로 연결할까요?", true);
128
+ if (!go) {
129
+ return (0, contracts_1.jsonError)("init", contracts_1.ERROR_CODE.AUTH_FAILED, "취소했습니다. connect init을 다시 실행해 주세요.");
130
+ }
131
+ }
112
132
  // --- 3~4. Readiness Gate + CRM 스키마 생성 (설치 단계 DDL) ---
113
133
  const adapter = new db_1.PostgresAdapter({
114
134
  host: config.db.host,
package/dist/index.js CHANGED
@@ -10,7 +10,7 @@ const program = new commander_1.Command();
10
10
  program
11
11
  .name("connect")
12
12
  .description("crmforall 커넥터 설치/진단 CLI. AI 도구(Claude Code 등)로 운전하려면 패키지의 AGENTS.md를 참조하세요.")
13
- .version("0.1.6");
13
+ .version("0.1.8");
14
14
  function emit(result, asJson) {
15
15
  if (asJson) {
16
16
  console.log(JSON.stringify(result, null, 2));
package/dist/prompts.js CHANGED
@@ -1,6 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.isInteractive = isInteractive;
4
+ exports.section = section;
5
+ exports.select = select;
6
+ exports.confirm = confirm;
4
7
  exports.prompt = prompt;
5
8
  exports.promptHidden = promptHidden;
6
9
  const promises_1 = require("node:readline/promises");
@@ -13,6 +16,29 @@ const promises_1 = require("node:readline/promises");
13
16
  function isInteractive() {
14
17
  return Boolean(process.stdin.isTTY && process.stdout.isTTY);
15
18
  }
19
+ /** 굵은 글씨 섹션 머리말 (마법사 단계 구분) */
20
+ function section(title) {
21
+ console.log(`\n${title}`);
22
+ }
23
+ /** 번호 선택 메뉴 — 정해진 보기 중 하나를 고른다 (의존성 없이 readline 기반) */
24
+ async function select(question, choices, defaultIndex = 0) {
25
+ console.log(question);
26
+ choices.forEach((c, i) => {
27
+ const mark = i === defaultIndex ? "›" : " ";
28
+ console.log(` ${mark} ${i + 1}) ${c.label}${c.hint ? ` — ${c.hint}` : ""}`);
29
+ });
30
+ const raw = await prompt("번호 선택", String(defaultIndex + 1));
31
+ const n = Number(raw);
32
+ const idx = Number.isInteger(n) && n >= 1 && n <= choices.length ? n - 1 : defaultIndex;
33
+ return choices[idx].value;
34
+ }
35
+ /** 예/아니오 확인 */
36
+ async function confirm(question, defaultYes = true) {
37
+ const a = (await prompt(`${question} (${defaultYes ? "Y/n" : "y/N"})`)).toLowerCase();
38
+ if (!a)
39
+ return defaultYes;
40
+ return a === "y" || a === "yes";
41
+ }
16
42
  async function prompt(question, defaultValue) {
17
43
  const rl = (0, promises_1.createInterface)({ input: process.stdin, output: process.stdout });
18
44
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crmforall/connect",
3
- "version": "0.1.6",
3
+ "version": "0.1.8",
4
4
  "description": "crmforall 커넥터 설치/진단 CLI — npx @crmforall/connect init --token=...",
5
5
  "main": "./dist/index.js",
6
6
  "bin": {
@@ -10,14 +10,9 @@
10
10
  "files": [
11
11
  "dist"
12
12
  ],
13
- "scripts": {
14
- "build": "tsc && chmod +x dist/index.js",
15
- "prepack": "chmod +x dist/index.js",
16
- "typecheck": "tsc --noEmit"
17
- },
18
13
  "dependencies": {
19
- "@crmforall/connector": "workspace:*",
20
- "commander": "^13.0.0"
14
+ "commander": "^13.0.0",
15
+ "@crmforall/connector": "0.1.8"
21
16
  },
22
17
  "devDependencies": {
23
18
  "@types/node": "^22.0.0",
@@ -33,5 +28,9 @@
33
28
  },
34
29
  "engines": {
35
30
  "node": ">=22"
31
+ },
32
+ "scripts": {
33
+ "build": "tsc && chmod +x dist/index.js",
34
+ "typecheck": "tsc --noEmit"
36
35
  }
37
- }
36
+ }