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.
Files changed (173) hide show
  1. package/README.md +1 -1
  2. package/cli.js +8 -3
  3. package/lib/async_path_builder.js +38 -39
  4. package/lib/async_path_builder.test.js +27 -0
  5. package/lib/base.js +51 -17
  6. package/lib/base.test.js +80 -0
  7. package/lib/client.js +49 -0
  8. package/lib/command.js +69 -0
  9. package/lib/commands/_importer.js +1 -3
  10. package/lib/commands/create_database.js +2 -0
  11. package/lib/commands/drop_database.js +2 -0
  12. package/lib/commands/generate_command.js +32 -0
  13. package/lib/commands/generate_migration.js +45 -0
  14. package/lib/commands/generate_model.js +44 -0
  15. package/lib/commands/generate_project.js +49 -0
  16. package/lib/commands/generate_service.js +32 -0
  17. package/lib/commands/generate_static_site.js +79 -0
  18. package/lib/commands/generate_view.js +34 -0
  19. package/lib/commands/generate_widget.js +36 -0
  20. package/lib/commands/init_database.js +6 -0
  21. package/lib/commands/list_commands.js +14 -0
  22. package/lib/commands/list_migrations.js +14 -0
  23. package/lib/commands/list_models.js +14 -0
  24. package/lib/commands/list_services.js +15 -0
  25. package/lib/commands/list_views.js +14 -0
  26. package/lib/commands/list_widgets.js +14 -0
  27. package/lib/commands/migrate_database.js +2 -0
  28. package/lib/commands/reset_database.js +5 -0
  29. package/lib/commands/seed_database.js +4 -0
  30. package/lib/commands/{start_console.server.js → start_console.js} +8 -7
  31. package/lib/commands/start_server.js +76 -0
  32. package/lib/constants.js +21 -0
  33. package/lib/database/column.js +94 -0
  34. package/lib/database/constants.js +84 -0
  35. package/lib/database/migration.js +74 -0
  36. package/lib/database/migrator.js +38 -0
  37. package/lib/database/row.js +278 -0
  38. package/lib/database/sql.js +75 -0
  39. package/lib/database/table.js +488 -0
  40. package/lib/database/union.js +180 -0
  41. package/lib/database.js +197 -0
  42. package/lib/environment.js +29 -25
  43. package/lib/event_wrapper.js +26 -25
  44. package/lib/hookable.js +21 -19
  45. package/lib/html.js +60 -58
  46. package/lib/import_all.js +17 -17
  47. package/lib/index.js +19 -10
  48. package/lib/inflector.js +162 -160
  49. package/lib/initialize.client.js +25 -23
  50. package/lib/migrations/1627976184_create_user.js +9 -0
  51. package/lib/migrations/1628057822_create_session.js +7 -0
  52. package/lib/migrations/_importer.js +2 -0
  53. package/lib/models/_importer.js +2 -0
  54. package/lib/models/session.js +9 -0
  55. package/lib/models/user.js +45 -0
  56. package/lib/node_wrapper.js +426 -246
  57. package/lib/overload.js +1 -0
  58. package/lib/project.js +36 -38
  59. package/lib/registrable.js +80 -42
  60. package/lib/service_factory.js +90 -47
  61. package/lib/services/_importer.js +2 -0
  62. package/lib/services/args.js +2 -0
  63. package/lib/services/cli_utils.js +71 -0
  64. package/lib/services/config.js +9 -0
  65. package/lib/services/cookies.js +20 -0
  66. package/lib/services/database.js +12 -0
  67. package/lib/services/fetch.js +99 -0
  68. package/lib/services/fork_environment.js +16 -0
  69. package/lib/services/fs_builder.js +130 -0
  70. package/lib/services/global.js +9 -0
  71. package/lib/services/params.js +2 -0
  72. package/lib/services/project.js +4 -0
  73. package/lib/services/read_file.js +6 -0
  74. package/lib/services/render_file.js +9 -0
  75. package/lib/services/render_form.js +223 -0
  76. package/lib/services/render_html.js +6 -0
  77. package/lib/services/render_list.js +58 -0
  78. package/lib/services/render_markdown.js +6 -0
  79. package/lib/services/render_table.js +68 -0
  80. package/lib/services/render_view.js +18 -0
  81. package/lib/services/reset_environment.js +19 -0
  82. package/lib/services/run_command.js +9 -0
  83. package/lib/services/session.js +9 -0
  84. package/lib/services/view.js +4 -0
  85. package/lib/string_reader.js +20 -22
  86. package/lib/thatify.js +6 -0
  87. package/lib/url.js +77 -76
  88. package/lib/url.test.js +5 -1
  89. package/lib/validatable.js +60 -48
  90. package/lib/view.js +121 -2
  91. package/lib/views/_importer.js +1 -3
  92. package/lib/views/_layout.js +51 -0
  93. package/lib/views/bundle.css +10384 -0
  94. package/lib/views/bundle.css.map +1 -0
  95. package/lib/views/bundle.js +37 -0
  96. package/lib/views/sign_in.js +44 -0
  97. package/lib/views/sign_out.js +15 -0
  98. package/lib/virtual_node.js +125 -174
  99. package/lib/widgets/_importer.js +1 -3
  100. package/lib/widgets/frame.client.js +124 -0
  101. package/lib/widgets/internal/actions.client.js +51 -0
  102. package/lib/widgets/internal/document.client.js +56 -0
  103. package/lib/widgets/internal/markdown_editor.client.js +26 -0
  104. package/lib/widgets/internal/overlay.client.js +43 -0
  105. package/lib/widgets/{progress_bar.js → internal/progress_bar.client.js} +10 -3
  106. package/lib/widgets/trigger.client.js +20 -0
  107. package/package.json +16 -11
  108. package/pinstripe.scss +2 -0
  109. package/lib/command.server.js +0 -34
  110. package/lib/commands/create_database.server.js +0 -6
  111. package/lib/commands/drop_database.server.js +0 -6
  112. package/lib/commands/generate_command.server.js +0 -42
  113. package/lib/commands/generate_controller.server.js +0 -48
  114. package/lib/commands/generate_migration.server.js +0 -50
  115. package/lib/commands/generate_model.server.js +0 -50
  116. package/lib/commands/generate_project.server.js +0 -62
  117. package/lib/commands/generate_service.server.js +0 -42
  118. package/lib/commands/generate_view.server.js +0 -49
  119. package/lib/commands/generate_widget.server.js +0 -38
  120. package/lib/commands/init_database.server.js +0 -7
  121. package/lib/commands/list_commands.server.js +0 -15
  122. package/lib/commands/list_controllers.server.js +0 -15
  123. package/lib/commands/list_migrations.server.js +0 -15
  124. package/lib/commands/list_models.server.js +0 -15
  125. package/lib/commands/list_services.server.js +0 -15
  126. package/lib/commands/list_views.server.js +0 -15
  127. package/lib/commands/list_widgets.server.js +0 -15
  128. package/lib/commands/migrate_database.server.js +0 -7
  129. package/lib/commands/reset_database.server.js +0 -8
  130. package/lib/commands/start_server.server.js +0 -48
  131. package/lib/controller.js +0 -6
  132. package/lib/controllers/bundle.server.js +0 -61
  133. package/lib/database/column.server.js +0 -100
  134. package/lib/database/migration.server.js +0 -35
  135. package/lib/database/migrator.server.js +0 -40
  136. package/lib/database/row.server.js +0 -173
  137. package/lib/database/sql.server.js +0 -73
  138. package/lib/database/table.server.js +0 -409
  139. package/lib/database/union.server.js +0 -84
  140. package/lib/database.server.js +0 -181
  141. package/lib/generate_css.js +0 -39
  142. package/lib/renderable.js +0 -43
  143. package/lib/service_factories/_importer.js +0 -4
  144. package/lib/service_factories/args.server.js +0 -6
  145. package/lib/service_factories/camelize.js +0 -8
  146. package/lib/service_factories/capitalize.js +0 -8
  147. package/lib/service_factories/cli_utils.server.js +0 -76
  148. package/lib/service_factories/config.js +0 -13
  149. package/lib/service_factories/dasherize.js +0 -8
  150. package/lib/service_factories/database.server.js +0 -9
  151. package/lib/service_factories/fetch.js +0 -87
  152. package/lib/service_factories/fork_environment.js +0 -13
  153. package/lib/service_factories/fs_builder.server.js +0 -132
  154. package/lib/service_factories/params.js +0 -6
  155. package/lib/service_factories/pascalize.js +0 -8
  156. package/lib/service_factories/pluralize.js +0 -8
  157. package/lib/service_factories/project.js +0 -8
  158. package/lib/service_factories/render_controller.js +0 -11
  159. package/lib/service_factories/render_html.js +0 -8
  160. package/lib/service_factories/render_view.js +0 -11
  161. package/lib/service_factories/reset_environment.js +0 -21
  162. package/lib/service_factories/run_command.server.js +0 -11
  163. package/lib/service_factories/singularize.js +0 -8
  164. package/lib/service_factories/snakeify.js +0 -8
  165. package/lib/service_factories/uncapitalize.js +0 -8
  166. package/lib/views/layout.js +0 -13
  167. package/lib/widgets/anchor.js +0 -48
  168. package/lib/widgets/document.js +0 -38
  169. package/lib/widgets/form.js +0 -58
  170. package/lib/widgets/frame.js +0 -69
  171. package/lib/widgets/input.js +0 -13
  172. package/lib/widgets/modal.js +0 -20
  173. 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 and the browser that follows the [model-view-controller (MVC)](https://en.wikipedia.org/wiki/Model-view-controller) design pattern.
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.server.js';
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
- await runCommand(...args);
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().open(Class => Class
5
- .props({
6
- initialize(startObject, path = []){
7
- this._startObject = startObject;
8
- this._path = path;
9
- },
4
+ export const AsyncPathBuilder = Base.extend().include({
5
+ initialize(startObject, path = []){
6
+ this._startObject = startObject;
7
+ this._path = path;
8
+ },
10
9
 
11
- __getMissing(name){
12
- return new this.constructor(this._startObject, [...this._path, [ name ]]);
13
- },
10
+ __getMissing(name){
11
+ return new this.constructor(this._startObject, [...this._path, name ]);
12
+ },
14
13
 
15
- __call(...args){
16
- const path = [...this._path];
17
- path.push([...path.pop(), ...args]);
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
- then(...args){
24
- return unwrap(this._startObject, [...this._path]).then(...args);
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 function unwrap(startObject, path) {
23
+ const unwrap = async (startObject, path) => {
40
24
  let out = await startObject;
25
+ let originalPath = [ ...path ];
41
26
  while(path.length){
42
- const [ name, ...args ] = path.shift();
43
- if(typeof out[name] == 'function'){
44
- out = await out[name](...args);
45
- } else {
46
- out = await out[name];
47
- if(typeof out == 'function'){
48
- out = await out(...args);
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 open(fn){
7
- fn.call(this, this);
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
- this.open(...args);
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
- Object.defineProperty(target, name, Object.getOwnPropertyDescriptor(source, name));
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;
@@ -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
+ };
@@ -1,4 +1,2 @@
1
1
 
2
- import { Command } from 'pinstripe';
3
-
4
- export default Command.importer;
2
+ export { commandImporter as default } from 'pinstripe';
@@ -0,0 +1,2 @@
1
+
2
+ export default ({ database }) => database.create();
@@ -0,0 +1,2 @@
1
+
2
+ export default ({ database }) => database.drop();
@@ -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
+ };