@firfi/huly-mcp 0.49.6 → 0.50.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/README.md +15 -3
- package/dist/index.cjs +1168 -1039
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -115697,7 +115697,11 @@ var init_issues = __esm({
|
|
|
115697
115697
|
)}. Use status for exact project-specific status names.`
|
|
115698
115698
|
})
|
|
115699
115699
|
),
|
|
115700
|
-
assignee: Schema_exports.optional(
|
|
115700
|
+
assignee: Schema_exports.optional(
|
|
115701
|
+
PersonRefInput.annotate({
|
|
115702
|
+
description: "Filter by assignee email, Person display name, or exact agent UserProfile title"
|
|
115703
|
+
})
|
|
115704
|
+
),
|
|
115701
115705
|
creator: Schema_exports.optional(
|
|
115702
115706
|
PersonRefInput.annotate({
|
|
115703
115707
|
description: "Filter by creator using a raw Person ID, exact email address, or exact display name. Ambiguous exact display names are rejected; unknown people return an empty list."
|
|
@@ -115806,7 +115810,9 @@ var init_issues = __esm({
|
|
|
115806
115810
|
priority: Schema_exports.optional(
|
|
115807
115811
|
IssuePrioritySchema.annotate({ description: "Issue priority (urgent, high, medium, low, no-priority)" })
|
|
115808
115812
|
),
|
|
115809
|
-
assignee: Schema_exports.optional(
|
|
115813
|
+
assignee: Schema_exports.optional(
|
|
115814
|
+
PersonRefInput.annotate({ description: "Assignee email, Person display name, or exact agent UserProfile title" })
|
|
115815
|
+
),
|
|
115810
115816
|
status: Schema_exports.optional(
|
|
115811
115817
|
StatusName.annotate({ description: "Initial status (uses project default if not specified)" })
|
|
115812
115818
|
),
|
|
@@ -115848,7 +115854,9 @@ var init_issues = __esm({
|
|
|
115848
115854
|
),
|
|
115849
115855
|
priority: Schema_exports.optional(IssuePrioritySchema.annotate({ description: "New issue priority" })),
|
|
115850
115856
|
assignee: Schema_exports.optional(
|
|
115851
|
-
Schema_exports.NullOr(PersonRefInput).annotate({
|
|
115857
|
+
Schema_exports.NullOr(PersonRefInput).annotate({
|
|
115858
|
+
description: "New assignee email, Person display name, or exact agent UserProfile title (null to unassign)"
|
|
115859
|
+
})
|
|
115852
115860
|
),
|
|
115853
115861
|
status: Schema_exports.optional(StatusName.annotate({ description: "New status" })),
|
|
115854
115862
|
taskType: Schema_exports.optional(
|
|
@@ -125061,7 +125069,7 @@ var init_unavailable_diagnostics = __esm({
|
|
|
125061
125069
|
});
|
|
125062
125070
|
|
|
125063
125071
|
// src/huly/errors-base.ts
|
|
125064
|
-
var HulyError, NoUpdateFieldsError, HulyConnectionError, HulyDataInvalidError, HulyUnavailableError, HulyAuthError, HulyModelNameSchema, HulyModelFieldSchema, HulyModelMetadataError;
|
|
125072
|
+
var HulyError, NoUpdateFieldsError, HulyConnectionOperation, HulyHttpStatus, HulyConnectionDiagnostic, HulyConnectionError, HTTP_ERROR_STATUS_PATTERN, hulyHttpStatusFromCause, makeOperationConnectionError, HulyDataInvalidError, HulyUnavailableError, HulyAuthError, HulyModelNameSchema, HulyModelFieldSchema, HulyModelMetadataError;
|
|
125065
125073
|
var init_errors_base = __esm({
|
|
125066
125074
|
"src/huly/errors-base.ts"() {
|
|
125067
125075
|
"use strict";
|
|
@@ -125080,11 +125088,67 @@ var init_errors_base = __esm({
|
|
|
125080
125088
|
return `${this.operation} requires at least one update field: ${this.fields.join(", ")}`;
|
|
125081
125089
|
}
|
|
125082
125090
|
};
|
|
125091
|
+
HulyConnectionOperation = Schema_exports.Literals([
|
|
125092
|
+
"findAll",
|
|
125093
|
+
"findOne",
|
|
125094
|
+
"findAllInModel",
|
|
125095
|
+
"createDoc",
|
|
125096
|
+
"conditionalCreateDoc",
|
|
125097
|
+
"updateDoc",
|
|
125098
|
+
"conditionalUpdateDoc",
|
|
125099
|
+
"addCollection",
|
|
125100
|
+
"updateCollection",
|
|
125101
|
+
"removeCollection",
|
|
125102
|
+
"removeDoc",
|
|
125103
|
+
"conditionalRemoveDoc",
|
|
125104
|
+
"createMixin",
|
|
125105
|
+
"updateMixin",
|
|
125106
|
+
"uploadMarkup",
|
|
125107
|
+
"fetchMarkup",
|
|
125108
|
+
"updateMarkup",
|
|
125109
|
+
"searchFulltext",
|
|
125110
|
+
"getWorkspaceMembers",
|
|
125111
|
+
"getPersonInfo",
|
|
125112
|
+
"updateWorkspaceRole",
|
|
125113
|
+
"getWorkspaceInfo",
|
|
125114
|
+
"getUserWorkspaces",
|
|
125115
|
+
"createWorkspace",
|
|
125116
|
+
"deleteWorkspace",
|
|
125117
|
+
"getUserProfile",
|
|
125118
|
+
"setMyProfile",
|
|
125119
|
+
"createAccessLink",
|
|
125120
|
+
"updateAllowReadOnlyGuests",
|
|
125121
|
+
"updateAllowGuestSignUp",
|
|
125122
|
+
"getRegionInfo"
|
|
125123
|
+
]);
|
|
125124
|
+
HulyHttpStatus = Schema_exports.Int.check(Schema_exports.isBetween({ minimum: 100, maximum: 599 })).pipe(
|
|
125125
|
+
Schema_exports.brand("HulyHttpStatus")
|
|
125126
|
+
);
|
|
125127
|
+
HulyConnectionDiagnostic = Schema_exports.Struct({
|
|
125128
|
+
operation: HulyConnectionOperation,
|
|
125129
|
+
httpStatus: Schema_exports.optionalKey(HulyHttpStatus)
|
|
125130
|
+
});
|
|
125083
125131
|
HulyConnectionError = class extends Schema_exports.TaggedError()("HulyConnectionError", {
|
|
125084
125132
|
message: Schema_exports.String,
|
|
125085
|
-
cause: Schema_exports.optional(Schema_exports.Defect())
|
|
125133
|
+
cause: Schema_exports.optional(Schema_exports.Defect()),
|
|
125134
|
+
diagnostic: Schema_exports.optionalKey(HulyConnectionDiagnostic)
|
|
125086
125135
|
}) {
|
|
125087
125136
|
};
|
|
125137
|
+
HTTP_ERROR_STATUS_PATTERN = /\bHTTP(?: error)?\s+(?<status>[1-5]\d{2})\b/i;
|
|
125138
|
+
hulyHttpStatusFromCause = (cause) => {
|
|
125139
|
+
if (!(cause instanceof Error)) return void 0;
|
|
125140
|
+
const statusText = HTTP_ERROR_STATUS_PATTERN.exec(cause.message)?.groups?.status;
|
|
125141
|
+
if (statusText === void 0) return void 0;
|
|
125142
|
+
return HulyHttpStatus.make(Number(statusText));
|
|
125143
|
+
};
|
|
125144
|
+
makeOperationConnectionError = (operation, cause) => {
|
|
125145
|
+
const httpStatus = hulyHttpStatusFromCause(cause);
|
|
125146
|
+
const message = `${operation} failed${httpStatus === void 0 ? "" : ` with HTTP ${httpStatus}`}`;
|
|
125147
|
+
return new HulyConnectionError({
|
|
125148
|
+
message,
|
|
125149
|
+
diagnostic: { operation, ...httpStatus === void 0 ? {} : { httpStatus } }
|
|
125150
|
+
});
|
|
125151
|
+
};
|
|
125088
125152
|
HulyDataInvalidError = class extends Schema_exports.TaggedError()("HulyDataInvalidError", {
|
|
125089
125153
|
operation: Schema_exports.String,
|
|
125090
125154
|
entity: Schema_exports.String,
|
|
@@ -125144,7 +125208,7 @@ var VERSION;
|
|
|
125144
125208
|
var init_version = __esm({
|
|
125145
125209
|
"src/version.ts"() {
|
|
125146
125210
|
"use strict";
|
|
125147
|
-
VERSION = true ? "0.
|
|
125211
|
+
VERSION = true ? "0.50.0" : "0.0.0-dev";
|
|
125148
125212
|
}
|
|
125149
125213
|
});
|
|
125150
125214
|
|
|
@@ -125489,7 +125553,7 @@ var init_errors_contacts = __esm({
|
|
|
125489
125553
|
{ identifier: Schema_exports.String, matches: AmbiguousMatchCount }
|
|
125490
125554
|
) {
|
|
125491
125555
|
get message() {
|
|
125492
|
-
return `Person identifier '${this.identifier}' matched ${this.matches} people; use
|
|
125556
|
+
return `Person identifier '${this.identifier}' matched ${this.matches} people; use a unique Person display name or email address instead`;
|
|
125493
125557
|
}
|
|
125494
125558
|
};
|
|
125495
125559
|
OrganizationNotFoundError = class extends Schema_exports.TaggedError()(
|
|
@@ -128260,7 +128324,7 @@ var init_tool_responses = __esm({
|
|
|
128260
128324
|
});
|
|
128261
128325
|
|
|
128262
128326
|
// src/mcp/error-mapping.ts
|
|
128263
|
-
var INVALID_PARAMS_TAGS, INTERNAL_ERROR_PREFIX, hulyUnavailableMessage, mapDomainErrorToMcp, isClientResolutionError, clientResolutionFailure, mapClientResolutionErrorToMcp, mapClientResolutionCauseToMcp, clientResolutionErrorMessage, clientResolutionCauseMessage, mapParseErrorToMcp, mapParseCauseToMcp, mapDomainCauseToMcp;
|
|
128327
|
+
var INVALID_PARAMS_TAGS, INTERNAL_ERROR_PREFIX, CONNECTION_ERROR_GUIDANCE, hulyConnectionMessage, hulyUnavailableMessage, mapDomainErrorToMcp, isClientResolutionError, clientResolutionFailure, redactResolutionDetail, mapClientResolutionErrorToMcp, mapClientResolutionCauseToMcp, clientResolutionErrorMessage, clientResolutionCauseMessage, mapParseErrorToMcp, mapParseCauseToMcp, mapDomainCauseToMcp;
|
|
128264
128328
|
var init_error_mapping = __esm({
|
|
128265
128329
|
"src/mcp/error-mapping.ts"() {
|
|
128266
128330
|
"use strict";
|
|
@@ -128472,9 +128536,13 @@ var init_error_mapping = __esm({
|
|
|
128472
128536
|
INTERNAL_ERROR_PREFIX = {
|
|
128473
128537
|
FileUploadError: "File upload error",
|
|
128474
128538
|
HulyStorageConfigError: "Storage configuration error",
|
|
128475
|
-
HulyConnectionError: "Connection error",
|
|
128476
128539
|
HulyAuthError: "Authentication error"
|
|
128477
128540
|
};
|
|
128541
|
+
CONNECTION_ERROR_GUIDANCE = "Verify HULY_URL, workspace, and network connectivity before retrying.";
|
|
128542
|
+
hulyConnectionMessage = (error3) => {
|
|
128543
|
+
const diagnostic = error3.diagnostic;
|
|
128544
|
+
return diagnostic === void 0 ? `Connection error while communicating with Huly. ${CONNECTION_ERROR_GUIDANCE}` : `Connection error while communicating with Huly: ${diagnostic.operation} failed${diagnostic.httpStatus === void 0 ? "" : ` with HTTP ${diagnostic.httpStatus}`}. ${CONNECTION_ERROR_GUIDANCE}`;
|
|
128545
|
+
};
|
|
128478
128546
|
hulyUnavailableMessage = (error3) => {
|
|
128479
128547
|
const failureGuidance = error3.failureKind === "timeout" ? " The request timed out; verify HULY_CONNECTION_TIMEOUT before retrying." : error3.failureKind === "dns" || error3.failureKind === "tls" ? " Verify the hostname, certificate, DNS, and proxy configuration before retrying." : "";
|
|
128480
128548
|
if (isDefaultHulyCloudOrigin(error3.endpointOrigin)) {
|
|
@@ -128487,12 +128555,7 @@ var init_error_mapping = __esm({
|
|
|
128487
128555
|
return createErrorResponse(hulyUnavailableMessage(error3), McpErrorCode.InternalError, error3._tag, warnings);
|
|
128488
128556
|
}
|
|
128489
128557
|
if (error3 instanceof HulyConnectionError) {
|
|
128490
|
-
return createErrorResponse(
|
|
128491
|
-
"Connection error while communicating with Huly. Verify HULY_URL, workspace, and network connectivity before retrying.",
|
|
128492
|
-
McpErrorCode.InternalError,
|
|
128493
|
-
error3._tag,
|
|
128494
|
-
warnings
|
|
128495
|
-
);
|
|
128558
|
+
return createErrorResponse(hulyConnectionMessage(error3), McpErrorCode.InternalError, error3._tag, warnings);
|
|
128496
128559
|
}
|
|
128497
128560
|
if (INVALID_PARAMS_TAGS.has(error3._tag)) {
|
|
128498
128561
|
return createErrorResponse(error3.message, McpErrorCode.InvalidParams, error3._tag, warnings);
|
|
@@ -128507,9 +128570,10 @@ var init_error_mapping = __esm({
|
|
|
128507
128570
|
if (!Cause_exports.isCause(error3)) return void 0;
|
|
128508
128571
|
return findRecoverableCauseFailure(error3, isClientResolutionError);
|
|
128509
128572
|
};
|
|
128573
|
+
redactResolutionDetail = (failure) => failure instanceof HulyConnectionError ? new HulyConnectionError({ message: "" }) : failure;
|
|
128510
128574
|
mapClientResolutionErrorToMcp = (error3) => {
|
|
128511
128575
|
const failure = clientResolutionFailure(error3);
|
|
128512
|
-
return failure === void 0 ? mapDomainErrorToMcp(new HulyError({ message: "Failed to initialize Huly clients" })) : mapDomainErrorToMcp(failure);
|
|
128576
|
+
return failure === void 0 ? mapDomainErrorToMcp(new HulyError({ message: "Failed to initialize Huly clients" })) : mapDomainErrorToMcp(redactResolutionDetail(failure));
|
|
128513
128577
|
};
|
|
128514
128578
|
mapClientResolutionCauseToMcp = (cause) => mapClientResolutionErrorToMcp(cause);
|
|
128515
128579
|
clientResolutionErrorMessage = (error3) => mapClientResolutionErrorToMcp(error3).content[0].text;
|
|
@@ -178671,39 +178735,36 @@ var init_client = __esm({
|
|
|
178671
178735
|
);
|
|
178672
178736
|
const markupUrlConfig = { refUrl: UrlString.make(refUrl), imageUrl: UrlString.make(imageUrl) };
|
|
178673
178737
|
const workbenchUrlConfig = { baseUrl: UrlString.make(config2.url), workspaceUrlSlug };
|
|
178674
|
-
const withClient = (op,
|
|
178675
|
-
try: () => op(client),
|
|
178676
|
-
catch: (e) => new HulyConnectionError({ message: `${errorMsg}: ${String(e)}`, cause: e })
|
|
178677
|
-
});
|
|
178738
|
+
const withClient = (op, operation) => Effect_exports.tryPromise({ try: () => op(client), catch: (error3) => makeOperationConnectionError(operation, error3) });
|
|
178678
178739
|
const operations = {
|
|
178679
178740
|
getAccountUuid: () => accountUuid,
|
|
178680
178741
|
getPrimarySocialId: () => primarySocialId,
|
|
178681
178742
|
getSocialIds: () => socialIds,
|
|
178682
178743
|
workbenchUrlConfig,
|
|
178683
178744
|
markupUrlConfig,
|
|
178684
|
-
findAll: (_class, query, options) => withClient((client2) => client2.findAll(_class, query, options), "findAll
|
|
178685
|
-
findOne: (_class, query, options) => withClient((client2) => client2.findOne(_class, query, options), "findOne
|
|
178745
|
+
findAll: (_class, query, options) => withClient((client2) => client2.findAll(_class, query, options), "findAll"),
|
|
178746
|
+
findOne: (_class, query, options) => withClient((client2) => client2.findOne(_class, query, options), "findOne"),
|
|
178686
178747
|
findAllInModel: (_class, query, options) => withClient(
|
|
178687
178748
|
(client2) => Promise.resolve(client2.getModel().findAllSync(_class, query, options)),
|
|
178688
|
-
"findAllInModel
|
|
178749
|
+
"findAllInModel"
|
|
178689
178750
|
),
|
|
178690
|
-
createDoc: (_class, space, attributes, id2) => withClient((client2) => client2.createDoc(_class, space, attributes, id2), "createDoc
|
|
178751
|
+
createDoc: (_class, space, attributes, id2) => withClient((client2) => client2.createDoc(_class, space, attributes, id2), "createDoc"),
|
|
178691
178752
|
createDocIfNotMatched: (_class, space, attributes, id2, matchClass, matchQuery, scope3) => withClient(async (client2) => {
|
|
178692
178753
|
const apply2 = client2.apply(scope3);
|
|
178693
178754
|
apply2.notMatch(matchClass, matchQuery);
|
|
178694
178755
|
await apply2.createDoc(_class, space, attributes, id2);
|
|
178695
178756
|
return (await apply2.commit()).result ? "applied" : "condition-not-met";
|
|
178696
|
-
}, "
|
|
178697
|
-
updateDoc: (_class, space, objectId, ops, retrieve) => withClient((client2) => client2.updateDoc(_class, space, objectId, ops, retrieve), "updateDoc
|
|
178757
|
+
}, "conditionalCreateDoc"),
|
|
178758
|
+
updateDoc: (_class, space, objectId, ops, retrieve) => withClient((client2) => client2.updateDoc(_class, space, objectId, ops, retrieve), "updateDoc"),
|
|
178698
178759
|
updateDocIfMatched: (_class, space, objectId, matchQuery, operations2, scope3) => withClient(async (client2) => {
|
|
178699
178760
|
const apply2 = client2.apply(scope3);
|
|
178700
178761
|
apply2.match(_class, matchQuery);
|
|
178701
178762
|
await apply2.updateDoc(_class, space, objectId, operations2);
|
|
178702
178763
|
return (await apply2.commit()).result ? "applied" : "condition-not-met";
|
|
178703
|
-
}, "
|
|
178764
|
+
}, "conditionalUpdateDoc"),
|
|
178704
178765
|
addCollection: (_class, space, attachedTo, attachedToClass, collection, attributes, id2) => withClient(
|
|
178705
178766
|
(client2) => client2.addCollection(_class, space, attachedTo, attachedToClass, collection, attributes, id2),
|
|
178706
|
-
"addCollection
|
|
178767
|
+
"addCollection"
|
|
178707
178768
|
),
|
|
178708
178769
|
updateCollection: (_class, space, objectId, attachedTo, attachedToClass, collection, operations2, retrieve) => withClient(
|
|
178709
178770
|
(client2) => client2.updateCollection(
|
|
@@ -178716,40 +178777,40 @@ var init_client = __esm({
|
|
|
178716
178777
|
operations2,
|
|
178717
178778
|
retrieve
|
|
178718
178779
|
),
|
|
178719
|
-
"updateCollection
|
|
178780
|
+
"updateCollection"
|
|
178720
178781
|
),
|
|
178721
178782
|
removeCollection: (_class, space, objectId, attachedTo, attachedToClass, collection) => withClient(
|
|
178722
178783
|
(client2) => client2.removeCollection(_class, space, objectId, attachedTo, attachedToClass, collection),
|
|
178723
|
-
"removeCollection
|
|
178784
|
+
"removeCollection"
|
|
178724
178785
|
),
|
|
178725
|
-
removeDoc: (_class, space, objectId) => withClient((client2) => client2.removeDoc(_class, space, objectId), "removeDoc
|
|
178786
|
+
removeDoc: (_class, space, objectId) => withClient((client2) => client2.removeDoc(_class, space, objectId), "removeDoc"),
|
|
178726
178787
|
removeDocIfMatched: (_class, space, objectId, matchQuery, scope3) => withClient(async (client2) => {
|
|
178727
178788
|
const apply2 = client2.apply(scope3);
|
|
178728
178789
|
apply2.match(_class, matchQuery);
|
|
178729
178790
|
await apply2.removeDoc(_class, space, objectId);
|
|
178730
178791
|
return (await apply2.commit()).result ? "applied" : "condition-not-met";
|
|
178731
|
-
}, "
|
|
178792
|
+
}, "conditionalRemoveDoc"),
|
|
178732
178793
|
createMixin: (objectId, objectClass, objectSpace, mixin, attributes) => withClient(
|
|
178733
178794
|
(client2) => client2.createMixin(objectId, objectClass, objectSpace, mixin, attributes),
|
|
178734
|
-
"createMixin
|
|
178795
|
+
"createMixin"
|
|
178735
178796
|
),
|
|
178736
178797
|
updateMixin: (objectId, objectClass, objectSpace, mixin, attributes) => withClient(
|
|
178737
178798
|
(client2) => client2.updateMixin(objectId, objectClass, objectSpace, mixin, attributes),
|
|
178738
|
-
"updateMixin
|
|
178799
|
+
"updateMixin"
|
|
178739
178800
|
),
|
|
178740
178801
|
uploadMarkup: (objectClass, objectId, objectAttr, markup, format5) => Effect_exports.tryPromise({
|
|
178741
178802
|
try: () => markupOps.uploadMarkup(objectClass, objectId, objectAttr, markup, format5),
|
|
178742
|
-
catch: (
|
|
178803
|
+
catch: (error3) => makeOperationConnectionError("uploadMarkup", error3)
|
|
178743
178804
|
}),
|
|
178744
178805
|
fetchMarkup: (objectClass, objectId, objectAttr, id2, format5) => Effect_exports.tryPromise({
|
|
178745
178806
|
try: () => markupOps.fetchMarkup(objectClass, objectId, objectAttr, id2, format5),
|
|
178746
|
-
catch: (
|
|
178807
|
+
catch: (error3) => makeOperationConnectionError("fetchMarkup", error3)
|
|
178747
178808
|
}),
|
|
178748
178809
|
updateMarkup: (objectClass, objectId, objectAttr, markup, format5) => Effect_exports.tryPromise({
|
|
178749
178810
|
try: () => markupOps.updateMarkup(objectClass, objectId, objectAttr, markup, format5),
|
|
178750
|
-
catch: (
|
|
178811
|
+
catch: (error3) => makeOperationConnectionError("updateMarkup", error3)
|
|
178751
178812
|
}),
|
|
178752
|
-
searchFulltext: (query, options) => withClient((client2) => client2.searchFulltext(query, options), "searchFulltext
|
|
178813
|
+
searchFulltext: (query, options) => withClient((client2) => client2.searchFulltext(query, options), "searchFulltext")
|
|
178753
178814
|
};
|
|
178754
178815
|
return operations;
|
|
178755
178816
|
})
|
|
@@ -179225,14 +179286,50 @@ var init_update_guards = __esm({
|
|
|
179225
179286
|
}
|
|
179226
179287
|
});
|
|
179227
179288
|
|
|
179289
|
+
// src/utils/assertions.ts
|
|
179290
|
+
var PAIR_LENGTH, AssertionError, assertExists, isExistent, assertAt, isNonEmpty3, isSingle, isPair, getOneOrNoneEffect;
|
|
179291
|
+
var init_assertions = __esm({
|
|
179292
|
+
"src/utils/assertions.ts"() {
|
|
179293
|
+
"use strict";
|
|
179294
|
+
init_dist();
|
|
179295
|
+
PAIR_LENGTH = 2;
|
|
179296
|
+
AssertionError = class extends Error {
|
|
179297
|
+
_tag = "AssertionError";
|
|
179298
|
+
constructor(message) {
|
|
179299
|
+
super(message);
|
|
179300
|
+
this.name = "AssertionError";
|
|
179301
|
+
}
|
|
179302
|
+
};
|
|
179303
|
+
assertExists = (value3, message) => {
|
|
179304
|
+
if (value3 === null || value3 === void 0) {
|
|
179305
|
+
throw new AssertionError(message ?? "Expected value to exist");
|
|
179306
|
+
}
|
|
179307
|
+
return value3;
|
|
179308
|
+
};
|
|
179309
|
+
isExistent = (value3) => value3 !== null && value3 !== void 0;
|
|
179310
|
+
assertAt = (arr, index2, message) => {
|
|
179311
|
+
return assertExists(arr[index2], message ?? `Expected array item at index ${index2}`);
|
|
179312
|
+
};
|
|
179313
|
+
isNonEmpty3 = (arr) => arr.length > 0;
|
|
179314
|
+
isSingle = (arr) => arr.length === 1;
|
|
179315
|
+
isPair = (arr) => arr.length === PAIR_LENGTH;
|
|
179316
|
+
getOneOrNoneEffect = (arr, onTooMany) => {
|
|
179317
|
+
if (arr.length === 0) return Effect_exports.succeed(Option_exports.none());
|
|
179318
|
+
if (isSingle(arr)) return Effect_exports.succeed(Option_exports.some(arr[0]));
|
|
179319
|
+
return Effect_exports.fail(onTooMany(arr));
|
|
179320
|
+
};
|
|
179321
|
+
}
|
|
179322
|
+
});
|
|
179323
|
+
|
|
179228
179324
|
// src/huly/operations/contacts-shared.ts
|
|
179229
|
-
var import_core38, isEmailIdentifier, findPersonById, findPersonByEmail, batchGetEmailsForPersons, findPersonIdsByEmailSearch, findPersonBySocialIdentityEmail, findPersonByExactEmail, findPersonByExactName, findPersonByExactEmailOrName, findPersonByIdOrExactEmailOrName, resolveEmployeeAccountUuid, findPersonByEmailOrName;
|
|
179325
|
+
var import_core38, isEmailIdentifier, findPersonById, findPersonByEmail, batchGetEmailsForPersons, findPersonIdsByEmailSearch, findPersonIdsByEmailChannelSearch, findPersonIdsByExactEmailSources, loadPeopleByIds, findPeopleByExactName, findPeopleByNameSearch, findPersonBySocialIdentityEmail, findPersonByExactEmail, findPersonByExactName, findPersonByExactEmailOrName, findPersonByIdOrExactEmailOrName, resolveEmployeeAccountUuid, findPersonByEmailOrName;
|
|
179230
179326
|
var init_contacts_shared = __esm({
|
|
179231
179327
|
"src/huly/operations/contacts-shared.ts"() {
|
|
179232
179328
|
"use strict";
|
|
179233
179329
|
import_core38 = __toESM(require_lib6(), 1);
|
|
179234
179330
|
init_dist();
|
|
179235
179331
|
init_shared();
|
|
179332
|
+
init_assertions();
|
|
179236
179333
|
init_errors4();
|
|
179237
179334
|
init_huly_plugins();
|
|
179238
179335
|
init_query_helpers();
|
|
@@ -179268,24 +179365,60 @@ var init_contacts_shared = __esm({
|
|
|
179268
179365
|
return emailMap;
|
|
179269
179366
|
});
|
|
179270
179367
|
findPersonIdsByEmailSearch = (client, emailSearch) => Effect_exports.gen(function* () {
|
|
179271
|
-
const
|
|
179272
|
-
|
|
179273
|
-
client.findAll(
|
|
179274
|
-
contact.class.Channel,
|
|
179275
|
-
hulyQuery({ provider: contact.channelProvider.Email, value: value3 })
|
|
179276
|
-
),
|
|
179368
|
+
const [channelPersonIds, socialIdentities] = yield* Effect_exports.all([
|
|
179369
|
+
findPersonIdsByEmailChannelSearch(client, emailSearch),
|
|
179277
179370
|
client.findAll(
|
|
179278
179371
|
contact.class.SocialIdentity,
|
|
179279
|
-
hulyQuery({
|
|
179372
|
+
hulyQuery({
|
|
179373
|
+
type: import_core38.SocialIdType.EMAIL,
|
|
179374
|
+
value: { $like: `%${escapeLikeWildcards(emailSearch)}%` }
|
|
179375
|
+
})
|
|
179280
179376
|
)
|
|
179281
179377
|
]);
|
|
179282
179378
|
return [
|
|
179283
|
-
.../* @__PURE__ */ new Set([
|
|
179284
|
-
...channels.map((channel) => toRef(channel.attachedTo)),
|
|
179285
|
-
...socialIdentities.map((identity2) => toRef(identity2.attachedTo))
|
|
179286
|
-
])
|
|
179379
|
+
.../* @__PURE__ */ new Set([...channelPersonIds, ...socialIdentities.map((identity2) => toRef(identity2.attachedTo))])
|
|
179287
179380
|
];
|
|
179288
179381
|
});
|
|
179382
|
+
findPersonIdsByEmailChannelSearch = (client, emailSearch) => Effect_exports.map(
|
|
179383
|
+
client.findAll(
|
|
179384
|
+
contact.class.Channel,
|
|
179385
|
+
hulyQuery({
|
|
179386
|
+
provider: contact.channelProvider.Email,
|
|
179387
|
+
value: { $like: `%${escapeLikeWildcards(emailSearch)}%` }
|
|
179388
|
+
})
|
|
179389
|
+
),
|
|
179390
|
+
(channels) => [...new Set(channels.map((channel) => toRef(channel.attachedTo)))]
|
|
179391
|
+
);
|
|
179392
|
+
findPersonIdsByExactEmailSources = (client, email3) => Effect_exports.map(
|
|
179393
|
+
Effect_exports.all([
|
|
179394
|
+
client.findAll(
|
|
179395
|
+
contact.class.SocialIdentity,
|
|
179396
|
+
hulyQuery({ type: import_core38.SocialIdType.EMAIL, value: email3 })
|
|
179397
|
+
),
|
|
179398
|
+
client.findAll(
|
|
179399
|
+
contact.class.Channel,
|
|
179400
|
+
hulyQuery({ value: email3, provider: contact.channelProvider.Email })
|
|
179401
|
+
)
|
|
179402
|
+
]),
|
|
179403
|
+
([socialIdentities, channels]) => [
|
|
179404
|
+
.../* @__PURE__ */ new Set([
|
|
179405
|
+
...socialIdentities.map((identity2) => toRef(identity2.attachedTo)),
|
|
179406
|
+
...channels.map((channel) => toRef(channel.attachedTo))
|
|
179407
|
+
])
|
|
179408
|
+
]
|
|
179409
|
+
);
|
|
179410
|
+
loadPeopleByIds = (client, personIds) => {
|
|
179411
|
+
const uniqueIds = [...new Set(personIds)];
|
|
179412
|
+
return uniqueIds.length === 0 ? Effect_exports.succeed([]) : Effect_exports.map(
|
|
179413
|
+
client.findAll(contact.class.Person, hulyQuery({ _id: { $in: uniqueIds } })),
|
|
179414
|
+
(people) => [...new Map(people.map((person) => [person._id, person])).values()]
|
|
179415
|
+
);
|
|
179416
|
+
};
|
|
179417
|
+
findPeopleByExactName = (client, name) => client.findAll(contact.class.Person, hulyQuery({ name }));
|
|
179418
|
+
findPeopleByNameSearch = (client, nameSearch) => client.findAll(
|
|
179419
|
+
contact.class.Person,
|
|
179420
|
+
hulyQuery({ name: { $like: `%${escapeLikeWildcards(nameSearch)}%` } })
|
|
179421
|
+
);
|
|
179289
179422
|
findPersonBySocialIdentityEmail = (client, email3) => Effect_exports.gen(function* () {
|
|
179290
179423
|
const identity2 = yield* client.findOne(contact.class.SocialIdentity, {
|
|
179291
179424
|
type: import_core38.SocialIdType.EMAIL,
|
|
@@ -179295,43 +179428,23 @@ var init_contacts_shared = __esm({
|
|
|
179295
179428
|
return yield* client.findOne(contact.class.Person, { _id: identity2.attachedTo });
|
|
179296
179429
|
});
|
|
179297
179430
|
findPersonByExactEmail = (client, email3) => Effect_exports.gen(function* () {
|
|
179298
|
-
const
|
|
179299
|
-
|
|
179300
|
-
|
|
179301
|
-
|
|
179302
|
-
|
|
179303
|
-
|
|
179304
|
-
|
|
179305
|
-
|
|
179306
|
-
const personIds = [
|
|
179307
|
-
.../* @__PURE__ */ new Set([
|
|
179308
|
-
...socialIdentities.map((identity2) => identity2.attachedTo),
|
|
179309
|
-
...channels.map((channel) => channel.attachedTo)
|
|
179310
|
-
])
|
|
179311
|
-
];
|
|
179312
|
-
if (personIds.length === 0) {
|
|
179313
|
-
return void 0;
|
|
179314
|
-
}
|
|
179315
|
-
const persons = yield* client.findAll(contact.class.Person, {
|
|
179316
|
-
_id: { $in: personIds.map(toRef) }
|
|
179317
|
-
});
|
|
179318
|
-
if (persons.length === 0) {
|
|
179319
|
-
return void 0;
|
|
179320
|
-
}
|
|
179321
|
-
if (persons.length > 1) {
|
|
179322
|
-
return yield* new PersonIdentifierAmbiguousError({ identifier: email3, matches: Count.make(persons.length) });
|
|
179323
|
-
}
|
|
179324
|
-
return persons[0];
|
|
179431
|
+
const personIds = yield* findPersonIdsByExactEmailSources(client, email3);
|
|
179432
|
+
const persons = yield* loadPeopleByIds(client, personIds);
|
|
179433
|
+
return Option_exports.getOrUndefined(
|
|
179434
|
+
yield* getOneOrNoneEffect(
|
|
179435
|
+
persons,
|
|
179436
|
+
(matches) => new PersonIdentifierAmbiguousError({ identifier: email3, matches: Count.make(matches.length) })
|
|
179437
|
+
)
|
|
179438
|
+
);
|
|
179325
179439
|
});
|
|
179326
179440
|
findPersonByExactName = (client, name) => Effect_exports.gen(function* () {
|
|
179327
|
-
const persons = yield* client
|
|
179328
|
-
|
|
179329
|
-
|
|
179330
|
-
|
|
179331
|
-
|
|
179332
|
-
|
|
179333
|
-
|
|
179334
|
-
return persons[0];
|
|
179441
|
+
const persons = yield* findPeopleByExactName(client, name);
|
|
179442
|
+
return Option_exports.getOrUndefined(
|
|
179443
|
+
yield* getOneOrNoneEffect(
|
|
179444
|
+
persons,
|
|
179445
|
+
(matches) => new PersonIdentifierAmbiguousError({ identifier: name, matches: Count.make(matches.length) })
|
|
179446
|
+
)
|
|
179447
|
+
);
|
|
179335
179448
|
});
|
|
179336
179449
|
findPersonByExactEmailOrName = (client, identifier2) => isEmailIdentifier(identifier2) ? findPersonByExactEmail(client, identifier2) : findPersonByExactName(client, identifier2);
|
|
179337
179450
|
findPersonByIdOrExactEmailOrName = (client, identifier2) => Effect_exports.gen(function* () {
|
|
@@ -179384,35 +179497,6 @@ var init_contacts_shared = __esm({
|
|
|
179384
179497
|
}
|
|
179385
179498
|
});
|
|
179386
179499
|
|
|
179387
|
-
// src/utils/assertions.ts
|
|
179388
|
-
var PAIR_LENGTH, AssertionError, assertExists, isExistent, assertAt, isNonEmpty3, isSingle, isPair;
|
|
179389
|
-
var init_assertions = __esm({
|
|
179390
|
-
"src/utils/assertions.ts"() {
|
|
179391
|
-
"use strict";
|
|
179392
|
-
PAIR_LENGTH = 2;
|
|
179393
|
-
AssertionError = class extends Error {
|
|
179394
|
-
_tag = "AssertionError";
|
|
179395
|
-
constructor(message) {
|
|
179396
|
-
super(message);
|
|
179397
|
-
this.name = "AssertionError";
|
|
179398
|
-
}
|
|
179399
|
-
};
|
|
179400
|
-
assertExists = (value3, message) => {
|
|
179401
|
-
if (value3 === null || value3 === void 0) {
|
|
179402
|
-
throw new AssertionError(message ?? "Expected value to exist");
|
|
179403
|
-
}
|
|
179404
|
-
return value3;
|
|
179405
|
-
};
|
|
179406
|
-
isExistent = (value3) => value3 !== null && value3 !== void 0;
|
|
179407
|
-
assertAt = (arr, index2, message) => {
|
|
179408
|
-
return assertExists(arr[index2], message ?? `Expected array item at index ${index2}`);
|
|
179409
|
-
};
|
|
179410
|
-
isNonEmpty3 = (arr) => arr.length > 0;
|
|
179411
|
-
isSingle = (arr) => arr.length === 1;
|
|
179412
|
-
isPair = (arr) => arr.length === PAIR_LENGTH;
|
|
179413
|
-
}
|
|
179414
|
-
});
|
|
179415
|
-
|
|
179416
179500
|
// src/huly/operations/spaces-shared.ts
|
|
179417
179501
|
var import_core39, spaceClass, sortStrings, uniqueSorted, mergeUniqueSortedAccountUuids, removeAccountUuids, arraysEqual, optionalString, optionalObjectClassName, RoleAssignmentStorageSchema, RoleAssignmentStorageObjectSchema, parseRoleAssignmentStorageObject, validStoredAccountUuid, parsedSpaceRoleAssignmentEntry, spaceRoleAssignmentSource, roleAssignmentsMalformedError, readSpaceRoleAssignmentEntries, spaceRoleAssignmentEntries, hasSpaceRoleAssignmentMixin, strictSpaceRoleAssignments, roleAssignmentDegradationMessage, spaceRoleAssignmentsMixin, applySpaceFilters, findSpace, spaceMapById, updateSpaceDoc, resolveMembers;
|
|
179418
179502
|
var init_spaces_shared = __esm({
|
|
@@ -183437,10 +183521,7 @@ var init_workspace_client = __esm({
|
|
|
183437
183521
|
{ url: config2.url, auth: config2.auth, workspace: config2.workspace },
|
|
183438
183522
|
sdk
|
|
183439
183523
|
);
|
|
183440
|
-
const withClient = (op,
|
|
183441
|
-
try: () => op(client),
|
|
183442
|
-
catch: (e) => new HulyConnectionError({ message: `${errorMsg}: ${String(e)}`, cause: e })
|
|
183443
|
-
});
|
|
183524
|
+
const withClient = (op, operation) => Effect_exports.tryPromise({ try: () => op(client), catch: (error3) => makeOperationConnectionError(operation, error3) });
|
|
183444
183525
|
const accessLinkIdentityOptions = (options) => ({
|
|
183445
183526
|
...options.firstName !== void 0 ? { firstName: options.firstName } : {},
|
|
183446
183527
|
...options.lastName !== void 0 ? { lastName: options.lastName } : {},
|
|
@@ -183454,25 +183535,19 @@ var init_workspace_client = __esm({
|
|
|
183454
183535
|
});
|
|
183455
183536
|
const toAccountClientAccessLinkOptions = (options) => options === void 0 ? void 0 : { ...accessLinkIdentityOptions(options), ...accessLinkTimingOptions(options) };
|
|
183456
183537
|
const operations = {
|
|
183457
|
-
getWorkspaceMembers: () => withClient((c) => c.getWorkspaceMembers(), "
|
|
183458
|
-
getPersonInfo: (account) => withClient((c) => c.getPersonInfo(account), "
|
|
183459
|
-
updateWorkspaceRole: (account, role) => withClient((c) => c.updateWorkspaceRole(account, role), "
|
|
183460
|
-
getWorkspaceInfo: (updateLastVisit) => withClient((c) => c.getWorkspaceInfo(updateLastVisit), "
|
|
183461
|
-
getUserWorkspaces: () => withClient((c) => c.getUserWorkspaces(), "
|
|
183462
|
-
createWorkspace: (name, region) => withClient((c) => c.createWorkspace(name, region), "
|
|
183463
|
-
deleteWorkspace: () => withClient((c) => c.deleteWorkspace(), "
|
|
183464
|
-
getUserProfile: (personUuid) => withClient((c) => c.getUserProfile(personUuid), "
|
|
183465
|
-
setMyProfile: (profile) => withClient((c) => c.setMyProfile(profile), "
|
|
183466
|
-
createAccessLink: (role, options) => withClient(
|
|
183467
|
-
|
|
183468
|
-
|
|
183469
|
-
),
|
|
183470
|
-
updateAllowReadOnlyGuests: (readOnlyGuestsAllowed) => withClient(
|
|
183471
|
-
(c) => c.updateAllowReadOnlyGuests(readOnlyGuestsAllowed),
|
|
183472
|
-
"Failed to update read-only guest setting"
|
|
183473
|
-
),
|
|
183474
|
-
updateAllowGuestSignUp: (guestSignUpAllowed) => withClient((c) => c.updateAllowGuestSignUp(guestSignUpAllowed), "Failed to update guest sign-up setting"),
|
|
183475
|
-
getRegionInfo: () => withClient((c) => c.getRegionInfo(), "Failed to get region info")
|
|
183538
|
+
getWorkspaceMembers: () => withClient((c) => c.getWorkspaceMembers(), "getWorkspaceMembers"),
|
|
183539
|
+
getPersonInfo: (account) => withClient((c) => c.getPersonInfo(account), "getPersonInfo"),
|
|
183540
|
+
updateWorkspaceRole: (account, role) => withClient((c) => c.updateWorkspaceRole(account, role), "updateWorkspaceRole"),
|
|
183541
|
+
getWorkspaceInfo: (updateLastVisit) => withClient((c) => c.getWorkspaceInfo(updateLastVisit), "getWorkspaceInfo"),
|
|
183542
|
+
getUserWorkspaces: () => withClient((c) => c.getUserWorkspaces(), "getUserWorkspaces"),
|
|
183543
|
+
createWorkspace: (name, region) => withClient((c) => c.createWorkspace(name, region), "createWorkspace"),
|
|
183544
|
+
deleteWorkspace: () => withClient((c) => c.deleteWorkspace(), "deleteWorkspace"),
|
|
183545
|
+
getUserProfile: (personUuid) => withClient((c) => c.getUserProfile(personUuid), "getUserProfile"),
|
|
183546
|
+
setMyProfile: (profile) => withClient((c) => c.setMyProfile(profile), "setMyProfile"),
|
|
183547
|
+
createAccessLink: (role, options) => withClient((c) => c.createAccessLink(role, toAccountClientAccessLinkOptions(options)), "createAccessLink"),
|
|
183548
|
+
updateAllowReadOnlyGuests: (readOnlyGuestsAllowed) => withClient((c) => c.updateAllowReadOnlyGuests(readOnlyGuestsAllowed), "updateAllowReadOnlyGuests"),
|
|
183549
|
+
updateAllowGuestSignUp: (guestSignUpAllowed) => withClient((c) => c.updateAllowGuestSignUp(guestSignUpAllowed), "updateAllowGuestSignUp"),
|
|
183550
|
+
getRegionInfo: () => withClient((c) => c.getRegionInfo(), "getRegionInfo")
|
|
183476
183551
|
};
|
|
183477
183552
|
return operations;
|
|
183478
183553
|
})
|
|
@@ -193821,7 +193896,7 @@ var init_persons = __esm({
|
|
|
193821
193896
|
};
|
|
193822
193897
|
applyPersonEmailSearch = (client, query, emailSearch) => Effect_exports.gen(function* () {
|
|
193823
193898
|
if (emailSearch === void 0 || emailSearch === "") return true;
|
|
193824
|
-
const matchingPersonIds = yield* findPersonIdsByEmailSearch(client, emailSearch);
|
|
193899
|
+
const matchingPersonIds = yield* findPersonIdsByEmailSearch(client, NonEmptyString2.make(emailSearch));
|
|
193825
193900
|
if (matchingPersonIds.length === 0) return false;
|
|
193826
193901
|
query._id = { $in: matchingPersonIds };
|
|
193827
193902
|
return true;
|
|
@@ -199859,319 +199934,947 @@ var init_issues_parent = __esm({
|
|
|
199859
199934
|
}
|
|
199860
199935
|
});
|
|
199861
199936
|
|
|
199862
|
-
// src/huly/operations/
|
|
199863
|
-
var
|
|
199864
|
-
var
|
|
199865
|
-
"src/huly/operations/
|
|
199937
|
+
// src/huly/operations/issue-native-references.ts
|
|
199938
|
+
var renderIssueDescriptionForWrite;
|
|
199939
|
+
var init_issue_native_references = __esm({
|
|
199940
|
+
"src/huly/operations/issue-native-references.ts"() {
|
|
199866
199941
|
"use strict";
|
|
199867
|
-
import_core87 = __toESM(require_lib6(), 1);
|
|
199868
|
-
import_tracker3 = __toESM(require_lib25(), 1);
|
|
199869
199942
|
init_dist();
|
|
199870
|
-
|
|
199871
|
-
|
|
199872
|
-
|
|
199873
|
-
|
|
199874
|
-
|
|
199875
|
-
|
|
199876
|
-
|
|
199877
|
-
|
|
199878
|
-
issueTargetClass = TagTargetClass.make(String(tracker.class.Issue));
|
|
199879
|
-
addLabel = (params2) => Effect_exports.gen(function* () {
|
|
199880
|
-
const { issue: issue2, project } = yield* findProjectAndIssue(params2);
|
|
199881
|
-
const labelTitle = TagIdentifier.make(params2.label.trim());
|
|
199882
|
-
const tag2 = yield* ensureTagElement({
|
|
199883
|
-
targetClass: issueTargetClass,
|
|
199884
|
-
titleOrId: labelTitle,
|
|
199885
|
-
color: params2.color,
|
|
199886
|
-
fallbackCategory: tracker.category.Other
|
|
199887
|
-
});
|
|
199888
|
-
const result3 = yield* attachTagReference({
|
|
199889
|
-
tag: tag2,
|
|
199890
|
-
objectId: issue2._id,
|
|
199891
|
-
objectClass: tracker.class.Issue,
|
|
199892
|
-
space: project._id,
|
|
199893
|
-
collection: "labels",
|
|
199894
|
-
matchTitleCaseInsensitive: true
|
|
199895
|
-
});
|
|
199896
|
-
return { identifier: IssueIdentifier.make(issue2.identifier), labelAdded: result3.attached };
|
|
199897
|
-
});
|
|
199898
|
-
moveIssue = (params2) => Effect_exports.gen(function* () {
|
|
199899
|
-
const { client, issue: issue2, project } = yield* findProjectAndIssue(params2);
|
|
199900
|
-
const oldParentIsIssue = hasConcreteIssueParent(issue2);
|
|
199901
|
-
const newParentParam = params2.newParent;
|
|
199902
|
-
const target = newParentParam !== null ? yield* Effect_exports.gen(function* () {
|
|
199903
|
-
const parentIssue = yield* findIssueInProject(client, project, newParentParam);
|
|
199904
|
-
return {
|
|
199905
|
-
_tag: "Child",
|
|
199906
|
-
identifier: IssueIdentifier.make(parentIssue.identifier),
|
|
199907
|
-
issue: parentIssue,
|
|
199908
|
-
parent: childIssueParent(parentIssue, project._id)
|
|
199909
|
-
};
|
|
199910
|
-
}) : { _tag: "TopLevel", parent: topLevelIssueParent() };
|
|
199911
|
-
if (target._tag === "Child") {
|
|
199912
|
-
yield* attachIssueChild(client, project._id, issue2._id, target.issue, {});
|
|
199913
|
-
} else {
|
|
199914
|
-
yield* client.updateDoc(tracker.class.Issue, project._id, issue2._id, {
|
|
199915
|
-
attachedTo: toRef(target.parent.attachedTo),
|
|
199916
|
-
attachedToClass: target.parent.attachedToClass,
|
|
199917
|
-
collection: target.parent.collection,
|
|
199918
|
-
parents: target.parent.parents
|
|
199919
|
-
});
|
|
199920
|
-
}
|
|
199921
|
-
if (oldParentIsIssue) {
|
|
199922
|
-
yield* client.updateDoc(
|
|
199923
|
-
tracker.class.Issue,
|
|
199924
|
-
project._id,
|
|
199925
|
-
// issue.attachedTo is Ref<Doc>; for sub-issues it points to the parent issue.
|
|
199926
|
-
// Cast needed because updateDoc expects Ref<HulyIssue> but attachedTo is Ref<Doc>.
|
|
199927
|
-
toRef(issue2.attachedTo),
|
|
199928
|
-
{ $inc: { subIssues: -1 } }
|
|
199929
|
-
);
|
|
199930
|
-
}
|
|
199931
|
-
if (issue2.subIssues > 0) {
|
|
199932
|
-
yield* updateDescendantParents(client, project._id, issue2, target.parent.parents);
|
|
199933
|
-
}
|
|
199934
|
-
const result3 = { identifier: IssueIdentifier.make(issue2.identifier), moved: true };
|
|
199935
|
-
if (target._tag === "Child") {
|
|
199936
|
-
return { ...result3, newParent: target.identifier };
|
|
199937
|
-
}
|
|
199938
|
-
return result3;
|
|
199939
|
-
});
|
|
199940
|
-
updateDescendantParents = (client, spaceId, parentIssue, parentNewParents) => Effect_exports.gen(function* () {
|
|
199941
|
-
const thisParentInfo = {
|
|
199942
|
-
parentId: parentIssue._id,
|
|
199943
|
-
identifier: parentIssue.identifier,
|
|
199944
|
-
parentTitle: parentIssue.title,
|
|
199945
|
-
space: spaceId
|
|
199946
|
-
};
|
|
199947
|
-
const children = yield* client.findAll(
|
|
199948
|
-
tracker.class.Issue,
|
|
199949
|
-
hulyQuery({ attachedTo: parentIssue._id, space: spaceId })
|
|
199950
|
-
);
|
|
199951
|
-
for (const child of children) {
|
|
199952
|
-
const childNewParents = [...parentNewParents, thisParentInfo];
|
|
199953
|
-
yield* client.updateDoc(tracker.class.Issue, spaceId, child._id, { parents: childNewParents });
|
|
199954
|
-
if (child.subIssues > 0) {
|
|
199955
|
-
yield* updateDescendantParents(client, spaceId, child, childNewParents);
|
|
199956
|
-
}
|
|
199943
|
+
init_client();
|
|
199944
|
+
init_errors4();
|
|
199945
|
+
init_native_reference_markup();
|
|
199946
|
+
renderIssueDescriptionForWrite = (description) => Effect_exports.gen(function* () {
|
|
199947
|
+
const client = yield* HulyClient;
|
|
199948
|
+
const rendered = renderMarkdownWithNativeReferencesForWrite(description, client.markupUrlConfig, "description");
|
|
199949
|
+
if (rendered._tag === "malformed") {
|
|
199950
|
+
return yield* new IssueReferenceError({ reason: rendered.reason });
|
|
199957
199951
|
}
|
|
199952
|
+
return rendered.rendered;
|
|
199958
199953
|
});
|
|
199959
199954
|
}
|
|
199960
199955
|
});
|
|
199961
199956
|
|
|
199962
|
-
// src/huly/operations/issue-
|
|
199963
|
-
var
|
|
199964
|
-
var
|
|
199965
|
-
"src/huly/operations/issue-
|
|
199957
|
+
// src/huly/operations/issue-assignee-resolution.ts
|
|
199958
|
+
var findExactPeople, findFuzzyPeople, oneAssigneeOrNone, findIssueAssignee;
|
|
199959
|
+
var init_issue_assignee_resolution = __esm({
|
|
199960
|
+
"src/huly/operations/issue-assignee-resolution.ts"() {
|
|
199966
199961
|
"use strict";
|
|
199967
199962
|
init_dist();
|
|
199968
|
-
|
|
199969
|
-
|
|
199970
|
-
|
|
199963
|
+
init_shared();
|
|
199964
|
+
init_assertions();
|
|
199965
|
+
init_errors4();
|
|
199971
199966
|
init_huly_plugins();
|
|
199972
199967
|
init_contacts_shared();
|
|
199973
199968
|
init_query_helpers();
|
|
199974
199969
|
init_sdk_boundary();
|
|
199975
|
-
|
|
199976
|
-
|
|
199977
|
-
|
|
199978
|
-
|
|
199979
|
-
|
|
199980
|
-
|
|
199981
|
-
|
|
199982
|
-
|
|
199970
|
+
findExactPeople = Effect_exports.fn("IssueAssigneeResolution.findExactPeople")(function* (client, identifier2) {
|
|
199971
|
+
const [emailPersonIds, namedPeople, profiles] = yield* Effect_exports.all([
|
|
199972
|
+
findPersonIdsByExactEmailSources(client, identifier2),
|
|
199973
|
+
findPeopleByExactName(client, identifier2),
|
|
199974
|
+
client.findAll(
|
|
199975
|
+
toClassRef(contact.class.UserProfile),
|
|
199976
|
+
hulyQuery({ title: identifier2 })
|
|
199977
|
+
)
|
|
199978
|
+
]);
|
|
199979
|
+
return yield* loadPeopleByIds(client, [
|
|
199980
|
+
...emailPersonIds,
|
|
199981
|
+
...namedPeople.map((person) => person._id),
|
|
199982
|
+
...profiles.map((profile) => profile.person)
|
|
199983
|
+
]);
|
|
199983
199984
|
});
|
|
199984
|
-
|
|
199985
|
-
|
|
199986
|
-
|
|
199987
|
-
|
|
199988
|
-
|
|
199989
|
-
|
|
199990
|
-
|
|
199991
|
-
|
|
199992
|
-
|
|
199993
|
-
|
|
199994
|
-
|
|
199995
|
-
|
|
199996
|
-
);
|
|
199997
|
-
const
|
|
199998
|
-
|
|
199999
|
-
|
|
200000
|
-
);
|
|
200001
|
-
const personById = new Map(persons.map((person) => [person._id, person]));
|
|
200002
|
-
const index2 = /* @__PURE__ */ new Map();
|
|
200003
|
-
for (const identity2 of identities) {
|
|
200004
|
-
const person = personById.get(identity2.attachedTo);
|
|
200005
|
-
if (person === void 0) continue;
|
|
200006
|
-
const parsed = creatorRef(person, emailByPerson);
|
|
200007
|
-
if (Option_exports.isSome(parsed)) index2.set(identity2._id, parsed.value);
|
|
200008
|
-
}
|
|
200009
|
-
const unresolvedCount = creatorIds.filter((creatorId) => !index2.has(creatorId)).length;
|
|
200010
|
-
if (unresolvedCount > 0) {
|
|
200011
|
-
const diagnostics = yield* Diagnostics;
|
|
200012
|
-
yield* diagnostics.warnAgent({
|
|
200013
|
-
code: IssueCreatorMetadataDegradedWarningCode,
|
|
200014
|
-
message: `${unresolvedCount} unresolved issue creator reference(s) were omitted from issue results.`
|
|
200015
|
-
});
|
|
200016
|
-
}
|
|
200017
|
-
return index2;
|
|
199985
|
+
findFuzzyPeople = Effect_exports.fn("IssueAssigneeResolution.findFuzzyPeople")(function* (client, identifier2) {
|
|
199986
|
+
const [emailPersonIds, namedPeople] = yield* Effect_exports.all([
|
|
199987
|
+
findPersonIdsByEmailChannelSearch(client, identifier2),
|
|
199988
|
+
findPeopleByNameSearch(client, identifier2)
|
|
199989
|
+
]);
|
|
199990
|
+
return yield* loadPeopleByIds(client, [...emailPersonIds, ...namedPeople.map((person) => person._id)]);
|
|
199991
|
+
});
|
|
199992
|
+
oneAssigneeOrNone = (identifier2, people) => getOneOrNoneEffect(
|
|
199993
|
+
people,
|
|
199994
|
+
(matches) => new PersonIdentifierAmbiguousError({ identifier: identifier2, matches: Count.make(matches.length) })
|
|
199995
|
+
);
|
|
199996
|
+
findIssueAssignee = Effect_exports.fn("IssueAssigneeResolution.findIssueAssignee")(function* (client, identifier2) {
|
|
199997
|
+
const exactPeople = yield* findExactPeople(client, identifier2);
|
|
199998
|
+
const exactPerson = yield* oneAssigneeOrNone(identifier2, exactPeople);
|
|
199999
|
+
if (Option_exports.isSome(exactPerson)) return exactPerson;
|
|
200000
|
+
return yield* oneAssigneeOrNone(identifier2, yield* findFuzzyPeople(client, identifier2));
|
|
200018
200001
|
});
|
|
200019
200002
|
}
|
|
200020
200003
|
});
|
|
200021
200004
|
|
|
200022
|
-
// src/huly/operations/
|
|
200023
|
-
var
|
|
200024
|
-
var
|
|
200025
|
-
"src/huly/operations/
|
|
200005
|
+
// src/huly/operations/issues-write-shared.ts
|
|
200006
|
+
var resolveAssignee, TASK_TYPE_DISCOVERY_HINT, taskTypeMatches, describeTaskTypeOptions, mergeTaskTypes2, resolveTaskTypeWorkflow, validStatusNames, resolveStatusForTaskType, chooseStatusForTaskType;
|
|
200007
|
+
var init_issues_write_shared = __esm({
|
|
200008
|
+
"src/huly/operations/issues-write-shared.ts"() {
|
|
200026
200009
|
"use strict";
|
|
200027
200010
|
init_dist();
|
|
200028
|
-
|
|
200029
|
-
|
|
200030
|
-
init_diagnostics();
|
|
200011
|
+
init_normalize();
|
|
200012
|
+
init_errors4();
|
|
200031
200013
|
init_huly_plugins();
|
|
200014
|
+
init_issue_assignee_resolution();
|
|
200032
200015
|
init_query_helpers();
|
|
200033
|
-
|
|
200034
|
-
|
|
200035
|
-
|
|
200036
|
-
|
|
200037
|
-
|
|
200038
|
-
|
|
200039
|
-
}).annotate({
|
|
200040
|
-
title: "IssueLabelAttachmentBoundary",
|
|
200041
|
-
description: "Partial Huly TagReference fields used to project issue labels. Missing or malformed presentation fields are handled by stable projection rules."
|
|
200016
|
+
resolveAssignee = (client, assigneeIdentifier) => Effect_exports.gen(function* () {
|
|
200017
|
+
const person = yield* findIssueAssignee(client, assigneeIdentifier);
|
|
200018
|
+
return yield* Option_exports.match(person, {
|
|
200019
|
+
onNone: () => Effect_exports.fail(new PersonNotFoundError({ identifier: assigneeIdentifier })),
|
|
200020
|
+
onSome: Effect_exports.succeed
|
|
200021
|
+
});
|
|
200042
200022
|
});
|
|
200043
|
-
|
|
200044
|
-
|
|
200045
|
-
|
|
200046
|
-
|
|
200047
|
-
|
|
200048
|
-
|
|
200049
|
-
|
|
200050
|
-
COLOR_SORT_WIDTH = 2;
|
|
200051
|
-
compareStrings = (left, right) => Number(left > right) - Number(left < right);
|
|
200052
|
-
candidateSortKey = (candidate) => [
|
|
200053
|
-
candidate.normalizedTitle,
|
|
200054
|
-
candidate.color === void 0 ? "1" : "0",
|
|
200055
|
-
candidate.title,
|
|
200056
|
-
String(candidate.color).padStart(COLOR_SORT_WIDTH, "0"),
|
|
200057
|
-
candidate.referenceId
|
|
200058
|
-
].join("\0");
|
|
200059
|
-
compareCandidates = (left, right) => compareStrings(candidateSortKey(left), candidateSortKey(right));
|
|
200060
|
-
toCandidate3 = (input) => {
|
|
200061
|
-
const attachment2 = decodeAttachment(input);
|
|
200062
|
-
if (Result_exports.isFailure(attachment2)) {
|
|
200063
|
-
return { _tag: "Rejected", degradationReason: "malformed_attachment" };
|
|
200064
|
-
}
|
|
200065
|
-
const title = decodeTitle(attachment2.success.title);
|
|
200066
|
-
if (Result_exports.isFailure(title)) {
|
|
200067
|
-
return { _tag: "Rejected", degradationReason: "missing_or_malformed_title" };
|
|
200023
|
+
TASK_TYPE_DISCOVERY_HINT = "Use list_task_types or get_project_type to discover valid task types and statuses.";
|
|
200024
|
+
taskTypeMatches = (taskType, taskTypeRef) => String(taskType._id) === String(taskTypeRef) || normalizeForComparison(taskType.name) === normalizeForComparison(taskTypeRef);
|
|
200025
|
+
describeTaskTypeOptions = (taskTypes) => taskTypes.length === 0 ? "No task types are configured for this project type." : `Available task types: ${taskTypes.map((taskType) => `${taskType.name} (${taskType._id})`).join(", ")}.`;
|
|
200026
|
+
mergeTaskTypes2 = (first, second) => {
|
|
200027
|
+
const taskTypesById = /* @__PURE__ */ new Map();
|
|
200028
|
+
for (const taskType of [...first, ...second]) {
|
|
200029
|
+
taskTypesById.set(String(taskType._id), taskType);
|
|
200068
200030
|
}
|
|
200069
|
-
|
|
200070
|
-
const color = colorInput === void 0 ? void 0 : decodeColor(colorInput);
|
|
200071
|
-
const candidate = {
|
|
200072
|
-
referenceId: attachment2.success._id,
|
|
200073
|
-
issueId: attachment2.success.attachedTo,
|
|
200074
|
-
title: title.success,
|
|
200075
|
-
normalizedTitle: normalizeLabelTitle(title.success),
|
|
200076
|
-
...color !== void 0 && Result_exports.isSuccess(color) ? { color: color.success } : {}
|
|
200077
|
-
};
|
|
200078
|
-
return color !== void 0 && Result_exports.isFailure(color) ? { _tag: "DegradedSuccess", candidate, degradationReason: "invalid_color" } : { _tag: "Success", candidate };
|
|
200031
|
+
return [...taskTypesById.values()];
|
|
200079
200032
|
};
|
|
200080
|
-
|
|
200081
|
-
|
|
200082
|
-
|
|
200083
|
-
|
|
200084
|
-
|
|
200085
|
-
|
|
200086
|
-
|
|
200087
|
-
|
|
200033
|
+
resolveTaskTypeWorkflow = (client, project, projectType, projectStatuses, taskTypeRef, projectIdentifier) => Effect_exports.gen(function* () {
|
|
200034
|
+
const workflowProjectType = projectType ?? (yield* client.findOne(task.class.ProjectType, hulyQuery({ _id: project.type })));
|
|
200035
|
+
if (workflowProjectType === void 0) {
|
|
200036
|
+
return yield* Effect_exports.fail(
|
|
200037
|
+
new HulyError({
|
|
200038
|
+
message: `Project '${projectIdentifier}' does not expose a project type/workflow, so taskType cannot be resolved. ${TASK_TYPE_DISCOVERY_HINT}`
|
|
200039
|
+
})
|
|
200040
|
+
);
|
|
200088
200041
|
}
|
|
200089
|
-
|
|
200090
|
-
|
|
200091
|
-
|
|
200092
|
-
|
|
200093
|
-
|
|
200094
|
-
|
|
200095
|
-
|
|
200096
|
-
|
|
200097
|
-
|
|
200098
|
-
|
|
200099
|
-
|
|
200100
|
-
|
|
200101
|
-
|
|
200102
|
-
|
|
200103
|
-
|
|
200104
|
-
|
|
200105
|
-
|
|
200106
|
-
|
|
200107
|
-
projectCandidateGroup(candidates.filter((candidate) => candidate.issueId === issueId))
|
|
200108
|
-
])
|
|
200109
|
-
),
|
|
200110
|
-
degradationReasons: projections.flatMap(projectionDegradationReason)
|
|
200111
|
-
};
|
|
200112
|
-
};
|
|
200113
|
-
countReason = (reasons, reason) => reasons.filter((candidate) => candidate === reason).length;
|
|
200114
|
-
degradationMessage = (reasons) => {
|
|
200115
|
-
const malformedAttachments = countReason(reasons, "malformed_attachment");
|
|
200116
|
-
const malformedTitles = countReason(reasons, "missing_or_malformed_title");
|
|
200117
|
-
const invalidColors = countReason(reasons, "invalid_color");
|
|
200118
|
-
return `Issue label summaries omitted or partially projected malformed Huly metadata: ${malformedAttachments} malformed attachment(s), ${malformedTitles} missing or malformed title(s), and ${invalidColors} invalid color(s). Duplicate case-insensitive titles prefer a reference with a valid color.`;
|
|
200119
|
-
};
|
|
200120
|
-
labelsForIssue = (index2, issueId) => index2.byIssueId.get(IssueId.make(issueId)) ?? [];
|
|
200121
|
-
issueIdsMatchingLabel = (index2, label) => {
|
|
200122
|
-
const normalizedFilter = normalizeLabelTitle(label);
|
|
200123
|
-
return [...index2.byIssueId].filter(([, labels]) => labels.some((summary) => normalizeLabelTitle(summary.title) === normalizedFilter)).map(([issueId]) => toIssueRef(issueId)).sort(compareStrings);
|
|
200124
|
-
};
|
|
200125
|
-
loadIssueLabelIndex = (client, space, issueIds) => Effect_exports.gen(function* () {
|
|
200126
|
-
if (issueIds !== void 0 && issueIds.length === 0) return buildIssueLabelIndex([]);
|
|
200127
|
-
const diagnostics = yield* Diagnostics;
|
|
200128
|
-
const baseQuery = {
|
|
200129
|
-
space,
|
|
200130
|
-
attachedToClass: tracker.class.Issue,
|
|
200131
|
-
collection: "labels"
|
|
200132
|
-
};
|
|
200133
|
-
const query = issueIds === void 0 ? baseQuery : { ...baseQuery, attachedTo: { $in: issueIds.map(toDocRef2) } };
|
|
200134
|
-
const attachments = yield* client.findAll(tags.class.TagReference, hulyQuery(query));
|
|
200135
|
-
const index2 = buildIssueLabelIndex(attachments);
|
|
200136
|
-
if (index2.degradationReasons.length > 0) {
|
|
200137
|
-
yield* diagnostics.warnAgent({
|
|
200138
|
-
code: IssueLabelMetadataDegradedWarningCode,
|
|
200139
|
-
message: degradationMessage(index2.degradationReasons)
|
|
200140
|
-
});
|
|
200042
|
+
const taskTypesByProjectTypeList = yield* client.findAll(
|
|
200043
|
+
task.class.TaskType,
|
|
200044
|
+
hulyQuery({ _id: { $in: [...workflowProjectType.tasks] } })
|
|
200045
|
+
);
|
|
200046
|
+
const taskTypesByParent = yield* client.findAll(
|
|
200047
|
+
task.class.TaskType,
|
|
200048
|
+
hulyQuery({ parent: workflowProjectType._id })
|
|
200049
|
+
);
|
|
200050
|
+
const taskTypes = mergeTaskTypes2([...taskTypesByProjectTypeList], [...taskTypesByParent]);
|
|
200051
|
+
const matches = [...taskTypes].filter((candidate) => taskTypeMatches(candidate, taskTypeRef));
|
|
200052
|
+
const selectedTaskType = matches.length === 1 ? matches[0] : void 0;
|
|
200053
|
+
if (selectedTaskType === void 0) {
|
|
200054
|
+
const reason = matches.length === 0 ? "was not found" : "matched more than one task type";
|
|
200055
|
+
return yield* Effect_exports.fail(
|
|
200056
|
+
new HulyError({
|
|
200057
|
+
message: `Task type '${taskTypeRef}' ${reason} in project '${projectIdentifier}' workflow. ${describeTaskTypeOptions([...taskTypes])} ${TASK_TYPE_DISCOVERY_HINT}`
|
|
200058
|
+
})
|
|
200059
|
+
);
|
|
200141
200060
|
}
|
|
200142
|
-
|
|
200061
|
+
const scopedStatuses = selectedTaskType.statuses.flatMap(
|
|
200062
|
+
(statusId) => projectStatuses.filter((status) => status._id === statusId)
|
|
200063
|
+
);
|
|
200064
|
+
const defaultStatusId = selectedTaskType.statuses.includes(project.defaultIssueStatus) ? project.defaultIssueStatus : selectedTaskType.statuses.at(0);
|
|
200065
|
+
return { defaultStatusId, statuses: scopedStatuses, taskType: selectedTaskType };
|
|
200143
200066
|
});
|
|
200067
|
+
validStatusNames = (workflow) => workflow.statuses.length === 0 ? workflow.taskType.statuses.join(", ") : workflow.statuses.map((status) => status.name).join(", ");
|
|
200068
|
+
resolveStatusForTaskType = (workflow, statusName, projectIdentifier) => {
|
|
200069
|
+
const normalizedStatusName = normalizeForComparison(statusName);
|
|
200070
|
+
const match9 = workflow.statuses.find((status) => normalizeForComparison(status.name) === normalizedStatusName);
|
|
200071
|
+
const statusNames = validStatusNames(workflow);
|
|
200072
|
+
return match9 !== void 0 ? Effect_exports.succeed(match9._id) : Effect_exports.fail(
|
|
200073
|
+
new HulyError({
|
|
200074
|
+
message: `Status '${statusName}' is not valid for task type '${workflow.taskType.name}' in project '${projectIdentifier}'. Valid statuses for this task type: ${statusNames}. ${TASK_TYPE_DISCOVERY_HINT}`
|
|
200075
|
+
})
|
|
200076
|
+
);
|
|
200077
|
+
};
|
|
200078
|
+
chooseStatusForTaskType = (workflow, requestedStatus, currentStatus, projectIdentifier) => {
|
|
200079
|
+
if (requestedStatus !== void 0) {
|
|
200080
|
+
return resolveStatusForTaskType(workflow, requestedStatus, projectIdentifier);
|
|
200081
|
+
}
|
|
200082
|
+
if (currentStatus !== void 0 && workflow.taskType.statuses.includes(currentStatus)) {
|
|
200083
|
+
return Effect_exports.succeed(currentStatus);
|
|
200084
|
+
}
|
|
200085
|
+
return workflow.defaultStatusId !== void 0 ? Effect_exports.succeed(workflow.defaultStatusId) : Effect_exports.fail(
|
|
200086
|
+
new HulyError({
|
|
200087
|
+
message: `Task type '${workflow.taskType.name}' in project '${projectIdentifier}' has no valid status. ${TASK_TYPE_DISCOVERY_HINT}`
|
|
200088
|
+
})
|
|
200089
|
+
);
|
|
200090
|
+
};
|
|
200144
200091
|
}
|
|
200145
200092
|
});
|
|
200146
200093
|
|
|
200147
|
-
// src/huly/operations/
|
|
200148
|
-
var
|
|
200149
|
-
var
|
|
200150
|
-
"src/huly/operations/
|
|
200094
|
+
// src/huly/operations/issues-write.ts
|
|
200095
|
+
var import_core87, import_rank5, import_tracker3, TxIncResult2, extractUpdatedSequence, requireUpdatedSequence, resolveCreateIssueTaskType, resolveCreateIssueStatus, resolveCreateIssueAssignee, renderCreateIssueDescription, resolveCreateIssueParent, uploadCreateIssueDescription, createIssueWithAssignee, createIssue, createIssueWithResolvedAssignee, deleteIssue;
|
|
200096
|
+
var init_issues_write = __esm({
|
|
200097
|
+
"src/huly/operations/issues-write.ts"() {
|
|
200151
200098
|
"use strict";
|
|
200099
|
+
import_core87 = __toESM(require_lib6(), 1);
|
|
200100
|
+
import_rank5 = __toESM(require_lib24(), 1);
|
|
200101
|
+
import_tracker3 = __toESM(require_lib25(), 1);
|
|
200152
200102
|
init_dist();
|
|
200153
200103
|
init_issues();
|
|
200154
200104
|
init_shared();
|
|
200155
|
-
|
|
200156
|
-
init_diagnostics();
|
|
200105
|
+
init_errors4();
|
|
200157
200106
|
init_huly_plugins();
|
|
200107
|
+
init_issue_native_references();
|
|
200108
|
+
init_issues_parent();
|
|
200109
|
+
init_issues_shared();
|
|
200110
|
+
init_issues_write_shared();
|
|
200158
200111
|
init_query_helpers();
|
|
200159
|
-
|
|
200160
|
-
|
|
200161
|
-
|
|
200162
|
-
|
|
200163
|
-
|
|
200164
|
-
|
|
200165
|
-
|
|
200166
|
-
|
|
200167
|
-
|
|
200168
|
-
|
|
200169
|
-
|
|
200170
|
-
|
|
200171
|
-
|
|
200172
|
-
|
|
200173
|
-
|
|
200174
|
-
|
|
200112
|
+
init_sdk_boundary();
|
|
200113
|
+
TxIncResult2 = Schema_exports.Struct({ object: Schema_exports.Struct({ sequence: Schema_exports.Number }) });
|
|
200114
|
+
extractUpdatedSequence = (txResult) => {
|
|
200115
|
+
const decoded = Schema_exports.decodeUnknownOption(TxIncResult2)(txResult);
|
|
200116
|
+
return decoded._tag === "Some" ? decoded.value.object.sequence : void 0;
|
|
200117
|
+
};
|
|
200118
|
+
requireUpdatedSequence = (txResult, projectIdentifier) => {
|
|
200119
|
+
const sequence = extractUpdatedSequence(txResult);
|
|
200120
|
+
return sequence === void 0 ? Effect_exports.fail(
|
|
200121
|
+
new HulyError({
|
|
200122
|
+
message: `Project '${projectIdentifier}' sequence increment did not return the updated sequence; issue creation stopped to avoid a duplicate identifier.`
|
|
200123
|
+
})
|
|
200124
|
+
) : Effect_exports.succeed(sequence);
|
|
200125
|
+
};
|
|
200126
|
+
resolveCreateIssueTaskType = (client, project, workflow, params2) => params2.taskType === void 0 ? Effect_exports.succeed(void 0) : resolveTaskTypeWorkflow(client, project, workflow.projectType, workflow.statuses, params2.taskType, params2.project);
|
|
200127
|
+
resolveCreateIssueStatus = (workflow, taskTypeWorkflow, params2) => {
|
|
200128
|
+
if (taskTypeWorkflow !== void 0) {
|
|
200129
|
+
return chooseStatusForTaskType(taskTypeWorkflow, params2.status, void 0, params2.project);
|
|
200130
|
+
}
|
|
200131
|
+
if (params2.status !== void 0) return resolveStatusByName(workflow.statuses, params2.status, params2.project);
|
|
200132
|
+
if (workflow.defaultStatusId !== void 0) return Effect_exports.succeed(workflow.defaultStatusId);
|
|
200133
|
+
return Effect_exports.fail(new InvalidStatusError({ status: "(default)", project: params2.project }));
|
|
200134
|
+
};
|
|
200135
|
+
resolveCreateIssueAssignee = (client, params2) => params2.assignee === void 0 ? Effect_exports.succeed(null) : Effect_exports.map(resolveAssignee(client, params2.assignee), (person) => person._id);
|
|
200136
|
+
renderCreateIssueDescription = (params2) => params2.description !== void 0 && params2.description.trim() !== "" ? renderIssueDescriptionForWrite(params2.description) : Effect_exports.succeed(void 0);
|
|
200137
|
+
resolveCreateIssueParent = (client, project, parentIssue) => parentIssue === void 0 ? Effect_exports.succeed(topLevelIssueParent()) : Effect_exports.map(findIssueInProject(client, project, parentIssue), (parent) => childIssueParent(parent, project._id));
|
|
200138
|
+
uploadCreateIssueDescription = (client, issueId, renderedDescription) => renderedDescription === void 0 ? Effect_exports.succeed(null) : client.uploadMarkup(
|
|
200139
|
+
tracker.class.Issue,
|
|
200140
|
+
issueId,
|
|
200141
|
+
"description",
|
|
200142
|
+
renderedDescription.markup,
|
|
200143
|
+
renderedDescription.format
|
|
200144
|
+
);
|
|
200145
|
+
createIssueWithAssignee = Effect_exports.fn("Issues.createWithAssignee")(function* (params2, assigneeResolution) {
|
|
200146
|
+
const { client, defaultStatusId, project, projectType, statuses } = yield* findProjectWithStatuses(params2.project);
|
|
200147
|
+
const issueId = (0, import_core87.generateId)();
|
|
200148
|
+
const workflow = { projectType, statuses, defaultStatusId };
|
|
200149
|
+
const taskTypeWorkflow = yield* resolveCreateIssueTaskType(client, project, workflow, params2);
|
|
200150
|
+
const statusRef = yield* resolveCreateIssueStatus(workflow, taskTypeWorkflow, params2);
|
|
200151
|
+
const assigneeRef = yield* assigneeResolution(client, params2);
|
|
200152
|
+
const renderedDescription = yield* renderCreateIssueDescription(params2);
|
|
200153
|
+
const { attachedTo, attachedToClass, collection, parents } = yield* resolveCreateIssueParent(
|
|
200154
|
+
client,
|
|
200155
|
+
project,
|
|
200156
|
+
params2.parentIssue
|
|
200157
|
+
);
|
|
200158
|
+
const incOps = { $inc: { sequence: 1 } };
|
|
200159
|
+
const incResult = yield* client.updateDoc(
|
|
200160
|
+
tracker.class.Project,
|
|
200161
|
+
toRef("core:space:Space"),
|
|
200162
|
+
project._id,
|
|
200163
|
+
incOps,
|
|
200164
|
+
true
|
|
200165
|
+
);
|
|
200166
|
+
const sequence = yield* requireUpdatedSequence(incResult, params2.project);
|
|
200167
|
+
const lastIssue = yield* client.findOne(
|
|
200168
|
+
tracker.class.Issue,
|
|
200169
|
+
hulyQuery({ space: project._id }),
|
|
200170
|
+
{ sort: { rank: import_core87.SortingOrder.Descending } }
|
|
200171
|
+
);
|
|
200172
|
+
const rank = (0, import_rank5.makeRank)(lastIssue?.rank, void 0);
|
|
200173
|
+
const descriptionMarkupRef = yield* uploadCreateIssueDescription(client, issueId, renderedDescription);
|
|
200174
|
+
const priority = stringToPriority(params2.priority ?? DEFAULT_ISSUE_PRIORITY);
|
|
200175
|
+
const identifier2 = `${project.identifier}-${sequence}`;
|
|
200176
|
+
const issueData = {
|
|
200177
|
+
title: params2.title,
|
|
200178
|
+
description: descriptionMarkupRef,
|
|
200179
|
+
status: statusRef,
|
|
200180
|
+
number: sequence,
|
|
200181
|
+
kind: taskTypeWorkflow?.taskType._id ?? tracker.taskTypes.Issue,
|
|
200182
|
+
identifier: identifier2,
|
|
200183
|
+
priority,
|
|
200184
|
+
assignee: assigneeRef,
|
|
200185
|
+
component: null,
|
|
200186
|
+
estimation: params2.estimation ?? 0,
|
|
200187
|
+
remainingTime: 0,
|
|
200188
|
+
reportedTime: 0,
|
|
200189
|
+
reports: 0,
|
|
200190
|
+
subIssues: 0,
|
|
200191
|
+
parents,
|
|
200192
|
+
childInfo: [],
|
|
200193
|
+
dueDate: params2.dueDate ?? null,
|
|
200194
|
+
rank
|
|
200195
|
+
};
|
|
200196
|
+
yield* client.addCollection(
|
|
200197
|
+
tracker.class.Issue,
|
|
200198
|
+
project._id,
|
|
200199
|
+
attachedTo,
|
|
200200
|
+
attachedToClass,
|
|
200201
|
+
collection,
|
|
200202
|
+
issueData,
|
|
200203
|
+
issueId
|
|
200204
|
+
);
|
|
200205
|
+
return { identifier: IssueIdentifier.make(identifier2), issueId: IssueId.make(issueId) };
|
|
200206
|
+
});
|
|
200207
|
+
createIssue = (params2) => createIssueWithAssignee(params2, resolveCreateIssueAssignee);
|
|
200208
|
+
createIssueWithResolvedAssignee = (params2) => createIssueWithAssignee(params2, () => Effect_exports.succeed(params2.resolvedAssignee));
|
|
200209
|
+
deleteIssue = (params2) => Effect_exports.gen(function* () {
|
|
200210
|
+
const { client, issue: issue2, project } = yield* findProjectAndIssue(params2);
|
|
200211
|
+
yield* client.removeDoc(tracker.class.Issue, project._id, issue2._id);
|
|
200212
|
+
return { identifier: IssueIdentifier.make(issue2.identifier), deleted: true };
|
|
200213
|
+
});
|
|
200214
|
+
}
|
|
200215
|
+
});
|
|
200216
|
+
|
|
200217
|
+
// src/huly/operations/issue-templates.ts
|
|
200218
|
+
var import_core88, NOT_FOUND_INDEX2, findTemplateByIdOrTitle, findProjectAndTemplate, resolveTemplateReferenceLabels, templateChildProjection, resolveChild, buildTemplateChild, listIssueTemplates, getIssueTemplate, createIssueTemplate, resolveIssueFromTemplateAssignee, templateChildCreateParams, templateChildUpdate, createTemplateChildIssues, createIssueFromTemplate, updateIssueTemplate, deleteIssueTemplate, addTemplateChild, removeTemplateChild;
|
|
200219
|
+
var init_issue_templates2 = __esm({
|
|
200220
|
+
"src/huly/operations/issue-templates.ts"() {
|
|
200221
|
+
"use strict";
|
|
200222
|
+
import_core88 = __toESM(require_lib6(), 1);
|
|
200223
|
+
init_dist();
|
|
200224
|
+
init_issue_templates();
|
|
200225
|
+
init_issues();
|
|
200226
|
+
init_shared();
|
|
200227
|
+
init_time();
|
|
200228
|
+
init_assertions();
|
|
200229
|
+
init_errors4();
|
|
200230
|
+
init_clear_field_updates();
|
|
200231
|
+
init_components2();
|
|
200232
|
+
init_contacts_shared();
|
|
200233
|
+
init_issues_parent();
|
|
200234
|
+
init_issues_shared();
|
|
200235
|
+
init_issues_write();
|
|
200236
|
+
init_query_helpers();
|
|
200237
|
+
init_sdk_boundary();
|
|
200238
|
+
init_update_guards();
|
|
200239
|
+
init_huly_plugins();
|
|
200240
|
+
init_markup();
|
|
200241
|
+
NOT_FOUND_INDEX2 = -1;
|
|
200242
|
+
findTemplateByIdOrTitle = (client, projectId, templateIdOrTitle) => Effect_exports.gen(function* () {
|
|
200243
|
+
const template = (yield* client.findOne(tracker.class.IssueTemplate, {
|
|
200244
|
+
space: projectId,
|
|
200245
|
+
_id: toRef(templateIdOrTitle)
|
|
200246
|
+
})) ?? (yield* client.findOne(tracker.class.IssueTemplate, {
|
|
200247
|
+
space: projectId,
|
|
200248
|
+
title: templateIdOrTitle
|
|
200249
|
+
}));
|
|
200250
|
+
return template;
|
|
200251
|
+
});
|
|
200252
|
+
findProjectAndTemplate = (params2) => Effect_exports.gen(function* () {
|
|
200253
|
+
const { client, project } = yield* findProject(params2.project);
|
|
200254
|
+
const template = yield* findTemplateByIdOrTitle(client, project._id, params2.template);
|
|
200255
|
+
if (template === void 0) {
|
|
200256
|
+
return yield* new IssueTemplateNotFoundError({ identifier: params2.template, project: params2.project });
|
|
200257
|
+
}
|
|
200258
|
+
return { client, project, template };
|
|
200259
|
+
});
|
|
200260
|
+
resolveTemplateReferenceLabels = (client, assignee, component) => Effect_exports.gen(function* () {
|
|
200261
|
+
const assigneeName = assignee === null ? void 0 : (yield* client.findOne(contact.class.Person, hulyQuery({ _id: assignee })))?.name;
|
|
200262
|
+
const componentLabel = component === null ? void 0 : (yield* client.findOne(tracker.class.Component, hulyQuery({ _id: component })))?.label;
|
|
200263
|
+
return {
|
|
200264
|
+
...assigneeName === void 0 ? {} : { assigneeName },
|
|
200265
|
+
...componentLabel === void 0 ? {} : { componentLabel }
|
|
200266
|
+
};
|
|
200267
|
+
});
|
|
200268
|
+
templateChildProjection = (child, description, labels) => {
|
|
200269
|
+
const rawEstimation = zeroAsUnset(NonNegativeNumber.make(child.estimation));
|
|
200270
|
+
const estimation = rawEstimation === void 0 ? void 0 : PositiveTimeHours.make(rawEstimation);
|
|
200271
|
+
return {
|
|
200272
|
+
id: IssueTemplateChildId.make(child.id),
|
|
200273
|
+
title: child.title,
|
|
200274
|
+
priority: priorityToString(child.priority),
|
|
200275
|
+
...description === void 0 ? {} : { description },
|
|
200276
|
+
...labels.assigneeName === void 0 ? {} : { assignee: PersonName.make(labels.assigneeName) },
|
|
200277
|
+
...labels.componentLabel === void 0 ? {} : { component: ComponentLabel.make(labels.componentLabel) },
|
|
200278
|
+
...estimation === void 0 ? {} : { estimation }
|
|
200279
|
+
};
|
|
200280
|
+
};
|
|
200281
|
+
resolveChild = (client, markupUrlConfig, child) => Effect_exports.gen(function* () {
|
|
200282
|
+
const labels = yield* resolveTemplateReferenceLabels(client, child.assignee, child.component);
|
|
200283
|
+
const description = child.description ? yield* optionalMarkupToMarkdown(child.description, markupUrlConfig, "", {
|
|
200284
|
+
operation: "getIssueTemplate",
|
|
200285
|
+
entity: "issue template child description"
|
|
200286
|
+
}) : void 0;
|
|
200287
|
+
return templateChildProjection(child, description, labels);
|
|
200288
|
+
});
|
|
200289
|
+
buildTemplateChild = (client, markupUrlConfig, projectId, projectIdentifier, input) => Effect_exports.gen(function* () {
|
|
200290
|
+
const assigneeParam = input.assignee;
|
|
200291
|
+
const assigneeRef = assigneeParam !== void 0 ? yield* Effect_exports.gen(function* () {
|
|
200292
|
+
const person = yield* findPersonByEmailOrName(client, assigneeParam);
|
|
200293
|
+
if (person === void 0) {
|
|
200294
|
+
return yield* new PersonNotFoundError({ identifier: assigneeParam });
|
|
200295
|
+
}
|
|
200296
|
+
return person._id;
|
|
200297
|
+
}) : null;
|
|
200298
|
+
const componentParam = input.component;
|
|
200299
|
+
const componentRef = componentParam !== void 0 ? yield* Effect_exports.gen(function* () {
|
|
200300
|
+
const component = yield* findComponentByIdOrLabel(client, projectId, componentParam);
|
|
200301
|
+
if (component === void 0) {
|
|
200302
|
+
return yield* new ComponentNotFoundError({ identifier: componentParam, project: projectIdentifier });
|
|
200303
|
+
}
|
|
200304
|
+
return component._id;
|
|
200305
|
+
}) : null;
|
|
200306
|
+
return {
|
|
200307
|
+
id: (0, import_core88.generateId)(),
|
|
200308
|
+
title: input.title,
|
|
200309
|
+
description: optionalMarkdownToMarkup(input.description, markupUrlConfig, ""),
|
|
200310
|
+
priority: stringToPriority(input.priority ?? DEFAULT_ISSUE_PRIORITY),
|
|
200311
|
+
assignee: assigneeRef,
|
|
200312
|
+
component: componentRef,
|
|
200313
|
+
estimation: input.estimation ?? 0
|
|
200314
|
+
};
|
|
200315
|
+
});
|
|
200316
|
+
listIssueTemplates = (params2) => Effect_exports.gen(function* () {
|
|
200317
|
+
const { client, project } = yield* findProject(params2.project);
|
|
200318
|
+
const limit = clampLimit(params2.limit);
|
|
200319
|
+
const templates2 = yield* client.findAll(
|
|
200320
|
+
tracker.class.IssueTemplate,
|
|
200321
|
+
{ space: project._id },
|
|
200322
|
+
{ limit, sort: { modifiedOn: import_core88.SortingOrder.Descending } }
|
|
200323
|
+
);
|
|
200324
|
+
const summaries = templates2.map((t) => {
|
|
200325
|
+
const base2 = {
|
|
200326
|
+
id: IssueTemplateId.make(t._id),
|
|
200327
|
+
title: t.title,
|
|
200328
|
+
priority: priorityToString(t.priority),
|
|
200329
|
+
modifiedOn: Timestamp.make(t.modifiedOn)
|
|
200330
|
+
};
|
|
200331
|
+
if (t.children.length > 0) {
|
|
200332
|
+
return { ...base2, childrenCount: Count.make(t.children.length) };
|
|
200333
|
+
}
|
|
200334
|
+
return base2;
|
|
200335
|
+
});
|
|
200336
|
+
return summaries;
|
|
200337
|
+
});
|
|
200338
|
+
getIssueTemplate = (params2) => Effect_exports.gen(function* () {
|
|
200339
|
+
const { client, template } = yield* findProjectAndTemplate(params2);
|
|
200340
|
+
const markupUrlConfig = client.markupUrlConfig;
|
|
200341
|
+
const labels = yield* resolveTemplateReferenceLabels(client, template.assignee, template.component);
|
|
200342
|
+
const description = yield* optionalMarkupToMarkdown(template.description, markupUrlConfig, "", {
|
|
200343
|
+
operation: "getIssueTemplate",
|
|
200344
|
+
entity: "issue template description"
|
|
200345
|
+
});
|
|
200346
|
+
const resolvedChildren = [];
|
|
200347
|
+
for (const child of template.children) {
|
|
200348
|
+
resolvedChildren.push(yield* resolveChild(client, markupUrlConfig, child));
|
|
200349
|
+
}
|
|
200350
|
+
const result3 = {
|
|
200351
|
+
id: IssueTemplateId.make(template._id),
|
|
200352
|
+
title: template.title,
|
|
200353
|
+
description,
|
|
200354
|
+
priority: priorityToString(template.priority),
|
|
200355
|
+
assignee: labels.assigneeName !== void 0 ? PersonName.make(labels.assigneeName) : void 0,
|
|
200356
|
+
component: labels.componentLabel !== void 0 ? ComponentLabel.make(labels.componentLabel) : void 0,
|
|
200357
|
+
estimation: template.estimation > 0 ? PositiveTimeHours.make(template.estimation) : void 0,
|
|
200358
|
+
project: params2.project,
|
|
200359
|
+
modifiedOn: Timestamp.make(template.modifiedOn),
|
|
200360
|
+
createdOn: template.createdOn === void 0 ? void 0 : Timestamp.make(template.createdOn)
|
|
200361
|
+
};
|
|
200362
|
+
if (resolvedChildren.length > 0) {
|
|
200363
|
+
return { ...result3, children: resolvedChildren };
|
|
200364
|
+
}
|
|
200365
|
+
return result3;
|
|
200366
|
+
});
|
|
200367
|
+
createIssueTemplate = (params2) => Effect_exports.gen(function* () {
|
|
200368
|
+
const { client, project } = yield* findProject(params2.project);
|
|
200369
|
+
const markupUrlConfig = client.markupUrlConfig;
|
|
200370
|
+
const templateId = (0, import_core88.generateId)();
|
|
200371
|
+
const assigneeParam = params2.assignee;
|
|
200372
|
+
const assigneeRef = assigneeParam !== void 0 ? yield* Effect_exports.gen(function* () {
|
|
200373
|
+
const person = yield* findPersonByEmailOrName(client, assigneeParam);
|
|
200374
|
+
if (person === void 0) {
|
|
200375
|
+
return yield* new PersonNotFoundError({ identifier: assigneeParam });
|
|
200376
|
+
}
|
|
200377
|
+
return person._id;
|
|
200378
|
+
}) : null;
|
|
200379
|
+
const componentParam = params2.component;
|
|
200380
|
+
const componentRef = componentParam !== void 0 ? yield* Effect_exports.gen(function* () {
|
|
200381
|
+
const component = yield* findComponentByIdOrLabel(client, project._id, componentParam);
|
|
200382
|
+
if (component === void 0) {
|
|
200383
|
+
return yield* new ComponentNotFoundError({ identifier: componentParam, project: params2.project });
|
|
200384
|
+
}
|
|
200385
|
+
return component._id;
|
|
200386
|
+
}) : null;
|
|
200387
|
+
const priority = stringToPriority(params2.priority ?? DEFAULT_ISSUE_PRIORITY);
|
|
200388
|
+
const children = [];
|
|
200389
|
+
if (params2.children !== void 0) {
|
|
200390
|
+
for (const childInput of params2.children) {
|
|
200391
|
+
children.push(yield* buildTemplateChild(client, markupUrlConfig, project._id, params2.project, childInput));
|
|
200392
|
+
}
|
|
200393
|
+
}
|
|
200394
|
+
const templateData = {
|
|
200395
|
+
title: params2.title,
|
|
200396
|
+
description: optionalMarkdownToMarkup(params2.description, markupUrlConfig, ""),
|
|
200397
|
+
priority,
|
|
200398
|
+
assignee: assigneeRef,
|
|
200399
|
+
component: componentRef,
|
|
200400
|
+
estimation: params2.estimation ?? 0,
|
|
200401
|
+
children,
|
|
200402
|
+
comments: 0
|
|
200403
|
+
};
|
|
200404
|
+
yield* client.createDoc(tracker.class.IssueTemplate, project._id, templateData, templateId);
|
|
200405
|
+
return { id: IssueTemplateId.make(templateId), title: params2.title };
|
|
200406
|
+
});
|
|
200407
|
+
resolveIssueFromTemplateAssignee = (client, params2, template) => Effect_exports.gen(function* () {
|
|
200408
|
+
if (params2.assignee === void 0) {
|
|
200409
|
+
if (template.assignee === null) return null;
|
|
200410
|
+
const templatePerson = yield* client.findOne(
|
|
200411
|
+
contact.class.Person,
|
|
200412
|
+
hulyQuery({ _id: template.assignee })
|
|
200413
|
+
);
|
|
200414
|
+
return templatePerson?._id ?? null;
|
|
200415
|
+
}
|
|
200416
|
+
const person = yield* findPersonByEmailOrName(client, params2.assignee);
|
|
200417
|
+
if (person === void 0) return yield* new PersonNotFoundError({ identifier: params2.assignee });
|
|
200418
|
+
return person._id;
|
|
200419
|
+
});
|
|
200420
|
+
templateChildCreateParams = (params2, child, markupUrlConfig) => optionalMarkupToMarkdown(child.description, markupUrlConfig, void 0, {
|
|
200421
|
+
operation: "createIssueFromTemplate",
|
|
200422
|
+
entity: "issue template child description"
|
|
200423
|
+
}).pipe(
|
|
200424
|
+
Effect_exports.map(
|
|
200425
|
+
(description) => ({
|
|
200426
|
+
project: params2.project,
|
|
200427
|
+
title: child.title,
|
|
200428
|
+
priority: priorityToString(child.priority),
|
|
200429
|
+
resolvedAssignee: null,
|
|
200430
|
+
...description === void 0 ? {} : { description }
|
|
200431
|
+
})
|
|
200432
|
+
)
|
|
200433
|
+
);
|
|
200434
|
+
templateChildUpdate = (child) => ({
|
|
200435
|
+
...child.assignee === null ? {} : { assignee: child.assignee },
|
|
200436
|
+
...child.component === null ? {} : { component: child.component },
|
|
200437
|
+
...child.estimation > 0 ? { estimation: child.estimation } : {}
|
|
200438
|
+
});
|
|
200439
|
+
createTemplateChildIssues = (client, project, template, params2, parentResult, title, markupUrlConfig) => Effect_exports.gen(function* () {
|
|
200440
|
+
const parentIssue = {
|
|
200441
|
+
_id: toRef(parentResult.issueId),
|
|
200442
|
+
identifier: parentResult.identifier,
|
|
200443
|
+
title,
|
|
200444
|
+
parents: []
|
|
200445
|
+
};
|
|
200446
|
+
for (const child of template.children) {
|
|
200447
|
+
const childParams = yield* templateChildCreateParams(params2, child, markupUrlConfig);
|
|
200448
|
+
const childResult = yield* createIssueWithResolvedAssignee(childParams);
|
|
200449
|
+
yield* attachIssueChild(
|
|
200450
|
+
client,
|
|
200451
|
+
project._id,
|
|
200452
|
+
toRef(childResult.issueId),
|
|
200453
|
+
parentIssue,
|
|
200454
|
+
templateChildUpdate(child)
|
|
200455
|
+
);
|
|
200456
|
+
}
|
|
200457
|
+
});
|
|
200458
|
+
createIssueFromTemplate = (params2) => Effect_exports.gen(function* () {
|
|
200459
|
+
const { client, project, template } = yield* findProjectAndTemplate(params2);
|
|
200460
|
+
const markupUrlConfig = client.markupUrlConfig;
|
|
200461
|
+
const title = params2.title ?? template.title;
|
|
200462
|
+
const description = params2.description ?? (yield* optionalMarkupToMarkdown(template.description, markupUrlConfig, void 0, {
|
|
200463
|
+
operation: "createIssueFromTemplate",
|
|
200464
|
+
entity: "issue template description"
|
|
200465
|
+
}));
|
|
200466
|
+
const priority = params2.priority ?? priorityToString(template.priority);
|
|
200467
|
+
const assignee = yield* resolveIssueFromTemplateAssignee(client, params2, template);
|
|
200468
|
+
const issueParams = {
|
|
200469
|
+
project: params2.project,
|
|
200470
|
+
title,
|
|
200471
|
+
description,
|
|
200472
|
+
priority,
|
|
200473
|
+
resolvedAssignee: assignee,
|
|
200474
|
+
status: params2.status
|
|
200475
|
+
};
|
|
200476
|
+
const result3 = yield* createIssueWithResolvedAssignee(issueParams);
|
|
200477
|
+
if (template.component !== null) {
|
|
200478
|
+
yield* client.updateDoc(tracker.class.Issue, project._id, toRef(result3.issueId), {
|
|
200479
|
+
component: template.component
|
|
200480
|
+
});
|
|
200481
|
+
}
|
|
200482
|
+
const includeChildren = params2.includeChildren ?? DEFAULT_INCLUDE_TEMPLATE_CHILDREN;
|
|
200483
|
+
if (includeChildren && template.children.length > 0) {
|
|
200484
|
+
yield* createTemplateChildIssues(client, project, template, params2, result3, title, markupUrlConfig);
|
|
200485
|
+
return { ...result3, childrenCreated: Count.make(template.children.length) };
|
|
200486
|
+
}
|
|
200487
|
+
return result3;
|
|
200488
|
+
});
|
|
200489
|
+
updateIssueTemplate = (params2) => Effect_exports.gen(function* () {
|
|
200490
|
+
yield* requireUpdateFields("update_issue_template", params2, UPDATE_ISSUE_TEMPLATE_FIELDS);
|
|
200491
|
+
const { client, project, template } = yield* findProjectAndTemplate(params2);
|
|
200492
|
+
const markupUrlConfig = client.markupUrlConfig;
|
|
200493
|
+
const updateEntries = {
|
|
200494
|
+
title: Effect_exports.succeed(params2.title === void 0 ? {} : { title: params2.title }),
|
|
200495
|
+
description: Effect_exports.succeed(
|
|
200496
|
+
params2.description === void 0 ? {} : { description: optionalMarkdownToMarkup(clearTextAsEmptyString(params2.description), markupUrlConfig, "") }
|
|
200497
|
+
),
|
|
200498
|
+
priority: Effect_exports.succeed(params2.priority === void 0 ? {} : { priority: stringToPriority(params2.priority) }),
|
|
200499
|
+
assignee: Effect_exports.gen(function* () {
|
|
200500
|
+
if (params2.assignee === void 0) return {};
|
|
200501
|
+
if (params2.assignee === null) return { assignee: null };
|
|
200502
|
+
const person = yield* findPersonByEmailOrName(client, params2.assignee);
|
|
200503
|
+
if (person === void 0) {
|
|
200504
|
+
return yield* new PersonNotFoundError({ identifier: params2.assignee });
|
|
200505
|
+
}
|
|
200506
|
+
return { assignee: person._id };
|
|
200507
|
+
}),
|
|
200508
|
+
component: Effect_exports.gen(function* () {
|
|
200509
|
+
if (params2.component === void 0) return {};
|
|
200510
|
+
if (params2.component === null) return { component: null };
|
|
200511
|
+
const component = yield* findComponentByIdOrLabel(client, project._id, params2.component);
|
|
200512
|
+
if (component === void 0) {
|
|
200513
|
+
return yield* new ComponentNotFoundError({ identifier: params2.component, project: params2.project });
|
|
200514
|
+
}
|
|
200515
|
+
return { component: component._id };
|
|
200516
|
+
}),
|
|
200517
|
+
estimation: Effect_exports.succeed(
|
|
200518
|
+
params2.estimation === void 0 ? {} : { estimation: params2.estimation === null ? 0 : params2.estimation }
|
|
200519
|
+
)
|
|
200520
|
+
};
|
|
200521
|
+
const updateOps = mergeUpdateEntries(
|
|
200522
|
+
yield* Effect_exports.all(Object.values(updateEntries))
|
|
200523
|
+
);
|
|
200524
|
+
yield* client.updateDoc(tracker.class.IssueTemplate, project._id, template._id, updateOps);
|
|
200525
|
+
return { id: IssueTemplateId.make(template._id), updated: true };
|
|
200526
|
+
});
|
|
200527
|
+
deleteIssueTemplate = (params2) => Effect_exports.gen(function* () {
|
|
200528
|
+
const { client, project, template } = yield* findProjectAndTemplate(params2);
|
|
200529
|
+
yield* client.removeDoc(tracker.class.IssueTemplate, project._id, template._id);
|
|
200530
|
+
return { id: IssueTemplateId.make(template._id), deleted: true };
|
|
200531
|
+
});
|
|
200532
|
+
addTemplateChild = (params2) => Effect_exports.gen(function* () {
|
|
200533
|
+
const { client, project, template } = yield* findProjectAndTemplate(params2);
|
|
200534
|
+
const markupUrlConfig = client.markupUrlConfig;
|
|
200535
|
+
const child = yield* buildTemplateChild(client, markupUrlConfig, project._id, params2.project, {
|
|
200536
|
+
title: params2.title,
|
|
200537
|
+
description: params2.description,
|
|
200538
|
+
priority: params2.priority,
|
|
200539
|
+
assignee: params2.assignee,
|
|
200540
|
+
component: params2.component,
|
|
200541
|
+
estimation: params2.estimation
|
|
200542
|
+
});
|
|
200543
|
+
const newChildren = [...template.children, child];
|
|
200544
|
+
yield* client.updateDoc(tracker.class.IssueTemplate, project._id, template._id, { children: newChildren });
|
|
200545
|
+
return { id: IssueTemplateChildId.make(child.id), title: child.title, added: true };
|
|
200546
|
+
});
|
|
200547
|
+
removeTemplateChild = (params2) => Effect_exports.gen(function* () {
|
|
200548
|
+
const { client, project, template } = yield* findProjectAndTemplate(params2);
|
|
200549
|
+
const childIndex = template.children.findIndex((c) => String(c.id) === String(params2.childId));
|
|
200550
|
+
if (childIndex === NOT_FOUND_INDEX2) {
|
|
200551
|
+
return yield* new TemplateChildNotFoundError({
|
|
200552
|
+
childId: params2.childId,
|
|
200553
|
+
template: params2.template,
|
|
200554
|
+
project: params2.project
|
|
200555
|
+
});
|
|
200556
|
+
}
|
|
200557
|
+
const removedChild = assertAt(template.children, childIndex);
|
|
200558
|
+
const newChildren = template.children.filter((_, i) => i !== childIndex);
|
|
200559
|
+
yield* client.updateDoc(tracker.class.IssueTemplate, project._id, template._id, { children: newChildren });
|
|
200560
|
+
return { id: IssueTemplateChildId.make(removedChild.id), title: removedChild.title, removed: true };
|
|
200561
|
+
});
|
|
200562
|
+
}
|
|
200563
|
+
});
|
|
200564
|
+
|
|
200565
|
+
// src/huly/operations/issues-move.ts
|
|
200566
|
+
var import_core89, import_tracker4, issueTargetClass, addLabel, moveIssue, updateDescendantParents;
|
|
200567
|
+
var init_issues_move = __esm({
|
|
200568
|
+
"src/huly/operations/issues-move.ts"() {
|
|
200569
|
+
"use strict";
|
|
200570
|
+
import_core89 = __toESM(require_lib6(), 1);
|
|
200571
|
+
import_tracker4 = __toESM(require_lib25(), 1);
|
|
200572
|
+
init_dist();
|
|
200573
|
+
init_shared();
|
|
200574
|
+
init_tags();
|
|
200575
|
+
init_huly_plugins();
|
|
200576
|
+
init_issues_parent();
|
|
200577
|
+
init_issues_shared();
|
|
200578
|
+
init_query_helpers();
|
|
200579
|
+
init_sdk_boundary();
|
|
200580
|
+
init_tags_shared();
|
|
200581
|
+
issueTargetClass = TagTargetClass.make(String(tracker.class.Issue));
|
|
200582
|
+
addLabel = (params2) => Effect_exports.gen(function* () {
|
|
200583
|
+
const { issue: issue2, project } = yield* findProjectAndIssue(params2);
|
|
200584
|
+
const labelTitle = TagIdentifier.make(params2.label.trim());
|
|
200585
|
+
const tag2 = yield* ensureTagElement({
|
|
200586
|
+
targetClass: issueTargetClass,
|
|
200587
|
+
titleOrId: labelTitle,
|
|
200588
|
+
color: params2.color,
|
|
200589
|
+
fallbackCategory: tracker.category.Other
|
|
200590
|
+
});
|
|
200591
|
+
const result3 = yield* attachTagReference({
|
|
200592
|
+
tag: tag2,
|
|
200593
|
+
objectId: issue2._id,
|
|
200594
|
+
objectClass: tracker.class.Issue,
|
|
200595
|
+
space: project._id,
|
|
200596
|
+
collection: "labels",
|
|
200597
|
+
matchTitleCaseInsensitive: true
|
|
200598
|
+
});
|
|
200599
|
+
return { identifier: IssueIdentifier.make(issue2.identifier), labelAdded: result3.attached };
|
|
200600
|
+
});
|
|
200601
|
+
moveIssue = (params2) => Effect_exports.gen(function* () {
|
|
200602
|
+
const { client, issue: issue2, project } = yield* findProjectAndIssue(params2);
|
|
200603
|
+
const oldParentIsIssue = hasConcreteIssueParent(issue2);
|
|
200604
|
+
const newParentParam = params2.newParent;
|
|
200605
|
+
const target = newParentParam !== null ? yield* Effect_exports.gen(function* () {
|
|
200606
|
+
const parentIssue = yield* findIssueInProject(client, project, newParentParam);
|
|
200607
|
+
return {
|
|
200608
|
+
_tag: "Child",
|
|
200609
|
+
identifier: IssueIdentifier.make(parentIssue.identifier),
|
|
200610
|
+
issue: parentIssue,
|
|
200611
|
+
parent: childIssueParent(parentIssue, project._id)
|
|
200612
|
+
};
|
|
200613
|
+
}) : { _tag: "TopLevel", parent: topLevelIssueParent() };
|
|
200614
|
+
if (target._tag === "Child") {
|
|
200615
|
+
yield* attachIssueChild(client, project._id, issue2._id, target.issue, {});
|
|
200616
|
+
} else {
|
|
200617
|
+
yield* client.updateDoc(tracker.class.Issue, project._id, issue2._id, {
|
|
200618
|
+
attachedTo: toRef(target.parent.attachedTo),
|
|
200619
|
+
attachedToClass: target.parent.attachedToClass,
|
|
200620
|
+
collection: target.parent.collection,
|
|
200621
|
+
parents: target.parent.parents
|
|
200622
|
+
});
|
|
200623
|
+
}
|
|
200624
|
+
if (oldParentIsIssue) {
|
|
200625
|
+
yield* client.updateDoc(
|
|
200626
|
+
tracker.class.Issue,
|
|
200627
|
+
project._id,
|
|
200628
|
+
// issue.attachedTo is Ref<Doc>; for sub-issues it points to the parent issue.
|
|
200629
|
+
// Cast needed because updateDoc expects Ref<HulyIssue> but attachedTo is Ref<Doc>.
|
|
200630
|
+
toRef(issue2.attachedTo),
|
|
200631
|
+
{ $inc: { subIssues: -1 } }
|
|
200632
|
+
);
|
|
200633
|
+
}
|
|
200634
|
+
if (issue2.subIssues > 0) {
|
|
200635
|
+
yield* updateDescendantParents(client, project._id, issue2, target.parent.parents);
|
|
200636
|
+
}
|
|
200637
|
+
const result3 = { identifier: IssueIdentifier.make(issue2.identifier), moved: true };
|
|
200638
|
+
if (target._tag === "Child") {
|
|
200639
|
+
return { ...result3, newParent: target.identifier };
|
|
200640
|
+
}
|
|
200641
|
+
return result3;
|
|
200642
|
+
});
|
|
200643
|
+
updateDescendantParents = (client, spaceId, parentIssue, parentNewParents) => Effect_exports.gen(function* () {
|
|
200644
|
+
const thisParentInfo = {
|
|
200645
|
+
parentId: parentIssue._id,
|
|
200646
|
+
identifier: parentIssue.identifier,
|
|
200647
|
+
parentTitle: parentIssue.title,
|
|
200648
|
+
space: spaceId
|
|
200649
|
+
};
|
|
200650
|
+
const children = yield* client.findAll(
|
|
200651
|
+
tracker.class.Issue,
|
|
200652
|
+
hulyQuery({ attachedTo: parentIssue._id, space: spaceId })
|
|
200653
|
+
);
|
|
200654
|
+
for (const child of children) {
|
|
200655
|
+
const childNewParents = [...parentNewParents, thisParentInfo];
|
|
200656
|
+
yield* client.updateDoc(tracker.class.Issue, spaceId, child._id, { parents: childNewParents });
|
|
200657
|
+
if (child.subIssues > 0) {
|
|
200658
|
+
yield* updateDescendantParents(client, spaceId, child, childNewParents);
|
|
200659
|
+
}
|
|
200660
|
+
}
|
|
200661
|
+
});
|
|
200662
|
+
}
|
|
200663
|
+
});
|
|
200664
|
+
|
|
200665
|
+
// src/huly/operations/issue-creators-read.ts
|
|
200666
|
+
var parsePersonRef, uniqueCreatorIds, creatorRef, creatorForIssue, loadIssueCreatorIndex;
|
|
200667
|
+
var init_issue_creators_read = __esm({
|
|
200668
|
+
"src/huly/operations/issue-creators-read.ts"() {
|
|
200669
|
+
"use strict";
|
|
200670
|
+
init_dist();
|
|
200671
|
+
init_issues();
|
|
200672
|
+
init_tool_warnings();
|
|
200673
|
+
init_diagnostics();
|
|
200674
|
+
init_huly_plugins();
|
|
200675
|
+
init_contacts_shared();
|
|
200676
|
+
init_query_helpers();
|
|
200677
|
+
init_sdk_boundary();
|
|
200678
|
+
parsePersonRef = Schema_exports.decodeUnknownOption(PersonRefSchema);
|
|
200679
|
+
uniqueCreatorIds = (issues) => [
|
|
200680
|
+
...new Set(issues.flatMap((issue2) => issue2.createdBy === void 0 ? [] : [issue2.createdBy]))
|
|
200681
|
+
];
|
|
200682
|
+
creatorRef = (person, emailByPerson) => parsePersonRef({
|
|
200683
|
+
id: person._id,
|
|
200684
|
+
...person.name.trim() === "" ? {} : { name: person.name },
|
|
200685
|
+
...emailByPerson.has(person._id) ? { email: emailByPerson.get(person._id) } : {}
|
|
200686
|
+
});
|
|
200687
|
+
creatorForIssue = (index2, issue2) => issue2.createdBy === void 0 ? void 0 : index2.get(issue2.createdBy);
|
|
200688
|
+
loadIssueCreatorIndex = (client, issues) => Effect_exports.gen(function* () {
|
|
200689
|
+
const creatorIds = uniqueCreatorIds(issues);
|
|
200690
|
+
if (creatorIds.length === 0) return /* @__PURE__ */ new Map();
|
|
200691
|
+
const identities = yield* client.findAll(
|
|
200692
|
+
contact.class.SocialIdentity,
|
|
200693
|
+
hulyQuery({ _id: { $in: creatorIds.map(toSocialIdentityRef) } })
|
|
200694
|
+
);
|
|
200695
|
+
const personIds = [...new Set(identities.map((identity2) => identity2.attachedTo))];
|
|
200696
|
+
const persons = personIds.length === 0 ? [] : yield* client.findAll(
|
|
200697
|
+
contact.class.Person,
|
|
200698
|
+
hulyQuery({ _id: { $in: personIds.map(toRef) } })
|
|
200699
|
+
);
|
|
200700
|
+
const emailByPerson = yield* batchGetEmailsForPersons(
|
|
200701
|
+
client,
|
|
200702
|
+
persons.map((person) => person._id)
|
|
200703
|
+
);
|
|
200704
|
+
const personById = new Map(persons.map((person) => [person._id, person]));
|
|
200705
|
+
const index2 = /* @__PURE__ */ new Map();
|
|
200706
|
+
for (const identity2 of identities) {
|
|
200707
|
+
const person = personById.get(identity2.attachedTo);
|
|
200708
|
+
if (person === void 0) continue;
|
|
200709
|
+
const parsed = creatorRef(person, emailByPerson);
|
|
200710
|
+
if (Option_exports.isSome(parsed)) index2.set(identity2._id, parsed.value);
|
|
200711
|
+
}
|
|
200712
|
+
const unresolvedCount = creatorIds.filter((creatorId) => !index2.has(creatorId)).length;
|
|
200713
|
+
if (unresolvedCount > 0) {
|
|
200714
|
+
const diagnostics = yield* Diagnostics;
|
|
200715
|
+
yield* diagnostics.warnAgent({
|
|
200716
|
+
code: IssueCreatorMetadataDegradedWarningCode,
|
|
200717
|
+
message: `${unresolvedCount} unresolved issue creator reference(s) were omitted from issue results.`
|
|
200718
|
+
});
|
|
200719
|
+
}
|
|
200720
|
+
return index2;
|
|
200721
|
+
});
|
|
200722
|
+
}
|
|
200723
|
+
});
|
|
200724
|
+
|
|
200725
|
+
// src/huly/operations/issue-labels-read.ts
|
|
200726
|
+
var IssueLabelAttachmentBoundarySchema, NormalizedLabelTitle, decodeAttachment, decodeTitle, decodeColor, toDocRef2, toIssueRef, normalizeLabelTitle, COLOR_SORT_WIDTH, compareStrings, candidateSortKey, compareCandidates, toCandidate3, projectionCandidate, projectionDegradationReason, projectCandidateGroup, buildIssueLabelIndex, countReason, degradationMessage, labelsForIssue, issueIdsMatchingLabel, loadIssueLabelIndex;
|
|
200727
|
+
var init_issue_labels_read = __esm({
|
|
200728
|
+
"src/huly/operations/issue-labels-read.ts"() {
|
|
200729
|
+
"use strict";
|
|
200730
|
+
init_dist();
|
|
200731
|
+
init_shared();
|
|
200732
|
+
init_tool_warnings();
|
|
200733
|
+
init_diagnostics();
|
|
200734
|
+
init_huly_plugins();
|
|
200735
|
+
init_query_helpers();
|
|
200736
|
+
init_sdk_boundary();
|
|
200737
|
+
IssueLabelAttachmentBoundarySchema = Schema_exports.Struct({
|
|
200738
|
+
_id: TagReferenceId,
|
|
200739
|
+
attachedTo: IssueId,
|
|
200740
|
+
title: Schema_exports.optional(Schema_exports.Unknown),
|
|
200741
|
+
color: Schema_exports.optional(Schema_exports.Unknown)
|
|
200742
|
+
}).annotate({
|
|
200743
|
+
title: "IssueLabelAttachmentBoundary",
|
|
200744
|
+
description: "Partial Huly TagReference fields used to project issue labels. Missing or malformed presentation fields are handled by stable projection rules."
|
|
200745
|
+
});
|
|
200746
|
+
NormalizedLabelTitle = NonEmptyString2.pipe(Schema_exports.brand("NormalizedLabelTitle"));
|
|
200747
|
+
decodeAttachment = Schema_exports.decodeUnknownResult(IssueLabelAttachmentBoundarySchema);
|
|
200748
|
+
decodeTitle = Schema_exports.decodeUnknownResult(NonEmptyString2);
|
|
200749
|
+
decodeColor = Schema_exports.decodeUnknownResult(ColorCode);
|
|
200750
|
+
toDocRef2 = (id2) => toRef(IssueId.make(id2));
|
|
200751
|
+
toIssueRef = toRef;
|
|
200752
|
+
normalizeLabelTitle = (title) => NormalizedLabelTitle.make(title.toLowerCase());
|
|
200753
|
+
COLOR_SORT_WIDTH = 2;
|
|
200754
|
+
compareStrings = (left, right) => Number(left > right) - Number(left < right);
|
|
200755
|
+
candidateSortKey = (candidate) => [
|
|
200756
|
+
candidate.normalizedTitle,
|
|
200757
|
+
candidate.color === void 0 ? "1" : "0",
|
|
200758
|
+
candidate.title,
|
|
200759
|
+
String(candidate.color).padStart(COLOR_SORT_WIDTH, "0"),
|
|
200760
|
+
candidate.referenceId
|
|
200761
|
+
].join("\0");
|
|
200762
|
+
compareCandidates = (left, right) => compareStrings(candidateSortKey(left), candidateSortKey(right));
|
|
200763
|
+
toCandidate3 = (input) => {
|
|
200764
|
+
const attachment2 = decodeAttachment(input);
|
|
200765
|
+
if (Result_exports.isFailure(attachment2)) {
|
|
200766
|
+
return { _tag: "Rejected", degradationReason: "malformed_attachment" };
|
|
200767
|
+
}
|
|
200768
|
+
const title = decodeTitle(attachment2.success.title);
|
|
200769
|
+
if (Result_exports.isFailure(title)) {
|
|
200770
|
+
return { _tag: "Rejected", degradationReason: "missing_or_malformed_title" };
|
|
200771
|
+
}
|
|
200772
|
+
const colorInput = attachment2.success.color;
|
|
200773
|
+
const color = colorInput === void 0 ? void 0 : decodeColor(colorInput);
|
|
200774
|
+
const candidate = {
|
|
200775
|
+
referenceId: attachment2.success._id,
|
|
200776
|
+
issueId: attachment2.success.attachedTo,
|
|
200777
|
+
title: title.success,
|
|
200778
|
+
normalizedTitle: normalizeLabelTitle(title.success),
|
|
200779
|
+
...color !== void 0 && Result_exports.isSuccess(color) ? { color: color.success } : {}
|
|
200780
|
+
};
|
|
200781
|
+
return color !== void 0 && Result_exports.isFailure(color) ? { _tag: "DegradedSuccess", candidate, degradationReason: "invalid_color" } : { _tag: "Success", candidate };
|
|
200782
|
+
};
|
|
200783
|
+
projectionCandidate = (projection) => projection._tag === "Rejected" ? [] : [projection.candidate];
|
|
200784
|
+
projectionDegradationReason = (projection) => {
|
|
200785
|
+
switch (projection._tag) {
|
|
200786
|
+
case "Success":
|
|
200787
|
+
return [];
|
|
200788
|
+
case "DegradedSuccess":
|
|
200789
|
+
case "Rejected":
|
|
200790
|
+
return [projection.degradationReason];
|
|
200791
|
+
}
|
|
200792
|
+
};
|
|
200793
|
+
projectCandidateGroup = (candidates) => {
|
|
200794
|
+
const sorted = [...candidates].sort(compareCandidates);
|
|
200795
|
+
return sorted.filter(
|
|
200796
|
+
(candidate, index2) => sorted.findIndex((other) => other.normalizedTitle === candidate.normalizedTitle) === index2
|
|
200797
|
+
).map((candidate) => ({
|
|
200798
|
+
title: candidate.title,
|
|
200799
|
+
...candidate.color === void 0 ? {} : { color: candidate.color }
|
|
200800
|
+
}));
|
|
200801
|
+
};
|
|
200802
|
+
buildIssueLabelIndex = (attachments) => {
|
|
200803
|
+
const projections = attachments.map(toCandidate3);
|
|
200804
|
+
const candidates = projections.flatMap(projectionCandidate);
|
|
200805
|
+
const issueIds = [...new Set(candidates.map((candidate) => candidate.issueId))];
|
|
200806
|
+
return {
|
|
200807
|
+
byIssueId: new Map(
|
|
200808
|
+
issueIds.map((issueId) => [
|
|
200809
|
+
issueId,
|
|
200810
|
+
projectCandidateGroup(candidates.filter((candidate) => candidate.issueId === issueId))
|
|
200811
|
+
])
|
|
200812
|
+
),
|
|
200813
|
+
degradationReasons: projections.flatMap(projectionDegradationReason)
|
|
200814
|
+
};
|
|
200815
|
+
};
|
|
200816
|
+
countReason = (reasons, reason) => reasons.filter((candidate) => candidate === reason).length;
|
|
200817
|
+
degradationMessage = (reasons) => {
|
|
200818
|
+
const malformedAttachments = countReason(reasons, "malformed_attachment");
|
|
200819
|
+
const malformedTitles = countReason(reasons, "missing_or_malformed_title");
|
|
200820
|
+
const invalidColors = countReason(reasons, "invalid_color");
|
|
200821
|
+
return `Issue label summaries omitted or partially projected malformed Huly metadata: ${malformedAttachments} malformed attachment(s), ${malformedTitles} missing or malformed title(s), and ${invalidColors} invalid color(s). Duplicate case-insensitive titles prefer a reference with a valid color.`;
|
|
200822
|
+
};
|
|
200823
|
+
labelsForIssue = (index2, issueId) => index2.byIssueId.get(IssueId.make(issueId)) ?? [];
|
|
200824
|
+
issueIdsMatchingLabel = (index2, label) => {
|
|
200825
|
+
const normalizedFilter = normalizeLabelTitle(label);
|
|
200826
|
+
return [...index2.byIssueId].filter(([, labels]) => labels.some((summary) => normalizeLabelTitle(summary.title) === normalizedFilter)).map(([issueId]) => toIssueRef(issueId)).sort(compareStrings);
|
|
200827
|
+
};
|
|
200828
|
+
loadIssueLabelIndex = (client, space, issueIds) => Effect_exports.gen(function* () {
|
|
200829
|
+
if (issueIds !== void 0 && issueIds.length === 0) return buildIssueLabelIndex([]);
|
|
200830
|
+
const diagnostics = yield* Diagnostics;
|
|
200831
|
+
const baseQuery = {
|
|
200832
|
+
space,
|
|
200833
|
+
attachedToClass: tracker.class.Issue,
|
|
200834
|
+
collection: "labels"
|
|
200835
|
+
};
|
|
200836
|
+
const query = issueIds === void 0 ? baseQuery : { ...baseQuery, attachedTo: { $in: issueIds.map(toDocRef2) } };
|
|
200837
|
+
const attachments = yield* client.findAll(tags.class.TagReference, hulyQuery(query));
|
|
200838
|
+
const index2 = buildIssueLabelIndex(attachments);
|
|
200839
|
+
if (index2.degradationReasons.length > 0) {
|
|
200840
|
+
yield* diagnostics.warnAgent({
|
|
200841
|
+
code: IssueLabelMetadataDegradedWarningCode,
|
|
200842
|
+
message: degradationMessage(index2.degradationReasons)
|
|
200843
|
+
});
|
|
200844
|
+
}
|
|
200845
|
+
return index2;
|
|
200846
|
+
});
|
|
200847
|
+
}
|
|
200848
|
+
});
|
|
200849
|
+
|
|
200850
|
+
// src/huly/operations/issue-milestones-read.ts
|
|
200851
|
+
var parseMilestoneRef, uniqueMilestoneRefs, milestoneForIssue, loadIssueMilestoneIndex;
|
|
200852
|
+
var init_issue_milestones_read = __esm({
|
|
200853
|
+
"src/huly/operations/issue-milestones-read.ts"() {
|
|
200854
|
+
"use strict";
|
|
200855
|
+
init_dist();
|
|
200856
|
+
init_issues();
|
|
200857
|
+
init_shared();
|
|
200858
|
+
init_tool_warnings();
|
|
200859
|
+
init_diagnostics();
|
|
200860
|
+
init_huly_plugins();
|
|
200861
|
+
init_query_helpers();
|
|
200862
|
+
parseMilestoneRef = Schema_exports.decodeUnknownOption(IssueMilestoneRefSchema);
|
|
200863
|
+
uniqueMilestoneRefs = (issues) => [
|
|
200864
|
+
...new Set(
|
|
200865
|
+
issues.flatMap((issue2) => issue2.milestone === null || issue2.milestone === void 0 ? [] : [issue2.milestone])
|
|
200866
|
+
)
|
|
200867
|
+
];
|
|
200868
|
+
milestoneForIssue = (index2, issue2) => issue2.milestone === null || issue2.milestone === void 0 ? void 0 : index2.get(MilestoneId.make(issue2.milestone));
|
|
200869
|
+
loadIssueMilestoneIndex = (client, project, issues) => Effect_exports.gen(function* () {
|
|
200870
|
+
const refs = uniqueMilestoneRefs(issues);
|
|
200871
|
+
if (refs.length === 0) return /* @__PURE__ */ new Map();
|
|
200872
|
+
const milestones = yield* client.findAll(
|
|
200873
|
+
tracker.class.Milestone,
|
|
200874
|
+
hulyQuery({ space: project._id, _id: { $in: refs } })
|
|
200875
|
+
);
|
|
200876
|
+
const index2 = /* @__PURE__ */ new Map();
|
|
200877
|
+
for (const milestone of milestones) {
|
|
200175
200878
|
const parsed = parseMilestoneRef({ id: milestone._id, label: milestone.label });
|
|
200176
200879
|
if (Option_exports.isSome(parsed)) index2.set(parsed.value.id, parsed.value);
|
|
200177
200880
|
}
|
|
@@ -200251,12 +200954,12 @@ var init_milestone_resolution = __esm({
|
|
|
200251
200954
|
});
|
|
200252
200955
|
|
|
200253
200956
|
// src/huly/operations/issues-read.ts
|
|
200254
|
-
var
|
|
200957
|
+
var import_core90, import_tracker5, resolveStatusName, hasUnknownStatusCategory, requireKnownStatusCategories, statusIdsByCategory, applyStatusAndAssigneeFilters, applyCreatorFilter, applyIssueTextFilters, applyIssuePresenceFilters, applyIssueScopeFilters, applyIssueMilestoneFilter, applyIssueQueryFilters, issueSummaryProjection, findIssueForRead, loadIssueAssignee, loadIssueDescription, issueDetailRelationshipFields, issueDetailMetricFields, issueDetailProjection, listIssues, getIssue;
|
|
200255
200958
|
var init_issues_read = __esm({
|
|
200256
200959
|
"src/huly/operations/issues-read.ts"() {
|
|
200257
200960
|
"use strict";
|
|
200258
|
-
|
|
200259
|
-
|
|
200961
|
+
import_core90 = __toESM(require_lib6(), 1);
|
|
200962
|
+
import_tracker5 = __toESM(require_lib25(), 1);
|
|
200260
200963
|
init_dist();
|
|
200261
200964
|
init_issues();
|
|
200262
200965
|
init_shared();
|
|
@@ -200264,6 +200967,7 @@ var init_issues_read = __esm({
|
|
|
200264
200967
|
init_huly_plugins();
|
|
200265
200968
|
init_components2();
|
|
200266
200969
|
init_contacts_shared();
|
|
200970
|
+
init_issue_assignee_resolution();
|
|
200267
200971
|
init_issue_creators_read();
|
|
200268
200972
|
init_issue_labels_read();
|
|
200269
200973
|
init_issue_milestones_read();
|
|
@@ -200294,9 +200998,9 @@ var init_issues_read = __esm({
|
|
|
200294
200998
|
query.status = yield* resolveStatusByName([...statuses], params2.status, params2.project);
|
|
200295
200999
|
}
|
|
200296
201000
|
if (params2.assignee !== void 0) {
|
|
200297
|
-
const assigneePerson = yield*
|
|
200298
|
-
if (assigneePerson
|
|
200299
|
-
query.assignee = assigneePerson._id;
|
|
201001
|
+
const assigneePerson = yield* findIssueAssignee(client, params2.assignee);
|
|
201002
|
+
if (Option_exports.isNone(assigneePerson)) return false;
|
|
201003
|
+
query.assignee = assigneePerson.value._id;
|
|
200300
201004
|
}
|
|
200301
201005
|
return true;
|
|
200302
201006
|
});
|
|
@@ -200436,164 +201140,55 @@ var init_issues_read = __esm({
|
|
|
200436
201140
|
tracker.class.Issue,
|
|
200437
201141
|
hulyQuery(effectiveQuery),
|
|
200438
201142
|
withLookup(
|
|
200439
|
-
{ limit, sort: { modifiedOn:
|
|
201143
|
+
{ limit, sort: { modifiedOn: import_core90.SortingOrder.Descending } },
|
|
200440
201144
|
{ assignee: contact.class.Person }
|
|
200441
201145
|
)
|
|
200442
201146
|
);
|
|
200443
201147
|
const labelIndex = labelFilterContext === void 0 ? yield* loadIssueLabelIndex(
|
|
200444
201148
|
client,
|
|
200445
|
-
project._id,
|
|
200446
|
-
issues.map((issue2) => issue2._id)
|
|
200447
|
-
) : labelFilterContext.index;
|
|
200448
|
-
const milestoneIndex = yield* loadIssueMilestoneIndex(client, project, issues);
|
|
200449
|
-
const creatorIndex = yield* loadIssueCreatorIndex(client, issues);
|
|
200450
|
-
const rawSummaries = issues.map(
|
|
200451
|
-
(issue2) => issueSummaryProjection(issue2, statuses, labelIndex, milestoneIndex, creatorIndex)
|
|
200452
|
-
);
|
|
200453
|
-
const parseIssueSummaries = Schema_exports.decodeUnknownEffect(Schema_exports.Array(IssueSummarySchema));
|
|
200454
|
-
const validated = yield* parseIssueSummaries(rawSummaries).pipe(
|
|
200455
|
-
Effect_exports.mapError(
|
|
200456
|
-
(parseError) => new HulyDataInvalidError({ operation: "listIssues", entity: "issue", cause: parseError })
|
|
200457
|
-
)
|
|
200458
|
-
);
|
|
200459
|
-
return [...validated];
|
|
200460
|
-
});
|
|
200461
|
-
getIssue = (params2) => Effect_exports.gen(function* () {
|
|
200462
|
-
const { client, project, statuses } = yield* findProjectWithStatuses(params2.project);
|
|
200463
|
-
const issue2 = yield* findIssueForRead(client, project, params2);
|
|
200464
|
-
const statusName = resolveStatusName(statuses, issue2.status);
|
|
200465
|
-
const person = yield* loadIssueAssignee(client, issue2);
|
|
200466
|
-
const description = yield* loadIssueDescription(client, issue2);
|
|
200467
|
-
const labelIndex = yield* loadIssueLabelIndex(client, project._id, [issue2._id]);
|
|
200468
|
-
const milestoneIndex = yield* loadIssueMilestoneIndex(client, project, [issue2]);
|
|
200469
|
-
const creatorIndex = yield* loadIssueCreatorIndex(client, [issue2]);
|
|
200470
|
-
const milestone = milestoneForIssue(milestoneIndex, issue2);
|
|
200471
|
-
const creator = creatorForIssue(creatorIndex, issue2);
|
|
200472
|
-
const projected = issueDetailProjection(
|
|
200473
|
-
issue2,
|
|
200474
|
-
params2,
|
|
200475
|
-
statusName,
|
|
200476
|
-
person,
|
|
200477
|
-
description,
|
|
200478
|
-
labelsForIssue(labelIndex, issue2._id),
|
|
200479
|
-
milestone,
|
|
200480
|
-
creator
|
|
200481
|
-
);
|
|
200482
|
-
return yield* parseIssue(projected).pipe(
|
|
200483
|
-
Effect_exports.mapError(
|
|
200484
|
-
(parseError) => new HulyDataInvalidError({ operation: "getIssue", entity: "issue", cause: parseError })
|
|
200485
|
-
)
|
|
200486
|
-
);
|
|
200487
|
-
});
|
|
200488
|
-
}
|
|
200489
|
-
});
|
|
200490
|
-
|
|
200491
|
-
// src/huly/operations/issue-native-references.ts
|
|
200492
|
-
var renderIssueDescriptionForWrite;
|
|
200493
|
-
var init_issue_native_references = __esm({
|
|
200494
|
-
"src/huly/operations/issue-native-references.ts"() {
|
|
200495
|
-
"use strict";
|
|
200496
|
-
init_dist();
|
|
200497
|
-
init_client();
|
|
200498
|
-
init_errors4();
|
|
200499
|
-
init_native_reference_markup();
|
|
200500
|
-
renderIssueDescriptionForWrite = (description) => Effect_exports.gen(function* () {
|
|
200501
|
-
const client = yield* HulyClient;
|
|
200502
|
-
const rendered = renderMarkdownWithNativeReferencesForWrite(description, client.markupUrlConfig, "description");
|
|
200503
|
-
if (rendered._tag === "malformed") {
|
|
200504
|
-
return yield* new IssueReferenceError({ reason: rendered.reason });
|
|
200505
|
-
}
|
|
200506
|
-
return rendered.rendered;
|
|
200507
|
-
});
|
|
200508
|
-
}
|
|
200509
|
-
});
|
|
200510
|
-
|
|
200511
|
-
// src/huly/operations/issues-write-shared.ts
|
|
200512
|
-
var resolveAssignee, TASK_TYPE_DISCOVERY_HINT, taskTypeMatches, describeTaskTypeOptions, mergeTaskTypes2, resolveTaskTypeWorkflow, validStatusNames, resolveStatusForTaskType, chooseStatusForTaskType;
|
|
200513
|
-
var init_issues_write_shared = __esm({
|
|
200514
|
-
"src/huly/operations/issues-write-shared.ts"() {
|
|
200515
|
-
"use strict";
|
|
200516
|
-
init_dist();
|
|
200517
|
-
init_normalize();
|
|
200518
|
-
init_errors4();
|
|
200519
|
-
init_huly_plugins();
|
|
200520
|
-
init_contacts_shared();
|
|
200521
|
-
init_query_helpers();
|
|
200522
|
-
resolveAssignee = (client, assigneeIdentifier) => Effect_exports.gen(function* () {
|
|
200523
|
-
const person = yield* findPersonByEmailOrName(client, assigneeIdentifier);
|
|
200524
|
-
if (person === void 0) {
|
|
200525
|
-
return yield* new PersonNotFoundError({ identifier: assigneeIdentifier });
|
|
200526
|
-
}
|
|
200527
|
-
return person;
|
|
200528
|
-
});
|
|
200529
|
-
TASK_TYPE_DISCOVERY_HINT = "Use list_task_types or get_project_type to discover valid task types and statuses.";
|
|
200530
|
-
taskTypeMatches = (taskType, taskTypeRef) => String(taskType._id) === String(taskTypeRef) || normalizeForComparison(taskType.name) === normalizeForComparison(taskTypeRef);
|
|
200531
|
-
describeTaskTypeOptions = (taskTypes) => taskTypes.length === 0 ? "No task types are configured for this project type." : `Available task types: ${taskTypes.map((taskType) => `${taskType.name} (${taskType._id})`).join(", ")}.`;
|
|
200532
|
-
mergeTaskTypes2 = (first, second) => {
|
|
200533
|
-
const taskTypesById = /* @__PURE__ */ new Map();
|
|
200534
|
-
for (const taskType of [...first, ...second]) {
|
|
200535
|
-
taskTypesById.set(String(taskType._id), taskType);
|
|
200536
|
-
}
|
|
200537
|
-
return [...taskTypesById.values()];
|
|
200538
|
-
};
|
|
200539
|
-
resolveTaskTypeWorkflow = (client, project, projectType, projectStatuses, taskTypeRef, projectIdentifier) => Effect_exports.gen(function* () {
|
|
200540
|
-
const workflowProjectType = projectType ?? (yield* client.findOne(task.class.ProjectType, hulyQuery({ _id: project.type })));
|
|
200541
|
-
if (workflowProjectType === void 0) {
|
|
200542
|
-
return yield* Effect_exports.fail(
|
|
200543
|
-
new HulyError({
|
|
200544
|
-
message: `Project '${projectIdentifier}' does not expose a project type/workflow, so taskType cannot be resolved. ${TASK_TYPE_DISCOVERY_HINT}`
|
|
200545
|
-
})
|
|
200546
|
-
);
|
|
200547
|
-
}
|
|
200548
|
-
const taskTypesByProjectTypeList = yield* client.findAll(
|
|
200549
|
-
task.class.TaskType,
|
|
200550
|
-
hulyQuery({ _id: { $in: [...workflowProjectType.tasks] } })
|
|
200551
|
-
);
|
|
200552
|
-
const taskTypesByParent = yield* client.findAll(
|
|
200553
|
-
task.class.TaskType,
|
|
200554
|
-
hulyQuery({ parent: workflowProjectType._id })
|
|
200555
|
-
);
|
|
200556
|
-
const taskTypes = mergeTaskTypes2([...taskTypesByProjectTypeList], [...taskTypesByParent]);
|
|
200557
|
-
const matches = [...taskTypes].filter((candidate) => taskTypeMatches(candidate, taskTypeRef));
|
|
200558
|
-
const selectedTaskType = matches.length === 1 ? matches[0] : void 0;
|
|
200559
|
-
if (selectedTaskType === void 0) {
|
|
200560
|
-
const reason = matches.length === 0 ? "was not found" : "matched more than one task type";
|
|
200561
|
-
return yield* Effect_exports.fail(
|
|
200562
|
-
new HulyError({
|
|
200563
|
-
message: `Task type '${taskTypeRef}' ${reason} in project '${projectIdentifier}' workflow. ${describeTaskTypeOptions([...taskTypes])} ${TASK_TYPE_DISCOVERY_HINT}`
|
|
200564
|
-
})
|
|
200565
|
-
);
|
|
200566
|
-
}
|
|
200567
|
-
const scopedStatuses = selectedTaskType.statuses.flatMap(
|
|
200568
|
-
(statusId) => projectStatuses.filter((status) => status._id === statusId)
|
|
201149
|
+
project._id,
|
|
201150
|
+
issues.map((issue2) => issue2._id)
|
|
201151
|
+
) : labelFilterContext.index;
|
|
201152
|
+
const milestoneIndex = yield* loadIssueMilestoneIndex(client, project, issues);
|
|
201153
|
+
const creatorIndex = yield* loadIssueCreatorIndex(client, issues);
|
|
201154
|
+
const rawSummaries = issues.map(
|
|
201155
|
+
(issue2) => issueSummaryProjection(issue2, statuses, labelIndex, milestoneIndex, creatorIndex)
|
|
200569
201156
|
);
|
|
200570
|
-
const
|
|
200571
|
-
|
|
201157
|
+
const parseIssueSummaries = Schema_exports.decodeUnknownEffect(Schema_exports.Array(IssueSummarySchema));
|
|
201158
|
+
const validated = yield* parseIssueSummaries(rawSummaries).pipe(
|
|
201159
|
+
Effect_exports.mapError(
|
|
201160
|
+
(parseError) => new HulyDataInvalidError({ operation: "listIssues", entity: "issue", cause: parseError })
|
|
201161
|
+
)
|
|
201162
|
+
);
|
|
201163
|
+
return [...validated];
|
|
200572
201164
|
});
|
|
200573
|
-
|
|
200574
|
-
|
|
200575
|
-
const
|
|
200576
|
-
const
|
|
200577
|
-
const
|
|
200578
|
-
|
|
200579
|
-
|
|
200580
|
-
|
|
200581
|
-
|
|
201165
|
+
getIssue = (params2) => Effect_exports.gen(function* () {
|
|
201166
|
+
const { client, project, statuses } = yield* findProjectWithStatuses(params2.project);
|
|
201167
|
+
const issue2 = yield* findIssueForRead(client, project, params2);
|
|
201168
|
+
const statusName = resolveStatusName(statuses, issue2.status);
|
|
201169
|
+
const person = yield* loadIssueAssignee(client, issue2);
|
|
201170
|
+
const description = yield* loadIssueDescription(client, issue2);
|
|
201171
|
+
const labelIndex = yield* loadIssueLabelIndex(client, project._id, [issue2._id]);
|
|
201172
|
+
const milestoneIndex = yield* loadIssueMilestoneIndex(client, project, [issue2]);
|
|
201173
|
+
const creatorIndex = yield* loadIssueCreatorIndex(client, [issue2]);
|
|
201174
|
+
const milestone = milestoneForIssue(milestoneIndex, issue2);
|
|
201175
|
+
const creator = creatorForIssue(creatorIndex, issue2);
|
|
201176
|
+
const projected = issueDetailProjection(
|
|
201177
|
+
issue2,
|
|
201178
|
+
params2,
|
|
201179
|
+
statusName,
|
|
201180
|
+
person,
|
|
201181
|
+
description,
|
|
201182
|
+
labelsForIssue(labelIndex, issue2._id),
|
|
201183
|
+
milestone,
|
|
201184
|
+
creator
|
|
200582
201185
|
);
|
|
200583
|
-
|
|
200584
|
-
|
|
200585
|
-
|
|
200586
|
-
|
|
200587
|
-
}
|
|
200588
|
-
if (currentStatus !== void 0 && workflow.taskType.statuses.includes(currentStatus)) {
|
|
200589
|
-
return Effect_exports.succeed(currentStatus);
|
|
200590
|
-
}
|
|
200591
|
-
return workflow.defaultStatusId !== void 0 ? Effect_exports.succeed(workflow.defaultStatusId) : Effect_exports.fail(
|
|
200592
|
-
new HulyError({
|
|
200593
|
-
message: `Task type '${workflow.taskType.name}' in project '${projectIdentifier}' has no valid status. ${TASK_TYPE_DISCOVERY_HINT}`
|
|
200594
|
-
})
|
|
201186
|
+
return yield* parseIssue(projected).pipe(
|
|
201187
|
+
Effect_exports.mapError(
|
|
201188
|
+
(parseError) => new HulyDataInvalidError({ operation: "getIssue", entity: "issue", cause: parseError })
|
|
201189
|
+
)
|
|
200595
201190
|
);
|
|
200596
|
-
};
|
|
201191
|
+
});
|
|
200597
201192
|
}
|
|
200598
201193
|
});
|
|
200599
201194
|
|
|
@@ -200698,127 +201293,6 @@ var init_issues_update = __esm({
|
|
|
200698
201293
|
}
|
|
200699
201294
|
});
|
|
200700
201295
|
|
|
200701
|
-
// src/huly/operations/issues-write.ts
|
|
200702
|
-
var import_core89, import_rank5, import_tracker5, TxIncResult2, extractUpdatedSequence, requireUpdatedSequence, resolveCreateIssueTaskType, resolveCreateIssueStatus, resolveCreateIssueAssignee, renderCreateIssueDescription, resolveCreateIssueParent, uploadCreateIssueDescription, createIssue, deleteIssue;
|
|
200703
|
-
var init_issues_write = __esm({
|
|
200704
|
-
"src/huly/operations/issues-write.ts"() {
|
|
200705
|
-
"use strict";
|
|
200706
|
-
import_core89 = __toESM(require_lib6(), 1);
|
|
200707
|
-
import_rank5 = __toESM(require_lib24(), 1);
|
|
200708
|
-
import_tracker5 = __toESM(require_lib25(), 1);
|
|
200709
|
-
init_dist();
|
|
200710
|
-
init_issues();
|
|
200711
|
-
init_shared();
|
|
200712
|
-
init_errors4();
|
|
200713
|
-
init_huly_plugins();
|
|
200714
|
-
init_issue_native_references();
|
|
200715
|
-
init_issues_parent();
|
|
200716
|
-
init_issues_shared();
|
|
200717
|
-
init_issues_write_shared();
|
|
200718
|
-
init_query_helpers();
|
|
200719
|
-
init_sdk_boundary();
|
|
200720
|
-
TxIncResult2 = Schema_exports.Struct({ object: Schema_exports.Struct({ sequence: Schema_exports.Number }) });
|
|
200721
|
-
extractUpdatedSequence = (txResult) => {
|
|
200722
|
-
const decoded = Schema_exports.decodeUnknownOption(TxIncResult2)(txResult);
|
|
200723
|
-
return decoded._tag === "Some" ? decoded.value.object.sequence : void 0;
|
|
200724
|
-
};
|
|
200725
|
-
requireUpdatedSequence = (txResult, projectIdentifier) => {
|
|
200726
|
-
const sequence = extractUpdatedSequence(txResult);
|
|
200727
|
-
return sequence === void 0 ? Effect_exports.fail(
|
|
200728
|
-
new HulyError({
|
|
200729
|
-
message: `Project '${projectIdentifier}' sequence increment did not return the updated sequence; issue creation stopped to avoid a duplicate identifier.`
|
|
200730
|
-
})
|
|
200731
|
-
) : Effect_exports.succeed(sequence);
|
|
200732
|
-
};
|
|
200733
|
-
resolveCreateIssueTaskType = (client, project, workflow, params2) => params2.taskType === void 0 ? Effect_exports.succeed(void 0) : resolveTaskTypeWorkflow(client, project, workflow.projectType, workflow.statuses, params2.taskType, params2.project);
|
|
200734
|
-
resolveCreateIssueStatus = (workflow, taskTypeWorkflow, params2) => {
|
|
200735
|
-
if (taskTypeWorkflow !== void 0) {
|
|
200736
|
-
return chooseStatusForTaskType(taskTypeWorkflow, params2.status, void 0, params2.project);
|
|
200737
|
-
}
|
|
200738
|
-
if (params2.status !== void 0) return resolveStatusByName(workflow.statuses, params2.status, params2.project);
|
|
200739
|
-
if (workflow.defaultStatusId !== void 0) return Effect_exports.succeed(workflow.defaultStatusId);
|
|
200740
|
-
return Effect_exports.fail(new InvalidStatusError({ status: "(default)", project: params2.project }));
|
|
200741
|
-
};
|
|
200742
|
-
resolveCreateIssueAssignee = (client, params2) => params2.assignee === void 0 ? Effect_exports.succeed(null) : Effect_exports.map(resolveAssignee(client, params2.assignee), (person) => person._id);
|
|
200743
|
-
renderCreateIssueDescription = (params2) => params2.description !== void 0 && params2.description.trim() !== "" ? renderIssueDescriptionForWrite(params2.description) : Effect_exports.succeed(void 0);
|
|
200744
|
-
resolveCreateIssueParent = (client, project, parentIssue) => parentIssue === void 0 ? Effect_exports.succeed(topLevelIssueParent()) : Effect_exports.map(findIssueInProject(client, project, parentIssue), (parent) => childIssueParent(parent, project._id));
|
|
200745
|
-
uploadCreateIssueDescription = (client, issueId, renderedDescription) => renderedDescription === void 0 ? Effect_exports.succeed(null) : client.uploadMarkup(
|
|
200746
|
-
tracker.class.Issue,
|
|
200747
|
-
issueId,
|
|
200748
|
-
"description",
|
|
200749
|
-
renderedDescription.markup,
|
|
200750
|
-
renderedDescription.format
|
|
200751
|
-
);
|
|
200752
|
-
createIssue = (params2) => Effect_exports.gen(function* () {
|
|
200753
|
-
const { client, defaultStatusId, project, projectType, statuses } = yield* findProjectWithStatuses(params2.project);
|
|
200754
|
-
const issueId = (0, import_core89.generateId)();
|
|
200755
|
-
const workflow = { projectType, statuses, defaultStatusId };
|
|
200756
|
-
const taskTypeWorkflow = yield* resolveCreateIssueTaskType(client, project, workflow, params2);
|
|
200757
|
-
const statusRef = yield* resolveCreateIssueStatus(workflow, taskTypeWorkflow, params2);
|
|
200758
|
-
const assigneeRef = yield* resolveCreateIssueAssignee(client, params2);
|
|
200759
|
-
const renderedDescription = yield* renderCreateIssueDescription(params2);
|
|
200760
|
-
const { attachedTo, attachedToClass, collection, parents } = yield* resolveCreateIssueParent(
|
|
200761
|
-
client,
|
|
200762
|
-
project,
|
|
200763
|
-
params2.parentIssue
|
|
200764
|
-
);
|
|
200765
|
-
const incOps = { $inc: { sequence: 1 } };
|
|
200766
|
-
const incResult = yield* client.updateDoc(
|
|
200767
|
-
tracker.class.Project,
|
|
200768
|
-
toRef("core:space:Space"),
|
|
200769
|
-
project._id,
|
|
200770
|
-
incOps,
|
|
200771
|
-
true
|
|
200772
|
-
);
|
|
200773
|
-
const sequence = yield* requireUpdatedSequence(incResult, params2.project);
|
|
200774
|
-
const lastIssue = yield* client.findOne(
|
|
200775
|
-
tracker.class.Issue,
|
|
200776
|
-
hulyQuery({ space: project._id }),
|
|
200777
|
-
{ sort: { rank: import_core89.SortingOrder.Descending } }
|
|
200778
|
-
);
|
|
200779
|
-
const rank = (0, import_rank5.makeRank)(lastIssue?.rank, void 0);
|
|
200780
|
-
const descriptionMarkupRef = yield* uploadCreateIssueDescription(client, issueId, renderedDescription);
|
|
200781
|
-
const priority = stringToPriority(params2.priority ?? DEFAULT_ISSUE_PRIORITY);
|
|
200782
|
-
const identifier2 = `${project.identifier}-${sequence}`;
|
|
200783
|
-
const issueData = {
|
|
200784
|
-
title: params2.title,
|
|
200785
|
-
description: descriptionMarkupRef,
|
|
200786
|
-
status: statusRef,
|
|
200787
|
-
number: sequence,
|
|
200788
|
-
kind: taskTypeWorkflow?.taskType._id ?? tracker.taskTypes.Issue,
|
|
200789
|
-
identifier: identifier2,
|
|
200790
|
-
priority,
|
|
200791
|
-
assignee: assigneeRef,
|
|
200792
|
-
component: null,
|
|
200793
|
-
estimation: params2.estimation ?? 0,
|
|
200794
|
-
remainingTime: 0,
|
|
200795
|
-
reportedTime: 0,
|
|
200796
|
-
reports: 0,
|
|
200797
|
-
subIssues: 0,
|
|
200798
|
-
parents,
|
|
200799
|
-
childInfo: [],
|
|
200800
|
-
dueDate: params2.dueDate ?? null,
|
|
200801
|
-
rank
|
|
200802
|
-
};
|
|
200803
|
-
yield* client.addCollection(
|
|
200804
|
-
tracker.class.Issue,
|
|
200805
|
-
project._id,
|
|
200806
|
-
attachedTo,
|
|
200807
|
-
attachedToClass,
|
|
200808
|
-
collection,
|
|
200809
|
-
issueData,
|
|
200810
|
-
issueId
|
|
200811
|
-
);
|
|
200812
|
-
return { identifier: IssueIdentifier.make(identifier2), issueId: IssueId.make(issueId) };
|
|
200813
|
-
});
|
|
200814
|
-
deleteIssue = (params2) => Effect_exports.gen(function* () {
|
|
200815
|
-
const { client, issue: issue2, project } = yield* findProjectAndIssue(params2);
|
|
200816
|
-
yield* client.removeDoc(tracker.class.Issue, project._id, issue2._id);
|
|
200817
|
-
return { identifier: IssueIdentifier.make(issue2.identifier), deleted: true };
|
|
200818
|
-
});
|
|
200819
|
-
}
|
|
200820
|
-
});
|
|
200821
|
-
|
|
200822
201296
|
// src/huly/operations/issues.ts
|
|
200823
201297
|
var init_issues2 = __esm({
|
|
200824
201298
|
"src/huly/operations/issues.ts"() {
|
|
@@ -200830,351 +201304,6 @@ var init_issues2 = __esm({
|
|
|
200830
201304
|
}
|
|
200831
201305
|
});
|
|
200832
201306
|
|
|
200833
|
-
// src/huly/operations/issue-templates.ts
|
|
200834
|
-
var import_core90, NOT_FOUND_INDEX2, findTemplateByIdOrTitle, findProjectAndTemplate, resolveTemplateReferenceLabels, templateChildProjection, resolveChild, buildTemplateChild, listIssueTemplates, getIssueTemplate, createIssueTemplate, resolveIssueFromTemplateAssignee, templateChildCreateParams, templateChildUpdate, createTemplateChildIssues, createIssueFromTemplate, updateIssueTemplate, deleteIssueTemplate, addTemplateChild, removeTemplateChild;
|
|
200835
|
-
var init_issue_templates2 = __esm({
|
|
200836
|
-
"src/huly/operations/issue-templates.ts"() {
|
|
200837
|
-
"use strict";
|
|
200838
|
-
import_core90 = __toESM(require_lib6(), 1);
|
|
200839
|
-
init_dist();
|
|
200840
|
-
init_issue_templates();
|
|
200841
|
-
init_issues();
|
|
200842
|
-
init_shared();
|
|
200843
|
-
init_time();
|
|
200844
|
-
init_assertions();
|
|
200845
|
-
init_errors4();
|
|
200846
|
-
init_clear_field_updates();
|
|
200847
|
-
init_components2();
|
|
200848
|
-
init_contacts_shared();
|
|
200849
|
-
init_issues_parent();
|
|
200850
|
-
init_issues_shared();
|
|
200851
|
-
init_issues2();
|
|
200852
|
-
init_query_helpers();
|
|
200853
|
-
init_sdk_boundary();
|
|
200854
|
-
init_update_guards();
|
|
200855
|
-
init_huly_plugins();
|
|
200856
|
-
init_markup();
|
|
200857
|
-
NOT_FOUND_INDEX2 = -1;
|
|
200858
|
-
findTemplateByIdOrTitle = (client, projectId, templateIdOrTitle) => Effect_exports.gen(function* () {
|
|
200859
|
-
const template = (yield* client.findOne(tracker.class.IssueTemplate, {
|
|
200860
|
-
space: projectId,
|
|
200861
|
-
_id: toRef(templateIdOrTitle)
|
|
200862
|
-
})) ?? (yield* client.findOne(tracker.class.IssueTemplate, {
|
|
200863
|
-
space: projectId,
|
|
200864
|
-
title: templateIdOrTitle
|
|
200865
|
-
}));
|
|
200866
|
-
return template;
|
|
200867
|
-
});
|
|
200868
|
-
findProjectAndTemplate = (params2) => Effect_exports.gen(function* () {
|
|
200869
|
-
const { client, project } = yield* findProject(params2.project);
|
|
200870
|
-
const template = yield* findTemplateByIdOrTitle(client, project._id, params2.template);
|
|
200871
|
-
if (template === void 0) {
|
|
200872
|
-
return yield* new IssueTemplateNotFoundError({ identifier: params2.template, project: params2.project });
|
|
200873
|
-
}
|
|
200874
|
-
return { client, project, template };
|
|
200875
|
-
});
|
|
200876
|
-
resolveTemplateReferenceLabels = (client, assignee, component) => Effect_exports.gen(function* () {
|
|
200877
|
-
const assigneeName = assignee === null ? void 0 : (yield* client.findOne(contact.class.Person, hulyQuery({ _id: assignee })))?.name;
|
|
200878
|
-
const componentLabel = component === null ? void 0 : (yield* client.findOne(tracker.class.Component, hulyQuery({ _id: component })))?.label;
|
|
200879
|
-
return {
|
|
200880
|
-
...assigneeName === void 0 ? {} : { assigneeName },
|
|
200881
|
-
...componentLabel === void 0 ? {} : { componentLabel }
|
|
200882
|
-
};
|
|
200883
|
-
});
|
|
200884
|
-
templateChildProjection = (child, description, labels) => {
|
|
200885
|
-
const rawEstimation = zeroAsUnset(NonNegativeNumber.make(child.estimation));
|
|
200886
|
-
const estimation = rawEstimation === void 0 ? void 0 : PositiveTimeHours.make(rawEstimation);
|
|
200887
|
-
return {
|
|
200888
|
-
id: IssueTemplateChildId.make(child.id),
|
|
200889
|
-
title: child.title,
|
|
200890
|
-
priority: priorityToString(child.priority),
|
|
200891
|
-
...description === void 0 ? {} : { description },
|
|
200892
|
-
...labels.assigneeName === void 0 ? {} : { assignee: PersonName.make(labels.assigneeName) },
|
|
200893
|
-
...labels.componentLabel === void 0 ? {} : { component: ComponentLabel.make(labels.componentLabel) },
|
|
200894
|
-
...estimation === void 0 ? {} : { estimation }
|
|
200895
|
-
};
|
|
200896
|
-
};
|
|
200897
|
-
resolveChild = (client, markupUrlConfig, child) => Effect_exports.gen(function* () {
|
|
200898
|
-
const labels = yield* resolveTemplateReferenceLabels(client, child.assignee, child.component);
|
|
200899
|
-
const description = child.description ? yield* optionalMarkupToMarkdown(child.description, markupUrlConfig, "", {
|
|
200900
|
-
operation: "getIssueTemplate",
|
|
200901
|
-
entity: "issue template child description"
|
|
200902
|
-
}) : void 0;
|
|
200903
|
-
return templateChildProjection(child, description, labels);
|
|
200904
|
-
});
|
|
200905
|
-
buildTemplateChild = (client, markupUrlConfig, projectId, projectIdentifier, input) => Effect_exports.gen(function* () {
|
|
200906
|
-
const assigneeParam = input.assignee;
|
|
200907
|
-
const assigneeRef = assigneeParam !== void 0 ? yield* Effect_exports.gen(function* () {
|
|
200908
|
-
const person = yield* findPersonByEmailOrName(client, assigneeParam);
|
|
200909
|
-
if (person === void 0) {
|
|
200910
|
-
return yield* new PersonNotFoundError({ identifier: assigneeParam });
|
|
200911
|
-
}
|
|
200912
|
-
return person._id;
|
|
200913
|
-
}) : null;
|
|
200914
|
-
const componentParam = input.component;
|
|
200915
|
-
const componentRef = componentParam !== void 0 ? yield* Effect_exports.gen(function* () {
|
|
200916
|
-
const component = yield* findComponentByIdOrLabel(client, projectId, componentParam);
|
|
200917
|
-
if (component === void 0) {
|
|
200918
|
-
return yield* new ComponentNotFoundError({ identifier: componentParam, project: projectIdentifier });
|
|
200919
|
-
}
|
|
200920
|
-
return component._id;
|
|
200921
|
-
}) : null;
|
|
200922
|
-
return {
|
|
200923
|
-
id: (0, import_core90.generateId)(),
|
|
200924
|
-
title: input.title,
|
|
200925
|
-
description: optionalMarkdownToMarkup(input.description, markupUrlConfig, ""),
|
|
200926
|
-
priority: stringToPriority(input.priority ?? DEFAULT_ISSUE_PRIORITY),
|
|
200927
|
-
assignee: assigneeRef,
|
|
200928
|
-
component: componentRef,
|
|
200929
|
-
estimation: input.estimation ?? 0
|
|
200930
|
-
};
|
|
200931
|
-
});
|
|
200932
|
-
listIssueTemplates = (params2) => Effect_exports.gen(function* () {
|
|
200933
|
-
const { client, project } = yield* findProject(params2.project);
|
|
200934
|
-
const limit = clampLimit(params2.limit);
|
|
200935
|
-
const templates2 = yield* client.findAll(
|
|
200936
|
-
tracker.class.IssueTemplate,
|
|
200937
|
-
{ space: project._id },
|
|
200938
|
-
{ limit, sort: { modifiedOn: import_core90.SortingOrder.Descending } }
|
|
200939
|
-
);
|
|
200940
|
-
const summaries = templates2.map((t) => {
|
|
200941
|
-
const base2 = {
|
|
200942
|
-
id: IssueTemplateId.make(t._id),
|
|
200943
|
-
title: t.title,
|
|
200944
|
-
priority: priorityToString(t.priority),
|
|
200945
|
-
modifiedOn: Timestamp.make(t.modifiedOn)
|
|
200946
|
-
};
|
|
200947
|
-
if (t.children.length > 0) {
|
|
200948
|
-
return { ...base2, childrenCount: Count.make(t.children.length) };
|
|
200949
|
-
}
|
|
200950
|
-
return base2;
|
|
200951
|
-
});
|
|
200952
|
-
return summaries;
|
|
200953
|
-
});
|
|
200954
|
-
getIssueTemplate = (params2) => Effect_exports.gen(function* () {
|
|
200955
|
-
const { client, template } = yield* findProjectAndTemplate(params2);
|
|
200956
|
-
const markupUrlConfig = client.markupUrlConfig;
|
|
200957
|
-
const labels = yield* resolveTemplateReferenceLabels(client, template.assignee, template.component);
|
|
200958
|
-
const description = yield* optionalMarkupToMarkdown(template.description, markupUrlConfig, "", {
|
|
200959
|
-
operation: "getIssueTemplate",
|
|
200960
|
-
entity: "issue template description"
|
|
200961
|
-
});
|
|
200962
|
-
const resolvedChildren = [];
|
|
200963
|
-
for (const child of template.children) {
|
|
200964
|
-
resolvedChildren.push(yield* resolveChild(client, markupUrlConfig, child));
|
|
200965
|
-
}
|
|
200966
|
-
const result3 = {
|
|
200967
|
-
id: IssueTemplateId.make(template._id),
|
|
200968
|
-
title: template.title,
|
|
200969
|
-
description,
|
|
200970
|
-
priority: priorityToString(template.priority),
|
|
200971
|
-
assignee: labels.assigneeName !== void 0 ? PersonName.make(labels.assigneeName) : void 0,
|
|
200972
|
-
component: labels.componentLabel !== void 0 ? ComponentLabel.make(labels.componentLabel) : void 0,
|
|
200973
|
-
estimation: template.estimation > 0 ? PositiveTimeHours.make(template.estimation) : void 0,
|
|
200974
|
-
project: params2.project,
|
|
200975
|
-
modifiedOn: Timestamp.make(template.modifiedOn),
|
|
200976
|
-
createdOn: template.createdOn === void 0 ? void 0 : Timestamp.make(template.createdOn)
|
|
200977
|
-
};
|
|
200978
|
-
if (resolvedChildren.length > 0) {
|
|
200979
|
-
return { ...result3, children: resolvedChildren };
|
|
200980
|
-
}
|
|
200981
|
-
return result3;
|
|
200982
|
-
});
|
|
200983
|
-
createIssueTemplate = (params2) => Effect_exports.gen(function* () {
|
|
200984
|
-
const { client, project } = yield* findProject(params2.project);
|
|
200985
|
-
const markupUrlConfig = client.markupUrlConfig;
|
|
200986
|
-
const templateId = (0, import_core90.generateId)();
|
|
200987
|
-
const assigneeParam = params2.assignee;
|
|
200988
|
-
const assigneeRef = assigneeParam !== void 0 ? yield* Effect_exports.gen(function* () {
|
|
200989
|
-
const person = yield* findPersonByEmailOrName(client, assigneeParam);
|
|
200990
|
-
if (person === void 0) {
|
|
200991
|
-
return yield* new PersonNotFoundError({ identifier: assigneeParam });
|
|
200992
|
-
}
|
|
200993
|
-
return person._id;
|
|
200994
|
-
}) : null;
|
|
200995
|
-
const componentParam = params2.component;
|
|
200996
|
-
const componentRef = componentParam !== void 0 ? yield* Effect_exports.gen(function* () {
|
|
200997
|
-
const component = yield* findComponentByIdOrLabel(client, project._id, componentParam);
|
|
200998
|
-
if (component === void 0) {
|
|
200999
|
-
return yield* new ComponentNotFoundError({ identifier: componentParam, project: params2.project });
|
|
201000
|
-
}
|
|
201001
|
-
return component._id;
|
|
201002
|
-
}) : null;
|
|
201003
|
-
const priority = stringToPriority(params2.priority ?? DEFAULT_ISSUE_PRIORITY);
|
|
201004
|
-
const children = [];
|
|
201005
|
-
if (params2.children !== void 0) {
|
|
201006
|
-
for (const childInput of params2.children) {
|
|
201007
|
-
children.push(yield* buildTemplateChild(client, markupUrlConfig, project._id, params2.project, childInput));
|
|
201008
|
-
}
|
|
201009
|
-
}
|
|
201010
|
-
const templateData = {
|
|
201011
|
-
title: params2.title,
|
|
201012
|
-
description: optionalMarkdownToMarkup(params2.description, markupUrlConfig, ""),
|
|
201013
|
-
priority,
|
|
201014
|
-
assignee: assigneeRef,
|
|
201015
|
-
component: componentRef,
|
|
201016
|
-
estimation: params2.estimation ?? 0,
|
|
201017
|
-
children,
|
|
201018
|
-
comments: 0
|
|
201019
|
-
};
|
|
201020
|
-
yield* client.createDoc(tracker.class.IssueTemplate, project._id, templateData, templateId);
|
|
201021
|
-
return { id: IssueTemplateId.make(templateId), title: params2.title };
|
|
201022
|
-
});
|
|
201023
|
-
resolveIssueFromTemplateAssignee = (client, params2, template) => Effect_exports.gen(function* () {
|
|
201024
|
-
if (params2.assignee !== void 0) return params2.assignee;
|
|
201025
|
-
if (template.assignee === null) return void 0;
|
|
201026
|
-
const person = yield* client.findOne(contact.class.Person, hulyQuery({ _id: template.assignee }));
|
|
201027
|
-
if (person === void 0) return void 0;
|
|
201028
|
-
const emailChannel = yield* client.findOne(
|
|
201029
|
-
contact.class.Channel,
|
|
201030
|
-
hulyQuery({ attachedTo: person._id, provider: contact.channelProvider.Email })
|
|
201031
|
-
);
|
|
201032
|
-
return Email.make(emailChannel?.value ?? person.name);
|
|
201033
|
-
});
|
|
201034
|
-
templateChildCreateParams = (params2, child, markupUrlConfig) => optionalMarkupToMarkdown(child.description, markupUrlConfig, void 0, {
|
|
201035
|
-
operation: "createIssueFromTemplate",
|
|
201036
|
-
entity: "issue template child description"
|
|
201037
|
-
}).pipe(
|
|
201038
|
-
Effect_exports.map(
|
|
201039
|
-
(description) => ({
|
|
201040
|
-
project: params2.project,
|
|
201041
|
-
title: child.title,
|
|
201042
|
-
priority: priorityToString(child.priority),
|
|
201043
|
-
...description === void 0 ? {} : { description }
|
|
201044
|
-
})
|
|
201045
|
-
)
|
|
201046
|
-
);
|
|
201047
|
-
templateChildUpdate = (child) => ({
|
|
201048
|
-
...child.assignee === null ? {} : { assignee: child.assignee },
|
|
201049
|
-
...child.component === null ? {} : { component: child.component },
|
|
201050
|
-
...child.estimation > 0 ? { estimation: child.estimation } : {}
|
|
201051
|
-
});
|
|
201052
|
-
createTemplateChildIssues = (client, project, template, params2, parentResult, title, markupUrlConfig) => Effect_exports.gen(function* () {
|
|
201053
|
-
const parentIssue = {
|
|
201054
|
-
_id: toRef(parentResult.issueId),
|
|
201055
|
-
identifier: parentResult.identifier,
|
|
201056
|
-
title,
|
|
201057
|
-
parents: []
|
|
201058
|
-
};
|
|
201059
|
-
for (const child of template.children) {
|
|
201060
|
-
const childParams = yield* templateChildCreateParams(params2, child, markupUrlConfig);
|
|
201061
|
-
const childResult = yield* createIssue(childParams);
|
|
201062
|
-
yield* attachIssueChild(
|
|
201063
|
-
client,
|
|
201064
|
-
project._id,
|
|
201065
|
-
toRef(childResult.issueId),
|
|
201066
|
-
parentIssue,
|
|
201067
|
-
templateChildUpdate(child)
|
|
201068
|
-
);
|
|
201069
|
-
}
|
|
201070
|
-
});
|
|
201071
|
-
createIssueFromTemplate = (params2) => Effect_exports.gen(function* () {
|
|
201072
|
-
const { client, project, template } = yield* findProjectAndTemplate(params2);
|
|
201073
|
-
const markupUrlConfig = client.markupUrlConfig;
|
|
201074
|
-
const title = params2.title ?? template.title;
|
|
201075
|
-
const description = params2.description ?? (yield* optionalMarkupToMarkdown(template.description, markupUrlConfig, void 0, {
|
|
201076
|
-
operation: "createIssueFromTemplate",
|
|
201077
|
-
entity: "issue template description"
|
|
201078
|
-
}));
|
|
201079
|
-
const priority = params2.priority ?? priorityToString(template.priority);
|
|
201080
|
-
const assignee = yield* resolveIssueFromTemplateAssignee(client, params2, template);
|
|
201081
|
-
const issueParams = {
|
|
201082
|
-
project: params2.project,
|
|
201083
|
-
title,
|
|
201084
|
-
description,
|
|
201085
|
-
priority,
|
|
201086
|
-
assignee,
|
|
201087
|
-
status: params2.status
|
|
201088
|
-
};
|
|
201089
|
-
const result3 = yield* createIssue(issueParams);
|
|
201090
|
-
if (template.component !== null) {
|
|
201091
|
-
yield* client.updateDoc(tracker.class.Issue, project._id, toRef(result3.issueId), {
|
|
201092
|
-
component: template.component
|
|
201093
|
-
});
|
|
201094
|
-
}
|
|
201095
|
-
const includeChildren = params2.includeChildren ?? DEFAULT_INCLUDE_TEMPLATE_CHILDREN;
|
|
201096
|
-
if (includeChildren && template.children.length > 0) {
|
|
201097
|
-
yield* createTemplateChildIssues(client, project, template, params2, result3, title, markupUrlConfig);
|
|
201098
|
-
return { ...result3, childrenCreated: Count.make(template.children.length) };
|
|
201099
|
-
}
|
|
201100
|
-
return result3;
|
|
201101
|
-
});
|
|
201102
|
-
updateIssueTemplate = (params2) => Effect_exports.gen(function* () {
|
|
201103
|
-
yield* requireUpdateFields("update_issue_template", params2, UPDATE_ISSUE_TEMPLATE_FIELDS);
|
|
201104
|
-
const { client, project, template } = yield* findProjectAndTemplate(params2);
|
|
201105
|
-
const markupUrlConfig = client.markupUrlConfig;
|
|
201106
|
-
const updateEntries = {
|
|
201107
|
-
title: Effect_exports.succeed(params2.title === void 0 ? {} : { title: params2.title }),
|
|
201108
|
-
description: Effect_exports.succeed(
|
|
201109
|
-
params2.description === void 0 ? {} : { description: optionalMarkdownToMarkup(clearTextAsEmptyString(params2.description), markupUrlConfig, "") }
|
|
201110
|
-
),
|
|
201111
|
-
priority: Effect_exports.succeed(params2.priority === void 0 ? {} : { priority: stringToPriority(params2.priority) }),
|
|
201112
|
-
assignee: Effect_exports.gen(function* () {
|
|
201113
|
-
if (params2.assignee === void 0) return {};
|
|
201114
|
-
if (params2.assignee === null) return { assignee: null };
|
|
201115
|
-
const person = yield* findPersonByEmailOrName(client, params2.assignee);
|
|
201116
|
-
if (person === void 0) {
|
|
201117
|
-
return yield* new PersonNotFoundError({ identifier: params2.assignee });
|
|
201118
|
-
}
|
|
201119
|
-
return { assignee: person._id };
|
|
201120
|
-
}),
|
|
201121
|
-
component: Effect_exports.gen(function* () {
|
|
201122
|
-
if (params2.component === void 0) return {};
|
|
201123
|
-
if (params2.component === null) return { component: null };
|
|
201124
|
-
const component = yield* findComponentByIdOrLabel(client, project._id, params2.component);
|
|
201125
|
-
if (component === void 0) {
|
|
201126
|
-
return yield* new ComponentNotFoundError({ identifier: params2.component, project: params2.project });
|
|
201127
|
-
}
|
|
201128
|
-
return { component: component._id };
|
|
201129
|
-
}),
|
|
201130
|
-
estimation: Effect_exports.succeed(
|
|
201131
|
-
params2.estimation === void 0 ? {} : { estimation: params2.estimation === null ? 0 : params2.estimation }
|
|
201132
|
-
)
|
|
201133
|
-
};
|
|
201134
|
-
const updateOps = mergeUpdateEntries(
|
|
201135
|
-
yield* Effect_exports.all(Object.values(updateEntries))
|
|
201136
|
-
);
|
|
201137
|
-
yield* client.updateDoc(tracker.class.IssueTemplate, project._id, template._id, updateOps);
|
|
201138
|
-
return { id: IssueTemplateId.make(template._id), updated: true };
|
|
201139
|
-
});
|
|
201140
|
-
deleteIssueTemplate = (params2) => Effect_exports.gen(function* () {
|
|
201141
|
-
const { client, project, template } = yield* findProjectAndTemplate(params2);
|
|
201142
|
-
yield* client.removeDoc(tracker.class.IssueTemplate, project._id, template._id);
|
|
201143
|
-
return { id: IssueTemplateId.make(template._id), deleted: true };
|
|
201144
|
-
});
|
|
201145
|
-
addTemplateChild = (params2) => Effect_exports.gen(function* () {
|
|
201146
|
-
const { client, project, template } = yield* findProjectAndTemplate(params2);
|
|
201147
|
-
const markupUrlConfig = client.markupUrlConfig;
|
|
201148
|
-
const child = yield* buildTemplateChild(client, markupUrlConfig, project._id, params2.project, {
|
|
201149
|
-
title: params2.title,
|
|
201150
|
-
description: params2.description,
|
|
201151
|
-
priority: params2.priority,
|
|
201152
|
-
assignee: params2.assignee,
|
|
201153
|
-
component: params2.component,
|
|
201154
|
-
estimation: params2.estimation
|
|
201155
|
-
});
|
|
201156
|
-
const newChildren = [...template.children, child];
|
|
201157
|
-
yield* client.updateDoc(tracker.class.IssueTemplate, project._id, template._id, { children: newChildren });
|
|
201158
|
-
return { id: IssueTemplateChildId.make(child.id), title: child.title, added: true };
|
|
201159
|
-
});
|
|
201160
|
-
removeTemplateChild = (params2) => Effect_exports.gen(function* () {
|
|
201161
|
-
const { client, project, template } = yield* findProjectAndTemplate(params2);
|
|
201162
|
-
const childIndex = template.children.findIndex((c) => String(c.id) === String(params2.childId));
|
|
201163
|
-
if (childIndex === NOT_FOUND_INDEX2) {
|
|
201164
|
-
return yield* new TemplateChildNotFoundError({
|
|
201165
|
-
childId: params2.childId,
|
|
201166
|
-
template: params2.template,
|
|
201167
|
-
project: params2.project
|
|
201168
|
-
});
|
|
201169
|
-
}
|
|
201170
|
-
const removedChild = assertAt(template.children, childIndex);
|
|
201171
|
-
const newChildren = template.children.filter((_, i) => i !== childIndex);
|
|
201172
|
-
yield* client.updateDoc(tracker.class.IssueTemplate, project._id, template._id, { children: newChildren });
|
|
201173
|
-
return { id: IssueTemplateChildId.make(removedChild.id), title: removedChild.title, removed: true };
|
|
201174
|
-
});
|
|
201175
|
-
}
|
|
201176
|
-
});
|
|
201177
|
-
|
|
201178
201307
|
// src/huly/operations/tags.ts
|
|
201179
201308
|
var import_core91, toTagSummary, buildUpdateTagOperations, listTags, createTag, updateTag, deleteTag, listAttachedTags, attachTag, detachTag;
|
|
201180
201309
|
var init_tags2 = __esm({
|
|
@@ -201464,7 +201593,7 @@ var init_issues3 = __esm({
|
|
|
201464
201593
|
name: "list_issues",
|
|
201465
201594
|
description: `Query Huly issues with optional filters. Returns issues sorted by modification date (newest first). Supports filtering by project, exact workflow status name (status), Huly SDK task.statusCategory key (statusCategory: ${enumValuesDescription(
|
|
201466
201595
|
StatusCategoryValues
|
|
201467
|
-
)}), assignee, creator (raw Person ID, exact email, or exact display name), component, a human-readable attached label title (label, exact and case-insensitive), milestone (project-scoped ID or exact case-insensitive label), milestone presence (hasMilestone), parentIssue (to list children of a specific issue), and isTopLevel (to return only native top-level issues). Creator, label, and milestone filters are applied before the result limit; ambiguous creator display names fail actionably and unknown creators return an empty list. Each result includes creator as a stable Person reference { id, name?, email? } when resolvable and the assigned milestone as { id, label } when resolvable. Supports searching by title substring (titleSearch) and description content (descriptionSearch). Each result includes deterministic label summaries with title and available color; missing labels are an empty array, duplicate titles collapse case-insensitively while preferring a valid color, and unusable partial attachments are omitted with a tool warning.`,
|
|
201596
|
+
)}), assignee (email, Person display name, or exact agent UserProfile title), creator (raw Person ID, exact email, or exact display name), component, a human-readable attached label title (label, exact and case-insensitive), milestone (project-scoped ID or exact case-insensitive label), milestone presence (hasMilestone), parentIssue (to list children of a specific issue), and isTopLevel (to return only native top-level issues). Creator, label, and milestone filters are applied before the result limit; ambiguous creator display names fail actionably and unknown creators return an empty list. Each result includes creator as a stable Person reference { id, name?, email? } when resolvable and the assigned milestone as { id, label } when resolvable. Supports searching by title substring (titleSearch) and description content (descriptionSearch). Each result includes deterministic label summaries with title and available color; missing labels are an empty array, duplicate titles collapse case-insensitively while preferring a valid color, and unusable partial attachments are omitted with a tool warning.`,
|
|
201468
201597
|
category: CATEGORY24,
|
|
201469
201598
|
inputSchema: listIssuesParamsJsonSchema,
|
|
201470
201599
|
resultSchema: ListIssuesResultSchema
|
|
@@ -201486,7 +201615,7 @@ var init_issues3 = __esm({
|
|
|
201486
201615
|
defineTool(
|
|
201487
201616
|
{
|
|
201488
201617
|
name: "create_issue",
|
|
201489
|
-
description: "Create a new issue in a Huly project. Omit parentIssue for a native top-level issue, or specify parentIssue to create a sub-issue. Optionally set taskType by ID or display name; it is resolved within the target project's project type, and status is validated against that task type's workflow. Use list_task_types or get_project_type to discover valid task types and statuses. Description supports markdown formatting; markdown links to current-workspace Huly browse URLs with _class, _id, and label become native references, while external URLs stay normal links. Returns the created issue identifier.",
|
|
201618
|
+
description: "Create a new issue in a Huly project. Assignee accepts an email, Person display name, or exact agent UserProfile title and always stores the linked Person. Omit parentIssue for a native top-level issue, or specify parentIssue to create a sub-issue. Optionally set taskType by ID or display name; it is resolved within the target project's project type, and status is validated against that task type's workflow. Use list_task_types or get_project_type to discover valid task types and statuses. Description supports markdown formatting; markdown links to current-workspace Huly browse URLs with _class, _id, and label become native references, while external URLs stay normal links. Returns the created issue identifier.",
|
|
201490
201619
|
category: CATEGORY24,
|
|
201491
201620
|
inputSchema: createIssueParamsJsonSchema,
|
|
201492
201621
|
resultSchema: CreateIssueResultSchema
|
|
@@ -201497,7 +201626,7 @@ var init_issues3 = __esm({
|
|
|
201497
201626
|
defineTool(
|
|
201498
201627
|
{
|
|
201499
201628
|
name: "update_issue",
|
|
201500
|
-
description: "Update fields on an existing Huly issue. Optionally set taskType by ID or display name; it is resolved within the target project's project type, and the status is preserved only when valid for the new task type. Use list_task_types or get_project_type to discover valid task types and statuses. Only provided fields are modified. Description updates support markdown; markdown links to current-workspace Huly browse URLs with _class, _id, and label become native references, while external URLs stay normal links.",
|
|
201629
|
+
description: "Update fields on an existing Huly issue. Assignee accepts an email, Person display name, or exact agent UserProfile title and always stores the linked Person; use null to unassign. Optionally set taskType by ID or display name; it is resolved within the target project's project type, and the status is preserved only when valid for the new task type. Use list_task_types or get_project_type to discover valid task types and statuses. Only provided fields are modified. Description updates support markdown; markdown links to current-workspace Huly browse URLs with _class, _id, and label become native references, while external URLs stay normal links.",
|
|
201501
201630
|
category: CATEGORY24,
|
|
201502
201631
|
inputSchema: updateIssueParamsJsonSchema,
|
|
201503
201632
|
resultSchema: UpdateIssueResultSchema
|
|
@@ -223136,7 +223265,7 @@ if (unsupportedRuntime) {
|
|
|
223136
223265
|
detectedNodeVersion: process.versions.node,
|
|
223137
223266
|
executable: process.execPath,
|
|
223138
223267
|
requiredNodeVersion: nodeEngineRequirement,
|
|
223139
|
-
serverVersion: "0.
|
|
223268
|
+
serverVersion: "0.50.0"
|
|
223140
223269
|
});
|
|
223141
223270
|
startUnsupportedNodeMcp(config2);
|
|
223142
223271
|
} else {
|