From 01a158f45aa2183c5c2a7ca8d2a902b236b8a0d4 Mon Sep 17 00:00:00 2001 From: Tea Date: Tue, 12 May 2026 16:38:29 -0400 Subject: [PATCH] test --- .github/workflows/release.yml | 56 +++++++++++++++++++++++++++++++++++ main.ts | 42 +++++++++++++++----------- 2 files changed, 81 insertions(+), 17 deletions(-) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..a783f2d --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,56 @@ +name: Release + +on: + push: + tags: + - "*" + +permissions: + contents: write + attestations: write + id-token: write + +jobs: + release: + name: Build and release plugin + runs-on: ubuntu-latest + + steps: + - name: Check out repository + uses: actions/checkout@v4 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + cache: npm + + - name: Install dependencies + run: npm ci + + - name: Build plugin + run: npm run build + + - name: Stage release assets + run: | + mkdir -p release + cp main.js manifest.json styles.css release/ + + - name: Generate artifact attestations + uses: actions/attest-build-provenance@v2 + with: + subject-path: | + release/main.js + release/manifest.json + release/styles.css + + - name: Create GitHub release + env: + GH_TOKEN: ${{ github.token }} + run: | + gh release create "${GITHUB_REF_NAME}" \ + release/main.js \ + release/manifest.json \ + release/styles.css \ + --title "${GITHUB_REF_NAME}" \ + --notes "Multimuse Tracker ${GITHUB_REF_NAME}" diff --git a/main.ts b/main.ts index 454df47..d229f06 100644 --- a/main.ts +++ b/main.ts @@ -106,12 +106,11 @@ function getErrorMessage(error: unknown): string { return 'Unknown error'; } -function getErrorStatus(error: unknown): number | undefined { - if (error && typeof error === 'object') { - const details = error as { status?: unknown }; - if (typeof details.status === 'number') return details.status; - } - return undefined; +function frontmatterValueToString(value: unknown, fallback = ''): string { + if (value === null || value === undefined) return fallback; + if (typeof value === 'string') return value; + if (typeof value === 'number' || typeof value === 'boolean') return String(value); + return fallback; } export default class MultimuseObsidian extends Plugin { @@ -250,7 +249,11 @@ export default class MultimuseObsidian extends Plugin { } async loadSettings() { - this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()); + const loaded = await this.loadData() as unknown; + const savedSettings = loaded && typeof loaded === 'object' + ? loaded as Partial + : {}; + this.settings = Object.assign({}, DEFAULT_SETTINGS, savedSettings); // Ensure botApiUrl always uses default if empty or not set if (!this.settings.botApiUrl || this.settings.botApiUrl.trim() === '') { this.settings.botApiUrl = DEFAULT_SETTINGS.botApiUrl; @@ -944,7 +947,8 @@ export default class MultimuseObsidian extends Plugin { const map = new Map(); for (const file of this.getSceneFiles()) { const cache = this.app.metadataCache.getFileCache(file); - const link = cache?.frontmatter?.['Link']; + const frontmatter = this.getFrontmatter(cache); + const link = frontmatter?.['Link']; if (!link || typeof link !== 'string') continue; const threadId = this.extractThreadIdFromUrl(link); if (threadId) map.set(threadId, file); @@ -971,13 +975,17 @@ export default class MultimuseObsidian extends Plugin { // Handle both array and single value if (Array.isArray(characters)) { - return characters.map(c => String(c).trim()); + return characters + .map(c => frontmatterValueToString(c).trim()) + .filter(c => c.length > 0); } else if (typeof characters === 'string') { // Handle comma-separated string return characters.split(',').map(c => c.trim()).filter(c => c.length > 0); + } else if (typeof characters === 'number' || typeof characters === 'boolean') { + return [frontmatterValueToString(characters).trim()]; } - return [String(characters).trim()]; + return []; } @@ -1498,9 +1506,9 @@ export default class MultimuseObsidian extends Plugin { // Extract characters from frontmatter const characters = this.getCharacterNames(frontmatter); - const link = frontmatter['Link'] || ''; - const participants = frontmatter['Participants'] || 2; - const replied = frontmatter['Replied?'] || false; + const link = frontmatterValueToString(frontmatter['Link']); + const participants = frontmatterValueToString(frontmatter['Participants'], '2'); + const replied = frontmatterValueToString(frontmatter['Replied?'], 'false'); // Check if scene already exists in table if (baseContent.includes(`| ${file.basename} |`)) { @@ -1781,12 +1789,12 @@ export default class MultimuseObsidian extends Plugin { return; } const cache = this.app.metadataCache.getFileCache(file); - if (!cache?.frontmatter) { + const frontmatter = this.getFrontmatter(cache); + if (!frontmatter) { new Notice('No frontmatter. Add a Link property (Discord thread URL) to this note.'); return; } - const frontmatter = this.getFrontmatter(cache); - const link = frontmatter?.['Link']; + const link = frontmatter['Link']; if (typeof link !== 'string') { new Notice('No Link property. Add the Discord thread URL to frontmatter to use @ mentions.'); return; @@ -2003,7 +2011,7 @@ class MultimuseObsidianSettingTab extends PluginSettingTab { containerEl.empty(); new Setting(containerEl) - .setName('Multimuse Settings') + .setName('Multimuse Tracker') .setHeading(); // Enable/Disable toggle