Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 7a2402a

Browse files
jamesdanielsrobertIsaac
andauthoredMay 27, 2023
Allow ng16 peer (#3361)
* Allow peer of ng 16, firebase-tools 12 * Cleanup ng-add to use web frameworks * Cleanup tests --- Co-authored-by: robertIsaac <robertIsaac@users.noreply.github.com>
1 parent 1ec218a commit 7a2402a

27 files changed

+5391
-6771
lines changed
 

‎.github/workflows/codeql-analysis.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ jobs:
3939

4040
# Initializes the CodeQL tools for scanning.
4141
- name: Initialize CodeQL
42-
uses: github/codeql-action/init@v1
42+
uses: github/codeql-action/init@v2
4343
with:
4444
languages: ${{ matrix.language }}
4545
# If you wish to specify custom queries, you can do so here or in a config file.
@@ -50,7 +50,7 @@ jobs:
5050
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
5151
# If this step fails, then you should remove it and run the build manually (see below)
5252
- name: Autobuild
53-
uses: github/codeql-action/autobuild@v1
53+
uses: github/codeql-action/autobuild@v2
5454

5555
# ℹ️ Command-line programs to run using the OS shell.
5656
# 📚 https://git.io/JvXDl
@@ -64,4 +64,4 @@ jobs:
6464
# make release
6565

6666
- name: Perform CodeQL Analysis
67-
uses: github/codeql-action/analyze@v1
67+
uses: github/codeql-action/analyze@v2

‎.github/workflows/test.yml

Lines changed: 76 additions & 208 deletions
Large diffs are not rendered by default.

‎README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ AngularFire doesn't follow Angular's versioning as Firebase also has breaking ch
6969

7070
| Angular | Firebase | AngularFire |
7171
| --------|----------|--------------|
72+
| 16 | 9 | ^7.6 |
7273
| 15 | 9 | ^7.5 |
7374
| 14 | 9 | ^7.4 |
7475
| 13 | 9 | ^7.2 |

‎package.json

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
{
22
"name": "@angular/fire",
3-
"version": "7.5.0",
3+
"version": "7.6.0",
44
"description": "The official Angular library for Firebase.",
55
"private": true,
66
"scripts": {
77
"test": "npm run build:jasmine && npm run test:node && npm run test:chrome-headless",
8-
"test:watch": "npx firebase-tools@latest emulators:exec --project=angularfire2-test \"ng test --watch=true --browsers=Chrome\"",
9-
"test:chrome": "npx firebase-tools@latest emulators:exec --project=angularfire2-test \"ng test --watch=false --browsers=Chrome\"",
10-
"test:firefox": "npx firebase-tools@latest emulators:exec --project=angularfire2-test \"ng test --watch=false --browsers=Firefox\"",
11-
"test:safari": "npx firebase-tools@latest emulators:exec --project=angularfire2-test \"ng test --watch=false --browsers=SafariNative\"",
12-
"test:chrome-headless": "npx firebase-tools@latest emulators:exec --project=angularfire2-test \"ng test --watch=false --browsers=ChromeHeadless\"",
13-
"test:firefox-headless": "npx firebase-tools@latest emulators:exec --project=angularfire2-test \"ng test --watch=false --browsers=FirefoxHeadless\"",
8+
"test:watch": "npx --yes firebase-tools emulators:exec --project=demo123 \"ng test --watch=true --browsers=Chrome\"",
9+
"test:chrome": "npx --yes firebase-tools emulators:exec --project=demo123 \"ng test --watch=false --browsers=Chrome\"",
10+
"test:firefox": "npx --yes firebase-tools emulators:exec --project=demo123 \"ng test --watch=false --browsers=Firefox\"",
11+
"test:safari": "npx --yes firebase-tools emulators:exec --project=demo123 \"ng test --watch=false --browsers=SafariNative\"",
12+
"test:chrome-headless": "npx --yes firebase-tools emulators:exec --project=demo123 \"ng test --watch=false --browsers=ChromeHeadless\"",
13+
"test:firefox-headless": "npx --yes firebase-tools emulators:exec --project=demo123 \"ng test --watch=false --browsers=FirefoxHeadless\"",
1414
"lint": "ng lint",
1515
"test:node": "node -r tsconfig-paths/register ./dist/out-tsc/jasmine/tools/jasmine.js --input-type=commonjs",
1616
"test:node-esm": "node -r tsconfig-paths/register ./dist/out-tsc/jasmine/tools/jasmine.mjs --input-type=commonjs",
@@ -57,7 +57,7 @@
5757
"firebase": "^9.8.2",
5858
"firebase-admin": "^9.11.1",
5959
"firebase-functions": "^3.6.0",
60-
"firebase-tools": "^9.0.0",
60+
"firebase-tools": "^12.2.1",
6161
"fs-extra": "^8.0.1",
6262
"fuzzy": "^0.1.3",
6363
"husky": "^4.2.5",

‎src/compat/firestore/collection-group/collection-group.spec.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,7 @@ describe('AngularFirestoreCollectionGroup', () => {
353353

354354
it('should be able to filter snapshotChanges() types - removed', done => {
355355
(async () => {
356+
356357
const ITEMS = 10;
357358
const { ref, stocks, names } = await collectionHarness(afs, ITEMS);
358359

‎src/messaging/messaging.spec.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,16 @@ describe('Messaging', () => {
3535
messaging = TestBed.inject(Messaging);
3636
});
3737

38-
it('should be injectable', () => {
39-
expect(providedMessaging).toBeTruthy();
40-
expect(messaging).toEqual(providedMessaging);
38+
it('should be injectable', async (done) => {
39+
const supported = await isSupported();
40+
if (supported) {
41+
expect(providedMessaging).toBeTruthy();
42+
expect(messaging).toEqual(providedMessaging);
43+
} else {
44+
expect(providedMessaging).toBeUndefined();
45+
expect(messaging).toBeNull();
46+
}
47+
done();
4148
});
4249

4350
});

‎src/package.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,21 +23,21 @@
2323
"author": "angular,firebase",
2424
"license": "MIT",
2525
"peerDependencies": {
26-
"@angular/common": "^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0",
27-
"@angular/core": "^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0",
28-
"@angular/platform-browser": "^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0",
29-
"@angular/platform-browser-dynamic": "^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0",
26+
"@angular/common": "^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0",
27+
"@angular/core": "^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0",
28+
"@angular/platform-browser": "^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0",
29+
"@angular/platform-browser-dynamic": "^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0",
3030
"rxjs": "~6.6.0 || ^7.0.0",
31-
"firebase-tools": "^9.9.0 || ^10.0.0 || ^11.0.0"
31+
"firebase-tools": "^9.9.0 || ^10.0.0 || ^11.0.0 || ^12.0.0"
3232
},
3333
"peerDependenciesMeta": {
3434
"firebase-tools": { "optional": true }
3535
},
3636
"dependencies": {
3737
"firebase": "^9.8.0",
3838
"rxfire": "^6.0.0",
39-
"@angular-devkit/schematics": "^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0",
40-
"@schematics/angular": "^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0",
39+
"@angular-devkit/schematics": "^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0",
40+
"@schematics/angular": "^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0",
4141
"tslib": "^2.0.0",
4242
"fuzzy": "^0.1.3",
4343
"inquirer-autocomplete-prompt": "^1.0.1",

‎src/schematics/deploy/actions.ts

Lines changed: 36 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { copySync, removeSync } from 'fs-extra';
55
import { dirname, join } from 'path';
66
import { execSync, spawn, SpawnOptionsWithoutStdio } from 'child_process';
77
import { defaultFunction, functionGen2, defaultPackage, DEFAULT_FUNCTION_NAME, dockerfile } from './functions-templates';
8-
import { satisfies } from 'semver';
8+
import { satisfies, lt } from 'semver';
99
import open from 'open';
1010
import { SchematicsException } from '@angular-devkit/schematics';
1111
import { firebaseFunctionsDependencies } from '../versions.json';
@@ -79,7 +79,7 @@ const deployToHosting = async (
7979
await firebaseTools.serve({
8080
port: DEFAULT_EMULATOR_PORT,
8181
host: DEFAULT_EMULATOR_HOST,
82-
targets: [`hosting:${siteTarget}`],
82+
only: `hosting:${siteTarget}`,
8383
nonInteractive: true,
8484
projectRoot: workspaceRoot,
8585
});
@@ -92,6 +92,8 @@ const deployToHosting = async (
9292

9393
if (!deployProject) { return; }
9494

95+
process.env.FIREBASE_FRAMEWORKS_SKIP_BUILD = 'true';
96+
9597
}
9698

9799
return await firebaseTools.deploy({
@@ -394,37 +396,44 @@ export default async function deploy(
394396
console.log(`Logged into Firebase as ${user.email}.`);
395397
}
396398

397-
if (prerenderBuildTarget) {
399+
if (options.version && options.version >= 2) {
400+
if (lt(firebaseTools.cli.version(), '12.2')) {
401+
throw new SchematicsException('firebase-tools version 12.2+ is required.');
402+
}
403+
process.env.FIREBASE_FRAMEWORK_BUILD_TARGET = (prerenderBuildTarget || serverBuildTarget || staticBuildTarget).name;
404+
} else {
405+
if (prerenderBuildTarget) {
398406

399-
const run = await context.scheduleTarget(
400-
targetFromTargetString(prerenderBuildTarget.name),
401-
prerenderBuildTarget.options
402-
);
403-
await run.result;
407+
const run = await context.scheduleTarget(
408+
targetFromTargetString(prerenderBuildTarget.name),
409+
prerenderBuildTarget.options
410+
);
411+
await run.result;
404412

405-
} else {
413+
} else {
406414

407-
if (!context.target) {
408-
throw new Error('Cannot execute the build target');
409-
}
415+
if (!context.target) {
416+
throw new Error('Cannot execute the build target');
417+
}
410418

411-
context.logger.info(`📦 Building "${context.target.project}"`);
419+
context.logger.info(`📦 Building "${context.target.project}"`);
412420

413-
const builders = [
414-
context.scheduleTarget(
415-
targetFromTargetString(staticBuildTarget.name),
416-
staticBuildTarget.options
417-
).then(run => run.result)
418-
];
421+
const builders = [
422+
context.scheduleTarget(
423+
targetFromTargetString(staticBuildTarget.name),
424+
staticBuildTarget.options
425+
).then(run => run.result)
426+
];
419427

420-
if (serverBuildTarget) {
421-
builders.push(context.scheduleTarget(
422-
targetFromTargetString(serverBuildTarget.name),
423-
serverBuildTarget.options
424-
).then(run => run.result));
425-
}
428+
if (serverBuildTarget) {
429+
builders.push(context.scheduleTarget(
430+
targetFromTargetString(serverBuildTarget.name),
431+
serverBuildTarget.options
432+
).then(run => run.result));
433+
}
426434

427-
await Promise.all(builders);
435+
await Promise.all(builders);
436+
}
428437
}
429438

430439
try {
@@ -457,7 +466,7 @@ export default async function deploy(
457466

458467
firebaseTools.logger.logger.add(logger);
459468

460-
if (serverBuildTarget) {
469+
if ((!options.version || options.version < 2) && serverBuildTarget) {
461470
if (options.ssr === 'cloud-run') {
462471
await deployToCloudRun(
463472
firebaseTools,

‎src/schematics/firebaseTools.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,20 @@ declare global {
1010
export const getFirebaseTools = () => globalThis.firebaseTools ?
1111
Promise.resolve(globalThis.firebaseTools) :
1212
new Promise<FirebaseTools>((resolve, reject) => {
13+
process.env.FIREBASE_CLI_EXPERIMENTS ||= 'webframeworks';
1314
try {
1415
resolve(require('firebase-tools'));
1516
} catch (e) {
1617
try {
17-
const root = execSync('npm root -g').toString().trim();
18+
const root = execSync('npm root --location=global').toString().trim();
1819
resolve(require(`${root}/firebase-tools`));
1920
} catch (e) {
2021
const spinner = ora({
2122
text: `Installing firebase-tools...`,
2223
// Workaround for https://github.com/sindresorhus/ora/issues/136.
2324
discardStdin: process.platform !== 'win32',
2425
}).start();
25-
spawn('npm', ['i', '-g', 'firebase-tools'], {
26+
spawn('npm', ['i', '--location=global', 'firebase-tools'], {
2627
stdio: 'pipe',
2728
shell: true,
2829
}).on('close', (code) => {

‎src/schematics/interfaces.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export const featureOptions = [
2626
{ name: 'Remote Config', value: FEATURES.RemoteConfig },
2727
];
2828

29-
export const enum PROJECT_TYPE { Static, CloudFunctions, CloudRun }
29+
export const enum PROJECT_TYPE { Static, CloudFunctions, CloudRun, WebFrameworks }
3030

3131
export interface NgAddOptions {
3232
firebaseProject: string;
@@ -39,10 +39,11 @@ export interface NgAddNormalizedOptions {
3939
firebaseApp: FirebaseApp|undefined;
4040
firebaseHostingSite: FirebaseHostingSite|undefined;
4141
sdkConfig: Record<string, string>|undefined;
42-
prerender: boolean;
42+
prerender: boolean|undefined;
4343
browserTarget: string|undefined;
4444
serverTarget: string|undefined;
4545
prerenderTarget: string|undefined;
46+
ssrRegion: string|undefined;
4647
}
4748

4849
export interface DeployOptions {
@@ -139,9 +140,9 @@ export interface FirebaseHostingRewrite {
139140

140141
export interface FirebaseHostingConfig {
141142
public?: string;
142-
ignore: string[];
143-
target: string;
144-
rewrites: FirebaseHostingRewrite[];
143+
ignore?: string[];
144+
target?: string;
145+
rewrites?: FirebaseHostingRewrite[];
145146
}
146147

147148
export interface FirebaseFunctionsConfig { [key: string]: any; }
@@ -179,6 +180,7 @@ export interface DeployBuilderSchema {
179180
cloudRunOptions?: Partial<CloudRunOptions>;
180181
outputPath?: string;
181182
CF3v2?: boolean;
183+
version?: number;
182184
}
183185

184186
export interface CloudRunOptions {

‎src/schematics/ng-add.jasmine.ts

Lines changed: 19 additions & 175 deletions
Original file line numberDiff line numberDiff line change
@@ -91,36 +91,8 @@ const initialFirebaseJson = `{
9191
\"hosting\": [
9292
{
9393
\"target\": \"pie-ka-chu\",
94-
\"public\": \"dist/ikachu\",
95-
\"ignore\": [
96-
\"**/.*\"
97-
],
98-
\"headers\": [
99-
{
100-
\"source\": \"*.[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f].+(css|js)\",
101-
\"headers\": [
102-
{
103-
\"key\": \"Cache-Control\",
104-
\"value\": \"public,max-age=31536000,immutable\"
105-
}
106-
]
107-
},
108-
{
109-
\"source\": \"/@(ngsw-worker.js|ngsw.json)\",
110-
\"headers\": [
111-
{
112-
\"key\": \"Cache-Control\",
113-
\"value\": \"no-cache\"
114-
}
115-
]
116-
}
117-
],
118-
\"rewrites\": [
119-
{
120-
\"source\": \"**\",
121-
\"destination\": \"/index.html\"
122-
}
123-
]
94+
\"source\": \".\",
95+
\"frameworksBackend\": {}
12496
}
12597
]
12698
}`;
@@ -155,9 +127,7 @@ const initialAngularJson = `{
155127
\"deploy\": {
156128
\"builder\": \"@angular/fire:deploy\",
157129
\"options\": {
158-
\"prerender\": false,
159-
\"ssr\": false,
160-
\"firebaseProject\": \"pirojok-111e3\"
130+
\"version\": 2
161131
}
162132
}
163133
}
@@ -180,36 +150,8 @@ const overwriteFirebaseJson = `{
180150
\"hosting\": [
181151
{
182152
\"target\": \"pie-ka-chu\",
183-
\"public\": \"dist/ikachu\",
184-
\"ignore\": [
185-
\"**/.*\"
186-
],
187-
\"headers\": [
188-
{
189-
\"source\": \"*.[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f].+(css|js)\",
190-
\"headers\": [
191-
{
192-
\"key\": \"Cache-Control\",
193-
\"value\": \"public,max-age=31536000,immutable\"
194-
}
195-
]
196-
},
197-
{
198-
\"source\": \"/@(ngsw-worker.js|ngsw.json)\",
199-
\"headers\": [
200-
{
201-
\"key\": \"Cache-Control\",
202-
\"value\": \"no-cache\"
203-
}
204-
]
205-
}
206-
],
207-
\"rewrites\": [
208-
{
209-
\"source\": \"**\",
210-
\"destination\": \"/index.html\"
211-
}
212-
]
153+
\"source\": \".\",
154+
\"frameworksBackend\": {}
213155
}
214156
]
215157
}`;
@@ -244,9 +186,7 @@ const overwriteAngularJson = `{
244186
\"deploy\": {
245187
\"builder\": \"@angular/fire:deploy\",
246188
\"options\": {
247-
\"prerender\": false,
248-
\"ssr\": false,
249-
\"firebaseProject\": \"pirojok-111e3\"
189+
\"version\": 2
250190
}
251191
}
252192
}
@@ -269,69 +209,13 @@ const projectFirebaseJson = `{
269209
\"hosting\": [
270210
{
271211
\"target\": \"pie-ka-chu\",
272-
\"public\": \"dist/ikachu\",
273-
\"ignore\": [
274-
\"**/.*\"
275-
],
276-
\"headers\": [
277-
{
278-
\"source\": \"*.[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f].+(css|js)\",
279-
\"headers\": [
280-
{
281-
\"key\": \"Cache-Control\",
282-
\"value\": \"public,max-age=31536000,immutable\"
283-
}
284-
]
285-
},
286-
{
287-
\"source\": \"/@(ngsw-worker.js|ngsw.json)\",
288-
\"headers\": [
289-
{
290-
\"key\": \"Cache-Control\",
291-
\"value\": \"no-cache\"
292-
}
293-
]
294-
}
295-
],
296-
\"rewrites\": [
297-
{
298-
\"source\": \"**\",
299-
\"destination\": \"/index.html\"
300-
}
301-
]
212+
\"source\": \".\",
213+
\"frameworksBackend\": {}
302214
},
303215
{
304216
\"target\": \"pi-catch-you\",
305-
\"public\": \"dist/ikachu\",
306-
\"ignore\": [
307-
\"**/.*\"
308-
],
309-
\"headers\": [
310-
{
311-
\"source\": \"*.[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f].+(css|js)\",
312-
\"headers\": [
313-
{
314-
\"key\": \"Cache-Control\",
315-
\"value\": \"public,max-age=31536000,immutable\"
316-
}
317-
]
318-
},
319-
{
320-
\"source\": \"/@(ngsw-worker.js|ngsw.json)\",
321-
\"headers\": [
322-
{
323-
\"key\": \"Cache-Control\",
324-
\"value\": \"no-cache\"
325-
}
326-
]
327-
}
328-
],
329-
\"rewrites\": [
330-
{
331-
\"source\": \"**\",
332-
\"destination\": \"/index.html\"
333-
}
334-
]
217+
\"source\": \".\",
218+
\"frameworksBackend\": {}
335219
}
336220
]
337221
}`;
@@ -373,9 +257,7 @@ const projectAngularJson = `{
373257
\"deploy\": {
374258
\"builder\": \"@angular/fire:deploy\",
375259
\"options\": {
376-
\"prerender": false,
377-
\"ssr\": false,
378-
\"firebaseProject\": \"pirojok-111e3\"
260+
\"version": 2
379261
}
380262
}
381263
}
@@ -392,9 +274,7 @@ const projectAngularJson = `{
392274
\"deploy\": {
393275
\"builder\": \"@angular/fire:deploy\",
394276
\"options\": {
395-
\"prerender\": false,
396-
\"ssr\": false,
397-
\"firebaseProject\": \"bi-catch-you-77e7e\"
277+
\"version\": 2
398278
}
399279
}
400280
}
@@ -405,33 +285,9 @@ const projectAngularJson = `{
405285
const universalFirebaseJson = {
406286
hosting: [{
407287
target: 'pie-ka-chu',
408-
public: 'dist/ikachu',
409-
ignore: [
410-
'**/.*'
411-
],
412-
headers: [{
413-
source: '*.[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f].+(css|js)',
414-
headers: [{
415-
key: 'Cache-Control',
416-
value: 'public,max-age=31536000,immutable'
417-
}]
418-
}, {
419-
source: '/@(ngsw-worker.js|ngsw.json)',
420-
headers: [{
421-
key: 'Cache-Control',
422-
value: 'no-cache',
423-
}],
424-
}],
425-
rewrites: [
426-
{
427-
source: '**',
428-
function: 'ssr_pie-ka-chu'
429-
}
430-
]
288+
source: '.',
289+
frameworksBackend: {},
431290
}],
432-
functions: {
433-
source: 'dist/pie-ka-chu/functions'
434-
}
435291
};
436292

437293
describe('ng-add', () => {
@@ -583,7 +439,7 @@ describe('ng-add', () => {
583439
project: PROJECT_NAME,
584440
prerender: false,
585441
})).toBeRejectedWith(
586-
new SchematicsException('Cannot read the output path (architect.build.options.outputPath) of the Angular project "pie-ka-chu" in angular.json')
442+
new SchematicsException('Angular project "pie-ka-chu" has a malformed angular.json')
587443
);
588444
});
589445

@@ -630,7 +486,9 @@ describe('ng-add', () => {
630486
project: PROJECT_NAME,
631487
prerender: false,
632488
})).toBeRejectedWith(
633-
new SchematicsException('Error when parsing .firebaserc: Unexpected token I in JSON at position 0')
489+
parseInt(process.versions.node, 10) >= 20 ?
490+
new SchematicsException(`Error when parsing .firebaserc: Unexpected token 'I', "I'm broken 😔" is not valid JSON`) :
491+
new SchematicsException('Error when parsing .firebaserc: Unexpected token I in JSON at position 0')
634492
);
635493
});
636494

@@ -674,20 +532,6 @@ describe('ng-add', () => {
674532
}); */
675533

676534
describe('universal app', () => {
677-
it('should fail without a server project', async () => {
678-
const tree = Tree.empty();
679-
tree.create('angular.json', JSON.stringify(generateAngularJson()));
680-
tree.create('package.json', JSON.stringify(generatePackageJson()));
681-
682-
await expectAsync(setupProject(tree, {} as any, [FEATURES.Hosting], {
683-
firebaseProject: { projectId: FIREBASE_PROJECT } as any,
684-
projectType: PROJECT_TYPE.CloudFunctions,
685-
project: PROJECT_NAME,
686-
prerender: false,
687-
})).toBeRejectedWith(
688-
new SchematicsException('Cannot read the output path (architect.server.options.outputPath) of the Angular project "pie-ka-chu" in angular.json')
689-
);
690-
});
691535

692536
it('should add a @angular/fire builder', async () => {
693537
const tree = Tree.empty();
@@ -703,7 +547,7 @@ describe('ng-add', () => {
703547
});
704548

705549
const workspace = JSON.parse((await result.read('angular.json')).toString());
706-
expect(workspace.projects['pie-ka-chu'].architect.deploy.options.ssr).toEqual('cloud-functions');
550+
expect(workspace.projects['pie-ka-chu'].architect.deploy).toBeTruthy();
707551
});
708552

709553
it('should configure firebase.json', async () => {

‎src/schematics/setup/index.ts

Lines changed: 91 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -5,29 +5,33 @@ import {
55
addToNgModule, addIgnoreFiles, addFixesToServer
66
} from '../utils';
77
import { projectTypePrompt, appPrompt, sitePrompt, projectPrompt, featuresPrompt, userPrompt } from './prompts';
8-
import { setupUniversalDeployment } from './ssr';
9-
import { setupStaticDeployment } from './static';
108
import {
119
FirebaseApp, FirebaseHostingSite, FirebaseProject, DeployOptions, NgAddNormalizedOptions,
1210
FEATURES, PROJECT_TYPE
1311
} from '../interfaces';
1412
import { getFirebaseTools } from '../firebaseTools';
1513
import { writeFileSync } from 'fs';
1614
import { join } from 'path';
15+
import {
16+
generateFirebaseRc,
17+
overwriteIfExists,
18+
safeReadJSON,
19+
stringifyFormatted
20+
} from '../common';
21+
import { FirebaseJSON, Workspace, WorkspaceProject } from '../interfaces';
1722

1823
export const setupProject =
1924
async (tree: Tree, context: SchematicContext, features: FEATURES[], config: DeployOptions & {
2025
firebaseProject: FirebaseProject,
2126
firebaseApp?: FirebaseApp,
2227
firebaseHostingSite?: FirebaseHostingSite,
2328
sdkConfig?: Record<string, string>,
24-
projectType: PROJECT_TYPE,
25-
prerender: boolean,
2629
nodeVersion?: string,
2730
browserTarget?: string,
2831
serverTarget?: string,
2932
prerenderTarget?: string,
3033
project: string,
34+
ssrRegion?: string,
3135
}) => {
3236
const { path: workspacePath, workspace } = getWorkspace(tree);
3337

@@ -73,39 +77,22 @@ ${Object.entries(config.sdkConfig).reduce(
7377
firebaseApp: config.firebaseApp,
7478
firebaseHostingSite: config.firebaseHostingSite,
7579
sdkConfig: config.sdkConfig,
76-
prerender: config.prerender,
80+
prerender: undefined,
7781
browserTarget: config.browserTarget,
7882
serverTarget: config.serverTarget,
7983
prerenderTarget: config.prerenderTarget,
84+
ssrRegion: config.ssrRegion,
8085
};
8186

8287
if (features.includes(FEATURES.Hosting)) {
83-
// TODO dry up by always doing the static work
84-
switch (config.projectType) {
85-
case PROJECT_TYPE.CloudFunctions:
86-
case PROJECT_TYPE.CloudRun:
87-
return setupUniversalDeployment({
88-
workspace,
89-
workspacePath,
90-
options,
91-
tree,
92-
context,
93-
project,
94-
projectType: config.projectType,
95-
// tslint:disable-next-line:no-non-null-assertion
96-
nodeVersion: config.nodeVersion!,
97-
});
98-
case PROJECT_TYPE.Static:
99-
return setupStaticDeployment({
100-
workspace,
101-
workspacePath,
102-
options,
103-
tree,
104-
context,
105-
project
106-
});
107-
default: throw(new SchematicsException(`Unimplemented PROJECT_TYPE ${config.projectType}`));
108-
}
88+
return setupFirebase({
89+
workspace,
90+
workspacePath,
91+
options,
92+
tree,
93+
context,
94+
project
95+
});
10996
} else {
11097
return Promise.resolve();
11198
}
@@ -137,7 +124,7 @@ export const ngAddSetupProject = (
137124

138125
const firebaseProject = await projectPrompt(defaultProjectName, { projectRoot, account: user.email });
139126

140-
let hosting = { projectType: PROJECT_TYPE.Static, prerender: false };
127+
let hosting = { };
141128
let firebaseHostingSite: FirebaseHostingSite|undefined;
142129

143130
if (features.includes(FEATURES.Hosting)) {
@@ -166,3 +153,75 @@ export const ngAddSetupProject = (
166153

167154
}
168155
};
156+
157+
export function generateFirebaseJson(
158+
tree: Tree,
159+
path: string,
160+
project: string,
161+
region: string|undefined,
162+
) {
163+
const firebaseJson: FirebaseJSON = tree.exists(path)
164+
? safeReadJSON(path, tree)
165+
: {};
166+
167+
const newConfig = {
168+
target: project,
169+
source: '.',
170+
frameworksBackend: {
171+
region
172+
}
173+
};
174+
if (firebaseJson.hosting === undefined) {
175+
firebaseJson.hosting = [newConfig];
176+
} else if (Array.isArray(firebaseJson.hosting)) {
177+
const existingConfigIndex = firebaseJson.hosting.findIndex(config => config.target === newConfig.target);
178+
if (existingConfigIndex > -1) {
179+
firebaseJson.hosting.splice(existingConfigIndex, 1, newConfig);
180+
} else {
181+
firebaseJson.hosting.push(newConfig);
182+
}
183+
} else {
184+
firebaseJson.hosting = [firebaseJson.hosting, newConfig];
185+
}
186+
187+
overwriteIfExists(tree, path, stringifyFormatted(firebaseJson));
188+
}
189+
190+
export const setupFirebase = (config: {
191+
project: WorkspaceProject;
192+
options: NgAddNormalizedOptions;
193+
workspacePath: string;
194+
workspace: Workspace;
195+
tree: Tree;
196+
context: SchematicContext;
197+
}) => {
198+
const { tree, workspacePath, workspace, options } = config;
199+
const project = workspace.projects[options.project];
200+
201+
if (!project.architect) {
202+
throw new SchematicsException(`Angular project "${options.project}" has a malformed angular.json`);
203+
}
204+
205+
project.architect.deploy = {
206+
builder: '@angular/fire:deploy',
207+
options: {
208+
version: 2,
209+
browserTarget: options.browserTarget,
210+
...(options.serverTarget ? {serverTarget: options.serverTarget} : {}),
211+
...(options.prerenderTarget ? {prerenderTarget: options.prerenderTarget} : {})
212+
}
213+
};
214+
215+
tree.overwrite(workspacePath, JSON.stringify(workspace, null, 2));
216+
217+
generateFirebaseJson(tree, 'firebase.json', options.project, options.ssrRegion);
218+
generateFirebaseRc(
219+
tree,
220+
'.firebaserc',
221+
options.firebaseProject.projectId,
222+
options.firebaseHostingSite,
223+
options.project
224+
);
225+
226+
return tree;
227+
};

‎src/schematics/setup/prompts.ts

Lines changed: 18 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -228,58 +228,32 @@ export const sitePrompt = async ({ projectId: project }: FirebaseProject, option
228228
return (await sites).find(it => shortSiteName(it) === siteName)!;
229229
};
230230

231+
const DEFAULT_REGION = 'us-central1';
232+
const ALLOWED_SSR_REGIONS = [
233+
{ name: 'us-central1 (Iowa)', value: 'us-central1' },
234+
{ name: 'us-west1 (Oregon)', value: 'us-west1' },
235+
{ name: 'us-east1 (South Carolina)', value: 'us-east1' },
236+
{ name: 'europe-west1 (Belgium)', value: 'europe-west1' },
237+
{ name: 'asia-east1 (Taiwan)', value: 'asia-east1' },
238+
];
239+
231240
export const projectTypePrompt = async (project: WorkspaceProject, name: string) => {
232-
let prerender = false;
233-
let nodeVersion: string|undefined;
234241
let serverTarget: string|undefined;
235242
let browserTarget = `${name}:build:${project.architect?.build?.defaultConfiguration || 'production'}`;
236243
let prerenderTarget: string|undefined;
237244
if (isUniversalApp(project)) {
238245
serverTarget = `${name}:server:${project.architect?.server?.defaultConfiguration || 'production'}`;
239246
browserTarget = `${name}:build:${project.architect?.build?.defaultConfiguration || 'production'}`;
240-
if (hasPrerenderOption(project)) {
241-
prerenderTarget = `${name}:prerender:${project.architect?.prerender?.defaultConfiguration || 'production'}`;
242-
const { shouldPrerender } = await inquirer.prompt({
243-
type: 'confirm',
244-
name: 'shouldPrerender',
245-
message: 'Should we prerender before deployment?',
246-
default: true
247-
});
248-
prerender = shouldPrerender;
249-
}
250-
const choices = [
251-
{ name: prerender ? 'Pre-render only' : 'Don\'t render universal content', value: PROJECT_TYPE.Static },
252-
{ name: 'Cloud Functions', value: PROJECT_TYPE.CloudFunctions },
253-
{ name: 'Cloud Run', value: PROJECT_TYPE.CloudRun },
254-
];
255-
const { projectType } = await inquirer.prompt({
247+
const prerender = hasPrerenderOption(project);
248+
prerenderTarget = prerender && `${name}:prerender:${prerender.defaultConfiguration || 'production'}`;
249+
const { ssrRegion } = await inquirer.prompt({
256250
type: 'list',
257-
name: 'projectType',
258-
choices,
259-
message: 'How would you like to render server-side content?',
260-
default: PROJECT_TYPE.CloudFunctions,
251+
name: 'ssrRegion',
252+
choices: ALLOWED_SSR_REGIONS,
253+
message: 'In which region would you like to host server-side content?',
254+
default: DEFAULT_REGION,
261255
});
262-
if (projectType === PROJECT_TYPE.CloudFunctions) {
263-
const { newNodeVersion } = await inquirer.prompt({
264-
type: 'list',
265-
name: 'newNodeVersion',
266-
choices: ['12', '14', '16'],
267-
message: 'What version of Node.js would you like to use?',
268-
default: parseInt(process.versions.node, 10).toString(),
269-
});
270-
nodeVersion = newNodeVersion;
271-
} else if (projectType === PROJECT_TYPE.CloudRun) {
272-
const fetch = require('node-fetch');
273-
const { newNodeVersion } = await inquirer.prompt({
274-
type: 'input',
275-
name: 'newNodeVersion',
276-
message: 'What version of Node.js would you like to use?',
277-
validate: it => fetch(`https://hub.docker.com/v2/repositories/library/node/tags/${it}-slim`).then(it => it.status === 200 || `Can't find node:${it}-slim docker image.`),
278-
default: parseFloat(process.versions.node).toString(),
279-
});
280-
nodeVersion = newNodeVersion;
281-
}
282-
return { prerender, projectType, nodeVersion, browserTarget, serverTarget, prerenderTarget };
256+
return { prerender, projectType: PROJECT_TYPE.WebFrameworks, ssrRegion, browserTarget, serverTarget, prerenderTarget };
283257
}
284-
return { projectType: PROJECT_TYPE.Static, prerender, nodeVersion, browserTarget, serverTarget, prerenderTarget };
258+
return { projectType: PROJECT_TYPE.WebFrameworks, browserTarget, serverTarget, prerenderTarget };
285259
};

‎src/schematics/setup/ssr.ts

Lines changed: 0 additions & 160 deletions
This file was deleted.

‎src/schematics/setup/static.ts

Lines changed: 0 additions & 114 deletions
This file was deleted.

‎src/schematics/utils.ts

Lines changed: 30 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -112,41 +112,43 @@ export function addEnvironmentEntry(
112112
filePath: string,
113113
data: string,
114114
): Tree {
115-
if (!host.exists(filePath)) {
116-
throw new Error(`File ${filePath} does not exist`);
117-
}
118-
119-
const buffer = host.read(filePath);
120-
if (!buffer) {
121-
throw new SchematicsException(`Cannot read ${filePath}`);
122-
}
123-
const sourceFile = ts.createSourceFile(filePath, buffer.toString('utf-8'), ts.ScriptTarget.Latest, true);
115+
const fileExists = host.exists(filePath);
116+
if (fileExists) {
117+
const buffer = host.read(filePath);
118+
if (!buffer) {
119+
throw new SchematicsException(`Cannot read ${filePath}`);
120+
}
121+
const sourceFile = ts.createSourceFile(filePath, buffer.toString('utf-8'), ts.ScriptTarget.Latest, true);
124122

125-
const envIdentifier = findNode(sourceFile as any, ts.SyntaxKind.Identifier, 'environment');
126-
if (!envIdentifier || !envIdentifier.parent) {
127-
throw new SchematicsException(`Cannot find 'environment' identifier in ${filePath}`);
128-
}
123+
const envIdentifier = findNode(sourceFile as any, ts.SyntaxKind.Identifier, 'environment');
124+
if (!envIdentifier || !envIdentifier.parent) {
125+
throw new SchematicsException(`Cannot find 'environment' identifier in ${filePath}`);
126+
}
129127

130-
const envObjectLiteral = envIdentifier.parent.getChildren().find(({ kind }) => kind === ts.SyntaxKind.ObjectLiteralExpression);
131-
if (!envObjectLiteral) {
132-
throw new SchematicsException(`${filePath} is not in the expected format`);
133-
}
134-
const firebaseIdentifier = findNode(envObjectLiteral, ts.SyntaxKind.Identifier, 'firebase');
128+
const envObjectLiteral = envIdentifier.parent.getChildren().find(({ kind }) => kind === ts.SyntaxKind.ObjectLiteralExpression);
129+
if (!envObjectLiteral) {
130+
throw new SchematicsException(`${filePath} is not in the expected format`);
131+
}
132+
const firebaseIdentifier = findNode(envObjectLiteral, ts.SyntaxKind.Identifier, 'firebase');
135133

136-
const recorder = host.beginUpdate(filePath);
137-
if (firebaseIdentifier && firebaseIdentifier.parent) {
138-
const change = new ReplaceChange(filePath, firebaseIdentifier.parent.pos, firebaseIdentifier.parent.getFullText(), data);
139-
applyToUpdateRecorder(recorder, [change]);
140-
} else {
141-
const openBracketToken = envObjectLiteral.getChildren().find(({ kind }) => kind === ts.SyntaxKind.OpenBraceToken);
142-
if (openBracketToken) {
143-
const change = new InsertChange(filePath, openBracketToken.end, `${data},`);
134+
const recorder = host.beginUpdate(filePath);
135+
if (firebaseIdentifier && firebaseIdentifier.parent) {
136+
const change = new ReplaceChange(filePath, firebaseIdentifier.parent.pos, firebaseIdentifier.parent.getFullText(), data);
144137
applyToUpdateRecorder(recorder, [change]);
145138
} else {
146-
throw new SchematicsException(`${filePath} is not in the expected format`);
139+
const openBracketToken = envObjectLiteral.getChildren().find(({ kind }) => kind === ts.SyntaxKind.OpenBraceToken);
140+
if (openBracketToken) {
141+
const change = new InsertChange(filePath, openBracketToken.end, `${data},`);
142+
applyToUpdateRecorder(recorder, [change]);
143+
} else {
144+
throw new SchematicsException(`${filePath} is not in the expected format`);
145+
}
147146
}
147+
host.commitUpdate(recorder);
148+
} else {
149+
host.create(filePath, `export const environment = {${data},
150+
};`);
148151
}
149-
host.commitUpdate(recorder);
150152

151153
return host;
152154
}

‎test/ng-build/.browserslistrc

Lines changed: 0 additions & 17 deletions
This file was deleted.

‎test/ng-build/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ chrome-profiler-events*.json
3131
.history/*
3232

3333
# misc
34+
/.angular/cache
3435
/.sass-cache
3536
/connect.lock
3637
/coverage

‎test/ng-build/angular.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,9 @@
125125
"development": {
126126
"optimization": false,
127127
"sourceMap": true,
128-
"extractLicenses": false
128+
"extractLicenses": false,
129+
"vendorChunk": true,
130+
"buildOptimizer": false
129131
}
130132
},
131133
"defaultConfiguration": "production"
@@ -165,6 +167,5 @@
165167
}
166168
}
167169
}
168-
},
169-
"defaultProject": "ng-build"
170+
}
170171
}

‎test/ng-build/package.json

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,31 +13,31 @@
1313
},
1414
"private": true,
1515
"dependencies": {
16-
"@angular/animations": "~12.2.0",
17-
"@angular/common": "~12.2.0",
18-
"@angular/compiler": "~12.2.0",
19-
"@angular/core": "~12.2.0",
20-
"@angular/forms": "~12.2.0",
21-
"@angular/platform-browser": "~12.2.0",
22-
"@angular/platform-browser-dynamic": "~12.2.0",
23-
"@angular/platform-server": "~12.2.0",
24-
"@angular/router": "~12.2.0",
25-
"@nguniversal/express-engine": "12",
16+
"@angular/animations": "^16.0.3",
17+
"@angular/common": "^16.0.3",
18+
"@angular/compiler": "^16.0.3",
19+
"@angular/core": "^16.0.3",
20+
"@angular/forms": "^16.0.3",
21+
"@angular/platform-browser": "^16.0.3",
22+
"@angular/platform-browser-dynamic": "^16.0.3",
23+
"@angular/platform-server": "^16.0.3",
24+
"@angular/router": "^16.0.3",
25+
"@nguniversal/express-engine": "16.0.2",
2626
"express": "^4.15.2",
2727
"firebase": "^9.6.9",
2828
"firebase-admin": "^10.0.2",
2929
"rxjs": "~6.6.0",
3030
"tslib": "^2.3.0",
31-
"zone.js": "~0.11.4"
31+
"zone.js": "~0.13.0"
3232
},
3333
"devDependencies": {
34-
"@angular-devkit/build-angular": "~12.2.16",
35-
"@angular/cli": "~12.2.16",
36-
"@angular/compiler-cli": "~12.2.0",
34+
"@angular-devkit/build-angular": "^16.0.3",
35+
"@angular/cli": "^16.0.3",
36+
"@angular/compiler-cli": "^16.0.3",
3737
"@firebase/app-check-types": "^0.4.0",
38-
"@nguniversal/builders": "^12.1.3",
38+
"@nguniversal/builders": "^16.0.2",
3939
"@types/express": "^4.17.0",
4040
"@types/node": "^12.11.1",
41-
"typescript": "~4.3.5"
41+
"typescript": "~4.9.5"
4242
}
43-
}
43+
}

‎test/ng-build/src/main.server.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,3 @@ if (environment.production) {
1616
}
1717

1818
export { AppServerModule } from './app/app.server.module';
19-
export { renderModule, renderModuleFactory } from '@angular/platform-server';

‎test/ng-build/src/polyfills.ts

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,6 @@
1818
* BROWSER POLYFILLS
1919
*/
2020

21-
/**
22-
* IE11 requires the following for NgClass support on SVG elements
23-
*/
24-
// import 'classlist.js'; // Run `npm install --save classlist.js`.
25-
26-
/**
27-
* Web Animations `@angular/platform-browser/animations`
28-
* Only required if AnimationBuilder is used within the application and using IE/Edge or Safari.
29-
* Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0).
30-
*/
31-
// import 'web-animations-js'; // Run `npm install --save web-animations-js`.
32-
3321
/**
3422
* By default, zone.js will patch all possible macroTask and DomEvents
3523
* user can disable parts of macroTask/DomEvents patch by setting following flags

‎test/ng-build/tsconfig.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,13 @@
1515
"skipLibCheck": true,
1616
"moduleResolution": "node",
1717
"importHelpers": true,
18-
"target": "es2017",
18+
"target": "ES2022",
1919
"module": "es2020",
2020
"lib": [
2121
"es2018",
2222
"dom"
23-
]
23+
],
24+
"useDefineForClassFields": false
2425
},
2526
"angularCompilerOptions": {
2627
"enableI18nLegacyMessageIdFormat": false,

‎test/ng-build/tsconfig.server.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
"extends": "./tsconfig.app.json",
44
"compilerOptions": {
55
"outDir": "./out-tsc/server",
6-
"target": "es2019",
76
"types": [
87
"node"
98
]

‎test/ng-build/yarn.lock

Lines changed: 3843 additions & 4897 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎tools/build.ts

Lines changed: 1 addition & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -244,79 +244,8 @@ function measureLibrary() {
244244
return Promise.all(UMD_NAMES.map(measure));
245245
}
246246

247-
async function buildDocs() {
248-
try {
249-
// INVESTIGATE json to stdout rather than FS?
250-
await Promise.all(
251-
MODULES.map(module =>
252-
spawnPromise('npx', ['typedoc',
253-
`${module === 'core' ?
254-
join(process.cwd(), 'src') :
255-
join(process.cwd(), 'src', module)}`,
256-
'--json',
257-
join(process.cwd(), 'dist', 'typedocs', `${module}.json`)
258-
])));
259-
const entries = await Promise.all(MODULES.map(async (module) => {
260247

261-
const buffer = await readFile(join(process.cwd(), 'dist', 'typedocs', `${module}.json`));
262-
const typedoc = JSON.parse(buffer.toString());
263-
if (!typedoc.children) {
264-
console.error('typedoc fail', module);
265-
}
266-
// TODO infer the entryPoint from the package.json
267-
const entryPoint = typedoc.children.find((c: any) => c.name === '"public_api"');
268-
const allChildren = [].concat(...typedoc.children.map(child =>
269-
// TODO chop out the working directory and filename
270-
child.children ?
271-
child.children.map(c => {
272-
return { ...c, path: dirname(child.originalName.split(process.cwd())[1]) };
273-
}) :
274-
[]
275-
));
276-
return (entryPoint.children || [])
277-
.filter(c => c.name[0] !== 'ɵ' && c.name[0] !== '_' /* private */)
278-
.map(child => ({ ...allChildren.find(c => child.target === c.id) }))
279-
.reduce((acc, child) => ({ ...acc, [encodeURIComponent(child.name)]: child }), {});
280-
}));
281-
const root = await rootPackage;
282-
const pipes = ['MonoTypeOperatorFunction', 'OperatorFunction', 'AuthPipe', 'UnaryFunction'];
283-
const tocType = child => {
284-
const decorators: string[] = child.decorators && child.decorators.map(d => d.name) || [];
285-
if (decorators.includes('NgModule')) {
286-
return 'NgModule';
287-
} else if (child.kindString === 'Type alias') {
288-
return 'Type alias';
289-
} else if (child.kindString === 'Variable' && child.defaultValue && child.defaultValue.startsWith('new InjectionToken')) {
290-
return 'InjectionToken';
291-
} else if (child.type) {
292-
return pipes.includes(child.type.name) ? 'Pipe' : child.type.name;
293-
} else if (child.signatures && child.signatures[0] && child.signatures[0].type && pipes.includes(child.signatures[0].type.name)) {
294-
return 'Pipe';
295-
} else {
296-
return child.kindString;
297-
}
298-
};
299-
const tableOfContents = entries.reduce((acc, entry, index) =>
300-
({
301-
...acc, [MODULES[index]]: {
302-
name: ENTRY_NAMES[index],
303-
exports: Object.keys(entry).reduce((acc, key) => ({ ...acc, [key]: tocType(entry[key]) }), {})
304-
}
305-
}),
306-
{}
307-
);
308-
const afdoc = entries.reduce((acc, entry, index) => ({ ...acc, [MODULES[index]]: entry }), { table_of_contents: tableOfContents });
309-
return writeFile(join(process.cwd(), `api-${root.version}.json`), JSON.stringify(afdoc, null, 2));
310-
} catch (e) {
311-
console.warn(e);
312-
return Promise.resolve();
313-
}
314-
}
315-
316-
Promise.all([
317-
buildDocs(),
318-
buildLibrary()
319-
]).then(measureLibrary).then(stats =>
248+
buildLibrary().then(measureLibrary).then(stats =>
320249
console.log(`
321250
Package Size Gzipped
322251
------------------------------------

‎yarn.lock

Lines changed: 1212 additions & 933 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)
Please sign in to comment.