silgi 0.7.0 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/build/framework/h3.mjs +46 -0
- package/dist/cli/build/framework/index.mjs +7 -0
- package/dist/cli/build/framework/nitro.mjs +28 -0
- package/dist/cli/build/framework/nuxt.mjs +9 -0
- package/dist/cli/build/prepare.mjs +7 -0
- package/dist/cli/build/scanURIs.mjs +27 -0
- package/dist/cli/build/template/framework.mjs +91 -0
- package/dist/cli/build/template/schema.mjs +115 -0
- package/dist/cli/build/template/silgi.mjs +149 -0
- package/dist/cli/build/types.mjs +130 -0
- package/dist/cli/commands/prepare.mjs +49 -0
- package/dist/cli/common.mjs +13 -0
- package/dist/cli/core/app.mjs +89 -0
- package/dist/cli/core/scan.mjs +40 -0
- package/dist/cli/core/silgi.mjs +77 -0
- package/dist/cli/core/storage.mjs +11 -0
- package/dist/cli/core/templates.mjs +29 -0
- package/dist/cli/index.mjs +3 -3
- package/dist/cli/module/exportScan.mjs +69 -0
- package/dist/cli/module/install.mjs +52 -0
- package/dist/cli/module/scan.mjs +141 -0
- package/dist/cli/{compatibility.mjs → utils/compatibility.mjs} +1 -1
- package/dist/cli/utils/generateRouterDTS.mjs +84 -0
- package/dist/cli/utils/ignore.mjs +46 -0
- package/dist/cli/utils/readCoreFile.mjs +47 -0
- package/dist/cli/utils/scan.mjs +147 -0
- package/dist/cli/utils/storage.mjs +21 -0
- package/dist/cli/utils/uri.mjs +71 -0
- package/dist/core/config/defaults.mjs +96 -0
- package/dist/core/config/loader.mjs +98 -0
- package/dist/core/config/resolvers/compatibility.mjs +90 -0
- package/dist/core/config/resolvers/imports.mjs +96 -0
- package/dist/core/config/resolvers/paths.mjs +194 -0
- package/dist/core/config/resolvers/storage.mjs +25 -0
- package/dist/core/config/resolvers/url.mjs +7 -0
- package/dist/core/config/types.mjs +160 -0
- package/dist/core/createSilgi.mjs +84 -0
- package/dist/core/error.mjs +227 -0
- package/dist/core/fetch/ofetch.mjs +35 -0
- package/dist/core/index.mjs +16 -1678
- package/dist/core/parser.mjs +136 -0
- package/dist/core/silgi.mjs +114 -0
- package/dist/core/silgiApp.mjs +15 -0
- package/dist/core/unctx.mjs +27 -0
- package/dist/core/uris/uri.mjs +33 -0
- package/dist/core/uris/utils.mjs +127 -0
- package/dist/core/utils/event.mjs +5 -0
- package/dist/core/utils/global.mjs +12 -0
- package/dist/core/utils/merge.mjs +25 -0
- package/dist/core/utils/schema.mjs +5 -0
- package/dist/core/utils/service.mjs +5 -0
- package/dist/core/utils/shared.mjs +5 -0
- package/dist/core/utils/storage.mjs +70 -0
- package/dist/ecosystem/nitro/index.mjs +1 -62
- package/dist/ecosystem/nitro/module.mjs +62 -0
- package/dist/kit/esm.mjs +10 -0
- package/dist/kit/fs.mjs +25 -0
- package/dist/kit/index.mjs +10 -299
- package/dist/kit/isFramework.mjs +25 -0
- package/dist/kit/logger.mjs +8 -0
- package/dist/kit/module.mjs +73 -0
- package/dist/kit/path.mjs +34 -0
- package/dist/kit/preset.mjs +6 -0
- package/dist/kit/resolve.mjs +78 -0
- package/dist/kit/template.mjs +47 -0
- package/dist/kit/utils.mjs +20 -0
- package/dist/meta/index.d.mts +1 -1
- package/dist/meta/index.d.ts +1 -1
- package/dist/meta/index.mjs +1 -1
- package/dist/package.json.mjs +5 -0
- package/dist/schema/common.mjs +43 -0
- package/dist/schema/index.mjs +9 -0
- package/dist/schema/internal.mjs +22 -0
- package/package.json +1 -1
- package/dist/_chunks/index.mjs +0 -5
- package/dist/cli/prepare.mjs +0 -1481
- /package/dist/cli/{init.mjs → commands/init.mjs} +0 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { mkdirSync, writeFileSync, promises } from 'node:fs';
|
|
2
|
+
import { resolve, dirname } from 'pathe';
|
|
3
|
+
import { normalizeTemplate, useLogger, relativeWithDot } from 'silgi/kit';
|
|
4
|
+
import * as templates from './templates.mjs';
|
|
5
|
+
import { pluginsDeclaration } from './templates.mjs';
|
|
6
|
+
|
|
7
|
+
const postTemplates = [
|
|
8
|
+
pluginsDeclaration.filename
|
|
9
|
+
];
|
|
10
|
+
const logger = useLogger("silgi");
|
|
11
|
+
async function generateApp(app, options = {}) {
|
|
12
|
+
app.templates = Object.values(templates).concat(app.options.build.templates);
|
|
13
|
+
await app.callHook("app:templates", app);
|
|
14
|
+
app.templates = app.templates.map((tmpl) => normalizeTemplate(tmpl, app.options.silgi.vfsDir));
|
|
15
|
+
const filteredTemplates = {
|
|
16
|
+
pre: [],
|
|
17
|
+
post: []
|
|
18
|
+
};
|
|
19
|
+
for (const template of app.templates) {
|
|
20
|
+
if (options.filter && !options.filter(template)) {
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
const key = template.filename && postTemplates.includes(template.filename) ? "post" : "pre";
|
|
24
|
+
filteredTemplates[key].push(template);
|
|
25
|
+
}
|
|
26
|
+
const templateContext = { app };
|
|
27
|
+
const writes = [];
|
|
28
|
+
const indexImports = [];
|
|
29
|
+
const dirs = /* @__PURE__ */ new Set();
|
|
30
|
+
const changedTemplates = [];
|
|
31
|
+
async function processTemplate(template) {
|
|
32
|
+
const fullPath = template.dst || resolve(app.options.silgi.vfsDir, template.filename);
|
|
33
|
+
const start = performance.now();
|
|
34
|
+
const contents = await compileTemplate(template, templateContext).catch((e) => {
|
|
35
|
+
logger.error(`Could not compile template \`${template.filename}\`.`);
|
|
36
|
+
logger.error(e);
|
|
37
|
+
throw e;
|
|
38
|
+
});
|
|
39
|
+
template.modified = true;
|
|
40
|
+
if (template.modified) {
|
|
41
|
+
changedTemplates.push(template);
|
|
42
|
+
}
|
|
43
|
+
const perf = performance.now() - start;
|
|
44
|
+
const setupTime = Math.round(perf * 100) / 100;
|
|
45
|
+
if (app.options.debug || setupTime > 500) {
|
|
46
|
+
logger.info(`Compiled \`${template.filename}\` in ${setupTime}ms`);
|
|
47
|
+
}
|
|
48
|
+
if (template.modified && template.write) {
|
|
49
|
+
dirs.add(dirname(fullPath));
|
|
50
|
+
if (!fullPath.endsWith(".d.ts")) {
|
|
51
|
+
indexImports.push(relativeWithDot(app.options.silgi.serverDir, fullPath));
|
|
52
|
+
}
|
|
53
|
+
writes.push(() => writeFileSync(fullPath, contents, "utf8"));
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
await Promise.allSettled(filteredTemplates.pre.map(processTemplate));
|
|
57
|
+
await Promise.allSettled(filteredTemplates.post.map(processTemplate));
|
|
58
|
+
for (const dir of dirs) {
|
|
59
|
+
mkdirSync(dir, { recursive: true });
|
|
60
|
+
}
|
|
61
|
+
for (const write of writes) {
|
|
62
|
+
write();
|
|
63
|
+
}
|
|
64
|
+
writeFileSync(resolve(app.options.silgi.serverDir, "index.ts"), `${indexImports.map((i) => `export * from '${i}'`).join("\n")}
|
|
65
|
+
`, "utf8");
|
|
66
|
+
if (changedTemplates.length) {
|
|
67
|
+
await app.callHook("app:templatesGenerated", app, changedTemplates, options);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
async function compileTemplate(template, ctx) {
|
|
71
|
+
delete ctx.utils;
|
|
72
|
+
if (template.src) {
|
|
73
|
+
try {
|
|
74
|
+
return await promises.readFile(template.src, "utf-8");
|
|
75
|
+
} catch (err) {
|
|
76
|
+
logger.error(`[nuxt] Error reading template from \`${template.src}\``);
|
|
77
|
+
throw err;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (template.getContents) {
|
|
81
|
+
return template.getContents({
|
|
82
|
+
...ctx,
|
|
83
|
+
options: template.options
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
throw new Error(`[nuxt] Invalid template. Templates must have either \`src\` or \`getContents\`: ${JSON.stringify(template)}`);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export { generateApp, logger };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { globby } from 'globby';
|
|
2
|
+
import { join, relative } from 'pathe';
|
|
3
|
+
import 'ufo';
|
|
4
|
+
|
|
5
|
+
const GLOB_SCAN_PATTERN = "**/*.{js,mjs,cjs,ts,mts,cts,tsx,jsx}";
|
|
6
|
+
async function scanAndSyncOptions(silgi) {
|
|
7
|
+
const scannedModules = await scanModules(silgi);
|
|
8
|
+
silgi.options.modules = silgi.options.modules || [];
|
|
9
|
+
for (const modPath of scannedModules) {
|
|
10
|
+
if (!silgi.options.modules.includes(modPath)) {
|
|
11
|
+
silgi.options.modules.push(modPath);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
async function scanModules(silgi) {
|
|
16
|
+
const files = await scanFiles(silgi, "silgi/modules");
|
|
17
|
+
return files.map((f) => f.fullPath);
|
|
18
|
+
}
|
|
19
|
+
async function scanFiles(silgi, name) {
|
|
20
|
+
const files = await Promise.all(
|
|
21
|
+
silgi.options.scanDirs.map((dir) => scanDir(silgi, dir, name))
|
|
22
|
+
).then((r) => r.flat());
|
|
23
|
+
return files;
|
|
24
|
+
}
|
|
25
|
+
async function scanDir(silgi, dir, name) {
|
|
26
|
+
const fileNames = await globby(join(name, GLOB_SCAN_PATTERN), {
|
|
27
|
+
cwd: dir,
|
|
28
|
+
dot: true,
|
|
29
|
+
ignore: silgi.options.ignore,
|
|
30
|
+
absolute: true
|
|
31
|
+
});
|
|
32
|
+
return fileNames.map((fullPath) => {
|
|
33
|
+
return {
|
|
34
|
+
fullPath,
|
|
35
|
+
path: relative(join(dir, name), fullPath)
|
|
36
|
+
};
|
|
37
|
+
}).sort((a, b) => a.path.localeCompare(b.path));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export { GLOB_SCAN_PATTERN, scanAndSyncOptions, scanModules };
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { consola } from 'consola';
|
|
2
|
+
import { createHooks, createDebugger } from 'hookable';
|
|
3
|
+
import { join } from 'pathe';
|
|
4
|
+
import { loadOptions, silgiCLICtx } from 'silgi/core';
|
|
5
|
+
import { runtimeDir } from 'silgi/runtime/meta';
|
|
6
|
+
import { createUnimport } from 'unimport';
|
|
7
|
+
import { registerModuleExportScan } from '../module/exportScan.mjs';
|
|
8
|
+
import { installModules } from '../module/install.mjs';
|
|
9
|
+
import { scanModules } from '../module/scan.mjs';
|
|
10
|
+
import { scanFiles } from '../utils/scan.mjs';
|
|
11
|
+
import { createStorageCLI } from '../utils/storage.mjs';
|
|
12
|
+
import { generateApp } from './app.mjs';
|
|
13
|
+
import { scanAndSyncOptions } from './scan.mjs';
|
|
14
|
+
|
|
15
|
+
async function createSilgiCLI(config = {}, opts = {}) {
|
|
16
|
+
const options = await loadOptions(config, opts);
|
|
17
|
+
const hooks = createHooks();
|
|
18
|
+
const silgi = {
|
|
19
|
+
modulesURIs: {},
|
|
20
|
+
scannedURIs: /* @__PURE__ */ new Map(),
|
|
21
|
+
services: {},
|
|
22
|
+
uris: {},
|
|
23
|
+
shareds: {},
|
|
24
|
+
schemas: {},
|
|
25
|
+
unimport: void 0,
|
|
26
|
+
options,
|
|
27
|
+
hooks,
|
|
28
|
+
// vfs: {}
|
|
29
|
+
_requiredModules: {},
|
|
30
|
+
logger: consola.withTag("silgi"),
|
|
31
|
+
close: () => silgi.hooks.callHook("close", silgi),
|
|
32
|
+
storage: void 0,
|
|
33
|
+
scanModules: [],
|
|
34
|
+
templates: [],
|
|
35
|
+
callHook: hooks.callHook,
|
|
36
|
+
addHooks: hooks.addHooks,
|
|
37
|
+
hook: hooks.hook,
|
|
38
|
+
async updateConfig(_config) {
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
if (silgiCLICtx.tryUse()) {
|
|
42
|
+
silgiCLICtx.unset();
|
|
43
|
+
silgiCLICtx.set(silgi);
|
|
44
|
+
} else {
|
|
45
|
+
silgiCLICtx.set(silgi);
|
|
46
|
+
silgi.hook("close", () => silgiCLICtx.unset());
|
|
47
|
+
}
|
|
48
|
+
if (silgi.options.debug) {
|
|
49
|
+
createDebugger(silgi.hooks, { tag: "silgi" });
|
|
50
|
+
silgi.options.plugins.push({
|
|
51
|
+
path: join(runtimeDir, "internal/debug"),
|
|
52
|
+
packageImport: "silgi/runtime/internal/debug"
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
await scanAndSyncOptions(silgi);
|
|
56
|
+
await scanModules(silgi);
|
|
57
|
+
await scanFiles(silgi);
|
|
58
|
+
silgi.storage = await createStorageCLI(silgi);
|
|
59
|
+
silgi.hooks.hook("close", async () => {
|
|
60
|
+
await silgi.storage.dispose();
|
|
61
|
+
});
|
|
62
|
+
if (silgi.options.logLevel !== void 0) {
|
|
63
|
+
silgi.logger.level = silgi.options.logLevel;
|
|
64
|
+
}
|
|
65
|
+
silgi.hooks.addHooks(silgi.options.hooks);
|
|
66
|
+
await installModules(silgi);
|
|
67
|
+
await silgi.hooks.callHook("scanFiles:done", silgi);
|
|
68
|
+
await generateApp(silgi);
|
|
69
|
+
if (silgi.options.imports) {
|
|
70
|
+
silgi.unimport = createUnimport(silgi.options.imports);
|
|
71
|
+
await silgi.unimport.init();
|
|
72
|
+
}
|
|
73
|
+
await registerModuleExportScan(silgi);
|
|
74
|
+
return silgi;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export { createSilgiCLI };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
async function generateSilgiStorageBaseType(silgi) {
|
|
2
|
+
silgi.hook("prepare:schema.ts", async (options) => {
|
|
3
|
+
if (silgi.options.storage) {
|
|
4
|
+
for (const [key, _value] of Object.entries(silgi.options.storage)) {
|
|
5
|
+
options.storeBase.push(key);
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export { generateSilgiStorageBaseType };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
const vueShim = {
|
|
2
|
+
filename: "types/vue-shim.d.ts",
|
|
3
|
+
getContents: ({ app }) => {
|
|
4
|
+
if (!app.options.typescript.shim) {
|
|
5
|
+
return "";
|
|
6
|
+
}
|
|
7
|
+
return [
|
|
8
|
+
"declare module '*.vue' {",
|
|
9
|
+
" import { DefineComponent } from 'vue'",
|
|
10
|
+
" const component: DefineComponent<{}, {}, any>",
|
|
11
|
+
" export default component",
|
|
12
|
+
"}"
|
|
13
|
+
].join("\n");
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
const pluginsDeclaration = {
|
|
17
|
+
filename: "types/plugins.d.ts",
|
|
18
|
+
getContents: async () => {
|
|
19
|
+
return `
|
|
20
|
+
declare module 'nuxt' {
|
|
21
|
+
interface NuxtApp {
|
|
22
|
+
$myPlugin: any;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
`;
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export { pluginsDeclaration, vueShim };
|
package/dist/cli/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { defineCommand, runMain } from 'citty';
|
|
2
2
|
import consola from 'consola';
|
|
3
|
-
import
|
|
3
|
+
import packageJson from '../package.json.mjs';
|
|
4
4
|
|
|
5
5
|
const main = defineCommand({
|
|
6
6
|
meta: {
|
|
@@ -15,8 +15,8 @@ const main = defineCommand({
|
|
|
15
15
|
}
|
|
16
16
|
},
|
|
17
17
|
subCommands: {
|
|
18
|
-
prepare: () => import('./prepare.mjs').then((m) => m.default),
|
|
19
|
-
init: () => import('./init.mjs').then((m) => m.default)
|
|
18
|
+
prepare: () => import('./commands/prepare.mjs').then((m) => m.default),
|
|
19
|
+
init: () => import('./commands/init.mjs').then((m) => m.default)
|
|
20
20
|
},
|
|
21
21
|
run({ args }) {
|
|
22
22
|
consola.info("Silgi CLI , --help for more info");
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { pascalCase } from 'scule';
|
|
2
|
+
import { relativeWithDot } from 'silgi/kit';
|
|
3
|
+
|
|
4
|
+
async function registerModuleExportScan(silgi) {
|
|
5
|
+
silgi.hook("prepare:schema.ts", async (options) => {
|
|
6
|
+
for (const module of silgi.scanModules) {
|
|
7
|
+
const exports = module.meta.exports;
|
|
8
|
+
if (!exports?.length)
|
|
9
|
+
continue;
|
|
10
|
+
const configKey = module.meta.configKey;
|
|
11
|
+
const moduleName = module.meta.name || module.meta._packageName;
|
|
12
|
+
options.importItems[configKey] = {
|
|
13
|
+
import: [],
|
|
14
|
+
from: module.meta._packageName ? moduleName : relativeWithDot(silgi.options.build.typesDir, module.entryPath)
|
|
15
|
+
};
|
|
16
|
+
const exportedTypes = exports.filter((exp) => exp.type).map((exp) => exp.name);
|
|
17
|
+
if (exportedTypes.includes("ModuleOptions")) {
|
|
18
|
+
const importName = pascalCase(`${configKey}Config`);
|
|
19
|
+
options.importItems[configKey].import.push({
|
|
20
|
+
name: `ModuleOptions as ${importName}`,
|
|
21
|
+
type: true
|
|
22
|
+
});
|
|
23
|
+
options.configs.push({ key: configKey, value: importName });
|
|
24
|
+
}
|
|
25
|
+
if (exportedTypes.includes("ModuleRuntimeContext")) {
|
|
26
|
+
const importName = pascalCase(`${configKey}Context`);
|
|
27
|
+
options.importItems[configKey].import.push({
|
|
28
|
+
name: `ModuleRuntimeContext as ${importName}`,
|
|
29
|
+
type: true
|
|
30
|
+
});
|
|
31
|
+
options.contexts.push({ key: configKey, value: importName });
|
|
32
|
+
}
|
|
33
|
+
if (exportedTypes.includes("ModuleRuntimeMethods")) {
|
|
34
|
+
const importName = pascalCase(`${configKey}Method`);
|
|
35
|
+
options.importItems[configKey].import.push({
|
|
36
|
+
name: `ModuleRuntimeMethods as ${importName}`,
|
|
37
|
+
type: true
|
|
38
|
+
});
|
|
39
|
+
options.methods.push({ key: configKey, value: importName });
|
|
40
|
+
}
|
|
41
|
+
if (exportedTypes.includes("ModuleRuntimeShared")) {
|
|
42
|
+
const importName = pascalCase(`${configKey}Shared`);
|
|
43
|
+
options.importItems[configKey].import.push({
|
|
44
|
+
name: `ModuleRuntimeShared as ${importName}`,
|
|
45
|
+
type: true
|
|
46
|
+
});
|
|
47
|
+
options.shareds.push({ key: configKey, value: importName });
|
|
48
|
+
}
|
|
49
|
+
if (exportedTypes.includes("ModuleHooks")) {
|
|
50
|
+
const importName = pascalCase(`${configKey}Hooks`);
|
|
51
|
+
options.importItems[configKey].import.push({
|
|
52
|
+
name: `ModuleHooks as ${importName}`,
|
|
53
|
+
type: true
|
|
54
|
+
});
|
|
55
|
+
options.hooks.push({ key: configKey, value: importName });
|
|
56
|
+
}
|
|
57
|
+
if (exportedTypes.includes("ModuleRuntimeHooks")) {
|
|
58
|
+
const importName = pascalCase(`${configKey}RuntimeHooks`);
|
|
59
|
+
options.importItems[configKey].import.push({
|
|
60
|
+
name: `ModuleRuntimeHooks as ${importName}`,
|
|
61
|
+
type: true
|
|
62
|
+
});
|
|
63
|
+
options.runtimeHooks.push({ key: configKey, value: importName });
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export { registerModuleExportScan };
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { createJiti } from 'dev-jiti';
|
|
2
|
+
import { useSilgiCLI } from 'silgi/core';
|
|
3
|
+
import { hasInstalledModule } from '../utils/compatibility.mjs';
|
|
4
|
+
|
|
5
|
+
async function loadSilgiModuleInstance(silgiModule) {
|
|
6
|
+
if (typeof silgiModule === "string") {
|
|
7
|
+
throw new TypeError(`Could not load \`${silgiModule}\`. Is it installed?`);
|
|
8
|
+
}
|
|
9
|
+
if (typeof silgiModule !== "function") {
|
|
10
|
+
throw new TypeError(`Nuxt module should be a function: ${silgiModule}`);
|
|
11
|
+
}
|
|
12
|
+
return { silgiModule };
|
|
13
|
+
}
|
|
14
|
+
async function installModules(silgi) {
|
|
15
|
+
const jiti = createJiti(silgi.options.rootDir, {
|
|
16
|
+
alias: silgi.options.alias
|
|
17
|
+
});
|
|
18
|
+
for (const module of silgi.scanModules) {
|
|
19
|
+
if (hasInstalledModule(module.meta.configKey)) {
|
|
20
|
+
silgi.logger.info(`Module ${module.meta.configKey} installed`);
|
|
21
|
+
}
|
|
22
|
+
try {
|
|
23
|
+
const silgiModule = await jiti.import(module.entryPath, {
|
|
24
|
+
default: true,
|
|
25
|
+
conditions: silgi.options.conditions
|
|
26
|
+
});
|
|
27
|
+
if (silgiModule.name !== "silgiNormalizedModule") {
|
|
28
|
+
silgi.scanModules = silgi.scanModules.filter((m) => m.entryPath !== module.entryPath);
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
await installModule(silgiModule, silgi);
|
|
32
|
+
} catch (err) {
|
|
33
|
+
silgi.logger.error(err);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
async function installModule(moduleToInstall, silgi = useSilgiCLI(), inlineOptions) {
|
|
38
|
+
const { silgiModule } = await loadSilgiModuleInstance(moduleToInstall);
|
|
39
|
+
const res = await silgiModule({}, silgi) ?? {};
|
|
40
|
+
if (res === false) {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
const metaData = await silgiModule.getMeta?.();
|
|
44
|
+
const installedModule = silgi.scanModules.find((m) => m.meta.configKey === metaData?.configKey);
|
|
45
|
+
if (installedModule) {
|
|
46
|
+
installedModule.installed = true;
|
|
47
|
+
} else {
|
|
48
|
+
throw new Error(`Module ${metaData?.name} not found`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export { installModules, loadSilgiModuleInstance };
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { existsSync, promises } from 'node:fs';
|
|
2
|
+
import { pathToFileURL, fileURLToPath } from 'node:url';
|
|
3
|
+
import { consola } from 'consola';
|
|
4
|
+
import { createJiti } from 'dev-jiti';
|
|
5
|
+
import { resolve as resolve$1 } from 'mlly';
|
|
6
|
+
import { resolve, join, isAbsolute } from 'pathe';
|
|
7
|
+
import { resolveAlias, resolvePath } from 'silgi/kit';
|
|
8
|
+
import { isRelative } from 'ufo';
|
|
9
|
+
import { scanExports } from 'unimport';
|
|
10
|
+
|
|
11
|
+
const logger = consola;
|
|
12
|
+
async function _resolveSilgiModule(mod, silgi) {
|
|
13
|
+
let _url;
|
|
14
|
+
let buildTimeModuleMeta = {};
|
|
15
|
+
const jiti = createJiti(silgi.options.rootDir, {
|
|
16
|
+
alias: silgi.options.alias
|
|
17
|
+
});
|
|
18
|
+
if (typeof mod === "string") {
|
|
19
|
+
const paths = /* @__PURE__ */ new Set();
|
|
20
|
+
mod = resolveAlias(mod, silgi.options.alias);
|
|
21
|
+
if (isRelative(mod)) {
|
|
22
|
+
mod = resolve(silgi.options.rootDir, mod);
|
|
23
|
+
}
|
|
24
|
+
paths.add(join(mod, "module"));
|
|
25
|
+
paths.add(mod);
|
|
26
|
+
for (const path of paths) {
|
|
27
|
+
try {
|
|
28
|
+
const src = isAbsolute(path) ? pathToFileURL(await resolvePath(path, { fallbackToOriginal: false, extensions: silgi.options.extensions })).href : await resolve$1(path, { url: silgi.options.modulesDir.map((m) => pathToFileURL(m.replace(/\/node_modules\/?$/, ""))), extensions: silgi.options.extensions });
|
|
29
|
+
mod = await jiti.import(src, {
|
|
30
|
+
default: true,
|
|
31
|
+
conditions: silgi.options.conditions
|
|
32
|
+
});
|
|
33
|
+
_url = fileURLToPath(new URL(src));
|
|
34
|
+
const moduleMetadataPath = new URL("module.json", src);
|
|
35
|
+
if (existsSync(moduleMetadataPath)) {
|
|
36
|
+
buildTimeModuleMeta = JSON.parse(await promises.readFile(moduleMetadataPath, "utf-8"));
|
|
37
|
+
} else {
|
|
38
|
+
if (typeof mod === "function") {
|
|
39
|
+
const meta = await mod.getMeta?.();
|
|
40
|
+
const _exports = await scanExports(_url, true);
|
|
41
|
+
buildTimeModuleMeta = {
|
|
42
|
+
...meta,
|
|
43
|
+
exports: _exports.map(({ from, ...rest }) => rest)
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
break;
|
|
48
|
+
} catch (error) {
|
|
49
|
+
const code = error.code;
|
|
50
|
+
if (code === "MODULE_NOT_FOUND" || code === "ERR_PACKAGE_PATH_NOT_EXPORTED" || code === "ERR_MODULE_NOT_FOUND" || code === "ERR_UNSUPPORTED_DIR_IMPORT" || code === "ENOTDIR") {
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
logger.error(`Error while importing module \`${mod}\`: ${error}`);
|
|
54
|
+
throw error;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (!buildTimeModuleMeta) {
|
|
59
|
+
throw new Error(`Module ${mod} is not a valid Silgi module`);
|
|
60
|
+
}
|
|
61
|
+
if (typeof mod === "function") {
|
|
62
|
+
if (silgi.scanModules.some((m) => m.meta?.configKey === buildTimeModuleMeta.configKey)) {
|
|
63
|
+
throw new Error(`Module with key \`${buildTimeModuleMeta.configKey}\` already exists`);
|
|
64
|
+
}
|
|
65
|
+
silgi.scanModules.push({
|
|
66
|
+
meta: buildTimeModuleMeta,
|
|
67
|
+
entryPath: _url,
|
|
68
|
+
installed: false,
|
|
69
|
+
options: await mod.getOptions?.() || {}
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
async function scanModules(silgi) {
|
|
74
|
+
const _modules = [
|
|
75
|
+
...silgi.options._modules,
|
|
76
|
+
...silgi.options.modules
|
|
77
|
+
];
|
|
78
|
+
for await (const mod of _modules) {
|
|
79
|
+
await _resolveSilgiModule(mod, silgi);
|
|
80
|
+
}
|
|
81
|
+
const moduleMap = new Map(
|
|
82
|
+
silgi.scanModules.map((m) => [m.meta?.configKey, m])
|
|
83
|
+
);
|
|
84
|
+
const graph = createDependencyGraph(silgi.scanModules);
|
|
85
|
+
const sortedKeys = topologicalSort(graph);
|
|
86
|
+
const modules = sortedKeys.map((key) => moduleMap.get(key)).filter((module) => Boolean(module));
|
|
87
|
+
silgi.scanModules = modules;
|
|
88
|
+
}
|
|
89
|
+
function createDependencyGraph(modules) {
|
|
90
|
+
const graph = /* @__PURE__ */ new Map();
|
|
91
|
+
modules.forEach((module) => {
|
|
92
|
+
const key = module.meta?.configKey;
|
|
93
|
+
if (key) {
|
|
94
|
+
graph.set(key, /* @__PURE__ */ new Set());
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
modules.forEach((module) => {
|
|
98
|
+
const key = module.meta?.configKey;
|
|
99
|
+
const deps = module.meta?.dependencies || [];
|
|
100
|
+
if (key && deps.length > 0) {
|
|
101
|
+
const modulesDeps = graph.get(key) || /* @__PURE__ */ new Set();
|
|
102
|
+
deps.forEach((dep) => {
|
|
103
|
+
if (graph.has(dep)) {
|
|
104
|
+
modulesDeps.add(dep);
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
graph.set(key, modulesDeps);
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
return graph;
|
|
111
|
+
}
|
|
112
|
+
function topologicalSort(graph) {
|
|
113
|
+
const visited = /* @__PURE__ */ new Set();
|
|
114
|
+
const temp = /* @__PURE__ */ new Set();
|
|
115
|
+
const order = [];
|
|
116
|
+
function visit(node) {
|
|
117
|
+
if (temp.has(node))
|
|
118
|
+
throw new Error(`Circular dependency detected: ${node}`);
|
|
119
|
+
if (visited.has(node))
|
|
120
|
+
return;
|
|
121
|
+
temp.add(node);
|
|
122
|
+
const deps = graph.get(node) || /* @__PURE__ */ new Set();
|
|
123
|
+
for (const dep of deps) {
|
|
124
|
+
visit(dep);
|
|
125
|
+
}
|
|
126
|
+
temp.delete(node);
|
|
127
|
+
visited.add(node);
|
|
128
|
+
order.unshift(node);
|
|
129
|
+
}
|
|
130
|
+
for (const [node, deps] of graph.entries()) {
|
|
131
|
+
if (deps.size === 0 && !visited.has(node))
|
|
132
|
+
visit(node);
|
|
133
|
+
}
|
|
134
|
+
for (const node of graph.keys()) {
|
|
135
|
+
if (!visited.has(node))
|
|
136
|
+
visit(node);
|
|
137
|
+
}
|
|
138
|
+
return order;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export { logger, scanModules };
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { promises } from 'node:fs';
|
|
2
|
+
import { resolve } from 'pathe';
|
|
3
|
+
|
|
4
|
+
async function generateRouterDTS(silgi) {
|
|
5
|
+
silgi.hook("finish:types", async (data) => {
|
|
6
|
+
const uris = data.object.uris;
|
|
7
|
+
const subPath = "srn";
|
|
8
|
+
const groupedPaths = /* @__PURE__ */ new Map();
|
|
9
|
+
Object.entries(uris || {}).forEach(([key, params]) => {
|
|
10
|
+
const [service, resource, method, action] = key.split("/");
|
|
11
|
+
const basePath = params ? `${subPath}/${service}/${resource}/${action}/${params}` : `${subPath}/${service}/${resource}/${action}`;
|
|
12
|
+
const fullPath = `${subPath}/${service}/${resource}/${action}`;
|
|
13
|
+
if (!groupedPaths.has(basePath)) {
|
|
14
|
+
groupedPaths.set(basePath, /* @__PURE__ */ new Map());
|
|
15
|
+
}
|
|
16
|
+
groupedPaths.get(basePath)?.set(method.toLowerCase(), fullPath);
|
|
17
|
+
});
|
|
18
|
+
const keys = [
|
|
19
|
+
" keys: {",
|
|
20
|
+
Array.from(groupedPaths.entries()).map(([basePath, methods]) => {
|
|
21
|
+
return ` '/${basePath}': {${Array.from(methods.entries()).map(([method, path]) => `
|
|
22
|
+
${method}: '/${path}'`).join(",")}
|
|
23
|
+
}`;
|
|
24
|
+
}).join(",\n"),
|
|
25
|
+
" }",
|
|
26
|
+
""
|
|
27
|
+
].join("\n");
|
|
28
|
+
const groupedRoutes = Object.entries(uris || {}).reduce((acc, [key, _params]) => {
|
|
29
|
+
const [service, resource, method, action] = key.split("/");
|
|
30
|
+
const routePath = `${subPath}/${service}/${resource}/${action}`;
|
|
31
|
+
if (!acc[routePath]) {
|
|
32
|
+
acc[routePath] = {};
|
|
33
|
+
}
|
|
34
|
+
acc[routePath][method] = {
|
|
35
|
+
input: `ExtractInputFromURI<'${key}'>`,
|
|
36
|
+
output: `ExtractOutputFromURI<'${key}'>`,
|
|
37
|
+
params: `ExtractRouterParamsFromURI<'${key}'>['params']`
|
|
38
|
+
};
|
|
39
|
+
return acc;
|
|
40
|
+
}, {});
|
|
41
|
+
const routerTypes = Object.entries(groupedRoutes).map(([path, methods]) => {
|
|
42
|
+
const methodEntries = Object.entries(methods).map(([method, { input, output, params }]) => {
|
|
43
|
+
return ` '${method}': {
|
|
44
|
+
input: ${input},
|
|
45
|
+
output: ${output}
|
|
46
|
+
params: ${params}
|
|
47
|
+
}`;
|
|
48
|
+
}).join(",\n");
|
|
49
|
+
return ` '/${path}': {
|
|
50
|
+
${methodEntries}
|
|
51
|
+
}`;
|
|
52
|
+
});
|
|
53
|
+
const nitro = [
|
|
54
|
+
"declare module 'nitropack/types' {",
|
|
55
|
+
" interface InternalApi extends RouterTypes {}",
|
|
56
|
+
"}"
|
|
57
|
+
];
|
|
58
|
+
const content = [
|
|
59
|
+
keys.slice(0, -1),
|
|
60
|
+
// son satırdaki boş satırı kaldır
|
|
61
|
+
...routerTypes
|
|
62
|
+
].join(",\n");
|
|
63
|
+
const context = [
|
|
64
|
+
"import type { ExtractInputFromURI, ExtractOutputFromURI, ExtractRouterParamsFromURI } from 'silgi/types'",
|
|
65
|
+
"",
|
|
66
|
+
"export interface RouterTypes {",
|
|
67
|
+
content,
|
|
68
|
+
"}",
|
|
69
|
+
"",
|
|
70
|
+
"declare module 'silgi/types' {",
|
|
71
|
+
" interface SilgiRouterTypes extends RouterTypes {",
|
|
72
|
+
" }",
|
|
73
|
+
"}",
|
|
74
|
+
"",
|
|
75
|
+
silgi.options.preset === "h3" || silgi.options.preset === "nitro" ? nitro.join("\n") : "",
|
|
76
|
+
"",
|
|
77
|
+
"export {}"
|
|
78
|
+
].join("\n");
|
|
79
|
+
const outputPath = resolve(silgi.options.build.typesDir, "silgi-routes.d.ts");
|
|
80
|
+
await promises.writeFile(outputPath, context);
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export { generateRouterDTS };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import ignore from 'ignore';
|
|
3
|
+
import { relative, join } from 'pathe';
|
|
4
|
+
|
|
5
|
+
function resolveIgnorePatterns(silgi, relativePath) {
|
|
6
|
+
if (!silgi) {
|
|
7
|
+
return [];
|
|
8
|
+
}
|
|
9
|
+
const ignorePatterns = silgi.options.ignore.flatMap((s) => resolveGroupSyntax(s));
|
|
10
|
+
const nuxtignoreFile = join(silgi.options.rootDir, ".nuxtignore");
|
|
11
|
+
if (existsSync(nuxtignoreFile)) {
|
|
12
|
+
const contents = readFileSync(nuxtignoreFile, "utf-8");
|
|
13
|
+
ignorePatterns.push(...contents.trim().split(/\r?\n/));
|
|
14
|
+
}
|
|
15
|
+
return ignorePatterns;
|
|
16
|
+
}
|
|
17
|
+
function isIgnored(pathname, silgi, _stats) {
|
|
18
|
+
if (!silgi) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
if (!silgi._ignore) {
|
|
22
|
+
silgi._ignore = ignore(silgi.options.ignoreOptions);
|
|
23
|
+
silgi._ignore.add(resolveIgnorePatterns(silgi));
|
|
24
|
+
}
|
|
25
|
+
const relativePath = relative(silgi.options.rootDir, pathname);
|
|
26
|
+
if (relativePath[0] === "." && relativePath[1] === ".") {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
return !!(relativePath && silgi._ignore.ignores(relativePath));
|
|
30
|
+
}
|
|
31
|
+
function resolveGroupSyntax(group) {
|
|
32
|
+
let groups = [group];
|
|
33
|
+
while (groups.some((group2) => group2.includes("{"))) {
|
|
34
|
+
groups = groups.flatMap((group2) => {
|
|
35
|
+
const [head, ...tail] = group2.split("{");
|
|
36
|
+
if (tail.length) {
|
|
37
|
+
const [body = "", ...rest] = tail.join("{").split("}");
|
|
38
|
+
return body.split(",").map((part) => `${head}${part}${rest.join("")}`);
|
|
39
|
+
}
|
|
40
|
+
return group2;
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
return groups;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export { isIgnored, resolveGroupSyntax, resolveIgnorePatterns };
|