windmill-cli 1.600.0 → 1.601.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.
- package/esm/gen/core/OpenAPI.js +1 -1
- package/esm/src/commands/app/app_metadata.js +9 -3
- package/esm/src/commands/app/dev.js +5 -4
- package/esm/src/commands/app/lint.js +3 -2
- package/esm/src/commands/app/new.js +2 -1
- package/esm/src/commands/dev/dev.js +5 -3
- package/esm/src/commands/flow/flow_metadata.js +2 -3
- package/esm/src/commands/init/init.js +1 -0
- package/esm/src/commands/script/script.js +20 -7
- package/esm/src/commands/sync/sync.js +22 -24
- package/esm/src/commands/workspace/fork.js +1 -1
- package/esm/src/core/conf.js +4 -0
- package/esm/src/core/constants.js +5 -0
- package/esm/src/core/context.js +1 -1
- package/esm/src/main.js +3 -2
- package/esm/src/types.js +10 -9
- package/esm/src/utils/git.js +1 -1
- package/esm/src/utils/resource_folders.js +329 -0
- package/esm/src/utils/utils.js +2 -1
- package/esm/windmill-utils-internal/src/inline-scripts/extractor.js +3 -2
- package/esm/windmill-utils-internal/src/path-utils/path-assigner.js +11 -3
- package/package.json +1 -1
- package/types/src/commands/app/app_metadata.d.ts.map +1 -1
- package/types/src/commands/app/dev.d.ts.map +1 -1
- package/types/src/commands/app/lint.d.ts.map +1 -1
- package/types/src/commands/app/new.d.ts.map +1 -1
- package/types/src/commands/dev/dev.d.ts.map +1 -1
- package/types/src/commands/flow/flow_metadata.d.ts.map +1 -1
- package/types/src/commands/init/init.d.ts.map +1 -1
- package/types/src/commands/script/script.d.ts +10 -0
- package/types/src/commands/script/script.d.ts.map +1 -1
- package/types/src/commands/sync/sync.d.ts.map +1 -1
- package/types/src/core/conf.d.ts +2 -1
- package/types/src/core/conf.d.ts.map +1 -1
- package/types/src/core/constants.d.ts +6 -0
- package/types/src/core/constants.d.ts.map +1 -0
- package/types/src/main.d.ts +2 -2
- package/types/src/main.d.ts.map +1 -1
- package/types/src/types.d.ts.map +1 -1
- package/types/src/utils/resource_folders.d.ts +160 -0
- package/types/src/utils/resource_folders.d.ts.map +1 -0
- package/types/src/utils/utils.d.ts.map +1 -1
- package/types/windmill-utils-internal/src/inline-scripts/extractor.d.ts +9 -1
- package/types/windmill-utils-internal/src/inline-scripts/extractor.d.ts.map +1 -1
- package/types/windmill-utils-internal/src/path-utils/path-assigner.d.ts +9 -1
- package/types/windmill-utils-internal/src/path-utils/path-assigner.d.ts.map +1 -1
package/esm/gen/core/OpenAPI.js
CHANGED
|
@@ -13,6 +13,7 @@ import { newPathAssigner, newRawAppPathAssigner, } from "../../../windmill-utils
|
|
|
13
13
|
import { mergeConfigWithConfigFile } from "../../core/conf.js";
|
|
14
14
|
import { resolveWorkspace } from "../../core/context.js";
|
|
15
15
|
import { requireLogin } from "../../core/auth.js";
|
|
16
|
+
import { getNonDottedPaths } from "../../utils/resource_folders.js";
|
|
16
17
|
const TOP_HASH = "__app_hash";
|
|
17
18
|
export const APP_BACKEND_FOLDER = "backend";
|
|
18
19
|
/**
|
|
@@ -26,8 +27,13 @@ async function generateAppHash(rawReqs, folder, rawApp, defaultTs) {
|
|
|
26
27
|
try {
|
|
27
28
|
const elems = await FSFSElement(runnablesFolder, [], true);
|
|
28
29
|
for await (const f of elems.getChildren()) {
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
// For normal apps, skip non-script files (metadata files like app.yaml)
|
|
31
|
+
// For raw apps, all files in backend/ are scripts
|
|
32
|
+
if (!rawApp) {
|
|
33
|
+
const isMetadataFile = f.path.endsWith("app.yaml") || f.path.endsWith("app.json");
|
|
34
|
+
if (isMetadataFile) {
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
31
37
|
}
|
|
32
38
|
if (exts.some((e) => f.path.endsWith(e))) {
|
|
33
39
|
// Embed lock into hash
|
|
@@ -252,7 +258,7 @@ async function updateRawAppRunnables(workspace, runnables, remotePath, appFolder
|
|
|
252
258
|
* but for the app.value structure instead of app.runnables
|
|
253
259
|
*/
|
|
254
260
|
async function updateAppInlineScripts(workspace, appValue, remotePath, appFolder, rawDeps, defaultTs = "bun") {
|
|
255
|
-
const pathAssigner = newPathAssigner(defaultTs);
|
|
261
|
+
const pathAssigner = newPathAssigner(defaultTs, { skipInlineScriptSuffix: getNonDottedPaths() });
|
|
256
262
|
const processor = async (inlineScript, context) => {
|
|
257
263
|
const language = inlineScript.language;
|
|
258
264
|
const content = inlineScript.content;
|
|
@@ -17,6 +17,7 @@ import { replaceInlineScripts } from "./app.js";
|
|
|
17
17
|
import { APP_BACKEND_FOLDER, inferRunnableSchemaFromFile, } from "./app_metadata.js";
|
|
18
18
|
import { loadRunnablesFromBackend } from "./raw_apps.js";
|
|
19
19
|
import { regenerateAgentDocs } from "./generate_agents.js";
|
|
20
|
+
import { hasFolderSuffix, getFolderSuffix } from "../../utils/resource_folders.js";
|
|
20
21
|
const DEFAULT_PORT = 4000;
|
|
21
22
|
const DEFAULT_HOST = "localhost";
|
|
22
23
|
// HTML template with live reload and SQL migration modal
|
|
@@ -277,17 +278,17 @@ async function dev(opts) {
|
|
|
277
278
|
// Validate that we're in a .raw_app folder
|
|
278
279
|
const cwd = process.cwd();
|
|
279
280
|
const currentDirName = path.basename(cwd);
|
|
280
|
-
if (!currentDirName
|
|
281
|
-
log.error(colors.red(`Error: The dev command must be run inside a
|
|
281
|
+
if (!hasFolderSuffix(currentDirName, "raw_app")) {
|
|
282
|
+
log.error(colors.red(`Error: The dev command must be run inside a ${getFolderSuffix("raw_app")} folder.\n` +
|
|
282
283
|
`Current directory: ${currentDirName}\n` +
|
|
283
|
-
`Please navigate to a folder ending with '
|
|
284
|
+
`Please navigate to a folder ending with '${getFolderSuffix("raw_app")}' before running this command.`));
|
|
284
285
|
dntShim.Deno.exit(1);
|
|
285
286
|
}
|
|
286
287
|
// Check for raw_app.yaml
|
|
287
288
|
const rawAppPath = path.join(cwd, "raw_app.yaml");
|
|
288
289
|
if (!fs.existsSync(rawAppPath)) {
|
|
289
290
|
log.error(colors.red(`Error: raw_app.yaml not found in current directory.\n` +
|
|
290
|
-
`The dev command must be run in a
|
|
291
|
+
`The dev command must be run in a ${getFolderSuffix("raw_app")} folder containing a raw_app.yaml file.`));
|
|
291
292
|
dntShim.Deno.exit(1);
|
|
292
293
|
}
|
|
293
294
|
// Resolve workspace and authenticate
|
|
@@ -7,6 +7,7 @@ import { Command, colors, log, yamlParseFile } from "../../../deps.js";
|
|
|
7
7
|
import { createBundle } from "./bundle.js";
|
|
8
8
|
import { APP_BACKEND_FOLDER } from "./app_metadata.js";
|
|
9
9
|
import { loadRunnablesFromBackend } from "./raw_apps.js";
|
|
10
|
+
import { hasFolderSuffix, getFolderSuffix } from "../../utils/resource_folders.js";
|
|
10
11
|
/**
|
|
11
12
|
* Validates the structure of raw_app.yaml
|
|
12
13
|
*/
|
|
@@ -81,8 +82,8 @@ async function lintRawApp(appDir, opts) {
|
|
|
81
82
|
const warnings = [];
|
|
82
83
|
// Check if we're in a .raw_app folder
|
|
83
84
|
const currentDirName = path.basename(appDir);
|
|
84
|
-
if (!currentDirName
|
|
85
|
-
errors.push(`Not a raw app folder: '${currentDirName}' does not end with '
|
|
85
|
+
if (!hasFolderSuffix(currentDirName, "raw_app")) {
|
|
86
|
+
errors.push(`Not a raw app folder: '${currentDirName}' does not end with '${getFolderSuffix("raw_app")}'`);
|
|
86
87
|
return { valid: false, errors, warnings };
|
|
87
88
|
}
|
|
88
89
|
// Check if raw_app.yaml exists
|
|
@@ -5,6 +5,7 @@ import { resolveWorkspace } from "../../core/context.js";
|
|
|
5
5
|
import { requireLogin } from "../../core/auth.js";
|
|
6
6
|
import * as wmill from "../../../gen/services.gen.js";
|
|
7
7
|
import path from "node:path";
|
|
8
|
+
import { buildFolderPath } from "../../utils/resource_folders.js";
|
|
8
9
|
// Framework templates - adapted from frontend/src/routes/(root)/(logged)/apps_raw/add/templates.ts
|
|
9
10
|
const reactIndex = `
|
|
10
11
|
import React from 'react'
|
|
@@ -393,7 +394,7 @@ CREATE SCHEMA IF NOT EXISTS ${schemaName};
|
|
|
393
394
|
log.info(colors.gray("You can configure datatables in Workspace Settings > Windmill Data Tables"));
|
|
394
395
|
}
|
|
395
396
|
// Create the directory structure - preserve full path (e.g., f/foobar/x/y becomes f/foobar/x/y.raw_app)
|
|
396
|
-
const folderName =
|
|
397
|
+
const folderName = buildFolderPath(appPath, "raw_app");
|
|
397
398
|
const appDir = path.join(dntShim.Deno.cwd(), folderName);
|
|
398
399
|
// Check if directory already exists
|
|
399
400
|
try {
|
|
@@ -9,6 +9,7 @@ import { exts, removeExtensionToPath } from "../script/script.js";
|
|
|
9
9
|
import { inferContentTypeFromFilePath } from "../../utils/script_common.js";
|
|
10
10
|
import { replaceInlineScripts } from "../../../windmill-utils-internal/src/inline-scripts/replacer.js";
|
|
11
11
|
import { parseMetadataFile } from "../../utils/metadata.js";
|
|
12
|
+
import { getFolderSuffixWithSep, getMetadataFileName, extractFolderPath, } from "../../utils/resource_folders.js";
|
|
12
13
|
const PORT = 3001;
|
|
13
14
|
async function dev(opts) {
|
|
14
15
|
const workspace = await resolveWorkspace(opts);
|
|
@@ -35,9 +36,10 @@ async function dev(opts) {
|
|
|
35
36
|
}, 100);
|
|
36
37
|
}
|
|
37
38
|
}
|
|
38
|
-
const
|
|
39
|
+
const flowFolderSuffix = getFolderSuffixWithSep("flow");
|
|
40
|
+
const flowMetadataFile = getMetadataFileName("flow", "yaml");
|
|
39
41
|
async function loadPaths(pathsToLoad) {
|
|
40
|
-
const paths = pathsToLoad.filter((path) => exts.some((ext) => path.endsWith(ext) || path.endsWith(
|
|
42
|
+
const paths = pathsToLoad.filter((path) => exts.some((ext) => path.endsWith(ext) || path.endsWith(flowFolderSuffix + flowMetadataFile)));
|
|
41
43
|
if (paths.length == 0) {
|
|
42
44
|
return;
|
|
43
45
|
}
|
|
@@ -46,7 +48,7 @@ async function dev(opts) {
|
|
|
46
48
|
const typ = getTypeStrFromPath(cpath);
|
|
47
49
|
log.info("Detected change in " + cpath + " (" + typ + ")");
|
|
48
50
|
if (typ == "flow") {
|
|
49
|
-
const localPath = cpath
|
|
51
|
+
const localPath = extractFolderPath(cpath, "flow");
|
|
50
52
|
const localFlow = (await yamlParseFile(localPath + "flow.yaml"));
|
|
51
53
|
await replaceInlineScripts(localFlow.value.modules, async (path) => await dntShim.Deno.readTextFile(localPath + path), log, localPath, SEP, undefined);
|
|
52
54
|
currentLastEdit = {
|
|
@@ -7,6 +7,7 @@ import { exts } from "../script/script.js";
|
|
|
7
7
|
import { FSFSElement } from "../sync/sync.js";
|
|
8
8
|
import { replaceInlineScripts } from "../../../windmill-utils-internal/src/inline-scripts/replacer.js";
|
|
9
9
|
import { workspaceDependenciesLanguages } from "../../utils/script_common.js";
|
|
10
|
+
import { extractNameFromFolder } from "../../utils/resource_folders.js";
|
|
10
11
|
const TOP_HASH = "__flow_hash";
|
|
11
12
|
async function generateFlowHash(rawWorkspaceDependencies, folder, defaultTs) {
|
|
12
13
|
const elems = await FSFSElement(path.join(dntShim.Deno.cwd(), folder), [], true);
|
|
@@ -23,9 +24,7 @@ export async function generateFlowLockInternal(folder, dryRun, workspace, opts,
|
|
|
23
24
|
if (folder.endsWith(SEP)) {
|
|
24
25
|
folder = folder.substring(0, folder.length - 1);
|
|
25
26
|
}
|
|
26
|
-
const remote_path = folder
|
|
27
|
-
.replaceAll(SEP, "/")
|
|
28
|
-
.substring(0, folder.length - ".flow".length);
|
|
27
|
+
const remote_path = extractNameFromFolder(folder.replaceAll(SEP, "/"), "flow");
|
|
29
28
|
if (!justUpdateMetadataLock && !noStaleMessage) {
|
|
30
29
|
log.info(`Generating lock for flow ${folder} at ${remote_path}`);
|
|
31
30
|
}
|
|
@@ -34,6 +34,7 @@ async function initAction(opts) {
|
|
|
34
34
|
else {
|
|
35
35
|
initialConfig.gitBranches = {};
|
|
36
36
|
}
|
|
37
|
+
initialConfig.nonDottedPaths = true;
|
|
37
38
|
await dntShim.Deno.writeTextFile("wmill.yaml", yamlStringify(initialConfig));
|
|
38
39
|
log.info(colors.green("wmill.yaml created with default settings"));
|
|
39
40
|
// Create lock file
|
|
@@ -17,15 +17,27 @@ import { mergeConfigWithConfigFile, readConfigFile, } from "../../core/conf.js";
|
|
|
17
17
|
import { listSyncCodebases } from "../../utils/codebase.js";
|
|
18
18
|
import fs from "node:fs";
|
|
19
19
|
import { execSync } from "node:child_process";
|
|
20
|
+
import { isRawAppBackendPath as isRawAppBackendPathInternal, isAppInlineScriptPath as isAppInlineScriptPathInternal, isFlowInlineScriptPath as isFlowInlineScriptPathInternal, isFlowPath, isAppPath, } from "../../utils/resource_folders.js";
|
|
20
21
|
/**
|
|
21
22
|
* Checks if a path is inside a raw app backend folder.
|
|
22
23
|
* Matches patterns like: .../myApp.raw_app/backend/...
|
|
23
24
|
*/
|
|
24
25
|
export function isRawAppBackendPath(filePath) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
return isRawAppBackendPathInternal(filePath);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Checks if a path is inside a normal app folder (inline script).
|
|
30
|
+
* Matches patterns like: .../myApp.app/... or .../myApp__app/...
|
|
31
|
+
*/
|
|
32
|
+
export function isAppInlineScriptPath(filePath) {
|
|
33
|
+
return isAppInlineScriptPathInternal(filePath);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Checks if a path is inside a flow folder (inline script).
|
|
37
|
+
* Matches patterns like: .../myFlow.flow/... or .../myFlow__flow/...
|
|
38
|
+
*/
|
|
39
|
+
export function isFlowInlineScriptPath(filePath) {
|
|
40
|
+
return isFlowInlineScriptPathInternal(filePath);
|
|
29
41
|
}
|
|
30
42
|
async function push(opts, filePath) {
|
|
31
43
|
opts = await mergeConfigWithConfigFile(opts);
|
|
@@ -89,7 +101,8 @@ export async function handleScriptMetadata(path, workspace, alreadySynced, messa
|
|
|
89
101
|
}
|
|
90
102
|
}
|
|
91
103
|
export async function handleFile(path, workspace, alreadySynced, message, opts, rawWorkspaceDependencies, codebases) {
|
|
92
|
-
if (!path
|
|
104
|
+
if (!isAppInlineScriptPath(path) &&
|
|
105
|
+
!isFlowInlineScriptPath(path) &&
|
|
93
106
|
!isRawAppBackendPath(path) &&
|
|
94
107
|
exts.some((exts) => path.endsWith(exts))) {
|
|
95
108
|
if (alreadySynced.includes(path)) {
|
|
@@ -736,8 +749,8 @@ async function generateMetadata(opts, scriptPath) {
|
|
|
736
749
|
const elems = await elementsToMap(await FSFSElement(dntShim.Deno.cwd(), codebases, false), (p, isD) => {
|
|
737
750
|
return ((!isD && !exts.some((ext) => p.endsWith(ext))) ||
|
|
738
751
|
ignore(p, isD) ||
|
|
739
|
-
p
|
|
740
|
-
p
|
|
752
|
+
isFlowPath(p) ||
|
|
753
|
+
isAppPath(p));
|
|
741
754
|
}, false, {});
|
|
742
755
|
let hasAny = false;
|
|
743
756
|
log.info("Generating metadata for all stale scripts:");
|
|
@@ -20,6 +20,7 @@ import { extractInlineScripts as extractInlineScriptsForFlows } from "../../../w
|
|
|
20
20
|
import { generateFlowLockInternal } from "../flow/flow_metadata.js";
|
|
21
21
|
import { isExecutionModeAnonymous } from "../app/app.js";
|
|
22
22
|
import { APP_BACKEND_FOLDER, generateAppLocksInternal, } from "../app/app_metadata.js";
|
|
23
|
+
import { isFlowPath, isAppPath, isRawAppPath, extractFolderPath, isFlowMetadataFile, isAppMetadataFile, isRawAppMetadataFile, isRawAppFolderMetadataFile, getDeleteSuffix, transformJsonPathToDir, getFolderSuffix, getNonDottedPaths, } from "../../utils/resource_folders.js";
|
|
23
24
|
// Merge CLI options with effective settings, preserving CLI flags as overrides
|
|
24
25
|
function mergeCliWithEffectiveOptions(cliOpts, effectiveOpts) {
|
|
25
26
|
// overlay CLI options on top (undefined cliOpts won't override effectiveOpts)
|
|
@@ -567,11 +568,11 @@ export function extractInlineScriptsForApps(key, rec, pathAssigner, toId, remove
|
|
|
567
568
|
}
|
|
568
569
|
function ZipFSElement(zip, useYaml, defaultTs, resourceTypeToFormatExtension, ignoreCodebaseChanges) {
|
|
569
570
|
async function _internal_file(p, f) {
|
|
570
|
-
const kind = p
|
|
571
|
+
const kind = isFlowMetadataFile(p)
|
|
571
572
|
? "flow"
|
|
572
|
-
: p
|
|
573
|
+
: isAppMetadataFile(p)
|
|
573
574
|
? "app"
|
|
574
|
-
: p
|
|
575
|
+
: isRawAppMetadataFile(p)
|
|
575
576
|
? "raw_app"
|
|
576
577
|
: p.endsWith(".script.json")
|
|
577
578
|
? "script"
|
|
@@ -583,13 +584,13 @@ function ZipFSElement(zip, useYaml, defaultTs, resourceTypeToFormatExtension, ig
|
|
|
583
584
|
const isJson = p.endsWith(".json");
|
|
584
585
|
function transformPath() {
|
|
585
586
|
if (kind == "flow") {
|
|
586
|
-
return p
|
|
587
|
+
return transformJsonPathToDir(p, "flow");
|
|
587
588
|
}
|
|
588
589
|
else if (kind == "app") {
|
|
589
|
-
return p
|
|
590
|
+
return transformJsonPathToDir(p, "app");
|
|
590
591
|
}
|
|
591
592
|
else if (kind == "raw_app") {
|
|
592
|
-
return p
|
|
593
|
+
return transformJsonPathToDir(p, "raw_app");
|
|
593
594
|
}
|
|
594
595
|
else if (kind == "dependencies") {
|
|
595
596
|
return p;
|
|
@@ -615,7 +616,8 @@ function ZipFSElement(zip, useYaml, defaultTs, resourceTypeToFormatExtension, ig
|
|
|
615
616
|
}
|
|
616
617
|
let inlineScripts;
|
|
617
618
|
try {
|
|
618
|
-
inlineScripts = extractInlineScriptsForFlows(flow.value.modules, {}, SEP, defaultTs
|
|
619
|
+
inlineScripts = extractInlineScriptsForFlows(flow.value.modules, {}, SEP, defaultTs, undefined, // pathAssigner - let it create one
|
|
620
|
+
{ skipInlineScriptSuffix: getNonDottedPaths() });
|
|
619
621
|
}
|
|
620
622
|
catch (error) {
|
|
621
623
|
log.error(`Failed to extract inline scripts for flow at path: ${p}`);
|
|
@@ -653,7 +655,7 @@ function ZipFSElement(zip, useYaml, defaultTs, resourceTypeToFormatExtension, ig
|
|
|
653
655
|
}
|
|
654
656
|
let inlineScripts;
|
|
655
657
|
try {
|
|
656
|
-
inlineScripts = extractInlineScriptsForApps(undefined, app?.["value"], newPathAssigner(defaultTs), (_, val) => val["name"], false);
|
|
658
|
+
inlineScripts = extractInlineScriptsForApps(undefined, app?.["value"], newPathAssigner(defaultTs, { skipInlineScriptSuffix: getNonDottedPaths() }), (_, val) => val["name"], false);
|
|
657
659
|
}
|
|
658
660
|
catch (error) {
|
|
659
661
|
log.error(`Failed to extract inline scripts for app at path: ${p}`);
|
|
@@ -1053,7 +1055,7 @@ export async function elementsToMap(els, ignore, json, skips, specificItems) {
|
|
|
1053
1055
|
}
|
|
1054
1056
|
}
|
|
1055
1057
|
if (isRawAppFile(path)) {
|
|
1056
|
-
const suffix = path.split("
|
|
1058
|
+
const suffix = path.split(getFolderSuffix("raw_app") + SEP).pop();
|
|
1057
1059
|
if (suffix?.startsWith("dist/") ||
|
|
1058
1060
|
suffix == "wmill.d.ts" ||
|
|
1059
1061
|
suffix == "package-lock.json" ||
|
|
@@ -1498,27 +1500,24 @@ export async function ignoreF(wmillconf) {
|
|
|
1498
1500
|
(!isDirectory && whitelist != undefined && !whitelist.approve(p))));
|
|
1499
1501
|
};
|
|
1500
1502
|
}
|
|
1501
|
-
const FLOW_EXT = ".flow" + SEP;
|
|
1502
|
-
const APP_EXT = ".app" + SEP;
|
|
1503
|
-
const RAW_APP_EXT = ".raw_app" + SEP;
|
|
1504
1503
|
// deno-lint-ignore no-inner-declarations
|
|
1505
1504
|
async function addToChangedIfNotExists(p, tracker) {
|
|
1506
1505
|
const isScript = exts.some((e) => p.endsWith(e));
|
|
1507
1506
|
if (isScript) {
|
|
1508
|
-
if (p
|
|
1509
|
-
const folder = p
|
|
1507
|
+
if (isFlowPath(p)) {
|
|
1508
|
+
const folder = extractFolderPath(p, "flow");
|
|
1510
1509
|
if (!tracker.flows.includes(folder)) {
|
|
1511
1510
|
tracker.flows.push(folder);
|
|
1512
1511
|
}
|
|
1513
1512
|
}
|
|
1514
|
-
else if (p
|
|
1515
|
-
const folder = p
|
|
1513
|
+
else if (isAppPath(p)) {
|
|
1514
|
+
const folder = extractFolderPath(p, "app");
|
|
1516
1515
|
if (!tracker.apps.includes(folder)) {
|
|
1517
1516
|
tracker.apps.push(folder);
|
|
1518
1517
|
}
|
|
1519
1518
|
}
|
|
1520
|
-
else if (p
|
|
1521
|
-
const folder = p
|
|
1519
|
+
else if (isRawAppPath(p)) {
|
|
1520
|
+
const folder = extractFolderPath(p, "raw_app");
|
|
1522
1521
|
if (!tracker.rawApps.includes(folder)) {
|
|
1523
1522
|
tracker.rawApps.push(folder);
|
|
1524
1523
|
}
|
|
@@ -2040,7 +2039,7 @@ export async function push(opts) {
|
|
|
2040
2039
|
const isRawApp = isRawAppFile(changes[0].path);
|
|
2041
2040
|
if (isRawApp) {
|
|
2042
2041
|
const deleteRawApp = changes.find((change) => change.name === "deleted" &&
|
|
2043
|
-
change.path
|
|
2042
|
+
isRawAppFolderMetadataFile(change.path));
|
|
2044
2043
|
if (deleteRawApp) {
|
|
2045
2044
|
changes = [deleteRawApp];
|
|
2046
2045
|
}
|
|
@@ -2178,21 +2177,20 @@ export async function push(opts) {
|
|
|
2178
2177
|
case "flow":
|
|
2179
2178
|
await wmill.deleteFlowByPath({
|
|
2180
2179
|
workspace: workspaceId,
|
|
2181
|
-
path: removeSuffix(target, "
|
|
2180
|
+
path: removeSuffix(target, getDeleteSuffix("flow", "json")),
|
|
2182
2181
|
});
|
|
2183
2182
|
break;
|
|
2184
2183
|
case "app":
|
|
2185
2184
|
await wmill.deleteApp({
|
|
2186
2185
|
workspace: workspaceId,
|
|
2187
|
-
path: removeSuffix(target, "
|
|
2186
|
+
path: removeSuffix(target, getDeleteSuffix("app", "json")),
|
|
2188
2187
|
});
|
|
2189
2188
|
break;
|
|
2190
2189
|
case "raw_app":
|
|
2191
|
-
if (target
|
|
2192
|
-
target.endsWith(".raw_app/raw_app.json")) {
|
|
2190
|
+
if (isRawAppFolderMetadataFile(target)) {
|
|
2193
2191
|
await wmill.deleteApp({
|
|
2194
2192
|
workspace: workspaceId,
|
|
2195
|
-
path: removeSuffix(target, "
|
|
2193
|
+
path: removeSuffix(target, getDeleteSuffix("raw_app", "json")),
|
|
2196
2194
|
});
|
|
2197
2195
|
}
|
|
2198
2196
|
break;
|
|
@@ -2,7 +2,7 @@ import { colors, Input, log, setClient } from "../../../deps.js";
|
|
|
2
2
|
import { allWorkspaces, list, removeWorkspace } from "./workspace.js";
|
|
3
3
|
import * as wmill from "../../../gen/services.gen.js";
|
|
4
4
|
import { getCurrentGitBranch, getOriginalBranchForWorkspaceForks, isGitRepository } from "../../utils/git.js";
|
|
5
|
-
import { WM_FORK_PREFIX } from "../../
|
|
5
|
+
import { WM_FORK_PREFIX } from "../../core/constants.js";
|
|
6
6
|
import { tryResolveBranchWorkspace } from "../../core/context.js";
|
|
7
7
|
// NOTE: This import will work after regenerating the API client
|
|
8
8
|
// Run ./gen_wm_client.sh to regenerate after backend changes
|
package/esm/src/core/conf.js
CHANGED
|
@@ -4,6 +4,7 @@ import { getCurrentGitBranch, getOriginalBranchForWorkspaceForks, isGitRepositor
|
|
|
4
4
|
import { join, dirname, resolve, relative } from "node:path";
|
|
5
5
|
import { existsSync } from "node:fs";
|
|
6
6
|
import { execSync } from "node:child_process";
|
|
7
|
+
import { setNonDottedPaths } from "../utils/resource_folders.js";
|
|
7
8
|
export let showDiffs = false;
|
|
8
9
|
export function setShowDiffs(value) {
|
|
9
10
|
showDiffs = value;
|
|
@@ -143,6 +144,8 @@ export async function readConfigFile() {
|
|
|
143
144
|
if (conf?.defaultTs == undefined) {
|
|
144
145
|
log.warn("No defaultTs defined in your wmill.yaml. Using 'bun' as default.");
|
|
145
146
|
}
|
|
147
|
+
// Initialize global nonDottedPaths setting from config
|
|
148
|
+
setNonDottedPaths(conf?.nonDottedPaths ?? false);
|
|
146
149
|
return typeof conf == "object" ? conf : {};
|
|
147
150
|
}
|
|
148
151
|
catch (e) {
|
|
@@ -191,6 +194,7 @@ export const DEFAULT_SYNC_OPTIONS = {
|
|
|
191
194
|
includeSettings: false,
|
|
192
195
|
includeKey: false,
|
|
193
196
|
skipWorkspaceDependencies: false,
|
|
197
|
+
nonDottedPaths: false,
|
|
194
198
|
};
|
|
195
199
|
export async function mergeConfigWithConfigFile(opts) {
|
|
196
200
|
const configFile = await readConfigFile();
|
package/esm/src/core/context.js
CHANGED
|
@@ -7,7 +7,7 @@ import { getActiveWorkspace, getWorkspaceByName, allWorkspaces, addWorkspace, }
|
|
|
7
7
|
import { getLastUsedProfile, setLastUsedProfile } from "./branch-profiles.js";
|
|
8
8
|
import { readConfigFile } from "./conf.js";
|
|
9
9
|
import { getCurrentGitBranch, getOriginalBranchForWorkspaceForks, getWorkspaceIdForWorkspaceForkFromBranchName, isGitRepository, } from "../utils/git.js";
|
|
10
|
-
import { WM_FORK_PREFIX } from "
|
|
10
|
+
import { WM_FORK_PREFIX } from "./constants.js";
|
|
11
11
|
// Helper function to select from multiple matching profiles
|
|
12
12
|
async function selectFromMultipleProfiles(profiles, baseUrl, workspaceId, context, configDir) {
|
|
13
13
|
if (profiles.length === 1) {
|
package/esm/src/main.js
CHANGED
|
@@ -40,8 +40,9 @@ export { flow, app, script, workspace, resource, resourceType, user, variable, h
|
|
|
40
40
|
// console.error(JSON.stringify(event.error, null, 4));
|
|
41
41
|
// }
|
|
42
42
|
// });
|
|
43
|
-
export const VERSION = "1.
|
|
44
|
-
|
|
43
|
+
export const VERSION = "1.601.0";
|
|
44
|
+
// Re-exported from constants.ts to maintain backwards compatibility
|
|
45
|
+
export { WM_FORK_PREFIX } from "./core/constants.js";
|
|
45
46
|
const command = new Command()
|
|
46
47
|
.name("wmill")
|
|
47
48
|
.action(() => log.info(`Welcome to Windmill CLI ${VERSION}. Use -h for help.`))
|
package/esm/src/types.js
CHANGED
|
@@ -17,6 +17,7 @@ import { pushWorkspaceDependencies } from "./commands/dependencies/dependencies.
|
|
|
17
17
|
import { pushWorkspaceSettings, pushWorkspaceKey } from "./core/settings.js";
|
|
18
18
|
import { pushTrigger } from "./commands/trigger/trigger.js";
|
|
19
19
|
import { pushRawApp } from "./commands/app/raw_apps.js";
|
|
20
|
+
import { isFlowPath, isAppPath, isRawAppPath, extractResourceName, buildFolderPath, } from "./utils/resource_folders.js";
|
|
20
21
|
export const TRIGGER_TYPES = [
|
|
21
22
|
"http",
|
|
22
23
|
"websocket",
|
|
@@ -93,12 +94,12 @@ export function showConflict(path, local, remote) {
|
|
|
93
94
|
export async function pushObj(workspace, p, befObj, newObj, plainSecrets, alreadySynced, message, originalLocalPath) {
|
|
94
95
|
const typeEnding = getTypeStrFromPath(p);
|
|
95
96
|
if (typeEnding === "app") {
|
|
96
|
-
const appName = p
|
|
97
|
-
await pushApp(workspace, appName, appName
|
|
97
|
+
const appName = extractResourceName(p, "app");
|
|
98
|
+
await pushApp(workspace, appName, buildFolderPath(appName, "app"), message);
|
|
98
99
|
}
|
|
99
100
|
else if (typeEnding === "raw_app") {
|
|
100
|
-
const rawAppName = p
|
|
101
|
-
await pushRawApp(workspace, rawAppName, rawAppName
|
|
101
|
+
const rawAppName = extractResourceName(p, "raw_app");
|
|
102
|
+
await pushRawApp(workspace, rawAppName, buildFolderPath(rawAppName, "raw_app"), message);
|
|
102
103
|
}
|
|
103
104
|
else if (typeEnding === "folder") {
|
|
104
105
|
await pushFolder(workspace, p, befObj, newObj);
|
|
@@ -107,8 +108,8 @@ export async function pushObj(workspace, p, befObj, newObj, plainSecrets, alread
|
|
|
107
108
|
await pushVariable(workspace, p, befObj, newObj, plainSecrets);
|
|
108
109
|
}
|
|
109
110
|
else if (typeEnding === "flow") {
|
|
110
|
-
const flowName = p
|
|
111
|
-
await pushFlow(workspace, flowName, flowName
|
|
111
|
+
const flowName = extractResourceName(p, "flow");
|
|
112
|
+
await pushFlow(workspace, flowName, buildFolderPath(flowName, "flow"), message);
|
|
112
113
|
}
|
|
113
114
|
else if (typeEnding === "resource") {
|
|
114
115
|
if (!alreadySynced.includes(p)) {
|
|
@@ -189,13 +190,13 @@ export function parseFromFile(p) {
|
|
|
189
190
|
}
|
|
190
191
|
}
|
|
191
192
|
export function getTypeStrFromPath(p) {
|
|
192
|
-
if (p
|
|
193
|
+
if (isFlowPath(p)) {
|
|
193
194
|
return "flow";
|
|
194
195
|
}
|
|
195
|
-
if (p
|
|
196
|
+
if (isAppPath(p)) {
|
|
196
197
|
return "app";
|
|
197
198
|
}
|
|
198
|
-
if (p
|
|
199
|
+
if (isRawAppPath(p)) {
|
|
199
200
|
return "raw_app";
|
|
200
201
|
}
|
|
201
202
|
if (p.startsWith("dependencies" + SEP)) {
|
package/esm/src/utils/git.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { log } from "../../deps.js";
|
|
2
2
|
import { execSync } from "node:child_process";
|
|
3
|
-
import { WM_FORK_PREFIX } from "../
|
|
3
|
+
import { WM_FORK_PREFIX } from "../core/constants.js";
|
|
4
4
|
export function getCurrentGitBranch() {
|
|
5
5
|
try {
|
|
6
6
|
const result = execSync("git rev-parse --abbrev-ref HEAD", {
|