@share-crm/sharecrm-cli 1.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/README.md +293 -0
- package/dist/cli/parser.js +79 -0
- package/dist/cli/root.js +63 -0
- package/dist/cli/router.js +32 -0
- package/dist/commands/auth/login.js +34 -0
- package/dist/commands/auth/logout.js +12 -0
- package/dist/commands/auth/status.js +41 -0
- package/dist/commands/auth/token.js +70 -0
- package/dist/commands/config/init.js +28 -0
- package/dist/commands/help/help.js +174 -0
- package/dist/commands/remote/execute.js +131 -0
- package/dist/core/auth/authTypes.js +2 -0
- package/dist/core/auth/deviceFlow.js +77 -0
- package/dist/core/auth/tokenManager.js +45 -0
- package/dist/core/cache/cacheTypes.js +2 -0
- package/dist/core/cache/commandCache.js +24 -0
- package/dist/core/config/authBaseUrl.js +11 -0
- package/dist/core/config/envPersistence.js +59 -0
- package/dist/core/config/interactive.js +60 -0
- package/dist/core/config/locale.js +9 -0
- package/dist/core/debug/debugOutput.js +18 -0
- package/dist/core/debug/runtimeDebug.js +19 -0
- package/dist/core/http/apiClient.js +320 -0
- package/dist/core/http/requestTypes.js +2 -0
- package/dist/core/output/errors.js +44 -0
- package/dist/core/output/stderr.js +6 -0
- package/dist/core/output/stdout.js +6 -0
- package/dist/core/state/authSessionStore.js +129 -0
- package/dist/core/state/authSessionTypes.js +2 -0
- package/dist/core/state/configStore.js +65 -0
- package/dist/core/state/fileLock.js +66 -0
- package/dist/core/state/legacySessionMigration.js +109 -0
- package/dist/core/state/paths.js +40 -0
- package/dist/core/state/secretStore/commonFileCrypto.js +61 -0
- package/dist/core/state/secretStore/index.js +28 -0
- package/dist/core/state/secretStore/secretStore.darwin.js +139 -0
- package/dist/core/state/secretStore/secretStore.linux.js +90 -0
- package/dist/core/state/secretStore/secretStore.unsupported.js +17 -0
- package/dist/core/state/secretStore/secretStore.win32.js +162 -0
- package/dist/core/state/secretStore/types.js +2 -0
- package/dist/core/state/sessionMetaStore.js +24 -0
- package/dist/core/state/sessionStore.js +23 -0
- package/dist/index.js +49 -0
- package/dist/shared/constants.js +13 -0
- package/dist/shared/env.js +69 -0
- package/dist/shared/generatedConfig.js +9 -0
- package/dist/shared/utils.js +14 -0
- package/dist/types/command.js +2 -0
- package/package.json +40 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SessionStore = void 0;
|
|
4
|
+
const errors_1 = require("../output/errors");
|
|
5
|
+
const authSessionStore_1 = require("./authSessionStore");
|
|
6
|
+
class SessionStore {
|
|
7
|
+
authStore = new authSessionStore_1.AuthSessionStore();
|
|
8
|
+
async load() {
|
|
9
|
+
try {
|
|
10
|
+
return await this.authStore.load();
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
throw new errors_1.CliError('Failed to read session file.', 1);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
async save(session) {
|
|
17
|
+
await this.authStore.save(session);
|
|
18
|
+
}
|
|
19
|
+
async clear() {
|
|
20
|
+
await this.authStore.clear();
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
exports.SessionStore = SessionStore;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.formatDebugException = formatDebugException;
|
|
5
|
+
const root_1 = require("./cli/root");
|
|
6
|
+
const errors_1 = require("./core/output/errors");
|
|
7
|
+
const stderr_1 = require("./core/output/stderr");
|
|
8
|
+
const runtimeDebug_1 = require("./core/debug/runtimeDebug");
|
|
9
|
+
const debugOutput_1 = require("./core/debug/debugOutput");
|
|
10
|
+
function formatDebugException(error) {
|
|
11
|
+
if (error instanceof errors_1.CliError) {
|
|
12
|
+
return {
|
|
13
|
+
name: error.name,
|
|
14
|
+
message: error.message,
|
|
15
|
+
stack: error.stack,
|
|
16
|
+
errorCode: 'errorCode' in error && typeof error.errorCode === 'number' ? error.errorCode : undefined,
|
|
17
|
+
exitCode: error.exitCode,
|
|
18
|
+
details: error.details,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
if (error instanceof Error) {
|
|
22
|
+
return {
|
|
23
|
+
name: error.name,
|
|
24
|
+
message: error.message,
|
|
25
|
+
stack: error.stack,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
name: 'UnknownError',
|
|
30
|
+
message: typeof error === 'string' ? error : 'Unknown CLI error',
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
async function main() {
|
|
34
|
+
const program = (0, root_1.createRootCommand)();
|
|
35
|
+
await program.parseAsync(process.argv);
|
|
36
|
+
}
|
|
37
|
+
main().catch((error) => {
|
|
38
|
+
if ((0, runtimeDebug_1.isDebugEnabled)()) {
|
|
39
|
+
(0, debugOutput_1.writeDebugException)(formatDebugException(error));
|
|
40
|
+
}
|
|
41
|
+
if (error instanceof errors_1.CliError) {
|
|
42
|
+
(0, stderr_1.writeStderr)(error.message);
|
|
43
|
+
process.exitCode = error.exitCode;
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const message = error instanceof Error ? error.message : 'Unknown CLI error';
|
|
47
|
+
(0, stderr_1.writeStderr)(message);
|
|
48
|
+
process.exitCode = 1;
|
|
49
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_COMMAND_CACHE_TTL_SECONDS = exports.DEFAULT_DEVICE_CLIENT_ID = exports.CLI_VERSION = exports.CLI_NAME = void 0;
|
|
4
|
+
exports.getDefaultDeviceClientId = getDefaultDeviceClientId;
|
|
5
|
+
const generatedConfig_1 = require("./generatedConfig");
|
|
6
|
+
const packageJson = require('../../package.json');
|
|
7
|
+
exports.CLI_NAME = 'sharecrm';
|
|
8
|
+
exports.CLI_VERSION = packageJson.version;
|
|
9
|
+
function getDefaultDeviceClientId() {
|
|
10
|
+
return process.env.FS_CLI_DEFAULT_CLIENT_ID || generatedConfig_1.GENERATED_RUNTIME_CONFIG.defaultClientId;
|
|
11
|
+
}
|
|
12
|
+
exports.DEFAULT_DEVICE_CLIENT_ID = getDefaultDeviceClientId();
|
|
13
|
+
exports.DEFAULT_COMMAND_CACHE_TTL_SECONDS = 3600;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.resolveEnvironment = resolveEnvironment;
|
|
7
|
+
const node_os_1 = __importDefault(require("node:os"));
|
|
8
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
9
|
+
const generatedConfig_1 = require("./generatedConfig");
|
|
10
|
+
const configStore_1 = require("../core/state/configStore");
|
|
11
|
+
const locale_1 = require("../core/config/locale");
|
|
12
|
+
function enforceHttps(url, label) {
|
|
13
|
+
if (!url)
|
|
14
|
+
return undefined;
|
|
15
|
+
if (!url.startsWith('https://')) {
|
|
16
|
+
throw new Error(`${label} 必须使用 HTTPS 协议,当前值:${url}`);
|
|
17
|
+
}
|
|
18
|
+
return url;
|
|
19
|
+
}
|
|
20
|
+
function resolveUnixHomeDir() {
|
|
21
|
+
const homeDir = node_os_1.default.homedir() || process.env.HOME?.trim();
|
|
22
|
+
if (homeDir) {
|
|
23
|
+
return homeDir;
|
|
24
|
+
}
|
|
25
|
+
throw new Error('HOME 环境变量未设置,无法确定配置目录位置。');
|
|
26
|
+
}
|
|
27
|
+
function resolveWindowsHomeDir() {
|
|
28
|
+
const homeDir = node_os_1.default.homedir();
|
|
29
|
+
if (homeDir) {
|
|
30
|
+
return homeDir;
|
|
31
|
+
}
|
|
32
|
+
const userProfile = process.env.USERPROFILE?.trim();
|
|
33
|
+
if (userProfile) {
|
|
34
|
+
return userProfile;
|
|
35
|
+
}
|
|
36
|
+
const homeDrive = process.env.HOMEDRIVE?.trim();
|
|
37
|
+
const homePath = process.env.HOMEPATH?.trim();
|
|
38
|
+
if (homeDrive && homePath) {
|
|
39
|
+
return node_path_1.default.join(homeDrive, homePath);
|
|
40
|
+
}
|
|
41
|
+
throw new Error('USERPROFILE/HOMEDRIVE/HOMEPATH 环境变量未设置,无法确定配置目录位置。');
|
|
42
|
+
}
|
|
43
|
+
function resolveHomeDir(platform = process.platform) {
|
|
44
|
+
switch (platform) {
|
|
45
|
+
case 'win32':
|
|
46
|
+
return resolveWindowsHomeDir();
|
|
47
|
+
case 'darwin':
|
|
48
|
+
case 'linux':
|
|
49
|
+
default:
|
|
50
|
+
return resolveUnixHomeDir();
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
async function resolveEnvironment(platform = process.platform) {
|
|
54
|
+
const homeDir = resolveHomeDir(platform);
|
|
55
|
+
const configDir = process.env.FS_CLI_CONFIG_DIR ?? node_path_1.default.join(homeDir, '.sharecrm-cli');
|
|
56
|
+
const config = await new configStore_1.ConfigStore().load();
|
|
57
|
+
const authBaseUrl = enforceHttps(process.env.FS_CLI_AUTH_BASE_URL?.trim()
|
|
58
|
+
?? config?.authBaseUrl
|
|
59
|
+
?? generatedConfig_1.GENERATED_RUNTIME_CONFIG.authBaseUrl, 'FS_CLI_AUTH_BASE_URL');
|
|
60
|
+
const apiBaseUrl = enforceHttps(process.env.FS_CLI_API_BASE_URL?.trim() ?? generatedConfig_1.GENERATED_RUNTIME_CONFIG.apiBaseUrl, 'FS_CLI_API_BASE_URL');
|
|
61
|
+
const locale = (0, locale_1.isCliLocale)(config?.locale ?? '') ? config.locale : locale_1.DEFAULT_LOCALE;
|
|
62
|
+
return {
|
|
63
|
+
homeDir,
|
|
64
|
+
configDir,
|
|
65
|
+
authBaseUrl,
|
|
66
|
+
apiBaseUrl,
|
|
67
|
+
locale,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GENERATED_RUNTIME_CONFIG = void 0;
|
|
4
|
+
exports.GENERATED_RUNTIME_CONFIG = {
|
|
5
|
+
envName: 'production',
|
|
6
|
+
authBaseUrl: 'https://open.fxiaoke.com/',
|
|
7
|
+
apiBaseUrl: 'https://open.fxiaoke.com/cli/',
|
|
8
|
+
defaultClientId: 'afe5bdb8c735e5bd00674c4262b21580',
|
|
9
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.joinCommandSegments = joinCommandSegments;
|
|
4
|
+
exports.isHelpFlag = isHelpFlag;
|
|
5
|
+
exports.toIsoTimestamp = toIsoTimestamp;
|
|
6
|
+
function joinCommandSegments(segments) {
|
|
7
|
+
return segments.map((segment) => segment.trim()).filter(Boolean).join(' ');
|
|
8
|
+
}
|
|
9
|
+
function isHelpFlag(token) {
|
|
10
|
+
return token === '--help' || token === '-h';
|
|
11
|
+
}
|
|
12
|
+
function toIsoTimestamp(date = new Date()) {
|
|
13
|
+
return date.toISOString();
|
|
14
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@share-crm/sharecrm-cli",
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "ShareCRM CLI client skeleton",
|
|
5
|
+
"type": "commonjs",
|
|
6
|
+
"engines": {
|
|
7
|
+
"node": ">=18.17"
|
|
8
|
+
},
|
|
9
|
+
"bin": {
|
|
10
|
+
"sharecrm": "dist/index.js"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"bin",
|
|
14
|
+
"dist"
|
|
15
|
+
],
|
|
16
|
+
"scripts": {
|
|
17
|
+
"build": "node scripts/build.js production && tsc -p tsconfig.json",
|
|
18
|
+
"build:dev": "node scripts/build.js development && tsc -p tsconfig.json",
|
|
19
|
+
"build:debug": "node scripts/build.js development && tsx src/index.ts",
|
|
20
|
+
"build:prod": "node scripts/build.js production && tsc -p tsconfig.json",
|
|
21
|
+
"build:test": "node scripts/build.js test && tsc -p tsconfig.json",
|
|
22
|
+
"lint": "eslint . --ext .ts",
|
|
23
|
+
"pretest": "npm run build",
|
|
24
|
+
"test": "vitest run",
|
|
25
|
+
"typecheck": "tsc --noEmit"
|
|
26
|
+
},
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"commander": "^12.1.0"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@types/node": "^24.6.0",
|
|
32
|
+
"@typescript-eslint/eslint-plugin": "^8.35.1",
|
|
33
|
+
"@typescript-eslint/parser": "^8.35.1",
|
|
34
|
+
"eslint": "^9.26.0",
|
|
35
|
+
"prettier": "^3.6.2",
|
|
36
|
+
"tsx": "^4.20.6",
|
|
37
|
+
"typescript": "^5.9.3",
|
|
38
|
+
"vitest": "^3.2.4"
|
|
39
|
+
}
|
|
40
|
+
}
|