diff --git a/src/generators/generator.ts b/src/generators/generator.ts
index 2d4d118..c8b19b8 100644
--- a/src/generators/generator.ts
+++ b/src/generators/generator.ts
@@ -154,6 +154,7 @@ export function defineGenerator({
};
const templateCompiled = template({
+ args: resolvedArgs,
name: {
...entityNameCases,
camelCurlyBrackets: `{{${entityNameCases.camel}}}`,
@@ -327,6 +328,15 @@ export function name(): GeneratorArgFactory {
});
}
+export function namedExport(): GeneratorArgFactory {
+ return () => ({
+ alias: ["named"],
+ description: "Generate a named export, instead of a default export",
+ name: "namedExport",
+ type: "boolean",
+ });
+}
+
export function nested({
description,
}: {
diff --git a/src/generators/generators.ts b/src/generators/generators.ts
index ba608a6..bcfafa8 100644
--- a/src/generators/generators.ts
+++ b/src/generators/generators.ts
@@ -3,6 +3,7 @@ import {
classBased,
defineGenerator,
defineTestGenerator,
+ namedExport,
nested,
test,
testGeneratorName,
@@ -21,6 +22,7 @@ export const generators: Generator[] = [
defineGenerator({
args: [
classBased({ functionBasedName: "template-only" }),
+ namedExport(),
nested({
description:
"Generate a nested colocated component, e.g. `foo/bar/index.gts`",
@@ -49,7 +51,7 @@ export const generators: Generator[] = [
}),
defineGenerator({
- args: [classBased(), test(), typescript()],
+ args: [classBased(), namedExport(), test(), typescript()],
name: "helper",
}),
@@ -60,7 +62,7 @@ export const generators: Generator[] = [
}),
defineGenerator({
- args: [classBased(), test(), typescript()],
+ args: [classBased(), namedExport(), test(), typescript()],
name: "modifier",
}),
@@ -93,7 +95,7 @@ export const generators: Generator[] = [
}),
defineGenerator({
- args: [test(), typescript()],
+ args: [namedExport(), test(), typescript()],
name: "util",
}),
diff --git a/templates/component/component.class-based.gjs b/templates/component/component.class-based.gjs
index efbc0ff..7855815 100644
--- a/templates/component/component.class-based.gjs
+++ b/templates/component/component.class-based.gjs
@@ -1,5 +1,5 @@
import Component from '@glimmer/component';
-export default class {{name.pascal}} extends Component {
+{{#if args.namedExport}}export{{else}}export default{{/if}} class {{name.pascal}} extends Component {
\{{yield}}
}
diff --git a/templates/component/component.class-based.gts b/templates/component/component.class-based.gts
index 1bc552d..15e8082 100644
--- a/templates/component/component.class-based.gts
+++ b/templates/component/component.class-based.gts
@@ -8,7 +8,7 @@ export interface {{name.signature}} {
Element: null;
}
-export default class {{name.pascal}} extends Component<{{name.signature}}> {
+{{#if args.namedExport}}export{{else}}export default{{/if}} class {{name.pascal}} extends Component<{{name.signature}}> {
\{{yield}}
diff --git a/templates/component/component.template-only.gts b/templates/component/component.template-only.gts
index d93ff6c..98f8838 100644
--- a/templates/component/component.template-only.gts
+++ b/templates/component/component.template-only.gts
@@ -8,6 +8,8 @@ export interface {{name.signature}} {
Element: null;
}
-const {{name.pascal}}: TOC<{{name.signature}}> = \{{yield}};
+{{#if args.namedExport}}export {{/if}}const {{name.pascal}}: TOC<{{name.signature}}> = \{{yield}};
+{{#unless args.namedExport}}
export default {{name.pascal}};
+{{/unless}}
diff --git a/templates/helper/helper.class-based.js b/templates/helper/helper.class-based.js
index d3f7fc2..5963c93 100644
--- a/templates/helper/helper.class-based.js
+++ b/templates/helper/helper.class-based.js
@@ -1,6 +1,6 @@
import Helper from '@ember/component/helper';
-export default class {{name.camel}} extends Helper {
+{{#if args.namedExport}}export{{else}}export default{{/if}} class {{name.camel}} extends Helper {
compute(positional, named) {
return positional;
}
diff --git a/templates/helper/helper.class-based.ts b/templates/helper/helper.class-based.ts
index 38153d8..a6ad8c9 100644
--- a/templates/helper/helper.class-based.ts
+++ b/templates/helper/helper.class-based.ts
@@ -12,7 +12,7 @@ export interface {{name.signature}} {
Return: Return;
}
-export default class {{name.camel}} extends Helper<{{name.signature}}> {
+{{#if args.namedExport}}export{{else}}export default{{/if}} class {{name.camel}} extends Helper<{{name.signature}}> {
compute(positional: Positional, named: Named): Return {
return positional;
}
diff --git a/templates/helper/helper.function-based.js b/templates/helper/helper.function-based.js
index 477d464..12b9fd8 100644
--- a/templates/helper/helper.function-based.js
+++ b/templates/helper/helper.function-based.js
@@ -1,3 +1,3 @@
-export default function {{name.camel}}(positional, named) {
+{{#if args.namedExport}}export{{else}}export default{{/if}} function {{name.camel}}(positional, named) {
return positional;
}
diff --git a/templates/modifier/modifier.class-based.js b/templates/modifier/modifier.class-based.js
index 4ab3bd6..78647f7 100644
--- a/templates/modifier/modifier.class-based.js
+++ b/templates/modifier/modifier.class-based.js
@@ -1,5 +1,5 @@
import Modifier from 'ember-modifier';
-export default class {{name.camel}} extends Modifier {
+{{#if args.namedExport}}export{{else}}export default{{/if}} class {{name.camel}} extends Modifier {
modify(element, positional, named) {}
}
diff --git a/templates/modifier/modifier.class-based.ts b/templates/modifier/modifier.class-based.ts
index 5251dec..f88ef0a 100644
--- a/templates/modifier/modifier.class-based.ts
+++ b/templates/modifier/modifier.class-based.ts
@@ -12,6 +12,6 @@ export interface {{name.signature}} {
Element: Element;
}
-export default class {{name.camel}} extends Modifier<{{name.signature}}> {
+{{#if args.namedExport}}export{{else}}export default{{/if}} class {{name.camel}} extends Modifier<{{name.signature}}> {
modify(element: Element, positional: Positional, named: Named) {}
}
diff --git a/templates/modifier/modifier.function-based.js b/templates/modifier/modifier.function-based.js
index e12995c..9a494eb 100644
--- a/templates/modifier/modifier.function-based.js
+++ b/templates/modifier/modifier.function-based.js
@@ -1,3 +1,3 @@
import { modifier } from 'ember-modifier';
-export default modifier(function {{name.camel}}(element, positional, named) {});
+{{#if args.namedExport}}export const {{name.camel}} ={{else}}export default{{/if}} modifier(function {{name.camel}}(element, positional, named) {});
diff --git a/templates/modifier/modifier.function-based.ts b/templates/modifier/modifier.function-based.ts
index d4c58eb..875208d 100644
--- a/templates/modifier/modifier.function-based.ts
+++ b/templates/modifier/modifier.function-based.ts
@@ -8,4 +8,4 @@ export interface {{name.signature}} {
Element: null;
}
-export default modifier<{{name.signature}}>(function {{name.camel}}(element, positional, named) {});
+{{#if args.namedExport}}export const {{name.camel}} ={{else}}export default{{/if}} modifier<{{name.signature}}>(function {{name.camel}}(element, positional, named) {});
diff --git a/templates/util/util.js b/templates/util/util.js
index 29ed98b..7126931 100644
--- a/templates/util/util.js
+++ b/templates/util/util.js
@@ -1,3 +1,3 @@
-export default function {{name.camel}}() {
+{{#if args.namedExport}}export{{else}}export default{{/if}} function {{name.camel}}() {
return true;
}
diff --git a/test/generators/__snapshots__/component.test.ts.snap b/test/generators/__snapshots__/component.test.ts.snap
index 0b7b54a..a53ddef 100644
--- a/test/generators/__snapshots__/component.test.ts.snap
+++ b/test/generators/__snapshots__/component.test.ts.snap
@@ -28,6 +28,49 @@ export default class Foo extends Component {
"
`;
+exports[`generates a named export > --classBased --typescript 1`] = `
+"import Component from '@glimmer/component';
+
+export interface FooSignature {
+ Args: {};
+ Blocks: {
+ default: [];
+ };
+ Element: null;
+}
+
+export class Foo extends Component {
+
+ {{yield}}
+
+}
+"
+`;
+
+exports[`generates a named export > --classBased 1`] = `
+"import Component from '@glimmer/component';
+
+export class Foo extends Component {
+ {{yield}}
+}
+"
+`;
+
+exports[`generates a named export > --typescript 1`] = `
+"import type { TOC } from '@ember/component/template-only';
+
+export interface FooSignature {
+ Args: {};
+ Blocks: {
+ default: [];
+ };
+ Element: null;
+}
+
+export const Foo: TOC = {{yield}};
+"
+`;
+
exports[`generates a nested colocated template-only \`.gjs\` component 1`] = `
"{{yield}}
"
diff --git a/test/generators/__snapshots__/helper.test.ts.snap b/test/generators/__snapshots__/helper.test.ts.snap
index 5e4ad60..c73f963 100644
--- a/test/generators/__snapshots__/helper.test.ts.snap
+++ b/test/generators/__snapshots__/helper.test.ts.snap
@@ -62,6 +62,54 @@ exports[`generates a function-based \`.ts\` helper at a custom path 1`] = `
"
`;
+exports[`generates a named export > --classBased --typescript 1`] = `
+"import Helper from '@ember/component/helper';
+
+type Named = {};
+type Positional = [];
+type Return = Positional;
+
+export interface FooSignature {
+ Args: {
+ Named: Named;
+ Positional: Positional;
+ };
+ Return: Return;
+}
+
+export class foo extends Helper {
+ compute(positional: Positional, named: Named): Return {
+ return positional;
+ }
+}
+"
+`;
+
+exports[`generates a named export > --classBased 1`] = `
+"import Helper from '@ember/component/helper';
+
+export class foo extends Helper {
+ compute(positional, named) {
+ return positional;
+ }
+}
+"
+`;
+
+exports[`generates a named export > --typescript 1`] = `
+"export function foo(positional, named) {
+ return positional;
+}
+"
+`;
+
+exports[`generates a named export > no extra args 1`] = `
+"export function foo(positional, named) {
+ return positional;
+}
+"
+`;
+
exports[`generates a nested function-based \`.js\` helper 1`] = `
"export default function fooBar(positional, named) {
return positional;
diff --git a/test/generators/__snapshots__/modifier.test.ts.snap b/test/generators/__snapshots__/modifier.test.ts.snap
index 0cb409a..ce0028d 100644
--- a/test/generators/__snapshots__/modifier.test.ts.snap
+++ b/test/generators/__snapshots__/modifier.test.ts.snap
@@ -74,6 +74,58 @@ export default modifier(function foo(element, positional, named) {
"
`;
+exports[`generates a named export > --classBased --typescript 1`] = `
+"import Modifier from 'ember-modifier';
+
+type Named = {};
+type Positional = [];
+type Element = null;
+
+export interface FooSignature {
+ Args: {
+ Named: Named;
+ Positional: Positional;
+ };
+ Element: Element;
+}
+
+export class foo extends Modifier {
+ modify(element: Element, positional: Positional, named: Named) {}
+}
+"
+`;
+
+exports[`generates a named export > --classBased 1`] = `
+"import Modifier from 'ember-modifier';
+
+export class foo extends Modifier {
+ modify(element, positional, named) {}
+}
+"
+`;
+
+exports[`generates a named export > --typescript 1`] = `
+"import { modifier } from 'ember-modifier';
+
+export interface FooSignature {
+ Args: {
+ Named: {};
+ Positional: [];
+ };
+ Element: null;
+}
+
+export const foo = modifier(function foo(element, positional, named) {});
+"
+`;
+
+exports[`generates a named export > no extra args 1`] = `
+"import { modifier } from 'ember-modifier';
+
+export const foo = modifier(function foo(element, positional, named) {});
+"
+`;
+
exports[`generates a nested function-based \`.js\` modifier 1`] = `
"import { modifier } from 'ember-modifier';
diff --git a/test/generators/__snapshots__/util.test.ts.snap b/test/generators/__snapshots__/util.test.ts.snap
index 43c14e4..e9abb7e 100644
--- a/test/generators/__snapshots__/util.test.ts.snap
+++ b/test/generators/__snapshots__/util.test.ts.snap
@@ -28,6 +28,20 @@ exports[`generates a \`.ts\` util at a custom path 1`] = `
"
`;
+exports[`generates a named export > --typescript 1`] = `
+"export function foo() {
+ return true;
+}
+"
+`;
+
+exports[`generates a named export > no extra args 1`] = `
+"export function foo() {
+ return true;
+}
+"
+`;
+
exports[`generates a nested \`.js\` util 1`] = `
"export default function fooBar() {
return true;
diff --git a/test/generators/component.test.ts b/test/generators/component.test.ts
index 0032e85..da58f70 100644
--- a/test/generators/component.test.ts
+++ b/test/generators/component.test.ts
@@ -1,4 +1,4 @@
-import { afterEach, it } from "vitest";
+import { afterEach, describe, it } from "vitest";
import { Package } from "../helpers.ts";
let pkg: Package;
@@ -107,3 +107,27 @@ it("destroys a component", async (ctx) => {
ctx.expect(await pkg.pathExists("src/components/foo.gjs")).to.equal(false);
});
+
+describe("generates a named export", () => {
+ for (const args of [
+ ["--classBased"],
+ ["--classBased", "--typescript"],
+ ["--typescript"],
+ ]) {
+ it(args.length ? args.join(" ") : "no extra args", async (ctx) => {
+ pkg = await Package.create("v2-addon");
+
+ await pkg.gember("component", "foo", "--namedExport", ...args);
+
+ const content = await pkg.readFile(
+ addExtension("src/components/foo", args),
+ );
+
+ ctx.expect(content).toMatchSnapshot();
+ });
+ }
+});
+
+function addExtension(path: string, args: string[]): string {
+ return path + (args.includes("--typescript") ? ".gts" : ".gjs");
+}
diff --git a/test/generators/helper.test.ts b/test/generators/helper.test.ts
index 9ba6894..f1d08c5 100644
--- a/test/generators/helper.test.ts
+++ b/test/generators/helper.test.ts
@@ -1,4 +1,4 @@
-import { afterEach, it } from "vitest";
+import { afterEach, describe, it } from "vitest";
import { Package } from "../helpers.ts";
let pkg: Package;
@@ -97,3 +97,26 @@ it("destroys a helper", async (ctx) => {
ctx.expect(await pkg.pathExists("src/helpers/foo.js")).to.equal(false);
});
+
+describe("generates a named export", () => {
+ for (const args of [
+ [],
+ ["--classBased"],
+ ["--classBased", "--typescript"],
+ ["--typescript"],
+ ]) {
+ it(args.length ? args.join(" ") : "no extra args", async (ctx) => {
+ pkg = await Package.create("v2-addon");
+
+ await pkg.gember("helper", "foo", "--namedExport", ...args);
+
+ const content = await pkg.readFile(addExtension("src/helpers/foo", args));
+
+ ctx.expect(content).toMatchSnapshot();
+ });
+ }
+});
+
+function addExtension(path: string, args: string[]): string {
+ return path + (args.includes("--typescript") ? ".ts" : ".js");
+}
diff --git a/test/generators/modifier.test.ts b/test/generators/modifier.test.ts
index 8a3964f..2c4b6d3 100644
--- a/test/generators/modifier.test.ts
+++ b/test/generators/modifier.test.ts
@@ -1,4 +1,4 @@
-import { afterEach, it } from "vitest";
+import { afterEach, describe, it } from "vitest";
import { Package } from "../helpers.ts";
let pkg: Package;
@@ -97,3 +97,28 @@ it("destroys a modifier", async (ctx) => {
ctx.expect(await pkg.pathExists("src/modifiers/foo.js")).to.equal(false);
});
+
+describe("generates a named export", () => {
+ for (const args of [
+ [],
+ ["--classBased"],
+ ["--classBased", "--typescript"],
+ ["--typescript"],
+ ]) {
+ it(args.length ? args.join(" ") : "no extra args", async (ctx) => {
+ pkg = await Package.create("v2-addon");
+
+ await pkg.gember("modifier", "foo", "--namedExport", ...args);
+
+ const content = await pkg.readFile(
+ addExtension("src/modifiers/foo", args),
+ );
+
+ ctx.expect(content).toMatchSnapshot();
+ });
+ }
+});
+
+function addExtension(path: string, args: string[]): string {
+ return path + (args.includes("--typescript") ? ".ts" : ".js");
+}
diff --git a/test/generators/util.test.ts b/test/generators/util.test.ts
index 14783ce..64f112c 100644
--- a/test/generators/util.test.ts
+++ b/test/generators/util.test.ts
@@ -1,4 +1,4 @@
-import { afterEach, it } from "vitest";
+import { afterEach, describe, it } from "vitest";
import { Package } from "../helpers.ts";
let pkg: Package;
@@ -87,3 +87,21 @@ it("destroys a util", async (ctx) => {
ctx.expect(await pkg.pathExists("src/utils/foo.js")).to.equal(false);
});
+
+describe("generates a named export", () => {
+ for (const args of [[], ["--typescript"]]) {
+ it(args.length ? args.join(" ") : "no extra args", async (ctx) => {
+ pkg = await Package.create("v2-addon");
+
+ await pkg.gember("util", "foo", "--namedExport", ...args);
+
+ const content = await pkg.readFile(addExtension("src/utils/foo", args));
+
+ ctx.expect(content).toMatchSnapshot();
+ });
+ }
+});
+
+function addExtension(path: string, args: string[]): string {
+ return path + (args.includes("--typescript") ? ".ts" : ".js");
+}