Skip to content

Commit

Permalink
fix: regression or integration execution ordering
Browse files Browse the repository at this point in the history
Signed-off-by: Andres Correa Casablanca <andreu@kindspells.dev>
  • Loading branch information
castarco committed Nov 2, 2024
1 parent adf105b commit bdafbd4
Show file tree
Hide file tree
Showing 12 changed files with 678 additions and 1,125 deletions.
12 changes: 6 additions & 6 deletions @kindspells/astro-shield/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,15 @@
"astro": "^4.0.0"
},
"devDependencies": {
"@types/node": "^22.7.4",
"astro": "^4.15.11",
"@types/node": "^22.8.6",
"astro": "^4.16.8",
"get-tsconfig": "^4.8.1",
"rollup": "^4.24.0",
"rollup": "^4.24.3",
"rollup-plugin-dts": "^6.1.1",
"rollup-plugin-esbuild": "^6.1.1",
"typescript": "^5.6.2",
"vite": "^5.4.8",
"vitest": "^2.1.2"
"typescript": "^5.6.3",
"vite": "^5.4.10",
"vitest": "^2.1.4"
},
"repository": {
"type": "git",
Expand Down
26 changes: 16 additions & 10 deletions @kindspells/astro-shield/src/core.mts
Original file line number Diff line number Diff line change
Expand Up @@ -996,7 +996,7 @@ export const getViteMiddlewarePlugin = (
}
}

const getAstroBuildDone = (
export const getAstroBuildDone = (
state: IntegrationState,
sri: Required<SRIOptions>,
securityHeaders: SecurityHeadersOptions | undefined,
Expand Down Expand Up @@ -1042,15 +1042,21 @@ export const getAstroConfigSetup = (
})
}

updateConfig({
integrations: [
{
name: '@kindspells/astro-shield-post-config-setup',
hooks: {
'astro:build:done': getAstroBuildDone(state, sri, securityHeaders),
if (state.delayTransform) {
updateConfig({
integrations: [
{
name: '@kindspells/astro-shield-post-config-setup',
hooks: {
'astro:build:done': getAstroBuildDone(
state,
sri,
securityHeaders,
),
},
},
},
],
})
],
})
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"license": "MIT",
"dependencies": {
"@astrojs/node": "^8.3.4",
"astro": "^4.15.11"
"astro": "^4.16.8"
},
"devDependencies": {
"@kindspells/astro-shield": "workspace:*"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"license": "MIT",
"dependencies": {
"@astrojs/node": "^8.3.4",
"astro": "^4.15.11"
"astro": "^4.16.8"
},
"devDependencies": {
"@kindspells/astro-shield": "workspace:*"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"license": "MIT",
"dependencies": {
"@astrojs/node": "^8.3.4",
"astro": "^4.15.11"
"astro": "^4.16.8"
},
"devDependencies": {
"@kindspells/astro-shield": "workspace:*"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"license": "MIT",
"dependencies": {
"@astrojs/node": "^8.3.4",
"astro": "^4.15.11"
"astro": "^4.16.8"
},
"devDependencies": {
"@kindspells/astro-shield": "workspace:*"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
},
"license": "MIT",
"dependencies": {
"astro": "^4.15.11"
"astro": "^4.16.8"
},
"devDependencies": {
"@kindspells/astro-shield": "workspace:*"
Expand Down
18 changes: 15 additions & 3 deletions @kindspells/astro-shield/src/main.mts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import type { AstroIntegration } from 'astro'

import { getAstroConfigSetup } from '#as/core'
import { getAstroBuildDone, getAstroConfigSetup } from '#as/core'
import type { IntegrationState, ShieldOptions, SRIOptions } from './types.mts'

const logWarn = (msg: string): void =>
Expand All @@ -15,10 +15,10 @@ const logWarn = (msg: string): void =>
// Integration
// -----------------------------------------------------------------------------
export const shield = ({
delayTransform,
securityHeaders,
sri,
}: ShieldOptions): AstroIntegration => {
// We need to merge the deprecated options into the new object
const _sri = {
enableMiddleware: sri?.enableMiddleware ?? false,
enableStatic: sri?.enableStatic ?? true,
Expand All @@ -35,12 +35,24 @@ export const shield = ({
logWarn('`sri.hashesModule` is ignored when `sri.enableStatic` is `false`')
}

const state: IntegrationState = { config: {} }
const _delayTransform =
delayTransform ??
securityHeaders?.enableOnStaticPages?.provider === 'vercel'

const state: IntegrationState = {
delayTransform: _delayTransform,
config: {},
}

return {
name: '@kindspells/astro-shield',
hooks: {
'astro:config:setup': getAstroConfigSetup(state, _sri, securityHeaders),
...(_delayTransform
? undefined
: {
'astro:build:done': getAstroBuildDone(state, _sri, securityHeaders),
}),
},
} satisfies AstroIntegration
}
Expand Down
37 changes: 29 additions & 8 deletions @kindspells/astro-shield/src/tests/main.test.mts
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,33 @@ import { describe, expect, it } from 'vitest'
import defaultIntegrationExport, { shield } from '../main.mts'

describe('sriCSP', () => {
it('is exported as default', () => {
expect(defaultIntegrationExport).toBe(shield)
expect(shield).toBeInstanceOf(Function)
})
const defaultIntegrationKeys = [
'astro:build:done',
'astro:config:setup',
] as Readonly<['astro:build:done', 'astro:config:setup']>

const checkIntegration = (
integration: AstroIntegration,
keys: (keyof AstroIntegration['hooks'])[] = ['astro:config:setup'] as const,
keys: Readonly<
(keyof AstroIntegration['hooks'])[]
> = defaultIntegrationKeys,
) => {
expect(Object.keys(integration).sort()).toEqual(['hooks', 'name'])
expect(integration.name).toBe('@kindspells/astro-shield')

const sortedKeys = keys.sort()
const sortedKeys = keys.slice().sort() // TODO: use toSorted when widely available
expect(Object.keys(integration.hooks).sort()).toEqual(sortedKeys)
for (const key of sortedKeys) {
expect(integration.hooks[key]).toBeTruthy()
expect(integration.hooks[key]).toBeInstanceOf(Function)
}
}

it('is exported as default', () => {
expect(defaultIntegrationExport).toBe(shield)
expect(shield).toBeInstanceOf(Function)
})

it('returns a valid AstroIntegration object for default config', () => {
const integration = shield({})
checkIntegration(integration)
Expand All @@ -44,12 +51,12 @@ describe('sriCSP', () => {
const integration = shield({ sri: { enableStatic: false } })

// NOTE: it is too much work to verify that those hooks will do nothing
checkIntegration(integration, ['astro:config:setup'])
checkIntegration(integration, defaultIntegrationKeys)
})

it('returns hooks for static & dynamic content when we enable middleware', () => {
const integration = shield({ sri: { enableMiddleware: true } })
checkIntegration(integration, ['astro:config:setup'])
checkIntegration(integration, defaultIntegrationKeys)
})

it('returns hooks only for dynamic content when we enable middleware and disable static sri', () => {
Expand All @@ -59,6 +66,20 @@ describe('sriCSP', () => {
enableMiddleware: true,
},
})
checkIntegration(integration, defaultIntegrationKeys)
})

it('removes build:done from base config when delayTransform=true', () => {
const integration = shield({
delayTransform: true,
})
checkIntegration(integration, ['astro:config:setup'])
})

it('keeps build:done in base config when delayTransform=false', () => {
const integration = shield({
delayTransform: false,
})
checkIntegration(integration, ['astro:build:done', 'astro:config:setup'])
})
})
19 changes: 18 additions & 1 deletion @kindspells/astro-shield/src/types.mts
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,20 @@ export type SecurityHeadersOptions = {
}

export type ShieldOptions = {
/**
* When set to `true`, the transformation of static pages will be delayed to
* be executed as late as possible in the build process. This might be
* necessary in case you are using many integrations that transform the HTML
* output.
*
* If not set and any of the following conditions are met, then this option
* will be automatically set to `true`:
* - securityHeaders.enableOnStaticPages is set to `{ provider: 'vercel' }`
*
* Defaults to `false`.
*/
delayTransform?: boolean

/**
* Options related to Subresource Integrity (SRI).
*/
Expand Down Expand Up @@ -176,4 +190,7 @@ export type HashesCollection = {
perResourceSriHashes: MiddlewareHashes
}

export type IntegrationState = { config: Partial<AstroConfig> }
export type IntegrationState = {
delayTransform: boolean
config: Partial<AstroConfig>
}
10 changes: 5 additions & 5 deletions docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@
"dependencies": {
"astro-sst": "^2.43.5",
"sharp": "0.33.5",
"sst": "^3.1.67"
"sst": "^3.2.73"
},
"devDependencies": {
"@astrojs/check": "^0.9.4",
"@astrojs/starlight": "^0.28.2",
"@astrojs/ts-plugin": "^1.10.2",
"@astrojs/starlight": "^0.28.5",
"@astrojs/ts-plugin": "^1.10.4",
"@kindspells/astro-shield": "workspace:^",
"astro": "^4.15.11",
"typescript": "^5.6.2"
"astro": "^4.16.8",
"typescript": "^5.6.3"
}
}
Loading

0 comments on commit bdafbd4

Please sign in to comment.