@lumerahq/cli 0.36.0-dev.0 → 0.36.1

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.
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  findFunctionsProjectRoot
3
- } from "./chunk-XZ5VCTGY.js";
3
+ } from "./chunk-PIY3XXJI.js";
4
4
  import {
5
5
  RELEASE_SDK_REQUIREMENT
6
- } from "./chunk-5FGDEZSJ.js";
6
+ } from "./chunk-KI57NBGA.js";
7
7
 
8
8
  // src/commands/project.ts
9
9
  import { spawn } from "child_process";
@@ -1,6 +1,6 @@
1
1
  // src/lib/functions-sdk.ts
2
- var FUNCTIONS_SDK_VERSION_RANGE = ">=0.45.0,<0.46.0";
3
- var FUNCTIONS_SDK_COMPATIBILITY_RANGE = ">=0.34.0,<0.46.0";
2
+ var FUNCTIONS_SDK_VERSION_RANGE = ">=0.48.0,<0.49.0";
3
+ var FUNCTIONS_SDK_COMPATIBILITY_RANGE = ">=0.34.0,<0.49.0";
4
4
  var FUNCTIONS_SDK_REQUIREMENT = `lumera[functions]${FUNCTIONS_SDK_COMPATIBILITY_RANGE}`;
5
5
  var DEFAULT_FUNCTIONS_SDK_REQUIREMENT = `lumera[functions]${FUNCTIONS_SDK_VERSION_RANGE}`;
6
6
  var RELEASE_SDK_REQUIREMENT = `lumera[release]${FUNCTIONS_SDK_VERSION_RANGE}`;
@@ -5,7 +5,7 @@ import {
5
5
  import {
6
6
  buildReleaseRunnerArgs,
7
7
  runReleaseRunner
8
- } from "./chunk-2EHJH2QU.js";
8
+ } from "./chunk-CHUCWVFV.js";
9
9
  import {
10
10
  userContextHeaders
11
11
  } from "./chunk-RV7WQAK3.js";
@@ -200,7 +200,7 @@ async function deploy(options) {
200
200
  accessLevel,
201
201
  skipAppAPI
202
202
  } = options;
203
- if (!existsSync(distDir)) {
203
+ if (!options.reuseFrontend && !existsSync(distDir)) {
204
204
  throw new Error(`dist directory not found: ${distDir}`);
205
205
  }
206
206
  const projectDir = dirname(distDir);
@@ -210,12 +210,19 @@ async function deploy(options) {
210
210
  console.log(pc.dim("Ensuring app record..."));
211
211
  await ensureAppRecord(apiUrl, token, appName, appTitle, accessLevel);
212
212
  console.log(pc.cyan(`Preparing ${appTitle}...`));
213
- const version = resolveDeploymentVersion(projectDir, gitRelease, options.version);
213
+ const version = options.reuseFrontend ? options.version || process.env.LUMERA_APP_VERSION?.trim() || gitRelease.sha.slice(0, 7) : resolveDeploymentVersion(projectDir, gitRelease, options.version);
214
+ if (options.reuseFrontend && !gitRelease.sha) {
215
+ throw new Error("Reusing a frontend requires a committed Git revision");
216
+ }
214
217
  console.log(pc.dim(`Version: ${version}`));
215
- const tarball = await createTarball(distDir);
216
- console.log(pc.dim(`Package: ${(tarball.length / 1024).toFixed(1)} KB`));
217
218
  const formData = new FormData();
218
- formData.append("tarball", new Blob([new Uint8Array(tarball)]), "dist.tar.gz");
219
+ if (options.reuseFrontend) {
220
+ formData.append("reuse_frontend", options.reuseFrontend);
221
+ } else {
222
+ const tarball = await createTarball(distDir);
223
+ console.log(pc.dim(`Package: ${(tarball.length / 1024).toFixed(1)} KB`));
224
+ formData.append("tarball", new Blob([new Uint8Array(tarball)]), "dist.tar.gz");
225
+ }
219
226
  formData.append("version", version);
220
227
  if (gitRelease.sha) formData.append("git_sha", gitRelease.sha);
221
228
  const uiVersion = resolveUIVersion(projectDir);
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  FUNCTIONS_SDK_REQUIREMENT
3
- } from "./chunk-5FGDEZSJ.js";
3
+ } from "./chunk-KI57NBGA.js";
4
4
 
5
5
  // src/commands/functions.ts
6
6
  import { spawn } from "child_process";
@@ -146,6 +146,7 @@ async function syncResourceShareDeps(projectRoot, api, projectExternalId, opts)
146
146
  mkdirSync(viewsDir, { recursive: true });
147
147
  }
148
148
  for (const item of functionImports) {
149
+ if (item.managed_by_git) continue;
149
150
  const fileName = functionImportFileName(item);
150
151
  const filePath = join(functionsDir, fileName);
151
152
  const exists = existsSync(filePath);
@@ -2,7 +2,7 @@ import {
2
2
  deps,
3
3
  syncDeps,
4
4
  syncResourceShareDeps
5
- } from "./chunk-MFAEFPHY.js";
5
+ } from "./chunk-Z7GPNMK5.js";
6
6
  import "./chunk-2CR762KB.js";
7
7
  import "./chunk-RV7WQAK3.js";
8
8
  import "./chunk-JLVVHTBY.js";
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  dev
3
- } from "./chunk-DXHA72QY.js";
3
+ } from "./chunk-LPKJZUG2.js";
4
4
  import "./chunk-UGAIWMQV.js";
5
- import "./chunk-2EHJH2QU.js";
6
- import "./chunk-XZ5VCTGY.js";
7
- import "./chunk-5FGDEZSJ.js";
5
+ import "./chunk-CHUCWVFV.js";
6
+ import "./chunk-PIY3XXJI.js";
7
+ import "./chunk-KI57NBGA.js";
8
8
  import {
9
9
  syncDeps
10
- } from "./chunk-MFAEFPHY.js";
10
+ } from "./chunk-Z7GPNMK5.js";
11
11
  import {
12
12
  loadEnv
13
13
  } from "./chunk-2CR762KB.js";
@@ -4,8 +4,8 @@ import {
4
4
  findFunctionsProjectRoot,
5
5
  functions,
6
6
  runFunctionRunner
7
- } from "./chunk-XZ5VCTGY.js";
8
- import "./chunk-5FGDEZSJ.js";
7
+ } from "./chunk-PIY3XXJI.js";
8
+ import "./chunk-KI57NBGA.js";
9
9
  import "./chunk-PNKVD2UK.js";
10
10
  export {
11
11
  buildFunctionRunnerArgs,
package/dist/index.js CHANGED
@@ -243,40 +243,40 @@ async function main() {
243
243
  switch (command) {
244
244
  // Resource commands
245
245
  case "plan":
246
- await import("./resources-IW5JT7A3.js").then((m) => m.plan(args.slice(1)));
246
+ await import("./resources-S7IGFX2W.js").then((m) => m.plan(args.slice(1)));
247
247
  break;
248
248
  case "apply":
249
- await import("./resources-IW5JT7A3.js").then((m) => m.apply(args.slice(1)));
249
+ await import("./resources-S7IGFX2W.js").then((m) => m.apply(args.slice(1)));
250
250
  break;
251
251
  case "pull":
252
- await import("./resources-IW5JT7A3.js").then((m) => m.pull(args.slice(1)));
252
+ await import("./resources-S7IGFX2W.js").then((m) => m.pull(args.slice(1)));
253
253
  break;
254
254
  case "destroy":
255
- await import("./resources-IW5JT7A3.js").then((m) => m.destroy(args.slice(1)));
255
+ await import("./resources-S7IGFX2W.js").then((m) => m.destroy(args.slice(1)));
256
256
  break;
257
257
  case "list":
258
- await import("./resources-IW5JT7A3.js").then((m) => m.list(args.slice(1)));
258
+ await import("./resources-S7IGFX2W.js").then((m) => m.list(args.slice(1)));
259
259
  break;
260
260
  case "show":
261
- await import("./resources-IW5JT7A3.js").then((m) => m.show(args.slice(1)));
261
+ await import("./resources-S7IGFX2W.js").then((m) => m.show(args.slice(1)));
262
262
  break;
263
263
  case "diff":
264
- await import("./resources-IW5JT7A3.js").then((m) => m.diff(args.slice(1)));
264
+ await import("./resources-S7IGFX2W.js").then((m) => m.diff(args.slice(1)));
265
265
  break;
266
266
  // Development
267
267
  case "dev":
268
- await import("./dev-NEHWUIWB.js").then((m) => m.dev(args.slice(1)));
268
+ await import("./dev-PDBCCR3L.js").then((m) => m.dev(args.slice(1)));
269
269
  break;
270
270
  case "run":
271
271
  await import("./run-TMJPC4PK.js").then((m) => m.run(args.slice(1)));
272
272
  break;
273
273
  case "functions":
274
- await import("./functions-5OOHGQT7.js").then(
274
+ await import("./functions-C5SGYMZK.js").then(
275
275
  (m) => m.functions(subcommand, args.slice(2))
276
276
  );
277
277
  break;
278
278
  case "project":
279
- await import("./project-ISKXDHGJ.js").then(
279
+ await import("./project-ESK2Z6H6.js").then(
280
280
  (m) => m.project(subcommand, args.slice(2))
281
281
  );
282
282
  break;
@@ -294,7 +294,7 @@ async function main() {
294
294
  await import("./status-NPNIY3QP.js").then((m) => m.status(args.slice(1)));
295
295
  break;
296
296
  case "migrate":
297
- await import("./migrate-Q2QY3YSL.js").then((m) => m.migrate(args.slice(1)));
297
+ await import("./migrate-NWTNC2V3.js").then((m) => m.migrate(args.slice(1)));
298
298
  break;
299
299
  // Skills
300
300
  case "skills":
@@ -302,7 +302,7 @@ async function main() {
302
302
  break;
303
303
  // Dependencies
304
304
  case "deps":
305
- await import("./deps-OUTYSIZU.js").then((m) => m.deps(args.slice(1)));
305
+ await import("./deps-SIKW7IW2.js").then((m) => m.deps(args.slice(1)));
306
306
  break;
307
307
  // Feature flags (read the in-sandbox snapshot)
308
308
  case "flags":
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-UGAIWMQV.js";
5
5
  import {
6
6
  DEFAULT_FUNCTIONS_SDK_REQUIREMENT
7
- } from "./chunk-5FGDEZSJ.js";
7
+ } from "./chunk-KI57NBGA.js";
8
8
  import {
9
9
  detectProjectVersion,
10
10
  findProjectRoot
@@ -2,9 +2,9 @@ import {
2
2
  buildReleaseRunnerArgs,
3
3
  project,
4
4
  runReleaseRunner
5
- } from "./chunk-2EHJH2QU.js";
6
- import "./chunk-XZ5VCTGY.js";
7
- import "./chunk-5FGDEZSJ.js";
5
+ } from "./chunk-CHUCWVFV.js";
6
+ import "./chunk-PIY3XXJI.js";
7
+ import "./chunk-KI57NBGA.js";
8
8
  import "./chunk-PNKVD2UK.js";
9
9
  export {
10
10
  buildReleaseRunnerArgs,
@@ -1,14 +1,14 @@
1
1
  import {
2
2
  deploy,
3
3
  deployAppAPI
4
- } from "./chunk-DXHA72QY.js";
4
+ } from "./chunk-LPKJZUG2.js";
5
5
  import "./chunk-UGAIWMQV.js";
6
- import "./chunk-2EHJH2QU.js";
7
- import "./chunk-XZ5VCTGY.js";
8
- import "./chunk-5FGDEZSJ.js";
6
+ import "./chunk-CHUCWVFV.js";
7
+ import "./chunk-PIY3XXJI.js";
8
+ import "./chunk-KI57NBGA.js";
9
9
  import {
10
10
  syncDeps
11
- } from "./chunk-MFAEFPHY.js";
11
+ } from "./chunk-Z7GPNMK5.js";
12
12
  import {
13
13
  loadEnv
14
14
  } from "./chunk-2CR762KB.js";
@@ -482,7 +482,7 @@ var collectionSchemaRule = {
482
482
  ...field.multiple !== void 0 ? ['"multiple"'] : []
483
483
  ];
484
484
  if (ignored.length > 0) {
485
- const fixed = legacyFile ? " A lumera_file field's maxSelect cannot change after it is first deployed; use lumera_file_v2 if it needs to." : "";
485
+ const fixed = legacyFile ? " A lumera_file field's maxSelect cannot change after it is first deployed." : "";
486
486
  issues.push(warning(
487
487
  target,
488
488
  `File field ${label} sets ${ignored.join(" and ")}, which collection files ignore; it deploys with maxSelect ${field.maxSelect ?? 1}. Set top-level "maxSelect" instead.${fixed}`
@@ -1268,7 +1268,7 @@ async function lintAgentFiles(api, projectRoot, platformDir, appName, filterName
1268
1268
  return result.issues;
1269
1269
  }
1270
1270
  var PACKAGE_MANAGERS = ["bun", "pnpm", "yarn", "npm"];
1271
- var PACKAGE_MANAGER_VALUE_FLAGS = /* @__PURE__ */ new Set(["--package-manager"]);
1271
+ var PACKAGE_MANAGER_VALUE_FLAGS = /* @__PURE__ */ new Set(["--package-manager", "--reuse-frontend"]);
1272
1272
  function isPackageManager(value) {
1273
1273
  return PACKAGE_MANAGERS.includes(value);
1274
1274
  }
@@ -1682,6 +1682,7 @@ ${pc2.dim("Resources:")}
1682
1682
 
1683
1683
  ${pc2.dim("Options:")}
1684
1684
  --yes, -y Skip confirmation prompt (for CI/CD)
1685
+ --reuse-frontend <deployment-id> Publish all resources/runtime with an existing frontend
1685
1686
  --skip-build Skip the frontend build; still deploy the project runtime
1686
1687
  --skip-app-api Publish only the frontend without deploying the project runtime
1687
1688
  --no-app Apply resources only; do not build/deploy the app
@@ -2150,7 +2151,7 @@ function lumeraFileMaxSelectErrors(local, remote) {
2150
2151
  const requestedMaxSelect = Math.max(Number(normalizeFieldOption("lumera_file", "maxSelect", field.maxSelect)), 1);
2151
2152
  if (deployedMaxSelect === requestedMaxSelect) continue;
2152
2153
  const requested = field.maxSelect === void 0 ? "omitting maxSelect (defaults to 1)" : `maxSelect ${requestedMaxSelect}`;
2153
- errors.push(`File field "${field.name}" is deployed with maxSelect ${deployedMaxSelect}; ${requested} would change it, which is not supported. Keep maxSelect ${deployedMaxSelect}. To change the limit, move the field to lumera_file_v2.`);
2154
+ errors.push(`File field "${field.name}" is deployed with maxSelect ${deployedMaxSelect}; ${requested} would change it, which is not supported. Keep maxSelect ${deployedMaxSelect}.`);
2154
2155
  }
2155
2156
  return errors;
2156
2157
  }
@@ -2798,7 +2799,8 @@ async function applyHooks(api, localHooks, collections, projectId) {
2798
2799
  return errors;
2799
2800
  }
2800
2801
  async function applyApp(args) {
2801
- const skipBuild = args.includes("--skip-build");
2802
+ const reuseFrontend = getFlagValue(args, "reuse-frontend");
2803
+ const skipBuild = args.includes("--skip-build") || !!reuseFrontend;
2802
2804
  const skipAppAPI = args.includes("--skip-app-api");
2803
2805
  const projectRoot = findProjectRoot();
2804
2806
  loadEnv(projectRoot);
@@ -2830,7 +2832,7 @@ async function applyApp(args) {
2830
2832
  `Invalid --access-level "${accessLevel}". Valid values: ${validAccessLevels.join(", ")}`
2831
2833
  );
2832
2834
  }
2833
- await deploy({ token, appName, appTitle, distDir, apiUrl, accessLevel, skipAppAPI });
2835
+ await deploy({ token, appName, appTitle, distDir, apiUrl, accessLevel, skipAppAPI, reuseFrontend });
2834
2836
  }
2835
2837
  async function applyAppAPI(projectRoot) {
2836
2838
  await deployAppAPI({
@@ -4743,6 +4745,9 @@ async function apply(args) {
4743
4745
  const { type, name } = parseResource(positionalArgs[0]);
4744
4746
  const autoConfirm = args.includes("--yes") || args.includes("-y") || !!process.env.CI;
4745
4747
  const skipApp = args.includes("--no-app") || args.includes("--resources-only");
4748
+ if (args.includes("--reuse-frontend") && (type || skipApp || args.includes("--skip-app-api") || !getFlagValue(args, "reuse-frontend"))) {
4749
+ throw new Error("--reuse-frontend requires a deployment ID and a full resource/runtime apply");
4750
+ }
4746
4751
  if (type === "app" && skipApp) {
4747
4752
  throw new Error("Cannot combine app resource with --no-app / --resources-only");
4748
4753
  }
@@ -4827,7 +4832,7 @@ async function apply(args) {
4827
4832
  let willDeployApp = false;
4828
4833
  if (!type && !skipApp) {
4829
4834
  try {
4830
- if (existsSync3(join3(projectRoot, "dist")) || existsSync3(join3(projectRoot, "src"))) {
4835
+ if (getFlagValue(args, "reuse-frontend") || existsSync3(join3(projectRoot, "dist")) || existsSync3(join3(projectRoot, "src"))) {
4831
4836
  willDeployApp = true;
4832
4837
  }
4833
4838
  } catch {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lumerahq/cli",
3
- "version": "0.36.0-dev.0",
3
+ "version": "0.36.1",
4
4
  "description": "CLI for building and deploying Lumera apps",
5
5
  "type": "module",
6
6
  "engines": {
@@ -4,7 +4,7 @@ version = "0.1.0"
4
4
  description = "{{projectTitle}} - Lumera custom app"
5
5
  requires-python = ">=3.11"
6
6
  dependencies = [
7
- "lumera[functions]>=0.45.0,<0.46.0",
7
+ "lumera[functions]>=0.48.0,<0.49.0",
8
8
  ]
9
9
 
10
10
  [project.optional-dependencies]