pinstripe 0.21.0 → 0.23.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 +10 -0
- package/lib/client.js +2 -3
- package/lib/command.js +1 -1
- package/lib/commands/generate_migration.js +16 -8
- package/lib/commands/generate_model.js +1 -1
- package/lib/commands/generate_project.js +3 -1
- package/lib/component.js +38 -27
- package/lib/component_event.js +28 -0
- package/lib/components/_file_importer.js +1 -1
- package/lib/components/pinstripe_markdown_editor.js +2 -2
- package/lib/components/pinstripe_overlay.js +1 -1
- package/lib/components/pinstripe_silo.js +2 -0
- package/lib/constants.js +4 -0
- package/lib/database/client.js +14 -2
- package/lib/database/migration.js +2 -2
- package/lib/database/migrator.js +2 -2
- package/lib/database/row.js +64 -55
- package/lib/database/table.js +5 -3
- package/lib/database/union.js +4 -4
- package/lib/database.js +19 -15
- package/lib/escape_html.js +2 -0
- package/lib/html.js +0 -1
- package/lib/import_all.js +26 -13
- package/lib/index.js +1 -3
- package/lib/model.js +1 -1
- package/lib/project.js +1 -1
- package/lib/registry.js +1 -1
- package/lib/service_consumer.js +1 -1
- package/lib/service_factory.js +1 -1
- package/lib/services/defer.js +1 -1
- package/lib/services/inflector.js +1 -1
- package/lib/services/render_form.js +5 -5
- package/lib/services/render_markdown.js +1 -2
- package/lib/unescape_html.js +1 -20
- package/lib/util.js +3 -0
- package/lib/view.js +1 -0
- package/lib/virtual_node.js +3 -4
- package/lib/virtual_node.test.js +17 -14
- package/package.json +6 -7
- package/lib/event_wrapper.js +0 -26
- package/lib/migrations/1627976184_create_user.js +0 -13
- package/lib/migrations/1628057822_create_session.js +0 -10
- package/lib/migrations/_file_importer.js +0 -1
- package/lib/models/_file_importer.js +0 -1
- package/lib/models/session.js +0 -9
- package/lib/models/user.js +0 -53
- package/lib/services/session.js +0 -19
- package/lib/views/sign_in/index.js +0 -34
- package/lib/views/sign_in/verify_password.js +0 -52
- package/lib/views/sign_out.js +0 -16
- /package/lib/components/{pinstripe_anchor.js → a.js} +0 -0
- /package/lib/components/{pinstripe_body.js → body.js} +0 -0
- /package/lib/components/{pinstripe_document.js → document.js} +0 -0
- /package/lib/components/{pinstripe_form.js → form.js} +0 -0
package/README.md
ADDED
package/lib/client.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { fileURLToPath } from 'url';
|
|
2
2
|
|
|
3
|
-
import { Class } from
|
|
4
|
-
import { Singleton } from
|
|
5
|
-
|
|
3
|
+
import { Class } from './class.js';
|
|
4
|
+
import { Singleton } from './singleton.js';
|
|
6
5
|
|
|
7
6
|
export const Client = Class.extend().include({
|
|
8
7
|
meta(){
|
package/lib/command.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
|
|
2
2
|
import { Class } from './class.js';
|
|
3
|
+
import { inflector } from './inflector.js';
|
|
3
4
|
import { Registry } from './registry.js';
|
|
4
5
|
import { ServiceConsumer } from './service_consumer.js';
|
|
5
|
-
import { inflector } from "./inflector.js";
|
|
6
6
|
|
|
7
7
|
export const Command = Class.extend().include({
|
|
8
8
|
meta(){
|
|
@@ -29,15 +29,23 @@ export default {
|
|
|
29
29
|
|
|
30
30
|
await generateFile(`lib/migrations/${name}.js`, () => {
|
|
31
31
|
line();
|
|
32
|
-
line(`export default
|
|
32
|
+
line(`export default {`);
|
|
33
33
|
indent(() => {
|
|
34
|
-
line();
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
line(`await database
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
34
|
+
line(`async migrate(){`);
|
|
35
|
+
indent(() => {
|
|
36
|
+
if(table && fields.length){
|
|
37
|
+
line(`await this.database.table('${table}', async ${table} => {`);
|
|
38
|
+
indent(() => {
|
|
39
|
+
fields.forEach(({ name, type }) => {
|
|
40
|
+
line(`await ${table}.addColumn('${name}', '${type}');`);
|
|
41
|
+
});
|
|
42
|
+
})
|
|
43
|
+
line(`});`);
|
|
44
|
+
} else {
|
|
45
|
+
line();
|
|
46
|
+
}
|
|
47
|
+
})
|
|
48
|
+
line(`}`);
|
|
41
49
|
})
|
|
42
50
|
line('};');
|
|
43
51
|
line();
|
|
@@ -11,7 +11,7 @@ export default {
|
|
|
11
11
|
const fields = extractFields();
|
|
12
12
|
|
|
13
13
|
const collectionName = this.inflector.camelize(this.inflector.pluralize(name));
|
|
14
|
-
if(!await this.database[collectionName]
|
|
14
|
+
if(!await this.database[collectionName]){
|
|
15
15
|
const denormalizedFields = fields.map(({ mandatory, name, type }) => {
|
|
16
16
|
return `${ mandatory ? '^' : '' }${name}:${type}`
|
|
17
17
|
});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
|
|
2
2
|
import { spawnSync } from 'child_process';
|
|
3
|
+
import * as crypto from 'crypto';
|
|
3
4
|
|
|
4
5
|
export default {
|
|
5
6
|
async run(){
|
|
@@ -92,7 +93,8 @@ export default {
|
|
|
92
93
|
line(`export default {`);
|
|
93
94
|
indent(() => {
|
|
94
95
|
line(`database,`);
|
|
95
|
-
line(`mail
|
|
96
|
+
line(`mail,`);
|
|
97
|
+
line(`salt: '${crypto.randomUUID()}'`)
|
|
96
98
|
})
|
|
97
99
|
line(`};`);
|
|
98
100
|
});
|
package/lib/component.js
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
|
|
2
2
|
import { fileURLToPath } from 'url'; // pinstripe-if-client: const fileURLToPath = undefined;
|
|
3
3
|
|
|
4
|
-
import { VirtualNode } from './virtual_node.js';
|
|
5
|
-
import { EventWrapper } from './event_wrapper.js';
|
|
6
|
-
import { TEXT_ONLY_TAGS } from './constants.js';
|
|
7
|
-
|
|
8
4
|
import { Class } from './class.js';
|
|
5
|
+
import { TEXT_ONLY_TAGS } from './constants.js';
|
|
6
|
+
import { Inflector } from './inflector.js';
|
|
7
|
+
import { VirtualNode } from './virtual_node.js';
|
|
9
8
|
import { Registry } from './registry.js';
|
|
9
|
+
import { ComponentEvent } from './component_event.js';
|
|
10
10
|
import { Client } from './client.js'; // pinstripe-if-client: const Client = undefined;
|
|
11
|
-
import { Inflector } from './inflector.js';
|
|
12
11
|
|
|
13
12
|
export const Component = Class.extend().include({
|
|
14
13
|
meta(){
|
|
@@ -41,6 +40,10 @@ export const Component = Class.extend().include({
|
|
|
41
40
|
import include from ${JSON.stringify(filePath)};
|
|
42
41
|
Component.register(${JSON.stringify(relativeFilePathWithoutExtension)}, include);
|
|
43
42
|
`);
|
|
43
|
+
} else {
|
|
44
|
+
Client.instance.addModule(`
|
|
45
|
+
import ${JSON.stringify(filePath)};
|
|
46
|
+
`);
|
|
44
47
|
}
|
|
45
48
|
return importFile.call(this, params);
|
|
46
49
|
}
|
|
@@ -124,7 +127,9 @@ export const Component = Class.extend().include({
|
|
|
124
127
|
},
|
|
125
128
|
|
|
126
129
|
get realParent(){
|
|
127
|
-
|
|
130
|
+
if(this.node.parentNode) return this.constructor.instanceFor(this.node.parentNode);
|
|
131
|
+
if(this.node.host instanceof Element) return this.constructor.instanceFor(this.node.host);
|
|
132
|
+
return null;
|
|
128
133
|
},
|
|
129
134
|
|
|
130
135
|
get parent(){
|
|
@@ -298,7 +303,7 @@ export const Component = Class.extend().include({
|
|
|
298
303
|
const selector = args.pop()
|
|
299
304
|
|
|
300
305
|
const wrapperFn = (event, ...args) => {
|
|
301
|
-
const eventWrapper =
|
|
306
|
+
const eventWrapper = ComponentEvent.instanceFor(event)
|
|
302
307
|
if(selector){
|
|
303
308
|
if(eventWrapper.target.is(selector)){
|
|
304
309
|
return fn.call(eventWrapper.target, eventWrapper, ...args);
|
|
@@ -485,6 +490,9 @@ const matchesSelector = (() => {
|
|
|
485
490
|
})();
|
|
486
491
|
|
|
487
492
|
function cleanChildren(){
|
|
493
|
+
if(this.node.shadowRoot){
|
|
494
|
+
this.shadow.children.forEach(child => clean.call(child));
|
|
495
|
+
}
|
|
488
496
|
this.children.forEach(child => clean.call(child));
|
|
489
497
|
}
|
|
490
498
|
|
|
@@ -515,6 +523,9 @@ function clearTimers(){
|
|
|
515
523
|
}
|
|
516
524
|
|
|
517
525
|
function initChildren(){
|
|
526
|
+
if(this.node.shadowRoot){
|
|
527
|
+
this.shadow.children.forEach(child => initChildren.call(child));
|
|
528
|
+
}
|
|
518
529
|
this.children.forEach(child => initChildren.call(child));
|
|
519
530
|
}
|
|
520
531
|
|
|
@@ -537,13 +548,19 @@ function createVirtualNode(html){
|
|
|
537
548
|
}
|
|
538
549
|
|
|
539
550
|
function patch(attributes, virtualChildren){
|
|
540
|
-
const
|
|
551
|
+
const isFrame = this.type == 'pinstripe-frame' || this.attributes['data-component'] == 'pinstripe-frame';
|
|
552
|
+
const isEmptyFrame = isFrame && virtualChildren.length == 0;
|
|
541
553
|
if(isEmptyFrame && attributes['data-load-on-init'] === undefined){
|
|
542
554
|
attributes['data-load-on-init'] = 'true';
|
|
543
555
|
}
|
|
544
556
|
patchAttributes.call(this, attributes);
|
|
545
557
|
if(isEmptyFrame) return;
|
|
546
|
-
|
|
558
|
+
if(this.is('pinstripe-silo, [data-component="pinstripe-silo"]')){
|
|
559
|
+
patchChildren.call(this.shadow, virtualChildren);
|
|
560
|
+
patchChildren.call(this, []);
|
|
561
|
+
} else {
|
|
562
|
+
patchChildren.call(this, virtualChildren);
|
|
563
|
+
}
|
|
547
564
|
}
|
|
548
565
|
|
|
549
566
|
function patchAttributes(attributes){
|
|
@@ -622,10 +639,17 @@ function insert(virtualNode, referenceChild, returnComponent = true){
|
|
|
622
639
|
insert.call(new Component(node, true), child, null, false);
|
|
623
640
|
})
|
|
624
641
|
|
|
625
|
-
this.
|
|
626
|
-
node
|
|
627
|
-
|
|
628
|
-
|
|
642
|
+
if(this.is('pinstripe-silo, [data-component="pinstripe-silo"]')){
|
|
643
|
+
this.shadow.node.insertBefore(
|
|
644
|
+
node,
|
|
645
|
+
referenceChild && referenceChild.node
|
|
646
|
+
);
|
|
647
|
+
} else {
|
|
648
|
+
this.node.insertBefore(
|
|
649
|
+
node,
|
|
650
|
+
referenceChild && referenceChild.node
|
|
651
|
+
);
|
|
652
|
+
}
|
|
629
653
|
|
|
630
654
|
if(returnComponent){
|
|
631
655
|
return Component.instanceFor(node);
|
|
@@ -653,17 +677,4 @@ function normalizeVirtualNode(){
|
|
|
653
677
|
}
|
|
654
678
|
}
|
|
655
679
|
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
[
|
|
659
|
-
['#document', 'pinstripe-document'],
|
|
660
|
-
['a', 'pinstripe-anchor'],
|
|
661
|
-
['body', 'pinstripe-body'],
|
|
662
|
-
['form', 'pinstripe-form']
|
|
663
|
-
].forEach(([name, include]) => {
|
|
664
|
-
Component.register(name, {
|
|
665
|
-
meta(){
|
|
666
|
-
this.include(include);
|
|
667
|
-
}
|
|
668
|
-
})
|
|
669
|
-
});
|
|
680
|
+
ComponentEvent.Component = Component;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
|
|
2
|
+
import { Class } from './class.js';
|
|
3
|
+
import { trapify } from './trapify.js';
|
|
4
|
+
|
|
5
|
+
export const ComponentEvent = Class.extend().include({
|
|
6
|
+
meta(){
|
|
7
|
+
this.assignProps({
|
|
8
|
+
instanceFor(event){
|
|
9
|
+
if(!event._componentEvent){
|
|
10
|
+
event._componentEvent = ComponentEvent.new(event);
|
|
11
|
+
}
|
|
12
|
+
return event._componentEvent;
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
},
|
|
16
|
+
|
|
17
|
+
initialize(event){
|
|
18
|
+
this.event = event;
|
|
19
|
+
return trapify(this);
|
|
20
|
+
},
|
|
21
|
+
|
|
22
|
+
__get(target, name){
|
|
23
|
+
const out = target.event[name];
|
|
24
|
+
if(out instanceof Node) return ComponentEvent.Component.instanceFor(out);
|
|
25
|
+
if(typeof out == 'function') return (...args) => out.call(target.event, ...args);
|
|
26
|
+
return out;
|
|
27
|
+
}
|
|
28
|
+
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { Component as default } from 'pinstripe'
|
|
1
|
+
export { Component as default } from 'pinstripe';
|
|
@@ -59,11 +59,11 @@ Component.register('pinstripe-markdown-editor/line-inserter', {
|
|
|
59
59
|
|
|
60
60
|
Component.register('pinstripe-markdown-editor/anchor', {
|
|
61
61
|
meta(){
|
|
62
|
-
this.include('
|
|
62
|
+
this.include('a');
|
|
63
63
|
},
|
|
64
64
|
|
|
65
65
|
initialize(...args){
|
|
66
|
-
this.constructor.for('
|
|
66
|
+
this.constructor.for('a').prototype.initialize.call(this, ...args);
|
|
67
67
|
|
|
68
68
|
this.patch({
|
|
69
69
|
...this.attributes,
|
package/lib/constants.js
CHANGED
package/lib/database/client.js
CHANGED
|
@@ -2,7 +2,8 @@ import mysql from 'mysql2';
|
|
|
2
2
|
import sqlite from 'sqlite3';
|
|
3
3
|
import { existsSync, unlinkSync } from 'fs';
|
|
4
4
|
|
|
5
|
-
import { Class } from
|
|
5
|
+
import { Class } from '../class.js';
|
|
6
|
+
|
|
6
7
|
|
|
7
8
|
export const Client = Class.extend().include({
|
|
8
9
|
initialize(config){
|
|
@@ -31,7 +32,7 @@ export const Client = Class.extend().include({
|
|
|
31
32
|
}
|
|
32
33
|
});
|
|
33
34
|
}
|
|
34
|
-
return run.call(this, ...prepare.call(this, query));
|
|
35
|
+
return run.call(this, ...prepare.call(this, await resolveQuery(query)));
|
|
35
36
|
},
|
|
36
37
|
|
|
37
38
|
async lock(fn){
|
|
@@ -130,6 +131,17 @@ export const Client = Class.extend().include({
|
|
|
130
131
|
});
|
|
131
132
|
|
|
132
133
|
|
|
134
|
+
async function resolveQuery(query){
|
|
135
|
+
let out = await query;
|
|
136
|
+
if(Array.isArray(out)){
|
|
137
|
+
out = [ ...out ];
|
|
138
|
+
for(let i = 0; i < out.length; i++){
|
|
139
|
+
out[i] = await resolveQuery(out[i]);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return out;
|
|
143
|
+
}
|
|
144
|
+
|
|
133
145
|
function flattenFirst(query){
|
|
134
146
|
if(!Array.isArray(query[0])) return query;
|
|
135
147
|
return flattenFirst([...query[0], ...query.slice(1)]);
|
package/lib/database/migrator.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
import { Class } from
|
|
2
|
+
import { Class } from '../class.js';
|
|
3
3
|
import { Migration } from "./migration.js";
|
|
4
4
|
|
|
5
5
|
export const Migrator = Class.extend().include({
|
|
@@ -8,7 +8,7 @@ export const Migrator = Class.extend().include({
|
|
|
8
8
|
},
|
|
9
9
|
|
|
10
10
|
async migrate(){
|
|
11
|
-
if(!this.database.table('pinstripeAppliedMigrations').exists){
|
|
11
|
+
if(!await this.database.table('pinstripeAppliedMigrations').exists){
|
|
12
12
|
await this.database.table('pinstripeAppliedMigrations', async pinstripeAppliedMigrations => {
|
|
13
13
|
await pinstripeAppliedMigrations.addColumn('schemaVersion', 'integer');
|
|
14
14
|
});
|
package/lib/database/row.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
+
|
|
1
2
|
import crypto from 'crypto';
|
|
2
3
|
|
|
4
|
+
import { Registry } from '../registry.js';
|
|
3
5
|
import { Model, defineCallbacks } from "../model.js";
|
|
4
|
-
import { Registry } from "../registry.js";
|
|
5
6
|
import { Table } from "./table.js";
|
|
6
7
|
import { TableReference } from './table_reference.js';
|
|
7
8
|
import { defer } from '../defer.js';
|
|
8
|
-
import { inflector } from '../inflector.js'
|
|
9
|
+
import { inflector } from '../inflector.js';
|
|
9
10
|
import { COLUMN_TYPE_TO_FORM_FIELD_TYPE_MAP } from './constants.js';
|
|
10
11
|
|
|
11
12
|
export const Row = Model.extend().include({
|
|
@@ -150,79 +151,82 @@ export const Row = Model.extend().include({
|
|
|
150
151
|
modifiedFields[name] = this[name];
|
|
151
152
|
}
|
|
152
153
|
});
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
154
|
+
|
|
155
|
+
if(Object.keys(modifiedFields).length) {
|
|
156
|
+
const query = [];
|
|
156
157
|
|
|
157
|
-
|
|
158
|
+
const tableReference = TableReference.new(this.constructor.collectionName);
|
|
158
159
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
160
|
+
if(this._exists){
|
|
161
|
+
query.push('update ? set ', tableReference);
|
|
162
|
+
Object.keys(modifiedFields).forEach((name, i) => {
|
|
163
|
+
if(name == 'id') return;
|
|
164
|
+
this.database.client.adapt({
|
|
165
|
+
mysql(){
|
|
166
|
+
if(name.match(/(^id|Id)$/)){
|
|
167
|
+
query.push(i > 0 ? ', ? = uuid_to_bin(?)' : '? = uuid_to_bin(?)', tableReference.createColumnReference(name), modifiedFields[name]);
|
|
168
|
+
} else {
|
|
169
|
+
query.push(i > 0 ? ', ? = ?' : '? = ?', tableReference.createColumnReference(name), modifiedFields[name]);
|
|
170
|
+
}
|
|
171
|
+
},
|
|
171
172
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
173
|
+
sqlite(){
|
|
174
|
+
query.push(i > 0 ? `, \`${name}\` = ?` : `\`${name}\` = ?`, modifiedFields[name]);
|
|
175
|
+
}
|
|
176
|
+
});
|
|
175
177
|
});
|
|
176
|
-
|
|
177
|
-
this.database.client.adapt(this, {
|
|
178
|
-
mysql(){
|
|
179
|
-
query.push(' where ? = uuid_to_bin(?)', tableReference.createColumnReference('id'), this._initialFields.id);
|
|
180
|
-
},
|
|
181
|
-
|
|
182
|
-
sqlite(){
|
|
183
|
-
query.push(' where ? = ?', tableReference.createColumnReference('id'), this._initialFields.id);
|
|
184
|
-
}
|
|
185
|
-
});
|
|
186
|
-
|
|
187
|
-
} else {
|
|
188
|
-
query.push('insert into ?(', tableReference);
|
|
189
|
-
Object.keys(modifiedFields).forEach((name, i) => {
|
|
190
|
-
this.database.client.adapt({
|
|
178
|
+
this.database.client.adapt(this, {
|
|
191
179
|
mysql(){
|
|
192
|
-
query.push(
|
|
180
|
+
query.push(' where ? = uuid_to_bin(?)', tableReference.createColumnReference('id'), this._initialFields.id);
|
|
193
181
|
},
|
|
194
182
|
|
|
195
183
|
sqlite(){
|
|
196
|
-
query.push(
|
|
184
|
+
query.push(' where ? = ?', tableReference.createColumnReference('id'), this._initialFields.id);
|
|
197
185
|
}
|
|
198
186
|
});
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
187
|
+
|
|
188
|
+
} else {
|
|
189
|
+
query.push('insert into ?(', tableReference);
|
|
190
|
+
Object.keys(modifiedFields).forEach((name, i) => {
|
|
203
191
|
this.database.client.adapt({
|
|
204
192
|
mysql(){
|
|
205
|
-
query.push(i > 0 ? ',
|
|
193
|
+
query.push(i > 0 ? ', ?' : '?', tableReference.createColumnReference(name));
|
|
206
194
|
},
|
|
207
195
|
|
|
208
196
|
sqlite(){
|
|
209
|
-
query.push(i > 0 ?
|
|
197
|
+
query.push(i > 0 ? `, \`${name}\`` : `\`${name}\``,);
|
|
210
198
|
}
|
|
211
199
|
});
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
200
|
+
});
|
|
201
|
+
query.push(') values(');
|
|
202
|
+
Object.keys(modifiedFields).forEach((name, i) => {
|
|
203
|
+
if(name.match(/(^id|Id)$/)){
|
|
204
|
+
this.database.client.adapt({
|
|
205
|
+
mysql(){
|
|
206
|
+
query.push(i > 0 ? ', uuid_to_bin(?)' : 'uuid_to_bin(?)', modifiedFields[name]);
|
|
207
|
+
},
|
|
208
|
+
|
|
209
|
+
sqlite(){
|
|
210
|
+
query.push(i > 0 ? ', ?' : '?', modifiedFields[name]);
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
} else {
|
|
214
|
+
query.push(i > 0 ? ', ?' : '?', modifiedFields[name]);
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
query.push(')');
|
|
218
|
+
}
|
|
218
219
|
|
|
219
|
-
|
|
220
|
+
await this.database.run(query);
|
|
220
221
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
222
|
+
Object.keys(modifiedFields).forEach(name => {
|
|
223
|
+
this[name] = modifiedFields[name];
|
|
224
|
+
this._initialFields[name] = modifiedFields[name];
|
|
225
|
+
});
|
|
224
226
|
|
|
225
|
-
|
|
227
|
+
this._exists = true;
|
|
228
|
+
|
|
229
|
+
}
|
|
226
230
|
|
|
227
231
|
await (this._exists ? this._runAfterUpdateCallbacks() : this._runAfterInsertCallbacks());
|
|
228
232
|
|
|
@@ -326,6 +330,11 @@ function defineRelationship({ name, type, collectionName, fromKey, toKey, cascad
|
|
|
326
330
|
this.prototype.assignProps({
|
|
327
331
|
get [name](){
|
|
328
332
|
return defer(() => {
|
|
333
|
+
if(fromKey != 'id'){
|
|
334
|
+
const out = this.database[collectionName].where({ [toKey]: this[fromKey] });
|
|
335
|
+
if(type == 'singular') return out.first();
|
|
336
|
+
return out;
|
|
337
|
+
}
|
|
329
338
|
const out = this.database[this.constructor.collectionName].where({ id: this.id })[name];
|
|
330
339
|
if(type == 'singular') return out.first();
|
|
331
340
|
return out;
|
package/lib/database/table.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
|
|
2
|
-
import { Class } from
|
|
3
|
-
import {
|
|
2
|
+
import { Class } from '../class.js';
|
|
3
|
+
import { inflector } from '../inflector.js';
|
|
4
|
+
import { Registry } from '../registry.js';
|
|
4
5
|
import { TableReference } from "./table_reference.js";
|
|
5
6
|
import {
|
|
6
7
|
MYSQL_COLUMN_TYPE_TO_TYPE_MAP,
|
|
@@ -13,7 +14,6 @@ import {
|
|
|
13
14
|
COLUMN_TYPE_TO_FORM_FIELD_TYPE_MAP
|
|
14
15
|
} from './constants.js';
|
|
15
16
|
import { Union } from "./union.js";
|
|
16
|
-
import { inflector } from "../inflector.js";
|
|
17
17
|
|
|
18
18
|
export const Table = Class.extend().include({
|
|
19
19
|
meta(){
|
|
@@ -489,6 +489,8 @@ export const Table = Class.extend().include({
|
|
|
489
489
|
}
|
|
490
490
|
});
|
|
491
491
|
|
|
492
|
+
Union.Table = Table;
|
|
493
|
+
|
|
492
494
|
function joinToUnion(fromKey, collectionName, toKey){
|
|
493
495
|
return Union.new(
|
|
494
496
|
this.database,
|
package/lib/database/union.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
|
|
2
|
-
import { Class } from
|
|
2
|
+
import { Class } from '../class.js';
|
|
3
|
+
import { inflector } from '../inflector.js';
|
|
3
4
|
import { Row } from './row.js';
|
|
4
|
-
import { inflector } from "../inflector.js";
|
|
5
5
|
|
|
6
6
|
export const Union = Class.extend().include({
|
|
7
7
|
meta(){
|
|
@@ -12,7 +12,7 @@ export const Union = Class.extend().include({
|
|
|
12
12
|
},
|
|
13
13
|
|
|
14
14
|
create(name, database){
|
|
15
|
-
return this.new(database, this.tableNamesFor(name).map(tableName =>
|
|
15
|
+
return this.new(database, this.tableNamesFor(name).map(tableName => this.Table.create(tableName, database)));
|
|
16
16
|
}
|
|
17
17
|
});
|
|
18
18
|
},
|
|
@@ -125,4 +125,4 @@ export const Union = Class.extend().include({
|
|
|
125
125
|
}
|
|
126
126
|
return this;
|
|
127
127
|
}
|
|
128
|
-
});
|
|
128
|
+
});
|
package/lib/database.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
|
|
2
1
|
import { Class } from './class.js';
|
|
3
|
-
import { Table, Union, Row, Migrator } from './database/index.js';
|
|
4
2
|
import { trapify } from './trapify.js';
|
|
3
|
+
import { defer } from './defer.js';
|
|
4
|
+
import { Table, Union, Row, Migrator } from './database/index.js';
|
|
5
5
|
|
|
6
6
|
let loadSchemaPromise;
|
|
7
7
|
|
|
@@ -23,26 +23,30 @@ export const Database = Class.extend().include({
|
|
|
23
23
|
},
|
|
24
24
|
|
|
25
25
|
table(name, fn){
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
return defer(() => {
|
|
27
|
+
const out = Table.create(name, this);
|
|
28
|
+
if(fn) return fn.call(out, out);
|
|
29
|
+
return out;
|
|
30
|
+
});
|
|
29
31
|
},
|
|
30
32
|
|
|
31
33
|
union(name){
|
|
32
|
-
return Union.create(name, this);
|
|
34
|
+
return defer(() => Union.create(name, this));
|
|
33
35
|
},
|
|
34
36
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
if(out) return out;
|
|
41
|
-
return this.lock(async () => {
|
|
37
|
+
singleton(name){
|
|
38
|
+
return defer(async () => {
|
|
39
|
+
const { abstract, singleton, collectionName } = Row.for(name);
|
|
40
|
+
if(!singleton || abstract) return;
|
|
41
|
+
const table = this.table(collectionName);
|
|
42
42
|
const out = await table.first();
|
|
43
43
|
if(out) return out;
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
return this.lock(async () => {
|
|
45
|
+
const out = await table.first();
|
|
46
|
+
if(out) return out;
|
|
47
|
+
await table.insert();
|
|
48
|
+
return table.first();
|
|
49
|
+
});
|
|
46
50
|
});
|
|
47
51
|
},
|
|
48
52
|
|