@arcgis/coding-components 4.31.0-next.2 → 4.31.0-next.21
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 +22 -3
- package/dist/arcgis-coding-components/arcgis-coding-components.esm.js +2 -2
- package/dist/arcgis-coding-components/assets/arcade-language/t9n/profile.t9n.ar.json +1 -1
- package/dist/arcgis-coding-components/assets/arcade-language/t9n/profile.t9n.bg.json +1 -1
- package/dist/arcgis-coding-components/assets/arcade-language/t9n/profile.t9n.bs.json +1 -1
- package/dist/arcgis-coding-components/assets/arcade-language/t9n/profile.t9n.ca.json +6 -6
- package/dist/arcgis-coding-components/assets/arcade-language/t9n/profile.t9n.cs.json +1 -1
- package/dist/arcgis-coding-components/assets/arcade-language/t9n/profile.t9n.da.json +1 -1
- package/dist/arcgis-coding-components/assets/arcade-language/t9n/profile.t9n.de.json +1 -1
- package/dist/arcgis-coding-components/assets/arcade-language/t9n/profile.t9n.el.json +1 -1
- package/dist/arcgis-coding-components/assets/arcade-language/t9n/profile.t9n.es.json +1 -1
- package/dist/arcgis-coding-components/assets/arcade-language/t9n/profile.t9n.et.json +1 -1
- package/dist/arcgis-coding-components/assets/arcade-language/t9n/profile.t9n.fi.json +1 -1
- package/dist/arcgis-coding-components/assets/arcade-language/t9n/profile.t9n.fr.json +1 -1
- package/dist/arcgis-coding-components/assets/arcade-language/t9n/profile.t9n.he.json +1 -1
- package/dist/arcgis-coding-components/assets/arcade-language/t9n/profile.t9n.hr.json +1 -1
- package/dist/arcgis-coding-components/assets/arcade-language/t9n/profile.t9n.id.json +1 -1
- package/dist/arcgis-coding-components/assets/arcade-language/t9n/profile.t9n.it.json +1 -1
- package/dist/arcgis-coding-components/assets/arcade-language/t9n/profile.t9n.ko.json +1 -1
- package/dist/arcgis-coding-components/assets/arcade-language/t9n/profile.t9n.nb.json +1 -1
- package/dist/arcgis-coding-components/assets/arcade-language/t9n/profile.t9n.nl.json +1 -1
- package/dist/arcgis-coding-components/assets/arcade-language/t9n/profile.t9n.pl.json +1 -1
- package/dist/arcgis-coding-components/assets/arcade-language/t9n/profile.t9n.pt-BR.json +1 -1
- package/dist/arcgis-coding-components/assets/arcade-language/t9n/profile.t9n.pt-PT.json +1 -1
- package/dist/arcgis-coding-components/assets/arcade-language/t9n/profile.t9n.ru.json +1 -1
- package/dist/arcgis-coding-components/assets/arcade-language/t9n/profile.t9n.sk.json +1 -1
- package/dist/arcgis-coding-components/assets/arcade-language/t9n/profile.t9n.sl.json +1 -1
- package/dist/arcgis-coding-components/assets/arcade-language/t9n/profile.t9n.sr.json +1 -1
- package/dist/arcgis-coding-components/assets/arcade-language/t9n/profile.t9n.sv.json +1 -1
- package/dist/arcgis-coding-components/assets/arcade-language/t9n/profile.t9n.th.json +1 -1
- package/dist/arcgis-coding-components/assets/arcade-language/t9n/profile.t9n.tr.json +1 -1
- package/dist/arcgis-coding-components/assets/arcade-language/t9n/profile.t9n.uk.json +5 -5
- package/dist/arcgis-coding-components/assets/arcade-language/t9n/profile.t9n.vi.json +1 -1
- package/dist/arcgis-coding-components/assets/arcade-language/t9n/profile.t9n.zh-CN.json +1 -1
- package/dist/arcgis-coding-components/assets/arcade-language/t9n/profile.t9n.zh-HK.json +1 -1
- package/dist/arcgis-coding-components/assets/arcade-language/t9n/profile.t9n.zh-TW.json +1 -1
- package/dist/arcgis-coding-components/assets/arcade-results/t9n/arcade-results.t9n.ca.json +2 -2
- package/dist/arcgis-coding-components/assets/arcade-results/t9n/arcade-results.t9n.de.json +1 -1
- package/dist/arcgis-coding-components/assets/arcade-results/t9n/arcade-results.t9n.he.json +1 -1
- package/dist/arcgis-coding-components/assets/arcade-variables/t9n/arcade-variables.t9n.ca.json +1 -1
- package/dist/arcgis-coding-components/assets/arcade-variables/t9n/arcade-variables.t9n.it.json +1 -1
- package/dist/arcgis-coding-components/assets/code-editor/css.worker.js +1 -1
- package/dist/arcgis-coding-components/assets/code-editor/html.worker.js +1 -1
- package/dist/arcgis-coding-components/assets/code-editor/json.worker.js +1 -1
- package/dist/arcgis-coding-components/assets/code-editor/sql-expr.worker.js +33 -0
- package/dist/arcgis-coding-components/assets/code-editor/ts.worker.js +1 -1
- package/dist/arcgis-coding-components/assets/language-api-panel/t9n/language-api-panel.t9n.ca.json +1 -1
- package/dist/arcgis-coding-components/assets/sql-expression-editor/api/sql-expression-api.t9n.en.json +735 -0
- package/dist/arcgis-coding-components/index.esm.js +2 -2
- package/dist/arcgis-coding-components/{p-7984ea8e.js → p-1b799777.js} +2 -2
- package/dist/arcgis-coding-components/p-4d5cf512.entry.js +6 -0
- package/dist/arcgis-coding-components/{p-60c2a820.js → p-56266a64.js} +2 -2
- package/dist/arcgis-coding-components/{p-e8211ffe.js → p-57b8bcd7.js} +1 -1
- package/dist/arcgis-coding-components/{p-9eced6fc.js → p-5b67b62b.js} +2 -2
- package/dist/arcgis-coding-components/{p-93a97573.js → p-64137fec.js} +3 -3
- package/dist/arcgis-coding-components/{p-e7ee4d64.js → p-6621a80f.js} +3 -3
- package/dist/arcgis-coding-components/p-77dd5521.js +6 -0
- package/dist/arcgis-coding-components/p-8eb7e694.js +6 -0
- package/dist/arcgis-coding-components/p-a2341e0c.js +6 -0
- package/dist/arcgis-coding-components/{p-bb7e832e.js → p-b715834b.js} +3 -3
- package/dist/arcgis-coding-components/p-cbee273f.js +6 -0
- package/dist/arcgis-coding-components/{p-5ef7cce5.js → p-cdc52d2f.js} +1 -1
- package/dist/arcgis-coding-components/{p-36fedc23.js → p-d7d1f130.js} +12 -12
- package/dist/arcgis-coding-components/p-e1f9b463.entry.js +6 -0
- package/dist/arcgis-coding-components/{p-62ee6251.js → p-e5a924a1.js} +1 -1
- package/dist/arcgis-coding-components/p-f2d64a9d.js +6 -0
- package/dist/arcgis-coding-components/{p-03ea6cd7.js → p-ff62d134.js} +3 -3
- package/dist/arcgis-coding-components/p-ffce0588.entry.js +6 -0
- package/dist/cjs/{app-globals-aee5f4b5.js → app-globals-a9ef3ca8.js} +1 -1
- package/dist/cjs/arcade-defaults-f5241680.js +349 -0
- package/dist/cjs/arcade-language-features-0b9f3947.js +274 -0
- package/dist/cjs/arcade-mode-cc08d9cd.js +335 -0
- package/dist/cjs/arcgis-arcade-editor_6.cjs.entry.js +181 -1501
- package/dist/cjs/arcgis-coding-components.cjs.js +4 -4
- package/dist/cjs/arcgis-sql-expression-editor.cjs.entry.js +81 -0
- package/dist/cjs/arcgis-sql-expression-fields.cjs.entry.js +80 -0
- package/dist/cjs/{css-7cc05f76.js → css-bb6a49ec.js} +1 -1
- package/dist/cjs/{cssMode-2b0daeae.js → cssMode-e7fac7d7.js} +3 -4
- package/dist/cjs/{html-f56911e1.js → html-7ff4071d.js} +3 -4
- package/dist/cjs/{htmlMode-43eed674.js → htmlMode-c89193ec.js} +3 -4
- package/dist/cjs/{index-b34238a6.js → index-4b7880ab.js} +9 -1
- package/dist/cjs/index.cjs.js +4 -3
- package/dist/cjs/{javascript-5115cb76.js → javascript-864c0220.js} +3 -4
- package/dist/cjs/{jsonMode-550dda36.js → jsonMode-ac4a7be7.js} +3 -4
- package/dist/cjs/{arcade-defaults-a8d8f8e2.js → language-defaults-base-57b37f9f.js} +842 -1183
- package/dist/cjs/loader.cjs.js +4 -4
- package/dist/cjs/sql-expr-defaults-245b036d.js +1347 -0
- package/dist/cjs/sql-expr-mode-304f5ce2.js +20844 -0
- package/dist/cjs/{tsMode-336306a9.js → tsMode-d30d4ab1.js} +4 -5
- package/dist/cjs/{typescript-b395242f.js → typescript-6c87ddb3.js} +3 -4
- package/dist/components/arcade-defaults.js +54 -1369
- package/dist/components/arcade-language-features.js +271 -0
- package/dist/components/arcade-mode.js +4 -264
- package/dist/components/arcade-results.js +7 -5
- package/dist/components/arcade-suggestions.js +7 -5
- package/dist/components/arcade-variables.js +8 -6
- package/dist/components/arcgis-arcade-editor.js +37 -35
- package/dist/components/arcgis-arcade-results.js +1 -1
- package/dist/components/arcgis-arcade-suggestions.js +1 -1
- package/dist/components/arcgis-arcade-variables.js +1 -1
- package/dist/components/arcgis-assets.d.ts +1 -1
- package/dist/components/arcgis-assets.js +1 -1
- package/dist/components/arcgis-code-editor.js +1 -1
- package/dist/components/arcgis-language-api-panel.js +1 -1
- package/dist/components/arcgis-sql-expression-editor.d.ts +11 -0
- package/dist/components/arcgis-sql-expression-editor.js +120 -0
- package/dist/components/arcgis-sql-expression-fields.d.ts +11 -0
- package/dist/components/arcgis-sql-expression-fields.js +11 -0
- package/dist/components/chunk-2JTWBRMN.js +1154 -0
- package/dist/components/code-editor.js +40 -13
- package/dist/components/fields.js +5 -5
- package/dist/components/index.js +1 -1
- package/dist/components/index2.js +30 -22
- package/dist/components/language-api-panel.js +13 -40
- package/dist/components/language-defaults-base.js +1309 -0
- package/dist/components/markdown.js +1 -1
- package/dist/components/sql-expr-defaults.js +196 -0
- package/dist/components/sql-expr-mode.js +20842 -0
- package/dist/components/sql-expression-fields.js +102 -0
- package/dist/components/useT9n.js +45 -8
- package/dist/components/utilities.js +1 -1
- package/dist/esm/{app-globals-59faaf33.js → app-globals-6d0ca11d.js} +1 -1
- package/dist/esm/arcade-defaults-066445c4.js +344 -0
- package/dist/esm/arcade-language-features-0e00c199.js +269 -0
- package/dist/esm/{arcade-mode-5d46035e.js → arcade-mode-abf1e1cf.js} +3 -263
- package/dist/esm/arcgis-arcade-editor_6.entry.js +127 -1447
- package/dist/esm/arcgis-coding-components.js +5 -5
- package/dist/esm/arcgis-sql-expression-editor.entry.js +77 -0
- package/dist/esm/arcgis-sql-expression-fields.entry.js +76 -0
- package/dist/esm/{css-e257dc49.js → css-c6dae12d.js} +1 -1
- package/dist/esm/{cssMode-c11f7f40.js → cssMode-052bb603.js} +2 -3
- package/dist/esm/{html-a6c37a99.js → html-572696a1.js} +2 -3
- package/dist/esm/{htmlMode-1270bc7d.js → htmlMode-fc184f2d.js} +2 -3
- package/dist/esm/{index-a970952c.js → index-0edd9846.js} +9 -1
- package/dist/esm/index.js +4 -3
- package/dist/esm/{javascript-ee179624.js → javascript-8bfc0096.js} +3 -4
- package/dist/esm/{jsonMode-07502ccb.js → jsonMode-7adf94ff.js} +2 -3
- package/dist/esm/{arcade-defaults-9eb28407.js → language-defaults-base-85a7f476.js} +833 -1179
- package/dist/esm/loader.js +5 -5
- package/dist/esm/sql-expr-defaults-be84ec7f.js +1339 -0
- package/dist/esm/sql-expr-mode-a4413e5c.js +20840 -0
- package/dist/esm/{tsMode-96749a12.js → tsMode-d10773c8.js} +2 -3
- package/dist/esm/{typescript-a3cf9881.js → typescript-9491f23e.js} +2 -3
- package/dist/loader/cdn.js +1 -1
- package/dist/loader/index.cjs.js +1 -1
- package/dist/loader/index.es2017.js +1 -1
- package/dist/loader/index.js +1 -1
- package/dist/types/components/arcade-editor/arcade-editor.d.ts +45 -10
- package/dist/types/components/arcade-results/arcade-results.d.ts +43 -1
- package/dist/types/components/arcade-suggestions/arcade-suggestions.d.ts +22 -1
- package/dist/types/components/arcade-variables/arcade-variables.d.ts +28 -1
- package/dist/types/components/code-editor/code-editor.d.ts +16 -5
- package/dist/types/components/language-api-panel/language-api-panel.d.ts +34 -8
- package/dist/types/components/sql-expression-editor/sql-expression-editor.d.ts +24 -0
- package/dist/types/components/sql-expression-fields/sql-expression-fields.d.ts +32 -0
- package/dist/types/components.d.ts +98 -24
- package/dist/types/data/actions-runner-1/_work/arcgis-web-components/arcgis-web-components/packages/coding-packages/coding-components/.stencil/stories/internal/arcade-editor/arcade-editor.stories.d.ts +8 -1
- package/dist/types/data/actions-runner-1/_work/arcgis-web-components/arcgis-web-components/packages/coding-packages/coding-components/.stencil/stories/internal/arcade-editor/editorContext.d.ts +5 -1
- package/dist/types/data/actions-runner-1/_work/arcgis-web-components/arcgis-web-components/packages/coding-packages/coding-components/.stencil/stories/internal/sql-expression-editor/sql-expression-editor.stories.d.ts +13 -0
- package/dist/types/dependencies.d.ts +6 -10
- package/dist/types/utils/arcade-monaco/arcade-language-features.d.ts +1 -0
- package/dist/types/utils/arcade-monaco/arcade-profile-strategy.d.ts +9 -0
- package/dist/types/utils/fields.d.ts +2 -2
- package/dist/types/utils/language-defaults-base.d.ts +2 -9
- package/dist/types/utils/profile/editor-profile.d.ts +7 -6
- package/dist/types/utils/profile/types.d.ts +53 -65
- package/dist/types/utils/profile/utils.d.ts +9 -8
- package/dist/types/utils/sql-expr-monaco/DependentFiles/DateOnly.d.ts +41 -0
- package/dist/types/utils/sql-expr-monaco/DependentFiles/SqlInterval.d.ts +16 -0
- package/dist/types/utils/sql-expr-monaco/DependentFiles/SqlTimestampOffset.d.ts +26 -0
- package/dist/types/utils/sql-expr-monaco/DependentFiles/TimeOnly.d.ts +37 -0
- package/dist/types/utils/sql-expr-monaco/DependentFiles/UnknownTimeZone.d.ts +11 -0
- package/dist/types/utils/sql-expr-monaco/DependentFiles/WhereGrammar.d.ts +122 -0
- package/dist/types/utils/sql-expr-monaco/DependentFiles/sqlCompareUtils.d.ts +5 -0
- package/dist/types/utils/sql-expr-monaco/DependentFiles/sqlDateParsingUtils.d.ts +18 -0
- package/dist/types/utils/sql-expr-monaco/DependentFiles/sqlUtils.d.ts +6 -0
- package/dist/types/utils/sql-expr-monaco/DependentFiles/standardizedFunctions.d.ts +156 -0
- package/dist/types/utils/sql-expr-monaco/DependentFiles/support.d.ts +150 -0
- package/dist/types/utils/sql-expr-monaco/PeggyGrammar/sql92grammar.d.ts +1397 -0
- package/dist/types/utils/sql-expr-monaco/sql-expr-completion.d.ts +6 -0
- package/dist/types/utils/sql-expr-monaco/sql-expr-constants.d.ts +45 -0
- package/dist/types/utils/sql-expr-monaco/sql-expr-contribution.d.ts +1 -0
- package/dist/types/utils/sql-expr-monaco/sql-expr-defaults.d.ts +21 -0
- package/dist/types/utils/sql-expr-monaco/sql-expr-language-features.d.ts +39 -0
- package/dist/types/utils/sql-expr-monaco/sql-expr-language-syntax.d.ts +8 -0
- package/dist/types/utils/sql-expr-monaco/sql-expr-mode.d.ts +43 -0
- package/dist/types/utils/sql-expr-monaco/sql-expr-service-accessors.d.ts +19 -0
- package/dist/types/utils/sql-expr-monaco/sql-expr-validation-diagnostic-adapter.d.ts +34 -0
- package/dist/types/utils/sql-expr-monaco/sql-expr-validation-utils.d.ts +100 -0
- package/dist/types/utils/sql-expr-monaco/sql-expr-validation.d.ts +41 -0
- package/dist/types/utils/sql-expr-monaco/sql-expr-worker-manager.d.ts +17 -0
- package/dist/types/utils/sql-expr-monaco/sql-expr.worker.d.ts +24 -0
- package/dist/types/utils/sql-expr-monaco/sql-expression-profile-strategy.d.ts +13 -0
- package/dist/types/utils/sql-expr-monaco/types.d.ts +89 -0
- package/package.json +27 -21
- package/dist/arcgis-coding-components/p-0c6de9b3.js +0 -6
- package/dist/arcgis-coding-components/p-81c37dab.entry.js +0 -6
- package/dist/cjs/arcade-mode-b85ae7d4.js +0 -595
- package/dist/components/chunk-IHYYRFLQ.js +0 -1363
- package/dist/types/components/arcade-editor/t9n-types.d.ts +0 -8
- package/dist/types/components/arcade-results/t9n-types.d.ts +0 -13
- package/dist/types/components/arcade-suggestions/t9n-types.d.ts +0 -6
- package/dist/types/components/arcade-variables/t9n-types.d.ts +0 -8
- package/dist/types/components/language-api-panel/t9n-types.d.ts +0 -8
- package/dist/types/utils/profile/predefined-profile.d.ts +0 -2
|
@@ -1,253 +1,59 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* All material copyright Esri, All Rights Reserved, unless otherwise specified.
|
|
3
3
|
* See https://js.arcgis.com/4.31/esri/copyright.txt for details.
|
|
4
|
-
* v4.31.0-next.
|
|
4
|
+
* v4.31.0-next.21
|
|
5
5
|
*/
|
|
6
|
-
import {
|
|
6
|
+
import { Uri } from 'monaco-editor';
|
|
7
|
+
import { f as fieldsToProfileValues, i as isPredefinedProfile, a as isFeatureSetCollectionDefinition, b as isFeatureSetDefinition, c as isFeatureDefinition, L as LanguageDefaultsBase, E as EditorProfile } from './language-defaults-base.js';
|
|
8
|
+
import { s as supportedLocales, f as fetchT9nStringsBundle } from './index2.js';
|
|
7
9
|
import { CompletionItemKind, InsertTextMode, InsertTextFormat } from 'vscode-languageserver-types';
|
|
8
|
-
import { n as newLayersFeatureLayer, i as importRequest, s as supportedFields, a as newPortalPortalItem, b as newWebScene, c as newWebMap, f as fieldAlias, d as fieldTypeToIconName, e as fieldTypeToArcadeType } from './fields.js';
|
|
9
|
-
import { p as portalItemPageUrl } from './utilities.js';
|
|
10
|
-
import { i as isNotNull, a as isNotUndefined, b as addLTRMark, s as setValuesInString, c as supportedLocales, f as fetchT9NStringsBundle } from './index2.js';
|
|
11
10
|
import { getArcgisAssetPath as getAssetPath } from "./arcgis-assets.js";
|
|
12
11
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
function
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
"declaredClass" in item &&
|
|
28
|
-
typeof item.declaredClass === "string" &&
|
|
29
|
-
item.declaredClass === "esri.layers.support.SubtypeSublayer");
|
|
30
|
-
}
|
|
31
|
-
function isGroupLayerInstance(item) {
|
|
32
|
-
return (!!item &&
|
|
33
|
-
typeof item === "object" &&
|
|
34
|
-
"declaredClass" in item &&
|
|
35
|
-
typeof item.declaredClass === "string" &&
|
|
36
|
-
item.declaredClass === "esri.layers.GroupLayer");
|
|
37
|
-
}
|
|
38
|
-
function isMapInstance(item) {
|
|
39
|
-
return (!!item &&
|
|
40
|
-
typeof item === "object" &&
|
|
41
|
-
"declaredClass" in item &&
|
|
42
|
-
typeof item.declaredClass === "string" &&
|
|
43
|
-
(item.declaredClass === "esri.Map" ||
|
|
44
|
-
item.declaredClass === "esri.WebMap" ||
|
|
45
|
-
item.declaredClass === "esri.WebScene"));
|
|
46
|
-
}
|
|
47
|
-
function isWebMapInstance(item) {
|
|
48
|
-
return item.declaredClass === "esri.WebMap";
|
|
49
|
-
}
|
|
50
|
-
function isWebSceneInstance(item) {
|
|
51
|
-
return item.declaredClass === "esri.WebScene";
|
|
52
|
-
}
|
|
53
|
-
function isLoadableMapInstance(item) {
|
|
54
|
-
return item.declaredClass === "esri.WebMap" || item.declaredClass === "esri.WebScene";
|
|
55
|
-
}
|
|
56
|
-
function isPortalItemDefinition(item) {
|
|
57
|
-
return !!item && typeof item === "object" && "portalItem" in item && item.portalItem != null;
|
|
58
|
-
}
|
|
59
|
-
function isFeatureLayerItemDefinition(item) {
|
|
60
|
-
return !!item && typeof item === "object" && "portalItem" in item && item.portalItem != null;
|
|
61
|
-
}
|
|
62
|
-
function isFieldsDefinition(item) {
|
|
63
|
-
return !!item && typeof item === "object" && "fields" in item && Array.isArray(item.fields);
|
|
64
|
-
}
|
|
65
|
-
function isUrlDefinition(item) {
|
|
66
|
-
return !!item && typeof item === "object" && "url" in item && typeof item.url === "string";
|
|
67
|
-
}
|
|
68
|
-
function isSupportedServiceUrlDefinition(item) {
|
|
69
|
-
return isUrlDefinition(item) && /\/(?:featureserver|mapserver)(?:\/|$)/iu.test(item.url);
|
|
70
|
-
}
|
|
71
|
-
function isSubtypeInstance(item) {
|
|
72
|
-
return (!!item &&
|
|
73
|
-
typeof item === "object" &&
|
|
74
|
-
"declaredClass" in item &&
|
|
75
|
-
item.declaredClass === "esri.layers.support.Subtype");
|
|
76
|
-
}
|
|
77
|
-
function isCodedValueDomainInstance(item) {
|
|
78
|
-
return (!!item &&
|
|
79
|
-
typeof item === "object" &&
|
|
80
|
-
"declaredClass" in item &&
|
|
81
|
-
item.declaredClass === "esri.layers.support.CodedValueDomain");
|
|
82
|
-
}
|
|
83
|
-
function isInheritedDomainInstance(item) {
|
|
84
|
-
return (!!item &&
|
|
85
|
-
typeof item === "object" &&
|
|
86
|
-
"declaredClass" in item &&
|
|
87
|
-
item.declaredClass === "esri.layers.support.InheritedDomain");
|
|
88
|
-
}
|
|
89
|
-
function isPredefinedProfile(item) {
|
|
90
|
-
return (!!item &&
|
|
91
|
-
typeof item === "object" &&
|
|
92
|
-
"id" in item &&
|
|
93
|
-
typeof item.id === "string" &&
|
|
94
|
-
"definitions" in item &&
|
|
95
|
-
typeof item.definitions === "object" &&
|
|
96
|
-
!Array.isArray(item.definitions));
|
|
97
|
-
}
|
|
98
|
-
function isTitleCapableSource(item) {
|
|
99
|
-
return !!item && typeof item === "object" && "title" in item && typeof item.title === "string";
|
|
100
|
-
}
|
|
101
|
-
function isUrlCapableSource(item) {
|
|
102
|
-
return !!item && typeof item === "object" && "url" in item && typeof item.url === "string";
|
|
103
|
-
}
|
|
104
|
-
function isLayerIdCapableSource(item) {
|
|
105
|
-
return !!item && typeof item === "object" && "layerId" in item && typeof item.layerId === "number";
|
|
106
|
-
}
|
|
107
|
-
function isFeatureTypesCapableLayer(item) {
|
|
108
|
-
return !!item && typeof item === "object" && "typeIdField" in item && "types" in item;
|
|
109
|
-
}
|
|
110
|
-
function isDomainsCapableLayer(item) {
|
|
111
|
-
return !!item && typeof item === "object" && "getFieldDomain" in item && typeof item.getFieldDomain === "function";
|
|
112
|
-
}
|
|
113
|
-
function isSubtypeFieldCapableLayer(item) {
|
|
114
|
-
return !!item && typeof item === "object" && "subtypeField" in item;
|
|
115
|
-
}
|
|
116
|
-
function isSubtypesCapableLayer(item) {
|
|
117
|
-
return isSubtypeFieldCapableLayer(item) && "subtypes" in item;
|
|
118
|
-
}
|
|
119
|
-
function isRelationshipsCapableLayer(item) {
|
|
120
|
-
return (isLayerIdCapableSource(item) &&
|
|
121
|
-
"relationships" in item &&
|
|
122
|
-
"url" in item &&
|
|
123
|
-
Array.isArray(item.relationships) &&
|
|
124
|
-
typeof item.url === "string");
|
|
125
|
-
}
|
|
126
|
-
function isTableCapableLayer(item) {
|
|
127
|
-
return !!item && typeof item === "object" && "isTable" in item && typeof item.isTable === "boolean";
|
|
128
|
-
}
|
|
129
|
-
function isLoadableSource(item) {
|
|
130
|
-
return !!item && typeof item === "object" && "load" in item && typeof item.load === "function";
|
|
131
|
-
}
|
|
132
|
-
//#endregion
|
|
133
|
-
//#region Service Metadata
|
|
134
|
-
async function supportedSourceFromDefinition(definition) {
|
|
135
|
-
if (!definition) {
|
|
136
|
-
return null;
|
|
137
|
-
}
|
|
138
|
-
let source = null;
|
|
139
|
-
if (isFieldsDefinition(definition)) {
|
|
140
|
-
source = definition;
|
|
141
|
-
}
|
|
142
|
-
else {
|
|
143
|
-
source = await newLayersFeatureLayer(definition);
|
|
144
|
-
}
|
|
145
|
-
if (isLoadableSource(source)) {
|
|
146
|
-
await source.load();
|
|
147
|
-
}
|
|
148
|
-
return source;
|
|
12
|
+
/**
|
|
13
|
+
* Returns the arcade diagnostic service.
|
|
14
|
+
* Example:
|
|
15
|
+
* ```ts
|
|
16
|
+
* const diagnosticService = await getArcadeDiagnosticService();
|
|
17
|
+
* diagnosticService.onDidChangeDiagnostics(({uri, diaganostics }) => {
|
|
18
|
+
* // Filter the diagnostics for the uri of interest
|
|
19
|
+
* // Do something with the diagnostics
|
|
20
|
+
* });
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
async function getArcadeDiagnosticService() {
|
|
24
|
+
const mode = await getMode();
|
|
25
|
+
return mode.getArcadeDiagnosticService();
|
|
149
26
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
27
|
+
/**
|
|
28
|
+
* Returns the arcade worker for the model.
|
|
29
|
+
* Example:
|
|
30
|
+
* ```ts
|
|
31
|
+
* const arcadeWorker = await getArcadeWorker(model.uri);
|
|
32
|
+
* ```
|
|
33
|
+
* @returns arcade worker
|
|
34
|
+
*/
|
|
35
|
+
async function getArcadeWorker(uri) {
|
|
36
|
+
const mode = await getMode();
|
|
37
|
+
return await mode.getArcadeWorker(uri);
|
|
158
38
|
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
case "Feature Layer":
|
|
166
|
-
case "Oriented Imagery Layer":
|
|
167
|
-
case "Catalog Layer":
|
|
168
|
-
case "Table": {
|
|
169
|
-
const capabilities = layer.capabilities
|
|
170
|
-
? layer.capabilities
|
|
171
|
-
.toLowerCase()
|
|
172
|
-
.split(",")
|
|
173
|
-
.map((value) => value.trim())
|
|
174
|
-
: [];
|
|
175
|
-
return capabilities.includes(queryCapability);
|
|
176
|
-
}
|
|
177
|
-
default:
|
|
178
|
-
return false;
|
|
179
|
-
}
|
|
180
|
-
});
|
|
39
|
+
/**
|
|
40
|
+
* Request the arcade mode
|
|
41
|
+
* @returns arcade mode module
|
|
42
|
+
*/
|
|
43
|
+
async function getMode() {
|
|
44
|
+
return await import('./arcade-mode.js');
|
|
181
45
|
}
|
|
182
|
-
//#endregion
|
|
183
46
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
return
|
|
193
|
-
if (firstField.type === "oid") {
|
|
194
|
-
return -1;
|
|
195
|
-
}
|
|
196
|
-
if (secondField.type === "oid") {
|
|
197
|
-
return 1;
|
|
198
|
-
}
|
|
199
|
-
if (isSubtypeSublayerInstance(layer)) {
|
|
200
|
-
if (firstField.name === layer.parent.subtypeField) {
|
|
201
|
-
return -1;
|
|
202
|
-
}
|
|
203
|
-
if (secondField.name === layer.parent.subtypeField) {
|
|
204
|
-
return 1;
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
if (isSubtypeFieldCapableLayer(layer)) {
|
|
208
|
-
if (firstField.name === layer.subtypeField) {
|
|
209
|
-
return -1;
|
|
210
|
-
}
|
|
211
|
-
if (secondField.name === layer.subtypeField) {
|
|
212
|
-
return 1;
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
if (isFeatureTypesCapableLayer(layer)) {
|
|
216
|
-
if (firstField.name === layer.typeIdField) {
|
|
217
|
-
return -1;
|
|
218
|
-
}
|
|
219
|
-
if (secondField.name === layer.typeIdField) {
|
|
220
|
-
return 1;
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
return firstField.name.localeCompare(secondField.name, "en", { sensitivity: "base" });
|
|
224
|
-
};
|
|
225
|
-
}
|
|
226
|
-
function areAllDomainsInherited(types, field) {
|
|
227
|
-
return types?.every((type) => type.domains?.[field.name]?.type === "inherited") ?? false;
|
|
228
|
-
}
|
|
229
|
-
// const validIdentifierExpr = new RegExp(/^[a-z_$][\w$]*$/gi);
|
|
230
|
-
const validIdentifierExpr = /^[a-z_$][a-z0-9_$]*$/giu;
|
|
231
|
-
function getMemberExpressionProperty(prop, includeDot = true) {
|
|
232
|
-
if (prop.match(validIdentifierExpr)) {
|
|
233
|
-
return `${includeDot ? "." : ""}${prop}`;
|
|
234
|
-
}
|
|
235
|
-
return `["${prop}"]`;
|
|
236
|
-
}
|
|
237
|
-
function assembleMemberExpression(obj, prop) {
|
|
238
|
-
if (!obj) {
|
|
239
|
-
return prop;
|
|
240
|
-
}
|
|
241
|
-
return `${obj}${getMemberExpressionProperty(prop)}`;
|
|
242
|
-
}
|
|
243
|
-
function getMapPortalItem(map) {
|
|
244
|
-
if (isWebMapInstance(map) || isWebSceneInstance(map)) {
|
|
245
|
-
return map.portalItem;
|
|
246
|
-
}
|
|
247
|
-
return null;
|
|
47
|
+
// #region convert editor profile to apiProfile
|
|
48
|
+
/**
|
|
49
|
+
* Converts an editor profile to an api profile.
|
|
50
|
+
* The api profile is an optimized version of the editor profile designed for minimal data transfer between the main thread and the worker.
|
|
51
|
+
*/
|
|
52
|
+
async function arcadeEditorToApiProfile(editorProfile) {
|
|
53
|
+
const { apiVersion, bundles, hiddenApiItems } = editorProfile.toEditorProfileDefinition();
|
|
54
|
+
const variables = await variablesToLSVariable(editorProfile.dictionaryVariables);
|
|
55
|
+
return { apiVersion, bundles, variables, hiddenApiItems: hiddenApiItems?.map((s) => s.toLowerCase()) };
|
|
248
56
|
}
|
|
249
|
-
//#endregion
|
|
250
|
-
//#region Editor Profile to Language Service Profile functions
|
|
251
57
|
async function variablesToLSVariable(editorVariables, kind = CompletionItemKind.Variable) {
|
|
252
58
|
return await Promise.all(editorVariables.map(async (editorVariable) => {
|
|
253
59
|
switch (editorVariable.type) {
|
|
@@ -304,63 +110,8 @@ async function featureToLSFeature(editorFeature, kind) {
|
|
|
304
110
|
}
|
|
305
111
|
// Create properties for the fields and the aliases
|
|
306
112
|
// Also improve the feature completion documentation
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
const aliasProfileValues = [];
|
|
310
|
-
supportedFields(source.fields).forEach((field) => {
|
|
311
|
-
let fieldCompletionDescription = `**${field.name}** \n${field.type}`;
|
|
312
|
-
if (field.description) {
|
|
313
|
-
fieldCompletionDescription += ` \n'${field.description}`;
|
|
314
|
-
}
|
|
315
|
-
if (featureCompletionDescription) {
|
|
316
|
-
featureCompletionDescription += " \n \n";
|
|
317
|
-
}
|
|
318
|
-
featureCompletionDescription += `**${field.name}** (${fieldAlias(field)}) \n${field.type}`;
|
|
319
|
-
if (field.description) {
|
|
320
|
-
featureCompletionDescription += ` \n'${field.description}`;
|
|
321
|
-
}
|
|
322
|
-
// The property for the field
|
|
323
|
-
const type = fieldTypeToArcadeType(field);
|
|
324
|
-
const insertText = getMemberExpressionProperty(field.name, false);
|
|
325
|
-
const description = fieldAlias(field);
|
|
326
|
-
fieldProfileValues.push({
|
|
327
|
-
name: field.name,
|
|
328
|
-
description,
|
|
329
|
-
type,
|
|
330
|
-
completion: {
|
|
331
|
-
label: field.name,
|
|
332
|
-
detail: description,
|
|
333
|
-
insertText,
|
|
334
|
-
insertTextMode: InsertTextMode.asIs,
|
|
335
|
-
insertTextFormat: InsertTextFormat.PlainText,
|
|
336
|
-
kind: CompletionItemKind.Field,
|
|
337
|
-
documentation: { kind: "markdown", value: fieldCompletionDescription },
|
|
338
|
-
},
|
|
339
|
-
});
|
|
340
|
-
if (!field.alias || field.alias.toLowerCase() === field.name.toLowerCase()) {
|
|
341
|
-
return;
|
|
342
|
-
}
|
|
343
|
-
// The property for the alias if different than the field name
|
|
344
|
-
let aliasCompletionDescription = `**${field.alias}** \n${field.type}`;
|
|
345
|
-
if (field.description) {
|
|
346
|
-
aliasCompletionDescription += ` \n'${field.description}`;
|
|
347
|
-
}
|
|
348
|
-
aliasProfileValues.push({
|
|
349
|
-
name: field.alias,
|
|
350
|
-
description: field.name,
|
|
351
|
-
type,
|
|
352
|
-
completion: {
|
|
353
|
-
label: field.alias,
|
|
354
|
-
detail: field.name,
|
|
355
|
-
insertText,
|
|
356
|
-
insertTextMode: InsertTextMode.asIs,
|
|
357
|
-
insertTextFormat: InsertTextFormat.PlainText,
|
|
358
|
-
kind: CompletionItemKind.Field,
|
|
359
|
-
documentation: { kind: "markdown", value: aliasCompletionDescription },
|
|
360
|
-
},
|
|
361
|
-
});
|
|
362
|
-
});
|
|
363
|
-
result.properties = [...fieldProfileValues, ...aliasProfileValues];
|
|
113
|
+
const [properties, featureCompletionDescription] = fieldsToProfileValues(source.fields, description, true);
|
|
114
|
+
result.properties = properties;
|
|
364
115
|
resultCompletion.documentation = { kind: "markdown", value: featureCompletionDescription };
|
|
365
116
|
return result;
|
|
366
117
|
}
|
|
@@ -394,945 +145,8 @@ async function dictionaryToLSDictionary(editorDictionary, kind) {
|
|
|
394
145
|
},
|
|
395
146
|
};
|
|
396
147
|
}
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
* rendering in the editor. In addition to the representation of profile variables, other
|
|
400
|
-
* structures are created such as groups.
|
|
401
|
-
*/
|
|
402
|
-
class ProfileItemBase {
|
|
403
|
-
constructor(_profile, _label, description) {
|
|
404
|
-
this._profile = _profile;
|
|
405
|
-
this._label = _label;
|
|
406
|
-
this.description = description;
|
|
407
|
-
this.filterDescription = false;
|
|
408
|
-
}
|
|
409
|
-
/**
|
|
410
|
-
* Returns the label string.
|
|
411
|
-
*/
|
|
412
|
-
getLabel() {
|
|
413
|
-
if (this._label == null) {
|
|
414
|
-
return "";
|
|
415
|
-
}
|
|
416
|
-
if (typeof this._label === "string") {
|
|
417
|
-
// Some of our variables can start with a $ sign.
|
|
418
|
-
// If the component is under RTL, the string is messed up.
|
|
419
|
-
// It is converted from $feature to feature$, This is not acceptable since the label
|
|
420
|
-
// represents a variable name. We are adding in front of the $ sign a right to left mark.
|
|
421
|
-
return addLTRMark(this._label);
|
|
422
|
-
}
|
|
423
|
-
return setValuesInString(this._profile?.intlStrings[this._label.code], this._label.formatValues);
|
|
424
|
-
}
|
|
425
|
-
/**
|
|
426
|
-
* Returns the description string.
|
|
427
|
-
*/
|
|
428
|
-
getDescription() {
|
|
429
|
-
if (this.description == null) {
|
|
430
|
-
return "";
|
|
431
|
-
}
|
|
432
|
-
if (typeof this.description === "string") {
|
|
433
|
-
return this.description;
|
|
434
|
-
}
|
|
435
|
-
return setValuesInString(this._profile?.intlStrings[this.description.code], this.description.formatValues);
|
|
436
|
-
}
|
|
437
|
-
/**
|
|
438
|
-
* Returns true if the item pass the filter test
|
|
439
|
-
*/
|
|
440
|
-
passFilter(filterExpression) {
|
|
441
|
-
if (!filterExpression) {
|
|
442
|
-
return true;
|
|
443
|
-
}
|
|
444
|
-
if (filterExpression.test(this.getLabel())) {
|
|
445
|
-
return true;
|
|
446
|
-
}
|
|
447
|
-
return this.filterDescription && filterExpression.test(this.getDescription());
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
/**
|
|
451
|
-
* The base class for profile variables representation in the EditorProfile.
|
|
452
|
-
*/
|
|
453
|
-
class VariableBase extends ProfileItemBase {
|
|
454
|
-
constructor(props) {
|
|
455
|
-
super(props.profile, props.label, props.description ?? props.declaration?.description);
|
|
456
|
-
this.declaration = props.declaration ?? {};
|
|
457
|
-
this.name = props.declaration?.name ?? "";
|
|
458
|
-
this.snippet = props.snippet ?? "";
|
|
459
|
-
this.nonInteractive = props.nonInteractive ?? false;
|
|
460
|
-
this.filterDescription = props.filterDescription ?? false;
|
|
461
|
-
this.icon = props.icon;
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
/**
|
|
465
|
-
* Represents the IProfileValue.
|
|
466
|
-
*/
|
|
467
|
-
class ValueVariable extends VariableBase {
|
|
468
|
-
constructor(props) {
|
|
469
|
-
super(props);
|
|
470
|
-
this.type = "text";
|
|
471
|
-
this.isCollection = false;
|
|
472
|
-
this.type = props.declaration?.type ?? "text";
|
|
473
|
-
}
|
|
474
|
-
getDescription() {
|
|
475
|
-
if (this.description == null) {
|
|
476
|
-
return this._profile?.intlStrings[this.type.toLowerCase()] ?? "";
|
|
477
|
-
}
|
|
478
|
-
return super.getDescription();
|
|
479
|
-
}
|
|
480
|
-
toProfileVariableDefinition() {
|
|
481
|
-
return { type: this.type, name: "", ...this.declaration };
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
/**
|
|
485
|
-
* Represents the IProfileArray. The main difference is that the IProfileValue type
|
|
486
|
-
* is used as valueType.
|
|
487
|
-
*/
|
|
488
|
-
class ArrayVariable extends VariableBase {
|
|
489
|
-
constructor(props) {
|
|
490
|
-
super(props);
|
|
491
|
-
this.type = "array";
|
|
492
|
-
this.isCollection = false;
|
|
493
|
-
this.elementType = props.declaration?.elementType ?? { type: "number", name: "number" };
|
|
494
|
-
}
|
|
495
|
-
getDescription() {
|
|
496
|
-
if (this.description == null) {
|
|
497
|
-
return this._profile?.intlStrings[this.type.toLowerCase()] ?? "";
|
|
498
|
-
}
|
|
499
|
-
return super.getDescription();
|
|
500
|
-
}
|
|
501
|
-
toProfileVariableDefinition() {
|
|
502
|
-
return { type: this.type, elementType: this.elementType, name: "", ...this.declaration };
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
|
-
/**
|
|
506
|
-
* Represents a collection of items. The collection of items can be synchronous or
|
|
507
|
-
* asynchronous. If the collection is asynchronous then the collection should be
|
|
508
|
-
* loaded by using the function 'load'. The property 'loaded' indicates if the
|
|
509
|
-
* collection is ready or not.
|
|
510
|
-
*/
|
|
511
|
-
class CollectionBasedVariable extends VariableBase {
|
|
512
|
-
constructor(owner, props) {
|
|
513
|
-
super(props);
|
|
514
|
-
this.owner = owner;
|
|
515
|
-
this.isCollection = true;
|
|
516
|
-
this._loaded = true;
|
|
517
|
-
/**
|
|
518
|
-
* The collection of items used to display the profile.
|
|
519
|
-
* If the collection is asynchronous, the 'load' function should
|
|
520
|
-
* be called first before using the items.
|
|
521
|
-
*/
|
|
522
|
-
this.variables = [];
|
|
523
|
-
}
|
|
524
|
-
get breadcrumb() {
|
|
525
|
-
// If there's an owner, prepend its breadcrumb and append the current name
|
|
526
|
-
if (this.owner) {
|
|
527
|
-
const ownerBreadcrumb = this.owner.breadcrumb;
|
|
528
|
-
return ownerBreadcrumb ? `${ownerBreadcrumb} / ${this.name}` : this.name;
|
|
529
|
-
}
|
|
530
|
-
// If there's no owner, this is the root element, so just return its name
|
|
531
|
-
return this.name;
|
|
532
|
-
}
|
|
533
|
-
/**
|
|
534
|
-
* Returns true if the collection has been loaded
|
|
535
|
-
*/
|
|
536
|
-
get loaded() {
|
|
537
|
-
return this._loaded;
|
|
538
|
-
}
|
|
539
|
-
/**
|
|
540
|
-
* Returns an url to the associated information
|
|
541
|
-
*/
|
|
542
|
-
get informationUrl() {
|
|
543
|
-
return null;
|
|
544
|
-
}
|
|
545
|
-
get informationType() {
|
|
546
|
-
return "";
|
|
547
|
-
}
|
|
548
|
-
}
|
|
549
|
-
class GroupOfVariables extends ProfileItemBase {
|
|
550
|
-
constructor(profile, label, variables = []) {
|
|
551
|
-
super(profile, label);
|
|
552
|
-
this.variables = variables;
|
|
553
|
-
this.type = "group";
|
|
554
|
-
this.isCollection = true;
|
|
555
|
-
}
|
|
556
|
-
passFilter() {
|
|
557
|
-
return true;
|
|
558
|
-
}
|
|
559
|
-
}
|
|
560
|
-
class DictionaryVariable extends CollectionBasedVariable {
|
|
561
|
-
constructor(owner, props) {
|
|
562
|
-
super(owner, props);
|
|
563
|
-
this.type = "dictionary";
|
|
564
|
-
/**
|
|
565
|
-
* The variables that the dictionary holds. It is different than the variables.
|
|
566
|
-
* The variables may contain grouping.
|
|
567
|
-
*/
|
|
568
|
-
this.dictionaryVariables = [];
|
|
569
|
-
this.loadPropertyDeclarations(props.declaration?.properties);
|
|
570
|
-
// If we have a snippet then wrap the properties in a group and use the snippet as the heading
|
|
571
|
-
// This is not applicable for root Dictionary such as Profile
|
|
572
|
-
if (this.snippet && this.dictionaryVariables.length) {
|
|
573
|
-
this.variables = [new GroupOfVariables(this._profile, this.snippet, this.dictionaryVariables)];
|
|
574
|
-
}
|
|
575
|
-
}
|
|
576
|
-
async loadSource() {
|
|
577
|
-
// No-op
|
|
578
|
-
}
|
|
579
|
-
loadPropertyDeclarations(declarations) {
|
|
580
|
-
this.dictionaryVariables = this.createVariableInstances(declarations);
|
|
581
|
-
this.variables = this.dictionaryVariables;
|
|
582
|
-
}
|
|
583
|
-
createVariableInstances(declarations) {
|
|
584
|
-
if (!Array.isArray(declarations)) {
|
|
585
|
-
return [];
|
|
586
|
-
}
|
|
587
|
-
const properties = [];
|
|
588
|
-
declarations.forEach((declaration) => {
|
|
589
|
-
const variable = this.createVariableInstance(declaration);
|
|
590
|
-
if (variable) {
|
|
591
|
-
properties.push(variable);
|
|
592
|
-
}
|
|
593
|
-
});
|
|
594
|
-
return properties;
|
|
595
|
-
}
|
|
596
|
-
createVariableInstance(declaration) {
|
|
597
|
-
const snippet = assembleMemberExpression(this.snippet, declaration.name);
|
|
598
|
-
switch (declaration.type) {
|
|
599
|
-
case "number":
|
|
600
|
-
case "text":
|
|
601
|
-
case "boolean":
|
|
602
|
-
case "date":
|
|
603
|
-
case "dateOnly":
|
|
604
|
-
case "time":
|
|
605
|
-
case "geometry":
|
|
606
|
-
case "knowledgeGraph":
|
|
607
|
-
return new ValueVariable({ profile: this._profile, declaration, label: snippet, snippet });
|
|
608
|
-
case "feature":
|
|
609
|
-
return new FeatureVariable(this, { profile: this._profile, declaration, label: snippet, snippet });
|
|
610
|
-
case "featureSet":
|
|
611
|
-
return new FeatureSetVariable(this, { profile: this._profile, declaration, label: snippet, snippet }, [
|
|
612
|
-
new ValueVariable({ profile: this._profile, label: snippet, description: "", snippet }),
|
|
613
|
-
]);
|
|
614
|
-
case "featureSetCollection":
|
|
615
|
-
return new FeatureSetCollectionVariable(this, {
|
|
616
|
-
profile: this._profile,
|
|
617
|
-
declaration,
|
|
618
|
-
label: snippet,
|
|
619
|
-
snippet,
|
|
620
|
-
});
|
|
621
|
-
case "dictionary":
|
|
622
|
-
return new DictionaryVariable(this, {
|
|
623
|
-
profile: this._profile,
|
|
624
|
-
declaration,
|
|
625
|
-
label: snippet,
|
|
626
|
-
snippet,
|
|
627
|
-
});
|
|
628
|
-
case "array":
|
|
629
|
-
return new ArrayVariable({
|
|
630
|
-
profile: this._profile,
|
|
631
|
-
declaration,
|
|
632
|
-
label: snippet,
|
|
633
|
-
snippet,
|
|
634
|
-
});
|
|
635
|
-
default:
|
|
636
|
-
console.error("Editor profile: Invalid profile variable", declaration);
|
|
637
|
-
return null;
|
|
638
|
-
}
|
|
639
|
-
}
|
|
640
|
-
toProfileVariableDefinition() {
|
|
641
|
-
return {
|
|
642
|
-
type: this.type,
|
|
643
|
-
name: "",
|
|
644
|
-
...this.declaration,
|
|
645
|
-
properties: this.dictionaryVariables.map((variable) => variable.toProfileVariableDefinition()),
|
|
646
|
-
};
|
|
647
|
-
}
|
|
648
|
-
}
|
|
649
|
-
class SourceBasedVariable extends CollectionBasedVariable {
|
|
650
|
-
constructor(owner, props, relationshipsProperties) {
|
|
651
|
-
super(owner, props);
|
|
652
|
-
this.relationshipsProperties = relationshipsProperties;
|
|
653
|
-
this._source = null;
|
|
654
|
-
this._loaded = false;
|
|
655
|
-
this._definition = props.declaration?.definition;
|
|
656
|
-
}
|
|
657
|
-
get title() {
|
|
658
|
-
return isTitleCapableSource(this._source) ? this._source.title : "";
|
|
659
|
-
}
|
|
660
|
-
get url() {
|
|
661
|
-
return isUrlCapableSource(this._source) ? this._source.url : "";
|
|
662
|
-
}
|
|
663
|
-
get informationUrl() {
|
|
664
|
-
if (!this.loaded) {
|
|
665
|
-
return null;
|
|
666
|
-
}
|
|
667
|
-
if (!this.url) {
|
|
668
|
-
return null;
|
|
669
|
-
}
|
|
670
|
-
return isLayerIdCapableSource(this._source) ? `${this.url}/${this._source.layerId}` : this.url;
|
|
671
|
-
}
|
|
672
|
-
get informationType() {
|
|
673
|
-
return this._profile?.intlStrings.layer ?? "layer";
|
|
674
|
-
}
|
|
675
|
-
async loadSource() {
|
|
676
|
-
if (isNotNull(this._loadPromise) && isNotUndefined(this._loadPromise)) {
|
|
677
|
-
return await this._loadPromise;
|
|
678
|
-
}
|
|
679
|
-
this._loadPromise = this._loadSource();
|
|
680
|
-
return await this._loadPromise;
|
|
681
|
-
}
|
|
682
|
-
_getValueSnippet(field) {
|
|
683
|
-
// If the source is a feature, then we want to assemble the snippet ($feature) with the field name as a member expression
|
|
684
|
-
return this.type === "feature" ? assembleMemberExpression(this.snippet, field.name) : field.name;
|
|
685
|
-
}
|
|
686
|
-
_getSubtypeOrDomainNameSnippet(field) {
|
|
687
|
-
if (this.type !== "feature") {
|
|
688
|
-
return null;
|
|
689
|
-
}
|
|
690
|
-
if (isSubtypeFieldCapableLayer(this._source) && field.name === this._source.subtypeField) {
|
|
691
|
-
return `SubtypeName(${this.snippet})`;
|
|
692
|
-
}
|
|
693
|
-
return `DomainName(${this.snippet}, "${field.name}")`;
|
|
694
|
-
}
|
|
695
|
-
_getFieldProperty(field) {
|
|
696
|
-
// Check if the field is the type id field or of the field has a coded domain.
|
|
697
|
-
// If it has then the property will be an exanpdable property (dictionary).
|
|
698
|
-
// Otherwise just return a simple value property.
|
|
699
|
-
const subtypesOrDomainValuesDictionary = this._getDomainDictionary(field);
|
|
700
|
-
if (subtypesOrDomainValuesDictionary) {
|
|
701
|
-
return subtypesOrDomainValuesDictionary;
|
|
702
|
-
}
|
|
703
|
-
// Create the value property
|
|
704
|
-
const valueSnippet = this._getValueSnippet(field);
|
|
705
|
-
return new ValueVariable({
|
|
706
|
-
profile: this._profile,
|
|
707
|
-
label: valueSnippet,
|
|
708
|
-
description: fieldAlias(field),
|
|
709
|
-
snippet: valueSnippet,
|
|
710
|
-
icon: fieldTypeToIconName(field),
|
|
711
|
-
filterDescription: true,
|
|
712
|
-
});
|
|
713
|
-
}
|
|
714
|
-
_getDomainDictionary(field) {
|
|
715
|
-
if (!isDomainsCapableLayer(this._source)) {
|
|
716
|
-
return null;
|
|
717
|
-
}
|
|
718
|
-
// Note we have multiple scenarios:
|
|
719
|
-
// - Layers without subtypes or feature types: We will check if the field has a domain
|
|
720
|
-
// - Layers with only subtypes: We will parse the subtypes metadata and create a dictionary
|
|
721
|
-
// - Layers with only feature types: We will parse the feature types metadata
|
|
722
|
-
// - Layers with both subtypes and feature types: we will actually use the subtypes metadata
|
|
723
|
-
// Summary, we will always use the subtypes metadata if available.
|
|
724
|
-
if (isSubtypeFieldCapableLayer(this._source) && !!this._source.subtypeField) {
|
|
725
|
-
return this._getSubtypeDomainDictionary(field);
|
|
726
|
-
}
|
|
727
|
-
if (isFeatureTypesCapableLayer(this._source) && !!this._source.typeIdField) {
|
|
728
|
-
return this._getFeatureTypeDomainDictionary(field);
|
|
729
|
-
}
|
|
730
|
-
return this._getFieldDomainDictionary(field);
|
|
731
|
-
}
|
|
732
|
-
_getSubtypeDomainDictionary(field) {
|
|
733
|
-
// Should be tested before calling this function
|
|
734
|
-
if (!isSubtypeFieldCapableLayer(this._source)) {
|
|
735
|
-
return null;
|
|
736
|
-
}
|
|
737
|
-
// If the source has a subtype field but doesn't have subtypes, it is certainly a subtype sublayer
|
|
738
|
-
if (!isSubtypesCapableLayer(this._source)) {
|
|
739
|
-
// For the subtype field there is no domain
|
|
740
|
-
if (field.name === this._source.subtypeField) {
|
|
741
|
-
return null;
|
|
742
|
-
}
|
|
743
|
-
// For the other fields, we will use the getFieldDomain function
|
|
744
|
-
return this._getFieldDomainDictionary(field);
|
|
745
|
-
}
|
|
746
|
-
// The code here shoud be executed for layers that have subtypes
|
|
747
|
-
// Sepcial case for the subtype field
|
|
748
|
-
if (field.name === this._source.subtypeField) {
|
|
749
|
-
const domainDictionary = this._createDomainDictionary(field);
|
|
750
|
-
domainDictionary.icon = "subtype";
|
|
751
|
-
domainDictionary.variables.push(this._getTypeOrSubtypeDomainGroup(this._source.subtypes, field));
|
|
752
|
-
return domainDictionary;
|
|
753
|
-
}
|
|
754
|
-
// Check if all the domains for the field in the types are inherited.
|
|
755
|
-
// If it is we can simplify the structure by avoiding splitting in subtypes
|
|
756
|
-
if (areAllDomainsInherited(this._source.subtypes, field)) {
|
|
757
|
-
return this._getFieldDomainDictionary(field);
|
|
758
|
-
}
|
|
759
|
-
// We have domains per subtype
|
|
760
|
-
// We need to go thru each types and create a dictionary.
|
|
761
|
-
const domainValuesBySubtypeGroup = this._getDomainValuesGroup(this._source.subtypes, field);
|
|
762
|
-
if (!domainValuesBySubtypeGroup) {
|
|
763
|
-
return null;
|
|
764
|
-
}
|
|
765
|
-
const domainDictionary = this._createDomainDictionary(field);
|
|
766
|
-
domainDictionary.variables.push(domainValuesBySubtypeGroup);
|
|
767
|
-
return domainDictionary;
|
|
768
|
-
}
|
|
769
|
-
_getFeatureTypeDomainDictionary(field) {
|
|
770
|
-
// SHould be tested before calling this function
|
|
771
|
-
if (!isFeatureTypesCapableLayer(this._source)) {
|
|
772
|
-
return null;
|
|
773
|
-
}
|
|
774
|
-
// Special case for the type id field
|
|
775
|
-
if (field.name === this._source.typeIdField) {
|
|
776
|
-
const domainDictionary = this._createDomainDictionary(field);
|
|
777
|
-
domainDictionary.variables.push(this._getTypeOrSubtypeDomainGroup(this._source.types, field));
|
|
778
|
-
return domainDictionary;
|
|
779
|
-
}
|
|
780
|
-
// Check if all the domains for the field in the types are inherited.
|
|
781
|
-
// If it is we can simplify the structure by avoiding splitting in subtypes
|
|
782
|
-
if (areAllDomainsInherited(this._source.types, field)) {
|
|
783
|
-
return this._getFieldDomainDictionary(field);
|
|
784
|
-
}
|
|
785
|
-
// We have domains per feature type
|
|
786
|
-
// We need to go thru each types and create a dictionary.
|
|
787
|
-
const domainValuesByFeatureTypeGroup = this._getDomainValuesGroup(this._source.types, field);
|
|
788
|
-
if (!domainValuesByFeatureTypeGroup) {
|
|
789
|
-
return null;
|
|
790
|
-
}
|
|
791
|
-
const domainDictionary = this._createDomainDictionary(field);
|
|
792
|
-
domainDictionary.variables.push(domainValuesByFeatureTypeGroup);
|
|
793
|
-
return domainDictionary;
|
|
794
|
-
}
|
|
795
|
-
_getFieldDomainDictionary(field) {
|
|
796
|
-
// SHould be tested before calling this function
|
|
797
|
-
if (!isDomainsCapableLayer(this._source)) {
|
|
798
|
-
return null;
|
|
799
|
-
}
|
|
800
|
-
const fieldDomain = this._source.getFieldDomain(field.name);
|
|
801
|
-
if (!isCodedValueDomainInstance(fieldDomain)) {
|
|
802
|
-
return null;
|
|
803
|
-
}
|
|
804
|
-
const domainValuesGroup = this._getCodedValueDomainGroup(fieldDomain, {
|
|
805
|
-
code: "domainvalues",
|
|
806
|
-
});
|
|
807
|
-
const domainDictionary = this._createDomainDictionary(field);
|
|
808
|
-
domainDictionary.variables.push(domainValuesGroup);
|
|
809
|
-
return domainDictionary;
|
|
810
|
-
}
|
|
811
|
-
_getTypeOrSubtypeDomainGroup(types, field) {
|
|
812
|
-
// Try the coded domain first
|
|
813
|
-
if (isCodedValueDomainInstance(field.domain)) {
|
|
814
|
-
return this._getCodedValueDomainGroup(field.domain, { code: "subtypes" });
|
|
815
|
-
}
|
|
816
|
-
// No coded domain, we will manufacture it
|
|
817
|
-
const values = types?.map((t) => {
|
|
818
|
-
const label = isSubtypeInstance(t) ? t.code : t.id;
|
|
819
|
-
return new ValueVariable({
|
|
820
|
-
profile: this._profile,
|
|
821
|
-
label: `${label}`,
|
|
822
|
-
description: t.name,
|
|
823
|
-
snippet: `"${label}"`,
|
|
824
|
-
});
|
|
825
|
-
}) ?? [];
|
|
826
|
-
return new GroupOfVariables(this._profile, { code: "subtypes" }, values);
|
|
827
|
-
}
|
|
828
|
-
_getCodedValueDomainGroup(domain, label) {
|
|
829
|
-
const values = domain.codedValues.map((v) => new ValueVariable({
|
|
830
|
-
profile: this._profile,
|
|
831
|
-
label: `${v.code}`,
|
|
832
|
-
description: v.name,
|
|
833
|
-
snippet: `"${v.code}"`,
|
|
834
|
-
filterDescription: true,
|
|
835
|
-
}));
|
|
836
|
-
return new GroupOfVariables(this._profile, label, values);
|
|
837
|
-
}
|
|
838
|
-
_getDomainValuesGroup(types, field) {
|
|
839
|
-
const variables = [];
|
|
840
|
-
if (!types || types.length === 0) {
|
|
841
|
-
return null;
|
|
842
|
-
}
|
|
843
|
-
types.forEach((type) => {
|
|
844
|
-
let domain = type.domains?.[field.name];
|
|
845
|
-
if (!domain) {
|
|
846
|
-
return;
|
|
847
|
-
}
|
|
848
|
-
if (isInheritedDomainInstance(domain)) {
|
|
849
|
-
domain = field.domain;
|
|
850
|
-
return;
|
|
851
|
-
}
|
|
852
|
-
if (!isCodedValueDomainInstance(domain)) {
|
|
853
|
-
return;
|
|
854
|
-
}
|
|
855
|
-
const alias = fieldAlias(field);
|
|
856
|
-
const domainValuesGroup = this._getCodedValueDomainGroup(domain, {
|
|
857
|
-
code: "domainvaluesfortypeformat",
|
|
858
|
-
formatValues: {
|
|
859
|
-
fieldName: alias,
|
|
860
|
-
typeName: type.name,
|
|
861
|
-
},
|
|
862
|
-
});
|
|
863
|
-
const id = isSubtypeInstance(type) ? type.code : type.id;
|
|
864
|
-
const label = `${id}`;
|
|
865
|
-
const snippet = `"${id}""`;
|
|
866
|
-
const subtypeDictionary = new DictionaryVariable(this, {
|
|
867
|
-
profile: this._profile,
|
|
868
|
-
label,
|
|
869
|
-
snippet,
|
|
870
|
-
description: type.name,
|
|
871
|
-
declaration: { name: alias },
|
|
872
|
-
});
|
|
873
|
-
subtypeDictionary.variables = [domainValuesGroup];
|
|
874
|
-
variables.push(subtypeDictionary);
|
|
875
|
-
});
|
|
876
|
-
if (!variables.length) {
|
|
877
|
-
return null;
|
|
878
|
-
}
|
|
879
|
-
return new GroupOfVariables(this._profile, { code: "domainvaluesbysubtypes" }, variables);
|
|
880
|
-
}
|
|
881
|
-
_createDomainDictionary(field) {
|
|
882
|
-
// Create the domain dictionary.
|
|
883
|
-
// The dictionary will have a header group and a value group.
|
|
884
|
-
// At this point we are only creating the header group in the dictionary.
|
|
885
|
-
const valueSnippet = this._getValueSnippet(field);
|
|
886
|
-
const alias = fieldAlias(field);
|
|
887
|
-
const domainDictionary = new DictionaryVariable(this, {
|
|
888
|
-
profile: this._profile,
|
|
889
|
-
label: valueSnippet,
|
|
890
|
-
description: alias,
|
|
891
|
-
snippet: valueSnippet,
|
|
892
|
-
icon: "form-dropdown",
|
|
893
|
-
declaration: { name: field.name },
|
|
894
|
-
});
|
|
895
|
-
// Add the header group
|
|
896
|
-
const headerGroup = new GroupOfVariables(this._profile, alias, [
|
|
897
|
-
new ValueVariable({
|
|
898
|
-
profile: this._profile,
|
|
899
|
-
label: valueSnippet,
|
|
900
|
-
description: "",
|
|
901
|
-
snippet: valueSnippet,
|
|
902
|
-
}),
|
|
903
|
-
]);
|
|
904
|
-
domainDictionary.variables = [headerGroup];
|
|
905
|
-
// Add the SubtypeName or DomainName snippet if available
|
|
906
|
-
const subtypeOrDomainNameSnippet = this._getSubtypeOrDomainNameSnippet(field);
|
|
907
|
-
if (subtypeOrDomainNameSnippet) {
|
|
908
|
-
headerGroup.variables.push(new ValueVariable({
|
|
909
|
-
profile: this._profile,
|
|
910
|
-
label: subtypeOrDomainNameSnippet,
|
|
911
|
-
description: "",
|
|
912
|
-
snippet: subtypeOrDomainNameSnippet,
|
|
913
|
-
}));
|
|
914
|
-
}
|
|
915
|
-
return domainDictionary;
|
|
916
|
-
}
|
|
917
|
-
async _getRelationshipsProperty() {
|
|
918
|
-
// We need the data store to find the relationship feature layers
|
|
919
|
-
if (!this.relationshipsProperties?.exposeRelationships || !this._profile?.supportFeatureSetFunctions) {
|
|
920
|
-
return null;
|
|
921
|
-
}
|
|
922
|
-
const source = this._source;
|
|
923
|
-
if (!isRelationshipsCapableLayer(source)) {
|
|
924
|
-
return null;
|
|
925
|
-
}
|
|
926
|
-
const relationshipsGroup = new GroupOfVariables(this._profile, { code: "relationships" });
|
|
927
|
-
const relationshipItems = await Promise.all(source.relationships.map(async (relationship) => {
|
|
928
|
-
const relatedLayer = await getRelatedFeatureLayer(source, relationship);
|
|
929
|
-
if (!isQueryableLayerInstance(relatedLayer)) {
|
|
930
|
-
return null;
|
|
931
|
-
}
|
|
932
|
-
if (relationship.relatedTableId === this.relationshipsProperties?.sourceTableId) {
|
|
933
|
-
// We don't want to show the reverse relationship
|
|
934
|
-
return null;
|
|
935
|
-
}
|
|
936
|
-
const snippet = `FeatureSetByRelationshipName(${this.snippet}, "${relationship.name}")`;
|
|
937
|
-
return new FeatureSetVariable(this, {
|
|
938
|
-
profile: this._profile,
|
|
939
|
-
declaration: { definition: relatedLayer },
|
|
940
|
-
label: relatedLayer.title,
|
|
941
|
-
description: "",
|
|
942
|
-
nonInteractive: true,
|
|
943
|
-
}, [new ValueVariable({ profile: this._profile, label: snippet, description: "", snippet })], { exposeRelationships: true, sourceTableId: source.layerId });
|
|
944
|
-
}));
|
|
945
|
-
relationshipsGroup.variables = relationshipItems.filter(isNotNull);
|
|
946
|
-
if (!relationshipsGroup.variables.length) {
|
|
947
|
-
return null;
|
|
948
|
-
}
|
|
949
|
-
return relationshipsGroup;
|
|
950
|
-
}
|
|
951
|
-
}
|
|
952
|
-
class FeatureVariable extends SourceBasedVariable {
|
|
953
|
-
constructor(owner, props) {
|
|
954
|
-
super(owner, props, { exposeRelationships: true });
|
|
955
|
-
this.type = "feature";
|
|
956
|
-
}
|
|
957
|
-
get title() {
|
|
958
|
-
if (isTitleCapableSource(this._source)) {
|
|
959
|
-
return this._source.title ?? "";
|
|
960
|
-
}
|
|
961
|
-
return { code: "feature" };
|
|
962
|
-
}
|
|
963
|
-
async _loadSource() {
|
|
964
|
-
if (this.loaded) {
|
|
965
|
-
return this._source;
|
|
966
|
-
}
|
|
967
|
-
try {
|
|
968
|
-
this._source = await supportedSourceFromDefinition(this._definition);
|
|
969
|
-
if (!this._source) {
|
|
970
|
-
throw new Error("Invalid definition");
|
|
971
|
-
}
|
|
972
|
-
// The title group and snippet
|
|
973
|
-
const title = isTitleCapableSource(this._source) ? this._source.title ?? "" : "";
|
|
974
|
-
this.variables.push(new GroupOfVariables(this._profile, title, [
|
|
975
|
-
new ValueVariable({
|
|
976
|
-
profile: this._profile,
|
|
977
|
-
label: this.snippet,
|
|
978
|
-
description: "",
|
|
979
|
-
snippet: this.snippet,
|
|
980
|
-
}),
|
|
981
|
-
]));
|
|
982
|
-
// The collection of feature attribute values
|
|
983
|
-
const valuesGroup = new GroupOfVariables(this._profile, { code: "values" });
|
|
984
|
-
this.variables.push(valuesGroup);
|
|
985
|
-
// Add the geometry if it's a feature layer and not a table
|
|
986
|
-
if (isTableCapableLayer(this._source) && !this._source.isTable) {
|
|
987
|
-
const snippet = `Geometry(${this.snippet})`;
|
|
988
|
-
const geometryProperty = new ValueVariable({
|
|
989
|
-
profile: this._profile,
|
|
990
|
-
declaration: { name: snippet },
|
|
991
|
-
label: snippet,
|
|
992
|
-
description: "Geometry",
|
|
993
|
-
snippet,
|
|
994
|
-
icon: "shapes",
|
|
995
|
-
filterDescription: true,
|
|
996
|
-
});
|
|
997
|
-
valuesGroup.variables.push(geometryProperty);
|
|
998
|
-
}
|
|
999
|
-
this._source.fields.sort(sortFields(this._source)).forEach((field) => {
|
|
1000
|
-
valuesGroup.variables.push(this._getFieldProperty(field));
|
|
1001
|
-
});
|
|
1002
|
-
// The relatonships
|
|
1003
|
-
const relationshipsGroup = await this._getRelationshipsProperty();
|
|
1004
|
-
if (relationshipsGroup) {
|
|
1005
|
-
this.variables.push(relationshipsGroup);
|
|
1006
|
-
}
|
|
1007
|
-
}
|
|
1008
|
-
catch (error) {
|
|
1009
|
-
console.error("Error with definition", error, this._definition);
|
|
1010
|
-
this._source = null;
|
|
1011
|
-
}
|
|
1012
|
-
finally {
|
|
1013
|
-
this._loaded = true;
|
|
1014
|
-
}
|
|
1015
|
-
return this._source;
|
|
1016
|
-
}
|
|
1017
|
-
toProfileVariableDefinition() {
|
|
1018
|
-
return { type: this.type, name: "", ...this.declaration, definition: this._definition };
|
|
1019
|
-
}
|
|
1020
|
-
}
|
|
1021
|
-
class FeatureSetVariable extends SourceBasedVariable {
|
|
1022
|
-
constructor(owner, props, featureSetSnippets = [],
|
|
1023
|
-
// Relationships for feature set if only supported if the feature set is actually
|
|
1024
|
-
// representing a relationsip feature layer for a feature source.
|
|
1025
|
-
relationshipProps) {
|
|
1026
|
-
super(owner, props, relationshipProps);
|
|
1027
|
-
this.featureSetSnippets = featureSetSnippets;
|
|
1028
|
-
this.type = "featureSet";
|
|
1029
|
-
}
|
|
1030
|
-
get title() {
|
|
1031
|
-
if (isTitleCapableSource(this._source)) {
|
|
1032
|
-
return this._source.title ?? "";
|
|
1033
|
-
}
|
|
1034
|
-
return { code: "featureset" };
|
|
1035
|
-
}
|
|
1036
|
-
async _loadSource() {
|
|
1037
|
-
if (this.loaded) {
|
|
1038
|
-
return this._source;
|
|
1039
|
-
}
|
|
1040
|
-
try {
|
|
1041
|
-
this._source = await supportedSourceFromDefinition(this._definition);
|
|
1042
|
-
if (!this._source) {
|
|
1043
|
-
throw new Error("Invalid definition");
|
|
1044
|
-
}
|
|
1045
|
-
// The title group and snippet
|
|
1046
|
-
this.variables.push(new GroupOfVariables(this._profile, this.title, this.featureSetSnippets));
|
|
1047
|
-
// Add the fields
|
|
1048
|
-
const fieldsGroup = new GroupOfVariables(this._profile, { code: "fields" });
|
|
1049
|
-
this.variables.push(fieldsGroup);
|
|
1050
|
-
fieldsGroup.variables = this._source.fields
|
|
1051
|
-
.sort(sortFields(this._source))
|
|
1052
|
-
.map((field) => this._getFieldProperty(field));
|
|
1053
|
-
// Add the relationships if enabled
|
|
1054
|
-
const relationshipsGroup = await this._getRelationshipsProperty();
|
|
1055
|
-
if (relationshipsGroup) {
|
|
1056
|
-
this.variables.push(relationshipsGroup);
|
|
1057
|
-
}
|
|
1058
|
-
}
|
|
1059
|
-
catch (error) {
|
|
1060
|
-
console.error("Error with definition", error, this._definition);
|
|
1061
|
-
this._source = null;
|
|
1062
|
-
}
|
|
1063
|
-
finally {
|
|
1064
|
-
this._loaded = true;
|
|
1065
|
-
}
|
|
1066
|
-
return this._source;
|
|
1067
|
-
}
|
|
1068
|
-
toProfileVariableDefinition() {
|
|
1069
|
-
return { type: this.type, name: "", ...this.declaration, definition: this._definition };
|
|
1070
|
-
}
|
|
1071
|
-
}
|
|
1072
|
-
class FeatureSetCollectionVariable extends CollectionBasedVariable {
|
|
1073
|
-
constructor(owner, props) {
|
|
1074
|
-
super(owner, props);
|
|
1075
|
-
this.type = "featureSetCollection";
|
|
1076
|
-
this._featureSetCollections = null;
|
|
1077
|
-
this._loaded = false;
|
|
1078
|
-
this._definition = props.declaration?.definition;
|
|
1079
|
-
}
|
|
1080
|
-
get informationUrl() {
|
|
1081
|
-
if (!this.loaded || !this._featureSetCollections) {
|
|
1082
|
-
return null;
|
|
1083
|
-
}
|
|
1084
|
-
if (typeof this._featureSetCollections.source !== "string") {
|
|
1085
|
-
return portalItemPageUrl(getMapPortalItem(this._featureSetCollections.source));
|
|
1086
|
-
}
|
|
1087
|
-
// const firstLayer = this._featureSetCollection.layers[0] ?? this._featureSetCollection.tables[0];
|
|
1088
|
-
// if (!firstLayer) {
|
|
1089
|
-
return null;
|
|
1090
|
-
// }
|
|
1091
|
-
// return `${firstLayer.url}`;
|
|
1092
|
-
}
|
|
1093
|
-
get informationType() {
|
|
1094
|
-
if (!this.loaded || !this._featureSetCollections) {
|
|
1095
|
-
return "";
|
|
1096
|
-
}
|
|
1097
|
-
if (typeof this._featureSetCollections.source === "string") {
|
|
1098
|
-
return this._profile?.intlStrings.featureservice ?? "featureservice";
|
|
1099
|
-
}
|
|
1100
|
-
if (isWebSceneInstance(this._featureSetCollections.source)) {
|
|
1101
|
-
return this._profile?.intlStrings.webscene ?? "webscene";
|
|
1102
|
-
}
|
|
1103
|
-
if (isWebMapInstance(this._featureSetCollections.source)) {
|
|
1104
|
-
return this._profile?.intlStrings.webmap ?? "webmap";
|
|
1105
|
-
}
|
|
1106
|
-
return this._profile?.intlStrings.map ?? "map";
|
|
1107
|
-
}
|
|
1108
|
-
async loadSource() {
|
|
1109
|
-
if (isNotNull(this._loadPromise) && isNotUndefined(this._loadPromise)) {
|
|
1110
|
-
return await this._loadPromise;
|
|
1111
|
-
}
|
|
1112
|
-
this._loadPromise = this._loadSource();
|
|
1113
|
-
return await this._loadPromise;
|
|
1114
|
-
}
|
|
1115
|
-
async _loadSource() {
|
|
1116
|
-
if (this.loaded) {
|
|
1117
|
-
return this._featureSetCollections;
|
|
1118
|
-
}
|
|
1119
|
-
try {
|
|
1120
|
-
this._featureSetCollections = await this._featureSetCollectionsFromDefinition();
|
|
1121
|
-
if (!this._featureSetCollections) {
|
|
1122
|
-
throw new Error("Invalid definition");
|
|
1123
|
-
}
|
|
1124
|
-
// Create the group for the header
|
|
1125
|
-
const groupLabel = typeof this._featureSetCollections.source === "string"
|
|
1126
|
-
? { code: this._featureSetCollections.source.endsWith("FeatureServer") ? "featureservice" : "mapservice" }
|
|
1127
|
-
: {
|
|
1128
|
-
code: "webmapformat",
|
|
1129
|
-
formatValues: {
|
|
1130
|
-
webMapTitle: getMapPortalItem(this._featureSetCollections.source)?.title || "Untitled map",
|
|
1131
|
-
},
|
|
1132
|
-
};
|
|
1133
|
-
const headerGroup = new GroupOfVariables(this._profile, groupLabel, [
|
|
1134
|
-
new ValueVariable({
|
|
1135
|
-
profile: this._profile,
|
|
1136
|
-
label: this.snippet,
|
|
1137
|
-
description: "",
|
|
1138
|
-
snippet: this.snippet,
|
|
1139
|
-
}),
|
|
1140
|
-
]);
|
|
1141
|
-
// Creates the groups for the layer and tables
|
|
1142
|
-
const layersGroup = new GroupOfVariables(this._profile, { code: "layers" }, this._featureSetCollections.layers);
|
|
1143
|
-
const tablesGroup = new GroupOfVariables(this._profile, { code: "tables" }, this._featureSetCollections.tables);
|
|
1144
|
-
this.variables.push(headerGroup, layersGroup, tablesGroup);
|
|
1145
|
-
}
|
|
1146
|
-
catch (error) {
|
|
1147
|
-
console.error("Error with definition", error, this._definition);
|
|
1148
|
-
this._featureSetCollections = null;
|
|
1149
|
-
}
|
|
1150
|
-
finally {
|
|
1151
|
-
this._loaded = true;
|
|
1152
|
-
}
|
|
1153
|
-
return this._featureSetCollections;
|
|
1154
|
-
}
|
|
1155
|
-
async _featureSetCollectionsFromDefinition() {
|
|
1156
|
-
if (!this._definition) {
|
|
1157
|
-
return null;
|
|
1158
|
-
}
|
|
1159
|
-
if (isMapInstance(this._definition)) {
|
|
1160
|
-
return await this._featureSetCollectionFromMap(this._definition);
|
|
1161
|
-
}
|
|
1162
|
-
if (isUrlDefinition(this._definition)) {
|
|
1163
|
-
return await this._featureSetCollectionFromUrl(this._definition.url);
|
|
1164
|
-
}
|
|
1165
|
-
if (isPortalItemDefinition(this._definition)) {
|
|
1166
|
-
// Preload the portal item so we can discover if are dealing with a Web Map
|
|
1167
|
-
// or Feature Service
|
|
1168
|
-
return await this._featureSetCollectionFromPortalItem(this._definition.portalItem);
|
|
1169
|
-
}
|
|
1170
|
-
return null;
|
|
1171
|
-
}
|
|
1172
|
-
async _featureSetCollectionFromMap(map) {
|
|
1173
|
-
if (isLoadableMapInstance(map)) {
|
|
1174
|
-
// Make sure the map is loaded
|
|
1175
|
-
await map.loadAll();
|
|
1176
|
-
}
|
|
1177
|
-
// Until jsapi fix a bug we have to load the table separately
|
|
1178
|
-
await Promise.all(map.tables.map(async (t) => (await t.load())));
|
|
1179
|
-
return {
|
|
1180
|
-
layers: this._convertWebMapLayersToVariables(map.layers),
|
|
1181
|
-
tables: this._convertWebMapLayersToVariables(map.tables, true),
|
|
1182
|
-
source: map,
|
|
1183
|
-
};
|
|
1184
|
-
}
|
|
1185
|
-
async _featureSetCollectionFromPortalItem(definition) {
|
|
1186
|
-
const portalItem = await newPortalPortalItem(definition);
|
|
1187
|
-
await portalItem.load();
|
|
1188
|
-
switch (portalItem.type) {
|
|
1189
|
-
case "Web Map": {
|
|
1190
|
-
const webMap = await newWebMap({ portalItem });
|
|
1191
|
-
return await this._featureSetCollectionFromMap(webMap);
|
|
1192
|
-
}
|
|
1193
|
-
case "Web Scene": {
|
|
1194
|
-
const webScene = await newWebScene({ portalItem });
|
|
1195
|
-
return await this._featureSetCollectionFromMap(webScene);
|
|
1196
|
-
}
|
|
1197
|
-
case "Feature Service":
|
|
1198
|
-
return await this._featureSetCollectionFromUrl(portalItem.url);
|
|
1199
|
-
default:
|
|
1200
|
-
console.error("Unsupported portal item", definition);
|
|
1201
|
-
return null;
|
|
1202
|
-
}
|
|
1203
|
-
}
|
|
1204
|
-
async _featureSetCollectionFromUrl(url) {
|
|
1205
|
-
let processedUrl = url.replace(/\/featureserver\/[0-9]*/iu, "/FeatureServer");
|
|
1206
|
-
processedUrl = processedUrl.replace(/\/mapserver\/[0-9]*/iu, "/MapServer");
|
|
1207
|
-
processedUrl = processedUrl.split("?")[0];
|
|
1208
|
-
if (!processedUrl) {
|
|
1209
|
-
return null;
|
|
1210
|
-
}
|
|
1211
|
-
const metadata = await serviceMetaData(processedUrl);
|
|
1212
|
-
const layersPromise = Promise.all(metadata.layers.map(async (layerInfo) => {
|
|
1213
|
-
const featureLayer = await newLayersFeatureLayer({ url: `${processedUrl}/${layerInfo.id}` });
|
|
1214
|
-
await featureLayer.load();
|
|
1215
|
-
return this._createFeatureSetVariable(featureLayer);
|
|
1216
|
-
}));
|
|
1217
|
-
const tablesPromise = Promise.all(metadata.tables.map(async (layerInfo) => {
|
|
1218
|
-
const table = await newLayersFeatureLayer({ url: `${processedUrl}/${layerInfo.id}` });
|
|
1219
|
-
await table.load();
|
|
1220
|
-
return this._createFeatureSetVariable(table);
|
|
1221
|
-
}));
|
|
1222
|
-
const [layers, tables] = await Promise.all([layersPromise, tablesPromise]);
|
|
1223
|
-
return { layers, tables, source: processedUrl };
|
|
1224
|
-
}
|
|
1225
|
-
_convertWebMapLayersToVariables(layers, filteringTables = false) {
|
|
1226
|
-
const layerVariables = [];
|
|
1227
|
-
layers
|
|
1228
|
-
.toArray()
|
|
1229
|
-
.reverse()
|
|
1230
|
-
.forEach((layer) => {
|
|
1231
|
-
if (isQueryableLayerInstance(layer)) {
|
|
1232
|
-
layerVariables.push(this._createFeatureSetVariable(layer, true));
|
|
1233
|
-
return;
|
|
1234
|
-
}
|
|
1235
|
-
if (isGroupLayerInstance(layer)) {
|
|
1236
|
-
const groupLayerVariables = filteringTables
|
|
1237
|
-
? this._convertWebMapLayersToVariables(layer.allTables, true)
|
|
1238
|
-
: this._convertWebMapLayersToVariables(layer.allLayers);
|
|
1239
|
-
layerVariables.push(...groupLayerVariables);
|
|
1240
|
-
}
|
|
1241
|
-
});
|
|
1242
|
-
return layerVariables;
|
|
1243
|
-
}
|
|
1244
|
-
_createFeatureSetVariable(featureLayer, isFromWebMap = false) {
|
|
1245
|
-
return new FeatureSetVariable(this, {
|
|
1246
|
-
profile: this._profile,
|
|
1247
|
-
declaration: { name: featureLayer.title, definition: featureLayer },
|
|
1248
|
-
label: isFromWebMap
|
|
1249
|
-
? featureLayer.title
|
|
1250
|
-
: featureLayer.sourceJSON.name ?? featureLayer.title,
|
|
1251
|
-
description: "",
|
|
1252
|
-
nonInteractive: true,
|
|
1253
|
-
}, this._makeFeatureSetSnippets(featureLayer, isFromWebMap));
|
|
1254
|
-
}
|
|
1255
|
-
_makeFeatureSetSnippets(featureLayer, isFromWebMap = false) {
|
|
1256
|
-
if (!this._profile?.supportFeatureSetFunctions) {
|
|
1257
|
-
return [];
|
|
1258
|
-
}
|
|
1259
|
-
if (isFromWebMap) {
|
|
1260
|
-
const snippetById = `FeatureSetById(${this.snippet}, "${featureLayer.id}")`;
|
|
1261
|
-
const snippetByName = `FeatureSetByName(${this.snippet}, "${featureLayer.title}")`;
|
|
1262
|
-
return [
|
|
1263
|
-
new ValueVariable({ profile: this._profile, label: snippetById, description: "", snippet: snippetById }),
|
|
1264
|
-
new ValueVariable({ profile: this._profile, label: snippetByName, description: "", snippet: snippetByName }),
|
|
1265
|
-
];
|
|
1266
|
-
}
|
|
1267
|
-
else {
|
|
1268
|
-
const snippetById = `FeatureSetById(${this.snippet}, "${featureLayer.layerId}")`;
|
|
1269
|
-
return [new ValueVariable({ profile: this._profile, label: snippetById, description: "", snippet: snippetById })];
|
|
1270
|
-
}
|
|
1271
|
-
}
|
|
1272
|
-
toProfileVariableDefinition() {
|
|
1273
|
-
return { type: this.type, name: "", ...this.declaration, definition: this._definition };
|
|
1274
|
-
}
|
|
1275
|
-
}
|
|
1276
|
-
/**
|
|
1277
|
-
* The EditorProfile is an object that represents an Arcade Profile.
|
|
1278
|
-
* It is used to display the profile in the editor.
|
|
1279
|
-
* It takes an IEditorProfile as a definition and a locale.
|
|
1280
|
-
* A EditorPofile instance
|
|
1281
|
-
* Some of the variables in the profile are based on layers, web maps, or feature services.
|
|
1282
|
-
* They need to be loaded asynchronously to get the metadata necessary for validation and completion.
|
|
1283
|
-
*/
|
|
1284
|
-
class EditorProfile extends DictionaryVariable {
|
|
1285
|
-
constructor(definition, intlStrings, locale = "en") {
|
|
1286
|
-
// Delay the load of the variable declarations so we have a `this`
|
|
1287
|
-
super(undefined, {
|
|
1288
|
-
profile: null,
|
|
1289
|
-
declaration: { properties: [] },
|
|
1290
|
-
});
|
|
1291
|
-
this.definition = definition;
|
|
1292
|
-
this.intlStrings = intlStrings;
|
|
1293
|
-
this.locale = locale;
|
|
1294
|
-
this.variables = [];
|
|
1295
|
-
// We are the root
|
|
1296
|
-
this._profile = this;
|
|
1297
|
-
// Now that `this` is defined, we can load the variables
|
|
1298
|
-
this.loadPropertyDeclarations(definition?.variables);
|
|
1299
|
-
}
|
|
1300
|
-
/**
|
|
1301
|
-
* Returns true if the profile supports feature set functions for snippets.
|
|
1302
|
-
*/
|
|
1303
|
-
get supportFeatureSetFunctions() {
|
|
1304
|
-
return this.definition?.bundles?.includes("data-access") ?? false;
|
|
1305
|
-
}
|
|
1306
|
-
/**
|
|
1307
|
-
* Returns the language service profile. It is different than the editor profile as it is optimized for Monaco.
|
|
1308
|
-
*/
|
|
1309
|
-
async toLSProfile() {
|
|
1310
|
-
const { apiVersion, bundles, hiddenApiItems } = this.definition ?? {};
|
|
1311
|
-
const variables = await variablesToLSVariable(this.dictionaryVariables);
|
|
1312
|
-
return { apiVersion, bundles, variables, hiddenApiItems: hiddenApiItems?.map((s) => s.toLowerCase()) };
|
|
1313
|
-
}
|
|
1314
|
-
/**
|
|
1315
|
-
* Returns the EditorProfile as a json. The EditorProfile may have been updated. This function allows to
|
|
1316
|
-
* get the new json representing mutations.
|
|
1317
|
-
*/
|
|
1318
|
-
toEditorProfileDefinition() {
|
|
1319
|
-
return {
|
|
1320
|
-
...this.definition,
|
|
1321
|
-
variables: this.dictionaryVariables.map((variable) => variable.toProfileVariableDefinition()),
|
|
1322
|
-
};
|
|
1323
|
-
}
|
|
1324
|
-
}
|
|
1325
|
-
//#endregion
|
|
1326
|
-
|
|
1327
|
-
function isFeatureDefinition(item) {
|
|
1328
|
-
return isUrlDefinition(item) || isFieldsDefinition(item) || isFeatureLayerItemDefinition(item);
|
|
1329
|
-
}
|
|
1330
|
-
function isFeatureSetDefinition(item) {
|
|
1331
|
-
return isUrlDefinition(item) || isFieldsDefinition(item) || isFeatureLayerItemDefinition(item);
|
|
1332
|
-
}
|
|
1333
|
-
function isFeatureSetCollectionDefinition(item) {
|
|
1334
|
-
return isPortalItemDefinition(item) || isMapInstance(item) || isSupportedServiceUrlDefinition(item);
|
|
1335
|
-
}
|
|
148
|
+
// #endregion
|
|
149
|
+
// #region predefined profile to editor profile definition
|
|
1336
150
|
/**
|
|
1337
151
|
* Get a PredefinedProfile for a locale. If not already loaded then fetch it.
|
|
1338
152
|
* If the locale doesn't exist or the locale profile file doesn't exist then returns
|
|
@@ -1461,136 +275,7 @@ async function convertToEditorProfileDefinition(predefinedProfile, locale = "en"
|
|
|
1461
275
|
}
|
|
1462
276
|
return editorProfile;
|
|
1463
277
|
}
|
|
1464
|
-
|
|
1465
|
-
/**
|
|
1466
|
-
* Returns the arcade diagnostic service.
|
|
1467
|
-
* Example:
|
|
1468
|
-
* ```ts
|
|
1469
|
-
* const diagnosticService = await getArcadeDiagnosticService();
|
|
1470
|
-
* diagnosticService.onDidChangeDiagnostics(({uri, diaganostics }) => {
|
|
1471
|
-
* // Filter the diagnostics for the uri of interest
|
|
1472
|
-
* // Do something with the diagnostics
|
|
1473
|
-
* });
|
|
1474
|
-
* ```
|
|
1475
|
-
*/
|
|
1476
|
-
async function getArcadeDiagnosticService() {
|
|
1477
|
-
const mode = await getMode();
|
|
1478
|
-
return mode.getArcadeDiagnosticService();
|
|
1479
|
-
}
|
|
1480
|
-
/**
|
|
1481
|
-
* Returns the arcade worker for the model.
|
|
1482
|
-
* Example:
|
|
1483
|
-
* ```ts
|
|
1484
|
-
* const arcadeWorker = await getArcadeWorker(model.uri);
|
|
1485
|
-
* ```
|
|
1486
|
-
* @returns arcade worker
|
|
1487
|
-
*/
|
|
1488
|
-
async function getArcadeWorker(uri) {
|
|
1489
|
-
const mode = await getMode();
|
|
1490
|
-
return await mode.getArcadeWorker(uri);
|
|
1491
|
-
}
|
|
1492
|
-
/**
|
|
1493
|
-
* Request the arcade mode
|
|
1494
|
-
* @returns arcade mode module
|
|
1495
|
-
*/
|
|
1496
|
-
async function getMode() {
|
|
1497
|
-
return await import('./arcade-mode.js');
|
|
1498
|
-
}
|
|
1499
|
-
|
|
1500
|
-
// this file contains the building blocks for a language default provider
|
|
1501
|
-
const defaultContext = {
|
|
1502
|
-
locale: "en",
|
|
1503
|
-
};
|
|
1504
|
-
class LanguageDefaultsBase {
|
|
1505
|
-
constructor() {
|
|
1506
|
-
// #endregion
|
|
1507
|
-
// #region Protected properties
|
|
1508
|
-
this._onDidChange = new Emitter();
|
|
1509
|
-
this._profileMap = new Map();
|
|
1510
|
-
this._apiContextMap = new Map();
|
|
1511
|
-
this._onModelContextDidChange = new Emitter();
|
|
1512
|
-
this._onDidModelContextChangeTimeout = -1;
|
|
1513
|
-
// #endregion
|
|
1514
|
-
}
|
|
1515
|
-
// #endregion
|
|
1516
|
-
// #region Protected methods
|
|
1517
|
-
_fireModelContextDidChange(key) {
|
|
1518
|
-
if (this._onDidModelContextChangeTimeout !== -1) {
|
|
1519
|
-
return;
|
|
1520
|
-
}
|
|
1521
|
-
this._onDidModelContextChangeTimeout = window.setTimeout(() => {
|
|
1522
|
-
this._onDidModelContextChangeTimeout = -1;
|
|
1523
|
-
this._onModelContextDidChange.fire(key);
|
|
1524
|
-
}, 0);
|
|
1525
|
-
}
|
|
1526
|
-
_getApiKey(modelId) {
|
|
1527
|
-
if (!Uri.isUri(modelId)) {
|
|
1528
|
-
modelId = Uri.parse(modelId);
|
|
1529
|
-
}
|
|
1530
|
-
return modelId.toString();
|
|
1531
|
-
}
|
|
1532
|
-
// #endregion
|
|
1533
|
-
// #region Public methods
|
|
1534
|
-
get onDidChange() {
|
|
1535
|
-
return this._onDidChange.event;
|
|
1536
|
-
}
|
|
1537
|
-
get languageOptions() {
|
|
1538
|
-
return this._languageOptions;
|
|
1539
|
-
}
|
|
1540
|
-
/**
|
|
1541
|
-
* Dispose the editor profile for the given model id.
|
|
1542
|
-
* It is the responsibility of the caller that created the editor profile to dispose it.
|
|
1543
|
-
* @param modelId The model id for which to dispose the editor profile.
|
|
1544
|
-
*/
|
|
1545
|
-
disposeEditorProfileForModel(modelId) {
|
|
1546
|
-
const key = this._getApiKey(modelId);
|
|
1547
|
-
this._profileMap.delete(key);
|
|
1548
|
-
}
|
|
1549
|
-
/**
|
|
1550
|
-
* Dispose the api context for the given model id.
|
|
1551
|
-
* @param modelId The model id for which to dispose the api context.
|
|
1552
|
-
*/
|
|
1553
|
-
disposeApiContextForModel(modelId) {
|
|
1554
|
-
const key = this._getApiKey(modelId);
|
|
1555
|
-
if (this._apiContextMap.delete(key)) {
|
|
1556
|
-
this._fireModelContextDidChange(key);
|
|
1557
|
-
}
|
|
1558
|
-
}
|
|
1559
|
-
/**
|
|
1560
|
-
* Returns the editor profile for the given model id.
|
|
1561
|
-
* @param modelId The model id for which to get the editor profile.
|
|
1562
|
-
* @returns The editor profile for the model.
|
|
1563
|
-
*/
|
|
1564
|
-
getEditorProfileForModel(modelId) {
|
|
1565
|
-
return this._profileMap.get(this._getApiKey(modelId));
|
|
1566
|
-
}
|
|
1567
|
-
/**
|
|
1568
|
-
* Returns the API context for the given model id.
|
|
1569
|
-
* Returns the default context if the model has no context.
|
|
1570
|
-
* @param modelId The model id for which to get the API context.
|
|
1571
|
-
* @returns The API context for the model.
|
|
1572
|
-
*/
|
|
1573
|
-
getApiContextForModel(contextId) {
|
|
1574
|
-
return this._apiContextMap.get(this._getApiKey(contextId)) ?? defaultContext;
|
|
1575
|
-
}
|
|
1576
|
-
/**
|
|
1577
|
-
* Set or update api context for the given model id.
|
|
1578
|
-
* @param modelId The model id for which to set the context.
|
|
1579
|
-
* @param apiContext The api context to set.
|
|
1580
|
-
*/
|
|
1581
|
-
updateApiContextForModel(modelId, apiContext) {
|
|
1582
|
-
const key = this._getApiKey(modelId);
|
|
1583
|
-
const currentApiContext = this._apiContextMap.get(key) ?? {};
|
|
1584
|
-
this._apiContextMap.set(key, { ...currentApiContext, ...apiContext });
|
|
1585
|
-
this._fireModelContextDidChange(key);
|
|
1586
|
-
}
|
|
1587
|
-
get onModelContextDidChange() {
|
|
1588
|
-
return this._onModelContextDidChange.event;
|
|
1589
|
-
}
|
|
1590
|
-
get languageId() {
|
|
1591
|
-
return this._languageId;
|
|
1592
|
-
}
|
|
1593
|
-
}
|
|
278
|
+
// #endregion
|
|
1594
279
|
|
|
1595
280
|
const arcadeLanguageId = "arcade";
|
|
1596
281
|
class ArcadeLanguageServiceDefaults extends LanguageDefaultsBase {
|
|
@@ -1614,15 +299,15 @@ class ArcadeLanguageServiceDefaults extends LanguageDefaultsBase {
|
|
|
1614
299
|
if (isPredefinedProfile(definition)) {
|
|
1615
300
|
definition = await convertToEditorProfileDefinition(definition, apiContext.locale);
|
|
1616
301
|
}
|
|
1617
|
-
const
|
|
1618
|
-
if (!
|
|
302
|
+
const profileStrings = await fetchT9nStringsBundle(apiContext.locale, getAssetPath("./assets/arcade-language/t9n"), "profile.t9n.");
|
|
303
|
+
if (!profileStrings) {
|
|
1619
304
|
throw new Error(`Failed to load the language bundle for ${apiContext.locale}`);
|
|
1620
305
|
}
|
|
1621
|
-
this.
|
|
306
|
+
this.disposeForModel(modelId);
|
|
1622
307
|
const key = this._getApiKey(modelId);
|
|
1623
|
-
const editorProfile = new EditorProfile(definition,
|
|
308
|
+
const editorProfile = new EditorProfile(definition, profileStrings);
|
|
1624
309
|
this._profileMap.set(key, editorProfile);
|
|
1625
|
-
const apiProfile = await editorProfile
|
|
310
|
+
const apiProfile = await arcadeEditorToApiProfile(editorProfile);
|
|
1626
311
|
this.updateApiContextForModel(modelId, {
|
|
1627
312
|
locale: apiContext.locale,
|
|
1628
313
|
profile: apiProfile,
|