mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-10-25 08:03:45 +00:00
chore: bump windmill-utils-internal to 1.8.3 and drop its workarounds (#11942)
* chore: bump windmill-utils-internal to 1.8.3 and drop frontend workarounds * chore: resolve windmill-utils-internal 1.8.3 in the frontend lockfile
This commit is contained in:
+2
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "windmill-utils-internal",
|
||||
"version": "1.7.0",
|
||||
"version": "1.8.3",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "windmill-utils-internal",
|
||||
"version": "1.7.0",
|
||||
"version": "1.8.3",
|
||||
"license": "Apache 2.0",
|
||||
"devDependencies": {
|
||||
"@types/node": "^24.2.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "windmill-utils-internal",
|
||||
"version": "1.8.2",
|
||||
"version": "1.8.3",
|
||||
"description": "Internal utility functions for Windmill",
|
||||
"main": "dist/cjs/index.js",
|
||||
"module": "dist/esm/index.js",
|
||||
|
||||
@@ -926,7 +926,11 @@ export async function getItemValue(
|
||||
path,
|
||||
decryptSecret: true,
|
||||
});
|
||||
return variable.value;
|
||||
return {
|
||||
value: variable.value,
|
||||
is_secret: variable.is_secret,
|
||||
description: variable.description,
|
||||
};
|
||||
} else if (kind === "resource") {
|
||||
const resource = await provider.getResource({ workspace, path });
|
||||
// Each workspace resolves its own agent identity, which a deploy never copies.
|
||||
|
||||
@@ -190,7 +190,7 @@ export async function replacePathScriptsWithLocal(
|
||||
}
|
||||
const localScript = await scriptReader(toolValue.path);
|
||||
if (localScript) {
|
||||
(tool as AiAgent["tools"][number]).value = {
|
||||
(tool as NonNullable<AiAgent["tools"]>[number]).value = {
|
||||
tool_type: "flowmodule",
|
||||
type: "rawscript",
|
||||
content: localScript.content,
|
||||
|
||||
@@ -5,7 +5,7 @@ const INLINE_SCRIPT_PREFIX = "inline_script";
|
||||
/**
|
||||
* Union type of all supported programming languages in Windmill
|
||||
*/
|
||||
export type SupportedLanguage = RawScript["language"] | "frontend" | "bunnative" | "oracledb" | "rust" | "csharp" | "nu" | "ansible" | "java" | "duckdb";
|
||||
export type SupportedLanguage = RawScript["language"] | "frontend" | "bunnative" | "oracledb" | "rust" | "csharp" | "nu" | "ansible" | "java" | "duckdb" | "dbt";
|
||||
|
||||
/**
|
||||
* Mapping of supported languages to their file extensions
|
||||
|
||||
Generated
+4
-4
@@ -110,7 +110,7 @@
|
||||
"windmill-parser-wasm-wac": "1.830.0",
|
||||
"windmill-parser-wasm-yaml": "1.770.0",
|
||||
"windmill-sql-datatype-parser-wasm": "1.512.0",
|
||||
"windmill-utils-internal": "1.8.2",
|
||||
"windmill-utils-internal": "1.8.3",
|
||||
"xterm": "^5.3.0",
|
||||
"xterm-readline": "^1.1.2",
|
||||
"y-monaco": "^0.1.4",
|
||||
@@ -14719,9 +14719,9 @@
|
||||
"integrity": "sha512-uHNL8F72/Tf96xF3hOHnPDjkEyqXw7fNjcPJiUhth9sTQkcwUIoJMOdwm8/cs+j9kKVRJ4tgNYMHEBLylazp6g=="
|
||||
},
|
||||
"node_modules/windmill-utils-internal": {
|
||||
"version": "1.8.2",
|
||||
"resolved": "https://registry.npmjs.org/windmill-utils-internal/-/windmill-utils-internal-1.8.2.tgz",
|
||||
"integrity": "sha512-Otdn4iCE0QiOtMKPdHX5I89oECfZa3vmO2jdLdSETf7MBSv/gw9gvQm3oUQ29ymIHXLeuhQk/ebPD+WYolQJEA==",
|
||||
"version": "1.8.3",
|
||||
"resolved": "https://registry.npmjs.org/windmill-utils-internal/-/windmill-utils-internal-1.8.3.tgz",
|
||||
"integrity": "sha512-Lp8fVM/uHUvO6q01rIODIR46hTQ9D9R9BEiKoZHQqw9NJoy1OxhcsvX4usBbkXff/GbHlkWiQfZXCOn0ozJeKQ==",
|
||||
"license": "Apache 2.0"
|
||||
},
|
||||
"node_modules/word-wrap": {
|
||||
|
||||
@@ -177,7 +177,7 @@
|
||||
"windmill-parser-wasm-wac": "1.830.0",
|
||||
"windmill-parser-wasm-yaml": "1.770.0",
|
||||
"windmill-sql-datatype-parser-wasm": "1.512.0",
|
||||
"windmill-utils-internal": "1.8.2",
|
||||
"windmill-utils-internal": "1.8.3",
|
||||
"xterm": "^5.3.0",
|
||||
"xterm-readline": "^1.1.2",
|
||||
"y-monaco": "^0.1.4",
|
||||
|
||||
@@ -32,8 +32,8 @@ vi.mock('$lib/gen', async (importOriginal) => ({
|
||||
}
|
||||
}))
|
||||
|
||||
// The deploy runs the published shared package, whose variable body has no `labels`: this
|
||||
// pins that the adapter still carries them until a version that does is installed.
|
||||
// The variable body is built by the installed shared package: this pins that a deploy from the
|
||||
// app sends the source's labels on create and on update.
|
||||
describe('deploying a variable to another workspace', () => {
|
||||
it('carries its labels on create and on update', async () => {
|
||||
for (const workspaceTo of ['lacks-it', 'has-it']) {
|
||||
|
||||
@@ -186,30 +186,13 @@ export type AppIdentity = { email: string; permissionedAs: string }
|
||||
export type DeployConflict = { hit: boolean }
|
||||
|
||||
/**
|
||||
* `deployItem` overrides only the email half of the identity, while the body it builds
|
||||
* spreads the *source* item — which carries the source workspace's permissioned_as, valid
|
||||
* nowhere else since usernames are per-workspace. The key is therefore always overwritten:
|
||||
* with the picked user's principal for a custom choice, and cleared otherwise so the
|
||||
* backend derives the target's own from the email it is given. The shared `deployItem`
|
||||
* does the same, but this app consumes the published package, so the rewrite has to exist
|
||||
* on both sides until that version ships.
|
||||
*
|
||||
* An app carries both halves inside its `policy` instead, so it needs both stamped here:
|
||||
* the published package leaves the policy untouched, and a source principal beside a
|
||||
* target address is rejected as a pair naming two different accounts.
|
||||
*
|
||||
* A group kept as the target identity travels as its synthetic `group-*@windmill.dev`
|
||||
* address, which an admin-created account holding it would win on the backend: known and
|
||||
* accepted, see `users::permissioned_as_from_email`.
|
||||
*
|
||||
* An agent carries its principal inside its resource value, and is handed the chosen one as a
|
||||
* principal, as a trigger is. Every read here drops the source's, so a diff never shows it and
|
||||
* the published `deployItem` copies none; the write then stamps the chosen one, or none, which
|
||||
* leaves the backend to make it the deployer's.
|
||||
* `deployItem` takes the identity only as an email and clears the source workspace's
|
||||
* principal, leaving the backend to derive the target's own from that email. When the user
|
||||
* picked a specific user, their principal is known here, so it is stamped on the body: on a
|
||||
* flow or script directly, and inside the `policy` for an app, which holds both halves.
|
||||
*/
|
||||
function makeProvider(
|
||||
onBehalfOfPrincipal?: string,
|
||||
onBehalfOf?: string,
|
||||
/**
|
||||
* Refuse the writes the shared `deployItem` reaches for only when the item already exists in
|
||||
* the target, turning its silent switch to an update into a failure the caller can act on.
|
||||
@@ -219,48 +202,16 @@ function makeProvider(
|
||||
*/
|
||||
conflict?: DeployConflict
|
||||
): DeployProvider {
|
||||
const withPermissionedAs = <T extends Record<string, any>>(requestBody: T): T => ({
|
||||
...requestBody,
|
||||
on_behalf_of: onBehalfOfPrincipal
|
||||
})
|
||||
const withPermissionedAs = <T extends Record<string, any>>(requestBody: T): T =>
|
||||
onBehalfOfPrincipal ? { ...requestBody, on_behalf_of: onBehalfOfPrincipal } : requestBody
|
||||
const withPolicyIdentity = <T extends Record<string, any>>(app: T): T =>
|
||||
app.policy
|
||||
? {
|
||||
...app,
|
||||
policy: {
|
||||
...app.policy,
|
||||
on_behalf_of: onBehalfOfPrincipal,
|
||||
on_behalf_of_email: onBehalfOf
|
||||
}
|
||||
}
|
||||
onBehalfOfPrincipal && app.policy
|
||||
? { ...app, policy: { ...app.policy, on_behalf_of: onBehalfOfPrincipal } }
|
||||
: app
|
||||
const agents = new Set<string>()
|
||||
const withAgentIdentity = <T extends Record<string, any>>(requestBody: T, path: string): T =>
|
||||
agents.has(path) && requestBody.value && typeof requestBody.value === 'object'
|
||||
? {
|
||||
...requestBody,
|
||||
value: onBehalfOf
|
||||
? { ...requestBody.value, on_behalf_of: onBehalfOf }
|
||||
: requestBody.value,
|
||||
preserve_on_behalf_of: onBehalfOf !== undefined
|
||||
}
|
||||
: requestBody
|
||||
const refuseUpdate = (): never => {
|
||||
if (conflict) conflict.hit = true
|
||||
throw new Error('item already exists in the target workspace')
|
||||
}
|
||||
// The published package builds variable, resource and folder bodies field by field without
|
||||
// `labels`, so carry the source item's across from the read `deployItem` does just before the
|
||||
// write. One provider serves one deploy, so the read always belongs to the write that follows.
|
||||
let sourceLabels: string[] | undefined
|
||||
const readLabels = <T extends { labels?: string[] }>(item: T): T => {
|
||||
sourceLabels = item.labels
|
||||
return item
|
||||
}
|
||||
const withLabels = <T extends Record<string, any>>(requestBody: T): T => ({
|
||||
...requestBody,
|
||||
labels: sourceLabels
|
||||
})
|
||||
return {
|
||||
existsFlowByPath: (p) => FlowService.existsFlowByPath(p),
|
||||
existsScriptByPath: (p) => ScriptService.existsScriptByPath(p),
|
||||
@@ -305,43 +256,21 @@ function makeProvider(
|
||||
getPublicSecretOfLatestVersionOfApp: (p) => AppService.getPublicSecretOfLatestVersionOfApp(p),
|
||||
getRawAppData: (p) => AppService.getRawAppData(p),
|
||||
deleteApp: (p) => AppService.deleteApp(p),
|
||||
getVariable: (p) => VariableService.getVariable(p).then(readLabels),
|
||||
createVariable: (p) =>
|
||||
VariableService.createVariable({ ...p, requestBody: withLabels(p.requestBody) }),
|
||||
updateVariable: (p) =>
|
||||
VariableService.updateVariable({ ...p, requestBody: withLabels(p.requestBody) }),
|
||||
getVariable: (p) => VariableService.getVariable(p),
|
||||
createVariable: (p) => VariableService.createVariable(p),
|
||||
updateVariable: (p) => VariableService.updateVariable(p),
|
||||
deleteVariable: (p) => VariableService.deleteVariable(p),
|
||||
getResource: async (p) => {
|
||||
const resource = readLabels(await ResourceService.getResource(p))
|
||||
if (resource.resource_type !== 'ai_agent' || !resource.value) return resource
|
||||
agents.add(p.path)
|
||||
const { on_behalf_of: _, ...value } = resource.value as Record<string, any>
|
||||
return { ...resource, value }
|
||||
},
|
||||
createResource: (p) =>
|
||||
ResourceService.createResource({
|
||||
...p,
|
||||
requestBody: withAgentIdentity(withLabels(p.requestBody), p.requestBody.path)
|
||||
}),
|
||||
updateResource: (p) =>
|
||||
ResourceService.updateResource({
|
||||
...p,
|
||||
requestBody: withAgentIdentity(withLabels(p.requestBody), p.path)
|
||||
}),
|
||||
getResource: (p) => ResourceService.getResource(p),
|
||||
createResource: (p) => ResourceService.createResource(p),
|
||||
updateResource: (p) => ResourceService.updateResource(p),
|
||||
deleteResource: (p) => ResourceService.deleteResource(p),
|
||||
getResourceType: (p) => ResourceService.getResourceType(p),
|
||||
createResourceType: (p) => ResourceService.createResourceType(p),
|
||||
updateResourceType: (p) => ResourceService.updateResourceType(p),
|
||||
deleteResourceType: (p) => ResourceService.deleteResourceType(p),
|
||||
getFolder: (p) => FolderService.getFolder(p).then(readLabels),
|
||||
createFolder: (p) =>
|
||||
FolderService.createFolder({ ...p, requestBody: withLabels(p.requestBody) }),
|
||||
// A folder with no labels reads back without the field, so clearing them needs an explicit [].
|
||||
updateFolder: (p) =>
|
||||
FolderService.updateFolder({
|
||||
...p,
|
||||
requestBody: { ...p.requestBody, labels: sourceLabels ?? [] }
|
||||
}),
|
||||
getFolder: (p) => FolderService.getFolder(p),
|
||||
createFolder: (p) => FolderService.createFolder(p),
|
||||
updateFolder: (p) => FolderService.updateFolder(p),
|
||||
deleteFolder: (p) => FolderService.deleteFolder(p),
|
||||
// Triggers
|
||||
existsTriggerByKind: (kind, p) => triggerServiceFor(kind).exists(p),
|
||||
@@ -483,7 +412,7 @@ export async function deployItem(
|
||||
|
||||
const conflict: DeployConflict | undefined = createOnly ? { hit: false } : undefined
|
||||
const result = await sharedDeployItem(
|
||||
makeProvider(onBehalfOfPrincipal, onBehalfOf, conflict),
|
||||
makeProvider(onBehalfOfPrincipal, conflict),
|
||||
kind as DeployKind,
|
||||
path,
|
||||
workspaceFrom,
|
||||
|
||||
Reference in New Issue
Block a user