silgi 0.14.4 → 0.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.
@@ -1,4 +1,4 @@
1
- const version = "0.14.4";
1
+ const version = "0.15.0";
2
2
  const peerDependencies = {
3
3
  "@fastify/deepmerge": "^2.0.2",
4
4
  "@nuxt/kit": "^3.15.3",
@@ -0,0 +1,274 @@
1
+ function patternToRegex(pattern) {
2
+ let regexStr = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&");
3
+ regexStr = regexStr.replace(/\*\*/g, ".+");
4
+ regexStr = regexStr.replace(/\*/g, "[^/]+");
5
+ regexStr = regexStr.replace(/:([^/]+)/g, "([^/]+)");
6
+ return new RegExp(`^${regexStr}$`);
7
+ }
8
+ function extractParams(url, pattern) {
9
+ if (!pattern.includes(":"))
10
+ return null;
11
+ const paramNames = [];
12
+ const patternRegex = pattern.replace(/:([^/]+)/g, (_, name) => {
13
+ paramNames.push(name);
14
+ return "([^/]+)";
15
+ });
16
+ const regex = new RegExp(`^${patternRegex}$`);
17
+ const matches = url.match(regex);
18
+ if (!matches)
19
+ return null;
20
+ const params = {};
21
+ paramNames.forEach((name, i) => {
22
+ params[name] = matches[i + 1];
23
+ });
24
+ return Object.keys(params).length > 0 ? params : null;
25
+ }
26
+ function matchesPattern(url, pattern) {
27
+ if (url === pattern)
28
+ return true;
29
+ if (url.endsWith("/") && !pattern.endsWith("/") || !url.endsWith("/") && pattern.endsWith("/")) {
30
+ return false;
31
+ }
32
+ if (pattern.endsWith("/**")) {
33
+ const basePath = pattern.slice(0, -3);
34
+ return url === basePath || url.startsWith(`${basePath}/`);
35
+ }
36
+ const urlParts = url.split("/");
37
+ const patternParts = pattern.split("/");
38
+ if (!pattern.includes("**") && urlParts.length !== patternParts.length) {
39
+ return false;
40
+ }
41
+ if (pattern.includes("/**/")) {
42
+ const [prefix, ...suffixParts] = pattern.split("/**/");
43
+ const suffix = suffixParts.join("/");
44
+ return url.startsWith(prefix) && (!suffix || url.endsWith(`/${suffix}`));
45
+ }
46
+ return patternToRegex(pattern).test(url);
47
+ }
48
+ function deepClone(obj) {
49
+ if (obj === null || typeof obj !== "object")
50
+ return obj;
51
+ if (typeof obj === "function")
52
+ return obj;
53
+ if (Array.isArray(obj))
54
+ return obj.map(deepClone);
55
+ const cloned = {};
56
+ for (const key in obj) {
57
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
58
+ cloned[key] = deepClone(obj[key]);
59
+ }
60
+ }
61
+ return cloned;
62
+ }
63
+ function mergeConfigs(...configs) {
64
+ const result = {};
65
+ for (const config of configs) {
66
+ if (!config)
67
+ continue;
68
+ for (const key in config) {
69
+ const value = config[key];
70
+ if (value && typeof value === "object" && !Array.isArray(value) && result[key] && typeof result[key] === "object" && typeof result[key] !== "function") {
71
+ const resultValue = result[key];
72
+ const valueToMerge = value;
73
+ result[key] = mergeConfigs(resultValue, valueToMerge);
74
+ } else {
75
+ result[key] = value;
76
+ }
77
+ }
78
+ }
79
+ return result;
80
+ }
81
+ function createRouteRules() {
82
+ let _rules = {};
83
+ let _mergedRules = {};
84
+ let _rulesModified = false;
85
+ function getRules() {
86
+ return deepClone(_rules);
87
+ }
88
+ function importRules(config) {
89
+ _rules = deepClone(config);
90
+ _rulesModified = true;
91
+ updateMergeRules();
92
+ }
93
+ function exportRules() {
94
+ return deepClone(_rules);
95
+ }
96
+ function addRule(pattern, config) {
97
+ _rules[pattern] = deepClone(config);
98
+ _rulesModified = true;
99
+ updateMergeRules();
100
+ }
101
+ function updateRule(pattern, config) {
102
+ if (_rules[pattern]) {
103
+ _rules[pattern] = { ..._rules[pattern], ...deepClone(config) };
104
+ } else {
105
+ _rules[pattern] = deepClone(config);
106
+ }
107
+ _rulesModified = true;
108
+ updateMergeRules();
109
+ }
110
+ function removeRule(pattern) {
111
+ delete _rules[pattern];
112
+ _rulesModified = true;
113
+ updateMergeRules();
114
+ }
115
+ function matchesRule(url, pattern) {
116
+ return matchesPattern(url, pattern);
117
+ }
118
+ function getMatchingPatterns(url) {
119
+ return Object.keys(_rules).filter((pattern) => matchesPattern(url, pattern)).sort((a, b) => {
120
+ if (a === url)
121
+ return -1;
122
+ if (b === url)
123
+ return 1;
124
+ const aSegments = a.split("/").filter(Boolean).length;
125
+ const bSegments = b.split("/").filter(Boolean).length;
126
+ if (aSegments !== bSegments)
127
+ return bSegments - aSegments;
128
+ const aWildcards = (a.match(/\*/g) || []).length;
129
+ const bWildcards = (b.match(/\*/g) || []).length;
130
+ if (aWildcards !== bWildcards)
131
+ return aWildcards - bWildcards;
132
+ const aDoubleWildcards = (a.match(/\*\*/g) || []).length;
133
+ const bDoubleWildcards = (b.match(/\*\*/g) || []).length;
134
+ if (aDoubleWildcards !== bDoubleWildcards)
135
+ return aDoubleWildcards - bDoubleWildcards;
136
+ return b.length - a.length;
137
+ });
138
+ }
139
+ function getConfig(url) {
140
+ if (_rulesModified) {
141
+ updateMergeRules();
142
+ }
143
+ if (_mergedRules[url]) {
144
+ return deepClone(_mergedRules[url]);
145
+ }
146
+ const patterns = getMatchingPatterns(url);
147
+ if (!patterns.length)
148
+ return null;
149
+ const mergedConfig = {};
150
+ for (let i = patterns.length - 1; i >= 0; i--) {
151
+ const pattern = patterns[i];
152
+ const patternConfig = _mergedRules[pattern] || _rules[pattern];
153
+ Object.assign(mergedConfig, deepClone(patternConfig));
154
+ }
155
+ _mergedRules[url] = deepClone(mergedConfig);
156
+ return mergedConfig;
157
+ }
158
+ function computeMergedConfig(url, patterns) {
159
+ const matchingPatterns = patterns || getMatchingPatterns(url);
160
+ if (!matchingPatterns.length)
161
+ return {};
162
+ const allPatternsHaveCache = matchingPatterns.every((pattern) => !!_mergedRules[pattern]);
163
+ if (allPatternsHaveCache) {
164
+ return matchingPatterns.reduceRight((result, pattern) => mergeConfigs(result, deepClone(_mergedRules[pattern])), {});
165
+ }
166
+ return matchingPatterns.reduceRight((result, pattern) => mergeConfigs(result, deepClone(_rules[pattern])), {});
167
+ }
168
+ function getParams(url, pattern) {
169
+ return extractParams(url, pattern);
170
+ }
171
+ function match(url) {
172
+ const patterns = getMatchingPatterns(url);
173
+ if (!patterns.length)
174
+ return null;
175
+ const bestPattern = patterns[0];
176
+ return {
177
+ pattern: bestPattern,
178
+ config: deepClone(_rules[bestPattern]),
179
+ params: getParams(url, bestPattern)
180
+ };
181
+ }
182
+ function clear() {
183
+ _rules = {};
184
+ clearMergedRules();
185
+ _rulesModified = false;
186
+ }
187
+ function clearMergedRules() {
188
+ _mergedRules = {};
189
+ _rulesModified = true;
190
+ }
191
+ function precomputeMergedRules(urls) {
192
+ if (_rulesModified) {
193
+ updateMergeRules();
194
+ }
195
+ for (const url of urls) {
196
+ if (!_mergedRules[url]) {
197
+ const patterns = getMatchingPatterns(url);
198
+ if (patterns.length) {
199
+ _mergedRules[url] = computeMergedConfig(url, patterns);
200
+ }
201
+ }
202
+ }
203
+ }
204
+ function setMergedRule(url, config) {
205
+ _mergedRules[url] = deepClone(config);
206
+ if (url.includes("*") || url.includes(":")) {
207
+ _rulesModified = false;
208
+ }
209
+ }
210
+ function getMergedRules() {
211
+ return deepClone(_mergedRules);
212
+ }
213
+ function configure(config) {
214
+ importRules(config);
215
+ }
216
+ function updateMergeRules() {
217
+ if (!_rulesModified) {
218
+ return _mergedRules;
219
+ }
220
+ _mergedRules = {};
221
+ const rulePatterns = Object.keys(_rules);
222
+ for (const pattern of rulePatterns) {
223
+ const patterns = getMatchingPatterns(pattern);
224
+ _mergedRules[pattern] = computeMergedConfig(pattern, patterns);
225
+ }
226
+ for (const pattern of rulePatterns) {
227
+ if (pattern.includes("/:")) {
228
+ const segments = pattern.split("/");
229
+ let partialPath = "";
230
+ for (const segment of segments) {
231
+ if (segment) {
232
+ partialPath += `/${segment}`;
233
+ if (segment.startsWith(":") && partialPath !== pattern) {
234
+ const samplePath = partialPath.replace(/:\w+/g, "sample");
235
+ const patterns = getMatchingPatterns(samplePath);
236
+ _mergedRules[samplePath] = computeMergedConfig(samplePath, patterns);
237
+ }
238
+ }
239
+ }
240
+ }
241
+ }
242
+ _rulesModified = false;
243
+ return _mergedRules;
244
+ }
245
+ return {
246
+ // Public getters that return a cloned version to prevent direct modification
247
+ get rules() {
248
+ return getRules();
249
+ },
250
+ get mergedRules() {
251
+ return getMergedRules();
252
+ },
253
+ // API methods
254
+ importRules,
255
+ exportRules,
256
+ addRule,
257
+ updateRule,
258
+ removeRule,
259
+ matchesRule,
260
+ getMatchingPatterns,
261
+ getConfig,
262
+ getParams,
263
+ match,
264
+ clear,
265
+ clearMergedRules,
266
+ precomputeMergedRules,
267
+ setMergedRule,
268
+ getMergedRules,
269
+ configure,
270
+ updateMergeRules
271
+ };
272
+ }
273
+
274
+ export { createRouteRules as c };
package/dist/cli/dev.mjs CHANGED
@@ -15,6 +15,7 @@ import 'silgi/kit';
15
15
  import 'silgi/runtime/meta';
16
16
  import 'silgi/types';
17
17
  import 'unimport';
18
+ import '../_chunks/routeRules.mjs';
18
19
  import './env.mjs';
19
20
  import '@clack/prompts';
20
21
  import 'dotenv';
@@ -1,17 +1,18 @@
1
1
  import { defineCommand } from 'citty';
2
2
  import consola from 'consola';
3
- import { resolve } from 'pathe';
3
+ import { join, resolve } from 'pathe';
4
4
  import { version } from 'silgi/meta';
5
+ import { writeFile } from 'silgi/kit';
5
6
  import { c as createSilgiCLI, p as prepare$1, w as writeTypesAndFiles, a as writeCoreFile } from './writeTypesAndFiles.mjs';
6
7
  import { c as commonArgs } from './common.mjs';
7
8
  import 'node:fs';
8
9
  import 'node:fs/promises';
9
10
  import 'hookable';
10
11
  import 'silgi/core';
11
- import 'silgi/kit';
12
12
  import 'silgi/runtime/meta';
13
13
  import 'silgi/types';
14
14
  import 'unimport';
15
+ import '../_chunks/routeRules.mjs';
15
16
  import './env.mjs';
16
17
  import '@clack/prompts';
17
18
  import 'dotenv';
@@ -39,6 +40,48 @@ import 'pathe/utils';
39
40
  import 'untyped';
40
41
  import './types.mjs';
41
42
 
43
+ function serializeToString(obj, indent = 0) {
44
+ const spacing = " ".repeat(indent);
45
+ const innerSpacing = " ".repeat(indent + 4);
46
+ if (obj === null || obj === void 0)
47
+ return "null";
48
+ if (typeof obj === "function")
49
+ return obj.toString();
50
+ if (typeof obj !== "object")
51
+ return JSON.stringify(obj);
52
+ if (Array.isArray(obj)) {
53
+ if (obj.length === 0)
54
+ return "[]";
55
+ const items = obj.map((item) => serializeToString(item, indent + 4));
56
+ return `[
57
+ ${innerSpacing}${items.join(`,
58
+ ${innerSpacing}`)}
59
+ ${spacing}]`;
60
+ }
61
+ const entries = Object.entries(obj);
62
+ if (entries.length === 0)
63
+ return "{}";
64
+ const props = entries.map(
65
+ ([key, value]) => `${innerSpacing}"${key}": ${serializeToString(value, indent + 4)}`
66
+ );
67
+ return `{
68
+ ${props.join(",\n")}
69
+ ${spacing}}`;
70
+ }
71
+ async function prepareBuild(silgi) {
72
+ const exportedRules = silgi.routeRules.exportRules();
73
+ const serialized = serializeToString(exportedRules);
74
+ const content = `/* eslint-disable */
75
+ // @ts-nocheck
76
+ // This file is auto-generated at build time
77
+ // Contains route rules with preserved functions
78
+
79
+ export const rules = ${serialized}
80
+ `;
81
+ const file = join(silgi.options.silgi.serverDir, "rules.ts");
82
+ await writeFile(file, content);
83
+ }
84
+
42
85
  const prepare = defineCommand({
43
86
  meta: {
44
87
  name: "prepare",
@@ -73,6 +116,7 @@ const prepare = defineCommand({
73
116
  await prepare$1();
74
117
  await writeTypesAndFiles(silgi);
75
118
  await writeCoreFile(silgi);
119
+ await prepareBuild(silgi);
76
120
  const close = async () => {
77
121
  await silgi.close();
78
122
  await silgi.callHook("close", silgi);
@@ -8,6 +8,7 @@ import { relativeWithDot, hash, resolveAlias, resolvePath, writeFile, normalizeT
8
8
  import { runtimeDir } from 'silgi/runtime/meta';
9
9
  import { autoImportTypes } from 'silgi/types';
10
10
  import { scanExports, createUnimport, toExports } from 'unimport';
11
+ import { c as createRouteRules } from '../_chunks/routeRules.mjs';
11
12
  import { p as prepareEnv } from './env.mjs';
12
13
  import { resolveModuleExportNames, resolve as resolve$1, resolvePath as resolvePath$1, parseNodeModulePath, lookupNodeModuleSubpath } from 'mlly';
13
14
  import { createJiti } from 'dev-jiti';
@@ -317,6 +318,15 @@ async function registerModuleExportScan(silgi) {
317
318
  });
318
319
  options.methods.push({ key: configKey, value: importName });
319
320
  }
321
+ if (exportedTypes.includes("ModuleRuntimeRouteRules")) {
322
+ const importName = `_${hash(`${configKey}ModuleRuntimeRouteRules`)}`;
323
+ options.importItems[configKey].import.push({
324
+ name: `ModuleRuntimeRouteRules as ${importName}`,
325
+ type: true,
326
+ key: importName
327
+ });
328
+ options.routeRules.push({ key: configKey, value: importName });
329
+ }
320
330
  }
321
331
  });
322
332
  }
@@ -1454,8 +1464,12 @@ async function createSilgiCLI(config = {}, opts = {}) {
1454
1464
  addHooks: hooks.addHooks,
1455
1465
  hook: hooks.hook,
1456
1466
  async updateConfig(_config) {
1457
- }
1467
+ },
1468
+ routeRules: void 0
1458
1469
  };
1470
+ const routeRules = createRouteRules();
1471
+ routeRules.importRules(options.routeRules ?? {});
1472
+ silgi.routeRules = routeRules;
1459
1473
  useCLIRuntimeConfig(silgi);
1460
1474
  if (silgiCLICtx.tryUse()) {
1461
1475
  silgiCLICtx.unset();
@@ -1956,7 +1970,8 @@ async function prepareSchema(silgi) {
1956
1970
  hooks: [],
1957
1971
  runtimeHooks: [],
1958
1972
  runtimeOptions: [],
1959
- methods: []
1973
+ methods: [],
1974
+ routeRules: []
1960
1975
  };
1961
1976
  await silgi.callHook("prepare:schema.ts", data);
1962
1977
  relativeWithDot(silgi.options.build.typesDir, `${silgi.options.silgi.serverDir}/core.ts`);
@@ -1995,6 +2010,8 @@ async function prepareSchema(silgi) {
1995
2010
  "",
1996
2011
  `type RuntimeMethodExtends = ${data.methods?.length ? data.methods.map(({ value }) => `${value}`).join(" & ") : "{}"}`,
1997
2012
  "",
2013
+ `type RuntimeRouteRulesExtends = ${data.routeRules?.length ? data.routeRules.map(({ value }) => `${value}`).join(" & ") : "{}"}`,
2014
+ "",
1998
2015
  `type SilgiModuleSharedExtends = ${data.shareds.length ? data.shareds.map(({ value }) => `${value}`).join(" & ") : "{}"}`,
1999
2016
  "",
2000
2017
  `type SilgiModuleOptionExtend = ${data.options?.length ? data.options.map(({ value }) => `${value}`).join(" & ") : "{}"}`,
@@ -2056,6 +2073,7 @@ async function prepareSchema(silgi) {
2056
2073
  " interface SilgiRuntimeConfig extends SilgiRuntimeConfigExtends {}",
2057
2074
  " interface SilgiHooks extends ModuleHooksExtend {}",
2058
2075
  " interface SilgiRuntimeMethods extends RuntimeMethodExtends {}",
2076
+ " interface SilgiRuntimeRouteRules extends RuntimeRouteRulesExtends {}",
2059
2077
  "}",
2060
2078
  "",
2061
2079
  "export {}"
@@ -1,6 +1,7 @@
1
1
  import { createConsola } from 'consola';
2
2
  import defu, { defu as defu$1 } from 'defu';
3
3
  import { createHooks } from 'hookable';
4
+ import { c as createRouteRules } from '../_chunks/routeRules.mjs';
4
5
  import { getContext } from 'unctx';
5
6
  import { Buffer } from 'node:buffer';
6
7
  import { klona } from 'klona';
@@ -510,8 +511,12 @@ async function createSilgi(config) {
510
511
  tag: "silgi"
511
512
  })).withTag("silgi"),
512
513
  captureError: config.captureError ?? (() => {
513
- })
514
+ }),
515
+ routeRules: void 0
514
516
  };
517
+ const routeRules = createRouteRules();
518
+ routeRules.importRules(config.options.routeRules ?? {});
519
+ silgi.routeRules = routeRules;
515
520
  silgi.hooks.addHooks(silgi.options.hooks);
516
521
  await runSilgiPlugins(silgi);
517
522
  await scanAction(silgi);
@@ -121,7 +121,7 @@ function _defineSilgiModule(definition) {
121
121
  async function getOptions(inlineOptions, silgi = useSilgiCLI()) {
122
122
  const nuxtConfigOptionsKey = module.meta.configKey || module.meta.name;
123
123
  const nuxtConfigOptions = nuxtConfigOptionsKey && nuxtConfigOptionsKey in silgi.options ? silgi.options[nuxtConfigOptionsKey] : {};
124
- const optionsDefaults = module.defaults instanceof Function ? await module.defaults(silgi) : module.defaults ?? {};
124
+ const optionsDefaults = typeof module.defaults === "function" ? await module.defaults(silgi) : module.defaults ?? {};
125
125
  const options = defu(inlineOptions, nuxtConfigOptions, optionsDefaults);
126
126
  return Promise.resolve(options);
127
127
  }
@@ -1,4 +1,4 @@
1
- const version = "0.14.4";
1
+ const version = "0.15.0";
2
2
  const peerDependencies = {
3
3
  "@fastify/deepmerge": "^2.0.2",
4
4
  "@nuxt/kit": "^3.15.3",
@@ -1,4 +1,4 @@
1
- const version = "0.14.4";
1
+ const version = "0.15.0";
2
2
  const peerDependencies = {
3
3
  "@fastify/deepmerge": "^2.0.2",
4
4
  "@nuxt/kit": "^3.15.3",
@@ -6,7 +6,7 @@ import { Hookable, NestedHooks } from 'hookable';
6
6
  import { Ignore, Options } from 'ignore';
7
7
  import { TSConfig } from 'pkg-types';
8
8
  import { PresetName, PresetOptions, PresetNameInput } from 'silgi/presets';
9
- import { ResolvedServiceType as ResolvedServiceType$1, SilgiRuntimeShareds as SilgiRuntimeShareds$1, SilgiRuntimeOptions as SilgiRuntimeOptions$1, ModuleMeta as ModuleMeta$1, DotenvOptions as DotenvOptions$1, EnvOptions as EnvOptions$1, SilgiRuntimeConfig as SilgiRuntimeConfig$1, SilgiCLIHooks as SilgiCLIHooks$1, StorageMounts as StorageMounts$1, SilgiTemplate as SilgiTemplate$1, SilgiFrameworkInfo as SilgiFrameworkInfo$1 } from 'silgi/types';
9
+ import { ResolvedServiceType as ResolvedServiceType$1, SilgiRuntimeShareds as SilgiRuntimeShareds$1, SilgiRuntimeOptions as SilgiRuntimeOptions$1, RouteRules as RouteRules$1, ModuleMeta as ModuleMeta$1, SilgiRuntimeRouteRules as SilgiRuntimeRouteRules$1, DotenvOptions as DotenvOptions$1, EnvOptions as EnvOptions$1, SilgiRuntimeConfig as SilgiRuntimeConfig$1, SilgiCLIHooks as SilgiCLIHooks$1, StorageMounts as StorageMounts$1, SilgiTemplate as SilgiTemplate$1, SilgiFrameworkInfo as SilgiFrameworkInfo$1 } from 'silgi/types';
10
10
  import { UnimportPluginOptions } from 'unimport/unplugin';
11
11
  import { Defu } from 'defu';
12
12
  import { Unimport } from 'unimport';
@@ -55,6 +55,7 @@ interface SilgiCLI {
55
55
  modulesURIs: Partial<Record<keyof SilgiRuntimeOptions$1 | (string & {}), any>>;
56
56
  scannedURIs: Map<string, string>;
57
57
  templates: SilgiTemplate[];
58
+ routeRules: RouteRules$1;
58
59
  hooks: Hookable<SilgiCLIHooks>;
59
60
  hook: SilgiCLI['hooks']['hook'];
60
61
  callHook: SilgiCLI['hooks']['callHook'];
@@ -170,6 +171,10 @@ interface SchemaPreparationOptions extends ImportItem {
170
171
  key: string;
171
172
  value: string;
172
173
  }[];
174
+ routeRules: {
175
+ key: string;
176
+ value: string;
177
+ }[];
173
178
  contexts: {
174
179
  key: string;
175
180
  value: string;
@@ -563,6 +568,7 @@ interface SilgiCLIOptions extends PresetOptions {
563
568
  command?: string;
564
569
  };
565
570
  commandType: CommandType;
571
+ routeRules: SilgiRuntimeRouteRules$1;
566
572
  environments: DotenvOptions$1[];
567
573
  activeEnvironment: string;
568
574
  envOptions: EnvOptions$1;
@@ -576,7 +582,6 @@ interface SilgiCLIOptions extends PresetOptions {
576
582
  path: string;
577
583
  packageImport: string;
578
584
  }[];
579
- routeRules: Record<string, string>;
580
585
  compatibilityDate: CompatibilityDates;
581
586
  modules: (SilgiModule<any> | string | [SilgiModule | string, Record<string, any>] | undefined | null | false)[];
582
587
  _modules: (SilgiModule<any> | string | [SilgiModule | string, Record<string, any>] | undefined | null | false)[];
@@ -866,6 +871,43 @@ interface ResolvedMethodHandlerType {
866
871
  execute: (input: StandardSchemaV1.InferInput<any>, shared: SilgiRuntimeShareds, event: SilgiEvents, source: StandardSchemaV1.InferInput<any>) => Promise<StandardSchemaV1.InferInput<any>>;
867
872
  }
868
873
 
874
+ type DefaultRouteConfig = Record<string, any>;
875
+ type DefaultRouterRulesConfig = Record<string, DefaultRouteConfig>;
876
+ type DefaultMergedRulesCache = Record<string, DefaultRouteConfig>;
877
+ type RouteConfig<T extends Record<string, any> = DefaultRouteConfig> = T;
878
+ type RouteRulesConfig<T extends Record<string, any> = DefaultRouteConfig> = Record<string, T>;
879
+ type MergedRulesCache<T extends Record<string, any> = DefaultRouteConfig> = Record<string, T>;
880
+ interface SilgiRuntimeRouteRules extends RouteConfig {
881
+ }
882
+ /**
883
+ * Interface for the object returned by createRouteRules
884
+ */
885
+ interface RouteRules<T extends Record<string, any> = SilgiRuntimeRouteRules> {
886
+ readonly rules: RouteRulesConfig<T>;
887
+ readonly mergedRules: MergedRulesCache<T>;
888
+ importRules: (config: RouteRulesConfig<T>) => void;
889
+ exportRules: () => RouteRulesConfig<T>;
890
+ addRule: (pattern: string, config: RouteConfig<T>) => void;
891
+ updateRule: (pattern: string, config: Partial<RouteConfig<T>>) => void;
892
+ removeRule: (pattern: string) => void;
893
+ matchesRule: (url: string, pattern: string) => boolean;
894
+ getMatchingPatterns: (url: string) => string[];
895
+ getConfig: (url: string) => RouteConfig<T> | null;
896
+ getParams: (url: string, pattern: string) => Record<string, string> | null;
897
+ match: (url: string) => {
898
+ pattern: string;
899
+ config: RouteConfig<T>;
900
+ params: Record<string, string> | null;
901
+ } | null;
902
+ clear: () => void;
903
+ clearMergedRules: () => void;
904
+ precomputeMergedRules: (urls: string[]) => void;
905
+ setMergedRule: (url: string, config: RouteConfig<T>) => void;
906
+ getMergedRules: () => MergedRulesCache<T>;
907
+ configure: (config: RouteRulesConfig<T>) => void;
908
+ updateMergeRules: () => MergedRulesCache<T>;
909
+ }
910
+
869
911
  type SilgiServiceInterface<T extends BaseSchemaType<StandardSchemaV1>> = {
870
912
  [Action in keyof T]: T[Action] extends Record<string, any> ? {
871
913
  [Method in keyof T[Action]]: {
@@ -927,6 +969,7 @@ interface Silgi {
927
969
  scannedHandlers: Map<string, ResolvedMethodHandlerType>;
928
970
  plugins: SilgiAppPlugin[];
929
971
  framework: FrameworkContext;
972
+ routeRules: RouteRules;
930
973
  _ignore?: Ignore;
931
974
  hooks: Hookable<SilgiRuntimeHooks & DefaultHooks>;
932
975
  hook: Silgi['hooks']['hook'];
@@ -987,6 +1030,7 @@ interface SilgiRuntimeConfig {
987
1030
  }
988
1031
  interface SilgiOptions {
989
1032
  consolaOptions?: Partial<ConsolaOptions>;
1033
+ routeRules: SilgiRuntimeRouteRules;
990
1034
  present: PresetNameInput;
991
1035
  hooks: Partial<SilgiRuntimeHooks & DefaultHooks>;
992
1036
  /**
@@ -1056,4 +1100,4 @@ type Namespaces<T extends BaseNamespaceType> = {
1056
1100
 
1057
1101
  declare const autoImportTypes: string[];
1058
1102
 
1059
- export { type AppConfig, type Awaitable, type BaseNamespaceType, type BaseSchemaType, type BaseSilgiMethodType, type CaptureError, type CapturedErrorContext, type CommandType, type CreateScope, type DeepPartial, type DefaultHooks, type DefaultNamespaces, type DotenvOptions, type EnvOptions, type EventHandlerResponse, type ExtendContext, type ExtendShared, type ExtractInputFromURI, type ExtractOutputFromURI, type ExtractPathParamsFromURI, type ExtractQueryParamsFromURI, type ExtractSourceFromURI, type FrameworkContext, type GenerateAppOptions, type GraphQLJSON, type HookResult, type ImportItem, type LoadConfigOptions, type MergedSilgiSchema, type MethodHandlerType, type ModuleDefinition, type ModuleHookContext, type ModuleMeta, type ModuleOptionsCustom, type ModuleSetupInstallResult, type ModuleSetupReturn, type Namespaces, type NitroBuildInfo, type PrepareCore, type RequiredServiceType, type ResolvedMethodHandlerType, type ResolvedModuleMeta, type ResolvedModuleOptions, type ResolvedServiceType, type ResolvedSilgiTemplate, type ScanFile, type SchemaPreparationOptions, type ServiceType, type Silgi, type SilgiAppPlugin, type SilgiCLI, type SilgiCLIConfig, type SilgiCLIDynamicConfig, type SilgiCLIHooks, type SilgiCLIOptions, type SilgiCompatibility, type SilgiCompatibilityIssue, type SilgiCompatibilityIssues, type SilgiConfig, type SilgiEvents, type SilgiFrameworkInfo, type SilgiFunction, type SilgiHooks, type SilgiModule, type SilgiModuleInput, type SilgiModuleOptions, type SilgiNamespaces, type SilgiOperation, type SilgiOptions, type SilgiPreset, type SilgiPresetMeta, type SilgiRouterTypes, type SilgiRuntimeActions, type SilgiRuntimeConfig, type SilgiRuntimeContext, type SilgiRuntimeHooks, type SilgiRuntimeMethods, type SilgiRuntimeOptions, type SilgiRuntimeSharedExtends, type SilgiRuntimeShareds, type SilgiSchema, type SilgiServiceInterface, type SilgiStorageBase, type SilgiTemplate, type SilgiURIs, type StorageConfig, type StorageKeyGenerator, type StorageKeyParams, type StorageMounts, type TSReference, type URIsTypes, autoImportTypes };
1103
+ export { type AppConfig, type Awaitable, type BaseNamespaceType, type BaseSchemaType, type BaseSilgiMethodType, type CaptureError, type CapturedErrorContext, type CommandType, type CreateScope, type DeepPartial, type DefaultHooks, type DefaultMergedRulesCache, type DefaultNamespaces, type DefaultRouteConfig, type DefaultRouterRulesConfig, type DotenvOptions, type EnvOptions, type EventHandlerResponse, type ExtendContext, type ExtendShared, type ExtractInputFromURI, type ExtractOutputFromURI, type ExtractPathParamsFromURI, type ExtractQueryParamsFromURI, type ExtractSourceFromURI, type FrameworkContext, type GenerateAppOptions, type GraphQLJSON, type HookResult, type ImportItem, type LoadConfigOptions, type MergedRulesCache, type MergedSilgiSchema, type MethodHandlerType, type ModuleDefinition, type ModuleHookContext, type ModuleMeta, type ModuleOptionsCustom, type ModuleSetupInstallResult, type ModuleSetupReturn, type Namespaces, type NitroBuildInfo, type PrepareCore, type RequiredServiceType, type ResolvedMethodHandlerType, type ResolvedModuleMeta, type ResolvedModuleOptions, type ResolvedServiceType, type ResolvedSilgiTemplate, type RouteConfig, type RouteRules, type RouteRulesConfig, type ScanFile, type SchemaPreparationOptions, type ServiceType, type Silgi, type SilgiAppPlugin, type SilgiCLI, type SilgiCLIConfig, type SilgiCLIDynamicConfig, type SilgiCLIHooks, type SilgiCLIOptions, type SilgiCompatibility, type SilgiCompatibilityIssue, type SilgiCompatibilityIssues, type SilgiConfig, type SilgiEvents, type SilgiFrameworkInfo, type SilgiFunction, type SilgiHooks, type SilgiModule, type SilgiModuleInput, type SilgiModuleOptions, type SilgiNamespaces, type SilgiOperation, type SilgiOptions, type SilgiPreset, type SilgiPresetMeta, type SilgiRouterTypes, type SilgiRuntimeActions, type SilgiRuntimeConfig, type SilgiRuntimeContext, type SilgiRuntimeHooks, type SilgiRuntimeMethods, type SilgiRuntimeOptions, type SilgiRuntimeRouteRules, type SilgiRuntimeSharedExtends, type SilgiRuntimeShareds, type SilgiSchema, type SilgiServiceInterface, type SilgiStorageBase, type SilgiTemplate, type SilgiURIs, type StorageConfig, type StorageKeyGenerator, type StorageKeyParams, type StorageMounts, type TSReference, type URIsTypes, autoImportTypes };
@@ -6,7 +6,7 @@ import { Hookable, NestedHooks } from 'hookable';
6
6
  import { Ignore, Options } from 'ignore';
7
7
  import { TSConfig } from 'pkg-types';
8
8
  import { PresetName, PresetOptions, PresetNameInput } from 'silgi/presets';
9
- import { ResolvedServiceType as ResolvedServiceType$1, SilgiRuntimeShareds as SilgiRuntimeShareds$1, SilgiRuntimeOptions as SilgiRuntimeOptions$1, ModuleMeta as ModuleMeta$1, DotenvOptions as DotenvOptions$1, EnvOptions as EnvOptions$1, SilgiRuntimeConfig as SilgiRuntimeConfig$1, SilgiCLIHooks as SilgiCLIHooks$1, StorageMounts as StorageMounts$1, SilgiTemplate as SilgiTemplate$1, SilgiFrameworkInfo as SilgiFrameworkInfo$1 } from 'silgi/types';
9
+ import { ResolvedServiceType as ResolvedServiceType$1, SilgiRuntimeShareds as SilgiRuntimeShareds$1, SilgiRuntimeOptions as SilgiRuntimeOptions$1, RouteRules as RouteRules$1, ModuleMeta as ModuleMeta$1, SilgiRuntimeRouteRules as SilgiRuntimeRouteRules$1, DotenvOptions as DotenvOptions$1, EnvOptions as EnvOptions$1, SilgiRuntimeConfig as SilgiRuntimeConfig$1, SilgiCLIHooks as SilgiCLIHooks$1, StorageMounts as StorageMounts$1, SilgiTemplate as SilgiTemplate$1, SilgiFrameworkInfo as SilgiFrameworkInfo$1 } from 'silgi/types';
10
10
  import { UnimportPluginOptions } from 'unimport/unplugin';
11
11
  import { Defu } from 'defu';
12
12
  import { Unimport } from 'unimport';
@@ -55,6 +55,7 @@ interface SilgiCLI {
55
55
  modulesURIs: Partial<Record<keyof SilgiRuntimeOptions$1 | (string & {}), any>>;
56
56
  scannedURIs: Map<string, string>;
57
57
  templates: SilgiTemplate[];
58
+ routeRules: RouteRules$1;
58
59
  hooks: Hookable<SilgiCLIHooks>;
59
60
  hook: SilgiCLI['hooks']['hook'];
60
61
  callHook: SilgiCLI['hooks']['callHook'];
@@ -170,6 +171,10 @@ interface SchemaPreparationOptions extends ImportItem {
170
171
  key: string;
171
172
  value: string;
172
173
  }[];
174
+ routeRules: {
175
+ key: string;
176
+ value: string;
177
+ }[];
173
178
  contexts: {
174
179
  key: string;
175
180
  value: string;
@@ -563,6 +568,7 @@ interface SilgiCLIOptions extends PresetOptions {
563
568
  command?: string;
564
569
  };
565
570
  commandType: CommandType;
571
+ routeRules: SilgiRuntimeRouteRules$1;
566
572
  environments: DotenvOptions$1[];
567
573
  activeEnvironment: string;
568
574
  envOptions: EnvOptions$1;
@@ -576,7 +582,6 @@ interface SilgiCLIOptions extends PresetOptions {
576
582
  path: string;
577
583
  packageImport: string;
578
584
  }[];
579
- routeRules: Record<string, string>;
580
585
  compatibilityDate: CompatibilityDates;
581
586
  modules: (SilgiModule<any> | string | [SilgiModule | string, Record<string, any>] | undefined | null | false)[];
582
587
  _modules: (SilgiModule<any> | string | [SilgiModule | string, Record<string, any>] | undefined | null | false)[];
@@ -866,6 +871,43 @@ interface ResolvedMethodHandlerType {
866
871
  execute: (input: StandardSchemaV1.InferInput<any>, shared: SilgiRuntimeShareds, event: SilgiEvents, source: StandardSchemaV1.InferInput<any>) => Promise<StandardSchemaV1.InferInput<any>>;
867
872
  }
868
873
 
874
+ type DefaultRouteConfig = Record<string, any>;
875
+ type DefaultRouterRulesConfig = Record<string, DefaultRouteConfig>;
876
+ type DefaultMergedRulesCache = Record<string, DefaultRouteConfig>;
877
+ type RouteConfig<T extends Record<string, any> = DefaultRouteConfig> = T;
878
+ type RouteRulesConfig<T extends Record<string, any> = DefaultRouteConfig> = Record<string, T>;
879
+ type MergedRulesCache<T extends Record<string, any> = DefaultRouteConfig> = Record<string, T>;
880
+ interface SilgiRuntimeRouteRules extends RouteConfig {
881
+ }
882
+ /**
883
+ * Interface for the object returned by createRouteRules
884
+ */
885
+ interface RouteRules<T extends Record<string, any> = SilgiRuntimeRouteRules> {
886
+ readonly rules: RouteRulesConfig<T>;
887
+ readonly mergedRules: MergedRulesCache<T>;
888
+ importRules: (config: RouteRulesConfig<T>) => void;
889
+ exportRules: () => RouteRulesConfig<T>;
890
+ addRule: (pattern: string, config: RouteConfig<T>) => void;
891
+ updateRule: (pattern: string, config: Partial<RouteConfig<T>>) => void;
892
+ removeRule: (pattern: string) => void;
893
+ matchesRule: (url: string, pattern: string) => boolean;
894
+ getMatchingPatterns: (url: string) => string[];
895
+ getConfig: (url: string) => RouteConfig<T> | null;
896
+ getParams: (url: string, pattern: string) => Record<string, string> | null;
897
+ match: (url: string) => {
898
+ pattern: string;
899
+ config: RouteConfig<T>;
900
+ params: Record<string, string> | null;
901
+ } | null;
902
+ clear: () => void;
903
+ clearMergedRules: () => void;
904
+ precomputeMergedRules: (urls: string[]) => void;
905
+ setMergedRule: (url: string, config: RouteConfig<T>) => void;
906
+ getMergedRules: () => MergedRulesCache<T>;
907
+ configure: (config: RouteRulesConfig<T>) => void;
908
+ updateMergeRules: () => MergedRulesCache<T>;
909
+ }
910
+
869
911
  type SilgiServiceInterface<T extends BaseSchemaType<StandardSchemaV1>> = {
870
912
  [Action in keyof T]: T[Action] extends Record<string, any> ? {
871
913
  [Method in keyof T[Action]]: {
@@ -927,6 +969,7 @@ interface Silgi {
927
969
  scannedHandlers: Map<string, ResolvedMethodHandlerType>;
928
970
  plugins: SilgiAppPlugin[];
929
971
  framework: FrameworkContext;
972
+ routeRules: RouteRules;
930
973
  _ignore?: Ignore;
931
974
  hooks: Hookable<SilgiRuntimeHooks & DefaultHooks>;
932
975
  hook: Silgi['hooks']['hook'];
@@ -987,6 +1030,7 @@ interface SilgiRuntimeConfig {
987
1030
  }
988
1031
  interface SilgiOptions {
989
1032
  consolaOptions?: Partial<ConsolaOptions>;
1033
+ routeRules: SilgiRuntimeRouteRules;
990
1034
  present: PresetNameInput;
991
1035
  hooks: Partial<SilgiRuntimeHooks & DefaultHooks>;
992
1036
  /**
@@ -1056,4 +1100,4 @@ type Namespaces<T extends BaseNamespaceType> = {
1056
1100
 
1057
1101
  declare const autoImportTypes: string[];
1058
1102
 
1059
- export { type AppConfig, type Awaitable, type BaseNamespaceType, type BaseSchemaType, type BaseSilgiMethodType, type CaptureError, type CapturedErrorContext, type CommandType, type CreateScope, type DeepPartial, type DefaultHooks, type DefaultNamespaces, type DotenvOptions, type EnvOptions, type EventHandlerResponse, type ExtendContext, type ExtendShared, type ExtractInputFromURI, type ExtractOutputFromURI, type ExtractPathParamsFromURI, type ExtractQueryParamsFromURI, type ExtractSourceFromURI, type FrameworkContext, type GenerateAppOptions, type GraphQLJSON, type HookResult, type ImportItem, type LoadConfigOptions, type MergedSilgiSchema, type MethodHandlerType, type ModuleDefinition, type ModuleHookContext, type ModuleMeta, type ModuleOptionsCustom, type ModuleSetupInstallResult, type ModuleSetupReturn, type Namespaces, type NitroBuildInfo, type PrepareCore, type RequiredServiceType, type ResolvedMethodHandlerType, type ResolvedModuleMeta, type ResolvedModuleOptions, type ResolvedServiceType, type ResolvedSilgiTemplate, type ScanFile, type SchemaPreparationOptions, type ServiceType, type Silgi, type SilgiAppPlugin, type SilgiCLI, type SilgiCLIConfig, type SilgiCLIDynamicConfig, type SilgiCLIHooks, type SilgiCLIOptions, type SilgiCompatibility, type SilgiCompatibilityIssue, type SilgiCompatibilityIssues, type SilgiConfig, type SilgiEvents, type SilgiFrameworkInfo, type SilgiFunction, type SilgiHooks, type SilgiModule, type SilgiModuleInput, type SilgiModuleOptions, type SilgiNamespaces, type SilgiOperation, type SilgiOptions, type SilgiPreset, type SilgiPresetMeta, type SilgiRouterTypes, type SilgiRuntimeActions, type SilgiRuntimeConfig, type SilgiRuntimeContext, type SilgiRuntimeHooks, type SilgiRuntimeMethods, type SilgiRuntimeOptions, type SilgiRuntimeSharedExtends, type SilgiRuntimeShareds, type SilgiSchema, type SilgiServiceInterface, type SilgiStorageBase, type SilgiTemplate, type SilgiURIs, type StorageConfig, type StorageKeyGenerator, type StorageKeyParams, type StorageMounts, type TSReference, type URIsTypes, autoImportTypes };
1103
+ export { type AppConfig, type Awaitable, type BaseNamespaceType, type BaseSchemaType, type BaseSilgiMethodType, type CaptureError, type CapturedErrorContext, type CommandType, type CreateScope, type DeepPartial, type DefaultHooks, type DefaultMergedRulesCache, type DefaultNamespaces, type DefaultRouteConfig, type DefaultRouterRulesConfig, type DotenvOptions, type EnvOptions, type EventHandlerResponse, type ExtendContext, type ExtendShared, type ExtractInputFromURI, type ExtractOutputFromURI, type ExtractPathParamsFromURI, type ExtractQueryParamsFromURI, type ExtractSourceFromURI, type FrameworkContext, type GenerateAppOptions, type GraphQLJSON, type HookResult, type ImportItem, type LoadConfigOptions, type MergedRulesCache, type MergedSilgiSchema, type MethodHandlerType, type ModuleDefinition, type ModuleHookContext, type ModuleMeta, type ModuleOptionsCustom, type ModuleSetupInstallResult, type ModuleSetupReturn, type Namespaces, type NitroBuildInfo, type PrepareCore, type RequiredServiceType, type ResolvedMethodHandlerType, type ResolvedModuleMeta, type ResolvedModuleOptions, type ResolvedServiceType, type ResolvedSilgiTemplate, type RouteConfig, type RouteRules, type RouteRulesConfig, type ScanFile, type SchemaPreparationOptions, type ServiceType, type Silgi, type SilgiAppPlugin, type SilgiCLI, type SilgiCLIConfig, type SilgiCLIDynamicConfig, type SilgiCLIHooks, type SilgiCLIOptions, type SilgiCompatibility, type SilgiCompatibilityIssue, type SilgiCompatibilityIssues, type SilgiConfig, type SilgiEvents, type SilgiFrameworkInfo, type SilgiFunction, type SilgiHooks, type SilgiModule, type SilgiModuleInput, type SilgiModuleOptions, type SilgiNamespaces, type SilgiOperation, type SilgiOptions, type SilgiPreset, type SilgiPresetMeta, type SilgiRouterTypes, type SilgiRuntimeActions, type SilgiRuntimeConfig, type SilgiRuntimeContext, type SilgiRuntimeHooks, type SilgiRuntimeMethods, type SilgiRuntimeOptions, type SilgiRuntimeRouteRules, type SilgiRuntimeSharedExtends, type SilgiRuntimeShareds, type SilgiSchema, type SilgiServiceInterface, type SilgiStorageBase, type SilgiTemplate, type SilgiURIs, type StorageConfig, type StorageKeyGenerator, type StorageKeyParams, type StorageMounts, type TSReference, type URIsTypes, autoImportTypes };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "silgi",
3
3
  "type": "module",
4
- "version": "0.14.4",
4
+ "version": "0.15.0",
5
5
  "private": false,
6
6
  "sideEffects": false,
7
7
  "exports": {
@@ -113,7 +113,7 @@
113
113
  "dependencies": {
114
114
  "@clack/prompts": "^0.10.0",
115
115
  "@fastify/deepmerge": "^2.0.2",
116
- "@oxc-parser/wasm": "^0.53.0",
116
+ "@oxc-parser/wasm": "^0.56.0",
117
117
  "@standard-schema/spec": "^1.0.0",
118
118
  "c12": "^3.0.2",
119
119
  "chokidar": "^4.0.3",
@@ -133,13 +133,13 @@
133
133
  "knitwork": "^1.2.0",
134
134
  "mlly": "^1.7.4",
135
135
  "ofetch": "^1.4.1",
136
- "ohash": "^2.0.9",
136
+ "ohash": "^2.0.11",
137
137
  "pathe": "^2.0.3",
138
138
  "picocolors": "^1.1.1",
139
- "pkg-types": "^2.0.1",
139
+ "pkg-types": "^2.1.0",
140
140
  "scule": "^1.3.0",
141
141
  "semver": "^7.7.1",
142
- "std-env": "^3.8.0",
142
+ "std-env": "^3.8.1",
143
143
  "ufo": "^1.5.4",
144
144
  "unctx": "^2.4.1",
145
145
  "unimport": "^4.1.2",
@@ -147,19 +147,19 @@
147
147
  "untyped": "^2.0.0"
148
148
  },
149
149
  "devDependencies": {
150
- "@antfu/eslint-config": "^4.4.0",
150
+ "@antfu/eslint-config": "^4.6.0",
151
151
  "@nuxt/kit": "^3.15.4",
152
152
  "@nuxt/schema": "^3.15.4",
153
- "@types/node": "^22.13.8",
153
+ "@types/node": "^22.13.9",
154
154
  "@types/semver": "^7.5.8",
155
155
  "@vitest/coverage-v8": "3.0.5",
156
156
  "eslint": "^9.21.0",
157
157
  "h3": "^1.15.1",
158
- "nitropack": "^2.10.4",
158
+ "nitropack": "^2.11.4",
159
159
  "nuxt": "^3.15.4",
160
160
  "typescript": "^5.8.2",
161
161
  "unbuild": "^3.5.0",
162
- "vitest": "^3.0.7",
162
+ "vitest": "^3.0.8",
163
163
  "vue": "^3.5.13",
164
164
  "zod": "^3.24.2"
165
165
  },