refactor: finish feature module tooling
This commit is contained in:
1 parent
425cb653a1
commit
c988c35b29
7 files changed
+377
-111
No files matched your search
@@ -5,6 +5,7 @@ import { fileURLToPath, pathToFileURL } from "node:url";
|
||||
import { format } from "oxfmt";
|
||||
|
||||
import type { IntegrationModuleDefinition } from "../../packages/definitions/src/integration-module";
|
||||
import { integrationCategories, integrationSecretKinds } from "../../packages/definitions/src/integration";
|
||||
|
||||
const repositoryRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../..");
|
||||
const integrationsRoot = path.join(repositoryRoot, "packages/integrations/src");
|
||||
@@ -15,6 +16,8 @@ const integrationCreatorsSource = path.join(integrationsRoot, "base/creator.ts")
|
||||
const checkOnly = process.argv.includes("--check");
|
||||
const generatedHeader = "// This file is generated by pnpm integrations:sync. Do not edit it directly.\n\n";
|
||||
const generatedDocsMarker = ".integration-module-generated";
|
||||
const integrationCategorySet = new Set<string>(integrationCategories);
|
||||
const integrationSecretKindSet = new Set<string>(integrationSecretKinds);
|
||||
|
||||
interface LoadedIntegrationModule {
|
||||
definition: IntegrationModuleDefinition;
|
||||
@@ -106,17 +109,35 @@ const validateIntegrationModuleAsync = async (module: LoadedIntegrationModule) =
|
||||
if (!Array.isArray(definition.secretKinds) || definition.secretKinds.length === 0) {
|
||||
throw new Error(`Integration ${definition.kind} must declare at least one secret alternative`);
|
||||
}
|
||||
for (const secretAlternative of definition.secretKinds) {
|
||||
if (!Array.isArray(secretAlternative)) {
|
||||
throw new Error(`Integration ${definition.kind} secret alternatives must be arrays`);
|
||||
}
|
||||
for (const secretKind of secretAlternative) {
|
||||
if (!integrationSecretKindSet.has(secretKind)) {
|
||||
throw new Error(`Integration ${definition.kind} has unknown secret kind ${secretKind}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!Array.isArray(definition.categories) || definition.categories.length === 0) {
|
||||
throw new Error(`Integration ${definition.kind} must declare at least one category`);
|
||||
}
|
||||
for (const category of definition.categories) {
|
||||
if (!integrationCategorySet.has(category)) {
|
||||
throw new Error(`Integration ${definition.kind} has unknown category ${category}`);
|
||||
}
|
||||
}
|
||||
if (!/^[a-z0-9][a-z0-9-]*$/.test(definition.documentation.slug)) {
|
||||
throw new Error(`Integration ${definition.kind} has invalid documentation slug ${definition.documentation.slug}`);
|
||||
}
|
||||
if (
|
||||
definition.defaultPort !== undefined &&
|
||||
(!Number.isSafeInteger(definition.defaultPort) || definition.defaultPort < 1)
|
||||
(!Number.isSafeInteger(definition.defaultPort) || definition.defaultPort < 1 || definition.defaultPort > 65_535)
|
||||
) {
|
||||
throw new Error(`Integration ${definition.kind} default port must be a positive integer`);
|
||||
throw new Error(`Integration ${definition.kind} default port must be an integer between 1 and 65535`);
|
||||
}
|
||||
if (definition.defaultUrl !== undefined && !URL.canParse(definition.defaultUrl)) {
|
||||
throw new Error(`Integration ${definition.kind} default URL is invalid`);
|
||||
}
|
||||
|
||||
const docsDirectory = path.resolve(module.directory, definition.documentation.sourceDirectory);
|
||||
@@ -231,7 +252,14 @@ const renderDefinitionsRegistry = (modules: LoadedIntegrationModule[]) => {
|
||||
const entries = modules
|
||||
.map((module) => ` ${JSON.stringify(module.definition.kind)}: ${renderDefinition(module.definition)},`)
|
||||
.join("\n");
|
||||
return `${generatedHeader}export const generatedIntegrationDefinitions = {\n${entries}\n} as const;\n`;
|
||||
const documentationSources = modules
|
||||
.map((module) => {
|
||||
const source = path.resolve(module.directory, module.definition.documentation.sourceDirectory);
|
||||
const relativeSource = toPosixPath(path.relative(repositoryRoot, source));
|
||||
return ` ${JSON.stringify(module.definition.documentation.slug)}: ${JSON.stringify(relativeSource)},`;
|
||||
})
|
||||
.join("\n");
|
||||
return `${generatedHeader}export const generatedIntegrationDefinitions = {\n${entries}\n} as const;\n\nexport const generatedIntegrationDocumentationSources = {\n${documentationSources}\n} as const;\n`;
|
||||
};
|
||||
|
||||
const getCreatorImportPath = (module: LoadedIntegrationModule) => {
|
||||
|
||||
Reference in new issue
Block a user