@kardoe/quickback 0.4.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/dist/commands/compile.d.ts +18 -0
- package/dist/commands/compile.d.ts.map +1 -0
- package/dist/commands/compile.js +144 -0
- package/dist/commands/compile.js.map +1 -0
- package/dist/commands/create.d.ts +18 -0
- package/dist/commands/create.d.ts.map +1 -0
- package/dist/commands/create.js +669 -0
- package/dist/commands/create.js.map +1 -0
- package/dist/commands/init.d.ts +6 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +383 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/login.d.ts +8 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +190 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.d.ts +7 -0
- package/dist/commands/logout.d.ts.map +1 -0
- package/dist/commands/logout.js +19 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/whoami.d.ts +7 -0
- package/dist/commands/whoami.d.ts.map +1 -0
- package/dist/commands/whoami.js +37 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +140 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/api-client.d.ts +82 -0
- package/dist/lib/api-client.d.ts.map +1 -0
- package/dist/lib/api-client.js +59 -0
- package/dist/lib/api-client.js.map +1 -0
- package/dist/lib/auth.d.ts +44 -0
- package/dist/lib/auth.d.ts.map +1 -0
- package/dist/lib/auth.js +85 -0
- package/dist/lib/auth.js.map +1 -0
- package/dist/lib/compiler-stubs.d.ts +66 -0
- package/dist/lib/compiler-stubs.d.ts.map +1 -0
- package/dist/lib/compiler-stubs.js +75 -0
- package/dist/lib/compiler-stubs.js.map +1 -0
- package/dist/lib/file-loader.d.ts +73 -0
- package/dist/lib/file-loader.d.ts.map +1 -0
- package/dist/lib/file-loader.js +291 -0
- package/dist/lib/file-loader.js.map +1 -0
- package/dist/lib/file-writer.d.ts +33 -0
- package/dist/lib/file-writer.d.ts.map +1 -0
- package/dist/lib/file-writer.js +110 -0
- package/dist/lib/file-writer.js.map +1 -0
- package/dist/lib/helpers.d.ts +39 -0
- package/dist/lib/helpers.d.ts.map +1 -0
- package/dist/lib/helpers.js +299 -0
- package/dist/lib/helpers.js.map +1 -0
- package/dist/lib/shell.d.ts +15 -0
- package/dist/lib/shell.d.ts.map +1 -0
- package/dist/lib/shell.js +32 -0
- package/dist/lib/shell.js.map +1 -0
- package/dist/templates/registry.d.ts +36 -0
- package/dist/templates/registry.d.ts.map +1 -0
- package/dist/templates/registry.js +143 -0
- package/dist/templates/registry.js.map +1 -0
- package/package.json +37 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compiler Stubs for CLI Runtime
|
|
3
|
+
*
|
|
4
|
+
* These stub functions allow config/resource/action definition files to be loaded
|
|
5
|
+
* by the CLI without needing the full @quickback/compiler package.
|
|
6
|
+
*
|
|
7
|
+
* The actual validation happens server-side in the compiler worker.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Stub for defineConfig - just returns the config as-is
|
|
11
|
+
*/
|
|
12
|
+
export function defineConfig(config) {
|
|
13
|
+
return config;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Stub for defineRuntime - returns provider config
|
|
17
|
+
*/
|
|
18
|
+
export function defineRuntime(name, config) {
|
|
19
|
+
return { name, config: config || {} };
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Stub for defineDatabase - returns provider config
|
|
23
|
+
*/
|
|
24
|
+
export function defineDatabase(name, config) {
|
|
25
|
+
return { name, config: config || {} };
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Stub for defineAuth - returns provider config
|
|
29
|
+
*/
|
|
30
|
+
export function defineAuth(name, config) {
|
|
31
|
+
return { name, config: config || {} };
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Stub for defineStorage - returns provider config
|
|
35
|
+
*/
|
|
36
|
+
export function defineStorage(name, config) {
|
|
37
|
+
return { name, config: config || {} };
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Stub for defineResource - just returns the config with schema reference
|
|
41
|
+
*/
|
|
42
|
+
export function defineResource(schema, config) {
|
|
43
|
+
return {
|
|
44
|
+
...config,
|
|
45
|
+
__schema: schema,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Stub for defineTable - combines schema with all configuration
|
|
50
|
+
*
|
|
51
|
+
* This is the new unified API that combines schema definition with
|
|
52
|
+
* all configuration (firewall, guards, crud, embeddings, realtime) in one place.
|
|
53
|
+
*/
|
|
54
|
+
export function defineTable(schema, config) {
|
|
55
|
+
return {
|
|
56
|
+
...config,
|
|
57
|
+
__schema: schema,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Stub for defineActions - just returns the actions with schema reference
|
|
62
|
+
*/
|
|
63
|
+
export function defineActions(schema, actions) {
|
|
64
|
+
return {
|
|
65
|
+
...actions,
|
|
66
|
+
__schema: schema,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Stub for defineAction - returns a curried function that returns the config
|
|
71
|
+
*/
|
|
72
|
+
export function defineAction() {
|
|
73
|
+
return (config) => config;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=compiler-stubs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compiler-stubs.js","sourceRoot":"","sources":["../../src/lib/compiler-stubs.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,MAA+B;IAC1D,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,MAAgC;IAC1E,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,IAAI,EAAE,EAAE,CAAC;AACxC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY,EAAE,MAAgC;IAC3E,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,IAAI,EAAE,EAAE,CAAC;AACxC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,IAAY,EAAE,MAAgC;IACvE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,IAAI,EAAE,EAAE,CAAC;AACxC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,MAAgC;IAC1E,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,IAAI,EAAE,EAAE,CAAC;AACxC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAC5B,MAAe,EACf,MAA+B;IAE/B,OAAO;QACL,GAAG,MAAM;QACT,QAAQ,EAAE,MAAM;KACjB,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CACzB,MAAe,EACf,MAA+B;IAE/B,OAAO;QACL,GAAG,MAAM;QACT,QAAQ,EAAE,MAAM;KACjB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAC3B,MAAe,EACf,OAAgC;IAEhC,OAAO;QACL,GAAG,OAAO;QACV,QAAQ,EAAE,MAAM;KACjB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY;IAC1B,OAAO,CAAC,MAA+B,EAAE,EAAE,CAAC,MAAM,CAAC;AACrD,CAAC"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File Loader
|
|
3
|
+
*
|
|
4
|
+
* Loads configuration and feature definitions from disk.
|
|
5
|
+
* This is CLI-side only - reads files and prepares them for the API.
|
|
6
|
+
*
|
|
7
|
+
* Supports two modes:
|
|
8
|
+
* 1. Legacy mode: schema.ts + resource.ts separate files
|
|
9
|
+
* 2. Combined mode: defineTable() in *.ts files (schema + config together)
|
|
10
|
+
*/
|
|
11
|
+
export interface LoadedConfig {
|
|
12
|
+
name: string;
|
|
13
|
+
preset: string;
|
|
14
|
+
template?: string;
|
|
15
|
+
providers?: any;
|
|
16
|
+
build?: {
|
|
17
|
+
outputDir?: string;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* A table definition from a single file (combined mode)
|
|
22
|
+
*/
|
|
23
|
+
export interface LoadedTableDefinition {
|
|
24
|
+
/** Original filename, e.g., "claims.ts", "claim-versions.ts" */
|
|
25
|
+
fileName: string;
|
|
26
|
+
/** Export name (camelCase), e.g., "claims", "claimVersions" */
|
|
27
|
+
tableName: string;
|
|
28
|
+
/** Full file source code */
|
|
29
|
+
source: string;
|
|
30
|
+
/** Has defineTable default export (generates routes) */
|
|
31
|
+
hasResourceConfig: boolean;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Legacy mode: single schema per feature
|
|
35
|
+
*/
|
|
36
|
+
export interface LoadedFeature {
|
|
37
|
+
name: string;
|
|
38
|
+
/** Legacy: single schema (used when schema.ts exists) */
|
|
39
|
+
schema: {
|
|
40
|
+
tableName: string;
|
|
41
|
+
columns: Record<string, any>;
|
|
42
|
+
source: string;
|
|
43
|
+
};
|
|
44
|
+
/** Combined mode: multiple tables per feature */
|
|
45
|
+
tables?: LoadedTableDefinition[];
|
|
46
|
+
resource?: any;
|
|
47
|
+
resourceSource?: string;
|
|
48
|
+
actions?: any;
|
|
49
|
+
actionsSource?: string;
|
|
50
|
+
handlerFiles?: Record<string, string>;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Load quickback.config.ts from disk
|
|
54
|
+
*/
|
|
55
|
+
export declare function loadConfig(configPath: string): Promise<LoadedConfig>;
|
|
56
|
+
/**
|
|
57
|
+
* Load all features from definitions/features/
|
|
58
|
+
*/
|
|
59
|
+
export declare function loadFeatures(featuresDir: string): Promise<LoadedFeature[]>;
|
|
60
|
+
/**
|
|
61
|
+
* Find the config file path
|
|
62
|
+
*/
|
|
63
|
+
export declare function findConfigPath(startDir?: string): string | null;
|
|
64
|
+
/**
|
|
65
|
+
* Find the features directory
|
|
66
|
+
*/
|
|
67
|
+
export declare function findFeaturesDir(startDir?: string): string | null;
|
|
68
|
+
/**
|
|
69
|
+
* Load existing drizzle migration state (meta files and journal)
|
|
70
|
+
* This allows the compiler to generate incremental migrations (ALTER vs CREATE)
|
|
71
|
+
*/
|
|
72
|
+
export declare function loadDrizzleMeta(projectRoot: string): Record<string, string> | undefined;
|
|
73
|
+
//# sourceMappingURL=file-loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-loader.d.ts","sourceRoot":"","sources":["../../src/lib/file-loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAaH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,GAAG,CAAC;IAChB,KAAK,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,gEAAgE;IAChE,QAAQ,EAAE,MAAM,CAAC;IACjB,+DAA+D;IAC/D,SAAS,EAAE,MAAM,CAAC;IAClB,4BAA4B;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,yDAAyD;IACzD,MAAM,EAAE;QACN,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC7B,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,iDAAiD;IACjD,MAAM,CAAC,EAAE,qBAAqB,EAAE,CAAC;IACjC,QAAQ,CAAC,EAAE,GAAG,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACvC;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CA8B1E;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAoBhF;AA2LD;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,GAAE,MAAsB,GAAG,MAAM,GAAG,IAAI,CAa9E;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,GAAE,MAAsB,GAAG,MAAM,GAAG,IAAI,CAa/E;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAmCvF"}
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File Loader
|
|
3
|
+
*
|
|
4
|
+
* Loads configuration and feature definitions from disk.
|
|
5
|
+
* This is CLI-side only - reads files and prepares them for the API.
|
|
6
|
+
*
|
|
7
|
+
* Supports two modes:
|
|
8
|
+
* 1. Legacy mode: schema.ts + resource.ts separate files
|
|
9
|
+
* 2. Combined mode: defineTable() in *.ts files (schema + config together)
|
|
10
|
+
*/
|
|
11
|
+
import { existsSync, readdirSync, readFileSync, statSync } from 'fs';
|
|
12
|
+
import { join, basename, dirname } from 'path';
|
|
13
|
+
import { build } from 'esbuild';
|
|
14
|
+
import { tmpdir } from 'os';
|
|
15
|
+
import { fileURLToPath } from 'url';
|
|
16
|
+
// Get the directory of this file for resolving stubs
|
|
17
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
18
|
+
const __dirname = dirname(__filename);
|
|
19
|
+
const stubsPath = join(__dirname, 'compiler-stubs.js');
|
|
20
|
+
/**
|
|
21
|
+
* Load quickback.config.ts from disk
|
|
22
|
+
*/
|
|
23
|
+
export async function loadConfig(configPath) {
|
|
24
|
+
if (!existsSync(configPath)) {
|
|
25
|
+
throw new Error(`Config file not found: ${configPath}`);
|
|
26
|
+
}
|
|
27
|
+
const config = await loadTypeScriptFile(configPath);
|
|
28
|
+
// Handle default export
|
|
29
|
+
const configData = config.default || config;
|
|
30
|
+
if (!configData.name) {
|
|
31
|
+
throw new Error('Config must have a name');
|
|
32
|
+
}
|
|
33
|
+
// Determine preset from providers or explicit preset
|
|
34
|
+
let preset = configData.preset;
|
|
35
|
+
if (!preset && configData.providers) {
|
|
36
|
+
// Infer preset from runtime provider
|
|
37
|
+
const runtimeName = configData.providers.runtime?.name;
|
|
38
|
+
if (runtimeName === 'cloudflare')
|
|
39
|
+
preset = 'cloudflare';
|
|
40
|
+
else if (runtimeName === 'bun')
|
|
41
|
+
preset = 'bun';
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
name: configData.name,
|
|
45
|
+
preset: preset || 'cloudflare',
|
|
46
|
+
template: configData.template,
|
|
47
|
+
providers: configData.providers,
|
|
48
|
+
build: configData.build,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Load all features from definitions/features/
|
|
53
|
+
*/
|
|
54
|
+
export async function loadFeatures(featuresDir) {
|
|
55
|
+
if (!existsSync(featuresDir)) {
|
|
56
|
+
return [];
|
|
57
|
+
}
|
|
58
|
+
const features = [];
|
|
59
|
+
const featureDirs = readdirSync(featuresDir).filter((f) => {
|
|
60
|
+
const fullPath = join(featuresDir, f);
|
|
61
|
+
return statSync(fullPath).isDirectory();
|
|
62
|
+
});
|
|
63
|
+
for (const featureName of featureDirs) {
|
|
64
|
+
const featureDir = join(featuresDir, featureName);
|
|
65
|
+
const feature = await loadFeature(featureName, featureDir);
|
|
66
|
+
if (feature) {
|
|
67
|
+
features.push(feature);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return features;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Load a single feature from its directory
|
|
74
|
+
*
|
|
75
|
+
* Supports two modes:
|
|
76
|
+
* 1. Legacy mode: schema.ts + resource.ts separate files
|
|
77
|
+
* 2. Combined mode: defineTable() in *.ts files (schema + config together)
|
|
78
|
+
*
|
|
79
|
+
* Detection:
|
|
80
|
+
* - If schema.ts exists → legacy mode
|
|
81
|
+
* - If no schema.ts but *.ts files with sqliteTable/pgTable → combined mode
|
|
82
|
+
*
|
|
83
|
+
* Sends source code strings to the server for parsing.
|
|
84
|
+
* This avoids needing drizzle-orm and @quickback/compiler at CLI runtime.
|
|
85
|
+
*/
|
|
86
|
+
async function loadFeature(name, dir) {
|
|
87
|
+
const schemaPath = join(dir, 'schema.ts');
|
|
88
|
+
const resourcePath = join(dir, 'resource.ts');
|
|
89
|
+
const actionsPath = join(dir, 'actions.ts');
|
|
90
|
+
// Load actions source if exists (common to both modes)
|
|
91
|
+
let actionsSource;
|
|
92
|
+
if (existsSync(actionsPath)) {
|
|
93
|
+
actionsSource = readFileSync(actionsPath, 'utf-8');
|
|
94
|
+
}
|
|
95
|
+
// Load handler files if handlers/ directory exists (common to both modes)
|
|
96
|
+
const handlersDir = join(dir, 'handlers');
|
|
97
|
+
let handlerFiles;
|
|
98
|
+
if (existsSync(handlersDir) && statSync(handlersDir).isDirectory()) {
|
|
99
|
+
handlerFiles = {};
|
|
100
|
+
const handlers = readdirSync(handlersDir).filter((f) => f.endsWith('.ts'));
|
|
101
|
+
for (const handler of handlers) {
|
|
102
|
+
const handlerPath = join(handlersDir, handler);
|
|
103
|
+
handlerFiles[`handlers/${handler}`] = readFileSync(handlerPath, 'utf-8');
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
// Check for legacy mode (schema.ts exists)
|
|
107
|
+
if (existsSync(schemaPath)) {
|
|
108
|
+
return loadFeatureLegacy(name, dir, schemaPath, resourcePath, actionsSource, handlerFiles);
|
|
109
|
+
}
|
|
110
|
+
// Try combined mode - scan for table files
|
|
111
|
+
return loadFeatureCombined(name, dir, actionsSource, handlerFiles);
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Load feature in legacy mode (schema.ts + resource.ts)
|
|
115
|
+
*/
|
|
116
|
+
async function loadFeatureLegacy(name, dir, schemaPath, resourcePath, actionsSource, handlerFiles) {
|
|
117
|
+
// Load schema source
|
|
118
|
+
const schemaSource = readFileSync(schemaPath, 'utf-8');
|
|
119
|
+
// Parse table name from schema - support both pgTable and sqliteTable
|
|
120
|
+
const pgTableMatch = schemaSource.match(/export const (\w+) = pgTable/);
|
|
121
|
+
const sqliteTableMatch = schemaSource.match(/export const (\w+) = sqliteTable/);
|
|
122
|
+
const tableName = pgTableMatch?.[1] || sqliteTableMatch?.[1] || name;
|
|
123
|
+
// Load resource source if exists (don't evaluate, send to server)
|
|
124
|
+
let resourceSource;
|
|
125
|
+
if (existsSync(resourcePath)) {
|
|
126
|
+
resourceSource = readFileSync(resourcePath, 'utf-8');
|
|
127
|
+
}
|
|
128
|
+
return {
|
|
129
|
+
name,
|
|
130
|
+
schema: {
|
|
131
|
+
tableName,
|
|
132
|
+
columns: {}, // Column parsing happens on server
|
|
133
|
+
source: schemaSource,
|
|
134
|
+
},
|
|
135
|
+
resourceSource,
|
|
136
|
+
actionsSource,
|
|
137
|
+
handlerFiles,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Load feature in combined mode (defineTable in *.ts files)
|
|
142
|
+
*/
|
|
143
|
+
async function loadFeatureCombined(name, dir, actionsSource, handlerFiles) {
|
|
144
|
+
const tables = [];
|
|
145
|
+
// Scan for table files (*.ts except actions.ts)
|
|
146
|
+
const files = readdirSync(dir).filter((f) => f.endsWith('.ts') && f !== 'actions.ts');
|
|
147
|
+
for (const file of files) {
|
|
148
|
+
const filePath = join(dir, file);
|
|
149
|
+
// Skip directories
|
|
150
|
+
if (statSync(filePath).isDirectory())
|
|
151
|
+
continue;
|
|
152
|
+
const source = readFileSync(filePath, 'utf-8');
|
|
153
|
+
// Check for table export (pgTable or sqliteTable)
|
|
154
|
+
const tableMatch = source.match(/export const (\w+)\s*=\s*(?:pg|sqlite)Table/);
|
|
155
|
+
if (!tableMatch)
|
|
156
|
+
continue;
|
|
157
|
+
// Check for resource config (default export with defineTable)
|
|
158
|
+
const hasResourceConfig = /export default defineTable/.test(source);
|
|
159
|
+
tables.push({
|
|
160
|
+
fileName: file,
|
|
161
|
+
tableName: tableMatch[1],
|
|
162
|
+
source,
|
|
163
|
+
hasResourceConfig,
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
if (tables.length === 0) {
|
|
167
|
+
console.warn(`Feature ${name} has no schema.ts or table definitions, skipping`);
|
|
168
|
+
return null;
|
|
169
|
+
}
|
|
170
|
+
// For combined mode, use first table as "primary" for backward compatibility
|
|
171
|
+
const primaryTable = tables[0];
|
|
172
|
+
return {
|
|
173
|
+
name,
|
|
174
|
+
schema: {
|
|
175
|
+
tableName: primaryTable.tableName,
|
|
176
|
+
columns: {}, // Column parsing happens on server
|
|
177
|
+
source: primaryTable.source,
|
|
178
|
+
},
|
|
179
|
+
tables,
|
|
180
|
+
// Resource comes from defineTable in combined mode, not separate file
|
|
181
|
+
resourceSource: primaryTable.hasResourceConfig ? primaryTable.source : undefined,
|
|
182
|
+
actionsSource,
|
|
183
|
+
handlerFiles,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Load and evaluate a TypeScript file
|
|
188
|
+
*/
|
|
189
|
+
async function loadTypeScriptFile(filePath) {
|
|
190
|
+
const outfile = join(tmpdir(), `quickback-${Date.now()}-${basename(filePath)}.mjs`);
|
|
191
|
+
try {
|
|
192
|
+
await build({
|
|
193
|
+
entryPoints: [filePath],
|
|
194
|
+
outfile,
|
|
195
|
+
bundle: true,
|
|
196
|
+
format: 'esm',
|
|
197
|
+
platform: 'node',
|
|
198
|
+
target: 'node18',
|
|
199
|
+
external: [
|
|
200
|
+
'drizzle-orm',
|
|
201
|
+
'drizzle-orm/*',
|
|
202
|
+
'zod',
|
|
203
|
+
],
|
|
204
|
+
alias: {
|
|
205
|
+
'@quickback/compiler': stubsPath,
|
|
206
|
+
},
|
|
207
|
+
logLevel: 'silent',
|
|
208
|
+
});
|
|
209
|
+
// Dynamic import the built file
|
|
210
|
+
const module = await import(outfile);
|
|
211
|
+
return module;
|
|
212
|
+
}
|
|
213
|
+
finally {
|
|
214
|
+
// Cleanup temp file
|
|
215
|
+
try {
|
|
216
|
+
const { unlinkSync } = await import('fs');
|
|
217
|
+
unlinkSync(outfile);
|
|
218
|
+
}
|
|
219
|
+
catch {
|
|
220
|
+
// Ignore cleanup errors
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Find the config file path
|
|
226
|
+
*/
|
|
227
|
+
export function findConfigPath(startDir = process.cwd()) {
|
|
228
|
+
const candidates = [
|
|
229
|
+
join(startDir, 'quickback.config.ts'),
|
|
230
|
+
join(startDir, 'quickback', 'quickback.config.ts'),
|
|
231
|
+
];
|
|
232
|
+
for (const candidate of candidates) {
|
|
233
|
+
if (existsSync(candidate)) {
|
|
234
|
+
return candidate;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
return null;
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Find the features directory
|
|
241
|
+
*/
|
|
242
|
+
export function findFeaturesDir(startDir = process.cwd()) {
|
|
243
|
+
const candidates = [
|
|
244
|
+
join(startDir, 'definitions', 'features'),
|
|
245
|
+
join(startDir, 'quickback', 'definitions', 'features'),
|
|
246
|
+
];
|
|
247
|
+
for (const candidate of candidates) {
|
|
248
|
+
if (existsSync(candidate)) {
|
|
249
|
+
return candidate;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
return null;
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Load existing drizzle migration state (meta files and journal)
|
|
256
|
+
* This allows the compiler to generate incremental migrations (ALTER vs CREATE)
|
|
257
|
+
*/
|
|
258
|
+
export function loadDrizzleMeta(projectRoot) {
|
|
259
|
+
const metaFiles = {};
|
|
260
|
+
// Check for features drizzle meta (dual database mode)
|
|
261
|
+
const featuresMeta = join(projectRoot, 'drizzle', 'features', 'meta');
|
|
262
|
+
const legacyMeta = join(projectRoot, 'drizzle', 'meta');
|
|
263
|
+
// Determine which meta dir exists and its relative path for the compiler
|
|
264
|
+
let metaDir = null;
|
|
265
|
+
let relativePath = '';
|
|
266
|
+
if (existsSync(featuresMeta)) {
|
|
267
|
+
metaDir = featuresMeta;
|
|
268
|
+
relativePath = 'drizzle/features/meta';
|
|
269
|
+
}
|
|
270
|
+
else if (existsSync(legacyMeta)) {
|
|
271
|
+
metaDir = legacyMeta;
|
|
272
|
+
relativePath = 'drizzle/meta';
|
|
273
|
+
}
|
|
274
|
+
if (!metaDir) {
|
|
275
|
+
return undefined;
|
|
276
|
+
}
|
|
277
|
+
try {
|
|
278
|
+
const files = readdirSync(metaDir);
|
|
279
|
+
for (const file of files) {
|
|
280
|
+
if (file.endsWith('.json')) {
|
|
281
|
+
const filePath = join(metaDir, file);
|
|
282
|
+
metaFiles[`${relativePath}/${file}`] = readFileSync(filePath, 'utf-8');
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
return Object.keys(metaFiles).length > 0 ? metaFiles : undefined;
|
|
286
|
+
}
|
|
287
|
+
catch {
|
|
288
|
+
return undefined;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
//# sourceMappingURL=file-loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-loader.js","sourceRoot":"","sources":["../../src/lib/file-loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File Writer
|
|
3
|
+
*
|
|
4
|
+
* Writes generated files to disk with smart merge strategies.
|
|
5
|
+
*/
|
|
6
|
+
export interface GeneratedFile {
|
|
7
|
+
path: string;
|
|
8
|
+
content: string;
|
|
9
|
+
type?: string;
|
|
10
|
+
feature?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Clean and recreate output directory (used for testing only)
|
|
14
|
+
*/
|
|
15
|
+
export declare function cleanOutputDir(dir: string): void;
|
|
16
|
+
/**
|
|
17
|
+
* Write generated files to disk (overwrites all)
|
|
18
|
+
*/
|
|
19
|
+
export declare function writeFiles(outputDir: string, files: GeneratedFile[]): void;
|
|
20
|
+
/**
|
|
21
|
+
* Write generated files with smart merge strategy
|
|
22
|
+
*
|
|
23
|
+
* - Generated code (src/, etc.): Overwrite
|
|
24
|
+
* - Migrations (drizzle/, supabase/migrations/): Only add new files, don't overwrite
|
|
25
|
+
* - package.json: Merge dependencies
|
|
26
|
+
* - Config files: Overwrite
|
|
27
|
+
*/
|
|
28
|
+
export declare function writeFilesWithMerge(outputDir: string, files: GeneratedFile[]): void;
|
|
29
|
+
/**
|
|
30
|
+
* Write a single file
|
|
31
|
+
*/
|
|
32
|
+
export declare function writeFile(filePath: string, content: string): void;
|
|
33
|
+
//# sourceMappingURL=file-writer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-writer.d.ts","sourceRoot":"","sources":["../../src/lib/file-writer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAKhD;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,IAAI,CAa1E;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,IAAI,CA+BnF;AAqCD;;GAEG;AACH,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAQjE"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File Writer
|
|
3
|
+
*
|
|
4
|
+
* Writes generated files to disk with smart merge strategies.
|
|
5
|
+
*/
|
|
6
|
+
import { existsSync, mkdirSync, writeFileSync, rmSync, readFileSync } from 'fs';
|
|
7
|
+
import { join, dirname } from 'path';
|
|
8
|
+
/**
|
|
9
|
+
* Clean and recreate output directory (used for testing only)
|
|
10
|
+
*/
|
|
11
|
+
export function cleanOutputDir(dir) {
|
|
12
|
+
if (existsSync(dir)) {
|
|
13
|
+
rmSync(dir, { recursive: true, force: true });
|
|
14
|
+
}
|
|
15
|
+
mkdirSync(dir, { recursive: true });
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Write generated files to disk (overwrites all)
|
|
19
|
+
*/
|
|
20
|
+
export function writeFiles(outputDir, files) {
|
|
21
|
+
for (const file of files) {
|
|
22
|
+
const fullPath = join(outputDir, file.path);
|
|
23
|
+
const fileDir = dirname(fullPath);
|
|
24
|
+
// Ensure directory exists
|
|
25
|
+
if (!existsSync(fileDir)) {
|
|
26
|
+
mkdirSync(fileDir, { recursive: true });
|
|
27
|
+
}
|
|
28
|
+
// Write file
|
|
29
|
+
writeFileSync(fullPath, file.content, 'utf-8');
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Write generated files with smart merge strategy
|
|
34
|
+
*
|
|
35
|
+
* - Generated code (src/, etc.): Overwrite
|
|
36
|
+
* - Migrations (drizzle/, supabase/migrations/): Only add new files, don't overwrite
|
|
37
|
+
* - package.json: Merge dependencies
|
|
38
|
+
* - Config files: Overwrite
|
|
39
|
+
*/
|
|
40
|
+
export function writeFilesWithMerge(outputDir, files) {
|
|
41
|
+
for (const file of files) {
|
|
42
|
+
const fullPath = join(outputDir, file.path);
|
|
43
|
+
const fileDir = dirname(fullPath);
|
|
44
|
+
// Ensure directory exists
|
|
45
|
+
if (!existsSync(fileDir)) {
|
|
46
|
+
mkdirSync(fileDir, { recursive: true });
|
|
47
|
+
}
|
|
48
|
+
// Check if this is a migration file
|
|
49
|
+
const isMigration = file.path.includes('/migrations/') ||
|
|
50
|
+
file.path.startsWith('drizzle/') ||
|
|
51
|
+
file.path.startsWith('supabase/migrations/');
|
|
52
|
+
if (isMigration && existsSync(fullPath)) {
|
|
53
|
+
// Skip existing migrations - don't overwrite
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
// Check if this is package.json
|
|
57
|
+
if (file.path === 'package.json' && existsSync(fullPath)) {
|
|
58
|
+
// Merge package.json
|
|
59
|
+
const merged = mergePackageJson(fullPath, file.content);
|
|
60
|
+
writeFileSync(fullPath, merged, 'utf-8');
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
// Default: write/overwrite
|
|
64
|
+
writeFileSync(fullPath, file.content, 'utf-8');
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Merge generated package.json with existing one
|
|
69
|
+
* Preserves user's custom scripts, adds new dependencies
|
|
70
|
+
*/
|
|
71
|
+
function mergePackageJson(existingPath, newContent) {
|
|
72
|
+
try {
|
|
73
|
+
const existing = JSON.parse(readFileSync(existingPath, 'utf-8'));
|
|
74
|
+
const generated = JSON.parse(newContent);
|
|
75
|
+
// Merge dependencies (generated takes precedence for versions)
|
|
76
|
+
const merged = {
|
|
77
|
+
...existing,
|
|
78
|
+
name: generated.name || existing.name,
|
|
79
|
+
version: existing.version || generated.version,
|
|
80
|
+
scripts: {
|
|
81
|
+
...generated.scripts,
|
|
82
|
+
...existing.scripts, // User scripts take precedence
|
|
83
|
+
},
|
|
84
|
+
dependencies: {
|
|
85
|
+
...existing.dependencies,
|
|
86
|
+
...generated.dependencies, // Generated deps take precedence (newer versions)
|
|
87
|
+
},
|
|
88
|
+
devDependencies: {
|
|
89
|
+
...existing.devDependencies,
|
|
90
|
+
...generated.devDependencies,
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
return JSON.stringify(merged, null, 2);
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
// If merge fails, use generated content
|
|
97
|
+
return newContent;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Write a single file
|
|
102
|
+
*/
|
|
103
|
+
export function writeFile(filePath, content) {
|
|
104
|
+
const dir = dirname(filePath);
|
|
105
|
+
if (!existsSync(dir)) {
|
|
106
|
+
mkdirSync(dir, { recursive: true });
|
|
107
|
+
}
|
|
108
|
+
writeFileSync(filePath, content, 'utf-8');
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=file-writer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-writer.js","sourceRoot":"","sources":["../../src/lib/file-writer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export type JSONValue = string | number | boolean | null | JSONArray | JSONObject;
|
|
2
|
+
export interface JSONObject {
|
|
3
|
+
[key: string]: JSONValue;
|
|
4
|
+
}
|
|
5
|
+
export interface JSONArray extends Array<JSONValue> {
|
|
6
|
+
}
|
|
7
|
+
export declare function validateBindingName(name: string): string | undefined;
|
|
8
|
+
export declare function updateJSON(filePath: string, mutator: (json: JSONObject) => JSONObject): void;
|
|
9
|
+
export declare function extractFirstBlock(toml: string, header: string): {
|
|
10
|
+
block: string;
|
|
11
|
+
start: number;
|
|
12
|
+
end: number;
|
|
13
|
+
} | null;
|
|
14
|
+
export declare function updateD1Block(toml: string, binding: string, dbName: string): string;
|
|
15
|
+
export declare function appendOrReplaceKvNamespaceBlock(toml: string, binding: string, id?: string): string;
|
|
16
|
+
export declare function appendOrReplaceR2Block(toml: string, binding: string, bucketName: string): string;
|
|
17
|
+
export declare function appendOrReplaceHyperdriveBlock(toml: string, binding: string, id?: string, database?: "hyperdrive-postgres" | "hyperdrive-mysql", connectionString?: string): string;
|
|
18
|
+
export interface DatabaseConfig {
|
|
19
|
+
type: "d1" | "hyperdrive";
|
|
20
|
+
binding: string;
|
|
21
|
+
name?: string;
|
|
22
|
+
id?: string;
|
|
23
|
+
}
|
|
24
|
+
export declare function parseWranglerToml(tomlContent: string): {
|
|
25
|
+
databases: DatabaseConfig[];
|
|
26
|
+
hasMultipleDatabases: boolean;
|
|
27
|
+
};
|
|
28
|
+
export declare function extractD1DatabaseId(wranglerOutput: string): string | null;
|
|
29
|
+
export declare function extractKvNamespaceId(wranglerOutput: string): string | null;
|
|
30
|
+
export declare function extractHyperdriveId(wranglerOutput: string): string | null;
|
|
31
|
+
export declare function updateD1BlockWithId(toml: string, binding: string, dbName: string, databaseId: string): string;
|
|
32
|
+
export declare function updateKvBlockWithId(toml: string, binding: string, namespaceId: string): string;
|
|
33
|
+
export declare function updateHyperdriveBlockWithId(toml: string, binding: string, hyperdriveId: string, connectionString?: string): string;
|
|
34
|
+
export interface GitInitResult {
|
|
35
|
+
success: boolean;
|
|
36
|
+
error?: string;
|
|
37
|
+
}
|
|
38
|
+
export declare function initializeGitRepository(projectPath: string): GitInitResult;
|
|
39
|
+
//# sourceMappingURL=helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/lib/helpers.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,GAAG,UAAU,CAAC;AAClF,MAAM,WAAW,UAAU;IACvB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5B;AACD,MAAM,WAAW,SAAU,SAAQ,KAAK,CAAC,SAAS,CAAC;CAAG;AAEtD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAIpE;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,UAAU,QAKrF;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;;;;SAK7D;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,UAa1E;AAED,wBAAgB,+BAA+B,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,UAezF;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,UAUvF;AAED,wBAAgB,8BAA8B,CAC1C,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,EAAE,CAAC,EAAE,MAAM,EACX,QAAQ,CAAC,EAAE,qBAAqB,GAAG,kBAAkB,EACrD,gBAAgB,CAAC,EAAE,MAAM,UAyB5B;AAED,MAAM,WAAW,cAAc;IAC3B,IAAI,EAAE,IAAI,GAAG,YAAY,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG;IACpD,SAAS,EAAE,cAAc,EAAE,CAAC;IAC5B,oBAAoB,EAAE,OAAO,CAAC;CACjC,CAgDA;AAGD,wBAAgB,mBAAmB,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAgCzE;AAED,wBAAgB,oBAAoB,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAmB1E;AAED,wBAAgB,mBAAmB,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA0BzE;AAGD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,UA6BpG;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,UAGrF;AAED,wBAAgB,2BAA2B,CACvC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,gBAAgB,CAAC,EAAE,MAAM,UA+B5B;AAED,MAAM,WAAW,aAAa;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,MAAM,GAAG,aAAa,CA2C1E"}
|