@jsonic/multisource 0.0.7 → 0.2.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/package.json CHANGED
@@ -1,37 +1,58 @@
1
1
  {
2
2
  "name": "@jsonic/multisource",
3
- "version": "0.0.7",
3
+ "version": "0.2.0",
4
4
  "description": "",
5
5
  "main": "dist/multisource.js",
6
6
  "type": "commonjs",
7
7
  "types": "dist/multisource.d.ts",
8
+ "homepage": "https://github.com/jsonicjs/multisource",
9
+ "keywords": [
10
+ "pattern",
11
+ "matcher",
12
+ "object",
13
+ "property",
14
+ "json"
15
+ ],
16
+ "author": "Richard Rodger, http://richardrodger.com",
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "git://github.com/jsonicjs/multisource.git"
20
+ },
8
21
  "scripts": {
22
+ "test": "jest --coverage",
23
+ "test-some": "jest -t",
24
+ "test-watch": "jest --coverage --watchAll",
9
25
  "watch": "tsc -w -d",
10
- "build": "tsc -d",
11
- "test": "lab -v -P test -t 50 --sourcemaps --transform node_modules/lab-transform-typescript -r console -o stdout -r html -o test/coverage.html",
12
- "test-some": "lab -v -P test --sourcemaps --transform node_modules/lab-transform-typescript -g",
13
- "test-web": "echo no-test-web",
26
+ "build": "tsc -d && cp dist/multisource.js dist/multisource.min.js && browserify -o dist/multisource.min.js -e dist/multisource.js -s @JsonicMultiSource -im -i assert -p tinyify",
27
+ "prettier": "prettier --write --no-semi --single-quote **/*.ts",
14
28
  "clean": "rm -rf node_modules yarn.lock package-lock.json",
15
- "reset": "npm run clean && npm i && npm run build && npm test",
29
+ "reset": "npm run clean && npm i && npm test",
16
30
  "repo-tag": "REPO_VERSION=`node -e \"console.log(require('./package').version)\"` && echo TAG: v$REPO_VERSION && git commit -a -m v$REPO_VERSION && git push && git tag v$REPO_VERSION && git push --tags;",
17
31
  "repo-publish": "npm run clean && npm i && npm run repo-publish-quick",
18
- "repo-publish-quick": "npm run build && npm run test && npm run test-web && npm run repo-tag && npm publish --registry http://registry.npmjs.org --access=public"
32
+ "repo-publish-quick": "npm run prettier && npm run build && npm run test && npm run repo-tag && npm publish --access public --registry https://registry.npmjs.org "
19
33
  },
20
- "author": "",
21
34
  "license": "MIT",
22
35
  "files": [
23
36
  "*.ts",
24
37
  "*.js",
25
- "lib",
38
+ "*.map",
26
39
  "LICENSE",
27
- "resolver",
40
+ "src",
28
41
  "dist"
29
42
  ],
30
43
  "devDependencies": {
31
- "jsonic": "jsonicjs/jsonic#nextgen",
32
- "@hapi/code": "^8.0.3",
33
- "@hapi/lab": "^24.2.1",
34
- "lab-transform-typescript": "^3.0.1",
35
- "typescript": "^4.2.4"
44
+ "@types/jest": "^27.4.1",
45
+ "browserify": "^17.0.0",
46
+ "esbuild": "^0.14.28",
47
+ "esbuild-jest": "^0.5.0",
48
+ "jest": "^27.5.1",
49
+ "jsonic": "github:jsonicjs/jsonic#nextgen",
50
+ "prettier": "^2.6.1",
51
+ "tinyify": "^3.0.0",
52
+ "ts-jest": "^27.1.4",
53
+ "typescript": "^4.6.3"
54
+ },
55
+ "dependencies": {
56
+ "@jsonic/directive": "^0.4.1"
36
57
  }
37
58
  }
@@ -0,0 +1,217 @@
1
+ /* Copyright (c) 2021 Richard Rodger, MIT License */
2
+
3
+ import { Jsonic, Context, Rule, Plugin } from 'jsonic'
4
+ import { Directive, DirectiveOptions } from '@jsonic/directive'
5
+
6
+ import { makeJsonicProcessor } from './processor/jsonic'
7
+ import { makeJavaScriptProcessor } from './processor/js'
8
+
9
+ // TODO: jsonic-cli should provide basepath
10
+
11
+ // Jsonic parsing meta data. In this case, storing the dependency tree.
12
+ interface MultiSourceMeta {
13
+ path?: string // Base path for this parse run.
14
+ deps?: DependencyMap // Provide an empty object to be filled.
15
+ }
16
+
17
+ // Unknown source reference file extension.
18
+ const NONE = ''
19
+
20
+ // Options for this plugin.
21
+ type MultiSourceOptions = {
22
+ resolver: Resolver // Resolve multisource spec to source
23
+ path?: string // Base path, prefixed to paths
24
+ markchar?: string // Character to mark start of multisource directive
25
+ processor?: { [kind: string]: Processor }
26
+ implictExt?: []
27
+ }
28
+
29
+ // The path to the source, including base prefix (if any).
30
+ type PathSpec = {
31
+ kind: string // Source kind, usually normalized file extension
32
+ path?: string // Original path (possibly relative)
33
+ full?: string // Normalized full path
34
+ base?: string // Current base path
35
+ abs: boolean // Path was absolute
36
+ }
37
+
38
+ // The source and where it was found.
39
+ type Resolution = PathSpec & {
40
+ src?: string // Undefined if no resolution
41
+ val?: any // Undefined if no resolution
42
+ found: boolean // True if source file was found
43
+ }
44
+
45
+ // Resolve the source.
46
+ type Resolver = (
47
+ spec: PathSpec,
48
+ popts: MultiSourceOptions,
49
+ rule: Rule,
50
+ ctx: Context,
51
+ jsonic: Jsonic
52
+ ) => Resolution
53
+
54
+ // Process the source into a value.
55
+ type Processor = (
56
+ res: Resolution,
57
+ popts: MultiSourceOptions,
58
+ rule: Rule,
59
+ ctx: Context,
60
+ jsonic: Jsonic
61
+ ) => void
62
+
63
+ type Dependency = {
64
+ tar: string | typeof TOP // Target that depends on source (src).
65
+ src: string // Source that target (tar) depends on.
66
+ wen: number // Time of resolution.
67
+ }
68
+
69
+ // A flattened dependency tree (assumes each element is a unique full path).
70
+ type DependencyMap = {
71
+ [tar_full_path: string]: {
72
+ [src_full_path: string]: Dependency
73
+ }
74
+ }
75
+
76
+ // The top of the dependence tree.
77
+ const TOP = Symbol('TOP')
78
+
79
+ const MultiSource: Plugin = (jsonic: Jsonic, popts: MultiSourceOptions) => {
80
+ const markchar = popts.markchar as string
81
+ const resolver = popts.resolver as Resolver
82
+ const processor = popts.processor as { [kind: string]: Processor }
83
+
84
+ // Normalize implicit extensions to format `.name`.
85
+ const implictExt = (popts.implictExt || []) as string[]
86
+ for (let extI = 0; extI < implictExt.length; extI++) {
87
+ let ext = implictExt[extI]
88
+ implictExt[extI] = ext.startsWith('.') ? ext : '.' + ext
89
+ }
90
+
91
+ jsonic.options({
92
+ error: {
93
+ multisource_not_found: 'source not found: $path',
94
+ },
95
+ hint: {
96
+ multisource_not_found: 'TODO: PATH: $path DETAILS: $details',
97
+ },
98
+ })
99
+
100
+ // Define a directive that can load content from multiple sources.
101
+ let dopts: DirectiveOptions = {
102
+ name: 'multisource',
103
+ open: markchar,
104
+ action: (rule: Rule, ctx: Context) => {
105
+ let spec = rule.child.node
106
+
107
+ let res = resolver(spec, popts, rule, ctx, jsonic)
108
+ if (!res.found) {
109
+ return rule.parent?.o0.bad('multisource_not_found', { ...res })
110
+ }
111
+
112
+ res.kind = null == res.kind ? NONE : res.kind
113
+
114
+ let proc = processor[res.kind] || processor[NONE]
115
+ proc(res, popts, rule, ctx, jsonic)
116
+
117
+ rule.node = res.val
118
+ },
119
+ }
120
+ jsonic.use(Directive, dopts)
121
+ }
122
+
123
+ // Convenience maker for Processors
124
+ function makeProcessor(process: (src: string, res: Resolution) => any) {
125
+ return (res: Resolution) => (res.val = process(res.src as string, res))
126
+ }
127
+
128
+ // Default is just to insert file contents as a string.
129
+ const defaultProcessor = makeProcessor((src: string) => src)
130
+
131
+ // TODO: use json plugin to get better error msgs.
132
+ const jsonProcessor = makeProcessor((src: string) =>
133
+ null == src ? undefined : JSON.parse(src)
134
+ )
135
+
136
+ const jsonicProcessor = makeJsonicProcessor()
137
+ const jsProcessor = makeJavaScriptProcessor()
138
+
139
+ MultiSource.defaults = {
140
+ markchar: '@',
141
+ processor: {
142
+ [NONE]: defaultProcessor,
143
+ jsonic: jsonicProcessor,
144
+ jsc: jsonicProcessor,
145
+ json: jsonProcessor,
146
+ js: jsProcessor,
147
+ },
148
+ implictExt: ['jsonic', 'jsc', 'json', 'js'],
149
+ }
150
+
151
+ function resolvePathSpec(
152
+ popts: MultiSourceOptions,
153
+ ctx: Context,
154
+ spec: any,
155
+ resolvefolder: (path: string) => string
156
+ ): PathSpec {
157
+ let msmeta = ctx.meta?.multisource
158
+ let base = resolvefolder(
159
+ null == msmeta || null == msmeta.path ? popts.path : msmeta.path
160
+ )
161
+
162
+ let path =
163
+ 'string' === typeof spec
164
+ ? spec
165
+ : null != spec.path
166
+ ? '' + spec.path
167
+ : undefined
168
+
169
+ let abs = !!(path?.startsWith('/') || path?.startsWith('\\'))
170
+ let full = abs
171
+ ? path
172
+ : null != path && '' != path
173
+ ? null != base && '' != base
174
+ ? base + '/' + path
175
+ : path
176
+ : undefined
177
+
178
+ let kind = null == full ? NONE : (full.match(/\.([^.]*)$/) || [NONE, NONE])[1]
179
+
180
+ let res: Resolution = {
181
+ kind,
182
+ path,
183
+ full,
184
+ base,
185
+ abs,
186
+ found: false,
187
+ }
188
+
189
+ // console.log('RES', res)
190
+
191
+ return res
192
+ }
193
+
194
+ export type {
195
+ Resolver,
196
+ Resolution,
197
+ Processor,
198
+ MultiSourceOptions,
199
+ Dependency,
200
+ DependencyMap,
201
+ MultiSourceMeta,
202
+ PathSpec,
203
+ }
204
+
205
+ export {
206
+ MultiSource,
207
+ resolvePathSpec,
208
+ NONE,
209
+ TOP,
210
+
211
+ // // Re-exported from jsonic for convenience
212
+ // Context,
213
+
214
+ // // TODO: remove for better tree shaking
215
+ // makeFileResolver,
216
+ // makeMemResolver,
217
+ }
@@ -0,0 +1,42 @@
1
+ /* Copyright (c) 2021 Richard Rodger, MIT License */
2
+
3
+
4
+ import {
5
+ Processor,
6
+ Resolution,
7
+ } from '../multisource'
8
+
9
+
10
+ function makeJavaScriptProcessor(opts?: {
11
+ evalOnly?: boolean
12
+ }): Processor {
13
+
14
+ const JavaScriptProcessor = (
15
+ res: Resolution,
16
+ ) => {
17
+ res.val = evaluate(res, opts)
18
+ }
19
+
20
+ JavaScriptProcessor.opts = opts
21
+
22
+ return JavaScriptProcessor
23
+ }
24
+
25
+ // TODO: too simplistic - handle more module cases
26
+ function evaluate(res: Resolution, opts?: any) {
27
+ let out = undefined
28
+ if (true !== opts?.evalOnly && undefined !== typeof (require)) {
29
+ out = require((res.full as string))
30
+ }
31
+ else {
32
+ let exports = null
33
+ let module = { exports }
34
+ eval((res.src as string))
35
+ out = module.exports
36
+ }
37
+ return out
38
+ }
39
+
40
+ export {
41
+ makeJavaScriptProcessor
42
+ }
@@ -0,0 +1,63 @@
1
+ /* Copyright (c) 2021 Richard Rodger, MIT License */
2
+
3
+
4
+ import { Jsonic, Rule, Context } from 'jsonic'
5
+
6
+ import {
7
+ MultiSourceOptions,
8
+ Processor,
9
+ Resolution,
10
+ TOP,
11
+ DependencyMap,
12
+ Dependency,
13
+ MultiSourceMeta,
14
+ } from '../multisource'
15
+
16
+
17
+ function makeJsonicProcessor(): Processor {
18
+
19
+ return function JsonicProcessor(
20
+ res: Resolution,
21
+ _popts: MultiSourceOptions,
22
+ _rule: Rule,
23
+ ctx: Context,
24
+ jsonic: Jsonic
25
+ ) {
26
+ if (null != res.src && null != res.full) {
27
+
28
+ // Pass down any meta info.
29
+ let msmeta: MultiSourceMeta = ctx.meta?.multisource || {}
30
+ let meta = {
31
+ ...(ctx.meta || {}),
32
+ multisource: {
33
+ ...msmeta,
34
+ path: res.full
35
+ }
36
+ }
37
+
38
+ // console.log('PM', meta, res)
39
+ res.val = jsonic(res.src, meta)
40
+
41
+ // Build dependency tree branch.
42
+ if (msmeta.deps) {
43
+ let depmap = (msmeta.deps as DependencyMap)
44
+ let parent = (msmeta.path || TOP) as string
45
+ if (null != parent) {
46
+ let dep: Dependency = {
47
+ tar: parent,
48
+ src: res.full,
49
+ wen: Date.now()
50
+ }
51
+ depmap[parent] = depmap[parent] || {}
52
+ depmap[parent][res.full] = dep
53
+ }
54
+ }
55
+ }
56
+ }
57
+ }
58
+
59
+
60
+
61
+ export {
62
+ makeJsonicProcessor
63
+ }
@@ -0,0 +1,91 @@
1
+ import Fs from 'fs'
2
+ import Path from 'path'
3
+
4
+ import { Rule, Context } from 'jsonic'
5
+
6
+ import {
7
+ MultiSourceOptions,
8
+ Resolver,
9
+ Resolution,
10
+ resolvePathSpec,
11
+ NONE,
12
+ } from '../multisource'
13
+
14
+
15
+ import {
16
+ buildPotentials
17
+ } from './mem'
18
+
19
+
20
+ function makeFileResolver(): Resolver {
21
+
22
+ return function FileResolver(
23
+ spec: any,
24
+ popts: MultiSourceOptions,
25
+ _rule: Rule,
26
+ ctx: Context,
27
+ ): Resolution {
28
+ let ps = resolvePathSpec(popts, ctx, spec, resolvefolder)
29
+ let src = undefined
30
+
31
+ // console.log(ps)
32
+
33
+ if (null != ps.full) {
34
+ ps.full = Path.resolve(ps.full)
35
+
36
+ src = load(ps.full)
37
+
38
+ if (null == src && NONE === ps.kind) {
39
+ let potentials =
40
+ buildPotentials(ps, popts, (...s) =>
41
+ Path.resolve(s.reduce((a, p) => Path.join(a, p))))
42
+
43
+ for (let path of potentials) {
44
+ if (null != (src = load(path))) {
45
+ ps.full = path
46
+ ps.kind = (path.match(/\.([^.]*)$/) || [NONE, NONE])[1]
47
+ break
48
+ }
49
+ }
50
+ }
51
+ }
52
+
53
+ let res: Resolution = {
54
+ ...ps,
55
+ src,
56
+ found: null != src
57
+ }
58
+
59
+ return res
60
+ }
61
+ }
62
+
63
+ function resolvefolder(path: string) {
64
+ let folder = path
65
+ let pathstats = Fs.statSync(path)
66
+
67
+ if (pathstats.isFile()) {
68
+ let pathdesc = Path.parse(path)
69
+ folder = pathdesc.dir
70
+ }
71
+
72
+ return folder
73
+ }
74
+
75
+
76
+ // TODO: in multisource.ts, generate an error token if cannot resolve
77
+ function load(path: string) {
78
+ // console.log('LOAD', path)
79
+ try {
80
+ return Fs.readFileSync(path).toString()
81
+ }
82
+ catch (e) {
83
+ // NOTE: don't need this, as in all cases, we consider failed
84
+ // reads to indicate non-existence.
85
+ }
86
+ }
87
+
88
+
89
+ export {
90
+ makeFileResolver,
91
+ }
@@ -0,0 +1,110 @@
1
+
2
+
3
+ import { Rule, Context } from 'jsonic'
4
+
5
+ import {
6
+ MultiSourceOptions,
7
+ Resolver,
8
+ Resolution,
9
+ resolvePathSpec,
10
+ NONE,
11
+ PathSpec,
12
+ } from '../multisource'
13
+
14
+
15
+ function makeMemResolver(filemap: { [fullpath: string]: string }): Resolver {
16
+
17
+ return function MemResolver(
18
+ spec: any,
19
+ popts: MultiSourceOptions,
20
+ _rule: Rule,
21
+ ctx: Context,
22
+ ): Resolution {
23
+ let ps = resolvePathSpec(popts, ctx, spec, makeresolvefolder(filemap))
24
+ let src = undefined
25
+
26
+ if (null != ps.full) {
27
+ src = filemap[ps.full]
28
+
29
+ if (null == src && NONE === ps.kind) {
30
+ let potentials =
31
+ buildPotentials(ps, popts, (...s) =>
32
+ s.reduce((a, p) => a + '/' + p))
33
+
34
+ for (let path of potentials) {
35
+ if (null != (src = filemap[path])) {
36
+ ps.full = path
37
+ ps.kind = (path.match(/\.([^.]*)$/) || [NONE, NONE])[1]
38
+ break
39
+ }
40
+ }
41
+ }
42
+ }
43
+
44
+ let res: Resolution = {
45
+ ...ps,
46
+ src,
47
+ found: null != src
48
+ }
49
+
50
+ return res
51
+ }
52
+ }
53
+
54
+
55
+ function makeresolvefolder(filemap: { [fullpath: string]: string }) {
56
+ return function resolvefolder(path: string) {
57
+ let folder = path
58
+ if (filemap[path]) {
59
+ folder = (path
60
+ .replace(/[\\\/]+$/, '')
61
+ .match(/[\\\/]+([^\\\/]+)$/) || ['', ''])[1]
62
+ // console.log('PF', path, folder)
63
+ }
64
+ // console.log('RF', folder)
65
+ return folder
66
+ }
67
+ }
68
+
69
+
70
+ function buildPotentials(
71
+ ps: PathSpec,
72
+ popts: MultiSourceOptions,
73
+ pathjoin: (...parts: string[]) => string): string[] {
74
+ let full = (ps.full as string)
75
+ let potentials: string[] = []
76
+ let implictExt: string[] = popts.implictExt || []
77
+
78
+ // Implicit extensions.
79
+ for (let ext of implictExt) {
80
+ potentials.push(full + ext)
81
+ }
82
+
83
+ // Folder index file.
84
+ for (let ext of implictExt) {
85
+ potentials.push(pathjoin(full, 'index' + ext))
86
+ }
87
+
88
+ // Folder index file (includes folder name).
89
+ if (null != ps.path) {
90
+ let folder = (ps.path
91
+ .replace(/[\\\/]+$/, '')
92
+ .match(/[^\\\/]+$/) || [])[0]
93
+ if (null != folder) {
94
+ for (let ext of implictExt) {
95
+ potentials.push(pathjoin(full, 'index.' + folder + ext))
96
+ }
97
+ }
98
+ }
99
+
100
+ // console.log(potentials)
101
+
102
+ return potentials
103
+ }
104
+
105
+
106
+
107
+ export {
108
+ buildPotentials,
109
+ makeMemResolver,
110
+ }
@@ -1 +0,0 @@
1
- export {};
@@ -1,85 +0,0 @@
1
- "use strict";
2
- /* Copyright (c) 2021 Richard Rodger and other contributors, MIT License */
3
- var __importDefault = (this && this.__importDefault) || function (mod) {
4
- return (mod && mod.__esModule) ? mod : { "default": mod };
5
- };
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- const lab_1 = __importDefault(require("@hapi/lab"));
8
- const code_1 = __importDefault(require("@hapi/code"));
9
- const lab = (exports.lab = lab_1.default.script());
10
- const describe = lab.describe;
11
- const it = lab.it;
12
- const expect = code_1.default.expect;
13
- const jsonic_1 = require("jsonic");
14
- const multisource_1 = require("../multisource");
15
- const file_1 = require("../resolver/file");
16
- const mem_1 = require("../resolver/mem");
17
- describe('multisource', function () {
18
- it('happy', () => {
19
- let j0 = jsonic_1.Jsonic.make().use(multisource_1.MultiSource, {
20
- resolver: mem_1.makeMemResolver({
21
- '/a': 'b:1',
22
- }),
23
- });
24
- expect(j0('c:1')).equals({ c: 1 });
25
- expect(j0('c:@"/a"')).equals({ c: { b: 1 } });
26
- expect(j0('x:y:1, x:z:2')).equals({ x: { y: 1, z: 2 } });
27
- });
28
- it('file', () => {
29
- let r0 = file_1.makeFileResolver();
30
- let j0 = jsonic_1.Jsonic.make().use(multisource_1.MultiSource, {
31
- resolver: r0,
32
- });
33
- let deps = {};
34
- expect(j0('a:1,b:@"./t01.jsonic"', { multisource: { path: __dirname, deps } }))
35
- .equals({ a: 1, b: { c: 2 } });
36
- //console.dir(deps, { depth: null })
37
- deps = {};
38
- expect(j0('a:1,b:@"./t02.jsonic",c:3', { multisource: { path: __dirname, deps } }))
39
- .equals({ a: 1, b: { d: 2, e: { f: 4 } }, c: 3 });
40
- //console.dir(deps, { depth: null })
41
- });
42
- it('mem', () => {
43
- let r0 = mem_1.makeMemResolver({
44
- '/a': 'a:1',
45
- '/b': 'b:@"c",',
46
- '/b/c': 'c:@"/a"',
47
- '/d': 'd:4',
48
- });
49
- let j0 = jsonic_1.Jsonic.make().use(multisource_1.MultiSource, {
50
- resolver: r0,
51
- });
52
- let deps = {};
53
- expect(j0('q:11,x:@"a",k:@"d",y:@"b",z:@"/b/c",w:22', { multisource: { deps } }))
54
- .equals({
55
- q: 11,
56
- x: { a: 1 },
57
- k: { d: 4 },
58
- y: { b: { c: { a: 1 } } },
59
- z: { c: { a: 1 } },
60
- w: 22,
61
- });
62
- //console.dir(deps, { depth: null })
63
- expect(remove(deps, 'wen')).equal({
64
- '/b/c': { '/a': { tar: '/b/c', src: '/a' } },
65
- '/b': { '/b/c': { tar: '/b', src: '/b/c' } },
66
- [multisource_1.TOP]: {
67
- '/a': { tar: multisource_1.TOP, src: '/a' },
68
- '/d': { tar: multisource_1.TOP, src: '/d' },
69
- '/b': { tar: multisource_1.TOP, src: '/b' },
70
- '/b/c': { tar: multisource_1.TOP, src: '/b/c' }
71
- }
72
- });
73
- });
74
- });
75
- function remove(o, k) {
76
- if (null != o && 'object' === typeof (o)) {
77
- delete o[k];
78
- remove(o[multisource_1.TOP], k);
79
- for (let p in o) {
80
- remove(o[p], k);
81
- }
82
- }
83
- return o;
84
- }
85
- //# sourceMappingURL=multisource.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"multisource.test.js","sourceRoot":"","sources":["../../test/multisource.test.ts"],"names":[],"mappings":"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"}