extracted foam-core and created @foam modules

This commit is contained in:
Riccardo Ferretti
2020-07-11 16:59:33 +02:00
parent d7425f88e4
commit 639edafe52
32 changed files with 207 additions and 530 deletions

2
.gitignore vendored
View File

@@ -2,3 +2,5 @@ node_modules
.DS_Store
.vscode-test/
*.vsix
*.log
dist

2
.vscode/launch.json vendored
View File

@@ -42,7 +42,7 @@
"name": "Workspace Manager tests",
"program": "${workspaceFolder}/node_modules/tsdx/dist/index.js",
"args": ["test"],
"cwd": "${workspaceFolder}/packages/foam-workspace-manager",
"cwd": "${workspaceFolder}/packages/foam-core",
"internalConsoleOptions": "openOnSessionStart"
}
]

View File

@@ -14,5 +14,19 @@
},
"devDependencies": {
"all-contributors-cli": "^6.16.1"
},
"engines": {
"node": ">=10"
},
"husky": {
"hooks": {
"pre-commit": "tsdx lint"
}
},
"prettier": {
"printWidth": 80,
"semi": true,
"singleQuote": true,
"trailingComma": "es5"
}
}

View File

@@ -73,5 +73,5 @@ _See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v3.1.0
- Run `yarn` somewhere in workspace (ideally root, see [yarn workspace docs](https://classic.yarnpkg.com/en/docs/workspaces/)
- This will automatically symlink all package directories so you're using the local copy
- In `packages/foam-workspace-manager`, run `yarn start` to rebuild the library on every change
- In `packages/foam-core`, run `yarn start` to rebuild the library on every change
- In `packages/foam-cli`, make changes and run with `yarn run cli`. This should use latest workspace manager changes.

View File

@@ -1,5 +1,5 @@
{
"name": "foam-cli",
"name": "@foam/cli",
"description": "Foam CLI",
"version": "0.1.0",
"author": "Jani Eväkallio @jevakallio",
@@ -11,7 +11,6 @@
"@oclif/command": "^1",
"@oclif/config": "^1",
"@oclif/plugin-help": "^3",
"foam-workspace-manager": "^0.1.1",
"tslib": "^1"
},
"devDependencies": {
@@ -23,7 +22,11 @@
"eslint-config-oclif-typescript": "^0.1",
"globby": "^10",
"ts-node": "^8",
"typescript": "^3.3"
"typescript": "^3.3",
"@foam/core": "^0.1.1"
},
"peerDependencies": {
"@foam/core": "^0.1.1"
},
"engines": {
"node": ">=8.0.0"

View File

@@ -1,5 +1,5 @@
import {Command, flags} from '@oclif/command'
import { WorkspaceManager } from 'foam-workspace-manager';
import { NoteGraph } from '@foam/core';
export default class Hello extends Command {
static description = 'describe the command here'
@@ -23,7 +23,7 @@ hello world from ./src/hello.ts!
const {args, flags} = this.parse(Hello)
const name = flags.name ?? 'world'
const wm = new WorkspaceManager('./foo');
const wm = new NoteGraph();
wm.addNoteFromMarkdown('page-a.md', `
# Page A
## Section

View File

@@ -10,5 +10,6 @@
},
"include": [
"src/**/*"
]
],
"references": [{ "path": "../foam-core" }]
}

View File

@@ -1,6 +1,6 @@
# Foam Workspace Manager
# Foam Core
Repository for tooling user for managing Foam workspaces
Repository for tooling used by the other modules
## Local Development

View File

@@ -1,15 +1,12 @@
{
"name": "@foam/core",
"author": "Jani Eväkallio",
"repository": "https://github.com/foambubble/foam",
"version": "0.1.1",
"license": "MIT",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"files": [
"dist",
"src"
"dist"
],
"engines": {
"node": ">=10"
},
"scripts": {
"start": "tsdx watch",
"build": "tsdx build",
@@ -17,36 +14,22 @@
"lint": "tsdx lint",
"prepare": "tsdx build"
},
"peerDependencies": {},
"husky": {
"hooks": {
"pre-commit": "tsdx lint"
}
},
"prettier": {
"printWidth": 80,
"semi": true,
"singleQuote": true,
"trailingComma": "es5"
},
"name": "foam-workspace-manager",
"author": "Jani Eväkallio",
"repository": "https://github.com/foambubble/foam",
"module": "dist/foam-workspace-manager.esm.js",
"devDependencies": {
"@types/graphlib": "^2.1.6",
"@types/lodash": "^4.14.157",
"husky": "^4.2.5",
"tsdx": "^0.13.2",
"tslib": "^2.0.0",
"typescript": "^3.9.5"
},
"dependencies": {
"@types/graphlib": "^2.1.6",
"@types/lodash": "^4.14.157",
"graphlib": "^2.1.8",
"lodash": "^4.17.15",
"remark-parse": "^8.0.2",
"remark-wiki-link": "^0.0.4",
"unified": "^9.0.0",
"unist-util-visit": "^2.0.2"
}
},
"main": "dist/index.js",
"types": "dist/index.d.ts"
}

View File

@@ -0,0 +1,2 @@
export { NoteGraph, Note, NoteLink } from './core'
export { createNoteFromMarkdown, createMarkdownReferences } from './markdown-provider'

View File

@@ -4,14 +4,9 @@ import wikiLinkPlugin from 'remark-wiki-link';
import visit, { CONTINUE, EXIT } from 'unist-util-visit';
import { Node, Parent } from 'unist';
import * as path from 'path';
import { Link, Note, NoteGraph } from '../core';
import { Link, Note, NoteGraph } from './core';
import { dropExtension } from './utils';
// @ts-expect-error
export function readWorkspaceFile(filename: string): string {
throw new Error('Not implemented');
}
// pipeline cache
let processor: unified.Processor | null = null;
function parse(markdown: string): Node {
@@ -70,34 +65,3 @@ export function createMarkdownReferences(notes: NoteGraph, noteId: string): Mark
})
.sort()
}
function dropExtension(path: string): string {
const parts = path.split(".");
parts.pop();
return parts.join(".");
}
export function parseNoteTitleFromMarkdown(markdown: string): string | null {
let title: string | null = null;
const tree = parse(markdown);
visit(tree, node => {
if (node.type === 'heading' && node.depth === 1) {
title = ((node as Parent)!.children[0].value as string) || null;
}
return title === null;
});
return title;
}
export function parseNoteLinksFromMarkdown(markdown: string): string[] {
let links: string[] = [];
const tree = parse(markdown);
visit(tree, node => {
if (node.type === 'wikiLink') {
links.push(node.value as string);
}
});
return links;
}

View File

@@ -0,0 +1,5 @@
export function dropExtension(path: string): string {
const parts = path.split(".");
parts.pop();
return parts.join(".");
}

View File

@@ -1,5 +1,4 @@
import { NoteGraph, Note } from '../src/core'
import { createNoteFromMarkdown } from '../src/utils/utils'
describe('Note graph', () => {
it('Adds notes to graph', () => {
@@ -55,42 +54,3 @@ describe('Note graph', () => {
})
})
const pageA = `
# Page A
## Section
- [[page-b]]
- [[page-c]];
`;
const pageB = `
# Page B
This references [[page-a]]`;
const pageC = `
# Page C
`;
describe('Markdown loader', () => {
it('Converts markdown to notes', () => {
const graph = new NoteGraph()
graph.setNote(createNoteFromMarkdown('page-a', pageA))
graph.setNote(createNoteFromMarkdown('page-b', pageB))
graph.setNote(createNoteFromMarkdown('page-c', pageC))
expect(graph.getNotes().map(n => n.id).sort()).toEqual(['page-a', 'page-b', 'page-c'])
})
it('Parses wikilinks correctly', () => {
const graph = new NoteGraph()
graph.setNote(createNoteFromMarkdown('page-a', pageA))
graph.setNote(createNoteFromMarkdown('page-b', pageB))
graph.setNote(createNoteFromMarkdown('page-c', pageC))
expect(graph.getBacklinks('page-b').map(link => link.from)).toEqual(['page-a'])
expect(graph.getForwardLinks('page-a').map(link => link.to)).toEqual(['page-b', 'page-c'])
})
})

View File

@@ -0,0 +1,40 @@
import { createNoteFromMarkdown } from "../src/markdown-provider";
import { NoteGraph } from "../src/core";
const pageA = `
# Page A
## Section
- [[page-b]]
- [[page-c]];
`;
const pageB = `
# Page B
This references [[page-a]]`;
const pageC = `
# Page C
`;
describe('Markdown loader', () => {
it('Converts markdown to notes', () => {
const graph = new NoteGraph()
graph.setNote(createNoteFromMarkdown('page-a', pageA))
graph.setNote(createNoteFromMarkdown('page-b', pageB))
graph.setNote(createNoteFromMarkdown('page-c', pageC))
expect(graph.getNotes().map(n => n.id).sort()).toEqual(['page-a', 'page-b', 'page-c'])
})
it('Parses wikilinks correctly', () => {
const graph = new NoteGraph()
graph.setNote(createNoteFromMarkdown('page-a', pageA))
graph.setNote(createNoteFromMarkdown('page-b', pageB))
graph.setNote(createNoteFromMarkdown('page-c', pageC))
expect(graph.getBacklinks('page-b').map(link => link.from)).toEqual(['page-a'])
expect(graph.getForwardLinks('page-a').map(link => link.to)).toEqual(['page-b', 'page-c'])
})
})

View File

@@ -1,23 +1,30 @@
{
"extends": "../../tsconfig.base.json",
"include": ["src", "types"],
"compilerOptions": {
"module": "esnext",
"lib": ["dom", "esnext"],
"importHelpers": true,
"composite": true,
"declaration": true,
"sourceMap": true,
"declarationMap": true,
// to override config from tsconfig.base.json
"outDir": "dist",
"rootDir": "./src",
// for references
"baseUrl": "src",
"lib": ["esnext"],
"module": "esnext",
"importHelpers": true,
"sourceMap": true,
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"moduleResolution": "node",
"baseUrl": "./",
"paths": {
"*": ["src/*", "node_modules/*"]
},
"jsx": "react",
"esModuleInterop": true
}
// "paths": {
// "*": ["src/*", "node_modules/*"]
// },
// "jsx": "react",
},
}

View File

@@ -1,4 +1,3 @@
out
node_modules
.vscode-test/
*.vsix

View File

@@ -49,6 +49,6 @@
"vscode-test": "^1.3.0"
},
"dependencies": {
"foam-workspace-manager": "^0.1.1"
"@foam/core": "^0.1.1"
}
}

View File

@@ -22,7 +22,7 @@ import {
Position,
} from "vscode";
import { createMarkdownReferences } from 'foam-workspace-manager'
import { createMarkdownReferences } from '@foam/core'
import { basename, dirname, relative } from "path";
import * as ws from "./workspace";

View File

@@ -0,0 +1,78 @@
import {
CancellationToken,
CodeLens,
CodeLensProvider,
commands,
EndOfLine,
ExtensionContext,
languages,
Range,
TextEditor,
TextDocument,
TextDocumentWillSaveEvent,
window,
workspace,
Position,
} from "vscode";
export const docConfig = { tab: " ", eol: "\r\n" };
export const mdDocSelector = [
{ language: "markdown", scheme: "file" },
{ language: "markdown", scheme: "untitled" },
];
export function loadDocConfig() {
// Load workspace config
let activeEditor = window.activeTextEditor;
if (!activeEditor) {
console.log("Failed to load config, no active editor");
return;
}
docConfig.eol = activeEditor.document.eol === EndOfLine.CRLF ? "\r\n" : "\n";
let tabSize = Number(activeEditor.options.tabSize);
let insertSpaces = activeEditor.options.insertSpaces;
if (insertSpaces) {
docConfig.tab = " ".repeat(tabSize);
} else {
docConfig.tab = "\t";
}
}
export function detectGeneratedCode(fullText: string, header: string, footer: string): {range: Range | null, lines: string[]} {
const lines = fullText.split(docConfig.eol)
const headerLine = lines.findIndex(line => line === header)
const footerLine = lines.findIndex(line => line === footer)
if (headerLine < 0 || headerLine >= footerLine) {
return {
range: null,
lines: [],
};
}
return {
range: new Range(
new Position(headerLine, 0),
new Position(footerLine, lines[footerLine].length + 1)
),
lines: lines.slice(headerLine + 1, footerLine + 1),
}
}
export function hasEmptyTrailing(doc: TextDocument): boolean {
return doc.lineAt(doc.lineCount - 1).isEmptyOrWhitespace;
}
export function getText(range: Range): string {
return window.activeTextEditor.document.getText(range);
}
export function dropExtension(path: string): string {
const parts = path.split(".");
parts.pop();
return parts.join(".");
}

View File

@@ -1,10 +1,9 @@
import * as fs from "fs";
import { basename } from "path";
import { workspace } from "vscode";
import { WorkspaceManager, NoteGraph, createNoteFromMarkdown } from "foam-workspace-manager";
import { NoteGraph, createNoteFromMarkdown } from "@foam/core";
// build initial index
export const manager = new WorkspaceManager(workspace.rootPath);
export const ready = (async () => {
const files = await workspace.findFiles("**/*");
const foam = new NoteGraph()
@@ -15,8 +14,7 @@ export const ready = (async () => {
)
.map((f) => {
return fs.promises.readFile(f.fsPath).then((data) => {
let markdown = (data || "").toString();
manager.addNoteFromMarkdown(f.fsPath, markdown);
const markdown = (data || "").toString();
foam.setNote(createNoteFromMarkdown(f.fsPath, markdown))
});
})

View File

@@ -1,6 +1,8 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"module": "commonjs",
"moduleResolution": "node",
"target": "es6",
"outDir": "out",
"lib": ["es6"],
@@ -12,5 +14,9 @@
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
// "noUnusedParameters": true, /* Report errors on unused parameters. */
},
"exclude": ["node_modules", ".vscode-test"]
"include": ["src"],
"exclude": ["node_modules", ".vscode-test"],
"references": [{
"path": "../foam-core/tsconfig.json"
}]
}

View File

@@ -1,42 +0,0 @@
name: CI
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Begin CI...
uses: actions/checkout@v2
- name: Use Node 12
uses: actions/setup-node@v1
with:
node-version: 12.x
- name: Use cached node_modules
uses: actions/cache@v1
with:
path: node_modules
key: nodeModules-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
nodeModules-
- name: Install dependencies
run: yarn install --frozen-lockfile
env:
CI: true
- name: Lint
run: yarn lint
env:
CI: true
- name: Test
run: yarn test --ci --coverage --maxWorkers=2
env:
CI: true
- name: Build
run: yarn build
env:
CI: true

View File

@@ -1,4 +0,0 @@
*.log
.DS_Store
node_modules
dist

View File

@@ -1,21 +0,0 @@
MIT License
Copyright (c) 2020 Jani Eväkallio
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.

View File

@@ -1,179 +0,0 @@
// for readability
import { basename } from 'path';
import {
readWorkspaceFile,
parseNoteTitleFromMarkdown,
parseNoteLinksFromMarkdown,
} from './utils/utils';
type ID = string;
type Index = Map<ID, Set<ID>>;
export interface Note {
/**
* Base name of the file without extension, e.g. wiki-link
*/
id: ID;
title: string;
filename: string;
extension: string;
absolutePath: string;
markdown: string; // do we need this?
}
export interface NoteWithLinks extends Note {
/**
* Notes referenced from this note (wikilinks)
*/
linkedNotes: Note[];
/**
* Notes that reference this note (backlinks) */
backlinks: Note[];
}
function getOrInitializeIndexForId(index: Index, id: ID): Set<ID> {
let links: Set<ID>;
if (index.has(id)) {
links = index.get(id)!;
} else {
index.set(id, (links = new Set<ID>()));
}
return links;
}
export class WorkspaceManager {
/**
* Workspace base path
*/
path: string;
/**
* Note metadata for files in this workspace, keyed by id
*/
notes: Map<ID, Note> = new Map();
/**
* Link index A->B
*/
linksFromNoteById: Index = new Map();
/**
* Reverse backlinks B->A
*/
linksBackToNoteById: Index = new Map();
constructor(path: string, notes: Note[] = []) {
this.path = path;
this.notes = new Map<ID, Note>(notes.map(note => [note.id, note]));
}
public getNoteWithLinks(id: ID): NoteWithLinks | null {
const note = this.notes.get(id);
if (!note) {
return null;
}
const linkedNotes = Array.from(
getOrInitializeIndexForId(this.linksFromNoteById, id)
)
.map(id => this.notes.get(id))
.filter(Boolean) as Note[];
const backlinks = Array.from(
getOrInitializeIndexForId(this.linksBackToNoteById, id)
)
.map(id => this.notes.get(id))
.filter(Boolean) as Note[];
return {
...note,
linkedNotes,
backlinks,
};
}
/**
*
* @param filename File name relative to workspace path
*/
public async addNoteByFilePath(filePath: string): Promise<Note> {
return await this.addNoteFromMarkdown(
this.path,
await readWorkspaceFile(filePath)
);
}
public addNoteFromMarkdown(absolutePath: string, markdown: string): Note {
// parse markdown
const filename = basename(absolutePath);
const parts = filename.split('.');
const extension = parts.pop()!;
const id = parts.join('.');
const title = parseNoteTitleFromMarkdown(markdown);
const note: Note = {
id,
title: title || id,
filename,
absolutePath,
extension,
markdown,
};
// extract linksTo
return this.addNote(note);
}
public addNote(note: Note): Note {
const linkIds = parseNoteLinksFromMarkdown(note.markdown);
this.notes.set(note.id, note);
if (linkIds.length > 0) {
let linksFromNote = getOrInitializeIndexForId(
this.linksFromNoteById,
note.id
);
for (const id of linkIds) {
linksFromNote.add(id);
getOrInitializeIndexForId(this.linksBackToNoteById, id).add(note.id);
}
}
return note;
}
/*
// Clearly I'm too tired to do this right now
public removeNote(a: ID): Note | null {
let note = this.notes.get(a);
if (!note) {
return null;
}
// find references from this note to others
let linksFromNote = getOrInitializeIndexForId(this.linksFromNoteById, a);
// remove the index
this.linksFromNoteById.delete(a);
// find all notes that reference the note we are deleting
for (const b in linksFromNote) {
const backlinks = getOrInitializeIndexForId(this.linksBackToNoteById, b);
if (backlinks.has(a)) {
// @todo, trigger event?
backlinks.delete(a);
}
}
return note;
}
// @ts-expect-error
public renameNote(note: Note, newFilename: string) {
throw new Error('Not implemented');
}
*/
}

View File

@@ -1,3 +0,0 @@
export { WorkspaceManager, Note, NoteWithLinks } from './WorkspaceManager';
export { NoteGraph, Note as FNote, Link } from './core'
export { createNoteFromMarkdown, createMarkdownReferences } from './utils/utils'

View File

@@ -1,95 +0,0 @@
import { WorkspaceManager } from '../src/WorkspaceManager';
const pageA = `
# Page A
## Section
- [[page-b]]
- [[page-c]];
`;
const pageB = `
# Page B
This references [[page-a]]`;
const pageC = `
# Page C
`;
const updatedPageC = `
# Page C
[[page-a]]
[[page-b]]
`;
describe.skip('WorkspaceManager', () => {
it('links things correctly when added in order', () => {
const ws = new WorkspaceManager('dir/');
ws.addNoteFromMarkdown('page-a.md', pageA);
ws.addNoteFromMarkdown('page-b.md', pageB);
ws.addNoteFromMarkdown('page-c.md', pageC);
const note = ws.getNoteWithLinks('page-a');
expect(note).not.toBeNull();
expect(note!.linkedNotes.map(n => n.id)).toEqual(['page-b', 'page-c']);
expect(note!.backlinks.map(n => n.id)).toEqual(['page-b']);
});
it('links things correctly when added out of order', () => {
const ws = new WorkspaceManager('dir/');
ws.addNoteFromMarkdown('page-b.md', pageB);
ws.addNoteFromMarkdown('page-a.md', pageA);
ws.addNoteFromMarkdown('page-c.md', pageC);
const note = ws.getNoteWithLinks('page-a');
expect(note).not.toBeNull();
expect(note!.linkedNotes.map(n => n.id)).toEqual(['page-b', 'page-c']);
expect(note!.backlinks.map(n => n.id)).toEqual(['page-b']);
});
it('updates links when adding a changed document', () => {
const ws = new WorkspaceManager('dir/');
ws.addNoteFromMarkdown('page-b.md', pageB);
ws.addNoteFromMarkdown('page-a.md', pageA);
ws.addNoteFromMarkdown('page-c.md', pageC);
const before = ws.getNoteWithLinks('page-a');
// change document
ws.addNoteFromMarkdown('page-c.md', updatedPageC);
const after = ws.getNoteWithLinks('page-a');
expect(before).not.toEqual(after);
expect(before!.linkedNotes.map(n => n.id)).toEqual(['page-b', 'page-c']);
expect(before!.backlinks.map(n => n.id)).toEqual(['page-b']);
expect(after!.linkedNotes.map(n => n.id)).toEqual(['page-b', 'page-c']);
expect(after!.backlinks.map(n => n.id)).toEqual(['page-b', 'page-c']);
});
/*
it('updates links correctly when page is removed', () => {
const ws = new WorkspaceManager('dir/');
ws.addNoteFromMarkdown('page-a.md', pageA);
ws.addNoteFromMarkdown('page-b.md', pageB);
ws.addNoteFromMarkdown('page-c.md', pageC);
ws.removeNote('page-c');
const note = ws.getNoteWithLinks('page-a');
console.log(note);
expect(note).not.toBeNull();
expect(note!.linkedNotes.map(n => n.id)).toEqual(['page-b']);
expect(note!.backlinks.map(n => n.id)).toEqual(['page-b']);
});
*/
});

View File

@@ -1,54 +0,0 @@
import {
parseNoteTitleFromMarkdown,
parseNoteLinksFromMarkdown,
} from '../../src/utils/utils';
const pageA = `
# Page A
## Section
- [[page-b]]
- [[page-c]]
`;
const pageB = `
# Page B
`;
const pageC = `
foo
bar
`;
const pageD = `
# Page D
hello world
# Another header
hello world
`;
describe('WorkspaceManager', () => {
it('finds top level headings', () => {
const titleA = parseNoteTitleFromMarkdown(pageA);
const titleB = parseNoteTitleFromMarkdown(pageB);
const titleC = parseNoteTitleFromMarkdown(pageC);
const titleD = parseNoteTitleFromMarkdown(pageD);
expect(titleA).toEqual('Page A');
expect(titleB).toEqual('Page B');
expect(titleC).toBeNull();
// in case of multiple top level headings, the first one rules
expect(titleD).toEqual('Page D');
});
it('finds wikilinks', () => {
const linksA = parseNoteLinksFromMarkdown(pageA);
const linksB = parseNoteLinksFromMarkdown(pageB);
const linksC = parseNoteLinksFromMarkdown(pageC);
expect(linksA).toEqual(['page-b', 'page-c']);
expect(linksB).toEqual([]);
expect(linksC).toEqual([]);
});
});

13
tsconfig.base.json Normal file
View File

@@ -0,0 +1,13 @@
{
"include": ["./packages/*/src"],
"compilerOptions": {
"declaration": true,
"declarationMap": true,
"baseUrl": ".",
"paths": {
"@foam/core": ["./packages/foam-core/src"],
"@foam/cli": ["./packages/foam-cli/src"],
"foam-vscode": ["./packages/foam-vscode/src"]
}
}
}