@lumerahq/cli 0.18.11 → 0.18.13

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.
@@ -52,7 +52,8 @@ async function fetchUserInfo(token) {
52
52
  try {
53
53
  const response = await fetchWithRetry(`${baseUrl}/api/me`, {
54
54
  headers: {
55
- Authorization: `Bearer ${token}`
55
+ Authorization: `Bearer ${token}`,
56
+ "X-Lumera-Client": "lumera-cli"
56
57
  }
57
58
  });
58
59
  if (!response.ok) {
@@ -25,7 +25,9 @@ function hashContent(content) {
25
25
  async function fetchSkillsList() {
26
26
  const baseUrl = getBaseUrl();
27
27
  const skillsApiUrl = `${baseUrl}/api/public/skills`;
28
- const listRes = await fetchWithRetry(skillsApiUrl);
28
+ const listRes = await fetchWithRetry(skillsApiUrl, {
29
+ headers: { "X-Lumera-Client": "lumera-cli" }
30
+ });
29
31
  if (!listRes.ok) {
30
32
  throw new Error(`Failed to fetch skills list: ${listRes.status}`);
31
33
  }
@@ -34,7 +36,9 @@ async function fetchSkillsList() {
34
36
  async function fetchSkillContent(slug) {
35
37
  const baseUrl = getBaseUrl();
36
38
  const skillsApiUrl = `${baseUrl}/api/public/skills`;
37
- const mdRes = await fetchWithRetry(`${skillsApiUrl}/${slug}.md`);
39
+ const mdRes = await fetchWithRetry(`${skillsApiUrl}/${slug}.md`, {
40
+ headers: { "X-Lumera-Client": "lumera-cli" }
41
+ });
38
42
  if (!mdRes.ok) {
39
43
  return null;
40
44
  }
@@ -52,6 +52,7 @@ var ApiClient = class {
52
52
  "Content-Type": "application/json",
53
53
  Authorization: `Bearer ${this.token}`,
54
54
  "User-Agent": CLI_USER_AGENT,
55
+ "X-Lumera-Client": "lumera-cli",
55
56
  ...this.projectExternalId ? { "X-Lumera-Project": this.projectExternalId } : {},
56
57
  ...options.headers
57
58
  };
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-2CR762KB.js";
4
4
  import {
5
5
  createApiClient
6
- } from "./chunk-PPSLI2ZI.js";
6
+ } from "./chunk-IBE6ACPE.js";
7
7
  import {
8
8
  findProjectRoot,
9
9
  getAppName
@@ -53,7 +53,12 @@ async function ensureAppRecord(apiBase, token, appName, appTitle) {
53
53
  const filterParam = encodeURIComponent(JSON.stringify({ external_id: appName }));
54
54
  const searchRes = await fetchWithRetry(
55
55
  `${apiBase}/pb/collections/lm_custom_apps/records?filter=${filterParam}`,
56
- { headers: { Authorization: `Bearer ${token}` } }
56
+ {
57
+ headers: {
58
+ Authorization: `Bearer ${token}`,
59
+ "X-Lumera-Client": "lumera-cli"
60
+ }
61
+ }
57
62
  );
58
63
  if (!searchRes.ok) {
59
64
  throw new Error(`Failed to check app record: ${await searchRes.text()}`);
@@ -65,11 +70,12 @@ async function ensureAppRecord(apiBase, token, appName, appTitle) {
65
70
  hosting_type: "s3"
66
71
  };
67
72
  const endpoint = existing ? `${apiBase}/pb/collections/lm_custom_apps/records/${existing.id}` : `${apiBase}/pb/collections/lm_custom_apps/records`;
68
- const res = await fetch(endpoint, {
73
+ const res = await fetchWithRetry(endpoint, {
69
74
  method: existing ? "PATCH" : "POST",
70
75
  headers: {
71
76
  Authorization: `Bearer ${token}`,
72
- "Content-Type": "application/json"
77
+ "Content-Type": "application/json",
78
+ "X-Lumera-Client": "lumera-cli"
73
79
  },
74
80
  body: JSON.stringify(appData)
75
81
  });
@@ -98,9 +104,12 @@ async function deploy(options) {
98
104
  const formData = new FormData();
99
105
  formData.append("tarball", new Blob([new Uint8Array(tarball)]), "dist.tar.gz");
100
106
  formData.append("version", version);
101
- const res = await fetch(`${apiUrl}/custom-apps/${appName}/deploy`, {
107
+ const res = await fetchWithRetry(`${apiUrl}/custom-apps/${appName}/deploy`, {
102
108
  method: "POST",
103
- headers: { Authorization: `Bearer ${token}` },
109
+ headers: {
110
+ Authorization: `Bearer ${token}`,
111
+ "X-Lumera-Client": "lumera-cli"
112
+ },
104
113
  body: formData
105
114
  });
106
115
  if (!res.ok) {
@@ -157,7 +166,7 @@ async function dev(options) {
157
166
  } = options;
158
167
  const projectRoot = process.cwd();
159
168
  const parentOrigin = getParentOrigin(apiUrl);
160
- const lumeraAppUrl = `${parentOrigin}/custom-app/${appName}?dev`;
169
+ const lumeraAppUrl = `${parentOrigin}/preview_app/${appName}`;
161
170
  if (await isPortInUse(port)) {
162
171
  console.log(pc.yellow(` Dev server already running on port ${port}, skipping start.`));
163
172
  return;
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  deps,
3
3
  syncDeps
4
- } from "./chunk-NJWVSQEL.js";
4
+ } from "./chunk-MVUNFAVL.js";
5
5
  import "./chunk-2CR762KB.js";
6
- import "./chunk-PPSLI2ZI.js";
6
+ import "./chunk-IBE6ACPE.js";
7
7
  import "./chunk-ZH3NVYEQ.js";
8
8
  import "./chunk-FJFIWC7G.js";
9
9
  import "./chunk-PNKVD2UK.js";
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  dev
3
- } from "./chunk-JTDHLA3L.js";
3
+ } from "./chunk-SU26C4GL.js";
4
4
  import {
5
5
  loadEnv
6
6
  } from "./chunk-2CR762KB.js";
7
7
  import {
8
8
  createApiClient
9
- } from "./chunk-PPSLI2ZI.js";
9
+ } from "./chunk-IBE6ACPE.js";
10
10
  import {
11
11
  findProjectRoot,
12
12
  getApiUrl,
package/dist/index.js CHANGED
@@ -219,66 +219,66 @@ async function main() {
219
219
  switch (command) {
220
220
  // Resource commands
221
221
  case "plan":
222
- await import("./resources-K6XXMEXX.js").then((m) => m.plan(args.slice(1)));
222
+ await import("./resources-KPRAWMQN.js").then((m) => m.plan(args.slice(1)));
223
223
  break;
224
224
  case "apply":
225
- await import("./resources-K6XXMEXX.js").then((m) => m.apply(args.slice(1)));
225
+ await import("./resources-KPRAWMQN.js").then((m) => m.apply(args.slice(1)));
226
226
  break;
227
227
  case "pull":
228
- await import("./resources-K6XXMEXX.js").then((m) => m.pull(args.slice(1)));
228
+ await import("./resources-KPRAWMQN.js").then((m) => m.pull(args.slice(1)));
229
229
  break;
230
230
  case "destroy":
231
- await import("./resources-K6XXMEXX.js").then((m) => m.destroy(args.slice(1)));
231
+ await import("./resources-KPRAWMQN.js").then((m) => m.destroy(args.slice(1)));
232
232
  break;
233
233
  case "list":
234
- await import("./resources-K6XXMEXX.js").then((m) => m.list(args.slice(1)));
234
+ await import("./resources-KPRAWMQN.js").then((m) => m.list(args.slice(1)));
235
235
  break;
236
236
  case "show":
237
- await import("./resources-K6XXMEXX.js").then((m) => m.show(args.slice(1)));
237
+ await import("./resources-KPRAWMQN.js").then((m) => m.show(args.slice(1)));
238
238
  break;
239
239
  case "diff":
240
- await import("./resources-K6XXMEXX.js").then((m) => m.diff(args.slice(1)));
240
+ await import("./resources-KPRAWMQN.js").then((m) => m.diff(args.slice(1)));
241
241
  break;
242
242
  // Development
243
243
  case "dev":
244
- await import("./dev-GYNUSRUC.js").then((m) => m.dev(args.slice(1)));
244
+ await import("./dev-R2CZ7IYR.js").then((m) => m.dev(args.slice(1)));
245
245
  break;
246
246
  case "run":
247
- await import("./run-SQM3OWD2.js").then((m) => m.run(args.slice(1)));
247
+ await import("./run-JZX3E4UX.js").then((m) => m.run(args.slice(1)));
248
248
  break;
249
249
  // Project
250
250
  case "init":
251
- await import("./init-PSYCZETD.js").then((m) => m.init(args.slice(1)));
251
+ await import("./init-F4UYW6LD.js").then((m) => m.init(args.slice(1)));
252
252
  break;
253
253
  case "register":
254
- await import("./register-NYC5WVGZ.js").then((m) => m.register(args.slice(1)));
254
+ await import("./register-QPUXYBZ7.js").then((m) => m.register(args.slice(1)));
255
255
  break;
256
256
  case "templates":
257
257
  await import("./templates-M3RDNDDY.js").then((m) => m.templates(subcommand, args.slice(2)));
258
258
  break;
259
259
  case "status":
260
- await import("./status-LP73L4IV.js").then((m) => m.status(args.slice(1)));
260
+ await import("./status-X7WQYX2L.js").then((m) => m.status(args.slice(1)));
261
261
  break;
262
262
  case "migrate":
263
263
  await import("./migrate-NCZKP7FM.js").then((m) => m.migrate(args.slice(1)));
264
264
  break;
265
265
  // Skills
266
266
  case "skills":
267
- await import("./skills-YWYBMOVO.js").then((m) => m.skills(subcommand, args.slice(2)));
267
+ await import("./skills-FBYZIK3M.js").then((m) => m.skills(subcommand, args.slice(2)));
268
268
  break;
269
269
  // Dependencies
270
270
  case "deps":
271
- await import("./deps-V24GK3KJ.js").then((m) => m.deps(args.slice(1)));
271
+ await import("./deps-AVTV7FP3.js").then((m) => m.deps(args.slice(1)));
272
272
  break;
273
273
  // Auth
274
274
  case "login":
275
- await import("./auth-PDTSQN7X.js").then((m) => m.login(args.slice(1)));
275
+ await import("./auth-NI7JTMJM.js").then((m) => m.login(args.slice(1)));
276
276
  break;
277
277
  case "logout":
278
- await import("./auth-PDTSQN7X.js").then((m) => m.logout(args.slice(1)));
278
+ await import("./auth-NI7JTMJM.js").then((m) => m.logout(args.slice(1)));
279
279
  break;
280
280
  case "whoami":
281
- await import("./auth-PDTSQN7X.js").then((m) => m.whoami());
281
+ await import("./auth-NI7JTMJM.js").then((m) => m.whoami());
282
282
  break;
283
283
  // Convenience aliases
284
284
  case "help":
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  installAllSkills,
3
3
  syncClaudeMd
4
- } from "./chunk-CCP66T22.js";
4
+ } from "./chunk-AUYOTENF.js";
5
5
  import {
6
6
  spinner
7
7
  } from "./chunk-BHYDYR75.js";
8
8
  import {
9
9
  createApiClient
10
- } from "./chunk-PPSLI2ZI.js";
10
+ } from "./chunk-IBE6ACPE.js";
11
11
  import {
12
12
  getToken,
13
13
  init_auth,
@@ -6,7 +6,7 @@ import {
6
6
  } from "./chunk-BHYDYR75.js";
7
7
  import {
8
8
  createApiClient
9
- } from "./chunk-PPSLI2ZI.js";
9
+ } from "./chunk-IBE6ACPE.js";
10
10
  import {
11
11
  findProjectRoot,
12
12
  getAppName,
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  syncDeps
3
- } from "./chunk-NJWVSQEL.js";
3
+ } from "./chunk-MVUNFAVL.js";
4
4
  import {
5
5
  deploy
6
- } from "./chunk-JTDHLA3L.js";
6
+ } from "./chunk-SU26C4GL.js";
7
7
  import {
8
8
  loadEnv
9
9
  } from "./chunk-2CR762KB.js";
10
10
  import {
11
11
  createApiClient
12
- } from "./chunk-PPSLI2ZI.js";
12
+ } from "./chunk-IBE6ACPE.js";
13
13
  import {
14
14
  findProjectRoot,
15
15
  getApiUrl,
@@ -665,6 +665,12 @@ function convertCollectionToApiFormat(local) {
665
665
  options.collectionId = field.collection;
666
666
  options.maxSelect = field.multiple ? 999 : 1;
667
667
  }
668
+ if (field.type === "currency") {
669
+ if (field.defaultCurrency) options.defaultCurrency = field.defaultCurrency;
670
+ if (field.decimalPrecision !== void 0) {
671
+ options.decimalPrecision = field.decimalPrecision;
672
+ }
673
+ }
668
674
  if (field.max !== void 0) options.max = field.max;
669
675
  if (field.min !== void 0) options.min = field.min;
670
676
  if (Object.keys(options).length > 0) {
@@ -692,7 +698,8 @@ function mapFieldType(type) {
692
698
  relation: "relation",
693
699
  file: "lumera_file",
694
700
  json: "json",
695
- editor: "editor"
701
+ editor: "editor",
702
+ currency: "currency"
696
703
  };
697
704
  return typeMap[type] || type;
698
705
  }
@@ -716,6 +723,14 @@ function fieldsDiffer(local, remote) {
716
723
  if (localMultiple && remoteMaxSelect <= 1) return true;
717
724
  if (!localMultiple && remoteMaxSelect > 1) return true;
718
725
  }
726
+ if (local.type === "currency") {
727
+ const localDefaultCurrency = (local.defaultCurrency || "USD").trim().toUpperCase();
728
+ const remoteDefaultCurrency = (opts.defaultCurrency || "USD").trim().toUpperCase();
729
+ if (localDefaultCurrency !== remoteDefaultCurrency) return true;
730
+ const localDecimalPrecision = local.decimalPrecision !== void 0 ? local.decimalPrecision : 2;
731
+ const remoteDecimalPrecision = opts.decimalPrecision !== void 0 ? opts.decimalPrecision : 2;
732
+ if (localDecimalPrecision !== remoteDecimalPrecision) return true;
733
+ }
719
734
  const localMin = local.min !== void 0 ? local.min : void 0;
720
735
  const remoteMin = opts.min !== void 0 ? opts.min : void 0;
721
736
  if (localMin !== remoteMin) return true;
@@ -1169,6 +1184,12 @@ async function pullCollections(api, platformDir, filterName, appName) {
1169
1184
  if (field.options.values) localField.values = field.options.values;
1170
1185
  if (field.options.collectionId) localField.collection = field.options.collectionId;
1171
1186
  if (field.options.maxSelect && field.options.maxSelect > 1) localField.multiple = true;
1187
+ if (field.options.defaultCurrency) {
1188
+ localField.defaultCurrency = field.options.defaultCurrency;
1189
+ }
1190
+ if (field.options.decimalPrecision !== void 0) {
1191
+ localField.decimalPrecision = field.options.decimalPrecision;
1192
+ }
1172
1193
  }
1173
1194
  return localField;
1174
1195
  }),
@@ -1873,7 +1894,12 @@ async function destroyApp(skipConfirm) {
1873
1894
  const filterParam = encodeURIComponent(JSON.stringify({ external_id: appName }));
1874
1895
  const searchRes = await fetchWithRetry(
1875
1896
  `${apiUrl}/api/pb/collections/lm_custom_apps/records?filter=${filterParam}`,
1876
- { headers: { Authorization: `Bearer ${token}` } }
1897
+ {
1898
+ headers: {
1899
+ Authorization: `Bearer ${token}`,
1900
+ "X-Lumera-Client": "lumera-cli"
1901
+ }
1902
+ }
1877
1903
  );
1878
1904
  if (!searchRes.ok) {
1879
1905
  throw new Error(`Failed to find app: ${await searchRes.text()}`);
@@ -1898,9 +1924,15 @@ async function destroyApp(skipConfirm) {
1898
1924
  return;
1899
1925
  }
1900
1926
  }
1901
- const deleteRes = await fetch(
1927
+ const deleteRes = await fetchWithRetry(
1902
1928
  `${apiUrl}/api/pb/collections/lm_custom_apps/records/${appRecord.id}`,
1903
- { method: "DELETE", headers: { Authorization: `Bearer ${token}` } }
1929
+ {
1930
+ method: "DELETE",
1931
+ headers: {
1932
+ Authorization: `Bearer ${token}`,
1933
+ "X-Lumera-Client": "lumera-cli"
1934
+ }
1935
+ }
1904
1936
  );
1905
1937
  if (!deleteRes.ok) {
1906
1938
  throw new Error(`Failed to delete app: ${await deleteRes.text()}`);
@@ -2064,7 +2096,12 @@ async function showResource(api, platformDir, resourceType, resourceName, appNam
2064
2096
  const filterParam = encodeURIComponent(JSON.stringify({ external_id: appName2 }));
2065
2097
  const searchRes = await fetchWithRetry(
2066
2098
  `${apiUrl}/api/pb/collections/lm_custom_apps/records?filter=${filterParam}`,
2067
- { headers: { Authorization: `Bearer ${token}` } }
2099
+ {
2100
+ headers: {
2101
+ Authorization: `Bearer ${token}`,
2102
+ "X-Lumera-Client": "lumera-cli"
2103
+ }
2104
+ }
2068
2105
  );
2069
2106
  if (searchRes.ok) {
2070
2107
  const data = await searchRes.json();
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-2CR762KB.js";
4
4
  import {
5
5
  createApiClient
6
- } from "./chunk-PPSLI2ZI.js";
6
+ } from "./chunk-IBE6ACPE.js";
7
7
  import {
8
8
  findProjectRoot,
9
9
  getApiUrl,
@@ -168,7 +168,8 @@ async function triggerAutomation(automationName, projectRoot, flags) {
168
168
  method: "POST",
169
169
  headers: {
170
170
  "Authorization": `Bearer ${token}`,
171
- "Content-Type": "application/json"
171
+ "Content-Type": "application/json",
172
+ "X-Lumera-Client": "lumera-cli"
172
173
  },
173
174
  body: JSON.stringify({
174
175
  automation_id: automation.id,
@@ -8,7 +8,7 @@ import {
8
8
  slugToDirName,
9
9
  slugToFilename,
10
10
  syncClaudeMd
11
- } from "./chunk-CCP66T22.js";
11
+ } from "./chunk-AUYOTENF.js";
12
12
  import "./chunk-ZH3NVYEQ.js";
13
13
  import "./chunk-FJFIWC7G.js";
14
14
  import "./chunk-PNKVD2UK.js";
@@ -23,7 +23,10 @@ async function validateToken(token) {
23
23
  const baseUrl = getBaseUrl();
24
24
  try {
25
25
  const response = await fetchWithRetry(`${baseUrl}/api/me`, {
26
- headers: { Authorization: `Bearer ${token}` }
26
+ headers: {
27
+ Authorization: `Bearer ${token}`,
28
+ "X-Lumera-Client": "lumera-cli"
29
+ }
27
30
  });
28
31
  if (!response.ok) {
29
32
  return { valid: false, error: `${response.status} ${response.statusText}` };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lumerahq/cli",
3
- "version": "0.18.11",
3
+ "version": "0.18.13",
4
4
  "description": "CLI for building and deploying Lumera apps",
5
5
  "type": "module",
6
6
  "engines": {