@komaci/esm-generator 240.1.3
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/build/__tests__/compile-generated-module-fixtures.spec.d.ts +2 -0
- package/build/__tests__/compile-generated-module-fixtures.spec.js +45 -0
- package/build/__tests__/fixtures-combined-files/exclude-comps-unused-import-prop/actual.d.ts +5 -0
- package/build/__tests__/fixtures-combined-files/exclude-comps-unused-import-prop/actual.js +28 -0
- package/build/__tests__/fixtures-combined-files/exclude-partial-classProps-indirect-importRef-getter/actual.d.ts +28 -0
- package/build/__tests__/fixtures-combined-files/exclude-partial-classProps-indirect-importRef-getter/actual.js +144 -0
- package/build/__tests__/fixtures-combined-files/exclude-total-unused-import-getter-from-one/actual.d.ts +8 -0
- package/build/__tests__/fixtures-combined-files/exclude-total-unused-import-getter-from-one/actual.js +35 -0
- package/build/__tests__/fixtures-combined-files/exclude-total-unused-import-getter-from-two/actual.d.ts +9 -0
- package/build/__tests__/fixtures-combined-files/exclude-total-unused-import-getter-from-two/actual.js +39 -0
- package/build/__tests__/fixtures-combined-files/exclude-wire-unused-import-prop/actual.d.ts +6 -0
- package/build/__tests__/fixtures-combined-files/exclude-wire-unused-import-prop/actual.js +34 -0
- package/build/__tests__/fixtures-combined-files/image-type/actual.d.ts +12 -0
- package/build/__tests__/fixtures-combined-files/image-type/actual.js +41 -0
- package/build/__tests__/fixtures-combined-files/include-all-indirect-importRef-getter-complex/actual.d.ts +13 -0
- package/build/__tests__/fixtures-combined-files/include-all-indirect-importRef-getter-complex/actual.js +75 -0
- package/build/__tests__/fixtures-combined-files/include-class-prop-indirect-importRef-getter/actual.d.ts +17 -0
- package/build/__tests__/fixtures-combined-files/include-class-prop-indirect-importRef-getter/actual.js +99 -0
- package/build/__tests__/fixtures-combined-files/include-comps-used-import-prop/actual.d.ts +5 -0
- package/build/__tests__/fixtures-combined-files/include-comps-used-import-prop/actual.js +28 -0
- package/build/__tests__/fixtures-combined-files/include-template-strings/actual.d.ts +9 -0
- package/build/__tests__/fixtures-combined-files/include-template-strings/actual.js +41 -0
- package/build/__tests__/fixtures-combined-files/include-used-import-getter/actual.d.ts +8 -0
- package/build/__tests__/fixtures-combined-files/include-used-import-getter/actual.js +38 -0
- package/build/__tests__/fixtures-combined-files/include-wire-used-import-prop/actual.d.ts +6 -0
- package/build/__tests__/fixtures-combined-files/include-wire-used-import-prop/actual.js +34 -0
- package/build/__tests__/fixtures-combined-files/unsupported-wire-from-supported-namespace/actual.d.ts +5 -0
- package/build/__tests__/fixtures-combined-files/unsupported-wire-from-supported-namespace/actual.js +19 -0
- package/build/__tests__/fixtures-script-files/class-extends-multiple-with-separate-imports/actual.d.ts +8 -0
- package/build/__tests__/fixtures-script-files/class-extends-multiple-with-separate-imports/actual.js +17 -0
- package/build/__tests__/fixtures-script-files/class-extends-separate-imports/actual.d.ts +4 -0
- package/build/__tests__/fixtures-script-files/class-extends-separate-imports/actual.js +13 -0
- package/build/__tests__/fixtures-script-files/class-extends-separate-imports-alias/actual.d.ts +4 -0
- package/build/__tests__/fixtures-script-files/class-extends-separate-imports-alias/actual.js +10 -0
- package/build/__tests__/fixtures-script-files/class-props/actual.d.ts +25 -0
- package/build/__tests__/fixtures-script-files/class-props/actual.js +92 -0
- package/build/__tests__/fixtures-script-files/empty-class/actual.d.ts +3 -0
- package/build/__tests__/fixtures-script-files/empty-class/actual.js +7 -0
- package/build/__tests__/fixtures-script-files/empty-doc/actual.d.ts +1 -0
- package/build/__tests__/fixtures-script-files/empty-doc/actual.js +2 -0
- package/build/__tests__/fixtures-script-files/empty-wire/actual.d.ts +4 -0
- package/build/__tests__/fixtures-script-files/empty-wire/actual.js +16 -0
- package/build/__tests__/fixtures-script-files/exclude-wire-unused-import-prop/actual.d.ts +6 -0
- package/build/__tests__/fixtures-script-files/exclude-wire-unused-import-prop/actual.js +34 -0
- package/build/__tests__/fixtures-script-files/exports/actual.d.ts +21 -0
- package/build/__tests__/fixtures-script-files/exports/actual.js +63 -0
- package/build/__tests__/fixtures-script-files/imports/actual.d.ts +10 -0
- package/build/__tests__/fixtures-script-files/imports/actual.js +76 -0
- package/build/__tests__/fixtures-script-files/imports-namespaced/actual.d.ts +9 -0
- package/build/__tests__/fixtures-script-files/imports-namespaced/actual.js +59 -0
- package/build/__tests__/fixtures-script-files/include-wire-unused-import-prop/actual.d.ts +6 -0
- package/build/__tests__/fixtures-script-files/include-wire-unused-import-prop/actual.js +34 -0
- package/build/__tests__/fixtures-script-files/inheritance-imports-default/actual.d.ts +3 -0
- package/build/__tests__/fixtures-script-files/inheritance-imports-default/actual.js +10 -0
- package/build/__tests__/fixtures-script-files/inheritance-imports-local/actual.d.ts +8 -0
- package/build/__tests__/fixtures-script-files/inheritance-imports-local/actual.js +24 -0
- package/build/__tests__/fixtures-script-files/inheritance-imports-named/actual.d.ts +4 -0
- package/build/__tests__/fixtures-script-files/inheritance-imports-named/actual.js +17 -0
- package/build/__tests__/fixtures-script-files/inheritance-parent-unresolved/actual.d.ts +4 -0
- package/build/__tests__/fixtures-script-files/inheritance-parent-unresolved/actual.js +17 -0
- package/build/__tests__/fixtures-script-files/unsupported-wire-from-supported-namespace/actual.d.ts +5 -0
- package/build/__tests__/fixtures-script-files/unsupported-wire-from-supported-namespace/actual.js +19 -0
- package/build/__tests__/fixtures-script-files/wire-basic/actual.d.ts +7 -0
- package/build/__tests__/fixtures-script-files/wire-basic/actual.js +30 -0
- package/build/__tests__/fixtures-script-files/wire-functions/actual.d.ts +12 -0
- package/build/__tests__/fixtures-script-files/wire-functions/actual.js +46 -0
- package/build/__tests__/fixtures-script-files/wire-imports/actual.d.ts +10 -0
- package/build/__tests__/fixtures-script-files/wire-imports/actual.js +59 -0
- package/build/__tests__/fixtures-source-code/badImportRef.d.ts +4 -0
- package/build/__tests__/fixtures-source-code/badImportRef.js +21 -0
- package/build/__tests__/fixtures-source-code/generalMockSourceCode.d.ts +5 -0
- package/build/__tests__/fixtures-source-code/generalMockSourceCode.js +93 -0
- package/build/__tests__/general-komaci-docs/assorted-template-strings/source.d.ts +9 -0
- package/build/__tests__/general-komaci-docs/assorted-template-strings/source.js +41 -0
- package/build/__tests__/general-komaci-docs/getters-and-compositions-collisions/source.d.ts +6 -0
- package/build/__tests__/general-komaci-docs/getters-and-compositions-collisions/source.js +31 -0
- package/build/__tests__/general-komaci-docs/import-types/source.d.ts +18 -0
- package/build/__tests__/general-komaci-docs/import-types/source.js +104 -0
- package/build/__tests__/general-komaci-docs/import-types/validationStuff.d.ts +18 -0
- package/build/__tests__/general-komaci-docs/import-types/validationStuff.js +63 -0
- package/build/__tests__/general-komaci-docs/template-component/source.d.ts +8 -0
- package/build/__tests__/general-komaci-docs/template-component/source.js +34 -0
- package/build/__tests__/index.spec.d.ts +2 -0
- package/build/__tests__/index.spec.js +124 -0
- package/build/__tests__/komaci-ast-unit.spec.d.ts +2 -0
- package/build/__tests__/komaci-ast-unit.spec.js +628 -0
- package/build/__tests__/komaci-bundle-module.fixtures.spec.d.ts +2 -0
- package/build/__tests__/komaci-bundle-module.fixtures.spec.js +75 -0
- package/build/__tests__/komaci-script-module.fixtures.spec.d.ts +2 -0
- package/build/__tests__/komaci-script-module.fixtures.spec.js +66 -0
- package/build/__tests__/komaci-template-module.fixtures.spec.d.ts +2 -0
- package/build/__tests__/komaci-template-module.fixtures.spec.js +56 -0
- package/build/__tests__/modGenScript.spec.d.ts +2 -0
- package/build/__tests__/modGenScript.spec.js +110 -0
- package/build/__tests__/modGenTemplate.spec.d.ts +2 -0
- package/build/__tests__/modGenTemplate.spec.js +196 -0
- package/build/__tests__/shared.spec.d.ts +2 -0
- package/build/__tests__/shared.spec.js +62 -0
- package/build/__tests__/templateStrings.spec.d.ts +2 -0
- package/build/__tests__/templateStrings.spec.js +130 -0
- package/build/index.d.ts +4 -0
- package/build/index.js +130 -0
- package/build/modGenScript.d.ts +38 -0
- package/build/modGenScript.js +1027 -0
- package/build/modGenTemplate.d.ts +37 -0
- package/build/modGenTemplate.js +402 -0
- package/build/shared.d.ts +170 -0
- package/build/shared.js +588 -0
- package/build/types.d.ts +132 -0
- package/build/types.js +14 -0
- package/package.json +40 -0
|
@@ -0,0 +1,1027 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
+
}) : function(o, v) {
|
|
12
|
+
o["default"] = v;
|
|
13
|
+
});
|
|
14
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
|
+
if (mod && mod.__esModule) return mod;
|
|
16
|
+
var result = {};
|
|
17
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
|
+
__setModuleDefault(result, mod);
|
|
19
|
+
return result;
|
|
20
|
+
};
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
exports.produceErrorAdgFunction = exports.generateCombinedModule = exports.updateImportsWithGetterConsumption = exports.generateScriptModule = void 0;
|
|
23
|
+
/* eslint-disable @typescript-eslint/no-use-before-define */
|
|
24
|
+
const t = __importStar(require("@babel/types"));
|
|
25
|
+
const static_analyzer_1 = require("@komaci/static-analyzer");
|
|
26
|
+
const shared_1 = require("./shared");
|
|
27
|
+
const types_1 = require("./types");
|
|
28
|
+
const modGenTemplate_1 = require("./modGenTemplate");
|
|
29
|
+
const common_shared_1 = require("@komaci/common-shared");
|
|
30
|
+
const IMPORT_TARGET = 'importTarget';
|
|
31
|
+
const FUNC_NAME_IMPORT = 'import';
|
|
32
|
+
const CONST_TYPE = 'const';
|
|
33
|
+
const CONTEXT_MAPPING = {
|
|
34
|
+
cpr: 'CurrentPageReference',
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Generate the resolvable module for a single JS Script
|
|
38
|
+
* @param {GeneratorState} generatorState the state of the ESM generator
|
|
39
|
+
* @param {KomaciDocument} komaciDoc the KomaciDocument representation of the JS Script
|
|
40
|
+
* @returns {File} babel/types File representation of the entire JS Script. In other works, the Abstract systax tree
|
|
41
|
+
* of the generated resolvable module.
|
|
42
|
+
*/
|
|
43
|
+
function generateScriptModule(generatorState, komaciDoc) {
|
|
44
|
+
const statements = [];
|
|
45
|
+
// gathers information about properties in a JS class and whether they are being used by wire functions
|
|
46
|
+
const properties = (0, common_shared_1.collectPropertyMetadataFromScriptDoc)(komaciDoc);
|
|
47
|
+
const src = (0, shared_1.getComponentSrcJs)(generatorState);
|
|
48
|
+
const moduleLevelConsumption = {
|
|
49
|
+
consumedImports: new Map(),
|
|
50
|
+
};
|
|
51
|
+
let processedGetterContext;
|
|
52
|
+
let processedTemplateStrings;
|
|
53
|
+
if (src) {
|
|
54
|
+
const ast = (0, common_shared_1.generateAstFromSrcCode)(src);
|
|
55
|
+
generatorState.scriptGenState.ast = ast;
|
|
56
|
+
const { getters, templateStrings } = (0, common_shared_1.getPropertyMetadataFromAst)(ast);
|
|
57
|
+
const moduleContext = {
|
|
58
|
+
astContext: (0, common_shared_1.getAstContextObject)(ast),
|
|
59
|
+
isExternal: (0, common_shared_1.isExternalModule)(generatorState.input.moduleInfo.namespace),
|
|
60
|
+
};
|
|
61
|
+
generatorState.scriptGenState.importMetadata =
|
|
62
|
+
moduleContext.astContext.importDeclarations;
|
|
63
|
+
// determine which getters are valid, as well as which imports are being by those getters
|
|
64
|
+
processedGetterContext = (0, shared_1.processGetters)(properties, moduleContext, moduleLevelConsumption, getters);
|
|
65
|
+
processedTemplateStrings = (0, shared_1.processTemplateStrings)(properties, moduleContext, moduleLevelConsumption, templateStrings);
|
|
66
|
+
// once we know what getters are using which imports, modify the functions array in the komaci documents
|
|
67
|
+
// (in memory) as well property references in the Properties array
|
|
68
|
+
updateImportsWithGetterConsumption(komaciDoc, moduleLevelConsumption.consumedImports);
|
|
69
|
+
(0, shared_1.updateKomaciDocumentWithValidGetters)(komaciDoc, processedGetterContext);
|
|
70
|
+
(0, shared_1.updateKomaciDocumentWithValidTemplatedStrings)(komaciDoc, processedTemplateStrings);
|
|
71
|
+
}
|
|
72
|
+
// Import default composition if not in-lined into the ADGs.
|
|
73
|
+
importDefaultCompositionIfNotInlinedIntoADG(generatorState, komaciDoc.adgs, statements);
|
|
74
|
+
// Add import declarations for all the Imports in the Komaci doc.
|
|
75
|
+
addImportStatements(generatorState, komaciDoc, statements, moduleLevelConsumption, properties, {
|
|
76
|
+
calledFromGenerateCombinedModule: false,
|
|
77
|
+
});
|
|
78
|
+
// Create map that maintains adg indexes to it's names
|
|
79
|
+
createAdgNameMap(generatorState, komaciDoc);
|
|
80
|
+
// Process the exports in the Komaci doc, including the Adgs which are being exported.
|
|
81
|
+
processExports(generatorState, komaciDoc, statements);
|
|
82
|
+
// Process the adgs that are not exported.
|
|
83
|
+
processNonExportAdgs(generatorState, komaciDoc, statements);
|
|
84
|
+
// add default export from AdgReference (if not already added).
|
|
85
|
+
addDefaultExportFromAdgReferenceIfNoneExists(generatorState, statements);
|
|
86
|
+
// remove invalid imports that are only used in wire adapters
|
|
87
|
+
removeInvalidImportsOnlyUsedInWireAdapter(generatorState, statements);
|
|
88
|
+
// append priming adapter imports and perform any final changes and return generated source file
|
|
89
|
+
const generatedFile = appendPrimingAdapterImportsAndGenerateFinalFile(generatorState, statements);
|
|
90
|
+
// transform getters in the generated source file AST by hoisting them to the module level
|
|
91
|
+
if (processedGetterContext &&
|
|
92
|
+
generatorState.scriptGenState.ast &&
|
|
93
|
+
generatorState.scriptGenState.importMetadata &&
|
|
94
|
+
generatedFile) {
|
|
95
|
+
// needs fully generated, final source file AST, so transformGetters call is done last
|
|
96
|
+
(0, shared_1.transformGetters)(generatedFile, generatorState.scriptGenState.importRefsMap, generatorState.scriptGenState.importMetadata, processedGetterContext);
|
|
97
|
+
}
|
|
98
|
+
if (processedTemplateStrings &&
|
|
99
|
+
generatorState.scriptGenState.ast &&
|
|
100
|
+
generatorState.scriptGenState.importMetadata &&
|
|
101
|
+
generatedFile) {
|
|
102
|
+
(0, shared_1.hoistTemplateStrings)(generatedFile, generatorState.scriptGenState.importRefsMap, generatorState.scriptGenState.importMetadata, processedTemplateStrings);
|
|
103
|
+
}
|
|
104
|
+
return generatedFile;
|
|
105
|
+
}
|
|
106
|
+
exports.generateScriptModule = generateScriptModule;
|
|
107
|
+
/**
|
|
108
|
+
* Given information about what imports a getter consumes, we check the komaci doc to make sure all the
|
|
109
|
+
* import info is available
|
|
110
|
+
* @param komaciScriptDoc The Komaci doc to process
|
|
111
|
+
* @param consumedImports metadata about getter import consumption
|
|
112
|
+
*/
|
|
113
|
+
function updateImportsWithGetterConsumption(komaciScriptDoc, consumedImports) {
|
|
114
|
+
if (!komaciScriptDoc.imports) {
|
|
115
|
+
komaciScriptDoc.imports = [];
|
|
116
|
+
}
|
|
117
|
+
for (const consumedImportInfo of consumedImports.values()) {
|
|
118
|
+
const index = komaciScriptDoc.imports.findIndex((current) => current.resourceName === consumedImportInfo.resourceName);
|
|
119
|
+
if (index !== -1 && !consumedImportInfo.isNamespaceSpecifier) {
|
|
120
|
+
// we update komaciScriptDoc with any import specs that might be missing, from the getter
|
|
121
|
+
// consumption, and not the other way around
|
|
122
|
+
const komaciImportSpecifiers = new Set(komaciScriptDoc.imports[index].names);
|
|
123
|
+
const consumedImportsSpecifiers = Array.from(consumedImportInfo.names);
|
|
124
|
+
consumedImportsSpecifiers.forEach((consumedSpec) => {
|
|
125
|
+
if (!komaciImportSpecifiers.has(consumedSpec) &&
|
|
126
|
+
komaciScriptDoc?.imports) {
|
|
127
|
+
komaciScriptDoc.imports[index].names.push(consumedSpec);
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
else if (index !== -1 && consumedImportInfo.isNamespaceSpecifier) {
|
|
132
|
+
komaciScriptDoc.imports[index].names = ['*'];
|
|
133
|
+
}
|
|
134
|
+
else if (consumedImportInfo.isNamespaceSpecifier) {
|
|
135
|
+
komaciScriptDoc.imports.push({
|
|
136
|
+
resourceName: consumedImportInfo.resourceName,
|
|
137
|
+
names: ['*'],
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
komaciScriptDoc.imports.push({
|
|
142
|
+
resourceName: consumedImportInfo.resourceName,
|
|
143
|
+
names: Array.from(consumedImportInfo.names),
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
exports.updateImportsWithGetterConsumption = updateImportsWithGetterConsumption;
|
|
149
|
+
/**
|
|
150
|
+
* Generates the resolvable runtime module for a script and template file.
|
|
151
|
+
* @param {GeneratorState} generatorState the state of the ESM generator
|
|
152
|
+
* @param {KomaciDocument} komaciScriptDoc the Komaci doc for the script file
|
|
153
|
+
* @param {KomaciDocument} komaciTemplateDoc the Komaci doc for the template file
|
|
154
|
+
* @returns babel/types File representing the generated, combined resolvable runtime module. In other words,
|
|
155
|
+
* the Abstract Syntax Tree of the combined, resolvable module.
|
|
156
|
+
*/
|
|
157
|
+
function generateCombinedModule(generatorState, komaciScriptDoc, komaciTemplateDoc) {
|
|
158
|
+
// script module generation code
|
|
159
|
+
const statements = [];
|
|
160
|
+
// gathers information about properties in a JS class and whether they are being used by wire functions
|
|
161
|
+
const properties = (0, common_shared_1.collectPropertyMetadataFromScriptDoc)(komaciScriptDoc);
|
|
162
|
+
(0, common_shared_1.updatePropertyMetadataFromTemplateDoc)(komaciTemplateDoc, properties);
|
|
163
|
+
const src = (0, shared_1.getComponentSrcJs)(generatorState);
|
|
164
|
+
const moduleLevelConsumption = {
|
|
165
|
+
consumedImports: new Map(),
|
|
166
|
+
};
|
|
167
|
+
let processedGetterContext;
|
|
168
|
+
let processedTemplateStrings;
|
|
169
|
+
if (src) {
|
|
170
|
+
const ast = (0, common_shared_1.generateAstFromSrcCode)(src);
|
|
171
|
+
const { getters, templateStrings } = (0, common_shared_1.getPropertyMetadataFromAst)(ast);
|
|
172
|
+
generatorState.scriptGenState.ast = ast;
|
|
173
|
+
const moduleContext = {
|
|
174
|
+
astContext: (0, common_shared_1.getAstContextObject)(ast),
|
|
175
|
+
isExternal: (0, common_shared_1.isExternalModule)(generatorState.input.moduleInfo.namespace),
|
|
176
|
+
};
|
|
177
|
+
generatorState.scriptGenState.importMetadata =
|
|
178
|
+
moduleContext.astContext.importDeclarations;
|
|
179
|
+
// determine which getters are valid, as well as which imports are being by those getters
|
|
180
|
+
processedGetterContext = (0, shared_1.processGetters)(properties, moduleContext, moduleLevelConsumption, getters);
|
|
181
|
+
processedTemplateStrings = (0, shared_1.processTemplateStrings)(properties, moduleContext, moduleLevelConsumption, templateStrings);
|
|
182
|
+
// once we know what getters are using which imports, modify the functions array in the komaci documents
|
|
183
|
+
// (in memory) as well property references in the Properties array
|
|
184
|
+
updateImportsWithGetterConsumption(komaciScriptDoc, moduleLevelConsumption.consumedImports);
|
|
185
|
+
(0, shared_1.updateKomaciDocumentWithValidGetters)(komaciScriptDoc, processedGetterContext);
|
|
186
|
+
(0, shared_1.updateKomaciDocumentWithValidTemplatedStrings)(komaciScriptDoc, processedTemplateStrings);
|
|
187
|
+
}
|
|
188
|
+
generatorState.inlineTemplateDoc = komaciTemplateDoc;
|
|
189
|
+
if (doesScriptHaveADGs(komaciScriptDoc)) {
|
|
190
|
+
(0, modGenTemplate_1.processTemplateImports)(komaciTemplateDoc, generatorState, statements);
|
|
191
|
+
}
|
|
192
|
+
// Add import declarations for all the Imports in the Komaci doc.
|
|
193
|
+
addImportStatements(generatorState, komaciScriptDoc, statements, moduleLevelConsumption, properties, {
|
|
194
|
+
calledFromGenerateCombinedModule: true,
|
|
195
|
+
});
|
|
196
|
+
// Create map that maintains adg indexes to it's names
|
|
197
|
+
createAdgNameMap(generatorState, komaciScriptDoc);
|
|
198
|
+
// Process the exports in the Komaci doc, including the Adgs which are being exported.
|
|
199
|
+
processExports(generatorState, komaciScriptDoc, statements);
|
|
200
|
+
// Process the adgs that are not exported.
|
|
201
|
+
processNonExportAdgs(generatorState, komaciScriptDoc, statements);
|
|
202
|
+
// add default export if not already added.
|
|
203
|
+
addDefaultExportFromAdgReferenceIfNoneExists(generatorState, statements);
|
|
204
|
+
// add dynamic import for target module (for bundle only)
|
|
205
|
+
addDynamicImportOfTargetModuleForBundle(generatorState, statements);
|
|
206
|
+
// remove invalid imports that are only used in a wire adapter
|
|
207
|
+
removeInvalidImportsOnlyUsedInWireAdapter(generatorState, statements);
|
|
208
|
+
// append priming adapter imports and perform any final changes and return generated source file
|
|
209
|
+
const generatedFile = appendPrimingAdapterImportsAndGenerateFinalFile(generatorState, statements);
|
|
210
|
+
// transform getters in the generated source file AST by hoisting them to the module level
|
|
211
|
+
if (processedGetterContext &&
|
|
212
|
+
generatorState.scriptGenState.ast &&
|
|
213
|
+
generatorState.scriptGenState.importMetadata &&
|
|
214
|
+
generatedFile) {
|
|
215
|
+
// needs fully generated source file AST, so transformGetters call is last
|
|
216
|
+
(0, shared_1.transformGetters)(generatedFile, generatorState.scriptGenState.importRefsMap, generatorState.scriptGenState.importMetadata, processedGetterContext);
|
|
217
|
+
}
|
|
218
|
+
if (processedTemplateStrings &&
|
|
219
|
+
generatorState.scriptGenState.ast &&
|
|
220
|
+
generatorState.scriptGenState.importMetadata &&
|
|
221
|
+
generatedFile) {
|
|
222
|
+
(0, shared_1.hoistTemplateStrings)(generatedFile, generatorState.scriptGenState.importRefsMap, generatorState.scriptGenState.importMetadata, processedTemplateStrings);
|
|
223
|
+
}
|
|
224
|
+
return generatedFile;
|
|
225
|
+
}
|
|
226
|
+
exports.generateCombinedModule = generateCombinedModule;
|
|
227
|
+
/**
|
|
228
|
+
* Performs any remaining modifications and creates a final File representing the entire program.
|
|
229
|
+
*
|
|
230
|
+
* @param {GeneratorState} generatorState the GeneratorState for this module generation run
|
|
231
|
+
* @param {Statement[]} statements t.Statement[] the statements of the analyzed program, up to this point
|
|
232
|
+
* @returns babel/types File, i.e. the AST of generated resolvable module
|
|
233
|
+
*/
|
|
234
|
+
function appendPrimingAdapterImportsAndGenerateFinalFile(generatorState, statements) {
|
|
235
|
+
// append import statements for priming adapters
|
|
236
|
+
const allStatements = [
|
|
237
|
+
...generatorState.scriptGenState.primingAdapterImportDeclarations,
|
|
238
|
+
...statements,
|
|
239
|
+
];
|
|
240
|
+
// generate the program
|
|
241
|
+
const program = t.program(allStatements);
|
|
242
|
+
const file = t.file(program);
|
|
243
|
+
return file;
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Removes invalid imports (or import specifiers therein) that are only used in wire adapter annotation (and nowhere else).
|
|
247
|
+
*
|
|
248
|
+
* Note: While this method does not return anything, it does modify the input Statement array.
|
|
249
|
+
*
|
|
250
|
+
* @param {GeneratorState} generatorState the current state of the esm generator
|
|
251
|
+
* @param {Statement[]} statements t.Statement[] the statements of the analyzed program, up to this point.
|
|
252
|
+
*/
|
|
253
|
+
function removeInvalidImportsOnlyUsedInWireAdapter(generatorState, statements) {
|
|
254
|
+
// gather all of the ImportInfos for the ImportSpecifiers that should be removed
|
|
255
|
+
const importInfosToRemove = findImportInfosToRemove(generatorState);
|
|
256
|
+
// remove ImportSpecifiers and ImportDeclarations as appropriate
|
|
257
|
+
for (const importInfo of importInfosToRemove) {
|
|
258
|
+
const importDeclaration = importInfo.importDeclaration;
|
|
259
|
+
if (importDeclaration?.specifiers && importInfo.importSpecifier) {
|
|
260
|
+
importDeclaration.specifiers.splice(importDeclaration.specifiers.indexOf(importInfo.importSpecifier), 1);
|
|
261
|
+
}
|
|
262
|
+
if (importDeclaration?.specifiers.length === 0) {
|
|
263
|
+
// there are no more valid wire adapters left as specifiers, remove whole import statement
|
|
264
|
+
statements.splice(statements.indexOf(importDeclaration), 1);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* Finds the ImportInfos of the ImportSpecifiers that need to be removed due not representing a
|
|
271
|
+
* supported wire adapter.
|
|
272
|
+
* @param {GeneratorState} generatorState the current state of the esm generator
|
|
273
|
+
* @returns ImportInfo[] corresponding to all ImportSpecifiers that need to be removed because they
|
|
274
|
+
* represent unsupported wire adapters
|
|
275
|
+
*/
|
|
276
|
+
function findImportInfosToRemove(generatorState) {
|
|
277
|
+
const importInfosToRemove = [];
|
|
278
|
+
for (const importInfo of generatorState.scriptGenState.importInfosForWireAdapter) {
|
|
279
|
+
// if it's used by something other than a wire adapter, we can't remove it, so might as well skip this iteration.
|
|
280
|
+
if (importInfo.importUsages.size > 1) {
|
|
281
|
+
continue;
|
|
282
|
+
}
|
|
283
|
+
if (importInfo.primingAdapterImportNames) {
|
|
284
|
+
// if it's for a priming adapter then we want to remove the
|
|
285
|
+
// import for the original wire adapter.
|
|
286
|
+
importInfosToRemove.push(importInfo);
|
|
287
|
+
}
|
|
288
|
+
else if (importInfo.importSpecifier.type === 'ImportSpecifier') {
|
|
289
|
+
// if it's not a supported wire adapter, remove it.
|
|
290
|
+
const identifier = (importInfo.importSpecifier.imported);
|
|
291
|
+
const exportName = identifier.name;
|
|
292
|
+
if (!(0, static_analyzer_1.isSupportedWireAdapter)(importInfo.resourceName, exportName)) {
|
|
293
|
+
importInfosToRemove.push(importInfo);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
return importInfosToRemove;
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Determines whether Komaci JS document has any ADGs defined within it
|
|
301
|
+
* @param {KomaciDocument} komaciScriptDoc a KomaciDocument representation of a Javascript project
|
|
302
|
+
* @returns boolean true is the Komaci JS document has any ADGs defined within it
|
|
303
|
+
*/
|
|
304
|
+
function doesScriptHaveADGs(komaciScriptDoc) {
|
|
305
|
+
return (komaciScriptDoc.adgs?.length || 0) > 0;
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Detects if the composition has not been in-lined into the ADG(s).
|
|
309
|
+
* If not, then generate an import declaration for the default composition file.
|
|
310
|
+
*
|
|
311
|
+
* Note: While this method does not return anything, it does modify the input Statement array.
|
|
312
|
+
*
|
|
313
|
+
* @param {GeneratorState} generatorState the current state of the esm generator
|
|
314
|
+
* @param {Adg[] | undefined} adgs an array of Adg in which to search for compositions
|
|
315
|
+
* @param {Statement[]} statements Array of Statement to be modified by this method
|
|
316
|
+
*/
|
|
317
|
+
function importDefaultCompositionIfNotInlinedIntoADG(generatorState, adgs, statements) {
|
|
318
|
+
if (adgs) {
|
|
319
|
+
const adgNoComposition = adgs.find((adg) => {
|
|
320
|
+
return !adg.compositions || adg.compositions.length === 0;
|
|
321
|
+
});
|
|
322
|
+
if (adgNoComposition) {
|
|
323
|
+
// If we find adg without composition, then we'll need to import
|
|
324
|
+
// it in order to be referenced later.
|
|
325
|
+
const namespace = generatorState.input.moduleInfo.namespace;
|
|
326
|
+
const name = generatorState.input.moduleInfo.name;
|
|
327
|
+
const resource = t.stringLiteral(`@salesforce/komaci/${namespace}__${name}__${name}.html`);
|
|
328
|
+
statements.push(t.importDeclaration([t.importDefaultSpecifier(shared_1.ID.DEFAULT_COMP)], resource));
|
|
329
|
+
generatorState.defaultCompImported = true;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Adds a babel import decleration to the AST for each Komaci import
|
|
335
|
+
*
|
|
336
|
+
* Note: While this method does not return anything, it does modify the input Statement array.
|
|
337
|
+
*
|
|
338
|
+
* @param {GeneratorState} generatorState the current state of the esm generator
|
|
339
|
+
* @param {KomaciDocument} komaciScriptDoc the Komaci doc for the script file
|
|
340
|
+
* @param {Statement[]} statements Array of Statement to be modified by this method for this program
|
|
341
|
+
* @param {ModuleLevelConsumption | undefined} moduleLevelConsumption ModuleLevelConsumption object containing the Map of
|
|
342
|
+
* imports which are being consumed
|
|
343
|
+
* @param {ClassPropertyContexts} properties Map of class properties and all their relevant metadata
|
|
344
|
+
* @param {{ calledFromGenerateCombinedModule: boolean }} options flag to distinguish whether we have been called
|
|
345
|
+
* to generate a combined module or not.
|
|
346
|
+
*/
|
|
347
|
+
function addImportStatements(generatorState, komaciScriptDoc, statements, moduleLevelConsumption, properties, options) {
|
|
348
|
+
const imports = komaciScriptDoc.imports;
|
|
349
|
+
if (imports) {
|
|
350
|
+
for (let importIdx = 0; importIdx < imports.length; ++importIdx) {
|
|
351
|
+
// outer for loop for import statement
|
|
352
|
+
const komaciImport = imports[importIdx];
|
|
353
|
+
const specifiers = [];
|
|
354
|
+
const importInfosForDecl = [];
|
|
355
|
+
for (let nameIdx = 0; nameIdx < komaciImport.names.length; ++nameIdx) {
|
|
356
|
+
// inner for loop for import specifiers
|
|
357
|
+
const exportName = komaciImport.names[nameIdx];
|
|
358
|
+
if ((0, static_analyzer_1.isSupportedNamespace)(komaciImport.resourceName)) {
|
|
359
|
+
++generatorState.importAliasSuffix;
|
|
360
|
+
}
|
|
361
|
+
const localName = (0, static_analyzer_1.isSupportedNamespace)(komaciImport.resourceName)
|
|
362
|
+
? t.identifier(`i${generatorState.importAliasSuffix}`)
|
|
363
|
+
: t.identifier(shared_1.UNRESOLVED);
|
|
364
|
+
let specifier;
|
|
365
|
+
if (exportName === 'default') {
|
|
366
|
+
// e.g. `import i1 from "@salesforce/user/Id";`
|
|
367
|
+
specifier = t.importDefaultSpecifier(localName);
|
|
368
|
+
specifiers.unshift(specifier);
|
|
369
|
+
}
|
|
370
|
+
else if (exportName === '*' && komaciImport.names.length === 1) {
|
|
371
|
+
// e.g. `import i1 from "@salesforce/user/Id";`
|
|
372
|
+
specifier = t.importNamespaceSpecifier(localName);
|
|
373
|
+
specifiers.push(specifier);
|
|
374
|
+
}
|
|
375
|
+
else {
|
|
376
|
+
// e.g. `import { getRecord as i1 } from "lightning/uiRecordApi";`.
|
|
377
|
+
// `getRecord` is the exportName, `i1` is the localName
|
|
378
|
+
specifier = t.importSpecifier(localName, t.identifier(exportName));
|
|
379
|
+
specifiers.push(specifier);
|
|
380
|
+
}
|
|
381
|
+
const importInfo = {
|
|
382
|
+
localName,
|
|
383
|
+
resourceName: komaciImport.resourceName,
|
|
384
|
+
exportName: exportName,
|
|
385
|
+
importUsages: new Set(),
|
|
386
|
+
importSpecifier: specifier,
|
|
387
|
+
importDeclaration: undefined,
|
|
388
|
+
};
|
|
389
|
+
// Helpful state for translation between import ref and local name.
|
|
390
|
+
const importRefId = `${importIdx}/names/${nameIdx}`;
|
|
391
|
+
// skip this if it is an import, whose export is assigned to a memeber, but that member is not used in either a
|
|
392
|
+
// wire input, or in a composition.
|
|
393
|
+
generatorState.scriptGenState.importRefsMap[importRefId] = importInfo;
|
|
394
|
+
// store the ImportInfo in the area for later use
|
|
395
|
+
importInfosForDecl.push(importInfo);
|
|
396
|
+
} // end import inner loop for exports
|
|
397
|
+
// only write the import statement if it is from a supported
|
|
398
|
+
// namespace (in lines above, we still keep the state in the importRefsMap)
|
|
399
|
+
let resourceName = komaciImport.resourceName;
|
|
400
|
+
if ((0, static_analyzer_1.isSupportedNamespace)(resourceName) && specifiers.length > 0) {
|
|
401
|
+
if (options.calledFromGenerateCombinedModule &&
|
|
402
|
+
resourceName.startsWith('@salesforce/komaci')) {
|
|
403
|
+
// @salesforce/komaci/c__foo__foo.js -> @salesforce/komaci/c__foo
|
|
404
|
+
const lastIndex = resourceName.lastIndexOf('__');
|
|
405
|
+
resourceName = resourceName.slice(0, lastIndex);
|
|
406
|
+
}
|
|
407
|
+
const resource = t.stringLiteral(resourceName);
|
|
408
|
+
const importDeclaration = t.importDeclaration(specifiers, resource);
|
|
409
|
+
statements.push(importDeclaration);
|
|
410
|
+
// this object here will need to go into importInfo so it can be located/removed from the statements array later
|
|
411
|
+
importInfosForDecl.forEach((importInfo) => {
|
|
412
|
+
importInfo.importDeclaration = importDeclaration;
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
} // end import outer loop for import declarations
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* Creates a Map that maintains ADG indexes to its corresponding names, generating a new
|
|
420
|
+
* entry if it is not available
|
|
421
|
+
* @param {GeneratorState} generatorState the current state of the esm generator
|
|
422
|
+
* @param {KomaciDocument} komaciScriptDoc the Komaci doc for the script file
|
|
423
|
+
*/
|
|
424
|
+
function createAdgNameMap(generatorState, komaciScriptDoc) {
|
|
425
|
+
const exports = komaciScriptDoc.exports;
|
|
426
|
+
if (exports) {
|
|
427
|
+
Object.keys(exports).forEach((key) => {
|
|
428
|
+
const keyedExport = exports[key];
|
|
429
|
+
if (keyedExport && keyedExport.type === 'AdgReference') {
|
|
430
|
+
generatorState.adgNameMap[keyedExport.value] = key;
|
|
431
|
+
}
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
// generate names if it is not avaialble
|
|
435
|
+
komaciScriptDoc.adgs?.forEach((_adg, index) => {
|
|
436
|
+
if (!generatorState.adgNameMap[index]) {
|
|
437
|
+
generatorState.adgNameMap[index] = 'adg' + index;
|
|
438
|
+
}
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
/**
|
|
442
|
+
* Process exports in the Komaci Script document, which produces functions to return ADG definitions
|
|
443
|
+
*
|
|
444
|
+
* Note: While this method does not return anything, it does modify the input Statement array.
|
|
445
|
+
*
|
|
446
|
+
* @param {GeneratorState} generatorState the current state of the esm generator
|
|
447
|
+
* @param {KomaciDocument} komaciScriptDoc the Komaci doc for the script file
|
|
448
|
+
* @param {Statement[]} statements Array of Statement to be modified by this method for this program
|
|
449
|
+
*/
|
|
450
|
+
function processExports(generatorState, komaciScriptDoc, statements) {
|
|
451
|
+
if (komaciScriptDoc.exports) {
|
|
452
|
+
for (const [exportName, komaciExport] of Object.entries(komaciScriptDoc.exports)) {
|
|
453
|
+
if (komaciExport &&
|
|
454
|
+
(komaciExport.type === 'AdgReference' ||
|
|
455
|
+
komaciExport.type === 'CompositionReference')) {
|
|
456
|
+
// Validate integrity of komaci doc.
|
|
457
|
+
if (!komaciScriptDoc.adgs ||
|
|
458
|
+
komaciExport.value < 0 ||
|
|
459
|
+
komaciExport.value > komaciScriptDoc.adgs.length) {
|
|
460
|
+
throw new Error(shared_1.ERROR_PREFIX +
|
|
461
|
+
'komaciDoc contains invalid ADG or composition references');
|
|
462
|
+
}
|
|
463
|
+
// For each exported Adg create a corresponding export of a function
|
|
464
|
+
// which returns the AdgDefinition described in Resolver API.
|
|
465
|
+
const komaciAdg = komaciScriptDoc.adgs[komaciExport.value];
|
|
466
|
+
const body = getAdgFunctionBody(generatorState, komaciAdg);
|
|
467
|
+
if (exportName === 'default') {
|
|
468
|
+
generatorState.isDefaultExportFound = true;
|
|
469
|
+
// e.g. `export default function (fct, ctx) {`
|
|
470
|
+
statements.push(t.exportDefaultDeclaration(t.functionDeclaration(null, [shared_1.ID.FACTORY, shared_1.ID.CONTEXT], body)));
|
|
471
|
+
}
|
|
472
|
+
else {
|
|
473
|
+
// e.g. `export function MyComponentClass(fct, ctx) {`
|
|
474
|
+
statements.push(t.exportNamedDeclaration(t.functionDeclaration(t.identifier(exportName), [shared_1.ID.FACTORY, shared_1.ID.CONTEXT], body)));
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
/**
|
|
481
|
+
* Processes the ADGs that are not exported
|
|
482
|
+
*
|
|
483
|
+
* Note: While this method does not return anything, it does modify the input Statement array.
|
|
484
|
+
*
|
|
485
|
+
* @param {GeneratorState} generatorState the current state of the esm generator
|
|
486
|
+
* @param {KomaciDocument} komaciScriptDoc the Komaci doc for the script file
|
|
487
|
+
* @param {Statement[]} statements Array of Statement to be modified by this method for this program
|
|
488
|
+
*/
|
|
489
|
+
function processNonExportAdgs(generatorState, komaciScriptDoc, statements) {
|
|
490
|
+
komaciScriptDoc.adgs?.forEach((adg, index) => {
|
|
491
|
+
const localGeneratedName = generatorState.adgNameMap[index];
|
|
492
|
+
if (localGeneratedName.startsWith('adg')) {
|
|
493
|
+
const body = getAdgFunctionBody(generatorState, adg);
|
|
494
|
+
statements.push(t.functionDeclaration(t.identifier(localGeneratedName), [shared_1.ID.FACTORY, shared_1.ID.CONTEXT], body));
|
|
495
|
+
}
|
|
496
|
+
});
|
|
497
|
+
}
|
|
498
|
+
/**
|
|
499
|
+
* Compose the function that calls the `adg` function with all of it's needful info
|
|
500
|
+
* @param {GeneratorState} generatorState the current state of the esm generator
|
|
501
|
+
* @param {Adg} adg The current ADG for which to compose the babel statements
|
|
502
|
+
* @returns the babel statements to represent the function
|
|
503
|
+
*/
|
|
504
|
+
function getAdgFunctionBody(generatorState, adg) {
|
|
505
|
+
const adgFuncCall = adgToExpression(generatorState, adg);
|
|
506
|
+
const fctFuncs = (0, shared_1.getFactoryFuncDeclaration)(generatorState, true);
|
|
507
|
+
const funcStatements = [];
|
|
508
|
+
const body = t.blockStatement(funcStatements);
|
|
509
|
+
// Function body will be destructuring of factory object and the return
|
|
510
|
+
// statement for the adg() function call from Resolver API.
|
|
511
|
+
// e.g. `{ const { adg } = fct; return adg({...}); }`
|
|
512
|
+
if (fctFuncs) {
|
|
513
|
+
funcStatements.push(fctFuncs);
|
|
514
|
+
}
|
|
515
|
+
funcStatements.push(t.returnStatement(adgFuncCall));
|
|
516
|
+
return body;
|
|
517
|
+
}
|
|
518
|
+
/**
|
|
519
|
+
* Adds a default export to the program statements, if no default export that is derived from an AdgReference already exists
|
|
520
|
+
*
|
|
521
|
+
* Note: While this method does not return anything, it does modify the input Statement array.
|
|
522
|
+
*
|
|
523
|
+
* @param {GeneratorState} generatorState The GeneratorState, from which the moduleInfo type is checked
|
|
524
|
+
* @param {Statement[]} statements The babel/types array of Statement, representing statements of the JS Script
|
|
525
|
+
*/
|
|
526
|
+
function addDefaultExportFromAdgReferenceIfNoneExists(generatorState, statements) {
|
|
527
|
+
// If no default export of an AdgReference (e.g. an LWC library module) currently exists, then we
|
|
528
|
+
// must still include one within the generated module.
|
|
529
|
+
if (!generatorState.isDefaultExportFound) {
|
|
530
|
+
statements.push(
|
|
531
|
+
// `export default function () { return undefined; }`
|
|
532
|
+
t.exportDefaultDeclaration(t.functionDeclaration(null, [], t.blockStatement([t.returnStatement(shared_1.ID.UNDEFINED)]))));
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
/**
|
|
536
|
+
* Adds the dynamic import of target module, but only for bundles (if moduleInfo.type === "bundle").
|
|
537
|
+
* This method modifies the input statements array, and does not return anything.
|
|
538
|
+
*
|
|
539
|
+
* Note: While this method does not return anything, it does modify the input Statement array.
|
|
540
|
+
*
|
|
541
|
+
* @param {GeneratorState} generatorState The GeneratorState, from which the moduleInfo type is checked
|
|
542
|
+
* @param {Statement[]} statements The babel/types array of Statement, representing statements of the JS Script
|
|
543
|
+
*/
|
|
544
|
+
function addDynamicImportOfTargetModuleForBundle(generatorState, statements) {
|
|
545
|
+
// dynamic import of target module (generated only if moduleInfo.type is "bundle")
|
|
546
|
+
// e.g.
|
|
547
|
+
// ```
|
|
548
|
+
// export const importTarget = () => {
|
|
549
|
+
// return import("lightning/input");
|
|
550
|
+
// };
|
|
551
|
+
// ```
|
|
552
|
+
if (generatorState?.input?.moduleInfo?.type === 'bundle') {
|
|
553
|
+
statements.push(exportNamedDeclarationForDynamicImport(generatorState));
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
/**
|
|
557
|
+
* Returns an export named declaration. The declaration is assigned an arrowFunctionExpression, which returns
|
|
558
|
+
* a dynamic import based on the moduleInfo namespace and name.
|
|
559
|
+
* @param generatorState The GeneratorState, from which the resourceName for the import is determined
|
|
560
|
+
* @returns ExportNamedDeclaration containing the statement of the dynamic import of the target module
|
|
561
|
+
*/
|
|
562
|
+
function exportNamedDeclarationForDynamicImport(generatorState) {
|
|
563
|
+
const moduleResourceName = generatorState.input.options?.targetModule ||
|
|
564
|
+
generatorState.input.moduleInfo?.namespace +
|
|
565
|
+
'/' +
|
|
566
|
+
generatorState.input.moduleInfo?.name;
|
|
567
|
+
const returnStatement = t.returnStatement(t.callExpression(t.identifier(FUNC_NAME_IMPORT), [
|
|
568
|
+
t.stringLiteral(moduleResourceName),
|
|
569
|
+
]));
|
|
570
|
+
return t.exportNamedDeclaration(t.variableDeclaration(CONST_TYPE, [
|
|
571
|
+
t.variableDeclarator(t.identifier(IMPORT_TARGET), t.arrowFunctionExpression([], t.blockStatement([returnStatement]))),
|
|
572
|
+
]));
|
|
573
|
+
}
|
|
574
|
+
/**
|
|
575
|
+
* Converts a Komaci ADG into a CallExpression to the ADG factory function
|
|
576
|
+
* call for the Resolver API.
|
|
577
|
+
* @param {GeneratorState} generatorState the current state of the esm generator
|
|
578
|
+
* @param {Adg} adg the current ADG to convert into an Expression
|
|
579
|
+
* @returns {t.Expression} Babel Expression representation of the adg() factory function call
|
|
580
|
+
*/
|
|
581
|
+
function adgToExpression(generatorState, adg) {
|
|
582
|
+
const params = [];
|
|
583
|
+
generatorState.scriptGenState.requiredFactoryFunctions.add(shared_1.ID.ADG_FUNC);
|
|
584
|
+
// arg1: Parent Class.
|
|
585
|
+
if (adg.parentClass) {
|
|
586
|
+
let exp;
|
|
587
|
+
if (adg.parentClass.type === 'Unresolved') {
|
|
588
|
+
generatorState.scriptGenState.requiredFactoryFunctions.add(shared_1.ID.UNRESOLVED_VALUE);
|
|
589
|
+
params.push(shared_1.ID.UNRESOLVED_VALUE);
|
|
590
|
+
}
|
|
591
|
+
else if (adg.parentClass.type === 'ImportReference' &&
|
|
592
|
+
!(0, static_analyzer_1.isSupportedNamespace)(generatorState.scriptGenState.importRefsMap[adg.parentClass.value]
|
|
593
|
+
?.resourceName)) {
|
|
594
|
+
generatorState.scriptGenState.requiredFactoryFunctions.add(shared_1.ID.UNRESOLVED_VALUE);
|
|
595
|
+
params.push(shared_1.ID.UNRESOLVED_VALUE);
|
|
596
|
+
}
|
|
597
|
+
else {
|
|
598
|
+
if (adg.parentClass.type === 'AdgReference') {
|
|
599
|
+
const name = generatorState.adgNameMap[adg.parentClass.value];
|
|
600
|
+
exp = t.identifier(name);
|
|
601
|
+
}
|
|
602
|
+
else {
|
|
603
|
+
exp = (0, shared_1.valueToExpression)(generatorState, adg.parentClass, true, types_1.ImportUsageState.parentadg);
|
|
604
|
+
}
|
|
605
|
+
const parentFunc = t.callExpression(exp, [shared_1.ID.FACTORY, shared_1.ID.CONTEXT]);
|
|
606
|
+
params.push(parentFunc);
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
else {
|
|
610
|
+
params.push(shared_1.ID.UNDEFINED);
|
|
611
|
+
}
|
|
612
|
+
// arg2: Properties object.
|
|
613
|
+
if (adg.properties) {
|
|
614
|
+
const objProps = [];
|
|
615
|
+
for (const [propName, propValue] of Object.entries(adg.properties)) {
|
|
616
|
+
objProps.push(t.objectProperty(t.identifier(propName), propertyToExpression(generatorState, adg, propValue)));
|
|
617
|
+
}
|
|
618
|
+
params.push(t.objectExpression(objProps));
|
|
619
|
+
}
|
|
620
|
+
else {
|
|
621
|
+
params.push(t.objectExpression([]));
|
|
622
|
+
}
|
|
623
|
+
// arg3: Functions array.
|
|
624
|
+
const functionsArray = [];
|
|
625
|
+
if (adg.functions) {
|
|
626
|
+
adg.functions.forEach((adgFunc) => {
|
|
627
|
+
const expr = functionToExpression(generatorState, adgFunc);
|
|
628
|
+
if (expr) {
|
|
629
|
+
functionsArray.push(expr);
|
|
630
|
+
}
|
|
631
|
+
else {
|
|
632
|
+
functionsArray.push(null);
|
|
633
|
+
}
|
|
634
|
+
});
|
|
635
|
+
}
|
|
636
|
+
if (functionsArray.length) {
|
|
637
|
+
params.push(t.arrayExpression(functionsArray));
|
|
638
|
+
}
|
|
639
|
+
else {
|
|
640
|
+
params.push(t.arrayExpression([]));
|
|
641
|
+
}
|
|
642
|
+
// arg4: Imported in-line composition function.
|
|
643
|
+
if (generatorState && generatorState.inlineTemplateDoc) {
|
|
644
|
+
const compositions = [];
|
|
645
|
+
if (generatorState.inlineTemplateDoc.compositions &&
|
|
646
|
+
generatorState.inlineTemplateDoc.compositions.length > 0) {
|
|
647
|
+
// current assumption: comp for templateDoc is in first element
|
|
648
|
+
compositions.push(generatorState.inlineTemplateDoc.compositions[0]);
|
|
649
|
+
} // otherwise, if we are processing an empty in-line templateDoc, pass in an empty array
|
|
650
|
+
params.push(getInlineFunctionFromTemplateCompositions(generatorState, compositions));
|
|
651
|
+
}
|
|
652
|
+
else if (generatorState.defaultCompImported) {
|
|
653
|
+
params.push(shared_1.ID.DEFAULT_COMP);
|
|
654
|
+
}
|
|
655
|
+
// arg5: pass properties that the template references (only if processing a bundle)
|
|
656
|
+
if (generatorState.input.moduleInfo.type === 'bundle') {
|
|
657
|
+
// this array of t.stringLiterals may include properties mentioned the Template that aren't necessarily
|
|
658
|
+
// defined in the Script. Resolution engine has logic to handle these
|
|
659
|
+
params.push(t.arrayExpression(Array.from(generatorState.templateGenState.refProps).map((v) => t.stringLiteral(v))));
|
|
660
|
+
}
|
|
661
|
+
else {
|
|
662
|
+
params.push(t.arrayExpression([]));
|
|
663
|
+
}
|
|
664
|
+
return t.callExpression(shared_1.ID.ADG_FUNC, params);
|
|
665
|
+
}
|
|
666
|
+
/**
|
|
667
|
+
* Converts array of template Compositions into a representation that is an inline function
|
|
668
|
+
* @param {GeneratorState} generatorState the current state of esm-generator
|
|
669
|
+
* @param {Composition[]} compositions array of Compositions to convert
|
|
670
|
+
* @returns {t.ArrowFunctionExpression} an inline ArrowFunctionExpression representing the input Compositions
|
|
671
|
+
*/
|
|
672
|
+
function getInlineFunctionFromTemplateCompositions(generatorState, compositions) {
|
|
673
|
+
const params = [shared_1.ID.FACTORY, shared_1.ID.CONTEXT];
|
|
674
|
+
const statements = [];
|
|
675
|
+
const body = t.blockStatement(statements);
|
|
676
|
+
const emptyCompositionsArray = compositions.length < 1;
|
|
677
|
+
const compositionArrayExpr = emptyCompositionsArray
|
|
678
|
+
? t.arrayExpression([])
|
|
679
|
+
: (0, modGenTemplate_1.compositionsToArrayExpression)(generatorState, true, compositions) ||
|
|
680
|
+
t.arrayExpression([]);
|
|
681
|
+
// function body destructured factory object. e.g. `const { cg } = fct;`
|
|
682
|
+
const fctFuncs = (0, shared_1.getFactoryFuncDeclaration)(generatorState, false); // passing in false because we are not processing the script file in this method
|
|
683
|
+
if (fctFuncs && !emptyCompositionsArray) {
|
|
684
|
+
statements.push(fctFuncs);
|
|
685
|
+
}
|
|
686
|
+
statements.push(t.returnStatement(compositionArrayExpr));
|
|
687
|
+
return t.arrowFunctionExpression(params, body);
|
|
688
|
+
}
|
|
689
|
+
/**
|
|
690
|
+
* Convert a single Komaci property to an object expression in the shape of
|
|
691
|
+
* a PropertyDefinition as defined in Resolver API.
|
|
692
|
+
* @param {GeneratorState} generatorState the current state of esm-generator
|
|
693
|
+
* @param {Adg} adg the current ADG from which to seek out FunctionReferences
|
|
694
|
+
* @param {Propery} property the Komaci property to process
|
|
695
|
+
* @returns {Expression} the komaci property converted to an object Expression
|
|
696
|
+
*/
|
|
697
|
+
function propertyToExpression(generatorState, adg, property) {
|
|
698
|
+
const objProps = [];
|
|
699
|
+
// Whether the prop is public or not, e.g. `a: true`.
|
|
700
|
+
objProps.push(t.objectProperty(shared_1.ID.PROP_API, t.booleanLiteral(!!property.isPublic)));
|
|
701
|
+
if (property.initial) {
|
|
702
|
+
// initial value
|
|
703
|
+
// Initial value of the prop, e.g. `i: 5`.
|
|
704
|
+
objProps.push(t.objectProperty(shared_1.ID.PROP_INIT, (0, shared_1.valueToExpression)(generatorState, property.initial, true, types_1.ImportUsageState.initialvalue)));
|
|
705
|
+
}
|
|
706
|
+
if (property.input) {
|
|
707
|
+
if (property.input.type === 'FunctionReference') {
|
|
708
|
+
// Index of function where this property receives input, e.g. `f: 0`.
|
|
709
|
+
const funcIdx = property.input.value;
|
|
710
|
+
if (!adg.functions || funcIdx < 0 || funcIdx >= adg.functions.length) {
|
|
711
|
+
throw new Error(shared_1.ERROR_PREFIX + 'komaciDoc contains invalid function reference');
|
|
712
|
+
}
|
|
713
|
+
// if the property input type is a FunctionReference that refers to a Wire Function, then make sure its
|
|
714
|
+
// corresponding ImportReference does not refer to a unsupported resourceName; if it does, then
|
|
715
|
+
// replace the `f: functionIndex`, with `g: unresolved`
|
|
716
|
+
const resourceKey = adg.functions[funcIdx].reference.value;
|
|
717
|
+
const importInfo = (0, shared_1.retrieveImportInfo)(generatorState, resourceKey, true);
|
|
718
|
+
const resourceName = importInfo?.resourceName;
|
|
719
|
+
const exportName = importInfo?.exportName;
|
|
720
|
+
if (adg.functions[funcIdx].type == shared_1.WIRE_FUNCTION &&
|
|
721
|
+
(adg.functions[funcIdx].reference.type === 'Unresolved' ||
|
|
722
|
+
!(0, static_analyzer_1.isSupportedNamespace)(resourceName) ||
|
|
723
|
+
!(0, static_analyzer_1.isSupportedWireAdapter)(resourceName, exportName))) {
|
|
724
|
+
objProps.push(t.objectProperty(shared_1.ID.PROP_GETTER, shared_1.ID.UNRESOLVED_VALUE));
|
|
725
|
+
generatorState.scriptGenState.requiredFactoryFunctions.add(shared_1.ID.UNRESOLVED_VALUE);
|
|
726
|
+
}
|
|
727
|
+
else {
|
|
728
|
+
objProps.push(t.objectProperty(shared_1.ID.PROP_FUNC, t.numericLiteral(funcIdx)));
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
else {
|
|
732
|
+
// setting up modgen for getter (static values returned via getter)
|
|
733
|
+
// If associated w/ getter, then the hardcoded value from the getter,
|
|
734
|
+
// e.g. `g: 'some hardcoded string'`
|
|
735
|
+
objProps.push(t.objectProperty(shared_1.ID.PROP_GETTER, (0, shared_1.valueToExpression)(generatorState, property.input, true, types_1.ImportUsageState.getter)));
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
return t.objectExpression(objProps);
|
|
739
|
+
}
|
|
740
|
+
/**
|
|
741
|
+
* Convert a single Komaci function to an object expression in the shape of a
|
|
742
|
+
* FunctionDefinition as defined in Resolver API.
|
|
743
|
+
* @param {GeneratorState} generatorState the current esm generator state
|
|
744
|
+
* @param {FunctionType} adgFunc a function from the adg functions arrray.
|
|
745
|
+
* @returns {Expression} a babel Expression if propertly processed or undefined.
|
|
746
|
+
*/
|
|
747
|
+
function functionToExpression(generatorState,
|
|
748
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
749
|
+
adgFunc) {
|
|
750
|
+
let importInfo;
|
|
751
|
+
if (adgFunc.type === shared_1.GETTER_FUNCTION) {
|
|
752
|
+
const getterFuncObjPropArr = processLocalFunction(adgFunc, shared_1.GETTER_FUNCTION);
|
|
753
|
+
return t.objectExpression(getterFuncObjPropArr);
|
|
754
|
+
}
|
|
755
|
+
else if (adgFunc.type === shared_1.TEMPLATED_STRING_FUNCTION) {
|
|
756
|
+
return t.objectExpression(processLocalFunction(adgFunc, shared_1.TEMPLATED_STRING_FUNCTION));
|
|
757
|
+
}
|
|
758
|
+
else if (adgFunc.type === shared_1.ERROR_FUNCTION) {
|
|
759
|
+
return t.objectExpression(processErrorFunction(generatorState, adgFunc));
|
|
760
|
+
}
|
|
761
|
+
// Use import map to set function id to local alias name, e.g. `f: i1`.
|
|
762
|
+
if (adgFunc.reference.type === 'ImportReference') {
|
|
763
|
+
importInfo = (0, shared_1.updateImportInfoState)(generatorState, adgFunc.reference.value, true, types_1.ImportUsageState.wireadapter); // wireadapter import usage
|
|
764
|
+
}
|
|
765
|
+
else {
|
|
766
|
+
// UnresolvedValue
|
|
767
|
+
return undefined;
|
|
768
|
+
}
|
|
769
|
+
// Validate and set function type, e.g. `t: "WireFunction"`
|
|
770
|
+
if (adgFunc.type !== shared_1.WIRE_FUNCTION) {
|
|
771
|
+
throw new Error(shared_1.ERROR_PREFIX + 'ADG function has invalid type');
|
|
772
|
+
}
|
|
773
|
+
const wireFunctionObjArr = processWireFunctionType(importInfo, generatorState, adgFunc);
|
|
774
|
+
if (wireFunctionObjArr) {
|
|
775
|
+
return t.objectExpression(wireFunctionObjArr);
|
|
776
|
+
}
|
|
777
|
+
return undefined;
|
|
778
|
+
}
|
|
779
|
+
function processErrorFunction(generatorState, adgFunc) {
|
|
780
|
+
const funcObjProps = [];
|
|
781
|
+
const t_value = t.stringLiteral(shared_1.ERROR_FUNCTION);
|
|
782
|
+
const configObjExpr = (0, shared_1.valueToExpression)(generatorState,
|
|
783
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
784
|
+
adgFunc.input[0], true, types_1.ImportUsageState.initialvalue);
|
|
785
|
+
funcObjProps.push(t.objectProperty(shared_1.ID.FUNC_TYPE, t_value), t.objectProperty(shared_1.ID.FUNC_CONFIG, configObjExpr));
|
|
786
|
+
return funcObjProps;
|
|
787
|
+
}
|
|
788
|
+
/**
|
|
789
|
+
* Function to create the object property array for a local function
|
|
790
|
+
* @param {FunctionType} adgFunc a function from the adg functions array.
|
|
791
|
+
* @param {string} type The type of function. getter or templated string
|
|
792
|
+
* @returns {ObjectProperty[]} a babel object property array.
|
|
793
|
+
*/
|
|
794
|
+
function processLocalFunction(adgFunc, type) {
|
|
795
|
+
const funcObjProps = [];
|
|
796
|
+
const f_reference = {
|
|
797
|
+
type: 'Identifier',
|
|
798
|
+
name: adgFunc.reference.value,
|
|
799
|
+
leadingComments: null,
|
|
800
|
+
innerComments: null,
|
|
801
|
+
trailingComments: null,
|
|
802
|
+
start: null,
|
|
803
|
+
end: null,
|
|
804
|
+
loc: null,
|
|
805
|
+
};
|
|
806
|
+
const t_value = t.stringLiteral(type);
|
|
807
|
+
funcObjProps.push(t.objectProperty(shared_1.ID.FUNC_ID, f_reference), t.objectProperty(shared_1.ID.FUNC_TYPE, t_value));
|
|
808
|
+
if (adgFunc.input) {
|
|
809
|
+
const inputArray = adgFunc.input.filter((entry) => entry.type === 'ArrayValue')[0];
|
|
810
|
+
const in_value = t.arrayExpression(inputArray.value.map((v) => t.stringLiteral(v.value)));
|
|
811
|
+
funcObjProps.push(t.objectProperty(shared_1.ID.FUNC_INPUT, in_value));
|
|
812
|
+
}
|
|
813
|
+
return funcObjProps;
|
|
814
|
+
}
|
|
815
|
+
/**
|
|
816
|
+
* Function to generate the object property array for a wire function node type.
|
|
817
|
+
*
|
|
818
|
+
* NOTE: if the obj representing the function is from an unsupported namespace, and it
|
|
819
|
+
* is for a wire function, then leave out the function node from the generated resolvable
|
|
820
|
+
* module, by returning undefined.
|
|
821
|
+
* @param {ImportInfo} importInfo import information against which to check the wire function's validity
|
|
822
|
+
* @param {GeneratorState} generatorState the current state of the esm generator
|
|
823
|
+
* @param {FunctionType} adgFunc a wire function from the adg functions array.
|
|
824
|
+
* @returns {ObjectProperty[]} an representation of the wire function node as array of ObjectProperty
|
|
825
|
+
*/
|
|
826
|
+
function processWireFunctionType(importInfo, generatorState, adgFunc) {
|
|
827
|
+
const funcObjProps = [];
|
|
828
|
+
// if the obj representing the function is from an unsupported namespace, and it is for a wire function,
|
|
829
|
+
// then leave out the function node form the generated resolvable module, by returning undefined.
|
|
830
|
+
const resourceName = importInfo.resourceName;
|
|
831
|
+
const exportName = importInfo.exportName;
|
|
832
|
+
if (!exportName ||
|
|
833
|
+
!(0, static_analyzer_1.isSupportedNamespace)(resourceName) ||
|
|
834
|
+
!(0, static_analyzer_1.isSupportedWireAdapter)(resourceName, exportName)) {
|
|
835
|
+
return undefined;
|
|
836
|
+
}
|
|
837
|
+
// If we don't already know, check to see if this is a priming adapter.
|
|
838
|
+
if (!importInfo.primingAdapterImportNames) {
|
|
839
|
+
const primingAdapterDef = (0, static_analyzer_1.getPrimingAdapter)(resourceName, exportName);
|
|
840
|
+
if (primingAdapterDef) {
|
|
841
|
+
// create imports and store local names in this importInfo.
|
|
842
|
+
importInfo.primingAdapterImportNames = createPrimingAdapterImports(generatorState, primingAdapterDef);
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
if (importInfo.primingAdapterImportNames) {
|
|
846
|
+
const primingAdapterDef = importInfo.primingAdapterImportNames.primingAdapterDef;
|
|
847
|
+
// Add props for imports relating to this priming adapter.
|
|
848
|
+
funcObjProps.push(t.objectProperty(shared_1.ID.FUNC_ID, importInfo.primingAdapterImportNames.adapter), t.objectProperty(shared_1.ID.FUNC_NAME, t.stringLiteral(primingAdapterDef.prime.identifier)));
|
|
849
|
+
if (importInfo.primingAdapterImportNames.batchAdapter &&
|
|
850
|
+
primingAdapterDef.batch) {
|
|
851
|
+
funcObjProps.push(t.objectProperty(shared_1.ID.BATCH_FUNC_ID, importInfo.primingAdapterImportNames.batchAdapter), t.objectProperty(shared_1.ID.BATCH_FUNC_NAME, t.stringLiteral(primingAdapterDef.batch.prime.identifier)));
|
|
852
|
+
}
|
|
853
|
+
if (importInfo.primingAdapterImportNames.reducer) {
|
|
854
|
+
funcObjProps.push(t.objectProperty(shared_1.ID.REDUCER_FUNC_ID, importInfo.primingAdapterImportNames.reducer));
|
|
855
|
+
}
|
|
856
|
+
funcObjProps.push(t.objectProperty(shared_1.ID.FUNC_TYPE, t.stringLiteral(shared_1.PRIMING_FUNCTION)));
|
|
857
|
+
}
|
|
858
|
+
else {
|
|
859
|
+
// Traditional wire adapter.
|
|
860
|
+
funcObjProps.push(t.objectProperty(shared_1.ID.FUNC_ID, importInfo.localName), t.objectProperty(shared_1.ID.FUNC_NAME, t.stringLiteral(getWireName(resourceName, exportName))), t.objectProperty(shared_1.ID.FUNC_TYPE, t.stringLiteral(shared_1.WIRE_FUNCTION)));
|
|
861
|
+
// Check if the export name matches one of the supported context wires. If so we set
|
|
862
|
+
// wire type. e.g. `wt: "cpr"`
|
|
863
|
+
if (isSupportedContextWire(exportName)) {
|
|
864
|
+
const contextWireName = Object.keys(CONTEXT_MAPPING).find((key) => CONTEXT_MAPPING[key] === exportName);
|
|
865
|
+
if (contextWireName) {
|
|
866
|
+
funcObjProps.push(t.objectProperty(shared_1.ID.WIRE_TYPE, t.stringLiteral(contextWireName)));
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
else if (isApexWire(resourceName)) {
|
|
870
|
+
funcObjProps.push(t.objectProperty(shared_1.ID.WIRE_TYPE, t.stringLiteral('apex')));
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
// Construct function to return config object and list of input properties.
|
|
874
|
+
let configObjExpr;
|
|
875
|
+
const inputProps = new Set();
|
|
876
|
+
if (adgFunc.input && adgFunc.input.length > 0) {
|
|
877
|
+
if (adgFunc.input.length !== 1 || adgFunc.input[0].type !== 'ObjectValue') {
|
|
878
|
+
// Only valid input according to Wire Adapter Protocol.
|
|
879
|
+
throw new Error(shared_1.ERROR_PREFIX + 'WireFunction has invalid input');
|
|
880
|
+
}
|
|
881
|
+
const inputObject = adgFunc.input[0];
|
|
882
|
+
configObjExpr = (0, shared_1.valueToExpression)(generatorState, inputObject, true, types_1.ImportUsageState.wireconfig); // wireconfig import usage
|
|
883
|
+
// Create list of property names which are inputs into the function.
|
|
884
|
+
for (const propValue of Object.values(inputObject.value)) {
|
|
885
|
+
// NOTE: LWC doesn't allow for property references to be nested in
|
|
886
|
+
// objects or arrays, so only need to check the top-level props.
|
|
887
|
+
if (propValue.type === 'PropertyReference') {
|
|
888
|
+
inputProps.add(propValue.value.split('/')[0]);
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
else {
|
|
893
|
+
// Matches LWC compiler behavior which always pass an object into a wire's
|
|
894
|
+
// update() method. Even if original source doesn't provide config.
|
|
895
|
+
configObjExpr = t.objectExpression([]);
|
|
896
|
+
}
|
|
897
|
+
// e.g. `c: ctx => ({ recordId: "001RM000004UZqLYAW" })`
|
|
898
|
+
const configFunc = t.arrowFunctionExpression([shared_1.ID.CONTEXT], configObjExpr);
|
|
899
|
+
funcObjProps.push(t.objectProperty(shared_1.ID.FUNC_CONFIG, configFunc));
|
|
900
|
+
// e.g. in: ['recordId', 'fields']
|
|
901
|
+
if (inputProps.size) {
|
|
902
|
+
funcObjProps.push(t.objectProperty(shared_1.ID.FUNC_INPUT, t.arrayExpression(Array.from(inputProps).map((v) => t.stringLiteral(v)))));
|
|
903
|
+
}
|
|
904
|
+
return funcObjProps;
|
|
905
|
+
}
|
|
906
|
+
/**
|
|
907
|
+
* Create imports for the provided priming adapter, and stores then in the GeneratorState
|
|
908
|
+
* @param {GeneratorState} generatorState the current state of the esm generator
|
|
909
|
+
* @param {PrimingAdapterDefinition} primingAdapterDef the PrimingAdapterDefinition from which to find the Priming
|
|
910
|
+
* Adapter import name identifiers
|
|
911
|
+
* @returns {PrimingAdapterImportNames} an object containing the Priming adapter import names (adapter, batch adapter, and reducer)
|
|
912
|
+
*/
|
|
913
|
+
function createPrimingAdapterImports(generatorState, primingAdapterDef) {
|
|
914
|
+
const adapterLocalName = t.identifier(`i${++generatorState.importAliasSuffix}`);
|
|
915
|
+
const primingAdapterImportNames = {
|
|
916
|
+
primingAdapterDef,
|
|
917
|
+
adapter: adapterLocalName,
|
|
918
|
+
};
|
|
919
|
+
// create import for priming adapter and store in generator state
|
|
920
|
+
// to be appended to statements array for this script.
|
|
921
|
+
const adapterSpecifier = t.importSpecifier(adapterLocalName, t.identifier(primingAdapterDef.prime.identifier));
|
|
922
|
+
generatorState.scriptGenState.primingAdapterImportDeclarations.push(t.importDeclaration([adapterSpecifier], t.stringLiteral(primingAdapterDef.prime.importPath)));
|
|
923
|
+
primingAdapterImportNames.adapter = adapterLocalName;
|
|
924
|
+
// optionally create imports for batch adapter and reducer.
|
|
925
|
+
if (primingAdapterDef.batch) {
|
|
926
|
+
if (primingAdapterDef.batch.prime.importPath ===
|
|
927
|
+
primingAdapterDef.prime.importPath &&
|
|
928
|
+
primingAdapterDef.batch.prime.identifier ===
|
|
929
|
+
primingAdapterDef.prime.identifier) {
|
|
930
|
+
// Special case where batch adapter uses same priming adapter (e.g. getObjectInfos).
|
|
931
|
+
// Don't create new import, just reuse local name of non-batch adapter.
|
|
932
|
+
primingAdapterImportNames.batchAdapter = adapterLocalName;
|
|
933
|
+
}
|
|
934
|
+
else {
|
|
935
|
+
const batchLocalName = t.identifier(`i${++generatorState.importAliasSuffix}`);
|
|
936
|
+
const batchSpecifier = t.importSpecifier(batchLocalName, t.identifier(primingAdapterDef.batch.prime.identifier));
|
|
937
|
+
generatorState.scriptGenState.primingAdapterImportDeclarations.push(t.importDeclaration([batchSpecifier], t.stringLiteral(primingAdapterDef.batch.prime.importPath)));
|
|
938
|
+
primingAdapterImportNames.batchAdapter = batchLocalName;
|
|
939
|
+
}
|
|
940
|
+
const reducerLocalName = t.identifier(`i${++generatorState.importAliasSuffix}`);
|
|
941
|
+
const reducerSpecifier = t.importSpecifier(reducerLocalName, t.identifier(primingAdapterDef.batch.reducer.identifier));
|
|
942
|
+
generatorState.scriptGenState.primingAdapterImportDeclarations.push(t.importDeclaration([reducerSpecifier], t.stringLiteral(primingAdapterDef.batch.reducer.importPath)));
|
|
943
|
+
primingAdapterImportNames.reducer = reducerLocalName;
|
|
944
|
+
}
|
|
945
|
+
return primingAdapterImportNames;
|
|
946
|
+
}
|
|
947
|
+
/**
|
|
948
|
+
* Determines whether an export name matches one of the supported context wires
|
|
949
|
+
* @param {string | undefined} exportName the exportName of an import statement
|
|
950
|
+
* @returns {boolean} boolean true if the the export name matches a supported context wire
|
|
951
|
+
*/
|
|
952
|
+
function isSupportedContextWire(exportName) {
|
|
953
|
+
return (exportName !== undefined && Object.values(CONTEXT_MAPPING).includes(exportName));
|
|
954
|
+
}
|
|
955
|
+
/**
|
|
956
|
+
* Determines whether the resourceName of an import statement is that of an Apex wire
|
|
957
|
+
* @param {string | undefined} resourceName a string representing the resource name (ex: '@salesforce/apex/myApexwire')
|
|
958
|
+
* @returns {boolean} true if the resource name represent that of an Apex wire, false otherwise
|
|
959
|
+
*/
|
|
960
|
+
function isApexWire(resourceName) {
|
|
961
|
+
return !!(resourceName && resourceName.startsWith('@salesforce/apex/'));
|
|
962
|
+
}
|
|
963
|
+
/**
|
|
964
|
+
* Retrieves the name of an Apex wire
|
|
965
|
+
* @param {string} resourceName a string representing the resource name (ex: '@salesforce/apex/ContactController.getContactList')
|
|
966
|
+
* @param {string} exportName a string representing the name of the export (ex: `awire` in `import awire from '@salesforce/apex/awire'`)
|
|
967
|
+
* @returns {string} the Apex wire name, as a string
|
|
968
|
+
*/
|
|
969
|
+
function getWireName(resourceName, exportName) {
|
|
970
|
+
if (isApexWire(resourceName)) {
|
|
971
|
+
// eg. @salesforce/apex/ContactController.getContactList -> ContactController.getContactList
|
|
972
|
+
return resourceName.substring('@salesforce/apex/'.length);
|
|
973
|
+
}
|
|
974
|
+
return exportName;
|
|
975
|
+
}
|
|
976
|
+
/**
|
|
977
|
+
* A barebones resolvable module default export with a singular node describing the context of an error.
|
|
978
|
+
*
|
|
979
|
+
* We return this instead of a real resolvable module if something throws an error during resolvable module generation
|
|
980
|
+
* @param generatorState The state of the generator for pass through to adgToExpression
|
|
981
|
+
* @param error The error that was thrown
|
|
982
|
+
* @returns A default export representing the error state for this resolvable module
|
|
983
|
+
*/
|
|
984
|
+
function produceErrorAdgFunction(generatorState, error) {
|
|
985
|
+
const functionValues = {
|
|
986
|
+
error: {
|
|
987
|
+
type: 'PrimitiveValue',
|
|
988
|
+
value: error instanceof Error
|
|
989
|
+
? error.message
|
|
990
|
+
: shared_1.ERROR_PREFIX + 'Something that is not an error was thrown',
|
|
991
|
+
},
|
|
992
|
+
};
|
|
993
|
+
if (error instanceof Error && error.stack) {
|
|
994
|
+
functionValues.stack = {
|
|
995
|
+
type: 'PrimitiveValue',
|
|
996
|
+
value: error.stack,
|
|
997
|
+
};
|
|
998
|
+
}
|
|
999
|
+
const adgFuncCall = adgToExpression(generatorState, {
|
|
1000
|
+
functions: [
|
|
1001
|
+
{
|
|
1002
|
+
type: 'ErrorFunction',
|
|
1003
|
+
input: [
|
|
1004
|
+
{
|
|
1005
|
+
type: 'ObjectValue',
|
|
1006
|
+
value: functionValues,
|
|
1007
|
+
},
|
|
1008
|
+
],
|
|
1009
|
+
reference: {
|
|
1010
|
+
type: 'Unresolved',
|
|
1011
|
+
value: '',
|
|
1012
|
+
},
|
|
1013
|
+
},
|
|
1014
|
+
],
|
|
1015
|
+
});
|
|
1016
|
+
const factoryFuncs = (0, shared_1.getFactoryFuncDeclaration)(generatorState, true);
|
|
1017
|
+
return t.program([
|
|
1018
|
+
t.exportDefaultDeclaration(t.functionDeclaration(null, [shared_1.ID.FACTORY, shared_1.ID.CONTEXT], t.blockStatement([
|
|
1019
|
+
// it is literally impossible for this to be undefined given the adgToExpression call
|
|
1020
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
1021
|
+
factoryFuncs,
|
|
1022
|
+
t.returnStatement(adgFuncCall),
|
|
1023
|
+
]))),
|
|
1024
|
+
]);
|
|
1025
|
+
}
|
|
1026
|
+
exports.produceErrorAdgFunction = produceErrorAdgFunction;
|
|
1027
|
+
//# sourceMappingURL=modGenScript.js.map
|