jostraca 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cmp/Content.d.ts +2 -0
- package/dist/cmp/Content.js +12 -0
- package/dist/cmp/Content.js.map +1 -0
- package/dist/cmp/Copy.d.ts +1 -1
- package/dist/cmp/Copy.js +6 -19
- package/dist/cmp/Copy.js.map +1 -1
- package/dist/cmp/File.d.ts +2 -0
- package/dist/cmp/File.js +13 -0
- package/dist/cmp/File.js.map +1 -0
- package/dist/cmp/Folder.d.ts +2 -0
- package/dist/cmp/Folder.js +12 -0
- package/dist/cmp/Folder.js.map +1 -0
- package/dist/cmp/Project.d.ts +2 -0
- package/dist/cmp/Project.js +13 -0
- package/dist/cmp/Project.js.map +1 -0
- package/dist/jostraca.d.ts +8 -40
- package/dist/jostraca.js +98 -290
- package/dist/jostraca.js.map +1 -1
- package/dist/op/ContentOp.d.ts +6 -0
- package/dist/op/ContentOp.js +12 -0
- package/dist/op/ContentOp.js.map +1 -0
- package/dist/op/CopyOp.d.ts +1 -1
- package/dist/op/CopyOp.js +115 -14
- package/dist/op/CopyOp.js.map +1 -1
- package/dist/op/FileOp.d.ts +6 -0
- package/dist/op/FileOp.js +43 -0
- package/dist/op/FileOp.js.map +1 -0
- package/dist/op/FolderOp.d.ts +6 -0
- package/dist/op/FolderOp.js +23 -0
- package/dist/op/FolderOp.js.map +1 -0
- package/dist/op/NoneOp.d.ts +6 -0
- package/dist/op/NoneOp.js +9 -0
- package/dist/op/NoneOp.js.map +1 -0
- package/dist/op/ProjectOp.d.ts +6 -0
- package/dist/op/ProjectOp.js +24 -0
- package/dist/op/ProjectOp.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utility.d.ts +45 -0
- package/dist/utility.js +486 -0
- package/dist/utility.js.map +1 -0
- package/package.json +4 -4
- package/src/cmp/Content.ts +19 -0
- package/src/cmp/Copy.ts +9 -22
- package/src/cmp/File.ts +21 -0
- package/src/cmp/Folder.ts +21 -0
- package/src/cmp/Project.ts +22 -0
- package/src/jostraca.ts +115 -385
- package/src/op/ContentOp.ts +18 -0
- package/src/op/CopyOp.ts +144 -16
- package/src/op/FileOp.ts +58 -0
- package/src/op/FolderOp.ts +31 -0
- package/src/op/NoneOp.ts +14 -0
- package/src/op/ProjectOp.ts +33 -0
- package/src/utility.ts +582 -0
- package/src/op/CopyOp.ts~ +0 -12
package/src/jostraca.ts
CHANGED
|
@@ -1,44 +1,46 @@
|
|
|
1
1
|
/* Copyright (c) 2024 Richard Rodger, MIT License */
|
|
2
2
|
|
|
3
3
|
import * as Fs from 'node:fs'
|
|
4
|
+
import Path from 'node:path'
|
|
4
5
|
|
|
5
6
|
import { AsyncLocalStorage } from 'node:async_hooks'
|
|
6
7
|
|
|
7
|
-
import { Copy } from './cmp/Copy'
|
|
8
|
-
|
|
9
|
-
import { CopyOp } from './op/CopyOp'
|
|
10
|
-
|
|
11
|
-
import { util as JostracaUtil } from '@jsonic/jsonic-next'
|
|
12
|
-
|
|
13
|
-
const { deep } = JostracaUtil
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
type JostracaOptions = {
|
|
17
|
-
folder?: string
|
|
18
|
-
fs?: any
|
|
19
|
-
meta?: any
|
|
20
|
-
}
|
|
21
8
|
|
|
9
|
+
import type {
|
|
10
|
+
JostracaOptions,
|
|
11
|
+
Node,
|
|
12
|
+
OpDef,
|
|
13
|
+
Component,
|
|
14
|
+
} from './utility'
|
|
22
15
|
|
|
23
|
-
type Node = {
|
|
24
|
-
kind: string
|
|
25
|
-
children?: Node[]
|
|
26
|
-
name?: string
|
|
27
|
-
path?: string
|
|
28
|
-
from?: string
|
|
29
|
-
content?: any[]
|
|
30
|
-
}
|
|
31
16
|
|
|
17
|
+
import {
|
|
18
|
+
each,
|
|
19
|
+
select,
|
|
20
|
+
get,
|
|
21
|
+
getx,
|
|
22
|
+
camelify,
|
|
23
|
+
snakify,
|
|
24
|
+
kebabify,
|
|
25
|
+
cmap,
|
|
26
|
+
vmap,
|
|
27
|
+
names,
|
|
28
|
+
} from './utility'
|
|
32
29
|
|
|
33
|
-
type OpStep = (node: Node, ctx$: any, buildctx: any) => void
|
|
34
30
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
31
|
+
import { Content } from './cmp/Content'
|
|
32
|
+
import { Copy } from './cmp/Copy'
|
|
33
|
+
import { File } from './cmp/File'
|
|
34
|
+
import { Folder } from './cmp/Folder'
|
|
35
|
+
import { Project } from './cmp/Project'
|
|
39
36
|
|
|
37
|
+
import { CopyOp } from './op/CopyOp'
|
|
38
|
+
import { ProjectOp } from './op/ProjectOp'
|
|
39
|
+
import { FolderOp } from './op/FolderOp'
|
|
40
|
+
import { FileOp } from './op/FileOp'
|
|
41
|
+
import { ContentOp } from './op/ContentOp'
|
|
42
|
+
import { NoneOp } from './op/NoneOp'
|
|
40
43
|
|
|
41
|
-
type Component = (props: any, children?: any) => void
|
|
42
44
|
|
|
43
45
|
|
|
44
46
|
const GLOBAL = (global as any)
|
|
@@ -49,38 +51,40 @@ function Jostraca() {
|
|
|
49
51
|
GLOBAL.jostraca = new AsyncLocalStorage()
|
|
50
52
|
|
|
51
53
|
|
|
52
|
-
function generate(opts: JostracaOptions, root: Function) {
|
|
54
|
+
async function generate(opts: JostracaOptions, root: Function) {
|
|
53
55
|
const fs = opts.fs || Fs
|
|
54
56
|
const meta = opts.meta || {}
|
|
55
57
|
const folder = opts.folder || '.'
|
|
56
58
|
|
|
57
59
|
const ctx$ = {
|
|
58
|
-
fs,
|
|
59
60
|
folder,
|
|
60
61
|
content: null,
|
|
61
62
|
meta,
|
|
63
|
+
fs,
|
|
62
64
|
}
|
|
63
65
|
|
|
64
|
-
GLOBAL.jostraca.run(ctx$, () => {
|
|
66
|
+
return GLOBAL.jostraca.run(ctx$, async () => {
|
|
65
67
|
try {
|
|
66
|
-
//
|
|
68
|
+
// Define phase
|
|
67
69
|
root()
|
|
68
|
-
// console.log('END ROOT')
|
|
69
70
|
|
|
70
71
|
const ctx$ = GLOBAL.jostraca.getStore()
|
|
71
72
|
|
|
72
|
-
// console.
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
73
|
+
// console.dir(ctx$.node, { depth: null })
|
|
74
|
+
|
|
75
|
+
// Build phase
|
|
76
|
+
|
|
77
|
+
const buildctx = {
|
|
78
|
+
fs,
|
|
79
|
+
folder,
|
|
80
|
+
current: {
|
|
81
|
+
folder: {
|
|
82
|
+
parent: folder
|
|
81
83
|
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
await build(ctx$, buildctx)
|
|
87
|
+
return buildctx
|
|
84
88
|
}
|
|
85
89
|
catch (err: any) {
|
|
86
90
|
console.log('JOSTRACA ERROR:', err)
|
|
@@ -90,101 +94,80 @@ function Jostraca() {
|
|
|
90
94
|
}
|
|
91
95
|
|
|
92
96
|
|
|
93
|
-
function build(ctx$: any, buildctx: any) {
|
|
97
|
+
async function build(ctx$: any, buildctx: any) {
|
|
94
98
|
const topnode = ctx$.node
|
|
95
|
-
step(topnode, ctx$, buildctx)
|
|
96
|
-
}
|
|
97
99
|
|
|
100
|
+
let info = { exclude: [], last: -1 }
|
|
101
|
+
const infopath = Path.join(buildctx.folder, '.jostraca', 'info.json')
|
|
98
102
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
throw new Error('missing op: ' + node.kind)
|
|
103
|
+
try {
|
|
104
|
+
info = JSON.parse(ctx$.fs.readFileSync(
|
|
105
|
+
infopath, 'utf8'))
|
|
103
106
|
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
if (node.children) {
|
|
108
|
-
for (let childnode of node.children) {
|
|
109
|
-
step(childnode, ctx$, buildctx)
|
|
110
|
-
}
|
|
107
|
+
catch (err: any) {
|
|
108
|
+
// console.log(err)
|
|
109
|
+
// TODO: file not foound ignored, handle others!
|
|
111
110
|
}
|
|
112
111
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
const opmap: Record<string, OpDef> = {
|
|
118
|
-
|
|
119
|
-
project: {
|
|
120
|
-
before(node: Node, _ctx$: any, buildctx: any) {
|
|
121
|
-
const cproject: any = buildctx.current.project = (buildctx.current.project || {})
|
|
122
|
-
cproject.node = node
|
|
123
|
-
},
|
|
124
|
-
|
|
125
|
-
after(_node: Node, _ctx$: any, _buildctx: any) {
|
|
112
|
+
buildctx.info = info
|
|
113
|
+
// console.log('B-INFO', buildctx.info)
|
|
126
114
|
|
|
127
|
-
|
|
128
|
-
},
|
|
115
|
+
await step(topnode, ctx$, buildctx)
|
|
129
116
|
|
|
130
117
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
118
|
+
try {
|
|
119
|
+
ctx$.fs.mkdirSync(Path.dirname(infopath), { recursive: true })
|
|
120
|
+
const info = {
|
|
121
|
+
last: Date.now(),
|
|
122
|
+
exclude: buildctx.info.exclude,
|
|
123
|
+
}
|
|
124
|
+
ctx$.fs.writeFileSync(infopath, JSON.stringify(info, null, 2), { flush: true })
|
|
125
|
+
}
|
|
126
|
+
catch (err: any) {
|
|
127
|
+
console.log(err)
|
|
128
|
+
// TODO: file not foound ignored, handle others!
|
|
129
|
+
}
|
|
143
130
|
|
|
144
|
-
after(_node: Node, _ctx$: any, buildctx: any) {
|
|
145
|
-
const cfolder = buildctx.current.folder
|
|
146
|
-
cfolder.path.length = cfolder.path.length - 1
|
|
147
|
-
},
|
|
148
|
-
},
|
|
149
131
|
|
|
132
|
+
return { node: topnode, ctx$, buildctx }
|
|
133
|
+
}
|
|
150
134
|
|
|
151
|
-
file: {
|
|
152
|
-
before(node: Node, _ctx$: any, buildctx: any) {
|
|
153
|
-
const cfile = buildctx.current.file = node
|
|
154
|
-
cfile.path = buildctx.current.folder.path.join('/') + '/' + node.name
|
|
155
|
-
cfile.content = []
|
|
156
|
-
},
|
|
157
135
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
136
|
+
async function step(node: Node, ctx$: any, buildctx: any) {
|
|
137
|
+
try {
|
|
138
|
+
const op = opmap[node.kind]
|
|
139
|
+
if (null == op) {
|
|
140
|
+
throw new Error('missing op: ' + node.kind)
|
|
141
|
+
}
|
|
164
142
|
|
|
143
|
+
await op.before(node, ctx$, buildctx)
|
|
165
144
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
}
|
|
145
|
+
if (node.children) {
|
|
146
|
+
for (let childnode of node.children) {
|
|
147
|
+
await step(childnode, ctx$, buildctx)
|
|
148
|
+
}
|
|
149
|
+
}
|
|
171
150
|
|
|
172
|
-
after(
|
|
173
|
-
|
|
174
|
-
|
|
151
|
+
await op.after(node, ctx$, buildctx)
|
|
152
|
+
}
|
|
153
|
+
catch (err: any) {
|
|
154
|
+
if (err.jostraca) {
|
|
155
|
+
throw err
|
|
156
|
+
}
|
|
157
|
+
err.jostraca = true
|
|
158
|
+
err.step = node.kind
|
|
159
|
+
throw err
|
|
160
|
+
}
|
|
161
|
+
}
|
|
175
162
|
|
|
176
163
|
|
|
164
|
+
const opmap: Record<string, OpDef> = {
|
|
165
|
+
project: ProjectOp,
|
|
166
|
+
folder: FolderOp,
|
|
167
|
+
file: FileOp,
|
|
168
|
+
content: ContentOp,
|
|
177
169
|
copy: CopyOp,
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
none: {
|
|
181
|
-
before(_node: Node, _ctx$: any, buildctx: any) {
|
|
182
|
-
},
|
|
183
|
-
|
|
184
|
-
after(_node: Node, _ctx$: any, buildctx: any) {
|
|
185
|
-
},
|
|
186
|
-
},
|
|
187
|
-
|
|
170
|
+
none: NoneOp,
|
|
188
171
|
}
|
|
189
172
|
|
|
190
173
|
|
|
@@ -194,41 +177,6 @@ function Jostraca() {
|
|
|
194
177
|
}
|
|
195
178
|
|
|
196
179
|
|
|
197
|
-
const Code = cmp(function Code(props: any) {
|
|
198
|
-
props.ctx$.node.kind = 'content'
|
|
199
|
-
let src = props.arg
|
|
200
|
-
props.ctx$.node.content = src
|
|
201
|
-
})
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
const File = cmp(function File(props: any, children: any) {
|
|
205
|
-
props.ctx$.node.kind = 'file'
|
|
206
|
-
props.ctx$.node.name = props.name
|
|
207
|
-
|
|
208
|
-
// Code('// FILE START: ' + props.name + '\n')
|
|
209
|
-
|
|
210
|
-
each(children)
|
|
211
|
-
|
|
212
|
-
// Code('// FILE END: ' + props.name + '\n')
|
|
213
|
-
})
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
const Project: Component = cmp(function Project(props: any, children: any) {
|
|
217
|
-
props.ctx$.node.kind = 'project'
|
|
218
|
-
props.ctx$.node.name = props.name
|
|
219
|
-
|
|
220
|
-
each(children)
|
|
221
|
-
})
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
const Folder = cmp(function Folder(props: any, children: any) {
|
|
225
|
-
props.ctx$.node.kind = 'folder'
|
|
226
|
-
props.ctx$.node.name = props.name
|
|
227
|
-
|
|
228
|
-
each(children)
|
|
229
|
-
})
|
|
230
|
-
|
|
231
|
-
|
|
232
180
|
function cmp(component: Function): Component {
|
|
233
181
|
const cf = (props: any, children?: any) => {
|
|
234
182
|
props = props || {}
|
|
@@ -238,9 +186,10 @@ function cmp(component: Function): Component {
|
|
|
238
186
|
props.ctx$ = GLOBAL.jostraca.getStore()
|
|
239
187
|
children = 'function' === typeof children ? [children] : children
|
|
240
188
|
|
|
241
|
-
let node = {
|
|
189
|
+
let node: Node = {
|
|
242
190
|
kind: 'none',
|
|
243
|
-
children: []
|
|
191
|
+
children: [],
|
|
192
|
+
path: [],
|
|
244
193
|
}
|
|
245
194
|
|
|
246
195
|
const parent = props.ctx$.node = (props.ctx$.node || node)
|
|
@@ -250,6 +199,13 @@ function cmp(component: Function): Component {
|
|
|
250
199
|
props.ctx$.children = node.children
|
|
251
200
|
props.ctx$.node = node
|
|
252
201
|
|
|
202
|
+
node.path = parent.path.slice(0)
|
|
203
|
+
if ('string' === typeof props.name) {
|
|
204
|
+
node.path.push(props.name)
|
|
205
|
+
// console.log('CMP-PATH', component.name, node.path)
|
|
206
|
+
// console.trace()
|
|
207
|
+
}
|
|
208
|
+
|
|
253
209
|
let out = component(props, children)
|
|
254
210
|
|
|
255
211
|
props.ctx$.children = siblings
|
|
@@ -262,233 +218,6 @@ function cmp(component: Function): Component {
|
|
|
262
218
|
}
|
|
263
219
|
|
|
264
220
|
|
|
265
|
-
function each(subject?: any, apply?: any) {
|
|
266
|
-
if (null == apply) {
|
|
267
|
-
let out = []
|
|
268
|
-
if (Array.isArray(subject)) {
|
|
269
|
-
for (let fn of subject) {
|
|
270
|
-
out.push('function' === typeof fn ? fn() : fn)
|
|
271
|
-
}
|
|
272
|
-
return out.sort()
|
|
273
|
-
}
|
|
274
|
-
else if (null == subject || 'object' !== typeof subject) {
|
|
275
|
-
return []
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
else if (Array.isArray(subject)) {
|
|
279
|
-
return subject.map(apply)
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
if (null == subject || 'object' !== typeof subject) {
|
|
283
|
-
return []
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
const entries: any = Object.entries(subject).map((n: any[], _: any) =>
|
|
287
|
-
(_ = typeof n[1],
|
|
288
|
-
(null != n[1] && 'object' === _) ? (n[1].key$ = n[0]) :
|
|
289
|
-
(n[1] = { name: n[0], key$: n[0], val$: n[1] }), n))
|
|
290
|
-
|
|
291
|
-
if (1 < entries.length) {
|
|
292
|
-
if (entries[0] && entries[0][1] && 'string' === typeof entries[0][1].name) {
|
|
293
|
-
entries.sort((a: any, b: any) =>
|
|
294
|
-
a[1].name < b[1].name ? -1 : b[1].name < a[1].name ? 1 : 0)
|
|
295
|
-
}
|
|
296
|
-
else if (entries[0] && entries[0][1] && 'string' === typeof entries[0][1].key$) {
|
|
297
|
-
entries.sort((a: any, b: any) =>
|
|
298
|
-
a[1].key$ < b[1].key$ ? -1 : b[1].key$ < a[1].key$ ? 1 : 0)
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
apply = 'function' === typeof apply ? apply : (x: any) => x
|
|
303
|
-
|
|
304
|
-
return entries.map((n: any, ...args: any[]) =>
|
|
305
|
-
apply(n[1], n[0], ...args))
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
function select(key: any, map: Record<string, Function>) {
|
|
311
|
-
const fn = map && map[key]
|
|
312
|
-
return fn ? fn() : undefined
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
function getx(root: any, path: string | string[]): any {
|
|
318
|
-
path = ('string' === typeof path ? path.split(/[.\s\r\n\t]/) : path).filter(part => '' != part)
|
|
319
|
-
let node = root
|
|
320
|
-
let parents = []
|
|
321
|
-
|
|
322
|
-
partloop:
|
|
323
|
-
for (let i = 0; i < path.length && null != node; i++) {
|
|
324
|
-
let part = String(path[i]).trim()
|
|
325
|
-
let m = part.match(/^([^<=>~^?!]*)([<=>~^?!]+)(.*)$/)
|
|
326
|
-
|
|
327
|
-
if (m) {
|
|
328
|
-
part = m[1]
|
|
329
|
-
let op = m[2]
|
|
330
|
-
let arg = m[3]
|
|
331
|
-
|
|
332
|
-
let val = '' === part ? node : node[part]
|
|
333
|
-
|
|
334
|
-
if ('=' === op && 'null' === arg) {
|
|
335
|
-
parents.push(node)
|
|
336
|
-
node = {} // virtual node so that ^ works consistently
|
|
337
|
-
continue partloop
|
|
338
|
-
}
|
|
339
|
-
else if ('^' === op && '' === part && '' !== arg) {
|
|
340
|
-
node = parents[parents.length - Number(arg)]
|
|
341
|
-
continue partloop
|
|
342
|
-
}
|
|
343
|
-
else if ('?' === op[0]) {
|
|
344
|
-
arg = (1 < op.length ? op.substring(1) : '') + arg
|
|
345
|
-
node = Array.isArray(val) ?
|
|
346
|
-
each(val).filter((n: any) => (
|
|
347
|
-
null != getx(n, arg))) :
|
|
348
|
-
each(val).filter((n: any) => (
|
|
349
|
-
null != getx(n, arg)))
|
|
350
|
-
.reduce((a: any, n: any) => (a[n.key$] = n, delete n.key$, a), {})
|
|
351
|
-
|
|
352
|
-
continue partloop
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
if (null == val) return undefined
|
|
356
|
-
|
|
357
|
-
val = Array.isArray(val) ? val.length :
|
|
358
|
-
'object' === typeof val ? Object.keys(val).filter(k => !k.includes('$')).length :
|
|
359
|
-
val
|
|
360
|
-
|
|
361
|
-
switch (op) {
|
|
362
|
-
case '<':
|
|
363
|
-
if (!(val < arg)) return undefined
|
|
364
|
-
break
|
|
365
|
-
case '<=':
|
|
366
|
-
if (!(val <= arg)) return undefined
|
|
367
|
-
break
|
|
368
|
-
case '>':
|
|
369
|
-
if (!(val > arg)) return undefined
|
|
370
|
-
break
|
|
371
|
-
case '>=':
|
|
372
|
-
if (!(val >= arg)) return undefined
|
|
373
|
-
break
|
|
374
|
-
case '=':
|
|
375
|
-
if (!(val == arg)) return undefined
|
|
376
|
-
break
|
|
377
|
-
case '!=':
|
|
378
|
-
if (!(val != arg)) return undefined
|
|
379
|
-
break
|
|
380
|
-
case '~':
|
|
381
|
-
if (!(String(val).match(RegExp(arg)))) return undefined
|
|
382
|
-
break
|
|
383
|
-
case '^':
|
|
384
|
-
node = parents[parents.length - Number(arg)]
|
|
385
|
-
continue partloop
|
|
386
|
-
default:
|
|
387
|
-
return undefined
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
parents.push(node)
|
|
392
|
-
node = '' === part ? node : node[part]
|
|
393
|
-
}
|
|
394
|
-
return node
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
function get(root: any, path: string | string[]): any {
|
|
399
|
-
path = 'string' === typeof path ? path.split('.') : path
|
|
400
|
-
let node = root
|
|
401
|
-
for (let i = 0; i < path.length && null != node; i++) {
|
|
402
|
-
node = node[path[i]]
|
|
403
|
-
}
|
|
404
|
-
return node
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
function camelify(input: any[] | string) {
|
|
409
|
-
let parts = 'string' == typeof input ? input.split('-') : input.map(n => '' + n)
|
|
410
|
-
return parts
|
|
411
|
-
.map((p: string) => ('' === p ? '' : (p[0].toUpperCase() + p.substring(1))))
|
|
412
|
-
.join('')
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
function kebabify(input: any[] | string) {
|
|
417
|
-
let parts = 'string' == typeof input ? input.split(/([A-Z])/) : input.map(n => '' + n)
|
|
418
|
-
return parts
|
|
419
|
-
.filter((p: string) => '' !== p)
|
|
420
|
-
.reduce((a: any[], n: string, i: number) =>
|
|
421
|
-
((0 === i % 2 ? a.push(n.toLowerCase()) : a[(i / 2) | 0] += n), a), [])
|
|
422
|
-
.join('-')
|
|
423
|
-
}
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
function snakify(input: any[] | string) {
|
|
427
|
-
let parts = 'string' == typeof input ? input.split(/([A-Z])/) : input.map(n => '' + n)
|
|
428
|
-
return parts
|
|
429
|
-
.filter((p: string) => '' !== p)
|
|
430
|
-
.reduce((a: any[], n: string, i: number) =>
|
|
431
|
-
((0 === i % 2 ? a.push(n.toLowerCase()) : a[(i / 2) | 0] += n), a), [])
|
|
432
|
-
.join('_')
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
function names(base: any, name: string, prop = 'name') {
|
|
437
|
-
base.name$ = name
|
|
438
|
-
base[prop.toLowerCase()] = name.toLowerCase()
|
|
439
|
-
base[camelify(prop)] = camelify(name)
|
|
440
|
-
base[snakify(prop)] = snakify(name)
|
|
441
|
-
base[kebabify(prop)] = kebabify(name)
|
|
442
|
-
base[prop.toUpperCase()] = name.toUpperCase()
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
// Map child objects to new child objects
|
|
448
|
-
function cmap(o: any, p: any) {
|
|
449
|
-
return Object
|
|
450
|
-
.entries(o)
|
|
451
|
-
.reduce((r: any, n: any, _: any) => (_ = Object
|
|
452
|
-
.entries(p)
|
|
453
|
-
.reduce((s: any, m: any) => (cmap.FILTER === s ? s : (s[m[0]] = (
|
|
454
|
-
// transfom(val,key,current,parentkey,parent)
|
|
455
|
-
'function' === typeof m[1] ? m[1](n[1][m[0]], {
|
|
456
|
-
skey: m[0], self: n[1], key: n[0], parent: o
|
|
457
|
-
}) : m[1]
|
|
458
|
-
), (cmap.FILTER === s[m[0]] ? cmap.FILTER : s))), {})
|
|
459
|
-
, (cmap.FILTER === _ ? 0 : r[n[0]] = _), r), {})
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
cmap.COPY = (x: any) => x
|
|
463
|
-
// keep self if x is truthy, or function returning truthy-new-value or [truthy,new-value]
|
|
464
|
-
cmap.FILTER = (x: any) => 'function' === typeof x ? ((y: any, p: any, _: any) =>
|
|
465
|
-
(_ = x(y, p), Array.isArray(_) ? !_[0] ? _[1] : cmap.FILTER : _)) : (x ? x : cmap.FILTER)
|
|
466
|
-
cmap.KEY = (_: any, p: any) => p.key
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
// Map child objects to a list of child objects
|
|
470
|
-
function vmap(o: any, p: any) {
|
|
471
|
-
return Object
|
|
472
|
-
.entries(o)
|
|
473
|
-
.reduce((r: any, n: any, _: any) => (_ = Object
|
|
474
|
-
.entries(p)
|
|
475
|
-
.reduce((s: any, m: any) => (vmap.FILTER === s ? s : (s[m[0]] = (
|
|
476
|
-
// transfom(val,key,current,parentkey,parent)
|
|
477
|
-
// 'function' === typeof m[1] ? m[1](n[1][m[0]], m[0], n[1], n[0], o) : m[1]
|
|
478
|
-
'function' === typeof m[1] ? m[1](n[1][m[0]], {
|
|
479
|
-
skey: m[0], self: n[1], key: n[0], parent: o
|
|
480
|
-
}) : m[1]
|
|
481
|
-
), (vmap.FILTER === s[m[0]] ? vmap.FILTER : s))), {})
|
|
482
|
-
, (vmap.FILTER === _ ? 0 : r.push(_)), r), [])
|
|
483
|
-
|
|
484
|
-
}
|
|
485
|
-
vmap.COPY = (x: any) => x
|
|
486
|
-
vmap.FILTER = (x: any) => 'function' === typeof x ? ((y: any, p: any, _: any) =>
|
|
487
|
-
(_ = x(y, p), Array.isArray(_) ? !_[0] ? _[1] : vmap.FILTER : _)) : (x ? x : vmap.FILTER)
|
|
488
|
-
vmap.KEY = (_: any, p: any) => p.key
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
221
|
|
|
493
222
|
|
|
494
223
|
export type {
|
|
@@ -514,8 +243,9 @@ export {
|
|
|
514
243
|
names,
|
|
515
244
|
|
|
516
245
|
Project,
|
|
517
|
-
|
|
246
|
+
Content,
|
|
518
247
|
File,
|
|
519
248
|
Folder,
|
|
520
249
|
Copy,
|
|
521
250
|
}
|
|
251
|
+
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
import type { Node } from '../jostraca'
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
const ContentOp = {
|
|
7
|
+
before(node: Node, _ctx$: any, buildctx: any) {
|
|
8
|
+
const content = buildctx.current.content = node
|
|
9
|
+
buildctx.current.file.content.push(content.content)
|
|
10
|
+
},
|
|
11
|
+
|
|
12
|
+
after(_node: Node, _ctx$: any, buildctx: any) { },
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
export {
|
|
17
|
+
ContentOp
|
|
18
|
+
}
|