@strapi/typescript-utils 0.0.0-experimental.6340da17068c3bed7fb006e7bcc554c71129e282 → 0.0.0-experimental.63624e21eb5b0713345a0cf2f68f1c40eab427bc
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/compile.d.ts +5 -0
- package/dist/compile.d.ts.map +1 -0
- package/dist/compile.js +12 -0
- package/dist/compile.js.map +1 -0
- package/dist/compile.mjs +10 -0
- package/dist/compile.mjs.map +1 -0
- package/dist/compilers/basic.d.ts +11 -0
- package/dist/compilers/basic.d.ts.map +1 -0
- package/dist/compilers/basic.js +58 -0
- package/dist/compilers/basic.js.map +1 -0
- package/dist/compilers/basic.mjs +36 -0
- package/dist/compilers/basic.mjs.map +1 -0
- package/dist/compilers/index.d.ts +3 -0
- package/dist/compilers/index.d.ts.map +1 -0
- package/dist/compilers/index.js +8 -0
- package/dist/compilers/index.js.map +1 -0
- package/dist/compilers/index.mjs +3 -0
- package/dist/compilers/index.mjs.map +1 -0
- package/dist/generators/common/compare.d.ts +14 -0
- package/dist/generators/common/compare.d.ts.map +1 -0
- package/dist/generators/common/compare.js +25 -0
- package/dist/generators/common/compare.js.map +1 -0
- package/dist/generators/common/compare.mjs +22 -0
- package/dist/generators/common/compare.mjs.map +1 -0
- package/dist/generators/common/imports.d.ts +5 -0
- package/dist/generators/common/imports.d.ts.map +1 -0
- package/dist/generators/common/imports.js +42 -0
- package/dist/generators/common/imports.js.map +1 -0
- package/dist/generators/common/imports.mjs +19 -0
- package/dist/generators/common/imports.mjs.map +1 -0
- package/dist/generators/common/index.d.ts +4 -0
- package/dist/generators/common/index.d.ts.map +1 -0
- package/dist/generators/common/interface-names.d.ts +16 -0
- package/dist/generators/common/interface-names.d.ts.map +1 -0
- package/dist/generators/common/interface-names.js +54 -0
- package/dist/generators/common/interface-names.js.map +1 -0
- package/dist/generators/common/interface-names.mjs +52 -0
- package/dist/generators/common/interface-names.mjs.map +1 -0
- package/dist/generators/common/models/attributes.d.ts +38 -0
- package/dist/generators/common/models/attributes.d.ts.map +1 -0
- package/dist/generators/common/models/attributes.js +205 -0
- package/dist/generators/common/models/attributes.js.map +1 -0
- package/dist/generators/common/models/attributes.mjs +176 -0
- package/dist/generators/common/models/attributes.mjs.map +1 -0
- package/dist/generators/common/models/index.d.ts +7 -0
- package/dist/generators/common/models/index.d.ts.map +1 -0
- package/dist/generators/common/models/mappers.d.ts +9 -0
- package/dist/generators/common/models/mappers.d.ts.map +1 -0
- package/dist/generators/common/models/mappers.js +227 -0
- package/dist/generators/common/models/mappers.js.map +1 -0
- package/dist/generators/common/models/mappers.mjs +202 -0
- package/dist/generators/common/models/mappers.mjs.map +1 -0
- package/dist/generators/common/models/schema.d.ts +8 -0
- package/dist/generators/common/models/schema.d.ts.map +1 -0
- package/dist/generators/common/models/schema.js +78 -0
- package/dist/generators/common/models/schema.js.map +1 -0
- package/dist/generators/common/models/schema.mjs +56 -0
- package/dist/generators/common/models/schema.mjs.map +1 -0
- package/dist/generators/common/models/utils.d.ts +57 -0
- package/dist/generators/common/models/utils.d.ts.map +1 -0
- package/dist/generators/common/models/utils.js +110 -0
- package/dist/generators/common/models/utils.js.map +1 -0
- package/dist/generators/common/models/utils.mjs +82 -0
- package/dist/generators/common/models/utils.mjs.map +1 -0
- package/dist/generators/common/sources.d.ts +133 -0
- package/dist/generators/common/sources.d.ts.map +1 -0
- package/dist/generators/common/sources.js +354 -0
- package/dist/generators/common/sources.js.map +1 -0
- package/dist/generators/common/sources.mjs +318 -0
- package/dist/generators/common/sources.mjs.map +1 -0
- package/dist/generators/components/index.d.ts +9 -0
- package/dist/generators/components/index.d.ts.map +1 -0
- package/dist/generators/components/index.js +84 -0
- package/dist/generators/components/index.js.map +1 -0
- package/dist/generators/components/index.mjs +62 -0
- package/dist/generators/components/index.mjs.map +1 -0
- package/dist/generators/constants.d.ts +3 -0
- package/dist/generators/constants.d.ts.map +1 -0
- package/dist/generators/constants.js +8 -0
- package/dist/generators/constants.js.map +1 -0
- package/dist/generators/constants.mjs +5 -0
- package/dist/generators/constants.mjs.map +1 -0
- package/dist/generators/content-types/index.d.ts +9 -0
- package/dist/generators/content-types/index.d.ts.map +1 -0
- package/dist/generators/content-types/index.js +84 -0
- package/dist/generators/content-types/index.js.map +1 -0
- package/dist/generators/content-types/index.mjs +62 -0
- package/dist/generators/content-types/index.mjs.map +1 -0
- package/dist/generators/controllers/index.d.ts +35 -0
- package/dist/generators/controllers/index.d.ts.map +1 -0
- package/dist/generators/controllers/index.js +88 -0
- package/dist/generators/controllers/index.js.map +1 -0
- package/dist/generators/controllers/index.mjs +86 -0
- package/dist/generators/controllers/index.mjs.map +1 -0
- package/dist/generators/index.d.ts +31 -0
- package/dist/generators/index.d.ts.map +1 -0
- package/dist/generators/index.js +150 -0
- package/dist/generators/index.js.map +1 -0
- package/dist/generators/index.mjs +142 -0
- package/dist/generators/index.mjs.map +1 -0
- package/dist/generators/middlewares/index.d.ts +30 -0
- package/dist/generators/middlewares/index.d.ts.map +1 -0
- package/dist/generators/middlewares/index.js +163 -0
- package/dist/generators/middlewares/index.js.map +1 -0
- package/dist/generators/middlewares/index.mjs +141 -0
- package/dist/generators/middlewares/index.mjs.map +1 -0
- package/dist/generators/plugins/index.d.ts +9 -0
- package/dist/generators/plugins/index.d.ts.map +1 -0
- package/dist/generators/plugins/index.js +225 -0
- package/dist/generators/plugins/index.js.map +1 -0
- package/dist/generators/plugins/index.mjs +200 -0
- package/dist/generators/plugins/index.mjs.map +1 -0
- package/dist/generators/policies/index.d.ts +29 -0
- package/dist/generators/policies/index.d.ts.map +1 -0
- package/dist/generators/policies/index.js +135 -0
- package/dist/generators/policies/index.js.map +1 -0
- package/dist/generators/policies/index.mjs +113 -0
- package/dist/generators/policies/index.mjs.map +1 -0
- package/dist/generators/services/index.d.ts +35 -0
- package/dist/generators/services/index.d.ts.map +1 -0
- package/dist/generators/services/index.js +87 -0
- package/dist/generators/services/index.js.map +1 -0
- package/dist/generators/services/index.mjs +85 -0
- package/dist/generators/services/index.mjs.map +1 -0
- package/dist/generators/strict/index.d.ts +13 -0
- package/dist/generators/strict/index.d.ts.map +1 -0
- package/dist/generators/strict/index.js +24 -0
- package/dist/generators/strict/index.js.map +1 -0
- package/dist/generators/strict/index.mjs +22 -0
- package/dist/generators/strict/index.mjs.map +1 -0
- package/dist/generators/utils.d.ts +68 -0
- package/dist/generators/utils.d.ts.map +1 -0
- package/dist/generators/utils.js +201 -0
- package/dist/generators/utils.js.map +1 -0
- package/dist/generators/utils.mjs +166 -0
- package/dist/generators/utils.mjs.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +28 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +14 -0
- package/dist/index.mjs.map +1 -0
- package/dist/utils/format-host.d.ts +3 -0
- package/dist/utils/format-host.d.ts.map +1 -0
- package/dist/utils/format-host.js +33 -0
- package/dist/utils/format-host.js.map +1 -0
- package/dist/utils/format-host.mjs +11 -0
- package/dist/utils/format-host.mjs.map +1 -0
- package/dist/utils/get-config-path.d.ts +10 -0
- package/dist/utils/get-config-path.d.ts.map +1 -0
- package/dist/utils/get-config-path.js +43 -0
- package/dist/utils/get-config-path.js.map +1 -0
- package/dist/utils/get-config-path.mjs +18 -0
- package/dist/utils/get-config-path.mjs.map +1 -0
- package/dist/utils/index.d.ts +9 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/is-using-typescript-sync.d.ts +5 -0
- package/dist/utils/is-using-typescript-sync.d.ts.map +1 -0
- package/dist/utils/is-using-typescript-sync.js +20 -0
- package/dist/utils/is-using-typescript-sync.js.map +1 -0
- package/dist/utils/is-using-typescript-sync.mjs +14 -0
- package/dist/utils/is-using-typescript-sync.mjs.map +1 -0
- package/dist/utils/is-using-typescript.d.ts +5 -0
- package/dist/utils/is-using-typescript.d.ts.map +1 -0
- package/dist/utils/is-using-typescript.js +20 -0
- package/dist/utils/is-using-typescript.js.map +1 -0
- package/dist/utils/is-using-typescript.mjs +14 -0
- package/dist/utils/is-using-typescript.mjs.map +1 -0
- package/dist/utils/report-diagnostics.d.ts +6 -0
- package/dist/utils/report-diagnostics.d.ts.map +1 -0
- package/dist/utils/report-diagnostics.js +37 -0
- package/dist/utils/report-diagnostics.js.map +1 -0
- package/dist/utils/report-diagnostics.mjs +15 -0
- package/dist/utils/report-diagnostics.mjs.map +1 -0
- package/dist/utils/resolve-config-options.d.ts +12 -0
- package/dist/utils/resolve-config-options.d.ts.map +1 -0
- package/dist/utils/resolve-config-options.js +39 -0
- package/dist/utils/resolve-config-options.js.map +1 -0
- package/dist/utils/resolve-config-options.mjs +17 -0
- package/dist/utils/resolve-config-options.mjs.map +1 -0
- package/dist/utils/resolve-outdir-sync.d.ts +5 -0
- package/dist/utils/resolve-outdir-sync.d.ts.map +1 -0
- package/dist/utils/resolve-outdir-sync.js +19 -0
- package/dist/utils/resolve-outdir-sync.js.map +1 -0
- package/dist/utils/resolve-outdir-sync.mjs +13 -0
- package/dist/utils/resolve-outdir-sync.mjs.map +1 -0
- package/dist/utils/resolve-outdir.d.ts +5 -0
- package/dist/utils/resolve-outdir.d.ts.map +1 -0
- package/dist/utils/resolve-outdir.js +19 -0
- package/dist/utils/resolve-outdir.js.map +1 -0
- package/dist/utils/resolve-outdir.mjs +13 -0
- package/dist/utils/resolve-outdir.mjs.map +1 -0
- package/package.json +27 -12
- package/.eslintrc.cjs +0 -16
- package/index.d.ts +0 -5
- package/jest.config.js +0 -6
- package/lib/__tests__/generators/schemas/attributes.test.js +0 -903
- package/lib/__tests__/generators/schemas/imports.test.js +0 -56
- package/lib/__tests__/generators/schemas/utils.test.js +0 -314
- package/lib/compile.js +0 -10
- package/lib/compilers/basic.js +0 -50
- package/lib/compilers/index.js +0 -7
- package/lib/generators/common/imports.js +0 -34
- package/lib/generators/common/index.js +0 -9
- package/lib/generators/common/models/attributes.js +0 -198
- package/lib/generators/common/models/index.js +0 -15
- package/lib/generators/common/models/mappers.js +0 -144
- package/lib/generators/common/models/schema.js +0 -93
- package/lib/generators/common/models/utils.js +0 -178
- package/lib/generators/components/index.js +0 -74
- package/lib/generators/constants.js +0 -6
- package/lib/generators/content-types/index.js +0 -74
- package/lib/generators/index.js +0 -122
- package/lib/generators/utils.js +0 -216
- package/lib/index.js +0 -13
- package/lib/utils/format-host.js +0 -15
- package/lib/utils/get-config-path.js +0 -29
- package/lib/utils/index.js +0 -21
- package/lib/utils/is-using-typescript-sync.js +0 -19
- package/lib/utils/is-using-typescript.js +0 -17
- package/lib/utils/report-diagnostics.js +0 -19
- package/lib/utils/resolve-config-options.js +0 -23
- package/lib/utils/resolve-outdir-sync.js +0 -18
- package/lib/utils/resolve-outdir.js +0 -18
- package/lint-staged.config.mjs +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../src/generators/index.ts"],"sourcesContent":["import path from 'node:path';\nimport fs from 'node:fs/promises';\nimport chalk from 'chalk';\n\nimport { TYPES_ROOT_DIR, GENERATED_OUT_DIR } from './constants';\nimport { saveDefinitionToFileSystem, createLogger, timer, pathExists } from './utils';\nimport { generateContentTypesDefinitions } from './content-types';\nimport { generateComponentsDefinitions } from './components';\nimport { generatePluginDefinitions } from './plugins';\nimport { generateServicesDefinitions } from './services';\nimport { generateControllersDefinitions } from './controllers';\nimport { generatePoliciesDefinitions } from './policies';\nimport { generateMiddlewaresDefinitions } from './middlewares';\nimport { generateStrictDefinitions } from './strict';\n\nconst GENERATORS = {\n contentTypes: generateContentTypesDefinitions,\n components: generateComponentsDefinitions,\n plugins: generatePluginDefinitions,\n services: generateServicesDefinitions,\n controllers: generateControllersDefinitions,\n policies: generatePoliciesDefinitions,\n middlewares: generateMiddlewaresDefinitions,\n strict: generateStrictDefinitions,\n};\n\n/**\n * Artifacts written as `.ts` rather than `.d.ts`: they import the application's sources, and a\n * reference that no longer resolves (a moved source, a renamed contract) is reported by `tsc` even\n * with `skipLibCheck`, rather than silently typing the lookup as `any`. The other artifacts only\n * hold declarations generated from the schemas, and stay `.d.ts`.\n */\nconst SOURCE_ARTIFACTS = new Set(['services', 'controllers', 'policies', 'middlewares']);\n\n/**\n * The application's linters would check the `.ts` artifacts, whose helpers use `any`.\n */\nconst LINT_DISABLE_HEADER = '/* eslint-disable */\\n/* oxlint-disable */\\n';\n\nconst isSourceArtifact = (artifact: string) => SOURCE_ARTIFACTS.has(artifact);\n\nconst filenameOf = (artifact: string) =>\n isSourceArtifact(artifact) === true ? `${artifact}.ts` : `${artifact}.d.ts`;\n\n/**\n * File name an earlier generation wrote the artifact to, removed with the artifact's own file\n */\nconst previousFilenameOf = (artifact: string) =>\n isSourceArtifact(artifact) === true ? `${artifact}.d.ts` : undefined;\n\nexport interface GenerateConfig {\n strapi: any;\n pwd: string;\n rootDir?: string;\n /**\n * Artifacts to generate. `true` generates the artifact, `false` removes the file a previous\n * run may have generated for it, unset leaves it untouched.\n * `services`, `controllers`, `policies`, `middlewares` and `strict` are the strict types artifacts\n * (`typescript.strictTypes`).\n */\n artifacts?: {\n contentTypes?: boolean;\n components?: boolean;\n plugins?: boolean;\n services?: boolean;\n strict?: boolean;\n controllers?: boolean;\n policies?: boolean;\n middlewares?: boolean;\n };\n logger?: {\n silent?: boolean;\n debug?: boolean;\n verbose?: boolean;\n };\n}\n\n/**\n * Generate types definitions based on the given configuration\n */\nexport const generate = async (config: GenerateConfig = {} as GenerateConfig) => {\n const { pwd, rootDir = TYPES_ROOT_DIR, strapi, artifacts = {}, logger: loggerConfig } = config;\n const reports: Record<string, any> = {};\n const logger = createLogger(loggerConfig);\n const psTimer = timer().start();\n\n const registryPwd = path.join(pwd, rootDir, GENERATED_OUT_DIR);\n // Strict mode reads only the global schema registries, so schemas use that form with the opt-in.\n const strict = artifacts.strict === true;\n const generatorConfig = { strapi, pwd: registryPwd, appDir: pwd, logger, strict };\n\n const returnWithMessage = () => {\n const nbWarnings = chalk.yellow(`${logger.warnings} warning(s)`);\n const nbErrors = chalk.red(`${logger.errors} error(s)`);\n\n const status = logger.errors > 0 ? chalk.red('errored') : chalk.green('completed successfully');\n\n psTimer.end();\n\n logger.info(`The task ${status} with ${nbWarnings} and ${nbErrors} in ${psTimer.duration}s.`);\n\n return reports;\n };\n\n const enabledArtifacts = Object.keys(artifacts).filter(\n (p) => (artifacts as Record<string, boolean>)[p] === true\n );\n const disabledArtifacts = Object.keys(artifacts).filter(\n (p) => (artifacts as Record<string, boolean>)[p] === false && p in GENERATORS\n );\n\n logger.info('Starting the type generation process');\n logger.debug(`Enabled artifacts: ${enabledArtifacts.join(', ')}`);\n\n for (const artifact of enabledArtifacts) {\n const boldArtifact = chalk.bold(artifact); // used for log messages\n\n logger.info(`Generating types for ${boldArtifact}`);\n\n if (artifact in GENERATORS) {\n const generator = (GENERATORS as any)[artifact];\n\n try {\n const artifactGenTimer = timer().start();\n\n reports[artifact] = await generator(generatorConfig);\n\n artifactGenTimer.end();\n\n logger.debug(`Generated ${boldArtifact} in ${artifactGenTimer.duration}s`);\n } catch (e) {\n logger.error(\n `Failed to generate types for ${boldArtifact}: ${(e as any).message ?? (e as any).toString()}. Exiting`\n );\n return returnWithMessage();\n }\n } else {\n logger.warn(`The types generator for ${boldArtifact} is not implemented, skipping`);\n }\n }\n\n for (const artifact of Object.keys(reports)) {\n const boldArtifact = chalk.bold(artifact); // used for log messages\n\n const artifactFsTimer = timer().start();\n\n const report = reports[artifact];\n const filename = filenameOf(artifact);\n const previousFilename = previousFilenameOf(artifact);\n const content =\n isSourceArtifact(artifact) === true\n ? `${LINT_DISABLE_HEADER}${report.output}`\n : report.output;\n\n try {\n const outPath = await saveDefinitionToFileSystem(registryPwd, filename, content);\n\n // A stale `.d.ts` would declare the registry entries a second time\n if (previousFilename !== undefined) {\n await fs.rm(path.join(registryPwd, previousFilename), { force: true });\n }\n\n const relativeOutPath = path.relative(process.cwd(), outPath);\n\n artifactFsTimer.end();\n\n logger.info(`Saved ${boldArtifact} types in ${chalk.bold(relativeOutPath)}`);\n logger.debug(`Saved ${boldArtifact} in ${artifactFsTimer.duration}s`);\n } catch (e) {\n logger.error(\n `An error occurred while saving ${boldArtifact} types to the filesystem: ${\n (e as any).message ?? (e as any).toString()\n }. Exiting`\n );\n return returnWithMessage();\n }\n }\n\n // Disabled artifacts are removed so that a stale generated file does not keep applying\n for (const artifact of disabledArtifacts) {\n const boldArtifact = chalk.bold(artifact); // used for log messages\n const previousFilename = previousFilenameOf(artifact);\n const outPaths = [\n filenameOf(artifact),\n ...(previousFilename === undefined ? [] : [previousFilename]),\n ].map((filename) => path.join(registryPwd, filename));\n\n try {\n for (const outPath of outPaths) {\n if ((await pathExists(outPath)) === false) {\n continue;\n }\n\n await fs.rm(outPath);\n\n logger.info(\n `Removed ${boldArtifact} types from ${chalk.bold(path.relative(process.cwd(), outPath))} (artifact disabled)`\n );\n }\n } catch (e) {\n logger.error(\n `An error occurred while removing ${boldArtifact} types from the filesystem: ${\n (e as any).message ?? (e as any).toString()\n }. Exiting`\n );\n return returnWithMessage();\n }\n }\n\n return returnWithMessage();\n};\n"],"names":["GENERATORS","contentTypes","generateContentTypesDefinitions","components","generateComponentsDefinitions","plugins","generatePluginDefinitions","services","generateServicesDefinitions","controllers","generateControllersDefinitions","policies","generatePoliciesDefinitions","middlewares","generateMiddlewaresDefinitions","strict","generateStrictDefinitions","SOURCE_ARTIFACTS","Set","LINT_DISABLE_HEADER","isSourceArtifact","artifact","has","filenameOf","previousFilenameOf","undefined","generate","config","pwd","rootDir","TYPES_ROOT_DIR","strapi","artifacts","logger","loggerConfig","reports","createLogger","psTimer","timer","start","registryPwd","path","join","GENERATED_OUT_DIR","generatorConfig","appDir","returnWithMessage","nbWarnings","chalk","yellow","warnings","nbErrors","red","errors","status","green","end","info","duration","enabledArtifacts","Object","keys","filter","p","disabledArtifacts","debug","boldArtifact","bold","generator","artifactGenTimer","e","error","message","toString","warn","artifactFsTimer","report","filename","previousFilename","content","output","outPath","saveDefinitionToFileSystem","fs","rm","force","relativeOutPath","relative","process","cwd","outPaths","map","pathExists"],"mappings":"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"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import fs from 'node:fs/promises';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import { TYPES_ROOT_DIR, GENERATED_OUT_DIR } from './constants.mjs';
|
|
5
|
+
import { createLogger, timer, saveDefinitionToFileSystem, pathExists } from './utils.mjs';
|
|
6
|
+
import { generateContentTypesDefinitions } from './content-types/index.mjs';
|
|
7
|
+
import { generateComponentsDefinitions } from './components/index.mjs';
|
|
8
|
+
import { generatePluginDefinitions } from './plugins/index.mjs';
|
|
9
|
+
import { generateServicesDefinitions } from './services/index.mjs';
|
|
10
|
+
import { generateControllersDefinitions } from './controllers/index.mjs';
|
|
11
|
+
import { generatePoliciesDefinitions } from './policies/index.mjs';
|
|
12
|
+
import { generateMiddlewaresDefinitions } from './middlewares/index.mjs';
|
|
13
|
+
import { generateStrictDefinitions } from './strict/index.mjs';
|
|
14
|
+
|
|
15
|
+
const GENERATORS = {
|
|
16
|
+
contentTypes: generateContentTypesDefinitions,
|
|
17
|
+
components: generateComponentsDefinitions,
|
|
18
|
+
plugins: generatePluginDefinitions,
|
|
19
|
+
services: generateServicesDefinitions,
|
|
20
|
+
controllers: generateControllersDefinitions,
|
|
21
|
+
policies: generatePoliciesDefinitions,
|
|
22
|
+
middlewares: generateMiddlewaresDefinitions,
|
|
23
|
+
strict: generateStrictDefinitions
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Artifacts written as `.ts` rather than `.d.ts`: they import the application's sources, and a
|
|
27
|
+
* reference that no longer resolves (a moved source, a renamed contract) is reported by `tsc` even
|
|
28
|
+
* with `skipLibCheck`, rather than silently typing the lookup as `any`. The other artifacts only
|
|
29
|
+
* hold declarations generated from the schemas, and stay `.d.ts`.
|
|
30
|
+
*/ const SOURCE_ARTIFACTS = new Set([
|
|
31
|
+
'services',
|
|
32
|
+
'controllers',
|
|
33
|
+
'policies',
|
|
34
|
+
'middlewares'
|
|
35
|
+
]);
|
|
36
|
+
/**
|
|
37
|
+
* The application's linters would check the `.ts` artifacts, whose helpers use `any`.
|
|
38
|
+
*/ const LINT_DISABLE_HEADER = '/* eslint-disable */\n/* oxlint-disable */\n';
|
|
39
|
+
const isSourceArtifact = (artifact)=>SOURCE_ARTIFACTS.has(artifact);
|
|
40
|
+
const filenameOf = (artifact)=>isSourceArtifact(artifact) === true ? `${artifact}.ts` : `${artifact}.d.ts`;
|
|
41
|
+
/**
|
|
42
|
+
* File name an earlier generation wrote the artifact to, removed with the artifact's own file
|
|
43
|
+
*/ const previousFilenameOf = (artifact)=>isSourceArtifact(artifact) === true ? `${artifact}.d.ts` : undefined;
|
|
44
|
+
/**
|
|
45
|
+
* Generate types definitions based on the given configuration
|
|
46
|
+
*/ const generate = async (config = {})=>{
|
|
47
|
+
const { pwd, rootDir = TYPES_ROOT_DIR, strapi, artifacts = {}, logger: loggerConfig } = config;
|
|
48
|
+
const reports = {};
|
|
49
|
+
const logger = createLogger(loggerConfig);
|
|
50
|
+
const psTimer = timer().start();
|
|
51
|
+
const registryPwd = path.join(pwd, rootDir, GENERATED_OUT_DIR);
|
|
52
|
+
// Strict mode reads only the global schema registries, so schemas use that form with the opt-in.
|
|
53
|
+
const strict = artifacts.strict === true;
|
|
54
|
+
const generatorConfig = {
|
|
55
|
+
strapi,
|
|
56
|
+
pwd: registryPwd,
|
|
57
|
+
appDir: pwd,
|
|
58
|
+
logger,
|
|
59
|
+
strict
|
|
60
|
+
};
|
|
61
|
+
const returnWithMessage = ()=>{
|
|
62
|
+
const nbWarnings = chalk.yellow(`${logger.warnings} warning(s)`);
|
|
63
|
+
const nbErrors = chalk.red(`${logger.errors} error(s)`);
|
|
64
|
+
const status = logger.errors > 0 ? chalk.red('errored') : chalk.green('completed successfully');
|
|
65
|
+
psTimer.end();
|
|
66
|
+
logger.info(`The task ${status} with ${nbWarnings} and ${nbErrors} in ${psTimer.duration}s.`);
|
|
67
|
+
return reports;
|
|
68
|
+
};
|
|
69
|
+
const enabledArtifacts = Object.keys(artifacts).filter((p)=>artifacts[p] === true);
|
|
70
|
+
const disabledArtifacts = Object.keys(artifacts).filter((p)=>artifacts[p] === false && p in GENERATORS);
|
|
71
|
+
logger.info('Starting the type generation process');
|
|
72
|
+
logger.debug(`Enabled artifacts: ${enabledArtifacts.join(', ')}`);
|
|
73
|
+
for (const artifact of enabledArtifacts){
|
|
74
|
+
const boldArtifact = chalk.bold(artifact); // used for log messages
|
|
75
|
+
logger.info(`Generating types for ${boldArtifact}`);
|
|
76
|
+
if (artifact in GENERATORS) {
|
|
77
|
+
const generator = GENERATORS[artifact];
|
|
78
|
+
try {
|
|
79
|
+
const artifactGenTimer = timer().start();
|
|
80
|
+
reports[artifact] = await generator(generatorConfig);
|
|
81
|
+
artifactGenTimer.end();
|
|
82
|
+
logger.debug(`Generated ${boldArtifact} in ${artifactGenTimer.duration}s`);
|
|
83
|
+
} catch (e) {
|
|
84
|
+
logger.error(`Failed to generate types for ${boldArtifact}: ${e.message ?? e.toString()}. Exiting`);
|
|
85
|
+
return returnWithMessage();
|
|
86
|
+
}
|
|
87
|
+
} else {
|
|
88
|
+
logger.warn(`The types generator for ${boldArtifact} is not implemented, skipping`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
for (const artifact of Object.keys(reports)){
|
|
92
|
+
const boldArtifact = chalk.bold(artifact); // used for log messages
|
|
93
|
+
const artifactFsTimer = timer().start();
|
|
94
|
+
const report = reports[artifact];
|
|
95
|
+
const filename = filenameOf(artifact);
|
|
96
|
+
const previousFilename = previousFilenameOf(artifact);
|
|
97
|
+
const content = isSourceArtifact(artifact) === true ? `${LINT_DISABLE_HEADER}${report.output}` : report.output;
|
|
98
|
+
try {
|
|
99
|
+
const outPath = await saveDefinitionToFileSystem(registryPwd, filename, content);
|
|
100
|
+
// A stale `.d.ts` would declare the registry entries a second time
|
|
101
|
+
if (previousFilename !== undefined) {
|
|
102
|
+
await fs.rm(path.join(registryPwd, previousFilename), {
|
|
103
|
+
force: true
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
const relativeOutPath = path.relative(process.cwd(), outPath);
|
|
107
|
+
artifactFsTimer.end();
|
|
108
|
+
logger.info(`Saved ${boldArtifact} types in ${chalk.bold(relativeOutPath)}`);
|
|
109
|
+
logger.debug(`Saved ${boldArtifact} in ${artifactFsTimer.duration}s`);
|
|
110
|
+
} catch (e) {
|
|
111
|
+
logger.error(`An error occurred while saving ${boldArtifact} types to the filesystem: ${e.message ?? e.toString()}. Exiting`);
|
|
112
|
+
return returnWithMessage();
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
// Disabled artifacts are removed so that a stale generated file does not keep applying
|
|
116
|
+
for (const artifact of disabledArtifacts){
|
|
117
|
+
const boldArtifact = chalk.bold(artifact); // used for log messages
|
|
118
|
+
const previousFilename = previousFilenameOf(artifact);
|
|
119
|
+
const outPaths = [
|
|
120
|
+
filenameOf(artifact),
|
|
121
|
+
...previousFilename === undefined ? [] : [
|
|
122
|
+
previousFilename
|
|
123
|
+
]
|
|
124
|
+
].map((filename)=>path.join(registryPwd, filename));
|
|
125
|
+
try {
|
|
126
|
+
for (const outPath of outPaths){
|
|
127
|
+
if (await pathExists(outPath) === false) {
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
await fs.rm(outPath);
|
|
131
|
+
logger.info(`Removed ${boldArtifact} types from ${chalk.bold(path.relative(process.cwd(), outPath))} (artifact disabled)`);
|
|
132
|
+
}
|
|
133
|
+
} catch (e) {
|
|
134
|
+
logger.error(`An error occurred while removing ${boldArtifact} types from the filesystem: ${e.message ?? e.toString()}. Exiting`);
|
|
135
|
+
return returnWithMessage();
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return returnWithMessage();
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
export { generate };
|
|
142
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../../src/generators/index.ts"],"sourcesContent":["import path from 'node:path';\nimport fs from 'node:fs/promises';\nimport chalk from 'chalk';\n\nimport { TYPES_ROOT_DIR, GENERATED_OUT_DIR } from './constants';\nimport { saveDefinitionToFileSystem, createLogger, timer, pathExists } from './utils';\nimport { generateContentTypesDefinitions } from './content-types';\nimport { generateComponentsDefinitions } from './components';\nimport { generatePluginDefinitions } from './plugins';\nimport { generateServicesDefinitions } from './services';\nimport { generateControllersDefinitions } from './controllers';\nimport { generatePoliciesDefinitions } from './policies';\nimport { generateMiddlewaresDefinitions } from './middlewares';\nimport { generateStrictDefinitions } from './strict';\n\nconst GENERATORS = {\n contentTypes: generateContentTypesDefinitions,\n components: generateComponentsDefinitions,\n plugins: generatePluginDefinitions,\n services: generateServicesDefinitions,\n controllers: generateControllersDefinitions,\n policies: generatePoliciesDefinitions,\n middlewares: generateMiddlewaresDefinitions,\n strict: generateStrictDefinitions,\n};\n\n/**\n * Artifacts written as `.ts` rather than `.d.ts`: they import the application's sources, and a\n * reference that no longer resolves (a moved source, a renamed contract) is reported by `tsc` even\n * with `skipLibCheck`, rather than silently typing the lookup as `any`. The other artifacts only\n * hold declarations generated from the schemas, and stay `.d.ts`.\n */\nconst SOURCE_ARTIFACTS = new Set(['services', 'controllers', 'policies', 'middlewares']);\n\n/**\n * The application's linters would check the `.ts` artifacts, whose helpers use `any`.\n */\nconst LINT_DISABLE_HEADER = '/* eslint-disable */\\n/* oxlint-disable */\\n';\n\nconst isSourceArtifact = (artifact: string) => SOURCE_ARTIFACTS.has(artifact);\n\nconst filenameOf = (artifact: string) =>\n isSourceArtifact(artifact) === true ? `${artifact}.ts` : `${artifact}.d.ts`;\n\n/**\n * File name an earlier generation wrote the artifact to, removed with the artifact's own file\n */\nconst previousFilenameOf = (artifact: string) =>\n isSourceArtifact(artifact) === true ? `${artifact}.d.ts` : undefined;\n\nexport interface GenerateConfig {\n strapi: any;\n pwd: string;\n rootDir?: string;\n /**\n * Artifacts to generate. `true` generates the artifact, `false` removes the file a previous\n * run may have generated for it, unset leaves it untouched.\n * `services`, `controllers`, `policies`, `middlewares` and `strict` are the strict types artifacts\n * (`typescript.strictTypes`).\n */\n artifacts?: {\n contentTypes?: boolean;\n components?: boolean;\n plugins?: boolean;\n services?: boolean;\n strict?: boolean;\n controllers?: boolean;\n policies?: boolean;\n middlewares?: boolean;\n };\n logger?: {\n silent?: boolean;\n debug?: boolean;\n verbose?: boolean;\n };\n}\n\n/**\n * Generate types definitions based on the given configuration\n */\nexport const generate = async (config: GenerateConfig = {} as GenerateConfig) => {\n const { pwd, rootDir = TYPES_ROOT_DIR, strapi, artifacts = {}, logger: loggerConfig } = config;\n const reports: Record<string, any> = {};\n const logger = createLogger(loggerConfig);\n const psTimer = timer().start();\n\n const registryPwd = path.join(pwd, rootDir, GENERATED_OUT_DIR);\n // Strict mode reads only the global schema registries, so schemas use that form with the opt-in.\n const strict = artifacts.strict === true;\n const generatorConfig = { strapi, pwd: registryPwd, appDir: pwd, logger, strict };\n\n const returnWithMessage = () => {\n const nbWarnings = chalk.yellow(`${logger.warnings} warning(s)`);\n const nbErrors = chalk.red(`${logger.errors} error(s)`);\n\n const status = logger.errors > 0 ? chalk.red('errored') : chalk.green('completed successfully');\n\n psTimer.end();\n\n logger.info(`The task ${status} with ${nbWarnings} and ${nbErrors} in ${psTimer.duration}s.`);\n\n return reports;\n };\n\n const enabledArtifacts = Object.keys(artifacts).filter(\n (p) => (artifacts as Record<string, boolean>)[p] === true\n );\n const disabledArtifacts = Object.keys(artifacts).filter(\n (p) => (artifacts as Record<string, boolean>)[p] === false && p in GENERATORS\n );\n\n logger.info('Starting the type generation process');\n logger.debug(`Enabled artifacts: ${enabledArtifacts.join(', ')}`);\n\n for (const artifact of enabledArtifacts) {\n const boldArtifact = chalk.bold(artifact); // used for log messages\n\n logger.info(`Generating types for ${boldArtifact}`);\n\n if (artifact in GENERATORS) {\n const generator = (GENERATORS as any)[artifact];\n\n try {\n const artifactGenTimer = timer().start();\n\n reports[artifact] = await generator(generatorConfig);\n\n artifactGenTimer.end();\n\n logger.debug(`Generated ${boldArtifact} in ${artifactGenTimer.duration}s`);\n } catch (e) {\n logger.error(\n `Failed to generate types for ${boldArtifact}: ${(e as any).message ?? (e as any).toString()}. Exiting`\n );\n return returnWithMessage();\n }\n } else {\n logger.warn(`The types generator for ${boldArtifact} is not implemented, skipping`);\n }\n }\n\n for (const artifact of Object.keys(reports)) {\n const boldArtifact = chalk.bold(artifact); // used for log messages\n\n const artifactFsTimer = timer().start();\n\n const report = reports[artifact];\n const filename = filenameOf(artifact);\n const previousFilename = previousFilenameOf(artifact);\n const content =\n isSourceArtifact(artifact) === true\n ? `${LINT_DISABLE_HEADER}${report.output}`\n : report.output;\n\n try {\n const outPath = await saveDefinitionToFileSystem(registryPwd, filename, content);\n\n // A stale `.d.ts` would declare the registry entries a second time\n if (previousFilename !== undefined) {\n await fs.rm(path.join(registryPwd, previousFilename), { force: true });\n }\n\n const relativeOutPath = path.relative(process.cwd(), outPath);\n\n artifactFsTimer.end();\n\n logger.info(`Saved ${boldArtifact} types in ${chalk.bold(relativeOutPath)}`);\n logger.debug(`Saved ${boldArtifact} in ${artifactFsTimer.duration}s`);\n } catch (e) {\n logger.error(\n `An error occurred while saving ${boldArtifact} types to the filesystem: ${\n (e as any).message ?? (e as any).toString()\n }. Exiting`\n );\n return returnWithMessage();\n }\n }\n\n // Disabled artifacts are removed so that a stale generated file does not keep applying\n for (const artifact of disabledArtifacts) {\n const boldArtifact = chalk.bold(artifact); // used for log messages\n const previousFilename = previousFilenameOf(artifact);\n const outPaths = [\n filenameOf(artifact),\n ...(previousFilename === undefined ? [] : [previousFilename]),\n ].map((filename) => path.join(registryPwd, filename));\n\n try {\n for (const outPath of outPaths) {\n if ((await pathExists(outPath)) === false) {\n continue;\n }\n\n await fs.rm(outPath);\n\n logger.info(\n `Removed ${boldArtifact} types from ${chalk.bold(path.relative(process.cwd(), outPath))} (artifact disabled)`\n );\n }\n } catch (e) {\n logger.error(\n `An error occurred while removing ${boldArtifact} types from the filesystem: ${\n (e as any).message ?? (e as any).toString()\n }. Exiting`\n );\n return returnWithMessage();\n }\n }\n\n return returnWithMessage();\n};\n"],"names":["GENERATORS","contentTypes","generateContentTypesDefinitions","components","generateComponentsDefinitions","plugins","generatePluginDefinitions","services","generateServicesDefinitions","controllers","generateControllersDefinitions","policies","generatePoliciesDefinitions","middlewares","generateMiddlewaresDefinitions","strict","generateStrictDefinitions","SOURCE_ARTIFACTS","Set","LINT_DISABLE_HEADER","isSourceArtifact","artifact","has","filenameOf","previousFilenameOf","undefined","generate","config","pwd","rootDir","TYPES_ROOT_DIR","strapi","artifacts","logger","loggerConfig","reports","createLogger","psTimer","timer","start","registryPwd","path","join","GENERATED_OUT_DIR","generatorConfig","appDir","returnWithMessage","nbWarnings","chalk","yellow","warnings","nbErrors","red","errors","status","green","end","info","duration","enabledArtifacts","Object","keys","filter","p","disabledArtifacts","debug","boldArtifact","bold","generator","artifactGenTimer","e","error","message","toString","warn","artifactFsTimer","report","filename","previousFilename","content","output","outPath","saveDefinitionToFileSystem","fs","rm","force","relativeOutPath","relative","process","cwd","outPaths","map","pathExists"],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { GeneratorOptions } from '../utils';
|
|
2
|
+
/**
|
|
3
|
+
* Generate type definitions for the application's middlewares (global::* and api::*)
|
|
4
|
+
*
|
|
5
|
+
* Middlewares are typed from their source file, so only the ones with a source in src/middlewares or
|
|
6
|
+
* src/api are emitted. Bundled middlewares (strapi::*, admin::*, plugin::*) are left to the packages
|
|
7
|
+
* themselves (Strapi.Registries.PackageMiddlewares), so registering application middlewares keeps
|
|
8
|
+
* them accepted.
|
|
9
|
+
*
|
|
10
|
+
* declare global {
|
|
11
|
+
* namespace Strapi {
|
|
12
|
+
* namespace Registries {
|
|
13
|
+
* interface AppMiddlewares {
|
|
14
|
+
* 'global::<middleware>': MiddlewareConfig<typeof import('<relative path to the source>')>;
|
|
15
|
+
* 'api::<api>.<middleware>': MiddlewareConfig<typeof import('<relative path to the source>')>;
|
|
16
|
+
* 'global::<js middleware>': unknown;
|
|
17
|
+
* }
|
|
18
|
+
* }
|
|
19
|
+
* }
|
|
20
|
+
* }
|
|
21
|
+
*
|
|
22
|
+
* Like JS policies (see the policies generator), JS middlewares are registered as `unknown` without
|
|
23
|
+
* an import.
|
|
24
|
+
* TODO @Nico with `allowJs`, a JSDoc-typed JS middleware could register its config like a TS one
|
|
25
|
+
*/
|
|
26
|
+
export declare const generateMiddlewaresDefinitions: (options?: GeneratorOptions) => Promise<{
|
|
27
|
+
output: string;
|
|
28
|
+
stats: {};
|
|
29
|
+
}>;
|
|
30
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/generators/middlewares/index.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AA4KjD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,8BAA8B,GACzC,UAAS,gBAAyC;;;EAoCnD,CAAC"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var ts = require('typescript');
|
|
4
|
+
var sources = require('../common/sources.js');
|
|
5
|
+
|
|
6
|
+
function _interopNamespace(e) {
|
|
7
|
+
if (e && e.__esModule) return e;
|
|
8
|
+
var n = Object.create(null);
|
|
9
|
+
if (e) {
|
|
10
|
+
Object.keys(e).forEach(function (k) {
|
|
11
|
+
if (k !== 'default') {
|
|
12
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
13
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
get: function () { return e[k]; }
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
n.default = e;
|
|
21
|
+
return Object.freeze(n);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
var ts__namespace = /*#__PURE__*/_interopNamespace(ts);
|
|
25
|
+
|
|
26
|
+
const { factory } = ts__namespace;
|
|
27
|
+
const REGISTRY = 'AppMiddlewares';
|
|
28
|
+
const CONFIG_HELPER = 'MiddlewareConfig';
|
|
29
|
+
const FACTORY_CONFIG_HELPER = 'MiddlewareFactoryConfig';
|
|
30
|
+
const NO_MIDDLEWARE_PLACEHOLDER_COMMENT = `/*
|
|
31
|
+
* The app doesn't have any middlewares yet.
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
export {};
|
|
35
|
+
`;
|
|
36
|
+
/**
|
|
37
|
+
* type MiddlewareFactoryConfig<TFactory> = TFactory extends (...args: infer TArgs) => unknown
|
|
38
|
+
* ? TFactory extends (config: never, ctx: { strapi: never }) => unknown
|
|
39
|
+
* ? TArgs['length'] extends 0
|
|
40
|
+
* ? undefined
|
|
41
|
+
* : 0 extends 1 & TArgs[0]
|
|
42
|
+
* ? unknown
|
|
43
|
+
* : TArgs[0] extends { request: unknown; response: unknown; app: unknown }
|
|
44
|
+
* ? never
|
|
45
|
+
* : TArgs[0]
|
|
46
|
+
* : never
|
|
47
|
+
* : unknown;
|
|
48
|
+
*
|
|
49
|
+
* type MiddlewareConfig<TModule> = TModule extends { default: infer TExport }
|
|
50
|
+
* ? MiddlewareFactoryConfig<TExport>
|
|
51
|
+
* : unknown;
|
|
52
|
+
*
|
|
53
|
+
* Emitted in the file so that middlewares.ts stands alone, and only when a TypeScript middleware
|
|
54
|
+
* reads them, like the policies helpers.
|
|
55
|
+
*
|
|
56
|
+
* Resolves the config a middleware accepts from the type of its module: the first parameter of the
|
|
57
|
+
* factory it exports. A factory without parameters takes no config: `undefined`, as in
|
|
58
|
+
* PackageMiddlewares. An optional parameter keeps `undefined` in the config, so typed routes accept
|
|
59
|
+
* the name alone. An untyped (`any`) config and a module without a default export resolve to
|
|
60
|
+
* `unknown`, as for policies.
|
|
61
|
+
* A plain Koa handler `(ctx, next)` is not a factory: runtime calls it with the config and
|
|
62
|
+
* `{ strapi }`, which breaks. A function whose second parameter cannot take `{ strapi }`
|
|
63
|
+
* (Core.MiddlewareFactory) registers `never`, so typed routes reject its name. `never` stands for
|
|
64
|
+
* the Strapi instance, so that the file needs no import and any context type a factory declares
|
|
65
|
+
* accepts it.
|
|
66
|
+
* A handler with one parameter `(ctx)`, or an untyped `next`, takes `{ strapi }`: a first parameter
|
|
67
|
+
* with the required members of a Koa context (`request`, `response`, `app`) registers `never` too.
|
|
68
|
+
* TODO @Nico a handler whose context is `any` still registers as a factory with an untyped config
|
|
69
|
+
* (`unknown`); an opt-in `defineMiddleware` brand (new factory helpers, D15) would tell them apart
|
|
70
|
+
* TODO @Nico a module without a default export registers `undefined` at runtime (a reference to it
|
|
71
|
+
* throws "Middleware <uid> not found"); `unknown` accepts any reference to it, like an untyped one
|
|
72
|
+
*/ const generateConfigHelpersDefinition = ()=>{
|
|
73
|
+
const args = factory.createTypeReferenceNode('TArgs');
|
|
74
|
+
const configArg = factory.createIndexedAccessTypeNode(args, factory.createLiteralTypeNode(factory.createNumericLiteral(0)));
|
|
75
|
+
const never = ()=>factory.createKeywordTypeNode(ts__namespace.SyntaxKind.NeverKeyword);
|
|
76
|
+
// (config: never, ctx: { strapi: never }) => unknown, what runtime calls a middleware with
|
|
77
|
+
const factorySignature = factory.createFunctionTypeNode(undefined, [
|
|
78
|
+
factory.createParameterDeclaration(undefined, undefined, 'config', undefined, never()),
|
|
79
|
+
factory.createParameterDeclaration(undefined, undefined, 'ctx', undefined, factory.createTypeLiteralNode([
|
|
80
|
+
factory.createPropertySignature(undefined, 'strapi', undefined, never())
|
|
81
|
+
]))
|
|
82
|
+
], factory.createKeywordTypeNode(ts__namespace.SyntaxKind.UnknownKeyword));
|
|
83
|
+
// { request: unknown; response: unknown; app: unknown }, required members of a Koa context
|
|
84
|
+
const koaContextShape = factory.createTypeLiteralNode([
|
|
85
|
+
'request',
|
|
86
|
+
'response',
|
|
87
|
+
'app'
|
|
88
|
+
].map((member)=>factory.createPropertySignature(undefined, member, undefined, factory.createKeywordTypeNode(ts__namespace.SyntaxKind.UnknownKeyword))));
|
|
89
|
+
const factoryConfig = factory.createConditionalTypeNode(factory.createTypeReferenceNode('TFactory'), factory.createFunctionTypeNode(undefined, [
|
|
90
|
+
factory.createParameterDeclaration(undefined, factory.createToken(ts__namespace.SyntaxKind.DotDotDotToken), 'args', undefined, factory.createInferTypeNode(factory.createTypeParameterDeclaration(undefined, 'TArgs')))
|
|
91
|
+
], factory.createKeywordTypeNode(ts__namespace.SyntaxKind.UnknownKeyword)), factory.createConditionalTypeNode(factory.createTypeReferenceNode('TFactory'), factorySignature, factory.createConditionalTypeNode(factory.createIndexedAccessTypeNode(args, factory.createLiteralTypeNode(factory.createStringLiteral('length', true))), factory.createLiteralTypeNode(factory.createNumericLiteral(0)), factory.createKeywordTypeNode(ts__namespace.SyntaxKind.UndefinedKeyword), // 0 extends 1 & TArgs[0], true only when the config is `any`
|
|
92
|
+
factory.createConditionalTypeNode(factory.createLiteralTypeNode(factory.createNumericLiteral(0)), factory.createIntersectionTypeNode([
|
|
93
|
+
factory.createLiteralTypeNode(factory.createNumericLiteral(1)),
|
|
94
|
+
configArg
|
|
95
|
+
]), factory.createKeywordTypeNode(ts__namespace.SyntaxKind.UnknownKeyword), // A Koa handler (ctx) or (ctx, next: any): its first parameter is a context
|
|
96
|
+
factory.createConditionalTypeNode(configArg, koaContextShape, never(), configArg))), // A Koa handler (ctx, next): its `next` cannot take `{ strapi }`
|
|
97
|
+
never()), factory.createKeywordTypeNode(ts__namespace.SyntaxKind.UnknownKeyword));
|
|
98
|
+
const moduleConfig = factory.createConditionalTypeNode(factory.createTypeReferenceNode('TModule'), factory.createTypeLiteralNode([
|
|
99
|
+
factory.createPropertySignature(undefined, 'default', undefined, factory.createInferTypeNode(factory.createTypeParameterDeclaration(undefined, 'TExport')))
|
|
100
|
+
]), factory.createTypeReferenceNode(FACTORY_CONFIG_HELPER, [
|
|
101
|
+
factory.createTypeReferenceNode('TExport')
|
|
102
|
+
]), factory.createKeywordTypeNode(ts__namespace.SyntaxKind.UnknownKeyword));
|
|
103
|
+
return [
|
|
104
|
+
sources.withDocComment(factory.createTypeAliasDeclaration(undefined, factory.createIdentifier(FACTORY_CONFIG_HELPER), [
|
|
105
|
+
factory.createTypeParameterDeclaration(undefined, 'TFactory')
|
|
106
|
+
], factoryConfig), '*\n * Config a middleware factory accepts: its first parameter, `undefined` when it has none,\n * `unknown` when it is untyped, `never` when the function is not a factory (a Koa handler).\n '),
|
|
107
|
+
sources.withDocComment(factory.createTypeAliasDeclaration(undefined, factory.createIdentifier(CONFIG_HELPER), [
|
|
108
|
+
factory.createTypeParameterDeclaration(undefined, 'TModule')
|
|
109
|
+
], moduleConfig), '*\n * Config accepted by the factory a middleware module exports.\n ')
|
|
110
|
+
];
|
|
111
|
+
};
|
|
112
|
+
/**
|
|
113
|
+
* Generate type definitions for the application's middlewares (global::* and api::*)
|
|
114
|
+
*
|
|
115
|
+
* Middlewares are typed from their source file, so only the ones with a source in src/middlewares or
|
|
116
|
+
* src/api are emitted. Bundled middlewares (strapi::*, admin::*, plugin::*) are left to the packages
|
|
117
|
+
* themselves (Strapi.Registries.PackageMiddlewares), so registering application middlewares keeps
|
|
118
|
+
* them accepted.
|
|
119
|
+
*
|
|
120
|
+
* declare global {
|
|
121
|
+
* namespace Strapi {
|
|
122
|
+
* namespace Registries {
|
|
123
|
+
* interface AppMiddlewares {
|
|
124
|
+
* 'global::<middleware>': MiddlewareConfig<typeof import('<relative path to the source>')>;
|
|
125
|
+
* 'api::<api>.<middleware>': MiddlewareConfig<typeof import('<relative path to the source>')>;
|
|
126
|
+
* 'global::<js middleware>': unknown;
|
|
127
|
+
* }
|
|
128
|
+
* }
|
|
129
|
+
* }
|
|
130
|
+
* }
|
|
131
|
+
*
|
|
132
|
+
* Like JS policies (see the policies generator), JS middlewares are registered as `unknown` without
|
|
133
|
+
* an import.
|
|
134
|
+
* TODO @Nico with `allowJs`, a JSDoc-typed JS middleware could register its config like a TS one
|
|
135
|
+
*/ const generateMiddlewaresDefinitions = async (options = {})=>{
|
|
136
|
+
const { strapi, logger, pwd: outDir } = options;
|
|
137
|
+
if (!outDir) {
|
|
138
|
+
throw new Error('The middlewares generator needs the output directory to resolve source imports');
|
|
139
|
+
}
|
|
140
|
+
const sources$1 = await sources.collectAppSources('middlewares', {
|
|
141
|
+
global: strapi.dirs.app.middlewares,
|
|
142
|
+
api: strapi.dirs.app.api
|
|
143
|
+
}, outDir, logger);
|
|
144
|
+
const middlewaresDefinitions = sources.filterRegisteredSources(sources$1, strapi.middlewares, logger);
|
|
145
|
+
logger.debug(`Found ${middlewaresDefinitions.length} middlewares.`);
|
|
146
|
+
if (middlewaresDefinitions.length === 0) {
|
|
147
|
+
return {
|
|
148
|
+
output: NO_MIDDLEWARE_PLACEHOLDER_COMMENT,
|
|
149
|
+
stats: {}
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
// The helpers are only emitted when an entry reads them: `noUnusedLocals` reports unused ones
|
|
153
|
+
const output = await sources.emitRegistryDefinitions(REGISTRY, middlewaresDefinitions.some(sources.isTypedSource) === true ? generateConfigHelpersDefinition() : [], middlewaresDefinitions, (source)=>sources.isTypedSource(source) ? factory.createTypeReferenceNode(CONFIG_HELPER, [
|
|
154
|
+
sources.typeofImport(source)
|
|
155
|
+
]) : factory.createKeywordTypeNode(ts__namespace.SyntaxKind.UnknownKeyword));
|
|
156
|
+
return {
|
|
157
|
+
output,
|
|
158
|
+
stats: {}
|
|
159
|
+
};
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
exports.generateMiddlewaresDefinitions = generateMiddlewaresDefinitions;
|
|
163
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/generators/middlewares/index.ts"],"sourcesContent":["import * as ts from 'typescript';\n\nimport {\n collectAppSources,\n emitRegistryDefinitions,\n filterRegisteredSources,\n isTypedSource,\n typeofImport,\n withDocComment,\n} from '../common/sources';\nimport type { GeneratorOptions } from '../utils';\n\nconst { factory } = ts;\n\nconst REGISTRY = 'AppMiddlewares';\nconst CONFIG_HELPER = 'MiddlewareConfig';\nconst FACTORY_CONFIG_HELPER = 'MiddlewareFactoryConfig';\n\nconst NO_MIDDLEWARE_PLACEHOLDER_COMMENT = `/*\n * The app doesn't have any middlewares yet.\n */\n\nexport {};\n`;\n\n/**\n * type MiddlewareFactoryConfig<TFactory> = TFactory extends (...args: infer TArgs) => unknown\n * ? TFactory extends (config: never, ctx: { strapi: never }) => unknown\n * ? TArgs['length'] extends 0\n * ? undefined\n * : 0 extends 1 & TArgs[0]\n * ? unknown\n * : TArgs[0] extends { request: unknown; response: unknown; app: unknown }\n * ? never\n * : TArgs[0]\n * : never\n * : unknown;\n *\n * type MiddlewareConfig<TModule> = TModule extends { default: infer TExport }\n * ? MiddlewareFactoryConfig<TExport>\n * : unknown;\n *\n * Emitted in the file so that middlewares.ts stands alone, and only when a TypeScript middleware\n * reads them, like the policies helpers.\n *\n * Resolves the config a middleware accepts from the type of its module: the first parameter of the\n * factory it exports. A factory without parameters takes no config: `undefined`, as in\n * PackageMiddlewares. An optional parameter keeps `undefined` in the config, so typed routes accept\n * the name alone. An untyped (`any`) config and a module without a default export resolve to\n * `unknown`, as for policies.\n * A plain Koa handler `(ctx, next)` is not a factory: runtime calls it with the config and\n * `{ strapi }`, which breaks. A function whose second parameter cannot take `{ strapi }`\n * (Core.MiddlewareFactory) registers `never`, so typed routes reject its name. `never` stands for\n * the Strapi instance, so that the file needs no import and any context type a factory declares\n * accepts it.\n * A handler with one parameter `(ctx)`, or an untyped `next`, takes `{ strapi }`: a first parameter\n * with the required members of a Koa context (`request`, `response`, `app`) registers `never` too.\n * TODO @Nico a handler whose context is `any` still registers as a factory with an untyped config\n * (`unknown`); an opt-in `defineMiddleware` brand (new factory helpers, D15) would tell them apart\n * TODO @Nico a module without a default export registers `undefined` at runtime (a reference to it\n * throws \"Middleware <uid> not found\"); `unknown` accepts any reference to it, like an untyped one\n */\nconst generateConfigHelpersDefinition = () => {\n const args = factory.createTypeReferenceNode('TArgs');\n const configArg = factory.createIndexedAccessTypeNode(\n args,\n factory.createLiteralTypeNode(factory.createNumericLiteral(0))\n );\n\n const never = () => factory.createKeywordTypeNode(ts.SyntaxKind.NeverKeyword);\n\n // (config: never, ctx: { strapi: never }) => unknown, what runtime calls a middleware with\n const factorySignature = factory.createFunctionTypeNode(\n undefined,\n [\n factory.createParameterDeclaration(undefined, undefined, 'config', undefined, never()),\n factory.createParameterDeclaration(\n undefined,\n undefined,\n 'ctx',\n undefined,\n factory.createTypeLiteralNode([\n factory.createPropertySignature(undefined, 'strapi', undefined, never()),\n ])\n ),\n ],\n factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword)\n );\n\n // { request: unknown; response: unknown; app: unknown }, required members of a Koa context\n const koaContextShape = factory.createTypeLiteralNode(\n ['request', 'response', 'app'].map((member) =>\n factory.createPropertySignature(\n undefined,\n member,\n undefined,\n factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword)\n )\n )\n );\n\n const factoryConfig = factory.createConditionalTypeNode(\n factory.createTypeReferenceNode('TFactory'),\n factory.createFunctionTypeNode(\n undefined,\n [\n factory.createParameterDeclaration(\n undefined,\n factory.createToken(ts.SyntaxKind.DotDotDotToken),\n 'args',\n undefined,\n factory.createInferTypeNode(factory.createTypeParameterDeclaration(undefined, 'TArgs'))\n ),\n ],\n factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword)\n ),\n factory.createConditionalTypeNode(\n factory.createTypeReferenceNode('TFactory'),\n factorySignature,\n factory.createConditionalTypeNode(\n factory.createIndexedAccessTypeNode(\n args,\n factory.createLiteralTypeNode(factory.createStringLiteral('length', true))\n ),\n factory.createLiteralTypeNode(factory.createNumericLiteral(0)),\n factory.createKeywordTypeNode(ts.SyntaxKind.UndefinedKeyword),\n // 0 extends 1 & TArgs[0], true only when the config is `any`\n factory.createConditionalTypeNode(\n factory.createLiteralTypeNode(factory.createNumericLiteral(0)),\n factory.createIntersectionTypeNode([\n factory.createLiteralTypeNode(factory.createNumericLiteral(1)),\n configArg,\n ]),\n factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword),\n // A Koa handler (ctx) or (ctx, next: any): its first parameter is a context\n factory.createConditionalTypeNode(configArg, koaContextShape, never(), configArg)\n )\n ),\n // A Koa handler (ctx, next): its `next` cannot take `{ strapi }`\n never()\n ),\n factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword)\n );\n\n const moduleConfig = factory.createConditionalTypeNode(\n factory.createTypeReferenceNode('TModule'),\n factory.createTypeLiteralNode([\n factory.createPropertySignature(\n undefined,\n 'default',\n undefined,\n factory.createInferTypeNode(factory.createTypeParameterDeclaration(undefined, 'TExport'))\n ),\n ]),\n factory.createTypeReferenceNode(FACTORY_CONFIG_HELPER, [\n factory.createTypeReferenceNode('TExport'),\n ]),\n factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword)\n );\n\n return [\n withDocComment(\n factory.createTypeAliasDeclaration(\n undefined,\n factory.createIdentifier(FACTORY_CONFIG_HELPER),\n [factory.createTypeParameterDeclaration(undefined, 'TFactory')],\n factoryConfig\n ),\n '*\\n * Config a middleware factory accepts: its first parameter, `undefined` when it has none,\\n * `unknown` when it is untyped, `never` when the function is not a factory (a Koa handler).\\n '\n ),\n withDocComment(\n factory.createTypeAliasDeclaration(\n undefined,\n factory.createIdentifier(CONFIG_HELPER),\n [factory.createTypeParameterDeclaration(undefined, 'TModule')],\n moduleConfig\n ),\n '*\\n * Config accepted by the factory a middleware module exports.\\n '\n ),\n ];\n};\n\n/**\n * Generate type definitions for the application's middlewares (global::* and api::*)\n *\n * Middlewares are typed from their source file, so only the ones with a source in src/middlewares or\n * src/api are emitted. Bundled middlewares (strapi::*, admin::*, plugin::*) are left to the packages\n * themselves (Strapi.Registries.PackageMiddlewares), so registering application middlewares keeps\n * them accepted.\n *\n * declare global {\n * namespace Strapi {\n * namespace Registries {\n * interface AppMiddlewares {\n * 'global::<middleware>': MiddlewareConfig<typeof import('<relative path to the source>')>;\n * 'api::<api>.<middleware>': MiddlewareConfig<typeof import('<relative path to the source>')>;\n * 'global::<js middleware>': unknown;\n * }\n * }\n * }\n * }\n *\n * Like JS policies (see the policies generator), JS middlewares are registered as `unknown` without\n * an import.\n * TODO @Nico with `allowJs`, a JSDoc-typed JS middleware could register its config like a TS one\n */\nexport const generateMiddlewaresDefinitions = async (\n options: GeneratorOptions = {} as GeneratorOptions\n) => {\n const { strapi, logger, pwd: outDir } = options;\n\n if (!outDir) {\n throw new Error(\n 'The middlewares generator needs the output directory to resolve source imports'\n );\n }\n\n const sources = await collectAppSources(\n 'middlewares',\n { global: strapi.dirs.app.middlewares, api: strapi.dirs.app.api },\n outDir,\n logger\n );\n const middlewaresDefinitions = filterRegisteredSources(sources, strapi.middlewares, logger);\n\n logger.debug(`Found ${middlewaresDefinitions.length} middlewares.`);\n\n if (middlewaresDefinitions.length === 0) {\n return { output: NO_MIDDLEWARE_PLACEHOLDER_COMMENT, stats: {} };\n }\n\n // The helpers are only emitted when an entry reads them: `noUnusedLocals` reports unused ones\n const output = await emitRegistryDefinitions(\n REGISTRY,\n middlewaresDefinitions.some(isTypedSource) === true ? generateConfigHelpersDefinition() : [],\n middlewaresDefinitions,\n (source) =>\n isTypedSource(source)\n ? factory.createTypeReferenceNode(CONFIG_HELPER, [typeofImport(source)])\n : factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword)\n );\n\n return { output, stats: {} };\n};\n"],"names":["factory","ts","REGISTRY","CONFIG_HELPER","FACTORY_CONFIG_HELPER","NO_MIDDLEWARE_PLACEHOLDER_COMMENT","generateConfigHelpersDefinition","args","createTypeReferenceNode","configArg","createIndexedAccessTypeNode","createLiteralTypeNode","createNumericLiteral","never","createKeywordTypeNode","SyntaxKind","NeverKeyword","factorySignature","createFunctionTypeNode","undefined","createParameterDeclaration","createTypeLiteralNode","createPropertySignature","UnknownKeyword","koaContextShape","map","member","factoryConfig","createConditionalTypeNode","createToken","DotDotDotToken","createInferTypeNode","createTypeParameterDeclaration","createStringLiteral","UndefinedKeyword","createIntersectionTypeNode","moduleConfig","withDocComment","createTypeAliasDeclaration","createIdentifier","generateMiddlewaresDefinitions","options","strapi","logger","pwd","outDir","Error","sources","collectAppSources","global","dirs","app","middlewares","api","middlewaresDefinitions","filterRegisteredSources","debug","length","output","stats","emitRegistryDefinitions","some","isTypedSource","source","typeofImport"],"mappings":"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"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import * as ts from 'typescript';
|
|
2
|
+
import { collectAppSources, filterRegisteredSources, emitRegistryDefinitions, isTypedSource, withDocComment, typeofImport } from '../common/sources.mjs';
|
|
3
|
+
|
|
4
|
+
const { factory } = ts;
|
|
5
|
+
const REGISTRY = 'AppMiddlewares';
|
|
6
|
+
const CONFIG_HELPER = 'MiddlewareConfig';
|
|
7
|
+
const FACTORY_CONFIG_HELPER = 'MiddlewareFactoryConfig';
|
|
8
|
+
const NO_MIDDLEWARE_PLACEHOLDER_COMMENT = `/*
|
|
9
|
+
* The app doesn't have any middlewares yet.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
export {};
|
|
13
|
+
`;
|
|
14
|
+
/**
|
|
15
|
+
* type MiddlewareFactoryConfig<TFactory> = TFactory extends (...args: infer TArgs) => unknown
|
|
16
|
+
* ? TFactory extends (config: never, ctx: { strapi: never }) => unknown
|
|
17
|
+
* ? TArgs['length'] extends 0
|
|
18
|
+
* ? undefined
|
|
19
|
+
* : 0 extends 1 & TArgs[0]
|
|
20
|
+
* ? unknown
|
|
21
|
+
* : TArgs[0] extends { request: unknown; response: unknown; app: unknown }
|
|
22
|
+
* ? never
|
|
23
|
+
* : TArgs[0]
|
|
24
|
+
* : never
|
|
25
|
+
* : unknown;
|
|
26
|
+
*
|
|
27
|
+
* type MiddlewareConfig<TModule> = TModule extends { default: infer TExport }
|
|
28
|
+
* ? MiddlewareFactoryConfig<TExport>
|
|
29
|
+
* : unknown;
|
|
30
|
+
*
|
|
31
|
+
* Emitted in the file so that middlewares.ts stands alone, and only when a TypeScript middleware
|
|
32
|
+
* reads them, like the policies helpers.
|
|
33
|
+
*
|
|
34
|
+
* Resolves the config a middleware accepts from the type of its module: the first parameter of the
|
|
35
|
+
* factory it exports. A factory without parameters takes no config: `undefined`, as in
|
|
36
|
+
* PackageMiddlewares. An optional parameter keeps `undefined` in the config, so typed routes accept
|
|
37
|
+
* the name alone. An untyped (`any`) config and a module without a default export resolve to
|
|
38
|
+
* `unknown`, as for policies.
|
|
39
|
+
* A plain Koa handler `(ctx, next)` is not a factory: runtime calls it with the config and
|
|
40
|
+
* `{ strapi }`, which breaks. A function whose second parameter cannot take `{ strapi }`
|
|
41
|
+
* (Core.MiddlewareFactory) registers `never`, so typed routes reject its name. `never` stands for
|
|
42
|
+
* the Strapi instance, so that the file needs no import and any context type a factory declares
|
|
43
|
+
* accepts it.
|
|
44
|
+
* A handler with one parameter `(ctx)`, or an untyped `next`, takes `{ strapi }`: a first parameter
|
|
45
|
+
* with the required members of a Koa context (`request`, `response`, `app`) registers `never` too.
|
|
46
|
+
* TODO @Nico a handler whose context is `any` still registers as a factory with an untyped config
|
|
47
|
+
* (`unknown`); an opt-in `defineMiddleware` brand (new factory helpers, D15) would tell them apart
|
|
48
|
+
* TODO @Nico a module without a default export registers `undefined` at runtime (a reference to it
|
|
49
|
+
* throws "Middleware <uid> not found"); `unknown` accepts any reference to it, like an untyped one
|
|
50
|
+
*/ const generateConfigHelpersDefinition = ()=>{
|
|
51
|
+
const args = factory.createTypeReferenceNode('TArgs');
|
|
52
|
+
const configArg = factory.createIndexedAccessTypeNode(args, factory.createLiteralTypeNode(factory.createNumericLiteral(0)));
|
|
53
|
+
const never = ()=>factory.createKeywordTypeNode(ts.SyntaxKind.NeverKeyword);
|
|
54
|
+
// (config: never, ctx: { strapi: never }) => unknown, what runtime calls a middleware with
|
|
55
|
+
const factorySignature = factory.createFunctionTypeNode(undefined, [
|
|
56
|
+
factory.createParameterDeclaration(undefined, undefined, 'config', undefined, never()),
|
|
57
|
+
factory.createParameterDeclaration(undefined, undefined, 'ctx', undefined, factory.createTypeLiteralNode([
|
|
58
|
+
factory.createPropertySignature(undefined, 'strapi', undefined, never())
|
|
59
|
+
]))
|
|
60
|
+
], factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword));
|
|
61
|
+
// { request: unknown; response: unknown; app: unknown }, required members of a Koa context
|
|
62
|
+
const koaContextShape = factory.createTypeLiteralNode([
|
|
63
|
+
'request',
|
|
64
|
+
'response',
|
|
65
|
+
'app'
|
|
66
|
+
].map((member)=>factory.createPropertySignature(undefined, member, undefined, factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword))));
|
|
67
|
+
const factoryConfig = factory.createConditionalTypeNode(factory.createTypeReferenceNode('TFactory'), factory.createFunctionTypeNode(undefined, [
|
|
68
|
+
factory.createParameterDeclaration(undefined, factory.createToken(ts.SyntaxKind.DotDotDotToken), 'args', undefined, factory.createInferTypeNode(factory.createTypeParameterDeclaration(undefined, 'TArgs')))
|
|
69
|
+
], factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword)), factory.createConditionalTypeNode(factory.createTypeReferenceNode('TFactory'), factorySignature, factory.createConditionalTypeNode(factory.createIndexedAccessTypeNode(args, factory.createLiteralTypeNode(factory.createStringLiteral('length', true))), factory.createLiteralTypeNode(factory.createNumericLiteral(0)), factory.createKeywordTypeNode(ts.SyntaxKind.UndefinedKeyword), // 0 extends 1 & TArgs[0], true only when the config is `any`
|
|
70
|
+
factory.createConditionalTypeNode(factory.createLiteralTypeNode(factory.createNumericLiteral(0)), factory.createIntersectionTypeNode([
|
|
71
|
+
factory.createLiteralTypeNode(factory.createNumericLiteral(1)),
|
|
72
|
+
configArg
|
|
73
|
+
]), factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword), // A Koa handler (ctx) or (ctx, next: any): its first parameter is a context
|
|
74
|
+
factory.createConditionalTypeNode(configArg, koaContextShape, never(), configArg))), // A Koa handler (ctx, next): its `next` cannot take `{ strapi }`
|
|
75
|
+
never()), factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword));
|
|
76
|
+
const moduleConfig = factory.createConditionalTypeNode(factory.createTypeReferenceNode('TModule'), factory.createTypeLiteralNode([
|
|
77
|
+
factory.createPropertySignature(undefined, 'default', undefined, factory.createInferTypeNode(factory.createTypeParameterDeclaration(undefined, 'TExport')))
|
|
78
|
+
]), factory.createTypeReferenceNode(FACTORY_CONFIG_HELPER, [
|
|
79
|
+
factory.createTypeReferenceNode('TExport')
|
|
80
|
+
]), factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword));
|
|
81
|
+
return [
|
|
82
|
+
withDocComment(factory.createTypeAliasDeclaration(undefined, factory.createIdentifier(FACTORY_CONFIG_HELPER), [
|
|
83
|
+
factory.createTypeParameterDeclaration(undefined, 'TFactory')
|
|
84
|
+
], factoryConfig), '*\n * Config a middleware factory accepts: its first parameter, `undefined` when it has none,\n * `unknown` when it is untyped, `never` when the function is not a factory (a Koa handler).\n '),
|
|
85
|
+
withDocComment(factory.createTypeAliasDeclaration(undefined, factory.createIdentifier(CONFIG_HELPER), [
|
|
86
|
+
factory.createTypeParameterDeclaration(undefined, 'TModule')
|
|
87
|
+
], moduleConfig), '*\n * Config accepted by the factory a middleware module exports.\n ')
|
|
88
|
+
];
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* Generate type definitions for the application's middlewares (global::* and api::*)
|
|
92
|
+
*
|
|
93
|
+
* Middlewares are typed from their source file, so only the ones with a source in src/middlewares or
|
|
94
|
+
* src/api are emitted. Bundled middlewares (strapi::*, admin::*, plugin::*) are left to the packages
|
|
95
|
+
* themselves (Strapi.Registries.PackageMiddlewares), so registering application middlewares keeps
|
|
96
|
+
* them accepted.
|
|
97
|
+
*
|
|
98
|
+
* declare global {
|
|
99
|
+
* namespace Strapi {
|
|
100
|
+
* namespace Registries {
|
|
101
|
+
* interface AppMiddlewares {
|
|
102
|
+
* 'global::<middleware>': MiddlewareConfig<typeof import('<relative path to the source>')>;
|
|
103
|
+
* 'api::<api>.<middleware>': MiddlewareConfig<typeof import('<relative path to the source>')>;
|
|
104
|
+
* 'global::<js middleware>': unknown;
|
|
105
|
+
* }
|
|
106
|
+
* }
|
|
107
|
+
* }
|
|
108
|
+
* }
|
|
109
|
+
*
|
|
110
|
+
* Like JS policies (see the policies generator), JS middlewares are registered as `unknown` without
|
|
111
|
+
* an import.
|
|
112
|
+
* TODO @Nico with `allowJs`, a JSDoc-typed JS middleware could register its config like a TS one
|
|
113
|
+
*/ const generateMiddlewaresDefinitions = async (options = {})=>{
|
|
114
|
+
const { strapi, logger, pwd: outDir } = options;
|
|
115
|
+
if (!outDir) {
|
|
116
|
+
throw new Error('The middlewares generator needs the output directory to resolve source imports');
|
|
117
|
+
}
|
|
118
|
+
const sources = await collectAppSources('middlewares', {
|
|
119
|
+
global: strapi.dirs.app.middlewares,
|
|
120
|
+
api: strapi.dirs.app.api
|
|
121
|
+
}, outDir, logger);
|
|
122
|
+
const middlewaresDefinitions = filterRegisteredSources(sources, strapi.middlewares, logger);
|
|
123
|
+
logger.debug(`Found ${middlewaresDefinitions.length} middlewares.`);
|
|
124
|
+
if (middlewaresDefinitions.length === 0) {
|
|
125
|
+
return {
|
|
126
|
+
output: NO_MIDDLEWARE_PLACEHOLDER_COMMENT,
|
|
127
|
+
stats: {}
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
// The helpers are only emitted when an entry reads them: `noUnusedLocals` reports unused ones
|
|
131
|
+
const output = await emitRegistryDefinitions(REGISTRY, middlewaresDefinitions.some(isTypedSource) === true ? generateConfigHelpersDefinition() : [], middlewaresDefinitions, (source)=>isTypedSource(source) ? factory.createTypeReferenceNode(CONFIG_HELPER, [
|
|
132
|
+
typeofImport(source)
|
|
133
|
+
]) : factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword));
|
|
134
|
+
return {
|
|
135
|
+
output,
|
|
136
|
+
stats: {}
|
|
137
|
+
};
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
export { generateMiddlewaresDefinitions };
|
|
141
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../../../src/generators/middlewares/index.ts"],"sourcesContent":["import * as ts from 'typescript';\n\nimport {\n collectAppSources,\n emitRegistryDefinitions,\n filterRegisteredSources,\n isTypedSource,\n typeofImport,\n withDocComment,\n} from '../common/sources';\nimport type { GeneratorOptions } from '../utils';\n\nconst { factory } = ts;\n\nconst REGISTRY = 'AppMiddlewares';\nconst CONFIG_HELPER = 'MiddlewareConfig';\nconst FACTORY_CONFIG_HELPER = 'MiddlewareFactoryConfig';\n\nconst NO_MIDDLEWARE_PLACEHOLDER_COMMENT = `/*\n * The app doesn't have any middlewares yet.\n */\n\nexport {};\n`;\n\n/**\n * type MiddlewareFactoryConfig<TFactory> = TFactory extends (...args: infer TArgs) => unknown\n * ? TFactory extends (config: never, ctx: { strapi: never }) => unknown\n * ? TArgs['length'] extends 0\n * ? undefined\n * : 0 extends 1 & TArgs[0]\n * ? unknown\n * : TArgs[0] extends { request: unknown; response: unknown; app: unknown }\n * ? never\n * : TArgs[0]\n * : never\n * : unknown;\n *\n * type MiddlewareConfig<TModule> = TModule extends { default: infer TExport }\n * ? MiddlewareFactoryConfig<TExport>\n * : unknown;\n *\n * Emitted in the file so that middlewares.ts stands alone, and only when a TypeScript middleware\n * reads them, like the policies helpers.\n *\n * Resolves the config a middleware accepts from the type of its module: the first parameter of the\n * factory it exports. A factory without parameters takes no config: `undefined`, as in\n * PackageMiddlewares. An optional parameter keeps `undefined` in the config, so typed routes accept\n * the name alone. An untyped (`any`) config and a module without a default export resolve to\n * `unknown`, as for policies.\n * A plain Koa handler `(ctx, next)` is not a factory: runtime calls it with the config and\n * `{ strapi }`, which breaks. A function whose second parameter cannot take `{ strapi }`\n * (Core.MiddlewareFactory) registers `never`, so typed routes reject its name. `never` stands for\n * the Strapi instance, so that the file needs no import and any context type a factory declares\n * accepts it.\n * A handler with one parameter `(ctx)`, or an untyped `next`, takes `{ strapi }`: a first parameter\n * with the required members of a Koa context (`request`, `response`, `app`) registers `never` too.\n * TODO @Nico a handler whose context is `any` still registers as a factory with an untyped config\n * (`unknown`); an opt-in `defineMiddleware` brand (new factory helpers, D15) would tell them apart\n * TODO @Nico a module without a default export registers `undefined` at runtime (a reference to it\n * throws \"Middleware <uid> not found\"); `unknown` accepts any reference to it, like an untyped one\n */\nconst generateConfigHelpersDefinition = () => {\n const args = factory.createTypeReferenceNode('TArgs');\n const configArg = factory.createIndexedAccessTypeNode(\n args,\n factory.createLiteralTypeNode(factory.createNumericLiteral(0))\n );\n\n const never = () => factory.createKeywordTypeNode(ts.SyntaxKind.NeverKeyword);\n\n // (config: never, ctx: { strapi: never }) => unknown, what runtime calls a middleware with\n const factorySignature = factory.createFunctionTypeNode(\n undefined,\n [\n factory.createParameterDeclaration(undefined, undefined, 'config', undefined, never()),\n factory.createParameterDeclaration(\n undefined,\n undefined,\n 'ctx',\n undefined,\n factory.createTypeLiteralNode([\n factory.createPropertySignature(undefined, 'strapi', undefined, never()),\n ])\n ),\n ],\n factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword)\n );\n\n // { request: unknown; response: unknown; app: unknown }, required members of a Koa context\n const koaContextShape = factory.createTypeLiteralNode(\n ['request', 'response', 'app'].map((member) =>\n factory.createPropertySignature(\n undefined,\n member,\n undefined,\n factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword)\n )\n )\n );\n\n const factoryConfig = factory.createConditionalTypeNode(\n factory.createTypeReferenceNode('TFactory'),\n factory.createFunctionTypeNode(\n undefined,\n [\n factory.createParameterDeclaration(\n undefined,\n factory.createToken(ts.SyntaxKind.DotDotDotToken),\n 'args',\n undefined,\n factory.createInferTypeNode(factory.createTypeParameterDeclaration(undefined, 'TArgs'))\n ),\n ],\n factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword)\n ),\n factory.createConditionalTypeNode(\n factory.createTypeReferenceNode('TFactory'),\n factorySignature,\n factory.createConditionalTypeNode(\n factory.createIndexedAccessTypeNode(\n args,\n factory.createLiteralTypeNode(factory.createStringLiteral('length', true))\n ),\n factory.createLiteralTypeNode(factory.createNumericLiteral(0)),\n factory.createKeywordTypeNode(ts.SyntaxKind.UndefinedKeyword),\n // 0 extends 1 & TArgs[0], true only when the config is `any`\n factory.createConditionalTypeNode(\n factory.createLiteralTypeNode(factory.createNumericLiteral(0)),\n factory.createIntersectionTypeNode([\n factory.createLiteralTypeNode(factory.createNumericLiteral(1)),\n configArg,\n ]),\n factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword),\n // A Koa handler (ctx) or (ctx, next: any): its first parameter is a context\n factory.createConditionalTypeNode(configArg, koaContextShape, never(), configArg)\n )\n ),\n // A Koa handler (ctx, next): its `next` cannot take `{ strapi }`\n never()\n ),\n factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword)\n );\n\n const moduleConfig = factory.createConditionalTypeNode(\n factory.createTypeReferenceNode('TModule'),\n factory.createTypeLiteralNode([\n factory.createPropertySignature(\n undefined,\n 'default',\n undefined,\n factory.createInferTypeNode(factory.createTypeParameterDeclaration(undefined, 'TExport'))\n ),\n ]),\n factory.createTypeReferenceNode(FACTORY_CONFIG_HELPER, [\n factory.createTypeReferenceNode('TExport'),\n ]),\n factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword)\n );\n\n return [\n withDocComment(\n factory.createTypeAliasDeclaration(\n undefined,\n factory.createIdentifier(FACTORY_CONFIG_HELPER),\n [factory.createTypeParameterDeclaration(undefined, 'TFactory')],\n factoryConfig\n ),\n '*\\n * Config a middleware factory accepts: its first parameter, `undefined` when it has none,\\n * `unknown` when it is untyped, `never` when the function is not a factory (a Koa handler).\\n '\n ),\n withDocComment(\n factory.createTypeAliasDeclaration(\n undefined,\n factory.createIdentifier(CONFIG_HELPER),\n [factory.createTypeParameterDeclaration(undefined, 'TModule')],\n moduleConfig\n ),\n '*\\n * Config accepted by the factory a middleware module exports.\\n '\n ),\n ];\n};\n\n/**\n * Generate type definitions for the application's middlewares (global::* and api::*)\n *\n * Middlewares are typed from their source file, so only the ones with a source in src/middlewares or\n * src/api are emitted. Bundled middlewares (strapi::*, admin::*, plugin::*) are left to the packages\n * themselves (Strapi.Registries.PackageMiddlewares), so registering application middlewares keeps\n * them accepted.\n *\n * declare global {\n * namespace Strapi {\n * namespace Registries {\n * interface AppMiddlewares {\n * 'global::<middleware>': MiddlewareConfig<typeof import('<relative path to the source>')>;\n * 'api::<api>.<middleware>': MiddlewareConfig<typeof import('<relative path to the source>')>;\n * 'global::<js middleware>': unknown;\n * }\n * }\n * }\n * }\n *\n * Like JS policies (see the policies generator), JS middlewares are registered as `unknown` without\n * an import.\n * TODO @Nico with `allowJs`, a JSDoc-typed JS middleware could register its config like a TS one\n */\nexport const generateMiddlewaresDefinitions = async (\n options: GeneratorOptions = {} as GeneratorOptions\n) => {\n const { strapi, logger, pwd: outDir } = options;\n\n if (!outDir) {\n throw new Error(\n 'The middlewares generator needs the output directory to resolve source imports'\n );\n }\n\n const sources = await collectAppSources(\n 'middlewares',\n { global: strapi.dirs.app.middlewares, api: strapi.dirs.app.api },\n outDir,\n logger\n );\n const middlewaresDefinitions = filterRegisteredSources(sources, strapi.middlewares, logger);\n\n logger.debug(`Found ${middlewaresDefinitions.length} middlewares.`);\n\n if (middlewaresDefinitions.length === 0) {\n return { output: NO_MIDDLEWARE_PLACEHOLDER_COMMENT, stats: {} };\n }\n\n // The helpers are only emitted when an entry reads them: `noUnusedLocals` reports unused ones\n const output = await emitRegistryDefinitions(\n REGISTRY,\n middlewaresDefinitions.some(isTypedSource) === true ? generateConfigHelpersDefinition() : [],\n middlewaresDefinitions,\n (source) =>\n isTypedSource(source)\n ? factory.createTypeReferenceNode(CONFIG_HELPER, [typeofImport(source)])\n : factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword)\n );\n\n return { output, stats: {} };\n};\n"],"names":["factory","ts","REGISTRY","CONFIG_HELPER","FACTORY_CONFIG_HELPER","NO_MIDDLEWARE_PLACEHOLDER_COMMENT","generateConfigHelpersDefinition","args","createTypeReferenceNode","configArg","createIndexedAccessTypeNode","createLiteralTypeNode","createNumericLiteral","never","createKeywordTypeNode","SyntaxKind","NeverKeyword","factorySignature","createFunctionTypeNode","undefined","createParameterDeclaration","createTypeLiteralNode","createPropertySignature","UnknownKeyword","koaContextShape","map","member","factoryConfig","createConditionalTypeNode","createToken","DotDotDotToken","createInferTypeNode","createTypeParameterDeclaration","createStringLiteral","UndefinedKeyword","createIntersectionTypeNode","moduleConfig","withDocComment","createTypeAliasDeclaration","createIdentifier","generateMiddlewaresDefinitions","options","strapi","logger","pwd","outDir","Error","sources","collectAppSources","global","dirs","app","middlewares","api","middlewaresDefinitions","filterRegisteredSources","debug","length","output","stats","emitRegistryDefinitions","some","isTypedSource","source","typeofImport"],"mappings":"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"}
|