silgi 0.27.5 → 0.27.6
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/_chunks/silgiApp.mjs +287 -1
- package/dist/build.d.mts +3 -16
- package/dist/build.mjs +8 -32
- package/dist/cli/build.mjs +861 -0
- package/dist/cli/config/index.mjs +2 -1
- package/dist/cli/dev.mjs +12 -12
- package/dist/cli/index.mjs +1 -1
- package/dist/cli/init.mjs +14 -14
- package/dist/cli/install.mjs +14 -14
- package/dist/cli/loader.mjs +598 -0
- package/dist/cli/prepare.mjs +1575 -18
- package/dist/cli/types.mjs +6 -597
- package/dist/core/index.mjs +2 -2
- package/dist/index.mjs +1 -2
- package/package.json +1 -1
- package/dist/_chunks/routeRules.mjs +0 -288
- package/dist/cli/writeTypesAndFiles.mjs +0 -2413
|
@@ -1,6 +1,292 @@
|
|
|
1
|
+
import { withoutTrailingSlash, withLeadingSlash } from 'ufo';
|
|
1
2
|
import consola from 'consola';
|
|
2
3
|
import { getContext } from 'unctx';
|
|
3
4
|
|
|
5
|
+
function patternToRegex(pattern) {
|
|
6
|
+
let regexStr = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&");
|
|
7
|
+
regexStr = regexStr.replace(/\*\*/g, ".+");
|
|
8
|
+
regexStr = regexStr.replace(/\*/g, "[^/]+");
|
|
9
|
+
regexStr = regexStr.replace(/:([^/]+)/g, "([^/]+)");
|
|
10
|
+
return new RegExp(`^${regexStr}$`);
|
|
11
|
+
}
|
|
12
|
+
function extractParams(url, pattern) {
|
|
13
|
+
url = withoutTrailingSlash(withLeadingSlash(url));
|
|
14
|
+
pattern = withoutTrailingSlash(withLeadingSlash(pattern));
|
|
15
|
+
if (!pattern.includes(":"))
|
|
16
|
+
return null;
|
|
17
|
+
const paramNames = [];
|
|
18
|
+
const patternRegex = pattern.replace(/:([^/]+)/g, (_, name) => {
|
|
19
|
+
paramNames.push(name);
|
|
20
|
+
return "([^/]+)";
|
|
21
|
+
});
|
|
22
|
+
const regex = new RegExp(`^${patternRegex}$`);
|
|
23
|
+
const matches = url.match(regex);
|
|
24
|
+
if (!matches)
|
|
25
|
+
return null;
|
|
26
|
+
const params = {};
|
|
27
|
+
paramNames.forEach((name, i) => {
|
|
28
|
+
params[name] = matches[i + 1];
|
|
29
|
+
});
|
|
30
|
+
return Object.keys(params).length > 0 ? params : null;
|
|
31
|
+
}
|
|
32
|
+
function matchesPattern(url, pattern) {
|
|
33
|
+
url = withoutTrailingSlash(withLeadingSlash(url));
|
|
34
|
+
pattern = withoutTrailingSlash(withLeadingSlash(pattern));
|
|
35
|
+
if (url === pattern)
|
|
36
|
+
return true;
|
|
37
|
+
if (pattern.endsWith("/**")) {
|
|
38
|
+
const basePath = pattern.slice(0, -3);
|
|
39
|
+
return url === basePath || url.startsWith(`${basePath}/`);
|
|
40
|
+
}
|
|
41
|
+
const urlParts = url.split("/");
|
|
42
|
+
const patternParts = pattern.split("/");
|
|
43
|
+
if (!pattern.includes("**") && urlParts.length !== patternParts.length) {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
if (pattern.includes("/**/")) {
|
|
47
|
+
const [prefix, ...suffixParts] = pattern.split("/**/");
|
|
48
|
+
const suffix = suffixParts.join("/");
|
|
49
|
+
return url.startsWith(prefix) && (!suffix || url.endsWith(`/${suffix}`));
|
|
50
|
+
}
|
|
51
|
+
return patternToRegex(pattern).test(url);
|
|
52
|
+
}
|
|
53
|
+
function deepClone(obj) {
|
|
54
|
+
if (obj === null || typeof obj !== "object")
|
|
55
|
+
return obj;
|
|
56
|
+
if (typeof obj === "function")
|
|
57
|
+
return obj;
|
|
58
|
+
if (Array.isArray(obj))
|
|
59
|
+
return obj.map(deepClone);
|
|
60
|
+
const cloned = {};
|
|
61
|
+
for (const key in obj) {
|
|
62
|
+
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
63
|
+
cloned[key] = deepClone(obj[key]);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return cloned;
|
|
67
|
+
}
|
|
68
|
+
function mergeConfigs(...configs) {
|
|
69
|
+
const result = {};
|
|
70
|
+
for (const config of configs) {
|
|
71
|
+
if (!config)
|
|
72
|
+
continue;
|
|
73
|
+
for (const key in config) {
|
|
74
|
+
const value = config[key];
|
|
75
|
+
if (value && typeof value === "object" && !Array.isArray(value) && result[key] && typeof result[key] === "object" && typeof result[key] !== "function") {
|
|
76
|
+
const resultValue = result[key];
|
|
77
|
+
const valueToMerge = value;
|
|
78
|
+
result[key] = mergeConfigs(resultValue, valueToMerge);
|
|
79
|
+
} else {
|
|
80
|
+
result[key] = value;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return result;
|
|
85
|
+
}
|
|
86
|
+
function createRouteRules() {
|
|
87
|
+
let _rules = {};
|
|
88
|
+
let _mergedRules = {};
|
|
89
|
+
let _rulesModified = false;
|
|
90
|
+
function getRules() {
|
|
91
|
+
return deepClone(_rules);
|
|
92
|
+
}
|
|
93
|
+
function importRules(config) {
|
|
94
|
+
const normalizedConfig = {};
|
|
95
|
+
for (const pattern in config) {
|
|
96
|
+
normalizedConfig[withoutTrailingSlash(withLeadingSlash(pattern))] = deepClone(config[pattern]);
|
|
97
|
+
}
|
|
98
|
+
_rules = normalizedConfig;
|
|
99
|
+
_rulesModified = true;
|
|
100
|
+
updateMergeRules();
|
|
101
|
+
}
|
|
102
|
+
function exportRules() {
|
|
103
|
+
return deepClone(_rules);
|
|
104
|
+
}
|
|
105
|
+
function addRule(pattern, config) {
|
|
106
|
+
_rules[withoutTrailingSlash(withLeadingSlash(pattern))] = deepClone(config);
|
|
107
|
+
_rulesModified = true;
|
|
108
|
+
updateMergeRules();
|
|
109
|
+
}
|
|
110
|
+
function updateRule(pattern, config) {
|
|
111
|
+
const normalizedPattern = withoutTrailingSlash(withLeadingSlash(pattern));
|
|
112
|
+
if (_rules[normalizedPattern]) {
|
|
113
|
+
_rules[normalizedPattern] = { ..._rules[normalizedPattern], ...deepClone(config) };
|
|
114
|
+
} else {
|
|
115
|
+
_rules[normalizedPattern] = deepClone(config);
|
|
116
|
+
}
|
|
117
|
+
_rulesModified = true;
|
|
118
|
+
updateMergeRules();
|
|
119
|
+
}
|
|
120
|
+
function removeRule(pattern) {
|
|
121
|
+
delete _rules[withoutTrailingSlash(withLeadingSlash(pattern))];
|
|
122
|
+
_rulesModified = true;
|
|
123
|
+
updateMergeRules();
|
|
124
|
+
}
|
|
125
|
+
function matchesRule(url, pattern) {
|
|
126
|
+
return matchesPattern(withoutTrailingSlash(withLeadingSlash(url)), withoutTrailingSlash(withLeadingSlash(pattern)));
|
|
127
|
+
}
|
|
128
|
+
function getMatchingPatterns(url) {
|
|
129
|
+
const normalizedUrl = withoutTrailingSlash(withLeadingSlash(url));
|
|
130
|
+
return Object.keys(_rules).filter((pattern) => matchesPattern(normalizedUrl, pattern)).sort((a, b) => {
|
|
131
|
+
if (a === url)
|
|
132
|
+
return -1;
|
|
133
|
+
if (b === url)
|
|
134
|
+
return 1;
|
|
135
|
+
const aSegments = a.split("/").filter(Boolean).length;
|
|
136
|
+
const bSegments = b.split("/").filter(Boolean).length;
|
|
137
|
+
if (aSegments !== bSegments)
|
|
138
|
+
return bSegments - aSegments;
|
|
139
|
+
const aWildcards = (a.match(/\*/g) || []).length;
|
|
140
|
+
const bWildcards = (b.match(/\*/g) || []).length;
|
|
141
|
+
if (aWildcards !== bWildcards)
|
|
142
|
+
return aWildcards - bWildcards;
|
|
143
|
+
const aDoubleWildcards = (a.match(/\*\*/g) || []).length;
|
|
144
|
+
const bDoubleWildcards = (b.match(/\*\*/g) || []).length;
|
|
145
|
+
if (aDoubleWildcards !== bDoubleWildcards)
|
|
146
|
+
return aDoubleWildcards - bDoubleWildcards;
|
|
147
|
+
return b.length - a.length;
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
function getConfig(url) {
|
|
151
|
+
const normalizedUrl = withoutTrailingSlash(withLeadingSlash(url));
|
|
152
|
+
if (_rulesModified) {
|
|
153
|
+
updateMergeRules();
|
|
154
|
+
}
|
|
155
|
+
if (_mergedRules[normalizedUrl]) {
|
|
156
|
+
return deepClone(_mergedRules[normalizedUrl]);
|
|
157
|
+
}
|
|
158
|
+
const patterns = getMatchingPatterns(normalizedUrl);
|
|
159
|
+
if (!patterns.length)
|
|
160
|
+
return null;
|
|
161
|
+
const mergedConfig = {};
|
|
162
|
+
for (let i = patterns.length - 1; i >= 0; i--) {
|
|
163
|
+
const pattern = patterns[i];
|
|
164
|
+
const patternConfig = _mergedRules[pattern] || _rules[pattern];
|
|
165
|
+
Object.assign(mergedConfig, deepClone(patternConfig));
|
|
166
|
+
}
|
|
167
|
+
_mergedRules[normalizedUrl] = deepClone(mergedConfig);
|
|
168
|
+
return mergedConfig;
|
|
169
|
+
}
|
|
170
|
+
function computeMergedConfig(url, patterns) {
|
|
171
|
+
const normalizedUrl = withoutTrailingSlash(withLeadingSlash(url));
|
|
172
|
+
const matchingPatterns = patterns || getMatchingPatterns(normalizedUrl);
|
|
173
|
+
if (!matchingPatterns.length)
|
|
174
|
+
return {};
|
|
175
|
+
const allPatternsHaveCache = matchingPatterns.every((pattern) => !!_mergedRules[pattern]);
|
|
176
|
+
if (allPatternsHaveCache) {
|
|
177
|
+
return matchingPatterns.reduceRight((result, pattern) => mergeConfigs(result, deepClone(_mergedRules[pattern])), {});
|
|
178
|
+
}
|
|
179
|
+
return matchingPatterns.reduceRight((result, pattern) => mergeConfigs(result, deepClone(_rules[pattern])), {});
|
|
180
|
+
}
|
|
181
|
+
function getParams(url, pattern) {
|
|
182
|
+
return extractParams(withoutTrailingSlash(withLeadingSlash(url)), withoutTrailingSlash(withLeadingSlash(pattern)));
|
|
183
|
+
}
|
|
184
|
+
function match(url) {
|
|
185
|
+
const normalizedUrl = withoutTrailingSlash(withLeadingSlash(url));
|
|
186
|
+
const patterns = getMatchingPatterns(normalizedUrl);
|
|
187
|
+
if (!patterns.length)
|
|
188
|
+
return null;
|
|
189
|
+
const bestPattern = patterns[0];
|
|
190
|
+
return {
|
|
191
|
+
pattern: bestPattern,
|
|
192
|
+
config: deepClone(_rules[bestPattern]),
|
|
193
|
+
params: getParams(normalizedUrl, bestPattern)
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
function clear() {
|
|
197
|
+
_rules = {};
|
|
198
|
+
clearMergedRules();
|
|
199
|
+
_rulesModified = false;
|
|
200
|
+
}
|
|
201
|
+
function clearMergedRules() {
|
|
202
|
+
_mergedRules = {};
|
|
203
|
+
_rulesModified = true;
|
|
204
|
+
}
|
|
205
|
+
function precomputeMergedRules(urls) {
|
|
206
|
+
if (_rulesModified) {
|
|
207
|
+
updateMergeRules();
|
|
208
|
+
}
|
|
209
|
+
for (const url of urls) {
|
|
210
|
+
const normalizedUrl = withoutTrailingSlash(withLeadingSlash(url));
|
|
211
|
+
if (!_mergedRules[normalizedUrl]) {
|
|
212
|
+
const patterns = getMatchingPatterns(normalizedUrl);
|
|
213
|
+
if (patterns.length) {
|
|
214
|
+
_mergedRules[normalizedUrl] = computeMergedConfig(normalizedUrl, patterns);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
function setMergedRule(url, config) {
|
|
220
|
+
const normalizedUrl = withoutTrailingSlash(withLeadingSlash(url));
|
|
221
|
+
_mergedRules[normalizedUrl] = deepClone(config);
|
|
222
|
+
if (url.includes("*") || url.includes(":")) {
|
|
223
|
+
_rulesModified = false;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
function getMergedRules() {
|
|
227
|
+
return deepClone(_mergedRules);
|
|
228
|
+
}
|
|
229
|
+
function configure(config) {
|
|
230
|
+
importRules(config);
|
|
231
|
+
}
|
|
232
|
+
function updateMergeRules() {
|
|
233
|
+
if (!_rulesModified) {
|
|
234
|
+
return _mergedRules;
|
|
235
|
+
}
|
|
236
|
+
_mergedRules = {};
|
|
237
|
+
const rulePatterns = Object.keys(_rules);
|
|
238
|
+
for (const pattern of rulePatterns) {
|
|
239
|
+
const patterns = getMatchingPatterns(pattern);
|
|
240
|
+
_mergedRules[pattern] = computeMergedConfig(pattern, patterns);
|
|
241
|
+
}
|
|
242
|
+
for (const pattern of rulePatterns) {
|
|
243
|
+
if (pattern.includes("/:")) {
|
|
244
|
+
const segments = pattern.split("/");
|
|
245
|
+
let partialPath = "";
|
|
246
|
+
for (const segment of segments) {
|
|
247
|
+
if (segment) {
|
|
248
|
+
partialPath += `/${segment}`;
|
|
249
|
+
if (segment.startsWith(":") && partialPath !== pattern) {
|
|
250
|
+
const samplePath = partialPath.replace(/:\w+/g, "sample");
|
|
251
|
+
const patterns = getMatchingPatterns(samplePath);
|
|
252
|
+
_mergedRules[samplePath] = computeMergedConfig(samplePath, patterns);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
_rulesModified = false;
|
|
259
|
+
return _mergedRules;
|
|
260
|
+
}
|
|
261
|
+
return {
|
|
262
|
+
// Public getters that return a cloned version to prevent direct modification
|
|
263
|
+
get rules() {
|
|
264
|
+
return getRules();
|
|
265
|
+
},
|
|
266
|
+
get mergedRules() {
|
|
267
|
+
return getMergedRules();
|
|
268
|
+
},
|
|
269
|
+
// API methods
|
|
270
|
+
importRules,
|
|
271
|
+
exportRules,
|
|
272
|
+
addRule,
|
|
273
|
+
updateRule,
|
|
274
|
+
removeRule,
|
|
275
|
+
matchesRule,
|
|
276
|
+
getMatchingPatterns,
|
|
277
|
+
getConfig,
|
|
278
|
+
getParams,
|
|
279
|
+
match,
|
|
280
|
+
clear,
|
|
281
|
+
clearMergedRules,
|
|
282
|
+
precomputeMergedRules,
|
|
283
|
+
setMergedRule,
|
|
284
|
+
getMergedRules,
|
|
285
|
+
configure,
|
|
286
|
+
updateMergeRules
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
|
|
4
290
|
const silgiCLICtx = getContext("silgiCLI");
|
|
5
291
|
function useSilgiCLI() {
|
|
6
292
|
const instance = silgiCLICtx.tryUse();
|
|
@@ -22,4 +308,4 @@ function tryUseSilgiCLI() {
|
|
|
22
308
|
return silgiCLICtx.tryUse();
|
|
23
309
|
}
|
|
24
310
|
|
|
25
|
-
export { silgiCLIIClose as a, silgiCLICtx as s, tryUseSilgiCLI as t, useSilgiCLI as u };
|
|
311
|
+
export { silgiCLIIClose as a, createRouteRules as c, silgiCLICtx as s, tryUseSilgiCLI as t, useSilgiCLI as u };
|
package/dist/build.d.mts
CHANGED
|
@@ -1,18 +1,5 @@
|
|
|
1
|
-
import { SilgiCLI
|
|
1
|
+
import { SilgiCLI } from 'silgi/types';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
* Prepares route rules for the build
|
|
5
|
-
*/
|
|
6
|
-
declare function prepareBuild(silgi: SilgiCLI): Promise<void>;
|
|
3
|
+
declare function build(silgi: SilgiCLI): Promise<void>;
|
|
7
4
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
declare function prepare(_silgi: SilgiCLI): Promise<void>;
|
|
11
|
-
|
|
12
|
-
declare function createSilgiCLI(config?: SilgiCLIConfig, opts?: LoadConfigOptions): Promise<SilgiCLI>;
|
|
13
|
-
|
|
14
|
-
declare function writeCoreFile(silgi: SilgiCLI): Promise<void>;
|
|
15
|
-
|
|
16
|
-
declare function writeTypesAndFiles(silgi: SilgiCLI): Promise<void>;
|
|
17
|
-
|
|
18
|
-
export { createSilgiCLI, generateApiFul, prepare, prepareBuild, writeCoreFile, writeTypesAndFiles };
|
|
5
|
+
export { build };
|
package/dist/build.mjs
CHANGED
|
@@ -1,41 +1,17 @@
|
|
|
1
|
-
export {
|
|
2
|
-
import 'knitwork';
|
|
3
|
-
import 'pathe';
|
|
4
|
-
import 'silgi/kit';
|
|
1
|
+
export { b as build } from './cli/build.mjs';
|
|
5
2
|
import 'apiful/openapi';
|
|
6
3
|
import 'consola';
|
|
4
|
+
import 'pathe';
|
|
5
|
+
import 'silgi/kit';
|
|
7
6
|
import 'node:fs';
|
|
8
7
|
import 'node:fs/promises';
|
|
9
|
-
import '
|
|
10
|
-
import '
|
|
8
|
+
import 'knitwork';
|
|
9
|
+
import 'mlly';
|
|
10
|
+
import 'pathe/utils';
|
|
11
11
|
import 'silgi/runtime/meta';
|
|
12
12
|
import 'unimport';
|
|
13
|
-
import './_chunks/routeRules.mjs';
|
|
14
|
-
import 'ufo';
|
|
15
|
-
import '@clack/prompts';
|
|
16
|
-
import 'dotenv';
|
|
17
|
-
import 'mlly';
|
|
18
|
-
import 'dev-jiti';
|
|
19
|
-
import './cli/compatibility.mjs';
|
|
20
|
-
import 'semver/functions/satisfies.js';
|
|
21
|
-
import 'silgi/meta';
|
|
22
|
-
import 'node:url';
|
|
23
|
-
import 'defu';
|
|
24
|
-
import 'exsolve';
|
|
25
13
|
import 'untyped';
|
|
26
|
-
import 'globby';
|
|
27
|
-
import 'ignore';
|
|
28
|
-
import '@oxc-parser/wasm';
|
|
29
|
-
import 'klona';
|
|
30
|
-
import 'silgi/runtime';
|
|
31
|
-
import 'unstorage';
|
|
32
|
-
import 'scule';
|
|
33
14
|
import './cli/types.mjs';
|
|
34
|
-
import '
|
|
35
|
-
import 'compatx';
|
|
36
|
-
import 'klona/full';
|
|
37
|
-
import 'std-env';
|
|
38
|
-
import 'consola/utils';
|
|
39
|
-
import 'escape-string-regexp';
|
|
15
|
+
import 'defu';
|
|
40
16
|
import 'pkg-types';
|
|
41
|
-
import '
|
|
17
|
+
import 'ufo';
|