@esri/solution-common 6.6.1-next.8 → 6.6.1-next.81
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/cjs/arcgisRestJS.d.ts +6 -3
- package/dist/cjs/featureServiceHelpers.d.ts +26 -1
- package/dist/cjs/featureServiceHelpers.js +99 -10
- package/dist/cjs/restHelpers.d.ts +31 -14
- package/dist/cjs/restHelpers.js +61 -31
- package/dist/esm/arcgisRestJS.d.ts +6 -3
- package/dist/esm/arcgisRestJS.js +1 -1
- package/dist/esm/featureServiceHelpers.d.ts +26 -1
- package/dist/esm/featureServiceHelpers.js +96 -8
- package/dist/esm/restHelpers.d.ts +31 -14
- package/dist/esm/restHelpers.js +56 -28
- package/dist/solution.js_commit.txt +6 -6
- package/package.json +2 -2
|
@@ -19,9 +19,12 @@
|
|
|
19
19
|
import { IFolderIdOptions, IGetGroupContentOptions, IGetUserOptions, IGroup, IGroupContentResult, IGetRelatedItemsResponse, IGroupSharingOptions, IItem, IItemRelationshipOptions, IItemResourceOptions, IItemResourceResponse, IPortal, IRemoveItemResourceOptions, ISearchOptions, ISearchResult, ISharingResponse, IUpdateGroupOptions, IUpdateItemOptions, IUpdateItemResponse, IUser, IUserGroupOptions, IUserItemOptions, SearchQueryBuilder } from "@esri/arcgis-rest-portal";
|
|
20
20
|
import { IRequestOptions } from "@esri/arcgis-rest-request";
|
|
21
21
|
import { IAddToServiceDefinitionOptions, IAddToServiceDefinitionResult, IQueryRelatedOptions, IQueryRelatedResponse } from "@esri/arcgis-rest-feature-service";
|
|
22
|
-
export {
|
|
23
|
-
export {
|
|
24
|
-
export {
|
|
22
|
+
export { createFeatureService as svcAdminCreateFeatureService, queryFeatures, addFeatures, applyEdits, } from "@esri/arcgis-rest-feature-service";
|
|
23
|
+
export type { IAddToServiceDefinitionOptions, IAddToServiceDefinitionResult, ICreateServiceParams, ICreateServiceResult, IExtent, ISpatialReference, IFeature, IQueryRelatedOptions, IQueryRelatedResponse, IRelatedRecordGroup, } from "@esri/arcgis-rest-feature-service";
|
|
24
|
+
export { addItemData as restAddItemData, addItemRelationship, createFolder, createGroup, createItem, createItemInFolder, moveItem, protectItem, SearchQueryBuilder, getGroupCategorySchema as restGetGroupCategorySchema, getItem, getItemData, getItemResources as restGetItemResources, getUserContent, getPortal as restGetPortal, getPortalUrl, searchGroupContent, setItemAccess, searchGroups as restSearchGroups, removeGroupUsers, removeItem as restRemoveItem, } from "@esri/arcgis-rest-portal";
|
|
25
|
+
export type { IAddFolderResponse, IAddItemDataOptions, ICreateItemOptions, ICreateItemResponse, IFolder, IFolderIdOptions, IGetGroupContentOptions, IGetRelatedItemsResponse, IGroup, IGroupAdd, IGroupCategorySchema as restIGroupCategorySchema, IItem, IItemRelationshipOptions, IItemResourceOptions, IItemResourceResponse, IManageItemRelationshipOptions, IMoveItemOptions, IMoveItemResponse, IPagedResponse, IPagingParams, IPortal, IRemoveItemResourceOptions, ISearchGroupContentOptions, ISearchOptions, ISearchResult, ISetAccessOptions, ISharingResponse, ItemRelationshipType, IUpdateGroupOptions, IUpdateItemOptions, IUpdateItemResponse, IUser, IUserContentResponse, IUserGroupOptions, IGroupSharingOptions, IUserItemOptions, } from "@esri/arcgis-rest-portal";
|
|
26
|
+
export { ArcGISAuthError, encodeFormData, ArcGISIdentityManager as UserSession } from "@esri/arcgis-rest-request";
|
|
27
|
+
export type { IArcGISIdentityManagerOptions, ICredential, IRequestOptions, IParams } from "@esri/arcgis-rest-request";
|
|
25
28
|
export interface IFolderSuccessResult {
|
|
26
29
|
success: boolean;
|
|
27
30
|
folder: {
|
|
@@ -164,9 +164,12 @@ export declare function getLayerSettings(layerInfos: any, url: string, itemId: s
|
|
|
164
164
|
* The feature service name will have a generated GUID appended.
|
|
165
165
|
*
|
|
166
166
|
* @param templates A collection of AGO item templates.
|
|
167
|
+
* @param templateDictionary Optional hash of values used to resolve `{{...}}` tokens in the name
|
|
168
|
+
* before applying the 50-char base-name limit. When omitted, names containing unresolved tokens
|
|
169
|
+
* are passed through untruncated (legacy behavior).
|
|
167
170
|
* @returns An updated collection of AGO templates with unique feature service names.
|
|
168
171
|
*/
|
|
169
|
-
export declare function setNamesAndTitles(templates: IItemTemplate[]): IItemTemplate[];
|
|
172
|
+
export declare function setNamesAndTitles(templates: IItemTemplate[], templateDictionary?: any): IItemTemplate[];
|
|
170
173
|
/**
|
|
171
174
|
* This is used when deploying views.
|
|
172
175
|
* We need to update fields referenced in adminLayerInfo for relationships prior to deploying the view.
|
|
@@ -243,6 +246,28 @@ export declare function getExistingLayersAndTables(url: string, ids: number[], a
|
|
|
243
246
|
* @private
|
|
244
247
|
*/
|
|
245
248
|
export declare function addFeatureServiceLayersAndTables(itemTemplate: IItemTemplate, templateDictionary: any, popupInfos: IPopupInfos, authentication: UserSession): Promise<void>;
|
|
249
|
+
/**
|
|
250
|
+
* Shorten any layer or table name longer than `maxNameLength` to a unique value of at most
|
|
251
|
+
* `maxNameLength` characters, in preparation for an addToDefinition call, and report the original
|
|
252
|
+
* names so they can be restored afterward.
|
|
253
|
+
*
|
|
254
|
+
* Mutates the `name` of each over-long layer/table in `layerChunks` in place.
|
|
255
|
+
*
|
|
256
|
+
* @param layerChunks The addToDefinition chunks whose `layers` and `tables` will be added
|
|
257
|
+
* @param maxNameLength Names longer than this are truncated to a unique value of this length
|
|
258
|
+
* @returns The original names to restore, as `{ layers: [{ id, name }], tables: [{ id, name }] }`
|
|
259
|
+
* @private
|
|
260
|
+
*/
|
|
261
|
+
export declare function _truncateNamesForAddToDefinition(layerChunks: any[], maxNameLength: number): {
|
|
262
|
+
layers: Array<{
|
|
263
|
+
id: any;
|
|
264
|
+
name: string;
|
|
265
|
+
}>;
|
|
266
|
+
tables: Array<{
|
|
267
|
+
id: any;
|
|
268
|
+
name: string;
|
|
269
|
+
}>;
|
|
270
|
+
};
|
|
246
271
|
/**
|
|
247
272
|
* Updates a feature service with a list of layers and/or tables.
|
|
248
273
|
*
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
* limitations under the License.
|
|
16
16
|
*/
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
-
exports.
|
|
19
|
-
exports._getLayerChunkSize = exports._getNameMapping = exports._templatizeDefinitionQuery = exports._templatizeTimeInfo = exports._templatizeKeys = exports._templatizeTypeTemplates = exports._templatizeTemplates = exports._templatizeLabelingInfo = exports._templatizeArcadeExpressions = exports._templatizeAuthoringInfo = exports._templatizeTemporalRenderer = exports._templatizeGenRenderer = exports._templatizeRenderer = exports._templatizeDrawingInfo = exports._templatizeSimpleName = exports._templatizeDefinitionExpression = exports._templatizeDefinitionEditor = exports._templatizeMediaInfos = exports._templatizePopupElements = exports._templatizeExpressionInfos = exports._templatizeFieldName = exports._templatizePopupInfoFieldInfos = exports._templatizeName = exports._templatizePopupInfo = exports._templatizeRelationshipFields = exports._templatizeTopFilter = exports._templatizeAdminSourceLayerFields = exports._getDependantItemId = exports._templatizeAdminLayerInfoFields = exports._templatizeSourceServiceName = exports._processAdminObject = exports._templatizeAdminLayerInfo = exports._templatizeLayerFieldReferences = void 0;
|
|
18
|
+
exports._validateTypesTemplates = exports._validateTemplatesFields = exports._validateIndexes = exports._validateDisplayField = exports._validateFields = exports._templatizeLayer = exports._templatizeProperty = exports._templatize = exports.updatePopupInfo = exports._validateViewDomainFields = exports.postProcessFields = exports.updateLayerFieldReferences = exports._getSourceSpatialReferenceAndExtent = exports.validateSpatialReferenceAndExtent = exports.setDefaultSpatialReference = exports._updateTemplateDictionaryFields = exports._updateGeomFieldName = exports._updateSourceLayerFields = exports._updateItemFields = exports._getDynamicFieldNames = exports._getFieldNames = exports._updateForPortal = exports.removeLayerOptimization = exports._isSelfReferential = exports._updateAddOptions = exports._updateOrder = exports.addFeatureServiceDefinition = exports._truncateNamesForAddToDefinition = exports.addFeatureServiceLayersAndTables = exports.getExistingLayersAndTables = exports.getLayersAndTables = exports.deTemplatizeFieldInfos = exports.processContingentValues = exports.updateTemplateForInvalidDesignations = exports.updateSettingsFieldInfos = exports.setNamesAndTitles = exports.getLayerSettings = exports._setTrackingViewLayerSettings = exports._updateTypeKeywords = exports.updateTemplate = exports.cacheLayerInfo = exports._cachePopupInfo = exports.cachePopupInfos = exports._cacheFieldInfo = exports.cacheIndexes = exports.cacheContingentValues = exports.cacheFieldInfos = exports.deleteViewProps = exports.templatize = exports.getFeatureServiceRelatedRecords = void 0;
|
|
19
|
+
exports._getLayerChunkSize = exports._getNameMapping = exports._templatizeDefinitionQuery = exports._templatizeTimeInfo = exports._templatizeKeys = exports._templatizeTypeTemplates = exports._templatizeTemplates = exports._templatizeLabelingInfo = exports._templatizeArcadeExpressions = exports._templatizeAuthoringInfo = exports._templatizeTemporalRenderer = exports._templatizeGenRenderer = exports._templatizeRenderer = exports._templatizeDrawingInfo = exports._templatizeSimpleName = exports._templatizeDefinitionExpression = exports._templatizeDefinitionEditor = exports._templatizeMediaInfos = exports._templatizePopupElements = exports._templatizeExpressionInfos = exports._templatizeFieldName = exports._templatizePopupInfoFieldInfos = exports._templatizeName = exports._templatizePopupInfo = exports._templatizeRelationshipFields = exports._templatizeTopFilter = exports._templatizeAdminSourceLayerFields = exports._getDependantItemId = exports._templatizeAdminLayerInfoFields = exports._templatizeSourceServiceName = exports._processAdminObject = exports._templatizeAdminLayerInfo = exports._templatizeLayerFieldReferences = exports._validateEditFieldsInfo = void 0;
|
|
20
20
|
/**
|
|
21
21
|
* Provides general helper functions.
|
|
22
22
|
*
|
|
@@ -158,9 +158,11 @@ exports.deleteViewProps = deleteViewProps;
|
|
|
158
158
|
*/
|
|
159
159
|
function cacheFieldInfos(layer, fieldInfos, isView, isPortal) {
|
|
160
160
|
// cache the source fields as they are in the original source
|
|
161
|
-
|
|
161
|
+
// Note: layer.id is commonly 0 for the first layer, so use a presence check
|
|
162
|
+
// (not a truthy check) to avoid skipping the layer with id === 0.
|
|
163
|
+
if (layer && layer.id !== undefined && layer.id !== null) {
|
|
162
164
|
fieldInfos[layer.id] = {
|
|
163
|
-
sourceFields: JSON.parse(JSON.stringify(layer.fields)),
|
|
165
|
+
sourceFields: layer.fields ? JSON.parse(JSON.stringify(layer.fields)) : [],
|
|
164
166
|
type: layer.type,
|
|
165
167
|
id: layer.id,
|
|
166
168
|
};
|
|
@@ -443,9 +445,12 @@ exports.getLayerSettings = getLayerSettings;
|
|
|
443
445
|
* The feature service name will have a generated GUID appended.
|
|
444
446
|
*
|
|
445
447
|
* @param templates A collection of AGO item templates.
|
|
448
|
+
* @param templateDictionary Optional hash of values used to resolve `{{...}}` tokens in the name
|
|
449
|
+
* before applying the 50-char base-name limit. When omitted, names containing unresolved tokens
|
|
450
|
+
* are passed through untruncated (legacy behavior).
|
|
446
451
|
* @returns An updated collection of AGO templates with unique feature service names.
|
|
447
452
|
*/
|
|
448
|
-
function setNamesAndTitles(templates) {
|
|
453
|
+
function setNamesAndTitles(templates, templateDictionary) {
|
|
449
454
|
const guid = (0, generalHelpers_1.generateGUID)();
|
|
450
455
|
const names = [];
|
|
451
456
|
return templates.map((t) => {
|
|
@@ -459,9 +464,20 @@ function setNamesAndTitles(templates) {
|
|
|
459
464
|
let baseName = t.item.name || t.item.title;
|
|
460
465
|
// If the name already contains a GUID remove it
|
|
461
466
|
baseName = baseName.replace(/_[0-9A-F]{32}/gi, "");
|
|
462
|
-
//
|
|
463
|
-
//
|
|
464
|
-
const
|
|
467
|
+
// Resolve any {{...}} tokens (e.g. {{params.buildSolution.items.<id>.title}}) so the
|
|
468
|
+
// base-name length limit reflects the value AGOL will actually see at create time.
|
|
469
|
+
const resolvedBaseName = templateDictionary
|
|
470
|
+
? (0, templatization_1.replaceInTemplate)(baseName, templateDictionary)
|
|
471
|
+
: baseName;
|
|
472
|
+
// Limit the base name to 50 chars so the full service name (base + "_" + 32-char guid)
|
|
473
|
+
// stays within AGOL's service-name length limit. This 50-char cap is long-standing
|
|
474
|
+
// behavior. If unresolved {{...}} tokens remain we can't know the resolved length, so
|
|
475
|
+
// leave the name untruncated.
|
|
476
|
+
const maxBaseNameLength = 50;
|
|
477
|
+
const stillTemplatized = resolvedBaseName.includes("{{");
|
|
478
|
+
const name = stillTemplatized
|
|
479
|
+
? resolvedBaseName + "_" + guid
|
|
480
|
+
: resolvedBaseName.substring(0, maxBaseNameLength) + "_" + guid;
|
|
465
481
|
// If the name + GUID already exists then append "_occurrenceCount"
|
|
466
482
|
t.item.name = names.indexOf(name) === -1 ? name : `${name}_${names.filter((n) => n === name).length}`;
|
|
467
483
|
names.push(name);
|
|
@@ -742,6 +758,53 @@ function addFeatureServiceLayersAndTables(itemTemplate, templateDictionary, popu
|
|
|
742
758
|
});
|
|
743
759
|
}
|
|
744
760
|
exports.addFeatureServiceLayersAndTables = addFeatureServiceLayersAndTables;
|
|
761
|
+
/**
|
|
762
|
+
* Shorten any layer or table name longer than `maxNameLength` to a unique value of at most
|
|
763
|
+
* `maxNameLength` characters, in preparation for an addToDefinition call, and report the original
|
|
764
|
+
* names so they can be restored afterward.
|
|
765
|
+
*
|
|
766
|
+
* Mutates the `name` of each over-long layer/table in `layerChunks` in place.
|
|
767
|
+
*
|
|
768
|
+
* @param layerChunks The addToDefinition chunks whose `layers` and `tables` will be added
|
|
769
|
+
* @param maxNameLength Names longer than this are truncated to a unique value of this length
|
|
770
|
+
* @returns The original names to restore, as `{ layers: [{ id, name }], tables: [{ id, name }] }`
|
|
771
|
+
* @private
|
|
772
|
+
*/
|
|
773
|
+
function _truncateNamesForAddToDefinition(layerChunks, maxNameLength) {
|
|
774
|
+
const restore = {
|
|
775
|
+
layers: [],
|
|
776
|
+
tables: [],
|
|
777
|
+
};
|
|
778
|
+
const allItems = [];
|
|
779
|
+
layerChunks.forEach((chunk) => {
|
|
780
|
+
chunk.layers.forEach((layer) => allItems.push({ item: layer, isLayer: true }));
|
|
781
|
+
chunk.tables.forEach((table) => allItems.push({ item: table, isLayer: false }));
|
|
782
|
+
});
|
|
783
|
+
// Reserve names that are already short enough so the truncated names won't collide with them.
|
|
784
|
+
const usedNames = new Set();
|
|
785
|
+
allItems.forEach(({ item }) => {
|
|
786
|
+
if (item.name.length <= maxNameLength) {
|
|
787
|
+
usedNames.add(item.name.toLowerCase());
|
|
788
|
+
}
|
|
789
|
+
});
|
|
790
|
+
allItems.forEach(({ item, isLayer }) => {
|
|
791
|
+
if (item.name.length > maxNameLength) {
|
|
792
|
+
const originalName = item.name;
|
|
793
|
+
let candidate = originalName.substring(0, maxNameLength);
|
|
794
|
+
let counter = 1;
|
|
795
|
+
// Keep the truncated name unique by trimming room for a numeric suffix when needed.
|
|
796
|
+
while (usedNames.has(candidate.toLowerCase())) {
|
|
797
|
+
const suffix = `_${counter++}`;
|
|
798
|
+
candidate = originalName.substring(0, maxNameLength - suffix.length) + suffix;
|
|
799
|
+
}
|
|
800
|
+
usedNames.add(candidate.toLowerCase());
|
|
801
|
+
item.name = candidate;
|
|
802
|
+
(isLayer ? restore.layers : restore.tables).push({ id: item.id, name: originalName });
|
|
803
|
+
}
|
|
804
|
+
});
|
|
805
|
+
return restore;
|
|
806
|
+
}
|
|
807
|
+
exports._truncateNamesForAddToDefinition = _truncateNamesForAddToDefinition;
|
|
745
808
|
/**
|
|
746
809
|
* Updates a feature service with a list of layers and/or tables.
|
|
747
810
|
*
|
|
@@ -826,7 +889,12 @@ function addFeatureServiceDefinition(serviceUrl, listToAdd, templateDictionary,
|
|
|
826
889
|
removeLayerOptimization(item);
|
|
827
890
|
// this can still chunk layers
|
|
828
891
|
options = _updateAddOptions(itemTemplate, options, layerChunks, isSelfReferential, authentication);
|
|
829
|
-
|
|
892
|
+
// Route based on the discriminator set by getLayersAndTables (which derives from
|
|
893
|
+
// properties.layers vs properties.tables) rather than the layer object's own `type`
|
|
894
|
+
// field. The latter may be missing when users supply custom layer JSON via
|
|
895
|
+
// params (e.g. {{params.buildSolution.items.<id>.service.layers}}), which would
|
|
896
|
+
// otherwise cause every layer to be pushed into the `tables` array.
|
|
897
|
+
if (toAdd.type === "layer" || item.type === "Feature Layer") {
|
|
830
898
|
options.layers.push(item);
|
|
831
899
|
}
|
|
832
900
|
else {
|
|
@@ -849,9 +917,30 @@ function addFeatureServiceDefinition(serviceUrl, listToAdd, templateDictionary,
|
|
|
849
917
|
// will use async by default rather than chunk the layer requests when we have more layers
|
|
850
918
|
// than the defined chunk size
|
|
851
919
|
const useAsync = listToAdd.length > chunkSize;
|
|
920
|
+
// Shorten any over-long layer/table names to short, unique values before adding them.
|
|
921
|
+
// Names will be restored afterward with one updateDefinition call per layer/table.
|
|
922
|
+
const maxBackingTableNameLength = 30;
|
|
923
|
+
const restoreNames = _truncateNamesForAddToDefinition(layerChunks, maxBackingTableNameLength);
|
|
924
|
+
// Base admin URL used for the per-layer updateDefinition restore calls below.
|
|
925
|
+
const adminServiceUrl = (0, generalHelpers_1.checkUrlPathTermination)(serviceUrl.replace("/rest/services", "/rest/admin/services"));
|
|
852
926
|
layerChunks
|
|
853
927
|
.reduce((prev, curr) => prev.then(() => (0, restHelpers_1.addToServiceDefinition)(serviceUrl, curr, false, useAsync)), Promise.resolve(null))
|
|
854
|
-
.then(() =>
|
|
928
|
+
.then(() => {
|
|
929
|
+
// Restore the original (pre-truncation) display names.
|
|
930
|
+
// I was seeing the updateDefinition call succeed but the names not being restored when I was doing this
|
|
931
|
+
// with a single call at the service endpoint. So now we are doing this sequentially.
|
|
932
|
+
const restoreItems = [...restoreNames.layers, ...restoreNames.tables];
|
|
933
|
+
restoreItems
|
|
934
|
+
.reduce((prev, entry) => prev.then(() => {
|
|
935
|
+
const restoreUpdate = {
|
|
936
|
+
url: adminServiceUrl + entry.id + "/updateDefinition",
|
|
937
|
+
params: { updateDefinition: { name: entry.name } },
|
|
938
|
+
args: { authentication },
|
|
939
|
+
};
|
|
940
|
+
return (0, restHelpers_1.getRequest)(restoreUpdate, false, false, templateDictionary.isPortal);
|
|
941
|
+
}), Promise.resolve(null))
|
|
942
|
+
.then(() => resolve(null), (e) => reject((0, generalHelpers_1.fail)(e)));
|
|
943
|
+
}, (e) => reject((0, generalHelpers_1.fail)(e)));
|
|
855
944
|
}
|
|
856
945
|
});
|
|
857
946
|
}
|
|
@@ -90,6 +90,28 @@ export declare function convertToISearchOptions(search: string | ISearchOptions
|
|
|
90
90
|
* @private
|
|
91
91
|
*/
|
|
92
92
|
export declare function _validateExtent(extent: IExtent): IExtent;
|
|
93
|
+
/**
|
|
94
|
+
* The geometry service can resolve a projection request successfully but still
|
|
95
|
+
* return "NaN" coordinate values or no geometry at all. This check is used to
|
|
96
|
+
* decide whether a projected extent can be used for a service's initial and full
|
|
97
|
+
* extents.
|
|
98
|
+
*
|
|
99
|
+
* @param extent the extent to test
|
|
100
|
+
* @returns true if the extent has numeric xmin, ymin, xmax, and ymax values
|
|
101
|
+
* @private
|
|
102
|
+
*/
|
|
103
|
+
export declare function _extentIsValid(extent: any): boolean;
|
|
104
|
+
/**
|
|
105
|
+
* Removes the templatized extent from a template's layers and tables.
|
|
106
|
+
*
|
|
107
|
+
* Used when the organization's default extent cannot be projected into the
|
|
108
|
+
* service's spatial reference so that the layers and tables are created without an
|
|
109
|
+
* extent rather than with an unresolved template variable.
|
|
110
|
+
*
|
|
111
|
+
* @param itemTemplate the template whose layer and table extents should be removed
|
|
112
|
+
* @private
|
|
113
|
+
*/
|
|
114
|
+
export declare function _removeLayerExtents(itemTemplate: IItemTemplate): void;
|
|
93
115
|
/**
|
|
94
116
|
* If the request to convert the extent fails it has commonly been due to an invalid extent.
|
|
95
117
|
* This function will first attempt to use the provided extent. If it fails it will default to
|
|
@@ -107,7 +129,6 @@ export declare function _validateExtent(extent: IExtent): IExtent;
|
|
|
107
129
|
export declare function convertExtentWithFallback(extent: IExtent, fallbackExtent: any, outSR: ISpatialReference, geometryServiceUrl: string, authentication: UserSession): Promise<any>;
|
|
108
130
|
/**
|
|
109
131
|
* Converts an extent to a specified spatial reference.
|
|
110
|
-
*
|
|
111
132
|
* @param extent Extent object to check and (possibly) to project
|
|
112
133
|
* @param outSR Desired spatial reference
|
|
113
134
|
* @param geometryServiceUrl Path to geometry service providing `findTransformations` and `project` services
|
|
@@ -528,6 +549,15 @@ export declare function _addItemMetadataFile(itemId: string, metadataFile: File,
|
|
|
528
549
|
* @private
|
|
529
550
|
*/
|
|
530
551
|
export declare function _countRelationships(layers: any[]): number;
|
|
552
|
+
/**
|
|
553
|
+
* Remove spaces and replace other characters that are not allowed in a feature service name with "_".
|
|
554
|
+
* Spaces are removed entirely. Disallowed (replaced with "_"): '#', '%', '&', '"', '\', '/', '+', '?', ':', '*',
|
|
555
|
+
* '<', '>', '\t', '!', '@', "'", ';', ','
|
|
556
|
+
*
|
|
557
|
+
* @param name The candidate service name
|
|
558
|
+
* @returns The sanitized name, or the input unchanged if it is not a string
|
|
559
|
+
*/
|
|
560
|
+
export declare function sanitizeFeatureServiceName(name: string): string;
|
|
531
561
|
/**
|
|
532
562
|
* Gets the full definitions of the layers affiliated with a hosted service.
|
|
533
563
|
*
|
|
@@ -538,19 +568,6 @@ export declare function _countRelationships(layers: any[]): number;
|
|
|
538
568
|
* @private
|
|
539
569
|
*/
|
|
540
570
|
export declare function _getCreateServiceOptions(newItemTemplate: IItemTemplate, authentication: UserSession, templateDictionary: any): Promise<any>;
|
|
541
|
-
/**
|
|
542
|
-
* When the services spatial reference does not match that of it's default extent
|
|
543
|
-
* use the out SRs default extent if it exists in the templateDictionary
|
|
544
|
-
* this should be set when adding a custom out wkid to the params before calling deploy
|
|
545
|
-
* this will help avoid situations where the orgs default extent and default world extent
|
|
546
|
-
* will not project successfully to the out SR
|
|
547
|
-
*
|
|
548
|
-
* @param serviceInfo the object that contains the spatial reference to evaluate
|
|
549
|
-
* @param templateDictionary the template dictionary
|
|
550
|
-
* @returns the extent to use as the fallback
|
|
551
|
-
* @private
|
|
552
|
-
*/
|
|
553
|
-
export declare function _getFallbackExtent(serviceInfo: any, templateDictionary: any): any;
|
|
554
571
|
/**
|
|
555
572
|
* Add relationships to all layers in one call to retain fully functioning composite relationships
|
|
556
573
|
*
|
package/dist/cjs/restHelpers.js
CHANGED
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
* limitations under the License.
|
|
16
16
|
*/
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
-
exports.
|
|
19
|
-
exports._updateItemURL = exports._updateIndexesForRelationshipKeyFields = exports._setItemProperties = exports._reportVariablesInItem = exports._lowercaseDomain = exports._getUpdate = exports._getSubtypeUpdates = exports._getContingentValuesUpdates = exports._getRelationshipUpdates = exports.
|
|
18
|
+
exports._addItemDataFile = exports.updateItemURL = exports.updateItemTemplateFromDictionary = exports.updateItemExtended = exports.updateGroup = exports.updateItem = exports.shareItem = exports.removeUsers = exports.reassignGroup = exports.searchGroupContents = exports.searchGroupAllContents = exports.searchAllGroups = exports.searchGroups = exports.searchAllItems = exports.searchItems = exports.removeItemOrGroup = exports.removeItem = exports.removeGroup = exports.removeFolder = exports.hasInvalidGroupDesignations = exports._parseAdminServiceData = exports.setWorkflowConfigurationZip = exports.getWorkflowConfigurationZip = exports.getFeatureServiceProperties = exports.getServiceLayersAndTables = exports.getRequest = exports._sortRelationships = exports.moveItemsToFolder = exports.moveItemToFolder = exports.getLayerUpdates = exports.getLayers = exports.extractDependencies = exports.createUniqueGroup = exports.createUniqueFolder = exports.createItemWithData = exports.createFullItem = exports.createFeatureService = exports.convertExtent = exports.convertExtentWithFallback = exports._removeLayerExtents = exports._extentIsValid = exports._validateExtent = exports.convertToISearchOptions = exports.checkRequestStatus = exports.addToServiceDefinition = exports.addTokenToUrl = exports.addForwardItemRelationships = exports.addForwardItemRelationship = exports.getUserSession = exports.addItemData = void 0;
|
|
19
|
+
exports._updateItemURL = exports._updateIndexesForRelationshipKeyFields = exports._setItemProperties = exports._reportVariablesInItem = exports._lowercaseDomain = exports._getUpdate = exports._getSubtypeUpdates = exports._getContingentValuesUpdates = exports._getRelationshipUpdates = exports._getCreateServiceOptions = exports.sanitizeFeatureServiceName = exports._countRelationships = exports._addItemMetadataFile = void 0;
|
|
20
20
|
/**
|
|
21
21
|
* Provides common functions involving the arcgis-rest-js library.
|
|
22
22
|
*
|
|
@@ -261,6 +261,38 @@ function _validateExtent(extent) {
|
|
|
261
261
|
return extent;
|
|
262
262
|
}
|
|
263
263
|
exports._validateExtent = _validateExtent;
|
|
264
|
+
/**
|
|
265
|
+
* The geometry service can resolve a projection request successfully but still
|
|
266
|
+
* return "NaN" coordinate values or no geometry at all. This check is used to
|
|
267
|
+
* decide whether a projected extent can be used for a service's initial and full
|
|
268
|
+
* extents.
|
|
269
|
+
*
|
|
270
|
+
* @param extent the extent to test
|
|
271
|
+
* @returns true if the extent has numeric xmin, ymin, xmax, and ymax values
|
|
272
|
+
* @private
|
|
273
|
+
*/
|
|
274
|
+
function _extentIsValid(extent) {
|
|
275
|
+
return (!!extent &&
|
|
276
|
+
[extent.xmin, extent.ymin, extent.xmax, extent.ymax].every((coordinate) => typeof coordinate === "number" && !isNaN(coordinate)));
|
|
277
|
+
}
|
|
278
|
+
exports._extentIsValid = _extentIsValid;
|
|
279
|
+
/**
|
|
280
|
+
* Removes the templatized extent from a template's layers and tables.
|
|
281
|
+
*
|
|
282
|
+
* Used when the organization's default extent cannot be projected into the
|
|
283
|
+
* service's spatial reference so that the layers and tables are created without an
|
|
284
|
+
* extent rather than with an unresolved template variable.
|
|
285
|
+
*
|
|
286
|
+
* @param itemTemplate the template whose layer and table extents should be removed
|
|
287
|
+
* @private
|
|
288
|
+
*/
|
|
289
|
+
function _removeLayerExtents(itemTemplate) {
|
|
290
|
+
["properties.layers", "properties.tables"].forEach((path) => {
|
|
291
|
+
const items = (0, generalHelpers_1.getProp)(itemTemplate, path) || [];
|
|
292
|
+
items.forEach((item) => (0, generalHelpers_1.deleteProp)(item, "extent"));
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
exports._removeLayerExtents = _removeLayerExtents;
|
|
264
296
|
/**
|
|
265
297
|
* If the request to convert the extent fails it has commonly been due to an invalid extent.
|
|
266
298
|
* This function will first attempt to use the provided extent. If it fails it will default to
|
|
@@ -305,7 +337,6 @@ function convertExtentWithFallback(extent, fallbackExtent, outSR, geometryServic
|
|
|
305
337
|
exports.convertExtentWithFallback = convertExtentWithFallback;
|
|
306
338
|
/**
|
|
307
339
|
* Converts an extent to a specified spatial reference.
|
|
308
|
-
*
|
|
309
340
|
* @param extent Extent object to check and (possibly) to project
|
|
310
341
|
* @param outSR Desired spatial reference
|
|
311
342
|
* @param geometryServiceUrl Path to geometry service providing `findTransformations` and `project` services
|
|
@@ -1660,6 +1691,18 @@ function _countRelationships(layers) {
|
|
|
1660
1691
|
return layers.reduce(reducer, 0);
|
|
1661
1692
|
}
|
|
1662
1693
|
exports._countRelationships = _countRelationships;
|
|
1694
|
+
/**
|
|
1695
|
+
* Remove spaces and replace other characters that are not allowed in a feature service name with "_".
|
|
1696
|
+
* Spaces are removed entirely. Disallowed (replaced with "_"): '#', '%', '&', '"', '\', '/', '+', '?', ':', '*',
|
|
1697
|
+
* '<', '>', '\t', '!', '@', "'", ';', ','
|
|
1698
|
+
*
|
|
1699
|
+
* @param name The candidate service name
|
|
1700
|
+
* @returns The sanitized name, or the input unchanged if it is not a string
|
|
1701
|
+
*/
|
|
1702
|
+
function sanitizeFeatureServiceName(name) {
|
|
1703
|
+
return typeof name === "string" ? name.replace(/ /g, "").replace(/[#%&"\\/+?:*<>\t!@';,]/g, "_") : name;
|
|
1704
|
+
}
|
|
1705
|
+
exports.sanitizeFeatureServiceName = sanitizeFeatureServiceName;
|
|
1663
1706
|
/**
|
|
1664
1707
|
* Gets the full definitions of the layers affiliated with a hosted service.
|
|
1665
1708
|
*
|
|
@@ -1676,7 +1719,6 @@ function _getCreateServiceOptions(newItemTemplate, authentication, templateDicti
|
|
|
1676
1719
|
const isPortal = templateDictionary.isPortal;
|
|
1677
1720
|
const itemId = newItemTemplate.itemId;
|
|
1678
1721
|
(0, featureServiceHelpers_1.validateSpatialReferenceAndExtent)(serviceInfo, newItemTemplate, templateDictionary);
|
|
1679
|
-
const fallbackExtent = _getFallbackExtent(serviceInfo, templateDictionary);
|
|
1680
1722
|
const params = {};
|
|
1681
1723
|
const itemInfo = {
|
|
1682
1724
|
title: newItemTemplate.item.title,
|
|
@@ -1695,12 +1737,23 @@ function _getCreateServiceOptions(newItemTemplate, authentication, templateDicti
|
|
|
1695
1737
|
createOptions.item = !(0, trackingHelpers_1.isTrackingViewTemplate)(newItemTemplate)
|
|
1696
1738
|
? _setItemProperties(createOptions.item, newItemTemplate, serviceInfo, params, isPortal)
|
|
1697
1739
|
: (0, trackingHelpers_1.setTrackingOptions)(newItemTemplate, createOptions, templateDictionary);
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1740
|
+
convertExtent(_validateExtent(templateDictionary.organization.defaultExtent), serviceInfo.service.spatialReference, templateDictionary.organization.helperServices.geometry.url, authentication).then((extent) => {
|
|
1741
|
+
if (_extentIsValid(extent)) {
|
|
1742
|
+
templateDictionary[itemId].solutionExtent = extent;
|
|
1743
|
+
(0, featureServiceHelpers_1.setDefaultSpatialReference)(templateDictionary, itemId, extent.spatialReference);
|
|
1744
|
+
}
|
|
1745
|
+
else {
|
|
1746
|
+
// The org's default extent could not be projected into the service's spatial
|
|
1747
|
+
// reference, so remove the templatized extent properties from the service and
|
|
1748
|
+
// its layers and tables
|
|
1749
|
+
(0, generalHelpers_1.deleteProp)(createOptions.item, "initialExtent");
|
|
1750
|
+
(0, generalHelpers_1.deleteProp)(createOptions.item, "fullExtent");
|
|
1751
|
+
_removeLayerExtents(newItemTemplate);
|
|
1752
|
+
(0, featureServiceHelpers_1.setDefaultSpatialReference)(templateDictionary, itemId, serviceInfo.service.spatialReference);
|
|
1753
|
+
}
|
|
1702
1754
|
createOptions.item = (0, templatization_1.replaceInTemplate)(createOptions.item, templateDictionary);
|
|
1703
1755
|
createOptions.params = (0, templatization_1.replaceInTemplate)(createOptions.params, templateDictionary);
|
|
1756
|
+
createOptions.item.name = sanitizeFeatureServiceName(createOptions.item.name);
|
|
1704
1757
|
if (newItemTemplate.item.thumbnail) {
|
|
1705
1758
|
// Pass thumbnail file in via params because item property is serialized, which discards a blob
|
|
1706
1759
|
createOptions.params.thumbnail = newItemTemplate.item.thumbnail;
|
|
@@ -1710,29 +1763,6 @@ function _getCreateServiceOptions(newItemTemplate, authentication, templateDicti
|
|
|
1710
1763
|
});
|
|
1711
1764
|
}
|
|
1712
1765
|
exports._getCreateServiceOptions = _getCreateServiceOptions;
|
|
1713
|
-
/**
|
|
1714
|
-
* When the services spatial reference does not match that of it's default extent
|
|
1715
|
-
* use the out SRs default extent if it exists in the templateDictionary
|
|
1716
|
-
* this should be set when adding a custom out wkid to the params before calling deploy
|
|
1717
|
-
* this will help avoid situations where the orgs default extent and default world extent
|
|
1718
|
-
* will not project successfully to the out SR
|
|
1719
|
-
*
|
|
1720
|
-
* @param serviceInfo the object that contains the spatial reference to evaluate
|
|
1721
|
-
* @param templateDictionary the template dictionary
|
|
1722
|
-
* @returns the extent to use as the fallback
|
|
1723
|
-
* @private
|
|
1724
|
-
*/
|
|
1725
|
-
function _getFallbackExtent(serviceInfo, templateDictionary) {
|
|
1726
|
-
const serviceSR = serviceInfo.service.spatialReference;
|
|
1727
|
-
const serviceInfoWkid = (0, generalHelpers_1.getProp)(serviceInfo, "defaultExtent.spatialReference.wkid");
|
|
1728
|
-
const customDefaultExtent = (0, generalHelpers_1.getProp)(templateDictionary, "params.defaultExtent");
|
|
1729
|
-
return serviceInfoWkid && serviceInfoWkid === serviceSR.wkid
|
|
1730
|
-
? serviceInfo.defaultExtent
|
|
1731
|
-
: customDefaultExtent
|
|
1732
|
-
? customDefaultExtent
|
|
1733
|
-
: serviceInfo.defaultExtent;
|
|
1734
|
-
}
|
|
1735
|
-
exports._getFallbackExtent = _getFallbackExtent;
|
|
1736
1766
|
/**
|
|
1737
1767
|
* Add relationships to all layers in one call to retain fully functioning composite relationships
|
|
1738
1768
|
*
|
|
@@ -19,9 +19,12 @@
|
|
|
19
19
|
import { IFolderIdOptions, IGetGroupContentOptions, IGetUserOptions, IGroup, IGroupContentResult, IGetRelatedItemsResponse, IGroupSharingOptions, IItem, IItemRelationshipOptions, IItemResourceOptions, IItemResourceResponse, IPortal, IRemoveItemResourceOptions, ISearchOptions, ISearchResult, ISharingResponse, IUpdateGroupOptions, IUpdateItemOptions, IUpdateItemResponse, IUser, IUserGroupOptions, IUserItemOptions, SearchQueryBuilder } from "@esri/arcgis-rest-portal";
|
|
20
20
|
import { IRequestOptions } from "@esri/arcgis-rest-request";
|
|
21
21
|
import { IAddToServiceDefinitionOptions, IAddToServiceDefinitionResult, IQueryRelatedOptions, IQueryRelatedResponse } from "@esri/arcgis-rest-feature-service";
|
|
22
|
-
export {
|
|
23
|
-
export {
|
|
24
|
-
export {
|
|
22
|
+
export { createFeatureService as svcAdminCreateFeatureService, queryFeatures, addFeatures, applyEdits, } from "@esri/arcgis-rest-feature-service";
|
|
23
|
+
export type { IAddToServiceDefinitionOptions, IAddToServiceDefinitionResult, ICreateServiceParams, ICreateServiceResult, IExtent, ISpatialReference, IFeature, IQueryRelatedOptions, IQueryRelatedResponse, IRelatedRecordGroup, } from "@esri/arcgis-rest-feature-service";
|
|
24
|
+
export { addItemData as restAddItemData, addItemRelationship, createFolder, createGroup, createItem, createItemInFolder, moveItem, protectItem, SearchQueryBuilder, getGroupCategorySchema as restGetGroupCategorySchema, getItem, getItemData, getItemResources as restGetItemResources, getUserContent, getPortal as restGetPortal, getPortalUrl, searchGroupContent, setItemAccess, searchGroups as restSearchGroups, removeGroupUsers, removeItem as restRemoveItem, } from "@esri/arcgis-rest-portal";
|
|
25
|
+
export type { IAddFolderResponse, IAddItemDataOptions, ICreateItemOptions, ICreateItemResponse, IFolder, IFolderIdOptions, IGetGroupContentOptions, IGetRelatedItemsResponse, IGroup, IGroupAdd, IGroupCategorySchema as restIGroupCategorySchema, IItem, IItemRelationshipOptions, IItemResourceOptions, IItemResourceResponse, IManageItemRelationshipOptions, IMoveItemOptions, IMoveItemResponse, IPagedResponse, IPagingParams, IPortal, IRemoveItemResourceOptions, ISearchGroupContentOptions, ISearchOptions, ISearchResult, ISetAccessOptions, ISharingResponse, ItemRelationshipType, IUpdateGroupOptions, IUpdateItemOptions, IUpdateItemResponse, IUser, IUserContentResponse, IUserGroupOptions, IGroupSharingOptions, IUserItemOptions, } from "@esri/arcgis-rest-portal";
|
|
26
|
+
export { ArcGISAuthError, encodeFormData, ArcGISIdentityManager as UserSession } from "@esri/arcgis-rest-request";
|
|
27
|
+
export type { IArcGISIdentityManagerOptions, ICredential, IRequestOptions, IParams } from "@esri/arcgis-rest-request";
|
|
25
28
|
export interface IFolderSuccessResult {
|
|
26
29
|
success: boolean;
|
|
27
30
|
folder: {
|
package/dist/esm/arcgisRestJS.js
CHANGED
|
@@ -21,7 +21,7 @@ import { request as restRequest } from "@esri/arcgis-rest-request";
|
|
|
21
21
|
import { addToServiceDefinition, queryRelated as restQueryRelated, } from "@esri/arcgis-rest-feature-service";
|
|
22
22
|
export { createFeatureService as svcAdminCreateFeatureService, queryFeatures, addFeatures, applyEdits, } from "@esri/arcgis-rest-feature-service";
|
|
23
23
|
export { addItemData as restAddItemData, addItemRelationship, createFolder, createGroup, createItem, createItemInFolder, moveItem, protectItem, SearchQueryBuilder, getGroupCategorySchema as restGetGroupCategorySchema, getItem, getItemData, getItemResources as restGetItemResources, getUserContent, getPortal as restGetPortal, getPortalUrl, searchGroupContent, setItemAccess, searchGroups as restSearchGroups, removeGroupUsers, removeItem as restRemoveItem, } from "@esri/arcgis-rest-portal";
|
|
24
|
-
export { ArcGISAuthError, encodeFormData, ArcGISIdentityManager as UserSession
|
|
24
|
+
export { ArcGISAuthError, encodeFormData, ArcGISIdentityManager as UserSession } from "@esri/arcgis-rest-request";
|
|
25
25
|
//custom export functions that mimic the same export function from arcgis-rest-js
|
|
26
26
|
//to bypass unit test error:
|
|
27
27
|
//Error: <spyOn> : <functon or property> is not declared writable or has no setter
|
|
@@ -164,9 +164,12 @@ export declare function getLayerSettings(layerInfos: any, url: string, itemId: s
|
|
|
164
164
|
* The feature service name will have a generated GUID appended.
|
|
165
165
|
*
|
|
166
166
|
* @param templates A collection of AGO item templates.
|
|
167
|
+
* @param templateDictionary Optional hash of values used to resolve `{{...}}` tokens in the name
|
|
168
|
+
* before applying the 50-char base-name limit. When omitted, names containing unresolved tokens
|
|
169
|
+
* are passed through untruncated (legacy behavior).
|
|
167
170
|
* @returns An updated collection of AGO templates with unique feature service names.
|
|
168
171
|
*/
|
|
169
|
-
export declare function setNamesAndTitles(templates: IItemTemplate[]): IItemTemplate[];
|
|
172
|
+
export declare function setNamesAndTitles(templates: IItemTemplate[], templateDictionary?: any): IItemTemplate[];
|
|
170
173
|
/**
|
|
171
174
|
* This is used when deploying views.
|
|
172
175
|
* We need to update fields referenced in adminLayerInfo for relationships prior to deploying the view.
|
|
@@ -243,6 +246,28 @@ export declare function getExistingLayersAndTables(url: string, ids: number[], a
|
|
|
243
246
|
* @private
|
|
244
247
|
*/
|
|
245
248
|
export declare function addFeatureServiceLayersAndTables(itemTemplate: IItemTemplate, templateDictionary: any, popupInfos: IPopupInfos, authentication: UserSession): Promise<void>;
|
|
249
|
+
/**
|
|
250
|
+
* Shorten any layer or table name longer than `maxNameLength` to a unique value of at most
|
|
251
|
+
* `maxNameLength` characters, in preparation for an addToDefinition call, and report the original
|
|
252
|
+
* names so they can be restored afterward.
|
|
253
|
+
*
|
|
254
|
+
* Mutates the `name` of each over-long layer/table in `layerChunks` in place.
|
|
255
|
+
*
|
|
256
|
+
* @param layerChunks The addToDefinition chunks whose `layers` and `tables` will be added
|
|
257
|
+
* @param maxNameLength Names longer than this are truncated to a unique value of this length
|
|
258
|
+
* @returns The original names to restore, as `{ layers: [{ id, name }], tables: [{ id, name }] }`
|
|
259
|
+
* @private
|
|
260
|
+
*/
|
|
261
|
+
export declare function _truncateNamesForAddToDefinition(layerChunks: any[], maxNameLength: number): {
|
|
262
|
+
layers: Array<{
|
|
263
|
+
id: any;
|
|
264
|
+
name: string;
|
|
265
|
+
}>;
|
|
266
|
+
tables: Array<{
|
|
267
|
+
id: any;
|
|
268
|
+
name: string;
|
|
269
|
+
}>;
|
|
270
|
+
};
|
|
246
271
|
/**
|
|
247
272
|
* Updates a feature service with a list of layers and/or tables.
|
|
248
273
|
*
|
|
@@ -151,9 +151,11 @@ export function deleteViewProps(layer, isPortal) {
|
|
|
151
151
|
*/
|
|
152
152
|
export function cacheFieldInfos(layer, fieldInfos, isView, isPortal) {
|
|
153
153
|
// cache the source fields as they are in the original source
|
|
154
|
-
|
|
154
|
+
// Note: layer.id is commonly 0 for the first layer, so use a presence check
|
|
155
|
+
// (not a truthy check) to avoid skipping the layer with id === 0.
|
|
156
|
+
if (layer && layer.id !== undefined && layer.id !== null) {
|
|
155
157
|
fieldInfos[layer.id] = {
|
|
156
|
-
sourceFields: JSON.parse(JSON.stringify(layer.fields)),
|
|
158
|
+
sourceFields: layer.fields ? JSON.parse(JSON.stringify(layer.fields)) : [],
|
|
157
159
|
type: layer.type,
|
|
158
160
|
id: layer.id,
|
|
159
161
|
};
|
|
@@ -425,9 +427,12 @@ export function getLayerSettings(layerInfos, url, itemId, enterpriseIDMapping) {
|
|
|
425
427
|
* The feature service name will have a generated GUID appended.
|
|
426
428
|
*
|
|
427
429
|
* @param templates A collection of AGO item templates.
|
|
430
|
+
* @param templateDictionary Optional hash of values used to resolve `{{...}}` tokens in the name
|
|
431
|
+
* before applying the 50-char base-name limit. When omitted, names containing unresolved tokens
|
|
432
|
+
* are passed through untruncated (legacy behavior).
|
|
428
433
|
* @returns An updated collection of AGO templates with unique feature service names.
|
|
429
434
|
*/
|
|
430
|
-
export function setNamesAndTitles(templates) {
|
|
435
|
+
export function setNamesAndTitles(templates, templateDictionary) {
|
|
431
436
|
const guid = generateGUID();
|
|
432
437
|
const names = [];
|
|
433
438
|
return templates.map((t) => {
|
|
@@ -441,9 +446,20 @@ export function setNamesAndTitles(templates) {
|
|
|
441
446
|
let baseName = t.item.name || t.item.title;
|
|
442
447
|
// If the name already contains a GUID remove it
|
|
443
448
|
baseName = baseName.replace(/_[0-9A-F]{32}/gi, "");
|
|
444
|
-
//
|
|
445
|
-
//
|
|
446
|
-
const
|
|
449
|
+
// Resolve any {{...}} tokens (e.g. {{params.buildSolution.items.<id>.title}}) so the
|
|
450
|
+
// base-name length limit reflects the value AGOL will actually see at create time.
|
|
451
|
+
const resolvedBaseName = templateDictionary
|
|
452
|
+
? replaceInTemplate(baseName, templateDictionary)
|
|
453
|
+
: baseName;
|
|
454
|
+
// Limit the base name to 50 chars so the full service name (base + "_" + 32-char guid)
|
|
455
|
+
// stays within AGOL's service-name length limit. This 50-char cap is long-standing
|
|
456
|
+
// behavior. If unresolved {{...}} tokens remain we can't know the resolved length, so
|
|
457
|
+
// leave the name untruncated.
|
|
458
|
+
const maxBaseNameLength = 50;
|
|
459
|
+
const stillTemplatized = resolvedBaseName.includes("{{");
|
|
460
|
+
const name = stillTemplatized
|
|
461
|
+
? resolvedBaseName + "_" + guid
|
|
462
|
+
: resolvedBaseName.substring(0, maxBaseNameLength) + "_" + guid;
|
|
447
463
|
// If the name + GUID already exists then append "_occurrenceCount"
|
|
448
464
|
t.item.name = names.indexOf(name) === -1 ? name : `${name}_${names.filter((n) => n === name).length}`;
|
|
449
465
|
names.push(name);
|
|
@@ -716,6 +732,52 @@ export function addFeatureServiceLayersAndTables(itemTemplate, templateDictionar
|
|
|
716
732
|
}
|
|
717
733
|
});
|
|
718
734
|
}
|
|
735
|
+
/**
|
|
736
|
+
* Shorten any layer or table name longer than `maxNameLength` to a unique value of at most
|
|
737
|
+
* `maxNameLength` characters, in preparation for an addToDefinition call, and report the original
|
|
738
|
+
* names so they can be restored afterward.
|
|
739
|
+
*
|
|
740
|
+
* Mutates the `name` of each over-long layer/table in `layerChunks` in place.
|
|
741
|
+
*
|
|
742
|
+
* @param layerChunks The addToDefinition chunks whose `layers` and `tables` will be added
|
|
743
|
+
* @param maxNameLength Names longer than this are truncated to a unique value of this length
|
|
744
|
+
* @returns The original names to restore, as `{ layers: [{ id, name }], tables: [{ id, name }] }`
|
|
745
|
+
* @private
|
|
746
|
+
*/
|
|
747
|
+
export function _truncateNamesForAddToDefinition(layerChunks, maxNameLength) {
|
|
748
|
+
const restore = {
|
|
749
|
+
layers: [],
|
|
750
|
+
tables: [],
|
|
751
|
+
};
|
|
752
|
+
const allItems = [];
|
|
753
|
+
layerChunks.forEach((chunk) => {
|
|
754
|
+
chunk.layers.forEach((layer) => allItems.push({ item: layer, isLayer: true }));
|
|
755
|
+
chunk.tables.forEach((table) => allItems.push({ item: table, isLayer: false }));
|
|
756
|
+
});
|
|
757
|
+
// Reserve names that are already short enough so the truncated names won't collide with them.
|
|
758
|
+
const usedNames = new Set();
|
|
759
|
+
allItems.forEach(({ item }) => {
|
|
760
|
+
if (item.name.length <= maxNameLength) {
|
|
761
|
+
usedNames.add(item.name.toLowerCase());
|
|
762
|
+
}
|
|
763
|
+
});
|
|
764
|
+
allItems.forEach(({ item, isLayer }) => {
|
|
765
|
+
if (item.name.length > maxNameLength) {
|
|
766
|
+
const originalName = item.name;
|
|
767
|
+
let candidate = originalName.substring(0, maxNameLength);
|
|
768
|
+
let counter = 1;
|
|
769
|
+
// Keep the truncated name unique by trimming room for a numeric suffix when needed.
|
|
770
|
+
while (usedNames.has(candidate.toLowerCase())) {
|
|
771
|
+
const suffix = `_${counter++}`;
|
|
772
|
+
candidate = originalName.substring(0, maxNameLength - suffix.length) + suffix;
|
|
773
|
+
}
|
|
774
|
+
usedNames.add(candidate.toLowerCase());
|
|
775
|
+
item.name = candidate;
|
|
776
|
+
(isLayer ? restore.layers : restore.tables).push({ id: item.id, name: originalName });
|
|
777
|
+
}
|
|
778
|
+
});
|
|
779
|
+
return restore;
|
|
780
|
+
}
|
|
719
781
|
/**
|
|
720
782
|
* Updates a feature service with a list of layers and/or tables.
|
|
721
783
|
*
|
|
@@ -800,7 +862,12 @@ export function addFeatureServiceDefinition(serviceUrl, listToAdd, templateDicti
|
|
|
800
862
|
removeLayerOptimization(item);
|
|
801
863
|
// this can still chunk layers
|
|
802
864
|
options = _updateAddOptions(itemTemplate, options, layerChunks, isSelfReferential, authentication);
|
|
803
|
-
|
|
865
|
+
// Route based on the discriminator set by getLayersAndTables (which derives from
|
|
866
|
+
// properties.layers vs properties.tables) rather than the layer object's own `type`
|
|
867
|
+
// field. The latter may be missing when users supply custom layer JSON via
|
|
868
|
+
// params (e.g. {{params.buildSolution.items.<id>.service.layers}}), which would
|
|
869
|
+
// otherwise cause every layer to be pushed into the `tables` array.
|
|
870
|
+
if (toAdd.type === "layer" || item.type === "Feature Layer") {
|
|
804
871
|
options.layers.push(item);
|
|
805
872
|
}
|
|
806
873
|
else {
|
|
@@ -823,9 +890,30 @@ export function addFeatureServiceDefinition(serviceUrl, listToAdd, templateDicti
|
|
|
823
890
|
// will use async by default rather than chunk the layer requests when we have more layers
|
|
824
891
|
// than the defined chunk size
|
|
825
892
|
const useAsync = listToAdd.length > chunkSize;
|
|
893
|
+
// Shorten any over-long layer/table names to short, unique values before adding them.
|
|
894
|
+
// Names will be restored afterward with one updateDefinition call per layer/table.
|
|
895
|
+
const maxBackingTableNameLength = 30;
|
|
896
|
+
const restoreNames = _truncateNamesForAddToDefinition(layerChunks, maxBackingTableNameLength);
|
|
897
|
+
// Base admin URL used for the per-layer updateDefinition restore calls below.
|
|
898
|
+
const adminServiceUrl = checkUrlPathTermination(serviceUrl.replace("/rest/services", "/rest/admin/services"));
|
|
826
899
|
layerChunks
|
|
827
900
|
.reduce((prev, curr) => prev.then(() => addToServiceDefinition(serviceUrl, curr, false, useAsync)), Promise.resolve(null))
|
|
828
|
-
.then(() =>
|
|
901
|
+
.then(() => {
|
|
902
|
+
// Restore the original (pre-truncation) display names.
|
|
903
|
+
// I was seeing the updateDefinition call succeed but the names not being restored when I was doing this
|
|
904
|
+
// with a single call at the service endpoint. So now we are doing this sequentially.
|
|
905
|
+
const restoreItems = [...restoreNames.layers, ...restoreNames.tables];
|
|
906
|
+
restoreItems
|
|
907
|
+
.reduce((prev, entry) => prev.then(() => {
|
|
908
|
+
const restoreUpdate = {
|
|
909
|
+
url: adminServiceUrl + entry.id + "/updateDefinition",
|
|
910
|
+
params: { updateDefinition: { name: entry.name } },
|
|
911
|
+
args: { authentication },
|
|
912
|
+
};
|
|
913
|
+
return getRequest(restoreUpdate, false, false, templateDictionary.isPortal);
|
|
914
|
+
}), Promise.resolve(null))
|
|
915
|
+
.then(() => resolve(null), (e) => reject(fail(e)));
|
|
916
|
+
}, (e) => reject(fail(e)));
|
|
829
917
|
}
|
|
830
918
|
});
|
|
831
919
|
}
|
|
@@ -90,6 +90,28 @@ export declare function convertToISearchOptions(search: string | ISearchOptions
|
|
|
90
90
|
* @private
|
|
91
91
|
*/
|
|
92
92
|
export declare function _validateExtent(extent: IExtent): IExtent;
|
|
93
|
+
/**
|
|
94
|
+
* The geometry service can resolve a projection request successfully but still
|
|
95
|
+
* return "NaN" coordinate values or no geometry at all. This check is used to
|
|
96
|
+
* decide whether a projected extent can be used for a service's initial and full
|
|
97
|
+
* extents.
|
|
98
|
+
*
|
|
99
|
+
* @param extent the extent to test
|
|
100
|
+
* @returns true if the extent has numeric xmin, ymin, xmax, and ymax values
|
|
101
|
+
* @private
|
|
102
|
+
*/
|
|
103
|
+
export declare function _extentIsValid(extent: any): boolean;
|
|
104
|
+
/**
|
|
105
|
+
* Removes the templatized extent from a template's layers and tables.
|
|
106
|
+
*
|
|
107
|
+
* Used when the organization's default extent cannot be projected into the
|
|
108
|
+
* service's spatial reference so that the layers and tables are created without an
|
|
109
|
+
* extent rather than with an unresolved template variable.
|
|
110
|
+
*
|
|
111
|
+
* @param itemTemplate the template whose layer and table extents should be removed
|
|
112
|
+
* @private
|
|
113
|
+
*/
|
|
114
|
+
export declare function _removeLayerExtents(itemTemplate: IItemTemplate): void;
|
|
93
115
|
/**
|
|
94
116
|
* If the request to convert the extent fails it has commonly been due to an invalid extent.
|
|
95
117
|
* This function will first attempt to use the provided extent. If it fails it will default to
|
|
@@ -107,7 +129,6 @@ export declare function _validateExtent(extent: IExtent): IExtent;
|
|
|
107
129
|
export declare function convertExtentWithFallback(extent: IExtent, fallbackExtent: any, outSR: ISpatialReference, geometryServiceUrl: string, authentication: UserSession): Promise<any>;
|
|
108
130
|
/**
|
|
109
131
|
* Converts an extent to a specified spatial reference.
|
|
110
|
-
*
|
|
111
132
|
* @param extent Extent object to check and (possibly) to project
|
|
112
133
|
* @param outSR Desired spatial reference
|
|
113
134
|
* @param geometryServiceUrl Path to geometry service providing `findTransformations` and `project` services
|
|
@@ -528,6 +549,15 @@ export declare function _addItemMetadataFile(itemId: string, metadataFile: File,
|
|
|
528
549
|
* @private
|
|
529
550
|
*/
|
|
530
551
|
export declare function _countRelationships(layers: any[]): number;
|
|
552
|
+
/**
|
|
553
|
+
* Remove spaces and replace other characters that are not allowed in a feature service name with "_".
|
|
554
|
+
* Spaces are removed entirely. Disallowed (replaced with "_"): '#', '%', '&', '"', '\', '/', '+', '?', ':', '*',
|
|
555
|
+
* '<', '>', '\t', '!', '@', "'", ';', ','
|
|
556
|
+
*
|
|
557
|
+
* @param name The candidate service name
|
|
558
|
+
* @returns The sanitized name, or the input unchanged if it is not a string
|
|
559
|
+
*/
|
|
560
|
+
export declare function sanitizeFeatureServiceName(name: string): string;
|
|
531
561
|
/**
|
|
532
562
|
* Gets the full definitions of the layers affiliated with a hosted service.
|
|
533
563
|
*
|
|
@@ -538,19 +568,6 @@ export declare function _countRelationships(layers: any[]): number;
|
|
|
538
568
|
* @private
|
|
539
569
|
*/
|
|
540
570
|
export declare function _getCreateServiceOptions(newItemTemplate: IItemTemplate, authentication: UserSession, templateDictionary: any): Promise<any>;
|
|
541
|
-
/**
|
|
542
|
-
* When the services spatial reference does not match that of it's default extent
|
|
543
|
-
* use the out SRs default extent if it exists in the templateDictionary
|
|
544
|
-
* this should be set when adding a custom out wkid to the params before calling deploy
|
|
545
|
-
* this will help avoid situations where the orgs default extent and default world extent
|
|
546
|
-
* will not project successfully to the out SR
|
|
547
|
-
*
|
|
548
|
-
* @param serviceInfo the object that contains the spatial reference to evaluate
|
|
549
|
-
* @param templateDictionary the template dictionary
|
|
550
|
-
* @returns the extent to use as the fallback
|
|
551
|
-
* @private
|
|
552
|
-
*/
|
|
553
|
-
export declare function _getFallbackExtent(serviceInfo: any, templateDictionary: any): any;
|
|
554
571
|
/**
|
|
555
572
|
* Add relationships to all layers in one call to retain fully functioning composite relationships
|
|
556
573
|
*
|
package/dist/esm/restHelpers.js
CHANGED
|
@@ -248,6 +248,36 @@ export function _validateExtent(extent) {
|
|
|
248
248
|
}
|
|
249
249
|
return extent;
|
|
250
250
|
}
|
|
251
|
+
/**
|
|
252
|
+
* The geometry service can resolve a projection request successfully but still
|
|
253
|
+
* return "NaN" coordinate values or no geometry at all. This check is used to
|
|
254
|
+
* decide whether a projected extent can be used for a service's initial and full
|
|
255
|
+
* extents.
|
|
256
|
+
*
|
|
257
|
+
* @param extent the extent to test
|
|
258
|
+
* @returns true if the extent has numeric xmin, ymin, xmax, and ymax values
|
|
259
|
+
* @private
|
|
260
|
+
*/
|
|
261
|
+
export function _extentIsValid(extent) {
|
|
262
|
+
return (!!extent &&
|
|
263
|
+
[extent.xmin, extent.ymin, extent.xmax, extent.ymax].every((coordinate) => typeof coordinate === "number" && !isNaN(coordinate)));
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Removes the templatized extent from a template's layers and tables.
|
|
267
|
+
*
|
|
268
|
+
* Used when the organization's default extent cannot be projected into the
|
|
269
|
+
* service's spatial reference so that the layers and tables are created without an
|
|
270
|
+
* extent rather than with an unresolved template variable.
|
|
271
|
+
*
|
|
272
|
+
* @param itemTemplate the template whose layer and table extents should be removed
|
|
273
|
+
* @private
|
|
274
|
+
*/
|
|
275
|
+
export function _removeLayerExtents(itemTemplate) {
|
|
276
|
+
["properties.layers", "properties.tables"].forEach((path) => {
|
|
277
|
+
const items = getProp(itemTemplate, path) || [];
|
|
278
|
+
items.forEach((item) => deleteProp(item, "extent"));
|
|
279
|
+
});
|
|
280
|
+
}
|
|
251
281
|
/**
|
|
252
282
|
* If the request to convert the extent fails it has commonly been due to an invalid extent.
|
|
253
283
|
* This function will first attempt to use the provided extent. If it fails it will default to
|
|
@@ -291,7 +321,6 @@ export function convertExtentWithFallback(extent, fallbackExtent, outSR, geometr
|
|
|
291
321
|
}
|
|
292
322
|
/**
|
|
293
323
|
* Converts an extent to a specified spatial reference.
|
|
294
|
-
*
|
|
295
324
|
* @param extent Extent object to check and (possibly) to project
|
|
296
325
|
* @param outSR Desired spatial reference
|
|
297
326
|
* @param geometryServiceUrl Path to geometry service providing `findTransformations` and `project` services
|
|
@@ -1606,6 +1635,17 @@ export function _countRelationships(layers) {
|
|
|
1606
1635
|
const reducer = (accumulator, currentLayer) => accumulator + (currentLayer.relationships ? currentLayer.relationships.length : 0);
|
|
1607
1636
|
return layers.reduce(reducer, 0);
|
|
1608
1637
|
}
|
|
1638
|
+
/**
|
|
1639
|
+
* Remove spaces and replace other characters that are not allowed in a feature service name with "_".
|
|
1640
|
+
* Spaces are removed entirely. Disallowed (replaced with "_"): '#', '%', '&', '"', '\', '/', '+', '?', ':', '*',
|
|
1641
|
+
* '<', '>', '\t', '!', '@', "'", ';', ','
|
|
1642
|
+
*
|
|
1643
|
+
* @param name The candidate service name
|
|
1644
|
+
* @returns The sanitized name, or the input unchanged if it is not a string
|
|
1645
|
+
*/
|
|
1646
|
+
export function sanitizeFeatureServiceName(name) {
|
|
1647
|
+
return typeof name === "string" ? name.replace(/ /g, "").replace(/[#%&"\\/+?:*<>\t!@';,]/g, "_") : name;
|
|
1648
|
+
}
|
|
1609
1649
|
/**
|
|
1610
1650
|
* Gets the full definitions of the layers affiliated with a hosted service.
|
|
1611
1651
|
*
|
|
@@ -1622,7 +1662,6 @@ export function _getCreateServiceOptions(newItemTemplate, authentication, templa
|
|
|
1622
1662
|
const isPortal = templateDictionary.isPortal;
|
|
1623
1663
|
const itemId = newItemTemplate.itemId;
|
|
1624
1664
|
validateSpatialReferenceAndExtent(serviceInfo, newItemTemplate, templateDictionary);
|
|
1625
|
-
const fallbackExtent = _getFallbackExtent(serviceInfo, templateDictionary);
|
|
1626
1665
|
const params = {};
|
|
1627
1666
|
const itemInfo = {
|
|
1628
1667
|
title: newItemTemplate.item.title,
|
|
@@ -1641,12 +1680,23 @@ export function _getCreateServiceOptions(newItemTemplate, authentication, templa
|
|
|
1641
1680
|
createOptions.item = !isTrackingViewTemplate(newItemTemplate)
|
|
1642
1681
|
? _setItemProperties(createOptions.item, newItemTemplate, serviceInfo, params, isPortal)
|
|
1643
1682
|
: setTrackingOptions(newItemTemplate, createOptions, templateDictionary);
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1683
|
+
convertExtent(_validateExtent(templateDictionary.organization.defaultExtent), serviceInfo.service.spatialReference, templateDictionary.organization.helperServices.geometry.url, authentication).then((extent) => {
|
|
1684
|
+
if (_extentIsValid(extent)) {
|
|
1685
|
+
templateDictionary[itemId].solutionExtent = extent;
|
|
1686
|
+
setDefaultSpatialReference(templateDictionary, itemId, extent.spatialReference);
|
|
1687
|
+
}
|
|
1688
|
+
else {
|
|
1689
|
+
// The org's default extent could not be projected into the service's spatial
|
|
1690
|
+
// reference, so remove the templatized extent properties from the service and
|
|
1691
|
+
// its layers and tables
|
|
1692
|
+
deleteProp(createOptions.item, "initialExtent");
|
|
1693
|
+
deleteProp(createOptions.item, "fullExtent");
|
|
1694
|
+
_removeLayerExtents(newItemTemplate);
|
|
1695
|
+
setDefaultSpatialReference(templateDictionary, itemId, serviceInfo.service.spatialReference);
|
|
1696
|
+
}
|
|
1648
1697
|
createOptions.item = replaceInTemplate(createOptions.item, templateDictionary);
|
|
1649
1698
|
createOptions.params = replaceInTemplate(createOptions.params, templateDictionary);
|
|
1699
|
+
createOptions.item.name = sanitizeFeatureServiceName(createOptions.item.name);
|
|
1650
1700
|
if (newItemTemplate.item.thumbnail) {
|
|
1651
1701
|
// Pass thumbnail file in via params because item property is serialized, which discards a blob
|
|
1652
1702
|
createOptions.params.thumbnail = newItemTemplate.item.thumbnail;
|
|
@@ -1655,28 +1705,6 @@ export function _getCreateServiceOptions(newItemTemplate, authentication, templa
|
|
|
1655
1705
|
}, (e) => reject(fail(e)));
|
|
1656
1706
|
});
|
|
1657
1707
|
}
|
|
1658
|
-
/**
|
|
1659
|
-
* When the services spatial reference does not match that of it's default extent
|
|
1660
|
-
* use the out SRs default extent if it exists in the templateDictionary
|
|
1661
|
-
* this should be set when adding a custom out wkid to the params before calling deploy
|
|
1662
|
-
* this will help avoid situations where the orgs default extent and default world extent
|
|
1663
|
-
* will not project successfully to the out SR
|
|
1664
|
-
*
|
|
1665
|
-
* @param serviceInfo the object that contains the spatial reference to evaluate
|
|
1666
|
-
* @param templateDictionary the template dictionary
|
|
1667
|
-
* @returns the extent to use as the fallback
|
|
1668
|
-
* @private
|
|
1669
|
-
*/
|
|
1670
|
-
export function _getFallbackExtent(serviceInfo, templateDictionary) {
|
|
1671
|
-
const serviceSR = serviceInfo.service.spatialReference;
|
|
1672
|
-
const serviceInfoWkid = getProp(serviceInfo, "defaultExtent.spatialReference.wkid");
|
|
1673
|
-
const customDefaultExtent = getProp(templateDictionary, "params.defaultExtent");
|
|
1674
|
-
return serviceInfoWkid && serviceInfoWkid === serviceSR.wkid
|
|
1675
|
-
? serviceInfo.defaultExtent
|
|
1676
|
-
: customDefaultExtent
|
|
1677
|
-
? customDefaultExtent
|
|
1678
|
-
: serviceInfo.defaultExtent;
|
|
1679
|
-
}
|
|
1680
1708
|
/**
|
|
1681
1709
|
* Add relationships to all layers in one call to retain fully functioning composite relationships
|
|
1682
1710
|
*
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
Built
|
|
1
|
+
Built 06/25/2026 20:42:59.94
|
|
2
2
|
develop
|
|
3
|
-
commit
|
|
4
|
-
Merge:
|
|
3
|
+
commit 8bce353fe3c3c3286c3d17f2c47ad0608160e78a
|
|
4
|
+
Merge: 0713c37c5 bdf44674f
|
|
5
5
|
Author: Previn Wong <pwong@esri.com>
|
|
6
|
-
Date:
|
|
6
|
+
Date: Thu Jun 25 16:16:57 2026 -0700
|
|
7
7
|
|
|
8
|
-
Merge pull request #
|
|
8
|
+
Merge pull request #1591 from Esri/long-name-issue
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
Long name issue
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@esri/solution-common",
|
|
3
|
-
"version": "6.6.1-next.
|
|
3
|
+
"version": "6.6.1-next.81",
|
|
4
4
|
"description": "Provides general helper functions for @esri/solution.js.",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -96,5 +96,5 @@
|
|
|
96
96
|
"esri",
|
|
97
97
|
"ES6"
|
|
98
98
|
],
|
|
99
|
-
"gitHead": "
|
|
99
|
+
"gitHead": "8bce353fe3c3c3286c3d17f2c47ad0608160e78a"
|
|
100
100
|
}
|