@jsonic/multisource 0.0.8 → 0.3.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.8",
3
+ "version": "0.3.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#4edd639987b75ef62a74e3904fb890f59d21379c",
32
- "@hapi/code": "^8.0.3",
33
- "@hapi/lab": "^24.3.0",
34
- "lab-transform-typescript": "^3.0.1",
35
- "typescript": "^4.3.5"
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
+ // TODO: use $details for more explanation in error message.
97
+ // In particular to show resolved absolute path.
98
+ multisource_not_found: 'The source path $path was not found.',
99
+ },
100
+ })
101
+
102
+ // Define a directive that can load content from multiple sources.
103
+ let dopts: DirectiveOptions = {
104
+ name: 'multisource',
105
+ open: markchar,
106
+ action: (rule: Rule, ctx: Context) => {
107
+ let spec = rule.child.node
108
+
109
+ let res = resolver(spec, popts, rule, ctx, jsonic)
110
+ if (!res.found) {
111
+ return rule.parent?.o0.bad('multisource_not_found', { ...res })
112
+ }
113
+
114
+ res.kind = null == res.kind ? NONE : res.kind
115
+
116
+ let proc = processor[res.kind] || processor[NONE]
117
+ proc(res, popts, rule, ctx, jsonic)
118
+
119
+ rule.node = res.val
120
+ },
121
+ }
122
+ jsonic.use(Directive, dopts)
123
+ }
124
+
125
+ // Convenience maker for Processors
126
+ function makeProcessor(process: (src: string, res: Resolution) => any) {
127
+ return (res: Resolution) => (res.val = process(res.src as string, res))
128
+ }
129
+
130
+ // Default is just to insert file contents as a string.
131
+ const defaultProcessor = makeProcessor((src: string) => src)
132
+
133
+ // TODO: use json plugin to get better error msgs.
134
+ const jsonProcessor = makeProcessor((src: string) =>
135
+ null == src ? undefined : JSON.parse(src)
136
+ )
137
+
138
+ const jsonicProcessor = makeJsonicProcessor()
139
+ const jsProcessor = makeJavaScriptProcessor()
140
+
141
+ MultiSource.defaults = {
142
+ markchar: '@',
143
+ processor: {
144
+ [NONE]: defaultProcessor,
145
+ jsonic: jsonicProcessor,
146
+ jsc: jsonicProcessor,
147
+ json: jsonProcessor,
148
+ js: jsProcessor,
149
+ },
150
+ implictExt: ['jsonic', 'jsc', 'json', 'js'],
151
+ }
152
+
153
+ function resolvePathSpec(
154
+ popts: MultiSourceOptions,
155
+ ctx: Context,
156
+ spec: any,
157
+ resolvefolder: (path: string) => string
158
+ ): PathSpec {
159
+ let msmeta = ctx.meta?.multisource
160
+ let base = resolvefolder(
161
+ null == msmeta || null == msmeta.path ? popts.path : msmeta.path
162
+ )
163
+
164
+ let path =
165
+ 'string' === typeof spec
166
+ ? spec
167
+ : null != spec.path
168
+ ? '' + spec.path
169
+ : undefined
170
+
171
+ let abs = !!(path?.startsWith('/') || path?.startsWith('\\'))
172
+ let full = abs
173
+ ? path
174
+ : null != path && '' != path
175
+ ? null != base && '' != base
176
+ ? base + '/' + path
177
+ : path
178
+ : undefined
179
+
180
+ let kind = null == full ? NONE : (full.match(/\.([^.]*)$/) || [NONE, NONE])[1]
181
+
182
+ let res: Resolution = {
183
+ kind,
184
+ path,
185
+ full,
186
+ base,
187
+ abs,
188
+ found: false,
189
+ }
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,96 @@
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
+ type PathFinder = (spec: any) => string
21
+
22
+ function makeFileResolver(pathfinder?: PathFinder): Resolver {
23
+
24
+ return function FileResolver(
25
+ spec: any,
26
+ popts: MultiSourceOptions,
27
+ _rule: Rule,
28
+ ctx: Context,
29
+ ): Resolution {
30
+ let foundSpec = pathfinder ? pathfinder(spec) : spec
31
+
32
+ let ps = resolvePathSpec(popts, ctx, foundSpec, resolvefolder)
33
+ let src = undefined
34
+
35
+ if (null != ps.full) {
36
+ ps.full = Path.resolve(ps.full)
37
+
38
+ src = load(ps.full)
39
+
40
+ if (null == src && NONE === ps.kind) {
41
+ let potentials =
42
+ buildPotentials(ps, popts, (...s) =>
43
+ Path.resolve(s.reduce((a, p) => Path.join(a, p))))
44
+
45
+ for (let path of potentials) {
46
+ if (null != (src = load(path))) {
47
+ ps.full = path
48
+ ps.kind = (path.match(/\.([^.]*)$/) || [NONE, NONE])[1]
49
+ break
50
+ }
51
+ }
52
+ }
53
+ }
54
+
55
+ let res: Resolution = {
56
+ ...ps,
57
+ src,
58
+ found: null != src
59
+ }
60
+
61
+ return res
62
+ }
63
+ }
64
+
65
+ function resolvefolder(path: string) {
66
+ if ('string' !== typeof path) {
67
+ return path
68
+ }
69
+
70
+ let folder = path
71
+ let pathstats = Fs.statSync(path)
72
+
73
+ if (pathstats.isFile()) {
74
+ let pathdesc = Path.parse(path)
75
+ folder = pathdesc.dir
76
+ }
77
+
78
+ return folder
79
+ }
80
+
81
+
82
+ // TODO: in multisource.ts, generate an error token if cannot resolve
83
+ function load(path: string) {
84
+ try {
85
+ return Fs.readFileSync(path).toString()
86
+ }
87
+ catch (e) {
88
+ // NOTE: don't need this, as in all cases, we consider failed
89
+ // reads to indicate non-existence.
90
+ }
91
+ }
92
+
93
+
94
+ export {
95
+ makeFileResolver,
96
+ }
@@ -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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"}