@idevconn/create-icore 0.10.0 → 0.10.1
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/dist/cli.js +3 -0
- package/dist/index.cjs +3 -0
- package/dist/index.js +3 -0
- package/package.json +1 -1
- package/templates/apps/templates/client-antd/package.json +1 -1
- package/templates/libs/auth-strategies/firebase/package.json +1 -0
- package/templates/libs/auth-strategies/firebase/src/lib/firebase-auth.module.ts +2 -1
- package/templates/libs/auth-strategies/mongodb/package.json +1 -1
- package/templates/libs/db-strategies/firestore/package.json +1 -0
- package/templates/libs/db-strategies/firestore/src/lib/firestore-db.module.ts +2 -1
- package/templates/libs/db-strategies/mongodb/package.json +1 -1
- package/templates/libs/firebase-admin/package.json +1 -1
- package/templates/libs/firebase-admin/src/lib/__tests__/firebase-admin.unit.test.ts +11 -11
- package/templates/libs/firebase-admin/src/lib/firebase-admin.ts +6 -6
- package/templates/libs/storage-strategies/firebase/package.json +1 -0
- package/templates/libs/storage-strategies/firebase/src/lib/firebase-storage.module.ts +4 -1
- package/templates/libs/storage-strategies/mongodb/package.json +1 -1
- package/templates/libs/template-shared/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -2188,6 +2188,9 @@ async function scaffold(rawOpts, templatesDir2) {
|
|
|
2188
2188
|
await writePnpmWorkspace(opts.targetDir);
|
|
2189
2189
|
await rewritePnpmWorkspaceDeps(opts.targetDir);
|
|
2190
2190
|
}
|
|
2191
|
+
if (opts.packageManager === "npm") {
|
|
2192
|
+
await writeFile9(join10(opts.targetDir, ".npmrc"), "legacy-peer-deps=true\n");
|
|
2193
|
+
}
|
|
2191
2194
|
await patchGitignoreForPm(opts.targetDir, opts.packageManager);
|
|
2192
2195
|
await writeAiFiles(opts.targetDir, opts);
|
|
2193
2196
|
if (opts.install) runInstall(opts.targetDir, opts.packageManager);
|
package/dist/index.cjs
CHANGED
|
@@ -1892,6 +1892,9 @@ async function scaffold(rawOpts, templatesDir) {
|
|
|
1892
1892
|
await writePnpmWorkspace(opts.targetDir);
|
|
1893
1893
|
await rewritePnpmWorkspaceDeps(opts.targetDir);
|
|
1894
1894
|
}
|
|
1895
|
+
if (opts.packageManager === "npm") {
|
|
1896
|
+
await (0, import_promises9.writeFile)((0, import_node_path9.join)(opts.targetDir, ".npmrc"), "legacy-peer-deps=true\n");
|
|
1897
|
+
}
|
|
1895
1898
|
await patchGitignoreForPm(opts.targetDir, opts.packageManager);
|
|
1896
1899
|
await writeAiFiles(opts.targetDir, opts);
|
|
1897
1900
|
if (opts.install) runInstall(opts.targetDir, opts.packageManager);
|
package/dist/index.js
CHANGED
|
@@ -1849,6 +1849,9 @@ async function scaffold(rawOpts, templatesDir) {
|
|
|
1849
1849
|
await writePnpmWorkspace(opts.targetDir);
|
|
1850
1850
|
await rewritePnpmWorkspaceDeps(opts.targetDir);
|
|
1851
1851
|
}
|
|
1852
|
+
if (opts.packageManager === "npm") {
|
|
1853
|
+
await writeFile9(join9(opts.targetDir, ".npmrc"), "legacy-peer-deps=true\n");
|
|
1854
|
+
}
|
|
1852
1855
|
await patchGitignoreForPm(opts.targetDir, opts.packageManager);
|
|
1853
1856
|
await writeAiFiles(opts.targetDir, opts);
|
|
1854
1857
|
if (opts.install) runInstall(opts.targetDir, opts.packageManager);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@idevconn/create-icore",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.1",
|
|
4
4
|
"description": "Bootstrap a new project from the iCore scaffold (Nx + NestJS + React + Vite + shadcn/Tailwind, swappable auth + storage providers).",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "iDEVconn",
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Module, DynamicModule } from '@nestjs/common';
|
|
2
2
|
import { ConfigService } from '@nestjs/config';
|
|
3
3
|
import { getFirebaseAdmin, FIREBASE_ADMIN_REQUIRED_ENV } from '@icore/firebase-admin';
|
|
4
|
+
import { getAuth } from 'firebase-admin/auth';
|
|
4
5
|
import { buildStrategyWithFallback, FakeAuthStrategy } from '@icore/shared';
|
|
5
6
|
import type { AuthStrategy } from '@icore/shared';
|
|
6
7
|
import { FirebaseAuthStrategy } from './firebase-auth.strategy';
|
|
@@ -28,7 +29,7 @@ export class FirebaseAuthModule {
|
|
|
28
29
|
const identityToolkit = new HttpIdentityToolkitClient(
|
|
29
30
|
cfg.getOrThrow<string>('FIREBASE_WEB_API_KEY'),
|
|
30
31
|
);
|
|
31
|
-
return new FirebaseAuthStrategy({ identityToolkit, adminAuth: app
|
|
32
|
+
return new FirebaseAuthStrategy({ identityToolkit, adminAuth: getAuth(app) });
|
|
32
33
|
},
|
|
33
34
|
fake: () => new FakeAuthStrategy(),
|
|
34
35
|
}),
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Module, DynamicModule } from '@nestjs/common';
|
|
2
2
|
import { ConfigService } from '@nestjs/config';
|
|
3
3
|
import { getFirebaseAdmin, FIREBASE_ADMIN_REQUIRED_ENV } from '@icore/firebase-admin';
|
|
4
|
+
import { getFirestore } from 'firebase-admin/firestore';
|
|
4
5
|
import { buildStrategyWithFallback, FakeDBStrategy } from '@icore/shared';
|
|
5
6
|
import type { DBStrategy } from '@icore/shared';
|
|
6
7
|
import { FirestoreDBStrategy } from './firestore-db.strategy';
|
|
@@ -25,7 +26,7 @@ export class FirestoreDbModule {
|
|
|
25
26
|
build: () => {
|
|
26
27
|
const app = getFirebaseAdmin(cfg);
|
|
27
28
|
return new FirestoreDBStrategy({
|
|
28
|
-
db: app
|
|
29
|
+
db: getFirestore(app) as unknown as ConstructorParameters<
|
|
29
30
|
typeof FirestoreDBStrategy
|
|
30
31
|
>[0]['db'],
|
|
31
32
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
2
|
|
|
3
|
-
const { apps, cert, initializeApp,
|
|
3
|
+
const { apps, cert, initializeApp, getApp, getApps } = vi.hoisted(() => {
|
|
4
4
|
const apps: unknown[] = [];
|
|
5
5
|
return {
|
|
6
6
|
apps,
|
|
@@ -10,17 +10,16 @@ const { apps, cert, initializeApp, app } = vi.hoisted(() => {
|
|
|
10
10
|
apps.push(created);
|
|
11
11
|
return created;
|
|
12
12
|
}),
|
|
13
|
-
|
|
13
|
+
getApp: vi.fn(() => apps[0]),
|
|
14
|
+
getApps: vi.fn(() => apps),
|
|
14
15
|
};
|
|
15
16
|
});
|
|
16
17
|
|
|
17
|
-
vi.mock('firebase-admin', () => ({
|
|
18
|
-
|
|
19
|
-
return apps;
|
|
20
|
-
},
|
|
21
|
-
app,
|
|
18
|
+
vi.mock('firebase-admin/app', () => ({
|
|
19
|
+
cert,
|
|
22
20
|
initializeApp,
|
|
23
|
-
|
|
21
|
+
getApp,
|
|
22
|
+
getApps,
|
|
24
23
|
}));
|
|
25
24
|
|
|
26
25
|
import { FIREBASE_ADMIN_REQUIRED_ENV, getFirebaseAdmin } from '../firebase-admin';
|
|
@@ -59,7 +58,8 @@ describe('getFirebaseAdmin', () => {
|
|
|
59
58
|
apps.length = 0;
|
|
60
59
|
cert.mockClear();
|
|
61
60
|
initializeApp.mockClear();
|
|
62
|
-
|
|
61
|
+
getApp.mockClear();
|
|
62
|
+
getApps.mockClear();
|
|
63
63
|
});
|
|
64
64
|
|
|
65
65
|
afterEach(() => vi.restoreAllMocks());
|
|
@@ -94,12 +94,12 @@ describe('getFirebaseAdmin', () => {
|
|
|
94
94
|
expect(sa['private_key']).not.toContain('\\n');
|
|
95
95
|
});
|
|
96
96
|
|
|
97
|
-
it('initializes the default app only once (guards on
|
|
97
|
+
it('initializes the default app only once (guards on getApps)', () => {
|
|
98
98
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
99
99
|
const cfg = makeCfg() as any;
|
|
100
100
|
getFirebaseAdmin(cfg);
|
|
101
101
|
getFirebaseAdmin(cfg);
|
|
102
102
|
expect(initializeApp).toHaveBeenCalledTimes(1);
|
|
103
|
-
expect(
|
|
103
|
+
expect(getApp).toHaveBeenCalledTimes(1); // second call returns the existing app
|
|
104
104
|
});
|
|
105
105
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { initializeApp, getApps, getApp, cert, App, ServiceAccount } from 'firebase-admin/app';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Minimal structural view of NestJS's `ConfigService` — just the two readers
|
|
@@ -46,11 +46,11 @@ export const FIREBASE_ADMIN_REQUIRED_ENV = [
|
|
|
46
46
|
* tokens from project_id/client_email/private_key, but feeding the complete
|
|
47
47
|
* downloaded JSON keeps the code aligned with the documented FB_ADMIN_* env.
|
|
48
48
|
*/
|
|
49
|
-
export function getFirebaseAdmin(cfg: FirebaseConfigReader):
|
|
50
|
-
if (
|
|
49
|
+
export function getFirebaseAdmin(cfg: FirebaseConfigReader): App {
|
|
50
|
+
if (getApps().length > 0) return getApp();
|
|
51
51
|
|
|
52
|
-
return
|
|
53
|
-
credential:
|
|
52
|
+
return initializeApp({
|
|
53
|
+
credential: cert({
|
|
54
54
|
type: cfg.getOrThrow<string>('FB_ADMIN_TYPE'),
|
|
55
55
|
project_id: cfg.getOrThrow<string>('FB_ADMIN_PROJECT_ID'),
|
|
56
56
|
private_key_id: cfg.getOrThrow<string>('FB_ADMIN_PRIVATE_KEY_ID'),
|
|
@@ -62,7 +62,7 @@ export function getFirebaseAdmin(cfg: FirebaseConfigReader): admin.app.App {
|
|
|
62
62
|
auth_provider_x509_cert_url: cfg.getOrThrow<string>('FB_ADMIN_AUTH_PROVIDER_X509_CERT_URL'),
|
|
63
63
|
client_x509_cert_url: cfg.getOrThrow<string>('FB_ADMIN_CLIENT_X509_CERT_URL'),
|
|
64
64
|
universe_domain: cfg.getOrThrow<string>('FB_ADMIN_UNIVERSE_DOMAIN'),
|
|
65
|
-
} as
|
|
65
|
+
} as ServiceAccount),
|
|
66
66
|
// Optional: the storage MS also passes the bucket name explicitly to
|
|
67
67
|
// .bucket(); set here too so admin.storage().bucket() (no arg) works.
|
|
68
68
|
storageBucket: cfg.get<string>('FIREBASE_STORAGE_BUCKET'),
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Module, DynamicModule } from '@nestjs/common';
|
|
2
2
|
import { ConfigService } from '@nestjs/config';
|
|
3
3
|
import { getFirebaseAdmin, FIREBASE_ADMIN_REQUIRED_ENV } from '@icore/firebase-admin';
|
|
4
|
+
import { getStorage } from 'firebase-admin/storage';
|
|
4
5
|
import { buildStrategyWithFallback, FakeStorageStrategy } from '@icore/shared';
|
|
5
6
|
import type { StorageStrategy } from '@icore/shared';
|
|
6
7
|
import {
|
|
@@ -32,7 +33,9 @@ export class FirebaseStorageModule {
|
|
|
32
33
|
const bucketName = cfg.getOrThrow<string>('FIREBASE_STORAGE_BUCKET');
|
|
33
34
|
const app = getFirebaseAdmin(cfg);
|
|
34
35
|
return new FirebaseStorageStrategy({
|
|
35
|
-
bucket: app
|
|
36
|
+
bucket: getStorage(app).bucket(
|
|
37
|
+
bucketName,
|
|
38
|
+
) as unknown as FirebaseStorageBucketLike,
|
|
36
39
|
});
|
|
37
40
|
},
|
|
38
41
|
fake: () => new FakeStorageStrategy(),
|