esri-gl 1.0.5 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -6,6 +6,7 @@ A TypeScript library that bridges Esri ArcGIS REST services with MapLibre GL JS
6
6
  [![CI](https://github.com/muimsd/esri-gl/actions/workflows/ci.yml/badge.svg)](https://github.com/muimsd/esri-gl/actions/workflows/ci.yml)
7
7
  [![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-%230074c1.svg)](http://www.typescriptlang.org/)
8
8
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
9
+
9
10
  **[Documentation](https://esri-gl.pages.dev/)** · **[Live Demos](https://esri-gl-demo.pages.dev/)** · **[npm](https://www.npmjs.com/package/esri-gl)**
10
11
 
11
12
  ## Features
@@ -28,6 +29,14 @@ A TypeScript library that bridges Esri ArcGIS REST services with MapLibre GL JS
28
29
  - **react-map-gl** — Declarative `<EsriDynamicLayer>`, `<EsriFeatureLayer>`, etc.
29
30
  - **TypeScript** — Full type safety with comprehensive interfaces
30
31
 
32
+ ### Built on ArcGIS REST JS
33
+ - **Official client** — requests, authentication, and feature editing run on
34
+ [`@esri/arcgis-rest-js`](https://github.com/Esri/arcgis-rest-js)
35
+ (`-request`, `-feature-service`, `-portal`, `-basemap-sessions`)
36
+ - **Flexible auth** — `token`, `apiKey`, or any `IAuthenticationManager`
37
+ (`ApiKeyManager`, `ArcGISIdentityManager`, …) on every service and task
38
+ - **Portal item resolution** — turn a portal item id or Web Map into ready-to-render services
39
+
31
40
  ## Installation
32
41
 
33
42
  ```bash
@@ -132,6 +141,47 @@ const all = await query({ url: 'https://.../FeatureServer/0' })
132
141
  .runAll();
133
142
  ```
134
143
 
144
+ ## Authentication
145
+
146
+ Every service and task accepts `token`, `apiKey`, or an `authentication` manager
147
+ (precedence: `authentication` → `apiKey` → `token`). esri-gl uses ArcGIS REST JS's
148
+ authentication managers under the hood.
149
+
150
+ ```typescript
151
+ import { DynamicMapService, ArcGISIdentityManager, ApiKeyManager } from 'esri-gl';
152
+
153
+ // API key or static token
154
+ new DynamicMapService('source', map, { url, apiKey: 'AAPK…' });
155
+ new DynamicMapService('source', map, { url, token: 'eyJ…' });
156
+
157
+ // Named-user session with auto-refreshing token
158
+ const session = await ArcGISIdentityManager.signIn({ username, password });
159
+ new FeatureService('source', map, { url, authentication: session });
160
+ ```
161
+
162
+ See the [Authentication guide](https://esri-gl.pages.dev/docs/guides/authentication) for
163
+ the `authenticationrequired` event, the `esriRequest`/`resolveAuthentication` helpers, and
164
+ migration notes.
165
+
166
+ ## Portal Items & Web Maps
167
+
168
+ Resolve an ArcGIS portal item id — or a whole Web Map — straight to esri-gl services
169
+ (powered by `@esri/arcgis-rest-portal`):
170
+
171
+ ```typescript
172
+ import { serviceFromPortalItem, servicesFromWebMap } from 'esri-gl';
173
+
174
+ // Single item → the matching service (Feature/Map/Image/Vector Tile)
175
+ const { service, kind } = await serviceFromPortalItem('my-source', map, itemId, { apiKey });
176
+ map.addLayer({ id: 'my-layer', type: 'raster', source: 'my-source' });
177
+
178
+ // Web Map → a service per operational layer
179
+ const layers = await servicesFromWebMap(map, webMapItemId, { token });
180
+ ```
181
+
182
+ See the [Portal Items guide](https://esri-gl.pages.dev/docs/guides/portal-items) for the
183
+ item-type/layer-type mappings and options.
184
+
135
185
  ## React Integration
136
186
 
137
187
  ### Hooks
@@ -160,6 +210,7 @@ import { EsriDynamicLayer, EsriFeatureLayer } from 'esri-gl/react-map-gl';
160
210
  url="https://.../Census/MapServer"
161
211
  layers={[0, 1]}
162
212
  opacity={0.8}
213
+ token="YOUR_TOKEN"
163
214
  />
164
215
  <EsriFeatureLayer
165
216
  id="states"
@@ -169,6 +220,8 @@ import { EsriDynamicLayer, EsriFeatureLayer } from 'esri-gl/react-map-gl';
169
220
  </Map>
170
221
  ```
171
222
 
223
+ All layer components accept `token`, `apiKey`, `authentication`, `getAttributionFromService`, and `requestParams` for authenticated services and custom request behavior.
224
+
172
225
  ## Examples
173
226
 
174
227
  Working examples in [`examples/`](examples/):
@@ -188,7 +241,7 @@ cd examples/maplibre-esm && npm install && npm run dev
188
241
  ```bash
189
242
  npm run dev # Start demo dev server
190
243
  npm run build # Build library (ESM + UMD)
191
- npm run test # Run tests (727 tests, 31 suites)
244
+ npm run test # Run tests (733 tests, 31 suites)
192
245
  npm run type-check # TypeScript check
193
246
  npm run lint # ESLint
194
247
  npm run build:docs # Build documentation site
@@ -214,6 +267,7 @@ MIT — see [LICENSE](LICENSE)
214
267
 
215
268
  ## Acknowledgements
216
269
 
270
+ - **[ArcGIS REST JS](https://github.com/Esri/arcgis-rest-js)** — official client powering requests, auth, feature editing, and portal access
217
271
  - **[Esri Leaflet](https://esri.github.io/esri-leaflet/)** — API design inspiration
218
272
  - **[mapbox-gl-esri-sources](https://github.com/frontiersi/mapbox-gl-esri-sources/)** — Foundational integration patterns (this project originated as a fork)
219
273
  - **[mapbox-gl-arcgis-featureserver](https://github.com/rowanwins/mapbox-gl-arcgis-featureserver)** by Rowan Winsemius — FeatureService PBF implementation
@@ -1,4 +1,62 @@
1
+ import { IAuthenticationManager, IFeatureSet, IField, IExtent } from '@esri/arcgis-rest-request';
2
+ import * as _esri_arcgis_rest_feature_service from '@esri/arcgis-rest-feature-service';
3
+ import { IApplyEditsResult, IAttachmentInfo, IEditFeatureResult } from '@esri/arcgis-rest-feature-service';
1
4
  import { Map } from 'maplibre-gl';
5
+ import { BasemapStyleSession } from '@esri/arcgis-rest-basemap-sessions';
6
+ import { IItem, SearchQueryBuilder, ISearchOptions, ISearchResult } from '@esri/arcgis-rest-portal';
7
+
8
+ /**
9
+ * Shared request + authentication adapter built on `@esri/arcgis-rest-request`.
10
+ *
11
+ * Every network call in esri-gl that talks to an ArcGIS REST endpoint flows
12
+ * through this module so that authentication, error handling and parameter
13
+ * encoding are handled once by the official ArcGIS REST JS client instead of
14
+ * the bespoke `fetch` wrappers this library used to ship.
15
+ */
16
+
17
+ /**
18
+ * Authentication accepted throughout esri-gl. Either an ArcGIS REST JS
19
+ * authentication manager (`ApiKeyManager`, `ArcGISIdentityManager`, …) or a
20
+ * raw token/API-key string for convenience.
21
+ */
22
+ type EsriAuthentication = IAuthenticationManager | string;
23
+ /**
24
+ * Options every service/task accepts for authenticating ArcGIS REST requests.
25
+ * `authentication` takes precedence, then `apiKey`, then `token`.
26
+ */
27
+ interface EsriAuthOptions {
28
+ /** An ArcGIS REST JS authentication manager. */
29
+ authentication?: EsriAuthentication;
30
+ /** A static API key (ArcGIS Location Platform). */
31
+ apiKey?: string;
32
+ /** A static, pre-generated token. */
33
+ token?: string;
34
+ }
35
+ /**
36
+ * Normalise the various auth inputs into an `IAuthenticationManager` (or
37
+ * `undefined` for anonymous requests). A bare string is wrapped in an
38
+ * `ApiKeyManager` so it is sent as the `token` parameter, matching ArcGIS REST
39
+ * conventions.
40
+ */
41
+ declare function resolveAuthentication(options: EsriAuthOptions | undefined): IAuthenticationManager | undefined;
42
+ interface EsriRequestOptions extends EsriAuthOptions {
43
+ /** Query/body parameters. `f: 'json'` is supplied by default. */
44
+ params?: Record<string, unknown>;
45
+ /** HTTP method. ArcGIS REST JS defaults to POST; most reads use GET. */
46
+ httpMethod?: 'GET' | 'POST';
47
+ /** Return the raw `Response` instead of the parsed body (e.g. for PBF). */
48
+ rawResponse?: boolean;
49
+ /** Abort signal for cancellation/timeout support. */
50
+ signal?: AbortSignal;
51
+ /** Additional request headers. */
52
+ headers?: Record<string, string>;
53
+ }
54
+ /**
55
+ * Thin wrapper over `@esri/arcgis-rest-request`'s `request()` that applies
56
+ * esri-gl's auth resolution and sensible defaults. Throws `ArcGISRequestError`
57
+ * (and friends) on ArcGIS service-level or HTTP errors.
58
+ */
59
+ declare function esriRequest<T = unknown>(url: string, options?: EsriRequestOptions): Promise<T>;
2
60
 
3
61
  interface ServiceMetadata {
4
62
  attribution?: string;
@@ -21,6 +79,12 @@ interface EsriServiceOptions {
21
79
  transparent?: boolean;
22
80
  getAttributionFromService?: boolean;
23
81
  time?: number[] | false;
82
+ /** Static token sent as the `token` parameter. */
83
+ token?: string;
84
+ /** ArcGIS Location Platform API key. */
85
+ apiKey?: string;
86
+ /** An ArcGIS REST JS authentication manager (takes precedence over token/apiKey). */
87
+ authentication?: EsriAuthentication;
24
88
  }
25
89
  interface RasterSourceOptions {
26
90
  attribution?: string;
@@ -71,11 +135,15 @@ interface FeatureServiceOptions {
71
135
  useVectorTiles?: boolean;
72
136
  token?: string;
73
137
  apiKey?: string;
138
+ authentication?: EsriAuthentication;
74
139
  layers?: number[] | number;
75
140
  }
76
141
  interface VectorTileServiceOptions {
77
142
  url: string;
78
143
  getAttributionFromService?: boolean;
144
+ token?: string;
145
+ apiKey?: string;
146
+ authentication?: EsriAuthentication;
79
147
  }
80
148
  interface VectorBasemapStyleOptions {
81
149
  basemapEnum: string;
@@ -192,23 +260,12 @@ interface LayerLabelingInfo {
192
260
  interface StatisticResult {
193
261
  attributes: Record<string, unknown>;
194
262
  }
195
- interface FieldInfo {
196
- name: string;
197
- type: 'esriFieldTypeOID' | 'esriFieldTypeString' | 'esriFieldTypeInteger' | 'esriFieldTypeSmallInteger' | 'esriFieldTypeDouble' | 'esriFieldTypeSingle' | 'esriFieldTypeDate' | 'esriFieldTypeGeometry' | 'esriFieldTypeBlob' | 'esriFieldTypeRaster' | 'esriFieldTypeGUID' | 'esriFieldTypeGlobalID' | 'esriFieldTypeXML';
198
- alias?: string;
263
+ /** Layer field metadata. Alias of `IField` (@esri/arcgis-rest-request). */
264
+ type FieldInfo = IField & {
199
265
  length?: number;
200
266
  nullable?: boolean;
201
267
  defaultValue?: unknown;
202
- domain?: {
203
- type: 'codedValue' | 'range';
204
- name?: string;
205
- codedValues?: Array<{
206
- name: string;
207
- code: unknown;
208
- }>;
209
- range?: [number, number];
210
- };
211
- }
268
+ };
212
269
  interface LayerInfo {
213
270
  id: number;
214
271
  name: string;
@@ -244,29 +301,10 @@ interface LayerMetadata extends LayerInfo {
244
301
  cardinality: 'esriRelCardinalityOneToOne' | 'esriRelCardinalityOneToMany' | 'esriRelCardinalityManyToMany';
245
302
  }>;
246
303
  }
247
- interface Extent {
248
- xmin: number;
249
- ymin: number;
250
- xmax: number;
251
- ymax: number;
252
- spatialReference?: {
253
- wkid?: number;
254
- latestWkid?: number;
255
- };
256
- }
257
- interface FeatureSet {
258
- features: Array<{
259
- attributes: Record<string, unknown>;
260
- geometry?: Record<string, unknown>;
261
- }>;
262
- geometryType?: string;
263
- spatialReference?: {
264
- wkid?: number;
265
- latestWkid?: number;
266
- };
267
- fields?: FieldInfo[];
304
+ type Extent = IExtent;
305
+ type FeatureSet = IFeatureSet & {
268
306
  exceededTransferLimit?: boolean;
269
- }
307
+ };
270
308
  interface LayerQueryOptions {
271
309
  where?: string;
272
310
  geometry?: GeoJSON.Geometry;
@@ -346,31 +384,23 @@ interface AGOLServiceError {
346
384
  message: string;
347
385
  details?: string[];
348
386
  }
349
- interface EditResult {
350
- objectId: number;
387
+ /** Result of a single add/update/delete. Alias of `IEditFeatureResult`. */
388
+ type EditResult = IEditFeatureResult;
389
+ /** Result of an applyEdits transaction. Alias of `IApplyEditsResult`. */
390
+ type ApplyEditsResult = IApplyEditsResult;
391
+ /** Feature attachment metadata. Alias of `IAttachmentInfo` plus optional extras. */
392
+ type AttachmentInfo = IAttachmentInfo & {
351
393
  globalId?: string;
352
- success: boolean;
353
- error?: AGOLServiceError;
354
- }
355
- interface ApplyEditsResult {
356
- addResults?: EditResult[];
357
- updateResults?: EditResult[];
358
- deleteResults?: EditResult[];
359
- }
360
- interface AttachmentInfo {
361
- id: number;
362
- globalId?: string;
363
- name: string;
364
- contentType: string;
365
- size: number;
366
394
  keywords?: string;
367
- }
395
+ };
368
396
  interface PaginatedFeatureCollection extends GeoJSON.FeatureCollection {
369
397
  exceededTransferLimit?: boolean;
370
398
  }
371
399
 
372
400
  interface ServiceOptions {
373
401
  url: string;
402
+ /** @deprecated The leaflet-style proxy string is no longer applied; configure
403
+ * a proxy through your `authentication` manager or a global fetch override. */
374
404
  proxy?: string | boolean;
375
405
  useCors?: boolean;
376
406
  timeout?: number;
@@ -378,6 +408,8 @@ interface ServiceOptions {
378
408
  requestParams?: Record<string, unknown>;
379
409
  getAttributionFromService?: boolean;
380
410
  apiKey?: string;
411
+ /** An ArcGIS REST JS authentication manager (takes precedence over token/apiKey). */
412
+ authentication?: EsriAuthentication;
381
413
  }
382
414
  type ServiceCallback<T = unknown> = (error?: Error, response?: T) => void;
383
415
  interface ServiceEvents {
@@ -536,6 +568,9 @@ declare class DynamicMapService {
536
568
  setLayerDefinition(layerId: number, definitionExpression: string): void;
537
569
  setLayerFilter(layerId: number, filter: LayerFilter): void;
538
570
  private _appendTokenIfExists;
571
+ private _auth;
572
+ /** Resolved ArcGIS REST JS auth manager for the typed feature-service helpers. */
573
+ private _authentication;
539
574
  private _escapeValue;
540
575
  private _isGroupFilter;
541
576
  private _isBetweenFilter;
@@ -670,6 +705,7 @@ declare class ImageService {
670
705
  * Note: MapLibre GL v5+ may show vector tile parsing warnings with some Esri tiles.
671
706
  * These warnings are expected and do not affect map rendering functionality.
672
707
  */
708
+
673
709
  type EsriBasemapStyleName = 'arcgis/streets' | 'arcgis/topographic' | 'arcgis/navigation' | 'arcgis/streets-relief' | 'arcgis/dark-gray' | 'arcgis/light-gray' | 'arcgis/oceans' | 'arcgis/imagery' | 'arcgis/streets-night' | 'arcgis:streets' | 'arcgis:topographic' | 'arcgis:navigation' | 'arcgis:streetsrelief' | 'arcgis:darkgray' | 'arcgis:lightgray' | 'arcgis:oceans' | 'arcgis:imagery' | 'arcgis:streetsnight' | string;
674
710
  interface VectorBasemapStyleAuthOptions {
675
711
  apiKey?: string;
@@ -681,6 +717,8 @@ interface VectorBasemapStyleAuthOptions {
681
717
  language?: string;
682
718
  worldview?: string;
683
719
  itemId?: string;
720
+ useSession?: boolean;
721
+ sessionDuration?: number;
684
722
  }
685
723
  declare class VectorBasemapStyle {
686
724
  styleName: string;
@@ -693,6 +731,9 @@ declare class VectorBasemapStyle {
693
731
  private _language?;
694
732
  private _worldview?;
695
733
  private _itemId?;
734
+ private _useSession;
735
+ private _sessionDuration?;
736
+ private _session?;
696
737
  private static readonly COLON_TO_SLASH;
697
738
  constructor(styleName?: EsriBasemapStyleName, auth?: string | VectorBasemapStyleAuthOptions);
698
739
  get styleUrl(): string;
@@ -716,6 +757,35 @@ declare class VectorBasemapStyle {
716
757
  static applyStyle(map: {
717
758
  setStyle: (style: string) => void;
718
759
  }, styleName: EsriBasemapStyleName, auth: VectorBasemapStyleAuthOptions): void;
760
+ /**
761
+ * The style family for the official basemap sessions API, derived from the
762
+ * canonical style id. esri-gl styles are all in the `arcgis` family.
763
+ */
764
+ private get _styleFamily();
765
+ /**
766
+ * The token from the active session, if a session has been started. Useful
767
+ * for inspection / debugging. Returns `undefined` until `startSession()` runs.
768
+ */
769
+ get sessionToken(): string | undefined;
770
+ /**
771
+ * Start (or reuse) an official basemap style session via
772
+ * `@esri/arcgis-rest-basemap-sessions`. Requires an apiKey or token. The
773
+ * resulting session is cached so repeated calls return the same instance.
774
+ */
775
+ startSession(): Promise<BasemapStyleSession>;
776
+ /**
777
+ * Resolve the style URL to apply. When `useSession` is enabled this starts a
778
+ * session and returns a v2 style URL backed by the session token; otherwise it
779
+ * returns the synchronous `styleUrl`.
780
+ */
781
+ getStyleUrl(): Promise<string>;
782
+ /**
783
+ * Apply a basemap style to a MapLibre/Mapbox map using a session-backed style
784
+ * URL. Mirrors {@link applyStyle} but starts a basemap style session first.
785
+ */
786
+ static applyStyleWithSession(map: {
787
+ setStyle: (style: string) => void;
788
+ }, styleName: EsriBasemapStyleName, auth: VectorBasemapStyleAuthOptions): Promise<void>;
719
789
  private static _toCanonical;
720
790
  }
721
791
 
@@ -759,20 +829,6 @@ declare class VectorTileService {
759
829
  remove(): void;
760
830
  }
761
831
 
762
- /**
763
- * FeatureService - Tile-based feature loading from ArcGIS FeatureServers
764
- *
765
- * This implementation is based on mapbox-gl-arcgis-featureserver by Rowan Winsemius
766
- * @see https://github.com/rowanwins/mapbox-gl-arcgis-featureserver
767
- *
768
- * Key features:
769
- * - Prioritizes PBF format for minimal payload size (requires ArcGIS Server 10.7+)
770
- * - Falls back to GeoJSON if PBF is not supported
771
- * - Uses tiled requests for efficient data loading
772
- * - Client-side feature deduplication
773
- * - Service bounds detection and coordinate projection
774
- */
775
-
776
832
  interface FeatureServiceExtendedOptions extends FeatureServiceOptions {
777
833
  fetchOptions?: RequestInit;
778
834
  /** Use a static zoom level for tile requests instead of dynamic */
@@ -793,7 +849,7 @@ interface FeatureServiceExtendedOptions extends FeatureServiceOptions {
793
849
  useServiceBounds?: boolean;
794
850
  /** Custom projection endpoint URL */
795
851
  projectionEndpoint?: string;
796
- /** API key sent via X-Esri-Authorization header */
852
+ /** ArcGIS Location Platform API key (sent as the `token` parameter) */
797
853
  apiKey?: string;
798
854
  }
799
855
  interface GeoJSONSourceOptions {
@@ -841,6 +897,7 @@ declare class FeatureService {
841
897
  private _serviceMetadata;
842
898
  private _maxExtent;
843
899
  private _boundEvent;
900
+ private _removed;
844
901
  private _format;
845
902
  private _sourceReadyResolve;
846
903
  private _sourceReadyReject;
@@ -934,9 +991,14 @@ declare class FeatureService {
934
991
  private _projectBounds;
935
992
  private _projectionEndpointIsFallback;
936
993
  private _setAttribution;
937
- private _appendTokenIfExists;
938
- private _getFetchHeaders;
939
- private _checkAgolError;
994
+ /**
995
+ * Read the authentication-related fields off the service options. The
996
+ * `authentication` field is not part of the public options type, so the
997
+ * options object is cast to surface it for {@link resolveAuthentication}.
998
+ */
999
+ private _authOptions;
1000
+ /** Build an ArcGIS REST JS authentication manager from the service options. */
1001
+ private _authentication;
940
1002
  private _handleAuthError;
941
1003
  private _fireEvent;
942
1004
  /**
@@ -947,6 +1009,26 @@ declare class FeatureService {
947
1009
  * Remove event listener
948
1010
  */
949
1011
  off(event: string, callback: (event: unknown) => void): FeatureService;
1012
+ /**
1013
+ * Query records related to this layer's features through a relationship
1014
+ * class. Wraps `queryRelated` from `@esri/arcgis-rest-feature-service`.
1015
+ */
1016
+ queryRelatedRecords(options: {
1017
+ relationshipId?: number;
1018
+ objectIds?: number[];
1019
+ outFields?: string | string[];
1020
+ definitionExpression?: string;
1021
+ returnGeometry?: boolean;
1022
+ }): Promise<_esri_arcgis_rest_feature_service.IQueryRelatedResponse>;
1023
+ /**
1024
+ * Replace coded-value-domain codes with their human-readable names in a
1025
+ * query response. Wraps `decodeValues` from
1026
+ * `@esri/arcgis-rest-feature-service`.
1027
+ *
1028
+ * @param queryResponse A response from a `f=json` feature query.
1029
+ * @param fields Optional subset of field names to decode (defaults to all).
1030
+ */
1031
+ decodeValues(queryResponse: unknown, fields?: string[]): Promise<_esri_arcgis_rest_feature_service.IQueryFeaturesResponse>;
950
1032
  /**
951
1033
  * Add features to the service
952
1034
  */
@@ -1006,11 +1088,14 @@ declare class FeatureService {
1006
1088
 
1007
1089
  interface TaskOptions {
1008
1090
  url?: string;
1091
+ /** @deprecated No longer applied; use `authentication` or a global fetch override. */
1009
1092
  proxy?: string | boolean;
1010
1093
  useCors?: boolean;
1011
1094
  requestParams?: Record<string, unknown>;
1012
1095
  token?: string;
1013
1096
  apikey?: string;
1097
+ /** An ArcGIS REST JS authentication manager (takes precedence over token/apikey). */
1098
+ authentication?: EsriAuthentication;
1014
1099
  }
1015
1100
  /**
1016
1101
  * Base Task class for ArcGIS REST API operations
@@ -1048,7 +1133,10 @@ declare class Task {
1048
1133
  */
1049
1134
  request<T = unknown>(): Promise<T>;
1050
1135
  /**
1051
- * Direct HTTP request (when not using a service)
1136
+ * Direct HTTP request (when not using a service), delegated to
1137
+ * `@esri/arcgis-rest-request`. Token/apiKey supplied either as task options
1138
+ * or as `token`/`apiKey` params are routed through the auth layer rather than
1139
+ * being sent as raw query parameters.
1052
1140
  */
1053
1141
  private _request;
1054
1142
  }
@@ -1528,9 +1616,98 @@ declare class IdentifyImage extends Task {
1528
1616
  }
1529
1617
  declare function identifyImage(options: string | IdentifyImageOptions): IdentifyImage;
1530
1618
 
1619
+ /**
1620
+ * Portal item resolution.
1621
+ *
1622
+ * Turns an ArcGIS portal item id into ready-to-render esri-gl services using
1623
+ * `@esri/arcgis-rest-portal`. Two entry points are provided:
1624
+ *
1625
+ * - {@link serviceFromPortalItem} — resolve a single-layer item (Feature / Map /
1626
+ * Image / Vector Tile service) to the matching esri-gl service.
1627
+ * - {@link servicesFromWebMap} — read a Web Map item's `operationalLayers`
1628
+ * (and optionally its basemap) and instantiate a service per layer.
1629
+ */
1630
+
1631
+ /** Any esri-gl service instance a portal item can resolve to. */
1632
+ type PortalResolvedService = DynamicMapService | TiledMapService | ImageService | VectorTileService | FeatureService;
1633
+ /** esri-gl service kinds, used to label resolution results. */
1634
+ type PortalServiceKind = 'dynamic' | 'tiled' | 'image' | 'vector-tile' | 'feature';
1635
+ interface PortalRequestOptions extends EsriAuthOptions {
1636
+ /** Portal sharing REST URL. Defaults to ArcGIS Online. */
1637
+ portal?: string;
1638
+ }
1639
+ interface PortalItemServiceOptions extends PortalRequestOptions {
1640
+ /** For multi-layer Feature Services, which sublayer to load (default 0). */
1641
+ layerId?: number;
1642
+ /** Extra options merged into the constructed service's options object. */
1643
+ serviceOptions?: Record<string, unknown>;
1644
+ /** Raster source options (Dynamic / Tiled / Image services). */
1645
+ rasterSrcOptions?: Record<string, unknown>;
1646
+ /** Vector source options (Vector Tile service). */
1647
+ vectorSrcOptions?: Record<string, unknown>;
1648
+ /** GeoJSON source options (Feature service). */
1649
+ geojsonSourceOptions?: Record<string, unknown>;
1650
+ }
1651
+ interface PortalServiceResult {
1652
+ /** The instantiated esri-gl service. */
1653
+ service: PortalResolvedService;
1654
+ /** Which kind of service was created. */
1655
+ kind: PortalServiceKind;
1656
+ /** The source id registered on the map. */
1657
+ sourceId: string;
1658
+ /** The service URL the item resolved to. */
1659
+ url: string;
1660
+ /** The portal item (single-item resolution only). */
1661
+ item?: IItem;
1662
+ /** Human-readable title (item title or web map layer title). */
1663
+ title?: string;
1664
+ }
1665
+ /**
1666
+ * Resolve a single-layer portal item to the matching esri-gl service and add
1667
+ * its source to the map.
1668
+ *
1669
+ * @example
1670
+ * const { service } = await serviceFromPortalItem('my-source', map, 'a1b2c3', { token });
1671
+ */
1672
+ declare function serviceFromPortalItem(sourceId: string, map: Map, itemId: string, options?: PortalItemServiceOptions): Promise<PortalServiceResult>;
1673
+ interface WebMapOptions extends PortalItemServiceOptions {
1674
+ /** Also instantiate the web map's basemap layers (default false). */
1675
+ includeBasemap?: boolean;
1676
+ /** Prefix for generated source ids (default the web map item id). */
1677
+ sourceIdPrefix?: string;
1678
+ }
1679
+ /**
1680
+ * Read a Web Map item's data and instantiate an esri-gl service for each
1681
+ * supported operational layer (optionally including basemap layers).
1682
+ * Unsupported layer types are skipped.
1683
+ *
1684
+ * @example
1685
+ * const layers = await servicesFromWebMap(map, 'webmap-item-id', { token });
1686
+ * layers.forEach(({ service, title }) => { ... });
1687
+ */
1688
+ declare function servicesFromWebMap(map: Map, itemId: string, options?: WebMapOptions): Promise<PortalServiceResult[]>;
1689
+ /**
1690
+ * Search an ArcGIS portal for items, e.g. to discover services to load.
1691
+ * Thin wrapper over `searchItems` from `@esri/arcgis-rest-portal`; accepts a
1692
+ * query string, a {@link SearchQueryBuilder}, or a full `ISearchOptions`.
1693
+ *
1694
+ * @example
1695
+ * const { results } = await searchPortalItems('type:"Feature Service" AND owner:esri');
1696
+ * // or with auth / paging:
1697
+ * await searchPortalItems({ q: 'wildfire', num: 20, authentication }, { token });
1698
+ */
1699
+ declare function searchPortalItems(search: string | SearchQueryBuilder | ISearchOptions, options?: PortalRequestOptions): Promise<ISearchResult<IItem>>;
1700
+
1531
1701
  declare function cleanTrailingSlash(url: string): string;
1532
- declare function getServiceDetails(url: string, fetchOptions?: RequestInit, token?: string): Promise<ServiceMetadata>;
1702
+ /**
1703
+ * Fetch the `?f=json` metadata document for an ArcGIS service endpoint.
1704
+ *
1705
+ * Delegates to `@esri/arcgis-rest-request` via {@link esriRequest}, which
1706
+ * handles authentication and ArcGIS error responses. Accepts an
1707
+ * {@link EsriRequestOptions} object (`token` / `apiKey` / `authentication`).
1708
+ */
1709
+ declare function getServiceDetails(url: string, options?: EsriRequestOptions): Promise<ServiceMetadata>;
1533
1710
  declare function updateAttribution(newAttribution: string, sourceId: string, map: Map): void;
1534
1711
 
1535
- export { DynamicMapService as D, TiledMapService as T, Query as X, Service as Z, Task as a3, cleanTrailingSlash as a6, find as a7, getServiceDetails as a8, identifyImage as a9, query as aa, updateAttribution as ab, ImageService as e, VectorTileService as f, FeatureService as g, VectorBasemapStyle as h, IdentifyImage as i, Find as v, IdentifyFeatures as w };
1536
- export type { ServiceEventType as $, ApplyEditsResult as A, BatchLayerOperation as B, ComparisonFilter as C, EsriServiceOptions as E, FeatureServiceOptions as F, GroupFilter as G, LayerMetadata as H, IdentifyImageOptions as I, LayerQueryOptions as J, LayerScaleRange as K, LayerFilter as L, LayerSpecification as M, LayerTimeOptions as N, LayerUpdateEvent as O, LayerUpdateType as P, LegendInfo as Q, LogicalOp as R, MapExportOptions as S, NullFilter as U, VectorBasemapStyleOptions as V, PaginatedFeatureCollection as W, RasterSourceOptions as Y, ServiceErrorEvent as _, EditResult as a, ServiceMetadata as a0, SourceSpecification as a1, StatisticResult as a2, TimeAnimationOptions as a4, VectorSourceOptions as a5, FindOptions as b, ImageServiceOptions as c, VectorTileServiceOptions as d, AGOLServiceError as j, AttachmentInfo as k, BetweenFilter as l, ComparisonOp as m, DynamicLayer as n, EsriDrawingInfo as o, EsriDynamicMapLayerSource as p, EsriRenderer as q, EsriTextSymbol as r, Extent as s, FeatureSet as t, FieldInfo as u, InFilter as x, LayerInfo as y, LayerLabelingInfo as z };
1712
+ export { DynamicMapService as D, Find as G, IdentifyFeatures as J, TiledMapService as T, Query as a3, Service as a5, Task as ab, cleanTrailingSlash as af, esriRequest as ag, find as ah, getServiceDetails as ai, identifyImage as aj, query as ak, resolveAuthentication as al, searchPortalItems as am, serviceFromPortalItem as an, servicesFromWebMap as ao, updateAttribution as ap, ImageService as g, VectorTileService as h, FeatureService as i, VectorBasemapStyle as j, IdentifyImage as k };
1713
+ export type { NullFilter as $, ApplyEditsResult as A, BatchLayerOperation as B, ComparisonFilter as C, EsriServiceOptions as E, FeatureServiceOptions as F, GroupFilter as H, IdentifyImageOptions as I, InFilter as K, LayerFilter as L, LayerInfo as M, LayerLabelingInfo as N, LayerMetadata as O, PortalItemServiceOptions as P, LayerQueryOptions as Q, LayerScaleRange as R, LayerSpecification as S, LayerTimeOptions as U, VectorBasemapStyleOptions as V, LayerUpdateEvent as W, LayerUpdateType as X, LegendInfo as Y, LogicalOp as Z, MapExportOptions as _, EditResult as a, PaginatedFeatureCollection as a0, PortalRequestOptions as a1, PortalServiceResult as a2, RasterSourceOptions as a4, ServiceErrorEvent as a6, ServiceEventType as a7, ServiceMetadata as a8, SourceSpecification as a9, StatisticResult as aa, TimeAnimationOptions as ac, VectorSourceOptions as ad, WebMapOptions as ae, FindOptions as b, ImageServiceOptions as c, PortalResolvedService as d, PortalServiceKind as e, VectorTileServiceOptions as f, AGOLServiceError as l, AttachmentInfo as m, BetweenFilter as n, ComparisonOp as o, DynamicLayer as p, EsriAuthOptions as q, EsriAuthentication as r, EsriDrawingInfo as s, EsriDynamicMapLayerSource as t, EsriRenderer as u, EsriRequestOptions as v, EsriTextSymbol as w, Extent as x, FeatureSet as y, FieldInfo as z };