@thoughtpivot/flight 1.0.8 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/flight.js +58 -3
- package/package.json +1 -1
- package/src/flight.ts +71 -5
package/README.md
CHANGED
|
@@ -97,6 +97,7 @@ node flight.js --mode production --app_home .
|
|
|
97
97
|
Available CLI options:
|
|
98
98
|
|
|
99
99
|
- `--app_home`: Application root directory (default: current directory)
|
|
100
|
+
- `--exclude_paths` / `--exclude-paths`: Directories under `app_home` to omit when discovering `**/*.backend.ts` routes. Repeat the flag (`--exclude_paths node_modules --exclude_paths dist`) or use commas (`--exclude_paths node_modules,dist`). Also accepts `FLIGHT_EXCLUDE_PATHS` (comma-separated). Paths must stay inside `app_home`.
|
|
100
101
|
- `--app_key`: Application key for sessions (default: 'flightApp')
|
|
101
102
|
- `--app_secret`: Secret key for session encryption (default: 'the best secret key in the world')
|
|
102
103
|
- `--mode`: 'development' or 'production' (default: 'production')
|
package/dist/flight.js
CHANGED
|
@@ -21,9 +21,54 @@ const path_1 = __importDefault(require("path"));
|
|
|
21
21
|
const koa_ratelimit_1 = __importDefault(require("koa-ratelimit"));
|
|
22
22
|
const koa_static_1 = __importDefault(require("koa-static"));
|
|
23
23
|
const koa_session_1 = __importDefault(require("koa-session"));
|
|
24
|
+
function normalizeExcludePaths(value) {
|
|
25
|
+
if (value == null || value === '')
|
|
26
|
+
return [];
|
|
27
|
+
const parts = Array.isArray(value) ? value : [value];
|
|
28
|
+
const out = [];
|
|
29
|
+
for (const p of parts) {
|
|
30
|
+
const s = String(p).trim();
|
|
31
|
+
if (!s)
|
|
32
|
+
continue;
|
|
33
|
+
out.push(...s
|
|
34
|
+
.split(',')
|
|
35
|
+
.map((x) => x.trim())
|
|
36
|
+
.filter(Boolean));
|
|
37
|
+
}
|
|
38
|
+
return out;
|
|
39
|
+
}
|
|
40
|
+
function dedupeStrings(items) {
|
|
41
|
+
return [...new Set(items)];
|
|
42
|
+
}
|
|
43
|
+
/** Build fast-glob ignore globs for trees rooted under `appRootAbs`. */
|
|
44
|
+
function backendDiscoveryIgnorePatterns(appRootAbs, excludeRelativeDirs) {
|
|
45
|
+
const patterns = [];
|
|
46
|
+
for (const raw of excludeRelativeDirs) {
|
|
47
|
+
const trimmed = raw.trim();
|
|
48
|
+
if (!trimmed)
|
|
49
|
+
continue;
|
|
50
|
+
const resolved = path_1.default.resolve(appRootAbs, trimmed);
|
|
51
|
+
const rel = path_1.default.relative(appRootAbs, resolved);
|
|
52
|
+
const relPosix = rel.replace(/\\/g, '/');
|
|
53
|
+
if (!relPosix || relPosix.startsWith('..') || path_1.default.isAbsolute(rel)) {
|
|
54
|
+
console.warn(`Flight: exclude_paths entry skipped (outside app_home): ${trimmed}`);
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
patterns.push(`${relPosix}/**`);
|
|
58
|
+
}
|
|
59
|
+
return patterns;
|
|
60
|
+
}
|
|
24
61
|
const _yargs = require('yargs/yargs');
|
|
25
|
-
const
|
|
26
|
-
const argv =
|
|
62
|
+
const yargsEntry = typeof _yargs === 'function' ? _yargs : _yargs.default;
|
|
63
|
+
const argv = yargsEntry(process.argv.slice(2))
|
|
64
|
+
.option('exclude_paths', {
|
|
65
|
+
alias: 'exclude-paths',
|
|
66
|
+
type: 'array',
|
|
67
|
+
string: true,
|
|
68
|
+
default: [],
|
|
69
|
+
describe: 'Directories under app_home to skip when discovering **/*.backend.ts (repeat flag or comma-separated)'
|
|
70
|
+
})
|
|
71
|
+
.parseSync();
|
|
27
72
|
// Set default session duration (24 hours in milliseconds)
|
|
28
73
|
const DEFAULT_SESSION_DURATION = 86400000; // 24 hours in milliseconds
|
|
29
74
|
// Get session duration from environment variable or command line argument
|
|
@@ -65,8 +110,16 @@ if (argv.disable_vite === undefined) {
|
|
|
65
110
|
// Ensure the value is a boolean
|
|
66
111
|
argv.disable_vite = Boolean(argv.disable_vite);
|
|
67
112
|
const appHomePath = path_1.default.resolve(argv.app_home);
|
|
113
|
+
const excludePathsConfigured = dedupeStrings([
|
|
114
|
+
...normalizeExcludePaths(argv.exclude_paths),
|
|
115
|
+
...normalizeExcludePaths(process.env.FLIGHT_EXCLUDE_PATHS)
|
|
116
|
+
]);
|
|
117
|
+
const backendDiscoveryIgnores = backendDiscoveryIgnorePatterns(appHomePath, excludePathsConfigured);
|
|
68
118
|
process.chdir(appHomePath);
|
|
69
119
|
console.log(appHomePath);
|
|
120
|
+
if (backendDiscoveryIgnores.length > 0) {
|
|
121
|
+
console.log('Flight: excluding **/*.backend.ts discovery under:', backendDiscoveryIgnores.map((g) => g.replace(/\*\*$/, '')).join(', '));
|
|
122
|
+
}
|
|
70
123
|
const mode = process.env.FLIGHT_MODE || argv.mode || 'production';
|
|
71
124
|
/** Prefix without breaking printf-style logs (koa-logger uses `%s` as the first argument). */
|
|
72
125
|
const flightModeLabel = `Flight (${mode}):`;
|
|
@@ -115,7 +168,9 @@ else {
|
|
|
115
168
|
app.use((0, cors_1.default)()).use((0, koa_bodyparser_1.default)({
|
|
116
169
|
jsonLimit: argv.payload_limit
|
|
117
170
|
}));
|
|
118
|
-
const backEndFiles = fast_glob_1.default.sync('**/*.backend.ts'
|
|
171
|
+
const backEndFiles = fast_glob_1.default.sync('**/*.backend.ts', {
|
|
172
|
+
ignore: backendDiscoveryIgnores
|
|
173
|
+
});
|
|
119
174
|
backEndFiles.forEach((file) => {
|
|
120
175
|
const serverRoutes = require(path_1.default.resolve(file));
|
|
121
176
|
console.log('Found component backend file: ' + path_1.default.resolve(file));
|
package/package.json
CHANGED
package/src/flight.ts
CHANGED
|
@@ -29,13 +29,65 @@ interface FlightArgv {
|
|
|
29
29
|
payload_limit?: string
|
|
30
30
|
disable_vite?: boolean
|
|
31
31
|
mode?: string
|
|
32
|
+
exclude_paths?: string[]
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function normalizeExcludePaths(value: unknown): string[] {
|
|
36
|
+
if (value == null || value === '') return []
|
|
37
|
+
const parts = Array.isArray(value) ? value : [value]
|
|
38
|
+
const out: string[] = []
|
|
39
|
+
for (const p of parts) {
|
|
40
|
+
const s = String(p).trim()
|
|
41
|
+
if (!s) continue
|
|
42
|
+
out.push(
|
|
43
|
+
...s
|
|
44
|
+
.split(',')
|
|
45
|
+
.map((x) => x.trim())
|
|
46
|
+
.filter(Boolean)
|
|
47
|
+
)
|
|
48
|
+
}
|
|
49
|
+
return out
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function dedupeStrings(items: string[]): string[] {
|
|
53
|
+
return [...new Set(items)]
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** Build fast-glob ignore globs for trees rooted under `appRootAbs`. */
|
|
57
|
+
function backendDiscoveryIgnorePatterns(appRootAbs: string, excludeRelativeDirs: string[]): string[] {
|
|
58
|
+
const patterns: string[] = []
|
|
59
|
+
for (const raw of excludeRelativeDirs) {
|
|
60
|
+
const trimmed = raw.trim()
|
|
61
|
+
if (!trimmed) continue
|
|
62
|
+
const resolved = path.resolve(appRootAbs, trimmed)
|
|
63
|
+
const rel = path.relative(appRootAbs, resolved)
|
|
64
|
+
const relPosix = rel.replace(/\\/g, '/')
|
|
65
|
+
if (!relPosix || relPosix.startsWith('..') || path.isAbsolute(rel)) {
|
|
66
|
+
console.warn(`Flight: exclude_paths entry skipped (outside app_home): ${trimmed}`)
|
|
67
|
+
continue
|
|
68
|
+
}
|
|
69
|
+
patterns.push(`${relPosix}/**`)
|
|
70
|
+
}
|
|
71
|
+
return patterns
|
|
32
72
|
}
|
|
33
73
|
|
|
34
74
|
// tsx (and similar loaders) may expose require('yargs/yargs') as { default: factory } instead of factory.
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
75
|
+
interface YargsInstance {
|
|
76
|
+
option(key: string, opts: Record<string, unknown>): YargsInstance
|
|
77
|
+
parseSync(): FlightArgv
|
|
78
|
+
}
|
|
79
|
+
type YargsFn = (args: string[]) => YargsInstance
|
|
80
|
+
const _yargs = require('yargs/yargs') as YargsFn | { default: YargsFn }
|
|
81
|
+
const yargsEntry: YargsFn = typeof _yargs === 'function' ? _yargs : _yargs.default
|
|
82
|
+
const argv = yargsEntry(process.argv.slice(2))
|
|
83
|
+
.option('exclude_paths', {
|
|
84
|
+
alias: 'exclude-paths',
|
|
85
|
+
type: 'array',
|
|
86
|
+
string: true,
|
|
87
|
+
default: [],
|
|
88
|
+
describe: 'Directories under app_home to skip when discovering **/*.backend.ts (repeat flag or comma-separated)'
|
|
89
|
+
})
|
|
90
|
+
.parseSync() as FlightArgv
|
|
39
91
|
|
|
40
92
|
// Set default session duration (24 hours in milliseconds)
|
|
41
93
|
const DEFAULT_SESSION_DURATION = 86400000 // 24 hours in milliseconds
|
|
@@ -90,9 +142,21 @@ if (argv.disable_vite === undefined) {
|
|
|
90
142
|
argv.disable_vite = Boolean(argv.disable_vite)
|
|
91
143
|
|
|
92
144
|
const appHomePath = path.resolve(argv.app_home)
|
|
145
|
+
const excludePathsConfigured = dedupeStrings([
|
|
146
|
+
...normalizeExcludePaths(argv.exclude_paths),
|
|
147
|
+
...normalizeExcludePaths(process.env.FLIGHT_EXCLUDE_PATHS)
|
|
148
|
+
])
|
|
149
|
+
const backendDiscoveryIgnores = backendDiscoveryIgnorePatterns(appHomePath, excludePathsConfigured)
|
|
150
|
+
|
|
93
151
|
process.chdir(appHomePath)
|
|
94
152
|
|
|
95
153
|
console.log(appHomePath)
|
|
154
|
+
if (backendDiscoveryIgnores.length > 0) {
|
|
155
|
+
console.log(
|
|
156
|
+
'Flight: excluding **/*.backend.ts discovery under:',
|
|
157
|
+
backendDiscoveryIgnores.map((g) => g.replace(/\*\*$/, '')).join(', ')
|
|
158
|
+
)
|
|
159
|
+
}
|
|
96
160
|
|
|
97
161
|
const mode = process.env.FLIGHT_MODE || argv.mode || 'production'
|
|
98
162
|
|
|
@@ -152,7 +216,9 @@ if (cluster.isPrimary) {
|
|
|
152
216
|
})
|
|
153
217
|
)
|
|
154
218
|
|
|
155
|
-
const backEndFiles = fg.sync('**/*.backend.ts'
|
|
219
|
+
const backEndFiles = fg.sync('**/*.backend.ts', {
|
|
220
|
+
ignore: backendDiscoveryIgnores
|
|
221
|
+
})
|
|
156
222
|
backEndFiles.forEach((file) => {
|
|
157
223
|
const serverRoutes = require(path.resolve(file))
|
|
158
224
|
|