jostraca 0.0.9 → 0.1.2

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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2019 jostraca
3
+ Copyright (c) 2024 Richard Rodger and Jostraca contributors
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,12 +1,2 @@
1
1
  # jostraca
2
- Jostraca
3
2
 
4
-
5
- ## Development
6
-
7
- * Watch: `npm run tsc:w`
8
-
9
-
10
- ## Templating
11
-
12
- * The `<%=slots.foo%>` injection *currently* should always be placed at the start of a line to avoid adding indentation on each generation - whitespace handling needs to be smarter.
@@ -0,0 +1,16 @@
1
+ type JostracaOptions = {
2
+ folder: string;
3
+ fs: any;
4
+ };
5
+ type Component = (props: any, children?: any) => void;
6
+ declare function Jostraca(): {
7
+ cmp: (component: Function) => Component;
8
+ each: (subject: any, apply?: any) => any;
9
+ generate: (opts: JostracaOptions, root: Function) => void;
10
+ Project: Component;
11
+ Code: Component;
12
+ File: Component;
13
+ Folder: Component;
14
+ };
15
+ export type { JostracaOptions, Component, };
16
+ export { Jostraca, };
@@ -0,0 +1,189 @@
1
+ "use strict";
2
+ /* Copyright (c) 2024 Richard Rodger, MIT License */
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || function (mod) {
20
+ if (mod && mod.__esModule) return mod;
21
+ var result = {};
22
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
23
+ __setModuleDefault(result, mod);
24
+ return result;
25
+ };
26
+ Object.defineProperty(exports, "__esModule", { value: true });
27
+ exports.Jostraca = Jostraca;
28
+ const Fs = __importStar(require("node:fs"));
29
+ const node_async_hooks_1 = require("node:async_hooks");
30
+ function Jostraca() {
31
+ const GLOBAL = global;
32
+ GLOBAL.jostraca = new node_async_hooks_1.AsyncLocalStorage();
33
+ function generate(opts, root) {
34
+ const fs = opts.fs || Fs;
35
+ GLOBAL.jostraca.run({
36
+ content: null,
37
+ }, () => {
38
+ root();
39
+ const ctx$ = GLOBAL.jostraca.getStore();
40
+ const node = ctx$.node;
41
+ build(node, {
42
+ fs,
43
+ current: {
44
+ folder: {
45
+ parent: opts.folder
46
+ }
47
+ }
48
+ });
49
+ });
50
+ }
51
+ function cmp(component) {
52
+ const cf = (props, children) => {
53
+ props = props || {};
54
+ if (null == props || 'object' !== typeof props) {
55
+ props = { arg: props };
56
+ }
57
+ props.ctx$ = GLOBAL.jostraca.getStore();
58
+ children = 'function' === typeof children ? [children] : children;
59
+ let node = {
60
+ kind: 'content',
61
+ children: []
62
+ };
63
+ const parent = props.ctx$.node = (props.ctx$.node || node);
64
+ const siblings = props.ctx$.children = (props.ctx$.children || []);
65
+ siblings.push(node);
66
+ props.ctx$.children = node.children;
67
+ props.ctx$.node = node;
68
+ let out = component(props, children);
69
+ props.ctx$.children = siblings;
70
+ props.ctx$.node = parent;
71
+ return out;
72
+ };
73
+ Object.defineProperty(cf, 'name', { value: component.name });
74
+ return cf;
75
+ }
76
+ function each(subject, apply) {
77
+ if (null == apply) {
78
+ if (Array.isArray(subject)) {
79
+ for (let fn of subject) {
80
+ fn();
81
+ }
82
+ }
83
+ }
84
+ else {
85
+ if (Array.isArray(subject)) {
86
+ return subject.map(apply);
87
+ }
88
+ else {
89
+ const entries = Object.entries(subject);
90
+ if (entries[0] && entries[0][1] && 'string' === typeof entries[0][1].name) {
91
+ entries.sort((a, b) => a.name < b.name ? 1 : b.name < a.name ? -1 : 0);
92
+ }
93
+ return entries.map((n, ...args) => apply(n[1], [0], ...args));
94
+ }
95
+ }
96
+ }
97
+ function build(topnode, ctx) {
98
+ // console.dir(topnode, { depth: null })
99
+ step(topnode, ctx);
100
+ }
101
+ function step(node, ctx) {
102
+ const op = opmap[node.kind];
103
+ if (null == op) {
104
+ throw new Error('missing op: ' + node.kind);
105
+ }
106
+ op.before(node, ctx);
107
+ if (node.children) {
108
+ for (let childnode of node.children) {
109
+ step(childnode, ctx);
110
+ }
111
+ }
112
+ op.after(node, ctx);
113
+ }
114
+ const opmap = {
115
+ project: {
116
+ before(node, ctx) {
117
+ const cproject = ctx.current.project = (ctx.current.project || {});
118
+ cproject.node = node;
119
+ },
120
+ after(_node, _ctx) {
121
+ },
122
+ },
123
+ folder: {
124
+ before(node, ctx) {
125
+ const cfolder = ctx.current.folder = (ctx.current.folder || {});
126
+ cfolder.node = node;
127
+ cfolder.path = (cfolder.path || [ctx.current.folder.parent]);
128
+ cfolder.path.push(node.name);
129
+ let fullpath = cfolder.path.join('/');
130
+ ctx.fs.mkdirSync(fullpath, { recursive: true });
131
+ },
132
+ after(_node, ctx) {
133
+ const cfolder = ctx.current.folder;
134
+ cfolder.path.length = cfolder.path.length - 1;
135
+ },
136
+ },
137
+ file: {
138
+ before(node, ctx) {
139
+ const cfile = ctx.current.file = node;
140
+ cfile.path = ctx.current.folder.path.join('/') + '/' + node.name;
141
+ cfile.content = [];
142
+ },
143
+ after(_node, ctx) {
144
+ const cfile = ctx.current.file;
145
+ const content = cfile.content.join('');
146
+ ctx.fs.writeFileSync(cfile.path, content);
147
+ },
148
+ },
149
+ content: {
150
+ before(node, ctx) {
151
+ const ccontent = ctx.current.content = node;
152
+ ctx.current.file.content.push(ccontent.content);
153
+ },
154
+ after(_node, _ctx) {
155
+ },
156
+ },
157
+ };
158
+ const Code = cmp(function Code(props) {
159
+ let src = props.arg;
160
+ props.ctx$.node.content = src;
161
+ });
162
+ const File = cmp(function File(props, children) {
163
+ props.ctx$.node.kind = 'file';
164
+ props.ctx$.node.name = props.name;
165
+ // Code('// FILE START: ' + props.name + '\n')
166
+ each(children);
167
+ // Code('// FILE END: ' + props.name + '\n')
168
+ });
169
+ const Project = cmp(function Project(props, children) {
170
+ props.ctx$.node.kind = 'project';
171
+ props.ctx$.node.name = props.name;
172
+ each(children);
173
+ });
174
+ const Folder = cmp(function Folder(props, children) {
175
+ props.ctx$.node.kind = 'folder';
176
+ props.ctx$.node.name = props.name;
177
+ each(children);
178
+ });
179
+ return {
180
+ cmp,
181
+ each,
182
+ generate,
183
+ Project,
184
+ Code,
185
+ File,
186
+ Folder,
187
+ };
188
+ }
189
+ //# sourceMappingURL=jostraca.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jostraca.js","sourceRoot":"","sources":["../src/jostraca.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,87 +1,42 @@
1
1
  {
2
2
  "name": "jostraca",
3
- "version": "0.0.9",
4
- "description": "Jostraca",
5
- "main": "lib/index.js",
6
- "bin": {
7
- "jostraca": "./bin/run"
3
+ "version": "0.1.2",
4
+ "main": "dist/jostraca.js",
5
+ "type": "commonjs",
6
+ "types": "dist/jostraca.d.ts",
7
+ "description": "Jostraca Jostraca.",
8
+ "homepage": "https://github.com/jostraca/jostraca",
9
+ "keywords": [
10
+ "jostraca",
11
+ "jostraca"
12
+ ],
13
+ "author": "Richard Rodger (http://richardrodger.com)",
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "git://github.com/jostraca/jostraca.git"
8
17
  },
9
18
  "scripts": {
10
- "postpack": "rm -f oclif.manifest.json",
11
- "posttest": "tslint -p test -t stylish",
12
- "prepack": "rm -rf lib && tsc -b && oclif-dev manifest && oclif-dev readme",
13
- "test-mocha": "mocha --forbid-only \"test/**/*.test.ts\"",
14
- "test-nyc": "nyc --extension .ts mocha --forbid-only \"test/**/*.test.ts\"",
15
- "version": "oclif-dev readme && git add README.md",
16
- "compile": "tsc jostraca.ts",
17
- "test": "lab --sourcemaps --transform node_modules/lab-transform-typescript -P lab-test -v -t 50",
18
- "prettier": "prettier --write --no-semi --single-quote *.ts *.js src/**/*.ts test/**/*.ts test/**/*.js",
19
- "tsc:w": "tsc -w -d --noEmitOnError",
20
- "tsc": "tsc -d --noEmitOnError",
21
- "coveralls": "lab -s -P test -r lcov | coveralls",
22
- "reset": "npm run clean && npm i && npm run test",
19
+ "test": "node --enable-source-maps --test dist-test",
20
+ "test-some": "node --enable-source-maps --test-name-pattern=\"$npm_config_pattern\" --test dist-test",
21
+ "watch": "tsc --build src test -w",
22
+ "build": "tsc --build src test",
23
23
  "clean": "rm -rf node_modules yarn.lock package-lock.json",
24
+ "reset": "npm run clean && npm i && npm run build && npm test",
24
25
  "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;",
25
- "repo-publish": "npm run clean && npm i --registry=http://registry.npmjs.org && npm run prettier && npm test && npm run repo-tag && npm publish --access public --registry=http://registry.npmjs.org",
26
- "repo-publish-quick": "npm run prettier && npm run tsc && npm test && npm run repo-tag && npm publish --access public --registry=http://registry.npmjs.org"
26
+ "repo-publish": "npm run clean && npm i && npm run repo-publish-quick",
27
+ "repo-publish-quick": "npm run build && npm run test && npm run repo-tag && npm publish --registry https://registry.npmjs.org --access=public"
27
28
  },
29
+ "license": "MIT",
28
30
  "files": [
29
- "LICENSE",
30
- "README.md",
31
- "jostraca.js",
32
- "jostraca.ts",
33
- "lib",
34
- "bin"
31
+ "src",
32
+ "dist",
33
+ "LICENSE"
35
34
  ],
36
- "repository": {
37
- "type": "git",
38
- "url": "git+https://github.com/jostraca/jostraca.git"
39
- },
40
- "keywords": [
41
- "jostraca"
42
- ],
43
- "author": "Richard Rodger",
44
- "license": "MIT",
45
- "bugs": {
46
- "url": "https://github.com/jostraca/jostraca/issues"
47
- },
48
- "homepage": "https://github.com/jostraca/jostraca#readme",
49
- "dependencies": {
50
- "@oclif/command": "^1.6.1",
51
- "@oclif/config": "^1.15.1",
52
- "@oclif/plugin-help": "^3.0.1",
53
- "ejs": "^3.1.3",
54
- "jsonic": "^0.3.1",
55
- "lodash.defaultsdeep": "^4.6.1",
56
- "tslib": "^2.0.0"
57
- },
58
35
  "devDependencies": {
59
- "@hapi/code": "^8.0.1",
60
- "@hapi/lab": "^22.0.4",
61
- "@oclif/dev-cli": "^1.22.2",
62
- "@oclif/test": "^1.2.6",
63
- "@oclif/tslint": "^3.1.1",
64
- "@types/chai": "^4.2.11",
65
- "@types/mocha": "^7.0.2",
66
- "@types/node": "^14.0.9",
67
- "chai": "^4.2.0",
68
- "globby": "^11.0.1",
69
- "lab-transform-typescript": "^3.0.1",
70
- "mocha": "^7.2.0",
71
- "mock-fs": "^4.12.0",
72
- "nyc": "^15.1.0",
73
- "prettier": "^2.0.5",
74
- "ts-node": "^8.10.2",
75
- "tslint": "^6.1.2",
76
- "tslint-config-prettier": "^1.18.0",
77
- "typescript": "^3.9.3"
78
- },
79
- "oclif": {
80
- "commands": "./lib/commands",
81
- "bin": "jostraca",
82
- "plugins": [
83
- "@oclif/plugin-help"
84
- ]
85
- },
86
- "types": "lib/index.d.ts"
36
+ "@hapi/code": "^9.0.3",
37
+ "@types/node": "22.0.0",
38
+ "esbuild": "^0.23.0",
39
+ "memfs": "^4.11.1",
40
+ "typescript": "^5.5.4"
41
+ }
87
42
  }
@@ -0,0 +1,261 @@
1
+ /* Copyright (c) 2024 Richard Rodger, MIT License */
2
+
3
+ import * as Fs from 'node:fs'
4
+
5
+ import { AsyncLocalStorage } from 'node:async_hooks'
6
+
7
+
8
+ type JostracaOptions = {
9
+ folder: string
10
+ fs: any
11
+ }
12
+
13
+
14
+ type Node = {
15
+ kind: string
16
+ children?: Node[]
17
+ name?: string
18
+ path?: string
19
+ content?: any[]
20
+ }
21
+
22
+
23
+ type Component = (props: any, children?: any) => void
24
+
25
+
26
+ function Jostraca() {
27
+
28
+ const GLOBAL = (global as any)
29
+ GLOBAL.jostraca = new AsyncLocalStorage()
30
+
31
+
32
+ function generate(opts: JostracaOptions, root: Function) {
33
+ const fs = opts.fs || Fs
34
+ GLOBAL.jostraca.run({
35
+ content: null,
36
+ }, () => {
37
+ root()
38
+
39
+ const ctx$ = GLOBAL.jostraca.getStore()
40
+ const node = ctx$.node
41
+
42
+ build(
43
+ node,
44
+ {
45
+ fs,
46
+ current: {
47
+ folder: {
48
+ parent: opts.folder
49
+ }
50
+ }
51
+ })
52
+ })
53
+ }
54
+
55
+
56
+ function cmp(component: Function): Component {
57
+ const cf = (props: any, children?: any) => {
58
+ props = props || {}
59
+ if (null == props || 'object' !== typeof props) {
60
+ props = { arg: props }
61
+ }
62
+ props.ctx$ = GLOBAL.jostraca.getStore()
63
+ children = 'function' === typeof children ? [children] : children
64
+
65
+ let node = {
66
+ kind: 'content',
67
+ children: []
68
+ }
69
+
70
+ const parent = props.ctx$.node = (props.ctx$.node || node)
71
+ const siblings = props.ctx$.children = (props.ctx$.children || [])
72
+ siblings.push(node)
73
+
74
+ props.ctx$.children = node.children
75
+ props.ctx$.node = node
76
+
77
+ let out = component(props, children)
78
+
79
+ props.ctx$.children = siblings
80
+ props.ctx$.node = parent
81
+
82
+ return out
83
+ }
84
+ Object.defineProperty(cf, 'name', { value: component.name })
85
+ return cf
86
+ }
87
+
88
+
89
+ function each(subject: any, apply?: any) {
90
+ if (null == apply) {
91
+ if (Array.isArray(subject)) {
92
+ for (let fn of subject) {
93
+ fn()
94
+ }
95
+ }
96
+ }
97
+ else {
98
+ if (Array.isArray(subject)) {
99
+ return subject.map(apply)
100
+ }
101
+ else {
102
+ const entries: any = Object.entries(subject)
103
+ if (entries[0] && entries[0][1] && 'string' === typeof entries[0][1].name) {
104
+ entries.sort((a: any, b: any) => a.name < b.name ? 1 : b.name < a.name ? -1 : 0)
105
+ }
106
+ return entries.map((n: any, ...args: any[]) =>
107
+ apply(n[1], [0], ...args))
108
+ }
109
+ }
110
+ }
111
+
112
+
113
+ function build(topnode: Node, ctx: any) {
114
+ // console.dir(topnode, { depth: null })
115
+ step(topnode, ctx)
116
+ }
117
+
118
+
119
+ function step(node: Node, ctx: any) {
120
+ const op = opmap[node.kind]
121
+ if (null == op) {
122
+ throw new Error('missing op: ' + node.kind)
123
+ }
124
+
125
+ op.before(node, ctx)
126
+
127
+ if (node.children) {
128
+ for (let childnode of node.children) {
129
+ step(childnode, ctx)
130
+ }
131
+ }
132
+
133
+ op.after(node, ctx)
134
+ }
135
+
136
+
137
+
138
+ const opmap: any = {
139
+
140
+ project: {
141
+ before(node: Node, ctx: any) {
142
+ const cproject: any = ctx.current.project = (ctx.current.project || {})
143
+ cproject.node = node
144
+ },
145
+
146
+ after(_node: Node, _ctx: any) {
147
+
148
+ },
149
+ },
150
+
151
+
152
+ folder: {
153
+ before(node: Node, ctx: any) {
154
+ const cfolder = ctx.current.folder = (ctx.current.folder || {})
155
+
156
+ cfolder.node = node
157
+ cfolder.path = (cfolder.path || [ctx.current.folder.parent])
158
+ cfolder.path.push(node.name)
159
+
160
+ let fullpath = cfolder.path.join('/')
161
+ ctx.fs.mkdirSync(fullpath, { recursive: true })
162
+ },
163
+
164
+
165
+ after(_node: Node, ctx: any) {
166
+ const cfolder = ctx.current.folder
167
+ cfolder.path.length = cfolder.path.length - 1
168
+ },
169
+ },
170
+
171
+
172
+ file: {
173
+ before(node: Node, ctx: any) {
174
+ const cfile = ctx.current.file = node
175
+ cfile.path = ctx.current.folder.path.join('/') + '/' + node.name
176
+ cfile.content = []
177
+ },
178
+
179
+ after(_node: Node, ctx: any) {
180
+ const cfile = ctx.current.file
181
+ const content = cfile.content.join('')
182
+ ctx.fs.writeFileSync(cfile.path, content)
183
+ },
184
+ },
185
+
186
+
187
+ content: {
188
+ before(node: Node, ctx: any) {
189
+ const ccontent = ctx.current.content = node
190
+ ctx.current.file.content.push(ccontent.content)
191
+ },
192
+
193
+ after(_node: Node, _ctx: any) {
194
+
195
+ },
196
+ },
197
+
198
+
199
+ }
200
+
201
+
202
+
203
+ const Code = cmp(function Code(props: any) {
204
+ let src = props.arg
205
+ props.ctx$.node.content = src
206
+ })
207
+
208
+
209
+ const File = cmp(function File(props: any, children: any) {
210
+ props.ctx$.node.kind = 'file'
211
+ props.ctx$.node.name = props.name
212
+
213
+ // Code('// FILE START: ' + props.name + '\n')
214
+
215
+ each(children)
216
+
217
+ // Code('// FILE END: ' + props.name + '\n')
218
+ })
219
+
220
+
221
+ const Project: Component = cmp(function Project(props: any, children: any) {
222
+ props.ctx$.node.kind = 'project'
223
+ props.ctx$.node.name = props.name
224
+
225
+ each(children)
226
+ })
227
+
228
+
229
+ const Folder = cmp(function Folder(props: any, children: any) {
230
+ props.ctx$.node.kind = 'folder'
231
+ props.ctx$.node.name = props.name
232
+
233
+ each(children)
234
+ })
235
+
236
+
237
+
238
+ return {
239
+ cmp,
240
+ each,
241
+ generate,
242
+
243
+ Project,
244
+ Code,
245
+ File,
246
+ Folder,
247
+ }
248
+
249
+
250
+ }
251
+
252
+
253
+ export type {
254
+ JostracaOptions,
255
+ Component,
256
+ }
257
+
258
+
259
+ export {
260
+ Jostraca,
261
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "compilerOptions": {
3
+ "esModuleInterop": true,
4
+ "module": "nodenext",
5
+ "noEmitOnError": true,
6
+ "outDir":"../dist",
7
+ "rootDir":".",
8
+ "resolveJsonModule": true,
9
+ "sourceMap": true,
10
+ "strict": true,
11
+ "target": "es2021",
12
+ "declaration": true,
13
+ "declarationDir": "../dist"
14
+ }
15
+ }
16
+
@@ -1,10 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /* Copyright (c) 2019 Richard Rodger and other contributors, MIT License */
4
- 'use strict'
5
-
6
- const Jostraca = require('..')
7
-
8
- const js = Jostraca()
9
-
10
- console.log(''+js)
package/bin/run DELETED
@@ -1,5 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- require('@oclif/command').run()
4
- .then(require('@oclif/command/flush'))
5
- .catch(require('@oclif/errors/handle'))
package/bin/run.cmd DELETED
@@ -1,3 +0,0 @@
1
- @echo off
2
-
3
- node "%~dp0\run" %*
package/jostraca.js DELETED
@@ -1,15 +0,0 @@
1
- /* Copyright © 2019 Richard Rodger and other contributors, MIT License. */
2
- var Pkg = require('./package.json')
3
- var Seneca = require('seneca')
4
- module.exports = make_jostraca
5
- function make_jostraca() {
6
- return Jostraca()
7
- }
8
- function Jostraca() {
9
- var self = {}
10
- self.toString = function () {
11
- return 'jostraca@' + Pkg.version
12
- }
13
- self['seneca'] = Seneca()
14
- return self
15
- }
package/jostraca.ts DELETED
@@ -1,19 +0,0 @@
1
- /* Copyright © 2019 Richard Rodger and other contributors, MIT License. */
2
-
3
- const Pkg = require('./package.json')
4
-
5
- module.exports = make_jostraca
6
-
7
- function make_jostraca() {
8
- return Jostraca()
9
- }
10
-
11
- function Jostraca() {
12
- var self = {}
13
-
14
- self.toString = function () {
15
- return 'jostraca@' + Pkg.version
16
- }
17
-
18
- return self
19
- }
@@ -1,12 +0,0 @@
1
- import { Command, flags } from '@oclif/command';
2
- export default class Generate extends Command {
3
- static description: string;
4
- static examples: string[];
5
- static flags: {
6
- config: flags.IOptionFlag<string | undefined>;
7
- };
8
- static args: {
9
- name: string;
10
- }[];
11
- run(): Promise<void>;
12
- }
@@ -1,41 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const Path = require("path");
4
- const command_1 = require("@oclif/command");
5
- const repo_1 = require("../util/repo");
6
- // TODO: better resolver needed
7
- let config = {
8
- basefolder: process.cwd() + '/jostraca',
9
- };
10
- let Generate = /** @class */ (() => {
11
- class Generate extends command_1.Command {
12
- async run() {
13
- const { args, flags } = this.parse(Generate);
14
- const group = args.group || 'all';
15
- const repo = args.repo || '';
16
- const basefolder = Path.resolve(flags.config || config.basefolder);
17
- const systemfolder = Path.dirname(basefolder);
18
- const repofolder = Path.dirname(systemfolder);
19
- const spec = {
20
- group,
21
- repo,
22
- basefolder,
23
- repofolder,
24
- };
25
- // console.log('JOSTRACA GENERATE', spec)
26
- repo_1.generate(spec);
27
- }
28
- }
29
- Generate.description = 'Generate repo files';
30
- Generate.examples = [
31
- `$ jostraca generate`,
32
- `$ jostraca generate [group]`,
33
- `$ jostraca generate [group] [repo]`,
34
- ];
35
- Generate.flags = {
36
- config: command_1.flags.string({ char: 'c', description: 'config folder' }),
37
- };
38
- Generate.args = [{ name: 'group' }, { name: 'repo' }];
39
- return Generate;
40
- })();
41
- exports.default = Generate;
@@ -1,13 +0,0 @@
1
- import { Command, flags } from '@oclif/command';
2
- export default class Goodbye extends Command {
3
- static description: string;
4
- static flags: {
5
- help: import("@oclif/parser/lib/flags").IBooleanFlag<void>;
6
- name: flags.IOptionFlag<string | undefined>;
7
- force: import("@oclif/parser/lib/flags").IBooleanFlag<boolean>;
8
- };
9
- static args: {
10
- name: string;
11
- }[];
12
- run(): Promise<void>;
13
- }
@@ -1,26 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const command_1 = require("@oclif/command");
4
- let Goodbye = /** @class */ (() => {
5
- class Goodbye extends command_1.Command {
6
- async run() {
7
- const { args, flags } = this.parse(Goodbye);
8
- const name = flags.name || 'world';
9
- this.log(`hello ${name} from /root/cli/tmp/examples/example-multi-ts/src/commands/goodbye.ts`);
10
- if (args.file && flags.force) {
11
- this.log(`you input --force and --file: ${args.file}`);
12
- }
13
- }
14
- }
15
- Goodbye.description = 'describe the command here';
16
- Goodbye.flags = {
17
- help: command_1.flags.help({ char: 'h' }),
18
- // flag with a value (-n, --name=VALUE)
19
- name: command_1.flags.string({ char: 'n', description: 'name to print' }),
20
- // flag with no value (-f, --force)
21
- force: command_1.flags.boolean({ char: 'f' }),
22
- };
23
- Goodbye.args = [{ name: 'file' }];
24
- return Goodbye;
25
- })();
26
- exports.default = Goodbye;
package/lib/index.d.ts DELETED
@@ -1 +0,0 @@
1
- export { run } from '@oclif/command';
package/lib/index.js DELETED
@@ -1,4 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- var command_1 = require("@oclif/command");
4
- Object.defineProperty(exports, "run", { enumerable: true, get: function () { return command_1.run; } });
@@ -1,55 +0,0 @@
1
- interface Repo {
2
- name: string;
3
- order: number;
4
- props: object;
5
- }
6
- declare type MapRepo = Repo[] & {
7
- [key: string]: Repo;
8
- };
9
- interface Template {
10
- name: string;
11
- path: string;
12
- parent_folders: string[];
13
- text: string;
14
- kind: string;
15
- render?: (ctxt: any) => any;
16
- }
17
- interface TemplateContext {
18
- name: string;
19
- version: string;
20
- year: number;
21
- prefix: string;
22
- suffix: string;
23
- parent_folders: string[];
24
- props: object;
25
- slots?: {
26
- [key: string]: string;
27
- };
28
- }
29
- interface GenerateSpec {
30
- group: string;
31
- repo: string;
32
- basefolder: string;
33
- repofolder: string;
34
- }
35
- interface GroupSpec {
36
- name: string;
37
- repos: MapRepo;
38
- }
39
- interface RepoSpec {
40
- version: string;
41
- }
42
- declare const intern: {
43
- generate(spec: GenerateSpec): void;
44
- render_template(tm: Template, ctxt: TemplateContext, text: string): any;
45
- load_templates(folder: string): Template[];
46
- parse_templates(templates: Template[]): void;
47
- load_repo_spec(spec: GenerateSpec, repo: Repo): RepoSpec;
48
- load_repo_groups(folder: string): {
49
- [group: string]: GroupSpec;
50
- };
51
- parse_repo_list(text: string): Repo[];
52
- deep(...rest: any[]): any;
53
- };
54
- declare function generate(spec: GenerateSpec): void;
55
- export { generate, intern };
package/lib/util/repo.js DELETED
@@ -1,231 +0,0 @@
1
- "use strict";
2
- // Copyright © 2019 Richard Rodger and other contributors, MIT License.
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.intern = exports.generate = void 0;
5
- const Fs = require("fs");
6
- const Path = require("path");
7
- //import { Jsonic } from 'jsonic'
8
- const Jsonic = require('jsonic');
9
- const Ejs = require('ejs');
10
- const LodashDefaultsDeep = require('lodash.defaultsdeep');
11
- const intern = {
12
- generate(spec) {
13
- let groups = intern.load_repo_groups(spec.basefolder + '/repos');
14
- let all_group = groups.all;
15
- let group = groups[spec.group];
16
- let template_folder = spec.basefolder + '/templates';
17
- let templates = intern.load_templates(template_folder);
18
- let repos = group.repos.filter((repo) => {
19
- return '' === spec.repo || repo.name === spec.repo;
20
- });
21
- for (let rI = 0; rI < repos.length; rI++) {
22
- let repo = repos[rI];
23
- let repospec = intern.load_repo_spec(spec, repo);
24
- // inherit props from 'all' group
25
- let all_repo = all_group.repos[repo.name] || {};
26
- let props = intern.deep(all_repo.props, repo.props);
27
- let skip = false;
28
- for (let template of templates) {
29
- skip = false;
30
- let path = spec.repofolder +
31
- '/' +
32
- repo.name +
33
- '/' +
34
- template.path.substring(template_folder.length + 1);
35
- while (path !== (path = path.replace('%NAME%', repo.name))) { }
36
- let excludes = ('string' === typeof props.exclude$
37
- ? [props.exclude$]
38
- : props.exclude$) || [];
39
- for (let exclude of excludes) {
40
- skip = skip || -1 !== path.indexOf(exclude);
41
- }
42
- if (!skip) {
43
- let text = '';
44
- if (Fs.existsSync(path)) {
45
- text = Fs.readFileSync(path).toString();
46
- }
47
- let repo_name_prefix = '';
48
- let repo_name_suffix = '';
49
- let m = repo.name.match(/^(.*)-([^-]*?)$/);
50
- if (m) {
51
- repo_name_prefix = m[1];
52
- repo_name_suffix = m[2];
53
- }
54
- let ctxt = {
55
- name: repo.name,
56
- version: repospec.version,
57
- prefix: repo_name_prefix,
58
- suffix: repo_name_suffix,
59
- year: new Date().getFullYear(),
60
- parent_folders: template.parent_folders,
61
- props,
62
- };
63
- let out = intern.render_template(template, ctxt, text);
64
- let folder_part = Path.dirname(path);
65
- Fs.mkdirSync(folder_part, { recursive: true });
66
- Fs.writeFileSync(path, out);
67
- console_log('SAVE: ' + path);
68
- }
69
- else {
70
- console_log('skip: ' + path);
71
- }
72
- }
73
- }
74
- },
75
- render_template(tm, ctxt, text) {
76
- text = text || '';
77
- ctxt.slots = {};
78
- // NOTE: slot *MUST* have newline prefix and suffix
79
- // This supports syntax comments in source code
80
- let jostraca_slot_re = /[^\r\n]*?JOSTRACA-SLOT-START:([\S]+)[^\r\n]*[\r\n]?([\s\S]*?)[\r\n]?[^\r\n]*JOSTRACA-SLOT-END:\1[^\r\n]*/;
81
- let m = null;
82
- let last = 0;
83
- let index;
84
- while ((m = jostraca_slot_re.exec(text.substring(last)))) {
85
- //console.log(m)
86
- let slot_full = m[0];
87
- let slot_name = m[1];
88
- // Need to preserve slot markers on re-insert
89
- ctxt.slots[slot_name] = slot_full;
90
- index = m.index;
91
- // keep looking from end of last match
92
- last = last + index + slot_full.length;
93
- }
94
- let render_text = tm.render(ctxt);
95
- let out = render_text;
96
- let jostraca_inject_re = /(.*?JOSTRACA-INJECT-START.*?)([\r\n])[\s\S]*?([^\r\n]*JOSTRACA-INJECT-END.*)/;
97
- m = jostraca_inject_re.exec(text);
98
- //console.log('INJECT MATCH',m)
99
- if (m) {
100
- out = text.replace(m[0], m[1] + m[2] + render_text + m[3]);
101
- }
102
- return out;
103
- },
104
- load_templates(folder) {
105
- let found = [];
106
- walk(folder, [], found);
107
- intern.parse_templates(found);
108
- return found;
109
- function walk(folder, parent_folders, found) {
110
- let files = Fs.readdirSync(folder).filter((file_name) => {
111
- return !file_name.endsWith('~');
112
- });
113
- for (let file of files) {
114
- let path = folder + '/' + file;
115
- let entrystat = Fs.lstatSync(path);
116
- if (entrystat.isFile()) {
117
- let m = file.match(/\.([^.]+)$/);
118
- let kind = (m ? m[1] : '').toLowerCase();
119
- found.push({
120
- path,
121
- parent_folders,
122
- kind,
123
- name: file,
124
- text: Fs.readFileSync(path).toString(),
125
- });
126
- }
127
- else {
128
- // NOTE: parent folders ordered by ancestor ascending,
129
- // and thus opposite to folder path order. This is more
130
- // useful for immediate parent folder name conventions
131
- let child_parents = [file].concat(parent_folders);
132
- walk(path, child_parents, found);
133
- }
134
- }
135
- }
136
- },
137
- parse_templates(templates) {
138
- for (let template of templates) {
139
- let ejs_render = Ejs.compile(template.text, {});
140
- template.render = function (ctxt) {
141
- return ejs_render(ctxt);
142
- };
143
- }
144
- },
145
- load_repo_spec(spec, repo) {
146
- let version = '';
147
- let pkg_path = spec.repofolder + '/' + repo.name + '/package.json';
148
- if (Fs.existsSync(pkg_path)) {
149
- let pkg = require(pkg_path);
150
- version = pkg.version;
151
- }
152
- let repospec = {
153
- version,
154
- };
155
- return repospec;
156
- },
157
- load_repo_groups(folder) {
158
- let files = Fs.readdirSync(folder);
159
- files = files.filter((entry) => {
160
- // let entrystat = Fs.lstatSync(folder + '/' + entry)
161
- return (
162
- // entrystat.isFile() &&
163
- !entry.startsWith('.') && !entry.endsWith('~'));
164
- });
165
- let groups = {};
166
- for (let groupname of files) {
167
- let group_def_loc = folder + '/' + groupname;
168
- let is_folder = Fs.lstatSync(group_def_loc).isDirectory();
169
- let grouptext = '';
170
- // location is a folder, expect groupname.list file
171
- if (is_folder) {
172
- let groupfile = group_def_loc + '/' + groupname + '.list';
173
- if (Fs.existsSync(groupfile)) {
174
- grouptext = Fs.readFileSync(groupfile).toString();
175
- }
176
- }
177
- // location is a file
178
- else if (Fs.existsSync(group_def_loc)) {
179
- grouptext = Fs.readFileSync(group_def_loc).toString();
180
- }
181
- // try .list suffix
182
- else {
183
- grouptext = Fs.readFileSync(group_def_loc + '.list').toString();
184
- }
185
- let repolist = intern.parse_repo_list(grouptext);
186
- // index by repo name also
187
- repolist.forEach((repo) => {
188
- repolist[repo.name] = repo;
189
- });
190
- groups[groupname] = {
191
- repos: repolist,
192
- name: groupname,
193
- };
194
- }
195
- return groups;
196
- },
197
- parse_repo_list(text) {
198
- let repo_lines = text.split('\n').filter((line) => '' !== line);
199
- let order = 0;
200
- let repos = repo_lines
201
- .map((line) => {
202
- let m = line.match(/^([^#\.\s][^\s]*)(\s+.*)?$/);
203
- let name = null;
204
- let props_str = null;
205
- let props = null;
206
- if (m) {
207
- name = m[1];
208
- props_str = m[2];
209
- props = props_str ? Jsonic(props_str.substring(1)) : {};
210
- return { name, order: order++, props };
211
- }
212
- return null;
213
- })
214
- .filter((repo) => null !== repo);
215
- return repos;
216
- },
217
- // NOTE: treats arrays as if objects where indexes are keys - this is desired
218
- deep(...rest) {
219
- rest = rest.reverse();
220
- rest.unshift({});
221
- return LodashDefaultsDeep.apply(null, rest);
222
- },
223
- };
224
- exports.intern = intern;
225
- function console_log(...rest) {
226
- console.log(...rest);
227
- }
228
- function generate(spec) {
229
- return intern.generate(spec);
230
- }
231
- exports.generate = generate;