@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.
Files changed (225) hide show
  1. package/dist/compile.d.ts +5 -0
  2. package/dist/compile.d.ts.map +1 -0
  3. package/dist/compile.js +12 -0
  4. package/dist/compile.js.map +1 -0
  5. package/dist/compile.mjs +10 -0
  6. package/dist/compile.mjs.map +1 -0
  7. package/dist/compilers/basic.d.ts +11 -0
  8. package/dist/compilers/basic.d.ts.map +1 -0
  9. package/dist/compilers/basic.js +58 -0
  10. package/dist/compilers/basic.js.map +1 -0
  11. package/dist/compilers/basic.mjs +36 -0
  12. package/dist/compilers/basic.mjs.map +1 -0
  13. package/dist/compilers/index.d.ts +3 -0
  14. package/dist/compilers/index.d.ts.map +1 -0
  15. package/dist/compilers/index.js +8 -0
  16. package/dist/compilers/index.js.map +1 -0
  17. package/dist/compilers/index.mjs +3 -0
  18. package/dist/compilers/index.mjs.map +1 -0
  19. package/dist/generators/common/compare.d.ts +14 -0
  20. package/dist/generators/common/compare.d.ts.map +1 -0
  21. package/dist/generators/common/compare.js +25 -0
  22. package/dist/generators/common/compare.js.map +1 -0
  23. package/dist/generators/common/compare.mjs +22 -0
  24. package/dist/generators/common/compare.mjs.map +1 -0
  25. package/dist/generators/common/imports.d.ts +5 -0
  26. package/dist/generators/common/imports.d.ts.map +1 -0
  27. package/dist/generators/common/imports.js +42 -0
  28. package/dist/generators/common/imports.js.map +1 -0
  29. package/dist/generators/common/imports.mjs +19 -0
  30. package/dist/generators/common/imports.mjs.map +1 -0
  31. package/dist/generators/common/index.d.ts +4 -0
  32. package/dist/generators/common/index.d.ts.map +1 -0
  33. package/dist/generators/common/interface-names.d.ts +16 -0
  34. package/dist/generators/common/interface-names.d.ts.map +1 -0
  35. package/dist/generators/common/interface-names.js +54 -0
  36. package/dist/generators/common/interface-names.js.map +1 -0
  37. package/dist/generators/common/interface-names.mjs +52 -0
  38. package/dist/generators/common/interface-names.mjs.map +1 -0
  39. package/dist/generators/common/models/attributes.d.ts +38 -0
  40. package/dist/generators/common/models/attributes.d.ts.map +1 -0
  41. package/dist/generators/common/models/attributes.js +205 -0
  42. package/dist/generators/common/models/attributes.js.map +1 -0
  43. package/dist/generators/common/models/attributes.mjs +176 -0
  44. package/dist/generators/common/models/attributes.mjs.map +1 -0
  45. package/dist/generators/common/models/index.d.ts +7 -0
  46. package/dist/generators/common/models/index.d.ts.map +1 -0
  47. package/dist/generators/common/models/mappers.d.ts +9 -0
  48. package/dist/generators/common/models/mappers.d.ts.map +1 -0
  49. package/dist/generators/common/models/mappers.js +227 -0
  50. package/dist/generators/common/models/mappers.js.map +1 -0
  51. package/dist/generators/common/models/mappers.mjs +202 -0
  52. package/dist/generators/common/models/mappers.mjs.map +1 -0
  53. package/dist/generators/common/models/schema.d.ts +8 -0
  54. package/dist/generators/common/models/schema.d.ts.map +1 -0
  55. package/dist/generators/common/models/schema.js +78 -0
  56. package/dist/generators/common/models/schema.js.map +1 -0
  57. package/dist/generators/common/models/schema.mjs +56 -0
  58. package/dist/generators/common/models/schema.mjs.map +1 -0
  59. package/dist/generators/common/models/utils.d.ts +57 -0
  60. package/dist/generators/common/models/utils.d.ts.map +1 -0
  61. package/dist/generators/common/models/utils.js +110 -0
  62. package/dist/generators/common/models/utils.js.map +1 -0
  63. package/dist/generators/common/models/utils.mjs +82 -0
  64. package/dist/generators/common/models/utils.mjs.map +1 -0
  65. package/dist/generators/common/sources.d.ts +133 -0
  66. package/dist/generators/common/sources.d.ts.map +1 -0
  67. package/dist/generators/common/sources.js +354 -0
  68. package/dist/generators/common/sources.js.map +1 -0
  69. package/dist/generators/common/sources.mjs +318 -0
  70. package/dist/generators/common/sources.mjs.map +1 -0
  71. package/dist/generators/components/index.d.ts +9 -0
  72. package/dist/generators/components/index.d.ts.map +1 -0
  73. package/dist/generators/components/index.js +84 -0
  74. package/dist/generators/components/index.js.map +1 -0
  75. package/dist/generators/components/index.mjs +62 -0
  76. package/dist/generators/components/index.mjs.map +1 -0
  77. package/dist/generators/constants.d.ts +3 -0
  78. package/dist/generators/constants.d.ts.map +1 -0
  79. package/dist/generators/constants.js +8 -0
  80. package/dist/generators/constants.js.map +1 -0
  81. package/dist/generators/constants.mjs +5 -0
  82. package/dist/generators/constants.mjs.map +1 -0
  83. package/dist/generators/content-types/index.d.ts +9 -0
  84. package/dist/generators/content-types/index.d.ts.map +1 -0
  85. package/dist/generators/content-types/index.js +84 -0
  86. package/dist/generators/content-types/index.js.map +1 -0
  87. package/dist/generators/content-types/index.mjs +62 -0
  88. package/dist/generators/content-types/index.mjs.map +1 -0
  89. package/dist/generators/controllers/index.d.ts +35 -0
  90. package/dist/generators/controllers/index.d.ts.map +1 -0
  91. package/dist/generators/controllers/index.js +88 -0
  92. package/dist/generators/controllers/index.js.map +1 -0
  93. package/dist/generators/controllers/index.mjs +86 -0
  94. package/dist/generators/controllers/index.mjs.map +1 -0
  95. package/dist/generators/index.d.ts +31 -0
  96. package/dist/generators/index.d.ts.map +1 -0
  97. package/dist/generators/index.js +150 -0
  98. package/dist/generators/index.js.map +1 -0
  99. package/dist/generators/index.mjs +142 -0
  100. package/dist/generators/index.mjs.map +1 -0
  101. package/dist/generators/middlewares/index.d.ts +30 -0
  102. package/dist/generators/middlewares/index.d.ts.map +1 -0
  103. package/dist/generators/middlewares/index.js +163 -0
  104. package/dist/generators/middlewares/index.js.map +1 -0
  105. package/dist/generators/middlewares/index.mjs +141 -0
  106. package/dist/generators/middlewares/index.mjs.map +1 -0
  107. package/dist/generators/plugins/index.d.ts +9 -0
  108. package/dist/generators/plugins/index.d.ts.map +1 -0
  109. package/dist/generators/plugins/index.js +225 -0
  110. package/dist/generators/plugins/index.js.map +1 -0
  111. package/dist/generators/plugins/index.mjs +200 -0
  112. package/dist/generators/plugins/index.mjs.map +1 -0
  113. package/dist/generators/policies/index.d.ts +29 -0
  114. package/dist/generators/policies/index.d.ts.map +1 -0
  115. package/dist/generators/policies/index.js +135 -0
  116. package/dist/generators/policies/index.js.map +1 -0
  117. package/dist/generators/policies/index.mjs +113 -0
  118. package/dist/generators/policies/index.mjs.map +1 -0
  119. package/dist/generators/services/index.d.ts +35 -0
  120. package/dist/generators/services/index.d.ts.map +1 -0
  121. package/dist/generators/services/index.js +87 -0
  122. package/dist/generators/services/index.js.map +1 -0
  123. package/dist/generators/services/index.mjs +85 -0
  124. package/dist/generators/services/index.mjs.map +1 -0
  125. package/dist/generators/strict/index.d.ts +13 -0
  126. package/dist/generators/strict/index.d.ts.map +1 -0
  127. package/dist/generators/strict/index.js +24 -0
  128. package/dist/generators/strict/index.js.map +1 -0
  129. package/dist/generators/strict/index.mjs +22 -0
  130. package/dist/generators/strict/index.mjs.map +1 -0
  131. package/dist/generators/utils.d.ts +68 -0
  132. package/dist/generators/utils.d.ts.map +1 -0
  133. package/dist/generators/utils.js +201 -0
  134. package/dist/generators/utils.js.map +1 -0
  135. package/dist/generators/utils.mjs +166 -0
  136. package/dist/generators/utils.mjs.map +1 -0
  137. package/dist/index.d.ts +5 -0
  138. package/dist/index.d.ts.map +1 -0
  139. package/dist/index.js +28 -0
  140. package/dist/index.js.map +1 -0
  141. package/dist/index.mjs +14 -0
  142. package/dist/index.mjs.map +1 -0
  143. package/dist/utils/format-host.d.ts +3 -0
  144. package/dist/utils/format-host.d.ts.map +1 -0
  145. package/dist/utils/format-host.js +33 -0
  146. package/dist/utils/format-host.js.map +1 -0
  147. package/dist/utils/format-host.mjs +11 -0
  148. package/dist/utils/format-host.mjs.map +1 -0
  149. package/dist/utils/get-config-path.d.ts +10 -0
  150. package/dist/utils/get-config-path.d.ts.map +1 -0
  151. package/dist/utils/get-config-path.js +43 -0
  152. package/dist/utils/get-config-path.js.map +1 -0
  153. package/dist/utils/get-config-path.mjs +18 -0
  154. package/dist/utils/get-config-path.mjs.map +1 -0
  155. package/dist/utils/index.d.ts +9 -0
  156. package/dist/utils/index.d.ts.map +1 -0
  157. package/dist/utils/is-using-typescript-sync.d.ts +5 -0
  158. package/dist/utils/is-using-typescript-sync.d.ts.map +1 -0
  159. package/dist/utils/is-using-typescript-sync.js +20 -0
  160. package/dist/utils/is-using-typescript-sync.js.map +1 -0
  161. package/dist/utils/is-using-typescript-sync.mjs +14 -0
  162. package/dist/utils/is-using-typescript-sync.mjs.map +1 -0
  163. package/dist/utils/is-using-typescript.d.ts +5 -0
  164. package/dist/utils/is-using-typescript.d.ts.map +1 -0
  165. package/dist/utils/is-using-typescript.js +20 -0
  166. package/dist/utils/is-using-typescript.js.map +1 -0
  167. package/dist/utils/is-using-typescript.mjs +14 -0
  168. package/dist/utils/is-using-typescript.mjs.map +1 -0
  169. package/dist/utils/report-diagnostics.d.ts +6 -0
  170. package/dist/utils/report-diagnostics.d.ts.map +1 -0
  171. package/dist/utils/report-diagnostics.js +37 -0
  172. package/dist/utils/report-diagnostics.js.map +1 -0
  173. package/dist/utils/report-diagnostics.mjs +15 -0
  174. package/dist/utils/report-diagnostics.mjs.map +1 -0
  175. package/dist/utils/resolve-config-options.d.ts +12 -0
  176. package/dist/utils/resolve-config-options.d.ts.map +1 -0
  177. package/dist/utils/resolve-config-options.js +39 -0
  178. package/dist/utils/resolve-config-options.js.map +1 -0
  179. package/dist/utils/resolve-config-options.mjs +17 -0
  180. package/dist/utils/resolve-config-options.mjs.map +1 -0
  181. package/dist/utils/resolve-outdir-sync.d.ts +5 -0
  182. package/dist/utils/resolve-outdir-sync.d.ts.map +1 -0
  183. package/dist/utils/resolve-outdir-sync.js +19 -0
  184. package/dist/utils/resolve-outdir-sync.js.map +1 -0
  185. package/dist/utils/resolve-outdir-sync.mjs +13 -0
  186. package/dist/utils/resolve-outdir-sync.mjs.map +1 -0
  187. package/dist/utils/resolve-outdir.d.ts +5 -0
  188. package/dist/utils/resolve-outdir.d.ts.map +1 -0
  189. package/dist/utils/resolve-outdir.js +19 -0
  190. package/dist/utils/resolve-outdir.js.map +1 -0
  191. package/dist/utils/resolve-outdir.mjs +13 -0
  192. package/dist/utils/resolve-outdir.mjs.map +1 -0
  193. package/package.json +27 -12
  194. package/.eslintrc.cjs +0 -16
  195. package/index.d.ts +0 -5
  196. package/jest.config.js +0 -6
  197. package/lib/__tests__/generators/schemas/attributes.test.js +0 -903
  198. package/lib/__tests__/generators/schemas/imports.test.js +0 -56
  199. package/lib/__tests__/generators/schemas/utils.test.js +0 -314
  200. package/lib/compile.js +0 -10
  201. package/lib/compilers/basic.js +0 -50
  202. package/lib/compilers/index.js +0 -7
  203. package/lib/generators/common/imports.js +0 -34
  204. package/lib/generators/common/index.js +0 -9
  205. package/lib/generators/common/models/attributes.js +0 -198
  206. package/lib/generators/common/models/index.js +0 -15
  207. package/lib/generators/common/models/mappers.js +0 -144
  208. package/lib/generators/common/models/schema.js +0 -93
  209. package/lib/generators/common/models/utils.js +0 -178
  210. package/lib/generators/components/index.js +0 -74
  211. package/lib/generators/constants.js +0 -6
  212. package/lib/generators/content-types/index.js +0 -74
  213. package/lib/generators/index.js +0 -122
  214. package/lib/generators/utils.js +0 -216
  215. package/lib/index.js +0 -13
  216. package/lib/utils/format-host.js +0 -15
  217. package/lib/utils/get-config-path.js +0 -29
  218. package/lib/utils/index.js +0 -21
  219. package/lib/utils/is-using-typescript-sync.js +0 -19
  220. package/lib/utils/is-using-typescript.js +0 -17
  221. package/lib/utils/report-diagnostics.js +0 -19
  222. package/lib/utils/resolve-config-options.js +0 -23
  223. package/lib/utils/resolve-outdir-sync.js +0 -18
  224. package/lib/utils/resolve-outdir.js +0 -18
  225. 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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"}