@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,354 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var path = require('node:path');
|
|
4
|
+
var fs = require('node:fs');
|
|
5
|
+
var ts = require('typescript');
|
|
6
|
+
var _ = require('lodash');
|
|
7
|
+
var utils = require('../utils.js');
|
|
8
|
+
var compare = require('./compare.js');
|
|
9
|
+
|
|
10
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
11
|
+
|
|
12
|
+
function _interopNamespace(e) {
|
|
13
|
+
if (e && e.__esModule) return e;
|
|
14
|
+
var n = Object.create(null);
|
|
15
|
+
if (e) {
|
|
16
|
+
Object.keys(e).forEach(function (k) {
|
|
17
|
+
if (k !== 'default') {
|
|
18
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
19
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
20
|
+
enumerable: true,
|
|
21
|
+
get: function () { return e[k]; }
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
n.default = e;
|
|
27
|
+
return Object.freeze(n);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
var path__default = /*#__PURE__*/_interopDefault(path);
|
|
31
|
+
var fs__default = /*#__PURE__*/_interopDefault(fs);
|
|
32
|
+
var ts__namespace = /*#__PURE__*/_interopNamespace(ts);
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Shared by the generators of application modules (services, controllers, policies, middlewares):
|
|
36
|
+
* they find the source files the loaders of @strapi/core register, derive the same uids, and write
|
|
37
|
+
* one global registry each. Each generator keeps what it reads from a module type and which registry
|
|
38
|
+
* it writes.
|
|
39
|
+
*/ const { factory } = ts__namespace;
|
|
40
|
+
const GLOBAL_NAMESPACE = 'Strapi';
|
|
41
|
+
const REGISTRIES_NAMESPACE = 'Registries';
|
|
42
|
+
// Ordered by precedence when several files resolve to the same uid
|
|
43
|
+
const SOURCE_EXTENSIONS = [
|
|
44
|
+
'.ts',
|
|
45
|
+
'.js'
|
|
46
|
+
];
|
|
47
|
+
/**
|
|
48
|
+
* Mirror of the API loader's name normalization (@strapi/core, loaders/apis.ts): names already in
|
|
49
|
+
* kebab-case are kept as is, anything else is kebab-cased. Both must agree for the generated uids
|
|
50
|
+
* to match the ones registered at runtime. Global policies and middlewares (loaders/policies.ts,
|
|
51
|
+
* loaders/middlewares.ts) are not normalized.
|
|
52
|
+
*/ const isKebabCase = (value)=>/^([a-z][a-z0-9]*)(-[a-z0-9]+)*$/.test(value);
|
|
53
|
+
const normalizeName = (name)=>isKebabCase(name) ? name : _.kebabCase(name);
|
|
54
|
+
const isSourceFile = (fd)=>fd.isFile() && !fd.name.endsWith('.d.ts') && SOURCE_EXTENSIONS.includes(path__default.default.extname(fd.name));
|
|
55
|
+
const byExtensionPrecedence = (a, b)=>SOURCE_EXTENSIONS.indexOf(path__default.default.extname(a.name)) - SOURCE_EXTENSIONS.indexOf(path__default.default.extname(b.name));
|
|
56
|
+
const toImportSpecifier = (from, to)=>{
|
|
57
|
+
const specifier = path__default.default.relative(from, to).split(path__default.default.sep).join('/');
|
|
58
|
+
return specifier.startsWith('.') ? specifier : `./${specifier}`;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Add the source files of a directory to `sources`, under the uid returned by `toUID`
|
|
62
|
+
*/ const collectDirectorySources = async (dir, toUID, sources, outDir, logger)=>{
|
|
63
|
+
if (await utils.pathExists(dir) === false) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
const sourceFDs = (await fs__default.default.promises.readdir(dir, {
|
|
67
|
+
withFileTypes: true
|
|
68
|
+
})).filter(isSourceFile).sort(byExtensionPrecedence);
|
|
69
|
+
for (const sourceFD of sourceFDs){
|
|
70
|
+
const basename = path__default.default.basename(sourceFD.name, path__default.default.extname(sourceFD.name));
|
|
71
|
+
const uid = toUID(basename);
|
|
72
|
+
const file = path__default.default.join(dir, sourceFD.name);
|
|
73
|
+
if (sources.has(uid)) {
|
|
74
|
+
logger.warn(`Several source files resolve to ${uid}, ignoring ${file}`);
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
sources.set(uid, {
|
|
78
|
+
uid,
|
|
79
|
+
file,
|
|
80
|
+
specifier: toImportSpecifier(outDir, path__default.default.join(dir, basename))
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
/**
|
|
85
|
+
* Collect the global source files of a kind when `dirs.global` is given (src/<kind>/<name>.{ts,js}
|
|
86
|
+
* → global::<name>), then the ones of every API (src/api/<api>/<kind>/<name>.{ts,js} →
|
|
87
|
+
* api::<api>.<name>). The first file to resolve to a uid wins.
|
|
88
|
+
*/ const collectAppSources = async (kind, dirs, outDir, logger)=>{
|
|
89
|
+
const sources = new Map();
|
|
90
|
+
if (dirs.global !== undefined) {
|
|
91
|
+
await collectDirectorySources(dirs.global, (basename)=>`global::${basename}`, sources, outDir, logger);
|
|
92
|
+
}
|
|
93
|
+
if (await utils.pathExists(dirs.api) === true) {
|
|
94
|
+
const apiFDs = (await fs__default.default.promises.readdir(dirs.api, {
|
|
95
|
+
withFileTypes: true
|
|
96
|
+
})).filter((fd)=>fd.isDirectory() && !fd.name.startsWith('.'));
|
|
97
|
+
for (const apiFD of apiFDs){
|
|
98
|
+
const apiName = normalizeName(apiFD.name);
|
|
99
|
+
await collectDirectorySources(path__default.default.join(dirs.api, apiFD.name, kind), (basename)=>`api::${apiName}.${normalizeName(basename)}`, sources, outDir, logger);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return Array.from(sources.values());
|
|
103
|
+
};
|
|
104
|
+
/**
|
|
105
|
+
* Keep the sources whose uid the running app registered, sorted by uid
|
|
106
|
+
*/ const filterRegisteredSources = (sources, registered, logger)=>{
|
|
107
|
+
const registeredUIDs = new Set(Object.keys(registered));
|
|
108
|
+
return sources.filter((source)=>{
|
|
109
|
+
if (!registeredUIDs.has(source.uid)) {
|
|
110
|
+
logger.debug(`${source.uid} is not registered, ignoring ${source.file}`);
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
return true;
|
|
114
|
+
}).sort((a, b)=>compare.compareCodeUnits(a.uid, b.uid));
|
|
115
|
+
};
|
|
116
|
+
/**
|
|
117
|
+
* Application tsconfigs do not enable `allowJs`, so the import of a JS source does not resolve and is
|
|
118
|
+
* an error type. Unlike `any`, conditional types cannot map it to `unknown`.
|
|
119
|
+
*/ const isTypedSource = (source)=>path__default.default.extname(source.file) === '.ts';
|
|
120
|
+
const hasModifier = (statement, kind)=>ts__namespace.canHaveModifiers(statement) && (ts__namespace.getModifiers(statement) ?? []).some((modifier)=>modifier.kind === kind);
|
|
121
|
+
/**
|
|
122
|
+
* Whether a top-level statement is `export type <name>` or `export interface <name>`
|
|
123
|
+
*/ const isExportedTypeDeclarationNamed = (statement, name)=>(ts__namespace.isTypeAliasDeclaration(statement) || ts__namespace.isInterfaceDeclaration(statement)) && statement.name.text === name && hasModifier(statement, ts__namespace.SyntaxKind.ExportKeyword) === true && hasModifier(statement, ts__namespace.SyntaxKind.DefaultKeyword) === false;
|
|
124
|
+
/**
|
|
125
|
+
* Whether a type declaration can be referenced without type arguments, as the generated file does
|
|
126
|
+
*/ const hasDefaultTypeArguments = (statement)=>(statement.typeParameters ?? []).every((parameter)=>parameter.default !== undefined);
|
|
127
|
+
/**
|
|
128
|
+
* Whether a top-level statement exports a type under `name`: `export type <name>`,
|
|
129
|
+
* `export interface <name>`, or an export specifier named `<name>` (`export { <name> }`,
|
|
130
|
+
* `export { type X as <name> }`, `export type { X as <name> } from './x'`).
|
|
131
|
+
*
|
|
132
|
+
* A generic declaration only counts when each of its type parameters has a default: the generated
|
|
133
|
+
* file references it without type arguments.
|
|
134
|
+
*
|
|
135
|
+
* A specifier may name a value rather than a type, or a generic without defaults: its reference in
|
|
136
|
+
* the generated file does not resolve, and `tsc` reports it there.
|
|
137
|
+
* TODO @Nico a specifier of a local declaration could be checked like the declaration itself
|
|
138
|
+
*/ const exportsTypeNamed = (statement, name)=>{
|
|
139
|
+
if (ts__namespace.isTypeAliasDeclaration(statement) || ts__namespace.isInterfaceDeclaration(statement)) {
|
|
140
|
+
return isExportedTypeDeclarationNamed(statement, name) === true && hasDefaultTypeArguments(statement) === true;
|
|
141
|
+
}
|
|
142
|
+
if (ts__namespace.isExportDeclaration(statement) && statement.exportClause !== undefined && ts__namespace.isNamedExports(statement.exportClause)) {
|
|
143
|
+
return statement.exportClause.elements.some((element)=>element.name.text === name);
|
|
144
|
+
}
|
|
145
|
+
return false;
|
|
146
|
+
};
|
|
147
|
+
/**
|
|
148
|
+
* The uids of the TypeScript sources whose module exports a type named `name`, such as a service's
|
|
149
|
+
* `ServiceContract`.
|
|
150
|
+
*
|
|
151
|
+
* Each source is parsed on its own, without a program: type generation runs on every `strapi develop`
|
|
152
|
+
* start, before the compilation, and a program would need the application's tsconfig and its whole
|
|
153
|
+
* dependency graph. Only top-level declarations and export specifiers are read (see
|
|
154
|
+
* `exportsTypeNamed`). `export *` is not followed, and a source that cannot be read is skipped with a
|
|
155
|
+
* warning: both keep the type the source registers without a contract, rather than stopping the
|
|
156
|
+
* generation.
|
|
157
|
+
*
|
|
158
|
+
* JS sources are skipped: their import does not resolve without `allowJs` (see `isTypedSource`).
|
|
159
|
+
*/ const findTypeExports = async (sources, name, logger)=>{
|
|
160
|
+
// TODO @Nico A JS source could get a contract from a sibling `<name>.d.ts` that exports it: the
|
|
161
|
+
// extension-less import of the source resolves to that file without `allowJs`.
|
|
162
|
+
const typedSources = sources.filter(isTypedSource);
|
|
163
|
+
const verdicts = await Promise.all(typedSources.map(async (source)=>{
|
|
164
|
+
let content;
|
|
165
|
+
try {
|
|
166
|
+
content = await fs__default.default.promises.readFile(source.file, 'utf8');
|
|
167
|
+
} catch (error) {
|
|
168
|
+
logger.warn(`Could not read ${source.file} to find its ${name} export, typing ${source.uid} without it: ${error instanceof Error ? error.message : String(error)}`);
|
|
169
|
+
return false;
|
|
170
|
+
}
|
|
171
|
+
const sourceFile = ts__namespace.createSourceFile(source.file, content, ts__namespace.ScriptTarget.Latest, false, ts__namespace.ScriptKind.TS);
|
|
172
|
+
if (sourceFile.statements.some((statement)=>exportsTypeNamed(statement, name)) === true) {
|
|
173
|
+
return true;
|
|
174
|
+
}
|
|
175
|
+
if (sourceFile.statements.some((statement)=>isExportedTypeDeclarationNamed(statement, name) === true && hasDefaultTypeArguments(statement) === false) === true) {
|
|
176
|
+
logger.warn(`${source.file} exports ${name} with type parameters that have no default, typing ${source.uid} without it`);
|
|
177
|
+
}
|
|
178
|
+
if (sourceFile.statements.some((statement)=>ts__namespace.isExportDeclaration(statement) && statement.exportClause === undefined) === true) {
|
|
179
|
+
logger.debug(`${source.uid}: \`export *\` is not followed to find a ${name} export`);
|
|
180
|
+
}
|
|
181
|
+
return false;
|
|
182
|
+
}));
|
|
183
|
+
return new Set(typedSources.filter((_, index)=>verdicts[index] === true).map(({ uid })=>uid));
|
|
184
|
+
};
|
|
185
|
+
/**
|
|
186
|
+
* The type a service or controller source registers:
|
|
187
|
+
* - `<contract helper><import('<source>').<contract export>>` when the module exports the contract;
|
|
188
|
+
* - `<helper><typeof import('<source>')>` otherwise, which infers it from the default export;
|
|
189
|
+
* - `unknown` for a JS source, whose import is an error type without `allowJs` (see `isTypedSource`).
|
|
190
|
+
*
|
|
191
|
+
* The contract does not depend on the default export, so the factory can be checked against its own
|
|
192
|
+
* uid (`Core.ServiceFactory<uid>`). The inferred type does: the generators list those uids in a
|
|
193
|
+
* marker registry (see `isInferredSource`), which the factory types reject.
|
|
194
|
+
*/ const instanceTypeOf = (helper, logger, contract)=>(source)=>{
|
|
195
|
+
if (isTypedSource(source) === false) {
|
|
196
|
+
logger.debug(`${source.uid} has no TypeScript source, registering it as unknown`);
|
|
197
|
+
return factory.createKeywordTypeNode(ts__namespace.SyntaxKind.UnknownKeyword);
|
|
198
|
+
}
|
|
199
|
+
if (contract !== undefined && contract.uids.has(source.uid) === true) {
|
|
200
|
+
logger.debug(`${source.uid} exports ${contract.exportName}, registering it`);
|
|
201
|
+
return factory.createTypeReferenceNode(contract.helper, [
|
|
202
|
+
importedType(source, contract.exportName)
|
|
203
|
+
]);
|
|
204
|
+
}
|
|
205
|
+
return factory.createTypeReferenceNode(helper, [
|
|
206
|
+
typeofImport(source)
|
|
207
|
+
]);
|
|
208
|
+
};
|
|
209
|
+
/**
|
|
210
|
+
* Whether a source registers the type its module provides (see `instanceTypeOf`): a TypeScript
|
|
211
|
+
* source whose module does not export the contract.
|
|
212
|
+
*/ const isInferredSource = (contract)=>(source)=>isTypedSource(source) === true && contract.uids.has(source.uid) === false;
|
|
213
|
+
/**
|
|
214
|
+
* typeof import('<relative path to the source>')
|
|
215
|
+
*/ const typeofImport = (source)=>factory.createImportTypeNode(factory.createLiteralTypeNode(factory.createStringLiteral(source.specifier, true)), undefined, undefined, undefined, true);
|
|
216
|
+
/**
|
|
217
|
+
* import('<relative path to the source>').<name>
|
|
218
|
+
*/ const importedType = (source, name)=>factory.createImportTypeNode(factory.createLiteralTypeNode(factory.createStringLiteral(source.specifier, true)), undefined, factory.createIdentifier(name), undefined, false);
|
|
219
|
+
const withDocComment = (node, comment)=>ts__namespace.addSyntheticLeadingComment(node, ts__namespace.SyntaxKind.MultiLineCommentTrivia, comment, true);
|
|
220
|
+
/**
|
|
221
|
+
* type <name><TModule> = TModule extends { default: infer TExport }
|
|
222
|
+
* ? 0 extends 1 & TExport
|
|
223
|
+
* ? unknown
|
|
224
|
+
* : TExport extends (...args: any[]) => infer TInstance ? TInstance : TExport
|
|
225
|
+
* : unknown;
|
|
226
|
+
*
|
|
227
|
+
* Emitted in each file so that services.ts and controllers.ts stand alone, and only when a source
|
|
228
|
+
* registers its inferred type.
|
|
229
|
+
*
|
|
230
|
+
* Resolves the type registered for a service or a controller from the type of its module: the return
|
|
231
|
+
* type of the default export when it is a factory, the default export itself otherwise. A module
|
|
232
|
+
* without a default export registers nothing usable at runtime; with strict types enabled, an
|
|
233
|
+
* unregistered uid resolves to `unknown`, so the helper does the same rather than claiming a
|
|
234
|
+
* permissive contract for it. A module typed `any` and a default export typed `any` resolve to
|
|
235
|
+
* `unknown` too: `any` would match the factory branch and register `any`.
|
|
236
|
+
*
|
|
237
|
+
* An import that no longer resolves (the source moved after the generation) is an error type, which
|
|
238
|
+
* no conditional type maps to `unknown`. The generated file is a `.ts` file, so `tsc` reports the
|
|
239
|
+
* TS2307 there, `skipLibCheck` or not, until the next generation drops the entry.
|
|
240
|
+
*/ const generateInstanceHelperDefinition = (name, comment)=>{
|
|
241
|
+
const unwrapFactory = factory.createConditionalTypeNode(factory.createTypeReferenceNode('TExport'), factory.createFunctionTypeNode(undefined, [
|
|
242
|
+
factory.createParameterDeclaration(undefined, factory.createToken(ts__namespace.SyntaxKind.DotDotDotToken), 'args', undefined, factory.createArrayTypeNode(factory.createKeywordTypeNode(ts__namespace.SyntaxKind.AnyKeyword)))
|
|
243
|
+
], factory.createInferTypeNode(factory.createTypeParameterDeclaration(undefined, 'TInstance'))), factory.createTypeReferenceNode('TInstance'), factory.createTypeReferenceNode('TExport'));
|
|
244
|
+
// 0 extends 1 & TExport: only true when TExport is `any`
|
|
245
|
+
const guardAny = factory.createConditionalTypeNode(factory.createLiteralTypeNode(factory.createNumericLiteral(0)), factory.createIntersectionTypeNode([
|
|
246
|
+
factory.createLiteralTypeNode(factory.createNumericLiteral(1)),
|
|
247
|
+
factory.createTypeReferenceNode('TExport')
|
|
248
|
+
]), factory.createKeywordTypeNode(ts__namespace.SyntaxKind.UnknownKeyword), unwrapFactory);
|
|
249
|
+
const unwrapDefaultExport = factory.createConditionalTypeNode(factory.createTypeReferenceNode('TModule'), factory.createTypeLiteralNode([
|
|
250
|
+
factory.createPropertySignature(undefined, 'default', undefined, factory.createInferTypeNode(factory.createTypeParameterDeclaration(undefined, 'TExport')))
|
|
251
|
+
]), guardAny, factory.createKeywordTypeNode(ts__namespace.SyntaxKind.UnknownKeyword));
|
|
252
|
+
return withDocComment(factory.createTypeAliasDeclaration(undefined, factory.createIdentifier(name), [
|
|
253
|
+
factory.createTypeParameterDeclaration(undefined, 'TModule')
|
|
254
|
+
], unwrapDefaultExport), comment);
|
|
255
|
+
};
|
|
256
|
+
/**
|
|
257
|
+
* type <name><TContract> = 0 extends 1 & TContract ? unknown : TContract;
|
|
258
|
+
*
|
|
259
|
+
* Emitted only when at least one source exports a contract: an application without contracts does
|
|
260
|
+
* not get it.
|
|
261
|
+
*
|
|
262
|
+
* A contract typed `any` registers `unknown`, as for an unregistered uid, rather than turning every
|
|
263
|
+
* lookup of the uid into `any`.
|
|
264
|
+
*
|
|
265
|
+
* A contract reference that no longer resolves to a type (the export was renamed after the
|
|
266
|
+
* generation, or a specifier names a value) is an error type, which no conditional type can map to
|
|
267
|
+
* `unknown` (an alias instantiated with the error type stays the error type). The generated file is a
|
|
268
|
+
* `.ts` file, so `tsc` reports the TS2694/TS2749 there, `skipLibCheck` or not. The next generation,
|
|
269
|
+
* on every `strapi develop` start, registers the source without its contract again.
|
|
270
|
+
*/ const generateContractHelperDefinition = (name, comment)=>withDocComment(factory.createTypeAliasDeclaration(undefined, factory.createIdentifier(name), [
|
|
271
|
+
factory.createTypeParameterDeclaration(undefined, 'TContract')
|
|
272
|
+
], factory.createConditionalTypeNode(factory.createLiteralTypeNode(factory.createNumericLiteral(0)), factory.createIntersectionTypeNode([
|
|
273
|
+
factory.createLiteralTypeNode(factory.createNumericLiteral(1)),
|
|
274
|
+
factory.createTypeReferenceNode('TContract')
|
|
275
|
+
]), factory.createKeywordTypeNode(ts__namespace.SyntaxKind.UnknownKeyword), factory.createTypeReferenceNode('TContract'))), comment);
|
|
276
|
+
/**
|
|
277
|
+
* declare global {
|
|
278
|
+
* namespace Strapi {
|
|
279
|
+
* namespace Registries {
|
|
280
|
+
* interface <registry> {
|
|
281
|
+
* '<uid>': <value>;
|
|
282
|
+
* }
|
|
283
|
+
* …
|
|
284
|
+
* }
|
|
285
|
+
* }
|
|
286
|
+
* }
|
|
287
|
+
*
|
|
288
|
+
* The registries are global interfaces, so this augmentation merges with the base declaration and
|
|
289
|
+
* with the application's own entries, whatever module resolution the application uses. Lookups and
|
|
290
|
+
* route configs only consult it once the program opts into strict types.
|
|
291
|
+
*/ const generateRegistryExtensionDefinition = (registries)=>{
|
|
292
|
+
const interfaces = registries.map(({ registry, entries })=>factory.createInterfaceDeclaration(undefined, factory.createIdentifier(registry), undefined, undefined, entries.map(([uid, value])=>factory.createPropertySignature(undefined, factory.createStringLiteral(uid, true), undefined, value))));
|
|
293
|
+
const namespaceOf = (name, statements)=>factory.createModuleDeclaration(undefined, factory.createIdentifier(name), factory.createModuleBlock(statements), ts__namespace.NodeFlags.Namespace);
|
|
294
|
+
return factory.createModuleDeclaration([
|
|
295
|
+
factory.createModifier(ts__namespace.SyntaxKind.DeclareKeyword)
|
|
296
|
+
], factory.createIdentifier('global'), factory.createModuleBlock([
|
|
297
|
+
namespaceOf(GLOBAL_NAMESPACE, [
|
|
298
|
+
namespaceOf(REGISTRIES_NAMESPACE, interfaces)
|
|
299
|
+
])
|
|
300
|
+
]), ts__namespace.NodeFlags.GlobalAugmentation);
|
|
301
|
+
};
|
|
302
|
+
/**
|
|
303
|
+
* export {};
|
|
304
|
+
*
|
|
305
|
+
* <helpers>
|
|
306
|
+
*
|
|
307
|
+
* declare global { … <registry> … <markers> … }
|
|
308
|
+
*
|
|
309
|
+
* The module marker turns the generated file into a module: the global augmentation is only allowed
|
|
310
|
+
* in one. The helpers come first so that the file stands alone. A marker without uids is not
|
|
311
|
+
* emitted, so that the output of an application without such uids does not change.
|
|
312
|
+
*/ const emitRegistryDefinitions = async (registry, helpers, sources, toValue, markers = [])=>{
|
|
313
|
+
const allDefinitions = [
|
|
314
|
+
// Module marker
|
|
315
|
+
factory.createExportDeclaration(undefined, false, factory.createNamedExports([])),
|
|
316
|
+
// Add a newline after the marker
|
|
317
|
+
factory.createIdentifier('\n'),
|
|
318
|
+
// Helpers
|
|
319
|
+
...helpers,
|
|
320
|
+
// Add a newline after the helpers
|
|
321
|
+
factory.createIdentifier('\n'),
|
|
322
|
+
// Global
|
|
323
|
+
generateRegistryExtensionDefinition([
|
|
324
|
+
{
|
|
325
|
+
registry,
|
|
326
|
+
entries: sources.map((source)=>[
|
|
327
|
+
source.uid,
|
|
328
|
+
toValue(source)
|
|
329
|
+
])
|
|
330
|
+
},
|
|
331
|
+
...markers.filter((marker)=>marker.uids.length > 0).map((marker)=>({
|
|
332
|
+
registry: marker.registry,
|
|
333
|
+
entries: marker.uids.map((uid)=>[
|
|
334
|
+
uid,
|
|
335
|
+
factory.createLiteralTypeNode(factory.createTrue())
|
|
336
|
+
])
|
|
337
|
+
}))
|
|
338
|
+
])
|
|
339
|
+
];
|
|
340
|
+
return utils.format(utils.emitDefinitions(allDefinitions));
|
|
341
|
+
};
|
|
342
|
+
|
|
343
|
+
exports.collectAppSources = collectAppSources;
|
|
344
|
+
exports.emitRegistryDefinitions = emitRegistryDefinitions;
|
|
345
|
+
exports.filterRegisteredSources = filterRegisteredSources;
|
|
346
|
+
exports.findTypeExports = findTypeExports;
|
|
347
|
+
exports.generateContractHelperDefinition = generateContractHelperDefinition;
|
|
348
|
+
exports.generateInstanceHelperDefinition = generateInstanceHelperDefinition;
|
|
349
|
+
exports.instanceTypeOf = instanceTypeOf;
|
|
350
|
+
exports.isInferredSource = isInferredSource;
|
|
351
|
+
exports.isTypedSource = isTypedSource;
|
|
352
|
+
exports.typeofImport = typeofImport;
|
|
353
|
+
exports.withDocComment = withDocComment;
|
|
354
|
+
//# sourceMappingURL=sources.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sources.js","sources":["../../../src/generators/common/sources.ts"],"sourcesContent":["import path from 'node:path';\nimport fs, { type Dirent } from 'node:fs';\nimport * as ts from 'typescript';\nimport { kebabCase } from 'lodash';\n\nimport { emitDefinitions, format, pathExists } from '../utils';\nimport type { Logger } from '../utils';\nimport { compareCodeUnits } from './compare';\n\n/**\n * Shared by the generators of application modules (services, controllers, policies, middlewares):\n * they find the source files the loaders of @strapi/core register, derive the same uids, and write\n * one global registry each. Each generator keeps what it reads from a module type and which registry\n * it writes.\n */\n\nconst { factory } = ts;\n\nconst GLOBAL_NAMESPACE = 'Strapi';\nconst REGISTRIES_NAMESPACE = 'Registries';\n\n// Ordered by precedence when several files resolve to the same uid\nconst SOURCE_EXTENSIONS = ['.ts', '.js'];\n\nexport type AppModuleSource = {\n uid: string;\n file: string;\n // Extension-less path of the source file, relative to the generated directory\n specifier: string;\n};\n\n/**\n * Directory of each module kind in an API (src/api/<api>/<kind>), and in src/ for the kinds the\n * loaders also register globally (policies, middlewares)\n */\nexport type AppModuleKind = 'services' | 'controllers' | 'policies' | 'middlewares';\n\n/**\n * Mirror of the API loader's name normalization (@strapi/core, loaders/apis.ts): names already in\n * kebab-case are kept as is, anything else is kebab-cased. Both must agree for the generated uids\n * to match the ones registered at runtime. Global policies and middlewares (loaders/policies.ts,\n * loaders/middlewares.ts) are not normalized.\n */\nconst isKebabCase = (value: string) => /^([a-z][a-z0-9]*)(-[a-z0-9]+)*$/.test(value);\nconst normalizeName = (name: string) => (isKebabCase(name) ? name : kebabCase(name));\n\nconst isSourceFile = (fd: Dirent) =>\n fd.isFile() && !fd.name.endsWith('.d.ts') && SOURCE_EXTENSIONS.includes(path.extname(fd.name));\n\nconst byExtensionPrecedence = (a: Dirent, b: Dirent) =>\n SOURCE_EXTENSIONS.indexOf(path.extname(a.name)) - SOURCE_EXTENSIONS.indexOf(path.extname(b.name));\n\nconst toImportSpecifier = (from: string, to: string) => {\n const specifier = path.relative(from, to).split(path.sep).join('/');\n\n return specifier.startsWith('.') ? specifier : `./${specifier}`;\n};\n\n/**\n * Add the source files of a directory to `sources`, under the uid returned by `toUID`\n */\nconst collectDirectorySources = async (\n dir: string,\n toUID: (basename: string) => string,\n sources: Map<string, AppModuleSource>,\n outDir: string,\n logger: Logger\n) => {\n if ((await pathExists(dir)) === false) {\n return;\n }\n\n const sourceFDs = (await fs.promises.readdir(dir, { withFileTypes: true }))\n .filter(isSourceFile)\n .sort(byExtensionPrecedence);\n\n for (const sourceFD of sourceFDs) {\n const basename = path.basename(sourceFD.name, path.extname(sourceFD.name));\n const uid = toUID(basename);\n const file = path.join(dir, sourceFD.name);\n\n if (sources.has(uid)) {\n logger.warn(`Several source files resolve to ${uid}, ignoring ${file}`);\n continue;\n }\n\n sources.set(uid, {\n uid,\n file,\n specifier: toImportSpecifier(outDir, path.join(dir, basename)),\n });\n }\n};\n\n/**\n * Collect the global source files of a kind when `dirs.global` is given (src/<kind>/<name>.{ts,js}\n * → global::<name>), then the ones of every API (src/api/<api>/<kind>/<name>.{ts,js} →\n * api::<api>.<name>). The first file to resolve to a uid wins.\n */\nexport const collectAppSources = async (\n kind: AppModuleKind,\n dirs: { global?: string; api: string },\n outDir: string,\n logger: Logger\n): Promise<AppModuleSource[]> => {\n const sources = new Map<string, AppModuleSource>();\n\n if (dirs.global !== undefined) {\n await collectDirectorySources(\n dirs.global,\n (basename) => `global::${basename}`,\n sources,\n outDir,\n logger\n );\n }\n\n if ((await pathExists(dirs.api)) === true) {\n const apiFDs = (await fs.promises.readdir(dirs.api, { withFileTypes: true })).filter(\n (fd) => fd.isDirectory() && !fd.name.startsWith('.')\n );\n\n for (const apiFD of apiFDs) {\n const apiName = normalizeName(apiFD.name);\n\n await collectDirectorySources(\n path.join(dirs.api, apiFD.name, kind),\n (basename) => `api::${apiName}.${normalizeName(basename)}`,\n sources,\n outDir,\n logger\n );\n }\n }\n\n return Array.from(sources.values());\n};\n\n/**\n * Keep the sources whose uid the running app registered, sorted by uid\n */\nexport const filterRegisteredSources = (\n sources: AppModuleSource[],\n registered: Record<string, unknown>,\n logger: Logger\n) => {\n const registeredUIDs = new Set(Object.keys(registered));\n\n return sources\n .filter((source) => {\n if (!registeredUIDs.has(source.uid)) {\n logger.debug(`${source.uid} is not registered, ignoring ${source.file}`);\n return false;\n }\n\n return true;\n })\n .sort((a, b) => compareCodeUnits(a.uid, b.uid));\n};\n\n/**\n * Application tsconfigs do not enable `allowJs`, so the import of a JS source does not resolve and is\n * an error type. Unlike `any`, conditional types cannot map it to `unknown`.\n */\nexport const isTypedSource = (source: AppModuleSource) => path.extname(source.file) === '.ts';\n\nconst hasModifier = (statement: ts.Statement, kind: ts.ModifierSyntaxKind) =>\n ts.canHaveModifiers(statement) &&\n (ts.getModifiers(statement) ?? []).some((modifier) => modifier.kind === kind);\n\n/**\n * Whether a top-level statement is `export type <name>` or `export interface <name>`\n */\nconst isExportedTypeDeclarationNamed = (\n statement: ts.Statement,\n name: string\n): statement is ts.TypeAliasDeclaration | ts.InterfaceDeclaration =>\n (ts.isTypeAliasDeclaration(statement) || ts.isInterfaceDeclaration(statement)) &&\n statement.name.text === name &&\n hasModifier(statement, ts.SyntaxKind.ExportKeyword) === true &&\n hasModifier(statement, ts.SyntaxKind.DefaultKeyword) === false;\n\n/**\n * Whether a type declaration can be referenced without type arguments, as the generated file does\n */\nconst hasDefaultTypeArguments = (statement: ts.TypeAliasDeclaration | ts.InterfaceDeclaration) =>\n (statement.typeParameters ?? []).every((parameter) => parameter.default !== undefined);\n\n/**\n * Whether a top-level statement exports a type under `name`: `export type <name>`,\n * `export interface <name>`, or an export specifier named `<name>` (`export { <name> }`,\n * `export { type X as <name> }`, `export type { X as <name> } from './x'`).\n *\n * A generic declaration only counts when each of its type parameters has a default: the generated\n * file references it without type arguments.\n *\n * A specifier may name a value rather than a type, or a generic without defaults: its reference in\n * the generated file does not resolve, and `tsc` reports it there.\n * TODO @Nico a specifier of a local declaration could be checked like the declaration itself\n */\nconst exportsTypeNamed = (statement: ts.Statement, name: string) => {\n if (ts.isTypeAliasDeclaration(statement) || ts.isInterfaceDeclaration(statement)) {\n return (\n isExportedTypeDeclarationNamed(statement, name) === true &&\n hasDefaultTypeArguments(statement) === true\n );\n }\n\n if (\n ts.isExportDeclaration(statement) &&\n statement.exportClause !== undefined &&\n ts.isNamedExports(statement.exportClause)\n ) {\n return statement.exportClause.elements.some((element) => element.name.text === name);\n }\n\n return false;\n};\n\n/**\n * The uids of the TypeScript sources whose module exports a type named `name`, such as a service's\n * `ServiceContract`.\n *\n * Each source is parsed on its own, without a program: type generation runs on every `strapi develop`\n * start, before the compilation, and a program would need the application's tsconfig and its whole\n * dependency graph. Only top-level declarations and export specifiers are read (see\n * `exportsTypeNamed`). `export *` is not followed, and a source that cannot be read is skipped with a\n * warning: both keep the type the source registers without a contract, rather than stopping the\n * generation.\n *\n * JS sources are skipped: their import does not resolve without `allowJs` (see `isTypedSource`).\n */\nexport const findTypeExports = async (\n sources: AppModuleSource[],\n name: string,\n logger: Logger\n): Promise<Set<string>> => {\n // TODO @Nico A JS source could get a contract from a sibling `<name>.d.ts` that exports it: the\n // extension-less import of the source resolves to that file without `allowJs`.\n const typedSources = sources.filter(isTypedSource);\n\n const verdicts = await Promise.all(\n typedSources.map(async (source) => {\n let content: string;\n\n try {\n content = await fs.promises.readFile(source.file, 'utf8');\n } catch (error) {\n logger.warn(\n `Could not read ${source.file} to find its ${name} export, typing ${source.uid} without it: ${\n error instanceof Error ? error.message : String(error)\n }`\n );\n return false;\n }\n\n const sourceFile = ts.createSourceFile(\n source.file,\n content,\n ts.ScriptTarget.Latest,\n false,\n ts.ScriptKind.TS\n );\n\n if (sourceFile.statements.some((statement) => exportsTypeNamed(statement, name)) === true) {\n return true;\n }\n\n if (\n sourceFile.statements.some(\n (statement) =>\n isExportedTypeDeclarationNamed(statement, name) === true &&\n hasDefaultTypeArguments(statement) === false\n ) === true\n ) {\n logger.warn(\n `${source.file} exports ${name} with type parameters that have no default, typing ${source.uid} without it`\n );\n }\n\n if (\n sourceFile.statements.some(\n (statement) => ts.isExportDeclaration(statement) && statement.exportClause === undefined\n ) === true\n ) {\n logger.debug(`${source.uid}: \\`export *\\` is not followed to find a ${name} export`);\n }\n\n return false;\n })\n );\n\n return new Set(typedSources.filter((_, index) => verdicts[index] === true).map(({ uid }) => uid));\n};\n\n/**\n * A type export that replaces the inferred type of the sources that have it, such as a service's\n * `ServiceContract`.\n */\nexport type AppModuleContract = {\n // Name of the type export\n exportName: string;\n // Name of the generated helper that reads it (see `generateContractHelperDefinition`)\n helper: string;\n // Uids of the sources whose module exports it (see `findTypeExports`)\n uids: Set<string>;\n};\n\n/**\n * The type a service or controller source registers:\n * - `<contract helper><import('<source>').<contract export>>` when the module exports the contract;\n * - `<helper><typeof import('<source>')>` otherwise, which infers it from the default export;\n * - `unknown` for a JS source, whose import is an error type without `allowJs` (see `isTypedSource`).\n *\n * The contract does not depend on the default export, so the factory can be checked against its own\n * uid (`Core.ServiceFactory<uid>`). The inferred type does: the generators list those uids in a\n * marker registry (see `isInferredSource`), which the factory types reject.\n */\nexport const instanceTypeOf =\n (helper: string, logger: Logger, contract?: AppModuleContract) =>\n (source: AppModuleSource): ts.TypeNode => {\n if (isTypedSource(source) === false) {\n logger.debug(`${source.uid} has no TypeScript source, registering it as unknown`);\n return factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword);\n }\n\n if (contract !== undefined && contract.uids.has(source.uid) === true) {\n logger.debug(`${source.uid} exports ${contract.exportName}, registering it`);\n return factory.createTypeReferenceNode(contract.helper, [\n importedType(source, contract.exportName),\n ]);\n }\n\n return factory.createTypeReferenceNode(helper, [typeofImport(source)]);\n };\n\n/**\n * Whether a source registers the type its module provides (see `instanceTypeOf`): a TypeScript\n * source whose module does not export the contract.\n */\nexport const isInferredSource = (contract: AppModuleContract) => (source: AppModuleSource) =>\n isTypedSource(source) === true && contract.uids.has(source.uid) === false;\n\n/**\n * typeof import('<relative path to the source>')\n */\nexport const typeofImport = (source: AppModuleSource) =>\n factory.createImportTypeNode(\n factory.createLiteralTypeNode(factory.createStringLiteral(source.specifier, true)),\n undefined,\n undefined,\n undefined,\n true\n );\n\n/**\n * import('<relative path to the source>').<name>\n */\nconst importedType = (source: AppModuleSource, name: string) =>\n factory.createImportTypeNode(\n factory.createLiteralTypeNode(factory.createStringLiteral(source.specifier, true)),\n undefined,\n factory.createIdentifier(name),\n undefined,\n false\n );\n\nexport const withDocComment = <TNode extends ts.Node>(node: TNode, comment: string) =>\n ts.addSyntheticLeadingComment(node, ts.SyntaxKind.MultiLineCommentTrivia, comment, true);\n\n/**\n * type <name><TModule> = TModule extends { default: infer TExport }\n * ? 0 extends 1 & TExport\n * ? unknown\n * : TExport extends (...args: any[]) => infer TInstance ? TInstance : TExport\n * : unknown;\n *\n * Emitted in each file so that services.ts and controllers.ts stand alone, and only when a source\n * registers its inferred type.\n *\n * Resolves the type registered for a service or a controller from the type of its module: the return\n * type of the default export when it is a factory, the default export itself otherwise. A module\n * without a default export registers nothing usable at runtime; with strict types enabled, an\n * unregistered uid resolves to `unknown`, so the helper does the same rather than claiming a\n * permissive contract for it. A module typed `any` and a default export typed `any` resolve to\n * `unknown` too: `any` would match the factory branch and register `any`.\n *\n * An import that no longer resolves (the source moved after the generation) is an error type, which\n * no conditional type maps to `unknown`. The generated file is a `.ts` file, so `tsc` reports the\n * TS2307 there, `skipLibCheck` or not, until the next generation drops the entry.\n */\nexport const generateInstanceHelperDefinition = (name: string, comment: string) => {\n const unwrapFactory = factory.createConditionalTypeNode(\n factory.createTypeReferenceNode('TExport'),\n factory.createFunctionTypeNode(\n undefined,\n [\n factory.createParameterDeclaration(\n undefined,\n factory.createToken(ts.SyntaxKind.DotDotDotToken),\n 'args',\n undefined,\n factory.createArrayTypeNode(factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword))\n ),\n ],\n factory.createInferTypeNode(factory.createTypeParameterDeclaration(undefined, 'TInstance'))\n ),\n factory.createTypeReferenceNode('TInstance'),\n factory.createTypeReferenceNode('TExport')\n );\n\n // 0 extends 1 & TExport: only true when TExport is `any`\n const guardAny = factory.createConditionalTypeNode(\n factory.createLiteralTypeNode(factory.createNumericLiteral(0)),\n factory.createIntersectionTypeNode([\n factory.createLiteralTypeNode(factory.createNumericLiteral(1)),\n factory.createTypeReferenceNode('TExport'),\n ]),\n factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword),\n unwrapFactory\n );\n\n const unwrapDefaultExport = 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 guardAny,\n factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword)\n );\n\n return withDocComment(\n factory.createTypeAliasDeclaration(\n undefined,\n factory.createIdentifier(name),\n [factory.createTypeParameterDeclaration(undefined, 'TModule')],\n unwrapDefaultExport\n ),\n comment\n );\n};\n\n/**\n * type <name><TContract> = 0 extends 1 & TContract ? unknown : TContract;\n *\n * Emitted only when at least one source exports a contract: an application without contracts does\n * not get it.\n *\n * A contract typed `any` registers `unknown`, as for an unregistered uid, rather than turning every\n * lookup of the uid into `any`.\n *\n * A contract reference that no longer resolves to a type (the export was renamed after the\n * generation, or a specifier names a value) is an error type, which no conditional type can map to\n * `unknown` (an alias instantiated with the error type stays the error type). The generated file is a\n * `.ts` file, so `tsc` reports the TS2694/TS2749 there, `skipLibCheck` or not. The next generation,\n * on every `strapi develop` start, registers the source without its contract again.\n */\nexport const generateContractHelperDefinition = (name: string, comment: string) =>\n withDocComment(\n factory.createTypeAliasDeclaration(\n undefined,\n factory.createIdentifier(name),\n [factory.createTypeParameterDeclaration(undefined, 'TContract')],\n factory.createConditionalTypeNode(\n factory.createLiteralTypeNode(factory.createNumericLiteral(0)),\n factory.createIntersectionTypeNode([\n factory.createLiteralTypeNode(factory.createNumericLiteral(1)),\n factory.createTypeReferenceNode('TContract'),\n ]),\n factory.createKeywordTypeNode(ts.SyntaxKind.UnknownKeyword),\n factory.createTypeReferenceNode('TContract')\n )\n ),\n comment\n );\n\n/**\n * A registry that lists uids without typing them, such as the uids registered with their inferred\n * type. Each uid maps to `true`, which nothing reads: the marker never depends on a source.\n */\nexport type AppModuleMarker = {\n registry: string;\n uids: string[];\n};\n\n/**\n * declare global {\n * namespace Strapi {\n * namespace Registries {\n * interface <registry> {\n * '<uid>': <value>;\n * }\n * …\n * }\n * }\n * }\n *\n * The registries are global interfaces, so this augmentation merges with the base declaration and\n * with the application's own entries, whatever module resolution the application uses. Lookups and\n * route configs only consult it once the program opts into strict types.\n */\nconst generateRegistryExtensionDefinition = (\n registries: { registry: string; entries: [uid: string, value: ts.TypeNode][] }[]\n) => {\n const interfaces = registries.map(({ registry, entries }) =>\n factory.createInterfaceDeclaration(\n undefined,\n factory.createIdentifier(registry),\n undefined,\n undefined,\n entries.map(([uid, value]) =>\n factory.createPropertySignature(\n undefined,\n factory.createStringLiteral(uid, true),\n undefined,\n value\n )\n )\n )\n );\n\n const namespaceOf = (name: string, statements: ts.Statement[]) =>\n factory.createModuleDeclaration(\n undefined,\n factory.createIdentifier(name),\n factory.createModuleBlock(statements),\n ts.NodeFlags.Namespace\n );\n\n return factory.createModuleDeclaration(\n [factory.createModifier(ts.SyntaxKind.DeclareKeyword)],\n factory.createIdentifier('global'),\n factory.createModuleBlock([\n namespaceOf(GLOBAL_NAMESPACE, [namespaceOf(REGISTRIES_NAMESPACE, interfaces)]),\n ]),\n ts.NodeFlags.GlobalAugmentation\n );\n};\n\n/**\n * export {};\n *\n * <helpers>\n *\n * declare global { … <registry> … <markers> … }\n *\n * The module marker turns the generated file into a module: the global augmentation is only allowed\n * in one. The helpers come first so that the file stands alone. A marker without uids is not\n * emitted, so that the output of an application without such uids does not change.\n */\nexport const emitRegistryDefinitions = async (\n registry: string,\n helpers: ts.Node[],\n sources: AppModuleSource[],\n toValue: (source: AppModuleSource) => ts.TypeNode,\n markers: AppModuleMarker[] = []\n) => {\n const allDefinitions = [\n // Module marker\n factory.createExportDeclaration(undefined, false, factory.createNamedExports([])),\n\n // Add a newline after the marker\n factory.createIdentifier('\\n'),\n\n // Helpers\n ...helpers,\n\n // Add a newline after the helpers\n factory.createIdentifier('\\n'),\n\n // Global\n generateRegistryExtensionDefinition([\n {\n registry,\n entries: sources.map((source): [string, ts.TypeNode] => [source.uid, toValue(source)]),\n },\n ...markers\n .filter((marker) => marker.uids.length > 0)\n .map((marker) => ({\n registry: marker.registry,\n entries: marker.uids.map((uid): [string, ts.TypeNode] => [\n uid,\n factory.createLiteralTypeNode(factory.createTrue()),\n ]),\n })),\n ]),\n ];\n\n return format(emitDefinitions(allDefinitions));\n};\n"],"names":["factory","ts","GLOBAL_NAMESPACE","REGISTRIES_NAMESPACE","SOURCE_EXTENSIONS","isKebabCase","value","test","normalizeName","name","kebabCase","isSourceFile","fd","isFile","endsWith","includes","path","extname","byExtensionPrecedence","a","b","indexOf","toImportSpecifier","from","to","specifier","relative","split","sep","join","startsWith","collectDirectorySources","dir","toUID","sources","outDir","logger","pathExists","sourceFDs","fs","promises","readdir","withFileTypes","filter","sort","sourceFD","basename","uid","file","has","warn","set","collectAppSources","kind","dirs","Map","global","undefined","api","apiFDs","isDirectory","apiFD","apiName","Array","values","filterRegisteredSources","registered","registeredUIDs","Set","Object","keys","source","debug","compareCodeUnits","isTypedSource","hasModifier","statement","canHaveModifiers","getModifiers","some","modifier","isExportedTypeDeclarationNamed","isTypeAliasDeclaration","isInterfaceDeclaration","text","SyntaxKind","ExportKeyword","DefaultKeyword","hasDefaultTypeArguments","typeParameters","every","parameter","default","exportsTypeNamed","isExportDeclaration","exportClause","isNamedExports","elements","element","findTypeExports","typedSources","verdicts","Promise","all","map","content","readFile","error","Error","message","String","sourceFile","createSourceFile","ScriptTarget","Latest","ScriptKind","TS","statements","_","index","instanceTypeOf","helper","contract","createKeywordTypeNode","UnknownKeyword","uids","exportName","createTypeReferenceNode","importedType","typeofImport","isInferredSource","createImportTypeNode","createLiteralTypeNode","createStringLiteral","createIdentifier","withDocComment","node","comment","addSyntheticLeadingComment","MultiLineCommentTrivia","generateInstanceHelperDefinition","unwrapFactory","createConditionalTypeNode","createFunctionTypeNode","createParameterDeclaration","createToken","DotDotDotToken","createArrayTypeNode","AnyKeyword","createInferTypeNode","createTypeParameterDeclaration","guardAny","createNumericLiteral","createIntersectionTypeNode","unwrapDefaultExport","createTypeLiteralNode","createPropertySignature","createTypeAliasDeclaration","generateContractHelperDefinition","generateRegistryExtensionDefinition","registries","interfaces","registry","entries","createInterfaceDeclaration","namespaceOf","createModuleDeclaration","createModuleBlock","NodeFlags","Namespace","createModifier","DeclareKeyword","GlobalAugmentation","emitRegistryDefinitions","helpers","toValue","markers","allDefinitions","createExportDeclaration","createNamedExports","marker","length","createTrue","format","emitDefinitions"],"mappings":"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"}
|