@mdfriday/foundry 26.3.8 → 26.3.10
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/dist/cli.js +327 -119
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/internal/application/container.d.ts +9 -0
- package/dist/internal/application/index.d.ts +4 -0
- package/dist/internal/application/publish.d.ts +8 -9
- package/dist/internal/domain/identity/entity/user.d.ts +7 -1
- package/dist/internal/domain/identity/factory/user-factory.d.ts +6 -0
- package/dist/internal/domain/identity/index.d.ts +1 -0
- package/dist/internal/domain/identity/repository/index.d.ts +2 -0
- package/dist/internal/domain/identity/value-object/sync-config.d.ts +35 -0
- package/dist/internal/interfaces/cli/commands/publish.d.ts +1 -11
- package/dist/internal/interfaces/cli/container.d.ts +1 -7
- package/dist/internal/interfaces/cli/types.d.ts +0 -2
- package/dist/internal/interfaces/obsidian/auth.d.ts +5 -5
- package/dist/internal/interfaces/obsidian/container.d.ts +4 -4
- package/dist/internal/interfaces/obsidian/domain.d.ts +5 -5
- package/dist/internal/interfaces/obsidian/index.d.ts +4 -1
- package/dist/internal/interfaces/obsidian/license.d.ts +27 -7
- package/dist/internal/interfaces/obsidian/publish.d.ts +3 -2
- package/dist/internal/interfaces/obsidian/serve.d.ts +4 -4
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1970,6 +1970,126 @@ var init_license = __esm({
|
|
|
1970
1970
|
}
|
|
1971
1971
|
});
|
|
1972
1972
|
|
|
1973
|
+
// internal/domain/identity/value-object/sync-config.ts
|
|
1974
|
+
var SyncConfig;
|
|
1975
|
+
var init_sync_config = __esm({
|
|
1976
|
+
"internal/domain/identity/value-object/sync-config.ts"() {
|
|
1977
|
+
"use strict";
|
|
1978
|
+
SyncConfig = class _SyncConfig {
|
|
1979
|
+
dbEndpoint;
|
|
1980
|
+
dbName;
|
|
1981
|
+
email;
|
|
1982
|
+
dbPassword;
|
|
1983
|
+
userDir;
|
|
1984
|
+
constructor(data) {
|
|
1985
|
+
this.dbEndpoint = data.dbEndpoint;
|
|
1986
|
+
this.dbName = data.dbName;
|
|
1987
|
+
this.email = data.email;
|
|
1988
|
+
this.dbPassword = data.dbPassword;
|
|
1989
|
+
this.userDir = data.userDir;
|
|
1990
|
+
}
|
|
1991
|
+
// ============================================================================
|
|
1992
|
+
// Factory Methods
|
|
1993
|
+
// ============================================================================
|
|
1994
|
+
/**
|
|
1995
|
+
* 创建 SyncConfig 实例
|
|
1996
|
+
*/
|
|
1997
|
+
static create(data) {
|
|
1998
|
+
if (!data.dbEndpoint || !data.dbName || !data.email || !data.dbPassword) {
|
|
1999
|
+
throw new Error("Missing required sync configuration fields");
|
|
2000
|
+
}
|
|
2001
|
+
return new _SyncConfig(data);
|
|
2002
|
+
}
|
|
2003
|
+
/**
|
|
2004
|
+
* 从 JSON 数据创建 SyncConfig
|
|
2005
|
+
*/
|
|
2006
|
+
static fromJSON(data) {
|
|
2007
|
+
return _SyncConfig.create(data);
|
|
2008
|
+
}
|
|
2009
|
+
// ============================================================================
|
|
2010
|
+
// Getters
|
|
2011
|
+
// ============================================================================
|
|
2012
|
+
/**
|
|
2013
|
+
* 获取数据库端点 URL(包含数据库名)
|
|
2014
|
+
*/
|
|
2015
|
+
getDbEndpoint() {
|
|
2016
|
+
return this.dbEndpoint;
|
|
2017
|
+
}
|
|
2018
|
+
/**
|
|
2019
|
+
* 获取数据库名称
|
|
2020
|
+
*/
|
|
2021
|
+
getDbName() {
|
|
2022
|
+
return this.dbName;
|
|
2023
|
+
}
|
|
2024
|
+
/**
|
|
2025
|
+
* 获取用户邮箱
|
|
2026
|
+
*/
|
|
2027
|
+
getEmail() {
|
|
2028
|
+
return this.email;
|
|
2029
|
+
}
|
|
2030
|
+
/**
|
|
2031
|
+
* 获取数据库密码
|
|
2032
|
+
*/
|
|
2033
|
+
getDbPassword() {
|
|
2034
|
+
return this.dbPassword;
|
|
2035
|
+
}
|
|
2036
|
+
/**
|
|
2037
|
+
* 获取用户目录
|
|
2038
|
+
*/
|
|
2039
|
+
getUserDir() {
|
|
2040
|
+
return this.userDir;
|
|
2041
|
+
}
|
|
2042
|
+
/**
|
|
2043
|
+
* 获取 CouchDB URI(不包含数据库名)
|
|
2044
|
+
* 例如:https://couch.example.com/dbname -> https://couch.example.com
|
|
2045
|
+
*/
|
|
2046
|
+
getCouchDbUri() {
|
|
2047
|
+
return this.dbEndpoint.replace(`/${this.dbName}`, "");
|
|
2048
|
+
}
|
|
2049
|
+
// ============================================================================
|
|
2050
|
+
// Serialization
|
|
2051
|
+
// ============================================================================
|
|
2052
|
+
/**
|
|
2053
|
+
* 序列化为 JSON
|
|
2054
|
+
*/
|
|
2055
|
+
toJSON() {
|
|
2056
|
+
return {
|
|
2057
|
+
dbEndpoint: this.dbEndpoint,
|
|
2058
|
+
dbName: this.dbName,
|
|
2059
|
+
email: this.email,
|
|
2060
|
+
dbPassword: this.dbPassword,
|
|
2061
|
+
userDir: this.userDir
|
|
2062
|
+
};
|
|
2063
|
+
}
|
|
2064
|
+
/**
|
|
2065
|
+
* 转换为 Obsidian LiveSync 插件格式
|
|
2066
|
+
* 用于直接配置 Obsidian 的 LiveSync 插件
|
|
2067
|
+
*/
|
|
2068
|
+
toObsidianLiveSyncFormat() {
|
|
2069
|
+
return {
|
|
2070
|
+
couchDB_URI: this.getCouchDbUri(),
|
|
2071
|
+
couchDB_DBNAME: this.dbName,
|
|
2072
|
+
couchDB_USER: this.email,
|
|
2073
|
+
couchDB_PASSWORD: this.dbPassword,
|
|
2074
|
+
encrypt: true,
|
|
2075
|
+
syncOnStart: true,
|
|
2076
|
+
syncOnSave: true,
|
|
2077
|
+
liveSync: true
|
|
2078
|
+
};
|
|
2079
|
+
}
|
|
2080
|
+
// ============================================================================
|
|
2081
|
+
// Comparison
|
|
2082
|
+
// ============================================================================
|
|
2083
|
+
/**
|
|
2084
|
+
* 比较两个 SyncConfig 是否相同
|
|
2085
|
+
*/
|
|
2086
|
+
equals(other) {
|
|
2087
|
+
return this.dbEndpoint === other.dbEndpoint && this.dbName === other.dbName && this.email === other.email;
|
|
2088
|
+
}
|
|
2089
|
+
};
|
|
2090
|
+
}
|
|
2091
|
+
});
|
|
2092
|
+
|
|
1973
2093
|
// internal/domain/identity/value-object/device.ts
|
|
1974
2094
|
var Device;
|
|
1975
2095
|
var init_device = __esm({
|
|
@@ -2184,14 +2304,16 @@ var init_user = __esm({
|
|
|
2184
2304
|
token;
|
|
2185
2305
|
serverConfig;
|
|
2186
2306
|
license;
|
|
2307
|
+
syncConfig;
|
|
2187
2308
|
/**
|
|
2188
2309
|
* 构造函数(私有,通过 Factory 创建)
|
|
2189
2310
|
*/
|
|
2190
|
-
constructor(email, token, serverConfig, license = null) {
|
|
2311
|
+
constructor(email, token, serverConfig, license = null, syncConfig = null) {
|
|
2191
2312
|
this.email = email;
|
|
2192
2313
|
this.token = token;
|
|
2193
2314
|
this.serverConfig = serverConfig;
|
|
2194
2315
|
this.license = license;
|
|
2316
|
+
this.syncConfig = syncConfig;
|
|
2195
2317
|
}
|
|
2196
2318
|
// ============================================================================
|
|
2197
2319
|
// Getters
|
|
@@ -2220,6 +2342,12 @@ var init_user = __esm({
|
|
|
2220
2342
|
getLicense() {
|
|
2221
2343
|
return this.license;
|
|
2222
2344
|
}
|
|
2345
|
+
/**
|
|
2346
|
+
* 获取同步配置
|
|
2347
|
+
*/
|
|
2348
|
+
getSyncConfig() {
|
|
2349
|
+
return this.syncConfig;
|
|
2350
|
+
}
|
|
2223
2351
|
// ============================================================================
|
|
2224
2352
|
// Business Logic
|
|
2225
2353
|
// ============================================================================
|
|
@@ -2253,6 +2381,18 @@ var init_user = __esm({
|
|
|
2253
2381
|
clearLicense() {
|
|
2254
2382
|
this.license = null;
|
|
2255
2383
|
}
|
|
2384
|
+
/**
|
|
2385
|
+
* 设置同步配置
|
|
2386
|
+
*/
|
|
2387
|
+
setSyncConfig(syncConfig) {
|
|
2388
|
+
this.syncConfig = syncConfig;
|
|
2389
|
+
}
|
|
2390
|
+
/**
|
|
2391
|
+
* 清除同步配置
|
|
2392
|
+
*/
|
|
2393
|
+
clearSyncConfig() {
|
|
2394
|
+
this.syncConfig = null;
|
|
2395
|
+
}
|
|
2256
2396
|
/**
|
|
2257
2397
|
* 检查是否已认证
|
|
2258
2398
|
*/
|
|
@@ -2318,7 +2458,8 @@ var init_user = __esm({
|
|
|
2318
2458
|
email: this.email.toJSON(),
|
|
2319
2459
|
token: this.token?.toJSON() || null,
|
|
2320
2460
|
serverConfig: this.serverConfig.toJSON(),
|
|
2321
|
-
license: this.license?.toJSON() || null
|
|
2461
|
+
license: this.license?.toJSON() || null,
|
|
2462
|
+
syncConfig: this.syncConfig?.toJSON() || null
|
|
2322
2463
|
};
|
|
2323
2464
|
}
|
|
2324
2465
|
};
|
|
@@ -2335,6 +2476,7 @@ var init_user_factory = __esm({
|
|
|
2335
2476
|
init_token();
|
|
2336
2477
|
init_server_config();
|
|
2337
2478
|
init_license();
|
|
2479
|
+
init_sync_config();
|
|
2338
2480
|
init_device();
|
|
2339
2481
|
init_log();
|
|
2340
2482
|
log4 = getDomainLogger("user-factory", { component: "domain" });
|
|
@@ -2372,10 +2514,15 @@ var init_user_factory = __esm({
|
|
|
2372
2514
|
if (userData.license) {
|
|
2373
2515
|
user.setLicense(userData.license);
|
|
2374
2516
|
}
|
|
2517
|
+
if (userData.syncConfig) {
|
|
2518
|
+
const syncConfig = SyncConfig.fromJSON(userData.syncConfig);
|
|
2519
|
+
user.setSyncConfig(syncConfig);
|
|
2520
|
+
}
|
|
2375
2521
|
log4.debug("User loaded from storage", {
|
|
2376
2522
|
email: email.getValue(),
|
|
2377
2523
|
hasToken: !!userData.token,
|
|
2378
|
-
hasLicense: !!userData.license
|
|
2524
|
+
hasLicense: !!userData.license,
|
|
2525
|
+
hasSyncConfig: !!userData.syncConfig
|
|
2379
2526
|
});
|
|
2380
2527
|
return user;
|
|
2381
2528
|
} catch (error) {
|
|
@@ -2384,24 +2531,27 @@ var init_user_factory = __esm({
|
|
|
2384
2531
|
}
|
|
2385
2532
|
}
|
|
2386
2533
|
/**
|
|
2387
|
-
* 保存用户到存储(合并保存 token, license, server config)
|
|
2534
|
+
* 保存用户到存储(合并保存 token, license, server config, sync config)
|
|
2388
2535
|
*/
|
|
2389
2536
|
async save(user) {
|
|
2390
2537
|
try {
|
|
2391
2538
|
const token = user.getToken();
|
|
2392
2539
|
const license = user.getLicense();
|
|
2540
|
+
const syncConfig = user.getSyncConfig();
|
|
2393
2541
|
const serverConfig = user.getServerConfig();
|
|
2394
2542
|
const email = user.getEmail().getValue();
|
|
2395
2543
|
await this.storageProvider.saveUserData({
|
|
2396
2544
|
token,
|
|
2397
2545
|
license,
|
|
2546
|
+
syncConfig,
|
|
2398
2547
|
serverConfig,
|
|
2399
2548
|
email
|
|
2400
2549
|
});
|
|
2401
2550
|
log4.debug("User saved to storage", {
|
|
2402
2551
|
email,
|
|
2403
2552
|
hasToken: !!token,
|
|
2404
|
-
hasLicense: !!license
|
|
2553
|
+
hasLicense: !!license,
|
|
2554
|
+
hasSyncConfig: !!syncConfig
|
|
2405
2555
|
});
|
|
2406
2556
|
} catch (error) {
|
|
2407
2557
|
log4.error("Failed to save user to storage", error);
|
|
@@ -2665,10 +2815,27 @@ var init_user_factory = __esm({
|
|
|
2665
2815
|
Date.now()
|
|
2666
2816
|
);
|
|
2667
2817
|
user.setLicense(license);
|
|
2818
|
+
if (data.sync && data.features.sync_enabled) {
|
|
2819
|
+
const syncConfig = SyncConfig.create({
|
|
2820
|
+
dbEndpoint: data.sync.db_endpoint,
|
|
2821
|
+
dbName: data.sync.db_name,
|
|
2822
|
+
email: data.sync.email,
|
|
2823
|
+
dbPassword: data.sync.db_password,
|
|
2824
|
+
userDir: data.user.user_dir
|
|
2825
|
+
});
|
|
2826
|
+
user.setSyncConfig(syncConfig);
|
|
2827
|
+
log4.info("Sync configuration saved", {
|
|
2828
|
+
dbName: syncConfig.getDbName(),
|
|
2829
|
+
email: syncConfig.getEmail(),
|
|
2830
|
+
userDir: syncConfig.getUserDir()
|
|
2831
|
+
});
|
|
2832
|
+
}
|
|
2668
2833
|
await this.save(user);
|
|
2669
2834
|
log4.info("License activated successfully", {
|
|
2670
2835
|
plan: license.getPlan(),
|
|
2671
|
-
expires: license.getFormattedExpiresAt()
|
|
2836
|
+
expires: license.getFormattedExpiresAt(),
|
|
2837
|
+
syncEnabled: data.features.sync_enabled,
|
|
2838
|
+
hasSyncConfig: user.getSyncConfig() !== null
|
|
2672
2839
|
});
|
|
2673
2840
|
return user;
|
|
2674
2841
|
} catch (error) {
|
|
@@ -3113,6 +3280,7 @@ __export(identity_exports, {
|
|
|
3113
3280
|
Email: () => Email,
|
|
3114
3281
|
License: () => License,
|
|
3115
3282
|
ServerConfig: () => ServerConfig,
|
|
3283
|
+
SyncConfig: () => SyncConfig,
|
|
3116
3284
|
Token: () => Token,
|
|
3117
3285
|
User: () => User,
|
|
3118
3286
|
UserFactory: () => UserFactory
|
|
@@ -3124,6 +3292,7 @@ var init_identity = __esm({
|
|
|
3124
3292
|
init_token();
|
|
3125
3293
|
init_server_config();
|
|
3126
3294
|
init_license();
|
|
3295
|
+
init_sync_config();
|
|
3127
3296
|
init_device();
|
|
3128
3297
|
init_user();
|
|
3129
3298
|
init_user_factory();
|
|
@@ -9173,20 +9342,15 @@ var init_publish2 = __esm({
|
|
|
9173
9342
|
}
|
|
9174
9343
|
/**
|
|
9175
9344
|
* Publish project to specified platform
|
|
9345
|
+
*
|
|
9346
|
+
* @param project - 项目实例
|
|
9347
|
+
* @param config - 已合并的发布配置(由调用方准备)
|
|
9348
|
+
* @param options - 发布选项
|
|
9349
|
+
* @param onProgress - 进度回调
|
|
9176
9350
|
*/
|
|
9177
|
-
async publish(project,
|
|
9178
|
-
log17.info(`Publishing project: ${project.getName()} to ${
|
|
9351
|
+
async publish(project, config, options, onProgress) {
|
|
9352
|
+
log17.info(`Publishing project: ${project.getName()} to ${config.type}`);
|
|
9179
9353
|
try {
|
|
9180
|
-
const workspace = await this.workspaceService.loadWorkspace();
|
|
9181
|
-
const globalConfig = await workspace.getAllConfig();
|
|
9182
|
-
const publishConfig = WorkspacePublishConfig.fromGlobalConfig(globalConfig);
|
|
9183
|
-
let config;
|
|
9184
|
-
if (options?.config) {
|
|
9185
|
-
const mergedConfig = publishConfig.merge(options.config, method);
|
|
9186
|
-
config = await this.getMethodConfig(mergedConfig, method);
|
|
9187
|
-
} else {
|
|
9188
|
-
config = await this.getMethodConfig(publishConfig, method);
|
|
9189
|
-
}
|
|
9190
9354
|
const publicDir = await project.getPublishDir();
|
|
9191
9355
|
const publisher = this.publisherFactory.create(
|
|
9192
9356
|
project.getId(),
|
|
@@ -9205,27 +9369,59 @@ var init_publish2 = __esm({
|
|
|
9205
9369
|
const result = await publisher.publish(publicDir, publishOptions);
|
|
9206
9370
|
return result;
|
|
9207
9371
|
} catch (error) {
|
|
9208
|
-
log17.error(`Publish failed: ${
|
|
9372
|
+
log17.error(`Publish failed: ${config.type}`, error);
|
|
9209
9373
|
throw error;
|
|
9210
9374
|
}
|
|
9211
9375
|
}
|
|
9212
9376
|
/**
|
|
9213
9377
|
* Test connection
|
|
9378
|
+
*
|
|
9379
|
+
* @param project - 项目实例
|
|
9380
|
+
* @param config - 已合并的发布配置(由调用方准备)
|
|
9214
9381
|
*/
|
|
9215
|
-
async testConnection(project,
|
|
9216
|
-
|
|
9382
|
+
async testConnection(project, config) {
|
|
9383
|
+
log17.info(`Testing ${config.type} connection for project: ${project.getName()}`);
|
|
9384
|
+
try {
|
|
9385
|
+
const publisher = this.publisherFactory.create(
|
|
9386
|
+
project.getId(),
|
|
9387
|
+
project.getPath(),
|
|
9388
|
+
config
|
|
9389
|
+
);
|
|
9390
|
+
if (publisher.testConnection) {
|
|
9391
|
+
return await publisher.testConnection();
|
|
9392
|
+
}
|
|
9393
|
+
return { success: true };
|
|
9394
|
+
} catch (error) {
|
|
9395
|
+
log17.error(`Test connection failed: ${config.type}`, error);
|
|
9396
|
+
return {
|
|
9397
|
+
success: false,
|
|
9398
|
+
error: error.message
|
|
9399
|
+
};
|
|
9400
|
+
}
|
|
9401
|
+
}
|
|
9402
|
+
/**
|
|
9403
|
+
* 准备最终的发布配置
|
|
9404
|
+
*
|
|
9405
|
+
* 配置查找优先级(两级):
|
|
9406
|
+
* 1. 项目配置 (project.config.publish)
|
|
9407
|
+
* 2. 全局配置 (workspace global config)
|
|
9408
|
+
*
|
|
9409
|
+
* @param workspace - Workspace 实例
|
|
9410
|
+
* @param project - Project 实例
|
|
9411
|
+
* @param method - 发布方法
|
|
9412
|
+
* @returns 最终的发布配置
|
|
9413
|
+
*/
|
|
9414
|
+
async prepareFinalConfig(workspace, project, method) {
|
|
9217
9415
|
const globalConfig = await workspace.getAllConfig();
|
|
9218
|
-
|
|
9219
|
-
|
|
9220
|
-
const
|
|
9221
|
-
|
|
9222
|
-
|
|
9223
|
-
|
|
9224
|
-
|
|
9225
|
-
if (publisher.testConnection) {
|
|
9226
|
-
return await publisher.testConnection();
|
|
9416
|
+
let publishConfig = WorkspacePublishConfig.fromGlobalConfig(globalConfig);
|
|
9417
|
+
await project.loadConfig();
|
|
9418
|
+
const projectConfig = project.getConfig();
|
|
9419
|
+
if (projectConfig?.publish) {
|
|
9420
|
+
log17.debug("Merging project publish config");
|
|
9421
|
+
const projectPublishData = projectConfig.publish;
|
|
9422
|
+
publishConfig = publishConfig.merge(projectPublishData, method);
|
|
9227
9423
|
}
|
|
9228
|
-
return
|
|
9424
|
+
return this.getMethodConfig(publishConfig, method, workspace);
|
|
9229
9425
|
}
|
|
9230
9426
|
// ============================================================================
|
|
9231
9427
|
// Private Methods
|
|
@@ -9233,7 +9429,7 @@ var init_publish2 = __esm({
|
|
|
9233
9429
|
/**
|
|
9234
9430
|
* Get method-specific config from WorkspacePublishConfig
|
|
9235
9431
|
*/
|
|
9236
|
-
async getMethodConfig(publishConfig, method) {
|
|
9432
|
+
async getMethodConfig(publishConfig, method, workspace) {
|
|
9237
9433
|
switch (method) {
|
|
9238
9434
|
case "ftp":
|
|
9239
9435
|
const ftpConfig = publishConfig.getFTPConfig();
|
|
@@ -9267,15 +9463,14 @@ var init_publish2 = __esm({
|
|
|
9267
9463
|
const licenseKey = mdConfig.licenseKey || "";
|
|
9268
9464
|
if (!licenseKey) {
|
|
9269
9465
|
throw new Error(
|
|
9270
|
-
"\u274C MDFriday license key is required for publishing.\n\nDifferent licenses deploy to different servers.\nYou must explicitly configure
|
|
9466
|
+
"\u274C MDFriday license key is required for publishing.\n\nDifferent licenses deploy to different servers.\nYou must explicitly configure a license key:\n\nConfigure license globally (recommended):\n mdf config:set publish.mdfriday.licenseKey MDF-XXXX-XXXX-XXXX --global\n\nOr configure for project only:\n mdf config:set publish.mdfriday.licenseKey MDF-XXXX-XXXX-XXXX\n\n\u{1F4A1} Note: License login (mdf license:login) only gets TOKEN.\n Publishing requires explicitly setting a license key."
|
|
9271
9467
|
);
|
|
9272
9468
|
}
|
|
9273
|
-
const workspace = await this.workspaceService.loadWorkspace();
|
|
9274
9469
|
const { createIdentityService: createIdentityService2 } = await Promise.resolve().then(() => (init_container(), container_exports));
|
|
9275
9470
|
let accessToken = null;
|
|
9276
9471
|
let apiUrl = "https://app.mdfriday.com";
|
|
9277
9472
|
try {
|
|
9278
|
-
const identityService = await createIdentityService2();
|
|
9473
|
+
const identityService = await createIdentityService2(workspace.getInfo().path);
|
|
9279
9474
|
await identityService.initialize();
|
|
9280
9475
|
accessToken = identityService.getToken();
|
|
9281
9476
|
const serverConfig = identityService.getServerConfig();
|
|
@@ -9288,33 +9483,30 @@ var init_publish2 = __esm({
|
|
|
9288
9483
|
}
|
|
9289
9484
|
if (!accessToken) {
|
|
9290
9485
|
throw new Error(
|
|
9291
|
-
"\u274C
|
|
9486
|
+
"\u274C Not authenticated.\n\nPlease login first:\n mdf auth:login\n\nOr use license login:\n mdf license:login --key YOUR-LICENSE-KEY"
|
|
9292
9487
|
);
|
|
9293
9488
|
}
|
|
9294
9489
|
return {
|
|
9295
9490
|
type: "mdfriday",
|
|
9296
|
-
deploymentType: mdConfig.type || "share",
|
|
9297
|
-
// Already merged with CLI override
|
|
9298
9491
|
licenseKey,
|
|
9299
|
-
// Required, from merged config
|
|
9300
|
-
enabled: mdConfig.enabled,
|
|
9301
9492
|
accessToken,
|
|
9302
|
-
|
|
9303
|
-
|
|
9304
|
-
|
|
9493
|
+
apiUrl,
|
|
9494
|
+
deploymentType: mdConfig.type || "share",
|
|
9495
|
+
enabled: true
|
|
9305
9496
|
};
|
|
9306
9497
|
default:
|
|
9307
|
-
throw new Error(`
|
|
9498
|
+
throw new Error(`Unsupported publish method: ${method}`);
|
|
9308
9499
|
}
|
|
9309
9500
|
}
|
|
9310
9501
|
};
|
|
9311
9502
|
}
|
|
9312
9503
|
});
|
|
9313
9504
|
|
|
9314
|
-
// internal/
|
|
9505
|
+
// internal/application/container.ts
|
|
9315
9506
|
var container_exports = {};
|
|
9316
9507
|
__export(container_exports, {
|
|
9317
9508
|
createIdentityService: () => createIdentityService,
|
|
9509
|
+
createIdentityServiceForObsidian: () => createIdentityServiceForObsidian,
|
|
9318
9510
|
createPublishAppService: () => createPublishAppService,
|
|
9319
9511
|
createWorkspaceAppService: () => createWorkspaceAppService,
|
|
9320
9512
|
createWorkspaceFactory: () => createWorkspaceFactory
|
|
@@ -9334,19 +9526,30 @@ function createWorkspaceAppService() {
|
|
|
9334
9526
|
workspaceFactory
|
|
9335
9527
|
});
|
|
9336
9528
|
}
|
|
9337
|
-
async function createIdentityService(
|
|
9529
|
+
async function createIdentityService(workspacePath) {
|
|
9338
9530
|
const httpClient = new NodeHttpClient();
|
|
9339
9531
|
const workspaceAppService = createWorkspaceAppService();
|
|
9340
|
-
const workspace = await workspaceAppService.loadWorkspace(
|
|
9532
|
+
const workspace = await workspaceAppService.loadWorkspace(workspacePath);
|
|
9341
9533
|
const storageProvider = workspaceAppService.createIdentityStorage(workspace);
|
|
9342
9534
|
const userFactory = new UserFactory({
|
|
9343
9535
|
httpClient,
|
|
9344
9536
|
storageProvider
|
|
9345
9537
|
});
|
|
9346
|
-
|
|
9538
|
+
return new IdentityAppService({
|
|
9539
|
+
userFactory
|
|
9540
|
+
});
|
|
9541
|
+
}
|
|
9542
|
+
async function createIdentityServiceForObsidian(workspacePath, httpClient) {
|
|
9543
|
+
const workspaceAppService = createWorkspaceAppService();
|
|
9544
|
+
const workspace = await workspaceAppService.loadWorkspace(workspacePath);
|
|
9545
|
+
const storageProvider = workspaceAppService.createIdentityStorage(workspace);
|
|
9546
|
+
const userFactory = new UserFactory({
|
|
9547
|
+
httpClient,
|
|
9548
|
+
storageProvider
|
|
9549
|
+
});
|
|
9550
|
+
return new IdentityAppService({
|
|
9347
9551
|
userFactory
|
|
9348
9552
|
});
|
|
9349
|
-
return identityAppService;
|
|
9350
9553
|
}
|
|
9351
9554
|
function createPublishAppService() {
|
|
9352
9555
|
const { PublishAppService: PublishAppService2 } = (init_publish2(), __toCommonJS(publish_exports2));
|
|
@@ -9362,7 +9565,7 @@ function createPublishAppService() {
|
|
|
9362
9565
|
);
|
|
9363
9566
|
}
|
|
9364
9567
|
var init_container = __esm({
|
|
9365
|
-
"internal/
|
|
9568
|
+
"internal/application/container.ts"() {
|
|
9366
9569
|
"use strict";
|
|
9367
9570
|
init_workspace2();
|
|
9368
9571
|
init_workspace3();
|
|
@@ -9372,6 +9575,22 @@ var init_container = __esm({
|
|
|
9372
9575
|
}
|
|
9373
9576
|
});
|
|
9374
9577
|
|
|
9578
|
+
// internal/interfaces/cli/container.ts
|
|
9579
|
+
var container_exports2 = {};
|
|
9580
|
+
__export(container_exports2, {
|
|
9581
|
+
createIdentityService: () => createIdentityService,
|
|
9582
|
+
createIdentityServiceForObsidian: () => createIdentityServiceForObsidian,
|
|
9583
|
+
createPublishAppService: () => createPublishAppService,
|
|
9584
|
+
createWorkspaceAppService: () => createWorkspaceAppService,
|
|
9585
|
+
createWorkspaceFactory: () => createWorkspaceFactory
|
|
9586
|
+
});
|
|
9587
|
+
var init_container2 = __esm({
|
|
9588
|
+
"internal/interfaces/cli/container.ts"() {
|
|
9589
|
+
"use strict";
|
|
9590
|
+
init_container();
|
|
9591
|
+
}
|
|
9592
|
+
});
|
|
9593
|
+
|
|
9375
9594
|
// internal/domain/config/type.ts
|
|
9376
9595
|
var ConfigError, ErrConfigNotFound, ErrInvalidConfig, ErrWorkspaceNotFound, ErrConfigFileNotFound, ErrInvalidConfigFormat;
|
|
9377
9596
|
var init_type4 = __esm({
|
|
@@ -50558,7 +50777,7 @@ __export(cli_exports, {
|
|
|
50558
50777
|
module.exports = __toCommonJS(cli_exports);
|
|
50559
50778
|
|
|
50560
50779
|
// internal/interfaces/cli/router.ts
|
|
50561
|
-
|
|
50780
|
+
init_container2();
|
|
50562
50781
|
|
|
50563
50782
|
// internal/interfaces/cli/commands/workspace.ts
|
|
50564
50783
|
init_log();
|
|
@@ -52870,17 +53089,7 @@ var ServeCommand = class {
|
|
|
52870
53089
|
},
|
|
52871
53090
|
onSuccess: async () => {
|
|
52872
53091
|
if (options.publish && this.publishAppService) {
|
|
52873
|
-
|
|
52874
|
-
if (options.type)
|
|
52875
|
-
publishOptions.type = options.type;
|
|
52876
|
-
if (options.licenseKey)
|
|
52877
|
-
publishOptions.licenseKey = options.licenseKey;
|
|
52878
|
-
await this.autoPublish(
|
|
52879
|
-
project,
|
|
52880
|
-
options.publish,
|
|
52881
|
-
options.publishDelay,
|
|
52882
|
-
publishOptions
|
|
52883
|
-
);
|
|
53092
|
+
await this.autoPublish(workspace, project, options.publish, options.publishDelay);
|
|
52884
53093
|
}
|
|
52885
53094
|
}
|
|
52886
53095
|
};
|
|
@@ -52980,7 +53189,7 @@ Press Ctrl+C to stop`,
|
|
|
52980
53189
|
/**
|
|
52981
53190
|
* 自动发布(带防抖)
|
|
52982
53191
|
*/
|
|
52983
|
-
async autoPublish(project, method, delayMs
|
|
53192
|
+
async autoPublish(workspace, project, method, delayMs) {
|
|
52984
53193
|
if (this.publishTimer) {
|
|
52985
53194
|
clearTimeout(this.publishTimer);
|
|
52986
53195
|
}
|
|
@@ -52995,17 +53204,11 @@ Press Ctrl+C to stop`,
|
|
|
52995
53204
|
clearOnComplete: true
|
|
52996
53205
|
});
|
|
52997
53206
|
const startTime = Date.now();
|
|
52998
|
-
const
|
|
52999
|
-
if (options && (options.type || options.licenseKey)) {
|
|
53000
|
-
publishOptions.config = {
|
|
53001
|
-
type: options.type,
|
|
53002
|
-
licenseKey: options.licenseKey
|
|
53003
|
-
};
|
|
53004
|
-
}
|
|
53207
|
+
const config = await this.publishAppService.prepareFinalConfig(workspace, project, method);
|
|
53005
53208
|
const result = await this.publishAppService.publish(
|
|
53006
53209
|
project,
|
|
53007
|
-
|
|
53008
|
-
|
|
53210
|
+
config,
|
|
53211
|
+
{ incremental: true },
|
|
53009
53212
|
(progress) => {
|
|
53010
53213
|
progressBar.update(progress.percentage, progress.message);
|
|
53011
53214
|
}
|
|
@@ -53186,7 +53389,7 @@ var SnapshotDeleteCommand = class {
|
|
|
53186
53389
|
};
|
|
53187
53390
|
|
|
53188
53391
|
// internal/interfaces/cli/commands/auth.ts
|
|
53189
|
-
|
|
53392
|
+
init_container2();
|
|
53190
53393
|
init_log();
|
|
53191
53394
|
var log90 = getDomainLogger("auth-command", { component: "cli" });
|
|
53192
53395
|
async function getIdentityService() {
|
|
@@ -54335,18 +54538,22 @@ var PublishCommand = class {
|
|
|
54335
54538
|
description = "Publish project to hosting platform";
|
|
54336
54539
|
async execute(args, options) {
|
|
54337
54540
|
try {
|
|
54338
|
-
const
|
|
54541
|
+
const subcommand = args[0];
|
|
54542
|
+
if (subcommand === "test") {
|
|
54543
|
+
return await this.executeTest(args.slice(1), options);
|
|
54544
|
+
}
|
|
54545
|
+
const method = subcommand;
|
|
54339
54546
|
if (!method || !["ftp", "netlify", "mdfriday"].includes(method)) {
|
|
54340
54547
|
return {
|
|
54341
54548
|
success: false,
|
|
54342
|
-
message: "Please specify publish method: ftp, netlify, or mdfriday\n\nUsage:\n mdf publish ftp [options]\n mdf publish netlify [options]\n mdf publish mdfriday [options]\n\nOptions:\n --project <name> Project to publish\n --force Force full publish (ignore incremental)\n --verbose Show detailed progress\n\
|
|
54549
|
+
message: "Please specify publish method: ftp, netlify, or mdfriday\n\nUsage:\n mdf publish ftp [options]\n mdf publish netlify [options]\n mdf publish mdfriday [options]\n mdf publish test <method>\n\nOptions:\n --project <name> Project to publish\n --force Force full publish (ignore incremental)\n --verbose Show detailed progress\n\nConfiguration:\n All publish settings are configured via config command:\n mdf config:set publish.<method>.<key> <value> --global\n mdf config:set publish.<method>.<key> <value> (project-level)\n\nExamples:\n mdf publish ftp\n mdf publish ftp --project my-blog --force\n mdf publish test ftp"
|
|
54343
54550
|
};
|
|
54344
54551
|
}
|
|
54345
54552
|
const { workspace, project } = await this.workspaceAppService.loadWorkspaceAndProject(
|
|
54346
54553
|
options.project
|
|
54347
54554
|
);
|
|
54348
54555
|
log92.info(`Publishing project: ${project.getName()} to ${method}`);
|
|
54349
|
-
const
|
|
54556
|
+
const config = await this.publishService.prepareFinalConfig(workspace, project, method);
|
|
54350
54557
|
const progressBar = new ProgressBar({
|
|
54351
54558
|
width: 30,
|
|
54352
54559
|
showPercentage: true,
|
|
@@ -54354,17 +54561,10 @@ var PublishCommand = class {
|
|
|
54354
54561
|
clearOnComplete: true
|
|
54355
54562
|
});
|
|
54356
54563
|
const startTime = Date.now();
|
|
54357
|
-
const appPublishOptions = {};
|
|
54358
|
-
if (options.force) {
|
|
54359
|
-
appPublishOptions.force = true;
|
|
54360
|
-
}
|
|
54361
|
-
if (configOverride) {
|
|
54362
|
-
appPublishOptions.config = configOverride;
|
|
54363
|
-
}
|
|
54364
54564
|
const result = await this.publishService.publish(
|
|
54365
54565
|
project,
|
|
54366
|
-
|
|
54367
|
-
|
|
54566
|
+
config,
|
|
54567
|
+
options.force ? { force: true } : {},
|
|
54368
54568
|
(progress) => {
|
|
54369
54569
|
if (options.verbose) {
|
|
54370
54570
|
console.log(
|
|
@@ -54424,40 +54624,48 @@ var PublishCommand = class {
|
|
|
54424
54624
|
}
|
|
54425
54625
|
}
|
|
54426
54626
|
/**
|
|
54427
|
-
*
|
|
54627
|
+
* Execute test connection command
|
|
54428
54628
|
*/
|
|
54429
|
-
|
|
54430
|
-
|
|
54431
|
-
|
|
54432
|
-
|
|
54433
|
-
|
|
54434
|
-
|
|
54435
|
-
|
|
54436
|
-
|
|
54437
|
-
|
|
54438
|
-
|
|
54439
|
-
|
|
54440
|
-
|
|
54441
|
-
|
|
54442
|
-
|
|
54443
|
-
|
|
54444
|
-
|
|
54445
|
-
|
|
54446
|
-
|
|
54447
|
-
|
|
54448
|
-
|
|
54449
|
-
|
|
54450
|
-
|
|
54451
|
-
|
|
54452
|
-
|
|
54453
|
-
|
|
54454
|
-
|
|
54455
|
-
|
|
54456
|
-
|
|
54457
|
-
|
|
54458
|
-
|
|
54629
|
+
async executeTest(args, options) {
|
|
54630
|
+
try {
|
|
54631
|
+
const method = args[0];
|
|
54632
|
+
if (!method || !["ftp", "netlify", "mdfriday"].includes(method)) {
|
|
54633
|
+
return {
|
|
54634
|
+
success: false,
|
|
54635
|
+
message: "Please specify publish method to test: ftp, netlify, or mdfriday\n\nUsage:\n mdf publish test ftp\n mdf publish test netlify\n mdf publish test mdfriday\n\nOptions:\n --project <name> Project to test (optional)\n\nConfiguration:\n All publish settings are configured via config command:\n mdf config:set publish.<method>.<key> <value> --global\n mdf config:set publish.<method>.<key> <value> (project-level)\n\nExamples:\n mdf publish test ftp\n mdf publish test netlify"
|
|
54636
|
+
};
|
|
54637
|
+
}
|
|
54638
|
+
const { workspace, project } = await this.workspaceAppService.loadWorkspaceAndProject(
|
|
54639
|
+
options.project
|
|
54640
|
+
);
|
|
54641
|
+
log92.info(`Testing ${method} connection for project: ${project.getName()}`);
|
|
54642
|
+
const config = await this.publishService.prepareFinalConfig(workspace, project, method);
|
|
54643
|
+
console.log(`
|
|
54644
|
+
Testing ${method.toUpperCase()} connection...`);
|
|
54645
|
+
console.log("Configuration priority: Project config > Global config\n");
|
|
54646
|
+
const result = await this.publishService.testConnection(project, config);
|
|
54647
|
+
if (result.success) {
|
|
54648
|
+
return {
|
|
54649
|
+
success: true,
|
|
54650
|
+
message: `
|
|
54651
|
+
\u2713 ${method.toUpperCase()} connection test passed!`
|
|
54652
|
+
};
|
|
54653
|
+
} else {
|
|
54654
|
+
return {
|
|
54655
|
+
success: false,
|
|
54656
|
+
message: `
|
|
54657
|
+
\u2717 ${method.toUpperCase()} connection test failed: ${result.error}`,
|
|
54658
|
+
error: new Error(result.error)
|
|
54659
|
+
};
|
|
54660
|
+
}
|
|
54661
|
+
} catch (error) {
|
|
54662
|
+
log92.error("Test connection command failed", error);
|
|
54663
|
+
return {
|
|
54664
|
+
success: false,
|
|
54665
|
+
message: `Test connection failed: ${error.message}`,
|
|
54666
|
+
error
|
|
54667
|
+
};
|
|
54459
54668
|
}
|
|
54460
|
-
return void 0;
|
|
54461
54669
|
}
|
|
54462
54670
|
};
|
|
54463
54671
|
|
|
@@ -54480,7 +54688,7 @@ var CommandRegistry = class {
|
|
|
54480
54688
|
this.register(new ProjectShowCommand(workspaceAppService));
|
|
54481
54689
|
this.register(new ProjectDeleteCommand(workspaceAppService));
|
|
54482
54690
|
this.register(new BuildCommand(workspaceAppService));
|
|
54483
|
-
const { createPublishAppService: createPublishAppService2 } = (
|
|
54691
|
+
const { createPublishAppService: createPublishAppService2 } = (init_container2(), __toCommonJS(container_exports2));
|
|
54484
54692
|
const publishAppService = createPublishAppService2();
|
|
54485
54693
|
this.register(new PublishCommand(publishAppService, workspaceAppService));
|
|
54486
54694
|
this.register(new ServeCommand(workspaceAppService, publishAppService));
|
|
@@ -54832,7 +55040,7 @@ For more information, visit: https://help.mdfriday.com
|
|
|
54832
55040
|
* Show version
|
|
54833
55041
|
*/
|
|
54834
55042
|
showVersion() {
|
|
54835
|
-
const version = "26.3.
|
|
55043
|
+
const version = "26.3.10";
|
|
54836
55044
|
return {
|
|
54837
55045
|
success: true,
|
|
54838
55046
|
message: `MDFriday CLI v${version}`
|