Skip to content

Commit 27802c8

Browse files
Merge branch 'production'
2 parents ca152c6 + 4150276 commit 27802c8

File tree

16 files changed

+413
-31
lines changed

16 files changed

+413
-31
lines changed

.github/workflows/anchor-link-audit.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ jobs:
3939
- run: npm run build
4040
env:
4141
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
42-
NODE_OPTIONS: "--max-old-space-size=4192"
4342

4443
- name: Install dependencies
4544
run: curl https://htmltest.wjdp.uk | bash

.github/workflows/ci.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ jobs:
6565
- run: npm run build
6666
env:
6767
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
68-
NODE_OPTIONS: "--max-old-space-size=6144"
6968
RUN_LINK_CHECK: true
7069

7170
- run: npm run check:worker

.github/workflows/publish-preview.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ jobs:
3333
name: Build
3434
env:
3535
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
36-
NODE_OPTIONS: --max-old-space-size=6144
3736
- name: Deploy to Cloudflare Workers
3837
env:
3938
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}

.github/workflows/publish-production.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ jobs:
2828
name: Build
2929
env:
3030
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
31-
NODE_OPTIONS: --max-old-space-size=6144
3231
- run: npx wrangler deploy
3332
name: Deploy to Cloudflare Workers
3433
env:

bin/generate-descriptions.ts

Lines changed: 75 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,35 @@
1414
* 2. Have a local Worker running on `localhost:8787` with the following code (also requires adding a binding in the Wrangler config file):
1515
*
1616
* ```
17-
* export interface Env {
18-
* AI: Ai;
19-
* }
20-
21-
* export default {
22-
* async fetch(request, env): Promise<Response> {
23-
* const response = await env.AI.run("@cf/facebook/bart-large-cnn", {
24-
* input_text: await request.text(),
25-
* max_length: 60
26-
* });
27-
* return Response.json(response.summary);
28-
* },
29-
* } satisfies ExportedHandler<Env>;
17+
export interface Env {
18+
AI: Ai;
19+
}
20+
21+
export default {
22+
async fetch(request, env): Promise<Response> {
23+
24+
const input_text = await request.text()
25+
26+
const messages = [
27+
{ role: "system", content: "You are an assistant who helps summarize long chunks of text." },
28+
{ role: "system", content: "You help generate optimized SEO descriptions that are - at most - 60 words. These also convey the most important points of the page and contain keywords." },
29+
{ role: "system", content: "In your response, provide no content other than the summary text."},
30+
{
31+
role: "user",
32+
content: input_text,
33+
},
34+
];
35+
const response = await env.AI.run("@cf/meta/llama-3.3-70b-instruct-fp8-fast", { messages });
36+
37+
return Response.json(response.response);
38+
},
39+
} satisfies ExportedHandler<Env>;
3040
* ```
31-
* 3. Run `npx tsx bin/generate-descriptions.ts --pcx-content-type $TYPE` to generate the descriptions.
41+
* 3. Run `npx tsx bin/generate-descriptions.ts [options]` to generate the descriptions.
42+
*
43+
* Available options:
44+
* - `--pcx-content-type $TYPE`: Filter by content type (e.g., tutorial, overview)
45+
* - `--product $PRODUCT`: Filter by product folder (e.g., workers, pages, r2)
3246
*
3347
*/
3448

@@ -166,18 +180,22 @@ async function updateFrontmatter(
166180
function parseArgs() {
167181
const args = process.argv.slice(2);
168182
let pcxContentType: string | undefined;
183+
let product: string | undefined;
169184
let showHelp = false;
170185

171186
for (let i = 0; i < args.length; i++) {
172187
if (args[i] === "--pcx-content-type" && i + 1 < args.length) {
173188
pcxContentType = args[i + 1];
174189
i++; // Skip the next argument as it's the value
190+
} else if (args[i] === "--product" && i + 1 < args.length) {
191+
product = args[i + 1];
192+
i++; // Skip the next argument as it's the value
175193
} else if (args[i] === "--help" || args[i] === "-h") {
176194
showHelp = true;
177195
}
178196
}
179197

180-
return { pcxContentType, showHelp };
198+
return { pcxContentType, product, showHelp };
181199
}
182200

183201
/**
@@ -189,13 +207,14 @@ Usage: npx tsx bin/generate-descriptions.ts [options]
189207
190208
Options:
191209
--pcx-content-type <type> Filter MDX files by pcx_content_type (e.g., overview, tutorial, navigation)
210+
--product <product> Filter MDX files by product folder (e.g., workers, pages, r2)
192211
--help, -h Show this help message
193212
`);
194213
}
195214

196215
async function main() {
197216
// Parse command line arguments
198-
const { pcxContentType, showHelp } = parseArgs();
217+
const { pcxContentType, product, showHelp } = parseArgs();
199218

200219
if (showHelp) {
201220
showUsage();
@@ -205,6 +224,10 @@ async function main() {
205224
if (pcxContentType) {
206225
console.log(`Filtering by pcx_content_type: ${pcxContentType}`);
207226
}
227+
228+
if (product) {
229+
console.log(`Filtering by product: ${product}`);
230+
}
208231
try {
209232
// Find all MDX files in the docs directory
210233
const mdxFiles = await globby("**/*.mdx", {
@@ -213,21 +236,45 @@ async function main() {
213236
});
214237
console.log(`Found ${mdxFiles.length} MDX files in the docs directory`);
215238

216-
// Filter files by pcx_content_type if specified
239+
// Filter files by product if specified
217240
let filteredMdxFiles = mdxFiles;
241+
if (product) {
242+
const productPath = path.join(DOCS_DIR, product);
243+
244+
// Check if the product directory exists
245+
try {
246+
await fs.access(productPath);
247+
} catch (error) {
248+
console.error(
249+
`Product directory not found: ${productPath} -- ${error}`,
250+
);
251+
process.exit(1);
252+
}
253+
254+
// Filter files by product
255+
filteredMdxFiles = mdxFiles.filter((file) => {
256+
return file.startsWith(productPath);
257+
});
258+
console.log(
259+
`Filtered to ${filteredMdxFiles.length} MDX files in product: ${product}`,
260+
);
261+
}
262+
263+
// Further filter files by pcx_content_type if specified
218264
if (pcxContentType) {
219-
filteredMdxFiles = [];
220-
for (const mdxFile of mdxFiles) {
265+
const contentTypeFiltered = [];
266+
for (const mdxFile of filteredMdxFiles) {
221267
try {
222268
const content = await fs.readFile(mdxFile, "utf-8");
223269
const { data: frontmatter } = matter(content);
224270
if (frontmatter.pcx_content_type === pcxContentType) {
225-
filteredMdxFiles.push(mdxFile);
271+
contentTypeFiltered.push(mdxFile);
226272
}
227273
} catch (error) {
228274
console.error(`Error reading ${mdxFile}:`, error);
229275
}
230276
}
277+
filteredMdxFiles = contentTypeFiltered;
231278
console.log(
232279
`Filtered to ${filteredMdxFiles.length} MDX files with pcx_content_type: ${pcxContentType}`,
233280
);
@@ -306,6 +353,14 @@ async function main() {
306353

307354
console.log("\n--- Summary ---");
308355
console.log(`Total MDX files: ${mdxFiles.length}`);
356+
if (product) {
357+
console.log(`Files in product '${product}': ${filteredMdxFiles.length}`);
358+
}
359+
if (pcxContentType) {
360+
console.log(
361+
`Files with pcx_content_type '${pcxContentType}': ${filteredMdxFiles.length}`,
362+
);
363+
}
309364
console.log(`Updated: ${updatedCount}`);
310365
console.log(`Skipped (already had description): ${skippedExistingCount}`);
311366
console.log(`Skipped (description unchanged): ${skippedUnchangedCount}`);

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"type": "module",
55
"scripts": {
66
"astro": "npx astro",
7-
"build": "npx astro build",
7+
"build": "export NODE_OPTIONS='--max-old-space-size=6192' || set NODE_OPTIONS='--max-old-space-size=6192'&& npx astro build",
88
"typegen:worker": "npx wrangler types ./worker/worker-configuration.d.ts",
99
"check": "npm run check:astro && npm run check:worker",
1010
"check:astro": "npx astro check",
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
---
2+
title: Introducing email two-factor authentication
3+
description: Cloudflare now offers email two-factor authentication to protect your account
4+
date: 2025-10-30
5+
---
6+
7+
Two-factor authentication (2FA) is one of the best ways to protect your account from the risk of account takeover. Cloudflare has offered phishing resistant 2FA options including hardware based keys (for example, a Yubikey) and app based TOTP (time-based one-time password) options which use apps like Google or Microsoft's Authenticator app. Unfortunately, while these solutions are very secure, they can be lost if you misplace the hardware based key, or lose the phone which includes that app. The result is that users sometimes get locked out of their accounts and need to contact support.
8+
9+
Today, we are announcing the addition of email as a 2FA factor for all Cloudflare accounts. Email 2FA is in wide use across the industry as a least common denominator for 2FA because it is low friction, loss resistant, and still improves security over username/password login only. We also know that most commercial email providers already require 2FA, so your email address is usually well protected already.
10+
11+
You can now enable email 2FA on the Cloudflare dashboard:
12+
13+
1. Go to **Profile** at the top right corner.
14+
2. Select **Authentication**.
15+
3. Under **Two-Factor Authentication**, select **Set up**.
16+
17+
## Sign-in security best practices
18+
19+
Cloudflare is critical infrastructure, and you should protect it as such. Review the following best practices and make sure you are doing your part to secure your account:
20+
21+
- Use a unique password for every website, including Cloudflare, and store it in a password manager like 1Password or Keeper. These services are cross-platform and simplify the process of managing secure passwords.
22+
- Use 2FA to make it harder for an attacker to get into your account in the event your password is leaked.
23+
- Store your backup codes securely. A password manager is the best place since it keeps the backup codes encrypted, but you can also print them and put them somewhere safe in your home.
24+
- If you use an app to manage your 2FA keys, enable cloud backup, so that you don't lose your keys in the event you lose your phone.
25+
- If you use a custom email domain to sign in, [configure SSO](/fundamentals/manage-members/dashboard-sso/).
26+
- If you use a public email domain like Gmail or Hotmail, you can also use social login with Apple, GitHub, or Google to sign in.
27+
- If you manage a Cloudflare account for work:
28+
- Have at least two administrators in case one of them unexpectedly leaves your company.
29+
- Use SCIM to automate permissions management for members in your Cloudflare account.

src/content/docs/images/upload-images/sourcing-kit/index.mdx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ With Sourcing Kit you can define one or multiple repositories of images to bulk
1010

1111
Sourcing Kit also lets you target paths, define prefixes for imported images, and obtain error logs for bulk operations.
1212

13-
Sourcing Kit is available in beta. If you have any comments, questions, or bugs to report, contact the Images team on our [Discord channel](https://discord.cloudflare.com). You can also engage with other users and the Images team on the [Cloudflare Community](https://community.cloudflare.com/c/developers/images/63).
14-
1513
## When to use Sourcing Kit
1614

1715
Sourcing Kit can be a good choice if the Amazon S3 bucket you are importing consists primarily of images stored using non-archival storage classes, as images stored using [archival storage classes](https://aws.amazon.com/s3/storage-classes/#Archive) will be skipped and need to be imported separately. Specifically:

src/content/docs/r2/demos.mdx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ pcx_content_type: navigation
33
title: Demos and architectures
44
sidebar:
55
order: 10
6+
description: >-
7+
Explore Cloudflare R2 demos and reference architectures for fullstack applications, storage, and AI, with examples and use cases.
68
---
79

810
import {

src/content/docs/r2/get-started.mdx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ sidebar:
66
head:
77
- tag: title
88
content: Getting started guide
9+
description: >-
10+
Cloudflare R2 Storage allows developers to store unstructured data without costly egress fees, offering bucket creation and object upload via dashboard or API.
911
---
1012

1113
import { Render, PackageManagers, DashButton } from "~/components";

0 commit comments

Comments
 (0)