@komaci/esm-generator 262.15.0 → 262.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -303,6 +303,42 @@ describe('sanitizeFunction', () => {
|
|
|
303
303
|
it('should throw an error if we try to reference a bad input', () => {
|
|
304
304
|
expect(() => (0, functionAstGeneration_1.sanitizeFunction)(getters[1], imports, new Map())).toThrowError(new Error(`${common_shared_1.ERROR_PREFIX}: 'bad' does not map to valid import`));
|
|
305
305
|
});
|
|
306
|
+
it('should strip TypeScript non-null assertion operator (!)', () => {
|
|
307
|
+
const sourceWithNonNull = `
|
|
308
|
+
import accessCheck from '@salesforce/accessCheck/SomeCheck.enabled';
|
|
309
|
+
export default class TestComponent {
|
|
310
|
+
get showContent() {
|
|
311
|
+
return accessCheck! && this.isVisible;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
`;
|
|
315
|
+
const ast = (0, common_shared_1.generateAstFromSrcCode)(sourceWithNonNull);
|
|
316
|
+
const { getters } = (0, common_shared_1.getPropertyMetadataFromAst)(ast);
|
|
317
|
+
const imports = new Map();
|
|
318
|
+
imports.set('accessCheck', {
|
|
319
|
+
name: 'accessCheck',
|
|
320
|
+
resourceName: '@salesforce/accessCheck/SomeCheck.enabled',
|
|
321
|
+
staticallyAnalyzable: false,
|
|
322
|
+
usedInPriming: true,
|
|
323
|
+
isFromInternalNamespace: true,
|
|
324
|
+
isFromSupportedLibrary: true,
|
|
325
|
+
generatorAlias: 'i0',
|
|
326
|
+
komaciDocImportRef: '0/names/0',
|
|
327
|
+
});
|
|
328
|
+
(0, functionAstGeneration_1.sanitizeFunction)(getters[0], imports, new Map());
|
|
329
|
+
const hoisted = (0, types_1.functionDeclaration)((0, types_1.identifier)('g0'), [(0, types_1.identifier)('props')], getters[0].node.body);
|
|
330
|
+
const generatedFunction = (0, generator_1.default)((0, types_1.file)((0, types_1.program)([hoisted])));
|
|
331
|
+
// The non-null assertion operator (!) should be removed
|
|
332
|
+
// Should generate: i0 && props.isVisible
|
|
333
|
+
// Should NOT generate: i0! && props.isVisible
|
|
334
|
+
expect(generatedFunction.code).not.toContain('!');
|
|
335
|
+
expect(generatedFunction.code).toContain('i0 && props.isVisible');
|
|
336
|
+
expect(generatedFunction.code).toMatchInlineSnapshot(`
|
|
337
|
+
"function g0(props) {
|
|
338
|
+
return i0 && props.isVisible;
|
|
339
|
+
}"
|
|
340
|
+
`);
|
|
341
|
+
});
|
|
306
342
|
});
|
|
307
343
|
describe('adgToExpression', () => {
|
|
308
344
|
it('returns valid adg function from komaci doc', () => {
|
|
@@ -25,6 +25,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
26
|
const __1 = require("..");
|
|
27
27
|
const modgen = __importStar(require("../genericAstGeneration"));
|
|
28
|
+
const metadata_1 = require("@lwc/metadata");
|
|
28
29
|
describe('Handling errors that throw inside a call to generateKomaciModule', () => {
|
|
29
30
|
it('should return error adg when an error is produced', () => {
|
|
30
31
|
const input = {
|
|
@@ -290,4 +291,103 @@ describe('normalizeSrcFileKeys', () => {
|
|
|
290
291
|
expect(input.srcFileMap['templates/test2.html']).not.toBeUndefined();
|
|
291
292
|
});
|
|
292
293
|
});
|
|
294
|
+
describe('Bundle processing', () => {
|
|
295
|
+
it('when both .js and .ts files exist with for the component name', () => {
|
|
296
|
+
const bundleSrcFileMap = {
|
|
297
|
+
'test.js': {},
|
|
298
|
+
'test.ts': {},
|
|
299
|
+
'test.html': {},
|
|
300
|
+
};
|
|
301
|
+
const input = {
|
|
302
|
+
moduleInfo: {
|
|
303
|
+
name: 'test',
|
|
304
|
+
namespace: 'c',
|
|
305
|
+
type: 'bundle',
|
|
306
|
+
files: bundleSrcFileMap,
|
|
307
|
+
},
|
|
308
|
+
srcFileMap: {
|
|
309
|
+
'test.js': 'export default class Test {}',
|
|
310
|
+
'test.ts': 'export default class Test {}',
|
|
311
|
+
'test.html': '<template><div>Test</div></template>',
|
|
312
|
+
'test.css': 'p { text-align: center; }',
|
|
313
|
+
},
|
|
314
|
+
};
|
|
315
|
+
const res = (0, __1.generateKomaciModule)(input);
|
|
316
|
+
expect(res).toContain('ErrorFunction');
|
|
317
|
+
expect(res).toContain('[komaci esm-generator] multiple component script files with the same name found in bundle: test');
|
|
318
|
+
});
|
|
319
|
+
it('can handle multiple script files with the same name in different directories', () => {
|
|
320
|
+
const bundleSrcFileMap = {
|
|
321
|
+
'test.js': {},
|
|
322
|
+
'subdir/test.ts': {},
|
|
323
|
+
'test.html': {},
|
|
324
|
+
};
|
|
325
|
+
const input = {
|
|
326
|
+
moduleInfo: {
|
|
327
|
+
name: 'test',
|
|
328
|
+
namespace: 'c',
|
|
329
|
+
type: 'bundle',
|
|
330
|
+
files: bundleSrcFileMap,
|
|
331
|
+
},
|
|
332
|
+
srcFileMap: {
|
|
333
|
+
'test.js': 'export default class Test {}',
|
|
334
|
+
'subdir/test.ts': 'export default class Test {}',
|
|
335
|
+
'test.html': '<template><div>Test</div></template>',
|
|
336
|
+
'test.css': 'p { text-align: center; }',
|
|
337
|
+
},
|
|
338
|
+
};
|
|
339
|
+
const res = (0, __1.generateKomaciModule)(input);
|
|
340
|
+
expect(res).not.toContain('ErrorFunction');
|
|
341
|
+
expect(res).toContain('registerAdgFunction');
|
|
342
|
+
});
|
|
343
|
+
it('can handle multiple script files with different names in same directory', () => {
|
|
344
|
+
const testJsSource = `export default class Test extends LightningElement {
|
|
345
|
+
get testProp() {
|
|
346
|
+
return 'test';
|
|
347
|
+
}
|
|
348
|
+
}`;
|
|
349
|
+
const fooTsSource = `export default class Foo {
|
|
350
|
+
get fooProp() {
|
|
351
|
+
return 'foo';
|
|
352
|
+
}
|
|
353
|
+
}`;
|
|
354
|
+
const bundleConfig = {
|
|
355
|
+
namespace: 'c',
|
|
356
|
+
name: 'test',
|
|
357
|
+
type: 'internal',
|
|
358
|
+
files: [
|
|
359
|
+
{ fileName: 'test.js', source: testJsSource },
|
|
360
|
+
{ fileName: 'foo.ts', source: fooTsSource },
|
|
361
|
+
{ fileName: 'test.html', source: '<template><div>Test</div></template>' },
|
|
362
|
+
{ fileName: 'test.css', source: 'p { text-align: center; }' },
|
|
363
|
+
],
|
|
364
|
+
enableKomaci: true,
|
|
365
|
+
namespaceMapping: {},
|
|
366
|
+
npmModuleMapping: {},
|
|
367
|
+
};
|
|
368
|
+
const metadata = (0, metadata_1.collectBundleMetadata)(bundleConfig);
|
|
369
|
+
const inputFiles = Object.fromEntries(metadata.files
|
|
370
|
+
.map(({ fileName, komaciDoc }) => [fileName, komaciDoc])
|
|
371
|
+
.filter(([, komaciDoc]) => !!komaciDoc));
|
|
372
|
+
const input = {
|
|
373
|
+
moduleInfo: {
|
|
374
|
+
name: 'test',
|
|
375
|
+
namespace: 'c',
|
|
376
|
+
type: 'bundle',
|
|
377
|
+
files: inputFiles,
|
|
378
|
+
},
|
|
379
|
+
srcFileMap: {
|
|
380
|
+
'test.js': testJsSource,
|
|
381
|
+
'foo.ts': fooTsSource,
|
|
382
|
+
'test.html': '<template><div>Test</div></template>',
|
|
383
|
+
'test.css': 'p { text-align: center; }',
|
|
384
|
+
},
|
|
385
|
+
};
|
|
386
|
+
const res = (0, __1.generateKomaciModule)(input);
|
|
387
|
+
expect(res).not.toContain('ErrorFunction');
|
|
388
|
+
expect(res).toContain('registerAdgFunction');
|
|
389
|
+
expect(res).toContain('testProp');
|
|
390
|
+
expect(res).not.toContain('fooProp');
|
|
391
|
+
});
|
|
392
|
+
});
|
|
293
393
|
//# sourceMappingURL=index.spec.js.map
|
|
@@ -112,6 +112,11 @@ function sanitizeFunction(nodePath, importMetadata, gqlMetadataMap) {
|
|
|
112
112
|
path.replaceWith(t.memberExpression(t.identifier(common_shared_1.PROPS), path.node.property)); // replace this.<var> with props.<var>
|
|
113
113
|
}
|
|
114
114
|
},
|
|
115
|
+
TSNonNullExpression(path) {
|
|
116
|
+
// syntax like foo! is a TypeScript syntax that means "foo is not null or undefined"
|
|
117
|
+
// we need to remove the ! to make the code valid JavaScript
|
|
118
|
+
path.replaceWith(path.node.expression);
|
|
119
|
+
},
|
|
115
120
|
TaggedTemplateExpression(path) {
|
|
116
121
|
const taggedTmplExpr = path.node;
|
|
117
122
|
const taggedTmplLiteral = taggedTmplExpr.quasi;
|
package/build/index.js
CHANGED
|
@@ -116,38 +116,36 @@ function processGeneratorInputAndState(input) {
|
|
|
116
116
|
else if (input.moduleInfo.type === 'bundle') {
|
|
117
117
|
// code to process a bundle
|
|
118
118
|
let filename = '', fileExt;
|
|
119
|
-
const
|
|
120
|
-
const
|
|
119
|
+
const scriptDocs = {}; // {'test.js' : { filename: 'test', komaciDoc: KomaciDoc1 }}
|
|
120
|
+
const htmlDocs = {};
|
|
121
121
|
let sourceFile;
|
|
122
|
-
for (const [
|
|
122
|
+
for (const [filePath, komaciDoc] of Object.entries(input.moduleInfo.files)) {
|
|
123
123
|
// Determine file type based on extension in file name.
|
|
124
|
-
const segments = (0, common_shared_1.getFilepathSegments)(
|
|
124
|
+
const segments = (0, common_shared_1.getFilepathSegments)(filePath);
|
|
125
125
|
filename = segments[0]; // the filename, up to but not including, the file separator character
|
|
126
126
|
fileExt = segments[segments.length - 1]; // filename extension, not including the separator
|
|
127
|
-
let filesObj = {};
|
|
128
|
-
// check for existing map entry in order to append to it
|
|
129
|
-
// to support multiple files per filetype in the future
|
|
130
|
-
if (filesMap[fileExt]) {
|
|
131
|
-
filesObj = filesMap[fileExt];
|
|
132
|
-
}
|
|
133
|
-
filesObj[filename] = komaciDoc;
|
|
134
127
|
if (fileExt == 'html') {
|
|
135
|
-
|
|
128
|
+
htmlDocs[filename] = komaciDoc;
|
|
136
129
|
}
|
|
137
130
|
else if (fileExt === 'js' || fileExt === 'ts') {
|
|
138
|
-
|
|
131
|
+
scriptDocs[filePath] = { filename, komaciDoc };
|
|
139
132
|
}
|
|
140
133
|
else {
|
|
141
134
|
throw new Error(types_1.ERROR_PREFIX + 'unsupported file extension: ' + fileExt);
|
|
142
135
|
}
|
|
143
136
|
}
|
|
144
137
|
const source = (0, componentAstProcessing_1.getComponentSrcJs)(input);
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
138
|
+
// Find the main component script file(s)
|
|
139
|
+
const mainComponentScriptFiles = Object.values(scriptDocs).filter(({ filename }) => filename === input.moduleInfo.name);
|
|
140
|
+
// For now we only support one main component script file.
|
|
141
|
+
if (mainComponentScriptFiles.length > 1) {
|
|
142
|
+
throw new Error(types_1.ERROR_PREFIX +
|
|
143
|
+
'multiple component script files with the same name found in bundle: ' +
|
|
144
|
+
input.moduleInfo.name);
|
|
145
|
+
}
|
|
146
|
+
const uniqueMainComponentScriptDoc = mainComponentScriptFiles[0]?.komaciDoc ?? {};
|
|
149
147
|
// eslint-disable-next-line prefer-const
|
|
150
|
-
sourceFile = (0, genericAstGeneration_1.generateResolvableModule)(input,
|
|
148
|
+
sourceFile = (0, genericAstGeneration_1.generateResolvableModule)(input, uniqueMainComponentScriptDoc, htmlDocs, source);
|
|
151
149
|
// Generate source from constructed AST.
|
|
152
150
|
const babelOutput = (0, generator_1.default)(sourceFile);
|
|
153
151
|
return babelOutput.code;
|