@kubb/core 0.10.0 → 0.11.1
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/index.d.ts +57 -57
- package/dist/index.js +9 -30
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +10 -29
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,23 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
interface SerializablePluginCache {
|
|
4
|
-
[key: string]: [number, any];
|
|
5
|
-
}
|
|
6
|
-
interface Cache<TCache = any> {
|
|
7
|
-
delete(id: string): boolean;
|
|
8
|
-
get<T = TCache>(id: string): T;
|
|
9
|
-
has(id: string): boolean;
|
|
10
|
-
set<T = TCache>(id: string, value: T): void;
|
|
11
|
-
}
|
|
12
|
-
declare function createPluginCache(cache: SerializablePluginCache): Cache;
|
|
13
|
-
|
|
1
|
+
type WithPromise<T> = Promise<T> | T;
|
|
14
2
|
declare const isPromise: <T>(result: WithPromise<T>) => result is Promise<T>;
|
|
15
3
|
|
|
16
|
-
declare const createQueue: <TArray extends readonly any[] = readonly any[], TInput = TArray[number], TOuput = void>(arr: TArray | undefined, fun: (item: TInput) => WithPromise<TOuput>) => Promise<Awaited<TOuput>[]>;
|
|
17
|
-
|
|
18
|
-
type LogType = 'error' | 'warn' | 'info';
|
|
19
|
-
type LogLevel = LogType | 'silent';
|
|
20
|
-
|
|
21
4
|
type WriteOptions = {
|
|
22
5
|
format: boolean;
|
|
23
6
|
};
|
|
@@ -53,9 +36,19 @@ declare class FileEmitter {
|
|
|
53
36
|
on(...params: Parameters<typeof this$1.emitter['on']>): void;
|
|
54
37
|
private assignReferenceId;
|
|
55
38
|
getEmittedFile: (fileReferenceId?: string | null) => EmittedFile | undefined;
|
|
56
|
-
getFileName: (fileReferenceId: string | null) => string | undefined;
|
|
57
39
|
}
|
|
58
40
|
|
|
41
|
+
interface SerializablePluginCache {
|
|
42
|
+
[key: string]: [number, any];
|
|
43
|
+
}
|
|
44
|
+
interface Cache<TCache = any> {
|
|
45
|
+
delete(id: string): boolean;
|
|
46
|
+
get<T = TCache>(id: string): T;
|
|
47
|
+
has(id: string): boolean;
|
|
48
|
+
set<T = TCache>(id: string, value: T): void;
|
|
49
|
+
}
|
|
50
|
+
declare function createPluginCache(cache: SerializablePluginCache): Cache;
|
|
51
|
+
|
|
59
52
|
/**
|
|
60
53
|
* Get the type of the first argument in a function.
|
|
61
54
|
* @example Arg0<(a: string, b: number) => void> -> string
|
|
@@ -72,7 +65,6 @@ declare class PluginDriver {
|
|
|
72
65
|
constructor(config: Api['config'], pluginCache: Record<string, SerializablePluginCache> | undefined, options: {
|
|
73
66
|
logger: BuildContext['logger'];
|
|
74
67
|
});
|
|
75
|
-
get apis(): ReadonlyMap<Plugin<PluginOptions<unknown, false, any>>, PluginContext>;
|
|
76
68
|
get api(): PluginContext;
|
|
77
69
|
emitFile(...params: Parameters<FileEmitter['emitFile']>): Promise<EmittedFile>;
|
|
78
70
|
resolveId: (source: string, importer: string, meta: Record<string, any> | undefined) => Promise<string | null | undefined>;
|
|
@@ -99,10 +91,18 @@ declare class PluginDriver {
|
|
|
99
91
|
private runHookSync;
|
|
100
92
|
}
|
|
101
93
|
|
|
102
|
-
declare const formatOptions: Options;
|
|
103
94
|
declare const format: (text: string) => string;
|
|
104
95
|
|
|
105
|
-
declare const getRelativePath: (from?: string | null, to?: string | null) => string
|
|
96
|
+
declare const getRelativePath: (from?: string | null, to?: string | null) => string | {
|
|
97
|
+
(searchValue: string | RegExp, replaceValue: string): string;
|
|
98
|
+
(searchValue: string | RegExp, replacer: (substring: string, ...args: any[]) => string): string;
|
|
99
|
+
(searchValue: {
|
|
100
|
+
[Symbol.replace](string: string, replaceValue: string): string;
|
|
101
|
+
}, replaceValue: string): string;
|
|
102
|
+
(searchValue: {
|
|
103
|
+
[Symbol.replace](string: string, replacer: (substring: string, ...args: any[]) => string): string;
|
|
104
|
+
}, replacer: (substring: string, ...args: any[]) => string): string;
|
|
105
|
+
};
|
|
106
106
|
|
|
107
107
|
type PluginOptions<UserOptions = unknown, Nested extends boolean = false, Api = any> = {
|
|
108
108
|
userOptions: UserOptions;
|
|
@@ -117,40 +117,6 @@ type Plugin<TOptions extends PluginOptions = PluginOptions> = {
|
|
|
117
117
|
type PluginFactory<TOptions extends PluginOptions = PluginOptions> = (options: TOptions['userOptions']) => TOptions['nested'] extends true ? Array<Plugin<TOptions>> : Plugin<TOptions>;
|
|
118
118
|
declare function createPlugin<TOptions extends PluginOptions = PluginOptions>(factory: PluginFactory<TOptions>): (userOptions: TOptions['userOptions']) => TOptions["nested"] extends true ? Plugin<TOptions>[] : Plugin<TOptions>;
|
|
119
119
|
|
|
120
|
-
type PluginName = 'string';
|
|
121
|
-
type PluginLifecycle = {
|
|
122
|
-
validate: (this: PluginContext, plugins: Plugin[]) => WithPromise<ValidationResult>;
|
|
123
|
-
buildStart: (this: PluginContext) => WithPromise<void>;
|
|
124
|
-
resolveId: (this: PluginContext, source: string, importer: string | undefined, meta: Record<string, any> | undefined) => string | null | undefined;
|
|
125
|
-
load: (this: PluginContext, id: string) => WithPromise<TransformResult | null>;
|
|
126
|
-
transform: (this: PluginContext, code: string, id: string) => WithPromise<TransformResult>;
|
|
127
|
-
writeFile: (this: PluginContext, code: string | undefined, id: string) => WithPromise<void>;
|
|
128
|
-
buildEnd: (this: PluginContext) => WithPromise<void>;
|
|
129
|
-
};
|
|
130
|
-
type PluginLifecycleHooks = keyof PluginLifecycle;
|
|
131
|
-
type Api = {
|
|
132
|
-
config: UserConfig & {
|
|
133
|
-
root: string;
|
|
134
|
-
};
|
|
135
|
-
schema: Schema;
|
|
136
|
-
emitFile: FileEmitter['emitFile'];
|
|
137
|
-
resolveId: (source: string, importer?: string, meta?: Record<string, any>) => WithPromise<string | null | undefined>;
|
|
138
|
-
load: (id: string) => WithPromise<TransformResult | void>;
|
|
139
|
-
getFileName: FileEmitter['getFileName'];
|
|
140
|
-
getEmittedFile: FileEmitter['getEmittedFile'];
|
|
141
|
-
on: FileEmitter['on'];
|
|
142
|
-
};
|
|
143
|
-
type PluginContext = Api & {
|
|
144
|
-
cache: Cache;
|
|
145
|
-
};
|
|
146
|
-
type ValidationResult = true | {
|
|
147
|
-
message: string;
|
|
148
|
-
};
|
|
149
|
-
type TransformResult = string | null;
|
|
150
|
-
type WithPromise<T> = Promise<T> | T;
|
|
151
|
-
type Id = string;
|
|
152
|
-
type Schema = string;
|
|
153
|
-
|
|
154
120
|
interface ConfigEnv {
|
|
155
121
|
mode: string;
|
|
156
122
|
}
|
|
@@ -193,6 +159,40 @@ type UserConfigExport = WithPromise<UserConfig> | UserConfigFn;
|
|
|
193
159
|
*/
|
|
194
160
|
declare function defineConfig(config: UserConfigExport): UserConfigExport;
|
|
195
161
|
|
|
162
|
+
type PluginName = string;
|
|
163
|
+
type PluginLifecycle = {
|
|
164
|
+
validate: (this: PluginContext, plugins: Plugin[]) => WithPromise<ValidationResult>;
|
|
165
|
+
buildStart: (this: PluginContext) => WithPromise<void>;
|
|
166
|
+
resolveId: (this: PluginContext, source: string, importer: string | undefined, meta: Record<string, any> | undefined) => string | null | undefined;
|
|
167
|
+
load: (this: PluginContext, id: string) => WithPromise<TransformResult | null>;
|
|
168
|
+
transform: (this: PluginContext, code: string, id: string) => WithPromise<TransformResult>;
|
|
169
|
+
writeFile: (this: PluginContext, code: string | undefined, id: string) => WithPromise<void>;
|
|
170
|
+
buildEnd: (this: PluginContext) => WithPromise<void>;
|
|
171
|
+
};
|
|
172
|
+
type PluginLifecycleHooks = keyof PluginLifecycle;
|
|
173
|
+
type Api = {
|
|
174
|
+
config: UserConfig & {
|
|
175
|
+
root: string;
|
|
176
|
+
};
|
|
177
|
+
schema: Schema;
|
|
178
|
+
emitFile: FileEmitter['emitFile'];
|
|
179
|
+
resolveId: (source: string, importer?: string, meta?: Record<string, any>) => WithPromise<string | null | undefined>;
|
|
180
|
+
load: (id: string) => WithPromise<TransformResult | void>;
|
|
181
|
+
getEmittedFile: FileEmitter['getEmittedFile'];
|
|
182
|
+
on: FileEmitter['on'];
|
|
183
|
+
};
|
|
184
|
+
type PluginContext = Api & {
|
|
185
|
+
cache: Cache;
|
|
186
|
+
};
|
|
187
|
+
type ValidationResult = true | {
|
|
188
|
+
message: string;
|
|
189
|
+
};
|
|
190
|
+
type TransformResult = string | null;
|
|
191
|
+
type Id = string;
|
|
192
|
+
type Schema = string;
|
|
193
|
+
type LogType = 'error' | 'warn' | 'info';
|
|
194
|
+
type LogLevel = LogType | 'silent';
|
|
195
|
+
|
|
196
196
|
type BuildOutput = void;
|
|
197
197
|
type Spinner = {
|
|
198
198
|
start: (text?: string) => Spinner;
|
|
@@ -216,4 +216,4 @@ declare function getPluginContext(this: PluginDriver, plugin: Plugin, pluginCach
|
|
|
216
216
|
cache: Cache<any>;
|
|
217
217
|
};
|
|
218
218
|
|
|
219
|
-
export { Api, Argument0, BuildContext, Cache, ConfigEnv, EmitFile, EmittedFile, Emitter, FileEmitter, Id, Listener, LogLevel, LogType, Plugin, PluginContext, PluginDriver, PluginFactory, PluginLifecycle, PluginLifecycleHooks, PluginName, PluginOptions, Schema, SerializablePluginCache, TransformResult, UserConfig, UserConfigExport, UserConfigFn, ValidationResult, WithPromise, build, createPlugin, createPluginCache,
|
|
219
|
+
export { Api, Argument0, BuildContext, Cache, ConfigEnv, EmitFile, EmittedFile, Emitter, FileEmitter, Id, Listener, LogLevel, LogType, Plugin, PluginContext, PluginDriver, PluginFactory, PluginLifecycle, PluginLifecycleHooks, PluginName, PluginOptions, Schema, SerializablePluginCache, TransformResult, UserConfig, UserConfigExport, UserConfigFn, ValidationResult, WithPromise, build, createPlugin, createPluginCache, build as default, defineConfig, format, getPluginContext, getRelativePath, hooks, isPromise, write };
|
package/dist/index.js
CHANGED
|
@@ -91,12 +91,6 @@ var FileEmitter = class {
|
|
|
91
91
|
}
|
|
92
92
|
return this.filesByReferenceId.get(fileReferenceId);
|
|
93
93
|
};
|
|
94
|
-
getFileName = (fileReferenceId) => {
|
|
95
|
-
if (!fileReferenceId) {
|
|
96
|
-
return void 0;
|
|
97
|
-
}
|
|
98
|
-
return this.filesByReferenceId.get(fileReferenceId)?.source;
|
|
99
|
-
};
|
|
100
94
|
};
|
|
101
95
|
|
|
102
96
|
// src/utils/cache.ts
|
|
@@ -147,7 +141,8 @@ function createPlugin(factory) {
|
|
|
147
141
|
return plugin;
|
|
148
142
|
};
|
|
149
143
|
}
|
|
150
|
-
var
|
|
144
|
+
var name = "core";
|
|
145
|
+
var definePlugin = createPlugin((options) => {
|
|
151
146
|
const { fileEmitter, resolveId, load } = options;
|
|
152
147
|
const schema = fse2.readFileSync(path2.resolve(options.config.root, options.config.input.schema), "utf-8");
|
|
153
148
|
const api = {
|
|
@@ -158,14 +153,13 @@ var createCorePlugin = createPlugin((options) => {
|
|
|
158
153
|
return schema;
|
|
159
154
|
},
|
|
160
155
|
on: fileEmitter.on.bind(fileEmitter),
|
|
161
|
-
getFileName: fileEmitter.getFileName.bind(fileEmitter),
|
|
162
156
|
getEmittedFile: fileEmitter.getEmittedFile.bind(fileEmitter),
|
|
163
157
|
emitFile: fileEmitter.emitFile.bind(fileEmitter),
|
|
164
158
|
resolveId,
|
|
165
159
|
load
|
|
166
160
|
};
|
|
167
161
|
return {
|
|
168
|
-
name
|
|
162
|
+
name,
|
|
169
163
|
api
|
|
170
164
|
};
|
|
171
165
|
});
|
|
@@ -193,7 +187,7 @@ var PluginDriver = class {
|
|
|
193
187
|
this.config = config;
|
|
194
188
|
this.fileEmitter = new FileEmitter();
|
|
195
189
|
this.emitFile = this.fileEmitter.emitFile.bind(this.fileEmitter);
|
|
196
|
-
const corePlugin =
|
|
190
|
+
const corePlugin = definePlugin({ config, fileEmitter: this.fileEmitter, load: this.load, resolveId: this.resolveId });
|
|
197
191
|
this.plugins = [corePlugin, ...config.plugins || []];
|
|
198
192
|
const coreApi = corePlugin.api;
|
|
199
193
|
this.pluginContexts = new Map(
|
|
@@ -206,9 +200,6 @@ var PluginDriver = class {
|
|
|
206
200
|
})
|
|
207
201
|
);
|
|
208
202
|
}
|
|
209
|
-
get apis() {
|
|
210
|
-
return this.pluginContexts;
|
|
211
|
-
}
|
|
212
203
|
get api() {
|
|
213
204
|
let context = {};
|
|
214
205
|
this.pluginContexts.forEach((value) => {
|
|
@@ -395,20 +386,6 @@ function defineConfig(config) {
|
|
|
395
386
|
var isPromise = (result) => {
|
|
396
387
|
return typeof result?.then === "function";
|
|
397
388
|
};
|
|
398
|
-
|
|
399
|
-
// src/utils/createQueue.ts
|
|
400
|
-
var createQueue = (arr, fun) => {
|
|
401
|
-
const promises = [];
|
|
402
|
-
arr?.forEach((item) => {
|
|
403
|
-
const result = fun(item);
|
|
404
|
-
if (isPromise(result)) {
|
|
405
|
-
promises.push(result);
|
|
406
|
-
} else {
|
|
407
|
-
promises.push(Promise.resolve(result));
|
|
408
|
-
}
|
|
409
|
-
});
|
|
410
|
-
return Promise.all(promises);
|
|
411
|
-
};
|
|
412
389
|
var formatOptions = {
|
|
413
390
|
tabWidth: 2,
|
|
414
391
|
printWidth: 160,
|
|
@@ -440,7 +417,11 @@ var getRelativePath = (from, to) => {
|
|
|
440
417
|
if (!from || !to) {
|
|
441
418
|
throw new Error("From and to should be filled in when retrieving the relativePath");
|
|
442
419
|
}
|
|
443
|
-
|
|
420
|
+
const newPath = path2.relative(from, to).replace("../", "").replace(".ts", "").trimEnd();
|
|
421
|
+
if (newPath.startsWith("./") || newPath.startsWith("../")) {
|
|
422
|
+
return newPath.replace;
|
|
423
|
+
}
|
|
424
|
+
return `./${newPath}`;
|
|
444
425
|
};
|
|
445
426
|
|
|
446
427
|
// src/index.ts
|
|
@@ -452,11 +433,9 @@ exports.PluginDriver = PluginDriver;
|
|
|
452
433
|
exports.build = build;
|
|
453
434
|
exports.createPlugin = createPlugin;
|
|
454
435
|
exports.createPluginCache = createPluginCache;
|
|
455
|
-
exports.createQueue = createQueue;
|
|
456
436
|
exports.default = src_default;
|
|
457
437
|
exports.defineConfig = defineConfig;
|
|
458
438
|
exports.format = format;
|
|
459
|
-
exports.formatOptions = formatOptions;
|
|
460
439
|
exports.getPluginContext = getPluginContext;
|
|
461
440
|
exports.getRelativePath = getRelativePath;
|
|
462
441
|
exports.hooks = hooks;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/build.ts","../src/utils/Emitter.ts","../src/utils/FileEmitter.ts","../src/utils/cache.ts","../src/context.ts","../src/plugin.ts","../src/utils/PluginDriver.ts","../src/config.ts","../src/utils/isPromise.ts","../src/utils/createQueue.ts","../src/utils/write.ts","../src/utils/format.ts","../src/utils/read.ts","../src/index.ts"],"names":["path","argument0","fse"],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-unused-vars */\n/* eslint-disable @typescript-eslint/no-empty-function */\n/* eslint-disable no-console */\n\nimport path from 'path'\n\nimport { PluginDriver } from './utils/PluginDriver'\n\nimport type { Api, PluginContext, TransformResult, ValidationResult } from './types'\nimport type { UserConfig, ConfigEnv } from './config'\nimport type { LogLevel } from './utils/logger'\nimport type { Plugin } from './plugin'\n\ntype BuildOutput = void\n\n// Same type as ora\ntype Spinner = {\n start: (text?: string) => Spinner\n succeed: (text: string) => Spinner\n stopAndPersist: (options: { text: string }) => Spinner\n render: () => Spinner\n text: string\n info: (text: string) => Spinner\n}\n\nexport type BuildContext = {\n logger?: {\n log: (message: string, logLevel: LogLevel) => void\n spinner?: Spinner\n }\n}\n\nasync function transformReducer(this: PluginContext, previousCode: string, result: TransformResult, _plugin: Plugin) {\n if (result === null) {\n return null\n }\n return result\n}\n\ntype BuildImplementationOptions = {\n config: Api['config']\n env: ConfigEnv\n}\n\nasync function buildImplementation(this: BuildContext, options: BuildImplementationOptions, done: (output: BuildOutput) => void) {\n const { config } = options\n if (config.lifeCycle && config.lifeCycle !== 'plugins') {\n throw new Error('Only lifeCycle plugins possible')\n }\n\n if (config.strategy && config.strategy !== 'lifo') {\n throw new Error('Only strategy fifo possible')\n }\n\n const pluginCache = Object.create(null)\n const pluginDriver = new PluginDriver(config, pluginCache, { logger: this.logger })\n\n const validations = await pluginDriver.hookParallel<'validate', ValidationResult>('validate', [pluginDriver.plugins])\n\n const validationsWithMessage = validations.filter(Boolean)\n\n if (validationsWithMessage.some((validation) => typeof validation !== 'boolean')) {\n validationsWithMessage.forEach((validation) => {\n if (validation && typeof validation !== 'boolean' && validation?.message) {\n this.logger?.log(validation.message, 'warn')\n }\n })\n\n return\n }\n\n pluginDriver.fileEmitter.on('new', async (emittedFile) => {\n if (!emittedFile?.source) {\n return\n }\n\n const resolvedId = await pluginDriver.hookFirst('resolveId', [emittedFile.source, path.resolve(emittedFile.source), emittedFile.meta])\n const id = resolvedId || emittedFile.source\n let { code } = emittedFile\n\n const loadedResult = await pluginDriver.hookFirst('load', [id])\n if (loadedResult) {\n code = loadedResult\n }\n\n if (code) {\n const result = await pluginDriver.hookReduceArg0('transform', [code, id], transformReducer)\n\n await pluginDriver.hookParallel('writeFile', [result, id])\n pluginDriver.fileEmitter.delete(emittedFile.id)\n }\n })\n\n await pluginDriver.hookParallel('buildStart')\n\n pluginDriver.emitFile({\n id: path.resolve(pluginDriver.api.config.root, pluginDriver.api.config.input.schema),\n source: pluginDriver.api.config.input.schema,\n name: undefined,\n code: pluginDriver.api.schema,\n })\n\n pluginDriver.fileEmitter.on('end', async () => {\n await pluginDriver.hookParallel('buildEnd')\n done()\n })\n}\n\nexport function build(this: BuildContext, userConfig: UserConfig, env: ConfigEnv): Promise<BuildOutput> {\n const config: UserConfig = {\n ...userConfig,\n root: userConfig.root || process.cwd(),\n }\n\n return new Promise((resolve) => {\n buildImplementation.call(\n this,\n {\n config,\n env,\n },\n resolve\n )\n })\n}\n","export type Listener<T> = (value?: T) => void\n\nexport class Emitter<TValue = unknown, TTopics = unknown> {\n private readonly listeners: Set<{\n topic?: TTopics\n cb: Listener<TValue>\n }> = new Set()\n\n private readonly topics?: TTopics[]\n\n constructor(topics?: TTopics[]) {\n this.topics = topics\n }\n\n emit(...params: [topic: TTopics, value?: TValue] | [value?: TValue]) {\n const isTopic = (value: any): value is TTopics => !!this.topics?.includes(value)\n\n if (isTopic(params[0])) {\n this.listeners.forEach((listener) => {\n if (listener.topic === params[0]) {\n listener.cb(params[1])\n }\n })\n return\n }\n this.listeners.forEach((listener) => listener.cb(params[0] as TValue))\n }\n\n subscribe: (cb: Listener<TValue>) => () => void = (cb) => {\n const listener = {\n topic: undefined,\n cb,\n }\n this.listeners.add(listener)\n // Unsubscribe\n return () => this.listeners.delete(listener)\n }\n\n on(topic: TTopics, cb: Listener<TValue>) {\n const listener = {\n topic,\n cb,\n }\n this.listeners.add(listener)\n return () => this.listeners.delete(listener)\n }\n\n destroy: () => void = () => this.listeners.clear()\n}\n","import { Emitter } from './Emitter'\n\nexport interface EmittedFile {\n id: string\n // this can be used as a dynamic path, also resolveId will use this as source(first parameter)\n source: string | undefined\n name: string | undefined\n code: string | undefined\n meta?: Record<string, any>\n}\n\nexport type EmitFile = (emittedFile: EmittedFile) => void\n\ntype Topics = 'new' | 'delete' | 'end'\nexport class FileEmitter {\n private readonly emitter: Emitter<EmittedFile, Topics>\n\n private readonly filesByReferenceId: Map<string, EmittedFile> = new Map()\n\n constructor(emitter: Emitter<EmittedFile, Topics> = new Emitter<EmittedFile, Topics>(['delete', 'end', 'new'])) {\n this.emitter = emitter\n }\n\n emitFile(emitedFile: EmittedFile) {\n // save locally in this class\n this.assignReferenceId(emitedFile, emitedFile.id)\n this.emitter.emit('new', emitedFile)\n return new Promise<EmittedFile>((resolve) => {\n const subscribe = this.emitter.on('delete', (deletedFile) => {\n if (deletedFile?.id === emitedFile.id) {\n resolve(deletedFile)\n return subscribe()\n }\n return undefined\n })\n })\n }\n\n delete(fileReferenceId: string) {\n const deletedFile = this.filesByReferenceId.get(fileReferenceId)\n this.filesByReferenceId.delete(fileReferenceId)\n if (this.filesByReferenceId.size === 0) {\n this.emitter.emit('end')\n }\n return this.emitter.emit('delete', deletedFile)\n }\n\n subscribe(...params: Parameters<typeof this.emitter['subscribe']>) {\n this.emitter.subscribe(...params)\n }\n\n on(...params: Parameters<typeof this.emitter['on']>) {\n this.emitter.on(...params)\n }\n\n private assignReferenceId(emittedFile: EmittedFile, fileReferenceId: string | undefined) {\n if (fileReferenceId) {\n this.filesByReferenceId.set(fileReferenceId, emittedFile)\n }\n }\n\n getEmittedFile = (fileReferenceId?: string | null): EmittedFile | undefined => {\n if (!fileReferenceId) {\n return undefined\n }\n return this.filesByReferenceId.get(fileReferenceId)\n }\n\n getFileName = (fileReferenceId: string | null): string | undefined => {\n if (!fileReferenceId) {\n return undefined\n }\n return this.filesByReferenceId.get(fileReferenceId)?.source\n }\n}\n","/* eslint-disable no-param-reassign */\n/* eslint-disable consistent-return */\nexport interface SerializablePluginCache {\n [key: string]: [number, any]\n}\n\nexport interface Cache<TCache = any> {\n delete(id: string): boolean\n get<T = TCache>(id: string): T\n has(id: string): boolean\n set<T = TCache>(id: string, value: T): void\n}\n\nexport function createPluginCache(cache: SerializablePluginCache): Cache {\n return {\n delete(id: string) {\n return delete cache[id]\n },\n get(id: string) {\n const item = cache[id]\n if (!item) return\n item[0] = 0\n return item[1]\n },\n has(id: string) {\n const item = cache[id]\n if (!item) return false\n item[0] = 0\n return true\n },\n set(id: string, value: any) {\n cache[id] = [0, value]\n },\n }\n}\n","/* eslint-disable no-param-reassign */\nimport { createPluginCache } from './utils/cache'\n\nimport type { PluginDriver } from './utils/PluginDriver'\nimport type { SerializablePluginCache } from './utils/cache'\nimport type { Plugin } from './plugin'\n\nexport function getPluginContext(this: PluginDriver, plugin: Plugin, pluginCache: Record<string, SerializablePluginCache> | void) {\n const cacheKey = plugin.cacheKey || (plugin.name as string)\n\n const cacheInstance = createPluginCache(pluginCache[cacheKey] || (pluginCache[cacheKey] = Object.create(null)))\n\n return {\n cache: cacheInstance,\n }\n}\n","/* eslint-disable no-console */\n\nimport path from 'path'\n\nimport fse from 'fs-extra'\n\nimport type { FileEmitter } from './utils'\nimport type { PluginLifecycle, PluginName, Api } from './types'\n\n// use of type objects\nexport type PluginOptions<UserOptions = unknown, Nested extends boolean = false, Api = any> = {\n userOptions: UserOptions\n nested: Nested\n api: Api\n}\n\nexport type Plugin<TOptions extends PluginOptions = PluginOptions> = {\n name: PluginName | Omit<string, PluginName>\n cacheKey?: string\n api?: TOptions['api']\n} & Partial<PluginLifecycle>\n\nexport type PluginFactory<TOptions extends PluginOptions = PluginOptions> = (\n options: TOptions['userOptions']\n) => TOptions['nested'] extends true ? Array<Plugin<TOptions>> : Plugin<TOptions>\n\nexport function createPlugin<TOptions extends PluginOptions = PluginOptions>(factory: PluginFactory<TOptions>) {\n return (userOptions: TOptions['userOptions']) => {\n const plugin = factory(userOptions)\n if (Array.isArray(plugin)) {\n throw new Error('Not implemented')\n }\n\n // default transform\n if (!plugin.transform) {\n plugin.transform = function transform(code) {\n return code\n }\n }\n\n return plugin\n }\n}\n\ntype Options = {\n // root will be filled in with a default value in build(process.cwd)\n config: Api['config']\n fileEmitter: FileEmitter\n resolveId: Api['resolveId']\n load: Api['load']\n}\n\n// not exported\ntype CorePluginOptions = PluginOptions<Options, false, Api>\n\nexport const createCorePlugin = createPlugin<CorePluginOptions>((options) => {\n const { fileEmitter, resolveId, load } = options\n\n const schema = fse.readFileSync(path.resolve(options.config.root, options.config.input.schema), 'utf-8')\n\n const api: Api = {\n get config() {\n return options.config\n },\n get schema() {\n return schema\n },\n on: fileEmitter.on.bind(fileEmitter),\n getFileName: fileEmitter.getFileName.bind(fileEmitter),\n getEmittedFile: fileEmitter.getEmittedFile.bind(fileEmitter),\n emitFile: fileEmitter.emitFile.bind(fileEmitter),\n resolveId,\n load,\n }\n\n return {\n name: 'core',\n api,\n }\n})\n","/* eslint-disable @typescript-eslint/no-non-null-assertion */\n/* eslint-disable @typescript-eslint/no-unused-vars */\n/* eslint-disable no-restricted-syntax */\n/* eslint-disable no-await-in-loop */\n/* eslint-disable no-undef */\n// inspired by: https://github.com/rollup/rollup/blob/master/src/utils/PluginDriver.ts#\n\nimport { FileEmitter } from './FileEmitter'\n\nimport { getPluginContext } from '../context'\nimport { createCorePlugin } from '../plugin'\n\nimport type { BuildContext } from '../build'\nimport type { SerializablePluginCache } from './cache'\nimport type { Plugin } from '../plugin'\nimport type { PluginLifecycleHooks, PluginLifecycle, WithPromise, PluginContext, Api } from '../types'\n\n/**\n * Get the type of the first argument in a function.\n * @example Arg0<(a: string, b: number) => void> -> string\n */\nexport type Argument0<H extends keyof PluginLifecycle> = Parameters<PluginLifecycle[H]>[0]\n\ntype Strategy = 'hookFirst' | 'hookParallel' | 'hookReduceArg0' | 'hookSeq'\n\n// This will make sure no input hook is omitted\nconst hookNames: {\n [P in PluginLifecycleHooks]: 1\n} = {\n validate: 1,\n buildStart: 1,\n resolveId: 1,\n load: 1,\n transform: 1,\n writeFile: 1,\n buildEnd: 1,\n}\nexport const hooks = Object.keys(hookNames) as [PluginLifecycleHooks]\n\nexport class PluginDriver {\n private readonly pluginContexts: ReadonlyMap<Plugin, PluginContext>\n\n public plugins: Plugin[]\n\n public readonly fileEmitter: FileEmitter\n\n private readonly logger?: BuildContext['logger']\n\n private readonly config: Api['config']\n\n private readonly sortedPlugins = new Map<PluginLifecycleHooks, Plugin[]>()\n\n constructor(config: Api['config'], pluginCache: Record<string, SerializablePluginCache> | undefined, options: { logger: BuildContext['logger'] }) {\n this.logger = options.logger\n this.config = config\n\n this.fileEmitter = new FileEmitter()\n\n this.emitFile = this.fileEmitter.emitFile.bind(this.fileEmitter)\n\n const corePlugin = createCorePlugin({ config, fileEmitter: this.fileEmitter, load: this.load, resolveId: this.resolveId })\n this.plugins = [corePlugin, ...(config.plugins || [])]\n const coreApi = corePlugin.api\n this.pluginContexts = new Map(\n this.plugins.map((plugin) => {\n const context = {\n ...coreApi,\n ...getPluginContext.call(this, plugin, pluginCache),\n }\n return [plugin, context]\n })\n )\n }\n\n get apis() {\n return this.pluginContexts\n }\n\n get api() {\n let context = {}\n this.pluginContexts.forEach((value) => {\n context = { ...context, ...value }\n })\n return context as PluginContext\n }\n\n emitFile(...params: Parameters<FileEmitter['emitFile']>) {\n return this.fileEmitter.emitFile(...params)\n }\n\n resolveId = (source: string, importer: string, meta: Record<string, any> | undefined) => {\n return this.hookFirst('resolveId', [source, importer, meta])\n }\n\n load = async (id: string) => {\n const result = await this.hookFirst('load', [id])\n return result\n }\n\n // chains, first non-null result stops and returns\n hookFirst<H extends PluginLifecycleHooks>(\n hookName: H,\n parameters: Parameters<PluginLifecycle[H]>,\n skipped?: ReadonlySet<Plugin> | null\n ): Promise<ReturnType<PluginLifecycle[H]> | null> {\n let promise: Promise<ReturnType<PluginLifecycle[H]> | null> = Promise.resolve(null)\n for (const plugin of this.getSortedPlugins(hookName)) {\n if (skipped && skipped.has(plugin)) continue\n promise = promise.then((result) => {\n if (result != null) return result\n return this.runHook('hookFirst', hookName, parameters, plugin) as any\n })\n }\n return promise\n }\n\n // parallel\n async hookParallel<H extends PluginLifecycleHooks, TOuput = void>(hookName: H, parameters?: Parameters<PluginLifecycle[H]> | undefined) {\n const parallelPromises: Promise<TOuput>[] = []\n\n for (const plugin of this.getSortedPlugins(hookName)) {\n if ((plugin[hookName] as { sequential?: boolean })?.sequential) {\n await Promise.all(parallelPromises)\n parallelPromises.length = 0\n await this.runHook('hookParallel', hookName, parameters, plugin)\n } else {\n const promise: Promise<TOuput> = this.runHook('hookParallel', hookName, parameters, plugin)\n\n parallelPromises.push(promise)\n }\n }\n return Promise.all(parallelPromises)\n }\n\n // chains, reduces returned value, handling the reduced value as the first hook argument\n hookReduceArg0<H extends PluginLifecycleHooks>(\n hookName: H,\n [argument0, ...rest]: Parameters<PluginLifecycle[H]>,\n reduce: (reduction: Argument0<H>, result: ReturnType<PluginLifecycle[H]>, plugin: Plugin) => WithPromise<Argument0<H> | null>\n ): Promise<Argument0<H>> {\n let promise = Promise.resolve(argument0)\n for (const plugin of this.getSortedPlugins(hookName)) {\n promise = promise.then((argument0) =>\n this.runHook('hookReduceArg0', hookName, [argument0, ...rest] as Parameters<PluginLifecycle[H]>, plugin).then((result) =>\n reduce.call(this.api, argument0, result, plugin)\n )\n )\n }\n return promise\n }\n\n // chains\n\n hookSeq<H extends PluginLifecycleHooks>(hookName: H, parameters?: Parameters<PluginLifecycle[H]>) {\n let promise: Promise<void> = Promise.resolve()\n for (const plugin of this.getSortedPlugins(hookName)) {\n promise = promise.then(() => this.runHook('hookSeq', hookName, parameters, plugin))\n }\n return promise.then(noReturn)\n }\n\n private getSortedPlugins(_hookName: keyof PluginLifecycle): Plugin[] {\n return [...this.plugins]\n }\n\n /**\n * Run an async plugin hook and return the result.\n * @param hookName Name of the plugin hook. Must be either in `PluginHooks` or `OutputPluginValueHooks`.\n * @param args Arguments passed to the plugin hook.\n * @param plugin The actual pluginObject to run.\n */\n // Implementation signature\n private runHook<H extends PluginLifecycleHooks, TResult = void>(\n strategy: Strategy,\n hookName: H,\n parameters: unknown[] | undefined,\n plugin: Plugin\n ): Promise<TResult> {\n // We always filter for plugins that support the hook before running it\n const hook = plugin[hookName]!\n // const context = this.pluginContexts.get(plugin) || {};\n\n return Promise.resolve().then(() => {\n if (typeof hook !== 'function') {\n return hook\n }\n\n if (this.config.logLevel === 'info' && this.logger?.spinner) {\n this.logger.spinner.text = `[${strategy}] ${hookName}: Excecuting task for plugin ${plugin.name} \\n`\n }\n\n const hookResult = (hook as any).apply(this.api, parameters)\n\n if (!hookResult?.then) {\n // short circuit for non-thenables and non-Promises\n if (this.config.logLevel === 'info' && this.logger?.spinner) {\n this.logger.spinner.succeed(`[${strategy}] ${hookName}: Excecuting task for plugin ${plugin.name} \\n`)\n }\n return hookResult\n }\n\n return Promise.resolve(hookResult).then((result) => {\n // action was fulfilled\n if (this.config.logLevel === 'info' && this.logger?.spinner) {\n this.logger.spinner.succeed(`[${strategy}] ${hookName}: Excecuting task for plugin ${plugin.name} \\n`)\n }\n return result\n })\n })\n }\n\n /**\n * Run a sync plugin hook and return the result.\n * @param hookName Name of the plugin hook. Must be in `PluginHooks`.\n * @param args Arguments passed to the plugin hook.\n * @param plugin The acutal plugin\n * @param replaceContext When passed, the plugin context can be overridden.\n */\n private runHookSync<H extends PluginLifecycleHooks>(hookName: H, parameters: Parameters<PluginLifecycle[H]>, plugin: Plugin): ReturnType<PluginLifecycle[H]> {\n const hook = plugin[hookName]!\n\n // const context = this.pluginContexts.get(plugin)!;\n\n try {\n // eslint-disable-next-line @typescript-eslint/ban-types\n return (hook as Function).apply(this.api, parameters)\n } catch (error: any) {\n return error\n }\n }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-function\nfunction noReturn() {}\n","import type { WithPromise } from './types'\nimport type { LogLevel } from './utils/logger'\nimport type { Plugin } from './plugin'\n\nexport interface ConfigEnv {\n mode: string\n}\n// TODO revert to this to have multiple options like async, object, ...\n// export type PluginOption = PluginOptions | false | null | undefined | PluginOption[] | Promise<PluginOptions | false | null | undefined | PluginOption[]>;\n\nexport interface UserConfig {\n /**\n * Project root directory. Can be an absolute path, or a path relative from\n * the location of the config file itself.\n * @default process.cwd()\n */\n root?: string\n mode?: 'single'\n /**\n * plugins means it will run context, buildStart, transform and buildEnd based on order of the plugins array\n * Example of an order(plugin x does not have a buildEnd): [buildStart of plugin x, buildStart of plugin y, transform of plugin x, transform of plugin y, buildEnd of plugin y ]\n * Default: plugins\n */\n lifeCycle?: 'plugins'\n /**\n * Default: fifo\n */\n strategy?: 'fifo' | 'lifo'\n input: {\n schema: string\n }\n output: {\n path: string\n }\n /**\n * Array of kubb plugins to use.\n */\n plugins?: Plugin[]\n\n logLevel?: LogLevel\n}\n\nexport type UserConfigFn = (env: ConfigEnv) => WithPromise<UserConfig>\nexport type UserConfigExport = WithPromise<UserConfig> | UserConfigFn\n\n/**\n * Type helper to make it easier to use kubb.config.ts\n * accepts a direct {@link UserConfig} object, or a function that returns it.\n * The function receives a {@link ConfigEnv} object that exposes two properties:\n */\nexport function defineConfig(config: UserConfigExport): UserConfigExport {\n return config\n}\n","import type { WithPromise } from '../types'\n\nexport const isPromise = <T>(result: WithPromise<T>): result is Promise<T> => {\n return typeof (result as any)?.then === 'function'\n}\n","import { isPromise } from './isPromise'\n\nimport type { WithPromise } from '../types'\n\nexport const createQueue = <TArray extends readonly any[] = readonly any[], TInput = TArray[number], TOuput = void>(\n arr: TArray | undefined,\n fun: (item: TInput) => WithPromise<TOuput>\n) => {\n const promises: Promise<TOuput>[] = []\n\n arr?.forEach((item) => {\n const result = fun(item)\n if (isPromise<TOuput>(result)) {\n promises.push(result)\n } else {\n promises.push(Promise.resolve(result))\n }\n })\n\n return Promise.all(promises)\n}\n","/* eslint-disable consistent-return */\nimport fse from 'fs-extra'\n\nimport { format } from './format'\n\ntype WriteOptions = {\n format: boolean\n}\n\nexport const write = async (data: string, path: string, options: WriteOptions = { format: false }) => {\n const formattedData = options.format ? format(data) : data\n\n try {\n await fse.stat(path)\n const oldContent = await fse.readFile(path, { encoding: 'utf-8' })\n if (oldContent?.toString() === formattedData) {\n return\n }\n } catch (_err) {\n return fse.outputFile(path, formattedData)\n }\n\n return fse.outputFile(path, formattedData)\n}\n","import { format as prettierFormat } from 'prettier'\n\nimport type { Options } from 'prettier'\n\nexport const formatOptions: Options = {\n tabWidth: 2,\n printWidth: 160,\n parser: 'typescript',\n singleQuote: true,\n semi: false,\n bracketSameLine: false,\n endOfLine: 'auto',\n}\nexport const format = (text: string) => {\n return prettierFormat(text, formatOptions)\n}\n","import path from 'path'\n\n// TODO check for a better way or resolving the relative path\nexport const getRelativePath = (from?: string | null, to?: string | null) => {\n if (!from || !to) {\n throw new Error('From and to should be filled in when retrieving the relativePath')\n }\n return path.relative(from, to).replace('../', '').replace('.ts', '').trimEnd()\n}\n","/* eslint-disable @typescript-eslint/no-empty-interface */\nimport { build } from './build'\n\nexport * from './config'\nexport * from './build'\nexport { Plugin, PluginOptions, PluginFactory, createPlugin } from './plugin'\nexport * from './utils'\nexport * from './types'\nexport * from './context'\n\nexport default build\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/build.ts","../src/utils/Emitter.ts","../src/utils/FileEmitter.ts","../src/utils/cache.ts","../src/context.ts","../src/plugin.ts","../src/utils/PluginDriver.ts","../src/config.ts","../src/utils/isPromise.ts","../src/utils/write.ts","../src/utils/format.ts","../src/utils/read.ts","../src/index.ts"],"names":["path","argument0","fse"],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-unused-vars */\n/* eslint-disable @typescript-eslint/no-empty-function */\n/* eslint-disable no-console */\n\nimport path from 'path'\n\nimport { PluginDriver } from './utils/PluginDriver'\n\nimport type { Api, PluginContext, TransformResult, ValidationResult, LogLevel } from './types'\nimport type { UserConfig, ConfigEnv } from './config'\nimport type { Plugin } from './plugin'\n\ntype BuildOutput = void\n\n// Same type as ora\ntype Spinner = {\n start: (text?: string) => Spinner\n succeed: (text: string) => Spinner\n stopAndPersist: (options: { text: string }) => Spinner\n render: () => Spinner\n text: string\n info: (text: string) => Spinner\n}\n\nexport type BuildContext = {\n logger?: {\n log: (message: string, logLevel: LogLevel) => void\n spinner?: Spinner\n }\n}\n\nasync function transformReducer(this: PluginContext, previousCode: string, result: TransformResult, _plugin: Plugin) {\n if (result === null) {\n return null\n }\n return result\n}\n\ntype BuildImplementationOptions = {\n config: Api['config']\n env: ConfigEnv\n}\n\nasync function buildImplementation(this: BuildContext, options: BuildImplementationOptions, done: (output: BuildOutput) => void) {\n const { config } = options\n if (config.lifeCycle && config.lifeCycle !== 'plugins') {\n throw new Error('Only lifeCycle plugins possible')\n }\n\n if (config.strategy && config.strategy !== 'lifo') {\n throw new Error('Only strategy fifo possible')\n }\n\n const pluginCache = Object.create(null)\n const pluginDriver = new PluginDriver(config, pluginCache, { logger: this.logger })\n\n const validations = await pluginDriver.hookParallel<'validate', ValidationResult>('validate', [pluginDriver.plugins])\n\n const validationsWithMessage = validations.filter(Boolean)\n\n if (validationsWithMessage.some((validation) => typeof validation !== 'boolean')) {\n validationsWithMessage.forEach((validation) => {\n if (validation && typeof validation !== 'boolean' && validation?.message) {\n this.logger?.log(validation.message, 'warn')\n }\n })\n\n return\n }\n\n pluginDriver.fileEmitter.on('new', async (emittedFile) => {\n if (!emittedFile?.source) {\n return\n }\n\n const resolvedId = await pluginDriver.hookFirst('resolveId', [emittedFile.source, path.resolve(emittedFile.source), emittedFile.meta])\n const id = resolvedId || emittedFile.source\n let { code } = emittedFile\n\n const loadedResult = await pluginDriver.hookFirst('load', [id])\n if (loadedResult) {\n code = loadedResult\n }\n\n if (code) {\n const result = await pluginDriver.hookReduceArg0('transform', [code, id], transformReducer)\n\n await pluginDriver.hookParallel('writeFile', [result, id])\n pluginDriver.fileEmitter.delete(emittedFile.id)\n }\n })\n\n await pluginDriver.hookParallel('buildStart')\n\n pluginDriver.emitFile({\n id: path.resolve(pluginDriver.api.config.root, pluginDriver.api.config.input.schema),\n source: pluginDriver.api.config.input.schema,\n name: undefined,\n code: pluginDriver.api.schema,\n })\n\n pluginDriver.fileEmitter.on('end', async () => {\n await pluginDriver.hookParallel('buildEnd')\n done()\n })\n}\n\nexport function build(this: BuildContext, userConfig: UserConfig, env: ConfigEnv): Promise<BuildOutput> {\n const config: UserConfig = {\n ...userConfig,\n root: userConfig.root || process.cwd(),\n }\n\n return new Promise((resolve) => {\n buildImplementation.call(\n this,\n {\n config,\n env,\n },\n resolve\n )\n })\n}\n","export type Listener<T> = (value?: T) => void\n\nexport class Emitter<TValue = unknown, TTopics = unknown> {\n private readonly listeners: Set<{\n topic?: TTopics\n cb: Listener<TValue>\n }> = new Set()\n\n private readonly topics?: TTopics[]\n\n constructor(topics?: TTopics[]) {\n this.topics = topics\n }\n\n emit(...params: [topic: TTopics, value?: TValue] | [value?: TValue]) {\n const isTopic = (value: any): value is TTopics => !!this.topics?.includes(value)\n\n if (isTopic(params[0])) {\n this.listeners.forEach((listener) => {\n if (listener.topic === params[0]) {\n listener.cb(params[1])\n }\n })\n return\n }\n this.listeners.forEach((listener) => listener.cb(params[0] as TValue))\n }\n\n subscribe: (cb: Listener<TValue>) => () => void = (cb) => {\n const listener = {\n topic: undefined,\n cb,\n }\n this.listeners.add(listener)\n // Unsubscribe\n return () => this.listeners.delete(listener)\n }\n\n on(topic: TTopics, cb: Listener<TValue>) {\n const listener = {\n topic,\n cb,\n }\n this.listeners.add(listener)\n return () => this.listeners.delete(listener)\n }\n\n destroy: () => void = () => this.listeners.clear()\n}\n","import { Emitter } from './Emitter'\n\nexport interface EmittedFile {\n id: string\n // this can be used as a dynamic path, also resolveId will use this as source(first parameter)\n source: string | undefined\n name: string | undefined\n code: string | undefined\n meta?: Record<string, any>\n}\n\nexport type EmitFile = (emittedFile: EmittedFile) => void\n\ntype Topics = 'new' | 'delete' | 'end'\nexport class FileEmitter {\n private readonly emitter: Emitter<EmittedFile, Topics>\n\n private readonly filesByReferenceId: Map<string, EmittedFile> = new Map()\n\n constructor(emitter: Emitter<EmittedFile, Topics> = new Emitter<EmittedFile, Topics>(['delete', 'end', 'new'])) {\n this.emitter = emitter\n }\n\n emitFile(emitedFile: EmittedFile) {\n // save locally in this class\n this.assignReferenceId(emitedFile, emitedFile.id)\n this.emitter.emit('new', emitedFile)\n return new Promise<EmittedFile>((resolve) => {\n const subscribe = this.emitter.on('delete', (deletedFile) => {\n if (deletedFile?.id === emitedFile.id) {\n resolve(deletedFile)\n return subscribe()\n }\n return undefined\n })\n })\n }\n\n delete(fileReferenceId: string) {\n const deletedFile = this.filesByReferenceId.get(fileReferenceId)\n this.filesByReferenceId.delete(fileReferenceId)\n if (this.filesByReferenceId.size === 0) {\n this.emitter.emit('end')\n }\n return this.emitter.emit('delete', deletedFile)\n }\n\n subscribe(...params: Parameters<typeof this.emitter['subscribe']>) {\n this.emitter.subscribe(...params)\n }\n\n on(...params: Parameters<typeof this.emitter['on']>) {\n this.emitter.on(...params)\n }\n\n private assignReferenceId(emittedFile: EmittedFile, fileReferenceId: string | undefined) {\n if (fileReferenceId) {\n this.filesByReferenceId.set(fileReferenceId, emittedFile)\n }\n }\n\n getEmittedFile = (fileReferenceId?: string | null): EmittedFile | undefined => {\n if (!fileReferenceId) {\n return undefined\n }\n return this.filesByReferenceId.get(fileReferenceId)\n }\n}\n","/* eslint-disable no-param-reassign */\n/* eslint-disable consistent-return */\nexport interface SerializablePluginCache {\n [key: string]: [number, any]\n}\n\nexport interface Cache<TCache = any> {\n delete(id: string): boolean\n get<T = TCache>(id: string): T\n has(id: string): boolean\n set<T = TCache>(id: string, value: T): void\n}\n\nexport function createPluginCache(cache: SerializablePluginCache): Cache {\n return {\n delete(id: string) {\n return delete cache[id]\n },\n get(id: string) {\n const item = cache[id]\n if (!item) return\n item[0] = 0\n return item[1]\n },\n has(id: string) {\n const item = cache[id]\n if (!item) return false\n item[0] = 0\n return true\n },\n set(id: string, value: any) {\n cache[id] = [0, value]\n },\n }\n}\n","/* eslint-disable no-param-reassign */\nimport { createPluginCache } from './utils/cache'\n\nimport type { PluginDriver } from './utils/PluginDriver'\nimport type { SerializablePluginCache } from './utils/cache'\nimport type { Plugin } from './plugin'\n\nexport function getPluginContext(this: PluginDriver, plugin: Plugin, pluginCache: Record<string, SerializablePluginCache> | void) {\n const cacheKey = plugin.cacheKey || (plugin.name as string)\n\n const cacheInstance = createPluginCache(pluginCache[cacheKey] || (pluginCache[cacheKey] = Object.create(null)))\n\n return {\n cache: cacheInstance,\n }\n}\n","/* eslint-disable no-console */\n\nimport path from 'path'\n\nimport fse from 'fs-extra'\n\nimport type { FileEmitter } from './utils'\nimport type { PluginLifecycle, PluginName, Api } from './types'\n\n// use of type objects\nexport type PluginOptions<UserOptions = unknown, Nested extends boolean = false, Api = any> = {\n userOptions: UserOptions\n nested: Nested\n api: Api\n}\n\nexport type Plugin<TOptions extends PluginOptions = PluginOptions> = {\n name: PluginName | Omit<string, PluginName>\n cacheKey?: string\n api?: TOptions['api']\n} & Partial<PluginLifecycle>\n\nexport type PluginFactory<TOptions extends PluginOptions = PluginOptions> = (\n options: TOptions['userOptions']\n) => TOptions['nested'] extends true ? Array<Plugin<TOptions>> : Plugin<TOptions>\n\nexport function createPlugin<TOptions extends PluginOptions = PluginOptions>(factory: PluginFactory<TOptions>) {\n return (userOptions: TOptions['userOptions']) => {\n const plugin = factory(userOptions)\n if (Array.isArray(plugin)) {\n throw new Error('Not implemented')\n }\n\n // default transform\n if (!plugin.transform) {\n plugin.transform = function transform(code) {\n return code\n }\n }\n\n return plugin\n }\n}\n\ntype Options = {\n // root will be filled in with a default value in build(process.cwd)\n config: Api['config']\n fileEmitter: FileEmitter\n resolveId: Api['resolveId']\n load: Api['load']\n}\n\n// not exported\ntype CorePluginOptions = PluginOptions<Options, false, Api>\n\nexport const name = 'core' as const\n\nexport const definePlugin = createPlugin<CorePluginOptions>((options) => {\n const { fileEmitter, resolveId, load } = options\n\n const schema = fse.readFileSync(path.resolve(options.config.root, options.config.input.schema), 'utf-8')\n\n const api: Api = {\n get config() {\n return options.config\n },\n get schema() {\n return schema\n },\n on: fileEmitter.on.bind(fileEmitter),\n getEmittedFile: fileEmitter.getEmittedFile.bind(fileEmitter),\n emitFile: fileEmitter.emitFile.bind(fileEmitter),\n resolveId,\n load,\n }\n\n return {\n name,\n api,\n }\n})\n","/* eslint-disable @typescript-eslint/no-non-null-assertion */\n/* eslint-disable @typescript-eslint/no-unused-vars */\n/* eslint-disable no-restricted-syntax */\n/* eslint-disable no-await-in-loop */\n/* eslint-disable no-undef */\n// inspired by: https://github.com/rollup/rollup/blob/master/src/utils/PluginDriver.ts#\n\nimport { FileEmitter } from './FileEmitter'\n\nimport { getPluginContext } from '../context'\nimport { definePlugin } from '../plugin'\n\nimport type { WithPromise } from './isPromise'\nimport type { BuildContext } from '../build'\nimport type { SerializablePluginCache } from './cache'\nimport type { Plugin } from '../plugin'\nimport type { PluginLifecycleHooks, PluginLifecycle, PluginContext, Api } from '../types'\n\n/**\n * Get the type of the first argument in a function.\n * @example Arg0<(a: string, b: number) => void> -> string\n */\nexport type Argument0<H extends keyof PluginLifecycle> = Parameters<PluginLifecycle[H]>[0]\n\ntype Strategy = 'hookFirst' | 'hookParallel' | 'hookReduceArg0' | 'hookSeq'\n\n// This will make sure no input hook is omitted\nconst hookNames: {\n [P in PluginLifecycleHooks]: 1\n} = {\n validate: 1,\n buildStart: 1,\n resolveId: 1,\n load: 1,\n transform: 1,\n writeFile: 1,\n buildEnd: 1,\n}\nexport const hooks = Object.keys(hookNames) as [PluginLifecycleHooks]\n\nexport class PluginDriver {\n private readonly pluginContexts: ReadonlyMap<Plugin, PluginContext>\n\n public plugins: Plugin[]\n\n public readonly fileEmitter: FileEmitter\n\n private readonly logger?: BuildContext['logger']\n\n private readonly config: Api['config']\n\n private readonly sortedPlugins = new Map<PluginLifecycleHooks, Plugin[]>()\n\n constructor(config: Api['config'], pluginCache: Record<string, SerializablePluginCache> | undefined, options: { logger: BuildContext['logger'] }) {\n this.logger = options.logger\n this.config = config\n\n this.fileEmitter = new FileEmitter()\n\n this.emitFile = this.fileEmitter.emitFile.bind(this.fileEmitter)\n\n const corePlugin = definePlugin({ config, fileEmitter: this.fileEmitter, load: this.load, resolveId: this.resolveId })\n this.plugins = [corePlugin, ...(config.plugins || [])]\n const coreApi = corePlugin.api\n this.pluginContexts = new Map(\n this.plugins.map((plugin) => {\n const context = {\n ...coreApi,\n ...getPluginContext.call(this, plugin, pluginCache),\n }\n return [plugin, context]\n })\n )\n }\n\n get api() {\n let context = {}\n this.pluginContexts.forEach((value) => {\n context = { ...context, ...value }\n })\n return context as PluginContext\n }\n\n emitFile(...params: Parameters<FileEmitter['emitFile']>) {\n return this.fileEmitter.emitFile(...params)\n }\n\n resolveId = (source: string, importer: string, meta: Record<string, any> | undefined) => {\n return this.hookFirst('resolveId', [source, importer, meta])\n }\n\n load = async (id: string) => {\n const result = await this.hookFirst('load', [id])\n return result\n }\n\n // chains, first non-null result stops and returns\n hookFirst<H extends PluginLifecycleHooks>(\n hookName: H,\n parameters: Parameters<PluginLifecycle[H]>,\n skipped?: ReadonlySet<Plugin> | null\n ): Promise<ReturnType<PluginLifecycle[H]> | null> {\n let promise: Promise<ReturnType<PluginLifecycle[H]> | null> = Promise.resolve(null)\n for (const plugin of this.getSortedPlugins(hookName)) {\n if (skipped && skipped.has(plugin)) continue\n promise = promise.then((result) => {\n if (result != null) return result\n return this.runHook('hookFirst', hookName, parameters, plugin) as any\n })\n }\n return promise\n }\n\n // parallel\n async hookParallel<H extends PluginLifecycleHooks, TOuput = void>(hookName: H, parameters?: Parameters<PluginLifecycle[H]> | undefined) {\n const parallelPromises: Promise<TOuput>[] = []\n\n for (const plugin of this.getSortedPlugins(hookName)) {\n if ((plugin[hookName] as { sequential?: boolean })?.sequential) {\n await Promise.all(parallelPromises)\n parallelPromises.length = 0\n await this.runHook('hookParallel', hookName, parameters, plugin)\n } else {\n const promise: Promise<TOuput> = this.runHook('hookParallel', hookName, parameters, plugin)\n\n parallelPromises.push(promise)\n }\n }\n return Promise.all(parallelPromises)\n }\n\n // chains, reduces returned value, handling the reduced value as the first hook argument\n hookReduceArg0<H extends PluginLifecycleHooks>(\n hookName: H,\n [argument0, ...rest]: Parameters<PluginLifecycle[H]>,\n reduce: (reduction: Argument0<H>, result: ReturnType<PluginLifecycle[H]>, plugin: Plugin) => WithPromise<Argument0<H> | null>\n ): Promise<Argument0<H>> {\n let promise = Promise.resolve(argument0)\n for (const plugin of this.getSortedPlugins(hookName)) {\n promise = promise.then((argument0) =>\n this.runHook('hookReduceArg0', hookName, [argument0, ...rest] as Parameters<PluginLifecycle[H]>, plugin).then((result) =>\n reduce.call(this.api, argument0, result, plugin)\n )\n )\n }\n return promise\n }\n\n // chains\n\n hookSeq<H extends PluginLifecycleHooks>(hookName: H, parameters?: Parameters<PluginLifecycle[H]>) {\n let promise: Promise<void> = Promise.resolve()\n for (const plugin of this.getSortedPlugins(hookName)) {\n promise = promise.then(() => this.runHook('hookSeq', hookName, parameters, plugin))\n }\n return promise.then(noReturn)\n }\n\n private getSortedPlugins(_hookName: keyof PluginLifecycle): Plugin[] {\n return [...this.plugins]\n }\n\n /**\n * Run an async plugin hook and return the result.\n * @param hookName Name of the plugin hook. Must be either in `PluginHooks` or `OutputPluginValueHooks`.\n * @param args Arguments passed to the plugin hook.\n * @param plugin The actual pluginObject to run.\n */\n // Implementation signature\n private runHook<H extends PluginLifecycleHooks, TResult = void>(\n strategy: Strategy,\n hookName: H,\n parameters: unknown[] | undefined,\n plugin: Plugin\n ): Promise<TResult> {\n // We always filter for plugins that support the hook before running it\n const hook = plugin[hookName]!\n // const context = this.pluginContexts.get(plugin) || {};\n\n return Promise.resolve().then(() => {\n if (typeof hook !== 'function') {\n return hook\n }\n\n if (this.config.logLevel === 'info' && this.logger?.spinner) {\n this.logger.spinner.text = `[${strategy}] ${hookName}: Excecuting task for plugin ${plugin.name} \\n`\n }\n\n const hookResult = (hook as any).apply(this.api, parameters)\n\n if (!hookResult?.then) {\n // short circuit for non-thenables and non-Promises\n if (this.config.logLevel === 'info' && this.logger?.spinner) {\n this.logger.spinner.succeed(`[${strategy}] ${hookName}: Excecuting task for plugin ${plugin.name} \\n`)\n }\n return hookResult\n }\n\n return Promise.resolve(hookResult).then((result) => {\n // action was fulfilled\n if (this.config.logLevel === 'info' && this.logger?.spinner) {\n this.logger.spinner.succeed(`[${strategy}] ${hookName}: Excecuting task for plugin ${plugin.name} \\n`)\n }\n return result\n })\n })\n }\n\n /**\n * Run a sync plugin hook and return the result.\n * @param hookName Name of the plugin hook. Must be in `PluginHooks`.\n * @param args Arguments passed to the plugin hook.\n * @param plugin The acutal plugin\n * @param replaceContext When passed, the plugin context can be overridden.\n */\n private runHookSync<H extends PluginLifecycleHooks>(hookName: H, parameters: Parameters<PluginLifecycle[H]>, plugin: Plugin): ReturnType<PluginLifecycle[H]> {\n const hook = plugin[hookName]!\n\n // const context = this.pluginContexts.get(plugin)!;\n\n try {\n // eslint-disable-next-line @typescript-eslint/ban-types\n return (hook as Function).apply(this.api, parameters)\n } catch (error: any) {\n return error\n }\n }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-function\nfunction noReturn() {}\n","import type { WithPromise } from './utils/isPromise'\nimport type { LogLevel } from './types'\nimport type { Plugin } from './plugin'\n\nexport interface ConfigEnv {\n mode: string\n}\n// TODO revert to this to have multiple options like async, object, ...\n// export type PluginOption = PluginOptions | false | null | undefined | PluginOption[] | Promise<PluginOptions | false | null | undefined | PluginOption[]>;\n\nexport interface UserConfig {\n /**\n * Project root directory. Can be an absolute path, or a path relative from\n * the location of the config file itself.\n * @default process.cwd()\n */\n root?: string\n mode?: 'single'\n /**\n * plugins means it will run context, buildStart, transform and buildEnd based on order of the plugins array\n * Example of an order(plugin x does not have a buildEnd): [buildStart of plugin x, buildStart of plugin y, transform of plugin x, transform of plugin y, buildEnd of plugin y ]\n * Default: plugins\n */\n lifeCycle?: 'plugins'\n /**\n * Default: fifo\n */\n strategy?: 'fifo' | 'lifo'\n input: {\n schema: string\n }\n output: {\n path: string\n }\n /**\n * Array of kubb plugins to use.\n */\n plugins?: Plugin[]\n\n logLevel?: LogLevel\n}\n\nexport type UserConfigFn = (env: ConfigEnv) => WithPromise<UserConfig>\nexport type UserConfigExport = WithPromise<UserConfig> | UserConfigFn\n\n/**\n * Type helper to make it easier to use kubb.config.ts\n * accepts a direct {@link UserConfig} object, or a function that returns it.\n * The function receives a {@link ConfigEnv} object that exposes two properties:\n */\nexport function defineConfig(config: UserConfigExport): UserConfigExport {\n return config\n}\n","export type WithPromise<T> = Promise<T> | T\n\nexport const isPromise = <T>(result: WithPromise<T>): result is Promise<T> => {\n return typeof (result as any)?.then === 'function'\n}\n","/* eslint-disable consistent-return */\nimport fse from 'fs-extra'\n\nimport { format } from './format'\n\ntype WriteOptions = {\n format: boolean\n}\n\nexport const write = async (data: string, path: string, options: WriteOptions = { format: false }) => {\n const formattedData = options.format ? format(data) : data\n\n try {\n await fse.stat(path)\n const oldContent = await fse.readFile(path, { encoding: 'utf-8' })\n if (oldContent?.toString() === formattedData) {\n return\n }\n } catch (_err) {\n return fse.outputFile(path, formattedData)\n }\n\n return fse.outputFile(path, formattedData)\n}\n","import { format as prettierFormat } from 'prettier'\n\nimport type { Options } from 'prettier'\n\nconst formatOptions: Options = {\n tabWidth: 2,\n printWidth: 160,\n parser: 'typescript',\n singleQuote: true,\n semi: false,\n bracketSameLine: false,\n endOfLine: 'auto',\n}\nexport const format = (text: string) => {\n return prettierFormat(text, formatOptions)\n}\n","import path from 'path'\n\n// TODO check for a better way or resolving the relative path\nexport const getRelativePath = (from?: string | null, to?: string | null) => {\n if (!from || !to) {\n throw new Error('From and to should be filled in when retrieving the relativePath')\n }\n const newPath = path.relative(from, to).replace('../', '').replace('.ts', '').trimEnd()\n\n if (newPath.startsWith('./') || newPath.startsWith('../')) {\n return newPath.replace\n }\n return `./${newPath}`\n}\n","/* eslint-disable @typescript-eslint/no-empty-interface */\nimport { build } from './build'\n\nexport * from './config'\nexport * from './build'\nexport { Plugin, PluginOptions, PluginFactory, createPlugin } from './plugin'\nexport * from './utils'\nexport * from './types'\nexport * from './context'\n\nexport default build\n"]}
|
package/dist/index.mjs
CHANGED
|
@@ -87,12 +87,6 @@ var FileEmitter = class {
|
|
|
87
87
|
}
|
|
88
88
|
return this.filesByReferenceId.get(fileReferenceId);
|
|
89
89
|
};
|
|
90
|
-
getFileName = (fileReferenceId) => {
|
|
91
|
-
if (!fileReferenceId) {
|
|
92
|
-
return void 0;
|
|
93
|
-
}
|
|
94
|
-
return this.filesByReferenceId.get(fileReferenceId)?.source;
|
|
95
|
-
};
|
|
96
90
|
};
|
|
97
91
|
|
|
98
92
|
// src/utils/cache.ts
|
|
@@ -143,7 +137,8 @@ function createPlugin(factory) {
|
|
|
143
137
|
return plugin;
|
|
144
138
|
};
|
|
145
139
|
}
|
|
146
|
-
var
|
|
140
|
+
var name = "core";
|
|
141
|
+
var definePlugin = createPlugin((options) => {
|
|
147
142
|
const { fileEmitter, resolveId, load } = options;
|
|
148
143
|
const schema = fse2.readFileSync(path2.resolve(options.config.root, options.config.input.schema), "utf-8");
|
|
149
144
|
const api = {
|
|
@@ -154,14 +149,13 @@ var createCorePlugin = createPlugin((options) => {
|
|
|
154
149
|
return schema;
|
|
155
150
|
},
|
|
156
151
|
on: fileEmitter.on.bind(fileEmitter),
|
|
157
|
-
getFileName: fileEmitter.getFileName.bind(fileEmitter),
|
|
158
152
|
getEmittedFile: fileEmitter.getEmittedFile.bind(fileEmitter),
|
|
159
153
|
emitFile: fileEmitter.emitFile.bind(fileEmitter),
|
|
160
154
|
resolveId,
|
|
161
155
|
load
|
|
162
156
|
};
|
|
163
157
|
return {
|
|
164
|
-
name
|
|
158
|
+
name,
|
|
165
159
|
api
|
|
166
160
|
};
|
|
167
161
|
});
|
|
@@ -189,7 +183,7 @@ var PluginDriver = class {
|
|
|
189
183
|
this.config = config;
|
|
190
184
|
this.fileEmitter = new FileEmitter();
|
|
191
185
|
this.emitFile = this.fileEmitter.emitFile.bind(this.fileEmitter);
|
|
192
|
-
const corePlugin =
|
|
186
|
+
const corePlugin = definePlugin({ config, fileEmitter: this.fileEmitter, load: this.load, resolveId: this.resolveId });
|
|
193
187
|
this.plugins = [corePlugin, ...config.plugins || []];
|
|
194
188
|
const coreApi = corePlugin.api;
|
|
195
189
|
this.pluginContexts = new Map(
|
|
@@ -202,9 +196,6 @@ var PluginDriver = class {
|
|
|
202
196
|
})
|
|
203
197
|
);
|
|
204
198
|
}
|
|
205
|
-
get apis() {
|
|
206
|
-
return this.pluginContexts;
|
|
207
|
-
}
|
|
208
199
|
get api() {
|
|
209
200
|
let context = {};
|
|
210
201
|
this.pluginContexts.forEach((value) => {
|
|
@@ -391,20 +382,6 @@ function defineConfig(config) {
|
|
|
391
382
|
var isPromise = (result) => {
|
|
392
383
|
return typeof result?.then === "function";
|
|
393
384
|
};
|
|
394
|
-
|
|
395
|
-
// src/utils/createQueue.ts
|
|
396
|
-
var createQueue = (arr, fun) => {
|
|
397
|
-
const promises = [];
|
|
398
|
-
arr?.forEach((item) => {
|
|
399
|
-
const result = fun(item);
|
|
400
|
-
if (isPromise(result)) {
|
|
401
|
-
promises.push(result);
|
|
402
|
-
} else {
|
|
403
|
-
promises.push(Promise.resolve(result));
|
|
404
|
-
}
|
|
405
|
-
});
|
|
406
|
-
return Promise.all(promises);
|
|
407
|
-
};
|
|
408
385
|
var formatOptions = {
|
|
409
386
|
tabWidth: 2,
|
|
410
387
|
printWidth: 160,
|
|
@@ -436,12 +413,16 @@ var getRelativePath = (from, to) => {
|
|
|
436
413
|
if (!from || !to) {
|
|
437
414
|
throw new Error("From and to should be filled in when retrieving the relativePath");
|
|
438
415
|
}
|
|
439
|
-
|
|
416
|
+
const newPath = path2.relative(from, to).replace("../", "").replace(".ts", "").trimEnd();
|
|
417
|
+
if (newPath.startsWith("./") || newPath.startsWith("../")) {
|
|
418
|
+
return newPath.replace;
|
|
419
|
+
}
|
|
420
|
+
return `./${newPath}`;
|
|
440
421
|
};
|
|
441
422
|
|
|
442
423
|
// src/index.ts
|
|
443
424
|
var src_default = build;
|
|
444
425
|
|
|
445
|
-
export { Emitter, FileEmitter, PluginDriver, build, createPlugin, createPluginCache,
|
|
426
|
+
export { Emitter, FileEmitter, PluginDriver, build, createPlugin, createPluginCache, src_default as default, defineConfig, format, getPluginContext, getRelativePath, hooks, isPromise, write };
|
|
446
427
|
//# sourceMappingURL=out.js.map
|
|
447
428
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/build.ts","../src/utils/Emitter.ts","../src/utils/FileEmitter.ts","../src/utils/cache.ts","../src/context.ts","../src/plugin.ts","../src/utils/PluginDriver.ts","../src/config.ts","../src/utils/isPromise.ts","../src/utils/createQueue.ts","../src/utils/write.ts","../src/utils/format.ts","../src/utils/read.ts","../src/index.ts"],"names":["path","argument0","fse"],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-unused-vars */\n/* eslint-disable @typescript-eslint/no-empty-function */\n/* eslint-disable no-console */\n\nimport path from 'path'\n\nimport { PluginDriver } from './utils/PluginDriver'\n\nimport type { Api, PluginContext, TransformResult, ValidationResult } from './types'\nimport type { UserConfig, ConfigEnv } from './config'\nimport type { LogLevel } from './utils/logger'\nimport type { Plugin } from './plugin'\n\ntype BuildOutput = void\n\n// Same type as ora\ntype Spinner = {\n start: (text?: string) => Spinner\n succeed: (text: string) => Spinner\n stopAndPersist: (options: { text: string }) => Spinner\n render: () => Spinner\n text: string\n info: (text: string) => Spinner\n}\n\nexport type BuildContext = {\n logger?: {\n log: (message: string, logLevel: LogLevel) => void\n spinner?: Spinner\n }\n}\n\nasync function transformReducer(this: PluginContext, previousCode: string, result: TransformResult, _plugin: Plugin) {\n if (result === null) {\n return null\n }\n return result\n}\n\ntype BuildImplementationOptions = {\n config: Api['config']\n env: ConfigEnv\n}\n\nasync function buildImplementation(this: BuildContext, options: BuildImplementationOptions, done: (output: BuildOutput) => void) {\n const { config } = options\n if (config.lifeCycle && config.lifeCycle !== 'plugins') {\n throw new Error('Only lifeCycle plugins possible')\n }\n\n if (config.strategy && config.strategy !== 'lifo') {\n throw new Error('Only strategy fifo possible')\n }\n\n const pluginCache = Object.create(null)\n const pluginDriver = new PluginDriver(config, pluginCache, { logger: this.logger })\n\n const validations = await pluginDriver.hookParallel<'validate', ValidationResult>('validate', [pluginDriver.plugins])\n\n const validationsWithMessage = validations.filter(Boolean)\n\n if (validationsWithMessage.some((validation) => typeof validation !== 'boolean')) {\n validationsWithMessage.forEach((validation) => {\n if (validation && typeof validation !== 'boolean' && validation?.message) {\n this.logger?.log(validation.message, 'warn')\n }\n })\n\n return\n }\n\n pluginDriver.fileEmitter.on('new', async (emittedFile) => {\n if (!emittedFile?.source) {\n return\n }\n\n const resolvedId = await pluginDriver.hookFirst('resolveId', [emittedFile.source, path.resolve(emittedFile.source), emittedFile.meta])\n const id = resolvedId || emittedFile.source\n let { code } = emittedFile\n\n const loadedResult = await pluginDriver.hookFirst('load', [id])\n if (loadedResult) {\n code = loadedResult\n }\n\n if (code) {\n const result = await pluginDriver.hookReduceArg0('transform', [code, id], transformReducer)\n\n await pluginDriver.hookParallel('writeFile', [result, id])\n pluginDriver.fileEmitter.delete(emittedFile.id)\n }\n })\n\n await pluginDriver.hookParallel('buildStart')\n\n pluginDriver.emitFile({\n id: path.resolve(pluginDriver.api.config.root, pluginDriver.api.config.input.schema),\n source: pluginDriver.api.config.input.schema,\n name: undefined,\n code: pluginDriver.api.schema,\n })\n\n pluginDriver.fileEmitter.on('end', async () => {\n await pluginDriver.hookParallel('buildEnd')\n done()\n })\n}\n\nexport function build(this: BuildContext, userConfig: UserConfig, env: ConfigEnv): Promise<BuildOutput> {\n const config: UserConfig = {\n ...userConfig,\n root: userConfig.root || process.cwd(),\n }\n\n return new Promise((resolve) => {\n buildImplementation.call(\n this,\n {\n config,\n env,\n },\n resolve\n )\n })\n}\n","export type Listener<T> = (value?: T) => void\n\nexport class Emitter<TValue = unknown, TTopics = unknown> {\n private readonly listeners: Set<{\n topic?: TTopics\n cb: Listener<TValue>\n }> = new Set()\n\n private readonly topics?: TTopics[]\n\n constructor(topics?: TTopics[]) {\n this.topics = topics\n }\n\n emit(...params: [topic: TTopics, value?: TValue] | [value?: TValue]) {\n const isTopic = (value: any): value is TTopics => !!this.topics?.includes(value)\n\n if (isTopic(params[0])) {\n this.listeners.forEach((listener) => {\n if (listener.topic === params[0]) {\n listener.cb(params[1])\n }\n })\n return\n }\n this.listeners.forEach((listener) => listener.cb(params[0] as TValue))\n }\n\n subscribe: (cb: Listener<TValue>) => () => void = (cb) => {\n const listener = {\n topic: undefined,\n cb,\n }\n this.listeners.add(listener)\n // Unsubscribe\n return () => this.listeners.delete(listener)\n }\n\n on(topic: TTopics, cb: Listener<TValue>) {\n const listener = {\n topic,\n cb,\n }\n this.listeners.add(listener)\n return () => this.listeners.delete(listener)\n }\n\n destroy: () => void = () => this.listeners.clear()\n}\n","import { Emitter } from './Emitter'\n\nexport interface EmittedFile {\n id: string\n // this can be used as a dynamic path, also resolveId will use this as source(first parameter)\n source: string | undefined\n name: string | undefined\n code: string | undefined\n meta?: Record<string, any>\n}\n\nexport type EmitFile = (emittedFile: EmittedFile) => void\n\ntype Topics = 'new' | 'delete' | 'end'\nexport class FileEmitter {\n private readonly emitter: Emitter<EmittedFile, Topics>\n\n private readonly filesByReferenceId: Map<string, EmittedFile> = new Map()\n\n constructor(emitter: Emitter<EmittedFile, Topics> = new Emitter<EmittedFile, Topics>(['delete', 'end', 'new'])) {\n this.emitter = emitter\n }\n\n emitFile(emitedFile: EmittedFile) {\n // save locally in this class\n this.assignReferenceId(emitedFile, emitedFile.id)\n this.emitter.emit('new', emitedFile)\n return new Promise<EmittedFile>((resolve) => {\n const subscribe = this.emitter.on('delete', (deletedFile) => {\n if (deletedFile?.id === emitedFile.id) {\n resolve(deletedFile)\n return subscribe()\n }\n return undefined\n })\n })\n }\n\n delete(fileReferenceId: string) {\n const deletedFile = this.filesByReferenceId.get(fileReferenceId)\n this.filesByReferenceId.delete(fileReferenceId)\n if (this.filesByReferenceId.size === 0) {\n this.emitter.emit('end')\n }\n return this.emitter.emit('delete', deletedFile)\n }\n\n subscribe(...params: Parameters<typeof this.emitter['subscribe']>) {\n this.emitter.subscribe(...params)\n }\n\n on(...params: Parameters<typeof this.emitter['on']>) {\n this.emitter.on(...params)\n }\n\n private assignReferenceId(emittedFile: EmittedFile, fileReferenceId: string | undefined) {\n if (fileReferenceId) {\n this.filesByReferenceId.set(fileReferenceId, emittedFile)\n }\n }\n\n getEmittedFile = (fileReferenceId?: string | null): EmittedFile | undefined => {\n if (!fileReferenceId) {\n return undefined\n }\n return this.filesByReferenceId.get(fileReferenceId)\n }\n\n getFileName = (fileReferenceId: string | null): string | undefined => {\n if (!fileReferenceId) {\n return undefined\n }\n return this.filesByReferenceId.get(fileReferenceId)?.source\n }\n}\n","/* eslint-disable no-param-reassign */\n/* eslint-disable consistent-return */\nexport interface SerializablePluginCache {\n [key: string]: [number, any]\n}\n\nexport interface Cache<TCache = any> {\n delete(id: string): boolean\n get<T = TCache>(id: string): T\n has(id: string): boolean\n set<T = TCache>(id: string, value: T): void\n}\n\nexport function createPluginCache(cache: SerializablePluginCache): Cache {\n return {\n delete(id: string) {\n return delete cache[id]\n },\n get(id: string) {\n const item = cache[id]\n if (!item) return\n item[0] = 0\n return item[1]\n },\n has(id: string) {\n const item = cache[id]\n if (!item) return false\n item[0] = 0\n return true\n },\n set(id: string, value: any) {\n cache[id] = [0, value]\n },\n }\n}\n","/* eslint-disable no-param-reassign */\nimport { createPluginCache } from './utils/cache'\n\nimport type { PluginDriver } from './utils/PluginDriver'\nimport type { SerializablePluginCache } from './utils/cache'\nimport type { Plugin } from './plugin'\n\nexport function getPluginContext(this: PluginDriver, plugin: Plugin, pluginCache: Record<string, SerializablePluginCache> | void) {\n const cacheKey = plugin.cacheKey || (plugin.name as string)\n\n const cacheInstance = createPluginCache(pluginCache[cacheKey] || (pluginCache[cacheKey] = Object.create(null)))\n\n return {\n cache: cacheInstance,\n }\n}\n","/* eslint-disable no-console */\n\nimport path from 'path'\n\nimport fse from 'fs-extra'\n\nimport type { FileEmitter } from './utils'\nimport type { PluginLifecycle, PluginName, Api } from './types'\n\n// use of type objects\nexport type PluginOptions<UserOptions = unknown, Nested extends boolean = false, Api = any> = {\n userOptions: UserOptions\n nested: Nested\n api: Api\n}\n\nexport type Plugin<TOptions extends PluginOptions = PluginOptions> = {\n name: PluginName | Omit<string, PluginName>\n cacheKey?: string\n api?: TOptions['api']\n} & Partial<PluginLifecycle>\n\nexport type PluginFactory<TOptions extends PluginOptions = PluginOptions> = (\n options: TOptions['userOptions']\n) => TOptions['nested'] extends true ? Array<Plugin<TOptions>> : Plugin<TOptions>\n\nexport function createPlugin<TOptions extends PluginOptions = PluginOptions>(factory: PluginFactory<TOptions>) {\n return (userOptions: TOptions['userOptions']) => {\n const plugin = factory(userOptions)\n if (Array.isArray(plugin)) {\n throw new Error('Not implemented')\n }\n\n // default transform\n if (!plugin.transform) {\n plugin.transform = function transform(code) {\n return code\n }\n }\n\n return plugin\n }\n}\n\ntype Options = {\n // root will be filled in with a default value in build(process.cwd)\n config: Api['config']\n fileEmitter: FileEmitter\n resolveId: Api['resolveId']\n load: Api['load']\n}\n\n// not exported\ntype CorePluginOptions = PluginOptions<Options, false, Api>\n\nexport const createCorePlugin = createPlugin<CorePluginOptions>((options) => {\n const { fileEmitter, resolveId, load } = options\n\n const schema = fse.readFileSync(path.resolve(options.config.root, options.config.input.schema), 'utf-8')\n\n const api: Api = {\n get config() {\n return options.config\n },\n get schema() {\n return schema\n },\n on: fileEmitter.on.bind(fileEmitter),\n getFileName: fileEmitter.getFileName.bind(fileEmitter),\n getEmittedFile: fileEmitter.getEmittedFile.bind(fileEmitter),\n emitFile: fileEmitter.emitFile.bind(fileEmitter),\n resolveId,\n load,\n }\n\n return {\n name: 'core',\n api,\n }\n})\n","/* eslint-disable @typescript-eslint/no-non-null-assertion */\n/* eslint-disable @typescript-eslint/no-unused-vars */\n/* eslint-disable no-restricted-syntax */\n/* eslint-disable no-await-in-loop */\n/* eslint-disable no-undef */\n// inspired by: https://github.com/rollup/rollup/blob/master/src/utils/PluginDriver.ts#\n\nimport { FileEmitter } from './FileEmitter'\n\nimport { getPluginContext } from '../context'\nimport { createCorePlugin } from '../plugin'\n\nimport type { BuildContext } from '../build'\nimport type { SerializablePluginCache } from './cache'\nimport type { Plugin } from '../plugin'\nimport type { PluginLifecycleHooks, PluginLifecycle, WithPromise, PluginContext, Api } from '../types'\n\n/**\n * Get the type of the first argument in a function.\n * @example Arg0<(a: string, b: number) => void> -> string\n */\nexport type Argument0<H extends keyof PluginLifecycle> = Parameters<PluginLifecycle[H]>[0]\n\ntype Strategy = 'hookFirst' | 'hookParallel' | 'hookReduceArg0' | 'hookSeq'\n\n// This will make sure no input hook is omitted\nconst hookNames: {\n [P in PluginLifecycleHooks]: 1\n} = {\n validate: 1,\n buildStart: 1,\n resolveId: 1,\n load: 1,\n transform: 1,\n writeFile: 1,\n buildEnd: 1,\n}\nexport const hooks = Object.keys(hookNames) as [PluginLifecycleHooks]\n\nexport class PluginDriver {\n private readonly pluginContexts: ReadonlyMap<Plugin, PluginContext>\n\n public plugins: Plugin[]\n\n public readonly fileEmitter: FileEmitter\n\n private readonly logger?: BuildContext['logger']\n\n private readonly config: Api['config']\n\n private readonly sortedPlugins = new Map<PluginLifecycleHooks, Plugin[]>()\n\n constructor(config: Api['config'], pluginCache: Record<string, SerializablePluginCache> | undefined, options: { logger: BuildContext['logger'] }) {\n this.logger = options.logger\n this.config = config\n\n this.fileEmitter = new FileEmitter()\n\n this.emitFile = this.fileEmitter.emitFile.bind(this.fileEmitter)\n\n const corePlugin = createCorePlugin({ config, fileEmitter: this.fileEmitter, load: this.load, resolveId: this.resolveId })\n this.plugins = [corePlugin, ...(config.plugins || [])]\n const coreApi = corePlugin.api\n this.pluginContexts = new Map(\n this.plugins.map((plugin) => {\n const context = {\n ...coreApi,\n ...getPluginContext.call(this, plugin, pluginCache),\n }\n return [plugin, context]\n })\n )\n }\n\n get apis() {\n return this.pluginContexts\n }\n\n get api() {\n let context = {}\n this.pluginContexts.forEach((value) => {\n context = { ...context, ...value }\n })\n return context as PluginContext\n }\n\n emitFile(...params: Parameters<FileEmitter['emitFile']>) {\n return this.fileEmitter.emitFile(...params)\n }\n\n resolveId = (source: string, importer: string, meta: Record<string, any> | undefined) => {\n return this.hookFirst('resolveId', [source, importer, meta])\n }\n\n load = async (id: string) => {\n const result = await this.hookFirst('load', [id])\n return result\n }\n\n // chains, first non-null result stops and returns\n hookFirst<H extends PluginLifecycleHooks>(\n hookName: H,\n parameters: Parameters<PluginLifecycle[H]>,\n skipped?: ReadonlySet<Plugin> | null\n ): Promise<ReturnType<PluginLifecycle[H]> | null> {\n let promise: Promise<ReturnType<PluginLifecycle[H]> | null> = Promise.resolve(null)\n for (const plugin of this.getSortedPlugins(hookName)) {\n if (skipped && skipped.has(plugin)) continue\n promise = promise.then((result) => {\n if (result != null) return result\n return this.runHook('hookFirst', hookName, parameters, plugin) as any\n })\n }\n return promise\n }\n\n // parallel\n async hookParallel<H extends PluginLifecycleHooks, TOuput = void>(hookName: H, parameters?: Parameters<PluginLifecycle[H]> | undefined) {\n const parallelPromises: Promise<TOuput>[] = []\n\n for (const plugin of this.getSortedPlugins(hookName)) {\n if ((plugin[hookName] as { sequential?: boolean })?.sequential) {\n await Promise.all(parallelPromises)\n parallelPromises.length = 0\n await this.runHook('hookParallel', hookName, parameters, plugin)\n } else {\n const promise: Promise<TOuput> = this.runHook('hookParallel', hookName, parameters, plugin)\n\n parallelPromises.push(promise)\n }\n }\n return Promise.all(parallelPromises)\n }\n\n // chains, reduces returned value, handling the reduced value as the first hook argument\n hookReduceArg0<H extends PluginLifecycleHooks>(\n hookName: H,\n [argument0, ...rest]: Parameters<PluginLifecycle[H]>,\n reduce: (reduction: Argument0<H>, result: ReturnType<PluginLifecycle[H]>, plugin: Plugin) => WithPromise<Argument0<H> | null>\n ): Promise<Argument0<H>> {\n let promise = Promise.resolve(argument0)\n for (const plugin of this.getSortedPlugins(hookName)) {\n promise = promise.then((argument0) =>\n this.runHook('hookReduceArg0', hookName, [argument0, ...rest] as Parameters<PluginLifecycle[H]>, plugin).then((result) =>\n reduce.call(this.api, argument0, result, plugin)\n )\n )\n }\n return promise\n }\n\n // chains\n\n hookSeq<H extends PluginLifecycleHooks>(hookName: H, parameters?: Parameters<PluginLifecycle[H]>) {\n let promise: Promise<void> = Promise.resolve()\n for (const plugin of this.getSortedPlugins(hookName)) {\n promise = promise.then(() => this.runHook('hookSeq', hookName, parameters, plugin))\n }\n return promise.then(noReturn)\n }\n\n private getSortedPlugins(_hookName: keyof PluginLifecycle): Plugin[] {\n return [...this.plugins]\n }\n\n /**\n * Run an async plugin hook and return the result.\n * @param hookName Name of the plugin hook. Must be either in `PluginHooks` or `OutputPluginValueHooks`.\n * @param args Arguments passed to the plugin hook.\n * @param plugin The actual pluginObject to run.\n */\n // Implementation signature\n private runHook<H extends PluginLifecycleHooks, TResult = void>(\n strategy: Strategy,\n hookName: H,\n parameters: unknown[] | undefined,\n plugin: Plugin\n ): Promise<TResult> {\n // We always filter for plugins that support the hook before running it\n const hook = plugin[hookName]!\n // const context = this.pluginContexts.get(plugin) || {};\n\n return Promise.resolve().then(() => {\n if (typeof hook !== 'function') {\n return hook\n }\n\n if (this.config.logLevel === 'info' && this.logger?.spinner) {\n this.logger.spinner.text = `[${strategy}] ${hookName}: Excecuting task for plugin ${plugin.name} \\n`\n }\n\n const hookResult = (hook as any).apply(this.api, parameters)\n\n if (!hookResult?.then) {\n // short circuit for non-thenables and non-Promises\n if (this.config.logLevel === 'info' && this.logger?.spinner) {\n this.logger.spinner.succeed(`[${strategy}] ${hookName}: Excecuting task for plugin ${plugin.name} \\n`)\n }\n return hookResult\n }\n\n return Promise.resolve(hookResult).then((result) => {\n // action was fulfilled\n if (this.config.logLevel === 'info' && this.logger?.spinner) {\n this.logger.spinner.succeed(`[${strategy}] ${hookName}: Excecuting task for plugin ${plugin.name} \\n`)\n }\n return result\n })\n })\n }\n\n /**\n * Run a sync plugin hook and return the result.\n * @param hookName Name of the plugin hook. Must be in `PluginHooks`.\n * @param args Arguments passed to the plugin hook.\n * @param plugin The acutal plugin\n * @param replaceContext When passed, the plugin context can be overridden.\n */\n private runHookSync<H extends PluginLifecycleHooks>(hookName: H, parameters: Parameters<PluginLifecycle[H]>, plugin: Plugin): ReturnType<PluginLifecycle[H]> {\n const hook = plugin[hookName]!\n\n // const context = this.pluginContexts.get(plugin)!;\n\n try {\n // eslint-disable-next-line @typescript-eslint/ban-types\n return (hook as Function).apply(this.api, parameters)\n } catch (error: any) {\n return error\n }\n }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-function\nfunction noReturn() {}\n","import type { WithPromise } from './types'\nimport type { LogLevel } from './utils/logger'\nimport type { Plugin } from './plugin'\n\nexport interface ConfigEnv {\n mode: string\n}\n// TODO revert to this to have multiple options like async, object, ...\n// export type PluginOption = PluginOptions | false | null | undefined | PluginOption[] | Promise<PluginOptions | false | null | undefined | PluginOption[]>;\n\nexport interface UserConfig {\n /**\n * Project root directory. Can be an absolute path, or a path relative from\n * the location of the config file itself.\n * @default process.cwd()\n */\n root?: string\n mode?: 'single'\n /**\n * plugins means it will run context, buildStart, transform and buildEnd based on order of the plugins array\n * Example of an order(plugin x does not have a buildEnd): [buildStart of plugin x, buildStart of plugin y, transform of plugin x, transform of plugin y, buildEnd of plugin y ]\n * Default: plugins\n */\n lifeCycle?: 'plugins'\n /**\n * Default: fifo\n */\n strategy?: 'fifo' | 'lifo'\n input: {\n schema: string\n }\n output: {\n path: string\n }\n /**\n * Array of kubb plugins to use.\n */\n plugins?: Plugin[]\n\n logLevel?: LogLevel\n}\n\nexport type UserConfigFn = (env: ConfigEnv) => WithPromise<UserConfig>\nexport type UserConfigExport = WithPromise<UserConfig> | UserConfigFn\n\n/**\n * Type helper to make it easier to use kubb.config.ts\n * accepts a direct {@link UserConfig} object, or a function that returns it.\n * The function receives a {@link ConfigEnv} object that exposes two properties:\n */\nexport function defineConfig(config: UserConfigExport): UserConfigExport {\n return config\n}\n","import type { WithPromise } from '../types'\n\nexport const isPromise = <T>(result: WithPromise<T>): result is Promise<T> => {\n return typeof (result as any)?.then === 'function'\n}\n","import { isPromise } from './isPromise'\n\nimport type { WithPromise } from '../types'\n\nexport const createQueue = <TArray extends readonly any[] = readonly any[], TInput = TArray[number], TOuput = void>(\n arr: TArray | undefined,\n fun: (item: TInput) => WithPromise<TOuput>\n) => {\n const promises: Promise<TOuput>[] = []\n\n arr?.forEach((item) => {\n const result = fun(item)\n if (isPromise<TOuput>(result)) {\n promises.push(result)\n } else {\n promises.push(Promise.resolve(result))\n }\n })\n\n return Promise.all(promises)\n}\n","/* eslint-disable consistent-return */\nimport fse from 'fs-extra'\n\nimport { format } from './format'\n\ntype WriteOptions = {\n format: boolean\n}\n\nexport const write = async (data: string, path: string, options: WriteOptions = { format: false }) => {\n const formattedData = options.format ? format(data) : data\n\n try {\n await fse.stat(path)\n const oldContent = await fse.readFile(path, { encoding: 'utf-8' })\n if (oldContent?.toString() === formattedData) {\n return\n }\n } catch (_err) {\n return fse.outputFile(path, formattedData)\n }\n\n return fse.outputFile(path, formattedData)\n}\n","import { format as prettierFormat } from 'prettier'\n\nimport type { Options } from 'prettier'\n\nexport const formatOptions: Options = {\n tabWidth: 2,\n printWidth: 160,\n parser: 'typescript',\n singleQuote: true,\n semi: false,\n bracketSameLine: false,\n endOfLine: 'auto',\n}\nexport const format = (text: string) => {\n return prettierFormat(text, formatOptions)\n}\n","import path from 'path'\n\n// TODO check for a better way or resolving the relative path\nexport const getRelativePath = (from?: string | null, to?: string | null) => {\n if (!from || !to) {\n throw new Error('From and to should be filled in when retrieving the relativePath')\n }\n return path.relative(from, to).replace('../', '').replace('.ts', '').trimEnd()\n}\n","/* eslint-disable @typescript-eslint/no-empty-interface */\nimport { build } from './build'\n\nexport * from './config'\nexport * from './build'\nexport { Plugin, PluginOptions, PluginFactory, createPlugin } from './plugin'\nexport * from './utils'\nexport * from './types'\nexport * from './context'\n\nexport default build\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/build.ts","../src/utils/Emitter.ts","../src/utils/FileEmitter.ts","../src/utils/cache.ts","../src/context.ts","../src/plugin.ts","../src/utils/PluginDriver.ts","../src/config.ts","../src/utils/isPromise.ts","../src/utils/write.ts","../src/utils/format.ts","../src/utils/read.ts","../src/index.ts"],"names":["path","argument0","fse"],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-unused-vars */\n/* eslint-disable @typescript-eslint/no-empty-function */\n/* eslint-disable no-console */\n\nimport path from 'path'\n\nimport { PluginDriver } from './utils/PluginDriver'\n\nimport type { Api, PluginContext, TransformResult, ValidationResult, LogLevel } from './types'\nimport type { UserConfig, ConfigEnv } from './config'\nimport type { Plugin } from './plugin'\n\ntype BuildOutput = void\n\n// Same type as ora\ntype Spinner = {\n start: (text?: string) => Spinner\n succeed: (text: string) => Spinner\n stopAndPersist: (options: { text: string }) => Spinner\n render: () => Spinner\n text: string\n info: (text: string) => Spinner\n}\n\nexport type BuildContext = {\n logger?: {\n log: (message: string, logLevel: LogLevel) => void\n spinner?: Spinner\n }\n}\n\nasync function transformReducer(this: PluginContext, previousCode: string, result: TransformResult, _plugin: Plugin) {\n if (result === null) {\n return null\n }\n return result\n}\n\ntype BuildImplementationOptions = {\n config: Api['config']\n env: ConfigEnv\n}\n\nasync function buildImplementation(this: BuildContext, options: BuildImplementationOptions, done: (output: BuildOutput) => void) {\n const { config } = options\n if (config.lifeCycle && config.lifeCycle !== 'plugins') {\n throw new Error('Only lifeCycle plugins possible')\n }\n\n if (config.strategy && config.strategy !== 'lifo') {\n throw new Error('Only strategy fifo possible')\n }\n\n const pluginCache = Object.create(null)\n const pluginDriver = new PluginDriver(config, pluginCache, { logger: this.logger })\n\n const validations = await pluginDriver.hookParallel<'validate', ValidationResult>('validate', [pluginDriver.plugins])\n\n const validationsWithMessage = validations.filter(Boolean)\n\n if (validationsWithMessage.some((validation) => typeof validation !== 'boolean')) {\n validationsWithMessage.forEach((validation) => {\n if (validation && typeof validation !== 'boolean' && validation?.message) {\n this.logger?.log(validation.message, 'warn')\n }\n })\n\n return\n }\n\n pluginDriver.fileEmitter.on('new', async (emittedFile) => {\n if (!emittedFile?.source) {\n return\n }\n\n const resolvedId = await pluginDriver.hookFirst('resolveId', [emittedFile.source, path.resolve(emittedFile.source), emittedFile.meta])\n const id = resolvedId || emittedFile.source\n let { code } = emittedFile\n\n const loadedResult = await pluginDriver.hookFirst('load', [id])\n if (loadedResult) {\n code = loadedResult\n }\n\n if (code) {\n const result = await pluginDriver.hookReduceArg0('transform', [code, id], transformReducer)\n\n await pluginDriver.hookParallel('writeFile', [result, id])\n pluginDriver.fileEmitter.delete(emittedFile.id)\n }\n })\n\n await pluginDriver.hookParallel('buildStart')\n\n pluginDriver.emitFile({\n id: path.resolve(pluginDriver.api.config.root, pluginDriver.api.config.input.schema),\n source: pluginDriver.api.config.input.schema,\n name: undefined,\n code: pluginDriver.api.schema,\n })\n\n pluginDriver.fileEmitter.on('end', async () => {\n await pluginDriver.hookParallel('buildEnd')\n done()\n })\n}\n\nexport function build(this: BuildContext, userConfig: UserConfig, env: ConfigEnv): Promise<BuildOutput> {\n const config: UserConfig = {\n ...userConfig,\n root: userConfig.root || process.cwd(),\n }\n\n return new Promise((resolve) => {\n buildImplementation.call(\n this,\n {\n config,\n env,\n },\n resolve\n )\n })\n}\n","export type Listener<T> = (value?: T) => void\n\nexport class Emitter<TValue = unknown, TTopics = unknown> {\n private readonly listeners: Set<{\n topic?: TTopics\n cb: Listener<TValue>\n }> = new Set()\n\n private readonly topics?: TTopics[]\n\n constructor(topics?: TTopics[]) {\n this.topics = topics\n }\n\n emit(...params: [topic: TTopics, value?: TValue] | [value?: TValue]) {\n const isTopic = (value: any): value is TTopics => !!this.topics?.includes(value)\n\n if (isTopic(params[0])) {\n this.listeners.forEach((listener) => {\n if (listener.topic === params[0]) {\n listener.cb(params[1])\n }\n })\n return\n }\n this.listeners.forEach((listener) => listener.cb(params[0] as TValue))\n }\n\n subscribe: (cb: Listener<TValue>) => () => void = (cb) => {\n const listener = {\n topic: undefined,\n cb,\n }\n this.listeners.add(listener)\n // Unsubscribe\n return () => this.listeners.delete(listener)\n }\n\n on(topic: TTopics, cb: Listener<TValue>) {\n const listener = {\n topic,\n cb,\n }\n this.listeners.add(listener)\n return () => this.listeners.delete(listener)\n }\n\n destroy: () => void = () => this.listeners.clear()\n}\n","import { Emitter } from './Emitter'\n\nexport interface EmittedFile {\n id: string\n // this can be used as a dynamic path, also resolveId will use this as source(first parameter)\n source: string | undefined\n name: string | undefined\n code: string | undefined\n meta?: Record<string, any>\n}\n\nexport type EmitFile = (emittedFile: EmittedFile) => void\n\ntype Topics = 'new' | 'delete' | 'end'\nexport class FileEmitter {\n private readonly emitter: Emitter<EmittedFile, Topics>\n\n private readonly filesByReferenceId: Map<string, EmittedFile> = new Map()\n\n constructor(emitter: Emitter<EmittedFile, Topics> = new Emitter<EmittedFile, Topics>(['delete', 'end', 'new'])) {\n this.emitter = emitter\n }\n\n emitFile(emitedFile: EmittedFile) {\n // save locally in this class\n this.assignReferenceId(emitedFile, emitedFile.id)\n this.emitter.emit('new', emitedFile)\n return new Promise<EmittedFile>((resolve) => {\n const subscribe = this.emitter.on('delete', (deletedFile) => {\n if (deletedFile?.id === emitedFile.id) {\n resolve(deletedFile)\n return subscribe()\n }\n return undefined\n })\n })\n }\n\n delete(fileReferenceId: string) {\n const deletedFile = this.filesByReferenceId.get(fileReferenceId)\n this.filesByReferenceId.delete(fileReferenceId)\n if (this.filesByReferenceId.size === 0) {\n this.emitter.emit('end')\n }\n return this.emitter.emit('delete', deletedFile)\n }\n\n subscribe(...params: Parameters<typeof this.emitter['subscribe']>) {\n this.emitter.subscribe(...params)\n }\n\n on(...params: Parameters<typeof this.emitter['on']>) {\n this.emitter.on(...params)\n }\n\n private assignReferenceId(emittedFile: EmittedFile, fileReferenceId: string | undefined) {\n if (fileReferenceId) {\n this.filesByReferenceId.set(fileReferenceId, emittedFile)\n }\n }\n\n getEmittedFile = (fileReferenceId?: string | null): EmittedFile | undefined => {\n if (!fileReferenceId) {\n return undefined\n }\n return this.filesByReferenceId.get(fileReferenceId)\n }\n}\n","/* eslint-disable no-param-reassign */\n/* eslint-disable consistent-return */\nexport interface SerializablePluginCache {\n [key: string]: [number, any]\n}\n\nexport interface Cache<TCache = any> {\n delete(id: string): boolean\n get<T = TCache>(id: string): T\n has(id: string): boolean\n set<T = TCache>(id: string, value: T): void\n}\n\nexport function createPluginCache(cache: SerializablePluginCache): Cache {\n return {\n delete(id: string) {\n return delete cache[id]\n },\n get(id: string) {\n const item = cache[id]\n if (!item) return\n item[0] = 0\n return item[1]\n },\n has(id: string) {\n const item = cache[id]\n if (!item) return false\n item[0] = 0\n return true\n },\n set(id: string, value: any) {\n cache[id] = [0, value]\n },\n }\n}\n","/* eslint-disable no-param-reassign */\nimport { createPluginCache } from './utils/cache'\n\nimport type { PluginDriver } from './utils/PluginDriver'\nimport type { SerializablePluginCache } from './utils/cache'\nimport type { Plugin } from './plugin'\n\nexport function getPluginContext(this: PluginDriver, plugin: Plugin, pluginCache: Record<string, SerializablePluginCache> | void) {\n const cacheKey = plugin.cacheKey || (plugin.name as string)\n\n const cacheInstance = createPluginCache(pluginCache[cacheKey] || (pluginCache[cacheKey] = Object.create(null)))\n\n return {\n cache: cacheInstance,\n }\n}\n","/* eslint-disable no-console */\n\nimport path from 'path'\n\nimport fse from 'fs-extra'\n\nimport type { FileEmitter } from './utils'\nimport type { PluginLifecycle, PluginName, Api } from './types'\n\n// use of type objects\nexport type PluginOptions<UserOptions = unknown, Nested extends boolean = false, Api = any> = {\n userOptions: UserOptions\n nested: Nested\n api: Api\n}\n\nexport type Plugin<TOptions extends PluginOptions = PluginOptions> = {\n name: PluginName | Omit<string, PluginName>\n cacheKey?: string\n api?: TOptions['api']\n} & Partial<PluginLifecycle>\n\nexport type PluginFactory<TOptions extends PluginOptions = PluginOptions> = (\n options: TOptions['userOptions']\n) => TOptions['nested'] extends true ? Array<Plugin<TOptions>> : Plugin<TOptions>\n\nexport function createPlugin<TOptions extends PluginOptions = PluginOptions>(factory: PluginFactory<TOptions>) {\n return (userOptions: TOptions['userOptions']) => {\n const plugin = factory(userOptions)\n if (Array.isArray(plugin)) {\n throw new Error('Not implemented')\n }\n\n // default transform\n if (!plugin.transform) {\n plugin.transform = function transform(code) {\n return code\n }\n }\n\n return plugin\n }\n}\n\ntype Options = {\n // root will be filled in with a default value in build(process.cwd)\n config: Api['config']\n fileEmitter: FileEmitter\n resolveId: Api['resolveId']\n load: Api['load']\n}\n\n// not exported\ntype CorePluginOptions = PluginOptions<Options, false, Api>\n\nexport const name = 'core' as const\n\nexport const definePlugin = createPlugin<CorePluginOptions>((options) => {\n const { fileEmitter, resolveId, load } = options\n\n const schema = fse.readFileSync(path.resolve(options.config.root, options.config.input.schema), 'utf-8')\n\n const api: Api = {\n get config() {\n return options.config\n },\n get schema() {\n return schema\n },\n on: fileEmitter.on.bind(fileEmitter),\n getEmittedFile: fileEmitter.getEmittedFile.bind(fileEmitter),\n emitFile: fileEmitter.emitFile.bind(fileEmitter),\n resolveId,\n load,\n }\n\n return {\n name,\n api,\n }\n})\n","/* eslint-disable @typescript-eslint/no-non-null-assertion */\n/* eslint-disable @typescript-eslint/no-unused-vars */\n/* eslint-disable no-restricted-syntax */\n/* eslint-disable no-await-in-loop */\n/* eslint-disable no-undef */\n// inspired by: https://github.com/rollup/rollup/blob/master/src/utils/PluginDriver.ts#\n\nimport { FileEmitter } from './FileEmitter'\n\nimport { getPluginContext } from '../context'\nimport { definePlugin } from '../plugin'\n\nimport type { WithPromise } from './isPromise'\nimport type { BuildContext } from '../build'\nimport type { SerializablePluginCache } from './cache'\nimport type { Plugin } from '../plugin'\nimport type { PluginLifecycleHooks, PluginLifecycle, PluginContext, Api } from '../types'\n\n/**\n * Get the type of the first argument in a function.\n * @example Arg0<(a: string, b: number) => void> -> string\n */\nexport type Argument0<H extends keyof PluginLifecycle> = Parameters<PluginLifecycle[H]>[0]\n\ntype Strategy = 'hookFirst' | 'hookParallel' | 'hookReduceArg0' | 'hookSeq'\n\n// This will make sure no input hook is omitted\nconst hookNames: {\n [P in PluginLifecycleHooks]: 1\n} = {\n validate: 1,\n buildStart: 1,\n resolveId: 1,\n load: 1,\n transform: 1,\n writeFile: 1,\n buildEnd: 1,\n}\nexport const hooks = Object.keys(hookNames) as [PluginLifecycleHooks]\n\nexport class PluginDriver {\n private readonly pluginContexts: ReadonlyMap<Plugin, PluginContext>\n\n public plugins: Plugin[]\n\n public readonly fileEmitter: FileEmitter\n\n private readonly logger?: BuildContext['logger']\n\n private readonly config: Api['config']\n\n private readonly sortedPlugins = new Map<PluginLifecycleHooks, Plugin[]>()\n\n constructor(config: Api['config'], pluginCache: Record<string, SerializablePluginCache> | undefined, options: { logger: BuildContext['logger'] }) {\n this.logger = options.logger\n this.config = config\n\n this.fileEmitter = new FileEmitter()\n\n this.emitFile = this.fileEmitter.emitFile.bind(this.fileEmitter)\n\n const corePlugin = definePlugin({ config, fileEmitter: this.fileEmitter, load: this.load, resolveId: this.resolveId })\n this.plugins = [corePlugin, ...(config.plugins || [])]\n const coreApi = corePlugin.api\n this.pluginContexts = new Map(\n this.plugins.map((plugin) => {\n const context = {\n ...coreApi,\n ...getPluginContext.call(this, plugin, pluginCache),\n }\n return [plugin, context]\n })\n )\n }\n\n get api() {\n let context = {}\n this.pluginContexts.forEach((value) => {\n context = { ...context, ...value }\n })\n return context as PluginContext\n }\n\n emitFile(...params: Parameters<FileEmitter['emitFile']>) {\n return this.fileEmitter.emitFile(...params)\n }\n\n resolveId = (source: string, importer: string, meta: Record<string, any> | undefined) => {\n return this.hookFirst('resolveId', [source, importer, meta])\n }\n\n load = async (id: string) => {\n const result = await this.hookFirst('load', [id])\n return result\n }\n\n // chains, first non-null result stops and returns\n hookFirst<H extends PluginLifecycleHooks>(\n hookName: H,\n parameters: Parameters<PluginLifecycle[H]>,\n skipped?: ReadonlySet<Plugin> | null\n ): Promise<ReturnType<PluginLifecycle[H]> | null> {\n let promise: Promise<ReturnType<PluginLifecycle[H]> | null> = Promise.resolve(null)\n for (const plugin of this.getSortedPlugins(hookName)) {\n if (skipped && skipped.has(plugin)) continue\n promise = promise.then((result) => {\n if (result != null) return result\n return this.runHook('hookFirst', hookName, parameters, plugin) as any\n })\n }\n return promise\n }\n\n // parallel\n async hookParallel<H extends PluginLifecycleHooks, TOuput = void>(hookName: H, parameters?: Parameters<PluginLifecycle[H]> | undefined) {\n const parallelPromises: Promise<TOuput>[] = []\n\n for (const plugin of this.getSortedPlugins(hookName)) {\n if ((plugin[hookName] as { sequential?: boolean })?.sequential) {\n await Promise.all(parallelPromises)\n parallelPromises.length = 0\n await this.runHook('hookParallel', hookName, parameters, plugin)\n } else {\n const promise: Promise<TOuput> = this.runHook('hookParallel', hookName, parameters, plugin)\n\n parallelPromises.push(promise)\n }\n }\n return Promise.all(parallelPromises)\n }\n\n // chains, reduces returned value, handling the reduced value as the first hook argument\n hookReduceArg0<H extends PluginLifecycleHooks>(\n hookName: H,\n [argument0, ...rest]: Parameters<PluginLifecycle[H]>,\n reduce: (reduction: Argument0<H>, result: ReturnType<PluginLifecycle[H]>, plugin: Plugin) => WithPromise<Argument0<H> | null>\n ): Promise<Argument0<H>> {\n let promise = Promise.resolve(argument0)\n for (const plugin of this.getSortedPlugins(hookName)) {\n promise = promise.then((argument0) =>\n this.runHook('hookReduceArg0', hookName, [argument0, ...rest] as Parameters<PluginLifecycle[H]>, plugin).then((result) =>\n reduce.call(this.api, argument0, result, plugin)\n )\n )\n }\n return promise\n }\n\n // chains\n\n hookSeq<H extends PluginLifecycleHooks>(hookName: H, parameters?: Parameters<PluginLifecycle[H]>) {\n let promise: Promise<void> = Promise.resolve()\n for (const plugin of this.getSortedPlugins(hookName)) {\n promise = promise.then(() => this.runHook('hookSeq', hookName, parameters, plugin))\n }\n return promise.then(noReturn)\n }\n\n private getSortedPlugins(_hookName: keyof PluginLifecycle): Plugin[] {\n return [...this.plugins]\n }\n\n /**\n * Run an async plugin hook and return the result.\n * @param hookName Name of the plugin hook. Must be either in `PluginHooks` or `OutputPluginValueHooks`.\n * @param args Arguments passed to the plugin hook.\n * @param plugin The actual pluginObject to run.\n */\n // Implementation signature\n private runHook<H extends PluginLifecycleHooks, TResult = void>(\n strategy: Strategy,\n hookName: H,\n parameters: unknown[] | undefined,\n plugin: Plugin\n ): Promise<TResult> {\n // We always filter for plugins that support the hook before running it\n const hook = plugin[hookName]!\n // const context = this.pluginContexts.get(plugin) || {};\n\n return Promise.resolve().then(() => {\n if (typeof hook !== 'function') {\n return hook\n }\n\n if (this.config.logLevel === 'info' && this.logger?.spinner) {\n this.logger.spinner.text = `[${strategy}] ${hookName}: Excecuting task for plugin ${plugin.name} \\n`\n }\n\n const hookResult = (hook as any).apply(this.api, parameters)\n\n if (!hookResult?.then) {\n // short circuit for non-thenables and non-Promises\n if (this.config.logLevel === 'info' && this.logger?.spinner) {\n this.logger.spinner.succeed(`[${strategy}] ${hookName}: Excecuting task for plugin ${plugin.name} \\n`)\n }\n return hookResult\n }\n\n return Promise.resolve(hookResult).then((result) => {\n // action was fulfilled\n if (this.config.logLevel === 'info' && this.logger?.spinner) {\n this.logger.spinner.succeed(`[${strategy}] ${hookName}: Excecuting task for plugin ${plugin.name} \\n`)\n }\n return result\n })\n })\n }\n\n /**\n * Run a sync plugin hook and return the result.\n * @param hookName Name of the plugin hook. Must be in `PluginHooks`.\n * @param args Arguments passed to the plugin hook.\n * @param plugin The acutal plugin\n * @param replaceContext When passed, the plugin context can be overridden.\n */\n private runHookSync<H extends PluginLifecycleHooks>(hookName: H, parameters: Parameters<PluginLifecycle[H]>, plugin: Plugin): ReturnType<PluginLifecycle[H]> {\n const hook = plugin[hookName]!\n\n // const context = this.pluginContexts.get(plugin)!;\n\n try {\n // eslint-disable-next-line @typescript-eslint/ban-types\n return (hook as Function).apply(this.api, parameters)\n } catch (error: any) {\n return error\n }\n }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-function\nfunction noReturn() {}\n","import type { WithPromise } from './utils/isPromise'\nimport type { LogLevel } from './types'\nimport type { Plugin } from './plugin'\n\nexport interface ConfigEnv {\n mode: string\n}\n// TODO revert to this to have multiple options like async, object, ...\n// export type PluginOption = PluginOptions | false | null | undefined | PluginOption[] | Promise<PluginOptions | false | null | undefined | PluginOption[]>;\n\nexport interface UserConfig {\n /**\n * Project root directory. Can be an absolute path, or a path relative from\n * the location of the config file itself.\n * @default process.cwd()\n */\n root?: string\n mode?: 'single'\n /**\n * plugins means it will run context, buildStart, transform and buildEnd based on order of the plugins array\n * Example of an order(plugin x does not have a buildEnd): [buildStart of plugin x, buildStart of plugin y, transform of plugin x, transform of plugin y, buildEnd of plugin y ]\n * Default: plugins\n */\n lifeCycle?: 'plugins'\n /**\n * Default: fifo\n */\n strategy?: 'fifo' | 'lifo'\n input: {\n schema: string\n }\n output: {\n path: string\n }\n /**\n * Array of kubb plugins to use.\n */\n plugins?: Plugin[]\n\n logLevel?: LogLevel\n}\n\nexport type UserConfigFn = (env: ConfigEnv) => WithPromise<UserConfig>\nexport type UserConfigExport = WithPromise<UserConfig> | UserConfigFn\n\n/**\n * Type helper to make it easier to use kubb.config.ts\n * accepts a direct {@link UserConfig} object, or a function that returns it.\n * The function receives a {@link ConfigEnv} object that exposes two properties:\n */\nexport function defineConfig(config: UserConfigExport): UserConfigExport {\n return config\n}\n","export type WithPromise<T> = Promise<T> | T\n\nexport const isPromise = <T>(result: WithPromise<T>): result is Promise<T> => {\n return typeof (result as any)?.then === 'function'\n}\n","/* eslint-disable consistent-return */\nimport fse from 'fs-extra'\n\nimport { format } from './format'\n\ntype WriteOptions = {\n format: boolean\n}\n\nexport const write = async (data: string, path: string, options: WriteOptions = { format: false }) => {\n const formattedData = options.format ? format(data) : data\n\n try {\n await fse.stat(path)\n const oldContent = await fse.readFile(path, { encoding: 'utf-8' })\n if (oldContent?.toString() === formattedData) {\n return\n }\n } catch (_err) {\n return fse.outputFile(path, formattedData)\n }\n\n return fse.outputFile(path, formattedData)\n}\n","import { format as prettierFormat } from 'prettier'\n\nimport type { Options } from 'prettier'\n\nconst formatOptions: Options = {\n tabWidth: 2,\n printWidth: 160,\n parser: 'typescript',\n singleQuote: true,\n semi: false,\n bracketSameLine: false,\n endOfLine: 'auto',\n}\nexport const format = (text: string) => {\n return prettierFormat(text, formatOptions)\n}\n","import path from 'path'\n\n// TODO check for a better way or resolving the relative path\nexport const getRelativePath = (from?: string | null, to?: string | null) => {\n if (!from || !to) {\n throw new Error('From and to should be filled in when retrieving the relativePath')\n }\n const newPath = path.relative(from, to).replace('../', '').replace('.ts', '').trimEnd()\n\n if (newPath.startsWith('./') || newPath.startsWith('../')) {\n return newPath.replace\n }\n return `./${newPath}`\n}\n","/* eslint-disable @typescript-eslint/no-empty-interface */\nimport { build } from './build'\n\nexport * from './config'\nexport * from './build'\nexport { Plugin, PluginOptions, PluginFactory, createPlugin } from './plugin'\nexport * from './utils'\nexport * from './types'\nexport * from './context'\n\nexport default build\n"]}
|