From 01861969bb9ea9a24c97972ca90bc34c3306ee7e Mon Sep 17 00:00:00 2001 From: Ryan Bantz Date: Mon, 25 Nov 2024 16:04:29 -0600 Subject: [PATCH] Initial commit --- .gitignore | 22 ++ esbuild.config.mjs | 49 +++++ main.ts | 422 +++++++++++++++++++++++++++++++++++ manifest.json | 10 + package-lock.json | 533 +++++++++++++++++++++++++++++++++++++++++++++ package.json | 20 ++ style.css | 0 tsconfig.json | 18 ++ 8 files changed, 1074 insertions(+) create mode 100644 .gitignore create mode 100644 esbuild.config.mjs create mode 100644 main.ts create mode 100644 manifest.json create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 style.css create mode 100644 tsconfig.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8bed253 --- /dev/null +++ b/.gitignore @@ -0,0 +1,22 @@ +# vscode +.vscode + +# Intellij +*.iml +.idea + +# npm +node_modules + +# Don't include the compiled main.js file in the repo. +# They should be uploaded to GitHub releases instead. +main.js + +# Exclude sourcemaps +*.map + +# obsidian +data.json + +# Exclude macOS Finder (System Explorer) View States +.DS_Store \ No newline at end of file diff --git a/esbuild.config.mjs b/esbuild.config.mjs new file mode 100644 index 0000000..539e1de --- /dev/null +++ b/esbuild.config.mjs @@ -0,0 +1,49 @@ +import esbuild from "esbuild"; +import process from "process"; +import builtins from "builtin-modules"; + +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 +*/ +`; + +const prod = (process.argv[2] === "production"); + +const context = await esbuild.context({ + banner: { + js: banner, + }, + entryPoints: ["main.ts"], + bundle: true, + 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", + ...builtins], + format: "cjs", + target: "es2018", + logLevel: "info", + sourcemap: prod ? false : "inline", + treeShaking: true, + outfile: "main.js", + minify: prod, +}); + +if (prod) { + await context.rebuild(); + process.exit(0); +} else { + await context.watch(); +} \ No newline at end of file diff --git a/main.ts b/main.ts new file mode 100644 index 0000000..a6a3e06 --- /dev/null +++ b/main.ts @@ -0,0 +1,422 @@ +import { + App, + Modal, + Notice, + Plugin, + PluginSettingTab, + Setting, + requestUrl, + Editor, + TextComponent, + ToggleComponent +} from 'obsidian'; + +/** + * Interface for plugin settings. + */ +interface AsanaPluginSettings { + asanaToken: string; + markTaskAsCompleted: boolean; +} + +/** + * Default settings for the plugin. + */ +const DEFAULT_SETTINGS: AsanaPluginSettings = { + asanaToken: '', + markTaskAsCompleted: false, +}; + +/** + * Main plugin class. + */ +export default class AsanaPlugin extends Plugin { + settings: AsanaPluginSettings; + + async onload() { + console.log('Loading Asana Task Creator plugin'); + + // Load settings + await this.loadSettings(); + + // Add command to the command palette + this.addCommand({ + id: 'create-asana-task', + name: 'Create Asana Task', + editorCallback: (editor: Editor) => this.createAsanaTask(editor), + }); + + // Add settings tab + this.addSettingTab(new AsanaSettingTab(this.app, this)); + + // Add right-click context menu option (requires Obsidian API version 0.13.0 or higher) + // Uncomment the following lines if your Obsidian version supports registering editor menu items + /* + this.registerEvent( + this.app.workspace.on('editor-menu', (menu, editor) => { + menu.addItem((item) => { + item.setTitle('Create Asana Task') + .setIcon('checkmark') + .onClick(() => this.createAsanaTask(editor)); + }); + }) + ); + */ + } + + onunload() { + console.log('Unloading Asana Task Creator plugin'); + } + + /** + * Loads plugin settings from disk. + */ + async loadSettings() { + this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()); + } + + /** + * Saves plugin settings to disk. + */ + async saveSettings() { + await this.saveData(this.settings); + } + + /** + * Main function to create an Asana task. + * @param editor The current editor instance. + */ + async createAsanaTask(editor: Editor) { + // Get the selected text or the current line + let selectedText = editor.getSelection(); + if (!selectedText) { + const cursor = editor.getCursor(); + selectedText = editor.getLine(cursor.line); + } + + // Prompt the user to select workspace, project, and section + const taskDetails = await this.promptForTaskDetails(); + if (!taskDetails) { + return; + } + + const { workspaceGid, projectGid, sectionGid } = taskDetails; + + // Create the task in Asana + try { + const response = await this.createTaskInAsana( + selectedText, + workspaceGid, + projectGid, + sectionGid + ); + + // Update the editor with the Asana task link + this.updateEditorWithTaskLink( + editor, + response.permalink_url, + taskDetails.projectName, + taskDetails.sectionName + ); + + // Optionally mark the task as completed in Obsidian + if (this.settings.markTaskAsCompleted) { + this.markTaskAsCompleted(editor); + } + } catch (error) { + new Notice(`Error creating Asana task: ${error.message}`); + } + } + + /** + * Prompts the user to select the workspace, project, and section. + * @returns An object containing the selected workspace, project, and section IDs and names. + */ + async promptForTaskDetails() { + const token = this.settings.asanaToken; + if (!token) { + new Notice('Asana Personal Access Token not set in plugin settings.'); + return null; + } + + try { + // Fetch workspaces + const workspacesResponse = await requestUrl({ + url: 'https://app.asana.com/api/1.0/workspaces', + method: 'GET', + headers: { + Authorization: `Bearer ${token}`, + }, + }); + const workspaces = workspacesResponse.json.data; + + // Prompt for workspace selection + const workspace = await this.promptForSelection( + 'Select Workspace', + workspaces.map((ws: any) => ({ name: ws.name, gid: ws.gid })) + ); + if (!workspace) return null; + + // Fetch projects in the workspace + const projectsResponse = await requestUrl({ + url: `https://app.asana.com/api/1.0/workspaces/${workspace.gid}/projects`, + method: 'GET', + headers: { + Authorization: `Bearer ${token}`, + }, + }); + const projects = projectsResponse.json.data; + + // Prompt for project selection + const project = await this.promptForSelection( + 'Select Project', + projects.map((p: any) => ({ name: p.name, gid: p.gid })) + ); + if (!project) return null; + + // Fetch sections in the project + const sectionsResponse = await requestUrl({ + url: `https://app.asana.com/api/1.0/projects/${project.gid}/sections`, + method: 'GET', + headers: { + Authorization: `Bearer ${token}`, + }, + }); + const sections = sectionsResponse.json.data; + + // Prompt for section selection + const section = await this.promptForSelection( + 'Select Section', + sections.map((s: any) => ({ name: s.name, gid: s.gid })) + ); + if (!section) return null; + + return { + workspaceGid: workspace.gid, + projectGid: project.gid, + sectionGid: section.gid, + projectName: project.name, + sectionName: section.name, + }; + } catch (error) { + new Notice(`Error fetching Asana data: ${error.message}`); + return null; + } + } + + /** + * Prompts the user to select an option from a list. + * @param title The title of the prompt. + * @param options The list of options to select from. + * @returns The selected option. + */ + async promptForSelection(title: string, options: Array<{ name: string; gid: string }>) { + return new Promise<{ name: string; gid: string } | null>((resolve) => { + const modal = new SelectionModal(this.app as App, title, options, resolve); + modal.open(); + }); + } + + /** + * Creates a task in Asana using the API. + * @param taskName The name of the task to create. + * @param workspaceGid The workspace GID. + * @param projectGid The project GID. + * @param sectionGid The section GID. + * @returns The response data from the API. + */ + async createTaskInAsana( + taskName: string, + workspaceGid: string, + projectGid: string, + sectionGid: string + ) { + const token = this.settings.asanaToken; + + const response = await requestUrl({ + url: 'https://app.asana.com/api/1.0/tasks', + method: 'POST', + headers: { + Authorization: `Bearer ${token}`, + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + data: { + name: taskName, + projects: [projectGid], + workspace: workspaceGid, + }, + }), + }); + + if (response.status >= 200 && response.status < 300) { + const taskGid = response.json.data.gid; + + // Move task to the selected section + await requestUrl({ + url: `https://app.asana.com/api/1.0/sections/${sectionGid}/addTask`, + method: 'POST', + headers: { + Authorization: `Bearer ${token}`, + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + data: { + task: taskGid, + }, + }), + }); + + // Fetch the task details to get the permalink_url + const taskResponse = await requestUrl({ + url: `https://app.asana.com/api/1.0/tasks/${taskGid}`, + method: 'GET', + headers: { + Authorization: `Bearer ${token}`, + }, + }); + + return taskResponse.json.data; + } else { + throw new Error(response.text); + } + } + + /** + * Updates the editor by inserting a markdown link to the Asana task. + * @param editor The current editor instance. + * @param taskUrl The URL of the Asana task. + * @param projectName The name of the Asana project. + * @param sectionName The name of the Asana section. + */ + updateEditorWithTaskLink( + editor: Editor, + taskUrl: string, + projectName: string, + sectionName: string + ) { + const linkText = `[asana#${projectName}/${sectionName}](${taskUrl})`; + const selectedText = editor.getSelection(); + if (selectedText) { + editor.replaceSelection(`${selectedText} ${linkText}`); + } else { + const cursor = editor.getCursor(); + const lineText = editor.getLine(cursor.line); + editor.setLine(cursor.line, `${lineText} ${linkText}`); + } + } + + /** + * Marks the task as completed in Obsidian by changing `- [ ]` to `- [x]`. + * @param editor The current editor instance. + */ + markTaskAsCompleted(editor: Editor) { + const cursor = editor.getCursor(); + const lineText = editor.getLine(cursor.line); + const completedLine = lineText.replace('- [ ]', '- [x]'); + editor.setLine(cursor.line, completedLine); + } +} + +/** + * Modal for selection prompts. + */ +class SelectionModal extends Modal { + title: string; + options: Array<{ name: string; gid: string }>; + onSelect: (result: { name: string; gid: string } | null) => void; + + constructor( + app: App, + title: string, + options: Array<{ name: string; gid: string }>, + onSelect: (result: { name: string; gid: string } | null) => void + ) { + super(app); + this.title = title; + this.options = options; + this.onSelect = onSelect; + } + + onOpen() { + const { contentEl } = this; + contentEl.createEl('h2', { text: this.title }); + + this.options.forEach((option) => { + const button = contentEl.createEl('button', { text: option.name }); + button.onclick = () => { + this.onSelect(option); + this.close(); + }; + }); + } + + onClose() { + const { contentEl } = this; + contentEl.empty(); + } +} + +/** + * Plugin settings tab. + */ +class AsanaSettingTab extends PluginSettingTab { + plugin: AsanaPlugin; + + constructor(app: App, plugin: AsanaPlugin) { + super(app, plugin); + this.plugin = plugin; + } + + display(): void { + const { containerEl } = this; + + containerEl.empty(); + + containerEl.createEl('h2', { text: 'Asana Task Creator Settings' }); + + // Asana Personal Access Token Setting + new Setting(containerEl) + .setName('Asana Personal Access Token') + .setDesc( + 'Enter your Asana Personal Access Token. You can create one in your Asana account settings.' + ) + // .addText((text: TextComponent) => + // text + // .setPlaceholder('Enter your token') + // .setValue(this.plugin.settings.asanaToken) + // .onChange(async (value) => { + // this.plugin.settings.asanaToken = value.trim(); + // await this.plugin.saveSettings(); + // }) + // ); + // Corrected addText + .addText((text: TextComponent) => { + text.setPlaceholder('Enter your token') // Correct usage of TextComponent + .setValue(this.plugin.settings.asanaToken) + .onChange(async (value: string) => { // Explicitly type `value` + this.plugin.settings.asanaToken = value.trim(); + await this.plugin.saveSettings(); + }); + }); + + // Mark Task as Completed Setting + new Setting(containerEl) + .setName('Mark Task as Completed') + .setDesc('Automatically mark the task as completed in Obsidian after creating it in Asana.') + // .addToggle((toggle: ToggleComponent) => + // toggle.setValue(this.plugin.settings.markTaskAsCompleted).onChange(async (value) => { + // this.plugin.settings.markTaskAsCompleted = value; + // await this.plugin.saveSettings(); + // }) + // ); + // Corrected addToggle + .addToggle((toggle: ToggleComponent) => { + toggle.setValue(this.plugin.settings.markTaskAsCompleted) + .onChange(async (value: boolean) => { // Explicitly type `value` + this.plugin.settings.markTaskAsCompleted = value; + await this.plugin.saveSettings(); + }); + }); + } +} \ No newline at end of file diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..0c3f0d5 --- /dev/null +++ b/manifest.json @@ -0,0 +1,10 @@ +{ + "id": "asana-task-creator", + "name": "Asana Task Creator", + "version": "1.0.0", + "minAppVersion": "0.12.0", + "description": "Create Asana tasks from highlighted text or current line in Obsidian.", + "author": "Your Name", + "authorUrl": "https://yourwebsite.com", + "isDesktopOnly": false +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..ba7a678 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,533 @@ +{ + "name": "asana-task-creator", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "asana-task-creator", + "version": "1.0.0", + "license": "MIT", + "devDependencies": { + "builtin-modules": "^4.0.0", + "esbuild": "0.17.3", + "obsidian": "^1.7.2", + "tslib": "^2.8.1", + "typescript": "^4.0.0" + } + }, + "node_modules/@codemirror/state": { + "version": "6.4.1", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@codemirror/view": { + "version": "6.35.0", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@codemirror/state": "^6.4.0", + "style-mod": "^4.1.0", + "w3c-keyname": "^2.2.4" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.3.tgz", + "integrity": "sha512-1Mlz934GvbgdDmt26rTLmf03cAgLg5HyOgJN+ZGCeP3Q9ynYTNMn2/LQxIl7Uy+o4K6Rfi2OuLsr12JQQR8gNg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.3.tgz", + "integrity": "sha512-XvJsYo3dO3Pi4kpalkyMvfQsjxPWHYjoX4MDiB/FUM4YMfWcXa5l4VCwFWVYI1+92yxqjuqrhNg0CZg3gSouyQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.3.tgz", + "integrity": "sha512-nuV2CmLS07Gqh5/GrZLuqkU9Bm6H6vcCspM+zjp9TdQlxJtIe+qqEXQChmfc7nWdyr/yz3h45Utk1tUn8Cz5+A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.3.tgz", + "integrity": "sha512-01Hxaaat6m0Xp9AXGM8mjFtqqwDjzlMP0eQq9zll9U85ttVALGCGDuEvra5Feu/NbP5AEP1MaopPwzsTcUq1cw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.3.tgz", + "integrity": "sha512-Eo2gq0Q/er2muf8Z83X21UFoB7EU6/m3GNKvrhACJkjVThd0uA+8RfKpfNhuMCl1bKRfBzKOk6xaYKQZ4lZqvA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.3.tgz", + "integrity": "sha512-CN62ESxaquP61n1ZjQP/jZte8CE09M6kNn3baos2SeUfdVBkWN5n6vGp2iKyb/bm/x4JQzEvJgRHLGd5F5b81w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.3.tgz", + "integrity": "sha512-feq+K8TxIznZE+zhdVurF3WNJ/Sa35dQNYbaqM/wsCbWdzXr5lyq+AaTUSER2cUR+SXPnd/EY75EPRjf4s1SLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.3.tgz", + "integrity": "sha512-CLP3EgyNuPcg2cshbwkqYy5bbAgK+VhyfMU7oIYyn+x4Y67xb5C5ylxsNUjRmr8BX+MW3YhVNm6Lq6FKtRTWHQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.3.tgz", + "integrity": "sha512-JHeZXD4auLYBnrKn6JYJ0o5nWJI9PhChA/Nt0G4MvLaMrvXuWnY93R3a7PiXeJQphpL1nYsaMcoV2QtuvRnF/g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.3.tgz", + "integrity": "sha512-FyXlD2ZjZqTFh0sOQxFDiWG1uQUEOLbEh9gKN/7pFxck5Vw0qjWSDqbn6C10GAa1rXJpwsntHcmLqydY9ST9ZA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.3.tgz", + "integrity": "sha512-OrDGMvDBI2g7s04J8dh8/I7eSO+/E7nMDT2Z5IruBfUO/RiigF1OF6xoH33Dn4W/OwAWSUf1s2nXamb28ZklTA==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.3.tgz", + "integrity": "sha512-DcnUpXnVCJvmv0TzuLwKBC2nsQHle8EIiAJiJ+PipEVC16wHXaPEKP0EqN8WnBe0TPvMITOUlP2aiL5YMld+CQ==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.3.tgz", + "integrity": "sha512-BDYf/l1WVhWE+FHAW3FzZPtVlk9QsrwsxGzABmN4g8bTjmhazsId3h127pliDRRu5674k1Y2RWejbpN46N9ZhQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.3.tgz", + "integrity": "sha512-WViAxWYMRIi+prTJTyV1wnqd2mS2cPqJlN85oscVhXdb/ZTFJdrpaqm/uDsZPGKHtbg5TuRX/ymKdOSk41YZow==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.3.tgz", + "integrity": "sha512-Iw8lkNHUC4oGP1O/KhumcVy77u2s6+KUjieUqzEU3XuWJqZ+AY7uVMrrCbAiwWTkpQHkr00BuXH5RpC6Sb/7Ug==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.3.tgz", + "integrity": "sha512-0AGkWQMzeoeAtXQRNB3s4J1/T2XbigM2/Mn2yU1tQSmQRmHIZdkGbVq2A3aDdNslPyhb9/lH0S5GMTZ4xsjBqg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.3.tgz", + "integrity": "sha512-4+rR/WHOxIVh53UIQIICryjdoKdHsFZFD4zLSonJ9RRw7bhKzVyXbnRPsWSfwybYqw9sB7ots/SYyufL1mBpEg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.3.tgz", + "integrity": "sha512-cVpWnkx9IYg99EjGxa5Gc0XmqumtAwK3aoz7O4Dii2vko+qXbkHoujWA68cqXjhh6TsLaQelfDO4MVnyr+ODeA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.3.tgz", + "integrity": "sha512-RxmhKLbTCDAY2xOfrww6ieIZkZF+KBqG7S2Ako2SljKXRFi+0863PspK74QQ7JpmWwncChY25JTJSbVBYGQk2Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.3.tgz", + "integrity": "sha512-0r36VeEJ4efwmofxVJRXDjVRP2jTmv877zc+i+Pc7MNsIr38NfsjkQj23AfF7l0WbB+RQ7VUb+LDiqC/KY/M/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.3.tgz", + "integrity": "sha512-wgO6rc7uGStH22nur4aLFcq7Wh86bE9cOFmfTr/yxN3BXvDEdCSXyKkO+U5JIt53eTOgC47v9k/C1bITWL/Teg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.3.tgz", + "integrity": "sha512-FdVl64OIuiKjgXBjwZaJLKp0eaEckifbhn10dXWhysMJkWblg3OEEGKSIyhiD5RSgAya8WzP3DNkngtIg3Nt7g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@types/codemirror": { + "version": "5.60.8", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/tern": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/tern": { + "version": "0.23.9", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/builtin-modules": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-4.0.0.tgz", + "integrity": "sha512-p1n8zyCkt1BVrKNFymOHjcDSAl7oq/gUvfgULv2EblgpPVQlQr9yHnWjg9IJ2MhfwPqiYqMMrr01OY7yQoK2yA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/esbuild": { + "version": "0.17.3", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.3.tgz", + "integrity": "sha512-9n3AsBRe6sIyOc6kmoXg2ypCLgf3eZSraWFRpnkto+svt8cZNuKTkb1bhQcitBcvIqjNiK7K0J3KPmwGSfkA8g==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/android-arm": "0.17.3", + "@esbuild/android-arm64": "0.17.3", + "@esbuild/android-x64": "0.17.3", + "@esbuild/darwin-arm64": "0.17.3", + "@esbuild/darwin-x64": "0.17.3", + "@esbuild/freebsd-arm64": "0.17.3", + "@esbuild/freebsd-x64": "0.17.3", + "@esbuild/linux-arm": "0.17.3", + "@esbuild/linux-arm64": "0.17.3", + "@esbuild/linux-ia32": "0.17.3", + "@esbuild/linux-loong64": "0.17.3", + "@esbuild/linux-mips64el": "0.17.3", + "@esbuild/linux-ppc64": "0.17.3", + "@esbuild/linux-riscv64": "0.17.3", + "@esbuild/linux-s390x": "0.17.3", + "@esbuild/linux-x64": "0.17.3", + "@esbuild/netbsd-x64": "0.17.3", + "@esbuild/openbsd-x64": "0.17.3", + "@esbuild/sunos-x64": "0.17.3", + "@esbuild/win32-arm64": "0.17.3", + "@esbuild/win32-ia32": "0.17.3", + "@esbuild/win32-x64": "0.17.3" + } + }, + "node_modules/moment": { + "version": "2.29.4", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/obsidian": { + "version": "1.7.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/codemirror": "5.60.8", + "moment": "2.29.4" + }, + "peerDependencies": { + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0" + } + }, + "node_modules/style-mod": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/tslib": { + "version": "2.8.1", + "dev": true, + "license": "0BSD" + }, + "node_modules/typescript": { + "version": "4.9.5", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/w3c-keyname": { + "version": "2.2.8", + "dev": true, + "license": "MIT", + "peer": true + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..f7a5156 --- /dev/null +++ b/package.json @@ -0,0 +1,20 @@ +{ + "name": "asana-task-creator", + "version": "1.0.0", + "main": "main.js", + "scripts": { + "dev": "node esbuild.config.mjs", + "build": "tsc -noEmit -skipLibCheck && node esbuild.config.mjs production", + "version": "node version-bump.mjs && git add manifest.json versions.json" + }, + "keywords": [], + "author": "", + "license": "MIT", + "devDependencies": { + "builtin-modules": "^4.0.0", + "esbuild": "0.17.3", + "obsidian": "^1.7.2", + "tslib": "^2.8.1", + "typescript": "^4.0.0" + } +} diff --git a/style.css b/style.css new file mode 100644 index 0000000..e69de29 diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..e72624c --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "inlineSourceMap": true, + "inlineSources": true, + "module": "ESNext", + "target": "ES6", + "allowJs": true, + "noImplicitAny": true, + "moduleResolution": "node", + "importHelpers": true, + "isolatedModules": true, + "strictNullChecks": true, + "lib": ["DOM", "ES6"], + "types": ["obsidian"] + }, + "include": ["**/*.ts"] +} \ No newline at end of file