commit 0f2422bb5f442a4216a49ff4a0658faa21178568 Author: Kirill Gavrilov Date: Tue Jan 21 19:29:37 2025 +0300 build: prepare minimal environment for timecodes plugin development diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2f82878 --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +# Intellij +*.iml +.idea/ + +# package managers +node_modules/ +.pnpm-store/ +package-lock.json +pnpm-lock.yaml +yarn.lock + +# build +out/ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..855ec66 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Kirill Gavrilov + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..0d74d81 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# Obsidian Timecodes Plugin diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..95ce090 --- /dev/null +++ b/manifest.json @@ -0,0 +1,10 @@ +{ + "id": "timecodes", + "name": "Timecodes", + "version": "0.0.1", + "minAppVersion": "0.13.8", + "description": "Converts raw text timecodes into clickable URLs if a note contains a link to a video", + "author": "Kirill Gavrilov", + "authorUrl": "https://github.com/gavvvr", + "isDesktopOnly": false +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..f14de80 --- /dev/null +++ b/package.json @@ -0,0 +1,25 @@ +{ + "name": "obsidian-timecodes-plugin", + "type": "module", + "private": true, + "scripts": { + "dev": "node scripts/dev.js", + "build": "tsc -noEmit -skipLibCheck && node scripts/esbuild.build.js production" + }, + "keywords": [ + "obsidian.md", + "youtube", + "timecodes" + ], + "author": "Kirill Gavrilov", + "license": "MIT", + "devDependencies": { + "@types/node": "22.10.7", + "enquirer": "2.4.1", + "esbuild": "0.24.2", + "obsidian": "1.7.2", + "obsidian-utils": "0.10.2", + "typescript": "5.7.3" + }, + "packageManager": "pnpm@9.15.4" +} diff --git a/scripts/dev.js b/scripts/dev.js new file mode 100644 index 0000000..21381a7 --- /dev/null +++ b/scripts/dev.js @@ -0,0 +1,51 @@ +// @ts-check + +import fs from 'node:fs/promises' +import path from 'node:path' +import { exit } from 'node:process' + +import enquirer from 'enquirer' +import esbuild from 'esbuild' +import obsidianUtils from 'obsidian-utils' + +import { sharedEsbuildConfig } from './esbuild.config.js' + +const { findVault, installPluginFromGithub, isPluginInstalled } = obsidianUtils + +let vaults +try { + vaults = await findVault() +} catch (e) { + console.error('Failed to find vaults', e) + exit(1) +} + +const vaultsOptions = vaults.map(v => ({ message: v.name, name: v.path })) + +/** @type {{ selectedVaultPath: string }} */ +const { selectedVaultPath } = await enquirer.prompt({ + type: 'select', + name: 'selectedVaultPath', + message: 'Select Obsidian Vault for development', + choices: vaultsOptions, +}) + +if (!await isPluginInstalled('hot-reload', selectedVaultPath)) { + console.log('Installing hot-reload from github...') + await installPluginFromGithub('pjeby/hot-reload', 'latest', selectedVaultPath) +} + +const localManifestPath = path.join(process.cwd(), 'manifest.json') +const manifest = JSON.parse(await fs.readFile(localManifestPath, { encoding: 'utf-8' })) + +const pluginPath = path.join(selectedVaultPath, '.obsidian', 'plugins', manifest.id) + +fs.mkdir(pluginPath, { recursive: true }) +await fs.copyFile(localManifestPath, path.join(pluginPath, 'manifest.json')) +await fs.writeFile(path.join(pluginPath, '.hotreload'), '') + +const esbuildCtx = await esbuild.context({ + ...sharedEsbuildConfig, + ...{ outfile: path.join(pluginPath, 'main.js') }, +}) +esbuildCtx.watch() diff --git a/scripts/esbuild.build.js b/scripts/esbuild.build.js new file mode 100644 index 0000000..cf0a7f2 --- /dev/null +++ b/scripts/esbuild.build.js @@ -0,0 +1,25 @@ +// @ts-check + +import process from 'node:process' + +import esbuild from 'esbuild' + +import { sharedEsbuildConfig } from './esbuild.config.js' + +const config = sharedEsbuildConfig + +const prod = process.argv[2] === 'production' + +const context = await esbuild.context({ + ...config, + ...prod + ? { minify: true, sourcemap: false } + : {}, +}) + +if (prod) { + await context.rebuild() + process.exit(0) +} else { + await context.watch() +} diff --git a/scripts/esbuild.config.js b/scripts/esbuild.config.js new file mode 100644 index 0000000..9c1b04b --- /dev/null +++ b/scripts/esbuild.config.js @@ -0,0 +1,40 @@ +// @ts-check + +import path from 'node:path' + +const banner = `/* +THIS IS A GENERATED/BUNDLED FILE BY ESBUILD +if you want to view the source, please visit the github repository of this plugin +*/ +` + +/** @type {import("esbuild").BuildOptions} */ +export const sharedEsbuildConfig = { + logLevel: 'info', + banner: { + js: banner, + }, + external: [ + 'obsidian', + 'electron', + '@codemirror/autocomplete', + '@codemirror/collab', + '@codemirror/commands', + '@codemirror/language', + '@codemirror/lint', + '@codemirror/search', + '@codemirror/state', + '@codemirror/view', + '@lezer/common', + '@lezer/highlight', + '@lezer/lr', + ], + bundle: true, + entryPoints: ['src/TimecodesPlugin.ts'], + format: 'cjs', + target: 'es2018', + minify: false, + sourcemap: 'inline', + treeShaking: true, + outfile: path.join('out', 'main.js'), +} diff --git a/src/TimecodesPlugin.ts b/src/TimecodesPlugin.ts new file mode 100644 index 0000000..51907ef --- /dev/null +++ b/src/TimecodesPlugin.ts @@ -0,0 +1,7 @@ +import { Plugin } from 'obsidian' + +export default class TimecodesPlugin extends Plugin { + override onload() { + console.log('Timecodes Plugin has started') + } +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..2c70fb5 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "module": "ESNext", + "moduleResolution": "node", + "target": "ES6", + "noImplicitAny": true, + "isolatedModules": true, + "strict": true, + "strictBindCallApply": true, + "strictNullChecks": true, + "lib": [ + "DOM", + "DOM.Iterable", + "ES5", + "ES6", + "ES7" + ], + }, + "include": [ + "**/*.ts" + ], +} diff --git a/versions.json b/versions.json new file mode 100644 index 0000000..f706e94 --- /dev/null +++ b/versions.json @@ -0,0 +1,3 @@ +{ + "0.0.1": "0.13.8" +}