106 lines
3.4 KiB
JavaScript
106 lines
3.4 KiB
JavaScript
import fs from 'fs';
|
|
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
import { globby } from 'globby';
|
|
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
import { createModuleGraph } from '@thepassle/module-graph';
|
|
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
import { create, ts } from '@custom-elements-manifest/analyzer';
|
|
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
import { litPlugin } from '@custom-elements-manifest/analyzer/src/features/framework-plugins/lit/lit.js';
|
|
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
import { generateCustomData } from 'cem-plugin-vs-code-custom-data-generator';
|
|
|
|
/**
|
|
* Find all entrypoints for lion to create the CEM from
|
|
*/
|
|
const globs = await globby('./exports/**/*.js');
|
|
|
|
/**
|
|
* Based on the entrypoints, create a module graph including @lion/ui dependency
|
|
* We'll feed these modules to the CEM analyzer
|
|
*/
|
|
const moduleGraph = await createModuleGraph(globs, {
|
|
exclude: [
|
|
/** Don't include translations in the CEM */
|
|
i => i.includes('/translations/'),
|
|
/** Don't include SVGs in the CEM */
|
|
i => i.endsWith('.svg.js'),
|
|
],
|
|
});
|
|
|
|
/**
|
|
* @param {{name: string}} a
|
|
* @param {{name: string}} b
|
|
* @returns
|
|
*/
|
|
function sortName(a, b) {
|
|
const nameA = a.name?.toUpperCase(); // ignore upper and lowercase
|
|
const nameB = b.name?.toUpperCase(); // ignore upper and lowercase
|
|
if (nameA < nameB) {
|
|
return -1;
|
|
}
|
|
if (nameA > nameB) {
|
|
return 1;
|
|
}
|
|
|
|
// names must be equal
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* Create ts.sourceFiles from the modules in the module graph
|
|
* to pass to the CEM analyzer
|
|
*/
|
|
const modules = [];
|
|
for (const [, module] of moduleGraph.modules) {
|
|
modules.push(ts.createSourceFile(module.path, module.source, ts.ScriptTarget.ES2015, true));
|
|
}
|
|
|
|
/** Exclude information inherited from these mixins, they're generally not useful for public api */
|
|
const inheritanceDenyList = [
|
|
'ScopedElementsMixin',
|
|
'SyncUpdatableMixin',
|
|
'LocalizeMixin',
|
|
'SlotMixin',
|
|
];
|
|
|
|
const cem = create({
|
|
modules,
|
|
plugins: [
|
|
...litPlugin(),
|
|
generateCustomData(),
|
|
{
|
|
packageLinkPhase({ customElementsManifest }) {
|
|
for (const definition of customElementsManifest.modules) {
|
|
for (const declaration of definition.declarations) {
|
|
if (declaration.kind === 'class' && declaration?.members?.length) {
|
|
/**
|
|
* Filter out unwanted information from the docs
|
|
*/
|
|
declaration.members = declaration.members
|
|
.filter(
|
|
/** @param {{inheritedFrom: {name: string}}} member */ member =>
|
|
!inheritanceDenyList.includes(member.inheritedFrom?.name),
|
|
)
|
|
.sort(sortName);
|
|
/**
|
|
* Set privacy for members based on naming conventions
|
|
*/
|
|
for (const m of declaration.members) {
|
|
if (!m.privacy && !m.name?.startsWith('_') && !m.name?.startsWith('#')) {
|
|
m.privacy = 'public';
|
|
} else if (m.name?.startsWith('#') || m.name?.startsWith('__')) {
|
|
m.privacy = 'private';
|
|
} else if (!m.privacy && m.name?.startsWith('_')) {
|
|
m.privacy = 'protected';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
},
|
|
],
|
|
});
|
|
|
|
fs.writeFileSync('./custom-elements.json', JSON.stringify(cem, null, 2));
|