Skip to content

Commit

Permalink
Make sure the component-class blueprint generates a signature in a …
Browse files Browse the repository at this point in the history
…TS project
  • Loading branch information
Bert De Block committed Feb 7, 2024
1 parent 12106b7 commit 632a6ce
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 27 deletions.
24 changes: 24 additions & 0 deletions blueprints/-utils.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,33 @@
const { dasherize } = require('ember-cli-string-utils');
const { EOL } = require('os');

function generateComponentSignature(componentName) {
let args = ` // The arguments accepted by the component${EOL} Args: {};`;

let blocks =
` // Any blocks yielded by the component${EOL}` +
` Blocks: {${EOL}` +
` default: []${EOL}` +
` };`;

let element =
` // The element to which \`...attributes\` is applied in the component template${EOL}` +
` Element: null;`;

return (
`interface ${componentName}Signature {${EOL}` +
`${args}${EOL}` +
`${blocks}${EOL}` +
`${element}${EOL}` +
`}${EOL}`
);
}

function modulePrefixForProject(project) {
return dasherize(project.config().modulePrefix);
}

module.exports = {
generateComponentSignature,
modulePrefixForProject,
};
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<%= importComponent %>
<%= importTemplate %>
<%= componentSignature %>
export default <%= defaultExport %>
27 changes: 24 additions & 3 deletions blueprints/component-class/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ const getPathOption = require('ember-cli-get-component-path-option');
const normalizeEntityName = require('ember-cli-normalize-entity-name');
const { EOL } = require('os');
const { has } = require('@ember/edition-utils');
const { generateComponentSignature } = require('../-utils');

const maybePolyfillTypeScriptBlueprints = require('../-maybe-polyfill-typescript-blueprints');

Expand Down Expand Up @@ -49,9 +50,17 @@ module.exports = {
},
],

/**
Flag to let us correctly handle the case where we are running against a
version of Ember CLI which does not support TS-based emit, and where we
therefore *must* not emit a `defaultExport` local which includes a type
parameter in the exported function call or class definition.
*/
_isUsingTS: false,

init() {
this._super && this._super.init.apply(this, arguments);
maybePolyfillTypeScriptBlueprints(this);
this._isUsingTS = maybePolyfillTypeScriptBlueprints(this);
let isOctane = has('octane');

this.availableOptions.forEach((option) => {
Expand Down Expand Up @@ -134,6 +143,7 @@ module.exports = {
let importComponent = '';
let importTemplate = '';
let defaultExport = '';
let componentSignature = '';

// if we're in an addon, build import statement
if (options.project.isEmberCLIAddon() || (options.inRepoAddon && !options.inDummy)) {
Expand Down Expand Up @@ -161,17 +171,28 @@ module.exports = {
break;
case '@glimmer/component':
importComponent = `import Component from '@glimmer/component';`;
defaultExport = `class ${classifiedModuleName}Component extends Component {}`;
if (this._isUsingTS) {
componentSignature = generateComponentSignature(classifiedModuleName);
defaultExport = `class ${classifiedModuleName}Component extends Component<${classifiedModuleName}Signature> {}`;
} else {
defaultExport = `class ${classifiedModuleName}Component extends Component {}`;
}
break;
case '@ember/component/template-only':
importComponent = `import templateOnly from '@ember/component/template-only';`;
defaultExport = `templateOnly();`;
if (this._isUsingTS) {
componentSignature = generateComponentSignature(classifiedModuleName);
defaultExport = `templateOnly<${classifiedModuleName}Signature>();`;
} else {
defaultExport = `templateOnly();`;
}
break;
}

return {
importTemplate,
importComponent,
componentSignature,
defaultExport,
path: getPathOption(options),
componentClass,
Expand Down
27 changes: 3 additions & 24 deletions blueprints/component/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const getPathOption = require('ember-cli-get-component-path-option');
const normalizeEntityName = require('ember-cli-normalize-entity-name');
const { EOL } = require('os');
const { has } = require('@ember/edition-utils');
const { generateComponentSignature } = require('../-utils');

const maybePolyfillTypeScriptBlueprints = require('../-maybe-polyfill-typescript-blueprints');

Expand Down Expand Up @@ -273,7 +274,7 @@ module.exports = {
case '@glimmer/component':
importComponent = `import Component from '@glimmer/component';`;
if (this._isUsingTS) {
componentSignature = signatureFor(classifiedModuleName);
componentSignature = generateComponentSignature(classifiedModuleName);
defaultExport = `class ${classifiedModuleName}Component extends Component<${classifiedModuleName}Signature> {}`;
} else {
defaultExport = `class ${classifiedModuleName}Component extends Component {}`;
Expand All @@ -282,7 +283,7 @@ module.exports = {
case '@ember/component/template-only':
importComponent = `import templateOnly from '@ember/component/template-only';`;
if (this._isUsingTS) {
componentSignature = signatureFor(classifiedModuleName);
componentSignature = generateComponentSignature(classifiedModuleName);
defaultExport = `templateOnly<${classifiedModuleName}Signature>();`;
} else {
defaultExport = `templateOnly();`;
Expand All @@ -300,25 +301,3 @@ module.exports = {
};
},
};

function signatureFor(classifiedModuleName) {
let args = ` // The arguments accepted by the component${EOL} Args: {};`;

let blocks =
` // Any blocks yielded by the component${EOL}` +
` Blocks: {${EOL}` +
` default: []${EOL}` +
` };`;

let element =
` // The element to which \`...attributes\` is applied in the component template${EOL}` +
` Element: null;`;

return (
`interface ${classifiedModuleName}Signature {${EOL}` +
`${args}${EOL}` +
`${blocks}${EOL}` +
`${element}${EOL}` +
`}${EOL}`
);
}

0 comments on commit 632a6ce

Please sign in to comment.