@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 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 yargsFactory = typeof _yargs === 'function' ? _yargs : _yargs.default;
26
- const argv = yargsFactory(process.argv.slice(2)).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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thoughtpivot/flight",
3
- "version": "1.0.8",
3
+ "version": "1.1.0",
4
4
  "description": "A web server designed for running full stack, component based applications at enterprise scale.",
5
5
  "main": "src/flight.ts",
6
6
  "publishConfig": {
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
- type YargsFactoryFn = (args: string[]) => { argv: FlightArgv }
36
- const _yargs = require('yargs/yargs') as YargsFactoryFn | { default: YargsFactoryFn }
37
- const yargsFactory: YargsFactoryFn = typeof _yargs === 'function' ? _yargs : _yargs.default
38
- const argv = yargsFactory(process.argv.slice(2)).argv
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