@lumerahq/cli 0.22.1 → 0.22.3
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.
|
@@ -95,7 +95,7 @@ async function deploy(options) {
|
|
|
95
95
|
console.log(pc.dim("Ensuring app record..."));
|
|
96
96
|
await ensureAppRecord(apiUrl, token, appName, appTitle);
|
|
97
97
|
console.log(pc.cyan(`Deploying ${appTitle}...`));
|
|
98
|
-
const version = options.version || resolveVersion(dirname(distDir));
|
|
98
|
+
const version = options.version || process.env.LUMERA_APP_VERSION?.trim() || resolveVersion(dirname(distDir));
|
|
99
99
|
console.log(pc.dim(`Version: ${version}`));
|
|
100
100
|
const tarball = await createTarball(distDir);
|
|
101
101
|
console.log(pc.dim(`Package: ${(tarball.length / 1024).toFixed(1)} KB`));
|
package/dist/index.js
CHANGED
|
@@ -226,29 +226,29 @@ async function main() {
|
|
|
226
226
|
switch (command) {
|
|
227
227
|
// Resource commands
|
|
228
228
|
case "plan":
|
|
229
|
-
await import("./resources-
|
|
229
|
+
await import("./resources-DP24VKSG.js").then((m) => m.plan(args.slice(1)));
|
|
230
230
|
break;
|
|
231
231
|
case "apply":
|
|
232
|
-
await import("./resources-
|
|
232
|
+
await import("./resources-DP24VKSG.js").then((m) => m.apply(args.slice(1)));
|
|
233
233
|
break;
|
|
234
234
|
case "pull":
|
|
235
|
-
await import("./resources-
|
|
235
|
+
await import("./resources-DP24VKSG.js").then((m) => m.pull(args.slice(1)));
|
|
236
236
|
break;
|
|
237
237
|
case "destroy":
|
|
238
|
-
await import("./resources-
|
|
238
|
+
await import("./resources-DP24VKSG.js").then((m) => m.destroy(args.slice(1)));
|
|
239
239
|
break;
|
|
240
240
|
case "list":
|
|
241
|
-
await import("./resources-
|
|
241
|
+
await import("./resources-DP24VKSG.js").then((m) => m.list(args.slice(1)));
|
|
242
242
|
break;
|
|
243
243
|
case "show":
|
|
244
|
-
await import("./resources-
|
|
244
|
+
await import("./resources-DP24VKSG.js").then((m) => m.show(args.slice(1)));
|
|
245
245
|
break;
|
|
246
246
|
case "diff":
|
|
247
|
-
await import("./resources-
|
|
247
|
+
await import("./resources-DP24VKSG.js").then((m) => m.diff(args.slice(1)));
|
|
248
248
|
break;
|
|
249
249
|
// Development
|
|
250
250
|
case "dev":
|
|
251
|
-
await import("./dev-
|
|
251
|
+
await import("./dev-UTPD4MN5.js").then((m) => m.dev(args.slice(1)));
|
|
252
252
|
break;
|
|
253
253
|
case "run":
|
|
254
254
|
await import("./run-DJXAXDD2.js").then((m) => m.run(args.slice(1)));
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
deploy
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-WV5HOQNX.js";
|
|
4
4
|
import {
|
|
5
5
|
syncDeps
|
|
6
6
|
} from "./chunk-3ESHIPZH.js";
|
|
@@ -125,6 +125,15 @@ var collectionSchemaRule = {
|
|
|
125
125
|
const name = parsed.name;
|
|
126
126
|
const fields = parsed.fields;
|
|
127
127
|
const indexes = parsed.indexes;
|
|
128
|
+
const search = parsed.search;
|
|
129
|
+
const localFieldTypes = /* @__PURE__ */ new Map();
|
|
130
|
+
if (Array.isArray(fields)) {
|
|
131
|
+
for (const field of fields) {
|
|
132
|
+
if (isRecord2(field) && typeof field.name === "string") {
|
|
133
|
+
localFieldTypes.set(field.name, field.type);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
128
137
|
if (typeof id !== "string" || id.trim() === "") {
|
|
129
138
|
issues.push(error(target, 'Missing required string field "id".'));
|
|
130
139
|
}
|
|
@@ -173,6 +182,56 @@ var collectionSchemaRule = {
|
|
|
173
182
|
}
|
|
174
183
|
}
|
|
175
184
|
}
|
|
185
|
+
if (search !== void 0) {
|
|
186
|
+
if (!isRecord2(search)) {
|
|
187
|
+
issues.push(error(target, 'Optional field "search" must be an object when present.'));
|
|
188
|
+
} else {
|
|
189
|
+
const unknownSearchKeys = Object.keys(search).filter((key) => key !== "fulltext");
|
|
190
|
+
for (const key of unknownSearchKeys) {
|
|
191
|
+
issues.push(error(target, `Unknown search option "${key}".`));
|
|
192
|
+
}
|
|
193
|
+
const fulltext = search.fulltext;
|
|
194
|
+
if (!isRecord2(fulltext)) {
|
|
195
|
+
issues.push(error(target, '"search.fulltext" must be an object.'));
|
|
196
|
+
} else {
|
|
197
|
+
const allowed = /* @__PURE__ */ new Set(["fields", "language", "fuzzy_fields"]);
|
|
198
|
+
for (const key of Object.keys(fulltext).filter((key2) => !allowed.has(key2))) {
|
|
199
|
+
issues.push(error(target, `Unknown search.fulltext option "${key}".`));
|
|
200
|
+
}
|
|
201
|
+
if (!isRecord2(fulltext.fields) || Object.keys(fulltext.fields).length === 0) {
|
|
202
|
+
issues.push(error(target, '"search.fulltext.fields" must be a non-empty field-to-weight object.'));
|
|
203
|
+
} else {
|
|
204
|
+
if (Object.keys(fulltext.fields).length > 8) {
|
|
205
|
+
issues.push(error(target, '"search.fulltext.fields" cannot contain more than 8 fields.'));
|
|
206
|
+
}
|
|
207
|
+
for (const [field, weight] of Object.entries(fulltext.fields)) {
|
|
208
|
+
if (!["A", "B", "C", "D"].includes(String(weight))) {
|
|
209
|
+
issues.push(error(target, `Search field "${field}" must use weight A, B, C, or D.`));
|
|
210
|
+
}
|
|
211
|
+
const type = localFieldTypes.get(field);
|
|
212
|
+
if (type !== "text" && type !== "editor") {
|
|
213
|
+
issues.push(error(target, `Search field "${field}" must name a text or editor field.`));
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
if (fulltext.language !== void 0 && fulltext.language !== "english" && fulltext.language !== "simple") {
|
|
218
|
+
issues.push(error(target, '"search.fulltext.language" must be "english" or "simple".'));
|
|
219
|
+
}
|
|
220
|
+
if (fulltext.fuzzy_fields !== void 0) {
|
|
221
|
+
if (!Array.isArray(fulltext.fuzzy_fields) || !fulltext.fuzzy_fields.every((field) => typeof field === "string")) {
|
|
222
|
+
issues.push(error(target, '"search.fulltext.fuzzy_fields" must be an array of field names.'));
|
|
223
|
+
} else {
|
|
224
|
+
for (const field of fulltext.fuzzy_fields) {
|
|
225
|
+
const type = localFieldTypes.get(field);
|
|
226
|
+
if (type !== "text" && type !== "editor") {
|
|
227
|
+
issues.push(error(target, `Fuzzy search field "${field}" must name a text or editor field.`));
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
176
235
|
return issues;
|
|
177
236
|
}
|
|
178
237
|
};
|
|
@@ -1455,7 +1514,7 @@ function convertCollectionToApiFormat(local) {
|
|
|
1455
1514
|
const indexName = `idx_${local.id}_${idx.fields.join("_")}`;
|
|
1456
1515
|
return `CREATE ${unique}INDEX ${indexName} ON ${local.name} (${fields})`;
|
|
1457
1516
|
});
|
|
1458
|
-
return { id: local.id, name: local.name, schema, indexes };
|
|
1517
|
+
return { id: local.id, name: local.name, schema, indexes, search: local.search ?? null };
|
|
1459
1518
|
}
|
|
1460
1519
|
function mapFieldType(type) {
|
|
1461
1520
|
const typeMap = {
|
|
@@ -1545,6 +1604,19 @@ function indexesDiffer(local, remoteIndexes) {
|
|
|
1545
1604
|
}
|
|
1546
1605
|
return false;
|
|
1547
1606
|
}
|
|
1607
|
+
function normalizeCollectionSearch(search) {
|
|
1608
|
+
if (!search) return "null";
|
|
1609
|
+
const fields = Object.fromEntries(
|
|
1610
|
+
Object.entries(search.fulltext.fields).sort(([left], [right]) => left.localeCompare(right))
|
|
1611
|
+
);
|
|
1612
|
+
return JSON.stringify({
|
|
1613
|
+
fulltext: {
|
|
1614
|
+
fields,
|
|
1615
|
+
language: search.fulltext.language ?? "english",
|
|
1616
|
+
fuzzy_fields: [...search.fulltext.fuzzy_fields ?? []].sort()
|
|
1617
|
+
}
|
|
1618
|
+
});
|
|
1619
|
+
}
|
|
1548
1620
|
async function planCollections(api, localCollections) {
|
|
1549
1621
|
const changes = [];
|
|
1550
1622
|
const remoteCollections = await api.listCollections();
|
|
@@ -1582,12 +1654,14 @@ async function planCollections(api, localCollections) {
|
|
|
1582
1654
|
}
|
|
1583
1655
|
}
|
|
1584
1656
|
const indexesChanged = indexesDiffer(local, remote.indexes || []);
|
|
1585
|
-
|
|
1657
|
+
const searchChanged = normalizeCollectionSearch(local.search) !== normalizeCollectionSearch(remote.search);
|
|
1658
|
+
if (added.length > 0 || removed.length > 0 || modified.length > 0 || indexesChanged || searchChanged) {
|
|
1586
1659
|
const details = [];
|
|
1587
1660
|
if (added.length > 0) details.push(`+${added.length} field${added.length > 1 ? "s" : ""}`);
|
|
1588
1661
|
if (removed.length > 0) details.push(`-${removed.length} field${removed.length > 1 ? "s" : ""}`);
|
|
1589
1662
|
if (modified.length > 0) details.push(`~${modified.length} field${modified.length > 1 ? "s" : ""} (${modified.join(", ")})`);
|
|
1590
1663
|
if (indexesChanged) details.push("indexes changed");
|
|
1664
|
+
if (searchChanged) details.push("search changed");
|
|
1591
1665
|
const fieldDetails = [];
|
|
1592
1666
|
for (const name of added) {
|
|
1593
1667
|
const f = localFieldMap.get(name);
|
|
@@ -2099,7 +2173,8 @@ async function pullCollections(api, platformDir, filterName, appName) {
|
|
|
2099
2173
|
return { fields: match[2].split(",").map((f) => f.trim()), unique: !!match[1] };
|
|
2100
2174
|
}
|
|
2101
2175
|
return null;
|
|
2102
|
-
}).filter((idx) => idx !== null)
|
|
2176
|
+
}).filter((idx) => idx !== null),
|
|
2177
|
+
search: collection.search
|
|
2103
2178
|
};
|
|
2104
2179
|
const fileName = toSafeFilename(localName);
|
|
2105
2180
|
const filePath = join2(collectionsDir, `${fileName}.json`);
|
|
@@ -3375,6 +3450,14 @@ async function apply(args) {
|
|
|
3375
3450
|
totalErrors += await applyMailboxes(api, localMailboxes);
|
|
3376
3451
|
console.log();
|
|
3377
3452
|
}
|
|
3453
|
+
if (totalErrors > 0) {
|
|
3454
|
+
console.log(pc2.red(` \u2717 ${totalErrors} error${totalErrors > 1 ? "s" : ""} during apply.`));
|
|
3455
|
+
if (willDeployApp) {
|
|
3456
|
+
console.log(pc2.dim(" App deploy skipped because resource apply failed."));
|
|
3457
|
+
}
|
|
3458
|
+
console.log();
|
|
3459
|
+
process.exit(1);
|
|
3460
|
+
}
|
|
3378
3461
|
if (willDeployApp) {
|
|
3379
3462
|
console.log(pc2.bold(" App:"));
|
|
3380
3463
|
await applyApp(args);
|
|
@@ -3382,11 +3465,6 @@ async function apply(args) {
|
|
|
3382
3465
|
}
|
|
3383
3466
|
totalCreated = creates.length;
|
|
3384
3467
|
totalUpdated = updates.length;
|
|
3385
|
-
if (totalErrors > 0) {
|
|
3386
|
-
console.log(pc2.red(` \u2717 ${totalErrors} error${totalErrors > 1 ? "s" : ""} during apply.`));
|
|
3387
|
-
console.log();
|
|
3388
|
-
process.exit(1);
|
|
3389
|
-
}
|
|
3390
3468
|
const summary = [];
|
|
3391
3469
|
if (totalCreated > 0) summary.push(pc2.green(`${totalCreated} created`));
|
|
3392
3470
|
if (totalUpdated > 0) summary.push(pc2.yellow(`${totalUpdated} updated`));
|
package/package.json
CHANGED