mirror of
https://github.com/mryanb/obsidian-asana.git
synced 2026-07-22 05:38:24 +00:00
Initial commit
This commit is contained in:
commit
01861969bb
8 changed files with 1074 additions and 0 deletions
22
.gitignore
vendored
Normal file
22
.gitignore
vendored
Normal file
|
|
@ -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
|
||||
49
esbuild.config.mjs
Normal file
49
esbuild.config.mjs
Normal file
|
|
@ -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();
|
||||
}
|
||||
422
main.ts
Normal file
422
main.ts
Normal file
|
|
@ -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();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
10
manifest.json
Normal file
10
manifest.json
Normal file
|
|
@ -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
|
||||
}
|
||||
533
package-lock.json
generated
Normal file
533
package-lock.json
generated
Normal file
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
20
package.json
Normal file
20
package.json
Normal file
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
0
style.css
Normal file
0
style.css
Normal file
18
tsconfig.json
Normal file
18
tsconfig.json
Normal file
|
|
@ -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"]
|
||||
}
|
||||
Loading…
Reference in a new issue