@esri/solution-common 6.6.1-next.7 → 6.6.1-next.71

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.
@@ -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 { IAddToServiceDefinitionOptions, IAddToServiceDefinitionResult, ICreateServiceParams, ICreateServiceResult, IExtent, ISpatialReference, IFeature, IQueryRelatedOptions, IQueryRelatedResponse, IRelatedRecordGroup, createFeatureService as svcAdminCreateFeatureService, queryFeatures, addFeatures, applyEdits, } from "@esri/arcgis-rest-feature-service";
23
- export { 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, 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 { IArcGISIdentityManagerOptions, ICredential, IRequestOptions, IParams, ArcGISAuthError, encodeFormData, ArcGISIdentityManager as UserSession, } from "@esri/arcgis-rest-request";
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: {
@@ -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
- if (layer && layer.fields) {
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
  };
@@ -461,7 +463,10 @@ function setNamesAndTitles(templates) {
461
463
  baseName = baseName.replace(/_[0-9A-F]{32}/gi, "");
462
464
  // The name length limit is 98
463
465
  // Limit the baseName to 50 characters before the _<guid>
464
- const name = baseName.substring(0, 50) + "_" + guid;
466
+ // If the baseName includes '{{params' it is likely being used in a template replacement, so do not truncate.
467
+ const name = baseName.includes("{{params")
468
+ ? baseName + "_" + guid
469
+ : baseName.substring(0, 50) + "_" + guid;
465
470
  // If the name + GUID already exists then append "_occurrenceCount"
466
471
  t.item.name = names.indexOf(name) === -1 ? name : `${name}_${names.filter((n) => n === name).length}`;
467
472
  names.push(name);
@@ -826,7 +831,12 @@ function addFeatureServiceDefinition(serviceUrl, listToAdd, templateDictionary,
826
831
  removeLayerOptimization(item);
827
832
  // this can still chunk layers
828
833
  options = _updateAddOptions(itemTemplate, options, layerChunks, isSelfReferential, authentication);
829
- if (item.type === "Feature Layer") {
834
+ // Route based on the discriminator set by getLayersAndTables (which derives from
835
+ // properties.layers vs properties.tables) rather than the layer object's own `type`
836
+ // field. The latter may be missing when users supply custom layer JSON via
837
+ // params (e.g. {{params.buildSolution.items.<id>.service.layers}}), which would
838
+ // otherwise cause every layer to be pushed into the `tables` array.
839
+ if (toAdd.type === "layer" || item.type === "Feature Layer") {
830
840
  options.layers.push(item);
831
841
  }
832
842
  else {
@@ -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
  *
@@ -15,8 +15,8 @@
15
15
  * limitations under the License.
16
16
  */
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
- exports._countRelationships = exports._addItemMetadataFile = 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._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._getFallbackExtent = exports._getCreateServiceOptions = void 0;
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
- // project the portals extent to match that of the service
1699
- convertExtentWithFallback(templateDictionary.organization.defaultExtent, fallbackExtent, serviceInfo.service.spatialReference, templateDictionary.organization.helperServices.geometry.url, authentication).then((extent) => {
1700
- templateDictionary[itemId].solutionExtent = extent;
1701
- (0, featureServiceHelpers_1.setDefaultSpatialReference)(templateDictionary, itemId, extent.spatialReference);
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 { IAddToServiceDefinitionOptions, IAddToServiceDefinitionResult, ICreateServiceParams, ICreateServiceResult, IExtent, ISpatialReference, IFeature, IQueryRelatedOptions, IQueryRelatedResponse, IRelatedRecordGroup, createFeatureService as svcAdminCreateFeatureService, queryFeatures, addFeatures, applyEdits, } from "@esri/arcgis-rest-feature-service";
23
- export { 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, 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 { IArcGISIdentityManagerOptions, ICredential, IRequestOptions, IParams, ArcGISAuthError, encodeFormData, ArcGISIdentityManager as UserSession, } from "@esri/arcgis-rest-request";
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: {
@@ -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, } from "@esri/arcgis-rest-request";
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
@@ -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
- if (layer && layer.fields) {
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
  };
@@ -443,7 +445,10 @@ export function setNamesAndTitles(templates) {
443
445
  baseName = baseName.replace(/_[0-9A-F]{32}/gi, "");
444
446
  // The name length limit is 98
445
447
  // Limit the baseName to 50 characters before the _<guid>
446
- const name = baseName.substring(0, 50) + "_" + guid;
448
+ // If the baseName includes '{{params' it is likely being used in a template replacement, so do not truncate.
449
+ const name = baseName.includes("{{params")
450
+ ? baseName + "_" + guid
451
+ : baseName.substring(0, 50) + "_" + guid;
447
452
  // If the name + GUID already exists then append "_occurrenceCount"
448
453
  t.item.name = names.indexOf(name) === -1 ? name : `${name}_${names.filter((n) => n === name).length}`;
449
454
  names.push(name);
@@ -800,7 +805,12 @@ export function addFeatureServiceDefinition(serviceUrl, listToAdd, templateDicti
800
805
  removeLayerOptimization(item);
801
806
  // this can still chunk layers
802
807
  options = _updateAddOptions(itemTemplate, options, layerChunks, isSelfReferential, authentication);
803
- if (item.type === "Feature Layer") {
808
+ // Route based on the discriminator set by getLayersAndTables (which derives from
809
+ // properties.layers vs properties.tables) rather than the layer object's own `type`
810
+ // field. The latter may be missing when users supply custom layer JSON via
811
+ // params (e.g. {{params.buildSolution.items.<id>.service.layers}}), which would
812
+ // otherwise cause every layer to be pushed into the `tables` array.
813
+ if (toAdd.type === "layer" || item.type === "Feature Layer") {
804
814
  options.layers.push(item);
805
815
  }
806
816
  else {
@@ -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
  *
@@ -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
- // project the portals extent to match that of the service
1645
- convertExtentWithFallback(templateDictionary.organization.defaultExtent, fallbackExtent, serviceInfo.service.spatialReference, templateDictionary.organization.helperServices.geometry.url, authentication).then((extent) => {
1646
- templateDictionary[itemId].solutionExtent = extent;
1647
- setDefaultSpatialReference(templateDictionary, itemId, extent.spatialReference);
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,7 +1,7 @@
1
- Built 04/14/2026 20:42:31.85
1
+ Built 06/16/2026 20:42:41.99
2
2
  develop
3
- commit c8197336df5a67bc98b25e267a42425708c4962c
3
+ commit ef78f4b09950332c63bf63e629216a2c50ac9dfa
4
4
  Author: Ryan Cosby <ryan9313@esri.com>
5
- Date: Mon Apr 13 20:49:36 2026 -0700
5
+ Date: Mon Jun 15 20:49:27 2026 -0700
6
6
 
7
- v6.6.1-next.6
7
+ v6.6.1-next.70
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@esri/solution-common",
3
- "version": "6.6.1-next.7",
3
+ "version": "6.6.1-next.71",
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": "c8197336df5a67bc98b25e267a42425708c4962c"
99
+ "gitHead": "ef78f4b09950332c63bf63e629216a2c50ac9dfa"
100
100
  }