Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: CI

on:
push:
branches: [ main, master ]
pull_request:
branches: [ main, master ]

jobs:
test:
runs-on: ${{ matrix.os }}

strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
node-version: [16.x, 18.x, 20.x, 22.x, 24.x]

steps:
- uses: actions/checkout@v4

- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v6
with:
node-version: ${{ matrix.node-version }}

- name: Install dependencies
run: npm install

- name: Run tests
run: npm test
13 changes: 7 additions & 6 deletions bin/darko-serve
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
'use strict'

const program = require('commander')
const mime = require('mime-types')

program
.option('-s --source [source]', 'Source directory (default to ./)', './')
Expand Down Expand Up @@ -77,12 +78,7 @@ function handle(req, res) {

function sendFile(fpath) {
debug('Sending ' + fpath)
const mime = {
'.css': 'text/css',
'.html': 'text/html',
'.js': 'application/javascript'
}
const contentType = mime[path.extname(fpath).toLowerCase()]
const contentType = mime.contentType(path.extname(fpath).toLowerCase())

if (contentType) {
res.setHeader('Content-Type', contentType)
Expand Down Expand Up @@ -115,6 +111,11 @@ function handle(req, res) {
return
}

if (!(fpath.startsWith(site.dest) || fpath.startsWith(droot))) {
send404()
return
}

const stats = fs.statSync(fpath)

if (stats.isFile()) {
Expand Down
4 changes: 2 additions & 2 deletions lib/parsers/page.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ function Page(attrs) {
this.ext = path.extname(fpath)

this.slug = path.basename(fpath, this.ext)
this.path = path.relative(this.site.cwd, fpath)
this.path = path.relative(this.site.cwd, fpath).replaceAll(path.sep, '/')
this.title = util.capitalize(this.slug)

if (this.validFormat && fs.existsSync(fpath)) {
Expand All @@ -33,7 +33,7 @@ function Page(attrs) {
}
}

this.url = path.resolve('/', this.path).replace(/\/index\.(?:md|html)$/, '')
this.url = `/${this.path}`.replace(/\/index\.(?:md|html)$/, '')

this.dest = path.join(this.site.dest, this.site.baseurl.slice(1),
this.path.replace(/\.\w+$/, this.ext == '.md' ? '.html' : this.ext))
Expand Down
1 change: 0 additions & 1 deletion lib/writers/templated.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ const path = require('path')
const yaml = require('yaml-js')
const mkdirp = require('mkdirp')
const debug = require('debug')('darko')
const util = require('util')
const fs = require('fs')

const md = require('../markdown')
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"highlight.js": "^11.11.1",
"liquid-node": "^3.0.0",
"markit": "~0.1.0",
"mime-types": "^3.0.1",
"mkdirp": "~0.3.5",
"rimraf": "^2.6.2",
"strftime": "~0.9.0",
Expand Down
1 change: 1 addition & 0 deletions test/fixture/assets/darko.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions test/fixture/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ layout: post
title: Welcome!
---

<img src="/assets/darko.svg">

Good luck, have fun!

<ul>
Expand Down
103 changes: 0 additions & 103 deletions test/liquid.js

This file was deleted.

89 changes: 89 additions & 0 deletions test/liquid.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
'use strict'

var expect = require('expect.js')
var engine = require('..').Liquid


function liquid(tpl, data) {
return engine.parseAndRender(tpl, data)
}

describe('Liquid', function() {
const timezoneOffset = new Date().getTimezoneOffset();
const timezone = [
timezoneOffset > 0 ? '-' : '+',
String(Math.abs(Math.floor(timezoneOffset / 60))).padStart(2, '0'),
':',
String(Math.abs(timezoneOffset % 60)).padStart(2, '0')
].join('');

it('has filter date_to_xmlschema', async function() {
const result = await liquid('{{ date | date_to_xmlschema }}', {
date: new Date(2014, 0, 12)
});
expect(result).to.equal(`2014-01-12T00:00:00${timezone}`);
});

it('has filter date_to_rfc822', async function() {
const result = await liquid('{{ date | date_to_rfc822 }}', {
date: new Date(2014, 0, 12)
});
expect(result).to.equal(`Sun, 12 Jan 2014 00:00:00 ${timezone.replace(':', '')}`);
});

it('has filter date_to_string', async function() {
const result = await liquid('{{ date | date_to_string }}', {
date: new Date(2014, 0, 12)
});
expect(result).to.equal('12 Jan 2014');
});

it('has filter date_to_long_string', async function() {
const result = await liquid('{{ date | date_to_long_string }}', {
date: new Date(2014, 0, 12)
});
expect(result).to.equal('12 January 2014')
})

it('has filter array_to_sentence_string', async function() {
const result = await liquid('{{ tags | array_to_sentence_string }}', {
tags: [ 'life', 'rails', 'conf' ]
})
expect(result).to.equal('life, rails, and conf');
})

it('has filter markdownify', async function() {
const result = await liquid('{{ excerpt | markdownify }}', {
excerpt: '## Excerpt'
});
expect(result).to.contain('<h2 id="excerpt">Excerpt</h2>');
});

it('has filter jsonify', async function() {
const result = await liquid('{{ data | jsonify }}', {
data: { foo: 'bar' }
});
expect(result).to.equal('{"foo":"bar"}');
});

it('has filter xml_escape', async function() {
const result = await liquid('{{ data | xml_escape }}', {
data: 'How to go home? Taxi -> Train -> Taxi'
});
expect(result).to.equal('How to go home? Taxi -&gt; Train -&gt; Taxi');
});

it('has filter cgi_escape', async function() {
const result = await liquid('{{ data | cgi_escape }}', {
data: 'http://google.com/foo?bar=at#anchor&title=My Blog & Your Blog'
});
expect(result).to.equal('http%3A%2F%2Fgoogle.com%2Ffoo%3Fbar%3Dat%23anchor%26title%3DMy+Blog+%26+Your+Blog');
});

it('has filter uri_escape', async function() {
const result = await liquid('{{ data | uri_escape }}', {
data: 'http://google.com/foo?bar=at#anchor&title=My Blog & Your Blog'
});
expect(result).to.equal('http://google.com/foo?bar=at%23anchor&title=My%20Blog%20&%20Your%20Blog');
});
});
4 changes: 2 additions & 2 deletions test/site.js → test/site.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ var site = new Site({
describe('basic attributes of Site', function() {

it('should set cwd and dest', function() {
expect(site.cwd).to.contain('test/fixture')
expect(site.dest).to.contain('test/fixture/_site')
expect(site.cwd.replaceAll(path.sep, '/')).to.contain('test/fixture')
expect(site.dest.replaceAll(path.sep, '/')).to.contain('test/fixture/_site')
})

it('should parse _config.yml', function() {
Expand Down