create-analog 1.9.0-beta.1 → 1.9.0-beta.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.
Files changed (34) hide show
  1. package/files/analog-env.d.ts +9 -0
  2. package/files/styles.css +5 -0
  3. package/index.js +90 -32
  4. package/package.json +1 -1
  5. package/template-angular-v16/package.json +5 -5
  6. package/template-angular-v17/package.json +5 -5
  7. package/template-blog/package.json +5 -5
  8. package/template-blog/src/app/app-root.ag +25 -0
  9. package/template-blog/src/app/app-root.spec.ts +20 -0
  10. package/template-blog/src/app/app.component.spec.ts +5 -2
  11. package/template-blog/src/app/app.component.ts +16 -17
  12. package/template-blog/src/app/pages/blog/[slug].page.ag +24 -0
  13. package/template-blog/src/app/pages/blog/[slug].page.ts +6 -8
  14. package/template-blog/src/app/pages/blog/index.page.ag +32 -0
  15. package/template-blog/src/app/pages/blog/index.page.ts +15 -15
  16. package/template-blog/src/main.server.ts +2 -2
  17. package/template-blog/src/main.ts +2 -2
  18. package/template-blog/vite.config.ts +1 -1
  19. package/template-latest/package.json +5 -5
  20. package/template-latest/src/app/app-root.ag +16 -0
  21. package/template-latest/src/app/app-root.spec.ts +20 -0
  22. package/template-latest/src/app/app.component.ts +8 -10
  23. package/template-latest/src/app/pages/index.page.ag +53 -0
  24. package/template-latest/src/app/pages/index.page.ts +20 -20
  25. package/template-latest/src/main.server.ts +2 -2
  26. package/template-latest/src/main.ts +2 -2
  27. package/template-latest/src/styles.css +5 -0
  28. package/template-latest/vite.config.ts +1 -1
  29. package/template-minimal/src/app/app-root.ag +7 -0
  30. package/template-minimal/src/app/pages/index.page.ag +32 -0
  31. package/template-minimal/src/app/pages/index.page.ts +4 -3
  32. package/template-minimal/src/main.server.ts +2 -2
  33. package/template-minimal/src/main.ts +2 -2
  34. package/template-minimal/vite.config.ts +1 -1
@@ -0,0 +1,9 @@
1
+ declare module '*.analog' {
2
+ const cmp: any;
3
+ export default cmp;
4
+ }
5
+
6
+ declare module '*.ag' {
7
+ const cmp: any;
8
+ export default cmp;
9
+ }
package/files/styles.css CHANGED
@@ -26,6 +26,7 @@ a {
26
26
  color: #646cff;
27
27
  text-decoration: inherit;
28
28
  }
29
+
29
30
  a:hover {
30
31
  color: #535bf2;
31
32
  }
@@ -54,9 +55,11 @@ button {
54
55
  cursor: pointer;
55
56
  transition: border-color 0.25s;
56
57
  }
58
+
57
59
  button:hover {
58
60
  border-color: #646cff;
59
61
  }
62
+
60
63
  button:focus,
61
64
  button:focus-visible {
62
65
  outline: 4px auto -webkit-focus-ring-color;
@@ -75,9 +78,11 @@ button:focus-visible {
75
78
  color: #213547;
76
79
  background-color: #ffffff;
77
80
  }
81
+
78
82
  a:hover {
79
83
  color: #747bff;
80
84
  }
85
+
81
86
  button {
82
87
  background-color: #f9f9f9;
83
88
  }
package/index.js CHANGED
@@ -4,8 +4,8 @@
4
4
  import { blue, green, red, reset, yellow } from 'kolorist';
5
5
  import minimist from 'minimist';
6
6
  import { execSync } from 'node:child_process';
7
- import fs, { readdirSync } from 'node:fs';
8
- import path, { join } from 'node:path';
7
+ import fs from 'node:fs';
8
+ import path from 'node:path';
9
9
  import { fileURLToPath } from 'node:url';
10
10
  import prompts from 'prompts';
11
11
 
@@ -64,7 +64,8 @@ const renameFiles = {
64
64
  async function init() {
65
65
  let targetDir = formatTargetDir(argv._[0]);
66
66
  let template = argv.template || argv.t;
67
- let skipTailwind = argv.skipTailwind || false;
67
+ let skipTailwind = fromBoolArg(argv.skipTailwind);
68
+ let useAnalogSFC = fromBoolArg(argv.analogSFC);
68
69
 
69
70
  const defaultTargetDir = 'analog-project';
70
71
  const getProjectName = () =>
@@ -135,7 +136,12 @@ async function init() {
135
136
  initial: 1,
136
137
  },
137
138
  {
138
- type: skipTailwind ? null : 'confirm',
139
+ type: useAnalogSFC === undefined ? 'confirm' : null,
140
+ name: 'analogSFC',
141
+ message: 'Would you like to use Analog SFCs?',
142
+ },
143
+ {
144
+ type: skipTailwind === undefined ? 'confirm' : null,
139
145
  name: 'tailwind',
140
146
  message: 'Would you like to add Tailwind to your project?',
141
147
  },
@@ -157,6 +163,7 @@ async function init() {
157
163
  overwrite,
158
164
  packageName,
159
165
  variant,
166
+ analogSFC,
160
167
  tailwind,
161
168
  syntaxHighlighter,
162
169
  } = result;
@@ -173,7 +180,8 @@ async function init() {
173
180
  template = variant || framework || template;
174
181
  // determine syntax highlighter
175
182
  let highlighter = syntaxHighlighter ?? (template === 'blog' ? 'prism' : null);
176
- skipTailwind = !tailwind || skipTailwind;
183
+ skipTailwind = skipTailwind ?? !tailwind;
184
+ useAnalogSFC = useAnalogSFC ?? analogSFC;
177
185
 
178
186
  console.log(`\nScaffolding project in ${root}...`);
179
187
 
@@ -235,6 +243,7 @@ async function init() {
235
243
  write('package.json', JSON.stringify(pkg, null, 2));
236
244
 
237
245
  setProjectTitle(root, getProjectName());
246
+ setComponentFormat(root, filesDir, write, template, useAnalogSFC);
238
247
 
239
248
  console.log(`\nInitializing git repository:`);
240
249
  execSync(`git init ${targetDir} && cd ${targetDir} && git add .`);
@@ -397,31 +406,19 @@ function addYarnDevDependencies(pkg, template) {
397
406
  }
398
407
 
399
408
  function ensureSyntaxHighlighter(root, pkg, highlighter) {
400
- const appConfigPath = path.join(root, 'src/app/app.config.ts');
401
- const appConfigContent = fs.readFileSync(appConfigPath, 'utf-8');
402
-
403
- fs.writeFileSync(
404
- appConfigPath,
405
- appConfigContent
406
- .replace(/__HIGHLIGHTER__/g, HIGHLIGHTERS[highlighter].highlighter)
407
- .replace(
408
- /__HIGHLIGHTER_ENTRY_POINT__/g,
409
- HIGHLIGHTERS[highlighter].entryPoint
410
- )
411
- );
409
+ replacePlaceholders(root, 'src/app/app.config.ts', {
410
+ __HIGHLIGHTER__: HIGHLIGHTERS[highlighter].highlighter,
411
+ __HIGHLIGHTER_ENTRY_POINT__: HIGHLIGHTERS[highlighter].entryPoint,
412
+ });
412
413
 
413
414
  const dependencies = HIGHLIGHTERS[highlighter].dependencies;
414
415
  for (const [name, version] of Object.entries(dependencies)) {
415
416
  pkg.dependencies[name] = version;
416
417
  }
417
418
 
418
- const viteConfigPath = path.join(root, 'vite.config.ts');
419
- const viteConfigContent = fs.readFileSync(viteConfigPath, 'utf-8');
420
-
421
- fs.writeFileSync(
422
- viteConfigPath,
423
- viteConfigContent.replace(/__CONTENT_HIGHLIGHTER__/g, highlighter)
424
- );
419
+ replacePlaceholders(root, 'vite.config.ts', {
420
+ __CONTENT_HIGHLIGHTER__: highlighter,
421
+ });
425
422
  }
426
423
 
427
424
  function sortObjectKeys(obj) {
@@ -434,20 +431,81 @@ function sortObjectKeys(obj) {
434
431
  }
435
432
 
436
433
  function setProjectTitle(root, title) {
437
- const filePaths = [
438
- path.join(root, 'index.html'),
439
- path.join(root, 'README.md'),
440
- ];
434
+ replacePlaceholders(root, ['index.html', 'README.md'], {
435
+ __PROJECT_TITLE__: title,
436
+ });
437
+ }
438
+
439
+ function setComponentFormat(root, filesDir, write, template, useAnalogSFC) {
440
+ const getSFCConfig = () => {
441
+ const sfcConfigOption =
442
+ 'vite: { experimental: { supportAnalogFormat: true } }';
443
+
444
+ return template === 'latest'
445
+ ? `{ ${sfcConfigOption} }`
446
+ : `\n ${sfcConfigOption},`;
447
+ };
448
+
449
+ replacePlaceholders(root, 'vite.config.ts', {
450
+ __ANALOG_SFC_CONFIG__: useAnalogSFC ? getSFCConfig() : '',
451
+ });
452
+ replacePlaceholders(root, ['src/main.ts', 'src/main.server.ts'], {
453
+ __APP_COMPONENT__: useAnalogSFC ? 'App' : 'AppComponent',
454
+ __APP_COMPONENT_IMPORT__: useAnalogSFC
455
+ ? "import App from './app/app-root.ag';"
456
+ : "import { AppComponent } from './app/app.component';",
457
+ });
458
+
459
+ const cmpForDelete = useAnalogSFC ? 'app.component' : 'app-root';
460
+ const deleteExt = useAnalogSFC ? 'ts' : 'ag';
461
+ deleteFiles(root, [
462
+ useAnalogSFC ? `src/app/${cmpForDelete}.ts` : `src/app/${cmpForDelete}.ag`,
463
+ template === 'blog'
464
+ ? [
465
+ `src/app/pages/blog/index.page.${deleteExt}`,
466
+ `src/app/pages/blog/[slug].page.${deleteExt}`,
467
+ ]
468
+ : `src/app/pages/index.page.${deleteExt}`,
469
+ template !== 'minimal' && `src/app/${cmpForDelete}.spec.ts`,
470
+ ]);
471
+
472
+ if (useAnalogSFC) {
473
+ write(
474
+ 'src/analog-env.d.ts',
475
+ fs.readFileSync(path.join(filesDir, 'analog-env.d.ts'), 'utf-8')
476
+ );
477
+ }
478
+ }
441
479
 
442
- for (const filePath of filePaths) {
480
+ function replacePlaceholders(root, files, config) {
481
+ for (const file of toFlatArray(files)) {
482
+ const filePath = path.join(root, file);
443
483
  const fileContent = fs.readFileSync(filePath, 'utf-8');
444
- fs.writeFileSync(
445
- filePath,
446
- fileContent.replace(/__PROJECT_TITLE__/g, title)
484
+ const newFileContent = Object.keys(config).reduce(
485
+ (content, placeholder) =>
486
+ content.replace(RegExp(placeholder, 'g'), config[placeholder]),
487
+ fileContent
447
488
  );
489
+ fs.writeFileSync(filePath, newFileContent);
490
+ }
491
+ }
492
+
493
+ function deleteFiles(root, files) {
494
+ for (const file of toFlatArray(files)) {
495
+ fs.unlinkSync(path.join(root, file));
448
496
  }
449
497
  }
450
498
 
499
+ function toFlatArray(value) {
500
+ return (Array.isArray(value) ? value : [value]).filter(Boolean).flat();
501
+ }
502
+
503
+ function fromBoolArg(arg) {
504
+ return ['boolean', 'undefined'].includes(typeof arg)
505
+ ? arg
506
+ : ['', 'true'].includes(arg);
507
+ }
508
+
451
509
  init().catch((e) => {
452
510
  console.error(e);
453
511
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-analog",
3
- "version": "1.9.0-beta.1",
3
+ "version": "1.9.0-beta.2",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "author": "Brandon Roberts",
@@ -15,8 +15,8 @@
15
15
  "test": "ng test"
16
16
  },
17
17
  "dependencies": {
18
- "@analogjs/content": "^1.9.0-beta.1",
19
- "@analogjs/router": "^1.9.0-beta.1",
18
+ "@analogjs/content": "^1.9.0-beta.2",
19
+ "@analogjs/router": "^1.9.0-beta.2",
20
20
  "@angular/animations": "^16.2.0",
21
21
  "@angular/common": "^16.2.0",
22
22
  "@angular/compiler": "^16.2.0",
@@ -38,9 +38,9 @@
38
38
  "zone.js": "~0.13.0"
39
39
  },
40
40
  "devDependencies": {
41
- "@analogjs/platform": "^1.9.0-beta.1",
42
- "@analogjs/vite-plugin-angular": "^1.9.0-beta.1",
43
- "@analogjs/vitest-angular": "^1.9.0-beta.1",
41
+ "@analogjs/platform": "^1.9.0-beta.2",
42
+ "@analogjs/vite-plugin-angular": "^1.9.0-beta.2",
43
+ "@analogjs/vitest-angular": "^1.9.0-beta.2",
44
44
  "@angular-devkit/build-angular": "^16.2.0",
45
45
  "@angular/cli": "^16.2.0",
46
46
  "@angular/compiler-cli": "^16.2.0",
@@ -15,8 +15,8 @@
15
15
  "test": "ng test"
16
16
  },
17
17
  "dependencies": {
18
- "@analogjs/content": "^1.9.0-beta.1",
19
- "@analogjs/router": "^1.9.0-beta.1",
18
+ "@analogjs/content": "^1.9.0-beta.2",
19
+ "@analogjs/router": "^1.9.0-beta.2",
20
20
  "@angular/animations": "^17.2.0",
21
21
  "@angular/common": "^17.2.0",
22
22
  "@angular/compiler": "^17.2.0",
@@ -38,9 +38,9 @@
38
38
  "zone.js": "~0.14.0"
39
39
  },
40
40
  "devDependencies": {
41
- "@analogjs/platform": "^1.9.0-beta.1",
42
- "@analogjs/vite-plugin-angular": "^1.9.0-beta.1",
43
- "@analogjs/vitest-angular": "^1.9.0-beta.1",
41
+ "@analogjs/platform": "^1.9.0-beta.2",
42
+ "@analogjs/vite-plugin-angular": "^1.9.0-beta.2",
43
+ "@analogjs/vitest-angular": "^1.9.0-beta.2",
44
44
  "@angular-devkit/build-angular": "^17.2.0",
45
45
  "@angular/cli": "^17.2.0",
46
46
  "@angular/compiler-cli": "^17.2.0",
@@ -15,8 +15,8 @@
15
15
  "test": "ng test"
16
16
  },
17
17
  "dependencies": {
18
- "@analogjs/content": "^1.9.0-beta.1",
19
- "@analogjs/router": "^1.9.0-beta.1",
18
+ "@analogjs/content": "^1.9.0-beta.2",
19
+ "@analogjs/router": "^1.9.0-beta.2",
20
20
  "@angular/animations": "^18.0.0",
21
21
  "@angular/build": "^18.0.0",
22
22
  "@angular/common": "^18.0.0",
@@ -36,9 +36,9 @@
36
36
  "zone.js": "~0.14.0"
37
37
  },
38
38
  "devDependencies": {
39
- "@analogjs/platform": "^1.9.0-beta.1",
40
- "@analogjs/vite-plugin-angular": "^1.9.0-beta.1",
41
- "@analogjs/vitest-angular": "^1.9.0-beta.1",
39
+ "@analogjs/platform": "^1.9.0-beta.2",
40
+ "@analogjs/vite-plugin-angular": "^1.9.0-beta.2",
41
+ "@analogjs/vitest-angular": "^1.9.0-beta.2",
42
42
  "@angular/cli": "^18.0.0",
43
43
  "@angular/compiler-cli": "^18.0.0",
44
44
  "jsdom": "^22.1.0",
@@ -0,0 +1,25 @@
1
+ <script lang="ts">
2
+ import { RouterLink, RouterOutlet } from '@angular/router' with { analog: 'imports' };
3
+ </script>
4
+
5
+ <template>
6
+ <nav>
7
+ <a routerLink="/">Home</a>
8
+ </nav>
9
+
10
+ <router-outlet />
11
+ </template>
12
+
13
+ <style>
14
+ :host {
15
+ max-width: 1280px;
16
+ margin: 0 auto;
17
+ padding: 2rem;
18
+ text-align: center;
19
+ }
20
+
21
+ nav {
22
+ text-align: left;
23
+ padding: 0 0 2rem 0;
24
+ }
25
+ </style>
@@ -0,0 +1,20 @@
1
+ import { TestBed } from '@angular/core/testing';
2
+ import { provideRouter } from '@angular/router';
3
+ import { provideLocationMocks } from '@angular/common/testing';
4
+
5
+ import App from './app-root.ag';
6
+
7
+ describe('App', () => {
8
+ beforeEach(async () => {
9
+ await TestBed.configureTestingModule({
10
+ imports: [App],
11
+ providers: [provideRouter([]), provideLocationMocks()],
12
+ }).compileComponents();
13
+ });
14
+
15
+ it('should create the app', () => {
16
+ const fixture = TestBed.createComponent(App);
17
+ const app = fixture.componentInstance;
18
+ expect(app).toBeTruthy();
19
+ });
20
+ });
@@ -1,11 +1,14 @@
1
1
  import { TestBed } from '@angular/core/testing';
2
- import { RouterTestingModule } from '@angular/router/testing';
2
+ import { provideRouter } from '@angular/router';
3
+ import { provideLocationMocks } from '@angular/common/testing';
4
+
3
5
  import { AppComponent } from './app.component';
4
6
 
5
7
  describe('AppComponent', () => {
6
8
  beforeEach(async () => {
7
9
  await TestBed.configureTestingModule({
8
- imports: [RouterTestingModule, AppComponent],
10
+ imports: [AppComponent],
11
+ providers: [provideRouter([]), provideLocationMocks()],
9
12
  }).compileComponents();
10
13
  });
11
14
 
@@ -1,30 +1,29 @@
1
1
  import { Component } from '@angular/core';
2
- import { RouterOutlet } from '@angular/router';
2
+ import { RouterLink, RouterOutlet } from '@angular/router';
3
3
 
4
4
  @Component({
5
5
  selector: 'app-root',
6
6
  standalone: true,
7
- imports: [RouterOutlet],
7
+ imports: [RouterLink, RouterOutlet],
8
8
  template: `
9
9
  <nav>
10
- <a href="/">Home</a>
10
+ <a routerLink="/">Home</a>
11
11
  </nav>
12
+
12
13
  <router-outlet />
13
14
  `,
14
- styles: [
15
- `
16
- :host {
17
- max-width: 1280px;
18
- margin: 0 auto;
19
- padding: 2rem;
20
- text-align: center;
21
- }
15
+ styles: `
16
+ :host {
17
+ max-width: 1280px;
18
+ margin: 0 auto;
19
+ padding: 2rem;
20
+ text-align: center;
21
+ }
22
22
 
23
- nav {
24
- text-align: left;
25
- padding: 0 0 2rem 0;
26
- }
27
- `,
28
- ],
23
+ nav {
24
+ text-align: left;
25
+ padding: 0 0 2rem 0;
26
+ }
27
+ `,
29
28
  })
30
29
  export class AppComponent {}
@@ -0,0 +1,24 @@
1
+ <script lang="ts">
2
+ import { AsyncPipe } from '@angular/common' with { analog: 'imports' };
3
+ import { MarkdownComponent } from '@analogjs/content' with { analog: 'imports' };
4
+ import { injectContent } from '@analogjs/content';
5
+
6
+ import PostAttributes from '../../post-attributes';
7
+
8
+ const post$ = injectContent<PostAttributes>('slug');
9
+ </script>
10
+
11
+ <template>
12
+ @if (post$ | async; as post) {
13
+ <article>
14
+ <img class="post__image" [src]="post.attributes.coverImage" />
15
+ <analog-markdown [content]="post.content" />
16
+ </article>
17
+ }
18
+ </template>
19
+
20
+ <style>
21
+ .post__image {
22
+ max-height: 40vh;
23
+ }
24
+ </style>
@@ -1,6 +1,6 @@
1
1
  import { Component } from '@angular/core';
2
- import { injectContent, MarkdownComponent } from '@analogjs/content';
3
2
  import { AsyncPipe } from '@angular/common';
3
+ import { injectContent, MarkdownComponent } from '@analogjs/content';
4
4
 
5
5
  import PostAttributes from '../../post-attributes';
6
6
 
@@ -16,13 +16,11 @@ import PostAttributes from '../../post-attributes';
16
16
  </article>
17
17
  }
18
18
  `,
19
- styles: [
20
- `
21
- .post__image {
22
- max-height: 40vh;
23
- }
24
- `,
25
- ],
19
+ styles: `
20
+ .post__image {
21
+ max-height: 40vh;
22
+ }
23
+ `,
26
24
  })
27
25
  export default class BlogPostComponent {
28
26
  readonly post$ = injectContent<PostAttributes>('slug');
@@ -0,0 +1,32 @@
1
+ <script lang="ts">
2
+ import { RouterLink } from '@angular/router' with { analog: 'imports' };
3
+ import { injectContentFiles } from '@analogjs/content';
4
+
5
+ import PostAttributes from '../../post-attributes';
6
+
7
+ const posts = injectContentFiles<PostAttributes>();
8
+ </script>
9
+
10
+ <template>
11
+ <h1>Blog Archive</h1>
12
+
13
+ @for (post of posts; track post.attributes.slug) {
14
+ <a [routerLink]="['/blog/', post.attributes.slug]">
15
+ <h2 class="post__title">{{ post.attributes.title }}</h2>
16
+ <p class="post__desc">{{ post.attributes.description }}</p>
17
+ </a>
18
+ }
19
+ </template>
20
+
21
+ <style>
22
+ a {
23
+ text-align: left;
24
+ display: block;
25
+ margin-bottom: 2rem;
26
+ }
27
+
28
+ .post__title,
29
+ .post__desc {
30
+ margin: 0;
31
+ }
32
+ </style>
@@ -1,7 +1,8 @@
1
1
  import { Component } from '@angular/core';
2
+ import { RouterLink } from '@angular/router';
2
3
  import { injectContentFiles } from '@analogjs/content';
4
+
3
5
  import PostAttributes from '../../post-attributes';
4
- import { RouterLink } from '@angular/router';
5
6
 
6
7
  @Component({
7
8
  selector: 'app-blog',
@@ -9,27 +10,26 @@ import { RouterLink } from '@angular/router';
9
10
  imports: [RouterLink],
10
11
  template: `
11
12
  <h1>Blog Archive</h1>
12
- @for (post of posts;track post.attributes.slug) {
13
+
14
+ @for (post of posts; track post.attributes.slug) {
13
15
  <a [routerLink]="['/blog/', post.attributes.slug]">
14
16
  <h2 class="post__title">{{ post.attributes.title }}</h2>
15
17
  <p class="post__desc">{{ post.attributes.description }}</p>
16
18
  </a>
17
19
  }
18
20
  `,
19
- styles: [
20
- `
21
- a {
22
- text-align: left;
23
- display: block;
24
- margin-bottom: 2rem;
25
- }
21
+ styles: `
22
+ a {
23
+ text-align: left;
24
+ display: block;
25
+ margin-bottom: 2rem;
26
+ }
26
27
 
27
- .post__title,
28
- .post__desc {
29
- margin: 0;
30
- }
31
- `,
32
- ],
28
+ .post__title,
29
+ .post__desc {
30
+ margin: 0;
31
+ }
32
+ `,
33
33
  })
34
34
  export default class BlogComponent {
35
35
  readonly posts = injectContentFiles<PostAttributes>();
@@ -6,15 +6,15 @@ import { renderApplication } from '@angular/platform-server';
6
6
  import { provideServerContext } from '@analogjs/router/server';
7
7
  import { ServerContext } from '@analogjs/router/tokens';
8
8
 
9
+ __APP_COMPONENT_IMPORT__
9
10
  import { config } from './app/app.config.server';
10
- import { AppComponent } from './app/app.component';
11
11
 
12
12
  if (import.meta.env.PROD) {
13
13
  enableProdMode();
14
14
  }
15
15
 
16
16
  export function bootstrap() {
17
- return bootstrapApplication(AppComponent, config);
17
+ return bootstrapApplication(__APP_COMPONENT__, config);
18
18
  }
19
19
 
20
20
  export default async function render(
@@ -1,7 +1,7 @@
1
1
  import 'zone.js';
2
2
  import { bootstrapApplication } from '@angular/platform-browser';
3
3
 
4
- import { AppComponent } from './app/app.component';
4
+ __APP_COMPONENT_IMPORT__
5
5
  import { appConfig } from './app/app.config';
6
6
 
7
- bootstrapApplication(AppComponent, appConfig);
7
+ bootstrapApplication(__APP_COMPONENT__, appConfig);
@@ -18,7 +18,7 @@ export default defineConfig(({ mode }) => ({
18
18
  },
19
19
  prerender: {
20
20
  routes: ['/blog', '/blog/2022-12-27-my-first-post'],
21
- },
21
+ },__ANALOG_SFC_CONFIG__
22
22
  }),
23
23
  ],
24
24
  test: {
@@ -15,8 +15,8 @@
15
15
  },
16
16
  "private": true,
17
17
  "dependencies": {
18
- "@analogjs/content": "^1.9.0-beta.1",
19
- "@analogjs/router": "^1.9.0-beta.1",
18
+ "@analogjs/content": "^1.9.0-beta.2",
19
+ "@analogjs/router": "^1.9.0-beta.2",
20
20
  "@angular/animations": "^18.0.0",
21
21
  "@angular/build": "^18.0.0",
22
22
  "@angular/common": "^18.0.0",
@@ -38,9 +38,9 @@
38
38
  "zone.js": "~0.14.3"
39
39
  },
40
40
  "devDependencies": {
41
- "@analogjs/platform": "^1.9.0-beta.1",
42
- "@analogjs/vite-plugin-angular": "^1.9.0-beta.1",
43
- "@analogjs/vitest-angular": "^1.9.0-beta.1",
41
+ "@analogjs/platform": "^1.9.0-beta.2",
42
+ "@analogjs/vite-plugin-angular": "^1.9.0-beta.2",
43
+ "@analogjs/vitest-angular": "^1.9.0-beta.2",
44
44
  "@angular/cli": "^18.0.0",
45
45
  "@angular/compiler-cli": "^18.0.0",
46
46
  "jsdom": "^22.0.0",
@@ -0,0 +1,16 @@
1
+ <script lang="ts">
2
+ import { RouterOutlet } from '@angular/router' with { analog: 'imports' };
3
+ </script>
4
+
5
+ <template>
6
+ <router-outlet />
7
+ </template>
8
+
9
+ <style>
10
+ :host {
11
+ max-width: 1280px;
12
+ margin: 0 auto;
13
+ padding: 2rem;
14
+ text-align: center;
15
+ }
16
+ </style>
@@ -0,0 +1,20 @@
1
+ import { TestBed } from '@angular/core/testing';
2
+ import { provideRouter } from '@angular/router';
3
+ import { provideLocationMocks } from '@angular/common/testing';
4
+
5
+ import App from './app-root.ag';
6
+
7
+ describe('App', () => {
8
+ beforeEach(async () => {
9
+ await TestBed.configureTestingModule({
10
+ imports: [App],
11
+ providers: [provideRouter([]), provideLocationMocks()],
12
+ }).compileComponents();
13
+ });
14
+
15
+ it('should create the app', () => {
16
+ const fixture = TestBed.createComponent(App);
17
+ const app = fixture.componentInstance;
18
+ expect(app).toBeTruthy();
19
+ });
20
+ });
@@ -6,15 +6,13 @@ import { RouterOutlet } from '@angular/router';
6
6
  standalone: true,
7
7
  imports: [RouterOutlet],
8
8
  template: `<router-outlet />`,
9
- styles: [
10
- `
11
- :host {
12
- max-width: 1280px;
13
- margin: 0 auto;
14
- padding: 2rem;
15
- text-align: center;
16
- }
17
- `,
18
- ],
9
+ styles: `
10
+ :host {
11
+ max-width: 1280px;
12
+ margin: 0 auto;
13
+ padding: 2rem;
14
+ text-align: center;
15
+ }
16
+ `,
19
17
  })
20
18
  export class AppComponent {}
@@ -0,0 +1,53 @@
1
+ <script lang="ts">
2
+ import { signal } from '@angular/core';
3
+
4
+ const count = signal(0);
5
+
6
+ function increment() {
7
+ this.count.update((count) => count + 1);
8
+ }
9
+ </script>
10
+
11
+ <template>
12
+ <div>
13
+ <a href="https://analogjs.org/" target="_blank">
14
+ <img alt="Analog Logo" class="logo analog" src="/analog.svg" />
15
+ </a>
16
+ </div>
17
+
18
+ <h2>Analog</h2>
19
+
20
+ <h3>The fullstack meta-framework for Angular!</h3>
21
+
22
+ <div class="card">
23
+ <button type="button" (click)="increment()">Count {{ count() }}</button>
24
+ </div>
25
+
26
+ <p class="read-the-docs">
27
+ <a href="https://analogjs.org" target="_blank">Docs</a> |
28
+ <a href="https://github.com/analogjs/analog" target="_blank">GitHub</a> |
29
+ <a href="https://github.com/sponsors/brandonroberts" target="_blank">
30
+ Sponsor
31
+ </a>
32
+ </p>
33
+ </template>
34
+
35
+ <style>
36
+ .logo {
37
+ will-change: filter;
38
+ }
39
+
40
+ .logo:hover {
41
+ filter: drop-shadow(0 0 2em #646cffaa);
42
+ }
43
+
44
+ .read-the-docs > * {
45
+ color: #fff;
46
+ }
47
+
48
+ @media (prefers-color-scheme: light) {
49
+ .read-the-docs > * {
50
+ color: #213547;
51
+ }
52
+ }
53
+ </style>
@@ -21,30 +21,30 @@ import { Component, signal } from '@angular/core';
21
21
  <p class="read-the-docs">
22
22
  <a href="https://analogjs.org" target="_blank">Docs</a> |
23
23
  <a href="https://github.com/analogjs/analog" target="_blank">GitHub</a> |
24
- <a href="https://github.com/sponsors/brandonroberts" target="_blank"
25
- >Sponsor</a
26
- >
24
+ <a href="https://github.com/sponsors/brandonroberts" target="_blank">
25
+ Sponsor
26
+ </a>
27
27
  </p>
28
28
  `,
29
- styles: [
30
- `
31
- .logo {
32
- will-change: filter;
33
- }
34
- .logo:hover {
35
- filter: drop-shadow(0 0 2em #646cffaa);
36
- }
37
- .read-the-docs > * {
38
- color: #fff;
39
- }
29
+ styles: `
30
+ .logo {
31
+ will-change: filter;
32
+ }
40
33
 
41
- @media (prefers-color-scheme: light) {
42
- .read-the-docs > * {
43
- color: #213547;
44
- }
34
+ .logo:hover {
35
+ filter: drop-shadow(0 0 2em #646cffaa);
36
+ }
37
+
38
+ .read-the-docs > * {
39
+ color: #fff;
40
+ }
41
+
42
+ @media (prefers-color-scheme: light) {
43
+ .read-the-docs > * {
44
+ color: #213547;
45
45
  }
46
- `,
47
- ],
46
+ }
47
+ `,
48
48
  })
49
49
  export default class HomeComponent {
50
50
  count = signal(0);
@@ -6,15 +6,15 @@ import { renderApplication } from '@angular/platform-server';
6
6
  import { provideServerContext } from '@analogjs/router/server';
7
7
  import { ServerContext } from '@analogjs/router/tokens';
8
8
 
9
+ __APP_COMPONENT_IMPORT__
9
10
  import { config } from './app/app.config.server';
10
- import { AppComponent } from './app/app.component';
11
11
 
12
12
  if (import.meta.env.PROD) {
13
13
  enableProdMode();
14
14
  }
15
15
 
16
16
  export function bootstrap() {
17
- return bootstrapApplication(AppComponent, config);
17
+ return bootstrapApplication(__APP_COMPONENT__, config);
18
18
  }
19
19
 
20
20
  export default async function render(
@@ -1,7 +1,7 @@
1
1
  import 'zone.js';
2
2
  import { bootstrapApplication } from '@angular/platform-browser';
3
3
 
4
- import { AppComponent } from './app/app.component';
4
+ __APP_COMPONENT_IMPORT__
5
5
  import { appConfig } from './app/app.config';
6
6
 
7
- bootstrapApplication(AppComponent, appConfig);
7
+ bootstrapApplication(__APP_COMPONENT__, appConfig);
@@ -21,6 +21,7 @@ a {
21
21
  color: #646cff;
22
22
  text-decoration: inherit;
23
23
  }
24
+
24
25
  a:hover {
25
26
  color: #535bf2;
26
27
  }
@@ -49,9 +50,11 @@ button {
49
50
  cursor: pointer;
50
51
  transition: border-color 0.25s;
51
52
  }
53
+
52
54
  button:hover {
53
55
  border-color: #646cff;
54
56
  }
57
+
55
58
  button:focus,
56
59
  button:focus-visible {
57
60
  outline: 4px auto -webkit-focus-ring-color;
@@ -66,9 +69,11 @@ button:focus-visible {
66
69
  color: #213547;
67
70
  background-color: #ffffff;
68
71
  }
72
+
69
73
  a:hover {
70
74
  color: #747bff;
71
75
  }
76
+
72
77
  button {
73
78
  background-color: #f9f9f9;
74
79
  }
@@ -11,7 +11,7 @@ export default defineConfig(({ mode }) => ({
11
11
  resolve: {
12
12
  mainFields: ['module'],
13
13
  },
14
- plugins: [analog()],
14
+ plugins: [analog(__ANALOG_SFC_CONFIG__)],
15
15
  test: {
16
16
  globals: true,
17
17
  environment: 'jsdom',
@@ -0,0 +1,7 @@
1
+ <script lang="ts">
2
+ import { RouterOutlet } from '@angular/router' with { analog: 'imports' };
3
+ </script>
4
+
5
+ <template>
6
+ <router-outlet />
7
+ </template>
@@ -0,0 +1,32 @@
1
+ <template>
2
+ <h2>Analog</h2>
3
+
4
+ <h3>The fullstack meta-framework for Angular!</h3>
5
+
6
+ <p class="read-the-docs">
7
+ <a href="https://analogjs.org" target="_blank">Docs</a> |
8
+ <a href="https://github.com/analogjs/analog" target="_blank">GitHub</a> |
9
+ <a href="https://github.com/sponsors/brandonroberts" target="_blank">
10
+ Sponsor
11
+ </a>
12
+ </p>
13
+ </template>
14
+
15
+ <style>
16
+ :host {
17
+ display: flex;
18
+ flex-direction: column;
19
+ justify-content: center;
20
+ align-items: center;
21
+ }
22
+
23
+ .read-the-docs > * {
24
+ color: #fff;
25
+ }
26
+
27
+ @media (prefers-color-scheme: light) {
28
+ .read-the-docs > * {
29
+ color: #213547;
30
+ }
31
+ }
32
+ </style>
@@ -11,9 +11,9 @@ import { Component } from '@angular/core';
11
11
  <p class="read-the-docs">
12
12
  <a href="https://analogjs.org" target="_blank">Docs</a> |
13
13
  <a href="https://github.com/analogjs/analog" target="_blank">GitHub</a> |
14
- <a href="https://github.com/sponsors/brandonroberts" target="_blank"
15
- >Sponsor</a
16
- >
14
+ <a href="https://github.com/sponsors/brandonroberts" target="_blank">
15
+ Sponsor
16
+ </a>
17
17
  </p>
18
18
  `,
19
19
  styles: `
@@ -23,6 +23,7 @@ import { Component } from '@angular/core';
23
23
  justify-content: center;
24
24
  align-items: center;
25
25
  }
26
+
26
27
  .read-the-docs > * {
27
28
  color: #fff;
28
29
  }
@@ -6,15 +6,15 @@ import { renderApplication } from '@angular/platform-server';
6
6
  import { provideServerContext } from '@analogjs/router/server';
7
7
  import { ServerContext } from '@analogjs/router/tokens';
8
8
 
9
+ __APP_COMPONENT_IMPORT__
9
10
  import { config } from './app/app.config.server';
10
- import { AppComponent } from './app/app.component';
11
11
 
12
12
  if (import.meta.env.PROD) {
13
13
  enableProdMode();
14
14
  }
15
15
 
16
16
  export function bootstrap() {
17
- return bootstrapApplication(AppComponent, config);
17
+ return bootstrapApplication(__APP_COMPONENT__, config);
18
18
  }
19
19
 
20
20
  export default async function render(
@@ -1,7 +1,7 @@
1
1
  import 'zone.js';
2
2
  import { bootstrapApplication } from '@angular/platform-browser';
3
3
 
4
- import { AppComponent } from './app/app.component';
4
+ __APP_COMPONENT_IMPORT__
5
5
  import { appConfig } from './app/app.config';
6
6
 
7
- bootstrapApplication(AppComponent, appConfig);
7
+ bootstrapApplication(__APP_COMPONENT__, appConfig);
@@ -17,7 +17,7 @@ export default defineConfig(({ mode }) => ({
17
17
  static: true,
18
18
  prerender: {
19
19
  routes: [],
20
- },
20
+ },__ANALOG_SFC_CONFIG__
21
21
  }),
22
22
  ],
23
23
  }));