@lumerahq/cli 0.32.7 → 0.32.8-dev.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/dist/index.js CHANGED
@@ -242,25 +242,25 @@ async function main() {
242
242
  switch (command) {
243
243
  // Resource commands
244
244
  case "plan":
245
- await import("./resources-4677FHV6.js").then((m) => m.plan(args.slice(1)));
245
+ await import("./resources-RBGDP6E2.js").then((m) => m.plan(args.slice(1)));
246
246
  break;
247
247
  case "apply":
248
- await import("./resources-4677FHV6.js").then((m) => m.apply(args.slice(1)));
248
+ await import("./resources-RBGDP6E2.js").then((m) => m.apply(args.slice(1)));
249
249
  break;
250
250
  case "pull":
251
- await import("./resources-4677FHV6.js").then((m) => m.pull(args.slice(1)));
251
+ await import("./resources-RBGDP6E2.js").then((m) => m.pull(args.slice(1)));
252
252
  break;
253
253
  case "destroy":
254
- await import("./resources-4677FHV6.js").then((m) => m.destroy(args.slice(1)));
254
+ await import("./resources-RBGDP6E2.js").then((m) => m.destroy(args.slice(1)));
255
255
  break;
256
256
  case "list":
257
- await import("./resources-4677FHV6.js").then((m) => m.list(args.slice(1)));
257
+ await import("./resources-RBGDP6E2.js").then((m) => m.list(args.slice(1)));
258
258
  break;
259
259
  case "show":
260
- await import("./resources-4677FHV6.js").then((m) => m.show(args.slice(1)));
260
+ await import("./resources-RBGDP6E2.js").then((m) => m.show(args.slice(1)));
261
261
  break;
262
262
  case "diff":
263
- await import("./resources-4677FHV6.js").then((m) => m.diff(args.slice(1)));
263
+ await import("./resources-RBGDP6E2.js").then((m) => m.diff(args.slice(1)));
264
264
  break;
265
265
  // Development
266
266
  case "dev":
@@ -1178,6 +1178,29 @@ function buildIndexSql(local, idx, appName) {
1178
1178
  }
1179
1179
  var AGENT_IDLE_REAP_TIMEOUT_MIN_SECONDS = 10;
1180
1180
  var AGENT_IDLE_REAP_TIMEOUT_MAX_SECONDS = 900;
1181
+ var FIELD_OPTION_KEYS_BY_TYPE = {
1182
+ text: ["min", "max", "pattern"],
1183
+ number: ["min", "max", "noDecimal"],
1184
+ bool: [],
1185
+ relation: ["cascadeDelete", "minSelect", "maxSelect"],
1186
+ json: ["maxSize"],
1187
+ lumera_file: ["maxSelect", "maxSize", "mimeTypes", "protected"],
1188
+ editor: ["maxSize", "convertURLs"],
1189
+ date: ["min", "max"],
1190
+ select: ["values", "maxSelect"],
1191
+ currency: ["defaultCurrency", "decimalPrecision"]
1192
+ };
1193
+ var FIELD_OPTION_DEFAULTS = {
1194
+ text: { min: 0, max: 0, pattern: "" },
1195
+ number: { noDecimal: false },
1196
+ relation: { cascadeDelete: false, minSelect: 0, maxSelect: 1 },
1197
+ json: { maxSize: 0 },
1198
+ lumera_file: { maxSelect: 1, maxSize: 0, mimeTypes: [], protected: false },
1199
+ editor: { maxSize: 0, convertURLs: false },
1200
+ date: { min: "", max: "" },
1201
+ select: { values: [], maxSelect: 1 },
1202
+ currency: { defaultCurrency: "USD", decimalPrecision: 2 }
1203
+ };
1181
1204
  function buildCollectionIdMap(collections, appName) {
1182
1205
  const result = /* @__PURE__ */ new Map();
1183
1206
  const add = (key, id) => {
@@ -1811,35 +1834,57 @@ function loadLocalHooks(platformDir, filterName, appName) {
1811
1834
  }
1812
1835
  return hooks;
1813
1836
  }
1837
+ function fieldOptionKeys(type) {
1838
+ return FIELD_OPTION_KEYS_BY_TYPE[mapFieldType(type)] || [];
1839
+ }
1840
+ function convertCollectionFieldToApiFormat(field) {
1841
+ const type = mapFieldType(field.type);
1842
+ const apiField = {
1843
+ name: field.name,
1844
+ type,
1845
+ required: field.required
1846
+ };
1847
+ if (field.id) apiField.id = field.id;
1848
+ if (field.hidden !== void 0) apiField.hidden = field.hidden;
1849
+ if (field.presentable !== void 0) apiField.presentable = field.presentable;
1850
+ const options = {};
1851
+ for (const key of fieldOptionKeys(type)) {
1852
+ const value = field[key];
1853
+ if (value !== void 0) options[key] = value;
1854
+ }
1855
+ if (type === "relation" && field.collection !== void 0) {
1856
+ options.collectionId = field.collection;
1857
+ }
1858
+ if (options.maxSelect === void 0 && type === "select" && field.values) {
1859
+ options.maxSelect = field.multiple ? field.values.length : 1;
1860
+ }
1861
+ if (options.maxSelect === void 0 && type === "relation" && field.collection) {
1862
+ options.maxSelect = field.multiple ? 999 : 1;
1863
+ }
1864
+ if (Object.keys(options).length > 0) apiField.options = options;
1865
+ return apiField;
1866
+ }
1867
+ function convertApiFieldToLocalFormat(field) {
1868
+ const localField = {
1869
+ name: field.name,
1870
+ type: field.type,
1871
+ required: field.required
1872
+ };
1873
+ if (field.id) localField.id = field.id;
1874
+ if (field.hidden !== void 0) localField.hidden = field.hidden;
1875
+ if (field.presentable !== void 0) localField.presentable = field.presentable;
1876
+ const options = field.options || {};
1877
+ const writableLocalField = localField;
1878
+ for (const key of fieldOptionKeys(field.type)) {
1879
+ if (options[key] !== void 0) writableLocalField[key] = options[key];
1880
+ }
1881
+ if (field.type === "relation" && options.collectionId !== void 0) {
1882
+ localField.collection = options.collectionId;
1883
+ }
1884
+ return localField;
1885
+ }
1814
1886
  function convertCollectionToApiFormat(local, appName) {
1815
- const schema = local.fields.map((field) => {
1816
- const apiField = {
1817
- name: field.name,
1818
- type: mapFieldType(field.type),
1819
- required: field.required
1820
- };
1821
- const options = {};
1822
- if (field.type === "select" && field.values) {
1823
- options.values = field.values;
1824
- options.maxSelect = field.multiple ? field.values.length : 1;
1825
- }
1826
- if (field.type === "relation" && field.collection) {
1827
- options.collectionId = field.collection;
1828
- options.maxSelect = field.multiple ? 999 : 1;
1829
- }
1830
- if (field.type === "currency") {
1831
- if (field.defaultCurrency) options.defaultCurrency = field.defaultCurrency;
1832
- if (field.decimalPrecision !== void 0) {
1833
- options.decimalPrecision = field.decimalPrecision;
1834
- }
1835
- }
1836
- if (field.max !== void 0) options.max = field.max;
1837
- if (field.min !== void 0) options.min = field.min;
1838
- if (Object.keys(options).length > 0) {
1839
- apiField.options = options;
1840
- }
1841
- return apiField;
1842
- });
1887
+ const schema = local.fields.map(convertCollectionFieldToApiFormat);
1843
1888
  const indexes = local.indexes?.map((idx) => buildIndexSql(local, idx, appName));
1844
1889
  return {
1845
1890
  id: local.id,
@@ -1867,50 +1912,36 @@ function mapFieldType(type) {
1867
1912
  };
1868
1913
  return typeMap[type] || type;
1869
1914
  }
1870
- function normalizeConstraintValue(fieldType, value) {
1871
- if (value === void 0 || value === null) return void 0;
1872
- if (["text", "email", "url", "editor"].includes(fieldType) && value === 0) {
1873
- return void 0;
1874
- }
1875
- if (fieldType === "date" && value === "") {
1876
- return void 0;
1915
+ function normalizeFieldOption(type, key, value) {
1916
+ if (value === void 0 || value === null) {
1917
+ return FIELD_OPTION_DEFAULTS[type]?.[key];
1877
1918
  }
1919
+ if (key === "defaultCurrency") return String(value).trim().toUpperCase();
1878
1920
  return value;
1879
1921
  }
1922
+ function fieldOptionValuesEqual(left, right) {
1923
+ if (Array.isArray(left) || Array.isArray(right)) {
1924
+ return JSON.stringify(left) === JSON.stringify(right);
1925
+ }
1926
+ return left === right;
1927
+ }
1880
1928
  function fieldsDiffer(local, remote) {
1881
- if (mapFieldType(local.type) !== remote.type) return true;
1929
+ const type = mapFieldType(local.type);
1930
+ if (type !== remote.type) return true;
1882
1931
  if ((local.required || false) !== (remote.required || false)) return true;
1883
- const opts = remote.options || {};
1884
- if (local.type === "select") {
1885
- const localValues = [...local.values || []].sort();
1886
- const remoteValues = [...opts.values || []].sort();
1887
- if (localValues.join(",") !== remoteValues.join(",")) return true;
1888
- const localMultiple = local.multiple || false;
1889
- const remoteMaxSelect = opts.maxSelect || 1;
1890
- if (localMultiple && remoteMaxSelect <= 1) return true;
1891
- if (!localMultiple && remoteMaxSelect > 1) return true;
1892
- }
1893
- if (local.type === "relation") {
1894
- if (local.collection && local.collection !== opts.collectionId) return true;
1895
- const localMultiple = local.multiple || false;
1896
- const remoteMaxSelect = opts.maxSelect || 1;
1897
- if (localMultiple && remoteMaxSelect <= 1) return true;
1898
- if (!localMultiple && remoteMaxSelect > 1) return true;
1899
- }
1900
- if (local.type === "currency") {
1901
- const localDefaultCurrency = (local.defaultCurrency || "USD").trim().toUpperCase();
1902
- const remoteDefaultCurrency = (opts.defaultCurrency || "USD").trim().toUpperCase();
1903
- if (localDefaultCurrency !== remoteDefaultCurrency) return true;
1904
- const localDecimalPrecision = local.decimalPrecision !== void 0 ? local.decimalPrecision : 2;
1905
- const remoteDecimalPrecision = opts.decimalPrecision !== void 0 ? opts.decimalPrecision : 2;
1906
- if (localDecimalPrecision !== remoteDecimalPrecision) return true;
1907
- }
1908
- const localMin = normalizeConstraintValue(local.type, local.min);
1909
- const remoteMin = normalizeConstraintValue(local.type, opts.min);
1910
- if (localMin !== remoteMin) return true;
1911
- const localMax = normalizeConstraintValue(local.type, local.max);
1912
- const remoteMax = normalizeConstraintValue(local.type, opts.max);
1913
- if (localMax !== remoteMax) return true;
1932
+ if ((local.hidden || false) !== (remote.hidden || false)) return true;
1933
+ if ((local.presentable || false) !== (remote.presentable || false)) return true;
1934
+ if (local.id !== void 0 && local.id !== remote.id) return true;
1935
+ const localOptions = convertCollectionFieldToApiFormat(local).options || {};
1936
+ const remoteOptions = remote.options || {};
1937
+ if (type === "relation") {
1938
+ if ((localOptions.collectionId || "") !== (remoteOptions.collectionId || "")) return true;
1939
+ }
1940
+ for (const key of fieldOptionKeys(type)) {
1941
+ const localValue = normalizeFieldOption(type, key, localOptions[key]);
1942
+ const remoteValue = normalizeFieldOption(type, key, remoteOptions[key]);
1943
+ if (!fieldOptionValuesEqual(localValue, remoteValue)) return true;
1944
+ }
1914
1945
  return false;
1915
1946
  }
1916
1947
  function localIndexesToSql(local, appName) {
@@ -2540,25 +2571,7 @@ async function pullCollections(api, platformDir, filterName, projectId) {
2540
2571
  id: collection.id,
2541
2572
  name: localName,
2542
2573
  audit: collection.audit,
2543
- fields: collection.schema.map((field) => {
2544
- const localField = {
2545
- name: field.name,
2546
- type: field.type,
2547
- required: field.required
2548
- };
2549
- if (field.options) {
2550
- if (field.options.values) localField.values = field.options.values;
2551
- if (field.options.collectionId) localField.collection = field.options.collectionId;
2552
- if (field.options.maxSelect && field.options.maxSelect > 1) localField.multiple = true;
2553
- if (field.options.defaultCurrency) {
2554
- localField.defaultCurrency = field.options.defaultCurrency;
2555
- }
2556
- if (field.options.decimalPrecision !== void 0) {
2557
- localField.decimalPrecision = field.options.decimalPrecision;
2558
- }
2559
- }
2560
- return localField;
2561
- }),
2574
+ fields: collection.schema.map(convertApiFieldToLocalFormat),
2562
2575
  indexes: collection.indexes?.map((idx) => {
2563
2576
  const match = idx.match(/CREATE\s+(UNIQUE\s+)?INDEX\s+\w+\s+ON\s+\w+\s+\(([^)]+)\)/i);
2564
2577
  if (match) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lumerahq/cli",
3
- "version": "0.32.7",
3
+ "version": "0.32.8-dev.0",
4
4
  "description": "CLI for building and deploying Lumera apps",
5
5
  "type": "module",
6
6
  "engines": {