json-fs-query 1.0.6 → 2.0.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/LICENSE +674 -674
- package/README.md +295 -98
- package/browser/jsonFsQuery.js +12733 -10777
- package/browser/jsonFsQuery.min.js +1 -1
- package/dist/data/introspect/create.d.ts +1 -1
- package/dist/data/introspect/create.js +35 -4
- package/dist/data/introspect/create.min.js +1 -1
- package/dist/data/introspect/definitions/field.d.ts +6 -2
- package/dist/data/introspect/definitions/field.js +7 -1
- package/dist/data/introspect/definitions/field.min.js +1 -1
- package/dist/data/introspect/index.d.ts +6 -3
- package/dist/data/introspect/index.js +10 -19
- package/dist/data/introspect/index.min.js +1 -1
- package/dist/data/introspect/policies/foreignKeyExists.js +5 -1
- package/dist/data/introspect/policies/foreignKeyExists.min.js +1 -1
- package/dist/data/introspect/policies/hasDependents.js +3 -1
- package/dist/data/introspect/policies/hasDependents.min.js +1 -1
- package/dist/data/introspect/policies/keyUnique.js +5 -1
- package/dist/data/introspect/policies/keyUnique.min.js +1 -1
- package/dist/data/introspect/policies/typeCheck.d.ts +9 -1
- package/dist/data/introspect/policies/typeCheck.js +16 -2
- package/dist/data/introspect/policies/typeCheck.min.js +1 -1
- package/dist/data/queries/createRecord.d.ts +11 -0
- package/dist/data/queries/createRecord.js +58 -0
- package/dist/data/queries/createRecord.min.js +1 -0
- package/dist/data/queries/deleteEntity.js +2 -1
- package/dist/data/queries/deleteEntity.min.js +1 -1
- package/dist/data/queries/describeRecord.d.ts +9 -0
- package/dist/data/queries/describeRecord.js +29 -0
- package/dist/data/queries/describeRecord.min.js +1 -0
- package/dist/data/queries/dropRecord.d.ts +9 -0
- package/dist/data/queries/dropRecord.js +61 -0
- package/dist/data/queries/dropRecord.min.js +1 -0
- package/dist/data/queries/insertEntity.js +11 -5
- package/dist/data/queries/insertEntity.min.js +1 -1
- package/dist/data/queries/parser.d.ts +1 -1
- package/dist/data/queries/parser.js +7 -15
- package/dist/data/queries/parser.min.js +1 -1
- package/dist/data/queries/query.d.ts +6 -0
- package/dist/data/queries/query.js +15 -6
- package/dist/data/queries/query.min.js +1 -1
- package/dist/data/queries/queryStatus.d.ts +15 -0
- package/dist/data/queries/queryStatus.js +52 -0
- package/dist/data/queries/queryStatus.min.js +1 -0
- package/dist/data/queries/quote.d.ts +11 -0
- package/dist/data/queries/quote.js +17 -0
- package/dist/data/queries/quote.min.js +1 -0
- package/dist/data/queries/showRecords.d.ts +6 -0
- package/dist/data/queries/showRecords.js +21 -0
- package/dist/data/queries/showRecords.min.js +1 -0
- package/dist/data/queries/sortBy.js +3 -0
- package/dist/data/queries/updateEntity.js +74 -18
- package/dist/data/queries/updateEntity.min.js +1 -1
- package/dist/data/queries/where.d.ts +2 -1
- package/dist/data/queries/where.js +18 -6
- package/dist/data/queries/where.min.js +1 -1
- package/dist/data/utilities/compareAs.d.ts +20 -0
- package/dist/data/utilities/compareAs.js +58 -0
- package/dist/data/utilities/compareAs.min.js +1 -0
- package/dist/data/utilities/config.d.ts +15 -0
- package/dist/data/utilities/config.js +31 -1
- package/dist/data/utilities/config.min.js +1 -1
- package/dist/data/utilities/databaseLock.d.ts +16 -0
- package/dist/data/utilities/databaseLock.js +63 -0
- package/dist/data/utilities/databaseLock.min.js +1 -0
- package/dist/data/utilities/fieldType.d.ts +16 -0
- package/dist/data/utilities/fieldType.js +23 -0
- package/dist/data/utilities/fieldType.min.js +1 -0
- package/dist/data/utilities/getConditionIndexedList.js +2 -1
- package/dist/data/utilities/getConditionIndexedList.min.js +1 -1
- package/dist/data/utilities/matchIndexedJoins.js +3 -1
- package/dist/data/utilities/matchIndexedJoins.min.js +1 -1
- package/dist/data/utilities/mergeJoin.js +5 -1
- package/dist/data/utilities/mergeJoin.min.js +1 -1
- package/dist/data/utilities/parsers/findConditions.d.ts +5 -1
- package/dist/data/utilities/parsers/findConditions.js +15 -6
- package/dist/data/utilities/parsers/findConditions.min.js +1 -1
- package/dist/data/utilities/parsers/findInsertValues.js +3 -2
- package/dist/data/utilities/parsers/findInsertValues.min.js +1 -1
- package/dist/data/utilities/parsers/findSelects.js +6 -3
- package/dist/data/utilities/parsers/findSelects.min.js +1 -1
- package/dist/data/utilities/parsers/findSortClauses.js +5 -2
- package/dist/data/utilities/parsers/findSortClauses.min.js +1 -1
- package/dist/data/utilities/parsers/findUpdateValues.js +3 -2
- package/dist/data/utilities/parsers/findUpdateValues.min.js +1 -1
- package/dist/data/utilities/parsers/maskStrings.d.ts +39 -0
- package/dist/data/utilities/parsers/maskStrings.js +123 -0
- package/dist/data/utilities/parsers/maskStrings.min.js +1 -0
- package/dist/data/utilities/parsers/parseCreate.d.ts +20 -0
- package/dist/data/utilities/parsers/parseCreate.js +330 -0
- package/dist/data/utilities/parsers/parseCreate.min.js +1 -0
- package/dist/data/utilities/parsers/parseLiteralValue.d.ts +2 -1
- package/dist/data/utilities/parsers/parseLiteralValue.js +6 -3
- package/dist/data/utilities/parsers/parseLiteralValue.min.js +1 -1
- package/dist/data/utilities/parsers/parseQuery.d.ts +3 -0
- package/dist/data/utilities/parsers/parseQuery.js +28 -2
- package/dist/data/utilities/parsers/parseQuery.min.js +1 -1
- package/dist/data/utilities/parsers/parseSchemaStatement.d.ts +13 -0
- package/dist/data/utilities/parsers/parseSchemaStatement.js +82 -0
- package/dist/data/utilities/parsers/parseSchemaStatement.min.js +1 -0
- package/dist/data/utilities/parsers/scanQuery.d.ts +52 -0
- package/dist/data/utilities/parsers/scanQuery.js +158 -0
- package/dist/data/utilities/parsers/scanQuery.min.js +1 -0
- package/dist/data/utilities/parsers/splitQueries.d.ts +6 -0
- package/dist/data/utilities/parsers/splitQueries.js +20 -2
- package/dist/data/utilities/parsers/splitQueries.min.js +1 -1
- package/dist/data/utilities/parsers/startsQuery.d.ts +5 -0
- package/dist/data/utilities/parsers/startsQuery.js +10 -0
- package/dist/data/utilities/parsers/startsQuery.min.js +1 -0
- package/dist/data/utilities/recordExists.d.ts +6 -0
- package/dist/data/utilities/recordExists.js +18 -0
- package/dist/data/utilities/recordExists.min.js +1 -0
- package/dist/data/utilities/removeFromIndex.d.ts +2 -1
- package/dist/data/utilities/removeFromIndex.js +4 -2
- package/dist/data/utilities/removeFromIndex.min.js +1 -1
- package/dist/data/utilities/runQuery.js +49 -0
- package/dist/data/utilities/runQuery.min.js +1 -1
- package/dist/data/utilities/updateIndex.d.ts +2 -1
- package/dist/data/utilities/updateIndex.js +4 -2
- package/dist/data/utilities/updateIndex.min.js +1 -1
- package/dist/data/utilities/useJoinClause.js +8 -2
- package/dist/data/utilities/useJoinClause.min.js +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +14 -0
- package/dist/index.min.js +1 -1
- package/package.json +68 -55
|
@@ -2,7 +2,7 @@ import { recordDefinition } from './definitions/record';
|
|
|
2
2
|
import { keyProperties } from './definitions/key';
|
|
3
3
|
import { fieldProperties } from './definitions/field';
|
|
4
4
|
/**
|
|
5
|
-
* Create a new record.
|
|
5
|
+
* Create a new record. Throws if the definition is invalid (see assertValidDefinition).
|
|
6
6
|
* @param recordName
|
|
7
7
|
* @param definition
|
|
8
8
|
* @param keys
|
|
@@ -5,11 +5,41 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.create = void 0;
|
|
7
7
|
require("core-js/modules/es.json.stringify.js");
|
|
8
|
+
require("core-js/modules/esnext.iterator.constructor.js");
|
|
9
|
+
require("core-js/modules/esnext.iterator.find.js");
|
|
10
|
+
require("core-js/modules/esnext.iterator.some.js");
|
|
8
11
|
var _record = require("./definitions/record");
|
|
9
12
|
var _registerRecord = require("../utilities/registerRecord");
|
|
10
13
|
var _config = require("../utilities/config");
|
|
14
|
+
var _typeCheck = require("./policies/typeCheck");
|
|
11
15
|
/**
|
|
12
|
-
*
|
|
16
|
+
* Reject a definition that could never be written correctly, before anything is created: a
|
|
17
|
+
* default that fails its field's type check (otherwise every insert leaving that field out would
|
|
18
|
+
* fail instead), including a null default on a field that isn't nullable, and a nullable field in
|
|
19
|
+
* the primary key (an entry's file name comes from its primary key value).
|
|
20
|
+
* @param recordName
|
|
21
|
+
* @param recordContent
|
|
22
|
+
*/
|
|
23
|
+
const assertValidDefinition = (recordName, recordContent) => {
|
|
24
|
+
for (const field of recordContent.definition) {
|
|
25
|
+
if (!Object.prototype.hasOwnProperty.call(field, 'default')) {
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
try {
|
|
29
|
+
(0, _typeCheck.typeCheck)(field.type, field['default'], field.nullable);
|
|
30
|
+
} catch (err) {
|
|
31
|
+
throw new Error(`Invalid default for field "${field.name}" of ${recordName}: ${err.message}`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const primaryKey = recordContent.keys.find(key => key.type === 'primary');
|
|
35
|
+
for (const fieldName of primaryKey ? primaryKey.fields : []) {
|
|
36
|
+
if (recordContent.definition.some(field => field.name === fieldName && field.nullable)) {
|
|
37
|
+
throw new Error(`Primary key field "${fieldName}" of ${recordName} can't be nullable`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Create a new record. Throws if the definition is invalid (see assertValidDefinition).
|
|
13
43
|
* @param recordName
|
|
14
44
|
* @param definition
|
|
15
45
|
* @param keys
|
|
@@ -29,14 +59,15 @@ const create = async (recordName, definition = [], keys = []) => {
|
|
|
29
59
|
if (existsSync(`${databasePath}${recordName}.json`)) {
|
|
30
60
|
return null;
|
|
31
61
|
}
|
|
32
|
-
await mkdir(databasePath, {
|
|
33
|
-
recursive: true
|
|
34
|
-
});
|
|
35
62
|
const recordContent = (0, _record.record)({
|
|
36
63
|
path: recordName,
|
|
37
64
|
definition,
|
|
38
65
|
keys
|
|
39
66
|
});
|
|
67
|
+
assertValidDefinition(recordName, recordContent);
|
|
68
|
+
await mkdir(databasePath, {
|
|
69
|
+
recursive: true
|
|
70
|
+
});
|
|
40
71
|
await writeFile(`${databasePath}${recordName}.json`, JSON.stringify(recordContent, null, 2));
|
|
41
72
|
await mkdir(`${databasePath}${recordName}`, {
|
|
42
73
|
recursive: true
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.create=void 0,require("core-js/modules/es.json.stringify.js");var _record=require("./definitions/record"),_registerRecord=require("../utilities/registerRecord"),_config=require("../utilities/config");const create=async(e,r=[],
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.create=void 0,require("core-js/modules/es.json.stringify.js"),require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.find.js"),require("core-js/modules/esnext.iterator.some.js");var _record=require("./definitions/record"),_registerRecord=require("../utilities/registerRecord"),_config=require("../utilities/config"),_typeCheck=require("./policies/typeCheck");const assertValidDefinition=(e,r)=>{for(const t of r.definition)if(Object.prototype.hasOwnProperty.call(t,"default"))try{(0,_typeCheck.typeCheck)(t.type,t.default,t.nullable)}catch(r){throw new Error(`Invalid default for field "${t.name}" of ${e}: ${r.message}`)}const t=r.keys.find((e=>"primary"===e.type));for(const i of t?t.fields:[])if(r.definition.some((e=>e.name===i&&e.nullable)))throw new Error(`Primary key field "${i}" of ${e} can't be nullable`)},create=async(e,r=[],t=[])=>{const{writeFile:i,mkdir:s}=require("fs/promises"),{existsSync:o}=require("fs"),n=(0,_config.getSetting)("databasePath","database/");if("__RECORDS"===e)return null;if(o(`${n}${e}.json`))return null;const a=(0,_record.record)({path:e,definition:r,keys:t});return assertValidDefinition(e,a),await s(n,{recursive:!0}),await i(`${n}${e}.json`,JSON.stringify(a,null,2)),await s(`${n}${e}`,{recursive:!0}),await(0,_registerRecord.registerRecord)(e),a};exports.create=create;
|
|
@@ -3,6 +3,7 @@ export type fieldDefinition = {
|
|
|
3
3
|
name: fieldName;
|
|
4
4
|
type: string;
|
|
5
5
|
optional: boolean;
|
|
6
|
+
nullable?: boolean;
|
|
6
7
|
default?: any;
|
|
7
8
|
autoGenerate: boolean;
|
|
8
9
|
};
|
|
@@ -10,19 +11,22 @@ export type fieldProperties = {
|
|
|
10
11
|
name?: string;
|
|
11
12
|
type?: string;
|
|
12
13
|
optional?: boolean;
|
|
14
|
+
nullable?: boolean;
|
|
13
15
|
useDefault?: boolean;
|
|
14
16
|
defaultValue?: any;
|
|
15
17
|
autoGenerate?: boolean;
|
|
16
18
|
};
|
|
17
19
|
/**
|
|
18
|
-
* Generate a field for a record.
|
|
20
|
+
* Generate a field for a record. `nullable` is only stored when true (like `default`), so fields
|
|
21
|
+
* that never mention it, and schemas written before it existed, stay exactly as they were.
|
|
19
22
|
* @param properties
|
|
20
23
|
* @param properties.name
|
|
21
24
|
* @param properties.type
|
|
22
25
|
* @param properties.optional
|
|
26
|
+
* @param properties.nullable
|
|
23
27
|
* @param properties.useDefault
|
|
24
28
|
* @param properties.defaultValue
|
|
25
29
|
* @param properties.autoGenerate
|
|
26
30
|
*/
|
|
27
|
-
export declare const field: ({ name, type, optional, useDefault, defaultValue, autoGenerate }?: fieldProperties) => fieldDefinition;
|
|
31
|
+
export declare const field: ({ name, type, optional, nullable, useDefault, defaultValue, autoGenerate }?: fieldProperties) => fieldDefinition;
|
|
28
32
|
//# sourceMappingURL=field.d.ts.map
|
|
@@ -5,11 +5,13 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.field = void 0;
|
|
7
7
|
/**
|
|
8
|
-
* Generate a field for a record.
|
|
8
|
+
* Generate a field for a record. `nullable` is only stored when true (like `default`), so fields
|
|
9
|
+
* that never mention it, and schemas written before it existed, stay exactly as they were.
|
|
9
10
|
* @param properties
|
|
10
11
|
* @param properties.name
|
|
11
12
|
* @param properties.type
|
|
12
13
|
* @param properties.optional
|
|
14
|
+
* @param properties.nullable
|
|
13
15
|
* @param properties.useDefault
|
|
14
16
|
* @param properties.defaultValue
|
|
15
17
|
* @param properties.autoGenerate
|
|
@@ -18,6 +20,7 @@ const field = ({
|
|
|
18
20
|
name = '',
|
|
19
21
|
type = 'string',
|
|
20
22
|
optional = false,
|
|
23
|
+
nullable = false,
|
|
21
24
|
useDefault = false,
|
|
22
25
|
defaultValue = '',
|
|
23
26
|
autoGenerate = false
|
|
@@ -28,6 +31,9 @@ const field = ({
|
|
|
28
31
|
optional,
|
|
29
32
|
autoGenerate
|
|
30
33
|
};
|
|
34
|
+
if (nullable) {
|
|
35
|
+
returnField['nullable'] = true;
|
|
36
|
+
}
|
|
31
37
|
if (useDefault) {
|
|
32
38
|
returnField['default'] = defaultValue;
|
|
33
39
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.field=void 0;const field=({name:e="",type:t="string",optional:
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.field=void 0;const field=({name:e="",type:t="string",optional:l=!1,nullable:a=!1,useDefault:o=!1,defaultValue:n="",autoGenerate:u=!1}={})=>{const r={name:e,type:t,optional:l,autoGenerate:u};return a&&(r.nullable=!0),o&&(r.default=n),r};exports.field=field;
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { create as createRecord } from './create';
|
|
2
|
+
import { drop as dropRecord } from './drop';
|
|
3
|
+
import { describe as describeRecord } from './describe';
|
|
4
|
+
export declare const create: (...args: Parameters<typeof createRecord>) => ReturnType<typeof createRecord>;
|
|
5
|
+
export declare const drop: (...args: Parameters<typeof dropRecord>) => ReturnType<typeof dropRecord>;
|
|
6
|
+
export declare const describe: (...args: Parameters<typeof describeRecord>) => ReturnType<typeof describeRecord>;
|
|
4
7
|
export { fieldProperties, fieldDefinition, fieldName } from './definitions/field';
|
|
5
8
|
export { keyProperties, keyDefinition, indexType, indexLocation } from './definitions/key';
|
|
6
9
|
export { referenceProperties, reference } from './definitions/keyReference';
|
|
@@ -7,24 +7,15 @@ require("core-js/modules/esnext.iterator.drop.js");
|
|
|
7
7
|
Object.defineProperty(exports, "__esModule", {
|
|
8
8
|
value: true
|
|
9
9
|
});
|
|
10
|
-
|
|
11
|
-
enumerable: true,
|
|
12
|
-
get: function () {
|
|
13
|
-
return _create.create;
|
|
14
|
-
}
|
|
15
|
-
});
|
|
16
|
-
Object.defineProperty(exports, "describe", {
|
|
17
|
-
enumerable: true,
|
|
18
|
-
get: function () {
|
|
19
|
-
return _describe.describe;
|
|
20
|
-
}
|
|
21
|
-
});
|
|
22
|
-
Object.defineProperty(exports, "drop", {
|
|
23
|
-
enumerable: true,
|
|
24
|
-
get: function () {
|
|
25
|
-
return _drop.drop;
|
|
26
|
-
}
|
|
27
|
-
});
|
|
10
|
+
exports.drop = exports.describe = exports.create = void 0;
|
|
28
11
|
var _create = require("./create");
|
|
29
12
|
var _drop = require("./drop");
|
|
30
|
-
var _describe = require("./describe");
|
|
13
|
+
var _describe = require("./describe");
|
|
14
|
+
var _databaseLock = require("../utilities/databaseLock");
|
|
15
|
+
// The public versions take the database lock (see withDatabaseLock); code inside the package imports the files directly
|
|
16
|
+
const create = (...args) => (0, _databaseLock.withDatabaseLock)(() => (0, _create.create)(...args));
|
|
17
|
+
exports.create = create;
|
|
18
|
+
const drop = (...args) => (0, _databaseLock.withDatabaseLock)(() => (0, _drop.drop)(...args));
|
|
19
|
+
exports.drop = drop;
|
|
20
|
+
const describe = (...args) => (0, _databaseLock.withDatabaseLock)(() => (0, _describe.describe)(...args));
|
|
21
|
+
exports.describe = describe;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";require("core-js/modules/esnext.async-iterator.constructor.js"),require("core-js/modules/esnext.async-iterator.drop.js"),require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.drop.js"),Object.defineProperty(exports,"__esModule",{value:!0}),
|
|
1
|
+
"use strict";require("core-js/modules/esnext.async-iterator.constructor.js"),require("core-js/modules/esnext.async-iterator.drop.js"),require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.drop.js"),Object.defineProperty(exports,"__esModule",{value:!0}),exports.drop=exports.describe=exports.create=void 0;var _create=require("./create"),_drop=require("./drop"),_describe=require("./describe"),_databaseLock=require("../utilities/databaseLock");const create=(...e)=>(0,_databaseLock.withDatabaseLock)((()=>(0,_create.create)(...e)));exports.create=create;const drop=(...e)=>(0,_databaseLock.withDatabaseLock)((()=>(0,_drop.drop)(...e)));exports.drop=drop;const describe=(...e)=>(0,_databaseLock.withDatabaseLock)((()=>(0,_describe.describe)(...e)));exports.describe=describe;
|
|
@@ -6,6 +6,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.foreignKeyExists = void 0;
|
|
7
7
|
var _retrieveRecords = require("../../utilities/retrieveRecords");
|
|
8
8
|
var _where = require("../../queries/where");
|
|
9
|
+
var _retrieveRecord = require("../../utilities/retrieveRecord");
|
|
10
|
+
var _fieldType = require("../../utilities/fieldType");
|
|
9
11
|
/**
|
|
10
12
|
* Check whether any record in the referenced entity has the given property set to the given
|
|
11
13
|
* value - the mirror image of keyUnique(), which checks that no record already has a value.
|
|
@@ -15,10 +17,12 @@ var _where = require("../../queries/where");
|
|
|
15
17
|
*/
|
|
16
18
|
const foreignKeyExists = async (entity, property, value) => {
|
|
17
19
|
const records = await (0, _retrieveRecords.retrieveRecords)(entity);
|
|
20
|
+
const type = (0, _fieldType.fieldType)(await (0, _retrieveRecord.retrieveRecord)(entity), property);
|
|
18
21
|
const found = (0, _where.where)(records, {
|
|
19
22
|
property,
|
|
20
23
|
comparator: '=',
|
|
21
|
-
value
|
|
24
|
+
value,
|
|
25
|
+
type
|
|
22
26
|
});
|
|
23
27
|
return found.length > 0;
|
|
24
28
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.foreignKeyExists=void 0;var _retrieveRecords=require("../../utilities/retrieveRecords"),_where=require("../../queries/where");const foreignKeyExists=async(e,r,
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.foreignKeyExists=void 0;var _retrieveRecords=require("../../utilities/retrieveRecords"),_where=require("../../queries/where"),_retrieveRecord=require("../../utilities/retrieveRecord"),_fieldType=require("../../utilities/fieldType");const foreignKeyExists=async(e,r,i)=>{const t=await(0,_retrieveRecords.retrieveRecords)(e),s=(0,_fieldType.fieldType)(await(0,_retrieveRecord.retrieveRecord)(e),r);return(0,_where.where)(t,{property:r,comparator:"=",value:i,type:s}).length>0};exports.foreignKeyExists=foreignKeyExists;
|
|
@@ -8,6 +8,7 @@ var _describe = require("../describe");
|
|
|
8
8
|
var _retrieveRecord = require("../../utilities/retrieveRecord");
|
|
9
9
|
var _retrieveRecords = require("../../utilities/retrieveRecords");
|
|
10
10
|
var _where = require("../../queries/where");
|
|
11
|
+
var _fieldType = require("../../utilities/fieldType");
|
|
11
12
|
var _splitEntityProperty = require("../../utilities/parsers/splitEntityProperty");
|
|
12
13
|
/**
|
|
13
14
|
* Check whether any other record, in any entity, still has a single-field foreign key pointing
|
|
@@ -40,7 +41,8 @@ const hasDependents = async (entity, property, value) => {
|
|
|
40
41
|
const found = (0, _where.where)(records, {
|
|
41
42
|
property: key.fields[0],
|
|
42
43
|
comparator: '=',
|
|
43
|
-
value
|
|
44
|
+
value,
|
|
45
|
+
type: (0, _fieldType.fieldType)(otherRecord, key.fields[0])
|
|
44
46
|
});
|
|
45
47
|
if (found.length) {
|
|
46
48
|
return true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.hasDependents=void 0;var _describe=require("../describe"),_retrieveRecord=require("../../utilities/retrieveRecord"),_retrieveRecords=require("../../utilities/retrieveRecords"),_where=require("../../queries/where"),_splitEntityProperty=require("../../utilities/parsers/splitEntityProperty");const hasDependents=async(e,r,t)=>{const i=await(0,_describe.describe)();for(const s of i){const i=s.replace(/\.json$/,""),o=await(0,_retrieveRecord.retrieveRecord)(i);for(const s of o.keys){if("foreign"!==s.type||1!==s.fields.length||!s.references||1!==s.references.length)continue;const{entity:
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.hasDependents=void 0;var _describe=require("../describe"),_retrieveRecord=require("../../utilities/retrieveRecord"),_retrieveRecords=require("../../utilities/retrieveRecords"),_where=require("../../queries/where"),_fieldType=require("../../utilities/fieldType"),_splitEntityProperty=require("../../utilities/parsers/splitEntityProperty");const hasDependents=async(e,r,t)=>{const i=await(0,_describe.describe)();for(const s of i){const i=s.replace(/\.json$/,""),o=await(0,_retrieveRecord.retrieveRecord)(i);for(const s of o.keys){if("foreign"!==s.type||1!==s.fields.length||!s.references||1!==s.references.length)continue;const{entity:n,property:c}=(0,_splitEntityProperty.splitEntityProperty)(s.references[0].fields[0]);if(n!==e||c!==r)continue;const p=await(0,_retrieveRecords.retrieveRecords)(i);if((0,_where.where)(p,{property:s.fields[0],comparator:"=",value:t,type:(0,_fieldType.fieldType)(o,s.fields[0])}).length)return!0}}return!1};exports.hasDependents=hasDependents;
|
|
@@ -6,6 +6,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.keyUnique = void 0;
|
|
7
7
|
var _retrieveRecords = require("../../utilities/retrieveRecords");
|
|
8
8
|
var _where = require("../../queries/where");
|
|
9
|
+
var _retrieveRecord = require("../../utilities/retrieveRecord");
|
|
10
|
+
var _fieldType = require("../../utilities/fieldType");
|
|
9
11
|
/**
|
|
10
12
|
* Check that no existing record already has this combination of values across all of the given
|
|
11
13
|
* fields - a single field for a normal unique/primary key, or several for a composite one.
|
|
@@ -19,11 +21,13 @@ const keyUnique = async (entity, references = [], checkKeys = []) => {
|
|
|
19
21
|
return false;
|
|
20
22
|
}
|
|
21
23
|
let records = await (0, _retrieveRecords.retrieveRecords)(entity);
|
|
24
|
+
const record = await (0, _retrieveRecord.retrieveRecord)(entity);
|
|
22
25
|
for (let i = 0; i < references.length; i++) {
|
|
23
26
|
records = (0, _where.where)(records, {
|
|
24
27
|
property: references[i],
|
|
25
28
|
comparator: '=',
|
|
26
|
-
value: checkKeys[i]
|
|
29
|
+
value: checkKeys[i],
|
|
30
|
+
type: (0, _fieldType.fieldType)(record, references[i])
|
|
27
31
|
});
|
|
28
32
|
}
|
|
29
33
|
return !records.length;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.keyUnique=void 0;var _retrieveRecords=require("../../utilities/retrieveRecords"),_where=require("../../queries/where");const keyUnique=async(e,r=[],t=[])=>{if(!r.length||r.length!==t.length)return!1;let i=await(0,_retrieveRecords.retrieveRecords)(e);for(let e=0;e<r.length;e++)i=(0,_where.where)(i,{property:r[e],comparator:"=",value:t[e]});return!i.length};exports.keyUnique=keyUnique;
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.keyUnique=void 0;var _retrieveRecords=require("../../utilities/retrieveRecords"),_where=require("../../queries/where"),_retrieveRecord=require("../../utilities/retrieveRecord"),_fieldType=require("../../utilities/fieldType");const keyUnique=async(e,r=[],t=[])=>{if(!r.length||r.length!==t.length)return!1;let i=await(0,_retrieveRecords.retrieveRecords)(e);const o=await(0,_retrieveRecord.retrieveRecord)(e);for(let e=0;e<r.length;e++)i=(0,_where.where)(i,{property:r[e],comparator:"=",value:t[e],type:(0,_fieldType.fieldType)(o,r[e])});return!i.length};exports.keyUnique=keyUnique;
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The type names typeCheck knows. The create statement accepts only these; create() accepts any name (see below).
|
|
3
|
+
*/
|
|
4
|
+
export declare const fieldTypes: string[];
|
|
1
5
|
/**
|
|
2
6
|
* Validate (and where sensible, coerce) a value against a field's declared type. Runs only
|
|
3
7
|
* against values being written by insertEntity/updateEntity - it never re-validates data already
|
|
@@ -5,8 +9,12 @@
|
|
|
5
9
|
* happen, since nothing enforced this before) is left alone until something actually updates it.
|
|
6
10
|
* An unrecognized type name is treated as unconstrained rather than rejected, so a typo in a
|
|
7
11
|
* schema's field type can't silently block every write to that field.
|
|
12
|
+
*
|
|
13
|
+
* A null is a real JSON null, kept as it is for a nullable field and rejected for any other, of
|
|
14
|
+
* any type: it is never coerced, so a string field can't store the text "null" or an int field 0.
|
|
8
15
|
* @param type
|
|
9
16
|
* @param value
|
|
17
|
+
* @param nullable - Whether the field may hold null (the field definition's `nullable`).
|
|
10
18
|
*/
|
|
11
|
-
export declare const typeCheck: (type?: string, value?: any) => any;
|
|
19
|
+
export declare const typeCheck: (type?: string, value?: any, nullable?: boolean) => any;
|
|
12
20
|
//# sourceMappingURL=typeCheck.d.ts.map
|
|
@@ -3,7 +3,11 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.typeCheck = void 0;
|
|
6
|
+
exports.typeCheck = exports.fieldTypes = void 0;
|
|
7
|
+
/**
|
|
8
|
+
* The type names typeCheck knows. The create statement accepts only these; create() accepts any name (see below).
|
|
9
|
+
*/
|
|
10
|
+
const fieldTypes = exports.fieldTypes = ['string', 'int', 'boolean', 'object', 'array'];
|
|
7
11
|
/**
|
|
8
12
|
* Validate (and where sensible, coerce) a value against a field's declared type. Runs only
|
|
9
13
|
* against values being written by insertEntity/updateEntity - it never re-validates data already
|
|
@@ -11,13 +15,23 @@ exports.typeCheck = void 0;
|
|
|
11
15
|
* happen, since nothing enforced this before) is left alone until something actually updates it.
|
|
12
16
|
* An unrecognized type name is treated as unconstrained rather than rejected, so a typo in a
|
|
13
17
|
* schema's field type can't silently block every write to that field.
|
|
18
|
+
*
|
|
19
|
+
* A null is a real JSON null, kept as it is for a nullable field and rejected for any other, of
|
|
20
|
+
* any type: it is never coerced, so a string field can't store the text "null" or an int field 0.
|
|
14
21
|
* @param type
|
|
15
22
|
* @param value
|
|
23
|
+
* @param nullable - Whether the field may hold null (the field definition's `nullable`).
|
|
16
24
|
*/
|
|
17
|
-
const typeCheck = (type = 'string', value = undefined) => {
|
|
25
|
+
const typeCheck = (type = 'string', value = undefined, nullable = false) => {
|
|
18
26
|
if (typeof value === 'undefined') {
|
|
19
27
|
return value;
|
|
20
28
|
}
|
|
29
|
+
if (value === null) {
|
|
30
|
+
if (nullable) {
|
|
31
|
+
return value;
|
|
32
|
+
}
|
|
33
|
+
throw new Error('Value "null" is not allowed: the field is not nullable');
|
|
34
|
+
}
|
|
21
35
|
switch (type) {
|
|
22
36
|
case 'string':
|
|
23
37
|
return typeof value === 'string' ? value : String(value);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.typeCheck=void 0;const typeCheck=(
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.typeCheck=exports.fieldTypes=void 0;const fieldTypes=exports.fieldTypes=["string","int","boolean","object","array"],typeCheck=(e="string",r=void 0,t=!1)=>{if(void 0===r)return r;if(null===r){if(t)return r;throw new Error('Value "null" is not allowed: the field is not nullable')}switch(e){case"string":return"string"==typeof r?r:String(r);case"int":{const e=Number(r);if(Number.isNaN(e)||!Number.isInteger(e))throw new Error(`Value "${r}" is not a valid int`);return e}case"boolean":if("boolean"==typeof r)return r;if("true"===r)return!0;if("false"===r)return!1;throw new Error(`Value "${r}" is not a valid boolean`);case"object":if("object"!=typeof r||null===r||Array.isArray(r))throw new Error(`Value "${r}" is not a valid object`);return r;case"array":if(!Array.isArray(r))throw new Error(`Value "${r}" is not a valid array`);return r;default:return r}};exports.typeCheck=typeCheck;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { recordDefinition } from '../introspect/definitions/record';
|
|
2
|
+
import { ParsedCreate } from '../utilities/parsers/parseCreate';
|
|
3
|
+
/**
|
|
4
|
+
* Run a parsed create statement: an error if the record already exists, unless the statement says
|
|
5
|
+
* `if not exists` (then nothing happens and the result is null). Otherwise create() it and resolve to its
|
|
6
|
+
* definition, as create() does.
|
|
7
|
+
* @param entity
|
|
8
|
+
* @param parsed
|
|
9
|
+
*/
|
|
10
|
+
export declare const createRecord: (entity: string, parsed: ParsedCreate) => Promise<recordDefinition | null>;
|
|
11
|
+
//# sourceMappingURL=createRecord.d.ts.map
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.createRecord = void 0;
|
|
7
|
+
require("core-js/modules/es.array.includes.js");
|
|
8
|
+
require("core-js/modules/esnext.iterator.constructor.js");
|
|
9
|
+
require("core-js/modules/esnext.iterator.map.js");
|
|
10
|
+
var _create = require("../introspect/create");
|
|
11
|
+
var _retrieveRecord = require("../utilities/retrieveRecord");
|
|
12
|
+
var _splitEntityProperty = require("../utilities/parsers/splitEntityProperty");
|
|
13
|
+
var _recordExists = require("../utilities/recordExists");
|
|
14
|
+
/**
|
|
15
|
+
* Reject a foreign key whose referenced record, or field on it, doesn't exist. A key referencing the record being
|
|
16
|
+
* created is checked against its own fields.
|
|
17
|
+
* @param entity
|
|
18
|
+
* @param parsed
|
|
19
|
+
*/
|
|
20
|
+
const assertReferencesExist = async (entity, parsed) => {
|
|
21
|
+
for (const key of parsed.keys) {
|
|
22
|
+
if (key.type !== 'foreign') {
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
const {
|
|
26
|
+
entity: refEntity,
|
|
27
|
+
property: refProperty
|
|
28
|
+
} = (0, _splitEntityProperty.splitEntityProperty)(key.references[0].fields[0]);
|
|
29
|
+
let fields = parsed.definition.map(field => field.name);
|
|
30
|
+
if (refEntity !== entity) {
|
|
31
|
+
if (!(0, _recordExists.recordExists)(refEntity)) {
|
|
32
|
+
throw new Error(`Foreign key "${key.fields[0]}" references "${refEntity}", which doesn't exist`);
|
|
33
|
+
}
|
|
34
|
+
fields = (await (0, _retrieveRecord.retrieveRecord)(refEntity)).definition.map(field => field.name);
|
|
35
|
+
}
|
|
36
|
+
if (!fields.includes(refProperty)) {
|
|
37
|
+
throw new Error(`Foreign key "${key.fields[0]}" references "${refEntity}.${refProperty}", which is not a field`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Run a parsed create statement: an error if the record already exists, unless the statement says
|
|
43
|
+
* `if not exists` (then nothing happens and the result is null). Otherwise create() it and resolve to its
|
|
44
|
+
* definition, as create() does.
|
|
45
|
+
* @param entity
|
|
46
|
+
* @param parsed
|
|
47
|
+
*/
|
|
48
|
+
const createRecord = async (entity, parsed) => {
|
|
49
|
+
if ((0, _recordExists.recordExists)(entity)) {
|
|
50
|
+
if (parsed.ifNotExists) {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
throw new Error(`Record "${entity}" already exists`);
|
|
54
|
+
}
|
|
55
|
+
await assertReferencesExist(entity, parsed);
|
|
56
|
+
return (0, _create.create)(entity, parsed.definition, parsed.keys);
|
|
57
|
+
};
|
|
58
|
+
exports.createRecord = createRecord;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.createRecord=void 0,require("core-js/modules/es.array.includes.js"),require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.map.js");var _create=require("../introspect/create"),_retrieveRecord=require("../utilities/retrieveRecord"),_splitEntityProperty=require("../utilities/parsers/splitEntityProperty"),_recordExists=require("../utilities/recordExists");const assertReferencesExist=async(e,r)=>{for(const t of r.keys){if("foreign"!==t.type)continue;const{entity:i,property:s}=(0,_splitEntityProperty.splitEntityProperty)(t.references[0].fields[0]);let o=r.definition.map((e=>e.name));if(i!==e){if(!(0,_recordExists.recordExists)(i))throw new Error(`Foreign key "${t.fields[0]}" references "${i}", which doesn't exist`);o=(await(0,_retrieveRecord.retrieveRecord)(i)).definition.map((e=>e.name))}if(!o.includes(s))throw new Error(`Foreign key "${t.fields[0]}" references "${i}.${s}", which is not a field`)}},createRecord=async(e,r)=>{if((0,_recordExists.recordExists)(e)){if(r.ifNotExists)return null;throw new Error(`Record "${e}" already exists`)}return await assertReferencesExist(e,r),(0,_create.create)(e,r.definition,r.keys)};exports.createRecord=createRecord;
|
|
@@ -28,6 +28,7 @@ var _retrieveRecord = require("../utilities/retrieveRecord");
|
|
|
28
28
|
var _retrieveFile = require("../utilities/retrieveFile");
|
|
29
29
|
var _removeFromIndex = require("../utilities/removeFromIndex");
|
|
30
30
|
var _computeKeyValue = require("../utilities/computeKeyValue");
|
|
31
|
+
var _fieldType = require("../utilities/fieldType");
|
|
31
32
|
var _hasDependents = require("../introspect/policies/hasDependents");
|
|
32
33
|
var _config = require("../utilities/config");
|
|
33
34
|
const {
|
|
@@ -75,7 +76,7 @@ const removeMatchingEntries = async (entity, record, primaryKey, deletedValues)
|
|
|
75
76
|
}
|
|
76
77
|
await rm(`${databasePath}${record.path}/${fileName}`);
|
|
77
78
|
for (const key of record.keys) {
|
|
78
|
-
await (0, _removeFromIndex.removeFromIndex)(record.path, key, (0, _computeKeyValue.computeKeyValue)(key.fields, data), fileName);
|
|
79
|
+
await (0, _removeFromIndex.removeFromIndex)(record.path, key, (0, _computeKeyValue.computeKeyValue)(key.fields, data), fileName, (0, _fieldType.keyValueType)(record, key));
|
|
79
80
|
}
|
|
80
81
|
}
|
|
81
82
|
return remainingEntries;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.deleteEntity=void 0,require("core-js/modules/es.json.stringify.js"),require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.find.js"),require("core-js/modules/esnext.iterator.map.js"),require("core-js/modules/esnext.set.add-all.js"),require("core-js/modules/esnext.set.delete-all.js"),require("core-js/modules/esnext.set.difference.js"),require("core-js/modules/esnext.set.every.js"),require("core-js/modules/esnext.set.filter.js"),require("core-js/modules/esnext.set.find.js"),require("core-js/modules/esnext.set.intersection.js"),require("core-js/modules/esnext.set.is-disjoint-from.js"),require("core-js/modules/esnext.set.is-subset-of.js"),require("core-js/modules/esnext.set.is-superset-of.js"),require("core-js/modules/esnext.set.join.js"),require("core-js/modules/esnext.set.map.js"),require("core-js/modules/esnext.set.reduce.js"),require("core-js/modules/esnext.set.some.js"),require("core-js/modules/esnext.set.symmetric-difference.js"),require("core-js/modules/esnext.set.union.js");var _retrieveRecord=require("../utilities/retrieveRecord"),_retrieveFile=require("../utilities/retrieveFile"),_removeFromIndex=require("../utilities/removeFromIndex"),_computeKeyValue=require("../utilities/computeKeyValue"),_hasDependents=require("../introspect/policies/hasDependents"),_config=require("../utilities/config");const{rm:rm,writeFile:writeFile}=require("fs/promises"),assertNoDependents=async(e,r,s)=>{if(!(0,_config.getSetting)("enforceForeignKeys",!0)||1!==r.fields.length)return;const t=r.fields[0];for(const r of s)if(await(0,_hasDependents.hasDependents)(e,t,r[t]))throw new Error(`Cannot delete from "${e}" where "${t}" = ${r[t]} - other records still reference it`)},removeMatchingEntries=async(e,r,s,t)=>{const i=(0,_config.getSetting)("databasePath","database/"),o=[];for(const e of r.entries){const n=await(0,_retrieveFile.retrieveFile)(`${r.path}/${e}`);if(t.has((0,_computeKeyValue.computeKeyValue)(s.fields,n))){await rm(`${i}${r.path}/${e}`);for(const s of r.keys)await(0,_removeFromIndex.removeFromIndex)(r.path,s,(0,_computeKeyValue.computeKeyValue)(s.fields,n),e)}else o.push(e)}return o},deleteEntity=async(e="",r={})=>{const s=(0,_config.getSetting)("databasePath","database/"),t=await(0,_retrieveRecord.retrieveRecord)(e),i=t.keys.find((e=>"primary"===e.type));if(!i)throw new Error(`Cannot delete from "${e}" without a primary key`);const o=r[e]||[];if(!o.length)return r;await assertNoDependents(e,i,o);const n=new Set(o.map((e=>(0,_computeKeyValue.computeKeyValue)(i.fields,e))));return t.entries=await removeMatchingEntries(0,t,i,n),await writeFile(`${s}${t.path}.json`,JSON.stringify(t,null,2)),r};exports.deleteEntity=deleteEntity;
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.deleteEntity=void 0,require("core-js/modules/es.json.stringify.js"),require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.find.js"),require("core-js/modules/esnext.iterator.map.js"),require("core-js/modules/esnext.set.add-all.js"),require("core-js/modules/esnext.set.delete-all.js"),require("core-js/modules/esnext.set.difference.js"),require("core-js/modules/esnext.set.every.js"),require("core-js/modules/esnext.set.filter.js"),require("core-js/modules/esnext.set.find.js"),require("core-js/modules/esnext.set.intersection.js"),require("core-js/modules/esnext.set.is-disjoint-from.js"),require("core-js/modules/esnext.set.is-subset-of.js"),require("core-js/modules/esnext.set.is-superset-of.js"),require("core-js/modules/esnext.set.join.js"),require("core-js/modules/esnext.set.map.js"),require("core-js/modules/esnext.set.reduce.js"),require("core-js/modules/esnext.set.some.js"),require("core-js/modules/esnext.set.symmetric-difference.js"),require("core-js/modules/esnext.set.union.js");var _retrieveRecord=require("../utilities/retrieveRecord"),_retrieveFile=require("../utilities/retrieveFile"),_removeFromIndex=require("../utilities/removeFromIndex"),_computeKeyValue=require("../utilities/computeKeyValue"),_fieldType=require("../utilities/fieldType"),_hasDependents=require("../introspect/policies/hasDependents"),_config=require("../utilities/config");const{rm:rm,writeFile:writeFile}=require("fs/promises"),assertNoDependents=async(e,r,s)=>{if(!(0,_config.getSetting)("enforceForeignKeys",!0)||1!==r.fields.length)return;const t=r.fields[0];for(const r of s)if(await(0,_hasDependents.hasDependents)(e,t,r[t]))throw new Error(`Cannot delete from "${e}" where "${t}" = ${r[t]} - other records still reference it`)},removeMatchingEntries=async(e,r,s,t)=>{const i=(0,_config.getSetting)("databasePath","database/"),o=[];for(const e of r.entries){const n=await(0,_retrieveFile.retrieveFile)(`${r.path}/${e}`);if(t.has((0,_computeKeyValue.computeKeyValue)(s.fields,n))){await rm(`${i}${r.path}/${e}`);for(const s of r.keys)await(0,_removeFromIndex.removeFromIndex)(r.path,s,(0,_computeKeyValue.computeKeyValue)(s.fields,n),e,(0,_fieldType.keyValueType)(r,s))}else o.push(e)}return o},deleteEntity=async(e="",r={})=>{const s=(0,_config.getSetting)("databasePath","database/"),t=await(0,_retrieveRecord.retrieveRecord)(e),i=t.keys.find((e=>"primary"===e.type));if(!i)throw new Error(`Cannot delete from "${e}" without a primary key`);const o=r[e]||[];if(!o.length)return r;await assertNoDependents(e,i,o);const n=new Set(o.map((e=>(0,_computeKeyValue.computeKeyValue)(i.fields,e))));return t.entries=await removeMatchingEntries(0,t,i,n),await writeFile(`${s}${t.path}.json`,JSON.stringify(t,null,2)),r};exports.deleteEntity=deleteEntity;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { recordDefinition } from '../introspect/definitions/record';
|
|
2
|
+
export type recordDescription = Pick<recordDefinition, 'path' | 'definition' | 'keys'>;
|
|
3
|
+
/**
|
|
4
|
+
* Run a parsed describe statement: the record's fields and keys (describe() in JS gives only the fields). An error
|
|
5
|
+
* if the record doesn't exist.
|
|
6
|
+
* @param entity
|
|
7
|
+
*/
|
|
8
|
+
export declare const describeRecord: (entity: string) => Promise<recordDescription>;
|
|
9
|
+
//# sourceMappingURL=describeRecord.d.ts.map
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.describeRecord = void 0;
|
|
7
|
+
var _retrieveRecord = require("../utilities/retrieveRecord");
|
|
8
|
+
var _recordExists = require("../utilities/recordExists");
|
|
9
|
+
/**
|
|
10
|
+
* Run a parsed describe statement: the record's fields and keys (describe() in JS gives only the fields). An error
|
|
11
|
+
* if the record doesn't exist.
|
|
12
|
+
* @param entity
|
|
13
|
+
*/
|
|
14
|
+
const describeRecord = async entity => {
|
|
15
|
+
if (!(0, _recordExists.recordExists)(entity)) {
|
|
16
|
+
throw new Error(`Record "${entity}" doesn't exist`);
|
|
17
|
+
}
|
|
18
|
+
const {
|
|
19
|
+
path,
|
|
20
|
+
definition,
|
|
21
|
+
keys
|
|
22
|
+
} = await (0, _retrieveRecord.retrieveRecord)(entity);
|
|
23
|
+
return {
|
|
24
|
+
path,
|
|
25
|
+
definition,
|
|
26
|
+
keys
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
exports.describeRecord = describeRecord;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.describeRecord=void 0;var _retrieveRecord=require("../utilities/retrieveRecord"),_recordExists=require("../utilities/recordExists");const describeRecord=async e=>{if(!(0,_recordExists.recordExists)(e))throw new Error(`Record "${e}" doesn't exist`);const{path:r,definition:i,keys:t}=await(0,_retrieveRecord.retrieveRecord)(e);return{path:r,definition:i,keys:t}};exports.describeRecord=describeRecord;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { recordDefinition } from '../introspect/definitions/record';
|
|
2
|
+
/**
|
|
3
|
+
* Run a parsed drop statement: an error if the record doesn't exist, unless the statement says `if exists` (then
|
|
4
|
+
* nothing happens and the result is null). Otherwise drop() it and resolve to the definition it had.
|
|
5
|
+
* @param entity
|
|
6
|
+
* @param ifExists
|
|
7
|
+
*/
|
|
8
|
+
export declare const dropRecord: (entity: string, ifExists: boolean) => Promise<recordDefinition | null>;
|
|
9
|
+
//# sourceMappingURL=dropRecord.d.ts.map
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
require("core-js/modules/esnext.async-iterator.constructor.js");
|
|
4
|
+
require("core-js/modules/esnext.async-iterator.drop.js");
|
|
5
|
+
require("core-js/modules/esnext.iterator.drop.js");
|
|
6
|
+
Object.defineProperty(exports, "__esModule", {
|
|
7
|
+
value: true
|
|
8
|
+
});
|
|
9
|
+
exports.dropRecord = void 0;
|
|
10
|
+
require("core-js/modules/esnext.iterator.constructor.js");
|
|
11
|
+
require("core-js/modules/esnext.iterator.some.js");
|
|
12
|
+
var _drop = require("../introspect/drop");
|
|
13
|
+
var _retrieveRecord = require("../utilities/retrieveRecord");
|
|
14
|
+
var _recordExists = require("../utilities/recordExists");
|
|
15
|
+
var _splitEntityProperty = require("../utilities/parsers/splitEntityProperty");
|
|
16
|
+
var _config = require("../utilities/config");
|
|
17
|
+
/**
|
|
18
|
+
* RESTRICT, as MySQL does for a referenced table: reject dropping a record while another record has a foreign key
|
|
19
|
+
* referencing it, since every write to that record would then fail looking for the dropped one. A record referencing
|
|
20
|
+
* itself doesn't count. Off with enforceForeignKeys, like the row-level checks.
|
|
21
|
+
* @param entity
|
|
22
|
+
*/
|
|
23
|
+
const assertNotReferenced = async entity => {
|
|
24
|
+
if (!(0, _config.getSetting)('enforceForeignKeys', true) || !(0, _recordExists.recordExists)('__RECORDS')) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const registry = await (0, _retrieveRecord.retrieveRecord)('__RECORDS');
|
|
28
|
+
for (const fileName of registry.entries) {
|
|
29
|
+
const other = fileName.replace(/\.json$/, '');
|
|
30
|
+
if (other === entity || !(0, _recordExists.recordExists)(other)) {
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
for (const key of (await (0, _retrieveRecord.retrieveRecord)(other)).keys) {
|
|
34
|
+
if (key.type !== 'foreign' || !key.references) {
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
if (key.references.some(reference => (0, _splitEntityProperty.splitEntityProperty)(reference.fields[0]).entity === entity)) {
|
|
38
|
+
throw new Error(`Cannot drop "${entity}": ${other}.${key.fields.join(', ')} references it`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Run a parsed drop statement: an error if the record doesn't exist, unless the statement says `if exists` (then
|
|
45
|
+
* nothing happens and the result is null). Otherwise drop() it and resolve to the definition it had.
|
|
46
|
+
* @param entity
|
|
47
|
+
* @param ifExists
|
|
48
|
+
*/
|
|
49
|
+
const dropRecord = async (entity, ifExists) => {
|
|
50
|
+
if (!(0, _recordExists.recordExists)(entity)) {
|
|
51
|
+
if (ifExists) {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
throw new Error(`Record "${entity}" doesn't exist`);
|
|
55
|
+
}
|
|
56
|
+
await assertNotReferenced(entity);
|
|
57
|
+
const record = await (0, _retrieveRecord.retrieveRecord)(entity);
|
|
58
|
+
await (0, _drop.drop)(entity);
|
|
59
|
+
return record;
|
|
60
|
+
};
|
|
61
|
+
exports.dropRecord = dropRecord;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";require("core-js/modules/esnext.async-iterator.constructor.js"),require("core-js/modules/esnext.async-iterator.drop.js"),require("core-js/modules/esnext.iterator.drop.js"),Object.defineProperty(exports,"__esModule",{value:!0}),exports.dropRecord=void 0,require("core-js/modules/esnext.iterator.constructor.js"),require("core-js/modules/esnext.iterator.some.js");var _drop=require("../introspect/drop"),_retrieveRecord=require("../utilities/retrieveRecord"),_recordExists=require("../utilities/recordExists"),_splitEntityProperty=require("../utilities/parsers/splitEntityProperty"),_config=require("../utilities/config");const assertNotReferenced=async e=>{if(!(0,_config.getSetting)("enforceForeignKeys",!0)||!(0,_recordExists.recordExists)("__RECORDS"))return;const r=await(0,_retrieveRecord.retrieveRecord)("__RECORDS");for(const t of r.entries){const r=t.replace(/\.json$/,"");if(r!==e&&(0,_recordExists.recordExists)(r))for(const t of(await(0,_retrieveRecord.retrieveRecord)(r)).keys)if("foreign"===t.type&&t.references&&t.references.some((r=>(0,_splitEntityProperty.splitEntityProperty)(r.fields[0]).entity===e)))throw new Error(`Cannot drop "${e}": ${r}.${t.fields.join(", ")} references it`)}},dropRecord=async(e,r)=>{if(!(0,_recordExists.recordExists)(e)){if(r)return null;throw new Error(`Record "${e}" doesn't exist`)}await assertNotReferenced(e);const t=await(0,_retrieveRecord.retrieveRecord)(e);return await(0,_drop.drop)(e),t};exports.dropRecord=dropRecord;
|