add experimental integrations flag (#2894)
This commit is contained in:
parent
068e3b4dee
commit
9d6e0b5dba
4 changed files with 37 additions and 15 deletions
5
.changeset/hip-vans-return.md
Normal file
5
.changeset/hip-vans-return.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
'astro': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Add the "--experimental-integrations" flag to enable 3rd-party integrations.
|
|
@ -34,6 +34,7 @@ export interface CLIFlags {
|
||||||
/** @deprecated */
|
/** @deprecated */
|
||||||
experimentalStaticBuild?: boolean;
|
experimentalStaticBuild?: boolean;
|
||||||
experimentalSsr?: boolean;
|
experimentalSsr?: boolean;
|
||||||
|
experimentalIntegrations?: boolean;
|
||||||
legacyBuild?: boolean;
|
legacyBuild?: boolean;
|
||||||
drafts?: boolean;
|
drafts?: boolean;
|
||||||
}
|
}
|
||||||
|
@ -417,6 +418,12 @@ export interface AstroUserConfig {
|
||||||
trailingSlash?: 'always' | 'never' | 'ignore';
|
trailingSlash?: 'always' | 'never' | 'ignore';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable experimental support for 3rd-party integrations.
|
||||||
|
* Default: false
|
||||||
|
*/
|
||||||
|
experimentalIntegrations?: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @docs
|
* @docs
|
||||||
* @name vite
|
* @name vite
|
||||||
|
|
|
@ -73,14 +73,7 @@ export const AstroConfigSchema = z.object({
|
||||||
// preprocess
|
// preprocess
|
||||||
(val) => (Array.isArray(val) ? val.flat(Infinity).filter(Boolean) : val),
|
(val) => (Array.isArray(val) ? val.flat(Infinity).filter(Boolean) : val),
|
||||||
// validate
|
// validate
|
||||||
z
|
z.array(z.object({ name: z.string(), hooks: z.object({}).passthrough().default({}) })).default([])
|
||||||
.array(z.object({ name: z.string(), hooks: z.object({}).passthrough().default({}) }))
|
|
||||||
.default([])
|
|
||||||
// validate: first-party integrations only
|
|
||||||
// TODO: Add `To use 3rd-party integrations or to create your own, use the --experimental-integrations flag.`,
|
|
||||||
.refine((arr) => arr.every((integration) => integration.name.startsWith('@astrojs/')), {
|
|
||||||
message: `Astro integrations are still experimental, and only official integrations are currently supported`,
|
|
||||||
})
|
|
||||||
),
|
),
|
||||||
adapter: z.object({ name: z.string(), hooks: z.object({}).passthrough().default({}) }).optional(),
|
adapter: z.object({ name: z.string(), hooks: z.object({}).passthrough().default({}) }).optional(),
|
||||||
styleOptions: z
|
styleOptions: z
|
||||||
|
@ -133,6 +126,7 @@ export const AstroConfigSchema = z.object({
|
||||||
})
|
})
|
||||||
.optional()
|
.optional()
|
||||||
.default({}),
|
.default({}),
|
||||||
|
experimentalIntegrations: z.boolean().optional().default(false),
|
||||||
vite: z.any().optional().default({}), // TODO: we don’t need validation, but can we get better type inference?
|
vite: z.any().optional().default({}), // TODO: we don’t need validation, but can we get better type inference?
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -209,10 +203,24 @@ export async function validateConfig(userConfig: any, root: string): Promise<Ast
|
||||||
.optional()
|
.optional()
|
||||||
.default({}),
|
.default({}),
|
||||||
});
|
});
|
||||||
return {
|
// First-Pass Validation
|
||||||
|
const result = {
|
||||||
...(await AstroConfigRelativeSchema.parseAsync(userConfig)),
|
...(await AstroConfigRelativeSchema.parseAsync(userConfig)),
|
||||||
_ctx: { scripts: [], renderers: [], adapter: undefined },
|
_ctx: { scripts: [], renderers: [], adapter: undefined },
|
||||||
};
|
};
|
||||||
|
// Final-Pass Validation (perform checks that require the full config object)
|
||||||
|
if (!result.experimentalIntegrations && !result.integrations.every((int) => int.name.startsWith('@astrojs/'))) {
|
||||||
|
throw new Error([
|
||||||
|
`Astro integrations are still experimental.`,
|
||||||
|
``,
|
||||||
|
`Only official "@astrojs/*" integrations are currently supported.`,
|
||||||
|
`To enable 3rd-party integrations, use the "--experimental-integrations" flag.`,
|
||||||
|
`Breaking changes may occur in this API before Astro v1.0 is released.`,
|
||||||
|
``
|
||||||
|
].join('\n'));
|
||||||
|
}
|
||||||
|
// If successful, return the result as a verified AstroConfig object.
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Adds '/' to end of string but doesn’t double-up */
|
/** Adds '/' to end of string but doesn’t double-up */
|
||||||
|
@ -236,6 +244,7 @@ function resolveFlags(flags: Partial<Flags>): CLIFlags {
|
||||||
host: typeof flags.host === 'string' || typeof flags.host === 'boolean' ? flags.host : undefined,
|
host: typeof flags.host === 'string' || typeof flags.host === 'boolean' ? flags.host : undefined,
|
||||||
legacyBuild: typeof flags.legacyBuild === 'boolean' ? flags.legacyBuild : false,
|
legacyBuild: typeof flags.legacyBuild === 'boolean' ? flags.legacyBuild : false,
|
||||||
experimentalSsr: typeof flags.experimentalSsr === 'boolean' ? flags.experimentalSsr : false,
|
experimentalSsr: typeof flags.experimentalSsr === 'boolean' ? flags.experimentalSsr : false,
|
||||||
|
experimentalIntegrations: typeof flags.experimentalIntegrations === 'boolean' ? flags.experimentalIntegrations : false,
|
||||||
drafts: typeof flags.drafts === 'boolean' ? flags.drafts : false,
|
drafts: typeof flags.drafts === 'boolean' ? flags.drafts : false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -256,6 +265,7 @@ function mergeCLIFlags(astroConfig: AstroUserConfig, flags: CLIFlags) {
|
||||||
astroConfig.buildOptions.legacyBuild = false;
|
astroConfig.buildOptions.legacyBuild = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (typeof flags.experimentalIntegrations === 'boolean') astroConfig.experimentalIntegrations = flags.experimentalIntegrations;
|
||||||
if (typeof flags.drafts === 'boolean') astroConfig.buildOptions.drafts = flags.drafts;
|
if (typeof flags.drafts === 'boolean') astroConfig.buildOptions.drafts = flags.drafts;
|
||||||
return astroConfig;
|
return astroConfig;
|
||||||
}
|
}
|
||||||
|
@ -311,6 +321,7 @@ export async function loadConfig(configOptions: LoadConfigOptions): Promise<Astr
|
||||||
export async function resolveConfig(userConfig: AstroUserConfig, root: string, flags: CLIFlags = {}): Promise<AstroConfig> {
|
export async function resolveConfig(userConfig: AstroUserConfig, root: string, flags: CLIFlags = {}): Promise<AstroConfig> {
|
||||||
const mergedConfig = mergeCLIFlags(userConfig, flags);
|
const mergedConfig = mergeCLIFlags(userConfig, flags);
|
||||||
const validatedConfig = await validateConfig(mergedConfig, root);
|
const validatedConfig = await validateConfig(mergedConfig, root);
|
||||||
|
|
||||||
return validatedConfig;
|
return validatedConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,11 +64,10 @@ describe('Config Validation', () => {
|
||||||
});
|
});
|
||||||
it('blocks third-party "integration" values', async () => {
|
it('blocks third-party "integration" values', async () => {
|
||||||
const configError = await validateConfig({ integrations: [{ name: '@my-plugin/a' }] }, process.cwd()).catch((err) => err);
|
const configError = await validateConfig({ integrations: [{ name: '@my-plugin/a' }] }, process.cwd()).catch((err) => err);
|
||||||
expect(configError instanceof z.ZodError).to.equal(true);
|
expect(configError).to.be.instanceOf(Error);
|
||||||
const formattedError = stripAnsi(formatConfigError(configError));
|
expect(configError.message).to.include('Astro integrations are still experimental.');
|
||||||
expect(formattedError).to.equal(
|
});
|
||||||
`[config] Astro found issue(s) with your configuration:
|
it('allows third-party "integration" values with the --experimental-integrations flag', async () => {
|
||||||
! integrations Astro integrations are still experimental, and only official integrations are currently supported.`
|
await validateConfig({ integrations: [{ name: '@my-plugin/a' }], experimentalIntegrations: true }, process.cwd()).catch((err) => err);
|
||||||
);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue