cloudflare-next-intl 0.10.6 → 0.10.7
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/src/firebase_auth_check/check_firebase_auth_config.d.ts +5 -0
- package/dist/src/firebase_auth_check/check_firebase_auth_config.js +74 -1
- package/dist/src/firebase_auth_check/index.d.ts +2 -1
- package/dist/src/firebase_auth_check/index.js +2 -1
- package/dist/src/firebase_auth_check/load_resolved_firebase_auth.d.ts +8 -0
- package/dist/src/firebase_auth_check/load_resolved_firebase_auth.js +51 -0
- package/dist/src/vite/firebase_auth_check_plugin.js +16 -2
- package/package.json +1 -1
|
@@ -27,3 +27,8 @@ export declare function extractFieldValue(body: string, key: string): {
|
|
|
27
27
|
} | null;
|
|
28
28
|
export declare function formatFirebaseAuthConfigMessage(issues: FirebaseAuthConfigIssue[], intlConfigPath?: string): string;
|
|
29
29
|
export declare function checkFirebaseAuthConfig(options?: CheckFirebaseAuthConfigOptions): CheckFirebaseAuthConfigReport;
|
|
30
|
+
export interface ValidateFirebaseAuthConfigValuesOptions {
|
|
31
|
+
firebaseAuth: Record<string, unknown> | undefined;
|
|
32
|
+
intlConfigPath?: string;
|
|
33
|
+
}
|
|
34
|
+
export declare function validateFirebaseAuthConfigValues(options: ValidateFirebaseAuthConfigValuesOptions): CheckFirebaseAuthConfigReport;
|
|
@@ -337,7 +337,29 @@ function resolveSpreadBodies(mainBody, source, fromFile, cache) {
|
|
|
337
337
|
return { bodies, hasUnresolvedSpread };
|
|
338
338
|
}
|
|
339
339
|
export function extractFieldValue(body, key) {
|
|
340
|
-
const
|
|
340
|
+
const masked = maskCommentsAndStrings(body);
|
|
341
|
+
const keyPattern = new RegExp(`^${key}\\s*:`);
|
|
342
|
+
let searchDepth = 0;
|
|
343
|
+
let scanIndex = 0;
|
|
344
|
+
let keyMatch = null;
|
|
345
|
+
while (scanIndex < masked.length) {
|
|
346
|
+
const char = masked[scanIndex];
|
|
347
|
+
if (char === "{" || char === "[" || char === "(") {
|
|
348
|
+
searchDepth += 1;
|
|
349
|
+
}
|
|
350
|
+
else if (char === "}" || char === "]" || char === ")") {
|
|
351
|
+
searchDepth -= 1;
|
|
352
|
+
}
|
|
353
|
+
else if (searchDepth === 0 && (scanIndex === 0 || /[\s{,]/.test(masked[scanIndex - 1]))) {
|
|
354
|
+
const candidate = keyPattern.exec(masked.slice(scanIndex));
|
|
355
|
+
if (candidate) {
|
|
356
|
+
keyMatch = candidate;
|
|
357
|
+
keyMatch.index = scanIndex;
|
|
358
|
+
break;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
scanIndex += 1;
|
|
362
|
+
}
|
|
341
363
|
if (!keyMatch)
|
|
342
364
|
return null;
|
|
343
365
|
const start = keyMatch.index + keyMatch[0].length;
|
|
@@ -531,3 +553,54 @@ export function checkFirebaseAuthConfig(options = {}) {
|
|
|
531
553
|
}
|
|
532
554
|
return { valid, checked: true, issues, formattedMessage };
|
|
533
555
|
}
|
|
556
|
+
function isUsableFieldValue(value) {
|
|
557
|
+
if (value === undefined || value === null)
|
|
558
|
+
return false;
|
|
559
|
+
if (typeof value === "string")
|
|
560
|
+
return value.trim() !== "";
|
|
561
|
+
return true;
|
|
562
|
+
}
|
|
563
|
+
const UNUSABLE_REASON = "resolved to an empty or missing value";
|
|
564
|
+
export function validateFirebaseAuthConfigValues(options) {
|
|
565
|
+
const { firebaseAuth } = options;
|
|
566
|
+
if (!firebaseAuth) {
|
|
567
|
+
return { valid: true, checked: false, issues: [], formattedMessage: "" };
|
|
568
|
+
}
|
|
569
|
+
const issues = [];
|
|
570
|
+
for (const key of REQUIRED_AUTH_FIELDS) {
|
|
571
|
+
if (!isUsableFieldValue(firebaseAuth[key])) {
|
|
572
|
+
issues.push({ field: `firebaseAuth.${key}`, severity: "error", reason: UNUSABLE_REASON });
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
const appCheck = firebaseAuth.appCheck;
|
|
576
|
+
if (appCheck && appCheck.reportMissingServerCredentials !== false) {
|
|
577
|
+
for (const key of REQUIRED_APP_CHECK_FIELDS) {
|
|
578
|
+
if (!isUsableFieldValue(appCheck[key])) {
|
|
579
|
+
issues.push({ field: `firebaseAuth.appCheck.${key}`, severity: "warning", reason: UNUSABLE_REASON });
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
const hasPrivateKey = isUsableFieldValue(appCheck.privateKey);
|
|
583
|
+
const tripleUsable = OAUTH_TRIPLE.map((key) => isUsableFieldValue(appCheck[key]));
|
|
584
|
+
const hasTriple = tripleUsable.every(Boolean);
|
|
585
|
+
if (!hasPrivateKey && !hasTriple) {
|
|
586
|
+
const hasPartialTriple = tripleUsable.some(Boolean);
|
|
587
|
+
if (hasPartialTriple) {
|
|
588
|
+
OAUTH_TRIPLE.forEach((key, index) => {
|
|
589
|
+
if (!tripleUsable[index]) {
|
|
590
|
+
issues.push({ field: `firebaseAuth.appCheck.${key}`, severity: "warning", reason: UNUSABLE_REASON });
|
|
591
|
+
}
|
|
592
|
+
});
|
|
593
|
+
}
|
|
594
|
+
else {
|
|
595
|
+
issues.push({
|
|
596
|
+
field: "firebaseAuth.appCheck.privateKey",
|
|
597
|
+
severity: "warning",
|
|
598
|
+
reason: UNUSABLE_REASON + " — set it, or the full oauthClientId/oauthClientSecret/oauthRefreshToken triple",
|
|
599
|
+
});
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
const valid = !issues.some((issue) => issue.severity === "error");
|
|
604
|
+
const formattedMessage = formatFirebaseAuthConfigMessage(issues, options.intlConfigPath);
|
|
605
|
+
return { valid, checked: true, issues, formattedMessage };
|
|
606
|
+
}
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export { checkFirebaseAuthConfig, formatFirebaseAuthConfigMessage, extractObjectLiteral, extractFieldValue, type FirebaseAuthConfigIssue, type CheckFirebaseAuthConfigOptions, type CheckFirebaseAuthConfigReport, } from "./check_firebase_auth_config.js";
|
|
1
|
+
export { checkFirebaseAuthConfig, validateFirebaseAuthConfigValues, formatFirebaseAuthConfigMessage, extractObjectLiteral, extractFieldValue, type FirebaseAuthConfigIssue, type CheckFirebaseAuthConfigOptions, type CheckFirebaseAuthConfigReport, type ValidateFirebaseAuthConfigValuesOptions, } from "./check_firebase_auth_config.js";
|
|
2
|
+
export { loadResolvedFirebaseAuth, type LoadResolvedFirebaseAuthOptions } from "./load_resolved_firebase_auth.js";
|
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export { checkFirebaseAuthConfig, formatFirebaseAuthConfigMessage, extractObjectLiteral, extractFieldValue, } from "./check_firebase_auth_config.js";
|
|
1
|
+
export { checkFirebaseAuthConfig, validateFirebaseAuthConfigValues, formatFirebaseAuthConfigMessage, extractObjectLiteral, extractFieldValue, } from "./check_firebase_auth_config.js";
|
|
2
|
+
export { loadResolvedFirebaseAuth } from "./load_resolved_firebase_auth.js";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ResolvedConfig } from "vite";
|
|
2
|
+
export interface LoadResolvedFirebaseAuthOptions {
|
|
3
|
+
intlConfigPath: string;
|
|
4
|
+
viteConfig: Pick<ResolvedConfig, "root" | "envDir" | "mode"> & {
|
|
5
|
+
resolve: Pick<ResolvedConfig["resolve"], "alias">;
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
export declare function loadResolvedFirebaseAuth(options: LoadResolvedFirebaseAuthOptions): Promise<Record<string, unknown> | undefined>;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export async function loadResolvedFirebaseAuth(options) {
|
|
2
|
+
let server;
|
|
3
|
+
try {
|
|
4
|
+
const { createServer } = await import("vite");
|
|
5
|
+
server = await createServer({
|
|
6
|
+
configFile: false,
|
|
7
|
+
root: options.viteConfig.root,
|
|
8
|
+
envDir: options.viteConfig.envDir,
|
|
9
|
+
mode: options.viteConfig.mode,
|
|
10
|
+
resolve: { alias: options.viteConfig.resolve.alias },
|
|
11
|
+
server: { middlewareMode: true, hmr: false, watch: null },
|
|
12
|
+
optimizeDeps: { noDiscovery: true },
|
|
13
|
+
logLevel: "silent",
|
|
14
|
+
clearScreen: false,
|
|
15
|
+
ssr: { noExternal: ["cloudflare-next-intl", /^cloudflare:/] },
|
|
16
|
+
plugins: [
|
|
17
|
+
{
|
|
18
|
+
name: "cfni:firebase-auth-check-intl-config-alias",
|
|
19
|
+
enforce: "pre",
|
|
20
|
+
resolveId(id) {
|
|
21
|
+
if (id === "@intl-config")
|
|
22
|
+
return options.intlConfigPath;
|
|
23
|
+
if (id === "cloudflare:workers" || id.startsWith("cloudflare:")) {
|
|
24
|
+
return "\0cfni:cloudflare-workers-stub";
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
load(id) {
|
|
28
|
+
if (id === "\0cfni:cloudflare-workers-stub") {
|
|
29
|
+
return ("export class WorkerEntrypoint {}\n" +
|
|
30
|
+
"export class DurableObject {}\n" +
|
|
31
|
+
"export const env = {};\n" +
|
|
32
|
+
"export default {};\n");
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
});
|
|
38
|
+
const mod = await server.ssrLoadModule(options.intlConfigPath);
|
|
39
|
+
const exported = mod.default;
|
|
40
|
+
const firebaseAuth = exported?.firebaseAuth;
|
|
41
|
+
return firebaseAuth && typeof firebaseAuth === "object"
|
|
42
|
+
? firebaseAuth
|
|
43
|
+
: undefined;
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return undefined;
|
|
47
|
+
}
|
|
48
|
+
finally {
|
|
49
|
+
await server?.close();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { checkFirebaseAuthConfig } from "../firebase_auth_check/index.js";
|
|
1
|
+
import { checkFirebaseAuthConfig, validateFirebaseAuthConfigValues, loadResolvedFirebaseAuth, } from "../firebase_auth_check/index.js";
|
|
2
2
|
import { resolveDefaultIntlConfigPath } from "./locale_file_plugin.js";
|
|
3
3
|
export function firebaseAuthCheckPlugin(options = {}) {
|
|
4
4
|
let ran = false;
|
|
@@ -23,7 +23,21 @@ export function firebaseAuthCheckPlugin(options = {}) {
|
|
|
23
23
|
...process.env,
|
|
24
24
|
};
|
|
25
25
|
}
|
|
26
|
-
const
|
|
26
|
+
const previousEnv = { ...process.env };
|
|
27
|
+
Object.assign(process.env, env);
|
|
28
|
+
let firebaseAuth;
|
|
29
|
+
try {
|
|
30
|
+
firebaseAuth = await loadResolvedFirebaseAuth({
|
|
31
|
+
intlConfigPath,
|
|
32
|
+
viteConfig: { root: config.root, envDir: config.envDir, mode: config.mode, resolve: { alias: config.resolve?.alias } },
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
finally {
|
|
36
|
+
process.env = previousEnv;
|
|
37
|
+
}
|
|
38
|
+
const report = firebaseAuth !== undefined
|
|
39
|
+
? validateFirebaseAuthConfigValues({ firebaseAuth, intlConfigPath })
|
|
40
|
+
: checkFirebaseAuthConfig({ intlConfigPath, env, throwOnError: false });
|
|
27
41
|
if (report.issues.length === 0)
|
|
28
42
|
return;
|
|
29
43
|
console.warn(report.formattedMessage);
|