chore: import upstream snapshot with attribution
Deploy (to testing) and Test Playground Preview Worker / Deploy Playground Preview Worker (testing) (push) Has been skipped
Deploy Workers Shared Staging / Deploy Workers Shared Staging (push) Failing after 0s
Prerelease / build (push) Has been skipped
Handle Changesets / Handle Changesets (push) Has been cancelled
Semgrep OSS scan / semgrep-oss (push) Has been cancelled
Deploy (to testing) and Test Playground Preview Worker / Deploy Playground Preview Worker (testing) (push) Has been skipped
Deploy Workers Shared Staging / Deploy Workers Shared Staging (push) Failing after 0s
Prerelease / build (push) Has been skipped
Handle Changesets / Handle Changesets (push) Has been cancelled
Semgrep OSS scan / semgrep-oss (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
import pages from "./pages/c3";
|
||||
import workers from "./workers/c3";
|
||||
import type { MultiPlatformTemplateConfig } from "../../src/templates";
|
||||
|
||||
const config: MultiPlatformTemplateConfig = {
|
||||
displayName: "Angular",
|
||||
platformVariants: { pages, workers },
|
||||
};
|
||||
export default config;
|
||||
@@ -0,0 +1,131 @@
|
||||
import { resolve } from "node:path";
|
||||
import { logRaw } from "@cloudflare/cli-shared-helpers";
|
||||
import { brandColor, dim } from "@cloudflare/cli-shared-helpers/colors";
|
||||
import { spinner } from "@cloudflare/cli-shared-helpers/interactive";
|
||||
import { runFrameworkGenerator } from "frameworks/index";
|
||||
import { readFile, readJSON, writeFile } from "helpers/files";
|
||||
import { detectPackageManager } from "helpers/packageManagers";
|
||||
import { installPackages } from "helpers/packages";
|
||||
import type { TemplateConfig } from "../../../src/templates";
|
||||
import type { C3Context, PackageJson } from "types";
|
||||
|
||||
const { npm } = detectPackageManager();
|
||||
|
||||
const generate = async (ctx: C3Context) => {
|
||||
await runFrameworkGenerator(ctx, [ctx.project.name, "--ssr"]);
|
||||
logRaw("");
|
||||
};
|
||||
|
||||
const configure = async (ctx: C3Context) => {
|
||||
updateAngularJson(ctx);
|
||||
await updateAppCode();
|
||||
await installCFWorker();
|
||||
};
|
||||
|
||||
async function installCFWorker() {
|
||||
await installPackages(["xhr2"], {
|
||||
dev: true,
|
||||
startText: "Installing additional dependencies",
|
||||
doneText: `${brandColor("installed")} ${dim(`via \`${npm} install\``)}`,
|
||||
});
|
||||
}
|
||||
async function updateAppCode() {
|
||||
const s = spinner();
|
||||
s.start(`Updating application code`);
|
||||
|
||||
// Update an app config file to:
|
||||
// - add the `provideHttpClient(withFetch())` call to enable `fetch` usage in `HttpClient`
|
||||
const appConfigPath = "src/app/app.config.ts";
|
||||
const appConfig = readFile(resolve(appConfigPath));
|
||||
const newAppConfig =
|
||||
"import { provideHttpClient, withFetch } from '@angular/common/http';\n" +
|
||||
appConfig.replace(
|
||||
"providers: [",
|
||||
"providers: [provideHttpClient(withFetch()), "
|
||||
);
|
||||
writeFile(resolve(appConfigPath), newAppConfig);
|
||||
s.stop(`${brandColor(`updated`)} ${dim(appConfigPath)}`);
|
||||
|
||||
// Update an app server routes file to:
|
||||
const appServerRoutesPath = "src/app/app.routes.server.ts";
|
||||
const appRoutes = readFile(resolve(appServerRoutesPath));
|
||||
const newAppRoutes = appRoutes.replace(
|
||||
"RenderMode.Prerender",
|
||||
"RenderMode.Server"
|
||||
);
|
||||
writeFile(resolve(appServerRoutesPath), newAppRoutes);
|
||||
s.stop(`${brandColor(`updated`)} ${dim(appServerRoutesPath)}`);
|
||||
|
||||
// Remove unwanted dependencies
|
||||
s.start(`Updating package.json`);
|
||||
const packageJsonPath = resolve("package.json");
|
||||
const packageManifest = readJSON(packageJsonPath) as PackageJson;
|
||||
|
||||
delete packageManifest["dependencies"]?.["express"];
|
||||
delete packageManifest["devDependencies"]?.["@types/express"];
|
||||
|
||||
writeFile(packageJsonPath, JSON.stringify(packageManifest, null, 2));
|
||||
s.stop(`${brandColor(`updated`)} ${dim(`\`package.json\``)}`);
|
||||
}
|
||||
|
||||
function updateAngularJson(ctx: C3Context) {
|
||||
const s = spinner();
|
||||
s.start(`Updating angular.json config`);
|
||||
const angularJson = readJSON("angular.json") as AngularJson;
|
||||
|
||||
// Update builder
|
||||
const architectSection = angularJson.projects[ctx.project.name].architect;
|
||||
architectSection.build.options.outputPath = "dist";
|
||||
architectSection.build.options.outputMode = "server";
|
||||
architectSection.build.options.ssr.platform = "neutral";
|
||||
architectSection.build.options.assets.push("src/_routes.json");
|
||||
|
||||
writeFile(resolve("angular.json"), JSON.stringify(angularJson, null, 2));
|
||||
s.stop(`${brandColor(`updated`)} ${dim(`\`angular.json\``)}`);
|
||||
}
|
||||
|
||||
const config: TemplateConfig = {
|
||||
configVersion: 1,
|
||||
id: "angular",
|
||||
frameworkCli: "@angular/create",
|
||||
displayName: "Angular",
|
||||
platform: "pages",
|
||||
hidden: true,
|
||||
copyFiles: {
|
||||
path: "./templates",
|
||||
},
|
||||
path: "templates/angular/pages",
|
||||
devScript: "start",
|
||||
deployScript: "deploy",
|
||||
previewScript: "start",
|
||||
generate,
|
||||
configure,
|
||||
transformPackageJson: async () => ({
|
||||
scripts: {
|
||||
start: `${npm} run build && wrangler pages dev`,
|
||||
build: `ng build && ${npm} run process`,
|
||||
process: "node ./tools/copy-files.mjs",
|
||||
deploy: `${npm} run build && wrangler pages deploy`,
|
||||
"cf-typegen": `wrangler types`,
|
||||
},
|
||||
}),
|
||||
};
|
||||
export default config;
|
||||
|
||||
type AngularJson = {
|
||||
projects: Record<
|
||||
string,
|
||||
{
|
||||
architect: {
|
||||
build: {
|
||||
options: {
|
||||
outputPath: string;
|
||||
outputMode: string;
|
||||
ssr: Record<string, unknown>;
|
||||
assets: string[];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
>;
|
||||
};
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"version": 1,
|
||||
"include": ["/*"],
|
||||
"exclude": ["/*.*"]
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import { AngularAppEngine, createRequestHandler } from '@angular/ssr';
|
||||
|
||||
const angularApp = new AngularAppEngine({
|
||||
// It is safe to set allow `localhost`, so that SSR can run in local development,
|
||||
// as, in production, Cloudflare will ensure that `localhost` is not the host.
|
||||
allowedHosts: ['localhost'],
|
||||
});
|
||||
|
||||
/**
|
||||
* This is a request handler used by the Angular CLI (dev-server and during build).
|
||||
*/
|
||||
export const reqHandler = createRequestHandler(async (req) => {
|
||||
const res = await angularApp.handle(req);
|
||||
|
||||
return res ?? new Response('Page not found.', { status: 404 });
|
||||
});
|
||||
|
||||
|
||||
export default { fetch: reqHandler };
|
||||
@@ -0,0 +1,15 @@
|
||||
// Copy the files over so that they can be uploaded by the pages publish command.
|
||||
import fs from "node:fs";
|
||||
import { join, resolve } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const root = resolve(fileURLToPath(import.meta.url), "../../");
|
||||
const client = resolve(root, "dist/browser");
|
||||
const ssr = resolve(root, "dist/server");
|
||||
const cloudflare = resolve(root, "dist/cloudflare");
|
||||
const worker = resolve(cloudflare, "_worker.js");
|
||||
|
||||
fs.cpSync(client, cloudflare, { recursive: true });
|
||||
fs.cpSync(ssr, worker, { recursive: true });
|
||||
|
||||
fs.renameSync(join(worker, "server.mjs"), join(worker, "index.js"));
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"name": "<WORKER_NAME>",
|
||||
"compatibility_date": "<COMPATIBILITY_DATE>",
|
||||
"pages_build_output_dir": "./dist/cloudflare"
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
import { resolve } from "node:path";
|
||||
import { logRaw } from "@cloudflare/cli-shared-helpers";
|
||||
import { brandColor, dim } from "@cloudflare/cli-shared-helpers/colors";
|
||||
import { spinner } from "@cloudflare/cli-shared-helpers/interactive";
|
||||
import { runFrameworkGenerator } from "frameworks/index";
|
||||
import { readFile, readJSON, writeFile } from "helpers/files";
|
||||
import { detectPackageManager } from "helpers/packageManagers";
|
||||
import { installPackages } from "helpers/packages";
|
||||
import type { TemplateConfig } from "../../../src/templates";
|
||||
import type { C3Context, PackageJson } from "types";
|
||||
|
||||
const { npm } = detectPackageManager();
|
||||
|
||||
const generate = async (ctx: C3Context) => {
|
||||
await runFrameworkGenerator(ctx, [ctx.project.name, "--ssr"]);
|
||||
logRaw("");
|
||||
};
|
||||
|
||||
const configure = async (ctx: C3Context) => {
|
||||
updateAngularJson(ctx);
|
||||
await updateAppCode();
|
||||
await installCFWorker();
|
||||
};
|
||||
|
||||
async function installCFWorker() {
|
||||
await installPackages(["xhr2"], {
|
||||
dev: true,
|
||||
startText: "Installing additional dependencies",
|
||||
doneText: `${brandColor("installed")} ${dim(`via \`${npm} install\``)}`,
|
||||
});
|
||||
}
|
||||
async function updateAppCode() {
|
||||
const s = spinner();
|
||||
s.start(`Updating application code`);
|
||||
|
||||
// Update an app config file to:
|
||||
// - add the `provideHttpClient(withFetch())` call to enable `fetch` usage in `HttpClient`
|
||||
const appConfigPath = "src/app/app.config.ts";
|
||||
const appConfig = readFile(resolve(appConfigPath));
|
||||
const newAppConfig =
|
||||
"import { provideHttpClient, withFetch } from '@angular/common/http';\n" +
|
||||
appConfig.replace(
|
||||
"providers: [",
|
||||
"providers: [provideHttpClient(withFetch()), "
|
||||
);
|
||||
writeFile(resolve(appConfigPath), newAppConfig);
|
||||
s.stop(`${brandColor(`updated`)} ${dim(appConfigPath)}`);
|
||||
|
||||
// Update an app server routes file to:
|
||||
const appServerRoutesPath = "src/app/app.routes.server.ts";
|
||||
const appRoutes = readFile(resolve(appServerRoutesPath));
|
||||
const newAppRoutes = appRoutes.replace(
|
||||
"RenderMode.Prerender",
|
||||
"RenderMode.Server"
|
||||
);
|
||||
writeFile(resolve(appServerRoutesPath), newAppRoutes);
|
||||
s.stop(`${brandColor(`updated`)} ${dim(appServerRoutesPath)}`);
|
||||
|
||||
// Remove unwanted dependencies
|
||||
s.start(`Updating package.json`);
|
||||
const packageJsonPath = resolve("package.json");
|
||||
const packageManifest = readJSON(packageJsonPath) as PackageJson;
|
||||
|
||||
delete packageManifest["dependencies"]?.["express"];
|
||||
delete packageManifest["devDependencies"]?.["@types/express"];
|
||||
|
||||
writeFile(packageJsonPath, JSON.stringify(packageManifest, null, 2));
|
||||
s.stop(`${brandColor(`updated`)} ${dim(`\`package.json\``)}`);
|
||||
}
|
||||
|
||||
function updateAngularJson(ctx: C3Context) {
|
||||
const s = spinner();
|
||||
s.start(`Updating angular.json config`);
|
||||
const angularJson = readJSON(resolve("angular.json")) as AngularJson;
|
||||
// Update builder
|
||||
const architectSection = angularJson.projects[ctx.project.name].architect;
|
||||
architectSection.build.options.outputPath = "dist";
|
||||
architectSection.build.options.outputMode = "server";
|
||||
architectSection.build.options.ssr.platform = "neutral";
|
||||
|
||||
writeFile(resolve("angular.json"), JSON.stringify(angularJson, null, 2));
|
||||
s.stop(`${brandColor(`updated`)} ${dim(`\`angular.json\``)}`);
|
||||
}
|
||||
|
||||
const config: TemplateConfig = {
|
||||
configVersion: 1,
|
||||
id: "angular",
|
||||
frameworkCli: "@angular/create",
|
||||
displayName: "Angular",
|
||||
platform: "workers",
|
||||
copyFiles: {
|
||||
path: "./templates",
|
||||
},
|
||||
path: "templates/angular/workers",
|
||||
devScript: "start",
|
||||
deployScript: "deploy",
|
||||
previewScript: "preview",
|
||||
generate,
|
||||
configure,
|
||||
transformPackageJson: async () => ({
|
||||
scripts: {
|
||||
preview: `${npm} run build && wrangler dev`,
|
||||
build: `ng build`,
|
||||
deploy: `${npm} run build && wrangler deploy`,
|
||||
"cf-typegen": `wrangler types`,
|
||||
},
|
||||
}),
|
||||
};
|
||||
export default config;
|
||||
|
||||
type AngularJson = {
|
||||
projects: Record<
|
||||
string,
|
||||
{
|
||||
architect: {
|
||||
build: {
|
||||
options: {
|
||||
outputPath: string;
|
||||
outputMode: string;
|
||||
ssr: Record<string, unknown>;
|
||||
assets: string[];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
>;
|
||||
};
|
||||
@@ -0,0 +1,19 @@
|
||||
import { AngularAppEngine, createRequestHandler } from '@angular/ssr';
|
||||
|
||||
const angularApp = new AngularAppEngine({
|
||||
// It is safe to set allow `localhost`, so that SSR can run in local development,
|
||||
// as, in production, Cloudflare will ensure that `localhost` is not the host.
|
||||
allowedHosts: ['localhost'],
|
||||
});
|
||||
|
||||
/**
|
||||
* This is a request handler used by the Angular CLI (dev-server and during build).
|
||||
*/
|
||||
export const reqHandler = createRequestHandler(async (req) => {
|
||||
const res = await angularApp.handle(req);
|
||||
|
||||
return res ?? new Response('Page not found.', { status: 404 });
|
||||
});
|
||||
|
||||
|
||||
export default { fetch: reqHandler };
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"name": "<WORKER_NAME>",
|
||||
"main": "./dist/server/server.mjs",
|
||||
"compatibility_date": "<COMPATIBILITY_DATE>",
|
||||
"assets": {
|
||||
"binding": "ASSETS",
|
||||
"directory": "./dist/browser"
|
||||
},
|
||||
"observability": {
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user