added filename encoding...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2022-09-04 03:20:47 +03:00
parent c0265b2edd
commit dc16742a2f
2 changed files with 63 additions and 36 deletions

View File

@ -15,12 +15,10 @@ var object = require('ig-object')
var types = require('ig-types')
var pwpath = require('../path')
var base = require('./base')
//---------------------------------------------------------------------
//
@ -40,6 +38,7 @@ var FILESTORE_OPTIONS = {
verbose: true,
}
var getOpts =
function(opts){
return {
@ -47,6 +46,22 @@ function(opts){
...(opts ?? {}),
} }
var encode =
module.encode =
function(str){
return str.replace(/[^\w .\\\/_\-]/gi,
function(c){
return `%${c
.charCodeAt(0)
.toString(16)
.toUpperCase()}` }) }
var decode =
module.decode =
function(str){
return decodeURIComponent(str) }
// func(base[, options])
// -> true/false
//
@ -65,9 +80,10 @@ async function(base, sub, options){
base = null }
var {index} = getOpts(options)
var target = base ?
pwpath.join(base, sub)
: sub
var target = encode(
base ?
pwpath.join(base, sub)
: sub)
if(!fs.existsSync(target)){
return false }
var stat = await fs.promises.stat(target)
@ -83,9 +99,10 @@ async function(base, sub, options){
base = null }
var {index} = getOpts(options)
var target = base ?
pwpath.join(base, sub)
: sub
var target = encode(
base ?
pwpath.join(base, sub)
: sub)
if(!fs.existsSync(target)){
return undefined }
// handle dir text...
@ -109,9 +126,10 @@ async function(base, sub, options){
var levels = pwpath.split(sub)
for(var level of levels){
base = base == null ?
level
: pwpath.join(base, level)
base = encode(
base == null ?
level
: pwpath.join(base, level))
// nothing exists -- create dir and continue...
if(!fs.existsSync(base)){
verbose
@ -140,9 +158,10 @@ async function(base, sub, data, options){
base = null }
var {index} = getOpts(options)
var target = base ?
pwpath.join(base, sub)
: sub
var target = encode(
base ?
pwpath.join(base, sub)
: sub)
// path already exists...
if(fs.existsSync(target)){
var stat = await fs.promises.stat(target)
@ -176,9 +195,10 @@ async function(base, sub, options){
var {index} = getOpts(options)
// remove leaf...
var target = base == '' ?
sub
: pwpath.join(base, sub)
var target = encode(
base == '' ?
sub
: pwpath.join(base, sub))
// dir...
if(fs.existsSync(target)){
var stat = await fs.promises.stat(target)
@ -198,8 +218,9 @@ async function(base, sub, options){
} else {
await fs.promises.rm(target) } }
// cleanup path -- remove empty dirs... (XXX ???)
var levels = pwpath.split(sub)
var levels = pwpath.split(encode(sub))
.slice(0, -1)
base = encode(base)
while(levels.length > 0){
var cur = pwpath.join(base, ...levels)
if(fs.existsSync(cur)){
@ -216,7 +237,7 @@ module.cleanup =
async function(base, options){
var {index, clearEmptyDir, dirToFile, verbose} = getOpts(options)
glob(pwpath.join(base, '**/*'))
glob(pwpath.join(encode(base), '**/*'))
.on('end', async function(paths){
paths
.sort(function(a, b){
@ -548,7 +569,7 @@ module.FileStoreRO = {
Promise.all(paths
.map(async function(path){
return await module.exists(path) ?
path
decode(path)
.slice(that.__path__.length)
: [] }))
.then(function(paths){

View File

@ -1,17 +1,6 @@
/**********************************************************************
*
*
* XXX might be fun to push the async parts of the render to the dom...
* ...i.e. return a partially rendered DOM with handlers to fill
* in the blanks wen they are ready...
* XXX UI/UX: add a cached/sync page.preview with ready events...
* XXX Q: empty title???
* - special default name
* a timestamp or some thing similar
* this can be hidden until changed by user
* XXX FILE prevent paths from using reserved chars like: ":", "#", ...
* XXX do we need something like /System/Actions/.. for fast actions called
* in the same way as direct page actions???
* XXX FEATURE tags and accompanying API...
* - add tags to page -- macro/filter
* - <page>.text -> <page>.tags (cached on .update(..))
@ -27,14 +16,34 @@
* - path integration...
* i.e. a way to pass tags through path...
* /some/path:tags=a,b,c
* XXX might be fun to push the async parts of the render to the dom...
* ...i.e. return a partially rendered DOM with handlers to fill
* in the blanks wen they are ready...
* something like:
* place placeholder element
* -> on visible / close to visible
* -> trigger load (set id)
* -> on load
* -> fill content (on id)
* example:
* @include(./path ..)
* -> <span pwiki="@include(/full/path ..)"/>
* XXX FILE prevent paths from using reserved chars like: ":", "#", ...
* XXX OPTIMIZE CACHE match pattern paths -- to catch page creation...
* 1) explicit subpath matching -- same as .match(..)
* 2) identify recursive patterns -- same as **
* XXX Q: empty title???
* - special default name
* a timestamp or some thing similar
* this can be hidden until changed by user
* XXX do we need something like /System/Actions/.. for fast actions called
* in the same way as direct page actions???
* XXX FEATURE list macro paging...
* ...should this be macro level or handled in .each()
* what mode?
* - count + block-offset (preferred)
* - count + elem-offset
* - from + to
* XXX TITLE revise how title is handled...
* ...do we need a separate title and path???
* XXX fs: handle odd file names...
* - we need '*' and '**'
* - would be nice to be able to name files without
@ -81,9 +90,6 @@
* e.g. when searching for xxx/tree the only "tree" available is
* System/tree, and if it is overloaded it's now a question of
* picking one out of two and not out of tens generated by .paths()
* XXX OPTIMIZE CACHE match pattern paths -- to catch page creation...
* 1) explicit subpath matching -- same as .match(..)
* 2) identify recursive patterns -- same as **
* XXX OPTIMIZE CACHE track store changes...
* XXX OPTIMIZE CACHE/DEPENDS might be a good idea to add a dependencyUpdated event...
* ...and use it for cache invalidation...