fexapi 0.1.0 → 0.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.
- package/README.md +142 -1
- package/dist/cli/args.d.ts +24 -0
- package/dist/cli/args.d.ts.map +1 -0
- package/dist/cli/args.js +98 -0
- package/dist/cli/help.d.ts +2 -0
- package/dist/cli/help.d.ts.map +1 -0
- package/dist/cli/help.js +51 -0
- package/dist/commands/dev.d.ts +7 -0
- package/dist/commands/dev.d.ts.map +1 -0
- package/dist/commands/dev.js +114 -0
- package/dist/commands/generate.d.ts +2 -0
- package/dist/commands/generate.d.ts.map +1 -0
- package/dist/commands/generate.js +81 -0
- package/dist/commands/init.d.ts +4 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +250 -0
- package/dist/commands/serve.d.ts +12 -0
- package/dist/commands/serve.d.ts.map +1 -0
- package/dist/commands/serve.js +68 -0
- package/dist/config/generated-spec.d.ts +3 -0
- package/dist/config/generated-spec.d.ts.map +1 -0
- package/dist/config/generated-spec.js +26 -0
- package/dist/config/runtime-config.d.ts +3 -0
- package/dist/config/runtime-config.d.ts.map +1 -0
- package/dist/config/runtime-config.js +97 -0
- package/dist/config/schema-definitions.d.ts +3 -0
- package/dist/config/schema-definitions.d.ts.map +1 -0
- package/dist/config/schema-definitions.js +90 -0
- package/dist/constants.d.ts +2 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +4 -0
- package/dist/index.js +74 -411
- package/dist/project/detect.d.ts +4 -0
- package/dist/project/detect.d.ts.map +1 -0
- package/dist/project/detect.js +113 -0
- package/dist/project/paths.d.ts +3 -0
- package/dist/project/paths.d.ts.map +1 -0
- package/dist/project/paths.js +28 -0
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +4 -6
- package/dist/server.d.ts +5 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +123 -43
- package/dist/types/config.d.ts +20 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +2 -0
- package/dist/types/project.d.ts +7 -0
- package/dist/types/project.d.ts.map +1 -0
- package/dist/types/project.js +2 -0
- package/package.json +56 -51
package/dist/schema.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,eAAe,GACvB,QAAQ,GACR,QAAQ,GACR,SAAS,GACT,MAAM,GACN,MAAM,GACN,OAAO,GACP,KAAK,GACL,MAAM,GACN,OAAO,CAAC;AAEZ,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,eAAe,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB,CAAC;
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,eAAe,GACvB,QAAQ,GACR,QAAQ,GACR,SAAS,GACT,MAAM,GACN,MAAM,GACN,OAAO,GACP,KAAK,GACL,MAAM,GACN,OAAO,CAAC;AAEZ,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,eAAe,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB,CAAC;AAiGF,eAAO,MAAM,iBAAiB,GAC5B,YAAY,MAAM,KACjB;IAAE,MAAM,CAAC,EAAE,YAAY,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAoD3C,CAAC"}
|
package/dist/schema.js
CHANGED
|
@@ -13,6 +13,8 @@ const VALID_TYPES = [
|
|
|
13
13
|
"phone",
|
|
14
14
|
];
|
|
15
15
|
const DEFAULT_PORT = 4000;
|
|
16
|
+
const ROUTE_FORMAT_ERROR_MESSAGE = "Invalid route definition. Expected format: " +
|
|
17
|
+
"METHOD /endpoint: field:type,field:type";
|
|
16
18
|
const parseField = (rawField) => {
|
|
17
19
|
const [rawName, rawType] = rawField.split(":");
|
|
18
20
|
const name = rawName?.trim();
|
|
@@ -36,16 +38,12 @@ const parseField = (rawField) => {
|
|
|
36
38
|
const parseRoute = (line) => {
|
|
37
39
|
const separatorIndex = line.indexOf(":");
|
|
38
40
|
if (separatorIndex === -1) {
|
|
39
|
-
return {
|
|
40
|
-
error: "Invalid route definition. Expected format: METHOD /endpoint: field:type,field:type",
|
|
41
|
-
};
|
|
41
|
+
return { error: ROUTE_FORMAT_ERROR_MESSAGE };
|
|
42
42
|
}
|
|
43
43
|
const rawLeft = line.slice(0, separatorIndex);
|
|
44
44
|
const rawFields = line.slice(separatorIndex + 1);
|
|
45
45
|
if (!rawLeft || !rawFields) {
|
|
46
|
-
return {
|
|
47
|
-
error: "Invalid route definition. Expected format: METHOD /endpoint: field:type,field:type",
|
|
48
|
-
};
|
|
46
|
+
return { error: ROUTE_FORMAT_ERROR_MESSAGE };
|
|
49
47
|
}
|
|
50
48
|
const [rawMethod, rawPath] = rawLeft.trim().split(/\s+/, 2);
|
|
51
49
|
const method = rawMethod?.toUpperCase();
|
package/dist/server.d.ts
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
import type { ServerResponse } from "node:http";
|
|
2
2
|
import type { FexapiRoute } from "./schema";
|
|
3
|
+
import type { FexapiRuntimeConfig, FexapiSchemaDefinitions } from "./types/config";
|
|
3
4
|
export type ServerOptions = {
|
|
4
5
|
host?: string;
|
|
5
6
|
port?: number;
|
|
6
7
|
apiSpec?: GeneratedApiSpec;
|
|
8
|
+
runtimeConfig?: FexapiRuntimeConfig;
|
|
9
|
+
schemaDefinitions?: FexapiSchemaDefinitions;
|
|
10
|
+
logRequests?: boolean;
|
|
7
11
|
};
|
|
8
12
|
export type GeneratedApiSpec = {
|
|
9
13
|
port: number;
|
|
10
14
|
routes: FexapiRoute[];
|
|
11
15
|
};
|
|
12
|
-
export declare const startServer: ({ host, port, apiSpec, }?: ServerOptions) => import("http").Server<typeof import("http").IncomingMessage, typeof ServerResponse>;
|
|
16
|
+
export declare const startServer: ({ host, port, apiSpec, runtimeConfig, schemaDefinitions, logRequests, }?: ServerOptions) => import("http").Server<typeof import("http").IncomingMessage, typeof ServerResponse>;
|
|
13
17
|
//# sourceMappingURL=server.d.ts.map
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,KAAK,EAAe,WAAW,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,KAAK,EAAe,WAAW,EAAE,MAAM,UAAU,CAAC;AACzD,OAAO,KAAK,EACV,mBAAmB,EACnB,uBAAuB,EAExB,MAAM,gBAAgB,CAAC;AAExB,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,gBAAgB,CAAC;IAC3B,aAAa,CAAC,EAAE,mBAAmB,CAAC;IACpC,iBAAiB,CAAC,EAAE,uBAAuB,CAAC;IAC5C,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB,CAAC;AAyLF,eAAO,MAAM,WAAW,GAAI,0EAOzB,aAAkB,wFAmGpB,CAAC"}
|
package/dist/server.js
CHANGED
|
@@ -5,9 +5,25 @@ const faker_1 = require("@faker-js/faker");
|
|
|
5
5
|
const node_http_1 = require("node:http");
|
|
6
6
|
const DEFAULT_HOST = "127.0.0.1";
|
|
7
7
|
const DEFAULT_PORT = 4000;
|
|
8
|
-
const sendJson = (response, statusCode, payload) => {
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
const sendJson = (response, statusCode, payload, options) => {
|
|
9
|
+
const send = () => {
|
|
10
|
+
const headers = {
|
|
11
|
+
"Content-Type": "application/json",
|
|
12
|
+
};
|
|
13
|
+
if (options.cors) {
|
|
14
|
+
headers["Access-Control-Allow-Origin"] = "*";
|
|
15
|
+
headers["Access-Control-Allow-Methods"] =
|
|
16
|
+
"GET,POST,PUT,PATCH,DELETE,OPTIONS";
|
|
17
|
+
headers["Access-Control-Allow-Headers"] = "Content-Type,Authorization";
|
|
18
|
+
}
|
|
19
|
+
response.writeHead(statusCode, headers);
|
|
20
|
+
response.end(JSON.stringify(payload));
|
|
21
|
+
};
|
|
22
|
+
if (options.delay > 0) {
|
|
23
|
+
setTimeout(send, options.delay);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
send();
|
|
11
27
|
};
|
|
12
28
|
const createValueFromField = (field) => {
|
|
13
29
|
switch (field.type) {
|
|
@@ -39,6 +55,62 @@ const createRecordFromRoute = (route) => {
|
|
|
39
55
|
return record;
|
|
40
56
|
}, {});
|
|
41
57
|
};
|
|
58
|
+
const resolveFakerMethod = (path) => {
|
|
59
|
+
const pathParts = path.split(".").filter(Boolean);
|
|
60
|
+
let current = faker_1.faker;
|
|
61
|
+
for (const pathPart of pathParts) {
|
|
62
|
+
if (typeof current !== "object" || current === null) {
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
current = current[pathPart];
|
|
66
|
+
}
|
|
67
|
+
if (typeof current !== "function") {
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
70
|
+
return current;
|
|
71
|
+
};
|
|
72
|
+
const createValueFromSchemaFieldDefinition = (fieldDefinition) => {
|
|
73
|
+
if (fieldDefinition.faker) {
|
|
74
|
+
const fakerMethod = resolveFakerMethod(fieldDefinition.faker);
|
|
75
|
+
if (fakerMethod) {
|
|
76
|
+
return fakerMethod();
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
switch (fieldDefinition.type) {
|
|
80
|
+
case "number": {
|
|
81
|
+
const min = typeof fieldDefinition.min === "number" ? fieldDefinition.min : 1;
|
|
82
|
+
const max = typeof fieldDefinition.max === "number" ? fieldDefinition.max : 10000;
|
|
83
|
+
return faker_1.faker.number.int({
|
|
84
|
+
min: Math.min(min, max),
|
|
85
|
+
max: Math.max(min, max),
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
case "boolean":
|
|
89
|
+
return faker_1.faker.datatype.boolean();
|
|
90
|
+
case "date":
|
|
91
|
+
return faker_1.faker.date.recent({ days: 30 }).toISOString();
|
|
92
|
+
case "uuid":
|
|
93
|
+
return faker_1.faker.string.uuid();
|
|
94
|
+
case "email":
|
|
95
|
+
return faker_1.faker.internet.email();
|
|
96
|
+
case "url":
|
|
97
|
+
return faker_1.faker.internet.url();
|
|
98
|
+
case "name":
|
|
99
|
+
return faker_1.faker.person.fullName();
|
|
100
|
+
case "phone":
|
|
101
|
+
return faker_1.faker.phone.number();
|
|
102
|
+
case "string":
|
|
103
|
+
default:
|
|
104
|
+
return faker_1.faker.lorem.words({ min: 1, max: 4 });
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
const createRecordFromSchemaDefinition = (schemaDefinition) => {
|
|
108
|
+
const result = {};
|
|
109
|
+
for (const [fieldName, fieldDefinition] of Object.entries(schemaDefinition)) {
|
|
110
|
+
result[fieldName] = createValueFromSchemaFieldDefinition(fieldDefinition);
|
|
111
|
+
}
|
|
112
|
+
return result;
|
|
113
|
+
};
|
|
42
114
|
const toCollectionKey = (routePath) => {
|
|
43
115
|
const segments = routePath.split("/").filter(Boolean);
|
|
44
116
|
const lastSegment = segments[segments.length - 1];
|
|
@@ -47,21 +119,17 @@ const toCollectionKey = (routePath) => {
|
|
|
47
119
|
}
|
|
48
120
|
return lastSegment.replace(/[^a-zA-Z0-9_]/g, "_");
|
|
49
121
|
};
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
avatarUrl: faker_1.faker.image.avatar(),
|
|
57
|
-
};
|
|
58
|
-
};
|
|
59
|
-
const createMockPost = () => {
|
|
122
|
+
const createRecordFromSchemaName = (schemaName, schemaDefinitions) => {
|
|
123
|
+
const normalizedSchemaName = schemaName.trim().toLowerCase();
|
|
124
|
+
const customSchemaDefinition = schemaDefinitions[normalizedSchemaName];
|
|
125
|
+
if (customSchemaDefinition) {
|
|
126
|
+
return createRecordFromSchemaDefinition(customSchemaDefinition);
|
|
127
|
+
}
|
|
60
128
|
return {
|
|
61
129
|
id: faker_1.faker.string.uuid(),
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
createdAt: faker_1.faker.date.recent({ days:
|
|
130
|
+
type: normalizedSchemaName || "record",
|
|
131
|
+
value: faker_1.faker.lorem.words({ min: 1, max: 4 }),
|
|
132
|
+
createdAt: faker_1.faker.date.recent({ days: 7 }).toISOString(),
|
|
65
133
|
};
|
|
66
134
|
};
|
|
67
135
|
const getCountFromUrl = (urlText, fallback = 5) => {
|
|
@@ -75,16 +143,47 @@ const getCountFromUrl = (urlText, fallback = 5) => {
|
|
|
75
143
|
}
|
|
76
144
|
return Math.min(Math.max(Math.floor(rawCount), 1), 50);
|
|
77
145
|
};
|
|
78
|
-
const startServer = ({ host = DEFAULT_HOST, port = DEFAULT_PORT, apiSpec, } = {}) => {
|
|
146
|
+
const startServer = ({ host = DEFAULT_HOST, port = DEFAULT_PORT, apiSpec, runtimeConfig, schemaDefinitions = {}, logRequests = false, } = {}) => {
|
|
147
|
+
const corsEnabled = runtimeConfig?.cors ?? false;
|
|
148
|
+
const responseDelay = runtimeConfig?.delay ?? 0;
|
|
149
|
+
const configuredRoutes = runtimeConfig?.routes ?? {};
|
|
150
|
+
const availableConfiguredRoutes = Object.keys(configuredRoutes).map((path) => `GET ${path}`);
|
|
151
|
+
const availableSchemaRoutes = apiSpec
|
|
152
|
+
? apiSpec.routes.map((route) => `${route.method} ${route.path}`)
|
|
153
|
+
: [];
|
|
154
|
+
const availableRoutes = [
|
|
155
|
+
...new Set([...availableConfiguredRoutes, ...availableSchemaRoutes]),
|
|
156
|
+
];
|
|
79
157
|
const server = (0, node_http_1.createServer)((request, response) => {
|
|
158
|
+
const requestStartedAt = Date.now();
|
|
80
159
|
const pathname = new URL(request.url ?? "/", "http://localhost").pathname;
|
|
81
|
-
if (
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
160
|
+
if (logRequests) {
|
|
161
|
+
response.on("finish", () => {
|
|
162
|
+
const method = request.method ?? "UNKNOWN";
|
|
163
|
+
const durationMs = Date.now() - requestStartedAt;
|
|
164
|
+
const statusCode = response.statusCode;
|
|
165
|
+
console.log(`[${method}] ${pathname} → ${statusCode} (${durationMs}ms)`);
|
|
85
166
|
});
|
|
167
|
+
}
|
|
168
|
+
if (corsEnabled && request.method === "OPTIONS") {
|
|
169
|
+
response.writeHead(204, {
|
|
170
|
+
"Access-Control-Allow-Origin": "*",
|
|
171
|
+
"Access-Control-Allow-Methods": "GET,POST,PUT,PATCH,DELETE,OPTIONS",
|
|
172
|
+
"Access-Control-Allow-Headers": "Content-Type,Authorization",
|
|
173
|
+
});
|
|
174
|
+
response.end();
|
|
86
175
|
return;
|
|
87
176
|
}
|
|
177
|
+
if (request.method === "GET") {
|
|
178
|
+
const configuredRoute = configuredRoutes[pathname];
|
|
179
|
+
if (configuredRoute) {
|
|
180
|
+
const payloadKey = toCollectionKey(pathname);
|
|
181
|
+
sendJson(response, 200, {
|
|
182
|
+
[payloadKey]: Array.from({ length: configuredRoute.count }, () => createRecordFromSchemaName(configuredRoute.schema, schemaDefinitions)),
|
|
183
|
+
}, { cors: corsEnabled, delay: responseDelay });
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
88
187
|
if (apiSpec) {
|
|
89
188
|
const matchedRoute = apiSpec.routes.find((route) => route.method === request.method && route.path === pathname);
|
|
90
189
|
if (matchedRoute) {
|
|
@@ -92,33 +191,14 @@ const startServer = ({ host = DEFAULT_HOST, port = DEFAULT_PORT, apiSpec, } = {}
|
|
|
92
191
|
const payloadKey = toCollectionKey(matchedRoute.path);
|
|
93
192
|
sendJson(response, 200, {
|
|
94
193
|
[payloadKey]: Array.from({ length: count }, () => createRecordFromRoute(matchedRoute)),
|
|
95
|
-
});
|
|
194
|
+
}, { cors: corsEnabled, delay: responseDelay });
|
|
96
195
|
return;
|
|
97
196
|
}
|
|
98
197
|
}
|
|
99
|
-
if (request.method === "GET" && pathname === "/users") {
|
|
100
|
-
const count = getCountFromUrl(request.url, 8);
|
|
101
|
-
sendJson(response, 200, {
|
|
102
|
-
users: Array.from({ length: count }, createMockUser),
|
|
103
|
-
});
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
|
-
if (request.method === "GET" && pathname === "/posts") {
|
|
107
|
-
const count = getCountFromUrl(request.url, 5);
|
|
108
|
-
sendJson(response, 200, {
|
|
109
|
-
posts: Array.from({ length: count }, createMockPost),
|
|
110
|
-
});
|
|
111
|
-
return;
|
|
112
|
-
}
|
|
113
198
|
sendJson(response, 404, {
|
|
114
199
|
message: "Route not found",
|
|
115
|
-
availableRoutes
|
|
116
|
-
|
|
117
|
-
"GET /health",
|
|
118
|
-
...apiSpec.routes.map((route) => `${route.method} ${route.path}`),
|
|
119
|
-
]
|
|
120
|
-
: ["GET /health", "GET /users?count=10", "GET /posts?count=5"],
|
|
121
|
-
});
|
|
200
|
+
availableRoutes,
|
|
201
|
+
}, { cors: corsEnabled, delay: responseDelay });
|
|
122
202
|
});
|
|
123
203
|
server.listen(port, host, () => {
|
|
124
204
|
console.log(`Mock API running at http://${host}:${port}`);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export type FexapiRouteConfig = {
|
|
2
|
+
count: number;
|
|
3
|
+
schema: string;
|
|
4
|
+
};
|
|
5
|
+
export type FexapiFieldValueType = "number" | "string" | "boolean" | "date" | "uuid" | "email" | "url" | "name" | "phone";
|
|
6
|
+
export type FexapiSchemaFieldDefinition = {
|
|
7
|
+
type: FexapiFieldValueType;
|
|
8
|
+
faker?: string;
|
|
9
|
+
min?: number;
|
|
10
|
+
max?: number;
|
|
11
|
+
};
|
|
12
|
+
export type FexapiSchemaDefinition = Record<string, FexapiSchemaFieldDefinition>;
|
|
13
|
+
export type FexapiSchemaDefinitions = Record<string, FexapiSchemaDefinition>;
|
|
14
|
+
export type FexapiRuntimeConfig = {
|
|
15
|
+
port?: number;
|
|
16
|
+
routes?: Record<string, FexapiRouteConfig>;
|
|
17
|
+
cors?: boolean;
|
|
18
|
+
delay?: number;
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAC5B,QAAQ,GACR,QAAQ,GACR,SAAS,GACT,MAAM,GACN,MAAM,GACN,OAAO,GACP,KAAK,GACL,MAAM,GACN,OAAO,CAAC;AAEZ,MAAM,MAAM,2BAA2B,GAAG;IACxC,IAAI,EAAE,oBAAoB,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG,MAAM,CACzC,MAAM,EACN,2BAA2B,CAC5B,CAAC;AACF,MAAM,MAAM,uBAAuB,GAAG,MAAM,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;AAE7E,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAC3C,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type SupportedFramework = "nextjs" | "reactjs" | "vue" | "nuxt" | "svelte" | "sveltekit" | "angular" | "solid" | "remix" | "astro" | "unknown";
|
|
2
|
+
export type DetectedProject = {
|
|
3
|
+
primaryFramework: SupportedFramework;
|
|
4
|
+
frameworks: SupportedFramework[];
|
|
5
|
+
tooling: string[];
|
|
6
|
+
};
|
|
7
|
+
//# sourceMappingURL=project.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../../src/types/project.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,kBAAkB,GAC1B,QAAQ,GACR,SAAS,GACT,KAAK,GACL,MAAM,GACN,QAAQ,GACR,WAAW,GACX,SAAS,GACT,OAAO,GACP,OAAO,GACP,OAAO,GACP,SAAS,CAAC;AAEd,MAAM,MAAM,eAAe,GAAG;IAC5B,gBAAgB,EAAE,kBAAkB,CAAC;IACrC,UAAU,EAAE,kBAAkB,EAAE,CAAC;IACjC,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,51 +1,56 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "fexapi",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "Mock API generation CLI tool for local development and testing",
|
|
5
|
-
"main": "./dist/index.js",
|
|
6
|
-
"types": "./dist/index.d.ts",
|
|
7
|
-
"bin": {
|
|
8
|
-
"fexapi": "dist/index.js"
|
|
9
|
-
},
|
|
10
|
-
"files": [
|
|
11
|
-
"dist",
|
|
12
|
-
"README.md"
|
|
13
|
-
],
|
|
14
|
-
"scripts": {
|
|
15
|
-
"build": "tsc -p tsconfig.json",
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
"
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
"
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
"
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "fexapi",
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "Mock API generation CLI tool for local development and testing",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"bin": {
|
|
8
|
+
"fexapi": "dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"README.md"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "tsc -p tsconfig.json",
|
|
16
|
+
"lint": "pnpm exec eslint . --max-warnings 0",
|
|
17
|
+
"check-types": "tsc --noEmit",
|
|
18
|
+
"start": "node dist/index.js",
|
|
19
|
+
"serve": "node dist/index.js serve",
|
|
20
|
+
"dev": "tsc -w -p tsconfig.json",
|
|
21
|
+
"prepublishOnly": "pnpm build"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"mock",
|
|
25
|
+
"api",
|
|
26
|
+
"cli",
|
|
27
|
+
"testing",
|
|
28
|
+
"development",
|
|
29
|
+
"faker",
|
|
30
|
+
"mock-server"
|
|
31
|
+
],
|
|
32
|
+
"author": "Shreeteja Mutukundu smutukundu2006@gmail.com",
|
|
33
|
+
"license": "MIT",
|
|
34
|
+
"repository": {
|
|
35
|
+
"type": "git",
|
|
36
|
+
"url": "git+https://github.com/shreeteja172/fexapi.git",
|
|
37
|
+
"directory": "apps/cli"
|
|
38
|
+
},
|
|
39
|
+
"bugs": {
|
|
40
|
+
"url": "https://github.com/shreeteja172/fexapi/issues"
|
|
41
|
+
},
|
|
42
|
+
"homepage": "https://github.com/shreeteja172/fexapi#readme",
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@repo/eslint-config": "workspace:*",
|
|
45
|
+
"@types/node": "^22.15.3",
|
|
46
|
+
"eslint": "^9.39.1",
|
|
47
|
+
"typescript": "5.9.2"
|
|
48
|
+
},
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"@faker-js/faker": "^10.3.0",
|
|
51
|
+
"yaml": "^2.8.3"
|
|
52
|
+
},
|
|
53
|
+
"engines": {
|
|
54
|
+
"node": ">=18.0.0"
|
|
55
|
+
}
|
|
56
|
+
}
|