pinstripe 0.7.0 → 0.11.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/README.md +1 -1
- package/cli.js +8 -3
- package/lib/async_path_builder.js +38 -39
- package/lib/async_path_builder.test.js +27 -0
- package/lib/base.js +51 -17
- package/lib/base.test.js +80 -0
- package/lib/client.js +49 -0
- package/lib/command.js +69 -0
- package/lib/commands/_importer.js +1 -3
- package/lib/commands/create_database.js +2 -0
- package/lib/commands/drop_database.js +2 -0
- package/lib/commands/generate_command.js +32 -0
- package/lib/commands/generate_migration.js +45 -0
- package/lib/commands/generate_model.js +44 -0
- package/lib/commands/generate_project.js +49 -0
- package/lib/commands/generate_service.js +32 -0
- package/lib/commands/generate_static_site.js +79 -0
- package/lib/commands/generate_view.js +34 -0
- package/lib/commands/generate_widget.js +36 -0
- package/lib/commands/init_database.js +6 -0
- package/lib/commands/list_commands.js +14 -0
- package/lib/commands/list_migrations.js +14 -0
- package/lib/commands/list_models.js +14 -0
- package/lib/commands/list_services.js +15 -0
- package/lib/commands/list_views.js +14 -0
- package/lib/commands/list_widgets.js +14 -0
- package/lib/commands/migrate_database.js +2 -0
- package/lib/commands/reset_database.js +5 -0
- package/lib/commands/seed_database.js +4 -0
- package/lib/commands/{start_console.server.js → start_console.js} +8 -7
- package/lib/commands/start_server.js +76 -0
- package/lib/constants.js +21 -0
- package/lib/database/column.js +94 -0
- package/lib/database/constants.js +84 -0
- package/lib/database/migration.js +74 -0
- package/lib/database/migrator.js +38 -0
- package/lib/database/row.js +278 -0
- package/lib/database/sql.js +75 -0
- package/lib/database/table.js +488 -0
- package/lib/database/union.js +180 -0
- package/lib/database.js +197 -0
- package/lib/environment.js +29 -25
- package/lib/event_wrapper.js +26 -25
- package/lib/hookable.js +21 -19
- package/lib/html.js +60 -58
- package/lib/import_all.js +17 -17
- package/lib/index.js +19 -10
- package/lib/inflector.js +162 -160
- package/lib/initialize.client.js +25 -23
- package/lib/migrations/1627976184_create_user.js +9 -0
- package/lib/migrations/1628057822_create_session.js +7 -0
- package/lib/migrations/_importer.js +2 -0
- package/lib/models/_importer.js +2 -0
- package/lib/models/session.js +9 -0
- package/lib/models/user.js +45 -0
- package/lib/node_wrapper.js +426 -246
- package/lib/overload.js +1 -0
- package/lib/project.js +36 -38
- package/lib/registrable.js +80 -42
- package/lib/service_factory.js +90 -47
- package/lib/services/_importer.js +2 -0
- package/lib/services/args.js +2 -0
- package/lib/services/cli_utils.js +71 -0
- package/lib/services/config.js +9 -0
- package/lib/services/cookies.js +20 -0
- package/lib/services/database.js +12 -0
- package/lib/services/fetch.js +99 -0
- package/lib/services/fork_environment.js +16 -0
- package/lib/services/fs_builder.js +130 -0
- package/lib/services/global.js +9 -0
- package/lib/services/params.js +2 -0
- package/lib/services/project.js +4 -0
- package/lib/services/read_file.js +6 -0
- package/lib/services/render_file.js +9 -0
- package/lib/services/render_form.js +223 -0
- package/lib/services/render_html.js +6 -0
- package/lib/services/render_list.js +58 -0
- package/lib/services/render_markdown.js +6 -0
- package/lib/services/render_table.js +68 -0
- package/lib/services/render_view.js +18 -0
- package/lib/services/reset_environment.js +19 -0
- package/lib/services/run_command.js +9 -0
- package/lib/services/session.js +9 -0
- package/lib/services/view.js +4 -0
- package/lib/string_reader.js +20 -22
- package/lib/thatify.js +6 -0
- package/lib/url.js +77 -76
- package/lib/url.test.js +5 -1
- package/lib/validatable.js +60 -48
- package/lib/view.js +121 -2
- package/lib/views/_importer.js +1 -3
- package/lib/views/_layout.js +51 -0
- package/lib/views/bundle.css +10384 -0
- package/lib/views/bundle.css.map +1 -0
- package/lib/views/bundle.js +37 -0
- package/lib/views/sign_in.js +44 -0
- package/lib/views/sign_out.js +15 -0
- package/lib/virtual_node.js +125 -174
- package/lib/widgets/_importer.js +1 -3
- package/lib/widgets/frame.client.js +124 -0
- package/lib/widgets/internal/actions.client.js +51 -0
- package/lib/widgets/internal/document.client.js +56 -0
- package/lib/widgets/internal/markdown_editor.client.js +26 -0
- package/lib/widgets/internal/overlay.client.js +43 -0
- package/lib/widgets/{progress_bar.js → internal/progress_bar.client.js} +10 -3
- package/lib/widgets/trigger.client.js +20 -0
- package/package.json +16 -11
- package/pinstripe.scss +2 -0
- package/lib/command.server.js +0 -34
- package/lib/commands/create_database.server.js +0 -6
- package/lib/commands/drop_database.server.js +0 -6
- package/lib/commands/generate_command.server.js +0 -42
- package/lib/commands/generate_controller.server.js +0 -48
- package/lib/commands/generate_migration.server.js +0 -50
- package/lib/commands/generate_model.server.js +0 -50
- package/lib/commands/generate_project.server.js +0 -62
- package/lib/commands/generate_service.server.js +0 -42
- package/lib/commands/generate_view.server.js +0 -49
- package/lib/commands/generate_widget.server.js +0 -38
- package/lib/commands/init_database.server.js +0 -7
- package/lib/commands/list_commands.server.js +0 -15
- package/lib/commands/list_controllers.server.js +0 -15
- package/lib/commands/list_migrations.server.js +0 -15
- package/lib/commands/list_models.server.js +0 -15
- package/lib/commands/list_services.server.js +0 -15
- package/lib/commands/list_views.server.js +0 -15
- package/lib/commands/list_widgets.server.js +0 -15
- package/lib/commands/migrate_database.server.js +0 -7
- package/lib/commands/reset_database.server.js +0 -8
- package/lib/commands/start_server.server.js +0 -48
- package/lib/controller.js +0 -6
- package/lib/controllers/bundle.server.js +0 -61
- package/lib/database/column.server.js +0 -100
- package/lib/database/migration.server.js +0 -35
- package/lib/database/migrator.server.js +0 -40
- package/lib/database/row.server.js +0 -173
- package/lib/database/sql.server.js +0 -73
- package/lib/database/table.server.js +0 -409
- package/lib/database/union.server.js +0 -84
- package/lib/database.server.js +0 -181
- package/lib/generate_css.js +0 -39
- package/lib/renderable.js +0 -43
- package/lib/service_factories/_importer.js +0 -4
- package/lib/service_factories/args.server.js +0 -6
- package/lib/service_factories/camelize.js +0 -8
- package/lib/service_factories/capitalize.js +0 -8
- package/lib/service_factories/cli_utils.server.js +0 -76
- package/lib/service_factories/config.js +0 -13
- package/lib/service_factories/dasherize.js +0 -8
- package/lib/service_factories/database.server.js +0 -9
- package/lib/service_factories/fetch.js +0 -87
- package/lib/service_factories/fork_environment.js +0 -13
- package/lib/service_factories/fs_builder.server.js +0 -132
- package/lib/service_factories/params.js +0 -6
- package/lib/service_factories/pascalize.js +0 -8
- package/lib/service_factories/pluralize.js +0 -8
- package/lib/service_factories/project.js +0 -8
- package/lib/service_factories/render_controller.js +0 -11
- package/lib/service_factories/render_html.js +0 -8
- package/lib/service_factories/render_view.js +0 -11
- package/lib/service_factories/reset_environment.js +0 -21
- package/lib/service_factories/run_command.server.js +0 -11
- package/lib/service_factories/singularize.js +0 -8
- package/lib/service_factories/snakeify.js +0 -8
- package/lib/service_factories/uncapitalize.js +0 -8
- package/lib/views/layout.js +0 -13
- package/lib/widgets/anchor.js +0 -48
- package/lib/widgets/document.js +0 -38
- package/lib/widgets/form.js +0 -58
- package/lib/widgets/frame.js +0 -69
- package/lib/widgets/input.js +0 -13
- package/lib/widgets/modal.js +0 -20
- package/lib/widgets/script.js +0 -7
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
## What is Pinstripe?
|
|
5
5
|
|
|
6
|
-
Pinstripe is a fullstack JavaScript web framework for Node.js
|
|
6
|
+
Pinstripe is a fullstack JavaScript web framework for Node.js.
|
|
7
7
|
|
|
8
8
|
## License
|
|
9
9
|
|
package/cli.js
CHANGED
|
@@ -4,7 +4,7 @@ import { spawn } from 'child_process';
|
|
|
4
4
|
|
|
5
5
|
import { importAll } from './lib/import_all.js';
|
|
6
6
|
import { project } from './lib/project.js';
|
|
7
|
-
import { Command } from './lib/command.
|
|
7
|
+
import { Command } from './lib/command.js';
|
|
8
8
|
import { Environment } from './lib/environment.js';
|
|
9
9
|
|
|
10
10
|
(async () => {
|
|
@@ -35,7 +35,12 @@ import { Environment } from './lib/environment.js';
|
|
|
35
35
|
});
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
const { runCommand } = Environment.new();
|
|
39
|
-
|
|
38
|
+
const { runCommand, resetEnvironment } = Environment.new();
|
|
39
|
+
try {
|
|
40
|
+
await runCommand(...args);
|
|
41
|
+
} catch(e) {
|
|
42
|
+
console.error(e);
|
|
43
|
+
}
|
|
44
|
+
await resetEnvironment();
|
|
40
45
|
}
|
|
41
46
|
})();
|
|
@@ -1,53 +1,52 @@
|
|
|
1
1
|
|
|
2
2
|
import { Base } from './base.js';
|
|
3
3
|
|
|
4
|
-
export const AsyncPathBuilder = Base.extend().
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
},
|
|
4
|
+
export const AsyncPathBuilder = Base.extend().include({
|
|
5
|
+
initialize(startObject, path = []){
|
|
6
|
+
this._startObject = startObject;
|
|
7
|
+
this._path = path;
|
|
8
|
+
},
|
|
10
9
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
__getMissing(name){
|
|
11
|
+
return new this.constructor(this._startObject, [...this._path, name ]);
|
|
12
|
+
},
|
|
14
13
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const name = path[path.length - 1][0];
|
|
19
|
-
|
|
20
|
-
return new this.constructor(this._startObject, path);
|
|
21
|
-
},
|
|
14
|
+
__call(...args){
|
|
15
|
+
return new this.constructor(this._startObject, [...this._path, args ]);
|
|
16
|
+
},
|
|
22
17
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
async log(){
|
|
28
|
-
try {
|
|
29
|
-
console.log(
|
|
30
|
-
await unwrap(this._startObject, [...this._path])
|
|
31
|
-
);
|
|
32
|
-
} catch (e) {
|
|
33
|
-
console.error(e);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
})
|
|
37
|
-
);
|
|
18
|
+
then(...args){
|
|
19
|
+
return unwrap(this._startObject, [...this._path]).then(...args);
|
|
20
|
+
}
|
|
21
|
+
});
|
|
38
22
|
|
|
39
|
-
async
|
|
23
|
+
const unwrap = async (startObject, path) => {
|
|
40
24
|
let out = await startObject;
|
|
25
|
+
let originalPath = [ ...path ];
|
|
41
26
|
while(path.length){
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
27
|
+
if(out == undefined){
|
|
28
|
+
const completedPath = originalPath.slice(0, originalPath.length - path.length);
|
|
29
|
+
throw new Error(`Can't unwrap object${formatPath(originalPath)} (object${formatPath(completedPath)} is undefined)`);
|
|
30
|
+
}
|
|
31
|
+
if(typeof path[0] == 'string'){
|
|
32
|
+
const name = path.shift();
|
|
33
|
+
if(Array.isArray(path[0])){
|
|
34
|
+
const args = path.shift();
|
|
35
|
+
if(typeof out[name] != 'function'){
|
|
36
|
+
out = await out[name];
|
|
37
|
+
path.unshift(args);
|
|
38
|
+
} else {
|
|
39
|
+
out = await out[name](...args);
|
|
40
|
+
}
|
|
41
|
+
} else {
|
|
42
|
+
out = await out[name];
|
|
49
43
|
}
|
|
44
|
+
} else {
|
|
45
|
+
const args = path.shift();
|
|
46
|
+
out = await out(...args);
|
|
50
47
|
}
|
|
51
48
|
}
|
|
52
49
|
return out;
|
|
53
50
|
};
|
|
51
|
+
|
|
52
|
+
const formatPath = path => path.map(segment => typeof segment == 'string' ? `.${segment}` : '(...)').join('')
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
|
|
2
|
+
import { AsyncPathBuilder } from './async_path_builder.js';
|
|
3
|
+
|
|
4
|
+
test('AsyncPathBuilder (1)', async () => {
|
|
5
|
+
const hello = AsyncPathBuilder.new((name = 'world') => `hello ${name}`);
|
|
6
|
+
|
|
7
|
+
expect(hello instanceof AsyncPathBuilder).toBe(true);
|
|
8
|
+
expect(await hello()).toBe("hello world");
|
|
9
|
+
expect(await hello().length).toBe(11);
|
|
10
|
+
expect(await hello('jody')).toBe("hello jody");
|
|
11
|
+
expect(await hello('jody').length).toBe(10);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
test('AsyncPathBuilder (2)', async () => {
|
|
15
|
+
const foo = AsyncPathBuilder.new({
|
|
16
|
+
async bar(){
|
|
17
|
+
return this;
|
|
18
|
+
},
|
|
19
|
+
|
|
20
|
+
async baz(){
|
|
21
|
+
return "boo";
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
expect(await foo.bar().baz()).toBe("boo");
|
|
26
|
+
expect(await foo.bar().baz().length).toBe(3);
|
|
27
|
+
});
|
package/lib/base.js
CHANGED
|
@@ -3,23 +3,17 @@ import { getAllProps } from './get_all_props.js';
|
|
|
3
3
|
|
|
4
4
|
export class Base {
|
|
5
5
|
|
|
6
|
-
static
|
|
7
|
-
|
|
8
|
-
return this;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
static staticProps(...args){
|
|
12
|
-
assignProps(this, ...args);
|
|
13
|
-
return this;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
static props(...args){
|
|
17
|
-
assignProps(this.prototype, ...args);
|
|
18
|
-
return this;
|
|
6
|
+
static assignProps(...args){
|
|
7
|
+
return assignProps(this, ...args);
|
|
19
8
|
}
|
|
20
9
|
|
|
21
10
|
static include(...args){
|
|
22
|
-
|
|
11
|
+
args.forEach(arg => {
|
|
12
|
+
if(typeof arg.meta == 'function'){
|
|
13
|
+
arg.meta.call(this);
|
|
14
|
+
}
|
|
15
|
+
this.prototype.assignProps(arg, name => name != 'meta');
|
|
16
|
+
});
|
|
23
17
|
return this;
|
|
24
18
|
}
|
|
25
19
|
|
|
@@ -30,6 +24,10 @@ export class Base {
|
|
|
30
24
|
static extend(){
|
|
31
25
|
return class extends this {};
|
|
32
26
|
}
|
|
27
|
+
|
|
28
|
+
static get parent(){
|
|
29
|
+
return this.__proto__;
|
|
30
|
+
}
|
|
33
31
|
|
|
34
32
|
constructor(...args){
|
|
35
33
|
let out = this.initialize(...args);
|
|
@@ -43,6 +41,10 @@ export class Base {
|
|
|
43
41
|
|
|
44
42
|
}
|
|
45
43
|
|
|
44
|
+
assignProps(...args){
|
|
45
|
+
return assignProps(this, ...args);
|
|
46
|
+
}
|
|
47
|
+
|
|
46
48
|
get __proxy(){
|
|
47
49
|
let out = this;
|
|
48
50
|
|
|
@@ -51,10 +53,11 @@ export class Base {
|
|
|
51
53
|
const isGetMissingMethod = typeof this.__getMissing == 'function';
|
|
52
54
|
const isSetMissingMethod = typeof this.__setMissing == 'function';
|
|
53
55
|
const isCallMethod = typeof this.__call == 'function';
|
|
56
|
+
const isKeysMethod = typeof this.__keys == 'function';
|
|
54
57
|
|
|
55
58
|
if(isGetMissingMethod || isCallMethod){
|
|
56
59
|
traps.get = (target, name) => {
|
|
57
|
-
if(getAllProps(this).includes(name)){
|
|
60
|
+
if(getAllProps(this).includes(name) || name.match(/^_/)){
|
|
58
61
|
return this[name];
|
|
59
62
|
}
|
|
60
63
|
if(isGetMissingMethod && name != 'then'){
|
|
@@ -64,7 +67,7 @@ export class Base {
|
|
|
64
67
|
}
|
|
65
68
|
if(isSetMissingMethod || isCallMethod){
|
|
66
69
|
traps.set = (target, name, value) => {
|
|
67
|
-
if(getAllProps(this).includes(name)){
|
|
70
|
+
if(getAllProps(this).includes(name) || name.match(/^_/)){
|
|
68
71
|
this[name] = value;
|
|
69
72
|
} else if(isSetMissingMethod){
|
|
70
73
|
this.__setMissing(name, value);
|
|
@@ -74,10 +77,23 @@ export class Base {
|
|
|
74
77
|
}
|
|
75
78
|
if(isCallMethod){
|
|
76
79
|
out = () => {};
|
|
80
|
+
out.__proto__ = this;
|
|
77
81
|
traps.apply = (target, thisArg, args) => {
|
|
78
82
|
return this.__call(...args);
|
|
79
83
|
};
|
|
80
84
|
}
|
|
85
|
+
if(isKeysMethod){
|
|
86
|
+
traps.ownKeys = () => {
|
|
87
|
+
return this.__keys();
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
traps.getOwnPropertyDescriptor = (target, prop) => {
|
|
91
|
+
return {
|
|
92
|
+
enumerable: true,
|
|
93
|
+
configurable: true,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
}
|
|
81
97
|
|
|
82
98
|
if(Object.keys(traps).length){
|
|
83
99
|
out = new Proxy(out, traps);
|
|
@@ -93,9 +109,27 @@ export class Base {
|
|
|
93
109
|
};
|
|
94
110
|
|
|
95
111
|
const assignProps = (target, ...sources) => {
|
|
112
|
+
const fn = typeof sources[sources.length - 1] == 'function' ? sources.pop() : () => true;
|
|
113
|
+
|
|
96
114
|
sources.forEach(source => {
|
|
97
115
|
Object.getOwnPropertyNames(source).forEach(name => {
|
|
98
|
-
|
|
116
|
+
if(!fn(name)){
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
const descriptor = { ...Object.getOwnPropertyDescriptor(source, name) };
|
|
120
|
+
const { get } = descriptor;
|
|
121
|
+
if(get){
|
|
122
|
+
descriptor.get = function(...args){
|
|
123
|
+
return get.call(this.__proxy || this, ...args);
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
const { set } = descriptor;
|
|
127
|
+
if(set){
|
|
128
|
+
descriptor.set = function(...args){
|
|
129
|
+
set.call(this.__proxy || this, ...args);
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
Object.defineProperty(target, name, descriptor);
|
|
99
133
|
});
|
|
100
134
|
});
|
|
101
135
|
return target;
|
package/lib/base.test.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
|
|
2
|
+
import { Base } from './base.js';
|
|
3
|
+
|
|
4
|
+
test(`Base - initialize won't call magic methods`, async () => {
|
|
5
|
+
const fixture = Base.extend().include({
|
|
6
|
+
initialize(){
|
|
7
|
+
this.foo = 'bar';
|
|
8
|
+
},
|
|
9
|
+
|
|
10
|
+
__getMissing(name){
|
|
11
|
+
return 'baz';
|
|
12
|
+
}
|
|
13
|
+
}).new();
|
|
14
|
+
|
|
15
|
+
expect(fixture.bar).toBe("baz");
|
|
16
|
+
expect(fixture.foo).toBe("bar");
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
test('Base - magic methods should callable from getters', async () => {
|
|
20
|
+
const fixture = Base.extend().include({
|
|
21
|
+
get foo(){
|
|
22
|
+
return this.bar;
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
__getMissing(name){
|
|
26
|
+
return 'baz';
|
|
27
|
+
}
|
|
28
|
+
}).new();
|
|
29
|
+
|
|
30
|
+
expect(fixture.bar).toBe("baz");
|
|
31
|
+
expect(fixture.foo).toBe("baz");
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
test(`Base - properties starting with an underscore won't invoke a magic method`, async () => {
|
|
35
|
+
const fixture = Base.extend().include({
|
|
36
|
+
get foo(){
|
|
37
|
+
if(!this._foo){
|
|
38
|
+
this._foo = 'bar';
|
|
39
|
+
}
|
|
40
|
+
return this._foo;
|
|
41
|
+
},
|
|
42
|
+
|
|
43
|
+
__getMissing(name){
|
|
44
|
+
return 'baz';
|
|
45
|
+
},
|
|
46
|
+
|
|
47
|
+
__setMissing(name, value){
|
|
48
|
+
|
|
49
|
+
}
|
|
50
|
+
}).new();
|
|
51
|
+
|
|
52
|
+
expect(fixture.bar).toBe("baz");
|
|
53
|
+
expect(fixture.foo).toBe("bar");
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
test(`Base - if the __call has been defined getting/setting still works`, async () => {
|
|
57
|
+
const fixture = Base.extend().include({
|
|
58
|
+
initialize(){
|
|
59
|
+
this.foo = "bar";
|
|
60
|
+
},
|
|
61
|
+
|
|
62
|
+
__call(...args){
|
|
63
|
+
|
|
64
|
+
}
|
|
65
|
+
}).new();
|
|
66
|
+
|
|
67
|
+
expect(fixture.foo).toBe("bar");
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
test(`Base - can produce dynamic keys`, () => {
|
|
71
|
+
const fixture = Base.extend().include({
|
|
72
|
+
baz: 'hello world',
|
|
73
|
+
|
|
74
|
+
__keys(){
|
|
75
|
+
return ['foo', 'bar'];
|
|
76
|
+
}
|
|
77
|
+
}).new();
|
|
78
|
+
|
|
79
|
+
expect(Object.keys(fixture)).toEqual(['foo', 'bar']);
|
|
80
|
+
});
|
package/lib/client.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
|
|
2
|
+
import { promisify } from 'util';
|
|
3
|
+
import { readFile } from 'fs';
|
|
4
|
+
import { Volume as MemFs } from 'memfs';
|
|
5
|
+
import * as fs from 'fs';
|
|
6
|
+
import { Union as UnionFs } from 'unionfs';
|
|
7
|
+
|
|
8
|
+
import { Base } from './base.js';
|
|
9
|
+
import { overload } from './overload.js';
|
|
10
|
+
|
|
11
|
+
export const client = Base.extend().include({
|
|
12
|
+
initialize(){
|
|
13
|
+
this.files = {};
|
|
14
|
+
},
|
|
15
|
+
|
|
16
|
+
addFile: overload({
|
|
17
|
+
['string, function'](filePath, fn){
|
|
18
|
+
this.files[filePath] = fn;
|
|
19
|
+
},
|
|
20
|
+
|
|
21
|
+
string(filePath){
|
|
22
|
+
this.addFile(filePath, async () => {
|
|
23
|
+
return (await promisify(readFile)(filePath)).toString();
|
|
24
|
+
});
|
|
25
|
+
},
|
|
26
|
+
}),
|
|
27
|
+
|
|
28
|
+
async createFs(entryFilePath){
|
|
29
|
+
const files = {};
|
|
30
|
+
const filePaths = Object.keys(this.files);
|
|
31
|
+
while(filePaths.length){
|
|
32
|
+
const filePath = filePaths.pop();
|
|
33
|
+
const data = await this.files[filePath]();
|
|
34
|
+
files[filePath] = data.replace(/(.*)\/\/\s*pinstripe-if-client:\s*(.*)/g, '$2 // pinstripe-if-server: $1');
|
|
35
|
+
}
|
|
36
|
+
return new UnionFs().use(fs).use(new MemFs.fromJSON({
|
|
37
|
+
...files,
|
|
38
|
+
[entryFilePath]: `
|
|
39
|
+
${
|
|
40
|
+
Object.keys(this.files).filter(filePath => filePath.match(/\/[^\.\/]+(\.client\.js)$/)).map(filePath => `
|
|
41
|
+
import ${JSON.stringify(filePath)};
|
|
42
|
+
`).join('\n')
|
|
43
|
+
}
|
|
44
|
+
`
|
|
45
|
+
}));
|
|
46
|
+
}
|
|
47
|
+
}).new();
|
|
48
|
+
|
|
49
|
+
export const addFileToClient = (...args) => client.addFile(...args);
|
package/lib/command.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
|
|
2
|
+
import { Base } from './base.js';
|
|
3
|
+
import { Registrable } from './registrable.js';
|
|
4
|
+
import { dasherize } from './inflector.js';
|
|
5
|
+
import { overload } from './overload.js';
|
|
6
|
+
import { thatify } from './thatify.js';
|
|
7
|
+
import { addFileToClient } from './client.js';
|
|
8
|
+
|
|
9
|
+
export const Command = Base.extend().include({
|
|
10
|
+
meta(){
|
|
11
|
+
this.include(Registrable);
|
|
12
|
+
|
|
13
|
+
const { register } = this;
|
|
14
|
+
|
|
15
|
+
this.assignProps({
|
|
16
|
+
register(name){
|
|
17
|
+
return register.call(this, dasherize(name));
|
|
18
|
+
},
|
|
19
|
+
|
|
20
|
+
run(name = 'list-commands', ...args){
|
|
21
|
+
return this.create(name, ...args).run();
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
},
|
|
25
|
+
|
|
26
|
+
initialize(environment){
|
|
27
|
+
this.environment = environment;
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
run(){
|
|
31
|
+
console.error(`No such command "${this.constructor.name}" exists.`);
|
|
32
|
+
},
|
|
33
|
+
|
|
34
|
+
__getMissing(name){
|
|
35
|
+
return this.environment[name];
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
export const defineCommand = overload({
|
|
41
|
+
['string, object'](name, include){
|
|
42
|
+
const abstract = include.abstract;
|
|
43
|
+
delete include.abstract;
|
|
44
|
+
Command.register(name, abstract).include(include);
|
|
45
|
+
},
|
|
46
|
+
|
|
47
|
+
['string, function'](name, fn){
|
|
48
|
+
defineCommand(name, { run: thatify(fn) });
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
export const commandImporter = dirPath => {
|
|
53
|
+
return async filePath => {
|
|
54
|
+
const relativeFilePath = filePath.substr(dirPath.length).replace(/^\//, '');
|
|
55
|
+
|
|
56
|
+
if(filePath.match(/\.js$/)){
|
|
57
|
+
const relativeFilePathWithoutExtension = relativeFilePath.replace(/\.[^/]+$/, '');
|
|
58
|
+
if(relativeFilePathWithoutExtension == '_importer'){
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
addFileToClient(filePath);
|
|
62
|
+
const definition = await ( await import(filePath) ).default;
|
|
63
|
+
if(definition !== undefined){
|
|
64
|
+
defineCommand(relativeFilePathWithoutExtension, definition);
|
|
65
|
+
}
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
|
|
2
|
+
export default async ({
|
|
3
|
+
cliUtils: { extractArg },
|
|
4
|
+
fsBuilder: { inProjectRootDir, generateFile, line, indent },
|
|
5
|
+
snakeify, dasherize
|
|
6
|
+
}) => {
|
|
7
|
+
const name = snakeify(extractArg(''));
|
|
8
|
+
if(name == ''){
|
|
9
|
+
console.error('A command name must be given.');
|
|
10
|
+
process.exit();
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
await inProjectRootDir(async () => {
|
|
14
|
+
|
|
15
|
+
await generateFile(`lib/commands/_importer.js`, { skipIfExists: true }, () => {
|
|
16
|
+
line();
|
|
17
|
+
line(`export { commandImporter as default } from 'pinstripe';`);
|
|
18
|
+
line();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
await generateFile(`lib/commands/${name}.js`, () => {
|
|
22
|
+
line();
|
|
23
|
+
line(`export default () => {`);
|
|
24
|
+
indent(() => {
|
|
25
|
+
line(`console.log('${dasherize(name)} command coming soon!')`);
|
|
26
|
+
});
|
|
27
|
+
line('};');
|
|
28
|
+
line();
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
});
|
|
32
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
|
|
2
|
+
export default async ({
|
|
3
|
+
cliUtils: { extractArg, extractFields, extractOptions },
|
|
4
|
+
fsBuilder: { inProjectRootDir, generateFile, line, indent },
|
|
5
|
+
snakeify
|
|
6
|
+
}) => {
|
|
7
|
+
const suffix = snakeify(extractArg('migration'));
|
|
8
|
+
const fields = extractFields();
|
|
9
|
+
const { table } = extractOptions({
|
|
10
|
+
table: (() => {
|
|
11
|
+
const matches = suffix.match(/_to_(.+)$/);
|
|
12
|
+
if(matches){
|
|
13
|
+
return matches[1];
|
|
14
|
+
}
|
|
15
|
+
})()
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
const unixTime = Math.floor(new Date().getTime() / 1000);
|
|
19
|
+
const name = `${unixTime}_${suffix}`;
|
|
20
|
+
|
|
21
|
+
await inProjectRootDir(async () => {
|
|
22
|
+
|
|
23
|
+
await generateFile(`lib/migrations/_importer.js`, { skipIfExists: true }, () => {
|
|
24
|
+
line();
|
|
25
|
+
line(`export { migrationImporter as default } from 'pinstripe';`);
|
|
26
|
+
line();
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
await generateFile(`lib/migrations/${name}.js`, () => {
|
|
30
|
+
line();
|
|
31
|
+
line(`export default async ({ database }) => {`);
|
|
32
|
+
indent(() => {
|
|
33
|
+
line();
|
|
34
|
+
if(table && fields.length){
|
|
35
|
+
fields.forEach(({ name, type }) => {
|
|
36
|
+
line(`await database.${table}.addColumn('${name}', '${type}');`);
|
|
37
|
+
});
|
|
38
|
+
line();
|
|
39
|
+
}
|
|
40
|
+
})
|
|
41
|
+
line('};');
|
|
42
|
+
line();
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
|
|
2
|
+
export default async ({
|
|
3
|
+
cliUtils: { extractArg, extractFields },
|
|
4
|
+
fsBuilder: { inProjectRootDir, generateFile, line, indent },
|
|
5
|
+
snakeify, pluralize, camelize,
|
|
6
|
+
database,
|
|
7
|
+
runCommand
|
|
8
|
+
}) => {
|
|
9
|
+
const name = snakeify(extractArg(''));
|
|
10
|
+
if(name == ''){
|
|
11
|
+
console.error('A model name must be given.');
|
|
12
|
+
process.exit();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const fields = extractFields();
|
|
16
|
+
|
|
17
|
+
const collectionName = camelize(pluralize(name));
|
|
18
|
+
if(!await database[collectionName].exists()){
|
|
19
|
+
const denormalizedFields = fields.map(({ mandatory, name, type }) => {
|
|
20
|
+
return `${ mandatory ? '^' : '' }${name}:${type}`
|
|
21
|
+
});
|
|
22
|
+
await runCommand('generate-migration', `create_${name}`, ...denormalizedFields, '--table', collectionName)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
await inProjectRootDir(async () => {
|
|
26
|
+
|
|
27
|
+
await generateFile(`lib/models/_importer.js`, { skipIfExists: true }, () => {
|
|
28
|
+
line();
|
|
29
|
+
line(`export { modelImporter as default } from 'pinstripe';`);
|
|
30
|
+
line();
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
await generateFile(`lib/models/${name}.js`, () => {
|
|
34
|
+
line();
|
|
35
|
+
line(`export default {`);
|
|
36
|
+
indent(() => {
|
|
37
|
+
line();
|
|
38
|
+
});
|
|
39
|
+
line('};');
|
|
40
|
+
line();
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
});
|
|
44
|
+
};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
|
|
2
|
+
import { spawnSync } from 'child_process';
|
|
3
|
+
|
|
4
|
+
export default async ({
|
|
5
|
+
cliUtils: { extractArg, extractOptions },
|
|
6
|
+
fsBuilder: { generateDir, generateFile, line, indent, echo }
|
|
7
|
+
}) => {
|
|
8
|
+
const name = extractArg('');
|
|
9
|
+
if(name == ''){
|
|
10
|
+
console.error('A project name must be given.');
|
|
11
|
+
process.exit();
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const { with: dependencies } = extractOptions({
|
|
15
|
+
with: []
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
if(!dependencies.includes('pinstripe')){
|
|
19
|
+
dependencies.unshift('pinstripe')
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
await generateDir(name, async () => {
|
|
23
|
+
|
|
24
|
+
await generateFile(`package.json`, () => {
|
|
25
|
+
echo(JSON.stringify({
|
|
26
|
+
type: "module",
|
|
27
|
+
name,
|
|
28
|
+
version: "0.0.0",
|
|
29
|
+
license: "MIT",
|
|
30
|
+
exports: {
|
|
31
|
+
".": "./lib/index.js"
|
|
32
|
+
},
|
|
33
|
+
}, null, 2));
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
await generateFile(`lib/index.js`, () => {
|
|
37
|
+
line();
|
|
38
|
+
line(`import { importAll } from 'pinstripe';`);
|
|
39
|
+
line();
|
|
40
|
+
line(`importAll(import.meta.url);`);
|
|
41
|
+
line();
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
spawnSync('yarn', [ 'add', ...dependencies ], {
|
|
45
|
+
stdio: 'inherit'
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
});
|
|
49
|
+
};
|