@uipath/packager-tool-datafabric 1.204.0 → 1.205.0-preview.258
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/dist/canonical-path.d.ts +31 -0
- package/dist/index.d.ts +5 -2
- package/dist/index.js +802 -58
- package/dist/init/entity-init-service.d.ts +7 -0
- package/dist/init.js +1243 -451
- package/dist/inline/inline-entity-service.d.ts +209 -0
- package/dist/inline.d.ts +8 -0
- package/dist/inline.js +3665 -0
- package/dist/missing-path.d.ts +19 -0
- package/dist/pack/constants.d.ts +3 -0
- package/dist/pack/verify-pair.d.ts +14 -1
- package/dist/resource/local-entities.d.ts +14 -0
- package/dist/resource/unified-resource-file.d.ts +21 -0
- package/dist/schema/author-field.d.ts +82 -0
- package/dist/schema/create-entity-skeleton.d.ts +21 -0
- package/dist/schema/solution-entity-names.d.ts +45 -0
- package/dist/schema/validate-entity.d.ts +12 -0
- package/dist/sort-names.d.ts +11 -0
- package/package.json +5 -4
package/dist/init.js
CHANGED
|
@@ -7822,6 +7822,16 @@ class NodeFileSystem {
|
|
|
7822
7822
|
async rename(oldPath, newPath) {
|
|
7823
7823
|
await fs6.rename(oldPath, newPath);
|
|
7824
7824
|
}
|
|
7825
|
+
async isSymbolicLink(filePath) {
|
|
7826
|
+
try {
|
|
7827
|
+
return (await fs6.lstat(filePath)).isSymbolicLink();
|
|
7828
|
+
} catch (error) {
|
|
7829
|
+
if (this.isEnoent(error) || this.hasErrnoCode(error, "ENOTDIR")) {
|
|
7830
|
+
return false;
|
|
7831
|
+
}
|
|
7832
|
+
throw error;
|
|
7833
|
+
}
|
|
7834
|
+
}
|
|
7825
7835
|
async realpath(filePath) {
|
|
7826
7836
|
try {
|
|
7827
7837
|
return await fs6.realpath(filePath);
|
|
@@ -8529,7 +8539,7 @@ function setGlobalLogFilePath(path3) {
|
|
|
8529
8539
|
function getGlobalLogFilePath() {
|
|
8530
8540
|
return logFilePathSlot.get("");
|
|
8531
8541
|
}
|
|
8532
|
-
var DEFAULT_LOG_LEVEL =
|
|
8542
|
+
var DEFAULT_LOG_LEVEL = 2 /* WARN */;
|
|
8533
8543
|
|
|
8534
8544
|
class SimpleLogger {
|
|
8535
8545
|
__brand = "SimpleLogger";
|
|
@@ -8796,7 +8806,9 @@ var ErrorDimensions = {
|
|
|
8796
8806
|
Result: "Result",
|
|
8797
8807
|
ErrorCode: "ErrorCode",
|
|
8798
8808
|
Retry: "Retry",
|
|
8799
|
-
ErrorMessage: "ErrorMessage"
|
|
8809
|
+
ErrorMessage: "ErrorMessage",
|
|
8810
|
+
HttpStatus: "HttpStatus",
|
|
8811
|
+
UpstreamErrorCode: "UpstreamErrorCode"
|
|
8800
8812
|
};
|
|
8801
8813
|
var AuthDimensions = {
|
|
8802
8814
|
AuthenticationMethod: "AuthenticationMethod",
|
|
@@ -9778,7 +9790,9 @@ var CLI_ERROR_CODES = [
|
|
|
9778
9790
|
"timeout",
|
|
9779
9791
|
"server_error",
|
|
9780
9792
|
"method_not_allowed",
|
|
9793
|
+
"not_supported",
|
|
9781
9794
|
"configuration_error",
|
|
9795
|
+
"execution_failed",
|
|
9782
9796
|
"unknown_error"
|
|
9783
9797
|
];
|
|
9784
9798
|
var RETRY_HINTS = [
|
|
@@ -10735,7 +10749,9 @@ var OutputFormatter;
|
|
|
10735
10749
|
[ErrorDimensions.Result]: data.Result,
|
|
10736
10750
|
[ErrorDimensions.ErrorCode]: data.ErrorCode,
|
|
10737
10751
|
[ErrorDimensions.Retry]: data.Retry,
|
|
10738
|
-
[ErrorDimensions.ErrorMessage]: data.Message
|
|
10752
|
+
[ErrorDimensions.ErrorMessage]: data.Message,
|
|
10753
|
+
[ErrorDimensions.HttpStatus]: data.Context?.httpStatus?.toString(),
|
|
10754
|
+
[ErrorDimensions.UpstreamErrorCode]: data.Context?.errorCode
|
|
10739
10755
|
});
|
|
10740
10756
|
}
|
|
10741
10757
|
logOutput(normalizeOutputKeys(envelope), getOutputFormat());
|
|
@@ -11270,8 +11286,110 @@ var guardInstalledSlot = singleton("ConsoleGuardInstalled");
|
|
|
11270
11286
|
var savedOriginalsSlot = singleton("ConsoleGuardOriginals");
|
|
11271
11287
|
// ../../common/src/constants.ts
|
|
11272
11288
|
var DEFAULT_AUTH_TIMEOUT_MS = 5 * 60 * 1000;
|
|
11289
|
+
// ../../common/src/entity-field-rules.ts
|
|
11290
|
+
var MAX_SAFE_NUMERIC_BOUND = 9007199254740991;
|
|
11291
|
+
var LENGTH_LIMIT_RANGES = {
|
|
11292
|
+
STRING: [1, 4000],
|
|
11293
|
+
MULTILINE_TEXT: [1, 1e4],
|
|
11294
|
+
MULTILINE_MAX: [1, 131072]
|
|
11295
|
+
};
|
|
11296
|
+
var MAX_MULTILINE_MAX_FIELDS = 10;
|
|
11297
|
+
function isNumber(v) {
|
|
11298
|
+
return typeof v === "number" && Number.isFinite(v);
|
|
11299
|
+
}
|
|
11300
|
+
function findInvalidFieldConstraints(fields) {
|
|
11301
|
+
for (const f of fields) {
|
|
11302
|
+
if (typeof f !== "object" || f === null)
|
|
11303
|
+
continue;
|
|
11304
|
+
const rec = f;
|
|
11305
|
+
const type2 = rec.type;
|
|
11306
|
+
if (typeof type2 !== "string")
|
|
11307
|
+
continue;
|
|
11308
|
+
const fieldName = typeof rec.name === "string" ? rec.name : "<field>";
|
|
11309
|
+
if (rec.lengthLimit !== undefined) {
|
|
11310
|
+
if (!isNumber(rec.lengthLimit) || !Number.isInteger(rec.lengthLimit)) {
|
|
11311
|
+
return {
|
|
11312
|
+
message: `Field '${fieldName}' 'lengthLimit' must be an integer`,
|
|
11313
|
+
instructions: "Pass a positive integer within the type's range (STRING 1-4000, MULTILINE_TEXT 1-10000, MULTILINE_MAX 1-131072 UTF-16 bytes)."
|
|
11314
|
+
};
|
|
11315
|
+
}
|
|
11316
|
+
const range = LENGTH_LIMIT_RANGES[type2];
|
|
11317
|
+
if (range === undefined) {
|
|
11318
|
+
return {
|
|
11319
|
+
message: `Field '${fieldName}' of type '${type2}' does not accept 'lengthLimit'`,
|
|
11320
|
+
instructions: "'lengthLimit' applies only to STRING, MULTILINE_TEXT, and MULTILINE_MAX. Remove it or change the field type."
|
|
11321
|
+
};
|
|
11322
|
+
}
|
|
11323
|
+
const [min, max] = range;
|
|
11324
|
+
if (rec.lengthLimit < min || rec.lengthLimit > max) {
|
|
11325
|
+
return {
|
|
11326
|
+
message: `Field '${fieldName}' 'lengthLimit' ${rec.lengthLimit} is outside the allowed range for type '${type2}'`,
|
|
11327
|
+
instructions: `'lengthLimit' on '${type2}' must be between ${min} and ${max}. MULTILINE_MAX 'lengthLimit' is a UTF-16 byte budget (≈2 per char).`
|
|
11328
|
+
};
|
|
11329
|
+
}
|
|
11330
|
+
}
|
|
11331
|
+
if (rec.maxValue !== undefined || rec.minValue !== undefined) {
|
|
11332
|
+
if (type2 !== "DECIMAL" && type2 !== "AUTO_NUMBER") {
|
|
11333
|
+
const which = rec.maxValue !== undefined ? "maxValue" : "minValue";
|
|
11334
|
+
return {
|
|
11335
|
+
message: `Field '${fieldName}' of type '${type2}' does not accept '${which}'`,
|
|
11336
|
+
instructions: "'minValue' and 'maxValue' apply only to DECIMAL and AUTO_NUMBER. Remove them or change the field type."
|
|
11337
|
+
};
|
|
11338
|
+
}
|
|
11339
|
+
if (rec.maxValue !== undefined && !isNumber(rec.maxValue)) {
|
|
11340
|
+
return {
|
|
11341
|
+
message: `Field '${fieldName}' 'maxValue' must be a number`,
|
|
11342
|
+
instructions: "Pass a numeric value."
|
|
11343
|
+
};
|
|
11344
|
+
}
|
|
11345
|
+
if (rec.minValue !== undefined && !isNumber(rec.minValue)) {
|
|
11346
|
+
return {
|
|
11347
|
+
message: `Field '${fieldName}' 'minValue' must be a number`,
|
|
11348
|
+
instructions: "Pass a numeric value."
|
|
11349
|
+
};
|
|
11350
|
+
}
|
|
11351
|
+
const maxValue = rec.maxValue;
|
|
11352
|
+
if (maxValue !== undefined && (maxValue > MAX_SAFE_NUMERIC_BOUND || maxValue < -MAX_SAFE_NUMERIC_BOUND)) {
|
|
11353
|
+
return {
|
|
11354
|
+
message: `Field '${fieldName}' 'maxValue' ${rec.maxValue} is outside the supported numeric range`,
|
|
11355
|
+
instructions: `Use a value between ${-MAX_SAFE_NUMERIC_BOUND} and ${MAX_SAFE_NUMERIC_BOUND}.`
|
|
11356
|
+
};
|
|
11357
|
+
}
|
|
11358
|
+
const minValue = rec.minValue;
|
|
11359
|
+
if (minValue !== undefined && (minValue > MAX_SAFE_NUMERIC_BOUND || minValue < -MAX_SAFE_NUMERIC_BOUND)) {
|
|
11360
|
+
return {
|
|
11361
|
+
message: `Field '${fieldName}' 'minValue' ${rec.minValue} is outside the supported numeric range`,
|
|
11362
|
+
instructions: `Use a value between ${-MAX_SAFE_NUMERIC_BOUND} and ${MAX_SAFE_NUMERIC_BOUND}.`
|
|
11363
|
+
};
|
|
11364
|
+
}
|
|
11365
|
+
if (rec.maxValue !== undefined && rec.minValue !== undefined && rec.minValue > rec.maxValue) {
|
|
11366
|
+
return {
|
|
11367
|
+
message: `Field '${fieldName}' 'minValue' (${rec.minValue}) must not exceed 'maxValue' (${rec.maxValue})`,
|
|
11368
|
+
instructions: "Adjust the bounds so 'minValue <= maxValue', or drop one of the two."
|
|
11369
|
+
};
|
|
11370
|
+
}
|
|
11371
|
+
}
|
|
11372
|
+
if (rec.decimalPrecision !== undefined) {
|
|
11373
|
+
if (type2 !== "DECIMAL" && type2 !== "AUTO_NUMBER") {
|
|
11374
|
+
return {
|
|
11375
|
+
message: `Field '${fieldName}' of type '${type2}' does not accept 'decimalPrecision'`,
|
|
11376
|
+
instructions: "'decimalPrecision' applies only to DECIMAL and AUTO_NUMBER. Remove it or change the field type."
|
|
11377
|
+
};
|
|
11378
|
+
}
|
|
11379
|
+
if (!isNumber(rec.decimalPrecision) || !Number.isInteger(rec.decimalPrecision) || rec.decimalPrecision < 0 || rec.decimalPrecision > 10) {
|
|
11380
|
+
return {
|
|
11381
|
+
message: `Field '${fieldName}' 'decimalPrecision' ${rec.decimalPrecision} is invalid`,
|
|
11382
|
+
instructions: "'decimalPrecision' must be an integer between 0 and 10 (0 for whole numbers, 2 for money)."
|
|
11383
|
+
};
|
|
11384
|
+
}
|
|
11385
|
+
}
|
|
11386
|
+
}
|
|
11387
|
+
return null;
|
|
11388
|
+
}
|
|
11273
11389
|
// ../../common/src/entity-name-rules.ts
|
|
11274
11390
|
var RESERVED_SQL_KEYWORDS_LOWER = new Set(["group", "order"]);
|
|
11391
|
+
var ENTITY_NAME_PATTERN = /^[a-zA-Z][a-zA-Z0-9_]{2,99}$/;
|
|
11392
|
+
var FIELD_NAME_PATTERN = /^[a-zA-Z][a-zA-Z0-9]{2,99}$/;
|
|
11275
11393
|
var RESERVED_FIELD_NAMES_LOWER = new Set([
|
|
11276
11394
|
"id",
|
|
11277
11395
|
"createdby",
|
|
@@ -11468,6 +11586,37 @@ var RESERVED_KEYWORDS_LOWER = new Set([
|
|
|
11468
11586
|
"writeonly",
|
|
11469
11587
|
"xor"
|
|
11470
11588
|
]);
|
|
11589
|
+
function findReservedNameError(name, kind) {
|
|
11590
|
+
if (kind === "field" && RESERVED_FIELD_NAMES_LOWER.has(name.toLowerCase())) {
|
|
11591
|
+
return {
|
|
11592
|
+
message: `Field name '${name}' is reserved`,
|
|
11593
|
+
instructions: "The following field names are reserved by the platform (case-insensitive): Id, CreatedBy, CreateTime, UpdatedBy, UpdateTime, RecordOwner, Version. Pick a different name."
|
|
11594
|
+
};
|
|
11595
|
+
}
|
|
11596
|
+
if (RESERVED_KEYWORDS_LOWER.has(name.toLowerCase())) {
|
|
11597
|
+
return {
|
|
11598
|
+
message: `${kind === "entity" ? "Entity" : kind === "field" ? "Field" : "Choice set"} name '${name}' is a reserved C# or VB keyword`,
|
|
11599
|
+
instructions: "Reserved keywords are rejected with RESERVED_LANGUAGE_KEYWORDS. Pick a domain-specific rename, for example 'Case' -> 'WorkItem', 'Class' -> 'Category', 'New' -> 'IsNew'."
|
|
11600
|
+
};
|
|
11601
|
+
}
|
|
11602
|
+
if (kind === "entity" && RESERVED_SQL_KEYWORDS_LOWER.has(name.toLowerCase())) {
|
|
11603
|
+
return {
|
|
11604
|
+
message: `Entity name '${name}' is a reserved SQL keyword`,
|
|
11605
|
+
instructions: "The platform rejects 'Order' and 'Group' as entity names. Pick a domain-specific name such as 'PurchaseOrder' or 'TeamGroup'."
|
|
11606
|
+
};
|
|
11607
|
+
}
|
|
11608
|
+
return null;
|
|
11609
|
+
}
|
|
11610
|
+
function validateNameFormat(name, kind) {
|
|
11611
|
+
const pattern = kind === "field" ? FIELD_NAME_PATTERN : ENTITY_NAME_PATTERN;
|
|
11612
|
+
if (pattern.test(name)) {
|
|
11613
|
+
return null;
|
|
11614
|
+
}
|
|
11615
|
+
return {
|
|
11616
|
+
message: `Invalid ${kind} name '${name}'`,
|
|
11617
|
+
instructions: kind === "field" ? "Field names must start with a letter, contain only letters and digits (no underscores), and be 3-100 characters long." : "Names must start with a letter, contain only letters, digits, and underscores, and be 3-100 characters long."
|
|
11618
|
+
};
|
|
11619
|
+
}
|
|
11471
11620
|
// ../../common/src/host-global-options.ts
|
|
11472
11621
|
var HOST_GLOBAL_OPTIONS_WITH_VALUE = [
|
|
11473
11622
|
"--output",
|
|
@@ -11638,6 +11787,10 @@ function installRequestHeaderForwarding(BaseApiClass, patchKey, forward) {
|
|
|
11638
11787
|
function installSdkUserAgentHeader(BaseApiClass, userAgent) {
|
|
11639
11788
|
installRequestHeaderForwarding(BaseApiClass, userAgentPatchKey(userAgent), (headers) => addSdkUserAgentHeader(headers, userAgent));
|
|
11640
11789
|
}
|
|
11790
|
+
// ../../common/src/shell-quote.ts
|
|
11791
|
+
function quoteForShell(value) {
|
|
11792
|
+
return `'${value.replace(/'/g, "'\\''")}'`;
|
|
11793
|
+
}
|
|
11641
11794
|
// ../../common/src/solution-project-types.ts
|
|
11642
11795
|
var LIBRARY_NOT_A_PROJECT = "A library cannot be a project inside a solution — it is a reusable .nupkg that other projects consume as a NuGet dependency, not a deployable unit. Build and publish it on its own ('uip rpa pack <project-dir> <output-path>', then 'uip or libraries upload --file <nupkg-path>'), and reference it from a project's dependencies. To make the published library part of this solution, add it as a resource instead: 'uip solution resources add --source remote --kind Library --name <library-name>'.";
|
|
11643
11796
|
function unsupportedSolutionProjectType(projectType) {
|
|
@@ -11650,296 +11803,6 @@ function unsupportedSolutionProjectType(projectType) {
|
|
|
11650
11803
|
var shippedKeysSlot = singleton("ShipSucceededDedupeKeys");
|
|
11651
11804
|
// ../../common/src/tool-provider.ts
|
|
11652
11805
|
var factorySlot = singleton("PackagerFactoryProvider");
|
|
11653
|
-
// ../../../node_modules/@uipath/entity-modeler/dist/chunk-7VKIHCI7.js
|
|
11654
|
-
var SqlTypeName = {
|
|
11655
|
-
UNIQUEIDENTIFIER: "UNIQUEIDENTIFIER",
|
|
11656
|
-
NVARCHAR: "NVARCHAR",
|
|
11657
|
-
INT: "INT",
|
|
11658
|
-
DATETIME2: "DATETIME2",
|
|
11659
|
-
DATETIMEOFFSET: "DATETIMEOFFSET",
|
|
11660
|
-
FLOAT: "FLOAT",
|
|
11661
|
-
REAL: "REAL",
|
|
11662
|
-
BIGINT: "BIGINT",
|
|
11663
|
-
DATE: "DATE",
|
|
11664
|
-
BIT: "BIT",
|
|
11665
|
-
DECIMAL: "DECIMAL",
|
|
11666
|
-
MULTILINE: "MULTILINE",
|
|
11667
|
-
MULTILINE_MAX: "MULTILINE_MAX",
|
|
11668
|
-
UNKNOWN: "UNKNOWN"
|
|
11669
|
-
};
|
|
11670
|
-
var FieldDisplayType = {
|
|
11671
|
-
Basic: "Basic",
|
|
11672
|
-
Relationship: "Relationship",
|
|
11673
|
-
File: "File",
|
|
11674
|
-
ChoiceSetSingle: "ChoiceSetSingle",
|
|
11675
|
-
ChoiceSetMultiple: "ChoiceSetMultiple",
|
|
11676
|
-
AutoNumber: "AutoNumber",
|
|
11677
|
-
MultiLineText: "MultiLineText"
|
|
11678
|
-
};
|
|
11679
|
-
var NAME_PATTERN = /^[a-zA-Z][a-zA-Z0-9]{2,99}$/;
|
|
11680
|
-
var CSHARP_RESERVED_WORDS = [
|
|
11681
|
-
"__arglist",
|
|
11682
|
-
"__makeref",
|
|
11683
|
-
"__reftype",
|
|
11684
|
-
"__refvalue",
|
|
11685
|
-
"abstract",
|
|
11686
|
-
"as",
|
|
11687
|
-
"base",
|
|
11688
|
-
"bool",
|
|
11689
|
-
"break",
|
|
11690
|
-
"byte",
|
|
11691
|
-
"case",
|
|
11692
|
-
"catch",
|
|
11693
|
-
"char",
|
|
11694
|
-
"checked",
|
|
11695
|
-
"class",
|
|
11696
|
-
"const",
|
|
11697
|
-
"continue",
|
|
11698
|
-
"decimal",
|
|
11699
|
-
"default",
|
|
11700
|
-
"delegate",
|
|
11701
|
-
"do",
|
|
11702
|
-
"double",
|
|
11703
|
-
"else",
|
|
11704
|
-
"enum",
|
|
11705
|
-
"event",
|
|
11706
|
-
"explicit",
|
|
11707
|
-
"extern",
|
|
11708
|
-
"false",
|
|
11709
|
-
"finally",
|
|
11710
|
-
"fixed",
|
|
11711
|
-
"float",
|
|
11712
|
-
"for",
|
|
11713
|
-
"foreach",
|
|
11714
|
-
"goto",
|
|
11715
|
-
"if",
|
|
11716
|
-
"implicit",
|
|
11717
|
-
"in",
|
|
11718
|
-
"int",
|
|
11719
|
-
"interface",
|
|
11720
|
-
"internal",
|
|
11721
|
-
"is",
|
|
11722
|
-
"lock",
|
|
11723
|
-
"long",
|
|
11724
|
-
"namespace",
|
|
11725
|
-
"new",
|
|
11726
|
-
"null",
|
|
11727
|
-
"object",
|
|
11728
|
-
"operator",
|
|
11729
|
-
"out",
|
|
11730
|
-
"override",
|
|
11731
|
-
"params",
|
|
11732
|
-
"partial",
|
|
11733
|
-
"private",
|
|
11734
|
-
"protected",
|
|
11735
|
-
"public",
|
|
11736
|
-
"readonly",
|
|
11737
|
-
"ref",
|
|
11738
|
-
"return",
|
|
11739
|
-
"sbyte",
|
|
11740
|
-
"sealed",
|
|
11741
|
-
"short",
|
|
11742
|
-
"sizeof",
|
|
11743
|
-
"stackalloc",
|
|
11744
|
-
"static",
|
|
11745
|
-
"string",
|
|
11746
|
-
"struct",
|
|
11747
|
-
"switch",
|
|
11748
|
-
"this",
|
|
11749
|
-
"throw",
|
|
11750
|
-
"true",
|
|
11751
|
-
"try",
|
|
11752
|
-
"typeof",
|
|
11753
|
-
"uint",
|
|
11754
|
-
"ulong",
|
|
11755
|
-
"unchecked",
|
|
11756
|
-
"unsafe",
|
|
11757
|
-
"ushort",
|
|
11758
|
-
"using",
|
|
11759
|
-
"virtual",
|
|
11760
|
-
"void",
|
|
11761
|
-
"volatile",
|
|
11762
|
-
"where",
|
|
11763
|
-
"while",
|
|
11764
|
-
"yield"
|
|
11765
|
-
];
|
|
11766
|
-
var VB_RESERVED_WORDS = [
|
|
11767
|
-
"addhandler",
|
|
11768
|
-
"addressof",
|
|
11769
|
-
"alias",
|
|
11770
|
-
"and",
|
|
11771
|
-
"andalso",
|
|
11772
|
-
"ansi",
|
|
11773
|
-
"as",
|
|
11774
|
-
"assembly",
|
|
11775
|
-
"auto",
|
|
11776
|
-
"boolean",
|
|
11777
|
-
"byref",
|
|
11778
|
-
"byte",
|
|
11779
|
-
"byval",
|
|
11780
|
-
"call",
|
|
11781
|
-
"case",
|
|
11782
|
-
"catch",
|
|
11783
|
-
"cbool",
|
|
11784
|
-
"cbyte",
|
|
11785
|
-
"cchar",
|
|
11786
|
-
"cdate",
|
|
11787
|
-
"cdbl",
|
|
11788
|
-
"cdec",
|
|
11789
|
-
"char",
|
|
11790
|
-
"cint",
|
|
11791
|
-
"class",
|
|
11792
|
-
"class_finalize",
|
|
11793
|
-
"class_initialize",
|
|
11794
|
-
"clng",
|
|
11795
|
-
"cobj",
|
|
11796
|
-
"const",
|
|
11797
|
-
"continue",
|
|
11798
|
-
"csbyte",
|
|
11799
|
-
"cshort",
|
|
11800
|
-
"csng",
|
|
11801
|
-
"cstr",
|
|
11802
|
-
"ctype",
|
|
11803
|
-
"cuint",
|
|
11804
|
-
"culng",
|
|
11805
|
-
"cushort",
|
|
11806
|
-
"date",
|
|
11807
|
-
"decimal",
|
|
11808
|
-
"declare",
|
|
11809
|
-
"default",
|
|
11810
|
-
"delegate",
|
|
11811
|
-
"dim",
|
|
11812
|
-
"directcast",
|
|
11813
|
-
"do",
|
|
11814
|
-
"double",
|
|
11815
|
-
"each",
|
|
11816
|
-
"else",
|
|
11817
|
-
"elseif",
|
|
11818
|
-
"end",
|
|
11819
|
-
"endif",
|
|
11820
|
-
"enum",
|
|
11821
|
-
"erase",
|
|
11822
|
-
"error",
|
|
11823
|
-
"event",
|
|
11824
|
-
"exit",
|
|
11825
|
-
"false",
|
|
11826
|
-
"finally",
|
|
11827
|
-
"for",
|
|
11828
|
-
"friend",
|
|
11829
|
-
"function",
|
|
11830
|
-
"get",
|
|
11831
|
-
"gettype",
|
|
11832
|
-
"global",
|
|
11833
|
-
"gosub",
|
|
11834
|
-
"goto",
|
|
11835
|
-
"handles",
|
|
11836
|
-
"if",
|
|
11837
|
-
"implements",
|
|
11838
|
-
"imports",
|
|
11839
|
-
"in",
|
|
11840
|
-
"inherits",
|
|
11841
|
-
"integer",
|
|
11842
|
-
"interface",
|
|
11843
|
-
"is",
|
|
11844
|
-
"isnot",
|
|
11845
|
-
"let",
|
|
11846
|
-
"lib",
|
|
11847
|
-
"like",
|
|
11848
|
-
"long",
|
|
11849
|
-
"loop",
|
|
11850
|
-
"me",
|
|
11851
|
-
"mod",
|
|
11852
|
-
"module",
|
|
11853
|
-
"mustinherit",
|
|
11854
|
-
"mustoverride",
|
|
11855
|
-
"mybase",
|
|
11856
|
-
"myclass",
|
|
11857
|
-
"namespace",
|
|
11858
|
-
"narrowing",
|
|
11859
|
-
"new",
|
|
11860
|
-
"next",
|
|
11861
|
-
"not",
|
|
11862
|
-
"nothing",
|
|
11863
|
-
"notinheritable",
|
|
11864
|
-
"notoverridable",
|
|
11865
|
-
"object",
|
|
11866
|
-
"of",
|
|
11867
|
-
"on",
|
|
11868
|
-
"operator",
|
|
11869
|
-
"option",
|
|
11870
|
-
"optional",
|
|
11871
|
-
"or",
|
|
11872
|
-
"orelse",
|
|
11873
|
-
"overloads",
|
|
11874
|
-
"overridable",
|
|
11875
|
-
"overrides",
|
|
11876
|
-
"paramarray",
|
|
11877
|
-
"partial",
|
|
11878
|
-
"preserve",
|
|
11879
|
-
"private",
|
|
11880
|
-
"property",
|
|
11881
|
-
"protected",
|
|
11882
|
-
"public",
|
|
11883
|
-
"raiseevent",
|
|
11884
|
-
"readonly",
|
|
11885
|
-
"redim",
|
|
11886
|
-
"rem",
|
|
11887
|
-
"removehandler",
|
|
11888
|
-
"resume",
|
|
11889
|
-
"return",
|
|
11890
|
-
"sbyte",
|
|
11891
|
-
"select",
|
|
11892
|
-
"set",
|
|
11893
|
-
"shadows",
|
|
11894
|
-
"shared",
|
|
11895
|
-
"short",
|
|
11896
|
-
"single",
|
|
11897
|
-
"static",
|
|
11898
|
-
"step",
|
|
11899
|
-
"stop",
|
|
11900
|
-
"string",
|
|
11901
|
-
"structure",
|
|
11902
|
-
"sub",
|
|
11903
|
-
"synclock",
|
|
11904
|
-
"then",
|
|
11905
|
-
"throw",
|
|
11906
|
-
"to",
|
|
11907
|
-
"true",
|
|
11908
|
-
"try",
|
|
11909
|
-
"trycast",
|
|
11910
|
-
"typeof",
|
|
11911
|
-
"uinteger",
|
|
11912
|
-
"ulong",
|
|
11913
|
-
"unicode",
|
|
11914
|
-
"until",
|
|
11915
|
-
"ushort",
|
|
11916
|
-
"using",
|
|
11917
|
-
"variant",
|
|
11918
|
-
"wend",
|
|
11919
|
-
"when",
|
|
11920
|
-
"while",
|
|
11921
|
-
"widening",
|
|
11922
|
-
"with",
|
|
11923
|
-
"withevents",
|
|
11924
|
-
"writeonly",
|
|
11925
|
-
"xor"
|
|
11926
|
-
];
|
|
11927
|
-
var CSHARP_RESERVED = new Set(CSHARP_RESERVED_WORDS);
|
|
11928
|
-
var VB_RESERVED = new Set(VB_RESERVED_WORDS);
|
|
11929
|
-
var GA_TYPE_PAIRS = [
|
|
11930
|
-
[FieldDisplayType.Basic, SqlTypeName.NVARCHAR],
|
|
11931
|
-
[FieldDisplayType.Basic, SqlTypeName.DECIMAL],
|
|
11932
|
-
[FieldDisplayType.Basic, SqlTypeName.FLOAT],
|
|
11933
|
-
[FieldDisplayType.Basic, SqlTypeName.BIT],
|
|
11934
|
-
[FieldDisplayType.Basic, SqlTypeName.DATE],
|
|
11935
|
-
[FieldDisplayType.Basic, SqlTypeName.DATETIMEOFFSET],
|
|
11936
|
-
[FieldDisplayType.Basic, SqlTypeName.UNIQUEIDENTIFIER],
|
|
11937
|
-
[FieldDisplayType.AutoNumber, SqlTypeName.DECIMAL],
|
|
11938
|
-
[FieldDisplayType.Basic, SqlTypeName.MULTILINE],
|
|
11939
|
-
[FieldDisplayType.Basic, SqlTypeName.MULTILINE_MAX],
|
|
11940
|
-
[FieldDisplayType.File, SqlTypeName.UNIQUEIDENTIFIER]
|
|
11941
|
-
];
|
|
11942
|
-
var ALLOWED_TYPE_PAIRS = new Set(GA_TYPE_PAIRS.map(([display, sql]) => `${display}:${sql}`));
|
|
11943
11806
|
// ../../solution-sdk/generated/src/runtime.ts
|
|
11944
11807
|
var BASE_PATH = "https://alpha.uipath.com/uipattycyrhx/abizon_1/automationsolutions_".replace(/\/+$/, "");
|
|
11945
11808
|
|
|
@@ -12164,7 +12027,7 @@ var package_default = {
|
|
|
12164
12027
|
name: "@uipath/solution-sdk",
|
|
12165
12028
|
author: "UiPath",
|
|
12166
12029
|
license: "SEE LICENSE IN LICENSE.txt",
|
|
12167
|
-
version: "1.
|
|
12030
|
+
version: "1.205.0-preview.258",
|
|
12168
12031
|
repository: {
|
|
12169
12032
|
type: "git",
|
|
12170
12033
|
url: "https://github.com/UiPath/cli.git",
|
|
@@ -12193,6 +12056,14 @@ var package_default = {
|
|
|
12193
12056
|
"./auth": {
|
|
12194
12057
|
types: "./dist/src/solution-auth.d.ts",
|
|
12195
12058
|
default: "./dist/solution-auth.js"
|
|
12059
|
+
},
|
|
12060
|
+
"./deployments": {
|
|
12061
|
+
types: "./dist/src/deployment-search.d.ts",
|
|
12062
|
+
default: "./dist/deployment-search.js"
|
|
12063
|
+
},
|
|
12064
|
+
"./packages": {
|
|
12065
|
+
types: "./dist/src/package-search.d.ts",
|
|
12066
|
+
default: "./dist/package-search.js"
|
|
12196
12067
|
}
|
|
12197
12068
|
},
|
|
12198
12069
|
bin: {
|
|
@@ -12203,7 +12074,7 @@ var package_default = {
|
|
|
12203
12074
|
],
|
|
12204
12075
|
private: false,
|
|
12205
12076
|
scripts: {
|
|
12206
|
-
build: "bun build ./src/index.ts ./src/resources/index.ts ./src/solution-auth.ts --outdir dist --format esm --target node --splitting --sourcemap=linked && bun build ./src/scripts/generate-sdk.ts --outdir dist/scripts --format esm --target node --sourcemap=linked && tsc -p tsconfig.build.json --noCheck",
|
|
12077
|
+
build: "bun build ./src/index.ts ./src/resources/index.ts ./src/solution-auth.ts ./src/deployment-search.ts ./src/package-search.ts --outdir dist --format esm --target node --splitting --sourcemap=linked && bun build ./src/scripts/generate-sdk.ts --outdir dist/scripts --format esm --target node --sourcemap=linked && tsc -p tsconfig.build.json --noCheck",
|
|
12207
12078
|
generate: "bun run src/scripts/generate-sdk.ts",
|
|
12208
12079
|
lint: "biome check .",
|
|
12209
12080
|
test: "vitest run",
|
|
@@ -12215,7 +12086,8 @@ var package_default = {
|
|
|
12215
12086
|
"@uipath/common": "workspace:*",
|
|
12216
12087
|
"@uipath/filesystem": "workspace:*",
|
|
12217
12088
|
"@uipath/orchestrator-sdk": "workspace:*",
|
|
12218
|
-
"@uipath/
|
|
12089
|
+
"@uipath/pipelines-sdk": "workspace:*",
|
|
12090
|
+
"@uipath/resource-builder-sdk": "2025.11.0-alpha6584-4367",
|
|
12219
12091
|
"@uipath/solutionpackager-tool-core": "workspace:*",
|
|
12220
12092
|
"@uipath/studioweb-sdk": "workspace:*",
|
|
12221
12093
|
"@types/node": "^25.5.2",
|
|
@@ -12800,7 +12672,7 @@ function buildRegistrationSuccessInstructions(solutionDir) {
|
|
|
12800
12672
|
return [
|
|
12801
12673
|
"The project is listed in the parent solution manifest.",
|
|
12802
12674
|
"Packing or uploading the solution will sync solution resources automatically.",
|
|
12803
|
-
`To sync resources before packaging, run
|
|
12675
|
+
`To sync resources before packaging, run: uip solution resources refresh --solution-folder ${quoteForShell(solutionDir)}`
|
|
12804
12676
|
].join(`
|
|
12805
12677
|
`);
|
|
12806
12678
|
}
|
|
@@ -12839,11 +12711,56 @@ var DEFAULT_EXCLUDED_DIR_NAMES = new Set([
|
|
|
12839
12711
|
"__pycache__",
|
|
12840
12712
|
".git",
|
|
12841
12713
|
".local",
|
|
12842
|
-
".flow-sdk"
|
|
12714
|
+
".flow-sdk",
|
|
12715
|
+
".flow-debug"
|
|
12843
12716
|
]);
|
|
12844
12717
|
// ../../solution-sdk/src/project-debug-status.ts
|
|
12845
12718
|
var SUCCEEDED = "creationsucceeded";
|
|
12846
12719
|
var TERMINAL = new Set([SUCCEEDED, "creationfailed", "validationfailed"]);
|
|
12720
|
+
// src/canonical-path.ts
|
|
12721
|
+
async function canonicalPathAsync(target, fs7) {
|
|
12722
|
+
const realpath2 = fs7.realpath?.bind(fs7);
|
|
12723
|
+
const absolute = fs7.path.resolve(target);
|
|
12724
|
+
if (realpath2 === undefined)
|
|
12725
|
+
return absolute;
|
|
12726
|
+
const tail = [];
|
|
12727
|
+
let current = absolute;
|
|
12728
|
+
while (!await fs7.exists(current)) {
|
|
12729
|
+
const parent = fs7.path.dirname(current);
|
|
12730
|
+
if (parent === current)
|
|
12731
|
+
return absolute;
|
|
12732
|
+
tail.unshift(fs7.path.basename(current));
|
|
12733
|
+
current = parent;
|
|
12734
|
+
}
|
|
12735
|
+
return fs7.path.join(await realpath2(current), ...tail);
|
|
12736
|
+
}
|
|
12737
|
+
async function resolvesInsideAsync(target, root, fs7) {
|
|
12738
|
+
const canonicalRoot = await canonicalPathAsync(root, fs7);
|
|
12739
|
+
const resolved = await canonicalPathAsync(target, fs7);
|
|
12740
|
+
const relative2 = fs7.path.relative(canonicalRoot, resolved);
|
|
12741
|
+
const inside = relative2 !== "" && relative2.split(/[\\/]/)[0] !== ".." && !fs7.path.isAbsolute(relative2);
|
|
12742
|
+
return { inside, resolved, root: canonicalRoot };
|
|
12743
|
+
}
|
|
12744
|
+
async function isSymlinkEntryAsync(target, fs7) {
|
|
12745
|
+
const isSymbolicLink = fs7.isSymbolicLink?.bind(fs7);
|
|
12746
|
+
return isSymbolicLink === undefined ? false : isSymbolicLink(fs7.path.resolve(target));
|
|
12747
|
+
}
|
|
12748
|
+
|
|
12749
|
+
// src/missing-path.ts
|
|
12750
|
+
function isMissingPathError(error) {
|
|
12751
|
+
if (!(error instanceof Error) || !("code" in error))
|
|
12752
|
+
return false;
|
|
12753
|
+
const { code } = error;
|
|
12754
|
+
return code === "ENOENT" || code === "ENOTDIR" || code === "PathNotFound";
|
|
12755
|
+
}
|
|
12756
|
+
function isFilesystemError(error) {
|
|
12757
|
+
const code = error?.code;
|
|
12758
|
+
return typeof code === "string" && /^E[A-Z]+$/.test(code);
|
|
12759
|
+
}
|
|
12760
|
+
function isUnreadablePathError(error) {
|
|
12761
|
+
return isFilesystemError(error) && !isMissingPathError(error);
|
|
12762
|
+
}
|
|
12763
|
+
|
|
12847
12764
|
// src/pack/constants.ts
|
|
12848
12765
|
var ENTITY_EXTENSION_CONST = ".entity";
|
|
12849
12766
|
|
|
@@ -12853,8 +12770,9 @@ var ENTITY_RESOURCE_TYPE = "native";
|
|
|
12853
12770
|
var ENTITY_RESOURCE_API_VERSION = "dataservice.uipath.com/v2";
|
|
12854
12771
|
var ENTITY_RESOURCE_DOC_VERSION = "1.0.0";
|
|
12855
12772
|
var SOLUTION_FOLDER = "solution_folder";
|
|
12773
|
+
var ENTITY_RESOURCE_DIR = `${ENTITY_RESOURCE_KIND}/${ENTITY_RESOURCE_TYPE}`;
|
|
12856
12774
|
function entityResourcePath(entityName) {
|
|
12857
|
-
return `resources/${SOLUTION_FOLDER}
|
|
12775
|
+
return `resources/${SOLUTION_FOLDER}/${ENTITY_RESOURCE_DIR}/${entityName}.json`;
|
|
12858
12776
|
}
|
|
12859
12777
|
|
|
12860
12778
|
// src/resource/resource-io.ts
|
|
@@ -12865,6 +12783,15 @@ function serialize(value) {
|
|
|
12865
12783
|
function serializeEntityJson(entity) {
|
|
12866
12784
|
return JSON.stringify(entity);
|
|
12867
12785
|
}
|
|
12786
|
+
|
|
12787
|
+
class EntityResourceError extends Error {
|
|
12788
|
+
failure;
|
|
12789
|
+
constructor(failure, message) {
|
|
12790
|
+
super(message);
|
|
12791
|
+
this.failure = failure;
|
|
12792
|
+
this.name = "EntityResourceError";
|
|
12793
|
+
}
|
|
12794
|
+
}
|
|
12868
12795
|
function wrapEntityJson(entity) {
|
|
12869
12796
|
return {
|
|
12870
12797
|
docVersion: ENTITY_RESOURCE_DOC_VERSION,
|
|
@@ -12889,161 +12816,1029 @@ function wrapEntityJson(entity) {
|
|
|
12889
12816
|
}
|
|
12890
12817
|
};
|
|
12891
12818
|
}
|
|
12892
|
-
|
|
12893
|
-
|
|
12894
|
-
|
|
12895
|
-
var SYSTEM_FIELD_DEFAULTS = {
|
|
12896
|
-
IsPrimaryKey: false,
|
|
12897
|
-
IsForeignKey: false,
|
|
12898
|
-
IsExternalField: false,
|
|
12899
|
-
IsHiddenField: true,
|
|
12900
|
-
FieldCategoryId: 0,
|
|
12901
|
-
IsUnique: false,
|
|
12902
|
-
ReferenceType: "ManyToOne",
|
|
12903
|
-
Transformation: null,
|
|
12904
|
-
IsRequired: false,
|
|
12905
|
-
IsEncrypted: false,
|
|
12906
|
-
Description: "",
|
|
12907
|
-
IsSystemField: true,
|
|
12908
|
-
FieldDisplayType: FieldDisplayType.Basic,
|
|
12909
|
-
IsAttachment: false,
|
|
12910
|
-
IsRbacEnabled: false,
|
|
12911
|
-
IsModelReserved: false
|
|
12912
|
-
};
|
|
12913
|
-
var SYSTEM_FIELD_TEMPLATES = [
|
|
12914
|
-
{
|
|
12915
|
-
...SYSTEM_FIELD_DEFAULTS,
|
|
12916
|
-
Name: "Id",
|
|
12917
|
-
DisplayName: "Id",
|
|
12918
|
-
IsPrimaryKey: true,
|
|
12919
|
-
SqlType: { Name: SqlTypeName.UNIQUEIDENTIFIER }
|
|
12920
|
-
},
|
|
12921
|
-
{
|
|
12922
|
-
...SYSTEM_FIELD_DEFAULTS,
|
|
12923
|
-
Name: "CreateTime",
|
|
12924
|
-
DisplayName: "CreateTime",
|
|
12925
|
-
SqlType: { Name: SqlTypeName.DATETIMEOFFSET }
|
|
12926
|
-
},
|
|
12927
|
-
{
|
|
12928
|
-
...SYSTEM_FIELD_DEFAULTS,
|
|
12929
|
-
Name: "CreatedBy",
|
|
12930
|
-
DisplayName: "CreatedBy",
|
|
12931
|
-
FieldDisplayType: FieldDisplayType.Relationship,
|
|
12932
|
-
SqlType: { Name: SqlTypeName.UNIQUEIDENTIFIER }
|
|
12933
|
-
},
|
|
12934
|
-
{
|
|
12935
|
-
...SYSTEM_FIELD_DEFAULTS,
|
|
12936
|
-
Name: "UpdateTime",
|
|
12937
|
-
DisplayName: "UpdateTime",
|
|
12938
|
-
SqlType: { Name: SqlTypeName.DATETIMEOFFSET }
|
|
12939
|
-
},
|
|
12940
|
-
{
|
|
12941
|
-
...SYSTEM_FIELD_DEFAULTS,
|
|
12942
|
-
Name: "UpdatedBy",
|
|
12943
|
-
DisplayName: "UpdatedBy",
|
|
12944
|
-
FieldDisplayType: FieldDisplayType.Relationship,
|
|
12945
|
-
SqlType: { Name: SqlTypeName.UNIQUEIDENTIFIER }
|
|
12946
|
-
}
|
|
12947
|
-
];
|
|
12948
|
-
function createEntitySkeleton(name) {
|
|
12949
|
-
return {
|
|
12950
|
-
Id: globalThis.crypto.randomUUID(),
|
|
12951
|
-
Name: name,
|
|
12952
|
-
DisplayName: name,
|
|
12953
|
-
EntityTypeId: 0,
|
|
12954
|
-
EntityType: "Entity",
|
|
12955
|
-
Description: "",
|
|
12956
|
-
FolderId: UNASSIGNED_FOLDER_ID,
|
|
12957
|
-
Fields: SYSTEM_FIELD_TEMPLATES.map((template) => ({
|
|
12958
|
-
...template,
|
|
12959
|
-
SqlType: { ...template.SqlType }
|
|
12960
|
-
})),
|
|
12961
|
-
Data: null,
|
|
12962
|
-
ExternalFields: null,
|
|
12963
|
-
SourceJoinCriterias: null,
|
|
12964
|
-
RecordCount: 0,
|
|
12965
|
-
StorageSizeInMB: null,
|
|
12966
|
-
UsedStorageSizeInMB: null,
|
|
12967
|
-
AttachmentSizeInByte: null,
|
|
12968
|
-
IsRbacEnabled: false,
|
|
12969
|
-
InvalidIdentifiers: [],
|
|
12970
|
-
IsModelReserved: false,
|
|
12971
|
-
CategoryId: null
|
|
12972
|
-
};
|
|
12973
|
-
}
|
|
12974
|
-
|
|
12975
|
-
// src/init/entity-init-service.ts
|
|
12976
|
-
var VALID_PROJECT_NAME_REGEX = /^[a-zA-Z0-9_-]+$/;
|
|
12977
|
-
async function entityInitAsync(name, options) {
|
|
12978
|
-
if (!VALID_PROJECT_NAME_REGEX.test(name)) {
|
|
12979
|
-
throw new Error(`Invalid project name "${name}". Name can only contain letters, numbers, underscores (_), and hyphens (-).`);
|
|
12819
|
+
function unwrapResource(file) {
|
|
12820
|
+
if (typeof file !== "object" || file === null || Array.isArray(file)) {
|
|
12821
|
+
throw new EntityResourceError("NotAnObject", "Resource file is not a JSON object.");
|
|
12980
12822
|
}
|
|
12981
|
-
const
|
|
12982
|
-
if (
|
|
12983
|
-
throw new
|
|
12823
|
+
const resource = file.resource;
|
|
12824
|
+
if (typeof resource !== "object" || resource === null) {
|
|
12825
|
+
throw new EntityResourceError("MissingResource", "Resource file has no 'resource' object.");
|
|
12984
12826
|
}
|
|
12985
|
-
|
|
12986
|
-
|
|
12987
|
-
const { projectDir, autoCreatedSolution } = solutionFile ? { projectDir: fs7.path.join(fs7.path.dirname(solutionFile), name) } : await prepareProjectLocation(fs7, fs7.path.resolve(requireCwd(options), name), name, {});
|
|
12988
|
-
const [statError, stat2] = await catchError(fs7.stat(projectDir));
|
|
12989
|
-
if (statError && !isMissingPathError(statError)) {
|
|
12990
|
-
throw statError;
|
|
12827
|
+
if (resource.kind !== ENTITY_RESOURCE_KIND) {
|
|
12828
|
+
throw new EntityResourceError("NotAnEntityResource", `Resource kind is '${String(resource.kind)}', expected '${ENTITY_RESOURCE_KIND}'.`);
|
|
12991
12829
|
}
|
|
12992
|
-
const
|
|
12993
|
-
if (
|
|
12994
|
-
|
|
12995
|
-
if (existingEntries.length > 0) {
|
|
12996
|
-
throw new Error(`Directory "${name}" already exists and is not empty. Use --force to overwrite.`);
|
|
12997
|
-
}
|
|
12830
|
+
const spec = resource.spec;
|
|
12831
|
+
if (typeof spec !== "object" || spec === null || typeof spec.resourceJson !== "string") {
|
|
12832
|
+
throw new EntityResourceError("MissingSpec", "Resource file has no 'spec.resourceJson' string.");
|
|
12998
12833
|
}
|
|
12999
|
-
let registered;
|
|
13000
|
-
const rollback = async () => {
|
|
13001
|
-
if (registered) {
|
|
13002
|
-
await unregisterProject(registered);
|
|
13003
|
-
}
|
|
13004
|
-
if (!projectDirExisted) {
|
|
13005
|
-
await catchError(fs7.rm(projectDir));
|
|
13006
|
-
}
|
|
13007
|
-
};
|
|
13008
12834
|
try {
|
|
13009
|
-
|
|
13010
|
-
|
|
13011
|
-
|
|
13012
|
-
const entityFile = fs7.path.join(projectDir, `${entityName}${ENTITY_EXTENSION_CONST}`);
|
|
13013
|
-
await fs7.writeFile(entityFile, serialize({ name: entityName, resourcePath: relativeResourcePath }));
|
|
13014
|
-
const registration = await tryRegisterProjectInParentSolution(fs7, projectDir, {});
|
|
13015
|
-
if (registration.Status === "Registered" && registration.Solution && registration.ProjectId) {
|
|
13016
|
-
registered = {
|
|
13017
|
-
solutionFile: registration.Solution,
|
|
13018
|
-
projectId: registration.ProjectId
|
|
13019
|
-
};
|
|
13020
|
-
}
|
|
13021
|
-
if (registration.Status !== "Registered" && registration.Status !== "AlreadyRegistered" || !registration.Solution) {
|
|
13022
|
-
if (solutionFile && registration.Status === "Skipped") {
|
|
13023
|
-
throw new Error(`Entity project "${name}" could not be registered in '${solutionFile}': ` + `${registration.Instructions ?? registration.Message ?? "registration was skipped"}. ` + "A solution folder containing more than one .uipx is not supported yet — " + "register the project with 'uip solution projects add' instead.");
|
|
13024
|
-
}
|
|
13025
|
-
throw new Error(`Entity project "${name}" requires a parent solution (registration status: ${registration.Status}). ` + "Run inside a solution directory, or create one first with 'uip solution init'.");
|
|
13026
|
-
}
|
|
13027
|
-
const solutionDir = fs7.path.dirname(registration.Solution);
|
|
13028
|
-
const resourceFile = fs7.path.join(solutionDir, ...relativeResourcePath.split("/"));
|
|
13029
|
-
await fs7.mkdir(fs7.path.dirname(resourceFile));
|
|
13030
|
-
await fs7.writeFile(resourceFile, serialize(wrapEntityJson(createEntitySkeleton(entityName))));
|
|
13031
|
-
return {
|
|
13032
|
-
projectName: name,
|
|
13033
|
-
projectDir,
|
|
13034
|
-
entityFile,
|
|
13035
|
-
resourceFile,
|
|
13036
|
-
registration,
|
|
13037
|
-
autoCreatedSolution
|
|
13038
|
-
};
|
|
13039
|
-
} catch (error) {
|
|
13040
|
-
await rollback();
|
|
13041
|
-
throw error;
|
|
12835
|
+
return JSON.parse(spec.resourceJson);
|
|
12836
|
+
} catch {
|
|
12837
|
+
throw new EntityResourceError("ResourceJsonUnparsable", "'spec.resourceJson' is not valid JSON.");
|
|
13042
12838
|
}
|
|
13043
12839
|
}
|
|
13044
|
-
function
|
|
13045
|
-
|
|
13046
|
-
|
|
12840
|
+
function updateResourceSchema(file, entity) {
|
|
12841
|
+
return {
|
|
12842
|
+
...file,
|
|
12843
|
+
resource: {
|
|
12844
|
+
...file.resource,
|
|
12845
|
+
name: entity.Name,
|
|
12846
|
+
spec: {
|
|
12847
|
+
...file.resource.spec,
|
|
12848
|
+
resourceJson: serializeEntityJson(entity),
|
|
12849
|
+
name: entity.Name,
|
|
12850
|
+
displayName: entity.DisplayName,
|
|
12851
|
+
description: entity.Description
|
|
12852
|
+
}
|
|
12853
|
+
}
|
|
12854
|
+
};
|
|
12855
|
+
}
|
|
12856
|
+
|
|
12857
|
+
// ../../../node_modules/@uipath/entity-modeler/dist/chunk-7VKIHCI7.js
|
|
12858
|
+
var SqlTypeName = {
|
|
12859
|
+
UNIQUEIDENTIFIER: "UNIQUEIDENTIFIER",
|
|
12860
|
+
NVARCHAR: "NVARCHAR",
|
|
12861
|
+
INT: "INT",
|
|
12862
|
+
DATETIME2: "DATETIME2",
|
|
12863
|
+
DATETIMEOFFSET: "DATETIMEOFFSET",
|
|
12864
|
+
FLOAT: "FLOAT",
|
|
12865
|
+
REAL: "REAL",
|
|
12866
|
+
BIGINT: "BIGINT",
|
|
12867
|
+
DATE: "DATE",
|
|
12868
|
+
BIT: "BIT",
|
|
12869
|
+
DECIMAL: "DECIMAL",
|
|
12870
|
+
MULTILINE: "MULTILINE",
|
|
12871
|
+
MULTILINE_MAX: "MULTILINE_MAX",
|
|
12872
|
+
UNKNOWN: "UNKNOWN"
|
|
12873
|
+
};
|
|
12874
|
+
var FieldDisplayType = {
|
|
12875
|
+
Basic: "Basic",
|
|
12876
|
+
Relationship: "Relationship",
|
|
12877
|
+
File: "File",
|
|
12878
|
+
ChoiceSetSingle: "ChoiceSetSingle",
|
|
12879
|
+
ChoiceSetMultiple: "ChoiceSetMultiple",
|
|
12880
|
+
AutoNumber: "AutoNumber",
|
|
12881
|
+
MultiLineText: "MultiLineText"
|
|
12882
|
+
};
|
|
12883
|
+
var DEFAULT_REFERENCE_TYPE = "ManyToOne";
|
|
12884
|
+
var CSHARP_RESERVED_WORDS = [
|
|
12885
|
+
"__arglist",
|
|
12886
|
+
"__makeref",
|
|
12887
|
+
"__reftype",
|
|
12888
|
+
"__refvalue",
|
|
12889
|
+
"abstract",
|
|
12890
|
+
"as",
|
|
12891
|
+
"base",
|
|
12892
|
+
"bool",
|
|
12893
|
+
"break",
|
|
12894
|
+
"byte",
|
|
12895
|
+
"case",
|
|
12896
|
+
"catch",
|
|
12897
|
+
"char",
|
|
12898
|
+
"checked",
|
|
12899
|
+
"class",
|
|
12900
|
+
"const",
|
|
12901
|
+
"continue",
|
|
12902
|
+
"decimal",
|
|
12903
|
+
"default",
|
|
12904
|
+
"delegate",
|
|
12905
|
+
"do",
|
|
12906
|
+
"double",
|
|
12907
|
+
"else",
|
|
12908
|
+
"enum",
|
|
12909
|
+
"event",
|
|
12910
|
+
"explicit",
|
|
12911
|
+
"extern",
|
|
12912
|
+
"false",
|
|
12913
|
+
"finally",
|
|
12914
|
+
"fixed",
|
|
12915
|
+
"float",
|
|
12916
|
+
"for",
|
|
12917
|
+
"foreach",
|
|
12918
|
+
"goto",
|
|
12919
|
+
"if",
|
|
12920
|
+
"implicit",
|
|
12921
|
+
"in",
|
|
12922
|
+
"int",
|
|
12923
|
+
"interface",
|
|
12924
|
+
"internal",
|
|
12925
|
+
"is",
|
|
12926
|
+
"lock",
|
|
12927
|
+
"long",
|
|
12928
|
+
"namespace",
|
|
12929
|
+
"new",
|
|
12930
|
+
"null",
|
|
12931
|
+
"object",
|
|
12932
|
+
"operator",
|
|
12933
|
+
"out",
|
|
12934
|
+
"override",
|
|
12935
|
+
"params",
|
|
12936
|
+
"partial",
|
|
12937
|
+
"private",
|
|
12938
|
+
"protected",
|
|
12939
|
+
"public",
|
|
12940
|
+
"readonly",
|
|
12941
|
+
"ref",
|
|
12942
|
+
"return",
|
|
12943
|
+
"sbyte",
|
|
12944
|
+
"sealed",
|
|
12945
|
+
"short",
|
|
12946
|
+
"sizeof",
|
|
12947
|
+
"stackalloc",
|
|
12948
|
+
"static",
|
|
12949
|
+
"string",
|
|
12950
|
+
"struct",
|
|
12951
|
+
"switch",
|
|
12952
|
+
"this",
|
|
12953
|
+
"throw",
|
|
12954
|
+
"true",
|
|
12955
|
+
"try",
|
|
12956
|
+
"typeof",
|
|
12957
|
+
"uint",
|
|
12958
|
+
"ulong",
|
|
12959
|
+
"unchecked",
|
|
12960
|
+
"unsafe",
|
|
12961
|
+
"ushort",
|
|
12962
|
+
"using",
|
|
12963
|
+
"virtual",
|
|
12964
|
+
"void",
|
|
12965
|
+
"volatile",
|
|
12966
|
+
"where",
|
|
12967
|
+
"while",
|
|
12968
|
+
"yield"
|
|
12969
|
+
];
|
|
12970
|
+
var VB_RESERVED_WORDS = [
|
|
12971
|
+
"addhandler",
|
|
12972
|
+
"addressof",
|
|
12973
|
+
"alias",
|
|
12974
|
+
"and",
|
|
12975
|
+
"andalso",
|
|
12976
|
+
"ansi",
|
|
12977
|
+
"as",
|
|
12978
|
+
"assembly",
|
|
12979
|
+
"auto",
|
|
12980
|
+
"boolean",
|
|
12981
|
+
"byref",
|
|
12982
|
+
"byte",
|
|
12983
|
+
"byval",
|
|
12984
|
+
"call",
|
|
12985
|
+
"case",
|
|
12986
|
+
"catch",
|
|
12987
|
+
"cbool",
|
|
12988
|
+
"cbyte",
|
|
12989
|
+
"cchar",
|
|
12990
|
+
"cdate",
|
|
12991
|
+
"cdbl",
|
|
12992
|
+
"cdec",
|
|
12993
|
+
"char",
|
|
12994
|
+
"cint",
|
|
12995
|
+
"class",
|
|
12996
|
+
"class_finalize",
|
|
12997
|
+
"class_initialize",
|
|
12998
|
+
"clng",
|
|
12999
|
+
"cobj",
|
|
13000
|
+
"const",
|
|
13001
|
+
"continue",
|
|
13002
|
+
"csbyte",
|
|
13003
|
+
"cshort",
|
|
13004
|
+
"csng",
|
|
13005
|
+
"cstr",
|
|
13006
|
+
"ctype",
|
|
13007
|
+
"cuint",
|
|
13008
|
+
"culng",
|
|
13009
|
+
"cushort",
|
|
13010
|
+
"date",
|
|
13011
|
+
"decimal",
|
|
13012
|
+
"declare",
|
|
13013
|
+
"default",
|
|
13014
|
+
"delegate",
|
|
13015
|
+
"dim",
|
|
13016
|
+
"directcast",
|
|
13017
|
+
"do",
|
|
13018
|
+
"double",
|
|
13019
|
+
"each",
|
|
13020
|
+
"else",
|
|
13021
|
+
"elseif",
|
|
13022
|
+
"end",
|
|
13023
|
+
"endif",
|
|
13024
|
+
"enum",
|
|
13025
|
+
"erase",
|
|
13026
|
+
"error",
|
|
13027
|
+
"event",
|
|
13028
|
+
"exit",
|
|
13029
|
+
"false",
|
|
13030
|
+
"finally",
|
|
13031
|
+
"for",
|
|
13032
|
+
"friend",
|
|
13033
|
+
"function",
|
|
13034
|
+
"get",
|
|
13035
|
+
"gettype",
|
|
13036
|
+
"global",
|
|
13037
|
+
"gosub",
|
|
13038
|
+
"goto",
|
|
13039
|
+
"handles",
|
|
13040
|
+
"if",
|
|
13041
|
+
"implements",
|
|
13042
|
+
"imports",
|
|
13043
|
+
"in",
|
|
13044
|
+
"inherits",
|
|
13045
|
+
"integer",
|
|
13046
|
+
"interface",
|
|
13047
|
+
"is",
|
|
13048
|
+
"isnot",
|
|
13049
|
+
"let",
|
|
13050
|
+
"lib",
|
|
13051
|
+
"like",
|
|
13052
|
+
"long",
|
|
13053
|
+
"loop",
|
|
13054
|
+
"me",
|
|
13055
|
+
"mod",
|
|
13056
|
+
"module",
|
|
13057
|
+
"mustinherit",
|
|
13058
|
+
"mustoverride",
|
|
13059
|
+
"mybase",
|
|
13060
|
+
"myclass",
|
|
13061
|
+
"namespace",
|
|
13062
|
+
"narrowing",
|
|
13063
|
+
"new",
|
|
13064
|
+
"next",
|
|
13065
|
+
"not",
|
|
13066
|
+
"nothing",
|
|
13067
|
+
"notinheritable",
|
|
13068
|
+
"notoverridable",
|
|
13069
|
+
"object",
|
|
13070
|
+
"of",
|
|
13071
|
+
"on",
|
|
13072
|
+
"operator",
|
|
13073
|
+
"option",
|
|
13074
|
+
"optional",
|
|
13075
|
+
"or",
|
|
13076
|
+
"orelse",
|
|
13077
|
+
"overloads",
|
|
13078
|
+
"overridable",
|
|
13079
|
+
"overrides",
|
|
13080
|
+
"paramarray",
|
|
13081
|
+
"partial",
|
|
13082
|
+
"preserve",
|
|
13083
|
+
"private",
|
|
13084
|
+
"property",
|
|
13085
|
+
"protected",
|
|
13086
|
+
"public",
|
|
13087
|
+
"raiseevent",
|
|
13088
|
+
"readonly",
|
|
13089
|
+
"redim",
|
|
13090
|
+
"rem",
|
|
13091
|
+
"removehandler",
|
|
13092
|
+
"resume",
|
|
13093
|
+
"return",
|
|
13094
|
+
"sbyte",
|
|
13095
|
+
"select",
|
|
13096
|
+
"set",
|
|
13097
|
+
"shadows",
|
|
13098
|
+
"shared",
|
|
13099
|
+
"short",
|
|
13100
|
+
"single",
|
|
13101
|
+
"static",
|
|
13102
|
+
"step",
|
|
13103
|
+
"stop",
|
|
13104
|
+
"string",
|
|
13105
|
+
"structure",
|
|
13106
|
+
"sub",
|
|
13107
|
+
"synclock",
|
|
13108
|
+
"then",
|
|
13109
|
+
"throw",
|
|
13110
|
+
"to",
|
|
13111
|
+
"true",
|
|
13112
|
+
"try",
|
|
13113
|
+
"trycast",
|
|
13114
|
+
"typeof",
|
|
13115
|
+
"uinteger",
|
|
13116
|
+
"ulong",
|
|
13117
|
+
"unicode",
|
|
13118
|
+
"until",
|
|
13119
|
+
"ushort",
|
|
13120
|
+
"using",
|
|
13121
|
+
"variant",
|
|
13122
|
+
"wend",
|
|
13123
|
+
"when",
|
|
13124
|
+
"while",
|
|
13125
|
+
"widening",
|
|
13126
|
+
"with",
|
|
13127
|
+
"withevents",
|
|
13128
|
+
"writeonly",
|
|
13129
|
+
"xor"
|
|
13130
|
+
];
|
|
13131
|
+
var CSHARP_RESERVED = new Set(CSHARP_RESERVED_WORDS);
|
|
13132
|
+
var VB_RESERVED = new Set(VB_RESERVED_WORDS);
|
|
13133
|
+
var GA_TYPE_PAIRS = [
|
|
13134
|
+
[FieldDisplayType.Basic, SqlTypeName.NVARCHAR],
|
|
13135
|
+
[FieldDisplayType.Basic, SqlTypeName.DECIMAL],
|
|
13136
|
+
[FieldDisplayType.Basic, SqlTypeName.FLOAT],
|
|
13137
|
+
[FieldDisplayType.Basic, SqlTypeName.BIT],
|
|
13138
|
+
[FieldDisplayType.Basic, SqlTypeName.DATE],
|
|
13139
|
+
[FieldDisplayType.Basic, SqlTypeName.DATETIMEOFFSET],
|
|
13140
|
+
[FieldDisplayType.Basic, SqlTypeName.UNIQUEIDENTIFIER],
|
|
13141
|
+
[FieldDisplayType.AutoNumber, SqlTypeName.DECIMAL],
|
|
13142
|
+
[FieldDisplayType.Basic, SqlTypeName.MULTILINE],
|
|
13143
|
+
[FieldDisplayType.Basic, SqlTypeName.MULTILINE_MAX],
|
|
13144
|
+
[FieldDisplayType.File, SqlTypeName.UNIQUEIDENTIFIER]
|
|
13145
|
+
];
|
|
13146
|
+
var ALLOWED_TYPE_PAIRS = new Set(GA_TYPE_PAIRS.map(([display, sql]) => `${display}:${sql}`));
|
|
13147
|
+
// src/sort-names.ts
|
|
13148
|
+
function byName(a, b) {
|
|
13149
|
+
return a.localeCompare(b, "en");
|
|
13150
|
+
}
|
|
13151
|
+
|
|
13152
|
+
// src/schema/author-field.ts
|
|
13153
|
+
var TYPE_MAP = {
|
|
13154
|
+
STRING: [FieldDisplayType.Basic, SqlTypeName.NVARCHAR],
|
|
13155
|
+
DECIMAL: [FieldDisplayType.Basic, SqlTypeName.DECIMAL],
|
|
13156
|
+
BOOLEAN: [FieldDisplayType.Basic, SqlTypeName.BIT],
|
|
13157
|
+
DATE: [FieldDisplayType.Basic, SqlTypeName.DATE],
|
|
13158
|
+
DATETIME_WITH_TZ: [FieldDisplayType.Basic, SqlTypeName.DATETIMEOFFSET],
|
|
13159
|
+
MULTILINE_TEXT: [FieldDisplayType.Basic, SqlTypeName.MULTILINE],
|
|
13160
|
+
MULTILINE_MAX: [FieldDisplayType.Basic, SqlTypeName.MULTILINE_MAX],
|
|
13161
|
+
AUTO_NUMBER: [FieldDisplayType.AutoNumber, SqlTypeName.DECIMAL],
|
|
13162
|
+
FILE: [FieldDisplayType.File, SqlTypeName.UNIQUEIDENTIFIER]
|
|
13163
|
+
};
|
|
13164
|
+
var AUTHORABLE_FIELD_TYPES = Object.freeze(Object.keys(TYPE_MAP).sort(byName));
|
|
13165
|
+
var UNAUTHORABLE_TYPES = {
|
|
13166
|
+
CHOICE_SET_SINGLE: "choice-set fields are not authorable locally — add the field in Data Fabric",
|
|
13167
|
+
CHOICE_SET_MULTIPLE: "choice-set fields are not authorable locally — add the field in Data Fabric",
|
|
13168
|
+
RELATIONSHIP: "relationship fields are not authorable locally — add the field in Data Fabric",
|
|
13169
|
+
INTEGER: "use DECIMAL with decimalPrecision: 0",
|
|
13170
|
+
BIG_INTEGER: "use DECIMAL with decimalPrecision: 0",
|
|
13171
|
+
FLOAT: "use DECIMAL with a decimalPrecision",
|
|
13172
|
+
DOUBLE: "use DECIMAL with a decimalPrecision",
|
|
13173
|
+
UUID: "use STRING",
|
|
13174
|
+
DATETIME: "use DATETIME_WITH_TZ"
|
|
13175
|
+
};
|
|
13176
|
+
|
|
13177
|
+
class AuthoredFieldError extends Error {
|
|
13178
|
+
instructions;
|
|
13179
|
+
constructor(message, instructions) {
|
|
13180
|
+
super(message);
|
|
13181
|
+
this.instructions = instructions;
|
|
13182
|
+
this.name = "AuthoredFieldError";
|
|
13183
|
+
}
|
|
13184
|
+
}
|
|
13185
|
+
function buildSqlType(name, spec) {
|
|
13186
|
+
const sqlType = { Name: name };
|
|
13187
|
+
if (spec.lengthLimit != null)
|
|
13188
|
+
sqlType.LengthLimit = spec.lengthLimit;
|
|
13189
|
+
if (spec.decimalPrecision != null)
|
|
13190
|
+
sqlType.DecimalPrecision = spec.decimalPrecision;
|
|
13191
|
+
if (spec.maxValue != null)
|
|
13192
|
+
sqlType.MaxValue = spec.maxValue;
|
|
13193
|
+
if (spec.minValue != null)
|
|
13194
|
+
sqlType.MinValue = spec.minValue;
|
|
13195
|
+
return sqlType;
|
|
13196
|
+
}
|
|
13197
|
+
var DEFAULT_VALUE_SHAPES = {
|
|
13198
|
+
BOOLEAN: '"true" or "false"',
|
|
13199
|
+
DECIMAL: 'a number in quotes, e.g. "0"',
|
|
13200
|
+
AUTO_NUMBER: 'a number in quotes, e.g. "0"'
|
|
13201
|
+
};
|
|
13202
|
+
function assertDefaultValue(spec, checkContent) {
|
|
13203
|
+
const value = spec.defaultValue;
|
|
13204
|
+
if (value === undefined || value === null) {
|
|
13205
|
+
return;
|
|
13206
|
+
}
|
|
13207
|
+
if (!checkContent) {
|
|
13208
|
+
return;
|
|
13209
|
+
}
|
|
13210
|
+
if (typeof value !== "string") {
|
|
13211
|
+
const shape = DEFAULT_VALUE_SHAPES[spec.type] ?? "a string";
|
|
13212
|
+
throw new AuthoredFieldError(`Field '${spec.name}': 'defaultValue' must be a string or null`, `Received ${JSON.stringify(value)}. Entity documents store every default as text, whatever the field type — for ${spec.type} pass ${shape}, or null to clear it.`);
|
|
13213
|
+
}
|
|
13214
|
+
if (spec.type === "BOOLEAN" && value.toLowerCase() !== "true" && value.toLowerCase() !== "false") {
|
|
13215
|
+
throw new AuthoredFieldError(`Field '${spec.name}': 'defaultValue' ${JSON.stringify(value)} is not a boolean`, 'A BOOLEAN default is the text "true" or "false".');
|
|
13216
|
+
}
|
|
13217
|
+
if ((spec.type === "DECIMAL" || spec.type === "AUTO_NUMBER") && (value.trim() === "" || !Number.isFinite(Number(value)))) {
|
|
13218
|
+
throw new AuthoredFieldError(`Field '${spec.name}': 'defaultValue' ${JSON.stringify(value)} is not a number`, `A ${spec.type} default is a number written as text, e.g. "0".`);
|
|
13219
|
+
}
|
|
13220
|
+
}
|
|
13221
|
+
function authorField(spec, options = {}) {
|
|
13222
|
+
const pair = TYPE_MAP[spec.type];
|
|
13223
|
+
if (pair === undefined) {
|
|
13224
|
+
const redirect = UNAUTHORABLE_TYPES[spec.type];
|
|
13225
|
+
throw new AuthoredFieldError(`Field '${spec.name}' has unsupported type '${spec.type}'`, redirect === undefined ? `Supported types: ${AUTHORABLE_FIELD_TYPES.join(", ")}.` : `${redirect}. Supported types: ${AUTHORABLE_FIELD_TYPES.join(", ")}.`);
|
|
13226
|
+
}
|
|
13227
|
+
const [fieldDisplayType, sqlTypeName] = pair;
|
|
13228
|
+
const pairKey = `${fieldDisplayType}:${sqlTypeName}`;
|
|
13229
|
+
if (!ALLOWED_TYPE_PAIRS.has(pairKey)) {
|
|
13230
|
+
throw new AuthoredFieldError(`Internal: type '${spec.type}' maps to ${pairKey}, which is not an allowed pair`, "This is a defect in author-field.ts — the type map has drifted from GA_TYPE_PAIRS.");
|
|
13231
|
+
}
|
|
13232
|
+
for (const [key, value] of [
|
|
13233
|
+
["isRequired", spec.isRequired],
|
|
13234
|
+
["isUnique", spec.isUnique]
|
|
13235
|
+
]) {
|
|
13236
|
+
if (value !== undefined && typeof value !== "boolean") {
|
|
13237
|
+
throw new AuthoredFieldError(`Field '${spec.name}': '${key}' must be true or false`, `Received ${JSON.stringify(value)}. Use a JSON boolean, not a string.`);
|
|
13238
|
+
}
|
|
13239
|
+
}
|
|
13240
|
+
for (const [key, value] of [
|
|
13241
|
+
["displayName", spec.displayName],
|
|
13242
|
+
["description", spec.description]
|
|
13243
|
+
]) {
|
|
13244
|
+
if (value !== undefined && typeof value !== "string") {
|
|
13245
|
+
throw new AuthoredFieldError(`Field '${spec.name}': '${key}' must be a string`, `Received ${JSON.stringify(value)}.`);
|
|
13246
|
+
}
|
|
13247
|
+
}
|
|
13248
|
+
assertDefaultValue(spec, options.defaultValueFromCaller !== false);
|
|
13249
|
+
const constraintError = findInvalidFieldConstraints([
|
|
13250
|
+
{
|
|
13251
|
+
name: spec.name,
|
|
13252
|
+
type: spec.type,
|
|
13253
|
+
...spec.lengthLimit != null && {
|
|
13254
|
+
lengthLimit: spec.lengthLimit
|
|
13255
|
+
},
|
|
13256
|
+
...spec.decimalPrecision != null && {
|
|
13257
|
+
decimalPrecision: spec.decimalPrecision
|
|
13258
|
+
},
|
|
13259
|
+
...spec.maxValue != null && { maxValue: spec.maxValue },
|
|
13260
|
+
...spec.minValue != null && { minValue: spec.minValue }
|
|
13261
|
+
}
|
|
13262
|
+
]);
|
|
13263
|
+
if (constraintError) {
|
|
13264
|
+
throw new AuthoredFieldError(constraintError.message, constraintError.instructions);
|
|
13265
|
+
}
|
|
13266
|
+
return {
|
|
13267
|
+
Name: spec.name,
|
|
13268
|
+
DisplayName: spec.displayName ?? spec.name,
|
|
13269
|
+
SqlType: buildSqlType(sqlTypeName, spec),
|
|
13270
|
+
IsRequired: spec.isRequired ?? false,
|
|
13271
|
+
IsUnique: spec.isUnique ?? false,
|
|
13272
|
+
IsPrimaryKey: false,
|
|
13273
|
+
IsForeignKey: false,
|
|
13274
|
+
IsExternalField: false,
|
|
13275
|
+
IsHiddenField: false,
|
|
13276
|
+
FieldCategoryId: 0,
|
|
13277
|
+
ReferenceType: DEFAULT_REFERENCE_TYPE,
|
|
13278
|
+
Transformation: null,
|
|
13279
|
+
IsEncrypted: false,
|
|
13280
|
+
Description: spec.description ?? "",
|
|
13281
|
+
IsSystemField: false,
|
|
13282
|
+
FieldDisplayType: fieldDisplayType,
|
|
13283
|
+
DefaultValue: spec.defaultValue ?? null,
|
|
13284
|
+
IsAttachment: false,
|
|
13285
|
+
IsRbacEnabled: false,
|
|
13286
|
+
IsModelReserved: false,
|
|
13287
|
+
ReferenceChoiceSet: null,
|
|
13288
|
+
ReferenceEntity: null,
|
|
13289
|
+
ReferenceField: null,
|
|
13290
|
+
ReferenceName: null
|
|
13291
|
+
};
|
|
13292
|
+
}
|
|
13293
|
+
|
|
13294
|
+
// src/schema/create-entity-skeleton.ts
|
|
13295
|
+
var UNASSIGNED_FOLDER_ID = "99999999-9999-9999-9999-999999999999";
|
|
13296
|
+
function isLocallyAuthored(entity) {
|
|
13297
|
+
return entity.FolderId === UNASSIGNED_FOLDER_ID;
|
|
13298
|
+
}
|
|
13299
|
+
var SYSTEM_FIELD_DEFAULTS = {
|
|
13300
|
+
IsPrimaryKey: false,
|
|
13301
|
+
IsForeignKey: false,
|
|
13302
|
+
IsExternalField: false,
|
|
13303
|
+
IsHiddenField: true,
|
|
13304
|
+
FieldCategoryId: 0,
|
|
13305
|
+
IsUnique: false,
|
|
13306
|
+
ReferenceType: "ManyToOne",
|
|
13307
|
+
Transformation: null,
|
|
13308
|
+
IsRequired: false,
|
|
13309
|
+
IsEncrypted: false,
|
|
13310
|
+
Description: "",
|
|
13311
|
+
IsSystemField: true,
|
|
13312
|
+
FieldDisplayType: FieldDisplayType.Basic,
|
|
13313
|
+
IsAttachment: false,
|
|
13314
|
+
IsRbacEnabled: false,
|
|
13315
|
+
IsModelReserved: false
|
|
13316
|
+
};
|
|
13317
|
+
var SYSTEM_FIELD_TEMPLATES = [
|
|
13318
|
+
{
|
|
13319
|
+
...SYSTEM_FIELD_DEFAULTS,
|
|
13320
|
+
Name: "Id",
|
|
13321
|
+
DisplayName: "Id",
|
|
13322
|
+
IsPrimaryKey: true,
|
|
13323
|
+
SqlType: { Name: SqlTypeName.UNIQUEIDENTIFIER }
|
|
13324
|
+
},
|
|
13325
|
+
{
|
|
13326
|
+
...SYSTEM_FIELD_DEFAULTS,
|
|
13327
|
+
Name: "CreateTime",
|
|
13328
|
+
DisplayName: "CreateTime",
|
|
13329
|
+
SqlType: { Name: SqlTypeName.DATETIMEOFFSET }
|
|
13330
|
+
},
|
|
13331
|
+
{
|
|
13332
|
+
...SYSTEM_FIELD_DEFAULTS,
|
|
13333
|
+
Name: "CreatedBy",
|
|
13334
|
+
DisplayName: "CreatedBy",
|
|
13335
|
+
FieldDisplayType: FieldDisplayType.Relationship,
|
|
13336
|
+
SqlType: { Name: SqlTypeName.UNIQUEIDENTIFIER }
|
|
13337
|
+
},
|
|
13338
|
+
{
|
|
13339
|
+
...SYSTEM_FIELD_DEFAULTS,
|
|
13340
|
+
Name: "UpdateTime",
|
|
13341
|
+
DisplayName: "UpdateTime",
|
|
13342
|
+
SqlType: { Name: SqlTypeName.DATETIMEOFFSET }
|
|
13343
|
+
},
|
|
13344
|
+
{
|
|
13345
|
+
...SYSTEM_FIELD_DEFAULTS,
|
|
13346
|
+
Name: "UpdatedBy",
|
|
13347
|
+
DisplayName: "UpdatedBy",
|
|
13348
|
+
FieldDisplayType: FieldDisplayType.Relationship,
|
|
13349
|
+
SqlType: { Name: SqlTypeName.UNIQUEIDENTIFIER }
|
|
13350
|
+
}
|
|
13351
|
+
];
|
|
13352
|
+
function createEntitySkeleton(name) {
|
|
13353
|
+
return {
|
|
13354
|
+
Id: globalThis.crypto.randomUUID(),
|
|
13355
|
+
Name: name,
|
|
13356
|
+
DisplayName: name,
|
|
13357
|
+
EntityTypeId: 0,
|
|
13358
|
+
EntityType: "Entity",
|
|
13359
|
+
Description: "",
|
|
13360
|
+
FolderId: UNASSIGNED_FOLDER_ID,
|
|
13361
|
+
Fields: SYSTEM_FIELD_TEMPLATES.map((template) => ({
|
|
13362
|
+
...template,
|
|
13363
|
+
SqlType: { ...template.SqlType }
|
|
13364
|
+
})),
|
|
13365
|
+
Data: null,
|
|
13366
|
+
ExternalFields: null,
|
|
13367
|
+
SourceJoinCriterias: null,
|
|
13368
|
+
RecordCount: 0,
|
|
13369
|
+
StorageSizeInMB: null,
|
|
13370
|
+
UsedStorageSizeInMB: null,
|
|
13371
|
+
AttachmentSizeInByte: null,
|
|
13372
|
+
IsRbacEnabled: false,
|
|
13373
|
+
InvalidIdentifiers: [],
|
|
13374
|
+
IsModelReserved: false,
|
|
13375
|
+
CategoryId: null
|
|
13376
|
+
};
|
|
13377
|
+
}
|
|
13378
|
+
function requireAuthoredName(authored, entityName) {
|
|
13379
|
+
if (authored !== undefined && authored.Name !== entityName) {
|
|
13380
|
+
throw new AuthoredFieldError(`Authored entity '${authored.Name}' cannot be written as '${entityName}'`, "Author the document with the name it is created under.");
|
|
13381
|
+
}
|
|
13382
|
+
}
|
|
13383
|
+
|
|
13384
|
+
// src/schema/solution-entity-names.ts
|
|
13385
|
+
function withoutOneOccurrence(names, name) {
|
|
13386
|
+
const siblings = [...names];
|
|
13387
|
+
const self = siblings.indexOf(name);
|
|
13388
|
+
if (self >= 0) {
|
|
13389
|
+
siblings.splice(self, 1);
|
|
13390
|
+
}
|
|
13391
|
+
return siblings;
|
|
13392
|
+
}
|
|
13393
|
+
function isMissingPath(error) {
|
|
13394
|
+
return error instanceof Error && "code" in error && (error.code === "ENOENT" || error.code === "PathNotFound");
|
|
13395
|
+
}
|
|
13396
|
+
async function collectSolutionEntityNames(solutionDir, fs7) {
|
|
13397
|
+
const names = [];
|
|
13398
|
+
let topLevel = [];
|
|
13399
|
+
try {
|
|
13400
|
+
topLevel = await fs7.readdir(solutionDir);
|
|
13401
|
+
} catch (error) {
|
|
13402
|
+
if (!isMissingPath(error)) {
|
|
13403
|
+
throw error;
|
|
13404
|
+
}
|
|
13405
|
+
return names;
|
|
13406
|
+
}
|
|
13407
|
+
for (const entry of topLevel) {
|
|
13408
|
+
if (entry === "resources" || entry.startsWith(".")) {
|
|
13409
|
+
continue;
|
|
13410
|
+
}
|
|
13411
|
+
const dir = fs7.path.join(solutionDir, entry);
|
|
13412
|
+
try {
|
|
13413
|
+
const stat2 = await fs7.stat(dir);
|
|
13414
|
+
if (!stat2?.isDirectory()) {
|
|
13415
|
+
continue;
|
|
13416
|
+
}
|
|
13417
|
+
for (const file of await fs7.readdir(dir)) {
|
|
13418
|
+
if (file.endsWith(ENTITY_EXTENSION_CONST)) {
|
|
13419
|
+
names.push(fs7.path.basename(file, ENTITY_EXTENSION_CONST));
|
|
13420
|
+
}
|
|
13421
|
+
}
|
|
13422
|
+
} catch (error) {
|
|
13423
|
+
if (!isMissingPath(error)) {
|
|
13424
|
+
throw error;
|
|
13425
|
+
}
|
|
13426
|
+
}
|
|
13427
|
+
}
|
|
13428
|
+
return names;
|
|
13429
|
+
}
|
|
13430
|
+
async function siblingNamesFor(solutionDir, entityName, fs7) {
|
|
13431
|
+
return withoutOneOccurrence(await collectSolutionEntityNames(solutionDir, fs7), entityName);
|
|
13432
|
+
}
|
|
13433
|
+
async function findProjectsOwningEntity(solutionDir, entityName, fs7) {
|
|
13434
|
+
const owners = [];
|
|
13435
|
+
const wanted = `${entityName}${ENTITY_EXTENSION_CONST}`.toLowerCase();
|
|
13436
|
+
let topLevel = [];
|
|
13437
|
+
try {
|
|
13438
|
+
topLevel = await fs7.readdir(solutionDir);
|
|
13439
|
+
} catch (error) {
|
|
13440
|
+
if (isMissingPathError(error))
|
|
13441
|
+
return owners;
|
|
13442
|
+
throw error;
|
|
13443
|
+
}
|
|
13444
|
+
for (const entry of topLevel) {
|
|
13445
|
+
if (entry === "resources" || entry.startsWith(".")) {
|
|
13446
|
+
continue;
|
|
13447
|
+
}
|
|
13448
|
+
const dir = fs7.path.join(solutionDir, entry);
|
|
13449
|
+
try {
|
|
13450
|
+
const stat2 = await fs7.stat(dir);
|
|
13451
|
+
if (!stat2?.isDirectory()) {
|
|
13452
|
+
continue;
|
|
13453
|
+
}
|
|
13454
|
+
for (const file of await fs7.readdir(dir)) {
|
|
13455
|
+
if (file.toLowerCase() === wanted) {
|
|
13456
|
+
owners.push({
|
|
13457
|
+
projectName: entry,
|
|
13458
|
+
entityName: fs7.path.basename(file, ENTITY_EXTENSION_CONST)
|
|
13459
|
+
});
|
|
13460
|
+
break;
|
|
13461
|
+
}
|
|
13462
|
+
}
|
|
13463
|
+
} catch (error) {
|
|
13464
|
+
if (!isMissingPathError(error))
|
|
13465
|
+
throw error;
|
|
13466
|
+
}
|
|
13467
|
+
}
|
|
13468
|
+
return owners;
|
|
13469
|
+
}
|
|
13470
|
+
|
|
13471
|
+
// src/schema/validate-entity.ts
|
|
13472
|
+
var DIAGNOSTIC_CODES = {
|
|
13473
|
+
entityNameInvalid: "ENTITY_NAME_INVALID",
|
|
13474
|
+
entityNameNotUnique: "ENTITY_NAME_NOT_UNIQUE",
|
|
13475
|
+
fieldNameInvalid: "FIELD_NAME_INVALID",
|
|
13476
|
+
duplicateFieldName: "DUPLICATE_FIELD_NAME",
|
|
13477
|
+
fieldTypeNotAllowed: "FIELD_TYPE_NOT_ALLOWED",
|
|
13478
|
+
nameReserved: "NAME_RESERVED",
|
|
13479
|
+
systemFieldMissing: "SYSTEM_FIELD_MISSING",
|
|
13480
|
+
systemFieldModified: "SYSTEM_FIELD_MODIFIED",
|
|
13481
|
+
fieldsMalformed: "FIELDS_MALFORMED",
|
|
13482
|
+
tooManyMultilineMax: "TOO_MANY_MULTILINE_MAX",
|
|
13483
|
+
propertyTypeInvalid: "PROPERTY_TYPE_INVALID"
|
|
13484
|
+
};
|
|
13485
|
+
function validateEntity(entity, ctx) {
|
|
13486
|
+
const diagnostics = [];
|
|
13487
|
+
if (typeof entity?.Name !== "string") {
|
|
13488
|
+
return [
|
|
13489
|
+
{
|
|
13490
|
+
code: DIAGNOSTIC_CODES.entityNameInvalid,
|
|
13491
|
+
message: "The entity document has no 'Name'. The resource is malformed.",
|
|
13492
|
+
severity: "error"
|
|
13493
|
+
}
|
|
13494
|
+
];
|
|
13495
|
+
}
|
|
13496
|
+
const entityNameFormat = validateNameFormat(entity.Name, "entity");
|
|
13497
|
+
if (entityNameFormat) {
|
|
13498
|
+
diagnostics.push({
|
|
13499
|
+
code: DIAGNOSTIC_CODES.entityNameInvalid,
|
|
13500
|
+
message: `${entityNameFormat.message}. ${entityNameFormat.instructions}`,
|
|
13501
|
+
severity: "error"
|
|
13502
|
+
});
|
|
13503
|
+
}
|
|
13504
|
+
const reservedEntityName = findReservedNameError(entity.Name, "entity");
|
|
13505
|
+
if (reservedEntityName) {
|
|
13506
|
+
diagnostics.push({
|
|
13507
|
+
code: DIAGNOSTIC_CODES.nameReserved,
|
|
13508
|
+
message: `${reservedEntityName.message}. ${reservedEntityName.instructions}`,
|
|
13509
|
+
severity: "error"
|
|
13510
|
+
});
|
|
13511
|
+
}
|
|
13512
|
+
const entityNameLower = entity.Name.toLowerCase();
|
|
13513
|
+
if (ctx.siblingNames.some((sibling) => sibling.toLowerCase() === entityNameLower)) {
|
|
13514
|
+
diagnostics.push({
|
|
13515
|
+
code: DIAGNOSTIC_CODES.entityNameNotUnique,
|
|
13516
|
+
message: `An entity named '${entity.Name}' already exists in this solution. Entity names are solution-wide unique.`,
|
|
13517
|
+
severity: "error"
|
|
13518
|
+
});
|
|
13519
|
+
}
|
|
13520
|
+
diagnostics.push(...typeProblems(entity, ENTITY_SCALARS).map((problem) => propertyTypeDiagnostic(`Entity '${entity.Name}'`, problem)));
|
|
13521
|
+
if (!Array.isArray(entity.Fields)) {
|
|
13522
|
+
diagnostics.push({
|
|
13523
|
+
code: DIAGNOSTIC_CODES.fieldsMalformed,
|
|
13524
|
+
message: "The entity document has no usable 'Fields' array. The resource is malformed.",
|
|
13525
|
+
severity: "error"
|
|
13526
|
+
});
|
|
13527
|
+
return diagnostics;
|
|
13528
|
+
}
|
|
13529
|
+
const seenFieldNames = new Map;
|
|
13530
|
+
for (const field of entity.Fields) {
|
|
13531
|
+
if (typeof field?.Name !== "string") {
|
|
13532
|
+
diagnostics.push({
|
|
13533
|
+
code: DIAGNOSTIC_CODES.fieldNameInvalid,
|
|
13534
|
+
message: "A field has no 'Name'. Every field needs one, system or custom.",
|
|
13535
|
+
severity: "error"
|
|
13536
|
+
});
|
|
13537
|
+
continue;
|
|
13538
|
+
}
|
|
13539
|
+
const isSystem = isSystemField(field);
|
|
13540
|
+
if (!SYSTEM_FIELD_NAMES.has(field.Name)) {
|
|
13541
|
+
diagnostics.push(...fieldTypeDiagnostics(field));
|
|
13542
|
+
}
|
|
13543
|
+
const fieldNameFormat = isSystem ? null : validateNameFormat(field.Name, "field");
|
|
13544
|
+
if (fieldNameFormat) {
|
|
13545
|
+
diagnostics.push({
|
|
13546
|
+
code: DIAGNOSTIC_CODES.fieldNameInvalid,
|
|
13547
|
+
message: `${fieldNameFormat.message}. ${fieldNameFormat.instructions}`,
|
|
13548
|
+
severity: "error",
|
|
13549
|
+
fieldName: field.Name
|
|
13550
|
+
});
|
|
13551
|
+
}
|
|
13552
|
+
if (!isSystem) {
|
|
13553
|
+
const reservedFieldName = findReservedNameError(field.Name, "field");
|
|
13554
|
+
if (reservedFieldName) {
|
|
13555
|
+
diagnostics.push({
|
|
13556
|
+
code: DIAGNOSTIC_CODES.nameReserved,
|
|
13557
|
+
message: `${reservedFieldName.message}. ${reservedFieldName.instructions}`,
|
|
13558
|
+
severity: "error",
|
|
13559
|
+
fieldName: field.Name
|
|
13560
|
+
});
|
|
13561
|
+
}
|
|
13562
|
+
}
|
|
13563
|
+
const fieldNameLower = field.Name.toLowerCase();
|
|
13564
|
+
if (!isSystem && typeof entity.Name === "string" && fieldNameLower === entity.Name.toLowerCase()) {
|
|
13565
|
+
diagnostics.push({
|
|
13566
|
+
code: DIAGNOSTIC_CODES.fieldNameInvalid,
|
|
13567
|
+
message: `Field name '${field.Name}' cannot match entity name '${entity.Name}' (names are compared case-insensitively).`,
|
|
13568
|
+
severity: "error",
|
|
13569
|
+
fieldName: field.Name
|
|
13570
|
+
});
|
|
13571
|
+
}
|
|
13572
|
+
const firstWithName = seenFieldNames.get(fieldNameLower);
|
|
13573
|
+
if (firstWithName !== undefined) {
|
|
13574
|
+
diagnostics.push({
|
|
13575
|
+
code: DIAGNOSTIC_CODES.duplicateFieldName,
|
|
13576
|
+
message: `Duplicate field name '${field.Name}' (names are case-insensitive; first defined as '${firstWithName}').`,
|
|
13577
|
+
severity: "error",
|
|
13578
|
+
fieldName: field.Name
|
|
13579
|
+
});
|
|
13580
|
+
} else {
|
|
13581
|
+
seenFieldNames.set(fieldNameLower, field.Name);
|
|
13582
|
+
}
|
|
13583
|
+
if (!isSystem && !ALLOWED_TYPE_PAIRS.has(`${field.FieldDisplayType}:${field.SqlType?.Name}`)) {
|
|
13584
|
+
diagnostics.push({
|
|
13585
|
+
code: DIAGNOSTIC_CODES.fieldTypeNotAllowed,
|
|
13586
|
+
message: `Field '${field.Name}' uses an unsupported type combination ` + `(${field.FieldDisplayType} / ${field.SqlType?.Name}).`,
|
|
13587
|
+
severity: "error",
|
|
13588
|
+
fieldName: field.Name
|
|
13589
|
+
});
|
|
13590
|
+
}
|
|
13591
|
+
}
|
|
13592
|
+
const usableFields = entity.Fields.filter((field) => typeof field === "object" && field !== null);
|
|
13593
|
+
const multilineMax = usableFields.filter((field) => field.SqlType?.Name === SqlTypeName.MULTILINE_MAX);
|
|
13594
|
+
if (multilineMax.length > MAX_MULTILINE_MAX_FIELDS) {
|
|
13595
|
+
diagnostics.push({
|
|
13596
|
+
code: DIAGNOSTIC_CODES.tooManyMultilineMax,
|
|
13597
|
+
message: `Entity '${entity.Name}' defines ${multilineMax.length} MULTILINE_MAX fields; ` + `the maximum is ${MAX_MULTILINE_MAX_FIELDS}. Remove some, or use MULTILINE_TEXT where the content fits.`,
|
|
13598
|
+
severity: "error"
|
|
13599
|
+
});
|
|
13600
|
+
}
|
|
13601
|
+
diagnostics.push(...validateSystemFields(entity, usableFields));
|
|
13602
|
+
return diagnostics;
|
|
13603
|
+
}
|
|
13604
|
+
var SERVER_ASSIGNED_FIELD_PROPS = new Set([
|
|
13605
|
+
"Id",
|
|
13606
|
+
"CreateTime",
|
|
13607
|
+
"CreatedBy",
|
|
13608
|
+
"UpdateTime",
|
|
13609
|
+
"UpdatedBy"
|
|
13610
|
+
]);
|
|
13611
|
+
function isUnmodifiedSystemField(template, actual) {
|
|
13612
|
+
const equal = (left, right) => JSON.stringify(left ?? null) === JSON.stringify(right ?? null);
|
|
13613
|
+
for (const key of Object.keys(template)) {
|
|
13614
|
+
if (!equal(template[key], actual[key])) {
|
|
13615
|
+
return false;
|
|
13616
|
+
}
|
|
13617
|
+
}
|
|
13618
|
+
return Object.keys(actual).every((key) => (key in template) || SERVER_ASSIGNED_FIELD_PROPS.has(key));
|
|
13619
|
+
}
|
|
13620
|
+
function validateSystemFields(entity, usableFields) {
|
|
13621
|
+
const diagnostics = [];
|
|
13622
|
+
for (const template of SYSTEM_FIELD_TEMPLATES) {
|
|
13623
|
+
const actual = usableFields.find((field) => field.Name === template.Name);
|
|
13624
|
+
if (!actual) {
|
|
13625
|
+
diagnostics.push({
|
|
13626
|
+
code: DIAGNOSTIC_CODES.systemFieldMissing,
|
|
13627
|
+
message: `System field '${template.Name}' is missing. System fields cannot be removed.`,
|
|
13628
|
+
severity: "error",
|
|
13629
|
+
fieldName: template.Name
|
|
13630
|
+
});
|
|
13631
|
+
continue;
|
|
13632
|
+
}
|
|
13633
|
+
if (!isUnmodifiedSystemField(template, actual)) {
|
|
13634
|
+
diagnostics.push({
|
|
13635
|
+
code: DIAGNOSTIC_CODES.systemFieldModified,
|
|
13636
|
+
message: `System field '${template.Name}' was modified. System fields are read-only.`,
|
|
13637
|
+
severity: "error",
|
|
13638
|
+
fieldName: template.Name
|
|
13639
|
+
});
|
|
13640
|
+
}
|
|
13641
|
+
}
|
|
13642
|
+
return diagnostics;
|
|
13643
|
+
}
|
|
13644
|
+
function isSystemField(field) {
|
|
13645
|
+
const { IsSystemField: flag, Name: name } = field ?? {};
|
|
13646
|
+
return flag === true || typeof name === "string" && SYSTEM_FIELD_NAMES.has(name);
|
|
13647
|
+
}
|
|
13648
|
+
var SYSTEM_FIELD_NAMES = new Set(SYSTEM_FIELD_TEMPLATES.map((template) => template.Name));
|
|
13649
|
+
var ENTITY_SCALARS = [
|
|
13650
|
+
{ key: "DisplayName", kind: "string" },
|
|
13651
|
+
{ key: "Description", kind: "string" },
|
|
13652
|
+
{ key: "EntityTypeId", kind: "integer" },
|
|
13653
|
+
{ key: "RecordCount", kind: "integer" },
|
|
13654
|
+
{ key: "IsRbacEnabled", kind: "boolean" },
|
|
13655
|
+
{ key: "IsModelReserved", kind: "boolean" }
|
|
13656
|
+
];
|
|
13657
|
+
var FIELD_SCALARS = [
|
|
13658
|
+
{ key: "DisplayName", kind: "string" },
|
|
13659
|
+
{ key: "Description", kind: "string" },
|
|
13660
|
+
{ key: "ReferenceType", kind: "string" },
|
|
13661
|
+
{ key: "FieldCategoryId", kind: "integer" },
|
|
13662
|
+
{ key: "IsRequired", kind: "boolean" },
|
|
13663
|
+
{ key: "IsUnique", kind: "boolean" },
|
|
13664
|
+
{ key: "IsPrimaryKey", kind: "boolean" },
|
|
13665
|
+
{ key: "IsForeignKey", kind: "boolean" },
|
|
13666
|
+
{ key: "IsSystemField", kind: "boolean" },
|
|
13667
|
+
{ key: "IsExternalField", kind: "boolean" },
|
|
13668
|
+
{ key: "IsHiddenField", kind: "boolean" },
|
|
13669
|
+
{ key: "IsEncrypted", kind: "boolean" },
|
|
13670
|
+
{ key: "IsAttachment", kind: "boolean" },
|
|
13671
|
+
{ key: "IsRbacEnabled", kind: "boolean" },
|
|
13672
|
+
{ key: "IsModelReserved", kind: "boolean" }
|
|
13673
|
+
];
|
|
13674
|
+
var SQL_TYPE_SCALARS = [
|
|
13675
|
+
{ key: "LengthLimit", kind: "integer", nullable: true },
|
|
13676
|
+
{ key: "DecimalPrecision", kind: "integer", nullable: true },
|
|
13677
|
+
{ key: "MaxValue", kind: "number", nullable: true },
|
|
13678
|
+
{ key: "MinValue", kind: "number", nullable: true }
|
|
13679
|
+
];
|
|
13680
|
+
function typeProblems(record, rules, prefix = "") {
|
|
13681
|
+
const values = record;
|
|
13682
|
+
return rules.filter(({ key, kind, nullable }) => {
|
|
13683
|
+
const value = values[key];
|
|
13684
|
+
if (value === undefined)
|
|
13685
|
+
return false;
|
|
13686
|
+
if (value === null)
|
|
13687
|
+
return !nullable;
|
|
13688
|
+
if (kind === "integer")
|
|
13689
|
+
return !Number.isInteger(value);
|
|
13690
|
+
return kind === "number" ? !(typeof value === "number" && Number.isFinite(value)) : typeof value !== kind;
|
|
13691
|
+
}).map(({ key, kind, nullable }) => `'${prefix}${key}' must be ${kind === "integer" ? "an" : "a"} ${kind}${nullable ? " or null" : ""}`);
|
|
13692
|
+
}
|
|
13693
|
+
function propertyTypeDiagnostic(subject, problem, fieldName) {
|
|
13694
|
+
return {
|
|
13695
|
+
code: DIAGNOSTIC_CODES.propertyTypeInvalid,
|
|
13696
|
+
message: `${subject}: ${problem}. The resource was edited by hand or is malformed.`,
|
|
13697
|
+
severity: "error",
|
|
13698
|
+
...fieldName !== undefined && { fieldName }
|
|
13699
|
+
};
|
|
13700
|
+
}
|
|
13701
|
+
function fieldTypeDiagnostics(field) {
|
|
13702
|
+
const problems = typeProblems(field, FIELD_SCALARS);
|
|
13703
|
+
if (typeof field.SqlType === "object" && field.SqlType !== null) {
|
|
13704
|
+
problems.push(...typeProblems(field.SqlType, SQL_TYPE_SCALARS, "SqlType."));
|
|
13705
|
+
}
|
|
13706
|
+
const defaultValue = field.DefaultValue;
|
|
13707
|
+
const isYesNo = field.SqlType?.Name === SqlTypeName.BIT;
|
|
13708
|
+
if (defaultValue != null && typeof defaultValue !== "string" && !(isYesNo && typeof defaultValue === "boolean")) {
|
|
13709
|
+
problems.push(isYesNo ? "'DefaultValue' must be a boolean, a string or null" : "'DefaultValue' must be a string or null");
|
|
13710
|
+
}
|
|
13711
|
+
return problems.map((problem) => propertyTypeDiagnostic(`Field '${field.Name}'`, problem, field.Name));
|
|
13712
|
+
}
|
|
13713
|
+
|
|
13714
|
+
// src/init/entity-init-service.ts
|
|
13715
|
+
var VALID_PROJECT_NAME_REGEX = /^[a-zA-Z0-9_-]+$/;
|
|
13716
|
+
async function entityInitAsync(name, options) {
|
|
13717
|
+
if (!VALID_PROJECT_NAME_REGEX.test(name)) {
|
|
13718
|
+
throw new Error(`Invalid project name "${name}". Name can only contain letters, numbers, underscores (_), and hyphens (-).`);
|
|
13719
|
+
}
|
|
13720
|
+
const entityName = options.firstEntityName;
|
|
13721
|
+
requireAuthoredName(options.firstEntity, entityName);
|
|
13722
|
+
const nameError = validateNameFormat(entityName, "entity");
|
|
13723
|
+
if (nameError) {
|
|
13724
|
+
throw new Error(`${nameError.message}. ${nameError.instructions}`);
|
|
13725
|
+
}
|
|
13726
|
+
const fs7 = getFileSystem();
|
|
13727
|
+
const solutionFile = await resolveSolutionFileAsync(options);
|
|
13728
|
+
const { projectDir, autoCreatedSolution } = solutionFile ? { projectDir: fs7.path.join(fs7.path.dirname(solutionFile), name) } : await prepareProjectLocation(fs7, fs7.path.resolve(requireCwd(options), name), name, {});
|
|
13729
|
+
const [statError, stat2] = await catchError(fs7.stat(projectDir));
|
|
13730
|
+
if (statError && !isMissingPathError(statError)) {
|
|
13731
|
+
throw statError;
|
|
13732
|
+
}
|
|
13733
|
+
const projectDirExisted = !statError && stat2 !== null;
|
|
13734
|
+
if (await isSymlinkEntryAsync(projectDir, fs7)) {
|
|
13735
|
+
throw new Error(`Directory "${name}" is a link, not a project directory in the solution. ` + "Replace the link with the directory itself, or pick a different name.");
|
|
13736
|
+
}
|
|
13737
|
+
if (projectDirExisted && !options.force) {
|
|
13738
|
+
const existingEntries = await fs7.readdir(projectDir);
|
|
13739
|
+
if (existingEntries.length > 0) {
|
|
13740
|
+
throw new Error(`Directory "${name}" already exists and is not empty. Use --force to overwrite.`);
|
|
13741
|
+
}
|
|
13742
|
+
}
|
|
13743
|
+
let registered;
|
|
13744
|
+
const created = [];
|
|
13745
|
+
const writeTracked = async (path3, content) => {
|
|
13746
|
+
if (await isSymlinkEntryAsync(path3, fs7)) {
|
|
13747
|
+
throw new Error(`'${path3}' is a symbolic link. Entity project files must be real files; replace the link with the file itself.`);
|
|
13748
|
+
}
|
|
13749
|
+
const [readError, previous] = await catchError(fs7.readFile(path3, "utf-8"));
|
|
13750
|
+
if (readError && !isMissingPathError(readError))
|
|
13751
|
+
throw readError;
|
|
13752
|
+
created.push({
|
|
13753
|
+
path: path3,
|
|
13754
|
+
previous: typeof previous === "string" ? previous : undefined
|
|
13755
|
+
});
|
|
13756
|
+
await fs7.writeFile(path3, content);
|
|
13757
|
+
};
|
|
13758
|
+
const rollback = async () => {
|
|
13759
|
+
if (registered) {
|
|
13760
|
+
await unregisterProject(registered);
|
|
13761
|
+
}
|
|
13762
|
+
for (const { path: path3, previous } of [...created].reverse()) {
|
|
13763
|
+
const [undoError] = await catchError(previous === undefined ? fs7.rm(path3) : fs7.writeFile(path3, previous));
|
|
13764
|
+
if (undoError) {
|
|
13765
|
+
await reportUndoFailureAsync(path3, previous, undoError);
|
|
13766
|
+
}
|
|
13767
|
+
}
|
|
13768
|
+
if (!projectDirExisted) {
|
|
13769
|
+
await catchError(fs7.rm(projectDir));
|
|
13770
|
+
}
|
|
13771
|
+
};
|
|
13772
|
+
try {
|
|
13773
|
+
await fs7.mkdir(projectDir);
|
|
13774
|
+
const projectFile = fs7.path.join(projectDir, "project.uiproj");
|
|
13775
|
+
await writeTracked(projectFile, serialize({ Name: name, ProjectType: "Entity" }));
|
|
13776
|
+
const relativeResourcePath = entityResourcePath(entityName);
|
|
13777
|
+
const entityFile = fs7.path.join(projectDir, `${entityName}${ENTITY_EXTENSION_CONST}`);
|
|
13778
|
+
await writeTracked(entityFile, serialize({ name: entityName, resourcePath: relativeResourcePath }));
|
|
13779
|
+
const registration = await tryRegisterProjectInParentSolution(fs7, projectDir, {});
|
|
13780
|
+
if (registration.Status === "Registered" && registration.Solution && registration.ProjectId) {
|
|
13781
|
+
registered = {
|
|
13782
|
+
solutionFile: registration.Solution,
|
|
13783
|
+
projectId: registration.ProjectId
|
|
13784
|
+
};
|
|
13785
|
+
}
|
|
13786
|
+
if (registration.Status !== "Registered" && registration.Status !== "AlreadyRegistered" || !registration.Solution) {
|
|
13787
|
+
if (solutionFile && registration.Status === "Skipped") {
|
|
13788
|
+
throw new Error(`Entity project "${name}" could not be registered in '${solutionFile}': ` + `${registration.Instructions ?? registration.Message ?? "registration was skipped"}. ` + "A solution folder containing more than one .uipx is not supported yet — " + "register the project with 'uip solution projects add' instead.");
|
|
13789
|
+
}
|
|
13790
|
+
throw new Error(`Entity project "${name}" requires a parent solution (registration status: ${registration.Status}). ` + "Run inside a solution directory, or create one first with 'uip solution init'.");
|
|
13791
|
+
}
|
|
13792
|
+
const solutionDir = fs7.path.dirname(registration.Solution);
|
|
13793
|
+
const resourceFile = fs7.path.join(solutionDir, ...relativeResourcePath.split("/"));
|
|
13794
|
+
const document = options.firstEntity ?? createEntitySkeleton(entityName);
|
|
13795
|
+
const diagnostics = validateEntity(document, {
|
|
13796
|
+
siblingNames: await siblingNamesFor(solutionDir, entityName, fs7)
|
|
13797
|
+
});
|
|
13798
|
+
if (diagnostics.length > 0) {
|
|
13799
|
+
throw new Error(`Cannot create entity "${entityName}": ${diagnostics.map((diagnostic) => `${diagnostic.code}: ${diagnostic.message}`).join("; ")}`);
|
|
13800
|
+
}
|
|
13801
|
+
if (await fs7.exists(resourceFile)) {
|
|
13802
|
+
throw new Error(`An entity definition for "${entityName}" already exists in this solution ` + `('${relativeResourcePath}'). Entity names are solution-wide unique — ` + "pick a different name, or edit the existing entity with 'uip df entities update <Name> --local'.");
|
|
13803
|
+
}
|
|
13804
|
+
const destination = await resolvesInsideAsync(resourceFile, solutionDir, fs7);
|
|
13805
|
+
if (!destination.inside) {
|
|
13806
|
+
throw new Error(`The entity definition path '${relativeResourcePath}' resolves outside the solution, to '${destination.resolved}'. ` + `Entity definitions must live inside the solution at '${destination.root}'; replace the link with the directory itself.`);
|
|
13807
|
+
}
|
|
13808
|
+
await fs7.mkdir(fs7.path.dirname(resourceFile));
|
|
13809
|
+
await writeTracked(resourceFile, serialize(wrapEntityJson(document)));
|
|
13810
|
+
return {
|
|
13811
|
+
projectName: name,
|
|
13812
|
+
projectDir,
|
|
13813
|
+
entityFile,
|
|
13814
|
+
resourceFile,
|
|
13815
|
+
registration,
|
|
13816
|
+
autoCreatedSolution
|
|
13817
|
+
};
|
|
13818
|
+
} catch (error) {
|
|
13819
|
+
await rollback();
|
|
13820
|
+
throw error;
|
|
13821
|
+
}
|
|
13822
|
+
}
|
|
13823
|
+
async function reportUndoFailureAsync(path3, previous, undoError) {
|
|
13824
|
+
const fs7 = getFileSystem();
|
|
13825
|
+
if (previous !== undefined) {
|
|
13826
|
+
const [readError, now] = await catchError(fs7.readFile(path3, "utf-8"));
|
|
13827
|
+
if (readError) {
|
|
13828
|
+
logger.warn(`Could not restore '${path3}' after a failed --force (${undoError.message}), nor read it to check (${readError.message}). Check its content before retrying.`);
|
|
13829
|
+
} else if (now !== previous) {
|
|
13830
|
+
logger.warn(`Could not restore '${path3}' after a failed --force: ${undoError.message}. ` + "Its previous content was not written back; recover it from version control or a backup.");
|
|
13831
|
+
}
|
|
13832
|
+
return;
|
|
13833
|
+
}
|
|
13834
|
+
const [statError, stat2] = await catchError(fs7.stat(path3));
|
|
13835
|
+
if (statError || stat2 !== null) {
|
|
13836
|
+
logger.warn(`Could not remove '${path3}', written by the failed run: ${undoError.message}. Delete it before retrying.`);
|
|
13837
|
+
}
|
|
13838
|
+
}
|
|
13839
|
+
function requireCwd(options) {
|
|
13840
|
+
if (!options.cwd) {
|
|
13841
|
+
throw new Error("Either 'cwd' or 'uipxPath' is required: without one there is no base " + "directory to create the project in.");
|
|
13047
13842
|
}
|
|
13048
13843
|
return options.cwd;
|
|
13049
13844
|
}
|
|
@@ -13072,9 +13867,6 @@ async function resolveSolutionFileAsync(options) {
|
|
|
13072
13867
|
}
|
|
13073
13868
|
return resolved;
|
|
13074
13869
|
}
|
|
13075
|
-
function isMissingPathError(error) {
|
|
13076
|
-
return "code" in error && (error.code === "ENOENT" || error.code === "PathNotFound");
|
|
13077
|
-
}
|
|
13078
13870
|
async function unregisterProject(registered) {
|
|
13079
13871
|
const { solutionFile, projectId } = registered;
|
|
13080
13872
|
const fs7 = getFileSystem();
|
|
@@ -13093,4 +13885,4 @@ export {
|
|
|
13093
13885
|
entityInitAsync
|
|
13094
13886
|
};
|
|
13095
13887
|
|
|
13096
|
-
//# debugId=
|
|
13888
|
+
//# debugId=3E83943EDBFF213264756E2164756E21
|