-
Notifications
You must be signed in to change notification settings - Fork 103
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
And create a new (private) `cli` package which exposes our wrapper creation script to third-party web component libraries mid term. --------- Co-authored-by: Lukas Harbarth <lukas.harbarth@sap.com>
- Loading branch information
1 parent
c148f42
commit 250ad0d
Showing
422 changed files
with
5,673 additions
and
5,109 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
dist | ||
test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
{ | ||
"name": "@ui5/webcomponents-react-cli", | ||
"private": true, | ||
"description": "CLI for UI5 Web Components for React", | ||
"author": "SAP SE (https://www.sap.com)", | ||
"license": "Apache-2.0", | ||
"version": "1.22.0", | ||
"type": "module", | ||
"types": "./dist/index.d.ts", | ||
"main": "./dist/index.js", | ||
"exports": { | ||
".": { | ||
"types": "./dist/index.d.ts", | ||
"default": "./dist/index.js" | ||
}, | ||
"./package.json": "./package.json" | ||
}, | ||
"bin": { | ||
"ui5-wcr": "./dist/bin/index.js" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/SAP/ui5-webcomponents-react", | ||
"directory": "packages/cli" | ||
}, | ||
"scripts": { | ||
"clean": "rimraf dist" | ||
}, | ||
"publishConfig": { | ||
"access": "public" | ||
}, | ||
"files": [ | ||
"dist" | ||
], | ||
"dependencies": { | ||
"dedent": "^1.5.1", | ||
"turndown": "^7.1.2" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
#!/usr/bin/env node | ||
import { resolve } from 'node:path'; | ||
import { parseArgs } from 'node:util'; | ||
import * as process from 'process'; | ||
|
||
const options = { | ||
packageName: { | ||
type: 'string' as const | ||
}, | ||
out: { | ||
type: 'string' as const, | ||
short: 'o' | ||
}, | ||
additionalComponentNote: { | ||
type: 'string' as const | ||
} | ||
}; | ||
const { values, positionals } = parseArgs({ options, allowPositionals: true }); | ||
|
||
const [command] = positionals; | ||
|
||
console.log(command); | ||
|
||
switch (command) { | ||
case 'create-wrappers': | ||
const { packageName, out, additionalComponentNote } = values; | ||
const missingParameters = []; | ||
if (!packageName) { | ||
missingParameters.push('--packageName'); | ||
} | ||
if (!out) { | ||
missingParameters.push('--out'); | ||
} | ||
|
||
if (missingParameters.length > 0) { | ||
console.error(` | ||
Missing parameters: ${missingParameters.join(', ')} | ||
Example: ui5-wcr create-wrappers --packageName @ui5/webcomponents --out ./src/components | ||
Please add the missing parameters and try again. | ||
`); | ||
process.exit(1); | ||
} | ||
|
||
const createWrapperModule = await import('../scripts/create-wrappers/main.js'); | ||
|
||
const outDir = resolve(process.cwd(), values.out!); | ||
// eslint-disable-next-line @typescript-eslint/await-thenable | ||
await createWrapperModule.default(packageName!, outDir, { additionalComponentNote }); | ||
process.exit(0); | ||
break; | ||
default: | ||
console.warn('Unknown command', command); | ||
process.exit(1); | ||
} |
19 changes: 19 additions & 0 deletions
19
packages/cli/src/scripts/create-wrappers/AbstractRenderer.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import type { WebComponentWrapper } from './WebComponentWrapper.js'; | ||
|
||
export enum RenderingPhase { | ||
imports = 'imports', | ||
attributes = 'attributes', | ||
props = 'props', | ||
domRef = 'domRef', | ||
component = 'component', | ||
exports = 'exports' | ||
} | ||
|
||
export abstract class AbstractRenderer { | ||
public readonly phase!: RenderingPhase; | ||
|
||
public prepare(context: WebComponentWrapper) { | ||
// optional | ||
} | ||
abstract render(context: WebComponentWrapper): string; | ||
} |
102 changes: 102 additions & 0 deletions
102
packages/cli/src/scripts/create-wrappers/AttributesRenderer.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
import type * as CEM from '@ui5/webcomponents-tools/lib/cem/types-internal.d.ts'; | ||
import dedent from 'dedent'; | ||
import { | ||
mapWebComponentTypeToPrimitive, | ||
propDescriptionFormatter, | ||
snakeCaseToCamelCase | ||
} from '../../util/formatters.js'; | ||
import { resolveReferenceImports } from '../../util/referenceResolver.js'; | ||
import { AbstractRenderer, RenderingPhase } from './AbstractRenderer.js'; | ||
import { WebComponentWrapper } from './WebComponentWrapper.js'; | ||
|
||
const loggedTypes = new Set<string>(); | ||
|
||
function mapWebComponentTypeToTsType(type: string) { | ||
const primitive = mapWebComponentTypeToPrimitive(type); | ||
if (primitive) { | ||
return primitive; | ||
} | ||
switch (type) { | ||
case 'HTMLElement | string | undefined': | ||
case 'HTMLElement | string': | ||
// opener props only accept strings as prop types | ||
return 'string'; | ||
|
||
default: | ||
if (!loggedTypes.has(type)) { | ||
console.log('-> Attributes type', type); | ||
loggedTypes.add(type); | ||
} | ||
return type; | ||
} | ||
} | ||
|
||
export class AttributesRenderer extends AbstractRenderer { | ||
public phase = RenderingPhase.attributes; | ||
|
||
private _attributes: CEM.ClassField[] = []; | ||
|
||
setAttributes(value: CEM.Attribute[]) { | ||
this._attributes = value.toSorted((a, b) => a.name.localeCompare(b.name)) as CEM.ClassField[]; | ||
return this; | ||
} | ||
|
||
private descriptionBuilder(attribute: CEM.ClassField) { | ||
const parts: string[] = []; | ||
|
||
parts.push(` * ${propDescriptionFormatter(attribute.description ?? '')}`); | ||
if (attribute.default && attribute.default.length > 0 && attribute.default !== '""') { | ||
parts.push(` * @default ${attribute.default}`); | ||
} | ||
|
||
if (attribute.deprecated) { | ||
parts.push(` * @deprecated ${attribute.deprecated}`); | ||
} | ||
|
||
return `/**\n${parts.join('\n')}\n */`; | ||
} | ||
|
||
private propTyping(attribute: CEM.ClassField, context: WebComponentWrapper) { | ||
let type = attribute.type?.text ?? 'unknown'; | ||
type = mapWebComponentTypeToTsType(type); | ||
|
||
const references = attribute.type?.references; | ||
const isEnum = references != null && references?.length > 0; | ||
|
||
if (isEnum) { | ||
type += ` | keyof typeof ${type}`; | ||
} | ||
if (attribute._ui5validator === 'CSSColor') { | ||
type = `CSSProperties['color']`; | ||
} else if (attribute._ui5validator === 'CSSSize') { | ||
type = `CSSProperties['width'] | CSSProperties['height']`; | ||
} | ||
|
||
context.addAttribute(snakeCaseToCamelCase(attribute.name), type); | ||
|
||
return `${snakeCaseToCamelCase(attribute.name)}?: ${type};`; | ||
} | ||
|
||
prepare(context: WebComponentWrapper) { | ||
for (const attribute of this._attributes) { | ||
// special css handling | ||
if (attribute._ui5validator === 'CSSSize' || attribute._ui5validator === 'CSSColor') { | ||
context.addTypeImport('react', 'CSSProperties'); | ||
} else { | ||
resolveReferenceImports(attribute.type?.references ?? [], context); | ||
} | ||
} | ||
} | ||
|
||
render(context: WebComponentWrapper): string { | ||
return dedent` | ||
interface ${context.componentName}Attributes { | ||
${this._attributes | ||
.map((attribute) => { | ||
return `${this.descriptionBuilder(attribute)}\n${this.propTyping(attribute, context)}`; | ||
}) | ||
.join('\n\n')} | ||
} | ||
`; | ||
} | ||
} |
Oops, something went wrong.