@luckystack/devkit 0.10.2 → 0.11.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/AGENTS.md +9 -0
- package/CHANGELOG.md +9 -0
- package/README.md +2 -37
- package/dist/cli/validateDeploy.d.ts +2 -0
- package/dist/functionRegistry.d.ts +72 -0
- package/dist/hotReload.d.ts +1 -0
- package/dist/importDependencyGraph.d.ts +2 -0
- package/dist/index.d.ts +15 -280
- package/dist/index.js +551 -424
- package/dist/index.js.map +1 -1
- package/dist/internal/mapUtils.d.ts +2 -0
- package/dist/loader.d.ts +11 -0
- package/dist/prismaClientCheck.d.ts +19 -0
- package/dist/routeConventions.d.ts +20 -0
- package/dist/routeNamingValidation.d.ts +46 -0
- package/dist/routingRules.d.ts +62 -0
- package/dist/runtimeTypeResolver.d.ts +15 -0
- package/dist/supervisor.d.ts +25 -0
- package/dist/templateInjector.d.ts +60 -0
- package/dist/templateRegistry.d.ts +78 -0
- package/dist/typeMap/apiMeta.d.ts +42 -0
- package/dist/typeMap/discovery.d.ts +3 -0
- package/dist/typeMap/emitterArtifacts.d.ts +94 -0
- package/dist/typeMap/extractionDiagnostics.d.ts +16 -0
- package/dist/typeMap/extractors.d.ts +18 -0
- package/dist/typeMap/functionsMeta.d.ts +5 -0
- package/dist/typeMap/routeMeta.d.ts +6 -0
- package/dist/typeMap/tsApi.d.ts +12 -0
- package/dist/typeMap/tsProgram.d.ts +41 -0
- package/dist/typeMap/typeContext.d.ts +21 -0
- package/dist/typeMap/zodEmitter.d.ts +8 -0
- package/dist/typeMapGenerator.d.ts +5 -0
- package/dist/validateDeploy.d.ts +25 -0
- package/docs/cli.md +3 -243
- package/docs/hot-reload.md +4 -362
- package/docs/loader-pipeline.md +3 -322
- package/docs/runtime-type-resolver.md +3 -256
- package/docs/supervisor.md +3 -290
- package/docs/template-customization.md +2 -133
- package/docs/ts-program-cache.md +4 -197
- package/docs/type-map-generation.md +5 -418
- package/package.json +5 -5
- package/CLAUDE.md +0 -135
package/AGENTS.md
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# @luckystack/devkit — agent guidance
|
|
2
|
+
|
|
3
|
+
Devkit is development/build tooling, not a production runtime dependency. Use it for type generation, live route reloads, template injection and deployment-config validation; do not import its watchers or TypeScript Program into production bundles. See `README.md` and the focused `docs/` pages for the architectural constraints.
|
|
4
|
+
|
|
5
|
+
Generated route contracts must preserve transport-safe types. A source file missed by the TypeScript Program deserves a visible diagnostic, not a silently permissive generated contract. Keep generated Zod validation and generated type-map contracts in agreement; do not turn unresolved symbols into invented fields. Development can degrade gracefully when a type cannot be resolved, but production relies on generated schemas and must not silently depend on a dev-only resolver.
|
|
6
|
+
|
|
7
|
+
The one deliberate diagnostics exception — an absent optional sync side — must stay scoped to that side's own field and run after the thrown-extraction check (ADR 0057). Server-backed sync routes share the API side's auth/rate-limit extractors and schema converter so the test-runner can sweep them (ADR 0064). See `docs/type-map-generation.md`.
|
|
8
|
+
|
|
9
|
+
Hot reload should not block serving live requests while building developer artifacts. Avoid invalidating the shared Program on initial population without cause; do invalidate when source changes. Consumer-owned template overrides intentionally outlive the installed devkit's bundled defaults; do not overwrite them on upgrade.
|
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,15 @@ All notable changes to `@luckystack/devkit` are documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.11.0] - 2026-10-14
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- Devkit now analyses routes with the TypeScript 7 compiler API instead of the TypeScript 5/6 JavaScript compiler. It depends on an exact-pinned TypeScript 7.1 dev build through the `typescript-7-api` alias, so it no longer needs a `typescript` peer dependency. Your project's own `typescript` version no longer affects devkit. The compiler runs as a separate native process: one per generation run, stopped when the run ends. Type generation is faster and uses about a third of the memory: in this repository the generator's peak memory fell from about 780 MB to about 270 MB.
|
|
13
|
+
- Type declarations are emitted per source file by TypeScript 7 (`tsc -b`) instead of one bundled `.d.ts` per entry, so the framework build no longer runs package by package. The exported types are unchanged; relative imports inside the declarations carry `.js`, so `moduleResolution: "node16"`/`"nodenext"` projects resolve them as before.
|
|
14
|
+
- Generated route types (`apiTypes.generated.ts`, the input schemas and the docs JSON) now list union members and object properties in TypeScript 7's stable order. The types themselves are unchanged, but expect a one-time reordering diff in generated files after upgrading.
|
|
15
|
+
- Package design guidance now ships as `AGENTS.md`, not `CLAUDE.md`. Handwritten docs focus on rationale and safety; exact API contracts remain in installed declarations/source.
|
|
16
|
+
|
|
8
17
|
## [0.10.2] - 2026-10-09
|
|
9
18
|
|
|
10
19
|
### Added
|
package/README.md
CHANGED
|
@@ -1,44 +1,9 @@
|
|
|
1
1
|
# @luckystack/devkit
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
## Install
|
|
3
|
+
Development-time tooling for LuckyStack route loading, type-map generation, template injection, hot reload, and deployment validation. Install as a development dependency:
|
|
6
4
|
|
|
7
5
|
```bash
|
|
8
6
|
npm install --save-dev @luckystack/devkit
|
|
9
7
|
```
|
|
10
8
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
## CLIs
|
|
14
|
-
|
|
15
|
-
| Bin | What |
|
|
16
|
-
| --- | --- |
|
|
17
|
-
| `luckystack-validate-deploy` | Reads compiled `deploy.config.js` + `services.config.js` and asserts every service is bound, every preset references real services, env keys resolve. Exits non-zero on errors; `--strict` also fails on warnings. |
|
|
18
|
-
|
|
19
|
-
## What it exports
|
|
20
|
-
|
|
21
|
-
| Group | Exports |
|
|
22
|
-
| --- | --- |
|
|
23
|
-
| Type generation | `generateTypeMapFile`, `getInputTypeFromFile`, `getSyncClientDataType` |
|
|
24
|
-
| Route conventions | `API_VERSION_TOKEN_REGEX`, `SYNC_VERSION_TOKEN_REGEX`, `assertNoDuplicateNormalizedRouteKeys`, `assertValidRouteNaming` |
|
|
25
|
-
| Routing rules registry | `registerRoutingRules`, `getRoutingRules`, `apiMarkerSegment`, `syncMarkerSegment`, `isApiFileName`, `isSyncFileName`, `isSyncServerFileName`, `isSyncClientFileName`. Type: `RoutingRules` |
|
|
26
|
-
| Dev runtime loaders | `devApis`, `devSyncs`, `devFunctions`, `initializeAll`, `initializeApis`, `initializeSyncs`, `initializeFunctions`, `upsertApiFromFile`, `removeApiFromFile`, `upsertSyncFromFile`, `removeSyncFromFile` |
|
|
27
|
-
| Hot reload | `setupWatchers` |
|
|
28
|
-
| Deep type resolver | `resolveRuntimeTypeText`, `clearRuntimeTypeResolverCache` (lazy-imported by `@luckystack/core`'s runtime validator in dev) |
|
|
29
|
-
|
|
30
|
-
## Consumed by
|
|
31
|
-
|
|
32
|
-
- `scripts/generate*.ts` — type-map + Zod schema emitters.
|
|
33
|
-
- `server/dev/setupWatchers.ts` (this repo's own dev server) — hot reload.
|
|
34
|
-
- `server/prod/runtimeMaps.ts` — when `NODE_ENV !== 'production'`, loads `devApis` / `devSyncs` for live route resolution.
|
|
35
|
-
- `@luckystack/core/src/runtimeTypeValidation.ts` — dev-only deep alias resolution.
|
|
36
|
-
|
|
37
|
-
## Related architecture docs
|
|
38
|
-
|
|
39
|
-
- [`docs/ARCHITECTURE_ROUTING.md`](../../docs/ARCHITECTURE_ROUTING.md) — file conventions + version token rules.
|
|
40
|
-
- [`docs/ARCHITECTURE_PACKAGING.md`](../../docs/ARCHITECTURE_PACKAGING.md) — generated artifact layout per preset.
|
|
41
|
-
|
|
42
|
-
## License
|
|
43
|
-
|
|
44
|
-
MIT — see [LICENSE](../../LICENSE).
|
|
9
|
+
Do not import devkit watchers or the TypeScript Program in production code. Production reads generated route artifacts instead of recompiling or watching sources. The focused [`docs/`](./docs/) explain why live reload stays off the request path, why type generation reports unresolved types, and why consumer template overrides are retained across upgrades. Use the installed exports and CLI `--help` for current API and invocation details.
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
export interface FunctionModule {
|
|
2
|
+
/**
|
|
3
|
+
* Key path under the injected `functions` object. `shared/rbac/engine.ts`
|
|
4
|
+
* with root `shared` yields `['rbac', 'engine']`, reachable as
|
|
5
|
+
* `functions.rbac.engine`.
|
|
6
|
+
*/
|
|
7
|
+
keyPath: string[];
|
|
8
|
+
/** Workspace-relative, forward-slash path to the source file (with `.ts`). */
|
|
9
|
+
sourcePath: string;
|
|
10
|
+
/** Workspace-relative, forward-slash root directory that claimed this key path. */
|
|
11
|
+
rootPath: string;
|
|
12
|
+
}
|
|
13
|
+
/** Dotted rendering of a key path, e.g. `rbac.engine`. */
|
|
14
|
+
export declare const formatFunctionKeyPath: (keyPath: string[]) => string;
|
|
15
|
+
/**
|
|
16
|
+
* Last segment of a key path — the module's file name, which is also the alias
|
|
17
|
+
* a default-only export is published under (`functions.sleep.sleep`).
|
|
18
|
+
*
|
|
19
|
+
* Discovery never produces an empty key path; the guard exists so the callers
|
|
20
|
+
* get a real string instead of threading `string | undefined` through every
|
|
21
|
+
* emitter.
|
|
22
|
+
*/
|
|
23
|
+
export declare const functionModuleFileName: (keyPath: string[]) => string;
|
|
24
|
+
export declare const formatFunctionKeyConflict: (keyPath: string[], firstSourcePath: string, secondSourcePath: string) => string;
|
|
25
|
+
export declare const formatFunctionNamespaceConflict: (moduleKeyPath: string[], moduleSourcePath: string, nestedKeyPath: string[], nestedSourcePath: string) => string;
|
|
26
|
+
export interface CollectFunctionModulesOptions {
|
|
27
|
+
/**
|
|
28
|
+
* Override the configured roots (absolute paths). Tests pass this;
|
|
29
|
+
* production callers omit it and get `getServerFunctionDirs()`.
|
|
30
|
+
*/
|
|
31
|
+
roots?: string[];
|
|
32
|
+
/**
|
|
33
|
+
* When provided, a collision REPORTS through this callback and the offending
|
|
34
|
+
* module is skipped instead of throwing. The dev loader passes it so a
|
|
35
|
+
* duplicate does not hard-crash a running dev server; the build-time
|
|
36
|
+
* generators omit it so the same duplicate fails the build loudly.
|
|
37
|
+
*/
|
|
38
|
+
onConflict?: (message: string) => void;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Discover every server function module across the configured
|
|
42
|
+
* `paths.serverFunctionDirs` roots (default `['functions', 'shared']`), in
|
|
43
|
+
* config order, and derive its `functions.*` key path from its location
|
|
44
|
+
* relative to the root that owns it.
|
|
45
|
+
*
|
|
46
|
+
* Throws on a cross-root key collision or a module/namespace collision (unless
|
|
47
|
+
* `onConflict` is supplied), so a broken registry fails the BUILD instead of
|
|
48
|
+
* producing a map that is silently missing entries at runtime.
|
|
49
|
+
*/
|
|
50
|
+
export declare const collectFunctionModules: (options?: CollectFunctionModulesOptions) => FunctionModule[];
|
|
51
|
+
export interface RenderedFunctionsMap {
|
|
52
|
+
/** `import * as fn0 from '...'` lines, in emission order. */
|
|
53
|
+
imports: string[];
|
|
54
|
+
/** The full `export const functions = { ... };` declaration. */
|
|
55
|
+
source: string;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Render discovered modules into the `functions` export of a generated
|
|
59
|
+
* production runtime-map file. The emitted object is NESTED, matching what the
|
|
60
|
+
* dev loader builds and what `apiTypes.generated.ts` declares.
|
|
61
|
+
*
|
|
62
|
+
* @param modules Output of {@link collectFunctionModules}.
|
|
63
|
+
* @param importPrefix Prefix that turns a workspace-relative source path into a
|
|
64
|
+
* specifier relative to the generated file (`'../../'` for
|
|
65
|
+
* the standard `server/prod/` output location).
|
|
66
|
+
* @param varPrefix Import alias prefix; aliases are `<varPrefix><n>`.
|
|
67
|
+
*/
|
|
68
|
+
export declare const renderFunctionsMap: ({ modules, importPrefix, varPrefix, }: {
|
|
69
|
+
modules: FunctionModule[];
|
|
70
|
+
importPrefix: string;
|
|
71
|
+
varPrefix?: string;
|
|
72
|
+
}) => RenderedFunctionsMap;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const setupWatchers: () => void;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,280 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
context: string;
|
|
17
|
-
}) => void;
|
|
18
|
-
declare const assertNoDuplicateNormalizedRouteKeys: ({ srcDir, context, }: {
|
|
19
|
-
srcDir: string;
|
|
20
|
-
context: string;
|
|
21
|
-
}) => void;
|
|
22
|
-
|
|
23
|
-
interface FunctionModule {
|
|
24
|
-
/**
|
|
25
|
-
* Key path under the injected `functions` object. `shared/rbac/engine.ts`
|
|
26
|
-
* with root `shared` yields `['rbac', 'engine']`, reachable as
|
|
27
|
-
* `functions.rbac.engine`.
|
|
28
|
-
*/
|
|
29
|
-
keyPath: string[];
|
|
30
|
-
/** Workspace-relative, forward-slash path to the source file (with `.ts`). */
|
|
31
|
-
sourcePath: string;
|
|
32
|
-
/** Workspace-relative, forward-slash root directory that claimed this key path. */
|
|
33
|
-
rootPath: string;
|
|
34
|
-
}
|
|
35
|
-
/** Dotted rendering of a key path, e.g. `rbac.engine`. */
|
|
36
|
-
declare const formatFunctionKeyPath: (keyPath: string[]) => string;
|
|
37
|
-
/**
|
|
38
|
-
* Last segment of a key path — the module's file name, which is also the alias
|
|
39
|
-
* a default-only export is published under (`functions.sleep.sleep`).
|
|
40
|
-
*
|
|
41
|
-
* Discovery never produces an empty key path; the guard exists so the callers
|
|
42
|
-
* get a real string instead of threading `string | undefined` through every
|
|
43
|
-
* emitter.
|
|
44
|
-
*/
|
|
45
|
-
declare const functionModuleFileName: (keyPath: string[]) => string;
|
|
46
|
-
declare const formatFunctionKeyConflict: (keyPath: string[], firstSourcePath: string, secondSourcePath: string) => string;
|
|
47
|
-
declare const formatFunctionNamespaceConflict: (moduleKeyPath: string[], moduleSourcePath: string, nestedKeyPath: string[], nestedSourcePath: string) => string;
|
|
48
|
-
interface CollectFunctionModulesOptions {
|
|
49
|
-
/**
|
|
50
|
-
* Override the configured roots (absolute paths). Tests pass this;
|
|
51
|
-
* production callers omit it and get `getServerFunctionDirs()`.
|
|
52
|
-
*/
|
|
53
|
-
roots?: string[];
|
|
54
|
-
/**
|
|
55
|
-
* When provided, a collision REPORTS through this callback and the offending
|
|
56
|
-
* module is skipped instead of throwing. The dev loader passes it so a
|
|
57
|
-
* duplicate does not hard-crash a running dev server; the build-time
|
|
58
|
-
* generators omit it so the same duplicate fails the build loudly.
|
|
59
|
-
*/
|
|
60
|
-
onConflict?: (message: string) => void;
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Discover every server function module across the configured
|
|
64
|
-
* `paths.serverFunctionDirs` roots (default `['functions', 'shared']`), in
|
|
65
|
-
* config order, and derive its `functions.*` key path from its location
|
|
66
|
-
* relative to the root that owns it.
|
|
67
|
-
*
|
|
68
|
-
* Throws on a cross-root key collision or a module/namespace collision (unless
|
|
69
|
-
* `onConflict` is supplied), so a broken registry fails the BUILD instead of
|
|
70
|
-
* producing a map that is silently missing entries at runtime.
|
|
71
|
-
*/
|
|
72
|
-
declare const collectFunctionModules: (options?: CollectFunctionModulesOptions) => FunctionModule[];
|
|
73
|
-
interface RenderedFunctionsMap {
|
|
74
|
-
/** `import * as fn0 from '...'` lines, in emission order. */
|
|
75
|
-
imports: string[];
|
|
76
|
-
/** The full `export const functions = { ... };` declaration. */
|
|
77
|
-
source: string;
|
|
78
|
-
}
|
|
79
|
-
/**
|
|
80
|
-
* Render discovered modules into the `functions` export of a generated
|
|
81
|
-
* production runtime-map file. The emitted object is NESTED, matching what the
|
|
82
|
-
* dev loader builds and what `apiTypes.generated.ts` declares.
|
|
83
|
-
*
|
|
84
|
-
* @param modules Output of {@link collectFunctionModules}.
|
|
85
|
-
* @param importPrefix Prefix that turns a workspace-relative source path into a
|
|
86
|
-
* specifier relative to the generated file (`'../../'` for
|
|
87
|
-
* the standard `server/prod/` output location).
|
|
88
|
-
* @param varPrefix Import alias prefix; aliases are `<varPrefix><n>`.
|
|
89
|
-
*/
|
|
90
|
-
declare const renderFunctionsMap: ({ modules, importPrefix, varPrefix, }: {
|
|
91
|
-
modules: FunctionModule[];
|
|
92
|
-
importPrefix: string;
|
|
93
|
-
varPrefix?: string;
|
|
94
|
-
}) => RenderedFunctionsMap;
|
|
95
|
-
|
|
96
|
-
interface RoutingRules {
|
|
97
|
-
/** Folder name that marks an API directory. Default: `_api`. */
|
|
98
|
-
apiMarker: string;
|
|
99
|
-
/** Folder name that marks a sync directory. Default: `_sync`. */
|
|
100
|
-
syncMarker: string;
|
|
101
|
-
/** Suffix matcher for API files: must end with `_v<number>.ts`. */
|
|
102
|
-
apiVersionRegex: RegExp;
|
|
103
|
-
/** Suffix matcher for sync server files: must end with `_server_v<number>.ts`. */
|
|
104
|
-
syncServerVersionRegex: RegExp;
|
|
105
|
-
/** Suffix matcher for sync client files: must end with `_client_v<number>.ts`. */
|
|
106
|
-
syncClientVersionRegex: RegExp;
|
|
107
|
-
/** Combined sync regex (server or client). */
|
|
108
|
-
syncVersionRegex: RegExp;
|
|
109
|
-
/**
|
|
110
|
-
* Predicate called for each candidate file/folder during discovery.
|
|
111
|
-
* Return `true` to skip. Path is provided as a forward-slash relative
|
|
112
|
-
* string from the workspace root (e.g. `src/dashboard/__tests__/foo_v1.ts`).
|
|
113
|
-
*/
|
|
114
|
-
ignore: (relativePath: string) => boolean;
|
|
115
|
-
/**
|
|
116
|
-
* Single-character prefix that marks a folder as **invisible-parent** for
|
|
117
|
-
* page routing: `src/_housing/renting/page.tsx` resolves to `/renting`
|
|
118
|
-
* (the `_housing` segment is stripped from the URL). A `page.tsx` placed
|
|
119
|
-
* directly inside an `_<name>` folder is invalid (no URL segment left).
|
|
120
|
-
*
|
|
121
|
-
* Default: `'_'`. Override only if you need a different prefix scheme.
|
|
122
|
-
*/
|
|
123
|
-
privateFolderPrefix: string;
|
|
124
|
-
/**
|
|
125
|
-
* Folder names that are reserved for framework-internal use and may NEVER
|
|
126
|
-
* host a `page.tsx`. Scaffold + page-discovery emit a hard error when a
|
|
127
|
-
* page is placed inside one. Extend (do not replace) the defaults if you
|
|
128
|
-
* add your own internal folder convention.
|
|
129
|
-
*
|
|
130
|
-
* Defaults: `_api`, `_sync`, `_function(s)`, `_component(s)`, `_provider(s)`,
|
|
131
|
-
* `_locale(s)`, `_socket(s)`, `_shared`, `_server`. The semantic markers
|
|
132
|
-
* (`_api`, `_sync`) are also reserved by the API/sync routers.
|
|
133
|
-
*/
|
|
134
|
-
scaffoldIgnoredFolders: string[];
|
|
135
|
-
/**
|
|
136
|
-
* Optional predicate. Return `true` for a given absolute file path to
|
|
137
|
-
* disable template injection entirely for that file. Useful when a
|
|
138
|
-
* consumer wants to opt some part of the tree out of the scaffold
|
|
139
|
-
* (e.g. `/src/migrations/**` lives by hand). The argument is the
|
|
140
|
-
* absolute path the chokidar watcher provides; the predicate is
|
|
141
|
-
* called BEFORE the `isInApiFolder` / `isPageFile` checks fire.
|
|
142
|
-
*/
|
|
143
|
-
disableTemplateInjection?: (filePath: string) => boolean;
|
|
144
|
-
}
|
|
145
|
-
declare const registerRoutingRules: (overrides: Partial<RoutingRules>) => RoutingRules;
|
|
146
|
-
declare const getRoutingRules: () => RoutingRules;
|
|
147
|
-
declare const apiMarkerSegment: () => string;
|
|
148
|
-
declare const syncMarkerSegment: () => string;
|
|
149
|
-
declare const isApiFileName: (fileName: string) => boolean;
|
|
150
|
-
declare const isSyncServerFileName: (fileName: string) => boolean;
|
|
151
|
-
declare const isSyncClientFileName: (fileName: string) => boolean;
|
|
152
|
-
declare const isSyncFileName: (fileName: string) => boolean;
|
|
153
|
-
|
|
154
|
-
/**
|
|
155
|
-
* The six template kinds the framework ships out of the box. Consumers may
|
|
156
|
-
* register additional kinds (e.g. `page_marketing`) via `registerTemplateKind`.
|
|
157
|
-
*/
|
|
158
|
-
type BuiltInTemplateKind = 'api' | 'sync_server' | 'sync_client_paired' | 'sync_client_standalone' | 'page_plain' | 'page_dashboard';
|
|
159
|
-
type TemplateKind = BuiltInTemplateKind | (string & {});
|
|
160
|
-
declare const BUILT_IN_TEMPLATE_KINDS: readonly BuiltInTemplateKind[];
|
|
161
|
-
declare const BUILT_IN_TEMPLATE_FILENAMES: Record<BuiltInTemplateKind, string>;
|
|
162
|
-
/**
|
|
163
|
-
* Structural classification of the file an injection is being computed for.
|
|
164
|
-
* `templateInjector.ts` derives this from the folder + filename conventions
|
|
165
|
-
* (controlled separately via `registerRoutingRules`). Selection rules match
|
|
166
|
-
* against it to choose a template kind.
|
|
167
|
-
*/
|
|
168
|
-
interface TemplateMatchContext {
|
|
169
|
-
/** Absolute path of the file being created. */
|
|
170
|
-
filePath: string;
|
|
171
|
-
/** Structural kind derived from the route conventions. */
|
|
172
|
-
fileKind: 'api' | 'sync_server' | 'sync_client' | 'page';
|
|
173
|
-
/** For `sync_client`: whether a paired `_server_v<N>.ts` exists on disk. */
|
|
174
|
-
hasPairedServer: boolean;
|
|
175
|
-
/** Path relative to `src/` (forward slashes), or `null` if outside src. */
|
|
176
|
-
srcRelativePath: string | null;
|
|
177
|
-
}
|
|
178
|
-
/** A single template-selection rule. First matching rule (by priority) wins. */
|
|
179
|
-
interface TemplateRule {
|
|
180
|
-
kind: TemplateKind;
|
|
181
|
-
match: (ctx: TemplateMatchContext) => boolean;
|
|
182
|
-
/** Higher runs first. Built-in defaults use 10 (specific) / 0 (catch-all). */
|
|
183
|
-
priority: number;
|
|
184
|
-
}
|
|
185
|
-
interface RegisterTemplateKindOptions {
|
|
186
|
-
/** Predicate deciding when this kind is chosen. */
|
|
187
|
-
match: (ctx: TemplateMatchContext) => boolean;
|
|
188
|
-
/** Optional inline template body (same as calling `registerTemplate`). */
|
|
189
|
-
content?: string;
|
|
190
|
-
/** Higher runs first. Defaults to 100 so consumer kinds beat the built-ins. */
|
|
191
|
-
priority?: number;
|
|
192
|
-
}
|
|
193
|
-
declare const DEFAULT_DASHBOARD_PATH_PATTERN: RegExp;
|
|
194
|
-
/**
|
|
195
|
-
* Override the template body for a given kind. Subsequent injections emit the
|
|
196
|
-
* supplied content with the standard `{{REL_PATH}}` / `{{PAGE_PATH}}` /
|
|
197
|
-
* `{{SYNC_NAME}}` placeholder substitution. Resolution order in the injector
|
|
198
|
-
* is: consumer file (`.luckystack/templates/<kind>.template.*`) → this
|
|
199
|
-
* override → bundled disk template.
|
|
200
|
-
*/
|
|
201
|
-
declare const registerTemplate: (kind: TemplateKind, content: string) => void;
|
|
202
|
-
/** Read the registered content override for a kind, or `null` when none. */
|
|
203
|
-
declare const getRegisteredTemplate: (kind: TemplateKind) => string | null;
|
|
204
|
-
/** Drop every content override. Test-only. */
|
|
205
|
-
declare const clearTemplateOverrides: () => void;
|
|
206
|
-
/** Diagnostic: kinds that currently have a content override. */
|
|
207
|
-
declare const listRegisteredTemplateKinds: () => readonly TemplateKind[];
|
|
208
|
-
/**
|
|
209
|
-
* Register a selection rule. Rules are evaluated by descending `priority`,
|
|
210
|
-
* ties broken by descending registration order (so a later registration —
|
|
211
|
-
* e.g. a consumer overlay — beats an earlier same-priority default).
|
|
212
|
-
*/
|
|
213
|
-
declare const registerTemplateRule: (rule: TemplateRule) => void;
|
|
214
|
-
/**
|
|
215
|
-
* Register a brand-new template kind: its selection predicate plus (optionally)
|
|
216
|
-
* its inline content. Equivalent to `registerTemplateRule` + `registerTemplate`
|
|
217
|
-
* in one call. Default priority 100 so custom kinds win over the built-ins.
|
|
218
|
-
*/
|
|
219
|
-
declare const registerTemplateKind: (kind: TemplateKind, options: RegisterTemplateKindOptions) => void;
|
|
220
|
-
/** Drop every selection rule (including the built-in defaults). */
|
|
221
|
-
declare const clearTemplateRules: () => void;
|
|
222
|
-
/** Read the active rules in evaluation order (priority desc, then newest first). */
|
|
223
|
-
declare const getTemplateRules: () => readonly TemplateRule[];
|
|
224
|
-
/** Evaluate the active rules against a context; returns the first matching kind. */
|
|
225
|
-
declare const resolveTemplateKind: (ctx: TemplateMatchContext) => TemplateKind | null;
|
|
226
|
-
declare const registerDefaultTemplateRules: () => void;
|
|
227
|
-
|
|
228
|
-
declare const devApis: Record<string, unknown>;
|
|
229
|
-
declare const devSyncs: Record<string, unknown>;
|
|
230
|
-
declare const devFunctions: Record<string, unknown>;
|
|
231
|
-
declare const initializeAll: () => Promise<void>;
|
|
232
|
-
declare const initializeApis: () => Promise<void>;
|
|
233
|
-
declare const upsertApiFromFile: (filePath: string) => Promise<void>;
|
|
234
|
-
declare const removeApiFromFile: (filePath: string) => void;
|
|
235
|
-
declare const initializeSyncs: () => Promise<void>;
|
|
236
|
-
declare const upsertSyncFromFile: (filePath: string) => Promise<void>;
|
|
237
|
-
declare const removeSyncFromFile: (filePath: string) => void;
|
|
238
|
-
declare const initializeFunctions: () => Promise<void>;
|
|
239
|
-
|
|
240
|
-
declare const setupWatchers: () => void;
|
|
241
|
-
|
|
242
|
-
type ResolveResult = {
|
|
243
|
-
status: 'success';
|
|
244
|
-
typeText: string;
|
|
245
|
-
} | {
|
|
246
|
-
status: 'error';
|
|
247
|
-
message: string;
|
|
248
|
-
};
|
|
249
|
-
declare const clearRuntimeTypeResolverCache: () => void;
|
|
250
|
-
declare const resolveRuntimeTypeText: ({ typeText, filePath, }: {
|
|
251
|
-
typeText: string;
|
|
252
|
-
filePath?: string;
|
|
253
|
-
}) => ResolveResult;
|
|
254
|
-
|
|
255
|
-
type ValidationSeverity = 'error' | 'warning';
|
|
256
|
-
interface ValidationFinding {
|
|
257
|
-
severity: ValidationSeverity;
|
|
258
|
-
code: string;
|
|
259
|
-
message: string;
|
|
260
|
-
/** Human-readable location pointer (e.g. `services.config.ts > presets.api`). */
|
|
261
|
-
location?: string;
|
|
262
|
-
}
|
|
263
|
-
interface ValidateDeployInput {
|
|
264
|
-
services: ServicesConfigShape;
|
|
265
|
-
deploy: DeployConfigShape;
|
|
266
|
-
/**
|
|
267
|
-
* Environment values to consult for `synchronizedEnvKeys` / `urlEnvKey`
|
|
268
|
-
* presence checks. Defaults to `process.env`. Pass a fixture for tests.
|
|
269
|
-
*/
|
|
270
|
-
env?: Record<string, string | undefined>;
|
|
271
|
-
}
|
|
272
|
-
interface ValidateDeployResult {
|
|
273
|
-
ok: boolean;
|
|
274
|
-
findings: ValidationFinding[];
|
|
275
|
-
errorCount: number;
|
|
276
|
-
warningCount: number;
|
|
277
|
-
}
|
|
278
|
-
declare const validateDeploy: ({ services, deploy, env, }: ValidateDeployInput) => ValidateDeployResult;
|
|
279
|
-
|
|
280
|
-
export { API_VERSION_TOKEN_REGEX, BUILT_IN_TEMPLATE_FILENAMES, BUILT_IN_TEMPLATE_KINDS, type BuiltInTemplateKind, type CollectFunctionModulesOptions, DEFAULT_DASHBOARD_PATH_PATTERN, type FunctionModule, type RegisterTemplateKindOptions, type RenderedFunctionsMap, type RoutingRules, SYNC_VERSION_TOKEN_REGEX, type TemplateKind, type TemplateMatchContext, type TemplateRule, type ValidateDeployInput, type ValidateDeployResult, type ValidationFinding, type ValidationSeverity, apiMarkerSegment, assertNoDuplicateNormalizedRouteKeys, assertValidRouteNaming, clearRuntimeTypeResolverCache, clearTemplateOverrides, clearTemplateRules, collectFunctionModules, devApis, devFunctions, devSyncs, formatFunctionKeyConflict, formatFunctionKeyPath, formatFunctionNamespaceConflict, functionModuleFileName, generateTypeMapFile, getInputTypeFromFile, getRegisteredTemplate, getRoutingRules, getSyncClientDataType, getTemplateRules, initializeAll, initializeApis, initializeFunctions, initializeSyncs, isApiFileName, isSyncClientFileName, isSyncFileName, isSyncServerFileName, listRegisteredTemplateKinds, registerDefaultTemplateRules, registerRoutingRules, registerTemplate, registerTemplateKind, registerTemplateRule, removeApiFromFile, removeSyncFromFile, renderFunctionsMap, resolveRuntimeTypeText, resolveTemplateKind, setupWatchers, syncMarkerSegment, upsertApiFromFile, upsertSyncFromFile, validateDeploy };
|
|
1
|
+
export { generateTypeMapFile } from './typeMapGenerator.js';
|
|
2
|
+
export { getInputTypeFromFile, getSyncClientDataType, } from './typeMap/extractors.js';
|
|
3
|
+
export { API_VERSION_TOKEN_REGEX, SYNC_VERSION_TOKEN_REGEX, } from './routeConventions.js';
|
|
4
|
+
export { assertNoDuplicateNormalizedRouteKeys, assertValidRouteNaming, } from './routeNamingValidation.js';
|
|
5
|
+
export { collectFunctionModules, renderFunctionsMap, formatFunctionKeyPath, functionModuleFileName, formatFunctionKeyConflict, formatFunctionNamespaceConflict, } from './functionRegistry.js';
|
|
6
|
+
export type { FunctionModule, RenderedFunctionsMap, CollectFunctionModulesOptions, } from './functionRegistry.js';
|
|
7
|
+
export { registerRoutingRules, getRoutingRules, apiMarkerSegment, syncMarkerSegment, isApiFileName, isSyncFileName, isSyncServerFileName, isSyncClientFileName, } from './routingRules.js';
|
|
8
|
+
export type { RoutingRules } from './routingRules.js';
|
|
9
|
+
export { registerTemplate, getRegisteredTemplate, clearTemplateOverrides, listRegisteredTemplateKinds, registerTemplateRule, registerTemplateKind, clearTemplateRules, getTemplateRules, resolveTemplateKind, registerDefaultTemplateRules, BUILT_IN_TEMPLATE_KINDS, BUILT_IN_TEMPLATE_FILENAMES, DEFAULT_DASHBOARD_PATH_PATTERN, } from './templateRegistry.js';
|
|
10
|
+
export type { TemplateKind, BuiltInTemplateKind, TemplateRule, TemplateMatchContext, RegisterTemplateKindOptions, } from './templateRegistry.js';
|
|
11
|
+
export { devApis, devSyncs, devFunctions, initializeAll, initializeApis, initializeSyncs, initializeFunctions, upsertApiFromFile, removeApiFromFile, upsertSyncFromFile, removeSyncFromFile, } from './loader.js';
|
|
12
|
+
export { setupWatchers } from './hotReload.js';
|
|
13
|
+
export { resolveRuntimeTypeText, clearRuntimeTypeResolverCache } from './runtimeTypeResolver.js';
|
|
14
|
+
export { validateDeploy } from './validateDeploy.js';
|
|
15
|
+
export type { ValidateDeployInput, ValidateDeployResult, ValidationFinding, ValidationSeverity, } from './validateDeploy.js';
|