Skip to content

Commit

Permalink
feat(env): server/secret variables (#10954)
Browse files Browse the repository at this point in the history
Co-authored-by: Bjorn Lu <[email protected]>
Co-authored-by: Emanuele Stoppa <[email protected]>
  • Loading branch information
3 people authored May 8, 2024
1 parent 87ea8ab commit 9edc5e5
Show file tree
Hide file tree
Showing 32 changed files with 339 additions and 102 deletions.
3 changes: 1 addition & 2 deletions packages/astro/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,7 @@
"env.d.ts",
"client.d.ts",
"jsx-runtime.d.ts",
"content-types.template.d.ts",
"content-module.template.mjs",
"templates",
"astro-jsx.d.ts",
"types/content.d.ts",
"types.d.ts",
Expand Down
5 changes: 5 additions & 0 deletions packages/astro/src/@types/astro.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2428,6 +2428,11 @@ export type AstroFeatureMap = {
* List of features that orbit around the i18n routing
*/
i18nDomains?: SupportsKind;

/**
* The adapter is able to support `astro:env`
*/
env?: SupportsKind;
};

export interface AstroAssetsFeature {
Expand Down
8 changes: 4 additions & 4 deletions packages/astro/src/content/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ import { AstroError, AstroErrorData } from '../core/errors/index.js';

import { MarkdownError } from '../core/errors/index.js';
import { isYAMLException } from '../core/errors/utils.js';
import { CONTENT_FLAGS, CONTENT_TYPES_FILE, PROPAGATED_ASSET_FLAG } from './consts.js';
import { CONTENT_FLAGS, PROPAGATED_ASSET_FLAG } from './consts.js';
import { errorMap } from './error-map.js';
import { createImage } from './runtime-assets.js';

/**
* Amap from a collection + slug to the local file path.
* This is used internally to resolve entry imports when using `getEntry()`.
* @see `content-module.template.mjs`
* @see `templates/content/module.mjs`
*/
export type ContentLookupMap = {
[collectionName: string]: { type: 'content' | 'data'; entries: { [lookupId: string]: string } };
Expand Down Expand Up @@ -438,8 +438,8 @@ export function getContentPaths(
return {
contentDir: new URL('./content/', srcDir),
assetsDir: new URL('./assets/', srcDir),
typesTemplate: new URL('content-types.template.d.ts', pkgBase),
virtualModTemplate: new URL('content-module.template.mjs', pkgBase),
typesTemplate: new URL('templates/content/types.d.ts', pkgBase),
virtualModTemplate: new URL('templates/content/module.mjs', pkgBase),
config: configStats,
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ function getStringifiedCollectionFromLookup(
/**
* Generate a map from a collection + slug to the local file path.
* This is used internally to resolve entry imports when using `getEntry()`.
* @see `content-module.template.mjs`
* @see `templates/content/module.mjs`
*/
export async function generateLookupMap({
settings,
Expand Down
15 changes: 14 additions & 1 deletion packages/astro/src/core/app/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ import { matchRoute } from '../routing/match.js';
import { createOriginCheckMiddleware } from './middlewares.js';
import { AppPipeline } from './pipeline.js';
export { deserializeManifest } from './common.js';
import type { GetEnv } from '../../env/types.js';
import { setGetEnv } from '../../runtime/server/astro-env.js';

export interface RenderOptions {
/**
Expand Down Expand Up @@ -65,6 +67,9 @@ export interface RenderOptions {
* Default: `app.match(request)`
*/
routeData?: RouteData;

/** TODO: add docs in a later PR */
getEnv?: GetEnv;
}

export interface RenderErrorOptions {
Expand Down Expand Up @@ -260,13 +265,15 @@ export class App {
let locals: object | undefined;
let clientAddress: string | undefined;
let addCookieHeader: boolean | undefined;
let getEnv: GetEnv | undefined;

if (
routeDataOrOptions &&
('addCookieHeader' in routeDataOrOptions ||
'clientAddress' in routeDataOrOptions ||
'locals' in routeDataOrOptions ||
'routeData' in routeDataOrOptions)
'routeData' in routeDataOrOptions ||
'getEnv' in routeDataOrOptions)
) {
if ('addCookieHeader' in routeDataOrOptions) {
addCookieHeader = routeDataOrOptions.addCookieHeader;
Expand All @@ -280,6 +287,9 @@ export class App {
if ('locals' in routeDataOrOptions) {
locals = routeDataOrOptions.locals;
}
if ('getEnv' in routeDataOrOptions) {
getEnv = routeDataOrOptions.getEnv;
}
} else {
routeData = routeDataOrOptions as RouteData | undefined;
locals = maybeLocals;
Expand Down Expand Up @@ -307,6 +317,9 @@ export class App {
if (!routeData) {
return this.#renderError(request, { locals, status: 404 });
}
if (this.#manifest.experimentalEnv && getEnv) {
setGetEnv(getEnv);
}
const pathname = this.#getPathnameFromRequest(request);
const defaultStatus = this.#getDefaultStatusCode(routeData, pathname);
const mod = await this.#getModuleForRoute(routeData);
Expand Down
1 change: 1 addition & 0 deletions packages/astro/src/core/app/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export type SSRManifest = {
i18n: SSRManifestI18n | undefined;
middleware: MiddlewareHandler;
checkOrigin: boolean;
experimentalEnv: boolean;
};

export type SSRManifestI18n = {
Expand Down
1 change: 1 addition & 0 deletions packages/astro/src/core/build/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -616,5 +616,6 @@ function createBuildManifest(
buildFormat: settings.config.build.format,
middleware,
checkOrigin: settings.config.experimental.security?.csrfProtection?.origin ?? false,
experimentalEnv: !!settings.config.experimental.env,
};
}
1 change: 1 addition & 0 deletions packages/astro/src/core/build/plugins/plugin-manifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -277,5 +277,6 @@ function buildManifest(
i18n: i18nManifest,
buildFormat: settings.config.build.format,
checkOrigin: settings.config.experimental.security?.csrfProtection?.origin ?? false,
experimentalEnv: !!settings.config.experimental.env,
};
}
18 changes: 15 additions & 3 deletions packages/astro/src/core/errors/errors-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1162,10 +1162,22 @@ export const i18nNotEnabled = {
* The failing environment variable does not match the type and constraints defined in `experimental.env.schema`.
*/
export const EnvInvalidVariables = {
name: 'EnvInvalidVariable',
title: 'Invalid Environment variable',
name: 'EnvInvalidVariables',
title: 'Invalid Environment Variables',
message: (variables: string) =>
`The following environment variable does not match the type and constraints defined in \`experimental.env.schema\`:\n\n${variables}\n`,
`The following environment variables do not match the type and constraints defined in \`experimental.env.schema\`:\n\n${variables}\n`,
} satisfies ErrorData;

/**
* @docs
* @description
* The failing environment variable does not match the type and constraints defined in `experimental.env.schema`.
*/
export const EnvInvalidVariable = {
name: 'EnvInvalidVariable',
title: 'Invalid Environment Variable',
message: (key: string, type: string) =>
`The following environment variable does not match the type and constraints defined in \`experimental.env.schema\`: "${key}" is not of type ${type}`,
} satisfies ErrorData;

/**
Expand Down
15 changes: 10 additions & 5 deletions packages/astro/src/env/constants.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
export const VIRTUAL_CLIENT_MODULE_ID = 'astro:env/client';
export const RESOLVED_VIRTUAL_CLIENT_MODULE_ID = '\0astro:env/client';
export const VIRTUAL_SERVER_MODULE_ID = 'astro:env/server';
export const RESOLVED_VIRTUAL_SERVER_MODULE_ID = '\0astro:env/server';
export const VIRTUAL_MODULES_IDS = {
client: 'astro:env/client',
server: 'astro:env/server',
internal: 'virtual:astro:env/internal',
};

export const PUBLIC_PREFIX = 'PUBLIC_';
export const ENV_TYPES_FILE = 'astro-env.d.ts';
export const ENV_TYPES_FILE = 'env.d.ts';

const PKG_BASE = new URL('../../', import.meta.url);
export const MODULE_TEMPLATE_URL = new URL('templates/env/module.mjs', PKG_BASE);
export const TYPES_TEMPLATE_URL = new URL('templates/env/types.d.ts', PKG_BASE);
1 change: 1 addition & 0 deletions packages/astro/src/env/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type GetEnv = (key: string) => string | undefined;
Loading

0 comments on commit 9edc5e5

Please sign in to comment.