mirror of
https://github.com/withastro/astro.git
synced 2024-12-16 21:46:22 -05:00
Merge branch 'main' into next
This commit is contained in:
commit
40760a8ace
89 changed files with 1241 additions and 885 deletions
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
'@astrojs/db': patch
|
||||
---
|
||||
|
||||
Fixes mixed environment variable for app token when using DB commands with libSQL remote.
|
|
@ -1,5 +0,0 @@
|
|||
---
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
Fixes case where content layer did not update during clean dev builds on Linux and Windows
|
63
.changeset/mighty-stingrays-press.md
Normal file
63
.changeset/mighty-stingrays-press.md
Normal file
|
@ -0,0 +1,63 @@
|
|||
---
|
||||
'astro': patch
|
||||
---
|
||||
|
||||
Adds support for Zod discriminated unions on Action form inputs. This allows forms with different inputs to be submitted to the same action, using a given input to decide which object should be used for validation.
|
||||
|
||||
This example accepts either a `create` or `update` form submission, and uses the `type` field to determine which object to validate against.
|
||||
|
||||
```ts
|
||||
import { defineAction } from 'astro:actions';
|
||||
import { z } from 'astro:schema';
|
||||
|
||||
export const server = {
|
||||
changeUser: defineAction({
|
||||
accept: 'form',
|
||||
input: z.discriminatedUnion('type', [
|
||||
z.object({
|
||||
type: z.literal('create'),
|
||||
name: z.string(),
|
||||
email: z.string().email(),
|
||||
}),
|
||||
z.object({
|
||||
type: z.literal('update'),
|
||||
id: z.number(),
|
||||
name: z.string(),
|
||||
email: z.string().email(),
|
||||
}),
|
||||
]),
|
||||
async handler(input) {
|
||||
if (input.type === 'create') {
|
||||
// input is { type: 'create', name: string, email: string }
|
||||
} else {
|
||||
// input is { type: 'update', id: number, name: string, email: string }
|
||||
}
|
||||
},
|
||||
}),
|
||||
}
|
||||
```
|
||||
|
||||
The corresponding `create` and `update` forms may look like this:
|
||||
|
||||
```astro
|
||||
---
|
||||
import { actions } from 'astro:actions';
|
||||
---
|
||||
|
||||
<!--Create-->
|
||||
<form action={actions.changeUser} method="POST">
|
||||
<input type="hidden" name="type" value="create" />
|
||||
<input type="text" name="name" required />
|
||||
<input type="email" name="email" required />
|
||||
<button type="submit">Create User</button>
|
||||
</form>
|
||||
|
||||
<!--Update-->
|
||||
<form action={actions.changeUser} method="POST">
|
||||
<input type="hidden" name="type" value="update" />
|
||||
<input type="hidden" name="id" value="user-123" />
|
||||
<input type="text" name="name" required />
|
||||
<input type="email" name="email" required />
|
||||
<button type="submit">Update User</button>
|
||||
</form>
|
||||
```
|
|
@ -11,7 +11,7 @@
|
|||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/preact": "^3.5.2",
|
||||
"@astrojs/preact": "^3.5.3",
|
||||
"@astrojs/react": "^3.6.2",
|
||||
"@astrojs/solid-js": "^4.4.1",
|
||||
"@astrojs/svelte": "^6.0.0-alpha.0",
|
||||
|
@ -24,6 +24,6 @@
|
|||
"react-dom": "^18.3.1",
|
||||
"solid-js": "^1.8.22",
|
||||
"svelte": "^4.2.19",
|
||||
"vue": "^3.4.38"
|
||||
"vue": "^3.5.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/preact": "^3.5.2",
|
||||
"@astrojs/preact": "^3.5.3",
|
||||
"@preact/signals": "^1.3.0",
|
||||
"astro": "^5.0.0-alpha.6",
|
||||
"preact": "^10.23.2"
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
"@astrojs/react": "^3.6.2",
|
||||
"@astrojs/tailwind": "^6.0.0-alpha.0",
|
||||
"@fortawesome/fontawesome-free": "^6.6.0",
|
||||
"@tailwindcss/forms": "^0.5.8",
|
||||
"@tailwindcss/forms": "^0.5.9",
|
||||
"@types/react": "^18.3.5",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"astro": "^5.0.0-alpha.6",
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/preact": "^3.5.2",
|
||||
"@astrojs/preact": "^3.5.3",
|
||||
"@nanostores/preact": "^0.5.2",
|
||||
"astro": "^5.0.0-alpha.6",
|
||||
"nanostores": "^0.11.3",
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
"astro": "^5.0.0-alpha.6",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"canvas-confetti": "^1.9.3",
|
||||
"postcss": "^8.4.43",
|
||||
"postcss": "^8.4.45",
|
||||
"tailwindcss": "^3.4.10"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,10 +55,10 @@
|
|||
"@astrojs/check": "^0.9.3",
|
||||
"@biomejs/biome": "1.8.3",
|
||||
"@changesets/changelog-github": "^0.5.0",
|
||||
"@changesets/cli": "^2.27.7",
|
||||
"@changesets/cli": "^2.27.8",
|
||||
"@types/node": "^18.17.8",
|
||||
"esbuild": "^0.21.5",
|
||||
"eslint": "^9.9.1",
|
||||
"eslint": "^9.10.0",
|
||||
"eslint-plugin-no-only-tests": "^3.3.0",
|
||||
"eslint-plugin-regexp": "^2.6.0",
|
||||
"globby": "^14.0.2",
|
||||
|
@ -67,7 +67,7 @@
|
|||
"prettier-plugin-astro": "^0.14.1",
|
||||
"turbo": "^2.1.1",
|
||||
"typescript": "~5.5.4",
|
||||
"typescript-eslint": "^8.3.0"
|
||||
"typescript-eslint": "^8.4.0"
|
||||
},
|
||||
"pnpm": {
|
||||
"peerDependencyRules": {
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
"xml2js": "0.6.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"fast-xml-parser": "^4.4.1",
|
||||
"fast-xml-parser": "^4.5.0",
|
||||
"kleur": "^4.1.5"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,6 +69,42 @@
|
|||
});
|
||||
```
|
||||
|
||||
## 4.15.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#11879](https://github.com/withastro/astro/pull/11879) [`bd1d4aa`](https://github.com/withastro/astro/commit/bd1d4aaf8262187b4f132d7fe0365902131ddf1a) Thanks [@matthewp](https://github.com/matthewp)! - Allow passing a cryptography key via ASTRO_KEY
|
||||
|
||||
For Server islands Astro creates a cryptography key in order to hash props for the islands, preventing accidental leakage of secrets.
|
||||
|
||||
If you deploy to an environment with rolling updates then there could be multiple instances of your app with different keys, causing potential key mismatches.
|
||||
|
||||
To fix this you can now pass the `ASTRO_KEY` environment variable to your build in order to reuse the same key.
|
||||
|
||||
To generate a key use:
|
||||
|
||||
```
|
||||
astro create-key
|
||||
```
|
||||
|
||||
This will print out an environment variable to set like:
|
||||
|
||||
```
|
||||
ASTRO_KEY=PIAuyPNn2aKU/bviapEuc/nVzdzZPizKNo3OqF/5PmQ=
|
||||
```
|
||||
|
||||
- [#11935](https://github.com/withastro/astro/pull/11935) [`c58193a`](https://github.com/withastro/astro/commit/c58193a691775af5c568e461c63040a42e2471f7) Thanks [@Princesseuh](https://github.com/Princesseuh)! - Fixes `astro add` not using the proper export point when adding certain adapters
|
||||
|
||||
## 4.15.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#11902](https://github.com/withastro/astro/pull/11902) [`d63bc50`](https://github.com/withastro/astro/commit/d63bc50d9940c1107e0fee7687e5c332549a0eff) Thanks [@ascorbic](https://github.com/ascorbic)! - Fixes case where content layer did not update during clean dev builds on Linux and Windows
|
||||
|
||||
- [#11886](https://github.com/withastro/astro/pull/11886) [`7ff7134`](https://github.com/withastro/astro/commit/7ff7134b8038a3b798293b2218bbf6dd02d2ac32) Thanks [@matthewp](https://github.com/matthewp)! - Fixes a missing error message when actions throws during `astro sync`
|
||||
|
||||
- [#11904](https://github.com/withastro/astro/pull/11904) [`ca54e3f`](https://github.com/withastro/astro/commit/ca54e3f819fad009ac3c3c8b57a26014a2652a73) Thanks [@wtchnm](https://github.com/wtchnm)! - perf(assets): avoid downloading original image when using cache
|
||||
|
||||
## 5.0.0-alpha.5
|
||||
|
||||
### Major Changes
|
||||
|
|
|
@ -5,6 +5,6 @@
|
|||
"dependencies": {
|
||||
"@astrojs/vue": "workspace:*",
|
||||
"astro": "workspace:*",
|
||||
"vue": "^3.4.38"
|
||||
"vue": "^3.5.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,6 @@
|
|||
"react-dom": "^18.3.1",
|
||||
"solid-js": "^1.8.22",
|
||||
"svelte": "^4.2.19",
|
||||
"vue": "^3.4.38"
|
||||
"vue": "^3.5.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,6 @@
|
|||
"private": true,
|
||||
"dependencies": {
|
||||
"astro": "workspace:*",
|
||||
"sass": "^1.77.8"
|
||||
"sass": "^1.78.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,9 +12,9 @@
|
|||
"preact": "^10.23.2",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"sass": "^1.77.8",
|
||||
"sass": "^1.78.0",
|
||||
"solid-js": "^1.8.22",
|
||||
"svelte": "^4.2.19",
|
||||
"vue": "^3.4.38"
|
||||
"vue": "^3.5.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,6 @@
|
|||
"private": true,
|
||||
"devDependencies": {
|
||||
"astro": "workspace:*",
|
||||
"sass": "^1.77.8"
|
||||
"sass": "^1.78.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,6 @@
|
|||
"react-dom": "^18.3.1",
|
||||
"solid-js": "^1.8.22",
|
||||
"svelte": "^4.2.19",
|
||||
"vue": "^3.4.38"
|
||||
"vue": "^3.5.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,6 @@
|
|||
"react-dom": "^18.3.1",
|
||||
"solid-js": "^1.8.22",
|
||||
"svelte": "^4.2.19",
|
||||
"vue": "^3.4.38"
|
||||
"vue": "^3.5.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,6 @@
|
|||
"react-dom": "^18.3.1",
|
||||
"solid-js": "^1.8.22",
|
||||
"svelte": "^4.2.19",
|
||||
"vue": "^3.4.38"
|
||||
"vue": "^3.5.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,6 @@
|
|||
"react-dom": "^18.3.1",
|
||||
"solid-js": "^1.8.22",
|
||||
"svelte": "^4.2.19",
|
||||
"vue": "^3.4.38"
|
||||
"vue": "^3.5.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,6 @@
|
|||
"react-dom": "^18.3.1",
|
||||
"solid-js": "^1.8.22",
|
||||
"svelte": "^4.2.19",
|
||||
"vue": "^3.4.38"
|
||||
"vue": "^3.5.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,6 @@
|
|||
"react-dom": "^18.3.1",
|
||||
"solid-js": "^1.8.22",
|
||||
"svelte": "^4.2.19",
|
||||
"vue": "^3.4.38"
|
||||
"vue": "^3.5.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
"react-dom": "^18.3.1",
|
||||
"solid-js": "^1.8.22",
|
||||
"svelte": "^4.2.19",
|
||||
"vue": "^3.4.38"
|
||||
"vue": "^3.5.3"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "astro dev"
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
import { defineConfig } from 'astro/config';
|
||||
import node from '@astrojs/node';
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
output: 'server',
|
||||
adapter: node({ mode: 'standalone' }),
|
||||
integrations: [],
|
||||
experimental: {
|
||||
serverIslands: true,
|
||||
}
|
||||
});
|
12
packages/astro/e2e/fixtures/server-islands-key/package.json
Normal file
12
packages/astro/e2e/fixtures/server-islands-key/package.json
Normal file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"name": "@e2e/server-islands-key",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "astro dev"
|
||||
},
|
||||
"dependencies": {
|
||||
"astro": "workspace:*",
|
||||
"@astrojs/node": "^8.3.3"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
const { secret } = Astro.props;
|
||||
---
|
||||
<h2 id="island">I am an island</h2>
|
||||
<slot />
|
||||
<h3 id="secret">{secret}</h3>
|
|
@ -0,0 +1,14 @@
|
|||
---
|
||||
import Island from '../components/Island.astro';
|
||||
---
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<!-- Head Stuff -->
|
||||
</head>
|
||||
<body>
|
||||
<Island server:defer secret="test">
|
||||
<h3 id="children">children</h3>
|
||||
</Island>
|
||||
</body>
|
||||
</html>
|
|
@ -6,7 +6,7 @@
|
|||
"@astrojs/tailwind": "workspace:*",
|
||||
"astro": "workspace:*",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"postcss": "^8.4.43",
|
||||
"postcss": "^8.4.45",
|
||||
"tailwindcss": "^3.4.10"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,6 @@
|
|||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"svelte": "^4.2.19",
|
||||
"vue": "^3.4.38"
|
||||
"vue": "^3.5.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,6 @@
|
|||
"@astrojs/mdx": "workspace:*",
|
||||
"@astrojs/vue": "workspace:*",
|
||||
"astro": "workspace:*",
|
||||
"vue": "^3.4.38"
|
||||
"vue": "^3.5.3"
|
||||
}
|
||||
}
|
||||
|
|
33
packages/astro/e2e/server-islands-key.test.js
Normal file
33
packages/astro/e2e/server-islands-key.test.js
Normal file
|
@ -0,0 +1,33 @@
|
|||
import { expect } from '@playwright/test';
|
||||
import { testFactory } from './test-utils.js';
|
||||
|
||||
const test = testFactory(import.meta.url, { root: './fixtures/server-islands-key/' });
|
||||
|
||||
test.describe('Server islands - Key reuse', () => {
|
||||
test.describe('Production', () => {
|
||||
let previewServer;
|
||||
|
||||
test.beforeAll(async ({ astro }) => {
|
||||
// Playwright's Node version doesn't have these functions, so stub them.
|
||||
process.stdout.clearLine = () => {};
|
||||
process.stdout.cursorTo = () => {};
|
||||
process.env.ASTRO_KEY = 'eKBaVEuI7YjfanEXHuJe/pwZKKt3LkAHeMxvTU7aR0M=';
|
||||
await astro.build();
|
||||
previewServer = await astro.preview();
|
||||
});
|
||||
|
||||
test.afterAll(async () => {
|
||||
await previewServer.stop();
|
||||
delete process.env.ASTRO_KEY;
|
||||
});
|
||||
|
||||
test('Components render properly', async ({ page, astro }) => {
|
||||
await page.goto(astro.resolveUrl('/'));
|
||||
|
||||
let el = page.locator('#island');
|
||||
|
||||
await expect(el, 'element rendered').toBeVisible();
|
||||
await expect(el, 'should have content').toHaveText('I am an island');
|
||||
});
|
||||
});
|
||||
});
|
|
@ -14,6 +14,10 @@ const testFileToPort = new Map();
|
|||
for (let i = 0; i < testFiles.length; i++) {
|
||||
const file = testFiles[i];
|
||||
if (file.endsWith('.test.js')) {
|
||||
// Port 4045 is an unsafe port in Chrome, so skip it.
|
||||
if (4000 + i === 4045) {
|
||||
i++;
|
||||
}
|
||||
testFileToPort.set(file, 4000 + i);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -139,7 +139,7 @@
|
|||
"common-ancestor-path": "^1.0.1",
|
||||
"cookie": "^0.6.0",
|
||||
"cssesc": "^3.0.0",
|
||||
"debug": "^4.3.6",
|
||||
"debug": "^4.3.7",
|
||||
"deterministic-object-hash": "^2.0.2",
|
||||
"devalue": "^5.0.0",
|
||||
"diff": "^5.2.0",
|
||||
|
@ -170,14 +170,14 @@
|
|||
"prompts": "^2.4.2",
|
||||
"rehype": "^13.0.1",
|
||||
"semver": "^7.6.3",
|
||||
"shiki": "^1.16.1",
|
||||
"shiki": "^1.16.2",
|
||||
"string-width": "^7.2.0",
|
||||
"strip-ansi": "^7.1.0",
|
||||
"tinyexec": "^0.3.0",
|
||||
"tsconfck": "^3.1.3",
|
||||
"unist-util-visit": "^5.0.0",
|
||||
"vfile": "^6.0.3",
|
||||
"vite": "^5.4.2",
|
||||
"vite": "^5.4.3",
|
||||
"vitefu": "^1.0.2",
|
||||
"which-pm": "^3.0.0",
|
||||
"xxhash-wasm": "^1.0.2",
|
||||
|
@ -191,7 +191,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@astrojs/check": "^0.9.3",
|
||||
"@playwright/test": "^1.46.1",
|
||||
"@playwright/test": "^1.47.0",
|
||||
"@types/aria-query": "^5.0.4",
|
||||
"@types/common-ancestor-path": "^1.0.2",
|
||||
"@types/cssesc": "^3.0.2",
|
||||
|
@ -222,7 +222,7 @@
|
|||
"rehype-toc": "^3.0.2",
|
||||
"remark-code-titles": "^0.1.2",
|
||||
"rollup": "^4.21.2",
|
||||
"sass": "^1.77.8",
|
||||
"sass": "^1.78.0",
|
||||
"undici": "^6.19.8",
|
||||
"unified": "^11.0.5"
|
||||
},
|
||||
|
|
|
@ -92,7 +92,7 @@ function getFormServerHandler<TOutput, TInputSchema extends z.ZodType>(
|
|||
|
||||
if (!inputSchema) return await handler(unparsedInput, context);
|
||||
|
||||
const baseSchema = unwrapSchemaEffects(inputSchema);
|
||||
const baseSchema = unwrapBaseObjectSchema(inputSchema, unparsedInput);
|
||||
const parsed = await inputSchema.safeParseAsync(
|
||||
baseSchema instanceof z.ZodObject
|
||||
? formDataToObject(unparsedInput, baseSchema)
|
||||
|
@ -191,7 +191,7 @@ function handleFormDataGet(
|
|||
return validator instanceof z.ZodNumber ? Number(value) : value;
|
||||
}
|
||||
|
||||
function unwrapSchemaEffects(schema: z.ZodType) {
|
||||
function unwrapBaseObjectSchema(schema: z.ZodType, unparsedInput: FormData) {
|
||||
while (schema instanceof z.ZodEffects || schema instanceof z.ZodPipeline) {
|
||||
if (schema instanceof z.ZodEffects) {
|
||||
schema = schema._def.schema;
|
||||
|
@ -200,5 +200,15 @@ function unwrapSchemaEffects(schema: z.ZodType) {
|
|||
schema = schema._def.in;
|
||||
}
|
||||
}
|
||||
if (schema instanceof z.ZodDiscriminatedUnion) {
|
||||
const typeKey = schema._def.discriminator;
|
||||
const typeValue = unparsedInput.get(typeKey);
|
||||
if (typeof typeValue !== 'string') return schema;
|
||||
|
||||
const objSchema = schema._def.optionsMap.get(typeValue);
|
||||
if (!objSchema) return schema;
|
||||
|
||||
return objSchema;
|
||||
}
|
||||
return schema;
|
||||
}
|
||||
|
|
|
@ -98,11 +98,11 @@ export async function generateImagesForPath(
|
|||
env: AssetEnv,
|
||||
queue: PQueue,
|
||||
) {
|
||||
const originalImageData = await loadImage(originalFilePath, env);
|
||||
let originalImage: ImageData;
|
||||
|
||||
for (const [_, transform] of transformsAndPath.transforms) {
|
||||
await queue
|
||||
.add(async () => generateImage(originalImageData, transform.finalPath, transform.transform))
|
||||
.add(async () => generateImage(transform.finalPath, transform.transform))
|
||||
.catch((e) => {
|
||||
throw e;
|
||||
});
|
||||
|
@ -128,13 +128,9 @@ export async function generateImagesForPath(
|
|||
}
|
||||
}
|
||||
|
||||
async function generateImage(
|
||||
originalImage: ImageData,
|
||||
filepath: string,
|
||||
options: ImageTransform,
|
||||
) {
|
||||
async function generateImage(filepath: string, options: ImageTransform) {
|
||||
const timeStart = performance.now();
|
||||
const generationData = await generateImageInternal(originalImage, filepath, options);
|
||||
const generationData = await generateImageInternal(filepath, options);
|
||||
|
||||
const timeEnd = performance.now();
|
||||
const timeChange = getTimeStat(timeStart, timeEnd);
|
||||
|
@ -151,7 +147,6 @@ export async function generateImagesForPath(
|
|||
}
|
||||
|
||||
async function generateImageInternal(
|
||||
originalImage: ImageData,
|
||||
filepath: string,
|
||||
options: ImageTransform,
|
||||
): Promise<GenerationData> {
|
||||
|
@ -207,6 +202,10 @@ export async function generateImagesForPath(
|
|||
? (options.src as ImageMetadata).src
|
||||
: (options.src as string);
|
||||
|
||||
if (!originalImage) {
|
||||
originalImage = await loadImage(originalFilePath, env);
|
||||
}
|
||||
|
||||
let resultData: Partial<ImageData> = {
|
||||
data: undefined,
|
||||
expires: originalImage.expires,
|
||||
|
|
|
@ -279,7 +279,7 @@ export async function add(names: string[], { flags }: AddOptions) {
|
|||
if (isAdapter(integration)) {
|
||||
const officialExportName = OFFICIAL_ADAPTER_TO_IMPORT_MAP[integration.id];
|
||||
if (officialExportName) {
|
||||
setAdapter(mod, integration);
|
||||
setAdapter(mod, integration, officialExportName);
|
||||
} else {
|
||||
logger.info(
|
||||
'SKIP_FORMAT',
|
||||
|
@ -447,7 +447,11 @@ function addIntegration(mod: ProxifiedModule<any>, integration: IntegrationInfo)
|
|||
}
|
||||
}
|
||||
|
||||
export function setAdapter(mod: ProxifiedModule<any>, adapter: IntegrationInfo) {
|
||||
export function setAdapter(
|
||||
mod: ProxifiedModule<any>,
|
||||
adapter: IntegrationInfo,
|
||||
exportName: string,
|
||||
) {
|
||||
const config = getDefaultExportOptions(mod);
|
||||
const adapterId = toIdent(adapter.id);
|
||||
|
||||
|
@ -455,7 +459,7 @@ export function setAdapter(mod: ProxifiedModule<any>, adapter: IntegrationInfo)
|
|||
mod.imports.$append({
|
||||
imported: 'default',
|
||||
local: adapterId,
|
||||
from: adapter.packageName,
|
||||
from: exportName,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
33
packages/astro/src/cli/create-key/index.ts
Normal file
33
packages/astro/src/cli/create-key/index.ts
Normal file
|
@ -0,0 +1,33 @@
|
|||
import { createNodeLogger } from '../../core/config/logging.js';
|
||||
import { createKey as createCryptoKey, encodeKey } from '../../core/encryption.js';
|
||||
import { type Flags, flagsToAstroInlineConfig } from '../flags.js';
|
||||
|
||||
interface CreateKeyOptions {
|
||||
flags: Flags;
|
||||
}
|
||||
|
||||
export async function createKey({ flags }: CreateKeyOptions): Promise<0 | 1> {
|
||||
try {
|
||||
const inlineConfig = flagsToAstroInlineConfig(flags);
|
||||
const logger = createNodeLogger(inlineConfig);
|
||||
|
||||
const keyPromise = createCryptoKey();
|
||||
const key = await keyPromise;
|
||||
const encoded = await encodeKey(key);
|
||||
|
||||
logger.info(
|
||||
'crypto',
|
||||
`Generated a key to encrypt props passed to Server islands. To reuse the same key across builds, set this value as ASTRO_KEY in an environment variable on your build server.
|
||||
|
||||
ASTRO_KEY=${encoded}`,
|
||||
);
|
||||
} catch (err: unknown) {
|
||||
if (err != null) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(err.toString());
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -7,6 +7,7 @@ type CLICommand =
|
|||
| 'help'
|
||||
| 'version'
|
||||
| 'add'
|
||||
| 'create-key'
|
||||
| 'docs'
|
||||
| 'dev'
|
||||
| 'build'
|
||||
|
@ -30,6 +31,7 @@ async function printAstroHelp() {
|
|||
['add', 'Add an integration.'],
|
||||
['build', 'Build your project and write it to disk.'],
|
||||
['check', 'Check your project for errors.'],
|
||||
['create-key', 'Create a cryptography key'],
|
||||
['db', 'Manage your Astro database.'],
|
||||
['dev', 'Start the development server.'],
|
||||
['docs', 'Open documentation in your web browser.'],
|
||||
|
@ -78,6 +80,7 @@ function resolveCommand(flags: yargs.Arguments): CLICommand {
|
|||
'build',
|
||||
'preview',
|
||||
'check',
|
||||
'create-key',
|
||||
'docs',
|
||||
'db',
|
||||
'info',
|
||||
|
@ -111,6 +114,11 @@ async function runCommand(cmd: string, flags: yargs.Arguments) {
|
|||
await printInfo({ flags });
|
||||
return;
|
||||
}
|
||||
case 'create-key': {
|
||||
const { createKey } = await import('./create-key/index.js');
|
||||
const exitCode = await createKey({ flags });
|
||||
return process.exit(exitCode);
|
||||
}
|
||||
case 'docs': {
|
||||
const { docs } = await import('./docs/index.js');
|
||||
await docs({ flags });
|
||||
|
|
|
@ -18,7 +18,7 @@ import { resolveConfig } from '../config/config.js';
|
|||
import { createNodeLogger } from '../config/logging.js';
|
||||
import { createSettings } from '../config/settings.js';
|
||||
import { createVite } from '../create-vite.js';
|
||||
import { createKey } from '../encryption.js';
|
||||
import { createKey, getEnvironmentKey, hasEnvironmentKey } from '../encryption.js';
|
||||
import { AstroError, AstroErrorData } from '../errors/index.js';
|
||||
import type { Logger } from '../logger/core.js';
|
||||
import { levels, timerMessage } from '../logger/core.js';
|
||||
|
@ -193,6 +193,9 @@ class AstroBuilder {
|
|||
green(`✓ Completed in ${getTimeStat(this.timer.init, performance.now())}.`),
|
||||
);
|
||||
|
||||
const hasKey = hasEnvironmentKey();
|
||||
const keyPromise = hasKey ? getEnvironmentKey() : createKey();
|
||||
|
||||
const opts: StaticBuildOptions = {
|
||||
allPages,
|
||||
settings: this.settings,
|
||||
|
@ -203,7 +206,7 @@ class AstroBuilder {
|
|||
pageNames,
|
||||
teardownCompiler: this.teardownCompiler,
|
||||
viteConfig,
|
||||
key: createKey(),
|
||||
key: keyPromise,
|
||||
};
|
||||
|
||||
const { internals, ssrOutputChunkNames, contentFileNames } = await viteBuild(opts);
|
||||
|
|
|
@ -20,6 +20,37 @@ export async function createKey() {
|
|||
return key;
|
||||
}
|
||||
|
||||
// The environment variable name that can be used to provide the encrypted key.
|
||||
const ENVIRONMENT_KEY_NAME = 'ASTRO_KEY' as const;
|
||||
|
||||
/**
|
||||
* Get the encoded value of the ASTRO_KEY env var.
|
||||
*/
|
||||
export function getEncodedEnvironmentKey(): string {
|
||||
return process.env[ENVIRONMENT_KEY_NAME] || '';
|
||||
}
|
||||
|
||||
/**
|
||||
* See if the environment variable key ASTRO_KEY is set.
|
||||
*/
|
||||
export function hasEnvironmentKey(): boolean {
|
||||
return getEncodedEnvironmentKey() !== '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the environment variable key and decode it into a CryptoKey.
|
||||
*/
|
||||
export async function getEnvironmentKey(): Promise<CryptoKey> {
|
||||
// This should never happen, because we always check `hasEnvironmentKey` before this is called.
|
||||
if (!hasEnvironmentKey()) {
|
||||
throw new Error(
|
||||
`There is no environment key defined. If you see this error there is a bug in Astro.`,
|
||||
);
|
||||
}
|
||||
const encodedKey = getEncodedEnvironmentKey();
|
||||
return decodeKey(encodedKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a key that has been serialized to an array of bytes and returns a CryptoKey
|
||||
*/
|
||||
|
|
|
@ -18,6 +18,7 @@ export type LoggerLabel =
|
|||
| 'check'
|
||||
| 'config'
|
||||
| 'content'
|
||||
| 'crypto'
|
||||
| 'deprecated'
|
||||
| 'markdown'
|
||||
| 'router'
|
||||
|
@ -27,6 +28,7 @@ export type LoggerLabel =
|
|||
| 'middleware'
|
||||
| 'preferences'
|
||||
| 'redirects'
|
||||
| 'sync'
|
||||
| 'toolbar'
|
||||
| 'assets'
|
||||
| 'env'
|
||||
|
|
|
@ -66,7 +66,19 @@ export default async function sync(
|
|||
logger,
|
||||
});
|
||||
const manifest = await createRouteManifest({ settings, fsMod: fs }, logger);
|
||||
await runHookConfigDone({ settings, logger, command: 'sync' });
|
||||
|
||||
// Run `astro:config:done`
|
||||
// Actions will throw if there is misconfiguration, so catch here.
|
||||
try {
|
||||
await runHookConfigDone({ settings, logger });
|
||||
} catch (err) {
|
||||
if (err instanceof Error) {
|
||||
const errorMessage = err.toString();
|
||||
logger.error('sync', errorMessage);
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
|
||||
return await syncInternal({ settings, logger, fs, force: inlineConfig.force, manifest });
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,8 @@ interface ImportedStyle {
|
|||
content: string;
|
||||
}
|
||||
|
||||
const inlineQueryRE = /(?:\?|&)inline(?:$|&)/;
|
||||
|
||||
/** Given a filePath URL, crawl Vite’s module graph to find all style imports. */
|
||||
export async function getStylesForURL(
|
||||
filePath: URL,
|
||||
|
@ -32,21 +34,20 @@ export async function getStylesForURL(
|
|||
}
|
||||
// Else try to load it
|
||||
else {
|
||||
const url = new URL(importedModule.url, 'http://localhost');
|
||||
let modId = importedModule.url;
|
||||
// Mark url with ?inline so Vite will return the CSS as plain string, even for CSS modules
|
||||
url.searchParams.set('inline', '');
|
||||
const modId = `${decodeURI(url.pathname)}${url.search}`;
|
||||
|
||||
if (!inlineQueryRE.test(importedModule.url)) {
|
||||
if (importedModule.url.includes('?')) {
|
||||
modId = importedModule.url.replace('?', '?inline&');
|
||||
} else {
|
||||
modId += '?inline';
|
||||
}
|
||||
}
|
||||
try {
|
||||
// The SSR module is possibly not loaded. Load it if it's null.
|
||||
const ssrModule = await loader.import(modId);
|
||||
css = ssrModule.default;
|
||||
} catch {
|
||||
// Some CSS modules, e.g. from Vue files, may not work with the ?inline query.
|
||||
// If so, we fallback to a url instead
|
||||
if (modId.includes('.module.')) {
|
||||
importedCssUrls.add(importedModule.url);
|
||||
}
|
||||
// The module may not be inline-able, e.g. SCSS partials. Skip it as it may already
|
||||
// be inlined into other modules if it happens to be in the graph.
|
||||
continue;
|
||||
|
|
|
@ -225,7 +225,7 @@ describe('CSS', function () {
|
|||
it('<style module>', async () => {
|
||||
const el = $('#vue-modules');
|
||||
const classes = el.attr('class').split(' ');
|
||||
const moduleClass = classes.find((name) => /^_title_[\w-]+/.test(name));
|
||||
const moduleClass = classes.find((name) => /^_vueModules_[\w-]+/.test(name));
|
||||
|
||||
// 1. check HTML
|
||||
assert.equal(el.attr('class').includes(moduleClass), true);
|
||||
|
@ -405,18 +405,13 @@ describe('CSS', function () {
|
|||
});
|
||||
|
||||
it('resolves CSS from Vue', async () => {
|
||||
const styles = ['VueModules.vue?vue&type=style&index=0&lang.module.scss'];
|
||||
for (const style of styles) {
|
||||
const href = $(`link[href$="${style}"]`).attr('href');
|
||||
assert.equal((await fixture.fetch(href)).status, 200, style);
|
||||
}
|
||||
|
||||
const allInjectedStyles = $('style').text().replace(/\s*/g, '');
|
||||
|
||||
assert.equal(allInjectedStyles.includes('.vue-css{'), true);
|
||||
assert.equal(allInjectedStyles.includes('.vue-sass{'), true);
|
||||
assert.equal(allInjectedStyles.includes('.vue-scss{'), true);
|
||||
assert.equal(allInjectedStyles.includes('.vue-scoped[data-v-'), true);
|
||||
assert.equal(allInjectedStyles.includes('._vueModules_'), true);
|
||||
});
|
||||
|
||||
it('remove unused styles from client:load components', async () => {
|
||||
|
|
|
@ -395,6 +395,39 @@ describe('Astro Actions', () => {
|
|||
assert.ok(value.date instanceof Date);
|
||||
assert.ok(value.set instanceof Set);
|
||||
});
|
||||
|
||||
it('Supports discriminated union for different form fields', async () => {
|
||||
const formData = new FormData();
|
||||
formData.set('type', 'first-chunk');
|
||||
formData.set('alt', 'Cool image');
|
||||
formData.set('image', new File([''], 'chunk-1.png'));
|
||||
const reqFirst = new Request('http://example.com/_actions/imageUploadInChunks', {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
});
|
||||
|
||||
const resFirst = await app.render(reqFirst);
|
||||
assert.equal(resFirst.status, 200);
|
||||
assert.equal(resFirst.headers.get('Content-Type'), 'application/json+devalue');
|
||||
const data = devalue.parse(await resFirst.text());
|
||||
const uploadId = data?.uploadId;
|
||||
assert.ok(uploadId);
|
||||
|
||||
const formDataRest = new FormData();
|
||||
formDataRest.set('type', 'rest-chunk');
|
||||
formDataRest.set('uploadId', 'fake');
|
||||
formDataRest.set('image', new File([''], 'chunk-2.png'));
|
||||
const reqRest = new Request('http://example.com/_actions/imageUploadInChunks', {
|
||||
method: 'POST',
|
||||
body: formDataRest,
|
||||
});
|
||||
|
||||
const resRest = await app.render(reqRest);
|
||||
assert.equal(resRest.status, 200);
|
||||
assert.equal(resRest.headers.get('Content-Type'), 'application/json+devalue');
|
||||
const dataRest = devalue.parse(await resRest.text());
|
||||
assert.equal('fake', dataRest?.uploadId);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -10,6 +10,6 @@
|
|||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"svelte": "^4.2.19",
|
||||
"vue": "^3.4.38"
|
||||
"vue": "^3.5.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<style module lang="scss">
|
||||
$type: cursive;
|
||||
.title {
|
||||
.vueModules {
|
||||
font-family: $type;
|
||||
}
|
||||
</style>
|
||||
|
||||
<template>
|
||||
<h1 id="vue-modules" :class="$style.title">Vue CSS Modules</h1>
|
||||
<h1 id="vue-modules" :class="$style.vueModules">Vue CSS Modules</h1>
|
||||
</template>
|
||||
|
|
|
@ -7,6 +7,29 @@ const passwordSchema = z
|
|||
.max(128, 'Password length exceeded. Max 128 chars.');
|
||||
|
||||
export const server = {
|
||||
imageUploadInChunks: defineAction({
|
||||
accept: 'form',
|
||||
input: z.discriminatedUnion('type', [
|
||||
z.object({
|
||||
type: z.literal('first-chunk'),
|
||||
image: z.instanceof(File),
|
||||
alt: z.string(),
|
||||
}),
|
||||
z.object({ type: z.literal('rest-chunk'), image: z.instanceof(File), uploadId: z.string() }),
|
||||
]),
|
||||
handler: async (data) => {
|
||||
if (data.type === 'first-chunk') {
|
||||
const uploadId = Math.random().toString(36).slice(2);
|
||||
return {
|
||||
uploadId,
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
uploadId: data.uploadId,
|
||||
};
|
||||
}
|
||||
},
|
||||
}),
|
||||
subscribe: defineAction({
|
||||
input: z.object({ channel: z.string() }),
|
||||
handler: async ({ channel }) => {
|
||||
|
|
|
@ -9,6 +9,6 @@
|
|||
"astro": "workspace:*",
|
||||
"preact": "^10.23.2",
|
||||
"svelte": "^4.2.19",
|
||||
"vue": "^3.4.38"
|
||||
"vue": "^3.5.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,6 @@
|
|||
"dependencies": {
|
||||
"@astrojs/vue": "workspace:*",
|
||||
"astro": "workspace:*",
|
||||
"vue": "^3.4.38"
|
||||
"vue": "^3.5.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,6 @@
|
|||
"react-dom": "^18.3.1",
|
||||
"solid-js": "^1.8.22",
|
||||
"svelte": "^4.2.19",
|
||||
"vue": "^3.4.38"
|
||||
"vue": "^3.5.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,6 @@
|
|||
"astro": "workspace:*",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"vue": "^3.4.38"
|
||||
"vue": "^3.5.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,6 @@
|
|||
"astro": "workspace:*",
|
||||
"preact": "^10.23.2",
|
||||
"svelte": "^4.2.19",
|
||||
"vue": "^3.4.38"
|
||||
"vue": "^3.5.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@fontsource/monofett": "5.0.21",
|
||||
"@fontsource/montserrat": "5.0.19",
|
||||
"@fontsource/monofett": "5.0.22",
|
||||
"@fontsource/montserrat": "5.0.20",
|
||||
"astro": "workspace:*"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,6 @@
|
|||
"react-dom": "^18.3.1",
|
||||
"solid-js": "^1.8.22",
|
||||
"svelte": "^4.2.19",
|
||||
"vue": "^3.4.38"
|
||||
"vue": "^3.5.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,10 +8,10 @@
|
|||
"@astrojs/vue": "workspace:*",
|
||||
"astro": "workspace:*",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"postcss": "^8.4.43",
|
||||
"postcss": "^8.4.45",
|
||||
"solid-js": "^1.8.22",
|
||||
"svelte": "^4.2.19",
|
||||
"vue": "^3.4.38"
|
||||
"vue": "^3.5.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"postcss-preset-env": "^10.0.2"
|
||||
|
|
7
packages/astro/test/fixtures/preact-component/src/components/ComponentWithNullProp.jsx
vendored
Normal file
7
packages/astro/test/fixtures/preact-component/src/components/ComponentWithNullProp.jsx
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
import { h } from 'preact';
|
||||
|
||||
export default ({ nullProp }) => {
|
||||
return <div id="preact-component-with-null-prop">
|
||||
<p>I have a null prop: {nullProp}</p>
|
||||
</div>
|
||||
}
|
|
@ -3,6 +3,7 @@ import { signal } from '@preact/signals';
|
|||
import Signals from '../components/Signals';
|
||||
import SignalsInArray from '../components/SignalsInArray';
|
||||
import SignalsInObject from '../components/SignalsInObject';
|
||||
import ComponentWithNullProp from '../components/ComponentWithNullProp';
|
||||
const count = signal(1);
|
||||
const secondCount = signal(2);
|
||||
---
|
||||
|
@ -14,6 +15,7 @@ const secondCount = signal(2);
|
|||
<Signals client:load count={count} />
|
||||
<Signals client:load count={count} />
|
||||
<SignalsInArray client:load signalsArray={["I'm not a signal", count, count, 12345, secondCount]} />
|
||||
<SignalsInObject client:load signalsObject={{title:'I am a title', counter: count}} />
|
||||
<SignalsInObject client:load signalsObject={{title:'I am a title', counter: count}}, />
|
||||
<ComponentWithNullProp client:load nullProp={null} />
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import svelte from '@astrojs/svelte';
|
||||
import { defineConfig } from 'astro/config';
|
||||
import testAdapter from '../../../test-adapter.js';
|
||||
|
||||
export default defineConfig({
|
||||
adapter: testAdapter(),
|
||||
output: 'server',
|
||||
integrations: [
|
||||
svelte()
|
||||
|
|
|
@ -6,6 +6,6 @@
|
|||
"@astrojs/mdx": "workspace:*",
|
||||
"@astrojs/vue": "workspace:*",
|
||||
"astro": "workspace:*",
|
||||
"vue": "^3.4.38"
|
||||
"vue": "^3.5.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"dependencies": {
|
||||
"@astrojs/tailwind": "workspace:*",
|
||||
"astro": "workspace:*",
|
||||
"postcss": "^8.4.43",
|
||||
"postcss": "^8.4.45",
|
||||
"tailwindcss": "^3.4.10"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
"@astrojs/tailwind": "workspace:*",
|
||||
"astro": "workspace:*",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"postcss": "^8.4.43",
|
||||
"postcss": "^8.4.45",
|
||||
"tailwindcss": "^3.4.10"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,6 @@
|
|||
"dependencies": {
|
||||
"@astrojs/vue": "workspace:*",
|
||||
"astro": "workspace:*",
|
||||
"vue": "^3.4.38"
|
||||
"vue": "^3.5.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,6 @@
|
|||
"dependencies": {
|
||||
"@astrojs/vue": "workspace:*",
|
||||
"astro": "workspace:*",
|
||||
"vue": "^3.4.38"
|
||||
"vue": "^3.5.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,6 @@
|
|||
"@astrojs/vue": "workspace:*",
|
||||
"astro": "workspace:*",
|
||||
"svelte": "^4.2.19",
|
||||
"vue": "^3.4.38"
|
||||
"vue": "^3.5.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -140,4 +140,11 @@ describe('Preact component', () => {
|
|||
assert.equal(element.find('h1').text(), 'I am a title');
|
||||
assert.equal(element.find('p').text(), '1');
|
||||
});
|
||||
|
||||
it('Can use null props', async () => {
|
||||
const html = await fixture.readFile('/signals/index.html');
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
assert.equal($('#preact-component-with-null-prop').length, 1);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
# create-astro
|
||||
|
||||
## 4.9.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [#11924](https://github.com/withastro/astro/pull/11924) [`7d70ba3`](https://github.com/withastro/astro/commit/7d70ba317889b9281c7891038779a68fcb8f0778) Thanks [@florian-lefebvre](https://github.com/florian-lefebvre)! - Updates the default Astro config with `// @ts-check` if the Typescript preset is `strict` or `strictest`
|
||||
|
||||
## 4.8.4
|
||||
|
||||
### Patch Changes
|
||||
|
|
|
@ -140,6 +140,21 @@ const FILES_TO_UPDATE = {
|
|||
}
|
||||
}
|
||||
},
|
||||
'astro.config.mjs': async (file: string, options: { value: string }) => {
|
||||
if (!(options.value === 'strict' || options.value === 'strictest')) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
let data = await readFile(file, { encoding: 'utf-8' });
|
||||
data = `// @ts-check\n${data}`;
|
||||
await writeFile(file, data, { encoding: 'utf-8' });
|
||||
} catch (err) {
|
||||
// if there's no astro.config.mjs (which is very unlikely), then do nothing
|
||||
if (err && (err as any).code === 'ENOENT') return;
|
||||
if (err instanceof Error) throw new Error(err.message);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export async function setupTypeScript(value: string, ctx: PickedTypeScriptContext) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# @astrojs/db
|
||||
|
||||
## 0.13.2-alpha.1
|
||||
## 0.14.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
|
|
|
@ -92,6 +92,6 @@
|
|||
"astro-scripts": "workspace:*",
|
||||
"cheerio": "1.0.0",
|
||||
"typescript": "^5.5.4",
|
||||
"vite": "^5.4.2"
|
||||
"vite": "^5.4.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,10 +38,10 @@
|
|||
"alpinejs": "^3.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@playwright/test": "1.46.1",
|
||||
"@playwright/test": "1.47.0",
|
||||
"astro": "workspace:*",
|
||||
"astro-scripts": "workspace:*",
|
||||
"vite": "^5.4.2"
|
||||
"vite": "^5.4.3"
|
||||
},
|
||||
"publishConfig": {
|
||||
"provenance": true
|
||||
|
|
|
@ -80,7 +80,7 @@
|
|||
"astro-scripts": "workspace:*",
|
||||
"devalue": "^5.0.0",
|
||||
"linkedom": "^0.18.4",
|
||||
"vite": "^5.4.2"
|
||||
"vite": "^5.4.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.17.1 || ^20.3.0 || >=21.0.0"
|
||||
|
|
|
@ -69,9 +69,9 @@
|
|||
"remark-rehype": "^11.1.0",
|
||||
"remark-shiki-twoslash": "^3.1.3",
|
||||
"remark-toc": "^9.0.0",
|
||||
"shiki": "^1.16.1",
|
||||
"shiki": "^1.16.2",
|
||||
"unified": "^11.0.5",
|
||||
"vite": "^5.4.2"
|
||||
"vite": "^5.4.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.17.1 || ^20.3.0 || >=21.0.0"
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
# @astrojs/preact
|
||||
|
||||
## 3.5.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [#11930](https://github.com/withastro/astro/pull/11930) [`4a44e82`](https://github.com/withastro/astro/commit/4a44e82bbdf0572190618d8c5882c63a6525a198) Thanks [@lukasbachlechner](https://github.com/lukasbachlechner)! - Preact components no longer throw an error if a property is null.
|
||||
|
||||
## 3.5.2
|
||||
|
||||
### Patch Changes
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "@astrojs/preact",
|
||||
"description": "Use Preact components within Astro",
|
||||
"version": "3.5.2",
|
||||
"version": "3.5.3",
|
||||
"type": "module",
|
||||
"types": "./dist/index.d.ts",
|
||||
"author": "withastro",
|
||||
|
|
|
@ -38,7 +38,9 @@ export function serializeSignals(
|
|||
const signals: Signals = {};
|
||||
for (const [key, value] of Object.entries(props)) {
|
||||
const isPropArray = Array.isArray(value);
|
||||
const isPropObject = !isSignal(value) && typeof props[key] === 'object' && !isPropArray;
|
||||
// `typeof null` is 'object' in JS, so we need to check for `null` specifically
|
||||
const isPropObject =
|
||||
!isSignal(value) && typeof props[key] === 'object' && props[key] !== null && !isPropArray;
|
||||
|
||||
if (isPropObject || isPropArray) {
|
||||
const values = isPropObject ? Object.keys(props[key]) : value;
|
||||
|
|
|
@ -66,7 +66,7 @@
|
|||
"cheerio": "1.0.0",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"vite": "^5.4.2"
|
||||
"vite": "^5.4.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "^17.0.50 || ^18.0.21",
|
||||
|
|
|
@ -8,6 +8,6 @@
|
|||
"astro": "workspace:*",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"vue": "^3.4.38"
|
||||
"vue": "^3.5.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
"astro": "workspace:*",
|
||||
"astro-scripts": "workspace:*",
|
||||
"solid-js": "^1.8.22",
|
||||
"vite": "^5.4.2"
|
||||
"vite": "^5.4.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"solid-devtools": "^0.30.1",
|
||||
|
|
|
@ -51,13 +51,13 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@sveltejs/vite-plugin-svelte": "^3.1.2",
|
||||
"svelte2tsx": "^0.7.16"
|
||||
"svelte2tsx": "^0.7.18"
|
||||
},
|
||||
"devDependencies": {
|
||||
"astro": "workspace:*",
|
||||
"astro-scripts": "workspace:*",
|
||||
"svelte": "^4.2.19",
|
||||
"vite": "^5.4.2"
|
||||
"vite": "^5.4.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"astro": "^5.0.0-alpha.0",
|
||||
|
|
|
@ -34,14 +34,14 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"autoprefixer": "^10.4.20",
|
||||
"postcss": "^8.4.43",
|
||||
"postcss": "^8.4.45",
|
||||
"postcss-load-config": "^4.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"astro": "workspace:*",
|
||||
"astro-scripts": "workspace:*",
|
||||
"tailwindcss": "^3.4.10",
|
||||
"vite": "^5.4.2"
|
||||
"vite": "^5.4.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"astro": "^5.0.0-alpha.0",
|
||||
|
|
|
@ -46,16 +46,16 @@
|
|||
"dependencies": {
|
||||
"@vitejs/plugin-vue": "^5.1.3",
|
||||
"@vitejs/plugin-vue-jsx": "^4.0.1",
|
||||
"@vue/compiler-sfc": "^3.4.38",
|
||||
"vite-plugin-vue-devtools": "^7.3.9"
|
||||
"@vue/compiler-sfc": "^3.5.3",
|
||||
"vite-plugin-vue-devtools": "^7.4.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"astro": "workspace:*",
|
||||
"astro-scripts": "workspace:*",
|
||||
"cheerio": "1.0.0",
|
||||
"linkedom": "^0.18.4",
|
||||
"vite": "^5.4.2",
|
||||
"vue": "^3.4.38"
|
||||
"vite": "^5.4.3",
|
||||
"vue": "^3.5.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"astro": "^5.0.0-alpha.0",
|
||||
|
|
|
@ -6,6 +6,6 @@
|
|||
"@astrojs/vue": "workspace:*",
|
||||
"astro": "workspace:*",
|
||||
"vite-svg-loader": "5.1.0",
|
||||
"vue": "^3.4.38"
|
||||
"vue": "^3.5.3"
|
||||
}
|
||||
}
|
|
@ -9,6 +9,6 @@
|
|||
"@astrojs/vue": "workspace:*",
|
||||
"astro": "workspace:*",
|
||||
"vite-svg-loader": "5.1.0",
|
||||
"vue": "^3.4.38"
|
||||
"vue": "^3.5.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,6 @@
|
|||
"@astrojs/vue": "workspace:*",
|
||||
"astro": "workspace:*",
|
||||
"vite-svg-loader": "5.1.0",
|
||||
"vue": "^3.4.38"
|
||||
"vue": "^3.5.3"
|
||||
}
|
||||
}
|
|
@ -44,7 +44,7 @@
|
|||
"remark-parse": "^11.0.0",
|
||||
"remark-rehype": "^11.1.0",
|
||||
"remark-smartypants": "^3.0.2",
|
||||
"shiki": "^1.16.1",
|
||||
"shiki": "^1.16.2",
|
||||
"unified": "^11.0.5",
|
||||
"unist-util-remove-position": "^5.0.0",
|
||||
"unist-util-visit": "^5.0.0",
|
||||
|
|
|
@ -42,6 +42,6 @@
|
|||
"astro": "workspace:*",
|
||||
"astro-scripts": "workspace:*",
|
||||
"typescript": "^5.5.4",
|
||||
"vite": "^5.4.2"
|
||||
"vite": "^5.4.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
],
|
||||
"dependencies": {
|
||||
"ci-info": "^4.0.0",
|
||||
"debug": "^4.3.6",
|
||||
"debug": "^4.3.7",
|
||||
"dlv": "^1.1.3",
|
||||
"dset": "^3.1.3",
|
||||
"is-docker": "^3.0.0",
|
||||
|
|
1515
pnpm-lock.yaml
1515
pnpm-lock.yaml
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue