@blotch/angular-lynx 22.2.1 → 22.2.2

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blotch/angular-lynx",
3
- "version": "22.2.1",
3
+ "version": "22.2.2",
4
4
  "description": "Angular renderer for the Lynx cross-platform native UI framework",
5
5
  "homepage": "https://github.com/Blotch-Smart-Frames/AngularLynx#readme",
6
6
  "bugs": {
@@ -12,11 +12,6 @@
12
12
  "url": "git+https://github.com/Blotch-Smart-Frames/AngularLynx.git",
13
13
  "directory": "packages/runtime"
14
14
  },
15
- "files": [
16
- "dist",
17
- "schematics",
18
- "README.md"
19
- ],
20
15
  "sideEffects": false,
21
16
  "exports": {
22
17
  "./package.json": {
@@ -46,6 +41,16 @@
46
41
  "optional": true
47
42
  }
48
43
  },
44
+ "ng-update": {
45
+ "migrations": "./schematics/migrations.json",
46
+ "packageGroup": [
47
+ "@blotch/angular-lynx",
48
+ "@blotch/angular-lynx-build",
49
+ "@blotch/angular-lynx-testing-library",
50
+ "@blotch/rsbuild-plugin-angular-lynx",
51
+ "@blotch/angular-lynx-native"
52
+ ]
53
+ },
49
54
  "schematics": "./schematics/collection.json",
50
55
  "module": "fesm2022/blotch-angular-lynx.mjs",
51
56
  "typings": "types/blotch-angular-lynx.d.ts",
@@ -0,0 +1,151 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const schematics_1 = require("@angular-devkit/schematics");
4
+ const dependency_1 = require("@schematics/angular/utility/dependency");
5
+ const json_file_1 = require("@schematics/angular/utility/json-file");
6
+ const workspace_1 = require("@schematics/angular/utility/workspace");
7
+ /**
8
+ * Wires Angular's `@angular/localize` package into an AngularLynx app and
9
+ * provides the Lynx-aware `provideLocale()` provider that reads the active
10
+ * locale from Lynx's SystemInfo.
11
+ *
12
+ * Four-step setup, each step idempotent so re-running is safe:
13
+ * 1. **angular.json `i18n` block** — declares the source locale so any
14
+ * `ng extract-i18n` runs produce the right XLIFF.
15
+ * 2. **`@angular/localize/init` polyfill** — must run before the app boots
16
+ * so the global `$localize` function exists when components are
17
+ * instantiated.
18
+ * 3. **tsconfig `types`** — adds @angular/localize so $localize is typed
19
+ * and TypeScript doesn't flag it as an undefined global.
20
+ * 4. **provideLocale() in app.config** — registers the runtime provider
21
+ * that reads SystemInfo.language / appLocale and applies it to Angular's
22
+ * LOCALE_ID token.
23
+ */
24
+ exports.default = (options) => async (tree) => {
25
+ const workspace = await (0, workspace_1.getWorkspace)(tree);
26
+ const projectName = options.project ??
27
+ workspace.extensions['defaultProject'] ??
28
+ [...workspace.projects.keys()][0];
29
+ if (!projectName) {
30
+ throw new schematics_1.SchematicsException('No project found. Run this schematic inside an Angular workspace.');
31
+ }
32
+ const project = workspace.projects.get(projectName);
33
+ if (!project) {
34
+ throw new schematics_1.SchematicsException(`Project "${projectName}" not found in angular.json.`);
35
+ }
36
+ const sourceRoot = (project.sourceRoot ?? `${project.root}/src`);
37
+ const projectRoot = project.root;
38
+ return (0, schematics_1.chain)([
39
+ addI18nToAngularJson(projectName),
40
+ addLocalizeTypes(projectRoot),
41
+ updateAppConfig(sourceRoot),
42
+ addLocalizeDependency(),
43
+ ]);
44
+ };
45
+ const addI18nToAngularJson = (projectName) => {
46
+ return (tree) => {
47
+ const angularJson = new json_file_1.JSONFile(tree, '/angular.json');
48
+ const existingI18n = angularJson.get(['projects', projectName, 'i18n']);
49
+ if (!existingI18n) {
50
+ angularJson.modify(['projects', projectName, 'i18n'], {
51
+ sourceLocale: 'en-US',
52
+ });
53
+ }
54
+ // `@angular/localize/init` must be in `polyfills`, not a regular import.
55
+ // It patches the global `$localize` function before the app boots — if
56
+ // it's loaded lazily via a normal import, some translated strings can be
57
+ // called before the patch is in place and throw at runtime.
58
+ const polyfillsPath = [
59
+ 'projects',
60
+ projectName,
61
+ 'architect',
62
+ 'build',
63
+ 'options',
64
+ 'polyfills',
65
+ ];
66
+ const polyfills = angularJson.get(polyfillsPath) ?? [];
67
+ if (!polyfills.includes('@angular/localize/init')) {
68
+ angularJson.modify(polyfillsPath, [
69
+ ...polyfills,
70
+ '@angular/localize/init',
71
+ ]);
72
+ }
73
+ };
74
+ };
75
+ const addLocalizeTypes = (projectRoot) => {
76
+ return (tree) => {
77
+ const tsconfigPath = `${projectRoot ? projectRoot + '/' : ''}tsconfig.app.json`;
78
+ if (!tree.exists(tsconfigPath)) {
79
+ return;
80
+ }
81
+ const tsconfig = new json_file_1.JSONFile(tree, tsconfigPath);
82
+ const types = tsconfig.get(['compilerOptions', 'types']) ?? [];
83
+ if (!types.includes('@angular/localize')) {
84
+ tsconfig.modify(['compilerOptions', 'types'], [...types, '@angular/localize']);
85
+ }
86
+ };
87
+ };
88
+ const updateAppConfig = (sourceRoot) => {
89
+ return (tree) => {
90
+ const configPath = `${sourceRoot}/app/app.config.ts`;
91
+ if (!tree.exists(configPath)) {
92
+ return;
93
+ }
94
+ let content = tree.readText(configPath);
95
+ // Idempotency guard: if the user has already imported provideLocale
96
+ // (either from a previous run or by hand), bail out — re-running would
97
+ // duplicate the import and the providers entry, breaking the file.
98
+ if (content.includes('provideLocale')) {
99
+ return;
100
+ }
101
+ // Two paths for adding the symbol to imports:
102
+ // - If `@blotch/angular-lynx` is already imported (the common case
103
+ // after `ng add @blotch/angular-lynx`), append provideLocale to the
104
+ // existing destructured import list. We split on `,` and rebuild so
105
+ // trailing commas and whitespace are normalized regardless of the
106
+ // user's formatting preferences.
107
+ // - Otherwise prepend a brand-new import line at the top of the file.
108
+ // This branch shouldn't normally fire (add-i18n is meant to run on
109
+ // projects that already went through ng-add), but it keeps the
110
+ // schematic self-contained if someone runs it standalone.
111
+ if (content.includes("from '@blotch/angular-lynx'")) {
112
+ content = content.replace(/import\s*\{([^}]*)\}\s*from\s*['"]@blotch\/angular-lynx['"]/, (match, imports) => {
113
+ const importList = imports
114
+ .split(',')
115
+ .map((s) => s.trim())
116
+ .filter(Boolean);
117
+ importList.push('provideLocale');
118
+ return `import { ${importList.join(', ')} } from '@blotch/angular-lynx'`;
119
+ });
120
+ }
121
+ else {
122
+ content =
123
+ `import { provideLocale } from '@blotch/angular-lynx';\n` + content;
124
+ }
125
+ // Insert provideLocale() as the FIRST provider so it runs before
126
+ // anything that might call $localize during construction (e.g. a service
127
+ // that formats a date with a localized pattern at module load time).
128
+ // The regex matches `providers: [` and inserts on a new line right
129
+ // after, preserving the user's indentation/style for the rest of the array.
130
+ content = content.replace(/providers:\s*\[/, 'providers: [\n provideLocale(),');
131
+ tree.overwrite(configPath, content);
132
+ };
133
+ };
134
+ const addLocalizeDependency = () => {
135
+ return (tree) => {
136
+ // @angular/localize must match the rest of Angular, so it takes the app's
137
+ // own @angular/core range, as Angular Material's `ng add` does for the
138
+ // Angular packages it adds. A range written out here would install the
139
+ // wrong major once the app moves to the next Angular.
140
+ const pkg = new json_file_1.JSONFile(tree, '/package.json');
141
+ const coreRange = pkg.get(['dependencies', '@angular/core']) ??
142
+ pkg.get(['devDependencies', '@angular/core']);
143
+ if (typeof coreRange !== 'string') {
144
+ throw new schematics_1.SchematicsException("package.json doesn't list @angular/core, so add-i18n can't tell which @angular/localize version matches the app's Angular.");
145
+ }
146
+ return (0, dependency_1.addDependency)('@angular/localize', coreRange, {
147
+ type: dependency_1.DependencyType.Dev,
148
+ install: dependency_1.InstallBehavior.Auto,
149
+ });
150
+ };
151
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const schematics_1 = require("@angular-devkit/schematics");
4
+ const dependency_1 = require("@schematics/angular/utility/dependency");
5
+ const workspace_1 = require("@schematics/angular/utility/workspace");
6
+ const versions_1 = require("../ng-add/versions");
7
+ /**
8
+ * Adds Tailwind CSS to an existing AngularLynx project. This is split out
9
+ * from `ng-add` because users may opt out of Tailwind at scaffold time
10
+ * (`ng add @blotch/angular-lynx --tailwind=false`) but later change their
11
+ * minds — running this schematic later is the supported recovery path.
12
+ *
13
+ * Three steps, each idempotent:
14
+ * 1. **tailwind.config.ts** — written with `@lynx-js/tailwind-preset` as
15
+ * the only preset. The preset narrows Tailwind's class output to the
16
+ * subset Lynx's CSS engine can parse (no logical properties, no
17
+ * `:has()` selectors, no advanced color functions).
18
+ * 2. **styles.css/scss** — replaced with the Tailwind base + utilities
19
+ * layer directives (no components layer; see ng-add for why).
20
+ * 3. **package.json deps** — adds tailwindcss + the Lynx preset.
21
+ */
22
+ exports.default = (options) => async (tree) => {
23
+ const workspace = await (0, workspace_1.getWorkspace)(tree);
24
+ const projectName = options.project ??
25
+ workspace.extensions['defaultProject'] ??
26
+ [...workspace.projects.keys()][0];
27
+ if (!projectName) {
28
+ throw new schematics_1.SchematicsException('No project found. Run this schematic inside an Angular workspace.');
29
+ }
30
+ const project = workspace.projects.get(projectName);
31
+ if (!project) {
32
+ throw new schematics_1.SchematicsException(`Project "${projectName}" not found in angular.json.`);
33
+ }
34
+ const sourceRoot = (project.sourceRoot ?? `${project.root}/src`);
35
+ const projectRoot = project.root;
36
+ return (0, schematics_1.chain)([
37
+ addTailwindConfig(projectRoot),
38
+ updateStylesCss(sourceRoot),
39
+ addTailwindDependencies(),
40
+ ]);
41
+ };
42
+ const addTailwindConfig = (projectRoot) => {
43
+ return (tree) => {
44
+ const configPath = `${projectRoot ? projectRoot + '/' : ''}tailwind.config.ts`;
45
+ // content: ['./src/**/*.ts'] scans only .ts files — AngularLynx components
46
+ // inline their templates (no .html template files), so all class names
47
+ // live in TypeScript source. Including .html in the glob would just slow
48
+ // the watcher down without finding anything.
49
+ const content = `import type { Config } from 'tailwindcss';
50
+ import preset from '@lynx-js/tailwind-preset';
51
+
52
+ const config: Config = {
53
+ content: ['./src/**/*.ts'],
54
+ presets: [preset],
55
+ };
56
+
57
+ export default config;
58
+ `;
59
+ if (tree.exists(configPath)) {
60
+ tree.overwrite(configPath, content);
61
+ }
62
+ else {
63
+ tree.create(configPath, content);
64
+ }
65
+ };
66
+ };
67
+ const updateStylesCss = (sourceRoot) => {
68
+ return (tree) => {
69
+ const cssPath = `${sourceRoot}/styles.css`;
70
+ const scssPath = `${sourceRoot}/styles.scss`;
71
+ // Prefer styles.scss if it exists (the user picked SCSS at `ng new` time)
72
+ // — overwriting it with .css content would break their other imports.
73
+ const targetPath = tree.exists(scssPath) ? scssPath : cssPath;
74
+ // Only @tailwind base + utilities — no @tailwind components. Lynx's CSS
75
+ // engine doesn't parse many component-layer reset rules (focus-visible
76
+ // pseudo-class, form input pseudo-classes), which would produce
77
+ // diagnostic noise at build time. The base layer ships with the Lynx
78
+ // preset's own compatibility-safe normalize rules.
79
+ const content = `@tailwind base;
80
+ @tailwind utilities;
81
+ `;
82
+ if (tree.exists(targetPath)) {
83
+ tree.overwrite(targetPath, content);
84
+ }
85
+ else {
86
+ tree.create(cssPath, content);
87
+ }
88
+ };
89
+ };
90
+ const addTailwindDependencies = () => {
91
+ return (0, schematics_1.chain)([
92
+ (0, dependency_1.addDependency)('tailwindcss', versions_1.VERSIONS.tailwindcss, {
93
+ type: dependency_1.DependencyType.Dev,
94
+ install: dependency_1.InstallBehavior.Auto,
95
+ }),
96
+ (0, dependency_1.addDependency)('@lynx-js/tailwind-preset', versions_1.VERSIONS.tailwindPreset, {
97
+ type: dependency_1.DependencyType.Dev,
98
+ install: dependency_1.InstallBehavior.Auto,
99
+ }),
100
+ ]);
101
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const schematics_1 = require("@angular-devkit/schematics");
4
+ const dependency_1 = require("@schematics/angular/utility/dependency");
5
+ const json_file_1 = require("@schematics/angular/utility/json-file");
6
+ const workspace_1 = require("@schematics/angular/utility/workspace");
7
+ const versions_1 = require("../ng-add/versions");
8
+ exports.default = (options) => async (tree) => {
9
+ const workspace = await (0, workspace_1.getWorkspace)(tree);
10
+ const projectName = options.project ??
11
+ workspace.extensions['defaultProject'] ??
12
+ [...workspace.projects.keys()][0];
13
+ if (!projectName) {
14
+ throw new schematics_1.SchematicsException('No project found. Run this schematic inside an Angular workspace.');
15
+ }
16
+ const project = workspace.projects.get(projectName);
17
+ if (!project) {
18
+ throw new schematics_1.SchematicsException(`Project "${projectName}" not found in angular.json.`);
19
+ }
20
+ return (0, schematics_1.chain)([
21
+ useLynxTestBuilder(projectName),
22
+ updatePackageScripts(),
23
+ addTestingDependencies(),
24
+ ]);
25
+ };
26
+ /**
27
+ * Tests run with `ng test`, through the AngularLynx unit-test builder (which
28
+ * `ng add` already sets up; this covers projects set up before it). It sets
29
+ * up the testing library's Lynx environment itself when the package is
30
+ * installed, so the project needs no Vitest config or setup file of its own.
31
+ */
32
+ const useLynxTestBuilder = (projectName) => (0, workspace_1.updateWorkspace)((workspace) => {
33
+ const project = workspace.projects.get(projectName);
34
+ const test = project.targets.get('test');
35
+ if (test?.builder === '@blotch/angular-lynx-build:unit-test') {
36
+ return;
37
+ }
38
+ if (test) {
39
+ project.targets.delete('test');
40
+ }
41
+ project.targets.add({
42
+ name: 'test',
43
+ builder: '@blotch/angular-lynx-build:unit-test',
44
+ });
45
+ });
46
+ const updatePackageScripts = () => {
47
+ return (tree) => {
48
+ // `ng test` watches by default when run in a terminal, so the separate
49
+ // watch script this schematic used to add is gone with Vitest's.
50
+ const pkg = new json_file_1.JSONFile(tree, '/package.json');
51
+ pkg.modify(['scripts', 'test'], 'ng test');
52
+ if (pkg.get(['scripts', 'test:watch']) === 'vitest') {
53
+ pkg.remove(['scripts', 'test:watch']);
54
+ }
55
+ };
56
+ };
57
+ const addTestingDependencies = () => {
58
+ return (0, schematics_1.chain)([
59
+ // At this package's own release, like the builders `ng add` installs.
60
+ (0, dependency_1.addDependency)('@blotch/angular-lynx-testing-library', (0, versions_1.ownVersionRange)(), {
61
+ type: dependency_1.DependencyType.Dev,
62
+ install: dependency_1.InstallBehavior.Auto,
63
+ }),
64
+ // `ng new` already adds vitest and jsdom: keep the project's versions
65
+ // rather than replacing them (the default), which silently downgraded
66
+ // every new project. The testing library works with Vitest 4 and 5 and
67
+ // jsdom 25 to 30. The E2E tests run `npm test` in a fresh `ng new`
68
+ // project to keep it that way.
69
+ (0, dependency_1.addDependency)('vitest', versions_1.VERSIONS.vitest, {
70
+ type: dependency_1.DependencyType.Dev,
71
+ install: dependency_1.InstallBehavior.Auto,
72
+ existing: dependency_1.ExistingBehavior.Skip,
73
+ }),
74
+ (0, dependency_1.addDependency)('jsdom', versions_1.VERSIONS.jsdom, {
75
+ type: dependency_1.DependencyType.Dev,
76
+ install: dependency_1.InstallBehavior.Auto,
77
+ existing: dependency_1.ExistingBehavior.Skip,
78
+ }),
79
+ ]);
80
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -11,7 +11,7 @@
11
11
  "schema": "./add-tailwind/schema.json"
12
12
  },
13
13
  "add-testing": {
14
- "description": "Adds AngularLynx Testing Library with Vitest to an existing project",
14
+ "description": "Adds the AngularLynx Testing Library, which `ng test` sets up for rendering components on Lynx",
15
15
  "factory": "./add-testing/index",
16
16
  "schema": "./add-testing/schema.json"
17
17
  },
@@ -21,10 +21,15 @@
21
21
  "schema": "./add-i18n/schema.json"
22
22
  },
23
23
  "component": {
24
- "description": "Generates a standalone Angular component with Lynx element template",
24
+ "description": "Generates a component with Angular's component schematic, with a Lynx element template and LYNX_ELEMENTS imported",
25
25
  "factory": "./component/index",
26
26
  "schema": "./component/schema.json",
27
27
  "aliases": ["c"]
28
+ },
29
+ "eject": {
30
+ "description": "Writes the generated iOS and Android projects into ios/ and android/ for native changes (one-way)",
31
+ "factory": "./eject/index",
32
+ "schema": "./eject/schema.json"
28
33
  }
29
34
  }
30
35
  }
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const core_1 = require("@angular-devkit/core");
4
+ const schematics_1 = require("@angular-devkit/schematics");
5
+ /**
6
+ * `ng generate component` for Lynx (`ng add` makes it the one
7
+ * `ng generate component` runs). Angular's own component schematic generates
8
+ * the files, so every option, file name and angular.json default works as it
9
+ * does in any Angular app. Then the component becomes a Lynx one:
10
+ *
11
+ * 1. **Its template uses Lynx elements**: `<view><text>…</text></view>`
12
+ * instead of `<p>…</p>`, which Lynx has no element for.
13
+ * 2. **It imports LYNX_ELEMENTS**, the directives that declare Lynx's
14
+ * elements to Angular, so the template type-checks in the editor and
15
+ * under `ng test`, as it does in the app build.
16
+ * 3. **Its test renders it on Lynx** when the project has
17
+ * @blotch/angular-lynx-testing-library: a `*.test.ts` that renders the
18
+ * component through the Lynx renderer, in place of Angular's TestBed
19
+ * spec, which renders it with the DOM renderer. Without the library,
20
+ * Angular's spec stays: `ng test` runs both.
21
+ */
22
+ exports.default = (options) => async (tree) => {
23
+ const before = createdFiles(tree);
24
+ return (0, schematics_1.chain)([
25
+ (0, schematics_1.externalSchematic)('@schematics/angular', 'component', withoutUnset(options)),
26
+ (tree) => {
27
+ const created = [...createdFiles(tree)].filter((file) => !before.has(file));
28
+ const componentFile = created.find((file) => file.endsWith('.ts') && !file.endsWith('.spec.ts'));
29
+ if (!componentFile) {
30
+ return;
31
+ }
32
+ for (const file of created) {
33
+ if (file.endsWith('.html')) {
34
+ tree.overwrite(file, lynxTemplate(tree.readText(file)));
35
+ }
36
+ }
37
+ tree.overwrite(componentFile, lynxComponent(tree.readText(componentFile)));
38
+ const specFile = created.find((file) => file.endsWith('.spec.ts'));
39
+ if (specFile && hasTestingLibrary(tree)) {
40
+ tree.delete(specFile);
41
+ tree.create(specFile.replace(/\.spec\.ts$/, '.test.ts'), lynxTest(tree.readText(componentFile), componentFile, options.name));
42
+ }
43
+ },
44
+ ]);
45
+ };
46
+ /**
47
+ * The options the user (or angular.json's defaults for this schematic) set.
48
+ * Leaving the rest out lets Angular CLI apply angular.json's defaults for
49
+ * `@schematics/angular:component` (e.g. `style: scss` from
50
+ * `ng new --style scss`), then Angular's own, as `ng generate component`
51
+ * does without AngularLynx.
52
+ */
53
+ const withoutUnset = (options) => Object.fromEntries(Object.entries(options).filter(([, value]) => value !== undefined));
54
+ /**
55
+ * The files created so far in this run.
56
+ */
57
+ const createdFiles = (tree) => new Set(tree.actions
58
+ .filter((action) => action.kind === 'c')
59
+ .map((action) => action.path));
60
+ /**
61
+ * Angular's placeholder paragraph (`<p>name works!</p>`, in a template file
62
+ * or inline), as Lynx elements. Lynx has no `<p>`: text goes in `<text>`,
63
+ * inside a `<view>` for layout.
64
+ */
65
+ const lynxTemplate = (source) => source.replace(/^([ \t]*)<p>\s*([\s\S]*?)\s*<\/p>/m, (_match, indent, text) => `${indent}<view>\n${indent} <text>${text}</text>\n${indent}</view>`);
66
+ /**
67
+ * The generated component, with a Lynx template if it's inline, and
68
+ * LYNX_ELEMENTS among its imports. A component declared in an NgModule
69
+ * (`--standalone false`) has no `imports` of its own; its module would import
70
+ * them, so it's left as Angular generates it.
71
+ */
72
+ const lynxComponent = (source) => {
73
+ const component = lynxTemplate(source);
74
+ if (!/^\s*imports: \[\],$/m.test(component)) {
75
+ return component;
76
+ }
77
+ return component
78
+ .replace(/^(\s*)imports: \[\],$/m, '$1imports: [LYNX_ELEMENTS],')
79
+ .replace(/^(import .* from '@angular\/core';)$/m, "$1\nimport { LYNX_ELEMENTS } from '@blotch/angular-lynx';");
80
+ };
81
+ const hasTestingLibrary = (tree) => {
82
+ if (!tree.exists('/package.json')) {
83
+ return false;
84
+ }
85
+ const packageJson = tree.readJson('/package.json');
86
+ return [packageJson.dependencies, packageJson.devDependencies].some((dependencies) => dependencies?.['@blotch/angular-lynx-testing-library'] !== undefined);
87
+ };
88
+ /**
89
+ * A test that renders the component on Lynx with the testing library and
90
+ * finds its placeholder text, in place of Angular's TestBed spec.
91
+ */
92
+ const lynxTest = (component, componentFile, name) => {
93
+ const className = /export (?:default )?class (\w+)/.exec(component)[1];
94
+ const isDefault = /export default class/.test(component);
95
+ const importPath = `./${componentFile.split('/').pop().replace(/\.ts$/, '')}`;
96
+ // The text Angular's template says: the name's last segment, dasherized.
97
+ const text = `${core_1.strings.dasherize(name.split('/').pop())} works!`;
98
+ return `import { render } from '@blotch/angular-lynx-testing-library';
99
+ import { describe, expect, it } from 'vitest';
100
+
101
+ import ${isDefault ? className : `{ ${className} }`} from '${importPath}';
102
+
103
+ describe('${className}', () => {
104
+ it('should render', async () => {
105
+ const { getByText } = await render(${className});
106
+ expect(getByText('${text}')).toBeTruthy();
107
+ });
108
+ });
109
+ `;
110
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });