@anvil-works/anvil-cli 0.5.4 → 0.5.6

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/cli.js CHANGED
@@ -48023,6 +48023,16 @@ var __webpack_exports__ = {};
48023
48023
  function normalizeClientCodePath(relativePath) {
48024
48024
  return relativePath.replace(/\\/g, "/");
48025
48025
  }
48026
+ function isServerRequirementsPath(relativePath) {
48027
+ return "server_code/requirements.txt" === relativePath.replace(/\\/g, "/");
48028
+ }
48029
+ async function readServerRequirements(repoPath) {
48030
+ try {
48031
+ return await external_fs_.promises.readFile(external_path_default().join(repoPath, "server_code", "requirements.txt"), "utf8");
48032
+ } catch (error) {
48033
+ return;
48034
+ }
48035
+ }
48026
48036
  function detectFormTemplate(relativePath) {
48027
48037
  const normalized = normalizeClientCodePath(relativePath);
48028
48038
  if (!normalized.startsWith("client_code/")) return null;
@@ -48486,6 +48496,44 @@ var __webpack_exports__ = {};
48486
48496
  type: "ignore",
48487
48497
  reason: "anvil.yaml handled specially (multiple save paths)"
48488
48498
  };
48499
+ if (isServerRequirementsPath(relativePath)) {
48500
+ if ("unlink" === changeType) {
48501
+ const anvilYamlContent = await readFileContent(repoPath, "anvil.yaml", stagedOnly);
48502
+ const anvilConfig = jsYaml.load(anvilYamlContent) ?? {};
48503
+ const runtimeOptions = {
48504
+ ...anvilConfig.runtime_options ?? {}
48505
+ };
48506
+ const serverSpec = {
48507
+ ...runtimeOptions.server_spec ?? {}
48508
+ };
48509
+ delete serverSpec.requirements;
48510
+ if (Object.keys(serverSpec).length > 0) return {
48511
+ type: "save",
48512
+ savePath: [
48513
+ "runtime_options",
48514
+ "server_spec"
48515
+ ],
48516
+ content: serverSpec
48517
+ };
48518
+ delete runtimeOptions.server_spec;
48519
+ return {
48520
+ type: "save",
48521
+ savePath: [
48522
+ "runtime_options"
48523
+ ],
48524
+ content: runtimeOptions
48525
+ };
48526
+ }
48527
+ return {
48528
+ type: "save",
48529
+ savePath: [
48530
+ "runtime_options",
48531
+ "server_spec",
48532
+ "requirements"
48533
+ ],
48534
+ content: await readFileContent(repoPath, relativePath, stagedOnly)
48535
+ };
48536
+ }
48489
48537
  if ("unlink" === changeType) return await handleFileDeletion(repoPath, relativePath, editorYaml);
48490
48538
  for (const route of ROUTES)if (route.matches(relativePath)) return await route.handle(repoPath, relativePath, changeType, editorYaml, stagedOnly);
48491
48539
  return {
@@ -48892,6 +48940,14 @@ var __webpack_exports__ = {};
48892
48940
  throw new Error(`Failed to parse anvil.yaml: ${error.message}. File may be in an invalid state.`);
48893
48941
  }
48894
48942
  if (!parsedYaml || "object" != typeof parsedYaml) throw new Error("anvil.yaml is not a valid YAML object");
48943
+ const currentRequirements = await readServerRequirements(repoPath);
48944
+ if (void 0 !== currentRequirements) parsedYaml.runtime_options = {
48945
+ ...parsedYaml.runtime_options ?? {},
48946
+ server_spec: {
48947
+ ...parsedYaml.runtime_options?.server_spec ?? {},
48948
+ requirements: currentRequirements
48949
+ }
48950
+ };
48895
48951
  if (!validateAnvilYaml(yamlContent)) throw new Error("anvil.yaml validation failed - see errors above");
48896
48952
  const changes = [];
48897
48953
  for (const [key, value] of Object.entries(parsedYaml))if (!previousYaml || !deepEqual(previousYaml[key], value)) changes.push({
@@ -49135,7 +49191,19 @@ var __webpack_exports__ = {};
49135
49191
  async getHeadAnvilYaml() {
49136
49192
  try {
49137
49193
  const content = await this.config.gitService.show("HEAD:anvil.yaml");
49138
- return js_yaml_load(content);
49194
+ const parsedYaml = js_yaml_load(content);
49195
+ if (!parsedYaml || "object" != typeof parsedYaml) return null;
49196
+ try {
49197
+ const requirements = await this.config.gitService.show("HEAD:server_code/requirements.txt");
49198
+ parsedYaml.runtime_options = {
49199
+ ...parsedYaml.runtime_options ?? {},
49200
+ server_spec: {
49201
+ ...parsedYaml.runtime_options?.server_spec ?? {},
49202
+ requirements
49203
+ }
49204
+ };
49205
+ } catch (e) {}
49206
+ return parsedYaml;
49139
49207
  } catch (e) {
49140
49208
  return null;
49141
49209
  }
@@ -50807,7 +50875,7 @@ var __webpack_exports__ = {};
50807
50875
  async function confirmReverseLookupWithResolvedUser(anvilUrl, username) {
50808
50876
  const resolvedUsername = await resolveUsernameForUrl(anvilUrl, username, `Multiple accounts found for ${anvilUrl}. Which account should be used for app lookup?`);
50809
50877
  if (null === resolvedUsername) return null;
50810
- const shouldContinue = await logger_logger.confirm(`Search ${anvilUrl} ${resolvedUsername ? `for ${resolvedUsername}` : ""} for matching app IDs? (slower)`, true);
50878
+ const shouldContinue = await logger_logger.confirm(`Search ${anvilUrl} ${resolvedUsername ? `for ${resolvedUsername}` : ""} for matching app IDs? This is slower than detecting the app ID from local git remotes.`, true);
50811
50879
  return {
50812
50880
  username: resolvedUsername,
50813
50881
  shouldContinue
@@ -50864,6 +50932,11 @@ var __webpack_exports__ = {};
50864
50932
  };
50865
50933
  return null;
50866
50934
  }
50935
+ if (1 === candidates.length) {
50936
+ const [candidate] = candidates;
50937
+ logger_logger.success("Auto-selected detected app ID: " + chalk_source.bold(candidate.appId));
50938
+ return candidate;
50939
+ }
50867
50940
  const choices = candidates.map((candidate, index)=>({
50868
50941
  name: formatCandidateLabel(candidate),
50869
50942
  value: index
@@ -50873,12 +50946,11 @@ var __webpack_exports__ = {};
50873
50946
  value: null
50874
50947
  });
50875
50948
  try {
50876
- const promptText = 1 === candidates.length ? "Confirm the detected app ID:" : "Select an app ID:";
50877
50949
  const answer = await logger_logger.prompt([
50878
50950
  {
50879
50951
  type: "list",
50880
50952
  name: "appId",
50881
- message: promptText,
50953
+ message: "Select an app ID:",
50882
50954
  choices: choices,
50883
50955
  pageSize: 10
50884
50956
  }
package/dist/index.js CHANGED
@@ -23536,6 +23536,16 @@ var __webpack_exports__ = {};
23536
23536
  function normalizeClientCodePath(relativePath) {
23537
23537
  return relativePath.replace(/\\/g, "/");
23538
23538
  }
23539
+ function isServerRequirementsPath(relativePath) {
23540
+ return "server_code/requirements.txt" === relativePath.replace(/\\/g, "/");
23541
+ }
23542
+ async function readServerRequirements(repoPath) {
23543
+ try {
23544
+ return await external_fs_.promises.readFile(external_path_default().join(repoPath, "server_code", "requirements.txt"), "utf8");
23545
+ } catch (error) {
23546
+ return;
23547
+ }
23548
+ }
23539
23549
  function detectFormTemplate(relativePath) {
23540
23550
  const normalized = normalizeClientCodePath(relativePath);
23541
23551
  if (!normalized.startsWith("client_code/")) return null;
@@ -23999,6 +24009,44 @@ var __webpack_exports__ = {};
23999
24009
  type: "ignore",
24000
24010
  reason: "anvil.yaml handled specially (multiple save paths)"
24001
24011
  };
24012
+ if (isServerRequirementsPath(relativePath)) {
24013
+ if ("unlink" === changeType) {
24014
+ const anvilYamlContent = await readFileContent(repoPath, "anvil.yaml", stagedOnly);
24015
+ const anvilConfig = jsYaml.load(anvilYamlContent) ?? {};
24016
+ const runtimeOptions = {
24017
+ ...anvilConfig.runtime_options ?? {}
24018
+ };
24019
+ const serverSpec = {
24020
+ ...runtimeOptions.server_spec ?? {}
24021
+ };
24022
+ delete serverSpec.requirements;
24023
+ if (Object.keys(serverSpec).length > 0) return {
24024
+ type: "save",
24025
+ savePath: [
24026
+ "runtime_options",
24027
+ "server_spec"
24028
+ ],
24029
+ content: serverSpec
24030
+ };
24031
+ delete runtimeOptions.server_spec;
24032
+ return {
24033
+ type: "save",
24034
+ savePath: [
24035
+ "runtime_options"
24036
+ ],
24037
+ content: runtimeOptions
24038
+ };
24039
+ }
24040
+ return {
24041
+ type: "save",
24042
+ savePath: [
24043
+ "runtime_options",
24044
+ "server_spec",
24045
+ "requirements"
24046
+ ],
24047
+ content: await readFileContent(repoPath, relativePath, stagedOnly)
24048
+ };
24049
+ }
24002
24050
  if ("unlink" === changeType) return await handleFileDeletion(repoPath, relativePath, editorYaml);
24003
24051
  for (const route of ROUTES)if (route.matches(relativePath)) return await route.handle(repoPath, relativePath, changeType, editorYaml, stagedOnly);
24004
24052
  return {
@@ -24405,6 +24453,14 @@ var __webpack_exports__ = {};
24405
24453
  throw new Error(`Failed to parse anvil.yaml: ${error.message}. File may be in an invalid state.`);
24406
24454
  }
24407
24455
  if (!parsedYaml || "object" != typeof parsedYaml) throw new Error("anvil.yaml is not a valid YAML object");
24456
+ const currentRequirements = await readServerRequirements(repoPath);
24457
+ if (void 0 !== currentRequirements) parsedYaml.runtime_options = {
24458
+ ...parsedYaml.runtime_options ?? {},
24459
+ server_spec: {
24460
+ ...parsedYaml.runtime_options?.server_spec ?? {},
24461
+ requirements: currentRequirements
24462
+ }
24463
+ };
24408
24464
  if (!validateAnvilYaml(yamlContent)) throw new Error("anvil.yaml validation failed - see errors above");
24409
24465
  const changes = [];
24410
24466
  for (const [key, value] of Object.entries(parsedYaml))if (!previousYaml || !deepEqual(previousYaml[key], value)) changes.push({
@@ -24648,7 +24704,19 @@ var __webpack_exports__ = {};
24648
24704
  async getHeadAnvilYaml() {
24649
24705
  try {
24650
24706
  const content = await this.config.gitService.show("HEAD:anvil.yaml");
24651
- return load(content);
24707
+ const parsedYaml = load(content);
24708
+ if (!parsedYaml || "object" != typeof parsedYaml) return null;
24709
+ try {
24710
+ const requirements = await this.config.gitService.show("HEAD:server_code/requirements.txt");
24711
+ parsedYaml.runtime_options = {
24712
+ ...parsedYaml.runtime_options ?? {},
24713
+ server_spec: {
24714
+ ...parsedYaml.runtime_options?.server_spec ?? {},
24715
+ requirements
24716
+ }
24717
+ };
24718
+ } catch (e) {}
24719
+ return parsedYaml;
24652
24720
  } catch (e) {
24653
24721
  return null;
24654
24722
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anvil-works/anvil-cli",
3
- "version": "0.5.4",
3
+ "version": "0.5.6",
4
4
  "description": "CLI tool for developing Anvil apps locally",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -30,4 +30,10 @@ powershell -NoProfile -ExecutionPolicy Bypass -File "%SCRIPT_PATH%"
30
30
  set "EXIT_CODE=%ERRORLEVEL%"
31
31
 
32
32
  del /q "%SCRIPT_PATH%" >nul 2>&1
33
+
34
+ if "%EXIT_CODE%"=="0" (
35
+ echo.
36
+ echo Next steps: run 'anvil configure' or 'anvil checkout'
37
+ )
38
+
33
39
  exit /b %EXIT_CODE%
@@ -183,7 +183,7 @@ function Main {
183
183
 
184
184
  Write-Info ''
185
185
  Write-Info "anvil-cli installed successfully (v$version)"
186
- Write-Info "Next step: run 'anvil configure'"
186
+ Write-Info "Next steps: run 'anvil configure' or 'anvil checkout'"
187
187
  Write-Info "If your current terminal cannot find 'anvil', start a new terminal session."
188
188
  }
189
189
 
@@ -153,7 +153,7 @@ main() {
153
153
 
154
154
  log ""
155
155
  log "anvil-cli installed successfully${version:+ (v$version)}"
156
- log "Next step: run 'anvil configure'"
156
+ log "Next steps: run 'anvil configure' or 'anvil checkout'"
157
157
  log "If your current shell cannot find 'anvil', open a new terminal session."
158
158
  }
159
159