@onyx.dev/onyx-database 0.3.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +71 -1
- package/dist/gen/cli/generate.cjs +313 -30
- package/dist/gen/cli/generate.cjs.map +1 -1
- package/dist/index.cjs +329 -36
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +92 -6
- package/dist/index.d.ts +92 -6
- package/dist/index.js +328 -37
- package/dist/index.js.map +1 -1
- package/dist/schema/cli/schema.cjs +496 -35
- package/dist/schema/cli/schema.cjs.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -69,7 +69,7 @@ function readEnv(targetId) {
|
|
|
69
69
|
return res;
|
|
70
70
|
}
|
|
71
71
|
async function readProjectFile(databaseId) {
|
|
72
|
-
if (!isNode) return {};
|
|
72
|
+
if (!isNode) return { config: {} };
|
|
73
73
|
const fs = await nodeImport("node:fs/promises");
|
|
74
74
|
const path = await nodeImport("node:path");
|
|
75
75
|
const cwd = gProcess?.cwd?.() ?? ".";
|
|
@@ -78,7 +78,7 @@ async function readProjectFile(databaseId) {
|
|
|
78
78
|
const sanitized = txt.replace(/[\r\n]+/g, "");
|
|
79
79
|
const json = dropUndefined(JSON.parse(sanitized));
|
|
80
80
|
dbg("project file:", p, "\u2192", mask(json));
|
|
81
|
-
return json;
|
|
81
|
+
return { config: json, path: p };
|
|
82
82
|
};
|
|
83
83
|
if (databaseId) {
|
|
84
84
|
const specific = path.resolve(cwd, `onyx-database-${databaseId}.json`);
|
|
@@ -93,11 +93,11 @@ async function readProjectFile(databaseId) {
|
|
|
93
93
|
return await tryRead(fallback);
|
|
94
94
|
} catch {
|
|
95
95
|
dbg("project file not found:", fallback);
|
|
96
|
-
return {};
|
|
96
|
+
return { config: {} };
|
|
97
97
|
}
|
|
98
98
|
}
|
|
99
99
|
async function readHomeProfile(databaseId) {
|
|
100
|
-
if (!isNode) return {};
|
|
100
|
+
if (!isNode) return { config: {} };
|
|
101
101
|
const fs = await nodeImport("node:fs/promises");
|
|
102
102
|
const os = await nodeImport("node:os");
|
|
103
103
|
const path = await nodeImport("node:path");
|
|
@@ -117,7 +117,7 @@ async function readHomeProfile(databaseId) {
|
|
|
117
117
|
const sanitized = txt.replace(/[\r\n]+/g, "");
|
|
118
118
|
const json = dropUndefined(JSON.parse(sanitized));
|
|
119
119
|
dbg("home profile used:", p, "\u2192", mask(json));
|
|
120
|
-
return json;
|
|
120
|
+
return { config: json, path: p };
|
|
121
121
|
} catch (e) {
|
|
122
122
|
const msg = e instanceof Error ? e.message : String(e);
|
|
123
123
|
throw new OnyxConfigError(`Failed to read ${p}: ${msg}`);
|
|
@@ -136,7 +136,7 @@ async function readHomeProfile(databaseId) {
|
|
|
136
136
|
dbg("no home-root fallback:", defaultInHome);
|
|
137
137
|
if (!await fileExists(dir)) {
|
|
138
138
|
dbg("~/.onyx does not exist:", dir);
|
|
139
|
-
return {};
|
|
139
|
+
return { config: {} };
|
|
140
140
|
}
|
|
141
141
|
const files = await fs.readdir(dir).catch(() => []);
|
|
142
142
|
const matches2 = files.filter((f) => f.startsWith("onyx-database-") && f.endsWith(".json"));
|
|
@@ -150,10 +150,10 @@ async function readHomeProfile(databaseId) {
|
|
|
150
150
|
);
|
|
151
151
|
}
|
|
152
152
|
dbg("no usable home profiles found in", dir);
|
|
153
|
-
return {};
|
|
153
|
+
return { config: {} };
|
|
154
154
|
}
|
|
155
155
|
async function readConfigPath(p) {
|
|
156
|
-
if (!isNode) return {};
|
|
156
|
+
if (!isNode) return { config: {} };
|
|
157
157
|
const fs = await nodeImport("node:fs/promises");
|
|
158
158
|
const path = await nodeImport("node:path");
|
|
159
159
|
const cwd = gProcess?.cwd?.() ?? ".";
|
|
@@ -163,7 +163,7 @@ async function readConfigPath(p) {
|
|
|
163
163
|
const sanitized = txt.replace(/[\r\n]+/g, "");
|
|
164
164
|
const json = dropUndefined(JSON.parse(sanitized));
|
|
165
165
|
dbg("config path:", resolved, "\u2192", mask(json));
|
|
166
|
-
return json;
|
|
166
|
+
return { config: json, path: resolved };
|
|
167
167
|
} catch (e) {
|
|
168
168
|
const msg = e instanceof Error ? e.message : String(e);
|
|
169
169
|
throw new OnyxConfigError(`Failed to read ${resolved}: ${msg}`);
|
|
@@ -174,7 +174,8 @@ async function resolveConfig(input) {
|
|
|
174
174
|
const env = readEnv(input?.databaseId);
|
|
175
175
|
let cfgPath = {};
|
|
176
176
|
if (configPath) {
|
|
177
|
-
|
|
177
|
+
const cfgRes = await readConfigPath(configPath);
|
|
178
|
+
cfgPath = cfgRes.config;
|
|
178
179
|
}
|
|
179
180
|
const targetId = input?.databaseId ?? env.databaseId ?? cfgPath.databaseId;
|
|
180
181
|
let haveDbId = !!(input?.databaseId ?? env.databaseId ?? cfgPath.databaseId);
|
|
@@ -182,14 +183,16 @@ async function resolveConfig(input) {
|
|
|
182
183
|
let haveApiSecret = !!(input?.apiSecret ?? env.apiSecret ?? cfgPath.apiSecret);
|
|
183
184
|
let project = {};
|
|
184
185
|
if (!(haveDbId && haveApiKey && haveApiSecret)) {
|
|
185
|
-
|
|
186
|
+
const projRes = await readProjectFile(targetId);
|
|
187
|
+
project = projRes.config;
|
|
186
188
|
if (project.databaseId) haveDbId = true;
|
|
187
189
|
if (project.apiKey) haveApiKey = true;
|
|
188
190
|
if (project.apiSecret) haveApiSecret = true;
|
|
189
191
|
}
|
|
190
192
|
let home = {};
|
|
191
193
|
if (!(haveDbId && haveApiKey && haveApiSecret)) {
|
|
192
|
-
|
|
194
|
+
const homeRes = await readHomeProfile(targetId);
|
|
195
|
+
home = homeRes.config;
|
|
193
196
|
}
|
|
194
197
|
const merged = {
|
|
195
198
|
baseUrl: DEFAULT_BASE_URL,
|
|
@@ -833,6 +836,56 @@ var QueryResults = class extends Array {
|
|
|
833
836
|
}
|
|
834
837
|
};
|
|
835
838
|
|
|
839
|
+
// src/helpers/condition-normalizer.ts
|
|
840
|
+
function isQueryBuilderLike(value) {
|
|
841
|
+
return !!value && typeof value.toSerializableQueryObject === "function";
|
|
842
|
+
}
|
|
843
|
+
function normalizeCriteriaValue(value) {
|
|
844
|
+
if (Array.isArray(value)) {
|
|
845
|
+
let changed = false;
|
|
846
|
+
const normalized = value.map((item) => {
|
|
847
|
+
const result = normalizeCriteriaValue(item);
|
|
848
|
+
if (result.changed) changed = true;
|
|
849
|
+
return result.value;
|
|
850
|
+
});
|
|
851
|
+
if (!changed) {
|
|
852
|
+
for (let i = 0; i < normalized.length; i += 1) {
|
|
853
|
+
if (normalized[i] !== value[i]) {
|
|
854
|
+
changed = true;
|
|
855
|
+
break;
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
return { value: changed ? normalized : value, changed };
|
|
860
|
+
}
|
|
861
|
+
if (isQueryBuilderLike(value)) {
|
|
862
|
+
return { value: value.toSerializableQueryObject(), changed: true };
|
|
863
|
+
}
|
|
864
|
+
return { value, changed: false };
|
|
865
|
+
}
|
|
866
|
+
function normalizeConditionInternal(condition) {
|
|
867
|
+
if (condition.conditionType === "SingleCondition") {
|
|
868
|
+
const { value, changed: changed2 } = normalizeCriteriaValue(condition.criteria.value);
|
|
869
|
+
if (!changed2) return condition;
|
|
870
|
+
return {
|
|
871
|
+
...condition,
|
|
872
|
+
criteria: { ...condition.criteria, value }
|
|
873
|
+
};
|
|
874
|
+
}
|
|
875
|
+
let changed = false;
|
|
876
|
+
const normalizedConditions = condition.conditions.map((child) => {
|
|
877
|
+
const normalized = normalizeConditionInternal(child);
|
|
878
|
+
if (normalized !== child) changed = true;
|
|
879
|
+
return normalized;
|
|
880
|
+
});
|
|
881
|
+
if (!changed) return condition;
|
|
882
|
+
return { ...condition, conditions: normalizedConditions };
|
|
883
|
+
}
|
|
884
|
+
function normalizeCondition(condition) {
|
|
885
|
+
if (!condition) return condition;
|
|
886
|
+
return normalizeConditionInternal(condition);
|
|
887
|
+
}
|
|
888
|
+
|
|
836
889
|
// src/builders/cascade-relationship-builder.ts
|
|
837
890
|
var CascadeRelationshipBuilder = class {
|
|
838
891
|
graphName;
|
|
@@ -907,6 +960,194 @@ var OnyxError = class extends Error {
|
|
|
907
960
|
}
|
|
908
961
|
};
|
|
909
962
|
|
|
963
|
+
// src/helpers/schema-diff.ts
|
|
964
|
+
function mapByName(items) {
|
|
965
|
+
const map = /* @__PURE__ */ new Map();
|
|
966
|
+
for (const item of items ?? []) {
|
|
967
|
+
if (!item?.name) continue;
|
|
968
|
+
map.set(item.name, item);
|
|
969
|
+
}
|
|
970
|
+
return map;
|
|
971
|
+
}
|
|
972
|
+
function normalizeEntities(schema) {
|
|
973
|
+
if (Array.isArray(schema.entities)) {
|
|
974
|
+
return schema.entities ?? [];
|
|
975
|
+
}
|
|
976
|
+
const tables = schema.tables;
|
|
977
|
+
if (!Array.isArray(tables)) return [];
|
|
978
|
+
return tables.map((table) => ({
|
|
979
|
+
name: table.name,
|
|
980
|
+
attributes: table.attributes ?? []
|
|
981
|
+
}));
|
|
982
|
+
}
|
|
983
|
+
function normalizePartition(partition) {
|
|
984
|
+
if (partition == null) return "";
|
|
985
|
+
const trimmed = partition.trim();
|
|
986
|
+
return trimmed;
|
|
987
|
+
}
|
|
988
|
+
function identifiersEqual(a, b) {
|
|
989
|
+
if (!a && !b) return true;
|
|
990
|
+
if (!a || !b) return false;
|
|
991
|
+
return a.name === b.name && a.generator === b.generator && a.type === b.type;
|
|
992
|
+
}
|
|
993
|
+
function diffAttributes(apiAttrs, localAttrs) {
|
|
994
|
+
const apiMap = mapByName(apiAttrs);
|
|
995
|
+
const localMap = mapByName(localAttrs);
|
|
996
|
+
const added = [];
|
|
997
|
+
const removed = [];
|
|
998
|
+
const changed = [];
|
|
999
|
+
for (const [name, local] of localMap.entries()) {
|
|
1000
|
+
if (!apiMap.has(name)) {
|
|
1001
|
+
added.push(local);
|
|
1002
|
+
continue;
|
|
1003
|
+
}
|
|
1004
|
+
const api = apiMap.get(name);
|
|
1005
|
+
const apiNull = Boolean(api.isNullable);
|
|
1006
|
+
const localNull = Boolean(local.isNullable);
|
|
1007
|
+
if (api.type !== local.type || apiNull !== localNull) {
|
|
1008
|
+
changed.push({
|
|
1009
|
+
name,
|
|
1010
|
+
from: { type: api.type, isNullable: apiNull },
|
|
1011
|
+
to: { type: local.type, isNullable: localNull }
|
|
1012
|
+
});
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
for (const name of apiMap.keys()) {
|
|
1016
|
+
if (!localMap.has(name)) removed.push(name);
|
|
1017
|
+
}
|
|
1018
|
+
added.sort((a, b) => a.name.localeCompare(b.name));
|
|
1019
|
+
removed.sort();
|
|
1020
|
+
changed.sort((a, b) => a.name.localeCompare(b.name));
|
|
1021
|
+
if (!added.length && !removed.length && !changed.length) return null;
|
|
1022
|
+
return { added, removed, changed };
|
|
1023
|
+
}
|
|
1024
|
+
function diffIndexes(apiIndexes, localIndexes) {
|
|
1025
|
+
const apiMap = mapByName(apiIndexes);
|
|
1026
|
+
const localMap = mapByName(localIndexes);
|
|
1027
|
+
const added = [];
|
|
1028
|
+
const removed = [];
|
|
1029
|
+
const changed = [];
|
|
1030
|
+
for (const [name, local] of localMap.entries()) {
|
|
1031
|
+
if (!apiMap.has(name)) {
|
|
1032
|
+
added.push(local);
|
|
1033
|
+
continue;
|
|
1034
|
+
}
|
|
1035
|
+
const api = apiMap.get(name);
|
|
1036
|
+
const apiType = api.type ?? "DEFAULT";
|
|
1037
|
+
const localType = local.type ?? "DEFAULT";
|
|
1038
|
+
const apiScore = api.minimumScore;
|
|
1039
|
+
const localScore = local.minimumScore;
|
|
1040
|
+
if (apiType !== localType || apiScore !== localScore) {
|
|
1041
|
+
changed.push({ name, from: api, to: local });
|
|
1042
|
+
}
|
|
1043
|
+
}
|
|
1044
|
+
for (const name of apiMap.keys()) {
|
|
1045
|
+
if (!localMap.has(name)) removed.push(name);
|
|
1046
|
+
}
|
|
1047
|
+
added.sort((a, b) => a.name.localeCompare(b.name));
|
|
1048
|
+
removed.sort();
|
|
1049
|
+
changed.sort((a, b) => a.name.localeCompare(b.name));
|
|
1050
|
+
if (!added.length && !removed.length && !changed.length) return null;
|
|
1051
|
+
return { added, removed, changed };
|
|
1052
|
+
}
|
|
1053
|
+
function diffResolvers(apiResolvers, localResolvers) {
|
|
1054
|
+
const apiMap = mapByName(apiResolvers);
|
|
1055
|
+
const localMap = mapByName(localResolvers);
|
|
1056
|
+
const added = [];
|
|
1057
|
+
const removed = [];
|
|
1058
|
+
const changed = [];
|
|
1059
|
+
for (const [name, local] of localMap.entries()) {
|
|
1060
|
+
if (!apiMap.has(name)) {
|
|
1061
|
+
added.push(local);
|
|
1062
|
+
continue;
|
|
1063
|
+
}
|
|
1064
|
+
const api = apiMap.get(name);
|
|
1065
|
+
if (api.resolver !== local.resolver) {
|
|
1066
|
+
changed.push({ name, from: api, to: local });
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
for (const name of apiMap.keys()) {
|
|
1070
|
+
if (!localMap.has(name)) removed.push(name);
|
|
1071
|
+
}
|
|
1072
|
+
added.sort((a, b) => a.name.localeCompare(b.name));
|
|
1073
|
+
removed.sort();
|
|
1074
|
+
changed.sort((a, b) => a.name.localeCompare(b.name));
|
|
1075
|
+
if (!added.length && !removed.length && !changed.length) return null;
|
|
1076
|
+
return { added, removed, changed };
|
|
1077
|
+
}
|
|
1078
|
+
function diffTriggers(apiTriggers, localTriggers) {
|
|
1079
|
+
const apiMap = mapByName(apiTriggers);
|
|
1080
|
+
const localMap = mapByName(localTriggers);
|
|
1081
|
+
const added = [];
|
|
1082
|
+
const removed = [];
|
|
1083
|
+
const changed = [];
|
|
1084
|
+
for (const [name, local] of localMap.entries()) {
|
|
1085
|
+
if (!apiMap.has(name)) {
|
|
1086
|
+
added.push(local);
|
|
1087
|
+
continue;
|
|
1088
|
+
}
|
|
1089
|
+
const api = apiMap.get(name);
|
|
1090
|
+
if (api.event !== local.event || api.trigger !== local.trigger) {
|
|
1091
|
+
changed.push({ name, from: api, to: local });
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1094
|
+
for (const name of apiMap.keys()) {
|
|
1095
|
+
if (!localMap.has(name)) removed.push(name);
|
|
1096
|
+
}
|
|
1097
|
+
added.sort((a, b) => a.name.localeCompare(b.name));
|
|
1098
|
+
removed.sort();
|
|
1099
|
+
changed.sort((a, b) => a.name.localeCompare(b.name));
|
|
1100
|
+
if (!added.length && !removed.length && !changed.length) return null;
|
|
1101
|
+
return { added, removed, changed };
|
|
1102
|
+
}
|
|
1103
|
+
function computeSchemaDiff(apiSchema, localSchema) {
|
|
1104
|
+
const apiEntities = normalizeEntities(apiSchema);
|
|
1105
|
+
const localEntities = normalizeEntities(localSchema);
|
|
1106
|
+
const apiMap = mapByName(apiEntities);
|
|
1107
|
+
const localMap = mapByName(localEntities);
|
|
1108
|
+
const newTables = [];
|
|
1109
|
+
const removedTables = [];
|
|
1110
|
+
const changedTables = [];
|
|
1111
|
+
for (const [name, localEntity] of localMap.entries()) {
|
|
1112
|
+
if (!apiMap.has(name)) {
|
|
1113
|
+
newTables.push(name);
|
|
1114
|
+
continue;
|
|
1115
|
+
}
|
|
1116
|
+
const apiEntity = apiMap.get(name);
|
|
1117
|
+
const tableDiff = { name };
|
|
1118
|
+
const partitionFrom = normalizePartition(apiEntity.partition);
|
|
1119
|
+
const partitionTo = normalizePartition(localEntity.partition);
|
|
1120
|
+
if (partitionFrom !== partitionTo) {
|
|
1121
|
+
tableDiff.partition = { from: partitionFrom || null, to: partitionTo || null };
|
|
1122
|
+
}
|
|
1123
|
+
if (!identifiersEqual(apiEntity.identifier, localEntity.identifier)) {
|
|
1124
|
+
tableDiff.identifier = {
|
|
1125
|
+
from: apiEntity.identifier ?? null,
|
|
1126
|
+
to: localEntity.identifier ?? null
|
|
1127
|
+
};
|
|
1128
|
+
}
|
|
1129
|
+
const attrs = diffAttributes(apiEntity.attributes, localEntity.attributes);
|
|
1130
|
+
if (attrs) tableDiff.attributes = attrs;
|
|
1131
|
+
const indexes = diffIndexes(apiEntity.indexes, localEntity.indexes);
|
|
1132
|
+
if (indexes) tableDiff.indexes = indexes;
|
|
1133
|
+
const resolvers = diffResolvers(apiEntity.resolvers, localEntity.resolvers);
|
|
1134
|
+
if (resolvers) tableDiff.resolvers = resolvers;
|
|
1135
|
+
const triggers = diffTriggers(apiEntity.triggers, localEntity.triggers);
|
|
1136
|
+
if (triggers) tableDiff.triggers = triggers;
|
|
1137
|
+
const hasChange = tableDiff.partition || tableDiff.identifier || tableDiff.attributes || tableDiff.indexes || tableDiff.resolvers || tableDiff.triggers;
|
|
1138
|
+
if (hasChange) {
|
|
1139
|
+
changedTables.push(tableDiff);
|
|
1140
|
+
}
|
|
1141
|
+
}
|
|
1142
|
+
for (const name of apiMap.keys()) {
|
|
1143
|
+
if (!localMap.has(name)) removedTables.push(name);
|
|
1144
|
+
}
|
|
1145
|
+
newTables.sort();
|
|
1146
|
+
removedTables.sort();
|
|
1147
|
+
changedTables.sort((a, b) => a.name.localeCompare(b.name));
|
|
1148
|
+
return { newTables, removedTables, changedTables };
|
|
1149
|
+
}
|
|
1150
|
+
|
|
910
1151
|
// src/impl/onyx.ts
|
|
911
1152
|
var DEFAULT_CACHE_TTL = 5 * 60 * 1e3;
|
|
912
1153
|
var cachedCfg = null;
|
|
@@ -960,6 +1201,10 @@ function serializeDates(value) {
|
|
|
960
1201
|
}
|
|
961
1202
|
return value;
|
|
962
1203
|
}
|
|
1204
|
+
function stripEntityText(input) {
|
|
1205
|
+
const { entityText, ...rest } = input;
|
|
1206
|
+
return rest;
|
|
1207
|
+
}
|
|
963
1208
|
function normalizeSecretMetadata(input) {
|
|
964
1209
|
return { ...input, updatedAt: new Date(input.updatedAt) };
|
|
965
1210
|
}
|
|
@@ -973,7 +1218,20 @@ function normalizeDate(value) {
|
|
|
973
1218
|
return Number.isNaN(ts.getTime()) ? void 0 : ts;
|
|
974
1219
|
}
|
|
975
1220
|
function normalizeSchemaRevision(input, fallbackDatabaseId) {
|
|
976
|
-
const {
|
|
1221
|
+
const {
|
|
1222
|
+
meta,
|
|
1223
|
+
createdAt,
|
|
1224
|
+
publishedAt,
|
|
1225
|
+
revisionId,
|
|
1226
|
+
entityText,
|
|
1227
|
+
databaseId,
|
|
1228
|
+
entities,
|
|
1229
|
+
revisionDescription,
|
|
1230
|
+
...rest
|
|
1231
|
+
} = input;
|
|
1232
|
+
const dbId = typeof databaseId === "string" ? databaseId : fallbackDatabaseId;
|
|
1233
|
+
const entityList = Array.isArray(entities) ? entities : [];
|
|
1234
|
+
const revisionDesc = typeof revisionDescription === "string" ? revisionDescription : void 0;
|
|
977
1235
|
const mergedMeta = {
|
|
978
1236
|
revisionId: meta?.revisionId ?? revisionId,
|
|
979
1237
|
createdAt: normalizeDate(meta?.createdAt ?? createdAt),
|
|
@@ -981,10 +1239,11 @@ function normalizeSchemaRevision(input, fallbackDatabaseId) {
|
|
|
981
1239
|
};
|
|
982
1240
|
const cleanedMeta = mergedMeta.revisionId || mergedMeta.createdAt || mergedMeta.publishedAt ? mergedMeta : void 0;
|
|
983
1241
|
return {
|
|
984
|
-
|
|
985
|
-
|
|
1242
|
+
databaseId: dbId,
|
|
1243
|
+
revisionDescription: revisionDesc,
|
|
1244
|
+
entities: entityList,
|
|
986
1245
|
meta: cleanedMeta,
|
|
987
|
-
|
|
1246
|
+
...rest
|
|
988
1247
|
};
|
|
989
1248
|
}
|
|
990
1249
|
var OnyxDatabaseImpl = class {
|
|
@@ -1096,7 +1355,8 @@ var OnyxDatabaseImpl = class {
|
|
|
1096
1355
|
const path = `/data/${encodeURIComponent(databaseId)}/${encodeURIComponent(
|
|
1097
1356
|
table
|
|
1098
1357
|
)}/${encodeURIComponent(primaryKey)}${params.toString() ? `?${params.toString()}` : ""}`;
|
|
1099
|
-
|
|
1358
|
+
await http.request("DELETE", path);
|
|
1359
|
+
return true;
|
|
1100
1360
|
}
|
|
1101
1361
|
async saveDocument(doc) {
|
|
1102
1362
|
const { http, databaseId } = await this.ensureClient();
|
|
@@ -1139,20 +1399,32 @@ var OnyxDatabaseImpl = class {
|
|
|
1139
1399
|
const res = await http.request("GET", path);
|
|
1140
1400
|
return Array.isArray(res) ? res.map((entry) => normalizeSchemaRevision(entry, databaseId)) : [];
|
|
1141
1401
|
}
|
|
1402
|
+
async diffSchema(localSchema) {
|
|
1403
|
+
const apiSchema = await this.getSchema();
|
|
1404
|
+
return computeSchemaDiff(apiSchema, localSchema);
|
|
1405
|
+
}
|
|
1142
1406
|
async updateSchema(schema, options) {
|
|
1143
1407
|
const { http, databaseId } = await this.ensureClient();
|
|
1144
1408
|
const params = new URLSearchParams();
|
|
1145
1409
|
if (options?.publish) params.append("publish", "true");
|
|
1146
1410
|
const path = `/schemas/${encodeURIComponent(databaseId)}${params.size ? `?${params.toString()}` : ""}`;
|
|
1147
|
-
const body = { ...schema, databaseId: schema.databaseId ?? databaseId };
|
|
1148
|
-
const res = await http.request(
|
|
1411
|
+
const body = stripEntityText({ ...schema, databaseId: schema.databaseId ?? databaseId });
|
|
1412
|
+
const res = await http.request(
|
|
1413
|
+
"PUT",
|
|
1414
|
+
path,
|
|
1415
|
+
serializeDates(body)
|
|
1416
|
+
);
|
|
1149
1417
|
return normalizeSchemaRevision(res, databaseId);
|
|
1150
1418
|
}
|
|
1151
1419
|
async validateSchema(schema) {
|
|
1152
1420
|
const { http, databaseId } = await this.ensureClient();
|
|
1153
1421
|
const path = `/schemas/${encodeURIComponent(databaseId)}/validate`;
|
|
1154
|
-
const body = { ...schema, databaseId: schema.databaseId ?? databaseId };
|
|
1155
|
-
const res = await http.request(
|
|
1422
|
+
const body = stripEntityText({ ...schema, databaseId: schema.databaseId ?? databaseId });
|
|
1423
|
+
const res = await http.request(
|
|
1424
|
+
"POST",
|
|
1425
|
+
path,
|
|
1426
|
+
serializeDates(body)
|
|
1427
|
+
);
|
|
1156
1428
|
const normalizedSchema = res.schema ? normalizeSchemaRevision(res.schema, databaseId) : void 0;
|
|
1157
1429
|
return {
|
|
1158
1430
|
...res,
|
|
@@ -1314,11 +1586,14 @@ var QueryBuilderImpl = class {
|
|
|
1314
1586
|
if (!this.table) throw new Error("Table is not defined. Call from(<table>) first.");
|
|
1315
1587
|
return this.table;
|
|
1316
1588
|
}
|
|
1589
|
+
serializableConditions() {
|
|
1590
|
+
return normalizeCondition(this.conditions);
|
|
1591
|
+
}
|
|
1317
1592
|
toSelectQuery() {
|
|
1318
1593
|
return {
|
|
1319
1594
|
type: "SelectQuery",
|
|
1320
1595
|
fields: this.fields,
|
|
1321
|
-
conditions: this.
|
|
1596
|
+
conditions: this.serializableConditions(),
|
|
1322
1597
|
sort: this.sort,
|
|
1323
1598
|
limit: this.limitValue,
|
|
1324
1599
|
distinct: this.distinctValue,
|
|
@@ -1327,6 +1602,21 @@ var QueryBuilderImpl = class {
|
|
|
1327
1602
|
resolvers: this.resolvers
|
|
1328
1603
|
};
|
|
1329
1604
|
}
|
|
1605
|
+
toUpdateQuery() {
|
|
1606
|
+
return {
|
|
1607
|
+
type: "UpdateQuery",
|
|
1608
|
+
conditions: this.serializableConditions(),
|
|
1609
|
+
updates: this.updates ?? {},
|
|
1610
|
+
sort: this.sort,
|
|
1611
|
+
limit: this.limitValue,
|
|
1612
|
+
partition: this.partitionValue ?? null
|
|
1613
|
+
};
|
|
1614
|
+
}
|
|
1615
|
+
toSerializableQueryObject() {
|
|
1616
|
+
const table = this.ensureTable();
|
|
1617
|
+
const payload = this.mode === "update" ? this.toUpdateQuery() : this.toSelectQuery();
|
|
1618
|
+
return { ...payload, table };
|
|
1619
|
+
}
|
|
1330
1620
|
from(table) {
|
|
1331
1621
|
this.table = table;
|
|
1332
1622
|
return this;
|
|
@@ -1462,14 +1752,7 @@ var QueryBuilderImpl = class {
|
|
|
1462
1752
|
async update() {
|
|
1463
1753
|
if (this.mode !== "update") throw new Error("Call setUpdates(...) before update().");
|
|
1464
1754
|
const table = this.ensureTable();
|
|
1465
|
-
const update =
|
|
1466
|
-
type: "UpdateQuery",
|
|
1467
|
-
conditions: this.conditions,
|
|
1468
|
-
updates: this.updates ?? {},
|
|
1469
|
-
sort: this.sort,
|
|
1470
|
-
limit: this.limitValue,
|
|
1471
|
-
partition: this.partitionValue ?? null
|
|
1472
|
-
};
|
|
1755
|
+
const update = this.toUpdateQuery();
|
|
1473
1756
|
return this.db._update(table, update, this.partitionValue);
|
|
1474
1757
|
}
|
|
1475
1758
|
onItemAdded(listener) {
|
|
@@ -1682,12 +1965,20 @@ var ConditionBuilderImpl = class {
|
|
|
1682
1965
|
var c = (field, operator, value) => new ConditionBuilderImpl({ field, operator, value });
|
|
1683
1966
|
var eq = (field, value) => c(field, "EQUAL", value);
|
|
1684
1967
|
var neq = (field, value) => c(field, "NOT_EQUAL", value);
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
"IN",
|
|
1688
|
-
|
|
1689
|
-
)
|
|
1690
|
-
|
|
1968
|
+
function inOp(field, values) {
|
|
1969
|
+
const parsed = typeof values === "string" ? values.split(",").map((v) => v.trim()).filter((v) => v.length) : values;
|
|
1970
|
+
return c(field, "IN", parsed);
|
|
1971
|
+
}
|
|
1972
|
+
function within(field, values) {
|
|
1973
|
+
return inOp(field, values);
|
|
1974
|
+
}
|
|
1975
|
+
function notIn(field, values) {
|
|
1976
|
+
const parsed = typeof values === "string" ? values.split(",").map((v) => v.trim()).filter((v) => v.length) : values;
|
|
1977
|
+
return c(field, "NOT_IN", parsed);
|
|
1978
|
+
}
|
|
1979
|
+
function notWithin(field, values) {
|
|
1980
|
+
return notIn(field, values);
|
|
1981
|
+
}
|
|
1691
1982
|
var between = (field, lower2, upper2) => c(field, "BETWEEN", [lower2, upper2]);
|
|
1692
1983
|
var gt = (field, value) => c(field, "GREATER_THAN", value);
|
|
1693
1984
|
var gte = (field, value) => c(field, "GREATER_THAN_EQUAL", value);
|
|
@@ -1754,6 +2045,7 @@ exports.notLike = notLike;
|
|
|
1754
2045
|
exports.notMatches = notMatches;
|
|
1755
2046
|
exports.notNull = notNull;
|
|
1756
2047
|
exports.notStartsWith = notStartsWith;
|
|
2048
|
+
exports.notWithin = notWithin;
|
|
1757
2049
|
exports.onyx = onyx;
|
|
1758
2050
|
exports.percentile = percentile;
|
|
1759
2051
|
exports.replace = replace;
|
|
@@ -1765,5 +2057,6 @@ exports.substring = substring;
|
|
|
1765
2057
|
exports.sum = sum;
|
|
1766
2058
|
exports.upper = upper;
|
|
1767
2059
|
exports.variance = variance;
|
|
2060
|
+
exports.within = within;
|
|
1768
2061
|
//# sourceMappingURL=index.cjs.map
|
|
1769
2062
|
//# sourceMappingURL=index.cjs.map
|