2026-07-23 20:36:13 +08:00
/*
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
if you want to view the source, please visit the github repository of this plugin
*/
var __defProp = Object . defineProperty ;
var __getOwnPropDesc = Object . getOwnPropertyDescriptor ;
var __getOwnPropNames = Object . getOwnPropertyNames ;
var __hasOwnProp = Object . prototype . hasOwnProperty ;
var __export = ( target , all ) => {
for ( var name in all )
__defProp ( target , name , { get : all [ name ], enumerable : true });
};
var __copyProps = ( to , from , except , desc ) => {
if ( from && typeof from === "object" || typeof from === "function" ) {
for ( let key of __getOwnPropNames ( from ))
if ( ! __hasOwnProp . call ( to , key ) && key !== except )
__defProp ( to , key , { get : () => from [ key ], enumerable : ! ( desc = __getOwnPropDesc ( from , key )) || desc . enumerable });
}
return to ;
};
var __toCommonJS = ( mod ) => __copyProps ( __defProp ({}, "__esModule" , { value : true }), mod );
// src/main.ts
var main_exports = {};
__export ( main_exports , {
default : () => YuquePublishPlugin
});
module . exports = __toCommonJS ( main_exports );
var import_obsidian4 = require ( "obsidian" );
// src/settings.ts
var DEFAULT_SETTINGS = {
groups : []
};
// src/settings-tab.ts
var import_obsidian3 = require ( "obsidian" );
// src/yuque-validator.ts
var import_obsidian = require ( "obsidian" );
var import_obsidian2 = require ( "obsidian" );
var YuqueValidator = class {
static async validate ( config ) {
const urlRegex = /^https:\/\/([^\/]+)\.yuque\.com\/([^\/]+)(\/)?$/ ;
const match = config . urlPrefix . match ( urlRegex );
if ( ! match ) {
throw new Error ( "URL format is incorrect. It should be like https://spaceName.yuque.com/groupName/" );
}
const [, spaceName , groupName ] = match ;
const baseUrl = `https:// ${ spaceName } .yuque.com` ;
const apiUrl = ` ${ baseUrl } /api/v2/user` ;
try {
const response = await ( 0 , import_obsidian2 . requestUrl )({
url : apiUrl ,
method : "GET" ,
headers : {
"X-Auth-Token" : config . authToken
}
});
if ( response . status !== 200 ) {
throw new Error ( `API request failed with status ${ response . status } ` );
}
const data = response . json ;
const loginName = data . data . login ;
if ( loginName !== groupName ) {
throw new Error ( `Token is valid but the team name " ${ loginName } " does not match the configured name " ${ groupName } "` );
}
new import_obsidian . Notice ( "Configuration is valid!" );
} catch ( error ) {
if ( error instanceof Error ) {
throw new Error ( `Configuration validation failed: ${ error . message } ` );
}
throw new Error ( "Configuration validation failed: Unknown error" );
}
}
};
// src/settings-tab.ts
var YuquePublishSettingTab = class extends import_obsidian3 . PluginSettingTab {
constructor ( app , plugin ) {
super ( app , plugin );
this . plugin = plugin ;
}
display () {
const { containerEl } = this ;
containerEl . empty ();
new import_obsidian3 . Setting ( containerEl ). setHeading (). setName ( "Yuque group and token explanation" );
const explanationDiv = containerEl . createDiv ( "yuque-explanation" );
const ol = explanationDiv . createEl ( "ol" );
const li1 = ol . createEl ( "li" );
li1 . createEl ( "strong" , { text : "If you are using a personal account:" });
li1 . createEl ( "p" , { text : "Your URL prefix: https://www.yuque.com/yourUserName/" });
li1 . createEl ( "p" , { text : "You can find your access token in: https://www.yuque.com/settings/tokens" });
const li2 = ol . createEl ( "li" );
li2 . createEl ( "strong" , { text : "If you are using a team account:" });
li2 . createEl ( "p" , { text : "Your URL prefix: https://spaceName.yuque.com/groupName/" });
li2 . createEl ( "p" , { text : "You can find your access token in: https://spaceName.yuque.com/groupName/settings/tokens" });
new import_obsidian3 . Setting ( containerEl ). setName ( "Add group" ). setDesc ( "Add a new Yuque group configuration" ). addButton (( button ) => {
button . setButtonText ( "Add group" ). onClick ( async () => {
this . plugin . settings . groups . push ({
urlPrefix : "" ,
authToken : ""
});
await this . plugin . saveSettings ();
this . display ();
});
});
this . plugin . settings . groups . forEach (( group , index ) => {
const groupDiv = containerEl . createDiv ( "yuque-group-setting" );
new import_obsidian3 . Setting ( groupDiv ). setName ( `Group ${ index + 1 } ` ). setHeading ();
new import_obsidian3 . Setting ( groupDiv ). setName ( "URL prefix" ). setDesc ( "The URL prefix of your Yuque group (e.g., https://spaceName.yuque.com/groupName/)" ). addText (( text ) => text . setPlaceholder ( "Enter URL prefix" ). setValue ( group . urlPrefix ). onChange ( async ( value ) => {
this . plugin . settings . groups [ index ]. urlPrefix = value ;
await this . plugin . saveSettings ();
}));
new import_obsidian3 . Setting ( groupDiv ). setName ( "Access token" ). setDesc ( "The access token for this group" ). addText (( text ) => text . setPlaceholder ( "Enter access token" ). setValue ( group . authToken ). onChange ( async ( value ) => {
this . plugin . settings . groups [ index ]. authToken = value ;
await this . plugin . saveSettings ();
}));
new import_obsidian3 . Setting ( groupDiv ). addButton (( button ) => {
button . setButtonText ( "Test" ). onClick ( async () => {
try {
await YuqueValidator . validate ({
urlPrefix : group . urlPrefix ,
authToken : group . authToken
});
} catch ( error ) {
if ( error instanceof Error ) {
new import_obsidian3 . Notice ( error . message );
} else {
new import_obsidian3 . Notice ( "Configuration validation failed: Unknown error" );
}
}
});
}). addButton (( button ) => {
button . setButtonText ( "Delete" ). setWarning (). onClick ( async () => {
this . plugin . settings . groups . splice ( index , 1 );
await this . plugin . saveSettings ();
this . display ();
});
});
});
}
};
2026-09-28 07:57:09 +08:00
// src/frontmatter.ts
function stripFrontMatter ( content , boundary ) {
if ( ! boundary . exists ) {
if ( /^---(?:\r?\n|$)/ . test ( content )) {
throw new Error ( "Front matter is not closed with a --- delimiter" );
}
throw new Error ( "No front matter found in the document" );
}
return content . slice ( boundary . contentStart );
}
2026-07-23 20:36:13 +08:00
// src/main.ts
var YuquePublishPlugin = class extends import_obsidian4 . Plugin {
constructor ( app , manifest ) {
super ( app , manifest );
}
async onload () {
await this . loadSettings ();
this . addSettingTab ( new YuquePublishSettingTab ( this . app , this ));
this . addCommand ({
id : "publish-to-yuque" ,
name : "Publish to Yuque" ,
callback : async () => {
const activeFile = this . app . workspace . getActiveFile ();
if ( ! activeFile ) {
new import_obsidian4 . Notice ( "No active file found" );
return ;
}
try {
await this . publishToYuque ( activeFile );
} catch ( error ) {
new import_obsidian4 . Notice ( `Failed to publish: ${ error . message } ` );
}
}
});
}
async publishToYuque ( file ) {
var _a ;
const content = await this . app . vault . read ( file );
2026-09-28 07:57:09 +08:00
const contentWithoutFrontMatter = stripFrontMatter ( content , ( 0 , import_obsidian4 . getFrontMatterInfo )( content ));
2026-07-23 20:36:13 +08:00
const frontMatter = ( _a = this . app . metadataCache . getFileCache ( file )) == null ? void 0 : _a . frontmatter ;
if ( ! frontMatter ) {
throw new Error ( "No front matter found in the document" );
}
const yuqueDocUrl = frontMatter [ "yuque-doc-url" ];
if ( ! yuqueDocUrl ) {
throw new Error ( "yuque-doc-url is required in front matter" );
}
const urlRegex = /^https:\/\/([^\/]+)\.yuque\.com\/([^\/]+)\/([^\/]+)\/([^\/]+)$/ ;
const match = yuqueDocUrl . match ( urlRegex );
if ( ! match ) {
throw new Error ( "Invalid yuque-doc-url format, should be like https://spaceName.yuque.com/groupName/bookSlug/docSlug" );
}
const title = frontMatter [ "yuque-doc-title" ] || file . basename ;
const publicValue = frontMatter [ "yuque-doc-public" ] || 1 ;
if ( publicValue != 0 && publicValue != 1 && publicValue != 2 ) {
throw new Error ( "Invalid yuque-doc-public value, should be 0, 1, or 2; 0: private, 1: public, 2: public for space members" );
}
const urlParts = yuqueDocUrl . split ( "/" );
if ( urlParts . length !== 6 ) {
throw new Error ( "Invalid yuque-doc-url format" );
}
const domain = urlParts [ 2 ];
const groupLogin = urlParts [ 3 ];
const bookSlug = urlParts [ 4 ];
const docSlug = urlParts [ 5 ];
const groupConfig = this . settings . groups . find (
( group ) => yuqueDocUrl . startsWith ( group . urlPrefix )
);
if ( ! groupConfig ) {
throw new Error ( `No auth token configured for ${ yuqueDocUrl } ` );
}
const headers = {
"Content-Type" : "application/json" ,
"X-Auth-Token" : groupConfig . authToken
};
const checkUrl = `https:// ${ domain } /api/v2/repos/ ${ groupLogin } / ${ bookSlug } /docs/ ${ docSlug } ` ;
let checkResponse ;
try {
checkResponse = await ( 0 , import_obsidian4 . requestUrl )({
url : checkUrl ,
headers
});
} catch ( error ) {
if ( error . status === 404 ) {
checkResponse = { status : 404 };
} else {
throw error ;
}
}
const payload = {
slug : docSlug ,
title ,
public : publicValue ,
format : "markdown" ,
body : contentWithoutFrontMatter
};
let response ;
if ( checkResponse . status === 200 ) {
response = await ( 0 , import_obsidian4 . requestUrl )({
url : checkUrl ,
method : "PUT" ,
headers ,
body : JSON . stringify ( payload )
});
} else {
const createUrl = `https:// ${ domain } /api/v2/repos/ ${ groupLogin } / ${ bookSlug } /docs` ;
response = await ( 0 , import_obsidian4 . requestUrl )({
url : createUrl ,
method : "POST" ,
headers ,
body : JSON . stringify ( payload )
});
}
if ( response . status < 200 || response . status >= 300 ) {
throw new Error ( `Failed to publish document: ${ response . status } ` );
}
window . open ( yuqueDocUrl , "_blank" );
new import_obsidian4 . Notice ( "Document published successfully!" );
}
async loadSettings () {
this . settings = Object . assign ({}, DEFAULT_SETTINGS , await this . loadData ());
}
async saveSettings () {
await this . saveData ( this . settings );
}
onunload () {
}
};
/* nosourcemap */