@mokup/shared 1.1.0 → 1.1.2

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.
Files changed (71) hide show
  1. package/dist/config-core.cjs +9 -0
  2. package/dist/config-core.d.cts +4 -0
  3. package/dist/config-core.d.mts +4 -0
  4. package/dist/config-core.d.ts +4 -0
  5. package/dist/config-core.mjs +6 -0
  6. package/dist/config-utils.cjs +179 -0
  7. package/dist/config-utils.d.cts +62 -0
  8. package/dist/config-utils.d.mts +62 -0
  9. package/dist/config-utils.d.ts +62 -0
  10. package/dist/config-utils.mjs +171 -0
  11. package/dist/define-config.cjs +168 -0
  12. package/dist/define-config.d.cts +20 -0
  13. package/dist/define-config.d.mts +20 -0
  14. package/dist/define-config.d.ts +20 -0
  15. package/dist/define-config.mjs +166 -0
  16. package/dist/index.cjs +48 -0
  17. package/dist/index.d.cts +10 -98
  18. package/dist/index.d.mts +10 -98
  19. package/dist/index.d.ts +10 -98
  20. package/dist/index.mjs +18 -1
  21. package/dist/jsonc-utils.cjs +25 -0
  22. package/dist/jsonc-utils.d.cts +7 -0
  23. package/dist/jsonc-utils.d.mts +7 -0
  24. package/dist/jsonc-utils.d.ts +7 -0
  25. package/dist/jsonc-utils.mjs +23 -0
  26. package/dist/load-rules.cjs +39 -0
  27. package/dist/load-rules.d.cts +14 -0
  28. package/dist/load-rules.d.mts +14 -0
  29. package/dist/load-rules.d.ts +14 -0
  30. package/dist/load-rules.mjs +37 -0
  31. package/dist/mock-files.cjs +65 -0
  32. package/dist/mock-files.d.cts +10 -0
  33. package/dist/mock-files.d.mts +10 -0
  34. package/dist/mock-files.d.ts +10 -0
  35. package/dist/mock-files.mjs +61 -0
  36. package/dist/module-loader.cjs +93 -0
  37. package/dist/module-loader.d.cts +13 -0
  38. package/dist/module-loader.d.mts +13 -0
  39. package/dist/module-loader.d.ts +13 -0
  40. package/dist/module-loader.mjs +83 -0
  41. package/dist/path-utils.cjs +57 -0
  42. package/dist/path-utils.d.cts +7 -0
  43. package/dist/path-utils.d.mts +7 -0
  44. package/dist/path-utils.d.ts +7 -0
  45. package/dist/path-utils.mjs +51 -0
  46. package/dist/playground-grouping.cjs +95 -0
  47. package/dist/playground-grouping.d.cts +12 -0
  48. package/dist/playground-grouping.d.mts +12 -0
  49. package/dist/playground-grouping.d.ts +12 -0
  50. package/dist/playground-grouping.mjs +90 -0
  51. package/dist/route-constants.cjs +30 -0
  52. package/dist/route-constants.d.cts +7 -0
  53. package/dist/route-constants.d.mts +7 -0
  54. package/dist/route-constants.d.ts +7 -0
  55. package/dist/route-constants.mjs +24 -0
  56. package/dist/route-utils.cjs +126 -0
  57. package/dist/route-utils.d.cts +42 -0
  58. package/dist/route-utils.d.mts +42 -0
  59. package/dist/route-utils.d.ts +42 -0
  60. package/dist/route-utils.mjs +124 -0
  61. package/dist/scan-utils.cjs +39 -0
  62. package/dist/scan-utils.d.cts +114 -0
  63. package/dist/scan-utils.d.mts +114 -0
  64. package/dist/scan-utils.d.ts +114 -0
  65. package/dist/scan-utils.mjs +34 -0
  66. package/dist/timing.cjs +20 -0
  67. package/dist/timing.d.cts +4 -0
  68. package/dist/timing.d.mts +4 -0
  69. package/dist/timing.d.ts +4 -0
  70. package/dist/timing.mjs +17 -0
  71. package/package.json +81 -18
@@ -0,0 +1,42 @@
1
+ interface RouteParserResult<TToken = unknown> {
2
+ template: string;
3
+ tokens: TToken[];
4
+ score: number[];
5
+ errors: string[];
6
+ warnings: string[];
7
+ }
8
+ type RouteParser<TToken = unknown> = (template: string) => RouteParserResult<TToken>;
9
+ type RouteScoreComparator = (a: number[], b: number[]) => number;
10
+ interface DerivedRoute<TToken = unknown> {
11
+ template: string;
12
+ method: string;
13
+ tokens: TToken[];
14
+ score: number[];
15
+ }
16
+ declare function createRouteUtils<TToken = unknown, TRule extends {
17
+ handler: unknown;
18
+ } = {
19
+ handler: unknown;
20
+ }>(params: {
21
+ parseRouteTemplate: RouteParser<TToken>;
22
+ compareRouteScore: RouteScoreComparator;
23
+ }): {
24
+ deriveRouteFromFile: (file: string, rootDir: string, warn?: (message: string) => void) => DerivedRoute<TToken> | null;
25
+ resolveRule: <TOutput = DerivedRoute<TToken>>(input: {
26
+ rule: TRule;
27
+ derivedTemplate: string;
28
+ derivedMethod?: string;
29
+ prefix: string;
30
+ file: string;
31
+ warn?: (message: string) => void;
32
+ build?: (base: DerivedRoute<TToken>, rule: TRule) => TOutput;
33
+ }) => TOutput | null;
34
+ sortRoutes: <TRoute extends {
35
+ method: string;
36
+ score: number[];
37
+ template: string;
38
+ }>(routes: TRoute[]) => TRoute[];
39
+ };
40
+
41
+ export { createRouteUtils };
42
+ export type { DerivedRoute, RouteParser, RouteParserResult, RouteScoreComparator };
@@ -0,0 +1,42 @@
1
+ interface RouteParserResult<TToken = unknown> {
2
+ template: string;
3
+ tokens: TToken[];
4
+ score: number[];
5
+ errors: string[];
6
+ warnings: string[];
7
+ }
8
+ type RouteParser<TToken = unknown> = (template: string) => RouteParserResult<TToken>;
9
+ type RouteScoreComparator = (a: number[], b: number[]) => number;
10
+ interface DerivedRoute<TToken = unknown> {
11
+ template: string;
12
+ method: string;
13
+ tokens: TToken[];
14
+ score: number[];
15
+ }
16
+ declare function createRouteUtils<TToken = unknown, TRule extends {
17
+ handler: unknown;
18
+ } = {
19
+ handler: unknown;
20
+ }>(params: {
21
+ parseRouteTemplate: RouteParser<TToken>;
22
+ compareRouteScore: RouteScoreComparator;
23
+ }): {
24
+ deriveRouteFromFile: (file: string, rootDir: string, warn?: (message: string) => void) => DerivedRoute<TToken> | null;
25
+ resolveRule: <TOutput = DerivedRoute<TToken>>(input: {
26
+ rule: TRule;
27
+ derivedTemplate: string;
28
+ derivedMethod?: string;
29
+ prefix: string;
30
+ file: string;
31
+ warn?: (message: string) => void;
32
+ build?: (base: DerivedRoute<TToken>, rule: TRule) => TOutput;
33
+ }) => TOutput | null;
34
+ sortRoutes: <TRoute extends {
35
+ method: string;
36
+ score: number[];
37
+ template: string;
38
+ }>(routes: TRoute[]) => TRoute[];
39
+ };
40
+
41
+ export { createRouteUtils };
42
+ export type { DerivedRoute, RouteParser, RouteParserResult, RouteScoreComparator };
@@ -0,0 +1,42 @@
1
+ interface RouteParserResult<TToken = unknown> {
2
+ template: string;
3
+ tokens: TToken[];
4
+ score: number[];
5
+ errors: string[];
6
+ warnings: string[];
7
+ }
8
+ type RouteParser<TToken = unknown> = (template: string) => RouteParserResult<TToken>;
9
+ type RouteScoreComparator = (a: number[], b: number[]) => number;
10
+ interface DerivedRoute<TToken = unknown> {
11
+ template: string;
12
+ method: string;
13
+ tokens: TToken[];
14
+ score: number[];
15
+ }
16
+ declare function createRouteUtils<TToken = unknown, TRule extends {
17
+ handler: unknown;
18
+ } = {
19
+ handler: unknown;
20
+ }>(params: {
21
+ parseRouteTemplate: RouteParser<TToken>;
22
+ compareRouteScore: RouteScoreComparator;
23
+ }): {
24
+ deriveRouteFromFile: (file: string, rootDir: string, warn?: (message: string) => void) => DerivedRoute<TToken> | null;
25
+ resolveRule: <TOutput = DerivedRoute<TToken>>(input: {
26
+ rule: TRule;
27
+ derivedTemplate: string;
28
+ derivedMethod?: string;
29
+ prefix: string;
30
+ file: string;
31
+ warn?: (message: string) => void;
32
+ build?: (base: DerivedRoute<TToken>, rule: TRule) => TOutput;
33
+ }) => TOutput | null;
34
+ sortRoutes: <TRoute extends {
35
+ method: string;
36
+ score: number[];
37
+ template: string;
38
+ }>(routes: TRoute[]) => TRoute[];
39
+ };
40
+
41
+ export { createRouteUtils };
42
+ export type { DerivedRoute, RouteParser, RouteParserResult, RouteScoreComparator };
@@ -0,0 +1,124 @@
1
+ import { toPosix } from './path-utils.mjs';
2
+ import { relative, extname, dirname, basename, join } from 'pathe';
3
+ import { jsonExtensions, methodSuffixSet } from './route-constants.mjs';
4
+ import { normalizePrefix } from './scan-utils.mjs';
5
+ import 'node:process';
6
+
7
+ function createRouteUtils(params) {
8
+ const { parseRouteTemplate, compareRouteScore } = params;
9
+ function resolveTemplate(template, prefix) {
10
+ const normalized = template.startsWith("/") ? template : `/${template}`;
11
+ if (!prefix) {
12
+ return normalized;
13
+ }
14
+ const normalizedPrefix = normalizePrefix(prefix);
15
+ if (!normalizedPrefix) {
16
+ return normalized;
17
+ }
18
+ if (normalized === normalizedPrefix || normalized.startsWith(`${normalizedPrefix}/`)) {
19
+ return normalized;
20
+ }
21
+ if (normalized === "/") {
22
+ return `${normalizedPrefix}/`;
23
+ }
24
+ return `${normalizedPrefix}${normalized}`;
25
+ }
26
+ function stripMethodSuffix(base) {
27
+ const segments = base.split(".");
28
+ const last = segments.at(-1);
29
+ if (last && methodSuffixSet.has(last.toLowerCase())) {
30
+ segments.pop();
31
+ return {
32
+ name: segments.join("."),
33
+ method: last.toUpperCase()
34
+ };
35
+ }
36
+ return {
37
+ name: base,
38
+ method: void 0
39
+ };
40
+ }
41
+ function deriveRouteFromFile(file, rootDir, warn) {
42
+ const rel = toPosix(relative(rootDir, file));
43
+ const ext = extname(rel);
44
+ const withoutExt = rel.slice(0, rel.length - ext.length);
45
+ const dir = dirname(withoutExt);
46
+ const base = basename(withoutExt);
47
+ const { name, method } = stripMethodSuffix(base);
48
+ const resolvedMethod = method ?? (jsonExtensions.has(ext) ? "GET" : void 0);
49
+ if (!resolvedMethod) {
50
+ warn?.(`Skip mock without method suffix: ${file}`);
51
+ return null;
52
+ }
53
+ if (!name) {
54
+ warn?.(`Skip mock with empty route name: ${file}`);
55
+ return null;
56
+ }
57
+ const joined = dir === "." ? name : join(dir, name);
58
+ const segments = toPosix(joined).split("/");
59
+ if (segments.at(-1) === "index") {
60
+ segments.pop();
61
+ }
62
+ const template = segments.length === 0 ? "/" : `/${segments.join("/")}`;
63
+ const parsed = parseRouteTemplate(template);
64
+ if (parsed.errors.length > 0) {
65
+ for (const error of parsed.errors) {
66
+ warn?.(`${error} in ${file}`);
67
+ }
68
+ return null;
69
+ }
70
+ for (const warning of parsed.warnings) {
71
+ warn?.(`${warning} in ${file}`);
72
+ }
73
+ return {
74
+ template: parsed.template,
75
+ method: resolvedMethod,
76
+ tokens: parsed.tokens,
77
+ score: parsed.score
78
+ };
79
+ }
80
+ function resolveRule(input) {
81
+ const method = input.derivedMethod;
82
+ if (!method) {
83
+ input.warn?.(`Skip mock without method suffix: ${input.file}`);
84
+ return null;
85
+ }
86
+ const template = resolveTemplate(input.derivedTemplate, input.prefix);
87
+ const parsed = parseRouteTemplate(template);
88
+ if (parsed.errors.length > 0) {
89
+ for (const error of parsed.errors) {
90
+ input.warn?.(`${error} in ${input.file}`);
91
+ }
92
+ return null;
93
+ }
94
+ for (const warning of parsed.warnings) {
95
+ input.warn?.(`${warning} in ${input.file}`);
96
+ }
97
+ const base = {
98
+ template: parsed.template,
99
+ method,
100
+ tokens: parsed.tokens,
101
+ score: parsed.score
102
+ };
103
+ return input.build ? input.build(base, input.rule) : base;
104
+ }
105
+ function sortRoutes(routes) {
106
+ return routes.sort((a, b) => {
107
+ if (a.method !== b.method) {
108
+ return a.method.localeCompare(b.method);
109
+ }
110
+ const scoreCompare = compareRouteScore(a.score, b.score);
111
+ if (scoreCompare !== 0) {
112
+ return scoreCompare;
113
+ }
114
+ return a.template.localeCompare(b.template);
115
+ });
116
+ }
117
+ return {
118
+ deriveRouteFromFile,
119
+ resolveRule,
120
+ sortRoutes
121
+ };
122
+ }
123
+
124
+ export { createRouteUtils };
@@ -0,0 +1,39 @@
1
+ 'use strict';
2
+
3
+ const pathe = require('pathe');
4
+ const routeConstants = require('./route-constants.cjs');
5
+
6
+ function normalizeMethod(method) {
7
+ if (!method) {
8
+ return void 0;
9
+ }
10
+ const normalized = method.toUpperCase();
11
+ if (routeConstants.methodSet.has(normalized)) {
12
+ return normalized;
13
+ }
14
+ return void 0;
15
+ }
16
+ function normalizePrefix(prefix) {
17
+ if (!prefix) {
18
+ return "";
19
+ }
20
+ const normalized = prefix.startsWith("/") ? prefix : `/${prefix}`;
21
+ return normalized.endsWith("/") ? normalized.slice(0, -1) : normalized;
22
+ }
23
+ function resolveDirs(dir, root) {
24
+ const raw = typeof dir === "function" ? dir(root) : dir;
25
+ const resolved = Array.isArray(raw) ? raw : raw ? [raw] : ["mock"];
26
+ const normalized = resolved.map(
27
+ (entry) => pathe.isAbsolute(entry) ? entry : pathe.resolve(root, entry)
28
+ );
29
+ return Array.from(new Set(normalized));
30
+ }
31
+ function normalizeIgnorePrefix(value, fallback = ["."]) {
32
+ const list = typeof value === "undefined" ? fallback : Array.isArray(value) ? value : [value];
33
+ return list.filter((entry) => typeof entry === "string" && entry.length > 0);
34
+ }
35
+
36
+ exports.normalizeIgnorePrefix = normalizeIgnorePrefix;
37
+ exports.normalizeMethod = normalizeMethod;
38
+ exports.normalizePrefix = normalizePrefix;
39
+ exports.resolveDirs = resolveDirs;
@@ -0,0 +1,114 @@
1
+ import './config-core.cjs';
2
+ import './config-utils.cjs';
3
+ import './define-config.cjs';
4
+ import './jsonc-utils.cjs';
5
+ import './load-rules.cjs';
6
+ import './mock-files.cjs';
7
+ import './module-loader.cjs';
8
+ import './route-constants.cjs';
9
+ import './route-utils.cjs';
10
+
11
+ declare function normalizeMethod(method?: string | null): string | undefined;
12
+ declare function normalizePrefix(prefix: string): string;
13
+ declare function resolveDirs(dir: DirInput, root: string): string[];
14
+ declare function normalizeIgnorePrefix(value: string | string[] | undefined, fallback?: string[]): string[];
15
+
16
+ /**
17
+ * Directory input for mock scanning.
18
+ *
19
+ * @example
20
+ * import type { DirInput } from '@mokup/shared'
21
+ *
22
+ * const dir: DirInput = ['mock', 'fixtures']
23
+ */
24
+ type DirInput = string | string[] | ((root: string) => string | string[]) | undefined;
25
+ /**
26
+ * Shared entry options for mokup scanners and plugins.
27
+ *
28
+ * @example
29
+ * import type { MockEntryOptions } from '@mokup/shared'
30
+ *
31
+ * const entry: MockEntryOptions = {
32
+ * dir: 'mock',
33
+ * prefix: '/api',
34
+ * watch: true,
35
+ * }
36
+ */
37
+ interface MockEntryOptions {
38
+ /**
39
+ * Directory (or directories) to scan for mock routes.
40
+ *
41
+ * @default "mock" (resolved by Vite/webpack plugins)
42
+ */
43
+ dir?: DirInput;
44
+ /**
45
+ * Request path prefix to mount mock routes under.
46
+ *
47
+ * @default ""
48
+ */
49
+ prefix?: string;
50
+ /**
51
+ * Include filter for files to scan.
52
+ *
53
+ * @default undefined
54
+ */
55
+ include?: RegExp | RegExp[];
56
+ /**
57
+ * Exclude filter for files to scan.
58
+ *
59
+ * @default undefined
60
+ */
61
+ exclude?: RegExp | RegExp[];
62
+ /**
63
+ * Ignore file or folder prefixes when scanning.
64
+ *
65
+ * @default ["."]
66
+ */
67
+ ignorePrefix?: string | string[];
68
+ /**
69
+ * Enable file watching for live route updates.
70
+ *
71
+ * @default true
72
+ */
73
+ watch?: boolean;
74
+ /**
75
+ * Enable mokup logging.
76
+ *
77
+ * @default true
78
+ */
79
+ log?: boolean;
80
+ }
81
+ /**
82
+ * Playground configuration input.
83
+ *
84
+ * @example
85
+ * import type { PlaygroundOptionsInput } from '@mokup/shared'
86
+ *
87
+ * const playground: PlaygroundOptionsInput = {
88
+ * path: '/__mokup',
89
+ * enabled: true,
90
+ * }
91
+ */
92
+ type PlaygroundOptionsInput = boolean | {
93
+ /**
94
+ * Base path for the playground UI.
95
+ *
96
+ * @default "/__mokup"
97
+ */
98
+ path?: string;
99
+ /**
100
+ * Emit playground assets during production builds.
101
+ *
102
+ * @default false
103
+ */
104
+ build?: boolean;
105
+ /**
106
+ * Enable or disable the playground routes.
107
+ *
108
+ * @default true
109
+ */
110
+ enabled?: boolean;
111
+ } | undefined;
112
+
113
+ export { normalizeIgnorePrefix, normalizeMethod, normalizePrefix, resolveDirs };
114
+ export type { DirInput as D, MockEntryOptions as M, PlaygroundOptionsInput as P };
@@ -0,0 +1,114 @@
1
+ import './config-core.mjs';
2
+ import './config-utils.mjs';
3
+ import './define-config.mjs';
4
+ import './jsonc-utils.mjs';
5
+ import './load-rules.mjs';
6
+ import './mock-files.mjs';
7
+ import './module-loader.mjs';
8
+ import './route-constants.mjs';
9
+ import './route-utils.mjs';
10
+
11
+ declare function normalizeMethod(method?: string | null): string | undefined;
12
+ declare function normalizePrefix(prefix: string): string;
13
+ declare function resolveDirs(dir: DirInput, root: string): string[];
14
+ declare function normalizeIgnorePrefix(value: string | string[] | undefined, fallback?: string[]): string[];
15
+
16
+ /**
17
+ * Directory input for mock scanning.
18
+ *
19
+ * @example
20
+ * import type { DirInput } from '@mokup/shared'
21
+ *
22
+ * const dir: DirInput = ['mock', 'fixtures']
23
+ */
24
+ type DirInput = string | string[] | ((root: string) => string | string[]) | undefined;
25
+ /**
26
+ * Shared entry options for mokup scanners and plugins.
27
+ *
28
+ * @example
29
+ * import type { MockEntryOptions } from '@mokup/shared'
30
+ *
31
+ * const entry: MockEntryOptions = {
32
+ * dir: 'mock',
33
+ * prefix: '/api',
34
+ * watch: true,
35
+ * }
36
+ */
37
+ interface MockEntryOptions {
38
+ /**
39
+ * Directory (or directories) to scan for mock routes.
40
+ *
41
+ * @default "mock" (resolved by Vite/webpack plugins)
42
+ */
43
+ dir?: DirInput;
44
+ /**
45
+ * Request path prefix to mount mock routes under.
46
+ *
47
+ * @default ""
48
+ */
49
+ prefix?: string;
50
+ /**
51
+ * Include filter for files to scan.
52
+ *
53
+ * @default undefined
54
+ */
55
+ include?: RegExp | RegExp[];
56
+ /**
57
+ * Exclude filter for files to scan.
58
+ *
59
+ * @default undefined
60
+ */
61
+ exclude?: RegExp | RegExp[];
62
+ /**
63
+ * Ignore file or folder prefixes when scanning.
64
+ *
65
+ * @default ["."]
66
+ */
67
+ ignorePrefix?: string | string[];
68
+ /**
69
+ * Enable file watching for live route updates.
70
+ *
71
+ * @default true
72
+ */
73
+ watch?: boolean;
74
+ /**
75
+ * Enable mokup logging.
76
+ *
77
+ * @default true
78
+ */
79
+ log?: boolean;
80
+ }
81
+ /**
82
+ * Playground configuration input.
83
+ *
84
+ * @example
85
+ * import type { PlaygroundOptionsInput } from '@mokup/shared'
86
+ *
87
+ * const playground: PlaygroundOptionsInput = {
88
+ * path: '/__mokup',
89
+ * enabled: true,
90
+ * }
91
+ */
92
+ type PlaygroundOptionsInput = boolean | {
93
+ /**
94
+ * Base path for the playground UI.
95
+ *
96
+ * @default "/__mokup"
97
+ */
98
+ path?: string;
99
+ /**
100
+ * Emit playground assets during production builds.
101
+ *
102
+ * @default false
103
+ */
104
+ build?: boolean;
105
+ /**
106
+ * Enable or disable the playground routes.
107
+ *
108
+ * @default true
109
+ */
110
+ enabled?: boolean;
111
+ } | undefined;
112
+
113
+ export { normalizeIgnorePrefix, normalizeMethod, normalizePrefix, resolveDirs };
114
+ export type { DirInput as D, MockEntryOptions as M, PlaygroundOptionsInput as P };
@@ -0,0 +1,114 @@
1
+ import './config-core.js';
2
+ import './config-utils.js';
3
+ import './define-config.js';
4
+ import './jsonc-utils.js';
5
+ import './load-rules.js';
6
+ import './mock-files.js';
7
+ import './module-loader.js';
8
+ import './route-constants.js';
9
+ import './route-utils.js';
10
+
11
+ declare function normalizeMethod(method?: string | null): string | undefined;
12
+ declare function normalizePrefix(prefix: string): string;
13
+ declare function resolveDirs(dir: DirInput, root: string): string[];
14
+ declare function normalizeIgnorePrefix(value: string | string[] | undefined, fallback?: string[]): string[];
15
+
16
+ /**
17
+ * Directory input for mock scanning.
18
+ *
19
+ * @example
20
+ * import type { DirInput } from '@mokup/shared'
21
+ *
22
+ * const dir: DirInput = ['mock', 'fixtures']
23
+ */
24
+ type DirInput = string | string[] | ((root: string) => string | string[]) | undefined;
25
+ /**
26
+ * Shared entry options for mokup scanners and plugins.
27
+ *
28
+ * @example
29
+ * import type { MockEntryOptions } from '@mokup/shared'
30
+ *
31
+ * const entry: MockEntryOptions = {
32
+ * dir: 'mock',
33
+ * prefix: '/api',
34
+ * watch: true,
35
+ * }
36
+ */
37
+ interface MockEntryOptions {
38
+ /**
39
+ * Directory (or directories) to scan for mock routes.
40
+ *
41
+ * @default "mock" (resolved by Vite/webpack plugins)
42
+ */
43
+ dir?: DirInput;
44
+ /**
45
+ * Request path prefix to mount mock routes under.
46
+ *
47
+ * @default ""
48
+ */
49
+ prefix?: string;
50
+ /**
51
+ * Include filter for files to scan.
52
+ *
53
+ * @default undefined
54
+ */
55
+ include?: RegExp | RegExp[];
56
+ /**
57
+ * Exclude filter for files to scan.
58
+ *
59
+ * @default undefined
60
+ */
61
+ exclude?: RegExp | RegExp[];
62
+ /**
63
+ * Ignore file or folder prefixes when scanning.
64
+ *
65
+ * @default ["."]
66
+ */
67
+ ignorePrefix?: string | string[];
68
+ /**
69
+ * Enable file watching for live route updates.
70
+ *
71
+ * @default true
72
+ */
73
+ watch?: boolean;
74
+ /**
75
+ * Enable mokup logging.
76
+ *
77
+ * @default true
78
+ */
79
+ log?: boolean;
80
+ }
81
+ /**
82
+ * Playground configuration input.
83
+ *
84
+ * @example
85
+ * import type { PlaygroundOptionsInput } from '@mokup/shared'
86
+ *
87
+ * const playground: PlaygroundOptionsInput = {
88
+ * path: '/__mokup',
89
+ * enabled: true,
90
+ * }
91
+ */
92
+ type PlaygroundOptionsInput = boolean | {
93
+ /**
94
+ * Base path for the playground UI.
95
+ *
96
+ * @default "/__mokup"
97
+ */
98
+ path?: string;
99
+ /**
100
+ * Emit playground assets during production builds.
101
+ *
102
+ * @default false
103
+ */
104
+ build?: boolean;
105
+ /**
106
+ * Enable or disable the playground routes.
107
+ *
108
+ * @default true
109
+ */
110
+ enabled?: boolean;
111
+ } | undefined;
112
+
113
+ export { normalizeIgnorePrefix, normalizeMethod, normalizePrefix, resolveDirs };
114
+ export type { DirInput as D, MockEntryOptions as M, PlaygroundOptionsInput as P };
@@ -0,0 +1,34 @@
1
+ import { resolve, isAbsolute } from 'pathe';
2
+ import { methodSet } from './route-constants.mjs';
3
+
4
+ function normalizeMethod(method) {
5
+ if (!method) {
6
+ return void 0;
7
+ }
8
+ const normalized = method.toUpperCase();
9
+ if (methodSet.has(normalized)) {
10
+ return normalized;
11
+ }
12
+ return void 0;
13
+ }
14
+ function normalizePrefix(prefix) {
15
+ if (!prefix) {
16
+ return "";
17
+ }
18
+ const normalized = prefix.startsWith("/") ? prefix : `/${prefix}`;
19
+ return normalized.endsWith("/") ? normalized.slice(0, -1) : normalized;
20
+ }
21
+ function resolveDirs(dir, root) {
22
+ const raw = typeof dir === "function" ? dir(root) : dir;
23
+ const resolved = Array.isArray(raw) ? raw : raw ? [raw] : ["mock"];
24
+ const normalized = resolved.map(
25
+ (entry) => isAbsolute(entry) ? entry : resolve(root, entry)
26
+ );
27
+ return Array.from(new Set(normalized));
28
+ }
29
+ function normalizeIgnorePrefix(value, fallback = ["."]) {
30
+ const list = typeof value === "undefined" ? fallback : Array.isArray(value) ? value : [value];
31
+ return list.filter((entry) => typeof entry === "string" && entry.length > 0);
32
+ }
33
+
34
+ export { normalizeIgnorePrefix, normalizeMethod, normalizePrefix, resolveDirs };
@@ -0,0 +1,20 @@
1
+ 'use strict';
2
+
3
+ function createDebouncer(delayMs, fn) {
4
+ let timer = null;
5
+ return () => {
6
+ if (timer) {
7
+ clearTimeout(timer);
8
+ }
9
+ timer = setTimeout(() => {
10
+ timer = null;
11
+ fn();
12
+ }, delayMs);
13
+ };
14
+ }
15
+ function delay(ms) {
16
+ return new Promise((resolve) => setTimeout(resolve, ms));
17
+ }
18
+
19
+ exports.createDebouncer = createDebouncer;
20
+ exports.delay = delay;
@@ -0,0 +1,4 @@
1
+ declare function createDebouncer(delayMs: number, fn: () => void): () => void;
2
+ declare function delay(ms: number): Promise<void>;
3
+
4
+ export { createDebouncer, delay };
@@ -0,0 +1,4 @@
1
+ declare function createDebouncer(delayMs: number, fn: () => void): () => void;
2
+ declare function delay(ms: number): Promise<void>;
3
+
4
+ export { createDebouncer, delay };