├── .eslintignore ├── .eslintrc.js ├── .github ├── FUNDING.yml └── workflows │ └── main.yml ├── .gitignore ├── .prettierrc.js ├── README.md ├── manifest.json ├── package.json ├── rollup.config.js ├── screenshot.gif ├── src ├── OpenRandomTaggedNoteModalView.svelte ├── main.ts ├── openRandomTaggedNoteModal.ts ├── settingTab.ts ├── smartRandomNoteNotice.ts ├── types.ts └── utilities.ts ├── styles.css ├── tsconfig.json └── versions.json /.eslintignore: -------------------------------------------------------------------------------- 1 | dist/ -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | parser: '@typescript-eslint/parser', // Specifies the ESLint parser 3 | parserOptions: { 4 | ecmaVersion: 2020, // Allows for the parsing of modern ECMAScript features 5 | sourceType: 'module', // Allows for the use of imports 6 | }, 7 | extends: [ 8 | 'plugin:@typescript-eslint/recommended', // Uses the recommended rules from the @typescript-eslint/eslint-plugin 9 | 'prettier/@typescript-eslint', // Uses eslint-config-prettier to disable ESLint rules from @typescript-eslint/eslint-plugin that would conflict with prettier 10 | 'plugin:prettier/recommended', // Enables eslint-plugin-prettier and eslint-config-prettier. This will display prettier errors as ESLint errors. Make sure this is always the last configuration in the extends array. 11 | ], 12 | rules: { 13 | // Place to specify ESLint rules. Can be used to overwrite rules specified from the extended configs 14 | // e.g. "@typescript-eslint/explicit-function-return-type": "off", 15 | }, 16 | }; 17 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: ["erichalldev"] 2 | custom: ["https://www.buymeacoffee.com/erichall"] 3 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Build obsidian plugin 2 | 3 | on: 4 | push: 5 | # Sequence of patterns matched against refs/tags 6 | tags: 7 | - '*' # Push events to matching any tag format, i.e. 1.0, 20.15.10 8 | 9 | env: 10 | PLUGIN_NAME: smart-random-note # Change this to the name of your plugin-id folder 11 | 12 | jobs: 13 | build: 14 | 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - uses: actions/checkout@v2 19 | - name: Use Node.js 20 | uses: actions/setup-node@v1 21 | with: 22 | node-version: '14.x' # You might need to adjust this value to your own version 23 | - name: Build 24 | id: build 25 | run: | 26 | npm install 27 | npm run build --if-present 28 | mkdir ${{ env.PLUGIN_NAME }} 29 | cp dist/main.js manifest.json ${{ env.PLUGIN_NAME }} 30 | zip -r ${{ env.PLUGIN_NAME }}.zip ${{ env.PLUGIN_NAME }} 31 | ls 32 | echo "::set-output name=tag_name::$(git tag --sort version:refname | tail -n 1)" 33 | - name: Create Release 34 | id: create_release 35 | uses: actions/create-release@v1 36 | env: 37 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 38 | VERSION: ${{ github.ref }} 39 | with: 40 | tag_name: ${{ github.ref }} 41 | release_name: ${{ github.ref }} 42 | draft: false 43 | prerelease: false 44 | - name: Upload zip file 45 | id: upload-zip 46 | uses: actions/upload-release-asset@v1 47 | env: 48 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 49 | with: 50 | upload_url: ${{ steps.create_release.outputs.upload_url }} 51 | asset_path: ./${{ env.PLUGIN_NAME }}.zip 52 | asset_name: ${{ env.PLUGIN_NAME }}-${{ steps.build.outputs.tag_name }}.zip 53 | asset_content_type: application/zip 54 | - name: Upload main.js 55 | id: upload-main 56 | uses: actions/upload-release-asset@v1 57 | env: 58 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 59 | with: 60 | upload_url: ${{ steps.create_release.outputs.upload_url }} 61 | asset_path: ./dist/main.js 62 | asset_name: main.js 63 | asset_content_type: text/javascript 64 | - name: Upload manifest.json 65 | id: upload-manifest 66 | uses: actions/upload-release-asset@v1 67 | env: 68 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 69 | with: 70 | upload_url: ${{ steps.create_release.outputs.upload_url }} 71 | asset_path: ./manifest.json 72 | asset_name: manifest.json 73 | asset_content_type: application/json 74 | # - name: Upload styles.css 75 | # id: upload-css 76 | # uses: actions/upload-release-asset@v1 77 | # env: 78 | # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 79 | # with: 80 | # upload_url: ${{ steps.create_release.outputs.upload_url }} 81 | # asset_path: ./styles.css 82 | # asset_name: styles.css 83 | # asset_content_type: text/css 84 | 85 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | dist/ 3 | package-lock.json 4 | copy-to-vault.bat -------------------------------------------------------------------------------- /.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | semi: true, 3 | trailingComma: "all", 4 | singleQuote: true, 5 | printWidth: 120, 6 | tabWidth: 4, 7 | endOfLine: 'auto', 8 | }; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Downloads](https://img.shields.io/github/downloads/erichalldev/obsidian-smart-random-note/total.svg) 2 | 3 | # Smart Random Note Obsidian Plugin 4 | 5 | This plugin enhances opening random notes. 6 | 7 | Three commands are available: 8 | 9 | - Open Random Note from Search: opens a random note from the list of search results. 10 | - Insert Link at Cursor to Random Note from Search: inserts a link where the cursor is positioned to a raondom note from the list of search results. 11 | - Open Tagged Random Note: opens a random note that has a selected tag. 12 | - Open Random Note: behaves similarly to the core random note plugin. 13 | 14 | ![Screenshot](https://raw.githubusercontent.com/erichalldev/obsidian-smart-random-note/master/screenshot.gif) 15 | 16 | ## Future Plans 17 | 18 | - Originally I had plans to implement spaced repetition capabilities, but other plugins have been developed that handle that domain well. They are: 19 | - [Flashcards](https://github.com/reuseman/flashcards-obsidian) 20 | - [Spaced Repetition](https://github.com/st3v3nmw/obsidian-spaced-repetition) 21 | - [Recall](https://github.com/martin-jw/obsidian-recall) 22 | - I'd like to stay as close as possible to the Unix adage "do one thing, and do it well" with this plugin. Therefore any features and improvements must stay close to its core function: opening random notes with greater control. 23 | 24 | ## Installation 25 | 26 | ### From within Obsidian 27 | 28 | From Obsidian 0.9.8, you can activate this plugin within Obsidian by doing the following: 29 | 30 | - Open Settings > Third-party plugin 31 | - Make sure Safe mode is **off** 32 | - Click Browse community plugins 33 | - Search for "Smart Random Note" 34 | - Click Install 35 | - Once installed, close the community plugins window and activate the plugin 36 | 37 | ## Compatibility 38 | 39 | Custom plugins are officially supported in Obsidian version 0.9.7. This plugin currently targets API version 0.9.15 but should be compatible with version 0.9.7 or higher. 40 | 41 | ## Version History 42 | 43 | ### 0.2.1 44 | 45 | - Add command to insert a link at the cursor to a random note from search 46 | - Fix opening a new markdown note when an image was selected to open. Opening any files except markdown is not supported. 47 | 48 | ### 0.1.3 49 | 50 | - Fix broken open random note from search command in Obsidian 0.9.18 51 | 52 | ### 0.1.2 53 | 54 | - Add support for frontmatter tags introduced in Obsidian 0.9.16 55 | 56 | ### 0.1.1 57 | 58 | - Add command for opening a random note from the current search results 59 | - Add setting to add a button to the ribbon for opening a random note from the current search results 60 | - Add setting to open the random note in the active leaf or a new leaf 61 | 62 | ### 0.0.5 63 | 64 | - Initial Release 65 | - Add command for opening a random note from all notes 66 | - Add command for opening a random note given a tag 67 | -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "smart-random-note", 3 | "name": "Smart Random Note", 4 | "version": "0.2.1", 5 | "minAppVersion": "0.9.18", 6 | "description": "A smart random note plugin", 7 | "author": "Eric Hall", 8 | "authorUrl": "https://erichall.io", 9 | "isDesktopOnly": false 10 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "smart-random-note", 3 | "version": "0.2.0", 4 | "description": "A smart random note plugin for Obsidian (https://obsidian.md)", 5 | "main": "main.js", 6 | "scripts": { 7 | "dev": "rollup --config rollup.config.js -w", 8 | "build": "rollup --config rollup.config.js", 9 | "lint": "svelte-check && eslint ./**/*.{js,ts} --quiet --fix" 10 | }, 11 | "keywords": [], 12 | "author": "", 13 | "devDependencies": { 14 | "@rollup/plugin-commonjs": "^15.1.0", 15 | "@rollup/plugin-node-resolve": "^10.0.0", 16 | "@rollup/plugin-typescript": "^6.0.0", 17 | "@tsconfig/svelte": "^1.0.10", 18 | "@types/node": "^14.14.10", 19 | "@typescript-eslint/eslint-plugin": "^4.8.2", 20 | "@typescript-eslint/parser": "^4.8.2", 21 | "eslint": "^7.13.0", 22 | "eslint-config-prettier": "^6.15.0", 23 | "eslint-plugin-prettier": "^3.1.4", 24 | "obsidian": "https://github.com/obsidianmd/obsidian-api/tarball/master", 25 | "prettier": "^2.1.2", 26 | "rollup": "^2.33.2", 27 | "rollup-plugin-svelte": "^7.0.0", 28 | "svelte": "^3.30.0", 29 | "svelte-check": "^1.1.17", 30 | "svelte-preprocess": "^4.6.1", 31 | "tslib": "^2.0.3", 32 | "typescript": "^4.0.3" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import svelte from 'rollup-plugin-svelte'; 2 | import typescript from '@rollup/plugin-typescript'; 3 | import resolve from '@rollup/plugin-node-resolve'; 4 | import commonjs from '@rollup/plugin-commonjs'; 5 | import autoPreprocess from 'svelte-preprocess'; 6 | 7 | export default { 8 | input: 'src/main.ts', 9 | output: { 10 | dir: 'dist', 11 | sourcemap: 'inline', 12 | format: 'cjs', 13 | exports: 'default', 14 | }, 15 | external: ['obsidian'], 16 | plugins: [ 17 | svelte({ preprocess: autoPreprocess() }), 18 | typescript({ sourceMap: true }), 19 | resolve({ browser: true, dedupe: ['svelte'] }), 20 | commonjs({ include: 'node_modules/**' }), 21 | ], 22 | }; 23 | -------------------------------------------------------------------------------- /screenshot.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erichalldev/obsidian-smart-random-note/e17078681af5659c0400c4924cf8424dfa6d3b2a/screenshot.gif -------------------------------------------------------------------------------- /src/OpenRandomTaggedNoteModalView.svelte: -------------------------------------------------------------------------------- 1 | 9 | 10 |

Select Tag

11 | 12 |
13 | 18 | 19 |
20 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import { MarkdownView, Plugin, TFile } from 'obsidian'; 2 | import { getTagFilesMap, randomElement } from './utilities'; 3 | import { SmartRandomNoteSettingTab } from './settingTab'; 4 | import { SearchView, SmartRandomNoteSettings } from './types'; 5 | import { SmartRandomNoteNotice } from './smartRandomNoteNotice'; 6 | import { OpenRandomTaggedNoteModal } from './openRandomTaggedNoteModal'; 7 | 8 | export default class SmartRandomNotePlugin extends Plugin { 9 | settings: SmartRandomNoteSettings = { openInNewLeaf: true, enableRibbonIcon: true }; 10 | ribbonIconEl: HTMLElement | undefined = undefined; 11 | 12 | async onload(): Promise { 13 | console.log('loading smart-random-note'); 14 | 15 | await this.loadSettings(); 16 | 17 | this.addSettingTab(new SmartRandomNoteSettingTab(this)); 18 | 19 | this.addCommand({ 20 | id: 'open-random-note', 21 | name: 'Open Random Note', 22 | callback: this.handleOpenRandomNote, 23 | }); 24 | 25 | this.addCommand({ 26 | id: 'open-tagged-random-note', 27 | name: 'Open Tagged Random Note', 28 | callback: this.handleOpenTaggedRandomNote, 29 | }); 30 | 31 | this.addCommand({ 32 | id: 'open-random-note-from-search', 33 | name: 'Open Random Note from Search', 34 | callback: this.handleOpenRandomNoteFromSearch, 35 | }); 36 | 37 | this.addCommand({ 38 | id: 'insert-link-to-random-note-at-cursor', 39 | name: 'Insert Link at Cursor to Random Note from Search', 40 | callback: this.handleInsertLinkFromSearch, 41 | }); 42 | } 43 | 44 | onunload = (): void => { 45 | console.log('unloading smart-random-note'); 46 | }; 47 | 48 | handleOpenRandomNote = async (): Promise => { 49 | const markdownFiles = this.app.vault.getMarkdownFiles(); 50 | 51 | this.openRandomNote(markdownFiles); 52 | }; 53 | 54 | handleOpenTaggedRandomNote = (): void => { 55 | const tagFilesMap = getTagFilesMap(this.app); 56 | 57 | const tags = Object.keys(tagFilesMap); 58 | const modal = new OpenRandomTaggedNoteModal(this.app, tags); 59 | 60 | modal.submitCallback = async (selectedTag: string): Promise => { 61 | const taggedFiles = tagFilesMap[selectedTag]; 62 | await this.openRandomNote(taggedFiles); 63 | }; 64 | 65 | modal.open(); 66 | }; 67 | 68 | handleOpenRandomNoteFromSearch = async (): Promise => { 69 | const searchView = this.app.workspace.getLeavesOfType('search')[0]?.view as SearchView; 70 | 71 | if (!searchView) { 72 | new SmartRandomNoteNotice('The core search plugin is not enabled', 5000); 73 | return; 74 | } 75 | 76 | const searchResults = searchView.dom.getFiles(); 77 | 78 | if (!searchResults.length) { 79 | new SmartRandomNoteNotice('No search results available', 5000); 80 | return; 81 | } 82 | 83 | await this.openRandomNote(searchResults); 84 | }; 85 | 86 | handleInsertLinkFromSearch = async (): Promise => { 87 | const searchView = this.app.workspace.getLeavesOfType('search')[0]?.view as SearchView; 88 | 89 | if (!searchView) { 90 | new SmartRandomNoteNotice('The core search plugin is not enabled', 5000); 91 | return; 92 | } 93 | 94 | const searchResults = searchView.dom.getFiles(); 95 | 96 | if (!searchResults.length) { 97 | new SmartRandomNoteNotice('No search results available', 5000); 98 | return; 99 | } 100 | 101 | await this.insertRandomLinkAtCursor(searchResults); 102 | }; 103 | 104 | openRandomNote = async (files: TFile[]): Promise => { 105 | const markdownFiles = files.filter((file) => file.extension === 'md'); 106 | 107 | if (!markdownFiles.length) { 108 | new SmartRandomNoteNotice("Can't open note. No markdown files available to open.", 5000); 109 | return; 110 | } 111 | 112 | const fileToOpen = randomElement(markdownFiles); 113 | await this.app.workspace.openLinkText(fileToOpen.basename, '', this.settings.openInNewLeaf, { 114 | active: true, 115 | }); 116 | }; 117 | 118 | insertRandomLinkAtCursor = async (files: TFile[]): Promise => { 119 | const fileToLink = randomElement(files); 120 | const activeLeaf = this.app.workspace.activeLeaf; 121 | if (!activeLeaf) { 122 | new SmartRandomNoteNotice("Can't insert link. No active note to insert link into", 5000); 123 | return; 124 | } 125 | const viewState = activeLeaf.getViewState(); 126 | const canEdit = viewState.type === 'markdown' && viewState.state && viewState.state.mode == 'source'; 127 | 128 | if (!canEdit) { 129 | new SmartRandomNoteNotice("Can't insert link. The active file is not a markdown file in edit mode.", 5000); 130 | return; 131 | } 132 | 133 | const markdownView = activeLeaf.view as MarkdownView; 134 | const cursorPos = markdownView.editor.getCursor(); 135 | const textToInsert = `[[${fileToLink.name}]]`; 136 | markdownView.editor.replaceRange(textToInsert, cursorPos); 137 | }; 138 | 139 | loadSettings = async (): Promise => { 140 | const loadedSettings = (await this.loadData()) as SmartRandomNoteSettings; 141 | if (loadedSettings) { 142 | this.setOpenInNewLeaf(loadedSettings.openInNewLeaf); 143 | this.setEnableRibbonIcon(loadedSettings.enableRibbonIcon); 144 | } else { 145 | this.refreshRibbonIcon(); 146 | } 147 | }; 148 | 149 | setOpenInNewLeaf = (value: boolean): void => { 150 | this.settings.openInNewLeaf = value; 151 | this.saveData(this.settings); 152 | }; 153 | 154 | setEnableRibbonIcon = (value: boolean): void => { 155 | this.settings.enableRibbonIcon = value; 156 | this.refreshRibbonIcon(); 157 | this.saveData(this.settings); 158 | }; 159 | 160 | refreshRibbonIcon = (): void => { 161 | this.ribbonIconEl?.remove(); 162 | if (this.settings.enableRibbonIcon) { 163 | this.ribbonIconEl = this.addRibbonIcon( 164 | 'dice', 165 | 'Open Random Note from Search', 166 | this.handleOpenRandomNoteFromSearch, 167 | ); 168 | } 169 | }; 170 | } 171 | -------------------------------------------------------------------------------- /src/openRandomTaggedNoteModal.ts: -------------------------------------------------------------------------------- 1 | import { App, Modal } from 'obsidian'; 2 | import OpenRandomTaggedNoteModalView from './OpenRandomTaggedNoteModalView.svelte'; 3 | 4 | export class OpenRandomTaggedNoteModal extends Modal { 5 | view: OpenRandomTaggedNoteModalView; 6 | tags: string[]; 7 | submitCallback: ((selectedTag: string) => Promise) | undefined = undefined; 8 | 9 | constructor(app: App, tags: string[]) { 10 | super(app); 11 | this.tags = tags; 12 | this.view = new OpenRandomTaggedNoteModalView({ 13 | target: this.contentEl, 14 | props: { tags, handleSubmit: this.handleSubmit }, 15 | }); 16 | } 17 | 18 | handleSubmit = (tag: string): void => { 19 | if (this.submitCallback) { 20 | this.submitCallback(tag); 21 | } 22 | this.close(); 23 | }; 24 | } 25 | -------------------------------------------------------------------------------- /src/settingTab.ts: -------------------------------------------------------------------------------- 1 | import SmartRandomNotePlugin from './main'; 2 | import { PluginSettingTab, Setting } from 'obsidian'; 3 | 4 | export class SmartRandomNoteSettingTab extends PluginSettingTab { 5 | plugin: SmartRandomNotePlugin; 6 | 7 | constructor(plugin: SmartRandomNotePlugin) { 8 | super(plugin.app, plugin); 9 | this.plugin = plugin; 10 | } 11 | 12 | display(): void { 13 | const { containerEl } = this; 14 | 15 | containerEl.empty(); 16 | 17 | containerEl.createEl('h2', { text: 'Smart Random Note Settings ' }); 18 | 19 | new Setting(containerEl) 20 | .setName('Open in New Leaf') 21 | .setDesc('Default setting for opening random notes') 22 | .addToggle((toggle) => { 23 | toggle.setValue(this.plugin.settings.openInNewLeaf); 24 | toggle.onChange(this.plugin.setOpenInNewLeaf); 25 | }); 26 | 27 | new Setting(containerEl) 28 | .setName('Enable Ribbon Icon') 29 | .setDesc('Place an icon on the ribbon to open a random note from search') 30 | .addToggle((toggle) => { 31 | toggle.setValue(this.plugin.settings.enableRibbonIcon); 32 | toggle.onChange(this.plugin.setEnableRibbonIcon); 33 | }); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/smartRandomNoteNotice.ts: -------------------------------------------------------------------------------- 1 | import { Notice } from 'obsidian'; 2 | 3 | export class SmartRandomNoteNotice extends Notice { 4 | constructor(message: string, timeout?: number) { 5 | super('Smart Random Note: ' + message, timeout); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/types.ts: -------------------------------------------------------------------------------- 1 | import { TFile, View } from 'obsidian'; 2 | 3 | export type TagFilesMap = { [tag: string]: TFile[] }; 4 | 5 | export interface SearchDOM { 6 | getFiles(): TFile[]; 7 | } 8 | 9 | export interface SearchView extends View { 10 | dom: SearchDOM; 11 | } 12 | 13 | export interface SmartRandomNoteSettings { 14 | openInNewLeaf: boolean; 15 | enableRibbonIcon: boolean; 16 | } 17 | -------------------------------------------------------------------------------- /src/utilities.ts: -------------------------------------------------------------------------------- 1 | import { App, CachedMetadata } from 'obsidian'; 2 | import { TagFilesMap } from './types'; 3 | 4 | export function getTagFilesMap(app: App): TagFilesMap { 5 | const metadataCache = app.metadataCache; 6 | const markdownFiles = app.vault.getMarkdownFiles(); 7 | 8 | const tagFilesMap: TagFilesMap = {}; 9 | 10 | for (const markdownFile of markdownFiles) { 11 | const cachedMetadata = metadataCache.getFileCache(markdownFile); 12 | 13 | if (cachedMetadata) { 14 | const cachedTags = getCachedTags(cachedMetadata); 15 | if (cachedTags.length) { 16 | for (const cachedTag of cachedTags) { 17 | if (tagFilesMap[cachedTag]) { 18 | tagFilesMap[cachedTag].push(markdownFile); 19 | } else { 20 | tagFilesMap[cachedTag] = [markdownFile]; 21 | } 22 | } 23 | } 24 | } 25 | } 26 | 27 | return tagFilesMap; 28 | } 29 | 30 | function getCachedTags(cachedMetadata: CachedMetadata): string[] { 31 | const bodyTags: string[] = cachedMetadata.tags?.map((x) => x.tag) || []; 32 | const frontMatterTags: string[] = cachedMetadata.frontmatter?.tags || []; 33 | 34 | // frontmatter tags might not have a hashtag in front of them 35 | const cachedTags = bodyTags.concat(frontMatterTags).map((x) => (x.startsWith('#') ? x : '#' + x)); 36 | 37 | return cachedTags; 38 | } 39 | 40 | export function randomElement(array: T[]): T { 41 | return array[(array.length * Math.random()) << 0]; 42 | } 43 | -------------------------------------------------------------------------------- /styles.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/erichalldev/obsidian-smart-random-note/e17078681af5659c0400c4924cf8424dfa6d3b2a/styles.css -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "types": ["node", "svelte"], 4 | "baseUrl": ".", 5 | "inlineSourceMap": true, 6 | "inlineSources": true, 7 | "module": "ESNext", 8 | "target": "es6", 9 | "allowJs": false, 10 | "strict": true, 11 | "noUnusedLocals": true, 12 | "noUnusedParameters": true, 13 | "noImplicitReturns": true, 14 | "noFallthroughCasesInSwitch": true, 15 | "moduleResolution": "node", 16 | "importHelpers": true, 17 | "lib": [ 18 | "dom", 19 | "es5", 20 | "scripthost", 21 | "es2015" 22 | ] 23 | }, 24 | "include": [ 25 | "**/*.ts" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /versions.json: -------------------------------------------------------------------------------- 1 | { 2 | "0.2.0": "0.9.18", 3 | "0.1.3": "0.9.18", 4 | "0.1.2": "0.9.16", 5 | "0.1.1": "0.9.7", 6 | "0.0.5": "0.9.7" 7 | } --------------------------------------------------------------------------------