@luckystack/devkit 0.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.
@@ -0,0 +1,207 @@
1
+ import { ServicesConfigShape, DeployConfigShape } from '@luckystack/core';
2
+
3
+ interface GenerateTypeMapOptions {
4
+ quiet?: boolean;
5
+ }
6
+ declare const generateTypeMapFile: (options?: GenerateTypeMapOptions) => void;
7
+
8
+ declare const getInputTypeFromFile: (filePath: string) => string;
9
+ declare const getSyncClientDataType: (filePath: string) => string;
10
+
11
+ declare const API_VERSION_TOKEN_REGEX: RegExp;
12
+ declare const SYNC_VERSION_TOKEN_REGEX: RegExp;
13
+
14
+ declare const assertValidRouteNaming: ({ srcDir, context, }: {
15
+ srcDir: string;
16
+ context: string;
17
+ }) => void;
18
+ declare const assertNoDuplicateNormalizedRouteKeys: ({ srcDir, context, }: {
19
+ srcDir: string;
20
+ context: string;
21
+ }) => void;
22
+
23
+ interface RoutingRules {
24
+ /** Folder name that marks an API directory. Default: `_api`. */
25
+ apiMarker: string;
26
+ /** Folder name that marks a sync directory. Default: `_sync`. */
27
+ syncMarker: string;
28
+ /** Suffix matcher for API files: must end with `_v<number>.ts`. */
29
+ apiVersionRegex: RegExp;
30
+ /** Suffix matcher for sync server files: must end with `_server_v<number>.ts`. */
31
+ syncServerVersionRegex: RegExp;
32
+ /** Suffix matcher for sync client files: must end with `_client_v<number>.ts`. */
33
+ syncClientVersionRegex: RegExp;
34
+ /** Combined sync regex (server or client). */
35
+ syncVersionRegex: RegExp;
36
+ /**
37
+ * Predicate called for each candidate file/folder during discovery.
38
+ * Return `true` to skip. Path is provided as a forward-slash relative
39
+ * string from the workspace root (e.g. `src/dashboard/__tests__/foo_v1.ts`).
40
+ */
41
+ ignore: (relativePath: string) => boolean;
42
+ /**
43
+ * Single-character prefix that marks a folder as **invisible-parent** for
44
+ * page routing: `src/_housing/renting/page.tsx` resolves to `/renting`
45
+ * (the `_housing` segment is stripped from the URL). A `page.tsx` placed
46
+ * directly inside an `_<name>` folder is invalid (no URL segment left).
47
+ *
48
+ * Default: `'_'`. Override only if you need a different prefix scheme.
49
+ */
50
+ privateFolderPrefix: string;
51
+ /**
52
+ * Folder names that are reserved for framework-internal use and may NEVER
53
+ * host a `page.tsx`. Scaffold + page-discovery emit a hard error when a
54
+ * page is placed inside one. Extend (do not replace) the defaults if you
55
+ * add your own internal folder convention.
56
+ *
57
+ * Defaults: `_api`, `_sync`, `_function(s)`, `_component(s)`, `_provider(s)`,
58
+ * `_locale(s)`, `_socket(s)`, `_shared`, `_server`. The semantic markers
59
+ * (`_api`, `_sync`) are also reserved by the API/sync routers.
60
+ */
61
+ scaffoldIgnoredFolders: string[];
62
+ /**
63
+ * Optional predicate. Return `true` for a given absolute file path to
64
+ * disable template injection entirely for that file. Useful when a
65
+ * consumer wants to opt some part of the tree out of the scaffold
66
+ * (e.g. `/src/migrations/**` lives by hand). The argument is the
67
+ * absolute path the chokidar watcher provides; the predicate is
68
+ * called BEFORE the `isInApiFolder` / `isPageFile` checks fire.
69
+ */
70
+ disableTemplateInjection?: (filePath: string) => boolean;
71
+ }
72
+ declare const registerRoutingRules: (overrides: Partial<RoutingRules>) => RoutingRules;
73
+ declare const getRoutingRules: () => RoutingRules;
74
+ declare const apiMarkerSegment: () => string;
75
+ declare const syncMarkerSegment: () => string;
76
+ declare const isApiFileName: (fileName: string) => boolean;
77
+ declare const isSyncServerFileName: (fileName: string) => boolean;
78
+ declare const isSyncClientFileName: (fileName: string) => boolean;
79
+ declare const isSyncFileName: (fileName: string) => boolean;
80
+
81
+ /**
82
+ * The six template kinds the framework ships out of the box. Consumers may
83
+ * register additional kinds (e.g. `page_marketing`) via `registerTemplateKind`.
84
+ */
85
+ type BuiltInTemplateKind = 'api' | 'sync_server' | 'sync_client_paired' | 'sync_client_standalone' | 'page_plain' | 'page_dashboard';
86
+ type TemplateKind = BuiltInTemplateKind | (string & {});
87
+ declare const BUILT_IN_TEMPLATE_KINDS: readonly BuiltInTemplateKind[];
88
+ declare const BUILT_IN_TEMPLATE_FILENAMES: Record<BuiltInTemplateKind, string>;
89
+ /**
90
+ * Structural classification of the file an injection is being computed for.
91
+ * `templateInjector.ts` derives this from the folder + filename conventions
92
+ * (controlled separately via `registerRoutingRules`). Selection rules match
93
+ * against it to choose a template kind.
94
+ */
95
+ interface TemplateMatchContext {
96
+ /** Absolute path of the file being created. */
97
+ filePath: string;
98
+ /** Structural kind derived from the route conventions. */
99
+ fileKind: 'api' | 'sync_server' | 'sync_client' | 'page';
100
+ /** For `sync_client`: whether a paired `_server_v<N>.ts` exists on disk. */
101
+ hasPairedServer: boolean;
102
+ /** Path relative to `src/` (forward slashes), or `null` if outside src. */
103
+ srcRelativePath: string | null;
104
+ }
105
+ /** A single template-selection rule. First matching rule (by priority) wins. */
106
+ interface TemplateRule {
107
+ kind: TemplateKind;
108
+ match: (ctx: TemplateMatchContext) => boolean;
109
+ /** Higher runs first. Built-in defaults use 10 (specific) / 0 (catch-all). */
110
+ priority: number;
111
+ }
112
+ interface RegisterTemplateKindOptions {
113
+ /** Predicate deciding when this kind is chosen. */
114
+ match: (ctx: TemplateMatchContext) => boolean;
115
+ /** Optional inline template body (same as calling `registerTemplate`). */
116
+ content?: string;
117
+ /** Higher runs first. Defaults to 100 so consumer kinds beat the built-ins. */
118
+ priority?: number;
119
+ }
120
+ declare const DEFAULT_DASHBOARD_PATH_PATTERN: RegExp;
121
+ /**
122
+ * Override the template body for a given kind. Subsequent injections emit the
123
+ * supplied content with the standard `{{REL_PATH}}` / `{{PAGE_PATH}}` /
124
+ * `{{SYNC_NAME}}` placeholder substitution. Resolution order in the injector
125
+ * is: consumer file (`.luckystack/templates/<kind>.template.*`) → this
126
+ * override → bundled disk template.
127
+ */
128
+ declare const registerTemplate: (kind: TemplateKind, content: string) => void;
129
+ /** Read the registered content override for a kind, or `null` when none. */
130
+ declare const getRegisteredTemplate: (kind: TemplateKind) => string | null;
131
+ /** Drop every content override. Test-only. */
132
+ declare const clearTemplateOverrides: () => void;
133
+ /** Diagnostic: kinds that currently have a content override. */
134
+ declare const listRegisteredTemplateKinds: () => readonly TemplateKind[];
135
+ /**
136
+ * Register a selection rule. Rules are evaluated by descending `priority`,
137
+ * ties broken by descending registration order (so a later registration —
138
+ * e.g. a consumer overlay — beats an earlier same-priority default).
139
+ */
140
+ declare const registerTemplateRule: (rule: TemplateRule) => void;
141
+ /**
142
+ * Register a brand-new template kind: its selection predicate plus (optionally)
143
+ * its inline content. Equivalent to `registerTemplateRule` + `registerTemplate`
144
+ * in one call. Default priority 100 so custom kinds win over the built-ins.
145
+ */
146
+ declare const registerTemplateKind: (kind: TemplateKind, options: RegisterTemplateKindOptions) => void;
147
+ /** Drop every selection rule (including the built-in defaults). */
148
+ declare const clearTemplateRules: () => void;
149
+ /** Read the active rules in evaluation order (priority desc, then newest first). */
150
+ declare const getTemplateRules: () => readonly TemplateRule[];
151
+ /** Evaluate the active rules against a context; returns the first matching kind. */
152
+ declare const resolveTemplateKind: (ctx: TemplateMatchContext) => TemplateKind | null;
153
+ declare const registerDefaultTemplateRules: () => void;
154
+
155
+ declare const devApis: Record<string, unknown>;
156
+ declare const devSyncs: Record<string, unknown>;
157
+ declare const devFunctions: Record<string, unknown>;
158
+ declare const initializeAll: () => Promise<void>;
159
+ declare const initializeApis: () => Promise<void>;
160
+ declare const upsertApiFromFile: (filePath: string) => Promise<void>;
161
+ declare const removeApiFromFile: (filePath: string) => void;
162
+ declare const initializeSyncs: () => Promise<void>;
163
+ declare const upsertSyncFromFile: (filePath: string) => Promise<void>;
164
+ declare const removeSyncFromFile: (filePath: string) => void;
165
+ declare const initializeFunctions: () => Promise<void>;
166
+
167
+ declare const setupWatchers: () => void;
168
+
169
+ type ResolveResult = {
170
+ status: 'success';
171
+ typeText: string;
172
+ } | {
173
+ status: 'error';
174
+ message: string;
175
+ };
176
+ declare const clearRuntimeTypeResolverCache: () => void;
177
+ declare const resolveRuntimeTypeText: ({ typeText, filePath, }: {
178
+ typeText: string;
179
+ filePath?: string;
180
+ }) => ResolveResult;
181
+
182
+ type ValidationSeverity = 'error' | 'warning';
183
+ interface ValidationFinding {
184
+ severity: ValidationSeverity;
185
+ code: string;
186
+ message: string;
187
+ /** Human-readable location pointer (e.g. `services.config.ts > presets.api`). */
188
+ location?: string;
189
+ }
190
+ interface ValidateDeployInput {
191
+ services: ServicesConfigShape;
192
+ deploy: DeployConfigShape;
193
+ /**
194
+ * Environment values to consult for `synchronizedEnvKeys` / `urlEnvKey`
195
+ * presence checks. Defaults to `process.env`. Pass a fixture for tests.
196
+ */
197
+ env?: Record<string, string | undefined>;
198
+ }
199
+ interface ValidateDeployResult {
200
+ ok: boolean;
201
+ findings: ValidationFinding[];
202
+ errorCount: number;
203
+ warningCount: number;
204
+ }
205
+ declare const validateDeploy: ({ services, deploy, env, }: ValidateDeployInput) => ValidateDeployResult;
206
+
207
+ export { API_VERSION_TOKEN_REGEX, BUILT_IN_TEMPLATE_FILENAMES, BUILT_IN_TEMPLATE_KINDS, type BuiltInTemplateKind, DEFAULT_DASHBOARD_PATH_PATTERN, type RegisterTemplateKindOptions, 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, devApis, devFunctions, devSyncs, generateTypeMapFile, getInputTypeFromFile, getRegisteredTemplate, getRoutingRules, getSyncClientDataType, getTemplateRules, initializeAll, initializeApis, initializeFunctions, initializeSyncs, isApiFileName, isSyncClientFileName, isSyncFileName, isSyncServerFileName, listRegisteredTemplateKinds, registerDefaultTemplateRules, registerRoutingRules, registerTemplate, registerTemplateKind, registerTemplateRule, removeApiFromFile, removeSyncFromFile, resolveRuntimeTypeText, resolveTemplateKind, setupWatchers, syncMarkerSegment, upsertApiFromFile, upsertSyncFromFile, validateDeploy };