add tests for CLI
This commit is contained in:
94
cli/deno.lock
generated
94
cli/deno.lock
generated
@@ -1574,9 +1574,103 @@
|
||||
"https://deno.land/std@0.224.0/assert/unreachable.ts": "5ae3dbf63ef988615b93eb08d395dda771c96546565f9e521ed86f6510c29e19",
|
||||
"https://deno.land/std@0.224.0/cli/parse_args.ts": "5250832fb7c544d9111e8a41ad272c016f5a53f975ef84d5a9fe5fcb70566ece",
|
||||
"https://deno.land/std@0.224.0/fmt/colors.ts": "508563c0659dd7198ba4bbf87e97f654af3c34eb56ba790260f252ad8012e1c5",
|
||||
"https://deno.land/std@0.224.0/fs/_create_walk_entry.ts": "5d9d2aaec05bcf09a06748b1684224d33eba7a4de24cf4cf5599991ca6b5b412",
|
||||
"https://deno.land/std@0.224.0/fs/_get_file_info_type.ts": "da7bec18a7661dba360a1db475b826b18977582ce6fc9b25f3d4ee0403fe8cbd",
|
||||
"https://deno.land/std@0.224.0/fs/_is_same_path.ts": "709c95868345fea051c58b9e96af95cff94e6ae98dfcff2b66dee0c212c4221f",
|
||||
"https://deno.land/std@0.224.0/fs/_is_subdir.ts": "c68b309d46cc8568ed83c000f608a61bbdba0943b7524e7a30f9e450cf67eecd",
|
||||
"https://deno.land/std@0.224.0/fs/_to_path_string.ts": "29bfc9c6c112254961d75cbf6ba814d6de5349767818eb93090cecfa9665591e",
|
||||
"https://deno.land/std@0.224.0/fs/copy.ts": "7ab12a16adb65d155d4943c88081ca16ce3b0b5acada64c1ce93800653678039",
|
||||
"https://deno.land/std@0.224.0/fs/empty_dir.ts": "e400e96e1d2c8c558a5a1712063bd43939e00619c1d1cc29959babc6f1639418",
|
||||
"https://deno.land/std@0.224.0/fs/ensure_dir.ts": "51a6279016c65d2985f8803c848e2888e206d1b510686a509fa7cc34ce59d29f",
|
||||
"https://deno.land/std@0.224.0/fs/ensure_file.ts": "67608cf550529f3d4aa1f8b6b36bf817bdc40b14487bf8f60e61cbf68f507cf3",
|
||||
"https://deno.land/std@0.224.0/fs/ensure_link.ts": "5c98503ebfa9cc05e2f2efaa30e91e60b4dd5b43ebbda82f435c0a5c6e3ffa01",
|
||||
"https://deno.land/std@0.224.0/fs/ensure_symlink.ts": "cafe904cebacb9a761977d6dbf5e3af938be946a723bb394080b9a52714fafe4",
|
||||
"https://deno.land/std@0.224.0/fs/eol.ts": "18c4ac009d0318504c285879eb7f47942643f13619e0ff070a0edc59353306bd",
|
||||
"https://deno.land/std@0.224.0/fs/exists.ts": "3d38cb7dcbca3cf313be343a7b8af18a87bddb4b5ca1bd2314be12d06533b50f",
|
||||
"https://deno.land/std@0.224.0/fs/expand_glob.ts": "2e428d90acc6676b2aa7b5c78ef48f30641b13f1fe658e7976c9064fb4b05309",
|
||||
"https://deno.land/std@0.224.0/fs/mod.ts": "c25e6802cbf27f3050f60b26b00c2d8dba1cb7fcdafe34c66006a7473b7b34d4",
|
||||
"https://deno.land/std@0.224.0/fs/move.ts": "ca205d848908d7f217353bc5c623627b1333490b8b5d3ef4cab600a700c9bd8f",
|
||||
"https://deno.land/std@0.224.0/fs/walk.ts": "cddf87d2705c0163bff5d7767291f05b0f46ba10b8b28f227c3849cace08d303",
|
||||
"https://deno.land/std@0.224.0/internal/diff.ts": "6234a4b493ebe65dc67a18a0eb97ef683626a1166a1906232ce186ae9f65f4e6",
|
||||
"https://deno.land/std@0.224.0/internal/format.ts": "0a98ee226fd3d43450245b1844b47003419d34d210fa989900861c79820d21c2",
|
||||
"https://deno.land/std@0.224.0/internal/mod.ts": "534125398c8e7426183e12dc255bb635d94e06d0f93c60a297723abe69d3b22e",
|
||||
"https://deno.land/std@0.224.0/path/_common/assert_path.ts": "dbdd757a465b690b2cc72fc5fb7698c51507dec6bfafce4ca500c46b76ff7bd8",
|
||||
"https://deno.land/std@0.224.0/path/_common/basename.ts": "569744855bc8445f3a56087fd2aed56bdad39da971a8d92b138c9913aecc5fa2",
|
||||
"https://deno.land/std@0.224.0/path/_common/common.ts": "ef73c2860694775fe8ffcbcdd387f9f97c7a656febf0daa8c73b56f4d8a7bd4c",
|
||||
"https://deno.land/std@0.224.0/path/_common/constants.ts": "dc5f8057159f4b48cd304eb3027e42f1148cf4df1fb4240774d3492b5d12ac0c",
|
||||
"https://deno.land/std@0.224.0/path/_common/dirname.ts": "684df4aa71a04bbcc346c692c8485594fc8a90b9408dfbc26ff32cf3e0c98cc8",
|
||||
"https://deno.land/std@0.224.0/path/_common/format.ts": "92500e91ea5de21c97f5fe91e178bae62af524b72d5fcd246d6d60ae4bcada8b",
|
||||
"https://deno.land/std@0.224.0/path/_common/from_file_url.ts": "d672bdeebc11bf80e99bf266f886c70963107bdd31134c4e249eef51133ceccf",
|
||||
"https://deno.land/std@0.224.0/path/_common/glob_to_reg_exp.ts": "6cac16d5c2dc23af7d66348a7ce430e5de4e70b0eede074bdbcf4903f4374d8d",
|
||||
"https://deno.land/std@0.224.0/path/_common/normalize.ts": "684df4aa71a04bbcc346c692c8485594fc8a90b9408dfbc26ff32cf3e0c98cc8",
|
||||
"https://deno.land/std@0.224.0/path/_common/normalize_string.ts": "33edef773c2a8e242761f731adeb2bd6d683e9c69e4e3d0092985bede74f4ac3",
|
||||
"https://deno.land/std@0.224.0/path/_common/relative.ts": "faa2753d9b32320ed4ada0733261e3357c186e5705678d9dd08b97527deae607",
|
||||
"https://deno.land/std@0.224.0/path/_common/strip_trailing_separators.ts": "7024a93447efcdcfeaa9339a98fa63ef9d53de363f1fbe9858970f1bba02655a",
|
||||
"https://deno.land/std@0.224.0/path/_common/to_file_url.ts": "7f76adbc83ece1bba173e6e98a27c647712cab773d3f8cbe0398b74afc817883",
|
||||
"https://deno.land/std@0.224.0/path/_interface.ts": "8dfeb930ca4a772c458a8c7bbe1e33216fe91c253411338ad80c5b6fa93ddba0",
|
||||
"https://deno.land/std@0.224.0/path/_os.ts": "8fb9b90fb6b753bd8c77cfd8a33c2ff6c5f5bc185f50de8ca4ac6a05710b2c15",
|
||||
"https://deno.land/std@0.224.0/path/basename.ts": "7ee495c2d1ee516ffff48fb9a93267ba928b5a3486b550be73071bc14f8cc63e",
|
||||
"https://deno.land/std@0.224.0/path/common.ts": "03e52e22882402c986fe97ca3b5bb4263c2aa811c515ce84584b23bac4cc2643",
|
||||
"https://deno.land/std@0.224.0/path/constants.ts": "0c206169ca104938ede9da48ac952de288f23343304a1c3cb6ec7625e7325f36",
|
||||
"https://deno.land/std@0.224.0/path/dirname.ts": "85bd955bf31d62c9aafdd7ff561c4b5fb587d11a9a5a45e2b01aedffa4238a7c",
|
||||
"https://deno.land/std@0.224.0/path/extname.ts": "593303db8ae8c865cbd9ceec6e55d4b9ac5410c1e276bfd3131916591b954441",
|
||||
"https://deno.land/std@0.224.0/path/format.ts": "6ce1779b0980296cf2bc20d66436b12792102b831fd281ab9eb08fa8a3e6f6ac",
|
||||
"https://deno.land/std@0.224.0/path/from_file_url.ts": "911833ae4fd10a1c84f6271f36151ab785955849117dc48c6e43b929504ee069",
|
||||
"https://deno.land/std@0.224.0/path/glob_to_regexp.ts": "7f30f0a21439cadfdae1be1bf370880b415e676097fda584a63ce319053b5972",
|
||||
"https://deno.land/std@0.224.0/path/is_absolute.ts": "4791afc8bfd0c87f0526eaa616b0d16e7b3ab6a65b62942e50eac68de4ef67d7",
|
||||
"https://deno.land/std@0.224.0/path/is_glob.ts": "a65f6195d3058c3050ab905705891b412ff942a292bcbaa1a807a74439a14141",
|
||||
"https://deno.land/std@0.224.0/path/join.ts": "ae2ec5ca44c7e84a235fd532e4a0116bfb1f2368b394db1c4fb75e3c0f26a33a",
|
||||
"https://deno.land/std@0.224.0/path/join_globs.ts": "5b3bf248b93247194f94fa6947b612ab9d3abd571ca8386cf7789038545e54a0",
|
||||
"https://deno.land/std@0.224.0/path/mod.ts": "f6bd79cb08be0e604201bc9de41ac9248582699d1b2ee0ab6bc9190d472cf9cd",
|
||||
"https://deno.land/std@0.224.0/path/normalize.ts": "4155743ccceeed319b350c1e62e931600272fad8ad00c417b91df093867a8352",
|
||||
"https://deno.land/std@0.224.0/path/normalize_glob.ts": "cc89a77a7d3b1d01053b9dcd59462b75482b11e9068ae6c754b5cf5d794b374f",
|
||||
"https://deno.land/std@0.224.0/path/parse.ts": "77ad91dcb235a66c6f504df83087ce2a5471e67d79c402014f6e847389108d5a",
|
||||
"https://deno.land/std@0.224.0/path/posix/_util.ts": "1e3937da30f080bfc99fe45d7ed23c47dd8585c5e473b2d771380d3a6937cf9d",
|
||||
"https://deno.land/std@0.224.0/path/posix/basename.ts": "d2fa5fbbb1c5a3ab8b9326458a8d4ceac77580961b3739cd5bfd1d3541a3e5f0",
|
||||
"https://deno.land/std@0.224.0/path/posix/common.ts": "26f60ccc8b2cac3e1613000c23ac5a7d392715d479e5be413473a37903a2b5d4",
|
||||
"https://deno.land/std@0.224.0/path/posix/constants.ts": "93481efb98cdffa4c719c22a0182b994e5a6aed3047e1962f6c2c75b7592bef1",
|
||||
"https://deno.land/std@0.224.0/path/posix/dirname.ts": "76cd348ffe92345711409f88d4d8561d8645353ac215c8e9c80140069bf42f00",
|
||||
"https://deno.land/std@0.224.0/path/posix/extname.ts": "e398c1d9d1908d3756a7ed94199fcd169e79466dd88feffd2f47ce0abf9d61d2",
|
||||
"https://deno.land/std@0.224.0/path/posix/format.ts": "185e9ee2091a42dd39e2a3b8e4925370ee8407572cee1ae52838aed96310c5c1",
|
||||
"https://deno.land/std@0.224.0/path/posix/from_file_url.ts": "951aee3a2c46fd0ed488899d024c6352b59154c70552e90885ed0c2ab699bc40",
|
||||
"https://deno.land/std@0.224.0/path/posix/glob_to_regexp.ts": "76f012fcdb22c04b633f536c0b9644d100861bea36e9da56a94b9c589a742e8f",
|
||||
"https://deno.land/std@0.224.0/path/posix/is_absolute.ts": "cebe561ad0ae294f0ce0365a1879dcfca8abd872821519b4fcc8d8967f888ede",
|
||||
"https://deno.land/std@0.224.0/path/posix/is_glob.ts": "8a8b08c08bf731acf2c1232218f1f45a11131bc01de81e5f803450a5914434b9",
|
||||
"https://deno.land/std@0.224.0/path/posix/join.ts": "7fc2cb3716aa1b863e990baf30b101d768db479e70b7313b4866a088db016f63",
|
||||
"https://deno.land/std@0.224.0/path/posix/join_globs.ts": "a9475b44645feddceb484ee0498e456f4add112e181cb94042cdc6d47d1cdd25",
|
||||
"https://deno.land/std@0.224.0/path/posix/mod.ts": "2301fc1c54a28b349e20656f68a85f75befa0ee9b6cd75bfac3da5aca9c3f604",
|
||||
"https://deno.land/std@0.224.0/path/posix/normalize.ts": "baeb49816a8299f90a0237d214cef46f00ba3e95c0d2ceb74205a6a584b58a91",
|
||||
"https://deno.land/std@0.224.0/path/posix/normalize_glob.ts": "9c87a829b6c0f445d03b3ecadc14492e2864c3ebb966f4cea41e98326e4435c6",
|
||||
"https://deno.land/std@0.224.0/path/posix/parse.ts": "09dfad0cae530f93627202f28c1befa78ea6e751f92f478ca2cc3b56be2cbb6a",
|
||||
"https://deno.land/std@0.224.0/path/posix/relative.ts": "3907d6eda41f0ff723d336125a1ad4349112cd4d48f693859980314d5b9da31c",
|
||||
"https://deno.land/std@0.224.0/path/posix/resolve.ts": "08b699cfeee10cb6857ccab38fa4b2ec703b0ea33e8e69964f29d02a2d5257cf",
|
||||
"https://deno.land/std@0.224.0/path/posix/to_file_url.ts": "7aa752ba66a35049e0e4a4be5a0a31ac6b645257d2e031142abb1854de250aaf",
|
||||
"https://deno.land/std@0.224.0/path/posix/to_namespaced_path.ts": "28b216b3c76f892a4dca9734ff1cc0045d135532bfd9c435ae4858bfa5a2ebf0",
|
||||
"https://deno.land/std@0.224.0/path/relative.ts": "ab739d727180ed8727e34ed71d976912461d98e2b76de3d3de834c1066667add",
|
||||
"https://deno.land/std@0.224.0/path/resolve.ts": "a6f977bdb4272e79d8d0ed4333e3d71367cc3926acf15ac271f1d059c8494d8d",
|
||||
"https://deno.land/std@0.224.0/path/to_file_url.ts": "88f049b769bce411e2d2db5bd9e6fd9a185a5fbd6b9f5ad8f52bef517c4ece1b",
|
||||
"https://deno.land/std@0.224.0/path/to_namespaced_path.ts": "b706a4103b104cfadc09600a5f838c2ba94dbcdb642344557122dda444526e40",
|
||||
"https://deno.land/std@0.224.0/path/windows/_util.ts": "d5f47363e5293fced22c984550d5e70e98e266cc3f31769e1710511803d04808",
|
||||
"https://deno.land/std@0.224.0/path/windows/basename.ts": "6bbc57bac9df2cec43288c8c5334919418d784243a00bc10de67d392ab36d660",
|
||||
"https://deno.land/std@0.224.0/path/windows/common.ts": "26f60ccc8b2cac3e1613000c23ac5a7d392715d479e5be413473a37903a2b5d4",
|
||||
"https://deno.land/std@0.224.0/path/windows/constants.ts": "5afaac0a1f67b68b0a380a4ef391bf59feb55856aa8c60dfc01bd3b6abb813f5",
|
||||
"https://deno.land/std@0.224.0/path/windows/dirname.ts": "33e421be5a5558a1346a48e74c330b8e560be7424ed7684ea03c12c21b627bc9",
|
||||
"https://deno.land/std@0.224.0/path/windows/extname.ts": "165a61b00d781257fda1e9606a48c78b06815385e7d703232548dbfc95346bef",
|
||||
"https://deno.land/std@0.224.0/path/windows/format.ts": "bbb5ecf379305b472b1082cd2fdc010e44a0020030414974d6029be9ad52aeb6",
|
||||
"https://deno.land/std@0.224.0/path/windows/from_file_url.ts": "ced2d587b6dff18f963f269d745c4a599cf82b0c4007356bd957cb4cb52efc01",
|
||||
"https://deno.land/std@0.224.0/path/windows/glob_to_regexp.ts": "e45f1f89bf3fc36f94ab7b3b9d0026729829fabc486c77f414caebef3b7304f8",
|
||||
"https://deno.land/std@0.224.0/path/windows/is_absolute.ts": "4a8f6853f8598cf91a835f41abed42112cebab09478b072e4beb00ec81f8ca8a",
|
||||
"https://deno.land/std@0.224.0/path/windows/is_glob.ts": "8a8b08c08bf731acf2c1232218f1f45a11131bc01de81e5f803450a5914434b9",
|
||||
"https://deno.land/std@0.224.0/path/windows/join.ts": "8d03530ab89195185103b7da9dfc6327af13eabdcd44c7c63e42e27808f50ecf",
|
||||
"https://deno.land/std@0.224.0/path/windows/join_globs.ts": "a9475b44645feddceb484ee0498e456f4add112e181cb94042cdc6d47d1cdd25",
|
||||
"https://deno.land/std@0.224.0/path/windows/mod.ts": "2301fc1c54a28b349e20656f68a85f75befa0ee9b6cd75bfac3da5aca9c3f604",
|
||||
"https://deno.land/std@0.224.0/path/windows/normalize.ts": "78126170ab917f0ca355a9af9e65ad6bfa5be14d574c5fb09bb1920f52577780",
|
||||
"https://deno.land/std@0.224.0/path/windows/normalize_glob.ts": "9c87a829b6c0f445d03b3ecadc14492e2864c3ebb966f4cea41e98326e4435c6",
|
||||
"https://deno.land/std@0.224.0/path/windows/parse.ts": "08804327b0484d18ab4d6781742bf374976de662f8642e62a67e93346e759707",
|
||||
"https://deno.land/std@0.224.0/path/windows/relative.ts": "3e1abc7977ee6cc0db2730d1f9cb38be87b0ce4806759d271a70e4997fc638d7",
|
||||
"https://deno.land/std@0.224.0/path/windows/resolve.ts": "8dae1dadfed9d46ff46cc337c9525c0c7d959fb400a6308f34595c45bdca1972",
|
||||
"https://deno.land/std@0.224.0/path/windows/to_file_url.ts": "40e560ee4854fe5a3d4d12976cef2f4e8914125c81b11f1108e127934ced502e",
|
||||
"https://deno.land/std@0.224.0/path/windows/to_namespaced_path.ts": "4ffa4fb6fae321448d5fe810b3ca741d84df4d7897e61ee29be961a6aac89a4c",
|
||||
"https://deno.land/std@0.224.0/yaml/_dumper/dumper.ts": "08b595b40841a2e1c75303f5096392323b6baf8e9662430a91e3b36fbe175fe9",
|
||||
"https://deno.land/std@0.224.0/yaml/_dumper/dumper_state.ts": "9e29f700ea876ed230b43f11fa006fcb1a62eedc1e27d32baaeaf3210f19f1e7",
|
||||
"https://deno.land/std@0.224.0/yaml/_error.ts": "f38cdebdb69cde16903d9aa2f3b8a3dd9d13e5f7f3570bf662bfaca69fef669e",
|
||||
|
||||
@@ -4,7 +4,7 @@ import { colors, Input, log, setClient } from "../../../deps.ts";
|
||||
import { allWorkspaces, list, removeWorkspace } from "./workspace.ts";
|
||||
import * as wmill from "../../../gen/services.gen.ts";
|
||||
import { getCurrentGitBranch, getOriginalBranchForWorkspaceForks, isGitRepository } from "../../utils/git.ts";
|
||||
import { WM_FORK_PREFIX } from "../../main.ts";
|
||||
import { WM_FORK_PREFIX } from "../../core/constants.ts";
|
||||
import { tryResolveBranchWorkspace } from "../../core/context.ts";
|
||||
|
||||
// NOTE: This import will work after regenerating the API client
|
||||
|
||||
6
cli/src/core/constants.ts
Normal file
6
cli/src/core/constants.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* Shared constants used across the CLI.
|
||||
* This file should have minimal imports to avoid circular dependencies.
|
||||
*/
|
||||
|
||||
export const WM_FORK_PREFIX = "wm-fork";
|
||||
@@ -20,7 +20,7 @@ import {
|
||||
getWorkspaceIdForWorkspaceForkFromBranchName,
|
||||
isGitRepository,
|
||||
} from "../utils/git.ts";
|
||||
import { WM_FORK_PREFIX } from "../main.ts";
|
||||
import { WM_FORK_PREFIX } from "./constants.ts";
|
||||
|
||||
// Helper function to select from multiple matching profiles
|
||||
async function selectFromMultipleProfiles(
|
||||
|
||||
@@ -72,7 +72,8 @@ export {
|
||||
|
||||
export const VERSION = "1.600.1";
|
||||
|
||||
export const WM_FORK_PREFIX = "wm-fork";
|
||||
// Re-exported from constants.ts to maintain backwards compatibility
|
||||
export { WM_FORK_PREFIX } from "./core/constants.ts";
|
||||
|
||||
const command = new Command()
|
||||
.name("wmill")
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { log } from "../../deps.ts";
|
||||
import { execSync } from "node:child_process";
|
||||
import { WM_FORK_PREFIX } from "../main.ts";
|
||||
import { WM_FORK_PREFIX } from "../core/constants.ts";
|
||||
|
||||
export function getCurrentGitBranch(): string | null {
|
||||
try {
|
||||
|
||||
283
cli/src/utils/resource_folders.ts
Normal file
283
cli/src/utils/resource_folders.ts
Normal file
@@ -0,0 +1,283 @@
|
||||
/**
|
||||
* Utility module for handling resource folder naming conventions.
|
||||
*
|
||||
* This module centralizes the logic for detecting and manipulating paths
|
||||
* that contain resource folders (.flow, .app, .raw_app).
|
||||
*
|
||||
* The folder suffixes can be configured to use either dot-prefixed names
|
||||
* (.flow, .app, .raw_app) or dunder-prefixed names (__flow, __app, __raw_app).
|
||||
*/
|
||||
|
||||
import { SEP } from "../../deps.ts";
|
||||
|
||||
// Resource types that use folder-based storage
|
||||
export type FolderResourceType = "flow" | "app" | "raw_app";
|
||||
|
||||
// Configuration for folder suffixes - can be switched between dot and dunder prefixes
|
||||
// The default uses dot-prefixed names (.flow, .app, .raw_app)
|
||||
const FOLDER_SUFFIXES = {
|
||||
flow: ".flow",
|
||||
app: ".app",
|
||||
raw_app: ".raw_app",
|
||||
} as const;
|
||||
|
||||
// Metadata file names inside each folder type
|
||||
const METADATA_FILES = {
|
||||
flow: { yaml: "flow.yaml", json: "flow.json" },
|
||||
app: { yaml: "app.yaml", json: "app.json" },
|
||||
raw_app: { yaml: "raw_app.yaml", json: "raw_app.json" },
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* Get the folder suffix for a resource type (e.g., ".flow", ".app", ".raw_app")
|
||||
*/
|
||||
export function getFolderSuffix(type: FolderResourceType): string {
|
||||
return FOLDER_SUFFIXES[type];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the folder suffix with path separator (e.g., ".flow/", ".app/", ".raw_app/")
|
||||
*/
|
||||
export function getFolderSuffixWithSep(type: FolderResourceType): string {
|
||||
return FOLDER_SUFFIXES[type] + SEP;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the metadata file name for a resource type
|
||||
*/
|
||||
export function getMetadataFileName(
|
||||
type: FolderResourceType,
|
||||
format: "yaml" | "json"
|
||||
): string {
|
||||
return METADATA_FILES[type][format];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the full metadata file path suffix (e.g., ".flow/flow.yaml")
|
||||
*/
|
||||
export function getMetadataPathSuffix(
|
||||
type: FolderResourceType,
|
||||
format: "yaml" | "json"
|
||||
): string {
|
||||
return FOLDER_SUFFIXES[type] + "/" + METADATA_FILES[type][format];
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Path Detection Functions
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* Check if a path is inside a flow folder
|
||||
*/
|
||||
export function isFlowPath(p: string): boolean {
|
||||
return p.includes(FOLDER_SUFFIXES.flow + SEP);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a path is inside an app folder
|
||||
*/
|
||||
export function isAppPath(p: string): boolean {
|
||||
return p.includes(FOLDER_SUFFIXES.app + SEP);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a path is inside a raw_app folder
|
||||
*/
|
||||
export function isRawAppPath(p: string): boolean {
|
||||
return p.includes(FOLDER_SUFFIXES.raw_app + SEP);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a path is inside any folder-based resource (flow, app, or raw_app)
|
||||
*/
|
||||
export function isFolderResourcePath(p: string): boolean {
|
||||
return isFlowPath(p) || isAppPath(p) || isRawAppPath(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect the resource type from a path, if any
|
||||
*/
|
||||
export function detectFolderResourceType(
|
||||
p: string
|
||||
): FolderResourceType | null {
|
||||
if (isFlowPath(p)) return "flow";
|
||||
if (isAppPath(p)) return "app";
|
||||
if (isRawAppPath(p)) return "raw_app";
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a path is inside a raw app backend folder.
|
||||
* Matches patterns like: .../myApp.raw_app/backend/...
|
||||
*/
|
||||
export function isRawAppBackendPath(filePath: string): boolean {
|
||||
// Normalize path separators for consistent matching
|
||||
const normalizedPath = filePath.replaceAll(SEP, "/");
|
||||
// Check if path contains pattern: *.raw_app/backend/
|
||||
const pattern = new RegExp(
|
||||
`\\${FOLDER_SUFFIXES.raw_app.replace(".", "\\.")}/backend/`
|
||||
);
|
||||
return pattern.test(normalizedPath);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Path Manipulation Functions
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* Extract the resource name from a path (the part before the folder suffix)
|
||||
* e.g., "f/my_flow.flow/flow.yaml" -> "f/my_flow"
|
||||
*/
|
||||
export function extractResourceName(
|
||||
p: string,
|
||||
type: FolderResourceType
|
||||
): string | null {
|
||||
const suffix = FOLDER_SUFFIXES[type] + SEP;
|
||||
const index = p.indexOf(suffix);
|
||||
if (index === -1) return null;
|
||||
return p.substring(0, index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the folder path (resource name + folder suffix)
|
||||
* e.g., "f/my_flow.flow/flow.yaml" -> "f/my_flow.flow/"
|
||||
*/
|
||||
export function extractFolderPath(
|
||||
p: string,
|
||||
type: FolderResourceType
|
||||
): string | null {
|
||||
const suffix = FOLDER_SUFFIXES[type] + SEP;
|
||||
const index = p.indexOf(suffix);
|
||||
if (index === -1) return null;
|
||||
return p.substring(0, index) + suffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a folder path from a resource name
|
||||
* e.g., ("f/my_flow", "flow") -> "f/my_flow.flow"
|
||||
*/
|
||||
export function buildFolderPath(
|
||||
resourceName: string,
|
||||
type: FolderResourceType
|
||||
): string {
|
||||
return resourceName + FOLDER_SUFFIXES[type];
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a metadata file path from a resource name
|
||||
* e.g., ("f/my_flow", "flow", "yaml") -> "f/my_flow.flow/flow.yaml"
|
||||
*/
|
||||
export function buildMetadataPath(
|
||||
resourceName: string,
|
||||
type: FolderResourceType,
|
||||
format: "yaml" | "json"
|
||||
): string {
|
||||
return resourceName + FOLDER_SUFFIXES[type] + SEP + METADATA_FILES[type][format];
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Folder Validation Functions
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* Check if a directory name ends with a specific resource folder suffix
|
||||
* e.g., "my_app.raw_app" ends with ".raw_app"
|
||||
*/
|
||||
export function hasFolderSuffix(
|
||||
dirName: string,
|
||||
type: FolderResourceType
|
||||
): boolean {
|
||||
return dirName.endsWith(FOLDER_SUFFIXES[type]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that a directory name has the expected folder suffix
|
||||
* Returns an error message if invalid, null if valid
|
||||
*/
|
||||
export function validateFolderName(
|
||||
dirName: string,
|
||||
type: FolderResourceType
|
||||
): string | null {
|
||||
if (!hasFolderSuffix(dirName, type)) {
|
||||
return `'${dirName}' does not end with '${FOLDER_SUFFIXES[type]}'`;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the resource name from a folder name by removing the suffix
|
||||
* e.g., "my_app.raw_app" -> "my_app"
|
||||
*/
|
||||
export function extractNameFromFolder(
|
||||
folderName: string,
|
||||
type: FolderResourceType
|
||||
): string {
|
||||
const suffix = FOLDER_SUFFIXES[type];
|
||||
if (folderName.endsWith(suffix)) {
|
||||
return folderName.substring(0, folderName.length - suffix.length);
|
||||
}
|
||||
return folderName;
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Metadata File Detection Functions
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* Check if a path ends with a flow metadata file suffix
|
||||
*/
|
||||
export function isFlowMetadataFile(p: string): boolean {
|
||||
return p.endsWith(".flow.json") || p.endsWith(".flow.yaml");
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a path ends with an app metadata file suffix
|
||||
*/
|
||||
export function isAppMetadataFile(p: string): boolean {
|
||||
return p.endsWith(".app.json") || p.endsWith(".app.yaml");
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a path ends with a raw_app metadata file suffix
|
||||
*/
|
||||
export function isRawAppMetadataFile(p: string): boolean {
|
||||
return p.endsWith(".raw_app.json") || p.endsWith(".raw_app.yaml");
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a path ends with a specific raw_app metadata file
|
||||
* (inside the folder, e.g., ".raw_app/raw_app.yaml")
|
||||
*/
|
||||
export function isRawAppFolderMetadataFile(p: string): boolean {
|
||||
return (
|
||||
p.endsWith(getMetadataPathSuffix("raw_app", "yaml")) ||
|
||||
p.endsWith(getMetadataPathSuffix("raw_app", "json"))
|
||||
);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Sync-related Path Functions
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* Get the path suffix to remove when converting local path to API path
|
||||
* for delete operations
|
||||
*/
|
||||
export function getDeleteSuffix(
|
||||
type: FolderResourceType,
|
||||
format: "yaml" | "json"
|
||||
): string {
|
||||
return FOLDER_SUFFIXES[type] + "/" + METADATA_FILES[type][format];
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform a JSON path to the appropriate directory/file path for sync
|
||||
* e.g., "f/my_flow.flow.json" -> "f/my_flow.flow"
|
||||
*/
|
||||
export function transformJsonPathToDir(
|
||||
p: string,
|
||||
type: FolderResourceType
|
||||
): string {
|
||||
const suffix = METADATA_FILES[type].json;
|
||||
return p.replace(suffix, type);
|
||||
}
|
||||
1121
cli/test/sync_pull_push.test.ts
Normal file
1121
cli/test/sync_pull_push.test.ts
Normal file
File diff suppressed because it is too large
Load Diff
6
cli/workspace.ts
Normal file
6
cli/workspace.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
* Barrel file for workspace exports used by tests.
|
||||
* Re-exports key functions from the workspace command module.
|
||||
*/
|
||||
|
||||
export { addWorkspace, allWorkspaces, type Workspace } from "./src/commands/workspace/workspace.ts";
|
||||
Reference in New Issue
Block a user