@@ -12,7 +12,7 @@ import type { ExportSpecifierStructure, Node } from "ts-morph";
12
12
import { ModuleKind, Project, ScriptKind } from "ts-morph";
13
13
14
14
import { BaseCommand } from "../../base";
15
- import { ApiLevel, getApiExports } from "../../library";
15
+ import { ApiLevel, ApiTag, getApiExports } from "../../library";
16
16
import type { CommandLogger } from "../../logging";
17
17
18
18
/**
@@ -96,23 +96,23 @@ export default class GenerateEntrypointsCommand extends BaseCommand<
96
96
97
97
const pathPrefix = getOutPathPrefix(this.flags, packageJson).replace(/\\/g, "/");
98
98
99
- const mapQueryPathToApiLevel : Map<string | RegExp, ApiLevel | undefined> = new Map([
100
- [`${pathPrefix}${outFileAlpha}${outFileSuffix}`, ApiLevel .alpha],
101
- [`${pathPrefix}${outFileBeta}${outFileSuffix}`, ApiLevel .beta],
102
- [`${pathPrefix}${outFilePublic}${outFileSuffix}`, ApiLevel .public],
99
+ const mapQueryPathToApiTagLevel : Map<string | RegExp, ApiTag | undefined> = new Map([
100
+ [`${pathPrefix}${outFileAlpha}${outFileSuffix}`, ApiTag .alpha],
101
+ [`${pathPrefix}${outFileBeta}${outFileSuffix}`, ApiTag .beta],
102
+ [`${pathPrefix}${outFilePublic}${outFileSuffix}`, ApiTag .public],
103
103
]);
104
104
105
105
if (node10TypeCompat) {
106
106
// /internal export may be supported without API level generation; so
107
107
// add query for such path for Node10 type compat generation.
108
108
const dirPath = pathPrefix.replace(/\/[^/]*$/, "");
109
109
const internalPathRegex = new RegExp(`${dirPath}\\/index\\.d\\.?[cm]?ts$`);
110
- mapQueryPathToApiLevel .set(internalPathRegex, undefined);
110
+ mapQueryPathToApiTagLevel .set(internalPathRegex, undefined);
111
111
}
112
112
113
- const { mapApiLevelToOutputPath , mapExportPathToData } = buildOutputMaps(
113
+ const { mapApiTagLevelToOutputPath , mapExportPathToData } = buildOutputMaps(
114
114
packageJson,
115
- mapQueryPathToApiLevel ,
115
+ mapQueryPathToApiTagLevel ,
116
116
node10TypeCompat,
117
117
this.logger,
118
118
);
@@ -121,11 +121,11 @@ export default class GenerateEntrypointsCommand extends BaseCommand<
121
121
122
122
// Requested specific outputs that are not in the output map are explicitly
123
123
// removed for clean incremental build support.
124
- for (const [outputPath, apiLevel] of mapQueryPathToApiLevel .entries()) {
124
+ for (const [outputPath, apiLevel] of mapQueryPathToApiTagLevel .entries()) {
125
125
if (
126
126
apiLevel !== undefined &&
127
127
typeof outputPath === "string" &&
128
- !mapApiLevelToOutputPath .has(apiLevel)
128
+ !mapApiTagLevelToOutputPath .has(apiLevel)
129
129
) {
130
130
promises.push(fs.rm(outputPath, { force: true }));
131
131
}
@@ -137,15 +137,17 @@ export default class GenerateEntrypointsCommand extends BaseCommand<
137
137
);
138
138
}
139
139
140
- if (mapApiLevelToOutputPath .size === 0) {
140
+ if (mapApiTagLevelToOutputPath .size === 0) {
141
141
throw new Error(
142
142
`There are no package exports matching requested output entrypoints:\n\t${[
143
- ...mapQueryPathToApiLevel .keys(),
143
+ ...mapQueryPathToApiTagLevel .keys(),
144
144
].join("\n\t")}`,
145
145
);
146
146
}
147
147
148
- promises.push(generateEntrypoints(mainEntrypoint, mapApiLevelToOutputPath, this.logger));
148
+ promises.push(
149
+ generateEntrypoints(mainEntrypoint, mapApiTagLevelToOutputPath, this.logger),
150
+ );
149
151
150
152
if (node10TypeCompat) {
151
153
promises.push(generateNode10TypeEntrypoints(mapExportPathToData, this.logger));
@@ -202,13 +204,13 @@ function getLocalUnscopedPackageName(packageJson: PackageJson): string {
202
204
type ExportsRecordValue = Exclude<Extract<PackageJson["exports"], object>, unknown[]>;
203
205
204
206
function findTypesPathMatching(
205
- mapQueryPathToApiLevel : Map<string | RegExp, ApiLevel | undefined>,
207
+ mapQueryPathToApiTagLevel : Map<string | RegExp, ApiTag | undefined>,
206
208
exports: ExportsRecordValue,
207
- ): { apiLevel: ApiLevel | undefined; relPath: string; isTypeOnly: boolean } | undefined {
209
+ ): { apiTagLevel: ApiTag | undefined; relPath: string; isTypeOnly: boolean } | undefined {
208
210
for (const [entry, value] of Object.entries(exports)) {
209
211
if (typeof value === "string") {
210
212
if (entry === "types") {
211
- for (const [key, apiLevel ] of mapQueryPathToApiLevel .entries()) {
213
+ for (const [key, apiTagLevel ] of mapQueryPathToApiTagLevel .entries()) {
212
214
// eslint-disable-next-line max-depth
213
215
if (
214
216
typeof key === "string"
@@ -220,15 +222,15 @@ function findTypesPathMatching(
220
222
"import" in exports ||
221
223
"require" in exports
222
224
);
223
- return { apiLevel , relPath: value, isTypeOnly };
225
+ return { apiTagLevel , relPath: value, isTypeOnly };
224
226
}
225
227
}
226
228
}
227
229
} else if (value !== null) {
228
230
if (Array.isArray(value)) {
229
231
continue;
230
232
}
231
- const deepFind = findTypesPathMatching(mapQueryPathToApiLevel , value);
233
+ const deepFind = findTypesPathMatching(mapQueryPathToApiTagLevel , value);
232
234
if (deepFind !== undefined) {
233
235
return deepFind;
234
236
}
@@ -240,14 +242,14 @@ function findTypesPathMatching(
240
242
241
243
function buildOutputMaps(
242
244
packageJson: PackageJson,
243
- mapQueryPathToApiLevel : Map<string | RegExp, ApiLevel | undefined>,
245
+ mapQueryPathToApiTagLevel : Map<string | RegExp, ApiTag | undefined>,
244
246
node10TypeCompat: boolean,
245
247
log: CommandLogger,
246
248
): {
247
- mapApiLevelToOutputPath : Map<ApiLevel , string>;
249
+ mapApiTagLevelToOutputPath : Map<ApiTag , string>;
248
250
mapExportPathToData: Map<string, ExportData>;
249
251
} {
250
- const mapApiLevelToOutputPath = new Map<ApiLevel , string>();
252
+ const mapApiTagLevelToOutputPath = new Map<ApiTag , string>();
251
253
const mapExportPathToData = new Map<string, ExportData>();
252
254
253
255
const { exports } = packageJson;
@@ -275,16 +277,16 @@ function buildOutputMaps(
275
277
continue;
276
278
}
277
279
278
- const findResult = findTypesPathMatching(mapQueryPathToApiLevel , exportValue);
280
+ const findResult = findTypesPathMatching(mapQueryPathToApiTagLevel , exportValue);
279
281
if (findResult !== undefined) {
280
- const { apiLevel , relPath, isTypeOnly } = findResult;
282
+ const { apiTagLevel , relPath, isTypeOnly } = findResult;
281
283
282
284
// Add mapping for API level file generation
283
- if (apiLevel !== undefined) {
284
- if (mapApiLevelToOutputPath .has(apiLevel )) {
285
+ if (apiTagLevel !== undefined) {
286
+ if (mapApiTagLevelToOutputPath .has(apiTagLevel )) {
285
287
log.warning(`${relPath} found in exports multiple times.`);
286
288
} else {
287
- mapApiLevelToOutputPath .set(apiLevel , relPath);
289
+ mapApiTagLevelToOutputPath .set(apiTagLevel , relPath);
288
290
}
289
291
}
290
292
@@ -303,7 +305,7 @@ function buildOutputMaps(
303
305
}
304
306
}
305
307
306
- return { mapApiLevelToOutputPath, mapExportPathToData: mapExportPathToData };
308
+ return { mapApiTagLevelToOutputPath, mapExportPathToData };
307
309
}
308
310
309
311
function sourceContext(node: Node): string {
@@ -324,7 +326,7 @@ const generatedHeader: string = `/*!
324
326
325
327
async function generateEntrypoints(
326
328
mainEntrypoint: string,
327
- mapApiLevelToOutput : Map<ApiLevel , string>,
329
+ mapApiTagLevelToOutput : Map<ApiTag , string>,
328
330
log: CommandLogger,
329
331
): Promise<void> {
330
332
/**
@@ -347,16 +349,16 @@ async function generateEntrypoints(
347
349
const exports = getApiExports(mainSourceFile);
348
350
349
351
// This order is critical as public should include beta should include alpha.
350
- const apiLevels : readonly Exclude<ApiLevel , typeof ApiLevel .internal>[] = [
351
- ApiLevel .public,
352
- ApiLevel .beta,
353
- ApiLevel .alpha,
352
+ const apiTagLevels : readonly Exclude<ApiTag , typeof ApiTag .internal>[] = [
353
+ ApiTag .public,
354
+ ApiTag .beta,
355
+ ApiTag .alpha,
354
356
] as const;
355
357
const namedExports: Omit<ExportSpecifierStructure, "kind">[] = [];
356
358
357
359
if (exports.unknown.size > 0) {
358
360
log.errorLog(
359
- `${exports.unknown.size} export(s) found without a recognized API level:\n\t${[
361
+ `${exports.unknown.size} export(s) found without a recognized API level tag :\n\t${[
360
362
...exports.unknown.entries(),
361
363
]
362
364
.map(
@@ -376,19 +378,19 @@ async function generateEntrypoints(
376
378
namedExports[namedExports.length - 1].trailingTrivia = "\n";
377
379
}
378
380
379
- for (const apiLevel of apiLevels ) {
380
- // Append this levels additional (or only) exports sorted by ascending case-sensitive name
381
+ for (const apiTagLevel of apiTagLevels ) {
382
+ // Append this level's additional (or only) exports sorted by ascending case-sensitive name
381
383
const orgLength = namedExports.length;
382
- const levelExports = [...exports[apiLevel ]].sort((a, b) => (a.name > b.name ? 1 : -1));
384
+ const levelExports = [...exports[apiTagLevel ]].sort((a, b) => (a.name > b.name ? 1 : -1));
383
385
for (const levelExport of levelExports) {
384
386
namedExports.push({ ...levelExport, leadingTrivia: "\n\t" });
385
387
}
386
388
if (namedExports.length > orgLength) {
387
- namedExports[orgLength].leadingTrivia = `\n\t// ${apiLevel } APIs\n\t`;
389
+ namedExports[orgLength].leadingTrivia = `\n\t// @${apiTagLevel } APIs\n\t`;
388
390
namedExports[namedExports.length - 1].trailingTrivia = "\n";
389
391
}
390
392
391
- const outFile = mapApiLevelToOutput .get(apiLevel );
393
+ const outFile = mapApiTagLevelToOutput .get(apiTagLevel );
392
394
if (outFile === undefined) {
393
395
continue;
394
396
}
@@ -413,7 +415,7 @@ async function generateEntrypoints(
413
415
} else {
414
416
// At this point we already know that package "export" has a request
415
417
// for this entrypoint. Warn of emptiness, but make it valid for use.
416
- log.warning(`no exports for ${outFile} using API level ${apiLevel }`);
418
+ log.warning(`no exports for ${outFile} using API level tag ${apiTagLevel }`);
417
419
sourceFile.insertText(0, `${generatedHeader}export {}\n\n`);
418
420
}
419
421
0 commit comments