mirror of
https://github.com/cupcakearmy/cometa.git
synced 2025-03-12 14:27:28 +00:00
Bug fixes
This commit is contained in:
parent
c16cc2f522
commit
d90f695c9e
@ -1,10 +1,10 @@
|
||||
import { compileBlock } from './compiler'
|
||||
import { ActionFunction, re, error, options, Part } from './options'
|
||||
import { ActionFunction, error, Part } from './options'
|
||||
import { getFromObject, readFileSync } from './util'
|
||||
import { join } from 'path'
|
||||
import { computeParts } from './parser'
|
||||
|
||||
export const comment: ActionFunction = html => {
|
||||
export const comment: ActionFunction = (html, options, re) => {
|
||||
|
||||
const tag = re.comment + re.ending
|
||||
const end = html.indexOf(tag)
|
||||
@ -17,7 +17,7 @@ export const comment: ActionFunction = html => {
|
||||
}
|
||||
}
|
||||
|
||||
export const logic: ActionFunction = html => {
|
||||
export const logic: ActionFunction = (html, options, re) => {
|
||||
|
||||
const rexp = {
|
||||
start: new RegExp(`${re.begin}\\${re.if} *\\${re.if_else}?${re.valid_variable} *${re.ending}`, 'g'),
|
||||
@ -68,31 +68,31 @@ export const logic: ActionFunction = html => {
|
||||
if (current.inverted) isTrue = !isTrue
|
||||
|
||||
if (isTrue)
|
||||
return compileBlock(body.if).parts
|
||||
return compileBlock(body.if, options, re).parts
|
||||
else
|
||||
return compileBlock(body.else).parts
|
||||
return compileBlock(body.else, options, re).parts
|
||||
}],
|
||||
length: next.end.index + next.end[0].length
|
||||
}
|
||||
}
|
||||
|
||||
export const importer: ActionFunction = html => {
|
||||
export const importer: ActionFunction = (html, options, re) => {
|
||||
|
||||
const end = html.indexOf(re.ending)
|
||||
|
||||
if (end === -1) throw new Error(error.parse.include_not_closed)
|
||||
|
||||
const template_name: string = html.substring(re.begin.length + re.incude.length, end).trim()
|
||||
const file_name: string = join(options.template_dir, `${template_name}.${options.template_ext}`)
|
||||
const file_name: string = join(options.views, `${template_name}.${options.extension}`)
|
||||
const file: Part = readFileSync(file_name)
|
||||
|
||||
return {
|
||||
parts: compileBlock(file).parts,
|
||||
parts: compileBlock(file, options, re).parts,
|
||||
length: end + re.ending.length
|
||||
}
|
||||
}
|
||||
|
||||
export const variables: ActionFunction = html => {
|
||||
export const variables: ActionFunction = (html, options, re) => {
|
||||
|
||||
const end = html.indexOf(re.ending)
|
||||
|
||||
@ -114,7 +114,7 @@ export const variables: ActionFunction = html => {
|
||||
}
|
||||
}
|
||||
|
||||
export const loop: ActionFunction = html => {
|
||||
export const loop: ActionFunction = (html, options, re) => {
|
||||
|
||||
const rexp = {
|
||||
start: new RegExp(`${re.begin}\\${re.for} *${re.valid_variable} *${re.for_in} *${re.valid_variable} *${re.ending}`, 'g'),
|
||||
@ -156,7 +156,7 @@ export const loop: ActionFunction = html => {
|
||||
let ret = ''
|
||||
for (const variable of getFromObject(data, current.arr)) {
|
||||
const newData = Object.assign({ [current.variable]: variable }, data)
|
||||
ret += computeParts(compileBlock(html).parts, newData)
|
||||
ret += computeParts(compileBlock(html, options, re).parts, newData)
|
||||
}
|
||||
return ret
|
||||
}],
|
||||
|
55
src/blitz.ts
55
src/blitz.ts
@ -1,55 +0,0 @@
|
||||
import * as path from 'path'
|
||||
import * as util from './util'
|
||||
import * as parser from './parser'
|
||||
import * as compiler from './compiler'
|
||||
import { Compiled, options } from './options'
|
||||
|
||||
const cache: Map<string, Compiled> = new Map()
|
||||
|
||||
function compile(html: string): Compiled {
|
||||
return {
|
||||
template: compiler.process(html),
|
||||
time: Date.now()
|
||||
}
|
||||
}
|
||||
|
||||
export function renderFile(file: string, data: any, callback: (err: any, render: string) => void): void {
|
||||
util.readFile(file).then(html => {
|
||||
util.checksum(html, true).then(hash => {
|
||||
// Compile Template if is not in cache
|
||||
if (options.caching && !cache.get(html))
|
||||
cache.set(html, compile(html))
|
||||
|
||||
// Render the template and return the html
|
||||
const compiled = cache.get(html)
|
||||
if (compiled)
|
||||
callback(null, parser.computeParts(compiled.template, data))
|
||||
else
|
||||
callback('Error: Chache not found', '')
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export async function render(template_name: string, data?: any): Promise<string> {
|
||||
const template_path = path.join(options.template_dir, `${template_name}.${options.template_ext}`)
|
||||
|
||||
// Compile Template if is not in cache
|
||||
if (options.caching && !cache.get(template_name)) {
|
||||
const html = await util.readFile(template_path)
|
||||
if (html !== undefined)
|
||||
cache.set(template_name, compile(html))
|
||||
else {
|
||||
'No file found'.log()
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
// Render the template and return the html
|
||||
const compiled = cache.get(template_name)
|
||||
if (compiled)
|
||||
return parser.computeParts(compiled.template, data)
|
||||
else
|
||||
return ''
|
||||
}
|
||||
|
||||
export const _express = renderFile
|
57
src/cometa.ts
Normal file
57
src/cometa.ts
Normal file
@ -0,0 +1,57 @@
|
||||
import * as path from 'path'
|
||||
import * as util from './util'
|
||||
import * as parser from './parser'
|
||||
import * as compiler from './compiler'
|
||||
import { Compiled, options, Options, Expressions, re } from './options'
|
||||
|
||||
module.exports = class {
|
||||
private cache: Map<string, Compiled>
|
||||
private options: Options = options
|
||||
private expressions: Expressions = re
|
||||
|
||||
constructor(opt?: Options, rexp?: Expressions) {
|
||||
this.cache = new Map()
|
||||
|
||||
this.options = Object.assign(this.options, opt)
|
||||
this.expressions = Object.assign(this.expressions, rexp)
|
||||
|
||||
if (module.parent === null)
|
||||
throw new Error('Not imported')
|
||||
|
||||
this.options.views = path.join(path.dirname(module.parent.filename), this.options.views)
|
||||
}
|
||||
|
||||
renderFile(file: string, data: any, callback: (err: any, render: string) => void): void {
|
||||
console.log('Options', this.options)
|
||||
util.readFile(file).then(html => {
|
||||
console.log('Options', this.options)
|
||||
if (html === undefined) {
|
||||
callback(`No template found: ${file}`, '')
|
||||
return
|
||||
}
|
||||
util.checksum(html, true).then(hash => {
|
||||
// Compile Template if is not in cache
|
||||
if (this.options.caching && !this.cache.get(html))
|
||||
this.cache.set(html, {
|
||||
template: compiler.process(html, this.options, this.expressions),
|
||||
time: Date.now()
|
||||
})
|
||||
|
||||
// Render the template and return the html
|
||||
const compiled = this.cache.get(html)
|
||||
if (compiled)
|
||||
callback(null, parser.computeParts(compiled.template, data))
|
||||
else
|
||||
callback('Error: Chache not found', '')
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
renderTemplate(template_name: string, data: any, callback: (err: any, render: string) => void): void {
|
||||
const template_path = path.join(this.options.views, `${template_name}.${this.options.extension}`)
|
||||
this.renderFile(template_path, data, callback)
|
||||
}
|
||||
|
||||
_express = this.renderFile
|
||||
|
||||
}
|
@ -1,12 +1,13 @@
|
||||
import { Part, re, error, ActionFunction, ActionReturn } from './options'
|
||||
import { Part, error, ActionFunction, ActionReturn, options, Options, Expressions } from './options'
|
||||
import * as actions from './actions'
|
||||
|
||||
const rexp = Object.freeze({
|
||||
export const compileBlock: ActionFunction = (part, optoins, re) => {
|
||||
|
||||
const rexp = Object.freeze({
|
||||
begin: new RegExp(re.begin, 'g'),
|
||||
end: new RegExp(re.ending, 'g'),
|
||||
})
|
||||
})
|
||||
|
||||
export const compileBlock: ActionFunction = part => {
|
||||
interface Next {
|
||||
start: number
|
||||
end: number
|
||||
@ -56,7 +57,7 @@ export const compileBlock: ActionFunction = part => {
|
||||
break
|
||||
}
|
||||
|
||||
const result = func(part)
|
||||
const result = func(part, options, re)
|
||||
addToRet(result.parts)
|
||||
part = part.slice(result.length)
|
||||
|
||||
@ -68,8 +69,8 @@ export const compileBlock: ActionFunction = part => {
|
||||
return ret
|
||||
}
|
||||
|
||||
export function process(html: string, options = {}): Part[] {
|
||||
const parts: Part[] = compileBlock(html).parts
|
||||
export function process(html: string, options: Options, re: Expressions): Part[] {
|
||||
const parts: Part[] = compileBlock(html, options, re).parts
|
||||
return parts
|
||||
|
||||
}
|
@ -17,7 +17,7 @@ export interface ActionReturn {
|
||||
length: number
|
||||
}
|
||||
|
||||
export type ActionFunction = (part: Render) => ActionReturn
|
||||
export type ActionFunction = (part: Render, options: Options, re: Expressions) => ActionReturn
|
||||
|
||||
export interface Compiled {
|
||||
template: Part[]
|
||||
@ -36,27 +36,21 @@ export const error = {
|
||||
|
||||
}
|
||||
|
||||
interface Options {
|
||||
export interface Options {
|
||||
encoding: string
|
||||
caching: boolean
|
||||
template_dir: string
|
||||
template_ext: string
|
||||
compiled_dir: string
|
||||
compiled_ext: string
|
||||
max_recursion: number
|
||||
views: string
|
||||
extension: string
|
||||
}
|
||||
|
||||
export const options: Options = {
|
||||
encoding: 'utf-8',
|
||||
caching: true,
|
||||
template_dir: './views',
|
||||
template_ext: 'html',
|
||||
compiled_dir: './cache',
|
||||
compiled_ext: 'bjs',
|
||||
max_recursion: 100,
|
||||
views: './views',
|
||||
extension: 'html',
|
||||
}
|
||||
|
||||
interface Expressions {
|
||||
export interface Expressions {
|
||||
begin: string
|
||||
ending: string
|
||||
comment: string
|
||||
|
@ -2,7 +2,7 @@ import { Part, Render, isRender, PartFunction } from "./options";
|
||||
|
||||
|
||||
export function computeParts(parts: Part[], data = {}): Render {
|
||||
if (parts.length === 0)
|
||||
if (parts === undefined || parts.length === 0)
|
||||
return ''
|
||||
|
||||
return computePart(parts[0], data) + computeParts(parts.slice(1), data)
|
||||
|
38
src/util.ts
38
src/util.ts
@ -1,21 +1,11 @@
|
||||
import * as fs from 'fs'
|
||||
import * as crypto from 'crypto'
|
||||
|
||||
declare global {
|
||||
interface String {
|
||||
log: () => void
|
||||
}
|
||||
}
|
||||
|
||||
String.prototype.log = function (): void {
|
||||
console.log(this)
|
||||
}
|
||||
|
||||
export function readFile(url: string): Promise<string> {
|
||||
return new Promise(res => {
|
||||
fs.readFile(url, (err, data) => {
|
||||
if (err)
|
||||
throw new Error(`No such file: ${url}`)
|
||||
res()
|
||||
else
|
||||
res(data.toString())
|
||||
})
|
||||
@ -26,21 +16,6 @@ export function readFileSync(url: string): string {
|
||||
return fs.readFileSync(url).toString()
|
||||
}
|
||||
|
||||
export function writeFile(url: string, data: any): Promise<boolean> {
|
||||
return new Promise(res => {
|
||||
fs.writeFile(url, data, err => {
|
||||
if (err)
|
||||
res(false)
|
||||
res(true)
|
||||
})
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
export function writeFileSync(url: string, data: any): void {
|
||||
fs.writeFileSync(url, data)
|
||||
}
|
||||
|
||||
export function fileExists(url: string): Promise<boolean> {
|
||||
return new Promise(res => {
|
||||
fs.exists(url, _ => {
|
||||
@ -57,6 +32,7 @@ export function checksum(url: string, plain = false, alg = 'sha1'): Promise<stri
|
||||
res(hash.update(url).digest('hex'))
|
||||
}
|
||||
else {
|
||||
// For large files
|
||||
const stream = fs.createReadStream(url)
|
||||
stream.on('data', data => hash.update(data, 'utf8'))
|
||||
stream.on('end', _ => { res(hash.digest('hex')) })
|
||||
@ -64,10 +40,6 @@ export function checksum(url: string, plain = false, alg = 'sha1'): Promise<stri
|
||||
})
|
||||
}
|
||||
|
||||
export function replaceBetween(start: number, end: number, str: string, replace: string): string {
|
||||
return str.substring(0, start) + replace + str.substring(end)
|
||||
}
|
||||
|
||||
export function getFromObject(data: any, name: string): any {
|
||||
|
||||
name = name.trim()
|
||||
@ -79,9 +51,11 @@ export function getFromObject(data: any, name: string): any {
|
||||
|
||||
name = name.replace(/('|")/g, '')
|
||||
name = name.replace(/\[(\w+)\]/g, '.$1')
|
||||
|
||||
try {
|
||||
for (const i of name.split('.'))
|
||||
data = data[i]
|
||||
|
||||
} catch (e) {
|
||||
return ''
|
||||
}
|
||||
return data
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user