@tailor-platform/sdk 1.36.0 → 1.38.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/CHANGELOG.md +82 -0
- package/dist/application-C1ipG5Q6.mjs +4 -0
- package/dist/{application-BwboBFcU.mjs → application-DhQrXEld.mjs} +60 -22
- package/dist/application-DhQrXEld.mjs.map +1 -0
- package/dist/{brand-0SscafcY.mjs → brand-D-d15jx3.mjs} +1 -1
- package/dist/{brand-0SscafcY.mjs.map → brand-D-d15jx3.mjs.map} +1 -1
- package/dist/cli/index.mjs +369 -128
- package/dist/cli/index.mjs.map +1 -1
- package/dist/cli/lib.d.mts +6 -6
- package/dist/cli/lib.mjs +7 -7
- package/dist/{client-B6icVEv4.mjs → client-BWAbbA1C.mjs} +1 -1
- package/dist/{client-CN15WgW2.mjs → client-xzPXtc_e.mjs} +10 -4
- package/dist/{client-CN15WgW2.mjs.map → client-xzPXtc_e.mjs.map} +1 -1
- package/dist/configure/index.d.mts +4 -5
- package/dist/configure/index.mjs +8 -15
- package/dist/configure/index.mjs.map +1 -1
- package/dist/{crash-report-CB1UtT3O.mjs → crash-report-BEAiCSCl.mjs} +1 -1
- package/dist/{crash-report-CdxPj_SW.mjs → crash-report-DXhPL8Ue.mjs} +4 -4
- package/dist/{crash-report-CdxPj_SW.mjs.map → crash-report-DXhPL8Ue.mjs.map} +1 -1
- package/dist/{enum-constants-DI85-fPE.mjs → enum-constants-Dx82rSjf.mjs} +1 -1
- package/dist/{enum-constants-DI85-fPE.mjs.map → enum-constants-Dx82rSjf.mjs.map} +1 -1
- package/dist/errors-D9f2UJpT.mjs +43 -0
- package/dist/errors-D9f2UJpT.mjs.map +1 -0
- package/dist/{file-utils-C4rXlOVt.mjs → file-utils-DeWpvq3T.mjs} +1 -1
- package/dist/{file-utils-C4rXlOVt.mjs.map → file-utils-DeWpvq3T.mjs.map} +1 -1
- package/dist/{index-DZN1QFLM.d.mts → index-CHo73Aat.d.mts} +2 -2
- package/dist/{index-CxSLivW7.d.mts → index-CIIXsk3E.d.mts} +2 -2
- package/dist/{index-C7vIBAg8.d.mts → index-Cln_TTZn.d.mts} +2 -2
- package/dist/{index-CYaunQeL.d.mts → index-Cs3fwmLu.d.mts} +33 -13
- package/dist/{index-DDCyefuU.d.mts → index-D_W9-Lvk.d.mts} +2 -2
- package/dist/{interceptor-f7slMkCC.mjs → interceptor-CzaH2Ur6.mjs} +1 -1
- package/dist/{interceptor-f7slMkCC.mjs.map → interceptor-CzaH2Ur6.mjs.map} +1 -1
- package/dist/{job-CPKYCk_e.mjs → job-DkAklmE4.mjs} +2 -2
- package/dist/{job-CPKYCk_e.mjs.map → job-DkAklmE4.mjs.map} +1 -1
- package/dist/{kysely-type-DtnNdHn3.mjs → kysely-type-CwtvQuxh.mjs} +1 -1
- package/dist/{kysely-type-DtnNdHn3.mjs.map → kysely-type-CwtvQuxh.mjs.map} +1 -1
- package/dist/{logger-qz-Y4sBV.mjs → logger-5_JMzHmw.mjs} +42 -3
- package/dist/logger-5_JMzHmw.mjs.map +1 -0
- package/dist/package-json--6dmp6-h.mjs +4 -0
- package/dist/{package-json-CfUqjJaQ.mjs → package-json-BHViVisJ.mjs} +1 -1
- package/dist/{package-json-CfUqjJaQ.mjs.map → package-json-BHViVisJ.mjs.map} +1 -1
- package/dist/plugin/builtin/enum-constants/index.d.mts +1 -1
- package/dist/plugin/builtin/enum-constants/index.mjs +1 -1
- package/dist/plugin/builtin/file-utils/index.d.mts +1 -1
- package/dist/plugin/builtin/file-utils/index.mjs +1 -1
- package/dist/plugin/builtin/kysely-type/index.d.mts +1 -1
- package/dist/plugin/builtin/kysely-type/index.mjs +1 -1
- package/dist/plugin/builtin/seed/index.d.mts +1 -1
- package/dist/plugin/builtin/seed/index.mjs +1 -1
- package/dist/plugin/index.d.mts +1 -2
- package/dist/{plugin-CiPUxkyN.d.mts → plugin-D84blivd.d.mts} +67 -11
- package/dist/{runtime-C7RRDaB3.mjs → runtime-ChpwtPut.mjs} +587 -144
- package/dist/runtime-ChpwtPut.mjs.map +1 -0
- package/dist/{schema-D27cW0Ca.mjs → schema-CnwUqPyM.mjs} +4 -361
- package/dist/schema-CnwUqPyM.mjs.map +1 -0
- package/dist/{seed-BZIFDG27.mjs → seed-DrbB1VXd.mjs} +1 -1
- package/dist/{seed-BZIFDG27.mjs.map → seed-DrbB1VXd.mjs.map} +1 -1
- package/dist/service-Bcp6JB3w.mjs +132 -0
- package/dist/service-Bcp6JB3w.mjs.map +1 -0
- package/dist/telemetry-4IOPW6wE.mjs +4 -0
- package/dist/{telemetry-CREcGK8y.mjs → telemetry-DwHuiNiR.mjs} +2 -2
- package/dist/{telemetry-CREcGK8y.mjs.map → telemetry-DwHuiNiR.mjs.map} +1 -1
- package/dist/types-B9ZMosul.mjs +372 -0
- package/dist/types-B9ZMosul.mjs.map +1 -0
- package/dist/types-C45jRrCM.mjs +4 -0
- package/dist/utils/test/index.d.mts +2 -2
- package/dist/utils/test/index.mjs +7 -3
- package/dist/utils/test/index.mjs.map +1 -1
- package/dist/{workflow.generated-8BeGQsVU.d.mts → workflow.generated-BRdcCWfC.d.mts} +2 -2
- package/docs/cli/function.md +42 -16
- package/docs/cli/upgrade.md +51 -0
- package/docs/cli/user.md +1 -1
- package/docs/cli/workflow.md +10 -10
- package/docs/cli-reference.md +23 -14
- package/docs/configuration.md +9 -7
- package/docs/services/auth.md +6 -5
- package/docs/services/executor.md +44 -12
- package/docs/services/resolver.md +6 -13
- package/docs/services/tailordb.md +20 -0
- package/docs/services/workflow.md +4 -3
- package/package.json +10 -10
- package/dist/application-BB5TqXWY.mjs +0 -4
- package/dist/application-BwboBFcU.mjs.map +0 -1
- package/dist/env-_ce3IYbl.d.mts +0 -30
- package/dist/logger-qz-Y4sBV.mjs.map +0 -1
- package/dist/package-json-D5Km1jjt.mjs +0 -4
- package/dist/runtime-C7RRDaB3.mjs.map +0 -1
- package/dist/schema-D27cW0Ca.mjs.map +0 -1
- package/dist/telemetry-C508zIi1.mjs +0 -4
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
|
|
2
|
-
import { A as ExecutorJobStatus, B as AuthSCIMAttribute_Type, C as TailorDBType_PermitAction, D as IdPPermissionPermit, E as IdPPermissionOperator, F as AuthIDPConfig_AuthType, G as UserProfileProviderConfig_UserProfileProviderType, H as AuthSCIMConfig_AuthorizationType, I as AuthInvokerSchema, J as Condition_Operator, K as GetApplicationSchemaHealthResponse_ApplicationSchemaHealthStatus, L as AuthOAuth2Client_ClientType, M as ExecutorTriggerType, N as AuthConnection_Type, O as FunctionExecution_Status, P as AuthHookPoint, Q as Subgraph_ServiceType, R as AuthOAuth2Client_GrantType, S as TailorDBType_Permission_Permit, T as IdPLang, V as AuthSCIMAttribute_Uniqueness, W as TenantProviderConfig_TenantProviderType, X as PageDirection, Y as FilterSchema, Z as ApplicationSchemaUpdateAttemptStatus, _ as WorkflowJobExecution_Status, a as fetchMachineUserToken, b as TailorDBGQLPermission_Permit, f as platformBaseUrl, g as WorkflowExecution_Status, h as WorkspacePlatformUserRole, i as fetchAll, j as ExecutorTargetType, m as userAgent, p as resolveStaticWebsiteUrls, q as ConditionSchema, u as initOperatorClient, v as TailorDBGQLPermission_Action, w as PipelineResolver_OperationType, x as TailorDBType_Permission_Operator, y as TailorDBGQLPermission_Operator, z as AuthSCIMAttribute_Mutability } from "./client-
|
|
3
|
-
import { t as db } from "./schema-
|
|
4
|
-
import { i as symbols, n as logger, r as styles, t as CIPromptError } from "./logger-
|
|
5
|
-
import { t as readPackageJson } from "./package-json-
|
|
6
|
-
import { S as readPlatformConfig, T as writePlatformConfig, _ as hashFile, a as loadConfig, b as loadAccessToken, c as createExecutorService, d as TailorDBTypeSchema, f as stringifyFunction, g as getDistDir, h as createBundleCache, m as loadFilesWithIgnores, n as generatePluginFilesIfNeeded, p as tailorUserMap, r as loadApplication, t as defineApplication, u as OAuth2ClientSchema, x as loadWorkspaceId } from "./application-
|
|
7
|
-
import { r as withSpan } from "./telemetry-
|
|
2
|
+
import { A as ExecutorJobStatus, B as AuthSCIMAttribute_Type, C as TailorDBType_PermitAction, D as IdPPermissionPermit, E as IdPPermissionOperator, F as AuthIDPConfig_AuthType, G as UserProfileProviderConfig_UserProfileProviderType, H as AuthSCIMConfig_AuthorizationType, I as AuthInvokerSchema, J as Condition_Operator, K as GetApplicationSchemaHealthResponse_ApplicationSchemaHealthStatus, L as AuthOAuth2Client_ClientType, M as ExecutorTriggerType, N as AuthConnection_Type, O as FunctionExecution_Status, P as AuthHookPoint, Q as Subgraph_ServiceType, R as AuthOAuth2Client_GrantType, S as TailorDBType_Permission_Permit, T as IdPLang, V as AuthSCIMAttribute_Uniqueness, W as TenantProviderConfig_TenantProviderType, X as PageDirection, Y as FilterSchema, Z as ApplicationSchemaUpdateAttemptStatus, _ as WorkflowJobExecution_Status, a as fetchMachineUserToken, b as TailorDBGQLPermission_Permit, f as platformBaseUrl, g as WorkflowExecution_Status, h as WorkspacePlatformUserRole, i as fetchAll, j as ExecutorTargetType, m as userAgent, p as resolveStaticWebsiteUrls, q as ConditionSchema, u as initOperatorClient, v as TailorDBGQLPermission_Action, w as PipelineResolver_OperationType, x as TailorDBType_Permission_Operator, y as TailorDBGQLPermission_Operator, z as AuthSCIMAttribute_Mutability } from "./client-xzPXtc_e.mjs";
|
|
3
|
+
import { t as db } from "./schema-CnwUqPyM.mjs";
|
|
4
|
+
import { a as parseBoolean, i as symbols, n as logger, r as styles, t as CIPromptError } from "./logger-5_JMzHmw.mjs";
|
|
5
|
+
import { t as readPackageJson } from "./package-json-BHViVisJ.mjs";
|
|
6
|
+
import { S as readPlatformConfig, T as writePlatformConfig, _ as hashFile, a as loadConfig, b as loadAccessToken, c as createExecutorService, d as TailorDBTypeSchema, f as stringifyFunction, g as getDistDir, h as createBundleCache, m as loadFilesWithIgnores, n as generatePluginFilesIfNeeded, p as tailorUserMap, r as loadApplication, t as defineApplication, u as OAuth2ClientSchema, x as loadWorkspaceId } from "./application-DhQrXEld.mjs";
|
|
7
|
+
import { r as withSpan } from "./telemetry-DwHuiNiR.mjs";
|
|
8
|
+
import { n as isCLIError, t as createCLIError } from "./errors-D9f2UJpT.mjs";
|
|
8
9
|
import { arg, createDefineCommand, defineCommand, runCommand } from "politty";
|
|
9
10
|
import { z } from "zod";
|
|
10
11
|
import * as fs$1 from "node:fs";
|
|
11
12
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
12
13
|
import { parseEnv } from "node:util";
|
|
13
14
|
import * as path from "pathe";
|
|
14
|
-
import chalk from "chalk";
|
|
15
15
|
import { formatDistanceToNowStrict } from "date-fns";
|
|
16
16
|
import { getBorderCharacters, table } from "table";
|
|
17
17
|
import { ValueSchema, timestampDate } from "@bufbuild/protobuf/wkt";
|
|
@@ -463,9 +463,10 @@ function extractAttributesFromConfig(config) {
|
|
|
463
463
|
* @param attributeMap - Attribute map configuration
|
|
464
464
|
* @param attributeList - Attribute list configuration
|
|
465
465
|
* @param env - Environment configuration
|
|
466
|
+
* @param machineUserNames - Registered machine user names (used to narrow `authInvoker` strings)
|
|
466
467
|
* @returns Generated type definition source
|
|
467
468
|
*/
|
|
468
|
-
function generateTypeDefinition(attributeMap, attributeList, env) {
|
|
469
|
+
function generateTypeDefinition(attributeMap, attributeList, env, machineUserNames) {
|
|
469
470
|
const mapFields = attributeMap ? Object.entries(attributeMap).map(([key, value]) => ` ${key}: ${value};`).join("\n") : "";
|
|
470
471
|
const mapBody = !attributeMap || Object.keys(attributeMap).length === 0 ? "{}" : `{
|
|
471
472
|
${mapFields}
|
|
@@ -476,6 +477,11 @@ ${mapFields}
|
|
|
476
477
|
const envFields = env ? Object.entries(env).map(([key, value]) => {
|
|
477
478
|
return ` ${key}: ${typeof value === "string" ? `"${value}"` : String(value)};`;
|
|
478
479
|
}).join("\n") : "";
|
|
480
|
+
const envBody = !env || Object.keys(env).length === 0 ? "{}" : `{
|
|
481
|
+
${envFields}
|
|
482
|
+
}`;
|
|
483
|
+
const isValidIdentifier = (s) => /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(s);
|
|
484
|
+
const machineUserFields = machineUserNames?.length ? machineUserNames.map((name) => ` ${isValidIdentifier(name) ? name : JSON.stringify(name)}: true;`).join("\n") : "";
|
|
479
485
|
return ml`
|
|
480
486
|
// This file is auto-generated by @tailor-platform/sdk
|
|
481
487
|
// Do not edit this file manually
|
|
@@ -484,8 +490,9 @@ ${mapFields}
|
|
|
484
490
|
declare module "@tailor-platform/sdk" {
|
|
485
491
|
interface AttributeMap ${mapBody}
|
|
486
492
|
interface AttributeList ${listBody}
|
|
487
|
-
interface Env ${
|
|
488
|
-
${
|
|
493
|
+
interface Env ${envBody}
|
|
494
|
+
interface MachineUserNameRegistry ${!machineUserNames || machineUserNames.length === 0 ? "{}" : `{
|
|
495
|
+
${machineUserFields}
|
|
489
496
|
}`}
|
|
490
497
|
}
|
|
491
498
|
|
|
@@ -496,6 +503,8 @@ export {};
|
|
|
496
503
|
function collectAttributesFromConfig(config) {
|
|
497
504
|
const auth = config.auth;
|
|
498
505
|
if (!auth || typeof auth !== "object") return {};
|
|
506
|
+
const machineUsersObj = auth.machineUsers;
|
|
507
|
+
const machineUserNames = machineUsersObj && typeof machineUsersObj === "object" ? Object.keys(machineUsersObj) : void 0;
|
|
499
508
|
const inferAttributeType = (field) => {
|
|
500
509
|
const type = field?.type;
|
|
501
510
|
const metadata = field?.metadata;
|
|
@@ -516,18 +525,22 @@ function collectAttributesFromConfig(config) {
|
|
|
516
525
|
acc[key] = inferAttributeType(fields?.[key]);
|
|
517
526
|
return acc;
|
|
518
527
|
}, {}) : void 0,
|
|
519
|
-
attributeList
|
|
528
|
+
attributeList,
|
|
529
|
+
machineUserNames
|
|
520
530
|
};
|
|
521
531
|
}
|
|
522
532
|
if ("machineUserAttributes" in auth) {
|
|
523
533
|
const machineUserAttributes = auth.machineUserAttributes;
|
|
524
|
-
if (!machineUserAttributes) return {};
|
|
525
|
-
return {
|
|
526
|
-
acc[key]
|
|
527
|
-
|
|
528
|
-
|
|
534
|
+
if (!machineUserAttributes) return { machineUserNames };
|
|
535
|
+
return {
|
|
536
|
+
attributeMap: Object.entries(machineUserAttributes).reduce((acc, [key, field]) => {
|
|
537
|
+
acc[key] = inferAttributeType(field);
|
|
538
|
+
return acc;
|
|
539
|
+
}, {}),
|
|
540
|
+
machineUserNames
|
|
541
|
+
};
|
|
529
542
|
}
|
|
530
|
-
return {};
|
|
543
|
+
return { machineUserNames };
|
|
531
544
|
}
|
|
532
545
|
/**
|
|
533
546
|
* Resolve the output path for the generated type definition file.
|
|
@@ -545,13 +558,14 @@ function resolveTypeDefinitionPath(configPath) {
|
|
|
545
558
|
async function generateUserTypes(options) {
|
|
546
559
|
const { config, configPath } = options;
|
|
547
560
|
try {
|
|
548
|
-
const { attributeMap, attributeList } = extractAttributesFromConfig(config);
|
|
561
|
+
const { attributeMap, attributeList, machineUserNames } = extractAttributesFromConfig(config);
|
|
549
562
|
if (!attributeMap && !attributeList) logger.info("No attributes found in configuration", { mode: "plain" });
|
|
550
563
|
if (attributeMap) logger.debug(`Extracted AttributeMap: ${JSON.stringify(attributeMap)}`);
|
|
551
564
|
if (attributeList) logger.debug(`Extracted AttributeList: ${JSON.stringify(attributeList)}`);
|
|
565
|
+
if (machineUserNames?.length) logger.debug(`Extracted MachineUserNames: ${JSON.stringify(machineUserNames)}`);
|
|
552
566
|
const env = config.env;
|
|
553
567
|
if (env) logger.debug(`Extracted Env: ${JSON.stringify(env)}`);
|
|
554
|
-
const typeDefContent = generateTypeDefinition(attributeMap, attributeList, env);
|
|
568
|
+
const typeDefContent = generateTypeDefinition(attributeMap, attributeList, env, machineUserNames);
|
|
555
569
|
const outputPath = resolveTypeDefinitionPath(configPath);
|
|
556
570
|
fs$1.mkdirSync(path.dirname(outputPath), { recursive: true });
|
|
557
571
|
fs$1.writeFileSync(outputPath, typeDefContent);
|
|
@@ -945,7 +959,6 @@ function formatPlanSummary(summary) {
|
|
|
945
959
|
`${summary.delete} to delete`
|
|
946
960
|
];
|
|
947
961
|
if (summary.replace > 0) parts.push(`${summary.replace} to replace`);
|
|
948
|
-
parts.push(`${summary.unchanged} unchanged`);
|
|
949
962
|
return `Plan: ${parts.join(", ")}`;
|
|
950
963
|
}
|
|
951
964
|
|
|
@@ -1133,13 +1146,9 @@ async function planApplication(context) {
|
|
|
1133
1146
|
applicationName: application.name
|
|
1134
1147
|
}
|
|
1135
1148
|
});
|
|
1136
|
-
changeSet.print();
|
|
1137
|
-
return changeSet;
|
|
1138
|
-
}
|
|
1139
|
-
if (application.subgraphs.length === 0) {
|
|
1140
|
-
changeSet.print();
|
|
1141
1149
|
return changeSet;
|
|
1142
1150
|
}
|
|
1151
|
+
if (application.subgraphs.length === 0) return changeSet;
|
|
1143
1152
|
let authNamespace;
|
|
1144
1153
|
let authIdpConfigName;
|
|
1145
1154
|
if (application.authService && application.authService.config) {
|
|
@@ -1191,7 +1200,6 @@ async function planApplication(context) {
|
|
|
1191
1200
|
request,
|
|
1192
1201
|
metaRequest
|
|
1193
1202
|
});
|
|
1194
|
-
changeSet.print();
|
|
1195
1203
|
return changeSet;
|
|
1196
1204
|
}
|
|
1197
1205
|
function protoSubgraph(subgraph) {
|
|
@@ -1501,6 +1509,10 @@ function computeContentHash(content) {
|
|
|
1501
1509
|
function functionRegistryTrn$1(workspaceId, name) {
|
|
1502
1510
|
return `trn:v1:workspace:${workspaceId}:function_registry:${name}`;
|
|
1503
1511
|
}
|
|
1512
|
+
const RESOLVER_PREFIX = "resolver--";
|
|
1513
|
+
const EXECUTOR_PREFIX = "executor--";
|
|
1514
|
+
const WORKFLOW_PREFIX = "workflow--";
|
|
1515
|
+
const AUTH_HOOK_PREFIX = "auth-hook--";
|
|
1504
1516
|
/**
|
|
1505
1517
|
* Build a function registry name for a resolver.
|
|
1506
1518
|
* @param namespace - Resolver namespace
|
|
@@ -1508,7 +1520,7 @@ function functionRegistryTrn$1(workspaceId, name) {
|
|
|
1508
1520
|
* @returns Function registry name
|
|
1509
1521
|
*/
|
|
1510
1522
|
function resolverFunctionName(namespace, resolverName) {
|
|
1511
|
-
return
|
|
1523
|
+
return `${RESOLVER_PREFIX}${namespace}--${resolverName}`;
|
|
1512
1524
|
}
|
|
1513
1525
|
/**
|
|
1514
1526
|
* Build a function registry name for an executor.
|
|
@@ -1516,7 +1528,7 @@ function resolverFunctionName(namespace, resolverName) {
|
|
|
1516
1528
|
* @returns Function registry name
|
|
1517
1529
|
*/
|
|
1518
1530
|
function executorFunctionName(executorName) {
|
|
1519
|
-
return
|
|
1531
|
+
return `${EXECUTOR_PREFIX}${executorName}`;
|
|
1520
1532
|
}
|
|
1521
1533
|
/**
|
|
1522
1534
|
* Build a function registry name for a workflow job.
|
|
@@ -1524,7 +1536,50 @@ function executorFunctionName(executorName) {
|
|
|
1524
1536
|
* @returns Function registry name
|
|
1525
1537
|
*/
|
|
1526
1538
|
function workflowJobFunctionName(jobName) {
|
|
1527
|
-
return
|
|
1539
|
+
return `${WORKFLOW_PREFIX}${jobName}`;
|
|
1540
|
+
}
|
|
1541
|
+
/**
|
|
1542
|
+
* Split function registry changes into grouped buckets by resource-name prefix.
|
|
1543
|
+
* @param changeSet - Function registry change set
|
|
1544
|
+
* @returns Grouped function registry changes by resource kind
|
|
1545
|
+
*/
|
|
1546
|
+
function splitFunctionRegistryChanges(changeSet) {
|
|
1547
|
+
function partition(items) {
|
|
1548
|
+
const buckets = {
|
|
1549
|
+
workflowJob: [],
|
|
1550
|
+
resolver: [],
|
|
1551
|
+
executor: [],
|
|
1552
|
+
authHook: [],
|
|
1553
|
+
other: []
|
|
1554
|
+
};
|
|
1555
|
+
for (const item of items) if (item.name.startsWith("workflow--")) buckets.workflowJob.push(item);
|
|
1556
|
+
else if (item.name.startsWith("resolver--")) buckets.resolver.push(item);
|
|
1557
|
+
else if (item.name.startsWith("executor--")) buckets.executor.push(item);
|
|
1558
|
+
else if (item.name.startsWith("auth-hook--")) buckets.authHook.push(item);
|
|
1559
|
+
else buckets.other.push(item);
|
|
1560
|
+
return buckets;
|
|
1561
|
+
}
|
|
1562
|
+
const creates = partition(changeSet.creates);
|
|
1563
|
+
const updates = partition(changeSet.updates);
|
|
1564
|
+
const deletes = partition(changeSet.deletes);
|
|
1565
|
+
const replaces = partition(changeSet.replaces);
|
|
1566
|
+
const unchanged = partition(changeSet.unchanged);
|
|
1567
|
+
function collect(key) {
|
|
1568
|
+
return {
|
|
1569
|
+
creates: creates[key],
|
|
1570
|
+
updates: updates[key],
|
|
1571
|
+
deletes: deletes[key],
|
|
1572
|
+
replaces: replaces[key],
|
|
1573
|
+
unchanged: unchanged[key]
|
|
1574
|
+
};
|
|
1575
|
+
}
|
|
1576
|
+
return {
|
|
1577
|
+
workflowJobChanges: collect("workflowJob"),
|
|
1578
|
+
resolverFunctionChanges: collect("resolver"),
|
|
1579
|
+
executorFunctionChanges: collect("executor"),
|
|
1580
|
+
authHookFunctionChanges: collect("authHook"),
|
|
1581
|
+
otherChanges: collect("other")
|
|
1582
|
+
};
|
|
1528
1583
|
}
|
|
1529
1584
|
/**
|
|
1530
1585
|
* Build a function registry name for an auth hook.
|
|
@@ -1687,9 +1742,13 @@ async function planFunctionRegistry(client, workspaceId, appName, entries) {
|
|
|
1687
1742
|
workspaceId
|
|
1688
1743
|
});
|
|
1689
1744
|
}
|
|
1690
|
-
changeSet
|
|
1745
|
+
const { workflowJobChanges, resolverFunctionChanges, executorFunctionChanges, authHookFunctionChanges } = splitFunctionRegistryChanges(changeSet);
|
|
1691
1746
|
return {
|
|
1692
1747
|
changeSet,
|
|
1748
|
+
workflowJobChanges,
|
|
1749
|
+
resolverFunctionChanges,
|
|
1750
|
+
executorFunctionChanges,
|
|
1751
|
+
authHookFunctionChanges,
|
|
1693
1752
|
conflicts,
|
|
1694
1753
|
unmanaged,
|
|
1695
1754
|
resourceOwners
|
|
@@ -1763,6 +1822,228 @@ async function applyFunctionRegistry(client, workspaceId, result, phase = "creat
|
|
|
1763
1822
|
})));
|
|
1764
1823
|
}
|
|
1765
1824
|
|
|
1825
|
+
//#endregion
|
|
1826
|
+
//#region src/cli/commands/apply/grouped-display.ts
|
|
1827
|
+
/**
|
|
1828
|
+
* Convert grouped function registry changes into mutable name sets.
|
|
1829
|
+
* @param changes - Grouped function registry changes
|
|
1830
|
+
* @returns Mutable name sets keyed by action
|
|
1831
|
+
*/
|
|
1832
|
+
function createRelatedFunctionRegistryNameSets(changes) {
|
|
1833
|
+
return {
|
|
1834
|
+
creates: new Set(changes?.creates.map((item) => item.name) ?? []),
|
|
1835
|
+
updates: new Set(changes?.updates.map((item) => item.name) ?? []),
|
|
1836
|
+
deletes: new Set(changes?.deletes.map((item) => item.name) ?? []),
|
|
1837
|
+
replaces: new Set(changes?.replaces.map((item) => item.name) ?? [])
|
|
1838
|
+
};
|
|
1839
|
+
}
|
|
1840
|
+
const ACTION_SYMBOLS = {
|
|
1841
|
+
create: symbols.create,
|
|
1842
|
+
update: symbols.update,
|
|
1843
|
+
delete: symbols.delete,
|
|
1844
|
+
replace: symbols.replace
|
|
1845
|
+
};
|
|
1846
|
+
/**
|
|
1847
|
+
* Convert a plain change set into grouped display entries.
|
|
1848
|
+
* @param changeSet - Change set to convert
|
|
1849
|
+
* @param labels - Labels to attach to each entry
|
|
1850
|
+
* @param getNamespace - Optional callback to extract namespace from an item
|
|
1851
|
+
* @returns Display entries in CLI print order
|
|
1852
|
+
*/
|
|
1853
|
+
function formatChangeSetEntries(changeSet, labels = [], getNamespace) {
|
|
1854
|
+
function toEntry(action, item) {
|
|
1855
|
+
return {
|
|
1856
|
+
action,
|
|
1857
|
+
symbol: ACTION_SYMBOLS[action],
|
|
1858
|
+
name: item.name,
|
|
1859
|
+
labels: [...labels],
|
|
1860
|
+
namespace: getNamespace?.(item)
|
|
1861
|
+
};
|
|
1862
|
+
}
|
|
1863
|
+
return [
|
|
1864
|
+
...changeSet.creates.map((item) => toEntry("create", item)),
|
|
1865
|
+
...changeSet.deletes.map((item) => toEntry("delete", item)),
|
|
1866
|
+
...changeSet.updates.map((item) => toEntry("update", item)),
|
|
1867
|
+
...changeSet.replaces.map((item) => toEntry("replace", item))
|
|
1868
|
+
];
|
|
1869
|
+
}
|
|
1870
|
+
function formatGroupedDisplayLine(entry) {
|
|
1871
|
+
return entry.labels.length > 0 ? `${entry.symbol} ${entry.name} (${entry.labels.join(", ")})` : `${entry.symbol} ${entry.name}`;
|
|
1872
|
+
}
|
|
1873
|
+
function parseFunctionRegistryName(name) {
|
|
1874
|
+
if (name.startsWith("resolver--")) {
|
|
1875
|
+
const [, namespace, resolverName] = name.split("--");
|
|
1876
|
+
if (namespace && resolverName) return {
|
|
1877
|
+
displayName: resolverName,
|
|
1878
|
+
namespace
|
|
1879
|
+
};
|
|
1880
|
+
}
|
|
1881
|
+
if (name.startsWith("workflow--")) return { displayName: name.slice(WORKFLOW_PREFIX.length) };
|
|
1882
|
+
if (name.startsWith("executor--")) return { displayName: name.slice(EXECUTOR_PREFIX.length) };
|
|
1883
|
+
if (name.startsWith("auth-hook--")) {
|
|
1884
|
+
const [, namespace, hookPoint] = name.split("--");
|
|
1885
|
+
if (namespace && hookPoint) return {
|
|
1886
|
+
displayName: hookPoint,
|
|
1887
|
+
namespace
|
|
1888
|
+
};
|
|
1889
|
+
}
|
|
1890
|
+
return { displayName: name };
|
|
1891
|
+
}
|
|
1892
|
+
/**
|
|
1893
|
+
* Build function-registry-only entries that were not grouped with a parent resource.
|
|
1894
|
+
* @param names - Related function registry names keyed by action
|
|
1895
|
+
* @param consumed - Function registry names already grouped with parent resources
|
|
1896
|
+
* @returns Display entries for ungrouped function registry changes
|
|
1897
|
+
*/
|
|
1898
|
+
function buildRemainingFunctionRegistryEntries(names, consumed = createRelatedFunctionRegistryNameSets()) {
|
|
1899
|
+
return [
|
|
1900
|
+
[
|
|
1901
|
+
"create",
|
|
1902
|
+
names.creates,
|
|
1903
|
+
consumed.creates
|
|
1904
|
+
],
|
|
1905
|
+
[
|
|
1906
|
+
"delete",
|
|
1907
|
+
names.deletes,
|
|
1908
|
+
consumed.deletes
|
|
1909
|
+
],
|
|
1910
|
+
[
|
|
1911
|
+
"update",
|
|
1912
|
+
names.updates,
|
|
1913
|
+
consumed.updates
|
|
1914
|
+
],
|
|
1915
|
+
[
|
|
1916
|
+
"replace",
|
|
1917
|
+
names.replaces,
|
|
1918
|
+
consumed.replaces
|
|
1919
|
+
]
|
|
1920
|
+
].flatMap(([action, nameSet, consumedSet]) => [...nameSet].filter((name) => !consumedSet.has(name)).map((name) => {
|
|
1921
|
+
const { displayName, namespace } = parseFunctionRegistryName(name);
|
|
1922
|
+
return {
|
|
1923
|
+
action,
|
|
1924
|
+
symbol: ACTION_SYMBOLS[action],
|
|
1925
|
+
name: displayName,
|
|
1926
|
+
labels: ["function"],
|
|
1927
|
+
namespace
|
|
1928
|
+
};
|
|
1929
|
+
}));
|
|
1930
|
+
}
|
|
1931
|
+
/**
|
|
1932
|
+
* Format change set entries with function registry grouping.
|
|
1933
|
+
*
|
|
1934
|
+
* For each item in creates/updates/deletes, calls `getFunctionRegistryNames` to
|
|
1935
|
+
* derive zero or more function registry names. When a matching function registry
|
|
1936
|
+
* change exists for the same action, the item is displayed with both the resource
|
|
1937
|
+
* label and "functionRegistry". Ungrouped function registry changes are appended.
|
|
1938
|
+
* @param resourceLabel - Label for the resource kind (e.g. "executor", "resolver")
|
|
1939
|
+
* @param changeSet - Resource change set with creates/updates/deletes/replaces
|
|
1940
|
+
* @param changeSet.creates - Created resources
|
|
1941
|
+
* @param changeSet.updates - Updated resources
|
|
1942
|
+
* @param changeSet.deletes - Deleted resources
|
|
1943
|
+
* @param changeSet.replaces - Replaced resources
|
|
1944
|
+
* @param functionRegistryChanges - Related function registry changes
|
|
1945
|
+
* @param getFunctionRegistryNames - Derives function registry names from a resource item
|
|
1946
|
+
* @param options - Optional display callbacks
|
|
1947
|
+
* @param options.getNamespace - Extract namespace from an item for nested display
|
|
1948
|
+
* @param options.getDisplayName - Override display name for an item
|
|
1949
|
+
* @returns Display entries for CLI output
|
|
1950
|
+
*/
|
|
1951
|
+
function formatChangeEntriesWithFunctionRegistry(resourceLabel, changeSet, functionRegistryChanges, getFunctionRegistryNames, options) {
|
|
1952
|
+
const { getNamespace, getDisplayName } = options ?? {};
|
|
1953
|
+
const functionNames = createRelatedFunctionRegistryNameSets(functionRegistryChanges);
|
|
1954
|
+
const consumed = createRelatedFunctionRegistryNameSets();
|
|
1955
|
+
function processItems(items, action, fnNameSet, consumedSet) {
|
|
1956
|
+
return items.map((item) => {
|
|
1957
|
+
const names = getFunctionRegistryNames(item, action);
|
|
1958
|
+
const hasMatch = names.some((name) => fnNameSet.has(name));
|
|
1959
|
+
if (hasMatch) {
|
|
1960
|
+
for (const name of names) if (fnNameSet.has(name)) consumedSet.add(name);
|
|
1961
|
+
}
|
|
1962
|
+
return {
|
|
1963
|
+
action,
|
|
1964
|
+
symbol: ACTION_SYMBOLS[action],
|
|
1965
|
+
name: getDisplayName?.(item) ?? item.name,
|
|
1966
|
+
labels: hasMatch ? [resourceLabel, "function"] : [resourceLabel],
|
|
1967
|
+
namespace: getNamespace?.(item)
|
|
1968
|
+
};
|
|
1969
|
+
});
|
|
1970
|
+
}
|
|
1971
|
+
return [
|
|
1972
|
+
...processItems(changeSet.creates, "create", functionNames.creates, consumed.creates),
|
|
1973
|
+
...processItems(changeSet.deletes, "delete", functionNames.deletes, consumed.deletes),
|
|
1974
|
+
...processItems(changeSet.updates, "update", functionNames.updates, consumed.updates),
|
|
1975
|
+
...changeSet.replaces.map((item) => ({
|
|
1976
|
+
action: "replace",
|
|
1977
|
+
symbol: ACTION_SYMBOLS["replace"],
|
|
1978
|
+
name: getDisplayName?.(item) ?? item.name,
|
|
1979
|
+
labels: [resourceLabel],
|
|
1980
|
+
namespace: getNamespace?.(item)
|
|
1981
|
+
})),
|
|
1982
|
+
...buildRemainingFunctionRegistryEntries(functionNames, consumed)
|
|
1983
|
+
];
|
|
1984
|
+
}
|
|
1985
|
+
/**
|
|
1986
|
+
* Extract service-level actions from a change set for namespace header display.
|
|
1987
|
+
* @param changeSet - Service change set
|
|
1988
|
+
* @returns Array of namespace actions
|
|
1989
|
+
*/
|
|
1990
|
+
function extractServiceActions(changeSet) {
|
|
1991
|
+
return [
|
|
1992
|
+
...changeSet.creates.map((item) => ({
|
|
1993
|
+
name: item.name,
|
|
1994
|
+
action: "create"
|
|
1995
|
+
})),
|
|
1996
|
+
...changeSet.deletes.map((item) => ({
|
|
1997
|
+
name: item.name,
|
|
1998
|
+
action: "delete"
|
|
1999
|
+
})),
|
|
2000
|
+
...changeSet.updates.map((item) => ({
|
|
2001
|
+
name: item.name,
|
|
2002
|
+
action: "update"
|
|
2003
|
+
})),
|
|
2004
|
+
...changeSet.replaces.map((item) => ({
|
|
2005
|
+
name: item.name,
|
|
2006
|
+
action: "replace"
|
|
2007
|
+
}))
|
|
2008
|
+
];
|
|
2009
|
+
}
|
|
2010
|
+
/**
|
|
2011
|
+
* Print a titled section of grouped display entries, nesting by namespace.
|
|
2012
|
+
* Service-level changes are shown as the namespace header symbol.
|
|
2013
|
+
* Services without child entries are shown as flat entries.
|
|
2014
|
+
* @param title - Section title
|
|
2015
|
+
* @param entries - Entries to print (should NOT include service entries)
|
|
2016
|
+
* @param serviceActions - Optional service-level actions to merge into namespace headers
|
|
2017
|
+
*/
|
|
2018
|
+
function printGroupedDisplaySection(title, entries, serviceActions) {
|
|
2019
|
+
const serviceMap = /* @__PURE__ */ new Map();
|
|
2020
|
+
if (serviceActions) for (const sa of serviceActions) serviceMap.set(sa.name, sa.action);
|
|
2021
|
+
if (entries.length === 0 && serviceMap.size === 0) return;
|
|
2022
|
+
logger.log(styles.bold(`${title}:`));
|
|
2023
|
+
const namespaceOrder = [];
|
|
2024
|
+
const byNamespace = /* @__PURE__ */ new Map();
|
|
2025
|
+
for (const entry of entries) {
|
|
2026
|
+
const ns = entry.namespace;
|
|
2027
|
+
if (!byNamespace.has(ns)) {
|
|
2028
|
+
namespaceOrder.push(ns);
|
|
2029
|
+
byNamespace.set(ns, []);
|
|
2030
|
+
}
|
|
2031
|
+
byNamespace.get(ns).push(entry);
|
|
2032
|
+
}
|
|
2033
|
+
const printedServices = /* @__PURE__ */ new Set();
|
|
2034
|
+
for (const ns of namespaceOrder) {
|
|
2035
|
+
const group = byNamespace.get(ns);
|
|
2036
|
+
if (ns) {
|
|
2037
|
+
const svcAction = serviceMap.get(ns);
|
|
2038
|
+
const prefix = svcAction ? `${ACTION_SYMBOLS[svcAction]} ` : "";
|
|
2039
|
+
logger.log(` ${prefix}${styles.bold(`${ns}:`)}`);
|
|
2040
|
+
printedServices.add(ns);
|
|
2041
|
+
for (const entry of group) logger.log(` ${formatGroupedDisplayLine(entry)}`);
|
|
2042
|
+
} else for (const entry of group) logger.log(` ${formatGroupedDisplayLine(entry)}`);
|
|
2043
|
+
}
|
|
2044
|
+
for (const [name, action] of serviceMap) if (!printedServices.has(name)) logger.log(` ${ACTION_SYMBOLS[action]} ${name}`);
|
|
2045
|
+
}
|
|
2046
|
+
|
|
1766
2047
|
//#endregion
|
|
1767
2048
|
//#region src/parser/service/idp/permission.ts
|
|
1768
2049
|
const operatorMap = {
|
|
@@ -1949,13 +2230,10 @@ async function planIdP(context) {
|
|
|
1949
2230
|
const { client, workspaceId, application, forRemoval, forceApplyAll = false } = context;
|
|
1950
2231
|
const idps = forRemoval ? [] : application.idpServices;
|
|
1951
2232
|
const { changeSet: serviceChangeSet, conflicts, unmanaged, resourceOwners } = await planServices$3(client, workspaceId, application.name, idps);
|
|
1952
|
-
const clientChangeSet = await planClients(client, workspaceId, idps, serviceChangeSet.deletes.map((del) => del.name), forceApplyAll);
|
|
1953
|
-
serviceChangeSet.print();
|
|
1954
|
-
clientChangeSet.print();
|
|
1955
2233
|
return {
|
|
1956
2234
|
changeSet: {
|
|
1957
2235
|
service: serviceChangeSet,
|
|
1958
|
-
client:
|
|
2236
|
+
client: await planClients(client, workspaceId, idps, serviceChangeSet.deletes.map((del) => del.name), forceApplyAll)
|
|
1959
2237
|
},
|
|
1960
2238
|
conflicts,
|
|
1961
2239
|
unmanaged,
|
|
@@ -2396,16 +2674,6 @@ async function planAuth(context) {
|
|
|
2396
2674
|
planSCIMResources(client, workspaceId, auths, deletedServices),
|
|
2397
2675
|
planAuthConnections(client, workspaceId, application.name, auths)
|
|
2398
2676
|
]);
|
|
2399
|
-
serviceChangeSet.print();
|
|
2400
|
-
idpConfigChangeSet.print();
|
|
2401
|
-
userProfileConfigChangeSet.print();
|
|
2402
|
-
tenantConfigChangeSet.print();
|
|
2403
|
-
machineUserChangeSet.print();
|
|
2404
|
-
authHookChangeSet.print();
|
|
2405
|
-
oauth2ClientChangeSet.print();
|
|
2406
|
-
scimChangeSet.print();
|
|
2407
|
-
scimResourceChangeSet.print();
|
|
2408
|
-
connectionResult.changeSet.print();
|
|
2409
2677
|
return {
|
|
2410
2678
|
changeSet: {
|
|
2411
2679
|
service: serviceChangeSet,
|
|
@@ -3371,6 +3639,21 @@ function areAuthHooksEqual(existing, desired) {
|
|
|
3371
3639
|
} : void 0
|
|
3372
3640
|
});
|
|
3373
3641
|
}
|
|
3642
|
+
/**
|
|
3643
|
+
* Format auth hook changes for grouped dry-run display.
|
|
3644
|
+
* @param changeSet - Auth hook changes
|
|
3645
|
+
* @param functionRegistryAuthHookChanges - Related function registry changes for auth hooks
|
|
3646
|
+
* @returns Display entries for auth hook output
|
|
3647
|
+
*/
|
|
3648
|
+
function formatAuthHookChangeEntries(changeSet, functionRegistryAuthHookChanges) {
|
|
3649
|
+
return formatChangeEntriesWithFunctionRegistry("authHook", changeSet, functionRegistryAuthHookChanges, (item) => {
|
|
3650
|
+
const [namespace, hookPoint] = item.name.split("/");
|
|
3651
|
+
return namespace && hookPoint ? [authHookFunctionName(namespace, hookPoint)] : [];
|
|
3652
|
+
}, {
|
|
3653
|
+
getNamespace: (item) => item.name.split("/")[0],
|
|
3654
|
+
getDisplayName: (item) => item.name.split("/")[1] ?? item.name
|
|
3655
|
+
});
|
|
3656
|
+
}
|
|
3374
3657
|
async function planAuthHooks(client, workspaceId, auths, deletedServices, forceApplyAll = false) {
|
|
3375
3658
|
const changeSet = createChangeSet("Auth hooks");
|
|
3376
3659
|
for (const auth of auths) {
|
|
@@ -3606,6 +3889,32 @@ function buildResolverOperationHookExpr(env) {
|
|
|
3606
3889
|
return `({ ...context.pipeline, input: context.args, user: ${tailorUserMap}, env: ${JSON.stringify(env)} });`;
|
|
3607
3890
|
}
|
|
3608
3891
|
|
|
3892
|
+
//#endregion
|
|
3893
|
+
//#region src/cli/commands/apply/auth-invoker.ts
|
|
3894
|
+
/**
|
|
3895
|
+
* Normalize an authInvoker value to the object form required by the proto payload.
|
|
3896
|
+
*
|
|
3897
|
+
* Accepts either:
|
|
3898
|
+
* - `undefined` — returns undefined
|
|
3899
|
+
* - a plain string (machine user name) — expands to `{ namespace, machineUserName }` using `authNamespace`
|
|
3900
|
+
* - an object `{ namespace, machineUserName }` — returned as-is
|
|
3901
|
+
* @param authInvoker - String machine user name or object form
|
|
3902
|
+
* @param authNamespace - Auth service namespace (required when authInvoker is a string)
|
|
3903
|
+
* @param context - Contextual label used in error messages (e.g. `resolver "foo"`)
|
|
3904
|
+
* @returns Object form of auth invoker, or undefined
|
|
3905
|
+
*/
|
|
3906
|
+
function normalizeAuthInvoker(authInvoker, authNamespace, context) {
|
|
3907
|
+
if (authInvoker === void 0) return void 0;
|
|
3908
|
+
if (typeof authInvoker === "string") {
|
|
3909
|
+
if (!authNamespace) throw new Error(`${context} uses a string authInvoker ("${authInvoker}"), but no Auth service is configured. Configure an Auth service or use the object form { namespace, machineUserName }.`);
|
|
3910
|
+
return {
|
|
3911
|
+
namespace: authNamespace,
|
|
3912
|
+
machineUserName: authInvoker
|
|
3913
|
+
};
|
|
3914
|
+
}
|
|
3915
|
+
return authInvoker;
|
|
3916
|
+
}
|
|
3917
|
+
|
|
3609
3918
|
//#endregion
|
|
3610
3919
|
//#region src/cli/commands/apply/executor.ts
|
|
3611
3920
|
/**
|
|
@@ -3707,7 +4016,6 @@ async function planExecutor(context) {
|
|
|
3707
4016
|
}
|
|
3708
4017
|
});
|
|
3709
4018
|
});
|
|
3710
|
-
changeSet.print();
|
|
3711
4019
|
return {
|
|
3712
4020
|
changeSet,
|
|
3713
4021
|
conflicts,
|
|
@@ -3715,6 +4023,31 @@ async function planExecutor(context) {
|
|
|
3715
4023
|
resourceOwners
|
|
3716
4024
|
};
|
|
3717
4025
|
}
|
|
4026
|
+
function isFunctionBackedExecutor(executor) {
|
|
4027
|
+
return executor?.targetType === ExecutorTargetType.FUNCTION || executor?.targetType === ExecutorTargetType.JOB_FUNCTION;
|
|
4028
|
+
}
|
|
4029
|
+
/**
|
|
4030
|
+
* Build desired executor configs keyed by executor name from create/update changes.
|
|
4031
|
+
* @param changeSet - Executor create/update changes
|
|
4032
|
+
* @returns Executor configs keyed by name
|
|
4033
|
+
*/
|
|
4034
|
+
function buildPlannedExecutorsByName(changeSet) {
|
|
4035
|
+
return Object.fromEntries([...changeSet.creates, ...changeSet.updates].map((item) => [item.name, item.request.executor]));
|
|
4036
|
+
}
|
|
4037
|
+
/**
|
|
4038
|
+
* Format executor changes for grouped dry-run display.
|
|
4039
|
+
* @param changeSet - Executor changes
|
|
4040
|
+
* @param executors - Desired executor configs keyed by name
|
|
4041
|
+
* @param functionRegistryExecutorChanges - Related function registry changes for executors
|
|
4042
|
+
* @returns Display entries for executor output
|
|
4043
|
+
*/
|
|
4044
|
+
function formatExecutorChangeEntries(changeSet, executors, functionRegistryExecutorChanges) {
|
|
4045
|
+
return formatChangeEntriesWithFunctionRegistry("executor", changeSet, functionRegistryExecutorChanges, (item, action) => {
|
|
4046
|
+
if (action === "delete") return [executorFunctionName(item.name)];
|
|
4047
|
+
const executor = executors[item.name];
|
|
4048
|
+
return executor && isFunctionBackedExecutor(executor) ? [executorFunctionName(item.name)] : [];
|
|
4049
|
+
});
|
|
4050
|
+
}
|
|
3718
4051
|
function normalizeComparableExecutor(executor) {
|
|
3719
4052
|
const normalized = normalizeProtoConfig(executor) ?? {};
|
|
3720
4053
|
const webhookHeaders = normalized.targetConfig?.config?.case === "webhook" ? [...normalized.targetConfig.config.value.headers ?? []].sort((left, right) => (left.key ?? "").localeCompare(right.key ?? "")) : void 0;
|
|
@@ -3722,7 +4055,10 @@ function normalizeComparableExecutor(executor) {
|
|
|
3722
4055
|
...normalized.triggerConfig,
|
|
3723
4056
|
config: {
|
|
3724
4057
|
...normalized.triggerConfig.config,
|
|
3725
|
-
value: {
|
|
4058
|
+
value: {
|
|
4059
|
+
...normalized.triggerConfig.config.value,
|
|
4060
|
+
secret: void 0
|
|
4061
|
+
}
|
|
3726
4062
|
}
|
|
3727
4063
|
} : normalized.triggerConfig?.config?.case === "event" ? {
|
|
3728
4064
|
...normalized.triggerConfig,
|
|
@@ -3834,7 +4170,10 @@ function protoExecutor(application, executor) {
|
|
|
3834
4170
|
triggerType = ExecutorTriggerType.INCOMING_WEBHOOK;
|
|
3835
4171
|
triggerConfig = { config: {
|
|
3836
4172
|
case: "incomingWebhook",
|
|
3837
|
-
value: {
|
|
4173
|
+
value: { ...trigger.response ? { response: {
|
|
4174
|
+
...trigger.response.body ? { body: { expr: `(${stringifyFunction(trigger.response.body)})(${argsExpr})` } } : {},
|
|
4175
|
+
...trigger.response.statusCode != null ? { statusCode: trigger.response.statusCode } : {}
|
|
4176
|
+
} } : {} }
|
|
3838
4177
|
} };
|
|
3839
4178
|
break;
|
|
3840
4179
|
case "idpUser":
|
|
@@ -3862,6 +4201,8 @@ function protoExecutor(application, executor) {
|
|
|
3862
4201
|
const target = executor.operation;
|
|
3863
4202
|
let targetType;
|
|
3864
4203
|
let targetConfig;
|
|
4204
|
+
const authNamespace = application.authService?.parsedConfig.name;
|
|
4205
|
+
const invokerContext = `Executor "${executor.name}"`;
|
|
3865
4206
|
switch (target.kind) {
|
|
3866
4207
|
case "webhook":
|
|
3867
4208
|
targetType = ExecutorTargetType.WEBHOOK;
|
|
@@ -3899,7 +4240,7 @@ function protoExecutor(application, executor) {
|
|
|
3899
4240
|
appName: target.appName ?? appName,
|
|
3900
4241
|
query: target.query,
|
|
3901
4242
|
variables: target.variables ? { expr: `(${stringifyFunction(target.variables)})(${argsExpr})` } : void 0,
|
|
3902
|
-
invoker: target.authInvoker
|
|
4243
|
+
invoker: normalizeAuthInvoker(target.authInvoker, authNamespace, invokerContext)
|
|
3903
4244
|
}
|
|
3904
4245
|
} };
|
|
3905
4246
|
break;
|
|
@@ -3913,7 +4254,7 @@ function protoExecutor(application, executor) {
|
|
|
3913
4254
|
name: "operation",
|
|
3914
4255
|
scriptRef: executorFunctionName(executor.name),
|
|
3915
4256
|
variables: { expr: argsExpr },
|
|
3916
|
-
invoker: target.authInvoker
|
|
4257
|
+
invoker: normalizeAuthInvoker(target.authInvoker, authNamespace, invokerContext)
|
|
3917
4258
|
}
|
|
3918
4259
|
} };
|
|
3919
4260
|
break;
|
|
@@ -3924,7 +4265,7 @@ function protoExecutor(application, executor) {
|
|
|
3924
4265
|
value: {
|
|
3925
4266
|
workflowName: target.workflowName,
|
|
3926
4267
|
variables: target.args ? typeof target.args === "function" ? { expr: `(${stringifyFunction(target.args)})(${argsExpr})` } : { expr: JSON.stringify(target.args) } : void 0,
|
|
3927
|
-
invoker: target.authInvoker
|
|
4268
|
+
invoker: normalizeAuthInvoker(target.authInvoker, authNamespace, invokerContext)
|
|
3928
4269
|
}
|
|
3929
4270
|
} };
|
|
3930
4271
|
break;
|
|
@@ -4016,9 +4357,7 @@ async function planPipeline(context) {
|
|
|
4016
4357
|
}
|
|
4017
4358
|
const executors = forRemoval ? [] : Object.values(await application.executorService?.loadExecutors() ?? {});
|
|
4018
4359
|
const { changeSet: serviceChangeSet, conflicts, unmanaged, resourceOwners } = await planServices$1(client, workspaceId, application.name, pipelines);
|
|
4019
|
-
const resolverChangeSet = await planResolvers(client, workspaceId, pipelines, executors, serviceChangeSet.deletes.map((del) => del.name), application.env, forceApplyAll);
|
|
4020
|
-
serviceChangeSet.print();
|
|
4021
|
-
resolverChangeSet.print();
|
|
4360
|
+
const { changeSet: resolverChangeSet } = await planResolvers(client, workspaceId, pipelines, executors, serviceChangeSet.deletes.map((del) => del.name), application.env, application.authService?.config.name, forceApplyAll);
|
|
4022
4361
|
return {
|
|
4023
4362
|
changeSet: {
|
|
4024
4363
|
service: serviceChangeSet,
|
|
@@ -4110,7 +4449,7 @@ async function planServices$1(client, workspaceId, appName, pipelines) {
|
|
|
4110
4449
|
resourceOwners
|
|
4111
4450
|
};
|
|
4112
4451
|
}
|
|
4113
|
-
async function planResolvers(client, workspaceId, pipelines, executors, deletedServices, env, forceApplyAll = false) {
|
|
4452
|
+
async function planResolvers(client, workspaceId, pipelines, executors, deletedServices, env, authNamespace, forceApplyAll = false) {
|
|
4114
4453
|
const changeSet = createChangeSet("Pipeline resolvers");
|
|
4115
4454
|
const fetchResolvers = (namespaceName) => {
|
|
4116
4455
|
return fetchAll(async (pageToken, maxPageSize) => {
|
|
@@ -4135,7 +4474,7 @@ async function planResolvers(client, workspaceId, pipelines, executors, deletedS
|
|
|
4135
4474
|
const existingResolvers = await fetchResolvers(pipeline.namespace);
|
|
4136
4475
|
const existingResolversMap = new Map(existingResolvers.map((resolver) => [resolver.name, resolver]));
|
|
4137
4476
|
for (const resolver of Object.values(pipeline.resolvers)) {
|
|
4138
|
-
const desiredResolver = processResolver(pipeline.namespace, resolver, executorUsedResolvers, env);
|
|
4477
|
+
const desiredResolver = processResolver(pipeline.namespace, resolver, executorUsedResolvers, env, authNamespace);
|
|
4139
4478
|
if (existingResolversMap.get(resolver.name)) {
|
|
4140
4479
|
const { pipelineResolver: existingResolverDetail } = await client.getPipelineResolver({
|
|
4141
4480
|
workspaceId,
|
|
@@ -4182,7 +4521,19 @@ async function planResolvers(client, workspaceId, pipelines, executors, deletedS
|
|
|
4182
4521
|
}
|
|
4183
4522
|
});
|
|
4184
4523
|
});
|
|
4185
|
-
return changeSet;
|
|
4524
|
+
return { changeSet };
|
|
4525
|
+
}
|
|
4526
|
+
/**
|
|
4527
|
+
* Format resolver changes for grouped dry-run display.
|
|
4528
|
+
* @param changeSet - Resolver changes
|
|
4529
|
+
* @param resolverFunctionChanges - Related function registry changes for resolvers
|
|
4530
|
+
* @returns Display entries for resolver output
|
|
4531
|
+
*/
|
|
4532
|
+
function formatResolverChangeEntries(changeSet, resolverFunctionChanges) {
|
|
4533
|
+
return formatChangeEntriesWithFunctionRegistry("resolver", changeSet, resolverFunctionChanges, (item) => {
|
|
4534
|
+
const namespace = item.request.namespaceName;
|
|
4535
|
+
return namespace ? [resolverFunctionName(namespace, item.name)] : [];
|
|
4536
|
+
}, { getNamespace: (item) => item.request.namespaceName });
|
|
4186
4537
|
}
|
|
4187
4538
|
function normalizeComparableResolver(resolver) {
|
|
4188
4539
|
const normalized = normalizeProtoConfig(resolver) ?? {};
|
|
@@ -4237,7 +4588,7 @@ function normalizeComparableType(type) {
|
|
|
4237
4588
|
fields: (type.fields ?? []).map((field) => normalizeComparableField(field))
|
|
4238
4589
|
};
|
|
4239
4590
|
}
|
|
4240
|
-
function processResolver(namespace, resolver, executorUsedResolvers, env) {
|
|
4591
|
+
function processResolver(namespace, resolver, executorUsedResolvers, env, authNamespace) {
|
|
4241
4592
|
const pipelines = [{
|
|
4242
4593
|
name: "body",
|
|
4243
4594
|
operationName: "body",
|
|
@@ -4246,7 +4597,7 @@ function processResolver(namespace, resolver, executorUsedResolvers, env) {
|
|
|
4246
4597
|
operationSourceRef: resolverFunctionName(namespace, resolver.name),
|
|
4247
4598
|
operationHook: { expr: buildResolverOperationHookExpr(env) },
|
|
4248
4599
|
postScript: `args.body`,
|
|
4249
|
-
invoker: resolver.authInvoker
|
|
4600
|
+
invoker: normalizeAuthInvoker(resolver.authInvoker, authNamespace, `Resolver "${resolver.name}"`)
|
|
4250
4601
|
}];
|
|
4251
4602
|
const typeBaseName = inflection.camelize(resolver.name);
|
|
4252
4603
|
const inputs = resolver.input ? protoFields(resolver.input, `${typeBaseName}Input`, true) : [];
|
|
@@ -4444,12 +4795,6 @@ async function planSecretManager(context) {
|
|
|
4444
4795
|
});
|
|
4445
4796
|
}
|
|
4446
4797
|
}
|
|
4447
|
-
vaultChangeSet.print();
|
|
4448
|
-
secretChangeSet.print();
|
|
4449
|
-
if (skippedSecrets.length > 0) {
|
|
4450
|
-
logger.log(styles.bold("Secret Manager secrets (skipped - no value provided):"));
|
|
4451
|
-
for (const name of skippedSecrets) logger.log(` ${styles.dim("○")} ${name}`);
|
|
4452
|
-
}
|
|
4453
4798
|
return {
|
|
4454
4799
|
vaultChangeSet,
|
|
4455
4800
|
secretChangeSet,
|
|
@@ -4650,7 +4995,6 @@ async function planStaticWebsite(context) {
|
|
|
4650
4995
|
}
|
|
4651
4996
|
});
|
|
4652
4997
|
});
|
|
4653
|
-
changeSet.print();
|
|
4654
4998
|
return {
|
|
4655
4999
|
changeSet,
|
|
4656
5000
|
conflicts,
|
|
@@ -6771,9 +7115,6 @@ async function planTailorDB(context) {
|
|
|
6771
7115
|
const { changeSet: serviceChangeSet, conflicts, unmanaged, resourceOwners } = await planServices(client, workspaceId, application.name, tailordbs);
|
|
6772
7116
|
const deletedServices = serviceChangeSet.deletes.map((del) => del.name);
|
|
6773
7117
|
const [typeChangeSet, gqlPermissionChangeSet] = await Promise.all([planTypes(client, workspaceId, tailordbs, executors, deletedServices, void 0, forceApplyAll), planGqlPermissions(client, workspaceId, tailordbs, deletedServices, forceApplyAll)]);
|
|
6774
|
-
serviceChangeSet.print();
|
|
6775
|
-
typeChangeSet.print();
|
|
6776
|
-
gqlPermissionChangeSet.print();
|
|
6777
7118
|
return {
|
|
6778
7119
|
changeSet: {
|
|
6779
7120
|
service: serviceChangeSet,
|
|
@@ -6791,6 +7132,42 @@ async function planTailorDB(context) {
|
|
|
6791
7132
|
}
|
|
6792
7133
|
};
|
|
6793
7134
|
}
|
|
7135
|
+
function itemKey(item) {
|
|
7136
|
+
return `${item.request?.namespaceName ?? ""}/${item.name}`;
|
|
7137
|
+
}
|
|
7138
|
+
function collectTailorDBDisplayEntries(action, typeItems, gqlPermissionItems) {
|
|
7139
|
+
const typeKeys = new Set(typeItems.map(itemKey));
|
|
7140
|
+
const gqlPermissionKeys = new Set(gqlPermissionItems.map(itemKey));
|
|
7141
|
+
const typeEntries = typeItems.map((item) => ({
|
|
7142
|
+
action,
|
|
7143
|
+
symbol: ACTION_SYMBOLS[action],
|
|
7144
|
+
name: item.name,
|
|
7145
|
+
labels: gqlPermissionKeys.has(itemKey(item)) ? ["type", "gqlPermission"] : ["type"],
|
|
7146
|
+
namespace: item.request?.namespaceName
|
|
7147
|
+
}));
|
|
7148
|
+
const gqlPermissionOnlyEntries = gqlPermissionItems.filter((item) => !typeKeys.has(itemKey(item))).map((item) => ({
|
|
7149
|
+
action,
|
|
7150
|
+
symbol: ACTION_SYMBOLS[action],
|
|
7151
|
+
name: item.name,
|
|
7152
|
+
labels: ["gqlPermission"],
|
|
7153
|
+
namespace: item.request?.namespaceName
|
|
7154
|
+
}));
|
|
7155
|
+
return [...typeEntries, ...gqlPermissionOnlyEntries];
|
|
7156
|
+
}
|
|
7157
|
+
/**
|
|
7158
|
+
* Format TailorDB type and gqlPermission changes as grouped dry-run entries.
|
|
7159
|
+
* @param typeChangeSet - TailorDB type changes
|
|
7160
|
+
* @param gqlPermissionChangeSet - TailorDB gqlPermission changes
|
|
7161
|
+
* @returns Display entries for TailorDB resource output
|
|
7162
|
+
*/
|
|
7163
|
+
function formatTailorDBResourceChangeEntries(typeChangeSet, gqlPermissionChangeSet) {
|
|
7164
|
+
return [
|
|
7165
|
+
...collectTailorDBDisplayEntries("create", typeChangeSet.creates, gqlPermissionChangeSet.creates),
|
|
7166
|
+
...collectTailorDBDisplayEntries("delete", typeChangeSet.deletes, gqlPermissionChangeSet.deletes),
|
|
7167
|
+
...collectTailorDBDisplayEntries("update", typeChangeSet.updates, gqlPermissionChangeSet.updates),
|
|
7168
|
+
...collectTailorDBDisplayEntries("replace", typeChangeSet.replaces, gqlPermissionChangeSet.replaces)
|
|
7169
|
+
];
|
|
7170
|
+
}
|
|
6794
7171
|
function trn(workspaceId, name) {
|
|
6795
7172
|
return `${trnPrefix(workspaceId)}:tailordb:${name}`;
|
|
6796
7173
|
}
|
|
@@ -7688,15 +8065,16 @@ async function planWorkflow(client, workspaceId, appName, workflows, mainJobDeps
|
|
|
7688
8065
|
});
|
|
7689
8066
|
}
|
|
7690
8067
|
Object.values(existingWorkflows).forEach((existing) => {
|
|
7691
|
-
|
|
8068
|
+
if (!existing) return;
|
|
8069
|
+
const label = existing.label;
|
|
7692
8070
|
if (label && label !== appName) resourceOwners.add(label);
|
|
7693
8071
|
if (label === appName) changeSet.deletes.push({
|
|
7694
8072
|
name: existing.resource.name,
|
|
7695
8073
|
workspaceId,
|
|
7696
|
-
workflowId: existing.resource.id
|
|
8074
|
+
workflowId: existing.resource.id,
|
|
8075
|
+
usedJobNames: getExistingWorkflowJobNames(existing.resource)
|
|
7697
8076
|
});
|
|
7698
8077
|
});
|
|
7699
|
-
changeSet.print();
|
|
7700
8078
|
return {
|
|
7701
8079
|
changeSet,
|
|
7702
8080
|
conflicts,
|
|
@@ -7706,6 +8084,15 @@ async function planWorkflow(client, workspaceId, appName, workflows, mainJobDeps
|
|
|
7706
8084
|
unchangedWorkflowJobNames
|
|
7707
8085
|
};
|
|
7708
8086
|
}
|
|
8087
|
+
/**
|
|
8088
|
+
* Format workflow changes for grouped dry-run display.
|
|
8089
|
+
* @param changeSet - Workflow changes
|
|
8090
|
+
* @param workflowJobFunctionChanges - Related function registry changes for workflow jobs
|
|
8091
|
+
* @returns Display entries for workflow output
|
|
8092
|
+
*/
|
|
8093
|
+
function formatWorkflowChangeEntries(changeSet, workflowJobFunctionChanges) {
|
|
8094
|
+
return formatChangeEntriesWithFunctionRegistry("workflow", changeSet, workflowJobFunctionChanges, (item) => "usedJobNames" in item ? item.usedJobNames.map((jobName) => workflowJobFunctionName(jobName)) : []);
|
|
8095
|
+
}
|
|
7709
8096
|
function canTreatWorkflowAsUnchanged(existing, workflow, usedJobNames, unchangedJobFunctions) {
|
|
7710
8097
|
if (!usedJobNames.every((jobName) => unchangedJobFunctions.has(jobName))) return false;
|
|
7711
8098
|
return areWorkflowsEqual(existing, workflow, usedJobNames);
|
|
@@ -7740,6 +8127,11 @@ function normalizeComparableWorkflowRetryPolicy(policy) {
|
|
|
7740
8127
|
function normalizeComparableWorkflowJobNames(jobFunctions) {
|
|
7741
8128
|
return Array.isArray(jobFunctions) ? [...jobFunctions].sort() : Object.keys(jobFunctions ?? {}).sort();
|
|
7742
8129
|
}
|
|
8130
|
+
function getExistingWorkflowJobNames(existing) {
|
|
8131
|
+
const jobNames = new Set(Object.keys(existing.jobFunctions ?? {}));
|
|
8132
|
+
if (existing.mainJobFunctionName) jobNames.add(existing.mainJobFunctionName);
|
|
8133
|
+
return [...jobNames].sort();
|
|
8134
|
+
}
|
|
7743
8135
|
function normalizeRetryPolicyForCompare(policy) {
|
|
7744
8136
|
return {
|
|
7745
8137
|
maxRetries: policy.maxRetries,
|
|
@@ -7826,34 +8218,95 @@ async function shouldForceApplyAll(client, workspaceId, application, functionEnt
|
|
|
7826
8218
|
}
|
|
7827
8219
|
return false;
|
|
7828
8220
|
}
|
|
7829
|
-
function
|
|
7830
|
-
const
|
|
7831
|
-
|
|
7832
|
-
|
|
7833
|
-
|
|
7834
|
-
|
|
8221
|
+
function printPlanResults(results) {
|
|
8222
|
+
const executorEntries = formatExecutorChangeEntries(results.executor.changeSet, buildPlannedExecutorsByName(results.executor.changeSet), results.functionRegistry.executorFunctionChanges);
|
|
8223
|
+
const resolverEntries = formatResolverChangeEntries(results.pipeline.changeSet.resolver, results.functionRegistry.resolverFunctionChanges);
|
|
8224
|
+
const workflowEntries = formatWorkflowChangeEntries(results.workflow.changeSet, results.functionRegistry.workflowJobChanges);
|
|
8225
|
+
const authHookEntries = formatAuthHookChangeEntries(results.auth.changeSet.authHook, results.functionRegistry.authHookFunctionChanges);
|
|
8226
|
+
const tailorDBEntries = [...formatTailorDBResourceChangeEntries(results.tailorDB.changeSet.type, results.tailorDB.changeSet.gqlPermission)];
|
|
8227
|
+
const pipelineEntries = [...resolverEntries];
|
|
8228
|
+
const namespaceOf = (item) => {
|
|
8229
|
+
if ("request" in item && item.request && typeof item.request === "object" && "namespaceName" in item.request) return item.request.namespaceName;
|
|
8230
|
+
if ("namespaceName" in item) return item.namespaceName;
|
|
8231
|
+
};
|
|
8232
|
+
const authNamespaceOf = (item) => "request" in item && item.request && typeof item.request === "object" && "authNamespace" in item.request ? item.request.authNamespace : void 0;
|
|
8233
|
+
const idpEntries = [...formatChangeSetEntries(results.idp.changeSet.client, ["client"], namespaceOf)];
|
|
8234
|
+
const authEntries = [
|
|
8235
|
+
...formatChangeSetEntries(results.auth.changeSet.idpConfig, ["idpConfig"], namespaceOf),
|
|
8236
|
+
...formatChangeSetEntries(results.auth.changeSet.userProfileConfig, ["userProfileConfig"], namespaceOf),
|
|
8237
|
+
...formatChangeSetEntries(results.auth.changeSet.tenantConfig, ["tenantConfig"], namespaceOf),
|
|
8238
|
+
...formatChangeSetEntries(results.auth.changeSet.machineUser, ["machineUser"], authNamespaceOf),
|
|
8239
|
+
...authHookEntries,
|
|
8240
|
+
...formatChangeSetEntries(results.auth.changeSet.oauth2Client, ["oauth2Client"], namespaceOf),
|
|
8241
|
+
...formatChangeSetEntries(results.auth.changeSet.scim, ["scimConfig"], namespaceOf),
|
|
8242
|
+
...formatChangeSetEntries(results.auth.changeSet.scimResource, ["scimResource"], namespaceOf),
|
|
8243
|
+
...results.auth.changeSet.connection ? formatChangeSetEntries(results.auth.changeSet.connection, ["connection"], namespaceOf) : []
|
|
8244
|
+
];
|
|
8245
|
+
const { otherChanges: otherFunctionRegistryChanges } = splitFunctionRegistryChanges(results.functionRegistry.changeSet);
|
|
8246
|
+
printGroupedDisplaySection(results.functionRegistry.changeSet.title, formatChangeSetEntries(otherFunctionRegistryChanges));
|
|
8247
|
+
const tailorDBServiceActions = extractServiceActions(results.tailorDB.changeSet.service);
|
|
8248
|
+
const pipelineServiceActions = extractServiceActions(results.pipeline.changeSet.service);
|
|
8249
|
+
const idpServiceActions = extractServiceActions(results.idp.changeSet.service);
|
|
8250
|
+
const authServiceActions = extractServiceActions(results.auth.changeSet.service);
|
|
8251
|
+
results.staticWebsite.changeSet.print();
|
|
8252
|
+
results.app.print();
|
|
8253
|
+
printGroupedDisplaySection("TailorDB", tailorDBEntries, tailorDBServiceActions);
|
|
8254
|
+
printGroupedDisplaySection("Resolver", pipelineEntries, pipelineServiceActions);
|
|
8255
|
+
printGroupedDisplaySection("Executor", executorEntries);
|
|
8256
|
+
printGroupedDisplaySection("Workflow", workflowEntries);
|
|
8257
|
+
printGroupedDisplaySection("IdP", idpEntries, idpServiceActions);
|
|
8258
|
+
printGroupedDisplaySection("Auth", authEntries, authServiceActions);
|
|
8259
|
+
results.secretManager.vaultChangeSet.print();
|
|
8260
|
+
results.secretManager.secretChangeSet.print();
|
|
8261
|
+
if (results.secretManager.skippedSecrets.length > 0) {
|
|
8262
|
+
logger.log(styles.bold("Secret Manager secrets (skipped - no value provided):"));
|
|
8263
|
+
for (const name of results.secretManager.skippedSecrets) logger.log(` ${styles.dim("○")} ${name}`);
|
|
8264
|
+
}
|
|
8265
|
+
const summary = summarizePlanResults(results, [
|
|
8266
|
+
...tailorDBEntries,
|
|
8267
|
+
...pipelineEntries,
|
|
8268
|
+
...executorEntries,
|
|
8269
|
+
...workflowEntries,
|
|
8270
|
+
...idpEntries,
|
|
8271
|
+
...authEntries
|
|
8272
|
+
], [
|
|
8273
|
+
...tailorDBServiceActions,
|
|
8274
|
+
...pipelineServiceActions,
|
|
8275
|
+
...idpServiceActions,
|
|
8276
|
+
...authServiceActions
|
|
8277
|
+
]);
|
|
8278
|
+
logger.log(formatPlanSummary(summary));
|
|
8279
|
+
}
|
|
8280
|
+
/**
|
|
8281
|
+
* Summarize plan counts from display entries, service actions, and non-grouped changesets.
|
|
8282
|
+
* @param results - Planned apply results
|
|
8283
|
+
* @param displayEntries - All grouped display entries across sections
|
|
8284
|
+
* @param serviceActions - All service-level namespace actions
|
|
8285
|
+
* @returns Aggregated plan summary
|
|
8286
|
+
*/
|
|
8287
|
+
function summarizePlanResults(results, displayEntries, serviceActions) {
|
|
8288
|
+
const summary = {
|
|
8289
|
+
create: 0,
|
|
8290
|
+
update: 0,
|
|
8291
|
+
delete: 0,
|
|
8292
|
+
replace: 0,
|
|
8293
|
+
unchanged: 0
|
|
8294
|
+
};
|
|
8295
|
+
for (const entry of displayEntries) summary[entry.action] += 1;
|
|
8296
|
+
for (const sa of serviceActions) summary[sa.action] += 1;
|
|
8297
|
+
const { otherChanges } = splitFunctionRegistryChanges(results.functionRegistry.changeSet);
|
|
8298
|
+
const nonGrouped = summarizeChangeSets([
|
|
8299
|
+
otherChanges,
|
|
7835
8300
|
results.staticWebsite.changeSet,
|
|
7836
|
-
results.idp.changeSet.service,
|
|
7837
|
-
results.idp.changeSet.client,
|
|
7838
|
-
results.auth.changeSet.service,
|
|
7839
|
-
results.auth.changeSet.idpConfig,
|
|
7840
|
-
results.auth.changeSet.userProfileConfig,
|
|
7841
|
-
results.auth.changeSet.tenantConfig,
|
|
7842
|
-
results.auth.changeSet.machineUser,
|
|
7843
|
-
results.auth.changeSet.oauth2Client,
|
|
7844
|
-
results.auth.changeSet.authHook,
|
|
7845
|
-
results.auth.changeSet.scim,
|
|
7846
|
-
results.auth.changeSet.scimResource,
|
|
7847
|
-
...results.auth.changeSet.connection ? [results.auth.changeSet.connection] : [],
|
|
7848
|
-
results.pipeline.changeSet.service,
|
|
7849
|
-
results.pipeline.changeSet.resolver,
|
|
7850
8301
|
results.app,
|
|
7851
|
-
results.executor.changeSet,
|
|
7852
|
-
results.workflow.changeSet,
|
|
7853
8302
|
results.secretManager.vaultChangeSet,
|
|
7854
8303
|
results.secretManager.secretChangeSet
|
|
7855
8304
|
]);
|
|
7856
|
-
|
|
8305
|
+
summary.create += nonGrouped.create;
|
|
8306
|
+
summary.update += nonGrouped.update;
|
|
8307
|
+
summary.delete += nonGrouped.delete;
|
|
8308
|
+
summary.replace += nonGrouped.replace;
|
|
8309
|
+
return summary;
|
|
7857
8310
|
}
|
|
7858
8311
|
/**
|
|
7859
8312
|
* Apply the configured application to the Tailor platform.
|
|
@@ -7866,7 +8319,7 @@ async function apply(options) {
|
|
|
7866
8319
|
const { config, application, workflowBuildResult, bundledScripts, buildOnly } = await withSpan("build", async () => {
|
|
7867
8320
|
const { config, plugins } = await withSpan("build.loadConfig", () => loadConfig(options?.configPath));
|
|
7868
8321
|
const dryRun = options?.dryRun ?? false;
|
|
7869
|
-
const buildOnly = options?.buildOnly ?? process.env.TAILOR_PLATFORM_SDK_BUILD_ONLY ===
|
|
8322
|
+
const buildOnly = options?.buildOnly ?? parseBoolean(process.env.TAILOR_PLATFORM_SDK_BUILD_ONLY) === true;
|
|
7870
8323
|
const noCache = options?.noCache ?? false;
|
|
7871
8324
|
const packageJson = await readPackageJson();
|
|
7872
8325
|
const cacheDir = path.resolve(getDistDir(), "cache");
|
|
@@ -7943,7 +8396,7 @@ async function apply(options) {
|
|
|
7943
8396
|
forceApplyAll
|
|
7944
8397
|
};
|
|
7945
8398
|
const functionRegistry = await withSpan("plan.functionRegistry", () => planFunctionRegistry(client, workspaceId, application.name, functionEntries));
|
|
7946
|
-
const unchangedWorkflowJobs = new Set(functionRegistry.changeSet.unchanged.
|
|
8399
|
+
const unchangedWorkflowJobs = new Set(functionRegistry.changeSet.unchanged.filter((entry) => entry.name.startsWith(WORKFLOW_PREFIX)).map((entry) => entry.name.slice(WORKFLOW_PREFIX.length)));
|
|
7947
8400
|
const [tailorDB, staticWebsite, idp, auth, pipeline, app, executor, workflow, secretManager] = await Promise.all([
|
|
7948
8401
|
withSpan("plan.tailorDB", () => planTailorDB(ctx)),
|
|
7949
8402
|
withSpan("plan.staticWebsite", () => planStaticWebsite(ctx)),
|
|
@@ -8038,7 +8491,7 @@ async function apply(options) {
|
|
|
8038
8491
|
}
|
|
8039
8492
|
});
|
|
8040
8493
|
});
|
|
8041
|
-
|
|
8494
|
+
printPlanResults({
|
|
8042
8495
|
functionRegistry,
|
|
8043
8496
|
tailorDB,
|
|
8044
8497
|
staticWebsite,
|
|
@@ -9043,9 +9496,11 @@ const startCommand = defineAppCommand({
|
|
|
9043
9496
|
args: z.object({
|
|
9044
9497
|
...deploymentArgs,
|
|
9045
9498
|
...nameArgs,
|
|
9046
|
-
|
|
9499
|
+
"machine-user": arg(z.string(), {
|
|
9047
9500
|
alias: "m",
|
|
9048
|
-
|
|
9501
|
+
hiddenAlias: "machineuser",
|
|
9502
|
+
description: "Machine user name",
|
|
9503
|
+
env: "TAILOR_PLATFORM_MACHINE_USER_NAME"
|
|
9049
9504
|
}),
|
|
9050
9505
|
arg: arg(z.string().optional(), {
|
|
9051
9506
|
alias: "a",
|
|
@@ -9056,7 +9511,7 @@ const startCommand = defineAppCommand({
|
|
|
9056
9511
|
run: async (args) => {
|
|
9057
9512
|
const { executionId, wait } = await startWorkflowByName({
|
|
9058
9513
|
name: args.name,
|
|
9059
|
-
machineUser: args
|
|
9514
|
+
machineUser: args["machine-user"],
|
|
9060
9515
|
arg: args.arg,
|
|
9061
9516
|
workspaceId: args["workspace-id"],
|
|
9062
9517
|
profile: args.profile,
|
|
@@ -11436,6 +11891,30 @@ async function execRemove(client, workspaceId, application, config, confirm) {
|
|
|
11436
11891
|
const workflow = await planWorkflow(client, workspaceId, application.name, {}, {});
|
|
11437
11892
|
const functionRegistry = await planFunctionRegistry(client, workspaceId, application.name, []);
|
|
11438
11893
|
const secretManager = await planSecretManager(ctx);
|
|
11894
|
+
functionRegistry.changeSet.print();
|
|
11895
|
+
staticWebsite.changeSet.print();
|
|
11896
|
+
app.print();
|
|
11897
|
+
tailorDB.changeSet.service.print();
|
|
11898
|
+
tailorDB.changeSet.type.print();
|
|
11899
|
+
tailorDB.changeSet.gqlPermission.print();
|
|
11900
|
+
pipeline.changeSet.service.print();
|
|
11901
|
+
pipeline.changeSet.resolver.print();
|
|
11902
|
+
executor.changeSet.print();
|
|
11903
|
+
workflow.changeSet.print();
|
|
11904
|
+
idp.changeSet.service.print();
|
|
11905
|
+
idp.changeSet.client.print();
|
|
11906
|
+
auth.changeSet.service.print();
|
|
11907
|
+
auth.changeSet.idpConfig.print();
|
|
11908
|
+
auth.changeSet.userProfileConfig.print();
|
|
11909
|
+
auth.changeSet.tenantConfig.print();
|
|
11910
|
+
auth.changeSet.machineUser.print();
|
|
11911
|
+
auth.changeSet.oauth2Client.print();
|
|
11912
|
+
auth.changeSet.authHook.print();
|
|
11913
|
+
auth.changeSet.scim.print();
|
|
11914
|
+
auth.changeSet.scimResource.print();
|
|
11915
|
+
auth.changeSet.connection?.print();
|
|
11916
|
+
secretManager.vaultChangeSet.print();
|
|
11917
|
+
secretManager.secretChangeSet.print();
|
|
11439
11918
|
if (tailorDB.changeSet.service.deletes.length === 0 && staticWebsite.changeSet.deletes.length === 0 && idp.changeSet.service.deletes.length === 0 && auth.changeSet.service.deletes.length === 0 && pipeline.changeSet.service.deletes.length === 0 && app.deletes.length === 0 && executor.changeSet.deletes.length === 0 && workflow.changeSet.deletes.length === 0 && functionRegistry.changeSet.deletes.length === 0 && secretManager.vaultChangeSet.deletes.length === 0 && secretManager.secretChangeSet.deletes.length === 0) return;
|
|
11440
11919
|
if (confirm) await confirm();
|
|
11441
11920
|
await applyWorkflow(client, workflow, "delete");
|
|
@@ -12133,7 +12612,7 @@ async function generate(options) {
|
|
|
12133
12612
|
if (options.init) await handleInitOption(namespacesWithMigrations, options.yes);
|
|
12134
12613
|
let pluginManager;
|
|
12135
12614
|
if (plugins.length > 0) pluginManager = new PluginManager(plugins);
|
|
12136
|
-
const { defineApplication } = await import("./application-
|
|
12615
|
+
const { defineApplication } = await import("./application-C1ipG5Q6.mjs");
|
|
12137
12616
|
const application = defineApplication({
|
|
12138
12617
|
config,
|
|
12139
12618
|
pluginManager
|
|
@@ -13447,44 +13926,6 @@ async function bundleQueryScript(engine) {
|
|
|
13447
13926
|
})).output[0].code;
|
|
13448
13927
|
}
|
|
13449
13928
|
|
|
13450
|
-
//#endregion
|
|
13451
|
-
//#region src/cli/shared/errors.ts
|
|
13452
|
-
/**
|
|
13453
|
-
* Format CLI error for output
|
|
13454
|
-
* @param error - CLIError instance to format
|
|
13455
|
-
* @returns Formatted error message
|
|
13456
|
-
*/
|
|
13457
|
-
function formatError(error) {
|
|
13458
|
-
const parts = [chalk.red(`Error${error.code ? ` [${error.code}]` : ""}: ${error.message}`)];
|
|
13459
|
-
if (error.details) parts.push(`\n ${chalk.gray("Details:")} ${error.details}`);
|
|
13460
|
-
if (error.suggestion) parts.push(`\n ${chalk.cyan("Suggestion:")} ${error.suggestion}`);
|
|
13461
|
-
if (error.command) parts.push(`\n ${chalk.gray("Help:")} Run \`tailor-sdk ${error.command} --help\` for usage information.`);
|
|
13462
|
-
return parts.join("");
|
|
13463
|
-
}
|
|
13464
|
-
/**
|
|
13465
|
-
* Create a CLI error with formatted output
|
|
13466
|
-
* @param options - Options to construct a CLIError
|
|
13467
|
-
* @returns Constructed CLIError instance
|
|
13468
|
-
*/
|
|
13469
|
-
function createCLIError(options) {
|
|
13470
|
-
const error = new Error(options.message);
|
|
13471
|
-
error.name = "CLIError";
|
|
13472
|
-
error.code = options.code;
|
|
13473
|
-
error.details = options.details;
|
|
13474
|
-
error.suggestion = options.suggestion;
|
|
13475
|
-
error.command = options.command;
|
|
13476
|
-
error.format = () => formatError(error);
|
|
13477
|
-
return error;
|
|
13478
|
-
}
|
|
13479
|
-
/**
|
|
13480
|
-
* Type guard to check if an error is a CLIError
|
|
13481
|
-
* @param error - Error to check
|
|
13482
|
-
* @returns True if the error is a CLIError
|
|
13483
|
-
*/
|
|
13484
|
-
function isCLIError(error) {
|
|
13485
|
-
return error instanceof Error && error.name === "CLIError";
|
|
13486
|
-
}
|
|
13487
|
-
|
|
13488
13929
|
//#endregion
|
|
13489
13930
|
//#region src/cli/query/errors.ts
|
|
13490
13931
|
function toErrorMessage(error) {
|
|
@@ -14173,9 +14614,11 @@ const queryCommand = defineAppCommand({
|
|
|
14173
14614
|
description: "Read query string from file; omit to start REPL mode"
|
|
14174
14615
|
}),
|
|
14175
14616
|
edit: arg(z.boolean().default(false), { description: "Open a temporary file in your editor; omit to start REPL mode" }),
|
|
14176
|
-
|
|
14617
|
+
"machine-user": arg(z.string(), {
|
|
14177
14618
|
alias: "m",
|
|
14178
|
-
|
|
14619
|
+
hiddenAlias: "machineuser",
|
|
14620
|
+
description: "Machine user name for query execution",
|
|
14621
|
+
env: "TAILOR_PLATFORM_MACHINE_USER_NAME"
|
|
14179
14622
|
})
|
|
14180
14623
|
}).superRefine((args, ctx) => {
|
|
14181
14624
|
if (args.query != null && args.file != null) ctx.addIssue({
|
|
@@ -14206,7 +14649,7 @@ const queryCommand = defineAppCommand({
|
|
|
14206
14649
|
profile: args.profile,
|
|
14207
14650
|
configPath: args.config,
|
|
14208
14651
|
engine: args.engine,
|
|
14209
|
-
machineUser: args
|
|
14652
|
+
machineUser: args["machine-user"]
|
|
14210
14653
|
};
|
|
14211
14654
|
if (mode.mode === "abort") {
|
|
14212
14655
|
logger.info("Editor closed without a query. Nothing was executed.");
|
|
@@ -14335,5 +14778,5 @@ function isDeno() {
|
|
|
14335
14778
|
}
|
|
14336
14779
|
|
|
14337
14780
|
//#endregion
|
|
14338
|
-
export {
|
|
14339
|
-
//# sourceMappingURL=runtime-
|
|
14781
|
+
export { deleteCommand$1 as $, isValidMigrationNumber as $t, truncate as A, formatKeyValueTable as At, updateOrganization as B, DIFF_FILE_NAME as Bt, listCommand$2 as C, startWorkflow as Ct, resumeWorkflow as D, getWorkflowExecution as Dt, resumeCommand as E, executionsCommand as Et, showCommand as F, waitForExecution$1 as Ft, getCommand$1 as G, compareSnapshots as Gt, treeCommand as H, MIGRATE_FILE_NAME as Ht, logBetaWarning as I, MIGRATION_LABEL_KEY as It, updateFolder as J, getLatestMigrationNumber as Jt, getOrganization as K, createSnapshotFromLocalTypes as Kt, remove as L, parseMigrationLabelNumber as Lt, generate as M, getExecutor as Mt, generateCommand as N, apply as Nt, listCommand$3 as O, listWorkflowExecutions as Ot, show as P, executeScript as Pt, getFolder as Q, getNextMigrationNumber as Qt, removeCommand$1 as R, bundleMigrationScript as Rt, listApps as S, startCommand as St, healthCommand as T, getWorkflow as Tt, listCommand$4 as U, SCHEMA_FILE_NAME as Ut, organizationTree as V, INITIAL_SCHEMA_NUMBER as Vt, listOrganizations as W, compareLocalTypesWithSnapshot as Wt, listFolders as X, getMigrationFilePath as Xt, listCommand$5 as Y, getMigrationDirPath as Yt, getCommand$2 as Z, getMigrationFiles as Zt, getWorkspace as _, workspaceArgs as _n, listExecutors as _t, updateUser as a, getNamespacesWithMigrations as an, getCommand$3 as at, createCommand as b, listExecutorJobs as bt, listCommand as c, trnPrefix as cn, tokenCommand as ct, inviteUser as d, apiCommand as dn, generate$1 as dt, loadDiff as en, deleteFolder as et, restoreCommand as f, defineAppCommand as fn, listWebhookExecutors as ft, getCommand as g, isVerbose as gn, listCommand$8 as gt, listWorkspaces as h, deploymentArgs as hn, triggerExecutor as ht, updateCommand as i, hasChanges as in, listOAuth2Clients as it, truncateCommand as j, getCommand$5 as jt, listWorkflows as k, functionExecutionStatusToString as kt, listUsers as l, generateUserTypes as ln, listCommand$7 as lt, listCommand$1 as m, confirmationArgs as mn, triggerCommand as mt, query as n, formatDiffSummary as nn, createFolder as nt, removeCommand as o, prompt as on, getOAuth2Client as ot, restoreWorkspace as p, commonArgs as pn, webhookCommand as pt, updateCommand$2 as q, formatMigrationNumber as qt, queryCommand as r, formatMigrationDiff as rn, listCommand$6 as rt, removeUser as s, sdkNameLabelKey as sn, getMachineUserToken as st, isNativeTypeScriptRuntime as t, reconstructSnapshotFromMigrations as tn, createCommand$1 as tt, inviteCommand as u, apiCall as un, listMachineUsers as ut, deleteCommand as v, getExecutorJob as vt, getAppHealth as w, getCommand$4 as wt, createWorkspace as x, watchExecutorJob as xt, deleteWorkspace as y, jobsCommand as yt, updateCommand$1 as z, DB_TYPES_FILE_NAME as zt };
|
|
14782
|
+
//# sourceMappingURL=runtime-ChpwtPut.mjs.map
|