@xano/cli 0.0.95-beta.9 → 1.0.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.
Files changed (240) hide show
  1. package/README.md +111 -70
  2. package/dist/base-command.d.ts +16 -1
  3. package/dist/base-command.js +57 -5
  4. package/dist/commands/auth/index.d.ts +1 -0
  5. package/dist/commands/auth/index.js +15 -10
  6. package/dist/commands/branch/create/index.d.ts +4 -1
  7. package/dist/commands/branch/create/index.js +22 -21
  8. package/dist/commands/branch/delete/index.d.ts +1 -0
  9. package/dist/commands/branch/delete/index.js +1 -4
  10. package/dist/commands/branch/edit/index.d.ts +1 -0
  11. package/dist/commands/branch/edit/index.js +1 -4
  12. package/dist/commands/branch/get/index.d.ts +1 -0
  13. package/dist/commands/branch/get/index.js +1 -4
  14. package/dist/commands/branch/list/index.d.ts +2 -6
  15. package/dist/commands/branch/list/index.js +13 -17
  16. package/dist/commands/branch/set_live/index.d.ts +1 -0
  17. package/dist/commands/branch/set_live/index.js +1 -4
  18. package/dist/commands/function/create/index.d.ts +1 -0
  19. package/dist/commands/function/create/index.js +1 -2
  20. package/dist/commands/function/edit/index.d.ts +1 -0
  21. package/dist/commands/function/edit/index.js +1 -2
  22. package/dist/commands/function/get/index.d.ts +1 -0
  23. package/dist/commands/function/get/index.js +1 -4
  24. package/dist/commands/function/list/index.d.ts +1 -0
  25. package/dist/commands/function/list/index.js +1 -4
  26. package/dist/commands/platform/get/index.d.ts +1 -0
  27. package/dist/commands/platform/get/index.js +1 -4
  28. package/dist/commands/platform/list/index.d.ts +1 -0
  29. package/dist/commands/platform/list/index.js +1 -4
  30. package/dist/commands/profile/create/index.d.ts +1 -0
  31. package/dist/commands/profile/create/index.js +10 -4
  32. package/dist/commands/profile/delete/index.d.ts +1 -0
  33. package/dist/commands/profile/delete/index.js +8 -4
  34. package/dist/commands/profile/edit/index.d.ts +1 -0
  35. package/dist/commands/profile/edit/index.js +1 -4
  36. package/dist/commands/profile/get/index.d.ts +3 -0
  37. package/dist/commands/profile/get/index.js +12 -5
  38. package/dist/commands/profile/list/index.d.ts +1 -0
  39. package/dist/commands/profile/list/index.js +8 -4
  40. package/dist/commands/profile/me/index.d.ts +1 -0
  41. package/dist/commands/profile/me/index.js +1 -4
  42. package/dist/commands/profile/set/index.d.ts +3 -0
  43. package/dist/commands/profile/set/index.js +12 -6
  44. package/dist/commands/profile/token/index.d.ts +3 -0
  45. package/dist/commands/profile/token/index.js +12 -5
  46. package/dist/commands/profile/wizard/index.d.ts +1 -0
  47. package/dist/commands/profile/wizard/index.js +13 -9
  48. package/dist/commands/profile/workspace/index.d.ts +3 -0
  49. package/dist/commands/profile/workspace/index.js +12 -5
  50. package/dist/commands/profile/workspace/set/index.d.ts +1 -0
  51. package/dist/commands/profile/workspace/set/index.js +1 -3
  52. package/dist/commands/release/create/index.d.ts +4 -1
  53. package/dist/commands/release/create/index.js +12 -14
  54. package/dist/commands/release/delete/index.d.ts +1 -0
  55. package/dist/commands/release/delete/index.js +1 -4
  56. package/dist/commands/release/deploy/index.d.ts +3 -0
  57. package/dist/commands/release/deploy/index.js +31 -1
  58. package/dist/commands/release/edit/index.d.ts +1 -0
  59. package/dist/commands/release/edit/index.js +1 -4
  60. package/dist/commands/release/export/index.d.ts +1 -0
  61. package/dist/commands/release/export/index.js +1 -3
  62. package/dist/commands/release/get/index.d.ts +1 -0
  63. package/dist/commands/release/get/index.js +1 -4
  64. package/dist/commands/release/import/index.d.ts +1 -0
  65. package/dist/commands/release/import/index.js +1 -3
  66. package/dist/commands/release/list/index.d.ts +1 -0
  67. package/dist/commands/release/list/index.js +1 -4
  68. package/dist/commands/release/pull/index.d.ts +2 -3
  69. package/dist/commands/release/pull/index.js +19 -18
  70. package/dist/commands/release/push/index.d.ts +2 -3
  71. package/dist/commands/release/push/index.js +19 -22
  72. package/dist/commands/sandbox/delete/index.d.ts +13 -0
  73. package/dist/commands/sandbox/delete/index.js +71 -0
  74. package/dist/commands/sandbox/env/delete/index.d.ts +1 -0
  75. package/dist/commands/sandbox/env/delete/index.js +4 -2
  76. package/dist/commands/sandbox/env/get/index.d.ts +1 -0
  77. package/dist/commands/sandbox/env/get/index.js +4 -2
  78. package/dist/commands/sandbox/env/get_all/index.d.ts +1 -0
  79. package/dist/commands/sandbox/env/get_all/index.js +4 -2
  80. package/dist/commands/sandbox/env/list/index.d.ts +1 -0
  81. package/dist/commands/sandbox/env/list/index.js +4 -2
  82. package/dist/commands/sandbox/env/set/index.d.ts +1 -0
  83. package/dist/commands/sandbox/env/set/index.js +4 -2
  84. package/dist/commands/sandbox/env/set_all/index.d.ts +1 -0
  85. package/dist/commands/sandbox/env/set_all/index.js +4 -2
  86. package/dist/commands/sandbox/get/index.d.ts +1 -0
  87. package/dist/commands/sandbox/get/index.js +2 -0
  88. package/dist/commands/sandbox/license/get/index.d.ts +1 -0
  89. package/dist/commands/sandbox/license/get/index.js +4 -2
  90. package/dist/commands/sandbox/license/set/index.d.ts +1 -0
  91. package/dist/commands/sandbox/license/set/index.js +4 -2
  92. package/dist/commands/sandbox/pull/index.d.ts +2 -3
  93. package/dist/commands/sandbox/pull/index.js +19 -14
  94. package/dist/commands/sandbox/push/index.d.ts +12 -4
  95. package/dist/commands/sandbox/push/index.js +150 -95
  96. package/dist/commands/sandbox/reset/index.d.ts +1 -0
  97. package/dist/commands/sandbox/reset/index.js +4 -2
  98. package/dist/commands/sandbox/review/index.d.ts +1 -0
  99. package/dist/commands/sandbox/review/index.js +4 -2
  100. package/dist/commands/sandbox/unit_test/list/index.d.ts +1 -0
  101. package/dist/commands/sandbox/unit_test/list/index.js +4 -2
  102. package/dist/commands/sandbox/unit_test/run/index.d.ts +1 -0
  103. package/dist/commands/sandbox/unit_test/run/index.js +4 -2
  104. package/dist/commands/sandbox/unit_test/run_all/index.d.ts +1 -0
  105. package/dist/commands/sandbox/unit_test/run_all/index.js +4 -0
  106. package/dist/commands/sandbox/workflow_test/list/index.d.ts +1 -0
  107. package/dist/commands/sandbox/workflow_test/list/index.js +4 -2
  108. package/dist/commands/sandbox/workflow_test/run/index.d.ts +1 -0
  109. package/dist/commands/sandbox/workflow_test/run/index.js +4 -2
  110. package/dist/commands/sandbox/workflow_test/run_all/index.d.ts +1 -0
  111. package/dist/commands/sandbox/workflow_test/run_all/index.js +4 -0
  112. package/dist/commands/static_host/build/create/index.d.ts +1 -0
  113. package/dist/commands/static_host/build/create/index.js +1 -3
  114. package/dist/commands/static_host/build/get/index.d.ts +1 -0
  115. package/dist/commands/static_host/build/get/index.js +1 -4
  116. package/dist/commands/static_host/build/list/index.d.ts +1 -0
  117. package/dist/commands/static_host/build/list/index.js +1 -4
  118. package/dist/commands/static_host/list/index.d.ts +1 -0
  119. package/dist/commands/static_host/list/index.js +1 -4
  120. package/dist/commands/tenant/backup/create/index.d.ts +1 -0
  121. package/dist/commands/tenant/backup/create/index.js +1 -4
  122. package/dist/commands/tenant/backup/delete/index.d.ts +1 -0
  123. package/dist/commands/tenant/backup/delete/index.js +1 -4
  124. package/dist/commands/tenant/backup/export/index.d.ts +1 -0
  125. package/dist/commands/tenant/backup/export/index.js +1 -3
  126. package/dist/commands/tenant/backup/import/index.d.ts +1 -0
  127. package/dist/commands/tenant/backup/import/index.js +1 -3
  128. package/dist/commands/tenant/backup/list/index.d.ts +1 -0
  129. package/dist/commands/tenant/backup/list/index.js +1 -4
  130. package/dist/commands/tenant/backup/restore/index.d.ts +1 -0
  131. package/dist/commands/tenant/backup/restore/index.js +1 -4
  132. package/dist/commands/tenant/cluster/create/index.d.ts +1 -0
  133. package/dist/commands/tenant/cluster/create/index.js +1 -3
  134. package/dist/commands/tenant/cluster/delete/index.d.ts +1 -0
  135. package/dist/commands/tenant/cluster/delete/index.js +1 -4
  136. package/dist/commands/tenant/cluster/edit/index.d.ts +1 -0
  137. package/dist/commands/tenant/cluster/edit/index.js +1 -4
  138. package/dist/commands/tenant/cluster/get/index.d.ts +1 -0
  139. package/dist/commands/tenant/cluster/get/index.js +1 -4
  140. package/dist/commands/tenant/cluster/license/get/index.d.ts +1 -0
  141. package/dist/commands/tenant/cluster/license/get/index.js +1 -3
  142. package/dist/commands/tenant/cluster/license/set/index.d.ts +1 -0
  143. package/dist/commands/tenant/cluster/license/set/index.js +1 -3
  144. package/dist/commands/tenant/cluster/list/index.d.ts +1 -0
  145. package/dist/commands/tenant/cluster/list/index.js +1 -4
  146. package/dist/commands/tenant/create/index.d.ts +1 -0
  147. package/dist/commands/tenant/create/index.js +1 -3
  148. package/dist/commands/tenant/delete/index.d.ts +1 -0
  149. package/dist/commands/tenant/delete/index.js +1 -4
  150. package/dist/commands/tenant/deploy_platform/index.d.ts +1 -0
  151. package/dist/commands/tenant/deploy_platform/index.js +1 -3
  152. package/dist/commands/tenant/deploy_release/index.d.ts +1 -0
  153. package/dist/commands/tenant/deploy_release/index.js +1 -4
  154. package/dist/commands/tenant/edit/index.d.ts +1 -0
  155. package/dist/commands/tenant/edit/index.js +1 -4
  156. package/dist/commands/tenant/env/delete/index.d.ts +1 -0
  157. package/dist/commands/tenant/env/delete/index.js +1 -4
  158. package/dist/commands/tenant/env/get/index.d.ts +1 -0
  159. package/dist/commands/tenant/env/get/index.js +1 -4
  160. package/dist/commands/tenant/env/get_all/index.d.ts +1 -0
  161. package/dist/commands/tenant/env/get_all/index.js +1 -3
  162. package/dist/commands/tenant/env/list/index.d.ts +1 -0
  163. package/dist/commands/tenant/env/list/index.js +1 -4
  164. package/dist/commands/tenant/env/set/index.d.ts +1 -0
  165. package/dist/commands/tenant/env/set/index.js +1 -4
  166. package/dist/commands/tenant/env/set_all/index.d.ts +1 -0
  167. package/dist/commands/tenant/env/set_all/index.js +1 -3
  168. package/dist/commands/tenant/get/index.d.ts +1 -0
  169. package/dist/commands/tenant/get/index.js +1 -4
  170. package/dist/commands/tenant/impersonate/index.d.ts +1 -0
  171. package/dist/commands/tenant/impersonate/index.js +1 -4
  172. package/dist/commands/tenant/license/get/index.d.ts +1 -0
  173. package/dist/commands/tenant/license/get/index.js +1 -3
  174. package/dist/commands/tenant/license/set/index.d.ts +1 -0
  175. package/dist/commands/tenant/license/set/index.js +1 -3
  176. package/dist/commands/tenant/list/index.d.ts +1 -0
  177. package/dist/commands/tenant/list/index.js +1 -4
  178. package/dist/commands/tenant/pull/index.d.ts +2 -3
  179. package/dist/commands/tenant/pull/index.js +20 -21
  180. package/dist/commands/tenant/push/index.d.ts +2 -22
  181. package/dist/commands/tenant/push/index.js +7 -225
  182. package/dist/commands/tenant/unit_test/list/index.d.ts +1 -0
  183. package/dist/commands/tenant/unit_test/list/index.js +2 -27
  184. package/dist/commands/tenant/unit_test/run/index.d.ts +1 -0
  185. package/dist/commands/tenant/unit_test/run/index.js +2 -27
  186. package/dist/commands/tenant/unit_test/run_all/index.d.ts +1 -0
  187. package/dist/commands/tenant/unit_test/run_all/index.js +2 -27
  188. package/dist/commands/tenant/workflow_test/list/index.d.ts +1 -0
  189. package/dist/commands/tenant/workflow_test/list/index.js +2 -27
  190. package/dist/commands/tenant/workflow_test/run/index.d.ts +1 -0
  191. package/dist/commands/tenant/workflow_test/run/index.js +2 -27
  192. package/dist/commands/tenant/workflow_test/run_all/index.d.ts +1 -0
  193. package/dist/commands/tenant/workflow_test/run_all/index.js +2 -27
  194. package/dist/commands/unit_test/list/index.d.ts +1 -0
  195. package/dist/commands/unit_test/list/index.js +1 -4
  196. package/dist/commands/unit_test/run/index.d.ts +1 -0
  197. package/dist/commands/unit_test/run/index.js +1 -4
  198. package/dist/commands/unit_test/run_all/index.d.ts +1 -0
  199. package/dist/commands/unit_test/run_all/index.js +1 -4
  200. package/dist/commands/update/index.d.ts +1 -0
  201. package/dist/commands/workflow_test/delete/index.d.ts +1 -0
  202. package/dist/commands/workflow_test/delete/index.js +1 -4
  203. package/dist/commands/workflow_test/get/index.d.ts +1 -0
  204. package/dist/commands/workflow_test/get/index.js +1 -4
  205. package/dist/commands/workflow_test/list/index.d.ts +1 -0
  206. package/dist/commands/workflow_test/list/index.js +1 -4
  207. package/dist/commands/workflow_test/run/index.d.ts +1 -0
  208. package/dist/commands/workflow_test/run/index.js +1 -4
  209. package/dist/commands/workflow_test/run_all/index.d.ts +1 -0
  210. package/dist/commands/workflow_test/run_all/index.js +1 -4
  211. package/dist/commands/workspace/create/index.d.ts +1 -0
  212. package/dist/commands/workspace/create/index.js +1 -4
  213. package/dist/commands/workspace/delete/index.d.ts +2 -6
  214. package/dist/commands/workspace/delete/index.js +17 -16
  215. package/dist/commands/workspace/edit/index.d.ts +2 -6
  216. package/dist/commands/workspace/edit/index.js +16 -20
  217. package/dist/commands/workspace/get/index.d.ts +2 -6
  218. package/dist/commands/workspace/get/index.js +14 -18
  219. package/dist/commands/workspace/git/pull/index.d.ts +2 -3
  220. package/dist/commands/workspace/git/pull/index.js +18 -17
  221. package/dist/commands/workspace/list/index.d.ts +1 -0
  222. package/dist/commands/workspace/list/index.js +1 -4
  223. package/dist/commands/workspace/pull/index.d.ts +2 -3
  224. package/dist/commands/workspace/pull/index.js +21 -24
  225. package/dist/commands/workspace/push/index.d.ts +7 -16
  226. package/dist/commands/workspace/push/index.js +85 -700
  227. package/dist/utils/multidoc-push.d.ts +63 -0
  228. package/dist/utils/multidoc-push.js +690 -0
  229. package/dist/utils/reference-checker.d.ts +57 -0
  230. package/dist/utils/reference-checker.js +232 -0
  231. package/oclif.manifest.json +3562 -2647
  232. package/package.json +1 -1
  233. package/dist/commands/sandbox/workflow_test/delete/index.d.ts +0 -17
  234. package/dist/commands/sandbox/workflow_test/delete/index.js +0 -59
  235. package/dist/commands/sandbox/workflow_test/get/index.d.ts +0 -17
  236. package/dist/commands/sandbox/workflow_test/get/index.js +0 -58
  237. package/dist/commands/tenant/workflow_test/delete/index.d.ts +0 -19
  238. package/dist/commands/tenant/workflow_test/delete/index.js +0 -110
  239. package/dist/commands/tenant/workflow_test/get/index.d.ts +0 -19
  240. package/dist/commands/tenant/workflow_test/get/index.js +0 -112
package/README.md CHANGED
@@ -25,7 +25,7 @@ npm install -g @xano/cli
25
25
 
26
26
  3. Pull a workspace to local files:
27
27
  ```bash
28
- xano workspace pull ./my-workspace
28
+ xano workspace pull
29
29
  ```
30
30
 
31
31
  ## Commands
@@ -92,70 +92,76 @@ xano profile delete myprofile --force
92
92
  xano workspace list
93
93
 
94
94
  # Get workspace details
95
- xano workspace get <workspace_id>
95
+ xano workspace get -w <workspace_id>
96
96
 
97
97
  # Create a workspace
98
98
  xano workspace create my-workspace
99
99
  xano workspace create my-workspace -d "My application workspace"
100
100
 
101
101
  # Edit a workspace
102
- xano workspace edit <workspace_id> --name "new-name" -d "Updated description"
103
- xano workspace edit <workspace_id> --swagger # Enable swagger docs
104
- xano workspace edit <workspace_id> --no-swagger # Disable swagger docs
105
- xano workspace edit <workspace_id> --require-token # Require token for docs
102
+ xano workspace edit -w <workspace_id> --name "new-name" -d "Updated description"
103
+ xano workspace edit -w <workspace_id> --swagger # Enable swagger docs
104
+ xano workspace edit -w <workspace_id> --no-swagger # Disable swagger docs
105
+ xano workspace edit -w <workspace_id> --require-token # Require token for docs
106
106
 
107
107
  # Delete a workspace (confirmation required)
108
- xano workspace delete <workspace_id>
109
- xano workspace delete <workspace_id> --force
110
-
111
- # Pull workspace to local files
112
- xano workspace pull ./my-workspace
113
- xano workspace pull ./my-workspace -b dev # Specific branch
114
- xano workspace pull ./my-workspace --env --records # Include env vars and table records
115
- xano workspace pull ./my-workspace --draft # Include draft changes
116
-
117
- # Push local files to workspace (only changed files by default)
118
- xano workspace push ./my-workspace
119
- xano workspace push ./my-workspace -b dev
120
- xano workspace push ./my-workspace --sync # Full push send all files, not just changed ones
121
- xano workspace push ./my-workspace --sync --delete # Full push + delete remote objects not included
122
- xano workspace push ./my-workspace --dry-run # Preview changes without pushing
123
- xano workspace push ./my-workspace --records # Include table records
124
- xano workspace push ./my-workspace --env # Include environment variables
125
- xano workspace push ./my-workspace --truncate # Truncate tables before import
126
- xano workspace push ./my-workspace --no-transaction # Disable database transaction wrapping
127
- xano workspace push ./my-workspace --no-guids # Skip writing GUIDs back to local files
128
- xano workspace push ./my-workspace --force # Skip preview and confirmation (for CI/CD)
129
- xano workspace push ./my-workspace -i "function/*" # Push only matching files
130
- xano workspace push ./my-workspace -e "table/*" # Push all files except tables
131
- xano workspace push ./my-workspace -i "function/*" -e "**/test*" # Include functions, exclude tests
132
-
133
- # Pull from a git repository to local files
134
- xano workspace git pull ./output -r https://github.com/owner/repo
135
- xano workspace git pull ./output -r https://github.com/owner/repo -b main
136
- xano workspace git pull ./output -r https://github.com/owner/repo/tree/main/path/to/dir
137
- xano workspace git pull ./output -r https://github.com/owner/repo/blob/main/file.xs
138
- xano workspace git pull ./output -r git@github.com:owner/repo.git
139
- xano workspace git pull ./output -r https://gitlab.com/owner/repo/-/tree/master/path
140
- xano workspace git pull ./output -r https://github.com/owner/private-repo -t ghp_xxx
141
- xano workspace git pull ./output -r https://github.com/owner/repo --path subdir
108
+ xano workspace delete -w <workspace_id>
109
+ xano workspace delete -w <workspace_id> --force
110
+
111
+ # Pull workspace to local files (defaults to current directory)
112
+ xano workspace pull
113
+ xano workspace pull -d ./my-workspace # Specify output directory
114
+ xano workspace pull -b dev # Specific branch
115
+ xano workspace pull --env --records # Include env vars and table records
116
+ xano workspace pull --draft # Include draft changes
117
+
118
+ # Push local files to workspace (defaults to current directory, only changed files)
119
+ xano workspace push
120
+ xano workspace push -d ./my-workspace # Push from a specific directory
121
+ xano workspace push -b dev
122
+ xano workspace push --sync # Full push send all files, not just changed ones
123
+ xano workspace push --sync --delete # Full push + delete remote objects not included
124
+ xano workspace push --dry-run # Preview changes without pushing
125
+ xano workspace push --records # Include table records
126
+ xano workspace push --env # Include environment variables
127
+ xano workspace push --truncate # Truncate tables before import
128
+ xano workspace push --no-transaction # Disable database transaction wrapping
129
+ xano workspace push --no-guids # Skip writing GUIDs back to local files
130
+ xano workspace push --force # Skip preview and confirmation (for CI/CD)
131
+ xano workspace push -i "function/*" # Push only matching files
132
+ xano workspace push -e "table/*" # Push all files except tables
133
+ xano workspace push -i "function/*" -e "**/test*" # Include functions, exclude tests
134
+
135
+ # Pull from a git repository to local files (defaults to current directory)
136
+ xano workspace git pull -r https://github.com/owner/repo
137
+ xano workspace git pull -d ./output -r https://github.com/owner/repo
138
+ xano workspace git pull -r https://github.com/owner/repo -b main
139
+ xano workspace git pull -r https://github.com/owner/repo/tree/main/path/to/dir
140
+ xano workspace git pull -r https://github.com/owner/repo/blob/main/file.xs
141
+ xano workspace git pull -r git@github.com:owner/repo.git
142
+ xano workspace git pull -r https://gitlab.com/owner/repo/-/tree/master/path
143
+ xano workspace git pull -r https://github.com/owner/private-repo -t ghp_xxx
144
+ xano workspace git pull -r https://github.com/owner/repo --path subdir
142
145
  ```
143
146
 
144
147
  ### Branches
145
148
 
146
149
  All branch commands use **branch labels** (e.g., `v1`, `dev`), not IDs.
147
150
 
151
+ The `v1` branch is the default branch and always exists. It cannot be created, edited, or deleted.
152
+
148
153
  ```bash
149
154
  # List branches
150
155
  xano branch list
156
+ xano branch list -w <workspace_id>
151
157
 
152
158
  # Get branch details
153
159
  xano branch get <branch_label>
154
160
 
155
161
  # Create a branch
156
- xano branch create --label dev
157
- xano branch create -l feature-auth -s dev -d "Auth feature"
158
- xano branch create -l staging --color "#ebc346"
162
+ xano branch create dev
163
+ xano branch create feature-auth -s dev -d "Auth feature"
164
+ xano branch create staging --color "#ebc346"
159
165
 
160
166
  # Edit a branch
161
167
  xano branch edit <branch_label> --label "new-label"
@@ -209,9 +215,9 @@ xano release list
209
215
  xano release get <release_name>
210
216
 
211
217
  # Create a release
212
- xano release create --name "v1.0" --branch main
213
- xano release create --name "v1.1-hotfix" --branch main --hotfix
214
- xano release create --name "v1.0" --branch main --table-ids 1,2,3
218
+ xano release create "v1.0" --branch main
219
+ xano release create "v1.1-hotfix" --branch main --hotfix
220
+ xano release create "v1.0" --branch main --table-ids 1,2,3
215
221
 
216
222
  # Edit a release
217
223
  xano release edit <release_name> --name "v1.0-final" -d "Updated description"
@@ -227,19 +233,22 @@ xano release import --file ./my-release.tar.gz
227
233
  xano release delete <release_name>
228
234
  xano release delete <release_name> --force
229
235
 
230
- # Pull release to local files
231
- xano release pull ./my-release -r v1.0
232
- xano release pull ./my-release -r v1.0 --env --records
236
+ # Pull release to local files (defaults to current directory)
237
+ xano release pull -r v1.0
238
+ xano release pull -d ./my-release -r v1.0
239
+ xano release pull -r v1.0 --env --records
233
240
 
234
- # Push local files as a new release
235
- xano release push ./my-release -n "v2.0"
236
- xano release push ./my-release -n "v2.0" --hotfix -d "Critical fix"
237
- xano release push ./my-release -n "v2.0" --no-records --no-env
241
+ # Push local files as a new release (defaults to current directory)
242
+ xano release push -n "v2.0"
243
+ xano release push -d ./my-release -n "v2.0"
244
+ xano release push -n "v2.0" --hotfix --description "Critical fix"
245
+ xano release push -n "v2.0" --no-records --no-env
238
246
 
239
- # Deploy a release to its workspace as a new branch
247
+ # Deploy a release to its workspace as a new branch (confirmation required)
240
248
  xano release deploy "v1.0"
249
+ xano release deploy "v1.0" --force
241
250
  xano release deploy "v1.0" --branch "restore-v1" --no-set_live
242
- xano release deploy "v1.0" -w 40 -o json
251
+ xano release deploy "v1.0" -w 40 -o json --force
243
252
  ```
244
253
 
245
254
  ### Platforms
@@ -334,17 +343,19 @@ xano tenant impersonate <tenant_name> -o json
334
343
  #### Pull / Push
335
344
 
336
345
  ```bash
337
- # Pull tenant to local files
338
- xano tenant pull ./my-tenant -t <tenant_name>
339
- xano tenant pull ./my-tenant -t <tenant_name> --env --records
340
- xano tenant pull ./my-tenant -t <tenant_name> --draft
341
-
342
- # Push local files to tenant
343
- xano tenant push ./my-tenant -t <tenant_name>
344
- xano tenant push ./my-tenant -t <tenant_name> --records # Include table records
345
- xano tenant push ./my-tenant -t <tenant_name> --env # Include environment variables
346
- xano tenant push ./my-tenant -t <tenant_name> --truncate
347
- xano tenant push ./my-tenant -t <tenant_name> --no-transaction # Disable transaction wrapping
346
+ # Pull tenant to local files (defaults to current directory)
347
+ xano tenant pull -t <tenant_name>
348
+ xano tenant pull -d ./my-tenant -t <tenant_name>
349
+ xano tenant pull -t <tenant_name> --env --records
350
+ xano tenant pull -t <tenant_name> --draft
351
+
352
+ # Push local files to tenant (defaults to current directory)
353
+ xano tenant push -t <tenant_name>
354
+ xano tenant push -d ./my-tenant -t <tenant_name>
355
+ xano tenant push -t <tenant_name> --records # Include table records
356
+ xano tenant push -t <tenant_name> --env # Include environment variables
357
+ xano tenant push -t <tenant_name> --truncate
358
+ xano tenant push -t <tenant_name> --no-transaction # Disable transaction wrapping
348
359
  ```
349
360
 
350
361
  #### Deployments
@@ -455,9 +466,27 @@ Manage your sandbox tenant. Each user has a single sandbox tenant that is auto-p
455
466
  xano sandbox get
456
467
  xano sandbox get -o json
457
468
 
458
- # Push/pull workspace data
459
- xano sandbox push ./my-workspace
460
- xano sandbox pull ./my-tenant
469
+ # Pull sandbox to local files (defaults to current directory)
470
+ xano sandbox pull
471
+ xano sandbox pull -d ./my-sandbox
472
+ xano sandbox pull --env --records
473
+
474
+ # Push local files to sandbox (defaults to current directory, only changed files)
475
+ xano sandbox push
476
+ xano sandbox push -d ./my-workspace # Push from a specific directory
477
+ xano sandbox push --sync # Full push — send all files
478
+ xano sandbox push --sync --delete # Full push + delete remote objects not included
479
+ xano sandbox push --dry-run # Preview changes without pushing
480
+ xano sandbox push --records --env # Include records and environment variables
481
+ xano sandbox push --truncate # Truncate tables before import
482
+ xano sandbox push --no-guids # Skip writing GUIDs back to local files
483
+ xano sandbox push --force # Skip preview and confirmation
484
+ xano sandbox push -i "function/*" # Push only matching files
485
+ xano sandbox push -e "table/*" # Push all files except tables
486
+ xano sandbox push --review # Push and open sandbox review in the browser
487
+
488
+ # Review (open in browser)
489
+ xano sandbox review
461
490
 
462
491
  # Impersonate (open in browser)
463
492
  xano sandbox impersonate
@@ -489,6 +518,7 @@ All commands support these options:
489
518
 
490
519
  | Flag | Description |
491
520
  |------|-------------|
521
+ | `-c, --config` | Path to credentials file (or set `XANO_CONFIG` env var). Default: `~/.xano/credentials.yaml` |
492
522
  | `-p, --profile` | Profile to use (or set `XANO_PROFILE` env var) |
493
523
  | `-w, --workspace` | Workspace ID (overrides profile default) |
494
524
  | `-o, --output` | Output format: `summary` (default) or `json` |
@@ -509,7 +539,18 @@ This will show:
509
539
 
510
540
  ## Configuration
511
541
 
512
- Profiles are stored in `~/.xano/credentials.yaml`:
542
+ Profiles are stored in `~/.xano/credentials.yaml` by default. You can use a different credentials file with:
543
+
544
+ ```bash
545
+ # Via flag
546
+ xano profile list -c /path/to/other-credentials.yaml
547
+
548
+ # Via environment variable
549
+ export XANO_CONFIG=/path/to/other-credentials.yaml
550
+ xano workspace list
551
+ ```
552
+
553
+ ### Credentials File Format
513
554
 
514
555
  ```yaml
515
556
  profiles:
@@ -25,12 +25,19 @@ export interface SandboxTenant {
25
25
  state?: string;
26
26
  xano_domain?: string;
27
27
  }
28
+ /**
29
+ * Resolve the credentials file path from flag, env var, or default.
30
+ * Checks (in order): explicit configPath arg, XANO_CONFIG env var, ~/.xano/credentials.yaml
31
+ */
32
+ export declare function resolveCredentialsPath(configPath?: string): string;
28
33
  export default abstract class BaseCommand extends Command {
29
34
  static baseFlags: {
35
+ config: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
30
36
  profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
31
37
  verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
32
38
  };
33
39
  static flags: {
40
+ config: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
34
41
  profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
35
42
  verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
36
43
  };
@@ -46,8 +53,11 @@ export default abstract class BaseCommand extends Command {
46
53
  protected getDefaultProfile(): string;
47
54
  protected getProfile(): string | undefined;
48
55
  /**
49
- * Load and parse the credentials file. Returns null if the file doesn't exist.
56
+ * Get the resolved credentials file path, respecting --config flag and XANO_CONFIG env var.
57
+ * Reads -c/--config from process.argv directly because oclif doesn't set this.flags
58
+ * from parsed results — the static flags property is the flag definition, not parsed values.
50
59
  */
60
+ protected getCredentialsPath(): string;
51
61
  protected loadCredentialsFile(): CredentialsFile | null;
52
62
  /**
53
63
  * Get or create the singleton sandbox environment for the authenticated user.
@@ -63,6 +73,11 @@ export default abstract class BaseCommand extends Command {
63
73
  profile: ProfileConfig;
64
74
  profileName: string;
65
75
  };
76
+ /**
77
+ * Parse an API error response and return a clean error message.
78
+ * Extracts the message from JSON responses and adds context for common errors.
79
+ */
80
+ protected parseApiError(response: Response, fallbackPrefix: string): Promise<string>;
66
81
  /**
67
82
  * Make an HTTP request with optional verbose logging.
68
83
  * Use this for all Metadata API calls to support the --verbose flag.
@@ -7,8 +7,25 @@ import { checkForUpdate } from './update-check.js';
7
7
  export function buildUserAgent(version) {
8
8
  return `xano-cli/${version} (${process.platform}; ${process.arch}) node/${process.version}`;
9
9
  }
10
+ /**
11
+ * Resolve the credentials file path from flag, env var, or default.
12
+ * Checks (in order): explicit configPath arg, XANO_CONFIG env var, ~/.xano/credentials.yaml
13
+ */
14
+ export function resolveCredentialsPath(configPath) {
15
+ const explicit = configPath || process.env.XANO_CONFIG;
16
+ if (explicit) {
17
+ return path.resolve(explicit);
18
+ }
19
+ return path.join(os.homedir(), '.xano', 'credentials.yaml');
20
+ }
10
21
  export default class BaseCommand extends Command {
11
22
  static baseFlags = {
23
+ config: Flags.string({
24
+ char: 'c',
25
+ description: 'Path to credentials file (default: ~/.xano/credentials.yaml)',
26
+ env: 'XANO_CONFIG',
27
+ required: false,
28
+ }),
12
29
  profile: Flags.string({
13
30
  char: 'p',
14
31
  description: 'Profile to use (uses default profile if not specified)',
@@ -88,11 +105,22 @@ export default class BaseCommand extends Command {
88
105
  return this.flags?.profile;
89
106
  }
90
107
  /**
91
- * Load and parse the credentials file. Returns null if the file doesn't exist.
108
+ * Get the resolved credentials file path, respecting --config flag and XANO_CONFIG env var.
109
+ * Reads -c/--config from process.argv directly because oclif doesn't set this.flags
110
+ * from parsed results — the static flags property is the flag definition, not parsed values.
92
111
  */
112
+ getCredentialsPath() {
113
+ const args = process.argv;
114
+ for (let i = 0; i < args.length; i++) {
115
+ if ((args[i] === '--config' || args[i] === '-c') && args[i + 1])
116
+ return resolveCredentialsPath(args[i + 1]);
117
+ if (args[i]?.startsWith('--config='))
118
+ return resolveCredentialsPath(args[i].slice('--config='.length));
119
+ }
120
+ return resolveCredentialsPath();
121
+ }
93
122
  loadCredentialsFile() {
94
- const configDir = path.join(os.homedir(), '.xano');
95
- const credentialsPath = path.join(configDir, 'credentials.yaml');
123
+ const credentialsPath = this.getCredentialsPath();
96
124
  if (!fs.existsSync(credentialsPath)) {
97
125
  return null;
98
126
  }
@@ -117,8 +145,8 @@ export default class BaseCommand extends Command {
117
145
  method: 'GET',
118
146
  }, verbose, profile.access_token);
119
147
  if (!response.ok) {
120
- const errorText = await response.text();
121
- this.error(`Failed to get sandbox environment: ${response.status} ${response.statusText}\n${errorText}`);
148
+ const message = await this.parseApiError(response, 'Failed to get sandbox environment');
149
+ this.error(message);
122
150
  }
123
151
  return (await response.json());
124
152
  }
@@ -140,6 +168,30 @@ export default class BaseCommand extends Command {
140
168
  }
141
169
  return { profile, profileName };
142
170
  }
171
+ /**
172
+ * Parse an API error response and return a clean error message.
173
+ * Extracts the message from JSON responses and adds context for common errors.
174
+ */
175
+ async parseApiError(response, fallbackPrefix) {
176
+ const errorText = await response.text();
177
+ let message = `${fallbackPrefix} (${response.status})`;
178
+ try {
179
+ const errorJson = JSON.parse(errorText);
180
+ if (errorJson.message) {
181
+ message = errorJson.message;
182
+ }
183
+ }
184
+ catch {
185
+ if (errorText) {
186
+ message += `\n${errorText}`;
187
+ }
188
+ }
189
+ // Provide guidance when sandbox access is denied (free plan restriction)
190
+ if (response.status === 500 && message === 'Access Denied.') {
191
+ message = 'Sandbox is not available on the Free plan. Upgrade your plan to use sandbox features.';
192
+ }
193
+ return message;
194
+ }
143
195
  /**
144
196
  * Make an HTTP request with optional verbose logging.
145
197
  * Use this for all Metadata API calls to support the --verbose flag.
@@ -3,6 +3,7 @@ export default class Auth extends Command {
3
3
  static description: string;
4
4
  static examples: string[];
5
5
  static flags: {
6
+ config: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
6
7
  insecure: import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
8
  origin: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
8
9
  };
@@ -4,10 +4,9 @@ import inquirer from 'inquirer';
4
4
  import * as yaml from 'js-yaml';
5
5
  import * as fs from 'node:fs';
6
6
  import * as http from 'node:http';
7
- import * as os from 'node:os';
8
- import { join } from 'node:path';
7
+ import { dirname } from 'node:path';
9
8
  import open from 'open';
10
- import { buildUserAgent } from '../../base-command.js';
9
+ import { buildUserAgent, resolveCredentialsPath } from '../../base-command.js';
11
10
  const AUTH_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes
12
11
  export default class Auth extends Command {
13
12
  static description = 'Authenticate with Xano via browser login';
@@ -23,6 +22,12 @@ Profile 'default' created successfully!`,
23
22
  Opening browser for Xano login at https://custom.xano.com...`,
24
23
  ];
25
24
  static flags = {
25
+ config: Flags.string({
26
+ char: 'c',
27
+ description: 'Path to credentials file (default: ~/.xano/credentials.yaml)',
28
+ env: 'XANO_CONFIG',
29
+ required: false,
30
+ }),
26
31
  insecure: Flags.boolean({
27
32
  char: 'k',
28
33
  default: false,
@@ -101,7 +106,7 @@ Opening browser for Xano login at https://custom.xano.com...`,
101
106
  instance_origin: instance.origin,
102
107
  name: profileName,
103
108
  workspace: workspace?.id,
104
- });
109
+ }, flags.config);
105
110
  this.log('');
106
111
  this.log(`Profile '${profileName}' created successfully!`);
107
112
  // Ensure clean exit (the open() call can keep the event loop alive)
@@ -206,12 +211,12 @@ Opening browser for Xano login at https://custom.xano.com...`,
206
211
  ]);
207
212
  return profileName.trim() || 'default';
208
213
  }
209
- async saveProfile(profile) {
210
- const configDir = join(os.homedir(), '.xano');
211
- const credentialsPath = join(configDir, 'credentials.yaml');
212
- // Ensure the .xano directory exists
213
- if (!fs.existsSync(configDir)) {
214
- fs.mkdirSync(configDir, { recursive: true });
214
+ async saveProfile(profile, configPath) {
215
+ const credentialsPath = resolveCredentialsPath(configPath);
216
+ const credDir = dirname(credentialsPath);
217
+ // Ensure the directory exists
218
+ if (!fs.existsSync(credDir)) {
219
+ fs.mkdirSync(credDir, { recursive: true });
215
220
  }
216
221
  // Read existing credentials file or create new structure
217
222
  let credentials = { profiles: {} };
@@ -1,14 +1,17 @@
1
1
  import BaseCommand from '../../../base-command.js';
2
2
  export default class BranchCreate extends BaseCommand {
3
3
  static description: string;
4
+ static args: {
5
+ label: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
6
+ };
4
7
  static examples: string[];
5
8
  static flags: {
6
9
  color: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
10
  description: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
8
- label: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
9
11
  output: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
10
12
  source: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
11
13
  workspace: import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
14
+ config: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
12
15
  profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
13
16
  verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
14
17
  };
@@ -1,22 +1,26 @@
1
- import { Flags } from '@oclif/core';
1
+ import { Args, Flags } from '@oclif/core';
2
2
  import * as yaml from 'js-yaml';
3
3
  import * as fs from 'node:fs';
4
- import * as os from 'node:os';
5
- import * as path from 'node:path';
6
4
  import BaseCommand from '../../../base-command.js';
7
5
  export default class BranchCreate extends BaseCommand {
8
6
  static description = 'Create a new branch by cloning from an existing branch';
7
+ static args = {
8
+ label: Args.string({
9
+ description: 'Label for the new branch',
10
+ required: true,
11
+ }),
12
+ };
9
13
  static examples = [
10
- `$ xano branch create --label dev
14
+ `$ xano branch create dev
11
15
  Created branch: dev
12
16
  Cloned from: v1
13
17
  `,
14
- `$ xano branch create -l feature-auth -s dev -d "Authentication feature"
18
+ `$ xano branch create feature-auth -s dev -d "Authentication feature"
15
19
  Created branch: feature-auth
16
20
  Cloned from: dev
17
21
  Description: Authentication feature
18
22
  `,
19
- `$ xano branch create --label staging --color "#ebc346" --output json
23
+ `$ xano branch create staging --color "#ebc346" --output json
20
24
  {
21
25
  "created_at": "2024-02-11T10:00:00Z",
22
26
  "label": "staging",
@@ -37,11 +41,6 @@ Created branch: feature-auth
37
41
  description: 'Description for the new branch',
38
42
  required: false,
39
43
  }),
40
- label: Flags.string({
41
- char: 'l',
42
- description: 'Label for the new branch',
43
- required: true,
44
- }),
45
44
  output: Flags.string({
46
45
  char: 'o',
47
46
  default: 'summary',
@@ -62,7 +61,7 @@ Created branch: feature-auth
62
61
  }),
63
62
  };
64
63
  async run() {
65
- const { flags } = await this.parse(BranchCreate);
64
+ const { args, flags } = await this.parse(BranchCreate);
66
65
  // Get profile name (default or from flag/env)
67
66
  const profileName = flags.profile || this.getDefaultProfile();
68
67
  // Load credentials
@@ -84,11 +83,15 @@ Created branch: feature-auth
84
83
  const workspaceId = flags.workspace || profile.workspace;
85
84
  if (!workspaceId) {
86
85
  this.error('No workspace ID provided. Either use --workspace flag or set one in your profile.\n' +
87
- 'Usage: xano branch create --label <label> [--workspace <workspace_id>]');
86
+ 'Usage: xano branch create <label> [--workspace <workspace_id>]');
87
+ }
88
+ // Validate reserved branch names
89
+ if (args.label.toLowerCase() === 'v1') {
90
+ this.error("Cannot create a branch named 'v1'. This is the default branch and always exists.");
88
91
  }
89
92
  // Build request body
90
93
  const body = {
91
- label: flags.label,
94
+ label: args.label,
92
95
  source_branch: flags.source,
93
96
  };
94
97
  if (flags.description) {
@@ -104,8 +107,8 @@ Created branch: feature-auth
104
107
  const response = await this.verboseFetch(apiUrl, {
105
108
  body: JSON.stringify(body),
106
109
  headers: {
107
- 'accept': 'application/json',
108
- 'Authorization': `Bearer ${profile.access_token}`,
110
+ accept: 'application/json',
111
+ Authorization: `Bearer ${profile.access_token}`,
109
112
  'Content-Type': 'application/json',
110
113
  },
111
114
  method: 'POST',
@@ -114,7 +117,7 @@ Created branch: feature-auth
114
117
  const errorText = await response.text();
115
118
  this.error(`API request failed with status ${response.status}: ${response.statusText}\n${errorText}`);
116
119
  }
117
- const branch = await response.json();
120
+ const branch = (await response.json());
118
121
  // Output results
119
122
  if (flags.output === 'json') {
120
123
  this.log(JSON.stringify(branch, null, 2));
@@ -141,12 +144,10 @@ Created branch: feature-auth
141
144
  }
142
145
  }
143
146
  loadCredentials() {
144
- const configDir = path.join(os.homedir(), '.xano');
145
- const credentialsPath = path.join(configDir, 'credentials.yaml');
147
+ const credentialsPath = this.getCredentialsPath();
146
148
  // Check if credentials file exists
147
149
  if (!fs.existsSync(credentialsPath)) {
148
- this.error(`Credentials file not found at ${credentialsPath}\n` +
149
- `Create a profile using 'xano profile create'`);
150
+ this.error(`Credentials file not found at ${credentialsPath}\n` + `Create a profile using 'xano profile create'`);
150
151
  }
151
152
  // Read credentials file
152
153
  try {
@@ -9,6 +9,7 @@ export default class BranchDelete extends BaseCommand {
9
9
  force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
10
  output: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
11
11
  workspace: import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
12
+ config: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
12
13
  profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
13
14
  verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
14
15
  };
@@ -1,8 +1,6 @@
1
1
  import { Args, Flags } from '@oclif/core';
2
2
  import * as yaml from 'js-yaml';
3
3
  import * as fs from 'node:fs';
4
- import * as os from 'node:os';
5
- import * as path from 'node:path';
6
4
  import BaseCommand from '../../../base-command.js';
7
5
  export default class BranchDelete extends BaseCommand {
8
6
  static args = {
@@ -133,8 +131,7 @@ Deleted branch: dev
133
131
  });
134
132
  }
135
133
  loadCredentials() {
136
- const configDir = path.join(os.homedir(), '.xano');
137
- const credentialsPath = path.join(configDir, 'credentials.yaml');
134
+ const credentialsPath = this.getCredentialsPath();
138
135
  // Check if credentials file exists
139
136
  if (!fs.existsSync(credentialsPath)) {
140
137
  this.error(`Credentials file not found at ${credentialsPath}\n` +
@@ -11,6 +11,7 @@ export default class BranchEdit extends BaseCommand {
11
11
  label: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
12
12
  output: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
13
13
  workspace: import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
14
+ config: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
14
15
  profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
15
16
  verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
16
17
  };
@@ -1,8 +1,6 @@
1
1
  import { Args, Flags } from '@oclif/core';
2
2
  import * as yaml from 'js-yaml';
3
3
  import * as fs from 'node:fs';
4
- import * as os from 'node:os';
5
- import * as path from 'node:path';
6
4
  import BaseCommand from '../../../base-command.js';
7
5
  export default class BranchEdit extends BaseCommand {
8
6
  static args = {
@@ -143,8 +141,7 @@ Updated branch: feature-authentication
143
141
  }
144
142
  }
145
143
  loadCredentials() {
146
- const configDir = path.join(os.homedir(), '.xano');
147
- const credentialsPath = path.join(configDir, 'credentials.yaml');
144
+ const credentialsPath = this.getCredentialsPath();
148
145
  // Check if credentials file exists
149
146
  if (!fs.existsSync(credentialsPath)) {
150
147
  this.error(`Credentials file not found at ${credentialsPath}\n` +