@qualcomm-ui/mdx-vite 2.14.2 → 2.15.0
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/ai-knowledge/env.d.ts +27 -0
- package/dist/ai-knowledge/env.d.ts.map +1 -0
- package/dist/{open-web-ui-knowledge/generate-knowledge.d.ts → ai-knowledge/generator/command.d.ts} +3 -3
- package/dist/ai-knowledge/generator/command.d.ts.map +1 -0
- package/dist/ai-knowledge/generator/config.d.ts +4 -0
- package/dist/ai-knowledge/generator/config.d.ts.map +1 -0
- package/dist/ai-knowledge/generator/demo-plugin.d.ts +8 -0
- package/dist/ai-knowledge/generator/demo-plugin.d.ts.map +1 -0
- package/dist/ai-knowledge/generator/doc-props-plugin.d.ts +16 -0
- package/dist/ai-knowledge/generator/doc-props-plugin.d.ts.map +1 -0
- package/dist/ai-knowledge/generator/generator.types.d.ts +51 -0
- package/dist/ai-knowledge/generator/generator.types.d.ts.map +1 -0
- package/dist/ai-knowledge/generator/index.d.ts +2 -0
- package/dist/ai-knowledge/generator/index.d.ts.map +1 -0
- package/dist/ai-knowledge/generator/knowledge-generator.d.ts +35 -0
- package/dist/ai-knowledge/generator/knowledge-generator.d.ts.map +1 -0
- package/dist/ai-knowledge/generator/npm-install-tabs-plugin.d.ts +3 -0
- package/dist/ai-knowledge/generator/npm-install-tabs-plugin.d.ts.map +1 -0
- package/dist/ai-knowledge/generator/qds-theme-plugin.d.ts +7 -0
- package/dist/ai-knowledge/generator/qds-theme-plugin.d.ts.map +1 -0
- package/dist/ai-knowledge/generator/section-extractor.d.ts +47 -0
- package/dist/ai-knowledge/generator/section-extractor.d.ts.map +1 -0
- package/dist/ai-knowledge/generator/section.types.d.ts +83 -0
- package/dist/ai-knowledge/generator/section.types.d.ts.map +1 -0
- package/dist/ai-knowledge/generator/utils.d.ts +11 -0
- package/dist/ai-knowledge/generator/utils.d.ts.map +1 -0
- package/dist/ai-knowledge/open-web-ui/api.d.ts.map +1 -0
- package/dist/ai-knowledge/open-web-ui/common.d.ts +67 -0
- package/dist/ai-knowledge/open-web-ui/common.d.ts.map +1 -0
- package/dist/ai-knowledge/open-web-ui/download-knowledge.d.ts.map +1 -0
- package/dist/{open-web-ui-knowledge → ai-knowledge/open-web-ui}/knowledge-cleaner.d.ts +1 -1
- package/dist/ai-knowledge/open-web-ui/knowledge-cleaner.d.ts.map +1 -0
- package/dist/ai-knowledge/open-web-ui/upload-knowledge.d.ts.map +1 -0
- package/dist/ai-knowledge/types.d.ts +57 -0
- package/dist/ai-knowledge/types.d.ts.map +1 -0
- package/dist/cli.js +1879 -1459
- package/dist/cli.js.map +4 -4
- package/dist/docs-plugin/docs-plugin.d.ts.map +1 -1
- package/dist/docs-plugin/internal/config-schema.d.ts +30 -2
- package/dist/docs-plugin/internal/config-schema.d.ts.map +1 -1
- package/dist/docs-plugin/internal/services/markdown/remark-remove-jsx.d.ts.map +1 -1
- package/dist/docs-plugin/mdx-plugins.d.ts.map +1 -1
- package/dist/docs-plugin/remark/remark-extract-meta.d.ts +18 -0
- package/dist/docs-plugin/remark/remark-extract-meta.d.ts.map +1 -0
- package/dist/docs-plugin/types.d.ts +51 -6
- package/dist/docs-plugin/types.d.ts.map +1 -1
- package/dist/index.js +1126 -709
- package/dist/index.js.map +4 -4
- package/dist/tsbuildinfo +1 -1
- package/package.json +1 -1
- package/dist/open-web-ui-knowledge/api.d.ts.map +0 -1
- package/dist/open-web-ui-knowledge/common.d.ts +0 -33
- package/dist/open-web-ui-knowledge/common.d.ts.map +0 -1
- package/dist/open-web-ui-knowledge/download-knowledge.d.ts.map +0 -1
- package/dist/open-web-ui-knowledge/generate-knowledge.d.ts.map +0 -1
- package/dist/open-web-ui-knowledge/knowledge-cleaner.d.ts.map +0 -1
- package/dist/open-web-ui-knowledge/load-config-from-env.d.ts +0 -32
- package/dist/open-web-ui-knowledge/load-config-from-env.d.ts.map +0 -1
- package/dist/open-web-ui-knowledge/types.d.ts +0 -74
- package/dist/open-web-ui-knowledge/types.d.ts.map +0 -1
- package/dist/open-web-ui-knowledge/upload-knowledge.d.ts.map +0 -1
- /package/dist/{open-web-ui-knowledge → ai-knowledge/open-web-ui}/api.d.ts +0 -0
- /package/dist/{open-web-ui-knowledge → ai-knowledge/open-web-ui}/download-knowledge.d.ts +0 -0
- /package/dist/{open-web-ui-knowledge → ai-knowledge/open-web-ui}/upload-knowledge.d.ts +0 -0
package/dist/cli.js
CHANGED
|
@@ -1815,14 +1815,14 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1815
1815
|
* @return {Command} `this` command for chaining
|
|
1816
1816
|
* @private
|
|
1817
1817
|
*/
|
|
1818
|
-
_optionEx(
|
|
1818
|
+
_optionEx(config3, flags, description, fn, defaultValue) {
|
|
1819
1819
|
if (typeof flags === "object" && flags instanceof Option2) {
|
|
1820
1820
|
throw new Error(
|
|
1821
1821
|
"To add an Option object use addOption() instead of option() or requiredOption()"
|
|
1822
1822
|
);
|
|
1823
1823
|
}
|
|
1824
1824
|
const option = this.createOption(flags, description);
|
|
1825
|
-
option.makeOptionMandatory(!!
|
|
1825
|
+
option.makeOptionMandatory(!!config3.mandatory);
|
|
1826
1826
|
if (typeof fn === "function") {
|
|
1827
1827
|
option.default(defaultValue).argParser(fn);
|
|
1828
1828
|
} else if (fn instanceof RegExp) {
|
|
@@ -2797,9 +2797,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2797
2797
|
this._outputConfiguration.writeErr("\n");
|
|
2798
2798
|
this.outputHelp({ error: true });
|
|
2799
2799
|
}
|
|
2800
|
-
const
|
|
2801
|
-
const exitCode =
|
|
2802
|
-
const code =
|
|
2800
|
+
const config3 = errorOptions || {};
|
|
2801
|
+
const exitCode = config3.exitCode || 1;
|
|
2802
|
+
const code = config3.code || "commander.error";
|
|
2803
2803
|
this._exit(exitCode, code, message);
|
|
2804
2804
|
}
|
|
2805
2805
|
/**
|
|
@@ -3501,11 +3501,10 @@ var {
|
|
|
3501
3501
|
Help
|
|
3502
3502
|
} = import_index.default;
|
|
3503
3503
|
|
|
3504
|
-
// src/
|
|
3505
|
-
import {
|
|
3506
|
-
import {
|
|
3507
|
-
import { resolve } from "node:path";
|
|
3508
|
-
import { cwd } from "node:process";
|
|
3504
|
+
// src/ai-knowledge/env.ts
|
|
3505
|
+
import { config } from "dotenv";
|
|
3506
|
+
import { existsSync } from "node:fs";
|
|
3507
|
+
import { join as join2, resolve } from "node:path";
|
|
3509
3508
|
|
|
3510
3509
|
// src/docs-plugin/internal/config-loader.ts
|
|
3511
3510
|
import { cosmiconfigSync } from "cosmiconfig";
|
|
@@ -3555,15 +3554,27 @@ var knowledgeExtraFileSchema = implement().with({
|
|
|
3555
3554
|
processAsMdx: z2.boolean().optional(),
|
|
3556
3555
|
title: z2.string().optional()
|
|
3557
3556
|
});
|
|
3557
|
+
var frontmatterConfigSchema = z2.object({
|
|
3558
|
+
exclude: z2.array(z2.string()).optional(),
|
|
3559
|
+
extraFields: z2.record(z2.string(), z2.union([z2.string(), z2.array(z2.string())])).optional(),
|
|
3560
|
+
include: z2.array(z2.string()).optional()
|
|
3561
|
+
}).optional();
|
|
3562
|
+
var sectionsExportsSchema = implement().with({
|
|
3563
|
+
depths: z2.array(z2.number()).optional(),
|
|
3564
|
+
minContentLength: z2.number().optional(),
|
|
3565
|
+
outputPath: z2.string().optional()
|
|
3566
|
+
});
|
|
3558
3567
|
var knowledgeExportsSchema = implement().with({
|
|
3559
3568
|
enabled: z2.boolean().optional(),
|
|
3560
3569
|
exclude: z2.array(z2.string()).optional(),
|
|
3561
3570
|
extraFiles: z2.array(knowledgeExtraFileSchema).optional(),
|
|
3571
|
+
frontmatter: frontmatterConfigSchema,
|
|
3562
3572
|
generateBulkZip: z2.boolean().optional(),
|
|
3563
3573
|
generateManifest: z2.boolean().optional(),
|
|
3564
3574
|
manifestPath: z2.string().optional(),
|
|
3565
3575
|
metadata: z2.record(z2.string(), z2.string()).optional(),
|
|
3566
3576
|
pageTitlePrefix: z2.string().optional(),
|
|
3577
|
+
sections: sectionsExportsSchema.optional(),
|
|
3567
3578
|
staticPath: z2.string().optional()
|
|
3568
3579
|
});
|
|
3569
3580
|
var knowledgeIntegrationSchema = implement().with(
|
|
@@ -3573,7 +3584,7 @@ var knowledgeIntegrationSchema = implement().with(
|
|
|
3573
3584
|
exclude: z2.array(z2.string()).optional(),
|
|
3574
3585
|
exports: knowledgeExportsSchema.optional(),
|
|
3575
3586
|
extraFiles: z2.array(knowledgeExtraFileSchema).optional(),
|
|
3576
|
-
|
|
3587
|
+
frontmatter: frontmatterConfigSchema,
|
|
3577
3588
|
metadata: z2.record(z2.string(), z2.string()).optional(),
|
|
3578
3589
|
name: z2.string().optional(),
|
|
3579
3590
|
outputMode: z2.union([z2.literal("per-page"), z2.literal("aggregated")]).optional(),
|
|
@@ -3588,7 +3599,7 @@ var knowledgeEnvironmentSchema = implement().with({
|
|
|
3588
3599
|
exclude: z2.array(z2.string()).optional(),
|
|
3589
3600
|
exports: knowledgeExportsSchema.optional(),
|
|
3590
3601
|
extraFiles: z2.array(knowledgeExtraFileSchema).optional(),
|
|
3591
|
-
|
|
3602
|
+
frontmatter: frontmatterConfigSchema,
|
|
3592
3603
|
id: z2.string(),
|
|
3593
3604
|
metadata: z2.record(z2.string(), z2.string()).optional(),
|
|
3594
3605
|
name: z2.string().optional(),
|
|
@@ -3682,8 +3693,8 @@ var ConfigLoader = class {
|
|
|
3682
3693
|
}
|
|
3683
3694
|
return result;
|
|
3684
3695
|
}
|
|
3685
|
-
resolveConfigFromCosmiconfig(
|
|
3686
|
-
const parsed = configSchema.safeParse(
|
|
3696
|
+
resolveConfigFromCosmiconfig(config3) {
|
|
3697
|
+
const parsed = configSchema.safeParse(config3.config);
|
|
3687
3698
|
if (!parsed.success) {
|
|
3688
3699
|
console.dir(parsed.error.issues, { depth: 10 });
|
|
3689
3700
|
throw new Error("Failed to parse config file.");
|
|
@@ -3692,13 +3703,13 @@ var ConfigLoader = class {
|
|
|
3692
3703
|
return {
|
|
3693
3704
|
...conf,
|
|
3694
3705
|
appDirectory: conf.appDirectory || "app",
|
|
3695
|
-
filePath:
|
|
3706
|
+
filePath: config3.filepath,
|
|
3696
3707
|
pageDirectory: conf.pageDirectory ? removeTrailingSlash(conf.pageDirectory) : "routes"
|
|
3697
3708
|
};
|
|
3698
3709
|
}
|
|
3699
3710
|
loadConfig() {
|
|
3700
|
-
const
|
|
3701
|
-
return this.resolveConfigFromCosmiconfig(
|
|
3711
|
+
const config3 = this.getCosmiconfig();
|
|
3712
|
+
return this.resolveConfigFromCosmiconfig(config3);
|
|
3702
3713
|
}
|
|
3703
3714
|
};
|
|
3704
3715
|
|
|
@@ -4438,6 +4449,7 @@ var remarkRemoveJsx = () => {
|
|
|
4438
4449
|
return (tree, _file, done) => {
|
|
4439
4450
|
remove2(tree, "mdxjsEsm");
|
|
4440
4451
|
remove2(tree, "mdxJsxFlowElement");
|
|
4452
|
+
remove2(tree, "mdxJsxTextElement");
|
|
4441
4453
|
done();
|
|
4442
4454
|
};
|
|
4443
4455
|
};
|
|
@@ -5027,11 +5039,11 @@ function transformRouteMetaArray(meta, routeMetaNav) {
|
|
|
5027
5039
|
|
|
5028
5040
|
// src/docs-plugin/internal/search-indexer.ts
|
|
5029
5041
|
var SearchIndexer = class {
|
|
5030
|
-
constructor(
|
|
5031
|
-
this.config =
|
|
5042
|
+
constructor(config3, logWarnings = true, addons = {}) {
|
|
5043
|
+
this.config = config3;
|
|
5032
5044
|
this.logWarnings = logWarnings;
|
|
5033
5045
|
this.allowedHeadings = new Set(
|
|
5034
|
-
Array.from(
|
|
5046
|
+
Array.from(config3?.headings || ["h2", "h3", "h4"])
|
|
5035
5047
|
);
|
|
5036
5048
|
this.metaJson = transformRouteMetaArray(
|
|
5037
5049
|
this.config.navConfig ?? [],
|
|
@@ -5264,741 +5276,1032 @@ var SearchIndexer = class {
|
|
|
5264
5276
|
}
|
|
5265
5277
|
};
|
|
5266
5278
|
|
|
5267
|
-
// src/
|
|
5268
|
-
function
|
|
5269
|
-
program.
|
|
5270
|
-
|
|
5271
|
-
|
|
5272
|
-
|
|
5273
|
-
|
|
5274
|
-
|
|
5275
|
-
"-r, --routes-dir <routesDir>",
|
|
5276
|
-
"Path to the routes directory",
|
|
5277
|
-
"src/routes"
|
|
5278
|
-
).option(
|
|
5279
|
-
"-o, --output <output>",
|
|
5280
|
-
"Output path for the site data json",
|
|
5281
|
-
"site-data.json"
|
|
5282
|
-
).action(async (options) => {
|
|
5283
|
-
try {
|
|
5284
|
-
const configLoader = new ConfigLoader({ configFile: options.configFile });
|
|
5285
|
-
const resolvedConfig = configLoader.loadConfig();
|
|
5286
|
-
const routesDir = fixPath(
|
|
5287
|
-
resolve(resolvedConfig.appDirectory, resolvedConfig.pageDirectory)
|
|
5288
|
-
);
|
|
5289
|
-
const indexer = new SearchIndexer({
|
|
5290
|
-
...resolvedConfig,
|
|
5291
|
-
srcDir: fixPath(resolve(cwd(), resolvedConfig.appDirectory)),
|
|
5292
|
-
typeDocProps: {}
|
|
5293
|
-
});
|
|
5294
|
-
const files = glob.sync(
|
|
5295
|
-
[`${routesDir}/**/*.mdx`, `${routesDir}/**/*.tsx`],
|
|
5296
|
-
{
|
|
5297
|
-
absolute: true,
|
|
5298
|
-
cwd: cwd()
|
|
5299
|
-
}
|
|
5300
|
-
);
|
|
5301
|
-
indexer.buildIndex(files, true);
|
|
5302
|
-
await writeFile(
|
|
5303
|
-
resolve(cwd(), options.output),
|
|
5304
|
-
JSON.stringify(indexer.pageMap, null, 2),
|
|
5305
|
-
"utf-8"
|
|
5306
|
-
);
|
|
5307
|
-
} catch (error) {
|
|
5308
|
-
console.error(
|
|
5309
|
-
"Generate Site Data Error:",
|
|
5310
|
-
error instanceof Error ? error.message : String(error)
|
|
5311
|
-
);
|
|
5312
|
-
process.exit(1);
|
|
5313
|
-
}
|
|
5314
|
-
});
|
|
5279
|
+
// src/ai-knowledge/env.ts
|
|
5280
|
+
function loadEnv() {
|
|
5281
|
+
const options = program.optsWithGlobals();
|
|
5282
|
+
if (options.env) {
|
|
5283
|
+
config({ path: options.env, quiet: true });
|
|
5284
|
+
} else {
|
|
5285
|
+
config({ quiet: true });
|
|
5286
|
+
}
|
|
5315
5287
|
}
|
|
5316
|
-
|
|
5317
|
-
|
|
5318
|
-
|
|
5319
|
-
|
|
5320
|
-
|
|
5321
|
-
|
|
5322
|
-
|
|
5323
|
-
|
|
5324
|
-
|
|
5288
|
+
function getConfigFromEnv() {
|
|
5289
|
+
const openWebUiUrl = process.env.WEB_UI_URL || process.env.OPEN_WEB_UI_URL;
|
|
5290
|
+
const openWebUiKey = process.env.WEB_UI_KEY || process.env.OPEN_WEB_UI_API_KEY;
|
|
5291
|
+
const knowledgeId = process.env.KNOWLEDGE_ID || process.env.OPEN_WEB_UI_KNOWLEDGE_ID;
|
|
5292
|
+
if (!openWebUiUrl || !openWebUiKey || !knowledgeId) {
|
|
5293
|
+
throw new Error("WEB_UI_URL, WEB_UI_KEY, and KNOWLEDGE_ID must be set");
|
|
5294
|
+
}
|
|
5295
|
+
return {
|
|
5296
|
+
knowledgeId,
|
|
5297
|
+
webUiKey: openWebUiKey,
|
|
5298
|
+
webUiUrl: openWebUiUrl
|
|
5299
|
+
};
|
|
5325
5300
|
}
|
|
5326
|
-
|
|
5327
|
-
|
|
5328
|
-
|
|
5329
|
-
this.config = config2;
|
|
5301
|
+
function parseCliMetadata(cliMetadata) {
|
|
5302
|
+
if (!cliMetadata?.length) {
|
|
5303
|
+
return void 0;
|
|
5330
5304
|
}
|
|
5331
|
-
|
|
5332
|
-
|
|
5333
|
-
|
|
5334
|
-
|
|
5305
|
+
return Object.fromEntries(cliMetadata.map((entry) => entry.split("=")));
|
|
5306
|
+
}
|
|
5307
|
+
function loadKnowledgeConfigFromEnv(options) {
|
|
5308
|
+
const configLoader = new ConfigLoader({});
|
|
5309
|
+
const resolvedConfig = configLoader.loadConfig();
|
|
5310
|
+
const fileConfig = resolvedConfig.knowledge?.global;
|
|
5311
|
+
const exclude = (options.exclude?.length ? options.exclude : void 0) ?? fileConfig?.exclude ?? (process.env.FILE_EXCLUDE_PATTERN ?? "").split(",").filter(Boolean);
|
|
5312
|
+
const outputPath = options.outputPath ?? fileConfig?.outputPath ?? process.env.KNOWLEDGE_OUTPUT_PATH;
|
|
5313
|
+
if (!outputPath) {
|
|
5314
|
+
throw new Error("Missing required outputPath");
|
|
5335
5315
|
}
|
|
5336
|
-
|
|
5337
|
-
|
|
5338
|
-
|
|
5339
|
-
|
|
5340
|
-
|
|
5316
|
+
const routeDir = join2(
|
|
5317
|
+
resolvedConfig.appDirectory,
|
|
5318
|
+
resolvedConfig.pageDirectory
|
|
5319
|
+
);
|
|
5320
|
+
if (!existsSync(resolve(routeDir))) {
|
|
5321
|
+
throw new Error(`Route directory ${routeDir} does not exist`);
|
|
5341
5322
|
}
|
|
5342
|
-
|
|
5343
|
-
|
|
5344
|
-
|
|
5345
|
-
|
|
5346
|
-
|
|
5347
|
-
|
|
5323
|
+
const cliMetadata = parseCliMetadata(options.metadata);
|
|
5324
|
+
const mergedMetadata = fileConfig?.metadata || cliMetadata ? { ...fileConfig?.metadata, ...cliMetadata } : void 0;
|
|
5325
|
+
return {
|
|
5326
|
+
...fileConfig,
|
|
5327
|
+
...options,
|
|
5328
|
+
baseUrl: options.baseUrl ?? fileConfig?.baseUrl ?? process.env.DOCS_SITE_BASE_URL,
|
|
5329
|
+
docPropsPath: resolvedConfig.typeDocProps,
|
|
5330
|
+
exclude,
|
|
5331
|
+
extraFiles: fileConfig?.extraFiles,
|
|
5332
|
+
manifestOutputPath: outputPath,
|
|
5333
|
+
metadata: mergedMetadata,
|
|
5334
|
+
outputPath,
|
|
5335
|
+
pageTitlePrefix: options.pageTitlePrefix ?? fileConfig?.pageTitlePrefix ?? process.env.PAGE_TITLE_PREFIX,
|
|
5336
|
+
routeDir
|
|
5337
|
+
};
|
|
5338
|
+
}
|
|
5339
|
+
function mergeEnvironmentConfig(global, environment) {
|
|
5340
|
+
return {
|
|
5341
|
+
...global,
|
|
5342
|
+
...environment,
|
|
5343
|
+
extraFiles: environment.extraFiles ?? global?.extraFiles,
|
|
5344
|
+
metadata: global?.metadata || environment.metadata ? { ...global?.metadata, ...environment.metadata } : void 0
|
|
5345
|
+
};
|
|
5346
|
+
}
|
|
5347
|
+
function loadEnvironmentConfigs(options = {}) {
|
|
5348
|
+
const configLoader = new ConfigLoader({});
|
|
5349
|
+
const resolvedConfig = configLoader.loadConfig();
|
|
5350
|
+
const knowledgeConfig = resolvedConfig.knowledge;
|
|
5351
|
+
const globalConfig = knowledgeConfig?.global;
|
|
5352
|
+
const environments = knowledgeConfig?.environments;
|
|
5353
|
+
const routeDir = join2(
|
|
5354
|
+
resolvedConfig.appDirectory,
|
|
5355
|
+
resolvedConfig.pageDirectory
|
|
5356
|
+
);
|
|
5357
|
+
if (!existsSync(resolve(routeDir))) {
|
|
5358
|
+
throw new Error(`Route directory ${routeDir} does not exist`);
|
|
5348
5359
|
}
|
|
5349
|
-
|
|
5350
|
-
const
|
|
5351
|
-
|
|
5352
|
-
|
|
5353
|
-
|
|
5354
|
-
|
|
5355
|
-
|
|
5356
|
-
|
|
5357
|
-
|
|
5358
|
-
|
|
5359
|
-
|
|
5360
|
-
|
|
5361
|
-
|
|
5362
|
-
|
|
5360
|
+
if (!environments || environments.length === 0 || options.cliOptions?.outputPath) {
|
|
5361
|
+
const legacyConfig = loadKnowledgeConfigFromEnv(
|
|
5362
|
+
options.cliOptions ?? { outputMode: "per-page" }
|
|
5363
|
+
);
|
|
5364
|
+
return [legacyConfig];
|
|
5365
|
+
}
|
|
5366
|
+
let filteredEnvironments = environments;
|
|
5367
|
+
if (options.environments?.length) {
|
|
5368
|
+
const filterSet = new Set(options.environments);
|
|
5369
|
+
filteredEnvironments = environments.filter((env) => filterSet.has(env.id));
|
|
5370
|
+
}
|
|
5371
|
+
if (filteredEnvironments.length === 0) {
|
|
5372
|
+
throw new Error(
|
|
5373
|
+
`No matching environments found. Available: ${environments.map((e) => e.id).join(", ")}`
|
|
5374
|
+
);
|
|
5375
|
+
}
|
|
5376
|
+
return filteredEnvironments.map((envConfig) => {
|
|
5377
|
+
const merged = mergeEnvironmentConfig(globalConfig, envConfig);
|
|
5378
|
+
const cliOpts = options.cliOptions;
|
|
5379
|
+
const cliMetadata = parseCliMetadata(cliOpts?.metadata);
|
|
5380
|
+
const mergedMetadata = merged.metadata || cliMetadata ? { ...merged.metadata, ...cliMetadata } : void 0;
|
|
5381
|
+
return {
|
|
5382
|
+
...merged,
|
|
5383
|
+
...cliOpts,
|
|
5384
|
+
baseUrl: cliOpts?.baseUrl ?? merged.baseUrl ?? process.env.DOCS_SITE_BASE_URL,
|
|
5385
|
+
docPropsPath: resolvedConfig.typeDocProps,
|
|
5386
|
+
environmentName: envConfig.id,
|
|
5387
|
+
exclude: (cliOpts?.exclude?.length ? cliOpts.exclude : void 0) ?? merged.exclude ?? (process.env.FILE_EXCLUDE_PATTERN ?? "").split(",").filter(Boolean),
|
|
5388
|
+
extraFiles: merged.extraFiles,
|
|
5389
|
+
manifestOutputPath: merged.outputPath,
|
|
5390
|
+
metadata: mergedMetadata,
|
|
5391
|
+
outputMode: cliOpts?.outputMode ?? merged.outputMode ?? "per-page",
|
|
5392
|
+
outputPath: merged.outputPath,
|
|
5393
|
+
pageTitlePrefix: cliOpts?.pageTitlePrefix ?? merged.pageTitlePrefix ?? process.env.PAGE_TITLE_PREFIX,
|
|
5394
|
+
routeDir
|
|
5395
|
+
};
|
|
5396
|
+
});
|
|
5397
|
+
}
|
|
5398
|
+
|
|
5399
|
+
// src/ai-knowledge/generator/knowledge-generator.ts
|
|
5400
|
+
import AdmZip from "adm-zip";
|
|
5401
|
+
import chalk3 from "chalk";
|
|
5402
|
+
import { minimatch } from "minimatch";
|
|
5403
|
+
import { mkdir, readdir, readFile as readFile4, rm, stat, writeFile } from "node:fs/promises";
|
|
5404
|
+
import { basename as basename2, dirname as dirname3, join as join6, relative as relative2, resolve as resolve4 } from "node:path";
|
|
5405
|
+
import remarkFrontmatter2 from "remark-frontmatter";
|
|
5406
|
+
import remarkMdx3 from "remark-mdx";
|
|
5407
|
+
import remarkParse4 from "remark-parse";
|
|
5408
|
+
import remarkParseFrontmatter2 from "remark-parse-frontmatter";
|
|
5409
|
+
import remarkStringify4 from "remark-stringify";
|
|
5410
|
+
import { unified as unified5 } from "unified";
|
|
5411
|
+
import { visit as visit11 } from "unist-util-visit";
|
|
5412
|
+
import { kebabCase as kebabCase3 } from "@qualcomm-ui/utils/change-case";
|
|
5413
|
+
|
|
5414
|
+
// src/docs-plugin/remark/remark-extract-meta.ts
|
|
5415
|
+
import { SKIP, visit as visit5 } from "unist-util-visit";
|
|
5416
|
+
function parseValue(value) {
|
|
5417
|
+
const trimmed = value.trim();
|
|
5418
|
+
if (trimmed.startsWith("[") && trimmed.endsWith("]")) {
|
|
5419
|
+
const inner = trimmed.slice(1, -1);
|
|
5420
|
+
return inner.split(",").map((item) => item.trim()).filter(Boolean);
|
|
5421
|
+
}
|
|
5422
|
+
return trimmed;
|
|
5423
|
+
}
|
|
5424
|
+
function parseMetaContent(content) {
|
|
5425
|
+
const result = {};
|
|
5426
|
+
const lines = content.split("\n");
|
|
5427
|
+
for (const line of lines) {
|
|
5428
|
+
const trimmed = line.trim();
|
|
5429
|
+
if (!trimmed || trimmed === ":::") {
|
|
5430
|
+
continue;
|
|
5363
5431
|
}
|
|
5364
|
-
const
|
|
5365
|
-
if (
|
|
5366
|
-
|
|
5432
|
+
const colonIndex = trimmed.indexOf(":");
|
|
5433
|
+
if (colonIndex === -1) {
|
|
5434
|
+
continue;
|
|
5367
5435
|
}
|
|
5368
|
-
|
|
5369
|
-
|
|
5436
|
+
const key = trimmed.slice(0, colonIndex).trim();
|
|
5437
|
+
const value = trimmed.slice(colonIndex + 1).trim();
|
|
5438
|
+
if (key && value) {
|
|
5439
|
+
result[key] = parseValue(value);
|
|
5370
5440
|
}
|
|
5371
|
-
const url = `${this.config.baseUrl}/api/v1/files/${params.toString() ? `?${params}` : ""}`;
|
|
5372
|
-
const response = await fetch(url, {
|
|
5373
|
-
body: formData,
|
|
5374
|
-
headers: this.headers,
|
|
5375
|
-
method: "POST"
|
|
5376
|
-
});
|
|
5377
|
-
return this.handleResponse(response);
|
|
5378
5441
|
}
|
|
5379
|
-
|
|
5380
|
-
|
|
5381
|
-
|
|
5382
|
-
|
|
5383
|
-
|
|
5384
|
-
|
|
5442
|
+
return result;
|
|
5443
|
+
}
|
|
5444
|
+
var remarkExtractMeta = (metadata = {}) => {
|
|
5445
|
+
return (tree) => {
|
|
5446
|
+
const nodesToRemove = [];
|
|
5447
|
+
visit5(tree, "paragraph", (node, index, parent) => {
|
|
5448
|
+
if (!parent || index === void 0) {
|
|
5449
|
+
return;
|
|
5450
|
+
}
|
|
5451
|
+
const firstChild = node.children[0];
|
|
5452
|
+
if (firstChild?.type !== "text") {
|
|
5453
|
+
return;
|
|
5454
|
+
}
|
|
5455
|
+
const text = firstChild.value;
|
|
5456
|
+
const openMatch = text.match(/^:::\s*meta\s*/);
|
|
5457
|
+
if (!openMatch) {
|
|
5458
|
+
return;
|
|
5459
|
+
}
|
|
5460
|
+
if (text.includes(":::") && text.lastIndexOf(":::") > openMatch[0].length) {
|
|
5461
|
+
const afterOpen = text.slice(openMatch[0].length);
|
|
5462
|
+
const closeIndex = afterOpen.lastIndexOf(":::");
|
|
5463
|
+
const content = afterOpen.slice(0, closeIndex);
|
|
5464
|
+
const parsed = parseMetaContent(content);
|
|
5465
|
+
Object.assign(metadata, parsed);
|
|
5466
|
+
nodesToRemove.push({ index, parent });
|
|
5467
|
+
return SKIP;
|
|
5468
|
+
}
|
|
5469
|
+
let fullText = text;
|
|
5470
|
+
for (let i = 1; i < node.children.length; i++) {
|
|
5471
|
+
const child = node.children[i];
|
|
5472
|
+
if (child.type === "text") {
|
|
5473
|
+
fullText += child.value;
|
|
5474
|
+
}
|
|
5475
|
+
}
|
|
5476
|
+
const afterOpenFull = fullText.slice(openMatch[0].length);
|
|
5477
|
+
const closeIndexFull = afterOpenFull.lastIndexOf(":::");
|
|
5478
|
+
if (closeIndexFull !== -1) {
|
|
5479
|
+
const content = afterOpenFull.slice(0, closeIndexFull);
|
|
5480
|
+
const parsed = parseMetaContent(content);
|
|
5481
|
+
Object.assign(metadata, parsed);
|
|
5482
|
+
nodesToRemove.push({ index, parent });
|
|
5483
|
+
return SKIP;
|
|
5385
5484
|
}
|
|
5386
|
-
);
|
|
5387
|
-
return this.handleResponse(response);
|
|
5388
|
-
}
|
|
5389
|
-
async search(pattern, includeContent = true) {
|
|
5390
|
-
const params = new URLSearchParams({
|
|
5391
|
-
content: String(includeContent),
|
|
5392
|
-
filename: pattern
|
|
5393
5485
|
});
|
|
5394
|
-
|
|
5395
|
-
|
|
5396
|
-
|
|
5397
|
-
);
|
|
5398
|
-
if (response.status === 404) {
|
|
5399
|
-
return [];
|
|
5486
|
+
for (let i = nodesToRemove.length - 1; i >= 0; i--) {
|
|
5487
|
+
const { index, parent } = nodesToRemove[i];
|
|
5488
|
+
parent.children.splice(index, 1);
|
|
5400
5489
|
}
|
|
5401
|
-
|
|
5490
|
+
};
|
|
5491
|
+
};
|
|
5492
|
+
|
|
5493
|
+
// src/ai-knowledge/generator/config.ts
|
|
5494
|
+
var currentConfig = null;
|
|
5495
|
+
function setConfig(config3) {
|
|
5496
|
+
currentConfig = config3;
|
|
5497
|
+
}
|
|
5498
|
+
function getConfig() {
|
|
5499
|
+
if (!currentConfig) {
|
|
5500
|
+
throw new Error("Config not initialized");
|
|
5402
5501
|
}
|
|
5403
|
-
|
|
5404
|
-
|
|
5405
|
-
|
|
5406
|
-
|
|
5407
|
-
|
|
5408
|
-
|
|
5409
|
-
|
|
5410
|
-
|
|
5411
|
-
|
|
5412
|
-
|
|
5413
|
-
|
|
5414
|
-
|
|
5502
|
+
return currentConfig;
|
|
5503
|
+
}
|
|
5504
|
+
|
|
5505
|
+
// src/ai-knowledge/generator/demo-plugin.ts
|
|
5506
|
+
import { readFile as readFile2 } from "node:fs/promises";
|
|
5507
|
+
import { basename, extname, join as join4 } from "node:path";
|
|
5508
|
+
import { visit as visit6 } from "unist-util-visit";
|
|
5509
|
+
import { kebabCase } from "@qualcomm-ui/utils/change-case";
|
|
5510
|
+
|
|
5511
|
+
// src/ai-knowledge/generator/utils.ts
|
|
5512
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
5513
|
+
import { access, readFile } from "node:fs/promises";
|
|
5514
|
+
import { dirname, join as join3, resolve as resolve2 } from "node:path";
|
|
5515
|
+
import ts from "typescript";
|
|
5516
|
+
async function exists(dirPath) {
|
|
5517
|
+
return access(dirPath).then(() => true).catch(() => false);
|
|
5518
|
+
}
|
|
5519
|
+
function computeMd5(content) {
|
|
5520
|
+
return createHash2("md5").update(content).digest("hex");
|
|
5521
|
+
}
|
|
5522
|
+
function isPreviewLine(trimmedLine) {
|
|
5523
|
+
return trimmedLine === "// preview" || /^\{\s*\/\*\s*preview\s*\*\/\s*\}$/.test(trimmedLine) || /^<!--\s*preview\s*-->$/.test(trimmedLine);
|
|
5524
|
+
}
|
|
5525
|
+
function removePreviewLines(code) {
|
|
5526
|
+
return code.split("\n").filter((line) => !isPreviewLine(line.trim())).join("\n");
|
|
5527
|
+
}
|
|
5528
|
+
function getIntroLines(projectName, description) {
|
|
5529
|
+
const lines = [];
|
|
5530
|
+
if (projectName) {
|
|
5531
|
+
lines.push(`# ${projectName}`);
|
|
5415
5532
|
}
|
|
5416
|
-
|
|
5417
|
-
|
|
5418
|
-
|
|
5419
|
-
{ headers: this.headers }
|
|
5420
|
-
);
|
|
5421
|
-
return this.handleResponse(response);
|
|
5533
|
+
if (description) {
|
|
5534
|
+
lines.push("");
|
|
5535
|
+
lines.push(`> ${description}`);
|
|
5422
5536
|
}
|
|
5423
|
-
|
|
5424
|
-
|
|
5425
|
-
|
|
5426
|
-
|
|
5427
|
-
|
|
5428
|
-
|
|
5429
|
-
|
|
5537
|
+
return lines.join("\n");
|
|
5538
|
+
}
|
|
5539
|
+
function extractRelativeImports(content) {
|
|
5540
|
+
const sourceFile = ts.createSourceFile(
|
|
5541
|
+
"temp.ts",
|
|
5542
|
+
content,
|
|
5543
|
+
ts.ScriptTarget.Latest,
|
|
5544
|
+
false,
|
|
5545
|
+
ts.ScriptKind.TSX
|
|
5546
|
+
);
|
|
5547
|
+
const imports = [];
|
|
5548
|
+
for (const statement of sourceFile.statements) {
|
|
5549
|
+
if (ts.isImportDeclaration(statement) && ts.isStringLiteral(statement.moduleSpecifier)) {
|
|
5550
|
+
const path = statement.moduleSpecifier.text;
|
|
5551
|
+
if (path.startsWith(".")) {
|
|
5552
|
+
imports.push(path);
|
|
5430
5553
|
}
|
|
5431
|
-
await new Promise((resolve8) => setTimeout(resolve8, intervalMs));
|
|
5432
5554
|
}
|
|
5433
|
-
throw new Error(`File processing timed out after ${maxAttempts} attempts`);
|
|
5434
5555
|
}
|
|
5435
|
-
|
|
5436
|
-
|
|
5437
|
-
|
|
5438
|
-
|
|
5439
|
-
|
|
5440
|
-
|
|
5556
|
+
return imports;
|
|
5557
|
+
}
|
|
5558
|
+
async function resolveModulePath(importPath, fromFile) {
|
|
5559
|
+
const fromDir = dirname(fromFile);
|
|
5560
|
+
const baseResolved = resolve2(fromDir, importPath);
|
|
5561
|
+
const extensions = [".ts", ".tsx", ".js", ".jsx", ""];
|
|
5562
|
+
for (const ext of extensions) {
|
|
5563
|
+
const fullPath = baseResolved + ext;
|
|
5564
|
+
if (await exists(fullPath)) {
|
|
5565
|
+
return fullPath;
|
|
5566
|
+
}
|
|
5441
5567
|
}
|
|
5442
|
-
|
|
5443
|
-
const
|
|
5444
|
-
|
|
5445
|
-
|
|
5446
|
-
|
|
5447
|
-
|
|
5448
|
-
|
|
5568
|
+
if (await exists(baseResolved)) {
|
|
5569
|
+
const indexPath = join3(baseResolved, "index.ts");
|
|
5570
|
+
if (await exists(indexPath)) {
|
|
5571
|
+
return indexPath;
|
|
5572
|
+
}
|
|
5573
|
+
}
|
|
5574
|
+
return null;
|
|
5575
|
+
}
|
|
5576
|
+
function extractMetadata(metadata) {
|
|
5577
|
+
return Object.entries(metadata ?? {});
|
|
5578
|
+
}
|
|
5579
|
+
|
|
5580
|
+
// src/ai-knowledge/generator/demo-plugin.ts
|
|
5581
|
+
async function collectDemoImports(demoCode, demoFilePath, visited = /* @__PURE__ */ new Set()) {
|
|
5582
|
+
const modules = [];
|
|
5583
|
+
const relativeImports = extractRelativeImports(demoCode);
|
|
5584
|
+
for (const importPath of relativeImports) {
|
|
5585
|
+
const resolvedPath = await resolveModulePath(importPath, demoFilePath);
|
|
5586
|
+
if (!resolvedPath || visited.has(resolvedPath)) {
|
|
5587
|
+
continue;
|
|
5588
|
+
}
|
|
5589
|
+
visited.add(resolvedPath);
|
|
5590
|
+
try {
|
|
5591
|
+
const importContent = await readFile2(resolvedPath, "utf-8");
|
|
5592
|
+
modules.push({
|
|
5593
|
+
content: importContent,
|
|
5594
|
+
path: resolvedPath
|
|
5595
|
+
});
|
|
5596
|
+
const nestedModules = await collectDemoImports(
|
|
5597
|
+
importContent,
|
|
5598
|
+
resolvedPath,
|
|
5599
|
+
visited
|
|
5600
|
+
);
|
|
5601
|
+
modules.push(...nestedModules);
|
|
5602
|
+
} catch {
|
|
5603
|
+
if (getConfig().verbose) {
|
|
5604
|
+
console.log(` Could not read import: ${resolvedPath}`);
|
|
5449
5605
|
}
|
|
5450
|
-
|
|
5451
|
-
return this.handleResponse(response);
|
|
5606
|
+
}
|
|
5452
5607
|
}
|
|
5453
|
-
|
|
5454
|
-
|
|
5455
|
-
|
|
5456
|
-
|
|
5457
|
-
|
|
5458
|
-
|
|
5608
|
+
return modules;
|
|
5609
|
+
}
|
|
5610
|
+
function formatDemos(demosFolder) {
|
|
5611
|
+
return () => async (tree) => {
|
|
5612
|
+
const promises = [];
|
|
5613
|
+
visit6(
|
|
5614
|
+
tree,
|
|
5615
|
+
"mdxJsxFlowElement",
|
|
5616
|
+
(node, index, parent) => {
|
|
5617
|
+
if (!node?.name || !["QdsDemo", "CodeDemo", "Demo"].includes(node.name)) {
|
|
5618
|
+
return;
|
|
5619
|
+
}
|
|
5620
|
+
const nameAttr = node.attributes?.find(
|
|
5621
|
+
(attr) => attr.type === "mdxJsxAttribute" && attr.name === "name"
|
|
5622
|
+
);
|
|
5623
|
+
const nodeAttr = node.attributes?.find(
|
|
5624
|
+
(attr) => attr.type === "mdxJsxAttribute" && attr.name === "node"
|
|
5625
|
+
);
|
|
5626
|
+
let demoName;
|
|
5627
|
+
if (nameAttr && typeof nameAttr.value === "string") {
|
|
5628
|
+
demoName = nameAttr.value;
|
|
5629
|
+
} else if (nodeAttr?.value && typeof nodeAttr.value !== "string") {
|
|
5630
|
+
const estree = nodeAttr.value.data?.estree;
|
|
5631
|
+
if (estree?.body?.[0]?.type === "ExpressionStatement") {
|
|
5632
|
+
const expression = estree.body[0].expression;
|
|
5633
|
+
if (expression.type === "MemberExpression" && expression.object.type === "Identifier" && expression.object.name === "Demo" && expression.property.type === "Identifier") {
|
|
5634
|
+
demoName = expression.property.name;
|
|
5635
|
+
}
|
|
5636
|
+
}
|
|
5637
|
+
}
|
|
5638
|
+
if (!demoName) {
|
|
5639
|
+
if (parent && index !== void 0) {
|
|
5640
|
+
parent.children.splice(index, 1);
|
|
5641
|
+
}
|
|
5642
|
+
return;
|
|
5643
|
+
}
|
|
5644
|
+
promises.push(
|
|
5645
|
+
(async () => {
|
|
5646
|
+
const kebabName = kebabCase(demoName);
|
|
5647
|
+
let filePath = `${kebabName}.tsx`;
|
|
5648
|
+
if (!demosFolder) {
|
|
5649
|
+
if (getConfig().verbose) {
|
|
5650
|
+
console.log(` No demos folder for ${demoName}`);
|
|
5651
|
+
}
|
|
5652
|
+
if (parent && index !== void 0) {
|
|
5653
|
+
parent.children.splice(index, 1);
|
|
5654
|
+
}
|
|
5655
|
+
return;
|
|
5656
|
+
}
|
|
5657
|
+
let demoFilePath = join4(demosFolder, filePath);
|
|
5658
|
+
let isAngularDemo = false;
|
|
5659
|
+
if (!await exists(demoFilePath)) {
|
|
5660
|
+
demoFilePath = join4(demosFolder, `${kebabName}.ts`);
|
|
5661
|
+
if (await exists(demoFilePath)) {
|
|
5662
|
+
isAngularDemo = true;
|
|
5663
|
+
filePath = `${kebabCase(demoName).replace("-component", ".component")}.ts`;
|
|
5664
|
+
demoFilePath = join4(demosFolder, filePath);
|
|
5665
|
+
} else {
|
|
5666
|
+
console.log(` Demo not found ${demoName}`);
|
|
5667
|
+
if (parent && index !== void 0) {
|
|
5668
|
+
parent.children.splice(index, 1);
|
|
5669
|
+
}
|
|
5670
|
+
return;
|
|
5671
|
+
}
|
|
5672
|
+
}
|
|
5673
|
+
try {
|
|
5674
|
+
const demoCode = await readFile2(demoFilePath, "utf-8");
|
|
5675
|
+
const cleanedCode = removePreviewLines(demoCode);
|
|
5676
|
+
if (getConfig().verbose) {
|
|
5677
|
+
console.log(` Replaced demo ${demoName} with source code`);
|
|
5678
|
+
}
|
|
5679
|
+
const demoCodeBlock = {
|
|
5680
|
+
lang: isAngularDemo ? "angular-ts" : "tsx",
|
|
5681
|
+
meta: null,
|
|
5682
|
+
type: "code",
|
|
5683
|
+
value: cleanedCode
|
|
5684
|
+
};
|
|
5685
|
+
const importedModules = await collectDemoImports(
|
|
5686
|
+
demoCode,
|
|
5687
|
+
demoFilePath
|
|
5688
|
+
);
|
|
5689
|
+
if (importedModules.length === 0 || !parent || index === void 0) {
|
|
5690
|
+
Object.assign(node, demoCodeBlock);
|
|
5691
|
+
} else {
|
|
5692
|
+
const nodesToInsert = [demoCodeBlock];
|
|
5693
|
+
for (const importedModule of importedModules) {
|
|
5694
|
+
const ext = extname(importedModule.path).slice(1);
|
|
5695
|
+
const filename = basename(importedModule.path);
|
|
5696
|
+
nodesToInsert.push({
|
|
5697
|
+
lang: ext,
|
|
5698
|
+
meta: `title="${filename}"`,
|
|
5699
|
+
type: "code",
|
|
5700
|
+
value: importedModule.content
|
|
5701
|
+
});
|
|
5702
|
+
}
|
|
5703
|
+
parent.children.splice(index, 1, ...nodesToInsert);
|
|
5704
|
+
if (getConfig().verbose) {
|
|
5705
|
+
console.log(
|
|
5706
|
+
` Added ${importedModules.length} imported file(s) after demo`
|
|
5707
|
+
);
|
|
5708
|
+
}
|
|
5709
|
+
}
|
|
5710
|
+
} catch (error) {
|
|
5711
|
+
if (getConfig().verbose) {
|
|
5712
|
+
console.log(`Error reading demo ${demoName}`, error);
|
|
5713
|
+
}
|
|
5714
|
+
if (parent && index !== void 0) {
|
|
5715
|
+
parent.children.splice(index, 1);
|
|
5716
|
+
}
|
|
5717
|
+
}
|
|
5718
|
+
})()
|
|
5719
|
+
);
|
|
5459
5720
|
}
|
|
5460
5721
|
);
|
|
5722
|
+
await Promise.all(promises);
|
|
5723
|
+
};
|
|
5724
|
+
}
|
|
5725
|
+
|
|
5726
|
+
// src/ai-knowledge/generator/doc-props-plugin.ts
|
|
5727
|
+
import { readFile as readFile3 } from "node:fs/promises";
|
|
5728
|
+
import { dirname as dirname2, join as join5, resolve as resolve3 } from "node:path";
|
|
5729
|
+
import { visit as visit7 } from "unist-util-visit";
|
|
5730
|
+
function extractBestType(propInfo) {
|
|
5731
|
+
const type = propInfo.resolvedType?.prettyType || propInfo.type;
|
|
5732
|
+
return cleanType(type.startsWith("| ") ? type.substring(2) : type);
|
|
5733
|
+
}
|
|
5734
|
+
function extractRequired(propInfo, isPartial) {
|
|
5735
|
+
return Boolean(propInfo.resolvedType?.required && !isPartial);
|
|
5736
|
+
}
|
|
5737
|
+
function cleanType(type) {
|
|
5738
|
+
return type.replace(/\n/g, " ").replace(/\s+/g, " ").trim();
|
|
5739
|
+
}
|
|
5740
|
+
function cleanDefaultValue(defaultValue) {
|
|
5741
|
+
return defaultValue.replace(/^\n+/, "").replace(/\n+$/, "").trim();
|
|
5742
|
+
}
|
|
5743
|
+
function escapeText(value) {
|
|
5744
|
+
return value.replace(/\n/g, " ");
|
|
5745
|
+
}
|
|
5746
|
+
function propsToDefinitionList(props) {
|
|
5747
|
+
if (props.length === 0) {
|
|
5748
|
+
return "";
|
|
5461
5749
|
}
|
|
5462
|
-
|
|
5463
|
-
const
|
|
5464
|
-
if (
|
|
5465
|
-
|
|
5466
|
-
throw new Error(error.detail || "Failed to get file content");
|
|
5750
|
+
return props.map((prop) => {
|
|
5751
|
+
const parts = [`- **${prop.name}** (\`${escapeText(prop.type)}\``];
|
|
5752
|
+
if (prop.defaultValue) {
|
|
5753
|
+
parts.push(`, default: \`${escapeText(prop.defaultValue)}\``);
|
|
5467
5754
|
}
|
|
5468
|
-
|
|
5469
|
-
|
|
5470
|
-
async delete(id) {
|
|
5471
|
-
const response = await fetch(`${this.config.baseUrl}/api/v1/files/${id}`, {
|
|
5472
|
-
headers: this.headers,
|
|
5473
|
-
method: "DELETE"
|
|
5474
|
-
});
|
|
5475
|
-
return this.handleResponse(response);
|
|
5476
|
-
}
|
|
5477
|
-
};
|
|
5478
|
-
var KnowledgeApi = class {
|
|
5479
|
-
config;
|
|
5480
|
-
constructor(config2) {
|
|
5481
|
-
this.config = config2;
|
|
5482
|
-
}
|
|
5483
|
-
get headers() {
|
|
5484
|
-
return {
|
|
5485
|
-
Authorization: `Bearer ${this.config.apiKey}`
|
|
5486
|
-
};
|
|
5487
|
-
}
|
|
5488
|
-
get jsonHeaders() {
|
|
5489
|
-
return {
|
|
5490
|
-
...this.headers,
|
|
5491
|
-
"Content-Type": "application/json"
|
|
5492
|
-
};
|
|
5493
|
-
}
|
|
5494
|
-
async handleResponse(response) {
|
|
5495
|
-
const data = await response.json();
|
|
5496
|
-
if (isErrorResponse(data)) {
|
|
5497
|
-
throw new Error(data.detail);
|
|
5755
|
+
if (prop.required) {
|
|
5756
|
+
parts.push(", required");
|
|
5498
5757
|
}
|
|
5499
|
-
|
|
5500
|
-
|
|
5501
|
-
|
|
5502
|
-
|
|
5503
|
-
|
|
5504
|
-
|
|
5505
|
-
|
|
5506
|
-
|
|
5507
|
-
|
|
5508
|
-
|
|
5509
|
-
|
|
5510
|
-
|
|
5511
|
-
|
|
5758
|
+
parts.push(")");
|
|
5759
|
+
if (prop.description) {
|
|
5760
|
+
parts.push(` - ${escapeText(prop.description)}`);
|
|
5761
|
+
}
|
|
5762
|
+
return parts.join("");
|
|
5763
|
+
}).join("\n");
|
|
5764
|
+
}
|
|
5765
|
+
var PropFormatter = class {
|
|
5766
|
+
docProps = null;
|
|
5767
|
+
async loadDocProps() {
|
|
5768
|
+
if (this.docProps) {
|
|
5769
|
+
return this.docProps;
|
|
5770
|
+
}
|
|
5771
|
+
const config3 = getConfig();
|
|
5772
|
+
const resolvedDocPropsPath = config3.docPropsPath ? await exists(config3.docPropsPath) ? config3.docPropsPath : resolve3(process.cwd(), config3.docPropsPath) : join5(dirname2(config3.routeDir), "doc-props.json");
|
|
5773
|
+
if (!await exists(resolvedDocPropsPath)) {
|
|
5774
|
+
if (config3.verbose) {
|
|
5775
|
+
console.log(`Doc props file not found at: ${resolvedDocPropsPath}`);
|
|
5512
5776
|
}
|
|
5513
|
-
|
|
5514
|
-
|
|
5515
|
-
|
|
5516
|
-
|
|
5517
|
-
|
|
5518
|
-
|
|
5519
|
-
|
|
5520
|
-
|
|
5521
|
-
|
|
5522
|
-
|
|
5777
|
+
return null;
|
|
5778
|
+
}
|
|
5779
|
+
try {
|
|
5780
|
+
const content = await readFile3(resolvedDocPropsPath, "utf-8");
|
|
5781
|
+
const docProps = JSON.parse(content);
|
|
5782
|
+
if (config3.verbose) {
|
|
5783
|
+
console.log(`Loaded doc props from: ${resolvedDocPropsPath}`);
|
|
5784
|
+
console.log(
|
|
5785
|
+
`Found ${Object.keys(docProps.props).length} component types`
|
|
5786
|
+
);
|
|
5523
5787
|
}
|
|
5524
|
-
|
|
5525
|
-
|
|
5526
|
-
|
|
5527
|
-
|
|
5528
|
-
|
|
5529
|
-
`${this.config.baseUrl}/api/v1/knowledge/reindex`,
|
|
5530
|
-
{
|
|
5531
|
-
headers: this.jsonHeaders,
|
|
5532
|
-
method: "POST"
|
|
5788
|
+
this.docProps = docProps;
|
|
5789
|
+
return docProps;
|
|
5790
|
+
} catch (error) {
|
|
5791
|
+
if (config3.verbose) {
|
|
5792
|
+
console.log("Error loading doc props", error);
|
|
5533
5793
|
}
|
|
5534
|
-
|
|
5535
|
-
|
|
5794
|
+
return null;
|
|
5795
|
+
}
|
|
5536
5796
|
}
|
|
5537
|
-
|
|
5538
|
-
|
|
5539
|
-
|
|
5540
|
-
|
|
5541
|
-
|
|
5542
|
-
|
|
5543
|
-
|
|
5544
|
-
|
|
5545
|
-
|
|
5546
|
-
|
|
5547
|
-
|
|
5548
|
-
|
|
5549
|
-
|
|
5550
|
-
|
|
5551
|
-
|
|
5552
|
-
|
|
5797
|
+
formatCommentParts(parts) {
|
|
5798
|
+
return parts.map((part) => {
|
|
5799
|
+
switch (part.kind) {
|
|
5800
|
+
case "text":
|
|
5801
|
+
return part.text;
|
|
5802
|
+
case "code":
|
|
5803
|
+
const codeText = part.text.replace(/```\w*\n?/g, "").replace(/\n?```/g, "").trim();
|
|
5804
|
+
if (codeText.includes("\n")) {
|
|
5805
|
+
return `\`\`\`
|
|
5806
|
+
${codeText}
|
|
5807
|
+
\`\`\``;
|
|
5808
|
+
} else {
|
|
5809
|
+
return codeText;
|
|
5810
|
+
}
|
|
5811
|
+
default:
|
|
5812
|
+
if (getConfig().outputMode === "per-page" && "tag" in part && part.tag === "@link" && typeof part.target === "string") {
|
|
5813
|
+
if (part.text === "Learn more") {
|
|
5814
|
+
return "";
|
|
5815
|
+
}
|
|
5816
|
+
}
|
|
5817
|
+
return part.text;
|
|
5553
5818
|
}
|
|
5554
|
-
);
|
|
5555
|
-
return this.handleResponse(response);
|
|
5819
|
+
}).join("").replace(/\n/g, " ").replace(/\s+/g, " ").trim();
|
|
5556
5820
|
}
|
|
5557
|
-
|
|
5558
|
-
|
|
5559
|
-
|
|
5560
|
-
|
|
5561
|
-
|
|
5562
|
-
|
|
5563
|
-
|
|
5821
|
+
formatComment(comment) {
|
|
5822
|
+
if (!comment) {
|
|
5823
|
+
return "";
|
|
5824
|
+
}
|
|
5825
|
+
const parts = [];
|
|
5826
|
+
if (comment.summary && comment.summary.length > 0) {
|
|
5827
|
+
const summaryText = this.formatCommentParts(comment.summary);
|
|
5828
|
+
if (summaryText.trim()) {
|
|
5829
|
+
parts.push(summaryText.trim());
|
|
5564
5830
|
}
|
|
5565
|
-
|
|
5566
|
-
|
|
5567
|
-
|
|
5568
|
-
|
|
5569
|
-
|
|
5570
|
-
|
|
5571
|
-
|
|
5572
|
-
|
|
5573
|
-
|
|
5574
|
-
|
|
5831
|
+
}
|
|
5832
|
+
if (comment.blockTags && comment.blockTags.length > 0) {
|
|
5833
|
+
for (const blockTag of comment.blockTags) {
|
|
5834
|
+
const tagContent = this.formatCommentParts(blockTag.content);
|
|
5835
|
+
if (tagContent.trim()) {
|
|
5836
|
+
const tagName = blockTag.tag.replace("@", "");
|
|
5837
|
+
if (tagName === "default" || tagName === "defaultValue") {
|
|
5838
|
+
continue;
|
|
5839
|
+
}
|
|
5840
|
+
if (tagName === "example") {
|
|
5841
|
+
parts.push(`**Example:**
|
|
5842
|
+
\`\`\`
|
|
5843
|
+
${tagContent.trim()}
|
|
5844
|
+
\`\`\``);
|
|
5845
|
+
} else {
|
|
5846
|
+
parts.push(`**${tagName}:** ${tagContent.trim()}`);
|
|
5847
|
+
}
|
|
5848
|
+
}
|
|
5575
5849
|
}
|
|
5576
|
-
|
|
5577
|
-
return
|
|
5850
|
+
}
|
|
5851
|
+
return parts.join("\n\n");
|
|
5578
5852
|
}
|
|
5579
|
-
|
|
5580
|
-
const
|
|
5581
|
-
|
|
5582
|
-
|
|
5583
|
-
|
|
5584
|
-
|
|
5585
|
-
|
|
5586
|
-
|
|
5587
|
-
|
|
5588
|
-
|
|
5589
|
-
|
|
5853
|
+
extractProps(props, isPartial) {
|
|
5854
|
+
const propsInfo = [];
|
|
5855
|
+
if (props.props?.length) {
|
|
5856
|
+
propsInfo.push(
|
|
5857
|
+
...props.props.map((prop) => this.convertPropInfo(prop, isPartial))
|
|
5858
|
+
);
|
|
5859
|
+
}
|
|
5860
|
+
if (props.input?.length) {
|
|
5861
|
+
propsInfo.push(
|
|
5862
|
+
...props.input.map(
|
|
5863
|
+
(prop) => this.convertPropInfo(prop, isPartial, "input")
|
|
5864
|
+
)
|
|
5865
|
+
);
|
|
5866
|
+
}
|
|
5867
|
+
if (props.output?.length) {
|
|
5868
|
+
propsInfo.push(
|
|
5869
|
+
...props.output.map(
|
|
5870
|
+
(prop) => this.convertPropInfo(prop, isPartial, "output")
|
|
5871
|
+
)
|
|
5872
|
+
);
|
|
5873
|
+
}
|
|
5874
|
+
return propsInfo;
|
|
5590
5875
|
}
|
|
5591
|
-
|
|
5592
|
-
|
|
5593
|
-
|
|
5594
|
-
|
|
5595
|
-
|
|
5596
|
-
|
|
5597
|
-
}
|
|
5598
|
-
|
|
5599
|
-
|
|
5876
|
+
convertPropInfo(propInfo, isPartial, propType = void 0) {
|
|
5877
|
+
return {
|
|
5878
|
+
name: propInfo.name,
|
|
5879
|
+
type: extractBestType(propInfo),
|
|
5880
|
+
...propInfo.defaultValue && {
|
|
5881
|
+
defaultValue: cleanDefaultValue(propInfo.defaultValue)
|
|
5882
|
+
},
|
|
5883
|
+
description: this.formatComment(propInfo.comment || null),
|
|
5884
|
+
propType,
|
|
5885
|
+
required: extractRequired(propInfo, isPartial) || void 0
|
|
5886
|
+
};
|
|
5600
5887
|
}
|
|
5601
|
-
|
|
5602
|
-
|
|
5603
|
-
|
|
5604
|
-
|
|
5605
|
-
|
|
5606
|
-
|
|
5607
|
-
|
|
5608
|
-
|
|
5609
|
-
|
|
5888
|
+
/**
|
|
5889
|
+
* Creates a remark plugin that replaces TypeDocProps JSX elements with
|
|
5890
|
+
* Markdown tables containing component prop documentation.
|
|
5891
|
+
*/
|
|
5892
|
+
formatTypeDocProps() {
|
|
5893
|
+
return () => (tree, _file, done) => {
|
|
5894
|
+
visit7(
|
|
5895
|
+
tree,
|
|
5896
|
+
"mdxJsxFlowElement",
|
|
5897
|
+
(node, index, parent) => {
|
|
5898
|
+
if (node?.name !== "TypeDocProps") {
|
|
5899
|
+
return;
|
|
5900
|
+
}
|
|
5901
|
+
const nameAttr = node.attributes?.find(
|
|
5902
|
+
(attr) => attr.type === "mdxJsxAttribute" && attr.name === "name"
|
|
5903
|
+
);
|
|
5904
|
+
const isPartial = node.attributes?.some(
|
|
5905
|
+
(attr) => attr.type === "mdxJsxAttribute" && attr.name === "partial"
|
|
5906
|
+
);
|
|
5907
|
+
if (!this.docProps || !nameAttr) {
|
|
5908
|
+
if (parent && index !== void 0) {
|
|
5909
|
+
parent.children.splice(index, 1);
|
|
5910
|
+
}
|
|
5911
|
+
return;
|
|
5912
|
+
}
|
|
5913
|
+
const propsNames = extractNamesFromAttribute(nameAttr);
|
|
5914
|
+
if (propsNames.length === 0) {
|
|
5915
|
+
if (parent && index !== void 0) {
|
|
5916
|
+
parent.children.splice(index, 1);
|
|
5917
|
+
}
|
|
5918
|
+
return;
|
|
5919
|
+
}
|
|
5920
|
+
const propsName = propsNames[0];
|
|
5921
|
+
const componentProps = this.docProps.props[propsName];
|
|
5922
|
+
if (!componentProps) {
|
|
5923
|
+
if (getConfig().verbose) {
|
|
5924
|
+
console.log(` TypeDocProps not found: ${propsName}`);
|
|
5925
|
+
}
|
|
5926
|
+
if (parent && index !== void 0) {
|
|
5927
|
+
parent.children.splice(index, 1);
|
|
5928
|
+
}
|
|
5929
|
+
return;
|
|
5930
|
+
}
|
|
5931
|
+
const propsDoc = this.extractProps(componentProps, Boolean(isPartial));
|
|
5932
|
+
if (getConfig().verbose) {
|
|
5933
|
+
console.log(
|
|
5934
|
+
` Replaced TypeDocProps ${propsName} with API documentation`
|
|
5935
|
+
);
|
|
5936
|
+
}
|
|
5937
|
+
const regularProps = propsDoc.filter((p) => p.propType === void 0);
|
|
5938
|
+
const inputs = propsDoc.filter((p) => p.propType === "input");
|
|
5939
|
+
const outputs = propsDoc.filter((p) => p.propType === "output");
|
|
5940
|
+
const sections = [];
|
|
5941
|
+
if (regularProps.length > 0) {
|
|
5942
|
+
sections.push(propsToDefinitionList(regularProps));
|
|
5943
|
+
}
|
|
5944
|
+
if (inputs.length > 0) {
|
|
5945
|
+
sections.push(`**Inputs**
|
|
5946
|
+
|
|
5947
|
+
${propsToDefinitionList(inputs)}`);
|
|
5948
|
+
}
|
|
5949
|
+
if (outputs.length > 0) {
|
|
5950
|
+
sections.push(`**Outputs**
|
|
5951
|
+
|
|
5952
|
+
${propsToDefinitionList(outputs)}`);
|
|
5953
|
+
}
|
|
5954
|
+
const markdownContent = sections.join("\n\n");
|
|
5955
|
+
if (!markdownContent) {
|
|
5956
|
+
if (parent && index !== void 0) {
|
|
5957
|
+
parent.children.splice(index, 1);
|
|
5958
|
+
}
|
|
5959
|
+
return;
|
|
5960
|
+
}
|
|
5961
|
+
const propNames = propsDoc.map((p) => p.name);
|
|
5962
|
+
Object.assign(node, {
|
|
5963
|
+
data: { typeDocProps: { name: propsName, props: propNames } },
|
|
5964
|
+
lang: null,
|
|
5965
|
+
meta: null,
|
|
5966
|
+
type: "code",
|
|
5967
|
+
value: markdownContent
|
|
5968
|
+
});
|
|
5969
|
+
}
|
|
5970
|
+
);
|
|
5971
|
+
done();
|
|
5972
|
+
};
|
|
5610
5973
|
}
|
|
5611
|
-
|
|
5612
|
-
|
|
5613
|
-
|
|
5614
|
-
|
|
5615
|
-
|
|
5616
|
-
|
|
5617
|
-
|
|
5974
|
+
};
|
|
5975
|
+
|
|
5976
|
+
// src/ai-knowledge/generator/npm-install-tabs-plugin.ts
|
|
5977
|
+
import { visit as visit8 } from "unist-util-visit";
|
|
5978
|
+
var formatNpmInstallTabs = () => {
|
|
5979
|
+
return (tree, _file, done) => {
|
|
5980
|
+
visit8(
|
|
5981
|
+
tree,
|
|
5982
|
+
"mdxJsxFlowElement",
|
|
5983
|
+
(node, index, parent) => {
|
|
5984
|
+
if (node?.name === "NpmInstallTabs") {
|
|
5985
|
+
const packages = node.attributes?.find(
|
|
5986
|
+
(attr) => attr.type === "mdxJsxAttribute" && attr.name === "packages"
|
|
5987
|
+
);
|
|
5988
|
+
const packageNames = packages ? extractNamesFromAttribute(packages) : [];
|
|
5989
|
+
if (packageNames.length === 0) {
|
|
5990
|
+
if (parent && index !== void 0) {
|
|
5991
|
+
parent.children.splice(index, 1);
|
|
5992
|
+
}
|
|
5993
|
+
return;
|
|
5994
|
+
}
|
|
5995
|
+
Object.assign(node, {
|
|
5996
|
+
lang: "shell",
|
|
5997
|
+
meta: null,
|
|
5998
|
+
type: "code",
|
|
5999
|
+
value: `npm install ${packageNames.join(" ")}`
|
|
6000
|
+
});
|
|
6001
|
+
}
|
|
5618
6002
|
}
|
|
5619
6003
|
);
|
|
5620
|
-
|
|
5621
|
-
}
|
|
6004
|
+
done();
|
|
6005
|
+
};
|
|
5622
6006
|
};
|
|
5623
6007
|
|
|
5624
|
-
// src/
|
|
5625
|
-
import {
|
|
5626
|
-
function
|
|
5627
|
-
|
|
5628
|
-
|
|
5629
|
-
config({ path: options.env });
|
|
5630
|
-
} else {
|
|
5631
|
-
config();
|
|
5632
|
-
}
|
|
5633
|
-
}
|
|
5634
|
-
function getConfigFromEnv() {
|
|
5635
|
-
const openWebUiUrl = process.env.WEB_UI_URL || process.env.OPEN_WEB_UI_URL;
|
|
5636
|
-
const openWebUiKey = process.env.WEB_UI_KEY || process.env.OPEN_WEB_UI_API_KEY;
|
|
5637
|
-
const knowledgeId = process.env.KNOWLEDGE_ID || process.env.OPEN_WEB_UI_KNOWLEDGE_ID;
|
|
5638
|
-
if (!openWebUiUrl || !openWebUiKey || !knowledgeId) {
|
|
5639
|
-
throw new Error("WEB_UI_URL, WEB_UI_KEY, and KNOWLEDGE_ID must be set");
|
|
6008
|
+
// src/ai-knowledge/generator/qds-theme-plugin.ts
|
|
6009
|
+
import { visit as visit9 } from "unist-util-visit";
|
|
6010
|
+
function themeDataToJson(data, cssPropertyName) {
|
|
6011
|
+
if (!data || typeof data !== "object") {
|
|
6012
|
+
return "";
|
|
5640
6013
|
}
|
|
5641
|
-
|
|
5642
|
-
|
|
5643
|
-
webUiKey: openWebUiKey,
|
|
5644
|
-
webUiUrl: openWebUiUrl
|
|
5645
|
-
};
|
|
5646
|
-
}
|
|
5647
|
-
function loadOpenWebUiEnv(integration, integrationName) {
|
|
5648
|
-
const envFilePath = integration.envFile ?? `.env.${integration.id}`;
|
|
5649
|
-
config({ override: true, path: envFilePath });
|
|
5650
|
-
const url = process.env.OPEN_WEB_UI_URL ?? process.env.WEB_UI_URL;
|
|
5651
|
-
const apiKey = process.env.OPEN_WEB_UI_API_KEY ?? process.env.WEB_UI_KEY;
|
|
5652
|
-
const knowledgeId = process.env.OPEN_WEB_UI_KNOWLEDGE_ID ?? process.env.KNOWLEDGE_ID;
|
|
5653
|
-
if (!url) {
|
|
5654
|
-
throw new Error(
|
|
5655
|
-
`Missing OPEN_WEB_UI_URL for integration "${integrationName}" (env file: ${envFilePath})`
|
|
5656
|
-
);
|
|
6014
|
+
if (cssPropertyName) {
|
|
6015
|
+
return JSON.stringify({ cssProperty: cssPropertyName, data }, null, 2);
|
|
5657
6016
|
}
|
|
5658
|
-
|
|
5659
|
-
|
|
5660
|
-
|
|
5661
|
-
|
|
6017
|
+
return JSON.stringify(data, null, 2);
|
|
6018
|
+
}
|
|
6019
|
+
function getPath(obj, path) {
|
|
6020
|
+
return path.split(".").reduce(
|
|
6021
|
+
(acc, key) => acc && typeof acc === "object" ? acc[key] : void 0,
|
|
6022
|
+
obj
|
|
6023
|
+
);
|
|
6024
|
+
}
|
|
6025
|
+
function getAttrExpression(node, name) {
|
|
6026
|
+
const attr = node.attributes?.find(
|
|
6027
|
+
(a) => a.type === "mdxJsxAttribute" && a.name === name
|
|
6028
|
+
);
|
|
6029
|
+
if (!attr?.value) {
|
|
6030
|
+
return null;
|
|
5662
6031
|
}
|
|
5663
|
-
if (
|
|
5664
|
-
|
|
5665
|
-
|
|
5666
|
-
|
|
6032
|
+
if (typeof attr.value === "string") {
|
|
6033
|
+
return attr.value;
|
|
6034
|
+
} else if (typeof attr.value === "object" && "value" in attr.value) {
|
|
6035
|
+
return attr.value.value;
|
|
5667
6036
|
}
|
|
5668
|
-
return
|
|
6037
|
+
return null;
|
|
5669
6038
|
}
|
|
5670
|
-
function
|
|
5671
|
-
|
|
5672
|
-
|
|
5673
|
-
|
|
5674
|
-
|
|
5675
|
-
|
|
5676
|
-
|
|
5677
|
-
|
|
5678
|
-
|
|
6039
|
+
async function formatThemeNodes() {
|
|
6040
|
+
let themes = null;
|
|
6041
|
+
try {
|
|
6042
|
+
themes = await import("@qualcomm-ui/tailwind-plugin/theme");
|
|
6043
|
+
} catch {
|
|
6044
|
+
return () => {
|
|
6045
|
+
};
|
|
6046
|
+
}
|
|
6047
|
+
const handlers = {
|
|
6048
|
+
ColorTable: (node) => {
|
|
6049
|
+
const path = getAttrExpression(node, "data");
|
|
6050
|
+
return path && getPath(themes, path);
|
|
6051
|
+
},
|
|
6052
|
+
FontTable: (node) => {
|
|
6053
|
+
const path = getAttrExpression(node, "data");
|
|
6054
|
+
return path && getPath(themes, path);
|
|
6055
|
+
},
|
|
6056
|
+
SpacingTable: (node) => {
|
|
6057
|
+
const path = getAttrExpression(node, "data");
|
|
6058
|
+
return path && getPath(themes, path);
|
|
6059
|
+
},
|
|
6060
|
+
ThemePropertyTable: (node) => {
|
|
6061
|
+
const path = getAttrExpression(node, "data");
|
|
6062
|
+
const property = getAttrExpression(node, "cssProperty");
|
|
6063
|
+
const data = path && getPath(themes, path);
|
|
6064
|
+
return path && property ? { cssPropertyName: property, data } : void 0;
|
|
6065
|
+
}
|
|
5679
6066
|
};
|
|
5680
|
-
|
|
5681
|
-
|
|
5682
|
-
|
|
5683
|
-
|
|
5684
|
-
|
|
5685
|
-
loadEnv();
|
|
5686
|
-
const env = opts.environment;
|
|
5687
|
-
dotenv.config({ path: `.env.${env}` });
|
|
5688
|
-
await mkdir(opts.outputDir, { recursive: true }).catch();
|
|
5689
|
-
const config2 = getConfigFromEnv();
|
|
5690
|
-
const apiConfig = { apiKey: config2.webUiKey, baseUrl: config2.webUiUrl };
|
|
5691
|
-
const knowledgeApi = new KnowledgeApi(apiConfig);
|
|
5692
|
-
const filesApi = new FilesApi(apiConfig);
|
|
5693
|
-
const knowledge = await knowledgeApi.getById(config2.knowledgeId);
|
|
5694
|
-
for (const file of knowledge.files ?? []) {
|
|
5695
|
-
const fileName = file.meta?.name;
|
|
5696
|
-
if (!fileName) {
|
|
5697
|
-
continue;
|
|
6067
|
+
return () => (tree, _file, done) => {
|
|
6068
|
+
visit9(tree, "mdxJsxFlowElement", (node) => {
|
|
6069
|
+
const handler = node.name && handlers[node.name];
|
|
6070
|
+
if (!handler) {
|
|
6071
|
+
return;
|
|
5698
6072
|
}
|
|
5699
|
-
|
|
5700
|
-
|
|
5701
|
-
|
|
5702
|
-
|
|
5703
|
-
resolve2(opts.outputDir, fileName),
|
|
5704
|
-
content.content,
|
|
5705
|
-
"utf-8"
|
|
5706
|
-
);
|
|
5707
|
-
}
|
|
5708
|
-
} catch {
|
|
5709
|
-
console.warn(`Failed to download ${fileName}`);
|
|
6073
|
+
const data = handler(node);
|
|
6074
|
+
if (!data) {
|
|
6075
|
+
console.warn(`No theme data for ${node.name}`);
|
|
6076
|
+
return;
|
|
5710
6077
|
}
|
|
5711
|
-
|
|
5712
|
-
|
|
6078
|
+
let markdownTable;
|
|
6079
|
+
if (typeof data === "object" && data !== null && "cssPropertyName" in data && "data" in data) {
|
|
6080
|
+
const { cssPropertyName, data: themeData } = data;
|
|
6081
|
+
markdownTable = themeDataToJson(themeData, cssPropertyName);
|
|
6082
|
+
} else {
|
|
6083
|
+
markdownTable = themeDataToJson(data);
|
|
6084
|
+
}
|
|
6085
|
+
if (!markdownTable) {
|
|
6086
|
+
return;
|
|
6087
|
+
}
|
|
6088
|
+
Object.assign(node, {
|
|
6089
|
+
lang: "json",
|
|
6090
|
+
meta: null,
|
|
6091
|
+
type: "code",
|
|
6092
|
+
value: markdownTable
|
|
6093
|
+
});
|
|
6094
|
+
});
|
|
6095
|
+
done();
|
|
6096
|
+
};
|
|
5713
6097
|
}
|
|
5714
6098
|
|
|
5715
|
-
// src/
|
|
5716
|
-
import AdmZip from "adm-zip";
|
|
5717
|
-
import chalk3 from "chalk";
|
|
5718
|
-
import { minimatch } from "minimatch";
|
|
5719
|
-
import { createHash as createHash2 } from "node:crypto";
|
|
5720
|
-
import {
|
|
5721
|
-
access,
|
|
5722
|
-
mkdir as mkdir2,
|
|
5723
|
-
readdir,
|
|
5724
|
-
readFile,
|
|
5725
|
-
rm,
|
|
5726
|
-
stat,
|
|
5727
|
-
writeFile as writeFile3
|
|
5728
|
-
} from "node:fs/promises";
|
|
5729
|
-
import { basename, dirname, extname, join as join3, relative as relative2, resolve as resolve4 } from "node:path";
|
|
5730
|
-
import remarkFrontmatter2 from "remark-frontmatter";
|
|
5731
|
-
import remarkMdx3 from "remark-mdx";
|
|
5732
|
-
import remarkParse4 from "remark-parse";
|
|
5733
|
-
import remarkParseFrontmatter2 from "remark-parse-frontmatter";
|
|
6099
|
+
// src/ai-knowledge/generator/section-extractor.ts
|
|
5734
6100
|
import remarkStringify3 from "remark-stringify";
|
|
5735
6101
|
import { unified as unified4 } from "unified";
|
|
5736
|
-
import { visit as
|
|
5737
|
-
import { kebabCase } from "@qualcomm-ui/utils/change-case";
|
|
5738
|
-
|
|
5739
|
-
|
|
5740
|
-
|
|
5741
|
-
|
|
5742
|
-
|
|
5743
|
-
|
|
5744
|
-
|
|
6102
|
+
import { visit as visit10 } from "unist-util-visit";
|
|
6103
|
+
import { kebabCase as kebabCase2 } from "@qualcomm-ui/utils/change-case";
|
|
6104
|
+
var SectionExtractor = class {
|
|
6105
|
+
depths;
|
|
6106
|
+
minContentLength;
|
|
6107
|
+
constructor(options) {
|
|
6108
|
+
const defaultDepths = [1, 2, 3, 4];
|
|
6109
|
+
this.depths = new Set(options?.depths ?? defaultDepths);
|
|
6110
|
+
this.minContentLength = options?.minContentLength ?? 0;
|
|
5745
6111
|
}
|
|
5746
|
-
|
|
5747
|
-
|
|
5748
|
-
|
|
5749
|
-
|
|
5750
|
-
|
|
5751
|
-
|
|
5752
|
-
|
|
5753
|
-
|
|
5754
|
-
|
|
5755
|
-
|
|
6112
|
+
/**
|
|
6113
|
+
* Extracts sections from a parsed AST.
|
|
6114
|
+
*/
|
|
6115
|
+
extract(tree, pageInfo) {
|
|
6116
|
+
const sections = [];
|
|
6117
|
+
const headerStack = [{ depth: 1, text: pageInfo.title }];
|
|
6118
|
+
let pendingSection = null;
|
|
6119
|
+
const finalizeSection = () => {
|
|
6120
|
+
if (!pendingSection || pendingSection.nodes.length === 0) {
|
|
6121
|
+
return;
|
|
6122
|
+
}
|
|
6123
|
+
const entry = this.buildSectionEntry(pendingSection, pageInfo);
|
|
6124
|
+
if (entry && entry.content.length >= this.minContentLength) {
|
|
6125
|
+
sections.push(entry);
|
|
6126
|
+
}
|
|
6127
|
+
};
|
|
6128
|
+
for (let i = 0; i < tree.children.length; i++) {
|
|
6129
|
+
const node = tree.children[i];
|
|
6130
|
+
if (node.type === "heading") {
|
|
6131
|
+
const heading = node;
|
|
6132
|
+
if (!this.depths.has(heading.depth)) {
|
|
6133
|
+
if (pendingSection) {
|
|
6134
|
+
pendingSection.nodes.push(node);
|
|
6135
|
+
}
|
|
6136
|
+
continue;
|
|
6137
|
+
}
|
|
6138
|
+
finalizeSection();
|
|
6139
|
+
while (headerStack.length > 0 && headerStack[headerStack.length - 1].depth >= heading.depth) {
|
|
6140
|
+
headerStack.pop();
|
|
6141
|
+
}
|
|
6142
|
+
const headingText = this.getHeadingText(heading);
|
|
6143
|
+
headerStack.push({ depth: heading.depth, text: headingText });
|
|
6144
|
+
pendingSection = {
|
|
6145
|
+
headerPath: headerStack.map((h) => h.text),
|
|
6146
|
+
nodes: [],
|
|
6147
|
+
startIndex: i
|
|
6148
|
+
};
|
|
6149
|
+
} else if (pendingSection) {
|
|
6150
|
+
pendingSection.nodes.push(node);
|
|
6151
|
+
}
|
|
6152
|
+
}
|
|
6153
|
+
finalizeSection();
|
|
6154
|
+
return sections;
|
|
5756
6155
|
}
|
|
5757
|
-
|
|
5758
|
-
|
|
5759
|
-
|
|
5760
|
-
|
|
5761
|
-
|
|
5762
|
-
|
|
6156
|
+
getHeadingText(heading) {
|
|
6157
|
+
let text = "";
|
|
6158
|
+
visit10(heading, "text", (node) => {
|
|
6159
|
+
text += node.value;
|
|
6160
|
+
});
|
|
6161
|
+
return text.trim();
|
|
5763
6162
|
}
|
|
5764
|
-
|
|
5765
|
-
|
|
5766
|
-
|
|
5767
|
-
|
|
5768
|
-
|
|
5769
|
-
|
|
5770
|
-
|
|
5771
|
-
|
|
5772
|
-
|
|
5773
|
-
|
|
5774
|
-
|
|
5775
|
-
|
|
5776
|
-
|
|
5777
|
-
|
|
5778
|
-
}
|
|
5779
|
-
|
|
5780
|
-
|
|
5781
|
-
|
|
5782
|
-
|
|
5783
|
-
|
|
5784
|
-
|
|
5785
|
-
|
|
5786
|
-
}
|
|
5787
|
-
|
|
5788
|
-
|
|
5789
|
-
|
|
5790
|
-
|
|
5791
|
-
|
|
5792
|
-
|
|
5793
|
-
|
|
5794
|
-
|
|
5795
|
-
|
|
5796
|
-
|
|
5797
|
-
|
|
5798
|
-
|
|
6163
|
+
buildSectionEntry(section, pageInfo) {
|
|
6164
|
+
const { metadata, nodes } = this.extractMetadata(section.nodes);
|
|
6165
|
+
if (nodes.length === 0) {
|
|
6166
|
+
return null;
|
|
6167
|
+
}
|
|
6168
|
+
const contentNodes = [];
|
|
6169
|
+
const codeExamples = [];
|
|
6170
|
+
for (const node of nodes) {
|
|
6171
|
+
if (node.type === "code") {
|
|
6172
|
+
const codeNode = node;
|
|
6173
|
+
if (codeNode.data?.typeDocProps) {
|
|
6174
|
+
const { name, props } = codeNode.data.typeDocProps;
|
|
6175
|
+
metadata.props = [...metadata.props ?? [], ...props];
|
|
6176
|
+
metadata.type = name;
|
|
6177
|
+
}
|
|
6178
|
+
codeExamples.push({
|
|
6179
|
+
code: codeNode.value,
|
|
6180
|
+
language: codeNode.lang ?? ""
|
|
6181
|
+
});
|
|
6182
|
+
} else {
|
|
6183
|
+
contentNodes.push(node);
|
|
6184
|
+
}
|
|
6185
|
+
}
|
|
6186
|
+
const rawContent = this.nodesToRawContent(nodes);
|
|
6187
|
+
const content = this.nodesToContent(contentNodes);
|
|
6188
|
+
const sectionId = this.generateSectionId(section.headerPath);
|
|
6189
|
+
const url = pageInfo.url ? `${pageInfo.url}#${this.generateAnchorId(section.headerPath.at(-1) ?? "")}` : void 0;
|
|
6190
|
+
const hashData = {
|
|
6191
|
+
headerPath: section.headerPath,
|
|
6192
|
+
metadata: Object.keys(metadata).length ? metadata : void 0,
|
|
6193
|
+
pageFrontmatter: Object.keys(pageInfo.frontmatter).length ? pageInfo.frontmatter : void 0,
|
|
6194
|
+
pageId: pageInfo.id,
|
|
6195
|
+
rawContent: rawContent.trim()
|
|
6196
|
+
};
|
|
6197
|
+
const sectionHash = JSON.stringify(hashData);
|
|
6198
|
+
return {
|
|
6199
|
+
...hashData,
|
|
6200
|
+
codeExamples: codeExamples.length ? codeExamples : void 0,
|
|
6201
|
+
content: content.trim(),
|
|
6202
|
+
hash: sectionHash,
|
|
6203
|
+
sectionId,
|
|
6204
|
+
url
|
|
6205
|
+
};
|
|
5799
6206
|
}
|
|
5800
|
-
|
|
5801
|
-
const
|
|
5802
|
-
|
|
5803
|
-
)
|
|
5804
|
-
|
|
6207
|
+
extractMetadata(nodes) {
|
|
6208
|
+
const metadata = {};
|
|
6209
|
+
const filteredNodes = [];
|
|
6210
|
+
for (const node of nodes) {
|
|
6211
|
+
if (node.type === "paragraph") {
|
|
6212
|
+
const firstChild = node.children?.[0];
|
|
6213
|
+
if (firstChild?.type === "text") {
|
|
6214
|
+
const text = firstChild.value;
|
|
6215
|
+
const metaMatch = text.match(/^:::\s*meta\s*/);
|
|
6216
|
+
if (metaMatch) {
|
|
6217
|
+
const parsed = this.parseMetaBlock(text);
|
|
6218
|
+
Object.assign(metadata, parsed);
|
|
6219
|
+
continue;
|
|
6220
|
+
}
|
|
6221
|
+
}
|
|
6222
|
+
}
|
|
6223
|
+
filteredNodes.push(node);
|
|
6224
|
+
}
|
|
6225
|
+
return { metadata, nodes: filteredNodes };
|
|
5805
6226
|
}
|
|
5806
|
-
|
|
5807
|
-
|
|
5808
|
-
const
|
|
5809
|
-
|
|
6227
|
+
parseMetaBlock(text) {
|
|
6228
|
+
const metadata = {};
|
|
6229
|
+
const afterOpen = text.replace(/^:::\s*meta\s*/, "");
|
|
6230
|
+
const closeIndex = afterOpen.lastIndexOf(":::");
|
|
6231
|
+
const content = closeIndex !== -1 ? afterOpen.slice(0, closeIndex) : afterOpen;
|
|
6232
|
+
const lines = content.split("\n");
|
|
6233
|
+
for (const line of lines) {
|
|
6234
|
+
const trimmed = line.trim();
|
|
6235
|
+
if (!trimmed) {
|
|
6236
|
+
continue;
|
|
6237
|
+
}
|
|
6238
|
+
const colonIndex = trimmed.indexOf(":");
|
|
6239
|
+
if (colonIndex === -1) {
|
|
6240
|
+
continue;
|
|
6241
|
+
}
|
|
6242
|
+
const key = trimmed.slice(0, colonIndex).trim();
|
|
6243
|
+
const value = trimmed.slice(colonIndex + 1).trim();
|
|
6244
|
+
if (key && value) {
|
|
6245
|
+
metadata[key] = this.parseValue(value);
|
|
6246
|
+
}
|
|
6247
|
+
}
|
|
6248
|
+
return metadata;
|
|
5810
6249
|
}
|
|
5811
|
-
|
|
5812
|
-
|
|
5813
|
-
|
|
5814
|
-
|
|
6250
|
+
parseValue(value) {
|
|
6251
|
+
const trimmed = value.trim();
|
|
6252
|
+
if (trimmed.startsWith("[") && trimmed.endsWith("]")) {
|
|
6253
|
+
const inner = trimmed.slice(1, -1);
|
|
6254
|
+
return inner.split(",").map((item) => item.trim()).filter(Boolean);
|
|
6255
|
+
}
|
|
6256
|
+
return trimmed;
|
|
5815
6257
|
}
|
|
5816
|
-
|
|
5817
|
-
|
|
5818
|
-
|
|
5819
|
-
|
|
5820
|
-
|
|
5821
|
-
return {
|
|
5822
|
-
|
|
5823
|
-
|
|
5824
|
-
|
|
5825
|
-
|
|
5826
|
-
|
|
5827
|
-
|
|
5828
|
-
|
|
5829
|
-
|
|
5830
|
-
|
|
5831
|
-
|
|
5832
|
-
|
|
5833
|
-
|
|
6258
|
+
/**
|
|
6259
|
+
* Convert links to inline code. URLs are not relevant for text embeddings
|
|
6260
|
+
* and will muddy the vector storage.
|
|
6261
|
+
*/
|
|
6262
|
+
transformLinks() {
|
|
6263
|
+
return () => (tree) => {
|
|
6264
|
+
visit10(tree, "link", (node) => {
|
|
6265
|
+
let text = "";
|
|
6266
|
+
visit10(node, "text", (textNode) => {
|
|
6267
|
+
text += textNode.value;
|
|
6268
|
+
});
|
|
6269
|
+
Object.assign(node, {
|
|
6270
|
+
children: void 0,
|
|
6271
|
+
type: "inlineCode",
|
|
6272
|
+
url: void 0,
|
|
6273
|
+
value: text
|
|
6274
|
+
});
|
|
6275
|
+
});
|
|
5834
6276
|
};
|
|
5835
|
-
});
|
|
5836
|
-
}
|
|
5837
|
-
function loadOpenWebUiIntegrations(options = {}) {
|
|
5838
|
-
const configLoader = new ConfigLoader({});
|
|
5839
|
-
const resolvedConfig = configLoader.loadConfig();
|
|
5840
|
-
const knowledgeConfig = resolvedConfig.knowledge;
|
|
5841
|
-
const environments = knowledgeConfig?.environments;
|
|
5842
|
-
const integrations = knowledgeConfig?.integrations?.openWebUi;
|
|
5843
|
-
if (!integrations || integrations.length === 0) {
|
|
5844
|
-
return [];
|
|
5845
6277
|
}
|
|
5846
|
-
|
|
5847
|
-
|
|
5848
|
-
const
|
|
5849
|
-
|
|
5850
|
-
(integration) => filterSet.has(integration.id)
|
|
5851
|
-
);
|
|
6278
|
+
nodesToRawContent(nodes) {
|
|
6279
|
+
const tree = { children: nodes, type: "root" };
|
|
6280
|
+
const processor = unified4().use(remarkStringify3);
|
|
6281
|
+
return processor.stringify(tree);
|
|
5852
6282
|
}
|
|
5853
|
-
|
|
5854
|
-
const
|
|
5855
|
-
|
|
5856
|
-
|
|
5857
|
-
);
|
|
6283
|
+
nodesToContent(nodes) {
|
|
6284
|
+
const tree = { children: structuredClone(nodes), type: "root" };
|
|
6285
|
+
const processor = unified4().use(this.transformLinks()).use(remarkStringify3);
|
|
6286
|
+
const transformed = processor.runSync(tree);
|
|
6287
|
+
return processor.stringify(transformed);
|
|
5858
6288
|
}
|
|
5859
|
-
|
|
5860
|
-
|
|
5861
|
-
if (!envConfig) {
|
|
5862
|
-
throw new Error(
|
|
5863
|
-
`Integration "${integration.id}" references unknown environment "${integration.id}". Available environments: ${environments?.map((e) => e.id).join(", ") || "none"}`
|
|
5864
|
-
);
|
|
5865
|
-
}
|
|
5866
|
-
return {
|
|
5867
|
-
integration,
|
|
5868
|
-
name: integration.id,
|
|
5869
|
-
outputPath: envConfig.outputPath
|
|
5870
|
-
};
|
|
5871
|
-
});
|
|
5872
|
-
}
|
|
5873
|
-
|
|
5874
|
-
// src/open-web-ui-knowledge/generate-knowledge.ts
|
|
5875
|
-
async function exists(dirPath) {
|
|
5876
|
-
return access(dirPath).then(() => true).catch(() => false);
|
|
5877
|
-
}
|
|
5878
|
-
function computeMd5(content) {
|
|
5879
|
-
return createHash2("md5").update(content).digest("hex");
|
|
5880
|
-
}
|
|
5881
|
-
function extractBestType(propInfo) {
|
|
5882
|
-
const type = propInfo.resolvedType?.prettyType || propInfo.type;
|
|
5883
|
-
return cleanType(type.startsWith("| ") ? type.substring(2) : type);
|
|
5884
|
-
}
|
|
5885
|
-
function extractRequired(propInfo, isPartial) {
|
|
5886
|
-
return Boolean(propInfo.resolvedType?.required && !isPartial);
|
|
5887
|
-
}
|
|
5888
|
-
function cleanType(type) {
|
|
5889
|
-
return type.replace(/\n/g, " ").replace(/\s+/g, " ").trim();
|
|
5890
|
-
}
|
|
5891
|
-
function cleanDefaultValue(defaultValue) {
|
|
5892
|
-
return defaultValue.replace(/^\n+/, "").replace(/\n+$/, "").trim();
|
|
5893
|
-
}
|
|
5894
|
-
function isPreviewLine(trimmedLine) {
|
|
5895
|
-
return trimmedLine === "// preview" || /^\{\s*\/\*\s*preview\s*\*\/\s*\}$/.test(trimmedLine) || /^<!--\s*preview\s*-->$/.test(trimmedLine);
|
|
5896
|
-
}
|
|
5897
|
-
function removePreviewLines(code) {
|
|
5898
|
-
return code.split("\n").filter((line) => !isPreviewLine(line.trim())).join("\n");
|
|
5899
|
-
}
|
|
5900
|
-
function getIntroLines(projectName, description) {
|
|
5901
|
-
const lines = [];
|
|
5902
|
-
if (projectName) {
|
|
5903
|
-
lines.push(`# ${projectName}`);
|
|
5904
|
-
}
|
|
5905
|
-
if (description) {
|
|
5906
|
-
lines.push("");
|
|
5907
|
-
lines.push(`> ${description}`);
|
|
5908
|
-
}
|
|
5909
|
-
return lines.join("\n");
|
|
5910
|
-
}
|
|
5911
|
-
function extractRelativeImports(content) {
|
|
5912
|
-
const imports = [];
|
|
5913
|
-
const importRegex = /^import\s+(?:{[^}]*}|[\w*]+|\*\s+as\s+\w+)?\s*(?:,\s*{[^}]*})?\s*from\s+["'](\.[^"']+)["']/gm;
|
|
5914
|
-
let match;
|
|
5915
|
-
while ((match = importRegex.exec(content)) !== null) {
|
|
5916
|
-
imports.push(match[1]);
|
|
5917
|
-
}
|
|
5918
|
-
return imports;
|
|
5919
|
-
}
|
|
5920
|
-
async function resolveModulePath(importPath, fromFile) {
|
|
5921
|
-
const fromDir = dirname(fromFile);
|
|
5922
|
-
const baseResolved = resolve4(fromDir, importPath);
|
|
5923
|
-
const extensions = [".ts", ".tsx", ".js", ".jsx", ""];
|
|
5924
|
-
for (const ext of extensions) {
|
|
5925
|
-
const fullPath = baseResolved + ext;
|
|
5926
|
-
if (await exists(fullPath)) {
|
|
5927
|
-
return fullPath;
|
|
5928
|
-
}
|
|
6289
|
+
generateSectionId(headerPath) {
|
|
6290
|
+
return headerPath.map((h) => kebabCase2(h)).join("-");
|
|
5929
6291
|
}
|
|
5930
|
-
|
|
5931
|
-
|
|
5932
|
-
if (await exists(indexPath)) {
|
|
5933
|
-
return indexPath;
|
|
5934
|
-
}
|
|
6292
|
+
generateAnchorId(headerText) {
|
|
6293
|
+
return kebabCase2(headerText);
|
|
5935
6294
|
}
|
|
5936
|
-
return null;
|
|
5937
|
-
}
|
|
5938
|
-
function extractMetadata(metadata) {
|
|
5939
|
-
return Object.entries(metadata ?? {});
|
|
5940
|
-
}
|
|
5941
|
-
var replaceNpmInstallTabs = () => {
|
|
5942
|
-
return (tree, _file, done) => {
|
|
5943
|
-
visit5(tree, "mdxJsxFlowElement", (node) => {
|
|
5944
|
-
if (node?.name === "NpmInstallTabs") {
|
|
5945
|
-
const packages = node.attributes?.find(
|
|
5946
|
-
(attr) => attr.type === "mdxJsxAttribute" && attr.name === "packages"
|
|
5947
|
-
);
|
|
5948
|
-
const packageNames = packages ? extractNamesFromAttribute(packages) : [];
|
|
5949
|
-
Object.assign(node, {
|
|
5950
|
-
lang: "shell",
|
|
5951
|
-
meta: null,
|
|
5952
|
-
type: "code",
|
|
5953
|
-
value: `npm install ${packageNames.join(" ")}`
|
|
5954
|
-
});
|
|
5955
|
-
}
|
|
5956
|
-
});
|
|
5957
|
-
done();
|
|
5958
|
-
};
|
|
5959
6295
|
};
|
|
5960
|
-
|
|
5961
|
-
|
|
5962
|
-
(acc, key) => acc && typeof acc === "object" ? acc[key] : void 0,
|
|
5963
|
-
obj
|
|
5964
|
-
);
|
|
5965
|
-
}
|
|
5966
|
-
function escapeText(value) {
|
|
5967
|
-
return value.replace(/\n/g, " ");
|
|
5968
|
-
}
|
|
5969
|
-
function propsToDefinitionList(props) {
|
|
5970
|
-
if (props.length === 0) {
|
|
5971
|
-
return "";
|
|
5972
|
-
}
|
|
5973
|
-
return props.map((prop) => {
|
|
5974
|
-
const parts = [`- **${prop.name}** (\`${escapeText(prop.type)}\``];
|
|
5975
|
-
if (prop.defaultValue) {
|
|
5976
|
-
parts.push(`, default: \`${escapeText(prop.defaultValue)}\``);
|
|
5977
|
-
}
|
|
5978
|
-
if (prop.required) {
|
|
5979
|
-
parts.push(", required");
|
|
5980
|
-
}
|
|
5981
|
-
parts.push(")");
|
|
5982
|
-
if (prop.description) {
|
|
5983
|
-
parts.push(` - ${escapeText(prop.description)}`);
|
|
5984
|
-
}
|
|
5985
|
-
return parts.join("");
|
|
5986
|
-
}).join("\n");
|
|
5987
|
-
}
|
|
5988
|
-
function themeDataToJson(data, cssPropertyName) {
|
|
5989
|
-
if (!data || typeof data !== "object") {
|
|
5990
|
-
return "";
|
|
5991
|
-
}
|
|
5992
|
-
if (cssPropertyName) {
|
|
5993
|
-
return JSON.stringify({ cssProperty: cssPropertyName, data }, null, 2);
|
|
5994
|
-
}
|
|
5995
|
-
return JSON.stringify(data, null, 2);
|
|
5996
|
-
}
|
|
6296
|
+
|
|
6297
|
+
// src/ai-knowledge/generator/knowledge-generator.ts
|
|
5997
6298
|
var KnowledgeGenerator = class {
|
|
5998
6299
|
config;
|
|
5999
|
-
|
|
6000
|
-
constructor(
|
|
6001
|
-
|
|
6300
|
+
propFormatter;
|
|
6301
|
+
constructor(config3) {
|
|
6302
|
+
setConfig(config3);
|
|
6303
|
+
this.config = getConfig();
|
|
6304
|
+
this.propFormatter = new PropFormatter();
|
|
6002
6305
|
}
|
|
6003
6306
|
async run() {
|
|
6004
6307
|
const extractedMetadata = extractMetadata(this.config.metadata);
|
|
@@ -6008,11 +6311,10 @@ var KnowledgeGenerator = class {
|
|
|
6008
6311
|
console.log(`Excluding patterns: ${this.config.exclude.join(", ")}`);
|
|
6009
6312
|
}
|
|
6010
6313
|
}
|
|
6011
|
-
const [
|
|
6012
|
-
this.
|
|
6013
|
-
this.
|
|
6314
|
+
const [pages] = await Promise.all([
|
|
6315
|
+
this.scanPages(),
|
|
6316
|
+
this.propFormatter.loadDocProps()
|
|
6014
6317
|
]);
|
|
6015
|
-
this.docProps = docProps;
|
|
6016
6318
|
if (pages.length === 0) {
|
|
6017
6319
|
console.log("No pages found.");
|
|
6018
6320
|
return [];
|
|
@@ -6039,7 +6341,7 @@ var KnowledgeGenerator = class {
|
|
|
6039
6341
|
if (this.config.outputMode === "aggregated") {
|
|
6040
6342
|
await this.generateAggregatedOutput(processedPages, pages);
|
|
6041
6343
|
} else {
|
|
6042
|
-
await
|
|
6344
|
+
await mkdir(this.config.outputPath, { recursive: true }).catch(() => {
|
|
6043
6345
|
});
|
|
6044
6346
|
await this.generatePerPageExports(
|
|
6045
6347
|
pages,
|
|
@@ -6049,31 +6351,6 @@ var KnowledgeGenerator = class {
|
|
|
6049
6351
|
}
|
|
6050
6352
|
return pages;
|
|
6051
6353
|
}
|
|
6052
|
-
async loadDocProps() {
|
|
6053
|
-
const resolvedDocPropsPath = this.config.docPropsPath ? await exists(this.config.docPropsPath) ? this.config.docPropsPath : resolve4(process.cwd(), this.config.docPropsPath) : join3(dirname(this.config.routeDir), "doc-props.json");
|
|
6054
|
-
if (!await exists(resolvedDocPropsPath)) {
|
|
6055
|
-
if (this.config.verbose) {
|
|
6056
|
-
console.log(`Doc props file not found at: ${resolvedDocPropsPath}`);
|
|
6057
|
-
}
|
|
6058
|
-
return null;
|
|
6059
|
-
}
|
|
6060
|
-
try {
|
|
6061
|
-
const content = await readFile(resolvedDocPropsPath, "utf-8");
|
|
6062
|
-
const docProps = JSON.parse(content);
|
|
6063
|
-
if (this.config.verbose) {
|
|
6064
|
-
console.log(`Loaded doc props from: ${resolvedDocPropsPath}`);
|
|
6065
|
-
console.log(
|
|
6066
|
-
`Found ${Object.keys(docProps.props).length} component types`
|
|
6067
|
-
);
|
|
6068
|
-
}
|
|
6069
|
-
return docProps;
|
|
6070
|
-
} catch (error) {
|
|
6071
|
-
if (this.config.verbose) {
|
|
6072
|
-
console.log("Error loading doc props", error);
|
|
6073
|
-
}
|
|
6074
|
-
return null;
|
|
6075
|
-
}
|
|
6076
|
-
}
|
|
6077
6354
|
async scanPages() {
|
|
6078
6355
|
const components = [];
|
|
6079
6356
|
const excludePatterns = this.config.exclude ?? [];
|
|
@@ -6097,14 +6374,14 @@ var KnowledgeGenerator = class {
|
|
|
6097
6374
|
}
|
|
6098
6375
|
const entries = await readdir(dirPath, { withFileTypes: true });
|
|
6099
6376
|
const mdxFiles = entries.filter(
|
|
6100
|
-
(f) => f.name.endsWith(".mdx") && !shouldExclude(
|
|
6377
|
+
(f) => f.name.endsWith(".mdx") && !shouldExclude(join6(dirPath, f.name))
|
|
6101
6378
|
) ?? [];
|
|
6102
6379
|
const pageIdPrefix = this.config.pageIdPrefix ?? "";
|
|
6103
6380
|
for (const mdxFile of mdxFiles) {
|
|
6104
6381
|
const demosFolder = entries.find((f) => f.name === "demos");
|
|
6105
|
-
const demosFolderPath = demosFolder ?
|
|
6382
|
+
const demosFolderPath = demosFolder ? join6(dirPath, demosFolder.name) : void 0;
|
|
6106
6383
|
const segments = getPathSegmentsFromFileName(
|
|
6107
|
-
|
|
6384
|
+
join6(dirPath, mdxFile.name),
|
|
6108
6385
|
this.config.routeDir
|
|
6109
6386
|
);
|
|
6110
6387
|
const url = getPathnameFromPathSegments(segments);
|
|
@@ -6112,18 +6389,18 @@ var KnowledgeGenerator = class {
|
|
|
6112
6389
|
demosFolder: demosFolderPath,
|
|
6113
6390
|
filePath: dirPath,
|
|
6114
6391
|
id: `${pageIdPrefix ? `${pageIdPrefix}-` : ""}${segments.join("-").trim()}`,
|
|
6115
|
-
mdxFile:
|
|
6392
|
+
mdxFile: join6(dirPath, mdxFile.name),
|
|
6116
6393
|
name: segments.at(-1),
|
|
6117
6394
|
pathname: url,
|
|
6118
6395
|
url: this.config.baseUrl ? new URL(url, this.config.baseUrl).toString() : void 0
|
|
6119
6396
|
});
|
|
6120
6397
|
if (this.config.verbose) {
|
|
6121
|
-
console.log(`Found file: ${
|
|
6398
|
+
console.log(`Found file: ${basename2(dirPath)}`);
|
|
6122
6399
|
console.log(` Demos folder: ${demosFolderPath || "NOT FOUND"}`);
|
|
6123
6400
|
}
|
|
6124
6401
|
}
|
|
6125
6402
|
for (const entry of entries) {
|
|
6126
|
-
const fullPath =
|
|
6403
|
+
const fullPath = join6(dirPath, entry.name);
|
|
6127
6404
|
const stats = await stat(fullPath);
|
|
6128
6405
|
if (stats.isDirectory()) {
|
|
6129
6406
|
await scanDirectory(fullPath);
|
|
@@ -6133,807 +6410,892 @@ var KnowledgeGenerator = class {
|
|
|
6133
6410
|
await scanDirectory(this.config.routeDir);
|
|
6134
6411
|
return components;
|
|
6135
6412
|
}
|
|
6136
|
-
|
|
6137
|
-
|
|
6138
|
-
|
|
6139
|
-
|
|
6140
|
-
|
|
6141
|
-
|
|
6142
|
-
|
|
6143
|
-
|
|
6144
|
-
|
|
6145
|
-
|
|
6146
|
-
|
|
6147
|
-
|
|
6148
|
-
|
|
6149
|
-
|
|
6150
|
-
|
|
6151
|
-
|
|
6152
|
-
);
|
|
6413
|
+
formatFrontmatterExpressions(frontmatter) {
|
|
6414
|
+
return () => (tree) => {
|
|
6415
|
+
visit11(
|
|
6416
|
+
tree,
|
|
6417
|
+
"mdxFlowExpression",
|
|
6418
|
+
(node, index, parent) => {
|
|
6419
|
+
if (node.value.trim() !== "frontmatter.description" || index === void 0 || !parent) {
|
|
6420
|
+
return;
|
|
6421
|
+
}
|
|
6422
|
+
if (frontmatter.description) {
|
|
6423
|
+
parent.children.splice(index, 1, {
|
|
6424
|
+
children: [{ type: "text", value: frontmatter.description }],
|
|
6425
|
+
type: "paragraph"
|
|
6426
|
+
});
|
|
6427
|
+
} else {
|
|
6428
|
+
parent.children.splice(index, 1);
|
|
6153
6429
|
}
|
|
6154
|
-
continue;
|
|
6155
6430
|
}
|
|
6156
|
-
|
|
6157
|
-
|
|
6158
|
-
|
|
6159
|
-
|
|
6160
|
-
|
|
6161
|
-
|
|
6162
|
-
|
|
6163
|
-
|
|
6431
|
+
);
|
|
6432
|
+
const root = tree;
|
|
6433
|
+
const h1Index = root.children.findIndex((node) => {
|
|
6434
|
+
if (node.type !== "heading" || node.depth !== 1) {
|
|
6435
|
+
return false;
|
|
6436
|
+
}
|
|
6437
|
+
return node.children?.some(
|
|
6438
|
+
(child) => child.type === "mdxTextExpression" && child.value?.includes("frontmatter")
|
|
6164
6439
|
);
|
|
6165
|
-
|
|
6440
|
+
});
|
|
6441
|
+
if (h1Index >= 0) {
|
|
6442
|
+
root.children.splice(h1Index, 1);
|
|
6166
6443
|
}
|
|
6167
|
-
}
|
|
6168
|
-
|
|
6169
|
-
|
|
6444
|
+
};
|
|
6445
|
+
}
|
|
6446
|
+
/**
|
|
6447
|
+
* Creates a remark plugin that transforms relative URLs to absolute URLs.
|
|
6448
|
+
*/
|
|
6449
|
+
transformRelativeUrls(pageUrl) {
|
|
6450
|
+
const baseUrl = this.config.baseUrl;
|
|
6451
|
+
return () => (tree) => {
|
|
6452
|
+
if (!baseUrl || this.config.outputMode !== "per-page") {
|
|
6453
|
+
return;
|
|
6170
6454
|
}
|
|
6455
|
+
visit11(tree, "link", (node) => {
|
|
6456
|
+
if (node.url.startsWith("/")) {
|
|
6457
|
+
node.url = `${baseUrl}${node.url}`;
|
|
6458
|
+
} else if (node.url.startsWith("./#") && pageUrl) {
|
|
6459
|
+
node.url = `${pageUrl}${node.url.slice(2)}`;
|
|
6460
|
+
}
|
|
6461
|
+
});
|
|
6462
|
+
};
|
|
6463
|
+
}
|
|
6464
|
+
applyPlugins(opts, processor) {
|
|
6465
|
+
if (this.config.mdxPlugins) {
|
|
6466
|
+
this.config.mdxPlugins.forEach((plugin) => {
|
|
6467
|
+
processor.use(plugin(opts));
|
|
6468
|
+
});
|
|
6171
6469
|
}
|
|
6172
|
-
return modules;
|
|
6173
6470
|
}
|
|
6174
|
-
|
|
6175
|
-
|
|
6176
|
-
|
|
6177
|
-
propsInfo.push(
|
|
6178
|
-
...props.props.map((prop) => this.convertPropInfo(prop, isPartial))
|
|
6179
|
-
);
|
|
6471
|
+
filterFrontmatter(frontmatter) {
|
|
6472
|
+
if (!this.config.frontmatter?.include?.length) {
|
|
6473
|
+
return frontmatter;
|
|
6180
6474
|
}
|
|
6181
|
-
|
|
6182
|
-
|
|
6183
|
-
|
|
6184
|
-
|
|
6185
|
-
|
|
6475
|
+
const includePatterns = this.config.frontmatter.include;
|
|
6476
|
+
const excludePatterns = this.config.frontmatter.exclude ?? [];
|
|
6477
|
+
const filtered = {};
|
|
6478
|
+
for (const [field, value] of Object.entries(frontmatter)) {
|
|
6479
|
+
if (value === void 0) {
|
|
6480
|
+
continue;
|
|
6481
|
+
}
|
|
6482
|
+
const isIncluded = includePatterns.some(
|
|
6483
|
+
(pattern) => minimatch(field, pattern)
|
|
6186
6484
|
);
|
|
6187
|
-
|
|
6188
|
-
|
|
6189
|
-
propsInfo.push(
|
|
6190
|
-
...props.output.map(
|
|
6191
|
-
(prop) => this.convertPropInfo(prop, isPartial, "output")
|
|
6192
|
-
)
|
|
6485
|
+
const isExcluded = excludePatterns.some(
|
|
6486
|
+
(pattern) => minimatch(field, pattern)
|
|
6193
6487
|
);
|
|
6488
|
+
if (isIncluded && !isExcluded) {
|
|
6489
|
+
filtered[field] = value;
|
|
6490
|
+
}
|
|
6194
6491
|
}
|
|
6195
|
-
return
|
|
6492
|
+
return filtered;
|
|
6196
6493
|
}
|
|
6197
|
-
|
|
6198
|
-
|
|
6199
|
-
|
|
6200
|
-
|
|
6201
|
-
|
|
6202
|
-
|
|
6203
|
-
|
|
6204
|
-
|
|
6205
|
-
|
|
6494
|
+
/**
|
|
6495
|
+
* Processes MDX content by transforming JSX elements (TypeDocProps, demos)
|
|
6496
|
+
* into Markdown, resolving relative links, and cleaning up formatting.
|
|
6497
|
+
*/
|
|
6498
|
+
async processMdxContent(mdxContent, pageInfo, frontmatter) {
|
|
6499
|
+
const processor = unified5().use(remarkParse4).use(remarkMdx3).use(remarkFrontmatter2, ["yaml"]).use(this.propFormatter.formatTypeDocProps()).use(this.formatFrontmatterExpressions(frontmatter)).use(await formatThemeNodes()).use(formatDemos(pageInfo.demosFolder)).use(this.transformRelativeUrls(pageInfo.url));
|
|
6500
|
+
this.applyPlugins(pageInfo, processor);
|
|
6501
|
+
processor.use(remarkStringify4);
|
|
6502
|
+
return await processor.run(processor.parse(mdxContent));
|
|
6503
|
+
}
|
|
6504
|
+
async processMdxPage(pageInfo) {
|
|
6505
|
+
try {
|
|
6506
|
+
const mdxContent = await readFile4(pageInfo.mdxFile, "utf-8");
|
|
6507
|
+
if (this.config.verbose) {
|
|
6508
|
+
console.log(`Processing page: ${pageInfo.name}`);
|
|
6206
6509
|
}
|
|
6510
|
+
const processor = unified5().use(remarkParse4).use(remarkMdx3).use(formatNpmInstallTabs).use(remarkFrontmatter2, ["yaml"]).use(remarkParseFrontmatter2).use(remarkStringify4);
|
|
6511
|
+
const parsed = await processor.process(mdxContent);
|
|
6512
|
+
const frontmatter = parsed.data?.frontmatter || {};
|
|
6513
|
+
const ast = await this.processMdxContent(
|
|
6514
|
+
String(parsed),
|
|
6515
|
+
pageInfo,
|
|
6516
|
+
frontmatter
|
|
6517
|
+
);
|
|
6518
|
+
const removeJsxProcessor = unified5().use(remarkMdx3).use(remarkFrontmatter2, ["yaml"]).use(remarkRemoveJsx).use(remarkStringify4);
|
|
6519
|
+
const sectionAst = removeJsxProcessor.runSync(ast);
|
|
6520
|
+
const removedJsx = String(removeJsxProcessor.stringify(sectionAst));
|
|
6521
|
+
const rawContent = removedJsx.replace(/^---\r?\n[\s\S]*?\r?\n---\r?\n?/, "").replace(/(^#{1,6} .*\\<[^>]+)>/gm, "$1\\>");
|
|
6522
|
+
const stripMetaProcessor = unified5().use(remarkParse4).use(remarkExtractMeta, {}).use(remarkStringify4);
|
|
6523
|
+
const strippedContent = String(
|
|
6524
|
+
await stripMetaProcessor.process(rawContent)
|
|
6525
|
+
);
|
|
6526
|
+
const title = frontmatter.title || pageInfo.name;
|
|
6527
|
+
return {
|
|
6528
|
+
content: strippedContent.trim(),
|
|
6529
|
+
frontmatter,
|
|
6530
|
+
rawContent: rawContent.trim(),
|
|
6531
|
+
sectionAst,
|
|
6532
|
+
title,
|
|
6533
|
+
url: pageInfo.url
|
|
6534
|
+
};
|
|
6535
|
+
} catch (error) {
|
|
6536
|
+
console.error(`Error processing component ${pageInfo.name}:`, error);
|
|
6537
|
+
throw error;
|
|
6207
6538
|
}
|
|
6208
|
-
|
|
6209
|
-
|
|
6210
|
-
|
|
6211
|
-
|
|
6212
|
-
|
|
6213
|
-
|
|
6214
|
-
|
|
6215
|
-
|
|
6216
|
-
|
|
6217
|
-
|
|
6218
|
-
\`\`\`
|
|
6219
|
-
${tagContent.trim()}
|
|
6220
|
-
\`\`\``);
|
|
6221
|
-
} else {
|
|
6222
|
-
parts.push(`**${tagName}:** ${tagContent.trim()}`);
|
|
6223
|
-
}
|
|
6539
|
+
}
|
|
6540
|
+
generateLlmsTxt(pages) {
|
|
6541
|
+
const lines = [
|
|
6542
|
+
getIntroLines(this.config.name, this.config.description)
|
|
6543
|
+
];
|
|
6544
|
+
lines.push("");
|
|
6545
|
+
for (const page of pages) {
|
|
6546
|
+
const content = page.content.split("\n").map((line) => {
|
|
6547
|
+
if (line.startsWith("#")) {
|
|
6548
|
+
return `#${line}`;
|
|
6224
6549
|
}
|
|
6550
|
+
return line;
|
|
6551
|
+
});
|
|
6552
|
+
if (content.every((line) => !line.trim())) {
|
|
6553
|
+
continue;
|
|
6225
6554
|
}
|
|
6555
|
+
lines.push(`## ${page.title}`);
|
|
6556
|
+
lines.push("");
|
|
6557
|
+
lines.push(content.join("\n"));
|
|
6558
|
+
lines.push("");
|
|
6226
6559
|
}
|
|
6227
|
-
return
|
|
6560
|
+
return lines.join("\n");
|
|
6228
6561
|
}
|
|
6229
|
-
|
|
6230
|
-
|
|
6231
|
-
|
|
6232
|
-
|
|
6233
|
-
return part.text;
|
|
6234
|
-
case "code":
|
|
6235
|
-
const codeText = part.text.replace(/```\w*\n?/g, "").replace(/\n?```/g, "").trim();
|
|
6236
|
-
if (codeText.includes("\n")) {
|
|
6237
|
-
return `\`\`\`
|
|
6238
|
-
${codeText}
|
|
6239
|
-
\`\`\``;
|
|
6240
|
-
} else {
|
|
6241
|
-
return codeText;
|
|
6242
|
-
}
|
|
6243
|
-
default:
|
|
6244
|
-
if (this.config.outputMode === "per-page" && "tag" in part && part.tag === "@link" && typeof part.target === "string") {
|
|
6245
|
-
if (part.text === "Learn more") {
|
|
6246
|
-
return "";
|
|
6247
|
-
}
|
|
6248
|
-
}
|
|
6249
|
-
return part.text;
|
|
6562
|
+
async generateAggregatedOutput(processedPages, pages) {
|
|
6563
|
+
const llmsTxtContent = this.generateLlmsTxt(processedPages);
|
|
6564
|
+
await mkdir(dirname3(this.config.outputPath), { recursive: true }).catch(
|
|
6565
|
+
() => {
|
|
6250
6566
|
}
|
|
6251
|
-
|
|
6252
|
-
|
|
6253
|
-
|
|
6254
|
-
|
|
6255
|
-
|
|
6256
|
-
|
|
6257
|
-
|
|
6258
|
-
|
|
6259
|
-
},
|
|
6260
|
-
description: this.formatComment(propInfo.comment || null),
|
|
6261
|
-
propType,
|
|
6262
|
-
required: extractRequired(propInfo, isPartial) || void 0
|
|
6263
|
-
};
|
|
6567
|
+
);
|
|
6568
|
+
await writeFile(this.config.outputPath, llmsTxtContent, "utf-8");
|
|
6569
|
+
const outputStats = await stat(this.config.outputPath);
|
|
6570
|
+
const outputSizeKb = (outputStats.size / 1024).toFixed(1);
|
|
6571
|
+
console.log(
|
|
6572
|
+
`Generated ${this.config.outputPath} with ${pages.length} files(s) at: ${this.config.outputPath}`
|
|
6573
|
+
);
|
|
6574
|
+
console.log(`File size: ${outputSizeKb} KB`);
|
|
6264
6575
|
}
|
|
6265
|
-
|
|
6266
|
-
|
|
6267
|
-
|
|
6268
|
-
|
|
6269
|
-
|
|
6270
|
-
let themes = null;
|
|
6271
|
-
try {
|
|
6272
|
-
themes = await import("@qualcomm-ui/tailwind-plugin/theme");
|
|
6273
|
-
} catch {
|
|
6274
|
-
return () => {
|
|
6275
|
-
};
|
|
6576
|
+
async generateExtraFiles(metadata) {
|
|
6577
|
+
const start = performance.now();
|
|
6578
|
+
const extraFiles = this.config.extraFiles ?? [];
|
|
6579
|
+
if (extraFiles.length === 0) {
|
|
6580
|
+
return { count: 0, duration: 0, entries: [], totalSize: 0 };
|
|
6276
6581
|
}
|
|
6277
|
-
|
|
6278
|
-
|
|
6279
|
-
|
|
6280
|
-
|
|
6281
|
-
|
|
6282
|
-
|
|
6283
|
-
|
|
6284
|
-
|
|
6285
|
-
},
|
|
6286
|
-
SpacingTable: (node) => {
|
|
6287
|
-
const path = this.getAttrExpression(node, "data");
|
|
6288
|
-
return path && getPath(themes, path);
|
|
6289
|
-
},
|
|
6290
|
-
ThemePropertyTable: (node) => {
|
|
6291
|
-
const path = this.getAttrExpression(node, "data");
|
|
6292
|
-
const property = this.getAttrExpression(node, "cssProperty");
|
|
6293
|
-
const data = path && getPath(themes, path);
|
|
6294
|
-
return path && property ? { cssPropertyName: property, data } : void 0;
|
|
6295
|
-
}
|
|
6296
|
-
};
|
|
6297
|
-
return () => (tree, _file, done) => {
|
|
6298
|
-
visit5(tree, "mdxJsxFlowElement", (node) => {
|
|
6299
|
-
const handler = node.name && handlers[node.name];
|
|
6300
|
-
if (!handler) {
|
|
6301
|
-
return;
|
|
6302
|
-
}
|
|
6303
|
-
const data = handler(node);
|
|
6304
|
-
if (!data) {
|
|
6305
|
-
console.warn(`No theme data for ${node.name}`);
|
|
6306
|
-
return;
|
|
6582
|
+
let totalSize = 0;
|
|
6583
|
+
const entries = [];
|
|
6584
|
+
await Promise.all(
|
|
6585
|
+
extraFiles.map(async (extraFile) => {
|
|
6586
|
+
let contents = extraFile.contents;
|
|
6587
|
+
if (extraFile.processAsMdx) {
|
|
6588
|
+
const removeJsxProcessor = unified5().use(remarkParse4).use(remarkMdx3).use(remarkFrontmatter2, ["yaml"]).use(remarkRemoveJsx).use(this.transformRelativeUrls()).use(remarkStringify4);
|
|
6589
|
+
contents = String(await removeJsxProcessor.process(contents));
|
|
6307
6590
|
}
|
|
6308
|
-
|
|
6309
|
-
if (
|
|
6310
|
-
|
|
6311
|
-
|
|
6312
|
-
|
|
6313
|
-
|
|
6591
|
+
const lines = [];
|
|
6592
|
+
if (metadata.length) {
|
|
6593
|
+
lines.push("---");
|
|
6594
|
+
for (const [key, value] of metadata) {
|
|
6595
|
+
lines.push(`${key}: ${value}`);
|
|
6596
|
+
}
|
|
6597
|
+
lines.push("---");
|
|
6598
|
+
lines.push("");
|
|
6314
6599
|
}
|
|
6315
|
-
if (
|
|
6316
|
-
|
|
6600
|
+
if (extraFile.title) {
|
|
6601
|
+
lines.push(`# ${extraFile.title}`);
|
|
6602
|
+
lines.push("");
|
|
6317
6603
|
}
|
|
6318
|
-
|
|
6319
|
-
|
|
6320
|
-
|
|
6321
|
-
|
|
6322
|
-
|
|
6604
|
+
lines.push(contents);
|
|
6605
|
+
lines.push("");
|
|
6606
|
+
const fileContent = lines.join("\n");
|
|
6607
|
+
const fileName = `${kebabCase3(extraFile.id)}.md`;
|
|
6608
|
+
const outfile = `${resolve4(this.config.outputPath)}/${fileName}`;
|
|
6609
|
+
await writeFile(outfile, fileContent, "utf-8");
|
|
6610
|
+
const stats = await stat(outfile);
|
|
6611
|
+
totalSize += stats.size / 1024;
|
|
6612
|
+
entries.push({
|
|
6613
|
+
id: extraFile.id,
|
|
6614
|
+
md5: computeMd5(fileContent),
|
|
6615
|
+
path: fileName,
|
|
6616
|
+
size: stats.size,
|
|
6617
|
+
title: extraFile.title || extraFile.id
|
|
6323
6618
|
});
|
|
6324
|
-
})
|
|
6325
|
-
done();
|
|
6326
|
-
};
|
|
6327
|
-
}
|
|
6328
|
-
getAttrExpression(node, name) {
|
|
6329
|
-
const attr = node.attributes?.find(
|
|
6330
|
-
(a) => a.type === "mdxJsxAttribute" && a.name === name
|
|
6619
|
+
})
|
|
6331
6620
|
);
|
|
6332
|
-
|
|
6333
|
-
|
|
6334
|
-
|
|
6335
|
-
|
|
6336
|
-
|
|
6337
|
-
}
|
|
6338
|
-
return attr.value.value;
|
|
6339
|
-
}
|
|
6340
|
-
return null;
|
|
6621
|
+
return {
|
|
6622
|
+
count: extraFiles.length,
|
|
6623
|
+
duration: performance.now() - start,
|
|
6624
|
+
entries,
|
|
6625
|
+
totalSize
|
|
6626
|
+
};
|
|
6341
6627
|
}
|
|
6342
|
-
|
|
6343
|
-
|
|
6344
|
-
|
|
6345
|
-
|
|
6346
|
-
const baseUrl = this.config.baseUrl;
|
|
6347
|
-
return () => (tree) => {
|
|
6348
|
-
if (!baseUrl || this.config.outputMode !== "per-page") {
|
|
6349
|
-
return;
|
|
6628
|
+
async generatePerPageExports(pages, processedPages, metadata) {
|
|
6629
|
+
const start = performance.now();
|
|
6630
|
+
await mkdir(dirname3(this.config.outputPath), { recursive: true }).catch(
|
|
6631
|
+
() => {
|
|
6350
6632
|
}
|
|
6351
|
-
|
|
6352
|
-
|
|
6353
|
-
|
|
6354
|
-
|
|
6355
|
-
|
|
6633
|
+
);
|
|
6634
|
+
const count = processedPages.length;
|
|
6635
|
+
let totalSize = 0;
|
|
6636
|
+
const manifestEntries = [];
|
|
6637
|
+
await Promise.all(
|
|
6638
|
+
processedPages.map(async (processedPage, index) => {
|
|
6639
|
+
const page = pages[index];
|
|
6640
|
+
const lines = [];
|
|
6641
|
+
const frontmatterEntries = [];
|
|
6642
|
+
if (page.url) {
|
|
6643
|
+
frontmatterEntries.push(["url", page.url]);
|
|
6356
6644
|
}
|
|
6357
|
-
|
|
6358
|
-
|
|
6359
|
-
|
|
6360
|
-
|
|
6361
|
-
|
|
6362
|
-
|
|
6363
|
-
|
|
6364
|
-
|
|
6365
|
-
|
|
6366
|
-
|
|
6367
|
-
|
|
6368
|
-
"mdxJsxFlowElement",
|
|
6369
|
-
(node, index, parent) => {
|
|
6370
|
-
if (node?.name !== "TypeDocProps") {
|
|
6371
|
-
return;
|
|
6372
|
-
}
|
|
6373
|
-
const nameAttr = node.attributes?.find(
|
|
6374
|
-
(attr) => attr.type === "mdxJsxAttribute" && attr.name === "name"
|
|
6375
|
-
);
|
|
6376
|
-
const isPartial = node.attributes?.some(
|
|
6377
|
-
(attr) => attr.type === "mdxJsxAttribute" && attr.name === "partial"
|
|
6378
|
-
);
|
|
6379
|
-
if (!this.docProps || !nameAttr) {
|
|
6380
|
-
if (parent && index !== void 0) {
|
|
6381
|
-
parent.children.splice(index, 1);
|
|
6382
|
-
}
|
|
6383
|
-
return;
|
|
6384
|
-
}
|
|
6385
|
-
const propsNames = extractNamesFromAttribute(nameAttr);
|
|
6386
|
-
if (propsNames.length === 0) {
|
|
6387
|
-
if (parent && index !== void 0) {
|
|
6388
|
-
parent.children.splice(index, 1);
|
|
6389
|
-
}
|
|
6390
|
-
return;
|
|
6391
|
-
}
|
|
6392
|
-
const propsName = propsNames[0];
|
|
6393
|
-
const componentProps = this.docProps.props[propsName];
|
|
6394
|
-
if (!componentProps) {
|
|
6395
|
-
if (this.config.verbose) {
|
|
6396
|
-
console.log(` TypeDocProps not found: ${propsName}`);
|
|
6397
|
-
}
|
|
6398
|
-
if (parent && index !== void 0) {
|
|
6399
|
-
parent.children.splice(index, 1);
|
|
6645
|
+
for (const [key, value] of metadata) {
|
|
6646
|
+
frontmatterEntries.push([key, value]);
|
|
6647
|
+
}
|
|
6648
|
+
if (this.config.frontmatter?.include?.length) {
|
|
6649
|
+
const includePatterns = this.config.frontmatter.include;
|
|
6650
|
+
const excludePatterns = this.config.frontmatter.exclude ?? [];
|
|
6651
|
+
for (const [field, value] of Object.entries(
|
|
6652
|
+
processedPage.frontmatter
|
|
6653
|
+
)) {
|
|
6654
|
+
if (value === void 0) {
|
|
6655
|
+
continue;
|
|
6400
6656
|
}
|
|
6401
|
-
|
|
6402
|
-
|
|
6403
|
-
const propsDoc = this.extractProps(componentProps, Boolean(isPartial));
|
|
6404
|
-
if (this.config.verbose) {
|
|
6405
|
-
console.log(
|
|
6406
|
-
` Replaced TypeDocProps ${propsName} with API documentation`
|
|
6657
|
+
const isIncluded = includePatterns.some(
|
|
6658
|
+
(pattern) => minimatch(field, pattern)
|
|
6407
6659
|
);
|
|
6660
|
+
const isExcluded = excludePatterns.some(
|
|
6661
|
+
(pattern) => minimatch(field, pattern)
|
|
6662
|
+
);
|
|
6663
|
+
if (isIncluded && !isExcluded) {
|
|
6664
|
+
frontmatterEntries.push([
|
|
6665
|
+
field,
|
|
6666
|
+
Array.isArray(value) ? value : String(value)
|
|
6667
|
+
]);
|
|
6668
|
+
}
|
|
6408
6669
|
}
|
|
6409
|
-
|
|
6410
|
-
|
|
6411
|
-
const
|
|
6412
|
-
|
|
6413
|
-
|
|
6414
|
-
|
|
6415
|
-
}
|
|
6416
|
-
if (inputs.length > 0) {
|
|
6417
|
-
sections.push(`**Inputs**
|
|
6418
|
-
|
|
6419
|
-
${propsToDefinitionList(inputs)}`);
|
|
6420
|
-
}
|
|
6421
|
-
if (outputs.length > 0) {
|
|
6422
|
-
sections.push(`**Outputs**
|
|
6423
|
-
|
|
6424
|
-
${propsToDefinitionList(outputs)}`);
|
|
6670
|
+
}
|
|
6671
|
+
if (this.config.frontmatter?.extraFields) {
|
|
6672
|
+
for (const [key, value] of Object.entries(
|
|
6673
|
+
this.config.frontmatter.extraFields
|
|
6674
|
+
)) {
|
|
6675
|
+
frontmatterEntries.push([key, value]);
|
|
6425
6676
|
}
|
|
6426
|
-
|
|
6427
|
-
|
|
6428
|
-
|
|
6429
|
-
|
|
6677
|
+
}
|
|
6678
|
+
if (frontmatterEntries.length > 0) {
|
|
6679
|
+
lines.push("---");
|
|
6680
|
+
for (const [key, value] of frontmatterEntries) {
|
|
6681
|
+
if (Array.isArray(value)) {
|
|
6682
|
+
lines.push(`${key}: [${value.join(", ")}]`);
|
|
6683
|
+
} else {
|
|
6684
|
+
lines.push(`${key}: ${value}`);
|
|
6430
6685
|
}
|
|
6431
|
-
return;
|
|
6432
6686
|
}
|
|
6433
|
-
|
|
6434
|
-
|
|
6435
|
-
meta: null,
|
|
6436
|
-
type: "code",
|
|
6437
|
-
value: markdownContent
|
|
6438
|
-
});
|
|
6687
|
+
lines.push("---");
|
|
6688
|
+
lines.push("");
|
|
6439
6689
|
}
|
|
6440
|
-
|
|
6441
|
-
|
|
6442
|
-
|
|
6443
|
-
|
|
6444
|
-
|
|
6445
|
-
|
|
6446
|
-
|
|
6447
|
-
|
|
6448
|
-
|
|
6449
|
-
|
|
6450
|
-
|
|
6451
|
-
|
|
6452
|
-
|
|
6453
|
-
|
|
6454
|
-
(node, index, parent) => {
|
|
6455
|
-
if (!node?.name || !["QdsDemo", "CodeDemo", "Demo"].includes(node.name)) {
|
|
6456
|
-
return;
|
|
6457
|
-
}
|
|
6458
|
-
const nameAttr = node.attributes?.find(
|
|
6459
|
-
(attr) => attr.type === "mdxJsxAttribute" && attr.name === "name"
|
|
6460
|
-
);
|
|
6461
|
-
const nodeAttr = node.attributes?.find(
|
|
6462
|
-
(attr) => attr.type === "mdxJsxAttribute" && attr.name === "node"
|
|
6463
|
-
);
|
|
6464
|
-
let demoName;
|
|
6465
|
-
if (nameAttr && typeof nameAttr.value === "string") {
|
|
6466
|
-
demoName = nameAttr.value;
|
|
6467
|
-
} else if (nodeAttr?.value && typeof nodeAttr.value !== "string") {
|
|
6468
|
-
const estree = nodeAttr.value.data?.estree;
|
|
6469
|
-
if (estree?.body?.[0]?.type === "ExpressionStatement") {
|
|
6470
|
-
const expression = estree.body[0].expression;
|
|
6471
|
-
if (expression.type === "MemberExpression" && expression.object.type === "Identifier" && expression.object.name === "Demo" && expression.property.type === "Identifier") {
|
|
6472
|
-
demoName = expression.property.name;
|
|
6473
|
-
}
|
|
6474
|
-
}
|
|
6475
|
-
}
|
|
6476
|
-
if (!demoName) {
|
|
6477
|
-
if (parent && index !== void 0) {
|
|
6478
|
-
parent.children.splice(index, 1);
|
|
6479
|
-
}
|
|
6480
|
-
return;
|
|
6481
|
-
}
|
|
6482
|
-
promises.push(
|
|
6483
|
-
(async () => {
|
|
6484
|
-
const kebabName = kebabCase(demoName);
|
|
6485
|
-
let filePath = `${kebabName}.tsx`;
|
|
6486
|
-
if (!demosFolder) {
|
|
6487
|
-
if (this.config.verbose) {
|
|
6488
|
-
console.log(` No demos folder for ${demoName}`);
|
|
6489
|
-
}
|
|
6490
|
-
if (parent && index !== void 0) {
|
|
6491
|
-
parent.children.splice(index, 1);
|
|
6492
|
-
}
|
|
6493
|
-
return;
|
|
6494
|
-
}
|
|
6495
|
-
let demoFilePath = join3(demosFolder, filePath);
|
|
6496
|
-
let isAngularDemo = false;
|
|
6497
|
-
if (!await exists(demoFilePath)) {
|
|
6498
|
-
demoFilePath = join3(demosFolder, `${kebabName}.ts`);
|
|
6499
|
-
if (await exists(demoFilePath)) {
|
|
6500
|
-
isAngularDemo = true;
|
|
6501
|
-
filePath = `${kebabCase(demoName).replace("-component", ".component")}.ts`;
|
|
6502
|
-
demoFilePath = join3(demosFolder, filePath);
|
|
6503
|
-
} else {
|
|
6504
|
-
console.log(` Demo not found ${demoName}`);
|
|
6505
|
-
if (parent && index !== void 0) {
|
|
6506
|
-
parent.children.splice(index, 1);
|
|
6507
|
-
}
|
|
6508
|
-
return;
|
|
6509
|
-
}
|
|
6510
|
-
}
|
|
6511
|
-
try {
|
|
6512
|
-
const demoCode = await readFile(demoFilePath, "utf-8");
|
|
6513
|
-
const cleanedCode = removePreviewLines(demoCode);
|
|
6514
|
-
if (this.config.verbose) {
|
|
6515
|
-
console.log(` Replaced demo ${demoName} with source code`);
|
|
6516
|
-
}
|
|
6517
|
-
demoFiles.push(demoFilePath);
|
|
6518
|
-
Object.assign(node, {
|
|
6519
|
-
lang: isAngularDemo ? "angular-ts" : "tsx",
|
|
6520
|
-
meta: null,
|
|
6521
|
-
type: "code",
|
|
6522
|
-
value: cleanedCode
|
|
6523
|
-
});
|
|
6524
|
-
} catch (error) {
|
|
6525
|
-
if (this.config.verbose) {
|
|
6526
|
-
console.log(`Error reading demo ${demoName}`, error);
|
|
6527
|
-
}
|
|
6528
|
-
if (parent && index !== void 0) {
|
|
6529
|
-
parent.children.splice(index, 1);
|
|
6530
|
-
}
|
|
6531
|
-
}
|
|
6532
|
-
})()
|
|
6690
|
+
lines.push(`# ${processedPage.title}`);
|
|
6691
|
+
lines.push("");
|
|
6692
|
+
if (processedPage.frontmatter?.title) {
|
|
6693
|
+
page.name = processedPage.frontmatter.title;
|
|
6694
|
+
}
|
|
6695
|
+
let content = processedPage.content;
|
|
6696
|
+
content = content.replace(
|
|
6697
|
+
new RegExp(`^# ${processedPage.title}\\n+`, ""),
|
|
6698
|
+
""
|
|
6699
|
+
);
|
|
6700
|
+
if (this.config.pageTitlePrefix) {
|
|
6701
|
+
content = content.replace(
|
|
6702
|
+
`# ${page.name}`,
|
|
6703
|
+
`# ${this.config.pageTitlePrefix} ${page.name}`
|
|
6533
6704
|
);
|
|
6705
|
+
page.name = `${this.config.pageTitlePrefix} ${page.name}`;
|
|
6534
6706
|
}
|
|
6707
|
+
lines.push(content);
|
|
6708
|
+
lines.push("");
|
|
6709
|
+
const fileContent = lines.join("\n");
|
|
6710
|
+
const fileName = `${kebabCase3(page.id || page.name)}.md`;
|
|
6711
|
+
const outfile = `${resolve4(this.config.outputPath)}/${fileName}`;
|
|
6712
|
+
await writeFile(outfile, fileContent, "utf-8");
|
|
6713
|
+
const stats = await stat(outfile);
|
|
6714
|
+
totalSize += stats.size / 1024;
|
|
6715
|
+
manifestEntries.push({
|
|
6716
|
+
id: page.id || kebabCase3(page.name),
|
|
6717
|
+
md5: computeMd5(fileContent),
|
|
6718
|
+
path: fileName,
|
|
6719
|
+
size: stats.size,
|
|
6720
|
+
title: processedPage.title,
|
|
6721
|
+
url: page.url
|
|
6722
|
+
});
|
|
6723
|
+
})
|
|
6724
|
+
);
|
|
6725
|
+
const extraFilesResult = await this.generateExtraFiles(metadata);
|
|
6726
|
+
manifestEntries.push(...extraFilesResult.entries);
|
|
6727
|
+
if (this.config.manifestOutputPath) {
|
|
6728
|
+
if (this.config.generateManifest !== false) {
|
|
6729
|
+
await this.generateManifest(
|
|
6730
|
+
this.config.manifestOutputPath,
|
|
6731
|
+
manifestEntries
|
|
6732
|
+
);
|
|
6733
|
+
}
|
|
6734
|
+
if (this.config.generateBulkZip !== false) {
|
|
6735
|
+
await this.generateBulkZip(
|
|
6736
|
+
this.config.manifestOutputPath,
|
|
6737
|
+
manifestEntries
|
|
6738
|
+
);
|
|
6739
|
+
}
|
|
6740
|
+
await this.generateSectionsOutput(
|
|
6741
|
+
processedPages,
|
|
6742
|
+
pages,
|
|
6743
|
+
this.config.manifestOutputPath
|
|
6535
6744
|
);
|
|
6536
|
-
|
|
6745
|
+
}
|
|
6746
|
+
console.log(
|
|
6747
|
+
`Generated ${count + extraFilesResult.count} files(s) in ${chalk3.magenta.bold(`${Math.round(performance.now() - start + extraFilesResult.duration)}ms`)} at ${chalk3.blue.bold(this.config.outputPath)} - ${(totalSize + extraFilesResult.totalSize).toFixed(1)} KB`
|
|
6748
|
+
);
|
|
6749
|
+
}
|
|
6750
|
+
computeAggregateHash(entries) {
|
|
6751
|
+
const sortedHashes = entries.map((e) => e.md5).sort().join("");
|
|
6752
|
+
return computeMd5(sortedHashes);
|
|
6753
|
+
}
|
|
6754
|
+
async generateManifest(outputPath, entries) {
|
|
6755
|
+
const aggregateHash = this.computeAggregateHash(entries);
|
|
6756
|
+
const totalSize = entries.reduce((sum, e) => sum + e.size, 0);
|
|
6757
|
+
const manifest = {
|
|
6758
|
+
aggregateHash,
|
|
6759
|
+
baseUrl: this.config.baseUrl,
|
|
6760
|
+
files: entries,
|
|
6761
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6762
|
+
totalFiles: entries.length,
|
|
6763
|
+
totalSize,
|
|
6764
|
+
version: 1
|
|
6537
6765
|
};
|
|
6766
|
+
await mkdir(outputPath, { recursive: true }).catch(() => {
|
|
6767
|
+
});
|
|
6768
|
+
await writeFile(
|
|
6769
|
+
join6(outputPath, "manifest.json"),
|
|
6770
|
+
JSON.stringify(manifest, null, 2),
|
|
6771
|
+
"utf-8"
|
|
6772
|
+
);
|
|
6773
|
+
return manifest;
|
|
6538
6774
|
}
|
|
6539
|
-
|
|
6540
|
-
|
|
6541
|
-
|
|
6542
|
-
|
|
6543
|
-
|
|
6544
|
-
|
|
6545
|
-
|
|
6546
|
-
|
|
6547
|
-
|
|
6548
|
-
|
|
6549
|
-
|
|
6550
|
-
|
|
6551
|
-
|
|
6552
|
-
|
|
6553
|
-
|
|
6554
|
-
|
|
6555
|
-
|
|
6556
|
-
|
|
6557
|
-
|
|
6558
|
-
|
|
6559
|
-
const
|
|
6560
|
-
|
|
6561
|
-
|
|
6562
|
-
|
|
6563
|
-
|
|
6564
|
-
|
|
6565
|
-
|
|
6775
|
+
async generateBulkZip(outputPath, entries) {
|
|
6776
|
+
await mkdir(outputPath, { recursive: true }).catch(() => {
|
|
6777
|
+
});
|
|
6778
|
+
const zipPath = join6(outputPath, "bulk.zip");
|
|
6779
|
+
const zip = new AdmZip();
|
|
6780
|
+
for (const entry of entries) {
|
|
6781
|
+
const filePath = join6(this.config.outputPath, entry.path);
|
|
6782
|
+
const content = await readFile4(filePath);
|
|
6783
|
+
zip.addFile(entry.path, content);
|
|
6784
|
+
}
|
|
6785
|
+
zip.writeZip(zipPath);
|
|
6786
|
+
}
|
|
6787
|
+
async generateSectionsOutput(processedPages, pages, outputPath) {
|
|
6788
|
+
const sectionsConfig = this.config.sections ?? {};
|
|
6789
|
+
const extractor = new SectionExtractor({
|
|
6790
|
+
depths: sectionsConfig.depths,
|
|
6791
|
+
minContentLength: sectionsConfig.minContentLength
|
|
6792
|
+
});
|
|
6793
|
+
const allSections = [];
|
|
6794
|
+
for (let i = 0; i < processedPages.length; i++) {
|
|
6795
|
+
const processed = processedPages[i];
|
|
6796
|
+
const page = pages[i];
|
|
6797
|
+
const filteredFrontmatter = this.filterFrontmatter(processed.frontmatter);
|
|
6798
|
+
const pageSections = extractor.extract(processed.sectionAst, {
|
|
6799
|
+
frontmatter: filteredFrontmatter,
|
|
6800
|
+
id: page.id,
|
|
6801
|
+
title: processed.title,
|
|
6802
|
+
url: processed.url
|
|
6566
6803
|
});
|
|
6567
|
-
|
|
6568
|
-
|
|
6804
|
+
allSections.push(...pageSections);
|
|
6805
|
+
}
|
|
6806
|
+
const hash = computeMd5(JSON.stringify(allSections));
|
|
6807
|
+
const output = {
|
|
6808
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6809
|
+
hash,
|
|
6810
|
+
sections: allSections,
|
|
6811
|
+
totalSections: allSections.length,
|
|
6812
|
+
version: 1
|
|
6813
|
+
};
|
|
6814
|
+
const sectionsPath = join6(
|
|
6815
|
+
outputPath,
|
|
6816
|
+
sectionsConfig.outputPath ?? "sections.json"
|
|
6817
|
+
);
|
|
6818
|
+
await mkdir(dirname3(sectionsPath), { recursive: true }).catch(() => {
|
|
6819
|
+
});
|
|
6820
|
+
await writeFile(sectionsPath, JSON.stringify(output, null, 2), "utf-8");
|
|
6821
|
+
if (this.config.verbose) {
|
|
6822
|
+
console.log(
|
|
6823
|
+
`Generated ${allSections.length} sections at ${chalk3.blue.bold(sectionsPath)}`
|
|
6824
|
+
);
|
|
6825
|
+
}
|
|
6826
|
+
}
|
|
6827
|
+
};
|
|
6828
|
+
|
|
6829
|
+
// src/ai-knowledge/generator/command.ts
|
|
6830
|
+
async function generate(config3) {
|
|
6831
|
+
const generator = new KnowledgeGenerator(config3);
|
|
6832
|
+
return generator.run();
|
|
6833
|
+
}
|
|
6834
|
+
function addGenerateKnowledgeCommand() {
|
|
6835
|
+
program.description("Generate llms.txt from QUI Docs documentation").command("generate-llms-txt").option("-n, --name <name>", "Project name for llms.txt header").requiredOption("-m, --output-mode <outputMode>").option("-o, --outputPath <outputPath>", "Output file or directory.").option(
|
|
6836
|
+
"-d, --description <description>",
|
|
6837
|
+
"Project description for llms.txt"
|
|
6838
|
+
).option("-v, --verbose", "Enable verbose logging", false).option(
|
|
6839
|
+
"--exclude <patterns...>",
|
|
6840
|
+
"Glob patterns to exclude (e.g., **/internal/**, guide/drafts/*)",
|
|
6841
|
+
[]
|
|
6842
|
+
).option("--base-url <url>", "Base URL for component documentation links").option("--metadata <pairs...>", "metadata key-value pairs").option("--clean", "Clean the output path before generating").option("--include-imports", "Include relative import source files", true).option(
|
|
6843
|
+
"-e, --environment <environments>",
|
|
6844
|
+
"Comma-separated list of environments to generate (default: all)"
|
|
6845
|
+
).action(async (options) => {
|
|
6846
|
+
loadEnv();
|
|
6847
|
+
const cliOptions = {
|
|
6848
|
+
...options,
|
|
6849
|
+
outputMode: options.outputMode === "per-page" ? "per-page" : "aggregated"
|
|
6850
|
+
};
|
|
6851
|
+
const environmentFilter = options.environment?.split(",").map((e) => e.trim()).filter(Boolean);
|
|
6852
|
+
const configs = loadEnvironmentConfigs({
|
|
6853
|
+
cliOptions,
|
|
6854
|
+
environments: environmentFilter
|
|
6855
|
+
});
|
|
6856
|
+
for (const config3 of configs) {
|
|
6857
|
+
const envLabel = config3.environmentName ? `[${config3.environmentName}] ` : "";
|
|
6858
|
+
console.log(`${envLabel}Generating knowledge to ${config3.outputPath}`);
|
|
6859
|
+
await generate(config3);
|
|
6860
|
+
}
|
|
6861
|
+
if (configs.length > 1) {
|
|
6862
|
+
console.log(
|
|
6863
|
+
`
|
|
6864
|
+
Generated knowledge for ${configs.length} environment(s)`
|
|
6865
|
+
);
|
|
6866
|
+
}
|
|
6867
|
+
});
|
|
6868
|
+
}
|
|
6869
|
+
|
|
6870
|
+
// src/ai-knowledge/open-web-ui/download-knowledge.ts
|
|
6871
|
+
import dotenv from "dotenv";
|
|
6872
|
+
import { mkdir as mkdir2, writeFile as writeFile2 } from "node:fs/promises";
|
|
6873
|
+
import { resolve as resolve5 } from "node:path";
|
|
6874
|
+
|
|
6875
|
+
// src/ai-knowledge/open-web-ui/api.ts
|
|
6876
|
+
function isErrorResponse(response) {
|
|
6877
|
+
return typeof response === "object" && response !== null && "detail" in response;
|
|
6878
|
+
}
|
|
6879
|
+
var FilesApi = class {
|
|
6880
|
+
config;
|
|
6881
|
+
constructor(config3) {
|
|
6882
|
+
this.config = config3;
|
|
6883
|
+
}
|
|
6884
|
+
get headers() {
|
|
6885
|
+
return {
|
|
6886
|
+
Authorization: `Bearer ${this.config.apiKey}`
|
|
6887
|
+
};
|
|
6888
|
+
}
|
|
6889
|
+
get jsonHeaders() {
|
|
6890
|
+
return {
|
|
6891
|
+
...this.headers,
|
|
6892
|
+
"Content-Type": "application/json"
|
|
6893
|
+
};
|
|
6894
|
+
}
|
|
6895
|
+
async handleResponse(response) {
|
|
6896
|
+
const data = await response.json();
|
|
6897
|
+
if (isErrorResponse(data)) {
|
|
6898
|
+
throw new Error(data.detail);
|
|
6899
|
+
}
|
|
6900
|
+
return data;
|
|
6901
|
+
}
|
|
6902
|
+
async upload(file, filename, options) {
|
|
6903
|
+
const formData = new FormData();
|
|
6904
|
+
let blob;
|
|
6905
|
+
if (file instanceof Blob) {
|
|
6906
|
+
blob = file;
|
|
6907
|
+
} else if (file instanceof ArrayBuffer) {
|
|
6908
|
+
blob = new Blob([file]);
|
|
6909
|
+
} else {
|
|
6910
|
+
const copy = new Uint8Array(file).buffer;
|
|
6911
|
+
blob = new Blob([copy]);
|
|
6912
|
+
}
|
|
6913
|
+
formData.append("file", blob, filename);
|
|
6914
|
+
if (options?.metadata) {
|
|
6915
|
+
formData.append("metadata", JSON.stringify(options.metadata));
|
|
6916
|
+
}
|
|
6917
|
+
const params = new URLSearchParams();
|
|
6918
|
+
if (options?.process !== void 0) {
|
|
6919
|
+
params.set("process", String(options.process));
|
|
6920
|
+
}
|
|
6921
|
+
if (options?.processInBackground !== void 0) {
|
|
6922
|
+
params.set("process_in_background", String(options.processInBackground));
|
|
6923
|
+
}
|
|
6924
|
+
const url = `${this.config.baseUrl}/api/v1/files/${params.toString() ? `?${params}` : ""}`;
|
|
6925
|
+
const response = await fetch(url, {
|
|
6926
|
+
body: formData,
|
|
6927
|
+
headers: this.headers,
|
|
6928
|
+
method: "POST"
|
|
6929
|
+
});
|
|
6930
|
+
return this.handleResponse(response);
|
|
6931
|
+
}
|
|
6932
|
+
async list(includeContent = true) {
|
|
6933
|
+
const params = new URLSearchParams({ content: String(includeContent) });
|
|
6934
|
+
const response = await fetch(
|
|
6935
|
+
`${this.config.baseUrl}/api/v1/files/?${params}`,
|
|
6936
|
+
{
|
|
6937
|
+
headers: this.headers
|
|
6569
6938
|
}
|
|
6939
|
+
);
|
|
6940
|
+
return this.handleResponse(response);
|
|
6941
|
+
}
|
|
6942
|
+
async search(pattern, includeContent = true) {
|
|
6943
|
+
const params = new URLSearchParams({
|
|
6944
|
+
content: String(includeContent),
|
|
6945
|
+
filename: pattern
|
|
6946
|
+
});
|
|
6947
|
+
const response = await fetch(
|
|
6948
|
+
`${this.config.baseUrl}/api/v1/files/search?${params}`,
|
|
6949
|
+
{ headers: this.headers }
|
|
6950
|
+
);
|
|
6951
|
+
if (response.status === 404) {
|
|
6952
|
+
return [];
|
|
6953
|
+
}
|
|
6954
|
+
return this.handleResponse(response);
|
|
6955
|
+
}
|
|
6956
|
+
async deleteAll() {
|
|
6957
|
+
const response = await fetch(`${this.config.baseUrl}/api/v1/files/all`, {
|
|
6958
|
+
headers: this.headers,
|
|
6959
|
+
method: "DELETE"
|
|
6960
|
+
});
|
|
6961
|
+
return this.handleResponse(response);
|
|
6962
|
+
}
|
|
6963
|
+
async getById(id) {
|
|
6964
|
+
const response = await fetch(`${this.config.baseUrl}/api/v1/files/${id}`, {
|
|
6965
|
+
headers: this.headers
|
|
6966
|
+
});
|
|
6967
|
+
return this.handleResponse(response);
|
|
6968
|
+
}
|
|
6969
|
+
async getProcessStatus(id) {
|
|
6970
|
+
const response = await fetch(
|
|
6971
|
+
`${this.config.baseUrl}/api/v1/files/${id}/process/status`,
|
|
6972
|
+
{ headers: this.headers }
|
|
6973
|
+
);
|
|
6974
|
+
return this.handleResponse(response);
|
|
6975
|
+
}
|
|
6976
|
+
async waitForProcessing(id, options) {
|
|
6977
|
+
const maxAttempts = options?.maxAttempts ?? 120;
|
|
6978
|
+
const intervalMs = options?.intervalMs ?? 1e3;
|
|
6979
|
+
for (let i = 0; i < maxAttempts; i++) {
|
|
6980
|
+
const status = await this.getProcessStatus(id);
|
|
6981
|
+
if (status.status === "completed" || status.status === "failed") {
|
|
6982
|
+
return status;
|
|
6983
|
+
}
|
|
6984
|
+
await new Promise((resolve10) => setTimeout(resolve10, intervalMs));
|
|
6985
|
+
}
|
|
6986
|
+
throw new Error(`File processing timed out after ${maxAttempts} attempts`);
|
|
6987
|
+
}
|
|
6988
|
+
async getDataContent(id) {
|
|
6989
|
+
const response = await fetch(
|
|
6990
|
+
`${this.config.baseUrl}/api/v1/files/${id}/data/content`,
|
|
6991
|
+
{ headers: this.headers }
|
|
6992
|
+
);
|
|
6993
|
+
return this.handleResponse(response);
|
|
6994
|
+
}
|
|
6995
|
+
async updateDataContent(id, content) {
|
|
6996
|
+
const response = await fetch(
|
|
6997
|
+
`${this.config.baseUrl}/api/v1/files/${id}/data/content/update`,
|
|
6998
|
+
{
|
|
6999
|
+
body: JSON.stringify({ content }),
|
|
7000
|
+
headers: this.jsonHeaders,
|
|
7001
|
+
method: "POST"
|
|
7002
|
+
}
|
|
7003
|
+
);
|
|
7004
|
+
return this.handleResponse(response);
|
|
7005
|
+
}
|
|
7006
|
+
async getContent(id, asAttachment = false) {
|
|
7007
|
+
const params = new URLSearchParams({ attachment: String(asAttachment) });
|
|
7008
|
+
return fetch(
|
|
7009
|
+
`${this.config.baseUrl}/api/v1/files/${id}/content?${params}`,
|
|
7010
|
+
{
|
|
7011
|
+
headers: this.headers
|
|
7012
|
+
}
|
|
7013
|
+
);
|
|
7014
|
+
}
|
|
7015
|
+
async getContentAsText(id) {
|
|
7016
|
+
const response = await this.getContent(id);
|
|
7017
|
+
if (!response.ok) {
|
|
7018
|
+
const error = await response.json();
|
|
7019
|
+
throw new Error(error.detail || "Failed to get file content");
|
|
7020
|
+
}
|
|
7021
|
+
return response.text();
|
|
7022
|
+
}
|
|
7023
|
+
async delete(id) {
|
|
7024
|
+
const response = await fetch(`${this.config.baseUrl}/api/v1/files/${id}`, {
|
|
7025
|
+
headers: this.headers,
|
|
7026
|
+
method: "DELETE"
|
|
7027
|
+
});
|
|
7028
|
+
return this.handleResponse(response);
|
|
7029
|
+
}
|
|
7030
|
+
};
|
|
7031
|
+
var KnowledgeApi = class {
|
|
7032
|
+
config;
|
|
7033
|
+
constructor(config3) {
|
|
7034
|
+
this.config = config3;
|
|
7035
|
+
}
|
|
7036
|
+
get headers() {
|
|
7037
|
+
return {
|
|
7038
|
+
Authorization: `Bearer ${this.config.apiKey}`
|
|
6570
7039
|
};
|
|
6571
7040
|
}
|
|
6572
|
-
|
|
6573
|
-
|
|
6574
|
-
|
|
6575
|
-
|
|
6576
|
-
|
|
6577
|
-
const demoFiles = [];
|
|
6578
|
-
const processor = unified4().use(remarkParse4).use(remarkMdx3).use(remarkFrontmatter2, ["yaml"]).use(this.replaceTypeDocProps()).use(this.replaceFrontmatterExpressions(frontmatter)).use(await this.replaceThemeNodes()).use(this.replaceDemos(demosFolder, demoFiles)).use(this.transformRelativeUrls(pageUrl)).use(remarkStringify3);
|
|
6579
|
-
const processed = await processor.process(mdxContent);
|
|
6580
|
-
const processedContent = String(processed).replace(/\n\s*\n\s*\n/g, "\n\n");
|
|
6581
|
-
return { content: processedContent, demoFiles };
|
|
7041
|
+
get jsonHeaders() {
|
|
7042
|
+
return {
|
|
7043
|
+
...this.headers,
|
|
7044
|
+
"Content-Type": "application/json"
|
|
7045
|
+
};
|
|
6582
7046
|
}
|
|
6583
|
-
async
|
|
6584
|
-
|
|
6585
|
-
|
|
6586
|
-
|
|
6587
|
-
console.log(`Processing page: ${pageInfo.name}`);
|
|
6588
|
-
}
|
|
6589
|
-
const processor = unified4().use(remarkParse4).use(remarkMdx3).use(replaceNpmInstallTabs).use(remarkFrontmatter2, ["yaml"]).use(remarkParseFrontmatter2).use(remarkStringify3);
|
|
6590
|
-
const parsed = await processor.process(mdxContent);
|
|
6591
|
-
const frontmatter = parsed.data?.frontmatter || {};
|
|
6592
|
-
const { content: processedContent, demoFiles } = await this.processMdxContent(
|
|
6593
|
-
String(parsed),
|
|
6594
|
-
pageInfo.url,
|
|
6595
|
-
pageInfo.demosFolder,
|
|
6596
|
-
frontmatter
|
|
6597
|
-
);
|
|
6598
|
-
const removeJsxProcessor = unified4().use(remarkParse4).use(remarkMdx3).use(remarkFrontmatter2, ["yaml"]).use(remarkRemoveJsx).use(remarkStringify3);
|
|
6599
|
-
const removedJsx = String(
|
|
6600
|
-
await removeJsxProcessor.process(processedContent)
|
|
6601
|
-
);
|
|
6602
|
-
const contentWithoutFrontmatter = removedJsx.replace(/^---[\s\S]*?---\n/, "").replace(/(^#{1,6} .*\\<[^>]+)>/gm, "$1\\>");
|
|
6603
|
-
const title = frontmatter.title || pageInfo.name;
|
|
6604
|
-
return {
|
|
6605
|
-
content: contentWithoutFrontmatter.trim(),
|
|
6606
|
-
demoFiles,
|
|
6607
|
-
frontmatter,
|
|
6608
|
-
title,
|
|
6609
|
-
url: pageInfo.url
|
|
6610
|
-
};
|
|
6611
|
-
} catch (error) {
|
|
6612
|
-
console.error(`Error processing component ${pageInfo.name}:`, error);
|
|
6613
|
-
throw error;
|
|
7047
|
+
async handleResponse(response) {
|
|
7048
|
+
const data = await response.json();
|
|
7049
|
+
if (isErrorResponse(data)) {
|
|
7050
|
+
throw new Error(data.detail);
|
|
6614
7051
|
}
|
|
7052
|
+
return data;
|
|
6615
7053
|
}
|
|
6616
|
-
|
|
6617
|
-
const
|
|
6618
|
-
|
|
6619
|
-
|
|
6620
|
-
|
|
6621
|
-
|
|
6622
|
-
|
|
6623
|
-
|
|
6624
|
-
|
|
6625
|
-
|
|
6626
|
-
|
|
6627
|
-
});
|
|
6628
|
-
if (content.every((line) => !line.trim())) {
|
|
6629
|
-
continue;
|
|
7054
|
+
async list() {
|
|
7055
|
+
const response = await fetch(`${this.config.baseUrl}/api/v1/knowledge/`, {
|
|
7056
|
+
headers: this.headers
|
|
7057
|
+
});
|
|
7058
|
+
return this.handleResponse(response);
|
|
7059
|
+
}
|
|
7060
|
+
async listWritable() {
|
|
7061
|
+
const response = await fetch(
|
|
7062
|
+
`${this.config.baseUrl}/api/v1/knowledge/list`,
|
|
7063
|
+
{
|
|
7064
|
+
headers: this.headers
|
|
6630
7065
|
}
|
|
6631
|
-
|
|
6632
|
-
|
|
6633
|
-
lines.push(content.join("\n"));
|
|
6634
|
-
lines.push("");
|
|
6635
|
-
}
|
|
6636
|
-
return lines.join("\n");
|
|
7066
|
+
);
|
|
7067
|
+
return this.handleResponse(response);
|
|
6637
7068
|
}
|
|
6638
|
-
async
|
|
6639
|
-
const
|
|
6640
|
-
|
|
6641
|
-
|
|
7069
|
+
async create(form) {
|
|
7070
|
+
const response = await fetch(
|
|
7071
|
+
`${this.config.baseUrl}/api/v1/knowledge/create`,
|
|
7072
|
+
{
|
|
7073
|
+
body: JSON.stringify(form),
|
|
7074
|
+
headers: this.jsonHeaders,
|
|
7075
|
+
method: "POST"
|
|
6642
7076
|
}
|
|
6643
7077
|
);
|
|
6644
|
-
|
|
6645
|
-
|
|
6646
|
-
|
|
6647
|
-
|
|
6648
|
-
|
|
7078
|
+
return this.handleResponse(response);
|
|
7079
|
+
}
|
|
7080
|
+
async reindex() {
|
|
7081
|
+
const response = await fetch(
|
|
7082
|
+
`${this.config.baseUrl}/api/v1/knowledge/reindex`,
|
|
7083
|
+
{
|
|
7084
|
+
headers: this.jsonHeaders,
|
|
7085
|
+
method: "POST"
|
|
7086
|
+
}
|
|
6649
7087
|
);
|
|
6650
|
-
|
|
7088
|
+
return this.handleResponse(response);
|
|
6651
7089
|
}
|
|
6652
|
-
async
|
|
6653
|
-
const
|
|
6654
|
-
|
|
6655
|
-
|
|
6656
|
-
|
|
6657
|
-
|
|
6658
|
-
let totalSize = 0;
|
|
6659
|
-
const entries = [];
|
|
6660
|
-
await Promise.all(
|
|
6661
|
-
extraFiles.map(async (extraFile) => {
|
|
6662
|
-
let contents = extraFile.contents;
|
|
6663
|
-
if (extraFile.processAsMdx) {
|
|
6664
|
-
const removeJsxProcessor = unified4().use(remarkParse4).use(remarkMdx3).use(remarkFrontmatter2, ["yaml"]).use(remarkRemoveJsx).use(this.transformRelativeUrls()).use(remarkStringify3);
|
|
6665
|
-
contents = String(await removeJsxProcessor.process(contents));
|
|
6666
|
-
}
|
|
6667
|
-
const lines = [];
|
|
6668
|
-
if (metadata.length) {
|
|
6669
|
-
lines.push("---");
|
|
6670
|
-
for (const [key, value] of metadata) {
|
|
6671
|
-
lines.push(`${key}: ${value}`);
|
|
6672
|
-
}
|
|
6673
|
-
lines.push("---");
|
|
6674
|
-
lines.push("");
|
|
6675
|
-
}
|
|
6676
|
-
if (extraFile.title) {
|
|
6677
|
-
lines.push(`# ${extraFile.title}`);
|
|
6678
|
-
lines.push("");
|
|
6679
|
-
}
|
|
6680
|
-
lines.push(contents);
|
|
6681
|
-
lines.push("");
|
|
6682
|
-
const fileContent = lines.join("\n");
|
|
6683
|
-
const fileName = `${kebabCase(extraFile.id)}.md`;
|
|
6684
|
-
const outfile = `${resolve4(this.config.outputPath)}/${fileName}`;
|
|
6685
|
-
await writeFile3(outfile, fileContent, "utf-8");
|
|
6686
|
-
const stats = await stat(outfile);
|
|
6687
|
-
totalSize += stats.size / 1024;
|
|
6688
|
-
entries.push({
|
|
6689
|
-
id: extraFile.id,
|
|
6690
|
-
md5: computeMd5(fileContent),
|
|
6691
|
-
path: fileName,
|
|
6692
|
-
size: stats.size,
|
|
6693
|
-
title: extraFile.title || extraFile.id
|
|
6694
|
-
});
|
|
6695
|
-
})
|
|
7090
|
+
async getById(id) {
|
|
7091
|
+
const response = await fetch(
|
|
7092
|
+
`${this.config.baseUrl}/api/v1/knowledge/${id}`,
|
|
7093
|
+
{
|
|
7094
|
+
headers: this.headers
|
|
7095
|
+
}
|
|
6696
7096
|
);
|
|
6697
|
-
return
|
|
6698
|
-
count: extraFiles.length,
|
|
6699
|
-
duration: performance.now() - start,
|
|
6700
|
-
entries,
|
|
6701
|
-
totalSize
|
|
6702
|
-
};
|
|
7097
|
+
return this.handleResponse(response);
|
|
6703
7098
|
}
|
|
6704
|
-
async
|
|
6705
|
-
const
|
|
6706
|
-
|
|
6707
|
-
|
|
7099
|
+
async update(id, form) {
|
|
7100
|
+
const response = await fetch(
|
|
7101
|
+
`${this.config.baseUrl}/api/v1/knowledge/${id}/update`,
|
|
7102
|
+
{
|
|
7103
|
+
body: JSON.stringify(form),
|
|
7104
|
+
headers: this.jsonHeaders,
|
|
7105
|
+
method: "POST"
|
|
6708
7106
|
}
|
|
6709
7107
|
);
|
|
6710
|
-
|
|
6711
|
-
|
|
6712
|
-
|
|
6713
|
-
await
|
|
6714
|
-
|
|
6715
|
-
|
|
6716
|
-
|
|
6717
|
-
|
|
6718
|
-
|
|
6719
|
-
|
|
6720
|
-
}
|
|
6721
|
-
for (const [key, value] of metadata) {
|
|
6722
|
-
frontmatterEntries.push([key, value]);
|
|
6723
|
-
}
|
|
6724
|
-
if (this.config.frontmatterFields) {
|
|
6725
|
-
if (typeof this.config.frontmatterFields === "function") {
|
|
6726
|
-
const transformed = this.config.frontmatterFields(
|
|
6727
|
-
processedPage.frontmatter,
|
|
6728
|
-
page
|
|
6729
|
-
);
|
|
6730
|
-
for (const [key, value] of Object.entries(transformed)) {
|
|
6731
|
-
if (value !== void 0) {
|
|
6732
|
-
frontmatterEntries.push([key, String(value)]);
|
|
6733
|
-
}
|
|
6734
|
-
}
|
|
6735
|
-
} else {
|
|
6736
|
-
for (const field of this.config.frontmatterFields) {
|
|
6737
|
-
const value = processedPage.frontmatter[field];
|
|
6738
|
-
if (value !== void 0) {
|
|
6739
|
-
frontmatterEntries.push([field, String(value)]);
|
|
6740
|
-
}
|
|
6741
|
-
}
|
|
6742
|
-
}
|
|
6743
|
-
}
|
|
6744
|
-
if (frontmatterEntries.length > 0) {
|
|
6745
|
-
lines.push("---");
|
|
6746
|
-
for (const [key, value] of frontmatterEntries) {
|
|
6747
|
-
lines.push(`${key}: ${value}`);
|
|
6748
|
-
}
|
|
6749
|
-
lines.push("---");
|
|
6750
|
-
lines.push("");
|
|
6751
|
-
}
|
|
6752
|
-
lines.push(`# ${processedPage.title}`);
|
|
6753
|
-
lines.push("");
|
|
6754
|
-
if (processedPage.frontmatter?.title) {
|
|
6755
|
-
page.name = processedPage.frontmatter.title;
|
|
6756
|
-
}
|
|
6757
|
-
let content = processedPage.content;
|
|
6758
|
-
content = content.replace(
|
|
6759
|
-
new RegExp(`^# ${processedPage.title}\\n+`, ""),
|
|
6760
|
-
""
|
|
6761
|
-
);
|
|
6762
|
-
if (this.config.pageTitlePrefix) {
|
|
6763
|
-
content = content.replace(
|
|
6764
|
-
`# ${page.name}`,
|
|
6765
|
-
`# ${this.config.pageTitlePrefix} ${page.name}`
|
|
6766
|
-
);
|
|
6767
|
-
page.name = `${this.config.pageTitlePrefix} ${page.name}`;
|
|
6768
|
-
}
|
|
6769
|
-
lines.push(content);
|
|
6770
|
-
lines.push("");
|
|
6771
|
-
if (processedPage.demoFiles.length > 0) {
|
|
6772
|
-
if (this.config.verbose) {
|
|
6773
|
-
console.log(
|
|
6774
|
-
`Collecting imports for ${page.name} from ${processedPage.demoFiles.length} demo files`
|
|
6775
|
-
);
|
|
6776
|
-
}
|
|
6777
|
-
const allImports = [];
|
|
6778
|
-
for (const demoFile of processedPage.demoFiles) {
|
|
6779
|
-
const imports = await this.collectRelativeImports(
|
|
6780
|
-
demoFile,
|
|
6781
|
-
/* @__PURE__ */ new Set()
|
|
6782
|
-
);
|
|
6783
|
-
allImports.push(...imports);
|
|
6784
|
-
}
|
|
6785
|
-
const uniqueImports = Array.from(
|
|
6786
|
-
new Map(allImports.map((m) => [m.path, m])).values()
|
|
6787
|
-
);
|
|
6788
|
-
if (this.config.verbose) {
|
|
6789
|
-
console.log(
|
|
6790
|
-
` Collected ${uniqueImports.length} unique import modules`
|
|
6791
|
-
);
|
|
6792
|
-
}
|
|
6793
|
-
if (uniqueImports.length > 0) {
|
|
6794
|
-
lines.push("## Related Source Files");
|
|
6795
|
-
lines.push("");
|
|
6796
|
-
for (const importedModule of uniqueImports) {
|
|
6797
|
-
const ext = extname(importedModule.path).slice(1);
|
|
6798
|
-
lines.push(`### ${basename(importedModule.path)}`);
|
|
6799
|
-
lines.push("");
|
|
6800
|
-
lines.push(`\`\`\`${ext}`);
|
|
6801
|
-
lines.push(importedModule.content);
|
|
6802
|
-
lines.push("```");
|
|
6803
|
-
lines.push("");
|
|
6804
|
-
}
|
|
6805
|
-
}
|
|
6806
|
-
}
|
|
6807
|
-
const fileContent = lines.join("\n");
|
|
6808
|
-
const fileName = `${kebabCase(page.id || page.name)}.md`;
|
|
6809
|
-
const outfile = `${resolve4(this.config.outputPath)}/${fileName}`;
|
|
6810
|
-
await writeFile3(outfile, fileContent, "utf-8");
|
|
6811
|
-
const stats = await stat(outfile);
|
|
6812
|
-
totalSize += stats.size / 1024;
|
|
6813
|
-
manifestEntries.push({
|
|
6814
|
-
id: page.id || kebabCase(page.name),
|
|
6815
|
-
md5: computeMd5(fileContent),
|
|
6816
|
-
path: fileName,
|
|
6817
|
-
size: stats.size,
|
|
6818
|
-
title: processedPage.title,
|
|
6819
|
-
url: page.url
|
|
6820
|
-
});
|
|
6821
|
-
})
|
|
7108
|
+
return this.handleResponse(response);
|
|
7109
|
+
}
|
|
7110
|
+
async addFile(knowledgeId, fileId) {
|
|
7111
|
+
const response = await fetch(
|
|
7112
|
+
`${this.config.baseUrl}/api/v1/knowledge/${knowledgeId}/file/add`,
|
|
7113
|
+
{
|
|
7114
|
+
body: JSON.stringify({ file_id: fileId }),
|
|
7115
|
+
headers: this.jsonHeaders,
|
|
7116
|
+
method: "POST"
|
|
7117
|
+
}
|
|
6822
7118
|
);
|
|
6823
|
-
|
|
6824
|
-
|
|
6825
|
-
|
|
6826
|
-
|
|
6827
|
-
|
|
6828
|
-
|
|
6829
|
-
|
|
6830
|
-
|
|
7119
|
+
return this.handleResponse(response);
|
|
7120
|
+
}
|
|
7121
|
+
async updateFile(knowledgeId, fileId) {
|
|
7122
|
+
const response = await fetch(
|
|
7123
|
+
`${this.config.baseUrl}/api/v1/knowledge/${knowledgeId}/file/update`,
|
|
7124
|
+
{
|
|
7125
|
+
body: JSON.stringify({ file_id: fileId }),
|
|
7126
|
+
headers: this.jsonHeaders,
|
|
7127
|
+
method: "POST"
|
|
6831
7128
|
}
|
|
6832
|
-
|
|
6833
|
-
|
|
6834
|
-
|
|
6835
|
-
|
|
6836
|
-
|
|
7129
|
+
);
|
|
7130
|
+
return this.handleResponse(response);
|
|
7131
|
+
}
|
|
7132
|
+
async removeFile(knowledgeId, fileId, deleteFile = true) {
|
|
7133
|
+
const params = new URLSearchParams({ delete_file: String(deleteFile) });
|
|
7134
|
+
const response = await fetch(
|
|
7135
|
+
`${this.config.baseUrl}/api/v1/knowledge/${knowledgeId}/file/remove?${params}`,
|
|
7136
|
+
{
|
|
7137
|
+
body: JSON.stringify({ file_id: fileId }),
|
|
7138
|
+
headers: this.jsonHeaders,
|
|
7139
|
+
method: "POST"
|
|
6837
7140
|
}
|
|
6838
|
-
}
|
|
6839
|
-
console.log(
|
|
6840
|
-
`Generated ${count + extraFilesResult.count} files(s) in ${chalk3.magenta.bold(`${Math.round(performance.now() - start + extraFilesResult.duration)}ms`)} at ${chalk3.blue.bold(this.config.outputPath)} - ${(totalSize + extraFilesResult.totalSize).toFixed(1)} KB`
|
|
6841
7141
|
);
|
|
7142
|
+
return this.handleResponse(response);
|
|
6842
7143
|
}
|
|
6843
|
-
|
|
6844
|
-
const
|
|
6845
|
-
|
|
7144
|
+
async delete(id) {
|
|
7145
|
+
const response = await fetch(
|
|
7146
|
+
`${this.config.baseUrl}/api/v1/knowledge/${id}/delete`,
|
|
7147
|
+
{
|
|
7148
|
+
headers: this.headers,
|
|
7149
|
+
method: "DELETE"
|
|
7150
|
+
}
|
|
7151
|
+
);
|
|
7152
|
+
return this.handleResponse(response);
|
|
6846
7153
|
}
|
|
6847
|
-
async
|
|
6848
|
-
const
|
|
6849
|
-
|
|
6850
|
-
|
|
6851
|
-
|
|
6852
|
-
|
|
6853
|
-
|
|
6854
|
-
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6855
|
-
totalFiles: entries.length,
|
|
6856
|
-
totalSize,
|
|
6857
|
-
version: 1
|
|
6858
|
-
};
|
|
6859
|
-
await mkdir2(outputPath, { recursive: true }).catch(() => {
|
|
6860
|
-
});
|
|
6861
|
-
await writeFile3(
|
|
6862
|
-
join3(outputPath, "manifest.json"),
|
|
6863
|
-
JSON.stringify(manifest, null, 2),
|
|
6864
|
-
"utf-8"
|
|
7154
|
+
async reset(id) {
|
|
7155
|
+
const response = await fetch(
|
|
7156
|
+
`${this.config.baseUrl}/api/v1/knowledge/${id}/reset`,
|
|
7157
|
+
{
|
|
7158
|
+
headers: this.jsonHeaders,
|
|
7159
|
+
method: "POST"
|
|
7160
|
+
}
|
|
6865
7161
|
);
|
|
6866
|
-
return
|
|
7162
|
+
return this.handleResponse(response);
|
|
6867
7163
|
}
|
|
6868
|
-
async
|
|
6869
|
-
|
|
6870
|
-
|
|
6871
|
-
|
|
6872
|
-
|
|
6873
|
-
|
|
6874
|
-
|
|
6875
|
-
|
|
6876
|
-
|
|
6877
|
-
|
|
6878
|
-
zip.writeZip(zipPath);
|
|
7164
|
+
async addFilesBatch(knowledgeId, fileIds) {
|
|
7165
|
+
const response = await fetch(
|
|
7166
|
+
`${this.config.baseUrl}/api/v1/knowledge/${knowledgeId}/files/batch/add`,
|
|
7167
|
+
{
|
|
7168
|
+
body: JSON.stringify(fileIds.map((file_id) => ({ file_id }))),
|
|
7169
|
+
headers: this.jsonHeaders,
|
|
7170
|
+
method: "POST"
|
|
7171
|
+
}
|
|
7172
|
+
);
|
|
7173
|
+
return this.handleResponse(response);
|
|
6879
7174
|
}
|
|
6880
7175
|
};
|
|
6881
|
-
|
|
6882
|
-
|
|
6883
|
-
|
|
6884
|
-
|
|
6885
|
-
function addGenerateKnowledgeCommand() {
|
|
6886
|
-
program.description("Generate llms.txt from QUI Docs documentation").command("generate-llms-txt").option("-n, --name <name>", "Project name for llms.txt header").requiredOption("-m, --output-mode <outputMode>").option("-o, --outputPath <outputPath>", "Output file or directory.").option(
|
|
6887
|
-
"-d, --description <description>",
|
|
6888
|
-
"Project description for llms.txt"
|
|
6889
|
-
).option("-v, --verbose", "Enable verbose logging", false).option(
|
|
6890
|
-
"--exclude <patterns...>",
|
|
6891
|
-
"Glob patterns to exclude (e.g., **/internal/**, guide/drafts/*)",
|
|
6892
|
-
[]
|
|
6893
|
-
).option("--base-url <url>", "Base URL for component documentation links").option("--metadata <pairs...>", "metadata key-value pairs").option("--clean", "Clean the output path before generating").option("--include-imports", "Include relative import source files", true).option(
|
|
6894
|
-
"-e, --environment <environments>",
|
|
6895
|
-
"Comma-separated list of environments to generate (default: all)"
|
|
6896
|
-
).action(async (options) => {
|
|
7176
|
+
|
|
7177
|
+
// src/ai-knowledge/open-web-ui/download-knowledge.ts
|
|
7178
|
+
function addDownloadKnowledgeCommand() {
|
|
7179
|
+
program.command("download-knowledge").description("Download files from an Open Web UI knowledge base").requiredOption("-o, --output-dir <outputDir>", "Folder path").requiredOption("-e, --environment <environments>", "environment to load").action(async (opts) => {
|
|
6897
7180
|
loadEnv();
|
|
6898
|
-
const
|
|
6899
|
-
|
|
6900
|
-
|
|
6901
|
-
|
|
6902
|
-
const
|
|
6903
|
-
const
|
|
6904
|
-
|
|
6905
|
-
|
|
6906
|
-
|
|
6907
|
-
|
|
6908
|
-
|
|
6909
|
-
|
|
6910
|
-
|
|
6911
|
-
|
|
6912
|
-
|
|
6913
|
-
|
|
6914
|
-
|
|
6915
|
-
|
|
6916
|
-
|
|
7181
|
+
const env = opts.environment;
|
|
7182
|
+
dotenv.config({ path: `.env.${env}` });
|
|
7183
|
+
await mkdir2(opts.outputDir, { recursive: true }).catch();
|
|
7184
|
+
const config3 = getConfigFromEnv();
|
|
7185
|
+
const apiConfig = { apiKey: config3.webUiKey, baseUrl: config3.webUiUrl };
|
|
7186
|
+
const knowledgeApi = new KnowledgeApi(apiConfig);
|
|
7187
|
+
const filesApi = new FilesApi(apiConfig);
|
|
7188
|
+
const knowledge = await knowledgeApi.getById(config3.knowledgeId);
|
|
7189
|
+
for (const file of knowledge.files ?? []) {
|
|
7190
|
+
const fileName = file.meta?.name;
|
|
7191
|
+
if (!fileName) {
|
|
7192
|
+
continue;
|
|
7193
|
+
}
|
|
7194
|
+
try {
|
|
7195
|
+
const content = await filesApi.getDataContent(file.id);
|
|
7196
|
+
if (content?.content) {
|
|
7197
|
+
await writeFile2(
|
|
7198
|
+
resolve5(opts.outputDir, fileName),
|
|
7199
|
+
content.content,
|
|
7200
|
+
"utf-8"
|
|
7201
|
+
);
|
|
7202
|
+
}
|
|
7203
|
+
} catch {
|
|
7204
|
+
console.warn(`Failed to download ${fileName}`);
|
|
7205
|
+
}
|
|
6917
7206
|
}
|
|
6918
7207
|
});
|
|
6919
7208
|
}
|
|
6920
7209
|
|
|
6921
|
-
// src/open-web-ui
|
|
7210
|
+
// src/ai-knowledge/open-web-ui/upload-knowledge.ts
|
|
6922
7211
|
import { createHash as createHash3 } from "node:crypto";
|
|
6923
7212
|
import { writeFileSync } from "node:fs";
|
|
6924
|
-
import { access as access2, readdir as readdir2, readFile as
|
|
6925
|
-
import { resolve as
|
|
7213
|
+
import { access as access2, readdir as readdir2, readFile as readFile5, stat as stat2 } from "node:fs/promises";
|
|
7214
|
+
import { resolve as resolve6 } from "node:path";
|
|
6926
7215
|
import { setTimeout as setTimeout2 } from "node:timers/promises";
|
|
6927
7216
|
import ora from "ora";
|
|
6928
7217
|
|
|
6929
|
-
// src/open-web-ui
|
|
7218
|
+
// src/ai-knowledge/open-web-ui/common.ts
|
|
7219
|
+
import { config as config2 } from "dotenv";
|
|
7220
|
+
function loadOpenWebUiEnv(integration, integrationName) {
|
|
7221
|
+
const envFilePath = integration.envFile ?? `.env.${integration.id}`;
|
|
7222
|
+
config2({ override: true, path: envFilePath, quiet: true });
|
|
7223
|
+
const url = process.env.OPEN_WEB_UI_URL ?? process.env.WEB_UI_URL;
|
|
7224
|
+
const apiKey = process.env.OPEN_WEB_UI_API_KEY ?? process.env.WEB_UI_KEY;
|
|
7225
|
+
const knowledgeId = process.env.OPEN_WEB_UI_KNOWLEDGE_ID ?? process.env.KNOWLEDGE_ID;
|
|
7226
|
+
if (!url) {
|
|
7227
|
+
throw new Error(
|
|
7228
|
+
`Missing OPEN_WEB_UI_URL for integration "${integrationName}" (env file: ${envFilePath})`
|
|
7229
|
+
);
|
|
7230
|
+
}
|
|
7231
|
+
if (!apiKey) {
|
|
7232
|
+
throw new Error(
|
|
7233
|
+
`Missing OPEN_WEB_UI_API_KEY for integration "${integrationName}" (env file: ${envFilePath})`
|
|
7234
|
+
);
|
|
7235
|
+
}
|
|
7236
|
+
if (!knowledgeId) {
|
|
7237
|
+
throw new Error(
|
|
7238
|
+
`Missing OPEN_WEB_UI_KNOWLEDGE_ID for integration "${integrationName}" (env file: ${envFilePath})`
|
|
7239
|
+
);
|
|
7240
|
+
}
|
|
7241
|
+
return { apiKey, knowledgeId, url };
|
|
7242
|
+
}
|
|
7243
|
+
function resolveOpenWebUiIntegration(name, integration, outputPath) {
|
|
7244
|
+
const credentials = loadOpenWebUiEnv(integration, name);
|
|
7245
|
+
return {
|
|
7246
|
+
apiKey: credentials.apiKey,
|
|
7247
|
+
environment: integration.id,
|
|
7248
|
+
knowledgeId: credentials.knowledgeId,
|
|
7249
|
+
name,
|
|
7250
|
+
outputPath,
|
|
7251
|
+
url: credentials.url
|
|
7252
|
+
};
|
|
7253
|
+
}
|
|
7254
|
+
function loadOpenWebUiIntegrations(options = {}) {
|
|
7255
|
+
const configLoader = new ConfigLoader({});
|
|
7256
|
+
const resolvedConfig = configLoader.loadConfig();
|
|
7257
|
+
const knowledgeConfig = resolvedConfig.knowledge;
|
|
7258
|
+
const environments = knowledgeConfig?.environments;
|
|
7259
|
+
const integrations = knowledgeConfig?.integrations?.openWebUi;
|
|
7260
|
+
if (!integrations || integrations.length === 0) {
|
|
7261
|
+
return [];
|
|
7262
|
+
}
|
|
7263
|
+
let filteredIntegrations = integrations;
|
|
7264
|
+
if (options.integrations?.length) {
|
|
7265
|
+
const filterSet = new Set(options.integrations);
|
|
7266
|
+
filteredIntegrations = integrations.filter(
|
|
7267
|
+
(integration) => filterSet.has(integration.id)
|
|
7268
|
+
);
|
|
7269
|
+
}
|
|
7270
|
+
if (options.environments?.length) {
|
|
7271
|
+
const filterSet = new Set(options.environments);
|
|
7272
|
+
filteredIntegrations = filteredIntegrations.filter(
|
|
7273
|
+
(integration) => filterSet.has(integration.id)
|
|
7274
|
+
);
|
|
7275
|
+
}
|
|
7276
|
+
return filteredIntegrations.map((integration) => {
|
|
7277
|
+
const envConfig = environments?.find((e) => e.id === integration.id);
|
|
7278
|
+
if (!envConfig) {
|
|
7279
|
+
throw new Error(
|
|
7280
|
+
`Integration "${integration.id}" references unknown environment "${integration.id}". Available environments: ${environments?.map((e) => e.id).join(", ") || "none"}`
|
|
7281
|
+
);
|
|
7282
|
+
}
|
|
7283
|
+
return {
|
|
7284
|
+
integration,
|
|
7285
|
+
name: integration.id,
|
|
7286
|
+
outputPath: envConfig.outputPath
|
|
7287
|
+
};
|
|
7288
|
+
});
|
|
7289
|
+
}
|
|
7290
|
+
|
|
7291
|
+
// src/ai-knowledge/open-web-ui/knowledge-cleaner.ts
|
|
6930
7292
|
var KnowledgeCleaner = class {
|
|
6931
7293
|
filesApi;
|
|
6932
7294
|
knowledgeApi;
|
|
6933
|
-
constructor(
|
|
7295
|
+
constructor(config3) {
|
|
6934
7296
|
const apiConfig = {
|
|
6935
|
-
apiKey:
|
|
6936
|
-
baseUrl:
|
|
7297
|
+
apiKey: config3.webUiKey,
|
|
7298
|
+
baseUrl: config3.webUiUrl
|
|
6937
7299
|
};
|
|
6938
7300
|
this.filesApi = new FilesApi(apiConfig);
|
|
6939
7301
|
this.knowledgeApi = new KnowledgeApi(apiConfig);
|
|
@@ -6953,7 +7315,7 @@ var KnowledgeCleaner = class {
|
|
|
6953
7315
|
}
|
|
6954
7316
|
};
|
|
6955
7317
|
|
|
6956
|
-
// src/open-web-ui
|
|
7318
|
+
// src/ai-knowledge/open-web-ui/upload-knowledge.ts
|
|
6957
7319
|
function toKnowledgeFile(file) {
|
|
6958
7320
|
return {
|
|
6959
7321
|
id: file.id,
|
|
@@ -6971,15 +7333,15 @@ var Uploader = class {
|
|
|
6971
7333
|
fileHashCache = /* @__PURE__ */ new Map();
|
|
6972
7334
|
knowledgeFilesCache = null;
|
|
6973
7335
|
cleaner;
|
|
6974
|
-
constructor(
|
|
6975
|
-
this.config =
|
|
7336
|
+
constructor(config3) {
|
|
7337
|
+
this.config = config3;
|
|
6976
7338
|
const apiConfig = {
|
|
6977
|
-
apiKey:
|
|
6978
|
-
baseUrl:
|
|
7339
|
+
apiKey: config3.webUiKey,
|
|
7340
|
+
baseUrl: config3.webUiUrl
|
|
6979
7341
|
};
|
|
6980
7342
|
this.knowledgeApi = new KnowledgeApi(apiConfig);
|
|
6981
7343
|
this.filesApi = new FilesApi(apiConfig);
|
|
6982
|
-
this.cleaner = new KnowledgeCleaner(
|
|
7344
|
+
this.cleaner = new KnowledgeCleaner(config3);
|
|
6983
7345
|
}
|
|
6984
7346
|
async buildHashCache(files) {
|
|
6985
7347
|
const results = await Promise.allSettled(
|
|
@@ -7048,11 +7410,15 @@ var Uploader = class {
|
|
|
7048
7410
|
return { success: false };
|
|
7049
7411
|
}
|
|
7050
7412
|
async uploadDirectory() {
|
|
7051
|
-
const
|
|
7413
|
+
const allFileNames = await readdir2(this.config.knowledgeFilePath);
|
|
7414
|
+
const allowedExtensions = [".md", ".mdx", ".txt", ".pdf"];
|
|
7415
|
+
const fileNames = allFileNames.filter(
|
|
7416
|
+
(name) => allowedExtensions.some((ext) => name.endsWith(ext))
|
|
7417
|
+
);
|
|
7052
7418
|
const files = await Promise.all(
|
|
7053
7419
|
fileNames.map(async (name) => ({
|
|
7054
|
-
contents: await
|
|
7055
|
-
|
|
7420
|
+
contents: await readFile5(
|
|
7421
|
+
resolve6(this.config.knowledgeFilePath, name),
|
|
7056
7422
|
"utf-8"
|
|
7057
7423
|
),
|
|
7058
7424
|
name
|
|
@@ -7103,8 +7469,8 @@ var Uploader = class {
|
|
|
7103
7469
|
if (knowledgeFile) {
|
|
7104
7470
|
try {
|
|
7105
7471
|
const fileId = knowledgeFile.id;
|
|
7106
|
-
const fileString = await
|
|
7107
|
-
|
|
7472
|
+
const fileString = await readFile5(
|
|
7473
|
+
resolve6(this.config.knowledgeFilePath, name),
|
|
7108
7474
|
"utf-8"
|
|
7109
7475
|
);
|
|
7110
7476
|
const spinner2 = ora(`Updating ${name}`).start();
|
|
@@ -7118,8 +7484,8 @@ var Uploader = class {
|
|
|
7118
7484
|
}
|
|
7119
7485
|
}
|
|
7120
7486
|
const spinner = ora(`Uploading ${name}`).start();
|
|
7121
|
-
const fileBuffer = await
|
|
7122
|
-
|
|
7487
|
+
const fileBuffer = await readFile5(
|
|
7488
|
+
resolve6(this.config.knowledgeFilePath, name)
|
|
7123
7489
|
);
|
|
7124
7490
|
let uploadedFileId = void 0;
|
|
7125
7491
|
try {
|
|
@@ -7157,7 +7523,7 @@ var Uploader = class {
|
|
|
7157
7523
|
}
|
|
7158
7524
|
}
|
|
7159
7525
|
async uploadKnowledge() {
|
|
7160
|
-
const resolvedPath =
|
|
7526
|
+
const resolvedPath = resolve6(this.config.knowledgeFilePath);
|
|
7161
7527
|
if (!await access2(resolvedPath).then(() => true).catch(() => false)) {
|
|
7162
7528
|
throw new Error(`File or folder not found at ${resolvedPath}`);
|
|
7163
7529
|
}
|
|
@@ -7244,7 +7610,7 @@ Uploaded to ${successCount} integration(s)${failureCount > 0 ? `, ${failureCount
|
|
|
7244
7610
|
const files = await uploader.filesApi.search("*");
|
|
7245
7611
|
console.debug(`found ${files.length} files`);
|
|
7246
7612
|
writeFileSync(
|
|
7247
|
-
|
|
7613
|
+
resolve6(uploader.config.knowledgeFilePath, "files.json"),
|
|
7248
7614
|
JSON.stringify(files, null, 2),
|
|
7249
7615
|
"utf-8"
|
|
7250
7616
|
);
|
|
@@ -7286,18 +7652,72 @@ Uploaded to ${successCount} integration(s)${failureCount > 0 ? `, ${failureCount
|
|
|
7286
7652
|
});
|
|
7287
7653
|
}
|
|
7288
7654
|
|
|
7655
|
+
// src/docs-plugin/generate-page-map.ts
|
|
7656
|
+
import { glob } from "glob";
|
|
7657
|
+
import { writeFile as writeFile3 } from "node:fs/promises";
|
|
7658
|
+
import { resolve as resolve7 } from "node:path";
|
|
7659
|
+
import { cwd } from "node:process";
|
|
7660
|
+
function addGeneratePageMapCommand() {
|
|
7661
|
+
program.command("generate-page-map").description(
|
|
7662
|
+
"Invokes the docs-plugin once to build the site data and writes it to json"
|
|
7663
|
+
).option(
|
|
7664
|
+
"-c, --config-file <configFile>",
|
|
7665
|
+
"Path to the qui-docs.config.ts config file"
|
|
7666
|
+
).option(
|
|
7667
|
+
"-r, --routes-dir <routesDir>",
|
|
7668
|
+
"Path to the routes directory",
|
|
7669
|
+
"src/routes"
|
|
7670
|
+
).option(
|
|
7671
|
+
"-o, --output <output>",
|
|
7672
|
+
"Output path for the site data json",
|
|
7673
|
+
"site-data.json"
|
|
7674
|
+
).action(async (options) => {
|
|
7675
|
+
try {
|
|
7676
|
+
const configLoader = new ConfigLoader({ configFile: options.configFile });
|
|
7677
|
+
const resolvedConfig = configLoader.loadConfig();
|
|
7678
|
+
const routesDir = fixPath(
|
|
7679
|
+
resolve7(resolvedConfig.appDirectory, resolvedConfig.pageDirectory)
|
|
7680
|
+
);
|
|
7681
|
+
const indexer = new SearchIndexer({
|
|
7682
|
+
...resolvedConfig,
|
|
7683
|
+
srcDir: fixPath(resolve7(cwd(), resolvedConfig.appDirectory)),
|
|
7684
|
+
typeDocProps: {}
|
|
7685
|
+
});
|
|
7686
|
+
const files = glob.sync(
|
|
7687
|
+
[`${routesDir}/**/*.mdx`, `${routesDir}/**/*.tsx`],
|
|
7688
|
+
{
|
|
7689
|
+
absolute: true,
|
|
7690
|
+
cwd: cwd()
|
|
7691
|
+
}
|
|
7692
|
+
);
|
|
7693
|
+
indexer.buildIndex(files, true);
|
|
7694
|
+
await writeFile3(
|
|
7695
|
+
resolve7(cwd(), options.output),
|
|
7696
|
+
JSON.stringify(indexer.pageMap, null, 2),
|
|
7697
|
+
"utf-8"
|
|
7698
|
+
);
|
|
7699
|
+
} catch (error) {
|
|
7700
|
+
console.error(
|
|
7701
|
+
"Generate Site Data Error:",
|
|
7702
|
+
error instanceof Error ? error.message : String(error)
|
|
7703
|
+
);
|
|
7704
|
+
process.exit(1);
|
|
7705
|
+
}
|
|
7706
|
+
});
|
|
7707
|
+
}
|
|
7708
|
+
|
|
7289
7709
|
// src/react-demo-plugin/generate-lazy-demo-map.ts
|
|
7290
7710
|
import { glob as glob2 } from "glob";
|
|
7291
7711
|
import { uniqBy } from "lodash-es";
|
|
7292
7712
|
import { writeFile as writeFile4 } from "node:fs/promises";
|
|
7293
|
-
import { resolve as
|
|
7713
|
+
import { resolve as resolve9 } from "node:path";
|
|
7294
7714
|
import { dedent } from "@qualcomm-ui/utils/dedent";
|
|
7295
7715
|
|
|
7296
7716
|
// src/react-demo-plugin/demo-plugin-utils.ts
|
|
7297
7717
|
import chalk4 from "chalk";
|
|
7298
7718
|
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "node:fs";
|
|
7299
|
-
import { dirname as
|
|
7300
|
-
import * as
|
|
7719
|
+
import { dirname as dirname4, join as join7, relative as relative3, resolve as resolve8, sep } from "node:path";
|
|
7720
|
+
import * as ts2 from "typescript";
|
|
7301
7721
|
import { pascalCase } from "@qualcomm-ui/utils/change-case";
|
|
7302
7722
|
function extractPageId(filePath, routesDir) {
|
|
7303
7723
|
const relativePath = relative3(routesDir, filePath);
|
|
@@ -7306,7 +7726,7 @@ function extractPageId(filePath, routesDir) {
|
|
|
7306
7726
|
const demosIndex = pathParts.indexOf("demos");
|
|
7307
7727
|
return pathParts.slice(0, demosIndex).join(sep);
|
|
7308
7728
|
}
|
|
7309
|
-
return
|
|
7729
|
+
return dirname4(relativePath);
|
|
7310
7730
|
}
|
|
7311
7731
|
function isDemoFile(filePath) {
|
|
7312
7732
|
try {
|
|
@@ -7353,7 +7773,7 @@ function generateLazyDemoLoader(demoPages) {
|
|
|
7353
7773
|
}
|
|
7354
7774
|
async function generateLazyDemoMap(options) {
|
|
7355
7775
|
const routesDir = options.routesDir;
|
|
7356
|
-
const outputPath =
|
|
7776
|
+
const outputPath = resolve9(options.output);
|
|
7357
7777
|
console.log(`Scanning for demo pages in: ${routesDir}`);
|
|
7358
7778
|
const demoPages = await scanForDemoPages({ routesDir });
|
|
7359
7779
|
console.log(`Found ${demoPages.length} pages with demos`);
|