diff --git a/src/index.ts b/src/index.ts index c08e7b2..8ee1d7c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -2,29 +2,27 @@ import { Command } from 'commander' import chalk from 'chalk' //import fs from 'fs-extra' import path from 'path' -import { newProject, buildProject, appProject } from './project.js' +import Project from './project.js' import { serve } from './serve.js' const program = new Command() +let project = new Project() + program .command('init') .description('Initialize project in the current directory with the default theme') - .action(newProject) + .action(()=> { project.new() }) program .command('build') .description('Build the webpage') - .action(buildProject) + .action(()=> { project.build() }) program .command('serve') .description('Run the website locally') .action(serve) -program - .command('app') - .description('Run notes as the the app') - .action(appProject) program.parse(process.argv) \ No newline at end of file diff --git a/src/project-config.ts b/src/project-config.ts new file mode 100644 index 0000000..2a16661 --- /dev/null +++ b/src/project-config.ts @@ -0,0 +1,29 @@ +import fs from 'fs' +import path from 'path' +import yaml from 'js-yaml' + +export default class ProjectConfig { + public config: any = {} + + constructor() { + + } + + public load() { + this.config = { + ... this.read(), + buildDir: './.build', + ignore: [".build", ".sajt"] + } + + this.config.remote.port = 22 + this.config.remote.privateKey = fs.readFileSync(path.resolve(process.env.HOME ?? "", '.ssh/id_rsa')) + } + + read(): any { + const __dirname = process.cwd() + const configPath = path.join(__dirname, '.sajt/config.yaml') + const fileContents = fs.readFileSync(configPath, 'utf8') + return yaml.load(fileContents) + } +} \ No newline at end of file diff --git a/src/project.ts b/src/project.ts index cbd92aa..a2b90fc 100644 --- a/src/project.ts +++ b/src/project.ts @@ -1,72 +1,41 @@ import { fileURLToPath } from 'url' import path from 'path' -import fs from 'fs' import { cp } from './utils.js' - -// Get the directory of the current file -const __filename = fileURLToPath(import.meta.url) -const __dirname = path.dirname(__filename) - -// Path relative to the script file's directory -const DEFAULT_PROJECT_PATH = path.join(__dirname, 'empty') - -export function newProject() { - console.log("Initialize a new project") - console.log(DEFAULT_PROJECT_PATH) - cp(DEFAULT_PROJECT_PATH, ".") -} - -import { readConfig } from './site.js' import { build } from './site.js' +import ProjectConfig from './project-config.js' + + +export default class Project { + public config = new ProjectConfig() // should be injected + private __filename: string + private __dirname: string + private DEFAULT_PROJECT_PATH: string + + constructor() { + // Get the directory of the current file + this.__filename = fileURLToPath(import.meta.url) + this.__dirname = path.dirname(this.__filename) + + // Path relative to the script file's directory + this.DEFAULT_PROJECT_PATH = path.join(this.__dirname, '..', 'empty') -export function buildProject() { - console.log("building") - - let config = { - ... readConfig(), - buildDir: './.build', - ignore: [".build", ".sajt"] } - config.remote.port = 22 - config.remote.privateKey = fs.readFileSync(path.resolve(process.env.HOME ?? "", '.ssh/id_rsa')) + new() { + console.log("Initialize a new project") + console.log(this.DEFAULT_PROJECT_PATH) + cp(this.DEFAULT_PROJECT_PATH, ".") + console.log(this.config) + this.config.load() + } - build(config) + existing() { + this.config.load() + } - //loadTemplate() - //parseMD() - //buildProject(config) -} - -//import { run } from './src/desktop/main.js' -import * as proc from 'child_process' - -//import { app, BrowserWindow } from 'electron' - -import * as electron from 'electron' - -export function appProject() { - //run() - - //const child = proc.spawn(electron, ["."]) - // console.log(electron) - // console.log(electron.default) - -// const child = proc.spawn(electron.default, [".build"]) - - // https://www.matthewslipper.com/2019/09/22/everything-you-wanted-electron-child-process.html - // exec('node start', (error, stdout, stderr) => { - // if (error) { - // console.error(`error: ${error.message}`) - // return; - // } - - // if (stderr) { - // console.error(`stderr: ${stderr}`); - // return - // } - - // console.log(`stdout:\n${stdout}`) - // }) + build() { + this.config.load() + build(this.config.config) + } } \ No newline at end of file diff --git a/src/serve.ts b/src/serve.ts index 1406487..3b36d49 100644 --- a/src/serve.ts +++ b/src/serve.ts @@ -1,5 +1,6 @@ import express from 'express' import { setWatcher } from './watch.js' +import { webdavMiddleware } from "./webdav.js" const app = express() const PORT = process.env.PORT || 3000 @@ -7,6 +8,8 @@ const PORT = process.env.PORT || 3000 export function serve() { app.use(express.static('./.build')) + app.use(webdavMiddleware) + setWatcher(url => { console.log(url) }) diff --git a/src/site.ts b/src/site.ts index fd19853..d41651e 100755 --- a/src/site.ts +++ b/src/site.ts @@ -1,7 +1,6 @@ import fs from 'fs' import pug from 'pug' import path from 'path' -import yaml from 'js-yaml' import { cp } from "./utils.js" import { parseMarkdown } from './markdown.js' @@ -17,17 +16,10 @@ function removeDirectorySync(directory: string) { } } -export function readConfig(): any { - const __dirname = process.cwd() - const configPath = path.join(__dirname, '.sajt/config.yaml') - const fileContents = fs.readFileSync(configPath, 'utf8') - return yaml.load(fileContents) -} - function compile(template: string, content: any, output: string) { if (template == null) { - console.error("Template is not defined") - return + console.error("Template is not defined, loading the default") + template = "default" } const compiledFunction = pug.compileFile(`.sajt/layouts/${template}.pug`); const data = { @@ -53,14 +45,11 @@ function compileData(template: string, content: object, output: string) { fs.mkdirSync(dirname, { recursive: true }) } - const html = compiledFunction(content) fs.writeFileSync(output, html) console.log(`HTML has been rendered and saved to ${output}`); } - - function readMetadata(ignore: string[]) { let htmlExtension = "html" @@ -71,7 +60,6 @@ function readMetadata(ignore: string[]) { data: {} as any, md: parseMD(f) } as any }) - // sites needs to include data from header let listYML = getAllFilesWithExtension('.',".yml", ignore) .map(f => { return { @@ -84,9 +72,6 @@ function readMetadata(ignore: string[]) { let list = listMD.concat(listYML) for(const site of list) { - - //console.log(site.md.meta.path) - // TODO: data can set default path if (site.md.meta?.path != null && site.md.meta?.path != undefined) { site.path = path.join("/", site.md.meta.path) } else { @@ -106,17 +91,13 @@ function readMetadata(ignore: string[]) { site.fileName = dirArray.pop() dirArray.shift() site.dir = dirArray - site.meta = site.md.meta - site.hidden = site.data?.hidden || false } return list } - - export function build(config: any) { removeDirectorySync(config.buildDir) cp("./.sajt/static", path.join(config.buildDir, "static")) @@ -148,10 +129,4 @@ export function build(config: any) { path.join(config.buildDir, site.path)) } } - - //console.log(readMetadata()) - // sajt - - // Not to upload now - //uploadDirectory(serverConfig, buildFolder) } \ No newline at end of file diff --git a/src/webdav.ts b/src/webdav.ts new file mode 100644 index 0000000..17623f5 --- /dev/null +++ b/src/webdav.ts @@ -0,0 +1,29 @@ +import { v2 as webdav } from 'webdav-server'; + +// 1. Create a user manager and add a user +const userManager = new webdav.SimpleUserManager() +const user = userManager.addUser('user', 'password', false) + +// 2. Create a privilege manager +const privilegeManager = new webdav.SimplePathPrivilegeManager() + +// 3. Configure the WebDAV server +const server = new webdav.WebDAVServer({ + // HTTP Digest authentication for better security + httpAuthentication: new webdav.HTTPDigestAuthentication(userManager, 'default-realm'), + privilegeManager +}) + +// 4. Set up a physical file system folder (e.g., `./data`) as the root +const publicFileSystem = new webdav.PhysicalFileSystem('./') + +server.setFileSystem('/', publicFileSystem, (success) => { + if (!success) { + console.error('Failed to set file system') + process.exit(1) + } + // Give the user all permissions on the root + privilegeManager.setRights(user, '/', ['all']) +}); + +export const webdavMiddleware = webdav.extensions.express("/", server) diff --git a/types/config.d.ts b/types/config.d.ts new file mode 100644 index 0000000..f928a45 --- /dev/null +++ b/types/config.d.ts @@ -0,0 +1,7 @@ +export default class ProjectConfig { + config: any; + constructor(); + load(): void; + getConfig(): any; + read(): any; +} diff --git a/types/project-config.d.ts b/types/project-config.d.ts new file mode 100644 index 0000000..9620741 --- /dev/null +++ b/types/project-config.d.ts @@ -0,0 +1,6 @@ +export default class ProjectConfig { + config: any; + constructor(); + load(): void; + read(): any; +} diff --git a/types/project.d.ts b/types/project.d.ts index f0997b0..0652de8 100644 --- a/types/project.d.ts +++ b/types/project.d.ts @@ -1,3 +1,11 @@ -export declare function newProject(): void; -export declare function buildProject(): void; -export declare function appProject(): void; +import ProjectConfig from './project-config.js'; +export default class Project { + config: ProjectConfig; + private __filename; + private __dirname; + private DEFAULT_PROJECT_PATH; + constructor(); + new(): void; + existing(): void; + build(): void; +} diff --git a/types/site.d.ts b/types/site.d.ts index 4b82d49..73a7635 100644 --- a/types/site.d.ts +++ b/types/site.d.ts @@ -1,2 +1 @@ -export declare function readConfig(): any; export declare function build(config: any): void; diff --git a/types/webdav.d.ts b/types/webdav.d.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/types/webdav.d.ts @@ -0,0 +1 @@ +export {};