feat: init

This commit is contained in:
2026-02-13 22:02:30 +01:00
commit 8f9ff830fb
16711 changed files with 3307340 additions and 0 deletions

View File

@@ -0,0 +1,3 @@
export type { AWSAmplifyOptions as PresetOptions } from "./types";
declare const _default: readonly [any];
export default _default;

View File

@@ -0,0 +1,27 @@
import { defineNitroPreset } from "nitropack/kit";
import { writeAmplifyFiles } from "./utils.mjs";
const awsAmplify = defineNitroPreset(
{
extends: "node-server",
entry: "./runtime/aws-amplify",
output: {
dir: "{{ rootDir }}/.amplify-hosting",
serverDir: "{{ output.dir }}/compute/default",
publicDir: "{{ output.dir }}/static{{ baseURL }}"
},
commands: {
preview: "node {{ output.serverDir }}/server.js"
},
hooks: {
async compiled(nitro) {
await writeAmplifyFiles(nitro);
}
}
},
{
name: "aws-amplify",
stdName: "aws_amplify",
url: import.meta.url
}
);
export default [awsAmplify];

View File

@@ -0,0 +1 @@
import "#nitro-internal-pollyfills";

View File

@@ -0,0 +1,13 @@
import "#nitro-internal-pollyfills";
import { useNitroApp } from "nitropack/runtime";
import { Server } from "node:http";
import { toNodeListener } from "h3";
const nitroApp = useNitroApp();
const server = new Server(toNodeListener(nitroApp.h3App));
server.listen(3e3, (err) => {
if (err) {
console.error(err);
} else {
console.log(`Listening on http://localhost:3000 (AWS Amplify Hosting)`);
}
});

View File

@@ -0,0 +1,142 @@
export interface AmplifyComputeConfig {
/**
* The name property dictates the name of the provisioned compute resource. It is also the name
* of the sub-directory in the `compute` folder in the deployment bundle.
*/
name: string;
/**
* The runtime property dictates the runtime of the provisioned compute resource.
* Values are subset of https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html
*/
runtime: "nodejs16.x" | "nodejs18.x" | "nodejs20.x";
/**
* Specifies the starting file from which code will run for the given compute resource.
* The specified file should exist inside the given sub-directory that represents a compute resource.
*
* @example `"entrypoint.js"`
*/
entrypoint: string;
}
export type AmplifyRouteTarget = {
kind: "Static";
cacheControl?: string;
} | {
kind: "ImageOptimization";
cacheControl?: string;
} | {
kind: "Compute";
/**
* A string that indicates the name of the sub-directory in the given deployment bundle that
* contains the primitive's executable code. Valid and required only for the Compute primitive.
* The value here should point to one of the compute resources present in the given
* deployment bundle. The only supported value for this field is default.
*/
src: string;
};
export type AmplifyRoute = {
/**
* The path defines a glob pattern that matches incoming request paths (excluding querystring).
* The first match in a given list of rules determines which routing rule is applied to the incoming request.
* Only the following wildcard characters are supported as far as pattern matching is concerned: `*` (matches 0 or more characters)
*
* _Note_: The "/*" pattern is called a catch-all pattern and will match all incoming requests.
* It is special because fallback routing is only supported for catch-all routes.
*
*/
path: string;
/**
* An object that dictates the target to route the matched request to.
*/
target: AmplifyRouteTarget;
/** An object that dictates the target to fallback to if the original target returns a 404. */
fallback?: AmplifyRouteTarget;
};
export type AmplifyImageSettings = {
/** Array of supported image widths */
sizes: number[];
/**
* Array of allowed external domains that can use Image Optimization.
* Leave empty for only allowing the deployment domain to use Image Optimization.
*/
domains: string[];
/**
* Array of allowed external patterns that can use Image Optimization.
* Similar to `domains` but provides more control with RegExp.
*/
remotePatterns: {
/** The protocol of the allowed remote pattern. Can be `http` or `https`. */
protocol?: "http" | "https";
/**
* The hostname of the allowed remote pattern.
* Can be literal or wildcard. Single `*` matches a single subdomain.
* Double `**` matches any number of subdomains.
* We will disallow blanket wildcards of `**` with nothing else.
*/
hostname: string;
/** The port of the allowed remote pattern. */
port?: string;
/** The pathname of the allowed remote pattern. */
pathname?: string;
}[];
/** Array of allowed output image formats. */
formats: ("image/avif" | "image/webp" | "image/gif" | "image/png" | "image/jpeg")[];
/** Cache duration (in seconds) for the optimized images. */
minimumCacheTTL: number;
/** Allow SVG input image URLs. This is disabled by default for security purposes. */
dangerouslyAllowSVG: boolean;
};
export interface AmplifyDeployManifest {
/** The `version` property dictates the version of the Deployment Specification that has been implemented */
version: 1;
/**
* The routes property allows framework authors to leverage the routing rules primitive.
* Routing rules provide a mechanism by which incoming request paths can be routed to a specific target
* in the deployment bundle. Routing rules only dictate the destination of an incoming request and they are
* applied after rewrite/redirect rules have already transformed the request.
*
* Limits for routing rules:
* - A limit of 25 rules will be enforced on the routes array
*/
routes?: AmplifyRoute[];
/**
* The imageSettings property allows framework authors to customize the behavior of the image optimization primitive,
* which provides on-demand optimization of images at runtime.
*/
imageSettings?: AmplifyImageSettings;
/**
* Metadata about the provisioned compute resource(s). Each item in the array is an object that contains metadata
* about that compute resource.
*
* For example, given the following directory structure:
* ```
* .amplify
* └── compute
* └── default
* └── index.js
* ```
* The `computeResources` property would look like:
* ```
* [
* {
* name: 'default',
* runtime: 'nodejs16.x',
* entrypoint: 'index.js',
* }
* ]
* ```
*/
computeResources?: AmplifyComputeConfig[];
framework: {
name: string;
version: string;
};
}
export interface AWSAmplifyOptions {
catchAllStaticFallback?: boolean;
imageOptimization?: {
path?: string;
cacheControl?: string;
};
imageSettings?: AmplifyImageSettings;
runtime?: "nodejs16.x" | "nodejs18.x" | "nodejs20.x";
}

View File

View File

@@ -0,0 +1,2 @@
import type { Nitro } from "nitropack/types";
export declare function writeAmplifyFiles(nitro: Nitro): Promise<void>;

View File

@@ -0,0 +1,82 @@
import { writeFile } from "node:fs/promises";
import { resolve } from "node:path";
import { joinURL } from "ufo";
export async function writeAmplifyFiles(nitro) {
const outDir = nitro.options.output.dir;
const routes = [];
let hasWildcardPublicAsset = false;
if (nitro.options.awsAmplify?.imageOptimization && !nitro.options.static) {
const { path, cacheControl } = nitro.options.awsAmplify?.imageOptimization || {};
if (path) {
routes.push({
path,
target: {
kind: "ImageOptimization",
cacheControl
}
});
}
}
const computeTarget = nitro.options.static ? { kind: "Static" } : { kind: "Compute", src: "default" };
for (const publicAsset of nitro.options.publicAssets) {
if (!publicAsset.baseURL || publicAsset.baseURL === "/") {
hasWildcardPublicAsset = true;
continue;
}
routes.push({
path: `${publicAsset.baseURL.replace(/\/$/, "")}/*`,
target: {
kind: "Static",
cacheControl: publicAsset.maxAge > 0 ? `public, max-age=${publicAsset.maxAge}, immutable` : void 0
},
fallback: publicAsset.fallthrough ? computeTarget : void 0
});
}
if (hasWildcardPublicAsset && !nitro.options.static) {
routes.push({
path: "/*.*",
target: {
kind: "Static"
},
fallback: computeTarget
});
}
routes.push({
path: "/*",
target: computeTarget,
fallback: hasWildcardPublicAsset && nitro.options.awsAmplify?.catchAllStaticFallback ? {
kind: "Static"
} : void 0
});
for (const route of routes) {
if (route.path !== "/*") {
route.path = joinURL(nitro.options.baseURL, route.path);
}
}
const deployManifest = {
version: 1,
routes,
imageSettings: nitro.options.awsAmplify?.imageSettings || void 0,
computeResources: nitro.options.static ? void 0 : [
{
name: "default",
entrypoint: "server.js",
runtime: nitro.options.awsAmplify?.runtime || "nodejs20.x"
}
],
framework: {
name: nitro.options.framework.name || "nitro",
version: nitro.options.framework.version || "0.0.0"
}
};
await writeFile(
resolve(outDir, "deploy-manifest.json"),
JSON.stringify(deployManifest, null, 2)
);
if (!nitro.options.static) {
await writeFile(
resolve(outDir, "compute/default/server.js"),
`import("./index.mjs")`
);
}
}