adorn-api 1.0.13 ā 1.0.15
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/adapter/express/auth.d.ts +8 -0
- package/dist/adapter/express/auth.d.ts.map +1 -1
- package/dist/adapter/express/bootstrap.d.ts +14 -1
- package/dist/adapter/express/bootstrap.d.ts.map +1 -1
- package/dist/adapter/express/coercion.d.ts +81 -1
- package/dist/adapter/express/coercion.d.ts.map +1 -1
- package/dist/adapter/express/index.d.ts +1 -0
- package/dist/adapter/express/index.d.ts.map +1 -1
- package/dist/adapter/express/merge.d.ts +17 -0
- package/dist/adapter/express/merge.d.ts.map +1 -1
- package/dist/adapter/express/openapi.d.ts +55 -0
- package/dist/adapter/express/openapi.d.ts.map +1 -1
- package/dist/adapter/express/router.d.ts +6 -0
- package/dist/adapter/express/router.d.ts.map +1 -1
- package/dist/adapter/express/swagger.d.ts +6 -0
- package/dist/adapter/express/swagger.d.ts.map +1 -1
- package/dist/adapter/express/types.d.ts +39 -0
- package/dist/adapter/express/types.d.ts.map +1 -1
- package/dist/adapter/express/validation.d.ts +19 -2
- package/dist/adapter/express/validation.d.ts.map +1 -1
- package/dist/cli.cjs +192 -11
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +192 -11
- package/dist/cli.js.map +1 -1
- package/dist/compiler/analyze/index.d.ts +5 -0
- package/dist/compiler/analyze/index.d.ts.map +1 -0
- package/dist/compiler/analyze/scanControllers.d.ts +52 -0
- package/dist/compiler/analyze/scanControllers.d.ts.map +1 -1
- package/dist/compiler/cache/isStale.d.ts +26 -0
- package/dist/compiler/cache/isStale.d.ts.map +1 -1
- package/dist/compiler/cache/loadArtifacts.d.ts +36 -0
- package/dist/compiler/cache/loadArtifacts.d.ts.map +1 -1
- package/dist/compiler/cache/schema.d.ts +14 -0
- package/dist/compiler/cache/schema.d.ts.map +1 -1
- package/dist/compiler/cache/writeCache.d.ts +6 -0
- package/dist/compiler/cache/writeCache.d.ts.map +1 -1
- package/dist/compiler/gems.d.ts +75 -0
- package/dist/compiler/gems.d.ts.map +1 -0
- package/dist/compiler/generator/index.d.ts +7 -0
- package/dist/compiler/generator/index.d.ts.map +1 -0
- package/dist/compiler/generator/manifest.d.ts +23 -0
- package/dist/compiler/generator/manifest.d.ts.map +1 -0
- package/dist/compiler/generator/openapi.d.ts +118 -0
- package/dist/compiler/generator/openapi.d.ts.map +1 -0
- package/dist/compiler/graph/builder.d.ts +24 -0
- package/dist/compiler/graph/builder.d.ts.map +1 -0
- package/dist/compiler/graph/index.d.ts +7 -0
- package/dist/compiler/graph/index.d.ts.map +1 -0
- package/dist/compiler/graph/schemaGraph.d.ts +67 -0
- package/dist/compiler/graph/schemaGraph.d.ts.map +1 -0
- package/dist/compiler/graph/types.d.ts +203 -0
- package/dist/compiler/graph/types.d.ts.map +1 -0
- package/dist/compiler/index.d.ts +12 -0
- package/dist/compiler/index.d.ts.map +1 -0
- package/dist/compiler/ir/index.d.ts +7 -0
- package/dist/compiler/ir/index.d.ts.map +1 -0
- package/dist/compiler/ir/pipeline.d.ts +82 -0
- package/dist/compiler/ir/pipeline.d.ts.map +1 -0
- package/dist/compiler/ir/stages.d.ts +40 -0
- package/dist/compiler/ir/stages.d.ts.map +1 -0
- package/dist/compiler/ir/visitor.d.ts +98 -0
- package/dist/compiler/ir/visitor.d.ts.map +1 -0
- package/dist/compiler/manifest/emit.d.ts +14 -0
- package/dist/compiler/manifest/emit.d.ts.map +1 -1
- package/dist/compiler/manifest/format.d.ts +42 -0
- package/dist/compiler/manifest/format.d.ts.map +1 -1
- package/dist/compiler/manifest/index.d.ts +6 -0
- package/dist/compiler/manifest/index.d.ts.map +1 -0
- package/dist/compiler/runner/createProgram.d.ts +16 -0
- package/dist/compiler/runner/createProgram.d.ts.map +1 -1
- package/dist/compiler/runner/index.d.ts +5 -0
- package/dist/compiler/runner/index.d.ts.map +1 -0
- package/dist/compiler/schema/extractAnnotations.d.ts +47 -0
- package/dist/compiler/schema/extractAnnotations.d.ts.map +1 -1
- package/dist/compiler/schema/index.d.ts +6 -0
- package/dist/compiler/schema/index.d.ts.map +1 -0
- package/dist/compiler/schema/intersectionHandler.d.ts +37 -0
- package/dist/compiler/schema/intersectionHandler.d.ts.map +1 -1
- package/dist/compiler/schema/objectHandler.d.ts +86 -0
- package/dist/compiler/schema/objectHandler.d.ts.map +1 -1
- package/dist/compiler/schema/openapi.d.ts +15 -0
- package/dist/compiler/schema/openapi.d.ts.map +1 -1
- package/dist/compiler/schema/parameters.d.ts +72 -0
- package/dist/compiler/schema/parameters.d.ts.map +1 -1
- package/dist/compiler/schema/primitives.d.ts +58 -0
- package/dist/compiler/schema/primitives.d.ts.map +1 -1
- package/dist/compiler/schema/typeToJsonSchema.d.ts +20 -0
- package/dist/compiler/schema/typeToJsonSchema.d.ts.map +1 -1
- package/dist/compiler/schema/types.d.ts +15 -0
- package/dist/compiler/schema/types.d.ts.map +1 -1
- package/dist/compiler/schema/unionHandler.d.ts +60 -0
- package/dist/compiler/schema/unionHandler.d.ts.map +1 -1
- package/dist/compiler/transform/dedup.d.ts +35 -0
- package/dist/compiler/transform/dedup.d.ts.map +1 -0
- package/dist/compiler/transform/flatten.d.ts +50 -0
- package/dist/compiler/transform/flatten.d.ts.map +1 -0
- package/dist/compiler/transform/index.d.ts +7 -0
- package/dist/compiler/transform/index.d.ts.map +1 -0
- package/dist/compiler/transform/inline.d.ts +46 -0
- package/dist/compiler/transform/inline.d.ts.map +1 -0
- package/dist/compiler/validation/emitPrecompiledValidators.d.ts +16 -0
- package/dist/compiler/validation/emitPrecompiledValidators.d.ts.map +1 -1
- package/dist/compiler/validation/index.d.ts +5 -0
- package/dist/compiler/validation/index.d.ts.map +1 -0
- package/dist/decorators/Auth.d.ts +17 -0
- package/dist/decorators/Auth.d.ts.map +1 -1
- package/dist/decorators/Controller.d.ts +15 -0
- package/dist/decorators/Controller.d.ts.map +1 -1
- package/dist/decorators/Public.d.ts +13 -0
- package/dist/decorators/Public.d.ts.map +1 -1
- package/dist/decorators/Use.d.ts +18 -0
- package/dist/decorators/Use.d.ts.map +1 -1
- package/dist/decorators/methods.d.ts +20 -0
- package/dist/decorators/methods.d.ts.map +1 -1
- package/dist/express.cjs +71 -11
- package/dist/express.cjs.map +1 -1
- package/dist/express.d.ts +1 -0
- package/dist/express.d.ts.map +1 -1
- package/dist/express.js +71 -11
- package/dist/express.js.map +1 -1
- package/dist/index.cjs +160 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +155 -2
- package/dist/index.js.map +1 -1
- package/dist/metal/applyListQuery.d.ts +73 -0
- package/dist/metal/applyListQuery.d.ts.map +1 -1
- package/dist/metal/index.cjs.map +1 -1
- package/dist/metal/index.d.ts +4 -0
- package/dist/metal/index.d.ts.map +1 -1
- package/dist/metal/index.js.map +1 -1
- package/dist/metal/listQuery.d.ts +19 -0
- package/dist/metal/listQuery.d.ts.map +1 -1
- package/dist/metal/queryOptions.d.ts +8 -0
- package/dist/metal/queryOptions.d.ts.map +1 -1
- package/dist/metal/readMetalBag.d.ts +36 -0
- package/dist/metal/readMetalBag.d.ts.map +1 -1
- package/dist/metal/registerMetalEntities.d.ts +20 -0
- package/dist/metal/registerMetalEntities.d.ts.map +1 -1
- package/dist/metal/schemaFromEntity.d.ts +30 -0
- package/dist/metal/schemaFromEntity.d.ts.map +1 -1
- package/dist/metal/searchWhere.d.ts +39 -0
- package/dist/metal/searchWhere.d.ts.map +1 -1
- package/dist/metal/symbolMetadata.d.ts +6 -0
- package/dist/metal/symbolMetadata.d.ts.map +1 -1
- package/dist/runtime/auth/runtime.d.ts +155 -6
- package/dist/runtime/auth/runtime.d.ts.map +1 -1
- package/dist/runtime/metadata/bucket.d.ts +1 -2
- package/dist/runtime/metadata/bucket.d.ts.map +1 -1
- package/dist/runtime/metadata/key.d.ts +1 -1
- package/dist/runtime/metadata/key.d.ts.map +1 -1
- package/dist/runtime/metadata/read.d.ts +1 -2
- package/dist/runtime/metadata/read.d.ts.map +1 -1
- package/dist/runtime/metadata/types.d.ts +74 -0
- package/dist/runtime/metadata/types.d.ts.map +1 -1
- package/dist/runtime/polyfill.d.ts +1 -1
- package/dist/runtime/polyfill.d.ts.map +1 -1
- package/dist/runtime/upload.d.ts +37 -0
- package/dist/runtime/upload.d.ts.map +1 -1
- package/dist/runtime/validation/ajv.d.ts +100 -0
- package/dist/runtime/validation/ajv.d.ts.map +1 -1
- package/dist/runtime/validation/index.d.ts +9 -0
- package/dist/runtime/validation/index.d.ts.map +1 -1
- package/dist/scripts/adorn-example.cjs +238 -6
- package/dist/scripts/adorn-example.cjs.map +1 -1
- package/dist/utils/port.d.ts +9 -0
- package/dist/utils/port.d.ts.map +1 -0
- package/package.json +3 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../src/runtime/upload.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../src/runtime/upload.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAC,cAAc,CAAC;CAC/B"}
|
|
@@ -1,20 +1,120 @@
|
|
|
1
1
|
import Ajv from "ajv";
|
|
2
|
+
/**
|
|
3
|
+
* Runtime validation module using AJV.
|
|
4
|
+
*
|
|
5
|
+
* @remarks
|
|
6
|
+
* This module provides validation utilities using the AJV JSON schema validator.
|
|
7
|
+
* It includes interfaces for validation results, errors, and helper functions
|
|
8
|
+
* for creating validators and formatting error messages.
|
|
9
|
+
*
|
|
10
|
+
* @package
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Represents a single validation error with details.
|
|
14
|
+
*
|
|
15
|
+
* @public
|
|
16
|
+
*/
|
|
2
17
|
export interface ValidationError {
|
|
18
|
+
/**
|
|
19
|
+
* The JSON path to the invalid property.
|
|
20
|
+
*/
|
|
3
21
|
path: string;
|
|
22
|
+
/**
|
|
23
|
+
* Human-readable error message.
|
|
24
|
+
*/
|
|
4
25
|
message: string;
|
|
26
|
+
/**
|
|
27
|
+
* The AJV keyword that failed validation.
|
|
28
|
+
*/
|
|
5
29
|
keyword: string;
|
|
30
|
+
/**
|
|
31
|
+
* Additional parameters from the validation error.
|
|
32
|
+
*/
|
|
6
33
|
params: Record<string, unknown>;
|
|
7
34
|
}
|
|
35
|
+
/**
|
|
36
|
+
* Result of a validation operation.
|
|
37
|
+
*
|
|
38
|
+
* @public
|
|
39
|
+
*/
|
|
8
40
|
export interface ValidationResult {
|
|
41
|
+
/**
|
|
42
|
+
* Whether the data passed validation.
|
|
43
|
+
*/
|
|
9
44
|
valid: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Array of validation errors if validation failed, null otherwise.
|
|
47
|
+
*/
|
|
10
48
|
errors: ValidationError[] | null;
|
|
11
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* Error thrown when request validation fails.
|
|
52
|
+
*
|
|
53
|
+
* @public
|
|
54
|
+
*/
|
|
12
55
|
export declare class ValidationErrorResponse extends Error {
|
|
56
|
+
/**
|
|
57
|
+
* HTTP status code for validation errors.
|
|
58
|
+
*/
|
|
13
59
|
statusCode: number;
|
|
60
|
+
/**
|
|
61
|
+
* Detailed validation errors.
|
|
62
|
+
*/
|
|
14
63
|
errors: ValidationError[];
|
|
64
|
+
/**
|
|
65
|
+
* Creates a new ValidationErrorResponse.
|
|
66
|
+
*
|
|
67
|
+
* @param statusCode - HTTP status code (typically 400)
|
|
68
|
+
* @param errors - Array of validation errors
|
|
69
|
+
*/
|
|
15
70
|
constructor(statusCode: number, errors: ValidationError[]);
|
|
16
71
|
}
|
|
72
|
+
/**
|
|
73
|
+
* Creates a configured AJV validator instance.
|
|
74
|
+
*
|
|
75
|
+
* @remarks
|
|
76
|
+
* This function creates an AJV validator with adorn-api's default configuration,
|
|
77
|
+
* including support for custom formats like "br-phone" for Brazilian phone numbers.
|
|
78
|
+
*
|
|
79
|
+
* @returns A configured AJV validator instance
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* ```typescript
|
|
83
|
+
* const validator = createValidator();
|
|
84
|
+
* const validate = validator.compile(mySchema);
|
|
85
|
+
* const result = validate(myData);
|
|
86
|
+
* ```
|
|
87
|
+
*
|
|
88
|
+
* @public
|
|
89
|
+
*/
|
|
17
90
|
export declare function createValidator(): Ajv.Ajv;
|
|
91
|
+
/**
|
|
92
|
+
* Validates data against a JSON schema.
|
|
93
|
+
*
|
|
94
|
+
* @remarks
|
|
95
|
+
* This function compiles the schema and validates the data, returning a
|
|
96
|
+
* structured result with formatted error messages.
|
|
97
|
+
*
|
|
98
|
+
* @param ajv - The AJV validator instance
|
|
99
|
+
* @param data - The data to validate
|
|
100
|
+
* @param schema - The JSON schema to validate against
|
|
101
|
+
* @param dataPath - Base path for error messages (default: "#")
|
|
102
|
+
* @returns ValidationResult with validity and any errors
|
|
103
|
+
*
|
|
104
|
+
* @public
|
|
105
|
+
*/
|
|
18
106
|
export declare function validateData(ajv: ReturnType<typeof createValidator>, data: unknown, schema: Record<string, unknown>, dataPath?: string): ValidationResult;
|
|
107
|
+
/**
|
|
108
|
+
* Formats validation errors into a structured API response.
|
|
109
|
+
*
|
|
110
|
+
* @remarks
|
|
111
|
+
* This function converts validation errors into a format suitable for API
|
|
112
|
+
* responses, grouping errors by their path.
|
|
113
|
+
*
|
|
114
|
+
* @param errors - Array of validation errors
|
|
115
|
+
* @returns Formatted error response object
|
|
116
|
+
*
|
|
117
|
+
* @public
|
|
118
|
+
*/
|
|
19
119
|
export declare function formatValidationErrors(errors: ValidationError[]): Record<string, unknown>;
|
|
20
120
|
//# sourceMappingURL=ajv.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ajv.d.ts","sourceRoot":"","sources":["../../../src/runtime/validation/ajv.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,KAAK,CAAC;AAItB,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"ajv.d.ts","sourceRoot":"","sources":["../../../src/runtime/validation/ajv.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,KAAK,CAAC;AAItB;;;;;;;;;GASG;AAEH;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,KAAK,EAAE,OAAO,CAAC;IAEf;;OAEG;IACH,MAAM,EAAE,eAAe,EAAE,GAAG,IAAI,CAAC;CAClC;AAED;;;;GAIG;AACH,qBAAa,uBAAwB,SAAQ,KAAK;IAChD;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,MAAM,EAAE,eAAe,EAAE,CAAC;IAE1B;;;;;OAKG;gBACS,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE;CAM1D;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,eAAe,YAa9B;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,YAAY,CAC1B,GAAG,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,EACvC,IAAI,EAAE,OAAO,EACb,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,QAAQ,GAAE,MAAY,GACrB,gBAAgB,CAgBlB;AAqBD;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAezF"}
|
|
@@ -1,2 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Re-exports all validation utilities.
|
|
3
|
+
*
|
|
4
|
+
* @remarks
|
|
5
|
+
* This module re-exports the validation functionality provided by the AJV-based
|
|
6
|
+
* validation system, including validation results, errors, and helper functions.
|
|
7
|
+
*
|
|
8
|
+
* @package
|
|
9
|
+
*/
|
|
1
10
|
export * from "./ajv.js";
|
|
2
11
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/runtime/validation/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/runtime/validation/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,cAAc,UAAU,CAAC"}
|
|
@@ -24,10 +24,148 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
24
24
|
));
|
|
25
25
|
|
|
26
26
|
// scripts/adorn-example.ts
|
|
27
|
-
var
|
|
27
|
+
var import_child_process2 = require("child_process");
|
|
28
28
|
var import_path = require("path");
|
|
29
29
|
var import_fs = require("fs");
|
|
30
30
|
var import_node_process = __toESM(require("process"), 1);
|
|
31
|
+
var readline = __toESM(require("readline"), 1);
|
|
32
|
+
|
|
33
|
+
// src/utils/port.ts
|
|
34
|
+
var import_net = require("net");
|
|
35
|
+
var import_child_process = require("child_process");
|
|
36
|
+
var import_util = require("util");
|
|
37
|
+
var execAsync = (0, import_util.promisify)(import_child_process.exec);
|
|
38
|
+
async function isPortAvailable(port, host = "0.0.0.0") {
|
|
39
|
+
return new Promise((resolve) => {
|
|
40
|
+
const server = (0, import_net.createServer)();
|
|
41
|
+
server.on("error", (err) => {
|
|
42
|
+
if (err.code === "EADDRINUSE") {
|
|
43
|
+
resolve(false);
|
|
44
|
+
} else {
|
|
45
|
+
resolve(false);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
server.once("listening", () => {
|
|
49
|
+
server.close(() => {
|
|
50
|
+
resolve(true);
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
server.listen(port, host);
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
async function findProcessOnPort(port) {
|
|
57
|
+
try {
|
|
58
|
+
const platform = process.platform;
|
|
59
|
+
if (platform === "win32") {
|
|
60
|
+
const { stdout } = await execAsync(`netstat -ano | findstr :${port}`);
|
|
61
|
+
for (const line of stdout.split("\n")) {
|
|
62
|
+
const trimmed = line.trim();
|
|
63
|
+
if (!trimmed || trimmed.includes("PID")) continue;
|
|
64
|
+
const parts = trimmed.split(/\s+/);
|
|
65
|
+
if (parts.length >= 5) {
|
|
66
|
+
const address = parts[1];
|
|
67
|
+
const pid = parseInt(parts[parts.length - 1], 10);
|
|
68
|
+
if (address.includes(`:${port}`) && !isNaN(pid)) {
|
|
69
|
+
const command = await getProcessNameOnWindows(pid);
|
|
70
|
+
return { pid, command };
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
} else {
|
|
75
|
+
const { stdout } = await execAsync(`lsof -ti:${port}`);
|
|
76
|
+
const pids = stdout.trim().split("\n").filter(Boolean).map(Number);
|
|
77
|
+
if (pids.length > 0) {
|
|
78
|
+
const pid = pids[0];
|
|
79
|
+
const command = await getProcessNameOnUnix(pid);
|
|
80
|
+
return { pid, command };
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return null;
|
|
84
|
+
} catch (error) {
|
|
85
|
+
if (error.message.includes("matches found")) {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
async function getProcessNameOnWindows(pid) {
|
|
92
|
+
try {
|
|
93
|
+
const { stdout } = await execAsync(`tasklist /FI "PID eq ${pid}" /FO CSV /NH`);
|
|
94
|
+
const line = stdout.trim().split("\n")[0];
|
|
95
|
+
if (line) {
|
|
96
|
+
const parts = line.split('","');
|
|
97
|
+
if (parts.length >= 2) {
|
|
98
|
+
return parts[0].replace(/"/g, "");
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
} catch {
|
|
102
|
+
return void 0;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
async function getProcessNameOnUnix(pid) {
|
|
106
|
+
try {
|
|
107
|
+
const { stdout } = await execAsync(`ps -p ${pid} -o comm=`);
|
|
108
|
+
return stdout.trim() || void 0;
|
|
109
|
+
} catch {
|
|
110
|
+
return void 0;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
async function killProcess(pid) {
|
|
114
|
+
try {
|
|
115
|
+
process.kill(pid, "SIGTERM");
|
|
116
|
+
await new Promise((resolve, reject) => {
|
|
117
|
+
const timeout = setTimeout(() => {
|
|
118
|
+
reject(new Error("Process did not terminate gracefully"));
|
|
119
|
+
}, 5e3);
|
|
120
|
+
const check = () => {
|
|
121
|
+
try {
|
|
122
|
+
process.kill(pid, 0);
|
|
123
|
+
setTimeout(check, 500);
|
|
124
|
+
} catch {
|
|
125
|
+
clearInterval(interval);
|
|
126
|
+
clearTimeout(timeout);
|
|
127
|
+
resolve();
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
const interval = setInterval(check, 500);
|
|
131
|
+
});
|
|
132
|
+
return true;
|
|
133
|
+
} catch {
|
|
134
|
+
try {
|
|
135
|
+
process.kill(pid, "SIGKILL");
|
|
136
|
+
await new Promise((resolve, reject) => {
|
|
137
|
+
const timeout = setTimeout(() => {
|
|
138
|
+
reject(new Error("Process did not terminate"));
|
|
139
|
+
}, 3e3);
|
|
140
|
+
setTimeout(() => {
|
|
141
|
+
try {
|
|
142
|
+
process.kill(pid, 0);
|
|
143
|
+
clearTimeout(timeout);
|
|
144
|
+
reject(new Error("Process still running"));
|
|
145
|
+
} catch {
|
|
146
|
+
clearTimeout(timeout);
|
|
147
|
+
resolve();
|
|
148
|
+
}
|
|
149
|
+
}, 1e3);
|
|
150
|
+
});
|
|
151
|
+
return true;
|
|
152
|
+
} catch {
|
|
153
|
+
return false;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
async function waitForPort(port, host = "0.0.0.0", timeout = 5e3) {
|
|
158
|
+
const start = Date.now();
|
|
159
|
+
while (Date.now() - start < timeout) {
|
|
160
|
+
if (await isPortAvailable(port, host)) {
|
|
161
|
+
return true;
|
|
162
|
+
}
|
|
163
|
+
await new Promise((resolve) => setTimeout(resolve, 200));
|
|
164
|
+
}
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// scripts/adorn-example.ts
|
|
31
169
|
function findRepoRoot(startDir) {
|
|
32
170
|
let current = startDir;
|
|
33
171
|
while (true) {
|
|
@@ -59,12 +197,12 @@ function isWindows() {
|
|
|
59
197
|
}
|
|
60
198
|
function runCommand(command, cwd) {
|
|
61
199
|
const shell = isWindows() ? "cmd.exe" : "/bin/bash";
|
|
62
|
-
(0,
|
|
200
|
+
(0, import_child_process2.execSync)(command, { cwd, stdio: "inherit", shell });
|
|
63
201
|
}
|
|
64
202
|
function spawnCommand(args, cwd) {
|
|
65
203
|
return new Promise((resolve, reject) => {
|
|
66
204
|
const cmd = isWindows() ? "npm.cmd" : "npm";
|
|
67
|
-
const child = (0,
|
|
205
|
+
const child = (0, import_child_process2.spawn)(cmd, args, {
|
|
68
206
|
cwd,
|
|
69
207
|
stdio: "inherit",
|
|
70
208
|
shell: isWindows()
|
|
@@ -98,10 +236,86 @@ ${getExamples().map((e) => ` - ${e}`).join("\n")}
|
|
|
98
236
|
Options:
|
|
99
237
|
-h, --help Show this help message
|
|
100
238
|
-l, --list List all available examples
|
|
239
|
+
-f, --force Force kill process on port without prompting
|
|
240
|
+
-p, --port Specify port (default: 3000, env: ADORN_EXAMPLE_PORT)
|
|
101
241
|
|
|
102
242
|
From the adorn-api project root, you can also use:
|
|
103
243
|
npm run example <example-name>
|
|
104
|
-
`);
|
|
244
|
+
`);
|
|
245
|
+
}
|
|
246
|
+
async function promptWithTimeout(question, timeout = 1e4) {
|
|
247
|
+
const rl = readline.createInterface({
|
|
248
|
+
input: import_node_process.default.stdin,
|
|
249
|
+
output: import_node_process.default.stdout
|
|
250
|
+
});
|
|
251
|
+
let timeoutId = null;
|
|
252
|
+
const timeoutPromise = new Promise((resolve) => {
|
|
253
|
+
timeoutId = setTimeout(() => {
|
|
254
|
+
rl.close();
|
|
255
|
+
console.log("\n\u23F0 Timed out waiting for input");
|
|
256
|
+
resolve(null);
|
|
257
|
+
}, timeout);
|
|
258
|
+
});
|
|
259
|
+
const inputPromise = new Promise((resolve) => {
|
|
260
|
+
rl.question(question, (answer) => {
|
|
261
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
262
|
+
rl.close();
|
|
263
|
+
resolve(answer.trim());
|
|
264
|
+
});
|
|
265
|
+
});
|
|
266
|
+
return Promise.race([inputPromise, timeoutPromise]);
|
|
267
|
+
}
|
|
268
|
+
async function ensurePortAvailable(targetPort, force) {
|
|
269
|
+
console.log(`
|
|
270
|
+
\u{1F50D} Checking port ${targetPort}...`);
|
|
271
|
+
if (await isPortAvailable(targetPort)) {
|
|
272
|
+
console.log(`\u2713 Port ${targetPort} is available`);
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
console.log(`\u274C Port ${targetPort} is already in use.`);
|
|
276
|
+
const processInfo = await findProcessOnPort(targetPort);
|
|
277
|
+
if (!processInfo) {
|
|
278
|
+
console.error(" Could not determine process using this port");
|
|
279
|
+
console.error(" Please stop it manually or use a different port (ADORN_EXAMPLE_PORT env var)");
|
|
280
|
+
import_node_process.default.exit(1);
|
|
281
|
+
}
|
|
282
|
+
const { pid, command } = processInfo;
|
|
283
|
+
console.log(` Process PID: ${pid}`);
|
|
284
|
+
if (command) {
|
|
285
|
+
console.log(` Command: ${command}`);
|
|
286
|
+
}
|
|
287
|
+
if (force) {
|
|
288
|
+
console.log(`
|
|
289
|
+
Force flag enabled, killing process ${pid}...`);
|
|
290
|
+
} else {
|
|
291
|
+
const answer = await promptWithTimeout(" Kill existing process? (y/n): ", 1e4);
|
|
292
|
+
if (answer === null) {
|
|
293
|
+
console.log("\n\u274C Aborted. Please stop the process manually or use a different port");
|
|
294
|
+
import_node_process.default.exit(1);
|
|
295
|
+
}
|
|
296
|
+
if (answer.toLowerCase() !== "y" && answer.toLowerCase() !== "yes") {
|
|
297
|
+
console.log("\n\u274C Aborted. Please stop the process manually or use a different port");
|
|
298
|
+
console.log(" You can also use the --force flag to auto-kill");
|
|
299
|
+
import_node_process.default.exit(1);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
console.log(` Terminating process ${pid}...`);
|
|
303
|
+
if (await killProcess(pid)) {
|
|
304
|
+
console.log(" \u2713 Process killed successfully");
|
|
305
|
+
console.log(` Waiting for port ${targetPort} to be released...`);
|
|
306
|
+
const released = await waitForPort(targetPort, "0.0.0.0", 3e3);
|
|
307
|
+
if (!released) {
|
|
308
|
+
console.error(`
|
|
309
|
+
\u274C Port ${targetPort} still in use after killing process`);
|
|
310
|
+
import_node_process.default.exit(1);
|
|
311
|
+
}
|
|
312
|
+
console.log(` \u2713 Port ${targetPort} is now available`);
|
|
313
|
+
} else {
|
|
314
|
+
console.error(`
|
|
315
|
+
\u274C Failed to kill process ${pid}`);
|
|
316
|
+
console.error(" You may need to kill it manually or choose a different port");
|
|
317
|
+
import_node_process.default.exit(1);
|
|
318
|
+
}
|
|
105
319
|
}
|
|
106
320
|
async function main() {
|
|
107
321
|
const args = import_node_process.default.argv.slice(2);
|
|
@@ -114,7 +328,24 @@ async function main() {
|
|
|
114
328
|
getExamples().forEach((ex) => console.log(` - ${ex}`));
|
|
115
329
|
import_node_process.default.exit(0);
|
|
116
330
|
}
|
|
117
|
-
const
|
|
331
|
+
const forceFlag = args.includes("-f") || args.includes("--force");
|
|
332
|
+
const portIndex = args.indexOf("-p") !== -1 ? args.indexOf("-p") : args.indexOf("--port");
|
|
333
|
+
let targetPort = Number(import_node_process.default.env.ADORN_EXAMPLE_PORT || 3e3);
|
|
334
|
+
if (portIndex !== -1 && args[portIndex + 1]) {
|
|
335
|
+
const portArg = Number(args[portIndex + 1]);
|
|
336
|
+
if (!isNaN(portArg) && portArg > 0 && portArg <= 65535) {
|
|
337
|
+
targetPort = portArg;
|
|
338
|
+
} else {
|
|
339
|
+
console.error(`
|
|
340
|
+
\u274C Invalid port number: ${args[portIndex + 1]}`);
|
|
341
|
+
console.error(" Port must be between 1 and 65535");
|
|
342
|
+
import_node_process.default.exit(1);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
const filteredArgs = args.filter(
|
|
346
|
+
(arg) => !["-f", "--force", "-p", "--port"].includes(arg) && (portIndex === -1 || arg !== args[portIndex + 1])
|
|
347
|
+
);
|
|
348
|
+
const example = filteredArgs[0] || "basic";
|
|
118
349
|
const examplePath = (0, import_path.join)(repoRoot, "examples", example);
|
|
119
350
|
if (!(0, import_fs.existsSync)(examplePath)) {
|
|
120
351
|
console.error(`
|
|
@@ -137,7 +368,8 @@ async function main() {
|
|
|
137
368
|
}
|
|
138
369
|
console.log("\u{1F4E6} Building artifacts...");
|
|
139
370
|
runCommand("npm run build", examplePath);
|
|
140
|
-
|
|
371
|
+
await ensurePortAvailable(targetPort, forceFlag);
|
|
372
|
+
console.log("\n\u{1F310} Starting server...\n");
|
|
141
373
|
console.log("Press Ctrl+C to stop\n");
|
|
142
374
|
child = await spawnCommand(["run", "dev"], examplePath);
|
|
143
375
|
import_node_process.default.on("SIGINT", () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../scripts/adorn-example.ts"],"sourcesContent":["#!/usr/bin/env node\n\n/**\n * Adorn-API Example Runner\n * \n * Usage:\n * npx adorn-example <example-name>\n * npx adorn-example blog-platform\n * npx adorn-example task-manager\n * \n * Or from the adorn-api project root:\n * npm run example <example-name>\n */\n\nimport { execSync, spawn, ChildProcess } from \"child_process\";\nimport { dirname, join } from \"path\";\nimport { existsSync, readdirSync, statSync } from \"fs\";\nimport process from \"node:process\";\n\nfunction findRepoRoot(startDir: string): string | null {\n let current = startDir;\n while (true) {\n const examplesDir = join(current, \"examples\");\n const packageJson = join(current, \"package.json\");\n if (existsSync(examplesDir) && existsSync(packageJson)) {\n return current;\n }\n const parent = dirname(current);\n if (parent === current) {\n return null;\n }\n current = parent;\n }\n}\n\nfunction resolveRepoRoot(): string {\n const candidates = [process.env.INIT_CWD, process.cwd()].filter(\n (dir): dir is string => Boolean(dir),\n );\n\n for (const candidate of candidates) {\n const root = findRepoRoot(candidate);\n if (root) return root;\n }\n\n return process.cwd();\n}\n\nconst repoRoot = resolveRepoRoot();\n\nfunction isWindows(): boolean {\n return process.platform === \"win32\";\n}\n\nfunction runCommand(command: string, cwd: string): void {\n const shell = isWindows() ? \"cmd.exe\" : \"/bin/bash\";\n execSync(command, { cwd, stdio: \"inherit\", shell });\n}\n\nfunction spawnCommand(args: string[], cwd: string): Promise<ChildProcess> {\n return new Promise((resolve, reject) => {\n const cmd = isWindows() ? \"npm.cmd\" : \"npm\";\n const child = spawn(cmd, args, {\n cwd,\n stdio: \"inherit\",\n shell: isWindows(),\n });\n\n child.on(\"error\", reject);\n resolve(child);\n });\n}\n\nfunction getExamples(): string[] {\n const examplesDir = join(repoRoot, \"examples\");\n if (!existsSync(examplesDir)) return [];\n return readdirSync(examplesDir).filter(name => {\n const path = join(examplesDir, name);\n return statSync(path).isDirectory();\n });\n}\n\nfunction printHelp(): void {\n console.log(`\nUsage: npx adorn-example <example-name>\n\nRun an adorn-api example with automatic dependency installation.\n\nExamples:\n npx adorn-example blog-platform\n npx adorn-example task-manager\n npx adorn-example basic\n\nAvailable examples:\n${getExamples().map(e => ` - ${e}`).join(\"\\n\")}\n\nOptions:\n -h, --help Show this help message\n -l, --list List all available examples\n\nFrom the adorn-api project root, you can also use:\n npm run example <example-name>\n`);\n}\n\nasync function main(): Promise<void> {\n const args = process.argv.slice(2);\n \n if (args.includes(\"-h\") || args.includes(\"--help\")) {\n printHelp();\n process.exit(0);\n }\n\n if (args.includes(\"-l\") || args.includes(\"--list\")) {\n console.log(\"Available examples:\");\n getExamples().forEach(ex => console.log(` - ${ex}`));\n process.exit(0);\n }\n\n const example = args[0] || \"basic\";\n const examplePath = join(repoRoot, \"examples\", example);\n\n if (!existsSync(examplePath)) {\n console.error(`\\nā Example \"${example}\" not found.\\n`);\n console.log(\"Available examples:\");\n getExamples().forEach(ex => console.log(` - ${ex}`));\n process.exit(1);\n }\n\n console.log(`\\nš Running \"${example}\" example...\\n`);\n\n let child: ChildProcess | null = null;\n\n try {\n const nodeModulesPath = join(examplePath, \"node_modules\");\n const nodeModulesExists = existsSync(nodeModulesPath);\n\n if (!nodeModulesExists) {\n console.log(\"š¦ Installing dependencies...\");\n runCommand(\"npm install\", examplePath);\n }\n\n console.log(\"š¦ Building artifacts...\");\n runCommand(\"npm run build\", examplePath);\n\n console.log(\"š Starting server...\\n\");\n console.log(\"Press Ctrl+C to stop\\n\");\n\n child = await spawnCommand([\"run\", \"dev\"], examplePath);\n\n process.on(\"SIGINT\", () => {\n if (child) child.kill(\"SIGINT\");\n });\n\n process.on(\"SIGTERM\", () => {\n if (child) child.kill(\"SIGTERM\");\n });\n\n await new Promise<void>((resolve, reject) => {\n if (!child) {\n reject(new Error(\"Child process not started\"));\n return;\n }\n child.on(\"exit\", (code) => {\n if (code === 0 || code === null) {\n resolve();\n } else {\n reject(new Error(`Process exited with code ${code}`));\n }\n });\n child.on(\"error\", reject);\n });\n } catch (err: any) {\n if (err.code !== \"SIGINT\" && err.code !== \"SIGTERM\") {\n console.error(`\\nā Error: ${err.message}`);\n process.exit(1);\n }\n }\n}\n\nmain();\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAcA,2BAA8C;AAC9C,kBAA8B;AAC9B,gBAAkD;AAClD,0BAAoB;AAEpB,SAAS,aAAa,UAAiC;AACrD,MAAI,UAAU;AACd,SAAO,MAAM;AACX,UAAM,kBAAc,kBAAK,SAAS,UAAU;AAC5C,UAAM,kBAAc,kBAAK,SAAS,cAAc;AAChD,YAAI,sBAAW,WAAW,SAAK,sBAAW,WAAW,GAAG;AACtD,aAAO;AAAA,IACT;AACA,UAAM,aAAS,qBAAQ,OAAO;AAC9B,QAAI,WAAW,SAAS;AACtB,aAAO;AAAA,IACT;AACA,cAAU;AAAA,EACZ;AACF;AAEA,SAAS,kBAA0B;AACjC,QAAM,aAAa,CAAC,oBAAAA,QAAQ,IAAI,UAAU,oBAAAA,QAAQ,IAAI,CAAC,EAAE;AAAA,IACvD,CAAC,QAAuB,QAAQ,GAAG;AAAA,EACrC;AAEA,aAAW,aAAa,YAAY;AAClC,UAAM,OAAO,aAAa,SAAS;AACnC,QAAI,KAAM,QAAO;AAAA,EACnB;AAEA,SAAO,oBAAAA,QAAQ,IAAI;AACrB;AAEA,IAAM,WAAW,gBAAgB;AAEjC,SAAS,YAAqB;AAC5B,SAAO,oBAAAA,QAAQ,aAAa;AAC9B;AAEA,SAAS,WAAW,SAAiB,KAAmB;AACtD,QAAM,QAAQ,UAAU,IAAI,YAAY;AACxC,qCAAS,SAAS,EAAE,KAAK,OAAO,WAAW,MAAM,CAAC;AACpD;AAEA,SAAS,aAAa,MAAgB,KAAoC;AACxE,SAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,UAAM,MAAM,UAAU,IAAI,YAAY;AACtC,UAAM,YAAQ,4BAAM,KAAK,MAAM;AAAA,MAC7B;AAAA,MACA,OAAO;AAAA,MACP,OAAO,UAAU;AAAA,IACnB,CAAC;AAED,UAAM,GAAG,SAAS,MAAM;AACxB,YAAQ,KAAK;AAAA,EACf,CAAC;AACH;AAEA,SAAS,cAAwB;AAC/B,QAAM,kBAAc,kBAAK,UAAU,UAAU;AAC7C,MAAI,KAAC,sBAAW,WAAW,EAAG,QAAO,CAAC;AACtC,aAAO,uBAAY,WAAW,EAAE,OAAO,UAAQ;AAC7C,UAAM,WAAO,kBAAK,aAAa,IAAI;AACnC,eAAO,oBAAS,IAAI,EAAE,YAAY;AAAA,EACpC,CAAC;AACH;AAEA,SAAS,YAAkB;AACzB,UAAQ,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWZ,YAAY,EAAE,IAAI,OAAK,OAAO,CAAC,EAAE,EAAE,KAAK,IAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAQ9C;AACD;AAEA,eAAe,OAAsB;AACnC,QAAM,OAAO,oBAAAA,QAAQ,KAAK,MAAM,CAAC;AAEjC,MAAI,KAAK,SAAS,IAAI,KAAK,KAAK,SAAS,QAAQ,GAAG;AAClD,cAAU;AACV,wBAAAA,QAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,MAAI,KAAK,SAAS,IAAI,KAAK,KAAK,SAAS,QAAQ,GAAG;AAClD,YAAQ,IAAI,qBAAqB;AACjC,gBAAY,EAAE,QAAQ,QAAM,QAAQ,IAAI,OAAO,EAAE,EAAE,CAAC;AACpD,wBAAAA,QAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,UAAU,KAAK,CAAC,KAAK;AAC3B,QAAM,kBAAc,kBAAK,UAAU,YAAY,OAAO;AAEtD,MAAI,KAAC,sBAAW,WAAW,GAAG;AAC5B,YAAQ,MAAM;AAAA,kBAAgB,OAAO;AAAA,CAAgB;AACrD,YAAQ,IAAI,qBAAqB;AACjC,gBAAY,EAAE,QAAQ,QAAM,QAAQ,IAAI,OAAO,EAAE,EAAE,CAAC;AACpD,wBAAAA,QAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,UAAQ,IAAI;AAAA,qBAAiB,OAAO;AAAA,CAAgB;AAEpD,MAAI,QAA6B;AAEjC,MAAI;AACF,UAAM,sBAAkB,kBAAK,aAAa,cAAc;AACxD,UAAM,wBAAoB,sBAAW,eAAe;AAEpD,QAAI,CAAC,mBAAmB;AACtB,cAAQ,IAAI,sCAA+B;AAC3C,iBAAW,eAAe,WAAW;AAAA,IACvC;AAEA,YAAQ,IAAI,iCAA0B;AACtC,eAAW,iBAAiB,WAAW;AAEvC,YAAQ,IAAI,gCAAyB;AACrC,YAAQ,IAAI,wBAAwB;AAEpC,YAAQ,MAAM,aAAa,CAAC,OAAO,KAAK,GAAG,WAAW;AAEtD,wBAAAA,QAAQ,GAAG,UAAU,MAAM;AACzB,UAAI,MAAO,OAAM,KAAK,QAAQ;AAAA,IAChC,CAAC;AAED,wBAAAA,QAAQ,GAAG,WAAW,MAAM;AAC1B,UAAI,MAAO,OAAM,KAAK,SAAS;AAAA,IACjC,CAAC;AAED,UAAM,IAAI,QAAc,CAAC,SAAS,WAAW;AAC3C,UAAI,CAAC,OAAO;AACV,eAAO,IAAI,MAAM,2BAA2B,CAAC;AAC7C;AAAA,MACF;AACA,YAAM,GAAG,QAAQ,CAAC,SAAS;AACzB,YAAI,SAAS,KAAK,SAAS,MAAM;AAC/B,kBAAQ;AAAA,QACV,OAAO;AACL,iBAAO,IAAI,MAAM,4BAA4B,IAAI,EAAE,CAAC;AAAA,QACtD;AAAA,MACF,CAAC;AACD,YAAM,GAAG,SAAS,MAAM;AAAA,IAC1B,CAAC;AAAA,EACH,SAAS,KAAU;AACjB,QAAI,IAAI,SAAS,YAAY,IAAI,SAAS,WAAW;AACnD,cAAQ,MAAM;AAAA,gBAAc,IAAI,OAAO,EAAE;AACzC,0BAAAA,QAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF;AACF;AAEA,KAAK;","names":["process"]}
|
|
1
|
+
{"version":3,"sources":["../../scripts/adorn-example.ts","../../src/utils/port.ts"],"sourcesContent":["#!/usr/bin/env node\n\n/**\n * Adorn-API Example Runner\n * \n * Usage:\n * npx adorn-example <example-name>\n * npx adorn-example blog-platform\n * npx adorn-example task-manager\n * \n * Or from the adorn-api project root:\n * npm run example <example-name>\n */\n\nimport { execSync, spawn, ChildProcess } from \"child_process\";\nimport { dirname, join } from \"path\";\nimport { existsSync, readdirSync, statSync } from \"fs\";\nimport process from \"node:process\";\nimport * as readline from \"readline\";\nimport { isPortAvailable, findProcessOnPort, killProcess, waitForPort } from \"../src/utils/port\";\n\nfunction findRepoRoot(startDir: string): string | null {\n let current = startDir;\n while (true) {\n const examplesDir = join(current, \"examples\");\n const packageJson = join(current, \"package.json\");\n if (existsSync(examplesDir) && existsSync(packageJson)) {\n return current;\n }\n const parent = dirname(current);\n if (parent === current) {\n return null;\n }\n current = parent;\n }\n}\n\nfunction resolveRepoRoot(): string {\n const candidates = [process.env.INIT_CWD, process.cwd()].filter(\n (dir): dir is string => Boolean(dir),\n );\n\n for (const candidate of candidates) {\n const root = findRepoRoot(candidate);\n if (root) return root;\n }\n\n return process.cwd();\n}\n\nconst repoRoot = resolveRepoRoot();\n\nfunction isWindows(): boolean {\n return process.platform === \"win32\";\n}\n\nfunction runCommand(command: string, cwd: string): void {\n const shell = isWindows() ? \"cmd.exe\" : \"/bin/bash\";\n execSync(command, { cwd, stdio: \"inherit\", shell });\n}\n\nfunction spawnCommand(args: string[], cwd: string): Promise<ChildProcess> {\n return new Promise((resolve, reject) => {\n const cmd = isWindows() ? \"npm.cmd\" : \"npm\";\n const child = spawn(cmd, args, {\n cwd,\n stdio: \"inherit\",\n shell: isWindows(),\n });\n\n child.on(\"error\", reject);\n resolve(child);\n });\n}\n\nfunction getExamples(): string[] {\n const examplesDir = join(repoRoot, \"examples\");\n if (!existsSync(examplesDir)) return [];\n return readdirSync(examplesDir).filter(name => {\n const path = join(examplesDir, name);\n return statSync(path).isDirectory();\n });\n}\n\nfunction printHelp(): void {\n console.log(`\nUsage: npx adorn-example <example-name>\n\nRun an adorn-api example with automatic dependency installation.\n\nExamples:\n npx adorn-example blog-platform\n npx adorn-example task-manager\n npx adorn-example basic\n\nAvailable examples:\n${getExamples().map(e => ` - ${e}`).join(\"\\n\")}\n\nOptions:\n -h, --help Show this help message\n -l, --list List all available examples\n -f, --force Force kill process on port without prompting\n -p, --port Specify port (default: 3000, env: ADORN_EXAMPLE_PORT)\n\nFrom the adorn-api project root, you can also use:\n npm run example <example-name>\n `);\n}\n\nasync function promptWithTimeout(question: string, timeout: number = 10000): Promise<string | null> {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n let timeoutId: NodeJS.Timeout | null = null;\n\n const timeoutPromise = new Promise<string | null>((resolve) => {\n timeoutId = setTimeout(() => {\n rl.close();\n console.log(\"\\nā° Timed out waiting for input\");\n resolve(null);\n }, timeout);\n });\n\n const inputPromise = new Promise<string>((resolve) => {\n rl.question(question, (answer) => {\n if (timeoutId) clearTimeout(timeoutId);\n rl.close();\n resolve(answer.trim());\n });\n });\n\n return Promise.race([inputPromise, timeoutPromise]);\n}\n\nasync function ensurePortAvailable(targetPort: number, force: boolean): Promise<void> {\n console.log(`\\nš Checking port ${targetPort}...`);\n\n if (await isPortAvailable(targetPort)) {\n console.log(`ā Port ${targetPort} is available`);\n return;\n }\n\n console.log(`ā Port ${targetPort} is already in use.`);\n\n const processInfo = await findProcessOnPort(targetPort);\n \n if (!processInfo) {\n console.error(\" Could not determine process using this port\");\n console.error(\" Please stop it manually or use a different port (ADORN_EXAMPLE_PORT env var)\");\n process.exit(1);\n }\n\n const { pid, command } = processInfo;\n console.log(` Process PID: ${pid}`);\n if (command) {\n console.log(` Command: ${command}`);\n }\n\n if (force) {\n console.log(`\\n Force flag enabled, killing process ${pid}...`);\n } else {\n const answer = await promptWithTimeout(\" Kill existing process? (y/n): \", 10000);\n\n if (answer === null) {\n console.log(\"\\nā Aborted. Please stop the process manually or use a different port\");\n process.exit(1);\n }\n\n if (answer.toLowerCase() !== \"y\" && answer.toLowerCase() !== \"yes\") {\n console.log(\"\\nā Aborted. Please stop the process manually or use a different port\");\n console.log(\" You can also use the --force flag to auto-kill\");\n process.exit(1);\n }\n }\n\n console.log(` Terminating process ${pid}...`);\n if (await killProcess(pid)) {\n console.log(\" ā Process killed successfully\");\n\n console.log(` Waiting for port ${targetPort} to be released...`);\n const released = await waitForPort(targetPort, \"0.0.0.0\", 3000);\n\n if (!released) {\n console.error(`\\nā Port ${targetPort} still in use after killing process`);\n process.exit(1);\n }\n \n console.log(` ā Port ${targetPort} is now available`);\n } else {\n console.error(`\\nā Failed to kill process ${pid}`);\n console.error(\" You may need to kill it manually or choose a different port\");\n process.exit(1);\n }\n}\n\nasync function main(): Promise<void> {\n const args = process.argv.slice(2);\n \n if (args.includes(\"-h\") || args.includes(\"--help\")) {\n printHelp();\n process.exit(0);\n }\n\n if (args.includes(\"-l\") || args.includes(\"--list\")) {\n console.log(\"Available examples:\");\n getExamples().forEach(ex => console.log(` - ${ex}`));\n process.exit(0);\n }\n\n const forceFlag = args.includes(\"-f\") || args.includes(\"--force\");\n const portIndex = args.indexOf(\"-p\") !== -1 ? args.indexOf(\"-p\") : args.indexOf(\"--port\");\n let targetPort = Number(process.env.ADORN_EXAMPLE_PORT || 3000);\n \n if (portIndex !== -1 && args[portIndex + 1]) {\n const portArg = Number(args[portIndex + 1]);\n if (!isNaN(portArg) && portArg > 0 && portArg <= 65535) {\n targetPort = portArg;\n } else {\n console.error(`\\nā Invalid port number: ${args[portIndex + 1]}`);\n console.error(\" Port must be between 1 and 65535\");\n process.exit(1);\n }\n }\n\n const filteredArgs = args.filter(arg => \n ![\"-f\", \"--force\", \"-p\", \"--port\"].includes(arg) &&\n (portIndex === -1 || arg !== args[portIndex + 1])\n );\n\n const example = filteredArgs[0] || \"basic\";\n const examplePath = join(repoRoot, \"examples\", example);\n\n if (!existsSync(examplePath)) {\n console.error(`\\nā Example \"${example}\" not found.\\n`);\n console.log(\"Available examples:\");\n getExamples().forEach(ex => console.log(` - ${ex}`));\n process.exit(1);\n }\n\n console.log(`\\nš Running \"${example}\" example...\\n`);\n\n let child: ChildProcess | null = null;\n\n try {\n const nodeModulesPath = join(examplePath, \"node_modules\");\n const nodeModulesExists = existsSync(nodeModulesPath);\n\n if (!nodeModulesExists) {\n console.log(\"š¦ Installing dependencies...\");\n runCommand(\"npm install\", examplePath);\n }\n\n console.log(\"š¦ Building artifacts...\");\n runCommand(\"npm run build\", examplePath);\n\n await ensurePortAvailable(targetPort, forceFlag);\n\n console.log(\"\\nš Starting server...\\n\");\n console.log(\"Press Ctrl+C to stop\\n\");\n\n child = await spawnCommand([\"run\", \"dev\"], examplePath);\n\n process.on(\"SIGINT\", () => {\n if (child) child.kill(\"SIGINT\");\n });\n\n process.on(\"SIGTERM\", () => {\n if (child) child.kill(\"SIGTERM\");\n });\n\n await new Promise<void>((resolve, reject) => {\n if (!child) {\n reject(new Error(\"Child process not started\"));\n return;\n }\n child.on(\"exit\", (code) => {\n if (code === 0 || code === null) {\n resolve();\n } else {\n reject(new Error(`Process exited with code ${code}`));\n }\n });\n child.on(\"error\", reject);\n });\n } catch (err: any) {\n if (err.code !== \"SIGINT\" && err.code !== \"SIGTERM\") {\n console.error(`\\nā Error: ${err.message}`);\n process.exit(1);\n }\n }\n}\n\nmain();\n","import { createServer, Server } from \"net\";\nimport { exec } from \"child_process\";\nimport { promisify } from \"util\";\n\nconst execAsync = promisify(exec);\n\nexport interface ProcessInfo {\n pid: number;\n command?: string;\n}\n\nexport async function isPortAvailable(port: number, host: string = \"0.0.0.0\"): Promise<boolean> {\n return new Promise<boolean>((resolve) => {\n const server: Server = createServer();\n\n server.on(\"error\", (err: any) => {\n if (err.code === \"EADDRINUSE\") {\n resolve(false);\n } else {\n resolve(false);\n }\n });\n\n server.once(\"listening\", () => {\n server.close(() => {\n resolve(true);\n });\n });\n\n server.listen(port, host);\n });\n}\n\nexport async function findProcessOnPort(port: number): Promise<ProcessInfo | null> {\n try {\n const platform = process.platform;\n\n if (platform === \"win32\") {\n const { stdout } = await execAsync(`netstat -ano | findstr :${port}`);\n \n for (const line of stdout.split(\"\\n\")) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.includes(\"PID\")) continue;\n \n const parts = trimmed.split(/\\s+/);\n if (parts.length >= 5) {\n const address = parts[1];\n const pid = parseInt(parts[parts.length - 1], 10);\n \n if (address.includes(`:${port}`) && !isNaN(pid)) {\n const command = await getProcessNameOnWindows(pid);\n return { pid, command };\n }\n }\n }\n } else {\n const { stdout } = await execAsync(`lsof -ti:${port}`);\n const pids = stdout.trim().split(\"\\n\").filter(Boolean).map(Number);\n \n if (pids.length > 0) {\n const pid = pids[0];\n const command = await getProcessNameOnUnix(pid);\n return { pid, command };\n }\n }\n\n return null;\n } catch (error: any) {\n if (error.message.includes(\"matches found\")) {\n return null;\n }\n return null;\n }\n}\n\nasync function getProcessNameOnWindows(pid: number): Promise<string | undefined> {\n try {\n const { stdout } = await execAsync(`tasklist /FI \"PID eq ${pid}\" /FO CSV /NH`);\n const line = stdout.trim().split(\"\\n\")[0];\n if (line) {\n const parts = line.split('\",\"');\n if (parts.length >= 2) {\n return parts[0].replace(/\"/g, \"\");\n }\n }\n } catch {\n return undefined;\n }\n}\n\nasync function getProcessNameOnUnix(pid: number): Promise<string | undefined> {\n try {\n const { stdout } = await execAsync(`ps -p ${pid} -o comm=`);\n return stdout.trim() || undefined;\n } catch {\n return undefined;\n }\n}\n\nexport async function killProcess(pid: number): Promise<boolean> {\n try {\n process.kill(pid, \"SIGTERM\");\n \n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n reject(new Error(\"Process did not terminate gracefully\"));\n }, 5000);\n \n const check = () => {\n try {\n process.kill(pid, 0);\n setTimeout(check, 500);\n } catch {\n clearInterval(interval);\n clearTimeout(timeout);\n resolve();\n }\n };\n \n const interval = setInterval(check, 500);\n });\n \n return true;\n } catch {\n try {\n process.kill(pid, \"SIGKILL\");\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n reject(new Error(\"Process did not terminate\"));\n }, 3000);\n \n setTimeout(() => {\n try {\n process.kill(pid, 0);\n clearTimeout(timeout);\n reject(new Error(\"Process still running\"));\n } catch {\n clearTimeout(timeout);\n resolve();\n }\n }, 1000);\n });\n \n return true;\n } catch {\n return false;\n }\n }\n}\n\nexport async function waitForPort(port: number, host: string = \"0.0.0.0\", timeout: number = 5000): Promise<boolean> {\n const start = Date.now();\n \n while (Date.now() - start < timeout) {\n if (await isPortAvailable(port, host)) {\n return true;\n }\n await new Promise(resolve => setTimeout(resolve, 200));\n }\n \n return false;\n}\n"],"mappings":"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","names":["import_child_process","process"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface ProcessInfo {
|
|
2
|
+
pid: number;
|
|
3
|
+
command?: string;
|
|
4
|
+
}
|
|
5
|
+
export declare function isPortAvailable(port: number, host?: string): Promise<boolean>;
|
|
6
|
+
export declare function findProcessOnPort(port: number): Promise<ProcessInfo | null>;
|
|
7
|
+
export declare function killProcess(pid: number): Promise<boolean>;
|
|
8
|
+
export declare function waitForPort(port: number, host?: string, timeout?: number): Promise<boolean>;
|
|
9
|
+
//# sourceMappingURL=port.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"port.d.ts","sourceRoot":"","sources":["../../src/utils/port.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,MAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,CAoB9F;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAwCjF;AA0BD,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAiD/D;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,MAAkB,EAAE,OAAO,GAAE,MAAa,GAAG,OAAO,CAAC,OAAO,CAAC,CAWlH"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "adorn-api",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.15",
|
|
4
4
|
"description": "Stage-3 decorator-first OpenAPI + routing toolkit",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -64,6 +64,7 @@
|
|
|
64
64
|
"dependencies": {
|
|
65
65
|
"ajv": "^8.17.1",
|
|
66
66
|
"ajv-formats": "^3.0.1",
|
|
67
|
+
"cors": "^2.8.5",
|
|
67
68
|
"metal-orm": "^1.0.78",
|
|
68
69
|
"swagger-ui-express": "^5.0.0",
|
|
69
70
|
"typescript": "^5.9.0"
|
|
@@ -78,6 +79,7 @@
|
|
|
78
79
|
},
|
|
79
80
|
"devDependencies": {
|
|
80
81
|
"@eslint/js": "^9.39.2",
|
|
82
|
+
"@types/cors": "^2.8.17",
|
|
81
83
|
"@types/express": "^4.17.0",
|
|
82
84
|
"@types/node": "^20.0.0",
|
|
83
85
|
"@types/supertest": "^6.0.0",
|